From a031e4121e32d8d165535e8245ee12f77e5de45c Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Thu, 20 Nov 2025 20:45:32 -0800 Subject: [PATCH 01/61] remove suppressUndefinedRejections from base builder --- packages/core/src/runtime/resume-hook.ts | 46 ++++++++++++------------ 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/packages/core/src/runtime/resume-hook.ts b/packages/core/src/runtime/resume-hook.ts index 9ae5146b8..a0eeb8bf4 100644 --- a/packages/core/src/runtime/resume-hook.ts +++ b/packages/core/src/runtime/resume-hook.ts @@ -1,16 +1,16 @@ -import { waitUntil } from '@vercel/functions'; -import { ERROR_SLUGS, WorkflowRuntimeError } from '@workflow/errors'; -import type { Hook } from '@workflow/world'; -import type { WorkflowInvokePayload } from '../schemas.js'; +import { waitUntil } from "@vercel/functions"; +import { ERROR_SLUGS, WorkflowRuntimeError } from "@workflow/errors"; +import type { Hook } from "@workflow/world"; +import type { WorkflowInvokePayload } from "../schemas.js"; import { dehydrateStepReturnValue, hydrateStepArguments, -} from '../serialization.js'; -import { WEBHOOK_RESPONSE_WRITABLE } from '../symbols.js'; -import * as Attribute from '../telemetry/semantic-conventions.js'; -import { getSpanContextForTraceCarrier, trace } from '../telemetry.js'; -import { waitedUntil } from '../util.js'; -import { getWorld } from './world.js'; +} from "../serialization.js"; +import { WEBHOOK_RESPONSE_WRITABLE } from "../symbols.js"; +import * as Attribute from "../telemetry/semantic-conventions.js"; +import { getSpanContextForTraceCarrier, trace } from "../telemetry.js"; +import { waitedUntil } from "../util.js"; +import { getWorld } from "./world.js"; /** * Get the hook by token to find the associated workflow run, @@ -22,7 +22,7 @@ import { getWorld } from './world.js'; export async function getHookByToken(token: string): Promise { const world = getWorld(); const hook = await world.hooks.getByToken(token); - if (typeof hook.metadata !== 'undefined') { + if (typeof hook.metadata !== "undefined") { hook.metadata = hydrateStepArguments(hook.metadata as any, [], hook.runId); } return hook; @@ -59,10 +59,10 @@ export async function getHookByToken(token: string): Promise { */ export async function resumeHook( token: string, - payload: T + payload: T, ): Promise { return await waitedUntil(() => { - return trace('HOOK.resume', async (span) => { + return trace("HOOK.resume", async (span) => { const world = getWorld(); try { @@ -79,18 +79,18 @@ export async function resumeHook( const dehydratedPayload = dehydrateStepReturnValue( payload, ops, - hook.runId + hook.runId, ); // NOTE: Workaround instead of injecting catching undefined unhandled rejections in webhook bundle waitUntil( Promise.all(ops).catch((err) => { if (err !== undefined) throw err; - }) + }), ); // Create a hook_received event with the payload await world.events.create(hook.runId, { - eventType: 'hook_received', + eventType: "hook_received", correlationId: hook.hookId, eventData: { payload: dehydratedPayload, @@ -124,7 +124,7 @@ export async function resumeHook( } satisfies WorkflowInvokePayload, { deploymentId: workflowRun.deploymentId, - } + }, ); return hook; @@ -176,7 +176,7 @@ export async function resumeHook( */ export async function resumeWebhook( token: string, - request: Request + request: Request, ): Promise { const hook = await getHookByToken(token); @@ -184,10 +184,10 @@ export async function resumeWebhook( let responseReadable: ReadableStream | undefined; if ( hook.metadata && - typeof hook.metadata === 'object' && - 'respondWith' in hook.metadata + typeof hook.metadata === "object" && + "respondWith" in hook.metadata ) { - if (hook.metadata.respondWith === 'manual') { + if (hook.metadata.respondWith === "manual") { const { readable, writable } = new TransformStream(); responseReadable = readable; @@ -199,7 +199,7 @@ export async function resumeWebhook( } else { throw new WorkflowRuntimeError( `Invalid \`respondWith\` value: ${hook.metadata.respondWith}`, - { slug: ERROR_SLUGS.WEBHOOK_INVALID_RESPOND_WITH_VALUE } + { slug: ERROR_SLUGS.WEBHOOK_INVALID_RESPOND_WITH_VALUE }, ); } } else { @@ -221,7 +221,7 @@ export async function resumeWebhook( } if (!response) { - throw new WorkflowRuntimeError('Workflow run did not send a response', { + throw new WorkflowRuntimeError("Workflow run did not send a response", { slug: ERROR_SLUGS.WEBHOOK_RESPONSE_NOT_SENT, }); } From cf555632e479c48f0365b616d17973f7d822c062 Mon Sep 17 00:00:00 2001 From: Pranay Prakash Date: Sun, 9 Nov 2025 22:17:34 -0500 Subject: [PATCH 02/61] Normalize Workbenches Normalize trigger scripts across workbenches fix: include hono in local build test test: include src dir for test test: add workflow dir config in test to fix sveltekit dev tests add temp 7_full in example wokrflow format fix(sveltekit): detecting workflow folders and customizable dir Remove 7_full and 1_simple error replace API symlink in webpack workbench Fix sveltekit and vite tests Fix sveltekit symlinks Test fixes Fix sveltekit workflows path Dont symlink routes in vite Include e2e tests for hono and vite fix error tests post normalization wip - attempted fixes --- packages/sveltekit/src/builder.ts | 85 +- packages/sveltekit/src/plugin.ts | 14 +- workbench/astro/.astro/content-assets.mjs | 1 + workbench/astro/.astro/content-modules.mjs | 1 + workbench/astro/.astro/content.d.ts | 199 + workbench/astro/.astro/data-store.json | 1 + workbench/astro/.astro/settings.json | 5 + workbench/astro/.astro/types.d.ts | 1 + workbench/astro/dist/client/favicon.svg | 9 + workbench/astro/dist/client/index.html | 1 + .../dist/server/_@astrojs-ssr-adapter.mjs | 1 + .../astro/dist/server/_noop-middleware.mjs | 3 + .../dist/server/chunks/99_e2e_DTaFFPMr.mjs | 117 + .../chunks/_@astrojs-ssr-adapter_9__r_ZjJ.mjs | 10521 ++++ .../chunks/_commonjsHelpers_BFTU3MAI.mjs | 7 + .../astro-designed-error-pages_pFA87nEA.mjs | 364 + .../server/chunks/astro/server_DhWKww_t.mjs | 2766 + .../dist/server/chunks/fs-lite_COtHaKzy.mjs | 157 + .../dist/server/chunks/index_DqQ8k47W.mjs | 2319 + .../dist/server/chunks/index_ePTMDSOu.mjs | 42973 ++++++++++++++++ .../dist/server/chunks/node_C2n6Z2oQ.mjs | 1669 + .../dist/server/chunks/remote_OOD9OFqU.mjs | 188 + .../server/chunks/resume-hook_BHshEMMl.mjs | 181 + .../dist/server/chunks/runtime_CxdH0OC2.mjs | 2039 + .../dist/server/chunks/sharp_CR567j69.mjs | 99 + .../server/chunks/token-util_8GTOk-OQ.mjs | 260 + .../server/chunks/token-util_D6r3xWR2.mjs | 30 + .../dist/server/chunks/token_CrOFk7pc.mjs | 88 + workbench/astro/dist/server/entry.mjs | 51 + .../astro/dist/server/manifest_Dl93wae-.mjs | 101 + .../astro/dist/server/noop-entrypoint.mjs | 3 + .../.well-known/workflow/v1/flow.astro.mjs | 27439 ++++++++++ .../.well-known/workflow/v1/step.astro.mjs | 7609 +++ .../workflow/v1/webhook/_token_.astro.mjs | 67 + .../astro/dist/server/pages/_image.astro.mjs | 2 + .../dist/server/pages/api/hook.astro.mjs | 34 + .../pages/api/test-direct-step-call.astro.mjs | 22 + .../dist/server/pages/api/trigger.astro.mjs | 341 + .../astro/dist/server/pages/index.astro.mjs | 1 + workbench/astro/dist/server/renderers.mjs | 3 + workbench/astro/src/lib/_workflows.ts | 26 + workbench/example/workflows/7_full.ts | 18 +- .../nextjs-turbopack/app/api/trigger/route.ts | 52 +- .../nextjs-webpack/app/api/trigger/route.ts | 54 +- .../src/routes/api/trigger/+server.ts | 54 +- .../sveltekit/src/workflows/user-signup.ts | 18 +- workbench/vite/routes/api/hook.post.ts | 6 +- 47 files changed, 99867 insertions(+), 133 deletions(-) create mode 100644 workbench/astro/.astro/content-assets.mjs create mode 100644 workbench/astro/.astro/content-modules.mjs create mode 100644 workbench/astro/.astro/content.d.ts create mode 100644 workbench/astro/.astro/data-store.json create mode 100644 workbench/astro/.astro/settings.json create mode 100644 workbench/astro/.astro/types.d.ts create mode 100644 workbench/astro/dist/client/favicon.svg create mode 100644 workbench/astro/dist/client/index.html create mode 100644 workbench/astro/dist/server/_@astrojs-ssr-adapter.mjs create mode 100644 workbench/astro/dist/server/_noop-middleware.mjs create mode 100644 workbench/astro/dist/server/chunks/99_e2e_DTaFFPMr.mjs create mode 100644 workbench/astro/dist/server/chunks/_@astrojs-ssr-adapter_9__r_ZjJ.mjs create mode 100644 workbench/astro/dist/server/chunks/_commonjsHelpers_BFTU3MAI.mjs create mode 100644 workbench/astro/dist/server/chunks/astro-designed-error-pages_pFA87nEA.mjs create mode 100644 workbench/astro/dist/server/chunks/astro/server_DhWKww_t.mjs create mode 100644 workbench/astro/dist/server/chunks/fs-lite_COtHaKzy.mjs create mode 100644 workbench/astro/dist/server/chunks/index_DqQ8k47W.mjs create mode 100644 workbench/astro/dist/server/chunks/index_ePTMDSOu.mjs create mode 100644 workbench/astro/dist/server/chunks/node_C2n6Z2oQ.mjs create mode 100644 workbench/astro/dist/server/chunks/remote_OOD9OFqU.mjs create mode 100644 workbench/astro/dist/server/chunks/resume-hook_BHshEMMl.mjs create mode 100644 workbench/astro/dist/server/chunks/runtime_CxdH0OC2.mjs create mode 100644 workbench/astro/dist/server/chunks/sharp_CR567j69.mjs create mode 100644 workbench/astro/dist/server/chunks/token-util_8GTOk-OQ.mjs create mode 100644 workbench/astro/dist/server/chunks/token-util_D6r3xWR2.mjs create mode 100644 workbench/astro/dist/server/chunks/token_CrOFk7pc.mjs create mode 100644 workbench/astro/dist/server/entry.mjs create mode 100644 workbench/astro/dist/server/manifest_Dl93wae-.mjs create mode 100644 workbench/astro/dist/server/noop-entrypoint.mjs create mode 100644 workbench/astro/dist/server/pages/.well-known/workflow/v1/flow.astro.mjs create mode 100644 workbench/astro/dist/server/pages/.well-known/workflow/v1/step.astro.mjs create mode 100644 workbench/astro/dist/server/pages/.well-known/workflow/v1/webhook/_token_.astro.mjs create mode 100644 workbench/astro/dist/server/pages/_image.astro.mjs create mode 100644 workbench/astro/dist/server/pages/api/hook.astro.mjs create mode 100644 workbench/astro/dist/server/pages/api/test-direct-step-call.astro.mjs create mode 100644 workbench/astro/dist/server/pages/api/trigger.astro.mjs create mode 100644 workbench/astro/dist/server/pages/index.astro.mjs create mode 100644 workbench/astro/dist/server/renderers.mjs create mode 100644 workbench/astro/src/lib/_workflows.ts diff --git a/packages/sveltekit/src/builder.ts b/packages/sveltekit/src/builder.ts index 52b4c8895..8e4b4dd5b 100644 --- a/packages/sveltekit/src/builder.ts +++ b/packages/sveltekit/src/builder.ts @@ -1,7 +1,7 @@ -import { constants } from 'node:fs'; -import { access, mkdir, readFile, stat, writeFile } from 'node:fs/promises'; -import { join, resolve } from 'node:path'; -import { BaseBuilder, type SvelteKitConfig } from '@workflow/builders'; +import { constants } from "node:fs"; +import { access, mkdir, readFile, stat, writeFile } from "node:fs/promises"; +import { join, resolve } from "node:path"; +import { BaseBuilder, type SvelteKitConfig } from "@workflow/builders"; // Helper function code for converting SvelteKit requests to standard Request objects const SVELTEKIT_REQUEST_CONVERTER = ` @@ -23,11 +23,11 @@ export class SvelteKitBuilder extends BaseBuilder { super({ ...config, - dirs: ['workflows', 'src/workflows', 'routes', 'src/routes'], - buildTarget: 'sveltekit' as const, - stepsBundlePath: '', // unused in base - workflowsBundlePath: '', // unused in base - webhookBundlePath: '', // unused in base + dirs: ["workflows", "src/workflows", "routes", "src/routes"], + buildTarget: "sveltekit" as const, + stepsBundlePath: "", // unused in base + workflowsBundlePath: "", // unused in base + webhookBundlePath: "", // unused in base workingDir, }); } @@ -35,14 +35,14 @@ export class SvelteKitBuilder extends BaseBuilder { override async build(): Promise { // Find SvelteKit routes directory (src/routes or routes) const routesDir = await this.findRoutesDirectory(); - const workflowGeneratedDir = join(routesDir, '.well-known/workflow/v1'); + const workflowGeneratedDir = join(routesDir, ".well-known/workflow/v1"); // Ensure output directories exist await mkdir(workflowGeneratedDir, { recursive: true }); // Add .gitignore to exclude generated files from version control if (process.env.VERCEL_DEPLOYMENT_ID === undefined) { - await writeFile(join(workflowGeneratedDir, '.gitignore'), '*'); + await writeFile(join(workflowGeneratedDir, ".gitignore"), "*"); } // Get workflow and step files to bundle @@ -74,21 +74,21 @@ export class SvelteKitBuilder extends BaseBuilder { tsPaths?: Record; }) { // Create steps route: .well-known/workflow/v1/step/+server.js - const stepsRouteDir = join(workflowGeneratedDir, 'step'); + const stepsRouteDir = join(workflowGeneratedDir, "step"); await mkdir(stepsRouteDir, { recursive: true }); await this.createStepsBundle({ - format: 'esm', + format: "esm", inputFiles, - outfile: join(stepsRouteDir, '+server.js'), + outfile: join(stepsRouteDir, "+server.js"), externalizeNonSteps: true, tsBaseUrl, tsPaths, }); // Post-process the generated file to wrap with SvelteKit request converter - const stepsRouteFile = join(stepsRouteDir, '+server.js'); - let stepsRouteContent = await readFile(stepsRouteFile, 'utf-8'); + const stepsRouteFile = join(stepsRouteDir, "+server.js"); + let stepsRouteContent = await readFile(stepsRouteFile, "utf-8"); // Replace the default export with SvelteKit-compatible handler stepsRouteContent = stepsRouteContent.replace( @@ -97,7 +97,7 @@ export class SvelteKitBuilder extends BaseBuilder { export const POST = async ({request}) => { const normalRequest = await convertSvelteKitRequest(request); return stepEntrypoint(normalRequest); -}` +}`, ); await writeFile(stepsRouteFile, stepsRouteContent); @@ -115,12 +115,12 @@ export const POST = async ({request}) => { tsPaths?: Record; }) { // Create workflows route: .well-known/workflow/v1/flow/+server.js - const workflowsRouteDir = join(workflowGeneratedDir, 'flow'); + const workflowsRouteDir = join(workflowGeneratedDir, "flow"); await mkdir(workflowsRouteDir, { recursive: true }); await this.createWorkflowsBundle({ - format: 'esm', - outfile: join(workflowsRouteDir, '+server.js'), + format: "esm", + outfile: join(workflowsRouteDir, "+server.js"), bundleFinalOutput: false, inputFiles, tsBaseUrl, @@ -128,8 +128,8 @@ export const POST = async ({request}) => { }); // Post-process the generated file to wrap with SvelteKit request converter - const workflowsRouteFile = join(workflowsRouteDir, '+server.js'); - let workflowsRouteContent = await readFile(workflowsRouteFile, 'utf-8'); + const workflowsRouteFile = join(workflowsRouteDir, "+server.js"); + let workflowsRouteContent = await readFile(workflowsRouteFile, "utf-8"); // Replace the default export with SvelteKit-compatible handler workflowsRouteContent = workflowsRouteContent.replace( @@ -138,7 +138,7 @@ export const POST = async ({request}) => { export const POST = async ({request}) => { const normalRequest = await convertSvelteKitRequest(request); return workflowEntrypoint(workflowCode)(normalRequest); -}` +}`, ); await writeFile(workflowsRouteFile, workflowsRouteContent); } @@ -151,7 +151,7 @@ export const POST = async ({request}) => { // Create webhook route: .well-known/workflow/v1/webhook/[token]/+server.js const webhookRouteFile = join( workflowGeneratedDir, - 'webhook/[token]/+server.js' + "webhook/[token]/+server.js", ); await this.createWebhookBundle({ @@ -160,18 +160,18 @@ export const POST = async ({request}) => { }); // Post-process the generated file to wrap with SvelteKit request converter - let webhookRouteContent = await readFile(webhookRouteFile, 'utf-8'); + let webhookRouteContent = await readFile(webhookRouteFile, "utf-8"); // Update handler signature to accept token as parameter webhookRouteContent = webhookRouteContent.replace( /async function handler\(request\) \{[\s\S]*?const token = decodeURIComponent\(pathParts\[pathParts\.length - 1\]\);/, - `async function handler(request, token) {` + `async function handler(request, token) {`, ); // Remove the URL parsing code since we get token from params webhookRouteContent = webhookRouteContent.replace( /const url = new URL\(request\.url\);[\s\S]*?const pathParts = url\.pathname\.split\('\/'\);[\s\S]*?\n/, - '' + "", ); // Replace all HTTP method exports with SvelteKit-compatible handlers @@ -190,15 +190,15 @@ export const PUT = createSvelteKitHandler('PUT'); export const PATCH = createSvelteKitHandler('PATCH'); export const DELETE = createSvelteKitHandler('DELETE'); export const HEAD = createSvelteKitHandler('HEAD'); -export const OPTIONS = createSvelteKitHandler('OPTIONS');` +export const OPTIONS = createSvelteKitHandler('OPTIONS');`, ); await writeFile(webhookRouteFile, webhookRouteContent); } private async findRoutesDirectory(): Promise { - const routesDir = resolve(this.config.workingDir, 'src/routes'); - const rootRoutesDir = resolve(this.config.workingDir, 'routes'); + const routesDir = resolve(this.config.workingDir, "src/routes"); + const rootRoutesDir = resolve(this.config.workingDir, "routes"); // Try src/routes first (standard SvelteKit convention) try { @@ -215,15 +215,36 @@ export const OPTIONS = createSvelteKitHandler('OPTIONS');` const rootRoutesStats = await stat(rootRoutesDir); if (!rootRoutesStats.isDirectory()) { throw new Error( - `Path exists but is not a directory: ${rootRoutesDir}` + `Path exists but is not a directory: ${rootRoutesDir}`, ); } return rootRoutesDir; } catch { throw new Error( - 'Could not find SvelteKit routes directory. Expected either "src/routes" or "routes" to exist.' + 'Could not find SvelteKit routes directory. Expected either "src/routes" or "routes" to exist.', ); } } } } + +/** + * Gets the list of directories to scan for workflow files. + */ +export function getWorkflowDirs(options?: { dirs?: string[] }): string[] { + return unique([ + // User-provided directories take precedence + ...(options?.dirs ?? []), + // Scan routes directories (like Next.js does with app/pages directories) + // This allows workflows to be placed anywhere in the routes tree + "routes", + "src/routes", + // Also scan dedicated workflow directories for organization + "workflows", + "src/workflows", + ]).sort(); +} + +function unique(array: T[]): T[] { + return Array.from(new Set(array)); +} diff --git a/packages/sveltekit/src/plugin.ts b/packages/sveltekit/src/plugin.ts index 0041bddee..b9dc13d19 100644 --- a/packages/sveltekit/src/plugin.ts +++ b/packages/sveltekit/src/plugin.ts @@ -4,7 +4,15 @@ import { resolveModulePath } from 'exsolve'; import type { HotUpdateOptions, Plugin } from 'vite'; import { SvelteKitBuilder } from './builder.js'; -export function workflowPlugin(): Plugin { +export interface WorkflowPluginOptions { + /** + * Directories to scan for workflow files. + * If not specified, defaults to ['workflows', 'src/workflows', 'routes', 'src/routes'] + */ + dirs?: string[]; +} + +export function workflowPlugin(options?: WorkflowPluginOptions): Plugin { let builder: SvelteKitBuilder; return { @@ -89,7 +97,9 @@ export function workflowPlugin(): Plugin { }, configResolved() { - builder = new SvelteKitBuilder(); + builder = new SvelteKitBuilder({ + dirs: options?.dirs, + }); }, // TODO: Move this to @workflow/vite or something since this is vite specific diff --git a/workbench/astro/.astro/content-assets.mjs b/workbench/astro/.astro/content-assets.mjs new file mode 100644 index 000000000..2b8b8234b --- /dev/null +++ b/workbench/astro/.astro/content-assets.mjs @@ -0,0 +1 @@ +export default new Map(); \ No newline at end of file diff --git a/workbench/astro/.astro/content-modules.mjs b/workbench/astro/.astro/content-modules.mjs new file mode 100644 index 000000000..2b8b8234b --- /dev/null +++ b/workbench/astro/.astro/content-modules.mjs @@ -0,0 +1 @@ +export default new Map(); \ No newline at end of file diff --git a/workbench/astro/.astro/content.d.ts b/workbench/astro/.astro/content.d.ts new file mode 100644 index 000000000..c0082cc81 --- /dev/null +++ b/workbench/astro/.astro/content.d.ts @@ -0,0 +1,199 @@ +declare module 'astro:content' { + export interface RenderResult { + Content: import('astro/runtime/server/index.js').AstroComponentFactory; + headings: import('astro').MarkdownHeading[]; + remarkPluginFrontmatter: Record; + } + interface Render { + '.md': Promise; + } + + export interface RenderedContent { + html: string; + metadata?: { + imagePaths: Array; + [key: string]: unknown; + }; + } +} + +declare module 'astro:content' { + type Flatten = T extends { [K: string]: infer U } ? U : never; + + export type CollectionKey = keyof AnyEntryMap; + export type CollectionEntry = Flatten; + + export type ContentCollectionKey = keyof ContentEntryMap; + export type DataCollectionKey = keyof DataEntryMap; + + type AllValuesOf = T extends any ? T[keyof T] : never; + type ValidContentEntrySlug = AllValuesOf< + ContentEntryMap[C] + >['slug']; + + export type ReferenceDataEntry< + C extends CollectionKey, + E extends keyof DataEntryMap[C] = string, + > = { + collection: C; + id: E; + }; + export type ReferenceContentEntry< + C extends keyof ContentEntryMap, + E extends ValidContentEntrySlug | (string & {}) = string, + > = { + collection: C; + slug: E; + }; + export type ReferenceLiveEntry = { + collection: C; + id: string; + }; + + /** @deprecated Use `getEntry` instead. */ + export function getEntryBySlug< + C extends keyof ContentEntryMap, + E extends ValidContentEntrySlug | (string & {}), + >( + collection: C, + // Note that this has to accept a regular string too, for SSR + entrySlug: E, + ): E extends ValidContentEntrySlug + ? Promise> + : Promise | undefined>; + + /** @deprecated Use `getEntry` instead. */ + export function getDataEntryById( + collection: C, + entryId: E, + ): Promise>; + + export function getCollection>( + collection: C, + filter?: (entry: CollectionEntry) => entry is E, + ): Promise; + export function getCollection( + collection: C, + filter?: (entry: CollectionEntry) => unknown, + ): Promise[]>; + + export function getLiveCollection( + collection: C, + filter?: LiveLoaderCollectionFilterType, + ): Promise< + import('astro').LiveDataCollectionResult, LiveLoaderErrorType> + >; + + export function getEntry< + C extends keyof ContentEntryMap, + E extends ValidContentEntrySlug | (string & {}), + >( + entry: ReferenceContentEntry, + ): E extends ValidContentEntrySlug + ? Promise> + : Promise | undefined>; + export function getEntry< + C extends keyof DataEntryMap, + E extends keyof DataEntryMap[C] | (string & {}), + >( + entry: ReferenceDataEntry, + ): E extends keyof DataEntryMap[C] + ? Promise + : Promise | undefined>; + export function getEntry< + C extends keyof ContentEntryMap, + E extends ValidContentEntrySlug | (string & {}), + >( + collection: C, + slug: E, + ): E extends ValidContentEntrySlug + ? Promise> + : Promise | undefined>; + export function getEntry< + C extends keyof DataEntryMap, + E extends keyof DataEntryMap[C] | (string & {}), + >( + collection: C, + id: E, + ): E extends keyof DataEntryMap[C] + ? string extends keyof DataEntryMap[C] + ? Promise | undefined + : Promise + : Promise | undefined>; + export function getLiveEntry( + collection: C, + filter: string | LiveLoaderEntryFilterType, + ): Promise, LiveLoaderErrorType>>; + + /** Resolve an array of entry references from the same collection */ + export function getEntries( + entries: ReferenceContentEntry>[], + ): Promise[]>; + export function getEntries( + entries: ReferenceDataEntry[], + ): Promise[]>; + + export function render( + entry: AnyEntryMap[C][string], + ): Promise; + + export function reference( + collection: C, + ): import('astro/zod').ZodEffects< + import('astro/zod').ZodString, + C extends keyof ContentEntryMap + ? ReferenceContentEntry> + : ReferenceDataEntry + >; + // Allow generic `string` to avoid excessive type errors in the config + // if `dev` is not running to update as you edit. + // Invalid collection names will be caught at build time. + export function reference( + collection: C, + ): import('astro/zod').ZodEffects; + + type ReturnTypeOrOriginal = T extends (...args: any[]) => infer R ? R : T; + type InferEntrySchema = import('astro/zod').infer< + ReturnTypeOrOriginal['schema']> + >; + + type ContentEntryMap = { + + }; + + type DataEntryMap = { + + }; + + type AnyEntryMap = ContentEntryMap & DataEntryMap; + + type ExtractLoaderTypes = T extends import('astro/loaders').LiveLoader< + infer TData, + infer TEntryFilter, + infer TCollectionFilter, + infer TError + > + ? { data: TData; entryFilter: TEntryFilter; collectionFilter: TCollectionFilter; error: TError } + : { data: never; entryFilter: never; collectionFilter: never; error: never }; + type ExtractDataType = ExtractLoaderTypes['data']; + type ExtractEntryFilterType = ExtractLoaderTypes['entryFilter']; + type ExtractCollectionFilterType = ExtractLoaderTypes['collectionFilter']; + type ExtractErrorType = ExtractLoaderTypes['error']; + + type LiveLoaderDataType = + LiveContentConfig['collections'][C]['schema'] extends undefined + ? ExtractDataType + : import('astro/zod').infer< + Exclude + >; + type LiveLoaderEntryFilterType = + ExtractEntryFilterType; + type LiveLoaderCollectionFilterType = + ExtractCollectionFilterType; + type LiveLoaderErrorType = ExtractErrorType< + LiveContentConfig['collections'][C]['loader'] + >; + + export type ContentConfig = typeof import("../src/content.config.mjs"); + export type LiveContentConfig = never; +} diff --git a/workbench/astro/.astro/data-store.json b/workbench/astro/.astro/data-store.json new file mode 100644 index 000000000..44b17ba6a --- /dev/null +++ b/workbench/astro/.astro/data-store.json @@ -0,0 +1 @@ +[["Map",1,2],"meta::meta",["Map",3,4,5,6],"astro-version","5.15.6","astro-config-digest","{\"root\":{},\"srcDir\":{},\"publicDir\":{},\"outDir\":{},\"cacheDir\":{},\"compressHTML\":true,\"base\":\"/\",\"trailingSlash\":\"ignore\",\"output\":\"static\",\"scopedStyleStrategy\":\"attribute\",\"build\":{\"format\":\"directory\",\"client\":{},\"server\":{},\"assets\":\"_astro\",\"serverEntry\":\"entry.mjs\",\"redirects\":false,\"inlineStylesheets\":\"auto\",\"concurrency\":1},\"server\":{\"open\":false,\"host\":false,\"port\":4321,\"streaming\":true,\"allowedHosts\":[]},\"redirects\":{},\"image\":{\"endpoint\":{\"route\":\"/_image\",\"entrypoint\":\"astro/assets/endpoint/dev\"},\"service\":{\"entrypoint\":\"astro/assets/services/sharp\",\"config\":{}},\"domains\":[],\"remotePatterns\":[],\"responsiveStyles\":false},\"devToolbar\":{\"enabled\":true},\"markdown\":{\"syntaxHighlight\":{\"type\":\"shiki\",\"excludeLangs\":[\"math\"]},\"shikiConfig\":{\"langs\":[],\"langAlias\":{},\"theme\":\"github-dark\",\"themes\":{},\"wrap\":false,\"transformers\":[]},\"remarkPlugins\":[],\"rehypePlugins\":[],\"remarkRehype\":{},\"gfm\":true,\"smartypants\":true},\"security\":{\"checkOrigin\":true,\"allowedDomains\":[]},\"env\":{\"schema\":{},\"validateSecrets\":false},\"experimental\":{\"clientPrerender\":false,\"contentIntellisense\":false,\"headingIdCompat\":false,\"preserveScriptOrder\":false,\"liveContentCollections\":false,\"csp\":false,\"staticImportMetaEnv\":false,\"chromeDevtoolsWorkspace\":false,\"failOnPrerenderConflict\":false},\"legacy\":{\"collections\":false},\"session\":{\"driver\":\"fs-lite\",\"options\":{\"base\":\"/Users/adrianlam/GitHub/workflow/workbench/astro/node_modules/.astro/sessions\"}}}"] \ No newline at end of file diff --git a/workbench/astro/.astro/settings.json b/workbench/astro/.astro/settings.json new file mode 100644 index 000000000..6b79318ed --- /dev/null +++ b/workbench/astro/.astro/settings.json @@ -0,0 +1,5 @@ +{ + "_variables": { + "lastUpdateCheck": 1763142538065 + } +} \ No newline at end of file diff --git a/workbench/astro/.astro/types.d.ts b/workbench/astro/.astro/types.d.ts new file mode 100644 index 000000000..f964fe0cf --- /dev/null +++ b/workbench/astro/.astro/types.d.ts @@ -0,0 +1 @@ +/// diff --git a/workbench/astro/dist/client/favicon.svg b/workbench/astro/dist/client/favicon.svg new file mode 100644 index 000000000..f157bd1c5 --- /dev/null +++ b/workbench/astro/dist/client/favicon.svg @@ -0,0 +1,9 @@ + + + + diff --git a/workbench/astro/dist/client/index.html b/workbench/astro/dist/client/index.html new file mode 100644 index 000000000..0e372499c --- /dev/null +++ b/workbench/astro/dist/client/index.html @@ -0,0 +1 @@ + Astro

Astro

\ No newline at end of file diff --git a/workbench/astro/dist/server/_@astrojs-ssr-adapter.mjs b/workbench/astro/dist/server/_@astrojs-ssr-adapter.mjs new file mode 100644 index 000000000..ccb0b6fbf --- /dev/null +++ b/workbench/astro/dist/server/_@astrojs-ssr-adapter.mjs @@ -0,0 +1 @@ +export { c as createExports, a as start } from './chunks/_@astrojs-ssr-adapter_9__r_ZjJ.mjs'; diff --git a/workbench/astro/dist/server/_noop-middleware.mjs b/workbench/astro/dist/server/_noop-middleware.mjs new file mode 100644 index 000000000..84424b01b --- /dev/null +++ b/workbench/astro/dist/server/_noop-middleware.mjs @@ -0,0 +1,3 @@ +const onRequest = (_, next) => next(); + +export { onRequest }; diff --git a/workbench/astro/dist/server/chunks/99_e2e_DTaFFPMr.mjs b/workbench/astro/dist/server/chunks/99_e2e_DTaFFPMr.mjs new file mode 100644 index 000000000..8f79127c4 --- /dev/null +++ b/workbench/astro/dist/server/chunks/99_e2e_DTaFFPMr.mjs @@ -0,0 +1,117 @@ +async function add(a, b) { + return a + b; +} +async function addTenWorkflow(input) { + throw new Error("You attempted to execute workflow addTenWorkflow function directly. To start a workflow, use start(addTenWorkflow) from workflow/api"); +} +addTenWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//addTenWorkflow"; +async function nestedErrorWorkflow() { + throw new Error("You attempted to execute workflow nestedErrorWorkflow function directly. To start a workflow, use start(nestedErrorWorkflow) from workflow/api"); +} +nestedErrorWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//nestedErrorWorkflow"; +async function promiseAllWorkflow() { + throw new Error("You attempted to execute workflow promiseAllWorkflow function directly. To start a workflow, use start(promiseAllWorkflow) from workflow/api"); +} +promiseAllWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//promiseAllWorkflow"; +async function promiseRaceWorkflow() { + throw new Error("You attempted to execute workflow promiseRaceWorkflow function directly. To start a workflow, use start(promiseRaceWorkflow) from workflow/api"); +} +promiseRaceWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//promiseRaceWorkflow"; +async function promiseAnyWorkflow() { + throw new Error("You attempted to execute workflow promiseAnyWorkflow function directly. To start a workflow, use start(promiseAnyWorkflow) from workflow/api"); +} +promiseAnyWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//promiseAnyWorkflow"; +async function readableStreamWorkflow() { + throw new Error("You attempted to execute workflow readableStreamWorkflow function directly. To start a workflow, use start(readableStreamWorkflow) from workflow/api"); +} +readableStreamWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//readableStreamWorkflow"; +async function hookWorkflow(token, customData) { + throw new Error("You attempted to execute workflow hookWorkflow function directly. To start a workflow, use start(hookWorkflow) from workflow/api"); +} +hookWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//hookWorkflow"; +async function webhookWorkflow(token, token2, token3) { + throw new Error("You attempted to execute workflow webhookWorkflow function directly. To start a workflow, use start(webhookWorkflow) from workflow/api"); +} +webhookWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//webhookWorkflow"; +async function sleepingWorkflow() { + throw new Error("You attempted to execute workflow sleepingWorkflow function directly. To start a workflow, use start(sleepingWorkflow) from workflow/api"); +} +sleepingWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//sleepingWorkflow"; +async function nullByteWorkflow() { + throw new Error("You attempted to execute workflow nullByteWorkflow function directly. To start a workflow, use start(nullByteWorkflow) from workflow/api"); +} +nullByteWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//nullByteWorkflow"; +async function workflowAndStepMetadataWorkflow() { + throw new Error("You attempted to execute workflow workflowAndStepMetadataWorkflow function directly. To start a workflow, use start(workflowAndStepMetadataWorkflow) from workflow/api"); +} +workflowAndStepMetadataWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//workflowAndStepMetadataWorkflow"; +async function outputStreamWorkflow() { + throw new Error("You attempted to execute workflow outputStreamWorkflow function directly. To start a workflow, use start(outputStreamWorkflow) from workflow/api"); +} +outputStreamWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//outputStreamWorkflow"; +async function outputStreamInsideStepWorkflow() { + throw new Error("You attempted to execute workflow outputStreamInsideStepWorkflow function directly. To start a workflow, use start(outputStreamInsideStepWorkflow) from workflow/api"); +} +outputStreamInsideStepWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//outputStreamInsideStepWorkflow"; +async function fetchWorkflow() { + throw new Error("You attempted to execute workflow fetchWorkflow function directly. To start a workflow, use start(fetchWorkflow) from workflow/api"); +} +fetchWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//fetchWorkflow"; +async function promiseRaceStressTestDelayStep(dur, resp) { + console.log(`sleep`, resp, `/`, dur); + await new Promise((resolve)=>setTimeout(resolve, dur)); + console.log(resp, `done`); + return resp; +} +async function promiseRaceStressTestWorkflow() { + throw new Error("You attempted to execute workflow promiseRaceStressTestWorkflow function directly. To start a workflow, use start(promiseRaceStressTestWorkflow) from workflow/api"); +} +promiseRaceStressTestWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//promiseRaceStressTestWorkflow"; +async function retryAttemptCounterWorkflow() { + throw new Error("You attempted to execute workflow retryAttemptCounterWorkflow function directly. To start a workflow, use start(retryAttemptCounterWorkflow) from workflow/api"); +} +retryAttemptCounterWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//retryAttemptCounterWorkflow"; +async function crossFileErrorWorkflow() { + throw new Error("You attempted to execute workflow crossFileErrorWorkflow function directly. To start a workflow, use start(crossFileErrorWorkflow) from workflow/api"); +} +crossFileErrorWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//crossFileErrorWorkflow"; +async function retryableAndFatalErrorWorkflow() { + throw new Error("You attempted to execute workflow retryableAndFatalErrorWorkflow function directly. To start a workflow, use start(retryableAndFatalErrorWorkflow) from workflow/api"); +} +retryableAndFatalErrorWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//retryableAndFatalErrorWorkflow"; +async function hookCleanupTestWorkflow(token, customData) { + throw new Error("You attempted to execute workflow hookCleanupTestWorkflow function directly. To start a workflow, use start(hookCleanupTestWorkflow) from workflow/api"); +} +hookCleanupTestWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//hookCleanupTestWorkflow"; +async function stepFunctionPassingWorkflow() { + throw new Error("You attempted to execute workflow stepFunctionPassingWorkflow function directly. To start a workflow, use start(stepFunctionPassingWorkflow) from workflow/api"); +} +stepFunctionPassingWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//stepFunctionPassingWorkflow"; + +const workflow_99_e2e = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ + __proto__: null, + add, + addTenWorkflow, + crossFileErrorWorkflow, + fetchWorkflow, + hookCleanupTestWorkflow, + hookWorkflow, + nestedErrorWorkflow, + nullByteWorkflow, + outputStreamInsideStepWorkflow, + outputStreamWorkflow, + promiseAllWorkflow, + promiseAnyWorkflow, + promiseRaceStressTestDelayStep, + promiseRaceStressTestWorkflow, + promiseRaceWorkflow, + readableStreamWorkflow, + retryAttemptCounterWorkflow, + retryableAndFatalErrorWorkflow, + sleepingWorkflow, + stepFunctionPassingWorkflow, + webhookWorkflow, + workflowAndStepMetadataWorkflow +}, Symbol.toStringTag, { value: 'Module' })); + +export { add as a, workflow_99_e2e as w }; diff --git a/workbench/astro/dist/server/chunks/_@astrojs-ssr-adapter_9__r_ZjJ.mjs b/workbench/astro/dist/server/chunks/_@astrojs-ssr-adapter_9__r_ZjJ.mjs new file mode 100644 index 000000000..b880e3b9e --- /dev/null +++ b/workbench/astro/dist/server/chunks/_@astrojs-ssr-adapter_9__r_ZjJ.mjs @@ -0,0 +1,10521 @@ +import { n as decryptString, o as createSlotValueFromString, p as isAstroComponentFactory, q as renderComponent, r as renderTemplate, R as ROUTE_TYPE_HEADER, v as REROUTE_DIRECTIVE_HEADER, A as AstroError, w as i18nNoLocaleFoundInPath, x as ResponseSentError, y as ActionNotFoundError, z as MiddlewareNoDataOrNextCalled, B as MiddlewareNotAResponse, C as originPathnameSymbol, D as RewriteWithBodyUsed, G as GetStaticPathsRequired, H as InvalidGetStaticPathsReturn, J as InvalidGetStaticPathsEntry, K as GetStaticPathsExpectedParams, O as GetStaticPathsInvalidRouteParam, P as PageNumberParamNotFound, Q as DEFAULT_404_COMPONENT, S as NoMatchingStaticPathFound, T as PrerenderDynamicEndpointPathCollide, V as ReservedSlotName, W as renderSlotToString, X as renderJSX, Y as chunkToString, Z as isRenderInstruction, _ as ForbiddenRewrite, $ as SessionStorageInitError, a0 as SessionStorageSaveError, a1 as ASTRO_VERSION, a2 as CspNotEnabled, a3 as LocalsReassigned, a4 as generateCspDigest, a5 as PrerenderClientAddressNotAvailable, a6 as clientAddressSymbol, a7 as ClientAddressNotAvailable, a8 as StaticClientAddressNotAvailable, a9 as AstroResponseHeadersReassigned, aa as responseSentSymbol$1, ab as renderPage, ac as REWRITE_DIRECTIVE_HEADER_KEY, ad as REWRITE_DIRECTIVE_HEADER_VALUE, ae as renderEndpoint, af as LocalsNotAnObject, ag as REROUTABLE_STATUS_CODES, ah as nodeRequestAbortControllerCleanupSymbol } from './astro/server_DhWKww_t.mjs'; +import 'clsx'; +import { serialize, parse } from 'cookie'; +import { A as ActionError, d as deserializeActionResult, s as serializeActionResult, a as ACTION_RPC_ROUTE_PATTERN, b as ACTION_QUERY_PARAMS, g as getActionQueryString, D as DEFAULT_404_ROUTE, c as default404Instance, N as NOOP_MIDDLEWARE_FN, e as ensure404Route } from './astro-designed-error-pages_pFA87nEA.mjs'; +import 'es-module-lexer'; +import require$$0$3 from 'node:buffer'; +import crypto$1 from 'node:crypto'; +import fs, { existsSync, readFileSync } from 'node:fs'; +import { Http2ServerResponse } from 'node:http2'; +import { c as appendForwardSlash$1, j as joinPaths, f as fileExtension, s as slash, p as prependForwardSlash$1, d as removeTrailingForwardSlash, t as trimSlashes, m as matchPattern, e as isInternalPath, g as collapseDuplicateTrailingSlashes, h as hasFileExtension } from './remote_OOD9OFqU.mjs'; +import colors from 'picocolors'; +import { unflatten as unflatten$1, stringify as stringify$1 } from 'devalue'; +import { createStorage, builtinDrivers } from 'unstorage'; +import { AsyncLocalStorage } from 'node:async_hooks'; +import require$$2 from 'node:http'; +import https from 'node:https'; +import { g as getDefaultExportFromCjs } from './_commonjsHelpers_BFTU3MAI.mjs'; +import os from 'node:os'; +import path from 'node:path'; +import url from 'node:url'; +import require$$0$4 from 'path'; +import debug$1 from 'debug'; +import require$$0$6 from 'crypto'; +import require$$0$5 from 'fs'; +import ms from 'ms'; +import require$$13 from 'stream'; +import require$$14 from 'util'; + +function shouldAppendForwardSlash(trailingSlash, buildFormat) { + switch (trailingSlash) { + case "always": + return true; + case "never": + return false; + case "ignore": { + switch (buildFormat) { + case "directory": + return true; + case "preserve": + case "file": + return false; + } + } + } +} + +function redirectIsExternal(redirect) { + if (typeof redirect === "string") { + return redirect.startsWith("http://") || redirect.startsWith("https://"); + } else { + return redirect.destination.startsWith("http://") || redirect.destination.startsWith("https://"); + } +} +async function renderRedirect(renderContext) { + const { + request: { method }, + routeData + } = renderContext; + const { redirect, redirectRoute } = routeData; + const status = redirectRoute && typeof redirect === "object" ? redirect.status : method === "GET" ? 301 : 308; + const headers = { location: encodeURI(redirectRouteGenerate(renderContext)) }; + if (redirect && redirectIsExternal(redirect)) { + if (typeof redirect === "string") { + return Response.redirect(redirect, status); + } else { + return Response.redirect(redirect.destination, status); + } + } + return new Response(null, { status, headers }); +} +function redirectRouteGenerate(renderContext) { + const { + params, + routeData: { redirect, redirectRoute } + } = renderContext; + if (typeof redirectRoute !== "undefined") { + return redirectRoute?.generate(params) || redirectRoute?.pathname || "/"; + } else if (typeof redirect === "string") { + if (redirectIsExternal(redirect)) { + return redirect; + } else { + let target = redirect; + for (const param of Object.keys(params)) { + const paramValue = params[param]; + target = target.replace(`[${param}]`, paramValue).replace(`[...${param}]`, paramValue); + } + return target; + } + } else if (typeof redirect === "undefined") { + return "/"; + } + return redirect.destination; +} + +const SERVER_ISLAND_ROUTE = "/_server-islands/[name]"; +const SERVER_ISLAND_COMPONENT = "_server-islands.astro"; +const SERVER_ISLAND_BASE_PREFIX = "_server-islands"; +function badRequest(reason) { + return new Response(null, { + status: 400, + statusText: "Bad request: " + reason + }); +} +async function getRequestData(request) { + switch (request.method) { + case "GET": { + const url = new URL(request.url); + const params = url.searchParams; + if (!params.has("s") || !params.has("e") || !params.has("p")) { + return badRequest("Missing required query parameters."); + } + const rawSlots = params.get("s"); + try { + return { + componentExport: params.get("e"), + encryptedProps: params.get("p"), + slots: JSON.parse(rawSlots) + }; + } catch { + return badRequest("Invalid slots format."); + } + } + case "POST": { + try { + const raw = await request.text(); + const data = JSON.parse(raw); + return data; + } catch { + return badRequest("Request format is invalid."); + } + } + default: { + return new Response(null, { status: 405 }); + } + } +} +function createEndpoint(manifest) { + const page = async (result) => { + const params = result.params; + if (!params.name) { + return new Response(null, { + status: 400, + statusText: "Bad request" + }); + } + const componentId = params.name; + const data = await getRequestData(result.request); + if (data instanceof Response) { + return data; + } + const imp = manifest.serverIslandMap?.get(componentId); + if (!imp) { + return new Response(null, { + status: 404, + statusText: "Not found" + }); + } + const key = await manifest.key; + const encryptedProps = data.encryptedProps; + const propString = encryptedProps === "" ? "{}" : await decryptString(key, encryptedProps); + const props = JSON.parse(propString); + const componentModule = await imp(); + let Component = componentModule[data.componentExport]; + const slots = {}; + for (const prop in data.slots) { + slots[prop] = createSlotValueFromString(data.slots[prop]); + } + result.response.headers.set("X-Robots-Tag", "noindex"); + if (isAstroComponentFactory(Component)) { + const ServerIsland = Component; + Component = function(...args) { + return ServerIsland.apply(this, args); + }; + Object.assign(Component, ServerIsland); + Component.propagation = "self"; + } + return renderTemplate`${renderComponent(result, "Component", Component, props, slots)}`; + }; + page.isAstroComponentFactory = true; + const instance = { + default: page, + partial: true + }; + return instance; +} + +function matchRoute(pathname, manifest) { + return manifest.routes.find((route) => { + return route.pattern.test(pathname) || route.fallbackRoutes.some((fallbackRoute) => fallbackRoute.pattern.test(pathname)); + }); +} +const ROUTE404_RE = /^\/404\/?$/; +const ROUTE500_RE = /^\/500\/?$/; +function isRoute404(route) { + return ROUTE404_RE.test(route); +} +function isRoute500(route) { + return ROUTE500_RE.test(route); +} +function isRoute404or500(route) { + return isRoute404(route.route) || isRoute500(route.route); +} +function isRouteServerIsland(route) { + return route.component === SERVER_ISLAND_COMPONENT; +} +function isRequestServerIsland(request, base = "") { + const url = new URL(request.url); + const pathname = base === "/" ? url.pathname.slice(base.length) : url.pathname.slice(base.length + 1); + return pathname.startsWith(SERVER_ISLAND_BASE_PREFIX); +} +function requestIs404Or500(request, base = "") { + const url = new URL(request.url); + const pathname = url.pathname.slice(base.length); + return isRoute404(pathname) || isRoute500(pathname); +} +function isRouteExternalRedirect(route) { + return !!(route.type === "redirect" && route.redirect && redirectIsExternal(route.redirect)); +} + +function createI18nMiddleware(i18n, base, trailingSlash, format) { + if (!i18n) return (_, next) => next(); + const payload = { + ...i18n, + trailingSlash, + base, + format}; + const _redirectToDefaultLocale = redirectToDefaultLocale(payload); + const _noFoundForNonLocaleRoute = notFound(payload); + const _requestHasLocale = requestHasLocale(payload.locales); + const _redirectToFallback = redirectToFallback(payload); + const prefixAlways = (context, response) => { + const url = context.url; + if (url.pathname === base + "/" || url.pathname === base) { + return _redirectToDefaultLocale(context); + } else if (!_requestHasLocale(context)) { + return _noFoundForNonLocaleRoute(context, response); + } + return void 0; + }; + const prefixOtherLocales = (context, response) => { + let pathnameContainsDefaultLocale = false; + const url = context.url; + for (const segment of url.pathname.split("/")) { + if (normalizeTheLocale(segment) === normalizeTheLocale(i18n.defaultLocale)) { + pathnameContainsDefaultLocale = true; + break; + } + } + if (pathnameContainsDefaultLocale) { + const newLocation = url.pathname.replace(`/${i18n.defaultLocale}`, ""); + response.headers.set("Location", newLocation); + return _noFoundForNonLocaleRoute(context); + } + return void 0; + }; + return async (context, next) => { + const response = await next(); + const type = response.headers.get(ROUTE_TYPE_HEADER); + const isReroute = response.headers.get(REROUTE_DIRECTIVE_HEADER); + if (isReroute === "no" && typeof i18n.fallback === "undefined") { + return response; + } + if (type !== "page" && type !== "fallback") { + return response; + } + if (requestIs404Or500(context.request, base)) { + return response; + } + if (isRequestServerIsland(context.request, base)) { + return response; + } + const { currentLocale } = context; + switch (i18n.strategy) { + // NOTE: theoretically, we should never hit this code path + case "manual": { + return response; + } + case "domains-prefix-other-locales": { + if (localeHasntDomain(i18n, currentLocale)) { + const result = prefixOtherLocales(context, response); + if (result) { + return result; + } + } + break; + } + case "pathname-prefix-other-locales": { + const result = prefixOtherLocales(context, response); + if (result) { + return result; + } + break; + } + case "domains-prefix-always-no-redirect": { + if (localeHasntDomain(i18n, currentLocale)) { + const result = _noFoundForNonLocaleRoute(context, response); + if (result) { + return result; + } + } + break; + } + case "pathname-prefix-always-no-redirect": { + const result = _noFoundForNonLocaleRoute(context, response); + if (result) { + return result; + } + break; + } + case "pathname-prefix-always": { + const result = prefixAlways(context, response); + if (result) { + return result; + } + break; + } + case "domains-prefix-always": { + if (localeHasntDomain(i18n, currentLocale)) { + const result = prefixAlways(context, response); + if (result) { + return result; + } + } + break; + } + } + return _redirectToFallback(context, response); + }; +} +function localeHasntDomain(i18n, currentLocale) { + for (const domainLocale of Object.values(i18n.domainLookupTable)) { + if (domainLocale === currentLocale) { + return false; + } + } + return true; +} + +function requestHasLocale(locales) { + return function(context) { + return pathHasLocale(context.url.pathname, locales); + }; +} +function pathHasLocale(path, locales) { + const segments = path.split("/").map(normalizeThePath); + for (const segment of segments) { + for (const locale of locales) { + if (typeof locale === "string") { + if (normalizeTheLocale(segment) === normalizeTheLocale(locale)) { + return true; + } + } else if (segment === locale.path) { + return true; + } + } + } + return false; +} +function getPathByLocale(locale, locales) { + for (const loopLocale of locales) { + if (typeof loopLocale === "string") { + if (loopLocale === locale) { + return loopLocale; + } + } else { + for (const code of loopLocale.codes) { + if (code === locale) { + return loopLocale.path; + } + } + } + } + throw new AstroError(i18nNoLocaleFoundInPath); +} +function normalizeTheLocale(locale) { + return locale.replaceAll("_", "-").toLowerCase(); +} +function normalizeThePath(path) { + return path.endsWith(".html") ? path.slice(0, -5) : path; +} +function getAllCodes(locales) { + const result = []; + for (const loopLocale of locales) { + if (typeof loopLocale === "string") { + result.push(loopLocale); + } else { + result.push(...loopLocale.codes); + } + } + return result; +} +function redirectToDefaultLocale({ + trailingSlash, + format, + base, + defaultLocale +}) { + return function(context, statusCode) { + if (shouldAppendForwardSlash(trailingSlash, format)) { + return context.redirect(`${appendForwardSlash$1(joinPaths(base, defaultLocale))}`, statusCode); + } else { + return context.redirect(`${joinPaths(base, defaultLocale)}`, statusCode); + } + }; +} +function notFound({ base, locales, fallback }) { + return function(context, response) { + if (response?.headers.get(REROUTE_DIRECTIVE_HEADER) === "no" && typeof fallback === "undefined") { + return response; + } + const url = context.url; + const isRoot = url.pathname === base + "/" || url.pathname === base; + if (!(isRoot || pathHasLocale(url.pathname, locales))) { + if (response) { + response.headers.set(REROUTE_DIRECTIVE_HEADER, "no"); + return new Response(response.body, { + status: 404, + headers: response.headers + }); + } else { + return new Response(null, { + status: 404, + headers: { + [REROUTE_DIRECTIVE_HEADER]: "no" + } + }); + } + } + return void 0; + }; +} +function redirectToFallback({ + fallback, + locales, + defaultLocale, + strategy, + base, + fallbackType +}) { + return async function(context, response) { + if (response.status >= 300 && fallback) { + const fallbackKeys = fallback ? Object.keys(fallback) : []; + const segments = context.url.pathname.split("/"); + const urlLocale = segments.find((segment) => { + for (const locale of locales) { + if (typeof locale === "string") { + if (locale === segment) { + return true; + } + } else if (locale.path === segment) { + return true; + } + } + return false; + }); + if (urlLocale && fallbackKeys.includes(urlLocale)) { + const fallbackLocale = fallback[urlLocale]; + const pathFallbackLocale = getPathByLocale(fallbackLocale, locales); + let newPathname; + if (pathFallbackLocale === defaultLocale && strategy === "pathname-prefix-other-locales") { + if (context.url.pathname.includes(`${base}`)) { + newPathname = context.url.pathname.replace(`/${urlLocale}`, ``); + if (newPathname === "") { + newPathname = "/"; + } + } else { + newPathname = context.url.pathname.replace(`/${urlLocale}`, `/`); + } + } else { + newPathname = context.url.pathname.replace(`/${urlLocale}`, `/${pathFallbackLocale}`); + } + if (fallbackType === "rewrite") { + return await context.rewrite(newPathname + context.url.search); + } else { + return context.redirect(newPathname + context.url.search); + } + } + } + return response; + }; +} + +const DELETED_EXPIRATION = /* @__PURE__ */ new Date(0); +const DELETED_VALUE = "deleted"; +const responseSentSymbol = Symbol.for("astro.responseSent"); +const identity = (value) => value; +class AstroCookie { + constructor(value) { + this.value = value; + } + json() { + if (this.value === void 0) { + throw new Error(`Cannot convert undefined to an object.`); + } + return JSON.parse(this.value); + } + number() { + return Number(this.value); + } + boolean() { + if (this.value === "false") return false; + if (this.value === "0") return false; + return Boolean(this.value); + } +} +class AstroCookies { + #request; + #requestValues; + #outgoing; + #consumed; + constructor(request) { + this.#request = request; + this.#requestValues = null; + this.#outgoing = null; + this.#consumed = false; + } + /** + * Astro.cookies.delete(key) is used to delete a cookie. Using this method will result + * in a Set-Cookie header added to the response. + * @param key The cookie to delete + * @param options Options related to this deletion, such as the path of the cookie. + */ + delete(key, options) { + const { + // @ts-expect-error + maxAge: _ignoredMaxAge, + // @ts-expect-error + expires: _ignoredExpires, + ...sanitizedOptions + } = options || {}; + const serializeOptions = { + expires: DELETED_EXPIRATION, + ...sanitizedOptions + }; + this.#ensureOutgoingMap().set(key, [ + DELETED_VALUE, + serialize(key, DELETED_VALUE, serializeOptions), + false + ]); + } + /** + * Astro.cookies.get(key) is used to get a cookie value. The cookie value is read from the + * request. If you have set a cookie via Astro.cookies.set(key, value), the value will be taken + * from that set call, overriding any values already part of the request. + * @param key The cookie to get. + * @returns An object containing the cookie value as well as convenience methods for converting its value. + */ + get(key, options = void 0) { + if (this.#outgoing?.has(key)) { + let [serializedValue, , isSetValue] = this.#outgoing.get(key); + if (isSetValue) { + return new AstroCookie(serializedValue); + } else { + return void 0; + } + } + const decode = options?.decode ?? decodeURIComponent; + const values = this.#ensureParsed(); + if (key in values) { + const value = values[key]; + if (value) { + let decodedValue; + try { + decodedValue = decode(value); + } catch (_error) { + decodedValue = value; + } + return new AstroCookie(decodedValue); + } + } + } + /** + * Astro.cookies.has(key) returns a boolean indicating whether this cookie is either + * part of the initial request or set via Astro.cookies.set(key) + * @param key The cookie to check for. + * @param _options This parameter is no longer used. + * @returns + */ + has(key, _options) { + if (this.#outgoing?.has(key)) { + let [, , isSetValue] = this.#outgoing.get(key); + return isSetValue; + } + const values = this.#ensureParsed(); + return values[key] !== void 0; + } + /** + * Astro.cookies.set(key, value) is used to set a cookie's value. If provided + * an object it will be stringified via JSON.stringify(value). Additionally you + * can provide options customizing how this cookie will be set, such as setting httpOnly + * in order to prevent the cookie from being read in client-side JavaScript. + * @param key The name of the cookie to set. + * @param value A value, either a string or other primitive or an object. + * @param options Options for the cookie, such as the path and security settings. + */ + set(key, value, options) { + if (this.#consumed) { + const warning = new Error( + "Astro.cookies.set() was called after the cookies had already been sent to the browser.\nThis may have happened if this method was called in an imported component.\nPlease make sure that Astro.cookies.set() is only called in the frontmatter of the main page." + ); + warning.name = "Warning"; + console.warn(warning); + } + let serializedValue; + if (typeof value === "string") { + serializedValue = value; + } else { + let toStringValue = value.toString(); + if (toStringValue === Object.prototype.toString.call(value)) { + serializedValue = JSON.stringify(value); + } else { + serializedValue = toStringValue; + } + } + const serializeOptions = {}; + if (options) { + Object.assign(serializeOptions, options); + } + this.#ensureOutgoingMap().set(key, [ + serializedValue, + serialize(key, serializedValue, serializeOptions), + true + ]); + if (this.#request[responseSentSymbol]) { + throw new AstroError({ + ...ResponseSentError + }); + } + } + /** + * Merges a new AstroCookies instance into the current instance. Any new cookies + * will be added to the current instance, overwriting any existing cookies with the same name. + */ + merge(cookies) { + const outgoing = cookies.#outgoing; + if (outgoing) { + for (const [key, value] of outgoing) { + this.#ensureOutgoingMap().set(key, value); + } + } + } + /** + * Astro.cookies.header() returns an iterator for the cookies that have previously + * been set by either Astro.cookies.set() or Astro.cookies.delete(). + * This method is primarily used by adapters to set the header on outgoing responses. + * @returns + */ + *headers() { + if (this.#outgoing == null) return; + for (const [, value] of this.#outgoing) { + yield value[1]; + } + } + /** + * Behaves the same as AstroCookies.prototype.headers(), + * but allows a warning when cookies are set after the instance is consumed. + */ + static consume(cookies) { + cookies.#consumed = true; + return cookies.headers(); + } + #ensureParsed() { + if (!this.#requestValues) { + this.#parse(); + } + if (!this.#requestValues) { + this.#requestValues = {}; + } + return this.#requestValues; + } + #ensureOutgoingMap() { + if (!this.#outgoing) { + this.#outgoing = /* @__PURE__ */ new Map(); + } + return this.#outgoing; + } + #parse() { + const raw = this.#request.headers.get("cookie"); + if (!raw) { + return; + } + this.#requestValues = parse(raw, { decode: identity }); + } +} + +const astroCookiesSymbol = Symbol.for("astro.cookies"); +function attachCookiesToResponse(response, cookies) { + Reflect.set(response, astroCookiesSymbol, cookies); +} +function getCookiesFromResponse(response) { + let cookies = Reflect.get(response, astroCookiesSymbol); + if (cookies != null) { + return cookies; + } else { + return void 0; + } +} +function* getSetCookiesFromResponse(response) { + const cookies = getCookiesFromResponse(response); + if (!cookies) { + return []; + } + for (const headerValue of AstroCookies.consume(cookies)) { + yield headerValue; + } + return []; +} + +const dateTimeFormat = new Intl.DateTimeFormat([], { + hour: "2-digit", + minute: "2-digit", + second: "2-digit", + hour12: false +}); +const levels = { + debug: 20, + info: 30, + warn: 40, + error: 50, + silent: 90 +}; +function log(opts, level, label, message, newLine = true) { + const logLevel = opts.level; + const dest = opts.dest; + const event = { + label, + level, + message, + newLine + }; + if (!isLogLevelEnabled(logLevel, level)) { + return; + } + dest.write(event); +} +function isLogLevelEnabled(configuredLogLevel, level) { + return levels[configuredLogLevel] <= levels[level]; +} +function info(opts, label, message, newLine = true) { + return log(opts, "info", label, message, newLine); +} +function warn(opts, label, message, newLine = true) { + return log(opts, "warn", label, message, newLine); +} +function error(opts, label, message, newLine = true) { + return log(opts, "error", label, message, newLine); +} +function debug(...args) { + if ("_astroGlobalDebug" in globalThis) { + globalThis._astroGlobalDebug(...args); + } +} +function getEventPrefix({ level, label }) { + const timestamp = `${dateTimeFormat.format(/* @__PURE__ */ new Date())}`; + const prefix = []; + if (level === "error" || level === "warn") { + prefix.push(colors.bold(timestamp)); + prefix.push(`[${level.toUpperCase()}]`); + } else { + prefix.push(timestamp); + } + if (label) { + prefix.push(`[${label}]`); + } + if (level === "error") { + return colors.red(prefix.join(" ")); + } + if (level === "warn") { + return colors.yellow(prefix.join(" ")); + } + if (prefix.length === 1) { + return colors.dim(prefix[0]); + } + return colors.dim(prefix[0]) + " " + colors.blue(prefix.splice(1).join(" ")); +} +class Logger { + options; + constructor(options) { + this.options = options; + } + info(label, message, newLine = true) { + info(this.options, label, message, newLine); + } + warn(label, message, newLine = true) { + warn(this.options, label, message, newLine); + } + error(label, message, newLine = true) { + error(this.options, label, message, newLine); + } + debug(label, ...messages) { + debug(label, ...messages); + } + level() { + return this.options.level; + } + forkIntegrationLogger(label) { + return new AstroIntegrationLogger(this.options, label); + } +} +class AstroIntegrationLogger { + options; + label; + constructor(logging, label) { + this.options = logging; + this.label = label; + } + /** + * Creates a new logger instance with a new label, but the same log options. + */ + fork(label) { + return new AstroIntegrationLogger(this.options, label); + } + info(message) { + info(this.options, this.label, message); + } + warn(message) { + warn(this.options, this.label, message); + } + error(message) { + error(this.options, this.label, message); + } + debug(message) { + debug(this.label, message); + } +} + +const consoleLogDestination = { + write(event) { + let dest = console.error; + if (levels[event.level] < levels["error"]) { + dest = console.info; + } + if (event.label === "SKIP_FORMAT") { + dest(event.message); + } else { + dest(getEventPrefix(event) + " " + event.message); + } + return true; + } +}; + +function getAssetsPrefix(fileExtension, assetsPrefix) { + let prefix = ""; + if (!assetsPrefix) { + prefix = ""; + } else if (typeof assetsPrefix === "string") { + prefix = assetsPrefix; + } else { + const dotLessFileExtension = fileExtension.slice(1); + prefix = assetsPrefix[dotLessFileExtension] || assetsPrefix.fallback; + } + return prefix; +} + +function createAssetLink(href, base, assetsPrefix, queryParams) { + let url = ""; + if (assetsPrefix) { + const pf = getAssetsPrefix(fileExtension(href), assetsPrefix); + url = joinPaths(pf, slash(href)); + } else if (base) { + url = prependForwardSlash$1(joinPaths(base, slash(href))); + } else { + url = href; + } + return url; +} +function createStylesheetElement(stylesheet, base, assetsPrefix, queryParams) { + if (stylesheet.type === "inline") { + return { + props: {}, + children: stylesheet.content + }; + } else { + return { + props: { + rel: "stylesheet", + href: createAssetLink(stylesheet.src, base, assetsPrefix) + }, + children: "" + }; + } +} +function createStylesheetElementSet(stylesheets, base, assetsPrefix, queryParams) { + return new Set( + stylesheets.map((s) => createStylesheetElement(s, base, assetsPrefix)) + ); +} +function createModuleScriptElement(script, base, assetsPrefix, queryParams) { + if (script.type === "external") { + return createModuleScriptElementWithSrc(script.value, base, assetsPrefix); + } else { + return { + props: { + type: "module" + }, + children: script.value + }; + } +} +function createModuleScriptElementWithSrc(src, base, assetsPrefix, queryParams) { + return { + props: { + type: "module", + src: createAssetLink(src, base, assetsPrefix) + }, + children: "" + }; +} + +const ACTION_API_CONTEXT_SYMBOL = Symbol.for("astro.actionAPIContext"); +const formContentTypes = ["application/x-www-form-urlencoded", "multipart/form-data"]; +function hasContentType(contentType, expected) { + const type = contentType.split(";")[0].toLowerCase(); + return expected.some((t) => type === t); +} + +function getActionContext(context) { + const callerInfo = getCallerInfo(context); + const actionResultAlreadySet = Boolean(context.locals._actionPayload); + let action = void 0; + if (callerInfo && context.request.method === "POST" && !actionResultAlreadySet) { + action = { + calledFrom: callerInfo.from, + name: callerInfo.name, + handler: async () => { + const pipeline = Reflect.get(context, apiContextRoutesSymbol); + const callerInfoName = shouldAppendForwardSlash( + pipeline.manifest.trailingSlash, + pipeline.manifest.buildFormat + ) ? removeTrailingForwardSlash(callerInfo.name) : callerInfo.name; + let baseAction; + try { + baseAction = await pipeline.getAction(callerInfoName); + } catch (error) { + if (error instanceof Error && "name" in error && typeof error.name === "string" && error.name === ActionNotFoundError.name) { + return { data: void 0, error: new ActionError({ code: "NOT_FOUND" }) }; + } + throw error; + } + let input; + try { + input = await parseRequestBody(context.request); + } catch (e) { + if (e instanceof TypeError) { + return { data: void 0, error: new ActionError({ code: "UNSUPPORTED_MEDIA_TYPE" }) }; + } + throw e; + } + const omitKeys = ["props", "getActionResult", "callAction", "redirect"]; + const actionAPIContext = Object.create( + Object.getPrototypeOf(context), + Object.fromEntries( + Object.entries(Object.getOwnPropertyDescriptors(context)).filter( + ([key]) => !omitKeys.includes(key) + ) + ) + ); + Reflect.set(actionAPIContext, ACTION_API_CONTEXT_SYMBOL, true); + const handler = baseAction.bind(actionAPIContext); + return handler(input); + } + }; + } + function setActionResult(actionName, actionResult) { + context.locals._actionPayload = { + actionResult, + actionName + }; + } + return { + action, + setActionResult, + serializeActionResult, + deserializeActionResult + }; +} +function getCallerInfo(ctx) { + if (ctx.routePattern === ACTION_RPC_ROUTE_PATTERN) { + return { from: "rpc", name: ctx.url.pathname.replace(/^.*\/_actions\//, "") }; + } + const queryParam = ctx.url.searchParams.get(ACTION_QUERY_PARAMS.actionName); + if (queryParam) { + return { from: "form", name: queryParam }; + } + return void 0; +} +async function parseRequestBody(request) { + const contentType = request.headers.get("content-type"); + const contentLength = request.headers.get("Content-Length"); + if (!contentType) return void 0; + if (hasContentType(contentType, formContentTypes)) { + return await request.clone().formData(); + } + if (hasContentType(contentType, ["application/json"])) { + return contentLength === "0" ? void 0 : await request.clone().json(); + } + throw new TypeError("Unsupported content type"); +} + +function hasActionPayload(locals) { + return "_actionPayload" in locals; +} +function createGetActionResult(locals) { + return (actionFn) => { + if (!hasActionPayload(locals) || actionFn.toString() !== getActionQueryString(locals._actionPayload.actionName)) { + return void 0; + } + return deserializeActionResult(locals._actionPayload.actionResult); + }; +} +function createCallAction(context) { + return (baseAction, input) => { + Reflect.set(context, ACTION_API_CONTEXT_SYMBOL, true); + const action = baseAction.bind(context); + return action(input); + }; +} + +function parseLocale(header) { + if (header === "*") { + return [{ locale: header, qualityValue: void 0 }]; + } + const result = []; + const localeValues = header.split(",").map((str) => str.trim()); + for (const localeValue of localeValues) { + const split = localeValue.split(";").map((str) => str.trim()); + const localeName = split[0]; + const qualityValue = split[1]; + if (!split) { + continue; + } + if (qualityValue && qualityValue.startsWith("q=")) { + const qualityValueAsFloat = Number.parseFloat(qualityValue.slice("q=".length)); + if (Number.isNaN(qualityValueAsFloat) || qualityValueAsFloat > 1) { + result.push({ + locale: localeName, + qualityValue: void 0 + }); + } else { + result.push({ + locale: localeName, + qualityValue: qualityValueAsFloat + }); + } + } else { + result.push({ + locale: localeName, + qualityValue: void 0 + }); + } + } + return result; +} +function sortAndFilterLocales(browserLocaleList, locales) { + const normalizedLocales = getAllCodes(locales).map(normalizeTheLocale); + return browserLocaleList.filter((browserLocale) => { + if (browserLocale.locale !== "*") { + return normalizedLocales.includes(normalizeTheLocale(browserLocale.locale)); + } + return true; + }).sort((a, b) => { + if (a.qualityValue && b.qualityValue) { + return Math.sign(b.qualityValue - a.qualityValue); + } + return 0; + }); +} +function computePreferredLocale(request, locales) { + const acceptHeader = request.headers.get("Accept-Language"); + let result = void 0; + if (acceptHeader) { + const browserLocaleList = sortAndFilterLocales(parseLocale(acceptHeader), locales); + const firstResult = browserLocaleList.at(0); + if (firstResult && firstResult.locale !== "*") { + for (const currentLocale of locales) { + if (typeof currentLocale === "string") { + if (normalizeTheLocale(currentLocale) === normalizeTheLocale(firstResult.locale)) { + result = currentLocale; + break; + } + } else { + for (const currentCode of currentLocale.codes) { + if (normalizeTheLocale(currentCode) === normalizeTheLocale(firstResult.locale)) { + result = currentCode; + break; + } + } + } + } + } + } + return result; +} +function computePreferredLocaleList(request, locales) { + const acceptHeader = request.headers.get("Accept-Language"); + let result = []; + if (acceptHeader) { + const browserLocaleList = sortAndFilterLocales(parseLocale(acceptHeader), locales); + if (browserLocaleList.length === 1 && browserLocaleList.at(0).locale === "*") { + return getAllCodes(locales); + } else if (browserLocaleList.length > 0) { + for (const browserLocale of browserLocaleList) { + for (const loopLocale of locales) { + if (typeof loopLocale === "string") { + if (normalizeTheLocale(loopLocale) === normalizeTheLocale(browserLocale.locale)) { + result.push(loopLocale); + } + } else { + for (const code of loopLocale.codes) { + if (code === browserLocale.locale) { + result.push(code); + } + } + } + } + } + } + } + return result; +} +function computeCurrentLocale(pathname, locales, defaultLocale) { + for (const segment of pathname.split("/").map(normalizeThePath)) { + for (const locale of locales) { + if (typeof locale === "string") { + if (!segment.includes(locale)) continue; + if (normalizeTheLocale(locale) === normalizeTheLocale(segment)) { + return locale; + } + } else { + if (locale.path === segment) { + return locale.codes.at(0); + } else { + for (const code of locale.codes) { + if (normalizeTheLocale(code) === normalizeTheLocale(segment)) { + return code; + } + } + } + } + } + } + for (const locale of locales) { + if (typeof locale === "string") { + if (locale === defaultLocale) { + return locale; + } + } else { + if (locale.path === defaultLocale) { + return locale.codes.at(0); + } + } + } +} + +async function callMiddleware(onRequest, apiContext, responseFunction) { + let nextCalled = false; + let responseFunctionPromise = void 0; + const next = async (payload) => { + nextCalled = true; + responseFunctionPromise = responseFunction(apiContext, payload); + return responseFunctionPromise; + }; + let middlewarePromise = onRequest(apiContext, next); + return await Promise.resolve(middlewarePromise).then(async (value) => { + if (nextCalled) { + if (typeof value !== "undefined") { + if (value instanceof Response === false) { + throw new AstroError(MiddlewareNotAResponse); + } + return value; + } else { + if (responseFunctionPromise) { + return responseFunctionPromise; + } else { + throw new AstroError(MiddlewareNotAResponse); + } + } + } else if (typeof value === "undefined") { + throw new AstroError(MiddlewareNoDataOrNextCalled); + } else if (value instanceof Response === false) { + throw new AstroError(MiddlewareNotAResponse); + } else { + return value; + } + }); +} + +function createRequest({ + url, + headers, + method = "GET", + body = void 0, + logger, + isPrerendered = false, + routePattern, + init +}) { + const headersObj = isPrerendered ? void 0 : headers instanceof Headers ? headers : new Headers( + // Filter out HTTP/2 pseudo-headers. These are internally-generated headers added to all HTTP/2 requests with trusted metadata about the request. + // Examples include `:method`, `:scheme`, `:authority`, and `:path`. + // They are always prefixed with a colon to distinguish them from other headers, and it is an error to add the to a Headers object manually. + // See https://httpwg.org/specs/rfc7540.html#HttpRequest + Object.entries(headers).filter(([name]) => !name.startsWith(":")) + ); + if (typeof url === "string") url = new URL(url); + if (isPrerendered) { + url.search = ""; + } + const request = new Request(url, { + method, + headers: headersObj, + // body is made available only if the request is for a page that will be on-demand rendered + body: isPrerendered ? null : body, + ...init + }); + if (isPrerendered) { + let _headers = request.headers; + const { value, writable, ...headersDesc } = Object.getOwnPropertyDescriptor(request, "headers") || {}; + Object.defineProperty(request, "headers", { + ...headersDesc, + get() { + logger.warn( + null, + `\`Astro.request.headers\` was used when rendering the route \`${routePattern}'\`. \`Astro.request.headers\` is not available on prerendered pages. If you need access to request headers, make sure that the page is server-rendered using \`export const prerender = false;\` or by setting \`output\` to \`"server"\` in your Astro config to make all your pages server-rendered by default.` + ); + return _headers; + }, + set(newHeaders) { + _headers = newHeaders; + } + }); + } + return request; +} + +function findRouteToRewrite({ + payload, + routes, + request, + trailingSlash, + buildFormat, + base, + outDir +}) { + let newUrl = void 0; + if (payload instanceof URL) { + newUrl = payload; + } else if (payload instanceof Request) { + newUrl = new URL(payload.url); + } else { + newUrl = new URL(payload, new URL(request.url).origin); + } + let pathname = newUrl.pathname; + const shouldAppendSlash = shouldAppendForwardSlash(trailingSlash, buildFormat); + if (base !== "/") { + const isBasePathRequest = newUrl.pathname === base || newUrl.pathname === removeTrailingForwardSlash(base); + if (isBasePathRequest) { + pathname = shouldAppendSlash ? "/" : ""; + } else if (newUrl.pathname.startsWith(base)) { + pathname = shouldAppendSlash ? appendForwardSlash$1(newUrl.pathname) : removeTrailingForwardSlash(newUrl.pathname); + pathname = pathname.slice(base.length); + } + } + if (!pathname.startsWith("/") && shouldAppendSlash && newUrl.pathname.endsWith("/")) { + pathname = prependForwardSlash$1(pathname); + } + if (pathname === "/" && base !== "/" && !shouldAppendSlash) { + pathname = ""; + } + if (buildFormat === "file") { + pathname = pathname.replace(/\.html$/, ""); + } + if (base !== "/" && (pathname === "" || pathname === "/") && !shouldAppendSlash) { + newUrl.pathname = removeTrailingForwardSlash(base); + } else { + newUrl.pathname = joinPaths(...[base, pathname].filter(Boolean)); + } + const decodedPathname = decodeURI(pathname); + let foundRoute; + for (const route of routes) { + if (route.pattern.test(decodedPathname)) { + if (route.params && route.params.length !== 0 && route.distURL && route.distURL.length !== 0) { + if (!route.distURL.find( + (url) => url.href.replace(outDir.toString(), "").replace(/(?:\/index\.html|\.html)$/, "") == trimSlashes(decodedPathname) + )) { + continue; + } + } + foundRoute = route; + break; + } + } + if (foundRoute) { + return { + routeData: foundRoute, + newUrl, + pathname: decodedPathname + }; + } else { + const custom404 = routes.find((route) => route.route === "/404"); + if (custom404) { + return { routeData: custom404, newUrl, pathname }; + } else { + return { routeData: DEFAULT_404_ROUTE, newUrl, pathname }; + } + } +} +function copyRequest(newUrl, oldRequest, isPrerendered, logger, routePattern) { + if (oldRequest.bodyUsed) { + throw new AstroError(RewriteWithBodyUsed); + } + return createRequest({ + url: newUrl, + method: oldRequest.method, + body: oldRequest.body, + isPrerendered, + logger, + headers: isPrerendered ? {} : oldRequest.headers, + routePattern, + init: { + referrer: oldRequest.referrer, + referrerPolicy: oldRequest.referrerPolicy, + mode: oldRequest.mode, + credentials: oldRequest.credentials, + cache: oldRequest.cache, + redirect: oldRequest.redirect, + integrity: oldRequest.integrity, + signal: oldRequest.signal, + keepalive: oldRequest.keepalive, + // https://fetch.spec.whatwg.org/#dom-request-duplex + // @ts-expect-error It isn't part of the types, but undici accepts it and it allows to carry over the body to a new request + duplex: "half" + } + }); +} +function setOriginPathname(request, pathname, trailingSlash, buildFormat) { + if (!pathname) { + pathname = "/"; + } + const shouldAppendSlash = shouldAppendForwardSlash(trailingSlash, buildFormat); + let finalPathname; + if (pathname === "/") { + finalPathname = "/"; + } else if (shouldAppendSlash) { + finalPathname = appendForwardSlash$1(pathname); + } else { + finalPathname = removeTrailingForwardSlash(pathname); + } + Reflect.set(request, originPathnameSymbol, encodeURIComponent(finalPathname)); +} +function getOriginPathname(request) { + const origin = Reflect.get(request, originPathnameSymbol); + if (origin) { + return decodeURIComponent(origin); + } + return new URL(request.url).pathname; +} + +const NOOP_ACTIONS_MOD = { + server: {} +}; + +const FORM_CONTENT_TYPES = [ + "application/x-www-form-urlencoded", + "multipart/form-data", + "text/plain" +]; +const SAFE_METHODS = ["GET", "HEAD", "OPTIONS"]; +function createOriginCheckMiddleware() { + return defineMiddleware((context, next) => { + const { request, url, isPrerendered } = context; + if (isPrerendered) { + return next(); + } + if (SAFE_METHODS.includes(request.method)) { + return next(); + } + const isSameOrigin = request.headers.get("origin") === url.origin; + const hasContentType = request.headers.has("content-type"); + if (hasContentType) { + const formLikeHeader = hasFormLikeHeader(request.headers.get("content-type")); + if (formLikeHeader && !isSameOrigin) { + return new Response(`Cross-site ${request.method} form submissions are forbidden`, { + status: 403 + }); + } + } else { + if (!isSameOrigin) { + return new Response(`Cross-site ${request.method} form submissions are forbidden`, { + status: 403 + }); + } + } + return next(); + }); +} +function hasFormLikeHeader(contentType) { + if (contentType) { + for (const FORM_CONTENT_TYPE of FORM_CONTENT_TYPES) { + if (contentType.toLowerCase().includes(FORM_CONTENT_TYPE)) { + return true; + } + } + } + return false; +} + +const VALID_PARAM_TYPES = ["string", "number", "undefined"]; +function validateGetStaticPathsParameter([key, value], route) { + if (!VALID_PARAM_TYPES.includes(typeof value)) { + throw new AstroError({ + ...GetStaticPathsInvalidRouteParam, + message: GetStaticPathsInvalidRouteParam.message(key, value, typeof value), + location: { + file: route + } + }); + } +} +function validateDynamicRouteModule(mod, { + ssr, + route +}) { + if ((!ssr || route.prerender) && !mod.getStaticPaths) { + throw new AstroError({ + ...GetStaticPathsRequired, + location: { file: route.component } + }); + } +} +function validateGetStaticPathsResult(result, logger, route) { + if (!Array.isArray(result)) { + throw new AstroError({ + ...InvalidGetStaticPathsReturn, + message: InvalidGetStaticPathsReturn.message(typeof result), + location: { + file: route.component + } + }); + } + result.forEach((pathObject) => { + if (typeof pathObject === "object" && Array.isArray(pathObject) || pathObject === null) { + throw new AstroError({ + ...InvalidGetStaticPathsEntry, + message: InvalidGetStaticPathsEntry.message( + Array.isArray(pathObject) ? "array" : typeof pathObject + ) + }); + } + if (pathObject.params === void 0 || pathObject.params === null || pathObject.params && Object.keys(pathObject.params).length === 0) { + throw new AstroError({ + ...GetStaticPathsExpectedParams, + location: { + file: route.component + } + }); + } + for (const [key, val] of Object.entries(pathObject.params)) { + if (!(typeof val === "undefined" || typeof val === "string" || typeof val === "number")) { + logger.warn( + "router", + `getStaticPaths() returned an invalid path param: "${key}". A string, number or undefined value was expected, but got \`${JSON.stringify( + val + )}\`.` + ); + } + if (typeof val === "string" && val === "") { + logger.warn( + "router", + `getStaticPaths() returned an invalid path param: "${key}". \`undefined\` expected for an optional param, but got empty string.` + ); + } + } + }); +} + +function stringifyParams(params, route) { + const validatedParams = Object.entries(params).reduce((acc, next) => { + validateGetStaticPathsParameter(next, route.component); + const [key, value] = next; + if (value !== void 0) { + acc[key] = typeof value === "string" ? trimSlashes(value) : value.toString(); + } + return acc; + }, {}); + return route.generate(validatedParams); +} + +function generatePaginateFunction(routeMatch, base) { + return function paginateUtility(data, args = {}) { + let { pageSize: _pageSize, params: _params, props: _props } = args; + const pageSize = _pageSize || 10; + const paramName = "page"; + const additionalParams = _params || {}; + const additionalProps = _props || {}; + let includesFirstPageNumber; + if (routeMatch.params.includes(`...${paramName}`)) { + includesFirstPageNumber = false; + } else if (routeMatch.params.includes(`${paramName}`)) { + includesFirstPageNumber = true; + } else { + throw new AstroError({ + ...PageNumberParamNotFound, + message: PageNumberParamNotFound.message(paramName) + }); + } + const lastPage = Math.max(1, Math.ceil(data.length / pageSize)); + const result = [...Array(lastPage).keys()].map((num) => { + const pageNum = num + 1; + const start = pageSize === Infinity ? 0 : (pageNum - 1) * pageSize; + const end = Math.min(start + pageSize, data.length); + const params = { + ...additionalParams, + [paramName]: includesFirstPageNumber || pageNum > 1 ? String(pageNum) : void 0 + }; + const current = addRouteBase(routeMatch.generate({ ...params }), base); + const next = pageNum === lastPage ? void 0 : addRouteBase(routeMatch.generate({ ...params, page: String(pageNum + 1) }), base); + const prev = pageNum === 1 ? void 0 : addRouteBase( + routeMatch.generate({ + ...params, + page: !includesFirstPageNumber && pageNum - 1 === 1 ? void 0 : String(pageNum - 1) + }), + base + ); + const first = pageNum === 1 ? void 0 : addRouteBase( + routeMatch.generate({ + ...params, + page: includesFirstPageNumber ? "1" : void 0 + }), + base + ); + const last = pageNum === lastPage ? void 0 : addRouteBase(routeMatch.generate({ ...params, page: String(lastPage) }), base); + return { + params, + props: { + ...additionalProps, + page: { + data: data.slice(start, end), + start, + end: end - 1, + size: pageSize, + total: data.length, + currentPage: pageNum, + lastPage, + url: { current, next, prev, first, last } + } + } + }; + }); + return result; + }; +} +function addRouteBase(route, base) { + let routeWithBase = joinPaths(base, route); + if (routeWithBase === "") routeWithBase = "/"; + return routeWithBase; +} + +async function callGetStaticPaths({ + mod, + route, + routeCache, + logger, + ssr, + base +}) { + const cached = routeCache.get(route); + if (!mod) { + throw new Error("This is an error caused by Astro and not your code. Please file an issue."); + } + if (cached?.staticPaths) { + return cached.staticPaths; + } + validateDynamicRouteModule(mod, { ssr, route }); + if (ssr && !route.prerender) { + const entry = Object.assign([], { keyed: /* @__PURE__ */ new Map() }); + routeCache.set(route, { ...cached, staticPaths: entry }); + return entry; + } + let staticPaths = []; + if (!mod.getStaticPaths) { + throw new Error("Unexpected Error."); + } + staticPaths = await mod.getStaticPaths({ + // Q: Why the cast? + // A: So users downstream can have nicer typings, we have to make some sacrifice in our internal typings, which necessitate a cast here + paginate: generatePaginateFunction(route, base), + routePattern: route.route + }); + validateGetStaticPathsResult(staticPaths, logger, route); + const keyedStaticPaths = staticPaths; + keyedStaticPaths.keyed = /* @__PURE__ */ new Map(); + for (const sp of keyedStaticPaths) { + const paramsKey = stringifyParams(sp.params, route); + keyedStaticPaths.keyed.set(paramsKey, sp); + } + routeCache.set(route, { ...cached, staticPaths: keyedStaticPaths }); + return keyedStaticPaths; +} +class RouteCache { + logger; + cache = {}; + runtimeMode; + constructor(logger, runtimeMode = "production") { + this.logger = logger; + this.runtimeMode = runtimeMode; + } + /** Clear the cache. */ + clearAll() { + this.cache = {}; + } + set(route, entry) { + const key = this.key(route); + if (this.runtimeMode === "production" && this.cache[key]?.staticPaths) { + this.logger.warn(null, `Internal Warning: route cache overwritten. (${key})`); + } + this.cache[key] = entry; + } + get(route) { + return this.cache[this.key(route)]; + } + key(route) { + return `${route.route}_${route.component}`; + } +} +function findPathItemByKey(staticPaths, params, route, logger) { + const paramsKey = stringifyParams(params, route); + const matchedStaticPath = staticPaths.keyed.get(paramsKey); + if (matchedStaticPath) { + return matchedStaticPath; + } + logger.debug("router", `findPathItemByKey() - Unexpected cache miss looking for ${paramsKey}`); +} + +function createDefaultRoutes(manifest) { + const root = new URL(manifest.hrefRoot); + return [ + { + instance: default404Instance, + matchesComponent: (filePath) => filePath.href === new URL(DEFAULT_404_COMPONENT, root).href, + route: DEFAULT_404_ROUTE.route, + component: DEFAULT_404_COMPONENT + }, + { + instance: createEndpoint(manifest), + matchesComponent: (filePath) => filePath.href === new URL(SERVER_ISLAND_COMPONENT, root).href, + route: SERVER_ISLAND_ROUTE, + component: SERVER_ISLAND_COMPONENT + } + ]; +} + +class Pipeline { + constructor(logger, manifest, runtimeMode, renderers, resolve, serverLike, streaming, adapterName = manifest.adapterName, clientDirectives = manifest.clientDirectives, inlinedScripts = manifest.inlinedScripts, compressHTML = manifest.compressHTML, i18n = manifest.i18n, middleware = manifest.middleware, routeCache = new RouteCache(logger, runtimeMode), site = manifest.site ? new URL(manifest.site) : void 0, defaultRoutes = createDefaultRoutes(manifest), actions = manifest.actions) { + this.logger = logger; + this.manifest = manifest; + this.runtimeMode = runtimeMode; + this.renderers = renderers; + this.resolve = resolve; + this.serverLike = serverLike; + this.streaming = streaming; + this.adapterName = adapterName; + this.clientDirectives = clientDirectives; + this.inlinedScripts = inlinedScripts; + this.compressHTML = compressHTML; + this.i18n = i18n; + this.middleware = middleware; + this.routeCache = routeCache; + this.site = site; + this.defaultRoutes = defaultRoutes; + this.actions = actions; + this.internalMiddleware = []; + if (i18n?.strategy !== "manual") { + this.internalMiddleware.push( + createI18nMiddleware(i18n, manifest.base, manifest.trailingSlash, manifest.buildFormat) + ); + } + } + internalMiddleware; + resolvedMiddleware = void 0; + resolvedActions = void 0; + /** + * Resolves the middleware from the manifest, and returns the `onRequest` function. If `onRequest` isn't there, + * it returns a no-op function + */ + async getMiddleware() { + if (this.resolvedMiddleware) { + return this.resolvedMiddleware; + } else if (this.middleware) { + const middlewareInstance = await this.middleware(); + const onRequest = middlewareInstance.onRequest ?? NOOP_MIDDLEWARE_FN; + const internalMiddlewares = [onRequest]; + if (this.manifest.checkOrigin) { + internalMiddlewares.unshift(createOriginCheckMiddleware()); + } + this.resolvedMiddleware = sequence(...internalMiddlewares); + return this.resolvedMiddleware; + } else { + this.resolvedMiddleware = NOOP_MIDDLEWARE_FN; + return this.resolvedMiddleware; + } + } + setActions(actions) { + this.resolvedActions = actions; + } + async getActions() { + if (this.resolvedActions) { + return this.resolvedActions; + } else if (this.actions) { + return await this.actions(); + } + return NOOP_ACTIONS_MOD; + } + async getAction(path) { + const pathKeys = path.split(".").map((key) => decodeURIComponent(key)); + let { server } = await this.getActions(); + if (!server || !(typeof server === "object")) { + throw new TypeError( + `Expected \`server\` export in actions file to be an object. Received ${typeof server}.` + ); + } + for (const key of pathKeys) { + if (!(key in server)) { + throw new AstroError({ + ...ActionNotFoundError, + message: ActionNotFoundError.message(pathKeys.join(".")) + }); + } + server = server[key]; + } + if (typeof server !== "function") { + throw new TypeError( + `Expected handler for action ${pathKeys.join(".")} to be a function. Received ${typeof server}.` + ); + } + return server; + } +} + +function routeIsRedirect(route) { + return route?.type === "redirect"; +} +function routeIsFallback(route) { + return route?.type === "fallback"; +} + +const RedirectComponentInstance = { + default() { + return new Response(null, { + status: 301 + }); + } +}; +const RedirectSinglePageBuiltModule = { + page: () => Promise.resolve(RedirectComponentInstance), + onRequest: (_, next) => next(), + renderers: [] +}; + +async function getProps(opts) { + const { logger, mod, routeData: route, routeCache, pathname, serverLike, base } = opts; + if (!route || route.pathname) { + return {}; + } + if (routeIsRedirect(route) || routeIsFallback(route) || route.component === DEFAULT_404_COMPONENT) { + return {}; + } + const staticPaths = await callGetStaticPaths({ + mod, + route, + routeCache, + logger, + ssr: serverLike, + base + }); + const params = getParams(route, pathname); + const matchedStaticPath = findPathItemByKey(staticPaths, params, route, logger); + if (!matchedStaticPath && (serverLike ? route.prerender : true)) { + throw new AstroError({ + ...NoMatchingStaticPathFound, + message: NoMatchingStaticPathFound.message(pathname), + hint: NoMatchingStaticPathFound.hint([route.component]) + }); + } + if (mod) { + validatePrerenderEndpointCollision(route, mod, params); + } + const props = matchedStaticPath?.props ? { ...matchedStaticPath.props } : {}; + return props; +} +function getParams(route, pathname) { + if (!route.params.length) return {}; + const paramsMatch = route.pattern.exec(pathname) || route.fallbackRoutes.map((fallbackRoute) => fallbackRoute.pattern.exec(pathname)).find((x) => x); + if (!paramsMatch) return {}; + const params = {}; + route.params.forEach((key, i) => { + if (key.startsWith("...")) { + params[key.slice(3)] = paramsMatch[i + 1] ? paramsMatch[i + 1] : void 0; + } else { + params[key] = paramsMatch[i + 1]; + } + }); + return params; +} +function validatePrerenderEndpointCollision(route, mod, params) { + if (route.type === "endpoint" && mod.getStaticPaths) { + const lastSegment = route.segments[route.segments.length - 1]; + const paramValues = Object.values(params); + const lastParam = paramValues[paramValues.length - 1]; + if (lastSegment.length === 1 && lastSegment[0].dynamic && lastParam === void 0) { + throw new AstroError({ + ...PrerenderDynamicEndpointPathCollide, + message: PrerenderDynamicEndpointPathCollide.message(route.route), + hint: PrerenderDynamicEndpointPathCollide.hint(route.component), + location: { + file: route.component + } + }); + } + } +} + +function getFunctionExpression(slot) { + if (!slot) return; + const expressions = slot?.expressions?.filter((e) => isRenderInstruction(e) === false); + if (expressions?.length !== 1) return; + return expressions[0]; +} +class Slots { + #result; + #slots; + #logger; + constructor(result, slots, logger) { + this.#result = result; + this.#slots = slots; + this.#logger = logger; + if (slots) { + for (const key of Object.keys(slots)) { + if (this[key] !== void 0) { + throw new AstroError({ + ...ReservedSlotName, + message: ReservedSlotName.message(key) + }); + } + Object.defineProperty(this, key, { + get() { + return true; + }, + enumerable: true + }); + } + } + } + has(name) { + if (!this.#slots) return false; + return Boolean(this.#slots[name]); + } + async render(name, args = []) { + if (!this.#slots || !this.has(name)) return; + const result = this.#result; + if (!Array.isArray(args)) { + this.#logger.warn( + null, + `Expected second parameter to be an array, received a ${typeof args}. If you're trying to pass an array as a single argument and getting unexpected results, make sure you're passing your array as a item of an array. Ex: Astro.slots.render('default', [["Hello", "World"]])` + ); + } else if (args.length > 0) { + const slotValue = this.#slots[name]; + const component = typeof slotValue === "function" ? await slotValue(result) : await slotValue; + const expression = getFunctionExpression(component); + if (expression) { + const slot = async () => typeof expression === "function" ? expression(...args) : expression; + return await renderSlotToString(result, slot).then((res) => { + return res; + }); + } + if (typeof component === "function") { + return await renderJSX(result, component(...args)).then( + (res) => res != null ? String(res) : res + ); + } + } + const content = await renderSlotToString(result, this.#slots[name]); + const outHTML = chunkToString(result, content); + return outHTML; + } +} + +function sequence(...handlers) { + const filtered = handlers.filter((h) => !!h); + const length = filtered.length; + if (!length) { + return defineMiddleware((_context, next) => { + return next(); + }); + } + return defineMiddleware((context, next) => { + let carriedPayload = void 0; + return applyHandle(0, context); + function applyHandle(i, handleContext) { + const handle = filtered[i]; + const result = handle(handleContext, async (payload) => { + if (i < length - 1) { + if (payload) { + let newRequest; + if (payload instanceof Request) { + newRequest = payload; + } else if (payload instanceof URL) { + newRequest = new Request(payload, handleContext.request.clone()); + } else { + newRequest = new Request( + new URL(payload, handleContext.url.origin), + handleContext.request.clone() + ); + } + const oldPathname = handleContext.url.pathname; + const pipeline = Reflect.get(handleContext, apiContextRoutesSymbol); + const { routeData, pathname } = await pipeline.tryRewrite( + payload, + handleContext.request + ); + if (pipeline.serverLike === true && handleContext.isPrerendered === false && routeData.prerender === true) { + throw new AstroError({ + ...ForbiddenRewrite, + message: ForbiddenRewrite.message( + handleContext.url.pathname, + pathname, + routeData.component + ), + hint: ForbiddenRewrite.hint(routeData.component) + }); + } + carriedPayload = payload; + handleContext.request = newRequest; + handleContext.url = new URL(newRequest.url); + handleContext.params = getParams(routeData, pathname); + handleContext.routePattern = routeData.route; + setOriginPathname( + handleContext.request, + oldPathname, + pipeline.manifest.trailingSlash, + pipeline.manifest.buildFormat + ); + } + return applyHandle(i + 1, handleContext); + } else { + return next(payload ?? carriedPayload); + } + }); + return result; + } + }); +} + +function defineMiddleware(fn) { + return fn; +} + +const PERSIST_SYMBOL = Symbol(); +const DEFAULT_COOKIE_NAME = "astro-session"; +const VALID_COOKIE_REGEX = /^[\w-]+$/; +const unflatten = (parsed, _) => { + return unflatten$1(parsed, { + URL: (href) => new URL(href) + }); +}; +const stringify = (data, _) => { + return stringify$1(data, { + // Support URL objects + URL: (val) => val instanceof URL && val.href + }); +}; +class AstroSession { + // The cookies object. + #cookies; + // The session configuration. + #config; + // The cookie config + #cookieConfig; + // The cookie name + #cookieName; + // The unstorage object for the session driver. + #storage; + #data; + // The session ID. A v4 UUID. + #sessionID; + // Sessions to destroy. Needed because we won't have the old session ID after it's destroyed locally. + #toDestroy = /* @__PURE__ */ new Set(); + // Session keys to delete. Used for partial data sets to avoid overwriting the deleted value. + #toDelete = /* @__PURE__ */ new Set(); + // Whether the session is dirty and needs to be saved. + #dirty = false; + // Whether the session cookie has been set. + #cookieSet = false; + // The local data is "partial" if it has not been loaded from storage yet and only + // contains values that have been set or deleted in-memory locally. + // We do this to avoid the need to block on loading data when it is only being set. + // When we load the data from storage, we need to merge it with the local partial data, + // preserving in-memory changes and deletions. + #partial = true; + static #sharedStorage = /* @__PURE__ */ new Map(); + constructor(cookies, { + cookie: cookieConfig = DEFAULT_COOKIE_NAME, + ...config + }, runtimeMode) { + const { driver } = config; + if (!driver) { + throw new AstroError({ + ...SessionStorageInitError, + message: SessionStorageInitError.message( + "No driver was defined in the session configuration and the adapter did not provide a default driver." + ) + }); + } + this.#cookies = cookies; + let cookieConfigObject; + if (typeof cookieConfig === "object") { + const { name = DEFAULT_COOKIE_NAME, ...rest } = cookieConfig; + this.#cookieName = name; + cookieConfigObject = rest; + } else { + this.#cookieName = cookieConfig || DEFAULT_COOKIE_NAME; + } + this.#cookieConfig = { + sameSite: "lax", + secure: runtimeMode === "production", + path: "/", + ...cookieConfigObject, + httpOnly: true + }; + this.#config = { ...config, driver }; + } + /** + * Gets a session value. Returns `undefined` if the session or value does not exist. + */ + async get(key) { + return (await this.#ensureData()).get(key)?.data; + } + /** + * Checks if a session value exists. + */ + async has(key) { + return (await this.#ensureData()).has(key); + } + /** + * Gets all session values. + */ + async keys() { + return (await this.#ensureData()).keys(); + } + /** + * Gets all session values. + */ + async values() { + return [...(await this.#ensureData()).values()].map((entry) => entry.data); + } + /** + * Gets all session entries. + */ + async entries() { + return [...(await this.#ensureData()).entries()].map(([key, entry]) => [key, entry.data]); + } + /** + * Deletes a session value. + */ + delete(key) { + this.#data?.delete(key); + if (this.#partial) { + this.#toDelete.add(key); + } + this.#dirty = true; + } + /** + * Sets a session value. The session is created if it does not exist. + */ + set(key, value, { ttl } = {}) { + if (!key) { + throw new AstroError({ + ...SessionStorageSaveError, + message: "The session key was not provided." + }); + } + let cloned; + try { + cloned = unflatten(JSON.parse(stringify(value))); + } catch (err) { + throw new AstroError( + { + ...SessionStorageSaveError, + message: `The session data for ${key} could not be serialized.`, + hint: "See the devalue library for all supported types: https://github.com/rich-harris/devalue" + }, + { cause: err } + ); + } + if (!this.#cookieSet) { + this.#setCookie(); + this.#cookieSet = true; + } + this.#data ??= /* @__PURE__ */ new Map(); + const lifetime = ttl ?? this.#config.ttl; + const expires = typeof lifetime === "number" ? Date.now() + lifetime * 1e3 : lifetime; + this.#data.set(key, { + data: cloned, + expires + }); + this.#dirty = true; + } + /** + * Destroys the session, clearing the cookie and storage if it exists. + */ + destroy() { + const sessionId = this.#sessionID ?? this.#cookies.get(this.#cookieName)?.value; + if (sessionId) { + this.#toDestroy.add(sessionId); + } + this.#cookies.delete(this.#cookieName, this.#cookieConfig); + this.#sessionID = void 0; + this.#data = void 0; + this.#dirty = true; + } + /** + * Regenerates the session, creating a new session ID. The existing session data is preserved. + */ + async regenerate() { + let data = /* @__PURE__ */ new Map(); + try { + data = await this.#ensureData(); + } catch (err) { + console.error("Failed to load session data during regeneration:", err); + } + const oldSessionId = this.#sessionID; + this.#sessionID = crypto.randomUUID(); + this.#data = data; + await this.#setCookie(); + if (oldSessionId && this.#storage) { + this.#storage.removeItem(oldSessionId).catch((err) => { + console.error("Failed to remove old session data:", err); + }); + } + } + // Persists the session data to storage. + // This is called automatically at the end of the request. + // Uses a symbol to prevent users from calling it directly. + async [PERSIST_SYMBOL]() { + if (!this.#dirty && !this.#toDestroy.size) { + return; + } + const storage = await this.#ensureStorage(); + if (this.#dirty && this.#data) { + const data = await this.#ensureData(); + this.#toDelete.forEach((key2) => data.delete(key2)); + const key = this.#ensureSessionID(); + let serialized; + try { + serialized = stringify(data); + } catch (err) { + throw new AstroError( + { + ...SessionStorageSaveError, + message: SessionStorageSaveError.message( + "The session data could not be serialized.", + this.#config.driver + ) + }, + { cause: err } + ); + } + await storage.setItem(key, serialized); + this.#dirty = false; + } + if (this.#toDestroy.size > 0) { + const cleanupPromises = [...this.#toDestroy].map( + (sessionId) => storage.removeItem(sessionId).catch((err) => { + console.error(`Failed to clean up session ${sessionId}:`, err); + }) + ); + await Promise.all(cleanupPromises); + this.#toDestroy.clear(); + } + } + get sessionID() { + return this.#sessionID; + } + /** + * Loads a session from storage with the given ID, and replaces the current session. + * Any changes made to the current session will be lost. + * This is not normally needed, as the session is automatically loaded using the cookie. + * However it can be used to restore a session where the ID has been recorded somewhere + * else (e.g. in a database). + */ + async load(sessionID) { + this.#sessionID = sessionID; + this.#data = void 0; + await this.#setCookie(); + await this.#ensureData(); + } + /** + * Sets the session cookie. + */ + async #setCookie() { + if (!VALID_COOKIE_REGEX.test(this.#cookieName)) { + throw new AstroError({ + ...SessionStorageSaveError, + message: "Invalid cookie name. Cookie names can only contain letters, numbers, and dashes." + }); + } + const value = this.#ensureSessionID(); + this.#cookies.set(this.#cookieName, value, this.#cookieConfig); + } + /** + * Attempts to load the session data from storage, or creates a new data object if none exists. + * If there is existing partial data, it will be merged into the new data object. + */ + async #ensureData() { + const storage = await this.#ensureStorage(); + if (this.#data && !this.#partial) { + return this.#data; + } + this.#data ??= /* @__PURE__ */ new Map(); + const raw = await storage.get(this.#ensureSessionID()); + if (!raw) { + return this.#data; + } + try { + const storedMap = unflatten(raw); + if (!(storedMap instanceof Map)) { + await this.destroy(); + throw new AstroError({ + ...SessionStorageInitError, + message: SessionStorageInitError.message( + "The session data was an invalid type.", + this.#config.driver + ) + }); + } + const now = Date.now(); + for (const [key, value] of storedMap) { + const expired = typeof value.expires === "number" && value.expires < now; + if (!this.#data.has(key) && !this.#toDelete.has(key) && !expired) { + this.#data.set(key, value); + } + } + this.#partial = false; + return this.#data; + } catch (err) { + await this.destroy(); + if (err instanceof AstroError) { + throw err; + } + throw new AstroError( + { + ...SessionStorageInitError, + message: SessionStorageInitError.message( + "The session data could not be parsed.", + this.#config.driver + ) + }, + { cause: err } + ); + } + } + /** + * Returns the session ID, generating a new one if it does not exist. + */ + #ensureSessionID() { + this.#sessionID ??= this.#cookies.get(this.#cookieName)?.value ?? crypto.randomUUID(); + return this.#sessionID; + } + /** + * Ensures the storage is initialized. + * This is called automatically when a storage operation is needed. + */ + async #ensureStorage() { + if (this.#storage) { + return this.#storage; + } + if (AstroSession.#sharedStorage.has(this.#config.driver)) { + this.#storage = AstroSession.#sharedStorage.get(this.#config.driver); + return this.#storage; + } + if (this.#config.driver === "test") { + this.#storage = this.#config.options.mockStorage; + return this.#storage; + } + if (this.#config.driver === "fs" || this.#config.driver === "fsLite" || this.#config.driver === "fs-lite") { + this.#config.options ??= {}; + this.#config.driver = "fs-lite"; + this.#config.options.base ??= ".astro/session"; + } + let driver = null; + try { + if (this.#config.driverModule) { + driver = (await this.#config.driverModule()).default; + } else if (this.#config.driver) { + const driverName = resolveSessionDriverName(this.#config.driver); + if (driverName) { + driver = (await import(driverName)).default; + } + } + } catch (err) { + if (err.code === "ERR_MODULE_NOT_FOUND") { + throw new AstroError( + { + ...SessionStorageInitError, + message: SessionStorageInitError.message( + err.message.includes(`Cannot find package`) ? "The driver module could not be found." : err.message, + this.#config.driver + ) + }, + { cause: err } + ); + } + throw err; + } + if (!driver) { + throw new AstroError({ + ...SessionStorageInitError, + message: SessionStorageInitError.message( + "The module did not export a driver.", + this.#config.driver + ) + }); + } + try { + this.#storage = createStorage({ + driver: driver(this.#config.options) + }); + AstroSession.#sharedStorage.set(this.#config.driver, this.#storage); + return this.#storage; + } catch (err) { + throw new AstroError( + { + ...SessionStorageInitError, + message: SessionStorageInitError.message("Unknown error", this.#config.driver) + }, + { cause: err } + ); + } + } +} +function resolveSessionDriverName(driver) { + if (!driver) { + return null; + } + try { + if (driver === "fs") { + return builtinDrivers.fsLite; + } + if (driver in builtinDrivers) { + return builtinDrivers[driver]; + } + } catch { + return null; + } + return driver; +} + +const apiContextRoutesSymbol = Symbol.for("context.routes"); +class RenderContext { + constructor(pipeline, locals, middleware, actions, pathname, request, routeData, status, clientAddress, cookies = new AstroCookies(request), params = getParams(routeData, pathname), url = new URL(request.url), props = {}, partial = void 0, shouldInjectCspMetaTags = !!pipeline.manifest.csp, session = pipeline.manifest.sessionConfig ? new AstroSession(cookies, pipeline.manifest.sessionConfig, pipeline.runtimeMode) : void 0) { + this.pipeline = pipeline; + this.locals = locals; + this.middleware = middleware; + this.actions = actions; + this.pathname = pathname; + this.request = request; + this.routeData = routeData; + this.status = status; + this.clientAddress = clientAddress; + this.cookies = cookies; + this.params = params; + this.url = url; + this.props = props; + this.partial = partial; + this.shouldInjectCspMetaTags = shouldInjectCspMetaTags; + this.session = session; + } + /** + * A flag that tells the render content if the rewriting was triggered + */ + isRewriting = false; + /** + * A safety net in case of loops + */ + counter = 0; + result = void 0; + static async create({ + locals = {}, + middleware, + pathname, + pipeline, + request, + routeData, + clientAddress, + status = 200, + props, + partial = void 0, + actions, + shouldInjectCspMetaTags + }) { + const pipelineMiddleware = await pipeline.getMiddleware(); + const pipelineActions = actions ?? await pipeline.getActions(); + setOriginPathname( + request, + pathname, + pipeline.manifest.trailingSlash, + pipeline.manifest.buildFormat + ); + return new RenderContext( + pipeline, + locals, + sequence(...pipeline.internalMiddleware, middleware ?? pipelineMiddleware), + pipelineActions, + pathname, + request, + routeData, + status, + clientAddress, + void 0, + void 0, + void 0, + props, + partial, + shouldInjectCspMetaTags ?? !!pipeline.manifest.csp + ); + } + /** + * The main function of the RenderContext. + * + * Use this function to render any route known to Astro. + * It attempts to render a route. A route can be a: + * + * - page + * - redirect + * - endpoint + * - fallback + */ + async render(componentInstance, slots = {}) { + const { middleware, pipeline } = this; + const { logger, serverLike, streaming, manifest } = pipeline; + const props = Object.keys(this.props).length > 0 ? this.props : await getProps({ + mod: componentInstance, + routeData: this.routeData, + routeCache: this.pipeline.routeCache, + pathname: this.pathname, + logger, + serverLike, + base: manifest.base + }); + const actionApiContext = this.createActionAPIContext(); + const apiContext = this.createAPIContext(props, actionApiContext); + this.counter++; + if (this.counter === 4) { + return new Response("Loop Detected", { + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/508 + status: 508, + statusText: "Astro detected a loop where you tried to call the rewriting logic more than four times." + }); + } + const lastNext = async (ctx, payload) => { + if (payload) { + const oldPathname = this.pathname; + pipeline.logger.debug("router", "Called rewriting to:", payload); + const { + routeData, + componentInstance: newComponent, + pathname, + newUrl + } = await pipeline.tryRewrite(payload, this.request); + if (this.pipeline.serverLike === true && this.routeData.prerender === false && routeData.prerender === true) { + throw new AstroError({ + ...ForbiddenRewrite, + message: ForbiddenRewrite.message(this.pathname, pathname, routeData.component), + hint: ForbiddenRewrite.hint(routeData.component) + }); + } + this.routeData = routeData; + componentInstance = newComponent; + if (payload instanceof Request) { + this.request = payload; + } else { + this.request = copyRequest( + newUrl, + this.request, + // need to send the flag of the previous routeData + routeData.prerender, + this.pipeline.logger, + this.routeData.route + ); + } + this.isRewriting = true; + this.url = new URL(this.request.url); + this.params = getParams(routeData, pathname); + this.pathname = pathname; + this.status = 200; + setOriginPathname( + this.request, + oldPathname, + this.pipeline.manifest.trailingSlash, + this.pipeline.manifest.buildFormat + ); + } + let response2; + if (!ctx.isPrerendered) { + const { action, setActionResult, serializeActionResult } = getActionContext(ctx); + if (action?.calledFrom === "form") { + const actionResult = await action.handler(); + setActionResult(action.name, serializeActionResult(actionResult)); + } + } + switch (this.routeData.type) { + case "endpoint": { + response2 = await renderEndpoint( + componentInstance, + ctx, + this.routeData.prerender, + logger + ); + break; + } + case "redirect": + return renderRedirect(this); + case "page": { + this.result = await this.createResult(componentInstance, actionApiContext); + try { + response2 = await renderPage( + this.result, + componentInstance?.default, + props, + slots, + streaming, + this.routeData + ); + } catch (e) { + this.result.cancelled = true; + throw e; + } + response2.headers.set(ROUTE_TYPE_HEADER, "page"); + if (this.routeData.route === "/404" || this.routeData.route === "/500") { + response2.headers.set(REROUTE_DIRECTIVE_HEADER, "no"); + } + if (this.isRewriting) { + response2.headers.set(REWRITE_DIRECTIVE_HEADER_KEY, REWRITE_DIRECTIVE_HEADER_VALUE); + } + break; + } + case "fallback": { + return new Response(null, { status: 500, headers: { [ROUTE_TYPE_HEADER]: "fallback" } }); + } + } + const responseCookies = getCookiesFromResponse(response2); + if (responseCookies) { + this.cookies.merge(responseCookies); + } + return response2; + }; + if (isRouteExternalRedirect(this.routeData)) { + return renderRedirect(this); + } + const response = await callMiddleware(middleware, apiContext, lastNext); + if (response.headers.get(ROUTE_TYPE_HEADER)) { + response.headers.delete(ROUTE_TYPE_HEADER); + } + attachCookiesToResponse(response, this.cookies); + return response; + } + createAPIContext(props, context) { + const redirect = (path, status = 302) => new Response(null, { status, headers: { Location: path } }); + Reflect.set(context, apiContextRoutesSymbol, this.pipeline); + return Object.assign(context, { + props, + redirect, + getActionResult: createGetActionResult(context.locals), + callAction: createCallAction(context) + }); + } + async #executeRewrite(reroutePayload) { + this.pipeline.logger.debug("router", "Calling rewrite: ", reroutePayload); + const oldPathname = this.pathname; + const { routeData, componentInstance, newUrl, pathname } = await this.pipeline.tryRewrite( + reroutePayload, + this.request + ); + const isI18nFallback = routeData.fallbackRoutes && routeData.fallbackRoutes.length > 0; + if (this.pipeline.serverLike && !this.routeData.prerender && routeData.prerender && !isI18nFallback) { + throw new AstroError({ + ...ForbiddenRewrite, + message: ForbiddenRewrite.message(this.pathname, pathname, routeData.component), + hint: ForbiddenRewrite.hint(routeData.component) + }); + } + this.routeData = routeData; + if (reroutePayload instanceof Request) { + this.request = reroutePayload; + } else { + this.request = copyRequest( + newUrl, + this.request, + // need to send the flag of the previous routeData + routeData.prerender, + this.pipeline.logger, + this.routeData.route + ); + } + this.url = new URL(this.request.url); + const newCookies = new AstroCookies(this.request); + if (this.cookies) { + newCookies.merge(this.cookies); + } + this.cookies = newCookies; + this.params = getParams(routeData, pathname); + this.pathname = pathname; + this.isRewriting = true; + this.status = 200; + setOriginPathname( + this.request, + oldPathname, + this.pipeline.manifest.trailingSlash, + this.pipeline.manifest.buildFormat + ); + return await this.render(componentInstance); + } + createActionAPIContext() { + const renderContext = this; + const { params, pipeline, url } = this; + const generator = `Astro v${ASTRO_VERSION}`; + const rewrite = async (reroutePayload) => { + return await this.#executeRewrite(reroutePayload); + }; + return { + // Don't allow reassignment of cookies because it doesn't work + get cookies() { + return renderContext.cookies; + }, + routePattern: this.routeData.route, + isPrerendered: this.routeData.prerender, + get clientAddress() { + return renderContext.getClientAddress(); + }, + get currentLocale() { + return renderContext.computeCurrentLocale(); + }, + generator, + get locals() { + return renderContext.locals; + }, + set locals(_) { + throw new AstroError(LocalsReassigned); + }, + params, + get preferredLocale() { + return renderContext.computePreferredLocale(); + }, + get preferredLocaleList() { + return renderContext.computePreferredLocaleList(); + }, + rewrite, + request: this.request, + site: pipeline.site, + url, + get originPathname() { + return getOriginPathname(renderContext.request); + }, + get session() { + if (this.isPrerendered) { + pipeline.logger.warn( + "session", + `context.session was used when rendering the route ${colors.green(this.routePattern)}, but it is not available on prerendered routes. If you need access to sessions, make sure that the route is server-rendered using \`export const prerender = false;\` or by setting \`output\` to \`"server"\` in your Astro config to make all your routes server-rendered by default. For more information, see https://docs.astro.build/en/guides/sessions/` + ); + return void 0; + } + if (!renderContext.session) { + pipeline.logger.warn( + "session", + `context.session was used when rendering the route ${colors.green(this.routePattern)}, but no storage configuration was provided. Either configure the storage manually or use an adapter that provides session storage. For more information, see https://docs.astro.build/en/guides/sessions/` + ); + return void 0; + } + return renderContext.session; + }, + get csp() { + return { + insertDirective(payload) { + if (!pipeline.manifest.csp) { + throw new AstroError(CspNotEnabled); + } + renderContext.result?.directives.push(payload); + }, + insertScriptResource(resource) { + if (!pipeline.manifest.csp) { + throw new AstroError(CspNotEnabled); + } + renderContext.result?.scriptResources.push(resource); + }, + insertStyleResource(resource) { + if (!pipeline.manifest.csp) { + throw new AstroError(CspNotEnabled); + } + renderContext.result?.styleResources.push(resource); + }, + insertStyleHash(hash) { + if (!pipeline.manifest.csp) { + throw new AstroError(CspNotEnabled); + } + renderContext.result?.styleHashes.push(hash); + }, + insertScriptHash(hash) { + if (!pipeline.manifest.csp) { + throw new AstroError(CspNotEnabled); + } + renderContext.result?.scriptHashes.push(hash); + } + }; + } + }; + } + async createResult(mod, ctx) { + const { cookies, pathname, pipeline, routeData, status } = this; + const { clientDirectives, inlinedScripts, compressHTML, manifest, renderers, resolve } = pipeline; + const { links, scripts, styles } = await pipeline.headElements(routeData); + const extraStyleHashes = []; + const extraScriptHashes = []; + const shouldInjectCspMetaTags = this.shouldInjectCspMetaTags; + const cspAlgorithm = manifest.csp?.algorithm ?? "SHA-256"; + if (shouldInjectCspMetaTags) { + for (const style of styles) { + extraStyleHashes.push(await generateCspDigest(style.children, cspAlgorithm)); + } + for (const script of scripts) { + extraScriptHashes.push(await generateCspDigest(script.children, cspAlgorithm)); + } + } + const componentMetadata = await pipeline.componentMetadata(routeData) ?? manifest.componentMetadata; + const headers = new Headers({ "Content-Type": "text/html" }); + const partial = typeof this.partial === "boolean" ? this.partial : Boolean(mod.partial); + const actionResult = hasActionPayload(this.locals) ? deserializeActionResult(this.locals._actionPayload.actionResult) : void 0; + const response = { + status: actionResult?.error ? actionResult?.error.status : status, + statusText: actionResult?.error ? actionResult?.error.type : "OK", + get headers() { + return headers; + }, + // Disallow `Astro.response.headers = new Headers` + set headers(_) { + throw new AstroError(AstroResponseHeadersReassigned); + } + }; + const result = { + base: manifest.base, + userAssetsBase: manifest.userAssetsBase, + cancelled: false, + clientDirectives, + inlinedScripts, + componentMetadata, + compressHTML, + cookies, + /** This function returns the `Astro` faux-global */ + createAstro: (astroGlobal, props, slots) => this.createAstro(result, astroGlobal, props, slots, ctx), + links, + params: this.params, + partial, + pathname, + renderers, + resolve, + response, + request: this.request, + scripts, + styles, + actionResult, + serverIslandNameMap: manifest.serverIslandNameMap ?? /* @__PURE__ */ new Map(), + key: manifest.key, + trailingSlash: manifest.trailingSlash, + _metadata: { + hasHydrationScript: false, + rendererSpecificHydrationScripts: /* @__PURE__ */ new Set(), + hasRenderedHead: false, + renderedScripts: /* @__PURE__ */ new Set(), + hasDirectives: /* @__PURE__ */ new Set(), + hasRenderedServerIslandRuntime: false, + headInTree: false, + extraHead: [], + extraStyleHashes, + extraScriptHashes, + propagators: /* @__PURE__ */ new Set() + }, + cspDestination: manifest.csp?.cspDestination ?? (routeData.prerender ? "meta" : "header"), + shouldInjectCspMetaTags, + cspAlgorithm, + // The following arrays must be cloned, otherwise they become mutable across routes. + scriptHashes: manifest.csp?.scriptHashes ? [...manifest.csp.scriptHashes] : [], + scriptResources: manifest.csp?.scriptResources ? [...manifest.csp.scriptResources] : [], + styleHashes: manifest.csp?.styleHashes ? [...manifest.csp.styleHashes] : [], + styleResources: manifest.csp?.styleResources ? [...manifest.csp.styleResources] : [], + directives: manifest.csp?.directives ? [...manifest.csp.directives] : [], + isStrictDynamic: manifest.csp?.isStrictDynamic ?? false, + internalFetchHeaders: manifest.internalFetchHeaders + }; + return result; + } + #astroPagePartial; + /** + * The Astro global is sourced in 3 different phases: + * - **Static**: `.generator` and `.glob` is printed by the compiler, instantiated once per process per astro file + * - **Page-level**: `.request`, `.cookies`, `.locals` etc. These remain the same for the duration of the request. + * - **Component-level**: `.props`, `.slots`, and `.self` are unique to each _use_ of each component. + * + * The page level partial is used as the prototype of the user-visible `Astro` global object, which is instantiated once per use of a component. + */ + createAstro(result, astroStaticPartial, props, slotValues, apiContext) { + let astroPagePartial; + if (this.isRewriting) { + astroPagePartial = this.#astroPagePartial = this.createAstroPagePartial( + result, + astroStaticPartial, + apiContext + ); + } else { + astroPagePartial = this.#astroPagePartial ??= this.createAstroPagePartial( + result, + astroStaticPartial, + apiContext + ); + } + const astroComponentPartial = { props, self: null }; + const Astro = Object.assign( + Object.create(astroPagePartial), + astroComponentPartial + ); + let _slots; + Object.defineProperty(Astro, "slots", { + get: () => { + if (!_slots) { + _slots = new Slots( + result, + slotValues, + this.pipeline.logger + ); + } + return _slots; + } + }); + return Astro; + } + createAstroPagePartial(result, astroStaticPartial, apiContext) { + const renderContext = this; + const { cookies, locals, params, pipeline, url } = this; + const { response } = result; + const redirect = (path, status = 302) => { + if (this.request[responseSentSymbol$1]) { + throw new AstroError({ + ...ResponseSentError + }); + } + return new Response(null, { status, headers: { Location: path } }); + }; + const rewrite = async (reroutePayload) => { + return await this.#executeRewrite(reroutePayload); + }; + const callAction = createCallAction(apiContext); + return { + generator: astroStaticPartial.generator, + glob: astroStaticPartial.glob, + routePattern: this.routeData.route, + isPrerendered: this.routeData.prerender, + cookies, + get session() { + if (this.isPrerendered) { + pipeline.logger.warn( + "session", + `Astro.session was used when rendering the route ${colors.green(this.routePattern)}, but it is not available on prerendered pages. If you need access to sessions, make sure that the page is server-rendered using \`export const prerender = false;\` or by setting \`output\` to \`"server"\` in your Astro config to make all your pages server-rendered by default. For more information, see https://docs.astro.build/en/guides/sessions/` + ); + return void 0; + } + if (!renderContext.session) { + pipeline.logger.warn( + "session", + `Astro.session was used when rendering the route ${colors.green(this.routePattern)}, but no storage configuration was provided. Either configure the storage manually or use an adapter that provides session storage. For more information, see https://docs.astro.build/en/guides/sessions/` + ); + return void 0; + } + return renderContext.session; + }, + get clientAddress() { + return renderContext.getClientAddress(); + }, + get currentLocale() { + return renderContext.computeCurrentLocale(); + }, + params, + get preferredLocale() { + return renderContext.computePreferredLocale(); + }, + get preferredLocaleList() { + return renderContext.computePreferredLocaleList(); + }, + locals, + redirect, + rewrite, + request: this.request, + response, + site: pipeline.site, + getActionResult: createGetActionResult(locals), + get callAction() { + return callAction; + }, + url, + get originPathname() { + return getOriginPathname(renderContext.request); + }, + get csp() { + return { + insertDirective(payload) { + if (!pipeline.manifest.csp) { + throw new AstroError(CspNotEnabled); + } + renderContext.result?.directives.push(payload); + }, + insertScriptResource(resource) { + if (!pipeline.manifest.csp) { + throw new AstroError(CspNotEnabled); + } + renderContext.result?.scriptResources.push(resource); + }, + insertStyleResource(resource) { + if (!pipeline.manifest.csp) { + throw new AstroError(CspNotEnabled); + } + renderContext.result?.styleResources.push(resource); + }, + insertStyleHash(hash) { + if (!pipeline.manifest.csp) { + throw new AstroError(CspNotEnabled); + } + renderContext.result?.styleHashes.push(hash); + }, + insertScriptHash(hash) { + if (!pipeline.manifest.csp) { + throw new AstroError(CspNotEnabled); + } + renderContext.result?.scriptHashes.push(hash); + } + }; + } + }; + } + getClientAddress() { + const { pipeline, request, routeData, clientAddress } = this; + if (routeData.prerender) { + throw new AstroError({ + ...PrerenderClientAddressNotAvailable, + message: PrerenderClientAddressNotAvailable.message(routeData.component) + }); + } + if (clientAddress) { + return clientAddress; + } + if (clientAddressSymbol in request) { + return Reflect.get(request, clientAddressSymbol); + } + if (pipeline.adapterName) { + throw new AstroError({ + ...ClientAddressNotAvailable, + message: ClientAddressNotAvailable.message(pipeline.adapterName) + }); + } + throw new AstroError(StaticClientAddressNotAvailable); + } + /** + * API Context may be created multiple times per request, i18n data needs to be computed only once. + * So, it is computed and saved here on creation of the first APIContext and reused for later ones. + */ + #currentLocale; + computeCurrentLocale() { + const { + url, + pipeline: { i18n }, + routeData + } = this; + if (!i18n) return; + const { defaultLocale, locales, strategy } = i18n; + const fallbackTo = strategy === "pathname-prefix-other-locales" || strategy === "domains-prefix-other-locales" ? defaultLocale : void 0; + if (this.#currentLocale) { + return this.#currentLocale; + } + let computedLocale; + if (isRouteServerIsland(routeData)) { + let referer = this.request.headers.get("referer"); + if (referer) { + if (URL.canParse(referer)) { + referer = new URL(referer).pathname; + } + computedLocale = computeCurrentLocale(referer, locales, defaultLocale); + } + } else { + let pathname = routeData.pathname; + if (!routeData.pattern.test(url.pathname)) { + for (const fallbackRoute of routeData.fallbackRoutes) { + if (fallbackRoute.pattern.test(url.pathname)) { + pathname = fallbackRoute.pathname; + break; + } + } + } + pathname = pathname && !isRoute404or500(routeData) ? pathname : url.pathname; + computedLocale = computeCurrentLocale(pathname, locales, defaultLocale); + } + this.#currentLocale = computedLocale ?? fallbackTo; + return this.#currentLocale; + } + #preferredLocale; + computePreferredLocale() { + const { + pipeline: { i18n }, + request + } = this; + if (!i18n) return; + return this.#preferredLocale ??= computePreferredLocale(request, i18n.locales); + } + #preferredLocaleList; + computePreferredLocaleList() { + const { + pipeline: { i18n }, + request + } = this; + if (!i18n) return; + return this.#preferredLocaleList ??= computePreferredLocaleList(request, i18n.locales); + } +} + +function redirectTemplate({ + status, + absoluteLocation, + relativeLocation, + from +}) { + const delay = status === 302 ? 2 : 0; + return ` +Redirecting to: ${relativeLocation} + + + + + Redirecting ${from ? `from ${from} ` : ""}to ${relativeLocation} +`; +} + +class AppPipeline extends Pipeline { + static create({ + logger, + manifest, + runtimeMode, + renderers, + resolve, + serverLike, + streaming, + defaultRoutes + }) { + const pipeline = new AppPipeline( + logger, + manifest, + runtimeMode, + renderers, + resolve, + serverLike, + streaming, + void 0, + void 0, + void 0, + void 0, + void 0, + void 0, + void 0, + void 0, + defaultRoutes + ); + return pipeline; + } + headElements(routeData) { + const routeInfo = this.manifest.routes.find((route) => route.routeData === routeData); + const links = /* @__PURE__ */ new Set(); + const scripts = /* @__PURE__ */ new Set(); + const styles = createStylesheetElementSet(routeInfo?.styles ?? []); + for (const script of routeInfo?.scripts ?? []) { + if ("stage" in script) { + if (script.stage === "head-inline") { + scripts.add({ + props: {}, + children: script.children + }); + } + } else { + scripts.add(createModuleScriptElement(script)); + } + } + return { links, styles, scripts }; + } + componentMetadata() { + } + async getComponentByRoute(routeData) { + const module = await this.getModuleForRoute(routeData); + return module.page(); + } + async tryRewrite(payload, request) { + const { newUrl, pathname, routeData } = findRouteToRewrite({ + payload, + request, + routes: this.manifest?.routes.map((r) => r.routeData), + trailingSlash: this.manifest.trailingSlash, + buildFormat: this.manifest.buildFormat, + base: this.manifest.base, + outDir: this.serverLike ? this.manifest.buildClientDir : this.manifest.outDir + }); + const componentInstance = await this.getComponentByRoute(routeData); + return { newUrl, pathname, componentInstance, routeData }; + } + async getModuleForRoute(route) { + for (const defaultRoute of this.defaultRoutes) { + if (route.component === defaultRoute.component) { + return { + page: () => Promise.resolve(defaultRoute.instance), + renderers: [] + }; + } + } + if (route.type === "redirect") { + return RedirectSinglePageBuiltModule; + } else { + if (this.manifest.pageMap) { + const importComponentInstance = this.manifest.pageMap.get(route.component); + if (!importComponentInstance) { + throw new Error( + `Unexpectedly unable to find a component instance for route ${route.route}` + ); + } + return await importComponentInstance(); + } else if (this.manifest.pageModule) { + return this.manifest.pageModule; + } + throw new Error( + "Astro couldn't find the correct page to render, probably because it wasn't correctly mapped for SSR usage. This is an internal error, please file an issue." + ); + } + } +} + +class App { + #manifest; + #manifestData; + #logger = new Logger({ + dest: consoleLogDestination, + level: "info" + }); + #baseWithoutTrailingSlash; + #pipeline; + #adapterLogger; + constructor(manifest, streaming = true) { + this.#manifest = manifest; + this.#manifestData = { + routes: manifest.routes.map((route) => route.routeData) + }; + ensure404Route(this.#manifestData); + this.#baseWithoutTrailingSlash = removeTrailingForwardSlash(this.#manifest.base); + this.#pipeline = this.#createPipeline(streaming); + this.#adapterLogger = new AstroIntegrationLogger( + this.#logger.options, + this.#manifest.adapterName + ); + } + getAdapterLogger() { + return this.#adapterLogger; + } + getAllowedDomains() { + return this.#manifest.allowedDomains; + } + get manifest() { + return this.#manifest; + } + set manifest(value) { + this.#manifest = value; + } + matchesAllowedDomains(forwardedHost, protocol) { + return App.validateForwardedHost(forwardedHost, this.#manifest.allowedDomains, protocol); + } + static validateForwardedHost(forwardedHost, allowedDomains, protocol) { + if (!allowedDomains || allowedDomains.length === 0) { + return false; + } + try { + const testUrl = new URL(`${protocol || "https"}://${forwardedHost}`); + return allowedDomains.some((pattern) => { + return matchPattern(testUrl, pattern); + }); + } catch { + return false; + } + } + /** + * Validate a hostname by rejecting any with path separators. + * Prevents path injection attacks. Invalid hostnames return undefined. + */ + static sanitizeHost(hostname) { + if (!hostname) return void 0; + if (/[/\\]/.test(hostname)) return void 0; + return hostname; + } + /** + * Validate forwarded headers (proto, host, port) against allowedDomains. + * Returns validated values or undefined for rejected headers. + * Uses strict defaults: http/https only for proto, rejects port if not in allowedDomains. + */ + static validateForwardedHeaders(forwardedProtocol, forwardedHost, forwardedPort, allowedDomains) { + const result = {}; + if (forwardedProtocol) { + if (allowedDomains && allowedDomains.length > 0) { + const hasProtocolPatterns = allowedDomains.some( + (pattern) => pattern.protocol !== void 0 + ); + if (hasProtocolPatterns) { + try { + const testUrl = new URL(`${forwardedProtocol}://example.com`); + const isAllowed = allowedDomains.some((pattern) => matchPattern(testUrl, pattern)); + if (isAllowed) { + result.protocol = forwardedProtocol; + } + } catch { + } + } else if (/^https?$/.test(forwardedProtocol)) { + result.protocol = forwardedProtocol; + } + } else if (/^https?$/.test(forwardedProtocol)) { + result.protocol = forwardedProtocol; + } + } + if (forwardedPort && allowedDomains && allowedDomains.length > 0) { + const hasPortPatterns = allowedDomains.some((pattern) => pattern.port !== void 0); + if (hasPortPatterns) { + const isAllowed = allowedDomains.some((pattern) => pattern.port === forwardedPort); + if (isAllowed) { + result.port = forwardedPort; + } + } + } + if (forwardedHost && forwardedHost.length > 0 && allowedDomains && allowedDomains.length > 0) { + const protoForValidation = result.protocol || "https"; + const sanitized = App.sanitizeHost(forwardedHost); + if (sanitized) { + try { + const hostnameOnly = sanitized.split(":")[0]; + const portFromHost = sanitized.includes(":") ? sanitized.split(":")[1] : void 0; + const portForValidation = result.port || portFromHost; + const hostWithPort = portForValidation ? `${hostnameOnly}:${portForValidation}` : hostnameOnly; + const testUrl = new URL(`${protoForValidation}://${hostWithPort}`); + const isAllowed = allowedDomains.some((pattern) => matchPattern(testUrl, pattern)); + if (isAllowed) { + result.host = sanitized; + } + } catch { + } + } + } + return result; + } + /** + * Creates a pipeline by reading the stored manifest + * + * @param streaming + * @private + */ + #createPipeline(streaming = false) { + return AppPipeline.create({ + logger: this.#logger, + manifest: this.#manifest, + runtimeMode: "production", + renderers: this.#manifest.renderers, + defaultRoutes: createDefaultRoutes(this.#manifest), + resolve: async (specifier) => { + if (!(specifier in this.#manifest.entryModules)) { + throw new Error(`Unable to resolve [${specifier}]`); + } + const bundlePath = this.#manifest.entryModules[specifier]; + if (bundlePath.startsWith("data:") || bundlePath.length === 0) { + return bundlePath; + } else { + return createAssetLink(bundlePath, this.#manifest.base, this.#manifest.assetsPrefix); + } + }, + serverLike: true, + streaming + }); + } + set setManifestData(newManifestData) { + this.#manifestData = newManifestData; + } + removeBase(pathname) { + if (pathname.startsWith(this.#manifest.base)) { + return pathname.slice(this.#baseWithoutTrailingSlash.length + 1); + } + return pathname; + } + /** + * It removes the base from the request URL, prepends it with a forward slash and attempts to decoded it. + * + * If the decoding fails, it logs the error and return the pathname as is. + * @param request + * @private + */ + #getPathnameFromRequest(request) { + const url = new URL(request.url); + const pathname = prependForwardSlash$1(this.removeBase(url.pathname)); + try { + return decodeURI(pathname); + } catch (e) { + this.getAdapterLogger().error(e.toString()); + return pathname; + } + } + /** + * Given a `Request`, it returns the `RouteData` that matches its `pathname`. By default, prerendered + * routes aren't returned, even if they are matched. + * + * When `allowPrerenderedRoutes` is `true`, the function returns matched prerendered routes too. + * @param request + * @param allowPrerenderedRoutes + */ + match(request, allowPrerenderedRoutes = false) { + const url = new URL(request.url); + if (this.#manifest.assets.has(url.pathname)) return void 0; + let pathname = this.#computePathnameFromDomain(request); + if (!pathname) { + pathname = prependForwardSlash$1(this.removeBase(url.pathname)); + } + let routeData = matchRoute(decodeURI(pathname), this.#manifestData); + if (!routeData) return void 0; + if (allowPrerenderedRoutes) { + return routeData; + } else if (routeData.prerender) { + return void 0; + } + return routeData; + } + #computePathnameFromDomain(request) { + let pathname = void 0; + const url = new URL(request.url); + if (this.#manifest.i18n && (this.#manifest.i18n.strategy === "domains-prefix-always" || this.#manifest.i18n.strategy === "domains-prefix-other-locales" || this.#manifest.i18n.strategy === "domains-prefix-always-no-redirect")) { + const validated = App.validateForwardedHeaders( + request.headers.get("X-Forwarded-Proto") ?? void 0, + request.headers.get("X-Forwarded-Host") ?? void 0, + request.headers.get("X-Forwarded-Port") ?? void 0, + this.#manifest.allowedDomains + ); + let protocol = validated.protocol ? validated.protocol + ":" : url.protocol; + let host = validated.host ?? request.headers.get("Host"); + if (host && protocol) { + host = host.split(":")[0]; + try { + let locale; + const hostAsUrl = new URL(`${protocol}//${host}`); + for (const [domainKey, localeValue] of Object.entries( + this.#manifest.i18n.domainLookupTable + )) { + const domainKeyAsUrl = new URL(domainKey); + if (hostAsUrl.host === domainKeyAsUrl.host && hostAsUrl.protocol === domainKeyAsUrl.protocol) { + locale = localeValue; + break; + } + } + if (locale) { + pathname = prependForwardSlash$1( + joinPaths(normalizeTheLocale(locale), this.removeBase(url.pathname)) + ); + if (url.pathname.endsWith("/")) { + pathname = appendForwardSlash$1(pathname); + } + } + } catch (e) { + this.#logger.error( + "router", + `Astro tried to parse ${protocol}//${host} as an URL, but it threw a parsing error. Check the X-Forwarded-Host and X-Forwarded-Proto headers.` + ); + this.#logger.error("router", `Error: ${e}`); + } + } + } + return pathname; + } + #redirectTrailingSlash(pathname) { + const { trailingSlash } = this.#manifest; + if (pathname === "/" || isInternalPath(pathname)) { + return pathname; + } + const path = collapseDuplicateTrailingSlashes(pathname, trailingSlash !== "never"); + if (path !== pathname) { + return path; + } + if (trailingSlash === "ignore") { + return pathname; + } + if (trailingSlash === "always" && !hasFileExtension(pathname)) { + return appendForwardSlash$1(pathname); + } + if (trailingSlash === "never") { + return removeTrailingForwardSlash(pathname); + } + return pathname; + } + async render(request, renderOptions) { + let routeData; + let locals; + let clientAddress; + let addCookieHeader; + const url = new URL(request.url); + const redirect = this.#redirectTrailingSlash(url.pathname); + const prerenderedErrorPageFetch = renderOptions?.prerenderedErrorPageFetch ?? fetch; + if (redirect !== url.pathname) { + const status = request.method === "GET" ? 301 : 308; + return new Response( + redirectTemplate({ + status, + relativeLocation: url.pathname, + absoluteLocation: redirect, + from: request.url + }), + { + status, + headers: { + location: redirect + url.search + } + } + ); + } + addCookieHeader = renderOptions?.addCookieHeader; + clientAddress = renderOptions?.clientAddress ?? Reflect.get(request, clientAddressSymbol); + routeData = renderOptions?.routeData; + locals = renderOptions?.locals; + if (routeData) { + this.#logger.debug( + "router", + "The adapter " + this.#manifest.adapterName + " provided a custom RouteData for ", + request.url + ); + this.#logger.debug("router", "RouteData:\n" + routeData); + } + if (locals) { + if (typeof locals !== "object") { + const error = new AstroError(LocalsNotAnObject); + this.#logger.error(null, error.stack); + return this.#renderError(request, { + status: 500, + error, + clientAddress, + prerenderedErrorPageFetch + }); + } + } + if (!routeData) { + routeData = this.match(request); + this.#logger.debug("router", "Astro matched the following route for " + request.url); + this.#logger.debug("router", "RouteData:\n" + routeData); + } + if (!routeData) { + routeData = this.#manifestData.routes.find( + (route) => route.component === "404.astro" || route.component === DEFAULT_404_COMPONENT + ); + } + if (!routeData) { + this.#logger.debug("router", "Astro hasn't found routes that match " + request.url); + this.#logger.debug("router", "Here's the available routes:\n", this.#manifestData); + return this.#renderError(request, { + locals, + status: 404, + clientAddress, + prerenderedErrorPageFetch + }); + } + const pathname = this.#getPathnameFromRequest(request); + const defaultStatus = this.#getDefaultStatusCode(routeData, pathname); + let response; + let session; + try { + const mod = await this.#pipeline.getModuleForRoute(routeData); + const renderContext = await RenderContext.create({ + pipeline: this.#pipeline, + locals, + pathname, + request, + routeData, + status: defaultStatus, + clientAddress + }); + session = renderContext.session; + response = await renderContext.render(await mod.page()); + } catch (err) { + this.#logger.error(null, err.stack || err.message || String(err)); + return this.#renderError(request, { + locals, + status: 500, + error: err, + clientAddress, + prerenderedErrorPageFetch + }); + } finally { + await session?.[PERSIST_SYMBOL](); + } + if (REROUTABLE_STATUS_CODES.includes(response.status) && response.headers.get(REROUTE_DIRECTIVE_HEADER) !== "no") { + return this.#renderError(request, { + locals, + response, + status: response.status, + // We don't have an error to report here. Passing null means we pass nothing intentionally + // while undefined means there's no error + error: response.status === 500 ? null : void 0, + clientAddress, + prerenderedErrorPageFetch + }); + } + if (response.headers.has(REROUTE_DIRECTIVE_HEADER)) { + response.headers.delete(REROUTE_DIRECTIVE_HEADER); + } + if (addCookieHeader) { + for (const setCookieHeaderValue of App.getSetCookieFromResponse(response)) { + response.headers.append("set-cookie", setCookieHeaderValue); + } + } + Reflect.set(response, responseSentSymbol$1, true); + return response; + } + setCookieHeaders(response) { + return getSetCookiesFromResponse(response); + } + /** + * Reads all the cookies written by `Astro.cookie.set()` onto the passed response. + * For example, + * ```ts + * for (const cookie_ of App.getSetCookieFromResponse(response)) { + * const cookie: string = cookie_ + * } + * ``` + * @param response The response to read cookies from. + * @returns An iterator that yields key-value pairs as equal-sign-separated strings. + */ + static getSetCookieFromResponse = getSetCookiesFromResponse; + /** + * If it is a known error code, try sending the according page (e.g. 404.astro / 500.astro). + * This also handles pre-rendered /404 or /500 routes + */ + async #renderError(request, { + locals, + status, + response: originalResponse, + skipMiddleware = false, + error, + clientAddress, + prerenderedErrorPageFetch + }) { + const errorRoutePath = `/${status}${this.#manifest.trailingSlash === "always" ? "/" : ""}`; + const errorRouteData = matchRoute(errorRoutePath, this.#manifestData); + const url = new URL(request.url); + if (errorRouteData) { + if (errorRouteData.prerender) { + const maybeDotHtml = errorRouteData.route.endsWith(`/${status}`) ? ".html" : ""; + const statusURL = new URL( + `${this.#baseWithoutTrailingSlash}/${status}${maybeDotHtml}`, + url + ); + if (statusURL.toString() !== request.url) { + const response2 = await prerenderedErrorPageFetch(statusURL.toString()); + const override = { status, removeContentEncodingHeaders: true }; + return this.#mergeResponses(response2, originalResponse, override); + } + } + const mod = await this.#pipeline.getModuleForRoute(errorRouteData); + let session; + try { + const renderContext = await RenderContext.create({ + locals, + pipeline: this.#pipeline, + middleware: skipMiddleware ? NOOP_MIDDLEWARE_FN : void 0, + pathname: this.#getPathnameFromRequest(request), + request, + routeData: errorRouteData, + status, + props: { error }, + clientAddress + }); + session = renderContext.session; + const response2 = await renderContext.render(await mod.page()); + return this.#mergeResponses(response2, originalResponse); + } catch { + if (skipMiddleware === false) { + return this.#renderError(request, { + locals, + status, + response: originalResponse, + skipMiddleware: true, + clientAddress, + prerenderedErrorPageFetch + }); + } + } finally { + await session?.[PERSIST_SYMBOL](); + } + } + const response = this.#mergeResponses(new Response(null, { status }), originalResponse); + Reflect.set(response, responseSentSymbol$1, true); + return response; + } + #mergeResponses(newResponse, originalResponse, override) { + let newResponseHeaders = newResponse.headers; + if (override?.removeContentEncodingHeaders) { + newResponseHeaders = new Headers(newResponseHeaders); + newResponseHeaders.delete("Content-Encoding"); + newResponseHeaders.delete("Content-Length"); + } + if (!originalResponse) { + if (override !== void 0) { + return new Response(newResponse.body, { + status: override.status, + statusText: newResponse.statusText, + headers: newResponseHeaders + }); + } + return newResponse; + } + const status = override?.status ? override.status : originalResponse.status === 200 ? newResponse.status : originalResponse.status; + try { + originalResponse.headers.delete("Content-type"); + } catch { + } + const mergedHeaders = new Map([ + ...Array.from(newResponseHeaders), + ...Array.from(originalResponse.headers) + ]); + const newHeaders = new Headers(); + for (const [name, value] of mergedHeaders) { + newHeaders.set(name, value); + } + return new Response(newResponse.body, { + status, + statusText: status === 200 ? newResponse.statusText : originalResponse.statusText, + // If you're looking at here for possible bugs, it means that it's not a bug. + // With the middleware, users can meddle with headers, and we should pass to the 404/500. + // If users see something weird, it's because they are setting some headers they should not. + // + // Although, we don't want it to replace the content-type, because the error page must return `text/html` + headers: newHeaders + }); + } + #getDefaultStatusCode(routeData, pathname) { + if (!routeData.pattern.test(pathname)) { + for (const fallbackRoute of routeData.fallbackRoutes) { + if (fallbackRoute.pattern.test(pathname)) { + return 302; + } + } + } + const route = removeTrailingForwardSlash(routeData.route); + if (route.endsWith("/404")) return 404; + if (route.endsWith("/500")) return 500; + return 200; + } +} + +const createOutgoingHttpHeaders = (headers) => { + if (!headers) { + return void 0; + } + const nodeHeaders = Object.fromEntries(headers.entries()); + if (Object.keys(nodeHeaders).length === 0) { + return void 0; + } + if (headers.has("set-cookie")) { + const cookieHeaders = headers.getSetCookie(); + if (cookieHeaders.length > 1) { + nodeHeaders["set-cookie"] = cookieHeaders; + } + } + return nodeHeaders; +}; + +function apply() { + if (!globalThis.crypto) { + Object.defineProperty(globalThis, "crypto", { + value: crypto$1.webcrypto + }); + } + if (!globalThis.File) { + Object.defineProperty(globalThis, "File", { + value: require$$0$3.File + }); + } +} + +class NodeApp extends App { + headersMap = void 0; + setHeadersMap(headers) { + this.headersMap = headers; + } + match(req, allowPrerenderedRoutes = false) { + if (!(req instanceof Request)) { + req = NodeApp.createRequest(req, { + skipBody: true, + allowedDomains: this.manifest.allowedDomains + }); + } + return super.match(req, allowPrerenderedRoutes); + } + render(req, routeDataOrOptions, maybeLocals) { + if (!(req instanceof Request)) { + req = NodeApp.createRequest(req, { + allowedDomains: this.manifest.allowedDomains + }); + } + return super.render(req, routeDataOrOptions, maybeLocals); + } + /** + * Converts a NodeJS IncomingMessage into a web standard Request. + * ```js + * import { NodeApp } from 'astro/app/node'; + * import { createServer } from 'node:http'; + * + * const server = createServer(async (req, res) => { + * const request = NodeApp.createRequest(req); + * const response = await app.render(request); + * await NodeApp.writeResponse(response, res); + * }) + * ``` + */ + static createRequest(req, { + skipBody = false, + allowedDomains = [] + } = {}) { + const controller = new AbortController(); + const isEncrypted = "encrypted" in req.socket && req.socket.encrypted; + const getFirstForwardedValue = (multiValueHeader) => { + return multiValueHeader?.toString()?.split(",").map((e) => e.trim())?.[0]; + }; + const providedProtocol = isEncrypted ? "https" : "http"; + const providedHostname = req.headers.host ?? req.headers[":authority"]; + const validated = App.validateForwardedHeaders( + getFirstForwardedValue(req.headers["x-forwarded-proto"]), + getFirstForwardedValue(req.headers["x-forwarded-host"]), + getFirstForwardedValue(req.headers["x-forwarded-port"]), + allowedDomains + ); + const protocol = validated.protocol ?? providedProtocol; + const sanitizedProvidedHostname = App.sanitizeHost( + typeof providedHostname === "string" ? providedHostname : void 0 + ); + const hostname = validated.host ?? sanitizedProvidedHostname; + const port = validated.port; + let url; + try { + const hostnamePort = getHostnamePort(hostname, port); + url = new URL(`${protocol}://${hostnamePort}${req.url}`); + } catch { + const hostnamePort = getHostnamePort(providedHostname, port); + url = new URL(`${providedProtocol}://${hostnamePort}`); + } + const options = { + method: req.method || "GET", + headers: makeRequestHeaders(req), + signal: controller.signal + }; + const bodyAllowed = options.method !== "HEAD" && options.method !== "GET" && skipBody === false; + if (bodyAllowed) { + Object.assign(options, makeRequestBody(req)); + } + const request = new Request(url, options); + const socket = getRequestSocket(req); + if (socket && typeof socket.on === "function") { + const existingCleanup = getAbortControllerCleanup(req); + if (existingCleanup) { + existingCleanup(); + } + let cleanedUp = false; + const removeSocketListener = () => { + if (typeof socket.off === "function") { + socket.off("close", onSocketClose); + } else if (typeof socket.removeListener === "function") { + socket.removeListener("close", onSocketClose); + } + }; + const cleanup = () => { + if (cleanedUp) return; + cleanedUp = true; + removeSocketListener(); + controller.signal.removeEventListener("abort", cleanup); + Reflect.deleteProperty(req, nodeRequestAbortControllerCleanupSymbol); + }; + const onSocketClose = () => { + cleanup(); + if (!controller.signal.aborted) { + controller.abort(); + } + }; + socket.on("close", onSocketClose); + controller.signal.addEventListener("abort", cleanup, { once: true }); + Reflect.set(req, nodeRequestAbortControllerCleanupSymbol, cleanup); + if (socket.destroyed) { + onSocketClose(); + } + } + const forwardedClientIp = getFirstForwardedValue(req.headers["x-forwarded-for"]); + const clientIp = forwardedClientIp || req.socket?.remoteAddress; + if (clientIp) { + Reflect.set(request, clientAddressSymbol, clientIp); + } + return request; + } + /** + * Streams a web-standard Response into a NodeJS Server Response. + * ```js + * import { NodeApp } from 'astro/app/node'; + * import { createServer } from 'node:http'; + * + * const server = createServer(async (req, res) => { + * const request = NodeApp.createRequest(req); + * const response = await app.render(request); + * await NodeApp.writeResponse(response, res); + * }) + * ``` + * @param source WhatWG Response + * @param destination NodeJS ServerResponse + */ + static async writeResponse(source, destination) { + const { status, headers, body, statusText } = source; + if (!(destination instanceof Http2ServerResponse)) { + destination.statusMessage = statusText; + } + destination.writeHead(status, createOutgoingHttpHeaders(headers)); + const cleanupAbortFromDestination = getAbortControllerCleanup( + destination.req ?? void 0 + ); + if (cleanupAbortFromDestination) { + const runCleanup = () => { + cleanupAbortFromDestination(); + if (typeof destination.off === "function") { + destination.off("finish", runCleanup); + destination.off("close", runCleanup); + } else { + destination.removeListener?.("finish", runCleanup); + destination.removeListener?.("close", runCleanup); + } + }; + destination.on("finish", runCleanup); + destination.on("close", runCleanup); + } + if (!body) return destination.end(); + try { + const reader = body.getReader(); + destination.on("close", () => { + reader.cancel().catch((err) => { + console.error( + `There was an uncaught error in the middle of the stream while rendering ${destination.req.url}.`, + err + ); + }); + }); + let result = await reader.read(); + while (!result.done) { + destination.write(result.value); + result = await reader.read(); + } + destination.end(); + } catch (err) { + destination.write("Internal server error", () => { + err instanceof Error ? destination.destroy(err) : destination.destroy(); + }); + } + } +} +function getHostnamePort(hostname, port) { + const portInHostname = typeof hostname === "string" && /:\d+$/.test(hostname); + const hostnamePort = portInHostname ? hostname : `${hostname}${port ? `:${port}` : ""}`; + return hostnamePort; +} +function makeRequestHeaders(req) { + const headers = new Headers(); + for (const [name, value] of Object.entries(req.headers)) { + if (value === void 0) { + continue; + } + if (Array.isArray(value)) { + for (const item of value) { + headers.append(name, item); + } + } else { + headers.append(name, value); + } + } + return headers; +} +function makeRequestBody(req) { + if (req.body !== void 0) { + if (typeof req.body === "string" && req.body.length > 0) { + return { body: Buffer.from(req.body) }; + } + if (typeof req.body === "object" && req.body !== null && Object.keys(req.body).length > 0) { + return { body: Buffer.from(JSON.stringify(req.body)) }; + } + if (typeof req.body === "object" && req.body !== null && typeof req.body[Symbol.asyncIterator] !== "undefined") { + return asyncIterableToBodyProps(req.body); + } + } + return asyncIterableToBodyProps(req); +} +function asyncIterableToBodyProps(iterable) { + return { + // Node uses undici for the Request implementation. Undici accepts + // a non-standard async iterable for the body. + // @ts-expect-error + body: iterable, + // The duplex property is required when using a ReadableStream or async + // iterable for the body. The type definitions do not include the duplex + // property because they are not up-to-date. + duplex: "half" + }; +} +function getAbortControllerCleanup(req) { + if (!req) return void 0; + const cleanup = Reflect.get(req, nodeRequestAbortControllerCleanupSymbol); + return typeof cleanup === "function" ? cleanup : void 0; +} +function getRequestSocket(req) { + if (req.socket && typeof req.socket.on === "function") { + return req.socket; + } + const http2Socket = req.stream?.session?.socket; + if (http2Socket && typeof http2Socket.on === "function") { + return http2Socket; + } + return void 0; +} + +apply(); + +function createAppHandler(app, options) { + const als = new AsyncLocalStorage(); + const logger = app.getAdapterLogger(); + process.on("unhandledRejection", (reason) => { + const requestUrl = als.getStore(); + logger.error(`Unhandled rejection while rendering ${requestUrl}`); + console.error(reason); + }); + const originUrl = options.experimentalErrorPageHost ? new URL(options.experimentalErrorPageHost) : void 0; + const prerenderedErrorPageFetch = originUrl ? (url) => { + const errorPageUrl = new URL(url); + errorPageUrl.protocol = originUrl.protocol; + errorPageUrl.host = originUrl.host; + return fetch(errorPageUrl); + } : void 0; + return async (req, res, next, locals) => { + let request; + try { + request = NodeApp.createRequest(req, { + allowedDomains: app.getAllowedDomains?.() ?? [] + }); + } catch (err) { + logger.error(`Could not render ${req.url}`); + console.error(err); + res.statusCode = 500; + res.end("Internal Server Error"); + return; + } + const routeData = app.match(request, true); + if (routeData) { + const response = await als.run( + request.url, + () => app.render(request, { + addCookieHeader: true, + locals, + routeData, + prerenderedErrorPageFetch + }) + ); + await NodeApp.writeResponse(response, res); + } else if (next) { + return next(); + } else { + const response = await app.render(req, { addCookieHeader: true, prerenderedErrorPageFetch }); + await NodeApp.writeResponse(response, res); + } + }; +} + +function createMiddleware(app, options) { + const handler = createAppHandler(app, options); + const logger = app.getAdapterLogger(); + return async (...args) => { + const [req, res, next, locals] = args; + if (req instanceof Error) { + const error = req; + if (next) { + return next(error); + } else { + throw error; + } + } + try { + await handler(req, res, next, locals); + } catch (err) { + logger.error(`Could not render ${req.url}`); + console.error(err); + if (!res.headersSent) { + res.writeHead(500, `Server error`); + res.end(); + } + } + }; +} + +const STATIC_HEADERS_FILE = "_experimentalHeaders.json"; + +var serverDestroy; +var hasRequiredServerDestroy; + +function requireServerDestroy () { + if (hasRequiredServerDestroy) return serverDestroy; + hasRequiredServerDestroy = 1; + serverDestroy = enableDestroy; + + function enableDestroy(server) { + var connections = {}; + + server.on('connection', function(conn) { + var key = conn.remoteAddress + ':' + conn.remotePort; + connections[key] = conn; + conn.on('close', function() { + delete connections[key]; + }); + }); + + server.destroy = function(cb) { + server.close(cb); + for (var key in connections) + connections[key].destroy(); + }; + } + return serverDestroy; +} + +var serverDestroyExports = requireServerDestroy(); +const enableDestroy = /*@__PURE__*/getDefaultExportFromCjs(serverDestroyExports); + +const wildcardHosts = /* @__PURE__ */ new Set(["0.0.0.0", "::", "0000:0000:0000:0000:0000:0000:0000:0000"]); +async function logListeningOn(logger, server, configuredHost) { + await new Promise((resolve) => server.once("listening", resolve)); + const protocol = server instanceof https.Server ? "https" : "http"; + const host = getResolvedHostForHttpServer(configuredHost); + const { port } = server.address(); + const address = getNetworkAddress(protocol, host, port); + if (host === void 0 || wildcardHosts.has(host)) { + logger.info( + `Server listening on + local: ${address.local[0]} + network: ${address.network[0]} +` + ); + } else { + logger.info(`Server listening on ${address.local[0]}`); + } +} +function getResolvedHostForHttpServer(host) { + if (host === false) { + return "localhost"; + } else if (host === true) { + return void 0; + } else { + return host; + } +} +function getNetworkAddress(protocol = "http", hostname, port, base) { + const NetworkAddress = { + local: [], + network: [] + }; + Object.values(os.networkInterfaces()).flatMap((nInterface) => nInterface ?? []).filter( + (detail) => detail && detail.address && (detail.family === "IPv4" || // @ts-expect-error Node 18.0 - 18.3 returns number + detail.family === 4) + ).forEach((detail) => { + let host = detail.address.replace( + "127.0.0.1", + hostname === void 0 || wildcardHosts.has(hostname) ? "localhost" : hostname + ); + if (host.includes(":")) { + host = `[${host}]`; + } + const url = `${protocol}://${host}:${port}${""}`; + if (detail.address.includes("127.0.0.1")) { + NetworkAddress.local.push(url); + } else { + NetworkAddress.network.push(url); + } + }); + return NetworkAddress; +} + +var httpErrors = {exports: {}}; + +/*! + * depd + * Copyright(c) 2014-2018 Douglas Christopher Wilson + * MIT Licensed + */ + +var depd_1; +var hasRequiredDepd; + +function requireDepd () { + if (hasRequiredDepd) return depd_1; + hasRequiredDepd = 1; + /** + * Module dependencies. + */ + + var relative = require$$0$4.relative; + + /** + * Module exports. + */ + + depd_1 = depd; + + /** + * Get the path to base files on. + */ + + var basePath = process.cwd(); + + /** + * Determine if namespace is contained in the string. + */ + + function containsNamespace (str, namespace) { + var vals = str.split(/[ ,]+/); + var ns = String(namespace).toLowerCase(); + + for (var i = 0; i < vals.length; i++) { + var val = vals[i]; + + // namespace contained + if (val && (val === '*' || val.toLowerCase() === ns)) { + return true + } + } + + return false + } + + /** + * Convert a data descriptor to accessor descriptor. + */ + + function convertDataDescriptorToAccessor (obj, prop, message) { + var descriptor = Object.getOwnPropertyDescriptor(obj, prop); + var value = descriptor.value; + + descriptor.get = function getter () { return value }; + + if (descriptor.writable) { + descriptor.set = function setter (val) { return (value = val) }; + } + + delete descriptor.value; + delete descriptor.writable; + + Object.defineProperty(obj, prop, descriptor); + + return descriptor + } + + /** + * Create arguments string to keep arity. + */ + + function createArgumentsString (arity) { + var str = ''; + + for (var i = 0; i < arity; i++) { + str += ', arg' + i; + } + + return str.substr(2) + } + + /** + * Create stack string from stack. + */ + + function createStackString (stack) { + var str = this.name + ': ' + this.namespace; + + if (this.message) { + str += ' deprecated ' + this.message; + } + + for (var i = 0; i < stack.length; i++) { + str += '\n at ' + stack[i].toString(); + } + + return str + } + + /** + * Create deprecate for namespace in caller. + */ + + function depd (namespace) { + if (!namespace) { + throw new TypeError('argument namespace is required') + } + + var stack = getStack(); + var site = callSiteLocation(stack[1]); + var file = site[0]; + + function deprecate (message) { + // call to self as log + log.call(deprecate, message); + } + + deprecate._file = file; + deprecate._ignored = isignored(namespace); + deprecate._namespace = namespace; + deprecate._traced = istraced(namespace); + deprecate._warned = Object.create(null); + + deprecate.function = wrapfunction; + deprecate.property = wrapproperty; + + return deprecate + } + + /** + * Determine if event emitter has listeners of a given type. + * + * The way to do this check is done three different ways in Node.js >= 0.8 + * so this consolidates them into a minimal set using instance methods. + * + * @param {EventEmitter} emitter + * @param {string} type + * @returns {boolean} + * @private + */ + + function eehaslisteners (emitter, type) { + var count = typeof emitter.listenerCount !== 'function' + ? emitter.listeners(type).length + : emitter.listenerCount(type); + + return count > 0 + } + + /** + * Determine if namespace is ignored. + */ + + function isignored (namespace) { + if (process.noDeprecation) { + // --no-deprecation support + return true + } + + var str = process.env.NO_DEPRECATION || ''; + + // namespace ignored + return containsNamespace(str, namespace) + } + + /** + * Determine if namespace is traced. + */ + + function istraced (namespace) { + if (process.traceDeprecation) { + // --trace-deprecation support + return true + } + + var str = process.env.TRACE_DEPRECATION || ''; + + // namespace traced + return containsNamespace(str, namespace) + } + + /** + * Display deprecation message. + */ + + function log (message, site) { + var haslisteners = eehaslisteners(process, 'deprecation'); + + // abort early if no destination + if (!haslisteners && this._ignored) { + return + } + + var caller; + var callFile; + var callSite; + var depSite; + var i = 0; + var seen = false; + var stack = getStack(); + var file = this._file; + + if (site) { + // provided site + depSite = site; + callSite = callSiteLocation(stack[1]); + callSite.name = depSite.name; + file = callSite[0]; + } else { + // get call site + i = 2; + depSite = callSiteLocation(stack[i]); + callSite = depSite; + } + + // get caller of deprecated thing in relation to file + for (; i < stack.length; i++) { + caller = callSiteLocation(stack[i]); + callFile = caller[0]; + + if (callFile === file) { + seen = true; + } else if (callFile === this._file) { + file = this._file; + } else if (seen) { + break + } + } + + var key = caller + ? depSite.join(':') + '__' + caller.join(':') + : undefined; + + if (key !== undefined && key in this._warned) { + // already warned + return + } + + this._warned[key] = true; + + // generate automatic message from call site + var msg = message; + if (!msg) { + msg = callSite === depSite || !callSite.name + ? defaultMessage(depSite) + : defaultMessage(callSite); + } + + // emit deprecation if listeners exist + if (haslisteners) { + var err = DeprecationError(this._namespace, msg, stack.slice(i)); + process.emit('deprecation', err); + return + } + + // format and write message + var format = process.stderr.isTTY + ? formatColor + : formatPlain; + var output = format.call(this, msg, caller, stack.slice(i)); + process.stderr.write(output + '\n', 'utf8'); + } + + /** + * Get call site location as array. + */ + + function callSiteLocation (callSite) { + var file = callSite.getFileName() || ''; + var line = callSite.getLineNumber(); + var colm = callSite.getColumnNumber(); + + if (callSite.isEval()) { + file = callSite.getEvalOrigin() + ', ' + file; + } + + var site = [file, line, colm]; + + site.callSite = callSite; + site.name = callSite.getFunctionName(); + + return site + } + + /** + * Generate a default message from the site. + */ + + function defaultMessage (site) { + var callSite = site.callSite; + var funcName = site.name; + + // make useful anonymous name + if (!funcName) { + funcName = ''; + } + + var context = callSite.getThis(); + var typeName = context && callSite.getTypeName(); + + // ignore useless type name + if (typeName === 'Object') { + typeName = undefined; + } + + // make useful type name + if (typeName === 'Function') { + typeName = context.name || typeName; + } + + return typeName && callSite.getMethodName() + ? typeName + '.' + funcName + : funcName + } + + /** + * Format deprecation message without color. + */ + + function formatPlain (msg, caller, stack) { + var timestamp = new Date().toUTCString(); + + var formatted = timestamp + + ' ' + this._namespace + + ' deprecated ' + msg; + + // add stack trace + if (this._traced) { + for (var i = 0; i < stack.length; i++) { + formatted += '\n at ' + stack[i].toString(); + } + + return formatted + } + + if (caller) { + formatted += ' at ' + formatLocation(caller); + } + + return formatted + } + + /** + * Format deprecation message with color. + */ + + function formatColor (msg, caller, stack) { + var formatted = '\x1b[36;1m' + this._namespace + '\x1b[22;39m' + // bold cyan + ' \x1b[33;1mdeprecated\x1b[22;39m' + // bold yellow + ' \x1b[0m' + msg + '\x1b[39m'; // reset + + // add stack trace + if (this._traced) { + for (var i = 0; i < stack.length; i++) { + formatted += '\n \x1b[36mat ' + stack[i].toString() + '\x1b[39m'; // cyan + } + + return formatted + } + + if (caller) { + formatted += ' \x1b[36m' + formatLocation(caller) + '\x1b[39m'; // cyan + } + + return formatted + } + + /** + * Format call site location. + */ + + function formatLocation (callSite) { + return relative(basePath, callSite[0]) + + ':' + callSite[1] + + ':' + callSite[2] + } + + /** + * Get the stack as array of call sites. + */ + + function getStack () { + var limit = Error.stackTraceLimit; + var obj = {}; + var prep = Error.prepareStackTrace; + + Error.prepareStackTrace = prepareObjectStackTrace; + Error.stackTraceLimit = Math.max(10, limit); + + // capture the stack + Error.captureStackTrace(obj); + + // slice this function off the top + var stack = obj.stack.slice(1); + + Error.prepareStackTrace = prep; + Error.stackTraceLimit = limit; + + return stack + } + + /** + * Capture call site stack from v8. + */ + + function prepareObjectStackTrace (obj, stack) { + return stack + } + + /** + * Return a wrapped function in a deprecation message. + */ + + function wrapfunction (fn, message) { + if (typeof fn !== 'function') { + throw new TypeError('argument fn must be a function') + } + + var args = createArgumentsString(fn.length); + var stack = getStack(); + var site = callSiteLocation(stack[1]); + + site.name = fn.name; + + // eslint-disable-next-line no-new-func + var deprecatedfn = new Function('fn', 'log', 'deprecate', 'message', 'site', + '"use strict"\n' + + 'return function (' + args + ') {' + + 'log.call(deprecate, message, site)\n' + + 'return fn.apply(this, arguments)\n' + + '}')(fn, log, this, message, site); + + return deprecatedfn + } + + /** + * Wrap property in a deprecation message. + */ + + function wrapproperty (obj, prop, message) { + if (!obj || (typeof obj !== 'object' && typeof obj !== 'function')) { + throw new TypeError('argument obj must be object') + } + + var descriptor = Object.getOwnPropertyDescriptor(obj, prop); + + if (!descriptor) { + throw new TypeError('must call property on owner object') + } + + if (!descriptor.configurable) { + throw new TypeError('property must be configurable') + } + + var deprecate = this; + var stack = getStack(); + var site = callSiteLocation(stack[1]); + + // set site name + site.name = prop; + + // convert data descriptor + if ('value' in descriptor) { + descriptor = convertDataDescriptorToAccessor(obj, prop); + } + + var get = descriptor.get; + var set = descriptor.set; + + // wrap getter + if (typeof get === 'function') { + descriptor.get = function getter () { + log.call(deprecate, message, site); + return get.apply(this, arguments) + }; + } + + // wrap setter + if (typeof set === 'function') { + descriptor.set = function setter () { + log.call(deprecate, message, site); + return set.apply(this, arguments) + }; + } + + Object.defineProperty(obj, prop, descriptor); + } + + /** + * Create DeprecationError for deprecation + */ + + function DeprecationError (namespace, message, stack) { + var error = new Error(); + var stackString; + + Object.defineProperty(error, 'constructor', { + value: DeprecationError + }); + + Object.defineProperty(error, 'message', { + configurable: true, + enumerable: false, + value: message, + writable: true + }); + + Object.defineProperty(error, 'name', { + enumerable: false, + configurable: true, + value: 'DeprecationError', + writable: true + }); + + Object.defineProperty(error, 'namespace', { + configurable: true, + enumerable: false, + value: namespace, + writable: true + }); + + Object.defineProperty(error, 'stack', { + configurable: true, + enumerable: false, + get: function () { + if (stackString !== undefined) { + return stackString + } + + // prepare stack trace + return (stackString = createStackString.call(this, stack)) + }, + set: function setter (val) { + stackString = val; + } + }); + + return error + } + return depd_1; +} + +var setprototypeof; +var hasRequiredSetprototypeof; + +function requireSetprototypeof () { + if (hasRequiredSetprototypeof) return setprototypeof; + hasRequiredSetprototypeof = 1; + /* eslint no-proto: 0 */ + setprototypeof = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array ? setProtoOf : mixinProperties); + + function setProtoOf (obj, proto) { + obj.__proto__ = proto; + return obj + } + + function mixinProperties (obj, proto) { + for (var prop in proto) { + if (!Object.prototype.hasOwnProperty.call(obj, prop)) { + obj[prop] = proto[prop]; + } + } + return obj + } + return setprototypeof; +} + +const require$$0$2 = { + "100": "Continue", + "101": "Switching Protocols", + "102": "Processing", + "103": "Early Hints", + "200": "OK", + "201": "Created", + "202": "Accepted", + "203": "Non-Authoritative Information", + "204": "No Content", + "205": "Reset Content", + "206": "Partial Content", + "207": "Multi-Status", + "208": "Already Reported", + "226": "IM Used", + "300": "Multiple Choices", + "301": "Moved Permanently", + "302": "Found", + "303": "See Other", + "304": "Not Modified", + "305": "Use Proxy", + "307": "Temporary Redirect", + "308": "Permanent Redirect", + "400": "Bad Request", + "401": "Unauthorized", + "402": "Payment Required", + "403": "Forbidden", + "404": "Not Found", + "405": "Method Not Allowed", + "406": "Not Acceptable", + "407": "Proxy Authentication Required", + "408": "Request Timeout", + "409": "Conflict", + "410": "Gone", + "411": "Length Required", + "412": "Precondition Failed", + "413": "Payload Too Large", + "414": "URI Too Long", + "415": "Unsupported Media Type", + "416": "Range Not Satisfiable", + "417": "Expectation Failed", + "418": "I'm a Teapot", + "421": "Misdirected Request", + "422": "Unprocessable Entity", + "423": "Locked", + "424": "Failed Dependency", + "425": "Too Early", + "426": "Upgrade Required", + "428": "Precondition Required", + "429": "Too Many Requests", + "431": "Request Header Fields Too Large", + "451": "Unavailable For Legal Reasons", + "500": "Internal Server Error", + "501": "Not Implemented", + "502": "Bad Gateway", + "503": "Service Unavailable", + "504": "Gateway Timeout", + "505": "HTTP Version Not Supported", + "506": "Variant Also Negotiates", + "507": "Insufficient Storage", + "508": "Loop Detected", + "509": "Bandwidth Limit Exceeded", + "510": "Not Extended", + "511": "Network Authentication Required", +}; + +/*! + * statuses + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2016 Douglas Christopher Wilson + * MIT Licensed + */ + +var statuses$1; +var hasRequiredStatuses$1; + +function requireStatuses$1 () { + if (hasRequiredStatuses$1) return statuses$1; + hasRequiredStatuses$1 = 1; + + /** + * Module dependencies. + * @private + */ + + var codes = require$$0$2; + + /** + * Module exports. + * @public + */ + + statuses$1 = status; + + // status code to message map + status.message = codes; + + // status message (lower-case) to code map + status.code = createMessageToStatusCodeMap(codes); + + // array of status codes + status.codes = createStatusCodeList(codes); + + // status codes for redirects + status.redirect = { + 300: true, + 301: true, + 302: true, + 303: true, + 305: true, + 307: true, + 308: true + }; + + // status codes for empty bodies + status.empty = { + 204: true, + 205: true, + 304: true + }; + + // status codes for when you should retry the request + status.retry = { + 502: true, + 503: true, + 504: true + }; + + /** + * Create a map of message to status code. + * @private + */ + + function createMessageToStatusCodeMap (codes) { + var map = {}; + + Object.keys(codes).forEach(function forEachCode (code) { + var message = codes[code]; + var status = Number(code); + + // populate map + map[message.toLowerCase()] = status; + }); + + return map + } + + /** + * Create a list of all status codes. + * @private + */ + + function createStatusCodeList (codes) { + return Object.keys(codes).map(function mapCode (code) { + return Number(code) + }) + } + + /** + * Get the status code for given message. + * @private + */ + + function getStatusCode (message) { + var msg = message.toLowerCase(); + + if (!Object.prototype.hasOwnProperty.call(status.code, msg)) { + throw new Error('invalid status message: "' + message + '"') + } + + return status.code[msg] + } + + /** + * Get the status message for given code. + * @private + */ + + function getStatusMessage (code) { + if (!Object.prototype.hasOwnProperty.call(status.message, code)) { + throw new Error('invalid status code: ' + code) + } + + return status.message[code] + } + + /** + * Get the status code. + * + * Given a number, this will throw if it is not a known status + * code, otherwise the code will be returned. Given a string, + * the string will be parsed for a number and return the code + * if valid, otherwise will lookup the code assuming this is + * the status message. + * + * @param {string|number} code + * @returns {number} + * @public + */ + + function status (code) { + if (typeof code === 'number') { + return getStatusMessage(code) + } + + if (typeof code !== 'string') { + throw new TypeError('code must be a number or string') + } + + // '403' + var n = parseInt(code, 10); + if (!isNaN(n)) { + return getStatusMessage(n) + } + + return getStatusCode(code) + } + return statuses$1; +} + +var inherits = {exports: {}}; + +var inherits_browser = {exports: {}}; + +var hasRequiredInherits_browser; + +function requireInherits_browser () { + if (hasRequiredInherits_browser) return inherits_browser.exports; + hasRequiredInherits_browser = 1; + if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + inherits_browser.exports = function inherits(ctor, superCtor) { + if (superCtor) { + ctor.super_ = superCtor; + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + } + }; + } else { + // old school shim for old browsers + inherits_browser.exports = function inherits(ctor, superCtor) { + if (superCtor) { + ctor.super_ = superCtor; + var TempCtor = function () {}; + TempCtor.prototype = superCtor.prototype; + ctor.prototype = new TempCtor(); + ctor.prototype.constructor = ctor; + } + }; + } + return inherits_browser.exports; +} + +var hasRequiredInherits; + +function requireInherits () { + if (hasRequiredInherits) return inherits.exports; + hasRequiredInherits = 1; + try { + var util = require('util'); + /* istanbul ignore next */ + if (typeof util.inherits !== 'function') throw ''; + inherits.exports = util.inherits; + } catch (e) { + /* istanbul ignore next */ + inherits.exports = requireInherits_browser(); + } + return inherits.exports; +} + +/*! + * toidentifier + * Copyright(c) 2016 Douglas Christopher Wilson + * MIT Licensed + */ + +var toidentifier; +var hasRequiredToidentifier; + +function requireToidentifier () { + if (hasRequiredToidentifier) return toidentifier; + hasRequiredToidentifier = 1; + + /** + * Module exports. + * @public + */ + + toidentifier = toIdentifier; + + /** + * Trasform the given string into a JavaScript identifier + * + * @param {string} str + * @returns {string} + * @public + */ + + function toIdentifier (str) { + return str + .split(' ') + .map(function (token) { + return token.slice(0, 1).toUpperCase() + token.slice(1) + }) + .join('') + .replace(/[^ _0-9a-z]/gi, '') + } + return toidentifier; +} + +/*! + * http-errors + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2016 Douglas Christopher Wilson + * MIT Licensed + */ + +var hasRequiredHttpErrors; + +function requireHttpErrors () { + if (hasRequiredHttpErrors) return httpErrors.exports; + hasRequiredHttpErrors = 1; + (function (module) { + + /** + * Module dependencies. + * @private + */ + + var deprecate = requireDepd()('http-errors'); + var setPrototypeOf = requireSetprototypeof(); + var statuses = requireStatuses$1(); + var inherits = requireInherits(); + var toIdentifier = requireToidentifier(); + + /** + * Module exports. + * @public + */ + + module.exports = createError; + module.exports.HttpError = createHttpErrorConstructor(); + module.exports.isHttpError = createIsHttpErrorFunction(module.exports.HttpError); + + // Populate exports for all constructors + populateConstructorExports(module.exports, statuses.codes, module.exports.HttpError); + + /** + * Get the code class of a status code. + * @private + */ + + function codeClass (status) { + return Number(String(status).charAt(0) + '00') + } + + /** + * Create a new HTTP Error. + * + * @returns {Error} + * @public + */ + + function createError () { + // so much arity going on ~_~ + var err; + var msg; + var status = 500; + var props = {}; + for (var i = 0; i < arguments.length; i++) { + var arg = arguments[i]; + var type = typeof arg; + if (type === 'object' && arg instanceof Error) { + err = arg; + status = err.status || err.statusCode || status; + } else if (type === 'number' && i === 0) { + status = arg; + } else if (type === 'string') { + msg = arg; + } else if (type === 'object') { + props = arg; + } else { + throw new TypeError('argument #' + (i + 1) + ' unsupported type ' + type) + } + } + + if (typeof status === 'number' && (status < 400 || status >= 600)) { + deprecate('non-error status code; use only 4xx or 5xx status codes'); + } + + if (typeof status !== 'number' || + (!statuses.message[status] && (status < 400 || status >= 600))) { + status = 500; + } + + // constructor + var HttpError = createError[status] || createError[codeClass(status)]; + + if (!err) { + // create error + err = HttpError + ? new HttpError(msg) + : new Error(msg || statuses.message[status]); + Error.captureStackTrace(err, createError); + } + + if (!HttpError || !(err instanceof HttpError) || err.status !== status) { + // add properties to generic error + err.expose = status < 500; + err.status = err.statusCode = status; + } + + for (var key in props) { + if (key !== 'status' && key !== 'statusCode') { + err[key] = props[key]; + } + } + + return err + } + + /** + * Create HTTP error abstract base class. + * @private + */ + + function createHttpErrorConstructor () { + function HttpError () { + throw new TypeError('cannot construct abstract class') + } + + inherits(HttpError, Error); + + return HttpError + } + + /** + * Create a constructor for a client error. + * @private + */ + + function createClientErrorConstructor (HttpError, name, code) { + var className = toClassName(name); + + function ClientError (message) { + // create the error object + var msg = message != null ? message : statuses.message[code]; + var err = new Error(msg); + + // capture a stack trace to the construction point + Error.captureStackTrace(err, ClientError); + + // adjust the [[Prototype]] + setPrototypeOf(err, ClientError.prototype); + + // redefine the error message + Object.defineProperty(err, 'message', { + enumerable: true, + configurable: true, + value: msg, + writable: true + }); + + // redefine the error name + Object.defineProperty(err, 'name', { + enumerable: false, + configurable: true, + value: className, + writable: true + }); + + return err + } + + inherits(ClientError, HttpError); + nameFunc(ClientError, className); + + ClientError.prototype.status = code; + ClientError.prototype.statusCode = code; + ClientError.prototype.expose = true; + + return ClientError + } + + /** + * Create function to test is a value is a HttpError. + * @private + */ + + function createIsHttpErrorFunction (HttpError) { + return function isHttpError (val) { + if (!val || typeof val !== 'object') { + return false + } + + if (val instanceof HttpError) { + return true + } + + return val instanceof Error && + typeof val.expose === 'boolean' && + typeof val.statusCode === 'number' && val.status === val.statusCode + } + } + + /** + * Create a constructor for a server error. + * @private + */ + + function createServerErrorConstructor (HttpError, name, code) { + var className = toClassName(name); + + function ServerError (message) { + // create the error object + var msg = message != null ? message : statuses.message[code]; + var err = new Error(msg); + + // capture a stack trace to the construction point + Error.captureStackTrace(err, ServerError); + + // adjust the [[Prototype]] + setPrototypeOf(err, ServerError.prototype); + + // redefine the error message + Object.defineProperty(err, 'message', { + enumerable: true, + configurable: true, + value: msg, + writable: true + }); + + // redefine the error name + Object.defineProperty(err, 'name', { + enumerable: false, + configurable: true, + value: className, + writable: true + }); + + return err + } + + inherits(ServerError, HttpError); + nameFunc(ServerError, className); + + ServerError.prototype.status = code; + ServerError.prototype.statusCode = code; + ServerError.prototype.expose = false; + + return ServerError + } + + /** + * Set the name of a function, if possible. + * @private + */ + + function nameFunc (func, name) { + var desc = Object.getOwnPropertyDescriptor(func, 'name'); + + if (desc && desc.configurable) { + desc.value = name; + Object.defineProperty(func, 'name', desc); + } + } + + /** + * Populate the exports object with constructors for every error class. + * @private + */ + + function populateConstructorExports (exports, codes, HttpError) { + codes.forEach(function forEachCode (code) { + var CodeError; + var name = toIdentifier(statuses.message[code]); + + switch (codeClass(code)) { + case 400: + CodeError = createClientErrorConstructor(HttpError, name, code); + break + case 500: + CodeError = createServerErrorConstructor(HttpError, name, code); + break + } + + if (CodeError) { + // export the constructor + exports[code] = CodeError; + exports[name] = CodeError; + } + }); + } + + /** + * Get a class name from a name identifier. + * @private + */ + + function toClassName (name) { + return name.substr(-5) !== 'Error' + ? name + 'Error' + : name + } + } (httpErrors)); + return httpErrors.exports; +} + +/*! + * encodeurl + * Copyright(c) 2016 Douglas Christopher Wilson + * MIT Licensed + */ + +var encodeurl; +var hasRequiredEncodeurl; + +function requireEncodeurl () { + if (hasRequiredEncodeurl) return encodeurl; + hasRequiredEncodeurl = 1; + + /** + * Module exports. + * @public + */ + + encodeurl = encodeUrl; + + /** + * RegExp to match non-URL code points, *after* encoding (i.e. not including "%") + * and including invalid escape sequences. + * @private + */ + + var ENCODE_CHARS_REGEXP = /(?:[^\x21\x23-\x3B\x3D\x3F-\x5F\x61-\x7A\x7C\x7E]|%(?:[^0-9A-Fa-f]|[0-9A-Fa-f][^0-9A-Fa-f]|$))+/g; + + /** + * RegExp to match unmatched surrogate pair. + * @private + */ + + var UNMATCHED_SURROGATE_PAIR_REGEXP = /(^|[^\uD800-\uDBFF])[\uDC00-\uDFFF]|[\uD800-\uDBFF]([^\uDC00-\uDFFF]|$)/g; + + /** + * String to replace unmatched surrogate pair with. + * @private + */ + + var UNMATCHED_SURROGATE_PAIR_REPLACE = '$1\uFFFD$2'; + + /** + * Encode a URL to a percent-encoded form, excluding already-encoded sequences. + * + * This function will take an already-encoded URL and encode all the non-URL + * code points. This function will not encode the "%" character unless it is + * not part of a valid sequence (`%20` will be left as-is, but `%foo` will + * be encoded as `%25foo`). + * + * This encode is meant to be "safe" and does not throw errors. It will try as + * hard as it can to properly encode the given URL, including replacing any raw, + * unpaired surrogate pairs with the Unicode replacement character prior to + * encoding. + * + * @param {string} url + * @return {string} + * @public + */ + + function encodeUrl (url) { + return String(url) + .replace(UNMATCHED_SURROGATE_PAIR_REGEXP, UNMATCHED_SURROGATE_PAIR_REPLACE) + .replace(ENCODE_CHARS_REGEXP, encodeURI) + } + return encodeurl; +} + +/*! + * escape-html + * Copyright(c) 2012-2013 TJ Holowaychuk + * Copyright(c) 2015 Andreas Lubbe + * Copyright(c) 2015 Tiancheng "Timothy" Gu + * MIT Licensed + */ + +var escapeHtml_1; +var hasRequiredEscapeHtml; + +function requireEscapeHtml () { + if (hasRequiredEscapeHtml) return escapeHtml_1; + hasRequiredEscapeHtml = 1; + + /** + * Module variables. + * @private + */ + + var matchHtmlRegExp = /["'&<>]/; + + /** + * Module exports. + * @public + */ + + escapeHtml_1 = escapeHtml; + + /** + * Escape special characters in the given string of html. + * + * @param {string} string The string to escape for inserting into HTML + * @return {string} + * @public + */ + + function escapeHtml(string) { + var str = '' + string; + var match = matchHtmlRegExp.exec(str); + + if (!match) { + return str; + } + + var escape; + var html = ''; + var index = 0; + var lastIndex = 0; + + for (index = match.index; index < str.length; index++) { + switch (str.charCodeAt(index)) { + case 34: // " + escape = '"'; + break; + case 38: // & + escape = '&'; + break; + case 39: // ' + escape = '''; + break; + case 60: // < + escape = '<'; + break; + case 62: // > + escape = '>'; + break; + default: + continue; + } + + if (lastIndex !== index) { + html += str.substring(lastIndex, index); + } + + lastIndex = index + 1; + html += escape; + } + + return lastIndex !== index + ? html + str.substring(lastIndex, index) + : html; + } + return escapeHtml_1; +} + +/*! + * etag + * Copyright(c) 2014-2016 Douglas Christopher Wilson + * MIT Licensed + */ + +var etag_1; +var hasRequiredEtag; + +function requireEtag () { + if (hasRequiredEtag) return etag_1; + hasRequiredEtag = 1; + + /** + * Module exports. + * @public + */ + + etag_1 = etag; + + /** + * Module dependencies. + * @private + */ + + var crypto = require$$0$6; + var Stats = require$$0$5.Stats; + + /** + * Module variables. + * @private + */ + + var toString = Object.prototype.toString; + + /** + * Generate an entity tag. + * + * @param {Buffer|string} entity + * @return {string} + * @private + */ + + function entitytag (entity) { + if (entity.length === 0) { + // fast-path empty + return '"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk"' + } + + // compute hash of entity + var hash = crypto + .createHash('sha1') + .update(entity, 'utf8') + .digest('base64') + .substring(0, 27); + + // compute length of entity + var len = typeof entity === 'string' + ? Buffer.byteLength(entity, 'utf8') + : entity.length; + + return '"' + len.toString(16) + '-' + hash + '"' + } + + /** + * Create a simple ETag. + * + * @param {string|Buffer|Stats} entity + * @param {object} [options] + * @param {boolean} [options.weak] + * @return {String} + * @public + */ + + function etag (entity, options) { + if (entity == null) { + throw new TypeError('argument entity is required') + } + + // support fs.Stats object + var isStats = isstats(entity); + var weak = options && typeof options.weak === 'boolean' + ? options.weak + : isStats; + + // validate argument + if (!isStats && typeof entity !== 'string' && !Buffer.isBuffer(entity)) { + throw new TypeError('argument entity must be string, Buffer, or fs.Stats') + } + + // generate entity tag + var tag = isStats + ? stattag(entity) + : entitytag(entity); + + return weak + ? 'W/' + tag + : tag + } + + /** + * Determine if object is a Stats object. + * + * @param {object} obj + * @return {boolean} + * @api private + */ + + function isstats (obj) { + // genuine fs.Stats + if (typeof Stats === 'function' && obj instanceof Stats) { + return true + } + + // quack quack + return obj && typeof obj === 'object' && + 'ctime' in obj && toString.call(obj.ctime) === '[object Date]' && + 'mtime' in obj && toString.call(obj.mtime) === '[object Date]' && + 'ino' in obj && typeof obj.ino === 'number' && + 'size' in obj && typeof obj.size === 'number' + } + + /** + * Generate a tag for a stat. + * + * @param {object} stat + * @return {string} + * @private + */ + + function stattag (stat) { + var mtime = stat.mtime.getTime().toString(16); + var size = stat.size.toString(16); + + return '"' + size + '-' + mtime + '"' + } + return etag_1; +} + +/*! + * fresh + * Copyright(c) 2012 TJ Holowaychuk + * Copyright(c) 2016-2017 Douglas Christopher Wilson + * MIT Licensed + */ + +var fresh_1; +var hasRequiredFresh; + +function requireFresh () { + if (hasRequiredFresh) return fresh_1; + hasRequiredFresh = 1; + + /** + * RegExp to check for no-cache token in Cache-Control. + * @private + */ + + var CACHE_CONTROL_NO_CACHE_REGEXP = /(?:^|,)\s*?no-cache\s*?(?:,|$)/; + + /** + * Module exports. + * @public + */ + + fresh_1 = fresh; + + /** + * Check freshness of the response using request and response headers. + * + * @param {Object} reqHeaders + * @param {Object} resHeaders + * @return {Boolean} + * @public + */ + + function fresh (reqHeaders, resHeaders) { + // fields + var modifiedSince = reqHeaders['if-modified-since']; + var noneMatch = reqHeaders['if-none-match']; + + // unconditional request + if (!modifiedSince && !noneMatch) { + return false + } + + // Always return stale when Cache-Control: no-cache + // to support end-to-end reload requests + // https://tools.ietf.org/html/rfc2616#section-14.9.4 + var cacheControl = reqHeaders['cache-control']; + if (cacheControl && CACHE_CONTROL_NO_CACHE_REGEXP.test(cacheControl)) { + return false + } + + // if-none-match takes precedent over if-modified-since + if (noneMatch) { + if (noneMatch === '*') { + return true + } + var etag = resHeaders.etag; + + if (!etag) { + return false + } + + var matches = parseTokenList(noneMatch); + for (var i = 0; i < matches.length; i++) { + var match = matches[i]; + if (match === etag || match === 'W/' + etag || 'W/' + match === etag) { + return true + } + } + + return false + } + + // if-modified-since + if (modifiedSince) { + var lastModified = resHeaders['last-modified']; + var modifiedStale = !lastModified || !(parseHttpDate(lastModified) <= parseHttpDate(modifiedSince)); + + if (modifiedStale) { + return false + } + } + + return true + } + + /** + * Parse an HTTP Date into a number. + * + * @param {string} date + * @private + */ + + function parseHttpDate (date) { + var timestamp = date && Date.parse(date); + + // istanbul ignore next: guard against date.js Date.parse patching + return typeof timestamp === 'number' + ? timestamp + : NaN + } + + /** + * Parse a HTTP token list. + * + * @param {string} str + * @private + */ + + function parseTokenList (str) { + var end = 0; + var list = []; + var start = 0; + + // gather tokens + for (var i = 0, len = str.length; i < len; i++) { + switch (str.charCodeAt(i)) { + case 0x20: /* */ + if (start === end) { + start = end = i + 1; + } + break + case 0x2c: /* , */ + list.push(str.substring(start, end)); + start = end = i + 1; + break + default: + end = i + 1; + break + } + } + + // final token + list.push(str.substring(start, end)); + + return list + } + return fresh_1; +} + +var mimeTypes = {}; + +const require$$0$1 = { + "application/1d-interleaved-parityfec": {"source":"iana"}, + "application/3gpdash-qoe-report+xml": {"source":"iana","charset":"UTF-8","compressible":true}, + "application/3gpp-ims+xml": {"source":"iana","compressible":true}, + "application/3gpphal+json": {"source":"iana","compressible":true}, + "application/3gpphalforms+json": {"source":"iana","compressible":true}, + "application/a2l": {"source":"iana"}, + "application/ace+cbor": {"source":"iana"}, + "application/ace+json": {"source":"iana","compressible":true}, + "application/ace-groupcomm+cbor": {"source":"iana"}, + "application/ace-trl+cbor": {"source":"iana"}, + "application/activemessage": {"source":"iana"}, + "application/activity+json": {"source":"iana","compressible":true}, + "application/aif+cbor": {"source":"iana"}, + "application/aif+json": {"source":"iana","compressible":true}, + "application/alto-cdni+json": {"source":"iana","compressible":true}, + "application/alto-cdnifilter+json": {"source":"iana","compressible":true}, + "application/alto-costmap+json": {"source":"iana","compressible":true}, + "application/alto-costmapfilter+json": {"source":"iana","compressible":true}, + "application/alto-directory+json": {"source":"iana","compressible":true}, + "application/alto-endpointcost+json": {"source":"iana","compressible":true}, + "application/alto-endpointcostparams+json": {"source":"iana","compressible":true}, + "application/alto-endpointprop+json": {"source":"iana","compressible":true}, + "application/alto-endpointpropparams+json": {"source":"iana","compressible":true}, + "application/alto-error+json": {"source":"iana","compressible":true}, + "application/alto-networkmap+json": {"source":"iana","compressible":true}, + "application/alto-networkmapfilter+json": {"source":"iana","compressible":true}, + "application/alto-propmap+json": {"source":"iana","compressible":true}, + "application/alto-propmapparams+json": {"source":"iana","compressible":true}, + "application/alto-tips+json": {"source":"iana","compressible":true}, + "application/alto-tipsparams+json": {"source":"iana","compressible":true}, + "application/alto-updatestreamcontrol+json": {"source":"iana","compressible":true}, + "application/alto-updatestreamparams+json": {"source":"iana","compressible":true}, + "application/aml": {"source":"iana"}, + "application/andrew-inset": {"source":"iana","extensions":["ez"]}, + "application/appinstaller": {"compressible":false,"extensions":["appinstaller"]}, + "application/applefile": {"source":"iana"}, + "application/applixware": {"source":"apache","extensions":["aw"]}, + "application/appx": {"compressible":false,"extensions":["appx"]}, + "application/appxbundle": {"compressible":false,"extensions":["appxbundle"]}, + "application/at+jwt": {"source":"iana"}, + "application/atf": {"source":"iana"}, + "application/atfx": {"source":"iana"}, + "application/atom+xml": {"source":"iana","compressible":true,"extensions":["atom"]}, + "application/atomcat+xml": {"source":"iana","compressible":true,"extensions":["atomcat"]}, + "application/atomdeleted+xml": {"source":"iana","compressible":true,"extensions":["atomdeleted"]}, + "application/atomicmail": {"source":"iana"}, + "application/atomsvc+xml": {"source":"iana","compressible":true,"extensions":["atomsvc"]}, + "application/atsc-dwd+xml": {"source":"iana","compressible":true,"extensions":["dwd"]}, + "application/atsc-dynamic-event-message": {"source":"iana"}, + "application/atsc-held+xml": {"source":"iana","compressible":true,"extensions":["held"]}, + "application/atsc-rdt+json": {"source":"iana","compressible":true}, + "application/atsc-rsat+xml": {"source":"iana","compressible":true,"extensions":["rsat"]}, + "application/atxml": {"source":"iana"}, + "application/auth-policy+xml": {"source":"iana","compressible":true}, + "application/automationml-aml+xml": {"source":"iana","compressible":true,"extensions":["aml"]}, + "application/automationml-amlx+zip": {"source":"iana","compressible":false,"extensions":["amlx"]}, + "application/bacnet-xdd+zip": {"source":"iana","compressible":false}, + "application/batch-smtp": {"source":"iana"}, + "application/bdoc": {"compressible":false,"extensions":["bdoc"]}, + "application/beep+xml": {"source":"iana","charset":"UTF-8","compressible":true}, + "application/bufr": {"source":"iana"}, + "application/c2pa": {"source":"iana"}, + "application/calendar+json": {"source":"iana","compressible":true}, + "application/calendar+xml": {"source":"iana","compressible":true,"extensions":["xcs"]}, + "application/call-completion": {"source":"iana"}, + "application/cals-1840": {"source":"iana"}, + "application/captive+json": {"source":"iana","compressible":true}, + "application/cbor": {"source":"iana"}, + "application/cbor-seq": {"source":"iana"}, + "application/cccex": {"source":"iana"}, + "application/ccmp+xml": {"source":"iana","compressible":true}, + "application/ccxml+xml": {"source":"iana","compressible":true,"extensions":["ccxml"]}, + "application/cda+xml": {"source":"iana","charset":"UTF-8","compressible":true}, + "application/cdfx+xml": {"source":"iana","compressible":true,"extensions":["cdfx"]}, + "application/cdmi-capability": {"source":"iana","extensions":["cdmia"]}, + "application/cdmi-container": {"source":"iana","extensions":["cdmic"]}, + "application/cdmi-domain": {"source":"iana","extensions":["cdmid"]}, + "application/cdmi-object": {"source":"iana","extensions":["cdmio"]}, + "application/cdmi-queue": {"source":"iana","extensions":["cdmiq"]}, + "application/cdni": {"source":"iana"}, + "application/ce+cbor": {"source":"iana"}, + "application/cea": {"source":"iana"}, + "application/cea-2018+xml": {"source":"iana","compressible":true}, + "application/cellml+xml": {"source":"iana","compressible":true}, + "application/cfw": {"source":"iana"}, + "application/cid-edhoc+cbor-seq": {"source":"iana"}, + "application/city+json": {"source":"iana","compressible":true}, + "application/city+json-seq": {"source":"iana"}, + "application/clr": {"source":"iana"}, + "application/clue+xml": {"source":"iana","compressible":true}, + "application/clue_info+xml": {"source":"iana","compressible":true}, + "application/cms": {"source":"iana"}, + "application/cnrp+xml": {"source":"iana","compressible":true}, + "application/coap-eap": {"source":"iana"}, + "application/coap-group+json": {"source":"iana","compressible":true}, + "application/coap-payload": {"source":"iana"}, + "application/commonground": {"source":"iana"}, + "application/concise-problem-details+cbor": {"source":"iana"}, + "application/conference-info+xml": {"source":"iana","compressible":true}, + "application/cose": {"source":"iana"}, + "application/cose-key": {"source":"iana"}, + "application/cose-key-set": {"source":"iana"}, + "application/cose-x509": {"source":"iana"}, + "application/cpl+xml": {"source":"iana","compressible":true,"extensions":["cpl"]}, + "application/csrattrs": {"source":"iana"}, + "application/csta+xml": {"source":"iana","compressible":true}, + "application/cstadata+xml": {"source":"iana","compressible":true}, + "application/csvm+json": {"source":"iana","compressible":true}, + "application/cu-seeme": {"source":"apache","extensions":["cu"]}, + "application/cwl": {"source":"iana","extensions":["cwl"]}, + "application/cwl+json": {"source":"iana","compressible":true}, + "application/cwl+yaml": {"source":"iana"}, + "application/cwt": {"source":"iana"}, + "application/cybercash": {"source":"iana"}, + "application/dart": {"compressible":true}, + "application/dash+xml": {"source":"iana","compressible":true,"extensions":["mpd"]}, + "application/dash-patch+xml": {"source":"iana","compressible":true,"extensions":["mpp"]}, + "application/dashdelta": {"source":"iana"}, + "application/davmount+xml": {"source":"iana","compressible":true,"extensions":["davmount"]}, + "application/dca-rft": {"source":"iana"}, + "application/dcd": {"source":"iana"}, + "application/dec-dx": {"source":"iana"}, + "application/dialog-info+xml": {"source":"iana","compressible":true}, + "application/dicom": {"source":"iana","extensions":["dcm"]}, + "application/dicom+json": {"source":"iana","compressible":true}, + "application/dicom+xml": {"source":"iana","compressible":true}, + "application/dii": {"source":"iana"}, + "application/dit": {"source":"iana"}, + "application/dns": {"source":"iana"}, + "application/dns+json": {"source":"iana","compressible":true}, + "application/dns-message": {"source":"iana"}, + "application/docbook+xml": {"source":"apache","compressible":true,"extensions":["dbk"]}, + "application/dots+cbor": {"source":"iana"}, + "application/dpop+jwt": {"source":"iana"}, + "application/dskpp+xml": {"source":"iana","compressible":true}, + "application/dssc+der": {"source":"iana","extensions":["dssc"]}, + "application/dssc+xml": {"source":"iana","compressible":true,"extensions":["xdssc"]}, + "application/dvcs": {"source":"iana"}, + "application/eat+cwt": {"source":"iana"}, + "application/eat+jwt": {"source":"iana"}, + "application/eat-bun+cbor": {"source":"iana"}, + "application/eat-bun+json": {"source":"iana","compressible":true}, + "application/eat-ucs+cbor": {"source":"iana"}, + "application/eat-ucs+json": {"source":"iana","compressible":true}, + "application/ecmascript": {"source":"apache","compressible":true,"extensions":["ecma"]}, + "application/edhoc+cbor-seq": {"source":"iana"}, + "application/edi-consent": {"source":"iana"}, + "application/edi-x12": {"source":"iana","compressible":false}, + "application/edifact": {"source":"iana","compressible":false}, + "application/efi": {"source":"iana"}, + "application/elm+json": {"source":"iana","charset":"UTF-8","compressible":true}, + "application/elm+xml": {"source":"iana","compressible":true}, + "application/emergencycalldata.cap+xml": {"source":"iana","charset":"UTF-8","compressible":true}, + "application/emergencycalldata.comment+xml": {"source":"iana","compressible":true}, + "application/emergencycalldata.control+xml": {"source":"iana","compressible":true}, + "application/emergencycalldata.deviceinfo+xml": {"source":"iana","compressible":true}, + "application/emergencycalldata.ecall.msd": {"source":"iana"}, + "application/emergencycalldata.legacyesn+json": {"source":"iana","compressible":true}, + "application/emergencycalldata.providerinfo+xml": {"source":"iana","compressible":true}, + "application/emergencycalldata.serviceinfo+xml": {"source":"iana","compressible":true}, + "application/emergencycalldata.subscriberinfo+xml": {"source":"iana","compressible":true}, + "application/emergencycalldata.veds+xml": {"source":"iana","compressible":true}, + "application/emma+xml": {"source":"iana","compressible":true,"extensions":["emma"]}, + "application/emotionml+xml": {"source":"iana","compressible":true,"extensions":["emotionml"]}, + "application/encaprtp": {"source":"iana"}, + "application/entity-statement+jwt": {"source":"iana"}, + "application/epp+xml": {"source":"iana","compressible":true}, + "application/epub+zip": {"source":"iana","compressible":false,"extensions":["epub"]}, + "application/eshop": {"source":"iana"}, + "application/exi": {"source":"iana","extensions":["exi"]}, + "application/expect-ct-report+json": {"source":"iana","compressible":true}, + "application/express": {"source":"iana","extensions":["exp"]}, + "application/fastinfoset": {"source":"iana"}, + "application/fastsoap": {"source":"iana"}, + "application/fdf": {"source":"iana","extensions":["fdf"]}, + "application/fdt+xml": {"source":"iana","compressible":true,"extensions":["fdt"]}, + "application/fhir+json": {"source":"iana","charset":"UTF-8","compressible":true}, + "application/fhir+xml": {"source":"iana","charset":"UTF-8","compressible":true}, + "application/fido.trusted-apps+json": {"compressible":true}, + "application/fits": {"source":"iana"}, + "application/flexfec": {"source":"iana"}, + "application/font-sfnt": {"source":"iana"}, + "application/font-tdpfr": {"source":"iana","extensions":["pfr"]}, + "application/font-woff": {"source":"iana","compressible":false}, + "application/framework-attributes+xml": {"source":"iana","compressible":true}, + "application/geo+json": {"source":"iana","compressible":true,"extensions":["geojson"]}, + "application/geo+json-seq": {"source":"iana"}, + "application/geopackage+sqlite3": {"source":"iana"}, + "application/geopose+json": {"source":"iana","compressible":true}, + "application/geoxacml+json": {"source":"iana","compressible":true}, + "application/geoxacml+xml": {"source":"iana","compressible":true}, + "application/gltf-buffer": {"source":"iana"}, + "application/gml+xml": {"source":"iana","compressible":true,"extensions":["gml"]}, + "application/gnap-binding-jws": {"source":"iana"}, + "application/gnap-binding-jwsd": {"source":"iana"}, + "application/gnap-binding-rotation-jws": {"source":"iana"}, + "application/gnap-binding-rotation-jwsd": {"source":"iana"}, + "application/gpx+xml": {"source":"apache","compressible":true,"extensions":["gpx"]}, + "application/grib": {"source":"iana"}, + "application/gxf": {"source":"apache","extensions":["gxf"]}, + "application/gzip": {"source":"iana","compressible":false,"extensions":["gz"]}, + "application/h224": {"source":"iana"}, + "application/held+xml": {"source":"iana","compressible":true}, + "application/hjson": {"extensions":["hjson"]}, + "application/hl7v2+xml": {"source":"iana","charset":"UTF-8","compressible":true}, + "application/http": {"source":"iana"}, + "application/hyperstudio": {"source":"iana","extensions":["stk"]}, + "application/ibe-key-request+xml": {"source":"iana","compressible":true}, + "application/ibe-pkg-reply+xml": {"source":"iana","compressible":true}, + "application/ibe-pp-data": {"source":"iana"}, + "application/iges": {"source":"iana"}, + "application/im-iscomposing+xml": {"source":"iana","charset":"UTF-8","compressible":true}, + "application/index": {"source":"iana"}, + "application/index.cmd": {"source":"iana"}, + "application/index.obj": {"source":"iana"}, + "application/index.response": {"source":"iana"}, + "application/index.vnd": {"source":"iana"}, + "application/inkml+xml": {"source":"iana","compressible":true,"extensions":["ink","inkml"]}, + "application/iotp": {"source":"iana"}, + "application/ipfix": {"source":"iana","extensions":["ipfix"]}, + "application/ipp": {"source":"iana"}, + "application/isup": {"source":"iana"}, + "application/its+xml": {"source":"iana","compressible":true,"extensions":["its"]}, + "application/java-archive": {"source":"iana","compressible":false,"extensions":["jar","war","ear"]}, + "application/java-serialized-object": {"source":"apache","compressible":false,"extensions":["ser"]}, + "application/java-vm": {"source":"apache","compressible":false,"extensions":["class"]}, + "application/javascript": {"source":"apache","charset":"UTF-8","compressible":true,"extensions":["js"]}, + "application/jf2feed+json": {"source":"iana","compressible":true}, + "application/jose": {"source":"iana"}, + "application/jose+json": {"source":"iana","compressible":true}, + "application/jrd+json": {"source":"iana","compressible":true}, + "application/jscalendar+json": {"source":"iana","compressible":true}, + "application/jscontact+json": {"source":"iana","compressible":true}, + "application/json": {"source":"iana","charset":"UTF-8","compressible":true,"extensions":["json","map"]}, + "application/json-patch+json": {"source":"iana","compressible":true}, + "application/json-seq": {"source":"iana"}, + "application/json5": {"extensions":["json5"]}, + "application/jsonml+json": {"source":"apache","compressible":true,"extensions":["jsonml"]}, + "application/jsonpath": {"source":"iana"}, + "application/jwk+json": {"source":"iana","compressible":true}, + "application/jwk-set+json": {"source":"iana","compressible":true}, + "application/jwk-set+jwt": {"source":"iana"}, + "application/jwt": {"source":"iana"}, + "application/kpml-request+xml": {"source":"iana","compressible":true}, + "application/kpml-response+xml": {"source":"iana","compressible":true}, + "application/ld+json": {"source":"iana","compressible":true,"extensions":["jsonld"]}, + "application/lgr+xml": {"source":"iana","compressible":true,"extensions":["lgr"]}, + "application/link-format": {"source":"iana"}, + "application/linkset": {"source":"iana"}, + "application/linkset+json": {"source":"iana","compressible":true}, + "application/load-control+xml": {"source":"iana","compressible":true}, + "application/logout+jwt": {"source":"iana"}, + "application/lost+xml": {"source":"iana","compressible":true,"extensions":["lostxml"]}, + "application/lostsync+xml": {"source":"iana","compressible":true}, + "application/lpf+zip": {"source":"iana","compressible":false}, + "application/lxf": {"source":"iana"}, + "application/mac-binhex40": {"source":"iana","extensions":["hqx"]}, + "application/mac-compactpro": {"source":"apache","extensions":["cpt"]}, + "application/macwriteii": {"source":"iana"}, + "application/mads+xml": {"source":"iana","compressible":true,"extensions":["mads"]}, + "application/manifest+json": {"source":"iana","charset":"UTF-8","compressible":true,"extensions":["webmanifest"]}, + "application/marc": {"source":"iana","extensions":["mrc"]}, + "application/marcxml+xml": {"source":"iana","compressible":true,"extensions":["mrcx"]}, + "application/mathematica": {"source":"iana","extensions":["ma","nb","mb"]}, + "application/mathml+xml": {"source":"iana","compressible":true,"extensions":["mathml"]}, + "application/mathml-content+xml": {"source":"iana","compressible":true}, + "application/mathml-presentation+xml": {"source":"iana","compressible":true}, + "application/mbms-associated-procedure-description+xml": {"source":"iana","compressible":true}, + "application/mbms-deregister+xml": {"source":"iana","compressible":true}, + "application/mbms-envelope+xml": {"source":"iana","compressible":true}, + "application/mbms-msk+xml": {"source":"iana","compressible":true}, + "application/mbms-msk-response+xml": {"source":"iana","compressible":true}, + "application/mbms-protection-description+xml": {"source":"iana","compressible":true}, + "application/mbms-reception-report+xml": {"source":"iana","compressible":true}, + "application/mbms-register+xml": {"source":"iana","compressible":true}, + "application/mbms-register-response+xml": {"source":"iana","compressible":true}, + "application/mbms-schedule+xml": {"source":"iana","compressible":true}, + "application/mbms-user-service-description+xml": {"source":"iana","compressible":true}, + "application/mbox": {"source":"iana","extensions":["mbox"]}, + "application/media-policy-dataset+xml": {"source":"iana","compressible":true,"extensions":["mpf"]}, + "application/media_control+xml": {"source":"iana","compressible":true}, + "application/mediaservercontrol+xml": {"source":"iana","compressible":true,"extensions":["mscml"]}, + "application/merge-patch+json": {"source":"iana","compressible":true}, + "application/metalink+xml": {"source":"apache","compressible":true,"extensions":["metalink"]}, + "application/metalink4+xml": {"source":"iana","compressible":true,"extensions":["meta4"]}, + "application/mets+xml": {"source":"iana","compressible":true,"extensions":["mets"]}, + "application/mf4": {"source":"iana"}, + "application/mikey": {"source":"iana"}, + "application/mipc": {"source":"iana"}, + "application/missing-blocks+cbor-seq": {"source":"iana"}, + "application/mmt-aei+xml": {"source":"iana","compressible":true,"extensions":["maei"]}, + "application/mmt-usd+xml": {"source":"iana","compressible":true,"extensions":["musd"]}, + "application/mods+xml": {"source":"iana","compressible":true,"extensions":["mods"]}, + "application/moss-keys": {"source":"iana"}, + "application/moss-signature": {"source":"iana"}, + "application/mosskey-data": {"source":"iana"}, + "application/mosskey-request": {"source":"iana"}, + "application/mp21": {"source":"iana","extensions":["m21","mp21"]}, + "application/mp4": {"source":"iana","extensions":["mp4","mpg4","mp4s","m4p"]}, + "application/mpeg4-generic": {"source":"iana"}, + "application/mpeg4-iod": {"source":"iana"}, + "application/mpeg4-iod-xmt": {"source":"iana"}, + "application/mrb-consumer+xml": {"source":"iana","compressible":true}, + "application/mrb-publish+xml": {"source":"iana","compressible":true}, + "application/msc-ivr+xml": {"source":"iana","charset":"UTF-8","compressible":true}, + "application/msc-mixer+xml": {"source":"iana","charset":"UTF-8","compressible":true}, + "application/msix": {"compressible":false,"extensions":["msix"]}, + "application/msixbundle": {"compressible":false,"extensions":["msixbundle"]}, + "application/msword": {"source":"iana","compressible":false,"extensions":["doc","dot"]}, + "application/mud+json": {"source":"iana","compressible":true}, + "application/multipart-core": {"source":"iana"}, + "application/mxf": {"source":"iana","extensions":["mxf"]}, + "application/n-quads": {"source":"iana","extensions":["nq"]}, + "application/n-triples": {"source":"iana","extensions":["nt"]}, + "application/nasdata": {"source":"iana"}, + "application/news-checkgroups": {"source":"iana","charset":"US-ASCII"}, + "application/news-groupinfo": {"source":"iana","charset":"US-ASCII"}, + "application/news-transmission": {"source":"iana"}, + "application/nlsml+xml": {"source":"iana","compressible":true}, + "application/node": {"source":"iana","extensions":["cjs"]}, + "application/nss": {"source":"iana"}, + "application/oauth-authz-req+jwt": {"source":"iana"}, + "application/oblivious-dns-message": {"source":"iana"}, + "application/ocsp-request": {"source":"iana"}, + "application/ocsp-response": {"source":"iana"}, + "application/octet-stream": {"source":"iana","compressible":true,"extensions":["bin","dms","lrf","mar","so","dist","distz","pkg","bpk","dump","elc","deploy","exe","dll","deb","dmg","iso","img","msi","msp","msm","buffer"]}, + "application/oda": {"source":"iana","extensions":["oda"]}, + "application/odm+xml": {"source":"iana","compressible":true}, + "application/odx": {"source":"iana"}, + "application/oebps-package+xml": {"source":"iana","compressible":true,"extensions":["opf"]}, + "application/ogg": {"source":"iana","compressible":false,"extensions":["ogx"]}, + "application/ohttp-keys": {"source":"iana"}, + "application/omdoc+xml": {"source":"apache","compressible":true,"extensions":["omdoc"]}, + "application/onenote": {"source":"apache","extensions":["onetoc","onetoc2","onetmp","onepkg","one","onea"]}, + "application/opc-nodeset+xml": {"source":"iana","compressible":true}, + "application/oscore": {"source":"iana"}, + "application/oxps": {"source":"iana","extensions":["oxps"]}, + "application/p21": {"source":"iana"}, + "application/p21+zip": {"source":"iana","compressible":false}, + "application/p2p-overlay+xml": {"source":"iana","compressible":true,"extensions":["relo"]}, + "application/parityfec": {"source":"iana"}, + "application/passport": {"source":"iana"}, + "application/patch-ops-error+xml": {"source":"iana","compressible":true,"extensions":["xer"]}, + "application/pdf": {"source":"iana","compressible":false,"extensions":["pdf"]}, + "application/pdx": {"source":"iana"}, + "application/pem-certificate-chain": {"source":"iana"}, + "application/pgp-encrypted": {"source":"iana","compressible":false,"extensions":["pgp"]}, + "application/pgp-keys": {"source":"iana","extensions":["asc"]}, + "application/pgp-signature": {"source":"iana","extensions":["sig","asc"]}, + "application/pics-rules": {"source":"apache","extensions":["prf"]}, + "application/pidf+xml": {"source":"iana","charset":"UTF-8","compressible":true}, + "application/pidf-diff+xml": {"source":"iana","charset":"UTF-8","compressible":true}, + "application/pkcs10": {"source":"iana","extensions":["p10"]}, + "application/pkcs12": {"source":"iana"}, + "application/pkcs7-mime": {"source":"iana","extensions":["p7m","p7c"]}, + "application/pkcs7-signature": {"source":"iana","extensions":["p7s"]}, + "application/pkcs8": {"source":"iana","extensions":["p8"]}, + "application/pkcs8-encrypted": {"source":"iana"}, + "application/pkix-attr-cert": {"source":"iana","extensions":["ac"]}, + "application/pkix-cert": {"source":"iana","extensions":["cer"]}, + "application/pkix-crl": {"source":"iana","extensions":["crl"]}, + "application/pkix-pkipath": {"source":"iana","extensions":["pkipath"]}, + "application/pkixcmp": {"source":"iana","extensions":["pki"]}, + "application/pls+xml": {"source":"iana","compressible":true,"extensions":["pls"]}, + "application/poc-settings+xml": {"source":"iana","charset":"UTF-8","compressible":true}, + "application/postscript": {"source":"iana","compressible":true,"extensions":["ai","eps","ps"]}, + "application/ppsp-tracker+json": {"source":"iana","compressible":true}, + "application/private-token-issuer-directory": {"source":"iana"}, + "application/private-token-request": {"source":"iana"}, + "application/private-token-response": {"source":"iana"}, + "application/problem+json": {"source":"iana","compressible":true}, + "application/problem+xml": {"source":"iana","compressible":true}, + "application/provenance+xml": {"source":"iana","compressible":true,"extensions":["provx"]}, + "application/provided-claims+jwt": {"source":"iana"}, + "application/prs.alvestrand.titrax-sheet": {"source":"iana"}, + "application/prs.cww": {"source":"iana","extensions":["cww"]}, + "application/prs.cyn": {"source":"iana","charset":"7-BIT"}, + "application/prs.hpub+zip": {"source":"iana","compressible":false}, + "application/prs.implied-document+xml": {"source":"iana","compressible":true}, + "application/prs.implied-executable": {"source":"iana"}, + "application/prs.implied-object+json": {"source":"iana","compressible":true}, + "application/prs.implied-object+json-seq": {"source":"iana"}, + "application/prs.implied-object+yaml": {"source":"iana"}, + "application/prs.implied-structure": {"source":"iana"}, + "application/prs.mayfile": {"source":"iana"}, + "application/prs.nprend": {"source":"iana"}, + "application/prs.plucker": {"source":"iana"}, + "application/prs.rdf-xml-crypt": {"source":"iana"}, + "application/prs.vcfbzip2": {"source":"iana"}, + "application/prs.xsf+xml": {"source":"iana","compressible":true,"extensions":["xsf"]}, + "application/pskc+xml": {"source":"iana","compressible":true,"extensions":["pskcxml"]}, + "application/pvd+json": {"source":"iana","compressible":true}, + "application/qsig": {"source":"iana"}, + "application/raml+yaml": {"compressible":true,"extensions":["raml"]}, + "application/raptorfec": {"source":"iana"}, + "application/rdap+json": {"source":"iana","compressible":true}, + "application/rdf+xml": {"source":"iana","compressible":true,"extensions":["rdf","owl"]}, + "application/reginfo+xml": {"source":"iana","compressible":true,"extensions":["rif"]}, + "application/relax-ng-compact-syntax": {"source":"iana","extensions":["rnc"]}, + "application/remote-printing": {"source":"apache"}, + "application/reputon+json": {"source":"iana","compressible":true}, + "application/resolve-response+jwt": {"source":"iana"}, + "application/resource-lists+xml": {"source":"iana","compressible":true,"extensions":["rl"]}, + "application/resource-lists-diff+xml": {"source":"iana","compressible":true,"extensions":["rld"]}, + "application/rfc+xml": {"source":"iana","compressible":true}, + "application/riscos": {"source":"iana"}, + "application/rlmi+xml": {"source":"iana","compressible":true}, + "application/rls-services+xml": {"source":"iana","compressible":true,"extensions":["rs"]}, + "application/route-apd+xml": {"source":"iana","compressible":true,"extensions":["rapd"]}, + "application/route-s-tsid+xml": {"source":"iana","compressible":true,"extensions":["sls"]}, + "application/route-usd+xml": {"source":"iana","compressible":true,"extensions":["rusd"]}, + "application/rpki-checklist": {"source":"iana"}, + "application/rpki-ghostbusters": {"source":"iana","extensions":["gbr"]}, + "application/rpki-manifest": {"source":"iana","extensions":["mft"]}, + "application/rpki-publication": {"source":"iana"}, + "application/rpki-roa": {"source":"iana","extensions":["roa"]}, + "application/rpki-signed-tal": {"source":"iana"}, + "application/rpki-updown": {"source":"iana"}, + "application/rsd+xml": {"source":"apache","compressible":true,"extensions":["rsd"]}, + "application/rss+xml": {"source":"apache","compressible":true,"extensions":["rss"]}, + "application/rtf": {"source":"iana","compressible":true,"extensions":["rtf"]}, + "application/rtploopback": {"source":"iana"}, + "application/rtx": {"source":"iana"}, + "application/samlassertion+xml": {"source":"iana","compressible":true}, + "application/samlmetadata+xml": {"source":"iana","compressible":true}, + "application/sarif+json": {"source":"iana","compressible":true}, + "application/sarif-external-properties+json": {"source":"iana","compressible":true}, + "application/sbe": {"source":"iana"}, + "application/sbml+xml": {"source":"iana","compressible":true,"extensions":["sbml"]}, + "application/scaip+xml": {"source":"iana","compressible":true}, + "application/scim+json": {"source":"iana","compressible":true}, + "application/scvp-cv-request": {"source":"iana","extensions":["scq"]}, + "application/scvp-cv-response": {"source":"iana","extensions":["scs"]}, + "application/scvp-vp-request": {"source":"iana","extensions":["spq"]}, + "application/scvp-vp-response": {"source":"iana","extensions":["spp"]}, + "application/sdp": {"source":"iana","extensions":["sdp"]}, + "application/secevent+jwt": {"source":"iana"}, + "application/senml+cbor": {"source":"iana"}, + "application/senml+json": {"source":"iana","compressible":true}, + "application/senml+xml": {"source":"iana","compressible":true,"extensions":["senmlx"]}, + "application/senml-etch+cbor": {"source":"iana"}, + "application/senml-etch+json": {"source":"iana","compressible":true}, + "application/senml-exi": {"source":"iana"}, + "application/sensml+cbor": {"source":"iana"}, + "application/sensml+json": {"source":"iana","compressible":true}, + "application/sensml+xml": {"source":"iana","compressible":true,"extensions":["sensmlx"]}, + "application/sensml-exi": {"source":"iana"}, + "application/sep+xml": {"source":"iana","compressible":true}, + "application/sep-exi": {"source":"iana"}, + "application/session-info": {"source":"iana"}, + "application/set-payment": {"source":"iana"}, + "application/set-payment-initiation": {"source":"iana","extensions":["setpay"]}, + "application/set-registration": {"source":"iana"}, + "application/set-registration-initiation": {"source":"iana","extensions":["setreg"]}, + "application/sgml": {"source":"iana"}, + "application/sgml-open-catalog": {"source":"iana"}, + "application/shf+xml": {"source":"iana","compressible":true,"extensions":["shf"]}, + "application/sieve": {"source":"iana","extensions":["siv","sieve"]}, + "application/simple-filter+xml": {"source":"iana","compressible":true}, + "application/simple-message-summary": {"source":"iana"}, + "application/simplesymbolcontainer": {"source":"iana"}, + "application/sipc": {"source":"iana"}, + "application/slate": {"source":"iana"}, + "application/smil": {"source":"apache"}, + "application/smil+xml": {"source":"iana","compressible":true,"extensions":["smi","smil"]}, + "application/smpte336m": {"source":"iana"}, + "application/soap+fastinfoset": {"source":"iana"}, + "application/soap+xml": {"source":"iana","compressible":true}, + "application/sparql-query": {"source":"iana","extensions":["rq"]}, + "application/sparql-results+xml": {"source":"iana","compressible":true,"extensions":["srx"]}, + "application/spdx+json": {"source":"iana","compressible":true}, + "application/spirits-event+xml": {"source":"iana","compressible":true}, + "application/sql": {"source":"iana","extensions":["sql"]}, + "application/srgs": {"source":"iana","extensions":["gram"]}, + "application/srgs+xml": {"source":"iana","compressible":true,"extensions":["grxml"]}, + "application/sru+xml": {"source":"iana","compressible":true,"extensions":["sru"]}, + "application/ssdl+xml": {"source":"apache","compressible":true,"extensions":["ssdl"]}, + "application/sslkeylogfile": {"source":"iana"}, + "application/ssml+xml": {"source":"iana","compressible":true,"extensions":["ssml"]}, + "application/st2110-41": {"source":"iana"}, + "application/stix+json": {"source":"iana","compressible":true}, + "application/stratum": {"source":"iana"}, + "application/swid+cbor": {"source":"iana"}, + "application/swid+xml": {"source":"iana","compressible":true,"extensions":["swidtag"]}, + "application/tamp-apex-update": {"source":"iana"}, + "application/tamp-apex-update-confirm": {"source":"iana"}, + "application/tamp-community-update": {"source":"iana"}, + "application/tamp-community-update-confirm": {"source":"iana"}, + "application/tamp-error": {"source":"iana"}, + "application/tamp-sequence-adjust": {"source":"iana"}, + "application/tamp-sequence-adjust-confirm": {"source":"iana"}, + "application/tamp-status-query": {"source":"iana"}, + "application/tamp-status-response": {"source":"iana"}, + "application/tamp-update": {"source":"iana"}, + "application/tamp-update-confirm": {"source":"iana"}, + "application/tar": {"compressible":true}, + "application/taxii+json": {"source":"iana","compressible":true}, + "application/td+json": {"source":"iana","compressible":true}, + "application/tei+xml": {"source":"iana","compressible":true,"extensions":["tei","teicorpus"]}, + "application/tetra_isi": {"source":"iana"}, + "application/thraud+xml": {"source":"iana","compressible":true,"extensions":["tfi"]}, + "application/timestamp-query": {"source":"iana"}, + "application/timestamp-reply": {"source":"iana"}, + "application/timestamped-data": {"source":"iana","extensions":["tsd"]}, + "application/tlsrpt+gzip": {"source":"iana"}, + "application/tlsrpt+json": {"source":"iana","compressible":true}, + "application/tm+json": {"source":"iana","compressible":true}, + "application/tnauthlist": {"source":"iana"}, + "application/toc+cbor": {"source":"iana"}, + "application/token-introspection+jwt": {"source":"iana"}, + "application/toml": {"source":"iana","compressible":true,"extensions":["toml"]}, + "application/trickle-ice-sdpfrag": {"source":"iana"}, + "application/trig": {"source":"iana","extensions":["trig"]}, + "application/trust-chain+json": {"source":"iana","compressible":true}, + "application/trust-mark+jwt": {"source":"iana"}, + "application/trust-mark-delegation+jwt": {"source":"iana"}, + "application/ttml+xml": {"source":"iana","compressible":true,"extensions":["ttml"]}, + "application/tve-trigger": {"source":"iana"}, + "application/tzif": {"source":"iana"}, + "application/tzif-leap": {"source":"iana"}, + "application/ubjson": {"compressible":false,"extensions":["ubj"]}, + "application/uccs+cbor": {"source":"iana"}, + "application/ujcs+json": {"source":"iana","compressible":true}, + "application/ulpfec": {"source":"iana"}, + "application/urc-grpsheet+xml": {"source":"iana","compressible":true}, + "application/urc-ressheet+xml": {"source":"iana","compressible":true,"extensions":["rsheet"]}, + "application/urc-targetdesc+xml": {"source":"iana","compressible":true,"extensions":["td"]}, + "application/urc-uisocketdesc+xml": {"source":"iana","compressible":true}, + "application/vc": {"source":"iana"}, + "application/vc+cose": {"source":"iana"}, + "application/vc+jwt": {"source":"iana"}, + "application/vcard+json": {"source":"iana","compressible":true}, + "application/vcard+xml": {"source":"iana","compressible":true}, + "application/vemmi": {"source":"iana"}, + "application/vividence.scriptfile": {"source":"apache"}, + "application/vnd.1000minds.decision-model+xml": {"source":"iana","compressible":true,"extensions":["1km"]}, + "application/vnd.1ob": {"source":"iana"}, + "application/vnd.3gpp-prose+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp-prose-pc3a+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp-prose-pc3ach+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp-prose-pc3ch+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp-prose-pc8+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp-v2x-local-service-information": {"source":"iana"}, + "application/vnd.3gpp.5gnas": {"source":"iana"}, + "application/vnd.3gpp.5gsa2x": {"source":"iana"}, + "application/vnd.3gpp.5gsa2x-local-service-information": {"source":"iana"}, + "application/vnd.3gpp.5gsv2x": {"source":"iana"}, + "application/vnd.3gpp.5gsv2x-local-service-information": {"source":"iana"}, + "application/vnd.3gpp.access-transfer-events+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.bsf+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.crs+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.current-location-discovery+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.gmop+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.gtpc": {"source":"iana"}, + "application/vnd.3gpp.interworking-data": {"source":"iana"}, + "application/vnd.3gpp.lpp": {"source":"iana"}, + "application/vnd.3gpp.mc-signalling-ear": {"source":"iana"}, + "application/vnd.3gpp.mcdata-affiliation-command+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.mcdata-info+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.mcdata-msgstore-ctrl-request+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.mcdata-payload": {"source":"iana"}, + "application/vnd.3gpp.mcdata-regroup+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.mcdata-service-config+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.mcdata-signalling": {"source":"iana"}, + "application/vnd.3gpp.mcdata-ue-config+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.mcdata-user-profile+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.mcptt-affiliation-command+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.mcptt-floor-request+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.mcptt-info+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.mcptt-location-info+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.mcptt-mbms-usage-info+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.mcptt-regroup+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.mcptt-service-config+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.mcptt-signed+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.mcptt-ue-config+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.mcptt-ue-init-config+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.mcptt-user-profile+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.mcvideo-affiliation-command+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.mcvideo-info+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.mcvideo-location-info+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.mcvideo-mbms-usage-info+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.mcvideo-regroup+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.mcvideo-service-config+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.mcvideo-transmission-request+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.mcvideo-ue-config+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.mcvideo-user-profile+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.mid-call+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.ngap": {"source":"iana"}, + "application/vnd.3gpp.pfcp": {"source":"iana"}, + "application/vnd.3gpp.pic-bw-large": {"source":"iana","extensions":["plb"]}, + "application/vnd.3gpp.pic-bw-small": {"source":"iana","extensions":["psb"]}, + "application/vnd.3gpp.pic-bw-var": {"source":"iana","extensions":["pvb"]}, + "application/vnd.3gpp.pinapp-info+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.s1ap": {"source":"iana"}, + "application/vnd.3gpp.seal-group-doc+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.seal-info+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.seal-location-info+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.seal-mbms-usage-info+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.seal-network-qos-management-info+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.seal-ue-config-info+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.seal-unicast-info+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.seal-user-profile-info+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.sms": {"source":"iana"}, + "application/vnd.3gpp.sms+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.srvcc-ext+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.srvcc-info+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.state-and-event-info+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.ussd+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp.v2x": {"source":"iana"}, + "application/vnd.3gpp.vae-info+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp2.bcmcsinfo+xml": {"source":"iana","compressible":true}, + "application/vnd.3gpp2.sms": {"source":"iana"}, + "application/vnd.3gpp2.tcap": {"source":"iana","extensions":["tcap"]}, + "application/vnd.3lightssoftware.imagescal": {"source":"iana"}, + "application/vnd.3m.post-it-notes": {"source":"iana","extensions":["pwn"]}, + "application/vnd.accpac.simply.aso": {"source":"iana","extensions":["aso"]}, + "application/vnd.accpac.simply.imp": {"source":"iana","extensions":["imp"]}, + "application/vnd.acm.addressxfer+json": {"source":"iana","compressible":true}, + "application/vnd.acm.chatbot+json": {"source":"iana","compressible":true}, + "application/vnd.acucobol": {"source":"iana","extensions":["acu"]}, + "application/vnd.acucorp": {"source":"iana","extensions":["atc","acutc"]}, + "application/vnd.adobe.air-application-installer-package+zip": {"source":"apache","compressible":false,"extensions":["air"]}, + "application/vnd.adobe.flash.movie": {"source":"iana"}, + "application/vnd.adobe.formscentral.fcdt": {"source":"iana","extensions":["fcdt"]}, + "application/vnd.adobe.fxp": {"source":"iana","extensions":["fxp","fxpl"]}, + "application/vnd.adobe.partial-upload": {"source":"iana"}, + "application/vnd.adobe.xdp+xml": {"source":"iana","compressible":true,"extensions":["xdp"]}, + "application/vnd.adobe.xfdf": {"source":"apache","extensions":["xfdf"]}, + "application/vnd.aether.imp": {"source":"iana"}, + "application/vnd.afpc.afplinedata": {"source":"iana"}, + "application/vnd.afpc.afplinedata-pagedef": {"source":"iana"}, + "application/vnd.afpc.cmoca-cmresource": {"source":"iana"}, + "application/vnd.afpc.foca-charset": {"source":"iana"}, + "application/vnd.afpc.foca-codedfont": {"source":"iana"}, + "application/vnd.afpc.foca-codepage": {"source":"iana"}, + "application/vnd.afpc.modca": {"source":"iana"}, + "application/vnd.afpc.modca-cmtable": {"source":"iana"}, + "application/vnd.afpc.modca-formdef": {"source":"iana"}, + "application/vnd.afpc.modca-mediummap": {"source":"iana"}, + "application/vnd.afpc.modca-objectcontainer": {"source":"iana"}, + "application/vnd.afpc.modca-overlay": {"source":"iana"}, + "application/vnd.afpc.modca-pagesegment": {"source":"iana"}, + "application/vnd.age": {"source":"iana","extensions":["age"]}, + "application/vnd.ah-barcode": {"source":"apache"}, + "application/vnd.ahead.space": {"source":"iana","extensions":["ahead"]}, + "application/vnd.airzip.filesecure.azf": {"source":"iana","extensions":["azf"]}, + "application/vnd.airzip.filesecure.azs": {"source":"iana","extensions":["azs"]}, + "application/vnd.amadeus+json": {"source":"iana","compressible":true}, + "application/vnd.amazon.ebook": {"source":"apache","extensions":["azw"]}, + "application/vnd.amazon.mobi8-ebook": {"source":"iana"}, + "application/vnd.americandynamics.acc": {"source":"iana","extensions":["acc"]}, + "application/vnd.amiga.ami": {"source":"iana","extensions":["ami"]}, + "application/vnd.amundsen.maze+xml": {"source":"iana","compressible":true}, + "application/vnd.android.ota": {"source":"iana"}, + "application/vnd.android.package-archive": {"source":"apache","compressible":false,"extensions":["apk"]}, + "application/vnd.anki": {"source":"iana"}, + "application/vnd.anser-web-certificate-issue-initiation": {"source":"iana","extensions":["cii"]}, + "application/vnd.anser-web-funds-transfer-initiation": {"source":"apache","extensions":["fti"]}, + "application/vnd.antix.game-component": {"source":"iana","extensions":["atx"]}, + "application/vnd.apache.arrow.file": {"source":"iana"}, + "application/vnd.apache.arrow.stream": {"source":"iana"}, + "application/vnd.apache.parquet": {"source":"iana"}, + "application/vnd.apache.thrift.binary": {"source":"iana"}, + "application/vnd.apache.thrift.compact": {"source":"iana"}, + "application/vnd.apache.thrift.json": {"source":"iana"}, + "application/vnd.apexlang": {"source":"iana"}, + "application/vnd.api+json": {"source":"iana","compressible":true}, + "application/vnd.aplextor.warrp+json": {"source":"iana","compressible":true}, + "application/vnd.apothekende.reservation+json": {"source":"iana","compressible":true}, + "application/vnd.apple.installer+xml": {"source":"iana","compressible":true,"extensions":["mpkg"]}, + "application/vnd.apple.keynote": {"source":"iana","extensions":["key"]}, + "application/vnd.apple.mpegurl": {"source":"iana","extensions":["m3u8"]}, + "application/vnd.apple.numbers": {"source":"iana","extensions":["numbers"]}, + "application/vnd.apple.pages": {"source":"iana","extensions":["pages"]}, + "application/vnd.apple.pkpass": {"compressible":false,"extensions":["pkpass"]}, + "application/vnd.arastra.swi": {"source":"apache"}, + "application/vnd.aristanetworks.swi": {"source":"iana","extensions":["swi"]}, + "application/vnd.artisan+json": {"source":"iana","compressible":true}, + "application/vnd.artsquare": {"source":"iana"}, + "application/vnd.astraea-software.iota": {"source":"iana","extensions":["iota"]}, + "application/vnd.audiograph": {"source":"iana","extensions":["aep"]}, + "application/vnd.autodesk.fbx": {"extensions":["fbx"]}, + "application/vnd.autopackage": {"source":"iana"}, + "application/vnd.avalon+json": {"source":"iana","compressible":true}, + "application/vnd.avistar+xml": {"source":"iana","compressible":true}, + "application/vnd.balsamiq.bmml+xml": {"source":"iana","compressible":true,"extensions":["bmml"]}, + "application/vnd.balsamiq.bmpr": {"source":"iana"}, + "application/vnd.banana-accounting": {"source":"iana"}, + "application/vnd.bbf.usp.error": {"source":"iana"}, + "application/vnd.bbf.usp.msg": {"source":"iana"}, + "application/vnd.bbf.usp.msg+json": {"source":"iana","compressible":true}, + "application/vnd.bekitzur-stech+json": {"source":"iana","compressible":true}, + "application/vnd.belightsoft.lhzd+zip": {"source":"iana","compressible":false}, + "application/vnd.belightsoft.lhzl+zip": {"source":"iana","compressible":false}, + "application/vnd.bint.med-content": {"source":"iana"}, + "application/vnd.biopax.rdf+xml": {"source":"iana","compressible":true}, + "application/vnd.blink-idb-value-wrapper": {"source":"iana"}, + "application/vnd.blueice.multipass": {"source":"iana","extensions":["mpm"]}, + "application/vnd.bluetooth.ep.oob": {"source":"iana"}, + "application/vnd.bluetooth.le.oob": {"source":"iana"}, + "application/vnd.bmi": {"source":"iana","extensions":["bmi"]}, + "application/vnd.bpf": {"source":"iana"}, + "application/vnd.bpf3": {"source":"iana"}, + "application/vnd.businessobjects": {"source":"iana","extensions":["rep"]}, + "application/vnd.byu.uapi+json": {"source":"iana","compressible":true}, + "application/vnd.bzip3": {"source":"iana"}, + "application/vnd.c3voc.schedule+xml": {"source":"iana","compressible":true}, + "application/vnd.cab-jscript": {"source":"iana"}, + "application/vnd.canon-cpdl": {"source":"iana"}, + "application/vnd.canon-lips": {"source":"iana"}, + "application/vnd.capasystems-pg+json": {"source":"iana","compressible":true}, + "application/vnd.cendio.thinlinc.clientconf": {"source":"iana"}, + "application/vnd.century-systems.tcp_stream": {"source":"iana"}, + "application/vnd.chemdraw+xml": {"source":"iana","compressible":true,"extensions":["cdxml"]}, + "application/vnd.chess-pgn": {"source":"iana"}, + "application/vnd.chipnuts.karaoke-mmd": {"source":"iana","extensions":["mmd"]}, + "application/vnd.ciedi": {"source":"iana"}, + "application/vnd.cinderella": {"source":"iana","extensions":["cdy"]}, + "application/vnd.cirpack.isdn-ext": {"source":"iana"}, + "application/vnd.citationstyles.style+xml": {"source":"iana","compressible":true,"extensions":["csl"]}, + "application/vnd.claymore": {"source":"iana","extensions":["cla"]}, + "application/vnd.cloanto.rp9": {"source":"iana","extensions":["rp9"]}, + "application/vnd.clonk.c4group": {"source":"iana","extensions":["c4g","c4d","c4f","c4p","c4u"]}, + "application/vnd.cluetrust.cartomobile-config": {"source":"iana","extensions":["c11amc"]}, + "application/vnd.cluetrust.cartomobile-config-pkg": {"source":"iana","extensions":["c11amz"]}, + "application/vnd.cncf.helm.chart.content.v1.tar+gzip": {"source":"iana"}, + "application/vnd.cncf.helm.chart.provenance.v1.prov": {"source":"iana"}, + "application/vnd.cncf.helm.config.v1+json": {"source":"iana","compressible":true}, + "application/vnd.coffeescript": {"source":"iana"}, + "application/vnd.collabio.xodocuments.document": {"source":"iana"}, + "application/vnd.collabio.xodocuments.document-template": {"source":"iana"}, + "application/vnd.collabio.xodocuments.presentation": {"source":"iana"}, + "application/vnd.collabio.xodocuments.presentation-template": {"source":"iana"}, + "application/vnd.collabio.xodocuments.spreadsheet": {"source":"iana"}, + "application/vnd.collabio.xodocuments.spreadsheet-template": {"source":"iana"}, + "application/vnd.collection+json": {"source":"iana","compressible":true}, + "application/vnd.collection.doc+json": {"source":"iana","compressible":true}, + "application/vnd.collection.next+json": {"source":"iana","compressible":true}, + "application/vnd.comicbook+zip": {"source":"iana","compressible":false}, + "application/vnd.comicbook-rar": {"source":"iana"}, + "application/vnd.commerce-battelle": {"source":"iana"}, + "application/vnd.commonspace": {"source":"iana","extensions":["csp"]}, + "application/vnd.contact.cmsg": {"source":"iana","extensions":["cdbcmsg"]}, + "application/vnd.coreos.ignition+json": {"source":"iana","compressible":true}, + "application/vnd.cosmocaller": {"source":"iana","extensions":["cmc"]}, + "application/vnd.crick.clicker": {"source":"iana","extensions":["clkx"]}, + "application/vnd.crick.clicker.keyboard": {"source":"iana","extensions":["clkk"]}, + "application/vnd.crick.clicker.palette": {"source":"iana","extensions":["clkp"]}, + "application/vnd.crick.clicker.template": {"source":"iana","extensions":["clkt"]}, + "application/vnd.crick.clicker.wordbank": {"source":"iana","extensions":["clkw"]}, + "application/vnd.criticaltools.wbs+xml": {"source":"iana","compressible":true,"extensions":["wbs"]}, + "application/vnd.cryptii.pipe+json": {"source":"iana","compressible":true}, + "application/vnd.crypto-shade-file": {"source":"iana"}, + "application/vnd.cryptomator.encrypted": {"source":"iana"}, + "application/vnd.cryptomator.vault": {"source":"iana"}, + "application/vnd.ctc-posml": {"source":"iana","extensions":["pml"]}, + "application/vnd.ctct.ws+xml": {"source":"iana","compressible":true}, + "application/vnd.cups-pdf": {"source":"iana"}, + "application/vnd.cups-postscript": {"source":"iana"}, + "application/vnd.cups-ppd": {"source":"iana","extensions":["ppd"]}, + "application/vnd.cups-raster": {"source":"iana"}, + "application/vnd.cups-raw": {"source":"iana"}, + "application/vnd.curl": {"source":"iana"}, + "application/vnd.curl.car": {"source":"apache","extensions":["car"]}, + "application/vnd.curl.pcurl": {"source":"apache","extensions":["pcurl"]}, + "application/vnd.cyan.dean.root+xml": {"source":"iana","compressible":true}, + "application/vnd.cybank": {"source":"iana"}, + "application/vnd.cyclonedx+json": {"source":"iana","compressible":true}, + "application/vnd.cyclonedx+xml": {"source":"iana","compressible":true}, + "application/vnd.d2l.coursepackage1p0+zip": {"source":"iana","compressible":false}, + "application/vnd.d3m-dataset": {"source":"iana"}, + "application/vnd.d3m-problem": {"source":"iana"}, + "application/vnd.dart": {"source":"iana","compressible":true,"extensions":["dart"]}, + "application/vnd.data-vision.rdz": {"source":"iana","extensions":["rdz"]}, + "application/vnd.datalog": {"source":"iana"}, + "application/vnd.datapackage+json": {"source":"iana","compressible":true}, + "application/vnd.dataresource+json": {"source":"iana","compressible":true}, + "application/vnd.dbf": {"source":"iana","extensions":["dbf"]}, + "application/vnd.dcmp+xml": {"source":"iana","compressible":true,"extensions":["dcmp"]}, + "application/vnd.debian.binary-package": {"source":"iana"}, + "application/vnd.dece.data": {"source":"iana","extensions":["uvf","uvvf","uvd","uvvd"]}, + "application/vnd.dece.ttml+xml": {"source":"iana","compressible":true,"extensions":["uvt","uvvt"]}, + "application/vnd.dece.unspecified": {"source":"iana","extensions":["uvx","uvvx"]}, + "application/vnd.dece.zip": {"source":"iana","extensions":["uvz","uvvz"]}, + "application/vnd.denovo.fcselayout-link": {"source":"iana","extensions":["fe_launch"]}, + "application/vnd.desmume.movie": {"source":"iana"}, + "application/vnd.dir-bi.plate-dl-nosuffix": {"source":"iana"}, + "application/vnd.dm.delegation+xml": {"source":"iana","compressible":true}, + "application/vnd.dna": {"source":"iana","extensions":["dna"]}, + "application/vnd.document+json": {"source":"iana","compressible":true}, + "application/vnd.dolby.mlp": {"source":"apache","extensions":["mlp"]}, + "application/vnd.dolby.mobile.1": {"source":"iana"}, + "application/vnd.dolby.mobile.2": {"source":"iana"}, + "application/vnd.doremir.scorecloud-binary-document": {"source":"iana"}, + "application/vnd.dpgraph": {"source":"iana","extensions":["dpg"]}, + "application/vnd.dreamfactory": {"source":"iana","extensions":["dfac"]}, + "application/vnd.drive+json": {"source":"iana","compressible":true}, + "application/vnd.ds-keypoint": {"source":"apache","extensions":["kpxx"]}, + "application/vnd.dtg.local": {"source":"iana"}, + "application/vnd.dtg.local.flash": {"source":"iana"}, + "application/vnd.dtg.local.html": {"source":"iana"}, + "application/vnd.dvb.ait": {"source":"iana","extensions":["ait"]}, + "application/vnd.dvb.dvbisl+xml": {"source":"iana","compressible":true}, + "application/vnd.dvb.dvbj": {"source":"iana"}, + "application/vnd.dvb.esgcontainer": {"source":"iana"}, + "application/vnd.dvb.ipdcdftnotifaccess": {"source":"iana"}, + "application/vnd.dvb.ipdcesgaccess": {"source":"iana"}, + "application/vnd.dvb.ipdcesgaccess2": {"source":"iana"}, + "application/vnd.dvb.ipdcesgpdd": {"source":"iana"}, + "application/vnd.dvb.ipdcroaming": {"source":"iana"}, + "application/vnd.dvb.iptv.alfec-base": {"source":"iana"}, + "application/vnd.dvb.iptv.alfec-enhancement": {"source":"iana"}, + "application/vnd.dvb.notif-aggregate-root+xml": {"source":"iana","compressible":true}, + "application/vnd.dvb.notif-container+xml": {"source":"iana","compressible":true}, + "application/vnd.dvb.notif-generic+xml": {"source":"iana","compressible":true}, + "application/vnd.dvb.notif-ia-msglist+xml": {"source":"iana","compressible":true}, + "application/vnd.dvb.notif-ia-registration-request+xml": {"source":"iana","compressible":true}, + "application/vnd.dvb.notif-ia-registration-response+xml": {"source":"iana","compressible":true}, + "application/vnd.dvb.notif-init+xml": {"source":"iana","compressible":true}, + "application/vnd.dvb.pfr": {"source":"iana"}, + "application/vnd.dvb.service": {"source":"iana","extensions":["svc"]}, + "application/vnd.dxr": {"source":"iana"}, + "application/vnd.dynageo": {"source":"iana","extensions":["geo"]}, + "application/vnd.dzr": {"source":"iana"}, + "application/vnd.easykaraoke.cdgdownload": {"source":"iana"}, + "application/vnd.ecdis-update": {"source":"iana"}, + "application/vnd.ecip.rlp": {"source":"iana"}, + "application/vnd.eclipse.ditto+json": {"source":"iana","compressible":true}, + "application/vnd.ecowin.chart": {"source":"iana","extensions":["mag"]}, + "application/vnd.ecowin.filerequest": {"source":"iana"}, + "application/vnd.ecowin.fileupdate": {"source":"iana"}, + "application/vnd.ecowin.series": {"source":"iana"}, + "application/vnd.ecowin.seriesrequest": {"source":"iana"}, + "application/vnd.ecowin.seriesupdate": {"source":"iana"}, + "application/vnd.efi.img": {"source":"iana"}, + "application/vnd.efi.iso": {"source":"iana"}, + "application/vnd.eln+zip": {"source":"iana","compressible":false}, + "application/vnd.emclient.accessrequest+xml": {"source":"iana","compressible":true}, + "application/vnd.enliven": {"source":"iana","extensions":["nml"]}, + "application/vnd.enphase.envoy": {"source":"iana"}, + "application/vnd.eprints.data+xml": {"source":"iana","compressible":true}, + "application/vnd.epson.esf": {"source":"iana","extensions":["esf"]}, + "application/vnd.epson.msf": {"source":"iana","extensions":["msf"]}, + "application/vnd.epson.quickanime": {"source":"iana","extensions":["qam"]}, + "application/vnd.epson.salt": {"source":"iana","extensions":["slt"]}, + "application/vnd.epson.ssf": {"source":"iana","extensions":["ssf"]}, + "application/vnd.ericsson.quickcall": {"source":"iana"}, + "application/vnd.erofs": {"source":"iana"}, + "application/vnd.espass-espass+zip": {"source":"iana","compressible":false}, + "application/vnd.eszigno3+xml": {"source":"iana","compressible":true,"extensions":["es3","et3"]}, + "application/vnd.etsi.aoc+xml": {"source":"iana","compressible":true}, + "application/vnd.etsi.asic-e+zip": {"source":"iana","compressible":false}, + "application/vnd.etsi.asic-s+zip": {"source":"iana","compressible":false}, + "application/vnd.etsi.cug+xml": {"source":"iana","compressible":true}, + "application/vnd.etsi.iptvcommand+xml": {"source":"iana","compressible":true}, + "application/vnd.etsi.iptvdiscovery+xml": {"source":"iana","compressible":true}, + "application/vnd.etsi.iptvprofile+xml": {"source":"iana","compressible":true}, + "application/vnd.etsi.iptvsad-bc+xml": {"source":"iana","compressible":true}, + "application/vnd.etsi.iptvsad-cod+xml": {"source":"iana","compressible":true}, + "application/vnd.etsi.iptvsad-npvr+xml": {"source":"iana","compressible":true}, + "application/vnd.etsi.iptvservice+xml": {"source":"iana","compressible":true}, + "application/vnd.etsi.iptvsync+xml": {"source":"iana","compressible":true}, + "application/vnd.etsi.iptvueprofile+xml": {"source":"iana","compressible":true}, + "application/vnd.etsi.mcid+xml": {"source":"iana","compressible":true}, + "application/vnd.etsi.mheg5": {"source":"iana"}, + "application/vnd.etsi.overload-control-policy-dataset+xml": {"source":"iana","compressible":true}, + "application/vnd.etsi.pstn+xml": {"source":"iana","compressible":true}, + "application/vnd.etsi.sci+xml": {"source":"iana","compressible":true}, + "application/vnd.etsi.simservs+xml": {"source":"iana","compressible":true}, + "application/vnd.etsi.timestamp-token": {"source":"iana"}, + "application/vnd.etsi.tsl+xml": {"source":"iana","compressible":true}, + "application/vnd.etsi.tsl.der": {"source":"iana"}, + "application/vnd.eu.kasparian.car+json": {"source":"iana","compressible":true}, + "application/vnd.eudora.data": {"source":"iana"}, + "application/vnd.evolv.ecig.profile": {"source":"iana"}, + "application/vnd.evolv.ecig.settings": {"source":"iana"}, + "application/vnd.evolv.ecig.theme": {"source":"iana"}, + "application/vnd.exstream-empower+zip": {"source":"iana","compressible":false}, + "application/vnd.exstream-package": {"source":"iana"}, + "application/vnd.ezpix-album": {"source":"iana","extensions":["ez2"]}, + "application/vnd.ezpix-package": {"source":"iana","extensions":["ez3"]}, + "application/vnd.f-secure.mobile": {"source":"iana"}, + "application/vnd.familysearch.gedcom+zip": {"source":"iana","compressible":false}, + "application/vnd.fastcopy-disk-image": {"source":"iana"}, + "application/vnd.fdf": {"source":"apache","extensions":["fdf"]}, + "application/vnd.fdsn.mseed": {"source":"iana","extensions":["mseed"]}, + "application/vnd.fdsn.seed": {"source":"iana","extensions":["seed","dataless"]}, + "application/vnd.fdsn.stationxml+xml": {"source":"iana","charset":"XML-BASED","compressible":true}, + "application/vnd.ffsns": {"source":"iana"}, + "application/vnd.ficlab.flb+zip": {"source":"iana","compressible":false}, + "application/vnd.filmit.zfc": {"source":"iana"}, + "application/vnd.fints": {"source":"iana"}, + "application/vnd.firemonkeys.cloudcell": {"source":"iana"}, + "application/vnd.flographit": {"source":"iana","extensions":["gph"]}, + "application/vnd.fluxtime.clip": {"source":"iana","extensions":["ftc"]}, + "application/vnd.font-fontforge-sfd": {"source":"iana"}, + "application/vnd.framemaker": {"source":"iana","extensions":["fm","frame","maker","book"]}, + "application/vnd.freelog.comic": {"source":"iana"}, + "application/vnd.frogans.fnc": {"source":"apache","extensions":["fnc"]}, + "application/vnd.frogans.ltf": {"source":"apache","extensions":["ltf"]}, + "application/vnd.fsc.weblaunch": {"source":"iana","extensions":["fsc"]}, + "application/vnd.fujifilm.fb.docuworks": {"source":"iana"}, + "application/vnd.fujifilm.fb.docuworks.binder": {"source":"iana"}, + "application/vnd.fujifilm.fb.docuworks.container": {"source":"iana"}, + "application/vnd.fujifilm.fb.jfi+xml": {"source":"iana","compressible":true}, + "application/vnd.fujitsu.oasys": {"source":"iana","extensions":["oas"]}, + "application/vnd.fujitsu.oasys2": {"source":"iana","extensions":["oa2"]}, + "application/vnd.fujitsu.oasys3": {"source":"iana","extensions":["oa3"]}, + "application/vnd.fujitsu.oasysgp": {"source":"iana","extensions":["fg5"]}, + "application/vnd.fujitsu.oasysprs": {"source":"iana","extensions":["bh2"]}, + "application/vnd.fujixerox.art-ex": {"source":"iana"}, + "application/vnd.fujixerox.art4": {"source":"iana"}, + "application/vnd.fujixerox.ddd": {"source":"iana","extensions":["ddd"]}, + "application/vnd.fujixerox.docuworks": {"source":"iana","extensions":["xdw"]}, + "application/vnd.fujixerox.docuworks.binder": {"source":"iana","extensions":["xbd"]}, + "application/vnd.fujixerox.docuworks.container": {"source":"iana"}, + "application/vnd.fujixerox.hbpl": {"source":"iana"}, + "application/vnd.fut-misnet": {"source":"iana"}, + "application/vnd.futoin+cbor": {"source":"iana"}, + "application/vnd.futoin+json": {"source":"iana","compressible":true}, + "application/vnd.fuzzysheet": {"source":"iana","extensions":["fzs"]}, + "application/vnd.ga4gh.passport+jwt": {"source":"iana"}, + "application/vnd.genomatix.tuxedo": {"source":"iana","extensions":["txd"]}, + "application/vnd.genozip": {"source":"iana"}, + "application/vnd.gentics.grd+json": {"source":"iana","compressible":true}, + "application/vnd.gentoo.catmetadata+xml": {"source":"iana","compressible":true}, + "application/vnd.gentoo.ebuild": {"source":"iana"}, + "application/vnd.gentoo.eclass": {"source":"iana"}, + "application/vnd.gentoo.gpkg": {"source":"iana"}, + "application/vnd.gentoo.manifest": {"source":"iana"}, + "application/vnd.gentoo.pkgmetadata+xml": {"source":"iana","compressible":true}, + "application/vnd.gentoo.xpak": {"source":"iana"}, + "application/vnd.geo+json": {"source":"apache","compressible":true}, + "application/vnd.geocube+xml": {"source":"apache","compressible":true}, + "application/vnd.geogebra.file": {"source":"iana","extensions":["ggb"]}, + "application/vnd.geogebra.pinboard": {"source":"iana"}, + "application/vnd.geogebra.slides": {"source":"iana","extensions":["ggs"]}, + "application/vnd.geogebra.tool": {"source":"iana","extensions":["ggt"]}, + "application/vnd.geometry-explorer": {"source":"iana","extensions":["gex","gre"]}, + "application/vnd.geonext": {"source":"iana","extensions":["gxt"]}, + "application/vnd.geoplan": {"source":"iana","extensions":["g2w"]}, + "application/vnd.geospace": {"source":"iana","extensions":["g3w"]}, + "application/vnd.gerber": {"source":"iana"}, + "application/vnd.globalplatform.card-content-mgt": {"source":"iana"}, + "application/vnd.globalplatform.card-content-mgt-response": {"source":"iana"}, + "application/vnd.gmx": {"source":"iana","extensions":["gmx"]}, + "application/vnd.gnu.taler.exchange+json": {"source":"iana","compressible":true}, + "application/vnd.gnu.taler.merchant+json": {"source":"iana","compressible":true}, + "application/vnd.google-apps.audio": {}, + "application/vnd.google-apps.document": {"compressible":false,"extensions":["gdoc"]}, + "application/vnd.google-apps.drawing": {"compressible":false,"extensions":["gdraw"]}, + "application/vnd.google-apps.drive-sdk": {"compressible":false}, + "application/vnd.google-apps.file": {}, + "application/vnd.google-apps.folder": {"compressible":false}, + "application/vnd.google-apps.form": {"compressible":false,"extensions":["gform"]}, + "application/vnd.google-apps.fusiontable": {}, + "application/vnd.google-apps.jam": {"compressible":false,"extensions":["gjam"]}, + "application/vnd.google-apps.mail-layout": {}, + "application/vnd.google-apps.map": {"compressible":false,"extensions":["gmap"]}, + "application/vnd.google-apps.photo": {}, + "application/vnd.google-apps.presentation": {"compressible":false,"extensions":["gslides"]}, + "application/vnd.google-apps.script": {"compressible":false,"extensions":["gscript"]}, + "application/vnd.google-apps.shortcut": {}, + "application/vnd.google-apps.site": {"compressible":false,"extensions":["gsite"]}, + "application/vnd.google-apps.spreadsheet": {"compressible":false,"extensions":["gsheet"]}, + "application/vnd.google-apps.unknown": {}, + "application/vnd.google-apps.video": {}, + "application/vnd.google-earth.kml+xml": {"source":"iana","compressible":true,"extensions":["kml"]}, + "application/vnd.google-earth.kmz": {"source":"iana","compressible":false,"extensions":["kmz"]}, + "application/vnd.gov.sk.e-form+xml": {"source":"apache","compressible":true}, + "application/vnd.gov.sk.e-form+zip": {"source":"iana","compressible":false}, + "application/vnd.gov.sk.xmldatacontainer+xml": {"source":"iana","compressible":true,"extensions":["xdcf"]}, + "application/vnd.gpxsee.map+xml": {"source":"iana","compressible":true}, + "application/vnd.grafeq": {"source":"iana","extensions":["gqf","gqs"]}, + "application/vnd.gridmp": {"source":"iana"}, + "application/vnd.groove-account": {"source":"iana","extensions":["gac"]}, + "application/vnd.groove-help": {"source":"iana","extensions":["ghf"]}, + "application/vnd.groove-identity-message": {"source":"iana","extensions":["gim"]}, + "application/vnd.groove-injector": {"source":"iana","extensions":["grv"]}, + "application/vnd.groove-tool-message": {"source":"iana","extensions":["gtm"]}, + "application/vnd.groove-tool-template": {"source":"iana","extensions":["tpl"]}, + "application/vnd.groove-vcard": {"source":"iana","extensions":["vcg"]}, + "application/vnd.hal+json": {"source":"iana","compressible":true}, + "application/vnd.hal+xml": {"source":"iana","compressible":true,"extensions":["hal"]}, + "application/vnd.handheld-entertainment+xml": {"source":"iana","compressible":true,"extensions":["zmm"]}, + "application/vnd.hbci": {"source":"iana","extensions":["hbci"]}, + "application/vnd.hc+json": {"source":"iana","compressible":true}, + "application/vnd.hcl-bireports": {"source":"iana"}, + "application/vnd.hdt": {"source":"iana"}, + "application/vnd.heroku+json": {"source":"iana","compressible":true}, + "application/vnd.hhe.lesson-player": {"source":"iana","extensions":["les"]}, + "application/vnd.hp-hpgl": {"source":"iana","extensions":["hpgl"]}, + "application/vnd.hp-hpid": {"source":"iana","extensions":["hpid"]}, + "application/vnd.hp-hps": {"source":"iana","extensions":["hps"]}, + "application/vnd.hp-jlyt": {"source":"iana","extensions":["jlt"]}, + "application/vnd.hp-pcl": {"source":"iana","extensions":["pcl"]}, + "application/vnd.hp-pclxl": {"source":"iana","extensions":["pclxl"]}, + "application/vnd.hsl": {"source":"iana"}, + "application/vnd.httphone": {"source":"iana"}, + "application/vnd.hydrostatix.sof-data": {"source":"iana","extensions":["sfd-hdstx"]}, + "application/vnd.hyper+json": {"source":"iana","compressible":true}, + "application/vnd.hyper-item+json": {"source":"iana","compressible":true}, + "application/vnd.hyperdrive+json": {"source":"iana","compressible":true}, + "application/vnd.hzn-3d-crossword": {"source":"iana"}, + "application/vnd.ibm.afplinedata": {"source":"apache"}, + "application/vnd.ibm.electronic-media": {"source":"iana"}, + "application/vnd.ibm.minipay": {"source":"iana","extensions":["mpy"]}, + "application/vnd.ibm.modcap": {"source":"apache","extensions":["afp","listafp","list3820"]}, + "application/vnd.ibm.rights-management": {"source":"iana","extensions":["irm"]}, + "application/vnd.ibm.secure-container": {"source":"iana","extensions":["sc"]}, + "application/vnd.iccprofile": {"source":"iana","extensions":["icc","icm"]}, + "application/vnd.ieee.1905": {"source":"iana"}, + "application/vnd.igloader": {"source":"iana","extensions":["igl"]}, + "application/vnd.imagemeter.folder+zip": {"source":"iana","compressible":false}, + "application/vnd.imagemeter.image+zip": {"source":"iana","compressible":false}, + "application/vnd.immervision-ivp": {"source":"iana","extensions":["ivp"]}, + "application/vnd.immervision-ivu": {"source":"iana","extensions":["ivu"]}, + "application/vnd.ims.imsccv1p1": {"source":"iana"}, + "application/vnd.ims.imsccv1p2": {"source":"iana"}, + "application/vnd.ims.imsccv1p3": {"source":"iana"}, + "application/vnd.ims.lis.v2.result+json": {"source":"iana","compressible":true}, + "application/vnd.ims.lti.v2.toolconsumerprofile+json": {"source":"iana","compressible":true}, + "application/vnd.ims.lti.v2.toolproxy+json": {"source":"iana","compressible":true}, + "application/vnd.ims.lti.v2.toolproxy.id+json": {"source":"iana","compressible":true}, + "application/vnd.ims.lti.v2.toolsettings+json": {"source":"iana","compressible":true}, + "application/vnd.ims.lti.v2.toolsettings.simple+json": {"source":"iana","compressible":true}, + "application/vnd.informedcontrol.rms+xml": {"source":"iana","compressible":true}, + "application/vnd.informix-visionary": {"source":"apache"}, + "application/vnd.infotech.project": {"source":"iana"}, + "application/vnd.infotech.project+xml": {"source":"iana","compressible":true}, + "application/vnd.innopath.wamp.notification": {"source":"iana"}, + "application/vnd.insors.igm": {"source":"iana","extensions":["igm"]}, + "application/vnd.intercon.formnet": {"source":"iana","extensions":["xpw","xpx"]}, + "application/vnd.intergeo": {"source":"iana","extensions":["i2g"]}, + "application/vnd.intertrust.digibox": {"source":"iana"}, + "application/vnd.intertrust.nncp": {"source":"iana"}, + "application/vnd.intu.qbo": {"source":"iana","extensions":["qbo"]}, + "application/vnd.intu.qfx": {"source":"iana","extensions":["qfx"]}, + "application/vnd.ipfs.ipns-record": {"source":"iana"}, + "application/vnd.ipld.car": {"source":"iana"}, + "application/vnd.ipld.dag-cbor": {"source":"iana"}, + "application/vnd.ipld.dag-json": {"source":"iana"}, + "application/vnd.ipld.raw": {"source":"iana"}, + "application/vnd.iptc.g2.catalogitem+xml": {"source":"iana","compressible":true}, + "application/vnd.iptc.g2.conceptitem+xml": {"source":"iana","compressible":true}, + "application/vnd.iptc.g2.knowledgeitem+xml": {"source":"iana","compressible":true}, + "application/vnd.iptc.g2.newsitem+xml": {"source":"iana","compressible":true}, + "application/vnd.iptc.g2.newsmessage+xml": {"source":"iana","compressible":true}, + "application/vnd.iptc.g2.packageitem+xml": {"source":"iana","compressible":true}, + "application/vnd.iptc.g2.planningitem+xml": {"source":"iana","compressible":true}, + "application/vnd.ipunplugged.rcprofile": {"source":"iana","extensions":["rcprofile"]}, + "application/vnd.irepository.package+xml": {"source":"iana","compressible":true,"extensions":["irp"]}, + "application/vnd.is-xpr": {"source":"iana","extensions":["xpr"]}, + "application/vnd.isac.fcs": {"source":"iana","extensions":["fcs"]}, + "application/vnd.iso11783-10+zip": {"source":"iana","compressible":false}, + "application/vnd.jam": {"source":"iana","extensions":["jam"]}, + "application/vnd.japannet-directory-service": {"source":"iana"}, + "application/vnd.japannet-jpnstore-wakeup": {"source":"iana"}, + "application/vnd.japannet-payment-wakeup": {"source":"iana"}, + "application/vnd.japannet-registration": {"source":"iana"}, + "application/vnd.japannet-registration-wakeup": {"source":"iana"}, + "application/vnd.japannet-setstore-wakeup": {"source":"iana"}, + "application/vnd.japannet-verification": {"source":"iana"}, + "application/vnd.japannet-verification-wakeup": {"source":"iana"}, + "application/vnd.jcp.javame.midlet-rms": {"source":"iana","extensions":["rms"]}, + "application/vnd.jisp": {"source":"iana","extensions":["jisp"]}, + "application/vnd.joost.joda-archive": {"source":"iana","extensions":["joda"]}, + "application/vnd.jsk.isdn-ngn": {"source":"iana"}, + "application/vnd.kahootz": {"source":"iana","extensions":["ktz","ktr"]}, + "application/vnd.kde.karbon": {"source":"iana","extensions":["karbon"]}, + "application/vnd.kde.kchart": {"source":"iana","extensions":["chrt"]}, + "application/vnd.kde.kformula": {"source":"iana","extensions":["kfo"]}, + "application/vnd.kde.kivio": {"source":"iana","extensions":["flw"]}, + "application/vnd.kde.kontour": {"source":"iana","extensions":["kon"]}, + "application/vnd.kde.kpresenter": {"source":"iana","extensions":["kpr","kpt"]}, + "application/vnd.kde.kspread": {"source":"iana","extensions":["ksp"]}, + "application/vnd.kde.kword": {"source":"iana","extensions":["kwd","kwt"]}, + "application/vnd.kdl": {"source":"iana"}, + "application/vnd.kenameaapp": {"source":"iana","extensions":["htke"]}, + "application/vnd.keyman.kmp+zip": {"source":"iana","compressible":false}, + "application/vnd.keyman.kmx": {"source":"iana"}, + "application/vnd.kidspiration": {"source":"iana","extensions":["kia"]}, + "application/vnd.kinar": {"source":"iana","extensions":["kne","knp"]}, + "application/vnd.koan": {"source":"iana","extensions":["skp","skd","skt","skm"]}, + "application/vnd.kodak-descriptor": {"source":"iana","extensions":["sse"]}, + "application/vnd.las": {"source":"iana"}, + "application/vnd.las.las+json": {"source":"iana","compressible":true}, + "application/vnd.las.las+xml": {"source":"iana","compressible":true,"extensions":["lasxml"]}, + "application/vnd.laszip": {"source":"iana"}, + "application/vnd.ldev.productlicensing": {"source":"iana"}, + "application/vnd.leap+json": {"source":"iana","compressible":true}, + "application/vnd.liberty-request+xml": {"source":"iana","compressible":true}, + "application/vnd.llamagraphics.life-balance.desktop": {"source":"iana","extensions":["lbd"]}, + "application/vnd.llamagraphics.life-balance.exchange+xml": {"source":"iana","compressible":true,"extensions":["lbe"]}, + "application/vnd.logipipe.circuit+zip": {"source":"iana","compressible":false}, + "application/vnd.loom": {"source":"iana"}, + "application/vnd.lotus-1-2-3": {"source":"iana","extensions":["123"]}, + "application/vnd.lotus-approach": {"source":"iana","extensions":["apr"]}, + "application/vnd.lotus-freelance": {"source":"iana","extensions":["pre"]}, + "application/vnd.lotus-notes": {"source":"iana","extensions":["nsf"]}, + "application/vnd.lotus-organizer": {"source":"iana","extensions":["org"]}, + "application/vnd.lotus-screencam": {"source":"iana","extensions":["scm"]}, + "application/vnd.lotus-wordpro": {"source":"iana","extensions":["lwp"]}, + "application/vnd.macports.portpkg": {"source":"iana","extensions":["portpkg"]}, + "application/vnd.mapbox-vector-tile": {"source":"iana","extensions":["mvt"]}, + "application/vnd.marlin.drm.actiontoken+xml": {"source":"iana","compressible":true}, + "application/vnd.marlin.drm.conftoken+xml": {"source":"iana","compressible":true}, + "application/vnd.marlin.drm.license+xml": {"source":"iana","compressible":true}, + "application/vnd.marlin.drm.mdcf": {"source":"iana"}, + "application/vnd.mason+json": {"source":"iana","compressible":true}, + "application/vnd.maxar.archive.3tz+zip": {"source":"iana","compressible":false}, + "application/vnd.maxmind.maxmind-db": {"source":"iana"}, + "application/vnd.mcd": {"source":"iana","extensions":["mcd"]}, + "application/vnd.mdl": {"source":"iana"}, + "application/vnd.mdl-mbsdf": {"source":"iana"}, + "application/vnd.medcalcdata": {"source":"iana","extensions":["mc1"]}, + "application/vnd.mediastation.cdkey": {"source":"iana","extensions":["cdkey"]}, + "application/vnd.medicalholodeck.recordxr": {"source":"iana"}, + "application/vnd.meridian-slingshot": {"source":"iana"}, + "application/vnd.mermaid": {"source":"iana"}, + "application/vnd.mfer": {"source":"iana","extensions":["mwf"]}, + "application/vnd.mfmp": {"source":"iana","extensions":["mfm"]}, + "application/vnd.micro+json": {"source":"iana","compressible":true}, + "application/vnd.micrografx.flo": {"source":"iana","extensions":["flo"]}, + "application/vnd.micrografx.igx": {"source":"iana","extensions":["igx"]}, + "application/vnd.microsoft.portable-executable": {"source":"iana"}, + "application/vnd.microsoft.windows.thumbnail-cache": {"source":"iana"}, + "application/vnd.miele+json": {"source":"iana","compressible":true}, + "application/vnd.mif": {"source":"iana","extensions":["mif"]}, + "application/vnd.minisoft-hp3000-save": {"source":"iana"}, + "application/vnd.mitsubishi.misty-guard.trustweb": {"source":"iana"}, + "application/vnd.mobius.daf": {"source":"iana","extensions":["daf"]}, + "application/vnd.mobius.dis": {"source":"iana","extensions":["dis"]}, + "application/vnd.mobius.mbk": {"source":"iana","extensions":["mbk"]}, + "application/vnd.mobius.mqy": {"source":"iana","extensions":["mqy"]}, + "application/vnd.mobius.msl": {"source":"iana","extensions":["msl"]}, + "application/vnd.mobius.plc": {"source":"iana","extensions":["plc"]}, + "application/vnd.mobius.txf": {"source":"iana","extensions":["txf"]}, + "application/vnd.modl": {"source":"iana"}, + "application/vnd.mophun.application": {"source":"iana","extensions":["mpn"]}, + "application/vnd.mophun.certificate": {"source":"iana","extensions":["mpc"]}, + "application/vnd.motorola.flexsuite": {"source":"iana"}, + "application/vnd.motorola.flexsuite.adsi": {"source":"iana"}, + "application/vnd.motorola.flexsuite.fis": {"source":"iana"}, + "application/vnd.motorola.flexsuite.gotap": {"source":"iana"}, + "application/vnd.motorola.flexsuite.kmr": {"source":"iana"}, + "application/vnd.motorola.flexsuite.ttc": {"source":"iana"}, + "application/vnd.motorola.flexsuite.wem": {"source":"iana"}, + "application/vnd.motorola.iprm": {"source":"iana"}, + "application/vnd.mozilla.xul+xml": {"source":"iana","compressible":true,"extensions":["xul"]}, + "application/vnd.ms-3mfdocument": {"source":"iana"}, + "application/vnd.ms-artgalry": {"source":"iana","extensions":["cil"]}, + "application/vnd.ms-asf": {"source":"iana"}, + "application/vnd.ms-cab-compressed": {"source":"iana","extensions":["cab"]}, + "application/vnd.ms-color.iccprofile": {"source":"apache"}, + "application/vnd.ms-excel": {"source":"iana","compressible":false,"extensions":["xls","xlm","xla","xlc","xlt","xlw"]}, + "application/vnd.ms-excel.addin.macroenabled.12": {"source":"iana","extensions":["xlam"]}, + "application/vnd.ms-excel.sheet.binary.macroenabled.12": {"source":"iana","extensions":["xlsb"]}, + "application/vnd.ms-excel.sheet.macroenabled.12": {"source":"iana","extensions":["xlsm"]}, + "application/vnd.ms-excel.template.macroenabled.12": {"source":"iana","extensions":["xltm"]}, + "application/vnd.ms-fontobject": {"source":"iana","compressible":true,"extensions":["eot"]}, + "application/vnd.ms-htmlhelp": {"source":"iana","extensions":["chm"]}, + "application/vnd.ms-ims": {"source":"iana","extensions":["ims"]}, + "application/vnd.ms-lrm": {"source":"iana","extensions":["lrm"]}, + "application/vnd.ms-office.activex+xml": {"source":"iana","compressible":true}, + "application/vnd.ms-officetheme": {"source":"iana","extensions":["thmx"]}, + "application/vnd.ms-opentype": {"source":"apache","compressible":true}, + "application/vnd.ms-outlook": {"compressible":false,"extensions":["msg"]}, + "application/vnd.ms-package.obfuscated-opentype": {"source":"apache"}, + "application/vnd.ms-pki.seccat": {"source":"apache","extensions":["cat"]}, + "application/vnd.ms-pki.stl": {"source":"apache","extensions":["stl"]}, + "application/vnd.ms-playready.initiator+xml": {"source":"iana","compressible":true}, + "application/vnd.ms-powerpoint": {"source":"iana","compressible":false,"extensions":["ppt","pps","pot"]}, + "application/vnd.ms-powerpoint.addin.macroenabled.12": {"source":"iana","extensions":["ppam"]}, + "application/vnd.ms-powerpoint.presentation.macroenabled.12": {"source":"iana","extensions":["pptm"]}, + "application/vnd.ms-powerpoint.slide.macroenabled.12": {"source":"iana","extensions":["sldm"]}, + "application/vnd.ms-powerpoint.slideshow.macroenabled.12": {"source":"iana","extensions":["ppsm"]}, + "application/vnd.ms-powerpoint.template.macroenabled.12": {"source":"iana","extensions":["potm"]}, + "application/vnd.ms-printdevicecapabilities+xml": {"source":"iana","compressible":true}, + "application/vnd.ms-printing.printticket+xml": {"source":"apache","compressible":true}, + "application/vnd.ms-printschematicket+xml": {"source":"iana","compressible":true}, + "application/vnd.ms-project": {"source":"iana","extensions":["mpp","mpt"]}, + "application/vnd.ms-tnef": {"source":"iana"}, + "application/vnd.ms-visio.viewer": {"extensions":["vdx"]}, + "application/vnd.ms-windows.devicepairing": {"source":"iana"}, + "application/vnd.ms-windows.nwprinting.oob": {"source":"iana"}, + "application/vnd.ms-windows.printerpairing": {"source":"iana"}, + "application/vnd.ms-windows.wsd.oob": {"source":"iana"}, + "application/vnd.ms-wmdrm.lic-chlg-req": {"source":"iana"}, + "application/vnd.ms-wmdrm.lic-resp": {"source":"iana"}, + "application/vnd.ms-wmdrm.meter-chlg-req": {"source":"iana"}, + "application/vnd.ms-wmdrm.meter-resp": {"source":"iana"}, + "application/vnd.ms-word.document.macroenabled.12": {"source":"iana","extensions":["docm"]}, + "application/vnd.ms-word.template.macroenabled.12": {"source":"iana","extensions":["dotm"]}, + "application/vnd.ms-works": {"source":"iana","extensions":["wps","wks","wcm","wdb"]}, + "application/vnd.ms-wpl": {"source":"iana","extensions":["wpl"]}, + "application/vnd.ms-xpsdocument": {"source":"iana","compressible":false,"extensions":["xps"]}, + "application/vnd.msa-disk-image": {"source":"iana"}, + "application/vnd.mseq": {"source":"iana","extensions":["mseq"]}, + "application/vnd.msgpack": {"source":"iana"}, + "application/vnd.msign": {"source":"iana"}, + "application/vnd.multiad.creator": {"source":"iana"}, + "application/vnd.multiad.creator.cif": {"source":"iana"}, + "application/vnd.music-niff": {"source":"iana"}, + "application/vnd.musician": {"source":"iana","extensions":["mus"]}, + "application/vnd.muvee.style": {"source":"iana","extensions":["msty"]}, + "application/vnd.mynfc": {"source":"iana","extensions":["taglet"]}, + "application/vnd.nacamar.ybrid+json": {"source":"iana","compressible":true}, + "application/vnd.nato.bindingdataobject+cbor": {"source":"iana"}, + "application/vnd.nato.bindingdataobject+json": {"source":"iana","compressible":true}, + "application/vnd.nato.bindingdataobject+xml": {"source":"iana","compressible":true,"extensions":["bdo"]}, + "application/vnd.nato.openxmlformats-package.iepd+zip": {"source":"iana","compressible":false}, + "application/vnd.ncd.control": {"source":"iana"}, + "application/vnd.ncd.reference": {"source":"iana"}, + "application/vnd.nearst.inv+json": {"source":"iana","compressible":true}, + "application/vnd.nebumind.line": {"source":"iana"}, + "application/vnd.nervana": {"source":"iana"}, + "application/vnd.netfpx": {"source":"iana"}, + "application/vnd.neurolanguage.nlu": {"source":"iana","extensions":["nlu"]}, + "application/vnd.nimn": {"source":"iana"}, + "application/vnd.nintendo.nitro.rom": {"source":"iana"}, + "application/vnd.nintendo.snes.rom": {"source":"iana"}, + "application/vnd.nitf": {"source":"iana","extensions":["ntf","nitf"]}, + "application/vnd.noblenet-directory": {"source":"iana","extensions":["nnd"]}, + "application/vnd.noblenet-sealer": {"source":"iana","extensions":["nns"]}, + "application/vnd.noblenet-web": {"source":"iana","extensions":["nnw"]}, + "application/vnd.nokia.catalogs": {"source":"iana"}, + "application/vnd.nokia.conml+wbxml": {"source":"iana"}, + "application/vnd.nokia.conml+xml": {"source":"iana","compressible":true}, + "application/vnd.nokia.iptv.config+xml": {"source":"iana","compressible":true}, + "application/vnd.nokia.isds-radio-presets": {"source":"iana"}, + "application/vnd.nokia.landmark+wbxml": {"source":"iana"}, + "application/vnd.nokia.landmark+xml": {"source":"iana","compressible":true}, + "application/vnd.nokia.landmarkcollection+xml": {"source":"iana","compressible":true}, + "application/vnd.nokia.n-gage.ac+xml": {"source":"iana","compressible":true,"extensions":["ac"]}, + "application/vnd.nokia.n-gage.data": {"source":"iana","extensions":["ngdat"]}, + "application/vnd.nokia.n-gage.symbian.install": {"source":"apache","extensions":["n-gage"]}, + "application/vnd.nokia.ncd": {"source":"iana"}, + "application/vnd.nokia.pcd+wbxml": {"source":"iana"}, + "application/vnd.nokia.pcd+xml": {"source":"iana","compressible":true}, + "application/vnd.nokia.radio-preset": {"source":"iana","extensions":["rpst"]}, + "application/vnd.nokia.radio-presets": {"source":"iana","extensions":["rpss"]}, + "application/vnd.novadigm.edm": {"source":"iana","extensions":["edm"]}, + "application/vnd.novadigm.edx": {"source":"iana","extensions":["edx"]}, + "application/vnd.novadigm.ext": {"source":"iana","extensions":["ext"]}, + "application/vnd.ntt-local.content-share": {"source":"iana"}, + "application/vnd.ntt-local.file-transfer": {"source":"iana"}, + "application/vnd.ntt-local.ogw_remote-access": {"source":"iana"}, + "application/vnd.ntt-local.sip-ta_remote": {"source":"iana"}, + "application/vnd.ntt-local.sip-ta_tcp_stream": {"source":"iana"}, + "application/vnd.oai.workflows": {"source":"iana"}, + "application/vnd.oai.workflows+json": {"source":"iana","compressible":true}, + "application/vnd.oai.workflows+yaml": {"source":"iana"}, + "application/vnd.oasis.opendocument.base": {"source":"iana"}, + "application/vnd.oasis.opendocument.chart": {"source":"iana","extensions":["odc"]}, + "application/vnd.oasis.opendocument.chart-template": {"source":"iana","extensions":["otc"]}, + "application/vnd.oasis.opendocument.database": {"source":"apache","extensions":["odb"]}, + "application/vnd.oasis.opendocument.formula": {"source":"iana","extensions":["odf"]}, + "application/vnd.oasis.opendocument.formula-template": {"source":"iana","extensions":["odft"]}, + "application/vnd.oasis.opendocument.graphics": {"source":"iana","compressible":false,"extensions":["odg"]}, + "application/vnd.oasis.opendocument.graphics-template": {"source":"iana","extensions":["otg"]}, + "application/vnd.oasis.opendocument.image": {"source":"iana","extensions":["odi"]}, + "application/vnd.oasis.opendocument.image-template": {"source":"iana","extensions":["oti"]}, + "application/vnd.oasis.opendocument.presentation": {"source":"iana","compressible":false,"extensions":["odp"]}, + "application/vnd.oasis.opendocument.presentation-template": {"source":"iana","extensions":["otp"]}, + "application/vnd.oasis.opendocument.spreadsheet": {"source":"iana","compressible":false,"extensions":["ods"]}, + "application/vnd.oasis.opendocument.spreadsheet-template": {"source":"iana","extensions":["ots"]}, + "application/vnd.oasis.opendocument.text": {"source":"iana","compressible":false,"extensions":["odt"]}, + "application/vnd.oasis.opendocument.text-master": {"source":"iana","extensions":["odm"]}, + "application/vnd.oasis.opendocument.text-master-template": {"source":"iana"}, + "application/vnd.oasis.opendocument.text-template": {"source":"iana","extensions":["ott"]}, + "application/vnd.oasis.opendocument.text-web": {"source":"iana","extensions":["oth"]}, + "application/vnd.obn": {"source":"iana"}, + "application/vnd.ocf+cbor": {"source":"iana"}, + "application/vnd.oci.image.manifest.v1+json": {"source":"iana","compressible":true}, + "application/vnd.oftn.l10n+json": {"source":"iana","compressible":true}, + "application/vnd.oipf.contentaccessdownload+xml": {"source":"iana","compressible":true}, + "application/vnd.oipf.contentaccessstreaming+xml": {"source":"iana","compressible":true}, + "application/vnd.oipf.cspg-hexbinary": {"source":"iana"}, + "application/vnd.oipf.dae.svg+xml": {"source":"iana","compressible":true}, + "application/vnd.oipf.dae.xhtml+xml": {"source":"iana","compressible":true}, + "application/vnd.oipf.mippvcontrolmessage+xml": {"source":"iana","compressible":true}, + "application/vnd.oipf.pae.gem": {"source":"iana"}, + "application/vnd.oipf.spdiscovery+xml": {"source":"iana","compressible":true}, + "application/vnd.oipf.spdlist+xml": {"source":"iana","compressible":true}, + "application/vnd.oipf.ueprofile+xml": {"source":"iana","compressible":true}, + "application/vnd.oipf.userprofile+xml": {"source":"iana","compressible":true}, + "application/vnd.olpc-sugar": {"source":"iana","extensions":["xo"]}, + "application/vnd.oma-scws-config": {"source":"iana"}, + "application/vnd.oma-scws-http-request": {"source":"iana"}, + "application/vnd.oma-scws-http-response": {"source":"iana"}, + "application/vnd.oma.bcast.associated-procedure-parameter+xml": {"source":"iana","compressible":true}, + "application/vnd.oma.bcast.drm-trigger+xml": {"source":"apache","compressible":true}, + "application/vnd.oma.bcast.imd+xml": {"source":"iana","compressible":true}, + "application/vnd.oma.bcast.ltkm": {"source":"iana"}, + "application/vnd.oma.bcast.notification+xml": {"source":"iana","compressible":true}, + "application/vnd.oma.bcast.provisioningtrigger": {"source":"iana"}, + "application/vnd.oma.bcast.sgboot": {"source":"iana"}, + "application/vnd.oma.bcast.sgdd+xml": {"source":"iana","compressible":true}, + "application/vnd.oma.bcast.sgdu": {"source":"iana"}, + "application/vnd.oma.bcast.simple-symbol-container": {"source":"iana"}, + "application/vnd.oma.bcast.smartcard-trigger+xml": {"source":"apache","compressible":true}, + "application/vnd.oma.bcast.sprov+xml": {"source":"iana","compressible":true}, + "application/vnd.oma.bcast.stkm": {"source":"iana"}, + "application/vnd.oma.cab-address-book+xml": {"source":"iana","compressible":true}, + "application/vnd.oma.cab-feature-handler+xml": {"source":"iana","compressible":true}, + "application/vnd.oma.cab-pcc+xml": {"source":"iana","compressible":true}, + "application/vnd.oma.cab-subs-invite+xml": {"source":"iana","compressible":true}, + "application/vnd.oma.cab-user-prefs+xml": {"source":"iana","compressible":true}, + "application/vnd.oma.dcd": {"source":"iana"}, + "application/vnd.oma.dcdc": {"source":"iana"}, + "application/vnd.oma.dd2+xml": {"source":"iana","compressible":true,"extensions":["dd2"]}, + "application/vnd.oma.drm.risd+xml": {"source":"iana","compressible":true}, + "application/vnd.oma.group-usage-list+xml": {"source":"iana","compressible":true}, + "application/vnd.oma.lwm2m+cbor": {"source":"iana"}, + "application/vnd.oma.lwm2m+json": {"source":"iana","compressible":true}, + "application/vnd.oma.lwm2m+tlv": {"source":"iana"}, + "application/vnd.oma.pal+xml": {"source":"iana","compressible":true}, + "application/vnd.oma.poc.detailed-progress-report+xml": {"source":"iana","compressible":true}, + "application/vnd.oma.poc.final-report+xml": {"source":"iana","compressible":true}, + "application/vnd.oma.poc.groups+xml": {"source":"iana","compressible":true}, + "application/vnd.oma.poc.invocation-descriptor+xml": {"source":"iana","compressible":true}, + "application/vnd.oma.poc.optimized-progress-report+xml": {"source":"iana","compressible":true}, + "application/vnd.oma.push": {"source":"iana"}, + "application/vnd.oma.scidm.messages+xml": {"source":"iana","compressible":true}, + "application/vnd.oma.xcap-directory+xml": {"source":"iana","compressible":true}, + "application/vnd.omads-email+xml": {"source":"iana","charset":"UTF-8","compressible":true}, + "application/vnd.omads-file+xml": {"source":"iana","charset":"UTF-8","compressible":true}, + "application/vnd.omads-folder+xml": {"source":"iana","charset":"UTF-8","compressible":true}, + "application/vnd.omaloc-supl-init": {"source":"iana"}, + "application/vnd.onepager": {"source":"iana"}, + "application/vnd.onepagertamp": {"source":"iana"}, + "application/vnd.onepagertamx": {"source":"iana"}, + "application/vnd.onepagertat": {"source":"iana"}, + "application/vnd.onepagertatp": {"source":"iana"}, + "application/vnd.onepagertatx": {"source":"iana"}, + "application/vnd.onvif.metadata": {"source":"iana"}, + "application/vnd.openblox.game+xml": {"source":"iana","compressible":true,"extensions":["obgx"]}, + "application/vnd.openblox.game-binary": {"source":"iana"}, + "application/vnd.openeye.oeb": {"source":"iana"}, + "application/vnd.openofficeorg.extension": {"source":"apache","extensions":["oxt"]}, + "application/vnd.openstreetmap.data+xml": {"source":"iana","compressible":true,"extensions":["osm"]}, + "application/vnd.opentimestamps.ots": {"source":"iana"}, + "application/vnd.openvpi.dspx+json": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.custom-properties+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.customxmlproperties+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.drawing+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.drawingml.chart+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.extended-properties+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.presentationml.comments+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.presentationml.presentation": {"source":"iana","compressible":false,"extensions":["pptx"]}, + "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.presentationml.presprops+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.presentationml.slide": {"source":"iana","extensions":["sldx"]}, + "application/vnd.openxmlformats-officedocument.presentationml.slide+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.presentationml.slideshow": {"source":"iana","extensions":["ppsx"]}, + "application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.presentationml.tags+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.presentationml.template": {"source":"iana","extensions":["potx"]}, + "application/vnd.openxmlformats-officedocument.presentationml.template.main+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": {"source":"iana","compressible":false,"extensions":["xlsx"]}, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.spreadsheetml.template": {"source":"iana","extensions":["xltx"]}, + "application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.theme+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.themeoverride+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.vmldrawing": {"source":"iana"}, + "application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.wordprocessingml.document": {"source":"iana","compressible":false,"extensions":["docx"]}, + "application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.wordprocessingml.template": {"source":"iana","extensions":["dotx"]}, + "application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-package.core-properties+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml": {"source":"iana","compressible":true}, + "application/vnd.openxmlformats-package.relationships+xml": {"source":"iana","compressible":true}, + "application/vnd.oracle.resource+json": {"source":"iana","compressible":true}, + "application/vnd.orange.indata": {"source":"iana"}, + "application/vnd.osa.netdeploy": {"source":"iana"}, + "application/vnd.osgeo.mapguide.package": {"source":"iana","extensions":["mgp"]}, + "application/vnd.osgi.bundle": {"source":"iana"}, + "application/vnd.osgi.dp": {"source":"iana","extensions":["dp"]}, + "application/vnd.osgi.subsystem": {"source":"iana","extensions":["esa"]}, + "application/vnd.otps.ct-kip+xml": {"source":"iana","compressible":true}, + "application/vnd.oxli.countgraph": {"source":"iana"}, + "application/vnd.pagerduty+json": {"source":"iana","compressible":true}, + "application/vnd.palm": {"source":"iana","extensions":["pdb","pqa","oprc"]}, + "application/vnd.panoply": {"source":"iana"}, + "application/vnd.paos.xml": {"source":"iana"}, + "application/vnd.patentdive": {"source":"iana"}, + "application/vnd.patientecommsdoc": {"source":"iana"}, + "application/vnd.pawaafile": {"source":"iana","extensions":["paw"]}, + "application/vnd.pcos": {"source":"iana"}, + "application/vnd.pg.format": {"source":"iana","extensions":["str"]}, + "application/vnd.pg.osasli": {"source":"iana","extensions":["ei6"]}, + "application/vnd.piaccess.application-licence": {"source":"iana"}, + "application/vnd.picsel": {"source":"iana","extensions":["efif"]}, + "application/vnd.pmi.widget": {"source":"iana","extensions":["wg"]}, + "application/vnd.poc.group-advertisement+xml": {"source":"iana","compressible":true}, + "application/vnd.pocketlearn": {"source":"iana","extensions":["plf"]}, + "application/vnd.powerbuilder6": {"source":"iana","extensions":["pbd"]}, + "application/vnd.powerbuilder6-s": {"source":"iana"}, + "application/vnd.powerbuilder7": {"source":"iana"}, + "application/vnd.powerbuilder7-s": {"source":"iana"}, + "application/vnd.powerbuilder75": {"source":"iana"}, + "application/vnd.powerbuilder75-s": {"source":"iana"}, + "application/vnd.preminet": {"source":"iana"}, + "application/vnd.previewsystems.box": {"source":"iana","extensions":["box"]}, + "application/vnd.procrate.brushset": {"extensions":["brushset"]}, + "application/vnd.procreate.brush": {"extensions":["brush"]}, + "application/vnd.procreate.dream": {"extensions":["drm"]}, + "application/vnd.proteus.magazine": {"source":"iana","extensions":["mgz"]}, + "application/vnd.psfs": {"source":"iana"}, + "application/vnd.pt.mundusmundi": {"source":"iana"}, + "application/vnd.publishare-delta-tree": {"source":"iana","extensions":["qps"]}, + "application/vnd.pvi.ptid1": {"source":"iana","extensions":["ptid"]}, + "application/vnd.pwg-multiplexed": {"source":"iana"}, + "application/vnd.pwg-xhtml-print+xml": {"source":"iana","compressible":true,"extensions":["xhtm"]}, + "application/vnd.qualcomm.brew-app-res": {"source":"iana"}, + "application/vnd.quarantainenet": {"source":"iana"}, + "application/vnd.quark.quarkxpress": {"source":"iana","extensions":["qxd","qxt","qwd","qwt","qxl","qxb"]}, + "application/vnd.quobject-quoxdocument": {"source":"iana"}, + "application/vnd.radisys.moml+xml": {"source":"iana","compressible":true}, + "application/vnd.radisys.msml+xml": {"source":"iana","compressible":true}, + "application/vnd.radisys.msml-audit+xml": {"source":"iana","compressible":true}, + "application/vnd.radisys.msml-audit-conf+xml": {"source":"iana","compressible":true}, + "application/vnd.radisys.msml-audit-conn+xml": {"source":"iana","compressible":true}, + "application/vnd.radisys.msml-audit-dialog+xml": {"source":"iana","compressible":true}, + "application/vnd.radisys.msml-audit-stream+xml": {"source":"iana","compressible":true}, + "application/vnd.radisys.msml-conf+xml": {"source":"iana","compressible":true}, + "application/vnd.radisys.msml-dialog+xml": {"source":"iana","compressible":true}, + "application/vnd.radisys.msml-dialog-base+xml": {"source":"iana","compressible":true}, + "application/vnd.radisys.msml-dialog-fax-detect+xml": {"source":"iana","compressible":true}, + "application/vnd.radisys.msml-dialog-fax-sendrecv+xml": {"source":"iana","compressible":true}, + "application/vnd.radisys.msml-dialog-group+xml": {"source":"iana","compressible":true}, + "application/vnd.radisys.msml-dialog-speech+xml": {"source":"iana","compressible":true}, + "application/vnd.radisys.msml-dialog-transform+xml": {"source":"iana","compressible":true}, + "application/vnd.rainstor.data": {"source":"iana"}, + "application/vnd.rapid": {"source":"iana"}, + "application/vnd.rar": {"source":"iana","extensions":["rar"]}, + "application/vnd.realvnc.bed": {"source":"iana","extensions":["bed"]}, + "application/vnd.recordare.musicxml": {"source":"iana","extensions":["mxl"]}, + "application/vnd.recordare.musicxml+xml": {"source":"iana","compressible":true,"extensions":["musicxml"]}, + "application/vnd.relpipe": {"source":"iana"}, + "application/vnd.renlearn.rlprint": {"source":"iana"}, + "application/vnd.resilient.logic": {"source":"iana"}, + "application/vnd.restful+json": {"source":"iana","compressible":true}, + "application/vnd.rig.cryptonote": {"source":"iana","extensions":["cryptonote"]}, + "application/vnd.rim.cod": {"source":"apache","extensions":["cod"]}, + "application/vnd.rn-realmedia": {"source":"apache","extensions":["rm"]}, + "application/vnd.rn-realmedia-vbr": {"source":"apache","extensions":["rmvb"]}, + "application/vnd.route66.link66+xml": {"source":"iana","compressible":true,"extensions":["link66"]}, + "application/vnd.rs-274x": {"source":"iana"}, + "application/vnd.ruckus.download": {"source":"iana"}, + "application/vnd.s3sms": {"source":"iana"}, + "application/vnd.sailingtracker.track": {"source":"iana","extensions":["st"]}, + "application/vnd.sar": {"source":"iana"}, + "application/vnd.sbm.cid": {"source":"iana"}, + "application/vnd.sbm.mid2": {"source":"iana"}, + "application/vnd.scribus": {"source":"iana"}, + "application/vnd.sealed.3df": {"source":"iana"}, + "application/vnd.sealed.csf": {"source":"iana"}, + "application/vnd.sealed.doc": {"source":"iana"}, + "application/vnd.sealed.eml": {"source":"iana"}, + "application/vnd.sealed.mht": {"source":"iana"}, + "application/vnd.sealed.net": {"source":"iana"}, + "application/vnd.sealed.ppt": {"source":"iana"}, + "application/vnd.sealed.tiff": {"source":"iana"}, + "application/vnd.sealed.xls": {"source":"iana"}, + "application/vnd.sealedmedia.softseal.html": {"source":"iana"}, + "application/vnd.sealedmedia.softseal.pdf": {"source":"iana"}, + "application/vnd.seemail": {"source":"iana","extensions":["see"]}, + "application/vnd.seis+json": {"source":"iana","compressible":true}, + "application/vnd.sema": {"source":"iana","extensions":["sema"]}, + "application/vnd.semd": {"source":"iana","extensions":["semd"]}, + "application/vnd.semf": {"source":"iana","extensions":["semf"]}, + "application/vnd.shade-save-file": {"source":"iana"}, + "application/vnd.shana.informed.formdata": {"source":"iana","extensions":["ifm"]}, + "application/vnd.shana.informed.formtemplate": {"source":"iana","extensions":["itp"]}, + "application/vnd.shana.informed.interchange": {"source":"iana","extensions":["iif"]}, + "application/vnd.shana.informed.package": {"source":"iana","extensions":["ipk"]}, + "application/vnd.shootproof+json": {"source":"iana","compressible":true}, + "application/vnd.shopkick+json": {"source":"iana","compressible":true}, + "application/vnd.shp": {"source":"iana"}, + "application/vnd.shx": {"source":"iana"}, + "application/vnd.sigrok.session": {"source":"iana"}, + "application/vnd.simtech-mindmapper": {"source":"iana","extensions":["twd","twds"]}, + "application/vnd.siren+json": {"source":"iana","compressible":true}, + "application/vnd.sketchometry": {"source":"iana"}, + "application/vnd.smaf": {"source":"iana","extensions":["mmf"]}, + "application/vnd.smart.notebook": {"source":"iana"}, + "application/vnd.smart.teacher": {"source":"iana","extensions":["teacher"]}, + "application/vnd.smintio.portals.archive": {"source":"iana"}, + "application/vnd.snesdev-page-table": {"source":"iana"}, + "application/vnd.software602.filler.form+xml": {"source":"iana","compressible":true,"extensions":["fo"]}, + "application/vnd.software602.filler.form-xml-zip": {"source":"iana"}, + "application/vnd.solent.sdkm+xml": {"source":"iana","compressible":true,"extensions":["sdkm","sdkd"]}, + "application/vnd.spotfire.dxp": {"source":"iana","extensions":["dxp"]}, + "application/vnd.spotfire.sfs": {"source":"iana","extensions":["sfs"]}, + "application/vnd.sqlite3": {"source":"iana"}, + "application/vnd.sss-cod": {"source":"iana"}, + "application/vnd.sss-dtf": {"source":"iana"}, + "application/vnd.sss-ntf": {"source":"iana"}, + "application/vnd.stardivision.calc": {"source":"apache","extensions":["sdc"]}, + "application/vnd.stardivision.draw": {"source":"apache","extensions":["sda"]}, + "application/vnd.stardivision.impress": {"source":"apache","extensions":["sdd"]}, + "application/vnd.stardivision.math": {"source":"apache","extensions":["smf"]}, + "application/vnd.stardivision.writer": {"source":"apache","extensions":["sdw","vor"]}, + "application/vnd.stardivision.writer-global": {"source":"apache","extensions":["sgl"]}, + "application/vnd.stepmania.package": {"source":"iana","extensions":["smzip"]}, + "application/vnd.stepmania.stepchart": {"source":"iana","extensions":["sm"]}, + "application/vnd.street-stream": {"source":"iana"}, + "application/vnd.sun.wadl+xml": {"source":"iana","compressible":true,"extensions":["wadl"]}, + "application/vnd.sun.xml.calc": {"source":"apache","extensions":["sxc"]}, + "application/vnd.sun.xml.calc.template": {"source":"apache","extensions":["stc"]}, + "application/vnd.sun.xml.draw": {"source":"apache","extensions":["sxd"]}, + "application/vnd.sun.xml.draw.template": {"source":"apache","extensions":["std"]}, + "application/vnd.sun.xml.impress": {"source":"apache","extensions":["sxi"]}, + "application/vnd.sun.xml.impress.template": {"source":"apache","extensions":["sti"]}, + "application/vnd.sun.xml.math": {"source":"apache","extensions":["sxm"]}, + "application/vnd.sun.xml.writer": {"source":"apache","extensions":["sxw"]}, + "application/vnd.sun.xml.writer.global": {"source":"apache","extensions":["sxg"]}, + "application/vnd.sun.xml.writer.template": {"source":"apache","extensions":["stw"]}, + "application/vnd.sus-calendar": {"source":"iana","extensions":["sus","susp"]}, + "application/vnd.svd": {"source":"iana","extensions":["svd"]}, + "application/vnd.swiftview-ics": {"source":"iana"}, + "application/vnd.sybyl.mol2": {"source":"iana"}, + "application/vnd.sycle+xml": {"source":"iana","compressible":true}, + "application/vnd.syft+json": {"source":"iana","compressible":true}, + "application/vnd.symbian.install": {"source":"apache","extensions":["sis","sisx"]}, + "application/vnd.syncml+xml": {"source":"iana","charset":"UTF-8","compressible":true,"extensions":["xsm"]}, + "application/vnd.syncml.dm+wbxml": {"source":"iana","charset":"UTF-8","extensions":["bdm"]}, + "application/vnd.syncml.dm+xml": {"source":"iana","charset":"UTF-8","compressible":true,"extensions":["xdm"]}, + "application/vnd.syncml.dm.notification": {"source":"iana"}, + "application/vnd.syncml.dmddf+wbxml": {"source":"iana"}, + "application/vnd.syncml.dmddf+xml": {"source":"iana","charset":"UTF-8","compressible":true,"extensions":["ddf"]}, + "application/vnd.syncml.dmtnds+wbxml": {"source":"iana"}, + "application/vnd.syncml.dmtnds+xml": {"source":"iana","charset":"UTF-8","compressible":true}, + "application/vnd.syncml.ds.notification": {"source":"iana"}, + "application/vnd.tableschema+json": {"source":"iana","compressible":true}, + "application/vnd.tao.intent-module-archive": {"source":"iana","extensions":["tao"]}, + "application/vnd.tcpdump.pcap": {"source":"iana","extensions":["pcap","cap","dmp"]}, + "application/vnd.think-cell.ppttc+json": {"source":"iana","compressible":true}, + "application/vnd.tmd.mediaflex.api+xml": {"source":"iana","compressible":true}, + "application/vnd.tml": {"source":"iana"}, + "application/vnd.tmobile-livetv": {"source":"iana","extensions":["tmo"]}, + "application/vnd.tri.onesource": {"source":"iana"}, + "application/vnd.trid.tpt": {"source":"iana","extensions":["tpt"]}, + "application/vnd.triscape.mxs": {"source":"iana","extensions":["mxs"]}, + "application/vnd.trueapp": {"source":"iana","extensions":["tra"]}, + "application/vnd.truedoc": {"source":"iana"}, + "application/vnd.ubisoft.webplayer": {"source":"iana"}, + "application/vnd.ufdl": {"source":"iana","extensions":["ufd","ufdl"]}, + "application/vnd.uic.osdm+json": {"source":"iana","compressible":true}, + "application/vnd.uiq.theme": {"source":"iana","extensions":["utz"]}, + "application/vnd.umajin": {"source":"iana","extensions":["umj"]}, + "application/vnd.unity": {"source":"iana","extensions":["unityweb"]}, + "application/vnd.uoml+xml": {"source":"iana","compressible":true,"extensions":["uoml","uo"]}, + "application/vnd.uplanet.alert": {"source":"iana"}, + "application/vnd.uplanet.alert-wbxml": {"source":"iana"}, + "application/vnd.uplanet.bearer-choice": {"source":"iana"}, + "application/vnd.uplanet.bearer-choice-wbxml": {"source":"iana"}, + "application/vnd.uplanet.cacheop": {"source":"iana"}, + "application/vnd.uplanet.cacheop-wbxml": {"source":"iana"}, + "application/vnd.uplanet.channel": {"source":"iana"}, + "application/vnd.uplanet.channel-wbxml": {"source":"iana"}, + "application/vnd.uplanet.list": {"source":"iana"}, + "application/vnd.uplanet.list-wbxml": {"source":"iana"}, + "application/vnd.uplanet.listcmd": {"source":"iana"}, + "application/vnd.uplanet.listcmd-wbxml": {"source":"iana"}, + "application/vnd.uplanet.signal": {"source":"iana"}, + "application/vnd.uri-map": {"source":"iana"}, + "application/vnd.valve.source.material": {"source":"iana"}, + "application/vnd.vcx": {"source":"iana","extensions":["vcx"]}, + "application/vnd.vd-study": {"source":"iana"}, + "application/vnd.vectorworks": {"source":"iana"}, + "application/vnd.vel+json": {"source":"iana","compressible":true}, + "application/vnd.veraison.tsm-report+cbor": {"source":"iana"}, + "application/vnd.veraison.tsm-report+json": {"source":"iana","compressible":true}, + "application/vnd.verimatrix.vcas": {"source":"iana"}, + "application/vnd.veritone.aion+json": {"source":"iana","compressible":true}, + "application/vnd.veryant.thin": {"source":"iana"}, + "application/vnd.ves.encrypted": {"source":"iana"}, + "application/vnd.vidsoft.vidconference": {"source":"iana"}, + "application/vnd.visio": {"source":"iana","extensions":["vsd","vst","vss","vsw","vsdx","vtx"]}, + "application/vnd.visionary": {"source":"iana","extensions":["vis"]}, + "application/vnd.vividence.scriptfile": {"source":"iana"}, + "application/vnd.vocalshaper.vsp4": {"source":"iana"}, + "application/vnd.vsf": {"source":"iana","extensions":["vsf"]}, + "application/vnd.wap.sic": {"source":"iana"}, + "application/vnd.wap.slc": {"source":"iana"}, + "application/vnd.wap.wbxml": {"source":"iana","charset":"UTF-8","extensions":["wbxml"]}, + "application/vnd.wap.wmlc": {"source":"iana","extensions":["wmlc"]}, + "application/vnd.wap.wmlscriptc": {"source":"iana","extensions":["wmlsc"]}, + "application/vnd.wasmflow.wafl": {"source":"iana"}, + "application/vnd.webturbo": {"source":"iana","extensions":["wtb"]}, + "application/vnd.wfa.dpp": {"source":"iana"}, + "application/vnd.wfa.p2p": {"source":"iana"}, + "application/vnd.wfa.wsc": {"source":"iana"}, + "application/vnd.windows.devicepairing": {"source":"iana"}, + "application/vnd.wmc": {"source":"iana"}, + "application/vnd.wmf.bootstrap": {"source":"iana"}, + "application/vnd.wolfram.mathematica": {"source":"iana"}, + "application/vnd.wolfram.mathematica.package": {"source":"iana"}, + "application/vnd.wolfram.player": {"source":"iana","extensions":["nbp"]}, + "application/vnd.wordlift": {"source":"iana"}, + "application/vnd.wordperfect": {"source":"iana","extensions":["wpd"]}, + "application/vnd.wqd": {"source":"iana","extensions":["wqd"]}, + "application/vnd.wrq-hp3000-labelled": {"source":"iana"}, + "application/vnd.wt.stf": {"source":"iana","extensions":["stf"]}, + "application/vnd.wv.csp+wbxml": {"source":"iana"}, + "application/vnd.wv.csp+xml": {"source":"iana","compressible":true}, + "application/vnd.wv.ssp+xml": {"source":"iana","compressible":true}, + "application/vnd.xacml+json": {"source":"iana","compressible":true}, + "application/vnd.xara": {"source":"iana","extensions":["xar"]}, + "application/vnd.xarin.cpj": {"source":"iana"}, + "application/vnd.xecrets-encrypted": {"source":"iana"}, + "application/vnd.xfdl": {"source":"iana","extensions":["xfdl"]}, + "application/vnd.xfdl.webform": {"source":"iana"}, + "application/vnd.xmi+xml": {"source":"iana","compressible":true}, + "application/vnd.xmpie.cpkg": {"source":"iana"}, + "application/vnd.xmpie.dpkg": {"source":"iana"}, + "application/vnd.xmpie.plan": {"source":"iana"}, + "application/vnd.xmpie.ppkg": {"source":"iana"}, + "application/vnd.xmpie.xlim": {"source":"iana"}, + "application/vnd.yamaha.hv-dic": {"source":"iana","extensions":["hvd"]}, + "application/vnd.yamaha.hv-script": {"source":"iana","extensions":["hvs"]}, + "application/vnd.yamaha.hv-voice": {"source":"iana","extensions":["hvp"]}, + "application/vnd.yamaha.openscoreformat": {"source":"iana","extensions":["osf"]}, + "application/vnd.yamaha.openscoreformat.osfpvg+xml": {"source":"iana","compressible":true,"extensions":["osfpvg"]}, + "application/vnd.yamaha.remote-setup": {"source":"iana"}, + "application/vnd.yamaha.smaf-audio": {"source":"iana","extensions":["saf"]}, + "application/vnd.yamaha.smaf-phrase": {"source":"iana","extensions":["spf"]}, + "application/vnd.yamaha.through-ngn": {"source":"iana"}, + "application/vnd.yamaha.tunnel-udpencap": {"source":"iana"}, + "application/vnd.yaoweme": {"source":"iana"}, + "application/vnd.yellowriver-custom-menu": {"source":"iana","extensions":["cmp"]}, + "application/vnd.zul": {"source":"iana","extensions":["zir","zirz"]}, + "application/vnd.zzazz.deck+xml": {"source":"iana","compressible":true,"extensions":["zaz"]}, + "application/voicexml+xml": {"source":"iana","compressible":true,"extensions":["vxml"]}, + "application/voucher-cms+json": {"source":"iana","compressible":true}, + "application/voucher-jws+json": {"source":"iana","compressible":true}, + "application/vp": {"source":"iana"}, + "application/vp+cose": {"source":"iana"}, + "application/vp+jwt": {"source":"iana"}, + "application/vq-rtcpxr": {"source":"iana"}, + "application/wasm": {"source":"iana","compressible":true,"extensions":["wasm"]}, + "application/watcherinfo+xml": {"source":"iana","compressible":true,"extensions":["wif"]}, + "application/webpush-options+json": {"source":"iana","compressible":true}, + "application/whoispp-query": {"source":"iana"}, + "application/whoispp-response": {"source":"iana"}, + "application/widget": {"source":"iana","extensions":["wgt"]}, + "application/winhlp": {"source":"apache","extensions":["hlp"]}, + "application/wita": {"source":"iana"}, + "application/wordperfect5.1": {"source":"iana"}, + "application/wsdl+xml": {"source":"iana","compressible":true,"extensions":["wsdl"]}, + "application/wspolicy+xml": {"source":"iana","compressible":true,"extensions":["wspolicy"]}, + "application/x-7z-compressed": {"source":"apache","compressible":false,"extensions":["7z"]}, + "application/x-abiword": {"source":"apache","extensions":["abw"]}, + "application/x-ace-compressed": {"source":"apache","extensions":["ace"]}, + "application/x-amf": {"source":"apache"}, + "application/x-apple-diskimage": {"source":"apache","extensions":["dmg"]}, + "application/x-arj": {"compressible":false,"extensions":["arj"]}, + "application/x-authorware-bin": {"source":"apache","extensions":["aab","x32","u32","vox"]}, + "application/x-authorware-map": {"source":"apache","extensions":["aam"]}, + "application/x-authorware-seg": {"source":"apache","extensions":["aas"]}, + "application/x-bcpio": {"source":"apache","extensions":["bcpio"]}, + "application/x-bdoc": {"compressible":false,"extensions":["bdoc"]}, + "application/x-bittorrent": {"source":"apache","extensions":["torrent"]}, + "application/x-blender": {"extensions":["blend"]}, + "application/x-blorb": {"source":"apache","extensions":["blb","blorb"]}, + "application/x-bzip": {"source":"apache","compressible":false,"extensions":["bz"]}, + "application/x-bzip2": {"source":"apache","compressible":false,"extensions":["bz2","boz"]}, + "application/x-cbr": {"source":"apache","extensions":["cbr","cba","cbt","cbz","cb7"]}, + "application/x-cdlink": {"source":"apache","extensions":["vcd"]}, + "application/x-cfs-compressed": {"source":"apache","extensions":["cfs"]}, + "application/x-chat": {"source":"apache","extensions":["chat"]}, + "application/x-chess-pgn": {"source":"apache","extensions":["pgn"]}, + "application/x-chrome-extension": {"extensions":["crx"]}, + "application/x-cocoa": {"source":"nginx","extensions":["cco"]}, + "application/x-compress": {"source":"apache"}, + "application/x-compressed": {"extensions":["rar"]}, + "application/x-conference": {"source":"apache","extensions":["nsc"]}, + "application/x-cpio": {"source":"apache","extensions":["cpio"]}, + "application/x-csh": {"source":"apache","extensions":["csh"]}, + "application/x-deb": {"compressible":false}, + "application/x-debian-package": {"source":"apache","extensions":["deb","udeb"]}, + "application/x-dgc-compressed": {"source":"apache","extensions":["dgc"]}, + "application/x-director": {"source":"apache","extensions":["dir","dcr","dxr","cst","cct","cxt","w3d","fgd","swa"]}, + "application/x-doom": {"source":"apache","extensions":["wad"]}, + "application/x-dtbncx+xml": {"source":"apache","compressible":true,"extensions":["ncx"]}, + "application/x-dtbook+xml": {"source":"apache","compressible":true,"extensions":["dtb"]}, + "application/x-dtbresource+xml": {"source":"apache","compressible":true,"extensions":["res"]}, + "application/x-dvi": {"source":"apache","compressible":false,"extensions":["dvi"]}, + "application/x-envoy": {"source":"apache","extensions":["evy"]}, + "application/x-eva": {"source":"apache","extensions":["eva"]}, + "application/x-font-bdf": {"source":"apache","extensions":["bdf"]}, + "application/x-font-dos": {"source":"apache"}, + "application/x-font-framemaker": {"source":"apache"}, + "application/x-font-ghostscript": {"source":"apache","extensions":["gsf"]}, + "application/x-font-libgrx": {"source":"apache"}, + "application/x-font-linux-psf": {"source":"apache","extensions":["psf"]}, + "application/x-font-pcf": {"source":"apache","extensions":["pcf"]}, + "application/x-font-snf": {"source":"apache","extensions":["snf"]}, + "application/x-font-speedo": {"source":"apache"}, + "application/x-font-sunos-news": {"source":"apache"}, + "application/x-font-type1": {"source":"apache","extensions":["pfa","pfb","pfm","afm"]}, + "application/x-font-vfont": {"source":"apache"}, + "application/x-freearc": {"source":"apache","extensions":["arc"]}, + "application/x-futuresplash": {"source":"apache","extensions":["spl"]}, + "application/x-gca-compressed": {"source":"apache","extensions":["gca"]}, + "application/x-glulx": {"source":"apache","extensions":["ulx"]}, + "application/x-gnumeric": {"source":"apache","extensions":["gnumeric"]}, + "application/x-gramps-xml": {"source":"apache","extensions":["gramps"]}, + "application/x-gtar": {"source":"apache","extensions":["gtar"]}, + "application/x-gzip": {"source":"apache"}, + "application/x-hdf": {"source":"apache","extensions":["hdf"]}, + "application/x-httpd-php": {"compressible":true,"extensions":["php"]}, + "application/x-install-instructions": {"source":"apache","extensions":["install"]}, + "application/x-ipynb+json": {"compressible":true,"extensions":["ipynb"]}, + "application/x-iso9660-image": {"source":"apache","extensions":["iso"]}, + "application/x-iwork-keynote-sffkey": {"extensions":["key"]}, + "application/x-iwork-numbers-sffnumbers": {"extensions":["numbers"]}, + "application/x-iwork-pages-sffpages": {"extensions":["pages"]}, + "application/x-java-archive-diff": {"source":"nginx","extensions":["jardiff"]}, + "application/x-java-jnlp-file": {"source":"apache","compressible":false,"extensions":["jnlp"]}, + "application/x-javascript": {"compressible":true}, + "application/x-keepass2": {"extensions":["kdbx"]}, + "application/x-latex": {"source":"apache","compressible":false,"extensions":["latex"]}, + "application/x-lua-bytecode": {"extensions":["luac"]}, + "application/x-lzh-compressed": {"source":"apache","extensions":["lzh","lha"]}, + "application/x-makeself": {"source":"nginx","extensions":["run"]}, + "application/x-mie": {"source":"apache","extensions":["mie"]}, + "application/x-mobipocket-ebook": {"source":"apache","extensions":["prc","mobi"]}, + "application/x-mpegurl": {"compressible":false}, + "application/x-ms-application": {"source":"apache","extensions":["application"]}, + "application/x-ms-shortcut": {"source":"apache","extensions":["lnk"]}, + "application/x-ms-wmd": {"source":"apache","extensions":["wmd"]}, + "application/x-ms-wmz": {"source":"apache","extensions":["wmz"]}, + "application/x-ms-xbap": {"source":"apache","extensions":["xbap"]}, + "application/x-msaccess": {"source":"apache","extensions":["mdb"]}, + "application/x-msbinder": {"source":"apache","extensions":["obd"]}, + "application/x-mscardfile": {"source":"apache","extensions":["crd"]}, + "application/x-msclip": {"source":"apache","extensions":["clp"]}, + "application/x-msdos-program": {"extensions":["exe"]}, + "application/x-msdownload": {"source":"apache","extensions":["exe","dll","com","bat","msi"]}, + "application/x-msmediaview": {"source":"apache","extensions":["mvb","m13","m14"]}, + "application/x-msmetafile": {"source":"apache","extensions":["wmf","wmz","emf","emz"]}, + "application/x-msmoney": {"source":"apache","extensions":["mny"]}, + "application/x-mspublisher": {"source":"apache","extensions":["pub"]}, + "application/x-msschedule": {"source":"apache","extensions":["scd"]}, + "application/x-msterminal": {"source":"apache","extensions":["trm"]}, + "application/x-mswrite": {"source":"apache","extensions":["wri"]}, + "application/x-netcdf": {"source":"apache","extensions":["nc","cdf"]}, + "application/x-ns-proxy-autoconfig": {"compressible":true,"extensions":["pac"]}, + "application/x-nzb": {"source":"apache","extensions":["nzb"]}, + "application/x-perl": {"source":"nginx","extensions":["pl","pm"]}, + "application/x-pilot": {"source":"nginx","extensions":["prc","pdb"]}, + "application/x-pkcs12": {"source":"apache","compressible":false,"extensions":["p12","pfx"]}, + "application/x-pkcs7-certificates": {"source":"apache","extensions":["p7b","spc"]}, + "application/x-pkcs7-certreqresp": {"source":"apache","extensions":["p7r"]}, + "application/x-pki-message": {"source":"iana"}, + "application/x-rar-compressed": {"source":"apache","compressible":false,"extensions":["rar"]}, + "application/x-redhat-package-manager": {"source":"nginx","extensions":["rpm"]}, + "application/x-research-info-systems": {"source":"apache","extensions":["ris"]}, + "application/x-sea": {"source":"nginx","extensions":["sea"]}, + "application/x-sh": {"source":"apache","compressible":true,"extensions":["sh"]}, + "application/x-shar": {"source":"apache","extensions":["shar"]}, + "application/x-shockwave-flash": {"source":"apache","compressible":false,"extensions":["swf"]}, + "application/x-silverlight-app": {"source":"apache","extensions":["xap"]}, + "application/x-sql": {"source":"apache","extensions":["sql"]}, + "application/x-stuffit": {"source":"apache","compressible":false,"extensions":["sit"]}, + "application/x-stuffitx": {"source":"apache","extensions":["sitx"]}, + "application/x-subrip": {"source":"apache","extensions":["srt"]}, + "application/x-sv4cpio": {"source":"apache","extensions":["sv4cpio"]}, + "application/x-sv4crc": {"source":"apache","extensions":["sv4crc"]}, + "application/x-t3vm-image": {"source":"apache","extensions":["t3"]}, + "application/x-tads": {"source":"apache","extensions":["gam"]}, + "application/x-tar": {"source":"apache","compressible":true,"extensions":["tar"]}, + "application/x-tcl": {"source":"apache","extensions":["tcl","tk"]}, + "application/x-tex": {"source":"apache","extensions":["tex"]}, + "application/x-tex-tfm": {"source":"apache","extensions":["tfm"]}, + "application/x-texinfo": {"source":"apache","extensions":["texinfo","texi"]}, + "application/x-tgif": {"source":"apache","extensions":["obj"]}, + "application/x-ustar": {"source":"apache","extensions":["ustar"]}, + "application/x-virtualbox-hdd": {"compressible":true,"extensions":["hdd"]}, + "application/x-virtualbox-ova": {"compressible":true,"extensions":["ova"]}, + "application/x-virtualbox-ovf": {"compressible":true,"extensions":["ovf"]}, + "application/x-virtualbox-vbox": {"compressible":true,"extensions":["vbox"]}, + "application/x-virtualbox-vbox-extpack": {"compressible":false,"extensions":["vbox-extpack"]}, + "application/x-virtualbox-vdi": {"compressible":true,"extensions":["vdi"]}, + "application/x-virtualbox-vhd": {"compressible":true,"extensions":["vhd"]}, + "application/x-virtualbox-vmdk": {"compressible":true,"extensions":["vmdk"]}, + "application/x-wais-source": {"source":"apache","extensions":["src"]}, + "application/x-web-app-manifest+json": {"compressible":true,"extensions":["webapp"]}, + "application/x-www-form-urlencoded": {"source":"iana","compressible":true}, + "application/x-x509-ca-cert": {"source":"iana","extensions":["der","crt","pem"]}, + "application/x-x509-ca-ra-cert": {"source":"iana"}, + "application/x-x509-next-ca-cert": {"source":"iana"}, + "application/x-xfig": {"source":"apache","extensions":["fig"]}, + "application/x-xliff+xml": {"source":"apache","compressible":true,"extensions":["xlf"]}, + "application/x-xpinstall": {"source":"apache","compressible":false,"extensions":["xpi"]}, + "application/x-xz": {"source":"apache","extensions":["xz"]}, + "application/x-zip-compressed": {"extensions":["zip"]}, + "application/x-zmachine": {"source":"apache","extensions":["z1","z2","z3","z4","z5","z6","z7","z8"]}, + "application/x400-bp": {"source":"iana"}, + "application/xacml+xml": {"source":"iana","compressible":true}, + "application/xaml+xml": {"source":"apache","compressible":true,"extensions":["xaml"]}, + "application/xcap-att+xml": {"source":"iana","compressible":true,"extensions":["xav"]}, + "application/xcap-caps+xml": {"source":"iana","compressible":true,"extensions":["xca"]}, + "application/xcap-diff+xml": {"source":"iana","compressible":true,"extensions":["xdf"]}, + "application/xcap-el+xml": {"source":"iana","compressible":true,"extensions":["xel"]}, + "application/xcap-error+xml": {"source":"iana","compressible":true}, + "application/xcap-ns+xml": {"source":"iana","compressible":true,"extensions":["xns"]}, + "application/xcon-conference-info+xml": {"source":"iana","compressible":true}, + "application/xcon-conference-info-diff+xml": {"source":"iana","compressible":true}, + "application/xenc+xml": {"source":"iana","compressible":true,"extensions":["xenc"]}, + "application/xfdf": {"source":"iana","extensions":["xfdf"]}, + "application/xhtml+xml": {"source":"iana","compressible":true,"extensions":["xhtml","xht"]}, + "application/xhtml-voice+xml": {"source":"apache","compressible":true}, + "application/xliff+xml": {"source":"iana","compressible":true,"extensions":["xlf"]}, + "application/xml": {"source":"iana","compressible":true,"extensions":["xml","xsl","xsd","rng"]}, + "application/xml-dtd": {"source":"iana","compressible":true,"extensions":["dtd"]}, + "application/xml-external-parsed-entity": {"source":"iana"}, + "application/xml-patch+xml": {"source":"iana","compressible":true}, + "application/xmpp+xml": {"source":"iana","compressible":true}, + "application/xop+xml": {"source":"iana","compressible":true,"extensions":["xop"]}, + "application/xproc+xml": {"source":"apache","compressible":true,"extensions":["xpl"]}, + "application/xslt+xml": {"source":"iana","compressible":true,"extensions":["xsl","xslt"]}, + "application/xspf+xml": {"source":"apache","compressible":true,"extensions":["xspf"]}, + "application/xv+xml": {"source":"iana","compressible":true,"extensions":["mxml","xhvml","xvml","xvm"]}, + "application/yaml": {"source":"iana"}, + "application/yang": {"source":"iana","extensions":["yang"]}, + "application/yang-data+cbor": {"source":"iana"}, + "application/yang-data+json": {"source":"iana","compressible":true}, + "application/yang-data+xml": {"source":"iana","compressible":true}, + "application/yang-patch+json": {"source":"iana","compressible":true}, + "application/yang-patch+xml": {"source":"iana","compressible":true}, + "application/yang-sid+json": {"source":"iana","compressible":true}, + "application/yin+xml": {"source":"iana","compressible":true,"extensions":["yin"]}, + "application/zip": {"source":"iana","compressible":false,"extensions":["zip"]}, + "application/zip+dotlottie": {"extensions":["lottie"]}, + "application/zlib": {"source":"iana"}, + "application/zstd": {"source":"iana"}, + "audio/1d-interleaved-parityfec": {"source":"iana"}, + "audio/32kadpcm": {"source":"iana"}, + "audio/3gpp": {"source":"iana","compressible":false,"extensions":["3gpp"]}, + "audio/3gpp2": {"source":"iana"}, + "audio/aac": {"source":"iana","extensions":["adts","aac"]}, + "audio/ac3": {"source":"iana"}, + "audio/adpcm": {"source":"apache","extensions":["adp"]}, + "audio/amr": {"source":"iana","extensions":["amr"]}, + "audio/amr-wb": {"source":"iana"}, + "audio/amr-wb+": {"source":"iana"}, + "audio/aptx": {"source":"iana"}, + "audio/asc": {"source":"iana"}, + "audio/atrac-advanced-lossless": {"source":"iana"}, + "audio/atrac-x": {"source":"iana"}, + "audio/atrac3": {"source":"iana"}, + "audio/basic": {"source":"iana","compressible":false,"extensions":["au","snd"]}, + "audio/bv16": {"source":"iana"}, + "audio/bv32": {"source":"iana"}, + "audio/clearmode": {"source":"iana"}, + "audio/cn": {"source":"iana"}, + "audio/dat12": {"source":"iana"}, + "audio/dls": {"source":"iana"}, + "audio/dsr-es201108": {"source":"iana"}, + "audio/dsr-es202050": {"source":"iana"}, + "audio/dsr-es202211": {"source":"iana"}, + "audio/dsr-es202212": {"source":"iana"}, + "audio/dv": {"source":"iana"}, + "audio/dvi4": {"source":"iana"}, + "audio/eac3": {"source":"iana"}, + "audio/encaprtp": {"source":"iana"}, + "audio/evrc": {"source":"iana"}, + "audio/evrc-qcp": {"source":"iana"}, + "audio/evrc0": {"source":"iana"}, + "audio/evrc1": {"source":"iana"}, + "audio/evrcb": {"source":"iana"}, + "audio/evrcb0": {"source":"iana"}, + "audio/evrcb1": {"source":"iana"}, + "audio/evrcnw": {"source":"iana"}, + "audio/evrcnw0": {"source":"iana"}, + "audio/evrcnw1": {"source":"iana"}, + "audio/evrcwb": {"source":"iana"}, + "audio/evrcwb0": {"source":"iana"}, + "audio/evrcwb1": {"source":"iana"}, + "audio/evs": {"source":"iana"}, + "audio/flac": {"source":"iana"}, + "audio/flexfec": {"source":"iana"}, + "audio/fwdred": {"source":"iana"}, + "audio/g711-0": {"source":"iana"}, + "audio/g719": {"source":"iana"}, + "audio/g722": {"source":"iana"}, + "audio/g7221": {"source":"iana"}, + "audio/g723": {"source":"iana"}, + "audio/g726-16": {"source":"iana"}, + "audio/g726-24": {"source":"iana"}, + "audio/g726-32": {"source":"iana"}, + "audio/g726-40": {"source":"iana"}, + "audio/g728": {"source":"iana"}, + "audio/g729": {"source":"iana"}, + "audio/g7291": {"source":"iana"}, + "audio/g729d": {"source":"iana"}, + "audio/g729e": {"source":"iana"}, + "audio/gsm": {"source":"iana"}, + "audio/gsm-efr": {"source":"iana"}, + "audio/gsm-hr-08": {"source":"iana"}, + "audio/ilbc": {"source":"iana"}, + "audio/ip-mr_v2.5": {"source":"iana"}, + "audio/isac": {"source":"apache"}, + "audio/l16": {"source":"iana"}, + "audio/l20": {"source":"iana"}, + "audio/l24": {"source":"iana","compressible":false}, + "audio/l8": {"source":"iana"}, + "audio/lpc": {"source":"iana"}, + "audio/matroska": {"source":"iana"}, + "audio/melp": {"source":"iana"}, + "audio/melp1200": {"source":"iana"}, + "audio/melp2400": {"source":"iana"}, + "audio/melp600": {"source":"iana"}, + "audio/mhas": {"source":"iana"}, + "audio/midi": {"source":"apache","extensions":["mid","midi","kar","rmi"]}, + "audio/midi-clip": {"source":"iana"}, + "audio/mobile-xmf": {"source":"iana","extensions":["mxmf"]}, + "audio/mp3": {"compressible":false,"extensions":["mp3"]}, + "audio/mp4": {"source":"iana","compressible":false,"extensions":["m4a","mp4a","m4b"]}, + "audio/mp4a-latm": {"source":"iana"}, + "audio/mpa": {"source":"iana"}, + "audio/mpa-robust": {"source":"iana"}, + "audio/mpeg": {"source":"iana","compressible":false,"extensions":["mpga","mp2","mp2a","mp3","m2a","m3a"]}, + "audio/mpeg4-generic": {"source":"iana"}, + "audio/musepack": {"source":"apache"}, + "audio/ogg": {"source":"iana","compressible":false,"extensions":["oga","ogg","spx","opus"]}, + "audio/opus": {"source":"iana"}, + "audio/parityfec": {"source":"iana"}, + "audio/pcma": {"source":"iana"}, + "audio/pcma-wb": {"source":"iana"}, + "audio/pcmu": {"source":"iana"}, + "audio/pcmu-wb": {"source":"iana"}, + "audio/prs.sid": {"source":"iana"}, + "audio/qcelp": {"source":"iana"}, + "audio/raptorfec": {"source":"iana"}, + "audio/red": {"source":"iana"}, + "audio/rtp-enc-aescm128": {"source":"iana"}, + "audio/rtp-midi": {"source":"iana"}, + "audio/rtploopback": {"source":"iana"}, + "audio/rtx": {"source":"iana"}, + "audio/s3m": {"source":"apache","extensions":["s3m"]}, + "audio/scip": {"source":"iana"}, + "audio/silk": {"source":"apache","extensions":["sil"]}, + "audio/smv": {"source":"iana"}, + "audio/smv-qcp": {"source":"iana"}, + "audio/smv0": {"source":"iana"}, + "audio/sofa": {"source":"iana"}, + "audio/sp-midi": {"source":"iana"}, + "audio/speex": {"source":"iana"}, + "audio/t140c": {"source":"iana"}, + "audio/t38": {"source":"iana"}, + "audio/telephone-event": {"source":"iana"}, + "audio/tetra_acelp": {"source":"iana"}, + "audio/tetra_acelp_bb": {"source":"iana"}, + "audio/tone": {"source":"iana"}, + "audio/tsvcis": {"source":"iana"}, + "audio/uemclip": {"source":"iana"}, + "audio/ulpfec": {"source":"iana"}, + "audio/usac": {"source":"iana"}, + "audio/vdvi": {"source":"iana"}, + "audio/vmr-wb": {"source":"iana"}, + "audio/vnd.3gpp.iufp": {"source":"iana"}, + "audio/vnd.4sb": {"source":"iana"}, + "audio/vnd.audiokoz": {"source":"iana"}, + "audio/vnd.celp": {"source":"iana"}, + "audio/vnd.cisco.nse": {"source":"iana"}, + "audio/vnd.cmles.radio-events": {"source":"iana"}, + "audio/vnd.cns.anp1": {"source":"iana"}, + "audio/vnd.cns.inf1": {"source":"iana"}, + "audio/vnd.dece.audio": {"source":"iana","extensions":["uva","uvva"]}, + "audio/vnd.digital-winds": {"source":"iana","extensions":["eol"]}, + "audio/vnd.dlna.adts": {"source":"iana"}, + "audio/vnd.dolby.heaac.1": {"source":"iana"}, + "audio/vnd.dolby.heaac.2": {"source":"iana"}, + "audio/vnd.dolby.mlp": {"source":"iana"}, + "audio/vnd.dolby.mps": {"source":"iana"}, + "audio/vnd.dolby.pl2": {"source":"iana"}, + "audio/vnd.dolby.pl2x": {"source":"iana"}, + "audio/vnd.dolby.pl2z": {"source":"iana"}, + "audio/vnd.dolby.pulse.1": {"source":"iana"}, + "audio/vnd.dra": {"source":"iana","extensions":["dra"]}, + "audio/vnd.dts": {"source":"iana","extensions":["dts"]}, + "audio/vnd.dts.hd": {"source":"iana","extensions":["dtshd"]}, + "audio/vnd.dts.uhd": {"source":"iana"}, + "audio/vnd.dvb.file": {"source":"iana"}, + "audio/vnd.everad.plj": {"source":"iana"}, + "audio/vnd.hns.audio": {"source":"iana"}, + "audio/vnd.lucent.voice": {"source":"iana","extensions":["lvp"]}, + "audio/vnd.ms-playready.media.pya": {"source":"iana","extensions":["pya"]}, + "audio/vnd.nokia.mobile-xmf": {"source":"iana"}, + "audio/vnd.nortel.vbk": {"source":"iana"}, + "audio/vnd.nuera.ecelp4800": {"source":"iana","extensions":["ecelp4800"]}, + "audio/vnd.nuera.ecelp7470": {"source":"iana","extensions":["ecelp7470"]}, + "audio/vnd.nuera.ecelp9600": {"source":"iana","extensions":["ecelp9600"]}, + "audio/vnd.octel.sbc": {"source":"iana"}, + "audio/vnd.presonus.multitrack": {"source":"iana"}, + "audio/vnd.qcelp": {"source":"apache"}, + "audio/vnd.rhetorex.32kadpcm": {"source":"iana"}, + "audio/vnd.rip": {"source":"iana","extensions":["rip"]}, + "audio/vnd.rn-realaudio": {"compressible":false}, + "audio/vnd.sealedmedia.softseal.mpeg": {"source":"iana"}, + "audio/vnd.vmx.cvsd": {"source":"iana"}, + "audio/vnd.wave": {"compressible":false}, + "audio/vorbis": {"source":"iana","compressible":false}, + "audio/vorbis-config": {"source":"iana"}, + "audio/wav": {"compressible":false,"extensions":["wav"]}, + "audio/wave": {"compressible":false,"extensions":["wav"]}, + "audio/webm": {"source":"apache","compressible":false,"extensions":["weba"]}, + "audio/x-aac": {"source":"apache","compressible":false,"extensions":["aac"]}, + "audio/x-aiff": {"source":"apache","extensions":["aif","aiff","aifc"]}, + "audio/x-caf": {"source":"apache","compressible":false,"extensions":["caf"]}, + "audio/x-flac": {"source":"apache","extensions":["flac"]}, + "audio/x-m4a": {"source":"nginx","extensions":["m4a"]}, + "audio/x-matroska": {"source":"apache","extensions":["mka"]}, + "audio/x-mpegurl": {"source":"apache","extensions":["m3u"]}, + "audio/x-ms-wax": {"source":"apache","extensions":["wax"]}, + "audio/x-ms-wma": {"source":"apache","extensions":["wma"]}, + "audio/x-pn-realaudio": {"source":"apache","extensions":["ram","ra"]}, + "audio/x-pn-realaudio-plugin": {"source":"apache","extensions":["rmp"]}, + "audio/x-realaudio": {"source":"nginx","extensions":["ra"]}, + "audio/x-tta": {"source":"apache"}, + "audio/x-wav": {"source":"apache","extensions":["wav"]}, + "audio/xm": {"source":"apache","extensions":["xm"]}, + "chemical/x-cdx": {"source":"apache","extensions":["cdx"]}, + "chemical/x-cif": {"source":"apache","extensions":["cif"]}, + "chemical/x-cmdf": {"source":"apache","extensions":["cmdf"]}, + "chemical/x-cml": {"source":"apache","extensions":["cml"]}, + "chemical/x-csml": {"source":"apache","extensions":["csml"]}, + "chemical/x-pdb": {"source":"apache"}, + "chemical/x-xyz": {"source":"apache","extensions":["xyz"]}, + "font/collection": {"source":"iana","extensions":["ttc"]}, + "font/otf": {"source":"iana","compressible":true,"extensions":["otf"]}, + "font/sfnt": {"source":"iana"}, + "font/ttf": {"source":"iana","compressible":true,"extensions":["ttf"]}, + "font/woff": {"source":"iana","extensions":["woff"]}, + "font/woff2": {"source":"iana","extensions":["woff2"]}, + "image/aces": {"source":"iana","extensions":["exr"]}, + "image/apng": {"source":"iana","compressible":false,"extensions":["apng"]}, + "image/avci": {"source":"iana","extensions":["avci"]}, + "image/avcs": {"source":"iana","extensions":["avcs"]}, + "image/avif": {"source":"iana","compressible":false,"extensions":["avif"]}, + "image/bmp": {"source":"iana","compressible":true,"extensions":["bmp","dib"]}, + "image/cgm": {"source":"iana","extensions":["cgm"]}, + "image/dicom-rle": {"source":"iana","extensions":["drle"]}, + "image/dpx": {"source":"iana","extensions":["dpx"]}, + "image/emf": {"source":"iana","extensions":["emf"]}, + "image/fits": {"source":"iana","extensions":["fits"]}, + "image/g3fax": {"source":"iana","extensions":["g3"]}, + "image/gif": {"source":"iana","compressible":false,"extensions":["gif"]}, + "image/heic": {"source":"iana","extensions":["heic"]}, + "image/heic-sequence": {"source":"iana","extensions":["heics"]}, + "image/heif": {"source":"iana","extensions":["heif"]}, + "image/heif-sequence": {"source":"iana","extensions":["heifs"]}, + "image/hej2k": {"source":"iana","extensions":["hej2"]}, + "image/ief": {"source":"iana","extensions":["ief"]}, + "image/j2c": {"source":"iana"}, + "image/jaii": {"source":"iana","extensions":["jaii"]}, + "image/jais": {"source":"iana","extensions":["jais"]}, + "image/jls": {"source":"iana","extensions":["jls"]}, + "image/jp2": {"source":"iana","compressible":false,"extensions":["jp2","jpg2"]}, + "image/jpeg": {"source":"iana","compressible":false,"extensions":["jpg","jpeg","jpe"]}, + "image/jph": {"source":"iana","extensions":["jph"]}, + "image/jphc": {"source":"iana","extensions":["jhc"]}, + "image/jpm": {"source":"iana","compressible":false,"extensions":["jpm","jpgm"]}, + "image/jpx": {"source":"iana","compressible":false,"extensions":["jpx","jpf"]}, + "image/jxl": {"source":"iana","extensions":["jxl"]}, + "image/jxr": {"source":"iana","extensions":["jxr"]}, + "image/jxra": {"source":"iana","extensions":["jxra"]}, + "image/jxrs": {"source":"iana","extensions":["jxrs"]}, + "image/jxs": {"source":"iana","extensions":["jxs"]}, + "image/jxsc": {"source":"iana","extensions":["jxsc"]}, + "image/jxsi": {"source":"iana","extensions":["jxsi"]}, + "image/jxss": {"source":"iana","extensions":["jxss"]}, + "image/ktx": {"source":"iana","extensions":["ktx"]}, + "image/ktx2": {"source":"iana","extensions":["ktx2"]}, + "image/naplps": {"source":"iana"}, + "image/pjpeg": {"compressible":false,"extensions":["jfif"]}, + "image/png": {"source":"iana","compressible":false,"extensions":["png"]}, + "image/prs.btif": {"source":"iana","extensions":["btif","btf"]}, + "image/prs.pti": {"source":"iana","extensions":["pti"]}, + "image/pwg-raster": {"source":"iana"}, + "image/sgi": {"source":"apache","extensions":["sgi"]}, + "image/svg+xml": {"source":"iana","compressible":true,"extensions":["svg","svgz"]}, + "image/t38": {"source":"iana","extensions":["t38"]}, + "image/tiff": {"source":"iana","compressible":false,"extensions":["tif","tiff"]}, + "image/tiff-fx": {"source":"iana","extensions":["tfx"]}, + "image/vnd.adobe.photoshop": {"source":"iana","compressible":true,"extensions":["psd"]}, + "image/vnd.airzip.accelerator.azv": {"source":"iana","extensions":["azv"]}, + "image/vnd.clip": {"source":"iana"}, + "image/vnd.cns.inf2": {"source":"iana"}, + "image/vnd.dece.graphic": {"source":"iana","extensions":["uvi","uvvi","uvg","uvvg"]}, + "image/vnd.djvu": {"source":"iana","extensions":["djvu","djv"]}, + "image/vnd.dvb.subtitle": {"source":"iana","extensions":["sub"]}, + "image/vnd.dwg": {"source":"iana","extensions":["dwg"]}, + "image/vnd.dxf": {"source":"iana","extensions":["dxf"]}, + "image/vnd.fastbidsheet": {"source":"iana","extensions":["fbs"]}, + "image/vnd.fpx": {"source":"iana","extensions":["fpx"]}, + "image/vnd.fst": {"source":"iana","extensions":["fst"]}, + "image/vnd.fujixerox.edmics-mmr": {"source":"iana","extensions":["mmr"]}, + "image/vnd.fujixerox.edmics-rlc": {"source":"iana","extensions":["rlc"]}, + "image/vnd.globalgraphics.pgb": {"source":"iana"}, + "image/vnd.microsoft.icon": {"source":"iana","compressible":true,"extensions":["ico"]}, + "image/vnd.mix": {"source":"iana"}, + "image/vnd.mozilla.apng": {"source":"iana"}, + "image/vnd.ms-dds": {"compressible":true,"extensions":["dds"]}, + "image/vnd.ms-modi": {"source":"iana","extensions":["mdi"]}, + "image/vnd.ms-photo": {"source":"apache","extensions":["wdp"]}, + "image/vnd.net-fpx": {"source":"iana","extensions":["npx"]}, + "image/vnd.pco.b16": {"source":"iana","extensions":["b16"]}, + "image/vnd.radiance": {"source":"iana"}, + "image/vnd.sealed.png": {"source":"iana"}, + "image/vnd.sealedmedia.softseal.gif": {"source":"iana"}, + "image/vnd.sealedmedia.softseal.jpg": {"source":"iana"}, + "image/vnd.svf": {"source":"iana"}, + "image/vnd.tencent.tap": {"source":"iana","extensions":["tap"]}, + "image/vnd.valve.source.texture": {"source":"iana","extensions":["vtf"]}, + "image/vnd.wap.wbmp": {"source":"iana","extensions":["wbmp"]}, + "image/vnd.xiff": {"source":"iana","extensions":["xif"]}, + "image/vnd.zbrush.pcx": {"source":"iana","extensions":["pcx"]}, + "image/webp": {"source":"iana","extensions":["webp"]}, + "image/wmf": {"source":"iana","extensions":["wmf"]}, + "image/x-3ds": {"source":"apache","extensions":["3ds"]}, + "image/x-adobe-dng": {"extensions":["dng"]}, + "image/x-cmu-raster": {"source":"apache","extensions":["ras"]}, + "image/x-cmx": {"source":"apache","extensions":["cmx"]}, + "image/x-emf": {"source":"iana"}, + "image/x-freehand": {"source":"apache","extensions":["fh","fhc","fh4","fh5","fh7"]}, + "image/x-icon": {"source":"apache","compressible":true,"extensions":["ico"]}, + "image/x-jng": {"source":"nginx","extensions":["jng"]}, + "image/x-mrsid-image": {"source":"apache","extensions":["sid"]}, + "image/x-ms-bmp": {"source":"nginx","compressible":true,"extensions":["bmp"]}, + "image/x-pcx": {"source":"apache","extensions":["pcx"]}, + "image/x-pict": {"source":"apache","extensions":["pic","pct"]}, + "image/x-portable-anymap": {"source":"apache","extensions":["pnm"]}, + "image/x-portable-bitmap": {"source":"apache","extensions":["pbm"]}, + "image/x-portable-graymap": {"source":"apache","extensions":["pgm"]}, + "image/x-portable-pixmap": {"source":"apache","extensions":["ppm"]}, + "image/x-rgb": {"source":"apache","extensions":["rgb"]}, + "image/x-tga": {"source":"apache","extensions":["tga"]}, + "image/x-wmf": {"source":"iana"}, + "image/x-xbitmap": {"source":"apache","extensions":["xbm"]}, + "image/x-xcf": {"compressible":false}, + "image/x-xpixmap": {"source":"apache","extensions":["xpm"]}, + "image/x-xwindowdump": {"source":"apache","extensions":["xwd"]}, + "message/bhttp": {"source":"iana"}, + "message/cpim": {"source":"iana"}, + "message/delivery-status": {"source":"iana"}, + "message/disposition-notification": {"source":"iana","extensions":["disposition-notification"]}, + "message/external-body": {"source":"iana"}, + "message/feedback-report": {"source":"iana"}, + "message/global": {"source":"iana","extensions":["u8msg"]}, + "message/global-delivery-status": {"source":"iana","extensions":["u8dsn"]}, + "message/global-disposition-notification": {"source":"iana","extensions":["u8mdn"]}, + "message/global-headers": {"source":"iana","extensions":["u8hdr"]}, + "message/http": {"source":"iana","compressible":false}, + "message/imdn+xml": {"source":"iana","compressible":true}, + "message/mls": {"source":"iana"}, + "message/news": {"source":"apache"}, + "message/ohttp-req": {"source":"iana"}, + "message/ohttp-res": {"source":"iana"}, + "message/partial": {"source":"iana","compressible":false}, + "message/rfc822": {"source":"iana","compressible":true,"extensions":["eml","mime","mht","mhtml"]}, + "message/s-http": {"source":"apache"}, + "message/sip": {"source":"iana"}, + "message/sipfrag": {"source":"iana"}, + "message/tracking-status": {"source":"iana"}, + "message/vnd.si.simp": {"source":"apache"}, + "message/vnd.wfa.wsc": {"source":"iana","extensions":["wsc"]}, + "model/3mf": {"source":"iana","extensions":["3mf"]}, + "model/e57": {"source":"iana"}, + "model/gltf+json": {"source":"iana","compressible":true,"extensions":["gltf"]}, + "model/gltf-binary": {"source":"iana","compressible":true,"extensions":["glb"]}, + "model/iges": {"source":"iana","compressible":false,"extensions":["igs","iges"]}, + "model/jt": {"source":"iana","extensions":["jt"]}, + "model/mesh": {"source":"iana","compressible":false,"extensions":["msh","mesh","silo"]}, + "model/mtl": {"source":"iana","extensions":["mtl"]}, + "model/obj": {"source":"iana","extensions":["obj"]}, + "model/prc": {"source":"iana","extensions":["prc"]}, + "model/step": {"source":"iana","extensions":["step","stp","stpnc","p21","210"]}, + "model/step+xml": {"source":"iana","compressible":true,"extensions":["stpx"]}, + "model/step+zip": {"source":"iana","compressible":false,"extensions":["stpz"]}, + "model/step-xml+zip": {"source":"iana","compressible":false,"extensions":["stpxz"]}, + "model/stl": {"source":"iana","extensions":["stl"]}, + "model/u3d": {"source":"iana","extensions":["u3d"]}, + "model/vnd.bary": {"source":"iana","extensions":["bary"]}, + "model/vnd.cld": {"source":"iana","extensions":["cld"]}, + "model/vnd.collada+xml": {"source":"iana","compressible":true,"extensions":["dae"]}, + "model/vnd.dwf": {"source":"iana","extensions":["dwf"]}, + "model/vnd.flatland.3dml": {"source":"iana"}, + "model/vnd.gdl": {"source":"iana","extensions":["gdl"]}, + "model/vnd.gs-gdl": {"source":"apache"}, + "model/vnd.gs.gdl": {"source":"iana"}, + "model/vnd.gtw": {"source":"iana","extensions":["gtw"]}, + "model/vnd.moml+xml": {"source":"iana","compressible":true}, + "model/vnd.mts": {"source":"iana","extensions":["mts"]}, + "model/vnd.opengex": {"source":"iana","extensions":["ogex"]}, + "model/vnd.parasolid.transmit.binary": {"source":"iana","extensions":["x_b"]}, + "model/vnd.parasolid.transmit.text": {"source":"iana","extensions":["x_t"]}, + "model/vnd.pytha.pyox": {"source":"iana","extensions":["pyo","pyox"]}, + "model/vnd.rosette.annotated-data-model": {"source":"iana"}, + "model/vnd.sap.vds": {"source":"iana","extensions":["vds"]}, + "model/vnd.usda": {"source":"iana","extensions":["usda"]}, + "model/vnd.usdz+zip": {"source":"iana","compressible":false,"extensions":["usdz"]}, + "model/vnd.valve.source.compiled-map": {"source":"iana","extensions":["bsp"]}, + "model/vnd.vtu": {"source":"iana","extensions":["vtu"]}, + "model/vrml": {"source":"iana","compressible":false,"extensions":["wrl","vrml"]}, + "model/x3d+binary": {"source":"apache","compressible":false,"extensions":["x3db","x3dbz"]}, + "model/x3d+fastinfoset": {"source":"iana","extensions":["x3db"]}, + "model/x3d+vrml": {"source":"apache","compressible":false,"extensions":["x3dv","x3dvz"]}, + "model/x3d+xml": {"source":"iana","compressible":true,"extensions":["x3d","x3dz"]}, + "model/x3d-vrml": {"source":"iana","extensions":["x3dv"]}, + "multipart/alternative": {"source":"iana","compressible":false}, + "multipart/appledouble": {"source":"iana"}, + "multipart/byteranges": {"source":"iana"}, + "multipart/digest": {"source":"iana"}, + "multipart/encrypted": {"source":"iana","compressible":false}, + "multipart/form-data": {"source":"iana","compressible":false}, + "multipart/header-set": {"source":"iana"}, + "multipart/mixed": {"source":"iana"}, + "multipart/multilingual": {"source":"iana"}, + "multipart/parallel": {"source":"iana"}, + "multipart/related": {"source":"iana","compressible":false}, + "multipart/report": {"source":"iana"}, + "multipart/signed": {"source":"iana","compressible":false}, + "multipart/vnd.bint.med-plus": {"source":"iana"}, + "multipart/voice-message": {"source":"iana"}, + "multipart/x-mixed-replace": {"source":"iana"}, + "text/1d-interleaved-parityfec": {"source":"iana"}, + "text/cache-manifest": {"source":"iana","compressible":true,"extensions":["appcache","manifest"]}, + "text/calendar": {"source":"iana","extensions":["ics","ifb"]}, + "text/calender": {"compressible":true}, + "text/cmd": {"compressible":true}, + "text/coffeescript": {"extensions":["coffee","litcoffee"]}, + "text/cql": {"source":"iana"}, + "text/cql-expression": {"source":"iana"}, + "text/cql-identifier": {"source":"iana"}, + "text/css": {"source":"iana","charset":"UTF-8","compressible":true,"extensions":["css"]}, + "text/csv": {"source":"iana","compressible":true,"extensions":["csv"]}, + "text/csv-schema": {"source":"iana"}, + "text/directory": {"source":"iana"}, + "text/dns": {"source":"iana"}, + "text/ecmascript": {"source":"apache"}, + "text/encaprtp": {"source":"iana"}, + "text/enriched": {"source":"iana"}, + "text/fhirpath": {"source":"iana"}, + "text/flexfec": {"source":"iana"}, + "text/fwdred": {"source":"iana"}, + "text/gff3": {"source":"iana"}, + "text/grammar-ref-list": {"source":"iana"}, + "text/hl7v2": {"source":"iana"}, + "text/html": {"source":"iana","compressible":true,"extensions":["html","htm","shtml"]}, + "text/jade": {"extensions":["jade"]}, + "text/javascript": {"source":"iana","charset":"UTF-8","compressible":true,"extensions":["js","mjs"]}, + "text/jcr-cnd": {"source":"iana"}, + "text/jsx": {"compressible":true,"extensions":["jsx"]}, + "text/less": {"compressible":true,"extensions":["less"]}, + "text/markdown": {"source":"iana","compressible":true,"extensions":["md","markdown"]}, + "text/mathml": {"source":"nginx","extensions":["mml"]}, + "text/mdx": {"compressible":true,"extensions":["mdx"]}, + "text/mizar": {"source":"iana"}, + "text/n3": {"source":"iana","charset":"UTF-8","compressible":true,"extensions":["n3"]}, + "text/parameters": {"source":"iana","charset":"UTF-8"}, + "text/parityfec": {"source":"iana"}, + "text/plain": {"source":"iana","compressible":true,"extensions":["txt","text","conf","def","list","log","in","ini"]}, + "text/provenance-notation": {"source":"iana","charset":"UTF-8"}, + "text/prs.fallenstein.rst": {"source":"iana"}, + "text/prs.lines.tag": {"source":"iana","extensions":["dsc"]}, + "text/prs.prop.logic": {"source":"iana"}, + "text/prs.texi": {"source":"iana"}, + "text/raptorfec": {"source":"iana"}, + "text/red": {"source":"iana"}, + "text/rfc822-headers": {"source":"iana"}, + "text/richtext": {"source":"iana","compressible":true,"extensions":["rtx"]}, + "text/rtf": {"source":"iana","compressible":true,"extensions":["rtf"]}, + "text/rtp-enc-aescm128": {"source":"iana"}, + "text/rtploopback": {"source":"iana"}, + "text/rtx": {"source":"iana"}, + "text/sgml": {"source":"iana","extensions":["sgml","sgm"]}, + "text/shaclc": {"source":"iana"}, + "text/shex": {"source":"iana","extensions":["shex"]}, + "text/slim": {"extensions":["slim","slm"]}, + "text/spdx": {"source":"iana","extensions":["spdx"]}, + "text/strings": {"source":"iana"}, + "text/stylus": {"extensions":["stylus","styl"]}, + "text/t140": {"source":"iana"}, + "text/tab-separated-values": {"source":"iana","compressible":true,"extensions":["tsv"]}, + "text/troff": {"source":"iana","extensions":["t","tr","roff","man","me","ms"]}, + "text/turtle": {"source":"iana","charset":"UTF-8","extensions":["ttl"]}, + "text/ulpfec": {"source":"iana"}, + "text/uri-list": {"source":"iana","compressible":true,"extensions":["uri","uris","urls"]}, + "text/vcard": {"source":"iana","compressible":true,"extensions":["vcard"]}, + "text/vnd.a": {"source":"iana"}, + "text/vnd.abc": {"source":"iana"}, + "text/vnd.ascii-art": {"source":"iana"}, + "text/vnd.curl": {"source":"iana","extensions":["curl"]}, + "text/vnd.curl.dcurl": {"source":"apache","extensions":["dcurl"]}, + "text/vnd.curl.mcurl": {"source":"apache","extensions":["mcurl"]}, + "text/vnd.curl.scurl": {"source":"apache","extensions":["scurl"]}, + "text/vnd.debian.copyright": {"source":"iana","charset":"UTF-8"}, + "text/vnd.dmclientscript": {"source":"iana"}, + "text/vnd.dvb.subtitle": {"source":"iana","extensions":["sub"]}, + "text/vnd.esmertec.theme-descriptor": {"source":"iana","charset":"UTF-8"}, + "text/vnd.exchangeable": {"source":"iana"}, + "text/vnd.familysearch.gedcom": {"source":"iana","extensions":["ged"]}, + "text/vnd.ficlab.flt": {"source":"iana"}, + "text/vnd.fly": {"source":"iana","extensions":["fly"]}, + "text/vnd.fmi.flexstor": {"source":"iana","extensions":["flx"]}, + "text/vnd.gml": {"source":"iana"}, + "text/vnd.graphviz": {"source":"iana","extensions":["gv"]}, + "text/vnd.hans": {"source":"iana"}, + "text/vnd.hgl": {"source":"iana"}, + "text/vnd.in3d.3dml": {"source":"iana","extensions":["3dml"]}, + "text/vnd.in3d.spot": {"source":"iana","extensions":["spot"]}, + "text/vnd.iptc.newsml": {"source":"iana"}, + "text/vnd.iptc.nitf": {"source":"iana"}, + "text/vnd.latex-z": {"source":"iana"}, + "text/vnd.motorola.reflex": {"source":"iana"}, + "text/vnd.ms-mediapackage": {"source":"iana"}, + "text/vnd.net2phone.commcenter.command": {"source":"iana"}, + "text/vnd.radisys.msml-basic-layout": {"source":"iana"}, + "text/vnd.senx.warpscript": {"source":"iana"}, + "text/vnd.si.uricatalogue": {"source":"apache"}, + "text/vnd.sosi": {"source":"iana"}, + "text/vnd.sun.j2me.app-descriptor": {"source":"iana","charset":"UTF-8","extensions":["jad"]}, + "text/vnd.trolltech.linguist": {"source":"iana","charset":"UTF-8"}, + "text/vnd.vcf": {"source":"iana"}, + "text/vnd.wap.si": {"source":"iana"}, + "text/vnd.wap.sl": {"source":"iana"}, + "text/vnd.wap.wml": {"source":"iana","extensions":["wml"]}, + "text/vnd.wap.wmlscript": {"source":"iana","extensions":["wmls"]}, + "text/vnd.zoo.kcl": {"source":"iana"}, + "text/vtt": {"source":"iana","charset":"UTF-8","compressible":true,"extensions":["vtt"]}, + "text/wgsl": {"source":"iana","extensions":["wgsl"]}, + "text/x-asm": {"source":"apache","extensions":["s","asm"]}, + "text/x-c": {"source":"apache","extensions":["c","cc","cxx","cpp","h","hh","dic"]}, + "text/x-component": {"source":"nginx","extensions":["htc"]}, + "text/x-fortran": {"source":"apache","extensions":["f","for","f77","f90"]}, + "text/x-gwt-rpc": {"compressible":true}, + "text/x-handlebars-template": {"extensions":["hbs"]}, + "text/x-java-source": {"source":"apache","extensions":["java"]}, + "text/x-jquery-tmpl": {"compressible":true}, + "text/x-lua": {"extensions":["lua"]}, + "text/x-markdown": {"compressible":true,"extensions":["mkd"]}, + "text/x-nfo": {"source":"apache","extensions":["nfo"]}, + "text/x-opml": {"source":"apache","extensions":["opml"]}, + "text/x-org": {"compressible":true,"extensions":["org"]}, + "text/x-pascal": {"source":"apache","extensions":["p","pas"]}, + "text/x-processing": {"compressible":true,"extensions":["pde"]}, + "text/x-sass": {"extensions":["sass"]}, + "text/x-scss": {"extensions":["scss"]}, + "text/x-setext": {"source":"apache","extensions":["etx"]}, + "text/x-sfv": {"source":"apache","extensions":["sfv"]}, + "text/x-suse-ymp": {"compressible":true,"extensions":["ymp"]}, + "text/x-uuencode": {"source":"apache","extensions":["uu"]}, + "text/x-vcalendar": {"source":"apache","extensions":["vcs"]}, + "text/x-vcard": {"source":"apache","extensions":["vcf"]}, + "text/xml": {"source":"iana","compressible":true,"extensions":["xml"]}, + "text/xml-external-parsed-entity": {"source":"iana"}, + "text/yaml": {"compressible":true,"extensions":["yaml","yml"]}, + "video/1d-interleaved-parityfec": {"source":"iana"}, + "video/3gpp": {"source":"iana","extensions":["3gp","3gpp"]}, + "video/3gpp-tt": {"source":"iana"}, + "video/3gpp2": {"source":"iana","extensions":["3g2"]}, + "video/av1": {"source":"iana"}, + "video/bmpeg": {"source":"iana"}, + "video/bt656": {"source":"iana"}, + "video/celb": {"source":"iana"}, + "video/dv": {"source":"iana"}, + "video/encaprtp": {"source":"iana"}, + "video/evc": {"source":"iana"}, + "video/ffv1": {"source":"iana"}, + "video/flexfec": {"source":"iana"}, + "video/h261": {"source":"iana","extensions":["h261"]}, + "video/h263": {"source":"iana","extensions":["h263"]}, + "video/h263-1998": {"source":"iana"}, + "video/h263-2000": {"source":"iana"}, + "video/h264": {"source":"iana","extensions":["h264"]}, + "video/h264-rcdo": {"source":"iana"}, + "video/h264-svc": {"source":"iana"}, + "video/h265": {"source":"iana"}, + "video/h266": {"source":"iana"}, + "video/iso.segment": {"source":"iana","extensions":["m4s"]}, + "video/jpeg": {"source":"iana","extensions":["jpgv"]}, + "video/jpeg2000": {"source":"iana"}, + "video/jpm": {"source":"apache","extensions":["jpm","jpgm"]}, + "video/jxsv": {"source":"iana"}, + "video/lottie+json": {"source":"iana","compressible":true}, + "video/matroska": {"source":"iana"}, + "video/matroska-3d": {"source":"iana"}, + "video/mj2": {"source":"iana","extensions":["mj2","mjp2"]}, + "video/mp1s": {"source":"iana"}, + "video/mp2p": {"source":"iana"}, + "video/mp2t": {"source":"iana","extensions":["ts","m2t","m2ts","mts"]}, + "video/mp4": {"source":"iana","compressible":false,"extensions":["mp4","mp4v","mpg4"]}, + "video/mp4v-es": {"source":"iana"}, + "video/mpeg": {"source":"iana","compressible":false,"extensions":["mpeg","mpg","mpe","m1v","m2v"]}, + "video/mpeg4-generic": {"source":"iana"}, + "video/mpv": {"source":"iana"}, + "video/nv": {"source":"iana"}, + "video/ogg": {"source":"iana","compressible":false,"extensions":["ogv"]}, + "video/parityfec": {"source":"iana"}, + "video/pointer": {"source":"iana"}, + "video/quicktime": {"source":"iana","compressible":false,"extensions":["qt","mov"]}, + "video/raptorfec": {"source":"iana"}, + "video/raw": {"source":"iana"}, + "video/rtp-enc-aescm128": {"source":"iana"}, + "video/rtploopback": {"source":"iana"}, + "video/rtx": {"source":"iana"}, + "video/scip": {"source":"iana"}, + "video/smpte291": {"source":"iana"}, + "video/smpte292m": {"source":"iana"}, + "video/ulpfec": {"source":"iana"}, + "video/vc1": {"source":"iana"}, + "video/vc2": {"source":"iana"}, + "video/vnd.cctv": {"source":"iana"}, + "video/vnd.dece.hd": {"source":"iana","extensions":["uvh","uvvh"]}, + "video/vnd.dece.mobile": {"source":"iana","extensions":["uvm","uvvm"]}, + "video/vnd.dece.mp4": {"source":"iana"}, + "video/vnd.dece.pd": {"source":"iana","extensions":["uvp","uvvp"]}, + "video/vnd.dece.sd": {"source":"iana","extensions":["uvs","uvvs"]}, + "video/vnd.dece.video": {"source":"iana","extensions":["uvv","uvvv"]}, + "video/vnd.directv.mpeg": {"source":"iana"}, + "video/vnd.directv.mpeg-tts": {"source":"iana"}, + "video/vnd.dlna.mpeg-tts": {"source":"iana"}, + "video/vnd.dvb.file": {"source":"iana","extensions":["dvb"]}, + "video/vnd.fvt": {"source":"iana","extensions":["fvt"]}, + "video/vnd.hns.video": {"source":"iana"}, + "video/vnd.iptvforum.1dparityfec-1010": {"source":"iana"}, + "video/vnd.iptvforum.1dparityfec-2005": {"source":"iana"}, + "video/vnd.iptvforum.2dparityfec-1010": {"source":"iana"}, + "video/vnd.iptvforum.2dparityfec-2005": {"source":"iana"}, + "video/vnd.iptvforum.ttsavc": {"source":"iana"}, + "video/vnd.iptvforum.ttsmpeg2": {"source":"iana"}, + "video/vnd.motorola.video": {"source":"iana"}, + "video/vnd.motorola.videop": {"source":"iana"}, + "video/vnd.mpegurl": {"source":"iana","extensions":["mxu","m4u"]}, + "video/vnd.ms-playready.media.pyv": {"source":"iana","extensions":["pyv"]}, + "video/vnd.nokia.interleaved-multimedia": {"source":"iana"}, + "video/vnd.nokia.mp4vr": {"source":"iana"}, + "video/vnd.nokia.videovoip": {"source":"iana"}, + "video/vnd.objectvideo": {"source":"iana"}, + "video/vnd.planar": {"source":"iana"}, + "video/vnd.radgamettools.bink": {"source":"iana"}, + "video/vnd.radgamettools.smacker": {"source":"apache"}, + "video/vnd.sealed.mpeg1": {"source":"iana"}, + "video/vnd.sealed.mpeg4": {"source":"iana"}, + "video/vnd.sealed.swf": {"source":"iana"}, + "video/vnd.sealedmedia.softseal.mov": {"source":"iana"}, + "video/vnd.uvvu.mp4": {"source":"iana","extensions":["uvu","uvvu"]}, + "video/vnd.vivo": {"source":"iana","extensions":["viv"]}, + "video/vnd.youtube.yt": {"source":"iana"}, + "video/vp8": {"source":"iana"}, + "video/vp9": {"source":"iana"}, + "video/webm": {"source":"apache","compressible":false,"extensions":["webm"]}, + "video/x-f4v": {"source":"apache","extensions":["f4v"]}, + "video/x-fli": {"source":"apache","extensions":["fli"]}, + "video/x-flv": {"source":"apache","compressible":false,"extensions":["flv"]}, + "video/x-m4v": {"source":"apache","extensions":["m4v"]}, + "video/x-matroska": {"source":"apache","compressible":false,"extensions":["mkv","mk3d","mks"]}, + "video/x-mng": {"source":"apache","extensions":["mng"]}, + "video/x-ms-asf": {"source":"apache","extensions":["asf","asx"]}, + "video/x-ms-vob": {"source":"apache","extensions":["vob"]}, + "video/x-ms-wm": {"source":"apache","extensions":["wm"]}, + "video/x-ms-wmv": {"source":"apache","compressible":false,"extensions":["wmv"]}, + "video/x-ms-wmx": {"source":"apache","extensions":["wmx"]}, + "video/x-ms-wvx": {"source":"apache","extensions":["wvx"]}, + "video/x-msvideo": {"source":"apache","extensions":["avi"]}, + "video/x-sgi-movie": {"source":"apache","extensions":["movie"]}, + "video/x-smv": {"source":"apache","extensions":["smv"]}, + "x-conference/x-cooltalk": {"source":"apache","extensions":["ice"]}, + "x-shader/x-fragment": {"compressible":true}, + "x-shader/x-vertex": {"compressible":true}, +}; + +/*! + * mime-db + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2015-2022 Douglas Christopher Wilson + * MIT Licensed + */ + +var mimeDb; +var hasRequiredMimeDb; + +function requireMimeDb () { + if (hasRequiredMimeDb) return mimeDb; + hasRequiredMimeDb = 1; + /** + * Module exports. + */ + + mimeDb = require$$0$1; + return mimeDb; +} + +var mimeScore; +var hasRequiredMimeScore; + +function requireMimeScore () { + if (hasRequiredMimeScore) return mimeScore; + hasRequiredMimeScore = 1; + // 'mime-score' back-ported to CommonJS + + // Score RFC facets (see https://tools.ietf.org/html/rfc6838#section-3) + var FACET_SCORES = { + 'prs.': 100, + 'x-': 200, + 'x.': 300, + 'vnd.': 400, + default: 900 + }; + + // Score mime source (Logic originally from `jshttp/mime-types` module) + var SOURCE_SCORES = { + nginx: 10, + apache: 20, + iana: 40, + default: 30 // definitions added by `jshttp/mime-db` project? + }; + + var TYPE_SCORES = { + // prefer application/xml over text/xml + // prefer application/rtf over text/rtf + application: 1, + + // prefer font/woff over application/font-woff + font: 2, + + default: 0 + }; + + /** + * Get each component of the score for a mime type. The sum of these is the + * total score. The higher the score, the more "official" the type. + */ + mimeScore = function mimeScore (mimeType, source = 'default') { + if (mimeType === 'application/octet-stream') { + return 0 + } + + const [type, subtype] = mimeType.split('/'); + + const facet = subtype.replace(/(\.|x-).*/, '$1'); + + const facetScore = FACET_SCORES[facet] || FACET_SCORES.default; + const sourceScore = SOURCE_SCORES[source] || SOURCE_SCORES.default; + const typeScore = TYPE_SCORES[type] || TYPE_SCORES.default; + + // All else being equal prefer shorter types + const lengthScore = 1 - mimeType.length / 100; + + return facetScore + sourceScore + typeScore + lengthScore + }; + return mimeScore; +} + +/*! + * mime-types + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + */ + +var hasRequiredMimeTypes; + +function requireMimeTypes () { + if (hasRequiredMimeTypes) return mimeTypes; + hasRequiredMimeTypes = 1; + (function (exports) { + + /** + * Module dependencies. + * @private + */ + + var db = requireMimeDb(); + var extname = require$$0$4.extname; + var mimeScore = requireMimeScore(); + + /** + * Module variables. + * @private + */ + + var EXTRACT_TYPE_REGEXP = /^\s*([^;\s]*)(?:;|\s|$)/; + var TEXT_TYPE_REGEXP = /^text\//i; + + /** + * Module exports. + * @public + */ + + exports.charset = charset; + exports.charsets = { lookup: charset }; + exports.contentType = contentType; + exports.extension = extension; + exports.extensions = Object.create(null); + exports.lookup = lookup; + exports.types = Object.create(null); + exports._extensionConflicts = []; + + // Populate the extensions/types maps + populateMaps(exports.extensions, exports.types); + + /** + * Get the default charset for a MIME type. + * + * @param {string} type + * @return {boolean|string} + */ + + function charset (type) { + if (!type || typeof type !== 'string') { + return false + } + + // TODO: use media-typer + var match = EXTRACT_TYPE_REGEXP.exec(type); + var mime = match && db[match[1].toLowerCase()]; + + if (mime && mime.charset) { + return mime.charset + } + + // default text/* to utf-8 + if (match && TEXT_TYPE_REGEXP.test(match[1])) { + return 'UTF-8' + } + + return false + } + + /** + * Create a full Content-Type header given a MIME type or extension. + * + * @param {string} str + * @return {boolean|string} + */ + + function contentType (str) { + // TODO: should this even be in this module? + if (!str || typeof str !== 'string') { + return false + } + + var mime = str.indexOf('/') === -1 ? exports.lookup(str) : str; + + if (!mime) { + return false + } + + // TODO: use content-type or other module + if (mime.indexOf('charset') === -1) { + var charset = exports.charset(mime); + if (charset) mime += '; charset=' + charset.toLowerCase(); + } + + return mime + } + + /** + * Get the default extension for a MIME type. + * + * @param {string} type + * @return {boolean|string} + */ + + function extension (type) { + if (!type || typeof type !== 'string') { + return false + } + + // TODO: use media-typer + var match = EXTRACT_TYPE_REGEXP.exec(type); + + // get extensions + var exts = match && exports.extensions[match[1].toLowerCase()]; + + if (!exts || !exts.length) { + return false + } + + return exts[0] + } + + /** + * Lookup the MIME type for a file path/extension. + * + * @param {string} path + * @return {boolean|string} + */ + + function lookup (path) { + if (!path || typeof path !== 'string') { + return false + } + + // get the extension ("ext" or ".ext" or full path) + var extension = extname('x.' + path) + .toLowerCase() + .slice(1); + + if (!extension) { + return false + } + + return exports.types[extension] || false + } + + /** + * Populate the extensions and types maps. + * @private + */ + + function populateMaps (extensions, types) { + Object.keys(db).forEach(function forEachMimeType (type) { + var mime = db[type]; + var exts = mime.extensions; + + if (!exts || !exts.length) { + return + } + + // mime -> extensions + extensions[type] = exts; + + // extension -> mime + for (var i = 0; i < exts.length; i++) { + var extension = exts[i]; + types[extension] = _preferredType(extension, types[extension], type); + + // DELETE (eventually): Capture extension->type maps that change as a + // result of switching to mime-score. This is just to help make reviewing + // PR #119 easier, and can be removed once that PR is approved. + const legacyType = _preferredTypeLegacy( + extension, + types[extension], + type + ); + if (legacyType !== types[extension]) { + exports._extensionConflicts.push([extension, legacyType, types[extension]]); + } + } + }); + } + + // Resolve type conflict using mime-score + function _preferredType (ext, type0, type1) { + var score0 = type0 ? mimeScore(type0, db[type0].source) : 0; + var score1 = type1 ? mimeScore(type1, db[type1].source) : 0; + + return score0 > score1 ? type0 : type1 + } + + // Resolve type conflict using pre-mime-score logic + function _preferredTypeLegacy (ext, type0, type1) { + var SOURCE_RANK = ['nginx', 'apache', undefined, 'iana']; + + var score0 = type0 ? SOURCE_RANK.indexOf(db[type0].source) : 0; + var score1 = type1 ? SOURCE_RANK.indexOf(db[type1].source) : 0; + + if ( + exports.types[extension] !== 'application/octet-stream' && + (score0 > score1 || + (score0 === score1 && + exports.types[extension]?.slice(0, 12) === 'application/')) + ) { + return type0 + } + + return score0 > score1 ? type0 : type1 + } + } (mimeTypes)); + return mimeTypes; +} + +var onFinished = {exports: {}}; + +/*! + * ee-first + * Copyright(c) 2014 Jonathan Ong + * MIT Licensed + */ + +var eeFirst; +var hasRequiredEeFirst; + +function requireEeFirst () { + if (hasRequiredEeFirst) return eeFirst; + hasRequiredEeFirst = 1; + + /** + * Module exports. + * @public + */ + + eeFirst = first; + + /** + * Get the first event in a set of event emitters and event pairs. + * + * @param {array} stuff + * @param {function} done + * @public + */ + + function first(stuff, done) { + if (!Array.isArray(stuff)) + throw new TypeError('arg must be an array of [ee, events...] arrays') + + var cleanups = []; + + for (var i = 0; i < stuff.length; i++) { + var arr = stuff[i]; + + if (!Array.isArray(arr) || arr.length < 2) + throw new TypeError('each array member must be [ee, events...]') + + var ee = arr[0]; + + for (var j = 1; j < arr.length; j++) { + var event = arr[j]; + var fn = listener(event, callback); + + // listen to the event + ee.on(event, fn); + // push this listener to the list of cleanups + cleanups.push({ + ee: ee, + event: event, + fn: fn, + }); + } + } + + function callback() { + cleanup(); + done.apply(null, arguments); + } + + function cleanup() { + var x; + for (var i = 0; i < cleanups.length; i++) { + x = cleanups[i]; + x.ee.removeListener(x.event, x.fn); + } + } + + function thunk(fn) { + done = fn; + } + + thunk.cancel = cleanup; + + return thunk + } + + /** + * Create the event listener. + * @private + */ + + function listener(event, done) { + return function onevent(arg1) { + var args = new Array(arguments.length); + var ee = this; + var err = event === 'error' + ? arg1 + : null; + + // copy args to prevent arguments escaping scope + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i]; + } + + done(err, ee, event, args); + } + } + return eeFirst; +} + +/*! + * on-finished + * Copyright(c) 2013 Jonathan Ong + * Copyright(c) 2014 Douglas Christopher Wilson + * MIT Licensed + */ + +var hasRequiredOnFinished; + +function requireOnFinished () { + if (hasRequiredOnFinished) return onFinished.exports; + hasRequiredOnFinished = 1; + + /** + * Module exports. + * @public + */ + + onFinished.exports = onFinished$1; + onFinished.exports.isFinished = isFinished; + + /** + * Module dependencies. + * @private + */ + + var asyncHooks = tryRequireAsyncHooks(); + var first = requireEeFirst(); + + /** + * Variables. + * @private + */ + + /* istanbul ignore next */ + var defer = typeof setImmediate === 'function' + ? setImmediate + : function (fn) { process.nextTick(fn.bind.apply(fn, arguments)); }; + + /** + * Invoke callback when the response has finished, useful for + * cleaning up resources afterwards. + * + * @param {object} msg + * @param {function} listener + * @return {object} + * @public + */ + + function onFinished$1 (msg, listener) { + if (isFinished(msg) !== false) { + defer(listener, null, msg); + return msg + } + + // attach the listener to the message + attachListener(msg, wrap(listener)); + + return msg + } + + /** + * Determine if message is already finished. + * + * @param {object} msg + * @return {boolean} + * @public + */ + + function isFinished (msg) { + var socket = msg.socket; + + if (typeof msg.finished === 'boolean') { + // OutgoingMessage + return Boolean(msg.finished || (socket && !socket.writable)) + } + + if (typeof msg.complete === 'boolean') { + // IncomingMessage + return Boolean(msg.upgrade || !socket || !socket.readable || (msg.complete && !msg.readable)) + } + + // don't know + return undefined + } + + /** + * Attach a finished listener to the message. + * + * @param {object} msg + * @param {function} callback + * @private + */ + + function attachFinishedListener (msg, callback) { + var eeMsg; + var eeSocket; + var finished = false; + + function onFinish (error) { + eeMsg.cancel(); + eeSocket.cancel(); + + finished = true; + callback(error); + } + + // finished on first message event + eeMsg = eeSocket = first([[msg, 'end', 'finish']], onFinish); + + function onSocket (socket) { + // remove listener + msg.removeListener('socket', onSocket); + + if (finished) return + if (eeMsg !== eeSocket) return + + // finished on first socket event + eeSocket = first([[socket, 'error', 'close']], onFinish); + } + + if (msg.socket) { + // socket already assigned + onSocket(msg.socket); + return + } + + // wait for socket to be assigned + msg.on('socket', onSocket); + + if (msg.socket === undefined) { + // istanbul ignore next: node.js 0.8 patch + patchAssignSocket(msg, onSocket); + } + } + + /** + * Attach the listener to the message. + * + * @param {object} msg + * @return {function} + * @private + */ + + function attachListener (msg, listener) { + var attached = msg.__onFinished; + + // create a private single listener with queue + if (!attached || !attached.queue) { + attached = msg.__onFinished = createListener(msg); + attachFinishedListener(msg, attached); + } + + attached.queue.push(listener); + } + + /** + * Create listener on message. + * + * @param {object} msg + * @return {function} + * @private + */ + + function createListener (msg) { + function listener (err) { + if (msg.__onFinished === listener) msg.__onFinished = null; + if (!listener.queue) return + + var queue = listener.queue; + listener.queue = null; + + for (var i = 0; i < queue.length; i++) { + queue[i](err, msg); + } + } + + listener.queue = []; + + return listener + } + + /** + * Patch ServerResponse.prototype.assignSocket for node.js 0.8. + * + * @param {ServerResponse} res + * @param {function} callback + * @private + */ + + // istanbul ignore next: node.js 0.8 patch + function patchAssignSocket (res, callback) { + var assignSocket = res.assignSocket; + + if (typeof assignSocket !== 'function') return + + // res.on('socket', callback) is broken in 0.8 + res.assignSocket = function _assignSocket (socket) { + assignSocket.call(this, socket); + callback(socket); + }; + } + + /** + * Try to require async_hooks + * @private + */ + + function tryRequireAsyncHooks () { + try { + return require('async_hooks') + } catch (e) { + return {} + } + } + + /** + * Wrap function with async resource, if possible. + * AsyncResource.bind static method backported. + * @private + */ + + function wrap (fn) { + var res; + + // create anonymous resource + if (asyncHooks.AsyncResource) { + res = new asyncHooks.AsyncResource(fn.name || 'bound-anonymous-fn'); + } + + // incompatible node.js + if (!res || !res.runInAsyncScope) { + return fn + } + + // return bound function + return res.runInAsyncScope.bind(res, fn, null) + } + return onFinished.exports; +} + +/*! + * range-parser + * Copyright(c) 2012-2014 TJ Holowaychuk + * Copyright(c) 2015-2016 Douglas Christopher Wilson + * MIT Licensed + */ + +var rangeParser_1; +var hasRequiredRangeParser; + +function requireRangeParser () { + if (hasRequiredRangeParser) return rangeParser_1; + hasRequiredRangeParser = 1; + + /** + * Module exports. + * @public + */ + + rangeParser_1 = rangeParser; + + /** + * Parse "Range" header `str` relative to the given file `size`. + * + * @param {Number} size + * @param {String} str + * @param {Object} [options] + * @return {Array} + * @public + */ + + function rangeParser (size, str, options) { + if (typeof str !== 'string') { + throw new TypeError('argument str must be a string') + } + + var index = str.indexOf('='); + + if (index === -1) { + return -2 + } + + // split the range string + var arr = str.slice(index + 1).split(','); + var ranges = []; + + // add ranges type + ranges.type = str.slice(0, index); + + // parse all ranges + for (var i = 0; i < arr.length; i++) { + var range = arr[i].split('-'); + var start = parseInt(range[0], 10); + var end = parseInt(range[1], 10); + + // -nnn + if (isNaN(start)) { + start = size - end; + end = size - 1; + // nnn- + } else if (isNaN(end)) { + end = size - 1; + } + + // limit last-byte-pos to current length + if (end > size - 1) { + end = size - 1; + } + + // invalid or unsatisifiable + if (isNaN(start) || isNaN(end) || start > end || start < 0) { + continue + } + + // add range + ranges.push({ + start: start, + end: end + }); + } + + if (ranges.length < 1) { + // unsatisifiable + return -1 + } + + return options && options.combine + ? combineRanges(ranges) + : ranges + } + + /** + * Combine overlapping & adjacent ranges. + * @private + */ + + function combineRanges (ranges) { + var ordered = ranges.map(mapWithIndex).sort(sortByRangeStart); + + for (var j = 0, i = 1; i < ordered.length; i++) { + var range = ordered[i]; + var current = ordered[j]; + + if (range.start > current.end + 1) { + // next range + ordered[++j] = range; + } else if (range.end > current.end) { + // extend range + current.end = range.end; + current.index = Math.min(current.index, range.index); + } + } + + // trim ordered array + ordered.length = j + 1; + + // generate combined range + var combined = ordered.sort(sortByRangeIndex).map(mapWithoutIndex); + + // copy ranges type + combined.type = ranges.type; + + return combined + } + + /** + * Map function to add index value to ranges. + * @private + */ + + function mapWithIndex (range, index) { + return { + start: range.start, + end: range.end, + index: index + } + } + + /** + * Map function to remove index value from ranges. + * @private + */ + + function mapWithoutIndex (range) { + return { + start: range.start, + end: range.end + } + } + + /** + * Sort function to sort ranges by index. + * @private + */ + + function sortByRangeIndex (a, b) { + return a.index - b.index + } + + /** + * Sort function to sort ranges by start position. + * @private + */ + + function sortByRangeStart (a, b) { + return a.start - b.start + } + return rangeParser_1; +} + +const require$$0 = { + "100": "Continue", + "101": "Switching Protocols", + "102": "Processing", + "103": "Early Hints", + "200": "OK", + "201": "Created", + "202": "Accepted", + "203": "Non-Authoritative Information", + "204": "No Content", + "205": "Reset Content", + "206": "Partial Content", + "207": "Multi-Status", + "208": "Already Reported", + "226": "IM Used", + "300": "Multiple Choices", + "301": "Moved Permanently", + "302": "Found", + "303": "See Other", + "304": "Not Modified", + "305": "Use Proxy", + "307": "Temporary Redirect", + "308": "Permanent Redirect", + "400": "Bad Request", + "401": "Unauthorized", + "402": "Payment Required", + "403": "Forbidden", + "404": "Not Found", + "405": "Method Not Allowed", + "406": "Not Acceptable", + "407": "Proxy Authentication Required", + "408": "Request Timeout", + "409": "Conflict", + "410": "Gone", + "411": "Length Required", + "412": "Precondition Failed", + "413": "Payload Too Large", + "414": "URI Too Long", + "415": "Unsupported Media Type", + "416": "Range Not Satisfiable", + "417": "Expectation Failed", + "418": "I'm a Teapot", + "421": "Misdirected Request", + "422": "Unprocessable Entity", + "423": "Locked", + "424": "Failed Dependency", + "425": "Too Early", + "426": "Upgrade Required", + "428": "Precondition Required", + "429": "Too Many Requests", + "431": "Request Header Fields Too Large", + "451": "Unavailable For Legal Reasons", + "500": "Internal Server Error", + "501": "Not Implemented", + "502": "Bad Gateway", + "503": "Service Unavailable", + "504": "Gateway Timeout", + "505": "HTTP Version Not Supported", + "506": "Variant Also Negotiates", + "507": "Insufficient Storage", + "508": "Loop Detected", + "509": "Bandwidth Limit Exceeded", + "510": "Not Extended", + "511": "Network Authentication Required", +}; + +/*! + * statuses + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2016 Douglas Christopher Wilson + * MIT Licensed + */ + +var statuses; +var hasRequiredStatuses; + +function requireStatuses () { + if (hasRequiredStatuses) return statuses; + hasRequiredStatuses = 1; + + /** + * Module dependencies. + * @private + */ + + var codes = require$$0; + + /** + * Module exports. + * @public + */ + + statuses = status; + + // status code to message map + status.message = codes; + + // status message (lower-case) to code map + status.code = createMessageToStatusCodeMap(codes); + + // array of status codes + status.codes = createStatusCodeList(codes); + + // status codes for redirects + status.redirect = { + 300: true, + 301: true, + 302: true, + 303: true, + 305: true, + 307: true, + 308: true + }; + + // status codes for empty bodies + status.empty = { + 204: true, + 205: true, + 304: true + }; + + // status codes for when you should retry the request + status.retry = { + 502: true, + 503: true, + 504: true + }; + + /** + * Create a map of message to status code. + * @private + */ + + function createMessageToStatusCodeMap (codes) { + var map = {}; + + Object.keys(codes).forEach(function forEachCode (code) { + var message = codes[code]; + var status = Number(code); + + // populate map + map[message.toLowerCase()] = status; + }); + + return map + } + + /** + * Create a list of all status codes. + * @private + */ + + function createStatusCodeList (codes) { + return Object.keys(codes).map(function mapCode (code) { + return Number(code) + }) + } + + /** + * Get the status code for given message. + * @private + */ + + function getStatusCode (message) { + var msg = message.toLowerCase(); + + if (!Object.prototype.hasOwnProperty.call(status.code, msg)) { + throw new Error('invalid status message: "' + message + '"') + } + + return status.code[msg] + } + + /** + * Get the status message for given code. + * @private + */ + + function getStatusMessage (code) { + if (!Object.prototype.hasOwnProperty.call(status.message, code)) { + throw new Error('invalid status code: ' + code) + } + + return status.message[code] + } + + /** + * Get the status code. + * + * Given a number, this will throw if it is not a known status + * code, otherwise the code will be returned. Given a string, + * the string will be parsed for a number and return the code + * if valid, otherwise will lookup the code assuming this is + * the status message. + * + * @param {string|number} code + * @returns {number} + * @public + */ + + function status (code) { + if (typeof code === 'number') { + return getStatusMessage(code) + } + + if (typeof code !== 'string') { + throw new TypeError('code must be a number or string') + } + + // '403' + var n = parseInt(code, 10); + if (!isNaN(n)) { + return getStatusMessage(n) + } + + return getStatusCode(code) + } + return statuses; +} + +/*! + * send + * Copyright(c) 2012 TJ Holowaychuk + * Copyright(c) 2014-2022 Douglas Christopher Wilson + * MIT Licensed + */ + +var send_1; +var hasRequiredSend; + +function requireSend () { + if (hasRequiredSend) return send_1; + hasRequiredSend = 1; + + /** + * Module dependencies. + * @private + */ + + var createError = requireHttpErrors(); + var debug = debug$1('send'); + var encodeUrl = requireEncodeurl(); + var escapeHtml = requireEscapeHtml(); + var etag = requireEtag(); + var fresh = requireFresh(); + var fs = require$$0$5; + var mime = requireMimeTypes(); + var ms$1 = ms; + var onFinished = requireOnFinished(); + var parseRange = requireRangeParser(); + var path = require$$0$4; + var statuses = requireStatuses(); + var Stream = require$$13; + var util = require$$14; + + /** + * Path function references. + * @private + */ + + var extname = path.extname; + var join = path.join; + var normalize = path.normalize; + var resolve = path.resolve; + var sep = path.sep; + + /** + * Regular expression for identifying a bytes Range header. + * @private + */ + + var BYTES_RANGE_REGEXP = /^ *bytes=/; + + /** + * Maximum value allowed for the max age. + * @private + */ + + var MAX_MAXAGE = 60 * 60 * 24 * 365 * 1000; // 1 year + + /** + * Regular expression to match a path with a directory up component. + * @private + */ + + var UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/; + + /** + * Module exports. + * @public + */ + + send_1 = send; + + /** + * Return a `SendStream` for `req` and `path`. + * + * @param {object} req + * @param {string} path + * @param {object} [options] + * @return {SendStream} + * @public + */ + + function send (req, path, options) { + return new SendStream(req, path, options) + } + + /** + * Initialize a `SendStream` with the given `path`. + * + * @param {Request} req + * @param {String} path + * @param {object} [options] + * @private + */ + + function SendStream (req, path, options) { + Stream.call(this); + + var opts = options || {}; + + this.options = opts; + this.path = path; + this.req = req; + + this._acceptRanges = opts.acceptRanges !== undefined + ? Boolean(opts.acceptRanges) + : true; + + this._cacheControl = opts.cacheControl !== undefined + ? Boolean(opts.cacheControl) + : true; + + this._etag = opts.etag !== undefined + ? Boolean(opts.etag) + : true; + + this._dotfiles = opts.dotfiles !== undefined + ? opts.dotfiles + : 'ignore'; + + if (this._dotfiles !== 'ignore' && this._dotfiles !== 'allow' && this._dotfiles !== 'deny') { + throw new TypeError('dotfiles option must be "allow", "deny", or "ignore"') + } + + this._extensions = opts.extensions !== undefined + ? normalizeList(opts.extensions, 'extensions option') + : []; + + this._immutable = opts.immutable !== undefined + ? Boolean(opts.immutable) + : false; + + this._index = opts.index !== undefined + ? normalizeList(opts.index, 'index option') + : ['index.html']; + + this._lastModified = opts.lastModified !== undefined + ? Boolean(opts.lastModified) + : true; + + this._maxage = opts.maxAge || opts.maxage; + this._maxage = typeof this._maxage === 'string' + ? ms$1(this._maxage) + : Number(this._maxage); + this._maxage = !isNaN(this._maxage) + ? Math.min(Math.max(0, this._maxage), MAX_MAXAGE) + : 0; + + this._root = opts.root + ? resolve(opts.root) + : null; + } + + /** + * Inherits from `Stream`. + */ + + util.inherits(SendStream, Stream); + + /** + * Emit error with `status`. + * + * @param {number} status + * @param {Error} [err] + * @private + */ + + SendStream.prototype.error = function error (status, err) { + // emit if listeners instead of responding + if (hasListeners(this, 'error')) { + return this.emit('error', createHttpError(status, err)) + } + + var res = this.res; + var msg = statuses.message[status] || String(status); + var doc = createHtmlDocument('Error', escapeHtml(msg)); + + // clear existing headers + clearHeaders(res); + + // add error headers + if (err && err.headers) { + setHeaders(res, err.headers); + } + + // send basic response + res.statusCode = status; + res.setHeader('Content-Type', 'text/html; charset=UTF-8'); + res.setHeader('Content-Length', Buffer.byteLength(doc)); + res.setHeader('Content-Security-Policy', "default-src 'none'"); + res.setHeader('X-Content-Type-Options', 'nosniff'); + res.end(doc); + }; + + /** + * Check if the pathname ends with "/". + * + * @return {boolean} + * @private + */ + + SendStream.prototype.hasTrailingSlash = function hasTrailingSlash () { + return this.path[this.path.length - 1] === '/' + }; + + /** + * Check if this is a conditional GET request. + * + * @return {Boolean} + * @api private + */ + + SendStream.prototype.isConditionalGET = function isConditionalGET () { + return this.req.headers['if-match'] || + this.req.headers['if-unmodified-since'] || + this.req.headers['if-none-match'] || + this.req.headers['if-modified-since'] + }; + + /** + * Check if the request preconditions failed. + * + * @return {boolean} + * @private + */ + + SendStream.prototype.isPreconditionFailure = function isPreconditionFailure () { + var req = this.req; + var res = this.res; + + // if-match + var match = req.headers['if-match']; + if (match) { + var etag = res.getHeader('ETag'); + return !etag || (match !== '*' && parseTokenList(match).every(function (match) { + return match !== etag && match !== 'W/' + etag && 'W/' + match !== etag + })) + } + + // if-unmodified-since + var unmodifiedSince = parseHttpDate(req.headers['if-unmodified-since']); + if (!isNaN(unmodifiedSince)) { + var lastModified = parseHttpDate(res.getHeader('Last-Modified')); + return isNaN(lastModified) || lastModified > unmodifiedSince + } + + return false + }; + + /** + * Strip various content header fields for a change in entity. + * + * @private + */ + + SendStream.prototype.removeContentHeaderFields = function removeContentHeaderFields () { + var res = this.res; + + res.removeHeader('Content-Encoding'); + res.removeHeader('Content-Language'); + res.removeHeader('Content-Length'); + res.removeHeader('Content-Range'); + res.removeHeader('Content-Type'); + }; + + /** + * Respond with 304 not modified. + * + * @api private + */ + + SendStream.prototype.notModified = function notModified () { + var res = this.res; + debug('not modified'); + this.removeContentHeaderFields(); + res.statusCode = 304; + res.end(); + }; + + /** + * Raise error that headers already sent. + * + * @api private + */ + + SendStream.prototype.headersAlreadySent = function headersAlreadySent () { + var err = new Error('Can\'t set headers after they are sent.'); + debug('headers already sent'); + this.error(500, err); + }; + + /** + * Check if the request is cacheable, aka + * responded with 2xx or 304 (see RFC 2616 section 14.2{5,6}). + * + * @return {Boolean} + * @api private + */ + + SendStream.prototype.isCachable = function isCachable () { + var statusCode = this.res.statusCode; + return (statusCode >= 200 && statusCode < 300) || + statusCode === 304 + }; + + /** + * Handle stat() error. + * + * @param {Error} error + * @private + */ + + SendStream.prototype.onStatError = function onStatError (error) { + switch (error.code) { + case 'ENAMETOOLONG': + case 'ENOENT': + case 'ENOTDIR': + this.error(404, error); + break + default: + this.error(500, error); + break + } + }; + + /** + * Check if the cache is fresh. + * + * @return {Boolean} + * @api private + */ + + SendStream.prototype.isFresh = function isFresh () { + return fresh(this.req.headers, { + etag: this.res.getHeader('ETag'), + 'last-modified': this.res.getHeader('Last-Modified') + }) + }; + + /** + * Check if the range is fresh. + * + * @return {Boolean} + * @api private + */ + + SendStream.prototype.isRangeFresh = function isRangeFresh () { + var ifRange = this.req.headers['if-range']; + + if (!ifRange) { + return true + } + + // if-range as etag + if (ifRange.indexOf('"') !== -1) { + var etag = this.res.getHeader('ETag'); + return Boolean(etag && ifRange.indexOf(etag) !== -1) + } + + // if-range as modified date + var lastModified = this.res.getHeader('Last-Modified'); + return parseHttpDate(lastModified) <= parseHttpDate(ifRange) + }; + + /** + * Redirect to path. + * + * @param {string} path + * @private + */ + + SendStream.prototype.redirect = function redirect (path) { + var res = this.res; + + if (hasListeners(this, 'directory')) { + this.emit('directory', res, path); + return + } + + if (this.hasTrailingSlash()) { + this.error(403); + return + } + + var loc = encodeUrl(collapseLeadingSlashes(this.path + '/')); + var doc = createHtmlDocument('Redirecting', 'Redirecting to ' + escapeHtml(loc)); + + // redirect + res.statusCode = 301; + res.setHeader('Content-Type', 'text/html; charset=UTF-8'); + res.setHeader('Content-Length', Buffer.byteLength(doc)); + res.setHeader('Content-Security-Policy', "default-src 'none'"); + res.setHeader('X-Content-Type-Options', 'nosniff'); + res.setHeader('Location', loc); + res.end(doc); + }; + + /** + * Pipe to `res. + * + * @param {Stream} res + * @return {Stream} res + * @api public + */ + + SendStream.prototype.pipe = function pipe (res) { + // root path + var root = this._root; + + // references + this.res = res; + + // decode the path + var path = decode(this.path); + if (path === -1) { + this.error(400); + return res + } + + // null byte(s) + if (~path.indexOf('\0')) { + this.error(400); + return res + } + + var parts; + if (root !== null) { + // normalize + if (path) { + path = normalize('.' + sep + path); + } + + // malicious path + if (UP_PATH_REGEXP.test(path)) { + debug('malicious path "%s"', path); + this.error(403); + return res + } + + // explode path parts + parts = path.split(sep); + + // join / normalize from optional root dir + path = normalize(join(root, path)); + } else { + // ".." is malicious without "root" + if (UP_PATH_REGEXP.test(path)) { + debug('malicious path "%s"', path); + this.error(403); + return res + } + + // explode path parts + parts = normalize(path).split(sep); + + // resolve the path + path = resolve(path); + } + + // dotfile handling + if (containsDotFile(parts)) { + debug('%s dotfile "%s"', this._dotfiles, path); + switch (this._dotfiles) { + case 'allow': + break + case 'deny': + this.error(403); + return res + case 'ignore': + default: + this.error(404); + return res + } + } + + // index file support + if (this._index.length && this.hasTrailingSlash()) { + this.sendIndex(path); + return res + } + + this.sendFile(path); + return res + }; + + /** + * Transfer `path`. + * + * @param {String} path + * @api public + */ + + SendStream.prototype.send = function send (path, stat) { + var len = stat.size; + var options = this.options; + var opts = {}; + var res = this.res; + var req = this.req; + var ranges = req.headers.range; + var offset = options.start || 0; + + if (res.headersSent) { + // impossible to send now + this.headersAlreadySent(); + return + } + + debug('pipe "%s"', path); + + // set header fields + this.setHeader(path, stat); + + // set content-type + this.type(path); + + // conditional GET support + if (this.isConditionalGET()) { + if (this.isPreconditionFailure()) { + this.error(412); + return + } + + if (this.isCachable() && this.isFresh()) { + this.notModified(); + return + } + } + + // adjust len to start/end options + len = Math.max(0, len - offset); + if (options.end !== undefined) { + var bytes = options.end - offset + 1; + if (len > bytes) len = bytes; + } + + // Range support + if (this._acceptRanges && BYTES_RANGE_REGEXP.test(ranges)) { + // parse + ranges = parseRange(len, ranges, { + combine: true + }); + + // If-Range support + if (!this.isRangeFresh()) { + debug('range stale'); + ranges = -2; + } + + // unsatisfiable + if (ranges === -1) { + debug('range unsatisfiable'); + + // Content-Range + res.setHeader('Content-Range', contentRange('bytes', len)); + + // 416 Requested Range Not Satisfiable + return this.error(416, { + headers: { 'Content-Range': res.getHeader('Content-Range') } + }) + } + + // valid (syntactically invalid/multiple ranges are treated as a regular response) + if (ranges !== -2 && ranges.length === 1) { + debug('range %j', ranges); + + // Content-Range + res.statusCode = 206; + res.setHeader('Content-Range', contentRange('bytes', len, ranges[0])); + + // adjust for requested range + offset += ranges[0].start; + len = ranges[0].end - ranges[0].start + 1; + } + } + + // clone options + for (var prop in options) { + opts[prop] = options[prop]; + } + + // set read options + opts.start = offset; + opts.end = Math.max(offset, offset + len - 1); + + // content-length + res.setHeader('Content-Length', len); + + // HEAD support + if (req.method === 'HEAD') { + res.end(); + return + } + + this.stream(path, opts); + }; + + /** + * Transfer file for `path`. + * + * @param {String} path + * @api private + */ + SendStream.prototype.sendFile = function sendFile (path) { + var i = 0; + var self = this; + + debug('stat "%s"', path); + fs.stat(path, function onstat (err, stat) { + var pathEndsWithSep = path[path.length - 1] === sep; + if (err && err.code === 'ENOENT' && !extname(path) && !pathEndsWithSep) { + // not found, check extensions + return next(err) + } + if (err) return self.onStatError(err) + if (stat.isDirectory()) return self.redirect(path) + if (pathEndsWithSep) return self.error(404) + self.emit('file', path, stat); + self.send(path, stat); + }); + + function next (err) { + if (self._extensions.length <= i) { + return err + ? self.onStatError(err) + : self.error(404) + } + + var p = path + '.' + self._extensions[i++]; + + debug('stat "%s"', p); + fs.stat(p, function (err, stat) { + if (err) return next(err) + if (stat.isDirectory()) return next() + self.emit('file', p, stat); + self.send(p, stat); + }); + } + }; + + /** + * Transfer index for `path`. + * + * @param {String} path + * @api private + */ + SendStream.prototype.sendIndex = function sendIndex (path) { + var i = -1; + var self = this; + + function next (err) { + if (++i >= self._index.length) { + if (err) return self.onStatError(err) + return self.error(404) + } + + var p = join(path, self._index[i]); + + debug('stat "%s"', p); + fs.stat(p, function (err, stat) { + if (err) return next(err) + if (stat.isDirectory()) return next() + self.emit('file', p, stat); + self.send(p, stat); + }); + } + + next(); + }; + + /** + * Stream `path` to the response. + * + * @param {String} path + * @param {Object} options + * @api private + */ + + SendStream.prototype.stream = function stream (path, options) { + var self = this; + var res = this.res; + + // pipe + var stream = fs.createReadStream(path, options); + this.emit('stream', stream); + stream.pipe(res); + + // cleanup + function cleanup () { + stream.destroy(); + } + + // response finished, cleanup + onFinished(res, cleanup); + + // error handling + stream.on('error', function onerror (err) { + // clean up stream early + cleanup(); + + // error + self.onStatError(err); + }); + + // end + stream.on('end', function onend () { + self.emit('end'); + }); + }; + + /** + * Set content-type based on `path` + * if it hasn't been explicitly set. + * + * @param {String} path + * @api private + */ + + SendStream.prototype.type = function type (path) { + var res = this.res; + + if (res.getHeader('Content-Type')) return + + var ext = extname(path); + var type = mime.contentType(ext) || 'application/octet-stream'; + + debug('content-type %s', type); + res.setHeader('Content-Type', type); + }; + + /** + * Set response header fields, most + * fields may be pre-defined. + * + * @param {String} path + * @param {Object} stat + * @api private + */ + + SendStream.prototype.setHeader = function setHeader (path, stat) { + var res = this.res; + + this.emit('headers', res, path, stat); + + if (this._acceptRanges && !res.getHeader('Accept-Ranges')) { + debug('accept ranges'); + res.setHeader('Accept-Ranges', 'bytes'); + } + + if (this._cacheControl && !res.getHeader('Cache-Control')) { + var cacheControl = 'public, max-age=' + Math.floor(this._maxage / 1000); + + if (this._immutable) { + cacheControl += ', immutable'; + } + + debug('cache-control %s', cacheControl); + res.setHeader('Cache-Control', cacheControl); + } + + if (this._lastModified && !res.getHeader('Last-Modified')) { + var modified = stat.mtime.toUTCString(); + debug('modified %s', modified); + res.setHeader('Last-Modified', modified); + } + + if (this._etag && !res.getHeader('ETag')) { + var val = etag(stat); + debug('etag %s', val); + res.setHeader('ETag', val); + } + }; + + /** + * Clear all headers from a response. + * + * @param {object} res + * @private + */ + + function clearHeaders (res) { + for (const header of res.getHeaderNames()) { + res.removeHeader(header); + } + } + + /** + * Collapse all leading slashes into a single slash + * + * @param {string} str + * @private + */ + function collapseLeadingSlashes (str) { + for (var i = 0; i < str.length; i++) { + if (str[i] !== '/') { + break + } + } + + return i > 1 + ? '/' + str.substr(i) + : str + } + + /** + * Determine if path parts contain a dotfile. + * + * @api private + */ + + function containsDotFile (parts) { + for (var i = 0; i < parts.length; i++) { + var part = parts[i]; + if (part.length > 1 && part[0] === '.') { + return true + } + } + + return false + } + + /** + * Create a Content-Range header. + * + * @param {string} type + * @param {number} size + * @param {array} [range] + */ + + function contentRange (type, size, range) { + return type + ' ' + (range ? range.start + '-' + range.end : '*') + '/' + size + } + + /** + * Create a minimal HTML document. + * + * @param {string} title + * @param {string} body + * @private + */ + + function createHtmlDocument (title, body) { + return '\n' + + '\n' + + '\n' + + '\n' + + '' + title + '\n' + + '\n' + + '\n' + + '
' + body + '
\n' + + '\n' + + '\n' + } + + /** + * Create a HttpError object from simple arguments. + * + * @param {number} status + * @param {Error|object} err + * @private + */ + + function createHttpError (status, err) { + if (!err) { + return createError(status) + } + + return err instanceof Error + ? createError(status, err, { expose: false }) + : createError(status, err) + } + + /** + * decodeURIComponent. + * + * Allows V8 to only deoptimize this fn instead of all + * of send(). + * + * @param {String} path + * @api private + */ + + function decode (path) { + try { + return decodeURIComponent(path) + } catch (err) { + return -1 + } + } + + /** + * Determine if emitter has listeners of a given type. + * + * The way to do this check is done three different ways in Node.js >= 0.10 + * so this consolidates them into a minimal set using instance methods. + * + * @param {EventEmitter} emitter + * @param {string} type + * @returns {boolean} + * @private + */ + + function hasListeners (emitter, type) { + var count = typeof emitter.listenerCount !== 'function' + ? emitter.listeners(type).length + : emitter.listenerCount(type); + + return count > 0 + } + + /** + * Normalize the index option into an array. + * + * @param {boolean|string|array} val + * @param {string} name + * @private + */ + + function normalizeList (val, name) { + var list = [].concat(val || []); + + for (var i = 0; i < list.length; i++) { + if (typeof list[i] !== 'string') { + throw new TypeError(name + ' must be array of strings or false') + } + } + + return list + } + + /** + * Parse an HTTP Date into a number. + * + * @param {string} date + * @private + */ + + function parseHttpDate (date) { + var timestamp = date && Date.parse(date); + + return typeof timestamp === 'number' + ? timestamp + : NaN + } + + /** + * Parse a HTTP token list. + * + * @param {string} str + * @private + */ + + function parseTokenList (str) { + var end = 0; + var list = []; + var start = 0; + + // gather tokens + for (var i = 0, len = str.length; i < len; i++) { + switch (str.charCodeAt(i)) { + case 0x20: /* */ + if (start === end) { + start = end = i + 1; + } + break + case 0x2c: /* , */ + if (start !== end) { + list.push(str.substring(start, end)); + } + start = end = i + 1; + break + default: + end = i + 1; + break + } + } + + // final token + if (start !== end) { + list.push(str.substring(start, end)); + } + + return list + } + + /** + * Set an object of headers on a response. + * + * @param {object} res + * @param {object} headers + * @private + */ + + function setHeaders (res, headers) { + var keys = Object.keys(headers); + + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + res.setHeader(key, headers[key]); + } + } + return send_1; +} + +var sendExports = requireSend(); +const send = /*@__PURE__*/getDefaultExportFromCjs(sendExports); + +function createStaticHandler(app, options) { + const client = resolveClientDir(options); + return (req, res, ssr) => { + if (req.url) { + const [urlPath, urlQuery] = req.url.split("?"); + const filePath = path.join(client, app.removeBase(urlPath)); + let isDirectory = false; + try { + isDirectory = fs.lstatSync(filePath).isDirectory(); + } catch { + } + const { trailingSlash = "ignore" } = options; + const hasSlash = urlPath.endsWith("/"); + let pathname = urlPath; + if (app.headersMap && app.headersMap.length > 0) { + const routeData = app.match(req, true); + if (routeData && routeData.prerender) { + const matchedRoute = app.headersMap.find((header) => header.pathname.includes(pathname)); + if (matchedRoute) { + for (const header of matchedRoute.headers) { + res.setHeader(header.key, header.value); + } + } + } + } + switch (trailingSlash) { + case "never": { + if (isDirectory && urlPath !== "/" && hasSlash) { + pathname = urlPath.slice(0, -1) + (urlQuery ? "?" + urlQuery : ""); + res.statusCode = 301; + res.setHeader("Location", pathname); + return res.end(); + } + if (isDirectory && !hasSlash) { + pathname = `${urlPath}/index.html`; + } + break; + } + case "ignore": { + if (isDirectory && !hasSlash) { + pathname = `${urlPath}/index.html`; + } + break; + } + case "always": { + if (!hasSlash && !hasFileExtension(urlPath) && !isInternalPath(urlPath)) { + pathname = urlPath + "/" + (urlQuery ? "?" + urlQuery : ""); + res.statusCode = 301; + res.setHeader("Location", pathname); + return res.end(); + } + break; + } + } + pathname = prependForwardSlash(app.removeBase(pathname)); + const stream = send(req, pathname, { + root: client, + dotfiles: pathname.startsWith("/.well-known/") ? "allow" : "deny" + }); + let forwardError = false; + stream.on("error", (err) => { + if (forwardError) { + console.error(err.toString()); + res.writeHead(500); + res.end("Internal server error"); + return; + } + ssr(); + }); + stream.on("headers", (_res) => { + if (pathname.startsWith(`/${options.assets}/`)) { + _res.setHeader("Cache-Control", "public, max-age=31536000, immutable"); + } + }); + stream.on("file", () => { + forwardError = true; + }); + stream.pipe(res); + } else { + ssr(); + } + }; +} +function resolveClientDir(options) { + const clientURLRaw = new URL(options.client); + const serverURLRaw = new URL(options.server); + const rel = path.relative(url.fileURLToPath(serverURLRaw), url.fileURLToPath(clientURLRaw)); + const serverFolder = path.basename(options.server); + let serverEntryFolderURL = path.dirname(import.meta.url); + while (!serverEntryFolderURL.endsWith(serverFolder)) { + serverEntryFolderURL = path.dirname(serverEntryFolderURL); + } + const serverEntryURL = serverEntryFolderURL + "/entry.mjs"; + const clientURL = new URL(appendForwardSlash(rel), serverEntryURL); + const client = url.fileURLToPath(clientURL); + return client; +} +function prependForwardSlash(pth) { + return pth.startsWith("/") ? pth : "/" + pth; +} +function appendForwardSlash(pth) { + return pth.endsWith("/") ? pth : pth + "/"; +} + +const hostOptions = (host) => { + if (typeof host === "boolean") { + return host ? "0.0.0.0" : "localhost"; + } + return host; +}; +function standalone(app, options) { + const port = process.env.PORT ? Number(process.env.PORT) : options.port ?? 8080; + const host = process.env.HOST ?? hostOptions(options.host); + const handler = createStandaloneHandler(app, options); + const server = createServer(handler, host, port); + server.server.listen(port, host); + if (process.env.ASTRO_NODE_LOGGING !== "disabled") { + logListeningOn(app.getAdapterLogger(), server.server, host); + } + return { + server, + done: server.closed() + }; +} +function createStandaloneHandler(app, options) { + const appHandler = createAppHandler(app, options); + const staticHandler = createStaticHandler(app, options); + return (req, res) => { + try { + decodeURI(req.url); + } catch { + res.writeHead(400); + res.end("Bad request."); + return; + } + staticHandler(req, res, () => appHandler(req, res)); + }; +} +function createServer(listener, host, port) { + let httpServer; + if (process.env.SERVER_CERT_PATH && process.env.SERVER_KEY_PATH) { + httpServer = https.createServer( + { + key: fs.readFileSync(process.env.SERVER_KEY_PATH), + cert: fs.readFileSync(process.env.SERVER_CERT_PATH) + }, + listener + ); + } else { + httpServer = require$$2.createServer(listener); + } + enableDestroy(httpServer); + const closed = new Promise((resolve, reject) => { + httpServer.addListener("close", resolve); + httpServer.addListener("error", reject); + }); + const previewable = { + host, + port, + closed() { + return closed; + }, + async stop() { + await new Promise((resolve, reject) => { + httpServer.destroy((err) => err ? reject(err) : resolve(void 0)); + }); + } + }; + return { + server: httpServer, + ...previewable + }; +} + +function createExports(manifest, options) { + const app = new NodeApp(manifest, !options.experimentalDisableStreaming); + let headersMap = void 0; + if (options.experimentalStaticHeaders) { + headersMap = readHeadersJson(manifest.outDir); + } + if (headersMap) { + app.setHeadersMap(headersMap); + } + options.trailingSlash = manifest.trailingSlash; + return { + options, + handler: options.mode === "middleware" ? createMiddleware(app, options) : createStandaloneHandler(app, options), + startServer: () => standalone(app, options) + }; +} +function start(manifest, options) { + if (options.mode !== "standalone" || process.env.ASTRO_NODE_AUTOSTART === "disabled") { + return; + } + let headersMap = void 0; + if (options.experimentalStaticHeaders) { + headersMap = readHeadersJson(manifest.outDir); + } + const app = new NodeApp(manifest, !options.experimentalDisableStreaming); + if (headersMap) { + app.setHeadersMap(headersMap); + } + standalone(app, options); +} +function readHeadersJson(outDir) { + let headersMap = void 0; + const headersUrl = new URL(STATIC_HEADERS_FILE, outDir); + if (existsSync(headersUrl)) { + const content = readFileSync(headersUrl, "utf-8"); + try { + headersMap = JSON.parse(content); + } catch (e) { + console.error("[@astrojs/node] Error parsing _headers.json: " + e.message); + console.error("[@astrojs/node] Please make sure your _headers.json is valid JSON."); + } + } + return headersMap; +} + +const serverEntrypointModule = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ + __proto__: null, + createExports, + start +}, Symbol.toStringTag, { value: 'Module' })); + +export { start as a, createExports as c, serverEntrypointModule as s }; diff --git a/workbench/astro/dist/server/chunks/_commonjsHelpers_BFTU3MAI.mjs b/workbench/astro/dist/server/chunks/_commonjsHelpers_BFTU3MAI.mjs new file mode 100644 index 000000000..004412e51 --- /dev/null +++ b/workbench/astro/dist/server/chunks/_commonjsHelpers_BFTU3MAI.mjs @@ -0,0 +1,7 @@ +var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + +function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; +} + +export { commonjsGlobal as c, getDefaultExportFromCjs as g }; diff --git a/workbench/astro/dist/server/chunks/astro-designed-error-pages_pFA87nEA.mjs b/workbench/astro/dist/server/chunks/astro-designed-error-pages_pFA87nEA.mjs new file mode 100644 index 000000000..1510a1eb0 --- /dev/null +++ b/workbench/astro/dist/server/chunks/astro-designed-error-pages_pFA87nEA.mjs @@ -0,0 +1,364 @@ +import { ai as NOOP_MIDDLEWARE_HEADER, aj as REDIRECT_STATUS_CODES, A as AstroError, ak as ActionsReturnedInvalidDataError, Q as DEFAULT_404_COMPONENT } from './astro/server_DhWKww_t.mjs'; +import { parse, stringify } from 'devalue'; +import { escape } from 'html-escaper'; + +const NOOP_MIDDLEWARE_FN = async (_ctx, next) => { + const response = await next(); + response.headers.set(NOOP_MIDDLEWARE_HEADER, "true"); + return response; +}; + +const ACTION_QUERY_PARAMS$1 = { + actionName: "_action"}; +const ACTION_RPC_ROUTE_PATTERN = "/_actions/[...path]"; + +const __vite_import_meta_env__ = {"ASSETS_PREFIX": undefined, "BASE_URL": "/", "DEV": false, "MODE": "production", "PROD": true, "SITE": undefined, "SSR": true}; +const ACTION_QUERY_PARAMS = ACTION_QUERY_PARAMS$1; +const codeToStatusMap = { + // Implemented from IANA HTTP Status Code Registry + // https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml + BAD_REQUEST: 400, + UNAUTHORIZED: 401, + PAYMENT_REQUIRED: 402, + FORBIDDEN: 403, + NOT_FOUND: 404, + METHOD_NOT_ALLOWED: 405, + NOT_ACCEPTABLE: 406, + PROXY_AUTHENTICATION_REQUIRED: 407, + REQUEST_TIMEOUT: 408, + CONFLICT: 409, + GONE: 410, + LENGTH_REQUIRED: 411, + PRECONDITION_FAILED: 412, + CONTENT_TOO_LARGE: 413, + URI_TOO_LONG: 414, + UNSUPPORTED_MEDIA_TYPE: 415, + RANGE_NOT_SATISFIABLE: 416, + EXPECTATION_FAILED: 417, + MISDIRECTED_REQUEST: 421, + UNPROCESSABLE_CONTENT: 422, + LOCKED: 423, + FAILED_DEPENDENCY: 424, + TOO_EARLY: 425, + UPGRADE_REQUIRED: 426, + PRECONDITION_REQUIRED: 428, + TOO_MANY_REQUESTS: 429, + REQUEST_HEADER_FIELDS_TOO_LARGE: 431, + UNAVAILABLE_FOR_LEGAL_REASONS: 451, + INTERNAL_SERVER_ERROR: 500, + NOT_IMPLEMENTED: 501, + BAD_GATEWAY: 502, + SERVICE_UNAVAILABLE: 503, + GATEWAY_TIMEOUT: 504, + HTTP_VERSION_NOT_SUPPORTED: 505, + VARIANT_ALSO_NEGOTIATES: 506, + INSUFFICIENT_STORAGE: 507, + LOOP_DETECTED: 508, + NETWORK_AUTHENTICATION_REQUIRED: 511 +}; +const statusToCodeMap = Object.entries(codeToStatusMap).reduce( + // reverse the key-value pairs + (acc, [key, value]) => ({ ...acc, [value]: key }), + {} +); +class ActionError extends Error { + type = "AstroActionError"; + code = "INTERNAL_SERVER_ERROR"; + status = 500; + constructor(params) { + super(params.message); + this.code = params.code; + this.status = ActionError.codeToStatus(params.code); + if (params.stack) { + this.stack = params.stack; + } + } + static codeToStatus(code) { + return codeToStatusMap[code]; + } + static statusToCode(status) { + return statusToCodeMap[status] ?? "INTERNAL_SERVER_ERROR"; + } + static fromJson(body) { + if (isInputError(body)) { + return new ActionInputError(body.issues); + } + if (isActionError(body)) { + return new ActionError(body); + } + return new ActionError({ + code: "INTERNAL_SERVER_ERROR" + }); + } +} +function isActionError(error) { + return typeof error === "object" && error != null && "type" in error && error.type === "AstroActionError"; +} +function isInputError(error) { + return typeof error === "object" && error != null && "type" in error && error.type === "AstroActionInputError" && "issues" in error && Array.isArray(error.issues); +} +class ActionInputError extends ActionError { + type = "AstroActionInputError"; + // We don't expose all ZodError properties. + // Not all properties will serialize from server to client, + // and we don't want to import the full ZodError object into the client. + issues; + fields; + constructor(issues) { + super({ + message: `Failed to validate: ${JSON.stringify(issues, null, 2)}`, + code: "BAD_REQUEST" + }); + this.issues = issues; + this.fields = {}; + for (const issue of issues) { + if (issue.path.length > 0) { + const key = issue.path[0].toString(); + this.fields[key] ??= []; + this.fields[key]?.push(issue.message); + } + } + } +} +function getActionQueryString(name) { + const searchParams = new URLSearchParams({ [ACTION_QUERY_PARAMS$1.actionName]: name }); + return `?${searchParams.toString()}`; +} +function serializeActionResult(res) { + if (res.error) { + if (Object.assign(__vite_import_meta_env__, {})?.DEV) { + actionResultErrorStack.set(res.error.stack); + } + let body2; + if (res.error instanceof ActionInputError) { + body2 = { + type: res.error.type, + issues: res.error.issues, + fields: res.error.fields + }; + } else { + body2 = { + ...res.error, + message: res.error.message + }; + } + return { + type: "error", + status: res.error.status, + contentType: "application/json", + body: JSON.stringify(body2) + }; + } + if (res.data === void 0) { + return { + type: "empty", + status: 204 + }; + } + let body; + try { + body = stringify(res.data, { + // Add support for URL objects + URL: (value) => value instanceof URL && value.href + }); + } catch (e) { + let hint = ActionsReturnedInvalidDataError.hint; + if (res.data instanceof Response) { + hint = REDIRECT_STATUS_CODES.includes(res.data.status) ? "If you need to redirect when the action succeeds, trigger a redirect where the action is called. See the Actions guide for server and client redirect examples: https://docs.astro.build/en/guides/actions." : "If you need to return a Response object, try using a server endpoint instead. See https://docs.astro.build/en/guides/endpoints/#server-endpoints-api-routes"; + } + throw new AstroError({ + ...ActionsReturnedInvalidDataError, + message: ActionsReturnedInvalidDataError.message(String(e)), + hint + }); + } + return { + type: "data", + status: 200, + contentType: "application/json+devalue", + body + }; +} +function deserializeActionResult(res) { + if (res.type === "error") { + let json; + try { + json = JSON.parse(res.body); + } catch { + return { + data: void 0, + error: new ActionError({ + message: res.body, + code: "INTERNAL_SERVER_ERROR" + }) + }; + } + if (Object.assign(__vite_import_meta_env__, {})?.PROD) { + return { error: ActionError.fromJson(json), data: void 0 }; + } else { + const error = ActionError.fromJson(json); + error.stack = actionResultErrorStack.get(); + return { + error, + data: void 0 + }; + } + } + if (res.type === "empty") { + return { data: void 0, error: void 0 }; + } + return { + data: parse(res.body, { + URL: (href) => new URL(href) + }), + error: void 0 + }; +} +const actionResultErrorStack = /* @__PURE__ */ (function actionResultErrorStackFn() { + let errorStack; + return { + set(stack) { + errorStack = stack; + }, + get() { + return errorStack; + } + }; +})(); + +function template({ + title, + pathname, + statusCode = 404, + tabTitle, + body +}) { + return ` + + + + ${tabTitle} + + + +
+ +

${statusCode ? `${statusCode}: ` : ""}${title}

+ ${body || ` +
Path: ${escape(pathname)}
+ `} +
+ +`; +} + +const DEFAULT_404_ROUTE = { + component: DEFAULT_404_COMPONENT, + generate: () => "", + params: [], + pattern: /^\/404\/?$/, + prerender: false, + pathname: "/404", + segments: [[{ content: "404", dynamic: false, spread: false }]], + type: "page", + route: "/404", + fallbackRoutes: [], + isIndex: false, + origin: "internal" +}; +function ensure404Route(manifest) { + if (!manifest.routes.some((route) => route.route === "/404")) { + manifest.routes.push(DEFAULT_404_ROUTE); + } + return manifest; +} +async function default404Page({ pathname }) { + return new Response( + template({ + statusCode: 404, + title: "Not found", + tabTitle: "404: Not Found", + pathname + }), + { status: 404, headers: { "Content-Type": "text/html" } } + ); +} +default404Page.isAstroComponentFactory = true; +const default404Instance = { + default: default404Page +}; + +export { ActionError as A, DEFAULT_404_ROUTE as D, NOOP_MIDDLEWARE_FN as N, ACTION_RPC_ROUTE_PATTERN as a, ACTION_QUERY_PARAMS as b, default404Instance as c, deserializeActionResult as d, ensure404Route as e, getActionQueryString as g, serializeActionResult as s }; diff --git a/workbench/astro/dist/server/chunks/astro/server_DhWKww_t.mjs b/workbench/astro/dist/server/chunks/astro/server_DhWKww_t.mjs new file mode 100644 index 000000000..6d5dfd99f --- /dev/null +++ b/workbench/astro/dist/server/chunks/astro/server_DhWKww_t.mjs @@ -0,0 +1,2766 @@ +import colors from 'picocolors'; +import { clsx } from 'clsx'; +import { escape } from 'html-escaper'; +import { decodeBase64, encodeBase64, decodeHex, encodeHexUpperCase } from '@oslojs/encoding'; +import { z } from 'zod'; +import 'cssesc'; + +const ASTRO_VERSION = "5.15.6"; +const REROUTE_DIRECTIVE_HEADER = "X-Astro-Reroute"; +const REWRITE_DIRECTIVE_HEADER_KEY = "X-Astro-Rewrite"; +const REWRITE_DIRECTIVE_HEADER_VALUE = "yes"; +const NOOP_MIDDLEWARE_HEADER = "X-Astro-Noop"; +const ROUTE_TYPE_HEADER = "X-Astro-Route-Type"; +const DEFAULT_404_COMPONENT = "astro-default-404.astro"; +const REDIRECT_STATUS_CODES = [301, 302, 303, 307, 308, 300, 304]; +const REROUTABLE_STATUS_CODES = [404, 500]; +const clientAddressSymbol = Symbol.for("astro.clientAddress"); +const originPathnameSymbol = Symbol.for("astro.originPathname"); +const nodeRequestAbortControllerCleanupSymbol = Symbol.for( + "astro.nodeRequestAbortControllerCleanup" +); +const responseSentSymbol = Symbol.for("astro.responseSent"); + +const ClientAddressNotAvailable = { + name: "ClientAddressNotAvailable", + title: "`Astro.clientAddress` is not available in current adapter.", + message: (adapterName) => `\`Astro.clientAddress\` is not available in the \`${adapterName}\` adapter. File an issue with the adapter to add support.` +}; +const PrerenderClientAddressNotAvailable = { + name: "PrerenderClientAddressNotAvailable", + title: "`Astro.clientAddress` cannot be used inside prerendered routes.", + message: (name) => `\`Astro.clientAddress\` cannot be used inside prerendered route ${name}` +}; +const StaticClientAddressNotAvailable = { + name: "StaticClientAddressNotAvailable", + title: "`Astro.clientAddress` is not available in prerendered pages.", + message: "`Astro.clientAddress` is only available on pages that are server-rendered.", + hint: "See https://docs.astro.build/en/guides/on-demand-rendering/ for more information on how to enable SSR." +}; +const NoMatchingStaticPathFound = { + name: "NoMatchingStaticPathFound", + title: "No static path found for requested path.", + message: (pathName) => `A \`getStaticPaths()\` route pattern was matched, but no matching static path was found for requested path \`${pathName}\`.`, + hint: (possibleRoutes) => `Possible dynamic routes being matched: ${possibleRoutes.join(", ")}.` +}; +const OnlyResponseCanBeReturned = { + name: "OnlyResponseCanBeReturned", + title: "Invalid type returned by Astro page.", + message: (route, returnedValue) => `Route \`${route ? route : ""}\` returned a \`${returnedValue}\`. Only a [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) can be returned from Astro files.`, + hint: "See https://docs.astro.build/en/guides/on-demand-rendering/#response for more information." +}; +const MissingMediaQueryDirective = { + name: "MissingMediaQueryDirective", + title: "Missing value for `client:media` directive.", + message: 'Media query not provided for `client:media` directive. A media query similar to `client:media="(max-width: 600px)"` must be provided' +}; +const NoMatchingRenderer = { + name: "NoMatchingRenderer", + title: "No matching renderer found.", + message: (componentName, componentExtension, plural, validRenderersCount) => `Unable to render \`${componentName}\`. + +${validRenderersCount > 0 ? `There ${plural ? "are" : "is"} ${validRenderersCount} renderer${plural ? "s" : ""} configured in your \`astro.config.mjs\` file, +but ${plural ? "none were" : "it was not"} able to server-side render \`${componentName}\`.` : `No valid renderer was found ${componentExtension ? `for the \`.${componentExtension}\` file extension.` : `for this file extension.`}`}`, + hint: (probableRenderers) => `Did you mean to enable the ${probableRenderers} integration? + +See https://docs.astro.build/en/guides/framework-components/ for more information on how to install and configure integrations.` +}; +const NoClientOnlyHint = { + name: "NoClientOnlyHint", + title: "Missing hint on client:only directive.", + message: (componentName) => `Unable to render \`${componentName}\`. When using the \`client:only\` hydration strategy, Astro needs a hint to use the correct renderer.`, + hint: (probableRenderers) => `Did you mean to pass \`client:only="${probableRenderers}"\`? See https://docs.astro.build/en/reference/directives-reference/#clientonly for more information on client:only` +}; +const InvalidGetStaticPathsEntry = { + name: "InvalidGetStaticPathsEntry", + title: "Invalid entry inside getStaticPath's return value", + message: (entryType) => `Invalid entry returned by getStaticPaths. Expected an object, got \`${entryType}\``, + hint: "If you're using a `.map` call, you might be looking for `.flatMap()` instead. See https://docs.astro.build/en/reference/routing-reference/#getstaticpaths for more information on getStaticPaths." +}; +const InvalidGetStaticPathsReturn = { + name: "InvalidGetStaticPathsReturn", + title: "Invalid value returned by getStaticPaths.", + message: (returnType) => `Invalid type returned by \`getStaticPaths\`. Expected an \`array\`, got \`${returnType}\``, + hint: "See https://docs.astro.build/en/reference/routing-reference/#getstaticpaths for more information on getStaticPaths." +}; +const GetStaticPathsExpectedParams = { + name: "GetStaticPathsExpectedParams", + title: "Missing params property on `getStaticPaths` route.", + message: "Missing or empty required `params` property on `getStaticPaths` route.", + hint: "See https://docs.astro.build/en/reference/routing-reference/#getstaticpaths for more information on getStaticPaths." +}; +const GetStaticPathsInvalidRouteParam = { + name: "GetStaticPathsInvalidRouteParam", + title: "Invalid value for `getStaticPaths` route parameter.", + message: (key, value, valueType) => `Invalid getStaticPaths route parameter for \`${key}\`. Expected undefined, a string or a number, received \`${valueType}\` (\`${value}\`)`, + hint: "See https://docs.astro.build/en/reference/routing-reference/#getstaticpaths for more information on getStaticPaths." +}; +const GetStaticPathsRequired = { + name: "GetStaticPathsRequired", + title: "`getStaticPaths()` function required for dynamic routes.", + message: "`getStaticPaths()` function is required for dynamic routes. Make sure that you `export` a `getStaticPaths` function from your dynamic route.", + hint: `See https://docs.astro.build/en/guides/routing/#dynamic-routes for more information on dynamic routes. + + If you meant for this route to be server-rendered, set \`export const prerender = false;\` in the page.` +}; +const ReservedSlotName = { + name: "ReservedSlotName", + title: "Invalid slot name.", + message: (slotName) => `Unable to create a slot named \`${slotName}\`. \`${slotName}\` is a reserved slot name. Please update the name of this slot.` +}; +const NoMatchingImport = { + name: "NoMatchingImport", + title: "No import found for component.", + message: (componentName) => `Could not render \`${componentName}\`. No matching import has been found for \`${componentName}\`.`, + hint: "Please make sure the component is properly imported." +}; +const InvalidComponentArgs = { + name: "InvalidComponentArgs", + title: "Invalid component arguments.", + message: (name) => `Invalid arguments passed to${name ? ` <${name}>` : ""} component.`, + hint: "Astro components cannot be rendered directly via function call, such as `Component()` or `{items.map(Component)}`." +}; +const PageNumberParamNotFound = { + name: "PageNumberParamNotFound", + title: "Page number param not found.", + message: (paramName) => `[paginate()] page number param \`${paramName}\` not found in your filepath.`, + hint: "Rename your file to `[page].astro` or `[...page].astro`." +}; +const ImageMissingAlt = { + name: "ImageMissingAlt", + title: 'Image missing required "alt" property.', + message: 'Image missing "alt" property. "alt" text is required to describe important images on the page.', + hint: 'Use an empty string ("") for decorative images.' +}; +const InvalidImageService = { + name: "InvalidImageService", + title: "Error while loading image service.", + message: "There was an error loading the configured image service. Please see the stack trace for more information." +}; +const MissingImageDimension = { + name: "MissingImageDimension", + title: "Missing image dimensions", + message: (missingDimension, imageURL) => `Missing ${missingDimension === "both" ? "width and height attributes" : `${missingDimension} attribute`} for ${imageURL}. When using remote images, both dimensions are required in order to avoid CLS.`, + hint: "If your image is inside your `src` folder, you probably meant to import it instead. See [the Imports guide for more information](https://docs.astro.build/en/guides/imports/#other-assets). You can also use `inferSize={true}` for remote images to get the original dimensions." +}; +const FailedToFetchRemoteImageDimensions = { + name: "FailedToFetchRemoteImageDimensions", + title: "Failed to retrieve remote image dimensions", + message: (imageURL) => `Failed to get the dimensions for ${imageURL}.`, + hint: "Verify your remote image URL is accurate, and that you are not using `inferSize` with a file located in your `public/` folder." +}; +const UnsupportedImageFormat = { + name: "UnsupportedImageFormat", + title: "Unsupported image format", + message: (format, imagePath, supportedFormats) => `Received unsupported format \`${format}\` from \`${imagePath}\`. Currently only ${supportedFormats.join( + ", " + )} are supported by our image services.`, + hint: "Using an `img` tag directly instead of the `Image` component might be what you're looking for." +}; +const UnsupportedImageConversion = { + name: "UnsupportedImageConversion", + title: "Unsupported image conversion", + message: "Converting between vector (such as SVGs) and raster (such as PNGs and JPEGs) images is not currently supported." +}; +const PrerenderDynamicEndpointPathCollide = { + name: "PrerenderDynamicEndpointPathCollide", + title: "Prerendered dynamic endpoint has path collision.", + message: (pathname) => `Could not render \`${pathname}\` with an \`undefined\` param as the generated path will collide during prerendering. Prevent passing \`undefined\` as \`params\` for the endpoint's \`getStaticPaths()\` function, or add an additional extension to the endpoint's filename.`, + hint: (filename) => `Rename \`${filename}\` to \`${filename.replace(/\.(?:js|ts)/, (m) => `.json` + m)}\`` +}; +const ExpectedImage = { + name: "ExpectedImage", + title: "Expected src to be an image.", + message: (src, typeofOptions, fullOptions) => `Expected \`src\` property for \`getImage\` or \`\` to be either an ESM imported image or a string with the path of a remote image. Received \`${src}\` (type: \`${typeofOptions}\`). + +Full serialized options received: \`${fullOptions}\`.`, + hint: "This error can often happen because of a wrong path. Make sure the path to your image is correct. If you're passing an async function, make sure to call and await it." +}; +const ExpectedImageOptions = { + name: "ExpectedImageOptions", + title: "Expected image options.", + message: (options) => `Expected getImage() parameter to be an object. Received \`${options}\`.` +}; +const ExpectedNotESMImage = { + name: "ExpectedNotESMImage", + title: "Expected image options, not an ESM-imported image.", + message: "An ESM-imported image cannot be passed directly to `getImage()`. Instead, pass an object with the image in the `src` property.", + hint: "Try changing `getImage(myImage)` to `getImage({ src: myImage })`" +}; +const IncompatibleDescriptorOptions = { + name: "IncompatibleDescriptorOptions", + title: "Cannot set both `densities` and `widths`", + message: "Only one of `densities` or `widths` can be specified. In most cases, you'll probably want to use only `widths` if you require specific widths.", + hint: "Those attributes are used to construct a `srcset` attribute, which cannot have both `x` and `w` descriptors." +}; +const NoImageMetadata = { + name: "NoImageMetadata", + title: "Could not process image metadata.", + message: (imagePath) => `Could not process image metadata${imagePath ? ` for \`${imagePath}\`` : ""}.`, + hint: "This is often caused by a corrupted or malformed image. Re-exporting the image from your image editor may fix this issue." +}; +const ResponseSentError = { + name: "ResponseSentError", + title: "Unable to set response.", + message: "The response has already been sent to the browser and cannot be altered." +}; +const MiddlewareNoDataOrNextCalled = { + name: "MiddlewareNoDataOrNextCalled", + title: "The middleware didn't return a `Response`.", + message: "Make sure your middleware returns a `Response` object, either directly or by returning the `Response` from calling the `next` function." +}; +const MiddlewareNotAResponse = { + name: "MiddlewareNotAResponse", + title: "The middleware returned something that is not a `Response` object.", + message: "Any data returned from middleware must be a valid `Response` object." +}; +const EndpointDidNotReturnAResponse = { + name: "EndpointDidNotReturnAResponse", + title: "The endpoint did not return a `Response`.", + message: "An endpoint must return either a `Response`, or a `Promise` that resolves with a `Response`." +}; +const LocalsNotAnObject = { + name: "LocalsNotAnObject", + title: "Value assigned to `locals` is not accepted.", + message: "`locals` can only be assigned to an object. Other values like numbers, strings, etc. are not accepted.", + hint: "If you tried to remove some information from the `locals` object, try to use `delete` or set the property to `undefined`." +}; +const LocalsReassigned = { + name: "LocalsReassigned", + title: "`locals` must not be reassigned.", + message: "`locals` can not be assigned directly.", + hint: "Set a `locals` property instead." +}; +const AstroResponseHeadersReassigned = { + name: "AstroResponseHeadersReassigned", + title: "`Astro.response.headers` must not be reassigned.", + message: "Individual headers can be added to and removed from `Astro.response.headers`, but it must not be replaced with another instance of `Headers` altogether.", + hint: "Consider using `Astro.response.headers.add()`, and `Astro.response.headers.delete()`." +}; +const LocalImageUsedWrongly = { + name: "LocalImageUsedWrongly", + title: "Local images must be imported.", + message: (imageFilePath) => `\`Image\`'s and \`getImage\`'s \`src\` parameter must be an imported image or an URL, it cannot be a string filepath. Received \`${imageFilePath}\`.`, + hint: "If you want to use an image from your `src` folder, you need to either import it or if the image is coming from a content collection, use the [image() schema helper](https://docs.astro.build/en/guides/images/#images-in-content-collections). See https://docs.astro.build/en/guides/images/#src-required for more information on the `src` property." +}; +const AstroGlobUsedOutside = { + name: "AstroGlobUsedOutside", + title: "Astro.glob() used outside of an Astro file.", + message: (globStr) => `\`Astro.glob(${globStr})\` can only be used in \`.astro\` files. \`import.meta.glob(${globStr})\` can be used instead to achieve a similar result.`, + hint: "See Vite's documentation on `import.meta.glob` for more information: https://vite.dev/guide/features.html#glob-import" +}; +const AstroGlobNoMatch = { + name: "AstroGlobNoMatch", + title: "Astro.glob() did not match any files.", + message: (globStr) => `\`Astro.glob(${globStr})\` did not return any matching files.`, + hint: "Check the pattern for typos." +}; +const MissingSharp = { + name: "MissingSharp", + title: "Could not find Sharp.", + message: "Could not find Sharp. Please install Sharp (`sharp`) manually into your project or migrate to another image service.", + hint: "See Sharp's installation instructions for more information: https://sharp.pixelplumbing.com/install. If you are not relying on `astro:assets` to optimize, transform, or process any images, you can configure a passthrough image service instead of installing Sharp. See https://docs.astro.build/en/reference/errors/missing-sharp for more information.\n\nSee https://docs.astro.build/en/guides/images/#default-image-service for more information on how to migrate to another image service." +}; +const i18nNoLocaleFoundInPath = { + name: "i18nNoLocaleFoundInPath", + title: "The path doesn't contain any locale", + message: "You tried to use an i18n utility on a path that doesn't contain any locale. You can use `pathHasLocale` first to determine if the path has a locale." +}; +const RewriteWithBodyUsed = { + name: "RewriteWithBodyUsed", + title: "Cannot use Astro.rewrite after the request body has been read", + message: "Astro.rewrite() cannot be used if the request body has already been read. If you need to read the body, first clone the request." +}; +const ForbiddenRewrite = { + name: "ForbiddenRewrite", + title: "Forbidden rewrite to a static route.", + message: (from, to, component) => `You tried to rewrite the on-demand route '${from}' with the static route '${to}', when using the 'server' output. + +The static route '${to}' is rendered by the component +'${component}', which is marked as prerendered. This is a forbidden operation because during the build the component '${component}' is compiled to an +HTML file, which can't be retrieved at runtime by Astro.`, + hint: (component) => `Add \`export const prerender = false\` to the component '${component}', or use a Astro.redirect().` +}; +const ExperimentalFontsNotEnabled = { + name: "ExperimentalFontsNotEnabled", + title: "Experimental fonts are not enabled", + message: "The Font component is used but experimental fonts have not been registered in the config.", + hint: "Check that you have enabled experimental fonts and also configured your preferred fonts." +}; +const FontFamilyNotFound = { + name: "FontFamilyNotFound", + title: "Font family not found", + message: (family) => `No data was found for the \`"${family}"\` family passed to the \`\` component.`, + hint: "This is often caused by a typo. Check that the `` component or `getFontData()` function are using a `cssVariable` specified in your config." +}; +const CspNotEnabled = { + name: "CspNotEnabled", + title: "CSP feature isn't enabled", + message: "The `experimental.csp` configuration isn't enabled." +}; +const ActionsReturnedInvalidDataError = { + name: "ActionsReturnedInvalidDataError", + title: "Action handler returned invalid data.", + message: (error) => `Action handler returned invalid data. Handlers should return serializable data types like objects, arrays, strings, and numbers. Parse error: ${error}`, + hint: "See the devalue library for all supported types: https://github.com/rich-harris/devalue" +}; +const ActionNotFoundError = { + name: "ActionNotFoundError", + title: "Action not found.", + message: (actionName) => `The server received a request for an action named \`${actionName}\` but could not find a match. If you renamed an action, check that you've updated your \`actions/index\` file and your calling code to match.`, + hint: "You can run `astro check` to detect type errors caused by mismatched action names." +}; +const SessionStorageInitError = { + name: "SessionStorageInitError", + title: "Session storage could not be initialized.", + message: (error, driver) => `Error when initializing session storage${driver ? ` with driver \`${driver}\`` : ""}. \`${error ?? ""}\``, + hint: "For more information, see https://docs.astro.build/en/guides/sessions/" +}; +const SessionStorageSaveError = { + name: "SessionStorageSaveError", + title: "Session data could not be saved.", + message: (error, driver) => `Error when saving session data${driver ? ` with driver \`${driver}\`` : ""}. \`${error ?? ""}\``, + hint: "For more information, see https://docs.astro.build/en/guides/sessions/" +}; + +function normalizeLF(code) { + return code.replace(/\r\n|\r(?!\n)|\n/g, "\n"); +} + +function codeFrame(src, loc) { + if (!loc || loc.line === void 0 || loc.column === void 0) { + return ""; + } + const lines = normalizeLF(src).split("\n").map((ln) => ln.replace(/\t/g, " ")); + const visibleLines = []; + for (let n = -2; n <= 2; n++) { + if (lines[loc.line + n]) visibleLines.push(loc.line + n); + } + let gutterWidth = 0; + for (const lineNo of visibleLines) { + let w = `> ${lineNo}`; + if (w.length > gutterWidth) gutterWidth = w.length; + } + let output = ""; + for (const lineNo of visibleLines) { + const isFocusedLine = lineNo === loc.line - 1; + output += isFocusedLine ? "> " : " "; + output += `${lineNo + 1} | ${lines[lineNo]} +`; + if (isFocusedLine) + output += `${Array.from({ length: gutterWidth }).join(" ")} | ${Array.from({ + length: loc.column + }).join(" ")}^ +`; + } + return output; +} + +class AstroError extends Error { + loc; + title; + hint; + frame; + type = "AstroError"; + constructor(props, options) { + const { name, title, message, stack, location, hint, frame } = props; + super(message, options); + this.title = title; + this.name = name; + if (message) this.message = message; + this.stack = stack ? stack : this.stack; + this.loc = location; + this.hint = hint; + this.frame = frame; + } + setLocation(location) { + this.loc = location; + } + setName(name) { + this.name = name; + } + setMessage(message) { + this.message = message; + } + setHint(hint) { + this.hint = hint; + } + setFrame(source, location) { + this.frame = codeFrame(source, location); + } + static is(err) { + return err.type === "AstroError"; + } +} + +function validateArgs(args) { + if (args.length !== 3) return false; + if (!args[0] || typeof args[0] !== "object") return false; + return true; +} +function baseCreateComponent(cb, moduleId, propagation) { + const name = moduleId?.split("/").pop()?.replace(".astro", "") ?? ""; + const fn = (...args) => { + if (!validateArgs(args)) { + throw new AstroError({ + ...InvalidComponentArgs, + message: InvalidComponentArgs.message(name) + }); + } + return cb(...args); + }; + Object.defineProperty(fn, "name", { value: name, writable: false }); + fn.isAstroComponentFactory = true; + fn.moduleId = moduleId; + fn.propagation = propagation; + return fn; +} +function createComponentWithOptions(opts) { + const cb = baseCreateComponent(opts.factory, opts.moduleId, opts.propagation); + return cb; +} +function createComponent(arg1, moduleId, propagation) { + if (typeof arg1 === "function") { + return baseCreateComponent(arg1, moduleId, propagation); + } else { + return createComponentWithOptions(arg1); + } +} + +function createAstroGlobFn() { + const globHandler = (importMetaGlobResult) => { + console.warn(`Astro.glob is deprecated and will be removed in a future major version of Astro. +Use import.meta.glob instead: https://vitejs.dev/guide/features.html#glob-import`); + if (typeof importMetaGlobResult === "string") { + throw new AstroError({ + ...AstroGlobUsedOutside, + message: AstroGlobUsedOutside.message(JSON.stringify(importMetaGlobResult)) + }); + } + let allEntries = [...Object.values(importMetaGlobResult)]; + if (allEntries.length === 0) { + throw new AstroError({ + ...AstroGlobNoMatch, + message: AstroGlobNoMatch.message(JSON.stringify(importMetaGlobResult)) + }); + } + return Promise.all(allEntries.map((fn) => fn())); + }; + return globHandler; +} +function createAstro(site) { + return { + site: void 0, + generator: `Astro v${ASTRO_VERSION}`, + glob: createAstroGlobFn() + }; +} + +async function renderEndpoint(mod, context, isPrerendered, logger) { + const { request, url } = context; + const method = request.method.toUpperCase(); + let handler = mod[method] ?? mod["ALL"]; + if (!handler && method === "HEAD" && mod["GET"]) { + handler = mod["GET"]; + } + if (isPrerendered && !["GET", "HEAD"].includes(method)) { + logger.warn( + "router", + `${url.pathname} ${colors.bold( + method + )} requests are not available in static endpoints. Mark this page as server-rendered (\`export const prerender = false;\`) or update your config to \`output: 'server'\` to make all your pages server-rendered by default.` + ); + } + if (handler === void 0) { + logger.warn( + "router", + `No API Route handler exists for the method "${method}" for the route "${url.pathname}". +Found handlers: ${Object.keys(mod).map((exp) => JSON.stringify(exp)).join(", ")} +` + ("all" in mod ? `One of the exported handlers is "all" (lowercase), did you mean to export 'ALL'? +` : "") + ); + return new Response(null, { status: 404 }); + } + if (typeof handler !== "function") { + logger.error( + "router", + `The route "${url.pathname}" exports a value for the method "${method}", but it is of the type ${typeof handler} instead of a function.` + ); + return new Response(null, { status: 500 }); + } + let response = await handler.call(mod, context); + if (!response || response instanceof Response === false) { + throw new AstroError(EndpointDidNotReturnAResponse); + } + if (REROUTABLE_STATUS_CODES.includes(response.status)) { + try { + response.headers.set(REROUTE_DIRECTIVE_HEADER, "no"); + } catch (err) { + if (err.message?.includes("immutable")) { + response = new Response(response.body, response); + response.headers.set(REROUTE_DIRECTIVE_HEADER, "no"); + } else { + throw err; + } + } + } + if (method === "HEAD") { + return new Response(null, response); + } + return response; +} + +function isPromise(value) { + return !!value && typeof value === "object" && "then" in value && typeof value.then === "function"; +} +async function* streamAsyncIterator(stream) { + const reader = stream.getReader(); + try { + while (true) { + const { done, value } = await reader.read(); + if (done) return; + yield value; + } + } finally { + reader.releaseLock(); + } +} + +const escapeHTML = escape; +class HTMLBytes extends Uint8Array { +} +Object.defineProperty(HTMLBytes.prototype, Symbol.toStringTag, { + get() { + return "HTMLBytes"; + } +}); +class HTMLString extends String { + get [Symbol.toStringTag]() { + return "HTMLString"; + } +} +const markHTMLString = (value) => { + if (value instanceof HTMLString) { + return value; + } + if (typeof value === "string") { + return new HTMLString(value); + } + return value; +}; +function isHTMLString(value) { + return Object.prototype.toString.call(value) === "[object HTMLString]"; +} +function markHTMLBytes(bytes) { + return new HTMLBytes(bytes); +} +function hasGetReader(obj) { + return typeof obj.getReader === "function"; +} +async function* unescapeChunksAsync(iterable) { + if (hasGetReader(iterable)) { + for await (const chunk of streamAsyncIterator(iterable)) { + yield unescapeHTML(chunk); + } + } else { + for await (const chunk of iterable) { + yield unescapeHTML(chunk); + } + } +} +function* unescapeChunks(iterable) { + for (const chunk of iterable) { + yield unescapeHTML(chunk); + } +} +function unescapeHTML(str) { + if (!!str && typeof str === "object") { + if (str instanceof Uint8Array) { + return markHTMLBytes(str); + } else if (str instanceof Response && str.body) { + const body = str.body; + return unescapeChunksAsync(body); + } else if (typeof str.then === "function") { + return Promise.resolve(str).then((value) => { + return unescapeHTML(value); + }); + } else if (str[Symbol.for("astro:slot-string")]) { + return str; + } else if (Symbol.iterator in str) { + return unescapeChunks(str); + } else if (Symbol.asyncIterator in str || hasGetReader(str)) { + return unescapeChunksAsync(str); + } + } + return markHTMLString(str); +} + +const AstroJSX = "astro:jsx"; +function isVNode(vnode) { + return vnode && typeof vnode === "object" && vnode[AstroJSX]; +} + +function isAstroComponentFactory(obj) { + return obj == null ? false : obj.isAstroComponentFactory === true; +} +function isAPropagatingComponent(result, factory) { + const hint = getPropagationHint(result, factory); + return hint === "in-tree" || hint === "self"; +} +function getPropagationHint(result, factory) { + let hint = factory.propagation || "none"; + if (factory.moduleId && result.componentMetadata.has(factory.moduleId) && hint === "none") { + hint = result.componentMetadata.get(factory.moduleId).propagation; + } + return hint; +} + +const PROP_TYPE = { + Value: 0, + JSON: 1, + // Actually means Array + RegExp: 2, + Date: 3, + Map: 4, + Set: 5, + BigInt: 6, + URL: 7, + Uint8Array: 8, + Uint16Array: 9, + Uint32Array: 10, + Infinity: 11 +}; +function serializeArray(value, metadata = {}, parents = /* @__PURE__ */ new WeakSet()) { + if (parents.has(value)) { + throw new Error(`Cyclic reference detected while serializing props for <${metadata.displayName} client:${metadata.hydrate}>! + +Cyclic references cannot be safely serialized for client-side usage. Please remove the cyclic reference.`); + } + parents.add(value); + const serialized = value.map((v) => { + return convertToSerializedForm(v, metadata, parents); + }); + parents.delete(value); + return serialized; +} +function serializeObject(value, metadata = {}, parents = /* @__PURE__ */ new WeakSet()) { + if (parents.has(value)) { + throw new Error(`Cyclic reference detected while serializing props for <${metadata.displayName} client:${metadata.hydrate}>! + +Cyclic references cannot be safely serialized for client-side usage. Please remove the cyclic reference.`); + } + parents.add(value); + const serialized = Object.fromEntries( + Object.entries(value).map(([k, v]) => { + return [k, convertToSerializedForm(v, metadata, parents)]; + }) + ); + parents.delete(value); + return serialized; +} +function convertToSerializedForm(value, metadata = {}, parents = /* @__PURE__ */ new WeakSet()) { + const tag = Object.prototype.toString.call(value); + switch (tag) { + case "[object Date]": { + return [PROP_TYPE.Date, value.toISOString()]; + } + case "[object RegExp]": { + return [PROP_TYPE.RegExp, value.source]; + } + case "[object Map]": { + return [PROP_TYPE.Map, serializeArray(Array.from(value), metadata, parents)]; + } + case "[object Set]": { + return [PROP_TYPE.Set, serializeArray(Array.from(value), metadata, parents)]; + } + case "[object BigInt]": { + return [PROP_TYPE.BigInt, value.toString()]; + } + case "[object URL]": { + return [PROP_TYPE.URL, value.toString()]; + } + case "[object Array]": { + return [PROP_TYPE.JSON, serializeArray(value, metadata, parents)]; + } + case "[object Uint8Array]": { + return [PROP_TYPE.Uint8Array, Array.from(value)]; + } + case "[object Uint16Array]": { + return [PROP_TYPE.Uint16Array, Array.from(value)]; + } + case "[object Uint32Array]": { + return [PROP_TYPE.Uint32Array, Array.from(value)]; + } + default: { + if (value !== null && typeof value === "object") { + return [PROP_TYPE.Value, serializeObject(value, metadata, parents)]; + } + if (value === Infinity) { + return [PROP_TYPE.Infinity, 1]; + } + if (value === -Infinity) { + return [PROP_TYPE.Infinity, -1]; + } + if (value === void 0) { + return [PROP_TYPE.Value]; + } + return [PROP_TYPE.Value, value]; + } + } +} +function serializeProps(props, metadata) { + const serialized = JSON.stringify(serializeObject(props, metadata)); + return serialized; +} + +const transitionDirectivesToCopyOnIsland = Object.freeze([ + "data-astro-transition-scope", + "data-astro-transition-persist", + "data-astro-transition-persist-props" +]); +function extractDirectives(inputProps, clientDirectives) { + let extracted = { + isPage: false, + hydration: null, + props: {}, + propsWithoutTransitionAttributes: {} + }; + for (const [key, value] of Object.entries(inputProps)) { + if (key.startsWith("server:")) { + if (key === "server:root") { + extracted.isPage = true; + } + } + if (key.startsWith("client:")) { + if (!extracted.hydration) { + extracted.hydration = { + directive: "", + value: "", + componentUrl: "", + componentExport: { value: "" } + }; + } + switch (key) { + case "client:component-path": { + extracted.hydration.componentUrl = value; + break; + } + case "client:component-export": { + extracted.hydration.componentExport.value = value; + break; + } + // This is a special prop added to prove that the client hydration method + // was added statically. + case "client:component-hydration": { + break; + } + case "client:display-name": { + break; + } + default: { + extracted.hydration.directive = key.split(":")[1]; + extracted.hydration.value = value; + if (!clientDirectives.has(extracted.hydration.directive)) { + const hydrationMethods = Array.from(clientDirectives.keys()).map((d) => `client:${d}`).join(", "); + throw new Error( + `Error: invalid hydration directive "${key}". Supported hydration methods: ${hydrationMethods}` + ); + } + if (extracted.hydration.directive === "media" && typeof extracted.hydration.value !== "string") { + throw new AstroError(MissingMediaQueryDirective); + } + break; + } + } + } else { + extracted.props[key] = value; + if (!transitionDirectivesToCopyOnIsland.includes(key)) { + extracted.propsWithoutTransitionAttributes[key] = value; + } + } + } + for (const sym of Object.getOwnPropertySymbols(inputProps)) { + extracted.props[sym] = inputProps[sym]; + extracted.propsWithoutTransitionAttributes[sym] = inputProps[sym]; + } + return extracted; +} +async function generateHydrateScript(scriptOptions, metadata) { + const { renderer, result, astroId, props, attrs } = scriptOptions; + const { hydrate, componentUrl, componentExport } = metadata; + if (!componentExport.value) { + throw new AstroError({ + ...NoMatchingImport, + message: NoMatchingImport.message(metadata.displayName) + }); + } + const island = { + children: "", + props: { + // This is for HMR, probably can avoid it in prod + uid: astroId + } + }; + if (attrs) { + for (const [key, value] of Object.entries(attrs)) { + island.props[key] = escapeHTML(value); + } + } + island.props["component-url"] = await result.resolve(decodeURI(componentUrl)); + if (renderer.clientEntrypoint) { + island.props["component-export"] = componentExport.value; + island.props["renderer-url"] = await result.resolve( + decodeURI(renderer.clientEntrypoint.toString()) + ); + island.props["props"] = escapeHTML(serializeProps(props, metadata)); + } + island.props["ssr"] = ""; + island.props["client"] = hydrate; + let beforeHydrationUrl = await result.resolve("astro:scripts/before-hydration.js"); + if (beforeHydrationUrl.length) { + island.props["before-hydration-url"] = beforeHydrationUrl; + } + island.props["opts"] = escapeHTML( + JSON.stringify({ + name: metadata.displayName, + value: metadata.hydrateArgs || "" + }) + ); + transitionDirectivesToCopyOnIsland.forEach((name) => { + if (typeof props[name] !== "undefined") { + island.props[name] = props[name]; + } + }); + return island; +} + +/** + * shortdash - https://github.com/bibig/node-shorthash + * + * @license + * + * (The MIT License) + * + * Copyright (c) 2013 Bibig + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +const dictionary = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY"; +const binary = dictionary.length; +function bitwise(str) { + let hash = 0; + if (str.length === 0) return hash; + for (let i = 0; i < str.length; i++) { + const ch = str.charCodeAt(i); + hash = (hash << 5) - hash + ch; + hash = hash & hash; + } + return hash; +} +function shorthash(text) { + let num; + let result = ""; + let integer = bitwise(text); + const sign = integer < 0 ? "Z" : ""; + integer = Math.abs(integer); + while (integer >= binary) { + num = integer % binary; + integer = Math.floor(integer / binary); + result = dictionary[num] + result; + } + if (integer > 0) { + result = dictionary[integer] + result; + } + return sign + result; +} + +const headAndContentSym = Symbol.for("astro.headAndContent"); +function isHeadAndContent(obj) { + return typeof obj === "object" && obj !== null && !!obj[headAndContentSym]; +} +function createThinHead() { + return { + [headAndContentSym]: true + }; +} + +var astro_island_prebuilt_default = `(()=>{var A=Object.defineProperty;var g=(i,o,a)=>o in i?A(i,o,{enumerable:!0,configurable:!0,writable:!0,value:a}):i[o]=a;var d=(i,o,a)=>g(i,typeof o!="symbol"?o+"":o,a);{let i={0:t=>m(t),1:t=>a(t),2:t=>new RegExp(t),3:t=>new Date(t),4:t=>new Map(a(t)),5:t=>new Set(a(t)),6:t=>BigInt(t),7:t=>new URL(t),8:t=>new Uint8Array(t),9:t=>new Uint16Array(t),10:t=>new Uint32Array(t),11:t=>1/0*t},o=t=>{let[l,e]=t;return l in i?i[l](e):void 0},a=t=>t.map(o),m=t=>typeof t!="object"||t===null?t:Object.fromEntries(Object.entries(t).map(([l,e])=>[l,o(e)]));class y extends HTMLElement{constructor(){super(...arguments);d(this,"Component");d(this,"hydrator");d(this,"hydrate",async()=>{var b;if(!this.hydrator||!this.isConnected)return;let e=(b=this.parentElement)==null?void 0:b.closest("astro-island[ssr]");if(e){e.addEventListener("astro:hydrate",this.hydrate,{once:!0});return}let c=this.querySelectorAll("astro-slot"),n={},h=this.querySelectorAll("template[data-astro-template]");for(let r of h){let s=r.closest(this.tagName);s!=null&&s.isSameNode(this)&&(n[r.getAttribute("data-astro-template")||"default"]=r.innerHTML,r.remove())}for(let r of c){let s=r.closest(this.tagName);s!=null&&s.isSameNode(this)&&(n[r.getAttribute("name")||"default"]=r.innerHTML)}let p;try{p=this.hasAttribute("props")?m(JSON.parse(this.getAttribute("props"))):{}}catch(r){let s=this.getAttribute("component-url")||"",v=this.getAttribute("component-export");throw v&&(s+=\` (export \${v})\`),console.error(\`[hydrate] Error parsing props for component \${s}\`,this.getAttribute("props"),r),r}let u;await this.hydrator(this)(this.Component,p,n,{client:this.getAttribute("client")}),this.removeAttribute("ssr"),this.dispatchEvent(new CustomEvent("astro:hydrate"))});d(this,"unmount",()=>{this.isConnected||this.dispatchEvent(new CustomEvent("astro:unmount"))})}disconnectedCallback(){document.removeEventListener("astro:after-swap",this.unmount),document.addEventListener("astro:after-swap",this.unmount,{once:!0})}connectedCallback(){if(!this.hasAttribute("await-children")||document.readyState==="interactive"||document.readyState==="complete")this.childrenConnectedCallback();else{let e=()=>{document.removeEventListener("DOMContentLoaded",e),c.disconnect(),this.childrenConnectedCallback()},c=new MutationObserver(()=>{var n;((n=this.lastChild)==null?void 0:n.nodeType)===Node.COMMENT_NODE&&this.lastChild.nodeValue==="astro:end"&&(this.lastChild.remove(),e())});c.observe(this,{childList:!0}),document.addEventListener("DOMContentLoaded",e)}}async childrenConnectedCallback(){let e=this.getAttribute("before-hydration-url");e&&await import(e),this.start()}async start(){let e=JSON.parse(this.getAttribute("opts")),c=this.getAttribute("client");if(Astro[c]===void 0){window.addEventListener(\`astro:\${c}\`,()=>this.start(),{once:!0});return}try{await Astro[c](async()=>{let n=this.getAttribute("renderer-url"),[h,{default:p}]=await Promise.all([import(this.getAttribute("component-url")),n?import(n):()=>()=>{}]),u=this.getAttribute("component-export")||"default";if(!u.includes("."))this.Component=h[u];else{this.Component=h;for(let f of u.split("."))this.Component=this.Component[f]}return this.hydrator=p,this.hydrate},e,this)}catch(n){console.error(\`[astro-island] Error hydrating \${this.getAttribute("component-url")}\`,n)}}attributeChangedCallback(){this.hydrate()}}d(y,"observedAttributes",["props"]),customElements.get("astro-island")||customElements.define("astro-island",y)}})();`; + +var astro_island_prebuilt_dev_default = `(()=>{var A=Object.defineProperty;var g=(i,o,a)=>o in i?A(i,o,{enumerable:!0,configurable:!0,writable:!0,value:a}):i[o]=a;var l=(i,o,a)=>g(i,typeof o!="symbol"?o+"":o,a);{let i={0:t=>y(t),1:t=>a(t),2:t=>new RegExp(t),3:t=>new Date(t),4:t=>new Map(a(t)),5:t=>new Set(a(t)),6:t=>BigInt(t),7:t=>new URL(t),8:t=>new Uint8Array(t),9:t=>new Uint16Array(t),10:t=>new Uint32Array(t),11:t=>1/0*t},o=t=>{let[h,e]=t;return h in i?i[h](e):void 0},a=t=>t.map(o),y=t=>typeof t!="object"||t===null?t:Object.fromEntries(Object.entries(t).map(([h,e])=>[h,o(e)]));class f extends HTMLElement{constructor(){super(...arguments);l(this,"Component");l(this,"hydrator");l(this,"hydrate",async()=>{var b;if(!this.hydrator||!this.isConnected)return;let e=(b=this.parentElement)==null?void 0:b.closest("astro-island[ssr]");if(e){e.addEventListener("astro:hydrate",this.hydrate,{once:!0});return}let c=this.querySelectorAll("astro-slot"),n={},p=this.querySelectorAll("template[data-astro-template]");for(let r of p){let s=r.closest(this.tagName);s!=null&&s.isSameNode(this)&&(n[r.getAttribute("data-astro-template")||"default"]=r.innerHTML,r.remove())}for(let r of c){let s=r.closest(this.tagName);s!=null&&s.isSameNode(this)&&(n[r.getAttribute("name")||"default"]=r.innerHTML)}let u;try{u=this.hasAttribute("props")?y(JSON.parse(this.getAttribute("props"))):{}}catch(r){let s=this.getAttribute("component-url")||"",v=this.getAttribute("component-export");throw v&&(s+=\` (export \${v})\`),console.error(\`[hydrate] Error parsing props for component \${s}\`,this.getAttribute("props"),r),r}let d,m=this.hydrator(this);d=performance.now(),await m(this.Component,u,n,{client:this.getAttribute("client")}),d&&this.setAttribute("client-render-time",(performance.now()-d).toString()),this.removeAttribute("ssr"),this.dispatchEvent(new CustomEvent("astro:hydrate"))});l(this,"unmount",()=>{this.isConnected||this.dispatchEvent(new CustomEvent("astro:unmount"))})}disconnectedCallback(){document.removeEventListener("astro:after-swap",this.unmount),document.addEventListener("astro:after-swap",this.unmount,{once:!0})}connectedCallback(){if(!this.hasAttribute("await-children")||document.readyState==="interactive"||document.readyState==="complete")this.childrenConnectedCallback();else{let e=()=>{document.removeEventListener("DOMContentLoaded",e),c.disconnect(),this.childrenConnectedCallback()},c=new MutationObserver(()=>{var n;((n=this.lastChild)==null?void 0:n.nodeType)===Node.COMMENT_NODE&&this.lastChild.nodeValue==="astro:end"&&(this.lastChild.remove(),e())});c.observe(this,{childList:!0}),document.addEventListener("DOMContentLoaded",e)}}async childrenConnectedCallback(){let e=this.getAttribute("before-hydration-url");e&&await import(e),this.start()}async start(){let e=JSON.parse(this.getAttribute("opts")),c=this.getAttribute("client");if(Astro[c]===void 0){window.addEventListener(\`astro:\${c}\`,()=>this.start(),{once:!0});return}try{await Astro[c](async()=>{let n=this.getAttribute("renderer-url"),[p,{default:u}]=await Promise.all([import(this.getAttribute("component-url")),n?import(n):()=>()=>{}]),d=this.getAttribute("component-export")||"default";if(!d.includes("."))this.Component=p[d];else{this.Component=p;for(let m of d.split("."))this.Component=this.Component[m]}return this.hydrator=u,this.hydrate},e,this)}catch(n){console.error(\`[astro-island] Error hydrating \${this.getAttribute("component-url")}\`,n)}}attributeChangedCallback(){this.hydrate()}}l(f,"observedAttributes",["props"]),customElements.get("astro-island")||customElements.define("astro-island",f)}})();`; + +const ISLAND_STYLES = "astro-island,astro-slot,astro-static-slot{display:contents}"; + +function determineIfNeedsHydrationScript(result) { + if (result._metadata.hasHydrationScript) { + return false; + } + return result._metadata.hasHydrationScript = true; +} +function determinesIfNeedsDirectiveScript(result, directive) { + if (result._metadata.hasDirectives.has(directive)) { + return false; + } + result._metadata.hasDirectives.add(directive); + return true; +} +function getDirectiveScriptText(result, directive) { + const clientDirectives = result.clientDirectives; + const clientDirective = clientDirectives.get(directive); + if (!clientDirective) { + throw new Error(`Unknown directive: ${directive}`); + } + return clientDirective; +} +function getPrescripts(result, type, directive) { + switch (type) { + case "both": + return ``; + case "directive": + return ``; + } +} + +function renderCspContent(result) { + const finalScriptHashes = /* @__PURE__ */ new Set(); + const finalStyleHashes = /* @__PURE__ */ new Set(); + for (const scriptHash of result.scriptHashes) { + finalScriptHashes.add(`'${scriptHash}'`); + } + for (const styleHash of result.styleHashes) { + finalStyleHashes.add(`'${styleHash}'`); + } + for (const styleHash of result._metadata.extraStyleHashes) { + finalStyleHashes.add(`'${styleHash}'`); + } + for (const scriptHash of result._metadata.extraScriptHashes) { + finalScriptHashes.add(`'${scriptHash}'`); + } + let directives; + if (result.directives.length > 0) { + directives = result.directives.join(";") + ";"; + } + let scriptResources = "'self'"; + if (result.scriptResources.length > 0) { + scriptResources = result.scriptResources.map((r) => `${r}`).join(" "); + } + let styleResources = "'self'"; + if (result.styleResources.length > 0) { + styleResources = result.styleResources.map((r) => `${r}`).join(" "); + } + const strictDynamic = result.isStrictDynamic ? ` 'strict-dynamic'` : ""; + const scriptSrc = `script-src ${scriptResources} ${Array.from(finalScriptHashes).join(" ")}${strictDynamic};`; + const styleSrc = `style-src ${styleResources} ${Array.from(finalStyleHashes).join(" ")};`; + return [directives, scriptSrc, styleSrc].filter(Boolean).join(" "); +} + +const RenderInstructionSymbol = Symbol.for("astro:render"); +function createRenderInstruction(instruction) { + return Object.defineProperty(instruction, RenderInstructionSymbol, { + value: true + }); +} +function isRenderInstruction(chunk) { + return chunk && typeof chunk === "object" && chunk[RenderInstructionSymbol]; +} + +const voidElementNames = /^(area|base|br|col|command|embed|hr|img|input|keygen|link|meta|param|source|track|wbr)$/i; +const htmlBooleanAttributes = /^(?:allowfullscreen|async|autofocus|autoplay|checked|controls|default|defer|disabled|disablepictureinpicture|disableremoteplayback|formnovalidate|hidden|inert|loop|muted|nomodule|novalidate|open|playsinline|readonly|required|reversed|scoped|seamless|selected|itemscope)$/i; +const AMPERSAND_REGEX = /&/g; +const DOUBLE_QUOTE_REGEX = /"/g; +const STATIC_DIRECTIVES = /* @__PURE__ */ new Set(["set:html", "set:text"]); +const toIdent = (k) => k.trim().replace(/(?!^)\b\w|\s+|\W+/g, (match, index) => { + if (/\W/.test(match)) return ""; + return index === 0 ? match : match.toUpperCase(); +}); +const toAttributeString = (value, shouldEscape = true) => shouldEscape ? String(value).replace(AMPERSAND_REGEX, "&").replace(DOUBLE_QUOTE_REGEX, """) : value; +const kebab = (k) => k.toLowerCase() === k ? k : k.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`); +const toStyleString = (obj) => Object.entries(obj).filter(([_, v]) => typeof v === "string" && v.trim() || typeof v === "number").map(([k, v]) => { + if (k[0] !== "-" && k[1] !== "-") return `${kebab(k)}:${v}`; + return `${k}:${v}`; +}).join(";"); +function defineScriptVars(vars) { + let output = ""; + for (const [key, value] of Object.entries(vars)) { + output += `const ${toIdent(key)} = ${JSON.stringify(value)?.replace( + /<\/script>/g, + "\\x3C/script>" + )}; +`; + } + return markHTMLString(output); +} +function formatList(values) { + if (values.length === 1) { + return values[0]; + } + return `${values.slice(0, -1).join(", ")} or ${values[values.length - 1]}`; +} +function isCustomElement(tagName) { + return tagName.includes("-"); +} +function handleBooleanAttribute(key, value, shouldEscape, tagName) { + if (tagName && isCustomElement(tagName)) { + return markHTMLString(` ${key}="${toAttributeString(value, shouldEscape)}"`); + } + return markHTMLString(value ? ` ${key}` : ""); +} +function addAttribute(value, key, shouldEscape = true, tagName = "") { + if (value == null) { + return ""; + } + if (STATIC_DIRECTIVES.has(key)) { + console.warn(`[astro] The "${key}" directive cannot be applied dynamically at runtime. It will not be rendered as an attribute. + +Make sure to use the static attribute syntax (\`${key}={value}\`) instead of the dynamic spread syntax (\`{...{ "${key}": value }}\`).`); + return ""; + } + if (key === "class:list") { + const listValue = toAttributeString(clsx(value), shouldEscape); + if (listValue === "") { + return ""; + } + return markHTMLString(` ${key.slice(0, -5)}="${listValue}"`); + } + if (key === "style" && !(value instanceof HTMLString)) { + if (Array.isArray(value) && value.length === 2) { + return markHTMLString( + ` ${key}="${toAttributeString(`${toStyleString(value[0])};${value[1]}`, shouldEscape)}"` + ); + } + if (typeof value === "object") { + return markHTMLString(` ${key}="${toAttributeString(toStyleString(value), shouldEscape)}"`); + } + } + if (key === "className") { + return markHTMLString(` class="${toAttributeString(value, shouldEscape)}"`); + } + if (typeof value === "string" && value.includes("&") && isHttpUrl(value)) { + return markHTMLString(` ${key}="${toAttributeString(value, false)}"`); + } + if (htmlBooleanAttributes.test(key)) { + return handleBooleanAttribute(key, value, shouldEscape, tagName); + } + if (value === "") { + return markHTMLString(` ${key}`); + } + if (key === "popover" && typeof value === "boolean") { + return handleBooleanAttribute(key, value, shouldEscape, tagName); + } + if (key === "download" && typeof value === "boolean") { + return handleBooleanAttribute(key, value, shouldEscape, tagName); + } + return markHTMLString(` ${key}="${toAttributeString(value, shouldEscape)}"`); +} +function internalSpreadAttributes(values, shouldEscape = true, tagName) { + let output = ""; + for (const [key, value] of Object.entries(values)) { + output += addAttribute(value, key, shouldEscape, tagName); + } + return markHTMLString(output); +} +function renderElement$1(name, { props: _props, children = "" }, shouldEscape = true) { + const { lang: _, "data-astro-id": astroId, "define:vars": defineVars, ...props } = _props; + if (defineVars) { + if (name === "style") { + delete props["is:global"]; + delete props["is:scoped"]; + } + if (name === "script") { + delete props.hoist; + children = defineScriptVars(defineVars) + "\n" + children; + } + } + if ((children == null || children == "") && voidElementNames.test(name)) { + return `<${name}${internalSpreadAttributes(props, shouldEscape, name)}>`; + } + return `<${name}${internalSpreadAttributes(props, shouldEscape, name)}>${children}`; +} +const noop = () => { +}; +class BufferedRenderer { + chunks = []; + renderPromise; + destination; + /** + * Determines whether buffer has been flushed + * to the final destination. + */ + flushed = false; + constructor(destination, renderFunction) { + this.destination = destination; + this.renderPromise = renderFunction(this); + if (isPromise(this.renderPromise)) { + Promise.resolve(this.renderPromise).catch(noop); + } + } + write(chunk) { + if (this.flushed) { + this.destination.write(chunk); + } else { + this.chunks.push(chunk); + } + } + flush() { + if (this.flushed) { + throw new Error("The render buffer has already been flushed."); + } + this.flushed = true; + for (const chunk of this.chunks) { + this.destination.write(chunk); + } + return this.renderPromise; + } +} +function createBufferedRenderer(destination, renderFunction) { + return new BufferedRenderer(destination, renderFunction); +} +const isNode = typeof process !== "undefined" && Object.prototype.toString.call(process) === "[object process]"; +const isDeno = typeof Deno !== "undefined"; +function promiseWithResolvers() { + let resolve, reject; + const promise = new Promise((_resolve, _reject) => { + resolve = _resolve; + reject = _reject; + }); + return { + promise, + resolve, + reject + }; +} +const VALID_PROTOCOLS = ["http:", "https:"]; +function isHttpUrl(url) { + try { + const parsedUrl = new URL(url); + return VALID_PROTOCOLS.includes(parsedUrl.protocol); + } catch { + return false; + } +} + +const uniqueElements = (item, index, all) => { + const props = JSON.stringify(item.props); + const children = item.children; + return index === all.findIndex((i) => JSON.stringify(i.props) === props && i.children == children); +}; +function renderAllHeadContent(result) { + result._metadata.hasRenderedHead = true; + let content = ""; + if (result.shouldInjectCspMetaTags && result.cspDestination === "meta") { + content += renderElement$1( + "meta", + { + props: { + "http-equiv": "content-security-policy", + content: renderCspContent(result) + }, + children: "" + }, + false + ); + } + const styles = Array.from(result.styles).filter(uniqueElements).map( + (style) => style.props.rel === "stylesheet" ? renderElement$1("link", style) : renderElement$1("style", style) + ); + result.styles.clear(); + const scripts = Array.from(result.scripts).filter(uniqueElements).map((script) => { + if (result.userAssetsBase) { + script.props.src = (result.base === "/" ? "" : result.base) + result.userAssetsBase + script.props.src; + } + return renderElement$1("script", script, false); + }); + const links = Array.from(result.links).filter(uniqueElements).map((link) => renderElement$1("link", link, false)); + content += styles.join("\n") + links.join("\n") + scripts.join("\n"); + if (result._metadata.extraHead.length > 0) { + for (const part of result._metadata.extraHead) { + content += part; + } + } + return markHTMLString(content); +} +function renderHead() { + return createRenderInstruction({ type: "head" }); +} +function maybeRenderHead() { + return createRenderInstruction({ type: "maybe-head" }); +} + +const ALGORITHMS = { + "SHA-256": "sha256-", + "SHA-384": "sha384-", + "SHA-512": "sha512-" +}; +const ALGORITHM_VALUES = Object.values(ALGORITHMS); +z.enum(Object.keys(ALGORITHMS)).optional().default("SHA-256"); +z.custom((value) => { + if (typeof value !== "string") { + return false; + } + return ALGORITHM_VALUES.some((allowedValue) => { + return value.startsWith(allowedValue); + }); +}); +const ALLOWED_DIRECTIVES = [ + "base-uri", + "child-src", + "connect-src", + "default-src", + "fenced-frame-src", + "font-src", + "form-action", + "frame-ancestors", + "frame-src", + "img-src", + "manifest-src", + "media-src", + "object-src", + "referrer", + "report-to", + "report-uri", + "require-trusted-types-for", + "sandbox", + "trusted-types", + "upgrade-insecure-requests", + "worker-src" +]; +z.custom((value) => { + if (typeof value !== "string") { + return false; + } + return ALLOWED_DIRECTIVES.some((allowedValue) => { + return value.startsWith(allowedValue); + }); +}); + +const ALGORITHM = "AES-GCM"; +async function decodeKey(encoded) { + const bytes = decodeBase64(encoded); + return crypto.subtle.importKey("raw", bytes.buffer, ALGORITHM, true, [ + "encrypt", + "decrypt" + ]); +} +const encoder$1 = new TextEncoder(); +const decoder$1 = new TextDecoder(); +const IV_LENGTH = 24; +async function encryptString(key, raw) { + const iv = crypto.getRandomValues(new Uint8Array(IV_LENGTH / 2)); + const data = encoder$1.encode(raw); + const buffer = await crypto.subtle.encrypt( + { + name: ALGORITHM, + iv + }, + key, + data + ); + return encodeHexUpperCase(iv) + encodeBase64(new Uint8Array(buffer)); +} +async function decryptString(key, encoded) { + const iv = decodeHex(encoded.slice(0, IV_LENGTH)); + const dataArray = decodeBase64(encoded.slice(IV_LENGTH)); + const decryptedBuffer = await crypto.subtle.decrypt( + { + name: ALGORITHM, + iv + }, + key, + dataArray + ); + const decryptedString = decoder$1.decode(decryptedBuffer); + return decryptedString; +} +async function generateCspDigest(data, algorithm) { + const hashBuffer = await crypto.subtle.digest(algorithm, encoder$1.encode(data)); + const hash = encodeBase64(new Uint8Array(hashBuffer)); + return `${ALGORITHMS[algorithm]}${hash}`; +} + +const renderTemplateResultSym = Symbol.for("astro.renderTemplateResult"); +class RenderTemplateResult { + [renderTemplateResultSym] = true; + htmlParts; + expressions; + error; + constructor(htmlParts, expressions) { + this.htmlParts = htmlParts; + this.error = void 0; + this.expressions = expressions.map((expression) => { + if (isPromise(expression)) { + return Promise.resolve(expression).catch((err) => { + if (!this.error) { + this.error = err; + throw err; + } + }); + } + return expression; + }); + } + render(destination) { + const flushers = this.expressions.map((exp) => { + return createBufferedRenderer(destination, (bufferDestination) => { + if (exp || exp === 0) { + return renderChild(bufferDestination, exp); + } + }); + }); + let i = 0; + const iterate = () => { + while (i < this.htmlParts.length) { + const html = this.htmlParts[i]; + const flusher = flushers[i]; + i++; + if (html) { + destination.write(markHTMLString(html)); + } + if (flusher) { + const result = flusher.flush(); + if (isPromise(result)) { + return result.then(iterate); + } + } + } + }; + return iterate(); + } +} +function isRenderTemplateResult(obj) { + return typeof obj === "object" && obj !== null && !!obj[renderTemplateResultSym]; +} +function renderTemplate(htmlParts, ...expressions) { + return new RenderTemplateResult(htmlParts, expressions); +} + +const slotString = Symbol.for("astro:slot-string"); +class SlotString extends HTMLString { + instructions; + [slotString]; + constructor(content, instructions) { + super(content); + this.instructions = instructions; + this[slotString] = true; + } +} +function isSlotString(str) { + return !!str[slotString]; +} +function renderSlot(result, slotted, fallback) { + return { + async render(destination) { + await renderChild(destination, typeof slotted === "function" ? slotted(result) : slotted); + } + }; +} +async function renderSlotToString(result, slotted, fallback) { + let content = ""; + let instructions = null; + const temporaryDestination = { + write(chunk) { + if (chunk instanceof SlotString) { + content += chunk; + if (chunk.instructions) { + instructions ??= []; + instructions.push(...chunk.instructions); + } + } else if (chunk instanceof Response) return; + else if (typeof chunk === "object" && "type" in chunk && typeof chunk.type === "string") { + if (instructions === null) { + instructions = []; + } + instructions.push(chunk); + } else { + content += chunkToString(result, chunk); + } + } + }; + const renderInstance = renderSlot(result, slotted); + await renderInstance.render(temporaryDestination); + return markHTMLString(new SlotString(content, instructions)); +} +async function renderSlots(result, slots = {}) { + let slotInstructions = null; + let children = {}; + if (slots) { + await Promise.all( + Object.entries(slots).map( + ([key, value]) => renderSlotToString(result, value).then((output) => { + if (output.instructions) { + if (slotInstructions === null) { + slotInstructions = []; + } + slotInstructions.push(...output.instructions); + } + children[key] = output; + }) + ) + ); + } + return { slotInstructions, children }; +} +function createSlotValueFromString(content) { + return function() { + return renderTemplate`${unescapeHTML(content)}`; + }; +} + +const internalProps = /* @__PURE__ */ new Set([ + "server:component-path", + "server:component-export", + "server:component-directive", + "server:defer" +]); +function containsServerDirective(props) { + return "server:component-directive" in props; +} +const SCRIPT_RE = /<\/script/giu; +const COMMENT_RE = /"); + for (const name in this.slots) { + if (name === "fallback") { + await renderChild(destination, this.slots.fallback(this.result)); + } + } + destination.write( + `` + ); + } + getComponentPath() { + if (this.componentPath) { + return this.componentPath; + } + const componentPath = this.props["server:component-path"]; + if (!componentPath) { + throw new Error(`Could not find server component path`); + } + this.componentPath = componentPath; + return componentPath; + } + getComponentExport() { + if (this.componentExport) { + return this.componentExport; + } + const componentExport = this.props["server:component-export"]; + if (!componentExport) { + throw new Error(`Could not find server component export`); + } + this.componentExport = componentExport; + return componentExport; + } + async getHostId() { + if (!this.hostId) { + this.hostId = await crypto.randomUUID(); + } + return this.hostId; + } + async getIslandContent() { + if (this.islandContent) { + return this.islandContent; + } + const componentPath = this.getComponentPath(); + const componentExport = this.getComponentExport(); + const componentId = this.result.serverIslandNameMap.get(componentPath); + if (!componentId) { + throw new Error(`Could not find server component name`); + } + for (const key2 of Object.keys(this.props)) { + if (internalProps.has(key2)) { + delete this.props[key2]; + } + } + const renderedSlots = {}; + for (const name in this.slots) { + if (name !== "fallback") { + const content = await renderSlotToString(this.result, this.slots[name]); + renderedSlots[name] = content.toString(); + } + } + const key = await this.result.key; + const propsEncrypted = Object.keys(this.props).length === 0 ? "" : await encryptString(key, JSON.stringify(this.props)); + const hostId = await this.getHostId(); + const slash = this.result.base.endsWith("/") ? "" : "/"; + let serverIslandUrl = `${this.result.base}${slash}_server-islands/${componentId}${this.result.trailingSlash === "always" ? "/" : ""}`; + const potentialSearchParams = createSearchParams( + componentExport, + propsEncrypted, + safeJsonStringify(renderedSlots) + ); + const useGETRequest = isWithinURLLimit(serverIslandUrl, potentialSearchParams); + if (useGETRequest) { + serverIslandUrl += "?" + potentialSearchParams.toString(); + this.result._metadata.extraHead.push( + markHTMLString( + `` + ) + ); + } + const adapterHeaders = this.result.internalFetchHeaders || {}; + const headersJson = safeJsonStringify(adapterHeaders); + const method = useGETRequest ? ( + // GET request + `const headers = new Headers(${headersJson}); +let response = await fetch('${serverIslandUrl}', { headers });` + ) : ( + // POST request + `let data = { + componentExport: ${safeJsonStringify(componentExport)}, + encryptedProps: ${safeJsonStringify(propsEncrypted)}, + slots: ${safeJsonStringify(renderedSlots)}, +}; +const headers = new Headers({ 'Content-Type': 'application/json', ...${headersJson} }); +let response = await fetch('${serverIslandUrl}', { + method: 'POST', + body: JSON.stringify(data), + headers, +});` + ); + this.islandContent = `${method}replaceServerIsland('${hostId}', response);`; + return this.islandContent; + } +} +const renderServerIslandRuntime = () => { + return ``; +}; +const SERVER_ISLAND_REPLACER = markHTMLString( + `async function replaceServerIsland(id, r) { + let s = document.querySelector(\`script[data-island-id="\${id}"]\`); + // If there's no matching script, or the request fails then return + if (!s || r.status !== 200 || r.headers.get('content-type')?.split(';')[0].trim() !== 'text/html') return; + // Load the HTML before modifying the DOM in case of errors + let html = await r.text(); + // Remove any placeholder content before the island script + while (s.previousSibling && s.previousSibling.nodeType !== 8 && s.previousSibling.data !== '[if astro]>server-island-start line.trim()).filter((line) => line && !line.startsWith("//")).join(" ") +); + +const Fragment = Symbol.for("astro:fragment"); +const Renderer = Symbol.for("astro:renderer"); +const encoder = new TextEncoder(); +const decoder = new TextDecoder(); +function stringifyChunk(result, chunk) { + if (isRenderInstruction(chunk)) { + const instruction = chunk; + switch (instruction.type) { + case "directive": { + const { hydration } = instruction; + let needsHydrationScript = hydration && determineIfNeedsHydrationScript(result); + let needsDirectiveScript = hydration && determinesIfNeedsDirectiveScript(result, hydration.directive); + if (needsHydrationScript) { + let prescripts = getPrescripts(result, "both", hydration.directive); + return markHTMLString(prescripts); + } else if (needsDirectiveScript) { + let prescripts = getPrescripts(result, "directive", hydration.directive); + return markHTMLString(prescripts); + } else { + return ""; + } + } + case "head": { + if (result._metadata.hasRenderedHead || result.partial) { + return ""; + } + return renderAllHeadContent(result); + } + case "maybe-head": { + if (result._metadata.hasRenderedHead || result._metadata.headInTree || result.partial) { + return ""; + } + return renderAllHeadContent(result); + } + case "renderer-hydration-script": { + const { rendererSpecificHydrationScripts } = result._metadata; + const { rendererName } = instruction; + if (!rendererSpecificHydrationScripts.has(rendererName)) { + rendererSpecificHydrationScripts.add(rendererName); + return instruction.render(); + } + return ""; + } + case "server-island-runtime": { + if (result._metadata.hasRenderedServerIslandRuntime) { + return ""; + } + result._metadata.hasRenderedServerIslandRuntime = true; + return renderServerIslandRuntime(); + } + default: { + throw new Error(`Unknown chunk type: ${chunk.type}`); + } + } + } else if (chunk instanceof Response) { + return ""; + } else if (isSlotString(chunk)) { + let out = ""; + const c = chunk; + if (c.instructions) { + for (const instr of c.instructions) { + out += stringifyChunk(result, instr); + } + } + out += chunk.toString(); + return out; + } + return chunk.toString(); +} +function chunkToString(result, chunk) { + if (ArrayBuffer.isView(chunk)) { + return decoder.decode(chunk); + } else { + return stringifyChunk(result, chunk); + } +} +function chunkToByteArray(result, chunk) { + if (ArrayBuffer.isView(chunk)) { + return chunk; + } else { + const stringified = stringifyChunk(result, chunk); + return encoder.encode(stringified.toString()); + } +} +function isRenderInstance(obj) { + return !!obj && typeof obj === "object" && "render" in obj && typeof obj.render === "function"; +} + +function renderChild(destination, child) { + if (isPromise(child)) { + return child.then((x) => renderChild(destination, x)); + } + if (child instanceof SlotString) { + destination.write(child); + return; + } + if (isHTMLString(child)) { + destination.write(child); + return; + } + if (Array.isArray(child)) { + return renderArray(destination, child); + } + if (typeof child === "function") { + return renderChild(destination, child()); + } + if (!child && child !== 0) { + return; + } + if (typeof child === "string") { + destination.write(markHTMLString(escapeHTML(child))); + return; + } + if (isRenderInstance(child)) { + return child.render(destination); + } + if (isRenderTemplateResult(child)) { + return child.render(destination); + } + if (isAstroComponentInstance(child)) { + return child.render(destination); + } + if (ArrayBuffer.isView(child)) { + destination.write(child); + return; + } + if (typeof child === "object" && (Symbol.asyncIterator in child || Symbol.iterator in child)) { + if (Symbol.asyncIterator in child) { + return renderAsyncIterable(destination, child); + } + return renderIterable(destination, child); + } + destination.write(child); +} +function renderArray(destination, children) { + const flushers = children.map((c) => { + return createBufferedRenderer(destination, (bufferDestination) => { + return renderChild(bufferDestination, c); + }); + }); + const iterator = flushers[Symbol.iterator](); + const iterate = () => { + for (; ; ) { + const { value: flusher, done } = iterator.next(); + if (done) { + break; + } + const result = flusher.flush(); + if (isPromise(result)) { + return result.then(iterate); + } + } + }; + return iterate(); +} +function renderIterable(destination, children) { + const iterator = children[Symbol.iterator](); + const iterate = () => { + for (; ; ) { + const { value, done } = iterator.next(); + if (done) { + break; + } + const result = renderChild(destination, value); + if (isPromise(result)) { + return result.then(iterate); + } + } + }; + return iterate(); +} +async function renderAsyncIterable(destination, children) { + for await (const value of children) { + await renderChild(destination, value); + } +} + +const astroComponentInstanceSym = Symbol.for("astro.componentInstance"); +class AstroComponentInstance { + [astroComponentInstanceSym] = true; + result; + props; + slotValues; + factory; + returnValue; + constructor(result, props, slots, factory) { + this.result = result; + this.props = props; + this.factory = factory; + this.slotValues = {}; + for (const name in slots) { + let didRender = false; + let value = slots[name](result); + this.slotValues[name] = () => { + if (!didRender) { + didRender = true; + return value; + } + return slots[name](result); + }; + } + } + init(result) { + if (this.returnValue !== void 0) { + return this.returnValue; + } + this.returnValue = this.factory(result, this.props, this.slotValues); + if (isPromise(this.returnValue)) { + this.returnValue.then((resolved) => { + this.returnValue = resolved; + }).catch(() => { + }); + } + return this.returnValue; + } + render(destination) { + const returnValue = this.init(this.result); + if (isPromise(returnValue)) { + return returnValue.then((x) => this.renderImpl(destination, x)); + } + return this.renderImpl(destination, returnValue); + } + renderImpl(destination, returnValue) { + if (isHeadAndContent(returnValue)) { + return returnValue.content.render(destination); + } else { + return renderChild(destination, returnValue); + } + } +} +function validateComponentProps(props, clientDirectives, displayName) { + if (props != null) { + const directives = [...clientDirectives.keys()].map((directive) => `client:${directive}`); + for (const prop of Object.keys(props)) { + if (directives.includes(prop)) { + console.warn( + `You are attempting to render <${displayName} ${prop} />, but ${displayName} is an Astro component. Astro components do not render in the client and should not have a hydration directive. Please use a framework component for client rendering.` + ); + } + } + } +} +function createAstroComponentInstance(result, displayName, factory, props, slots = {}) { + validateComponentProps(props, result.clientDirectives, displayName); + const instance = new AstroComponentInstance(result, props, slots, factory); + if (isAPropagatingComponent(result, factory)) { + result._metadata.propagators.add(instance); + } + return instance; +} +function isAstroComponentInstance(obj) { + return typeof obj === "object" && obj !== null && !!obj[astroComponentInstanceSym]; +} + +const DOCTYPE_EXP = /" : "\n"; + str += doctype; + } + } + if (chunk instanceof Response) return; + str += chunkToString(result, chunk); + } + }; + await templateResult.render(destination); + return str; +} +async function renderToReadableStream(result, componentFactory, props, children, isPage = false, route) { + const templateResult = await callComponentAsTemplateResultOrResponse( + result, + componentFactory, + props, + children, + route + ); + if (templateResult instanceof Response) return templateResult; + let renderedFirstPageChunk = false; + if (isPage) { + await bufferHeadContent(result); + } + return new ReadableStream({ + start(controller) { + const destination = { + write(chunk) { + if (isPage && !renderedFirstPageChunk) { + renderedFirstPageChunk = true; + if (!result.partial && !DOCTYPE_EXP.test(String(chunk))) { + const doctype = result.compressHTML ? "" : "\n"; + controller.enqueue(encoder.encode(doctype)); + } + } + if (chunk instanceof Response) { + throw new AstroError({ + ...ResponseSentError + }); + } + const bytes = chunkToByteArray(result, chunk); + controller.enqueue(bytes); + } + }; + (async () => { + try { + await templateResult.render(destination); + controller.close(); + } catch (e) { + if (AstroError.is(e) && !e.loc) { + e.setLocation({ + file: route?.component + }); + } + setTimeout(() => controller.error(e), 0); + } + })(); + }, + cancel() { + result.cancelled = true; + } + }); +} +async function callComponentAsTemplateResultOrResponse(result, componentFactory, props, children, route) { + const factoryResult = await componentFactory(result, props, children); + if (factoryResult instanceof Response) { + return factoryResult; + } else if (isHeadAndContent(factoryResult)) { + if (!isRenderTemplateResult(factoryResult.content)) { + throw new AstroError({ + ...OnlyResponseCanBeReturned, + message: OnlyResponseCanBeReturned.message( + route?.route, + typeof factoryResult + ), + location: { + file: route?.component + } + }); + } + return factoryResult.content; + } else if (!isRenderTemplateResult(factoryResult)) { + throw new AstroError({ + ...OnlyResponseCanBeReturned, + message: OnlyResponseCanBeReturned.message(route?.route, typeof factoryResult), + location: { + file: route?.component + } + }); + } + return factoryResult; +} +async function bufferHeadContent(result) { + const iterator = result._metadata.propagators.values(); + while (true) { + const { value, done } = iterator.next(); + if (done) { + break; + } + const returnValue = await value.init(result); + if (isHeadAndContent(returnValue) && returnValue.head) { + result._metadata.extraHead.push(returnValue.head); + } + } +} +async function renderToAsyncIterable(result, componentFactory, props, children, isPage = false, route) { + const templateResult = await callComponentAsTemplateResultOrResponse( + result, + componentFactory, + props, + children, + route + ); + if (templateResult instanceof Response) return templateResult; + let renderedFirstPageChunk = false; + if (isPage) { + await bufferHeadContent(result); + } + let error = null; + let next = null; + const buffer = []; + let renderingComplete = false; + const iterator = { + async next() { + if (result.cancelled) return { done: true, value: void 0 }; + if (next !== null) { + await next.promise; + } else if (!renderingComplete && !buffer.length) { + next = promiseWithResolvers(); + await next.promise; + } + if (!renderingComplete) { + next = promiseWithResolvers(); + } + if (error) { + throw error; + } + let length = 0; + for (let i = 0, len = buffer.length; i < len; i++) { + length += buffer[i].length; + } + let mergedArray = new Uint8Array(length); + let offset = 0; + for (let i = 0, len = buffer.length; i < len; i++) { + const item = buffer[i]; + mergedArray.set(item, offset); + offset += item.length; + } + buffer.length = 0; + const returnValue = { + // The iterator is done when rendering has finished + // and there are no more chunks to return. + done: length === 0 && renderingComplete, + value: mergedArray + }; + return returnValue; + }, + async return() { + result.cancelled = true; + return { done: true, value: void 0 }; + } + }; + const destination = { + write(chunk) { + if (isPage && !renderedFirstPageChunk) { + renderedFirstPageChunk = true; + if (!result.partial && !DOCTYPE_EXP.test(String(chunk))) { + const doctype = result.compressHTML ? "" : "\n"; + buffer.push(encoder.encode(doctype)); + } + } + if (chunk instanceof Response) { + throw new AstroError(ResponseSentError); + } + const bytes = chunkToByteArray(result, chunk); + if (bytes.length > 0) { + buffer.push(bytes); + next?.resolve(); + } else if (buffer.length > 0) { + next?.resolve(); + } + } + }; + const renderResult = toPromise(() => templateResult.render(destination)); + renderResult.catch((err) => { + error = err; + }).finally(() => { + renderingComplete = true; + next?.resolve(); + }); + return { + [Symbol.asyncIterator]() { + return iterator; + } + }; +} +function toPromise(fn) { + try { + const result = fn(); + return isPromise(result) ? result : Promise.resolve(result); + } catch (err) { + return Promise.reject(err); + } +} + +function componentIsHTMLElement(Component) { + return typeof HTMLElement !== "undefined" && HTMLElement.isPrototypeOf(Component); +} +async function renderHTMLElement(result, constructor, props, slots) { + const name = getHTMLElementName(constructor); + let attrHTML = ""; + for (const attr in props) { + attrHTML += ` ${attr}="${toAttributeString(await props[attr])}"`; + } + return markHTMLString( + `<${name}${attrHTML}>${await renderSlotToString(result, slots?.default)}` + ); +} +function getHTMLElementName(constructor) { + const definedName = customElements.getName(constructor); + if (definedName) return definedName; + const assignedName = constructor.name.replace(/^HTML|Element$/g, "").replace(/[A-Z]/g, "-$&").toLowerCase().replace(/^-/, "html-"); + return assignedName; +} + +const needsHeadRenderingSymbol = Symbol.for("astro.needsHeadRendering"); +const rendererAliases = /* @__PURE__ */ new Map([["solid", "solid-js"]]); +const clientOnlyValues = /* @__PURE__ */ new Set(["solid-js", "react", "preact", "vue", "svelte"]); +function guessRenderers(componentUrl) { + const extname = componentUrl?.split(".").pop(); + switch (extname) { + case "svelte": + return ["@astrojs/svelte"]; + case "vue": + return ["@astrojs/vue"]; + case "jsx": + case "tsx": + return ["@astrojs/react", "@astrojs/preact", "@astrojs/solid-js", "@astrojs/vue (jsx)"]; + case void 0: + default: + return [ + "@astrojs/react", + "@astrojs/preact", + "@astrojs/solid-js", + "@astrojs/vue", + "@astrojs/svelte" + ]; + } +} +function isFragmentComponent(Component) { + return Component === Fragment; +} +function isHTMLComponent(Component) { + return Component && Component["astro:html"] === true; +} +const ASTRO_SLOT_EXP = /<\/?astro-slot\b[^>]*>/g; +const ASTRO_STATIC_SLOT_EXP = /<\/?astro-static-slot\b[^>]*>/g; +function removeStaticAstroSlot(html, supportsAstroStaticSlot = true) { + const exp = supportsAstroStaticSlot ? ASTRO_STATIC_SLOT_EXP : ASTRO_SLOT_EXP; + return html.replace(exp, ""); +} +async function renderFrameworkComponent(result, displayName, Component, _props, slots = {}) { + if (!Component && "client:only" in _props === false) { + throw new Error( + `Unable to render ${displayName} because it is ${Component}! +Did you forget to import the component or is it possible there is a typo?` + ); + } + const { renderers, clientDirectives } = result; + const metadata = { + astroStaticSlot: true, + displayName + }; + const { hydration, isPage, props, propsWithoutTransitionAttributes } = extractDirectives( + _props, + clientDirectives + ); + let html = ""; + let attrs = void 0; + if (hydration) { + metadata.hydrate = hydration.directive; + metadata.hydrateArgs = hydration.value; + metadata.componentExport = hydration.componentExport; + metadata.componentUrl = hydration.componentUrl; + } + const probableRendererNames = guessRenderers(metadata.componentUrl); + const validRenderers = renderers.filter((r) => r.name !== "astro:jsx"); + const { children, slotInstructions } = await renderSlots(result, slots); + let renderer; + if (metadata.hydrate !== "only") { + let isTagged = false; + try { + isTagged = Component && Component[Renderer]; + } catch { + } + if (isTagged) { + const rendererName = Component[Renderer]; + renderer = renderers.find(({ name }) => name === rendererName); + } + if (!renderer) { + let error; + for (const r of renderers) { + try { + if (await r.ssr.check.call({ result }, Component, props, children)) { + renderer = r; + break; + } + } catch (e) { + error ??= e; + } + } + if (!renderer && error) { + throw error; + } + } + if (!renderer && typeof HTMLElement === "function" && componentIsHTMLElement(Component)) { + const output = await renderHTMLElement( + result, + Component, + _props, + slots + ); + return { + render(destination) { + destination.write(output); + } + }; + } + } else { + if (metadata.hydrateArgs) { + const rendererName = rendererAliases.has(metadata.hydrateArgs) ? rendererAliases.get(metadata.hydrateArgs) : metadata.hydrateArgs; + if (clientOnlyValues.has(rendererName)) { + renderer = renderers.find( + ({ name }) => name === `@astrojs/${rendererName}` || name === rendererName + ); + } + } + if (!renderer && validRenderers.length === 1) { + renderer = validRenderers[0]; + } + if (!renderer) { + const extname = metadata.componentUrl?.split(".").pop(); + renderer = renderers.find(({ name }) => name === `@astrojs/${extname}` || name === extname); + } + } + let componentServerRenderEndTime; + if (!renderer) { + if (metadata.hydrate === "only") { + const rendererName = rendererAliases.has(metadata.hydrateArgs) ? rendererAliases.get(metadata.hydrateArgs) : metadata.hydrateArgs; + if (clientOnlyValues.has(rendererName)) { + const plural = validRenderers.length > 1; + throw new AstroError({ + ...NoMatchingRenderer, + message: NoMatchingRenderer.message( + metadata.displayName, + metadata?.componentUrl?.split(".").pop(), + plural, + validRenderers.length + ), + hint: NoMatchingRenderer.hint( + formatList(probableRendererNames.map((r) => "`" + r + "`")) + ) + }); + } else { + throw new AstroError({ + ...NoClientOnlyHint, + message: NoClientOnlyHint.message(metadata.displayName), + hint: NoClientOnlyHint.hint( + probableRendererNames.map((r) => r.replace("@astrojs/", "")).join("|") + ) + }); + } + } else if (typeof Component !== "string") { + const matchingRenderers = validRenderers.filter( + (r) => probableRendererNames.includes(r.name) + ); + const plural = validRenderers.length > 1; + if (matchingRenderers.length === 0) { + throw new AstroError({ + ...NoMatchingRenderer, + message: NoMatchingRenderer.message( + metadata.displayName, + metadata?.componentUrl?.split(".").pop(), + plural, + validRenderers.length + ), + hint: NoMatchingRenderer.hint( + formatList(probableRendererNames.map((r) => "`" + r + "`")) + ) + }); + } else if (matchingRenderers.length === 1) { + renderer = matchingRenderers[0]; + ({ html, attrs } = await renderer.ssr.renderToStaticMarkup.call( + { result }, + Component, + propsWithoutTransitionAttributes, + children, + metadata + )); + } else { + throw new Error(`Unable to render ${metadata.displayName}! + +This component likely uses ${formatList(probableRendererNames)}, +but Astro encountered an error during server-side rendering. + +Please ensure that ${metadata.displayName}: +1. Does not unconditionally access browser-specific globals like \`window\` or \`document\`. + If this is unavoidable, use the \`client:only\` hydration directive. +2. Does not conditionally return \`null\` or \`undefined\` when rendered on the server. + +If you're still stuck, please open an issue on GitHub or join us at https://astro.build/chat.`); + } + } + } else { + if (metadata.hydrate === "only") { + html = await renderSlotToString(result, slots?.fallback); + } else { + const componentRenderStartTime = performance.now(); + ({ html, attrs } = await renderer.ssr.renderToStaticMarkup.call( + { result }, + Component, + propsWithoutTransitionAttributes, + children, + metadata + )); + if (process.env.NODE_ENV === "development") + componentServerRenderEndTime = performance.now() - componentRenderStartTime; + } + } + if (!html && typeof Component === "string") { + const Tag = sanitizeElementName(Component); + const childSlots = Object.values(children).join(""); + const renderTemplateResult = renderTemplate`<${Tag}${internalSpreadAttributes( + props, + true, + Tag + )}${markHTMLString( + childSlots === "" && voidElementNames.test(Tag) ? `/>` : `>${childSlots}` + )}`; + html = ""; + const destination = { + write(chunk) { + if (chunk instanceof Response) return; + html += chunkToString(result, chunk); + } + }; + await renderTemplateResult.render(destination); + } + if (!hydration) { + return { + render(destination) { + if (slotInstructions) { + for (const instruction of slotInstructions) { + destination.write(instruction); + } + } + if (isPage || renderer?.name === "astro:jsx") { + destination.write(html); + } else if (html && html.length > 0) { + destination.write( + markHTMLString(removeStaticAstroSlot(html, renderer?.ssr?.supportsAstroStaticSlot)) + ); + } + } + }; + } + const astroId = shorthash( + ` +${html} +${serializeProps( + props, + metadata + )}` + ); + const island = await generateHydrateScript( + { renderer, result, astroId, props, attrs }, + metadata + ); + if (componentServerRenderEndTime && process.env.NODE_ENV === "development") + island.props["server-render-time"] = componentServerRenderEndTime; + let unrenderedSlots = []; + if (html) { + if (Object.keys(children).length > 0) { + for (const key of Object.keys(children)) { + let tagName = renderer?.ssr?.supportsAstroStaticSlot ? !!metadata.hydrate ? "astro-slot" : "astro-static-slot" : "astro-slot"; + let expectedHTML = key === "default" ? `<${tagName}>` : `<${tagName} name="${key}">`; + if (!html.includes(expectedHTML)) { + unrenderedSlots.push(key); + } + } + } + } else { + unrenderedSlots = Object.keys(children); + } + const template = unrenderedSlots.length > 0 ? unrenderedSlots.map( + (key) => `` + ).join("") : ""; + island.children = `${html ?? ""}${template}`; + if (island.children) { + island.props["await-children"] = ""; + island.children += ``; + } + return { + render(destination) { + if (slotInstructions) { + for (const instruction of slotInstructions) { + destination.write(instruction); + } + } + destination.write(createRenderInstruction({ type: "directive", hydration })); + if (hydration.directive !== "only" && renderer?.ssr.renderHydrationScript) { + destination.write( + createRenderInstruction({ + type: "renderer-hydration-script", + rendererName: renderer.name, + render: renderer.ssr.renderHydrationScript + }) + ); + } + const renderedElement = renderElement$1("astro-island", island, false); + destination.write(markHTMLString(renderedElement)); + } + }; +} +function sanitizeElementName(tag) { + const unsafe = /[&<>'"\s]+/; + if (!unsafe.test(tag)) return tag; + return tag.trim().split(unsafe)[0].trim(); +} +async function renderFragmentComponent(result, slots = {}) { + const children = await renderSlotToString(result, slots?.default); + return { + render(destination) { + if (children == null) return; + destination.write(children); + } + }; +} +async function renderHTMLComponent(result, Component, _props, slots = {}) { + const { slotInstructions, children } = await renderSlots(result, slots); + const html = Component({ slots: children }); + const hydrationHtml = slotInstructions ? slotInstructions.map((instr) => chunkToString(result, instr)).join("") : ""; + return { + render(destination) { + destination.write(markHTMLString(hydrationHtml + html)); + } + }; +} +function renderAstroComponent(result, displayName, Component, props, slots = {}) { + if (containsServerDirective(props)) { + const serverIslandComponent = new ServerIslandComponent(result, props, slots, displayName); + result._metadata.propagators.add(serverIslandComponent); + return serverIslandComponent; + } + const instance = createAstroComponentInstance(result, displayName, Component, props, slots); + return { + render(destination) { + return instance.render(destination); + } + }; +} +function renderComponent(result, displayName, Component, props, slots = {}) { + if (isPromise(Component)) { + return Component.catch(handleCancellation).then((x) => { + return renderComponent(result, displayName, x, props, slots); + }); + } + if (isFragmentComponent(Component)) { + return renderFragmentComponent(result, slots).catch(handleCancellation); + } + props = normalizeProps(props); + if (isHTMLComponent(Component)) { + return renderHTMLComponent(result, Component, props, slots).catch(handleCancellation); + } + if (isAstroComponentFactory(Component)) { + return renderAstroComponent(result, displayName, Component, props, slots); + } + return renderFrameworkComponent(result, displayName, Component, props, slots).catch( + handleCancellation + ); + function handleCancellation(e) { + if (result.cancelled) + return { + render() { + } + }; + throw e; + } +} +function normalizeProps(props) { + if (props["class:list"] !== void 0) { + const value = props["class:list"]; + delete props["class:list"]; + props["class"] = clsx(props["class"], value); + if (props["class"] === "") { + delete props["class"]; + } + } + return props; +} +async function renderComponentToString(result, displayName, Component, props, slots = {}, isPage = false, route) { + let str = ""; + let renderedFirstPageChunk = false; + let head = ""; + if (isPage && !result.partial && nonAstroPageNeedsHeadInjection(Component)) { + head += chunkToString(result, maybeRenderHead()); + } + try { + const destination = { + write(chunk) { + if (isPage && !result.partial && !renderedFirstPageChunk) { + renderedFirstPageChunk = true; + if (!/" : "\n"; + str += doctype + head; + } + } + if (chunk instanceof Response) return; + str += chunkToString(result, chunk); + } + }; + const renderInstance = await renderComponent(result, displayName, Component, props, slots); + if (containsServerDirective(props)) { + await bufferHeadContent(result); + } + await renderInstance.render(destination); + } catch (e) { + if (AstroError.is(e) && !e.loc) { + e.setLocation({ + file: route?.component + }); + } + throw e; + } + return str; +} +function nonAstroPageNeedsHeadInjection(pageComponent) { + return !!pageComponent?.[needsHeadRenderingSymbol]; +} + +const ClientOnlyPlaceholder = "astro-client-only"; +const hasTriedRenderComponentSymbol = Symbol("hasTriedRenderComponent"); +async function renderJSX(result, vnode) { + switch (true) { + case vnode instanceof HTMLString: + if (vnode.toString().trim() === "") { + return ""; + } + return vnode; + case typeof vnode === "string": + return markHTMLString(escapeHTML(vnode)); + case typeof vnode === "function": + return vnode; + case (!vnode && vnode !== 0): + return ""; + case Array.isArray(vnode): + return markHTMLString( + (await Promise.all(vnode.map((v) => renderJSX(result, v)))).join("") + ); + } + return renderJSXVNode(result, vnode); +} +async function renderJSXVNode(result, vnode) { + if (isVNode(vnode)) { + switch (true) { + case !vnode.type: { + throw new Error(`Unable to render ${result.pathname} because it contains an undefined Component! +Did you forget to import the component or is it possible there is a typo?`); + } + case vnode.type === Symbol.for("astro:fragment"): + return renderJSX(result, vnode.props.children); + case isAstroComponentFactory(vnode.type): { + let props = {}; + let slots = {}; + for (const [key, value] of Object.entries(vnode.props ?? {})) { + if (key === "children" || value && typeof value === "object" && value["$$slot"]) { + slots[key === "children" ? "default" : key] = () => renderJSX(result, value); + } else { + props[key] = value; + } + } + const str = await renderComponentToString( + result, + vnode.type.name, + vnode.type, + props, + slots + ); + const html = markHTMLString(str); + return html; + } + case (!vnode.type && vnode.type !== 0): + return ""; + case (typeof vnode.type === "string" && vnode.type !== ClientOnlyPlaceholder): + return markHTMLString(await renderElement(result, vnode.type, vnode.props ?? {})); + } + if (vnode.type) { + let extractSlots2 = function(child) { + if (Array.isArray(child)) { + return child.map((c) => extractSlots2(c)); + } + if (!isVNode(child)) { + _slots.default.push(child); + return; + } + if ("slot" in child.props) { + _slots[child.props.slot] = [..._slots[child.props.slot] ?? [], child]; + delete child.props.slot; + return; + } + _slots.default.push(child); + }; + if (typeof vnode.type === "function" && vnode.props["server:root"]) { + const output2 = await vnode.type(vnode.props ?? {}); + return await renderJSX(result, output2); + } + if (typeof vnode.type === "function") { + if (vnode.props[hasTriedRenderComponentSymbol]) { + delete vnode.props[hasTriedRenderComponentSymbol]; + const output2 = await vnode.type(vnode.props ?? {}); + if (output2?.[AstroJSX] || !output2) { + return await renderJSXVNode(result, output2); + } else { + return; + } + } else { + vnode.props[hasTriedRenderComponentSymbol] = true; + } + } + const { children = null, ...props } = vnode.props ?? {}; + const _slots = { + default: [] + }; + extractSlots2(children); + for (const [key, value] of Object.entries(props)) { + if (value?.["$$slot"]) { + _slots[key] = value; + delete props[key]; + } + } + const slotPromises = []; + const slots = {}; + for (const [key, value] of Object.entries(_slots)) { + slotPromises.push( + renderJSX(result, value).then((output2) => { + if (output2.toString().trim().length === 0) return; + slots[key] = () => output2; + }) + ); + } + await Promise.all(slotPromises); + let output; + if (vnode.type === ClientOnlyPlaceholder && vnode.props["client:only"]) { + output = await renderComponentToString( + result, + vnode.props["client:display-name"] ?? "", + null, + props, + slots + ); + } else { + output = await renderComponentToString( + result, + typeof vnode.type === "function" ? vnode.type.name : vnode.type, + vnode.type, + props, + slots + ); + } + return markHTMLString(output); + } + } + return markHTMLString(`${vnode}`); +} +async function renderElement(result, tag, { children, ...props }) { + return markHTMLString( + `<${tag}${spreadAttributes(props)}${markHTMLString( + (children == null || children == "") && voidElementNames.test(tag) ? `/>` : `>${children == null ? "" : await renderJSX(result, prerenderElementChildren(tag, children))}` + )}` + ); +} +function prerenderElementChildren(tag, children) { + if (typeof children === "string" && (tag === "style" || tag === "script")) { + return markHTMLString(children); + } else { + return children; + } +} + +async function renderPage(result, componentFactory, props, children, streaming, route) { + if (!isAstroComponentFactory(componentFactory)) { + result._metadata.headInTree = result.componentMetadata.get(componentFactory.moduleId)?.containsHead ?? false; + const pageProps = { ...props ?? {}, "server:root": true }; + const str = await renderComponentToString( + result, + componentFactory.name, + componentFactory, + pageProps, + {}, + true, + route + ); + const bytes = encoder.encode(str); + const headers2 = new Headers([ + ["Content-Type", "text/html"], + ["Content-Length", bytes.byteLength.toString()] + ]); + if (result.shouldInjectCspMetaTags && (result.cspDestination === "header" || result.cspDestination === "adapter")) { + headers2.set("content-security-policy", renderCspContent(result)); + } + return new Response(bytes, { + headers: headers2 + }); + } + result._metadata.headInTree = result.componentMetadata.get(componentFactory.moduleId)?.containsHead ?? false; + let body; + if (streaming) { + if (isNode && !isDeno) { + const nodeBody = await renderToAsyncIterable( + result, + componentFactory, + props, + children, + true, + route + ); + body = nodeBody; + } else { + body = await renderToReadableStream(result, componentFactory, props, children, true, route); + } + } else { + body = await renderToString(result, componentFactory, props, children, true, route); + } + if (body instanceof Response) return body; + const init = result.response; + const headers = new Headers(init.headers); + if (result.shouldInjectCspMetaTags && result.cspDestination === "header" || result.cspDestination === "adapter") { + headers.set("content-security-policy", renderCspContent(result)); + } + if (!streaming && typeof body === "string") { + body = encoder.encode(body); + headers.set("Content-Length", body.byteLength.toString()); + } + let status = init.status; + let statusText = init.statusText; + if (route?.route === "/404") { + status = 404; + if (statusText === "OK") { + statusText = "Not Found"; + } + } else if (route?.route === "/500") { + status = 500; + if (statusText === "OK") { + statusText = "Internal Server Error"; + } + } + if (status) { + return new Response(body, { ...init, headers, status, statusText }); + } else { + return new Response(body, { ...init, headers }); + } +} + +"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_".split("").reduce((v, c) => (v[c.charCodeAt(0)] = c, v), []); +"-0123456789_".split("").reduce((v, c) => (v[c.charCodeAt(0)] = c, v), []); + +function spreadAttributes(values = {}, _name, { class: scopedClassName } = {}) { + let output = ""; + if (scopedClassName) { + if (typeof values.class !== "undefined") { + values.class += ` ${scopedClassName}`; + } else if (typeof values["class:list"] !== "undefined") { + values["class:list"] = [values["class:list"], scopedClassName]; + } else { + values.class = scopedClassName; + } + } + for (const [key, value] of Object.entries(values)) { + output += addAttribute(value, key, true, _name); + } + return markHTMLString(output); +} + +export { SessionStorageInitError as $, AstroError as A, MiddlewareNotAResponse as B, originPathnameSymbol as C, RewriteWithBodyUsed as D, ExpectedImage as E, FailedToFetchRemoteImageDimensions as F, GetStaticPathsRequired as G, InvalidGetStaticPathsReturn as H, IncompatibleDescriptorOptions as I, InvalidGetStaticPathsEntry as J, GetStaticPathsExpectedParams as K, LocalImageUsedWrongly as L, MissingImageDimension as M, NoImageMetadata as N, GetStaticPathsInvalidRouteParam as O, PageNumberParamNotFound as P, DEFAULT_404_COMPONENT as Q, ROUTE_TYPE_HEADER as R, NoMatchingStaticPathFound as S, PrerenderDynamicEndpointPathCollide as T, UnsupportedImageFormat as U, ReservedSlotName as V, renderSlotToString as W, renderJSX as X, chunkToString as Y, isRenderInstruction as Z, ForbiddenRewrite as _, UnsupportedImageConversion as a, SessionStorageSaveError as a0, ASTRO_VERSION as a1, CspNotEnabled as a2, LocalsReassigned as a3, generateCspDigest as a4, PrerenderClientAddressNotAvailable as a5, clientAddressSymbol as a6, ClientAddressNotAvailable as a7, StaticClientAddressNotAvailable as a8, AstroResponseHeadersReassigned as a9, responseSentSymbol as aa, renderPage as ab, REWRITE_DIRECTIVE_HEADER_KEY as ac, REWRITE_DIRECTIVE_HEADER_VALUE as ad, renderEndpoint as ae, LocalsNotAnObject as af, REROUTABLE_STATUS_CODES as ag, nodeRequestAbortControllerCleanupSymbol as ah, NOOP_MIDDLEWARE_HEADER as ai, REDIRECT_STATUS_CODES as aj, ActionsReturnedInvalidDataError as ak, MissingSharp as al, ExpectedImageOptions as b, ExpectedNotESMImage as c, InvalidImageService as d, createComponent as e, createAstro as f, ImageMissingAlt as g, addAttribute as h, ExperimentalFontsNotEnabled as i, FontFamilyNotFound as j, renderHead as k, decodeKey as l, maybeRenderHead as m, decryptString as n, createSlotValueFromString as o, isAstroComponentFactory as p, renderComponent as q, renderTemplate as r, spreadAttributes as s, toStyleString as t, unescapeHTML as u, REROUTE_DIRECTIVE_HEADER as v, i18nNoLocaleFoundInPath as w, ResponseSentError as x, ActionNotFoundError as y, MiddlewareNoDataOrNextCalled as z }; diff --git a/workbench/astro/dist/server/chunks/fs-lite_COtHaKzy.mjs b/workbench/astro/dist/server/chunks/fs-lite_COtHaKzy.mjs new file mode 100644 index 000000000..7dc736af8 --- /dev/null +++ b/workbench/astro/dist/server/chunks/fs-lite_COtHaKzy.mjs @@ -0,0 +1,157 @@ +import { promises, existsSync } from 'node:fs'; +import { resolve, dirname, join } from 'node:path'; + +function defineDriver(factory) { + return factory; +} +function createError(driver, message, opts) { + const err = new Error(`[unstorage] [${driver}] ${message}`, opts); + if (Error.captureStackTrace) { + Error.captureStackTrace(err, createError); + } + return err; +} +function createRequiredError(driver, name) { + if (Array.isArray(name)) { + return createError( + driver, + `Missing some of the required options ${name.map((n) => "`" + n + "`").join(", ")}` + ); + } + return createError(driver, `Missing required option \`${name}\`.`); +} + +function ignoreNotfound(err) { + return err.code === "ENOENT" || err.code === "EISDIR" ? null : err; +} +function ignoreExists(err) { + return err.code === "EEXIST" ? null : err; +} +async function writeFile(path, data, encoding) { + await ensuredir(dirname(path)); + return promises.writeFile(path, data, encoding); +} +function readFile(path, encoding) { + return promises.readFile(path, encoding).catch(ignoreNotfound); +} +function unlink(path) { + return promises.unlink(path).catch(ignoreNotfound); +} +function readdir(dir) { + return promises.readdir(dir, { withFileTypes: true }).catch(ignoreNotfound).then((r) => r || []); +} +async function ensuredir(dir) { + if (existsSync(dir)) { + return; + } + await ensuredir(dirname(dir)).catch(ignoreExists); + await promises.mkdir(dir).catch(ignoreExists); +} +async function readdirRecursive(dir, ignore, maxDepth) { + if (ignore && ignore(dir)) { + return []; + } + const entries = await readdir(dir); + const files = []; + await Promise.all( + entries.map(async (entry) => { + const entryPath = resolve(dir, entry.name); + if (entry.isDirectory()) { + if (maxDepth === void 0 || maxDepth > 0) { + const dirFiles = await readdirRecursive( + entryPath, + ignore, + maxDepth === void 0 ? void 0 : maxDepth - 1 + ); + files.push(...dirFiles.map((f) => entry.name + "/" + f)); + } + } else { + if (!(ignore && ignore(entry.name))) { + files.push(entry.name); + } + } + }) + ); + return files; +} +async function rmRecursive(dir) { + const entries = await readdir(dir); + await Promise.all( + entries.map((entry) => { + const entryPath = resolve(dir, entry.name); + if (entry.isDirectory()) { + return rmRecursive(entryPath).then(() => promises.rmdir(entryPath)); + } else { + return promises.unlink(entryPath); + } + }) + ); +} + +const PATH_TRAVERSE_RE = /\.\.:|\.\.$/; +const DRIVER_NAME = "fs-lite"; +const fsLite = defineDriver((opts = {}) => { + if (!opts.base) { + throw createRequiredError(DRIVER_NAME, "base"); + } + opts.base = resolve(opts.base); + const r = (key) => { + if (PATH_TRAVERSE_RE.test(key)) { + throw createError( + DRIVER_NAME, + `Invalid key: ${JSON.stringify(key)}. It should not contain .. segments` + ); + } + const resolved = join(opts.base, key.replace(/:/g, "/")); + return resolved; + }; + return { + name: DRIVER_NAME, + options: opts, + flags: { + maxDepth: true + }, + hasItem(key) { + return existsSync(r(key)); + }, + getItem(key) { + return readFile(r(key), "utf8"); + }, + getItemRaw(key) { + return readFile(r(key)); + }, + async getMeta(key) { + const { atime, mtime, size, birthtime, ctime } = await promises.stat(r(key)).catch(() => ({})); + return { atime, mtime, size, birthtime, ctime }; + }, + setItem(key, value) { + if (opts.readOnly) { + return; + } + return writeFile(r(key), value, "utf8"); + }, + setItemRaw(key, value) { + if (opts.readOnly) { + return; + } + return writeFile(r(key), value); + }, + removeItem(key) { + if (opts.readOnly) { + return; + } + return unlink(r(key)); + }, + getKeys(_base, topts) { + return readdirRecursive(r("."), opts.ignore, topts?.maxDepth); + }, + async clear() { + if (opts.readOnly || opts.noClear) { + return; + } + await rmRecursive(r(".")); + } + }; +}); + +export { fsLite as default }; diff --git a/workbench/astro/dist/server/chunks/index_DqQ8k47W.mjs b/workbench/astro/dist/server/chunks/index_DqQ8k47W.mjs new file mode 100644 index 000000000..46cd94fb3 --- /dev/null +++ b/workbench/astro/dist/server/chunks/index_DqQ8k47W.mjs @@ -0,0 +1,2319 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** only globals that common to node and browsers are allowed */ +// eslint-disable-next-line node/no-unsupported-features/es-builtins +var _globalThis = typeof globalThis === 'object' ? globalThis : global; + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// this is autogenerated file, see scripts/version-update.js +var VERSION = '1.9.0'; + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var re = /^(\d+)\.(\d+)\.(\d+)(-(.+))?$/; +/** + * Create a function to test an API version to see if it is compatible with the provided ownVersion. + * + * The returned function has the following semantics: + * - Exact match is always compatible + * - Major versions must match exactly + * - 1.x package cannot use global 2.x package + * - 2.x package cannot use global 1.x package + * - The minor version of the API module requesting access to the global API must be less than or equal to the minor version of this API + * - 1.3 package may use 1.4 global because the later global contains all functions 1.3 expects + * - 1.4 package may NOT use 1.3 global because it may try to call functions which don't exist on 1.3 + * - If the major version is 0, the minor version is treated as the major and the patch is treated as the minor + * - Patch and build tag differences are not considered at this time + * + * @param ownVersion version which should be checked against + */ +function _makeCompatibilityCheck(ownVersion) { + var acceptedVersions = new Set([ownVersion]); + var rejectedVersions = new Set(); + var myVersionMatch = ownVersion.match(re); + if (!myVersionMatch) { + // we cannot guarantee compatibility so we always return noop + return function () { return false; }; + } + var ownVersionParsed = { + major: +myVersionMatch[1], + minor: +myVersionMatch[2], + patch: +myVersionMatch[3], + prerelease: myVersionMatch[4], + }; + // if ownVersion has a prerelease tag, versions must match exactly + if (ownVersionParsed.prerelease != null) { + return function isExactmatch(globalVersion) { + return globalVersion === ownVersion; + }; + } + function _reject(v) { + rejectedVersions.add(v); + return false; + } + function _accept(v) { + acceptedVersions.add(v); + return true; + } + return function isCompatible(globalVersion) { + if (acceptedVersions.has(globalVersion)) { + return true; + } + if (rejectedVersions.has(globalVersion)) { + return false; + } + var globalVersionMatch = globalVersion.match(re); + if (!globalVersionMatch) { + // cannot parse other version + // we cannot guarantee compatibility so we always noop + return _reject(globalVersion); + } + var globalVersionParsed = { + major: +globalVersionMatch[1], + minor: +globalVersionMatch[2], + patch: +globalVersionMatch[3], + prerelease: globalVersionMatch[4], + }; + // if globalVersion has a prerelease tag, versions must match exactly + if (globalVersionParsed.prerelease != null) { + return _reject(globalVersion); + } + // major versions must match + if (ownVersionParsed.major !== globalVersionParsed.major) { + return _reject(globalVersion); + } + if (ownVersionParsed.major === 0) { + if (ownVersionParsed.minor === globalVersionParsed.minor && + ownVersionParsed.patch <= globalVersionParsed.patch) { + return _accept(globalVersion); + } + return _reject(globalVersion); + } + if (ownVersionParsed.minor <= globalVersionParsed.minor) { + return _accept(globalVersion); + } + return _reject(globalVersion); + }; +} +/** + * Test an API version to see if it is compatible with this API. + * + * - Exact match is always compatible + * - Major versions must match exactly + * - 1.x package cannot use global 2.x package + * - 2.x package cannot use global 1.x package + * - The minor version of the API module requesting access to the global API must be less than or equal to the minor version of this API + * - 1.3 package may use 1.4 global because the later global contains all functions 1.3 expects + * - 1.4 package may NOT use 1.3 global because it may try to call functions which don't exist on 1.3 + * - If the major version is 0, the minor version is treated as the major and the patch is treated as the minor + * - Patch and build tag differences are not considered at this time + * + * @param version version of the API requesting an instance of the global API + */ +var isCompatible = _makeCompatibilityCheck(VERSION); + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var major = VERSION.split('.')[0]; +var GLOBAL_OPENTELEMETRY_API_KEY = Symbol.for("opentelemetry.js.api." + major); +var _global = _globalThis; +function registerGlobal(type, instance, diag, allowOverride) { + var _a; + if (allowOverride === void 0) { allowOverride = false; } + var api = (_global[GLOBAL_OPENTELEMETRY_API_KEY] = (_a = _global[GLOBAL_OPENTELEMETRY_API_KEY]) !== null && _a !== void 0 ? _a : { + version: VERSION, + }); + if (!allowOverride && api[type]) { + // already registered an API of this type + var err = new Error("@opentelemetry/api: Attempted duplicate registration of API: " + type); + diag.error(err.stack || err.message); + return false; + } + if (api.version !== VERSION) { + // All registered APIs must be of the same version exactly + var err = new Error("@opentelemetry/api: Registration of version v" + api.version + " for " + type + " does not match previously registered API v" + VERSION); + diag.error(err.stack || err.message); + return false; + } + api[type] = instance; + diag.debug("@opentelemetry/api: Registered a global for " + type + " v" + VERSION + "."); + return true; +} +function getGlobal(type) { + var _a, _b; + var globalVersion = (_a = _global[GLOBAL_OPENTELEMETRY_API_KEY]) === null || _a === void 0 ? void 0 : _a.version; + if (!globalVersion || !isCompatible(globalVersion)) { + return; + } + return (_b = _global[GLOBAL_OPENTELEMETRY_API_KEY]) === null || _b === void 0 ? void 0 : _b[type]; +} +function unregisterGlobal(type, diag) { + diag.debug("@opentelemetry/api: Unregistering a global for " + type + " v" + VERSION + "."); + var api = _global[GLOBAL_OPENTELEMETRY_API_KEY]; + if (api) { + delete api[type]; + } +} + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var __read$4 = (undefined && undefined.__read) || function (o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } + catch (error) { e = { error: error }; } + finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } + finally { if (e) throw e.error; } + } + return ar; +}; +var __spreadArray$3 = (undefined && undefined.__spreadArray) || function (to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); +}; +/** + * Component Logger which is meant to be used as part of any component which + * will add automatically additional namespace in front of the log message. + * It will then forward all message to global diag logger + * @example + * const cLogger = diag.createComponentLogger({ namespace: '@opentelemetry/instrumentation-http' }); + * cLogger.debug('test'); + * // @opentelemetry/instrumentation-http test + */ +var DiagComponentLogger = /** @class */ (function () { + function DiagComponentLogger(props) { + this._namespace = props.namespace || 'DiagComponentLogger'; + } + DiagComponentLogger.prototype.debug = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + return logProxy('debug', this._namespace, args); + }; + DiagComponentLogger.prototype.error = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + return logProxy('error', this._namespace, args); + }; + DiagComponentLogger.prototype.info = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + return logProxy('info', this._namespace, args); + }; + DiagComponentLogger.prototype.warn = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + return logProxy('warn', this._namespace, args); + }; + DiagComponentLogger.prototype.verbose = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + return logProxy('verbose', this._namespace, args); + }; + return DiagComponentLogger; +}()); +function logProxy(funcName, namespace, args) { + var logger = getGlobal('diag'); + // shortcut if logger not set + if (!logger) { + return; + } + args.unshift(namespace); + return logger[funcName].apply(logger, __spreadArray$3([], __read$4(args), false)); +} + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Defines the available internal logging levels for the diagnostic logger, the numeric values + * of the levels are defined to match the original values from the initial LogLevel to avoid + * compatibility/migration issues for any implementation that assume the numeric ordering. + */ +var DiagLogLevel; +(function (DiagLogLevel) { + /** Diagnostic Logging level setting to disable all logging (except and forced logs) */ + DiagLogLevel[DiagLogLevel["NONE"] = 0] = "NONE"; + /** Identifies an error scenario */ + DiagLogLevel[DiagLogLevel["ERROR"] = 30] = "ERROR"; + /** Identifies a warning scenario */ + DiagLogLevel[DiagLogLevel["WARN"] = 50] = "WARN"; + /** General informational log message */ + DiagLogLevel[DiagLogLevel["INFO"] = 60] = "INFO"; + /** General debug log message */ + DiagLogLevel[DiagLogLevel["DEBUG"] = 70] = "DEBUG"; + /** + * Detailed trace level logging should only be used for development, should only be set + * in a development environment. + */ + DiagLogLevel[DiagLogLevel["VERBOSE"] = 80] = "VERBOSE"; + /** Used to set the logging level to include all logging */ + DiagLogLevel[DiagLogLevel["ALL"] = 9999] = "ALL"; +})(DiagLogLevel || (DiagLogLevel = {})); + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +function createLogLevelDiagLogger(maxLevel, logger) { + if (maxLevel < DiagLogLevel.NONE) { + maxLevel = DiagLogLevel.NONE; + } + else if (maxLevel > DiagLogLevel.ALL) { + maxLevel = DiagLogLevel.ALL; + } + // In case the logger is null or undefined + logger = logger || {}; + function _filterFunc(funcName, theLevel) { + var theFunc = logger[funcName]; + if (typeof theFunc === 'function' && maxLevel >= theLevel) { + return theFunc.bind(logger); + } + return function () { }; + } + return { + error: _filterFunc('error', DiagLogLevel.ERROR), + warn: _filterFunc('warn', DiagLogLevel.WARN), + info: _filterFunc('info', DiagLogLevel.INFO), + debug: _filterFunc('debug', DiagLogLevel.DEBUG), + verbose: _filterFunc('verbose', DiagLogLevel.VERBOSE), + }; +} + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var __read$3 = (undefined && undefined.__read) || function (o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } + catch (error) { e = { error: error }; } + finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } + finally { if (e) throw e.error; } + } + return ar; +}; +var __spreadArray$2 = (undefined && undefined.__spreadArray) || function (to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); +}; +var API_NAME$4 = 'diag'; +/** + * Singleton object which represents the entry point to the OpenTelemetry internal + * diagnostic API + */ +var DiagAPI = /** @class */ (function () { + /** + * Private internal constructor + * @private + */ + function DiagAPI() { + function _logProxy(funcName) { + return function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + var logger = getGlobal('diag'); + // shortcut if logger not set + if (!logger) + return; + return logger[funcName].apply(logger, __spreadArray$2([], __read$3(args), false)); + }; + } + // Using self local variable for minification purposes as 'this' cannot be minified + var self = this; + // DiagAPI specific functions + var setLogger = function (logger, optionsOrLogLevel) { + var _a, _b, _c; + if (optionsOrLogLevel === void 0) { optionsOrLogLevel = { logLevel: DiagLogLevel.INFO }; } + if (logger === self) { + // There isn't much we can do here. + // Logging to the console might break the user application. + // Try to log to self. If a logger was previously registered it will receive the log. + var err = new Error('Cannot use diag as the logger for itself. Please use a DiagLogger implementation like ConsoleDiagLogger or a custom implementation'); + self.error((_a = err.stack) !== null && _a !== void 0 ? _a : err.message); + return false; + } + if (typeof optionsOrLogLevel === 'number') { + optionsOrLogLevel = { + logLevel: optionsOrLogLevel, + }; + } + var oldLogger = getGlobal('diag'); + var newLogger = createLogLevelDiagLogger((_b = optionsOrLogLevel.logLevel) !== null && _b !== void 0 ? _b : DiagLogLevel.INFO, logger); + // There already is an logger registered. We'll let it know before overwriting it. + if (oldLogger && !optionsOrLogLevel.suppressOverrideMessage) { + var stack = (_c = new Error().stack) !== null && _c !== void 0 ? _c : ''; + oldLogger.warn("Current logger will be overwritten from " + stack); + newLogger.warn("Current logger will overwrite one already registered from " + stack); + } + return registerGlobal('diag', newLogger, self, true); + }; + self.setLogger = setLogger; + self.disable = function () { + unregisterGlobal(API_NAME$4, self); + }; + self.createComponentLogger = function (options) { + return new DiagComponentLogger(options); + }; + self.verbose = _logProxy('verbose'); + self.debug = _logProxy('debug'); + self.info = _logProxy('info'); + self.warn = _logProxy('warn'); + self.error = _logProxy('error'); + } + /** Get the singleton instance of the DiagAPI API */ + DiagAPI.instance = function () { + if (!this._instance) { + this._instance = new DiagAPI(); + } + return this._instance; + }; + return DiagAPI; +}()); + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var __read$2 = (undefined && undefined.__read) || function (o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } + catch (error) { e = { error: error }; } + finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } + finally { if (e) throw e.error; } + } + return ar; +}; +var __values = (undefined && undefined.__values) || function(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; + if (m) return m.call(o); + if (o && typeof o.length === "number") return { + next: function () { + if (o && i >= o.length) o = void 0; + return { value: o && o[i++], done: !o }; + } + }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); +}; +var BaggageImpl = /** @class */ (function () { + function BaggageImpl(entries) { + this._entries = entries ? new Map(entries) : new Map(); + } + BaggageImpl.prototype.getEntry = function (key) { + var entry = this._entries.get(key); + if (!entry) { + return undefined; + } + return Object.assign({}, entry); + }; + BaggageImpl.prototype.getAllEntries = function () { + return Array.from(this._entries.entries()).map(function (_a) { + var _b = __read$2(_a, 2), k = _b[0], v = _b[1]; + return [k, v]; + }); + }; + BaggageImpl.prototype.setEntry = function (key, entry) { + var newBaggage = new BaggageImpl(this._entries); + newBaggage._entries.set(key, entry); + return newBaggage; + }; + BaggageImpl.prototype.removeEntry = function (key) { + var newBaggage = new BaggageImpl(this._entries); + newBaggage._entries.delete(key); + return newBaggage; + }; + BaggageImpl.prototype.removeEntries = function () { + var e_1, _a; + var keys = []; + for (var _i = 0; _i < arguments.length; _i++) { + keys[_i] = arguments[_i]; + } + var newBaggage = new BaggageImpl(this._entries); + try { + for (var keys_1 = __values(keys), keys_1_1 = keys_1.next(); !keys_1_1.done; keys_1_1 = keys_1.next()) { + var key = keys_1_1.value; + newBaggage._entries.delete(key); + } + } + catch (e_1_1) { e_1 = { error: e_1_1 }; } + finally { + try { + if (keys_1_1 && !keys_1_1.done && (_a = keys_1.return)) _a.call(keys_1); + } + finally { if (e_1) throw e_1.error; } + } + return newBaggage; + }; + BaggageImpl.prototype.clear = function () { + return new BaggageImpl(); + }; + return BaggageImpl; +}()); + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Symbol used to make BaggageEntryMetadata an opaque type + */ +var baggageEntryMetadataSymbol = Symbol('BaggageEntryMetadata'); + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var diag$1 = DiagAPI.instance(); +/** + * Create a new Baggage with optional entries + * + * @param entries An array of baggage entries the new baggage should contain + */ +function createBaggage(entries) { + if (entries === void 0) { entries = {}; } + return new BaggageImpl(new Map(Object.entries(entries))); +} +/** + * Create a serializable BaggageEntryMetadata object from a string. + * + * @param str string metadata. Format is currently not defined by the spec and has no special meaning. + * + */ +function baggageEntryMetadataFromString(str) { + if (typeof str !== 'string') { + diag$1.error("Cannot create baggage metadata from unknown type: " + typeof str); + str = ''; + } + return { + __TYPE__: baggageEntryMetadataSymbol, + toString: function () { + return str; + }, + }; +} + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** Get a key to uniquely identify a context value */ +function createContextKey(description) { + // The specification states that for the same input, multiple calls should + // return different keys. Due to the nature of the JS dependency management + // system, this creates problems where multiple versions of some package + // could hold different keys for the same property. + // + // Therefore, we use Symbol.for which returns the same key for the same input. + return Symbol.for(description); +} +var BaseContext = /** @class */ (function () { + /** + * Construct a new context which inherits values from an optional parent context. + * + * @param parentContext a context from which to inherit values + */ + function BaseContext(parentContext) { + // for minification + var self = this; + self._currentContext = parentContext ? new Map(parentContext) : new Map(); + self.getValue = function (key) { return self._currentContext.get(key); }; + self.setValue = function (key, value) { + var context = new BaseContext(self._currentContext); + context._currentContext.set(key, value); + return context; + }; + self.deleteValue = function (key) { + var context = new BaseContext(self._currentContext); + context._currentContext.delete(key); + return context; + }; + } + return BaseContext; +}()); +/** The root context is used as the default parent context when there is no active context */ +var ROOT_CONTEXT = new BaseContext(); + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var consoleMap = [ + { n: 'error', c: 'error' }, + { n: 'warn', c: 'warn' }, + { n: 'info', c: 'info' }, + { n: 'debug', c: 'debug' }, + { n: 'verbose', c: 'trace' }, +]; +/** + * A simple Immutable Console based diagnostic logger which will output any messages to the Console. + * If you want to limit the amount of logging to a specific level or lower use the + * {@link createLogLevelDiagLogger} + */ +var DiagConsoleLogger = /** @class */ (function () { + function DiagConsoleLogger() { + function _consoleFunc(funcName) { + return function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + if (console) { + // Some environments only expose the console when the F12 developer console is open + // eslint-disable-next-line no-console + var theFunc = console[funcName]; + if (typeof theFunc !== 'function') { + // Not all environments support all functions + // eslint-disable-next-line no-console + theFunc = console.log; + } + // One last final check + if (typeof theFunc === 'function') { + return theFunc.apply(console, args); + } + } + }; + } + for (var i = 0; i < consoleMap.length; i++) { + this[consoleMap[i].n] = _consoleFunc(consoleMap[i].c); + } + } + return DiagConsoleLogger; +}()); + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var __extends = (undefined && undefined.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +/** + * NoopMeter is a noop implementation of the {@link Meter} interface. It reuses + * constant NoopMetrics for all of its methods. + */ +var NoopMeter = /** @class */ (function () { + function NoopMeter() { + } + /** + * @see {@link Meter.createGauge} + */ + NoopMeter.prototype.createGauge = function (_name, _options) { + return NOOP_GAUGE_METRIC; + }; + /** + * @see {@link Meter.createHistogram} + */ + NoopMeter.prototype.createHistogram = function (_name, _options) { + return NOOP_HISTOGRAM_METRIC; + }; + /** + * @see {@link Meter.createCounter} + */ + NoopMeter.prototype.createCounter = function (_name, _options) { + return NOOP_COUNTER_METRIC; + }; + /** + * @see {@link Meter.createUpDownCounter} + */ + NoopMeter.prototype.createUpDownCounter = function (_name, _options) { + return NOOP_UP_DOWN_COUNTER_METRIC; + }; + /** + * @see {@link Meter.createObservableGauge} + */ + NoopMeter.prototype.createObservableGauge = function (_name, _options) { + return NOOP_OBSERVABLE_GAUGE_METRIC; + }; + /** + * @see {@link Meter.createObservableCounter} + */ + NoopMeter.prototype.createObservableCounter = function (_name, _options) { + return NOOP_OBSERVABLE_COUNTER_METRIC; + }; + /** + * @see {@link Meter.createObservableUpDownCounter} + */ + NoopMeter.prototype.createObservableUpDownCounter = function (_name, _options) { + return NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC; + }; + /** + * @see {@link Meter.addBatchObservableCallback} + */ + NoopMeter.prototype.addBatchObservableCallback = function (_callback, _observables) { }; + /** + * @see {@link Meter.removeBatchObservableCallback} + */ + NoopMeter.prototype.removeBatchObservableCallback = function (_callback) { }; + return NoopMeter; +}()); +var NoopMetric = /** @class */ (function () { + function NoopMetric() { + } + return NoopMetric; +}()); +var NoopCounterMetric = /** @class */ (function (_super) { + __extends(NoopCounterMetric, _super); + function NoopCounterMetric() { + return _super !== null && _super.apply(this, arguments) || this; + } + NoopCounterMetric.prototype.add = function (_value, _attributes) { }; + return NoopCounterMetric; +}(NoopMetric)); +var NoopUpDownCounterMetric = /** @class */ (function (_super) { + __extends(NoopUpDownCounterMetric, _super); + function NoopUpDownCounterMetric() { + return _super !== null && _super.apply(this, arguments) || this; + } + NoopUpDownCounterMetric.prototype.add = function (_value, _attributes) { }; + return NoopUpDownCounterMetric; +}(NoopMetric)); +var NoopGaugeMetric = /** @class */ (function (_super) { + __extends(NoopGaugeMetric, _super); + function NoopGaugeMetric() { + return _super !== null && _super.apply(this, arguments) || this; + } + NoopGaugeMetric.prototype.record = function (_value, _attributes) { }; + return NoopGaugeMetric; +}(NoopMetric)); +var NoopHistogramMetric = /** @class */ (function (_super) { + __extends(NoopHistogramMetric, _super); + function NoopHistogramMetric() { + return _super !== null && _super.apply(this, arguments) || this; + } + NoopHistogramMetric.prototype.record = function (_value, _attributes) { }; + return NoopHistogramMetric; +}(NoopMetric)); +var NoopObservableMetric = /** @class */ (function () { + function NoopObservableMetric() { + } + NoopObservableMetric.prototype.addCallback = function (_callback) { }; + NoopObservableMetric.prototype.removeCallback = function (_callback) { }; + return NoopObservableMetric; +}()); +var NoopObservableCounterMetric = /** @class */ (function (_super) { + __extends(NoopObservableCounterMetric, _super); + function NoopObservableCounterMetric() { + return _super !== null && _super.apply(this, arguments) || this; + } + return NoopObservableCounterMetric; +}(NoopObservableMetric)); +var NoopObservableGaugeMetric = /** @class */ (function (_super) { + __extends(NoopObservableGaugeMetric, _super); + function NoopObservableGaugeMetric() { + return _super !== null && _super.apply(this, arguments) || this; + } + return NoopObservableGaugeMetric; +}(NoopObservableMetric)); +var NoopObservableUpDownCounterMetric = /** @class */ (function (_super) { + __extends(NoopObservableUpDownCounterMetric, _super); + function NoopObservableUpDownCounterMetric() { + return _super !== null && _super.apply(this, arguments) || this; + } + return NoopObservableUpDownCounterMetric; +}(NoopObservableMetric)); +var NOOP_METER = new NoopMeter(); +// Synchronous instruments +var NOOP_COUNTER_METRIC = new NoopCounterMetric(); +var NOOP_GAUGE_METRIC = new NoopGaugeMetric(); +var NOOP_HISTOGRAM_METRIC = new NoopHistogramMetric(); +var NOOP_UP_DOWN_COUNTER_METRIC = new NoopUpDownCounterMetric(); +// Asynchronous instruments +var NOOP_OBSERVABLE_COUNTER_METRIC = new NoopObservableCounterMetric(); +var NOOP_OBSERVABLE_GAUGE_METRIC = new NoopObservableGaugeMetric(); +var NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC = new NoopObservableUpDownCounterMetric(); +/** + * Create a no-op Meter + */ +function createNoopMeter() { + return NOOP_METER; +} + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** The Type of value. It describes how the data is reported. */ +var ValueType; +(function (ValueType) { + ValueType[ValueType["INT"] = 0] = "INT"; + ValueType[ValueType["DOUBLE"] = 1] = "DOUBLE"; +})(ValueType || (ValueType = {})); + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var defaultTextMapGetter = { + get: function (carrier, key) { + if (carrier == null) { + return undefined; + } + return carrier[key]; + }, + keys: function (carrier) { + if (carrier == null) { + return []; + } + return Object.keys(carrier); + }, +}; +var defaultTextMapSetter = { + set: function (carrier, key, value) { + if (carrier == null) { + return; + } + carrier[key] = value; + }, +}; + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var __read$1 = (undefined && undefined.__read) || function (o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } + catch (error) { e = { error: error }; } + finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } + finally { if (e) throw e.error; } + } + return ar; +}; +var __spreadArray$1 = (undefined && undefined.__spreadArray) || function (to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); +}; +var NoopContextManager = /** @class */ (function () { + function NoopContextManager() { + } + NoopContextManager.prototype.active = function () { + return ROOT_CONTEXT; + }; + NoopContextManager.prototype.with = function (_context, fn, thisArg) { + var args = []; + for (var _i = 3; _i < arguments.length; _i++) { + args[_i - 3] = arguments[_i]; + } + return fn.call.apply(fn, __spreadArray$1([thisArg], __read$1(args), false)); + }; + NoopContextManager.prototype.bind = function (_context, target) { + return target; + }; + NoopContextManager.prototype.enable = function () { + return this; + }; + NoopContextManager.prototype.disable = function () { + return this; + }; + return NoopContextManager; +}()); + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var __read = (undefined && undefined.__read) || function (o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } + catch (error) { e = { error: error }; } + finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } + finally { if (e) throw e.error; } + } + return ar; +}; +var __spreadArray = (undefined && undefined.__spreadArray) || function (to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); +}; +var API_NAME$3 = 'context'; +var NOOP_CONTEXT_MANAGER = new NoopContextManager(); +/** + * Singleton object which represents the entry point to the OpenTelemetry Context API + */ +var ContextAPI = /** @class */ (function () { + /** Empty private constructor prevents end users from constructing a new instance of the API */ + function ContextAPI() { + } + /** Get the singleton instance of the Context API */ + ContextAPI.getInstance = function () { + if (!this._instance) { + this._instance = new ContextAPI(); + } + return this._instance; + }; + /** + * Set the current context manager. + * + * @returns true if the context manager was successfully registered, else false + */ + ContextAPI.prototype.setGlobalContextManager = function (contextManager) { + return registerGlobal(API_NAME$3, contextManager, DiagAPI.instance()); + }; + /** + * Get the currently active context + */ + ContextAPI.prototype.active = function () { + return this._getContextManager().active(); + }; + /** + * Execute a function with an active context + * + * @param context context to be active during function execution + * @param fn function to execute in a context + * @param thisArg optional receiver to be used for calling fn + * @param args optional arguments forwarded to fn + */ + ContextAPI.prototype.with = function (context, fn, thisArg) { + var _a; + var args = []; + for (var _i = 3; _i < arguments.length; _i++) { + args[_i - 3] = arguments[_i]; + } + return (_a = this._getContextManager()).with.apply(_a, __spreadArray([context, fn, thisArg], __read(args), false)); + }; + /** + * Bind a context to a target function or event emitter + * + * @param context context to bind to the event emitter or function. Defaults to the currently active context + * @param target function or event emitter to bind + */ + ContextAPI.prototype.bind = function (context, target) { + return this._getContextManager().bind(context, target); + }; + ContextAPI.prototype._getContextManager = function () { + return getGlobal(API_NAME$3) || NOOP_CONTEXT_MANAGER; + }; + /** Disable and remove the global context manager */ + ContextAPI.prototype.disable = function () { + this._getContextManager().disable(); + unregisterGlobal(API_NAME$3, DiagAPI.instance()); + }; + return ContextAPI; +}()); + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var TraceFlags; +(function (TraceFlags) { + /** Represents no flag set. */ + TraceFlags[TraceFlags["NONE"] = 0] = "NONE"; + /** Bit to represent whether trace is sampled in trace flags. */ + TraceFlags[TraceFlags["SAMPLED"] = 1] = "SAMPLED"; +})(TraceFlags || (TraceFlags = {})); + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var INVALID_SPANID = '0000000000000000'; +var INVALID_TRACEID = '00000000000000000000000000000000'; +var INVALID_SPAN_CONTEXT = { + traceId: INVALID_TRACEID, + spanId: INVALID_SPANID, + traceFlags: TraceFlags.NONE, +}; + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * The NonRecordingSpan is the default {@link Span} that is used when no Span + * implementation is available. All operations are no-op including context + * propagation. + */ +var NonRecordingSpan = /** @class */ (function () { + function NonRecordingSpan(_spanContext) { + if (_spanContext === void 0) { _spanContext = INVALID_SPAN_CONTEXT; } + this._spanContext = _spanContext; + } + // Returns a SpanContext. + NonRecordingSpan.prototype.spanContext = function () { + return this._spanContext; + }; + // By default does nothing + NonRecordingSpan.prototype.setAttribute = function (_key, _value) { + return this; + }; + // By default does nothing + NonRecordingSpan.prototype.setAttributes = function (_attributes) { + return this; + }; + // By default does nothing + NonRecordingSpan.prototype.addEvent = function (_name, _attributes) { + return this; + }; + NonRecordingSpan.prototype.addLink = function (_link) { + return this; + }; + NonRecordingSpan.prototype.addLinks = function (_links) { + return this; + }; + // By default does nothing + NonRecordingSpan.prototype.setStatus = function (_status) { + return this; + }; + // By default does nothing + NonRecordingSpan.prototype.updateName = function (_name) { + return this; + }; + // By default does nothing + NonRecordingSpan.prototype.end = function (_endTime) { }; + // isRecording always returns false for NonRecordingSpan. + NonRecordingSpan.prototype.isRecording = function () { + return false; + }; + // By default does nothing + NonRecordingSpan.prototype.recordException = function (_exception, _time) { }; + return NonRecordingSpan; +}()); + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * span key + */ +var SPAN_KEY = createContextKey('OpenTelemetry Context Key SPAN'); +/** + * Return the span if one exists + * + * @param context context to get span from + */ +function getSpan(context) { + return context.getValue(SPAN_KEY) || undefined; +} +/** + * Gets the span from the current context, if one exists. + */ +function getActiveSpan() { + return getSpan(ContextAPI.getInstance().active()); +} +/** + * Set the span on a context + * + * @param context context to use as parent + * @param span span to set active + */ +function setSpan(context, span) { + return context.setValue(SPAN_KEY, span); +} +/** + * Remove current span stored in the context + * + * @param context context to delete span from + */ +function deleteSpan(context) { + return context.deleteValue(SPAN_KEY); +} +/** + * Wrap span context in a NoopSpan and set as span in a new + * context + * + * @param context context to set active span on + * @param spanContext span context to be wrapped + */ +function setSpanContext(context, spanContext) { + return setSpan(context, new NonRecordingSpan(spanContext)); +} +/** + * Get the span context of the span if it exists. + * + * @param context context to get values from + */ +function getSpanContext(context) { + var _a; + return (_a = getSpan(context)) === null || _a === void 0 ? void 0 : _a.spanContext(); +} + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var VALID_TRACEID_REGEX = /^([0-9a-f]{32})$/i; +var VALID_SPANID_REGEX = /^[0-9a-f]{16}$/i; +function isValidTraceId(traceId) { + return VALID_TRACEID_REGEX.test(traceId) && traceId !== INVALID_TRACEID; +} +function isValidSpanId(spanId) { + return VALID_SPANID_REGEX.test(spanId) && spanId !== INVALID_SPANID; +} +/** + * Returns true if this {@link SpanContext} is valid. + * @return true if this {@link SpanContext} is valid. + */ +function isSpanContextValid(spanContext) { + return (isValidTraceId(spanContext.traceId) && isValidSpanId(spanContext.spanId)); +} +/** + * Wrap the given {@link SpanContext} in a new non-recording {@link Span} + * + * @param spanContext span context to be wrapped + * @returns a new non-recording {@link Span} with the provided context + */ +function wrapSpanContext(spanContext) { + return new NonRecordingSpan(spanContext); +} + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var contextApi = ContextAPI.getInstance(); +/** + * No-op implementations of {@link Tracer}. + */ +var NoopTracer = /** @class */ (function () { + function NoopTracer() { + } + // startSpan starts a noop span. + NoopTracer.prototype.startSpan = function (name, options, context) { + if (context === void 0) { context = contextApi.active(); } + var root = Boolean(options === null || options === void 0 ? void 0 : options.root); + if (root) { + return new NonRecordingSpan(); + } + var parentFromContext = context && getSpanContext(context); + if (isSpanContext(parentFromContext) && + isSpanContextValid(parentFromContext)) { + return new NonRecordingSpan(parentFromContext); + } + else { + return new NonRecordingSpan(); + } + }; + NoopTracer.prototype.startActiveSpan = function (name, arg2, arg3, arg4) { + var opts; + var ctx; + var fn; + if (arguments.length < 2) { + return; + } + else if (arguments.length === 2) { + fn = arg2; + } + else if (arguments.length === 3) { + opts = arg2; + fn = arg3; + } + else { + opts = arg2; + ctx = arg3; + fn = arg4; + } + var parentContext = ctx !== null && ctx !== void 0 ? ctx : contextApi.active(); + var span = this.startSpan(name, opts, parentContext); + var contextWithSpanSet = setSpan(parentContext, span); + return contextApi.with(contextWithSpanSet, fn, undefined, span); + }; + return NoopTracer; +}()); +function isSpanContext(spanContext) { + return (typeof spanContext === 'object' && + typeof spanContext['spanId'] === 'string' && + typeof spanContext['traceId'] === 'string' && + typeof spanContext['traceFlags'] === 'number'); +} + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var NOOP_TRACER = new NoopTracer(); +/** + * Proxy tracer provided by the proxy tracer provider + */ +var ProxyTracer = /** @class */ (function () { + function ProxyTracer(_provider, name, version, options) { + this._provider = _provider; + this.name = name; + this.version = version; + this.options = options; + } + ProxyTracer.prototype.startSpan = function (name, options, context) { + return this._getTracer().startSpan(name, options, context); + }; + ProxyTracer.prototype.startActiveSpan = function (_name, _options, _context, _fn) { + var tracer = this._getTracer(); + return Reflect.apply(tracer.startActiveSpan, tracer, arguments); + }; + /** + * Try to get a tracer from the proxy tracer provider. + * If the proxy tracer provider has no delegate, return a noop tracer. + */ + ProxyTracer.prototype._getTracer = function () { + if (this._delegate) { + return this._delegate; + } + var tracer = this._provider.getDelegateTracer(this.name, this.version, this.options); + if (!tracer) { + return NOOP_TRACER; + } + this._delegate = tracer; + return this._delegate; + }; + return ProxyTracer; +}()); + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * An implementation of the {@link TracerProvider} which returns an impotent + * Tracer for all calls to `getTracer`. + * + * All operations are no-op. + */ +var NoopTracerProvider = /** @class */ (function () { + function NoopTracerProvider() { + } + NoopTracerProvider.prototype.getTracer = function (_name, _version, _options) { + return new NoopTracer(); + }; + return NoopTracerProvider; +}()); + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var NOOP_TRACER_PROVIDER = new NoopTracerProvider(); +/** + * Tracer provider which provides {@link ProxyTracer}s. + * + * Before a delegate is set, tracers provided are NoOp. + * When a delegate is set, traces are provided from the delegate. + * When a delegate is set after tracers have already been provided, + * all tracers already provided will use the provided delegate implementation. + */ +var ProxyTracerProvider = /** @class */ (function () { + function ProxyTracerProvider() { + } + /** + * Get a {@link ProxyTracer} + */ + ProxyTracerProvider.prototype.getTracer = function (name, version, options) { + var _a; + return ((_a = this.getDelegateTracer(name, version, options)) !== null && _a !== void 0 ? _a : new ProxyTracer(this, name, version, options)); + }; + ProxyTracerProvider.prototype.getDelegate = function () { + var _a; + return (_a = this._delegate) !== null && _a !== void 0 ? _a : NOOP_TRACER_PROVIDER; + }; + /** + * Set the delegate tracer provider + */ + ProxyTracerProvider.prototype.setDelegate = function (delegate) { + this._delegate = delegate; + }; + ProxyTracerProvider.prototype.getDelegateTracer = function (name, version, options) { + var _a; + return (_a = this._delegate) === null || _a === void 0 ? void 0 : _a.getTracer(name, version, options); + }; + return ProxyTracerProvider; +}()); + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @deprecated use the one declared in @opentelemetry/sdk-trace-base instead. + * A sampling decision that determines how a {@link Span} will be recorded + * and collected. + */ +var SamplingDecision; +(function (SamplingDecision) { + /** + * `Span.isRecording() === false`, span will not be recorded and all events + * and attributes will be dropped. + */ + SamplingDecision[SamplingDecision["NOT_RECORD"] = 0] = "NOT_RECORD"; + /** + * `Span.isRecording() === true`, but `Sampled` flag in {@link TraceFlags} + * MUST NOT be set. + */ + SamplingDecision[SamplingDecision["RECORD"] = 1] = "RECORD"; + /** + * `Span.isRecording() === true` AND `Sampled` flag in {@link TraceFlags} + * MUST be set. + */ + SamplingDecision[SamplingDecision["RECORD_AND_SAMPLED"] = 2] = "RECORD_AND_SAMPLED"; +})(SamplingDecision || (SamplingDecision = {})); + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var SpanKind; +(function (SpanKind) { + /** Default value. Indicates that the span is used internally. */ + SpanKind[SpanKind["INTERNAL"] = 0] = "INTERNAL"; + /** + * Indicates that the span covers server-side handling of an RPC or other + * remote request. + */ + SpanKind[SpanKind["SERVER"] = 1] = "SERVER"; + /** + * Indicates that the span covers the client-side wrapper around an RPC or + * other remote request. + */ + SpanKind[SpanKind["CLIENT"] = 2] = "CLIENT"; + /** + * Indicates that the span describes producer sending a message to a + * broker. Unlike client and server, there is no direct critical path latency + * relationship between producer and consumer spans. + */ + SpanKind[SpanKind["PRODUCER"] = 3] = "PRODUCER"; + /** + * Indicates that the span describes consumer receiving a message from a + * broker. Unlike client and server, there is no direct critical path latency + * relationship between producer and consumer spans. + */ + SpanKind[SpanKind["CONSUMER"] = 4] = "CONSUMER"; +})(SpanKind || (SpanKind = {})); + +/** + * An enumeration of status codes. + */ +var SpanStatusCode; +(function (SpanStatusCode) { + /** + * The default status. + */ + SpanStatusCode[SpanStatusCode["UNSET"] = 0] = "UNSET"; + /** + * The operation has been validated by an Application developer or + * Operator to have completed successfully. + */ + SpanStatusCode[SpanStatusCode["OK"] = 1] = "OK"; + /** + * The operation contains an error. + */ + SpanStatusCode[SpanStatusCode["ERROR"] = 2] = "ERROR"; +})(SpanStatusCode || (SpanStatusCode = {})); + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var VALID_KEY_CHAR_RANGE = '[_0-9a-z-*/]'; +var VALID_KEY = "[a-z]" + VALID_KEY_CHAR_RANGE + "{0,255}"; +var VALID_VENDOR_KEY = "[a-z0-9]" + VALID_KEY_CHAR_RANGE + "{0,240}@[a-z]" + VALID_KEY_CHAR_RANGE + "{0,13}"; +var VALID_KEY_REGEX = new RegExp("^(?:" + VALID_KEY + "|" + VALID_VENDOR_KEY + ")$"); +var VALID_VALUE_BASE_REGEX = /^[ -~]{0,255}[!-~]$/; +var INVALID_VALUE_COMMA_EQUAL_REGEX = /,|=/; +/** + * Key is opaque string up to 256 characters printable. It MUST begin with a + * lowercase letter, and can only contain lowercase letters a-z, digits 0-9, + * underscores _, dashes -, asterisks *, and forward slashes /. + * For multi-tenant vendor scenarios, an at sign (@) can be used to prefix the + * vendor name. Vendors SHOULD set the tenant ID at the beginning of the key. + * see https://www.w3.org/TR/trace-context/#key + */ +function validateKey(key) { + return VALID_KEY_REGEX.test(key); +} +/** + * Value is opaque string up to 256 characters printable ASCII RFC0020 + * characters (i.e., the range 0x20 to 0x7E) except comma , and =. + */ +function validateValue(value) { + return (VALID_VALUE_BASE_REGEX.test(value) && + !INVALID_VALUE_COMMA_EQUAL_REGEX.test(value)); +} + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var MAX_TRACE_STATE_ITEMS = 32; +var MAX_TRACE_STATE_LEN = 512; +var LIST_MEMBERS_SEPARATOR = ','; +var LIST_MEMBER_KEY_VALUE_SPLITTER = '='; +/** + * TraceState must be a class and not a simple object type because of the spec + * requirement (https://www.w3.org/TR/trace-context/#tracestate-field). + * + * Here is the list of allowed mutations: + * - New key-value pair should be added into the beginning of the list + * - The value of any key can be updated. Modified keys MUST be moved to the + * beginning of the list. + */ +var TraceStateImpl = /** @class */ (function () { + function TraceStateImpl(rawTraceState) { + this._internalState = new Map(); + if (rawTraceState) + this._parse(rawTraceState); + } + TraceStateImpl.prototype.set = function (key, value) { + // TODO: Benchmark the different approaches(map vs list) and + // use the faster one. + var traceState = this._clone(); + if (traceState._internalState.has(key)) { + traceState._internalState.delete(key); + } + traceState._internalState.set(key, value); + return traceState; + }; + TraceStateImpl.prototype.unset = function (key) { + var traceState = this._clone(); + traceState._internalState.delete(key); + return traceState; + }; + TraceStateImpl.prototype.get = function (key) { + return this._internalState.get(key); + }; + TraceStateImpl.prototype.serialize = function () { + var _this = this; + return this._keys() + .reduce(function (agg, key) { + agg.push(key + LIST_MEMBER_KEY_VALUE_SPLITTER + _this.get(key)); + return agg; + }, []) + .join(LIST_MEMBERS_SEPARATOR); + }; + TraceStateImpl.prototype._parse = function (rawTraceState) { + if (rawTraceState.length > MAX_TRACE_STATE_LEN) + return; + this._internalState = rawTraceState + .split(LIST_MEMBERS_SEPARATOR) + .reverse() // Store in reverse so new keys (.set(...)) will be placed at the beginning + .reduce(function (agg, part) { + var listMember = part.trim(); // Optional Whitespace (OWS) handling + var i = listMember.indexOf(LIST_MEMBER_KEY_VALUE_SPLITTER); + if (i !== -1) { + var key = listMember.slice(0, i); + var value = listMember.slice(i + 1, part.length); + if (validateKey(key) && validateValue(value)) { + agg.set(key, value); + } + } + return agg; + }, new Map()); + // Because of the reverse() requirement, trunc must be done after map is created + if (this._internalState.size > MAX_TRACE_STATE_ITEMS) { + this._internalState = new Map(Array.from(this._internalState.entries()) + .reverse() // Use reverse same as original tracestate parse chain + .slice(0, MAX_TRACE_STATE_ITEMS)); + } + }; + TraceStateImpl.prototype._keys = function () { + return Array.from(this._internalState.keys()).reverse(); + }; + TraceStateImpl.prototype._clone = function () { + var traceState = new TraceStateImpl(); + traceState._internalState = new Map(this._internalState); + return traceState; + }; + return TraceStateImpl; +}()); + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +function createTraceState(rawTraceState) { + return new TraceStateImpl(rawTraceState); +} + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// Split module-level variable definition into separate files to allow +// tree-shaking on each api instance. +/** Entrypoint for context API */ +var context = ContextAPI.getInstance(); + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// Split module-level variable definition into separate files to allow +// tree-shaking on each api instance. +/** + * Entrypoint for Diag API. + * Defines Diagnostic handler used for internal diagnostic logging operations. + * The default provides a Noop DiagLogger implementation which may be changed via the + * diag.setLogger(logger: DiagLogger) function. + */ +var diag = DiagAPI.instance(); + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * An implementation of the {@link MeterProvider} which returns an impotent Meter + * for all calls to `getMeter` + */ +var NoopMeterProvider = /** @class */ (function () { + function NoopMeterProvider() { + } + NoopMeterProvider.prototype.getMeter = function (_name, _version, _options) { + return NOOP_METER; + }; + return NoopMeterProvider; +}()); +var NOOP_METER_PROVIDER = new NoopMeterProvider(); + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var API_NAME$2 = 'metrics'; +/** + * Singleton object which represents the entry point to the OpenTelemetry Metrics API + */ +var MetricsAPI = /** @class */ (function () { + /** Empty private constructor prevents end users from constructing a new instance of the API */ + function MetricsAPI() { + } + /** Get the singleton instance of the Metrics API */ + MetricsAPI.getInstance = function () { + if (!this._instance) { + this._instance = new MetricsAPI(); + } + return this._instance; + }; + /** + * Set the current global meter provider. + * Returns true if the meter provider was successfully registered, else false. + */ + MetricsAPI.prototype.setGlobalMeterProvider = function (provider) { + return registerGlobal(API_NAME$2, provider, DiagAPI.instance()); + }; + /** + * Returns the global meter provider. + */ + MetricsAPI.prototype.getMeterProvider = function () { + return getGlobal(API_NAME$2) || NOOP_METER_PROVIDER; + }; + /** + * Returns a meter from the global meter provider. + */ + MetricsAPI.prototype.getMeter = function (name, version, options) { + return this.getMeterProvider().getMeter(name, version, options); + }; + /** Remove the global meter provider */ + MetricsAPI.prototype.disable = function () { + unregisterGlobal(API_NAME$2, DiagAPI.instance()); + }; + return MetricsAPI; +}()); + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// Split module-level variable definition into separate files to allow +// tree-shaking on each api instance. +/** Entrypoint for metrics API */ +var metrics = MetricsAPI.getInstance(); + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * No-op implementations of {@link TextMapPropagator}. + */ +var NoopTextMapPropagator = /** @class */ (function () { + function NoopTextMapPropagator() { + } + /** Noop inject function does nothing */ + NoopTextMapPropagator.prototype.inject = function (_context, _carrier) { }; + /** Noop extract function does nothing and returns the input context */ + NoopTextMapPropagator.prototype.extract = function (context, _carrier) { + return context; + }; + NoopTextMapPropagator.prototype.fields = function () { + return []; + }; + return NoopTextMapPropagator; +}()); + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Baggage key + */ +var BAGGAGE_KEY = createContextKey('OpenTelemetry Baggage Key'); +/** + * Retrieve the current baggage from the given context + * + * @param {Context} Context that manage all context values + * @returns {Baggage} Extracted baggage from the context + */ +function getBaggage(context) { + return context.getValue(BAGGAGE_KEY) || undefined; +} +/** + * Retrieve the current baggage from the active/current context + * + * @returns {Baggage} Extracted baggage from the context + */ +function getActiveBaggage() { + return getBaggage(ContextAPI.getInstance().active()); +} +/** + * Store a baggage in the given context + * + * @param {Context} Context that manage all context values + * @param {Baggage} baggage that will be set in the actual context + */ +function setBaggage(context, baggage) { + return context.setValue(BAGGAGE_KEY, baggage); +} +/** + * Delete the baggage stored in the given context + * + * @param {Context} Context that manage all context values + */ +function deleteBaggage(context) { + return context.deleteValue(BAGGAGE_KEY); +} + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var API_NAME$1 = 'propagation'; +var NOOP_TEXT_MAP_PROPAGATOR = new NoopTextMapPropagator(); +/** + * Singleton object which represents the entry point to the OpenTelemetry Propagation API + */ +var PropagationAPI = /** @class */ (function () { + /** Empty private constructor prevents end users from constructing a new instance of the API */ + function PropagationAPI() { + this.createBaggage = createBaggage; + this.getBaggage = getBaggage; + this.getActiveBaggage = getActiveBaggage; + this.setBaggage = setBaggage; + this.deleteBaggage = deleteBaggage; + } + /** Get the singleton instance of the Propagator API */ + PropagationAPI.getInstance = function () { + if (!this._instance) { + this._instance = new PropagationAPI(); + } + return this._instance; + }; + /** + * Set the current propagator. + * + * @returns true if the propagator was successfully registered, else false + */ + PropagationAPI.prototype.setGlobalPropagator = function (propagator) { + return registerGlobal(API_NAME$1, propagator, DiagAPI.instance()); + }; + /** + * Inject context into a carrier to be propagated inter-process + * + * @param context Context carrying tracing data to inject + * @param carrier carrier to inject context into + * @param setter Function used to set values on the carrier + */ + PropagationAPI.prototype.inject = function (context, carrier, setter) { + if (setter === void 0) { setter = defaultTextMapSetter; } + return this._getGlobalPropagator().inject(context, carrier, setter); + }; + /** + * Extract context from a carrier + * + * @param context Context which the newly created context will inherit from + * @param carrier Carrier to extract context from + * @param getter Function used to extract keys from a carrier + */ + PropagationAPI.prototype.extract = function (context, carrier, getter) { + if (getter === void 0) { getter = defaultTextMapGetter; } + return this._getGlobalPropagator().extract(context, carrier, getter); + }; + /** + * Return a list of all fields which may be used by the propagator. + */ + PropagationAPI.prototype.fields = function () { + return this._getGlobalPropagator().fields(); + }; + /** Remove the global propagator */ + PropagationAPI.prototype.disable = function () { + unregisterGlobal(API_NAME$1, DiagAPI.instance()); + }; + PropagationAPI.prototype._getGlobalPropagator = function () { + return getGlobal(API_NAME$1) || NOOP_TEXT_MAP_PROPAGATOR; + }; + return PropagationAPI; +}()); + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// Split module-level variable definition into separate files to allow +// tree-shaking on each api instance. +/** Entrypoint for propagation API */ +var propagation = PropagationAPI.getInstance(); + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var API_NAME = 'trace'; +/** + * Singleton object which represents the entry point to the OpenTelemetry Tracing API + */ +var TraceAPI = /** @class */ (function () { + /** Empty private constructor prevents end users from constructing a new instance of the API */ + function TraceAPI() { + this._proxyTracerProvider = new ProxyTracerProvider(); + this.wrapSpanContext = wrapSpanContext; + this.isSpanContextValid = isSpanContextValid; + this.deleteSpan = deleteSpan; + this.getSpan = getSpan; + this.getActiveSpan = getActiveSpan; + this.getSpanContext = getSpanContext; + this.setSpan = setSpan; + this.setSpanContext = setSpanContext; + } + /** Get the singleton instance of the Trace API */ + TraceAPI.getInstance = function () { + if (!this._instance) { + this._instance = new TraceAPI(); + } + return this._instance; + }; + /** + * Set the current global tracer. + * + * @returns true if the tracer provider was successfully registered, else false + */ + TraceAPI.prototype.setGlobalTracerProvider = function (provider) { + var success = registerGlobal(API_NAME, this._proxyTracerProvider, DiagAPI.instance()); + if (success) { + this._proxyTracerProvider.setDelegate(provider); + } + return success; + }; + /** + * Returns the global tracer provider. + */ + TraceAPI.prototype.getTracerProvider = function () { + return getGlobal(API_NAME) || this._proxyTracerProvider; + }; + /** + * Returns a tracer from the global tracer provider. + */ + TraceAPI.prototype.getTracer = function (name, version) { + return this.getTracerProvider().getTracer(name, version); + }; + /** Remove the global tracer provider */ + TraceAPI.prototype.disable = function () { + unregisterGlobal(API_NAME, DiagAPI.instance()); + this._proxyTracerProvider = new ProxyTracerProvider(); + }; + return TraceAPI; +}()); + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// Split module-level variable definition into separate files to allow +// tree-shaking on each api instance. +/** Entrypoint for trace API */ +var trace = TraceAPI.getInstance(); + +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// Default export. +const index = { + context: context, + diag: diag, + metrics: metrics, + propagation: propagation, + trace: trace, +}; + +export { DiagConsoleLogger, DiagLogLevel, INVALID_SPANID, INVALID_SPAN_CONTEXT, INVALID_TRACEID, ProxyTracer, ProxyTracerProvider, ROOT_CONTEXT, SamplingDecision, SpanKind, SpanStatusCode, TraceFlags, ValueType, baggageEntryMetadataFromString, context, createContextKey, createNoopMeter, createTraceState, index as default, defaultTextMapGetter, defaultTextMapSetter, diag, isSpanContextValid, isValidSpanId, isValidTraceId, metrics, propagation, trace }; diff --git a/workbench/astro/dist/server/chunks/index_ePTMDSOu.mjs b/workbench/astro/dist/server/chunks/index_ePTMDSOu.mjs new file mode 100644 index 000000000..9ad416bcd --- /dev/null +++ b/workbench/astro/dist/server/chunks/index_ePTMDSOu.mjs @@ -0,0 +1,42973 @@ +import * as z from 'zod'; +import z__default, { z as z$1, ZodError } from 'zod'; +import * as devalue from 'devalue'; +import { createRequire } from 'node:module'; +import path, { join } from 'node:path'; +import { setTimeout as setTimeout$1, scheduler, setImmediate as setImmediate$1 } from 'node:timers/promises'; +import process$2, { platform, hrtime, execPath, execArgv } from 'node:process'; +import isPlainObject from 'is-plain-obj'; +import url, { fileURLToPath } from 'node:url'; +import { ChildProcess, execFile, spawnSync, spawn } from 'node:child_process'; +import { StringDecoder } from 'node:string_decoder'; +import require$$0$6, { debuglog, stripVTControlCharacters, inspect, promisify, callbackify, aborted } from 'node:util'; +import { gray, redBright, yellowBright, bold } from 'yoctocolors'; +import { c as commonjsGlobal, g as getDefaultExportFromCjs } from './_commonjsHelpers_BFTU3MAI.mjs'; +import require$$0$2 from 'child_process'; +import require$$0$1 from 'path'; +import require$$0 from 'fs'; +import os, { constants as constants$5 } from 'node:os'; +import require$$8, { once as once$2, addAbortListener, EventEmitter, on, setMaxListeners } from 'node:events'; +import { serialize } from 'node:v8'; +import { statSync, readFileSync, appendFileSync, writeFileSync, createWriteStream, createReadStream, promises } from 'node:fs'; +import tty from 'node:tty'; +import require$$0$5, { Transform, getDefaultHighWaterMark, Duplex, Writable, Readable, PassThrough } from 'node:stream'; +import require$$0$3, { Buffer as Buffer$1 } from 'node:buffer'; +import { finished } from 'node:stream/promises'; +import { z as z$2 } from 'zod/v4'; +import crypto from 'node:crypto'; +import require$$0$4 from 'node:assert'; +import require$$4 from 'node:net'; +import require$$2 from 'node:http'; +import require$$7 from 'node:querystring'; +import require$$0$7 from 'node:diagnostics_channel'; +import require$$4$1 from 'node:tls'; +import require$$1 from 'node:zlib'; +import require$$5 from 'node:perf_hooks'; +import require$$8$1 from 'node:util/types'; +import require$$5$1 from 'node:async_hooks'; +import require$$1$1 from 'node:console'; +import require$$5$2 from 'string_decoder'; +import require$$3 from 'node:worker_threads'; +import debug from 'debug'; +import ms from 'ms'; + +var headers$1; +var hasRequiredHeaders$1; + +function requireHeaders$1 () { + if (hasRequiredHeaders$1) return headers$1; + hasRequiredHeaders$1 = 1; + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; + var __getOwnPropNames = Object.getOwnPropertyNames; + var __hasOwnProp = Object.prototype.hasOwnProperty; + var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + var headers_exports = {}; + __export(headers_exports, { + CITY_HEADER_NAME: () => CITY_HEADER_NAME, + COUNTRY_HEADER_NAME: () => COUNTRY_HEADER_NAME, + EMOJI_FLAG_UNICODE_STARTING_POSITION: () => EMOJI_FLAG_UNICODE_STARTING_POSITION, + IP_HEADER_NAME: () => IP_HEADER_NAME, + LATITUDE_HEADER_NAME: () => LATITUDE_HEADER_NAME, + LONGITUDE_HEADER_NAME: () => LONGITUDE_HEADER_NAME, + POSTAL_CODE_HEADER_NAME: () => POSTAL_CODE_HEADER_NAME, + REGION_HEADER_NAME: () => REGION_HEADER_NAME, + REQUEST_ID_HEADER_NAME: () => REQUEST_ID_HEADER_NAME, + geolocation: () => geolocation, + ipAddress: () => ipAddress + }); + headers$1 = __toCommonJS(headers_exports); + const CITY_HEADER_NAME = "x-vercel-ip-city"; + const COUNTRY_HEADER_NAME = "x-vercel-ip-country"; + const IP_HEADER_NAME = "x-real-ip"; + const LATITUDE_HEADER_NAME = "x-vercel-ip-latitude"; + const LONGITUDE_HEADER_NAME = "x-vercel-ip-longitude"; + const REGION_HEADER_NAME = "x-vercel-ip-country-region"; + const POSTAL_CODE_HEADER_NAME = "x-vercel-ip-postal-code"; + const REQUEST_ID_HEADER_NAME = "x-vercel-id"; + const EMOJI_FLAG_UNICODE_STARTING_POSITION = 127397; + function getHeader(headers, key) { + return headers.get(key) ?? void 0; + } + function getHeaderWithDecode(request, key) { + const header = getHeader(request.headers, key); + return header ? decodeURIComponent(header) : void 0; + } + function getFlag(countryCode) { + const regex = new RegExp("^[A-Z]{2}$").test(countryCode); + if (!countryCode || !regex) + return void 0; + return String.fromCodePoint( + ...countryCode.split("").map((char) => EMOJI_FLAG_UNICODE_STARTING_POSITION + char.charCodeAt(0)) + ); + } + function ipAddress(input) { + const headers = "headers" in input ? input.headers : input; + return getHeader(headers, IP_HEADER_NAME); + } + function getRegionFromRequestId(requestId) { + if (!requestId) { + return "dev1"; + } + return requestId.split(":")[0]; + } + function geolocation(request) { + return { + // city name may be encoded to support multi-byte characters + city: getHeaderWithDecode(request, CITY_HEADER_NAME), + country: getHeader(request.headers, COUNTRY_HEADER_NAME), + flag: getFlag(getHeader(request.headers, COUNTRY_HEADER_NAME)), + countryRegion: getHeader(request.headers, REGION_HEADER_NAME), + region: getRegionFromRequestId( + getHeader(request.headers, REQUEST_ID_HEADER_NAME) + ), + latitude: getHeader(request.headers, LATITUDE_HEADER_NAME), + longitude: getHeader(request.headers, LONGITUDE_HEADER_NAME), + postalCode: getHeader(request.headers, POSTAL_CODE_HEADER_NAME) + }; + } + return headers$1; +} + +var getEnv_1; +var hasRequiredGetEnv; + +function requireGetEnv () { + if (hasRequiredGetEnv) return getEnv_1; + hasRequiredGetEnv = 1; + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; + var __getOwnPropNames = Object.getOwnPropertyNames; + var __hasOwnProp = Object.prototype.hasOwnProperty; + var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + var get_env_exports = {}; + __export(get_env_exports, { + getEnv: () => getEnv + }); + getEnv_1 = __toCommonJS(get_env_exports); + const getEnv = (env = process.env) => ({ + /** + * An indicator to show that System Environment Variables have been exposed to your project's Deployments. + * @example "1" + */ + VERCEL: get(env, "VERCEL"), + /** + * An indicator that the code is running in a Continuous Integration environment. + * @example "1" + */ + CI: get(env, "CI"), + /** + * The Environment that the app is deployed and running on. + * @example "production" + */ + VERCEL_ENV: get(env, "VERCEL_ENV"), + /** + * The domain name of the generated deployment URL. The value does not include the protocol scheme https://. + * NOTE: This Variable cannot be used in conjunction with Standard Deployment Protection. + * @example "*.vercel.app" + */ + VERCEL_URL: get(env, "VERCEL_URL"), + /** + * The domain name of the generated Git branch URL. The value does not include the protocol scheme https://. + * @example "*-git-*.vercel.app" + */ + VERCEL_BRANCH_URL: get(env, "VERCEL_BRANCH_URL"), + /** + * A production domain name of the project. This is useful to reliably generate links that point to production such as OG-image URLs. + * The value does not include the protocol scheme https://. + * @example "myproject.vercel.app" + */ + VERCEL_PROJECT_PRODUCTION_URL: get(env, "VERCEL_PROJECT_PRODUCTION_URL"), + /** + * The ID of the Region where the app is running. + * + * Possible values: + * - arn1 (Stockholm, Sweden) + * - bom1 (Mumbai, India) + * - cdg1 (Paris, France) + * - cle1 (Cleveland, USA) + * - cpt1 (Cape Town, South Africa) + * - dub1 (Dublin, Ireland) + * - fra1 (Frankfurt, Germany) + * - gru1 (São Paulo, Brazil) + * - hkg1 (Hong Kong) + * - hnd1 (Tokyo, Japan) + * - iad1 (Washington, D.C., USA) + * - icn1 (Seoul, South Korea) + * - kix1 (Osaka, Japan) + * - lhr1 (London, United Kingdom) + * - pdx1 (Portland, USA) + * - sfo1 (San Francisco, USA) + * - sin1 (Singapore) + * - syd1 (Sydney, Australia) + * - dev1 (Development Region) + * + * @example "iad1" + */ + VERCEL_REGION: get(env, "VERCEL_REGION"), + /** + * The unique identifier for the deployment, which can be used to implement Skew Protection. + * @example "dpl_7Gw5ZMBpQA8h9GF832KGp7nwbuh3" + */ + VERCEL_DEPLOYMENT_ID: get(env, "VERCEL_DEPLOYMENT_ID"), + /** + * When Skew Protection is enabled in Project Settings, this value is set to 1. + * @example "1" + */ + VERCEL_SKEW_PROTECTION_ENABLED: get(env, "VERCEL_SKEW_PROTECTION_ENABLED"), + /** + * The Protection Bypass for Automation value, if the secret has been generated in the project's Deployment Protection settings. + */ + VERCEL_AUTOMATION_BYPASS_SECRET: get(env, "VERCEL_AUTOMATION_BYPASS_SECRET"), + /** + * The Git Provider the deployment is triggered from. + * @example "github" + */ + VERCEL_GIT_PROVIDER: get(env, "VERCEL_GIT_PROVIDER"), + /** + * The origin repository the deployment is triggered from. + * @example "my-site" + */ + VERCEL_GIT_REPO_SLUG: get(env, "VERCEL_GIT_REPO_SLUG"), + /** + * The account that owns the repository the deployment is triggered from. + * @example "acme" + */ + VERCEL_GIT_REPO_OWNER: get(env, "VERCEL_GIT_REPO_OWNER"), + /** + * The ID of the repository the deployment is triggered from. + * @example "117716146" + */ + VERCEL_GIT_REPO_ID: get(env, "VERCEL_GIT_REPO_ID"), + /** + * The git branch of the commit the deployment was triggered by. + * @example "improve-about-page" + */ + VERCEL_GIT_COMMIT_REF: get(env, "VERCEL_GIT_COMMIT_REF"), + /** + * The git SHA of the commit the deployment was triggered by. + * @example "fa1eade47b73733d6312d5abfad33ce9e4068081" + */ + VERCEL_GIT_COMMIT_SHA: get(env, "VERCEL_GIT_COMMIT_SHA"), + /** + * The message attached to the commit the deployment was triggered by. + * @example "Update about page" + */ + VERCEL_GIT_COMMIT_MESSAGE: get(env, "VERCEL_GIT_COMMIT_MESSAGE"), + /** + * The username attached to the author of the commit that the project was deployed by. + * @example "johndoe" + */ + VERCEL_GIT_COMMIT_AUTHOR_LOGIN: get(env, "VERCEL_GIT_COMMIT_AUTHOR_LOGIN"), + /** + * The name attached to the author of the commit that the project was deployed by. + * @example "John Doe" + */ + VERCEL_GIT_COMMIT_AUTHOR_NAME: get(env, "VERCEL_GIT_COMMIT_AUTHOR_NAME"), + /** + * The git SHA of the last successful deployment for the project and branch. + * NOTE: This Variable is only exposed when an Ignored Build Step is provided. + * @example "fa1eade47b73733d6312d5abfad33ce9e4068080" + */ + VERCEL_GIT_PREVIOUS_SHA: get(env, "VERCEL_GIT_PREVIOUS_SHA"), + /** + * The pull request id the deployment was triggered by. If a deployment is created on a branch before a pull request is made, this value will be an empty string. + * @example "23" + */ + VERCEL_GIT_PULL_REQUEST_ID: get(env, "VERCEL_GIT_PULL_REQUEST_ID") + }); + const get = (env, key) => { + const value = env[key]; + return value === "" ? void 0 : value; + }; + return getEnv_1; +} + +var getContext_1$1; +var hasRequiredGetContext$1; + +function requireGetContext$1 () { + if (hasRequiredGetContext$1) return getContext_1$1; + hasRequiredGetContext$1 = 1; + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; + var __getOwnPropNames = Object.getOwnPropertyNames; + var __hasOwnProp = Object.prototype.hasOwnProperty; + var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + var get_context_exports = {}; + __export(get_context_exports, { + SYMBOL_FOR_REQ_CONTEXT: () => SYMBOL_FOR_REQ_CONTEXT, + getContext: () => getContext + }); + getContext_1$1 = __toCommonJS(get_context_exports); + const SYMBOL_FOR_REQ_CONTEXT = Symbol.for("@vercel/request-context"); + function getContext() { + const fromSymbol = globalThis; + return fromSymbol[SYMBOL_FOR_REQ_CONTEXT]?.get?.() ?? {}; + } + return getContext_1$1; +} + +var waitUntil_1; +var hasRequiredWaitUntil; + +function requireWaitUntil () { + if (hasRequiredWaitUntil) return waitUntil_1; + hasRequiredWaitUntil = 1; + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; + var __getOwnPropNames = Object.getOwnPropertyNames; + var __hasOwnProp = Object.prototype.hasOwnProperty; + var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + var wait_until_exports = {}; + __export(wait_until_exports, { + waitUntil: () => waitUntil + }); + waitUntil_1 = __toCommonJS(wait_until_exports); + var import_get_context = requireGetContext$1(); + const waitUntil = (promise) => { + if (promise === null || typeof promise !== "object" || typeof promise.then !== "function") { + throw new TypeError( + `waitUntil can only be called with a Promise, got ${typeof promise}` + ); + } + return (0, import_get_context.getContext)().waitUntil?.(promise); + }; + return waitUntil_1; +} + +var middleware; +var hasRequiredMiddleware; + +function requireMiddleware () { + if (hasRequiredMiddleware) return middleware; + hasRequiredMiddleware = 1; + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; + var __getOwnPropNames = Object.getOwnPropertyNames; + var __hasOwnProp = Object.prototype.hasOwnProperty; + var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + var middleware_exports = {}; + __export(middleware_exports, { + next: () => next, + rewrite: () => rewrite + }); + middleware = __toCommonJS(middleware_exports); + function handleMiddlewareField(init, headers) { + if (init?.request?.headers) { + if (!(init.request.headers instanceof Headers)) { + throw new Error("request.headers must be an instance of Headers"); + } + const keys = []; + for (const [key, value] of init.request.headers) { + headers.set("x-middleware-request-" + key, value); + keys.push(key); + } + headers.set("x-middleware-override-headers", keys.join(",")); + } + } + function rewrite(destination, init) { + const headers = new Headers(init?.headers ?? {}); + headers.set("x-middleware-rewrite", String(destination)); + handleMiddlewareField(init, headers); + return new Response(null, { + ...init, + headers + }); + } + function next(init) { + const headers = new Headers(init?.headers ?? {}); + headers.set("x-middleware-next", "1"); + handleMiddlewareField(init, headers); + return new Response(null, { + ...init, + headers + }); + } + return middleware; +} + +var inMemoryCache; +var hasRequiredInMemoryCache; + +function requireInMemoryCache () { + if (hasRequiredInMemoryCache) return inMemoryCache; + hasRequiredInMemoryCache = 1; + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; + var __getOwnPropNames = Object.getOwnPropertyNames; + var __hasOwnProp = Object.prototype.hasOwnProperty; + var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + var in_memory_cache_exports = {}; + __export(in_memory_cache_exports, { + InMemoryCache: () => InMemoryCache + }); + inMemoryCache = __toCommonJS(in_memory_cache_exports); + class InMemoryCache { + constructor() { + this.cache = {}; + } + async get(key) { + const entry = this.cache[key]; + if (entry) { + if (entry.ttl && entry.lastModified + entry.ttl * 1e3 < Date.now()) { + await this.delete(key); + return null; + } + return entry.value; + } + return null; + } + async set(key, value, options) { + this.cache[key] = { + value, + lastModified: Date.now(), + ttl: options?.ttl, + tags: new Set(options?.tags || []) + }; + } + async delete(key) { + delete this.cache[key]; + } + async expireTag(tag) { + const tags = Array.isArray(tag) ? tag : [tag]; + for (const key in this.cache) { + if (Object.prototype.hasOwnProperty.call(this.cache, key)) { + const entry = this.cache[key]; + if (tags.some((t) => entry.tags.has(t))) { + delete this.cache[key]; + } + } + } + } + } + return inMemoryCache; +} + +var buildClient; +var hasRequiredBuildClient; + +function requireBuildClient () { + if (hasRequiredBuildClient) return buildClient; + hasRequiredBuildClient = 1; + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; + var __getOwnPropNames = Object.getOwnPropertyNames; + var __hasOwnProp = Object.prototype.hasOwnProperty; + var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + var build_client_exports = {}; + __export(build_client_exports, { + BuildCache: () => BuildCache + }); + buildClient = __toCommonJS(build_client_exports); + var import_index = requireCache$1(); + class BuildCache { + constructor({ + endpoint, + headers, + onError, + timeout = 500 + }) { + this.get = async (key) => { + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), this.timeout); + try { + const res = await fetch(`${this.endpoint}${key}`, { + headers: this.headers, + method: "GET", + signal: controller.signal + }); + if (res.status === 404) { + clearTimeout(timeoutId); + return null; + } + if (res.status === 200) { + const cacheState = res.headers.get( + import_index.HEADERS_VERCEL_CACHE_STATE + ); + if (cacheState !== import_index.PkgCacheState.Fresh) { + res.body?.cancel?.(); + clearTimeout(timeoutId); + return null; + } + const result = await res.json(); + clearTimeout(timeoutId); + return result; + } else { + clearTimeout(timeoutId); + throw new Error(`Failed to get cache: ${res.statusText}`); + } + } catch (error) { + clearTimeout(timeoutId); + if (error.name === "AbortError") { + const timeoutError = new Error( + `Cache request timed out after ${this.timeout}ms` + ); + timeoutError.stack = error.stack; + this.onError?.(timeoutError); + } else { + this.onError?.(error); + } + return null; + } + }; + this.set = async (key, value, options) => { + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), this.timeout); + try { + const optionalHeaders = {}; + if (options?.ttl) { + optionalHeaders[import_index.HEADERS_VERCEL_REVALIDATE] = options.ttl.toString(); + } + if (options?.tags && options.tags.length > 0) { + optionalHeaders[import_index.HEADERS_VERCEL_CACHE_TAGS] = options.tags.join(","); + } + if (options?.name) { + optionalHeaders[import_index.HEADERS_VERCEL_CACHE_ITEM_NAME] = options.name; + } + const res = await fetch(`${this.endpoint}${key}`, { + method: "POST", + headers: { + ...this.headers, + ...optionalHeaders + }, + body: JSON.stringify(value), + signal: controller.signal + }); + clearTimeout(timeoutId); + if (res.status !== 200) { + throw new Error(`Failed to set cache: ${res.status} ${res.statusText}`); + } + } catch (error) { + clearTimeout(timeoutId); + if (error.name === "AbortError") { + const timeoutError = new Error( + `Cache request timed out after ${this.timeout}ms` + ); + timeoutError.stack = error.stack; + this.onError?.(timeoutError); + } else { + this.onError?.(error); + } + } + }; + this.delete = async (key) => { + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), this.timeout); + try { + const res = await fetch(`${this.endpoint}${key}`, { + method: "DELETE", + headers: this.headers, + signal: controller.signal + }); + clearTimeout(timeoutId); + if (res.status !== 200) { + throw new Error(`Failed to delete cache: ${res.statusText}`); + } + } catch (error) { + clearTimeout(timeoutId); + if (error.name === "AbortError") { + const timeoutError = new Error( + `Cache request timed out after ${this.timeout}ms` + ); + timeoutError.stack = error.stack; + this.onError?.(timeoutError); + } else { + this.onError?.(error); + } + } + }; + this.expireTag = async (tag) => { + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), this.timeout); + try { + if (Array.isArray(tag)) { + tag = tag.join(","); + } + const res = await fetch(`${this.endpoint}revalidate?tags=${tag}`, { + method: "POST", + headers: this.headers, + signal: controller.signal + }); + clearTimeout(timeoutId); + if (res.status !== 200) { + throw new Error(`Failed to revalidate tag: ${res.statusText}`); + } + } catch (error) { + clearTimeout(timeoutId); + if (error.name === "AbortError") { + const timeoutError = new Error( + `Cache request timed out after ${this.timeout}ms` + ); + timeoutError.stack = error.stack; + this.onError?.(timeoutError); + } else { + this.onError?.(error); + } + } + }; + this.endpoint = endpoint; + this.headers = headers; + this.onError = onError; + this.timeout = timeout; + } + } + return buildClient; +} + +var cache$1; +var hasRequiredCache$1; + +function requireCache$1 () { + if (hasRequiredCache$1) return cache$1; + hasRequiredCache$1 = 1; + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; + var __getOwnPropNames = Object.getOwnPropertyNames; + var __hasOwnProp = Object.prototype.hasOwnProperty; + var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + var cache_exports = {}; + __export(cache_exports, { + HEADERS_VERCEL_CACHE_ITEM_NAME: () => HEADERS_VERCEL_CACHE_ITEM_NAME, + HEADERS_VERCEL_CACHE_STATE: () => HEADERS_VERCEL_CACHE_STATE, + HEADERS_VERCEL_CACHE_TAGS: () => HEADERS_VERCEL_CACHE_TAGS, + HEADERS_VERCEL_REVALIDATE: () => HEADERS_VERCEL_REVALIDATE, + PkgCacheState: () => PkgCacheState, + getCache: () => getCache + }); + cache$1 = __toCommonJS(cache_exports); + var import_get_context = requireGetContext$1(); + var import_in_memory_cache = requireInMemoryCache(); + var import_build_client = requireBuildClient(); + const defaultKeyHashFunction = (key) => { + let hash = 5381; + for (let i = 0; i < key.length; i++) { + hash = hash * 33 ^ key.charCodeAt(i); + } + return (hash >>> 0).toString(16); + }; + const defaultNamespaceSeparator = "$"; + let inMemoryCacheInstance = null; + let buildCacheInstance = null; + const getCache = (cacheOptions) => { + const resolveCache = () => { + let cache; + if ((0, import_get_context.getContext)().cache) { + cache = (0, import_get_context.getContext)().cache; + } else { + cache = getCacheImplementation( + process.env.SUSPENSE_CACHE_DEBUG === "true" + ); + } + return cache; + }; + return wrapWithKeyTransformation( + resolveCache, + createKeyTransformer(cacheOptions) + ); + }; + function createKeyTransformer(cacheOptions) { + const hashFunction = cacheOptions?.keyHashFunction || defaultKeyHashFunction; + return (key) => { + if (!cacheOptions?.namespace) + return hashFunction(key); + const separator = cacheOptions.namespaceSeparator || defaultNamespaceSeparator; + return `${cacheOptions.namespace}${separator}${hashFunction(key)}`; + }; + } + function wrapWithKeyTransformation(resolveCache, makeKey) { + return { + get: (key) => { + return resolveCache().get(makeKey(key)); + }, + set: (key, value, options) => { + return resolveCache().set(makeKey(key), value, options); + }, + delete: (key) => { + return resolveCache().delete(makeKey(key)); + }, + expireTag: (tag) => { + return resolveCache().expireTag(tag); + } + }; + } + let warnedCacheUnavailable = false; + function getCacheImplementation(debug) { + if (!inMemoryCacheInstance) { + inMemoryCacheInstance = new import_in_memory_cache.InMemoryCache(); + } + if (process.env.RUNTIME_CACHE_DISABLE_BUILD_CACHE === "true") { + debug && console.log("Using InMemoryCache as build cache is disabled"); + return inMemoryCacheInstance; + } + const { RUNTIME_CACHE_ENDPOINT, RUNTIME_CACHE_HEADERS } = process.env; + if (debug) { + console.log("Runtime cache environment variables:", { + RUNTIME_CACHE_ENDPOINT, + RUNTIME_CACHE_HEADERS + }); + } + if (!RUNTIME_CACHE_ENDPOINT || !RUNTIME_CACHE_HEADERS) { + if (!warnedCacheUnavailable) { + console.warn( + "Runtime Cache unavailable in this environment. Falling back to in-memory cache." + ); + warnedCacheUnavailable = true; + } + return inMemoryCacheInstance; + } + if (!buildCacheInstance) { + let parsedHeaders = {}; + try { + parsedHeaders = JSON.parse(RUNTIME_CACHE_HEADERS); + } catch (e) { + console.error("Failed to parse RUNTIME_CACHE_HEADERS:", e); + return inMemoryCacheInstance; + } + let timeout = 500; + if (process.env.RUNTIME_CACHE_TIMEOUT) { + const parsed = parseInt(process.env.RUNTIME_CACHE_TIMEOUT, 10); + if (!isNaN(parsed) && parsed > 0) { + timeout = parsed; + } else { + console.warn( + `Invalid RUNTIME_CACHE_TIMEOUT value: "${process.env.RUNTIME_CACHE_TIMEOUT}". Using default: ${timeout}ms` + ); + } + } + buildCacheInstance = new import_build_client.BuildCache({ + endpoint: RUNTIME_CACHE_ENDPOINT, + headers: parsedHeaders, + onError: (error) => console.error(error), + timeout + }); + } + return buildCacheInstance; + } + var PkgCacheState = /* @__PURE__ */ ((PkgCacheState2) => { + PkgCacheState2["Fresh"] = "fresh"; + PkgCacheState2["Stale"] = "stale"; + PkgCacheState2["Expired"] = "expired"; + PkgCacheState2["NotFound"] = "notFound"; + PkgCacheState2["Error"] = "error"; + return PkgCacheState2; + })(PkgCacheState || {}); + const HEADERS_VERCEL_CACHE_STATE = "x-vercel-cache-state"; + const HEADERS_VERCEL_REVALIDATE = "x-vercel-revalidate"; + const HEADERS_VERCEL_CACHE_TAGS = "x-vercel-cache-tags"; + const HEADERS_VERCEL_CACHE_ITEM_NAME = "x-vercel-cache-item-name"; + return cache$1; +} + +var dbConnections; +var hasRequiredDbConnections; + +function requireDbConnections () { + if (hasRequiredDbConnections) return dbConnections; + hasRequiredDbConnections = 1; + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; + var __getOwnPropNames = Object.getOwnPropertyNames; + var __hasOwnProp = Object.prototype.hasOwnProperty; + var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + var db_connections_exports = {}; + __export(db_connections_exports, { + attachDatabasePool: () => attachDatabasePool, + experimental_attachDatabasePool: () => experimental_attachDatabasePool + }); + dbConnections = __toCommonJS(db_connections_exports); + var import_get_context = requireGetContext$1(); + const DEBUG = !!process.env.DEBUG; + function getIdleTimeout(dbPool) { + if ("options" in dbPool && dbPool.options) { + if ("idleTimeoutMillis" in dbPool.options) { + return typeof dbPool.options.idleTimeoutMillis === "number" ? dbPool.options.idleTimeoutMillis : 1e4; + } + if ("maxIdleTimeMS" in dbPool.options) { + return typeof dbPool.options.maxIdleTimeMS === "number" ? dbPool.options.maxIdleTimeMS : 0; + } + if ("status" in dbPool) { + return 5e3; + } + if ("connect" in dbPool && "execute" in dbPool) { + return 3e4; + } + } + if ("config" in dbPool && dbPool.config) { + if ("connectionConfig" in dbPool.config && dbPool.config.connectionConfig) { + return dbPool.config.connectionConfig.idleTimeout || 6e4; + } + if ("idleTimeout" in dbPool.config) { + return typeof dbPool.config.idleTimeout === "number" ? dbPool.config.idleTimeout : 6e4; + } + } + if ("poolTimeout" in dbPool) { + return typeof dbPool.poolTimeout === "number" ? dbPool.poolTimeout : 6e4; + } + if ("idleTimeout" in dbPool) { + return typeof dbPool.idleTimeout === "number" ? dbPool.idleTimeout : 0; + } + return 1e4; + } + let idleTimeout = null; + let idleTimeoutResolve = () => { + }; + const bootTime = Date.now(); + const maximumDuration = 15 * 60 * 1e3 - 1e3; + function waitUntilIdleTimeout(dbPool) { + if (!process.env.VERCEL_URL || // This is not set during builds where we don't need to wait for idle connections using the mechanism + !process.env.VERCEL_REGION) { + return; + } + if (idleTimeout) { + clearTimeout(idleTimeout); + idleTimeoutResolve(); + } + const promise = new Promise((resolve) => { + idleTimeoutResolve = resolve; + }); + const waitTime = Math.min( + getIdleTimeout(dbPool) + 100, + maximumDuration - (Date.now() - bootTime) + ); + idleTimeout = setTimeout(() => { + idleTimeoutResolve?.(); + if (DEBUG) { + console.log("Database pool idle timeout reached. Releasing connections."); + } + }, waitTime); + const requestContext = (0, import_get_context.getContext)(); + if (requestContext?.waitUntil) { + requestContext.waitUntil(promise); + } else { + console.warn("Pool release event triggered outside of request scope."); + } + } + function attachDatabasePool(dbPool) { + if (idleTimeout) { + idleTimeoutResolve?.(); + clearTimeout(idleTimeout); + } + if ("on" in dbPool && dbPool.on && "options" in dbPool && "idleTimeoutMillis" in dbPool.options) { + const pgPool = dbPool; + pgPool.on("release", () => { + if (DEBUG) { + console.log("Client released from pool"); + } + waitUntilIdleTimeout(dbPool); + }); + return; + } else if ("on" in dbPool && dbPool.on && "config" in dbPool && dbPool.config && "connectionConfig" in dbPool.config) { + const mysqlPool = dbPool; + mysqlPool.on("release", () => { + if (DEBUG) { + console.log("MySQL client released from pool"); + } + waitUntilIdleTimeout(dbPool); + }); + return; + } else if ("on" in dbPool && dbPool.on && "config" in dbPool && dbPool.config && "idleTimeout" in dbPool.config) { + const mysql2Pool = dbPool; + mysql2Pool.on("release", () => { + if (DEBUG) { + console.log("MySQL2/MariaDB client released from pool"); + } + waitUntilIdleTimeout(dbPool); + }); + return; + } + if ("on" in dbPool && dbPool.on && "options" in dbPool && dbPool.options && "maxIdleTimeMS" in dbPool.options) { + const mongoPool = dbPool; + mongoPool.on("connectionCheckedOut", () => { + if (DEBUG) { + console.log("MongoDB connection checked out"); + } + waitUntilIdleTimeout(dbPool); + }); + return; + } + if ("on" in dbPool && dbPool.on && "options" in dbPool && dbPool.options && "socket" in dbPool.options) { + const redisPool = dbPool; + redisPool.on("end", () => { + if (DEBUG) { + console.log("Redis connection ended"); + } + waitUntilIdleTimeout(dbPool); + }); + return; + } + throw new Error("Unsupported database pool type"); + } + const experimental_attachDatabasePool = attachDatabasePool; + return dbConnections; +} + +var purge = {exports: {}}; + +var types; +var hasRequiredTypes; + +function requireTypes () { + if (hasRequiredTypes) return types; + hasRequiredTypes = 1; + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; + var __getOwnPropNames = Object.getOwnPropertyNames; + var __hasOwnProp = Object.prototype.hasOwnProperty; + var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + var types_exports = {}; + types = __toCommonJS(types_exports); + return types; +} + +var hasRequiredPurge; + +function requirePurge () { + if (hasRequiredPurge) return purge.exports; + hasRequiredPurge = 1; + (function (module) { + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; + var __getOwnPropNames = Object.getOwnPropertyNames; + var __hasOwnProp = Object.prototype.hasOwnProperty; + var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; + }; + var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default")); + var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + var purge_exports = {}; + __export(purge_exports, { + dangerouslyDeleteByTag: () => dangerouslyDeleteByTag, + invalidateByTag: () => invalidateByTag + }); + module.exports = __toCommonJS(purge_exports); + var import_get_context = requireGetContext$1(); + __reExport(purge_exports, requireTypes(), module.exports); + const invalidateByTag = (tag) => { + const api = (0, import_get_context.getContext)().purge; + if (api) { + return api.invalidateByTag(tag); + } + return Promise.resolve(); + }; + const dangerouslyDeleteByTag = (tag, options) => { + const api = (0, import_get_context.getContext)().purge; + if (api) { + return api.dangerouslyDeleteByTag(tag, options); + } + return Promise.resolve(); + }; + } (purge)); + return purge.exports; +} + +var functions; +var hasRequiredFunctions; + +function requireFunctions () { + if (hasRequiredFunctions) return functions; + hasRequiredFunctions = 1; + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; + var __getOwnPropNames = Object.getOwnPropertyNames; + var __hasOwnProp = Object.prototype.hasOwnProperty; + var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + var src_exports = {}; + __export(src_exports, { + attachDatabasePool: () => import_db_connections.attachDatabasePool, + dangerouslyDeleteByTag: () => import_purge.dangerouslyDeleteByTag, + experimental_attachDatabasePool: () => import_db_connections.experimental_attachDatabasePool, + geolocation: () => import_headers.geolocation, + getCache: () => import_cache.getCache, + getEnv: () => import_get_env.getEnv, + invalidateByTag: () => import_purge.invalidateByTag, + ipAddress: () => import_headers.ipAddress, + next: () => import_middleware.next, + rewrite: () => import_middleware.rewrite, + waitUntil: () => import_wait_until.waitUntil + }); + functions = __toCommonJS(src_exports); + var import_headers = requireHeaders$1(); + var import_get_env = requireGetEnv(); + var import_wait_until = requireWaitUntil(); + var import_middleware = requireMiddleware(); + var import_cache = requireCache$1(); + var import_db_connections = requireDbConnections(); + var import_purge = requirePurge(); + return functions; +} + +var functionsExports = requireFunctions(); + +/** + * Polyfill for `Promise.withResolvers()`. + * + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers + */ +function withResolvers() { + let resolve; + let reject; + const promise = new Promise((_resolve, _reject) => { + resolve = _resolve; + reject = _reject; + }); + return { promise, resolve, reject }; +} +/** + * Creates a lazily-evaluated, memoized version of the provided function. + * + * The returned object exposes a `value` getter that calls `fn` only once, + * caches its result, and returns the cached value on subsequent accesses. + * + * @typeParam T - The return type of the provided function. + * @param fn - The function to be called once and whose result will be cached. + * @returns An object with a `value` property that returns the memoized result of `fn`. + */ +function once$1(fn) { + const result = { + get value() { + const value = fn(); + Object.defineProperty(result, 'value', { value }); + return value; + }, + }; + return result; +} +/** + * Parses a duration parameter (string, number, or Date) and returns a Date object + * representing when the duration should elapse. + * + * - For strings: Parses duration strings like "1s", "5m", "1h", etc. using the `ms` library + * - For numbers: Treats as milliseconds from now + * - For Date objects: Returns the date directly (handles both Date instances and date-like objects from deserialization) + * + * @param param - The duration parameter (StringValue, Date, or number of milliseconds) + * @returns A Date object representing when the duration should elapse + * @throws {Error} If the parameter is invalid or cannot be parsed + */ +function parseDurationToDate(param) { + if (typeof param === 'string') { + const durationMs = ms(param); + if (typeof durationMs !== 'number' || durationMs < 0) { + throw new Error(`Invalid duration: "${param}". Expected a valid duration string like "1s", "1m", "1h", etc.`); + } + return new Date(Date.now() + durationMs); + } + else if (typeof param === 'number') { + if (param < 0 || !Number.isFinite(param)) { + throw new Error(`Invalid duration: ${param}. Expected a non-negative finite number of milliseconds.`); + } + return new Date(Date.now() + param); + } + else if (param instanceof Date || + (param && + typeof param === 'object' && + typeof param.getTime === 'function')) { + // Handle both Date instances and date-like objects (from deserialization) + return param instanceof Date ? param : new Date(param.getTime()); + } + else { + throw new Error(`Invalid duration parameter. Expected a duration string, number (milliseconds), or Date object.`); + } +} + +const BASE_URL = 'https://useworkflow.dev/err'; +/** + * @internal + * Check if a value is an Error without relying on Node.js utilities. + * This is needed for error classes that can be used in VM contexts where + * Node.js imports are not available. + */ +function isError(value) { + return (typeof value === 'object' && + value !== null && + 'name' in value && + 'message' in value); +} +/** + * @internal + * All the slugs of the errors used for documentation links. + */ +const ERROR_SLUGS = { + WEBHOOK_INVALID_RESPOND_WITH_VALUE: 'webhook-invalid-respond-with-value', + WEBHOOK_RESPONSE_NOT_SENT: 'webhook-response-not-sent', + FETCH_IN_WORKFLOW_FUNCTION: 'fetch-in-workflow', +}; +/** + * The base class for all Workflow-related errors. + * + * This error is thrown by the Workflow DevKit when internal operations fail. + * You can use this class with `instanceof` to catch any Workflow DevKit error. + * + * @example + * ```ts + * try { + * await getRun(runId); + * } catch (error) { + * if (error instanceof WorkflowError) { + * console.error('Workflow DevKit error:', error.message); + * } + * } + * ``` + */ +class WorkflowError extends Error { + cause; + constructor(message, options) { + const msgDocs = options?.slug + ? `${message}\n\nLearn more: ${BASE_URL}/${options.slug}` + : message; + super(msgDocs, { cause: options?.cause }); + this.cause = options?.cause; + if (options?.cause instanceof Error) { + this.stack = `${this.stack}\nCaused by: ${options.cause.stack}`; + } + } + static is(value) { + return isError(value) && value.name === 'WorkflowError'; + } +} +/** + * Thrown when a Workflow API request fails. + * + * This error is thrown when HTTP requests to the Workflow backend fail, + * typically due to network issues, invalid requests, or server errors. + * + * @example + * ```ts + * try { + * await startWorkflow('myWorkflow', input); + * } catch (error) { + * if (error instanceof WorkflowAPIError) { + * console.error(`API error (${error.status}):`, error.message); + * } + * } + * ``` + */ +class WorkflowAPIError extends WorkflowError { + status; + code; + url; + constructor(message, options) { + super(message, { + cause: options?.cause, + }); + this.name = 'WorkflowAPIError'; + this.status = options?.status; + this.code = options?.code; + this.url = options?.url; + } + static is(value) { + return isError(value) && value.name === 'WorkflowAPIError'; + } +} +/** + * Thrown when a workflow run fails during execution. + * + * This error indicates that the workflow encountered a fatal error + * and cannot continue. The `cause` property contains the underlying + * error with its message, stack trace, and optional error code. + * + * @example + * ``` + * const run = await getRun(runId); + * if (run.status === 'failed') { + * // WorkflowRunFailedError will be thrown + * } + * ``` + */ +class WorkflowRunFailedError extends WorkflowError { + runId; + constructor(runId, error) { + // Create a proper Error instance from the StructuredError to set as cause + // NOTE: custom error types do not get serialized/deserialized. Everything is an Error + const causeError = new Error(error.message); + if (error.stack) { + causeError.stack = error.stack; + } + if (error.code) { + causeError.code = error.code; + } + super(`Workflow run "${runId}" failed: ${error.message}`, { + cause: causeError, + }); + this.name = 'WorkflowRunFailedError'; + this.runId = runId; + } + static is(value) { + return isError(value) && value.name === 'WorkflowRunFailedError'; + } +} +/** + * Thrown when attempting to get results from an incomplete workflow run. + * + * This error occurs when you try to access the result of a workflow + * that is still running or hasn't completed yet. + */ +class WorkflowRunNotCompletedError extends WorkflowError { + runId; + status; + constructor(runId, status) { + super(`Workflow run "${runId}" has not completed`, {}); + this.name = 'WorkflowRunNotCompletedError'; + this.runId = runId; + this.status = status; + } + static is(value) { + return isError(value) && value.name === 'WorkflowRunNotCompletedError'; + } +} +/** + * Thrown when the Workflow runtime encounters an internal error. + * + * This error indicates an issue with workflow execution, such as + * serialization failures, starting an invalid workflow function, or + * other runtime problems. + */ +class WorkflowRuntimeError extends WorkflowError { + constructor(message, options) { + super(message, { + ...options, + }); + this.name = 'WorkflowRuntimeError'; + } + static is(value) { + return isError(value) && value.name === 'WorkflowRuntimeError'; + } +} +class WorkflowRunNotFoundError extends WorkflowError { + runId; + constructor(runId) { + super(`Workflow run "${runId}" not found`, {}); + this.name = 'WorkflowRunNotFoundError'; + this.runId = runId; + } + static is(value) { + return isError(value) && value.name === 'WorkflowRunNotFoundError'; + } +} +class WorkflowRunCancelledError extends WorkflowError { + runId; + constructor(runId) { + super(`Workflow run "${runId}" cancelled`, {}); + this.name = 'WorkflowRunCancelledError'; + this.runId = runId; + } + static is(value) { + return isError(value) && value.name === 'WorkflowRunCancelledError'; + } +} +/** + * A fatal error is an error that cannot be retried. + * It will cause the step to fail and the error will + * be bubbled up to the workflow logic. + */ +class FatalError extends Error { + fatal = true; + constructor(message) { + super(message); + this.name = 'FatalError'; + } + static is(value) { + return isError(value) && value.name === 'FatalError'; + } +} +/** + * An error that can happen during a step execution, allowing + * for configuration of the retry behavior. + */ +class RetryableError extends Error { + /** + * The Date when the step should be retried. + */ + retryAfter; + constructor(message, options = {}) { + super(message); + this.name = 'RetryableError'; + if (options.retryAfter !== undefined) { + this.retryAfter = parseDurationToDate(options.retryAfter); + } + else { + // Default to 1 second (1000 milliseconds) + this.retryAfter = new Date(Date.now() + 1000); + } + } + static is(value) { + return isError(value) && value.name === 'RetryableError'; + } +} + +// Allow some arguments/options to be either a file path string or a file URL +const safeNormalizeFileUrl = (file, name) => { + const fileString = normalizeFileUrl(normalizeDenoExecPath(file)); + + if (typeof fileString !== 'string') { + throw new TypeError(`${name} must be a string or a file URL: ${fileString}.`); + } + + return fileString; +}; + +// In Deno node:process execPath is a special object, not just a string: +// https://github.com/denoland/deno/blob/f460188e583f00144000aa0d8ade08218d47c3c1/ext/node/polyfills/process.ts#L344 +const normalizeDenoExecPath = file => isDenoExecPath(file) + ? file.toString() + : file; + +const isDenoExecPath = file => typeof file !== 'string' + && file + && Object.getPrototypeOf(file) === String.prototype; + +// Same but also allows other values, e.g. `boolean` for the `shell` option +const normalizeFileUrl = file => file instanceof URL ? fileURLToPath(file) : file; + +// The command `arguments` and `options` are both optional. +// This also does basic validation on them and on the command file. +const normalizeParameters = (rawFile, rawArguments = [], rawOptions = {}) => { + const filePath = safeNormalizeFileUrl(rawFile, 'First argument'); + const [commandArguments, options] = isPlainObject(rawArguments) + ? [[], rawArguments] + : [rawArguments, rawOptions]; + + if (!Array.isArray(commandArguments)) { + throw new TypeError(`Second argument must be either an array of arguments or an options object: ${commandArguments}`); + } + + if (commandArguments.some(commandArgument => typeof commandArgument === 'object' && commandArgument !== null)) { + throw new TypeError(`Second argument must be an array of strings: ${commandArguments}`); + } + + const normalizedArguments = commandArguments.map(String); + const nullByteArgument = normalizedArguments.find(normalizedArgument => normalizedArgument.includes('\0')); + if (nullByteArgument !== undefined) { + throw new TypeError(`Arguments cannot contain null bytes ("\\0"): ${nullByteArgument}`); + } + + if (!isPlainObject(options)) { + throw new TypeError(`Last argument must be an options object: ${options}`); + } + + return [filePath, normalizedArguments, options]; +}; + +const {toString: objectToString$1} = Object.prototype; + +const isArrayBuffer = value => objectToString$1.call(value) === '[object ArrayBuffer]'; + +// Is either Uint8Array or Buffer +const isUint8Array = value => objectToString$1.call(value) === '[object Uint8Array]'; + +const bufferToUint8Array = buffer => new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength); + +const textEncoder$1 = new TextEncoder(); +const stringToUint8Array = string => textEncoder$1.encode(string); + +const textDecoder = new TextDecoder(); +const uint8ArrayToString = uint8Array => textDecoder.decode(uint8Array); + +const joinToString = (uint8ArraysOrStrings, encoding) => { + const strings = uint8ArraysToStrings(uint8ArraysOrStrings, encoding); + return strings.join(''); +}; + +const uint8ArraysToStrings = (uint8ArraysOrStrings, encoding) => { + if (encoding === 'utf8' && uint8ArraysOrStrings.every(uint8ArrayOrString => typeof uint8ArrayOrString === 'string')) { + return uint8ArraysOrStrings; + } + + const decoder = new StringDecoder(encoding); + const strings = uint8ArraysOrStrings + .map(uint8ArrayOrString => typeof uint8ArrayOrString === 'string' + ? stringToUint8Array(uint8ArrayOrString) + : uint8ArrayOrString) + .map(uint8Array => decoder.write(uint8Array)); + const finalString = decoder.end(); + return finalString === '' ? strings : [...strings, finalString]; +}; + +const joinToUint8Array = uint8ArraysOrStrings => { + if (uint8ArraysOrStrings.length === 1 && isUint8Array(uint8ArraysOrStrings[0])) { + return uint8ArraysOrStrings[0]; + } + + return concatUint8Arrays(stringsToUint8Arrays(uint8ArraysOrStrings)); +}; + +const stringsToUint8Arrays = uint8ArraysOrStrings => uint8ArraysOrStrings.map(uint8ArrayOrString => typeof uint8ArrayOrString === 'string' + ? stringToUint8Array(uint8ArrayOrString) + : uint8ArrayOrString); + +const concatUint8Arrays = uint8Arrays => { + const result = new Uint8Array(getJoinLength(uint8Arrays)); + + let index = 0; + for (const uint8Array of uint8Arrays) { + result.set(uint8Array, index); + index += uint8Array.length; + } + + return result; +}; + +const getJoinLength = uint8Arrays => { + let joinLength = 0; + for (const uint8Array of uint8Arrays) { + joinLength += uint8Array.length; + } + + return joinLength; +}; + +// Check whether the template string syntax is being used +const isTemplateString = templates => Array.isArray(templates) && Array.isArray(templates.raw); + +// Convert execa`file ...commandArguments` to execa(file, commandArguments) +const parseTemplates = (templates, expressions) => { + let tokens = []; + + for (const [index, template] of templates.entries()) { + tokens = parseTemplate({ + templates, + expressions, + tokens, + index, + template, + }); + } + + if (tokens.length === 0) { + throw new TypeError('Template script must not be empty'); + } + + const [file, ...commandArguments] = tokens; + return [file, commandArguments, {}]; +}; + +const parseTemplate = ({templates, expressions, tokens, index, template}) => { + if (template === undefined) { + throw new TypeError(`Invalid backslash sequence: ${templates.raw[index]}`); + } + + const {nextTokens, leadingWhitespaces, trailingWhitespaces} = splitByWhitespaces(template, templates.raw[index]); + const newTokens = concatTokens(tokens, nextTokens, leadingWhitespaces); + + if (index === expressions.length) { + return newTokens; + } + + const expression = expressions[index]; + const expressionTokens = Array.isArray(expression) + ? expression.map(expression => parseExpression(expression)) + : [parseExpression(expression)]; + return concatTokens(newTokens, expressionTokens, trailingWhitespaces); +}; + +// Like `string.split(/[ \t\r\n]+/)` except newlines and tabs are: +// - ignored when input as a backslash sequence like: `echo foo\n bar` +// - not ignored when input directly +// The only way to distinguish those in JavaScript is to use a tagged template and compare: +// - the first array argument, which does not escape backslash sequences +// - its `raw` property, which escapes them +const splitByWhitespaces = (template, rawTemplate) => { + if (rawTemplate.length === 0) { + return {nextTokens: [], leadingWhitespaces: false, trailingWhitespaces: false}; + } + + const nextTokens = []; + let templateStart = 0; + const leadingWhitespaces = DELIMITERS.has(rawTemplate[0]); + + for ( + let templateIndex = 0, rawIndex = 0; + templateIndex < template.length; + templateIndex += 1, rawIndex += 1 + ) { + const rawCharacter = rawTemplate[rawIndex]; + if (DELIMITERS.has(rawCharacter)) { + if (templateStart !== templateIndex) { + nextTokens.push(template.slice(templateStart, templateIndex)); + } + + templateStart = templateIndex + 1; + } else if (rawCharacter === '\\') { + const nextRawCharacter = rawTemplate[rawIndex + 1]; + if (nextRawCharacter === '\n') { + // Handles escaped newlines in templates + templateIndex -= 1; + rawIndex += 1; + } else if (nextRawCharacter === 'u' && rawTemplate[rawIndex + 2] === '{') { + rawIndex = rawTemplate.indexOf('}', rawIndex + 3); + } else { + rawIndex += ESCAPE_LENGTH[nextRawCharacter] ?? 1; + } + } + } + + const trailingWhitespaces = templateStart === template.length; + if (!trailingWhitespaces) { + nextTokens.push(template.slice(templateStart)); + } + + return {nextTokens, leadingWhitespaces, trailingWhitespaces}; +}; + +const DELIMITERS = new Set([' ', '\t', '\r', '\n']); + +// Number of characters in backslash escape sequences: \0 \xXX or \uXXXX +// \cX is allowed in RegExps but not in strings +// Octal sequences are not allowed in strict mode +const ESCAPE_LENGTH = {x: 3, u: 5}; + +const concatTokens = (tokens, nextTokens, isSeparated) => isSeparated + || tokens.length === 0 + || nextTokens.length === 0 + ? [...tokens, ...nextTokens] + : [ + ...tokens.slice(0, -1), + `${tokens.at(-1)}${nextTokens[0]}`, + ...nextTokens.slice(1), + ]; + +// Handle `${expression}` inside the template string syntax +const parseExpression = expression => { + const typeOfExpression = typeof expression; + + if (typeOfExpression === 'string') { + return expression; + } + + if (typeOfExpression === 'number') { + return String(expression); + } + + if (isPlainObject(expression) && ('stdout' in expression || 'isMaxBuffer' in expression)) { + return getSubprocessResult(expression); + } + + if (expression instanceof ChildProcess || Object.prototype.toString.call(expression) === '[object Promise]') { + // eslint-disable-next-line no-template-curly-in-string + throw new TypeError('Unexpected subprocess in template expression. Please use ${await subprocess} instead of ${subprocess}.'); + } + + throw new TypeError(`Unexpected "${typeOfExpression}" in template expression`); +}; + +const getSubprocessResult = ({stdout}) => { + if (typeof stdout === 'string') { + return stdout; + } + + if (isUint8Array(stdout)) { + return uint8ArrayToString(stdout); + } + + if (stdout === undefined) { + throw new TypeError('Missing result.stdout in template expression. This is probably due to the previous subprocess\' "stdout" option.'); + } + + throw new TypeError(`Unexpected "${typeof stdout}" stdout in template expression`); +}; + +const isStandardStream = stream => STANDARD_STREAMS.includes(stream); +const STANDARD_STREAMS = [process$2.stdin, process$2.stdout, process$2.stderr]; +const STANDARD_STREAMS_ALIASES = ['stdin', 'stdout', 'stderr']; +const getStreamName = fdNumber => STANDARD_STREAMS_ALIASES[fdNumber] ?? `stdio[${fdNumber}]`; + +// Some options can have different values for `stdout`/`stderr`/`fd3`. +// This normalizes those to array of values. +// For example, `{verbose: {stdout: 'none', stderr: 'full'}}` becomes `{verbose: ['none', 'none', 'full']}` +const normalizeFdSpecificOptions = options => { + const optionsCopy = {...options}; + + for (const optionName of FD_SPECIFIC_OPTIONS) { + optionsCopy[optionName] = normalizeFdSpecificOption(options, optionName); + } + + return optionsCopy; +}; + +const normalizeFdSpecificOption = (options, optionName) => { + const optionBaseArray = Array.from({length: getStdioLength(options) + 1}); + const optionArray = normalizeFdSpecificValue(options[optionName], optionBaseArray, optionName); + return addDefaultValue$1(optionArray, optionName); +}; + +const getStdioLength = ({stdio}) => Array.isArray(stdio) + ? Math.max(stdio.length, STANDARD_STREAMS_ALIASES.length) + : STANDARD_STREAMS_ALIASES.length; + +const normalizeFdSpecificValue = (optionValue, optionArray, optionName) => isPlainObject(optionValue) + ? normalizeOptionObject(optionValue, optionArray, optionName) + : optionArray.fill(optionValue); + +const normalizeOptionObject = (optionValue, optionArray, optionName) => { + for (const fdName of Object.keys(optionValue).sort(compareFdName)) { + for (const fdNumber of parseFdName(fdName, optionName, optionArray)) { + optionArray[fdNumber] = optionValue[fdName]; + } + } + + return optionArray; +}; + +// Ensure priority order when setting both `stdout`/`stderr`, `fd1`/`fd2`, and `all` +const compareFdName = (fdNameA, fdNameB) => getFdNameOrder(fdNameA) < getFdNameOrder(fdNameB) ? 1 : -1; + +const getFdNameOrder = fdName => { + if (fdName === 'stdout' || fdName === 'stderr') { + return 0; + } + + return fdName === 'all' ? 2 : 1; +}; + +const parseFdName = (fdName, optionName, optionArray) => { + if (fdName === 'ipc') { + return [optionArray.length - 1]; + } + + const fdNumber = parseFd(fdName); + if (fdNumber === undefined || fdNumber === 0) { + throw new TypeError(`"${optionName}.${fdName}" is invalid. +It must be "${optionName}.stdout", "${optionName}.stderr", "${optionName}.all", "${optionName}.ipc", or "${optionName}.fd3", "${optionName}.fd4" (and so on).`); + } + + if (fdNumber >= optionArray.length) { + throw new TypeError(`"${optionName}.${fdName}" is invalid: that file descriptor does not exist. +Please set the "stdio" option to ensure that file descriptor exists.`); + } + + return fdNumber === 'all' ? [1, 2] : [fdNumber]; +}; + +// Use the same syntax for fd-specific options and the `from`/`to` options +const parseFd = fdName => { + if (fdName === 'all') { + return fdName; + } + + if (STANDARD_STREAMS_ALIASES.includes(fdName)) { + return STANDARD_STREAMS_ALIASES.indexOf(fdName); + } + + const regexpResult = FD_REGEXP.exec(fdName); + if (regexpResult !== null) { + return Number(regexpResult[1]); + } +}; + +const FD_REGEXP = /^fd(\d+)$/; + +const addDefaultValue$1 = (optionArray, optionName) => optionArray.map(optionValue => optionValue === undefined + ? DEFAULT_OPTIONS[optionName] + : optionValue); + +// Default value for the `verbose` option +const verboseDefault = debuglog('execa').enabled ? 'full' : 'none'; + +const DEFAULT_OPTIONS = { + lines: false, + buffer: true, + maxBuffer: 1000 * 1000 * 100, + verbose: verboseDefault, + stripFinalNewline: true, +}; + +// List of options which can have different values for `stdout`/`stderr` +const FD_SPECIFIC_OPTIONS = ['lines', 'buffer', 'maxBuffer', 'verbose', 'stripFinalNewline']; + +// Retrieve fd-specific option +const getFdSpecificValue = (optionArray, fdNumber) => fdNumber === 'ipc' + ? optionArray.at(-1) + : optionArray[fdNumber]; + +// The `verbose` option can have different values for `stdout`/`stderr` +const isVerbose = ({verbose}, fdNumber) => getFdVerbose(verbose, fdNumber) !== 'none'; + +// Whether IPC and output and logged +const isFullVerbose = ({verbose}, fdNumber) => !['none', 'short'].includes(getFdVerbose(verbose, fdNumber)); + +// The `verbose` option can be a function to customize logging +const getVerboseFunction = ({verbose}, fdNumber) => { + const fdVerbose = getFdVerbose(verbose, fdNumber); + return isVerboseFunction(fdVerbose) ? fdVerbose : undefined; +}; + +// When using `verbose: {stdout, stderr, fd3, ipc}`: +// - `verbose.stdout|stderr|fd3` is used for 'output' +// - `verbose.ipc` is only used for 'ipc' +// - highest `verbose.*` value is used for 'command', 'error' and 'duration' +const getFdVerbose = (verbose, fdNumber) => fdNumber === undefined + ? getFdGenericVerbose(verbose) + : getFdSpecificValue(verbose, fdNumber); + +// When using `verbose: {stdout, stderr, fd3, ipc}` and logging is not specific to a file descriptor. +// We then use the highest `verbose.*` value, using the following order: +// - function > 'full' > 'short' > 'none' +// - if several functions are defined: stdout > stderr > fd3 > ipc +const getFdGenericVerbose = verbose => verbose.find(fdVerbose => isVerboseFunction(fdVerbose)) + ?? VERBOSE_VALUES.findLast(fdVerbose => verbose.includes(fdVerbose)); + +// Whether the `verbose` option is customized using a function +const isVerboseFunction = fdVerbose => typeof fdVerbose === 'function'; + +const VERBOSE_VALUES = ['none', 'short', 'full']; + +// Compute `result.command` and `result.escapedCommand` +const joinCommand = (filePath, rawArguments) => { + const fileAndArguments = [filePath, ...rawArguments]; + const command = fileAndArguments.join(' '); + const escapedCommand = fileAndArguments + .map(fileAndArgument => quoteString(escapeControlCharacters(fileAndArgument))) + .join(' '); + return {command, escapedCommand}; +}; + +// Remove ANSI sequences and escape control characters and newlines +const escapeLines = lines => stripVTControlCharacters(lines) + .split('\n') + .map(line => escapeControlCharacters(line)) + .join('\n'); + +const escapeControlCharacters = line => line.replaceAll(SPECIAL_CHAR_REGEXP, character => escapeControlCharacter(character)); + +const escapeControlCharacter = character => { + const commonEscape = COMMON_ESCAPES[character]; + if (commonEscape !== undefined) { + return commonEscape; + } + + const codepoint = character.codePointAt(0); + const codepointHex = codepoint.toString(16); + return codepoint <= ASTRAL_START + ? `\\u${codepointHex.padStart(4, '0')}` + : `\\U${codepointHex}`; +}; + +// Characters that would create issues when printed are escaped using the \u or \U notation. +// Those include control characters and newlines. +// The \u and \U notation is Bash specific, but there is no way to do this in a shell-agnostic way. +// Some shells do not even have a way to print those characters in an escaped fashion. +// Therefore, we prioritize printing those safely, instead of allowing those to be copy-pasted. +// List of Unicode character categories: https://www.fileformat.info/info/unicode/category/index.htm +const getSpecialCharRegExp = () => { + try { + // This throws when using Node.js without ICU support. + // When using a RegExp literal, this would throw at parsing-time, instead of runtime. + // eslint-disable-next-line prefer-regex-literals + return new RegExp('\\p{Separator}|\\p{Other}', 'gu'); + } catch { + // Similar to the above RegExp, but works even when Node.js has been built without ICU support. + // Unlike the above RegExp, it only covers whitespaces and C0/C1 control characters. + // It does not cover some edge cases, such as Unicode reserved characters. + // See https://github.com/sindresorhus/execa/issues/1143 + // eslint-disable-next-line no-control-regex + return /[\s\u0000-\u001F\u007F-\u009F\u00AD]/g; + } +}; + +const SPECIAL_CHAR_REGEXP = getSpecialCharRegExp(); + +// Accepted by $'...' in Bash. +// Exclude \a \e \v which are accepted in Bash but not in JavaScript (except \v) and JSON. +const COMMON_ESCAPES = { + ' ': ' ', + '\b': '\\b', + '\f': '\\f', + '\n': '\\n', + '\r': '\\r', + '\t': '\\t', +}; + +// Up until that codepoint, \u notation can be used instead of \U +const ASTRAL_START = 65_535; + +// Some characters are shell-specific, i.e. need to be escaped when the command is copy-pasted then run. +// Escaping is shell-specific. We cannot know which shell is used: `process.platform` detection is not enough. +// For example, Windows users could be using `cmd.exe`, Powershell or Bash for Windows which all use different escaping. +// We use '...' on Unix, which is POSIX shell compliant and escape all characters but ' so this is fairly safe. +// On Windows, we assume cmd.exe is used and escape with "...", which also works with Powershell. +const quoteString = escapedArgument => { + if (NO_ESCAPE_REGEXP.test(escapedArgument)) { + return escapedArgument; + } + + return platform === 'win32' + ? `"${escapedArgument.replaceAll('"', '""')}"` + : `'${escapedArgument.replaceAll('\'', '\'\\\'\'')}'`; +}; + +const NO_ESCAPE_REGEXP = /^[\w./-]+$/; + +function isUnicodeSupported() { + const {env} = process$2; + const {TERM, TERM_PROGRAM} = env; + + if (process$2.platform !== 'win32') { + return TERM !== 'linux'; // Linux console (kernel) + } + + return Boolean(env.WT_SESSION) // Windows Terminal + || Boolean(env.TERMINUS_SUBLIME) // Terminus (<0.2.27) + || env.ConEmuTask === '{cmd::Cmder}' // ConEmu and cmder + || TERM_PROGRAM === 'Terminus-Sublime' + || TERM_PROGRAM === 'vscode' + || TERM === 'xterm-256color' + || TERM === 'alacritty' + || TERM === 'rxvt-unicode' + || TERM === 'rxvt-unicode-256color' + || env.TERMINAL_EMULATOR === 'JetBrains-JediTerm'; +} + +const common = { + circleQuestionMark: '(?)', + questionMarkPrefix: '(?)', + square: '█', + squareDarkShade: '▓', + squareMediumShade: '▒', + squareLightShade: '░', + squareTop: '▀', + squareBottom: '▄', + squareLeft: '▌', + squareRight: '▐', + squareCenter: '■', + bullet: '●', + dot: '․', + ellipsis: '…', + pointerSmall: '›', + triangleUp: '▲', + triangleUpSmall: '▴', + triangleDown: '▼', + triangleDownSmall: '▾', + triangleLeftSmall: '◂', + triangleRightSmall: '▸', + home: '⌂', + heart: '♥', + musicNote: '♪', + musicNoteBeamed: '♫', + arrowUp: '↑', + arrowDown: '↓', + arrowLeft: '←', + arrowRight: '→', + arrowLeftRight: '↔', + arrowUpDown: '↕', + almostEqual: '≈', + notEqual: '≠', + lessOrEqual: '≤', + greaterOrEqual: '≥', + identical: '≡', + infinity: '∞', + subscriptZero: '₀', + subscriptOne: '₁', + subscriptTwo: '₂', + subscriptThree: '₃', + subscriptFour: '₄', + subscriptFive: '₅', + subscriptSix: '₆', + subscriptSeven: '₇', + subscriptEight: '₈', + subscriptNine: '₉', + oneHalf: '½', + oneThird: '⅓', + oneQuarter: '¼', + oneFifth: '⅕', + oneSixth: '⅙', + oneEighth: '⅛', + twoThirds: '⅔', + twoFifths: '⅖', + threeQuarters: '¾', + threeFifths: '⅗', + threeEighths: '⅜', + fourFifths: '⅘', + fiveSixths: '⅚', + fiveEighths: '⅝', + sevenEighths: '⅞', + line: '─', + lineBold: '━', + lineDouble: '═', + lineDashed0: '┄', + lineDashed1: '┅', + lineDashed2: '┈', + lineDashed3: '┉', + lineDashed4: '╌', + lineDashed5: '╍', + lineDashed6: '╴', + lineDashed7: '╶', + lineDashed8: '╸', + lineDashed9: '╺', + lineDashed10: '╼', + lineDashed11: '╾', + lineDashed12: '−', + lineDashed13: '–', + lineDashed14: '‐', + lineDashed15: '⁃', + lineVertical: '│', + lineVerticalBold: '┃', + lineVerticalDouble: '║', + lineVerticalDashed0: '┆', + lineVerticalDashed1: '┇', + lineVerticalDashed2: '┊', + lineVerticalDashed3: '┋', + lineVerticalDashed4: '╎', + lineVerticalDashed5: '╏', + lineVerticalDashed6: '╵', + lineVerticalDashed7: '╷', + lineVerticalDashed8: '╹', + lineVerticalDashed9: '╻', + lineVerticalDashed10: '╽', + lineVerticalDashed11: '╿', + lineDownLeft: '┐', + lineDownLeftArc: '╮', + lineDownBoldLeftBold: '┓', + lineDownBoldLeft: '┒', + lineDownLeftBold: '┑', + lineDownDoubleLeftDouble: '╗', + lineDownDoubleLeft: '╖', + lineDownLeftDouble: '╕', + lineDownRight: '┌', + lineDownRightArc: '╭', + lineDownBoldRightBold: '┏', + lineDownBoldRight: '┎', + lineDownRightBold: '┍', + lineDownDoubleRightDouble: '╔', + lineDownDoubleRight: '╓', + lineDownRightDouble: '╒', + lineUpLeft: '┘', + lineUpLeftArc: '╯', + lineUpBoldLeftBold: '┛', + lineUpBoldLeft: '┚', + lineUpLeftBold: '┙', + lineUpDoubleLeftDouble: '╝', + lineUpDoubleLeft: '╜', + lineUpLeftDouble: '╛', + lineUpRight: '└', + lineUpRightArc: '╰', + lineUpBoldRightBold: '┗', + lineUpBoldRight: '┖', + lineUpRightBold: '┕', + lineUpDoubleRightDouble: '╚', + lineUpDoubleRight: '╙', + lineUpRightDouble: '╘', + lineUpDownLeft: '┤', + lineUpBoldDownBoldLeftBold: '┫', + lineUpBoldDownBoldLeft: '┨', + lineUpDownLeftBold: '┥', + lineUpBoldDownLeftBold: '┩', + lineUpDownBoldLeftBold: '┪', + lineUpDownBoldLeft: '┧', + lineUpBoldDownLeft: '┦', + lineUpDoubleDownDoubleLeftDouble: '╣', + lineUpDoubleDownDoubleLeft: '╢', + lineUpDownLeftDouble: '╡', + lineUpDownRight: '├', + lineUpBoldDownBoldRightBold: '┣', + lineUpBoldDownBoldRight: '┠', + lineUpDownRightBold: '┝', + lineUpBoldDownRightBold: '┡', + lineUpDownBoldRightBold: '┢', + lineUpDownBoldRight: '┟', + lineUpBoldDownRight: '┞', + lineUpDoubleDownDoubleRightDouble: '╠', + lineUpDoubleDownDoubleRight: '╟', + lineUpDownRightDouble: '╞', + lineDownLeftRight: '┬', + lineDownBoldLeftBoldRightBold: '┳', + lineDownLeftBoldRightBold: '┯', + lineDownBoldLeftRight: '┰', + lineDownBoldLeftBoldRight: '┱', + lineDownBoldLeftRightBold: '┲', + lineDownLeftRightBold: '┮', + lineDownLeftBoldRight: '┭', + lineDownDoubleLeftDoubleRightDouble: '╦', + lineDownDoubleLeftRight: '╥', + lineDownLeftDoubleRightDouble: '╤', + lineUpLeftRight: '┴', + lineUpBoldLeftBoldRightBold: '┻', + lineUpLeftBoldRightBold: '┷', + lineUpBoldLeftRight: '┸', + lineUpBoldLeftBoldRight: '┹', + lineUpBoldLeftRightBold: '┺', + lineUpLeftRightBold: '┶', + lineUpLeftBoldRight: '┵', + lineUpDoubleLeftDoubleRightDouble: '╩', + lineUpDoubleLeftRight: '╨', + lineUpLeftDoubleRightDouble: '╧', + lineUpDownLeftRight: '┼', + lineUpBoldDownBoldLeftBoldRightBold: '╋', + lineUpDownBoldLeftBoldRightBold: '╈', + lineUpBoldDownLeftBoldRightBold: '╇', + lineUpBoldDownBoldLeftRightBold: '╊', + lineUpBoldDownBoldLeftBoldRight: '╉', + lineUpBoldDownLeftRight: '╀', + lineUpDownBoldLeftRight: '╁', + lineUpDownLeftBoldRight: '┽', + lineUpDownLeftRightBold: '┾', + lineUpBoldDownBoldLeftRight: '╂', + lineUpDownLeftBoldRightBold: '┿', + lineUpBoldDownLeftBoldRight: '╃', + lineUpBoldDownLeftRightBold: '╄', + lineUpDownBoldLeftBoldRight: '╅', + lineUpDownBoldLeftRightBold: '╆', + lineUpDoubleDownDoubleLeftDoubleRightDouble: '╬', + lineUpDoubleDownDoubleLeftRight: '╫', + lineUpDownLeftDoubleRightDouble: '╪', + lineCross: '╳', + lineBackslash: '╲', + lineSlash: '╱', +}; + +const specialMainSymbols = { + tick: '✔', + info: 'ℹ', + warning: '⚠', + cross: '✘', + squareSmall: '◻', + squareSmallFilled: '◼', + circle: '◯', + circleFilled: '◉', + circleDotted: '◌', + circleDouble: '◎', + circleCircle: 'ⓞ', + circleCross: 'ⓧ', + circlePipe: 'Ⓘ', + radioOn: '◉', + radioOff: '◯', + checkboxOn: '☒', + checkboxOff: '☐', + checkboxCircleOn: 'ⓧ', + checkboxCircleOff: 'Ⓘ', + pointer: '❯', + triangleUpOutline: '△', + triangleLeft: '◀', + triangleRight: '▶', + lozenge: '◆', + lozengeOutline: '◇', + hamburger: '☰', + smiley: '㋡', + mustache: '෴', + star: '★', + play: '▶', + nodejs: '⬢', + oneSeventh: '⅐', + oneNinth: '⅑', + oneTenth: '⅒', +}; + +const specialFallbackSymbols = { + tick: '√', + info: 'i', + warning: '‼', + cross: '×', + squareSmall: '□', + squareSmallFilled: '■', + circle: '( )', + circleFilled: '(*)', + circleDotted: '( )', + circleDouble: '( )', + circleCircle: '(○)', + circleCross: '(×)', + circlePipe: '(│)', + radioOn: '(*)', + radioOff: '( )', + checkboxOn: '[×]', + checkboxOff: '[ ]', + checkboxCircleOn: '(×)', + checkboxCircleOff: '( )', + pointer: '>', + triangleUpOutline: '∆', + triangleLeft: '◄', + triangleRight: '►', + lozenge: '♦', + lozengeOutline: '◊', + hamburger: '≡', + smiley: '☺', + mustache: '┌─┐', + star: '✶', + play: '►', + nodejs: '♦', + oneSeventh: '1/7', + oneNinth: '1/9', + oneTenth: '1/10', +}; + +const mainSymbols = {...common, ...specialMainSymbols}; +const fallbackSymbols = {...common, ...specialFallbackSymbols}; + +const shouldUseMain = isUnicodeSupported(); +const figures = shouldUseMain ? mainSymbols : fallbackSymbols; + +// Default when `verbose` is not a function +const defaultVerboseFunction = ({ + type, + message, + timestamp, + piped, + commandId, + result: {failed = false} = {}, + options: {reject = true}, +}) => { + const timestampString = serializeTimestamp(timestamp); + const icon = ICONS[type]({failed, reject, piped}); + const color = COLORS[type]({reject}); + return `${gray(`[${timestampString}]`)} ${gray(`[${commandId}]`)} ${color(icon)} ${color(message)}`; +}; + +// Prepending the timestamp allows debugging the slow paths of a subprocess +const serializeTimestamp = timestamp => `${padField(timestamp.getHours(), 2)}:${padField(timestamp.getMinutes(), 2)}:${padField(timestamp.getSeconds(), 2)}.${padField(timestamp.getMilliseconds(), 3)}`; + +const padField = (field, padding) => String(field).padStart(padding, '0'); + +const getFinalIcon = ({failed, reject}) => { + if (!failed) { + return figures.tick; + } + + return reject ? figures.cross : figures.warning; +}; + +const ICONS = { + command: ({piped}) => piped ? '|' : '$', + output: () => ' ', + ipc: () => '*', + error: getFinalIcon, + duration: getFinalIcon, +}; + +const identity$1 = string => string; + +const COLORS = { + command: () => bold, + output: () => identity$1, + ipc: () => identity$1, + error: ({reject}) => reject ? redBright : yellowBright, + duration: () => gray, +}; + +// Apply the `verbose` function on each line +const applyVerboseOnLines = (printedLines, verboseInfo, fdNumber) => { + const verboseFunction = getVerboseFunction(verboseInfo, fdNumber); + return printedLines + .map(({verboseLine, verboseObject}) => applyVerboseFunction(verboseLine, verboseObject, verboseFunction)) + .filter(printedLine => printedLine !== undefined) + .map(printedLine => appendNewline(printedLine)) + .join(''); +}; + +const applyVerboseFunction = (verboseLine, verboseObject, verboseFunction) => { + if (verboseFunction === undefined) { + return verboseLine; + } + + const printedLine = verboseFunction(verboseLine, verboseObject); + if (typeof printedLine === 'string') { + return printedLine; + } +}; + +const appendNewline = printedLine => printedLine.endsWith('\n') + ? printedLine + : `${printedLine}\n`; + +// This prints on stderr. +// If the subprocess prints on stdout and is using `stdout: 'inherit'`, +// there is a chance both writes will compete (introducing a race condition). +// This means their respective order is not deterministic. +// In particular, this means the verbose command lines might be after the start of the subprocess output. +// Using synchronous I/O does not solve this problem. +// However, this only seems to happen when the stdout/stderr target +// (e.g. a terminal) is being written to by many subprocesses at once, which is unlikely in real scenarios. +const verboseLog = ({type, verboseMessage, fdNumber, verboseInfo, result}) => { + const verboseObject = getVerboseObject({type, result, verboseInfo}); + const printedLines = getPrintedLines(verboseMessage, verboseObject); + const finalLines = applyVerboseOnLines(printedLines, verboseInfo, fdNumber); + if (finalLines !== '') { + console.warn(finalLines.slice(0, -1)); + } +}; + +const getVerboseObject = ({ + type, + result, + verboseInfo: {escapedCommand, commandId, rawOptions: {piped = false, ...options}}, +}) => ({ + type, + escapedCommand, + commandId: `${commandId}`, + timestamp: new Date(), + piped, + result, + options, +}); + +const getPrintedLines = (verboseMessage, verboseObject) => verboseMessage + .split('\n') + .map(message => getPrintedLine({...verboseObject, message})); + +const getPrintedLine = verboseObject => { + const verboseLine = defaultVerboseFunction(verboseObject); + return {verboseLine, verboseObject}; +}; + +// Serialize any type to a line string, for logging +const serializeVerboseMessage = message => { + const messageString = typeof message === 'string' ? message : inspect(message); + const escapedMessage = escapeLines(messageString); + return escapedMessage.replaceAll('\t', ' '.repeat(TAB_SIZE)); +}; + +// Same as `util.inspect()` +const TAB_SIZE = 2; + +// When `verbose` is `short|full|custom`, print each command +const logCommand = (escapedCommand, verboseInfo) => { + if (!isVerbose(verboseInfo)) { + return; + } + + verboseLog({ + type: 'command', + verboseMessage: escapedCommand, + verboseInfo, + }); +}; + +// Information computed before spawning, used by the `verbose` option +const getVerboseInfo = (verbose, escapedCommand, rawOptions) => { + validateVerbose(verbose); + const commandId = getCommandId(verbose); + return { + verbose, + escapedCommand, + commandId, + rawOptions, + }; +}; + +const getCommandId = verbose => isVerbose({verbose}) ? COMMAND_ID++ : undefined; + +// Prepending the `pid` is useful when multiple commands print their output at the same time. +// However, we cannot use the real PID since this is not available with `child_process.spawnSync()`. +// Also, we cannot use the real PID if we want to print it before `child_process.spawn()` is run. +// As a pro, it is shorter than a normal PID and never re-uses the same id. +// As a con, it cannot be used to send signals. +let COMMAND_ID = 0n; + +const validateVerbose = verbose => { + for (const fdVerbose of verbose) { + if (fdVerbose === false) { + throw new TypeError('The "verbose: false" option was renamed to "verbose: \'none\'".'); + } + + if (fdVerbose === true) { + throw new TypeError('The "verbose: true" option was renamed to "verbose: \'short\'".'); + } + + if (!VERBOSE_VALUES.includes(fdVerbose) && !isVerboseFunction(fdVerbose)) { + const allowedValues = VERBOSE_VALUES.map(allowedValue => `'${allowedValue}'`).join(', '); + throw new TypeError(`The "verbose" option must not be ${fdVerbose}. Allowed values are: ${allowedValues} or a function.`); + } + } +}; + +// Start counting time before spawning the subprocess +const getStartTime = () => hrtime.bigint(); + +// Compute duration after the subprocess ended. +// Printed by the `verbose` option. +const getDurationMs = startTime => Number(hrtime.bigint() - startTime) / 1e6; + +// Compute `result.command`, `result.escapedCommand` and `verbose`-related information +const handleCommand = (filePath, rawArguments, rawOptions) => { + const startTime = getStartTime(); + const {command, escapedCommand} = joinCommand(filePath, rawArguments); + const verbose = normalizeFdSpecificOption(rawOptions, 'verbose'); + const verboseInfo = getVerboseInfo(verbose, escapedCommand, {...rawOptions}); + logCommand(escapedCommand, verboseInfo); + return { + command, + escapedCommand, + startTime, + verboseInfo, + }; +}; + +var crossSpawn$1 = {exports: {}}; + +var windows$1; +var hasRequiredWindows; + +function requireWindows () { + if (hasRequiredWindows) return windows$1; + hasRequiredWindows = 1; + windows$1 = isexe; + isexe.sync = sync; + + var fs = require$$0; + + function checkPathExt (path, options) { + var pathext = options.pathExt !== undefined ? + options.pathExt : process.env.PATHEXT; + + if (!pathext) { + return true + } + + pathext = pathext.split(';'); + if (pathext.indexOf('') !== -1) { + return true + } + for (var i = 0; i < pathext.length; i++) { + var p = pathext[i].toLowerCase(); + if (p && path.substr(-p.length).toLowerCase() === p) { + return true + } + } + return false + } + + function checkStat (stat, path, options) { + if (!stat.isSymbolicLink() && !stat.isFile()) { + return false + } + return checkPathExt(path, options) + } + + function isexe (path, options, cb) { + fs.stat(path, function (er, stat) { + cb(er, er ? false : checkStat(stat, path, options)); + }); + } + + function sync (path, options) { + return checkStat(fs.statSync(path), path, options) + } + return windows$1; +} + +var mode; +var hasRequiredMode; + +function requireMode () { + if (hasRequiredMode) return mode; + hasRequiredMode = 1; + mode = isexe; + isexe.sync = sync; + + var fs = require$$0; + + function isexe (path, options, cb) { + fs.stat(path, function (er, stat) { + cb(er, er ? false : checkStat(stat, options)); + }); + } + + function sync (path, options) { + return checkStat(fs.statSync(path), options) + } + + function checkStat (stat, options) { + return stat.isFile() && checkMode(stat, options) + } + + function checkMode (stat, options) { + var mod = stat.mode; + var uid = stat.uid; + var gid = stat.gid; + + var myUid = options.uid !== undefined ? + options.uid : process.getuid && process.getuid(); + var myGid = options.gid !== undefined ? + options.gid : process.getgid && process.getgid(); + + var u = parseInt('100', 8); + var g = parseInt('010', 8); + var o = parseInt('001', 8); + var ug = u | g; + + var ret = (mod & o) || + (mod & g) && gid === myGid || + (mod & u) && uid === myUid || + (mod & ug) && myUid === 0; + + return ret + } + return mode; +} + +var isexe_1; +var hasRequiredIsexe; + +function requireIsexe () { + if (hasRequiredIsexe) return isexe_1; + hasRequiredIsexe = 1; + var core; + if (process.platform === 'win32' || commonjsGlobal.TESTING_WINDOWS) { + core = requireWindows(); + } else { + core = requireMode(); + } + + isexe_1 = isexe; + isexe.sync = sync; + + function isexe (path, options, cb) { + if (typeof options === 'function') { + cb = options; + options = {}; + } + + if (!cb) { + if (typeof Promise !== 'function') { + throw new TypeError('callback not provided') + } + + return new Promise(function (resolve, reject) { + isexe(path, options || {}, function (er, is) { + if (er) { + reject(er); + } else { + resolve(is); + } + }); + }) + } + + core(path, options || {}, function (er, is) { + // ignore EACCES because that just means we aren't allowed to run it + if (er) { + if (er.code === 'EACCES' || options && options.ignoreErrors) { + er = null; + is = false; + } + } + cb(er, is); + }); + } + + function sync (path, options) { + // my kingdom for a filtered catch + try { + return core.sync(path, options || {}) + } catch (er) { + if (options && options.ignoreErrors || er.code === 'EACCES') { + return false + } else { + throw er + } + } + } + return isexe_1; +} + +var which_1; +var hasRequiredWhich; + +function requireWhich () { + if (hasRequiredWhich) return which_1; + hasRequiredWhich = 1; + const isWindows = process.platform === 'win32' || + process.env.OSTYPE === 'cygwin' || + process.env.OSTYPE === 'msys'; + + const path = require$$0$1; + const COLON = isWindows ? ';' : ':'; + const isexe = requireIsexe(); + + const getNotFoundError = (cmd) => + Object.assign(new Error(`not found: ${cmd}`), { code: 'ENOENT' }); + + const getPathInfo = (cmd, opt) => { + const colon = opt.colon || COLON; + + // If it has a slash, then we don't bother searching the pathenv. + // just check the file itself, and that's it. + const pathEnv = cmd.match(/\//) || isWindows && cmd.match(/\\/) ? [''] + : ( + [ + // windows always checks the cwd first + ...(isWindows ? [process.cwd()] : []), + ...(opt.path || process.env.PATH || + /* istanbul ignore next: very unusual */ '').split(colon), + ] + ); + const pathExtExe = isWindows + ? opt.pathExt || process.env.PATHEXT || '.EXE;.CMD;.BAT;.COM' + : ''; + const pathExt = isWindows ? pathExtExe.split(colon) : ['']; + + if (isWindows) { + if (cmd.indexOf('.') !== -1 && pathExt[0] !== '') + pathExt.unshift(''); + } + + return { + pathEnv, + pathExt, + pathExtExe, + } + }; + + const which = (cmd, opt, cb) => { + if (typeof opt === 'function') { + cb = opt; + opt = {}; + } + if (!opt) + opt = {}; + + const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt); + const found = []; + + const step = i => new Promise((resolve, reject) => { + if (i === pathEnv.length) + return opt.all && found.length ? resolve(found) + : reject(getNotFoundError(cmd)) + + const ppRaw = pathEnv[i]; + const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw; + + const pCmd = path.join(pathPart, cmd); + const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd + : pCmd; + + resolve(subStep(p, i, 0)); + }); + + const subStep = (p, i, ii) => new Promise((resolve, reject) => { + if (ii === pathExt.length) + return resolve(step(i + 1)) + const ext = pathExt[ii]; + isexe(p + ext, { pathExt: pathExtExe }, (er, is) => { + if (!er && is) { + if (opt.all) + found.push(p + ext); + else + return resolve(p + ext) + } + return resolve(subStep(p, i, ii + 1)) + }); + }); + + return cb ? step(0).then(res => cb(null, res), cb) : step(0) + }; + + const whichSync = (cmd, opt) => { + opt = opt || {}; + + const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt); + const found = []; + + for (let i = 0; i < pathEnv.length; i ++) { + const ppRaw = pathEnv[i]; + const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw; + + const pCmd = path.join(pathPart, cmd); + const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd + : pCmd; + + for (let j = 0; j < pathExt.length; j ++) { + const cur = p + pathExt[j]; + try { + const is = isexe.sync(cur, { pathExt: pathExtExe }); + if (is) { + if (opt.all) + found.push(cur); + else + return cur + } + } catch (ex) {} + } + } + + if (opt.all && found.length) + return found + + if (opt.nothrow) + return null + + throw getNotFoundError(cmd) + }; + + which_1 = which; + which.sync = whichSync; + return which_1; +} + +var pathKey$1 = {exports: {}}; + +var hasRequiredPathKey; + +function requirePathKey () { + if (hasRequiredPathKey) return pathKey$1.exports; + hasRequiredPathKey = 1; + + const pathKey = (options = {}) => { + const environment = options.env || process.env; + const platform = options.platform || process.platform; + + if (platform !== 'win32') { + return 'PATH'; + } + + return Object.keys(environment).reverse().find(key => key.toUpperCase() === 'PATH') || 'Path'; + }; + + pathKey$1.exports = pathKey; + // TODO: Remove this for the next major release + pathKey$1.exports.default = pathKey; + return pathKey$1.exports; +} + +var resolveCommand_1; +var hasRequiredResolveCommand; + +function requireResolveCommand () { + if (hasRequiredResolveCommand) return resolveCommand_1; + hasRequiredResolveCommand = 1; + + const path = require$$0$1; + const which = requireWhich(); + const getPathKey = requirePathKey(); + + function resolveCommandAttempt(parsed, withoutPathExt) { + const env = parsed.options.env || process.env; + const cwd = process.cwd(); + const hasCustomCwd = parsed.options.cwd != null; + // Worker threads do not have process.chdir() + const shouldSwitchCwd = hasCustomCwd && process.chdir !== undefined && !process.chdir.disabled; + + // If a custom `cwd` was specified, we need to change the process cwd + // because `which` will do stat calls but does not support a custom cwd + if (shouldSwitchCwd) { + try { + process.chdir(parsed.options.cwd); + } catch (err) { + /* Empty */ + } + } + + let resolved; + + try { + resolved = which.sync(parsed.command, { + path: env[getPathKey({ env })], + pathExt: withoutPathExt ? path.delimiter : undefined, + }); + } catch (e) { + /* Empty */ + } finally { + if (shouldSwitchCwd) { + process.chdir(cwd); + } + } + + // If we successfully resolved, ensure that an absolute path is returned + // Note that when a custom `cwd` was used, we need to resolve to an absolute path based on it + if (resolved) { + resolved = path.resolve(hasCustomCwd ? parsed.options.cwd : '', resolved); + } + + return resolved; + } + + function resolveCommand(parsed) { + return resolveCommandAttempt(parsed) || resolveCommandAttempt(parsed, true); + } + + resolveCommand_1 = resolveCommand; + return resolveCommand_1; +} + +var _escape = {}; + +var hasRequired_escape; + +function require_escape () { + if (hasRequired_escape) return _escape; + hasRequired_escape = 1; + + // See http://www.robvanderwoude.com/escapechars.php + const metaCharsRegExp = /([()\][%!^"`<>&|;, *?])/g; + + function escapeCommand(arg) { + // Escape meta chars + arg = arg.replace(metaCharsRegExp, '^$1'); + + return arg; + } + + function escapeArgument(arg, doubleEscapeMetaChars) { + // Convert to string + arg = `${arg}`; + + // Algorithm below is based on https://qntm.org/cmd + // It's slightly altered to disable JS backtracking to avoid hanging on specially crafted input + // Please see https://github.com/moxystudio/node-cross-spawn/pull/160 for more information + + // Sequence of backslashes followed by a double quote: + // double up all the backslashes and escape the double quote + arg = arg.replace(/(?=(\\+?)?)\1"/g, '$1$1\\"'); + + // Sequence of backslashes followed by the end of the string + // (which will become a double quote later): + // double up all the backslashes + arg = arg.replace(/(?=(\\+?)?)\1$/, '$1$1'); + + // All other backslashes occur literally + + // Quote the whole thing: + arg = `"${arg}"`; + + // Escape meta chars + arg = arg.replace(metaCharsRegExp, '^$1'); + + // Double escape meta chars if necessary + if (doubleEscapeMetaChars) { + arg = arg.replace(metaCharsRegExp, '^$1'); + } + + return arg; + } + + _escape.command = escapeCommand; + _escape.argument = escapeArgument; + return _escape; +} + +var shebangRegex; +var hasRequiredShebangRegex; + +function requireShebangRegex () { + if (hasRequiredShebangRegex) return shebangRegex; + hasRequiredShebangRegex = 1; + shebangRegex = /^#!(.*)/; + return shebangRegex; +} + +var shebangCommand; +var hasRequiredShebangCommand; + +function requireShebangCommand () { + if (hasRequiredShebangCommand) return shebangCommand; + hasRequiredShebangCommand = 1; + const shebangRegex = requireShebangRegex(); + + shebangCommand = (string = '') => { + const match = string.match(shebangRegex); + + if (!match) { + return null; + } + + const [path, argument] = match[0].replace(/#! ?/, '').split(' '); + const binary = path.split('/').pop(); + + if (binary === 'env') { + return argument; + } + + return argument ? `${binary} ${argument}` : binary; + }; + return shebangCommand; +} + +var readShebang_1; +var hasRequiredReadShebang; + +function requireReadShebang () { + if (hasRequiredReadShebang) return readShebang_1; + hasRequiredReadShebang = 1; + + const fs = require$$0; + const shebangCommand = requireShebangCommand(); + + function readShebang(command) { + // Read the first 150 bytes from the file + const size = 150; + const buffer = Buffer.alloc(size); + + let fd; + + try { + fd = fs.openSync(command, 'r'); + fs.readSync(fd, buffer, 0, size, 0); + fs.closeSync(fd); + } catch (e) { /* Empty */ } + + // Attempt to extract shebang (null is returned if not a shebang) + return shebangCommand(buffer.toString()); + } + + readShebang_1 = readShebang; + return readShebang_1; +} + +var parse_1; +var hasRequiredParse$1; + +function requireParse$1 () { + if (hasRequiredParse$1) return parse_1; + hasRequiredParse$1 = 1; + + const path = require$$0$1; + const resolveCommand = requireResolveCommand(); + const escape = require_escape(); + const readShebang = requireReadShebang(); + + const isWin = process.platform === 'win32'; + const isExecutableRegExp = /\.(?:com|exe)$/i; + const isCmdShimRegExp = /node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i; + + function detectShebang(parsed) { + parsed.file = resolveCommand(parsed); + + const shebang = parsed.file && readShebang(parsed.file); + + if (shebang) { + parsed.args.unshift(parsed.file); + parsed.command = shebang; + + return resolveCommand(parsed); + } + + return parsed.file; + } + + function parseNonShell(parsed) { + if (!isWin) { + return parsed; + } + + // Detect & add support for shebangs + const commandFile = detectShebang(parsed); + + // We don't need a shell if the command filename is an executable + const needsShell = !isExecutableRegExp.test(commandFile); + + // If a shell is required, use cmd.exe and take care of escaping everything correctly + // Note that `forceShell` is an hidden option used only in tests + if (parsed.options.forceShell || needsShell) { + // Need to double escape meta chars if the command is a cmd-shim located in `node_modules/.bin/` + // The cmd-shim simply calls execute the package bin file with NodeJS, proxying any argument + // Because the escape of metachars with ^ gets interpreted when the cmd.exe is first called, + // we need to double escape them + const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile); + + // Normalize posix paths into OS compatible paths (e.g.: foo/bar -> foo\bar) + // This is necessary otherwise it will always fail with ENOENT in those cases + parsed.command = path.normalize(parsed.command); + + // Escape command & arguments + parsed.command = escape.command(parsed.command); + parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars)); + + const shellCommand = [parsed.command].concat(parsed.args).join(' '); + + parsed.args = ['/d', '/s', '/c', `"${shellCommand}"`]; + parsed.command = process.env.comspec || 'cmd.exe'; + parsed.options.windowsVerbatimArguments = true; // Tell node's spawn that the arguments are already escaped + } + + return parsed; + } + + function parse(command, args, options) { + // Normalize arguments, similar to nodejs + if (args && !Array.isArray(args)) { + options = args; + args = null; + } + + args = args ? args.slice(0) : []; // Clone array to avoid changing the original + options = Object.assign({}, options); // Clone object to avoid changing the original + + // Build our parsed object + const parsed = { + command, + args, + options, + file: undefined, + original: { + command, + args, + }, + }; + + // Delegate further parsing to shell or non-shell + return options.shell ? parsed : parseNonShell(parsed); + } + + parse_1 = parse; + return parse_1; +} + +var enoent; +var hasRequiredEnoent; + +function requireEnoent () { + if (hasRequiredEnoent) return enoent; + hasRequiredEnoent = 1; + + const isWin = process.platform === 'win32'; + + function notFoundError(original, syscall) { + return Object.assign(new Error(`${syscall} ${original.command} ENOENT`), { + code: 'ENOENT', + errno: 'ENOENT', + syscall: `${syscall} ${original.command}`, + path: original.command, + spawnargs: original.args, + }); + } + + function hookChildProcess(cp, parsed) { + if (!isWin) { + return; + } + + const originalEmit = cp.emit; + + cp.emit = function (name, arg1) { + // If emitting "exit" event and exit code is 1, we need to check if + // the command exists and emit an "error" instead + // See https://github.com/IndigoUnited/node-cross-spawn/issues/16 + if (name === 'exit') { + const err = verifyENOENT(arg1, parsed); + + if (err) { + return originalEmit.call(cp, 'error', err); + } + } + + return originalEmit.apply(cp, arguments); // eslint-disable-line prefer-rest-params + }; + } + + function verifyENOENT(status, parsed) { + if (isWin && status === 1 && !parsed.file) { + return notFoundError(parsed.original, 'spawn'); + } + + return null; + } + + function verifyENOENTSync(status, parsed) { + if (isWin && status === 1 && !parsed.file) { + return notFoundError(parsed.original, 'spawnSync'); + } + + return null; + } + + enoent = { + hookChildProcess, + verifyENOENT, + verifyENOENTSync, + notFoundError, + }; + return enoent; +} + +var hasRequiredCrossSpawn; + +function requireCrossSpawn () { + if (hasRequiredCrossSpawn) return crossSpawn$1.exports; + hasRequiredCrossSpawn = 1; + + const cp = require$$0$2; + const parse = requireParse$1(); + const enoent = requireEnoent(); + + function spawn(command, args, options) { + // Parse the arguments + const parsed = parse(command, args, options); + + // Spawn the child process + const spawned = cp.spawn(parsed.command, parsed.args, parsed.options); + + // Hook into child process "exit" event to emit an error if the command + // does not exists, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16 + enoent.hookChildProcess(spawned, parsed); + + return spawned; + } + + function spawnSync(command, args, options) { + // Parse the arguments + const parsed = parse(command, args, options); + + // Spawn the child process + const result = cp.spawnSync(parsed.command, parsed.args, parsed.options); + + // Analyze if the command does not exist, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16 + result.error = result.error || enoent.verifyENOENTSync(result.status, parsed); + + return result; + } + + crossSpawn$1.exports = spawn; + crossSpawn$1.exports.spawn = spawn; + crossSpawn$1.exports.sync = spawnSync; + + crossSpawn$1.exports._parse = parse; + crossSpawn$1.exports._enoent = enoent; + return crossSpawn$1.exports; +} + +var crossSpawnExports = requireCrossSpawn(); +const crossSpawn = /*@__PURE__*/getDefaultExportFromCjs(crossSpawnExports); + +function pathKey(options = {}) { + const { + env = process.env, + platform = process.platform + } = options; + + if (platform !== 'win32') { + return 'PATH'; + } + + return Object.keys(env).reverse().find(key => key.toUpperCase() === 'PATH') || 'Path'; +} + +promisify(execFile); + +function toPath(urlOrPath) { + return urlOrPath instanceof URL ? fileURLToPath(urlOrPath) : urlOrPath; +} + +function traversePathUp(startPath) { + return { + * [Symbol.iterator]() { + let currentPath = path.resolve(toPath(startPath)); + let previousPath; + + while (previousPath !== currentPath) { + yield currentPath; + previousPath = currentPath; + currentPath = path.resolve(currentPath, '..'); + } + }, + }; +} + +const npmRunPath = ({ + cwd = process$2.cwd(), + path: pathOption = process$2.env[pathKey()], + preferLocal = true, + execPath = process$2.execPath, + addExecPath = true, +} = {}) => { + const cwdPath = path.resolve(toPath(cwd)); + const result = []; + const pathParts = pathOption.split(path.delimiter); + + if (preferLocal) { + applyPreferLocal(result, pathParts, cwdPath); + } + + if (addExecPath) { + applyExecPath(result, pathParts, execPath, cwdPath); + } + + return pathOption === '' || pathOption === path.delimiter + ? `${result.join(path.delimiter)}${pathOption}` + : [...result, pathOption].join(path.delimiter); +}; + +const applyPreferLocal = (result, pathParts, cwdPath) => { + for (const directory of traversePathUp(cwdPath)) { + const pathPart = path.join(directory, 'node_modules/.bin'); + if (!pathParts.includes(pathPart)) { + result.push(pathPart); + } + } +}; + +// Ensure the running `node` binary is used +const applyExecPath = (result, pathParts, execPath, cwdPath) => { + const pathPart = path.resolve(cwdPath, toPath(execPath), '..'); + if (!pathParts.includes(pathPart)) { + result.push(pathPart); + } +}; + +const npmRunPathEnv = ({env = process$2.env, ...options} = {}) => { + env = {...env}; + + const pathName = pathKey({env}); + options.path = env[pathName]; + env[pathName] = npmRunPath(options); + + return env; +}; + +// When the subprocess fails, this is the error instance being returned. +// If another error instance is being thrown, it is kept as `error.cause`. +const getFinalError = (originalError, message, isSync) => { + const ErrorClass = isSync ? ExecaSyncError : ExecaError; + const options = originalError instanceof DiscardedError ? {} : {cause: originalError}; + return new ErrorClass(message, options); +}; + +// Indicates that the error is used only to interrupt control flow, but not in the return value +class DiscardedError extends Error {} + +// Proper way to set `error.name`: it should be inherited and non-enumerable +const setErrorName = (ErrorClass, value) => { + Object.defineProperty(ErrorClass.prototype, 'name', { + value, + writable: true, + enumerable: false, + configurable: true, + }); + Object.defineProperty(ErrorClass.prototype, execaErrorSymbol, { + value: true, + writable: false, + enumerable: false, + configurable: false, + }); +}; + +// Unlike `instanceof`, this works across realms +const isExecaError = error => isErrorInstance(error) && execaErrorSymbol in error; + +const execaErrorSymbol = Symbol('isExecaError'); + +const isErrorInstance = value => Object.prototype.toString.call(value) === '[object Error]'; + +// We use two different Error classes for async/sync methods since they have slightly different shape and types +class ExecaError extends Error {} +setErrorName(ExecaError, ExecaError.name); + +class ExecaSyncError extends Error {} +setErrorName(ExecaSyncError, ExecaSyncError.name); + +const getRealtimeSignals=()=>{ +const length=SIGRTMAX-SIGRTMIN+1; +return Array.from({length},getRealtimeSignal) +}; + +const getRealtimeSignal=(value,index)=>({ +name:`SIGRT${index+1}`, +number:SIGRTMIN+index, +action:"terminate", +description:"Application-specific signal (realtime)", +standard:"posix" +}); + +const SIGRTMIN=34; +const SIGRTMAX=64; + +const SIGNALS=[ +{ +name:"SIGHUP", +number:1, +action:"terminate", +description:"Terminal closed", +standard:"posix" +}, +{ +name:"SIGINT", +number:2, +action:"terminate", +description:"User interruption with CTRL-C", +standard:"ansi" +}, +{ +name:"SIGQUIT", +number:3, +action:"core", +description:"User interruption with CTRL-\\", +standard:"posix" +}, +{ +name:"SIGILL", +number:4, +action:"core", +description:"Invalid machine instruction", +standard:"ansi" +}, +{ +name:"SIGTRAP", +number:5, +action:"core", +description:"Debugger breakpoint", +standard:"posix" +}, +{ +name:"SIGABRT", +number:6, +action:"core", +description:"Aborted", +standard:"ansi" +}, +{ +name:"SIGIOT", +number:6, +action:"core", +description:"Aborted", +standard:"bsd" +}, +{ +name:"SIGBUS", +number:7, +action:"core", +description: +"Bus error due to misaligned, non-existing address or paging error", +standard:"bsd" +}, +{ +name:"SIGEMT", +number:7, +action:"terminate", +description:"Command should be emulated but is not implemented", +standard:"other" +}, +{ +name:"SIGFPE", +number:8, +action:"core", +description:"Floating point arithmetic error", +standard:"ansi" +}, +{ +name:"SIGKILL", +number:9, +action:"terminate", +description:"Forced termination", +standard:"posix", +forced:true +}, +{ +name:"SIGUSR1", +number:10, +action:"terminate", +description:"Application-specific signal", +standard:"posix" +}, +{ +name:"SIGSEGV", +number:11, +action:"core", +description:"Segmentation fault", +standard:"ansi" +}, +{ +name:"SIGUSR2", +number:12, +action:"terminate", +description:"Application-specific signal", +standard:"posix" +}, +{ +name:"SIGPIPE", +number:13, +action:"terminate", +description:"Broken pipe or socket", +standard:"posix" +}, +{ +name:"SIGALRM", +number:14, +action:"terminate", +description:"Timeout or timer", +standard:"posix" +}, +{ +name:"SIGTERM", +number:15, +action:"terminate", +description:"Termination", +standard:"ansi" +}, +{ +name:"SIGSTKFLT", +number:16, +action:"terminate", +description:"Stack is empty or overflowed", +standard:"other" +}, +{ +name:"SIGCHLD", +number:17, +action:"ignore", +description:"Child process terminated, paused or unpaused", +standard:"posix" +}, +{ +name:"SIGCLD", +number:17, +action:"ignore", +description:"Child process terminated, paused or unpaused", +standard:"other" +}, +{ +name:"SIGCONT", +number:18, +action:"unpause", +description:"Unpaused", +standard:"posix", +forced:true +}, +{ +name:"SIGSTOP", +number:19, +action:"pause", +description:"Paused", +standard:"posix", +forced:true +}, +{ +name:"SIGTSTP", +number:20, +action:"pause", +description:"Paused using CTRL-Z or \"suspend\"", +standard:"posix" +}, +{ +name:"SIGTTIN", +number:21, +action:"pause", +description:"Background process cannot read terminal input", +standard:"posix" +}, +{ +name:"SIGBREAK", +number:21, +action:"terminate", +description:"User interruption with CTRL-BREAK", +standard:"other" +}, +{ +name:"SIGTTOU", +number:22, +action:"pause", +description:"Background process cannot write to terminal output", +standard:"posix" +}, +{ +name:"SIGURG", +number:23, +action:"ignore", +description:"Socket received out-of-band data", +standard:"bsd" +}, +{ +name:"SIGXCPU", +number:24, +action:"core", +description:"Process timed out", +standard:"bsd" +}, +{ +name:"SIGXFSZ", +number:25, +action:"core", +description:"File too big", +standard:"bsd" +}, +{ +name:"SIGVTALRM", +number:26, +action:"terminate", +description:"Timeout or timer", +standard:"bsd" +}, +{ +name:"SIGPROF", +number:27, +action:"terminate", +description:"Timeout or timer", +standard:"bsd" +}, +{ +name:"SIGWINCH", +number:28, +action:"ignore", +description:"Terminal window size changed", +standard:"bsd" +}, +{ +name:"SIGIO", +number:29, +action:"terminate", +description:"I/O is available", +standard:"other" +}, +{ +name:"SIGPOLL", +number:29, +action:"terminate", +description:"Watched event", +standard:"other" +}, +{ +name:"SIGINFO", +number:29, +action:"ignore", +description:"Request for process information", +standard:"other" +}, +{ +name:"SIGPWR", +number:30, +action:"terminate", +description:"Device running out of power", +standard:"systemv" +}, +{ +name:"SIGSYS", +number:31, +action:"core", +description:"Invalid system call", +standard:"other" +}, +{ +name:"SIGUNUSED", +number:31, +action:"terminate", +description:"Invalid system call", +standard:"other" +}]; + +const getSignals=()=>{ +const realtimeSignals=getRealtimeSignals(); +const signals=[...SIGNALS,...realtimeSignals].map(normalizeSignal$1); +return signals +}; + + + + + + + +const normalizeSignal$1=({ +name, +number:defaultNumber, +description, +action, +forced=false, +standard +})=>{ +const{ +signals:{[name]:constantSignal} +}=constants$5; +const supported=constantSignal!==undefined; +const number=supported?constantSignal:defaultNumber; +return {name,number,description,supported,action,forced,standard} +}; + +const getSignalsByName=()=>{ +const signals=getSignals(); +return Object.fromEntries(signals.map(getSignalByName)) +}; + +const getSignalByName=({ +name, +number, +description, +supported, +action, +forced, +standard +})=>[name,{name,number,description,supported,action,forced,standard}]; + +const signalsByName=getSignalsByName(); + + + + +const getSignalsByNumber=()=>{ +const signals=getSignals(); +const length=SIGRTMAX+1; +const signalsA=Array.from({length},(value,number)=> +getSignalByNumber(number,signals) +); +return Object.assign({},...signalsA) +}; + +const getSignalByNumber=(number,signals)=>{ +const signal=findSignalByNumber(number,signals); + +if(signal===undefined){ +return {} +} + +const{name,description,supported,action,forced,standard}=signal; +return { +[number]:{ +name, +number, +description, +supported, +action, +forced, +standard +} +} +}; + + + +const findSignalByNumber=(number,signals)=>{ +const signal=signals.find(({name})=>constants$5.signals[name]===number); + +if(signal!==undefined){ +return signal +} + +return signals.find((signalA)=>signalA.number===number) +}; + +getSignalsByNumber(); + +// Normalize signals for comparison purpose. +// Also validate the signal exists. +const normalizeKillSignal = killSignal => { + const optionName = 'option `killSignal`'; + if (killSignal === 0) { + throw new TypeError(`Invalid ${optionName}: 0 cannot be used.`); + } + + return normalizeSignal(killSignal, optionName); +}; + +const normalizeSignalArgument = signal => signal === 0 + ? signal + : normalizeSignal(signal, '`subprocess.kill()`\'s argument'); + +const normalizeSignal = (signalNameOrInteger, optionName) => { + if (Number.isInteger(signalNameOrInteger)) { + return normalizeSignalInteger(signalNameOrInteger, optionName); + } + + if (typeof signalNameOrInteger === 'string') { + return normalizeSignalName(signalNameOrInteger, optionName); + } + + throw new TypeError(`Invalid ${optionName} ${String(signalNameOrInteger)}: it must be a string or an integer.\n${getAvailableSignals()}`); +}; + +const normalizeSignalInteger = (signalInteger, optionName) => { + if (signalsIntegerToName.has(signalInteger)) { + return signalsIntegerToName.get(signalInteger); + } + + throw new TypeError(`Invalid ${optionName} ${signalInteger}: this signal integer does not exist.\n${getAvailableSignals()}`); +}; + +const getSignalsIntegerToName = () => new Map(Object.entries(constants$5.signals) + .reverse() + .map(([signalName, signalInteger]) => [signalInteger, signalName])); + +const signalsIntegerToName = getSignalsIntegerToName(); + +const normalizeSignalName = (signalName, optionName) => { + if (signalName in constants$5.signals) { + return signalName; + } + + if (signalName.toUpperCase() in constants$5.signals) { + throw new TypeError(`Invalid ${optionName} '${signalName}': please rename it to '${signalName.toUpperCase()}'.`); + } + + throw new TypeError(`Invalid ${optionName} '${signalName}': this signal name does not exist.\n${getAvailableSignals()}`); +}; + +const getAvailableSignals = () => `Available signal names: ${getAvailableSignalNames()}. +Available signal numbers: ${getAvailableSignalIntegers()}.`; + +const getAvailableSignalNames = () => Object.keys(constants$5.signals) + .sort() + .map(signalName => `'${signalName}'`) + .join(', '); + +const getAvailableSignalIntegers = () => [...new Set(Object.values(constants$5.signals) + .sort((signalInteger, signalIntegerTwo) => signalInteger - signalIntegerTwo))] + .join(', '); + +// Human-friendly description of a signal +const getSignalDescription = signal => signalsByName[signal].description; + +// Normalize the `forceKillAfterDelay` option +const normalizeForceKillAfterDelay = forceKillAfterDelay => { + if (forceKillAfterDelay === false) { + return forceKillAfterDelay; + } + + if (forceKillAfterDelay === true) { + return DEFAULT_FORCE_KILL_TIMEOUT; + } + + if (!Number.isFinite(forceKillAfterDelay) || forceKillAfterDelay < 0) { + throw new TypeError(`Expected the \`forceKillAfterDelay\` option to be a non-negative integer, got \`${forceKillAfterDelay}\` (${typeof forceKillAfterDelay})`); + } + + return forceKillAfterDelay; +}; + +const DEFAULT_FORCE_KILL_TIMEOUT = 1000 * 5; + +// Monkey-patches `subprocess.kill()` to add `forceKillAfterDelay` behavior and `.kill(error)` +const subprocessKill = ( + {kill, options: {forceKillAfterDelay, killSignal}, onInternalError, context, controller}, + signalOrError, + errorArgument, +) => { + const {signal, error} = parseKillArguments(signalOrError, errorArgument, killSignal); + emitKillError(error, onInternalError); + const killResult = kill(signal); + setKillTimeout({ + kill, + signal, + forceKillAfterDelay, + killSignal, + killResult, + context, + controller, + }); + return killResult; +}; + +const parseKillArguments = (signalOrError, errorArgument, killSignal) => { + const [signal = killSignal, error] = isErrorInstance(signalOrError) + ? [undefined, signalOrError] + : [signalOrError, errorArgument]; + + if (typeof signal !== 'string' && !Number.isInteger(signal)) { + throw new TypeError(`The first argument must be an error instance or a signal name string/integer: ${String(signal)}`); + } + + if (error !== undefined && !isErrorInstance(error)) { + throw new TypeError(`The second argument is optional. If specified, it must be an error instance: ${error}`); + } + + return {signal: normalizeSignalArgument(signal), error}; +}; + +// Fails right away when calling `subprocess.kill(error)`. +// Does not wait for actual signal termination. +// Uses a deferred promise instead of the `error` event on the subprocess, as this is less intrusive. +const emitKillError = (error, onInternalError) => { + if (error !== undefined) { + onInternalError.reject(error); + } +}; + +const setKillTimeout = async ({kill, signal, forceKillAfterDelay, killSignal, killResult, context, controller}) => { + if (signal === killSignal && killResult) { + killOnTimeout({ + kill, + forceKillAfterDelay, + context, + controllerSignal: controller.signal, + }); + } +}; + +// Forcefully terminate a subprocess after a timeout +const killOnTimeout = async ({kill, forceKillAfterDelay, context, controllerSignal}) => { + if (forceKillAfterDelay === false) { + return; + } + + try { + await setTimeout$1(forceKillAfterDelay, undefined, {signal: controllerSignal}); + if (kill('SIGKILL')) { + context.isForcefullyTerminated ??= true; + } + } catch {} +}; + +// Combines `util.aborted()` and `events.addAbortListener()`: promise-based and cleaned up with a stop signal +const onAbortedSignal = async (mainSignal, stopSignal) => { + if (!mainSignal.aborted) { + await once$2(mainSignal, 'abort', {signal: stopSignal}); + } +}; + +// Validate the `cancelSignal` option +const validateCancelSignal = ({cancelSignal}) => { + if (cancelSignal !== undefined && Object.prototype.toString.call(cancelSignal) !== '[object AbortSignal]') { + throw new Error(`The \`cancelSignal\` option must be an AbortSignal: ${String(cancelSignal)}`); + } +}; + +// Terminate the subprocess when aborting the `cancelSignal` option and `gracefulSignal` is `false` +const throwOnCancel = ({subprocess, cancelSignal, gracefulCancel, context, controller}) => cancelSignal === undefined || gracefulCancel + ? [] + : [terminateOnCancel(subprocess, cancelSignal, context, controller)]; + +const terminateOnCancel = async (subprocess, cancelSignal, context, {signal}) => { + await onAbortedSignal(cancelSignal, signal); + context.terminationReason ??= 'cancel'; + subprocess.kill(); + throw cancelSignal.reason; +}; + +// Validate the IPC channel is connected before receiving/sending messages +const validateIpcMethod = ({methodName, isSubprocess, ipc, isConnected}) => { + validateIpcOption(methodName, isSubprocess, ipc); + validateConnection(methodName, isSubprocess, isConnected); +}; + +// Better error message when forgetting to set `ipc: true` and using the IPC methods +const validateIpcOption = (methodName, isSubprocess, ipc) => { + if (!ipc) { + throw new Error(`${getMethodName(methodName, isSubprocess)} can only be used if the \`ipc\` option is \`true\`.`); + } +}; + +// Better error message when one process does not send/receive messages once the other process has disconnected. +// This also makes it clear that any buffered messages are lost once either process has disconnected. +// Also when aborting `cancelSignal` after disconnecting the IPC. +const validateConnection = (methodName, isSubprocess, isConnected) => { + if (!isConnected) { + throw new Error(`${getMethodName(methodName, isSubprocess)} cannot be used: the ${getOtherProcessName(isSubprocess)} has already exited or disconnected.`); + } +}; + +// When `getOneMessage()` could not complete due to an early disconnection +const throwOnEarlyDisconnect = isSubprocess => { + throw new Error(`${getMethodName('getOneMessage', isSubprocess)} could not complete: the ${getOtherProcessName(isSubprocess)} exited or disconnected.`); +}; + +// When both processes use `sendMessage()` with `strict` at the same time +const throwOnStrictDeadlockError = isSubprocess => { + throw new Error(`${getMethodName('sendMessage', isSubprocess)} failed: the ${getOtherProcessName(isSubprocess)} is sending a message too, instead of listening to incoming messages. +This can be fixed by both sending a message and listening to incoming messages at the same time: + +const [receivedMessage] = await Promise.all([ + ${getMethodName('getOneMessage', isSubprocess)}, + ${getMethodName('sendMessage', isSubprocess, 'message, {strict: true}')}, +]);`); +}; + +// When the other process used `strict` but the current process had I/O error calling `sendMessage()` for the response +const getStrictResponseError = (error, isSubprocess) => new Error(`${getMethodName('sendMessage', isSubprocess)} failed when sending an acknowledgment response to the ${getOtherProcessName(isSubprocess)}.`, {cause: error}); + +// When using `strict` but the other process was not listening for messages +const throwOnMissingStrict = isSubprocess => { + throw new Error(`${getMethodName('sendMessage', isSubprocess)} failed: the ${getOtherProcessName(isSubprocess)} is not listening to incoming messages.`); +}; + +// When using `strict` but the other process disconnected before receiving the message +const throwOnStrictDisconnect = isSubprocess => { + throw new Error(`${getMethodName('sendMessage', isSubprocess)} failed: the ${getOtherProcessName(isSubprocess)} exited without listening to incoming messages.`); +}; + +// When the current process disconnects while the subprocess is listening to `cancelSignal` +const getAbortDisconnectError = () => new Error(`\`cancelSignal\` aborted: the ${getOtherProcessName(true)} disconnected.`); + +// When the subprocess uses `cancelSignal` but not the current process +const throwOnMissingParent = () => { + throw new Error('`getCancelSignal()` cannot be used without setting the `cancelSignal` subprocess option.'); +}; + +// EPIPE can happen when sending a message to a subprocess that is closing but has not disconnected yet +const handleEpipeError = ({error, methodName, isSubprocess}) => { + if (error.code === 'EPIPE') { + throw new Error(`${getMethodName(methodName, isSubprocess)} cannot be used: the ${getOtherProcessName(isSubprocess)} is disconnecting.`, {cause: error}); + } +}; + +// Better error message when sending messages which cannot be serialized. +// Works with both `serialization: 'advanced'` and `serialization: 'json'`. +const handleSerializationError = ({error, methodName, isSubprocess, message}) => { + if (isSerializationError(error)) { + throw new Error(`${getMethodName(methodName, isSubprocess)}'s argument type is invalid: the message cannot be serialized: ${String(message)}.`, {cause: error}); + } +}; + +const isSerializationError = ({code, message}) => SERIALIZATION_ERROR_CODES.has(code) + || SERIALIZATION_ERROR_MESSAGES.some(serializationErrorMessage => message.includes(serializationErrorMessage)); + +// `error.code` set by Node.js when it failed to serialize the message +const SERIALIZATION_ERROR_CODES = new Set([ + // Message is `undefined` + 'ERR_MISSING_ARGS', + // Message is a function, a bigint, a symbol + 'ERR_INVALID_ARG_TYPE', +]); + +// `error.message` set by Node.js when it failed to serialize the message +const SERIALIZATION_ERROR_MESSAGES = [ + // Message is a promise or a proxy, with `serialization: 'advanced'` + 'could not be cloned', + // Message has cycles, with `serialization: 'json'` + 'circular structure', + // Message has cycles inside toJSON(), with `serialization: 'json'` + 'call stack size exceeded', +]; + +const getMethodName = (methodName, isSubprocess, parameters = '') => methodName === 'cancelSignal' + ? '`cancelSignal`\'s `controller.abort()`' + : `${getNamespaceName(isSubprocess)}${methodName}(${parameters})`; + +const getNamespaceName = isSubprocess => isSubprocess ? '' : 'subprocess.'; + +const getOtherProcessName = isSubprocess => isSubprocess ? 'parent process' : 'subprocess'; + +// When any error arises, we disconnect the IPC. +// Otherwise, it is likely that one of the processes will stop sending/receiving messages. +// This would leave the other process hanging. +const disconnect = anyProcess => { + if (anyProcess.connected) { + anyProcess.disconnect(); + } +}; + +const createDeferred = () => { + const methods = {}; + const promise = new Promise((resolve, reject) => { + Object.assign(methods, {resolve, reject}); + }); + return Object.assign(promise, methods); +}; + +// Retrieve stream targeted by the `to` option +const getToStream = (destination, to = 'stdin') => { + const isWritable = true; + const {options, fileDescriptors} = SUBPROCESS_OPTIONS.get(destination); + const fdNumber = getFdNumber(fileDescriptors, to, isWritable); + const destinationStream = destination.stdio[fdNumber]; + + if (destinationStream === null) { + throw new TypeError(getInvalidStdioOptionMessage(fdNumber, to, options, isWritable)); + } + + return destinationStream; +}; + +// Retrieve stream targeted by the `from` option +const getFromStream = (source, from = 'stdout') => { + const isWritable = false; + const {options, fileDescriptors} = SUBPROCESS_OPTIONS.get(source); + const fdNumber = getFdNumber(fileDescriptors, from, isWritable); + const sourceStream = fdNumber === 'all' ? source.all : source.stdio[fdNumber]; + + if (sourceStream === null || sourceStream === undefined) { + throw new TypeError(getInvalidStdioOptionMessage(fdNumber, from, options, isWritable)); + } + + return sourceStream; +}; + +// Keeps track of the options passed to each Execa call +const SUBPROCESS_OPTIONS = new WeakMap(); + +const getFdNumber = (fileDescriptors, fdName, isWritable) => { + const fdNumber = parseFdNumber(fdName, isWritable); + validateFdNumber(fdNumber, fdName, isWritable, fileDescriptors); + return fdNumber; +}; + +const parseFdNumber = (fdName, isWritable) => { + const fdNumber = parseFd(fdName); + if (fdNumber !== undefined) { + return fdNumber; + } + + const {validOptions, defaultValue} = isWritable + ? {validOptions: '"stdin"', defaultValue: 'stdin'} + : {validOptions: '"stdout", "stderr", "all"', defaultValue: 'stdout'}; + throw new TypeError(`"${getOptionName(isWritable)}" must not be "${fdName}". +It must be ${validOptions} or "fd3", "fd4" (and so on). +It is optional and defaults to "${defaultValue}".`); +}; + +const validateFdNumber = (fdNumber, fdName, isWritable, fileDescriptors) => { + const fileDescriptor = fileDescriptors[getUsedDescriptor(fdNumber)]; + if (fileDescriptor === undefined) { + throw new TypeError(`"${getOptionName(isWritable)}" must not be ${fdName}. That file descriptor does not exist. +Please set the "stdio" option to ensure that file descriptor exists.`); + } + + if (fileDescriptor.direction === 'input' && !isWritable) { + throw new TypeError(`"${getOptionName(isWritable)}" must not be ${fdName}. It must be a readable stream, not writable.`); + } + + if (fileDescriptor.direction !== 'input' && isWritable) { + throw new TypeError(`"${getOptionName(isWritable)}" must not be ${fdName}. It must be a writable stream, not readable.`); + } +}; + +const getInvalidStdioOptionMessage = (fdNumber, fdName, options, isWritable) => { + if (fdNumber === 'all' && !options.all) { + return 'The "all" option must be true to use "from: \'all\'".'; + } + + const {optionName, optionValue} = getInvalidStdioOption(fdNumber, options); + return `The "${optionName}: ${serializeOptionValue(optionValue)}" option is incompatible with using "${getOptionName(isWritable)}: ${serializeOptionValue(fdName)}". +Please set this option with "pipe" instead.`; +}; + +const getInvalidStdioOption = (fdNumber, {stdin, stdout, stderr, stdio}) => { + const usedDescriptor = getUsedDescriptor(fdNumber); + + if (usedDescriptor === 0 && stdin !== undefined) { + return {optionName: 'stdin', optionValue: stdin}; + } + + if (usedDescriptor === 1 && stdout !== undefined) { + return {optionName: 'stdout', optionValue: stdout}; + } + + if (usedDescriptor === 2 && stderr !== undefined) { + return {optionName: 'stderr', optionValue: stderr}; + } + + return {optionName: `stdio[${usedDescriptor}]`, optionValue: stdio[usedDescriptor]}; +}; + +const getUsedDescriptor = fdNumber => fdNumber === 'all' ? 1 : fdNumber; + +const getOptionName = isWritable => isWritable ? 'to' : 'from'; + +const serializeOptionValue = value => { + if (typeof value === 'string') { + return `'${value}'`; + } + + return typeof value === 'number' ? `${value}` : 'Stream'; +}; + +// Temporarily increase the maximum number of listeners on an eventEmitter +const incrementMaxListeners = (eventEmitter, maxListenersIncrement, signal) => { + const maxListeners = eventEmitter.getMaxListeners(); + if (maxListeners === 0 || maxListeners === Number.POSITIVE_INFINITY) { + return; + } + + eventEmitter.setMaxListeners(maxListeners + maxListenersIncrement); + addAbortListener(signal, () => { + eventEmitter.setMaxListeners(eventEmitter.getMaxListeners() - maxListenersIncrement); + }); +}; + +// By default, Node.js keeps the subprocess alive while it has a `message` or `disconnect` listener. +// We replicate the same logic for the events that we proxy. +// This ensures the subprocess is kept alive while `getOneMessage()` and `getEachMessage()` are ongoing. +// This is not a problem with `sendMessage()` since Node.js handles that method automatically. +// We do not use `anyProcess.channel.ref()` since this would prevent the automatic `.channel.refCounted()` Node.js is doing. +// We keep a reference to `anyProcess.channel` since it might be `null` while `getOneMessage()` or `getEachMessage()` is still processing debounced messages. +// See https://github.com/nodejs/node/blob/2aaeaa863c35befa2ebaa98fb7737ec84df4d8e9/lib/internal/child_process.js#L547 +const addReference = (channel, reference) => { + if (reference) { + addReferenceCount(channel); + } +}; + +const addReferenceCount = channel => { + channel.refCounted(); +}; + +const removeReference = (channel, reference) => { + if (reference) { + removeReferenceCount(channel); + } +}; + +const removeReferenceCount = channel => { + channel.unrefCounted(); +}; + +// To proxy events, we setup some global listeners on the `message` and `disconnect` events. +// Those should not keep the subprocess alive, so we remove the automatic counting that Node.js is doing. +// See https://github.com/nodejs/node/blob/1b965270a9c273d4cf70e8808e9d28b9ada7844f/lib/child_process.js#L180 +const undoAddedReferences = (channel, isSubprocess) => { + if (isSubprocess) { + removeReferenceCount(channel); + removeReferenceCount(channel); + } +}; + +// Reverse it during `disconnect` +const redoAddedReferences = (channel, isSubprocess) => { + if (isSubprocess) { + addReferenceCount(channel); + addReferenceCount(channel); + } +}; + +// By default, Node.js buffers `message` events. +// - Buffering happens when there is a `message` event is emitted but there is no handler. +// - As soon as a `message` event handler is set, all buffered `message` events are emitted, emptying the buffer. +// - This happens both in the current process and the subprocess. +// - See https://github.com/nodejs/node/blob/501546e8f37059cd577041e23941b640d0d4d406/lib/internal/child_process.js#L719 +// This is helpful. Notably, this allows sending messages to a subprocess that's still initializing. +// However, it has several problems. +// - This works with `events.on()` but not `events.once()` since all buffered messages are emitted at once. +// For example, users cannot call `await getOneMessage()`/`getEachMessage()` multiple times in a row. +// - When a user intentionally starts listening to `message` at a specific point in time, past `message` events are replayed, which might be unexpected. +// - Buffering is unlimited, which might lead to an out-of-memory crash. +// - This does not work well with multiple consumers. +// For example, Execa consumes events with both `result.ipcOutput` and manual IPC calls like `getOneMessage()`. +// Since `result.ipcOutput` reads all incoming messages, no buffering happens for manual IPC calls. +// - Forgetting to setup a `message` listener, or setting it up too late, is a programming mistake. +// The default behavior does not allow users to realize they made that mistake. +// To solve those problems, instead of buffering messages, we debounce them. +// The `message` event so it is emitted at most once per macrotask. +const onMessage = async ({anyProcess, channel, isSubprocess, ipcEmitter}, wrappedMessage) => { + if (handleStrictResponse(wrappedMessage) || handleAbort(wrappedMessage)) { + return; + } + + if (!INCOMING_MESSAGES.has(anyProcess)) { + INCOMING_MESSAGES.set(anyProcess, []); + } + + const incomingMessages = INCOMING_MESSAGES.get(anyProcess); + incomingMessages.push(wrappedMessage); + + if (incomingMessages.length > 1) { + return; + } + + while (incomingMessages.length > 0) { + // eslint-disable-next-line no-await-in-loop + await waitForOutgoingMessages(anyProcess, ipcEmitter, wrappedMessage); + // eslint-disable-next-line no-await-in-loop + await scheduler.yield(); + + // eslint-disable-next-line no-await-in-loop + const message = await handleStrictRequest({ + wrappedMessage: incomingMessages[0], + anyProcess, + channel, + isSubprocess, + ipcEmitter, + }); + + incomingMessages.shift(); + ipcEmitter.emit('message', message); + ipcEmitter.emit('message:done'); + } +}; + +// If the `message` event is currently debounced, the `disconnect` event must wait for it +const onDisconnect = async ({anyProcess, channel, isSubprocess, ipcEmitter, boundOnMessage}) => { + abortOnDisconnect(); + + const incomingMessages = INCOMING_MESSAGES.get(anyProcess); + while (incomingMessages?.length > 0) { + // eslint-disable-next-line no-await-in-loop + await once$2(ipcEmitter, 'message:done'); + } + + anyProcess.removeListener('message', boundOnMessage); + redoAddedReferences(channel, isSubprocess); + ipcEmitter.connected = false; + ipcEmitter.emit('disconnect'); +}; + +const INCOMING_MESSAGES = new WeakMap(); + +// Forward the `message` and `disconnect` events from the process and subprocess to a proxy emitter. +// This prevents the `error` event from stopping IPC. +// This also allows debouncing the `message` event. +const getIpcEmitter = (anyProcess, channel, isSubprocess) => { + if (IPC_EMITTERS.has(anyProcess)) { + return IPC_EMITTERS.get(anyProcess); + } + + // Use an `EventEmitter`, like the `process` that is being proxied + // eslint-disable-next-line unicorn/prefer-event-target + const ipcEmitter = new EventEmitter(); + ipcEmitter.connected = true; + IPC_EMITTERS.set(anyProcess, ipcEmitter); + forwardEvents({ + ipcEmitter, + anyProcess, + channel, + isSubprocess, + }); + return ipcEmitter; +}; + +const IPC_EMITTERS = new WeakMap(); + +// The `message` and `disconnect` events are buffered in the subprocess until the first listener is setup. +// However, unbuffering happens after one tick, so this give enough time for the caller to setup the listener on the proxy emitter first. +// See https://github.com/nodejs/node/blob/2aaeaa863c35befa2ebaa98fb7737ec84df4d8e9/lib/internal/child_process.js#L721 +const forwardEvents = ({ipcEmitter, anyProcess, channel, isSubprocess}) => { + const boundOnMessage = onMessage.bind(undefined, { + anyProcess, + channel, + isSubprocess, + ipcEmitter, + }); + anyProcess.on('message', boundOnMessage); + anyProcess.once('disconnect', onDisconnect.bind(undefined, { + anyProcess, + channel, + isSubprocess, + ipcEmitter, + boundOnMessage, + })); + undoAddedReferences(channel, isSubprocess); +}; + +// Check whether there might still be some `message` events to receive +const isConnected = anyProcess => { + const ipcEmitter = IPC_EMITTERS.get(anyProcess); + return ipcEmitter === undefined + ? anyProcess.channel !== null + : ipcEmitter.connected; +}; + +// When using the `strict` option, wrap the message with metadata during `sendMessage()` +const handleSendStrict = ({anyProcess, channel, isSubprocess, message, strict}) => { + if (!strict) { + return message; + } + + const ipcEmitter = getIpcEmitter(anyProcess, channel, isSubprocess); + const hasListeners = hasMessageListeners(anyProcess, ipcEmitter); + return { + id: count++, + type: REQUEST_TYPE, + message, + hasListeners, + }; +}; + +let count = 0n; + +// Handles when both processes are calling `sendMessage()` with `strict` at the same time. +// If neither process is listening, this would create a deadlock. We detect it and throw. +const validateStrictDeadlock = (outgoingMessages, wrappedMessage) => { + if (wrappedMessage?.type !== REQUEST_TYPE || wrappedMessage.hasListeners) { + return; + } + + for (const {id} of outgoingMessages) { + if (id !== undefined) { + STRICT_RESPONSES[id].resolve({isDeadlock: true, hasListeners: false}); + } + } +}; + +// The other process then sends the acknowledgment back as a response +const handleStrictRequest = async ({wrappedMessage, anyProcess, channel, isSubprocess, ipcEmitter}) => { + if (wrappedMessage?.type !== REQUEST_TYPE || !anyProcess.connected) { + return wrappedMessage; + } + + const {id, message} = wrappedMessage; + const response = {id, type: RESPONSE_TYPE, message: hasMessageListeners(anyProcess, ipcEmitter)}; + + try { + await sendMessage({ + anyProcess, + channel, + isSubprocess, + ipc: true, + }, response); + } catch (error) { + ipcEmitter.emit('strict:error', error); + } + + return message; +}; + +// Reception of the acknowledgment response +const handleStrictResponse = wrappedMessage => { + if (wrappedMessage?.type !== RESPONSE_TYPE) { + return false; + } + + const {id, message: hasListeners} = wrappedMessage; + STRICT_RESPONSES[id]?.resolve({isDeadlock: false, hasListeners}); + return true; +}; + +// Wait for the other process to receive the message from `sendMessage()` +const waitForStrictResponse = async (wrappedMessage, anyProcess, isSubprocess) => { + if (wrappedMessage?.type !== REQUEST_TYPE) { + return; + } + + const deferred = createDeferred(); + STRICT_RESPONSES[wrappedMessage.id] = deferred; + const controller = new AbortController(); + + try { + const {isDeadlock, hasListeners} = await Promise.race([ + deferred, + throwOnDisconnect$1(anyProcess, isSubprocess, controller), + ]); + + if (isDeadlock) { + throwOnStrictDeadlockError(isSubprocess); + } + + if (!hasListeners) { + throwOnMissingStrict(isSubprocess); + } + } finally { + controller.abort(); + delete STRICT_RESPONSES[wrappedMessage.id]; + } +}; + +const STRICT_RESPONSES = {}; + +const throwOnDisconnect$1 = async (anyProcess, isSubprocess, {signal}) => { + incrementMaxListeners(anyProcess, 1, signal); + await once$2(anyProcess, 'disconnect', {signal}); + throwOnStrictDisconnect(isSubprocess); +}; + +const REQUEST_TYPE = 'execa:ipc:request'; +const RESPONSE_TYPE = 'execa:ipc:response'; + +// When `sendMessage()` is ongoing, any `message` being received waits before being emitted. +// This allows calling one or multiple `await sendMessage()` followed by `await getOneMessage()`/`await getEachMessage()`. +// Without running into a race condition when the other process sends a response too fast, before the current process set up a listener. +const startSendMessage = (anyProcess, wrappedMessage, strict) => { + if (!OUTGOING_MESSAGES.has(anyProcess)) { + OUTGOING_MESSAGES.set(anyProcess, new Set()); + } + + const outgoingMessages = OUTGOING_MESSAGES.get(anyProcess); + const onMessageSent = createDeferred(); + const id = strict ? wrappedMessage.id : undefined; + const outgoingMessage = {onMessageSent, id}; + outgoingMessages.add(outgoingMessage); + return {outgoingMessages, outgoingMessage}; +}; + +const endSendMessage = ({outgoingMessages, outgoingMessage}) => { + outgoingMessages.delete(outgoingMessage); + outgoingMessage.onMessageSent.resolve(); +}; + +// Await while `sendMessage()` is ongoing, unless there is already a `message` listener +const waitForOutgoingMessages = async (anyProcess, ipcEmitter, wrappedMessage) => { + while (!hasMessageListeners(anyProcess, ipcEmitter) && OUTGOING_MESSAGES.get(anyProcess)?.size > 0) { + const outgoingMessages = [...OUTGOING_MESSAGES.get(anyProcess)]; + validateStrictDeadlock(outgoingMessages, wrappedMessage); + // eslint-disable-next-line no-await-in-loop + await Promise.all(outgoingMessages.map(({onMessageSent}) => onMessageSent)); + } +}; + +const OUTGOING_MESSAGES = new WeakMap(); + +// Whether any `message` listener is setup +const hasMessageListeners = (anyProcess, ipcEmitter) => ipcEmitter.listenerCount('message') > getMinListenerCount(anyProcess); + +// When `buffer` is `false`, we set up a `message` listener that should be ignored. +// That listener is only meant to intercept `strict` acknowledgement responses. +const getMinListenerCount = anyProcess => SUBPROCESS_OPTIONS.has(anyProcess) + && !getFdSpecificValue(SUBPROCESS_OPTIONS.get(anyProcess).options.buffer, 'ipc') + ? 1 + : 0; + +// Like `[sub]process.send()` but promise-based. +// We do not `await subprocess` during `.sendMessage()` nor `.getOneMessage()` since those methods are transient. +// Users would still need to `await subprocess` after the method is done. +// Also, this would prevent `unhandledRejection` event from being emitted, making it silent. +const sendMessage = ({anyProcess, channel, isSubprocess, ipc}, message, {strict = false} = {}) => { + const methodName = 'sendMessage'; + validateIpcMethod({ + methodName, + isSubprocess, + ipc, + isConnected: anyProcess.connected, + }); + + return sendMessageAsync({ + anyProcess, + channel, + methodName, + isSubprocess, + message, + strict, + }); +}; + +const sendMessageAsync = async ({anyProcess, channel, methodName, isSubprocess, message, strict}) => { + const wrappedMessage = handleSendStrict({ + anyProcess, + channel, + isSubprocess, + message, + strict, + }); + const outgoingMessagesState = startSendMessage(anyProcess, wrappedMessage, strict); + try { + await sendOneMessage({ + anyProcess, + methodName, + isSubprocess, + wrappedMessage, + message, + }); + } catch (error) { + disconnect(anyProcess); + throw error; + } finally { + endSendMessage(outgoingMessagesState); + } +}; + +// Used internally by `cancelSignal` +const sendOneMessage = async ({anyProcess, methodName, isSubprocess, wrappedMessage, message}) => { + const sendMethod = getSendMethod(anyProcess); + + try { + await Promise.all([ + waitForStrictResponse(wrappedMessage, anyProcess, isSubprocess), + sendMethod(wrappedMessage), + ]); + } catch (error) { + handleEpipeError({error, methodName, isSubprocess}); + handleSerializationError({ + error, + methodName, + isSubprocess, + message, + }); + throw error; + } +}; + +// [sub]process.send() promisified, memoized +const getSendMethod = anyProcess => { + if (PROCESS_SEND_METHODS.has(anyProcess)) { + return PROCESS_SEND_METHODS.get(anyProcess); + } + + const sendMethod = promisify(anyProcess.send.bind(anyProcess)); + PROCESS_SEND_METHODS.set(anyProcess, sendMethod); + return sendMethod; +}; + +const PROCESS_SEND_METHODS = new WeakMap(); + +// Send an IPC message so the subprocess performs a graceful termination +const sendAbort = (subprocess, message) => { + const methodName = 'cancelSignal'; + validateConnection(methodName, false, subprocess.connected); + return sendOneMessage({ + anyProcess: subprocess, + methodName, + isSubprocess: false, + wrappedMessage: {type: GRACEFUL_CANCEL_TYPE, message}, + message, + }); +}; + +// When the signal is being used, start listening for incoming messages. +// Unbuffering messages takes one microtask to complete, so this must be async. +const getCancelSignal = async ({anyProcess, channel, isSubprocess, ipc}) => { + await startIpc({ + anyProcess, + channel, + isSubprocess, + ipc, + }); + return cancelController.signal; +}; + +const startIpc = async ({anyProcess, channel, isSubprocess, ipc}) => { + if (cancelListening) { + return; + } + + cancelListening = true; + + if (!ipc) { + throwOnMissingParent(); + return; + } + + if (channel === null) { + abortOnDisconnect(); + return; + } + + getIpcEmitter(anyProcess, channel, isSubprocess); + await scheduler.yield(); +}; + +let cancelListening = false; + +// Reception of IPC message to perform a graceful termination +const handleAbort = wrappedMessage => { + if (wrappedMessage?.type !== GRACEFUL_CANCEL_TYPE) { + return false; + } + + cancelController.abort(wrappedMessage.message); + return true; +}; + +const GRACEFUL_CANCEL_TYPE = 'execa:ipc:cancel'; + +// When the current process disconnects early, the subprocess `cancelSignal` is aborted. +// Otherwise, the signal would never be able to be aborted later on. +const abortOnDisconnect = () => { + cancelController.abort(getAbortDisconnectError()); +}; + +const cancelController = new AbortController(); + +// Validate the `gracefulCancel` option +const validateGracefulCancel = ({gracefulCancel, cancelSignal, ipc, serialization}) => { + if (!gracefulCancel) { + return; + } + + if (cancelSignal === undefined) { + throw new Error('The `cancelSignal` option must be defined when setting the `gracefulCancel` option.'); + } + + if (!ipc) { + throw new Error('The `ipc` option cannot be false when setting the `gracefulCancel` option.'); + } + + if (serialization === 'json') { + throw new Error('The `serialization` option cannot be \'json\' when setting the `gracefulCancel` option.'); + } +}; + +// Send abort reason to the subprocess when aborting the `cancelSignal` option and `gracefulCancel` is `true` +const throwOnGracefulCancel = ({ + subprocess, + cancelSignal, + gracefulCancel, + forceKillAfterDelay, + context, + controller, +}) => gracefulCancel + ? [sendOnAbort({ + subprocess, + cancelSignal, + forceKillAfterDelay, + context, + controller, + })] + : []; + +const sendOnAbort = async ({subprocess, cancelSignal, forceKillAfterDelay, context, controller: {signal}}) => { + await onAbortedSignal(cancelSignal, signal); + const reason = getReason(cancelSignal); + await sendAbort(subprocess, reason); + killOnTimeout({ + kill: subprocess.kill, + forceKillAfterDelay, + context, + controllerSignal: signal, + }); + context.terminationReason ??= 'gracefulCancel'; + throw cancelSignal.reason; +}; + +// The default `reason` is a DOMException, which is not serializable with V8 +// See https://github.com/nodejs/node/issues/53225 +const getReason = ({reason}) => { + if (!(reason instanceof DOMException)) { + return reason; + } + + const error = new Error(reason.message); + Object.defineProperty(error, 'stack', { + value: reason.stack, + enumerable: false, + configurable: true, + writable: true, + }); + return error; +}; + +// Validate `timeout` option +const validateTimeout = ({timeout}) => { + if (timeout !== undefined && (!Number.isFinite(timeout) || timeout < 0)) { + throw new TypeError(`Expected the \`timeout\` option to be a non-negative integer, got \`${timeout}\` (${typeof timeout})`); + } +}; + +// Fails when the `timeout` option is exceeded +const throwOnTimeout = (subprocess, timeout, context, controller) => timeout === 0 || timeout === undefined + ? [] + : [killAfterTimeout(subprocess, timeout, context, controller)]; + +const killAfterTimeout = async (subprocess, timeout, context, {signal}) => { + await setTimeout$1(timeout, undefined, {signal}); + context.terminationReason ??= 'timeout'; + subprocess.kill(); + throw new DiscardedError(); +}; + +// `execaNode()` is a shortcut for `execa(..., {node: true})` +const mapNode = ({options}) => { + if (options.node === false) { + throw new TypeError('The "node" option cannot be false with `execaNode()`.'); + } + + return {options: {...options, node: true}}; +}; + +// Applies the `node: true` option, and the related `nodePath`/`nodeOptions` options. +// Modifies the file commands/arguments to ensure the same Node binary and flags are re-used. +// Also adds `ipc: true` and `shell: false`. +const handleNodeOption = (file, commandArguments, { + node: shouldHandleNode = false, + nodePath = execPath, + nodeOptions = execArgv.filter(nodeOption => !nodeOption.startsWith('--inspect')), + cwd, + execPath: formerNodePath, + ...options +}) => { + if (formerNodePath !== undefined) { + throw new TypeError('The "execPath" option has been removed. Please use the "nodePath" option instead.'); + } + + const normalizedNodePath = safeNormalizeFileUrl(nodePath, 'The "nodePath" option'); + const resolvedNodePath = path.resolve(cwd, normalizedNodePath); + const newOptions = { + ...options, + nodePath: resolvedNodePath, + node: shouldHandleNode, + cwd, + }; + + if (!shouldHandleNode) { + return [file, commandArguments, newOptions]; + } + + if (path.basename(file, '.exe') === 'node') { + throw new TypeError('When the "node" option is true, the first argument does not need to be "node".'); + } + + return [ + resolvedNodePath, + [...nodeOptions, file, ...commandArguments], + {ipc: true, ...newOptions, shell: false}, + ]; +}; + +// Validate the `ipcInput` option +const validateIpcInputOption = ({ipcInput, ipc, serialization}) => { + if (ipcInput === undefined) { + return; + } + + if (!ipc) { + throw new Error('The `ipcInput` option cannot be set unless the `ipc` option is `true`.'); + } + + validateIpcInput[serialization](ipcInput); +}; + +const validateAdvancedInput = ipcInput => { + try { + serialize(ipcInput); + } catch (error) { + throw new Error('The `ipcInput` option is not serializable with a structured clone.', {cause: error}); + } +}; + +const validateJsonInput = ipcInput => { + try { + JSON.stringify(ipcInput); + } catch (error) { + throw new Error('The `ipcInput` option is not serializable with JSON.', {cause: error}); + } +}; + +const validateIpcInput = { + advanced: validateAdvancedInput, + json: validateJsonInput, +}; + +// When the `ipcInput` option is set, it is sent as an initial IPC message to the subprocess +const sendIpcInput = async (subprocess, ipcInput) => { + if (ipcInput === undefined) { + return; + } + + await subprocess.sendMessage(ipcInput); +}; + +// Validate `encoding` option +const validateEncoding = ({encoding}) => { + if (ENCODINGS.has(encoding)) { + return; + } + + const correctEncoding = getCorrectEncoding(encoding); + if (correctEncoding !== undefined) { + throw new TypeError(`Invalid option \`encoding: ${serializeEncoding(encoding)}\`. +Please rename it to ${serializeEncoding(correctEncoding)}.`); + } + + const correctEncodings = [...ENCODINGS].map(correctEncoding => serializeEncoding(correctEncoding)).join(', '); + throw new TypeError(`Invalid option \`encoding: ${serializeEncoding(encoding)}\`. +Please rename it to one of: ${correctEncodings}.`); +}; + +const TEXT_ENCODINGS = new Set(['utf8', 'utf16le']); +const BINARY_ENCODINGS = new Set(['buffer', 'hex', 'base64', 'base64url', 'latin1', 'ascii']); +const ENCODINGS = new Set([...TEXT_ENCODINGS, ...BINARY_ENCODINGS]); + +const getCorrectEncoding = encoding => { + if (encoding === null) { + return 'buffer'; + } + + if (typeof encoding !== 'string') { + return; + } + + const lowerEncoding = encoding.toLowerCase(); + if (lowerEncoding in ENCODING_ALIASES) { + return ENCODING_ALIASES[lowerEncoding]; + } + + if (ENCODINGS.has(lowerEncoding)) { + return lowerEncoding; + } +}; + +const ENCODING_ALIASES = { + // eslint-disable-next-line unicorn/text-encoding-identifier-case + 'utf-8': 'utf8', + 'utf-16le': 'utf16le', + 'ucs-2': 'utf16le', + ucs2: 'utf16le', + binary: 'latin1', +}; + +const serializeEncoding = encoding => typeof encoding === 'string' ? `"${encoding}"` : String(encoding); + +// Normalize `cwd` option +const normalizeCwd = (cwd = getDefaultCwd()) => { + const cwdString = safeNormalizeFileUrl(cwd, 'The "cwd" option'); + return path.resolve(cwdString); +}; + +const getDefaultCwd = () => { + try { + return process$2.cwd(); + } catch (error) { + error.message = `The current directory does not exist.\n${error.message}`; + throw error; + } +}; + +// When `cwd` option has an invalid value, provide with a better error message +const fixCwdError = (originalMessage, cwd) => { + if (cwd === getDefaultCwd()) { + return originalMessage; + } + + let cwdStat; + try { + cwdStat = statSync(cwd); + } catch (error) { + return `The "cwd" option is invalid: ${cwd}.\n${error.message}\n${originalMessage}`; + } + + if (!cwdStat.isDirectory()) { + return `The "cwd" option is not a directory: ${cwd}.\n${originalMessage}`; + } + + return originalMessage; +}; + +// Normalize the options object, and sometimes also the file paths and arguments. +// Applies default values, validate allowed options, normalize them. +const normalizeOptions = (filePath, rawArguments, rawOptions) => { + rawOptions.cwd = normalizeCwd(rawOptions.cwd); + const [processedFile, processedArguments, processedOptions] = handleNodeOption(filePath, rawArguments, rawOptions); + + const {command: file, args: commandArguments, options: initialOptions} = crossSpawn._parse(processedFile, processedArguments, processedOptions); + + const fdOptions = normalizeFdSpecificOptions(initialOptions); + const options = addDefaultOptions(fdOptions); + validateTimeout(options); + validateEncoding(options); + validateIpcInputOption(options); + validateCancelSignal(options); + validateGracefulCancel(options); + options.shell = normalizeFileUrl(options.shell); + options.env = getEnv(options); + options.killSignal = normalizeKillSignal(options.killSignal); + options.forceKillAfterDelay = normalizeForceKillAfterDelay(options.forceKillAfterDelay); + options.lines = options.lines.map((lines, fdNumber) => lines && !BINARY_ENCODINGS.has(options.encoding) && options.buffer[fdNumber]); + + if (process$2.platform === 'win32' && path.basename(file, '.exe') === 'cmd') { + // #116 + commandArguments.unshift('/q'); + } + + return {file, commandArguments, options}; +}; + +const addDefaultOptions = ({ + extendEnv = true, + preferLocal = false, + cwd, + localDir: localDirectory = cwd, + encoding = 'utf8', + reject = true, + cleanup = true, + all = false, + windowsHide = true, + killSignal = 'SIGTERM', + forceKillAfterDelay = true, + gracefulCancel = false, + ipcInput, + ipc = ipcInput !== undefined || gracefulCancel, + serialization = 'advanced', + ...options +}) => ({ + ...options, + extendEnv, + preferLocal, + cwd, + localDirectory, + encoding, + reject, + cleanup, + all, + windowsHide, + killSignal, + forceKillAfterDelay, + gracefulCancel, + ipcInput, + ipc, + serialization, +}); + +const getEnv = ({env: envOption, extendEnv, preferLocal, node, localDirectory, nodePath}) => { + const env = extendEnv ? {...process$2.env, ...envOption} : envOption; + + if (preferLocal || node) { + return npmRunPathEnv({ + env, + cwd: localDirectory, + execPath: nodePath, + preferLocal, + addExecPath: node, + }); + } + + return env; +}; + +// When the `shell` option is set, any command argument is concatenated as a single string by Node.js: +// https://github.com/nodejs/node/blob/e38ce27f3ca0a65f68a31cedd984cddb927d4002/lib/child_process.js#L614-L624 +// However, since Node 24, it also prints a deprecation warning. +// To avoid this warning, we perform that same operation before calling `node:child_process`. +// Shells only understand strings, which is why Node.js performs that concatenation. +// However, we rely on users splitting command arguments as an array. +// For example, this allows us to easily detect which arguments are passed. +// So we do want users to pass array of arguments even with `shell: true`, but we also want to avoid any warning. +const concatenateShell = (file, commandArguments, options) => options.shell && commandArguments.length > 0 + ? [[file, ...commandArguments].join(' '), [], options] + : [file, commandArguments, options]; + +function stripFinalNewline(input) { + if (typeof input === 'string') { + return stripFinalNewlineString(input); + } + + if (!(ArrayBuffer.isView(input) && input.BYTES_PER_ELEMENT === 1)) { + throw new Error('Input must be a string or a Uint8Array'); + } + + return stripFinalNewlineBinary(input); +} + +const stripFinalNewlineString = input => + input.at(-1) === LF + ? input.slice(0, input.at(-2) === CR ? -2 : -1) + : input; + +const stripFinalNewlineBinary = input => + input.at(-1) === LF_BINARY + ? input.subarray(0, input.at(-2) === CR_BINARY ? -2 : -1) + : input; + +const LF = '\n'; +const LF_BINARY = LF.codePointAt(0); +const CR = '\r'; +const CR_BINARY = CR.codePointAt(0); + +function isStream(stream, {checkOpen = true} = {}) { + return stream !== null + && typeof stream === 'object' + && (stream.writable || stream.readable || !checkOpen || (stream.writable === undefined && stream.readable === undefined)) + && typeof stream.pipe === 'function'; +} + +function isWritableStream$1(stream, {checkOpen = true} = {}) { + return isStream(stream, {checkOpen}) + && (stream.writable || !checkOpen) + && typeof stream.write === 'function' + && typeof stream.end === 'function' + && typeof stream.writable === 'boolean' + && typeof stream.writableObjectMode === 'boolean' + && typeof stream.destroy === 'function' + && typeof stream.destroyed === 'boolean'; +} + +function isReadableStream$1(stream, {checkOpen = true} = {}) { + return isStream(stream, {checkOpen}) + && (stream.readable || !checkOpen) + && typeof stream.read === 'function' + && typeof stream.readable === 'boolean' + && typeof stream.readableObjectMode === 'boolean' + && typeof stream.destroy === 'function' + && typeof stream.destroyed === 'boolean'; +} + +function isDuplexStream(stream, options) { + return isWritableStream$1(stream, options) + && isReadableStream$1(stream, options); +} + +const a = Object.getPrototypeOf( + Object.getPrototypeOf( + /* istanbul ignore next */ + async function* () { + } + ).prototype +); +class c { + #t; + #n; + #r = false; + #e = void 0; + constructor(e, t) { + this.#t = e, this.#n = t; + } + next() { + const e = () => this.#s(); + return this.#e = this.#e ? this.#e.then(e, e) : e(), this.#e; + } + return(e) { + const t = () => this.#i(e); + return this.#e ? this.#e.then(t, t) : t(); + } + async #s() { + if (this.#r) + return { + done: true, + value: void 0 + }; + let e; + try { + e = await this.#t.read(); + } catch (t) { + throw this.#e = void 0, this.#r = true, this.#t.releaseLock(), t; + } + return e.done && (this.#e = void 0, this.#r = true, this.#t.releaseLock()), e; + } + async #i(e) { + if (this.#r) + return { + done: true, + value: e + }; + if (this.#r = true, !this.#n) { + const t = this.#t.cancel(e); + return this.#t.releaseLock(), await t, { + done: true, + value: e + }; + } + return this.#t.releaseLock(), { + done: true, + value: e + }; + } +} +const n = Symbol(); +function i() { + return this[n].next(); +} +Object.defineProperty(i, "name", { value: "next" }); +function o(r) { + return this[n].return(r); +} +Object.defineProperty(o, "name", { value: "return" }); +const u = Object.create(a, { + next: { + enumerable: true, + configurable: true, + writable: true, + value: i + }, + return: { + enumerable: true, + configurable: true, + writable: true, + value: o + } +}); +function h({ preventCancel: r = false } = {}) { + const e = this.getReader(), t = new c( + e, + r + ), s = Object.create(u); + return s[n] = t, s; +} + +const getAsyncIterable = stream => { + if (isReadableStream$1(stream, {checkOpen: false}) && nodeImports.on !== undefined) { + return getStreamIterable(stream); + } + + if (typeof stream?.[Symbol.asyncIterator] === 'function') { + return stream; + } + + // `ReadableStream[Symbol.asyncIterator]` support is missing in multiple browsers, so we ponyfill it + if (toString.call(stream) === '[object ReadableStream]') { + return h.call(stream); + } + + throw new TypeError('The first argument must be a Readable, a ReadableStream, or an async iterable.'); +}; + +const {toString} = Object.prototype; + +// The default iterable for Node.js streams does not allow for multiple readers at once, so we re-implement it +const getStreamIterable = async function * (stream) { + const controller = new AbortController(); + const state = {}; + handleStreamEnd(stream, controller, state); + + try { + for await (const [chunk] of nodeImports.on(stream, 'data', {signal: controller.signal})) { + yield chunk; + } + } catch (error) { + // Stream failure, for example due to `stream.destroy(error)` + if (state.error !== undefined) { + throw state.error; + // `error` event directly emitted on stream + } else if (!controller.signal.aborted) { + throw error; + // Otherwise, stream completed successfully + } + // The `finally` block also runs when the caller throws, for example due to the `maxBuffer` option + } finally { + stream.destroy(); + } +}; + +const handleStreamEnd = async (stream, controller, state) => { + try { + await nodeImports.finished(stream, { + cleanup: true, + readable: true, + writable: false, + error: false, + }); + } catch (error) { + state.error = error; + } finally { + controller.abort(); + } +}; + +// Loaded by the Node entrypoint, but not by the browser one. +// This prevents using dynamic imports. +const nodeImports = {}; + +const getStreamContents$1 = async (stream, {init, convertChunk, getSize, truncateChunk, addChunk, getFinalChunk, finalize}, {maxBuffer = Number.POSITIVE_INFINITY} = {}) => { + const asyncIterable = getAsyncIterable(stream); + + const state = init(); + state.length = 0; + + try { + for await (const chunk of asyncIterable) { + const chunkType = getChunkType(chunk); + const convertedChunk = convertChunk[chunkType](chunk, state); + appendChunk({ + convertedChunk, + state, + getSize, + truncateChunk, + addChunk, + maxBuffer, + }); + } + + appendFinalChunk({ + state, + convertChunk, + getSize, + truncateChunk, + addChunk, + getFinalChunk, + maxBuffer, + }); + return finalize(state); + } catch (error) { + const normalizedError = typeof error === 'object' && error !== null ? error : new Error(error); + normalizedError.bufferedData = finalize(state); + throw normalizedError; + } +}; + +const appendFinalChunk = ({state, getSize, truncateChunk, addChunk, getFinalChunk, maxBuffer}) => { + const convertedChunk = getFinalChunk(state); + if (convertedChunk !== undefined) { + appendChunk({ + convertedChunk, + state, + getSize, + truncateChunk, + addChunk, + maxBuffer, + }); + } +}; + +const appendChunk = ({convertedChunk, state, getSize, truncateChunk, addChunk, maxBuffer}) => { + const chunkSize = getSize(convertedChunk); + const newLength = state.length + chunkSize; + + if (newLength <= maxBuffer) { + addNewChunk(convertedChunk, state, addChunk, newLength); + return; + } + + const truncatedChunk = truncateChunk(convertedChunk, maxBuffer - state.length); + + if (truncatedChunk !== undefined) { + addNewChunk(truncatedChunk, state, addChunk, maxBuffer); + } + + throw new MaxBufferError(); +}; + +const addNewChunk = (convertedChunk, state, addChunk, newLength) => { + state.contents = addChunk(convertedChunk, state, newLength); + state.length = newLength; +}; + +const getChunkType = chunk => { + const typeOfChunk = typeof chunk; + + if (typeOfChunk === 'string') { + return 'string'; + } + + if (typeOfChunk !== 'object' || chunk === null) { + return 'others'; + } + + if (globalThis.Buffer?.isBuffer(chunk)) { + return 'buffer'; + } + + const prototypeName = objectToString.call(chunk); + + if (prototypeName === '[object ArrayBuffer]') { + return 'arrayBuffer'; + } + + if (prototypeName === '[object DataView]') { + return 'dataView'; + } + + if ( + Number.isInteger(chunk.byteLength) + && Number.isInteger(chunk.byteOffset) + && objectToString.call(chunk.buffer) === '[object ArrayBuffer]' + ) { + return 'typedArray'; + } + + return 'others'; +}; + +const {toString: objectToString} = Object.prototype; + +class MaxBufferError extends Error { + name = 'MaxBufferError'; + + constructor() { + super('maxBuffer exceeded'); + } +} + +const identity = value => value; + +const noop$1 = () => undefined; + +const getContentsProperty = ({contents}) => contents; + +const throwObjectStream = chunk => { + throw new Error(`Streams in object mode are not supported: ${String(chunk)}`); +}; + +const getLengthProperty = convertedChunk => convertedChunk.length; + +async function getStreamAsArray(stream, options) { + return getStreamContents$1(stream, arrayMethods, options); +} + +const initArray = () => ({contents: []}); + +const increment = () => 1; + +const addArrayChunk = (convertedChunk, {contents}) => { + contents.push(convertedChunk); + return contents; +}; + +const arrayMethods = { + init: initArray, + convertChunk: { + string: identity, + buffer: identity, + arrayBuffer: identity, + dataView: identity, + typedArray: identity, + others: identity, + }, + getSize: increment, + truncateChunk: noop$1, + addChunk: addArrayChunk, + getFinalChunk: noop$1, + finalize: getContentsProperty, +}; + +async function getStreamAsArrayBuffer(stream, options) { + return getStreamContents$1(stream, arrayBufferMethods, options); +} + +const initArrayBuffer = () => ({contents: new ArrayBuffer(0)}); + +const useTextEncoder = chunk => textEncoder.encode(chunk); +const textEncoder = new TextEncoder(); + +const useUint8Array = chunk => new Uint8Array(chunk); + +const useUint8ArrayWithOffset = chunk => new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength); + +const truncateArrayBufferChunk = (convertedChunk, chunkSize) => convertedChunk.slice(0, chunkSize); + +// `contents` is an increasingly growing `Uint8Array`. +const addArrayBufferChunk = (convertedChunk, {contents, length: previousLength}, length) => { + const newContents = hasArrayBufferResize() ? resizeArrayBuffer(contents, length) : resizeArrayBufferSlow(contents, length); + new Uint8Array(newContents).set(convertedChunk, previousLength); + return newContents; +}; + +// Without `ArrayBuffer.resize()`, `contents` size is always a power of 2. +// This means its last bytes are zeroes (not stream data), which need to be +// trimmed at the end with `ArrayBuffer.slice()`. +const resizeArrayBufferSlow = (contents, length) => { + if (length <= contents.byteLength) { + return contents; + } + + const arrayBuffer = new ArrayBuffer(getNewContentsLength(length)); + new Uint8Array(arrayBuffer).set(new Uint8Array(contents), 0); + return arrayBuffer; +}; + +// With `ArrayBuffer.resize()`, `contents` size matches exactly the size of +// the stream data. It does not include extraneous zeroes to trim at the end. +// The underlying `ArrayBuffer` does allocate a number of bytes that is a power +// of 2, but those bytes are only visible after calling `ArrayBuffer.resize()`. +const resizeArrayBuffer = (contents, length) => { + if (length <= contents.maxByteLength) { + contents.resize(length); + return contents; + } + + const arrayBuffer = new ArrayBuffer(length, {maxByteLength: getNewContentsLength(length)}); + new Uint8Array(arrayBuffer).set(new Uint8Array(contents), 0); + return arrayBuffer; +}; + +// Retrieve the closest `length` that is both >= and a power of 2 +const getNewContentsLength = length => SCALE_FACTOR ** Math.ceil(Math.log(length) / Math.log(SCALE_FACTOR)); + +const SCALE_FACTOR = 2; + +const finalizeArrayBuffer = ({contents, length}) => hasArrayBufferResize() ? contents : contents.slice(0, length); + +// `ArrayBuffer.slice()` is slow. When `ArrayBuffer.resize()` is available +// (Node >=20.0.0, Safari >=16.4 and Chrome), we can use it instead. +// eslint-disable-next-line no-warning-comments +// TODO: remove after dropping support for Node 20. +// eslint-disable-next-line no-warning-comments +// TODO: use `ArrayBuffer.transferToFixedLength()` instead once it is available +const hasArrayBufferResize = () => 'resize' in ArrayBuffer.prototype; + +const arrayBufferMethods = { + init: initArrayBuffer, + convertChunk: { + string: useTextEncoder, + buffer: useUint8Array, + arrayBuffer: useUint8Array, + dataView: useUint8ArrayWithOffset, + typedArray: useUint8ArrayWithOffset, + others: throwObjectStream, + }, + getSize: getLengthProperty, + truncateChunk: truncateArrayBufferChunk, + addChunk: addArrayBufferChunk, + getFinalChunk: noop$1, + finalize: finalizeArrayBuffer, +}; + +async function getStreamAsString(stream, options) { + return getStreamContents$1(stream, stringMethods, options); +} + +const initString = () => ({contents: '', textDecoder: new TextDecoder()}); + +const useTextDecoder = (chunk, {textDecoder}) => textDecoder.decode(chunk, {stream: true}); + +const addStringChunk = (convertedChunk, {contents}) => contents + convertedChunk; + +const truncateStringChunk = (convertedChunk, chunkSize) => convertedChunk.slice(0, chunkSize); + +const getFinalStringChunk = ({textDecoder}) => { + const finalChunk = textDecoder.decode(); + return finalChunk === '' ? undefined : finalChunk; +}; + +const stringMethods = { + init: initString, + convertChunk: { + string: identity, + buffer: useTextDecoder, + arrayBuffer: useTextDecoder, + dataView: useTextDecoder, + typedArray: useTextDecoder, + others: throwObjectStream, + }, + getSize: getLengthProperty, + truncateChunk: truncateStringChunk, + addChunk: addStringChunk, + getFinalChunk: getFinalStringChunk, + finalize: getContentsProperty, +}; + +// When the `maxBuffer` option is hit, a MaxBufferError is thrown. +// The stream is aborted, then specific information is kept for the error message. +const handleMaxBuffer = ({error, stream, readableObjectMode, lines, encoding, fdNumber}) => { + if (!(error instanceof MaxBufferError)) { + throw error; + } + + if (fdNumber === 'all') { + return error; + } + + const unit = getMaxBufferUnit(readableObjectMode, lines, encoding); + error.maxBufferInfo = {fdNumber, unit}; + stream.destroy(); + throw error; +}; + +const getMaxBufferUnit = (readableObjectMode, lines, encoding) => { + if (readableObjectMode) { + return 'objects'; + } + + if (lines) { + return 'lines'; + } + + if (encoding === 'buffer') { + return 'bytes'; + } + + return 'characters'; +}; + +// Check the `maxBuffer` option with `result.ipcOutput` +const checkIpcMaxBuffer = (subprocess, ipcOutput, maxBuffer) => { + if (ipcOutput.length !== maxBuffer) { + return; + } + + const error = new MaxBufferError(); + error.maxBufferInfo = {fdNumber: 'ipc'}; + throw error; +}; + +// Error message when `maxBuffer` is hit +const getMaxBufferMessage = (error, maxBuffer) => { + const {streamName, threshold, unit} = getMaxBufferInfo(error, maxBuffer); + return `Command's ${streamName} was larger than ${threshold} ${unit}`; +}; + +const getMaxBufferInfo = (error, maxBuffer) => { + if (error?.maxBufferInfo === undefined) { + return {streamName: 'output', threshold: maxBuffer[1], unit: 'bytes'}; + } + + const {maxBufferInfo: {fdNumber, unit}} = error; + delete error.maxBufferInfo; + + const threshold = getFdSpecificValue(maxBuffer, fdNumber); + if (fdNumber === 'ipc') { + return {streamName: 'IPC output', threshold, unit: 'messages'}; + } + + return {streamName: getStreamName(fdNumber), threshold, unit}; +}; + +// The only way to apply `maxBuffer` with `spawnSync()` is to use the native `maxBuffer` option Node.js provides. +// However, this has multiple limitations, and cannot behave the exact same way as the async behavior. +// When the `maxBuffer` is hit, a `ENOBUFS` error is thrown. +const isMaxBufferSync = (resultError, output, maxBuffer) => resultError?.code === 'ENOBUFS' + && output !== null + && output.some(result => result !== null && result.length > getMaxBufferSync(maxBuffer)); + +// When `maxBuffer` is hit, ensure the result is truncated +const truncateMaxBufferSync = (result, isMaxBuffer, maxBuffer) => { + if (!isMaxBuffer) { + return result; + } + + const maxBufferValue = getMaxBufferSync(maxBuffer); + return result.length > maxBufferValue ? result.slice(0, maxBufferValue) : result; +}; + +// `spawnSync()` does not allow differentiating `maxBuffer` per file descriptor, so we always use `stdout` +const getMaxBufferSync = ([, stdoutMaxBuffer]) => stdoutMaxBuffer; + +// Computes `error.message`, `error.shortMessage` and `error.originalMessage` +const createMessages = ({ + stdio, + all, + ipcOutput, + originalError, + signal, + signalDescription, + exitCode, + escapedCommand, + timedOut, + isCanceled, + isGracefullyCanceled, + isMaxBuffer, + isForcefullyTerminated, + forceKillAfterDelay, + killSignal, + maxBuffer, + timeout, + cwd, +}) => { + const errorCode = originalError?.code; + const prefix = getErrorPrefix({ + originalError, + timedOut, + timeout, + isMaxBuffer, + maxBuffer, + errorCode, + signal, + signalDescription, + exitCode, + isCanceled, + isGracefullyCanceled, + isForcefullyTerminated, + forceKillAfterDelay, + killSignal, + }); + const originalMessage = getOriginalMessage(originalError, cwd); + const suffix = originalMessage === undefined ? '' : `\n${originalMessage}`; + const shortMessage = `${prefix}: ${escapedCommand}${suffix}`; + const messageStdio = all === undefined ? [stdio[2], stdio[1]] : [all]; + const message = [ + shortMessage, + ...messageStdio, + ...stdio.slice(3), + ipcOutput.map(ipcMessage => serializeIpcMessage(ipcMessage)).join('\n'), + ] + .map(messagePart => escapeLines(stripFinalNewline(serializeMessagePart(messagePart)))) + .filter(Boolean) + .join('\n\n'); + return {originalMessage, shortMessage, message}; +}; + +const getErrorPrefix = ({ + originalError, + timedOut, + timeout, + isMaxBuffer, + maxBuffer, + errorCode, + signal, + signalDescription, + exitCode, + isCanceled, + isGracefullyCanceled, + isForcefullyTerminated, + forceKillAfterDelay, + killSignal, +}) => { + const forcefulSuffix = getForcefulSuffix(isForcefullyTerminated, forceKillAfterDelay); + + if (timedOut) { + return `Command timed out after ${timeout} milliseconds${forcefulSuffix}`; + } + + if (isGracefullyCanceled) { + if (signal === undefined) { + return `Command was gracefully canceled with exit code ${exitCode}`; + } + + return isForcefullyTerminated + ? `Command was gracefully canceled${forcefulSuffix}` + : `Command was gracefully canceled with ${signal} (${signalDescription})`; + } + + if (isCanceled) { + return `Command was canceled${forcefulSuffix}`; + } + + if (isMaxBuffer) { + return `${getMaxBufferMessage(originalError, maxBuffer)}${forcefulSuffix}`; + } + + if (errorCode !== undefined) { + return `Command failed with ${errorCode}${forcefulSuffix}`; + } + + if (isForcefullyTerminated) { + return `Command was killed with ${killSignal} (${getSignalDescription(killSignal)})${forcefulSuffix}`; + } + + if (signal !== undefined) { + return `Command was killed with ${signal} (${signalDescription})`; + } + + if (exitCode !== undefined) { + return `Command failed with exit code ${exitCode}`; + } + + return 'Command failed'; +}; + +const getForcefulSuffix = (isForcefullyTerminated, forceKillAfterDelay) => isForcefullyTerminated + ? ` and was forcefully terminated after ${forceKillAfterDelay} milliseconds` + : ''; + +const getOriginalMessage = (originalError, cwd) => { + if (originalError instanceof DiscardedError) { + return; + } + + const originalMessage = isExecaError(originalError) + ? originalError.originalMessage + : String(originalError?.message ?? originalError); + const escapedOriginalMessage = escapeLines(fixCwdError(originalMessage, cwd)); + return escapedOriginalMessage === '' ? undefined : escapedOriginalMessage; +}; + +const serializeIpcMessage = ipcMessage => typeof ipcMessage === 'string' + ? ipcMessage + : inspect(ipcMessage); + +const serializeMessagePart = messagePart => Array.isArray(messagePart) + ? messagePart.map(messageItem => stripFinalNewline(serializeMessageItem(messageItem))).filter(Boolean).join('\n') + : serializeMessageItem(messagePart); + +const serializeMessageItem = messageItem => { + if (typeof messageItem === 'string') { + return messageItem; + } + + if (isUint8Array(messageItem)) { + return uint8ArrayToString(messageItem); + } + + return ''; +}; + +// Object returned on subprocess success +const makeSuccessResult = ({ + command, + escapedCommand, + stdio, + all, + ipcOutput, + options: {cwd}, + startTime, +}) => omitUndefinedProperties({ + command, + escapedCommand, + cwd, + durationMs: getDurationMs(startTime), + failed: false, + timedOut: false, + isCanceled: false, + isGracefullyCanceled: false, + isTerminated: false, + isMaxBuffer: false, + isForcefullyTerminated: false, + exitCode: 0, + stdout: stdio[1], + stderr: stdio[2], + all, + stdio, + ipcOutput, + pipedFrom: [], +}); + +// Object returned on subprocess failure before spawning +const makeEarlyError = ({ + error, + command, + escapedCommand, + fileDescriptors, + options, + startTime, + isSync, +}) => makeError({ + error, + command, + escapedCommand, + startTime, + timedOut: false, + isCanceled: false, + isGracefullyCanceled: false, + isMaxBuffer: false, + isForcefullyTerminated: false, + stdio: Array.from({length: fileDescriptors.length}), + ipcOutput: [], + options, + isSync, +}); + +// Object returned on subprocess failure +const makeError = ({ + error: originalError, + command, + escapedCommand, + startTime, + timedOut, + isCanceled, + isGracefullyCanceled, + isMaxBuffer, + isForcefullyTerminated, + exitCode: rawExitCode, + signal: rawSignal, + stdio, + all, + ipcOutput, + options: { + timeoutDuration, + timeout = timeoutDuration, + forceKillAfterDelay, + killSignal, + cwd, + maxBuffer, + }, + isSync, +}) => { + const {exitCode, signal, signalDescription} = normalizeExitPayload(rawExitCode, rawSignal); + const {originalMessage, shortMessage, message} = createMessages({ + stdio, + all, + ipcOutput, + originalError, + signal, + signalDescription, + exitCode, + escapedCommand, + timedOut, + isCanceled, + isGracefullyCanceled, + isMaxBuffer, + isForcefullyTerminated, + forceKillAfterDelay, + killSignal, + maxBuffer, + timeout, + cwd, + }); + const error = getFinalError(originalError, message, isSync); + Object.assign(error, getErrorProperties({ + error, + command, + escapedCommand, + startTime, + timedOut, + isCanceled, + isGracefullyCanceled, + isMaxBuffer, + isForcefullyTerminated, + exitCode, + signal, + signalDescription, + stdio, + all, + ipcOutput, + cwd, + originalMessage, + shortMessage, + })); + return error; +}; + +const getErrorProperties = ({ + error, + command, + escapedCommand, + startTime, + timedOut, + isCanceled, + isGracefullyCanceled, + isMaxBuffer, + isForcefullyTerminated, + exitCode, + signal, + signalDescription, + stdio, + all, + ipcOutput, + cwd, + originalMessage, + shortMessage, +}) => omitUndefinedProperties({ + shortMessage, + originalMessage, + command, + escapedCommand, + cwd, + durationMs: getDurationMs(startTime), + failed: true, + timedOut, + isCanceled, + isGracefullyCanceled, + isTerminated: signal !== undefined, + isMaxBuffer, + isForcefullyTerminated, + exitCode, + signal, + signalDescription, + code: error.cause?.code, + stdout: stdio[1], + stderr: stdio[2], + all, + stdio, + ipcOutput, + pipedFrom: [], +}); + +const omitUndefinedProperties = result => Object.fromEntries(Object.entries(result).filter(([, value]) => value !== undefined)); + +// `signal` and `exitCode` emitted on `subprocess.on('exit')` event can be `null`. +// We normalize them to `undefined` +const normalizeExitPayload = (rawExitCode, rawSignal) => { + const exitCode = rawExitCode === null ? undefined : rawExitCode; + const signal = rawSignal === null ? undefined : rawSignal; + const signalDescription = signal === undefined ? undefined : getSignalDescription(rawSignal); + return {exitCode, signal, signalDescription}; +}; + +const toZeroIfInfinity = value => Number.isFinite(value) ? value : 0; + +function parseNumber(milliseconds) { + return { + days: Math.trunc(milliseconds / 86_400_000), + hours: Math.trunc(milliseconds / 3_600_000 % 24), + minutes: Math.trunc(milliseconds / 60_000 % 60), + seconds: Math.trunc(milliseconds / 1000 % 60), + milliseconds: Math.trunc(milliseconds % 1000), + microseconds: Math.trunc(toZeroIfInfinity(milliseconds * 1000) % 1000), + nanoseconds: Math.trunc(toZeroIfInfinity(milliseconds * 1e6) % 1000), + }; +} + +function parseBigint(milliseconds) { + return { + days: milliseconds / 86_400_000n, + hours: milliseconds / 3_600_000n % 24n, + minutes: milliseconds / 60_000n % 60n, + seconds: milliseconds / 1000n % 60n, + milliseconds: milliseconds % 1000n, + microseconds: 0n, + nanoseconds: 0n, + }; +} + +function parseMilliseconds(milliseconds) { + switch (typeof milliseconds) { + case 'number': { + if (Number.isFinite(milliseconds)) { + return parseNumber(milliseconds); + } + + break; + } + + case 'bigint': { + return parseBigint(milliseconds); + } + + // No default + } + + throw new TypeError('Expected a finite number or bigint'); +} + +const isZero = value => value === 0 || value === 0n; +const pluralize = (word, count) => (count === 1 || count === 1n) ? word : `${word}s`; + +const SECOND_ROUNDING_EPSILON = 0.000_000_1; +const ONE_DAY_IN_MILLISECONDS = 24n * 60n * 60n * 1000n; + +function prettyMilliseconds(milliseconds, options) { + const isBigInt = typeof milliseconds === 'bigint'; + if (!isBigInt && !Number.isFinite(milliseconds)) { + throw new TypeError('Expected a finite number or bigint'); + } + + options = {...options}; + + const sign = milliseconds < 0 ? '-' : ''; + milliseconds = milliseconds < 0 ? -milliseconds : milliseconds; // Cannot use `Math.abs()` because of BigInt support. + + if (options.colonNotation) { + options.compact = false; + options.formatSubMilliseconds = false; + options.separateMilliseconds = false; + options.verbose = false; + } + + if (options.compact) { + options.unitCount = 1; + options.secondsDecimalDigits = 0; + options.millisecondsDecimalDigits = 0; + } + + let result = []; + + const floorDecimals = (value, decimalDigits) => { + const flooredInterimValue = Math.floor((value * (10 ** decimalDigits)) + SECOND_ROUNDING_EPSILON); + const flooredValue = Math.round(flooredInterimValue) / (10 ** decimalDigits); + return flooredValue.toFixed(decimalDigits); + }; + + const add = (value, long, short, valueString) => { + if ( + (result.length === 0 || !options.colonNotation) + && isZero(value) + && !(options.colonNotation && short === 'm')) { + return; + } + + valueString ??= String(value); + if (options.colonNotation) { + const wholeDigits = valueString.includes('.') ? valueString.split('.')[0].length : valueString.length; + const minLength = result.length > 0 ? 2 : 1; + valueString = '0'.repeat(Math.max(0, minLength - wholeDigits)) + valueString; + } else { + valueString += options.verbose ? ' ' + pluralize(long, value) : short; + } + + result.push(valueString); + }; + + const parsed = parseMilliseconds(milliseconds); + const days = BigInt(parsed.days); + + if (options.hideYearAndDays) { + add((BigInt(days) * 24n) + BigInt(parsed.hours), 'hour', 'h'); + } else { + if (options.hideYear) { + add(days, 'day', 'd'); + } else { + add(days / 365n, 'year', 'y'); + add(days % 365n, 'day', 'd'); + } + + add(Number(parsed.hours), 'hour', 'h'); + } + + add(Number(parsed.minutes), 'minute', 'm'); + + if (!options.hideSeconds) { + if ( + options.separateMilliseconds + || options.formatSubMilliseconds + || (!options.colonNotation && milliseconds < 1000 && !options.subSecondsAsDecimals) + ) { + const seconds = Number(parsed.seconds); + const milliseconds = Number(parsed.milliseconds); + const microseconds = Number(parsed.microseconds); + const nanoseconds = Number(parsed.nanoseconds); + + add(seconds, 'second', 's'); + + if (options.formatSubMilliseconds) { + add(milliseconds, 'millisecond', 'ms'); + add(microseconds, 'microsecond', 'µs'); + add(nanoseconds, 'nanosecond', 'ns'); + } else { + const millisecondsAndBelow + = milliseconds + + (microseconds / 1000) + + (nanoseconds / 1e6); + + const millisecondsDecimalDigits + = typeof options.millisecondsDecimalDigits === 'number' + ? options.millisecondsDecimalDigits + : 0; + + const roundedMilliseconds = millisecondsAndBelow >= 1 + ? Math.round(millisecondsAndBelow) + : Math.ceil(millisecondsAndBelow); + + const millisecondsString = millisecondsDecimalDigits + ? millisecondsAndBelow.toFixed(millisecondsDecimalDigits) + : roundedMilliseconds; + + add( + Number.parseFloat(millisecondsString), + 'millisecond', + 'ms', + millisecondsString, + ); + } + } else { + const seconds = ( + (isBigInt ? Number(milliseconds % ONE_DAY_IN_MILLISECONDS) : milliseconds) + / 1000 + ) % 60; + const secondsDecimalDigits + = typeof options.secondsDecimalDigits === 'number' + ? options.secondsDecimalDigits + : 1; + const secondsFixed = floorDecimals(seconds, secondsDecimalDigits); + const secondsString = options.keepDecimalsOnWholeSeconds + ? secondsFixed + : secondsFixed.replace(/\.0+$/, ''); + add(Number.parseFloat(secondsString), 'second', 's', secondsString); + } + } + + if (result.length === 0) { + return sign + '0' + (options.verbose ? ' milliseconds' : 'ms'); + } + + const separator = options.colonNotation ? ':' : ' '; + if (typeof options.unitCount === 'number') { + result = result.slice(0, Math.max(options.unitCount, 1)); + } + + return sign + result.join(separator); +} + +// When `verbose` is `short|full|custom`, print each command's error when it fails +const logError = (result, verboseInfo) => { + if (result.failed) { + verboseLog({ + type: 'error', + verboseMessage: result.shortMessage, + verboseInfo, + result, + }); + } +}; + +// When `verbose` is `short|full|custom`, print each command's completion, duration and error +const logResult = (result, verboseInfo) => { + if (!isVerbose(verboseInfo)) { + return; + } + + logError(result, verboseInfo); + logDuration(result, verboseInfo); +}; + +const logDuration = (result, verboseInfo) => { + const verboseMessage = `(done in ${prettyMilliseconds(result.durationMs)})`; + verboseLog({ + type: 'duration', + verboseMessage, + verboseInfo, + result, + }); +}; + +// Applies the `reject` option. +// Also print the final log line with `verbose`. +const handleResult = (result, verboseInfo, {reject}) => { + logResult(result, verboseInfo); + + if (result.failed && reject) { + throw result; + } + + return result; +}; + +// The `stdin`/`stdout`/`stderr` option can be of many types. This detects it. +const getStdioItemType = (value, optionName) => { + if (isAsyncGenerator(value)) { + return 'asyncGenerator'; + } + + if (isSyncGenerator(value)) { + return 'generator'; + } + + if (isUrl(value)) { + return 'fileUrl'; + } + + if (isFilePathObject(value)) { + return 'filePath'; + } + + if (isWebStream(value)) { + return 'webStream'; + } + + if (isStream(value, {checkOpen: false})) { + return 'native'; + } + + if (isUint8Array(value)) { + return 'uint8Array'; + } + + if (isAsyncIterableObject(value)) { + return 'asyncIterable'; + } + + if (isIterableObject(value)) { + return 'iterable'; + } + + if (isTransformStream(value)) { + return getTransformStreamType({}, optionName); + } + + if (isTransformOptions(value)) { + return getTransformObjectType(value, optionName); + } + + return 'native'; +}; + +const getTransformObjectType = (value, optionName) => { + if (isDuplexStream(value.transform, {checkOpen: false})) { + return getDuplexType(value, optionName); + } + + if (isTransformStream(value.transform)) { + return getTransformStreamType(value, optionName); + } + + return getGeneratorObjectType(value, optionName); +}; + +const getDuplexType = (value, optionName) => { + validateNonGeneratorType(value, optionName, 'Duplex stream'); + return 'duplex'; +}; + +const getTransformStreamType = (value, optionName) => { + validateNonGeneratorType(value, optionName, 'web TransformStream'); + return 'webTransform'; +}; + +const validateNonGeneratorType = ({final, binary, objectMode}, optionName, typeName) => { + checkUndefinedOption(final, `${optionName}.final`, typeName); + checkUndefinedOption(binary, `${optionName}.binary`, typeName); + checkBooleanOption(objectMode, `${optionName}.objectMode`); +}; + +const checkUndefinedOption = (value, optionName, typeName) => { + if (value !== undefined) { + throw new TypeError(`The \`${optionName}\` option can only be defined when using a generator, not a ${typeName}.`); + } +}; + +const getGeneratorObjectType = ({transform, final, binary, objectMode}, optionName) => { + if (transform !== undefined && !isGenerator(transform)) { + throw new TypeError(`The \`${optionName}.transform\` option must be a generator, a Duplex stream or a web TransformStream.`); + } + + if (isDuplexStream(final, {checkOpen: false})) { + throw new TypeError(`The \`${optionName}.final\` option must not be a Duplex stream.`); + } + + if (isTransformStream(final)) { + throw new TypeError(`The \`${optionName}.final\` option must not be a web TransformStream.`); + } + + if (final !== undefined && !isGenerator(final)) { + throw new TypeError(`The \`${optionName}.final\` option must be a generator.`); + } + + checkBooleanOption(binary, `${optionName}.binary`); + checkBooleanOption(objectMode, `${optionName}.objectMode`); + + return isAsyncGenerator(transform) || isAsyncGenerator(final) ? 'asyncGenerator' : 'generator'; +}; + +const checkBooleanOption = (value, optionName) => { + if (value !== undefined && typeof value !== 'boolean') { + throw new TypeError(`The \`${optionName}\` option must use a boolean.`); + } +}; + +const isGenerator = value => isAsyncGenerator(value) || isSyncGenerator(value); +const isAsyncGenerator = value => Object.prototype.toString.call(value) === '[object AsyncGeneratorFunction]'; +const isSyncGenerator = value => Object.prototype.toString.call(value) === '[object GeneratorFunction]'; +const isTransformOptions = value => isPlainObject(value) + && (value.transform !== undefined || value.final !== undefined); + +const isUrl = value => Object.prototype.toString.call(value) === '[object URL]'; +const isRegularUrl = value => isUrl(value) && value.protocol !== 'file:'; + +const isFilePathObject = value => isPlainObject(value) + && Object.keys(value).length > 0 + && Object.keys(value).every(key => FILE_PATH_KEYS.has(key)) + && isFilePathString(value.file); +const FILE_PATH_KEYS = new Set(['file', 'append']); +const isFilePathString = file => typeof file === 'string'; + +const isUnknownStdioString = (type, value) => type === 'native' + && typeof value === 'string' + && !KNOWN_STDIO_STRINGS.has(value); +const KNOWN_STDIO_STRINGS = new Set(['ipc', 'ignore', 'inherit', 'overlapped', 'pipe']); + +const isReadableStream = value => Object.prototype.toString.call(value) === '[object ReadableStream]'; +const isWritableStream = value => Object.prototype.toString.call(value) === '[object WritableStream]'; +const isWebStream = value => isReadableStream(value) || isWritableStream(value); +const isTransformStream = value => isReadableStream(value?.readable) && isWritableStream(value?.writable); + +const isAsyncIterableObject = value => isObject(value) && typeof value[Symbol.asyncIterator] === 'function'; +const isIterableObject = value => isObject(value) && typeof value[Symbol.iterator] === 'function'; +const isObject = value => typeof value === 'object' && value !== null; + +// Types which modify `subprocess.std*` +const TRANSFORM_TYPES = new Set(['generator', 'asyncGenerator', 'duplex', 'webTransform']); +// Types which write to a file or a file descriptor +const FILE_TYPES = new Set(['fileUrl', 'filePath', 'fileNumber']); +// When two file descriptors of this type share the same target, we need to do some special logic +const SPECIAL_DUPLICATE_TYPES_SYNC = new Set(['fileUrl', 'filePath']); +const SPECIAL_DUPLICATE_TYPES = new Set([...SPECIAL_DUPLICATE_TYPES_SYNC, 'webStream', 'nodeStream']); +// Do not allow two file descriptors of this type sharing the same target +const FORBID_DUPLICATE_TYPES = new Set(['webTransform', 'duplex']); + +// Convert types to human-friendly strings for error messages +const TYPE_TO_MESSAGE = { + generator: 'a generator', + asyncGenerator: 'an async generator', + fileUrl: 'a file URL', + filePath: 'a file path string', + fileNumber: 'a file descriptor number', + webStream: 'a web stream', + nodeStream: 'a Node.js stream', + webTransform: 'a web TransformStream', + duplex: 'a Duplex stream', + native: 'any value', + iterable: 'an iterable', + asyncIterable: 'an async iterable', + string: 'a string', + uint8Array: 'a Uint8Array', +}; + +/* +Retrieve the `objectMode`s of a single transform. +`objectMode` determines the return value's type, i.e. the `readableObjectMode`. +The chunk argument's type is based on the previous generator's return value, i.e. the `writableObjectMode` is based on the previous `readableObjectMode`. +The last input's generator is read by `subprocess.stdin` which: +- should not be in `objectMode` for performance reasons. +- can only be strings, Buffers and Uint8Arrays. +Therefore its `readableObjectMode` must be `false`. +The same applies to the first output's generator's `writableObjectMode`. +*/ +const getTransformObjectModes = (objectMode, index, newTransforms, direction) => direction === 'output' + ? getOutputObjectModes(objectMode, index, newTransforms) + : getInputObjectModes(objectMode, index, newTransforms); + +const getOutputObjectModes = (objectMode, index, newTransforms) => { + const writableObjectMode = index !== 0 && newTransforms[index - 1].value.readableObjectMode; + const readableObjectMode = objectMode ?? writableObjectMode; + return {writableObjectMode, readableObjectMode}; +}; + +const getInputObjectModes = (objectMode, index, newTransforms) => { + const writableObjectMode = index === 0 + ? objectMode === true + : newTransforms[index - 1].value.readableObjectMode; + const readableObjectMode = index !== newTransforms.length - 1 && (objectMode ?? writableObjectMode); + return {writableObjectMode, readableObjectMode}; +}; + +// Retrieve the `objectMode` of a file descriptor, e.g. `stdout` or `stderr` +const getFdObjectMode = (stdioItems, direction) => { + const lastTransform = stdioItems.findLast(({type}) => TRANSFORM_TYPES.has(type)); + if (lastTransform === undefined) { + return false; + } + + return direction === 'input' + ? lastTransform.value.writableObjectMode + : lastTransform.value.readableObjectMode; +}; + +// Transforms generators/duplex/TransformStream can have multiple shapes. +// This normalizes it and applies default values. +const normalizeTransforms = (stdioItems, optionName, direction, options) => [ + ...stdioItems.filter(({type}) => !TRANSFORM_TYPES.has(type)), + ...getTransforms(stdioItems, optionName, direction, options), +]; + +const getTransforms = (stdioItems, optionName, direction, {encoding}) => { + const transforms = stdioItems.filter(({type}) => TRANSFORM_TYPES.has(type)); + const newTransforms = Array.from({length: transforms.length}); + + for (const [index, stdioItem] of Object.entries(transforms)) { + newTransforms[index] = normalizeTransform({ + stdioItem, + index: Number(index), + newTransforms, + optionName, + direction, + encoding, + }); + } + + return sortTransforms(newTransforms, direction); +}; + +const normalizeTransform = ({stdioItem, stdioItem: {type}, index, newTransforms, optionName, direction, encoding}) => { + if (type === 'duplex') { + return normalizeDuplex({stdioItem, optionName}); + } + + if (type === 'webTransform') { + return normalizeTransformStream({ + stdioItem, + index, + newTransforms, + direction, + }); + } + + return normalizeGenerator({ + stdioItem, + index, + newTransforms, + direction, + encoding, + }); +}; + +const normalizeDuplex = ({ + stdioItem, + stdioItem: { + value: { + transform, + transform: {writableObjectMode, readableObjectMode}, + objectMode = readableObjectMode, + }, + }, + optionName, +}) => { + if (objectMode && !readableObjectMode) { + throw new TypeError(`The \`${optionName}.objectMode\` option can only be \`true\` if \`new Duplex({objectMode: true})\` is used.`); + } + + if (!objectMode && readableObjectMode) { + throw new TypeError(`The \`${optionName}.objectMode\` option cannot be \`false\` if \`new Duplex({objectMode: true})\` is used.`); + } + + return { + ...stdioItem, + value: {transform, writableObjectMode, readableObjectMode}, + }; +}; + +const normalizeTransformStream = ({stdioItem, stdioItem: {value}, index, newTransforms, direction}) => { + const {transform, objectMode} = isPlainObject(value) ? value : {transform: value}; + const {writableObjectMode, readableObjectMode} = getTransformObjectModes(objectMode, index, newTransforms, direction); + return ({ + ...stdioItem, + value: {transform, writableObjectMode, readableObjectMode}, + }); +}; + +const normalizeGenerator = ({stdioItem, stdioItem: {value}, index, newTransforms, direction, encoding}) => { + const { + transform, + final, + binary: binaryOption = false, + preserveNewlines = false, + objectMode, + } = isPlainObject(value) ? value : {transform: value}; + const binary = binaryOption || BINARY_ENCODINGS.has(encoding); + const {writableObjectMode, readableObjectMode} = getTransformObjectModes(objectMode, index, newTransforms, direction); + return { + ...stdioItem, + value: { + transform, + final, + binary, + preserveNewlines, + writableObjectMode, + readableObjectMode, + }, + }; +}; + +const sortTransforms = (newTransforms, direction) => direction === 'input' ? newTransforms.reverse() : newTransforms; + +// For `stdio[fdNumber]` beyond stdin/stdout/stderr, we need to guess whether the value passed is intended for inputs or outputs. +// This allows us to know whether to pipe _into_ or _from_ the stream. +// When `stdio[fdNumber]` is a single value, this guess is fairly straightforward. +// However, when it is an array instead, we also need to make sure the different values are not incompatible with each other. +const getStreamDirection = (stdioItems, fdNumber, optionName) => { + const directions = stdioItems.map(stdioItem => getStdioItemDirection(stdioItem, fdNumber)); + + if (directions.includes('input') && directions.includes('output')) { + throw new TypeError(`The \`${optionName}\` option must not be an array of both readable and writable values.`); + } + + return directions.find(Boolean) ?? DEFAULT_DIRECTION; +}; + +const getStdioItemDirection = ({type, value}, fdNumber) => KNOWN_DIRECTIONS[fdNumber] ?? guessStreamDirection[type](value); + +// `stdin`/`stdout`/`stderr` have a known direction +const KNOWN_DIRECTIONS = ['input', 'output', 'output']; + +const anyDirection = () => undefined; +const alwaysInput = () => 'input'; + +// `string` can only be added through the `input` option, i.e. does not need to be handled here +const guessStreamDirection = { + generator: anyDirection, + asyncGenerator: anyDirection, + fileUrl: anyDirection, + filePath: anyDirection, + iterable: alwaysInput, + asyncIterable: alwaysInput, + uint8Array: alwaysInput, + webStream: value => isWritableStream(value) ? 'output' : 'input', + nodeStream(value) { + if (!isReadableStream$1(value, {checkOpen: false})) { + return 'output'; + } + + return isWritableStream$1(value, {checkOpen: false}) ? undefined : 'input'; + }, + webTransform: anyDirection, + duplex: anyDirection, + native(value) { + const standardStreamDirection = getStandardStreamDirection(value); + if (standardStreamDirection !== undefined) { + return standardStreamDirection; + } + + if (isStream(value, {checkOpen: false})) { + return guessStreamDirection.nodeStream(value); + } + }, +}; + +const getStandardStreamDirection = value => { + if ([0, process$2.stdin].includes(value)) { + return 'input'; + } + + if ([1, 2, process$2.stdout, process$2.stderr].includes(value)) { + return 'output'; + } +}; + +// When ambiguous, we initially keep the direction as `undefined`. +// This allows arrays of `stdio` values to resolve the ambiguity. +// For example, `stdio[3]: DuplexStream` is ambiguous, but `stdio[3]: [DuplexStream, WritableStream]` is not. +// When the ambiguity remains, we default to `output` since it is the most common use case for additional file descriptors. +const DEFAULT_DIRECTION = 'output'; + +// The `ipc` option adds an `ipc` item to the `stdio` option +const normalizeIpcStdioArray = (stdioArray, ipc) => ipc && !stdioArray.includes('ipc') + ? [...stdioArray, 'ipc'] + : stdioArray; + +// Add support for `stdin`/`stdout`/`stderr` as an alias for `stdio`. +// Also normalize the `stdio` option. +const normalizeStdioOption = ({stdio, ipc, buffer, ...options}, verboseInfo, isSync) => { + const stdioArray = getStdioArray(stdio, options).map((stdioOption, fdNumber) => addDefaultValue(stdioOption, fdNumber)); + return isSync + ? normalizeStdioSync(stdioArray, buffer, verboseInfo) + : normalizeIpcStdioArray(stdioArray, ipc); +}; + +const getStdioArray = (stdio, options) => { + if (stdio === undefined) { + return STANDARD_STREAMS_ALIASES.map(alias => options[alias]); + } + + if (hasAlias(options)) { + throw new Error(`It's not possible to provide \`stdio\` in combination with one of ${STANDARD_STREAMS_ALIASES.map(alias => `\`${alias}\``).join(', ')}`); + } + + if (typeof stdio === 'string') { + return [stdio, stdio, stdio]; + } + + if (!Array.isArray(stdio)) { + throw new TypeError(`Expected \`stdio\` to be of type \`string\` or \`Array\`, got \`${typeof stdio}\``); + } + + const length = Math.max(stdio.length, STANDARD_STREAMS_ALIASES.length); + return Array.from({length}, (_, fdNumber) => stdio[fdNumber]); +}; + +const hasAlias = options => STANDARD_STREAMS_ALIASES.some(alias => options[alias] !== undefined); + +const addDefaultValue = (stdioOption, fdNumber) => { + if (Array.isArray(stdioOption)) { + return stdioOption.map(item => addDefaultValue(item, fdNumber)); + } + + if (stdioOption === null || stdioOption === undefined) { + return fdNumber >= STANDARD_STREAMS_ALIASES.length ? 'ignore' : 'pipe'; + } + + return stdioOption; +}; + +// Using `buffer: false` with synchronous methods implies `stdout`/`stderr`: `ignore`. +// Unless the output is needed, e.g. due to `verbose: 'full'` or to redirecting to a file. +const normalizeStdioSync = (stdioArray, buffer, verboseInfo) => stdioArray.map((stdioOption, fdNumber) => + !buffer[fdNumber] + && fdNumber !== 0 + && !isFullVerbose(verboseInfo, fdNumber) + && isOutputPipeOnly(stdioOption) + ? 'ignore' + : stdioOption); + +const isOutputPipeOnly = stdioOption => stdioOption === 'pipe' + || (Array.isArray(stdioOption) && stdioOption.every(item => item === 'pipe')); + +// When we use multiple `stdio` values for the same streams, we pass 'pipe' to `child_process.spawn()`. +// We then emulate the piping done by core Node.js. +// To do so, we transform the following values: +// - Node.js streams are marked as `type: nodeStream` +// - 'inherit' becomes `process.stdin|stdout|stderr` +// - any file descriptor integer becomes `process.stdio[fdNumber]` +// All of the above transformations tell Execa to perform manual piping. +const handleNativeStream = ({stdioItem, stdioItem: {type}, isStdioArray, fdNumber, direction, isSync}) => { + if (!isStdioArray || type !== 'native') { + return stdioItem; + } + + return isSync + ? handleNativeStreamSync({stdioItem, fdNumber, direction}) + : handleNativeStreamAsync({stdioItem, fdNumber}); +}; + +// Synchronous methods use a different logic. +// 'inherit', file descriptors and process.std* are handled by readFileSync()/writeFileSync(). +const handleNativeStreamSync = ({stdioItem, stdioItem: {value, optionName}, fdNumber, direction}) => { + const targetFd = getTargetFd({ + value, + optionName, + fdNumber, + direction, + }); + if (targetFd !== undefined) { + return targetFd; + } + + if (isStream(value, {checkOpen: false})) { + throw new TypeError(`The \`${optionName}: Stream\` option cannot both be an array and include a stream with synchronous methods.`); + } + + return stdioItem; +}; + +const getTargetFd = ({value, optionName, fdNumber, direction}) => { + const targetFdNumber = getTargetFdNumber(value, fdNumber); + if (targetFdNumber === undefined) { + return; + } + + if (direction === 'output') { + return {type: 'fileNumber', value: targetFdNumber, optionName}; + } + + if (tty.isatty(targetFdNumber)) { + throw new TypeError(`The \`${optionName}: ${serializeOptionValue(value)}\` option is invalid: it cannot be a TTY with synchronous methods.`); + } + + return {type: 'uint8Array', value: bufferToUint8Array(readFileSync(targetFdNumber)), optionName}; +}; + +const getTargetFdNumber = (value, fdNumber) => { + if (value === 'inherit') { + return fdNumber; + } + + if (typeof value === 'number') { + return value; + } + + const standardStreamIndex = STANDARD_STREAMS.indexOf(value); + if (standardStreamIndex !== -1) { + return standardStreamIndex; + } +}; + +const handleNativeStreamAsync = ({stdioItem, stdioItem: {value, optionName}, fdNumber}) => { + if (value === 'inherit') { + return {type: 'nodeStream', value: getStandardStream(fdNumber, value, optionName), optionName}; + } + + if (typeof value === 'number') { + return {type: 'nodeStream', value: getStandardStream(value, value, optionName), optionName}; + } + + if (isStream(value, {checkOpen: false})) { + return {type: 'nodeStream', value, optionName}; + } + + return stdioItem; +}; + +// Node.js does not allow to easily retrieve file descriptors beyond stdin/stdout/stderr as streams. +// - `fs.createReadStream()`/`fs.createWriteStream()` with the `fd` option do not work with character devices that use blocking reads/writes (such as interactive TTYs). +// - Using a TCP `Socket` would work but be rather complex to implement. +// Since this is an edge case, we simply throw an error message. +// See https://github.com/sindresorhus/execa/pull/643#discussion_r1435905707 +const getStandardStream = (fdNumber, value, optionName) => { + const standardStream = STANDARD_STREAMS[fdNumber]; + + if (standardStream === undefined) { + throw new TypeError(`The \`${optionName}: ${value}\` option is invalid: no such standard stream.`); + } + + return standardStream; +}; + +// Append the `stdin` option with the `input` and `inputFile` options +const handleInputOptions = ({input, inputFile}, fdNumber) => fdNumber === 0 + ? [ + ...handleInputOption(input), + ...handleInputFileOption(inputFile), + ] + : []; + +const handleInputOption = input => input === undefined ? [] : [{ + type: getInputType(input), + value: input, + optionName: 'input', +}]; + +const getInputType = input => { + if (isReadableStream$1(input, {checkOpen: false})) { + return 'nodeStream'; + } + + if (typeof input === 'string') { + return 'string'; + } + + if (isUint8Array(input)) { + return 'uint8Array'; + } + + throw new Error('The `input` option must be a string, a Uint8Array or a Node.js Readable stream.'); +}; + +const handleInputFileOption = inputFile => inputFile === undefined ? [] : [{ + ...getInputFileType(inputFile), + optionName: 'inputFile', +}]; + +const getInputFileType = inputFile => { + if (isUrl(inputFile)) { + return {type: 'fileUrl', value: inputFile}; + } + + if (isFilePathString(inputFile)) { + return {type: 'filePath', value: {file: inputFile}}; + } + + throw new Error('The `inputFile` option must be a file path string or a file URL.'); +}; + +// Duplicates in the same file descriptor is most likely an error. +// However, this can be useful with generators. +const filterDuplicates = stdioItems => stdioItems.filter((stdioItemOne, indexOne) => + stdioItems.every((stdioItemTwo, indexTwo) => stdioItemOne.value !== stdioItemTwo.value + || indexOne >= indexTwo + || stdioItemOne.type === 'generator' + || stdioItemOne.type === 'asyncGenerator')); + +// Check if two file descriptors are sharing the same target. +// For example `{stdout: {file: './output.txt'}, stderr: {file: './output.txt'}}`. +const getDuplicateStream = ({stdioItem: {type, value, optionName}, direction, fileDescriptors, isSync}) => { + const otherStdioItems = getOtherStdioItems(fileDescriptors, type); + if (otherStdioItems.length === 0) { + return; + } + + if (isSync) { + validateDuplicateStreamSync({ + otherStdioItems, + type, + value, + optionName, + direction, + }); + return; + } + + if (SPECIAL_DUPLICATE_TYPES.has(type)) { + return getDuplicateStreamInstance({ + otherStdioItems, + type, + value, + optionName, + direction, + }); + } + + if (FORBID_DUPLICATE_TYPES.has(type)) { + validateDuplicateTransform({ + otherStdioItems, + type, + value, + optionName, + }); + } +}; + +// Values shared by multiple file descriptors +const getOtherStdioItems = (fileDescriptors, type) => fileDescriptors + .flatMap(({direction, stdioItems}) => stdioItems + .filter(stdioItem => stdioItem.type === type) + .map((stdioItem => ({...stdioItem, direction})))); + +// With `execaSync()`, do not allow setting a file path both in input and output +const validateDuplicateStreamSync = ({otherStdioItems, type, value, optionName, direction}) => { + if (SPECIAL_DUPLICATE_TYPES_SYNC.has(type)) { + getDuplicateStreamInstance({ + otherStdioItems, + type, + value, + optionName, + direction, + }); + } +}; + +// When two file descriptors share the file or stream, we need to re-use the same underlying stream. +// Otherwise, the stream would be closed twice when piping ends. +// This is only an issue with output file descriptors. +// This is not a problem with generator functions since those create a new instance for each file descriptor. +// We also forbid input and output file descriptors sharing the same file or stream, since that does not make sense. +const getDuplicateStreamInstance = ({otherStdioItems, type, value, optionName, direction}) => { + const duplicateStdioItems = otherStdioItems.filter(stdioItem => hasSameValue(stdioItem, value)); + if (duplicateStdioItems.length === 0) { + return; + } + + const differentStdioItem = duplicateStdioItems.find(stdioItem => stdioItem.direction !== direction); + throwOnDuplicateStream(differentStdioItem, optionName, type); + + return direction === 'output' ? duplicateStdioItems[0].stream : undefined; +}; + +const hasSameValue = ({type, value}, secondValue) => { + if (type === 'filePath') { + return value.file === secondValue.file; + } + + if (type === 'fileUrl') { + return value.href === secondValue.href; + } + + return value === secondValue; +}; + +// We do not allow two file descriptors to share the same Duplex or TransformStream. +// This is because those are set directly to `subprocess.std*`. +// For example, this could result in `subprocess.stdout` and `subprocess.stderr` being the same value. +// This means reading from either would get data from both stdout and stderr. +const validateDuplicateTransform = ({otherStdioItems, type, value, optionName}) => { + const duplicateStdioItem = otherStdioItems.find(({value: {transform}}) => transform === value.transform); + throwOnDuplicateStream(duplicateStdioItem, optionName, type); +}; + +const throwOnDuplicateStream = (stdioItem, optionName, type) => { + if (stdioItem !== undefined) { + throw new TypeError(`The \`${stdioItem.optionName}\` and \`${optionName}\` options must not target ${TYPE_TO_MESSAGE[type]} that is the same.`); + } +}; + +// Handle `input`, `inputFile`, `stdin`, `stdout` and `stderr` options, before spawning, in async/sync mode +// They are converted into an array of `fileDescriptors`. +// Each `fileDescriptor` is normalized, validated and contains all information necessary for further handling. +const handleStdio = (addProperties, options, verboseInfo, isSync) => { + const stdio = normalizeStdioOption(options, verboseInfo, isSync); + const initialFileDescriptors = stdio.map((stdioOption, fdNumber) => getFileDescriptor({ + stdioOption, + fdNumber, + options, + isSync, + })); + const fileDescriptors = getFinalFileDescriptors({ + initialFileDescriptors, + addProperties, + options, + isSync, + }); + options.stdio = fileDescriptors.map(({stdioItems}) => forwardStdio(stdioItems)); + return fileDescriptors; +}; + +const getFileDescriptor = ({stdioOption, fdNumber, options, isSync}) => { + const optionName = getStreamName(fdNumber); + const {stdioItems: initialStdioItems, isStdioArray} = initializeStdioItems({ + stdioOption, + fdNumber, + options, + optionName, + }); + const direction = getStreamDirection(initialStdioItems, fdNumber, optionName); + const stdioItems = initialStdioItems.map(stdioItem => handleNativeStream({ + stdioItem, + isStdioArray, + fdNumber, + direction, + isSync, + })); + const normalizedStdioItems = normalizeTransforms(stdioItems, optionName, direction, options); + const objectMode = getFdObjectMode(normalizedStdioItems, direction); + validateFileObjectMode(normalizedStdioItems, objectMode); + return {direction, objectMode, stdioItems: normalizedStdioItems}; +}; + +// We make sure passing an array with a single item behaves the same as passing that item without an array. +// This is what users would expect. +// For example, `stdout: ['ignore']` behaves the same as `stdout: 'ignore'`. +const initializeStdioItems = ({stdioOption, fdNumber, options, optionName}) => { + const values = Array.isArray(stdioOption) ? stdioOption : [stdioOption]; + const initialStdioItems = [ + ...values.map(value => initializeStdioItem(value, optionName)), + ...handleInputOptions(options, fdNumber), + ]; + + const stdioItems = filterDuplicates(initialStdioItems); + const isStdioArray = stdioItems.length > 1; + validateStdioArray(stdioItems, isStdioArray, optionName); + validateStreams(stdioItems); + return {stdioItems, isStdioArray}; +}; + +const initializeStdioItem = (value, optionName) => ({ + type: getStdioItemType(value, optionName), + value, + optionName, +}); + +const validateStdioArray = (stdioItems, isStdioArray, optionName) => { + if (stdioItems.length === 0) { + throw new TypeError(`The \`${optionName}\` option must not be an empty array.`); + } + + if (!isStdioArray) { + return; + } + + for (const {value, optionName} of stdioItems) { + if (INVALID_STDIO_ARRAY_OPTIONS.has(value)) { + throw new Error(`The \`${optionName}\` option must not include \`${value}\`.`); + } + } +}; + +// Using those `stdio` values together with others for the same stream does not make sense, so we make it fail. +// However, we do allow it if the array has a single item. +const INVALID_STDIO_ARRAY_OPTIONS = new Set(['ignore', 'ipc']); + +const validateStreams = stdioItems => { + for (const stdioItem of stdioItems) { + validateFileStdio(stdioItem); + } +}; + +const validateFileStdio = ({type, value, optionName}) => { + if (isRegularUrl(value)) { + throw new TypeError(`The \`${optionName}: URL\` option must use the \`file:\` scheme. +For example, you can use the \`pathToFileURL()\` method of the \`url\` core module.`); + } + + if (isUnknownStdioString(type, value)) { + throw new TypeError(`The \`${optionName}: { file: '...' }\` option must be used instead of \`${optionName}: '...'\`.`); + } +}; + +const validateFileObjectMode = (stdioItems, objectMode) => { + if (!objectMode) { + return; + } + + const fileStdioItem = stdioItems.find(({type}) => FILE_TYPES.has(type)); + if (fileStdioItem !== undefined) { + throw new TypeError(`The \`${fileStdioItem.optionName}\` option cannot use both files and transforms in objectMode.`); + } +}; + +// Some `stdio` values require Execa to create streams. +// For example, file paths create file read/write streams. +// Those transformations are specified in `addProperties`, which is both direction-specific and type-specific. +const getFinalFileDescriptors = ({initialFileDescriptors, addProperties, options, isSync}) => { + const fileDescriptors = []; + + try { + for (const fileDescriptor of initialFileDescriptors) { + fileDescriptors.push(getFinalFileDescriptor({ + fileDescriptor, + fileDescriptors, + addProperties, + options, + isSync, + })); + } + + return fileDescriptors; + } catch (error) { + cleanupCustomStreams(fileDescriptors); + throw error; + } +}; + +const getFinalFileDescriptor = ({ + fileDescriptor: {direction, objectMode, stdioItems}, + fileDescriptors, + addProperties, + options, + isSync, +}) => { + const finalStdioItems = stdioItems.map(stdioItem => addStreamProperties({ + stdioItem, + addProperties, + direction, + options, + fileDescriptors, + isSync, + })); + return {direction, objectMode, stdioItems: finalStdioItems}; +}; + +const addStreamProperties = ({stdioItem, addProperties, direction, options, fileDescriptors, isSync}) => { + const duplicateStream = getDuplicateStream({ + stdioItem, + direction, + fileDescriptors, + isSync, + }); + + if (duplicateStream !== undefined) { + return {...stdioItem, stream: duplicateStream}; + } + + return { + ...stdioItem, + ...addProperties[direction][stdioItem.type](stdioItem, options), + }; +}; + +// The stream error handling is performed by the piping logic above, which cannot be performed before subprocess spawning. +// If the subprocess spawning fails (e.g. due to an invalid command), the streams need to be manually destroyed. +// We need to create those streams before subprocess spawning, in case their creation fails, e.g. when passing an invalid generator as argument. +// Like this, an exception would be thrown, which would prevent spawning a subprocess. +const cleanupCustomStreams = fileDescriptors => { + for (const {stdioItems} of fileDescriptors) { + for (const {stream} of stdioItems) { + if (stream !== undefined && !isStandardStream(stream)) { + stream.destroy(); + } + } + } +}; + +// When the `std*: Iterable | WebStream | URL | filePath`, `input` or `inputFile` option is used, we pipe to `subprocess.std*`. +// When the `std*: Array` option is used, we emulate some of the native values ('inherit', Node.js stream and file descriptor integer). To do so, we also need to pipe to `subprocess.std*`. +// Therefore the `std*` options must be either `pipe` or `overlapped`. Other values do not set `subprocess.std*`. +const forwardStdio = stdioItems => { + if (stdioItems.length > 1) { + return stdioItems.some(({value}) => value === 'overlapped') ? 'overlapped' : 'pipe'; + } + + const [{type, value}] = stdioItems; + return type === 'native' ? value : 'pipe'; +}; + +// Normalize `input`, `inputFile`, `stdin`, `stdout` and `stderr` options, before spawning, in sync mode +const handleStdioSync = (options, verboseInfo) => handleStdio(addPropertiesSync, options, verboseInfo, true); + +const forbiddenIfSync = ({type, optionName}) => { + throwInvalidSyncValue(optionName, TYPE_TO_MESSAGE[type]); +}; + +const forbiddenNativeIfSync = ({optionName, value}) => { + if (value === 'ipc' || value === 'overlapped') { + throwInvalidSyncValue(optionName, `"${value}"`); + } + + return {}; +}; + +const throwInvalidSyncValue = (optionName, value) => { + throw new TypeError(`The \`${optionName}\` option cannot be ${value} with synchronous methods.`); +}; + +// Create streams used internally for redirecting when using specific values for the `std*` options, in sync mode. +// For example, `stdin: {file}` reads the file synchronously, then passes it as the `input` option. +const addProperties$1 = { + generator() {}, + asyncGenerator: forbiddenIfSync, + webStream: forbiddenIfSync, + nodeStream: forbiddenIfSync, + webTransform: forbiddenIfSync, + duplex: forbiddenIfSync, + asyncIterable: forbiddenIfSync, + native: forbiddenNativeIfSync, +}; + +const addPropertiesSync = { + input: { + ...addProperties$1, + fileUrl: ({value}) => ({contents: [bufferToUint8Array(readFileSync(value))]}), + filePath: ({value: {file}}) => ({contents: [bufferToUint8Array(readFileSync(file))]}), + fileNumber: forbiddenIfSync, + iterable: ({value}) => ({contents: [...value]}), + string: ({value}) => ({contents: [value]}), + uint8Array: ({value}) => ({contents: [value]}), + }, + output: { + ...addProperties$1, + fileUrl: ({value}) => ({path: value}), + filePath: ({value: {file, append}}) => ({path: file, append}), + fileNumber: ({value}) => ({path: value}), + iterable: forbiddenIfSync, + string: forbiddenIfSync, + uint8Array: forbiddenIfSync, + }, +}; + +// Apply `stripFinalNewline` option, which applies to `result.stdout|stderr|all|stdio[*]`. +// If the `lines` option is used, it is applied on each line, but using a different function. +const stripNewline = (value, {stripFinalNewline: stripFinalNewline$1}, fdNumber) => getStripFinalNewline(stripFinalNewline$1, fdNumber) && value !== undefined && !Array.isArray(value) + ? stripFinalNewline(value) + : value; + +// Retrieve `stripFinalNewline` option value, including with `subprocess.all` +const getStripFinalNewline = (stripFinalNewline, fdNumber) => fdNumber === 'all' + ? stripFinalNewline[1] || stripFinalNewline[2] + : stripFinalNewline[fdNumber]; + +// Split chunks line-wise for generators passed to the `std*` options +const getSplitLinesGenerator = (binary, preserveNewlines, skipped, state) => binary || skipped + ? undefined + : initializeSplitLines(preserveNewlines, state); + +// Same but for synchronous methods +const splitLinesSync = (chunk, preserveNewlines, objectMode) => objectMode + ? chunk.flatMap(item => splitLinesItemSync(item, preserveNewlines)) + : splitLinesItemSync(chunk, preserveNewlines); + +const splitLinesItemSync = (chunk, preserveNewlines) => { + const {transform, final} = initializeSplitLines(preserveNewlines, {}); + return [...transform(chunk), ...final()]; +}; + +const initializeSplitLines = (preserveNewlines, state) => { + state.previousChunks = ''; + return { + transform: splitGenerator.bind(undefined, state, preserveNewlines), + final: linesFinal.bind(undefined, state), + }; +}; + +// This imperative logic is much faster than using `String.split()` and uses very low memory. +const splitGenerator = function * (state, preserveNewlines, chunk) { + if (typeof chunk !== 'string') { + yield chunk; + return; + } + + let {previousChunks} = state; + let start = -1; + + for (let end = 0; end < chunk.length; end += 1) { + if (chunk[end] === '\n') { + const newlineLength = getNewlineLength(chunk, end, preserveNewlines, state); + let line = chunk.slice(start + 1, end + 1 - newlineLength); + + if (previousChunks.length > 0) { + line = concatString(previousChunks, line); + previousChunks = ''; + } + + yield line; + start = end; + } + } + + if (start !== chunk.length - 1) { + previousChunks = concatString(previousChunks, chunk.slice(start + 1)); + } + + state.previousChunks = previousChunks; +}; + +const getNewlineLength = (chunk, end, preserveNewlines, state) => { + if (preserveNewlines) { + return 0; + } + + state.isWindowsNewline = end !== 0 && chunk[end - 1] === '\r'; + return state.isWindowsNewline ? 2 : 1; +}; + +const linesFinal = function * ({previousChunks}) { + if (previousChunks.length > 0) { + yield previousChunks; + } +}; + +// Unless `preserveNewlines: true` is used, we strip the newline of each line. +// This re-adds them after the user `transform` code has run. +const getAppendNewlineGenerator = ({binary, preserveNewlines, readableObjectMode, state}) => binary || preserveNewlines || readableObjectMode + ? undefined + : {transform: appendNewlineGenerator.bind(undefined, state)}; + +const appendNewlineGenerator = function * ({isWindowsNewline = false}, chunk) { + const {unixNewline, windowsNewline, LF, concatBytes} = typeof chunk === 'string' ? linesStringInfo : linesUint8ArrayInfo; + + if (chunk.at(-1) === LF) { + yield chunk; + return; + } + + const newline = isWindowsNewline ? windowsNewline : unixNewline; + yield concatBytes(chunk, newline); +}; + +const concatString = (firstChunk, secondChunk) => `${firstChunk}${secondChunk}`; + +const linesStringInfo = { + windowsNewline: '\r\n', + unixNewline: '\n', + LF: '\n', + concatBytes: concatString, +}; + +const concatUint8Array = (firstChunk, secondChunk) => { + const chunk = new Uint8Array(firstChunk.length + secondChunk.length); + chunk.set(firstChunk, 0); + chunk.set(secondChunk, firstChunk.length); + return chunk; +}; + +const linesUint8ArrayInfo = { + windowsNewline: new Uint8Array([0x0D, 0x0A]), + unixNewline: new Uint8Array([0x0A]), + LF: 0x0A, + concatBytes: concatUint8Array, +}; + +// Validate the type of chunk argument passed to transform generators +const getValidateTransformInput = (writableObjectMode, optionName) => writableObjectMode + ? undefined + : validateStringTransformInput.bind(undefined, optionName); + +const validateStringTransformInput = function * (optionName, chunk) { + if (typeof chunk !== 'string' && !isUint8Array(chunk) && !Buffer$1.isBuffer(chunk)) { + throw new TypeError(`The \`${optionName}\` option's transform must use "objectMode: true" to receive as input: ${typeof chunk}.`); + } + + yield chunk; +}; + +// Validate the type of the value returned by transform generators +const getValidateTransformReturn = (readableObjectMode, optionName) => readableObjectMode + ? validateObjectTransformReturn.bind(undefined, optionName) + : validateStringTransformReturn.bind(undefined, optionName); + +const validateObjectTransformReturn = function * (optionName, chunk) { + validateEmptyReturn(optionName, chunk); + yield chunk; +}; + +const validateStringTransformReturn = function * (optionName, chunk) { + validateEmptyReturn(optionName, chunk); + + if (typeof chunk !== 'string' && !isUint8Array(chunk)) { + throw new TypeError(`The \`${optionName}\` option's function must yield a string or an Uint8Array, not ${typeof chunk}.`); + } + + yield chunk; +}; + +const validateEmptyReturn = (optionName, chunk) => { + if (chunk === null || chunk === undefined) { + throw new TypeError(`The \`${optionName}\` option's function must not call \`yield ${chunk}\`. +Instead, \`yield\` should either be called with a value, or not be called at all. For example: + if (condition) { yield value; }`); + } +}; + +/* +When using binary encodings, add an internal generator that converts chunks from `Buffer` to `string` or `Uint8Array`. +Chunks might be Buffer, Uint8Array or strings since: +- `subprocess.stdout|stderr` emits Buffers +- `subprocess.stdin.write()` accepts Buffer, Uint8Array or string +- Previous generators might return Uint8Array or string + +However, those are converted to Buffer: +- on writes: `Duplex.writable` `decodeStrings: true` default option +- on reads: `Duplex.readable` `readableEncoding: null` default option +*/ +const getEncodingTransformGenerator = (binary, encoding, skipped) => { + if (skipped) { + return; + } + + if (binary) { + return {transform: encodingUint8ArrayGenerator.bind(undefined, new TextEncoder())}; + } + + const stringDecoder = new StringDecoder(encoding); + return { + transform: encodingStringGenerator.bind(undefined, stringDecoder), + final: encodingStringFinal.bind(undefined, stringDecoder), + }; +}; + +const encodingUint8ArrayGenerator = function * (textEncoder, chunk) { + if (Buffer$1.isBuffer(chunk)) { + yield bufferToUint8Array(chunk); + } else if (typeof chunk === 'string') { + yield textEncoder.encode(chunk); + } else { + yield chunk; + } +}; + +const encodingStringGenerator = function * (stringDecoder, chunk) { + yield isUint8Array(chunk) ? stringDecoder.write(chunk) : chunk; +}; + +const encodingStringFinal = function * (stringDecoder) { + const lastChunk = stringDecoder.end(); + if (lastChunk !== '') { + yield lastChunk; + } +}; + +// Applies a series of generator functions asynchronously +const pushChunks = callbackify(async (getChunks, state, getChunksArguments, transformStream) => { + state.currentIterable = getChunks(...getChunksArguments); + + try { + for await (const chunk of state.currentIterable) { + transformStream.push(chunk); + } + } finally { + delete state.currentIterable; + } +}); + +// For each new chunk, apply each `transform()` method +const transformChunk = async function * (chunk, generators, index) { + if (index === generators.length) { + yield chunk; + return; + } + + const {transform = identityGenerator$1} = generators[index]; + for await (const transformedChunk of transform(chunk)) { + yield * transformChunk(transformedChunk, generators, index + 1); + } +}; + +// At the end, apply each `final()` method, followed by the `transform()` method of the next transforms +const finalChunks = async function * (generators) { + for (const [index, {final}] of Object.entries(generators)) { + yield * generatorFinalChunks(final, Number(index), generators); + } +}; + +const generatorFinalChunks = async function * (final, index, generators) { + if (final === undefined) { + return; + } + + for await (const finalChunk of final()) { + yield * transformChunk(finalChunk, generators, index + 1); + } +}; + +// Cancel any ongoing async generator when the Transform is destroyed, e.g. when the subprocess errors +const destroyTransform = callbackify(async ({currentIterable}, error) => { + if (currentIterable !== undefined) { + await (error ? currentIterable.throw(error) : currentIterable.return()); + return; + } + + if (error) { + throw error; + } +}); + +const identityGenerator$1 = function * (chunk) { + yield chunk; +}; + +// Duplicate the code from `run-async.js` but as synchronous functions +const pushChunksSync = (getChunksSync, getChunksArguments, transformStream, done) => { + try { + for (const chunk of getChunksSync(...getChunksArguments)) { + transformStream.push(chunk); + } + + done(); + } catch (error) { + done(error); + } +}; + +// Run synchronous generators with `execaSync()` +const runTransformSync = (generators, chunks) => [ + ...chunks.flatMap(chunk => [...transformChunkSync(chunk, generators, 0)]), + ...finalChunksSync(generators), +]; + +const transformChunkSync = function * (chunk, generators, index) { + if (index === generators.length) { + yield chunk; + return; + } + + const {transform = identityGenerator} = generators[index]; + for (const transformedChunk of transform(chunk)) { + yield * transformChunkSync(transformedChunk, generators, index + 1); + } +}; + +const finalChunksSync = function * (generators) { + for (const [index, {final}] of Object.entries(generators)) { + yield * generatorFinalChunksSync(final, Number(index), generators); + } +}; + +const generatorFinalChunksSync = function * (final, index, generators) { + if (final === undefined) { + return; + } + + for (const finalChunk of final()) { + yield * transformChunkSync(finalChunk, generators, index + 1); + } +}; + +const identityGenerator = function * (chunk) { + yield chunk; +}; + +/* +Generators can be used to transform/filter standard streams. + +Generators have a simple syntax, yet allows all of the following: +- Sharing `state` between chunks +- Flushing logic, by using a `final` function +- Asynchronous logic +- Emitting multiple chunks from a single source chunk, even if spaced in time, by using multiple `yield` +- Filtering, by using no `yield` + +Therefore, there is no need to allow Node.js or web transform streams. + +The `highWaterMark` is kept as the default value, since this is what `subprocess.std*` uses. + +Chunks are currently processed serially. We could add a `concurrency` option to parallelize in the future. + +Transform an array of generator functions into a `Transform` stream. +`Duplex.from(generator)` cannot be used because it does not allow setting the `objectMode` and `highWaterMark`. +*/ +const generatorToStream = ({ + value, + value: {transform, final, writableObjectMode, readableObjectMode}, + optionName, +}, {encoding}) => { + const state = {}; + const generators = addInternalGenerators(value, encoding, optionName); + + const transformAsync = isAsyncGenerator(transform); + const finalAsync = isAsyncGenerator(final); + const transformMethod = transformAsync + ? pushChunks.bind(undefined, transformChunk, state) + : pushChunksSync.bind(undefined, transformChunkSync); + const finalMethod = transformAsync || finalAsync + ? pushChunks.bind(undefined, finalChunks, state) + : pushChunksSync.bind(undefined, finalChunksSync); + const destroyMethod = transformAsync || finalAsync + ? destroyTransform.bind(undefined, state) + : undefined; + + const stream = new Transform({ + writableObjectMode, + writableHighWaterMark: getDefaultHighWaterMark(writableObjectMode), + readableObjectMode, + readableHighWaterMark: getDefaultHighWaterMark(readableObjectMode), + transform(chunk, encoding, done) { + transformMethod([chunk, generators, 0], this, done); + }, + flush(done) { + finalMethod([generators], this, done); + }, + destroy: destroyMethod, + }); + return {stream}; +}; + +// Applies transform generators in sync mode +const runGeneratorsSync = (chunks, stdioItems, encoding, isInput) => { + const generators = stdioItems.filter(({type}) => type === 'generator'); + const reversedGenerators = isInput ? generators.reverse() : generators; + + for (const {value, optionName} of reversedGenerators) { + const generators = addInternalGenerators(value, encoding, optionName); + chunks = runTransformSync(generators, chunks); + } + + return chunks; +}; + +// Generators used internally to convert the chunk type, validate it, and split into lines +const addInternalGenerators = ( + {transform, final, binary, writableObjectMode, readableObjectMode, preserveNewlines}, + encoding, + optionName, +) => { + const state = {}; + return [ + {transform: getValidateTransformInput(writableObjectMode, optionName)}, + getEncodingTransformGenerator(binary, encoding, writableObjectMode), + getSplitLinesGenerator(binary, preserveNewlines, writableObjectMode, state), + {transform, final}, + {transform: getValidateTransformReturn(readableObjectMode, optionName)}, + getAppendNewlineGenerator({ + binary, + preserveNewlines, + readableObjectMode, + state, + }), + ].filter(Boolean); +}; + +// Apply `stdin`/`input`/`inputFile` options, before spawning, in sync mode, by converting it to the `input` option +const addInputOptionsSync = (fileDescriptors, options) => { + for (const fdNumber of getInputFdNumbers(fileDescriptors)) { + addInputOptionSync(fileDescriptors, fdNumber, options); + } +}; + +const getInputFdNumbers = fileDescriptors => new Set(Object.entries(fileDescriptors) + .filter(([, {direction}]) => direction === 'input') + .map(([fdNumber]) => Number(fdNumber))); + +const addInputOptionSync = (fileDescriptors, fdNumber, options) => { + const {stdioItems} = fileDescriptors[fdNumber]; + const allStdioItems = stdioItems.filter(({contents}) => contents !== undefined); + if (allStdioItems.length === 0) { + return; + } + + if (fdNumber !== 0) { + const [{type, optionName}] = allStdioItems; + throw new TypeError(`Only the \`stdin\` option, not \`${optionName}\`, can be ${TYPE_TO_MESSAGE[type]} with synchronous methods.`); + } + + const allContents = allStdioItems.map(({contents}) => contents); + const transformedContents = allContents.map(contents => applySingleInputGeneratorsSync(contents, stdioItems)); + options.input = joinToUint8Array(transformedContents); +}; + +const applySingleInputGeneratorsSync = (contents, stdioItems) => { + const newContents = runGeneratorsSync(contents, stdioItems, 'utf8', true); + validateSerializable(newContents); + return joinToUint8Array(newContents); +}; + +const validateSerializable = newContents => { + const invalidItem = newContents.find(item => typeof item !== 'string' && !isUint8Array(item)); + if (invalidItem !== undefined) { + throw new TypeError(`The \`stdin\` option is invalid: when passing objects as input, a transform must be used to serialize them to strings or Uint8Arrays: ${invalidItem}.`); + } +}; + +// `ignore` opts-out of `verbose` for a specific stream. +// `ipc` cannot use piping. +// `inherit` would result in double printing. +// They can also lead to double printing when passing file descriptor integers or `process.std*`. +// This only leaves with `pipe` and `overlapped`. +const shouldLogOutput = ({stdioItems, encoding, verboseInfo, fdNumber}) => fdNumber !== 'all' + && isFullVerbose(verboseInfo, fdNumber) + && !BINARY_ENCODINGS.has(encoding) + && fdUsesVerbose(fdNumber) + && (stdioItems.some(({type, value}) => type === 'native' && PIPED_STDIO_VALUES.has(value)) + || stdioItems.every(({type}) => TRANSFORM_TYPES.has(type))); + +// Printing input streams would be confusing. +// Files and streams can produce big outputs, which we don't want to print. +// We could print `stdio[3+]` but it often is redirected to files and streams, with the same issue. +// So we only print stdout and stderr. +const fdUsesVerbose = fdNumber => fdNumber === 1 || fdNumber === 2; + +const PIPED_STDIO_VALUES = new Set(['pipe', 'overlapped']); + +// `verbose: 'full'` printing logic with async methods +const logLines = async (linesIterable, stream, fdNumber, verboseInfo) => { + for await (const line of linesIterable) { + if (!isPipingStream(stream)) { + logLine(line, fdNumber, verboseInfo); + } + } +}; + +// `verbose: 'full'` printing logic with sync methods +const logLinesSync = (linesArray, fdNumber, verboseInfo) => { + for (const line of linesArray) { + logLine(line, fdNumber, verboseInfo); + } +}; + +// When `subprocess.stdout|stderr.pipe()` is called, `verbose` becomes a noop. +// This prevents the following problems: +// - `.pipe()` achieves the same result as using `stdout: 'inherit'`, `stdout: stream`, etc. which also make `verbose` a noop. +// For example, `subprocess.stdout.pipe(process.stdin)` would print each line twice. +// - When chaining subprocesses with `subprocess.pipe(otherSubprocess)`, only the last one should print its output. +// Detecting whether `.pipe()` is impossible without monkey-patching it, so we use the following undocumented property. +// This is not a critical behavior since changes of the following property would only make `verbose` more verbose. +const isPipingStream = stream => stream._readableState.pipes.length > 0; + +// When `verbose` is `full`, print stdout|stderr +const logLine = (line, fdNumber, verboseInfo) => { + const verboseMessage = serializeVerboseMessage(line); + verboseLog({ + type: 'output', + verboseMessage, + fdNumber, + verboseInfo, + }); +}; + +// Apply `stdout`/`stderr` options, after spawning, in sync mode +const transformOutputSync = ({fileDescriptors, syncResult: {output}, options, isMaxBuffer, verboseInfo}) => { + if (output === null) { + return {output: Array.from({length: 3})}; + } + + const state = {}; + const outputFiles = new Set([]); + const transformedOutput = output.map((result, fdNumber) => + transformOutputResultSync({ + result, + fileDescriptors, + fdNumber, + state, + outputFiles, + isMaxBuffer, + verboseInfo, + }, options)); + return {output: transformedOutput, ...state}; +}; + +const transformOutputResultSync = ( + {result, fileDescriptors, fdNumber, state, outputFiles, isMaxBuffer, verboseInfo}, + {buffer, encoding, lines, stripFinalNewline, maxBuffer}, +) => { + if (result === null) { + return; + } + + const truncatedResult = truncateMaxBufferSync(result, isMaxBuffer, maxBuffer); + const uint8ArrayResult = bufferToUint8Array(truncatedResult); + const {stdioItems, objectMode} = fileDescriptors[fdNumber]; + const chunks = runOutputGeneratorsSync([uint8ArrayResult], stdioItems, encoding, state); + const {serializedResult, finalResult = serializedResult} = serializeChunks({ + chunks, + objectMode, + encoding, + lines, + stripFinalNewline, + fdNumber, + }); + + logOutputSync({ + serializedResult, + fdNumber, + state, + verboseInfo, + encoding, + stdioItems, + objectMode, + }); + + const returnedResult = buffer[fdNumber] ? finalResult : undefined; + + try { + if (state.error === undefined) { + writeToFiles(serializedResult, stdioItems, outputFiles); + } + + return returnedResult; + } catch (error) { + state.error = error; + return returnedResult; + } +}; + +// Applies transform generators to `stdout`/`stderr` +const runOutputGeneratorsSync = (chunks, stdioItems, encoding, state) => { + try { + return runGeneratorsSync(chunks, stdioItems, encoding, false); + } catch (error) { + state.error = error; + return chunks; + } +}; + +// The contents is converted to three stages: +// - serializedResult: used when the target is a file path/URL or a file descriptor (including 'inherit') +// - finalResult/returnedResult: returned as `result.std*` +const serializeChunks = ({chunks, objectMode, encoding, lines, stripFinalNewline, fdNumber}) => { + if (objectMode) { + return {serializedResult: chunks}; + } + + if (encoding === 'buffer') { + return {serializedResult: joinToUint8Array(chunks)}; + } + + const serializedResult = joinToString(chunks, encoding); + if (lines[fdNumber]) { + return {serializedResult, finalResult: splitLinesSync(serializedResult, !stripFinalNewline[fdNumber], objectMode)}; + } + + return {serializedResult}; +}; + +const logOutputSync = ({serializedResult, fdNumber, state, verboseInfo, encoding, stdioItems, objectMode}) => { + if (!shouldLogOutput({ + stdioItems, + encoding, + verboseInfo, + fdNumber, + })) { + return; + } + + const linesArray = splitLinesSync(serializedResult, false, objectMode); + + try { + logLinesSync(linesArray, fdNumber, verboseInfo); + } catch (error) { + state.error ??= error; + } +}; + +// When the `std*` target is a file path/URL or a file descriptor +const writeToFiles = (serializedResult, stdioItems, outputFiles) => { + for (const {path, append} of stdioItems.filter(({type}) => FILE_TYPES.has(type))) { + const pathString = typeof path === 'string' ? path : path.toString(); + if (append || outputFiles.has(pathString)) { + appendFileSync(path, serializedResult); + } else { + outputFiles.add(pathString); + writeFileSync(path, serializedResult); + } + } +}; + +// Retrieve `result.all` with synchronous methods +const getAllSync = ([, stdout, stderr], options) => { + if (!options.all) { + return; + } + + if (stdout === undefined) { + return stderr; + } + + if (stderr === undefined) { + return stdout; + } + + if (Array.isArray(stdout)) { + return Array.isArray(stderr) + ? [...stdout, ...stderr] + : [...stdout, stripNewline(stderr, options, 'all')]; + } + + if (Array.isArray(stderr)) { + return [stripNewline(stdout, options, 'all'), ...stderr]; + } + + if (isUint8Array(stdout) && isUint8Array(stderr)) { + return concatUint8Arrays([stdout, stderr]); + } + + return `${stdout}${stderr}`; +}; + +// If `error` is emitted before `spawn`, `exit` will never be emitted. +// However, `error` might be emitted after `spawn`. +// In that case, `exit` will still be emitted. +// Since the `exit` event contains the signal name, we want to make sure we are listening for it. +// This function also takes into account the following unlikely cases: +// - `exit` being emitted in the same microtask as `spawn` +// - `error` being emitted multiple times +const waitForExit = async (subprocess, context) => { + const [exitCode, signal] = await waitForExitOrError(subprocess); + context.isForcefullyTerminated ??= false; + return [exitCode, signal]; +}; + +const waitForExitOrError = async subprocess => { + const [spawnPayload, exitPayload] = await Promise.allSettled([ + once$2(subprocess, 'spawn'), + once$2(subprocess, 'exit'), + ]); + + if (spawnPayload.status === 'rejected') { + return []; + } + + return exitPayload.status === 'rejected' + ? waitForSubprocessExit(subprocess) + : exitPayload.value; +}; + +const waitForSubprocessExit = async subprocess => { + try { + return await once$2(subprocess, 'exit'); + } catch { + return waitForSubprocessExit(subprocess); + } +}; + +// Retrieve the final exit code and|or signal name +const waitForSuccessfulExit = async exitPromise => { + const [exitCode, signal] = await exitPromise; + + if (!isSubprocessErrorExit(exitCode, signal) && isFailedExit(exitCode, signal)) { + throw new DiscardedError(); + } + + return [exitCode, signal]; +}; + +// When the subprocess fails due to an `error` event +const isSubprocessErrorExit = (exitCode, signal) => exitCode === undefined && signal === undefined; +// When the subprocess fails due to a non-0 exit code or to a signal termination +const isFailedExit = (exitCode, signal) => exitCode !== 0 || signal !== null; + +// Retrieve exit code, signal name and error information, with synchronous methods +const getExitResultSync = ({error, status: exitCode, signal, output}, {maxBuffer}) => { + const resultError = getResultError(error, exitCode, signal); + const timedOut = resultError?.code === 'ETIMEDOUT'; + const isMaxBuffer = isMaxBufferSync(resultError, output, maxBuffer); + return { + resultError, + exitCode, + signal, + timedOut, + isMaxBuffer, + }; +}; + +const getResultError = (error, exitCode, signal) => { + if (error !== undefined) { + return error; + } + + return isFailedExit(exitCode, signal) ? new DiscardedError() : undefined; +}; + +// Main shared logic for all sync methods: `execaSync()`, `$.sync()` +const execaCoreSync = (rawFile, rawArguments, rawOptions) => { + const {file, commandArguments, command, escapedCommand, startTime, verboseInfo, options, fileDescriptors} = handleSyncArguments(rawFile, rawArguments, rawOptions); + const result = spawnSubprocessSync({ + file, + commandArguments, + options, + command, + escapedCommand, + verboseInfo, + fileDescriptors, + startTime, + }); + return handleResult(result, verboseInfo, options); +}; + +// Compute arguments to pass to `child_process.spawnSync()` +const handleSyncArguments = (rawFile, rawArguments, rawOptions) => { + const {command, escapedCommand, startTime, verboseInfo} = handleCommand(rawFile, rawArguments, rawOptions); + const syncOptions = normalizeSyncOptions(rawOptions); + const {file, commandArguments, options} = normalizeOptions(rawFile, rawArguments, syncOptions); + validateSyncOptions(options); + const fileDescriptors = handleStdioSync(options, verboseInfo); + return { + file, + commandArguments, + command, + escapedCommand, + startTime, + verboseInfo, + options, + fileDescriptors, + }; +}; + +// Options normalization logic specific to sync methods +const normalizeSyncOptions = options => options.node && !options.ipc ? {...options, ipc: false} : options; + +// Options validation logic specific to sync methods +const validateSyncOptions = ({ipc, ipcInput, detached, cancelSignal}) => { + if (ipcInput) { + throwInvalidSyncOption('ipcInput'); + } + + if (ipc) { + throwInvalidSyncOption('ipc: true'); + } + + if (detached) { + throwInvalidSyncOption('detached: true'); + } + + if (cancelSignal) { + throwInvalidSyncOption('cancelSignal'); + } +}; + +const throwInvalidSyncOption = value => { + throw new TypeError(`The "${value}" option cannot be used with synchronous methods.`); +}; + +const spawnSubprocessSync = ({file, commandArguments, options, command, escapedCommand, verboseInfo, fileDescriptors, startTime}) => { + const syncResult = runSubprocessSync({ + file, + commandArguments, + options, + command, + escapedCommand, + fileDescriptors, + startTime, + }); + if (syncResult.failed) { + return syncResult; + } + + const {resultError, exitCode, signal, timedOut, isMaxBuffer} = getExitResultSync(syncResult, options); + const {output, error = resultError} = transformOutputSync({ + fileDescriptors, + syncResult, + options, + isMaxBuffer, + verboseInfo, + }); + const stdio = output.map((stdioOutput, fdNumber) => stripNewline(stdioOutput, options, fdNumber)); + const all = stripNewline(getAllSync(output, options), options, 'all'); + return getSyncResult({ + error, + exitCode, + signal, + timedOut, + isMaxBuffer, + stdio, + all, + options, + command, + escapedCommand, + startTime, + }); +}; + +const runSubprocessSync = ({file, commandArguments, options, command, escapedCommand, fileDescriptors, startTime}) => { + try { + addInputOptionsSync(fileDescriptors, options); + const normalizedOptions = normalizeSpawnSyncOptions(options); + return spawnSync(...concatenateShell(file, commandArguments, normalizedOptions)); + } catch (error) { + return makeEarlyError({ + error, + command, + escapedCommand, + fileDescriptors, + options, + startTime, + isSync: true, + }); + } +}; + +// The `encoding` option is handled by Execa, not by `child_process.spawnSync()` +const normalizeSpawnSyncOptions = ({encoding, maxBuffer, ...options}) => ({...options, encoding: 'buffer', maxBuffer: getMaxBufferSync(maxBuffer)}); + +const getSyncResult = ({error, exitCode, signal, timedOut, isMaxBuffer, stdio, all, options, command, escapedCommand, startTime}) => error === undefined + ? makeSuccessResult({ + command, + escapedCommand, + stdio, + all, + ipcOutput: [], + options, + startTime, + }) + : makeError({ + error, + command, + escapedCommand, + timedOut, + isCanceled: false, + isGracefullyCanceled: false, + isMaxBuffer, + isForcefullyTerminated: false, + exitCode, + signal, + stdio, + all, + ipcOutput: [], + options, + startTime, + isSync: true, + }); + +// Like `[sub]process.once('message')` but promise-based +const getOneMessage = ({anyProcess, channel, isSubprocess, ipc}, {reference = true, filter} = {}) => { + validateIpcMethod({ + methodName: 'getOneMessage', + isSubprocess, + ipc, + isConnected: isConnected(anyProcess), + }); + + return getOneMessageAsync({ + anyProcess, + channel, + isSubprocess, + filter, + reference, + }); +}; + +const getOneMessageAsync = async ({anyProcess, channel, isSubprocess, filter, reference}) => { + addReference(channel, reference); + const ipcEmitter = getIpcEmitter(anyProcess, channel, isSubprocess); + const controller = new AbortController(); + try { + return await Promise.race([ + getMessage(ipcEmitter, filter, controller), + throwOnDisconnect(ipcEmitter, isSubprocess, controller), + throwOnStrictError(ipcEmitter, isSubprocess, controller), + ]); + } catch (error) { + disconnect(anyProcess); + throw error; + } finally { + controller.abort(); + removeReference(channel, reference); + } +}; + +const getMessage = async (ipcEmitter, filter, {signal}) => { + if (filter === undefined) { + const [message] = await once$2(ipcEmitter, 'message', {signal}); + return message; + } + + for await (const [message] of on(ipcEmitter, 'message', {signal})) { + if (filter(message)) { + return message; + } + } +}; + +const throwOnDisconnect = async (ipcEmitter, isSubprocess, {signal}) => { + await once$2(ipcEmitter, 'disconnect', {signal}); + throwOnEarlyDisconnect(isSubprocess); +}; + +const throwOnStrictError = async (ipcEmitter, isSubprocess, {signal}) => { + const [error] = await once$2(ipcEmitter, 'strict:error', {signal}); + throw getStrictResponseError(error, isSubprocess); +}; + +// Like `[sub]process.on('message')` but promise-based +const getEachMessage = ({anyProcess, channel, isSubprocess, ipc}, {reference = true} = {}) => loopOnMessages({ + anyProcess, + channel, + isSubprocess, + ipc, + shouldAwait: !isSubprocess, + reference, +}); + +// Same but used internally +const loopOnMessages = ({anyProcess, channel, isSubprocess, ipc, shouldAwait, reference}) => { + validateIpcMethod({ + methodName: 'getEachMessage', + isSubprocess, + ipc, + isConnected: isConnected(anyProcess), + }); + + addReference(channel, reference); + const ipcEmitter = getIpcEmitter(anyProcess, channel, isSubprocess); + const controller = new AbortController(); + const state = {}; + stopOnDisconnect(anyProcess, ipcEmitter, controller); + abortOnStrictError({ + ipcEmitter, + isSubprocess, + controller, + state, + }); + return iterateOnMessages({ + anyProcess, + channel, + ipcEmitter, + isSubprocess, + shouldAwait, + controller, + state, + reference, + }); +}; + +const stopOnDisconnect = async (anyProcess, ipcEmitter, controller) => { + try { + await once$2(ipcEmitter, 'disconnect', {signal: controller.signal}); + controller.abort(); + } catch {} +}; + +const abortOnStrictError = async ({ipcEmitter, isSubprocess, controller, state}) => { + try { + const [error] = await once$2(ipcEmitter, 'strict:error', {signal: controller.signal}); + state.error = getStrictResponseError(error, isSubprocess); + controller.abort(); + } catch {} +}; + +const iterateOnMessages = async function * ({anyProcess, channel, ipcEmitter, isSubprocess, shouldAwait, controller, state, reference}) { + try { + for await (const [message] of on(ipcEmitter, 'message', {signal: controller.signal})) { + throwIfStrictError(state); + yield message; + } + } catch { + throwIfStrictError(state); + } finally { + controller.abort(); + removeReference(channel, reference); + + if (!isSubprocess) { + disconnect(anyProcess); + } + + if (shouldAwait) { + await anyProcess; + } + } +}; + +const throwIfStrictError = ({error}) => { + if (error) { + throw error; + } +}; + +// Add promise-based IPC methods in current process +const addIpcMethods = (subprocess, {ipc}) => { + Object.assign(subprocess, getIpcMethods(subprocess, false, ipc)); +}; + +// Get promise-based IPC in the subprocess +const getIpcExport = () => { + const anyProcess = process$2; + const isSubprocess = true; + const ipc = process$2.channel !== undefined; + + return { + ...getIpcMethods(anyProcess, isSubprocess, ipc), + getCancelSignal: getCancelSignal.bind(undefined, { + anyProcess, + channel: anyProcess.channel, + isSubprocess, + ipc, + }), + }; +}; + +// Retrieve the `ipc` shared by both the current process and the subprocess +const getIpcMethods = (anyProcess, isSubprocess, ipc) => ({ + sendMessage: sendMessage.bind(undefined, { + anyProcess, + channel: anyProcess.channel, + isSubprocess, + ipc, + }), + getOneMessage: getOneMessage.bind(undefined, { + anyProcess, + channel: anyProcess.channel, + isSubprocess, + ipc, + }), + getEachMessage: getEachMessage.bind(undefined, { + anyProcess, + channel: anyProcess.channel, + isSubprocess, + ipc, + }), +}); + +// When the subprocess fails to spawn. +// We ensure the returned error is always both a promise and a subprocess. +const handleEarlyError = ({error, command, escapedCommand, fileDescriptors, options, startTime, verboseInfo}) => { + cleanupCustomStreams(fileDescriptors); + + const subprocess = new ChildProcess(); + createDummyStreams(subprocess, fileDescriptors); + Object.assign(subprocess, {readable: readable$1, writable, duplex}); + + const earlyError = makeEarlyError({ + error, + command, + escapedCommand, + fileDescriptors, + options, + startTime, + isSync: false, + }); + const promise = handleDummyPromise(earlyError, verboseInfo, options); + return {subprocess, promise}; +}; + +const createDummyStreams = (subprocess, fileDescriptors) => { + const stdin = createDummyStream(); + const stdout = createDummyStream(); + const stderr = createDummyStream(); + const extraStdio = Array.from({length: fileDescriptors.length - 3}, createDummyStream); + const all = createDummyStream(); + const stdio = [stdin, stdout, stderr, ...extraStdio]; + Object.assign(subprocess, { + stdin, + stdout, + stderr, + all, + stdio, + }); +}; + +const createDummyStream = () => { + const stream = new PassThrough(); + stream.end(); + return stream; +}; + +const readable$1 = () => new Readable({read() {}}); +const writable = () => new Writable({write() {}}); +const duplex = () => new Duplex({read() {}, write() {}}); + +const handleDummyPromise = async (error, verboseInfo, options) => handleResult(error, verboseInfo, options); + +// Handle `input`, `inputFile`, `stdin`, `stdout` and `stderr` options, before spawning, in async mode +const handleStdioAsync = (options, verboseInfo) => handleStdio(addPropertiesAsync, options, verboseInfo, false); + +const forbiddenIfAsync = ({type, optionName}) => { + throw new TypeError(`The \`${optionName}\` option cannot be ${TYPE_TO_MESSAGE[type]}.`); +}; + +// Create streams used internally for piping when using specific values for the `std*` options, in async mode. +// For example, `stdout: {file}` creates a file stream, which is piped from/to. +const addProperties = { + fileNumber: forbiddenIfAsync, + generator: generatorToStream, + asyncGenerator: generatorToStream, + nodeStream: ({value}) => ({stream: value}), + webTransform({value: {transform, writableObjectMode, readableObjectMode}}) { + const objectMode = writableObjectMode || readableObjectMode; + const stream = Duplex.fromWeb(transform, {objectMode}); + return {stream}; + }, + duplex: ({value: {transform}}) => ({stream: transform}), + native() {}, +}; + +const addPropertiesAsync = { + input: { + ...addProperties, + fileUrl: ({value}) => ({stream: createReadStream(value)}), + filePath: ({value: {file}}) => ({stream: createReadStream(file)}), + webStream: ({value}) => ({stream: Readable.fromWeb(value)}), + iterable: ({value}) => ({stream: Readable.from(value)}), + asyncIterable: ({value}) => ({stream: Readable.from(value)}), + string: ({value}) => ({stream: Readable.from(value)}), + uint8Array: ({value}) => ({stream: Readable.from(Buffer$1.from(value))}), + }, + output: { + ...addProperties, + fileUrl: ({value}) => ({stream: createWriteStream(value)}), + filePath: ({value: {file, append}}) => ({stream: createWriteStream(file, append ? {flags: 'a'} : {})}), + webStream: ({value}) => ({stream: Writable.fromWeb(value)}), + iterable: forbiddenIfAsync, + asyncIterable: forbiddenIfAsync, + string: forbiddenIfAsync, + uint8Array: forbiddenIfAsync, + }, +}; + +function mergeStreams(streams) { + if (!Array.isArray(streams)) { + throw new TypeError(`Expected an array, got \`${typeof streams}\`.`); + } + + for (const stream of streams) { + validateStream(stream); + } + + const objectMode = streams.some(({readableObjectMode}) => readableObjectMode); + const highWaterMark = getHighWaterMark(streams, objectMode); + const passThroughStream = new MergedStream({ + objectMode, + writableHighWaterMark: highWaterMark, + readableHighWaterMark: highWaterMark, + }); + + for (const stream of streams) { + passThroughStream.add(stream); + } + + return passThroughStream; +} + +const getHighWaterMark = (streams, objectMode) => { + if (streams.length === 0) { + return getDefaultHighWaterMark(objectMode); + } + + const highWaterMarks = streams + .filter(({readableObjectMode}) => readableObjectMode === objectMode) + .map(({readableHighWaterMark}) => readableHighWaterMark); + return Math.max(...highWaterMarks); +}; + +class MergedStream extends PassThrough { + #streams = new Set([]); + #ended = new Set([]); + #aborted = new Set([]); + #onFinished; + #unpipeEvent = Symbol('unpipe'); + #streamPromises = new WeakMap(); + + add(stream) { + validateStream(stream); + + if (this.#streams.has(stream)) { + return; + } + + this.#streams.add(stream); + + this.#onFinished ??= onMergedStreamFinished(this, this.#streams, this.#unpipeEvent); + const streamPromise = endWhenStreamsDone({ + passThroughStream: this, + stream, + streams: this.#streams, + ended: this.#ended, + aborted: this.#aborted, + onFinished: this.#onFinished, + unpipeEvent: this.#unpipeEvent, + }); + this.#streamPromises.set(stream, streamPromise); + + stream.pipe(this, {end: false}); + } + + async remove(stream) { + validateStream(stream); + + if (!this.#streams.has(stream)) { + return false; + } + + const streamPromise = this.#streamPromises.get(stream); + if (streamPromise === undefined) { + return false; + } + + this.#streamPromises.delete(stream); + + stream.unpipe(this); + await streamPromise; + return true; + } +} + +const onMergedStreamFinished = async (passThroughStream, streams, unpipeEvent) => { + updateMaxListeners(passThroughStream, PASSTHROUGH_LISTENERS_COUNT); + const controller = new AbortController(); + + try { + await Promise.race([ + onMergedStreamEnd(passThroughStream, controller), + onInputStreamsUnpipe(passThroughStream, streams, unpipeEvent, controller), + ]); + } finally { + controller.abort(); + updateMaxListeners(passThroughStream, -PASSTHROUGH_LISTENERS_COUNT); + } +}; + +const onMergedStreamEnd = async (passThroughStream, {signal}) => { + try { + await finished(passThroughStream, {signal, cleanup: true}); + } catch (error) { + errorOrAbortStream(passThroughStream, error); + throw error; + } +}; + +const onInputStreamsUnpipe = async (passThroughStream, streams, unpipeEvent, {signal}) => { + for await (const [unpipedStream] of on(passThroughStream, 'unpipe', {signal})) { + if (streams.has(unpipedStream)) { + unpipedStream.emit(unpipeEvent); + } + } +}; + +const validateStream = stream => { + if (typeof stream?.pipe !== 'function') { + throw new TypeError(`Expected a readable stream, got: \`${typeof stream}\`.`); + } +}; + +const endWhenStreamsDone = async ({passThroughStream, stream, streams, ended, aborted, onFinished, unpipeEvent}) => { + updateMaxListeners(passThroughStream, PASSTHROUGH_LISTENERS_PER_STREAM); + const controller = new AbortController(); + + try { + await Promise.race([ + afterMergedStreamFinished(onFinished, stream, controller), + onInputStreamEnd({ + passThroughStream, + stream, + streams, + ended, + aborted, + controller, + }), + onInputStreamUnpipe({ + stream, + streams, + ended, + aborted, + unpipeEvent, + controller, + }), + ]); + } finally { + controller.abort(); + updateMaxListeners(passThroughStream, -PASSTHROUGH_LISTENERS_PER_STREAM); + } + + if (streams.size > 0 && streams.size === ended.size + aborted.size) { + if (ended.size === 0 && aborted.size > 0) { + abortStream(passThroughStream); + } else { + endStream(passThroughStream); + } + } +}; + +const afterMergedStreamFinished = async (onFinished, stream, {signal}) => { + try { + await onFinished; + if (!signal.aborted) { + abortStream(stream); + } + } catch (error) { + if (!signal.aborted) { + errorOrAbortStream(stream, error); + } + } +}; + +const onInputStreamEnd = async ({passThroughStream, stream, streams, ended, aborted, controller: {signal}}) => { + try { + await finished(stream, { + signal, + cleanup: true, + readable: true, + writable: false, + }); + if (streams.has(stream)) { + ended.add(stream); + } + } catch (error) { + if (signal.aborted || !streams.has(stream)) { + return; + } + + if (isAbortError(error)) { + aborted.add(stream); + } else { + errorStream(passThroughStream, error); + } + } +}; + +const onInputStreamUnpipe = async ({stream, streams, ended, aborted, unpipeEvent, controller: {signal}}) => { + await once$2(stream, unpipeEvent, {signal}); + + if (!stream.readable) { + return once$2(signal, 'abort', {signal}); + } + + streams.delete(stream); + ended.delete(stream); + aborted.delete(stream); +}; + +const endStream = stream => { + if (stream.writable) { + stream.end(); + } +}; + +const errorOrAbortStream = (stream, error) => { + if (isAbortError(error)) { + abortStream(stream); + } else { + errorStream(stream, error); + } +}; + +// This is the error thrown by `finished()` on `stream.destroy()` +const isAbortError = error => error?.code === 'ERR_STREAM_PREMATURE_CLOSE'; + +const abortStream = stream => { + if (stream.readable || stream.writable) { + stream.destroy(); + } +}; + +// `stream.destroy(error)` crashes the process with `uncaughtException` if no `error` event listener exists on `stream`. +// We take care of error handling on user behalf, so we do not want this to happen. +const errorStream = (stream, error) => { + if (!stream.destroyed) { + stream.once('error', noop); + stream.destroy(error); + } +}; + +const noop = () => {}; + +const updateMaxListeners = (passThroughStream, increment) => { + const maxListeners = passThroughStream.getMaxListeners(); + if (maxListeners !== 0 && maxListeners !== Number.POSITIVE_INFINITY) { + passThroughStream.setMaxListeners(maxListeners + increment); + } +}; + +// Number of times `passThroughStream.on()` is called regardless of streams: +// - once due to `finished(passThroughStream)` +// - once due to `on(passThroughStream)` +const PASSTHROUGH_LISTENERS_COUNT = 2; + +// Number of times `passThroughStream.on()` is called per stream: +// - once due to `stream.pipe(passThroughStream)` +const PASSTHROUGH_LISTENERS_PER_STREAM = 1; + +// Similar to `Stream.pipeline(source, destination)`, but does not destroy standard streams +const pipeStreams = (source, destination) => { + source.pipe(destination); + onSourceFinish(source, destination); + onDestinationFinish(source, destination); +}; + +// `source.pipe(destination)` makes `destination` end when `source` ends. +// But it does not propagate aborts or errors. This function does it. +const onSourceFinish = async (source, destination) => { + if (isStandardStream(source) || isStandardStream(destination)) { + return; + } + + try { + await finished(source, {cleanup: true, readable: true, writable: false}); + } catch {} + + endDestinationStream(destination); +}; + +const endDestinationStream = destination => { + if (destination.writable) { + destination.end(); + } +}; + +// We do the same thing in the other direction as well. +const onDestinationFinish = async (source, destination) => { + if (isStandardStream(source) || isStandardStream(destination)) { + return; + } + + try { + await finished(destination, {cleanup: true, readable: false, writable: true}); + } catch {} + + abortSourceStream(source); +}; + +const abortSourceStream = source => { + if (source.readable) { + source.destroy(); + } +}; + +// Handle `input`, `inputFile`, `stdin`, `stdout` and `stderr` options, after spawning, in async mode +// When multiple input streams are used, we merge them to ensure the output stream ends only once each input stream has ended +const pipeOutputAsync = (subprocess, fileDescriptors, controller) => { + const pipeGroups = new Map(); + + for (const [fdNumber, {stdioItems, direction}] of Object.entries(fileDescriptors)) { + for (const {stream} of stdioItems.filter(({type}) => TRANSFORM_TYPES.has(type))) { + pipeTransform(subprocess, stream, direction, fdNumber); + } + + for (const {stream} of stdioItems.filter(({type}) => !TRANSFORM_TYPES.has(type))) { + pipeStdioItem({ + subprocess, + stream, + direction, + fdNumber, + pipeGroups, + controller, + }); + } + } + + for (const [outputStream, inputStreams] of pipeGroups.entries()) { + const inputStream = inputStreams.length === 1 ? inputStreams[0] : mergeStreams(inputStreams); + pipeStreams(inputStream, outputStream); + } +}; + +// When using transforms, `subprocess.stdin|stdout|stderr|stdio` is directly mutated +const pipeTransform = (subprocess, stream, direction, fdNumber) => { + if (direction === 'output') { + pipeStreams(subprocess.stdio[fdNumber], stream); + } else { + pipeStreams(stream, subprocess.stdio[fdNumber]); + } + + const streamProperty = SUBPROCESS_STREAM_PROPERTIES[fdNumber]; + if (streamProperty !== undefined) { + subprocess[streamProperty] = stream; + } + + subprocess.stdio[fdNumber] = stream; +}; + +const SUBPROCESS_STREAM_PROPERTIES = ['stdin', 'stdout', 'stderr']; + +// Most `std*` option values involve piping `subprocess.std*` to a stream. +// The stream is either passed by the user or created internally. +const pipeStdioItem = ({subprocess, stream, direction, fdNumber, pipeGroups, controller}) => { + if (stream === undefined) { + return; + } + + setStandardStreamMaxListeners(stream, controller); + + const [inputStream, outputStream] = direction === 'output' + ? [stream, subprocess.stdio[fdNumber]] + : [subprocess.stdio[fdNumber], stream]; + const outputStreams = pipeGroups.get(inputStream) ?? []; + pipeGroups.set(inputStream, [...outputStreams, outputStream]); +}; + +// Multiple subprocesses might be piping from/to `process.std*` at the same time. +// This is not necessarily an error and should not print a `maxListeners` warning. +const setStandardStreamMaxListeners = (stream, {signal}) => { + if (isStandardStream(stream)) { + incrementMaxListeners(stream, MAX_LISTENERS_INCREMENT, signal); + } +}; + +// `source.pipe(destination)` adds at most 1 listener for each event. +// If `stdin` option is an array, the values might be combined with `merge-streams`. +// That library also listens for `source` end, which adds 1 more listener. +const MAX_LISTENERS_INCREMENT = 2; + +/** + * This is not the set of all possible signals. + * + * It IS, however, the set of all signals that trigger + * an exit on either Linux or BSD systems. Linux is a + * superset of the signal names supported on BSD, and + * the unknown signals just fail to register, so we can + * catch that easily enough. + * + * Windows signals are a different set, since there are + * signals that terminate Windows processes, but don't + * terminate (or don't even exist) on Posix systems. + * + * Don't bother with SIGKILL. It's uncatchable, which + * means that we can't fire any callbacks anyway. + * + * If a user does happen to register a handler on a non- + * fatal signal like SIGWINCH or something, and then + * exit, it'll end up firing `process.emit('exit')`, so + * the handler will be fired anyway. + * + * SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised + * artificially, inherently leave the process in a + * state from which it is not safe to try and enter JS + * listeners. + */ +const signals = []; +signals.push('SIGHUP', 'SIGINT', 'SIGTERM'); +if (process.platform !== 'win32') { + signals.push('SIGALRM', 'SIGABRT', 'SIGVTALRM', 'SIGXCPU', 'SIGXFSZ', 'SIGUSR2', 'SIGTRAP', 'SIGSYS', 'SIGQUIT', 'SIGIOT' + // should detect profiler and enable/disable accordingly. + // see #21 + // 'SIGPROF' + ); +} +if (process.platform === 'linux') { + signals.push('SIGIO', 'SIGPOLL', 'SIGPWR', 'SIGSTKFLT'); +} + +// Note: since nyc uses this module to output coverage, any lines +// that are in the direct sync flow of nyc's outputCoverage are +// ignored, since we can never get coverage for them. +// grab a reference to node's real process object right away +const processOk = (process) => !!process && + typeof process === 'object' && + typeof process.removeListener === 'function' && + typeof process.emit === 'function' && + typeof process.reallyExit === 'function' && + typeof process.listeners === 'function' && + typeof process.kill === 'function' && + typeof process.pid === 'number' && + typeof process.on === 'function'; +const kExitEmitter = Symbol.for('signal-exit emitter'); +const global$3 = globalThis; +const ObjectDefineProperty = Object.defineProperty.bind(Object); +// teeny special purpose ee +class Emitter { + emitted = { + afterExit: false, + exit: false, + }; + listeners = { + afterExit: [], + exit: [], + }; + count = 0; + id = Math.random(); + constructor() { + if (global$3[kExitEmitter]) { + return global$3[kExitEmitter]; + } + ObjectDefineProperty(global$3, kExitEmitter, { + value: this, + writable: false, + enumerable: false, + configurable: false, + }); + } + on(ev, fn) { + this.listeners[ev].push(fn); + } + removeListener(ev, fn) { + const list = this.listeners[ev]; + const i = list.indexOf(fn); + /* c8 ignore start */ + if (i === -1) { + return; + } + /* c8 ignore stop */ + if (i === 0 && list.length === 1) { + list.length = 0; + } + else { + list.splice(i, 1); + } + } + emit(ev, code, signal) { + if (this.emitted[ev]) { + return false; + } + this.emitted[ev] = true; + let ret = false; + for (const fn of this.listeners[ev]) { + ret = fn(code, signal) === true || ret; + } + if (ev === 'exit') { + ret = this.emit('afterExit', code, signal) || ret; + } + return ret; + } +} +class SignalExitBase { +} +const signalExitWrap = (handler) => { + return { + onExit(cb, opts) { + return handler.onExit(cb, opts); + }, + load() { + return handler.load(); + }, + unload() { + return handler.unload(); + }, + }; +}; +class SignalExitFallback extends SignalExitBase { + onExit() { + return () => { }; + } + load() { } + unload() { } +} +class SignalExit extends SignalExitBase { + // "SIGHUP" throws an `ENOSYS` error on Windows, + // so use a supported signal instead + /* c8 ignore start */ + #hupSig = process$1.platform === 'win32' ? 'SIGINT' : 'SIGHUP'; + /* c8 ignore stop */ + #emitter = new Emitter(); + #process; + #originalProcessEmit; + #originalProcessReallyExit; + #sigListeners = {}; + #loaded = false; + constructor(process) { + super(); + this.#process = process; + // { : , ... } + this.#sigListeners = {}; + for (const sig of signals) { + this.#sigListeners[sig] = () => { + // If there are no other listeners, an exit is coming! + // Simplest way: remove us and then re-send the signal. + // We know that this will kill the process, so we can + // safely emit now. + const listeners = this.#process.listeners(sig); + let { count } = this.#emitter; + // This is a workaround for the fact that signal-exit v3 and signal + // exit v4 are not aware of each other, and each will attempt to let + // the other handle it, so neither of them do. To correct this, we + // detect if we're the only handler *except* for previous versions + // of signal-exit, and increment by the count of listeners it has + // created. + /* c8 ignore start */ + const p = process; + if (typeof p.__signal_exit_emitter__ === 'object' && + typeof p.__signal_exit_emitter__.count === 'number') { + count += p.__signal_exit_emitter__.count; + } + /* c8 ignore stop */ + if (listeners.length === count) { + this.unload(); + const ret = this.#emitter.emit('exit', null, sig); + /* c8 ignore start */ + const s = sig === 'SIGHUP' ? this.#hupSig : sig; + if (!ret) + process.kill(process.pid, s); + /* c8 ignore stop */ + } + }; + } + this.#originalProcessReallyExit = process.reallyExit; + this.#originalProcessEmit = process.emit; + } + onExit(cb, opts) { + /* c8 ignore start */ + if (!processOk(this.#process)) { + return () => { }; + } + /* c8 ignore stop */ + if (this.#loaded === false) { + this.load(); + } + const ev = opts?.alwaysLast ? 'afterExit' : 'exit'; + this.#emitter.on(ev, cb); + return () => { + this.#emitter.removeListener(ev, cb); + if (this.#emitter.listeners['exit'].length === 0 && + this.#emitter.listeners['afterExit'].length === 0) { + this.unload(); + } + }; + } + load() { + if (this.#loaded) { + return; + } + this.#loaded = true; + // This is the number of onSignalExit's that are in play. + // It's important so that we can count the correct number of + // listeners on signals, and don't wait for the other one to + // handle it instead of us. + this.#emitter.count += 1; + for (const sig of signals) { + try { + const fn = this.#sigListeners[sig]; + if (fn) + this.#process.on(sig, fn); + } + catch (_) { } + } + this.#process.emit = (ev, ...a) => { + return this.#processEmit(ev, ...a); + }; + this.#process.reallyExit = (code) => { + return this.#processReallyExit(code); + }; + } + unload() { + if (!this.#loaded) { + return; + } + this.#loaded = false; + signals.forEach(sig => { + const listener = this.#sigListeners[sig]; + /* c8 ignore start */ + if (!listener) { + throw new Error('Listener not defined for signal: ' + sig); + } + /* c8 ignore stop */ + try { + this.#process.removeListener(sig, listener); + /* c8 ignore start */ + } + catch (_) { } + /* c8 ignore stop */ + }); + this.#process.emit = this.#originalProcessEmit; + this.#process.reallyExit = this.#originalProcessReallyExit; + this.#emitter.count -= 1; + } + #processReallyExit(code) { + /* c8 ignore start */ + if (!processOk(this.#process)) { + return 0; + } + this.#process.exitCode = code || 0; + /* c8 ignore stop */ + this.#emitter.emit('exit', this.#process.exitCode, null); + return this.#originalProcessReallyExit.call(this.#process, this.#process.exitCode); + } + #processEmit(ev, ...args) { + const og = this.#originalProcessEmit; + if (ev === 'exit' && processOk(this.#process)) { + if (typeof args[0] === 'number') { + this.#process.exitCode = args[0]; + /* c8 ignore start */ + } + /* c8 ignore start */ + const ret = og.call(this.#process, ev, ...args); + /* c8 ignore start */ + this.#emitter.emit('exit', this.#process.exitCode, null); + /* c8 ignore stop */ + return ret; + } + else { + return og.call(this.#process, ev, ...args); + } + } +} +const process$1 = globalThis.process; +// wrap so that we call the method on the actual handler, without +// exporting it directly. +const { +/** + * Called when the process is exiting, whether via signal, explicit + * exit, or running out of stuff to do. + * + * If the global process object is not suitable for instrumentation, + * then this will be a no-op. + * + * Returns a function that may be used to unload signal-exit. + */ +onExit} = signalExitWrap(processOk(process$1) ? new SignalExit(process$1) : new SignalExitFallback()); + +// If the `cleanup` option is used, call `subprocess.kill()` when the parent process exits +const cleanupOnExit = (subprocess, {cleanup, detached}, {signal}) => { + if (!cleanup || detached) { + return; + } + + const removeExitHandler = onExit(() => { + subprocess.kill(); + }); + addAbortListener(signal, () => { + removeExitHandler(); + }); +}; + +// Normalize and validate arguments passed to `source.pipe(destination)` +const normalizePipeArguments = ({source, sourcePromise, boundOptions, createNested}, ...pipeArguments) => { + const startTime = getStartTime(); + const { + destination, + destinationStream, + destinationError, + from, + unpipeSignal, + } = getDestinationStream(boundOptions, createNested, pipeArguments); + const {sourceStream, sourceError} = getSourceStream(source, from); + const {options: sourceOptions, fileDescriptors} = SUBPROCESS_OPTIONS.get(source); + return { + sourcePromise, + sourceStream, + sourceOptions, + sourceError, + destination, + destinationStream, + destinationError, + unpipeSignal, + fileDescriptors, + startTime, + }; +}; + +const getDestinationStream = (boundOptions, createNested, pipeArguments) => { + try { + const { + destination, + pipeOptions: {from, to, unpipeSignal} = {}, + } = getDestination(boundOptions, createNested, ...pipeArguments); + const destinationStream = getToStream(destination, to); + return { + destination, + destinationStream, + from, + unpipeSignal, + }; + } catch (error) { + return {destinationError: error}; + } +}; + +// Piping subprocesses can use three syntaxes: +// - source.pipe('command', commandArguments, pipeOptionsOrDestinationOptions) +// - source.pipe`command commandArgument` or source.pipe(pipeOptionsOrDestinationOptions)`command commandArgument` +// - source.pipe(execa(...), pipeOptions) +const getDestination = (boundOptions, createNested, firstArgument, ...pipeArguments) => { + if (Array.isArray(firstArgument)) { + const destination = createNested(mapDestinationArguments, boundOptions)(firstArgument, ...pipeArguments); + return {destination, pipeOptions: boundOptions}; + } + + if (typeof firstArgument === 'string' || firstArgument instanceof URL || isDenoExecPath(firstArgument)) { + if (Object.keys(boundOptions).length > 0) { + throw new TypeError('Please use .pipe("file", ..., options) or .pipe(execa("file", ..., options)) instead of .pipe(options)("file", ...).'); + } + + const [rawFile, rawArguments, rawOptions] = normalizeParameters(firstArgument, ...pipeArguments); + const destination = createNested(mapDestinationArguments)(rawFile, rawArguments, rawOptions); + return {destination, pipeOptions: rawOptions}; + } + + if (SUBPROCESS_OPTIONS.has(firstArgument)) { + if (Object.keys(boundOptions).length > 0) { + throw new TypeError('Please use .pipe(options)`command` or .pipe($(options)`command`) instead of .pipe(options)($`command`).'); + } + + return {destination: firstArgument, pipeOptions: pipeArguments[0]}; + } + + throw new TypeError(`The first argument must be a template string, an options object, or an Execa subprocess: ${firstArgument}`); +}; + +// Force `stdin: 'pipe'` with the destination subprocess +const mapDestinationArguments = ({options}) => ({options: {...options, stdin: 'pipe', piped: true}}); + +const getSourceStream = (source, from) => { + try { + const sourceStream = getFromStream(source, from); + return {sourceStream}; + } catch (error) { + return {sourceError: error}; + } +}; + +// When passing invalid arguments to `source.pipe()`, throw asynchronously. +// We also abort both subprocesses. +const handlePipeArgumentsError = ({ + sourceStream, + sourceError, + destinationStream, + destinationError, + fileDescriptors, + sourceOptions, + startTime, +}) => { + const error = getPipeArgumentsError({ + sourceStream, + sourceError, + destinationStream, + destinationError, + }); + if (error !== undefined) { + throw createNonCommandError({ + error, + fileDescriptors, + sourceOptions, + startTime, + }); + } +}; + +const getPipeArgumentsError = ({sourceStream, sourceError, destinationStream, destinationError}) => { + if (sourceError !== undefined && destinationError !== undefined) { + return destinationError; + } + + if (destinationError !== undefined) { + abortSourceStream(sourceStream); + return destinationError; + } + + if (sourceError !== undefined) { + endDestinationStream(destinationStream); + return sourceError; + } +}; + +// Specific error return value when passing invalid arguments to `subprocess.pipe()` or when using `unpipeSignal` +const createNonCommandError = ({error, fileDescriptors, sourceOptions, startTime}) => makeEarlyError({ + error, + command: PIPE_COMMAND_MESSAGE, + escapedCommand: PIPE_COMMAND_MESSAGE, + fileDescriptors, + options: sourceOptions, + startTime, + isSync: false, +}); + +const PIPE_COMMAND_MESSAGE = 'source.pipe(destination)'; + +// Like Bash, we await both subprocesses. This is unlike some other shells which only await the destination subprocess. +// Like Bash with the `pipefail` option, if either subprocess fails, the whole pipe fails. +// Like Bash, if both subprocesses fail, we return the failure of the destination. +// This ensures both subprocesses' errors are present, using `error.pipedFrom`. +const waitForBothSubprocesses = async subprocessPromises => { + const [ + {status: sourceStatus, reason: sourceReason, value: sourceResult = sourceReason}, + {status: destinationStatus, reason: destinationReason, value: destinationResult = destinationReason}, + ] = await subprocessPromises; + + if (!destinationResult.pipedFrom.includes(sourceResult)) { + destinationResult.pipedFrom.push(sourceResult); + } + + if (destinationStatus === 'rejected') { + throw destinationResult; + } + + if (sourceStatus === 'rejected') { + throw sourceResult; + } + + return destinationResult; +}; + +// The piping behavior is like Bash. +// In particular, when one subprocess exits, the other is not terminated by a signal. +// Instead, its stdout (for the source) or stdin (for the destination) closes. +// If the subprocess uses it, it will make it error with SIGPIPE or EPIPE (for the source) or end (for the destination). +// If it does not use it, it will continue running. +// This allows for subprocesses to gracefully exit and lower the coupling between subprocesses. +const pipeSubprocessStream = (sourceStream, destinationStream, maxListenersController) => { + const mergedStream = MERGED_STREAMS.has(destinationStream) + ? pipeMoreSubprocessStream(sourceStream, destinationStream) + : pipeFirstSubprocessStream(sourceStream, destinationStream); + incrementMaxListeners(sourceStream, SOURCE_LISTENERS_PER_PIPE, maxListenersController.signal); + incrementMaxListeners(destinationStream, DESTINATION_LISTENERS_PER_PIPE, maxListenersController.signal); + cleanupMergedStreamsMap(destinationStream); + return mergedStream; +}; + +// We use `merge-streams` to allow for multiple sources to pipe to the same destination. +const pipeFirstSubprocessStream = (sourceStream, destinationStream) => { + const mergedStream = mergeStreams([sourceStream]); + pipeStreams(mergedStream, destinationStream); + MERGED_STREAMS.set(destinationStream, mergedStream); + return mergedStream; +}; + +const pipeMoreSubprocessStream = (sourceStream, destinationStream) => { + const mergedStream = MERGED_STREAMS.get(destinationStream); + mergedStream.add(sourceStream); + return mergedStream; +}; + +const cleanupMergedStreamsMap = async destinationStream => { + try { + await finished(destinationStream, {cleanup: true, readable: false, writable: true}); + } catch {} + + MERGED_STREAMS.delete(destinationStream); +}; + +const MERGED_STREAMS = new WeakMap(); + +// Number of listeners set up on `sourceStream` by each `sourceStream.pipe(destinationStream)` +// Those are added by `merge-streams` +const SOURCE_LISTENERS_PER_PIPE = 2; +// Number of listeners set up on `destinationStream` by each `sourceStream.pipe(destinationStream)` +// Those are added by `finished()` in `cleanupMergedStreamsMap()` +const DESTINATION_LISTENERS_PER_PIPE = 1; + +// When passing an `unpipeSignal` option, abort piping when the signal is aborted. +// However, do not terminate the subprocesses. +const unpipeOnAbort = (unpipeSignal, unpipeContext) => unpipeSignal === undefined + ? [] + : [unpipeOnSignalAbort(unpipeSignal, unpipeContext)]; + +const unpipeOnSignalAbort = async (unpipeSignal, {sourceStream, mergedStream, fileDescriptors, sourceOptions, startTime}) => { + await aborted(unpipeSignal, sourceStream); + await mergedStream.remove(sourceStream); + const error = new Error('Pipe canceled by `unpipeSignal` option.'); + throw createNonCommandError({ + error, + fileDescriptors, + sourceOptions, + startTime, + }); +}; + +// Pipe a subprocess' `stdout`/`stderr`/`stdio` into another subprocess' `stdin` +const pipeToSubprocess = (sourceInfo, ...pipeArguments) => { + if (isPlainObject(pipeArguments[0])) { + return pipeToSubprocess.bind(undefined, { + ...sourceInfo, + boundOptions: {...sourceInfo.boundOptions, ...pipeArguments[0]}, + }); + } + + const {destination, ...normalizedInfo} = normalizePipeArguments(sourceInfo, ...pipeArguments); + const promise = handlePipePromise({...normalizedInfo, destination}); + promise.pipe = pipeToSubprocess.bind(undefined, { + ...sourceInfo, + source: destination, + sourcePromise: promise, + boundOptions: {}, + }); + return promise; +}; + +// Asynchronous logic when piping subprocesses +const handlePipePromise = async ({ + sourcePromise, + sourceStream, + sourceOptions, + sourceError, + destination, + destinationStream, + destinationError, + unpipeSignal, + fileDescriptors, + startTime, +}) => { + const subprocessPromises = getSubprocessPromises(sourcePromise, destination); + handlePipeArgumentsError({ + sourceStream, + sourceError, + destinationStream, + destinationError, + fileDescriptors, + sourceOptions, + startTime, + }); + const maxListenersController = new AbortController(); + try { + const mergedStream = pipeSubprocessStream(sourceStream, destinationStream, maxListenersController); + return await Promise.race([ + waitForBothSubprocesses(subprocessPromises), + ...unpipeOnAbort(unpipeSignal, { + sourceStream, + mergedStream, + sourceOptions, + fileDescriptors, + startTime, + }), + ]); + } finally { + maxListenersController.abort(); + } +}; + +// `.pipe()` awaits the subprocess promises. +// When invalid arguments are passed to `.pipe()`, we throw an error, which prevents awaiting them. +// We need to ensure this does not create unhandled rejections. +const getSubprocessPromises = (sourcePromise, destination) => Promise.allSettled([sourcePromise, destination]); + +// Iterate over lines of `subprocess.stdout`, used by `subprocess.readable|duplex|iterable()` +const iterateOnSubprocessStream = ({subprocessStdout, subprocess, binary, shouldEncode, encoding, preserveNewlines}) => { + const controller = new AbortController(); + stopReadingOnExit(subprocess, controller); + return iterateOnStream({ + stream: subprocessStdout, + controller, + binary, + shouldEncode: !subprocessStdout.readableObjectMode && shouldEncode, + encoding, + shouldSplit: !subprocessStdout.readableObjectMode, + preserveNewlines, + }); +}; + +const stopReadingOnExit = async (subprocess, controller) => { + try { + await subprocess; + } catch {} finally { + controller.abort(); + } +}; + +// Iterate over lines of `subprocess.stdout`, used by `result.stdout` and the `verbose: 'full'` option. +// Applies the `lines` and `encoding` options. +const iterateForResult = ({stream, onStreamEnd, lines, encoding, stripFinalNewline, allMixed}) => { + const controller = new AbortController(); + stopReadingOnStreamEnd(onStreamEnd, controller, stream); + const objectMode = stream.readableObjectMode && !allMixed; + return iterateOnStream({ + stream, + controller, + binary: encoding === 'buffer', + shouldEncode: !objectMode, + encoding, + shouldSplit: !objectMode && lines, + preserveNewlines: !stripFinalNewline, + }); +}; + +const stopReadingOnStreamEnd = async (onStreamEnd, controller, stream) => { + try { + await onStreamEnd; + } catch { + stream.destroy(); + } finally { + controller.abort(); + } +}; + +const iterateOnStream = ({stream, controller, binary, shouldEncode, encoding, shouldSplit, preserveNewlines}) => { + const onStdoutChunk = on(stream, 'data', { + signal: controller.signal, + highWaterMark: HIGH_WATER_MARK, + // Backward compatibility with older name for this option + // See https://github.com/nodejs/node/pull/52080#discussion_r1525227861 + // @todo Remove after removing support for Node 21 + highWatermark: HIGH_WATER_MARK, + }); + return iterateOnData({ + onStdoutChunk, + controller, + binary, + shouldEncode, + encoding, + shouldSplit, + preserveNewlines, + }); +}; + +const DEFAULT_OBJECT_HIGH_WATER_MARK = getDefaultHighWaterMark(true); + +// The `highWaterMark` of `events.on()` is measured in number of events, not in bytes. +// Not knowing the average amount of bytes per `data` event, we use the same heuristic as streams in objectMode, since they have the same issue. +// Therefore, we use the value of `getDefaultHighWaterMark(true)`. +// Note: this option does not exist on Node 18, but this is ok since the logic works without it. It just consumes more memory. +const HIGH_WATER_MARK = DEFAULT_OBJECT_HIGH_WATER_MARK; + +const iterateOnData = async function * ({onStdoutChunk, controller, binary, shouldEncode, encoding, shouldSplit, preserveNewlines}) { + const generators = getGenerators({ + binary, + shouldEncode, + encoding, + shouldSplit, + preserveNewlines, + }); + + try { + for await (const [chunk] of onStdoutChunk) { + yield * transformChunkSync(chunk, generators, 0); + } + } catch (error) { + if (!controller.signal.aborted) { + throw error; + } + } finally { + yield * finalChunksSync(generators); + } +}; + +const getGenerators = ({binary, shouldEncode, encoding, shouldSplit, preserveNewlines}) => [ + getEncodingTransformGenerator(binary, encoding, !shouldEncode), + getSplitLinesGenerator(binary, preserveNewlines, !shouldSplit, {}), +].filter(Boolean); + +// Retrieve `result.stdout|stderr|all|stdio[*]` +const getStreamOutput = async ({stream, onStreamEnd, fdNumber, encoding, buffer, maxBuffer, lines, allMixed, stripFinalNewline, verboseInfo, streamInfo}) => { + const logPromise = logOutputAsync({ + stream, + onStreamEnd, + fdNumber, + encoding, + allMixed, + verboseInfo, + streamInfo, + }); + + if (!buffer) { + await Promise.all([resumeStream(stream), logPromise]); + return; + } + + const stripFinalNewlineValue = getStripFinalNewline(stripFinalNewline, fdNumber); + const iterable = iterateForResult({ + stream, + onStreamEnd, + lines, + encoding, + stripFinalNewline: stripFinalNewlineValue, + allMixed, + }); + const [output] = await Promise.all([ + getStreamContents({ + stream, + iterable, + fdNumber, + encoding, + maxBuffer, + lines, + }), + logPromise, + ]); + return output; +}; + +const logOutputAsync = async ({stream, onStreamEnd, fdNumber, encoding, allMixed, verboseInfo, streamInfo: {fileDescriptors}}) => { + if (!shouldLogOutput({ + stdioItems: fileDescriptors[fdNumber]?.stdioItems, + encoding, + verboseInfo, + fdNumber, + })) { + return; + } + + const linesIterable = iterateForResult({ + stream, + onStreamEnd, + lines: true, + encoding, + stripFinalNewline: true, + allMixed, + }); + await logLines(linesIterable, stream, fdNumber, verboseInfo); +}; + +// When using `buffer: false`, users need to read `subprocess.stdout|stderr|all` right away +// See https://github.com/sindresorhus/execa/issues/730 and https://github.com/sindresorhus/execa/pull/729#discussion_r1465496310 +const resumeStream = async stream => { + await setImmediate$1(); + if (stream.readableFlowing === null) { + stream.resume(); + } +}; + +const getStreamContents = async ({stream, stream: {readableObjectMode}, iterable, fdNumber, encoding, maxBuffer, lines}) => { + try { + if (readableObjectMode || lines) { + return await getStreamAsArray(iterable, {maxBuffer}); + } + + if (encoding === 'buffer') { + return new Uint8Array(await getStreamAsArrayBuffer(iterable, {maxBuffer})); + } + + return await getStreamAsString(iterable, {maxBuffer}); + } catch (error) { + return handleBufferedData(handleMaxBuffer({ + error, + stream, + readableObjectMode, + lines, + encoding, + fdNumber, + })); + } +}; + +// On failure, `result.stdout|stderr|all` should contain the currently buffered stream +// They are automatically closed and flushed by Node.js when the subprocess exits +// When `buffer` is `false`, `streamPromise` is `undefined` and there is no buffered data to retrieve +const getBufferedData = async streamPromise => { + try { + return await streamPromise; + } catch (error) { + return handleBufferedData(error); + } +}; + +// Ensure we are returning Uint8Arrays when using `encoding: 'buffer'` +const handleBufferedData = ({bufferedData}) => isArrayBuffer(bufferedData) + ? new Uint8Array(bufferedData) + : bufferedData; + +// Wraps `finished(stream)` to handle the following case: +// - When the subprocess exits, Node.js automatically calls `subprocess.stdin.destroy()`, which we need to ignore. +// - However, we still need to throw if `subprocess.stdin.destroy()` is called before subprocess exit. +const waitForStream = async (stream, fdNumber, streamInfo, {isSameDirection, stopOnExit = false} = {}) => { + const state = handleStdinDestroy(stream, streamInfo); + const abortController = new AbortController(); + try { + await Promise.race([ + ...(stopOnExit ? [streamInfo.exitPromise] : []), + finished(stream, {cleanup: true, signal: abortController.signal}), + ]); + } catch (error) { + if (!state.stdinCleanedUp) { + handleStreamError(error, fdNumber, streamInfo, isSameDirection); + } + } finally { + abortController.abort(); + } +}; + +// If `subprocess.stdin` is destroyed before being fully written to, it is considered aborted and should throw an error. +// This can happen for example when user called `subprocess.stdin.destroy()` before `subprocess.stdin.end()`. +// However, Node.js calls `subprocess.stdin.destroy()` on exit for cleanup purposes. +// https://github.com/nodejs/node/blob/0b4cdb4b42956cbd7019058e409e06700a199e11/lib/internal/child_process.js#L278 +// This is normal and should not throw an error. +// Therefore, we need to differentiate between both situations to know whether to throw an error. +// Unfortunately, events (`close`, `error`, `end`, `exit`) cannot be used because `.destroy()` can take an arbitrary amount of time. +// For example, `stdin: 'pipe'` is implemented as a TCP socket, and its `.destroy()` method waits for TCP disconnection. +// Therefore `.destroy()` might end before or after subprocess exit, based on OS speed and load. +// The only way to detect this is to spy on `subprocess.stdin._destroy()` by wrapping it. +// If `subprocess.exitCode` or `subprocess.signalCode` is set, it means `.destroy()` is being called by Node.js itself. +const handleStdinDestroy = (stream, {originalStreams: [originalStdin], subprocess}) => { + const state = {stdinCleanedUp: false}; + if (stream === originalStdin) { + spyOnStdinDestroy(stream, subprocess, state); + } + + return state; +}; + +const spyOnStdinDestroy = (subprocessStdin, subprocess, state) => { + const {_destroy} = subprocessStdin; + subprocessStdin._destroy = (...destroyArguments) => { + setStdinCleanedUp(subprocess, state); + _destroy.call(subprocessStdin, ...destroyArguments); + }; +}; + +const setStdinCleanedUp = ({exitCode, signalCode}, state) => { + if (exitCode !== null || signalCode !== null) { + state.stdinCleanedUp = true; + } +}; + +// We ignore EPIPEs on writable streams and aborts on readable streams since those can happen normally. +// When one stream errors, the error is propagated to the other streams on the same file descriptor. +// Those other streams might have a different direction due to the above. +// When this happens, the direction of both the initial stream and the others should then be taken into account. +// Therefore, we keep track of whether a stream error is currently propagating. +const handleStreamError = (error, fdNumber, streamInfo, isSameDirection) => { + if (!shouldIgnoreStreamError(error, fdNumber, streamInfo, isSameDirection)) { + throw error; + } +}; + +const shouldIgnoreStreamError = (error, fdNumber, streamInfo, isSameDirection = true) => { + if (streamInfo.propagating) { + return isStreamEpipe(error) || isStreamAbort(error); + } + + streamInfo.propagating = true; + return isInputFileDescriptor(streamInfo, fdNumber) === isSameDirection + ? isStreamEpipe(error) + : isStreamAbort(error); +}; + +// Unfortunately, we cannot use the stream's class or properties to know whether it is readable or writable. +// For example, `subprocess.stdin` is technically a Duplex, but can only be used as a writable. +// Therefore, we need to use the file descriptor's direction (`stdin` is input, `stdout` is output, etc.). +// However, while `subprocess.std*` and transforms follow that direction, any stream passed the `std*` option has the opposite direction. +// For example, `subprocess.stdin` is a writable, but the `stdin` option is a readable. +const isInputFileDescriptor = ({fileDescriptors}, fdNumber) => fdNumber !== 'all' && fileDescriptors[fdNumber].direction === 'input'; + +// When `stream.destroy()` is called without an `error` argument, stream is aborted. +// This is the only way to abort a readable stream, which can be useful in some instances. +// Therefore, we ignore this error on readable streams. +const isStreamAbort = error => error?.code === 'ERR_STREAM_PREMATURE_CLOSE'; + +// When `stream.write()` is called but the underlying source has been closed, `EPIPE` is emitted. +// When piping subprocesses, the source subprocess usually decides when to stop piping. +// However, there are some instances when the destination does instead, such as `... | head -n1`. +// It notifies the source by using `EPIPE`. +// Therefore, we ignore this error on writable streams. +const isStreamEpipe = error => error?.code === 'EPIPE'; + +// Read the contents of `subprocess.std*` and|or wait for its completion +const waitForStdioStreams = ({subprocess, encoding, buffer, maxBuffer, lines, stripFinalNewline, verboseInfo, streamInfo}) => subprocess.stdio.map((stream, fdNumber) => waitForSubprocessStream({ + stream, + fdNumber, + encoding, + buffer: buffer[fdNumber], + maxBuffer: maxBuffer[fdNumber], + lines: lines[fdNumber], + allMixed: false, + stripFinalNewline, + verboseInfo, + streamInfo, +})); + +// Read the contents of `subprocess.std*` or `subprocess.all` and|or wait for its completion +const waitForSubprocessStream = async ({stream, fdNumber, encoding, buffer, maxBuffer, lines, allMixed, stripFinalNewline, verboseInfo, streamInfo}) => { + if (!stream) { + return; + } + + const onStreamEnd = waitForStream(stream, fdNumber, streamInfo); + if (isInputFileDescriptor(streamInfo, fdNumber)) { + await onStreamEnd; + return; + } + + const [output] = await Promise.all([ + getStreamOutput({ + stream, + onStreamEnd, + fdNumber, + encoding, + buffer, + maxBuffer, + lines, + allMixed, + stripFinalNewline, + verboseInfo, + streamInfo, + }), + onStreamEnd, + ]); + return output; +}; + +// `all` interleaves `stdout` and `stderr` +const makeAllStream = ({stdout, stderr}, {all}) => all && (stdout || stderr) + ? mergeStreams([stdout, stderr].filter(Boolean)) + : undefined; + +// Read the contents of `subprocess.all` and|or wait for its completion +const waitForAllStream = ({subprocess, encoding, buffer, maxBuffer, lines, stripFinalNewline, verboseInfo, streamInfo}) => waitForSubprocessStream({ + ...getAllStream(subprocess, buffer), + fdNumber: 'all', + encoding, + maxBuffer: maxBuffer[1] + maxBuffer[2], + lines: lines[1] || lines[2], + allMixed: getAllMixed(subprocess), + stripFinalNewline, + verboseInfo, + streamInfo, +}); + +const getAllStream = ({stdout, stderr, all}, [, bufferStdout, bufferStderr]) => { + const buffer = bufferStdout || bufferStderr; + if (!buffer) { + return {stream: all, buffer}; + } + + if (!bufferStdout) { + return {stream: stderr, buffer}; + } + + if (!bufferStderr) { + return {stream: stdout, buffer}; + } + + return {stream: all, buffer}; +}; + +// When `subprocess.stdout` is in objectMode but not `subprocess.stderr` (or the opposite), we need to use both: +// - `getStreamAsArray()` for the chunks in objectMode, to return as an array without changing each chunk +// - `getStreamAsArrayBuffer()` or `getStream()` for the chunks not in objectMode, to convert them from Buffers to string or Uint8Array +// We do this by emulating the Buffer -> string|Uint8Array conversion performed by `get-stream` with our own, which is identical. +const getAllMixed = ({all, stdout, stderr}) => all + && stdout + && stderr + && stdout.readableObjectMode !== stderr.readableObjectMode; + +// When `verbose` is `'full'`, print IPC messages from the subprocess +const shouldLogIpc = verboseInfo => isFullVerbose(verboseInfo, 'ipc'); + +const logIpcOutput = (message, verboseInfo) => { + const verboseMessage = serializeVerboseMessage(message); + verboseLog({ + type: 'ipc', + verboseMessage, + fdNumber: 'ipc', + verboseInfo, + }); +}; + +// Iterate through IPC messages sent by the subprocess +const waitForIpcOutput = async ({ + subprocess, + buffer: bufferArray, + maxBuffer: maxBufferArray, + ipc, + ipcOutput, + verboseInfo, +}) => { + if (!ipc) { + return ipcOutput; + } + + const isVerbose = shouldLogIpc(verboseInfo); + const buffer = getFdSpecificValue(bufferArray, 'ipc'); + const maxBuffer = getFdSpecificValue(maxBufferArray, 'ipc'); + + for await (const message of loopOnMessages({ + anyProcess: subprocess, + channel: subprocess.channel, + isSubprocess: false, + ipc, + shouldAwait: false, + reference: true, + })) { + if (buffer) { + checkIpcMaxBuffer(subprocess, ipcOutput, maxBuffer); + ipcOutput.push(message); + } + + if (isVerbose) { + logIpcOutput(message, verboseInfo); + } + } + + return ipcOutput; +}; + +const getBufferedIpcOutput = async (ipcOutputPromise, ipcOutput) => { + await Promise.allSettled([ipcOutputPromise]); + return ipcOutput; +}; + +// Retrieve result of subprocess: exit code, signal, error, streams (stdout/stderr/all) +const waitForSubprocessResult = async ({ + subprocess, + options: { + encoding, + buffer, + maxBuffer, + lines, + timeoutDuration: timeout, + cancelSignal, + gracefulCancel, + forceKillAfterDelay, + stripFinalNewline, + ipc, + ipcInput, + }, + context, + verboseInfo, + fileDescriptors, + originalStreams, + onInternalError, + controller, +}) => { + const exitPromise = waitForExit(subprocess, context); + const streamInfo = { + originalStreams, + fileDescriptors, + subprocess, + exitPromise, + propagating: false, + }; + + const stdioPromises = waitForStdioStreams({ + subprocess, + encoding, + buffer, + maxBuffer, + lines, + stripFinalNewline, + verboseInfo, + streamInfo, + }); + const allPromise = waitForAllStream({ + subprocess, + encoding, + buffer, + maxBuffer, + lines, + stripFinalNewline, + verboseInfo, + streamInfo, + }); + const ipcOutput = []; + const ipcOutputPromise = waitForIpcOutput({ + subprocess, + buffer, + maxBuffer, + ipc, + ipcOutput, + verboseInfo, + }); + const originalPromises = waitForOriginalStreams(originalStreams, subprocess, streamInfo); + const customStreamsEndPromises = waitForCustomStreamsEnd(fileDescriptors, streamInfo); + + try { + return await Promise.race([ + Promise.all([ + {}, + waitForSuccessfulExit(exitPromise), + Promise.all(stdioPromises), + allPromise, + ipcOutputPromise, + sendIpcInput(subprocess, ipcInput), + ...originalPromises, + ...customStreamsEndPromises, + ]), + onInternalError, + throwOnSubprocessError(subprocess, controller), + ...throwOnTimeout(subprocess, timeout, context, controller), + ...throwOnCancel({ + subprocess, + cancelSignal, + gracefulCancel, + context, + controller, + }), + ...throwOnGracefulCancel({ + subprocess, + cancelSignal, + gracefulCancel, + forceKillAfterDelay, + context, + controller, + }), + ]); + } catch (error) { + context.terminationReason ??= 'other'; + return Promise.all([ + {error}, + exitPromise, + Promise.all(stdioPromises.map(stdioPromise => getBufferedData(stdioPromise))), + getBufferedData(allPromise), + getBufferedIpcOutput(ipcOutputPromise, ipcOutput), + Promise.allSettled(originalPromises), + Promise.allSettled(customStreamsEndPromises), + ]); + } +}; + +// Transforms replace `subprocess.std*`, which means they are not exposed to users. +// However, we still want to wait for their completion. +const waitForOriginalStreams = (originalStreams, subprocess, streamInfo) => + originalStreams.map((stream, fdNumber) => stream === subprocess.stdio[fdNumber] + ? undefined + : waitForStream(stream, fdNumber, streamInfo)); + +// Some `stdin`/`stdout`/`stderr` options create a stream, e.g. when passing a file path. +// The `.pipe()` method automatically ends that stream when `subprocess` ends. +// This makes sure we wait for the completion of those streams, in order to catch any error. +const waitForCustomStreamsEnd = (fileDescriptors, streamInfo) => fileDescriptors.flatMap(({stdioItems}, fdNumber) => stdioItems + .filter(({value, stream = value}) => isStream(stream, {checkOpen: false}) && !isStandardStream(stream)) + .map(({type, value, stream = value}) => waitForStream(stream, fdNumber, streamInfo, { + isSameDirection: TRANSFORM_TYPES.has(type), + stopOnExit: type === 'native', + }))); + +// Fails when the subprocess emits an `error` event +const throwOnSubprocessError = async (subprocess, {signal}) => { + const [error] = await once$2(subprocess, 'error', {signal}); + throw error; +}; + +// When using multiple `.readable()`/`.writable()`/`.duplex()`, `final` and `destroy` should wait for other streams +const initializeConcurrentStreams = () => ({ + readableDestroy: new WeakMap(), + writableFinal: new WeakMap(), + writableDestroy: new WeakMap(), +}); + +// Each file descriptor + `waitName` has its own array of promises. +// Each promise is a single `.readable()`/`.writable()`/`.duplex()` call. +const addConcurrentStream = (concurrentStreams, stream, waitName) => { + const weakMap = concurrentStreams[waitName]; + if (!weakMap.has(stream)) { + weakMap.set(stream, []); + } + + const promises = weakMap.get(stream); + const promise = createDeferred(); + promises.push(promise); + const resolve = promise.resolve.bind(promise); + return {resolve, promises}; +}; + +// Wait for other streams, but stop waiting when subprocess ends +const waitForConcurrentStreams = async ({resolve, promises}, subprocess) => { + resolve(); + const [isSubprocessExit] = await Promise.race([ + Promise.allSettled([true, subprocess]), + Promise.all([false, ...promises]), + ]); + return !isSubprocessExit; +}; + +const safeWaitForSubprocessStdin = async subprocessStdin => { + if (subprocessStdin === undefined) { + return; + } + + try { + await waitForSubprocessStdin(subprocessStdin); + } catch {} +}; + +const safeWaitForSubprocessStdout = async subprocessStdout => { + if (subprocessStdout === undefined) { + return; + } + + try { + await waitForSubprocessStdout(subprocessStdout); + } catch {} +}; + +const waitForSubprocessStdin = async subprocessStdin => { + await finished(subprocessStdin, {cleanup: true, readable: false, writable: true}); +}; + +const waitForSubprocessStdout = async subprocessStdout => { + await finished(subprocessStdout, {cleanup: true, readable: true, writable: false}); +}; + +// When `readable` or `writable` aborts/errors, awaits the subprocess, for the reason mentioned above +const waitForSubprocess = async (subprocess, error) => { + await subprocess; + if (error) { + throw error; + } +}; + +const destroyOtherStream = (stream, isOpen, error) => { + if (error && !isStreamAbort(error)) { + stream.destroy(error); + } else if (isOpen) { + stream.destroy(); + } +}; + +// Create a `Readable` stream that forwards from `stdout` and awaits the subprocess +const createReadable = ({subprocess, concurrentStreams, encoding}, {from, binary: binaryOption = true, preserveNewlines = true} = {}) => { + const binary = binaryOption || BINARY_ENCODINGS.has(encoding); + const {subprocessStdout, waitReadableDestroy} = getSubprocessStdout(subprocess, from, concurrentStreams); + const {readableEncoding, readableObjectMode, readableHighWaterMark} = getReadableOptions(subprocessStdout, binary); + const {read, onStdoutDataDone} = getReadableMethods({ + subprocessStdout, + subprocess, + binary, + encoding, + preserveNewlines, + }); + const readable = new Readable({ + read, + destroy: callbackify(onReadableDestroy.bind(undefined, {subprocessStdout, subprocess, waitReadableDestroy})), + highWaterMark: readableHighWaterMark, + objectMode: readableObjectMode, + encoding: readableEncoding, + }); + onStdoutFinished({ + subprocessStdout, + onStdoutDataDone, + readable, + subprocess, + }); + return readable; +}; + +// Retrieve `stdout` (or other stream depending on `from`) +const getSubprocessStdout = (subprocess, from, concurrentStreams) => { + const subprocessStdout = getFromStream(subprocess, from); + const waitReadableDestroy = addConcurrentStream(concurrentStreams, subprocessStdout, 'readableDestroy'); + return {subprocessStdout, waitReadableDestroy}; +}; + +const getReadableOptions = ({readableEncoding, readableObjectMode, readableHighWaterMark}, binary) => binary + ? {readableEncoding, readableObjectMode, readableHighWaterMark} + : {readableEncoding, readableObjectMode: true, readableHighWaterMark: DEFAULT_OBJECT_HIGH_WATER_MARK}; + +const getReadableMethods = ({subprocessStdout, subprocess, binary, encoding, preserveNewlines}) => { + const onStdoutDataDone = createDeferred(); + const onStdoutData = iterateOnSubprocessStream({ + subprocessStdout, + subprocess, + binary, + shouldEncode: !binary, + encoding, + preserveNewlines, + }); + + return { + read() { + onRead(this, onStdoutData, onStdoutDataDone); + }, + onStdoutDataDone, + }; +}; + +// Forwards data from `stdout` to `readable` +const onRead = async (readable, onStdoutData, onStdoutDataDone) => { + try { + const {value, done} = await onStdoutData.next(); + if (done) { + onStdoutDataDone.resolve(); + } else { + readable.push(value); + } + } catch {} +}; + +// When `subprocess.stdout` ends/aborts/errors, do the same on `readable`. +// Await the subprocess, for the same reason as above. +const onStdoutFinished = async ({subprocessStdout, onStdoutDataDone, readable, subprocess, subprocessStdin}) => { + try { + await waitForSubprocessStdout(subprocessStdout); + await subprocess; + await safeWaitForSubprocessStdin(subprocessStdin); + await onStdoutDataDone; + + if (readable.readable) { + readable.push(null); + } + } catch (error) { + await safeWaitForSubprocessStdin(subprocessStdin); + destroyOtherReadable(readable, error); + } +}; + +// When `readable` aborts/errors, do the same on `subprocess.stdout` +const onReadableDestroy = async ({subprocessStdout, subprocess, waitReadableDestroy}, error) => { + if (await waitForConcurrentStreams(waitReadableDestroy, subprocess)) { + destroyOtherReadable(subprocessStdout, error); + await waitForSubprocess(subprocess, error); + } +}; + +const destroyOtherReadable = (stream, error) => { + destroyOtherStream(stream, stream.readable, error); +}; + +// Create a `Writable` stream that forwards to `stdin` and awaits the subprocess +const createWritable = ({subprocess, concurrentStreams}, {to} = {}) => { + const {subprocessStdin, waitWritableFinal, waitWritableDestroy} = getSubprocessStdin(subprocess, to, concurrentStreams); + const writable = new Writable({ + ...getWritableMethods(subprocessStdin, subprocess, waitWritableFinal), + destroy: callbackify(onWritableDestroy.bind(undefined, { + subprocessStdin, + subprocess, + waitWritableFinal, + waitWritableDestroy, + })), + highWaterMark: subprocessStdin.writableHighWaterMark, + objectMode: subprocessStdin.writableObjectMode, + }); + onStdinFinished(subprocessStdin, writable); + return writable; +}; + +// Retrieve `stdin` (or other stream depending on `to`) +const getSubprocessStdin = (subprocess, to, concurrentStreams) => { + const subprocessStdin = getToStream(subprocess, to); + const waitWritableFinal = addConcurrentStream(concurrentStreams, subprocessStdin, 'writableFinal'); + const waitWritableDestroy = addConcurrentStream(concurrentStreams, subprocessStdin, 'writableDestroy'); + return {subprocessStdin, waitWritableFinal, waitWritableDestroy}; +}; + +const getWritableMethods = (subprocessStdin, subprocess, waitWritableFinal) => ({ + write: onWrite.bind(undefined, subprocessStdin), + final: callbackify(onWritableFinal.bind(undefined, subprocessStdin, subprocess, waitWritableFinal)), +}); + +// Forwards data from `writable` to `stdin` +const onWrite = (subprocessStdin, chunk, encoding, done) => { + if (subprocessStdin.write(chunk, encoding)) { + done(); + } else { + subprocessStdin.once('drain', done); + } +}; + +// Ensures that the writable `final` and readable `end` events awaits the subprocess. +// Like this, any subprocess failure is propagated as a stream `error` event, instead of being lost. +// The user does not need to `await` the subprocess anymore, but now needs to await the stream completion or error. +// When multiple writables are targeting the same stream, they wait for each other, unless the subprocess ends first. +const onWritableFinal = async (subprocessStdin, subprocess, waitWritableFinal) => { + if (await waitForConcurrentStreams(waitWritableFinal, subprocess)) { + if (subprocessStdin.writable) { + subprocessStdin.end(); + } + + await subprocess; + } +}; + +// When `subprocess.stdin` ends/aborts/errors, do the same on `writable`. +const onStdinFinished = async (subprocessStdin, writable, subprocessStdout) => { + try { + await waitForSubprocessStdin(subprocessStdin); + if (writable.writable) { + writable.end(); + } + } catch (error) { + await safeWaitForSubprocessStdout(subprocessStdout); + destroyOtherWritable(writable, error); + } +}; + +// When `writable` aborts/errors, do the same on `subprocess.stdin` +const onWritableDestroy = async ({subprocessStdin, subprocess, waitWritableFinal, waitWritableDestroy}, error) => { + await waitForConcurrentStreams(waitWritableFinal, subprocess); + if (await waitForConcurrentStreams(waitWritableDestroy, subprocess)) { + destroyOtherWritable(subprocessStdin, error); + await waitForSubprocess(subprocess, error); + } +}; + +const destroyOtherWritable = (stream, error) => { + destroyOtherStream(stream, stream.writable, error); +}; + +// Create a `Duplex` stream combining both `subprocess.readable()` and `subprocess.writable()` +const createDuplex = ({subprocess, concurrentStreams, encoding}, {from, to, binary: binaryOption = true, preserveNewlines = true} = {}) => { + const binary = binaryOption || BINARY_ENCODINGS.has(encoding); + const {subprocessStdout, waitReadableDestroy} = getSubprocessStdout(subprocess, from, concurrentStreams); + const {subprocessStdin, waitWritableFinal, waitWritableDestroy} = getSubprocessStdin(subprocess, to, concurrentStreams); + const {readableEncoding, readableObjectMode, readableHighWaterMark} = getReadableOptions(subprocessStdout, binary); + const {read, onStdoutDataDone} = getReadableMethods({ + subprocessStdout, + subprocess, + binary, + encoding, + preserveNewlines, + }); + const duplex = new Duplex({ + read, + ...getWritableMethods(subprocessStdin, subprocess, waitWritableFinal), + destroy: callbackify(onDuplexDestroy.bind(undefined, { + subprocessStdout, + subprocessStdin, + subprocess, + waitReadableDestroy, + waitWritableFinal, + waitWritableDestroy, + })), + readableHighWaterMark, + writableHighWaterMark: subprocessStdin.writableHighWaterMark, + readableObjectMode, + writableObjectMode: subprocessStdin.writableObjectMode, + encoding: readableEncoding, + }); + onStdoutFinished({ + subprocessStdout, + onStdoutDataDone, + readable: duplex, + subprocess, + subprocessStdin, + }); + onStdinFinished(subprocessStdin, duplex, subprocessStdout); + return duplex; +}; + +const onDuplexDestroy = async ({subprocessStdout, subprocessStdin, subprocess, waitReadableDestroy, waitWritableFinal, waitWritableDestroy}, error) => { + await Promise.all([ + onReadableDestroy({subprocessStdout, subprocess, waitReadableDestroy}, error), + onWritableDestroy({ + subprocessStdin, + subprocess, + waitWritableFinal, + waitWritableDestroy, + }, error), + ]); +}; + +// Convert the subprocess to an async iterable +const createIterable = (subprocess, encoding, { + from, + binary: binaryOption = false, + preserveNewlines = false, +} = {}) => { + const binary = binaryOption || BINARY_ENCODINGS.has(encoding); + const subprocessStdout = getFromStream(subprocess, from); + const onStdoutData = iterateOnSubprocessStream({ + subprocessStdout, + subprocess, + binary, + shouldEncode: true, + encoding, + preserveNewlines, + }); + return iterateOnStdoutData(onStdoutData, subprocessStdout, subprocess); +}; + +const iterateOnStdoutData = async function * (onStdoutData, subprocessStdout, subprocess) { + try { + yield * onStdoutData; + } finally { + if (subprocessStdout.readable) { + subprocessStdout.destroy(); + } + + await subprocess; + } +}; + +// Add methods to convert the subprocess to a stream or iterable +const addConvertedStreams = (subprocess, {encoding}) => { + const concurrentStreams = initializeConcurrentStreams(); + subprocess.readable = createReadable.bind(undefined, {subprocess, concurrentStreams, encoding}); + subprocess.writable = createWritable.bind(undefined, {subprocess, concurrentStreams}); + subprocess.duplex = createDuplex.bind(undefined, {subprocess, concurrentStreams, encoding}); + subprocess.iterable = createIterable.bind(undefined, subprocess, encoding); + subprocess[Symbol.asyncIterator] = createIterable.bind(undefined, subprocess, encoding, {}); +}; + +// The return value is a mixin of `subprocess` and `Promise` +const mergePromise = (subprocess, promise) => { + for (const [property, descriptor] of descriptors) { + const value = descriptor.value.bind(promise); + Reflect.defineProperty(subprocess, property, {...descriptor, value}); + } +}; + +// eslint-disable-next-line unicorn/prefer-top-level-await +const nativePromisePrototype = (async () => {})().constructor.prototype; + +const descriptors = ['then', 'catch', 'finally'].map(property => [ + property, + Reflect.getOwnPropertyDescriptor(nativePromisePrototype, property), +]); + +// Main shared logic for all async methods: `execa()`, `$`, `execaNode()` +const execaCoreAsync = (rawFile, rawArguments, rawOptions, createNested) => { + const {file, commandArguments, command, escapedCommand, startTime, verboseInfo, options, fileDescriptors} = handleAsyncArguments(rawFile, rawArguments, rawOptions); + const {subprocess, promise} = spawnSubprocessAsync({ + file, + commandArguments, + options, + startTime, + verboseInfo, + command, + escapedCommand, + fileDescriptors, + }); + subprocess.pipe = pipeToSubprocess.bind(undefined, { + source: subprocess, + sourcePromise: promise, + boundOptions: {}, + createNested, + }); + mergePromise(subprocess, promise); + SUBPROCESS_OPTIONS.set(subprocess, {options, fileDescriptors}); + return subprocess; +}; + +// Compute arguments to pass to `child_process.spawn()` +const handleAsyncArguments = (rawFile, rawArguments, rawOptions) => { + const {command, escapedCommand, startTime, verboseInfo} = handleCommand(rawFile, rawArguments, rawOptions); + const {file, commandArguments, options: normalizedOptions} = normalizeOptions(rawFile, rawArguments, rawOptions); + const options = handleAsyncOptions(normalizedOptions); + const fileDescriptors = handleStdioAsync(options, verboseInfo); + return { + file, + commandArguments, + command, + escapedCommand, + startTime, + verboseInfo, + options, + fileDescriptors, + }; +}; + +// Options normalization logic specific to async methods. +// Prevent passing the `timeout` option directly to `child_process.spawn()`. +const handleAsyncOptions = ({timeout, signal, ...options}) => { + if (signal !== undefined) { + throw new TypeError('The "signal" option has been renamed to "cancelSignal" instead.'); + } + + return {...options, timeoutDuration: timeout}; +}; + +const spawnSubprocessAsync = ({file, commandArguments, options, startTime, verboseInfo, command, escapedCommand, fileDescriptors}) => { + let subprocess; + try { + subprocess = spawn(...concatenateShell(file, commandArguments, options)); + } catch (error) { + return handleEarlyError({ + error, + command, + escapedCommand, + fileDescriptors, + options, + startTime, + verboseInfo, + }); + } + + const controller = new AbortController(); + setMaxListeners(Number.POSITIVE_INFINITY, controller.signal); + + const originalStreams = [...subprocess.stdio]; + pipeOutputAsync(subprocess, fileDescriptors, controller); + cleanupOnExit(subprocess, options, controller); + + const context = {}; + const onInternalError = createDeferred(); + subprocess.kill = subprocessKill.bind(undefined, { + kill: subprocess.kill.bind(subprocess), + options, + onInternalError, + context, + controller, + }); + subprocess.all = makeAllStream(subprocess, options); + addConvertedStreams(subprocess, options); + addIpcMethods(subprocess, options); + + const promise = handlePromise({ + subprocess, + options, + startTime, + verboseInfo, + fileDescriptors, + originalStreams, + command, + escapedCommand, + context, + onInternalError, + controller, + }); + return {subprocess, promise}; +}; + +// Asynchronous logic, as opposed to the previous logic which can be run synchronously, i.e. can be returned to user right away +const handlePromise = async ({subprocess, options, startTime, verboseInfo, fileDescriptors, originalStreams, command, escapedCommand, context, onInternalError, controller}) => { + const [ + errorInfo, + [exitCode, signal], + stdioResults, + allResult, + ipcOutput, + ] = await waitForSubprocessResult({ + subprocess, + options, + context, + verboseInfo, + fileDescriptors, + originalStreams, + onInternalError, + controller, + }); + controller.abort(); + onInternalError.resolve(); + + const stdio = stdioResults.map((stdioResult, fdNumber) => stripNewline(stdioResult, options, fdNumber)); + const all = stripNewline(allResult, options, 'all'); + const result = getAsyncResult({ + errorInfo, + exitCode, + signal, + stdio, + all, + ipcOutput, + context, + options, + command, + escapedCommand, + startTime, + }); + return handleResult(result, verboseInfo, options); +}; + +const getAsyncResult = ({errorInfo, exitCode, signal, stdio, all, ipcOutput, context, options, command, escapedCommand, startTime}) => 'error' in errorInfo + ? makeError({ + error: errorInfo.error, + command, + escapedCommand, + timedOut: context.terminationReason === 'timeout', + isCanceled: context.terminationReason === 'cancel' || context.terminationReason === 'gracefulCancel', + isGracefullyCanceled: context.terminationReason === 'gracefulCancel', + isMaxBuffer: errorInfo.error instanceof MaxBufferError, + isForcefullyTerminated: context.isForcefullyTerminated, + exitCode, + signal, + stdio, + all, + ipcOutput, + options, + startTime, + isSync: false, + }) + : makeSuccessResult({ + command, + escapedCommand, + stdio, + all, + ipcOutput, + options, + startTime, + }); + +// Deep merge specific options like `env`. Shallow merge the other ones. +const mergeOptions = (boundOptions, options) => { + const newOptions = Object.fromEntries( + Object.entries(options).map(([optionName, optionValue]) => [ + optionName, + mergeOption(optionName, boundOptions[optionName], optionValue), + ]), + ); + return {...boundOptions, ...newOptions}; +}; + +const mergeOption = (optionName, boundOptionValue, optionValue) => { + if (DEEP_OPTIONS.has(optionName) && isPlainObject(boundOptionValue) && isPlainObject(optionValue)) { + return {...boundOptionValue, ...optionValue}; + } + + return optionValue; +}; + +const DEEP_OPTIONS = new Set(['env', ...FD_SPECIFIC_OPTIONS]); + +// Wraps every exported methods to provide the following features: +// - template string syntax: execa`command argument` +// - options binding: boundExeca = execa(options) +// - optional argument/options: execa(file), execa(file, args), execa(file, options), execa(file, args, options) +// `mapArguments()` and `setBoundExeca()` allows for method-specific logic. +const createExeca = (mapArguments, boundOptions, deepOptions, setBoundExeca) => { + const createNested = (mapArguments, boundOptions, setBoundExeca) => createExeca(mapArguments, boundOptions, deepOptions, setBoundExeca); + const boundExeca = (...execaArguments) => callBoundExeca({ + mapArguments, + deepOptions, + boundOptions, + setBoundExeca, + createNested, + }, ...execaArguments); + + if (setBoundExeca !== undefined) { + setBoundExeca(boundExeca, createNested, boundOptions); + } + + return boundExeca; +}; + +const callBoundExeca = ({mapArguments, deepOptions = {}, boundOptions = {}, setBoundExeca, createNested}, firstArgument, ...nextArguments) => { + if (isPlainObject(firstArgument)) { + return createNested(mapArguments, mergeOptions(boundOptions, firstArgument), setBoundExeca); + } + + const {file, commandArguments, options, isSync} = parseArguments({ + mapArguments, + firstArgument, + nextArguments, + deepOptions, + boundOptions, + }); + return isSync + ? execaCoreSync(file, commandArguments, options) + : execaCoreAsync(file, commandArguments, options, createNested); +}; + +const parseArguments = ({mapArguments, firstArgument, nextArguments, deepOptions, boundOptions}) => { + const callArguments = isTemplateString(firstArgument) + ? parseTemplates(firstArgument, nextArguments) + : [firstArgument, ...nextArguments]; + const [initialFile, initialArguments, initialOptions] = normalizeParameters(...callArguments); + const mergedOptions = mergeOptions(mergeOptions(deepOptions, boundOptions), initialOptions); + const { + file = initialFile, + commandArguments = initialArguments, + options = mergedOptions, + isSync = false, + } = mapArguments({file: initialFile, commandArguments: initialArguments, options: mergedOptions}); + return { + file, + commandArguments, + options, + isSync, + }; +}; + +// Main logic for `execaCommand()` +const mapCommandAsync = ({file, commandArguments}) => parseCommand(file, commandArguments); + +// Main logic for `execaCommandSync()` +const mapCommandSync = ({file, commandArguments}) => ({...parseCommand(file, commandArguments), isSync: true}); + +// Convert `execaCommand(command)` into `execa(file, ...commandArguments)` +const parseCommand = (command, unusedArguments) => { + if (unusedArguments.length > 0) { + throw new TypeError(`The command and its arguments must be passed as a single string: ${command} ${unusedArguments}.`); + } + + const [file, ...commandArguments] = parseCommandString(command); + return {file, commandArguments}; +}; + +// Convert `command` string into an array of file or arguments to pass to $`${...fileOrCommandArguments}` +const parseCommandString = command => { + if (typeof command !== 'string') { + throw new TypeError(`The command must be a string: ${String(command)}.`); + } + + const trimmedCommand = command.trim(); + if (trimmedCommand === '') { + return []; + } + + const tokens = []; + for (const token of trimmedCommand.split(SPACES_REGEXP)) { + // Allow spaces to be escaped by a backslash if not meant as a delimiter + const previousToken = tokens.at(-1); + if (previousToken && previousToken.endsWith('\\')) { + // Merge previous token with current one + tokens[tokens.length - 1] = `${previousToken.slice(0, -1)} ${token}`; + } else { + tokens.push(token); + } + } + + return tokens; +}; + +const SPACES_REGEXP = / +/g; + +// Sets `$.sync` and `$.s` +const setScriptSync = (boundExeca, createNested, boundOptions) => { + boundExeca.sync = createNested(mapScriptSync, boundOptions); + boundExeca.s = boundExeca.sync; +}; + +// Main logic for `$` +const mapScriptAsync = ({options}) => getScriptOptions(options); + +// Main logic for `$.sync` +const mapScriptSync = ({options}) => ({...getScriptOptions(options), isSync: true}); + +// `$` is like `execa` but with script-friendly options: `{stdin: 'inherit', preferLocal: true}` +const getScriptOptions = options => ({options: {...getScriptStdinOption(options), ...options}}); + +const getScriptStdinOption = ({input, inputFile, stdio}) => input === undefined && inputFile === undefined && stdio === undefined + ? {stdin: 'inherit'} + : {}; + +// When using $(...).pipe(...), most script-friendly options should apply to both commands. +// However, some options (like `stdin: 'inherit'`) would create issues with piping, i.e. cannot be deep. +const deepScriptOptions = {preferLocal: true}; + +const execa = createExeca(() => ({})); +createExeca(() => ({isSync: true})); +createExeca(mapCommandAsync); +createExeca(mapCommandSync); +createExeca(mapNode); +createExeca(mapScriptAsync, {}, deepScriptOptions, setScriptSync); + +getIpcExport(); + +const netstat = async type => { + const {stdout} = await execa('netstat', ['-anv', '-p', type]); + return stdout; +}; + +const macos = async () => { + const [tcp, udp] = await Promise.all([ + netstat('tcp'), + netstat('udp'), + ]); + + // Column headers are on the second line + const headerStart = tcp.indexOf('\n') + 1; + const header = tcp.slice(headerStart, tcp.indexOf('\n', headerStart)); + + return { + stdout: [tcp, udp].join('\n'), + addressColumn: 3, + // Some versions of macOS print two extra columns for rxbytes and + // txbytes before pid. Unfortunately headers can't be parsed because + // they're space separated but some contain spaces, so we use this + // heuristic to distinguish the two netstat versions. + pidColumn: header.includes('rxbytes') ? 10 : 8, + }; +}; + +const linux = async () => { + const {stdout} = await execa('ss', ['-tunlp']); + return {stdout, addressColumn: 4, pidColumn: 6}; +}; + +const windows = async () => { + const {stdout} = await execa('netstat', ['-ano']); + return {stdout, addressColumn: 1, pidColumn: 4}; +}; + +const isProtocol = value => /^\s*(tcp|udp)/i.test(value); + +const stripIpv6Brackets = host => + host?.startsWith('[') && host.endsWith(']') ? host.slice(1, -1) : host; + +const normalizeHost = host => { + const normalizedHost = stripIpv6Brackets(host); + if (normalizedHost === 'localhost') { + return '127.0.0.1'; + } + + if (normalizedHost === '::ffff:127.0.0.1') { + return '127.0.0.1'; + } + + if (normalizedHost === '::') { + return '*'; + } + + return normalizedHost; +}; + +const parsePid = pid => { + if (typeof pid !== 'string') { + return; + } + + // Linux ss: users:(("node",pid=1337,fd=123)) + const linuxMatch = /pid=(?\d+)/.exec(pid); + if (linuxMatch?.groups?.pid) { + return Number.parseInt(linuxMatch.groups.pid, 10); + } + + // MacOS netstat - handles both old format (macOS 15 and older) and new format (macOS 26+) + // Old format: "1337" or ",1337" or ",pid=1337" + // New format: "prog:1337" (macOS 26+) + const macMatch = /(?:^|",|",pid=|[A-Za-z]+:)(?\d+)/.exec(pid); + if (macMatch?.groups?.pid) { + return Number.parseInt(macMatch.groups.pid, 10); + } + + // Windows netstat -ano: 1337 + if (/^\d+$/.test(pid)) { + return Number.parseInt(pid, 10); + } +}; + +const parseAddress = address => { + // Match "...:123" or "... .123" with the port at the end; keep host greedy to the last separator + const match = /^(?.+?)[.:](?\d+)$/.exec(address); + const rawHost = match?.groups?.host ?? address; + const host = normalizeHost(rawHost); + const port = match?.groups?.port ? Number.parseInt(match.groups.port, 10) : undefined; + return {host, port}; +}; + +const isLocalhostAddress = host => host === '127.0.0.1' || host === '::1'; + +const createHostFilter = host => { + const normalizedHost = normalizeHost(host); + if (normalizedHost === '*' || normalizedHost === '0.0.0.0' || normalizedHost === '::') { + return {type: 'all'}; + } + + if (normalizedHost === undefined) { + return {type: 'localhost'}; + } + + return {type: 'specific', host: normalizedHost}; +}; + +const applyHostFilter = (lines, addressColumn, hostFilter) => { + if (hostFilter.type === 'all') { + return lines; + } + + if (hostFilter.type === 'localhost') { + return lines.filter(line => { + const {host} = parseAddress(line[addressColumn]); + return isLocalhostAddress(host); + }); + } + + // Specific host + return lines.filter(line => { + const {host} = parseAddress(line[addressColumn]); + return host === hostFilter.host; + }); +}; + +const validatePid = pid => { + if (!Number.isInteger(pid)) { + throw new TypeError(`Expected an integer, got ${typeof pid}`); + } +}; + +const platformImplementations = {darwin: macos, linux}; +const implementation = platformImplementations[process$2.platform] ?? windows; + +const getList = async () => { + const {stdout, addressColumn, pidColumn} = await implementation(); + + const lines = stdout + .split('\n') + .filter(line => isProtocol(line)) + .map(line => line.match(/\S+/g) || []); + return {lines, addressColumn, pidColumn}; +}; + +const getPidsToPortsMap = async pids => { + const resultMap = new Map(pids.map(pid => [pid, new Set()])); + + // Get all ports from all interfaces for pidToPorts - user wants to know ALL ports this PID uses + for (const [port, pid] of await allPortsWithPid({host: '*'})) { + resultMap.get(pid)?.add(port); + } + + return resultMap; +}; + +async function pidToPorts(pid) { + if (Array.isArray(pid)) { + return getPidsToPortsMap(pid); + } + + validatePid(pid); + const resultMap = await getPidsToPortsMap([pid]); + return resultMap.get(pid); +} + +async function allPortsWithPid(options) { + const {lines, addressColumn, pidColumn} = await getList(); + const hostFilter = createHostFilter(options?.host); + + const resultMap = new Map(); + + // Apply host filtering to all lines, then extract ports + const filteredLines = applyHostFilter(lines, addressColumn, hostFilter); + + for (const line of filteredLines) { + const {port} = parseAddress(line[addressColumn]); + const pid = parsePid(line[pidColumn]); + + if (port !== undefined && pid !== undefined) { + resultMap.set(port, pid); + } + } + + return resultMap; +} + +/** + * Gets the port number that the process is listening on. + * @returns The port number that the process is listening on, or undefined if the process is not listening on any port. + * NOTE: Can't move this to @workflow/utils because it's being imported into @workflow/errors for RetryableError (inside workflow runtime) + */ +async function getPort() { + try { + const pid = process.pid; + const ports = await pidToPorts(pid); + if (!ports || ports.size === 0) { + return undefined; + } + const smallest = Math.min(...ports); + return smallest; + } + catch { + // If port detection fails (e.g., `ss` command not available in production), + // return undefined and fall back to default port + return undefined; + } +} + +// ============================================================ +// Trace Context Propagation Utilities +// ============================================================ +/** + * Serializes the current trace context into a format that can be passed through queues + * @returns A record of strings representing the trace context + */ +async function serializeTraceCarrier() { + const otel = await OtelApi.value; + if (!otel) + return {}; + const carrier = {}; + // Inject the current context into the carrier + otel.propagation.inject(otel.context.active(), carrier); + return carrier; +} +/** + * Deserializes trace context and returns a context that can be used to continue the trace + * @param traceCarrier The serialized trace context + * @returns OpenTelemetry context with the restored trace + */ +async function deserializeTraceCarrier(traceCarrier) { + const otel = await OtelApi.value; + if (!otel) + return; + // Extract the context from the carrier + return otel.propagation.extract(otel.context.active(), traceCarrier); +} +/** + * Runs a function within the context of a deserialized trace + * @param traceCarrier The serialized trace carrier (optional) + * @param fn The function to run within the trace context + * @returns The result of the function + */ +async function withTraceContext(traceCarrier, fn) { + if (!traceCarrier) { + return fn(); + } + const otel = await OtelApi.value; + if (!otel) + return fn(); + const extractedContext = await deserializeTraceCarrier(traceCarrier); + if (!extractedContext) { + return fn(); + } + return otel.context.with(extractedContext, async () => await fn()); +} +const OtelApi = once$1(async () => { + try { + return await import('./index_DqQ8k47W.mjs'); + } + catch { + console.warn('OpenTelemetry not available, tracing will be disabled'); + return null; + } +}); +const Tracer = once$1(async () => { + const api = await OtelApi.value; + if (!api) + return null; + return api.trace.getTracer('workflow'); +}); +async function trace(spanName, ...args) { + const [tracer, otel] = await Promise.all([Tracer.value, OtelApi.value]); + const { fn, opts } = typeof args[0] === 'function' + ? { fn: args[0], opts: {} } + : { fn: args[1], opts: args[0] }; + if (!fn) + throw new Error('Function to trace must be provided'); + if (!tracer || !otel) { + return await fn(); + } + return tracer.startActiveSpan(spanName, opts, async (span) => { + try { + const result = await fn(span); + span.setStatus({ code: otel.SpanStatusCode.OK }); + return result; + } + catch (e) { + span.setStatus({ + code: otel.SpanStatusCode.ERROR, + message: e.message, + }); + throw e; + } + finally { + span.end(); + } + }); +} +async function getSpanContextForTraceCarrier(carrier) { + const [deserialized, otel] = await Promise.all([ + deserializeTraceCarrier(carrier), + OtelApi.value, + ]); + if (!deserialized || !otel) + return; + return otel.trace.getSpanContext(deserialized); +} +async function getActiveSpan() { + const otel = await OtelApi.value; + if (!otel) + return null; + return otel.trace.getActiveSpan(); +} + +function createLogger(namespace) { + const baseDebug = debug(`workflow:${namespace}`); + const logger = (level) => { + const levelDebug = baseDebug.extend(level); + return (message, metadata) => { + levelDebug(message, metadata); + if (levelDebug.enabled) { + getActiveSpan() + .then((span) => { + span?.addEvent(`${level}.${namespace}`, { message, ...metadata }); + }) + .catch(() => { + // Silently ignore telemetry errors + }); + } + }; + }; + return { + debug: logger('debug'), + info: logger('info'), + warn: logger('warn'), + error: logger('error'), + }; +} +const stepLogger = createLogger('step'); +const runtimeLogger = createLogger('runtime'); +const webhookLogger = createLogger('webhook'); +const eventsLogger = createLogger('events'); +createLogger('adapter'); + +/** + * Utils used by the bundler when transforming code + */ +const registeredSteps = new Map(); +/** + * Register a step function to be served in the server bundle + */ +function registerStepFunction(stepId, stepFn) { + registeredSteps.set(stepId, stepFn); +} +/** + * Find a registered step function by name + */ +function getStepFunction(stepId) { + return registeredSteps.get(stepId); +} + +/** + * Creates a lazily-evaluated, memoized version of the provided function. + * + * The returned object exposes a `value` getter that calls `fn` only once, + * caches its result, and returns the cached value on subsequent accesses. + * + * @typeParam T - The return type of the provided function. + * @param fn - The function to be called once and whose result will be cached. + * @returns An object with a `value` property that returns the memoized result of `fn`. + */ +function once(fn) { + const result = { + get value() { + const value = fn(); + Object.defineProperty(result, 'value', { value }); + return value; + }, + }; + return result; +} + +const getDataDirFromEnv = () => { + return process.env.WORKFLOW_EMBEDDED_DATA_DIR || '.workflow-data'; +}; +const DEFAULT_RESOLVE_DATA_OPTION$1 = 'all'; +const getPortFromEnv = () => { + const port = process.env.PORT; + if (port) { + return Number(port); + } + return undefined; +}; +const config = once(() => { + const dataDir = getDataDirFromEnv(); + const port = getPortFromEnv(); + return { dataDir, port }; +}); + +// src/transports.ts +async function streamToBuffer$1(stream) { + let totalLength = 0; + const reader = stream.getReader(); + const chunks = []; + try { + while (true) { + const { done, value } = await reader.read(); + if (done) break; + chunks.push(value); + totalLength += value.length; + } + } finally { + reader.releaseLock(); + } + return Buffer.concat(chunks, totalLength); +} +var JsonTransport$1 = class JsonTransport { + contentType = "application/json"; + replacer; + reviver; + constructor(options = {}) { + this.replacer = options.replacer; + this.reviver = options.reviver; + } + serialize(value) { + return Buffer.from(JSON.stringify(value, this.replacer), "utf8"); + } + async deserialize(stream) { + const buffer = await streamToBuffer$1(stream); + return JSON.parse(buffer.toString("utf8"), this.reviver); + } +}; + +// src/dev.ts +var devRouteHandlers$1 = /* @__PURE__ */ new Map(); +var wildcardRouteHandlers$1 = /* @__PURE__ */ new Map(); +function clearDevHandlers$1() { + devRouteHandlers$1.clear(); + wildcardRouteHandlers$1.clear(); +} +if (process.env.NODE_ENV === "test" || process.env.VITEST) { + globalThis.__clearDevHandlers = clearDevHandlers$1; +} + +// Event type enum +const EventTypeSchema = z$1.enum([ + 'step_completed', + 'step_failed', + 'step_retrying', + 'step_started', + 'hook_created', + 'hook_received', + 'hook_disposed', + 'wait_created', + 'wait_completed', + 'workflow_completed', + 'workflow_failed', + 'workflow_started', +]); +// Base event schema with common properties +const BaseEventSchema = z$1.object({ + eventType: EventTypeSchema, + correlationId: z$1.string().optional(), +}); +// Event schemas (shared between creation requests and server responses) +const StepCompletedEventSchema = BaseEventSchema.extend({ + eventType: z$1.literal('step_completed'), + correlationId: z$1.string(), + eventData: z$1.object({ + result: z$1.any(), + }), +}); +const StepFailedEventSchema = BaseEventSchema.extend({ + eventType: z$1.literal('step_failed'), + correlationId: z$1.string(), + eventData: z$1.object({ + error: z$1.any(), + stack: z$1.string().optional(), + fatal: z$1.boolean().optional(), + }), +}); +// TODO: this is not actually used anywhere yet, we could remove it +// on client and server if needed +const StepRetryingEventSchema = BaseEventSchema.extend({ + eventType: z$1.literal('step_retrying'), + correlationId: z$1.string(), + eventData: z$1.object({ + attempt: z$1.number().min(1), + }), +}); +const StepStartedEventSchema = BaseEventSchema.extend({ + eventType: z$1.literal('step_started'), + correlationId: z$1.string(), +}); +const HookCreatedEventSchema = BaseEventSchema.extend({ + eventType: z$1.literal('hook_created'), + correlationId: z$1.string(), +}); +const HookReceivedEventSchema = BaseEventSchema.extend({ + eventType: z$1.literal('hook_received'), + correlationId: z$1.string(), + eventData: z$1.object({ + payload: z$1.any(), // Serialized payload + }), +}); +const HookDisposedEventSchema = BaseEventSchema.extend({ + eventType: z$1.literal('hook_disposed'), + correlationId: z$1.string(), +}); +const WaitCreatedEventSchema = BaseEventSchema.extend({ + eventType: z$1.literal('wait_created'), + correlationId: z$1.string(), + eventData: z$1.object({ + resumeAt: z$1.coerce.date(), + }), +}); +const WaitCompletedEventSchema = BaseEventSchema.extend({ + eventType: z$1.literal('wait_completed'), + correlationId: z$1.string(), +}); +// TODO: not used yet +const WorkflowCompletedEventSchema = BaseEventSchema.extend({ + eventType: z$1.literal('workflow_completed'), +}); +// TODO: not used yet +const WorkflowFailedEventSchema = BaseEventSchema.extend({ + eventType: z$1.literal('workflow_failed'), + eventData: z$1.object({ + error: z$1.any(), + }), +}); +// TODO: not used yet +const WorkflowStartedEventSchema = BaseEventSchema.extend({ + eventType: z$1.literal('workflow_started'), +}); +// Discriminated union (used for both creation requests and server responses) +const CreateEventSchema = z$1.discriminatedUnion('eventType', [ + StepCompletedEventSchema, + StepFailedEventSchema, + StepRetryingEventSchema, + StepStartedEventSchema, + HookCreatedEventSchema, + HookReceivedEventSchema, + HookDisposedEventSchema, + WaitCreatedEventSchema, + WaitCompletedEventSchema, + WorkflowCompletedEventSchema, + WorkflowFailedEventSchema, + WorkflowStartedEventSchema, +]); +// Server response include runId, eventId, and createdAt +const EventSchema = CreateEventSchema.and(z$1.object({ + runId: z$1.string(), + eventId: z$1.string(), + createdAt: z$1.coerce.date(), +})); + +const zodJsonSchema = z$1.lazy(() => { + return z$1.union([ + z$1.string(), + z$1.number(), + z$1.boolean(), + z$1.null(), + z$1.array(zodJsonSchema), + z$1.record(z$1.string(), zodJsonSchema), + ]); +}); +// Shared schema for paginated responses +const PaginatedResponseSchema = (dataSchema) => z$1.object({ + data: z$1.array(dataSchema), + cursor: z$1.string().nullable(), + hasMore: z$1.boolean(), +}); +/** + * A standard error schema shape for propogating errors from runs and steps + */ +const StructuredErrorSchema = z$1.object({ + message: z$1.string(), + stack: z$1.string().optional(), + code: z$1.string().optional(), // TODO: currently unused. make this an enum maybe +}); + +// Hook schemas +const HookSchema = z$1.object({ + runId: z$1.string(), + hookId: z$1.string(), + token: z$1.string(), + ownerId: z$1.string(), + projectId: z$1.string(), + environment: z$1.string(), + metadata: zodJsonSchema.optional(), + createdAt: z$1.coerce.date(), +}); + +const QueuePrefix = z$2.union([ + z$2.literal('__wkf_step_'), + z$2.literal('__wkf_workflow_'), +]); +const ValidQueueName = z$2.templateLiteral([QueuePrefix, z$2.string()]); +const MessageId = z$2 + .string() + .brand() + .describe('A stored queue message ID'); +/** + * OpenTelemetry trace context for distributed tracing + */ +const TraceCarrierSchema$1 = z$2.record(z$2.string(), z$2.string()); +const WorkflowInvokePayloadSchema$1 = z$2.object({ + runId: z$2.string(), + traceCarrier: TraceCarrierSchema$1.optional(), +}); +const StepInvokePayloadSchema$1 = z$2.object({ + workflowName: z$2.string(), + workflowRunId: z$2.string(), + workflowStartedAt: z$2.number(), + stepId: z$2.string(), + traceCarrier: TraceCarrierSchema$1.optional(), +}); +const QueuePayloadSchema = z$2.union([ + WorkflowInvokePayloadSchema$1, + StepInvokePayloadSchema$1, +]); + +// Workflow run schemas +const WorkflowRunStatusSchema = z$1.enum([ + 'pending', + 'running', + 'completed', + 'failed', + 'paused', + 'cancelled', +]); +/** + * Base schema for the Workflow runs. Prefer using WorkflowRunSchema + * which implements a discriminatedUnion for various states + */ +const WorkflowRunBaseSchema = z$1.object({ + runId: z$1.string(), + status: WorkflowRunStatusSchema, + deploymentId: z$1.string(), + workflowName: z$1.string(), + executionContext: z$1.record(z$1.string(), z$1.any()).optional(), + input: z$1.array(z$1.any()), + output: z$1.any().optional(), + error: StructuredErrorSchema.optional(), + startedAt: z$1.coerce.date().optional(), + completedAt: z$1.coerce.date().optional(), + createdAt: z$1.coerce.date(), + updatedAt: z$1.coerce.date(), +}); +// Discriminated union based on status +const WorkflowRunSchema = z$1.discriminatedUnion('status', [ + // Non-final states + WorkflowRunBaseSchema.extend({ + status: z$1.enum(['pending', 'running', 'paused']), + output: z$1.undefined(), + error: z$1.undefined(), + completedAt: z$1.undefined(), + }), + // Cancelled state + WorkflowRunBaseSchema.extend({ + status: z$1.literal('cancelled'), + output: z$1.undefined(), + error: z$1.undefined(), + completedAt: z$1.coerce.date(), + }), + // Completed state + WorkflowRunBaseSchema.extend({ + status: z$1.literal('completed'), + output: z$1.any(), + error: z$1.undefined(), + completedAt: z$1.coerce.date(), + }), + // Failed state + WorkflowRunBaseSchema.extend({ + status: z$1.literal('failed'), + output: z$1.undefined(), + error: StructuredErrorSchema, + completedAt: z$1.coerce.date(), + }), +]); + +// Step schemas +const StepStatusSchema = z$1.enum([ + 'pending', + 'running', + 'completed', + 'failed', + 'cancelled', +]); +// TODO: implement a discriminated union here just like the run schema +const StepSchema = z$1.object({ + runId: z$1.string(), + stepId: z$1.string(), + stepName: z$1.string(), + status: StepStatusSchema, + input: z$1.array(z$1.any()), + output: z$1.any().optional(), + error: StructuredErrorSchema.optional(), + attempt: z$1.number(), + startedAt: z$1.coerce.date().optional(), + completedAt: z$1.coerce.date().optional(), + createdAt: z$1.coerce.date(), + updatedAt: z$1.coerce.date(), + retryAfter: z$1.coerce.date().optional(), +}); + +const ENCODING = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"; // Crockford's Base32 +const ENCODING_LEN = 32; // from ENCODING.length; +const RANDOM_LEN = 16; +const TIME_LEN = 10; +const TIME_MAX = 281474976710655; // from Math.pow(2, 48) - 1; + +var ULIDErrorCode; +(function (ULIDErrorCode) { + ULIDErrorCode["Base32IncorrectEncoding"] = "B32_ENC_INVALID"; + ULIDErrorCode["DecodeTimeInvalidCharacter"] = "DEC_TIME_CHAR"; + ULIDErrorCode["DecodeTimeValueMalformed"] = "DEC_TIME_MALFORMED"; + ULIDErrorCode["EncodeTimeNegative"] = "ENC_TIME_NEG"; + ULIDErrorCode["EncodeTimeSizeExceeded"] = "ENC_TIME_SIZE_EXCEED"; + ULIDErrorCode["EncodeTimeValueMalformed"] = "ENC_TIME_MALFORMED"; + ULIDErrorCode["PRNGDetectFailure"] = "PRNG_DETECT"; + ULIDErrorCode["ULIDInvalid"] = "ULID_INVALID"; + ULIDErrorCode["Unexpected"] = "UNEXPECTED"; + ULIDErrorCode["UUIDInvalid"] = "UUID_INVALID"; +})(ULIDErrorCode || (ULIDErrorCode = {})); +class ULIDError extends Error { + constructor(errorCode, message) { + super(`${message} (${errorCode})`); + this.name = "ULIDError"; + this.code = errorCode; + } +} + +function randomChar(prng) { + // Currently PRNGs generate fractions from 0 to _less than_ 1, so no "%" is necessary. + // However, just in case a future PRNG can generate 1, + // we are applying "% ENCODING LEN" to wrap back to the first character + const randomPosition = Math.floor(prng() * ENCODING_LEN) % ENCODING_LEN; + return ENCODING.charAt(randomPosition); +} +function replaceCharAt(str, index, char) { + if (index > str.length - 1) { + return str; + } + return str.substr(0, index) + char + str.substr(index + 1); +} +function incrementBase32(str) { + let done = undefined, index = str.length, char, charIndex, output = str; + const maxCharIndex = ENCODING_LEN - 1; + while (!done && index-- >= 0) { + char = output[index]; + charIndex = ENCODING.indexOf(char); + if (charIndex === -1) { + throw new ULIDError(ULIDErrorCode.Base32IncorrectEncoding, "Incorrectly encoded string"); + } + if (charIndex === maxCharIndex) { + output = replaceCharAt(output, index, ENCODING[0]); + continue; + } + done = replaceCharAt(output, index, ENCODING[charIndex + 1]); + } + if (typeof done === "string") { + return done; + } + throw new ULIDError(ULIDErrorCode.Base32IncorrectEncoding, "Failed incrementing string"); +} + +/** + * Decode time from a ULID + * @param id The ULID + * @returns The decoded timestamp + */ +function decodeTime(id) { + if (id.length !== TIME_LEN + RANDOM_LEN) { + throw new ULIDError(ULIDErrorCode.DecodeTimeValueMalformed, "Malformed ULID"); + } + const time = id + .substr(0, TIME_LEN) + .toUpperCase() + .split("") + .reverse() + .reduce((carry, char, index) => { + const encodingIndex = ENCODING.indexOf(char); + if (encodingIndex === -1) { + throw new ULIDError(ULIDErrorCode.DecodeTimeInvalidCharacter, `Time decode error: Invalid character: ${char}`); + } + return (carry += encodingIndex * Math.pow(ENCODING_LEN, index)); + }, 0); + if (time > TIME_MAX) { + throw new ULIDError(ULIDErrorCode.DecodeTimeValueMalformed, `Malformed ULID: timestamp too large: ${time}`); + } + return time; +} +/** + * Detect the best PRNG (pseudo-random number generator) + * @param root The root to check from (global/window) + * @returns The PRNG function + */ +function detectPRNG(root) { + const rootLookup = detectRoot(); + const globalCrypto = (rootLookup && (rootLookup.crypto || rootLookup.msCrypto)) || + (typeof crypto !== "undefined" ? crypto : null); + if (typeof globalCrypto?.getRandomValues === "function") { + return () => { + const buffer = new Uint8Array(1); + globalCrypto.getRandomValues(buffer); + return buffer[0] / 0xff; + }; + } + else if (typeof globalCrypto?.randomBytes === "function") { + return () => globalCrypto.randomBytes(1).readUInt8() / 0xff; + } + else if (crypto?.randomBytes) { + return () => crypto.randomBytes(1).readUInt8() / 0xff; + } + throw new ULIDError(ULIDErrorCode.PRNGDetectFailure, "Failed to find a reliable PRNG"); +} +function detectRoot() { + if (inWebWorker()) + return self; + if (typeof window !== "undefined") { + return window; + } + if (typeof global !== "undefined") { + return global; + } + if (typeof globalThis !== "undefined") { + return globalThis; + } + return null; +} +function encodeRandom(len, prng) { + let str = ""; + for (; len > 0; len--) { + str = randomChar(prng) + str; + } + return str; +} +/** + * Encode the time portion of a ULID + * @param now The current timestamp + * @param len Length to generate + * @returns The encoded time + */ +function encodeTime(now, len = TIME_LEN) { + if (isNaN(now)) { + throw new ULIDError(ULIDErrorCode.EncodeTimeValueMalformed, `Time must be a number: ${now}`); + } + else if (now > TIME_MAX) { + throw new ULIDError(ULIDErrorCode.EncodeTimeSizeExceeded, `Cannot encode a time larger than ${TIME_MAX}: ${now}`); + } + else if (now < 0) { + throw new ULIDError(ULIDErrorCode.EncodeTimeNegative, `Time must be positive: ${now}`); + } + else if (Number.isInteger(now) === false) { + throw new ULIDError(ULIDErrorCode.EncodeTimeValueMalformed, `Time must be an integer: ${now}`); + } + let mod, str = ""; + for (let currentLen = len; currentLen > 0; currentLen--) { + mod = now % ENCODING_LEN; + str = ENCODING.charAt(mod) + str; + now = (now - mod) / ENCODING_LEN; + } + return str; +} +function inWebWorker() { + // @ts-ignore + return typeof WorkerGlobalScope !== "undefined" && self instanceof WorkerGlobalScope; +} +/** + * Create a ULID factory to generate monotonically-increasing + * ULIDs + * @param prng The PRNG to use + * @returns A ulid factory + * @example + * const ulid = monotonicFactory(); + * ulid(); // "01HNZXD07M5CEN5XA66EMZSRZW" + */ +function monotonicFactory(prng) { + const currentPRNG = prng || detectPRNG(); + let lastTime = 0, lastRandom; + return function _ulid(seedTime) { + const seed = !seedTime || isNaN(seedTime) ? Date.now() : seedTime; + if (seed <= lastTime) { + const incrementedRandom = (lastRandom = incrementBase32(lastRandom)); + return encodeTime(lastTime, TIME_LEN) + incrementedRandom; + } + lastTime = seed; + const newRandom = (lastRandom = encodeRandom(RANDOM_LEN, currentPRNG)); + return encodeTime(seed, TIME_LEN) + newRandom; + }; +} + +var undici = {}; + +var symbols$4; +var hasRequiredSymbols$4; + +function requireSymbols$4 () { + if (hasRequiredSymbols$4) return symbols$4; + hasRequiredSymbols$4 = 1; + symbols$4 = { + kClose: Symbol('close'), + kDestroy: Symbol('destroy'), + kDispatch: Symbol('dispatch'), + kUrl: Symbol('url'), + kWriting: Symbol('writing'), + kResuming: Symbol('resuming'), + kQueue: Symbol('queue'), + kConnect: Symbol('connect'), + kConnecting: Symbol('connecting'), + kKeepAliveDefaultTimeout: Symbol('default keep alive timeout'), + kKeepAliveMaxTimeout: Symbol('max keep alive timeout'), + kKeepAliveTimeoutThreshold: Symbol('keep alive timeout threshold'), + kKeepAliveTimeoutValue: Symbol('keep alive timeout'), + kKeepAlive: Symbol('keep alive'), + kHeadersTimeout: Symbol('headers timeout'), + kBodyTimeout: Symbol('body timeout'), + kServerName: Symbol('server name'), + kLocalAddress: Symbol('local address'), + kHost: Symbol('host'), + kNoRef: Symbol('no ref'), + kBodyUsed: Symbol('used'), + kBody: Symbol('abstracted request body'), + kRunning: Symbol('running'), + kBlocking: Symbol('blocking'), + kPending: Symbol('pending'), + kSize: Symbol('size'), + kBusy: Symbol('busy'), + kQueued: Symbol('queued'), + kFree: Symbol('free'), + kConnected: Symbol('connected'), + kClosed: Symbol('closed'), + kNeedDrain: Symbol('need drain'), + kReset: Symbol('reset'), + kDestroyed: Symbol.for('nodejs.stream.destroyed'), + kResume: Symbol('resume'), + kOnError: Symbol('on error'), + kMaxHeadersSize: Symbol('max headers size'), + kRunningIdx: Symbol('running index'), + kPendingIdx: Symbol('pending index'), + kError: Symbol('error'), + kClients: Symbol('clients'), + kClient: Symbol('client'), + kParser: Symbol('parser'), + kOnDestroyed: Symbol('destroy callbacks'), + kPipelining: Symbol('pipelining'), + kSocket: Symbol('socket'), + kHostHeader: Symbol('host header'), + kConnector: Symbol('connector'), + kStrictContentLength: Symbol('strict content length'), + kMaxRedirections: Symbol('maxRedirections'), + kMaxRequests: Symbol('maxRequestsPerClient'), + kProxy: Symbol('proxy agent options'), + kCounter: Symbol('socket request counter'), + kInterceptors: Symbol('dispatch interceptors'), + kMaxResponseSize: Symbol('max response size'), + kHTTP2Session: Symbol('http2Session'), + kHTTP2SessionState: Symbol('http2Session state'), + kRetryHandlerDefaultRetry: Symbol('retry agent default retry'), + kConstruct: Symbol('constructable'), + kListeners: Symbol('listeners'), + kHTTPContext: Symbol('http context'), + kMaxConcurrentStreams: Symbol('max concurrent streams'), + kNoProxyAgent: Symbol('no proxy agent'), + kHttpProxyAgent: Symbol('http proxy agent'), + kHttpsProxyAgent: Symbol('https proxy agent') + }; + return symbols$4; +} + +var errors; +var hasRequiredErrors; + +function requireErrors () { + if (hasRequiredErrors) return errors; + hasRequiredErrors = 1; + + class UndiciError extends Error { + constructor (message) { + super(message); + this.name = 'UndiciError'; + this.code = 'UND_ERR'; + } + } + + class ConnectTimeoutError extends UndiciError { + constructor (message) { + super(message); + this.name = 'ConnectTimeoutError'; + this.message = message || 'Connect Timeout Error'; + this.code = 'UND_ERR_CONNECT_TIMEOUT'; + } + } + + class HeadersTimeoutError extends UndiciError { + constructor (message) { + super(message); + this.name = 'HeadersTimeoutError'; + this.message = message || 'Headers Timeout Error'; + this.code = 'UND_ERR_HEADERS_TIMEOUT'; + } + } + + class HeadersOverflowError extends UndiciError { + constructor (message) { + super(message); + this.name = 'HeadersOverflowError'; + this.message = message || 'Headers Overflow Error'; + this.code = 'UND_ERR_HEADERS_OVERFLOW'; + } + } + + class BodyTimeoutError extends UndiciError { + constructor (message) { + super(message); + this.name = 'BodyTimeoutError'; + this.message = message || 'Body Timeout Error'; + this.code = 'UND_ERR_BODY_TIMEOUT'; + } + } + + class ResponseStatusCodeError extends UndiciError { + constructor (message, statusCode, headers, body) { + super(message); + this.name = 'ResponseStatusCodeError'; + this.message = message || 'Response Status Code Error'; + this.code = 'UND_ERR_RESPONSE_STATUS_CODE'; + this.body = body; + this.status = statusCode; + this.statusCode = statusCode; + this.headers = headers; + } + } + + class InvalidArgumentError extends UndiciError { + constructor (message) { + super(message); + this.name = 'InvalidArgumentError'; + this.message = message || 'Invalid Argument Error'; + this.code = 'UND_ERR_INVALID_ARG'; + } + } + + class InvalidReturnValueError extends UndiciError { + constructor (message) { + super(message); + this.name = 'InvalidReturnValueError'; + this.message = message || 'Invalid Return Value Error'; + this.code = 'UND_ERR_INVALID_RETURN_VALUE'; + } + } + + class AbortError extends UndiciError { + constructor (message) { + super(message); + this.name = 'AbortError'; + this.message = message || 'The operation was aborted'; + } + } + + class RequestAbortedError extends AbortError { + constructor (message) { + super(message); + this.name = 'AbortError'; + this.message = message || 'Request aborted'; + this.code = 'UND_ERR_ABORTED'; + } + } + + class InformationalError extends UndiciError { + constructor (message) { + super(message); + this.name = 'InformationalError'; + this.message = message || 'Request information'; + this.code = 'UND_ERR_INFO'; + } + } + + class RequestContentLengthMismatchError extends UndiciError { + constructor (message) { + super(message); + this.name = 'RequestContentLengthMismatchError'; + this.message = message || 'Request body length does not match content-length header'; + this.code = 'UND_ERR_REQ_CONTENT_LENGTH_MISMATCH'; + } + } + + class ResponseContentLengthMismatchError extends UndiciError { + constructor (message) { + super(message); + this.name = 'ResponseContentLengthMismatchError'; + this.message = message || 'Response body length does not match content-length header'; + this.code = 'UND_ERR_RES_CONTENT_LENGTH_MISMATCH'; + } + } + + class ClientDestroyedError extends UndiciError { + constructor (message) { + super(message); + this.name = 'ClientDestroyedError'; + this.message = message || 'The client is destroyed'; + this.code = 'UND_ERR_DESTROYED'; + } + } + + class ClientClosedError extends UndiciError { + constructor (message) { + super(message); + this.name = 'ClientClosedError'; + this.message = message || 'The client is closed'; + this.code = 'UND_ERR_CLOSED'; + } + } + + class SocketError extends UndiciError { + constructor (message, socket) { + super(message); + this.name = 'SocketError'; + this.message = message || 'Socket error'; + this.code = 'UND_ERR_SOCKET'; + this.socket = socket; + } + } + + class NotSupportedError extends UndiciError { + constructor (message) { + super(message); + this.name = 'NotSupportedError'; + this.message = message || 'Not supported error'; + this.code = 'UND_ERR_NOT_SUPPORTED'; + } + } + + class BalancedPoolMissingUpstreamError extends UndiciError { + constructor (message) { + super(message); + this.name = 'MissingUpstreamError'; + this.message = message || 'No upstream has been added to the BalancedPool'; + this.code = 'UND_ERR_BPL_MISSING_UPSTREAM'; + } + } + + class HTTPParserError extends Error { + constructor (message, code, data) { + super(message); + this.name = 'HTTPParserError'; + this.code = code ? `HPE_${code}` : undefined; + this.data = data ? data.toString() : undefined; + } + } + + class ResponseExceededMaxSizeError extends UndiciError { + constructor (message) { + super(message); + this.name = 'ResponseExceededMaxSizeError'; + this.message = message || 'Response content exceeded max size'; + this.code = 'UND_ERR_RES_EXCEEDED_MAX_SIZE'; + } + } + + class RequestRetryError extends UndiciError { + constructor (message, code, { headers, data }) { + super(message); + this.name = 'RequestRetryError'; + this.message = message || 'Request retry error'; + this.code = 'UND_ERR_REQ_RETRY'; + this.statusCode = code; + this.data = data; + this.headers = headers; + } + } + + class SecureProxyConnectionError extends UndiciError { + constructor (cause, message, options) { + super(message, { cause, ...(options ?? {}) }); + this.name = 'SecureProxyConnectionError'; + this.message = message || 'Secure Proxy Connection failed'; + this.code = 'UND_ERR_PRX_TLS'; + this.cause = cause; + } + } + + errors = { + AbortError, + HTTPParserError, + UndiciError, + HeadersTimeoutError, + HeadersOverflowError, + BodyTimeoutError, + RequestContentLengthMismatchError, + ConnectTimeoutError, + ResponseStatusCodeError, + InvalidArgumentError, + InvalidReturnValueError, + RequestAbortedError, + ClientDestroyedError, + ClientClosedError, + InformationalError, + SocketError, + NotSupportedError, + ResponseContentLengthMismatchError, + BalancedPoolMissingUpstreamError, + ResponseExceededMaxSizeError, + RequestRetryError, + SecureProxyConnectionError + }; + return errors; +} + +var constants$4; +var hasRequiredConstants$4; + +function requireConstants$4 () { + if (hasRequiredConstants$4) return constants$4; + hasRequiredConstants$4 = 1; + + /** @type {Record} */ + const headerNameLowerCasedRecord = {}; + + // https://developer.mozilla.org/docs/Web/HTTP/Headers + const wellknownHeaderNames = [ + 'Accept', + 'Accept-Encoding', + 'Accept-Language', + 'Accept-Ranges', + 'Access-Control-Allow-Credentials', + 'Access-Control-Allow-Headers', + 'Access-Control-Allow-Methods', + 'Access-Control-Allow-Origin', + 'Access-Control-Expose-Headers', + 'Access-Control-Max-Age', + 'Access-Control-Request-Headers', + 'Access-Control-Request-Method', + 'Age', + 'Allow', + 'Alt-Svc', + 'Alt-Used', + 'Authorization', + 'Cache-Control', + 'Clear-Site-Data', + 'Connection', + 'Content-Disposition', + 'Content-Encoding', + 'Content-Language', + 'Content-Length', + 'Content-Location', + 'Content-Range', + 'Content-Security-Policy', + 'Content-Security-Policy-Report-Only', + 'Content-Type', + 'Cookie', + 'Cross-Origin-Embedder-Policy', + 'Cross-Origin-Opener-Policy', + 'Cross-Origin-Resource-Policy', + 'Date', + 'Device-Memory', + 'Downlink', + 'ECT', + 'ETag', + 'Expect', + 'Expect-CT', + 'Expires', + 'Forwarded', + 'From', + 'Host', + 'If-Match', + 'If-Modified-Since', + 'If-None-Match', + 'If-Range', + 'If-Unmodified-Since', + 'Keep-Alive', + 'Last-Modified', + 'Link', + 'Location', + 'Max-Forwards', + 'Origin', + 'Permissions-Policy', + 'Pragma', + 'Proxy-Authenticate', + 'Proxy-Authorization', + 'RTT', + 'Range', + 'Referer', + 'Referrer-Policy', + 'Refresh', + 'Retry-After', + 'Sec-WebSocket-Accept', + 'Sec-WebSocket-Extensions', + 'Sec-WebSocket-Key', + 'Sec-WebSocket-Protocol', + 'Sec-WebSocket-Version', + 'Server', + 'Server-Timing', + 'Service-Worker-Allowed', + 'Service-Worker-Navigation-Preload', + 'Set-Cookie', + 'SourceMap', + 'Strict-Transport-Security', + 'Supports-Loading-Mode', + 'TE', + 'Timing-Allow-Origin', + 'Trailer', + 'Transfer-Encoding', + 'Upgrade', + 'Upgrade-Insecure-Requests', + 'User-Agent', + 'Vary', + 'Via', + 'WWW-Authenticate', + 'X-Content-Type-Options', + 'X-DNS-Prefetch-Control', + 'X-Frame-Options', + 'X-Permitted-Cross-Domain-Policies', + 'X-Powered-By', + 'X-Requested-With', + 'X-XSS-Protection' + ]; + + for (let i = 0; i < wellknownHeaderNames.length; ++i) { + const key = wellknownHeaderNames[i]; + const lowerCasedKey = key.toLowerCase(); + headerNameLowerCasedRecord[key] = headerNameLowerCasedRecord[lowerCasedKey] = + lowerCasedKey; + } + + // Note: object prototypes should not be able to be referenced. e.g. `Object#hasOwnProperty`. + Object.setPrototypeOf(headerNameLowerCasedRecord, null); + + constants$4 = { + wellknownHeaderNames, + headerNameLowerCasedRecord + }; + return constants$4; +} + +var tree_1; +var hasRequiredTree; + +function requireTree () { + if (hasRequiredTree) return tree_1; + hasRequiredTree = 1; + + const { + wellknownHeaderNames, + headerNameLowerCasedRecord + } = requireConstants$4(); + + class TstNode { + /** @type {any} */ + value = null + /** @type {null | TstNode} */ + left = null + /** @type {null | TstNode} */ + middle = null + /** @type {null | TstNode} */ + right = null + /** @type {number} */ + code + /** + * @param {string} key + * @param {any} value + * @param {number} index + */ + constructor (key, value, index) { + if (index === undefined || index >= key.length) { + throw new TypeError('Unreachable') + } + const code = this.code = key.charCodeAt(index); + // check code is ascii string + if (code > 0x7F) { + throw new TypeError('key must be ascii string') + } + if (key.length !== ++index) { + this.middle = new TstNode(key, value, index); + } else { + this.value = value; + } + } + + /** + * @param {string} key + * @param {any} value + */ + add (key, value) { + const length = key.length; + if (length === 0) { + throw new TypeError('Unreachable') + } + let index = 0; + let node = this; + while (true) { + const code = key.charCodeAt(index); + // check code is ascii string + if (code > 0x7F) { + throw new TypeError('key must be ascii string') + } + if (node.code === code) { + if (length === ++index) { + node.value = value; + break + } else if (node.middle !== null) { + node = node.middle; + } else { + node.middle = new TstNode(key, value, index); + break + } + } else if (node.code < code) { + if (node.left !== null) { + node = node.left; + } else { + node.left = new TstNode(key, value, index); + break + } + } else if (node.right !== null) { + node = node.right; + } else { + node.right = new TstNode(key, value, index); + break + } + } + } + + /** + * @param {Uint8Array} key + * @return {TstNode | null} + */ + search (key) { + const keylength = key.length; + let index = 0; + let node = this; + while (node !== null && index < keylength) { + let code = key[index]; + // A-Z + // First check if it is bigger than 0x5a. + // Lowercase letters have higher char codes than uppercase ones. + // Also we assume that headers will mostly contain lowercase characters. + if (code <= 0x5a && code >= 0x41) { + // Lowercase for uppercase. + code |= 32; + } + while (node !== null) { + if (code === node.code) { + if (keylength === ++index) { + // Returns Node since it is the last key. + return node + } + node = node.middle; + break + } + node = node.code < code ? node.left : node.right; + } + } + return null + } + } + + class TernarySearchTree { + /** @type {TstNode | null} */ + node = null + + /** + * @param {string} key + * @param {any} value + * */ + insert (key, value) { + if (this.node === null) { + this.node = new TstNode(key, value, 0); + } else { + this.node.add(key, value); + } + } + + /** + * @param {Uint8Array} key + * @return {any} + */ + lookup (key) { + return this.node?.search(key)?.value ?? null + } + } + + const tree = new TernarySearchTree(); + + for (let i = 0; i < wellknownHeaderNames.length; ++i) { + const key = headerNameLowerCasedRecord[wellknownHeaderNames[i]]; + tree.insert(key, key); + } + + tree_1 = { + TernarySearchTree, + tree + }; + return tree_1; +} + +var util$7; +var hasRequiredUtil$7; + +function requireUtil$7 () { + if (hasRequiredUtil$7) return util$7; + hasRequiredUtil$7 = 1; + + const assert = require$$0$4; + const { kDestroyed, kBodyUsed, kListeners, kBody } = requireSymbols$4(); + const { IncomingMessage } = require$$2; + const stream = require$$0$5; + const net = require$$4; + const { Blob } = require$$0$3; + const nodeUtil = require$$0$6; + const { stringify } = require$$7; + const { EventEmitter: EE } = require$$8; + const { InvalidArgumentError } = requireErrors(); + const { headerNameLowerCasedRecord } = requireConstants$4(); + const { tree } = requireTree(); + + const [nodeMajor, nodeMinor] = process.versions.node.split('.').map(v => Number(v)); + + class BodyAsyncIterable { + constructor (body) { + this[kBody] = body; + this[kBodyUsed] = false; + } + + async * [Symbol.asyncIterator] () { + assert(!this[kBodyUsed], 'disturbed'); + this[kBodyUsed] = true; + yield * this[kBody]; + } + } + + function wrapRequestBody (body) { + if (isStream(body)) { + // TODO (fix): Provide some way for the user to cache the file to e.g. /tmp + // so that it can be dispatched again? + // TODO (fix): Do we need 100-expect support to provide a way to do this properly? + if (bodyLength(body) === 0) { + body + .on('data', function () { + assert(false); + }); + } + + if (typeof body.readableDidRead !== 'boolean') { + body[kBodyUsed] = false; + EE.prototype.on.call(body, 'data', function () { + this[kBodyUsed] = true; + }); + } + + return body + } else if (body && typeof body.pipeTo === 'function') { + // TODO (fix): We can't access ReadableStream internal state + // to determine whether or not it has been disturbed. This is just + // a workaround. + return new BodyAsyncIterable(body) + } else if ( + body && + typeof body !== 'string' && + !ArrayBuffer.isView(body) && + isIterable(body) + ) { + // TODO: Should we allow re-using iterable if !this.opts.idempotent + // or through some other flag? + return new BodyAsyncIterable(body) + } else { + return body + } + } + + function nop () {} + + function isStream (obj) { + return obj && typeof obj === 'object' && typeof obj.pipe === 'function' && typeof obj.on === 'function' + } + + // based on https://github.com/node-fetch/fetch-blob/blob/8ab587d34080de94140b54f07168451e7d0b655e/index.js#L229-L241 (MIT License) + function isBlobLike (object) { + if (object === null) { + return false + } else if (object instanceof Blob) { + return true + } else if (typeof object !== 'object') { + return false + } else { + const sTag = object[Symbol.toStringTag]; + + return (sTag === 'Blob' || sTag === 'File') && ( + ('stream' in object && typeof object.stream === 'function') || + ('arrayBuffer' in object && typeof object.arrayBuffer === 'function') + ) + } + } + + function buildURL (url, queryParams) { + if (url.includes('?') || url.includes('#')) { + throw new Error('Query params cannot be passed when url already contains "?" or "#".') + } + + const stringified = stringify(queryParams); + + if (stringified) { + url += '?' + stringified; + } + + return url + } + + function isValidPort (port) { + const value = parseInt(port, 10); + return ( + value === Number(port) && + value >= 0 && + value <= 65535 + ) + } + + function isHttpOrHttpsPrefixed (value) { + return ( + value != null && + value[0] === 'h' && + value[1] === 't' && + value[2] === 't' && + value[3] === 'p' && + ( + value[4] === ':' || + ( + value[4] === 's' && + value[5] === ':' + ) + ) + ) + } + + function parseURL (url) { + if (typeof url === 'string') { + url = new URL(url); + + if (!isHttpOrHttpsPrefixed(url.origin || url.protocol)) { + throw new InvalidArgumentError('Invalid URL protocol: the URL must start with `http:` or `https:`.') + } + + return url + } + + if (!url || typeof url !== 'object') { + throw new InvalidArgumentError('Invalid URL: The URL argument must be a non-null object.') + } + + if (!(url instanceof URL)) { + if (url.port != null && url.port !== '' && isValidPort(url.port) === false) { + throw new InvalidArgumentError('Invalid URL: port must be a valid integer or a string representation of an integer.') + } + + if (url.path != null && typeof url.path !== 'string') { + throw new InvalidArgumentError('Invalid URL path: the path must be a string or null/undefined.') + } + + if (url.pathname != null && typeof url.pathname !== 'string') { + throw new InvalidArgumentError('Invalid URL pathname: the pathname must be a string or null/undefined.') + } + + if (url.hostname != null && typeof url.hostname !== 'string') { + throw new InvalidArgumentError('Invalid URL hostname: the hostname must be a string or null/undefined.') + } + + if (url.origin != null && typeof url.origin !== 'string') { + throw new InvalidArgumentError('Invalid URL origin: the origin must be a string or null/undefined.') + } + + if (!isHttpOrHttpsPrefixed(url.origin || url.protocol)) { + throw new InvalidArgumentError('Invalid URL protocol: the URL must start with `http:` or `https:`.') + } + + const port = url.port != null + ? url.port + : (url.protocol === 'https:' ? 443 : 80); + let origin = url.origin != null + ? url.origin + : `${url.protocol || ''}//${url.hostname || ''}:${port}`; + let path = url.path != null + ? url.path + : `${url.pathname || ''}${url.search || ''}`; + + if (origin[origin.length - 1] === '/') { + origin = origin.slice(0, origin.length - 1); + } + + if (path && path[0] !== '/') { + path = `/${path}`; + } + // new URL(path, origin) is unsafe when `path` contains an absolute URL + // From https://developer.mozilla.org/en-US/docs/Web/API/URL/URL: + // If first parameter is a relative URL, second param is required, and will be used as the base URL. + // If first parameter is an absolute URL, a given second param will be ignored. + return new URL(`${origin}${path}`) + } + + if (!isHttpOrHttpsPrefixed(url.origin || url.protocol)) { + throw new InvalidArgumentError('Invalid URL protocol: the URL must start with `http:` or `https:`.') + } + + return url + } + + function parseOrigin (url) { + url = parseURL(url); + + if (url.pathname !== '/' || url.search || url.hash) { + throw new InvalidArgumentError('invalid url') + } + + return url + } + + function getHostname (host) { + if (host[0] === '[') { + const idx = host.indexOf(']'); + + assert(idx !== -1); + return host.substring(1, idx) + } + + const idx = host.indexOf(':'); + if (idx === -1) return host + + return host.substring(0, idx) + } + + // IP addresses are not valid server names per RFC6066 + // > Currently, the only server names supported are DNS hostnames + function getServerName (host) { + if (!host) { + return null + } + + assert.strictEqual(typeof host, 'string'); + + const servername = getHostname(host); + if (net.isIP(servername)) { + return '' + } + + return servername + } + + function deepClone (obj) { + return JSON.parse(JSON.stringify(obj)) + } + + function isAsyncIterable (obj) { + return !!(obj != null && typeof obj[Symbol.asyncIterator] === 'function') + } + + function isIterable (obj) { + return !!(obj != null && (typeof obj[Symbol.iterator] === 'function' || typeof obj[Symbol.asyncIterator] === 'function')) + } + + function bodyLength (body) { + if (body == null) { + return 0 + } else if (isStream(body)) { + const state = body._readableState; + return state && state.objectMode === false && state.ended === true && Number.isFinite(state.length) + ? state.length + : null + } else if (isBlobLike(body)) { + return body.size != null ? body.size : null + } else if (isBuffer(body)) { + return body.byteLength + } + + return null + } + + function isDestroyed (body) { + return body && !!(body.destroyed || body[kDestroyed] || (stream.isDestroyed?.(body))) + } + + function destroy (stream, err) { + if (stream == null || !isStream(stream) || isDestroyed(stream)) { + return + } + + if (typeof stream.destroy === 'function') { + if (Object.getPrototypeOf(stream).constructor === IncomingMessage) { + // See: https://github.com/nodejs/node/pull/38505/files + stream.socket = null; + } + + stream.destroy(err); + } else if (err) { + queueMicrotask(() => { + stream.emit('error', err); + }); + } + + if (stream.destroyed !== true) { + stream[kDestroyed] = true; + } + } + + const KEEPALIVE_TIMEOUT_EXPR = /timeout=(\d+)/; + function parseKeepAliveTimeout (val) { + const m = val.toString().match(KEEPALIVE_TIMEOUT_EXPR); + return m ? parseInt(m[1], 10) * 1000 : null + } + + /** + * Retrieves a header name and returns its lowercase value. + * @param {string | Buffer} value Header name + * @returns {string} + */ + function headerNameToString (value) { + return typeof value === 'string' + ? headerNameLowerCasedRecord[value] ?? value.toLowerCase() + : tree.lookup(value) ?? value.toString('latin1').toLowerCase() + } + + /** + * Receive the buffer as a string and return its lowercase value. + * @param {Buffer} value Header name + * @returns {string} + */ + function bufferToLowerCasedHeaderName (value) { + return tree.lookup(value) ?? value.toString('latin1').toLowerCase() + } + + /** + * @param {Record | (Buffer | string | (Buffer | string)[])[]} headers + * @param {Record} [obj] + * @returns {Record} + */ + function parseHeaders (headers, obj) { + if (obj === undefined) obj = {}; + for (let i = 0; i < headers.length; i += 2) { + const key = headerNameToString(headers[i]); + let val = obj[key]; + + if (val) { + if (typeof val === 'string') { + val = [val]; + obj[key] = val; + } + val.push(headers[i + 1].toString('utf8')); + } else { + const headersValue = headers[i + 1]; + if (typeof headersValue === 'string') { + obj[key] = headersValue; + } else { + obj[key] = Array.isArray(headersValue) ? headersValue.map(x => x.toString('utf8')) : headersValue.toString('utf8'); + } + } + } + + // See https://github.com/nodejs/node/pull/46528 + if ('content-length' in obj && 'content-disposition' in obj) { + obj['content-disposition'] = Buffer.from(obj['content-disposition']).toString('latin1'); + } + + return obj + } + + function parseRawHeaders (headers) { + const len = headers.length; + const ret = new Array(len); + + let hasContentLength = false; + let contentDispositionIdx = -1; + let key; + let val; + let kLen = 0; + + for (let n = 0; n < headers.length; n += 2) { + key = headers[n]; + val = headers[n + 1]; + + typeof key !== 'string' && (key = key.toString()); + typeof val !== 'string' && (val = val.toString('utf8')); + + kLen = key.length; + if (kLen === 14 && key[7] === '-' && (key === 'content-length' || key.toLowerCase() === 'content-length')) { + hasContentLength = true; + } else if (kLen === 19 && key[7] === '-' && (key === 'content-disposition' || key.toLowerCase() === 'content-disposition')) { + contentDispositionIdx = n + 1; + } + ret[n] = key; + ret[n + 1] = val; + } + + // See https://github.com/nodejs/node/pull/46528 + if (hasContentLength && contentDispositionIdx !== -1) { + ret[contentDispositionIdx] = Buffer.from(ret[contentDispositionIdx]).toString('latin1'); + } + + return ret + } + + function isBuffer (buffer) { + // See, https://github.com/mcollina/undici/pull/319 + return buffer instanceof Uint8Array || Buffer.isBuffer(buffer) + } + + function validateHandler (handler, method, upgrade) { + if (!handler || typeof handler !== 'object') { + throw new InvalidArgumentError('handler must be an object') + } + + if (typeof handler.onConnect !== 'function') { + throw new InvalidArgumentError('invalid onConnect method') + } + + if (typeof handler.onError !== 'function') { + throw new InvalidArgumentError('invalid onError method') + } + + if (typeof handler.onBodySent !== 'function' && handler.onBodySent !== undefined) { + throw new InvalidArgumentError('invalid onBodySent method') + } + + if (upgrade || method === 'CONNECT') { + if (typeof handler.onUpgrade !== 'function') { + throw new InvalidArgumentError('invalid onUpgrade method') + } + } else { + if (typeof handler.onHeaders !== 'function') { + throw new InvalidArgumentError('invalid onHeaders method') + } + + if (typeof handler.onData !== 'function') { + throw new InvalidArgumentError('invalid onData method') + } + + if (typeof handler.onComplete !== 'function') { + throw new InvalidArgumentError('invalid onComplete method') + } + } + } + + // A body is disturbed if it has been read from and it cannot + // be re-used without losing state or data. + function isDisturbed (body) { + // TODO (fix): Why is body[kBodyUsed] needed? + return !!(body && (stream.isDisturbed(body) || body[kBodyUsed])) + } + + function isErrored (body) { + return !!(body && stream.isErrored(body)) + } + + function isReadable (body) { + return !!(body && stream.isReadable(body)) + } + + function getSocketInfo (socket) { + return { + localAddress: socket.localAddress, + localPort: socket.localPort, + remoteAddress: socket.remoteAddress, + remotePort: socket.remotePort, + remoteFamily: socket.remoteFamily, + timeout: socket.timeout, + bytesWritten: socket.bytesWritten, + bytesRead: socket.bytesRead + } + } + + /** @type {globalThis['ReadableStream']} */ + function ReadableStreamFrom (iterable) { + // We cannot use ReadableStream.from here because it does not return a byte stream. + + let iterator; + return new ReadableStream( + { + async start () { + iterator = iterable[Symbol.asyncIterator](); + }, + async pull (controller) { + const { done, value } = await iterator.next(); + if (done) { + queueMicrotask(() => { + controller.close(); + controller.byobRequest?.respond(0); + }); + } else { + const buf = Buffer.isBuffer(value) ? value : Buffer.from(value); + if (buf.byteLength) { + controller.enqueue(new Uint8Array(buf)); + } + } + return controller.desiredSize > 0 + }, + async cancel (reason) { + await iterator.return(); + }, + type: 'bytes' + } + ) + } + + // The chunk should be a FormData instance and contains + // all the required methods. + function isFormDataLike (object) { + return ( + object && + typeof object === 'object' && + typeof object.append === 'function' && + typeof object.delete === 'function' && + typeof object.get === 'function' && + typeof object.getAll === 'function' && + typeof object.has === 'function' && + typeof object.set === 'function' && + object[Symbol.toStringTag] === 'FormData' + ) + } + + function addAbortListener (signal, listener) { + if ('addEventListener' in signal) { + signal.addEventListener('abort', listener, { once: true }); + return () => signal.removeEventListener('abort', listener) + } + signal.addListener('abort', listener); + return () => signal.removeListener('abort', listener) + } + + const hasToWellFormed = typeof String.prototype.toWellFormed === 'function'; + const hasIsWellFormed = typeof String.prototype.isWellFormed === 'function'; + + /** + * @param {string} val + */ + function toUSVString (val) { + return hasToWellFormed ? `${val}`.toWellFormed() : nodeUtil.toUSVString(val) + } + + /** + * @param {string} val + */ + // TODO: move this to webidl + function isUSVString (val) { + return hasIsWellFormed ? `${val}`.isWellFormed() : toUSVString(val) === `${val}` + } + + /** + * @see https://tools.ietf.org/html/rfc7230#section-3.2.6 + * @param {number} c + */ + function isTokenCharCode (c) { + switch (c) { + case 0x22: + case 0x28: + case 0x29: + case 0x2c: + case 0x2f: + case 0x3a: + case 0x3b: + case 0x3c: + case 0x3d: + case 0x3e: + case 0x3f: + case 0x40: + case 0x5b: + case 0x5c: + case 0x5d: + case 0x7b: + case 0x7d: + // DQUOTE and "(),/:;<=>?@[\]{}" + return false + default: + // VCHAR %x21-7E + return c >= 0x21 && c <= 0x7e + } + } + + /** + * @param {string} characters + */ + function isValidHTTPToken (characters) { + if (characters.length === 0) { + return false + } + for (let i = 0; i < characters.length; ++i) { + if (!isTokenCharCode(characters.charCodeAt(i))) { + return false + } + } + return true + } + + // headerCharRegex have been lifted from + // https://github.com/nodejs/node/blob/main/lib/_http_common.js + + /** + * Matches if val contains an invalid field-vchar + * field-value = *( field-content / obs-fold ) + * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] + * field-vchar = VCHAR / obs-text + */ + const headerCharRegex = /[^\t\x20-\x7e\x80-\xff]/; + + /** + * @param {string} characters + */ + function isValidHeaderValue (characters) { + return !headerCharRegex.test(characters) + } + + // Parsed accordingly to RFC 9110 + // https://www.rfc-editor.org/rfc/rfc9110#field.content-range + function parseRangeHeader (range) { + if (range == null || range === '') return { start: 0, end: null, size: null } + + const m = range ? range.match(/^bytes (\d+)-(\d+)\/(\d+)?$/) : null; + return m + ? { + start: parseInt(m[1]), + end: m[2] ? parseInt(m[2]) : null, + size: m[3] ? parseInt(m[3]) : null + } + : null + } + + function addListener (obj, name, listener) { + const listeners = (obj[kListeners] ??= []); + listeners.push([name, listener]); + obj.on(name, listener); + return obj + } + + function removeAllListeners (obj) { + for (const [name, listener] of obj[kListeners] ?? []) { + obj.removeListener(name, listener); + } + obj[kListeners] = null; + } + + function errorRequest (client, request, err) { + try { + request.onError(err); + assert(request.aborted); + } catch (err) { + client.emit('error', err); + } + } + + const kEnumerableProperty = Object.create(null); + kEnumerableProperty.enumerable = true; + + const normalizedMethodRecordsBase = { + delete: 'DELETE', + DELETE: 'DELETE', + get: 'GET', + GET: 'GET', + head: 'HEAD', + HEAD: 'HEAD', + options: 'OPTIONS', + OPTIONS: 'OPTIONS', + post: 'POST', + POST: 'POST', + put: 'PUT', + PUT: 'PUT' + }; + + const normalizedMethodRecords = { + ...normalizedMethodRecordsBase, + patch: 'patch', + PATCH: 'PATCH' + }; + + // Note: object prototypes should not be able to be referenced. e.g. `Object#hasOwnProperty`. + Object.setPrototypeOf(normalizedMethodRecordsBase, null); + Object.setPrototypeOf(normalizedMethodRecords, null); + + util$7 = { + kEnumerableProperty, + nop, + isDisturbed, + isErrored, + isReadable, + toUSVString, + isUSVString, + isBlobLike, + parseOrigin, + parseURL, + getServerName, + isStream, + isIterable, + isAsyncIterable, + isDestroyed, + headerNameToString, + bufferToLowerCasedHeaderName, + addListener, + removeAllListeners, + errorRequest, + parseRawHeaders, + parseHeaders, + parseKeepAliveTimeout, + destroy, + bodyLength, + deepClone, + ReadableStreamFrom, + isBuffer, + validateHandler, + getSocketInfo, + isFormDataLike, + buildURL, + addAbortListener, + isValidHTTPToken, + isValidHeaderValue, + isTokenCharCode, + parseRangeHeader, + normalizedMethodRecordsBase, + normalizedMethodRecords, + isValidPort, + isHttpOrHttpsPrefixed, + nodeMajor, + nodeMinor, + safeHTTPMethods: ['GET', 'HEAD', 'OPTIONS', 'TRACE'], + wrapRequestBody + }; + return util$7; +} + +var diagnostics; +var hasRequiredDiagnostics; + +function requireDiagnostics () { + if (hasRequiredDiagnostics) return diagnostics; + hasRequiredDiagnostics = 1; + const diagnosticsChannel = require$$0$7; + const util = require$$0$6; + + const undiciDebugLog = util.debuglog('undici'); + const fetchDebuglog = util.debuglog('fetch'); + const websocketDebuglog = util.debuglog('websocket'); + let isClientSet = false; + const channels = { + // Client + beforeConnect: diagnosticsChannel.channel('undici:client:beforeConnect'), + connected: diagnosticsChannel.channel('undici:client:connected'), + connectError: diagnosticsChannel.channel('undici:client:connectError'), + sendHeaders: diagnosticsChannel.channel('undici:client:sendHeaders'), + // Request + create: diagnosticsChannel.channel('undici:request:create'), + bodySent: diagnosticsChannel.channel('undici:request:bodySent'), + headers: diagnosticsChannel.channel('undici:request:headers'), + trailers: diagnosticsChannel.channel('undici:request:trailers'), + error: diagnosticsChannel.channel('undici:request:error'), + // WebSocket + open: diagnosticsChannel.channel('undici:websocket:open'), + close: diagnosticsChannel.channel('undici:websocket:close'), + socketError: diagnosticsChannel.channel('undici:websocket:socket_error'), + ping: diagnosticsChannel.channel('undici:websocket:ping'), + pong: diagnosticsChannel.channel('undici:websocket:pong') + }; + + if (undiciDebugLog.enabled || fetchDebuglog.enabled) { + const debuglog = fetchDebuglog.enabled ? fetchDebuglog : undiciDebugLog; + + // Track all Client events + diagnosticsChannel.channel('undici:client:beforeConnect').subscribe(evt => { + const { + connectParams: { version, protocol, port, host } + } = evt; + debuglog( + 'connecting to %s using %s%s', + `${host}${port ? `:${port}` : ''}`, + protocol, + version + ); + }); + + diagnosticsChannel.channel('undici:client:connected').subscribe(evt => { + const { + connectParams: { version, protocol, port, host } + } = evt; + debuglog( + 'connected to %s using %s%s', + `${host}${port ? `:${port}` : ''}`, + protocol, + version + ); + }); + + diagnosticsChannel.channel('undici:client:connectError').subscribe(evt => { + const { + connectParams: { version, protocol, port, host }, + error + } = evt; + debuglog( + 'connection to %s using %s%s errored - %s', + `${host}${port ? `:${port}` : ''}`, + protocol, + version, + error.message + ); + }); + + diagnosticsChannel.channel('undici:client:sendHeaders').subscribe(evt => { + const { + request: { method, path, origin } + } = evt; + debuglog('sending request to %s %s/%s', method, origin, path); + }); + + // Track Request events + diagnosticsChannel.channel('undici:request:headers').subscribe(evt => { + const { + request: { method, path, origin }, + response: { statusCode } + } = evt; + debuglog( + 'received response to %s %s/%s - HTTP %d', + method, + origin, + path, + statusCode + ); + }); + + diagnosticsChannel.channel('undici:request:trailers').subscribe(evt => { + const { + request: { method, path, origin } + } = evt; + debuglog('trailers received from %s %s/%s', method, origin, path); + }); + + diagnosticsChannel.channel('undici:request:error').subscribe(evt => { + const { + request: { method, path, origin }, + error + } = evt; + debuglog( + 'request to %s %s/%s errored - %s', + method, + origin, + path, + error.message + ); + }); + + isClientSet = true; + } + + if (websocketDebuglog.enabled) { + if (!isClientSet) { + const debuglog = undiciDebugLog.enabled ? undiciDebugLog : websocketDebuglog; + diagnosticsChannel.channel('undici:client:beforeConnect').subscribe(evt => { + const { + connectParams: { version, protocol, port, host } + } = evt; + debuglog( + 'connecting to %s%s using %s%s', + host, + port ? `:${port}` : '', + protocol, + version + ); + }); + + diagnosticsChannel.channel('undici:client:connected').subscribe(evt => { + const { + connectParams: { version, protocol, port, host } + } = evt; + debuglog( + 'connected to %s%s using %s%s', + host, + port ? `:${port}` : '', + protocol, + version + ); + }); + + diagnosticsChannel.channel('undici:client:connectError').subscribe(evt => { + const { + connectParams: { version, protocol, port, host }, + error + } = evt; + debuglog( + 'connection to %s%s using %s%s errored - %s', + host, + port ? `:${port}` : '', + protocol, + version, + error.message + ); + }); + + diagnosticsChannel.channel('undici:client:sendHeaders').subscribe(evt => { + const { + request: { method, path, origin } + } = evt; + debuglog('sending request to %s %s/%s', method, origin, path); + }); + } + + // Track all WebSocket events + diagnosticsChannel.channel('undici:websocket:open').subscribe(evt => { + const { + address: { address, port } + } = evt; + websocketDebuglog('connection opened %s%s', address, port ? `:${port}` : ''); + }); + + diagnosticsChannel.channel('undici:websocket:close').subscribe(evt => { + const { websocket, code, reason } = evt; + websocketDebuglog( + 'closed connection to %s - %s %s', + websocket.url, + code, + reason + ); + }); + + diagnosticsChannel.channel('undici:websocket:socket_error').subscribe(err => { + websocketDebuglog('connection errored - %s', err.message); + }); + + diagnosticsChannel.channel('undici:websocket:ping').subscribe(evt => { + websocketDebuglog('ping received'); + }); + + diagnosticsChannel.channel('undici:websocket:pong').subscribe(evt => { + websocketDebuglog('pong received'); + }); + } + + diagnostics = { + channels + }; + return diagnostics; +} + +var request$1; +var hasRequiredRequest$1; + +function requireRequest$1 () { + if (hasRequiredRequest$1) return request$1; + hasRequiredRequest$1 = 1; + + const { + InvalidArgumentError, + NotSupportedError + } = requireErrors(); + const assert = require$$0$4; + const { + isValidHTTPToken, + isValidHeaderValue, + isStream, + destroy, + isBuffer, + isFormDataLike, + isIterable, + isBlobLike, + buildURL, + validateHandler, + getServerName, + normalizedMethodRecords + } = requireUtil$7(); + const { channels } = requireDiagnostics(); + const { headerNameLowerCasedRecord } = requireConstants$4(); + + // Verifies that a given path is valid does not contain control chars \x00 to \x20 + const invalidPathRegex = /[^\u0021-\u00ff]/; + + const kHandler = Symbol('handler'); + + class Request { + constructor (origin, { + path, + method, + body, + headers, + query, + idempotent, + blocking, + upgrade, + headersTimeout, + bodyTimeout, + reset, + throwOnError, + expectContinue, + servername + }, handler) { + if (typeof path !== 'string') { + throw new InvalidArgumentError('path must be a string') + } else if ( + path[0] !== '/' && + !(path.startsWith('http://') || path.startsWith('https://')) && + method !== 'CONNECT' + ) { + throw new InvalidArgumentError('path must be an absolute URL or start with a slash') + } else if (invalidPathRegex.test(path)) { + throw new InvalidArgumentError('invalid request path') + } + + if (typeof method !== 'string') { + throw new InvalidArgumentError('method must be a string') + } else if (normalizedMethodRecords[method] === undefined && !isValidHTTPToken(method)) { + throw new InvalidArgumentError('invalid request method') + } + + if (upgrade && typeof upgrade !== 'string') { + throw new InvalidArgumentError('upgrade must be a string') + } + + if (headersTimeout != null && (!Number.isFinite(headersTimeout) || headersTimeout < 0)) { + throw new InvalidArgumentError('invalid headersTimeout') + } + + if (bodyTimeout != null && (!Number.isFinite(bodyTimeout) || bodyTimeout < 0)) { + throw new InvalidArgumentError('invalid bodyTimeout') + } + + if (reset != null && typeof reset !== 'boolean') { + throw new InvalidArgumentError('invalid reset') + } + + if (expectContinue != null && typeof expectContinue !== 'boolean') { + throw new InvalidArgumentError('invalid expectContinue') + } + + this.headersTimeout = headersTimeout; + + this.bodyTimeout = bodyTimeout; + + this.throwOnError = throwOnError === true; + + this.method = method; + + this.abort = null; + + if (body == null) { + this.body = null; + } else if (isStream(body)) { + this.body = body; + + const rState = this.body._readableState; + if (!rState || !rState.autoDestroy) { + this.endHandler = function autoDestroy () { + destroy(this); + }; + this.body.on('end', this.endHandler); + } + + this.errorHandler = err => { + if (this.abort) { + this.abort(err); + } else { + this.error = err; + } + }; + this.body.on('error', this.errorHandler); + } else if (isBuffer(body)) { + this.body = body.byteLength ? body : null; + } else if (ArrayBuffer.isView(body)) { + this.body = body.buffer.byteLength ? Buffer.from(body.buffer, body.byteOffset, body.byteLength) : null; + } else if (body instanceof ArrayBuffer) { + this.body = body.byteLength ? Buffer.from(body) : null; + } else if (typeof body === 'string') { + this.body = body.length ? Buffer.from(body) : null; + } else if (isFormDataLike(body) || isIterable(body) || isBlobLike(body)) { + this.body = body; + } else { + throw new InvalidArgumentError('body must be a string, a Buffer, a Readable stream, an iterable, or an async iterable') + } + + this.completed = false; + + this.aborted = false; + + this.upgrade = upgrade || null; + + this.path = query ? buildURL(path, query) : path; + + this.origin = origin; + + this.idempotent = idempotent == null + ? method === 'HEAD' || method === 'GET' + : idempotent; + + this.blocking = blocking == null ? false : blocking; + + this.reset = reset == null ? null : reset; + + this.host = null; + + this.contentLength = null; + + this.contentType = null; + + this.headers = []; + + // Only for H2 + this.expectContinue = expectContinue != null ? expectContinue : false; + + if (Array.isArray(headers)) { + if (headers.length % 2 !== 0) { + throw new InvalidArgumentError('headers array must be even') + } + for (let i = 0; i < headers.length; i += 2) { + processHeader(this, headers[i], headers[i + 1]); + } + } else if (headers && typeof headers === 'object') { + if (headers[Symbol.iterator]) { + for (const header of headers) { + if (!Array.isArray(header) || header.length !== 2) { + throw new InvalidArgumentError('headers must be in key-value pair format') + } + processHeader(this, header[0], header[1]); + } + } else { + const keys = Object.keys(headers); + for (let i = 0; i < keys.length; ++i) { + processHeader(this, keys[i], headers[keys[i]]); + } + } + } else if (headers != null) { + throw new InvalidArgumentError('headers must be an object or an array') + } + + validateHandler(handler, method, upgrade); + + this.servername = servername || getServerName(this.host); + + this[kHandler] = handler; + + if (channels.create.hasSubscribers) { + channels.create.publish({ request: this }); + } + } + + onBodySent (chunk) { + if (this[kHandler].onBodySent) { + try { + return this[kHandler].onBodySent(chunk) + } catch (err) { + this.abort(err); + } + } + } + + onRequestSent () { + if (channels.bodySent.hasSubscribers) { + channels.bodySent.publish({ request: this }); + } + + if (this[kHandler].onRequestSent) { + try { + return this[kHandler].onRequestSent() + } catch (err) { + this.abort(err); + } + } + } + + onConnect (abort) { + assert(!this.aborted); + assert(!this.completed); + + if (this.error) { + abort(this.error); + } else { + this.abort = abort; + return this[kHandler].onConnect(abort) + } + } + + onResponseStarted () { + return this[kHandler].onResponseStarted?.() + } + + onHeaders (statusCode, headers, resume, statusText) { + assert(!this.aborted); + assert(!this.completed); + + if (channels.headers.hasSubscribers) { + channels.headers.publish({ request: this, response: { statusCode, headers, statusText } }); + } + + try { + return this[kHandler].onHeaders(statusCode, headers, resume, statusText) + } catch (err) { + this.abort(err); + } + } + + onData (chunk) { + assert(!this.aborted); + assert(!this.completed); + + try { + return this[kHandler].onData(chunk) + } catch (err) { + this.abort(err); + return false + } + } + + onUpgrade (statusCode, headers, socket) { + assert(!this.aborted); + assert(!this.completed); + + return this[kHandler].onUpgrade(statusCode, headers, socket) + } + + onComplete (trailers) { + this.onFinally(); + + assert(!this.aborted); + + this.completed = true; + if (channels.trailers.hasSubscribers) { + channels.trailers.publish({ request: this, trailers }); + } + + try { + return this[kHandler].onComplete(trailers) + } catch (err) { + // TODO (fix): This might be a bad idea? + this.onError(err); + } + } + + onError (error) { + this.onFinally(); + + if (channels.error.hasSubscribers) { + channels.error.publish({ request: this, error }); + } + + if (this.aborted) { + return + } + this.aborted = true; + + return this[kHandler].onError(error) + } + + onFinally () { + if (this.errorHandler) { + this.body.off('error', this.errorHandler); + this.errorHandler = null; + } + + if (this.endHandler) { + this.body.off('end', this.endHandler); + this.endHandler = null; + } + } + + addHeader (key, value) { + processHeader(this, key, value); + return this + } + } + + function processHeader (request, key, val) { + if (val && (typeof val === 'object' && !Array.isArray(val))) { + throw new InvalidArgumentError(`invalid ${key} header`) + } else if (val === undefined) { + return + } + + let headerName = headerNameLowerCasedRecord[key]; + + if (headerName === undefined) { + headerName = key.toLowerCase(); + if (headerNameLowerCasedRecord[headerName] === undefined && !isValidHTTPToken(headerName)) { + throw new InvalidArgumentError('invalid header key') + } + } + + if (Array.isArray(val)) { + const arr = []; + for (let i = 0; i < val.length; i++) { + if (typeof val[i] === 'string') { + if (!isValidHeaderValue(val[i])) { + throw new InvalidArgumentError(`invalid ${key} header`) + } + arr.push(val[i]); + } else if (val[i] === null) { + arr.push(''); + } else if (typeof val[i] === 'object') { + throw new InvalidArgumentError(`invalid ${key} header`) + } else { + arr.push(`${val[i]}`); + } + } + val = arr; + } else if (typeof val === 'string') { + if (!isValidHeaderValue(val)) { + throw new InvalidArgumentError(`invalid ${key} header`) + } + } else if (val === null) { + val = ''; + } else { + val = `${val}`; + } + + if (request.host === null && headerName === 'host') { + if (typeof val !== 'string') { + throw new InvalidArgumentError('invalid host header') + } + // Consumed by Client + request.host = val; + } else if (request.contentLength === null && headerName === 'content-length') { + request.contentLength = parseInt(val, 10); + if (!Number.isFinite(request.contentLength)) { + throw new InvalidArgumentError('invalid content-length header') + } + } else if (request.contentType === null && headerName === 'content-type') { + request.contentType = val; + request.headers.push(key, val); + } else if (headerName === 'transfer-encoding' || headerName === 'keep-alive' || headerName === 'upgrade') { + throw new InvalidArgumentError(`invalid ${headerName} header`) + } else if (headerName === 'connection') { + const value = typeof val === 'string' ? val.toLowerCase() : null; + if (value !== 'close' && value !== 'keep-alive') { + throw new InvalidArgumentError('invalid connection header') + } + + if (value === 'close') { + request.reset = true; + } + } else if (headerName === 'expect') { + throw new NotSupportedError('expect header not supported') + } else { + request.headers.push(key, val); + } + } + + request$1 = Request; + return request$1; +} + +var dispatcher; +var hasRequiredDispatcher; + +function requireDispatcher () { + if (hasRequiredDispatcher) return dispatcher; + hasRequiredDispatcher = 1; + const EventEmitter = require$$8; + + class Dispatcher extends EventEmitter { + dispatch () { + throw new Error('not implemented') + } + + close () { + throw new Error('not implemented') + } + + destroy () { + throw new Error('not implemented') + } + + compose (...args) { + // So we handle [interceptor1, interceptor2] or interceptor1, interceptor2, ... + const interceptors = Array.isArray(args[0]) ? args[0] : args; + let dispatch = this.dispatch.bind(this); + + for (const interceptor of interceptors) { + if (interceptor == null) { + continue + } + + if (typeof interceptor !== 'function') { + throw new TypeError(`invalid interceptor, expected function received ${typeof interceptor}`) + } + + dispatch = interceptor(dispatch); + + if (dispatch == null || typeof dispatch !== 'function' || dispatch.length !== 2) { + throw new TypeError('invalid interceptor') + } + } + + return new ComposedDispatcher(this, dispatch) + } + } + + class ComposedDispatcher extends Dispatcher { + #dispatcher = null + #dispatch = null + + constructor (dispatcher, dispatch) { + super(); + this.#dispatcher = dispatcher; + this.#dispatch = dispatch; + } + + dispatch (...args) { + this.#dispatch(...args); + } + + close (...args) { + return this.#dispatcher.close(...args) + } + + destroy (...args) { + return this.#dispatcher.destroy(...args) + } + } + + dispatcher = Dispatcher; + return dispatcher; +} + +var dispatcherBase; +var hasRequiredDispatcherBase; + +function requireDispatcherBase () { + if (hasRequiredDispatcherBase) return dispatcherBase; + hasRequiredDispatcherBase = 1; + + const Dispatcher = requireDispatcher(); + const { + ClientDestroyedError, + ClientClosedError, + InvalidArgumentError + } = requireErrors(); + const { kDestroy, kClose, kClosed, kDestroyed, kDispatch, kInterceptors } = requireSymbols$4(); + + const kOnDestroyed = Symbol('onDestroyed'); + const kOnClosed = Symbol('onClosed'); + const kInterceptedDispatch = Symbol('Intercepted Dispatch'); + + class DispatcherBase extends Dispatcher { + constructor () { + super(); + + this[kDestroyed] = false; + this[kOnDestroyed] = null; + this[kClosed] = false; + this[kOnClosed] = []; + } + + get destroyed () { + return this[kDestroyed] + } + + get closed () { + return this[kClosed] + } + + get interceptors () { + return this[kInterceptors] + } + + set interceptors (newInterceptors) { + if (newInterceptors) { + for (let i = newInterceptors.length - 1; i >= 0; i--) { + const interceptor = this[kInterceptors][i]; + if (typeof interceptor !== 'function') { + throw new InvalidArgumentError('interceptor must be an function') + } + } + } + + this[kInterceptors] = newInterceptors; + } + + close (callback) { + if (callback === undefined) { + return new Promise((resolve, reject) => { + this.close((err, data) => { + return err ? reject(err) : resolve(data) + }); + }) + } + + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } + + if (this[kDestroyed]) { + queueMicrotask(() => callback(new ClientDestroyedError(), null)); + return + } + + if (this[kClosed]) { + if (this[kOnClosed]) { + this[kOnClosed].push(callback); + } else { + queueMicrotask(() => callback(null, null)); + } + return + } + + this[kClosed] = true; + this[kOnClosed].push(callback); + + const onClosed = () => { + const callbacks = this[kOnClosed]; + this[kOnClosed] = null; + for (let i = 0; i < callbacks.length; i++) { + callbacks[i](null, null); + } + }; + + // Should not error. + this[kClose]() + .then(() => this.destroy()) + .then(() => { + queueMicrotask(onClosed); + }); + } + + destroy (err, callback) { + if (typeof err === 'function') { + callback = err; + err = null; + } + + if (callback === undefined) { + return new Promise((resolve, reject) => { + this.destroy(err, (err, data) => { + return err ? /* istanbul ignore next: should never error */ reject(err) : resolve(data) + }); + }) + } + + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } + + if (this[kDestroyed]) { + if (this[kOnDestroyed]) { + this[kOnDestroyed].push(callback); + } else { + queueMicrotask(() => callback(null, null)); + } + return + } + + if (!err) { + err = new ClientDestroyedError(); + } + + this[kDestroyed] = true; + this[kOnDestroyed] = this[kOnDestroyed] || []; + this[kOnDestroyed].push(callback); + + const onDestroyed = () => { + const callbacks = this[kOnDestroyed]; + this[kOnDestroyed] = null; + for (let i = 0; i < callbacks.length; i++) { + callbacks[i](null, null); + } + }; + + // Should not error. + this[kDestroy](err).then(() => { + queueMicrotask(onDestroyed); + }); + } + + [kInterceptedDispatch] (opts, handler) { + if (!this[kInterceptors] || this[kInterceptors].length === 0) { + this[kInterceptedDispatch] = this[kDispatch]; + return this[kDispatch](opts, handler) + } + + let dispatch = this[kDispatch].bind(this); + for (let i = this[kInterceptors].length - 1; i >= 0; i--) { + dispatch = this[kInterceptors][i](dispatch); + } + this[kInterceptedDispatch] = dispatch; + return dispatch(opts, handler) + } + + dispatch (opts, handler) { + if (!handler || typeof handler !== 'object') { + throw new InvalidArgumentError('handler must be an object') + } + + try { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('opts must be an object.') + } + + if (this[kDestroyed] || this[kOnDestroyed]) { + throw new ClientDestroyedError() + } + + if (this[kClosed]) { + throw new ClientClosedError() + } + + return this[kInterceptedDispatch](opts, handler) + } catch (err) { + if (typeof handler.onError !== 'function') { + throw new InvalidArgumentError('invalid onError method') + } + + handler.onError(err); + + return false + } + } + } + + dispatcherBase = DispatcherBase; + return dispatcherBase; +} + +var connect; +var hasRequiredConnect; + +function requireConnect () { + if (hasRequiredConnect) return connect; + hasRequiredConnect = 1; + + const net = require$$4; + const assert = require$$0$4; + const util = requireUtil$7(); + const { InvalidArgumentError, ConnectTimeoutError } = requireErrors(); + + let tls; // include tls conditionally since it is not always available + + // TODO: session re-use does not wait for the first + // connection to resolve the session and might therefore + // resolve the same servername multiple times even when + // re-use is enabled. + + let SessionCache; + // FIXME: remove workaround when the Node bug is fixed + // https://github.com/nodejs/node/issues/49344#issuecomment-1741776308 + if (commonjsGlobal.FinalizationRegistry && !(process.env.NODE_V8_COVERAGE || process.env.UNDICI_NO_FG)) { + SessionCache = class WeakSessionCache { + constructor (maxCachedSessions) { + this._maxCachedSessions = maxCachedSessions; + this._sessionCache = new Map(); + this._sessionRegistry = new commonjsGlobal.FinalizationRegistry((key) => { + if (this._sessionCache.size < this._maxCachedSessions) { + return + } + + const ref = this._sessionCache.get(key); + if (ref !== undefined && ref.deref() === undefined) { + this._sessionCache.delete(key); + } + }); + } + + get (sessionKey) { + const ref = this._sessionCache.get(sessionKey); + return ref ? ref.deref() : null + } + + set (sessionKey, session) { + if (this._maxCachedSessions === 0) { + return + } + + this._sessionCache.set(sessionKey, new WeakRef(session)); + this._sessionRegistry.register(session, sessionKey); + } + }; + } else { + SessionCache = class SimpleSessionCache { + constructor (maxCachedSessions) { + this._maxCachedSessions = maxCachedSessions; + this._sessionCache = new Map(); + } + + get (sessionKey) { + return this._sessionCache.get(sessionKey) + } + + set (sessionKey, session) { + if (this._maxCachedSessions === 0) { + return + } + + if (this._sessionCache.size >= this._maxCachedSessions) { + // remove the oldest session + const { value: oldestKey } = this._sessionCache.keys().next(); + this._sessionCache.delete(oldestKey); + } + + this._sessionCache.set(sessionKey, session); + } + }; + } + + function buildConnector ({ allowH2, maxCachedSessions, socketPath, timeout, session: customSession, ...opts }) { + if (maxCachedSessions != null && (!Number.isInteger(maxCachedSessions) || maxCachedSessions < 0)) { + throw new InvalidArgumentError('maxCachedSessions must be a positive integer or zero') + } + + const options = { path: socketPath, ...opts }; + const sessionCache = new SessionCache(maxCachedSessions == null ? 100 : maxCachedSessions); + timeout = timeout == null ? 10e3 : timeout; + allowH2 = allowH2 != null ? allowH2 : false; + return function connect ({ hostname, host, protocol, port, servername, localAddress, httpSocket }, callback) { + let socket; + if (protocol === 'https:') { + if (!tls) { + tls = require$$4$1; + } + servername = servername || options.servername || util.getServerName(host) || null; + + const sessionKey = servername || hostname; + const session = customSession || sessionCache.get(sessionKey) || null; + + assert(sessionKey); + + socket = tls.connect({ + highWaterMark: 16384, // TLS in node can't have bigger HWM anyway... + ...options, + servername, + session, + localAddress, + // TODO(HTTP/2): Add support for h2c + ALPNProtocols: allowH2 ? ['http/1.1', 'h2'] : ['http/1.1'], + socket: httpSocket, // upgrade socket connection + port: port || 443, + host: hostname + }); + + socket + .on('session', function (session) { + // TODO (fix): Can a session become invalid once established? Don't think so? + sessionCache.set(sessionKey, session); + }); + } else { + assert(!httpSocket, 'httpSocket can only be sent on TLS update'); + socket = net.connect({ + highWaterMark: 64 * 1024, // Same as nodejs fs streams. + ...options, + localAddress, + port: port || 80, + host: hostname + }); + } + + // Set TCP keep alive options on the socket here instead of in connect() for the case of assigning the socket + if (options.keepAlive == null || options.keepAlive) { + const keepAliveInitialDelay = options.keepAliveInitialDelay === undefined ? 60e3 : options.keepAliveInitialDelay; + socket.setKeepAlive(true, keepAliveInitialDelay); + } + + const cancelTimeout = setupTimeout(() => onConnectTimeout(socket), timeout); + + socket + .setNoDelay(true) + .once(protocol === 'https:' ? 'secureConnect' : 'connect', function () { + cancelTimeout(); + + if (callback) { + const cb = callback; + callback = null; + cb(null, this); + } + }) + .on('error', function (err) { + cancelTimeout(); + + if (callback) { + const cb = callback; + callback = null; + cb(err); + } + }); + + return socket + } + } + + function setupTimeout (onConnectTimeout, timeout) { + if (!timeout) { + return () => {} + } + + let s1 = null; + let s2 = null; + const timeoutId = setTimeout(() => { + // setImmediate is added to make sure that we prioritize socket error events over timeouts + s1 = setImmediate(() => { + if (process.platform === 'win32') { + // Windows needs an extra setImmediate probably due to implementation differences in the socket logic + s2 = setImmediate(() => onConnectTimeout()); + } else { + onConnectTimeout(); + } + }); + }, timeout); + return () => { + clearTimeout(timeoutId); + clearImmediate(s1); + clearImmediate(s2); + } + } + + function onConnectTimeout (socket) { + let message = 'Connect Timeout Error'; + if (Array.isArray(socket.autoSelectFamilyAttemptedAddresses)) { + message += ` (attempted addresses: ${socket.autoSelectFamilyAttemptedAddresses.join(', ')})`; + } + util.destroy(socket, new ConnectTimeoutError(message)); + } + + connect = buildConnector; + return connect; +} + +var timers; +var hasRequiredTimers; + +function requireTimers () { + if (hasRequiredTimers) return timers; + hasRequiredTimers = 1; + + const TICK_MS = 499; + + let fastNow = Date.now(); + let fastNowTimeout; + + const fastTimers = []; + + function onTimeout () { + fastNow = Date.now(); + + let len = fastTimers.length; + let idx = 0; + while (idx < len) { + const timer = fastTimers[idx]; + + if (timer.state === 0) { + timer.state = fastNow + timer.delay - TICK_MS; + } else if (timer.state > 0 && fastNow >= timer.state) { + timer.state = -1; + timer.callback(timer.opaque); + } + + if (timer.state === -1) { + timer.state = -2; + if (idx !== len - 1) { + fastTimers[idx] = fastTimers.pop(); + } else { + fastTimers.pop(); + } + len -= 1; + } else { + idx += 1; + } + } + + if (fastTimers.length > 0) { + refreshTimeout(); + } + } + + function refreshTimeout () { + if (fastNowTimeout?.refresh) { + fastNowTimeout.refresh(); + } else { + clearTimeout(fastNowTimeout); + fastNowTimeout = setTimeout(onTimeout, TICK_MS); + if (fastNowTimeout.unref) { + fastNowTimeout.unref(); + } + } + } + + class Timeout { + constructor (callback, delay, opaque) { + this.callback = callback; + this.delay = delay; + this.opaque = opaque; + + // -2 not in timer list + // -1 in timer list but inactive + // 0 in timer list waiting for time + // > 0 in timer list waiting for time to expire + this.state = -2; + + this.refresh(); + } + + refresh () { + if (this.state === -2) { + fastTimers.push(this); + if (!fastNowTimeout || fastTimers.length === 1) { + refreshTimeout(); + } + } + + this.state = 0; + } + + clear () { + this.state = -1; + } + } + + timers = { + setTimeout (callback, delay, opaque) { + return delay <= 1e3 + ? setTimeout(callback, delay, opaque) + : new Timeout(callback, delay, opaque) + }, + clearTimeout (timeout) { + if (timeout instanceof Timeout) { + timeout.clear(); + } else { + clearTimeout(timeout); + } + } + }; + return timers; +} + +var constants$3 = {}; + +var utils = {}; + +var hasRequiredUtils; + +function requireUtils () { + if (hasRequiredUtils) return utils; + hasRequiredUtils = 1; + Object.defineProperty(utils, "__esModule", { value: true }); + utils.enumToMap = void 0; + function enumToMap(obj) { + const res = {}; + Object.keys(obj).forEach((key) => { + const value = obj[key]; + if (typeof value === 'number') { + res[key] = value; + } + }); + return res; + } + utils.enumToMap = enumToMap; + + return utils; +} + +var hasRequiredConstants$3; + +function requireConstants$3 () { + if (hasRequiredConstants$3) return constants$3; + hasRequiredConstants$3 = 1; + (function (exports) { + Object.defineProperty(exports, "__esModule", { value: true }); + exports.SPECIAL_HEADERS = exports.HEADER_STATE = exports.MINOR = exports.MAJOR = exports.CONNECTION_TOKEN_CHARS = exports.HEADER_CHARS = exports.TOKEN = exports.STRICT_TOKEN = exports.HEX = exports.URL_CHAR = exports.STRICT_URL_CHAR = exports.USERINFO_CHARS = exports.MARK = exports.ALPHANUM = exports.NUM = exports.HEX_MAP = exports.NUM_MAP = exports.ALPHA = exports.FINISH = exports.H_METHOD_MAP = exports.METHOD_MAP = exports.METHODS_RTSP = exports.METHODS_ICE = exports.METHODS_HTTP = exports.METHODS = exports.LENIENT_FLAGS = exports.FLAGS = exports.TYPE = exports.ERROR = void 0; + const utils_1 = requireUtils(); + (function (ERROR) { + ERROR[ERROR["OK"] = 0] = "OK"; + ERROR[ERROR["INTERNAL"] = 1] = "INTERNAL"; + ERROR[ERROR["STRICT"] = 2] = "STRICT"; + ERROR[ERROR["LF_EXPECTED"] = 3] = "LF_EXPECTED"; + ERROR[ERROR["UNEXPECTED_CONTENT_LENGTH"] = 4] = "UNEXPECTED_CONTENT_LENGTH"; + ERROR[ERROR["CLOSED_CONNECTION"] = 5] = "CLOSED_CONNECTION"; + ERROR[ERROR["INVALID_METHOD"] = 6] = "INVALID_METHOD"; + ERROR[ERROR["INVALID_URL"] = 7] = "INVALID_URL"; + ERROR[ERROR["INVALID_CONSTANT"] = 8] = "INVALID_CONSTANT"; + ERROR[ERROR["INVALID_VERSION"] = 9] = "INVALID_VERSION"; + ERROR[ERROR["INVALID_HEADER_TOKEN"] = 10] = "INVALID_HEADER_TOKEN"; + ERROR[ERROR["INVALID_CONTENT_LENGTH"] = 11] = "INVALID_CONTENT_LENGTH"; + ERROR[ERROR["INVALID_CHUNK_SIZE"] = 12] = "INVALID_CHUNK_SIZE"; + ERROR[ERROR["INVALID_STATUS"] = 13] = "INVALID_STATUS"; + ERROR[ERROR["INVALID_EOF_STATE"] = 14] = "INVALID_EOF_STATE"; + ERROR[ERROR["INVALID_TRANSFER_ENCODING"] = 15] = "INVALID_TRANSFER_ENCODING"; + ERROR[ERROR["CB_MESSAGE_BEGIN"] = 16] = "CB_MESSAGE_BEGIN"; + ERROR[ERROR["CB_HEADERS_COMPLETE"] = 17] = "CB_HEADERS_COMPLETE"; + ERROR[ERROR["CB_MESSAGE_COMPLETE"] = 18] = "CB_MESSAGE_COMPLETE"; + ERROR[ERROR["CB_CHUNK_HEADER"] = 19] = "CB_CHUNK_HEADER"; + ERROR[ERROR["CB_CHUNK_COMPLETE"] = 20] = "CB_CHUNK_COMPLETE"; + ERROR[ERROR["PAUSED"] = 21] = "PAUSED"; + ERROR[ERROR["PAUSED_UPGRADE"] = 22] = "PAUSED_UPGRADE"; + ERROR[ERROR["PAUSED_H2_UPGRADE"] = 23] = "PAUSED_H2_UPGRADE"; + ERROR[ERROR["USER"] = 24] = "USER"; + })(exports.ERROR || (exports.ERROR = {})); + (function (TYPE) { + TYPE[TYPE["BOTH"] = 0] = "BOTH"; + TYPE[TYPE["REQUEST"] = 1] = "REQUEST"; + TYPE[TYPE["RESPONSE"] = 2] = "RESPONSE"; + })(exports.TYPE || (exports.TYPE = {})); + (function (FLAGS) { + FLAGS[FLAGS["CONNECTION_KEEP_ALIVE"] = 1] = "CONNECTION_KEEP_ALIVE"; + FLAGS[FLAGS["CONNECTION_CLOSE"] = 2] = "CONNECTION_CLOSE"; + FLAGS[FLAGS["CONNECTION_UPGRADE"] = 4] = "CONNECTION_UPGRADE"; + FLAGS[FLAGS["CHUNKED"] = 8] = "CHUNKED"; + FLAGS[FLAGS["UPGRADE"] = 16] = "UPGRADE"; + FLAGS[FLAGS["CONTENT_LENGTH"] = 32] = "CONTENT_LENGTH"; + FLAGS[FLAGS["SKIPBODY"] = 64] = "SKIPBODY"; + FLAGS[FLAGS["TRAILING"] = 128] = "TRAILING"; + // 1 << 8 is unused + FLAGS[FLAGS["TRANSFER_ENCODING"] = 512] = "TRANSFER_ENCODING"; + })(exports.FLAGS || (exports.FLAGS = {})); + (function (LENIENT_FLAGS) { + LENIENT_FLAGS[LENIENT_FLAGS["HEADERS"] = 1] = "HEADERS"; + LENIENT_FLAGS[LENIENT_FLAGS["CHUNKED_LENGTH"] = 2] = "CHUNKED_LENGTH"; + LENIENT_FLAGS[LENIENT_FLAGS["KEEP_ALIVE"] = 4] = "KEEP_ALIVE"; + })(exports.LENIENT_FLAGS || (exports.LENIENT_FLAGS = {})); + var METHODS; + (function (METHODS) { + METHODS[METHODS["DELETE"] = 0] = "DELETE"; + METHODS[METHODS["GET"] = 1] = "GET"; + METHODS[METHODS["HEAD"] = 2] = "HEAD"; + METHODS[METHODS["POST"] = 3] = "POST"; + METHODS[METHODS["PUT"] = 4] = "PUT"; + /* pathological */ + METHODS[METHODS["CONNECT"] = 5] = "CONNECT"; + METHODS[METHODS["OPTIONS"] = 6] = "OPTIONS"; + METHODS[METHODS["TRACE"] = 7] = "TRACE"; + /* WebDAV */ + METHODS[METHODS["COPY"] = 8] = "COPY"; + METHODS[METHODS["LOCK"] = 9] = "LOCK"; + METHODS[METHODS["MKCOL"] = 10] = "MKCOL"; + METHODS[METHODS["MOVE"] = 11] = "MOVE"; + METHODS[METHODS["PROPFIND"] = 12] = "PROPFIND"; + METHODS[METHODS["PROPPATCH"] = 13] = "PROPPATCH"; + METHODS[METHODS["SEARCH"] = 14] = "SEARCH"; + METHODS[METHODS["UNLOCK"] = 15] = "UNLOCK"; + METHODS[METHODS["BIND"] = 16] = "BIND"; + METHODS[METHODS["REBIND"] = 17] = "REBIND"; + METHODS[METHODS["UNBIND"] = 18] = "UNBIND"; + METHODS[METHODS["ACL"] = 19] = "ACL"; + /* subversion */ + METHODS[METHODS["REPORT"] = 20] = "REPORT"; + METHODS[METHODS["MKACTIVITY"] = 21] = "MKACTIVITY"; + METHODS[METHODS["CHECKOUT"] = 22] = "CHECKOUT"; + METHODS[METHODS["MERGE"] = 23] = "MERGE"; + /* upnp */ + METHODS[METHODS["M-SEARCH"] = 24] = "M-SEARCH"; + METHODS[METHODS["NOTIFY"] = 25] = "NOTIFY"; + METHODS[METHODS["SUBSCRIBE"] = 26] = "SUBSCRIBE"; + METHODS[METHODS["UNSUBSCRIBE"] = 27] = "UNSUBSCRIBE"; + /* RFC-5789 */ + METHODS[METHODS["PATCH"] = 28] = "PATCH"; + METHODS[METHODS["PURGE"] = 29] = "PURGE"; + /* CalDAV */ + METHODS[METHODS["MKCALENDAR"] = 30] = "MKCALENDAR"; + /* RFC-2068, section 19.6.1.2 */ + METHODS[METHODS["LINK"] = 31] = "LINK"; + METHODS[METHODS["UNLINK"] = 32] = "UNLINK"; + /* icecast */ + METHODS[METHODS["SOURCE"] = 33] = "SOURCE"; + /* RFC-7540, section 11.6 */ + METHODS[METHODS["PRI"] = 34] = "PRI"; + /* RFC-2326 RTSP */ + METHODS[METHODS["DESCRIBE"] = 35] = "DESCRIBE"; + METHODS[METHODS["ANNOUNCE"] = 36] = "ANNOUNCE"; + METHODS[METHODS["SETUP"] = 37] = "SETUP"; + METHODS[METHODS["PLAY"] = 38] = "PLAY"; + METHODS[METHODS["PAUSE"] = 39] = "PAUSE"; + METHODS[METHODS["TEARDOWN"] = 40] = "TEARDOWN"; + METHODS[METHODS["GET_PARAMETER"] = 41] = "GET_PARAMETER"; + METHODS[METHODS["SET_PARAMETER"] = 42] = "SET_PARAMETER"; + METHODS[METHODS["REDIRECT"] = 43] = "REDIRECT"; + METHODS[METHODS["RECORD"] = 44] = "RECORD"; + /* RAOP */ + METHODS[METHODS["FLUSH"] = 45] = "FLUSH"; + })(METHODS = exports.METHODS || (exports.METHODS = {})); + exports.METHODS_HTTP = [ + METHODS.DELETE, + METHODS.GET, + METHODS.HEAD, + METHODS.POST, + METHODS.PUT, + METHODS.CONNECT, + METHODS.OPTIONS, + METHODS.TRACE, + METHODS.COPY, + METHODS.LOCK, + METHODS.MKCOL, + METHODS.MOVE, + METHODS.PROPFIND, + METHODS.PROPPATCH, + METHODS.SEARCH, + METHODS.UNLOCK, + METHODS.BIND, + METHODS.REBIND, + METHODS.UNBIND, + METHODS.ACL, + METHODS.REPORT, + METHODS.MKACTIVITY, + METHODS.CHECKOUT, + METHODS.MERGE, + METHODS['M-SEARCH'], + METHODS.NOTIFY, + METHODS.SUBSCRIBE, + METHODS.UNSUBSCRIBE, + METHODS.PATCH, + METHODS.PURGE, + METHODS.MKCALENDAR, + METHODS.LINK, + METHODS.UNLINK, + METHODS.PRI, + // TODO(indutny): should we allow it with HTTP? + METHODS.SOURCE, + ]; + exports.METHODS_ICE = [ + METHODS.SOURCE, + ]; + exports.METHODS_RTSP = [ + METHODS.OPTIONS, + METHODS.DESCRIBE, + METHODS.ANNOUNCE, + METHODS.SETUP, + METHODS.PLAY, + METHODS.PAUSE, + METHODS.TEARDOWN, + METHODS.GET_PARAMETER, + METHODS.SET_PARAMETER, + METHODS.REDIRECT, + METHODS.RECORD, + METHODS.FLUSH, + // For AirPlay + METHODS.GET, + METHODS.POST, + ]; + exports.METHOD_MAP = utils_1.enumToMap(METHODS); + exports.H_METHOD_MAP = {}; + Object.keys(exports.METHOD_MAP).forEach((key) => { + if (/^H/.test(key)) { + exports.H_METHOD_MAP[key] = exports.METHOD_MAP[key]; + } + }); + (function (FINISH) { + FINISH[FINISH["SAFE"] = 0] = "SAFE"; + FINISH[FINISH["SAFE_WITH_CB"] = 1] = "SAFE_WITH_CB"; + FINISH[FINISH["UNSAFE"] = 2] = "UNSAFE"; + })(exports.FINISH || (exports.FINISH = {})); + exports.ALPHA = []; + for (let i = 'A'.charCodeAt(0); i <= 'Z'.charCodeAt(0); i++) { + // Upper case + exports.ALPHA.push(String.fromCharCode(i)); + // Lower case + exports.ALPHA.push(String.fromCharCode(i + 0x20)); + } + exports.NUM_MAP = { + 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, + 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, + }; + exports.HEX_MAP = { + 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, + 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, + A: 0XA, B: 0XB, C: 0XC, D: 0XD, E: 0XE, F: 0XF, + a: 0xa, b: 0xb, c: 0xc, d: 0xd, e: 0xe, f: 0xf, + }; + exports.NUM = [ + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + ]; + exports.ALPHANUM = exports.ALPHA.concat(exports.NUM); + exports.MARK = ['-', '_', '.', '!', '~', '*', '\'', '(', ')']; + exports.USERINFO_CHARS = exports.ALPHANUM + .concat(exports.MARK) + .concat(['%', ';', ':', '&', '=', '+', '$', ',']); + // TODO(indutny): use RFC + exports.STRICT_URL_CHAR = [ + '!', '"', '$', '%', '&', '\'', + '(', ')', '*', '+', ',', '-', '.', '/', + ':', ';', '<', '=', '>', + '@', '[', '\\', ']', '^', '_', + '`', + '{', '|', '}', '~', + ].concat(exports.ALPHANUM); + exports.URL_CHAR = exports.STRICT_URL_CHAR + .concat(['\t', '\f']); + // All characters with 0x80 bit set to 1 + for (let i = 0x80; i <= 0xff; i++) { + exports.URL_CHAR.push(i); + } + exports.HEX = exports.NUM.concat(['a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F']); + /* Tokens as defined by rfc 2616. Also lowercases them. + * token = 1* + * separators = "(" | ")" | "<" | ">" | "@" + * | "," | ";" | ":" | "\" | <"> + * | "/" | "[" | "]" | "?" | "=" + * | "{" | "}" | SP | HT + */ + exports.STRICT_TOKEN = [ + '!', '#', '$', '%', '&', '\'', + '*', '+', '-', '.', + '^', '_', '`', + '|', '~', + ].concat(exports.ALPHANUM); + exports.TOKEN = exports.STRICT_TOKEN.concat([' ']); + /* + * Verify that a char is a valid visible (printable) US-ASCII + * character or %x80-FF + */ + exports.HEADER_CHARS = ['\t']; + for (let i = 32; i <= 255; i++) { + if (i !== 127) { + exports.HEADER_CHARS.push(i); + } + } + // ',' = \x44 + exports.CONNECTION_TOKEN_CHARS = exports.HEADER_CHARS.filter((c) => c !== 44); + exports.MAJOR = exports.NUM_MAP; + exports.MINOR = exports.MAJOR; + var HEADER_STATE; + (function (HEADER_STATE) { + HEADER_STATE[HEADER_STATE["GENERAL"] = 0] = "GENERAL"; + HEADER_STATE[HEADER_STATE["CONNECTION"] = 1] = "CONNECTION"; + HEADER_STATE[HEADER_STATE["CONTENT_LENGTH"] = 2] = "CONTENT_LENGTH"; + HEADER_STATE[HEADER_STATE["TRANSFER_ENCODING"] = 3] = "TRANSFER_ENCODING"; + HEADER_STATE[HEADER_STATE["UPGRADE"] = 4] = "UPGRADE"; + HEADER_STATE[HEADER_STATE["CONNECTION_KEEP_ALIVE"] = 5] = "CONNECTION_KEEP_ALIVE"; + HEADER_STATE[HEADER_STATE["CONNECTION_CLOSE"] = 6] = "CONNECTION_CLOSE"; + HEADER_STATE[HEADER_STATE["CONNECTION_UPGRADE"] = 7] = "CONNECTION_UPGRADE"; + HEADER_STATE[HEADER_STATE["TRANSFER_ENCODING_CHUNKED"] = 8] = "TRANSFER_ENCODING_CHUNKED"; + })(HEADER_STATE = exports.HEADER_STATE || (exports.HEADER_STATE = {})); + exports.SPECIAL_HEADERS = { + 'connection': HEADER_STATE.CONNECTION, + 'content-length': HEADER_STATE.CONTENT_LENGTH, + 'proxy-connection': HEADER_STATE.CONNECTION, + 'transfer-encoding': HEADER_STATE.TRANSFER_ENCODING, + 'upgrade': HEADER_STATE.UPGRADE, + }; + + } (constants$3)); + return constants$3; +} + +var llhttpWasm; +var hasRequiredLlhttpWasm; + +function requireLlhttpWasm () { + if (hasRequiredLlhttpWasm) return llhttpWasm; + hasRequiredLlhttpWasm = 1; + + const { Buffer } = require$$0$3; + + llhttpWasm = Buffer.from('AGFzbQEAAAABJwdgAX8Bf2ADf39/AX9gAX8AYAJ/fwBgBH9/f38Bf2AAAGADf39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQAEA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAAy0sBQYAAAIAAAAAAAACAQIAAgICAAADAAAAAAMDAwMBAQEBAQEBAQEAAAIAAAAEBQFwARISBQMBAAIGCAF/AUGA1AQLB9EFIgZtZW1vcnkCAAtfaW5pdGlhbGl6ZQAIGV9faW5kaXJlY3RfZnVuY3Rpb25fdGFibGUBAAtsbGh0dHBfaW5pdAAJGGxsaHR0cF9zaG91bGRfa2VlcF9hbGl2ZQAvDGxsaHR0cF9hbGxvYwALBm1hbGxvYwAxC2xsaHR0cF9mcmVlAAwEZnJlZQAMD2xsaHR0cF9nZXRfdHlwZQANFWxsaHR0cF9nZXRfaHR0cF9tYWpvcgAOFWxsaHR0cF9nZXRfaHR0cF9taW5vcgAPEWxsaHR0cF9nZXRfbWV0aG9kABAWbGxodHRwX2dldF9zdGF0dXNfY29kZQAREmxsaHR0cF9nZXRfdXBncmFkZQASDGxsaHR0cF9yZXNldAATDmxsaHR0cF9leGVjdXRlABQUbGxodHRwX3NldHRpbmdzX2luaXQAFQ1sbGh0dHBfZmluaXNoABYMbGxodHRwX3BhdXNlABcNbGxodHRwX3Jlc3VtZQAYG2xsaHR0cF9yZXN1bWVfYWZ0ZXJfdXBncmFkZQAZEGxsaHR0cF9nZXRfZXJybm8AGhdsbGh0dHBfZ2V0X2Vycm9yX3JlYXNvbgAbF2xsaHR0cF9zZXRfZXJyb3JfcmVhc29uABwUbGxodHRwX2dldF9lcnJvcl9wb3MAHRFsbGh0dHBfZXJybm9fbmFtZQAeEmxsaHR0cF9tZXRob2RfbmFtZQAfEmxsaHR0cF9zdGF0dXNfbmFtZQAgGmxsaHR0cF9zZXRfbGVuaWVudF9oZWFkZXJzACEhbGxodHRwX3NldF9sZW5pZW50X2NodW5rZWRfbGVuZ3RoACIdbGxodHRwX3NldF9sZW5pZW50X2tlZXBfYWxpdmUAIyRsbGh0dHBfc2V0X2xlbmllbnRfdHJhbnNmZXJfZW5jb2RpbmcAJBhsbGh0dHBfbWVzc2FnZV9uZWVkc19lb2YALgkXAQBBAQsRAQIDBAUKBgcrLSwqKSglJyYK07MCLBYAQYjQACgCAARAAAtBiNAAQQE2AgALFAAgABAwIAAgAjYCOCAAIAE6ACgLFAAgACAALwEyIAAtAC4gABAvEAALHgEBf0HAABAyIgEQMCABQYAINgI4IAEgADoAKCABC48MAQd/AkAgAEUNACAAQQhrIgEgAEEEaygCACIAQXhxIgRqIQUCQCAAQQFxDQAgAEEDcUUNASABIAEoAgAiAGsiAUGc0AAoAgBJDQEgACAEaiEEAkACQEGg0AAoAgAgAUcEQCAAQf8BTQRAIABBA3YhAyABKAIIIgAgASgCDCICRgRAQYzQAEGM0AAoAgBBfiADd3E2AgAMBQsgAiAANgIIIAAgAjYCDAwECyABKAIYIQYgASABKAIMIgBHBEAgACABKAIIIgI2AgggAiAANgIMDAMLIAFBFGoiAygCACICRQRAIAEoAhAiAkUNAiABQRBqIQMLA0AgAyEHIAIiAEEUaiIDKAIAIgINACAAQRBqIQMgACgCECICDQALIAdBADYCAAwCCyAFKAIEIgBBA3FBA0cNAiAFIABBfnE2AgRBlNAAIAQ2AgAgBSAENgIAIAEgBEEBcjYCBAwDC0EAIQALIAZFDQACQCABKAIcIgJBAnRBvNIAaiIDKAIAIAFGBEAgAyAANgIAIAANAUGQ0ABBkNAAKAIAQX4gAndxNgIADAILIAZBEEEUIAYoAhAgAUYbaiAANgIAIABFDQELIAAgBjYCGCABKAIQIgIEQCAAIAI2AhAgAiAANgIYCyABQRRqKAIAIgJFDQAgAEEUaiACNgIAIAIgADYCGAsgASAFTw0AIAUoAgQiAEEBcUUNAAJAAkACQAJAIABBAnFFBEBBpNAAKAIAIAVGBEBBpNAAIAE2AgBBmNAAQZjQACgCACAEaiIANgIAIAEgAEEBcjYCBCABQaDQACgCAEcNBkGU0ABBADYCAEGg0ABBADYCAAwGC0Gg0AAoAgAgBUYEQEGg0AAgATYCAEGU0ABBlNAAKAIAIARqIgA2AgAgASAAQQFyNgIEIAAgAWogADYCAAwGCyAAQXhxIARqIQQgAEH/AU0EQCAAQQN2IQMgBSgCCCIAIAUoAgwiAkYEQEGM0ABBjNAAKAIAQX4gA3dxNgIADAULIAIgADYCCCAAIAI2AgwMBAsgBSgCGCEGIAUgBSgCDCIARwRAQZzQACgCABogACAFKAIIIgI2AgggAiAANgIMDAMLIAVBFGoiAygCACICRQRAIAUoAhAiAkUNAiAFQRBqIQMLA0AgAyEHIAIiAEEUaiIDKAIAIgINACAAQRBqIQMgACgCECICDQALIAdBADYCAAwCCyAFIABBfnE2AgQgASAEaiAENgIAIAEgBEEBcjYCBAwDC0EAIQALIAZFDQACQCAFKAIcIgJBAnRBvNIAaiIDKAIAIAVGBEAgAyAANgIAIAANAUGQ0ABBkNAAKAIAQX4gAndxNgIADAILIAZBEEEUIAYoAhAgBUYbaiAANgIAIABFDQELIAAgBjYCGCAFKAIQIgIEQCAAIAI2AhAgAiAANgIYCyAFQRRqKAIAIgJFDQAgAEEUaiACNgIAIAIgADYCGAsgASAEaiAENgIAIAEgBEEBcjYCBCABQaDQACgCAEcNAEGU0AAgBDYCAAwBCyAEQf8BTQRAIARBeHFBtNAAaiEAAn9BjNAAKAIAIgJBASAEQQN2dCIDcUUEQEGM0AAgAiADcjYCACAADAELIAAoAggLIgIgATYCDCAAIAE2AgggASAANgIMIAEgAjYCCAwBC0EfIQIgBEH///8HTQRAIARBJiAEQQh2ZyIAa3ZBAXEgAEEBdGtBPmohAgsgASACNgIcIAFCADcCECACQQJ0QbzSAGohAAJAQZDQACgCACIDQQEgAnQiB3FFBEAgACABNgIAQZDQACADIAdyNgIAIAEgADYCGCABIAE2AgggASABNgIMDAELIARBGSACQQF2a0EAIAJBH0cbdCECIAAoAgAhAAJAA0AgACIDKAIEQXhxIARGDQEgAkEddiEAIAJBAXQhAiADIABBBHFqQRBqIgcoAgAiAA0ACyAHIAE2AgAgASADNgIYIAEgATYCDCABIAE2AggMAQsgAygCCCIAIAE2AgwgAyABNgIIIAFBADYCGCABIAM2AgwgASAANgIIC0Gs0ABBrNAAKAIAQQFrIgBBfyAAGzYCAAsLBwAgAC0AKAsHACAALQAqCwcAIAAtACsLBwAgAC0AKQsHACAALwEyCwcAIAAtAC4LQAEEfyAAKAIYIQEgAC0ALSECIAAtACghAyAAKAI4IQQgABAwIAAgBDYCOCAAIAM6ACggACACOgAtIAAgATYCGAu74gECB38DfiABIAJqIQQCQCAAIgIoAgwiAA0AIAIoAgQEQCACIAE2AgQLIwBBEGsiCCQAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACfwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIAIoAhwiA0EBaw7dAdoBAdkBAgMEBQYHCAkKCwwNDtgBDxDXARES1gETFBUWFxgZGhvgAd8BHB0e1QEfICEiIyQl1AEmJygpKiss0wHSAS0u0QHQAS8wMTIzNDU2Nzg5Ojs8PT4/QEFCQ0RFRtsBR0hJSs8BzgFLzQFMzAFNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AAYEBggGDAYQBhQGGAYcBiAGJAYoBiwGMAY0BjgGPAZABkQGSAZMBlAGVAZYBlwGYAZkBmgGbAZwBnQGeAZ8BoAGhAaIBowGkAaUBpgGnAagBqQGqAasBrAGtAa4BrwGwAbEBsgGzAbQBtQG2AbcBywHKAbgByQG5AcgBugG7AbwBvQG+Ab8BwAHBAcIBwwHEAcUBxgEA3AELQQAMxgELQQ4MxQELQQ0MxAELQQ8MwwELQRAMwgELQRMMwQELQRQMwAELQRUMvwELQRYMvgELQRgMvQELQRkMvAELQRoMuwELQRsMugELQRwMuQELQR0MuAELQQgMtwELQR4MtgELQSAMtQELQR8MtAELQQcMswELQSEMsgELQSIMsQELQSMMsAELQSQMrwELQRIMrgELQREMrQELQSUMrAELQSYMqwELQScMqgELQSgMqQELQcMBDKgBC0EqDKcBC0ErDKYBC0EsDKUBC0EtDKQBC0EuDKMBC0EvDKIBC0HEAQyhAQtBMAygAQtBNAyfAQtBDAyeAQtBMQydAQtBMgycAQtBMwybAQtBOQyaAQtBNQyZAQtBxQEMmAELQQsMlwELQToMlgELQTYMlQELQQoMlAELQTcMkwELQTgMkgELQTwMkQELQTsMkAELQT0MjwELQQkMjgELQSkMjQELQT4MjAELQT8MiwELQcAADIoBC0HBAAyJAQtBwgAMiAELQcMADIcBC0HEAAyGAQtBxQAMhQELQcYADIQBC0EXDIMBC0HHAAyCAQtByAAMgQELQckADIABC0HKAAx/C0HLAAx+C0HNAAx9C0HMAAx8C0HOAAx7C0HPAAx6C0HQAAx5C0HRAAx4C0HSAAx3C0HTAAx2C0HUAAx1C0HWAAx0C0HVAAxzC0EGDHILQdcADHELQQUMcAtB2AAMbwtBBAxuC0HZAAxtC0HaAAxsC0HbAAxrC0HcAAxqC0EDDGkLQd0ADGgLQd4ADGcLQd8ADGYLQeEADGULQeAADGQLQeIADGMLQeMADGILQQIMYQtB5AAMYAtB5QAMXwtB5gAMXgtB5wAMXQtB6AAMXAtB6QAMWwtB6gAMWgtB6wAMWQtB7AAMWAtB7QAMVwtB7gAMVgtB7wAMVQtB8AAMVAtB8QAMUwtB8gAMUgtB8wAMUQtB9AAMUAtB9QAMTwtB9gAMTgtB9wAMTQtB+AAMTAtB+QAMSwtB+gAMSgtB+wAMSQtB/AAMSAtB/QAMRwtB/gAMRgtB/wAMRQtBgAEMRAtBgQEMQwtBggEMQgtBgwEMQQtBhAEMQAtBhQEMPwtBhgEMPgtBhwEMPQtBiAEMPAtBiQEMOwtBigEMOgtBiwEMOQtBjAEMOAtBjQEMNwtBjgEMNgtBjwEMNQtBkAEMNAtBkQEMMwtBkgEMMgtBkwEMMQtBlAEMMAtBlQEMLwtBlgEMLgtBlwEMLQtBmAEMLAtBmQEMKwtBmgEMKgtBmwEMKQtBnAEMKAtBnQEMJwtBngEMJgtBnwEMJQtBoAEMJAtBoQEMIwtBogEMIgtBowEMIQtBpAEMIAtBpQEMHwtBpgEMHgtBpwEMHQtBqAEMHAtBqQEMGwtBqgEMGgtBqwEMGQtBrAEMGAtBrQEMFwtBrgEMFgtBAQwVC0GvAQwUC0GwAQwTC0GxAQwSC0GzAQwRC0GyAQwQC0G0AQwPC0G1AQwOC0G2AQwNC0G3AQwMC0G4AQwLC0G5AQwKC0G6AQwJC0G7AQwIC0HGAQwHC0G8AQwGC0G9AQwFC0G+AQwEC0G/AQwDC0HAAQwCC0HCAQwBC0HBAQshAwNAAkACQAJAAkACQAJAAkACQAJAIAICfwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJ/AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgAgJ/AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACfwJAAkACfwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAC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iQEhAwykAgtBASABLQAAQd8ARw1nGiABQQFqIQEMXgtBigEhAyABIARGDaICIAIoAgAiACAEIAFraiEFIAEgAGtBAWohBgNAIAEtAAAgAEGMzwBqLQAARw1kIABBAUYN+gEgAEEBaiEAIAQgAUEBaiIBRw0ACyACIAU2AgAMogILQYsBIQMgASAERg2hAiACKAIAIgAgBCABa2ohBSABIABrQQJqIQYCQANAIAEtAAAgAEGOzwBqLQAARw1kIABBAkYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAyiAgsgAkEANgIAIAZBAWohAUECDGULQYwBIQMgASAERg2gAiACKAIAIgAgBCABa2ohBSABIABrQQFqIQYCQANAIAEtAAAgAEHwzwBqLQAARw1jIABBAUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAyhAgsgAkEANgIAIAZBAWohAUEfDGQLQY0BIQMgASAERg2fAiACKAIAIgAgBCABa2ohBSABIABrQQFqIQYCQANAIAEtAAAgAEHyzwBqLQAARw1iIABBAUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAygAgsgAkEANgIAIAZBAWohAUEJDGMLIAEgBEYEQEGOASEDDJ8CCwJAAkAgAS0AAEHJAGsOBwBiYmJiYgFiCyABQQFqIQFB+AAhAwyGAgsgAUEBaiEBQfkAIQMMhQILQY8BIQMgASAERg2dAiACKAIAIgAgBCABa2ohBSABIABrQQVqIQYCQANAIAEtAAAgAEGRzwBqLQAARw1gIABBBUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAyeAgsgAkEANgIAIAZBAWohAUEYDGELQZABIQMgASAERg2cAiACKAIAIgAgBCABa2ohBSABIABrQQJqIQYCQANAIAEtAAAgAEGXzwBqLQAARw1fIABBAkYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAydAgsgAkEANgIAIAZBAWohAUEXDGALQZEBIQMgASAERg2bAiACKAIAIgAgBCABa2ohBSABIABrQQZqIQYCQANAIAEtAAAgAEGazwBqLQAARw1eIABBBkYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAycAgsgAkEANgIAIAZBAWohAUEV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JSIARQ0RIAJB5QA2AhwgAiABNgIUIAIgADYCDEEAIQMMtAELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0gIAJB0wA2AhwgAiABNgIUIAIgADYCDEEAIQMMswELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0iIAJB0gA2AhwgAiABNgIUIAIgADYCDEEAIQMMsgELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0OIAJB5QA2AhwgAiABNgIUIAIgADYCDEEAIQMMsQELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0dIAJB0wA2AhwgAiABNgIUIAIgADYCDEEAIQMMsAELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0fIAJB0gA2AhwgAiABNgIUIAIgADYCDEEAIQMMrwELIABBP0cNASABQQFqCyEBQQUhAwyUAQtBACEDIAJBADYCHCACIAE2AhQgAkH9EjYCECACQQc2AgwMrAELIAJBADYCHCACIAE2AhQgAkHcCDYCECACQQc2AgxBACEDDKsBCyACKAIEIQAgAkEANgIEIAIgACABECUiAEUNByACQeUANgIcIAIgATYCFCACIAA2AgxBACEDDKoBCyACKAIEIQAgAkEANgIEIAIgACABECUiAEUNFiACQdMANgIcIAIgATYCFCACIAA2AgxBACEDDKkBCyACKAIEIQAgAkEANgIEIAIgACABECUiAEUNGCACQdIANgIcIAIgATYCFCACIAA2AgxBACEDDKgBCyACQQA2AhwgAiABNgIUIAJBxgo2AhAgAkEHNgIMQQAhAwynAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDQMgAkHlADYCHCACIAE2AhQgAiAANgIMQQAhAwymAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDRIgAkHTADYCHCACIAE2AhQgAiAANgIMQQAhAwylAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDRQgAkHSADYCHCACIAE2AhQgAiAANgIMQQAhAwykAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDQAgAkHlADYCHCACIAE2AhQgAiAANgIMQQAhAwyjAQtB1QAhAwyJAQsgAEEVRwRAIAJBADYCHCACIAE2AhQgAkG5DTYCECACQRo2AgxB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AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIABB5ABrDvQDY2IAAWFhYWFhYQIDBAVhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhBgcICQoLDA0OD2FhYWFhEGFhYWFhYWFhYWFhEWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYRITFBUWFxgZGhthYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2YTc4OTphYWFhYWFhYTthYWE8YWFhYT0+P2FhYWFhYWFhQGFhQWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYUJDREVGR0hJSktMTU5PUFFSU2FhYWFhYWFhVFVWV1hZWlthXF1hYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFeYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhX2BhC0HhJw8LQaQhDwtByywPC0H+MQ8LQcAkDwtBqyQPC0GNKA8LQeImDwtBgDAPC0G5Lw8LQdckDwtB7x8PC0HhHw8LQfofDwtB8iAPC0GoLw8LQa4yDwtBiDAPC0HsJw8LQYIiDwtBjh0PC0HQLg8LQcojDwtBxTIPC0HfHA8LQdIcDwtBxCAPC0HXIA8LQaIfDwtB7S4PC0GrMA8LQdQlDwtBzC4PC0H6Lg8LQfwrDwtB0jAPC0HxHQ8LQbsgDwtB9ysPC0GQMQ8LQdcxDwtBoi0PC0HUJw8LQeArDwtBnywPC0HrMQ8LQdUfDwtByjEPC0HeJQ8LQdQeDwtB9BwPC0GnMg8LQbEdDwtBoB0PC0G5MQ8LQbwwDwtBkiEPC0GzJg8LQeksDwtBrB4PC0HUKw8LQfcmDwtBgCYPC0GwIQ8LQf4eDwtBjSMPC0GJLQ8LQfciDwtBoDEPC0GuHw8LQcYlDwtB6B4PC0GTIg8LQcIvDwtBwx0PC0GLLA8LQeEdDwtBjS8PC0HqIQ8LQbQtDwtB0i8PC0HfMg8LQdIyDwtB8DAPC0GpIg8LQfkjDwtBmR4PC0G1LA8LQZswDwtBkjIPC0G2Kw8LQcIiDwtB+DIPC0GeJQ8LQdAiDwtBuh4PC0GBHg8LAAtB1iEhAQsgAQsWACAAIAAtAC1B/gFxIAFBAEdyOgAtCxkAIAAgAC0ALUH9AXEgAUEAR0EBdHI6AC0LGQAgACAALQAtQfsBcSABQQBHQQJ0cjoALQsZACAAIAAtAC1B9wFxIAFBAEdBA3RyOgAtCz4BAn8CQCAAKAI4IgNFDQAgAygCBCIDRQ0AIAAgASACIAFrIAMRAQAiBEF/Rw0AIABBxhE2AhBBGCEECyAECz4BAn8CQCAAKAI4IgNFDQAgAygCCCIDRQ0AIAAgASACIAFrIAMRAQAiBEF/Rw0AIABB9go2AhBBGCEECyAECz4BAn8CQCAAKAI4IgNFDQAgAygCDCIDRQ0AIAAgASACIAFrIAMRAQAiBEF/Rw0AIABB7Ro2AhBBGCEECyAECz4BAn8CQCAAKAI4IgNFDQAgAygCECIDRQ0AIAAgASACIAFrIAMRAQAiBEF/Rw0AIABBlRA2AhBBGCEECyAECz4BAn8CQCAAKAI4IgNFDQAgAygCFCIDRQ0AIAAgASACIAFrIAMRAQAiBEF/Rw0AIABBqhs2AhBBGCEECyAECz4BAn8CQCAAKAI4IgNFDQAgAygCGCIDRQ0AIAAgASACIAFrIAMRAQAiBEF/Rw0AIABB7RM2AhBBGCEECyAECz4BAn8CQCAAKAI4IgNFDQAgAygCKCIDRQ0AIAAgASACIAFrIAMRAQAiBEF/Rw0AIABB9gg2AhBBGCEECyAECz4BAn8CQCAAKAI4IgNFDQAgAygCHCIDRQ0AIAAgASACIAFrIAMRAQAiBEF/Rw0AIABBwhk2AhBBGCEECyAECz4BAn8CQCAAKAI4IgNFDQAgAygCICIDRQ0AIAAgASACIAFrIAMRAQAiBEF/Rw0AIABBlBQ2AhBBGCEECyAEC1kBAn8CQCAALQAoQQFGDQAgAC8BMiIBQeQAa0HkAEkNACABQcwBRg0AIAFBsAJGDQAgAC8BMCIAQcAAcQ0AQQEhAiAAQYgEcUGABEYNACAAQShxRSECCyACC4wBAQJ/AkACQAJAIAAtACpFDQAgAC0AK0UNACAALwEwIgFBAnFFDQEMAgsgAC8BMCIBQQFxRQ0BC0EBIQIgAC0AKEEBRg0AIAAvATIiAEHkAGtB5ABJDQAgAEHMAUYNACAAQbACRg0AIAFBwABxDQBBACECIAFBiARxQYAERg0AIAFBKHFBAEchAgsgAgtXACAAQRhqQgA3AwAgAEIANwMAIABBOGpCADcDACAAQTBqQgA3AwAgAEEoakIANwMAIABBIGpCADcDACAAQRBqQgA3AwAgAEEIakIANwMAIABB3QE2AhwLBgAgABAyC5otAQt/IwBBEGsiCiQAQaTQACgCACIJRQRAQeTTACgCACIFRQRAQfDTAEJ/NwIAQejTAEKAgISAgIDAADcCAEHk0wAgCkEIakFwcUHYqtWqBXMiBTYCAEH40wBBADYCAEHI0wBBADYCAAtBzNMAQYDUBDYCAEGc0ABBgNQENgIAQbDQACAFNgIAQazQAEF/NgIAQdDTAEGArAM2AgADQCABQcjQAGogAUG80ABqIgI2AgAgAiABQbTQAGoiAzYCACABQcDQAGogAzYCACABQdDQAGogAUHE0ABqIgM2AgAgAyACNgIAIAFB2NAAaiABQczQAGoiAjYCACACIAM2AgAgAUHU0ABqIAI2AgAgAUEgaiIBQYACRw0AC0GM1ARBwasDNgIAQajQAEH00wAoAgA2AgBBmNAAQcCrAzYCAEGk0ABBiNQENgIAQcz/B0E4NgIAQYjUBCEJCwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIABB7AFNBEBBjNAAKAIAIgZBECAAQRNqQXBxIABBC0kbIgRBA3YiAHYiAUEDcQRAAkAgAUEBcSAAckEBcyICQQN0IgBBtNAAaiIBIABBvNAAaigCACIAKAIIIgNGBEBBjNAAIAZBfiACd3E2AgAMAQsgASADNgIIIAMgATYCDAsgAEEIaiEBIAAgAkEDdCICQQNyNgIEIAAgAmoiACAAKAIEQQFyNgIEDBELQZTQACgCACIIIARPDQEgAQRAAkBBAiAAdCICQQAgAmtyIAEgAHRxaCIAQQN0IgJBtNAAaiIBIAJBvNAAaigCACICKAIIIgNGBEBBjNAAIAZBfiAAd3EiBjYCAAwBCyABIAM2AgggAyABNgIMCyACIARBA3I2AgQgAEEDdCIAIARrIQUgACACaiAFNgIAIAIgBGoiBCAFQQFyNgIEIAgEQCAIQXhxQbTQAGohAEGg0AAoAgAhAwJ/QQEgCEEDdnQiASAGcUUEQEGM0AAgASAGcjYCACAADAELIAAoAggLIgEgAzYCDCAAIAM2AgggAyAANgIMIAMgATYCCAsgAkEIaiEBQaDQACAENgIAQZTQACAFNgIADBELQZDQACgCACILRQ0BIAtoQQJ0QbzSAGooAgAiACgCBEF4cSAEayEFIAAhAgNAAkAgAigCECIBRQRAIAJBFGooAgAiAUUNAQsgASgCBEF4cSAEayIDIAVJIQIgAyAFIAIbIQUgASAAIAIbIQAgASECDAELCyAAKAIYIQkgACgCDCIDIABHBEBBnNAAKAIAGiADIAAoAggiATYCCCABIAM2AgwMEAsgAEEUaiICKAIAIgFFBEAgACgCECIBRQ0DIABBEGohAgsDQCACIQcgASIDQRRqIgIoAgAiAQ0AIANBEGohAiADKAIQIgENAAsgB0EANgIADA8LQX8hBCAAQb9/Sw0AIABBE2oiAUFwcSEEQZDQACgCACIIRQ0AQQAgBGshBQJAAkACQAJ/QQAgBEGAAkkNABpBHyAEQf///wdLDQAaIARBJiABQQh2ZyIAa3ZBAXEgAEEBdGtBPmoLIgZBAnRBvNIAaigCACICRQRAQQAhAUEAIQMMAQtBACEBIARBGSAGQQF2a0EAIAZBH0cbdCEAQQAhAwNAAkAgAigCBEF4cSAEayIHIAVPDQAgAiEDIAciBQ0AQQAhBSACIQEMAwsgASACQRRqKAIAIgcgByACIABBHXZBBHFqQRBqKAIAIgJGGyABIAcbIQEgAEEBdCEAIAINAAsLIAEgA3JFBEBBACEDQQIgBnQiAEEAIABrciAIcSIARQ0DIABoQQJ0QbzSAGooAgAhAQsgAUUNAQsDQCABKAIEQXhxIARrIgIgBUkhACACIAUgABshBSABIAMgABshAyABKAIQIgAEfyAABSABQRRqKAIACyIBDQALCyADRQ0AIAVBlNAAKAIAIARrTw0AIAMoAhghByADIAMoAgwiAEcEQEGc0AAoAgAaIAAgAygCCCIBNgIIIAEgADYCDAwOCyADQRRqIgIoAgAiAUUEQCADKAIQIgFFDQMgA0EQaiECCwNAIAIhBiABIgBBFGoiAigCACIBDQAgAEEQaiECIAAoAhAiAQ0ACyAGQQA2AgAMDQtBlNAAKAIAIgMgBE8EQEGg0AAoAgAhAQJAIAMgBGsiAkEQTwRAIAEgBGoiACACQQFyNgIEIAEgA2ogAjYCACABIARBA3I2AgQMAQsgASADQQNyNgIEIAEgA2oiACAAKAIEQQFyNgIEQQAhAEEAIQILQZTQACACNgIAQaDQACAANgIAIAFBCGohAQwPC0GY0AAoAgAiAyAESwRAIAQgCWoiACADIARrIgFBAXI2AgRBpNAAIAA2AgBBmNAAIAE2AgAgCSAEQQNyNgIEIAlBCGohAQwPC0EAIQEgBAJ/QeTTACgCAARAQezTACgCAAwBC0Hw0wBCfzcCAEHo0wBCgICEgICAwAA3AgBB5NMAIApBDGpBcHFB2KrVqgVzNgIAQfjTAEEANgIAQcjTAEEANgIAQYCABAsiACAEQccAaiIFaiIGQQAgAGsiB3EiAk8EQEH80wBBMDYCAAwPCwJAQcTTACgCACIBRQ0AQbzTACgCACIIIAJqIQAgACABTSAAIAhLcQ0AQQAhAUH80wBBMDYCAAwPC0HI0wAtAABBBHENBAJAAkAgCQRAQczTACEBA0AgASgCACIAIAlNBEAgACABKAIEaiAJSw0DCyABKAIIIgENAAsLQQAQMyIAQX9GDQUgAiEGQejTACgCACIBQQFrIgMgAHEEQCACIABrIAAgA2pBACABa3FqIQYLIAQgBk8NBSAGQf7///8HSw0FQcTTACgCACIDBEBBvNMAKAIAIgcgBmohASABIAdNDQYgASADSw0GCyAGEDMiASAARw0BDAcLIAYgA2sgB3EiBkH+////B0sNBCAGEDMhACAAIAEoAgAgASgCBGpGDQMgACEBCwJAIAYgBEHIAGpPDQAgAUF/Rg0AQezTACgCACIAIAUgBmtqQQAgAGtxIgBB/v///wdLBEAgASEADAcLIAAQM0F/RwRAIAAgBmohBiABIQAMBwtBACAGaxAzGgwECyABIgBBf0cNBQwDC0EAIQMMDAtBACEADAoLIABBf0cNAgtByNMAQcjTACgCAEEEcjYCAAsgAkH+////B0sNASACEDMhAEEAEDMhASAAQX9GDQEgAUF/Rg0BIAAgAU8NASABIABrIgYgBEE4ak0NAQtBvNMAQbzTACgCACAGaiIBNgIAQcDTACgCACABSQRAQcDTACABNgIACwJAAkACQEGk0AAoAgAiAgRAQczTACEBA0AgACABKAIAIgMgASgCBCIFakYNAiABKAIIIgENAAsMAgtBnNAAKAIAIgFBAEcgACABT3FFBEBBnNAAIAA2AgALQQAhAUHQ0wAgBjYCAEHM0wAgADYCAEGs0ABBfzYCAEGw0ABB5NMAKAIANgIAQdjTAEEANgIAA0AgAUHI0ABqIAFBvNAAaiICNgIAIAIgAUG00ABqIgM2AgAgAUHA0ABqIAM2AgAgAUHQ0ABqIAFBxNAAaiIDNgIAIAMgAjYCACABQdjQAGogAUHM0ABqIgI2AgAgAiADNgIAIAFB1NAAaiACNgIAIAFBIGoiAUGAAkcNAAtBeCAAa0EPcSIBIABqIgIgBkE4ayIDIAFrIgFBAXI2AgRBqNAAQfTTACgCADYCAEGY0AAgATYCAEGk0AAgAjYCACAAIANqQTg2AgQMAgsgACACTQ0AIAIgA0kNACABKAIMQQhxDQBBeCACa0EPcSIAIAJqIgNBmNAAKAIAIAZqIgcgAGsiAEEBcjYCBCABIAUgBmo2AgRBqNAAQfTTACgCADYCAEGY0AAgADYCAEGk0AAgAzYCACACIAdqQTg2AgQMAQsgAEGc0AAoAgBJBEBBnNAAIAA2AgALIAAgBmohA0HM0wAhAQJAAkACQANAIAMgASgCAEcEQCABKAIIIgENAQwCCwsgAS0ADEEIcUUNAQtBzNMAIQEDQCABKAIAIgMgAk0EQCADIAEoAgRqIgUgAksNAwsgASgCCCEBDAALAAsgASAANgIAIAEgASgCBCAGajYCBCAAQXggAGtBD3FqIgkgBEEDcjYCBCADQXggA2tBD3FqIgYgBCAJaiIEayEBIAIgBkYEQEGk0AAgBDYCAEGY0ABBmNAAKAIAIAFqIgA2AgAgBCAAQQFyNgIEDAgLQaDQACgCACAGRgRAQaDQACAENgIAQZTQAEGU0AAoAgAgAWoiADYCACAEIABBAXI2AgQgACAEaiAANgIADAgLIAYoAgQiBUEDcUEBRw0GIAVBeHEhCCAFQf8BTQRAIAVBA3YhAyAGKAIIIgAgBigCDCICRgRAQYzQAEGM0AAoAgBBfiADd3E2AgAMBwsgAiAANgIIIAAgAjYCDAwGCyAGKAIYIQcgBiAGKAIMIgBHBEAgACAGKAIIIgI2AgggAiAANgIMDAULIAZBFGoiAigCACIFRQRAIAYoAhAiBUUNBCAGQRBqIQILA0AgAiEDIAUiAEEUaiICKAIAIgUNACAAQRBqIQIgACgCECIFDQALIANBADYCAAwEC0F4IABrQQ9xIgEgAGoiByAGQThrIgMgAWsiAUEBcjYCBCAAIANqQTg2AgQgAiAFQTcgBWtBD3FqQT9rIgMgAyACQRBqSRsiA0EjNgIEQajQAEH00wAoAgA2AgBBmNAAIAE2AgBBpNAAIAc2AgAgA0EQakHU0wApAgA3AgAgA0HM0wApAgA3AghB1NMAIANBCGo2AgBB0NMAIAY2AgBBzNMAIAA2AgBB2NMAQQA2AgAgA0EkaiEBA0AgAUEHNgIAIAUgAUEEaiIBSw0ACyACIANGDQAgAyADKAIEQX5xNgIEIAMgAyACayIFNgIAIAIgBUEBcjYCBCAFQf8BTQRAIAVBeHFBtNAAaiEAAn9BjNAAKAIAIgFBASAFQQN2dCIDcUUEQEGM0AAgASADcjYCACAADAELIAAoAggLIgEgAjYCDCAAIAI2AgggAiAANgIMIAIgATYCCAwBC0EfIQEgBUH///8HTQRAIAVBJiAFQQh2ZyIAa3ZBAXEgAEEBdGtBPmohAQsgAiABNgIcIAJCADcCECABQQJ0QbzSAGohAEGQ0AAoAgAiA0EBIAF0IgZxRQRAIAAgAjYCAEGQ0AAgAyAGcjYCACACIAA2AhggAiACNgIIIAIgAjYCDAwBCyAFQRkgAUEBdmtBACABQR9HG3QhASAAKAIAIQMCQANAIAMiACgCBEF4cSAFRg0BIAFBHXYhAyABQQF0IQEgACADQQRxakEQaiIGKAIAIgMNAAsgBiACNgIAIAIgADYCGCACIAI2AgwgAiACNgIIDAELIAAoAggiASACNgIMIAAgAjYCCCACQQA2AhggAiAANgIMIAIgATYCCAtBmNAAKAIAIgEgBE0NAEGk0AAoAgAiACAEaiICIAEgBGsiAUEBcjYCBEGY0AAgATYCAEGk0AAgAjYCACAAIARBA3I2AgQgAEEIaiEBDAgLQQAhAUH80wBBMDYCAAwHC0EAIQALIAdFDQACQCAGKAIcIgJBAnRBvNIAaiIDKAIAIAZGBEAgAyAANgIAIAANAUGQ0ABBkNAAKAIAQX4gAndxNgIADAILIAdBEEEUIAcoAhAgBkYbaiAANgIAIABFDQELIAAgBzYCGCAGKAIQIgIEQCAAIAI2AhAgAiAANgIYCyAGQRRqKAIAIgJFDQAgAEEUaiACNgIAIAIgADYCGAsgASAIaiEBIAYgCGoiBigCBCEFCyAGIAVBfnE2AgQgASAEaiABNgIAIAQgAUEBcjYCBCABQf8BTQRAIAFBeHFBtNAAaiEAAn9BjNAAKAIAIgJBASABQQN2dCIBcUUEQEGM0AAgASACcjYCACAADAELIAAoAggLIgEgBDYCDCAAIAQ2AgggBCAANgIMIAQgATYCCAwBC0EfIQUgAUH///8HTQRAIAFBJiABQQh2ZyIAa3ZBAXEgAEEBdGtBPmohBQsgBCAFNgIcIARCADcCECAFQQJ0QbzSAGohAEGQ0AAoAgAiAkEBIAV0IgNxRQRAIAAgBDYCAEGQ0AAgAiADcjYCACAEIAA2AhggBCAENgIIIAQgBDYCDAwBCyABQRkgBUEBdmtBACAFQR9HG3QhBSAAKAIAIQACQANAIAAiAigCBEF4cSABRg0BIAVBHXYhACAFQQF0IQUgAiAAQQRxakEQaiIDKAIAIgANAAsgAyAENgIAIAQgAjYCGCAEIAQ2AgwgBCAENgIIDAELIAIoAggiACAENgIMIAIgBDYCCCAEQQA2AhggBCACNgIMIAQgADYCCAsgCUEIaiEBDAILAkAgB0UNAAJAIAMoAhwiAUECdEG80gBqIgIoAgAgA0YEQCACIAA2AgAgAA0BQZDQACAIQX4gAXdxIgg2AgAMAgsgB0EQQRQgBygCECADRhtqIAA2AgAgAEUNAQsgACAHNgIYIAMoAhAiAQRAIAAgATYCECABIAA2AhgLIANBFGooAgAiAUUNACAAQRRqIAE2AgAgASAANgIYCwJAIAVBD00EQCADIAQgBWoiAEEDcjYCBCAAIANqIgAgACgCBEEBcjYCBAwBCyADIARqIgIgBUEBcjYCBCADIARBA3I2AgQgAiAFaiAFNgIAIAVB/wFNBEAgBUF4cUG00ABqIQACf0GM0AAoAgAiAUEBIAVBA3Z0IgVxRQRAQYzQACABIAVyNgIAIAAMAQsgACgCCAsiASACNgIMIAAgAjYCCCACIAA2AgwgAiABNgIIDAELQR8hASAFQf///wdNBEAgBUEmIAVBCHZnIgBrdkEBcSAAQQF0a0E+aiEBCyACIAE2AhwgAkIANwIQIAFBAnRBvNIAaiEAQQEgAXQiBCAIcUUEQCAAIAI2AgBBkNAAIAQgCHI2AgAgAiAANgIYIAIgAjYCCCACIAI2AgwMAQsgBUEZIAFBAXZrQQAgAUEfRxt0IQEgACgCACEEAkADQCAEIgAoAgRBeHEgBUYNASABQR12IQQgAUEBdCEBIAAgBEEEcWpBEGoiBigCACIEDQALIAYgAjYCACACIAA2AhggAiACNgIMIAIgAjYCCAwBCyAAKAIIIgEgAjYCDCAAIAI2AgggAkEANgIYIAIgADYCDCACIAE2AggLIANBCGohAQwBCwJAIAlFDQACQCAAKAIcIgFBAnRBvNIAaiICKAIAIABGBEAgAiADNgIAIAMNAUGQ0AAgC0F+IAF3cTYCAAwCCyAJQRBBFCAJKAIQIABGG2ogAzYCACADRQ0BCyADIAk2AhggACgCECIBBEAgAyABNgIQIAEgAzYCGAsgAEEUaigCACIBRQ0AIANBFGogATYCACABIAM2AhgLAkAgBUEPTQRAIAAgBCAFaiIBQQNyNgIEIAAgAWoiASABKAIEQQFyNgIEDAELIAAgBGoiByAFQQFyNgIEIAAgBEEDcjYCBCAFIAdqIAU2AgAgCARAIAhBeHFBtNAAaiEBQaDQACgCACEDAn9BASAIQQN2dCICIAZxRQRAQYzQACACIAZyNgIAIAEMAQsgASgCCAsiAiADNgIMIAEgAzYCCCADIAE2AgwgAyACNgIIC0Gg0AAgBzYCAEGU0AAgBTYCAAsgAEEIaiEBCyAKQRBqJAAgAQtDACAARQRAPwBBEHQPCwJAIABB//8DcQ0AIABBAEgNACAAQRB2QAAiAEF/RgRAQfzTAEEwNgIAQX8PCyAAQRB0DwsACwvcPyIAQYAICwkBAAAAAgAAAAMAQZQICwUEAAAABQBBpAgLCQYAAAAHAAAACABB3AgLii1JbnZhbGlkIGNoYXIgaW4gdXJsIHF1ZXJ5AFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fYm9keQBDb250ZW50LUxlbmd0aCBvdmVyZmxvdwBDaHVuayBzaXplIG92ZXJmbG93AFJlc3BvbnNlIG92ZXJmbG93AEludmFsaWQgbWV0aG9kIGZvciBIVFRQL3gueCByZXF1ZXN0AEludmFsaWQgbWV0aG9kIGZvciBSVFNQL3gueCByZXF1ZXN0AEV4cGVjdGVkIFNPVVJDRSBtZXRob2QgZm9yIElDRS94LnggcmVxdWVzdABJbnZhbGlkIGNoYXIgaW4gdXJsIGZyYWdtZW50IHN0YXJ0AEV4cGVjdGVkIGRvdABTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3N0YXR1cwBJbnZhbGlkIHJlc3BvbnNlIHN0YXR1cwBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zAFVzZXIgY2FsbGJhY2sgZXJyb3IAYG9uX3Jlc2V0YCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfaGVhZGVyYCBjYWxsYmFjayBlcnJvcgBgb25fbWVzc2FnZV9iZWdpbmAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2V4dGVuc2lvbl92YWx1ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX3N0YXR1c19jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX3ZlcnNpb25fY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl91cmxfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9jaHVua19jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2hlYWRlcl92YWx1ZV9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX21lc3NhZ2VfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9tZXRob2RfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9oZWFkZXJfZmllbGRfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9jaHVua19leHRlbnNpb25fbmFtZWAgY2FsbGJhY2sgZXJyb3IAVW5leHBlY3RlZCBjaGFyIGluIHVybCBzZXJ2ZXIASW52YWxpZCBoZWFkZXIgdmFsdWUgY2hhcgBJbnZhbGlkIGhlYWRlciBmaWVsZCBjaGFyAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fdmVyc2lvbgBJbnZhbGlkIG1pbm9yIHZlcnNpb24ASW52YWxpZCBtYWpvciB2ZXJzaW9uAEV4cGVjdGVkIHNwYWNlIGFmdGVyIHZlcnNpb24ARXhwZWN0ZWQgQ1JMRiBhZnRlciB2ZXJzaW9uAEludmFsaWQgSFRUUCB2ZXJzaW9uAEludmFsaWQgaGVhZGVyIHRva2VuAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fdXJsAEludmFsaWQgY2hhcmFjdGVycyBpbiB1cmwAVW5leHBlY3RlZCBzdGFydCBjaGFyIGluIHVybABEb3VibGUgQCBpbiB1cmwARW1wdHkgQ29udGVudC1MZW5ndGgASW52YWxpZCBjaGFyYWN0ZXIgaW4gQ29udGVudC1MZW5ndGgARHVwbGljYXRlIENvbnRlbnQtTGVuZ3RoAEludmFsaWQgY2hhciBpbiB1cmwgcGF0aABDb250ZW50LUxlbmd0aCBjYW4ndCBiZSBwcmVzZW50IHdpdGggVHJhbnNmZXItRW5jb2RpbmcASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgc2l6ZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2hlYWRlcl92YWx1ZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2NodW5rX2V4dGVuc2lvbl92YWx1ZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIHZhbHVlAE1pc3NpbmcgZXhwZWN0ZWQgTEYgYWZ0ZXIgaGVhZGVyIHZhbHVlAEludmFsaWQgYFRyYW5zZmVyLUVuY29kaW5nYCBoZWFkZXIgdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyBxdW90ZSB2YWx1ZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIHF1b3RlZCB2YWx1ZQBQYXVzZWQgYnkgb25faGVhZGVyc19jb21wbGV0ZQBJbnZhbGlkIEVPRiBzdGF0ZQBvbl9yZXNldCBwYXVzZQBvbl9jaHVua19oZWFkZXIgcGF1c2UAb25fbWVzc2FnZV9iZWdpbiBwYXVzZQBvbl9jaHVua19leHRlbnNpb25fdmFsdWUgcGF1c2UAb25fc3RhdHVzX2NvbXBsZXRlIHBhdXNlAG9uX3ZlcnNpb25fY29tcGxldGUgcGF1c2UAb25fdXJsX2NvbXBsZXRlIHBhdXNlAG9uX2NodW5rX2NvbXBsZXRlIHBhdXNlAG9uX2hlYWRlcl92YWx1ZV9jb21wbGV0ZSBwYXVzZQBvbl9tZXNzYWdlX2NvbXBsZXRlIHBhdXNlAG9uX21ldGhvZF9jb21wbGV0ZSBwYXVzZQBvbl9oZWFkZXJfZmllbGRfY29tcGxldGUgcGF1c2UAb25fY2h1bmtfZXh0ZW5zaW9uX25hbWUgcGF1c2UAVW5leHBlY3RlZCBzcGFjZSBhZnRlciBzdGFydCBsaW5lAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fY2h1bmtfZXh0ZW5zaW9uX25hbWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyBuYW1lAFBhdXNlIG9uIENPTk5FQ1QvVXBncmFkZQBQYXVzZSBvbiBQUkkvVXBncmFkZQBFeHBlY3RlZCBIVFRQLzIgQ29ubmVjdGlvbiBQcmVmYWNlAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fbWV0aG9kAEV4cGVjdGVkIHNwYWNlIGFmdGVyIG1ldGhvZABTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2hlYWRlcl9maWVsZABQYXVzZWQASW52YWxpZCB3b3JkIGVuY291bnRlcmVkAEludmFsaWQgbWV0aG9kIGVuY291bnRlcmVkAFVuZXhwZWN0ZWQgY2hhciBpbiB1cmwgc2NoZW1hAFJlcXVlc3QgaGFzIGludmFsaWQgYFRyYW5zZmVyLUVuY29kaW5nYABTV0lUQ0hfUFJPWFkAVVNFX1BST1hZAE1LQUNUSVZJVFkAVU5QUk9DRVNTQUJMRV9FTlRJVFkAQ09QWQBNT1ZFRF9QRVJNQU5FTlRMWQBUT09fRUFSTFkATk9USUZZAEZBSUxFRF9ERVBFTkRFTkNZAEJBRF9HQVRFV0FZAFBMQVkAUFVUAENIRUNLT1VUAEdBVEVXQVlfVElNRU9VVABSRVFVRVNUX1RJTUVPVVQATkVUV09SS19DT05ORUNUX1RJTUVPVVQAQ09OTkVDVElPTl9USU1FT1VUAExPR0lOX1RJTUVPVVQATkVUV09SS19SRUFEX1RJTUVPVVQAUE9TVABNSVNESVJFQ1RFRF9SRVFVRVNUAENMSUVOVF9DTE9TRURfUkVRVUVTVABDTElFTlRfQ0xPU0VEX0xPQURfQkFMQU5DRURfUkVRVUVTVABCQURfUkVRVUVTVABIVFRQX1JFUVVFU1RfU0VOVF9UT19IVFRQU19QT1JUAFJFUE9SVABJTV9BX1RFQVBPVABSRVNFVF9DT05URU5UAE5PX0NPTlRFTlQAUEFSVElBTF9DT05URU5UAEhQRV9JTlZBTElEX0NPTlNUQU5UAEhQRV9DQl9SRVNFVABHRVQASFBFX1NUUklDVABDT05GTElDVABURU1QT1JBUllfUkVESVJFQ1QAUEVSTUFORU5UX1JFRElSRUNUAENPTk5FQ1QATVVMVElfU1RBVFVTAEhQRV9JTlZBTElEX1NUQVRVUwBUT09fTUFOWV9SRVFVRVNUUwBFQVJMWV9ISU5UUwBVTkFWQUlMQUJMRV9GT1JfTEVHQUxfUkVBU09OUwBPUFRJT05TAFNXSVRDSElOR19QUk9UT0NPTFMAVkFSSUFOVF9BTFNPX05FR09USUFURVMATVVMVElQTEVfQ0hPSUNFUwBJTlRFUk5BTF9TRVJWRVJfRVJST1IAV0VCX1NFUlZFUl9VTktOT1dOX0VSUk9SAFJBSUxHVU5fRVJST1IASURFTlRJVFlfUFJPVklERVJfQVVUSEVOVElDQVRJT05fRVJST1IAU1NMX0NFUlRJRklDQVRFX0VSUk9SAElOVkFMSURfWF9GT1JXQVJERURfRk9SAFNFVF9QQVJBTUVURVIAR0VUX1BBUkFNRVRFUgBIUEVfVVNFUgBTRUVfT1RIRVIASFBFX0NCX0NIVU5LX0hFQURFUgBNS0NBTEVOREFSAFNFVFVQAFdFQl9TRVJWRVJfSVNfRE9XTgBURUFSRE9XTgBIUEVfQ0xPU0VEX0NPTk5FQ1RJT04ASEVVUklTVElDX0VYUElSQVRJT04ARElTQ09OTkVDVEVEX09QRVJBVElPTgBOT05fQVVUSE9SSVRBVElWRV9JTkZPUk1BVElPTgBIUEVfSU5WQUxJRF9WRVJTSU9OAEhQRV9DQl9NRVNTQUdFX0JFR0lOAFNJVEVfSVNfRlJPWkVOAEhQRV9JTlZBTElEX0hFQURFUl9UT0tFTgBJTlZBTElEX1RPS0VOAEZPUkJJRERFTgBFTkhBTkNFX1lPVVJfQ0FMTQBIUEVfSU5WQUxJRF9VUkwAQkxPQ0tFRF9CWV9QQVJFTlRBTF9DT05UUk9MAE1LQ09MAEFDTABIUEVfSU5URVJOQUwAUkVRVUVTVF9IRUFERVJfRklFTERTX1RPT19MQVJHRV9VTk9GRklDSUFMAEhQRV9PSwBVTkxJTksAVU5MT0NLAFBSSQBSRVRSWV9XSVRIAEhQRV9JTlZBTElEX0NPTlRFTlRfTEVOR1RIAEhQRV9VTkVYUEVDVEVEX0NPTlRFTlRfTEVOR1RIAEZMVVNIAFBST1BQQVRDSABNLVNFQVJDSABVUklfVE9PX0xPTkcAUFJPQ0VTU0lORwBNSVNDRUxMQU5FT1VTX1BFUlNJU1RFTlRfV0FSTklORwBNSVNDRUxMQU5FT1VTX1dBUk5JTkcASFBFX0lOVkFMSURfVFJBTlNGRVJfRU5DT0RJTkcARXhwZWN0ZWQgQ1JMRgBIUEVfSU5WQUxJRF9DSFVOS19TSVpFAE1PVkUAQ09OVElOVUUASFBFX0NCX1NUQVRVU19DT01QTEVURQBIUEVfQ0JfSEVBREVSU19DT01QTEVURQBIUEVfQ0JfVkVSU0lPTl9DT01QTEVURQBIUEVfQ0JfVVJMX0NPTVBMRVRFAEhQRV9DQl9DSFVOS19DT01QTEVURQBIUEVfQ0JfSEVBREVSX1ZBTFVFX0NPTVBMRVRFAEhQRV9DQl9DSFVOS19FWFRFTlNJT05fVkFMVUVfQ09NUExFVEUASFBFX0NCX0NIVU5LX0VYVEVOU0lPTl9OQU1FX0NPTVBMRVRFAEhQRV9DQl9NRVNTQUdFX0NPTVBMRVRFAEhQRV9DQl9NRVRIT0RfQ09NUExFVEUASFBFX0NCX0hFQURFUl9GSUVMRF9DT01QTEVURQBERUxFVEUASFBFX0lOVkFMSURfRU9GX1NUQVRFAElOVkFMSURfU1NMX0NFUlRJRklDQVRFAFBBVVNFAE5PX1JFU1BPTlNFAFVOU1VQUE9SVEVEX01FRElBX1RZUEUAR09ORQBOT1RfQUNDRVBUQUJMRQBTRVJWSUNFX1VOQVZBSUxBQkxFAFJBTkdFX05PVF9TQVRJU0ZJQUJMRQBPUklHSU5fSVNfVU5SRUFDSEFCTEUAUkVTUE9OU0VfSVNfU1RBTEUAUFVSR0UATUVSR0UAUkVRVUVTVF9IRUFERVJfRklFTERTX1RPT19MQVJHRQBSRVFVRVNUX0hFQURFUl9UT09fTEFSR0UAUEFZTE9BRF9UT09fTEFSR0UASU5TVUZGSUNJRU5UX1NUT1JBR0UASFBFX1BBVVNFRF9VUEdSQURFAEhQRV9QQVVTRURfSDJfVVBHUkFERQBTT1VSQ0UAQU5OT1VOQ0UAVFJBQ0UASFBFX1VORVhQRUNURURfU1BBQ0UAREVTQ1JJQkUAVU5TVUJTQ1JJQkUAUkVDT1JEAEhQRV9JTlZBTElEX01FVEhPRABOT1RfRk9VTkQAUFJPUEZJTkQAVU5CSU5EAFJFQklORABVTkFVVEhPUklaRUQATUVUSE9EX05PVF9BTExPV0VEAEhUVFBfVkVSU0lPTl9OT1RfU1VQUE9SVEVEAEFMUkVBRFlfUkVQT1JURUQAQUNDRVBURUQATk9UX0lNUExFTUVOVEVEAExPT1BfREVURUNURUQASFBFX0NSX0VYUEVDVEVEAEhQRV9MRl9FWFBFQ1RFRABDUkVBVEVEAElNX1VTRUQASFBFX1BBVVNFRABUSU1FT1VUX09DQ1VSRUQAUEFZTUVOVF9SRVFVSVJFRABQUkVDT05ESVRJT05fUkVRVUlSRUQAUFJPWFlfQVVUSEVOVElDQVRJT05fUkVRVUlSRUQATkVUV09SS19BVVRIRU5USUNBVElPTl9SRVFVSVJFRABMRU5HVEhfUkVRVUlSRUQAU1NMX0NFUlRJRklDQVRFX1JFUVVJUkVEAFVQR1JBREVfUkVRVUlSRUQAUEFHRV9FWFBJUkVEAFBSRUNPTkRJVElPTl9GQUlMRUQARVhQRUNUQVRJT05fRkFJTEVEAFJFVkFMSURBVElPTl9GQUlMRUQAU1NMX0hBTkRTSEFLRV9GQUlMRUQATE9DS0VEAFRSQU5TRk9STUFUSU9OX0FQUExJRUQATk9UX01PRElGSUVEAE5PVF9FWFRFTkRFRABCQU5EV0lEVEhfTElNSVRfRVhDRUVERUQAU0lURV9JU19PVkVSTE9BREVEAEhFQUQARXhwZWN0ZWQgSFRUUC8AAF4TAAAmEwAAMBAAAPAXAACdEwAAFRIAADkXAADwEgAAChAAAHUSAACtEgAAghMAAE8UAAB/EAAAoBUAACMUAACJEgAAixQAAE0VAADUEQAAzxQAABAYAADJFgAA3BYAAMERAADgFwAAuxQAAHQUAAB8FQAA5RQAAAgXAAAfEAAAZRUAAKMUAAAoFQAAAhUAAJkVAAAsEAAAixkAAE8PAADUDgAAahAAAM4QAAACFwAAiQ4AAG4TAAAcEwAAZhQAAFYXAADBEwAAzRMAAGwTAABoFwAAZhcAAF8XAAAiEwAAzg8AAGkOAADYDgAAYxYAAMsTAACqDgAAKBcAACYXAADFEwAAXRYAAOgRAABnEwAAZRMAAPIWAABzEwAAHRcAAPkWAADzEQAAzw4AAM4VAAAMEgAAsxEAAKURAABhEAAAMhcAALsTAEH5NQsBAQBBkDYL4AEBAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQBB/TcLAQEAQZE4C14CAwICAgICAAACAgACAgACAgICAgICAgICAAQAAAAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAgACAEH9OQsBAQBBkToLXgIAAgICAgIAAAICAAICAAICAgICAgICAgIAAwAEAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAgACAAIAQfA7Cw1sb3NlZWVwLWFsaXZlAEGJPAsBAQBBoDwL4AEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQBBiT4LAQEAQaA+C+cBAQEBAQEBAQEBAQEBAgEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQFjaHVua2VkAEGwwAALXwEBAAEBAQEBAAABAQABAQABAQEBAQEBAQEBAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQABAEGQwgALIWVjdGlvbmVudC1sZW5ndGhvbnJveHktY29ubmVjdGlvbgBBwMIACy1yYW5zZmVyLWVuY29kaW5ncGdyYWRlDQoNCg0KU00NCg0KVFRQL0NFL1RTUC8AQfnCAAsFAQIAAQMAQZDDAAvgAQQBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAEH5xAALBQECAAEDAEGQxQAL4AEEAQEFAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQBB+cYACwQBAAABAEGRxwAL3wEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAEH6yAALBAEAAAIAQZDJAAtfAwQAAAQEBAQEBAQEBAQEBQQEBAQEBAQEBAQEBAAEAAYHBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQABAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAQAQfrKAAsEAQAAAQBBkMsACwEBAEGqywALQQIAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAEH6zAALBAEAAAEAQZDNAAsBAQBBms0ACwYCAAAAAAIAQbHNAAs6AwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwBB8M4AC5YBTk9VTkNFRUNLT1VUTkVDVEVURUNSSUJFTFVTSEVURUFEU0VBUkNIUkdFQ1RJVklUWUxFTkRBUlZFT1RJRllQVElPTlNDSFNFQVlTVEFUQ0hHRU9SRElSRUNUT1JUUkNIUEFSQU1FVEVSVVJDRUJTQ1JJQkVBUkRPV05BQ0VJTkROS0NLVUJTQ1JJQkVIVFRQL0FEVFAv', 'base64'); + return llhttpWasm; +} + +var llhttp_simdWasm; +var hasRequiredLlhttp_simdWasm; + +function requireLlhttp_simdWasm () { + if (hasRequiredLlhttp_simdWasm) return llhttp_simdWasm; + hasRequiredLlhttp_simdWasm = 1; + + const { Buffer } = require$$0$3; + + llhttp_simdWasm = Buffer.from('AGFzbQEAAAABJwdgAX8Bf2ADf39/AX9gAX8AYAJ/fwBgBH9/f38Bf2AAAGADf39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQAEA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAAy0sBQYAAAIAAAAAAAACAQIAAgICAAADAAAAAAMDAwMBAQEBAQEBAQEAAAIAAAAEBQFwARISBQMBAAIGCAF/AUGA1AQLB9EFIgZtZW1vcnkCAAtfaW5pdGlhbGl6ZQAIGV9faW5kaXJlY3RfZnVuY3Rpb25fdGFibGUBAAtsbGh0dHBfaW5pdAAJGGxsaHR0cF9zaG91bGRfa2VlcF9hbGl2ZQAvDGxsaHR0cF9hbGxvYwALBm1hbGxvYwAxC2xsaHR0cF9mcmVlAAwEZnJlZQAMD2xsaHR0cF9nZXRfdHlwZQANFWxsaHR0cF9nZXRfaHR0cF9tYWpvcgAOFWxsaHR0cF9nZXRfaHR0cF9taW5vcgAPEWxsaHR0cF9nZXRfbWV0aG9kABAWbGxodHRwX2dldF9zdGF0dXNfY29kZQAREmxsaHR0cF9nZXRfdXBncmFkZQASDGxsaHR0cF9yZXNldAATDmxsaHR0cF9leGVjdXRlABQUbGxodHRwX3NldHRpbmdzX2luaXQAFQ1sbGh0dHBfZmluaXNoABYMbGxodHRwX3BhdXNlABcNbGxodHRwX3Jlc3VtZQAYG2xsaHR0cF9yZXN1bWVfYWZ0ZXJfdXBncmFkZQAZEGxsaHR0cF9nZXRfZXJybm8AGhdsbGh0dHBfZ2V0X2Vycm9yX3JlYXNvbgAbF2xsaHR0cF9zZXRfZXJyb3JfcmVhc29uABwUbGxodHRwX2dldF9lcnJvcl9wb3MAHRFsbGh0dHBfZXJybm9fbmFtZQAeEmxsaHR0cF9tZXRob2RfbmFtZQAfEmxsaHR0cF9zdGF0dXNfbmFtZQAgGmxsaHR0cF9zZXRfbGVu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PgtBhwEMPQtBiAEMPAtBiQEMOwtBigEMOgtBiwEMOQtBjAEMOAtBjQEMNwtBjgEMNgtBjwEMNQtBkAEMNAtBkQEMMwtBkgEMMgtBkwEMMQtBlAEMMAtBlQEMLwtBlgEMLgtBlwEMLQtBmAEMLAtBmQEMKwtBmgEMKgtBmwEMKQtBnAEMKAtBnQEMJwtBngEMJgtBnwEMJQtBoAEMJAtBoQEMIwtBogEMIgtBowEMIQtBpAEMIAtBpQEMHwtBpgEMHgtBpwEMHQtBqAEMHAtBqQEMGwtBqgEMGgtBqwEMGQtBrAEMGAtBrQEMFwtBrgEMFgtBAQwVC0GvAQwUC0GwAQwTC0GxAQwSC0GzAQwRC0GyAQwQC0G0AQwPC0G1AQwOC0G2AQwNC0G3AQwMC0G4AQwLC0G5AQwKC0G6AQwJC0G7AQwIC0HGAQwHC0G8AQwGC0G9AQwFC0G+AQwEC0G/AQwDC0HAAQwCC0HCAQwBC0HBAQshAwNAAkACQAJAAkACQAJAAkACQAJAIAICfwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJ/AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgAgJ/AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACfwJAAkACfwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAC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iQEhAwykAgtBASABLQAAQd8ARw1nGiABQQFqIQEMXgtBigEhAyABIARGDaICIAIoAgAiACAEIAFraiEFIAEgAGtBAWohBgNAIAEtAAAgAEGMzwBqLQAARw1kIABBAUYN+gEgAEEBaiEAIAQgAUEBaiIBRw0ACyACIAU2AgAMogILQYsBIQMgASAERg2hAiACKAIAIgAgBCABa2ohBSABIABrQQJqIQYCQANAIAEtAAAgAEGOzwBqLQAARw1kIABBAkYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAyiAgsgAkEANgIAIAZBAWohAUECDGULQYwBIQMgASAERg2gAiACKAIAIgAgBCABa2ohBSABIABrQQFqIQYCQANAIAEtAAAgAEHwzwBqLQAARw1jIABBAUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAyhAgsgAkEANgIAIAZBAWohAUEfDGQLQY0BIQMgASAERg2fAiACKAIAIgAgBCABa2ohBSABIABrQQFqIQYCQANAIAEtAAAgAEHyzwBqLQAARw1iIABBAUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAygAgsgAkEANgIAIAZBAWohAUEJDGMLIAEgBEYEQEGOASEDDJ8CCwJAAkAgAS0AAEHJAGsOBwBiYmJiYgFiCyABQQFqIQFB+AAhAwyGAgsgAUEBaiEBQfkAIQMMhQILQY8BIQMgASAERg2dAiACKAIAIgAgBCABa2ohBSABIABrQQVqIQYCQANAIAEtAAAgAEGRzwBqLQAARw1gIABBBUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAyeAgsgAkEANgIAIAZBAWohAUEYDGELQZABIQMgASAERg2cAiACKAIAIgAgBCABa2ohBSABIABrQQJqIQYCQANAIAEtAAAgAEGXzwBqLQAARw1fIABBAkYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAydAgsgAkEANgIAIAZBAWohAUEXDGALQZEBIQMgASAERg2bAiACKAIAIgAgBCABa2ohBSABIABrQQZqIQYCQANAIAEtAAAgAEGazwBqLQAARw1eIABBBkYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAycAgsgAkEANgIAIAZBAWohAUEV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JSIARQ0RIAJB5QA2AhwgAiABNgIUIAIgADYCDEEAIQMMtAELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0gIAJB0wA2AhwgAiABNgIUIAIgADYCDEEAIQMMswELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0iIAJB0gA2AhwgAiABNgIUIAIgADYCDEEAIQMMsgELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0OIAJB5QA2AhwgAiABNgIUIAIgADYCDEEAIQMMsQELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0dIAJB0wA2AhwgAiABNgIUIAIgADYCDEEAIQMMsAELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0fIAJB0gA2AhwgAiABNgIUIAIgADYCDEEAIQMMrwELIABBP0cNASABQQFqCyEBQQUhAwyUAQtBACEDIAJBADYCHCACIAE2AhQgAkH9EjYCECACQQc2AgwMrAELIAJBADYCHCACIAE2AhQgAkHcCDYCECACQQc2AgxBACEDDKsBCyACKAIEIQAgAkEANgIEIAIgACABECUiAEUNByACQeUANgIcIAIgATYCFCACIAA2AgxBACEDDKoBCyACKAIEIQAgAkEANgIEIAIgACABECUiAEUNFiACQdMANgIcIAIgATYCFCACIAA2AgxBACEDDKkBCyACKAIEIQAgAkEANgIEIAIgACABECUiAEUNGCACQdIANgIcIAIgATYCFCACIAA2AgxBACEDDKgBCyACQQA2AhwgAiABNgIUIAJBxgo2AhAgAkEHNgIMQQAhAwynAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDQMgAkHlADYCHCACIAE2AhQgAiAANgIMQQAhAwymAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDRIgAkHTADYCHCACIAE2AhQgAiAANgIMQQAhAwylAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDRQgAkHSADYCHCACIAE2AhQgAiAANgIMQQAhAwykAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDQAgAkHlADYCHCACIAE2AhQgAiAANgIMQQAhAwyjAQtB1QAhAwyJAQsgAEEVRwRAIAJBADYCHCACIAE2AhQgAkG5DTYCECACQRo2AgxB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AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIABB5ABrDvQDY2IAAWFhYWFhYQIDBAVhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhBgcICQoLDA0OD2FhYWFhEGFhYWFhYWFhYWFhEWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYRITFBUWFxgZGhthYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2YTc4OTphYWFhYWFhYTthYWE8YWFhYT0+P2FhYWFhYWFhQGFhQWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYUJDREVGR0hJSktMTU5PUFFSU2FhYWFhYWFhVFVWV1hZWlthXF1hYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFeYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhX2BhC0HhJw8LQaQhDwtByywPC0H+MQ8LQcAkDwtBqyQPC0GNKA8LQeImDwtBgDAPC0G5Lw8LQdckDwtB7x8PC0HhHw8LQfofDwtB8iAPC0GoLw8LQa4yDwtBiDAPC0HsJw8LQYIiDwtBjh0PC0HQLg8LQcojDwtBxTIPC0HfHA8LQdIcDwtBxCAPC0HXIA8LQaIfDwtB7S4PC0GrMA8LQdQlDwtBzC4PC0H6Lg8LQfwrDwtB0jAPC0HxHQ8LQbsgDwtB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AAADAEGUCAsFBAAAAAUAQaQICwkGAAAABwAAAAgAQdwIC4otSW52YWxpZCBjaGFyIGluIHVybCBxdWVyeQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2JvZHkAQ29udGVudC1MZW5ndGggb3ZlcmZsb3cAQ2h1bmsgc2l6ZSBvdmVyZmxvdwBSZXNwb25zZSBvdmVyZmxvdwBJbnZhbGlkIG1ldGhvZCBmb3IgSFRUUC94LnggcmVxdWVzdABJbnZhbGlkIG1ldGhvZCBmb3IgUlRTUC94LnggcmVxdWVzdABFeHBlY3RlZCBTT1VSQ0UgbWV0aG9kIGZvciBJQ0UveC54IHJlcXVlc3QASW52YWxpZCBjaGFyIGluIHVybCBmcmFnbWVudCBzdGFydABFeHBlY3RlZCBkb3QAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9zdGF0dXMASW52YWxpZCByZXNwb25zZSBzdGF0dXMASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucwBVc2VyIGNhbGxiYWNrIGVycm9yAGBvbl9yZXNldGAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2hlYWRlcmAgY2FsbGJhY2sgZXJyb3IAYG9uX21lc3NhZ2VfYmVnaW5gIGNhbGxiYWNrIGVycm9yAGBvbl9jaHVua19leHRlbnNpb25fdmFsdWVgIGNhbGxiYWNrIGVycm9yAGBvbl9zdGF0dXNfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl92ZXJzaW9uX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fdXJsX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9oZWFkZXJfdmFsdWVfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9tZXNzYWdlX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fbWV0aG9kX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25faGVhZGVyX2ZpZWxkX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfZXh0ZW5zaW9uX25hbWVgIGNhbGxiYWNrIGVycm9yAFVuZXhwZWN0ZWQgY2hhciBpbiB1cmwgc2VydmVyAEludmFsaWQgaGVhZGVyIHZhbHVlIGNoYXIASW52YWxpZCBoZWFkZXIgZmllbGQgY2hhcgBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3ZlcnNpb24ASW52YWxpZCBtaW5vciB2ZXJzaW9uAEludmFsaWQgbWFqb3IgdmVyc2lvbgBFeHBlY3RlZCBzcGFjZSBhZnRlciB2ZXJzaW9uAEV4cGVjdGVkIENSTEYgYWZ0ZXIgdmVyc2lvbgBJbnZhbGlkIEhUVFAgdmVyc2lvbgBJbnZhbGlkIGhlYWRlciB0b2tlbgBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3VybABJbnZhbGlkIGNoYXJhY3RlcnMgaW4gdXJsAFVuZXhwZWN0ZWQgc3RhcnQgY2hhciBpbiB1cmwARG91YmxlIEAgaW4gdXJsAEVtcHR5IENvbnRlbnQtTGVuZ3RoAEludmFsaWQgY2hhcmFjdGVyIGluIENvbnRlbnQtTGVuZ3RoAER1cGxpY2F0ZSBDb250ZW50LUxlbmd0aABJbnZhbGlkIGNoYXIgaW4gdXJsIHBhdGgAQ29udGVudC1MZW5ndGggY2FuJ3QgYmUgcHJlc2VudCB3aXRoIFRyYW5zZmVyLUVuY29kaW5nAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIHNpemUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9oZWFkZXJfdmFsdWUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9jaHVua19leHRlbnNpb25fdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyB2YWx1ZQBNaXNzaW5nIGV4cGVjdGVkIExGIGFmdGVyIGhlYWRlciB2YWx1ZQBJbnZhbGlkIGBUcmFuc2Zlci1FbmNvZGluZ2AgaGVhZGVyIHZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgcXVvdGUgdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyBxdW90ZWQgdmFsdWUAUGF1c2VkIGJ5IG9uX2hlYWRlcnNfY29tcGxldGUASW52YWxpZCBFT0Ygc3RhdGUAb25fcmVzZXQgcGF1c2UAb25fY2h1bmtfaGVhZGVyIHBhdXNlAG9uX21lc3NhZ2VfYmVnaW4gcGF1c2UAb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlIHBhdXNlAG9uX3N0YXR1c19jb21wbGV0ZSBwYXVzZQBvbl92ZXJzaW9uX2NvbXBsZXRlIHBhdXNlAG9uX3VybF9jb21wbGV0ZSBwYXVzZQBvbl9jaHVua19jb21wbGV0ZSBwYXVzZQBvbl9oZWFkZXJfdmFsdWVfY29tcGxldGUgcGF1c2UAb25fbWVzc2FnZV9jb21wbGV0ZSBwYXVzZQBvbl9tZXRob2RfY29tcGxldGUgcGF1c2UAb25faGVhZGVyX2ZpZWxkX2NvbXBsZXRlIHBhdXNlAG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lIHBhdXNlAFVuZXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgc3RhcnQgbGluZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgbmFtZQBQYXVzZSBvbiBDT05ORUNUL1VwZ3JhZGUAUGF1c2Ugb24gUFJJL1VwZ3JhZGUARXhwZWN0ZWQgSFRUUC8yIENvbm5lY3Rpb24gUHJlZmFjZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX21ldGhvZABFeHBlY3RlZCBzcGFjZSBhZnRlciBtZXRob2QAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9oZWFkZXJfZmllbGQAUGF1c2VkAEludmFsaWQgd29yZCBlbmNvdW50ZXJlZABJbnZhbGlkIG1ldGhvZCBlbmNvdW50ZXJlZABVbmV4cGVjdGVkIGNoYXIgaW4gdXJsIHNjaGVtYQBSZXF1ZXN0IGhhcyBpbnZhbGlkIGBUcmFuc2Zlci1FbmNvZGluZ2AAU1dJVENIX1BST1hZAFVTRV9QUk9YWQBNS0FDVElWSVRZAFVOUFJPQ0VTU0FCTEVfRU5USVRZAENPUFkATU9WRURfUEVSTUFORU5UTFkAVE9PX0VBUkxZAE5PVElGWQBGQUlMRURfREVQRU5ERU5DWQBCQURfR0FURVdBWQBQTEFZAFBVVABDSEVDS09VVABHQVRFV0FZX1RJTUVPVVQAUkVRVUVTVF9USU1FT1VUAE5FVFdPUktfQ09OTkVDVF9USU1FT1VUAENPTk5FQ1RJT05fVElNRU9VVABMT0dJTl9USU1FT1VUAE5FVFdPUktfUkVBRF9USU1FT1VUAFBPU1QATUlTRElSRUNURURfUkVRVUVTVABDTElFTlRfQ0xPU0VEX1JFUVVFU1QAQ0xJRU5UX0NMT1NFRF9MT0FEX0JBTEFOQ0VEX1JFUVVFU1QAQkFEX1JFUVVFU1QASFRUUF9SRVFVRVNUX1NFTlRfVE9fSFRUUFNfUE9SVABSRVBPUlQASU1fQV9URUFQT1QAUkVTRVRfQ09OVEVOVABOT19DT05URU5UAFBBUlRJQUxfQ09OVEVOVABIUEVfSU5WQUxJRF9DT05TVEFOVABIUEVfQ0JfUkVTRVQAR0VUAEhQRV9TVFJJQ1QAQ09ORkxJQ1QAVEVNUE9SQVJZX1JFRElSRUNUAFBFUk1BTkVOVF9SRURJUkVDVABDT05ORUNUAE1VTFRJX1NUQVRVUwBIUEVfSU5WQUxJRF9TVEFUVVMAVE9PX01BTllfUkVRVUVTVFMARUFSTFlfSElOVFMAVU5BVkFJTEFCTEVfRk9SX0xFR0FMX1JFQVNPTlMAT1BUSU9OUwBTV0lUQ0hJTkdfUFJPVE9DT0xTAFZBUklBTlRfQUxTT19ORUdPVElBVEVTAE1VTFRJUExFX0NIT0lDRVMASU5URVJOQUxfU0VSVkVSX0VSUk9SAFdFQl9TRVJWRVJfVU5LTk9XTl9FUlJPUgBSQUlMR1VOX0VSUk9SAElERU5USVRZX1BST1ZJREVSX0FVVEhFTlRJQ0FUSU9OX0VSUk9SAFNTTF9DRVJUSUZJQ0FURV9FUlJPUgBJTlZBTElEX1hfRk9SV0FSREVEX0ZPUgBTRVRfUEFSQU1FVEVSAEdFVF9QQVJBTUVURVIASFBFX1VTRVIAU0VFX09USEVSAEhQRV9DQl9DSFVOS19IRUFERVIATUtDQUxFTkRBUgBTRVRVUABXRUJfU0VSVkVSX0lTX0RPV04AVEVBUkRPV04ASFBFX0NMT1NFRF9DT05ORUNUSU9OAEhFVVJJU1RJQ19FWFBJUkFUSU9OAERJU0NPTk5FQ1RFRF9PUEVSQVRJT04ATk9OX0FVVEhPUklUQVRJVkVfSU5GT1JNQVRJT04ASFBFX0lOVkFMSURfVkVSU0lPTgBIUEVfQ0JfTUVTU0FHRV9CRUdJTgBTSVRFX0lTX0ZST1pFTgBIUEVfSU5WQUxJRF9IRUFERVJfVE9LRU4ASU5WQUxJRF9UT0tFTgBGT1JCSURERU4ARU5IQU5DRV9ZT1VSX0NBTE0ASFBFX0lOVkFMSURfVVJMAEJMT0NLRURfQllfUEFSRU5UQUxfQ09OVFJPTABNS0NPTABBQ0wASFBFX0lOVEVSTkFMAFJFUVVFU1RfSEVBREVSX0ZJRUxEU19UT09fTEFSR0VfVU5PRkZJQ0lBTABIUEVfT0sAVU5MSU5LAFVOTE9DSwBQUkkAUkVUUllfV0lUSABIUEVfSU5WQUxJRF9DT05URU5UX0xFTkdUSABIUEVfVU5FWFBFQ1RFRF9DT05URU5UX0xFTkdUSABGTFVTSABQUk9QUEFUQ0gATS1TRUFSQ0gAVVJJX1RPT19MT05HAFBST0NFU1NJTkcATUlTQ0VMTEFORU9VU19QRVJTSVNURU5UX1dBUk5JTkcATUlTQ0VMTEFORU9VU19XQVJOSU5HAEhQRV9JTlZBTElEX1RSQU5TRkVSX0VOQ09ESU5HAEV4cGVjdGVkIENSTEYASFBFX0lOVkFMSURfQ0hVTktfU0laRQBNT1ZFAENPTlRJTlVFAEhQRV9DQl9TVEFUVVNfQ09NUExFVEUASFBFX0NCX0hFQURFUlNfQ09NUExFVEUASFBFX0NCX1ZFUlNJT05fQ09NUExFVEUASFBFX0NCX1VSTF9DT01QTEVURQBIUEVfQ0JfQ0hVTktfQ09NUExFVEUASFBFX0NCX0hFQURFUl9WQUxVRV9DT01QTEVURQBIUEVfQ0JfQ0hVTktfRVhURU5TSU9OX1ZBTFVFX0NPTVBMRVRFAEhQRV9DQl9DSFVOS19FWFRFTlNJT05fTkFNRV9DT01QTEVURQBIUEVfQ0JfTUVTU0FHRV9DT01QTEVURQBIUEVfQ0JfTUVUSE9EX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJfRklFTERfQ09NUExFVEUAREVMRVRFAEhQRV9JTlZBTElEX0VPRl9TVEFURQBJTlZBTElEX1NTTF9DRVJUSUZJQ0FURQBQQVVTRQBOT19SRVNQT05TRQBVTlNVUFBPUlRFRF9NRURJQV9UWVBFAEdPTkUATk9UX0FDQ0VQVEFCTEUAU0VSVklDRV9VTkFWQUlMQUJMRQBSQU5HRV9OT1RfU0FUSVNGSUFCTEUAT1JJR0lOX0lTX1VOUkVBQ0hBQkxFAFJFU1BPTlNFX0lTX1NUQUxFAFBVUkdFAE1FUkdFAFJFUVVFU1RfSEVBREVSX0ZJRUxEU19UT09fTEFSR0UAUkVRVUVTVF9IRUFERVJfVE9PX0xBUkdFAFBBWUxPQURfVE9PX0xBUkdFAElOU1VGRklDSUVOVF9TVE9SQUdFAEhQRV9QQVVTRURfVVBHUkFERQBIUEVfUEFVU0VEX0gyX1VQR1JBREUAU09VUkNFAEFOTk9VTkNFAFRSQUNFAEhQRV9VTkVYUEVDVEVEX1NQQUNFAERFU0NSSUJFAFVOU1VCU0NSSUJFAFJFQ09SRABIUEVfSU5WQUxJRF9NRVRIT0QATk9UX0ZPVU5EAFBST1BGSU5EAFVOQklORABSRUJJTkQAVU5BVVRIT1JJWkVEAE1FVEhPRF9OT1RfQUxMT1dFRABIVFRQX1ZFUlNJT05fTk9UX1NVUFBPUlRFRABBTFJFQURZX1JFUE9SVEVEAEFDQ0VQVEVEAE5PVF9JTVBMRU1FTlRFRABMT09QX0RFVEVDVEVEAEhQRV9DUl9FWFBFQ1RFRABIUEVfTEZfRVhQRUNURUQAQ1JFQVRFRABJTV9VU0VEAEhQRV9QQVVTRUQAVElNRU9VVF9PQ0NVUkVEAFBBWU1FTlRfUkVRVUlSRUQAUFJFQ09ORElUSU9OX1JFUVVJUkVEAFBST1hZX0FVVEhFTlRJQ0FUSU9OX1JFUVVJUkVEAE5FVFdPUktfQVVUSEVOVElDQVRJT05fUkVRVUlSRUQATEVOR1RIX1JFUVVJUkVEAFNTTF9DRVJUSUZJQ0FURV9SRVFVSVJFRABVUEdSQURFX1JFUVVJUkVEAFBBR0VfRVhQSVJFRABQUkVDT05ESVRJT05fRkFJTEVEAEVYUEVDVEFUSU9OX0ZBSUxFRABSRVZBTElEQVRJT05fRkFJTEVEAFNTTF9IQU5EU0hBS0VfRkFJTEVEAExPQ0tFRABUUkFOU0ZPUk1BVElPTl9BUFBMSUVEAE5PVF9NT0RJRklFRABOT1RfRVhURU5ERUQAQkFORFdJRFRIX0xJTUlUX0VYQ0VFREVEAFNJVEVfSVNfT1ZFUkxPQURFRABIRUFEAEV4cGVjdGVkIEhUVFAvAABeEwAAJhMAADAQAADwFwAAnRMAABUSAAA5FwAA8BIAAAoQAAB1EgAArRIAAIITAABPFAAAfxAAAKAVAAAjFAAAiRIAAIsUAABNFQAA1BEAAM8UAAAQGAAAyRYAANwWAADBEQAA4BcAALsUAAB0FAAAfBUAAOUUAAAIFwAAHxAAAGUVAACjFAAAKBUAAAIVAACZFQAALBAAAIsZAABPDwAA1A4AAGoQAADOEAAAAhcAAIkOAABuEwAAHBMAAGYUAABWFwAAwRMAAM0TAABsEwAAaBcAAGYXAABfFwAAIhMAAM4PAABpDgAA2A4AAGMWAADLEwAAqg4AACgXAAAmFwAAxRMAAF0WAADoEQAAZxMAAGUTAADyFgAAcxMAAB0XAAD5FgAA8xEAAM8OAADOFQAADBIAALMRAAClEQAAYRAAADIXAAC7EwBB+TULAQEAQZA2C+ABAQECAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAQf03CwEBAEGROAteAgMCAgICAgAAAgIAAgIAAgICAgICAgICAgAEAAAAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAgICAAIAAgBB/TkLAQEAQZE6C14CAAICAgICAAACAgACAgACAgICAgICAgICAAMABAAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAgACAEHwOwsNbG9zZWVlcC1hbGl2ZQBBiTwLAQEAQaA8C+ABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAQYk+CwEBAEGgPgvnAQEBAQEBAQEBAQEBAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBY2h1bmtlZABBsMAAC18BAQABAQEBAQAAAQEAAQEAAQEBAQEBAQEBAQAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEAAQBBkMIACyFlY3Rpb25lbnQtbGVuZ3Rob25yb3h5LWNvbm5lY3Rpb24AQcDCAAstcmFuc2Zlci1lbmNvZGluZ3BncmFkZQ0KDQoNClNNDQoNClRUUC9DRS9UU1AvAEH5wgALBQECAAEDAEGQwwAL4AEEAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQBB+cQACwUBAgABAwBBkMUAC+ABBAEBBQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAQfnGAAsEAQAAAQBBkccAC98BAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQBB+sgACwQBAAACAEGQyQALXwMEAAAEBAQEBAQEBAQEBAUEBAQEBAQEBAQEBAQABAAGBwQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEAAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAEAEH6ygALBAEAAAEAQZDLAAsBAQBBqssAC0ECAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwBB+swACwQBAAABAEGQzQALAQEAQZrNAAsGAgAAAAACAEGxzQALOgMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAQfDOAAuWAU5PVU5DRUVDS09VVE5FQ1RFVEVDUklCRUxVU0hFVEVBRFNFQVJDSFJHRUNUSVZJVFlMRU5EQVJWRU9USUZZUFRJT05TQ0hTRUFZU1RBVENIR0VPUkRJUkVDVE9SVFJDSFBBUkFNRVRFUlVSQ0VCU0NSSUJFQVJET1dOQUNFSU5ETktDS1VCU0NSSUJFSFRUUC9BRFRQLw==', 'base64'); + return llhttp_simdWasm; +} + +var constants$2; +var hasRequiredConstants$2; + +function requireConstants$2 () { + if (hasRequiredConstants$2) return constants$2; + hasRequiredConstants$2 = 1; + + const corsSafeListedMethods = ['GET', 'HEAD', 'POST']; + const corsSafeListedMethodsSet = new Set(corsSafeListedMethods); + + const nullBodyStatus = [101, 204, 205, 304]; + + const redirectStatus = [301, 302, 303, 307, 308]; + const redirectStatusSet = new Set(redirectStatus); + + // https://fetch.spec.whatwg.org/#block-bad-port + const badPorts = [ + '1', '7', '9', '11', '13', '15', '17', '19', '20', '21', '22', '23', '25', '37', '42', '43', '53', '69', '77', '79', + '87', '95', '101', '102', '103', '104', '109', '110', '111', '113', '115', '117', '119', '123', '135', '137', + '139', '143', '161', '179', '389', '427', '465', '512', '513', '514', '515', '526', '530', '531', '532', + '540', '548', '554', '556', '563', '587', '601', '636', '989', '990', '993', '995', '1719', '1720', '1723', + '2049', '3659', '4045', '4190', '5060', '5061', '6000', '6566', '6665', '6666', '6667', '6668', '6669', '6679', + '6697', '10080' + ]; + + const badPortsSet = new Set(badPorts); + + // https://w3c.github.io/webappsec-referrer-policy/#referrer-policies + const referrerPolicy = [ + '', + 'no-referrer', + 'no-referrer-when-downgrade', + 'same-origin', + 'origin', + 'strict-origin', + 'origin-when-cross-origin', + 'strict-origin-when-cross-origin', + 'unsafe-url' + ]; + const referrerPolicySet = new Set(referrerPolicy); + + const requestRedirect = ['follow', 'manual', 'error']; + + const safeMethods = ['GET', 'HEAD', 'OPTIONS', 'TRACE']; + const safeMethodsSet = new Set(safeMethods); + + const requestMode = ['navigate', 'same-origin', 'no-cors', 'cors']; + + const requestCredentials = ['omit', 'same-origin', 'include']; + + const requestCache = [ + 'default', + 'no-store', + 'reload', + 'no-cache', + 'force-cache', + 'only-if-cached' + ]; + + // https://fetch.spec.whatwg.org/#request-body-header-name + const requestBodyHeader = [ + 'content-encoding', + 'content-language', + 'content-location', + 'content-type', + // See https://github.com/nodejs/undici/issues/2021 + // 'Content-Length' is a forbidden header name, which is typically + // removed in the Headers implementation. However, undici doesn't + // filter out headers, so we add it here. + 'content-length' + ]; + + // https://fetch.spec.whatwg.org/#enumdef-requestduplex + const requestDuplex = [ + 'half' + ]; + + // http://fetch.spec.whatwg.org/#forbidden-method + const forbiddenMethods = ['CONNECT', 'TRACE', 'TRACK']; + const forbiddenMethodsSet = new Set(forbiddenMethods); + + const subresource = [ + 'audio', + 'audioworklet', + 'font', + 'image', + 'manifest', + 'paintworklet', + 'script', + 'style', + 'track', + 'video', + 'xslt', + '' + ]; + const subresourceSet = new Set(subresource); + + constants$2 = { + subresource, + forbiddenMethods, + requestBodyHeader, + referrerPolicy, + requestRedirect, + requestMode, + requestCredentials, + requestCache, + redirectStatus, + corsSafeListedMethods, + nullBodyStatus, + safeMethods, + badPorts, + requestDuplex, + subresourceSet, + badPortsSet, + redirectStatusSet, + corsSafeListedMethodsSet, + safeMethodsSet, + forbiddenMethodsSet, + referrerPolicySet + }; + return constants$2; +} + +var global$2; +var hasRequiredGlobal$1; + +function requireGlobal$1 () { + if (hasRequiredGlobal$1) return global$2; + hasRequiredGlobal$1 = 1; + + // In case of breaking changes, increase the version + // number to avoid conflicts. + const globalOrigin = Symbol.for('undici.globalOrigin.1'); + + function getGlobalOrigin () { + return globalThis[globalOrigin] + } + + function setGlobalOrigin (newOrigin) { + if (newOrigin === undefined) { + Object.defineProperty(globalThis, globalOrigin, { + value: undefined, + writable: true, + enumerable: false, + configurable: false + }); + + return + } + + const parsedURL = new URL(newOrigin); + + if (parsedURL.protocol !== 'http:' && parsedURL.protocol !== 'https:') { + throw new TypeError(`Only http & https urls are allowed, received ${parsedURL.protocol}`) + } + + Object.defineProperty(globalThis, globalOrigin, { + value: parsedURL, + writable: true, + enumerable: false, + configurable: false + }); + } + + global$2 = { + getGlobalOrigin, + setGlobalOrigin + }; + return global$2; +} + +var dataUrl; +var hasRequiredDataUrl; + +function requireDataUrl () { + if (hasRequiredDataUrl) return dataUrl; + hasRequiredDataUrl = 1; + + const assert = require$$0$4; + + const encoder = new TextEncoder(); + + /** + * @see https://mimesniff.spec.whatwg.org/#http-token-code-point + */ + const HTTP_TOKEN_CODEPOINTS = /^[!#$%&'*+\-.^_|~A-Za-z0-9]+$/; + const HTTP_WHITESPACE_REGEX = /[\u000A\u000D\u0009\u0020]/; // eslint-disable-line + const ASCII_WHITESPACE_REPLACE_REGEX = /[\u0009\u000A\u000C\u000D\u0020]/g; // eslint-disable-line + /** + * @see https://mimesniff.spec.whatwg.org/#http-quoted-string-token-code-point + */ + const HTTP_QUOTED_STRING_TOKENS = /^[\u0009\u0020-\u007E\u0080-\u00FF]+$/; // eslint-disable-line + + // https://fetch.spec.whatwg.org/#data-url-processor + /** @param {URL} dataURL */ + function dataURLProcessor (dataURL) { + // 1. Assert: dataURL’s scheme is "data". + assert(dataURL.protocol === 'data:'); + + // 2. Let input be the result of running the URL + // serializer on dataURL with exclude fragment + // set to true. + let input = URLSerializer(dataURL, true); + + // 3. Remove the leading "data:" string from input. + input = input.slice(5); + + // 4. Let position point at the start of input. + const position = { position: 0 }; + + // 5. Let mimeType be the result of collecting a + // sequence of code points that are not equal + // to U+002C (,), given position. + let mimeType = collectASequenceOfCodePointsFast( + ',', + input, + position + ); + + // 6. Strip leading and trailing ASCII whitespace + // from mimeType. + // Undici implementation note: we need to store the + // length because if the mimetype has spaces removed, + // the wrong amount will be sliced from the input in + // step #9 + const mimeTypeLength = mimeType.length; + mimeType = removeASCIIWhitespace(mimeType, true, true); + + // 7. If position is past the end of input, then + // return failure + if (position.position >= input.length) { + return 'failure' + } + + // 8. Advance position by 1. + position.position++; + + // 9. Let encodedBody be the remainder of input. + const encodedBody = input.slice(mimeTypeLength + 1); + + // 10. Let body be the percent-decoding of encodedBody. + let body = stringPercentDecode(encodedBody); + + // 11. If mimeType ends with U+003B (;), followed by + // zero or more U+0020 SPACE, followed by an ASCII + // case-insensitive match for "base64", then: + if (/;(\u0020){0,}base64$/i.test(mimeType)) { + // 1. Let stringBody be the isomorphic decode of body. + const stringBody = isomorphicDecode(body); + + // 2. Set body to the forgiving-base64 decode of + // stringBody. + body = forgivingBase64(stringBody); + + // 3. If body is failure, then return failure. + if (body === 'failure') { + return 'failure' + } + + // 4. Remove the last 6 code points from mimeType. + mimeType = mimeType.slice(0, -6); + + // 5. Remove trailing U+0020 SPACE code points from mimeType, + // if any. + mimeType = mimeType.replace(/(\u0020)+$/, ''); + + // 6. Remove the last U+003B (;) code point from mimeType. + mimeType = mimeType.slice(0, -1); + } + + // 12. If mimeType starts with U+003B (;), then prepend + // "text/plain" to mimeType. + if (mimeType.startsWith(';')) { + mimeType = 'text/plain' + mimeType; + } + + // 13. Let mimeTypeRecord be the result of parsing + // mimeType. + let mimeTypeRecord = parseMIMEType(mimeType); + + // 14. If mimeTypeRecord is failure, then set + // mimeTypeRecord to text/plain;charset=US-ASCII. + if (mimeTypeRecord === 'failure') { + mimeTypeRecord = parseMIMEType('text/plain;charset=US-ASCII'); + } + + // 15. Return a new data: URL struct whose MIME + // type is mimeTypeRecord and body is body. + // https://fetch.spec.whatwg.org/#data-url-struct + return { mimeType: mimeTypeRecord, body } + } + + // https://url.spec.whatwg.org/#concept-url-serializer + /** + * @param {URL} url + * @param {boolean} excludeFragment + */ + function URLSerializer (url, excludeFragment = false) { + if (!excludeFragment) { + return url.href + } + + const href = url.href; + const hashLength = url.hash.length; + + const serialized = hashLength === 0 ? href : href.substring(0, href.length - hashLength); + + if (!hashLength && href.endsWith('#')) { + return serialized.slice(0, -1) + } + + return serialized + } + + // https://infra.spec.whatwg.org/#collect-a-sequence-of-code-points + /** + * @param {(char: string) => boolean} condition + * @param {string} input + * @param {{ position: number }} position + */ + function collectASequenceOfCodePoints (condition, input, position) { + // 1. Let result be the empty string. + let result = ''; + + // 2. While position doesn’t point past the end of input and the + // code point at position within input meets the condition condition: + while (position.position < input.length && condition(input[position.position])) { + // 1. Append that code point to the end of result. + result += input[position.position]; + + // 2. Advance position by 1. + position.position++; + } + + // 3. Return result. + return result + } + + /** + * A faster collectASequenceOfCodePoints that only works when comparing a single character. + * @param {string} char + * @param {string} input + * @param {{ position: number }} position + */ + function collectASequenceOfCodePointsFast (char, input, position) { + const idx = input.indexOf(char, position.position); + const start = position.position; + + if (idx === -1) { + position.position = input.length; + return input.slice(start) + } + + position.position = idx; + return input.slice(start, position.position) + } + + // https://url.spec.whatwg.org/#string-percent-decode + /** @param {string} input */ + function stringPercentDecode (input) { + // 1. Let bytes be the UTF-8 encoding of input. + const bytes = encoder.encode(input); + + // 2. Return the percent-decoding of bytes. + return percentDecode(bytes) + } + + /** + * @param {number} byte + */ + function isHexCharByte (byte) { + // 0-9 A-F a-f + return (byte >= 0x30 && byte <= 0x39) || (byte >= 0x41 && byte <= 0x46) || (byte >= 0x61 && byte <= 0x66) + } + + /** + * @param {number} byte + */ + function hexByteToNumber (byte) { + return ( + // 0-9 + byte >= 0x30 && byte <= 0x39 + ? (byte - 48) + // Convert to uppercase + // ((byte & 0xDF) - 65) + 10 + : ((byte & 0xDF) - 55) + ) + } + + // https://url.spec.whatwg.org/#percent-decode + /** @param {Uint8Array} input */ + function percentDecode (input) { + const length = input.length; + // 1. Let output be an empty byte sequence. + /** @type {Uint8Array} */ + const output = new Uint8Array(length); + let j = 0; + // 2. For each byte byte in input: + for (let i = 0; i < length; ++i) { + const byte = input[i]; + + // 1. If byte is not 0x25 (%), then append byte to output. + if (byte !== 0x25) { + output[j++] = byte; + + // 2. Otherwise, if byte is 0x25 (%) and the next two bytes + // after byte in input are not in the ranges + // 0x30 (0) to 0x39 (9), 0x41 (A) to 0x46 (F), + // and 0x61 (a) to 0x66 (f), all inclusive, append byte + // to output. + } else if ( + byte === 0x25 && + !(isHexCharByte(input[i + 1]) && isHexCharByte(input[i + 2])) + ) { + output[j++] = 0x25; + + // 3. Otherwise: + } else { + // 1. Let bytePoint be the two bytes after byte in input, + // decoded, and then interpreted as hexadecimal number. + // 2. Append a byte whose value is bytePoint to output. + output[j++] = (hexByteToNumber(input[i + 1]) << 4) | hexByteToNumber(input[i + 2]); + + // 3. Skip the next two bytes in input. + i += 2; + } + } + + // 3. Return output. + return length === j ? output : output.subarray(0, j) + } + + // https://mimesniff.spec.whatwg.org/#parse-a-mime-type + /** @param {string} input */ + function parseMIMEType (input) { + // 1. Remove any leading and trailing HTTP whitespace + // from input. + input = removeHTTPWhitespace(input, true, true); + + // 2. Let position be a position variable for input, + // initially pointing at the start of input. + const position = { position: 0 }; + + // 3. Let type be the result of collecting a sequence + // of code points that are not U+002F (/) from + // input, given position. + const type = collectASequenceOfCodePointsFast( + '/', + input, + position + ); + + // 4. If type is the empty string or does not solely + // contain HTTP token code points, then return failure. + // https://mimesniff.spec.whatwg.org/#http-token-code-point + if (type.length === 0 || !HTTP_TOKEN_CODEPOINTS.test(type)) { + return 'failure' + } + + // 5. If position is past the end of input, then return + // failure + if (position.position > input.length) { + return 'failure' + } + + // 6. Advance position by 1. (This skips past U+002F (/).) + position.position++; + + // 7. Let subtype be the result of collecting a sequence of + // code points that are not U+003B (;) from input, given + // position. + let subtype = collectASequenceOfCodePointsFast( + ';', + input, + position + ); + + // 8. Remove any trailing HTTP whitespace from subtype. + subtype = removeHTTPWhitespace(subtype, false, true); + + // 9. If subtype is the empty string or does not solely + // contain HTTP token code points, then return failure. + if (subtype.length === 0 || !HTTP_TOKEN_CODEPOINTS.test(subtype)) { + return 'failure' + } + + const typeLowercase = type.toLowerCase(); + const subtypeLowercase = subtype.toLowerCase(); + + // 10. Let mimeType be a new MIME type record whose type + // is type, in ASCII lowercase, and subtype is subtype, + // in ASCII lowercase. + // https://mimesniff.spec.whatwg.org/#mime-type + const mimeType = { + type: typeLowercase, + subtype: subtypeLowercase, + /** @type {Map} */ + parameters: new Map(), + // https://mimesniff.spec.whatwg.org/#mime-type-essence + essence: `${typeLowercase}/${subtypeLowercase}` + }; + + // 11. While position is not past the end of input: + while (position.position < input.length) { + // 1. Advance position by 1. (This skips past U+003B (;).) + position.position++; + + // 2. Collect a sequence of code points that are HTTP + // whitespace from input given position. + collectASequenceOfCodePoints( + // https://fetch.spec.whatwg.org/#http-whitespace + char => HTTP_WHITESPACE_REGEX.test(char), + input, + position + ); + + // 3. Let parameterName be the result of collecting a + // sequence of code points that are not U+003B (;) + // or U+003D (=) from input, given position. + let parameterName = collectASequenceOfCodePoints( + (char) => char !== ';' && char !== '=', + input, + position + ); + + // 4. Set parameterName to parameterName, in ASCII + // lowercase. + parameterName = parameterName.toLowerCase(); + + // 5. If position is not past the end of input, then: + if (position.position < input.length) { + // 1. If the code point at position within input is + // U+003B (;), then continue. + if (input[position.position] === ';') { + continue + } + + // 2. Advance position by 1. (This skips past U+003D (=).) + position.position++; + } + + // 6. If position is past the end of input, then break. + if (position.position > input.length) { + break + } + + // 7. Let parameterValue be null. + let parameterValue = null; + + // 8. If the code point at position within input is + // U+0022 ("), then: + if (input[position.position] === '"') { + // 1. Set parameterValue to the result of collecting + // an HTTP quoted string from input, given position + // and the extract-value flag. + parameterValue = collectAnHTTPQuotedString(input, position, true); + + // 2. Collect a sequence of code points that are not + // U+003B (;) from input, given position. + collectASequenceOfCodePointsFast( + ';', + input, + position + ); + + // 9. Otherwise: + } else { + // 1. Set parameterValue to the result of collecting + // a sequence of code points that are not U+003B (;) + // from input, given position. + parameterValue = collectASequenceOfCodePointsFast( + ';', + input, + position + ); + + // 2. Remove any trailing HTTP whitespace from parameterValue. + parameterValue = removeHTTPWhitespace(parameterValue, false, true); + + // 3. If parameterValue is the empty string, then continue. + if (parameterValue.length === 0) { + continue + } + } + + // 10. If all of the following are true + // - parameterName is not the empty string + // - parameterName solely contains HTTP token code points + // - parameterValue solely contains HTTP quoted-string token code points + // - mimeType’s parameters[parameterName] does not exist + // then set mimeType’s parameters[parameterName] to parameterValue. + if ( + parameterName.length !== 0 && + HTTP_TOKEN_CODEPOINTS.test(parameterName) && + (parameterValue.length === 0 || HTTP_QUOTED_STRING_TOKENS.test(parameterValue)) && + !mimeType.parameters.has(parameterName) + ) { + mimeType.parameters.set(parameterName, parameterValue); + } + } + + // 12. Return mimeType. + return mimeType + } + + // https://infra.spec.whatwg.org/#forgiving-base64-decode + /** @param {string} data */ + function forgivingBase64 (data) { + // 1. Remove all ASCII whitespace from data. + data = data.replace(ASCII_WHITESPACE_REPLACE_REGEX, ''); // eslint-disable-line + + let dataLength = data.length; + // 2. If data’s code point length divides by 4 leaving + // no remainder, then: + if (dataLength % 4 === 0) { + // 1. If data ends with one or two U+003D (=) code points, + // then remove them from data. + if (data.charCodeAt(dataLength - 1) === 0x003D) { + --dataLength; + if (data.charCodeAt(dataLength - 1) === 0x003D) { + --dataLength; + } + } + } + + // 3. If data’s code point length divides by 4 leaving + // a remainder of 1, then return failure. + if (dataLength % 4 === 1) { + return 'failure' + } + + // 4. If data contains a code point that is not one of + // U+002B (+) + // U+002F (/) + // ASCII alphanumeric + // then return failure. + if (/[^+/0-9A-Za-z]/.test(data.length === dataLength ? data : data.substring(0, dataLength))) { + return 'failure' + } + + const buffer = Buffer.from(data, 'base64'); + return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength) + } + + // https://fetch.spec.whatwg.org/#collect-an-http-quoted-string + // tests: https://fetch.spec.whatwg.org/#example-http-quoted-string + /** + * @param {string} input + * @param {{ position: number }} position + * @param {boolean?} extractValue + */ + function collectAnHTTPQuotedString (input, position, extractValue) { + // 1. Let positionStart be position. + const positionStart = position.position; + + // 2. Let value be the empty string. + let value = ''; + + // 3. Assert: the code point at position within input + // is U+0022 ("). + assert(input[position.position] === '"'); + + // 4. Advance position by 1. + position.position++; + + // 5. While true: + while (true) { + // 1. Append the result of collecting a sequence of code points + // that are not U+0022 (") or U+005C (\) from input, given + // position, to value. + value += collectASequenceOfCodePoints( + (char) => char !== '"' && char !== '\\', + input, + position + ); + + // 2. If position is past the end of input, then break. + if (position.position >= input.length) { + break + } + + // 3. Let quoteOrBackslash be the code point at position within + // input. + const quoteOrBackslash = input[position.position]; + + // 4. Advance position by 1. + position.position++; + + // 5. If quoteOrBackslash is U+005C (\), then: + if (quoteOrBackslash === '\\') { + // 1. If position is past the end of input, then append + // U+005C (\) to value and break. + if (position.position >= input.length) { + value += '\\'; + break + } + + // 2. Append the code point at position within input to value. + value += input[position.position]; + + // 3. Advance position by 1. + position.position++; + + // 6. Otherwise: + } else { + // 1. Assert: quoteOrBackslash is U+0022 ("). + assert(quoteOrBackslash === '"'); + + // 2. Break. + break + } + } + + // 6. If the extract-value flag is set, then return value. + if (extractValue) { + return value + } + + // 7. Return the code points from positionStart to position, + // inclusive, within input. + return input.slice(positionStart, position.position) + } + + /** + * @see https://mimesniff.spec.whatwg.org/#serialize-a-mime-type + */ + function serializeAMimeType (mimeType) { + assert(mimeType !== 'failure'); + const { parameters, essence } = mimeType; + + // 1. Let serialization be the concatenation of mimeType’s + // type, U+002F (/), and mimeType’s subtype. + let serialization = essence; + + // 2. For each name → value of mimeType’s parameters: + for (let [name, value] of parameters.entries()) { + // 1. Append U+003B (;) to serialization. + serialization += ';'; + + // 2. Append name to serialization. + serialization += name; + + // 3. Append U+003D (=) to serialization. + serialization += '='; + + // 4. If value does not solely contain HTTP token code + // points or value is the empty string, then: + if (!HTTP_TOKEN_CODEPOINTS.test(value)) { + // 1. Precede each occurrence of U+0022 (") or + // U+005C (\) in value with U+005C (\). + value = value.replace(/(\\|")/g, '\\$1'); + + // 2. Prepend U+0022 (") to value. + value = '"' + value; + + // 3. Append U+0022 (") to value. + value += '"'; + } + + // 5. Append value to serialization. + serialization += value; + } + + // 3. Return serialization. + return serialization + } + + /** + * @see https://fetch.spec.whatwg.org/#http-whitespace + * @param {number} char + */ + function isHTTPWhiteSpace (char) { + // "\r\n\t " + return char === 0x00d || char === 0x00a || char === 0x009 || char === 0x020 + } + + /** + * @see https://fetch.spec.whatwg.org/#http-whitespace + * @param {string} str + * @param {boolean} [leading=true] + * @param {boolean} [trailing=true] + */ + function removeHTTPWhitespace (str, leading = true, trailing = true) { + return removeChars(str, leading, trailing, isHTTPWhiteSpace) + } + + /** + * @see https://infra.spec.whatwg.org/#ascii-whitespace + * @param {number} char + */ + function isASCIIWhitespace (char) { + // "\r\n\t\f " + return char === 0x00d || char === 0x00a || char === 0x009 || char === 0x00c || char === 0x020 + } + + /** + * @see https://infra.spec.whatwg.org/#strip-leading-and-trailing-ascii-whitespace + * @param {string} str + * @param {boolean} [leading=true] + * @param {boolean} [trailing=true] + */ + function removeASCIIWhitespace (str, leading = true, trailing = true) { + return removeChars(str, leading, trailing, isASCIIWhitespace) + } + + /** + * @param {string} str + * @param {boolean} leading + * @param {boolean} trailing + * @param {(charCode: number) => boolean} predicate + * @returns + */ + function removeChars (str, leading, trailing, predicate) { + let lead = 0; + let trail = str.length - 1; + + if (leading) { + while (lead < str.length && predicate(str.charCodeAt(lead))) lead++; + } + + if (trailing) { + while (trail > 0 && predicate(str.charCodeAt(trail))) trail--; + } + + return lead === 0 && trail === str.length - 1 ? str : str.slice(lead, trail + 1) + } + + /** + * @see https://infra.spec.whatwg.org/#isomorphic-decode + * @param {Uint8Array} input + * @returns {string} + */ + function isomorphicDecode (input) { + // 1. To isomorphic decode a byte sequence input, return a string whose code point + // length is equal to input’s length and whose code points have the same values + // as the values of input’s bytes, in the same order. + const length = input.length; + if ((2 << 15) - 1 > length) { + return String.fromCharCode.apply(null, input) + } + let result = ''; let i = 0; + let addition = (2 << 15) - 1; + while (i < length) { + if (i + addition > length) { + addition = length - i; + } + result += String.fromCharCode.apply(null, input.subarray(i, i += addition)); + } + return result + } + + /** + * @see https://mimesniff.spec.whatwg.org/#minimize-a-supported-mime-type + * @param {Exclude, 'failure'>} mimeType + */ + function minimizeSupportedMimeType (mimeType) { + switch (mimeType.essence) { + case 'application/ecmascript': + case 'application/javascript': + case 'application/x-ecmascript': + case 'application/x-javascript': + case 'text/ecmascript': + case 'text/javascript': + case 'text/javascript1.0': + case 'text/javascript1.1': + case 'text/javascript1.2': + case 'text/javascript1.3': + case 'text/javascript1.4': + case 'text/javascript1.5': + case 'text/jscript': + case 'text/livescript': + case 'text/x-ecmascript': + case 'text/x-javascript': + // 1. If mimeType is a JavaScript MIME type, then return "text/javascript". + return 'text/javascript' + case 'application/json': + case 'text/json': + // 2. If mimeType is a JSON MIME type, then return "application/json". + return 'application/json' + case 'image/svg+xml': + // 3. If mimeType’s essence is "image/svg+xml", then return "image/svg+xml". + return 'image/svg+xml' + case 'text/xml': + case 'application/xml': + // 4. If mimeType is an XML MIME type, then return "application/xml". + return 'application/xml' + } + + // 2. If mimeType is a JSON MIME type, then return "application/json". + if (mimeType.subtype.endsWith('+json')) { + return 'application/json' + } + + // 4. If mimeType is an XML MIME type, then return "application/xml". + if (mimeType.subtype.endsWith('+xml')) { + return 'application/xml' + } + + // 5. If mimeType is supported by the user agent, then return mimeType’s essence. + // Technically, node doesn't support any mimetypes. + + // 6. Return the empty string. + return '' + } + + dataUrl = { + dataURLProcessor, + URLSerializer, + collectASequenceOfCodePoints, + collectASequenceOfCodePointsFast, + stringPercentDecode, + parseMIMEType, + collectAnHTTPQuotedString, + serializeAMimeType, + removeChars, + removeHTTPWhitespace, + minimizeSupportedMimeType, + HTTP_TOKEN_CODEPOINTS, + isomorphicDecode + }; + return dataUrl; +} + +var webidl_1; +var hasRequiredWebidl; + +function requireWebidl () { + if (hasRequiredWebidl) return webidl_1; + hasRequiredWebidl = 1; + + const { types, inspect } = require$$0$6; + const { toUSVString } = requireUtil$7(); + + /** @type {import('../../../types/webidl').Webidl} */ + const webidl = {}; + webidl.converters = {}; + webidl.util = {}; + webidl.errors = {}; + + webidl.errors.exception = function (message) { + return new TypeError(`${message.header}: ${message.message}`) + }; + + webidl.errors.conversionFailed = function (context) { + const plural = context.types.length === 1 ? '' : ' one of'; + const message = + `${context.argument} could not be converted to` + + `${plural}: ${context.types.join(', ')}.`; + + return webidl.errors.exception({ + header: context.prefix, + message + }) + }; + + webidl.errors.invalidArgument = function (context) { + return webidl.errors.exception({ + header: context.prefix, + message: `"${context.value}" is an invalid ${context.type}.` + }) + }; + + // https://webidl.spec.whatwg.org/#implements + webidl.brandCheck = function (V, I, opts) { + if (opts?.strict !== false) { + if (!(V instanceof I)) { + const err = new TypeError('Illegal invocation'); + err.code = 'ERR_INVALID_THIS'; // node compat. + throw err + } + } else { + if (V?.[Symbol.toStringTag] !== I.prototype[Symbol.toStringTag]) { + const err = new TypeError('Illegal invocation'); + err.code = 'ERR_INVALID_THIS'; // node compat. + throw err + } + } + }; + + webidl.argumentLengthCheck = function ({ length }, min, ctx) { + if (length < min) { + throw webidl.errors.exception({ + message: `${min} argument${min !== 1 ? 's' : ''} required, ` + + `but${length ? ' only' : ''} ${length} found.`, + header: ctx + }) + } + }; + + webidl.illegalConstructor = function () { + throw webidl.errors.exception({ + header: 'TypeError', + message: 'Illegal constructor' + }) + }; + + // https://tc39.es/ecma262/#sec-ecmascript-data-types-and-values + webidl.util.Type = function (V) { + switch (typeof V) { + case 'undefined': return 'Undefined' + case 'boolean': return 'Boolean' + case 'string': return 'String' + case 'symbol': return 'Symbol' + case 'number': return 'Number' + case 'bigint': return 'BigInt' + case 'function': + case 'object': { + if (V === null) { + return 'Null' + } + + return 'Object' + } + } + }; + + // https://webidl.spec.whatwg.org/#abstract-opdef-converttoint + webidl.util.ConvertToInt = function (V, bitLength, signedness, opts) { + let upperBound; + let lowerBound; + + // 1. If bitLength is 64, then: + if (bitLength === 64) { + // 1. Let upperBound be 2^53 − 1. + upperBound = Math.pow(2, 53) - 1; + + // 2. If signedness is "unsigned", then let lowerBound be 0. + if (signedness === 'unsigned') { + lowerBound = 0; + } else { + // 3. Otherwise let lowerBound be −2^53 + 1. + lowerBound = Math.pow(-2, 53) + 1; + } + } else if (signedness === 'unsigned') { + // 2. Otherwise, if signedness is "unsigned", then: + + // 1. Let lowerBound be 0. + lowerBound = 0; + + // 2. Let upperBound be 2^bitLength − 1. + upperBound = Math.pow(2, bitLength) - 1; + } else { + // 3. Otherwise: + + // 1. Let lowerBound be -2^bitLength − 1. + lowerBound = Math.pow(-2, bitLength) - 1; + + // 2. Let upperBound be 2^bitLength − 1 − 1. + upperBound = Math.pow(2, bitLength - 1) - 1; + } + + // 4. Let x be ? ToNumber(V). + let x = Number(V); + + // 5. If x is −0, then set x to +0. + if (x === 0) { + x = 0; + } + + // 6. If the conversion is to an IDL type associated + // with the [EnforceRange] extended attribute, then: + if (opts?.enforceRange === true) { + // 1. If x is NaN, +∞, or −∞, then throw a TypeError. + if ( + Number.isNaN(x) || + x === Number.POSITIVE_INFINITY || + x === Number.NEGATIVE_INFINITY + ) { + throw webidl.errors.exception({ + header: 'Integer conversion', + message: `Could not convert ${webidl.util.Stringify(V)} to an integer.` + }) + } + + // 2. Set x to IntegerPart(x). + x = webidl.util.IntegerPart(x); + + // 3. If x < lowerBound or x > upperBound, then + // throw a TypeError. + if (x < lowerBound || x > upperBound) { + throw webidl.errors.exception({ + header: 'Integer conversion', + message: `Value must be between ${lowerBound}-${upperBound}, got ${x}.` + }) + } + + // 4. Return x. + return x + } + + // 7. If x is not NaN and the conversion is to an IDL + // type associated with the [Clamp] extended + // attribute, then: + if (!Number.isNaN(x) && opts?.clamp === true) { + // 1. Set x to min(max(x, lowerBound), upperBound). + x = Math.min(Math.max(x, lowerBound), upperBound); + + // 2. Round x to the nearest integer, choosing the + // even integer if it lies halfway between two, + // and choosing +0 rather than −0. + if (Math.floor(x) % 2 === 0) { + x = Math.floor(x); + } else { + x = Math.ceil(x); + } + + // 3. Return x. + return x + } + + // 8. If x is NaN, +0, +∞, or −∞, then return +0. + if ( + Number.isNaN(x) || + (x === 0 && Object.is(0, x)) || + x === Number.POSITIVE_INFINITY || + x === Number.NEGATIVE_INFINITY + ) { + return 0 + } + + // 9. Set x to IntegerPart(x). + x = webidl.util.IntegerPart(x); + + // 10. Set x to x modulo 2^bitLength. + x = x % Math.pow(2, bitLength); + + // 11. If signedness is "signed" and x ≥ 2^bitLength − 1, + // then return x − 2^bitLength. + if (signedness === 'signed' && x >= Math.pow(2, bitLength) - 1) { + return x - Math.pow(2, bitLength) + } + + // 12. Otherwise, return x. + return x + }; + + // https://webidl.spec.whatwg.org/#abstract-opdef-integerpart + webidl.util.IntegerPart = function (n) { + // 1. Let r be floor(abs(n)). + const r = Math.floor(Math.abs(n)); + + // 2. If n < 0, then return -1 × r. + if (n < 0) { + return -1 * r + } + + // 3. Otherwise, return r. + return r + }; + + webidl.util.Stringify = function (V) { + const type = webidl.util.Type(V); + + switch (type) { + case 'Symbol': + return `Symbol(${V.description})` + case 'Object': + return inspect(V) + case 'String': + return `"${V}"` + default: + return `${V}` + } + }; + + // https://webidl.spec.whatwg.org/#es-sequence + webidl.sequenceConverter = function (converter) { + return (V, prefix, argument, Iterable) => { + // 1. If Type(V) is not Object, throw a TypeError. + if (webidl.util.Type(V) !== 'Object') { + throw webidl.errors.exception({ + header: prefix, + message: `${argument} (${webidl.util.Stringify(V)}) is not iterable.` + }) + } + + // 2. Let method be ? GetMethod(V, @@iterator). + /** @type {Generator} */ + const method = typeof Iterable === 'function' ? Iterable() : V?.[Symbol.iterator]?.(); + const seq = []; + let index = 0; + + // 3. If method is undefined, throw a TypeError. + if ( + method === undefined || + typeof method.next !== 'function' + ) { + throw webidl.errors.exception({ + header: prefix, + message: `${argument} is not iterable.` + }) + } + + // https://webidl.spec.whatwg.org/#create-sequence-from-iterable + while (true) { + const { done, value } = method.next(); + + if (done) { + break + } + + seq.push(converter(value, prefix, `${argument}[${index++}]`)); + } + + return seq + } + }; + + // https://webidl.spec.whatwg.org/#es-to-record + webidl.recordConverter = function (keyConverter, valueConverter) { + return (O, prefix, argument) => { + // 1. If Type(O) is not Object, throw a TypeError. + if (webidl.util.Type(O) !== 'Object') { + throw webidl.errors.exception({ + header: prefix, + message: `${argument} ("${webidl.util.Type(O)}") is not an Object.` + }) + } + + // 2. Let result be a new empty instance of record. + const result = {}; + + if (!types.isProxy(O)) { + // 1. Let desc be ? O.[[GetOwnProperty]](key). + const keys = [...Object.getOwnPropertyNames(O), ...Object.getOwnPropertySymbols(O)]; + + for (const key of keys) { + // 1. Let typedKey be key converted to an IDL value of type K. + const typedKey = keyConverter(key, prefix, argument); + + // 2. Let value be ? Get(O, key). + // 3. Let typedValue be value converted to an IDL value of type V. + const typedValue = valueConverter(O[key], prefix, argument); + + // 4. Set result[typedKey] to typedValue. + result[typedKey] = typedValue; + } + + // 5. Return result. + return result + } + + // 3. Let keys be ? O.[[OwnPropertyKeys]](). + const keys = Reflect.ownKeys(O); + + // 4. For each key of keys. + for (const key of keys) { + // 1. Let desc be ? O.[[GetOwnProperty]](key). + const desc = Reflect.getOwnPropertyDescriptor(O, key); + + // 2. If desc is not undefined and desc.[[Enumerable]] is true: + if (desc?.enumerable) { + // 1. Let typedKey be key converted to an IDL value of type K. + const typedKey = keyConverter(key, prefix, argument); + + // 2. Let value be ? Get(O, key). + // 3. Let typedValue be value converted to an IDL value of type V. + const typedValue = valueConverter(O[key], prefix, argument); + + // 4. Set result[typedKey] to typedValue. + result[typedKey] = typedValue; + } + } + + // 5. Return result. + return result + } + }; + + webidl.interfaceConverter = function (i) { + return (V, prefix, argument, opts) => { + if (opts?.strict !== false && !(V instanceof i)) { + throw webidl.errors.exception({ + header: prefix, + message: `Expected ${argument} ("${webidl.util.Stringify(V)}") to be an instance of ${i.name}.` + }) + } + + return V + } + }; + + webidl.dictionaryConverter = function (converters) { + return (dictionary, prefix, argument) => { + const type = webidl.util.Type(dictionary); + const dict = {}; + + if (type === 'Null' || type === 'Undefined') { + return dict + } else if (type !== 'Object') { + throw webidl.errors.exception({ + header: prefix, + message: `Expected ${dictionary} to be one of: Null, Undefined, Object.` + }) + } + + for (const options of converters) { + const { key, defaultValue, required, converter } = options; + + if (required === true) { + if (!Object.hasOwn(dictionary, key)) { + throw webidl.errors.exception({ + header: prefix, + message: `Missing required key "${key}".` + }) + } + } + + let value = dictionary[key]; + const hasDefault = Object.hasOwn(options, 'defaultValue'); + + // Only use defaultValue if value is undefined and + // a defaultValue options was provided. + if (hasDefault && value !== null) { + value ??= defaultValue(); + } + + // A key can be optional and have no default value. + // When this happens, do not perform a conversion, + // and do not assign the key a value. + if (required || hasDefault || value !== undefined) { + value = converter(value, prefix, `${argument}.${key}`); + + if ( + options.allowedValues && + !options.allowedValues.includes(value) + ) { + throw webidl.errors.exception({ + header: prefix, + message: `${value} is not an accepted type. Expected one of ${options.allowedValues.join(', ')}.` + }) + } + + dict[key] = value; + } + } + + return dict + } + }; + + webidl.nullableConverter = function (converter) { + return (V, prefix, argument) => { + if (V === null) { + return V + } + + return converter(V, prefix, argument) + } + }; + + // https://webidl.spec.whatwg.org/#es-DOMString + webidl.converters.DOMString = function (V, prefix, argument, opts) { + // 1. If V is null and the conversion is to an IDL type + // associated with the [LegacyNullToEmptyString] + // extended attribute, then return the DOMString value + // that represents the empty string. + if (V === null && opts?.legacyNullToEmptyString) { + return '' + } + + // 2. Let x be ? ToString(V). + if (typeof V === 'symbol') { + throw webidl.errors.exception({ + header: prefix, + message: `${argument} is a symbol, which cannot be converted to a DOMString.` + }) + } + + // 3. Return the IDL DOMString value that represents the + // same sequence of code units as the one the + // ECMAScript String value x represents. + return String(V) + }; + + // https://webidl.spec.whatwg.org/#es-ByteString + webidl.converters.ByteString = function (V, prefix, argument) { + // 1. Let x be ? ToString(V). + // Note: DOMString converter perform ? ToString(V) + const x = webidl.converters.DOMString(V, prefix, argument); + + // 2. If the value of any element of x is greater than + // 255, then throw a TypeError. + for (let index = 0; index < x.length; index++) { + if (x.charCodeAt(index) > 255) { + throw new TypeError( + 'Cannot convert argument to a ByteString because the character at ' + + `index ${index} has a value of ${x.charCodeAt(index)} which is greater than 255.` + ) + } + } + + // 3. Return an IDL ByteString value whose length is the + // length of x, and where the value of each element is + // the value of the corresponding element of x. + return x + }; + + // https://webidl.spec.whatwg.org/#es-USVString + // TODO: rewrite this so we can control the errors thrown + webidl.converters.USVString = toUSVString; + + // https://webidl.spec.whatwg.org/#es-boolean + webidl.converters.boolean = function (V) { + // 1. Let x be the result of computing ToBoolean(V). + const x = Boolean(V); + + // 2. Return the IDL boolean value that is the one that represents + // the same truth value as the ECMAScript Boolean value x. + return x + }; + + // https://webidl.spec.whatwg.org/#es-any + webidl.converters.any = function (V) { + return V + }; + + // https://webidl.spec.whatwg.org/#es-long-long + webidl.converters['long long'] = function (V, prefix, argument) { + // 1. Let x be ? ConvertToInt(V, 64, "signed"). + const x = webidl.util.ConvertToInt(V, 64, 'signed', undefined, prefix, argument); + + // 2. Return the IDL long long value that represents + // the same numeric value as x. + return x + }; + + // https://webidl.spec.whatwg.org/#es-unsigned-long-long + webidl.converters['unsigned long long'] = function (V, prefix, argument) { + // 1. Let x be ? ConvertToInt(V, 64, "unsigned"). + const x = webidl.util.ConvertToInt(V, 64, 'unsigned', undefined, prefix, argument); + + // 2. Return the IDL unsigned long long value that + // represents the same numeric value as x. + return x + }; + + // https://webidl.spec.whatwg.org/#es-unsigned-long + webidl.converters['unsigned long'] = function (V, prefix, argument) { + // 1. Let x be ? ConvertToInt(V, 32, "unsigned"). + const x = webidl.util.ConvertToInt(V, 32, 'unsigned', undefined, prefix, argument); + + // 2. Return the IDL unsigned long value that + // represents the same numeric value as x. + return x + }; + + // https://webidl.spec.whatwg.org/#es-unsigned-short + webidl.converters['unsigned short'] = function (V, prefix, argument, opts) { + // 1. Let x be ? ConvertToInt(V, 16, "unsigned"). + const x = webidl.util.ConvertToInt(V, 16, 'unsigned', opts, prefix, argument); + + // 2. Return the IDL unsigned short value that represents + // the same numeric value as x. + return x + }; + + // https://webidl.spec.whatwg.org/#idl-ArrayBuffer + webidl.converters.ArrayBuffer = function (V, prefix, argument, opts) { + // 1. If Type(V) is not Object, or V does not have an + // [[ArrayBufferData]] internal slot, then throw a + // TypeError. + // see: https://tc39.es/ecma262/#sec-properties-of-the-arraybuffer-instances + // see: https://tc39.es/ecma262/#sec-properties-of-the-sharedarraybuffer-instances + if ( + webidl.util.Type(V) !== 'Object' || + !types.isAnyArrayBuffer(V) + ) { + throw webidl.errors.conversionFailed({ + prefix, + argument: `${argument} ("${webidl.util.Stringify(V)}")`, + types: ['ArrayBuffer'] + }) + } + + // 2. If the conversion is not to an IDL type associated + // with the [AllowShared] extended attribute, and + // IsSharedArrayBuffer(V) is true, then throw a + // TypeError. + if (opts?.allowShared === false && types.isSharedArrayBuffer(V)) { + throw webidl.errors.exception({ + header: 'ArrayBuffer', + message: 'SharedArrayBuffer is not allowed.' + }) + } + + // 3. If the conversion is not to an IDL type associated + // with the [AllowResizable] extended attribute, and + // IsResizableArrayBuffer(V) is true, then throw a + // TypeError. + if (V.resizable || V.growable) { + throw webidl.errors.exception({ + header: 'ArrayBuffer', + message: 'Received a resizable ArrayBuffer.' + }) + } + + // 4. Return the IDL ArrayBuffer value that is a + // reference to the same object as V. + return V + }; + + webidl.converters.TypedArray = function (V, T, prefix, name, opts) { + // 1. Let T be the IDL type V is being converted to. + + // 2. If Type(V) is not Object, or V does not have a + // [[TypedArrayName]] internal slot with a value + // equal to T’s name, then throw a TypeError. + if ( + webidl.util.Type(V) !== 'Object' || + !types.isTypedArray(V) || + V.constructor.name !== T.name + ) { + throw webidl.errors.conversionFailed({ + prefix, + argument: `${name} ("${webidl.util.Stringify(V)}")`, + types: [T.name] + }) + } + + // 3. If the conversion is not to an IDL type associated + // with the [AllowShared] extended attribute, and + // IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is + // true, then throw a TypeError. + if (opts?.allowShared === false && types.isSharedArrayBuffer(V.buffer)) { + throw webidl.errors.exception({ + header: 'ArrayBuffer', + message: 'SharedArrayBuffer is not allowed.' + }) + } + + // 4. If the conversion is not to an IDL type associated + // with the [AllowResizable] extended attribute, and + // IsResizableArrayBuffer(V.[[ViewedArrayBuffer]]) is + // true, then throw a TypeError. + if (V.buffer.resizable || V.buffer.growable) { + throw webidl.errors.exception({ + header: 'ArrayBuffer', + message: 'Received a resizable ArrayBuffer.' + }) + } + + // 5. Return the IDL value of type T that is a reference + // to the same object as V. + return V + }; + + webidl.converters.DataView = function (V, prefix, name, opts) { + // 1. If Type(V) is not Object, or V does not have a + // [[DataView]] internal slot, then throw a TypeError. + if (webidl.util.Type(V) !== 'Object' || !types.isDataView(V)) { + throw webidl.errors.exception({ + header: prefix, + message: `${name} is not a DataView.` + }) + } + + // 2. If the conversion is not to an IDL type associated + // with the [AllowShared] extended attribute, and + // IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is true, + // then throw a TypeError. + if (opts?.allowShared === false && types.isSharedArrayBuffer(V.buffer)) { + throw webidl.errors.exception({ + header: 'ArrayBuffer', + message: 'SharedArrayBuffer is not allowed.' + }) + } + + // 3. If the conversion is not to an IDL type associated + // with the [AllowResizable] extended attribute, and + // IsResizableArrayBuffer(V.[[ViewedArrayBuffer]]) is + // true, then throw a TypeError. + if (V.buffer.resizable || V.buffer.growable) { + throw webidl.errors.exception({ + header: 'ArrayBuffer', + message: 'Received a resizable ArrayBuffer.' + }) + } + + // 4. Return the IDL DataView value that is a reference + // to the same object as V. + return V + }; + + // https://webidl.spec.whatwg.org/#BufferSource + webidl.converters.BufferSource = function (V, prefix, name, opts) { + if (types.isAnyArrayBuffer(V)) { + return webidl.converters.ArrayBuffer(V, prefix, name, { ...opts, allowShared: false }) + } + + if (types.isTypedArray(V)) { + return webidl.converters.TypedArray(V, V.constructor, prefix, name, { ...opts, allowShared: false }) + } + + if (types.isDataView(V)) { + return webidl.converters.DataView(V, prefix, name, { ...opts, allowShared: false }) + } + + throw webidl.errors.conversionFailed({ + prefix, + argument: `${name} ("${webidl.util.Stringify(V)}")`, + types: ['BufferSource'] + }) + }; + + webidl.converters['sequence'] = webidl.sequenceConverter( + webidl.converters.ByteString + ); + + webidl.converters['sequence>'] = webidl.sequenceConverter( + webidl.converters['sequence'] + ); + + webidl.converters['record'] = webidl.recordConverter( + webidl.converters.ByteString, + webidl.converters.ByteString + ); + + webidl_1 = { + webidl + }; + return webidl_1; +} + +var util$6; +var hasRequiredUtil$6; + +function requireUtil$6 () { + if (hasRequiredUtil$6) return util$6; + hasRequiredUtil$6 = 1; + + const { Transform } = require$$0$5; + const zlib = require$$1; + const { redirectStatusSet, referrerPolicySet: referrerPolicyTokens, badPortsSet } = requireConstants$2(); + const { getGlobalOrigin } = requireGlobal$1(); + const { collectASequenceOfCodePoints, collectAnHTTPQuotedString, removeChars, parseMIMEType } = requireDataUrl(); + const { performance } = require$$5; + const { isBlobLike, ReadableStreamFrom, isValidHTTPToken, normalizedMethodRecordsBase } = requireUtil$7(); + const assert = require$$0$4; + const { isUint8Array } = require$$8$1; + const { webidl } = requireWebidl(); + + let supportedHashes = []; + + // https://nodejs.org/api/crypto.html#determining-if-crypto-support-is-unavailable + /** @type {import('crypto')} */ + let crypto; + try { + crypto = require('node:crypto'); + const possibleRelevantHashes = ['sha256', 'sha384', 'sha512']; + supportedHashes = crypto.getHashes().filter((hash) => possibleRelevantHashes.includes(hash)); + /* c8 ignore next 3 */ + } catch { + + } + + function responseURL (response) { + // https://fetch.spec.whatwg.org/#responses + // A response has an associated URL. It is a pointer to the last URL + // in response’s URL list and null if response’s URL list is empty. + const urlList = response.urlList; + const length = urlList.length; + return length === 0 ? null : urlList[length - 1].toString() + } + + // https://fetch.spec.whatwg.org/#concept-response-location-url + function responseLocationURL (response, requestFragment) { + // 1. If response’s status is not a redirect status, then return null. + if (!redirectStatusSet.has(response.status)) { + return null + } + + // 2. Let location be the result of extracting header list values given + // `Location` and response’s header list. + let location = response.headersList.get('location', true); + + // 3. If location is a header value, then set location to the result of + // parsing location with response’s URL. + if (location !== null && isValidHeaderValue(location)) { + if (!isValidEncodedURL(location)) { + // Some websites respond location header in UTF-8 form without encoding them as ASCII + // and major browsers redirect them to correctly UTF-8 encoded addresses. + // Here, we handle that behavior in the same way. + location = normalizeBinaryStringToUtf8(location); + } + location = new URL(location, responseURL(response)); + } + + // 4. If location is a URL whose fragment is null, then set location’s + // fragment to requestFragment. + if (location && !location.hash) { + location.hash = requestFragment; + } + + // 5. Return location. + return location + } + + /** + * @see https://www.rfc-editor.org/rfc/rfc1738#section-2.2 + * @param {string} url + * @returns {boolean} + */ + function isValidEncodedURL (url) { + for (let i = 0; i < url.length; ++i) { + const code = url.charCodeAt(i); + + if ( + code > 0x7E || // Non-US-ASCII + DEL + code < 0x20 // Control characters NUL - US + ) { + return false + } + } + return true + } + + /** + * If string contains non-ASCII characters, assumes it's UTF-8 encoded and decodes it. + * Since UTF-8 is a superset of ASCII, this will work for ASCII strings as well. + * @param {string} value + * @returns {string} + */ + function normalizeBinaryStringToUtf8 (value) { + return Buffer.from(value, 'binary').toString('utf8') + } + + /** @returns {URL} */ + function requestCurrentURL (request) { + return request.urlList[request.urlList.length - 1] + } + + function requestBadPort (request) { + // 1. Let url be request’s current URL. + const url = requestCurrentURL(request); + + // 2. If url’s scheme is an HTTP(S) scheme and url’s port is a bad port, + // then return blocked. + if (urlIsHttpHttpsScheme(url) && badPortsSet.has(url.port)) { + return 'blocked' + } + + // 3. Return allowed. + return 'allowed' + } + + function isErrorLike (object) { + return object instanceof Error || ( + object?.constructor?.name === 'Error' || + object?.constructor?.name === 'DOMException' + ) + } + + // Check whether |statusText| is a ByteString and + // matches the Reason-Phrase token production. + // RFC 2616: https://tools.ietf.org/html/rfc2616 + // RFC 7230: https://tools.ietf.org/html/rfc7230 + // "reason-phrase = *( HTAB / SP / VCHAR / obs-text )" + // https://github.com/chromium/chromium/blob/94.0.4604.1/third_party/blink/renderer/core/fetch/response.cc#L116 + function isValidReasonPhrase (statusText) { + for (let i = 0; i < statusText.length; ++i) { + const c = statusText.charCodeAt(i); + if ( + !( + ( + c === 0x09 || // HTAB + (c >= 0x20 && c <= 0x7e) || // SP / VCHAR + (c >= 0x80 && c <= 0xff) + ) // obs-text + ) + ) { + return false + } + } + return true + } + + /** + * @see https://fetch.spec.whatwg.org/#header-name + * @param {string} potentialValue + */ + const isValidHeaderName = isValidHTTPToken; + + /** + * @see https://fetch.spec.whatwg.org/#header-value + * @param {string} potentialValue + */ + function isValidHeaderValue (potentialValue) { + // - Has no leading or trailing HTTP tab or space bytes. + // - Contains no 0x00 (NUL) or HTTP newline bytes. + return ( + potentialValue[0] === '\t' || + potentialValue[0] === ' ' || + potentialValue[potentialValue.length - 1] === '\t' || + potentialValue[potentialValue.length - 1] === ' ' || + potentialValue.includes('\n') || + potentialValue.includes('\r') || + potentialValue.includes('\0') + ) === false + } + + // https://w3c.github.io/webappsec-referrer-policy/#set-requests-referrer-policy-on-redirect + function setRequestReferrerPolicyOnRedirect (request, actualResponse) { + // Given a request request and a response actualResponse, this algorithm + // updates request’s referrer policy according to the Referrer-Policy + // header (if any) in actualResponse. + + // 1. Let policy be the result of executing § 8.1 Parse a referrer policy + // from a Referrer-Policy header on actualResponse. + + // 8.1 Parse a referrer policy from a Referrer-Policy header + // 1. Let policy-tokens be the result of extracting header list values given `Referrer-Policy` and response’s header list. + const { headersList } = actualResponse; + // 2. Let policy be the empty string. + // 3. For each token in policy-tokens, if token is a referrer policy and token is not the empty string, then set policy to token. + // 4. Return policy. + const policyHeader = (headersList.get('referrer-policy', true) ?? '').split(','); + + // Note: As the referrer-policy can contain multiple policies + // separated by comma, we need to loop through all of them + // and pick the first valid one. + // Ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy#specify_a_fallback_policy + let policy = ''; + if (policyHeader.length > 0) { + // The right-most policy takes precedence. + // The left-most policy is the fallback. + for (let i = policyHeader.length; i !== 0; i--) { + const token = policyHeader[i - 1].trim(); + if (referrerPolicyTokens.has(token)) { + policy = token; + break + } + } + } + + // 2. If policy is not the empty string, then set request’s referrer policy to policy. + if (policy !== '') { + request.referrerPolicy = policy; + } + } + + // https://fetch.spec.whatwg.org/#cross-origin-resource-policy-check + function crossOriginResourcePolicyCheck () { + // TODO + return 'allowed' + } + + // https://fetch.spec.whatwg.org/#concept-cors-check + function corsCheck () { + // TODO + return 'success' + } + + // https://fetch.spec.whatwg.org/#concept-tao-check + function TAOCheck () { + // TODO + return 'success' + } + + function appendFetchMetadata (httpRequest) { + // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-dest-header + // TODO + + // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-mode-header + + // 1. Assert: r’s url is a potentially trustworthy URL. + // TODO + + // 2. Let header be a Structured Header whose value is a token. + let header = null; + + // 3. Set header’s value to r’s mode. + header = httpRequest.mode; + + // 4. Set a structured field value `Sec-Fetch-Mode`/header in r’s header list. + httpRequest.headersList.set('sec-fetch-mode', header, true); + + // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-site-header + // TODO + + // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-user-header + // TODO + } + + // https://fetch.spec.whatwg.org/#append-a-request-origin-header + function appendRequestOriginHeader (request) { + // 1. Let serializedOrigin be the result of byte-serializing a request origin + // with request. + // TODO: implement "byte-serializing a request origin" + let serializedOrigin = request.origin; + + // "'client' is changed to an origin during fetching." + // This doesn't happen in undici (in most cases) because undici, by default, + // has no concept of origin. + if (serializedOrigin === 'client') { + return + } + + // 2. If request’s response tainting is "cors" or request’s mode is "websocket", + // then append (`Origin`, serializedOrigin) to request’s header list. + // 3. Otherwise, if request’s method is neither `GET` nor `HEAD`, then: + if (request.responseTainting === 'cors' || request.mode === 'websocket') { + request.headersList.append('origin', serializedOrigin, true); + } else if (request.method !== 'GET' && request.method !== 'HEAD') { + // 1. Switch on request’s referrer policy: + switch (request.referrerPolicy) { + case 'no-referrer': + // Set serializedOrigin to `null`. + serializedOrigin = null; + break + case 'no-referrer-when-downgrade': + case 'strict-origin': + case 'strict-origin-when-cross-origin': + // If request’s origin is a tuple origin, its scheme is "https", and + // request’s current URL’s scheme is not "https", then set + // serializedOrigin to `null`. + if (request.origin && urlHasHttpsScheme(request.origin) && !urlHasHttpsScheme(requestCurrentURL(request))) { + serializedOrigin = null; + } + break + case 'same-origin': + // If request’s origin is not same origin with request’s current URL’s + // origin, then set serializedOrigin to `null`. + if (!sameOrigin(request, requestCurrentURL(request))) { + serializedOrigin = null; + } + break + // Do nothing. + } + + // 2. Append (`Origin`, serializedOrigin) to request’s header list. + request.headersList.append('origin', serializedOrigin, true); + } + } + + // https://w3c.github.io/hr-time/#dfn-coarsen-time + function coarsenTime (timestamp, crossOriginIsolatedCapability) { + // TODO + return timestamp + } + + // https://fetch.spec.whatwg.org/#clamp-and-coarsen-connection-timing-info + function clampAndCoarsenConnectionTimingInfo (connectionTimingInfo, defaultStartTime, crossOriginIsolatedCapability) { + if (!connectionTimingInfo?.startTime || connectionTimingInfo.startTime < defaultStartTime) { + return { + domainLookupStartTime: defaultStartTime, + domainLookupEndTime: defaultStartTime, + connectionStartTime: defaultStartTime, + connectionEndTime: defaultStartTime, + secureConnectionStartTime: defaultStartTime, + ALPNNegotiatedProtocol: connectionTimingInfo?.ALPNNegotiatedProtocol + } + } + + return { + domainLookupStartTime: coarsenTime(connectionTimingInfo.domainLookupStartTime), + domainLookupEndTime: coarsenTime(connectionTimingInfo.domainLookupEndTime), + connectionStartTime: coarsenTime(connectionTimingInfo.connectionStartTime), + connectionEndTime: coarsenTime(connectionTimingInfo.connectionEndTime), + secureConnectionStartTime: coarsenTime(connectionTimingInfo.secureConnectionStartTime), + ALPNNegotiatedProtocol: connectionTimingInfo.ALPNNegotiatedProtocol + } + } + + // https://w3c.github.io/hr-time/#dfn-coarsened-shared-current-time + function coarsenedSharedCurrentTime (crossOriginIsolatedCapability) { + return coarsenTime(performance.now()) + } + + // https://fetch.spec.whatwg.org/#create-an-opaque-timing-info + function createOpaqueTimingInfo (timingInfo) { + return { + startTime: timingInfo.startTime ?? 0, + redirectStartTime: 0, + redirectEndTime: 0, + postRedirectStartTime: timingInfo.startTime ?? 0, + finalServiceWorkerStartTime: 0, + finalNetworkResponseStartTime: 0, + finalNetworkRequestStartTime: 0, + endTime: 0, + encodedBodySize: 0, + decodedBodySize: 0, + finalConnectionTimingInfo: null + } + } + + // https://html.spec.whatwg.org/multipage/origin.html#policy-container + function makePolicyContainer () { + // Note: the fetch spec doesn't make use of embedder policy or CSP list + return { + referrerPolicy: 'strict-origin-when-cross-origin' + } + } + + // https://html.spec.whatwg.org/multipage/origin.html#clone-a-policy-container + function clonePolicyContainer (policyContainer) { + return { + referrerPolicy: policyContainer.referrerPolicy + } + } + + // https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer + function determineRequestsReferrer (request) { + // 1. Let policy be request's referrer policy. + const policy = request.referrerPolicy; + + // Note: policy cannot (shouldn't) be null or an empty string. + assert(policy); + + // 2. Let environment be request’s client. + + let referrerSource = null; + + // 3. Switch on request’s referrer: + if (request.referrer === 'client') { + // Note: node isn't a browser and doesn't implement document/iframes, + // so we bypass this step and replace it with our own. + + const globalOrigin = getGlobalOrigin(); + + if (!globalOrigin || globalOrigin.origin === 'null') { + return 'no-referrer' + } + + // note: we need to clone it as it's mutated + referrerSource = new URL(globalOrigin); + } else if (request.referrer instanceof URL) { + // Let referrerSource be request’s referrer. + referrerSource = request.referrer; + } + + // 4. Let request’s referrerURL be the result of stripping referrerSource for + // use as a referrer. + let referrerURL = stripURLForReferrer(referrerSource); + + // 5. Let referrerOrigin be the result of stripping referrerSource for use as + // a referrer, with the origin-only flag set to true. + const referrerOrigin = stripURLForReferrer(referrerSource, true); + + // 6. If the result of serializing referrerURL is a string whose length is + // greater than 4096, set referrerURL to referrerOrigin. + if (referrerURL.toString().length > 4096) { + referrerURL = referrerOrigin; + } + + const areSameOrigin = sameOrigin(request, referrerURL); + const isNonPotentiallyTrustWorthy = isURLPotentiallyTrustworthy(referrerURL) && + !isURLPotentiallyTrustworthy(request.url); + + // 8. Execute the switch statements corresponding to the value of policy: + switch (policy) { + case 'origin': return referrerOrigin != null ? referrerOrigin : stripURLForReferrer(referrerSource, true) + case 'unsafe-url': return referrerURL + case 'same-origin': + return areSameOrigin ? referrerOrigin : 'no-referrer' + case 'origin-when-cross-origin': + return areSameOrigin ? referrerURL : referrerOrigin + case 'strict-origin-when-cross-origin': { + const currentURL = requestCurrentURL(request); + + // 1. If the origin of referrerURL and the origin of request’s current + // URL are the same, then return referrerURL. + if (sameOrigin(referrerURL, currentURL)) { + return referrerURL + } + + // 2. If referrerURL is a potentially trustworthy URL and request’s + // current URL is not a potentially trustworthy URL, then return no + // referrer. + if (isURLPotentiallyTrustworthy(referrerURL) && !isURLPotentiallyTrustworthy(currentURL)) { + return 'no-referrer' + } + + // 3. Return referrerOrigin. + return referrerOrigin + } + case 'strict-origin': // eslint-disable-line + /** + * 1. If referrerURL is a potentially trustworthy URL and + * request’s current URL is not a potentially trustworthy URL, + * then return no referrer. + * 2. Return referrerOrigin + */ + case 'no-referrer-when-downgrade': // eslint-disable-line + /** + * 1. If referrerURL is a potentially trustworthy URL and + * request’s current URL is not a potentially trustworthy URL, + * then return no referrer. + * 2. Return referrerOrigin + */ + + default: // eslint-disable-line + return isNonPotentiallyTrustWorthy ? 'no-referrer' : referrerOrigin + } + } + + /** + * @see https://w3c.github.io/webappsec-referrer-policy/#strip-url + * @param {URL} url + * @param {boolean|undefined} originOnly + */ + function stripURLForReferrer (url, originOnly) { + // 1. Assert: url is a URL. + assert(url instanceof URL); + + url = new URL(url); + + // 2. If url’s scheme is a local scheme, then return no referrer. + if (url.protocol === 'file:' || url.protocol === 'about:' || url.protocol === 'blank:') { + return 'no-referrer' + } + + // 3. Set url’s username to the empty string. + url.username = ''; + + // 4. Set url’s password to the empty string. + url.password = ''; + + // 5. Set url’s fragment to null. + url.hash = ''; + + // 6. If the origin-only flag is true, then: + if (originOnly) { + // 1. Set url’s path to « the empty string ». + url.pathname = ''; + + // 2. Set url’s query to null. + url.search = ''; + } + + // 7. Return url. + return url + } + + function isURLPotentiallyTrustworthy (url) { + if (!(url instanceof URL)) { + return false + } + + // If child of about, return true + if (url.href === 'about:blank' || url.href === 'about:srcdoc') { + return true + } + + // If scheme is data, return true + if (url.protocol === 'data:') return true + + // If file, return true + if (url.protocol === 'file:') return true + + return isOriginPotentiallyTrustworthy(url.origin) + + function isOriginPotentiallyTrustworthy (origin) { + // If origin is explicitly null, return false + if (origin == null || origin === 'null') return false + + const originAsURL = new URL(origin); + + // If secure, return true + if (originAsURL.protocol === 'https:' || originAsURL.protocol === 'wss:') { + return true + } + + // If localhost or variants, return true + if (/^127(?:\.[0-9]+){0,2}\.[0-9]+$|^\[(?:0*:)*?:?0*1\]$/.test(originAsURL.hostname) || + (originAsURL.hostname === 'localhost' || originAsURL.hostname.includes('localhost.')) || + (originAsURL.hostname.endsWith('.localhost'))) { + return true + } + + // If any other, return false + return false + } + } + + /** + * @see https://w3c.github.io/webappsec-subresource-integrity/#does-response-match-metadatalist + * @param {Uint8Array} bytes + * @param {string} metadataList + */ + function bytesMatch (bytes, metadataList) { + // If node is not built with OpenSSL support, we cannot check + // a request's integrity, so allow it by default (the spec will + // allow requests if an invalid hash is given, as precedence). + /* istanbul ignore if: only if node is built with --without-ssl */ + if (crypto === undefined) { + return true + } + + // 1. Let parsedMetadata be the result of parsing metadataList. + const parsedMetadata = parseMetadata(metadataList); + + // 2. If parsedMetadata is no metadata, return true. + if (parsedMetadata === 'no metadata') { + return true + } + + // 3. If response is not eligible for integrity validation, return false. + // TODO + + // 4. If parsedMetadata is the empty set, return true. + if (parsedMetadata.length === 0) { + return true + } + + // 5. Let metadata be the result of getting the strongest + // metadata from parsedMetadata. + const strongest = getStrongestMetadata(parsedMetadata); + const metadata = filterMetadataListByAlgorithm(parsedMetadata, strongest); + + // 6. For each item in metadata: + for (const item of metadata) { + // 1. Let algorithm be the alg component of item. + const algorithm = item.algo; + + // 2. Let expectedValue be the val component of item. + const expectedValue = item.hash; + + // See https://github.com/web-platform-tests/wpt/commit/e4c5cc7a5e48093220528dfdd1c4012dc3837a0e + // "be liberal with padding". This is annoying, and it's not even in the spec. + + // 3. Let actualValue be the result of applying algorithm to bytes. + let actualValue = crypto.createHash(algorithm).update(bytes).digest('base64'); + + if (actualValue[actualValue.length - 1] === '=') { + if (actualValue[actualValue.length - 2] === '=') { + actualValue = actualValue.slice(0, -2); + } else { + actualValue = actualValue.slice(0, -1); + } + } + + // 4. If actualValue is a case-sensitive match for expectedValue, + // return true. + if (compareBase64Mixed(actualValue, expectedValue)) { + return true + } + } + + // 7. Return false. + return false + } + + // https://w3c.github.io/webappsec-subresource-integrity/#grammardef-hash-with-options + // https://www.w3.org/TR/CSP2/#source-list-syntax + // https://www.rfc-editor.org/rfc/rfc5234#appendix-B.1 + const parseHashWithOptions = /(?sha256|sha384|sha512)-((?[A-Za-z0-9+/]+|[A-Za-z0-9_-]+)={0,2}(?:\s|$)( +[!-~]*)?)?/i; + + /** + * @see https://w3c.github.io/webappsec-subresource-integrity/#parse-metadata + * @param {string} metadata + */ + function parseMetadata (metadata) { + // 1. Let result be the empty set. + /** @type {{ algo: string, hash: string }[]} */ + const result = []; + + // 2. Let empty be equal to true. + let empty = true; + + // 3. For each token returned by splitting metadata on spaces: + for (const token of metadata.split(' ')) { + // 1. Set empty to false. + empty = false; + + // 2. Parse token as a hash-with-options. + const parsedToken = parseHashWithOptions.exec(token); + + // 3. If token does not parse, continue to the next token. + if ( + parsedToken === null || + parsedToken.groups === undefined || + parsedToken.groups.algo === undefined + ) { + // Note: Chromium blocks the request at this point, but Firefox + // gives a warning that an invalid integrity was given. The + // correct behavior is to ignore these, and subsequently not + // check the integrity of the resource. + continue + } + + // 4. Let algorithm be the hash-algo component of token. + const algorithm = parsedToken.groups.algo.toLowerCase(); + + // 5. If algorithm is a hash function recognized by the user + // agent, add the parsed token to result. + if (supportedHashes.includes(algorithm)) { + result.push(parsedToken.groups); + } + } + + // 4. Return no metadata if empty is true, otherwise return result. + if (empty === true) { + return 'no metadata' + } + + return result + } + + /** + * @param {{ algo: 'sha256' | 'sha384' | 'sha512' }[]} metadataList + */ + function getStrongestMetadata (metadataList) { + // Let algorithm be the algo component of the first item in metadataList. + // Can be sha256 + let algorithm = metadataList[0].algo; + // If the algorithm is sha512, then it is the strongest + // and we can return immediately + if (algorithm[3] === '5') { + return algorithm + } + + for (let i = 1; i < metadataList.length; ++i) { + const metadata = metadataList[i]; + // If the algorithm is sha512, then it is the strongest + // and we can break the loop immediately + if (metadata.algo[3] === '5') { + algorithm = 'sha512'; + break + // If the algorithm is sha384, then a potential sha256 or sha384 is ignored + } else if (algorithm[3] === '3') { + continue + // algorithm is sha256, check if algorithm is sha384 and if so, set it as + // the strongest + } else if (metadata.algo[3] === '3') { + algorithm = 'sha384'; + } + } + return algorithm + } + + function filterMetadataListByAlgorithm (metadataList, algorithm) { + if (metadataList.length === 1) { + return metadataList + } + + let pos = 0; + for (let i = 0; i < metadataList.length; ++i) { + if (metadataList[i].algo === algorithm) { + metadataList[pos++] = metadataList[i]; + } + } + + metadataList.length = pos; + + return metadataList + } + + /** + * Compares two base64 strings, allowing for base64url + * in the second string. + * + * @param {string} actualValue always base64 + * @param {string} expectedValue base64 or base64url + * @returns {boolean} + */ + function compareBase64Mixed (actualValue, expectedValue) { + if (actualValue.length !== expectedValue.length) { + return false + } + for (let i = 0; i < actualValue.length; ++i) { + if (actualValue[i] !== expectedValue[i]) { + if ( + (actualValue[i] === '+' && expectedValue[i] === '-') || + (actualValue[i] === '/' && expectedValue[i] === '_') + ) { + continue + } + return false + } + } + + return true + } + + // https://w3c.github.io/webappsec-upgrade-insecure-requests/#upgrade-request + function tryUpgradeRequestToAPotentiallyTrustworthyURL (request) { + // TODO + } + + /** + * @link {https://html.spec.whatwg.org/multipage/origin.html#same-origin} + * @param {URL} A + * @param {URL} B + */ + function sameOrigin (A, B) { + // 1. If A and B are the same opaque origin, then return true. + if (A.origin === B.origin && A.origin === 'null') { + return true + } + + // 2. If A and B are both tuple origins and their schemes, + // hosts, and port are identical, then return true. + if (A.protocol === B.protocol && A.hostname === B.hostname && A.port === B.port) { + return true + } + + // 3. Return false. + return false + } + + function createDeferredPromise () { + let res; + let rej; + const promise = new Promise((resolve, reject) => { + res = resolve; + rej = reject; + }); + + return { promise, resolve: res, reject: rej } + } + + function isAborted (fetchParams) { + return fetchParams.controller.state === 'aborted' + } + + function isCancelled (fetchParams) { + return fetchParams.controller.state === 'aborted' || + fetchParams.controller.state === 'terminated' + } + + /** + * @see https://fetch.spec.whatwg.org/#concept-method-normalize + * @param {string} method + */ + function normalizeMethod (method) { + return normalizedMethodRecordsBase[method.toLowerCase()] ?? method + } + + // https://infra.spec.whatwg.org/#serialize-a-javascript-value-to-a-json-string + function serializeJavascriptValueToJSONString (value) { + // 1. Let result be ? Call(%JSON.stringify%, undefined, « value »). + const result = JSON.stringify(value); + + // 2. If result is undefined, then throw a TypeError. + if (result === undefined) { + throw new TypeError('Value is not JSON serializable') + } + + // 3. Assert: result is a string. + assert(typeof result === 'string'); + + // 4. Return result. + return result + } + + // https://tc39.es/ecma262/#sec-%25iteratorprototype%25-object + const esIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]())); + + /** + * @see https://webidl.spec.whatwg.org/#dfn-iterator-prototype-object + * @param {string} name name of the instance + * @param {symbol} kInternalIterator + * @param {string | number} [keyIndex] + * @param {string | number} [valueIndex] + */ + function createIterator (name, kInternalIterator, keyIndex = 0, valueIndex = 1) { + class FastIterableIterator { + /** @type {any} */ + #target + /** @type {'key' | 'value' | 'key+value'} */ + #kind + /** @type {number} */ + #index + + /** + * @see https://webidl.spec.whatwg.org/#dfn-default-iterator-object + * @param {unknown} target + * @param {'key' | 'value' | 'key+value'} kind + */ + constructor (target, kind) { + this.#target = target; + this.#kind = kind; + this.#index = 0; + } + + next () { + // 1. Let interface be the interface for which the iterator prototype object exists. + // 2. Let thisValue be the this value. + // 3. Let object be ? ToObject(thisValue). + // 4. If object is a platform object, then perform a security + // check, passing: + // 5. If object is not a default iterator object for interface, + // then throw a TypeError. + if (typeof this !== 'object' || this === null || !(#target in this)) { + throw new TypeError( + `'next' called on an object that does not implement interface ${name} Iterator.` + ) + } + + // 6. Let index be object’s index. + // 7. Let kind be object’s kind. + // 8. Let values be object’s target's value pairs to iterate over. + const index = this.#index; + const values = this.#target[kInternalIterator]; + + // 9. Let len be the length of values. + const len = values.length; + + // 10. If index is greater than or equal to len, then return + // CreateIterResultObject(undefined, true). + if (index >= len) { + return { + value: undefined, + done: true + } + } + + // 11. Let pair be the entry in values at index index. + const { [keyIndex]: key, [valueIndex]: value } = values[index]; + + // 12. Set object’s index to index + 1. + this.#index = index + 1; + + // 13. Return the iterator result for pair and kind. + + // https://webidl.spec.whatwg.org/#iterator-result + + // 1. Let result be a value determined by the value of kind: + let result; + switch (this.#kind) { + case 'key': + // 1. Let idlKey be pair’s key. + // 2. Let key be the result of converting idlKey to an + // ECMAScript value. + // 3. result is key. + result = key; + break + case 'value': + // 1. Let idlValue be pair’s value. + // 2. Let value be the result of converting idlValue to + // an ECMAScript value. + // 3. result is value. + result = value; + break + case 'key+value': + // 1. Let idlKey be pair’s key. + // 2. Let idlValue be pair’s value. + // 3. Let key be the result of converting idlKey to an + // ECMAScript value. + // 4. Let value be the result of converting idlValue to + // an ECMAScript value. + // 5. Let array be ! ArrayCreate(2). + // 6. Call ! CreateDataProperty(array, "0", key). + // 7. Call ! CreateDataProperty(array, "1", value). + // 8. result is array. + result = [key, value]; + break + } + + // 2. Return CreateIterResultObject(result, false). + return { + value: result, + done: false + } + } + } + + // https://webidl.spec.whatwg.org/#dfn-iterator-prototype-object + // @ts-ignore + delete FastIterableIterator.prototype.constructor; + + Object.setPrototypeOf(FastIterableIterator.prototype, esIteratorPrototype); + + Object.defineProperties(FastIterableIterator.prototype, { + [Symbol.toStringTag]: { + writable: false, + enumerable: false, + configurable: true, + value: `${name} Iterator` + }, + next: { writable: true, enumerable: true, configurable: true } + }); + + /** + * @param {unknown} target + * @param {'key' | 'value' | 'key+value'} kind + * @returns {IterableIterator} + */ + return function (target, kind) { + return new FastIterableIterator(target, kind) + } + } + + /** + * @see https://webidl.spec.whatwg.org/#dfn-iterator-prototype-object + * @param {string} name name of the instance + * @param {any} object class + * @param {symbol} kInternalIterator + * @param {string | number} [keyIndex] + * @param {string | number} [valueIndex] + */ + function iteratorMixin (name, object, kInternalIterator, keyIndex = 0, valueIndex = 1) { + const makeIterator = createIterator(name, kInternalIterator, keyIndex, valueIndex); + + const properties = { + keys: { + writable: true, + enumerable: true, + configurable: true, + value: function keys () { + webidl.brandCheck(this, object); + return makeIterator(this, 'key') + } + }, + values: { + writable: true, + enumerable: true, + configurable: true, + value: function values () { + webidl.brandCheck(this, object); + return makeIterator(this, 'value') + } + }, + entries: { + writable: true, + enumerable: true, + configurable: true, + value: function entries () { + webidl.brandCheck(this, object); + return makeIterator(this, 'key+value') + } + }, + forEach: { + writable: true, + enumerable: true, + configurable: true, + value: function forEach (callbackfn, thisArg = globalThis) { + webidl.brandCheck(this, object); + webidl.argumentLengthCheck(arguments, 1, `${name}.forEach`); + if (typeof callbackfn !== 'function') { + throw new TypeError( + `Failed to execute 'forEach' on '${name}': parameter 1 is not of type 'Function'.` + ) + } + for (const { 0: key, 1: value } of makeIterator(this, 'key+value')) { + callbackfn.call(thisArg, value, key, this); + } + } + } + }; + + return Object.defineProperties(object.prototype, { + ...properties, + [Symbol.iterator]: { + writable: true, + enumerable: false, + configurable: true, + value: properties.entries.value + } + }) + } + + /** + * @see https://fetch.spec.whatwg.org/#body-fully-read + */ + async function fullyReadBody (body, processBody, processBodyError, shouldClone) { + // 1. If taskDestination is null, then set taskDestination to + // the result of starting a new parallel queue. + + // 2. Let successSteps given a byte sequence bytes be to queue a + // fetch task to run processBody given bytes, with taskDestination. + const successSteps = processBody; + + // 3. Let errorSteps be to queue a fetch task to run processBodyError, + // with taskDestination. + const errorSteps = processBodyError; + + // 4. Let reader be the result of getting a reader for body’s stream. + // If that threw an exception, then run errorSteps with that + // exception and return. + let reader; + + try { + reader = body.stream.getReader(); + } catch (e) { + errorSteps(e); + return + } + + // 5. Read all bytes from reader, given successSteps and errorSteps. + try { + successSteps(await readAllBytes(reader, shouldClone)); + } catch (e) { + errorSteps(e); + } + } + + function isReadableStreamLike (stream) { + return stream instanceof ReadableStream || ( + stream[Symbol.toStringTag] === 'ReadableStream' && + typeof stream.tee === 'function' + ) + } + + /** + * @param {ReadableStreamController} controller + */ + function readableStreamClose (controller) { + try { + controller.close(); + controller.byobRequest?.respond(0); + } catch (err) { + // TODO: add comment explaining why this error occurs. + if (!err.message.includes('Controller is already closed') && !err.message.includes('ReadableStream is already closed')) { + throw err + } + } + } + + const invalidIsomorphicEncodeValueRegex = /[^\x00-\xFF]/; // eslint-disable-line + + /** + * @see https://infra.spec.whatwg.org/#isomorphic-encode + * @param {string} input + */ + function isomorphicEncode (input) { + // 1. Assert: input contains no code points greater than U+00FF. + assert(!invalidIsomorphicEncodeValueRegex.test(input)); + + // 2. Return a byte sequence whose length is equal to input’s code + // point length and whose bytes have the same values as the + // values of input’s code points, in the same order + return input + } + + /** + * @see https://streams.spec.whatwg.org/#readablestreamdefaultreader-read-all-bytes + * @see https://streams.spec.whatwg.org/#read-loop + * @param {ReadableStreamDefaultReader} reader + * @param {boolean} [shouldClone] + */ + async function readAllBytes (reader, shouldClone) { + const bytes = []; + let byteLength = 0; + + while (true) { + const { done, value: chunk } = await reader.read(); + + if (done) { + // 1. Call successSteps with bytes. + if (bytes.length === 1) { + const { buffer, byteOffset, byteLength } = bytes[0]; + if (shouldClone === false) { + return Buffer.from(buffer, byteOffset, byteLength) + } + return Buffer.from(buffer.slice(byteOffset, byteOffset + byteLength), 0, byteLength) + } + return Buffer.concat(bytes, byteLength) + } + + // 1. If chunk is not a Uint8Array object, call failureSteps + // with a TypeError and abort these steps. + if (!isUint8Array(chunk)) { + throw new TypeError('Received non-Uint8Array chunk') + } + + // 2. Append the bytes represented by chunk to bytes. + bytes.push(chunk); + byteLength += chunk.length; + + // 3. Read-loop given reader, bytes, successSteps, and failureSteps. + } + } + + /** + * @see https://fetch.spec.whatwg.org/#is-local + * @param {URL} url + */ + function urlIsLocal (url) { + assert('protocol' in url); // ensure it's a url object + + const protocol = url.protocol; + + return protocol === 'about:' || protocol === 'blob:' || protocol === 'data:' + } + + /** + * @param {string|URL} url + * @returns {boolean} + */ + function urlHasHttpsScheme (url) { + return ( + ( + typeof url === 'string' && + url[5] === ':' && + url[0] === 'h' && + url[1] === 't' && + url[2] === 't' && + url[3] === 'p' && + url[4] === 's' + ) || + url.protocol === 'https:' + ) + } + + /** + * @see https://fetch.spec.whatwg.org/#http-scheme + * @param {URL} url + */ + function urlIsHttpHttpsScheme (url) { + assert('protocol' in url); // ensure it's a url object + + const protocol = url.protocol; + + return protocol === 'http:' || protocol === 'https:' + } + + /** + * @see https://fetch.spec.whatwg.org/#simple-range-header-value + * @param {string} value + * @param {boolean} allowWhitespace + */ + function simpleRangeHeaderValue (value, allowWhitespace) { + // 1. Let data be the isomorphic decoding of value. + // Note: isomorphic decoding takes a sequence of bytes (ie. a Uint8Array) and turns it into a string, + // nothing more. We obviously don't need to do that if value is a string already. + const data = value; + + // 2. If data does not start with "bytes", then return failure. + if (!data.startsWith('bytes')) { + return 'failure' + } + + // 3. Let position be a position variable for data, initially pointing at the 5th code point of data. + const position = { position: 5 }; + + // 4. If allowWhitespace is true, collect a sequence of code points that are HTTP tab or space, + // from data given position. + if (allowWhitespace) { + collectASequenceOfCodePoints( + (char) => char === '\t' || char === ' ', + data, + position + ); + } + + // 5. If the code point at position within data is not U+003D (=), then return failure. + if (data.charCodeAt(position.position) !== 0x3D) { + return 'failure' + } + + // 6. Advance position by 1. + position.position++; + + // 7. If allowWhitespace is true, collect a sequence of code points that are HTTP tab or space, from + // data given position. + if (allowWhitespace) { + collectASequenceOfCodePoints( + (char) => char === '\t' || char === ' ', + data, + position + ); + } + + // 8. Let rangeStart be the result of collecting a sequence of code points that are ASCII digits, + // from data given position. + const rangeStart = collectASequenceOfCodePoints( + (char) => { + const code = char.charCodeAt(0); + + return code >= 0x30 && code <= 0x39 + }, + data, + position + ); + + // 9. Let rangeStartValue be rangeStart, interpreted as decimal number, if rangeStart is not the + // empty string; otherwise null. + const rangeStartValue = rangeStart.length ? Number(rangeStart) : null; + + // 10. If allowWhitespace is true, collect a sequence of code points that are HTTP tab or space, + // from data given position. + if (allowWhitespace) { + collectASequenceOfCodePoints( + (char) => char === '\t' || char === ' ', + data, + position + ); + } + + // 11. If the code point at position within data is not U+002D (-), then return failure. + if (data.charCodeAt(position.position) !== 0x2D) { + return 'failure' + } + + // 12. Advance position by 1. + position.position++; + + // 13. If allowWhitespace is true, collect a sequence of code points that are HTTP tab + // or space, from data given position. + // Note from Khafra: its the same step as in #8 again lol + if (allowWhitespace) { + collectASequenceOfCodePoints( + (char) => char === '\t' || char === ' ', + data, + position + ); + } + + // 14. Let rangeEnd be the result of collecting a sequence of code points that are + // ASCII digits, from data given position. + // Note from Khafra: you wouldn't guess it, but this is also the same step as #8 + const rangeEnd = collectASequenceOfCodePoints( + (char) => { + const code = char.charCodeAt(0); + + return code >= 0x30 && code <= 0x39 + }, + data, + position + ); + + // 15. Let rangeEndValue be rangeEnd, interpreted as decimal number, if rangeEnd + // is not the empty string; otherwise null. + // Note from Khafra: THE SAME STEP, AGAIN!!! + // Note: why interpret as a decimal if we only collect ascii digits? + const rangeEndValue = rangeEnd.length ? Number(rangeEnd) : null; + + // 16. If position is not past the end of data, then return failure. + if (position.position < data.length) { + return 'failure' + } + + // 17. If rangeEndValue and rangeStartValue are null, then return failure. + if (rangeEndValue === null && rangeStartValue === null) { + return 'failure' + } + + // 18. If rangeStartValue and rangeEndValue are numbers, and rangeStartValue is + // greater than rangeEndValue, then return failure. + // Note: ... when can they not be numbers? + if (rangeStartValue > rangeEndValue) { + return 'failure' + } + + // 19. Return (rangeStartValue, rangeEndValue). + return { rangeStartValue, rangeEndValue } + } + + /** + * @see https://fetch.spec.whatwg.org/#build-a-content-range + * @param {number} rangeStart + * @param {number} rangeEnd + * @param {number} fullLength + */ + function buildContentRange (rangeStart, rangeEnd, fullLength) { + // 1. Let contentRange be `bytes `. + let contentRange = 'bytes '; + + // 2. Append rangeStart, serialized and isomorphic encoded, to contentRange. + contentRange += isomorphicEncode(`${rangeStart}`); + + // 3. Append 0x2D (-) to contentRange. + contentRange += '-'; + + // 4. Append rangeEnd, serialized and isomorphic encoded to contentRange. + contentRange += isomorphicEncode(`${rangeEnd}`); + + // 5. Append 0x2F (/) to contentRange. + contentRange += '/'; + + // 6. Append fullLength, serialized and isomorphic encoded to contentRange. + contentRange += isomorphicEncode(`${fullLength}`); + + // 7. Return contentRange. + return contentRange + } + + // A Stream, which pipes the response to zlib.createInflate() or + // zlib.createInflateRaw() depending on the first byte of the Buffer. + // If the lower byte of the first byte is 0x08, then the stream is + // interpreted as a zlib stream, otherwise it's interpreted as a + // raw deflate stream. + class InflateStream extends Transform { + _transform (chunk, encoding, callback) { + if (!this._inflateStream) { + if (chunk.length === 0) { + callback(); + return + } + this._inflateStream = (chunk[0] & 0x0F) === 0x08 + ? zlib.createInflate() + : zlib.createInflateRaw(); + + this._inflateStream.on('data', this.push.bind(this)); + this._inflateStream.on('end', () => this.push(null)); + this._inflateStream.on('error', (err) => this.destroy(err)); + } + + this._inflateStream.write(chunk, encoding, callback); + } + + _final (callback) { + if (this._inflateStream) { + this._inflateStream.end(); + this._inflateStream = null; + } + callback(); + } + } + + function createInflate () { + return new InflateStream() + } + + /** + * @see https://fetch.spec.whatwg.org/#concept-header-extract-mime-type + * @param {import('./headers').HeadersList} headers + */ + function extractMimeType (headers) { + // 1. Let charset be null. + let charset = null; + + // 2. Let essence be null. + let essence = null; + + // 3. Let mimeType be null. + let mimeType = null; + + // 4. Let values be the result of getting, decoding, and splitting `Content-Type` from headers. + const values = getDecodeSplit('content-type', headers); + + // 5. If values is null, then return failure. + if (values === null) { + return 'failure' + } + + // 6. For each value of values: + for (const value of values) { + // 6.1. Let temporaryMimeType be the result of parsing value. + const temporaryMimeType = parseMIMEType(value); + + // 6.2. If temporaryMimeType is failure or its essence is "*/*", then continue. + if (temporaryMimeType === 'failure' || temporaryMimeType.essence === '*/*') { + continue + } + + // 6.3. Set mimeType to temporaryMimeType. + mimeType = temporaryMimeType; + + // 6.4. If mimeType’s essence is not essence, then: + if (mimeType.essence !== essence) { + // 6.4.1. Set charset to null. + charset = null; + + // 6.4.2. If mimeType’s parameters["charset"] exists, then set charset to + // mimeType’s parameters["charset"]. + if (mimeType.parameters.has('charset')) { + charset = mimeType.parameters.get('charset'); + } + + // 6.4.3. Set essence to mimeType’s essence. + essence = mimeType.essence; + } else if (!mimeType.parameters.has('charset') && charset !== null) { + // 6.5. Otherwise, if mimeType’s parameters["charset"] does not exist, and + // charset is non-null, set mimeType’s parameters["charset"] to charset. + mimeType.parameters.set('charset', charset); + } + } + + // 7. If mimeType is null, then return failure. + if (mimeType == null) { + return 'failure' + } + + // 8. Return mimeType. + return mimeType + } + + /** + * @see https://fetch.spec.whatwg.org/#header-value-get-decode-and-split + * @param {string|null} value + */ + function gettingDecodingSplitting (value) { + // 1. Let input be the result of isomorphic decoding value. + const input = value; + + // 2. Let position be a position variable for input, initially pointing at the start of input. + const position = { position: 0 }; + + // 3. Let values be a list of strings, initially empty. + const values = []; + + // 4. Let temporaryValue be the empty string. + let temporaryValue = ''; + + // 5. While position is not past the end of input: + while (position.position < input.length) { + // 5.1. Append the result of collecting a sequence of code points that are not U+0022 (") + // or U+002C (,) from input, given position, to temporaryValue. + temporaryValue += collectASequenceOfCodePoints( + (char) => char !== '"' && char !== ',', + input, + position + ); + + // 5.2. If position is not past the end of input, then: + if (position.position < input.length) { + // 5.2.1. If the code point at position within input is U+0022 ("), then: + if (input.charCodeAt(position.position) === 0x22) { + // 5.2.1.1. Append the result of collecting an HTTP quoted string from input, given position, to temporaryValue. + temporaryValue += collectAnHTTPQuotedString( + input, + position + ); + + // 5.2.1.2. If position is not past the end of input, then continue. + if (position.position < input.length) { + continue + } + } else { + // 5.2.2. Otherwise: + + // 5.2.2.1. Assert: the code point at position within input is U+002C (,). + assert(input.charCodeAt(position.position) === 0x2C); + + // 5.2.2.2. Advance position by 1. + position.position++; + } + } + + // 5.3. Remove all HTTP tab or space from the start and end of temporaryValue. + temporaryValue = removeChars(temporaryValue, true, true, (char) => char === 0x9 || char === 0x20); + + // 5.4. Append temporaryValue to values. + values.push(temporaryValue); + + // 5.6. Set temporaryValue to the empty string. + temporaryValue = ''; + } + + // 6. Return values. + return values + } + + /** + * @see https://fetch.spec.whatwg.org/#concept-header-list-get-decode-split + * @param {string} name lowercase header name + * @param {import('./headers').HeadersList} list + */ + function getDecodeSplit (name, list) { + // 1. Let value be the result of getting name from list. + const value = list.get(name, true); + + // 2. If value is null, then return null. + if (value === null) { + return null + } + + // 3. Return the result of getting, decoding, and splitting value. + return gettingDecodingSplitting(value) + } + + const textDecoder = new TextDecoder(); + + /** + * @see https://encoding.spec.whatwg.org/#utf-8-decode + * @param {Buffer} buffer + */ + function utf8DecodeBytes (buffer) { + if (buffer.length === 0) { + return '' + } + + // 1. Let buffer be the result of peeking three bytes from + // ioQueue, converted to a byte sequence. + + // 2. If buffer is 0xEF 0xBB 0xBF, then read three + // bytes from ioQueue. (Do nothing with those bytes.) + if (buffer[0] === 0xEF && buffer[1] === 0xBB && buffer[2] === 0xBF) { + buffer = buffer.subarray(3); + } + + // 3. Process a queue with an instance of UTF-8’s + // decoder, ioQueue, output, and "replacement". + const output = textDecoder.decode(buffer); + + // 4. Return output. + return output + } + + class EnvironmentSettingsObjectBase { + get baseUrl () { + return getGlobalOrigin() + } + + get origin () { + return this.baseUrl?.origin + } + + policyContainer = makePolicyContainer() + } + + class EnvironmentSettingsObject { + settingsObject = new EnvironmentSettingsObjectBase() + } + + const environmentSettingsObject = new EnvironmentSettingsObject(); + + util$6 = { + isAborted, + isCancelled, + isValidEncodedURL, + createDeferredPromise, + ReadableStreamFrom, + tryUpgradeRequestToAPotentiallyTrustworthyURL, + clampAndCoarsenConnectionTimingInfo, + coarsenedSharedCurrentTime, + determineRequestsReferrer, + makePolicyContainer, + clonePolicyContainer, + appendFetchMetadata, + appendRequestOriginHeader, + TAOCheck, + corsCheck, + crossOriginResourcePolicyCheck, + createOpaqueTimingInfo, + setRequestReferrerPolicyOnRedirect, + isValidHTTPToken, + requestBadPort, + requestCurrentURL, + responseURL, + responseLocationURL, + isBlobLike, + isURLPotentiallyTrustworthy, + isValidReasonPhrase, + sameOrigin, + normalizeMethod, + serializeJavascriptValueToJSONString, + iteratorMixin, + createIterator, + isValidHeaderName, + isValidHeaderValue, + isErrorLike, + fullyReadBody, + bytesMatch, + isReadableStreamLike, + readableStreamClose, + isomorphicEncode, + urlIsLocal, + urlHasHttpsScheme, + urlIsHttpHttpsScheme, + readAllBytes, + simpleRangeHeaderValue, + buildContentRange, + parseMetadata, + createInflate, + extractMimeType, + getDecodeSplit, + utf8DecodeBytes, + environmentSettingsObject + }; + return util$6; +} + +var symbols$3; +var hasRequiredSymbols$3; + +function requireSymbols$3 () { + if (hasRequiredSymbols$3) return symbols$3; + hasRequiredSymbols$3 = 1; + + symbols$3 = { + kUrl: Symbol('url'), + kHeaders: Symbol('headers'), + kSignal: Symbol('signal'), + kState: Symbol('state'), + kDispatcher: Symbol('dispatcher') + }; + return symbols$3; +} + +var file; +var hasRequiredFile; + +function requireFile () { + if (hasRequiredFile) return file; + hasRequiredFile = 1; + + const { Blob, File } = require$$0$3; + const { kState } = requireSymbols$3(); + const { webidl } = requireWebidl(); + + // TODO(@KhafraDev): remove + class FileLike { + constructor (blobLike, fileName, options = {}) { + // TODO: argument idl type check + + // The File constructor is invoked with two or three parameters, depending + // on whether the optional dictionary parameter is used. When the File() + // constructor is invoked, user agents must run the following steps: + + // 1. Let bytes be the result of processing blob parts given fileBits and + // options. + + // 2. Let n be the fileName argument to the constructor. + const n = fileName; + + // 3. Process FilePropertyBag dictionary argument by running the following + // substeps: + + // 1. If the type member is provided and is not the empty string, let t + // be set to the type dictionary member. If t contains any characters + // outside the range U+0020 to U+007E, then set t to the empty string + // and return from these substeps. + // TODO + const t = options.type; + + // 2. Convert every character in t to ASCII lowercase. + // TODO + + // 3. If the lastModified member is provided, let d be set to the + // lastModified dictionary member. If it is not provided, set d to the + // current date and time represented as the number of milliseconds since + // the Unix Epoch (which is the equivalent of Date.now() [ECMA-262]). + const d = options.lastModified ?? Date.now(); + + // 4. Return a new File object F such that: + // F refers to the bytes byte sequence. + // F.size is set to the number of total bytes in bytes. + // F.name is set to n. + // F.type is set to t. + // F.lastModified is set to d. + + this[kState] = { + blobLike, + name: n, + type: t, + lastModified: d + }; + } + + stream (...args) { + webidl.brandCheck(this, FileLike); + + return this[kState].blobLike.stream(...args) + } + + arrayBuffer (...args) { + webidl.brandCheck(this, FileLike); + + return this[kState].blobLike.arrayBuffer(...args) + } + + slice (...args) { + webidl.brandCheck(this, FileLike); + + return this[kState].blobLike.slice(...args) + } + + text (...args) { + webidl.brandCheck(this, FileLike); + + return this[kState].blobLike.text(...args) + } + + get size () { + webidl.brandCheck(this, FileLike); + + return this[kState].blobLike.size + } + + get type () { + webidl.brandCheck(this, FileLike); + + return this[kState].blobLike.type + } + + get name () { + webidl.brandCheck(this, FileLike); + + return this[kState].name + } + + get lastModified () { + webidl.brandCheck(this, FileLike); + + return this[kState].lastModified + } + + get [Symbol.toStringTag] () { + return 'File' + } + } + + webidl.converters.Blob = webidl.interfaceConverter(Blob); + + // If this function is moved to ./util.js, some tools (such as + // rollup) will warn about circular dependencies. See: + // https://github.com/nodejs/undici/issues/1629 + function isFileLike (object) { + return ( + (object instanceof File) || + ( + object && + (typeof object.stream === 'function' || + typeof object.arrayBuffer === 'function') && + object[Symbol.toStringTag] === 'File' + ) + ) + } + + file = { FileLike, isFileLike }; + return file; +} + +var formdata; +var hasRequiredFormdata; + +function requireFormdata () { + if (hasRequiredFormdata) return formdata; + hasRequiredFormdata = 1; + + const { isBlobLike, iteratorMixin } = requireUtil$6(); + const { kState } = requireSymbols$3(); + const { kEnumerableProperty } = requireUtil$7(); + const { FileLike, isFileLike } = requireFile(); + const { webidl } = requireWebidl(); + const { File: NativeFile } = require$$0$3; + const nodeUtil = require$$0$6; + + /** @type {globalThis['File']} */ + const File = globalThis.File ?? NativeFile; + + // https://xhr.spec.whatwg.org/#formdata + class FormData { + constructor (form) { + if (form !== undefined) { + throw webidl.errors.conversionFailed({ + prefix: 'FormData constructor', + argument: 'Argument 1', + types: ['undefined'] + }) + } + + this[kState] = []; + } + + append (name, value, filename = undefined) { + webidl.brandCheck(this, FormData); + + const prefix = 'FormData.append'; + webidl.argumentLengthCheck(arguments, 2, prefix); + + if (arguments.length === 3 && !isBlobLike(value)) { + throw new TypeError( + "Failed to execute 'append' on 'FormData': parameter 2 is not of type 'Blob'" + ) + } + + // 1. Let value be value if given; otherwise blobValue. + + name = webidl.converters.USVString(name, prefix, 'name'); + value = isBlobLike(value) + ? webidl.converters.Blob(value, prefix, 'value', { strict: false }) + : webidl.converters.USVString(value, prefix, 'value'); + filename = arguments.length === 3 + ? webidl.converters.USVString(filename, prefix, 'filename') + : undefined; + + // 2. Let entry be the result of creating an entry with + // name, value, and filename if given. + const entry = makeEntry(name, value, filename); + + // 3. Append entry to this’s entry list. + this[kState].push(entry); + } + + delete (name) { + webidl.brandCheck(this, FormData); + + const prefix = 'FormData.delete'; + webidl.argumentLengthCheck(arguments, 1, prefix); + + name = webidl.converters.USVString(name, prefix, 'name'); + + // The delete(name) method steps are to remove all entries whose name + // is name from this’s entry list. + this[kState] = this[kState].filter(entry => entry.name !== name); + } + + get (name) { + webidl.brandCheck(this, FormData); + + const prefix = 'FormData.get'; + webidl.argumentLengthCheck(arguments, 1, prefix); + + name = webidl.converters.USVString(name, prefix, 'name'); + + // 1. If there is no entry whose name is name in this’s entry list, + // then return null. + const idx = this[kState].findIndex((entry) => entry.name === name); + if (idx === -1) { + return null + } + + // 2. Return the value of the first entry whose name is name from + // this’s entry list. + return this[kState][idx].value + } + + getAll (name) { + webidl.brandCheck(this, FormData); + + const prefix = 'FormData.getAll'; + webidl.argumentLengthCheck(arguments, 1, prefix); + + name = webidl.converters.USVString(name, prefix, 'name'); + + // 1. If there is no entry whose name is name in this’s entry list, + // then return the empty list. + // 2. Return the values of all entries whose name is name, in order, + // from this’s entry list. + return this[kState] + .filter((entry) => entry.name === name) + .map((entry) => entry.value) + } + + has (name) { + webidl.brandCheck(this, FormData); + + const prefix = 'FormData.has'; + webidl.argumentLengthCheck(arguments, 1, prefix); + + name = webidl.converters.USVString(name, prefix, 'name'); + + // The has(name) method steps are to return true if there is an entry + // whose name is name in this’s entry list; otherwise false. + return this[kState].findIndex((entry) => entry.name === name) !== -1 + } + + set (name, value, filename = undefined) { + webidl.brandCheck(this, FormData); + + const prefix = 'FormData.set'; + webidl.argumentLengthCheck(arguments, 2, prefix); + + if (arguments.length === 3 && !isBlobLike(value)) { + throw new TypeError( + "Failed to execute 'set' on 'FormData': parameter 2 is not of type 'Blob'" + ) + } + + // The set(name, value) and set(name, blobValue, filename) method steps + // are: + + // 1. Let value be value if given; otherwise blobValue. + + name = webidl.converters.USVString(name, prefix, 'name'); + value = isBlobLike(value) + ? webidl.converters.Blob(value, prefix, 'name', { strict: false }) + : webidl.converters.USVString(value, prefix, 'name'); + filename = arguments.length === 3 + ? webidl.converters.USVString(filename, prefix, 'name') + : undefined; + + // 2. Let entry be the result of creating an entry with name, value, and + // filename if given. + const entry = makeEntry(name, value, filename); + + // 3. If there are entries in this’s entry list whose name is name, then + // replace the first such entry with entry and remove the others. + const idx = this[kState].findIndex((entry) => entry.name === name); + if (idx !== -1) { + this[kState] = [ + ...this[kState].slice(0, idx), + entry, + ...this[kState].slice(idx + 1).filter((entry) => entry.name !== name) + ]; + } else { + // 4. Otherwise, append entry to this’s entry list. + this[kState].push(entry); + } + } + + [nodeUtil.inspect.custom] (depth, options) { + const state = this[kState].reduce((a, b) => { + if (a[b.name]) { + if (Array.isArray(a[b.name])) { + a[b.name].push(b.value); + } else { + a[b.name] = [a[b.name], b.value]; + } + } else { + a[b.name] = b.value; + } + + return a + }, { __proto__: null }); + + options.depth ??= depth; + options.colors ??= true; + + const output = nodeUtil.formatWithOptions(options, state); + + // remove [Object null prototype] + return `FormData ${output.slice(output.indexOf(']') + 2)}` + } + } + + iteratorMixin('FormData', FormData, kState, 'name', 'value'); + + Object.defineProperties(FormData.prototype, { + append: kEnumerableProperty, + delete: kEnumerableProperty, + get: kEnumerableProperty, + getAll: kEnumerableProperty, + has: kEnumerableProperty, + set: kEnumerableProperty, + [Symbol.toStringTag]: { + value: 'FormData', + configurable: true + } + }); + + /** + * @see https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#create-an-entry + * @param {string} name + * @param {string|Blob} value + * @param {?string} filename + * @returns + */ + function makeEntry (name, value, filename) { + // 1. Set name to the result of converting name into a scalar value string. + // Note: This operation was done by the webidl converter USVString. + + // 2. If value is a string, then set value to the result of converting + // value into a scalar value string. + if (typeof value === 'string') ; else { + // 3. Otherwise: + + // 1. If value is not a File object, then set value to a new File object, + // representing the same bytes, whose name attribute value is "blob" + if (!isFileLike(value)) { + value = value instanceof Blob + ? new File([value], 'blob', { type: value.type }) + : new FileLike(value, 'blob', { type: value.type }); + } + + // 2. If filename is given, then set value to a new File object, + // representing the same bytes, whose name attribute is filename. + if (filename !== undefined) { + /** @type {FilePropertyBag} */ + const options = { + type: value.type, + lastModified: value.lastModified + }; + + value = value instanceof NativeFile + ? new File([value], filename, options) + : new FileLike(value, filename, options); + } + } + + // 4. Return an entry whose name is name and whose value is value. + return { name, value } + } + + formdata = { FormData, makeEntry }; + return formdata; +} + +var formdataParser; +var hasRequiredFormdataParser; + +function requireFormdataParser () { + if (hasRequiredFormdataParser) return formdataParser; + hasRequiredFormdataParser = 1; + + const { isUSVString, bufferToLowerCasedHeaderName } = requireUtil$7(); + const { utf8DecodeBytes } = requireUtil$6(); + const { HTTP_TOKEN_CODEPOINTS, isomorphicDecode } = requireDataUrl(); + const { isFileLike } = requireFile(); + const { makeEntry } = requireFormdata(); + const assert = require$$0$4; + const { File: NodeFile } = require$$0$3; + + const File = globalThis.File ?? NodeFile; + + const formDataNameBuffer = Buffer.from('form-data; name="'); + const filenameBuffer = Buffer.from('; filename'); + const dd = Buffer.from('--'); + const ddcrlf = Buffer.from('--\r\n'); + + /** + * @param {string} chars + */ + function isAsciiString (chars) { + for (let i = 0; i < chars.length; ++i) { + if ((chars.charCodeAt(i) & -128) !== 0) { + return false + } + } + return true + } + + /** + * @see https://andreubotella.github.io/multipart-form-data/#multipart-form-data-boundary + * @param {string} boundary + */ + function validateBoundary (boundary) { + const length = boundary.length; + + // - its length is greater or equal to 27 and lesser or equal to 70, and + if (length < 27 || length > 70) { + return false + } + + // - it is composed by bytes in the ranges 0x30 to 0x39, 0x41 to 0x5A, or + // 0x61 to 0x7A, inclusive (ASCII alphanumeric), or which are 0x27 ('), + // 0x2D (-) or 0x5F (_). + for (let i = 0; i < length; ++i) { + const cp = boundary.charCodeAt(i); + + if (!( + (cp >= 0x30 && cp <= 0x39) || + (cp >= 0x41 && cp <= 0x5a) || + (cp >= 0x61 && cp <= 0x7a) || + cp === 0x27 || + cp === 0x2d || + cp === 0x5f + )) { + return false + } + } + + return true + } + + /** + * @see https://andreubotella.github.io/multipart-form-data/#multipart-form-data-parser + * @param {Buffer} input + * @param {ReturnType} mimeType + */ + function multipartFormDataParser (input, mimeType) { + // 1. Assert: mimeType’s essence is "multipart/form-data". + assert(mimeType !== 'failure' && mimeType.essence === 'multipart/form-data'); + + const boundaryString = mimeType.parameters.get('boundary'); + + // 2. If mimeType’s parameters["boundary"] does not exist, return failure. + // Otherwise, let boundary be the result of UTF-8 decoding mimeType’s + // parameters["boundary"]. + if (boundaryString === undefined) { + return 'failure' + } + + const boundary = Buffer.from(`--${boundaryString}`, 'utf8'); + + // 3. Let entry list be an empty entry list. + const entryList = []; + + // 4. Let position be a pointer to a byte in input, initially pointing at + // the first byte. + const position = { position: 0 }; + + // Note: undici addition, allow \r\n before the body. + if (input[0] === 0x0d && input[1] === 0x0a) { + position.position += 2; + } + + // 5. While true: + while (true) { + // 5.1. If position points to a sequence of bytes starting with 0x2D 0x2D + // (`--`) followed by boundary, advance position by 2 + the length of + // boundary. Otherwise, return failure. + // Note: boundary is padded with 2 dashes already, no need to add 2. + if (input.subarray(position.position, position.position + boundary.length).equals(boundary)) { + position.position += boundary.length; + } else { + return 'failure' + } + + // 5.2. If position points to the sequence of bytes 0x2D 0x2D 0x0D 0x0A + // (`--` followed by CR LF) followed by the end of input, return entry list. + // Note: a body does NOT need to end with CRLF. It can end with --. + if ( + (position.position === input.length - 2 && bufferStartsWith(input, dd, position)) || + (position.position === input.length - 4 && bufferStartsWith(input, ddcrlf, position)) + ) { + return entryList + } + + // 5.3. If position does not point to a sequence of bytes starting with 0x0D + // 0x0A (CR LF), return failure. + if (input[position.position] !== 0x0d || input[position.position + 1] !== 0x0a) { + return 'failure' + } + + // 5.4. Advance position by 2. (This skips past the newline.) + position.position += 2; + + // 5.5. Let name, filename and contentType be the result of parsing + // multipart/form-data headers on input and position, if the result + // is not failure. Otherwise, return failure. + const result = parseMultipartFormDataHeaders(input, position); + + if (result === 'failure') { + return 'failure' + } + + let { name, filename, contentType, encoding } = result; + + // 5.6. Advance position by 2. (This skips past the empty line that marks + // the end of the headers.) + position.position += 2; + + // 5.7. Let body be the empty byte sequence. + let body; + + // 5.8. Body loop: While position is not past the end of input: + // TODO: the steps here are completely wrong + { + const boundaryIndex = input.indexOf(boundary.subarray(2), position.position); + + if (boundaryIndex === -1) { + return 'failure' + } + + body = input.subarray(position.position, boundaryIndex - 4); + + position.position += body.length; + + // Note: position must be advanced by the body's length before being + // decoded, otherwise the parsing will fail. + if (encoding === 'base64') { + body = Buffer.from(body.toString(), 'base64'); + } + } + + // 5.9. If position does not point to a sequence of bytes starting with + // 0x0D 0x0A (CR LF), return failure. Otherwise, advance position by 2. + if (input[position.position] !== 0x0d || input[position.position + 1] !== 0x0a) { + return 'failure' + } else { + position.position += 2; + } + + // 5.10. If filename is not null: + let value; + + if (filename !== null) { + // 5.10.1. If contentType is null, set contentType to "text/plain". + contentType ??= 'text/plain'; + + // 5.10.2. If contentType is not an ASCII string, set contentType to the empty string. + + // Note: `buffer.isAscii` can be used at zero-cost, but converting a string to a buffer is a high overhead. + // Content-Type is a relatively small string, so it is faster to use `String#charCodeAt`. + if (!isAsciiString(contentType)) { + contentType = ''; + } + + // 5.10.3. Let value be a new File object with name filename, type contentType, and body body. + value = new File([body], filename, { type: contentType }); + } else { + // 5.11. Otherwise: + + // 5.11.1. Let value be the UTF-8 decoding without BOM of body. + value = utf8DecodeBytes(Buffer.from(body)); + } + + // 5.12. Assert: name is a scalar value string and value is either a scalar value string or a File object. + assert(isUSVString(name)); + assert((typeof value === 'string' && isUSVString(value)) || isFileLike(value)); + + // 5.13. Create an entry with name and value, and append it to entry list. + entryList.push(makeEntry(name, value, filename)); + } + } + + /** + * @see https://andreubotella.github.io/multipart-form-data/#parse-multipart-form-data-headers + * @param {Buffer} input + * @param {{ position: number }} position + */ + function parseMultipartFormDataHeaders (input, position) { + // 1. Let name, filename and contentType be null. + let name = null; + let filename = null; + let contentType = null; + let encoding = null; + + // 2. While true: + while (true) { + // 2.1. If position points to a sequence of bytes starting with 0x0D 0x0A (CR LF): + if (input[position.position] === 0x0d && input[position.position + 1] === 0x0a) { + // 2.1.1. If name is null, return failure. + if (name === null) { + return 'failure' + } + + // 2.1.2. Return name, filename and contentType. + return { name, filename, contentType, encoding } + } + + // 2.2. Let header name be the result of collecting a sequence of bytes that are + // not 0x0A (LF), 0x0D (CR) or 0x3A (:), given position. + let headerName = collectASequenceOfBytes( + (char) => char !== 0x0a && char !== 0x0d && char !== 0x3a, + input, + position + ); + + // 2.3. Remove any HTTP tab or space bytes from the start or end of header name. + headerName = removeChars(headerName, true, true, (char) => char === 0x9 || char === 0x20); + + // 2.4. If header name does not match the field-name token production, return failure. + if (!HTTP_TOKEN_CODEPOINTS.test(headerName.toString())) { + return 'failure' + } + + // 2.5. If the byte at position is not 0x3A (:), return failure. + if (input[position.position] !== 0x3a) { + return 'failure' + } + + // 2.6. Advance position by 1. + position.position++; + + // 2.7. Collect a sequence of bytes that are HTTP tab or space bytes given position. + // (Do nothing with those bytes.) + collectASequenceOfBytes( + (char) => char === 0x20 || char === 0x09, + input, + position + ); + + // 2.8. Byte-lowercase header name and switch on the result: + switch (bufferToLowerCasedHeaderName(headerName)) { + case 'content-disposition': { + // 1. Set name and filename to null. + name = filename = null; + + // 2. If position does not point to a sequence of bytes starting with + // `form-data; name="`, return failure. + if (!bufferStartsWith(input, formDataNameBuffer, position)) { + return 'failure' + } + + // 3. Advance position so it points at the byte after the next 0x22 (") + // byte (the one in the sequence of bytes matched above). + position.position += 17; + + // 4. Set name to the result of parsing a multipart/form-data name given + // input and position, if the result is not failure. Otherwise, return + // failure. + name = parseMultipartFormDataName(input, position); + + if (name === null) { + return 'failure' + } + + // 5. If position points to a sequence of bytes starting with `; filename="`: + if (bufferStartsWith(input, filenameBuffer, position)) { + // Note: undici also handles filename* + let check = position.position + filenameBuffer.length; + + if (input[check] === 0x2a) { + position.position += 1; + check += 1; + } + + if (input[check] !== 0x3d || input[check + 1] !== 0x22) { // =" + return 'failure' + } + + // 1. Advance position so it points at the byte after the next 0x22 (") byte + // (the one in the sequence of bytes matched above). + position.position += 12; + + // 2. Set filename to the result of parsing a multipart/form-data name given + // input and position, if the result is not failure. Otherwise, return failure. + filename = parseMultipartFormDataName(input, position); + + if (filename === null) { + return 'failure' + } + } + + break + } + case 'content-type': { + // 1. Let header value be the result of collecting a sequence of bytes that are + // not 0x0A (LF) or 0x0D (CR), given position. + let headerValue = collectASequenceOfBytes( + (char) => char !== 0x0a && char !== 0x0d, + input, + position + ); + + // 2. Remove any HTTP tab or space bytes from the end of header value. + headerValue = removeChars(headerValue, false, true, (char) => char === 0x9 || char === 0x20); + + // 3. Set contentType to the isomorphic decoding of header value. + contentType = isomorphicDecode(headerValue); + + break + } + case 'content-transfer-encoding': { + let headerValue = collectASequenceOfBytes( + (char) => char !== 0x0a && char !== 0x0d, + input, + position + ); + + headerValue = removeChars(headerValue, false, true, (char) => char === 0x9 || char === 0x20); + + encoding = isomorphicDecode(headerValue); + + break + } + default: { + // Collect a sequence of bytes that are not 0x0A (LF) or 0x0D (CR), given position. + // (Do nothing with those bytes.) + collectASequenceOfBytes( + (char) => char !== 0x0a && char !== 0x0d, + input, + position + ); + } + } + + // 2.9. If position does not point to a sequence of bytes starting with 0x0D 0x0A + // (CR LF), return failure. Otherwise, advance position by 2 (past the newline). + if (input[position.position] !== 0x0d && input[position.position + 1] !== 0x0a) { + return 'failure' + } else { + position.position += 2; + } + } + } + + /** + * @see https://andreubotella.github.io/multipart-form-data/#parse-a-multipart-form-data-name + * @param {Buffer} input + * @param {{ position: number }} position + */ + function parseMultipartFormDataName (input, position) { + // 1. Assert: The byte at (position - 1) is 0x22 ("). + assert(input[position.position - 1] === 0x22); + + // 2. Let name be the result of collecting a sequence of bytes that are not 0x0A (LF), 0x0D (CR) or 0x22 ("), given position. + /** @type {string | Buffer} */ + let name = collectASequenceOfBytes( + (char) => char !== 0x0a && char !== 0x0d && char !== 0x22, + input, + position + ); + + // 3. If the byte at position is not 0x22 ("), return failure. Otherwise, advance position by 1. + if (input[position.position] !== 0x22) { + return null // name could be 'failure' + } else { + position.position++; + } + + // 4. Replace any occurrence of the following subsequences in name with the given byte: + // - `%0A`: 0x0A (LF) + // - `%0D`: 0x0D (CR) + // - `%22`: 0x22 (") + name = new TextDecoder().decode(name) + .replace(/%0A/ig, '\n') + .replace(/%0D/ig, '\r') + .replace(/%22/g, '"'); + + // 5. Return the UTF-8 decoding without BOM of name. + return name + } + + /** + * @param {(char: number) => boolean} condition + * @param {Buffer} input + * @param {{ position: number }} position + */ + function collectASequenceOfBytes (condition, input, position) { + let start = position.position; + + while (start < input.length && condition(input[start])) { + ++start; + } + + return input.subarray(position.position, (position.position = start)) + } + + /** + * @param {Buffer} buf + * @param {boolean} leading + * @param {boolean} trailing + * @param {(charCode: number) => boolean} predicate + * @returns {Buffer} + */ + function removeChars (buf, leading, trailing, predicate) { + let lead = 0; + let trail = buf.length - 1; + + if (leading) { + while (lead < buf.length && predicate(buf[lead])) lead++; + } + + { + while (trail > 0 && predicate(buf[trail])) trail--; + } + + return lead === 0 && trail === buf.length - 1 ? buf : buf.subarray(lead, trail + 1) + } + + /** + * Checks if {@param buffer} starts with {@param start} + * @param {Buffer} buffer + * @param {Buffer} start + * @param {{ position: number }} position + */ + function bufferStartsWith (buffer, start, position) { + if (buffer.length < start.length) { + return false + } + + for (let i = 0; i < start.length; i++) { + if (start[i] !== buffer[position.position + i]) { + return false + } + } + + return true + } + + formdataParser = { + multipartFormDataParser, + validateBoundary + }; + return formdataParser; +} + +var body; +var hasRequiredBody; + +function requireBody () { + if (hasRequiredBody) return body; + hasRequiredBody = 1; + + const util = requireUtil$7(); + const { + ReadableStreamFrom, + isBlobLike, + isReadableStreamLike, + readableStreamClose, + createDeferredPromise, + fullyReadBody, + extractMimeType, + utf8DecodeBytes + } = requireUtil$6(); + const { FormData } = requireFormdata(); + const { kState } = requireSymbols$3(); + const { webidl } = requireWebidl(); + const { Blob } = require$$0$3; + const assert = require$$0$4; + const { isErrored } = requireUtil$7(); + const { isArrayBuffer } = require$$8$1; + const { serializeAMimeType } = requireDataUrl(); + const { multipartFormDataParser } = requireFormdataParser(); + + const textEncoder = new TextEncoder(); + + // https://fetch.spec.whatwg.org/#concept-bodyinit-extract + function extractBody (object, keepalive = false) { + // 1. Let stream be null. + let stream = null; + + // 2. If object is a ReadableStream object, then set stream to object. + if (object instanceof ReadableStream) { + stream = object; + } else if (isBlobLike(object)) { + // 3. Otherwise, if object is a Blob object, set stream to the + // result of running object’s get stream. + stream = object.stream(); + } else { + // 4. Otherwise, set stream to a new ReadableStream object, and set + // up stream with byte reading support. + stream = new ReadableStream({ + async pull (controller) { + const buffer = typeof source === 'string' ? textEncoder.encode(source) : source; + + if (buffer.byteLength) { + controller.enqueue(buffer); + } + + queueMicrotask(() => readableStreamClose(controller)); + }, + start () {}, + type: 'bytes' + }); + } + + // 5. Assert: stream is a ReadableStream object. + assert(isReadableStreamLike(stream)); + + // 6. Let action be null. + let action = null; + + // 7. Let source be null. + let source = null; + + // 8. Let length be null. + let length = null; + + // 9. Let type be null. + let type = null; + + // 10. Switch on object: + if (typeof object === 'string') { + // Set source to the UTF-8 encoding of object. + // Note: setting source to a Uint8Array here breaks some mocking assumptions. + source = object; + + // Set type to `text/plain;charset=UTF-8`. + type = 'text/plain;charset=UTF-8'; + } else if (object instanceof URLSearchParams) { + // URLSearchParams + + // spec says to run application/x-www-form-urlencoded on body.list + // this is implemented in Node.js as apart of an URLSearchParams instance toString method + // See: https://github.com/nodejs/node/blob/e46c680bf2b211bbd52cf959ca17ee98c7f657f5/lib/internal/url.js#L490 + // and https://github.com/nodejs/node/blob/e46c680bf2b211bbd52cf959ca17ee98c7f657f5/lib/internal/url.js#L1100 + + // Set source to the result of running the application/x-www-form-urlencoded serializer with object’s list. + source = object.toString(); + + // Set type to `application/x-www-form-urlencoded;charset=UTF-8`. + type = 'application/x-www-form-urlencoded;charset=UTF-8'; + } else if (isArrayBuffer(object)) { + // BufferSource/ArrayBuffer + + // Set source to a copy of the bytes held by object. + source = new Uint8Array(object.slice()); + } else if (ArrayBuffer.isView(object)) { + // BufferSource/ArrayBufferView + + // Set source to a copy of the bytes held by object. + source = new Uint8Array(object.buffer.slice(object.byteOffset, object.byteOffset + object.byteLength)); + } else if (util.isFormDataLike(object)) { + const boundary = `----formdata-undici-0${`${Math.floor(Math.random() * 1e11)}`.padStart(11, '0')}`; + const prefix = `--${boundary}\r\nContent-Disposition: form-data`; + + /*! formdata-polyfill. MIT License. Jimmy Wärting */ + const escape = (str) => + str.replace(/\n/g, '%0A').replace(/\r/g, '%0D').replace(/"/g, '%22'); + const normalizeLinefeeds = (value) => value.replace(/\r?\n|\r/g, '\r\n'); + + // Set action to this step: run the multipart/form-data + // encoding algorithm, with object’s entry list and UTF-8. + // - This ensures that the body is immutable and can't be changed afterwords + // - That the content-length is calculated in advance. + // - And that all parts are pre-encoded and ready to be sent. + + const blobParts = []; + const rn = new Uint8Array([13, 10]); // '\r\n' + length = 0; + let hasUnknownSizeValue = false; + + for (const [name, value] of object) { + if (typeof value === 'string') { + const chunk = textEncoder.encode(prefix + + `; name="${escape(normalizeLinefeeds(name))}"` + + `\r\n\r\n${normalizeLinefeeds(value)}\r\n`); + blobParts.push(chunk); + length += chunk.byteLength; + } else { + const chunk = textEncoder.encode(`${prefix}; name="${escape(normalizeLinefeeds(name))}"` + + (value.name ? `; filename="${escape(value.name)}"` : '') + '\r\n' + + `Content-Type: ${ + value.type || 'application/octet-stream' + }\r\n\r\n`); + blobParts.push(chunk, value, rn); + if (typeof value.size === 'number') { + length += chunk.byteLength + value.size + rn.byteLength; + } else { + hasUnknownSizeValue = true; + } + } + } + + const chunk = textEncoder.encode(`--${boundary}--`); + blobParts.push(chunk); + length += chunk.byteLength; + if (hasUnknownSizeValue) { + length = null; + } + + // Set source to object. + source = object; + + action = async function * () { + for (const part of blobParts) { + if (part.stream) { + yield * part.stream(); + } else { + yield part; + } + } + }; + + // Set type to `multipart/form-data; boundary=`, + // followed by the multipart/form-data boundary string generated + // by the multipart/form-data encoding algorithm. + type = `multipart/form-data; boundary=${boundary}`; + } else if (isBlobLike(object)) { + // Blob + + // Set source to object. + source = object; + + // Set length to object’s size. + length = object.size; + + // If object’s type attribute is not the empty byte sequence, set + // type to its value. + if (object.type) { + type = object.type; + } + } else if (typeof object[Symbol.asyncIterator] === 'function') { + // If keepalive is true, then throw a TypeError. + if (keepalive) { + throw new TypeError('keepalive') + } + + // If object is disturbed or locked, then throw a TypeError. + if (util.isDisturbed(object) || object.locked) { + throw new TypeError( + 'Response body object should not be disturbed or locked' + ) + } + + stream = + object instanceof ReadableStream ? object : ReadableStreamFrom(object); + } + + // 11. If source is a byte sequence, then set action to a + // step that returns source and length to source’s length. + if (typeof source === 'string' || util.isBuffer(source)) { + length = Buffer.byteLength(source); + } + + // 12. If action is non-null, then run these steps in in parallel: + if (action != null) { + // Run action. + let iterator; + stream = new ReadableStream({ + async start () { + iterator = action(object)[Symbol.asyncIterator](); + }, + async pull (controller) { + const { value, done } = await iterator.next(); + if (done) { + // When running action is done, close stream. + queueMicrotask(() => { + controller.close(); + controller.byobRequest?.respond(0); + }); + } else { + // Whenever one or more bytes are available and stream is not errored, + // enqueue a Uint8Array wrapping an ArrayBuffer containing the available + // bytes into stream. + if (!isErrored(stream)) { + const buffer = new Uint8Array(value); + if (buffer.byteLength) { + controller.enqueue(buffer); + } + } + } + return controller.desiredSize > 0 + }, + async cancel (reason) { + await iterator.return(); + }, + type: 'bytes' + }); + } + + // 13. Let body be a body whose stream is stream, source is source, + // and length is length. + const body = { stream, source, length }; + + // 14. Return (body, type). + return [body, type] + } + + // https://fetch.spec.whatwg.org/#bodyinit-safely-extract + function safelyExtractBody (object, keepalive = false) { + // To safely extract a body and a `Content-Type` value from + // a byte sequence or BodyInit object object, run these steps: + + // 1. If object is a ReadableStream object, then: + if (object instanceof ReadableStream) { + // Assert: object is neither disturbed nor locked. + // istanbul ignore next + assert(!util.isDisturbed(object), 'The body has already been consumed.'); + // istanbul ignore next + assert(!object.locked, 'The stream is locked.'); + } + + // 2. Return the results of extracting object. + return extractBody(object, keepalive) + } + + function cloneBody (body) { + // To clone a body body, run these steps: + + // https://fetch.spec.whatwg.org/#concept-body-clone + + // 1. Let « out1, out2 » be the result of teeing body’s stream. + const [out1, out2] = body.stream.tee(); + + // 2. Set body’s stream to out1. + body.stream = out1; + + // 3. Return a body whose stream is out2 and other members are copied from body. + return { + stream: out2, + length: body.length, + source: body.source + } + } + + function throwIfAborted (state) { + if (state.aborted) { + throw new DOMException('The operation was aborted.', 'AbortError') + } + } + + function bodyMixinMethods (instance) { + const methods = { + blob () { + // The blob() method steps are to return the result of + // running consume body with this and the following step + // given a byte sequence bytes: return a Blob whose + // contents are bytes and whose type attribute is this’s + // MIME type. + return consumeBody(this, (bytes) => { + let mimeType = bodyMimeType(this); + + if (mimeType === null) { + mimeType = ''; + } else if (mimeType) { + mimeType = serializeAMimeType(mimeType); + } + + // Return a Blob whose contents are bytes and type attribute + // is mimeType. + return new Blob([bytes], { type: mimeType }) + }, instance, false) + }, + + arrayBuffer () { + // The arrayBuffer() method steps are to return the result + // of running consume body with this and the following step + // given a byte sequence bytes: return a new ArrayBuffer + // whose contents are bytes. + return consumeBody(this, (bytes) => { + // Note: arrayBuffer already cloned. + return bytes.buffer + }, instance, true) + }, + + text () { + // The text() method steps are to return the result of running + // consume body with this and UTF-8 decode. + return consumeBody(this, utf8DecodeBytes, instance, false) + }, + + json () { + // The json() method steps are to return the result of running + // consume body with this and parse JSON from bytes. + return consumeBody(this, parseJSONFromBytes, instance, false) + }, + + formData () { + // The formData() method steps are to return the result of running + // consume body with this and the following step given a byte sequence bytes: + return consumeBody(this, (value) => { + // 1. Let mimeType be the result of get the MIME type with this. + const mimeType = bodyMimeType(this); + + // 2. If mimeType is non-null, then switch on mimeType’s essence and run + // the corresponding steps: + if (mimeType !== null) { + switch (mimeType.essence) { + case 'multipart/form-data': { + // 1. ... [long step] + const parsed = multipartFormDataParser(value, mimeType); + + // 2. If that fails for some reason, then throw a TypeError. + if (parsed === 'failure') { + throw new TypeError('Failed to parse body as FormData.') + } + + // 3. Return a new FormData object, appending each entry, + // resulting from the parsing operation, to its entry list. + const fd = new FormData(); + fd[kState] = parsed; + + return fd + } + case 'application/x-www-form-urlencoded': { + // 1. Let entries be the result of parsing bytes. + const entries = new URLSearchParams(value.toString()); + + // 2. If entries is failure, then throw a TypeError. + + // 3. Return a new FormData object whose entry list is entries. + const fd = new FormData(); + + for (const [name, value] of entries) { + fd.append(name, value); + } + + return fd + } + } + } + + // 3. Throw a TypeError. + throw new TypeError( + 'Content-Type was not one of "multipart/form-data" or "application/x-www-form-urlencoded".' + ) + }, instance, false) + }, + + bytes () { + // The bytes() method steps are to return the result of running consume body + // with this and the following step given a byte sequence bytes: return the + // result of creating a Uint8Array from bytes in this’s relevant realm. + return consumeBody(this, (bytes) => { + return new Uint8Array(bytes.buffer, 0, bytes.byteLength) + }, instance, true) + } + }; + + return methods + } + + function mixinBody (prototype) { + Object.assign(prototype.prototype, bodyMixinMethods(prototype)); + } + + /** + * @see https://fetch.spec.whatwg.org/#concept-body-consume-body + * @param {Response|Request} object + * @param {(value: unknown) => unknown} convertBytesToJSValue + * @param {Response|Request} instance + * @param {boolean} [shouldClone] + */ + async function consumeBody (object, convertBytesToJSValue, instance, shouldClone) { + webidl.brandCheck(object, instance); + + // 1. If object is unusable, then return a promise rejected + // with a TypeError. + if (bodyUnusable(object[kState].body)) { + throw new TypeError('Body is unusable: Body has already been read') + } + + throwIfAborted(object[kState]); + + // 2. Let promise be a new promise. + const promise = createDeferredPromise(); + + // 3. Let errorSteps given error be to reject promise with error. + const errorSteps = (error) => promise.reject(error); + + // 4. Let successSteps given a byte sequence data be to resolve + // promise with the result of running convertBytesToJSValue + // with data. If that threw an exception, then run errorSteps + // with that exception. + const successSteps = (data) => { + try { + promise.resolve(convertBytesToJSValue(data)); + } catch (e) { + errorSteps(e); + } + }; + + // 5. If object’s body is null, then run successSteps with an + // empty byte sequence. + if (object[kState].body == null) { + successSteps(Buffer.allocUnsafe(0)); + return promise.promise + } + + // 6. Otherwise, fully read object’s body given successSteps, + // errorSteps, and object’s relevant global object. + await fullyReadBody(object[kState].body, successSteps, errorSteps, shouldClone); + + // 7. Return promise. + return promise.promise + } + + // https://fetch.spec.whatwg.org/#body-unusable + function bodyUnusable (body) { + // An object including the Body interface mixin is + // said to be unusable if its body is non-null and + // its body’s stream is disturbed or locked. + return body != null && (body.stream.locked || util.isDisturbed(body.stream)) + } + + /** + * @see https://infra.spec.whatwg.org/#parse-json-bytes-to-a-javascript-value + * @param {Uint8Array} bytes + */ + function parseJSONFromBytes (bytes) { + return JSON.parse(utf8DecodeBytes(bytes)) + } + + /** + * @see https://fetch.spec.whatwg.org/#concept-body-mime-type + * @param {import('./response').Response|import('./request').Request} requestOrResponse + */ + function bodyMimeType (requestOrResponse) { + // 1. Let headers be null. + // 2. If requestOrResponse is a Request object, then set headers to requestOrResponse’s request’s header list. + // 3. Otherwise, set headers to requestOrResponse’s response’s header list. + /** @type {import('./headers').HeadersList} */ + const headers = requestOrResponse[kState].headersList; + + // 4. Let mimeType be the result of extracting a MIME type from headers. + const mimeType = extractMimeType(headers); + + // 5. If mimeType is failure, then return null. + if (mimeType === 'failure') { + return null + } + + // 6. Return mimeType. + return mimeType + } + + body = { + extractBody, + safelyExtractBody, + cloneBody, + mixinBody + }; + return body; +} + +var clientH1; +var hasRequiredClientH1; + +function requireClientH1 () { + if (hasRequiredClientH1) return clientH1; + hasRequiredClientH1 = 1; + + /* global WebAssembly */ + + const assert = require$$0$4; + const util = requireUtil$7(); + const { channels } = requireDiagnostics(); + const timers = requireTimers(); + const { + RequestContentLengthMismatchError, + ResponseContentLengthMismatchError, + RequestAbortedError, + HeadersTimeoutError, + HeadersOverflowError, + SocketError, + InformationalError, + BodyTimeoutError, + HTTPParserError, + ResponseExceededMaxSizeError + } = requireErrors(); + const { + kUrl, + kReset, + kClient, + kParser, + kBlocking, + kRunning, + kPending, + kSize, + kWriting, + kQueue, + kNoRef, + kKeepAliveDefaultTimeout, + kHostHeader, + kPendingIdx, + kRunningIdx, + kError, + kPipelining, + kSocket, + kKeepAliveTimeoutValue, + kMaxHeadersSize, + kKeepAliveMaxTimeout, + kKeepAliveTimeoutThreshold, + kHeadersTimeout, + kBodyTimeout, + kStrictContentLength, + kMaxRequests, + kCounter, + kMaxResponseSize, + kOnError, + kResume, + kHTTPContext + } = requireSymbols$4(); + + const constants = requireConstants$3(); + const EMPTY_BUF = Buffer.alloc(0); + const FastBuffer = Buffer[Symbol.species]; + const addListener = util.addListener; + const removeAllListeners = util.removeAllListeners; + + let extractBody; + + async function lazyllhttp () { + const llhttpWasmData = process.env.JEST_WORKER_ID ? requireLlhttpWasm() : undefined; + + let mod; + try { + mod = await WebAssembly.compile(requireLlhttp_simdWasm()); + } catch (e) { + /* istanbul ignore next */ + + // We could check if the error was caused by the simd option not + // being enabled, but the occurring of this other error + // * https://github.com/emscripten-core/emscripten/issues/11495 + // got me to remove that check to avoid breaking Node 12. + mod = await WebAssembly.compile(llhttpWasmData || requireLlhttpWasm()); + } + + return await WebAssembly.instantiate(mod, { + env: { + /* eslint-disable camelcase */ + + wasm_on_url: (p, at, len) => { + /* istanbul ignore next */ + return 0 + }, + wasm_on_status: (p, at, len) => { + assert.strictEqual(currentParser.ptr, p); + const start = at - currentBufferPtr + currentBufferRef.byteOffset; + return currentParser.onStatus(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 + }, + wasm_on_message_begin: (p) => { + assert.strictEqual(currentParser.ptr, p); + return currentParser.onMessageBegin() || 0 + }, + wasm_on_header_field: (p, at, len) => { + assert.strictEqual(currentParser.ptr, p); + const start = at - currentBufferPtr + currentBufferRef.byteOffset; + return currentParser.onHeaderField(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 + }, + wasm_on_header_value: (p, at, len) => { + assert.strictEqual(currentParser.ptr, p); + const start = at - currentBufferPtr + currentBufferRef.byteOffset; + return currentParser.onHeaderValue(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 + }, + wasm_on_headers_complete: (p, statusCode, upgrade, shouldKeepAlive) => { + assert.strictEqual(currentParser.ptr, p); + return currentParser.onHeadersComplete(statusCode, Boolean(upgrade), Boolean(shouldKeepAlive)) || 0 + }, + wasm_on_body: (p, at, len) => { + assert.strictEqual(currentParser.ptr, p); + const start = at - currentBufferPtr + currentBufferRef.byteOffset; + return currentParser.onBody(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 + }, + wasm_on_message_complete: (p) => { + assert.strictEqual(currentParser.ptr, p); + return currentParser.onMessageComplete() || 0 + } + + /* eslint-enable camelcase */ + } + }) + } + + let llhttpInstance = null; + let llhttpPromise = lazyllhttp(); + llhttpPromise.catch(); + + let currentParser = null; + let currentBufferRef = null; + let currentBufferSize = 0; + let currentBufferPtr = null; + + const TIMEOUT_HEADERS = 1; + const TIMEOUT_BODY = 2; + const TIMEOUT_IDLE = 3; + + class Parser { + constructor (client, socket, { exports }) { + assert(Number.isFinite(client[kMaxHeadersSize]) && client[kMaxHeadersSize] > 0); + + this.llhttp = exports; + this.ptr = this.llhttp.llhttp_alloc(constants.TYPE.RESPONSE); + this.client = client; + this.socket = socket; + this.timeout = null; + this.timeoutValue = null; + this.timeoutType = null; + this.statusCode = null; + this.statusText = ''; + this.upgrade = false; + this.headers = []; + this.headersSize = 0; + this.headersMaxSize = client[kMaxHeadersSize]; + this.shouldKeepAlive = false; + this.paused = false; + this.resume = this.resume.bind(this); + + this.bytesRead = 0; + + this.keepAlive = ''; + this.contentLength = ''; + this.connection = ''; + this.maxResponseSize = client[kMaxResponseSize]; + } + + setTimeout (value, type) { + this.timeoutType = type; + if (value !== this.timeoutValue) { + timers.clearTimeout(this.timeout); + if (value) { + this.timeout = timers.setTimeout(onParserTimeout, value, this); + // istanbul ignore else: only for jest + if (this.timeout.unref) { + this.timeout.unref(); + } + } else { + this.timeout = null; + } + this.timeoutValue = value; + } else if (this.timeout) { + // istanbul ignore else: only for jest + if (this.timeout.refresh) { + this.timeout.refresh(); + } + } + } + + resume () { + if (this.socket.destroyed || !this.paused) { + return + } + + assert(this.ptr != null); + assert(currentParser == null); + + this.llhttp.llhttp_resume(this.ptr); + + assert(this.timeoutType === TIMEOUT_BODY); + if (this.timeout) { + // istanbul ignore else: only for jest + if (this.timeout.refresh) { + this.timeout.refresh(); + } + } + + this.paused = false; + this.execute(this.socket.read() || EMPTY_BUF); // Flush parser. + this.readMore(); + } + + readMore () { + while (!this.paused && this.ptr) { + const chunk = this.socket.read(); + if (chunk === null) { + break + } + this.execute(chunk); + } + } + + execute (data) { + assert(this.ptr != null); + assert(currentParser == null); + assert(!this.paused); + + const { socket, llhttp } = this; + + if (data.length > currentBufferSize) { + if (currentBufferPtr) { + llhttp.free(currentBufferPtr); + } + currentBufferSize = Math.ceil(data.length / 4096) * 4096; + currentBufferPtr = llhttp.malloc(currentBufferSize); + } + + new Uint8Array(llhttp.memory.buffer, currentBufferPtr, currentBufferSize).set(data); + + // Call `execute` on the wasm parser. + // We pass the `llhttp_parser` pointer address, the pointer address of buffer view data, + // and finally the length of bytes to parse. + // The return value is an error code or `constants.ERROR.OK`. + try { + let ret; + + try { + currentBufferRef = data; + currentParser = this; + ret = llhttp.llhttp_execute(this.ptr, currentBufferPtr, data.length); + /* eslint-disable-next-line no-useless-catch */ + } catch (err) { + /* istanbul ignore next: difficult to make a test case for */ + throw err + } finally { + currentParser = null; + currentBufferRef = null; + } + + const offset = llhttp.llhttp_get_error_pos(this.ptr) - currentBufferPtr; + + if (ret === constants.ERROR.PAUSED_UPGRADE) { + this.onUpgrade(data.slice(offset)); + } else if (ret === constants.ERROR.PAUSED) { + this.paused = true; + socket.unshift(data.slice(offset)); + } else if (ret !== constants.ERROR.OK) { + const ptr = llhttp.llhttp_get_error_reason(this.ptr); + let message = ''; + /* istanbul ignore else: difficult to make a test case for */ + if (ptr) { + const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0); + message = + 'Response does not match the HTTP/1.1 protocol (' + + Buffer.from(llhttp.memory.buffer, ptr, len).toString() + + ')'; + } + throw new HTTPParserError(message, constants.ERROR[ret], data.slice(offset)) + } + } catch (err) { + util.destroy(socket, err); + } + } + + destroy () { + assert(this.ptr != null); + assert(currentParser == null); + + this.llhttp.llhttp_free(this.ptr); + this.ptr = null; + + timers.clearTimeout(this.timeout); + this.timeout = null; + this.timeoutValue = null; + this.timeoutType = null; + + this.paused = false; + } + + onStatus (buf) { + this.statusText = buf.toString(); + } + + onMessageBegin () { + const { socket, client } = this; + + /* istanbul ignore next: difficult to make a test case for */ + if (socket.destroyed) { + return -1 + } + + const request = client[kQueue][client[kRunningIdx]]; + if (!request) { + return -1 + } + request.onResponseStarted(); + } + + onHeaderField (buf) { + const len = this.headers.length; + + if ((len & 1) === 0) { + this.headers.push(buf); + } else { + this.headers[len - 1] = Buffer.concat([this.headers[len - 1], buf]); + } + + this.trackHeader(buf.length); + } + + onHeaderValue (buf) { + let len = this.headers.length; + + if ((len & 1) === 1) { + this.headers.push(buf); + len += 1; + } else { + this.headers[len - 1] = Buffer.concat([this.headers[len - 1], buf]); + } + + const key = this.headers[len - 2]; + if (key.length === 10) { + const headerName = util.bufferToLowerCasedHeaderName(key); + if (headerName === 'keep-alive') { + this.keepAlive += buf.toString(); + } else if (headerName === 'connection') { + this.connection += buf.toString(); + } + } else if (key.length === 14 && util.bufferToLowerCasedHeaderName(key) === 'content-length') { + this.contentLength += buf.toString(); + } + + this.trackHeader(buf.length); + } + + trackHeader (len) { + this.headersSize += len; + if (this.headersSize >= this.headersMaxSize) { + util.destroy(this.socket, new HeadersOverflowError()); + } + } + + onUpgrade (head) { + const { upgrade, client, socket, headers, statusCode } = this; + + assert(upgrade); + + const request = client[kQueue][client[kRunningIdx]]; + assert(request); + + assert(!socket.destroyed); + assert(socket === client[kSocket]); + assert(!this.paused); + assert(request.upgrade || request.method === 'CONNECT'); + + this.statusCode = null; + this.statusText = ''; + this.shouldKeepAlive = null; + + assert(this.headers.length % 2 === 0); + this.headers = []; + this.headersSize = 0; + + socket.unshift(head); + + socket[kParser].destroy(); + socket[kParser] = null; + + socket[kClient] = null; + socket[kError] = null; + + removeAllListeners(socket); + + client[kSocket] = null; + client[kHTTPContext] = null; // TODO (fix): This is hacky... + client[kQueue][client[kRunningIdx]++] = null; + client.emit('disconnect', client[kUrl], [client], new InformationalError('upgrade')); + + try { + request.onUpgrade(statusCode, headers, socket); + } catch (err) { + util.destroy(socket, err); + } + + client[kResume](); + } + + onHeadersComplete (statusCode, upgrade, shouldKeepAlive) { + const { client, socket, headers, statusText } = this; + + /* istanbul ignore next: difficult to make a test case for */ + if (socket.destroyed) { + return -1 + } + + const request = client[kQueue][client[kRunningIdx]]; + + /* istanbul ignore next: difficult to make a test case for */ + if (!request) { + return -1 + } + + assert(!this.upgrade); + assert(this.statusCode < 200); + + if (statusCode === 100) { + util.destroy(socket, new SocketError('bad response', util.getSocketInfo(socket))); + return -1 + } + + /* this can only happen if server is misbehaving */ + if (upgrade && !request.upgrade) { + util.destroy(socket, new SocketError('bad upgrade', util.getSocketInfo(socket))); + return -1 + } + + assert.strictEqual(this.timeoutType, TIMEOUT_HEADERS); + + this.statusCode = statusCode; + this.shouldKeepAlive = ( + shouldKeepAlive || + // Override llhttp value which does not allow keepAlive for HEAD. + (request.method === 'HEAD' && !socket[kReset] && this.connection.toLowerCase() === 'keep-alive') + ); + + if (this.statusCode >= 200) { + const bodyTimeout = request.bodyTimeout != null + ? request.bodyTimeout + : client[kBodyTimeout]; + this.setTimeout(bodyTimeout, TIMEOUT_BODY); + } else if (this.timeout) { + // istanbul ignore else: only for jest + if (this.timeout.refresh) { + this.timeout.refresh(); + } + } + + if (request.method === 'CONNECT') { + assert(client[kRunning] === 1); + this.upgrade = true; + return 2 + } + + if (upgrade) { + assert(client[kRunning] === 1); + this.upgrade = true; + return 2 + } + + assert(this.headers.length % 2 === 0); + this.headers = []; + this.headersSize = 0; + + if (this.shouldKeepAlive && client[kPipelining]) { + const keepAliveTimeout = this.keepAlive ? util.parseKeepAliveTimeout(this.keepAlive) : null; + + if (keepAliveTimeout != null) { + const timeout = Math.min( + keepAliveTimeout - client[kKeepAliveTimeoutThreshold], + client[kKeepAliveMaxTimeout] + ); + if (timeout <= 0) { + socket[kReset] = true; + } else { + client[kKeepAliveTimeoutValue] = timeout; + } + } else { + client[kKeepAliveTimeoutValue] = client[kKeepAliveDefaultTimeout]; + } + } else { + // Stop more requests from being dispatched. + socket[kReset] = true; + } + + const pause = request.onHeaders(statusCode, headers, this.resume, statusText) === false; + + if (request.aborted) { + return -1 + } + + if (request.method === 'HEAD') { + return 1 + } + + if (statusCode < 200) { + return 1 + } + + if (socket[kBlocking]) { + socket[kBlocking] = false; + client[kResume](); + } + + return pause ? constants.ERROR.PAUSED : 0 + } + + onBody (buf) { + const { client, socket, statusCode, maxResponseSize } = this; + + if (socket.destroyed) { + return -1 + } + + const request = client[kQueue][client[kRunningIdx]]; + assert(request); + + assert.strictEqual(this.timeoutType, TIMEOUT_BODY); + if (this.timeout) { + // istanbul ignore else: only for jest + if (this.timeout.refresh) { + this.timeout.refresh(); + } + } + + assert(statusCode >= 200); + + if (maxResponseSize > -1 && this.bytesRead + buf.length > maxResponseSize) { + util.destroy(socket, new ResponseExceededMaxSizeError()); + return -1 + } + + this.bytesRead += buf.length; + + if (request.onData(buf) === false) { + return constants.ERROR.PAUSED + } + } + + onMessageComplete () { + const { client, socket, statusCode, upgrade, headers, contentLength, bytesRead, shouldKeepAlive } = this; + + if (socket.destroyed && (!statusCode || shouldKeepAlive)) { + return -1 + } + + if (upgrade) { + return + } + + const request = client[kQueue][client[kRunningIdx]]; + assert(request); + + assert(statusCode >= 100); + + this.statusCode = null; + this.statusText = ''; + this.bytesRead = 0; + this.contentLength = ''; + this.keepAlive = ''; + this.connection = ''; + + assert(this.headers.length % 2 === 0); + this.headers = []; + this.headersSize = 0; + + if (statusCode < 200) { + return + } + + /* istanbul ignore next: should be handled by llhttp? */ + if (request.method !== 'HEAD' && contentLength && bytesRead !== parseInt(contentLength, 10)) { + util.destroy(socket, new ResponseContentLengthMismatchError()); + return -1 + } + + request.onComplete(headers); + + client[kQueue][client[kRunningIdx]++] = null; + + if (socket[kWriting]) { + assert.strictEqual(client[kRunning], 0); + // Response completed before request. + util.destroy(socket, new InformationalError('reset')); + return constants.ERROR.PAUSED + } else if (!shouldKeepAlive) { + util.destroy(socket, new InformationalError('reset')); + return constants.ERROR.PAUSED + } else if (socket[kReset] && client[kRunning] === 0) { + // Destroy socket once all requests have completed. + // The request at the tail of the pipeline is the one + // that requested reset and no further requests should + // have been queued since then. + util.destroy(socket, new InformationalError('reset')); + return constants.ERROR.PAUSED + } else if (client[kPipelining] == null || client[kPipelining] === 1) { + // We must wait a full event loop cycle to reuse this socket to make sure + // that non-spec compliant servers are not closing the connection even if they + // said they won't. + setImmediate(() => client[kResume]()); + } else { + client[kResume](); + } + } + } + + function onParserTimeout (parser) { + const { socket, timeoutType, client } = parser; + + /* istanbul ignore else */ + if (timeoutType === TIMEOUT_HEADERS) { + if (!socket[kWriting] || socket.writableNeedDrain || client[kRunning] > 1) { + assert(!parser.paused, 'cannot be paused while waiting for headers'); + util.destroy(socket, new HeadersTimeoutError()); + } + } else if (timeoutType === TIMEOUT_BODY) { + if (!parser.paused) { + util.destroy(socket, new BodyTimeoutError()); + } + } else if (timeoutType === TIMEOUT_IDLE) { + assert(client[kRunning] === 0 && client[kKeepAliveTimeoutValue]); + util.destroy(socket, new InformationalError('socket idle timeout')); + } + } + + async function connectH1 (client, socket) { + client[kSocket] = socket; + + if (!llhttpInstance) { + llhttpInstance = await llhttpPromise; + llhttpPromise = null; + } + + socket[kNoRef] = false; + socket[kWriting] = false; + socket[kReset] = false; + socket[kBlocking] = false; + socket[kParser] = new Parser(client, socket, llhttpInstance); + + addListener(socket, 'error', function (err) { + const parser = this[kParser]; + + assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID'); + + // On Mac OS, we get an ECONNRESET even if there is a full body to be forwarded + // to the user. + if (err.code === 'ECONNRESET' && parser.statusCode && !parser.shouldKeepAlive) { + // We treat all incoming data so for as a valid response. + parser.onMessageComplete(); + return + } + + this[kError] = err; + + this[kClient][kOnError](err); + }); + addListener(socket, 'readable', function () { + const parser = this[kParser]; + + if (parser) { + parser.readMore(); + } + }); + addListener(socket, 'end', function () { + const parser = this[kParser]; + + if (parser.statusCode && !parser.shouldKeepAlive) { + // We treat all incoming data so far as a valid response. + parser.onMessageComplete(); + return + } + + util.destroy(this, new SocketError('other side closed', util.getSocketInfo(this))); + }); + addListener(socket, 'close', function () { + const client = this[kClient]; + const parser = this[kParser]; + + if (parser) { + if (!this[kError] && parser.statusCode && !parser.shouldKeepAlive) { + // We treat all incoming data so far as a valid response. + parser.onMessageComplete(); + } + + this[kParser].destroy(); + this[kParser] = null; + } + + const err = this[kError] || new SocketError('closed', util.getSocketInfo(this)); + + client[kSocket] = null; + client[kHTTPContext] = null; // TODO (fix): This is hacky... + + if (client.destroyed) { + assert(client[kPending] === 0); + + // Fail entire queue. + const requests = client[kQueue].splice(client[kRunningIdx]); + for (let i = 0; i < requests.length; i++) { + const request = requests[i]; + util.errorRequest(client, request, err); + } + } else if (client[kRunning] > 0 && err.code !== 'UND_ERR_INFO') { + // Fail head of pipeline. + const request = client[kQueue][client[kRunningIdx]]; + client[kQueue][client[kRunningIdx]++] = null; + + util.errorRequest(client, request, err); + } + + client[kPendingIdx] = client[kRunningIdx]; + + assert(client[kRunning] === 0); + + client.emit('disconnect', client[kUrl], [client], err); + + client[kResume](); + }); + + let closed = false; + socket.on('close', () => { + closed = true; + }); + + return { + version: 'h1', + defaultPipelining: 1, + write (...args) { + return writeH1(client, ...args) + }, + resume () { + resumeH1(client); + }, + destroy (err, callback) { + if (closed) { + queueMicrotask(callback); + } else { + socket.destroy(err).on('close', callback); + } + }, + get destroyed () { + return socket.destroyed + }, + busy (request) { + if (socket[kWriting] || socket[kReset] || socket[kBlocking]) { + return true + } + + if (request) { + if (client[kRunning] > 0 && !request.idempotent) { + // Non-idempotent request cannot be retried. + // Ensure that no other requests are inflight and + // could cause failure. + return true + } + + if (client[kRunning] > 0 && (request.upgrade || request.method === 'CONNECT')) { + // Don't dispatch an upgrade until all preceding requests have completed. + // A misbehaving server might upgrade the connection before all pipelined + // request has completed. + return true + } + + if (client[kRunning] > 0 && util.bodyLength(request.body) !== 0 && + (util.isStream(request.body) || util.isAsyncIterable(request.body) || util.isFormDataLike(request.body))) { + // Request with stream or iterator body can error while other requests + // are inflight and indirectly error those as well. + // Ensure this doesn't happen by waiting for inflight + // to complete before dispatching. + + // Request with stream or iterator body cannot be retried. + // Ensure that no other requests are inflight and + // could cause failure. + return true + } + } + + return false + } + } + } + + function resumeH1 (client) { + const socket = client[kSocket]; + + if (socket && !socket.destroyed) { + if (client[kSize] === 0) { + if (!socket[kNoRef] && socket.unref) { + socket.unref(); + socket[kNoRef] = true; + } + } else if (socket[kNoRef] && socket.ref) { + socket.ref(); + socket[kNoRef] = false; + } + + if (client[kSize] === 0) { + if (socket[kParser].timeoutType !== TIMEOUT_IDLE) { + socket[kParser].setTimeout(client[kKeepAliveTimeoutValue], TIMEOUT_IDLE); + } + } else if (client[kRunning] > 0 && socket[kParser].statusCode < 200) { + if (socket[kParser].timeoutType !== TIMEOUT_HEADERS) { + const request = client[kQueue][client[kRunningIdx]]; + const headersTimeout = request.headersTimeout != null + ? request.headersTimeout + : client[kHeadersTimeout]; + socket[kParser].setTimeout(headersTimeout, TIMEOUT_HEADERS); + } + } + } + } + + // https://www.rfc-editor.org/rfc/rfc7230#section-3.3.2 + function shouldSendContentLength (method) { + return method !== 'GET' && method !== 'HEAD' && method !== 'OPTIONS' && method !== 'TRACE' && method !== 'CONNECT' + } + + function writeH1 (client, request) { + const { method, path, host, upgrade, blocking, reset } = request; + + let { body, headers, contentLength } = request; + + // https://tools.ietf.org/html/rfc7231#section-4.3.1 + // https://tools.ietf.org/html/rfc7231#section-4.3.2 + // https://tools.ietf.org/html/rfc7231#section-4.3.5 + + // Sending a payload body on a request that does not + // expect it can cause undefined behavior on some + // servers and corrupt connection state. Do not + // re-use the connection for further requests. + + const expectsPayload = ( + method === 'PUT' || + method === 'POST' || + method === 'PATCH' + ); + + if (util.isFormDataLike(body)) { + if (!extractBody) { + extractBody = requireBody().extractBody; + } + + const [bodyStream, contentType] = extractBody(body); + if (request.contentType == null) { + headers.push('content-type', contentType); + } + body = bodyStream.stream; + contentLength = bodyStream.length; + } else if (util.isBlobLike(body) && request.contentType == null && body.type) { + headers.push('content-type', body.type); + } + + if (body && typeof body.read === 'function') { + // Try to read EOF in order to get length. + body.read(0); + } + + const bodyLength = util.bodyLength(body); + + contentLength = bodyLength ?? contentLength; + + if (contentLength === null) { + contentLength = request.contentLength; + } + + if (contentLength === 0 && !expectsPayload) { + // https://tools.ietf.org/html/rfc7230#section-3.3.2 + // A user agent SHOULD NOT send a Content-Length header field when + // the request message does not contain a payload body and the method + // semantics do not anticipate such a body. + + contentLength = null; + } + + // https://github.com/nodejs/undici/issues/2046 + // A user agent may send a Content-Length header with 0 value, this should be allowed. + if (shouldSendContentLength(method) && contentLength > 0 && request.contentLength !== null && request.contentLength !== contentLength) { + if (client[kStrictContentLength]) { + util.errorRequest(client, request, new RequestContentLengthMismatchError()); + return false + } + + process.emitWarning(new RequestContentLengthMismatchError()); + } + + const socket = client[kSocket]; + + const abort = (err) => { + if (request.aborted || request.completed) { + return + } + + util.errorRequest(client, request, err || new RequestAbortedError()); + + util.destroy(body); + util.destroy(socket, new InformationalError('aborted')); + }; + + try { + request.onConnect(abort); + } catch (err) { + util.errorRequest(client, request, err); + } + + if (request.aborted) { + return false + } + + if (method === 'HEAD') { + // https://github.com/mcollina/undici/issues/258 + // Close after a HEAD request to interop with misbehaving servers + // that may send a body in the response. + + socket[kReset] = true; + } + + if (upgrade || method === 'CONNECT') { + // On CONNECT or upgrade, block pipeline from dispatching further + // requests on this connection. + + socket[kReset] = true; + } + + if (reset != null) { + socket[kReset] = reset; + } + + if (client[kMaxRequests] && socket[kCounter]++ >= client[kMaxRequests]) { + socket[kReset] = true; + } + + if (blocking) { + socket[kBlocking] = true; + } + + let header = `${method} ${path} HTTP/1.1\r\n`; + + if (typeof host === 'string') { + header += `host: ${host}\r\n`; + } else { + header += client[kHostHeader]; + } + + if (upgrade) { + header += `connection: upgrade\r\nupgrade: ${upgrade}\r\n`; + } else if (client[kPipelining] && !socket[kReset]) { + header += 'connection: keep-alive\r\n'; + } else { + header += 'connection: close\r\n'; + } + + if (Array.isArray(headers)) { + for (let n = 0; n < headers.length; n += 2) { + const key = headers[n + 0]; + const val = headers[n + 1]; + + if (Array.isArray(val)) { + for (let i = 0; i < val.length; i++) { + header += `${key}: ${val[i]}\r\n`; + } + } else { + header += `${key}: ${val}\r\n`; + } + } + } + + if (channels.sendHeaders.hasSubscribers) { + channels.sendHeaders.publish({ request, headers: header, socket }); + } + + /* istanbul ignore else: assertion */ + if (!body || bodyLength === 0) { + writeBuffer(abort, null, client, request, socket, contentLength, header, expectsPayload); + } else if (util.isBuffer(body)) { + writeBuffer(abort, body, client, request, socket, contentLength, header, expectsPayload); + } else if (util.isBlobLike(body)) { + if (typeof body.stream === 'function') { + writeIterable(abort, body.stream(), client, request, socket, contentLength, header, expectsPayload); + } else { + writeBlob(abort, body, client, request, socket, contentLength, header, expectsPayload); + } + } else if (util.isStream(body)) { + writeStream(abort, body, client, request, socket, contentLength, header, expectsPayload); + } else if (util.isIterable(body)) { + writeIterable(abort, body, client, request, socket, contentLength, header, expectsPayload); + } else { + assert(false); + } + + return true + } + + function writeStream (abort, body, client, request, socket, contentLength, header, expectsPayload) { + assert(contentLength !== 0 || client[kRunning] === 0, 'stream body cannot be pipelined'); + + let finished = false; + + const writer = new AsyncWriter({ abort, socket, request, contentLength, client, expectsPayload, header }); + + const onData = function (chunk) { + if (finished) { + return + } + + try { + if (!writer.write(chunk) && this.pause) { + this.pause(); + } + } catch (err) { + util.destroy(this, err); + } + }; + const onDrain = function () { + if (finished) { + return + } + + if (body.resume) { + body.resume(); + } + }; + const onClose = function () { + // 'close' might be emitted *before* 'error' for + // broken streams. Wait a tick to avoid this case. + queueMicrotask(() => { + // It's only safe to remove 'error' listener after + // 'close'. + body.removeListener('error', onFinished); + }); + + if (!finished) { + const err = new RequestAbortedError(); + queueMicrotask(() => onFinished(err)); + } + }; + const onFinished = function (err) { + if (finished) { + return + } + + finished = true; + + assert(socket.destroyed || (socket[kWriting] && client[kRunning] <= 1)); + + socket + .off('drain', onDrain) + .off('error', onFinished); + + body + .removeListener('data', onData) + .removeListener('end', onFinished) + .removeListener('close', onClose); + + if (!err) { + try { + writer.end(); + } catch (er) { + err = er; + } + } + + writer.destroy(err); + + if (err && (err.code !== 'UND_ERR_INFO' || err.message !== 'reset')) { + util.destroy(body, err); + } else { + util.destroy(body); + } + }; + + body + .on('data', onData) + .on('end', onFinished) + .on('error', onFinished) + .on('close', onClose); + + if (body.resume) { + body.resume(); + } + + socket + .on('drain', onDrain) + .on('error', onFinished); + + if (body.errorEmitted ?? body.errored) { + setImmediate(() => onFinished(body.errored)); + } else if (body.endEmitted ?? body.readableEnded) { + setImmediate(() => onFinished(null)); + } + + if (body.closeEmitted ?? body.closed) { + setImmediate(onClose); + } + } + + function writeBuffer (abort, body, client, request, socket, contentLength, header, expectsPayload) { + try { + if (!body) { + if (contentLength === 0) { + socket.write(`${header}content-length: 0\r\n\r\n`, 'latin1'); + } else { + assert(contentLength === null, 'no body must not have content length'); + socket.write(`${header}\r\n`, 'latin1'); + } + } else if (util.isBuffer(body)) { + assert(contentLength === body.byteLength, 'buffer body must have content length'); + + socket.cork(); + socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1'); + socket.write(body); + socket.uncork(); + request.onBodySent(body); + + if (!expectsPayload) { + socket[kReset] = true; + } + } + request.onRequestSent(); + + client[kResume](); + } catch (err) { + abort(err); + } + } + + async function writeBlob (abort, body, client, request, socket, contentLength, header, expectsPayload) { + assert(contentLength === body.size, 'blob body must have content length'); + + try { + if (contentLength != null && contentLength !== body.size) { + throw new RequestContentLengthMismatchError() + } + + const buffer = Buffer.from(await body.arrayBuffer()); + + socket.cork(); + socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1'); + socket.write(buffer); + socket.uncork(); + + request.onBodySent(buffer); + request.onRequestSent(); + + if (!expectsPayload) { + socket[kReset] = true; + } + + client[kResume](); + } catch (err) { + abort(err); + } + } + + async function writeIterable (abort, body, client, request, socket, contentLength, header, expectsPayload) { + assert(contentLength !== 0 || client[kRunning] === 0, 'iterator body cannot be pipelined'); + + let callback = null; + function onDrain () { + if (callback) { + const cb = callback; + callback = null; + cb(); + } + } + + const waitForDrain = () => new Promise((resolve, reject) => { + assert(callback === null); + + if (socket[kError]) { + reject(socket[kError]); + } else { + callback = resolve; + } + }); + + socket + .on('close', onDrain) + .on('drain', onDrain); + + const writer = new AsyncWriter({ abort, socket, request, contentLength, client, expectsPayload, header }); + try { + // It's up to the user to somehow abort the async iterable. + for await (const chunk of body) { + if (socket[kError]) { + throw socket[kError] + } + + if (!writer.write(chunk)) { + await waitForDrain(); + } + } + + writer.end(); + } catch (err) { + writer.destroy(err); + } finally { + socket + .off('close', onDrain) + .off('drain', onDrain); + } + } + + class AsyncWriter { + constructor ({ abort, socket, request, contentLength, client, expectsPayload, header }) { + this.socket = socket; + this.request = request; + this.contentLength = contentLength; + this.client = client; + this.bytesWritten = 0; + this.expectsPayload = expectsPayload; + this.header = header; + this.abort = abort; + + socket[kWriting] = true; + } + + write (chunk) { + const { socket, request, contentLength, client, bytesWritten, expectsPayload, header } = this; + + if (socket[kError]) { + throw socket[kError] + } + + if (socket.destroyed) { + return false + } + + const len = Buffer.byteLength(chunk); + if (!len) { + return true + } + + // We should defer writing chunks. + if (contentLength !== null && bytesWritten + len > contentLength) { + if (client[kStrictContentLength]) { + throw new RequestContentLengthMismatchError() + } + + process.emitWarning(new RequestContentLengthMismatchError()); + } + + socket.cork(); + + if (bytesWritten === 0) { + if (!expectsPayload) { + socket[kReset] = true; + } + + if (contentLength === null) { + socket.write(`${header}transfer-encoding: chunked\r\n`, 'latin1'); + } else { + socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1'); + } + } + + if (contentLength === null) { + socket.write(`\r\n${len.toString(16)}\r\n`, 'latin1'); + } + + this.bytesWritten += len; + + const ret = socket.write(chunk); + + socket.uncork(); + + request.onBodySent(chunk); + + if (!ret) { + if (socket[kParser].timeout && socket[kParser].timeoutType === TIMEOUT_HEADERS) { + // istanbul ignore else: only for jest + if (socket[kParser].timeout.refresh) { + socket[kParser].timeout.refresh(); + } + } + } + + return ret + } + + end () { + const { socket, contentLength, client, bytesWritten, expectsPayload, header, request } = this; + request.onRequestSent(); + + socket[kWriting] = false; + + if (socket[kError]) { + throw socket[kError] + } + + if (socket.destroyed) { + return + } + + if (bytesWritten === 0) { + if (expectsPayload) { + // https://tools.ietf.org/html/rfc7230#section-3.3.2 + // A user agent SHOULD send a Content-Length in a request message when + // no Transfer-Encoding is sent and the request method defines a meaning + // for an enclosed payload body. + + socket.write(`${header}content-length: 0\r\n\r\n`, 'latin1'); + } else { + socket.write(`${header}\r\n`, 'latin1'); + } + } else if (contentLength === null) { + socket.write('\r\n0\r\n\r\n', 'latin1'); + } + + if (contentLength !== null && bytesWritten !== contentLength) { + if (client[kStrictContentLength]) { + throw new RequestContentLengthMismatchError() + } else { + process.emitWarning(new RequestContentLengthMismatchError()); + } + } + + if (socket[kParser].timeout && socket[kParser].timeoutType === TIMEOUT_HEADERS) { + // istanbul ignore else: only for jest + if (socket[kParser].timeout.refresh) { + socket[kParser].timeout.refresh(); + } + } + + client[kResume](); + } + + destroy (err) { + const { socket, client, abort } = this; + + socket[kWriting] = false; + + if (err) { + assert(client[kRunning] <= 1, 'pipeline should only contain this request'); + abort(err); + } + } + } + + clientH1 = connectH1; + return clientH1; +} + +var clientH2; +var hasRequiredClientH2; + +function requireClientH2 () { + if (hasRequiredClientH2) return clientH2; + hasRequiredClientH2 = 1; + + const assert = require$$0$4; + const { pipeline } = require$$0$5; + const util = requireUtil$7(); + const { + RequestContentLengthMismatchError, + RequestAbortedError, + SocketError, + InformationalError + } = requireErrors(); + const { + kUrl, + kReset, + kClient, + kRunning, + kPending, + kQueue, + kPendingIdx, + kRunningIdx, + kError, + kSocket, + kStrictContentLength, + kOnError, + kMaxConcurrentStreams, + kHTTP2Session, + kResume + } = requireSymbols$4(); + + const kOpenStreams = Symbol('open streams'); + + // Experimental + let h2ExperimentalWarned = false; + + /** @type {import('http2')} */ + let http2; + try { + http2 = require('node:http2'); + } catch { + // @ts-ignore + http2 = { constants: {} }; + } + + const { + constants: { + HTTP2_HEADER_AUTHORITY, + HTTP2_HEADER_METHOD, + HTTP2_HEADER_PATH, + HTTP2_HEADER_SCHEME, + HTTP2_HEADER_CONTENT_LENGTH, + HTTP2_HEADER_EXPECT, + HTTP2_HEADER_STATUS + } + } = http2; + + function parseH2Headers (headers) { + const result = []; + + for (const [name, value] of Object.entries(headers)) { + // h2 may concat the header value by array + // e.g. Set-Cookie + if (Array.isArray(value)) { + for (const subvalue of value) { + // we need to provide each header value of header name + // because the headers handler expect name-value pair + result.push(Buffer.from(name), Buffer.from(subvalue)); + } + } else { + result.push(Buffer.from(name), Buffer.from(value)); + } + } + + return result + } + + async function connectH2 (client, socket) { + client[kSocket] = socket; + + if (!h2ExperimentalWarned) { + h2ExperimentalWarned = true; + process.emitWarning('H2 support is experimental, expect them to change at any time.', { + code: 'UNDICI-H2' + }); + } + + const session = http2.connect(client[kUrl], { + createConnection: () => socket, + peerMaxConcurrentStreams: client[kMaxConcurrentStreams] + }); + + session[kOpenStreams] = 0; + session[kClient] = client; + session[kSocket] = socket; + + util.addListener(session, 'error', onHttp2SessionError); + util.addListener(session, 'frameError', onHttp2FrameError); + util.addListener(session, 'end', onHttp2SessionEnd); + util.addListener(session, 'goaway', onHTTP2GoAway); + util.addListener(session, 'close', function () { + const { [kClient]: client } = this; + const { [kSocket]: socket } = client; + + const err = this[kSocket][kError] || this[kError] || new SocketError('closed', util.getSocketInfo(socket)); + + client[kHTTP2Session] = null; + + if (client.destroyed) { + assert(client[kPending] === 0); + + // Fail entire queue. + const requests = client[kQueue].splice(client[kRunningIdx]); + for (let i = 0; i < requests.length; i++) { + const request = requests[i]; + util.errorRequest(client, request, err); + } + } + }); + + session.unref(); + + client[kHTTP2Session] = session; + socket[kHTTP2Session] = session; + + util.addListener(socket, 'error', function (err) { + assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID'); + + this[kError] = err; + + this[kClient][kOnError](err); + }); + + util.addListener(socket, 'end', function () { + util.destroy(this, new SocketError('other side closed', util.getSocketInfo(this))); + }); + + util.addListener(socket, 'close', function () { + const err = this[kError] || new SocketError('closed', util.getSocketInfo(this)); + + client[kSocket] = null; + + if (this[kHTTP2Session] != null) { + this[kHTTP2Session].destroy(err); + } + + client[kPendingIdx] = client[kRunningIdx]; + + assert(client[kRunning] === 0); + + client.emit('disconnect', client[kUrl], [client], err); + + client[kResume](); + }); + + let closed = false; + socket.on('close', () => { + closed = true; + }); + + return { + version: 'h2', + defaultPipelining: Infinity, + write (...args) { + // TODO (fix): return + writeH2(client, ...args); + }, + resume () { + + }, + destroy (err, callback) { + if (closed) { + queueMicrotask(callback); + } else { + // Destroying the socket will trigger the session close + socket.destroy(err).on('close', callback); + } + }, + get destroyed () { + return socket.destroyed + }, + busy () { + return false + } + } + } + + function onHttp2SessionError (err) { + assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID'); + + this[kSocket][kError] = err; + this[kClient][kOnError](err); + } + + function onHttp2FrameError (type, code, id) { + if (id === 0) { + const err = new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`); + this[kSocket][kError] = err; + this[kClient][kOnError](err); + } + } + + function onHttp2SessionEnd () { + const err = new SocketError('other side closed', util.getSocketInfo(this[kSocket])); + this.destroy(err); + util.destroy(this[kSocket], err); + } + + /** + * This is the root cause of #3011 + * We need to handle GOAWAY frames properly, and trigger the session close + * along with the socket right away + */ + function onHTTP2GoAway (code) { + const err = new RequestAbortedError(`HTTP/2: "GOAWAY" frame received with code ${code}`); + + // We need to trigger the close cycle right away + // We need to destroy the session and the socket + // Requests should be failed with the error after the current one is handled + this[kSocket][kError] = err; + this[kClient][kOnError](err); + + this.unref(); + + util.destroy(this[kSocket], err); + } + + // https://www.rfc-editor.org/rfc/rfc7230#section-3.3.2 + function shouldSendContentLength (method) { + return method !== 'GET' && method !== 'HEAD' && method !== 'OPTIONS' && method !== 'TRACE' && method !== 'CONNECT' + } + + function writeH2 (client, request) { + const session = client[kHTTP2Session]; + const { body, method, path, host, upgrade, expectContinue, signal, headers: reqHeaders } = request; + + if (upgrade) { + util.errorRequest(client, request, new Error('Upgrade not supported for H2')); + return false + } + + if (request.aborted) { + return false + } + + const headers = {}; + for (let n = 0; n < reqHeaders.length; n += 2) { + const key = reqHeaders[n + 0]; + const val = reqHeaders[n + 1]; + + if (Array.isArray(val)) { + for (let i = 0; i < val.length; i++) { + if (headers[key]) { + headers[key] += `,${val[i]}`; + } else { + headers[key] = val[i]; + } + } + } else { + headers[key] = val; + } + } + + /** @type {import('node:http2').ClientHttp2Stream} */ + let stream; + + const { hostname, port } = client[kUrl]; + + headers[HTTP2_HEADER_AUTHORITY] = host || `${hostname}${port ? `:${port}` : ''}`; + headers[HTTP2_HEADER_METHOD] = method; + + const abort = (err) => { + if (request.aborted || request.completed) { + return + } + + err = err || new RequestAbortedError(); + + util.errorRequest(client, request, err); + + if (stream != null) { + util.destroy(stream, err); + } + + // We do not destroy the socket as we can continue using the session + // the stream get's destroyed and the session remains to create new streams + util.destroy(body, err); + }; + + try { + // We are already connected, streams are pending. + // We can call on connect, and wait for abort + request.onConnect(abort); + } catch (err) { + util.errorRequest(client, request, err); + } + + if (method === 'CONNECT') { + session.ref(); + // We are already connected, streams are pending, first request + // will create a new stream. We trigger a request to create the stream and wait until + // `ready` event is triggered + // We disabled endStream to allow the user to write to the stream + stream = session.request(headers, { endStream: false, signal }); + + if (stream.id && !stream.pending) { + request.onUpgrade(null, null, stream); + ++session[kOpenStreams]; + } else { + stream.once('ready', () => { + request.onUpgrade(null, null, stream); + ++session[kOpenStreams]; + }); + } + + stream.once('close', () => { + session[kOpenStreams] -= 1; + if (session[kOpenStreams] === 0) session.unref(); + }); + + return true + } + + // https://tools.ietf.org/html/rfc7540#section-8.3 + // :path and :scheme headers must be omitted when sending CONNECT + + headers[HTTP2_HEADER_PATH] = path; + headers[HTTP2_HEADER_SCHEME] = 'https'; + + // https://tools.ietf.org/html/rfc7231#section-4.3.1 + // https://tools.ietf.org/html/rfc7231#section-4.3.2 + // https://tools.ietf.org/html/rfc7231#section-4.3.5 + + // Sending a payload body on a request that does not + // expect it can cause undefined behavior on some + // servers and corrupt connection state. Do not + // re-use the connection for further requests. + + const expectsPayload = ( + method === 'PUT' || + method === 'POST' || + method === 'PATCH' + ); + + if (body && typeof body.read === 'function') { + // Try to read EOF in order to get length. + body.read(0); + } + + let contentLength = util.bodyLength(body); + + if (contentLength == null) { + contentLength = request.contentLength; + } + + if (contentLength === 0 || !expectsPayload) { + // https://tools.ietf.org/html/rfc7230#section-3.3.2 + // A user agent SHOULD NOT send a Content-Length header field when + // the request message does not contain a payload body and the method + // semantics do not anticipate such a body. + + contentLength = null; + } + + // https://github.com/nodejs/undici/issues/2046 + // A user agent may send a Content-Length header with 0 value, this should be allowed. + if (shouldSendContentLength(method) && contentLength > 0 && request.contentLength != null && request.contentLength !== contentLength) { + if (client[kStrictContentLength]) { + util.errorRequest(client, request, new RequestContentLengthMismatchError()); + return false + } + + process.emitWarning(new RequestContentLengthMismatchError()); + } + + if (contentLength != null) { + assert(body, 'no body must not have content length'); + headers[HTTP2_HEADER_CONTENT_LENGTH] = `${contentLength}`; + } + + session.ref(); + + const shouldEndStream = method === 'GET' || method === 'HEAD' || body === null; + if (expectContinue) { + headers[HTTP2_HEADER_EXPECT] = '100-continue'; + stream = session.request(headers, { endStream: shouldEndStream, signal }); + + stream.once('continue', writeBodyH2); + } else { + stream = session.request(headers, { + endStream: shouldEndStream, + signal + }); + writeBodyH2(); + } + + // Increment counter as we have new streams open + ++session[kOpenStreams]; + + stream.once('response', headers => { + const { [HTTP2_HEADER_STATUS]: statusCode, ...realHeaders } = headers; + request.onResponseStarted(); + + // Due to the stream nature, it is possible we face a race condition + // where the stream has been assigned, but the request has been aborted + // the request remains in-flight and headers hasn't been received yet + // for those scenarios, best effort is to destroy the stream immediately + // as there's no value to keep it open. + if (request.aborted) { + const err = new RequestAbortedError(); + util.errorRequest(client, request, err); + util.destroy(stream, err); + return + } + + if (request.onHeaders(Number(statusCode), parseH2Headers(realHeaders), stream.resume.bind(stream), '') === false) { + stream.pause(); + } + + stream.on('data', (chunk) => { + if (request.onData(chunk) === false) { + stream.pause(); + } + }); + }); + + stream.once('end', () => { + // When state is null, it means we haven't consumed body and the stream still do not have + // a state. + // Present specially when using pipeline or stream + if (stream.state?.state == null || stream.state.state < 6) { + request.onComplete([]); + return + } + + // Stream is closed or half-closed-remote (6), decrement counter and cleanup + // It does not have sense to continue working with the stream as we do not + // have yet RST_STREAM support on client-side + if (session[kOpenStreams] === 0) { + session.unref(); + } + + abort(new InformationalError('HTTP/2: stream half-closed (remote)')); + }); + + stream.once('close', () => { + session[kOpenStreams] -= 1; + if (session[kOpenStreams] === 0) { + session.unref(); + } + }); + + stream.once('error', function (err) { + abort(err); + }); + + stream.once('frameError', (type, code) => { + abort(new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`)); + }); + + // stream.on('aborted', () => { + // // TODO(HTTP/2): Support aborted + // }) + + // stream.on('timeout', () => { + // // TODO(HTTP/2): Support timeout + // }) + + // stream.on('push', headers => { + // // TODO(HTTP/2): Support push + // }) + + // stream.on('trailers', headers => { + // // TODO(HTTP/2): Support trailers + // }) + + return true + + function writeBodyH2 () { + /* istanbul ignore else: assertion */ + if (!body || contentLength === 0) { + writeBuffer( + abort, + stream, + null, + client, + request, + client[kSocket], + contentLength, + expectsPayload + ); + } else if (util.isBuffer(body)) { + writeBuffer( + abort, + stream, + body, + client, + request, + client[kSocket], + contentLength, + expectsPayload + ); + } else if (util.isBlobLike(body)) { + if (typeof body.stream === 'function') { + writeIterable( + abort, + stream, + body.stream(), + client, + request, + client[kSocket], + contentLength, + expectsPayload + ); + } else { + writeBlob( + abort, + stream, + body, + client, + request, + client[kSocket], + contentLength, + expectsPayload + ); + } + } else if (util.isStream(body)) { + writeStream( + abort, + client[kSocket], + expectsPayload, + stream, + body, + client, + request, + contentLength + ); + } else if (util.isIterable(body)) { + writeIterable( + abort, + stream, + body, + client, + request, + client[kSocket], + contentLength, + expectsPayload + ); + } else { + assert(false); + } + } + } + + function writeBuffer (abort, h2stream, body, client, request, socket, contentLength, expectsPayload) { + try { + if (body != null && util.isBuffer(body)) { + assert(contentLength === body.byteLength, 'buffer body must have content length'); + h2stream.cork(); + h2stream.write(body); + h2stream.uncork(); + h2stream.end(); + + request.onBodySent(body); + } + + if (!expectsPayload) { + socket[kReset] = true; + } + + request.onRequestSent(); + client[kResume](); + } catch (error) { + abort(error); + } + } + + function writeStream (abort, socket, expectsPayload, h2stream, body, client, request, contentLength) { + assert(contentLength !== 0 || client[kRunning] === 0, 'stream body cannot be pipelined'); + + // For HTTP/2, is enough to pipe the stream + const pipe = pipeline( + body, + h2stream, + (err) => { + if (err) { + util.destroy(pipe, err); + abort(err); + } else { + util.removeAllListeners(pipe); + request.onRequestSent(); + + if (!expectsPayload) { + socket[kReset] = true; + } + + client[kResume](); + } + } + ); + + util.addListener(pipe, 'data', onPipeData); + + function onPipeData (chunk) { + request.onBodySent(chunk); + } + } + + async function writeBlob (abort, h2stream, body, client, request, socket, contentLength, expectsPayload) { + assert(contentLength === body.size, 'blob body must have content length'); + + try { + if (contentLength != null && contentLength !== body.size) { + throw new RequestContentLengthMismatchError() + } + + const buffer = Buffer.from(await body.arrayBuffer()); + + h2stream.cork(); + h2stream.write(buffer); + h2stream.uncork(); + h2stream.end(); + + request.onBodySent(buffer); + request.onRequestSent(); + + if (!expectsPayload) { + socket[kReset] = true; + } + + client[kResume](); + } catch (err) { + abort(err); + } + } + + async function writeIterable (abort, h2stream, body, client, request, socket, contentLength, expectsPayload) { + assert(contentLength !== 0 || client[kRunning] === 0, 'iterator body cannot be pipelined'); + + let callback = null; + function onDrain () { + if (callback) { + const cb = callback; + callback = null; + cb(); + } + } + + const waitForDrain = () => new Promise((resolve, reject) => { + assert(callback === null); + + if (socket[kError]) { + reject(socket[kError]); + } else { + callback = resolve; + } + }); + + h2stream + .on('close', onDrain) + .on('drain', onDrain); + + try { + // It's up to the user to somehow abort the async iterable. + for await (const chunk of body) { + if (socket[kError]) { + throw socket[kError] + } + + const res = h2stream.write(chunk); + request.onBodySent(chunk); + if (!res) { + await waitForDrain(); + } + } + + h2stream.end(); + + request.onRequestSent(); + + if (!expectsPayload) { + socket[kReset] = true; + } + + client[kResume](); + } catch (err) { + abort(err); + } finally { + h2stream + .off('close', onDrain) + .off('drain', onDrain); + } + } + + clientH2 = connectH2; + return clientH2; +} + +var redirectHandler; +var hasRequiredRedirectHandler; + +function requireRedirectHandler () { + if (hasRequiredRedirectHandler) return redirectHandler; + hasRequiredRedirectHandler = 1; + + const util = requireUtil$7(); + const { kBodyUsed } = requireSymbols$4(); + const assert = require$$0$4; + const { InvalidArgumentError } = requireErrors(); + const EE = require$$8; + + const redirectableStatusCodes = [300, 301, 302, 303, 307, 308]; + + const kBody = Symbol('body'); + + class BodyAsyncIterable { + constructor (body) { + this[kBody] = body; + this[kBodyUsed] = false; + } + + async * [Symbol.asyncIterator] () { + assert(!this[kBodyUsed], 'disturbed'); + this[kBodyUsed] = true; + yield * this[kBody]; + } + } + + class RedirectHandler { + constructor (dispatch, maxRedirections, opts, handler) { + if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) { + throw new InvalidArgumentError('maxRedirections must be a positive number') + } + + util.validateHandler(handler, opts.method, opts.upgrade); + + this.dispatch = dispatch; + this.location = null; + this.abort = null; + this.opts = { ...opts, maxRedirections: 0 }; // opts must be a copy + this.maxRedirections = maxRedirections; + this.handler = handler; + this.history = []; + this.redirectionLimitReached = false; + + if (util.isStream(this.opts.body)) { + // TODO (fix): Provide some way for the user to cache the file to e.g. /tmp + // so that it can be dispatched again? + // TODO (fix): Do we need 100-expect support to provide a way to do this properly? + if (util.bodyLength(this.opts.body) === 0) { + this.opts.body + .on('data', function () { + assert(false); + }); + } + + if (typeof this.opts.body.readableDidRead !== 'boolean') { + this.opts.body[kBodyUsed] = false; + EE.prototype.on.call(this.opts.body, 'data', function () { + this[kBodyUsed] = true; + }); + } + } else if (this.opts.body && typeof this.opts.body.pipeTo === 'function') { + // TODO (fix): We can't access ReadableStream internal state + // to determine whether or not it has been disturbed. This is just + // a workaround. + this.opts.body = new BodyAsyncIterable(this.opts.body); + } else if ( + this.opts.body && + typeof this.opts.body !== 'string' && + !ArrayBuffer.isView(this.opts.body) && + util.isIterable(this.opts.body) + ) { + // TODO: Should we allow re-using iterable if !this.opts.idempotent + // or through some other flag? + this.opts.body = new BodyAsyncIterable(this.opts.body); + } + } + + onConnect (abort) { + this.abort = abort; + this.handler.onConnect(abort, { history: this.history }); + } + + onUpgrade (statusCode, headers, socket) { + this.handler.onUpgrade(statusCode, headers, socket); + } + + onError (error) { + this.handler.onError(error); + } + + onHeaders (statusCode, headers, resume, statusText) { + this.location = this.history.length >= this.maxRedirections || util.isDisturbed(this.opts.body) + ? null + : parseLocation(statusCode, headers); + + if (this.opts.throwOnMaxRedirect && this.history.length >= this.maxRedirections) { + if (this.request) { + this.request.abort(new Error('max redirects')); + } + + this.redirectionLimitReached = true; + this.abort(new Error('max redirects')); + return + } + + if (this.opts.origin) { + this.history.push(new URL(this.opts.path, this.opts.origin)); + } + + if (!this.location) { + return this.handler.onHeaders(statusCode, headers, resume, statusText) + } + + const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin))); + const path = search ? `${pathname}${search}` : pathname; + + // Remove headers referring to the original URL. + // By default it is Host only, unless it's a 303 (see below), which removes also all Content-* headers. + // https://tools.ietf.org/html/rfc7231#section-6.4 + this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin); + this.opts.path = path; + this.opts.origin = origin; + this.opts.maxRedirections = 0; + this.opts.query = null; + + // https://tools.ietf.org/html/rfc7231#section-6.4.4 + // In case of HTTP 303, always replace method to be either HEAD or GET + if (statusCode === 303 && this.opts.method !== 'HEAD') { + this.opts.method = 'GET'; + this.opts.body = null; + } + } + + onData (chunk) { + if (this.location) ; else { + return this.handler.onData(chunk) + } + } + + onComplete (trailers) { + if (this.location) { + /* + https://tools.ietf.org/html/rfc7231#section-6.4 + + TLDR: undici always ignores 3xx response trailers as they are not expected in case of redirections + and neither are useful if present. + + See comment on onData method above for more detailed information. + */ + + this.location = null; + this.abort = null; + + this.dispatch(this.opts, this); + } else { + this.handler.onComplete(trailers); + } + } + + onBodySent (chunk) { + if (this.handler.onBodySent) { + this.handler.onBodySent(chunk); + } + } + } + + function parseLocation (statusCode, headers) { + if (redirectableStatusCodes.indexOf(statusCode) === -1) { + return null + } + + for (let i = 0; i < headers.length; i += 2) { + if (headers[i].length === 8 && util.headerNameToString(headers[i]) === 'location') { + return headers[i + 1] + } + } + } + + // https://tools.ietf.org/html/rfc7231#section-6.4.4 + function shouldRemoveHeader (header, removeContent, unknownOrigin) { + if (header.length === 4) { + return util.headerNameToString(header) === 'host' + } + if (removeContent && util.headerNameToString(header).startsWith('content-')) { + return true + } + if (unknownOrigin && (header.length === 13 || header.length === 6 || header.length === 19)) { + const name = util.headerNameToString(header); + return name === 'authorization' || name === 'cookie' || name === 'proxy-authorization' + } + return false + } + + // https://tools.ietf.org/html/rfc7231#section-6.4 + function cleanRequestHeaders (headers, removeContent, unknownOrigin) { + const ret = []; + if (Array.isArray(headers)) { + for (let i = 0; i < headers.length; i += 2) { + if (!shouldRemoveHeader(headers[i], removeContent, unknownOrigin)) { + ret.push(headers[i], headers[i + 1]); + } + } + } else if (headers && typeof headers === 'object') { + for (const key of Object.keys(headers)) { + if (!shouldRemoveHeader(key, removeContent, unknownOrigin)) { + ret.push(key, headers[key]); + } + } + } else { + assert(headers == null, 'headers must be an object or an array'); + } + return ret + } + + redirectHandler = RedirectHandler; + return redirectHandler; +} + +var redirectInterceptor; +var hasRequiredRedirectInterceptor; + +function requireRedirectInterceptor () { + if (hasRequiredRedirectInterceptor) return redirectInterceptor; + hasRequiredRedirectInterceptor = 1; + + const RedirectHandler = requireRedirectHandler(); + + function createRedirectInterceptor ({ maxRedirections: defaultMaxRedirections }) { + return (dispatch) => { + return function Intercept (opts, handler) { + const { maxRedirections = defaultMaxRedirections } = opts; + + if (!maxRedirections) { + return dispatch(opts, handler) + } + + const redirectHandler = new RedirectHandler(dispatch, maxRedirections, opts, handler); + opts = { ...opts, maxRedirections: 0 }; // Stop sub dispatcher from also redirecting. + return dispatch(opts, redirectHandler) + } + } + } + + redirectInterceptor = createRedirectInterceptor; + return redirectInterceptor; +} + +var client; +var hasRequiredClient; + +function requireClient () { + if (hasRequiredClient) return client; + hasRequiredClient = 1; + + const assert = require$$0$4; + const net = require$$4; + const http = require$$2; + const util = requireUtil$7(); + const { channels } = requireDiagnostics(); + const Request = requireRequest$1(); + const DispatcherBase = requireDispatcherBase(); + const { + InvalidArgumentError, + InformationalError, + ClientDestroyedError + } = requireErrors(); + const buildConnector = requireConnect(); + const { + kUrl, + kServerName, + kClient, + kBusy, + kConnect, + kResuming, + kRunning, + kPending, + kSize, + kQueue, + kConnected, + kConnecting, + kNeedDrain, + kKeepAliveDefaultTimeout, + kHostHeader, + kPendingIdx, + kRunningIdx, + kError, + kPipelining, + kKeepAliveTimeoutValue, + kMaxHeadersSize, + kKeepAliveMaxTimeout, + kKeepAliveTimeoutThreshold, + kHeadersTimeout, + kBodyTimeout, + kStrictContentLength, + kConnector, + kMaxRedirections, + kMaxRequests, + kCounter, + kClose, + kDestroy, + kDispatch, + kInterceptors, + kLocalAddress, + kMaxResponseSize, + kOnError, + kHTTPContext, + kMaxConcurrentStreams, + kResume + } = requireSymbols$4(); + const connectH1 = requireClientH1(); + const connectH2 = requireClientH2(); + let deprecatedInterceptorWarned = false; + + const kClosedResolve = Symbol('kClosedResolve'); + + function getPipelining (client) { + return client[kPipelining] ?? client[kHTTPContext]?.defaultPipelining ?? 1 + } + + /** + * @type {import('../../types/client.js').default} + */ + class Client extends DispatcherBase { + /** + * + * @param {string|URL} url + * @param {import('../../types/client.js').Client.Options} options + */ + constructor (url, { + interceptors, + maxHeaderSize, + headersTimeout, + socketTimeout, + requestTimeout, + connectTimeout, + bodyTimeout, + idleTimeout, + keepAlive, + keepAliveTimeout, + maxKeepAliveTimeout, + keepAliveMaxTimeout, + keepAliveTimeoutThreshold, + socketPath, + pipelining, + tls, + strictContentLength, + maxCachedSessions, + maxRedirections, + connect, + maxRequestsPerClient, + localAddress, + maxResponseSize, + autoSelectFamily, + autoSelectFamilyAttemptTimeout, + // h2 + maxConcurrentStreams, + allowH2 + } = {}) { + super(); + + if (keepAlive !== undefined) { + throw new InvalidArgumentError('unsupported keepAlive, use pipelining=0 instead') + } + + if (socketTimeout !== undefined) { + throw new InvalidArgumentError('unsupported socketTimeout, use headersTimeout & bodyTimeout instead') + } + + if (requestTimeout !== undefined) { + throw new InvalidArgumentError('unsupported requestTimeout, use headersTimeout & bodyTimeout instead') + } + + if (idleTimeout !== undefined) { + throw new InvalidArgumentError('unsupported idleTimeout, use keepAliveTimeout instead') + } + + if (maxKeepAliveTimeout !== undefined) { + throw new InvalidArgumentError('unsupported maxKeepAliveTimeout, use keepAliveMaxTimeout instead') + } + + if (maxHeaderSize != null && !Number.isFinite(maxHeaderSize)) { + throw new InvalidArgumentError('invalid maxHeaderSize') + } + + if (socketPath != null && typeof socketPath !== 'string') { + throw new InvalidArgumentError('invalid socketPath') + } + + if (connectTimeout != null && (!Number.isFinite(connectTimeout) || connectTimeout < 0)) { + throw new InvalidArgumentError('invalid connectTimeout') + } + + if (keepAliveTimeout != null && (!Number.isFinite(keepAliveTimeout) || keepAliveTimeout <= 0)) { + throw new InvalidArgumentError('invalid keepAliveTimeout') + } + + if (keepAliveMaxTimeout != null && (!Number.isFinite(keepAliveMaxTimeout) || keepAliveMaxTimeout <= 0)) { + throw new InvalidArgumentError('invalid keepAliveMaxTimeout') + } + + if (keepAliveTimeoutThreshold != null && !Number.isFinite(keepAliveTimeoutThreshold)) { + throw new InvalidArgumentError('invalid keepAliveTimeoutThreshold') + } + + if (headersTimeout != null && (!Number.isInteger(headersTimeout) || headersTimeout < 0)) { + throw new InvalidArgumentError('headersTimeout must be a positive integer or zero') + } + + if (bodyTimeout != null && (!Number.isInteger(bodyTimeout) || bodyTimeout < 0)) { + throw new InvalidArgumentError('bodyTimeout must be a positive integer or zero') + } + + if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') { + throw new InvalidArgumentError('connect must be a function or an object') + } + + if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) { + throw new InvalidArgumentError('maxRedirections must be a positive number') + } + + if (maxRequestsPerClient != null && (!Number.isInteger(maxRequestsPerClient) || maxRequestsPerClient < 0)) { + throw new InvalidArgumentError('maxRequestsPerClient must be a positive number') + } + + if (localAddress != null && (typeof localAddress !== 'string' || net.isIP(localAddress) === 0)) { + throw new InvalidArgumentError('localAddress must be valid string IP address') + } + + if (maxResponseSize != null && (!Number.isInteger(maxResponseSize) || maxResponseSize < -1)) { + throw new InvalidArgumentError('maxResponseSize must be a positive number') + } + + if ( + autoSelectFamilyAttemptTimeout != null && + (!Number.isInteger(autoSelectFamilyAttemptTimeout) || autoSelectFamilyAttemptTimeout < -1) + ) { + throw new InvalidArgumentError('autoSelectFamilyAttemptTimeout must be a positive number') + } + + // h2 + if (allowH2 != null && typeof allowH2 !== 'boolean') { + throw new InvalidArgumentError('allowH2 must be a valid boolean value') + } + + if (maxConcurrentStreams != null && (typeof maxConcurrentStreams !== 'number' || maxConcurrentStreams < 1)) { + throw new InvalidArgumentError('maxConcurrentStreams must be a positive integer, greater than 0') + } + + if (typeof connect !== 'function') { + connect = buildConnector({ + ...tls, + maxCachedSessions, + allowH2, + socketPath, + timeout: connectTimeout, + ...(autoSelectFamily ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : undefined), + ...connect + }); + } + + if (interceptors?.Client && Array.isArray(interceptors.Client)) { + this[kInterceptors] = interceptors.Client; + if (!deprecatedInterceptorWarned) { + deprecatedInterceptorWarned = true; + process.emitWarning('Client.Options#interceptor is deprecated. Use Dispatcher#compose instead.', { + code: 'UNDICI-CLIENT-INTERCEPTOR-DEPRECATED' + }); + } + } else { + this[kInterceptors] = [createRedirectInterceptor({ maxRedirections })]; + } + + this[kUrl] = util.parseOrigin(url); + this[kConnector] = connect; + this[kPipelining] = pipelining != null ? pipelining : 1; + this[kMaxHeadersSize] = maxHeaderSize || http.maxHeaderSize; + this[kKeepAliveDefaultTimeout] = keepAliveTimeout == null ? 4e3 : keepAliveTimeout; + this[kKeepAliveMaxTimeout] = keepAliveMaxTimeout == null ? 600e3 : keepAliveMaxTimeout; + this[kKeepAliveTimeoutThreshold] = keepAliveTimeoutThreshold == null ? 2e3 : keepAliveTimeoutThreshold; + this[kKeepAliveTimeoutValue] = this[kKeepAliveDefaultTimeout]; + this[kServerName] = null; + this[kLocalAddress] = localAddress != null ? localAddress : null; + this[kResuming] = 0; // 0, idle, 1, scheduled, 2 resuming + this[kNeedDrain] = 0; // 0, idle, 1, scheduled, 2 resuming + this[kHostHeader] = `host: ${this[kUrl].hostname}${this[kUrl].port ? `:${this[kUrl].port}` : ''}\r\n`; + this[kBodyTimeout] = bodyTimeout != null ? bodyTimeout : 300e3; + this[kHeadersTimeout] = headersTimeout != null ? headersTimeout : 300e3; + this[kStrictContentLength] = strictContentLength == null ? true : strictContentLength; + this[kMaxRedirections] = maxRedirections; + this[kMaxRequests] = maxRequestsPerClient; + this[kClosedResolve] = null; + this[kMaxResponseSize] = maxResponseSize > -1 ? maxResponseSize : -1; + this[kMaxConcurrentStreams] = maxConcurrentStreams != null ? maxConcurrentStreams : 100; // Max peerConcurrentStreams for a Node h2 server + this[kHTTPContext] = null; + + // kQueue is built up of 3 sections separated by + // the kRunningIdx and kPendingIdx indices. + // | complete | running | pending | + // ^ kRunningIdx ^ kPendingIdx ^ kQueue.length + // kRunningIdx points to the first running element. + // kPendingIdx points to the first pending element. + // This implements a fast queue with an amortized + // time of O(1). + + this[kQueue] = []; + this[kRunningIdx] = 0; + this[kPendingIdx] = 0; + + this[kResume] = (sync) => resume(this, sync); + this[kOnError] = (err) => onError(this, err); + } + + get pipelining () { + return this[kPipelining] + } + + set pipelining (value) { + this[kPipelining] = value; + this[kResume](true); + } + + get [kPending] () { + return this[kQueue].length - this[kPendingIdx] + } + + get [kRunning] () { + return this[kPendingIdx] - this[kRunningIdx] + } + + get [kSize] () { + return this[kQueue].length - this[kRunningIdx] + } + + get [kConnected] () { + return !!this[kHTTPContext] && !this[kConnecting] && !this[kHTTPContext].destroyed + } + + get [kBusy] () { + return Boolean( + this[kHTTPContext]?.busy(null) || + (this[kSize] >= (getPipelining(this) || 1)) || + this[kPending] > 0 + ) + } + + /* istanbul ignore: only used for test */ + [kConnect] (cb) { + connect(this); + this.once('connect', cb); + } + + [kDispatch] (opts, handler) { + const origin = opts.origin || this[kUrl].origin; + const request = new Request(origin, opts, handler); + + this[kQueue].push(request); + if (this[kResuming]) ; else if (util.bodyLength(request.body) == null && util.isIterable(request.body)) { + // Wait a tick in case stream/iterator is ended in the same tick. + this[kResuming] = 1; + queueMicrotask(() => resume(this)); + } else { + this[kResume](true); + } + + if (this[kResuming] && this[kNeedDrain] !== 2 && this[kBusy]) { + this[kNeedDrain] = 2; + } + + return this[kNeedDrain] < 2 + } + + async [kClose] () { + // TODO: for H2 we need to gracefully flush the remaining enqueued + // request and close each stream. + return new Promise((resolve) => { + if (this[kSize]) { + this[kClosedResolve] = resolve; + } else { + resolve(null); + } + }) + } + + async [kDestroy] (err) { + return new Promise((resolve) => { + const requests = this[kQueue].splice(this[kPendingIdx]); + for (let i = 0; i < requests.length; i++) { + const request = requests[i]; + util.errorRequest(this, request, err); + } + + const callback = () => { + if (this[kClosedResolve]) { + // TODO (fix): Should we error here with ClientDestroyedError? + this[kClosedResolve](); + this[kClosedResolve] = null; + } + resolve(null); + }; + + if (this[kHTTPContext]) { + this[kHTTPContext].destroy(err, callback); + this[kHTTPContext] = null; + } else { + queueMicrotask(callback); + } + + this[kResume](); + }) + } + } + + const createRedirectInterceptor = requireRedirectInterceptor(); + + function onError (client, err) { + if ( + client[kRunning] === 0 && + err.code !== 'UND_ERR_INFO' && + err.code !== 'UND_ERR_SOCKET' + ) { + // Error is not caused by running request and not a recoverable + // socket error. + + assert(client[kPendingIdx] === client[kRunningIdx]); + + const requests = client[kQueue].splice(client[kRunningIdx]); + + for (let i = 0; i < requests.length; i++) { + const request = requests[i]; + util.errorRequest(client, request, err); + } + assert(client[kSize] === 0); + } + } + + async function connect (client) { + assert(!client[kConnecting]); + assert(!client[kHTTPContext]); + + let { host, hostname, protocol, port } = client[kUrl]; + + // Resolve ipv6 + if (hostname[0] === '[') { + const idx = hostname.indexOf(']'); + + assert(idx !== -1); + const ip = hostname.substring(1, idx); + + assert(net.isIP(ip)); + hostname = ip; + } + + client[kConnecting] = true; + + if (channels.beforeConnect.hasSubscribers) { + channels.beforeConnect.publish({ + connectParams: { + host, + hostname, + protocol, + port, + version: client[kHTTPContext]?.version, + servername: client[kServerName], + localAddress: client[kLocalAddress] + }, + connector: client[kConnector] + }); + } + + try { + const socket = await new Promise((resolve, reject) => { + client[kConnector]({ + host, + hostname, + protocol, + port, + servername: client[kServerName], + localAddress: client[kLocalAddress] + }, (err, socket) => { + if (err) { + reject(err); + } else { + resolve(socket); + } + }); + }); + + if (client.destroyed) { + util.destroy(socket.on('error', () => {}), new ClientDestroyedError()); + return + } + + assert(socket); + + try { + client[kHTTPContext] = socket.alpnProtocol === 'h2' + ? await connectH2(client, socket) + : await connectH1(client, socket); + } catch (err) { + socket.destroy().on('error', () => {}); + throw err + } + + client[kConnecting] = false; + + socket[kCounter] = 0; + socket[kMaxRequests] = client[kMaxRequests]; + socket[kClient] = client; + socket[kError] = null; + + if (channels.connected.hasSubscribers) { + channels.connected.publish({ + connectParams: { + host, + hostname, + protocol, + port, + version: client[kHTTPContext]?.version, + servername: client[kServerName], + localAddress: client[kLocalAddress] + }, + connector: client[kConnector], + socket + }); + } + client.emit('connect', client[kUrl], [client]); + } catch (err) { + if (client.destroyed) { + return + } + + client[kConnecting] = false; + + if (channels.connectError.hasSubscribers) { + channels.connectError.publish({ + connectParams: { + host, + hostname, + protocol, + port, + version: client[kHTTPContext]?.version, + servername: client[kServerName], + localAddress: client[kLocalAddress] + }, + connector: client[kConnector], + error: err + }); + } + + if (err.code === 'ERR_TLS_CERT_ALTNAME_INVALID') { + assert(client[kRunning] === 0); + while (client[kPending] > 0 && client[kQueue][client[kPendingIdx]].servername === client[kServerName]) { + const request = client[kQueue][client[kPendingIdx]++]; + util.errorRequest(client, request, err); + } + } else { + onError(client, err); + } + + client.emit('connectionError', client[kUrl], [client], err); + } + + client[kResume](); + } + + function emitDrain (client) { + client[kNeedDrain] = 0; + client.emit('drain', client[kUrl], [client]); + } + + function resume (client, sync) { + if (client[kResuming] === 2) { + return + } + + client[kResuming] = 2; + + _resume(client, sync); + client[kResuming] = 0; + + if (client[kRunningIdx] > 256) { + client[kQueue].splice(0, client[kRunningIdx]); + client[kPendingIdx] -= client[kRunningIdx]; + client[kRunningIdx] = 0; + } + } + + function _resume (client, sync) { + while (true) { + if (client.destroyed) { + assert(client[kPending] === 0); + return + } + + if (client[kClosedResolve] && !client[kSize]) { + client[kClosedResolve](); + client[kClosedResolve] = null; + return + } + + if (client[kHTTPContext]) { + client[kHTTPContext].resume(); + } + + if (client[kBusy]) { + client[kNeedDrain] = 2; + } else if (client[kNeedDrain] === 2) { + if (sync) { + client[kNeedDrain] = 1; + queueMicrotask(() => emitDrain(client)); + } else { + emitDrain(client); + } + continue + } + + if (client[kPending] === 0) { + return + } + + if (client[kRunning] >= (getPipelining(client) || 1)) { + return + } + + const request = client[kQueue][client[kPendingIdx]]; + + if (client[kUrl].protocol === 'https:' && client[kServerName] !== request.servername) { + if (client[kRunning] > 0) { + return + } + + client[kServerName] = request.servername; + client[kHTTPContext]?.destroy(new InformationalError('servername changed'), () => { + client[kHTTPContext] = null; + resume(client); + }); + } + + if (client[kConnecting]) { + return + } + + if (!client[kHTTPContext]) { + connect(client); + return + } + + if (client[kHTTPContext].destroyed) { + return + } + + if (client[kHTTPContext].busy(request)) { + return + } + + if (!request.aborted && client[kHTTPContext].write(request)) { + client[kPendingIdx]++; + } else { + client[kQueue].splice(client[kPendingIdx], 1); + } + } + } + + client = Client; + return client; +} + +/* eslint-disable */ + +var fixedQueue; +var hasRequiredFixedQueue; + +function requireFixedQueue () { + if (hasRequiredFixedQueue) return fixedQueue; + hasRequiredFixedQueue = 1; + + // Extracted from node/lib/internal/fixed_queue.js + + // Currently optimal queue size, tested on V8 6.0 - 6.6. Must be power of two. + const kSize = 2048; + const kMask = kSize - 1; + + // The FixedQueue is implemented as a singly-linked list of fixed-size + // circular buffers. It looks something like this: + // + // head tail + // | | + // v v + // +-----------+ <-----\ +-----------+ <------\ +-----------+ + // | [null] | \----- | next | \------- | next | + // +-----------+ +-----------+ +-----------+ + // | item | <-- bottom | item | <-- bottom | [empty] | + // | item | | item | | [empty] | + // | item | | item | | [empty] | + // | item | | item | | [empty] | + // | item | | item | bottom --> | item | + // | item | | item | | item | + // | ... | | ... | | ... | + // | item | | item | | item | + // | item | | item | | item | + // | [empty] | <-- top | item | | item | + // | [empty] | | item | | item | + // | [empty] | | [empty] | <-- top top --> | [empty] | + // +-----------+ +-----------+ +-----------+ + // + // Or, if there is only one circular buffer, it looks something + // like either of these: + // + // head tail head tail + // | | | | + // v v v v + // +-----------+ +-----------+ + // | [null] | | [null] | + // +-----------+ +-----------+ + // | [empty] | | item | + // | [empty] | | item | + // | item | <-- bottom top --> | [empty] | + // | item | | [empty] | + // | [empty] | <-- top bottom --> | item | + // | [empty] | | item | + // +-----------+ +-----------+ + // + // Adding a value means moving `top` forward by one, removing means + // moving `bottom` forward by one. After reaching the end, the queue + // wraps around. + // + // When `top === bottom` the current queue is empty and when + // `top + 1 === bottom` it's full. This wastes a single space of storage + // but allows much quicker checks. + + class FixedCircularBuffer { + constructor() { + this.bottom = 0; + this.top = 0; + this.list = new Array(kSize); + this.next = null; + } + + isEmpty() { + return this.top === this.bottom; + } + + isFull() { + return ((this.top + 1) & kMask) === this.bottom; + } + + push(data) { + this.list[this.top] = data; + this.top = (this.top + 1) & kMask; + } + + shift() { + const nextItem = this.list[this.bottom]; + if (nextItem === undefined) + return null; + this.list[this.bottom] = undefined; + this.bottom = (this.bottom + 1) & kMask; + return nextItem; + } + } + + fixedQueue = class FixedQueue { + constructor() { + this.head = this.tail = new FixedCircularBuffer(); + } + + isEmpty() { + return this.head.isEmpty(); + } + + push(data) { + if (this.head.isFull()) { + // Head is full: Creates a new queue, sets the old queue's `.next` to it, + // and sets it as the new main queue. + this.head = this.head.next = new FixedCircularBuffer(); + } + this.head.push(data); + } + + shift() { + const tail = this.tail; + const next = tail.shift(); + if (tail.isEmpty() && tail.next !== null) { + // If there is another queue, it forms the new tail. + this.tail = tail.next; + } + return next; + } + }; + return fixedQueue; +} + +var poolStats; +var hasRequiredPoolStats; + +function requirePoolStats () { + if (hasRequiredPoolStats) return poolStats; + hasRequiredPoolStats = 1; + const { kFree, kConnected, kPending, kQueued, kRunning, kSize } = requireSymbols$4(); + const kPool = Symbol('pool'); + + class PoolStats { + constructor (pool) { + this[kPool] = pool; + } + + get connected () { + return this[kPool][kConnected] + } + + get free () { + return this[kPool][kFree] + } + + get pending () { + return this[kPool][kPending] + } + + get queued () { + return this[kPool][kQueued] + } + + get running () { + return this[kPool][kRunning] + } + + get size () { + return this[kPool][kSize] + } + } + + poolStats = PoolStats; + return poolStats; +} + +var poolBase; +var hasRequiredPoolBase; + +function requirePoolBase () { + if (hasRequiredPoolBase) return poolBase; + hasRequiredPoolBase = 1; + + const DispatcherBase = requireDispatcherBase(); + const FixedQueue = requireFixedQueue(); + const { kConnected, kSize, kRunning, kPending, kQueued, kBusy, kFree, kUrl, kClose, kDestroy, kDispatch } = requireSymbols$4(); + const PoolStats = requirePoolStats(); + + const kClients = Symbol('clients'); + const kNeedDrain = Symbol('needDrain'); + const kQueue = Symbol('queue'); + const kClosedResolve = Symbol('closed resolve'); + const kOnDrain = Symbol('onDrain'); + const kOnConnect = Symbol('onConnect'); + const kOnDisconnect = Symbol('onDisconnect'); + const kOnConnectionError = Symbol('onConnectionError'); + const kGetDispatcher = Symbol('get dispatcher'); + const kAddClient = Symbol('add client'); + const kRemoveClient = Symbol('remove client'); + const kStats = Symbol('stats'); + + class PoolBase extends DispatcherBase { + constructor () { + super(); + + this[kQueue] = new FixedQueue(); + this[kClients] = []; + this[kQueued] = 0; + + const pool = this; + + this[kOnDrain] = function onDrain (origin, targets) { + const queue = pool[kQueue]; + + let needDrain = false; + + while (!needDrain) { + const item = queue.shift(); + if (!item) { + break + } + pool[kQueued]--; + needDrain = !this.dispatch(item.opts, item.handler); + } + + this[kNeedDrain] = needDrain; + + if (!this[kNeedDrain] && pool[kNeedDrain]) { + pool[kNeedDrain] = false; + pool.emit('drain', origin, [pool, ...targets]); + } + + if (pool[kClosedResolve] && queue.isEmpty()) { + Promise + .all(pool[kClients].map(c => c.close())) + .then(pool[kClosedResolve]); + } + }; + + this[kOnConnect] = (origin, targets) => { + pool.emit('connect', origin, [pool, ...targets]); + }; + + this[kOnDisconnect] = (origin, targets, err) => { + pool.emit('disconnect', origin, [pool, ...targets], err); + }; + + this[kOnConnectionError] = (origin, targets, err) => { + pool.emit('connectionError', origin, [pool, ...targets], err); + }; + + this[kStats] = new PoolStats(this); + } + + get [kBusy] () { + return this[kNeedDrain] + } + + get [kConnected] () { + return this[kClients].filter(client => client[kConnected]).length + } + + get [kFree] () { + return this[kClients].filter(client => client[kConnected] && !client[kNeedDrain]).length + } + + get [kPending] () { + let ret = this[kQueued]; + for (const { [kPending]: pending } of this[kClients]) { + ret += pending; + } + return ret + } + + get [kRunning] () { + let ret = 0; + for (const { [kRunning]: running } of this[kClients]) { + ret += running; + } + return ret + } + + get [kSize] () { + let ret = this[kQueued]; + for (const { [kSize]: size } of this[kClients]) { + ret += size; + } + return ret + } + + get stats () { + return this[kStats] + } + + async [kClose] () { + if (this[kQueue].isEmpty()) { + return Promise.all(this[kClients].map(c => c.close())) + } else { + return new Promise((resolve) => { + this[kClosedResolve] = resolve; + }) + } + } + + async [kDestroy] (err) { + while (true) { + const item = this[kQueue].shift(); + if (!item) { + break + } + item.handler.onError(err); + } + + return Promise.all(this[kClients].map(c => c.destroy(err))) + } + + [kDispatch] (opts, handler) { + const dispatcher = this[kGetDispatcher](); + + if (!dispatcher) { + this[kNeedDrain] = true; + this[kQueue].push({ opts, handler }); + this[kQueued]++; + } else if (!dispatcher.dispatch(opts, handler)) { + dispatcher[kNeedDrain] = true; + this[kNeedDrain] = !this[kGetDispatcher](); + } + + return !this[kNeedDrain] + } + + [kAddClient] (client) { + client + .on('drain', this[kOnDrain]) + .on('connect', this[kOnConnect]) + .on('disconnect', this[kOnDisconnect]) + .on('connectionError', this[kOnConnectionError]); + + this[kClients].push(client); + + if (this[kNeedDrain]) { + queueMicrotask(() => { + if (this[kNeedDrain]) { + this[kOnDrain](client[kUrl], [this, client]); + } + }); + } + + return this + } + + [kRemoveClient] (client) { + client.close(() => { + const idx = this[kClients].indexOf(client); + if (idx !== -1) { + this[kClients].splice(idx, 1); + } + }); + + this[kNeedDrain] = this[kClients].some(dispatcher => ( + !dispatcher[kNeedDrain] && + dispatcher.closed !== true && + dispatcher.destroyed !== true + )); + } + } + + poolBase = { + PoolBase, + kClients, + kNeedDrain, + kAddClient, + kRemoveClient, + kGetDispatcher + }; + return poolBase; +} + +var pool; +var hasRequiredPool; + +function requirePool () { + if (hasRequiredPool) return pool; + hasRequiredPool = 1; + + const { + PoolBase, + kClients, + kNeedDrain, + kAddClient, + kGetDispatcher + } = requirePoolBase(); + const Client = requireClient(); + const { + InvalidArgumentError + } = requireErrors(); + const util = requireUtil$7(); + const { kUrl, kInterceptors } = requireSymbols$4(); + const buildConnector = requireConnect(); + + const kOptions = Symbol('options'); + const kConnections = Symbol('connections'); + const kFactory = Symbol('factory'); + + function defaultFactory (origin, opts) { + return new Client(origin, opts) + } + + class Pool extends PoolBase { + constructor (origin, { + connections, + factory = defaultFactory, + connect, + connectTimeout, + tls, + maxCachedSessions, + socketPath, + autoSelectFamily, + autoSelectFamilyAttemptTimeout, + allowH2, + ...options + } = {}) { + super(); + + if (connections != null && (!Number.isFinite(connections) || connections < 0)) { + throw new InvalidArgumentError('invalid connections') + } + + if (typeof factory !== 'function') { + throw new InvalidArgumentError('factory must be a function.') + } + + if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') { + throw new InvalidArgumentError('connect must be a function or an object') + } + + if (typeof connect !== 'function') { + connect = buildConnector({ + ...tls, + maxCachedSessions, + allowH2, + socketPath, + timeout: connectTimeout, + ...(autoSelectFamily ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : undefined), + ...connect + }); + } + + this[kInterceptors] = options.interceptors?.Pool && Array.isArray(options.interceptors.Pool) + ? options.interceptors.Pool + : []; + this[kConnections] = connections || null; + this[kUrl] = util.parseOrigin(origin); + this[kOptions] = { ...util.deepClone(options), connect, allowH2 }; + this[kOptions].interceptors = options.interceptors + ? { ...options.interceptors } + : undefined; + this[kFactory] = factory; + } + + [kGetDispatcher] () { + for (const client of this[kClients]) { + if (!client[kNeedDrain]) { + return client + } + } + + if (!this[kConnections] || this[kClients].length < this[kConnections]) { + const dispatcher = this[kFactory](this[kUrl], this[kOptions]); + this[kAddClient](dispatcher); + return dispatcher + } + } + } + + pool = Pool; + return pool; +} + +var balancedPool; +var hasRequiredBalancedPool; + +function requireBalancedPool () { + if (hasRequiredBalancedPool) return balancedPool; + hasRequiredBalancedPool = 1; + + const { + BalancedPoolMissingUpstreamError, + InvalidArgumentError + } = requireErrors(); + const { + PoolBase, + kClients, + kNeedDrain, + kAddClient, + kRemoveClient, + kGetDispatcher + } = requirePoolBase(); + const Pool = requirePool(); + const { kUrl, kInterceptors } = requireSymbols$4(); + const { parseOrigin } = requireUtil$7(); + const kFactory = Symbol('factory'); + + const kOptions = Symbol('options'); + const kGreatestCommonDivisor = Symbol('kGreatestCommonDivisor'); + const kCurrentWeight = Symbol('kCurrentWeight'); + const kIndex = Symbol('kIndex'); + const kWeight = Symbol('kWeight'); + const kMaxWeightPerServer = Symbol('kMaxWeightPerServer'); + const kErrorPenalty = Symbol('kErrorPenalty'); + + function getGreatestCommonDivisor (a, b) { + if (b === 0) return a + return getGreatestCommonDivisor(b, a % b) + } + + function defaultFactory (origin, opts) { + return new Pool(origin, opts) + } + + class BalancedPool extends PoolBase { + constructor (upstreams = [], { factory = defaultFactory, ...opts } = {}) { + super(); + + this[kOptions] = opts; + this[kIndex] = -1; + this[kCurrentWeight] = 0; + + this[kMaxWeightPerServer] = this[kOptions].maxWeightPerServer || 100; + this[kErrorPenalty] = this[kOptions].errorPenalty || 15; + + if (!Array.isArray(upstreams)) { + upstreams = [upstreams]; + } + + if (typeof factory !== 'function') { + throw new InvalidArgumentError('factory must be a function.') + } + + this[kInterceptors] = opts.interceptors?.BalancedPool && Array.isArray(opts.interceptors.BalancedPool) + ? opts.interceptors.BalancedPool + : []; + this[kFactory] = factory; + + for (const upstream of upstreams) { + this.addUpstream(upstream); + } + this._updateBalancedPoolStats(); + } + + addUpstream (upstream) { + const upstreamOrigin = parseOrigin(upstream).origin; + + if (this[kClients].find((pool) => ( + pool[kUrl].origin === upstreamOrigin && + pool.closed !== true && + pool.destroyed !== true + ))) { + return this + } + const pool = this[kFactory](upstreamOrigin, Object.assign({}, this[kOptions])); + + this[kAddClient](pool); + pool.on('connect', () => { + pool[kWeight] = Math.min(this[kMaxWeightPerServer], pool[kWeight] + this[kErrorPenalty]); + }); + + pool.on('connectionError', () => { + pool[kWeight] = Math.max(1, pool[kWeight] - this[kErrorPenalty]); + this._updateBalancedPoolStats(); + }); + + pool.on('disconnect', (...args) => { + const err = args[2]; + if (err && err.code === 'UND_ERR_SOCKET') { + // decrease the weight of the pool. + pool[kWeight] = Math.max(1, pool[kWeight] - this[kErrorPenalty]); + this._updateBalancedPoolStats(); + } + }); + + for (const client of this[kClients]) { + client[kWeight] = this[kMaxWeightPerServer]; + } + + this._updateBalancedPoolStats(); + + return this + } + + _updateBalancedPoolStats () { + this[kGreatestCommonDivisor] = this[kClients].map(p => p[kWeight]).reduce(getGreatestCommonDivisor, 0); + } + + removeUpstream (upstream) { + const upstreamOrigin = parseOrigin(upstream).origin; + + const pool = this[kClients].find((pool) => ( + pool[kUrl].origin === upstreamOrigin && + pool.closed !== true && + pool.destroyed !== true + )); + + if (pool) { + this[kRemoveClient](pool); + } + + return this + } + + get upstreams () { + return this[kClients] + .filter(dispatcher => dispatcher.closed !== true && dispatcher.destroyed !== true) + .map((p) => p[kUrl].origin) + } + + [kGetDispatcher] () { + // We validate that pools is greater than 0, + // otherwise we would have to wait until an upstream + // is added, which might never happen. + if (this[kClients].length === 0) { + throw new BalancedPoolMissingUpstreamError() + } + + const dispatcher = this[kClients].find(dispatcher => ( + !dispatcher[kNeedDrain] && + dispatcher.closed !== true && + dispatcher.destroyed !== true + )); + + if (!dispatcher) { + return + } + + const allClientsBusy = this[kClients].map(pool => pool[kNeedDrain]).reduce((a, b) => a && b, true); + + if (allClientsBusy) { + return + } + + let counter = 0; + + let maxWeightIndex = this[kClients].findIndex(pool => !pool[kNeedDrain]); + + while (counter++ < this[kClients].length) { + this[kIndex] = (this[kIndex] + 1) % this[kClients].length; + const pool = this[kClients][this[kIndex]]; + + // find pool index with the largest weight + if (pool[kWeight] > this[kClients][maxWeightIndex][kWeight] && !pool[kNeedDrain]) { + maxWeightIndex = this[kIndex]; + } + + // decrease the current weight every `this[kClients].length`. + if (this[kIndex] === 0) { + // Set the current weight to the next lower weight. + this[kCurrentWeight] = this[kCurrentWeight] - this[kGreatestCommonDivisor]; + + if (this[kCurrentWeight] <= 0) { + this[kCurrentWeight] = this[kMaxWeightPerServer]; + } + } + if (pool[kWeight] >= this[kCurrentWeight] && (!pool[kNeedDrain])) { + return pool + } + } + + this[kCurrentWeight] = this[kClients][maxWeightIndex][kWeight]; + this[kIndex] = maxWeightIndex; + return this[kClients][maxWeightIndex] + } + } + + balancedPool = BalancedPool; + return balancedPool; +} + +var agent; +var hasRequiredAgent; + +function requireAgent () { + if (hasRequiredAgent) return agent; + hasRequiredAgent = 1; + + const { InvalidArgumentError } = requireErrors(); + const { kClients, kRunning, kClose, kDestroy, kDispatch, kInterceptors } = requireSymbols$4(); + const DispatcherBase = requireDispatcherBase(); + const Pool = requirePool(); + const Client = requireClient(); + const util = requireUtil$7(); + const createRedirectInterceptor = requireRedirectInterceptor(); + + const kOnConnect = Symbol('onConnect'); + const kOnDisconnect = Symbol('onDisconnect'); + const kOnConnectionError = Symbol('onConnectionError'); + const kMaxRedirections = Symbol('maxRedirections'); + const kOnDrain = Symbol('onDrain'); + const kFactory = Symbol('factory'); + const kOptions = Symbol('options'); + + function defaultFactory (origin, opts) { + return opts && opts.connections === 1 + ? new Client(origin, opts) + : new Pool(origin, opts) + } + + class Agent extends DispatcherBase { + constructor ({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { + super(); + + if (typeof factory !== 'function') { + throw new InvalidArgumentError('factory must be a function.') + } + + if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') { + throw new InvalidArgumentError('connect must be a function or an object') + } + + if (!Number.isInteger(maxRedirections) || maxRedirections < 0) { + throw new InvalidArgumentError('maxRedirections must be a positive number') + } + + if (connect && typeof connect !== 'function') { + connect = { ...connect }; + } + + this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent) + ? options.interceptors.Agent + : [createRedirectInterceptor({ maxRedirections })]; + + this[kOptions] = { ...util.deepClone(options), connect }; + this[kOptions].interceptors = options.interceptors + ? { ...options.interceptors } + : undefined; + this[kMaxRedirections] = maxRedirections; + this[kFactory] = factory; + this[kClients] = new Map(); + + this[kOnDrain] = (origin, targets) => { + this.emit('drain', origin, [this, ...targets]); + }; + + this[kOnConnect] = (origin, targets) => { + this.emit('connect', origin, [this, ...targets]); + }; + + this[kOnDisconnect] = (origin, targets, err) => { + this.emit('disconnect', origin, [this, ...targets], err); + }; + + this[kOnConnectionError] = (origin, targets, err) => { + this.emit('connectionError', origin, [this, ...targets], err); + }; + } + + get [kRunning] () { + let ret = 0; + for (const client of this[kClients].values()) { + ret += client[kRunning]; + } + return ret + } + + [kDispatch] (opts, handler) { + let key; + if (opts.origin && (typeof opts.origin === 'string' || opts.origin instanceof URL)) { + key = String(opts.origin); + } else { + throw new InvalidArgumentError('opts.origin must be a non-empty string or URL.') + } + + let dispatcher = this[kClients].get(key); + + if (!dispatcher) { + dispatcher = this[kFactory](opts.origin, this[kOptions]) + .on('drain', this[kOnDrain]) + .on('connect', this[kOnConnect]) + .on('disconnect', this[kOnDisconnect]) + .on('connectionError', this[kOnConnectionError]); + + // This introduces a tiny memory leak, as dispatchers are never removed from the map. + // TODO(mcollina): remove te timer when the client/pool do not have any more + // active connections. + this[kClients].set(key, dispatcher); + } + + return dispatcher.dispatch(opts, handler) + } + + async [kClose] () { + const closePromises = []; + for (const client of this[kClients].values()) { + closePromises.push(client.close()); + } + this[kClients].clear(); + + await Promise.all(closePromises); + } + + async [kDestroy] (err) { + const destroyPromises = []; + for (const client of this[kClients].values()) { + destroyPromises.push(client.destroy(err)); + } + this[kClients].clear(); + + await Promise.all(destroyPromises); + } + } + + agent = Agent; + return agent; +} + +var proxyAgent; +var hasRequiredProxyAgent; + +function requireProxyAgent () { + if (hasRequiredProxyAgent) return proxyAgent; + hasRequiredProxyAgent = 1; + + const { kProxy, kClose, kDestroy, kInterceptors } = requireSymbols$4(); + const { URL } = url; + const Agent = requireAgent(); + const Pool = requirePool(); + const DispatcherBase = requireDispatcherBase(); + const { InvalidArgumentError, RequestAbortedError, SecureProxyConnectionError } = requireErrors(); + const buildConnector = requireConnect(); + + const kAgent = Symbol('proxy agent'); + const kClient = Symbol('proxy client'); + const kProxyHeaders = Symbol('proxy headers'); + const kRequestTls = Symbol('request tls settings'); + const kProxyTls = Symbol('proxy tls settings'); + const kConnectEndpoint = Symbol('connect endpoint function'); + + function defaultProtocolPort (protocol) { + return protocol === 'https:' ? 443 : 80 + } + + function defaultFactory (origin, opts) { + return new Pool(origin, opts) + } + + class ProxyAgent extends DispatcherBase { + constructor (opts) { + super(); + + if (!opts || (typeof opts === 'object' && !(opts instanceof URL) && !opts.uri)) { + throw new InvalidArgumentError('Proxy uri is mandatory') + } + + const { clientFactory = defaultFactory } = opts; + if (typeof clientFactory !== 'function') { + throw new InvalidArgumentError('Proxy opts.clientFactory must be a function.') + } + + const url = this.#getUrl(opts); + const { href, origin, port, protocol, username, password, hostname: proxyHostname } = url; + + this[kProxy] = { uri: href, protocol }; + this[kInterceptors] = opts.interceptors?.ProxyAgent && Array.isArray(opts.interceptors.ProxyAgent) + ? opts.interceptors.ProxyAgent + : []; + this[kRequestTls] = opts.requestTls; + this[kProxyTls] = opts.proxyTls; + this[kProxyHeaders] = opts.headers || {}; + + if (opts.auth && opts.token) { + throw new InvalidArgumentError('opts.auth cannot be used in combination with opts.token') + } else if (opts.auth) { + /* @deprecated in favour of opts.token */ + this[kProxyHeaders]['proxy-authorization'] = `Basic ${opts.auth}`; + } else if (opts.token) { + this[kProxyHeaders]['proxy-authorization'] = opts.token; + } else if (username && password) { + this[kProxyHeaders]['proxy-authorization'] = `Basic ${Buffer.from(`${decodeURIComponent(username)}:${decodeURIComponent(password)}`).toString('base64')}`; + } + + const connect = buildConnector({ ...opts.proxyTls }); + this[kConnectEndpoint] = buildConnector({ ...opts.requestTls }); + this[kClient] = clientFactory(url, { connect }); + this[kAgent] = new Agent({ + ...opts, + connect: async (opts, callback) => { + let requestedPath = opts.host; + if (!opts.port) { + requestedPath += `:${defaultProtocolPort(opts.protocol)}`; + } + try { + const { socket, statusCode } = await this[kClient].connect({ + origin, + port, + path: requestedPath, + signal: opts.signal, + headers: { + ...this[kProxyHeaders], + host: opts.host + }, + servername: this[kProxyTls]?.servername || proxyHostname + }); + if (statusCode !== 200) { + socket.on('error', () => {}).destroy(); + callback(new RequestAbortedError(`Proxy response (${statusCode}) !== 200 when HTTP Tunneling`)); + } + if (opts.protocol !== 'https:') { + callback(null, socket); + return + } + let servername; + if (this[kRequestTls]) { + servername = this[kRequestTls].servername; + } else { + servername = opts.servername; + } + this[kConnectEndpoint]({ ...opts, servername, httpSocket: socket }, callback); + } catch (err) { + if (err.code === 'ERR_TLS_CERT_ALTNAME_INVALID') { + // Throw a custom error to avoid loop in client.js#connect + callback(new SecureProxyConnectionError(err)); + } else { + callback(err); + } + } + } + }); + } + + dispatch (opts, handler) { + const headers = buildHeaders(opts.headers); + throwIfProxyAuthIsSent(headers); + + if (headers && !('host' in headers) && !('Host' in headers)) { + const { host } = new URL(opts.origin); + headers.host = host; + } + + return this[kAgent].dispatch( + { + ...opts, + headers + }, + handler + ) + } + + /** + * @param {import('../types/proxy-agent').ProxyAgent.Options | string | URL} opts + * @returns {URL} + */ + #getUrl (opts) { + if (typeof opts === 'string') { + return new URL(opts) + } else if (opts instanceof URL) { + return opts + } else { + return new URL(opts.uri) + } + } + + async [kClose] () { + await this[kAgent].close(); + await this[kClient].close(); + } + + async [kDestroy] () { + await this[kAgent].destroy(); + await this[kClient].destroy(); + } + } + + /** + * @param {string[] | Record} headers + * @returns {Record} + */ + function buildHeaders (headers) { + // When using undici.fetch, the headers list is stored + // as an array. + if (Array.isArray(headers)) { + /** @type {Record} */ + const headersPair = {}; + + for (let i = 0; i < headers.length; i += 2) { + headersPair[headers[i]] = headers[i + 1]; + } + + return headersPair + } + + return headers + } + + /** + * @param {Record} headers + * + * Previous versions of ProxyAgent suggests the Proxy-Authorization in request headers + * Nevertheless, it was changed and to avoid a security vulnerability by end users + * this check was created. + * It should be removed in the next major version for performance reasons + */ + function throwIfProxyAuthIsSent (headers) { + const existProxyAuth = headers && Object.keys(headers) + .find((key) => key.toLowerCase() === 'proxy-authorization'); + if (existProxyAuth) { + throw new InvalidArgumentError('Proxy-Authorization should be sent in ProxyAgent constructor') + } + } + + proxyAgent = ProxyAgent; + return proxyAgent; +} + +var envHttpProxyAgent; +var hasRequiredEnvHttpProxyAgent; + +function requireEnvHttpProxyAgent () { + if (hasRequiredEnvHttpProxyAgent) return envHttpProxyAgent; + hasRequiredEnvHttpProxyAgent = 1; + + const DispatcherBase = requireDispatcherBase(); + const { kClose, kDestroy, kClosed, kDestroyed, kDispatch, kNoProxyAgent, kHttpProxyAgent, kHttpsProxyAgent } = requireSymbols$4(); + const ProxyAgent = requireProxyAgent(); + const Agent = requireAgent(); + + const DEFAULT_PORTS = { + 'http:': 80, + 'https:': 443 + }; + + let experimentalWarned = false; + + class EnvHttpProxyAgent extends DispatcherBase { + #noProxyValue = null + #noProxyEntries = null + #opts = null + + constructor (opts = {}) { + super(); + this.#opts = opts; + + if (!experimentalWarned) { + experimentalWarned = true; + process.emitWarning('EnvHttpProxyAgent is experimental, expect them to change at any time.', { + code: 'UNDICI-EHPA' + }); + } + + const { httpProxy, httpsProxy, noProxy, ...agentOpts } = opts; + + this[kNoProxyAgent] = new Agent(agentOpts); + + const HTTP_PROXY = httpProxy ?? process.env.http_proxy ?? process.env.HTTP_PROXY; + if (HTTP_PROXY) { + this[kHttpProxyAgent] = new ProxyAgent({ ...agentOpts, uri: HTTP_PROXY }); + } else { + this[kHttpProxyAgent] = this[kNoProxyAgent]; + } + + const HTTPS_PROXY = httpsProxy ?? process.env.https_proxy ?? process.env.HTTPS_PROXY; + if (HTTPS_PROXY) { + this[kHttpsProxyAgent] = new ProxyAgent({ ...agentOpts, uri: HTTPS_PROXY }); + } else { + this[kHttpsProxyAgent] = this[kHttpProxyAgent]; + } + + this.#parseNoProxy(); + } + + [kDispatch] (opts, handler) { + const url = new URL(opts.origin); + const agent = this.#getProxyAgentForUrl(url); + return agent.dispatch(opts, handler) + } + + async [kClose] () { + await this[kNoProxyAgent].close(); + if (!this[kHttpProxyAgent][kClosed]) { + await this[kHttpProxyAgent].close(); + } + if (!this[kHttpsProxyAgent][kClosed]) { + await this[kHttpsProxyAgent].close(); + } + } + + async [kDestroy] (err) { + await this[kNoProxyAgent].destroy(err); + if (!this[kHttpProxyAgent][kDestroyed]) { + await this[kHttpProxyAgent].destroy(err); + } + if (!this[kHttpsProxyAgent][kDestroyed]) { + await this[kHttpsProxyAgent].destroy(err); + } + } + + #getProxyAgentForUrl (url) { + let { protocol, host: hostname, port } = url; + + // Stripping ports in this way instead of using parsedUrl.hostname to make + // sure that the brackets around IPv6 addresses are kept. + hostname = hostname.replace(/:\d*$/, '').toLowerCase(); + port = Number.parseInt(port, 10) || DEFAULT_PORTS[protocol] || 0; + if (!this.#shouldProxy(hostname, port)) { + return this[kNoProxyAgent] + } + if (protocol === 'https:') { + return this[kHttpsProxyAgent] + } + return this[kHttpProxyAgent] + } + + #shouldProxy (hostname, port) { + if (this.#noProxyChanged) { + this.#parseNoProxy(); + } + + if (this.#noProxyEntries.length === 0) { + return true // Always proxy if NO_PROXY is not set or empty. + } + if (this.#noProxyValue === '*') { + return false // Never proxy if wildcard is set. + } + + for (let i = 0; i < this.#noProxyEntries.length; i++) { + const entry = this.#noProxyEntries[i]; + if (entry.port && entry.port !== port) { + continue // Skip if ports don't match. + } + if (!/^[.*]/.test(entry.hostname)) { + // No wildcards, so don't proxy only if there is not an exact match. + if (hostname === entry.hostname) { + return false + } + } else { + // Don't proxy if the hostname ends with the no_proxy host. + if (hostname.endsWith(entry.hostname.replace(/^\*/, ''))) { + return false + } + } + } + + return true + } + + #parseNoProxy () { + const noProxyValue = this.#opts.noProxy ?? this.#noProxyEnv; + const noProxySplit = noProxyValue.split(/[,\s]/); + const noProxyEntries = []; + + for (let i = 0; i < noProxySplit.length; i++) { + const entry = noProxySplit[i]; + if (!entry) { + continue + } + const parsed = entry.match(/^(.+):(\d+)$/); + noProxyEntries.push({ + hostname: (parsed ? parsed[1] : entry).toLowerCase(), + port: parsed ? Number.parseInt(parsed[2], 10) : 0 + }); + } + + this.#noProxyValue = noProxyValue; + this.#noProxyEntries = noProxyEntries; + } + + get #noProxyChanged () { + if (this.#opts.noProxy !== undefined) { + return false + } + return this.#noProxyValue !== this.#noProxyEnv + } + + get #noProxyEnv () { + return process.env.no_proxy ?? process.env.NO_PROXY ?? '' + } + } + + envHttpProxyAgent = EnvHttpProxyAgent; + return envHttpProxyAgent; +} + +var retryHandler; +var hasRequiredRetryHandler; + +function requireRetryHandler () { + if (hasRequiredRetryHandler) return retryHandler; + hasRequiredRetryHandler = 1; + const assert = require$$0$4; + + const { kRetryHandlerDefaultRetry } = requireSymbols$4(); + const { RequestRetryError } = requireErrors(); + const { + isDisturbed, + parseHeaders, + parseRangeHeader, + wrapRequestBody + } = requireUtil$7(); + + function calculateRetryAfterHeader (retryAfter) { + const current = Date.now(); + return new Date(retryAfter).getTime() - current + } + + class RetryHandler { + constructor (opts, handlers) { + const { retryOptions, ...dispatchOpts } = opts; + const { + // Retry scoped + retry: retryFn, + maxRetries, + maxTimeout, + minTimeout, + timeoutFactor, + // Response scoped + methods, + errorCodes, + retryAfter, + statusCodes + } = retryOptions ?? {}; + + this.dispatch = handlers.dispatch; + this.handler = handlers.handler; + this.opts = { ...dispatchOpts, body: wrapRequestBody(opts.body) }; + this.abort = null; + this.aborted = false; + this.retryOpts = { + retry: retryFn ?? RetryHandler[kRetryHandlerDefaultRetry], + retryAfter: retryAfter ?? true, + maxTimeout: maxTimeout ?? 30 * 1000, // 30s, + minTimeout: minTimeout ?? 500, // .5s + timeoutFactor: timeoutFactor ?? 2, + maxRetries: maxRetries ?? 5, + // What errors we should retry + methods: methods ?? ['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE', 'TRACE'], + // Indicates which errors to retry + statusCodes: statusCodes ?? [500, 502, 503, 504, 429], + // List of errors to retry + errorCodes: errorCodes ?? [ + 'ECONNRESET', + 'ECONNREFUSED', + 'ENOTFOUND', + 'ENETDOWN', + 'ENETUNREACH', + 'EHOSTDOWN', + 'EHOSTUNREACH', + 'EPIPE', + 'UND_ERR_SOCKET' + ] + }; + + this.retryCount = 0; + this.retryCountCheckpoint = 0; + this.start = 0; + this.end = null; + this.etag = null; + this.resume = null; + + // Handle possible onConnect duplication + this.handler.onConnect(reason => { + this.aborted = true; + if (this.abort) { + this.abort(reason); + } else { + this.reason = reason; + } + }); + } + + onRequestSent () { + if (this.handler.onRequestSent) { + this.handler.onRequestSent(); + } + } + + onUpgrade (statusCode, headers, socket) { + if (this.handler.onUpgrade) { + this.handler.onUpgrade(statusCode, headers, socket); + } + } + + onConnect (abort) { + if (this.aborted) { + abort(this.reason); + } else { + this.abort = abort; + } + } + + onBodySent (chunk) { + if (this.handler.onBodySent) return this.handler.onBodySent(chunk) + } + + static [kRetryHandlerDefaultRetry] (err, { state, opts }, cb) { + const { statusCode, code, headers } = err; + const { method, retryOptions } = opts; + const { + maxRetries, + minTimeout, + maxTimeout, + timeoutFactor, + statusCodes, + errorCodes, + methods + } = retryOptions; + const { counter } = state; + + // Any code that is not a Undici's originated and allowed to retry + if (code && code !== 'UND_ERR_REQ_RETRY' && !errorCodes.includes(code)) { + cb(err); + return + } + + // If a set of method are provided and the current method is not in the list + if (Array.isArray(methods) && !methods.includes(method)) { + cb(err); + return + } + + // If a set of status code are provided and the current status code is not in the list + if ( + statusCode != null && + Array.isArray(statusCodes) && + !statusCodes.includes(statusCode) + ) { + cb(err); + return + } + + // If we reached the max number of retries + if (counter > maxRetries) { + cb(err); + return + } + + let retryAfterHeader = headers?.['retry-after']; + if (retryAfterHeader) { + retryAfterHeader = Number(retryAfterHeader); + retryAfterHeader = Number.isNaN(retryAfterHeader) + ? calculateRetryAfterHeader(retryAfterHeader) + : retryAfterHeader * 1e3; // Retry-After is in seconds + } + + const retryTimeout = + retryAfterHeader > 0 + ? Math.min(retryAfterHeader, maxTimeout) + : Math.min(minTimeout * timeoutFactor ** (counter - 1), maxTimeout); + + setTimeout(() => cb(null), retryTimeout); + } + + onHeaders (statusCode, rawHeaders, resume, statusMessage) { + const headers = parseHeaders(rawHeaders); + + this.retryCount += 1; + + if (statusCode >= 300) { + if (this.retryOpts.statusCodes.includes(statusCode) === false) { + return this.handler.onHeaders( + statusCode, + rawHeaders, + resume, + statusMessage + ) + } else { + this.abort( + new RequestRetryError('Request failed', statusCode, { + headers, + data: { + count: this.retryCount + } + }) + ); + return false + } + } + + // Checkpoint for resume from where we left it + if (this.resume != null) { + this.resume = null; + + if (statusCode !== 206) { + return true + } + + const contentRange = parseRangeHeader(headers['content-range']); + // If no content range + if (!contentRange) { + this.abort( + new RequestRetryError('Content-Range mismatch', statusCode, { + headers, + data: { count: this.retryCount } + }) + ); + return false + } + + // Let's start with a weak etag check + if (this.etag != null && this.etag !== headers.etag) { + this.abort( + new RequestRetryError('ETag mismatch', statusCode, { + headers, + data: { count: this.retryCount } + }) + ); + return false + } + + const { start, size, end = size } = contentRange; + + assert(this.start === start, 'content-range mismatch'); + assert(this.end == null || this.end === end, 'content-range mismatch'); + + this.resume = resume; + return true + } + + if (this.end == null) { + if (statusCode === 206) { + // First time we receive 206 + const range = parseRangeHeader(headers['content-range']); + + if (range == null) { + return this.handler.onHeaders( + statusCode, + rawHeaders, + resume, + statusMessage + ) + } + + const { start, size, end = size } = range; + assert( + start != null && Number.isFinite(start), + 'content-range mismatch' + ); + assert(end != null && Number.isFinite(end), 'invalid content-length'); + + this.start = start; + this.end = end; + } + + // We make our best to checkpoint the body for further range headers + if (this.end == null) { + const contentLength = headers['content-length']; + this.end = contentLength != null ? Number(contentLength) : null; + } + + assert(Number.isFinite(this.start)); + assert( + this.end == null || Number.isFinite(this.end), + 'invalid content-length' + ); + + this.resume = resume; + this.etag = headers.etag != null ? headers.etag : null; + + // Weak etags are not useful for comparison nor cache + // for instance not safe to assume if the response is byte-per-byte + // equal + if (this.etag != null && this.etag.startsWith('W/')) { + this.etag = null; + } + + return this.handler.onHeaders( + statusCode, + rawHeaders, + resume, + statusMessage + ) + } + + const err = new RequestRetryError('Request failed', statusCode, { + headers, + data: { count: this.retryCount } + }); + + this.abort(err); + + return false + } + + onData (chunk) { + this.start += chunk.length; + + return this.handler.onData(chunk) + } + + onComplete (rawTrailers) { + this.retryCount = 0; + return this.handler.onComplete(rawTrailers) + } + + onError (err) { + if (this.aborted || isDisturbed(this.opts.body)) { + return this.handler.onError(err) + } + + // We reconcile in case of a mix between network errors + // and server error response + if (this.retryCount - this.retryCountCheckpoint > 0) { + // We count the difference between the last checkpoint and the current retry count + this.retryCount = + this.retryCountCheckpoint + + (this.retryCount - this.retryCountCheckpoint); + } else { + this.retryCount += 1; + } + + this.retryOpts.retry( + err, + { + state: { counter: this.retryCount }, + opts: { retryOptions: this.retryOpts, ...this.opts } + }, + onRetry.bind(this) + ); + + function onRetry (err) { + if (err != null || this.aborted || isDisturbed(this.opts.body)) { + return this.handler.onError(err) + } + + if (this.start !== 0) { + const headers = { range: `bytes=${this.start}-${this.end ?? ''}` }; + + // Weak etag check - weak etags will make comparison algorithms never match + if (this.etag != null) { + headers['if-match'] = this.etag; + } + + this.opts = { + ...this.opts, + headers: { + ...this.opts.headers, + ...headers + } + }; + } + + try { + this.retryCountCheckpoint = this.retryCount; + this.dispatch(this.opts, this); + } catch (err) { + this.handler.onError(err); + } + } + } + } + + retryHandler = RetryHandler; + return retryHandler; +} + +var retryAgent; +var hasRequiredRetryAgent; + +function requireRetryAgent () { + if (hasRequiredRetryAgent) return retryAgent; + hasRequiredRetryAgent = 1; + + const Dispatcher = requireDispatcher(); + const RetryHandler = requireRetryHandler(); + + class RetryAgent extends Dispatcher { + #agent = null + #options = null + constructor (agent, options = {}) { + super(options); + this.#agent = agent; + this.#options = options; + } + + dispatch (opts, handler) { + const retry = new RetryHandler({ + ...opts, + retryOptions: this.#options + }, { + dispatch: this.#agent.dispatch.bind(this.#agent), + handler + }); + return this.#agent.dispatch(opts, retry) + } + + close () { + return this.#agent.close() + } + + destroy () { + return this.#agent.destroy() + } + } + + retryAgent = RetryAgent; + return retryAgent; +} + +var api = {}; + +var apiRequest = {exports: {}}; + +var readable; +var hasRequiredReadable; + +function requireReadable () { + if (hasRequiredReadable) return readable; + hasRequiredReadable = 1; + + const assert = require$$0$4; + const { Readable } = require$$0$5; + const { RequestAbortedError, NotSupportedError, InvalidArgumentError, AbortError } = requireErrors(); + const util = requireUtil$7(); + const { ReadableStreamFrom } = requireUtil$7(); + + const kConsume = Symbol('kConsume'); + const kReading = Symbol('kReading'); + const kBody = Symbol('kBody'); + const kAbort = Symbol('kAbort'); + const kContentType = Symbol('kContentType'); + const kContentLength = Symbol('kContentLength'); + + const noop = () => {}; + + class BodyReadable extends Readable { + constructor ({ + resume, + abort, + contentType = '', + contentLength, + highWaterMark = 64 * 1024 // Same as nodejs fs streams. + }) { + super({ + autoDestroy: true, + read: resume, + highWaterMark + }); + + this._readableState.dataEmitted = false; + + this[kAbort] = abort; + this[kConsume] = null; + this[kBody] = null; + this[kContentType] = contentType; + this[kContentLength] = contentLength; + + // Is stream being consumed through Readable API? + // This is an optimization so that we avoid checking + // for 'data' and 'readable' listeners in the hot path + // inside push(). + this[kReading] = false; + } + + destroy (err) { + if (!err && !this._readableState.endEmitted) { + err = new RequestAbortedError(); + } + + if (err) { + this[kAbort](); + } + + return super.destroy(err) + } + + _destroy (err, callback) { + // Workaround for Node "bug". If the stream is destroyed in same + // tick as it is created, then a user who is waiting for a + // promise (i.e micro tick) for installing a 'error' listener will + // never get a chance and will always encounter an unhandled exception. + if (!this[kReading]) { + setImmediate(() => { + callback(err); + }); + } else { + callback(err); + } + } + + on (ev, ...args) { + if (ev === 'data' || ev === 'readable') { + this[kReading] = true; + } + return super.on(ev, ...args) + } + + addListener (ev, ...args) { + return this.on(ev, ...args) + } + + off (ev, ...args) { + const ret = super.off(ev, ...args); + if (ev === 'data' || ev === 'readable') { + this[kReading] = ( + this.listenerCount('data') > 0 || + this.listenerCount('readable') > 0 + ); + } + return ret + } + + removeListener (ev, ...args) { + return this.off(ev, ...args) + } + + push (chunk) { + if (this[kConsume] && chunk !== null) { + consumePush(this[kConsume], chunk); + return this[kReading] ? super.push(chunk) : true + } + return super.push(chunk) + } + + // https://fetch.spec.whatwg.org/#dom-body-text + async text () { + return consume(this, 'text') + } + + // https://fetch.spec.whatwg.org/#dom-body-json + async json () { + return consume(this, 'json') + } + + // https://fetch.spec.whatwg.org/#dom-body-blob + async blob () { + return consume(this, 'blob') + } + + // https://fetch.spec.whatwg.org/#dom-body-arraybuffer + async arrayBuffer () { + return consume(this, 'arrayBuffer') + } + + // https://fetch.spec.whatwg.org/#dom-body-formdata + async formData () { + // TODO: Implement. + throw new NotSupportedError() + } + + // https://fetch.spec.whatwg.org/#dom-body-bodyused + get bodyUsed () { + return util.isDisturbed(this) + } + + // https://fetch.spec.whatwg.org/#dom-body-body + get body () { + if (!this[kBody]) { + this[kBody] = ReadableStreamFrom(this); + if (this[kConsume]) { + // TODO: Is this the best way to force a lock? + this[kBody].getReader(); // Ensure stream is locked. + assert(this[kBody].locked); + } + } + return this[kBody] + } + + async dump (opts) { + let limit = Number.isFinite(opts?.limit) ? opts.limit : 128 * 1024; + const signal = opts?.signal; + + if (signal != null && (typeof signal !== 'object' || !('aborted' in signal))) { + throw new InvalidArgumentError('signal must be an AbortSignal') + } + + signal?.throwIfAborted(); + + if (this._readableState.closeEmitted) { + return null + } + + return await new Promise((resolve, reject) => { + if (this[kContentLength] > limit) { + this.destroy(new AbortError()); + } + + const onAbort = () => { + this.destroy(signal.reason ?? new AbortError()); + }; + signal?.addEventListener('abort', onAbort); + + this + .on('close', function () { + signal?.removeEventListener('abort', onAbort); + if (signal?.aborted) { + reject(signal.reason ?? new AbortError()); + } else { + resolve(null); + } + }) + .on('error', noop) + .on('data', function (chunk) { + limit -= chunk.length; + if (limit <= 0) { + this.destroy(); + } + }) + .resume(); + }) + } + } + + // https://streams.spec.whatwg.org/#readablestream-locked + function isLocked (self) { + // Consume is an implicit lock. + return (self[kBody] && self[kBody].locked === true) || self[kConsume] + } + + // https://fetch.spec.whatwg.org/#body-unusable + function isUnusable (self) { + return util.isDisturbed(self) || isLocked(self) + } + + async function consume (stream, type) { + assert(!stream[kConsume]); + + return new Promise((resolve, reject) => { + if (isUnusable(stream)) { + const rState = stream._readableState; + if (rState.destroyed && rState.closeEmitted === false) { + stream + .on('error', err => { + reject(err); + }) + .on('close', () => { + reject(new TypeError('unusable')); + }); + } else { + reject(rState.errored ?? new TypeError('unusable')); + } + } else { + queueMicrotask(() => { + stream[kConsume] = { + type, + stream, + resolve, + reject, + length: 0, + body: [] + }; + + stream + .on('error', function (err) { + consumeFinish(this[kConsume], err); + }) + .on('close', function () { + if (this[kConsume].body !== null) { + consumeFinish(this[kConsume], new RequestAbortedError()); + } + }); + + consumeStart(stream[kConsume]); + }); + } + }) + } + + function consumeStart (consume) { + if (consume.body === null) { + return + } + + const { _readableState: state } = consume.stream; + + if (state.bufferIndex) { + const start = state.bufferIndex; + const end = state.buffer.length; + for (let n = start; n < end; n++) { + consumePush(consume, state.buffer[n]); + } + } else { + for (const chunk of state.buffer) { + consumePush(consume, chunk); + } + } + + if (state.endEmitted) { + consumeEnd(this[kConsume]); + } else { + consume.stream.on('end', function () { + consumeEnd(this[kConsume]); + }); + } + + consume.stream.resume(); + + while (consume.stream.read() != null) { + // Loop + } + } + + /** + * @param {Buffer[]} chunks + * @param {number} length + */ + function chunksDecode (chunks, length) { + if (chunks.length === 0 || length === 0) { + return '' + } + const buffer = chunks.length === 1 ? chunks[0] : Buffer.concat(chunks, length); + const bufferLength = buffer.length; + + // Skip BOM. + const start = + bufferLength > 2 && + buffer[0] === 0xef && + buffer[1] === 0xbb && + buffer[2] === 0xbf + ? 3 + : 0; + return buffer.utf8Slice(start, bufferLength) + } + + function consumeEnd (consume) { + const { type, body, resolve, stream, length } = consume; + + try { + if (type === 'text') { + resolve(chunksDecode(body, length)); + } else if (type === 'json') { + resolve(JSON.parse(chunksDecode(body, length))); + } else if (type === 'arrayBuffer') { + const dst = new Uint8Array(length); + + let pos = 0; + for (const buf of body) { + dst.set(buf, pos); + pos += buf.byteLength; + } + + resolve(dst.buffer); + } else if (type === 'blob') { + resolve(new Blob(body, { type: stream[kContentType] })); + } + + consumeFinish(consume); + } catch (err) { + stream.destroy(err); + } + } + + function consumePush (consume, chunk) { + consume.length += chunk.length; + consume.body.push(chunk); + } + + function consumeFinish (consume, err) { + if (consume.body === null) { + return + } + + if (err) { + consume.reject(err); + } else { + consume.resolve(); + } + + consume.type = null; + consume.stream = null; + consume.resolve = null; + consume.reject = null; + consume.length = 0; + consume.body = null; + } + + readable = { Readable: BodyReadable, chunksDecode }; + return readable; +} + +var util$5; +var hasRequiredUtil$5; + +function requireUtil$5 () { + if (hasRequiredUtil$5) return util$5; + hasRequiredUtil$5 = 1; + const assert = require$$0$4; + const { + ResponseStatusCodeError + } = requireErrors(); + + const { chunksDecode } = requireReadable(); + const CHUNK_LIMIT = 128 * 1024; + + async function getResolveErrorBodyCallback ({ callback, body, contentType, statusCode, statusMessage, headers }) { + assert(body); + + let chunks = []; + let length = 0; + + try { + for await (const chunk of body) { + chunks.push(chunk); + length += chunk.length; + if (length > CHUNK_LIMIT) { + chunks = []; + length = 0; + break + } + } + } catch { + chunks = []; + length = 0; + // Do nothing.... + } + + const message = `Response status code ${statusCode}${statusMessage ? `: ${statusMessage}` : ''}`; + + if (statusCode === 204 || !contentType || !length) { + queueMicrotask(() => callback(new ResponseStatusCodeError(message, statusCode, headers))); + return + } + + const stackTraceLimit = Error.stackTraceLimit; + Error.stackTraceLimit = 0; + let payload; + + try { + if (isContentTypeApplicationJson(contentType)) { + payload = JSON.parse(chunksDecode(chunks, length)); + } else if (isContentTypeText(contentType)) { + payload = chunksDecode(chunks, length); + } + } catch { + // process in a callback to avoid throwing in the microtask queue + } finally { + Error.stackTraceLimit = stackTraceLimit; + } + queueMicrotask(() => callback(new ResponseStatusCodeError(message, statusCode, headers, payload))); + } + + const isContentTypeApplicationJson = (contentType) => { + return ( + contentType.length > 15 && + contentType[11] === '/' && + contentType[0] === 'a' && + contentType[1] === 'p' && + contentType[2] === 'p' && + contentType[3] === 'l' && + contentType[4] === 'i' && + contentType[5] === 'c' && + contentType[6] === 'a' && + contentType[7] === 't' && + contentType[8] === 'i' && + contentType[9] === 'o' && + contentType[10] === 'n' && + contentType[12] === 'j' && + contentType[13] === 's' && + contentType[14] === 'o' && + contentType[15] === 'n' + ) + }; + + const isContentTypeText = (contentType) => { + return ( + contentType.length > 4 && + contentType[4] === '/' && + contentType[0] === 't' && + contentType[1] === 'e' && + contentType[2] === 'x' && + contentType[3] === 't' + ) + }; + + util$5 = { + getResolveErrorBodyCallback, + isContentTypeApplicationJson, + isContentTypeText + }; + return util$5; +} + +var hasRequiredApiRequest; + +function requireApiRequest () { + if (hasRequiredApiRequest) return apiRequest.exports; + hasRequiredApiRequest = 1; + + const assert = require$$0$4; + const { Readable } = requireReadable(); + const { InvalidArgumentError, RequestAbortedError } = requireErrors(); + const util = requireUtil$7(); + const { getResolveErrorBodyCallback } = requireUtil$5(); + const { AsyncResource } = require$$5$1; + + class RequestHandler extends AsyncResource { + constructor (opts, callback) { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') + } + + const { signal, method, opaque, body, onInfo, responseHeaders, throwOnError, highWaterMark } = opts; + + try { + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } + + if (highWaterMark && (typeof highWaterMark !== 'number' || highWaterMark < 0)) { + throw new InvalidArgumentError('invalid highWaterMark') + } + + if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { + throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') + } + + if (method === 'CONNECT') { + throw new InvalidArgumentError('invalid method') + } + + if (onInfo && typeof onInfo !== 'function') { + throw new InvalidArgumentError('invalid onInfo callback') + } + + super('UNDICI_REQUEST'); + } catch (err) { + if (util.isStream(body)) { + util.destroy(body.on('error', util.nop), err); + } + throw err + } + + this.method = method; + this.responseHeaders = responseHeaders || null; + this.opaque = opaque || null; + this.callback = callback; + this.res = null; + this.abort = null; + this.body = body; + this.trailers = {}; + this.context = null; + this.onInfo = onInfo || null; + this.throwOnError = throwOnError; + this.highWaterMark = highWaterMark; + this.signal = signal; + this.reason = null; + this.removeAbortListener = null; + + if (util.isStream(body)) { + body.on('error', (err) => { + this.onError(err); + }); + } + + if (this.signal) { + if (this.signal.aborted) { + this.reason = this.signal.reason ?? new RequestAbortedError(); + } else { + this.removeAbortListener = util.addAbortListener(this.signal, () => { + this.reason = this.signal.reason ?? new RequestAbortedError(); + if (this.res) { + util.destroy(this.res, this.reason); + } else if (this.abort) { + this.abort(this.reason); + } + + if (this.removeAbortListener) { + this.res?.off('close', this.removeAbortListener); + this.removeAbortListener(); + this.removeAbortListener = null; + } + }); + } + } + } + + onConnect (abort, context) { + if (this.reason) { + abort(this.reason); + return + } + + assert(this.callback); + + this.abort = abort; + this.context = context; + } + + onHeaders (statusCode, rawHeaders, resume, statusMessage) { + const { callback, opaque, abort, context, responseHeaders, highWaterMark } = this; + + const headers = responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders); + + if (statusCode < 200) { + if (this.onInfo) { + this.onInfo({ statusCode, headers }); + } + return + } + + const parsedHeaders = responseHeaders === 'raw' ? util.parseHeaders(rawHeaders) : headers; + const contentType = parsedHeaders['content-type']; + const contentLength = parsedHeaders['content-length']; + const res = new Readable({ + resume, + abort, + contentType, + contentLength: this.method !== 'HEAD' && contentLength + ? Number(contentLength) + : null, + highWaterMark + }); + + if (this.removeAbortListener) { + res.on('close', this.removeAbortListener); + } + + this.callback = null; + this.res = res; + if (callback !== null) { + if (this.throwOnError && statusCode >= 400) { + this.runInAsyncScope(getResolveErrorBodyCallback, null, + { callback, body: res, contentType, statusCode, statusMessage, headers } + ); + } else { + this.runInAsyncScope(callback, null, null, { + statusCode, + headers, + trailers: this.trailers, + opaque, + body: res, + context + }); + } + } + } + + onData (chunk) { + return this.res.push(chunk) + } + + onComplete (trailers) { + util.parseHeaders(trailers, this.trailers); + this.res.push(null); + } + + onError (err) { + const { res, callback, body, opaque } = this; + + if (callback) { + // TODO: Does this need queueMicrotask? + this.callback = null; + queueMicrotask(() => { + this.runInAsyncScope(callback, null, err, { opaque }); + }); + } + + if (res) { + this.res = null; + // Ensure all queued handlers are invoked before destroying res. + queueMicrotask(() => { + util.destroy(res, err); + }); + } + + if (body) { + this.body = null; + util.destroy(body, err); + } + + if (this.removeAbortListener) { + res?.off('close', this.removeAbortListener); + this.removeAbortListener(); + this.removeAbortListener = null; + } + } + } + + function request (opts, callback) { + if (callback === undefined) { + return new Promise((resolve, reject) => { + request.call(this, opts, (err, data) => { + return err ? reject(err) : resolve(data) + }); + }) + } + + try { + this.dispatch(opts, new RequestHandler(opts, callback)); + } catch (err) { + if (typeof callback !== 'function') { + throw err + } + const opaque = opts?.opaque; + queueMicrotask(() => callback(err, { opaque })); + } + } + + apiRequest.exports = request; + apiRequest.exports.RequestHandler = RequestHandler; + return apiRequest.exports; +} + +var abortSignal; +var hasRequiredAbortSignal; + +function requireAbortSignal () { + if (hasRequiredAbortSignal) return abortSignal; + hasRequiredAbortSignal = 1; + const { addAbortListener } = requireUtil$7(); + const { RequestAbortedError } = requireErrors(); + + const kListener = Symbol('kListener'); + const kSignal = Symbol('kSignal'); + + function abort (self) { + if (self.abort) { + self.abort(self[kSignal]?.reason); + } else { + self.reason = self[kSignal]?.reason ?? new RequestAbortedError(); + } + removeSignal(self); + } + + function addSignal (self, signal) { + self.reason = null; + + self[kSignal] = null; + self[kListener] = null; + + if (!signal) { + return + } + + if (signal.aborted) { + abort(self); + return + } + + self[kSignal] = signal; + self[kListener] = () => { + abort(self); + }; + + addAbortListener(self[kSignal], self[kListener]); + } + + function removeSignal (self) { + if (!self[kSignal]) { + return + } + + if ('removeEventListener' in self[kSignal]) { + self[kSignal].removeEventListener('abort', self[kListener]); + } else { + self[kSignal].removeListener('abort', self[kListener]); + } + + self[kSignal] = null; + self[kListener] = null; + } + + abortSignal = { + addSignal, + removeSignal + }; + return abortSignal; +} + +var apiStream; +var hasRequiredApiStream; + +function requireApiStream () { + if (hasRequiredApiStream) return apiStream; + hasRequiredApiStream = 1; + + const assert = require$$0$4; + const { finished, PassThrough } = require$$0$5; + const { InvalidArgumentError, InvalidReturnValueError } = requireErrors(); + const util = requireUtil$7(); + const { getResolveErrorBodyCallback } = requireUtil$5(); + const { AsyncResource } = require$$5$1; + const { addSignal, removeSignal } = requireAbortSignal(); + + class StreamHandler extends AsyncResource { + constructor (opts, factory, callback) { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') + } + + const { signal, method, opaque, body, onInfo, responseHeaders, throwOnError } = opts; + + try { + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } + + if (typeof factory !== 'function') { + throw new InvalidArgumentError('invalid factory') + } + + if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { + throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') + } + + if (method === 'CONNECT') { + throw new InvalidArgumentError('invalid method') + } + + if (onInfo && typeof onInfo !== 'function') { + throw new InvalidArgumentError('invalid onInfo callback') + } + + super('UNDICI_STREAM'); + } catch (err) { + if (util.isStream(body)) { + util.destroy(body.on('error', util.nop), err); + } + throw err + } + + this.responseHeaders = responseHeaders || null; + this.opaque = opaque || null; + this.factory = factory; + this.callback = callback; + this.res = null; + this.abort = null; + this.context = null; + this.trailers = null; + this.body = body; + this.onInfo = onInfo || null; + this.throwOnError = throwOnError || false; + + if (util.isStream(body)) { + body.on('error', (err) => { + this.onError(err); + }); + } + + addSignal(this, signal); + } + + onConnect (abort, context) { + if (this.reason) { + abort(this.reason); + return + } + + assert(this.callback); + + this.abort = abort; + this.context = context; + } + + onHeaders (statusCode, rawHeaders, resume, statusMessage) { + const { factory, opaque, context, callback, responseHeaders } = this; + + const headers = responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders); + + if (statusCode < 200) { + if (this.onInfo) { + this.onInfo({ statusCode, headers }); + } + return + } + + this.factory = null; + + let res; + + if (this.throwOnError && statusCode >= 400) { + const parsedHeaders = responseHeaders === 'raw' ? util.parseHeaders(rawHeaders) : headers; + const contentType = parsedHeaders['content-type']; + res = new PassThrough(); + + this.callback = null; + this.runInAsyncScope(getResolveErrorBodyCallback, null, + { callback, body: res, contentType, statusCode, statusMessage, headers } + ); + } else { + if (factory === null) { + return + } + + res = this.runInAsyncScope(factory, null, { + statusCode, + headers, + opaque, + context + }); + + if ( + !res || + typeof res.write !== 'function' || + typeof res.end !== 'function' || + typeof res.on !== 'function' + ) { + throw new InvalidReturnValueError('expected Writable') + } + + // TODO: Avoid finished. It registers an unnecessary amount of listeners. + finished(res, { readable: false }, (err) => { + const { callback, res, opaque, trailers, abort } = this; + + this.res = null; + if (err || !res.readable) { + util.destroy(res, err); + } + + this.callback = null; + this.runInAsyncScope(callback, null, err || null, { opaque, trailers }); + + if (err) { + abort(); + } + }); + } + + res.on('drain', resume); + + this.res = res; + + const needDrain = res.writableNeedDrain !== undefined + ? res.writableNeedDrain + : res._writableState?.needDrain; + + return needDrain !== true + } + + onData (chunk) { + const { res } = this; + + return res ? res.write(chunk) : true + } + + onComplete (trailers) { + const { res } = this; + + removeSignal(this); + + if (!res) { + return + } + + this.trailers = util.parseHeaders(trailers); + + res.end(); + } + + onError (err) { + const { res, callback, opaque, body } = this; + + removeSignal(this); + + this.factory = null; + + if (res) { + this.res = null; + util.destroy(res, err); + } else if (callback) { + this.callback = null; + queueMicrotask(() => { + this.runInAsyncScope(callback, null, err, { opaque }); + }); + } + + if (body) { + this.body = null; + util.destroy(body, err); + } + } + } + + function stream (opts, factory, callback) { + if (callback === undefined) { + return new Promise((resolve, reject) => { + stream.call(this, opts, factory, (err, data) => { + return err ? reject(err) : resolve(data) + }); + }) + } + + try { + this.dispatch(opts, new StreamHandler(opts, factory, callback)); + } catch (err) { + if (typeof callback !== 'function') { + throw err + } + const opaque = opts?.opaque; + queueMicrotask(() => callback(err, { opaque })); + } + } + + apiStream = stream; + return apiStream; +} + +var apiPipeline; +var hasRequiredApiPipeline; + +function requireApiPipeline () { + if (hasRequiredApiPipeline) return apiPipeline; + hasRequiredApiPipeline = 1; + + const { + Readable, + Duplex, + PassThrough + } = require$$0$5; + const { + InvalidArgumentError, + InvalidReturnValueError, + RequestAbortedError + } = requireErrors(); + const util = requireUtil$7(); + const { AsyncResource } = require$$5$1; + const { addSignal, removeSignal } = requireAbortSignal(); + const assert = require$$0$4; + + const kResume = Symbol('resume'); + + class PipelineRequest extends Readable { + constructor () { + super({ autoDestroy: true }); + + this[kResume] = null; + } + + _read () { + const { [kResume]: resume } = this; + + if (resume) { + this[kResume] = null; + resume(); + } + } + + _destroy (err, callback) { + this._read(); + + callback(err); + } + } + + class PipelineResponse extends Readable { + constructor (resume) { + super({ autoDestroy: true }); + this[kResume] = resume; + } + + _read () { + this[kResume](); + } + + _destroy (err, callback) { + if (!err && !this._readableState.endEmitted) { + err = new RequestAbortedError(); + } + + callback(err); + } + } + + class PipelineHandler extends AsyncResource { + constructor (opts, handler) { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') + } + + if (typeof handler !== 'function') { + throw new InvalidArgumentError('invalid handler') + } + + const { signal, method, opaque, onInfo, responseHeaders } = opts; + + if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { + throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') + } + + if (method === 'CONNECT') { + throw new InvalidArgumentError('invalid method') + } + + if (onInfo && typeof onInfo !== 'function') { + throw new InvalidArgumentError('invalid onInfo callback') + } + + super('UNDICI_PIPELINE'); + + this.opaque = opaque || null; + this.responseHeaders = responseHeaders || null; + this.handler = handler; + this.abort = null; + this.context = null; + this.onInfo = onInfo || null; + + this.req = new PipelineRequest().on('error', util.nop); + + this.ret = new Duplex({ + readableObjectMode: opts.objectMode, + autoDestroy: true, + read: () => { + const { body } = this; + + if (body?.resume) { + body.resume(); + } + }, + write: (chunk, encoding, callback) => { + const { req } = this; + + if (req.push(chunk, encoding) || req._readableState.destroyed) { + callback(); + } else { + req[kResume] = callback; + } + }, + destroy: (err, callback) => { + const { body, req, res, ret, abort } = this; + + if (!err && !ret._readableState.endEmitted) { + err = new RequestAbortedError(); + } + + if (abort && err) { + abort(); + } + + util.destroy(body, err); + util.destroy(req, err); + util.destroy(res, err); + + removeSignal(this); + + callback(err); + } + }).on('prefinish', () => { + const { req } = this; + + // Node < 15 does not call _final in same tick. + req.push(null); + }); + + this.res = null; + + addSignal(this, signal); + } + + onConnect (abort, context) { + const { ret, res } = this; + + if (this.reason) { + abort(this.reason); + return + } + + assert(!res, 'pipeline cannot be retried'); + assert(!ret.destroyed); + + this.abort = abort; + this.context = context; + } + + onHeaders (statusCode, rawHeaders, resume) { + const { opaque, handler, context } = this; + + if (statusCode < 200) { + if (this.onInfo) { + const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders); + this.onInfo({ statusCode, headers }); + } + return + } + + this.res = new PipelineResponse(resume); + + let body; + try { + this.handler = null; + const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders); + body = this.runInAsyncScope(handler, null, { + statusCode, + headers, + opaque, + body: this.res, + context + }); + } catch (err) { + this.res.on('error', util.nop); + throw err + } + + if (!body || typeof body.on !== 'function') { + throw new InvalidReturnValueError('expected Readable') + } + + body + .on('data', (chunk) => { + const { ret, body } = this; + + if (!ret.push(chunk) && body.pause) { + body.pause(); + } + }) + .on('error', (err) => { + const { ret } = this; + + util.destroy(ret, err); + }) + .on('end', () => { + const { ret } = this; + + ret.push(null); + }) + .on('close', () => { + const { ret } = this; + + if (!ret._readableState.ended) { + util.destroy(ret, new RequestAbortedError()); + } + }); + + this.body = body; + } + + onData (chunk) { + const { res } = this; + return res.push(chunk) + } + + onComplete (trailers) { + const { res } = this; + res.push(null); + } + + onError (err) { + const { ret } = this; + this.handler = null; + util.destroy(ret, err); + } + } + + function pipeline (opts, handler) { + try { + const pipelineHandler = new PipelineHandler(opts, handler); + this.dispatch({ ...opts, body: pipelineHandler.req }, pipelineHandler); + return pipelineHandler.ret + } catch (err) { + return new PassThrough().destroy(err) + } + } + + apiPipeline = pipeline; + return apiPipeline; +} + +var apiUpgrade; +var hasRequiredApiUpgrade; + +function requireApiUpgrade () { + if (hasRequiredApiUpgrade) return apiUpgrade; + hasRequiredApiUpgrade = 1; + + const { InvalidArgumentError, SocketError } = requireErrors(); + const { AsyncResource } = require$$5$1; + const util = requireUtil$7(); + const { addSignal, removeSignal } = requireAbortSignal(); + const assert = require$$0$4; + + class UpgradeHandler extends AsyncResource { + constructor (opts, callback) { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') + } + + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } + + const { signal, opaque, responseHeaders } = opts; + + if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { + throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') + } + + super('UNDICI_UPGRADE'); + + this.responseHeaders = responseHeaders || null; + this.opaque = opaque || null; + this.callback = callback; + this.abort = null; + this.context = null; + + addSignal(this, signal); + } + + onConnect (abort, context) { + if (this.reason) { + abort(this.reason); + return + } + + assert(this.callback); + + this.abort = abort; + this.context = null; + } + + onHeaders () { + throw new SocketError('bad upgrade', null) + } + + onUpgrade (statusCode, rawHeaders, socket) { + const { callback, opaque, context } = this; + + assert.strictEqual(statusCode, 101); + + removeSignal(this); + + this.callback = null; + const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders); + this.runInAsyncScope(callback, null, null, { + headers, + socket, + opaque, + context + }); + } + + onError (err) { + const { callback, opaque } = this; + + removeSignal(this); + + if (callback) { + this.callback = null; + queueMicrotask(() => { + this.runInAsyncScope(callback, null, err, { opaque }); + }); + } + } + } + + function upgrade (opts, callback) { + if (callback === undefined) { + return new Promise((resolve, reject) => { + upgrade.call(this, opts, (err, data) => { + return err ? reject(err) : resolve(data) + }); + }) + } + + try { + const upgradeHandler = new UpgradeHandler(opts, callback); + this.dispatch({ + ...opts, + method: opts.method || 'GET', + upgrade: opts.protocol || 'Websocket' + }, upgradeHandler); + } catch (err) { + if (typeof callback !== 'function') { + throw err + } + const opaque = opts?.opaque; + queueMicrotask(() => callback(err, { opaque })); + } + } + + apiUpgrade = upgrade; + return apiUpgrade; +} + +var apiConnect; +var hasRequiredApiConnect; + +function requireApiConnect () { + if (hasRequiredApiConnect) return apiConnect; + hasRequiredApiConnect = 1; + + const assert = require$$0$4; + const { AsyncResource } = require$$5$1; + const { InvalidArgumentError, SocketError } = requireErrors(); + const util = requireUtil$7(); + const { addSignal, removeSignal } = requireAbortSignal(); + + class ConnectHandler extends AsyncResource { + constructor (opts, callback) { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') + } + + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } + + const { signal, opaque, responseHeaders } = opts; + + if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { + throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') + } + + super('UNDICI_CONNECT'); + + this.opaque = opaque || null; + this.responseHeaders = responseHeaders || null; + this.callback = callback; + this.abort = null; + + addSignal(this, signal); + } + + onConnect (abort, context) { + if (this.reason) { + abort(this.reason); + return + } + + assert(this.callback); + + this.abort = abort; + this.context = context; + } + + onHeaders () { + throw new SocketError('bad connect', null) + } + + onUpgrade (statusCode, rawHeaders, socket) { + const { callback, opaque, context } = this; + + removeSignal(this); + + this.callback = null; + + let headers = rawHeaders; + // Indicates is an HTTP2Session + if (headers != null) { + headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders); + } + + this.runInAsyncScope(callback, null, null, { + statusCode, + headers, + socket, + opaque, + context + }); + } + + onError (err) { + const { callback, opaque } = this; + + removeSignal(this); + + if (callback) { + this.callback = null; + queueMicrotask(() => { + this.runInAsyncScope(callback, null, err, { opaque }); + }); + } + } + } + + function connect (opts, callback) { + if (callback === undefined) { + return new Promise((resolve, reject) => { + connect.call(this, opts, (err, data) => { + return err ? reject(err) : resolve(data) + }); + }) + } + + try { + const connectHandler = new ConnectHandler(opts, callback); + this.dispatch({ ...opts, method: 'CONNECT' }, connectHandler); + } catch (err) { + if (typeof callback !== 'function') { + throw err + } + const opaque = opts?.opaque; + queueMicrotask(() => callback(err, { opaque })); + } + } + + apiConnect = connect; + return apiConnect; +} + +var hasRequiredApi; + +function requireApi () { + if (hasRequiredApi) return api; + hasRequiredApi = 1; + + api.request = requireApiRequest(); + api.stream = requireApiStream(); + api.pipeline = requireApiPipeline(); + api.upgrade = requireApiUpgrade(); + api.connect = requireApiConnect(); + return api; +} + +var mockErrors; +var hasRequiredMockErrors; + +function requireMockErrors () { + if (hasRequiredMockErrors) return mockErrors; + hasRequiredMockErrors = 1; + + const { UndiciError } = requireErrors(); + + class MockNotMatchedError extends UndiciError { + constructor (message) { + super(message); + Error.captureStackTrace(this, MockNotMatchedError); + this.name = 'MockNotMatchedError'; + this.message = message || 'The request does not match any registered mock dispatches'; + this.code = 'UND_MOCK_ERR_MOCK_NOT_MATCHED'; + } + } + + mockErrors = { + MockNotMatchedError + }; + return mockErrors; +} + +var mockSymbols; +var hasRequiredMockSymbols; + +function requireMockSymbols () { + if (hasRequiredMockSymbols) return mockSymbols; + hasRequiredMockSymbols = 1; + + mockSymbols = { + kAgent: Symbol('agent'), + kOptions: Symbol('options'), + kFactory: Symbol('factory'), + kDispatches: Symbol('dispatches'), + kDispatchKey: Symbol('dispatch key'), + kDefaultHeaders: Symbol('default headers'), + kDefaultTrailers: Symbol('default trailers'), + kContentLength: Symbol('content length'), + kMockAgent: Symbol('mock agent'), + kMockAgentSet: Symbol('mock agent set'), + kMockAgentGet: Symbol('mock agent get'), + kMockDispatch: Symbol('mock dispatch'), + kClose: Symbol('close'), + kOriginalClose: Symbol('original agent close'), + kOrigin: Symbol('origin'), + kIsMockActive: Symbol('is mock active'), + kNetConnect: Symbol('net connect'), + kGetNetConnect: Symbol('get net connect'), + kConnected: Symbol('connected') + }; + return mockSymbols; +} + +var mockUtils; +var hasRequiredMockUtils; + +function requireMockUtils () { + if (hasRequiredMockUtils) return mockUtils; + hasRequiredMockUtils = 1; + + const { MockNotMatchedError } = requireMockErrors(); + const { + kDispatches, + kMockAgent, + kOriginalDispatch, + kOrigin, + kGetNetConnect + } = requireMockSymbols(); + const { buildURL } = requireUtil$7(); + const { STATUS_CODES } = require$$2; + const { + types: { + isPromise + } + } = require$$0$6; + + function matchValue (match, value) { + if (typeof match === 'string') { + return match === value + } + if (match instanceof RegExp) { + return match.test(value) + } + if (typeof match === 'function') { + return match(value) === true + } + return false + } + + function lowerCaseEntries (headers) { + return Object.fromEntries( + Object.entries(headers).map(([headerName, headerValue]) => { + return [headerName.toLocaleLowerCase(), headerValue] + }) + ) + } + + /** + * @param {import('../../index').Headers|string[]|Record} headers + * @param {string} key + */ + function getHeaderByName (headers, key) { + if (Array.isArray(headers)) { + for (let i = 0; i < headers.length; i += 2) { + if (headers[i].toLocaleLowerCase() === key.toLocaleLowerCase()) { + return headers[i + 1] + } + } + + return undefined + } else if (typeof headers.get === 'function') { + return headers.get(key) + } else { + return lowerCaseEntries(headers)[key.toLocaleLowerCase()] + } + } + + /** @param {string[]} headers */ + function buildHeadersFromArray (headers) { // fetch HeadersList + const clone = headers.slice(); + const entries = []; + for (let index = 0; index < clone.length; index += 2) { + entries.push([clone[index], clone[index + 1]]); + } + return Object.fromEntries(entries) + } + + function matchHeaders (mockDispatch, headers) { + if (typeof mockDispatch.headers === 'function') { + if (Array.isArray(headers)) { // fetch HeadersList + headers = buildHeadersFromArray(headers); + } + return mockDispatch.headers(headers ? lowerCaseEntries(headers) : {}) + } + if (typeof mockDispatch.headers === 'undefined') { + return true + } + if (typeof headers !== 'object' || typeof mockDispatch.headers !== 'object') { + return false + } + + for (const [matchHeaderName, matchHeaderValue] of Object.entries(mockDispatch.headers)) { + const headerValue = getHeaderByName(headers, matchHeaderName); + + if (!matchValue(matchHeaderValue, headerValue)) { + return false + } + } + return true + } + + function safeUrl (path) { + if (typeof path !== 'string') { + return path + } + + const pathSegments = path.split('?'); + + if (pathSegments.length !== 2) { + return path + } + + const qp = new URLSearchParams(pathSegments.pop()); + qp.sort(); + return [...pathSegments, qp.toString()].join('?') + } + + function matchKey (mockDispatch, { path, method, body, headers }) { + const pathMatch = matchValue(mockDispatch.path, path); + const methodMatch = matchValue(mockDispatch.method, method); + const bodyMatch = typeof mockDispatch.body !== 'undefined' ? matchValue(mockDispatch.body, body) : true; + const headersMatch = matchHeaders(mockDispatch, headers); + return pathMatch && methodMatch && bodyMatch && headersMatch + } + + function getResponseData (data) { + if (Buffer.isBuffer(data)) { + return data + } else if (typeof data === 'object') { + return JSON.stringify(data) + } else { + return data.toString() + } + } + + function getMockDispatch (mockDispatches, key) { + const basePath = key.query ? buildURL(key.path, key.query) : key.path; + const resolvedPath = typeof basePath === 'string' ? safeUrl(basePath) : basePath; + + // Match path + let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path }) => matchValue(safeUrl(path), resolvedPath)); + if (matchedMockDispatches.length === 0) { + throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`) + } + + // Match method + matchedMockDispatches = matchedMockDispatches.filter(({ method }) => matchValue(method, key.method)); + if (matchedMockDispatches.length === 0) { + throw new MockNotMatchedError(`Mock dispatch not matched for method '${key.method}' on path '${resolvedPath}'`) + } + + // Match body + matchedMockDispatches = matchedMockDispatches.filter(({ body }) => typeof body !== 'undefined' ? matchValue(body, key.body) : true); + if (matchedMockDispatches.length === 0) { + throw new MockNotMatchedError(`Mock dispatch not matched for body '${key.body}' on path '${resolvedPath}'`) + } + + // Match headers + matchedMockDispatches = matchedMockDispatches.filter((mockDispatch) => matchHeaders(mockDispatch, key.headers)); + if (matchedMockDispatches.length === 0) { + const headers = typeof key.headers === 'object' ? JSON.stringify(key.headers) : key.headers; + throw new MockNotMatchedError(`Mock dispatch not matched for headers '${headers}' on path '${resolvedPath}'`) + } + + return matchedMockDispatches[0] + } + + function addMockDispatch (mockDispatches, key, data) { + const baseData = { timesInvoked: 0, times: 1, persist: false, consumed: false }; + const replyData = typeof data === 'function' ? { callback: data } : { ...data }; + const newMockDispatch = { ...baseData, ...key, pending: true, data: { error: null, ...replyData } }; + mockDispatches.push(newMockDispatch); + return newMockDispatch + } + + function deleteMockDispatch (mockDispatches, key) { + const index = mockDispatches.findIndex(dispatch => { + if (!dispatch.consumed) { + return false + } + return matchKey(dispatch, key) + }); + if (index !== -1) { + mockDispatches.splice(index, 1); + } + } + + function buildKey (opts) { + const { path, method, body, headers, query } = opts; + return { + path, + method, + body, + headers, + query + } + } + + function generateKeyValues (data) { + const keys = Object.keys(data); + const result = []; + for (let i = 0; i < keys.length; ++i) { + const key = keys[i]; + const value = data[key]; + const name = Buffer.from(`${key}`); + if (Array.isArray(value)) { + for (let j = 0; j < value.length; ++j) { + result.push(name, Buffer.from(`${value[j]}`)); + } + } else { + result.push(name, Buffer.from(`${value}`)); + } + } + return result + } + + /** + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status + * @param {number} statusCode + */ + function getStatusText (statusCode) { + return STATUS_CODES[statusCode] || 'unknown' + } + + async function getResponse (body) { + const buffers = []; + for await (const data of body) { + buffers.push(data); + } + return Buffer.concat(buffers).toString('utf8') + } + + /** + * Mock dispatch function used to simulate undici dispatches + */ + function mockDispatch (opts, handler) { + // Get mock dispatch from built key + const key = buildKey(opts); + const mockDispatch = getMockDispatch(this[kDispatches], key); + + mockDispatch.timesInvoked++; + + // Here's where we resolve a callback if a callback is present for the dispatch data. + if (mockDispatch.data.callback) { + mockDispatch.data = { ...mockDispatch.data, ...mockDispatch.data.callback(opts) }; + } + + // Parse mockDispatch data + const { data: { statusCode, data, headers, trailers, error }, delay, persist } = mockDispatch; + const { timesInvoked, times } = mockDispatch; + + // If it's used up and not persistent, mark as consumed + mockDispatch.consumed = !persist && timesInvoked >= times; + mockDispatch.pending = timesInvoked < times; + + // If specified, trigger dispatch error + if (error !== null) { + deleteMockDispatch(this[kDispatches], key); + handler.onError(error); + return true + } + + // Handle the request with a delay if necessary + if (typeof delay === 'number' && delay > 0) { + setTimeout(() => { + handleReply(this[kDispatches]); + }, delay); + } else { + handleReply(this[kDispatches]); + } + + function handleReply (mockDispatches, _data = data) { + // fetch's HeadersList is a 1D string array + const optsHeaders = Array.isArray(opts.headers) + ? buildHeadersFromArray(opts.headers) + : opts.headers; + const body = typeof _data === 'function' + ? _data({ ...opts, headers: optsHeaders }) + : _data; + + // util.types.isPromise is likely needed for jest. + if (isPromise(body)) { + // If handleReply is asynchronous, throwing an error + // in the callback will reject the promise, rather than + // synchronously throw the error, which breaks some tests. + // Rather, we wait for the callback to resolve if it is a + // promise, and then re-run handleReply with the new body. + body.then((newData) => handleReply(mockDispatches, newData)); + return + } + + const responseData = getResponseData(body); + const responseHeaders = generateKeyValues(headers); + const responseTrailers = generateKeyValues(trailers); + + handler.onConnect?.(err => handler.onError(err), null); + handler.onHeaders?.(statusCode, responseHeaders, resume, getStatusText(statusCode)); + handler.onData?.(Buffer.from(responseData)); + handler.onComplete?.(responseTrailers); + deleteMockDispatch(mockDispatches, key); + } + + function resume () {} + + return true + } + + function buildMockDispatch () { + const agent = this[kMockAgent]; + const origin = this[kOrigin]; + const originalDispatch = this[kOriginalDispatch]; + + return function dispatch (opts, handler) { + if (agent.isMockActive) { + try { + mockDispatch.call(this, opts, handler); + } catch (error) { + if (error instanceof MockNotMatchedError) { + const netConnect = agent[kGetNetConnect](); + if (netConnect === false) { + throw new MockNotMatchedError(`${error.message}: subsequent request to origin ${origin} was not allowed (net.connect disabled)`) + } + if (checkNetConnect(netConnect, origin)) { + originalDispatch.call(this, opts, handler); + } else { + throw new MockNotMatchedError(`${error.message}: subsequent request to origin ${origin} was not allowed (net.connect is not enabled for this origin)`) + } + } else { + throw error + } + } + } else { + originalDispatch.call(this, opts, handler); + } + } + } + + function checkNetConnect (netConnect, origin) { + const url = new URL(origin); + if (netConnect === true) { + return true + } else if (Array.isArray(netConnect) && netConnect.some((matcher) => matchValue(matcher, url.host))) { + return true + } + return false + } + + function buildMockOptions (opts) { + if (opts) { + const { agent, ...mockOptions } = opts; + return mockOptions + } + } + + mockUtils = { + getResponseData, + getMockDispatch, + addMockDispatch, + deleteMockDispatch, + buildKey, + generateKeyValues, + matchValue, + getResponse, + getStatusText, + mockDispatch, + buildMockDispatch, + checkNetConnect, + buildMockOptions, + getHeaderByName, + buildHeadersFromArray + }; + return mockUtils; +} + +var mockInterceptor = {}; + +var hasRequiredMockInterceptor; + +function requireMockInterceptor () { + if (hasRequiredMockInterceptor) return mockInterceptor; + hasRequiredMockInterceptor = 1; + + const { getResponseData, buildKey, addMockDispatch } = requireMockUtils(); + const { + kDispatches, + kDispatchKey, + kDefaultHeaders, + kDefaultTrailers, + kContentLength, + kMockDispatch + } = requireMockSymbols(); + const { InvalidArgumentError } = requireErrors(); + const { buildURL } = requireUtil$7(); + + /** + * Defines the scope API for an interceptor reply + */ + class MockScope { + constructor (mockDispatch) { + this[kMockDispatch] = mockDispatch; + } + + /** + * Delay a reply by a set amount in ms. + */ + delay (waitInMs) { + if (typeof waitInMs !== 'number' || !Number.isInteger(waitInMs) || waitInMs <= 0) { + throw new InvalidArgumentError('waitInMs must be a valid integer > 0') + } + + this[kMockDispatch].delay = waitInMs; + return this + } + + /** + * For a defined reply, never mark as consumed. + */ + persist () { + this[kMockDispatch].persist = true; + return this + } + + /** + * Allow one to define a reply for a set amount of matching requests. + */ + times (repeatTimes) { + if (typeof repeatTimes !== 'number' || !Number.isInteger(repeatTimes) || repeatTimes <= 0) { + throw new InvalidArgumentError('repeatTimes must be a valid integer > 0') + } + + this[kMockDispatch].times = repeatTimes; + return this + } + } + + /** + * Defines an interceptor for a Mock + */ + class MockInterceptor { + constructor (opts, mockDispatches) { + if (typeof opts !== 'object') { + throw new InvalidArgumentError('opts must be an object') + } + if (typeof opts.path === 'undefined') { + throw new InvalidArgumentError('opts.path must be defined') + } + if (typeof opts.method === 'undefined') { + opts.method = 'GET'; + } + // See https://github.com/nodejs/undici/issues/1245 + // As per RFC 3986, clients are not supposed to send URI + // fragments to servers when they retrieve a document, + if (typeof opts.path === 'string') { + if (opts.query) { + opts.path = buildURL(opts.path, opts.query); + } else { + // Matches https://github.com/nodejs/undici/blob/main/lib/web/fetch/index.js#L1811 + const parsedURL = new URL(opts.path, 'data://'); + opts.path = parsedURL.pathname + parsedURL.search; + } + } + if (typeof opts.method === 'string') { + opts.method = opts.method.toUpperCase(); + } + + this[kDispatchKey] = buildKey(opts); + this[kDispatches] = mockDispatches; + this[kDefaultHeaders] = {}; + this[kDefaultTrailers] = {}; + this[kContentLength] = false; + } + + createMockScopeDispatchData ({ statusCode, data, responseOptions }) { + const responseData = getResponseData(data); + const contentLength = this[kContentLength] ? { 'content-length': responseData.length } : {}; + const headers = { ...this[kDefaultHeaders], ...contentLength, ...responseOptions.headers }; + const trailers = { ...this[kDefaultTrailers], ...responseOptions.trailers }; + + return { statusCode, data, headers, trailers } + } + + validateReplyParameters (replyParameters) { + if (typeof replyParameters.statusCode === 'undefined') { + throw new InvalidArgumentError('statusCode must be defined') + } + if (typeof replyParameters.responseOptions !== 'object' || replyParameters.responseOptions === null) { + throw new InvalidArgumentError('responseOptions must be an object') + } + } + + /** + * Mock an undici request with a defined reply. + */ + reply (replyOptionsCallbackOrStatusCode) { + // Values of reply aren't available right now as they + // can only be available when the reply callback is invoked. + if (typeof replyOptionsCallbackOrStatusCode === 'function') { + // We'll first wrap the provided callback in another function, + // this function will properly resolve the data from the callback + // when invoked. + const wrappedDefaultsCallback = (opts) => { + // Our reply options callback contains the parameter for statusCode, data and options. + const resolvedData = replyOptionsCallbackOrStatusCode(opts); + + // Check if it is in the right format + if (typeof resolvedData !== 'object' || resolvedData === null) { + throw new InvalidArgumentError('reply options callback must return an object') + } + + const replyParameters = { data: '', responseOptions: {}, ...resolvedData }; + this.validateReplyParameters(replyParameters); + // Since the values can be obtained immediately we return them + // from this higher order function that will be resolved later. + return { + ...this.createMockScopeDispatchData(replyParameters) + } + }; + + // Add usual dispatch data, but this time set the data parameter to function that will eventually provide data. + const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], wrappedDefaultsCallback); + return new MockScope(newMockDispatch) + } + + // We can have either one or three parameters, if we get here, + // we should have 1-3 parameters. So we spread the arguments of + // this function to obtain the parameters, since replyData will always + // just be the statusCode. + const replyParameters = { + statusCode: replyOptionsCallbackOrStatusCode, + data: arguments[1] === undefined ? '' : arguments[1], + responseOptions: arguments[2] === undefined ? {} : arguments[2] + }; + this.validateReplyParameters(replyParameters); + + // Send in-already provided data like usual + const dispatchData = this.createMockScopeDispatchData(replyParameters); + const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], dispatchData); + return new MockScope(newMockDispatch) + } + + /** + * Mock an undici request with a defined error. + */ + replyWithError (error) { + if (typeof error === 'undefined') { + throw new InvalidArgumentError('error must be defined') + } + + const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], { error }); + return new MockScope(newMockDispatch) + } + + /** + * Set default reply headers on the interceptor for subsequent replies + */ + defaultReplyHeaders (headers) { + if (typeof headers === 'undefined') { + throw new InvalidArgumentError('headers must be defined') + } + + this[kDefaultHeaders] = headers; + return this + } + + /** + * Set default reply trailers on the interceptor for subsequent replies + */ + defaultReplyTrailers (trailers) { + if (typeof trailers === 'undefined') { + throw new InvalidArgumentError('trailers must be defined') + } + + this[kDefaultTrailers] = trailers; + return this + } + + /** + * Set reply content length header for replies on the interceptor + */ + replyContentLength () { + this[kContentLength] = true; + return this + } + } + + mockInterceptor.MockInterceptor = MockInterceptor; + mockInterceptor.MockScope = MockScope; + return mockInterceptor; +} + +var mockClient; +var hasRequiredMockClient; + +function requireMockClient () { + if (hasRequiredMockClient) return mockClient; + hasRequiredMockClient = 1; + + const { promisify } = require$$0$6; + const Client = requireClient(); + const { buildMockDispatch } = requireMockUtils(); + const { + kDispatches, + kMockAgent, + kClose, + kOriginalClose, + kOrigin, + kOriginalDispatch, + kConnected + } = requireMockSymbols(); + const { MockInterceptor } = requireMockInterceptor(); + const Symbols = requireSymbols$4(); + const { InvalidArgumentError } = requireErrors(); + + /** + * MockClient provides an API that extends the Client to influence the mockDispatches. + */ + class MockClient extends Client { + constructor (origin, opts) { + super(origin, opts); + + if (!opts || !opts.agent || typeof opts.agent.dispatch !== 'function') { + throw new InvalidArgumentError('Argument opts.agent must implement Agent') + } + + this[kMockAgent] = opts.agent; + this[kOrigin] = origin; + this[kDispatches] = []; + this[kConnected] = 1; + this[kOriginalDispatch] = this.dispatch; + this[kOriginalClose] = this.close.bind(this); + + this.dispatch = buildMockDispatch.call(this); + this.close = this[kClose]; + } + + get [Symbols.kConnected] () { + return this[kConnected] + } + + /** + * Sets up the base interceptor for mocking replies from undici. + */ + intercept (opts) { + return new MockInterceptor(opts, this[kDispatches]) + } + + async [kClose] () { + await promisify(this[kOriginalClose])(); + this[kConnected] = 0; + this[kMockAgent][Symbols.kClients].delete(this[kOrigin]); + } + } + + mockClient = MockClient; + return mockClient; +} + +var mockPool; +var hasRequiredMockPool; + +function requireMockPool () { + if (hasRequiredMockPool) return mockPool; + hasRequiredMockPool = 1; + + const { promisify } = require$$0$6; + const Pool = requirePool(); + const { buildMockDispatch } = requireMockUtils(); + const { + kDispatches, + kMockAgent, + kClose, + kOriginalClose, + kOrigin, + kOriginalDispatch, + kConnected + } = requireMockSymbols(); + const { MockInterceptor } = requireMockInterceptor(); + const Symbols = requireSymbols$4(); + const { InvalidArgumentError } = requireErrors(); + + /** + * MockPool provides an API that extends the Pool to influence the mockDispatches. + */ + class MockPool extends Pool { + constructor (origin, opts) { + super(origin, opts); + + if (!opts || !opts.agent || typeof opts.agent.dispatch !== 'function') { + throw new InvalidArgumentError('Argument opts.agent must implement Agent') + } + + this[kMockAgent] = opts.agent; + this[kOrigin] = origin; + this[kDispatches] = []; + this[kConnected] = 1; + this[kOriginalDispatch] = this.dispatch; + this[kOriginalClose] = this.close.bind(this); + + this.dispatch = buildMockDispatch.call(this); + this.close = this[kClose]; + } + + get [Symbols.kConnected] () { + return this[kConnected] + } + + /** + * Sets up the base interceptor for mocking replies from undici. + */ + intercept (opts) { + return new MockInterceptor(opts, this[kDispatches]) + } + + async [kClose] () { + await promisify(this[kOriginalClose])(); + this[kConnected] = 0; + this[kMockAgent][Symbols.kClients].delete(this[kOrigin]); + } + } + + mockPool = MockPool; + return mockPool; +} + +var pluralizer; +var hasRequiredPluralizer; + +function requirePluralizer () { + if (hasRequiredPluralizer) return pluralizer; + hasRequiredPluralizer = 1; + + const singulars = { + pronoun: 'it', + is: 'is', + was: 'was', + this: 'this' + }; + + const plurals = { + pronoun: 'they', + is: 'are', + was: 'were', + this: 'these' + }; + + pluralizer = class Pluralizer { + constructor (singular, plural) { + this.singular = singular; + this.plural = plural; + } + + pluralize (count) { + const one = count === 1; + const keys = one ? singulars : plurals; + const noun = one ? this.singular : this.plural; + return { ...keys, count, noun } + } + }; + return pluralizer; +} + +var pendingInterceptorsFormatter; +var hasRequiredPendingInterceptorsFormatter; + +function requirePendingInterceptorsFormatter () { + if (hasRequiredPendingInterceptorsFormatter) return pendingInterceptorsFormatter; + hasRequiredPendingInterceptorsFormatter = 1; + + const { Transform } = require$$0$5; + const { Console } = require$$1$1; + + const PERSISTENT = process.versions.icu ? '✅' : 'Y '; + const NOT_PERSISTENT = process.versions.icu ? '❌' : 'N '; + + /** + * Gets the output of `console.table(…)` as a string. + */ + pendingInterceptorsFormatter = class PendingInterceptorsFormatter { + constructor ({ disableColors } = {}) { + this.transform = new Transform({ + transform (chunk, _enc, cb) { + cb(null, chunk); + } + }); + + this.logger = new Console({ + stdout: this.transform, + inspectOptions: { + colors: !disableColors && !process.env.CI + } + }); + } + + format (pendingInterceptors) { + const withPrettyHeaders = pendingInterceptors.map( + ({ method, path, data: { statusCode }, persist, times, timesInvoked, origin }) => ({ + Method: method, + Origin: origin, + Path: path, + 'Status code': statusCode, + Persistent: persist ? PERSISTENT : NOT_PERSISTENT, + Invocations: timesInvoked, + Remaining: persist ? Infinity : times - timesInvoked + })); + + this.logger.table(withPrettyHeaders); + return this.transform.read().toString() + } + }; + return pendingInterceptorsFormatter; +} + +var mockAgent; +var hasRequiredMockAgent; + +function requireMockAgent () { + if (hasRequiredMockAgent) return mockAgent; + hasRequiredMockAgent = 1; + + const { kClients } = requireSymbols$4(); + const Agent = requireAgent(); + const { + kAgent, + kMockAgentSet, + kMockAgentGet, + kDispatches, + kIsMockActive, + kNetConnect, + kGetNetConnect, + kOptions, + kFactory + } = requireMockSymbols(); + const MockClient = requireMockClient(); + const MockPool = requireMockPool(); + const { matchValue, buildMockOptions } = requireMockUtils(); + const { InvalidArgumentError, UndiciError } = requireErrors(); + const Dispatcher = requireDispatcher(); + const Pluralizer = requirePluralizer(); + const PendingInterceptorsFormatter = requirePendingInterceptorsFormatter(); + + class MockAgent extends Dispatcher { + constructor (opts) { + super(opts); + + this[kNetConnect] = true; + this[kIsMockActive] = true; + + // Instantiate Agent and encapsulate + if ((opts?.agent && typeof opts.agent.dispatch !== 'function')) { + throw new InvalidArgumentError('Argument opts.agent must implement Agent') + } + const agent = opts?.agent ? opts.agent : new Agent(opts); + this[kAgent] = agent; + + this[kClients] = agent[kClients]; + this[kOptions] = buildMockOptions(opts); + } + + get (origin) { + let dispatcher = this[kMockAgentGet](origin); + + if (!dispatcher) { + dispatcher = this[kFactory](origin); + this[kMockAgentSet](origin, dispatcher); + } + return dispatcher + } + + dispatch (opts, handler) { + // Call MockAgent.get to perform additional setup before dispatching as normal + this.get(opts.origin); + return this[kAgent].dispatch(opts, handler) + } + + async close () { + await this[kAgent].close(); + this[kClients].clear(); + } + + deactivate () { + this[kIsMockActive] = false; + } + + activate () { + this[kIsMockActive] = true; + } + + enableNetConnect (matcher) { + if (typeof matcher === 'string' || typeof matcher === 'function' || matcher instanceof RegExp) { + if (Array.isArray(this[kNetConnect])) { + this[kNetConnect].push(matcher); + } else { + this[kNetConnect] = [matcher]; + } + } else if (typeof matcher === 'undefined') { + this[kNetConnect] = true; + } else { + throw new InvalidArgumentError('Unsupported matcher. Must be one of String|Function|RegExp.') + } + } + + disableNetConnect () { + this[kNetConnect] = false; + } + + // This is required to bypass issues caused by using global symbols - see: + // https://github.com/nodejs/undici/issues/1447 + get isMockActive () { + return this[kIsMockActive] + } + + [kMockAgentSet] (origin, dispatcher) { + this[kClients].set(origin, dispatcher); + } + + [kFactory] (origin) { + const mockOptions = Object.assign({ agent: this }, this[kOptions]); + return this[kOptions] && this[kOptions].connections === 1 + ? new MockClient(origin, mockOptions) + : new MockPool(origin, mockOptions) + } + + [kMockAgentGet] (origin) { + // First check if we can immediately find it + const client = this[kClients].get(origin); + if (client) { + return client + } + + // If the origin is not a string create a dummy parent pool and return to user + if (typeof origin !== 'string') { + const dispatcher = this[kFactory]('http://localhost:9999'); + this[kMockAgentSet](origin, dispatcher); + return dispatcher + } + + // If we match, create a pool and assign the same dispatches + for (const [keyMatcher, nonExplicitDispatcher] of Array.from(this[kClients])) { + if (nonExplicitDispatcher && typeof keyMatcher !== 'string' && matchValue(keyMatcher, origin)) { + const dispatcher = this[kFactory](origin); + this[kMockAgentSet](origin, dispatcher); + dispatcher[kDispatches] = nonExplicitDispatcher[kDispatches]; + return dispatcher + } + } + } + + [kGetNetConnect] () { + return this[kNetConnect] + } + + pendingInterceptors () { + const mockAgentClients = this[kClients]; + + return Array.from(mockAgentClients.entries()) + .flatMap(([origin, scope]) => scope[kDispatches].map(dispatch => ({ ...dispatch, origin }))) + .filter(({ pending }) => pending) + } + + assertNoPendingInterceptors ({ pendingInterceptorsFormatter = new PendingInterceptorsFormatter() } = {}) { + const pending = this.pendingInterceptors(); + + if (pending.length === 0) { + return + } + + const pluralizer = new Pluralizer('interceptor', 'interceptors').pluralize(pending.length); + + throw new UndiciError(` +${pluralizer.count} ${pluralizer.noun} ${pluralizer.is} pending: + +${pendingInterceptorsFormatter.format(pending)} +`.trim()) + } + } + + mockAgent = MockAgent; + return mockAgent; +} + +var global$1; +var hasRequiredGlobal; + +function requireGlobal () { + if (hasRequiredGlobal) return global$1; + hasRequiredGlobal = 1; + + // We include a version number for the Dispatcher API. In case of breaking changes, + // this version number must be increased to avoid conflicts. + const globalDispatcher = Symbol.for('undici.globalDispatcher.1'); + const { InvalidArgumentError } = requireErrors(); + const Agent = requireAgent(); + + if (getGlobalDispatcher() === undefined) { + setGlobalDispatcher(new Agent()); + } + + function setGlobalDispatcher (agent) { + if (!agent || typeof agent.dispatch !== 'function') { + throw new InvalidArgumentError('Argument agent must implement Agent') + } + Object.defineProperty(globalThis, globalDispatcher, { + value: agent, + writable: true, + enumerable: false, + configurable: false + }); + } + + function getGlobalDispatcher () { + return globalThis[globalDispatcher] + } + + global$1 = { + setGlobalDispatcher, + getGlobalDispatcher + }; + return global$1; +} + +var decoratorHandler; +var hasRequiredDecoratorHandler; + +function requireDecoratorHandler () { + if (hasRequiredDecoratorHandler) return decoratorHandler; + hasRequiredDecoratorHandler = 1; + + decoratorHandler = class DecoratorHandler { + #handler + + constructor (handler) { + if (typeof handler !== 'object' || handler === null) { + throw new TypeError('handler must be an object') + } + this.#handler = handler; + } + + onConnect (...args) { + return this.#handler.onConnect?.(...args) + } + + onError (...args) { + return this.#handler.onError?.(...args) + } + + onUpgrade (...args) { + return this.#handler.onUpgrade?.(...args) + } + + onResponseStarted (...args) { + return this.#handler.onResponseStarted?.(...args) + } + + onHeaders (...args) { + return this.#handler.onHeaders?.(...args) + } + + onData (...args) { + return this.#handler.onData?.(...args) + } + + onComplete (...args) { + return this.#handler.onComplete?.(...args) + } + + onBodySent (...args) { + return this.#handler.onBodySent?.(...args) + } + }; + return decoratorHandler; +} + +var redirect; +var hasRequiredRedirect; + +function requireRedirect () { + if (hasRequiredRedirect) return redirect; + hasRequiredRedirect = 1; + const RedirectHandler = requireRedirectHandler(); + + redirect = opts => { + const globalMaxRedirections = opts?.maxRedirections; + return dispatch => { + return function redirectInterceptor (opts, handler) { + const { maxRedirections = globalMaxRedirections, ...baseOpts } = opts; + + if (!maxRedirections) { + return dispatch(opts, handler) + } + + const redirectHandler = new RedirectHandler( + dispatch, + maxRedirections, + opts, + handler + ); + + return dispatch(baseOpts, redirectHandler) + } + } + }; + return redirect; +} + +var retry; +var hasRequiredRetry; + +function requireRetry () { + if (hasRequiredRetry) return retry; + hasRequiredRetry = 1; + const RetryHandler = requireRetryHandler(); + + retry = globalOpts => { + return dispatch => { + return function retryInterceptor (opts, handler) { + return dispatch( + opts, + new RetryHandler( + { ...opts, retryOptions: { ...globalOpts, ...opts.retryOptions } }, + { + handler, + dispatch + } + ) + ) + } + } + }; + return retry; +} + +var dump; +var hasRequiredDump; + +function requireDump () { + if (hasRequiredDump) return dump; + hasRequiredDump = 1; + + const util = requireUtil$7(); + const { InvalidArgumentError, RequestAbortedError } = requireErrors(); + const DecoratorHandler = requireDecoratorHandler(); + + class DumpHandler extends DecoratorHandler { + #maxSize = 1024 * 1024 + #abort = null + #dumped = false + #aborted = false + #size = 0 + #reason = null + #handler = null + + constructor ({ maxSize }, handler) { + super(handler); + + if (maxSize != null && (!Number.isFinite(maxSize) || maxSize < 1)) { + throw new InvalidArgumentError('maxSize must be a number greater than 0') + } + + this.#maxSize = maxSize ?? this.#maxSize; + this.#handler = handler; + } + + onConnect (abort) { + this.#abort = abort; + + this.#handler.onConnect(this.#customAbort.bind(this)); + } + + #customAbort (reason) { + this.#aborted = true; + this.#reason = reason; + } + + // TODO: will require adjustment after new hooks are out + onHeaders (statusCode, rawHeaders, resume, statusMessage) { + const headers = util.parseHeaders(rawHeaders); + const contentLength = headers['content-length']; + + if (contentLength != null && contentLength > this.#maxSize) { + throw new RequestAbortedError( + `Response size (${contentLength}) larger than maxSize (${ + this.#maxSize + })` + ) + } + + if (this.#aborted) { + return true + } + + return this.#handler.onHeaders( + statusCode, + rawHeaders, + resume, + statusMessage + ) + } + + onError (err) { + if (this.#dumped) { + return + } + + err = this.#reason ?? err; + + this.#handler.onError(err); + } + + onData (chunk) { + this.#size = this.#size + chunk.length; + + if (this.#size >= this.#maxSize) { + this.#dumped = true; + + if (this.#aborted) { + this.#handler.onError(this.#reason); + } else { + this.#handler.onComplete([]); + } + } + + return true + } + + onComplete (trailers) { + if (this.#dumped) { + return + } + + if (this.#aborted) { + this.#handler.onError(this.reason); + return + } + + this.#handler.onComplete(trailers); + } + } + + function createDumpInterceptor ( + { maxSize: defaultMaxSize } = { + maxSize: 1024 * 1024 + } + ) { + return dispatch => { + return function Intercept (opts, handler) { + const { dumpMaxSize = defaultMaxSize } = + opts; + + const dumpHandler = new DumpHandler( + { maxSize: dumpMaxSize }, + handler + ); + + return dispatch(opts, dumpHandler) + } + } + } + + dump = createDumpInterceptor; + return dump; +} + +var headers; +var hasRequiredHeaders; + +function requireHeaders () { + if (hasRequiredHeaders) return headers; + hasRequiredHeaders = 1; + + const { kConstruct } = requireSymbols$4(); + const { kEnumerableProperty } = requireUtil$7(); + const { + iteratorMixin, + isValidHeaderName, + isValidHeaderValue + } = requireUtil$6(); + const { webidl } = requireWebidl(); + const assert = require$$0$4; + const util = require$$0$6; + + const kHeadersMap = Symbol('headers map'); + const kHeadersSortedMap = Symbol('headers map sorted'); + + /** + * @param {number} code + */ + function isHTTPWhiteSpaceCharCode (code) { + return code === 0x00a || code === 0x00d || code === 0x009 || code === 0x020 + } + + /** + * @see https://fetch.spec.whatwg.org/#concept-header-value-normalize + * @param {string} potentialValue + */ + function headerValueNormalize (potentialValue) { + // To normalize a byte sequence potentialValue, remove + // any leading and trailing HTTP whitespace bytes from + // potentialValue. + let i = 0; let j = potentialValue.length; + + while (j > i && isHTTPWhiteSpaceCharCode(potentialValue.charCodeAt(j - 1))) --j; + while (j > i && isHTTPWhiteSpaceCharCode(potentialValue.charCodeAt(i))) ++i; + + return i === 0 && j === potentialValue.length ? potentialValue : potentialValue.substring(i, j) + } + + function fill (headers, object) { + // To fill a Headers object headers with a given object object, run these steps: + + // 1. If object is a sequence, then for each header in object: + // Note: webidl conversion to array has already been done. + if (Array.isArray(object)) { + for (let i = 0; i < object.length; ++i) { + const header = object[i]; + // 1. If header does not contain exactly two items, then throw a TypeError. + if (header.length !== 2) { + throw webidl.errors.exception({ + header: 'Headers constructor', + message: `expected name/value pair to be length 2, found ${header.length}.` + }) + } + + // 2. Append (header’s first item, header’s second item) to headers. + appendHeader(headers, header[0], header[1]); + } + } else if (typeof object === 'object' && object !== null) { + // Note: null should throw + + // 2. Otherwise, object is a record, then for each key → value in object, + // append (key, value) to headers + const keys = Object.keys(object); + for (let i = 0; i < keys.length; ++i) { + appendHeader(headers, keys[i], object[keys[i]]); + } + } else { + throw webidl.errors.conversionFailed({ + prefix: 'Headers constructor', + argument: 'Argument 1', + types: ['sequence>', 'record'] + }) + } + } + + /** + * @see https://fetch.spec.whatwg.org/#concept-headers-append + */ + function appendHeader (headers, name, value) { + // 1. Normalize value. + value = headerValueNormalize(value); + + // 2. If name is not a header name or value is not a + // header value, then throw a TypeError. + if (!isValidHeaderName(name)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.append', + value: name, + type: 'header name' + }) + } else if (!isValidHeaderValue(value)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.append', + value, + type: 'header value' + }) + } + + // 3. If headers’s guard is "immutable", then throw a TypeError. + // 4. Otherwise, if headers’s guard is "request" and name is a + // forbidden header name, return. + // 5. Otherwise, if headers’s guard is "request-no-cors": + // TODO + // Note: undici does not implement forbidden header names + if (getHeadersGuard(headers) === 'immutable') { + throw new TypeError('immutable') + } + + // 6. Otherwise, if headers’s guard is "response" and name is a + // forbidden response-header name, return. + + // 7. Append (name, value) to headers’s header list. + return getHeadersList(headers).append(name, value, false) + + // 8. If headers’s guard is "request-no-cors", then remove + // privileged no-CORS request headers from headers + } + + function compareHeaderName (a, b) { + return a[0] < b[0] ? -1 : 1 + } + + class HeadersList { + /** @type {[string, string][]|null} */ + cookies = null + + constructor (init) { + if (init instanceof HeadersList) { + this[kHeadersMap] = new Map(init[kHeadersMap]); + this[kHeadersSortedMap] = init[kHeadersSortedMap]; + this.cookies = init.cookies === null ? null : [...init.cookies]; + } else { + this[kHeadersMap] = new Map(init); + this[kHeadersSortedMap] = null; + } + } + + /** + * @see https://fetch.spec.whatwg.org/#header-list-contains + * @param {string} name + * @param {boolean} isLowerCase + */ + contains (name, isLowerCase) { + // A header list list contains a header name name if list + // contains a header whose name is a byte-case-insensitive + // match for name. + + return this[kHeadersMap].has(isLowerCase ? name : name.toLowerCase()) + } + + clear () { + this[kHeadersMap].clear(); + this[kHeadersSortedMap] = null; + this.cookies = null; + } + + /** + * @see https://fetch.spec.whatwg.org/#concept-header-list-append + * @param {string} name + * @param {string} value + * @param {boolean} isLowerCase + */ + append (name, value, isLowerCase) { + this[kHeadersSortedMap] = null; + + // 1. If list contains name, then set name to the first such + // header’s name. + const lowercaseName = isLowerCase ? name : name.toLowerCase(); + const exists = this[kHeadersMap].get(lowercaseName); + + // 2. Append (name, value) to list. + if (exists) { + const delimiter = lowercaseName === 'cookie' ? '; ' : ', '; + this[kHeadersMap].set(lowercaseName, { + name: exists.name, + value: `${exists.value}${delimiter}${value}` + }); + } else { + this[kHeadersMap].set(lowercaseName, { name, value }); + } + + if (lowercaseName === 'set-cookie') { + (this.cookies ??= []).push(value); + } + } + + /** + * @see https://fetch.spec.whatwg.org/#concept-header-list-set + * @param {string} name + * @param {string} value + * @param {boolean} isLowerCase + */ + set (name, value, isLowerCase) { + this[kHeadersSortedMap] = null; + const lowercaseName = isLowerCase ? name : name.toLowerCase(); + + if (lowercaseName === 'set-cookie') { + this.cookies = [value]; + } + + // 1. If list contains name, then set the value of + // the first such header to value and remove the + // others. + // 2. Otherwise, append header (name, value) to list. + this[kHeadersMap].set(lowercaseName, { name, value }); + } + + /** + * @see https://fetch.spec.whatwg.org/#concept-header-list-delete + * @param {string} name + * @param {boolean} isLowerCase + */ + delete (name, isLowerCase) { + this[kHeadersSortedMap] = null; + if (!isLowerCase) name = name.toLowerCase(); + + if (name === 'set-cookie') { + this.cookies = null; + } + + this[kHeadersMap].delete(name); + } + + /** + * @see https://fetch.spec.whatwg.org/#concept-header-list-get + * @param {string} name + * @param {boolean} isLowerCase + * @returns {string | null} + */ + get (name, isLowerCase) { + // 1. If list does not contain name, then return null. + // 2. Return the values of all headers in list whose name + // is a byte-case-insensitive match for name, + // separated from each other by 0x2C 0x20, in order. + return this[kHeadersMap].get(isLowerCase ? name : name.toLowerCase())?.value ?? null + } + + * [Symbol.iterator] () { + // use the lowercased name + for (const { 0: name, 1: { value } } of this[kHeadersMap]) { + yield [name, value]; + } + } + + get entries () { + const headers = {}; + + if (this[kHeadersMap].size !== 0) { + for (const { name, value } of this[kHeadersMap].values()) { + headers[name] = value; + } + } + + return headers + } + + rawValues () { + return this[kHeadersMap].values() + } + + get entriesList () { + const headers = []; + + if (this[kHeadersMap].size !== 0) { + for (const { 0: lowerName, 1: { name, value } } of this[kHeadersMap]) { + if (lowerName === 'set-cookie') { + for (const cookie of this.cookies) { + headers.push([name, cookie]); + } + } else { + headers.push([name, value]); + } + } + } + + return headers + } + + // https://fetch.spec.whatwg.org/#convert-header-names-to-a-sorted-lowercase-set + toSortedArray () { + const size = this[kHeadersMap].size; + const array = new Array(size); + // In most cases, you will use the fast-path. + // fast-path: Use binary insertion sort for small arrays. + if (size <= 32) { + if (size === 0) { + // If empty, it is an empty array. To avoid the first index assignment. + return array + } + // Improve performance by unrolling loop and avoiding double-loop. + // Double-loop-less version of the binary insertion sort. + const iterator = this[kHeadersMap][Symbol.iterator](); + const firstValue = iterator.next().value; + // set [name, value] to first index. + array[0] = [firstValue[0], firstValue[1].value]; + // https://fetch.spec.whatwg.org/#concept-header-list-sort-and-combine + // 3.2.2. Assert: value is non-null. + assert(firstValue[1].value !== null); + for ( + let i = 1, j = 0, right = 0, left = 0, pivot = 0, x, value; + i < size; + ++i + ) { + // get next value + value = iterator.next().value; + // set [name, value] to current index. + x = array[i] = [value[0], value[1].value]; + // https://fetch.spec.whatwg.org/#concept-header-list-sort-and-combine + // 3.2.2. Assert: value is non-null. + assert(x[1] !== null); + left = 0; + right = i; + // binary search + while (left < right) { + // middle index + pivot = left + ((right - left) >> 1); + // compare header name + if (array[pivot][0] <= x[0]) { + left = pivot + 1; + } else { + right = pivot; + } + } + if (i !== pivot) { + j = i; + while (j > left) { + array[j] = array[--j]; + } + array[left] = x; + } + } + /* c8 ignore next 4 */ + if (!iterator.next().done) { + // This is for debugging and will never be called. + throw new TypeError('Unreachable') + } + return array + } else { + // This case would be a rare occurrence. + // slow-path: fallback + let i = 0; + for (const { 0: name, 1: { value } } of this[kHeadersMap]) { + array[i++] = [name, value]; + // https://fetch.spec.whatwg.org/#concept-header-list-sort-and-combine + // 3.2.2. Assert: value is non-null. + assert(value !== null); + } + return array.sort(compareHeaderName) + } + } + } + + // https://fetch.spec.whatwg.org/#headers-class + class Headers { + #guard + #headersList + + constructor (init = undefined) { + if (init === kConstruct) { + return + } + + this.#headersList = new HeadersList(); + + // The new Headers(init) constructor steps are: + + // 1. Set this’s guard to "none". + this.#guard = 'none'; + + // 2. If init is given, then fill this with init. + if (init !== undefined) { + init = webidl.converters.HeadersInit(init, 'Headers contructor', 'init'); + fill(this, init); + } + } + + // https://fetch.spec.whatwg.org/#dom-headers-append + append (name, value) { + webidl.brandCheck(this, Headers); + + webidl.argumentLengthCheck(arguments, 2, 'Headers.append'); + + const prefix = 'Headers.append'; + name = webidl.converters.ByteString(name, prefix, 'name'); + value = webidl.converters.ByteString(value, prefix, 'value'); + + return appendHeader(this, name, value) + } + + // https://fetch.spec.whatwg.org/#dom-headers-delete + delete (name) { + webidl.brandCheck(this, Headers); + + webidl.argumentLengthCheck(arguments, 1, 'Headers.delete'); + + const prefix = 'Headers.delete'; + name = webidl.converters.ByteString(name, prefix, 'name'); + + // 1. If name is not a header name, then throw a TypeError. + if (!isValidHeaderName(name)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.delete', + value: name, + type: 'header name' + }) + } + + // 2. If this’s guard is "immutable", then throw a TypeError. + // 3. Otherwise, if this’s guard is "request" and name is a + // forbidden header name, return. + // 4. Otherwise, if this’s guard is "request-no-cors", name + // is not a no-CORS-safelisted request-header name, and + // name is not a privileged no-CORS request-header name, + // return. + // 5. Otherwise, if this’s guard is "response" and name is + // a forbidden response-header name, return. + // Note: undici does not implement forbidden header names + if (this.#guard === 'immutable') { + throw new TypeError('immutable') + } + + // 6. If this’s header list does not contain name, then + // return. + if (!this.#headersList.contains(name, false)) { + return + } + + // 7. Delete name from this’s header list. + // 8. If this’s guard is "request-no-cors", then remove + // privileged no-CORS request headers from this. + this.#headersList.delete(name, false); + } + + // https://fetch.spec.whatwg.org/#dom-headers-get + get (name) { + webidl.brandCheck(this, Headers); + + webidl.argumentLengthCheck(arguments, 1, 'Headers.get'); + + const prefix = 'Headers.get'; + name = webidl.converters.ByteString(name, prefix, 'name'); + + // 1. If name is not a header name, then throw a TypeError. + if (!isValidHeaderName(name)) { + throw webidl.errors.invalidArgument({ + prefix, + value: name, + type: 'header name' + }) + } + + // 2. Return the result of getting name from this’s header + // list. + return this.#headersList.get(name, false) + } + + // https://fetch.spec.whatwg.org/#dom-headers-has + has (name) { + webidl.brandCheck(this, Headers); + + webidl.argumentLengthCheck(arguments, 1, 'Headers.has'); + + const prefix = 'Headers.has'; + name = webidl.converters.ByteString(name, prefix, 'name'); + + // 1. If name is not a header name, then throw a TypeError. + if (!isValidHeaderName(name)) { + throw webidl.errors.invalidArgument({ + prefix, + value: name, + type: 'header name' + }) + } + + // 2. Return true if this’s header list contains name; + // otherwise false. + return this.#headersList.contains(name, false) + } + + // https://fetch.spec.whatwg.org/#dom-headers-set + set (name, value) { + webidl.brandCheck(this, Headers); + + webidl.argumentLengthCheck(arguments, 2, 'Headers.set'); + + const prefix = 'Headers.set'; + name = webidl.converters.ByteString(name, prefix, 'name'); + value = webidl.converters.ByteString(value, prefix, 'value'); + + // 1. Normalize value. + value = headerValueNormalize(value); + + // 2. If name is not a header name or value is not a + // header value, then throw a TypeError. + if (!isValidHeaderName(name)) { + throw webidl.errors.invalidArgument({ + prefix, + value: name, + type: 'header name' + }) + } else if (!isValidHeaderValue(value)) { + throw webidl.errors.invalidArgument({ + prefix, + value, + type: 'header value' + }) + } + + // 3. If this’s guard is "immutable", then throw a TypeError. + // 4. Otherwise, if this’s guard is "request" and name is a + // forbidden header name, return. + // 5. Otherwise, if this’s guard is "request-no-cors" and + // name/value is not a no-CORS-safelisted request-header, + // return. + // 6. Otherwise, if this’s guard is "response" and name is a + // forbidden response-header name, return. + // Note: undici does not implement forbidden header names + if (this.#guard === 'immutable') { + throw new TypeError('immutable') + } + + // 7. Set (name, value) in this’s header list. + // 8. If this’s guard is "request-no-cors", then remove + // privileged no-CORS request headers from this + this.#headersList.set(name, value, false); + } + + // https://fetch.spec.whatwg.org/#dom-headers-getsetcookie + getSetCookie () { + webidl.brandCheck(this, Headers); + + // 1. If this’s header list does not contain `Set-Cookie`, then return « ». + // 2. Return the values of all headers in this’s header list whose name is + // a byte-case-insensitive match for `Set-Cookie`, in order. + + const list = this.#headersList.cookies; + + if (list) { + return [...list] + } + + return [] + } + + // https://fetch.spec.whatwg.org/#concept-header-list-sort-and-combine + get [kHeadersSortedMap] () { + if (this.#headersList[kHeadersSortedMap]) { + return this.#headersList[kHeadersSortedMap] + } + + // 1. Let headers be an empty list of headers with the key being the name + // and value the value. + const headers = []; + + // 2. Let names be the result of convert header names to a sorted-lowercase + // set with all the names of the headers in list. + const names = this.#headersList.toSortedArray(); + + const cookies = this.#headersList.cookies; + + // fast-path + if (cookies === null || cookies.length === 1) { + // Note: The non-null assertion of value has already been done by `HeadersList#toSortedArray` + return (this.#headersList[kHeadersSortedMap] = names) + } + + // 3. For each name of names: + for (let i = 0; i < names.length; ++i) { + const { 0: name, 1: value } = names[i]; + // 1. If name is `set-cookie`, then: + if (name === 'set-cookie') { + // 1. Let values be a list of all values of headers in list whose name + // is a byte-case-insensitive match for name, in order. + + // 2. For each value of values: + // 1. Append (name, value) to headers. + for (let j = 0; j < cookies.length; ++j) { + headers.push([name, cookies[j]]); + } + } else { + // 2. Otherwise: + + // 1. Let value be the result of getting name from list. + + // 2. Assert: value is non-null. + // Note: This operation was done by `HeadersList#toSortedArray`. + + // 3. Append (name, value) to headers. + headers.push([name, value]); + } + } + + // 4. Return headers. + return (this.#headersList[kHeadersSortedMap] = headers) + } + + [util.inspect.custom] (depth, options) { + options.depth ??= depth; + + return `Headers ${util.formatWithOptions(options, this.#headersList.entries)}` + } + + static getHeadersGuard (o) { + return o.#guard + } + + static setHeadersGuard (o, guard) { + o.#guard = guard; + } + + static getHeadersList (o) { + return o.#headersList + } + + static setHeadersList (o, list) { + o.#headersList = list; + } + } + + const { getHeadersGuard, setHeadersGuard, getHeadersList, setHeadersList } = Headers; + Reflect.deleteProperty(Headers, 'getHeadersGuard'); + Reflect.deleteProperty(Headers, 'setHeadersGuard'); + Reflect.deleteProperty(Headers, 'getHeadersList'); + Reflect.deleteProperty(Headers, 'setHeadersList'); + + iteratorMixin('Headers', Headers, kHeadersSortedMap, 0, 1); + + Object.defineProperties(Headers.prototype, { + append: kEnumerableProperty, + delete: kEnumerableProperty, + get: kEnumerableProperty, + has: kEnumerableProperty, + set: kEnumerableProperty, + getSetCookie: kEnumerableProperty, + [Symbol.toStringTag]: { + value: 'Headers', + configurable: true + }, + [util.inspect.custom]: { + enumerable: false + } + }); + + webidl.converters.HeadersInit = function (V, prefix, argument) { + if (webidl.util.Type(V) === 'Object') { + const iterator = Reflect.get(V, Symbol.iterator); + + // A work-around to ensure we send the properly-cased Headers when V is a Headers object. + // Read https://github.com/nodejs/undici/pull/3159#issuecomment-2075537226 before touching, please. + if (!util.types.isProxy(V) && iterator === Headers.prototype.entries) { // Headers object + try { + return getHeadersList(V).entriesList + } catch { + // fall-through + } + } + + if (typeof iterator === 'function') { + return webidl.converters['sequence>'](V, prefix, argument, iterator.bind(V)) + } + + return webidl.converters['record'](V, prefix, argument) + } + + throw webidl.errors.conversionFailed({ + prefix: 'Headers constructor', + argument: 'Argument 1', + types: ['sequence>', 'record'] + }) + }; + + headers = { + fill, + // for test. + compareHeaderName, + Headers, + HeadersList, + getHeadersGuard, + setHeadersGuard, + setHeadersList, + getHeadersList + }; + return headers; +} + +var response; +var hasRequiredResponse; + +function requireResponse () { + if (hasRequiredResponse) return response; + hasRequiredResponse = 1; + + const { Headers, HeadersList, fill, getHeadersGuard, setHeadersGuard, setHeadersList } = requireHeaders(); + const { extractBody, cloneBody, mixinBody } = requireBody(); + const util = requireUtil$7(); + const nodeUtil = require$$0$6; + const { kEnumerableProperty } = util; + const { + isValidReasonPhrase, + isCancelled, + isAborted, + isBlobLike, + serializeJavascriptValueToJSONString, + isErrorLike, + isomorphicEncode, + environmentSettingsObject: relevantRealm + } = requireUtil$6(); + const { + redirectStatusSet, + nullBodyStatus + } = requireConstants$2(); + const { kState, kHeaders } = requireSymbols$3(); + const { webidl } = requireWebidl(); + const { FormData } = requireFormdata(); + const { URLSerializer } = requireDataUrl(); + const { kConstruct } = requireSymbols$4(); + const assert = require$$0$4; + const { types } = require$$0$6; + const { isDisturbed, isErrored } = require$$0$5; + + const textEncoder = new TextEncoder('utf-8'); + + const hasFinalizationRegistry = globalThis.FinalizationRegistry && process.version.indexOf('v18') !== 0; + let registry; + + if (hasFinalizationRegistry) { + registry = new FinalizationRegistry((stream) => { + if (!stream.locked && !isDisturbed(stream) && !isErrored(stream)) { + stream.cancel('Response object has been garbage collected').catch(noop); + } + }); + } + + function noop () {} + + // https://fetch.spec.whatwg.org/#response-class + class Response { + // Creates network error Response. + static error () { + // The static error() method steps are to return the result of creating a + // Response object, given a new network error, "immutable", and this’s + // relevant Realm. + const responseObject = fromInnerResponse(makeNetworkError(), 'immutable'); + + return responseObject + } + + // https://fetch.spec.whatwg.org/#dom-response-json + static json (data, init = {}) { + webidl.argumentLengthCheck(arguments, 1, 'Response.json'); + + if (init !== null) { + init = webidl.converters.ResponseInit(init); + } + + // 1. Let bytes the result of running serialize a JavaScript value to JSON bytes on data. + const bytes = textEncoder.encode( + serializeJavascriptValueToJSONString(data) + ); + + // 2. Let body be the result of extracting bytes. + const body = extractBody(bytes); + + // 3. Let responseObject be the result of creating a Response object, given a new response, + // "response", and this’s relevant Realm. + const responseObject = fromInnerResponse(makeResponse({}), 'response'); + + // 4. Perform initialize a response given responseObject, init, and (body, "application/json"). + initializeResponse(responseObject, init, { body: body[0], type: 'application/json' }); + + // 5. Return responseObject. + return responseObject + } + + // Creates a redirect Response that redirects to url with status status. + static redirect (url, status = 302) { + webidl.argumentLengthCheck(arguments, 1, 'Response.redirect'); + + url = webidl.converters.USVString(url); + status = webidl.converters['unsigned short'](status); + + // 1. Let parsedURL be the result of parsing url with current settings + // object’s API base URL. + // 2. If parsedURL is failure, then throw a TypeError. + // TODO: base-URL? + let parsedURL; + try { + parsedURL = new URL(url, relevantRealm.settingsObject.baseUrl); + } catch (err) { + throw new TypeError(`Failed to parse URL from ${url}`, { cause: err }) + } + + // 3. If status is not a redirect status, then throw a RangeError. + if (!redirectStatusSet.has(status)) { + throw new RangeError(`Invalid status code ${status}`) + } + + // 4. Let responseObject be the result of creating a Response object, + // given a new response, "immutable", and this’s relevant Realm. + const responseObject = fromInnerResponse(makeResponse({}), 'immutable'); + + // 5. Set responseObject’s response’s status to status. + responseObject[kState].status = status; + + // 6. Let value be parsedURL, serialized and isomorphic encoded. + const value = isomorphicEncode(URLSerializer(parsedURL)); + + // 7. Append `Location`/value to responseObject’s response’s header list. + responseObject[kState].headersList.append('location', value, true); + + // 8. Return responseObject. + return responseObject + } + + // https://fetch.spec.whatwg.org/#dom-response + constructor (body = null, init = {}) { + if (body === kConstruct) { + return + } + + if (body !== null) { + body = webidl.converters.BodyInit(body); + } + + init = webidl.converters.ResponseInit(init); + + // 1. Set this’s response to a new response. + this[kState] = makeResponse({}); + + // 2. Set this’s headers to a new Headers object with this’s relevant + // Realm, whose header list is this’s response’s header list and guard + // is "response". + this[kHeaders] = new Headers(kConstruct); + setHeadersGuard(this[kHeaders], 'response'); + setHeadersList(this[kHeaders], this[kState].headersList); + + // 3. Let bodyWithType be null. + let bodyWithType = null; + + // 4. If body is non-null, then set bodyWithType to the result of extracting body. + if (body != null) { + const [extractedBody, type] = extractBody(body); + bodyWithType = { body: extractedBody, type }; + } + + // 5. Perform initialize a response given this, init, and bodyWithType. + initializeResponse(this, init, bodyWithType); + } + + // Returns response’s type, e.g., "cors". + get type () { + webidl.brandCheck(this, Response); + + // The type getter steps are to return this’s response’s type. + return this[kState].type + } + + // Returns response’s URL, if it has one; otherwise the empty string. + get url () { + webidl.brandCheck(this, Response); + + const urlList = this[kState].urlList; + + // The url getter steps are to return the empty string if this’s + // response’s URL is null; otherwise this’s response’s URL, + // serialized with exclude fragment set to true. + const url = urlList[urlList.length - 1] ?? null; + + if (url === null) { + return '' + } + + return URLSerializer(url, true) + } + + // Returns whether response was obtained through a redirect. + get redirected () { + webidl.brandCheck(this, Response); + + // The redirected getter steps are to return true if this’s response’s URL + // list has more than one item; otherwise false. + return this[kState].urlList.length > 1 + } + + // Returns response’s status. + get status () { + webidl.brandCheck(this, Response); + + // The status getter steps are to return this’s response’s status. + return this[kState].status + } + + // Returns whether response’s status is an ok status. + get ok () { + webidl.brandCheck(this, Response); + + // The ok getter steps are to return true if this’s response’s status is an + // ok status; otherwise false. + return this[kState].status >= 200 && this[kState].status <= 299 + } + + // Returns response’s status message. + get statusText () { + webidl.brandCheck(this, Response); + + // The statusText getter steps are to return this’s response’s status + // message. + return this[kState].statusText + } + + // Returns response’s headers as Headers. + get headers () { + webidl.brandCheck(this, Response); + + // The headers getter steps are to return this’s headers. + return this[kHeaders] + } + + get body () { + webidl.brandCheck(this, Response); + + return this[kState].body ? this[kState].body.stream : null + } + + get bodyUsed () { + webidl.brandCheck(this, Response); + + return !!this[kState].body && util.isDisturbed(this[kState].body.stream) + } + + // Returns a clone of response. + clone () { + webidl.brandCheck(this, Response); + + // 1. If this is unusable, then throw a TypeError. + if (this.bodyUsed || this.body?.locked) { + throw webidl.errors.exception({ + header: 'Response.clone', + message: 'Body has already been consumed.' + }) + } + + // 2. Let clonedResponse be the result of cloning this’s response. + const clonedResponse = cloneResponse(this[kState]); + + // 3. Return the result of creating a Response object, given + // clonedResponse, this’s headers’s guard, and this’s relevant Realm. + return fromInnerResponse(clonedResponse, getHeadersGuard(this[kHeaders])) + } + + [nodeUtil.inspect.custom] (depth, options) { + if (options.depth === null) { + options.depth = 2; + } + + options.colors ??= true; + + const properties = { + status: this.status, + statusText: this.statusText, + headers: this.headers, + body: this.body, + bodyUsed: this.bodyUsed, + ok: this.ok, + redirected: this.redirected, + type: this.type, + url: this.url + }; + + return `Response ${nodeUtil.formatWithOptions(options, properties)}` + } + } + + mixinBody(Response); + + Object.defineProperties(Response.prototype, { + type: kEnumerableProperty, + url: kEnumerableProperty, + status: kEnumerableProperty, + ok: kEnumerableProperty, + redirected: kEnumerableProperty, + statusText: kEnumerableProperty, + headers: kEnumerableProperty, + clone: kEnumerableProperty, + body: kEnumerableProperty, + bodyUsed: kEnumerableProperty, + [Symbol.toStringTag]: { + value: 'Response', + configurable: true + } + }); + + Object.defineProperties(Response, { + json: kEnumerableProperty, + redirect: kEnumerableProperty, + error: kEnumerableProperty + }); + + // https://fetch.spec.whatwg.org/#concept-response-clone + function cloneResponse (response) { + // To clone a response response, run these steps: + + // 1. If response is a filtered response, then return a new identical + // filtered response whose internal response is a clone of response’s + // internal response. + if (response.internalResponse) { + return filterResponse( + cloneResponse(response.internalResponse), + response.type + ) + } + + // 2. Let newResponse be a copy of response, except for its body. + const newResponse = makeResponse({ ...response, body: null }); + + // 3. If response’s body is non-null, then set newResponse’s body to the + // result of cloning response’s body. + if (response.body != null) { + newResponse.body = cloneBody(response.body); + } + + // 4. Return newResponse. + return newResponse + } + + function makeResponse (init) { + return { + aborted: false, + rangeRequested: false, + timingAllowPassed: false, + requestIncludesCredentials: false, + type: 'default', + status: 200, + timingInfo: null, + cacheState: '', + statusText: '', + ...init, + headersList: init?.headersList + ? new HeadersList(init?.headersList) + : new HeadersList(), + urlList: init?.urlList ? [...init.urlList] : [] + } + } + + function makeNetworkError (reason) { + const isError = isErrorLike(reason); + return makeResponse({ + type: 'error', + status: 0, + error: isError + ? reason + : new Error(reason ? String(reason) : reason), + aborted: reason && reason.name === 'AbortError' + }) + } + + // @see https://fetch.spec.whatwg.org/#concept-network-error + function isNetworkError (response) { + return ( + // A network error is a response whose type is "error", + response.type === 'error' && + // status is 0 + response.status === 0 + ) + } + + function makeFilteredResponse (response, state) { + state = { + internalResponse: response, + ...state + }; + + return new Proxy(response, { + get (target, p) { + return p in state ? state[p] : target[p] + }, + set (target, p, value) { + assert(!(p in state)); + target[p] = value; + return true + } + }) + } + + // https://fetch.spec.whatwg.org/#concept-filtered-response + function filterResponse (response, type) { + // Set response to the following filtered response with response as its + // internal response, depending on request’s response tainting: + if (type === 'basic') { + // A basic filtered response is a filtered response whose type is "basic" + // and header list excludes any headers in internal response’s header list + // whose name is a forbidden response-header name. + + // Note: undici does not implement forbidden response-header names + return makeFilteredResponse(response, { + type: 'basic', + headersList: response.headersList + }) + } else if (type === 'cors') { + // A CORS filtered response is a filtered response whose type is "cors" + // and header list excludes any headers in internal response’s header + // list whose name is not a CORS-safelisted response-header name, given + // internal response’s CORS-exposed header-name list. + + // Note: undici does not implement CORS-safelisted response-header names + return makeFilteredResponse(response, { + type: 'cors', + headersList: response.headersList + }) + } else if (type === 'opaque') { + // An opaque filtered response is a filtered response whose type is + // "opaque", URL list is the empty list, status is 0, status message + // is the empty byte sequence, header list is empty, and body is null. + + return makeFilteredResponse(response, { + type: 'opaque', + urlList: Object.freeze([]), + status: 0, + statusText: '', + body: null + }) + } else if (type === 'opaqueredirect') { + // An opaque-redirect filtered response is a filtered response whose type + // is "opaqueredirect", status is 0, status message is the empty byte + // sequence, header list is empty, and body is null. + + return makeFilteredResponse(response, { + type: 'opaqueredirect', + status: 0, + statusText: '', + headersList: [], + body: null + }) + } else { + assert(false); + } + } + + // https://fetch.spec.whatwg.org/#appropriate-network-error + function makeAppropriateNetworkError (fetchParams, err = null) { + // 1. Assert: fetchParams is canceled. + assert(isCancelled(fetchParams)); + + // 2. Return an aborted network error if fetchParams is aborted; + // otherwise return a network error. + return isAborted(fetchParams) + ? makeNetworkError(Object.assign(new DOMException('The operation was aborted.', 'AbortError'), { cause: err })) + : makeNetworkError(Object.assign(new DOMException('Request was cancelled.'), { cause: err })) + } + + // https://whatpr.org/fetch/1392.html#initialize-a-response + function initializeResponse (response, init, body) { + // 1. If init["status"] is not in the range 200 to 599, inclusive, then + // throw a RangeError. + if (init.status !== null && (init.status < 200 || init.status > 599)) { + throw new RangeError('init["status"] must be in the range of 200 to 599, inclusive.') + } + + // 2. If init["statusText"] does not match the reason-phrase token production, + // then throw a TypeError. + if ('statusText' in init && init.statusText != null) { + // See, https://datatracker.ietf.org/doc/html/rfc7230#section-3.1.2: + // reason-phrase = *( HTAB / SP / VCHAR / obs-text ) + if (!isValidReasonPhrase(String(init.statusText))) { + throw new TypeError('Invalid statusText') + } + } + + // 3. Set response’s response’s status to init["status"]. + if ('status' in init && init.status != null) { + response[kState].status = init.status; + } + + // 4. Set response’s response’s status message to init["statusText"]. + if ('statusText' in init && init.statusText != null) { + response[kState].statusText = init.statusText; + } + + // 5. If init["headers"] exists, then fill response’s headers with init["headers"]. + if ('headers' in init && init.headers != null) { + fill(response[kHeaders], init.headers); + } + + // 6. If body was given, then: + if (body) { + // 1. If response's status is a null body status, then throw a TypeError. + if (nullBodyStatus.includes(response.status)) { + throw webidl.errors.exception({ + header: 'Response constructor', + message: `Invalid response status code ${response.status}` + }) + } + + // 2. Set response's body to body's body. + response[kState].body = body.body; + + // 3. If body's type is non-null and response's header list does not contain + // `Content-Type`, then append (`Content-Type`, body's type) to response's header list. + if (body.type != null && !response[kState].headersList.contains('content-type', true)) { + response[kState].headersList.append('content-type', body.type, true); + } + } + } + + /** + * @see https://fetch.spec.whatwg.org/#response-create + * @param {any} innerResponse + * @param {'request' | 'immutable' | 'request-no-cors' | 'response' | 'none'} guard + * @returns {Response} + */ + function fromInnerResponse (innerResponse, guard) { + const response = new Response(kConstruct); + response[kState] = innerResponse; + response[kHeaders] = new Headers(kConstruct); + setHeadersList(response[kHeaders], innerResponse.headersList); + setHeadersGuard(response[kHeaders], guard); + + if (hasFinalizationRegistry && innerResponse.body?.stream) { + registry.register(response, innerResponse.body.stream); + } + + return response + } + + webidl.converters.ReadableStream = webidl.interfaceConverter( + ReadableStream + ); + + webidl.converters.FormData = webidl.interfaceConverter( + FormData + ); + + webidl.converters.URLSearchParams = webidl.interfaceConverter( + URLSearchParams + ); + + // https://fetch.spec.whatwg.org/#typedefdef-xmlhttprequestbodyinit + webidl.converters.XMLHttpRequestBodyInit = function (V, prefix, name) { + if (typeof V === 'string') { + return webidl.converters.USVString(V, prefix, name) + } + + if (isBlobLike(V)) { + return webidl.converters.Blob(V, prefix, name, { strict: false }) + } + + if (ArrayBuffer.isView(V) || types.isArrayBuffer(V)) { + return webidl.converters.BufferSource(V, prefix, name) + } + + if (util.isFormDataLike(V)) { + return webidl.converters.FormData(V, prefix, name, { strict: false }) + } + + if (V instanceof URLSearchParams) { + return webidl.converters.URLSearchParams(V, prefix, name) + } + + return webidl.converters.DOMString(V, prefix, name) + }; + + // https://fetch.spec.whatwg.org/#bodyinit + webidl.converters.BodyInit = function (V, prefix, argument) { + if (V instanceof ReadableStream) { + return webidl.converters.ReadableStream(V, prefix, argument) + } + + // Note: the spec doesn't include async iterables, + // this is an undici extension. + if (V?.[Symbol.asyncIterator]) { + return V + } + + return webidl.converters.XMLHttpRequestBodyInit(V, prefix, argument) + }; + + webidl.converters.ResponseInit = webidl.dictionaryConverter([ + { + key: 'status', + converter: webidl.converters['unsigned short'], + defaultValue: () => 200 + }, + { + key: 'statusText', + converter: webidl.converters.ByteString, + defaultValue: () => '' + }, + { + key: 'headers', + converter: webidl.converters.HeadersInit + } + ]); + + response = { + isNetworkError, + makeNetworkError, + makeResponse, + makeAppropriateNetworkError, + filterResponse, + Response, + cloneResponse, + fromInnerResponse + }; + return response; +} + +var dispatcherWeakref; +var hasRequiredDispatcherWeakref; + +function requireDispatcherWeakref () { + if (hasRequiredDispatcherWeakref) return dispatcherWeakref; + hasRequiredDispatcherWeakref = 1; + + const { kConnected, kSize } = requireSymbols$4(); + + class CompatWeakRef { + constructor (value) { + this.value = value; + } + + deref () { + return this.value[kConnected] === 0 && this.value[kSize] === 0 + ? undefined + : this.value + } + } + + class CompatFinalizer { + constructor (finalizer) { + this.finalizer = finalizer; + } + + register (dispatcher, key) { + if (dispatcher.on) { + dispatcher.on('disconnect', () => { + if (dispatcher[kConnected] === 0 && dispatcher[kSize] === 0) { + this.finalizer(key); + } + }); + } + } + + unregister (key) {} + } + + dispatcherWeakref = function () { + // FIXME: remove workaround when the Node bug is backported to v18 + // https://github.com/nodejs/node/issues/49344#issuecomment-1741776308 + if (process.env.NODE_V8_COVERAGE && process.version.startsWith('v18')) { + process._rawDebug('Using compatibility WeakRef and FinalizationRegistry'); + return { + WeakRef: CompatWeakRef, + FinalizationRegistry: CompatFinalizer + } + } + return { WeakRef, FinalizationRegistry } + }; + return dispatcherWeakref; +} + +/* globals AbortController */ + +var request; +var hasRequiredRequest; + +function requireRequest () { + if (hasRequiredRequest) return request; + hasRequiredRequest = 1; + + const { extractBody, mixinBody, cloneBody } = requireBody(); + const { Headers, fill: fillHeaders, HeadersList, setHeadersGuard, getHeadersGuard, setHeadersList, getHeadersList } = requireHeaders(); + const { FinalizationRegistry } = requireDispatcherWeakref()(); + const util = requireUtil$7(); + const nodeUtil = require$$0$6; + const { + isValidHTTPToken, + sameOrigin, + environmentSettingsObject + } = requireUtil$6(); + const { + forbiddenMethodsSet, + corsSafeListedMethodsSet, + referrerPolicy, + requestRedirect, + requestMode, + requestCredentials, + requestCache, + requestDuplex + } = requireConstants$2(); + const { kEnumerableProperty, normalizedMethodRecordsBase, normalizedMethodRecords } = util; + const { kHeaders, kSignal, kState, kDispatcher } = requireSymbols$3(); + const { webidl } = requireWebidl(); + const { URLSerializer } = requireDataUrl(); + const { kConstruct } = requireSymbols$4(); + const assert = require$$0$4; + const { getMaxListeners, setMaxListeners, getEventListeners, defaultMaxListeners } = require$$8; + + const kAbortController = Symbol('abortController'); + + const requestFinalizer = new FinalizationRegistry(({ signal, abort }) => { + signal.removeEventListener('abort', abort); + }); + + const dependentControllerMap = new WeakMap(); + + function buildAbort (acRef) { + return abort + + function abort () { + const ac = acRef.deref(); + if (ac !== undefined) { + // Currently, there is a problem with FinalizationRegistry. + // https://github.com/nodejs/node/issues/49344 + // https://github.com/nodejs/node/issues/47748 + // In the case of abort, the first step is to unregister from it. + // If the controller can refer to it, it is still registered. + // It will be removed in the future. + requestFinalizer.unregister(abort); + + // Unsubscribe a listener. + // FinalizationRegistry will no longer be called, so this must be done. + this.removeEventListener('abort', abort); + + ac.abort(this.reason); + + const controllerList = dependentControllerMap.get(ac.signal); + + if (controllerList !== undefined) { + if (controllerList.size !== 0) { + for (const ref of controllerList) { + const ctrl = ref.deref(); + if (ctrl !== undefined) { + ctrl.abort(this.reason); + } + } + controllerList.clear(); + } + dependentControllerMap.delete(ac.signal); + } + } + } + } + + let patchMethodWarning = false; + + // https://fetch.spec.whatwg.org/#request-class + class Request { + // https://fetch.spec.whatwg.org/#dom-request + constructor (input, init = {}) { + if (input === kConstruct) { + return + } + + const prefix = 'Request constructor'; + webidl.argumentLengthCheck(arguments, 1, prefix); + + input = webidl.converters.RequestInfo(input, prefix, 'input'); + init = webidl.converters.RequestInit(init, prefix, 'init'); + + // 1. Let request be null. + let request = null; + + // 2. Let fallbackMode be null. + let fallbackMode = null; + + // 3. Let baseURL be this’s relevant settings object’s API base URL. + const baseUrl = environmentSettingsObject.settingsObject.baseUrl; + + // 4. Let signal be null. + let signal = null; + + // 5. If input is a string, then: + if (typeof input === 'string') { + this[kDispatcher] = init.dispatcher; + + // 1. Let parsedURL be the result of parsing input with baseURL. + // 2. If parsedURL is failure, then throw a TypeError. + let parsedURL; + try { + parsedURL = new URL(input, baseUrl); + } catch (err) { + throw new TypeError('Failed to parse URL from ' + input, { cause: err }) + } + + // 3. If parsedURL includes credentials, then throw a TypeError. + if (parsedURL.username || parsedURL.password) { + throw new TypeError( + 'Request cannot be constructed from a URL that includes credentials: ' + + input + ) + } + + // 4. Set request to a new request whose URL is parsedURL. + request = makeRequest({ urlList: [parsedURL] }); + + // 5. Set fallbackMode to "cors". + fallbackMode = 'cors'; + } else { + this[kDispatcher] = init.dispatcher || input[kDispatcher]; + + // 6. Otherwise: + + // 7. Assert: input is a Request object. + assert(input instanceof Request); + + // 8. Set request to input’s request. + request = input[kState]; + + // 9. Set signal to input’s signal. + signal = input[kSignal]; + } + + // 7. Let origin be this’s relevant settings object’s origin. + const origin = environmentSettingsObject.settingsObject.origin; + + // 8. Let window be "client". + let window = 'client'; + + // 9. If request’s window is an environment settings object and its origin + // is same origin with origin, then set window to request’s window. + if ( + request.window?.constructor?.name === 'EnvironmentSettingsObject' && + sameOrigin(request.window, origin) + ) { + window = request.window; + } + + // 10. If init["window"] exists and is non-null, then throw a TypeError. + if (init.window != null) { + throw new TypeError(`'window' option '${window}' must be null`) + } + + // 11. If init["window"] exists, then set window to "no-window". + if ('window' in init) { + window = 'no-window'; + } + + // 12. Set request to a new request with the following properties: + request = makeRequest({ + // URL request’s URL. + // undici implementation note: this is set as the first item in request's urlList in makeRequest + // method request’s method. + method: request.method, + // header list A copy of request’s header list. + // undici implementation note: headersList is cloned in makeRequest + headersList: request.headersList, + // unsafe-request flag Set. + unsafeRequest: request.unsafeRequest, + // client This’s relevant settings object. + client: environmentSettingsObject.settingsObject, + // window window. + window, + // priority request’s priority. + priority: request.priority, + // origin request’s origin. The propagation of the origin is only significant for navigation requests + // being handled by a service worker. In this scenario a request can have an origin that is different + // from the current client. + origin: request.origin, + // referrer request’s referrer. + referrer: request.referrer, + // referrer policy request’s referrer policy. + referrerPolicy: request.referrerPolicy, + // mode request’s mode. + mode: request.mode, + // credentials mode request’s credentials mode. + credentials: request.credentials, + // cache mode request’s cache mode. + cache: request.cache, + // redirect mode request’s redirect mode. + redirect: request.redirect, + // integrity metadata request’s integrity metadata. + integrity: request.integrity, + // keepalive request’s keepalive. + keepalive: request.keepalive, + // reload-navigation flag request’s reload-navigation flag. + reloadNavigation: request.reloadNavigation, + // history-navigation flag request’s history-navigation flag. + historyNavigation: request.historyNavigation, + // URL list A clone of request’s URL list. + urlList: [...request.urlList] + }); + + const initHasKey = Object.keys(init).length !== 0; + + // 13. If init is not empty, then: + if (initHasKey) { + // 1. If request’s mode is "navigate", then set it to "same-origin". + if (request.mode === 'navigate') { + request.mode = 'same-origin'; + } + + // 2. Unset request’s reload-navigation flag. + request.reloadNavigation = false; + + // 3. Unset request’s history-navigation flag. + request.historyNavigation = false; + + // 4. Set request’s origin to "client". + request.origin = 'client'; + + // 5. Set request’s referrer to "client" + request.referrer = 'client'; + + // 6. Set request’s referrer policy to the empty string. + request.referrerPolicy = ''; + + // 7. Set request’s URL to request’s current URL. + request.url = request.urlList[request.urlList.length - 1]; + + // 8. Set request’s URL list to « request’s URL ». + request.urlList = [request.url]; + } + + // 14. If init["referrer"] exists, then: + if (init.referrer !== undefined) { + // 1. Let referrer be init["referrer"]. + const referrer = init.referrer; + + // 2. If referrer is the empty string, then set request’s referrer to "no-referrer". + if (referrer === '') { + request.referrer = 'no-referrer'; + } else { + // 1. Let parsedReferrer be the result of parsing referrer with + // baseURL. + // 2. If parsedReferrer is failure, then throw a TypeError. + let parsedReferrer; + try { + parsedReferrer = new URL(referrer, baseUrl); + } catch (err) { + throw new TypeError(`Referrer "${referrer}" is not a valid URL.`, { cause: err }) + } + + // 3. If one of the following is true + // - parsedReferrer’s scheme is "about" and path is the string "client" + // - parsedReferrer’s origin is not same origin with origin + // then set request’s referrer to "client". + if ( + (parsedReferrer.protocol === 'about:' && parsedReferrer.hostname === 'client') || + (origin && !sameOrigin(parsedReferrer, environmentSettingsObject.settingsObject.baseUrl)) + ) { + request.referrer = 'client'; + } else { + // 4. Otherwise, set request’s referrer to parsedReferrer. + request.referrer = parsedReferrer; + } + } + } + + // 15. If init["referrerPolicy"] exists, then set request’s referrer policy + // to it. + if (init.referrerPolicy !== undefined) { + request.referrerPolicy = init.referrerPolicy; + } + + // 16. Let mode be init["mode"] if it exists, and fallbackMode otherwise. + let mode; + if (init.mode !== undefined) { + mode = init.mode; + } else { + mode = fallbackMode; + } + + // 17. If mode is "navigate", then throw a TypeError. + if (mode === 'navigate') { + throw webidl.errors.exception({ + header: 'Request constructor', + message: 'invalid request mode navigate.' + }) + } + + // 18. If mode is non-null, set request’s mode to mode. + if (mode != null) { + request.mode = mode; + } + + // 19. If init["credentials"] exists, then set request’s credentials mode + // to it. + if (init.credentials !== undefined) { + request.credentials = init.credentials; + } + + // 18. If init["cache"] exists, then set request’s cache mode to it. + if (init.cache !== undefined) { + request.cache = init.cache; + } + + // 21. If request’s cache mode is "only-if-cached" and request’s mode is + // not "same-origin", then throw a TypeError. + if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') { + throw new TypeError( + "'only-if-cached' can be set only with 'same-origin' mode" + ) + } + + // 22. If init["redirect"] exists, then set request’s redirect mode to it. + if (init.redirect !== undefined) { + request.redirect = init.redirect; + } + + // 23. If init["integrity"] exists, then set request’s integrity metadata to it. + if (init.integrity != null) { + request.integrity = String(init.integrity); + } + + // 24. If init["keepalive"] exists, then set request’s keepalive to it. + if (init.keepalive !== undefined) { + request.keepalive = Boolean(init.keepalive); + } + + // 25. If init["method"] exists, then: + if (init.method !== undefined) { + // 1. Let method be init["method"]. + let method = init.method; + + const mayBeNormalized = normalizedMethodRecords[method]; + + if (mayBeNormalized !== undefined) { + // Note: Bypass validation DELETE, GET, HEAD, OPTIONS, POST, PUT, PATCH and these lowercase ones + request.method = mayBeNormalized; + } else { + // 2. If method is not a method or method is a forbidden method, then + // throw a TypeError. + if (!isValidHTTPToken(method)) { + throw new TypeError(`'${method}' is not a valid HTTP method.`) + } + + const upperCase = method.toUpperCase(); + + if (forbiddenMethodsSet.has(upperCase)) { + throw new TypeError(`'${method}' HTTP method is unsupported.`) + } + + // 3. Normalize method. + // https://fetch.spec.whatwg.org/#concept-method-normalize + // Note: must be in uppercase + method = normalizedMethodRecordsBase[upperCase] ?? method; + + // 4. Set request’s method to method. + request.method = method; + } + + if (!patchMethodWarning && request.method === 'patch') { + process.emitWarning('Using `patch` is highly likely to result in a `405 Method Not Allowed`. `PATCH` is much more likely to succeed.', { + code: 'UNDICI-FETCH-patch' + }); + + patchMethodWarning = true; + } + } + + // 26. If init["signal"] exists, then set signal to it. + if (init.signal !== undefined) { + signal = init.signal; + } + + // 27. Set this’s request to request. + this[kState] = request; + + // 28. Set this’s signal to a new AbortSignal object with this’s relevant + // Realm. + // TODO: could this be simplified with AbortSignal.any + // (https://dom.spec.whatwg.org/#dom-abortsignal-any) + const ac = new AbortController(); + this[kSignal] = ac.signal; + + // 29. If signal is not null, then make this’s signal follow signal. + if (signal != null) { + if ( + !signal || + typeof signal.aborted !== 'boolean' || + typeof signal.addEventListener !== 'function' + ) { + throw new TypeError( + "Failed to construct 'Request': member signal is not of type AbortSignal." + ) + } + + if (signal.aborted) { + ac.abort(signal.reason); + } else { + // Keep a strong ref to ac while request object + // is alive. This is needed to prevent AbortController + // from being prematurely garbage collected. + // See, https://github.com/nodejs/undici/issues/1926. + this[kAbortController] = ac; + + const acRef = new WeakRef(ac); + const abort = buildAbort(acRef); + + // Third-party AbortControllers may not work with these. + // See, https://github.com/nodejs/undici/pull/1910#issuecomment-1464495619. + try { + // If the max amount of listeners is equal to the default, increase it + // This is only available in node >= v19.9.0 + if (typeof getMaxListeners === 'function' && getMaxListeners(signal) === defaultMaxListeners) { + setMaxListeners(1500, signal); + } else if (getEventListeners(signal, 'abort').length >= defaultMaxListeners) { + setMaxListeners(1500, signal); + } + } catch {} + + util.addAbortListener(signal, abort); + // The third argument must be a registry key to be unregistered. + // Without it, you cannot unregister. + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/FinalizationRegistry + // abort is used as the unregister key. (because it is unique) + requestFinalizer.register(ac, { signal, abort }, abort); + } + } + + // 30. Set this’s headers to a new Headers object with this’s relevant + // Realm, whose header list is request’s header list and guard is + // "request". + this[kHeaders] = new Headers(kConstruct); + setHeadersList(this[kHeaders], request.headersList); + setHeadersGuard(this[kHeaders], 'request'); + + // 31. If this’s request’s mode is "no-cors", then: + if (mode === 'no-cors') { + // 1. If this’s request’s method is not a CORS-safelisted method, + // then throw a TypeError. + if (!corsSafeListedMethodsSet.has(request.method)) { + throw new TypeError( + `'${request.method} is unsupported in no-cors mode.` + ) + } + + // 2. Set this’s headers’s guard to "request-no-cors". + setHeadersGuard(this[kHeaders], 'request-no-cors'); + } + + // 32. If init is not empty, then: + if (initHasKey) { + /** @type {HeadersList} */ + const headersList = getHeadersList(this[kHeaders]); + // 1. Let headers be a copy of this’s headers and its associated header + // list. + // 2. If init["headers"] exists, then set headers to init["headers"]. + const headers = init.headers !== undefined ? init.headers : new HeadersList(headersList); + + // 3. Empty this’s headers’s header list. + headersList.clear(); + + // 4. If headers is a Headers object, then for each header in its header + // list, append header’s name/header’s value to this’s headers. + if (headers instanceof HeadersList) { + for (const { name, value } of headers.rawValues()) { + headersList.append(name, value, false); + } + // Note: Copy the `set-cookie` meta-data. + headersList.cookies = headers.cookies; + } else { + // 5. Otherwise, fill this’s headers with headers. + fillHeaders(this[kHeaders], headers); + } + } + + // 33. Let inputBody be input’s request’s body if input is a Request + // object; otherwise null. + const inputBody = input instanceof Request ? input[kState].body : null; + + // 34. If either init["body"] exists and is non-null or inputBody is + // non-null, and request’s method is `GET` or `HEAD`, then throw a + // TypeError. + if ( + (init.body != null || inputBody != null) && + (request.method === 'GET' || request.method === 'HEAD') + ) { + throw new TypeError('Request with GET/HEAD method cannot have body.') + } + + // 35. Let initBody be null. + let initBody = null; + + // 36. If init["body"] exists and is non-null, then: + if (init.body != null) { + // 1. Let Content-Type be null. + // 2. Set initBody and Content-Type to the result of extracting + // init["body"], with keepalive set to request’s keepalive. + const [extractedBody, contentType] = extractBody( + init.body, + request.keepalive + ); + initBody = extractedBody; + + // 3, If Content-Type is non-null and this’s headers’s header list does + // not contain `Content-Type`, then append `Content-Type`/Content-Type to + // this’s headers. + if (contentType && !getHeadersList(this[kHeaders]).contains('content-type', true)) { + this[kHeaders].append('content-type', contentType); + } + } + + // 37. Let inputOrInitBody be initBody if it is non-null; otherwise + // inputBody. + const inputOrInitBody = initBody ?? inputBody; + + // 38. If inputOrInitBody is non-null and inputOrInitBody’s source is + // null, then: + if (inputOrInitBody != null && inputOrInitBody.source == null) { + // 1. If initBody is non-null and init["duplex"] does not exist, + // then throw a TypeError. + if (initBody != null && init.duplex == null) { + throw new TypeError('RequestInit: duplex option is required when sending a body.') + } + + // 2. If this’s request’s mode is neither "same-origin" nor "cors", + // then throw a TypeError. + if (request.mode !== 'same-origin' && request.mode !== 'cors') { + throw new TypeError( + 'If request is made from ReadableStream, mode should be "same-origin" or "cors"' + ) + } + + // 3. Set this’s request’s use-CORS-preflight flag. + request.useCORSPreflightFlag = true; + } + + // 39. Let finalBody be inputOrInitBody. + let finalBody = inputOrInitBody; + + // 40. If initBody is null and inputBody is non-null, then: + if (initBody == null && inputBody != null) { + // 1. If input is unusable, then throw a TypeError. + if (util.isDisturbed(inputBody.stream) || inputBody.stream.locked) { + throw new TypeError( + 'Cannot construct a Request with a Request object that has already been used.' + ) + } + + // 2. Set finalBody to the result of creating a proxy for inputBody. + // https://streams.spec.whatwg.org/#readablestream-create-a-proxy + const identityTransform = new TransformStream(); + inputBody.stream.pipeThrough(identityTransform); + finalBody = { + source: inputBody.source, + length: inputBody.length, + stream: identityTransform.readable + }; + } + + // 41. Set this’s request’s body to finalBody. + this[kState].body = finalBody; + } + + // Returns request’s HTTP method, which is "GET" by default. + get method () { + webidl.brandCheck(this, Request); + + // The method getter steps are to return this’s request’s method. + return this[kState].method + } + + // Returns the URL of request as a string. + get url () { + webidl.brandCheck(this, Request); + + // The url getter steps are to return this’s request’s URL, serialized. + return URLSerializer(this[kState].url) + } + + // Returns a Headers object consisting of the headers associated with request. + // Note that headers added in the network layer by the user agent will not + // be accounted for in this object, e.g., the "Host" header. + get headers () { + webidl.brandCheck(this, Request); + + // The headers getter steps are to return this’s headers. + return this[kHeaders] + } + + // Returns the kind of resource requested by request, e.g., "document" + // or "script". + get destination () { + webidl.brandCheck(this, Request); + + // The destination getter are to return this’s request’s destination. + return this[kState].destination + } + + // Returns the referrer of request. Its value can be a same-origin URL if + // explicitly set in init, the empty string to indicate no referrer, and + // "about:client" when defaulting to the global’s default. This is used + // during fetching to determine the value of the `Referer` header of the + // request being made. + get referrer () { + webidl.brandCheck(this, Request); + + // 1. If this’s request’s referrer is "no-referrer", then return the + // empty string. + if (this[kState].referrer === 'no-referrer') { + return '' + } + + // 2. If this’s request’s referrer is "client", then return + // "about:client". + if (this[kState].referrer === 'client') { + return 'about:client' + } + + // Return this’s request’s referrer, serialized. + return this[kState].referrer.toString() + } + + // Returns the referrer policy associated with request. + // This is used during fetching to compute the value of the request’s + // referrer. + get referrerPolicy () { + webidl.brandCheck(this, Request); + + // The referrerPolicy getter steps are to return this’s request’s referrer policy. + return this[kState].referrerPolicy + } + + // Returns the mode associated with request, which is a string indicating + // whether the request will use CORS, or will be restricted to same-origin + // URLs. + get mode () { + webidl.brandCheck(this, Request); + + // The mode getter steps are to return this’s request’s mode. + return this[kState].mode + } + + // Returns the credentials mode associated with request, + // which is a string indicating whether credentials will be sent with the + // request always, never, or only when sent to a same-origin URL. + get credentials () { + // The credentials getter steps are to return this’s request’s credentials mode. + return this[kState].credentials + } + + // Returns the cache mode associated with request, + // which is a string indicating how the request will + // interact with the browser’s cache when fetching. + get cache () { + webidl.brandCheck(this, Request); + + // The cache getter steps are to return this’s request’s cache mode. + return this[kState].cache + } + + // Returns the redirect mode associated with request, + // which is a string indicating how redirects for the + // request will be handled during fetching. A request + // will follow redirects by default. + get redirect () { + webidl.brandCheck(this, Request); + + // The redirect getter steps are to return this’s request’s redirect mode. + return this[kState].redirect + } + + // Returns request’s subresource integrity metadata, which is a + // cryptographic hash of the resource being fetched. Its value + // consists of multiple hashes separated by whitespace. [SRI] + get integrity () { + webidl.brandCheck(this, Request); + + // The integrity getter steps are to return this’s request’s integrity + // metadata. + return this[kState].integrity + } + + // Returns a boolean indicating whether or not request can outlive the + // global in which it was created. + get keepalive () { + webidl.brandCheck(this, Request); + + // The keepalive getter steps are to return this’s request’s keepalive. + return this[kState].keepalive + } + + // Returns a boolean indicating whether or not request is for a reload + // navigation. + get isReloadNavigation () { + webidl.brandCheck(this, Request); + + // The isReloadNavigation getter steps are to return true if this’s + // request’s reload-navigation flag is set; otherwise false. + return this[kState].reloadNavigation + } + + // Returns a boolean indicating whether or not request is for a history + // navigation (a.k.a. back-forward navigation). + get isHistoryNavigation () { + webidl.brandCheck(this, Request); + + // The isHistoryNavigation getter steps are to return true if this’s request’s + // history-navigation flag is set; otherwise false. + return this[kState].historyNavigation + } + + // Returns the signal associated with request, which is an AbortSignal + // object indicating whether or not request has been aborted, and its + // abort event handler. + get signal () { + webidl.brandCheck(this, Request); + + // The signal getter steps are to return this’s signal. + return this[kSignal] + } + + get body () { + webidl.brandCheck(this, Request); + + return this[kState].body ? this[kState].body.stream : null + } + + get bodyUsed () { + webidl.brandCheck(this, Request); + + return !!this[kState].body && util.isDisturbed(this[kState].body.stream) + } + + get duplex () { + webidl.brandCheck(this, Request); + + return 'half' + } + + // Returns a clone of request. + clone () { + webidl.brandCheck(this, Request); + + // 1. If this is unusable, then throw a TypeError. + if (this.bodyUsed || this.body?.locked) { + throw new TypeError('unusable') + } + + // 2. Let clonedRequest be the result of cloning this’s request. + const clonedRequest = cloneRequest(this[kState]); + + // 3. Let clonedRequestObject be the result of creating a Request object, + // given clonedRequest, this’s headers’s guard, and this’s relevant Realm. + // 4. Make clonedRequestObject’s signal follow this’s signal. + const ac = new AbortController(); + if (this.signal.aborted) { + ac.abort(this.signal.reason); + } else { + let list = dependentControllerMap.get(this.signal); + if (list === undefined) { + list = new Set(); + dependentControllerMap.set(this.signal, list); + } + const acRef = new WeakRef(ac); + list.add(acRef); + util.addAbortListener( + ac.signal, + buildAbort(acRef) + ); + } + + // 4. Return clonedRequestObject. + return fromInnerRequest(clonedRequest, ac.signal, getHeadersGuard(this[kHeaders])) + } + + [nodeUtil.inspect.custom] (depth, options) { + if (options.depth === null) { + options.depth = 2; + } + + options.colors ??= true; + + const properties = { + method: this.method, + url: this.url, + headers: this.headers, + destination: this.destination, + referrer: this.referrer, + referrerPolicy: this.referrerPolicy, + mode: this.mode, + credentials: this.credentials, + cache: this.cache, + redirect: this.redirect, + integrity: this.integrity, + keepalive: this.keepalive, + isReloadNavigation: this.isReloadNavigation, + isHistoryNavigation: this.isHistoryNavigation, + signal: this.signal + }; + + return `Request ${nodeUtil.formatWithOptions(options, properties)}` + } + } + + mixinBody(Request); + + // https://fetch.spec.whatwg.org/#requests + function makeRequest (init) { + return { + method: init.method ?? 'GET', + localURLsOnly: init.localURLsOnly ?? false, + unsafeRequest: init.unsafeRequest ?? false, + body: init.body ?? null, + client: init.client ?? null, + reservedClient: init.reservedClient ?? null, + replacesClientId: init.replacesClientId ?? '', + window: init.window ?? 'client', + keepalive: init.keepalive ?? false, + serviceWorkers: init.serviceWorkers ?? 'all', + initiator: init.initiator ?? '', + destination: init.destination ?? '', + priority: init.priority ?? null, + origin: init.origin ?? 'client', + policyContainer: init.policyContainer ?? 'client', + referrer: init.referrer ?? 'client', + referrerPolicy: init.referrerPolicy ?? '', + mode: init.mode ?? 'no-cors', + useCORSPreflightFlag: init.useCORSPreflightFlag ?? false, + credentials: init.credentials ?? 'same-origin', + useCredentials: init.useCredentials ?? false, + cache: init.cache ?? 'default', + redirect: init.redirect ?? 'follow', + integrity: init.integrity ?? '', + cryptoGraphicsNonceMetadata: init.cryptoGraphicsNonceMetadata ?? '', + parserMetadata: init.parserMetadata ?? '', + reloadNavigation: init.reloadNavigation ?? false, + historyNavigation: init.historyNavigation ?? false, + userActivation: init.userActivation ?? false, + taintedOrigin: init.taintedOrigin ?? false, + redirectCount: init.redirectCount ?? 0, + responseTainting: init.responseTainting ?? 'basic', + preventNoCacheCacheControlHeaderModification: init.preventNoCacheCacheControlHeaderModification ?? false, + done: init.done ?? false, + timingAllowFailed: init.timingAllowFailed ?? false, + urlList: init.urlList, + url: init.urlList[0], + headersList: init.headersList + ? new HeadersList(init.headersList) + : new HeadersList() + } + } + + // https://fetch.spec.whatwg.org/#concept-request-clone + function cloneRequest (request) { + // To clone a request request, run these steps: + + // 1. Let newRequest be a copy of request, except for its body. + const newRequest = makeRequest({ ...request, body: null }); + + // 2. If request’s body is non-null, set newRequest’s body to the + // result of cloning request’s body. + if (request.body != null) { + newRequest.body = cloneBody(request.body); + } + + // 3. Return newRequest. + return newRequest + } + + /** + * @see https://fetch.spec.whatwg.org/#request-create + * @param {any} innerRequest + * @param {AbortSignal} signal + * @param {'request' | 'immutable' | 'request-no-cors' | 'response' | 'none'} guard + * @returns {Request} + */ + function fromInnerRequest (innerRequest, signal, guard) { + const request = new Request(kConstruct); + request[kState] = innerRequest; + request[kSignal] = signal; + request[kHeaders] = new Headers(kConstruct); + setHeadersList(request[kHeaders], innerRequest.headersList); + setHeadersGuard(request[kHeaders], guard); + return request + } + + Object.defineProperties(Request.prototype, { + method: kEnumerableProperty, + url: kEnumerableProperty, + headers: kEnumerableProperty, + redirect: kEnumerableProperty, + clone: kEnumerableProperty, + signal: kEnumerableProperty, + duplex: kEnumerableProperty, + destination: kEnumerableProperty, + body: kEnumerableProperty, + bodyUsed: kEnumerableProperty, + isHistoryNavigation: kEnumerableProperty, + isReloadNavigation: kEnumerableProperty, + keepalive: kEnumerableProperty, + integrity: kEnumerableProperty, + cache: kEnumerableProperty, + credentials: kEnumerableProperty, + attribute: kEnumerableProperty, + referrerPolicy: kEnumerableProperty, + referrer: kEnumerableProperty, + mode: kEnumerableProperty, + [Symbol.toStringTag]: { + value: 'Request', + configurable: true + } + }); + + webidl.converters.Request = webidl.interfaceConverter( + Request + ); + + // https://fetch.spec.whatwg.org/#requestinfo + webidl.converters.RequestInfo = function (V, prefix, argument) { + if (typeof V === 'string') { + return webidl.converters.USVString(V, prefix, argument) + } + + if (V instanceof Request) { + return webidl.converters.Request(V, prefix, argument) + } + + return webidl.converters.USVString(V, prefix, argument) + }; + + webidl.converters.AbortSignal = webidl.interfaceConverter( + AbortSignal + ); + + // https://fetch.spec.whatwg.org/#requestinit + webidl.converters.RequestInit = webidl.dictionaryConverter([ + { + key: 'method', + converter: webidl.converters.ByteString + }, + { + key: 'headers', + converter: webidl.converters.HeadersInit + }, + { + key: 'body', + converter: webidl.nullableConverter( + webidl.converters.BodyInit + ) + }, + { + key: 'referrer', + converter: webidl.converters.USVString + }, + { + key: 'referrerPolicy', + converter: webidl.converters.DOMString, + // https://w3c.github.io/webappsec-referrer-policy/#referrer-policy + allowedValues: referrerPolicy + }, + { + key: 'mode', + converter: webidl.converters.DOMString, + // https://fetch.spec.whatwg.org/#concept-request-mode + allowedValues: requestMode + }, + { + key: 'credentials', + converter: webidl.converters.DOMString, + // https://fetch.spec.whatwg.org/#requestcredentials + allowedValues: requestCredentials + }, + { + key: 'cache', + converter: webidl.converters.DOMString, + // https://fetch.spec.whatwg.org/#requestcache + allowedValues: requestCache + }, + { + key: 'redirect', + converter: webidl.converters.DOMString, + // https://fetch.spec.whatwg.org/#requestredirect + allowedValues: requestRedirect + }, + { + key: 'integrity', + converter: webidl.converters.DOMString + }, + { + key: 'keepalive', + converter: webidl.converters.boolean + }, + { + key: 'signal', + converter: webidl.nullableConverter( + (signal) => webidl.converters.AbortSignal( + signal, + 'RequestInit', + 'signal', + { strict: false } + ) + ) + }, + { + key: 'window', + converter: webidl.converters.any + }, + { + key: 'duplex', + converter: webidl.converters.DOMString, + allowedValues: requestDuplex + }, + { + key: 'dispatcher', // undici specific option + converter: webidl.converters.any + } + ]); + + request = { Request, makeRequest, fromInnerRequest, cloneRequest }; + return request; +} + +var fetch_1; +var hasRequiredFetch; + +function requireFetch () { + if (hasRequiredFetch) return fetch_1; + hasRequiredFetch = 1; + + const { + makeNetworkError, + makeAppropriateNetworkError, + filterResponse, + makeResponse, + fromInnerResponse + } = requireResponse(); + const { HeadersList } = requireHeaders(); + const { Request, cloneRequest } = requireRequest(); + const zlib = require$$1; + const { + bytesMatch, + makePolicyContainer, + clonePolicyContainer, + requestBadPort, + TAOCheck, + appendRequestOriginHeader, + responseLocationURL, + requestCurrentURL, + setRequestReferrerPolicyOnRedirect, + tryUpgradeRequestToAPotentiallyTrustworthyURL, + createOpaqueTimingInfo, + appendFetchMetadata, + corsCheck, + crossOriginResourcePolicyCheck, + determineRequestsReferrer, + coarsenedSharedCurrentTime, + createDeferredPromise, + isBlobLike, + sameOrigin, + isCancelled, + isAborted, + isErrorLike, + fullyReadBody, + readableStreamClose, + isomorphicEncode, + urlIsLocal, + urlIsHttpHttpsScheme, + urlHasHttpsScheme, + clampAndCoarsenConnectionTimingInfo, + simpleRangeHeaderValue, + buildContentRange, + createInflate, + extractMimeType + } = requireUtil$6(); + const { kState, kDispatcher } = requireSymbols$3(); + const assert = require$$0$4; + const { safelyExtractBody, extractBody } = requireBody(); + const { + redirectStatusSet, + nullBodyStatus, + safeMethodsSet, + requestBodyHeader, + subresourceSet + } = requireConstants$2(); + const EE = require$$8; + const { Readable, pipeline, finished } = require$$0$5; + const { addAbortListener, isErrored, isReadable, bufferToLowerCasedHeaderName } = requireUtil$7(); + const { dataURLProcessor, serializeAMimeType, minimizeSupportedMimeType } = requireDataUrl(); + const { getGlobalDispatcher } = requireGlobal(); + const { webidl } = requireWebidl(); + const { STATUS_CODES } = require$$2; + const GET_OR_HEAD = ['GET', 'HEAD']; + + const defaultUserAgent = typeof __UNDICI_IS_NODE__ !== 'undefined' || typeof esbuildDetection !== 'undefined' + ? 'node' + : 'undici'; + + /** @type {import('buffer').resolveObjectURL} */ + let resolveObjectURL; + + class Fetch extends EE { + constructor (dispatcher) { + super(); + + this.dispatcher = dispatcher; + this.connection = null; + this.dump = false; + this.state = 'ongoing'; + } + + terminate (reason) { + if (this.state !== 'ongoing') { + return + } + + this.state = 'terminated'; + this.connection?.destroy(reason); + this.emit('terminated', reason); + } + + // https://fetch.spec.whatwg.org/#fetch-controller-abort + abort (error) { + if (this.state !== 'ongoing') { + return + } + + // 1. Set controller’s state to "aborted". + this.state = 'aborted'; + + // 2. Let fallbackError be an "AbortError" DOMException. + // 3. Set error to fallbackError if it is not given. + if (!error) { + error = new DOMException('The operation was aborted.', 'AbortError'); + } + + // 4. Let serializedError be StructuredSerialize(error). + // If that threw an exception, catch it, and let + // serializedError be StructuredSerialize(fallbackError). + + // 5. Set controller’s serialized abort reason to serializedError. + this.serializedAbortReason = error; + + this.connection?.destroy(error); + this.emit('terminated', error); + } + } + + function handleFetchDone (response) { + finalizeAndReportTiming(response, 'fetch'); + } + + // https://fetch.spec.whatwg.org/#fetch-method + function fetch (input, init = undefined) { + webidl.argumentLengthCheck(arguments, 1, 'globalThis.fetch'); + + // 1. Let p be a new promise. + let p = createDeferredPromise(); + + // 2. Let requestObject be the result of invoking the initial value of + // Request as constructor with input and init as arguments. If this throws + // an exception, reject p with it and return p. + let requestObject; + + try { + requestObject = new Request(input, init); + } catch (e) { + p.reject(e); + return p.promise + } + + // 3. Let request be requestObject’s request. + const request = requestObject[kState]; + + // 4. If requestObject’s signal’s aborted flag is set, then: + if (requestObject.signal.aborted) { + // 1. Abort the fetch() call with p, request, null, and + // requestObject’s signal’s abort reason. + abortFetch(p, request, null, requestObject.signal.reason); + + // 2. Return p. + return p.promise + } + + // 5. Let globalObject be request’s client’s global object. + const globalObject = request.client.globalObject; + + // 6. If globalObject is a ServiceWorkerGlobalScope object, then set + // request’s service-workers mode to "none". + if (globalObject?.constructor?.name === 'ServiceWorkerGlobalScope') { + request.serviceWorkers = 'none'; + } + + // 7. Let responseObject be null. + let responseObject = null; + + // 8. Let relevantRealm be this’s relevant Realm. + + // 9. Let locallyAborted be false. + let locallyAborted = false; + + // 10. Let controller be null. + let controller = null; + + // 11. Add the following abort steps to requestObject’s signal: + addAbortListener( + requestObject.signal, + () => { + // 1. Set locallyAborted to true. + locallyAborted = true; + + // 2. Assert: controller is non-null. + assert(controller != null); + + // 3. Abort controller with requestObject’s signal’s abort reason. + controller.abort(requestObject.signal.reason); + + const realResponse = responseObject?.deref(); + + // 4. Abort the fetch() call with p, request, responseObject, + // and requestObject’s signal’s abort reason. + abortFetch(p, request, realResponse, requestObject.signal.reason); + } + ); + + // 12. Let handleFetchDone given response response be to finalize and + // report timing with response, globalObject, and "fetch". + // see function handleFetchDone + + // 13. Set controller to the result of calling fetch given request, + // with processResponseEndOfBody set to handleFetchDone, and processResponse + // given response being these substeps: + + const processResponse = (response) => { + // 1. If locallyAborted is true, terminate these substeps. + if (locallyAborted) { + return + } + + // 2. If response’s aborted flag is set, then: + if (response.aborted) { + // 1. Let deserializedError be the result of deserialize a serialized + // abort reason given controller’s serialized abort reason and + // relevantRealm. + + // 2. Abort the fetch() call with p, request, responseObject, and + // deserializedError. + + abortFetch(p, request, responseObject, controller.serializedAbortReason); + return + } + + // 3. If response is a network error, then reject p with a TypeError + // and terminate these substeps. + if (response.type === 'error') { + p.reject(new TypeError('fetch failed', { cause: response.error })); + return + } + + // 4. Set responseObject to the result of creating a Response object, + // given response, "immutable", and relevantRealm. + responseObject = new WeakRef(fromInnerResponse(response, 'immutable')); + + // 5. Resolve p with responseObject. + p.resolve(responseObject.deref()); + p = null; + }; + + controller = fetching({ + request, + processResponseEndOfBody: handleFetchDone, + processResponse, + dispatcher: requestObject[kDispatcher] // undici + }); + + // 14. Return p. + return p.promise + } + + // https://fetch.spec.whatwg.org/#finalize-and-report-timing + function finalizeAndReportTiming (response, initiatorType = 'other') { + // 1. If response is an aborted network error, then return. + if (response.type === 'error' && response.aborted) { + return + } + + // 2. If response’s URL list is null or empty, then return. + if (!response.urlList?.length) { + return + } + + // 3. Let originalURL be response’s URL list[0]. + const originalURL = response.urlList[0]; + + // 4. Let timingInfo be response’s timing info. + let timingInfo = response.timingInfo; + + // 5. Let cacheState be response’s cache state. + let cacheState = response.cacheState; + + // 6. If originalURL’s scheme is not an HTTP(S) scheme, then return. + if (!urlIsHttpHttpsScheme(originalURL)) { + return + } + + // 7. If timingInfo is null, then return. + if (timingInfo === null) { + return + } + + // 8. If response’s timing allow passed flag is not set, then: + if (!response.timingAllowPassed) { + // 1. Set timingInfo to a the result of creating an opaque timing info for timingInfo. + timingInfo = createOpaqueTimingInfo({ + startTime: timingInfo.startTime + }); + + // 2. Set cacheState to the empty string. + cacheState = ''; + } + + // 9. Set timingInfo’s end time to the coarsened shared current time + // given global’s relevant settings object’s cross-origin isolated + // capability. + // TODO: given global’s relevant settings object’s cross-origin isolated + // capability? + timingInfo.endTime = coarsenedSharedCurrentTime(); + + // 10. Set response’s timing info to timingInfo. + response.timingInfo = timingInfo; + + // 11. Mark resource timing for timingInfo, originalURL, initiatorType, + // global, and cacheState. + markResourceTiming( + timingInfo, + originalURL.href, + initiatorType, + globalThis, + cacheState + ); + } + + // https://w3c.github.io/resource-timing/#dfn-mark-resource-timing + const markResourceTiming = performance.markResourceTiming; + + // https://fetch.spec.whatwg.org/#abort-fetch + function abortFetch (p, request, responseObject, error) { + // 1. Reject promise with error. + if (p) { + // We might have already resolved the promise at this stage + p.reject(error); + } + + // 2. If request’s body is not null and is readable, then cancel request’s + // body with error. + if (request.body != null && isReadable(request.body?.stream)) { + request.body.stream.cancel(error).catch((err) => { + if (err.code === 'ERR_INVALID_STATE') { + // Node bug? + return + } + throw err + }); + } + + // 3. If responseObject is null, then return. + if (responseObject == null) { + return + } + + // 4. Let response be responseObject’s response. + const response = responseObject[kState]; + + // 5. If response’s body is not null and is readable, then error response’s + // body with error. + if (response.body != null && isReadable(response.body?.stream)) { + response.body.stream.cancel(error).catch((err) => { + if (err.code === 'ERR_INVALID_STATE') { + // Node bug? + return + } + throw err + }); + } + } + + // https://fetch.spec.whatwg.org/#fetching + function fetching ({ + request, + processRequestBodyChunkLength, + processRequestEndOfBody, + processResponse, + processResponseEndOfBody, + processResponseConsumeBody, + useParallelQueue = false, + dispatcher = getGlobalDispatcher() // undici + }) { + // Ensure that the dispatcher is set accordingly + assert(dispatcher); + + // 1. Let taskDestination be null. + let taskDestination = null; + + // 2. Let crossOriginIsolatedCapability be false. + let crossOriginIsolatedCapability = false; + + // 3. If request’s client is non-null, then: + if (request.client != null) { + // 1. Set taskDestination to request’s client’s global object. + taskDestination = request.client.globalObject; + + // 2. Set crossOriginIsolatedCapability to request’s client’s cross-origin + // isolated capability. + crossOriginIsolatedCapability = + request.client.crossOriginIsolatedCapability; + } + + // 4. If useParallelQueue is true, then set taskDestination to the result of + // starting a new parallel queue. + // TODO + + // 5. Let timingInfo be a new fetch timing info whose start time and + // post-redirect start time are the coarsened shared current time given + // crossOriginIsolatedCapability. + const currentTime = coarsenedSharedCurrentTime(crossOriginIsolatedCapability); + const timingInfo = createOpaqueTimingInfo({ + startTime: currentTime + }); + + // 6. Let fetchParams be a new fetch params whose + // request is request, + // timing info is timingInfo, + // process request body chunk length is processRequestBodyChunkLength, + // process request end-of-body is processRequestEndOfBody, + // process response is processResponse, + // process response consume body is processResponseConsumeBody, + // process response end-of-body is processResponseEndOfBody, + // task destination is taskDestination, + // and cross-origin isolated capability is crossOriginIsolatedCapability. + const fetchParams = { + controller: new Fetch(dispatcher), + request, + timingInfo, + processRequestBodyChunkLength, + processRequestEndOfBody, + processResponse, + processResponseConsumeBody, + processResponseEndOfBody, + taskDestination, + crossOriginIsolatedCapability + }; + + // 7. If request’s body is a byte sequence, then set request’s body to + // request’s body as a body. + // NOTE: Since fetching is only called from fetch, body should already be + // extracted. + assert(!request.body || request.body.stream); + + // 8. If request’s window is "client", then set request’s window to request’s + // client, if request’s client’s global object is a Window object; otherwise + // "no-window". + if (request.window === 'client') { + // TODO: What if request.client is null? + request.window = + request.client?.globalObject?.constructor?.name === 'Window' + ? request.client + : 'no-window'; + } + + // 9. If request’s origin is "client", then set request’s origin to request’s + // client’s origin. + if (request.origin === 'client') { + request.origin = request.client.origin; + } + + // 10. If all of the following conditions are true: + // TODO + + // 11. If request’s policy container is "client", then: + if (request.policyContainer === 'client') { + // 1. If request’s client is non-null, then set request’s policy + // container to a clone of request’s client’s policy container. [HTML] + if (request.client != null) { + request.policyContainer = clonePolicyContainer( + request.client.policyContainer + ); + } else { + // 2. Otherwise, set request’s policy container to a new policy + // container. + request.policyContainer = makePolicyContainer(); + } + } + + // 12. If request’s header list does not contain `Accept`, then: + if (!request.headersList.contains('accept', true)) { + // 1. Let value be `*/*`. + const value = '*/*'; + + // 2. A user agent should set value to the first matching statement, if + // any, switching on request’s destination: + // "document" + // "frame" + // "iframe" + // `text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8` + // "image" + // `image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5` + // "style" + // `text/css,*/*;q=0.1` + // TODO + + // 3. Append `Accept`/value to request’s header list. + request.headersList.append('accept', value, true); + } + + // 13. If request’s header list does not contain `Accept-Language`, then + // user agents should append `Accept-Language`/an appropriate value to + // request’s header list. + if (!request.headersList.contains('accept-language', true)) { + request.headersList.append('accept-language', '*', true); + } + + // 14. If request’s priority is null, then use request’s initiator and + // destination appropriately in setting request’s priority to a + // user-agent-defined object. + if (request.priority === null) ; + + // 15. If request is a subresource request, then: + if (subresourceSet.has(request.destination)) ; + + // 16. Run main fetch given fetchParams. + mainFetch(fetchParams) + .catch(err => { + fetchParams.controller.terminate(err); + }); + + // 17. Return fetchParam's controller + return fetchParams.controller + } + + // https://fetch.spec.whatwg.org/#concept-main-fetch + async function mainFetch (fetchParams, recursive = false) { + // 1. Let request be fetchParams’s request. + const request = fetchParams.request; + + // 2. Let response be null. + let response = null; + + // 3. If request’s local-URLs-only flag is set and request’s current URL is + // not local, then set response to a network error. + if (request.localURLsOnly && !urlIsLocal(requestCurrentURL(request))) { + response = makeNetworkError('local URLs only'); + } + + // 4. Run report Content Security Policy violations for request. + // TODO + + // 5. Upgrade request to a potentially trustworthy URL, if appropriate. + tryUpgradeRequestToAPotentiallyTrustworthyURL(request); + + // 6. If should request be blocked due to a bad port, should fetching request + // be blocked as mixed content, or should request be blocked by Content + // Security Policy returns blocked, then set response to a network error. + if (requestBadPort(request) === 'blocked') { + response = makeNetworkError('bad port'); + } + // TODO: should fetching request be blocked as mixed content? + // TODO: should request be blocked by Content Security Policy? + + // 7. If request’s referrer policy is the empty string, then set request’s + // referrer policy to request’s policy container’s referrer policy. + if (request.referrerPolicy === '') { + request.referrerPolicy = request.policyContainer.referrerPolicy; + } + + // 8. If request’s referrer is not "no-referrer", then set request’s + // referrer to the result of invoking determine request’s referrer. + if (request.referrer !== 'no-referrer') { + request.referrer = determineRequestsReferrer(request); + } + + // 9. Set request’s current URL’s scheme to "https" if all of the following + // conditions are true: + // - request’s current URL’s scheme is "http" + // - request’s current URL’s host is a domain + // - Matching request’s current URL’s host per Known HSTS Host Domain Name + // Matching results in either a superdomain match with an asserted + // includeSubDomains directive or a congruent match (with or without an + // asserted includeSubDomains directive). [HSTS] + // TODO + + // 10. If recursive is false, then run the remaining steps in parallel. + // TODO + + // 11. If response is null, then set response to the result of running + // the steps corresponding to the first matching statement: + if (response === null) { + response = await (async () => { + const currentURL = requestCurrentURL(request); + + if ( + // - request’s current URL’s origin is same origin with request’s origin, + // and request’s response tainting is "basic" + (sameOrigin(currentURL, request.url) && request.responseTainting === 'basic') || + // request’s current URL’s scheme is "data" + (currentURL.protocol === 'data:') || + // - request’s mode is "navigate" or "websocket" + (request.mode === 'navigate' || request.mode === 'websocket') + ) { + // 1. Set request’s response tainting to "basic". + request.responseTainting = 'basic'; + + // 2. Return the result of running scheme fetch given fetchParams. + return await schemeFetch(fetchParams) + } + + // request’s mode is "same-origin" + if (request.mode === 'same-origin') { + // 1. Return a network error. + return makeNetworkError('request mode cannot be "same-origin"') + } + + // request’s mode is "no-cors" + if (request.mode === 'no-cors') { + // 1. If request’s redirect mode is not "follow", then return a network + // error. + if (request.redirect !== 'follow') { + return makeNetworkError( + 'redirect mode cannot be "follow" for "no-cors" request' + ) + } + + // 2. Set request’s response tainting to "opaque". + request.responseTainting = 'opaque'; + + // 3. Return the result of running scheme fetch given fetchParams. + return await schemeFetch(fetchParams) + } + + // request’s current URL’s scheme is not an HTTP(S) scheme + if (!urlIsHttpHttpsScheme(requestCurrentURL(request))) { + // Return a network error. + return makeNetworkError('URL scheme must be a HTTP(S) scheme') + } + + // - request’s use-CORS-preflight flag is set + // - request’s unsafe-request flag is set and either request’s method is + // not a CORS-safelisted method or CORS-unsafe request-header names with + // request’s header list is not empty + // 1. Set request’s response tainting to "cors". + // 2. Let corsWithPreflightResponse be the result of running HTTP fetch + // given fetchParams and true. + // 3. If corsWithPreflightResponse is a network error, then clear cache + // entries using request. + // 4. Return corsWithPreflightResponse. + // TODO + + // Otherwise + // 1. Set request’s response tainting to "cors". + request.responseTainting = 'cors'; + + // 2. Return the result of running HTTP fetch given fetchParams. + return await httpFetch(fetchParams) + })(); + } + + // 12. If recursive is true, then return response. + if (recursive) { + return response + } + + // 13. If response is not a network error and response is not a filtered + // response, then: + if (response.status !== 0 && !response.internalResponse) { + // If request’s response tainting is "cors", then: + if (request.responseTainting === 'cors') ; + + // Set response to the following filtered response with response as its + // internal response, depending on request’s response tainting: + if (request.responseTainting === 'basic') { + response = filterResponse(response, 'basic'); + } else if (request.responseTainting === 'cors') { + response = filterResponse(response, 'cors'); + } else if (request.responseTainting === 'opaque') { + response = filterResponse(response, 'opaque'); + } else { + assert(false); + } + } + + // 14. Let internalResponse be response, if response is a network error, + // and response’s internal response otherwise. + let internalResponse = + response.status === 0 ? response : response.internalResponse; + + // 15. If internalResponse’s URL list is empty, then set it to a clone of + // request’s URL list. + if (internalResponse.urlList.length === 0) { + internalResponse.urlList.push(...request.urlList); + } + + // 16. If request’s timing allow failed flag is unset, then set + // internalResponse’s timing allow passed flag. + if (!request.timingAllowFailed) { + response.timingAllowPassed = true; + } + + // 17. If response is not a network error and any of the following returns + // blocked + // - should internalResponse to request be blocked as mixed content + // - should internalResponse to request be blocked by Content Security Policy + // - should internalResponse to request be blocked due to its MIME type + // - should internalResponse to request be blocked due to nosniff + // TODO + + // 18. If response’s type is "opaque", internalResponse’s status is 206, + // internalResponse’s range-requested flag is set, and request’s header + // list does not contain `Range`, then set response and internalResponse + // to a network error. + if ( + response.type === 'opaque' && + internalResponse.status === 206 && + internalResponse.rangeRequested && + !request.headers.contains('range', true) + ) { + response = internalResponse = makeNetworkError(); + } + + // 19. If response is not a network error and either request’s method is + // `HEAD` or `CONNECT`, or internalResponse’s status is a null body status, + // set internalResponse’s body to null and disregard any enqueuing toward + // it (if any). + if ( + response.status !== 0 && + (request.method === 'HEAD' || + request.method === 'CONNECT' || + nullBodyStatus.includes(internalResponse.status)) + ) { + internalResponse.body = null; + fetchParams.controller.dump = true; + } + + // 20. If request’s integrity metadata is not the empty string, then: + if (request.integrity) { + // 1. Let processBodyError be this step: run fetch finale given fetchParams + // and a network error. + const processBodyError = (reason) => + fetchFinale(fetchParams, makeNetworkError(reason)); + + // 2. If request’s response tainting is "opaque", or response’s body is null, + // then run processBodyError and abort these steps. + if (request.responseTainting === 'opaque' || response.body == null) { + processBodyError(response.error); + return + } + + // 3. Let processBody given bytes be these steps: + const processBody = (bytes) => { + // 1. If bytes do not match request’s integrity metadata, + // then run processBodyError and abort these steps. [SRI] + if (!bytesMatch(bytes, request.integrity)) { + processBodyError('integrity mismatch'); + return + } + + // 2. Set response’s body to bytes as a body. + response.body = safelyExtractBody(bytes)[0]; + + // 3. Run fetch finale given fetchParams and response. + fetchFinale(fetchParams, response); + }; + + // 4. Fully read response’s body given processBody and processBodyError. + await fullyReadBody(response.body, processBody, processBodyError); + } else { + // 21. Otherwise, run fetch finale given fetchParams and response. + fetchFinale(fetchParams, response); + } + } + + // https://fetch.spec.whatwg.org/#concept-scheme-fetch + // given a fetch params fetchParams + function schemeFetch (fetchParams) { + // Note: since the connection is destroyed on redirect, which sets fetchParams to a + // cancelled state, we do not want this condition to trigger *unless* there have been + // no redirects. See https://github.com/nodejs/undici/issues/1776 + // 1. If fetchParams is canceled, then return the appropriate network error for fetchParams. + if (isCancelled(fetchParams) && fetchParams.request.redirectCount === 0) { + return Promise.resolve(makeAppropriateNetworkError(fetchParams)) + } + + // 2. Let request be fetchParams’s request. + const { request } = fetchParams; + + const { protocol: scheme } = requestCurrentURL(request); + + // 3. Switch on request’s current URL’s scheme and run the associated steps: + switch (scheme) { + case 'about:': { + // If request’s current URL’s path is the string "blank", then return a new response + // whose status message is `OK`, header list is « (`Content-Type`, `text/html;charset=utf-8`) », + // and body is the empty byte sequence as a body. + + // Otherwise, return a network error. + return Promise.resolve(makeNetworkError('about scheme is not supported')) + } + case 'blob:': { + if (!resolveObjectURL) { + resolveObjectURL = require$$0$3.resolveObjectURL; + } + + // 1. Let blobURLEntry be request’s current URL’s blob URL entry. + const blobURLEntry = requestCurrentURL(request); + + // https://github.com/web-platform-tests/wpt/blob/7b0ebaccc62b566a1965396e5be7bb2bc06f841f/FileAPI/url/resources/fetch-tests.js#L52-L56 + // Buffer.resolveObjectURL does not ignore URL queries. + if (blobURLEntry.search.length !== 0) { + return Promise.resolve(makeNetworkError('NetworkError when attempting to fetch resource.')) + } + + const blob = resolveObjectURL(blobURLEntry.toString()); + + // 2. If request’s method is not `GET`, blobURLEntry is null, or blobURLEntry’s + // object is not a Blob object, then return a network error. + if (request.method !== 'GET' || !isBlobLike(blob)) { + return Promise.resolve(makeNetworkError('invalid method')) + } + + // 3. Let blob be blobURLEntry’s object. + // Note: done above + + // 4. Let response be a new response. + const response = makeResponse(); + + // 5. Let fullLength be blob’s size. + const fullLength = blob.size; + + // 6. Let serializedFullLength be fullLength, serialized and isomorphic encoded. + const serializedFullLength = isomorphicEncode(`${fullLength}`); + + // 7. Let type be blob’s type. + const type = blob.type; + + // 8. If request’s header list does not contain `Range`: + // 9. Otherwise: + if (!request.headersList.contains('range', true)) { + // 1. Let bodyWithType be the result of safely extracting blob. + // Note: in the FileAPI a blob "object" is a Blob *or* a MediaSource. + // In node, this can only ever be a Blob. Therefore we can safely + // use extractBody directly. + const bodyWithType = extractBody(blob); + + // 2. Set response’s status message to `OK`. + response.statusText = 'OK'; + + // 3. Set response’s body to bodyWithType’s body. + response.body = bodyWithType[0]; + + // 4. Set response’s header list to « (`Content-Length`, serializedFullLength), (`Content-Type`, type) ». + response.headersList.set('content-length', serializedFullLength, true); + response.headersList.set('content-type', type, true); + } else { + // 1. Set response’s range-requested flag. + response.rangeRequested = true; + + // 2. Let rangeHeader be the result of getting `Range` from request’s header list. + const rangeHeader = request.headersList.get('range', true); + + // 3. Let rangeValue be the result of parsing a single range header value given rangeHeader and true. + const rangeValue = simpleRangeHeaderValue(rangeHeader, true); + + // 4. If rangeValue is failure, then return a network error. + if (rangeValue === 'failure') { + return Promise.resolve(makeNetworkError('failed to fetch the data URL')) + } + + // 5. Let (rangeStart, rangeEnd) be rangeValue. + let { rangeStartValue: rangeStart, rangeEndValue: rangeEnd } = rangeValue; + + // 6. If rangeStart is null: + // 7. Otherwise: + if (rangeStart === null) { + // 1. Set rangeStart to fullLength − rangeEnd. + rangeStart = fullLength - rangeEnd; + + // 2. Set rangeEnd to rangeStart + rangeEnd − 1. + rangeEnd = rangeStart + rangeEnd - 1; + } else { + // 1. If rangeStart is greater than or equal to fullLength, then return a network error. + if (rangeStart >= fullLength) { + return Promise.resolve(makeNetworkError('Range start is greater than the blob\'s size.')) + } + + // 2. If rangeEnd is null or rangeEnd is greater than or equal to fullLength, then set + // rangeEnd to fullLength − 1. + if (rangeEnd === null || rangeEnd >= fullLength) { + rangeEnd = fullLength - 1; + } + } + + // 8. Let slicedBlob be the result of invoking slice blob given blob, rangeStart, + // rangeEnd + 1, and type. + const slicedBlob = blob.slice(rangeStart, rangeEnd, type); + + // 9. Let slicedBodyWithType be the result of safely extracting slicedBlob. + // Note: same reason as mentioned above as to why we use extractBody + const slicedBodyWithType = extractBody(slicedBlob); + + // 10. Set response’s body to slicedBodyWithType’s body. + response.body = slicedBodyWithType[0]; + + // 11. Let serializedSlicedLength be slicedBlob’s size, serialized and isomorphic encoded. + const serializedSlicedLength = isomorphicEncode(`${slicedBlob.size}`); + + // 12. Let contentRange be the result of invoking build a content range given rangeStart, + // rangeEnd, and fullLength. + const contentRange = buildContentRange(rangeStart, rangeEnd, fullLength); + + // 13. Set response’s status to 206. + response.status = 206; + + // 14. Set response’s status message to `Partial Content`. + response.statusText = 'Partial Content'; + + // 15. Set response’s header list to « (`Content-Length`, serializedSlicedLength), + // (`Content-Type`, type), (`Content-Range`, contentRange) ». + response.headersList.set('content-length', serializedSlicedLength, true); + response.headersList.set('content-type', type, true); + response.headersList.set('content-range', contentRange, true); + } + + // 10. Return response. + return Promise.resolve(response) + } + case 'data:': { + // 1. Let dataURLStruct be the result of running the + // data: URL processor on request’s current URL. + const currentURL = requestCurrentURL(request); + const dataURLStruct = dataURLProcessor(currentURL); + + // 2. If dataURLStruct is failure, then return a + // network error. + if (dataURLStruct === 'failure') { + return Promise.resolve(makeNetworkError('failed to fetch the data URL')) + } + + // 3. Let mimeType be dataURLStruct’s MIME type, serialized. + const mimeType = serializeAMimeType(dataURLStruct.mimeType); + + // 4. Return a response whose status message is `OK`, + // header list is « (`Content-Type`, mimeType) », + // and body is dataURLStruct’s body as a body. + return Promise.resolve(makeResponse({ + statusText: 'OK', + headersList: [ + ['content-type', { name: 'Content-Type', value: mimeType }] + ], + body: safelyExtractBody(dataURLStruct.body)[0] + })) + } + case 'file:': { + // For now, unfortunate as it is, file URLs are left as an exercise for the reader. + // When in doubt, return a network error. + return Promise.resolve(makeNetworkError('not implemented... yet...')) + } + case 'http:': + case 'https:': { + // Return the result of running HTTP fetch given fetchParams. + + return httpFetch(fetchParams) + .catch((err) => makeNetworkError(err)) + } + default: { + return Promise.resolve(makeNetworkError('unknown scheme')) + } + } + } + + // https://fetch.spec.whatwg.org/#finalize-response + function finalizeResponse (fetchParams, response) { + // 1. Set fetchParams’s request’s done flag. + fetchParams.request.done = true; + + // 2, If fetchParams’s process response done is not null, then queue a fetch + // task to run fetchParams’s process response done given response, with + // fetchParams’s task destination. + if (fetchParams.processResponseDone != null) { + queueMicrotask(() => fetchParams.processResponseDone(response)); + } + } + + // https://fetch.spec.whatwg.org/#fetch-finale + function fetchFinale (fetchParams, response) { + // 1. Let timingInfo be fetchParams’s timing info. + let timingInfo = fetchParams.timingInfo; + + // 2. If response is not a network error and fetchParams’s request’s client is a secure context, + // then set timingInfo’s server-timing headers to the result of getting, decoding, and splitting + // `Server-Timing` from response’s internal response’s header list. + // TODO + + // 3. Let processResponseEndOfBody be the following steps: + const processResponseEndOfBody = () => { + // 1. Let unsafeEndTime be the unsafe shared current time. + const unsafeEndTime = Date.now(); // ? + + // 2. If fetchParams’s request’s destination is "document", then set fetchParams’s controller’s + // full timing info to fetchParams’s timing info. + if (fetchParams.request.destination === 'document') { + fetchParams.controller.fullTimingInfo = timingInfo; + } + + // 3. Set fetchParams’s controller’s report timing steps to the following steps given a global object global: + fetchParams.controller.reportTimingSteps = () => { + // 1. If fetchParams’s request’s URL’s scheme is not an HTTP(S) scheme, then return. + if (fetchParams.request.url.protocol !== 'https:') { + return + } + + // 2. Set timingInfo’s end time to the relative high resolution time given unsafeEndTime and global. + timingInfo.endTime = unsafeEndTime; + + // 3. Let cacheState be response’s cache state. + let cacheState = response.cacheState; + + // 4. Let bodyInfo be response’s body info. + const bodyInfo = response.bodyInfo; + + // 5. If response’s timing allow passed flag is not set, then set timingInfo to the result of creating an + // opaque timing info for timingInfo and set cacheState to the empty string. + if (!response.timingAllowPassed) { + timingInfo = createOpaqueTimingInfo(timingInfo); + + cacheState = ''; + } + + // 6. Let responseStatus be 0. + let responseStatus = 0; + + // 7. If fetchParams’s request’s mode is not "navigate" or response’s has-cross-origin-redirects is false: + if (fetchParams.request.mode !== 'navigator' || !response.hasCrossOriginRedirects) { + // 1. Set responseStatus to response’s status. + responseStatus = response.status; + + // 2. Let mimeType be the result of extracting a MIME type from response’s header list. + const mimeType = extractMimeType(response.headersList); + + // 3. If mimeType is not failure, then set bodyInfo’s content type to the result of minimizing a supported MIME type given mimeType. + if (mimeType !== 'failure') { + bodyInfo.contentType = minimizeSupportedMimeType(mimeType); + } + } + + // 8. If fetchParams’s request’s initiator type is non-null, then mark resource timing given timingInfo, + // fetchParams’s request’s URL, fetchParams’s request’s initiator type, global, cacheState, bodyInfo, + // and responseStatus. + if (fetchParams.request.initiatorType != null) { + // TODO: update markresourcetiming + markResourceTiming(timingInfo, fetchParams.request.url.href, fetchParams.request.initiatorType, globalThis, cacheState, bodyInfo, responseStatus); + } + }; + + // 4. Let processResponseEndOfBodyTask be the following steps: + const processResponseEndOfBodyTask = () => { + // 1. Set fetchParams’s request’s done flag. + fetchParams.request.done = true; + + // 2. If fetchParams’s process response end-of-body is non-null, then run fetchParams’s process + // response end-of-body given response. + if (fetchParams.processResponseEndOfBody != null) { + queueMicrotask(() => fetchParams.processResponseEndOfBody(response)); + } + + // 3. If fetchParams’s request’s initiator type is non-null and fetchParams’s request’s client’s + // global object is fetchParams’s task destination, then run fetchParams’s controller’s report + // timing steps given fetchParams’s request’s client’s global object. + if (fetchParams.request.initiatorType != null) { + fetchParams.controller.reportTimingSteps(); + } + }; + + // 5. Queue a fetch task to run processResponseEndOfBodyTask with fetchParams’s task destination + queueMicrotask(() => processResponseEndOfBodyTask()); + }; + + // 4. If fetchParams’s process response is non-null, then queue a fetch task to run fetchParams’s + // process response given response, with fetchParams’s task destination. + if (fetchParams.processResponse != null) { + queueMicrotask(() => { + fetchParams.processResponse(response); + fetchParams.processResponse = null; + }); + } + + // 5. Let internalResponse be response, if response is a network error; otherwise response’s internal response. + const internalResponse = response.type === 'error' ? response : (response.internalResponse ?? response); + + // 6. If internalResponse’s body is null, then run processResponseEndOfBody. + // 7. Otherwise: + if (internalResponse.body == null) { + processResponseEndOfBody(); + } else { + // mcollina: all the following steps of the specs are skipped. + // The internal transform stream is not needed. + // See https://github.com/nodejs/undici/pull/3093#issuecomment-2050198541 + + // 1. Let transformStream be a new TransformStream. + // 2. Let identityTransformAlgorithm be an algorithm which, given chunk, enqueues chunk in transformStream. + // 3. Set up transformStream with transformAlgorithm set to identityTransformAlgorithm and flushAlgorithm + // set to processResponseEndOfBody. + // 4. Set internalResponse’s body’s stream to the result of internalResponse’s body’s stream piped through transformStream. + + finished(internalResponse.body.stream, () => { + processResponseEndOfBody(); + }); + } + } + + // https://fetch.spec.whatwg.org/#http-fetch + async function httpFetch (fetchParams) { + // 1. Let request be fetchParams’s request. + const request = fetchParams.request; + + // 2. Let response be null. + let response = null; + + // 3. Let actualResponse be null. + let actualResponse = null; + + // 4. Let timingInfo be fetchParams’s timing info. + const timingInfo = fetchParams.timingInfo; + + // 5. If request’s service-workers mode is "all", then: + if (request.serviceWorkers === 'all') ; + + // 6. If response is null, then: + if (response === null) { + // 1. If makeCORSPreflight is true and one of these conditions is true: + // TODO + + // 2. If request’s redirect mode is "follow", then set request’s + // service-workers mode to "none". + if (request.redirect === 'follow') { + request.serviceWorkers = 'none'; + } + + // 3. Set response and actualResponse to the result of running + // HTTP-network-or-cache fetch given fetchParams. + actualResponse = response = await httpNetworkOrCacheFetch(fetchParams); + + // 4. If request’s response tainting is "cors" and a CORS check + // for request and response returns failure, then return a network error. + if ( + request.responseTainting === 'cors' && + corsCheck(request, response) === 'failure' + ) { + return makeNetworkError('cors failure') + } + + // 5. If the TAO check for request and response returns failure, then set + // request’s timing allow failed flag. + if (TAOCheck(request, response) === 'failure') { + request.timingAllowFailed = true; + } + } + + // 7. If either request’s response tainting or response’s type + // is "opaque", and the cross-origin resource policy check with + // request’s origin, request’s client, request’s destination, + // and actualResponse returns blocked, then return a network error. + if ( + (request.responseTainting === 'opaque' || response.type === 'opaque') && + crossOriginResourcePolicyCheck( + request.origin, + request.client, + request.destination, + actualResponse + ) === 'blocked' + ) { + return makeNetworkError('blocked') + } + + // 8. If actualResponse’s status is a redirect status, then: + if (redirectStatusSet.has(actualResponse.status)) { + // 1. If actualResponse’s status is not 303, request’s body is not null, + // and the connection uses HTTP/2, then user agents may, and are even + // encouraged to, transmit an RST_STREAM frame. + // See, https://github.com/whatwg/fetch/issues/1288 + if (request.redirect !== 'manual') { + fetchParams.controller.connection.destroy(undefined, false); + } + + // 2. Switch on request’s redirect mode: + if (request.redirect === 'error') { + // Set response to a network error. + response = makeNetworkError('unexpected redirect'); + } else if (request.redirect === 'manual') { + // Set response to an opaque-redirect filtered response whose internal + // response is actualResponse. + // NOTE(spec): On the web this would return an `opaqueredirect` response, + // but that doesn't make sense server side. + // See https://github.com/nodejs/undici/issues/1193. + response = actualResponse; + } else if (request.redirect === 'follow') { + // Set response to the result of running HTTP-redirect fetch given + // fetchParams and response. + response = await httpRedirectFetch(fetchParams, response); + } else { + assert(false); + } + } + + // 9. Set response’s timing info to timingInfo. + response.timingInfo = timingInfo; + + // 10. Return response. + return response + } + + // https://fetch.spec.whatwg.org/#http-redirect-fetch + function httpRedirectFetch (fetchParams, response) { + // 1. Let request be fetchParams’s request. + const request = fetchParams.request; + + // 2. Let actualResponse be response, if response is not a filtered response, + // and response’s internal response otherwise. + const actualResponse = response.internalResponse + ? response.internalResponse + : response; + + // 3. Let locationURL be actualResponse’s location URL given request’s current + // URL’s fragment. + let locationURL; + + try { + locationURL = responseLocationURL( + actualResponse, + requestCurrentURL(request).hash + ); + + // 4. If locationURL is null, then return response. + if (locationURL == null) { + return response + } + } catch (err) { + // 5. If locationURL is failure, then return a network error. + return Promise.resolve(makeNetworkError(err)) + } + + // 6. If locationURL’s scheme is not an HTTP(S) scheme, then return a network + // error. + if (!urlIsHttpHttpsScheme(locationURL)) { + return Promise.resolve(makeNetworkError('URL scheme must be a HTTP(S) scheme')) + } + + // 7. If request’s redirect count is 20, then return a network error. + if (request.redirectCount === 20) { + return Promise.resolve(makeNetworkError('redirect count exceeded')) + } + + // 8. Increase request’s redirect count by 1. + request.redirectCount += 1; + + // 9. If request’s mode is "cors", locationURL includes credentials, and + // request’s origin is not same origin with locationURL’s origin, then return + // a network error. + if ( + request.mode === 'cors' && + (locationURL.username || locationURL.password) && + !sameOrigin(request, locationURL) + ) { + return Promise.resolve(makeNetworkError('cross origin not allowed for request mode "cors"')) + } + + // 10. If request’s response tainting is "cors" and locationURL includes + // credentials, then return a network error. + if ( + request.responseTainting === 'cors' && + (locationURL.username || locationURL.password) + ) { + return Promise.resolve(makeNetworkError( + 'URL cannot contain credentials for request mode "cors"' + )) + } + + // 11. If actualResponse’s status is not 303, request’s body is non-null, + // and request’s body’s source is null, then return a network error. + if ( + actualResponse.status !== 303 && + request.body != null && + request.body.source == null + ) { + return Promise.resolve(makeNetworkError()) + } + + // 12. If one of the following is true + // - actualResponse’s status is 301 or 302 and request’s method is `POST` + // - actualResponse’s status is 303 and request’s method is not `GET` or `HEAD` + if ( + ([301, 302].includes(actualResponse.status) && request.method === 'POST') || + (actualResponse.status === 303 && + !GET_OR_HEAD.includes(request.method)) + ) { + // then: + // 1. Set request’s method to `GET` and request’s body to null. + request.method = 'GET'; + request.body = null; + + // 2. For each headerName of request-body-header name, delete headerName from + // request’s header list. + for (const headerName of requestBodyHeader) { + request.headersList.delete(headerName); + } + } + + // 13. If request’s current URL’s origin is not same origin with locationURL’s + // origin, then for each headerName of CORS non-wildcard request-header name, + // delete headerName from request’s header list. + if (!sameOrigin(requestCurrentURL(request), locationURL)) { + // https://fetch.spec.whatwg.org/#cors-non-wildcard-request-header-name + request.headersList.delete('authorization', true); + + // https://fetch.spec.whatwg.org/#authentication-entries + request.headersList.delete('proxy-authorization', true); + + // "Cookie" and "Host" are forbidden request-headers, which undici doesn't implement. + request.headersList.delete('cookie', true); + request.headersList.delete('host', true); + } + + // 14. If request’s body is non-null, then set request’s body to the first return + // value of safely extracting request’s body’s source. + if (request.body != null) { + assert(request.body.source != null); + request.body = safelyExtractBody(request.body.source)[0]; + } + + // 15. Let timingInfo be fetchParams’s timing info. + const timingInfo = fetchParams.timingInfo; + + // 16. Set timingInfo’s redirect end time and post-redirect start time to the + // coarsened shared current time given fetchParams’s cross-origin isolated + // capability. + timingInfo.redirectEndTime = timingInfo.postRedirectStartTime = + coarsenedSharedCurrentTime(fetchParams.crossOriginIsolatedCapability); + + // 17. If timingInfo’s redirect start time is 0, then set timingInfo’s + // redirect start time to timingInfo’s start time. + if (timingInfo.redirectStartTime === 0) { + timingInfo.redirectStartTime = timingInfo.startTime; + } + + // 18. Append locationURL to request’s URL list. + request.urlList.push(locationURL); + + // 19. Invoke set request’s referrer policy on redirect on request and + // actualResponse. + setRequestReferrerPolicyOnRedirect(request, actualResponse); + + // 20. Return the result of running main fetch given fetchParams and true. + return mainFetch(fetchParams, true) + } + + // https://fetch.spec.whatwg.org/#http-network-or-cache-fetch + async function httpNetworkOrCacheFetch ( + fetchParams, + isAuthenticationFetch = false, + isNewConnectionFetch = false + ) { + // 1. Let request be fetchParams’s request. + const request = fetchParams.request; + + // 2. Let httpFetchParams be null. + let httpFetchParams = null; + + // 3. Let httpRequest be null. + let httpRequest = null; + + // 4. Let response be null. + let response = null; + + // 8. Run these steps, but abort when the ongoing fetch is terminated: + + // 1. If request’s window is "no-window" and request’s redirect mode is + // "error", then set httpFetchParams to fetchParams and httpRequest to + // request. + if (request.window === 'no-window' && request.redirect === 'error') { + httpFetchParams = fetchParams; + httpRequest = request; + } else { + // Otherwise: + + // 1. Set httpRequest to a clone of request. + httpRequest = cloneRequest(request); + + // 2. Set httpFetchParams to a copy of fetchParams. + httpFetchParams = { ...fetchParams }; + + // 3. Set httpFetchParams’s request to httpRequest. + httpFetchParams.request = httpRequest; + } + + // 3. Let includeCredentials be true if one of + const includeCredentials = + request.credentials === 'include' || + (request.credentials === 'same-origin' && + request.responseTainting === 'basic'); + + // 4. Let contentLength be httpRequest’s body’s length, if httpRequest’s + // body is non-null; otherwise null. + const contentLength = httpRequest.body ? httpRequest.body.length : null; + + // 5. Let contentLengthHeaderValue be null. + let contentLengthHeaderValue = null; + + // 6. If httpRequest’s body is null and httpRequest’s method is `POST` or + // `PUT`, then set contentLengthHeaderValue to `0`. + if ( + httpRequest.body == null && + ['POST', 'PUT'].includes(httpRequest.method) + ) { + contentLengthHeaderValue = '0'; + } + + // 7. If contentLength is non-null, then set contentLengthHeaderValue to + // contentLength, serialized and isomorphic encoded. + if (contentLength != null) { + contentLengthHeaderValue = isomorphicEncode(`${contentLength}`); + } + + // 8. If contentLengthHeaderValue is non-null, then append + // `Content-Length`/contentLengthHeaderValue to httpRequest’s header + // list. + if (contentLengthHeaderValue != null) { + httpRequest.headersList.append('content-length', contentLengthHeaderValue, true); + } + + // 9. If contentLengthHeaderValue is non-null, then append (`Content-Length`, + // contentLengthHeaderValue) to httpRequest’s header list. + + // 10. If contentLength is non-null and httpRequest’s keepalive is true, + // then: + if (contentLength != null && httpRequest.keepalive) ; + + // 11. If httpRequest’s referrer is a URL, then append + // `Referer`/httpRequest’s referrer, serialized and isomorphic encoded, + // to httpRequest’s header list. + if (httpRequest.referrer instanceof URL) { + httpRequest.headersList.append('referer', isomorphicEncode(httpRequest.referrer.href), true); + } + + // 12. Append a request `Origin` header for httpRequest. + appendRequestOriginHeader(httpRequest); + + // 13. Append the Fetch metadata headers for httpRequest. [FETCH-METADATA] + appendFetchMetadata(httpRequest); + + // 14. If httpRequest’s header list does not contain `User-Agent`, then + // user agents should append `User-Agent`/default `User-Agent` value to + // httpRequest’s header list. + if (!httpRequest.headersList.contains('user-agent', true)) { + httpRequest.headersList.append('user-agent', defaultUserAgent); + } + + // 15. If httpRequest’s cache mode is "default" and httpRequest’s header + // list contains `If-Modified-Since`, `If-None-Match`, + // `If-Unmodified-Since`, `If-Match`, or `If-Range`, then set + // httpRequest’s cache mode to "no-store". + if ( + httpRequest.cache === 'default' && + (httpRequest.headersList.contains('if-modified-since', true) || + httpRequest.headersList.contains('if-none-match', true) || + httpRequest.headersList.contains('if-unmodified-since', true) || + httpRequest.headersList.contains('if-match', true) || + httpRequest.headersList.contains('if-range', true)) + ) { + httpRequest.cache = 'no-store'; + } + + // 16. If httpRequest’s cache mode is "no-cache", httpRequest’s prevent + // no-cache cache-control header modification flag is unset, and + // httpRequest’s header list does not contain `Cache-Control`, then append + // `Cache-Control`/`max-age=0` to httpRequest’s header list. + if ( + httpRequest.cache === 'no-cache' && + !httpRequest.preventNoCacheCacheControlHeaderModification && + !httpRequest.headersList.contains('cache-control', true) + ) { + httpRequest.headersList.append('cache-control', 'max-age=0', true); + } + + // 17. If httpRequest’s cache mode is "no-store" or "reload", then: + if (httpRequest.cache === 'no-store' || httpRequest.cache === 'reload') { + // 1. If httpRequest’s header list does not contain `Pragma`, then append + // `Pragma`/`no-cache` to httpRequest’s header list. + if (!httpRequest.headersList.contains('pragma', true)) { + httpRequest.headersList.append('pragma', 'no-cache', true); + } + + // 2. If httpRequest’s header list does not contain `Cache-Control`, + // then append `Cache-Control`/`no-cache` to httpRequest’s header list. + if (!httpRequest.headersList.contains('cache-control', true)) { + httpRequest.headersList.append('cache-control', 'no-cache', true); + } + } + + // 18. If httpRequest’s header list contains `Range`, then append + // `Accept-Encoding`/`identity` to httpRequest’s header list. + if (httpRequest.headersList.contains('range', true)) { + httpRequest.headersList.append('accept-encoding', 'identity', true); + } + + // 19. Modify httpRequest’s header list per HTTP. Do not append a given + // header if httpRequest’s header list contains that header’s name. + // TODO: https://github.com/whatwg/fetch/issues/1285#issuecomment-896560129 + if (!httpRequest.headersList.contains('accept-encoding', true)) { + if (urlHasHttpsScheme(requestCurrentURL(httpRequest))) { + httpRequest.headersList.append('accept-encoding', 'br, gzip, deflate', true); + } else { + httpRequest.headersList.append('accept-encoding', 'gzip, deflate', true); + } + } + + httpRequest.headersList.delete('host', true); + + // 21. If there’s a proxy-authentication entry, use it as appropriate. + // TODO: proxy-authentication + + // 22. Set httpCache to the result of determining the HTTP cache + // partition, given httpRequest. + // TODO: cache + + // 23. If httpCache is null, then set httpRequest’s cache mode to + // "no-store". + { + httpRequest.cache = 'no-store'; + } + + // 24. If httpRequest’s cache mode is neither "no-store" nor "reload", + // then: + if (httpRequest.cache !== 'no-store' && httpRequest.cache !== 'reload') ; + + // 9. If aborted, then return the appropriate network error for fetchParams. + // TODO + + // 10. If response is null, then: + if (response == null) { + // 1. If httpRequest’s cache mode is "only-if-cached", then return a + // network error. + if (httpRequest.cache === 'only-if-cached') { + return makeNetworkError('only if cached') + } + + // 2. Let forwardResponse be the result of running HTTP-network fetch + // given httpFetchParams, includeCredentials, and isNewConnectionFetch. + const forwardResponse = await httpNetworkFetch( + httpFetchParams, + includeCredentials, + isNewConnectionFetch + ); + + // 3. If httpRequest’s method is unsafe and forwardResponse’s status is + // in the range 200 to 399, inclusive, invalidate appropriate stored + // responses in httpCache, as per the "Invalidation" chapter of HTTP + // Caching, and set storedResponse to null. [HTTP-CACHING] + if ( + !safeMethodsSet.has(httpRequest.method) && + forwardResponse.status >= 200 && + forwardResponse.status <= 399 + ) ; + + // 5. If response is null, then: + if (response == null) { + // 1. Set response to forwardResponse. + response = forwardResponse; + + // 2. Store httpRequest and forwardResponse in httpCache, as per the + // "Storing Responses in Caches" chapter of HTTP Caching. [HTTP-CACHING] + // TODO: cache + } + } + + // 11. Set response’s URL list to a clone of httpRequest’s URL list. + response.urlList = [...httpRequest.urlList]; + + // 12. If httpRequest’s header list contains `Range`, then set response’s + // range-requested flag. + if (httpRequest.headersList.contains('range', true)) { + response.rangeRequested = true; + } + + // 13. Set response’s request-includes-credentials to includeCredentials. + response.requestIncludesCredentials = includeCredentials; + + // 14. If response’s status is 401, httpRequest’s response tainting is not + // "cors", includeCredentials is true, and request’s window is an environment + // settings object, then: + // TODO + + // 15. If response’s status is 407, then: + if (response.status === 407) { + // 1. If request’s window is "no-window", then return a network error. + if (request.window === 'no-window') { + return makeNetworkError() + } + + // 2. ??? + + // 3. If fetchParams is canceled, then return the appropriate network error for fetchParams. + if (isCancelled(fetchParams)) { + return makeAppropriateNetworkError(fetchParams) + } + + // 4. Prompt the end user as appropriate in request’s window and store + // the result as a proxy-authentication entry. [HTTP-AUTH] + // TODO: Invoke some kind of callback? + + // 5. Set response to the result of running HTTP-network-or-cache fetch given + // fetchParams. + // TODO + return makeNetworkError('proxy authentication required') + } + + // 16. If all of the following are true + if ( + // response’s status is 421 + response.status === 421 && + // isNewConnectionFetch is false + !isNewConnectionFetch && + // request’s body is null, or request’s body is non-null and request’s body’s source is non-null + (request.body == null || request.body.source != null) + ) { + // then: + + // 1. If fetchParams is canceled, then return the appropriate network error for fetchParams. + if (isCancelled(fetchParams)) { + return makeAppropriateNetworkError(fetchParams) + } + + // 2. Set response to the result of running HTTP-network-or-cache + // fetch given fetchParams, isAuthenticationFetch, and true. + + // TODO (spec): The spec doesn't specify this but we need to cancel + // the active response before we can start a new one. + // https://github.com/whatwg/fetch/issues/1293 + fetchParams.controller.connection.destroy(); + + response = await httpNetworkOrCacheFetch( + fetchParams, + isAuthenticationFetch, + true + ); + } + + // 18. Return response. + return response + } + + // https://fetch.spec.whatwg.org/#http-network-fetch + async function httpNetworkFetch ( + fetchParams, + includeCredentials = false, + forceNewConnection = false + ) { + assert(!fetchParams.controller.connection || fetchParams.controller.connection.destroyed); + + fetchParams.controller.connection = { + abort: null, + destroyed: false, + destroy (err, abort = true) { + if (!this.destroyed) { + this.destroyed = true; + if (abort) { + this.abort?.(err ?? new DOMException('The operation was aborted.', 'AbortError')); + } + } + } + }; + + // 1. Let request be fetchParams’s request. + const request = fetchParams.request; + + // 2. Let response be null. + let response = null; + + // 3. Let timingInfo be fetchParams’s timing info. + const timingInfo = fetchParams.timingInfo; + + // 5. If httpCache is null, then set request’s cache mode to "no-store". + { + request.cache = 'no-store'; + } + + // 8. Switch on request’s mode: + if (request.mode === 'websocket') ; + + // 9. Run these steps, but abort when the ongoing fetch is terminated: + + // 1. If connection is failure, then return a network error. + + // 2. Set timingInfo’s final connection timing info to the result of + // calling clamp and coarsen connection timing info with connection’s + // timing info, timingInfo’s post-redirect start time, and fetchParams’s + // cross-origin isolated capability. + + // 3. If connection is not an HTTP/2 connection, request’s body is non-null, + // and request’s body’s source is null, then append (`Transfer-Encoding`, + // `chunked`) to request’s header list. + + // 4. Set timingInfo’s final network-request start time to the coarsened + // shared current time given fetchParams’s cross-origin isolated + // capability. + + // 5. Set response to the result of making an HTTP request over connection + // using request with the following caveats: + + // - Follow the relevant requirements from HTTP. [HTTP] [HTTP-SEMANTICS] + // [HTTP-COND] [HTTP-CACHING] [HTTP-AUTH] + + // - If request’s body is non-null, and request’s body’s source is null, + // then the user agent may have a buffer of up to 64 kibibytes and store + // a part of request’s body in that buffer. If the user agent reads from + // request’s body beyond that buffer’s size and the user agent needs to + // resend request, then instead return a network error. + + // - Set timingInfo’s final network-response start time to the coarsened + // shared current time given fetchParams’s cross-origin isolated capability, + // immediately after the user agent’s HTTP parser receives the first byte + // of the response (e.g., frame header bytes for HTTP/2 or response status + // line for HTTP/1.x). + + // - Wait until all the headers are transmitted. + + // - Any responses whose status is in the range 100 to 199, inclusive, + // and is not 101, are to be ignored, except for the purposes of setting + // timingInfo’s final network-response start time above. + + // - If request’s header list contains `Transfer-Encoding`/`chunked` and + // response is transferred via HTTP/1.0 or older, then return a network + // error. + + // - If the HTTP request results in a TLS client certificate dialog, then: + + // 1. If request’s window is an environment settings object, make the + // dialog available in request’s window. + + // 2. Otherwise, return a network error. + + // To transmit request’s body body, run these steps: + let requestBody = null; + // 1. If body is null and fetchParams’s process request end-of-body is + // non-null, then queue a fetch task given fetchParams’s process request + // end-of-body and fetchParams’s task destination. + if (request.body == null && fetchParams.processRequestEndOfBody) { + queueMicrotask(() => fetchParams.processRequestEndOfBody()); + } else if (request.body != null) { + // 2. Otherwise, if body is non-null: + + // 1. Let processBodyChunk given bytes be these steps: + const processBodyChunk = async function * (bytes) { + // 1. If the ongoing fetch is terminated, then abort these steps. + if (isCancelled(fetchParams)) { + return + } + + // 2. Run this step in parallel: transmit bytes. + yield bytes; + + // 3. If fetchParams’s process request body is non-null, then run + // fetchParams’s process request body given bytes’s length. + fetchParams.processRequestBodyChunkLength?.(bytes.byteLength); + }; + + // 2. Let processEndOfBody be these steps: + const processEndOfBody = () => { + // 1. If fetchParams is canceled, then abort these steps. + if (isCancelled(fetchParams)) { + return + } + + // 2. If fetchParams’s process request end-of-body is non-null, + // then run fetchParams’s process request end-of-body. + if (fetchParams.processRequestEndOfBody) { + fetchParams.processRequestEndOfBody(); + } + }; + + // 3. Let processBodyError given e be these steps: + const processBodyError = (e) => { + // 1. If fetchParams is canceled, then abort these steps. + if (isCancelled(fetchParams)) { + return + } + + // 2. If e is an "AbortError" DOMException, then abort fetchParams’s controller. + if (e.name === 'AbortError') { + fetchParams.controller.abort(); + } else { + fetchParams.controller.terminate(e); + } + }; + + // 4. Incrementally read request’s body given processBodyChunk, processEndOfBody, + // processBodyError, and fetchParams’s task destination. + requestBody = (async function * () { + try { + for await (const bytes of request.body.stream) { + yield * processBodyChunk(bytes); + } + processEndOfBody(); + } catch (err) { + processBodyError(err); + } + })(); + } + + try { + // socket is only provided for websockets + const { body, status, statusText, headersList, socket } = await dispatch({ body: requestBody }); + + if (socket) { + response = makeResponse({ status, statusText, headersList, socket }); + } else { + const iterator = body[Symbol.asyncIterator](); + fetchParams.controller.next = () => iterator.next(); + + response = makeResponse({ status, statusText, headersList }); + } + } catch (err) { + // 10. If aborted, then: + if (err.name === 'AbortError') { + // 1. If connection uses HTTP/2, then transmit an RST_STREAM frame. + fetchParams.controller.connection.destroy(); + + // 2. Return the appropriate network error for fetchParams. + return makeAppropriateNetworkError(fetchParams, err) + } + + return makeNetworkError(err) + } + + // 11. Let pullAlgorithm be an action that resumes the ongoing fetch + // if it is suspended. + const pullAlgorithm = async () => { + await fetchParams.controller.resume(); + }; + + // 12. Let cancelAlgorithm be an algorithm that aborts fetchParams’s + // controller with reason, given reason. + const cancelAlgorithm = (reason) => { + // If the aborted fetch was already terminated, then we do not + // need to do anything. + if (!isCancelled(fetchParams)) { + fetchParams.controller.abort(reason); + } + }; + + // 13. Let highWaterMark be a non-negative, non-NaN number, chosen by + // the user agent. + // TODO + + // 14. Let sizeAlgorithm be an algorithm that accepts a chunk object + // and returns a non-negative, non-NaN, non-infinite number, chosen by the user agent. + // TODO + + // 15. Let stream be a new ReadableStream. + // 16. Set up stream with byte reading support with pullAlgorithm set to pullAlgorithm, + // cancelAlgorithm set to cancelAlgorithm. + const stream = new ReadableStream( + { + async start (controller) { + fetchParams.controller.controller = controller; + }, + async pull (controller) { + await pullAlgorithm(); + }, + async cancel (reason) { + await cancelAlgorithm(reason); + }, + type: 'bytes' + } + ); + + // 17. Run these steps, but abort when the ongoing fetch is terminated: + + // 1. Set response’s body to a new body whose stream is stream. + response.body = { stream, source: null, length: null }; + + // 2. If response is not a network error and request’s cache mode is + // not "no-store", then update response in httpCache for request. + // TODO + + // 3. If includeCredentials is true and the user agent is not configured + // to block cookies for request (see section 7 of [COOKIES]), then run the + // "set-cookie-string" parsing algorithm (see section 5.2 of [COOKIES]) on + // the value of each header whose name is a byte-case-insensitive match for + // `Set-Cookie` in response’s header list, if any, and request’s current URL. + // TODO + + // 18. If aborted, then: + // TODO + + // 19. Run these steps in parallel: + + // 1. Run these steps, but abort when fetchParams is canceled: + fetchParams.controller.onAborted = onAborted; + fetchParams.controller.on('terminated', onAborted); + fetchParams.controller.resume = async () => { + // 1. While true + while (true) { + // 1-3. See onData... + + // 4. Set bytes to the result of handling content codings given + // codings and bytes. + let bytes; + let isFailure; + try { + const { done, value } = await fetchParams.controller.next(); + + if (isAborted(fetchParams)) { + break + } + + bytes = done ? undefined : value; + } catch (err) { + if (fetchParams.controller.ended && !timingInfo.encodedBodySize) { + // zlib doesn't like empty streams. + bytes = undefined; + } else { + bytes = err; + + // err may be propagated from the result of calling readablestream.cancel, + // which might not be an error. https://github.com/nodejs/undici/issues/2009 + isFailure = true; + } + } + + if (bytes === undefined) { + // 2. Otherwise, if the bytes transmission for response’s message + // body is done normally and stream is readable, then close + // stream, finalize response for fetchParams and response, and + // abort these in-parallel steps. + readableStreamClose(fetchParams.controller.controller); + + finalizeResponse(fetchParams, response); + + return + } + + // 5. Increase timingInfo’s decoded body size by bytes’s length. + timingInfo.decodedBodySize += bytes?.byteLength ?? 0; + + // 6. If bytes is failure, then terminate fetchParams’s controller. + if (isFailure) { + fetchParams.controller.terminate(bytes); + return + } + + // 7. Enqueue a Uint8Array wrapping an ArrayBuffer containing bytes + // into stream. + const buffer = new Uint8Array(bytes); + if (buffer.byteLength) { + fetchParams.controller.controller.enqueue(buffer); + } + + // 8. If stream is errored, then terminate the ongoing fetch. + if (isErrored(stream)) { + fetchParams.controller.terminate(); + return + } + + // 9. If stream doesn’t need more data ask the user agent to suspend + // the ongoing fetch. + if (fetchParams.controller.controller.desiredSize <= 0) { + return + } + } + }; + + // 2. If aborted, then: + function onAborted (reason) { + // 2. If fetchParams is aborted, then: + if (isAborted(fetchParams)) { + // 1. Set response’s aborted flag. + response.aborted = true; + + // 2. If stream is readable, then error stream with the result of + // deserialize a serialized abort reason given fetchParams’s + // controller’s serialized abort reason and an + // implementation-defined realm. + if (isReadable(stream)) { + fetchParams.controller.controller.error( + fetchParams.controller.serializedAbortReason + ); + } + } else { + // 3. Otherwise, if stream is readable, error stream with a TypeError. + if (isReadable(stream)) { + fetchParams.controller.controller.error(new TypeError('terminated', { + cause: isErrorLike(reason) ? reason : undefined + })); + } + } + + // 4. If connection uses HTTP/2, then transmit an RST_STREAM frame. + // 5. Otherwise, the user agent should close connection unless it would be bad for performance to do so. + fetchParams.controller.connection.destroy(); + } + + // 20. Return response. + return response + + function dispatch ({ body }) { + const url = requestCurrentURL(request); + /** @type {import('../..').Agent} */ + const agent = fetchParams.controller.dispatcher; + + return new Promise((resolve, reject) => agent.dispatch( + { + path: url.pathname + url.search, + origin: url.origin, + method: request.method, + body: agent.isMockActive ? request.body && (request.body.source || request.body.stream) : body, + headers: request.headersList.entries, + maxRedirections: 0, + upgrade: request.mode === 'websocket' ? 'websocket' : undefined + }, + { + body: null, + abort: null, + + onConnect (abort) { + // TODO (fix): Do we need connection here? + const { connection } = fetchParams.controller; + + // Set timingInfo’s final connection timing info to the result of calling clamp and coarsen + // connection timing info with connection’s timing info, timingInfo’s post-redirect start + // time, and fetchParams’s cross-origin isolated capability. + // TODO: implement connection timing + timingInfo.finalConnectionTimingInfo = clampAndCoarsenConnectionTimingInfo(undefined, timingInfo.postRedirectStartTime, fetchParams.crossOriginIsolatedCapability); + + if (connection.destroyed) { + abort(new DOMException('The operation was aborted.', 'AbortError')); + } else { + fetchParams.controller.on('terminated', abort); + this.abort = connection.abort = abort; + } + + // Set timingInfo’s final network-request start time to the coarsened shared current time given + // fetchParams’s cross-origin isolated capability. + timingInfo.finalNetworkRequestStartTime = coarsenedSharedCurrentTime(fetchParams.crossOriginIsolatedCapability); + }, + + onResponseStarted () { + // Set timingInfo’s final network-response start time to the coarsened shared current + // time given fetchParams’s cross-origin isolated capability, immediately after the + // user agent’s HTTP parser receives the first byte of the response (e.g., frame header + // bytes for HTTP/2 or response status line for HTTP/1.x). + timingInfo.finalNetworkResponseStartTime = coarsenedSharedCurrentTime(fetchParams.crossOriginIsolatedCapability); + }, + + onHeaders (status, rawHeaders, resume, statusText) { + if (status < 200) { + return + } + + /** @type {string[]} */ + let codings = []; + let location = ''; + + const headersList = new HeadersList(); + + for (let i = 0; i < rawHeaders.length; i += 2) { + headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString('latin1'), true); + } + const contentEncoding = headersList.get('content-encoding', true); + if (contentEncoding) { + // https://www.rfc-editor.org/rfc/rfc7231#section-3.1.2.1 + // "All content-coding values are case-insensitive..." + codings = contentEncoding.toLowerCase().split(',').map((x) => x.trim()); + } + location = headersList.get('location', true); + + this.body = new Readable({ read: resume }); + + const decoders = []; + + const willFollow = location && request.redirect === 'follow' && + redirectStatusSet.has(status); + + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding + if (codings.length !== 0 && request.method !== 'HEAD' && request.method !== 'CONNECT' && !nullBodyStatus.includes(status) && !willFollow) { + for (let i = 0; i < codings.length; ++i) { + const coding = codings[i]; + // https://www.rfc-editor.org/rfc/rfc9112.html#section-7.2 + if (coding === 'x-gzip' || coding === 'gzip') { + decoders.push(zlib.createGunzip({ + // Be less strict when decoding compressed responses, since sometimes + // servers send slightly invalid responses that are still accepted + // by common browsers. + // Always using Z_SYNC_FLUSH is what cURL does. + flush: zlib.constants.Z_SYNC_FLUSH, + finishFlush: zlib.constants.Z_SYNC_FLUSH + })); + } else if (coding === 'deflate') { + decoders.push(createInflate()); + } else if (coding === 'br') { + decoders.push(zlib.createBrotliDecompress()); + } else { + decoders.length = 0; + break + } + } + } + + resolve({ + status, + statusText, + headersList, + body: decoders.length + ? pipeline(this.body, ...decoders, () => { }) + : this.body.on('error', () => { }) + }); + + return true + }, + + onData (chunk) { + if (fetchParams.controller.dump) { + return + } + + // 1. If one or more bytes have been transmitted from response’s + // message body, then: + + // 1. Let bytes be the transmitted bytes. + const bytes = chunk; + + // 2. Let codings be the result of extracting header list values + // given `Content-Encoding` and response’s header list. + // See pullAlgorithm. + + // 3. Increase timingInfo’s encoded body size by bytes’s length. + timingInfo.encodedBodySize += bytes.byteLength; + + // 4. See pullAlgorithm... + + return this.body.push(bytes) + }, + + onComplete () { + if (this.abort) { + fetchParams.controller.off('terminated', this.abort); + } + + if (fetchParams.controller.onAborted) { + fetchParams.controller.off('terminated', fetchParams.controller.onAborted); + } + + fetchParams.controller.ended = true; + + this.body.push(null); + }, + + onError (error) { + if (this.abort) { + fetchParams.controller.off('terminated', this.abort); + } + + this.body?.destroy(error); + + fetchParams.controller.terminate(error); + + reject(error); + }, + + onUpgrade (status, rawHeaders, socket) { + if (status !== 101) { + return + } + + const headersList = new HeadersList(); + + for (let i = 0; i < rawHeaders.length; i += 2) { + headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString('latin1'), true); + } + + resolve({ + status, + statusText: STATUS_CODES[status], + headersList, + socket + }); + + return true + } + } + )) + } + } + + fetch_1 = { + fetch, + Fetch, + fetching, + finalizeAndReportTiming + }; + return fetch_1; +} + +var symbols$2; +var hasRequiredSymbols$2; + +function requireSymbols$2 () { + if (hasRequiredSymbols$2) return symbols$2; + hasRequiredSymbols$2 = 1; + + symbols$2 = { + kState: Symbol('FileReader state'), + kResult: Symbol('FileReader result'), + kError: Symbol('FileReader error'), + kLastProgressEventFired: Symbol('FileReader last progress event fired timestamp'), + kEvents: Symbol('FileReader events'), + kAborted: Symbol('FileReader aborted') + }; + return symbols$2; +} + +var progressevent; +var hasRequiredProgressevent; + +function requireProgressevent () { + if (hasRequiredProgressevent) return progressevent; + hasRequiredProgressevent = 1; + + const { webidl } = requireWebidl(); + + const kState = Symbol('ProgressEvent state'); + + /** + * @see https://xhr.spec.whatwg.org/#progressevent + */ + class ProgressEvent extends Event { + constructor (type, eventInitDict = {}) { + type = webidl.converters.DOMString(type, 'ProgressEvent constructor', 'type'); + eventInitDict = webidl.converters.ProgressEventInit(eventInitDict ?? {}); + + super(type, eventInitDict); + + this[kState] = { + lengthComputable: eventInitDict.lengthComputable, + loaded: eventInitDict.loaded, + total: eventInitDict.total + }; + } + + get lengthComputable () { + webidl.brandCheck(this, ProgressEvent); + + return this[kState].lengthComputable + } + + get loaded () { + webidl.brandCheck(this, ProgressEvent); + + return this[kState].loaded + } + + get total () { + webidl.brandCheck(this, ProgressEvent); + + return this[kState].total + } + } + + webidl.converters.ProgressEventInit = webidl.dictionaryConverter([ + { + key: 'lengthComputable', + converter: webidl.converters.boolean, + defaultValue: () => false + }, + { + key: 'loaded', + converter: webidl.converters['unsigned long long'], + defaultValue: () => 0 + }, + { + key: 'total', + converter: webidl.converters['unsigned long long'], + defaultValue: () => 0 + }, + { + key: 'bubbles', + converter: webidl.converters.boolean, + defaultValue: () => false + }, + { + key: 'cancelable', + converter: webidl.converters.boolean, + defaultValue: () => false + }, + { + key: 'composed', + converter: webidl.converters.boolean, + defaultValue: () => false + } + ]); + + progressevent = { + ProgressEvent + }; + return progressevent; +} + +var encoding; +var hasRequiredEncoding; + +function requireEncoding () { + if (hasRequiredEncoding) return encoding; + hasRequiredEncoding = 1; + + /** + * @see https://encoding.spec.whatwg.org/#concept-encoding-get + * @param {string|undefined} label + */ + function getEncoding (label) { + if (!label) { + return 'failure' + } + + // 1. Remove any leading and trailing ASCII whitespace from label. + // 2. If label is an ASCII case-insensitive match for any of the + // labels listed in the table below, then return the + // corresponding encoding; otherwise return failure. + switch (label.trim().toLowerCase()) { + case 'unicode-1-1-utf-8': + case 'unicode11utf8': + case 'unicode20utf8': + case 'utf-8': + case 'utf8': + case 'x-unicode20utf8': + return 'UTF-8' + case '866': + case 'cp866': + case 'csibm866': + case 'ibm866': + return 'IBM866' + case 'csisolatin2': + case 'iso-8859-2': + case 'iso-ir-101': + case 'iso8859-2': + case 'iso88592': + case 'iso_8859-2': + case 'iso_8859-2:1987': + case 'l2': + case 'latin2': + return 'ISO-8859-2' + case 'csisolatin3': + case 'iso-8859-3': + case 'iso-ir-109': + case 'iso8859-3': + case 'iso88593': + case 'iso_8859-3': + case 'iso_8859-3:1988': + case 'l3': + case 'latin3': + return 'ISO-8859-3' + case 'csisolatin4': + case 'iso-8859-4': + case 'iso-ir-110': + case 'iso8859-4': + case 'iso88594': + case 'iso_8859-4': + case 'iso_8859-4:1988': + case 'l4': + case 'latin4': + return 'ISO-8859-4' + case 'csisolatincyrillic': + case 'cyrillic': + case 'iso-8859-5': + case 'iso-ir-144': + case 'iso8859-5': + case 'iso88595': + case 'iso_8859-5': + case 'iso_8859-5:1988': + return 'ISO-8859-5' + case 'arabic': + case 'asmo-708': + case 'csiso88596e': + case 'csiso88596i': + case 'csisolatinarabic': + case 'ecma-114': + case 'iso-8859-6': + case 'iso-8859-6-e': + case 'iso-8859-6-i': + case 'iso-ir-127': + case 'iso8859-6': + case 'iso88596': + case 'iso_8859-6': + case 'iso_8859-6:1987': + return 'ISO-8859-6' + case 'csisolatingreek': + case 'ecma-118': + case 'elot_928': + case 'greek': + case 'greek8': + case 'iso-8859-7': + case 'iso-ir-126': + case 'iso8859-7': + case 'iso88597': + case 'iso_8859-7': + case 'iso_8859-7:1987': + case 'sun_eu_greek': + return 'ISO-8859-7' + case 'csiso88598e': + case 'csisolatinhebrew': + case 'hebrew': + case 'iso-8859-8': + case 'iso-8859-8-e': + case 'iso-ir-138': + case 'iso8859-8': + case 'iso88598': + case 'iso_8859-8': + case 'iso_8859-8:1988': + case 'visual': + return 'ISO-8859-8' + case 'csiso88598i': + case 'iso-8859-8-i': + case 'logical': + return 'ISO-8859-8-I' + case 'csisolatin6': + case 'iso-8859-10': + case 'iso-ir-157': + case 'iso8859-10': + case 'iso885910': + case 'l6': + case 'latin6': + return 'ISO-8859-10' + case 'iso-8859-13': + case 'iso8859-13': + case 'iso885913': + return 'ISO-8859-13' + case 'iso-8859-14': + case 'iso8859-14': + case 'iso885914': + return 'ISO-8859-14' + case 'csisolatin9': + case 'iso-8859-15': + case 'iso8859-15': + case 'iso885915': + case 'iso_8859-15': + case 'l9': + return 'ISO-8859-15' + case 'iso-8859-16': + return 'ISO-8859-16' + case 'cskoi8r': + case 'koi': + case 'koi8': + case 'koi8-r': + case 'koi8_r': + return 'KOI8-R' + case 'koi8-ru': + case 'koi8-u': + return 'KOI8-U' + case 'csmacintosh': + case 'mac': + case 'macintosh': + case 'x-mac-roman': + return 'macintosh' + case 'iso-8859-11': + case 'iso8859-11': + case 'iso885911': + case 'tis-620': + case 'windows-874': + return 'windows-874' + case 'cp1250': + case 'windows-1250': + case 'x-cp1250': + return 'windows-1250' + case 'cp1251': + case 'windows-1251': + case 'x-cp1251': + return 'windows-1251' + case 'ansi_x3.4-1968': + case 'ascii': + case 'cp1252': + case 'cp819': + case 'csisolatin1': + case 'ibm819': + case 'iso-8859-1': + case 'iso-ir-100': + case 'iso8859-1': + case 'iso88591': + case 'iso_8859-1': + case 'iso_8859-1:1987': + case 'l1': + case 'latin1': + case 'us-ascii': + case 'windows-1252': + case 'x-cp1252': + return 'windows-1252' + case 'cp1253': + case 'windows-1253': + case 'x-cp1253': + return 'windows-1253' + case 'cp1254': + case 'csisolatin5': + case 'iso-8859-9': + case 'iso-ir-148': + case 'iso8859-9': + case 'iso88599': + case 'iso_8859-9': + case 'iso_8859-9:1989': + case 'l5': + case 'latin5': + case 'windows-1254': + case 'x-cp1254': + return 'windows-1254' + case 'cp1255': + case 'windows-1255': + case 'x-cp1255': + return 'windows-1255' + case 'cp1256': + case 'windows-1256': + case 'x-cp1256': + return 'windows-1256' + case 'cp1257': + case 'windows-1257': + case 'x-cp1257': + return 'windows-1257' + case 'cp1258': + case 'windows-1258': + case 'x-cp1258': + return 'windows-1258' + case 'x-mac-cyrillic': + case 'x-mac-ukrainian': + return 'x-mac-cyrillic' + case 'chinese': + case 'csgb2312': + case 'csiso58gb231280': + case 'gb2312': + case 'gb_2312': + case 'gb_2312-80': + case 'gbk': + case 'iso-ir-58': + case 'x-gbk': + return 'GBK' + case 'gb18030': + return 'gb18030' + case 'big5': + case 'big5-hkscs': + case 'cn-big5': + case 'csbig5': + case 'x-x-big5': + return 'Big5' + case 'cseucpkdfmtjapanese': + case 'euc-jp': + case 'x-euc-jp': + return 'EUC-JP' + case 'csiso2022jp': + case 'iso-2022-jp': + return 'ISO-2022-JP' + case 'csshiftjis': + case 'ms932': + case 'ms_kanji': + case 'shift-jis': + case 'shift_jis': + case 'sjis': + case 'windows-31j': + case 'x-sjis': + return 'Shift_JIS' + case 'cseuckr': + case 'csksc56011987': + case 'euc-kr': + case 'iso-ir-149': + case 'korean': + case 'ks_c_5601-1987': + case 'ks_c_5601-1989': + case 'ksc5601': + case 'ksc_5601': + case 'windows-949': + return 'EUC-KR' + case 'csiso2022kr': + case 'hz-gb-2312': + case 'iso-2022-cn': + case 'iso-2022-cn-ext': + case 'iso-2022-kr': + case 'replacement': + return 'replacement' + case 'unicodefffe': + case 'utf-16be': + return 'UTF-16BE' + case 'csunicode': + case 'iso-10646-ucs-2': + case 'ucs-2': + case 'unicode': + case 'unicodefeff': + case 'utf-16': + case 'utf-16le': + return 'UTF-16LE' + case 'x-user-defined': + return 'x-user-defined' + default: return 'failure' + } + } + + encoding = { + getEncoding + }; + return encoding; +} + +var util$4; +var hasRequiredUtil$4; + +function requireUtil$4 () { + if (hasRequiredUtil$4) return util$4; + hasRequiredUtil$4 = 1; + + const { + kState, + kError, + kResult, + kAborted, + kLastProgressEventFired + } = requireSymbols$2(); + const { ProgressEvent } = requireProgressevent(); + const { getEncoding } = requireEncoding(); + const { serializeAMimeType, parseMIMEType } = requireDataUrl(); + const { types } = require$$0$6; + const { StringDecoder } = require$$5$2; + const { btoa } = require$$0$3; + + /** @type {PropertyDescriptor} */ + const staticPropertyDescriptors = { + enumerable: true, + writable: false, + configurable: false + }; + + /** + * @see https://w3c.github.io/FileAPI/#readOperation + * @param {import('./filereader').FileReader} fr + * @param {import('buffer').Blob} blob + * @param {string} type + * @param {string?} encodingName + */ + function readOperation (fr, blob, type, encodingName) { + // 1. If fr’s state is "loading", throw an InvalidStateError + // DOMException. + if (fr[kState] === 'loading') { + throw new DOMException('Invalid state', 'InvalidStateError') + } + + // 2. Set fr’s state to "loading". + fr[kState] = 'loading'; + + // 3. Set fr’s result to null. + fr[kResult] = null; + + // 4. Set fr’s error to null. + fr[kError] = null; + + // 5. Let stream be the result of calling get stream on blob. + /** @type {import('stream/web').ReadableStream} */ + const stream = blob.stream(); + + // 6. Let reader be the result of getting a reader from stream. + const reader = stream.getReader(); + + // 7. Let bytes be an empty byte sequence. + /** @type {Uint8Array[]} */ + const bytes = []; + + // 8. Let chunkPromise be the result of reading a chunk from + // stream with reader. + let chunkPromise = reader.read(); + + // 9. Let isFirstChunk be true. + let isFirstChunk = true + + // 10. In parallel, while true: + // Note: "In parallel" just means non-blocking + // Note 2: readOperation itself cannot be async as double + // reading the body would then reject the promise, instead + // of throwing an error. + ;(async () => { + while (!fr[kAborted]) { + // 1. Wait for chunkPromise to be fulfilled or rejected. + try { + const { done, value } = await chunkPromise; + + // 2. If chunkPromise is fulfilled, and isFirstChunk is + // true, queue a task to fire a progress event called + // loadstart at fr. + if (isFirstChunk && !fr[kAborted]) { + queueMicrotask(() => { + fireAProgressEvent('loadstart', fr); + }); + } + + // 3. Set isFirstChunk to false. + isFirstChunk = false; + + // 4. If chunkPromise is fulfilled with an object whose + // done property is false and whose value property is + // a Uint8Array object, run these steps: + if (!done && types.isUint8Array(value)) { + // 1. Let bs be the byte sequence represented by the + // Uint8Array object. + + // 2. Append bs to bytes. + bytes.push(value); + + // 3. If roughly 50ms have passed since these steps + // were last invoked, queue a task to fire a + // progress event called progress at fr. + if ( + ( + fr[kLastProgressEventFired] === undefined || + Date.now() - fr[kLastProgressEventFired] >= 50 + ) && + !fr[kAborted] + ) { + fr[kLastProgressEventFired] = Date.now(); + queueMicrotask(() => { + fireAProgressEvent('progress', fr); + }); + } + + // 4. Set chunkPromise to the result of reading a + // chunk from stream with reader. + chunkPromise = reader.read(); + } else if (done) { + // 5. Otherwise, if chunkPromise is fulfilled with an + // object whose done property is true, queue a task + // to run the following steps and abort this algorithm: + queueMicrotask(() => { + // 1. Set fr’s state to "done". + fr[kState] = 'done'; + + // 2. Let result be the result of package data given + // bytes, type, blob’s type, and encodingName. + try { + const result = packageData(bytes, type, blob.type, encodingName); + + // 4. Else: + + if (fr[kAborted]) { + return + } + + // 1. Set fr’s result to result. + fr[kResult] = result; + + // 2. Fire a progress event called load at the fr. + fireAProgressEvent('load', fr); + } catch (error) { + // 3. If package data threw an exception error: + + // 1. Set fr’s error to error. + fr[kError] = error; + + // 2. Fire a progress event called error at fr. + fireAProgressEvent('error', fr); + } + + // 5. If fr’s state is not "loading", fire a progress + // event called loadend at the fr. + if (fr[kState] !== 'loading') { + fireAProgressEvent('loadend', fr); + } + }); + + break + } + } catch (error) { + if (fr[kAborted]) { + return + } + + // 6. Otherwise, if chunkPromise is rejected with an + // error error, queue a task to run the following + // steps and abort this algorithm: + queueMicrotask(() => { + // 1. Set fr’s state to "done". + fr[kState] = 'done'; + + // 2. Set fr’s error to error. + fr[kError] = error; + + // 3. Fire a progress event called error at fr. + fireAProgressEvent('error', fr); + + // 4. If fr’s state is not "loading", fire a progress + // event called loadend at fr. + if (fr[kState] !== 'loading') { + fireAProgressEvent('loadend', fr); + } + }); + + break + } + } + })(); + } + + /** + * @see https://w3c.github.io/FileAPI/#fire-a-progress-event + * @see https://dom.spec.whatwg.org/#concept-event-fire + * @param {string} e The name of the event + * @param {import('./filereader').FileReader} reader + */ + function fireAProgressEvent (e, reader) { + // The progress event e does not bubble. e.bubbles must be false + // The progress event e is NOT cancelable. e.cancelable must be false + const event = new ProgressEvent(e, { + bubbles: false, + cancelable: false + }); + + reader.dispatchEvent(event); + } + + /** + * @see https://w3c.github.io/FileAPI/#blob-package-data + * @param {Uint8Array[]} bytes + * @param {string} type + * @param {string?} mimeType + * @param {string?} encodingName + */ + function packageData (bytes, type, mimeType, encodingName) { + // 1. A Blob has an associated package data algorithm, given + // bytes, a type, a optional mimeType, and a optional + // encodingName, which switches on type and runs the + // associated steps: + + switch (type) { + case 'DataURL': { + // 1. Return bytes as a DataURL [RFC2397] subject to + // the considerations below: + // * Use mimeType as part of the Data URL if it is + // available in keeping with the Data URL + // specification [RFC2397]. + // * If mimeType is not available return a Data URL + // without a media-type. [RFC2397]. + + // https://datatracker.ietf.org/doc/html/rfc2397#section-3 + // dataurl := "data:" [ mediatype ] [ ";base64" ] "," data + // mediatype := [ type "/" subtype ] *( ";" parameter ) + // data := *urlchar + // parameter := attribute "=" value + let dataURL = 'data:'; + + const parsed = parseMIMEType(mimeType || 'application/octet-stream'); + + if (parsed !== 'failure') { + dataURL += serializeAMimeType(parsed); + } + + dataURL += ';base64,'; + + const decoder = new StringDecoder('latin1'); + + for (const chunk of bytes) { + dataURL += btoa(decoder.write(chunk)); + } + + dataURL += btoa(decoder.end()); + + return dataURL + } + case 'Text': { + // 1. Let encoding be failure + let encoding = 'failure'; + + // 2. If the encodingName is present, set encoding to the + // result of getting an encoding from encodingName. + if (encodingName) { + encoding = getEncoding(encodingName); + } + + // 3. If encoding is failure, and mimeType is present: + if (encoding === 'failure' && mimeType) { + // 1. Let type be the result of parse a MIME type + // given mimeType. + const type = parseMIMEType(mimeType); + + // 2. If type is not failure, set encoding to the result + // of getting an encoding from type’s parameters["charset"]. + if (type !== 'failure') { + encoding = getEncoding(type.parameters.get('charset')); + } + } + + // 4. If encoding is failure, then set encoding to UTF-8. + if (encoding === 'failure') { + encoding = 'UTF-8'; + } + + // 5. Decode bytes using fallback encoding encoding, and + // return the result. + return decode(bytes, encoding) + } + case 'ArrayBuffer': { + // Return a new ArrayBuffer whose contents are bytes. + const sequence = combineByteSequences(bytes); + + return sequence.buffer + } + case 'BinaryString': { + // Return bytes as a binary string, in which every byte + // is represented by a code unit of equal value [0..255]. + let binaryString = ''; + + const decoder = new StringDecoder('latin1'); + + for (const chunk of bytes) { + binaryString += decoder.write(chunk); + } + + binaryString += decoder.end(); + + return binaryString + } + } + } + + /** + * @see https://encoding.spec.whatwg.org/#decode + * @param {Uint8Array[]} ioQueue + * @param {string} encoding + */ + function decode (ioQueue, encoding) { + const bytes = combineByteSequences(ioQueue); + + // 1. Let BOMEncoding be the result of BOM sniffing ioQueue. + const BOMEncoding = BOMSniffing(bytes); + + let slice = 0; + + // 2. If BOMEncoding is non-null: + if (BOMEncoding !== null) { + // 1. Set encoding to BOMEncoding. + encoding = BOMEncoding; + + // 2. Read three bytes from ioQueue, if BOMEncoding is + // UTF-8; otherwise read two bytes. + // (Do nothing with those bytes.) + slice = BOMEncoding === 'UTF-8' ? 3 : 2; + } + + // 3. Process a queue with an instance of encoding’s + // decoder, ioQueue, output, and "replacement". + + // 4. Return output. + + const sliced = bytes.slice(slice); + return new TextDecoder(encoding).decode(sliced) + } + + /** + * @see https://encoding.spec.whatwg.org/#bom-sniff + * @param {Uint8Array} ioQueue + */ + function BOMSniffing (ioQueue) { + // 1. Let BOM be the result of peeking 3 bytes from ioQueue, + // converted to a byte sequence. + const [a, b, c] = ioQueue; + + // 2. For each of the rows in the table below, starting with + // the first one and going down, if BOM starts with the + // bytes given in the first column, then return the + // encoding given in the cell in the second column of that + // row. Otherwise, return null. + if (a === 0xEF && b === 0xBB && c === 0xBF) { + return 'UTF-8' + } else if (a === 0xFE && b === 0xFF) { + return 'UTF-16BE' + } else if (a === 0xFF && b === 0xFE) { + return 'UTF-16LE' + } + + return null + } + + /** + * @param {Uint8Array[]} sequences + */ + function combineByteSequences (sequences) { + const size = sequences.reduce((a, b) => { + return a + b.byteLength + }, 0); + + let offset = 0; + + return sequences.reduce((a, b) => { + a.set(b, offset); + offset += b.byteLength; + return a + }, new Uint8Array(size)) + } + + util$4 = { + staticPropertyDescriptors, + readOperation, + fireAProgressEvent + }; + return util$4; +} + +var filereader; +var hasRequiredFilereader; + +function requireFilereader () { + if (hasRequiredFilereader) return filereader; + hasRequiredFilereader = 1; + + const { + staticPropertyDescriptors, + readOperation, + fireAProgressEvent + } = requireUtil$4(); + const { + kState, + kError, + kResult, + kEvents, + kAborted + } = requireSymbols$2(); + const { webidl } = requireWebidl(); + const { kEnumerableProperty } = requireUtil$7(); + + class FileReader extends EventTarget { + constructor () { + super(); + + this[kState] = 'empty'; + this[kResult] = null; + this[kError] = null; + this[kEvents] = { + loadend: null, + error: null, + abort: null, + load: null, + progress: null, + loadstart: null + }; + } + + /** + * @see https://w3c.github.io/FileAPI/#dfn-readAsArrayBuffer + * @param {import('buffer').Blob} blob + */ + readAsArrayBuffer (blob) { + webidl.brandCheck(this, FileReader); + + webidl.argumentLengthCheck(arguments, 1, 'FileReader.readAsArrayBuffer'); + + blob = webidl.converters.Blob(blob, { strict: false }); + + // The readAsArrayBuffer(blob) method, when invoked, + // must initiate a read operation for blob with ArrayBuffer. + readOperation(this, blob, 'ArrayBuffer'); + } + + /** + * @see https://w3c.github.io/FileAPI/#readAsBinaryString + * @param {import('buffer').Blob} blob + */ + readAsBinaryString (blob) { + webidl.brandCheck(this, FileReader); + + webidl.argumentLengthCheck(arguments, 1, 'FileReader.readAsBinaryString'); + + blob = webidl.converters.Blob(blob, { strict: false }); + + // The readAsBinaryString(blob) method, when invoked, + // must initiate a read operation for blob with BinaryString. + readOperation(this, blob, 'BinaryString'); + } + + /** + * @see https://w3c.github.io/FileAPI/#readAsDataText + * @param {import('buffer').Blob} blob + * @param {string?} encoding + */ + readAsText (blob, encoding = undefined) { + webidl.brandCheck(this, FileReader); + + webidl.argumentLengthCheck(arguments, 1, 'FileReader.readAsText'); + + blob = webidl.converters.Blob(blob, { strict: false }); + + if (encoding !== undefined) { + encoding = webidl.converters.DOMString(encoding, 'FileReader.readAsText', 'encoding'); + } + + // The readAsText(blob, encoding) method, when invoked, + // must initiate a read operation for blob with Text and encoding. + readOperation(this, blob, 'Text', encoding); + } + + /** + * @see https://w3c.github.io/FileAPI/#dfn-readAsDataURL + * @param {import('buffer').Blob} blob + */ + readAsDataURL (blob) { + webidl.brandCheck(this, FileReader); + + webidl.argumentLengthCheck(arguments, 1, 'FileReader.readAsDataURL'); + + blob = webidl.converters.Blob(blob, { strict: false }); + + // The readAsDataURL(blob) method, when invoked, must + // initiate a read operation for blob with DataURL. + readOperation(this, blob, 'DataURL'); + } + + /** + * @see https://w3c.github.io/FileAPI/#dfn-abort + */ + abort () { + // 1. If this's state is "empty" or if this's state is + // "done" set this's result to null and terminate + // this algorithm. + if (this[kState] === 'empty' || this[kState] === 'done') { + this[kResult] = null; + return + } + + // 2. If this's state is "loading" set this's state to + // "done" and set this's result to null. + if (this[kState] === 'loading') { + this[kState] = 'done'; + this[kResult] = null; + } + + // 3. If there are any tasks from this on the file reading + // task source in an affiliated task queue, then remove + // those tasks from that task queue. + this[kAborted] = true; + + // 4. Terminate the algorithm for the read method being processed. + // TODO + + // 5. Fire a progress event called abort at this. + fireAProgressEvent('abort', this); + + // 6. If this's state is not "loading", fire a progress + // event called loadend at this. + if (this[kState] !== 'loading') { + fireAProgressEvent('loadend', this); + } + } + + /** + * @see https://w3c.github.io/FileAPI/#dom-filereader-readystate + */ + get readyState () { + webidl.brandCheck(this, FileReader); + + switch (this[kState]) { + case 'empty': return this.EMPTY + case 'loading': return this.LOADING + case 'done': return this.DONE + } + } + + /** + * @see https://w3c.github.io/FileAPI/#dom-filereader-result + */ + get result () { + webidl.brandCheck(this, FileReader); + + // The result attribute’s getter, when invoked, must return + // this's result. + return this[kResult] + } + + /** + * @see https://w3c.github.io/FileAPI/#dom-filereader-error + */ + get error () { + webidl.brandCheck(this, FileReader); + + // The error attribute’s getter, when invoked, must return + // this's error. + return this[kError] + } + + get onloadend () { + webidl.brandCheck(this, FileReader); + + return this[kEvents].loadend + } + + set onloadend (fn) { + webidl.brandCheck(this, FileReader); + + if (this[kEvents].loadend) { + this.removeEventListener('loadend', this[kEvents].loadend); + } + + if (typeof fn === 'function') { + this[kEvents].loadend = fn; + this.addEventListener('loadend', fn); + } else { + this[kEvents].loadend = null; + } + } + + get onerror () { + webidl.brandCheck(this, FileReader); + + return this[kEvents].error + } + + set onerror (fn) { + webidl.brandCheck(this, FileReader); + + if (this[kEvents].error) { + this.removeEventListener('error', this[kEvents].error); + } + + if (typeof fn === 'function') { + this[kEvents].error = fn; + this.addEventListener('error', fn); + } else { + this[kEvents].error = null; + } + } + + get onloadstart () { + webidl.brandCheck(this, FileReader); + + return this[kEvents].loadstart + } + + set onloadstart (fn) { + webidl.brandCheck(this, FileReader); + + if (this[kEvents].loadstart) { + this.removeEventListener('loadstart', this[kEvents].loadstart); + } + + if (typeof fn === 'function') { + this[kEvents].loadstart = fn; + this.addEventListener('loadstart', fn); + } else { + this[kEvents].loadstart = null; + } + } + + get onprogress () { + webidl.brandCheck(this, FileReader); + + return this[kEvents].progress + } + + set onprogress (fn) { + webidl.brandCheck(this, FileReader); + + if (this[kEvents].progress) { + this.removeEventListener('progress', this[kEvents].progress); + } + + if (typeof fn === 'function') { + this[kEvents].progress = fn; + this.addEventListener('progress', fn); + } else { + this[kEvents].progress = null; + } + } + + get onload () { + webidl.brandCheck(this, FileReader); + + return this[kEvents].load + } + + set onload (fn) { + webidl.brandCheck(this, FileReader); + + if (this[kEvents].load) { + this.removeEventListener('load', this[kEvents].load); + } + + if (typeof fn === 'function') { + this[kEvents].load = fn; + this.addEventListener('load', fn); + } else { + this[kEvents].load = null; + } + } + + get onabort () { + webidl.brandCheck(this, FileReader); + + return this[kEvents].abort + } + + set onabort (fn) { + webidl.brandCheck(this, FileReader); + + if (this[kEvents].abort) { + this.removeEventListener('abort', this[kEvents].abort); + } + + if (typeof fn === 'function') { + this[kEvents].abort = fn; + this.addEventListener('abort', fn); + } else { + this[kEvents].abort = null; + } + } + } + + // https://w3c.github.io/FileAPI/#dom-filereader-empty + FileReader.EMPTY = FileReader.prototype.EMPTY = 0; + // https://w3c.github.io/FileAPI/#dom-filereader-loading + FileReader.LOADING = FileReader.prototype.LOADING = 1; + // https://w3c.github.io/FileAPI/#dom-filereader-done + FileReader.DONE = FileReader.prototype.DONE = 2; + + Object.defineProperties(FileReader.prototype, { + EMPTY: staticPropertyDescriptors, + LOADING: staticPropertyDescriptors, + DONE: staticPropertyDescriptors, + readAsArrayBuffer: kEnumerableProperty, + readAsBinaryString: kEnumerableProperty, + readAsText: kEnumerableProperty, + readAsDataURL: kEnumerableProperty, + abort: kEnumerableProperty, + readyState: kEnumerableProperty, + result: kEnumerableProperty, + error: kEnumerableProperty, + onloadstart: kEnumerableProperty, + onprogress: kEnumerableProperty, + onload: kEnumerableProperty, + onabort: kEnumerableProperty, + onerror: kEnumerableProperty, + onloadend: kEnumerableProperty, + [Symbol.toStringTag]: { + value: 'FileReader', + writable: false, + enumerable: false, + configurable: true + } + }); + + Object.defineProperties(FileReader, { + EMPTY: staticPropertyDescriptors, + LOADING: staticPropertyDescriptors, + DONE: staticPropertyDescriptors + }); + + filereader = { + FileReader + }; + return filereader; +} + +var symbols$1; +var hasRequiredSymbols$1; + +function requireSymbols$1 () { + if (hasRequiredSymbols$1) return symbols$1; + hasRequiredSymbols$1 = 1; + + symbols$1 = { + kConstruct: requireSymbols$4().kConstruct + }; + return symbols$1; +} + +var util$3; +var hasRequiredUtil$3; + +function requireUtil$3 () { + if (hasRequiredUtil$3) return util$3; + hasRequiredUtil$3 = 1; + + const assert = require$$0$4; + const { URLSerializer } = requireDataUrl(); + const { isValidHeaderName } = requireUtil$6(); + + /** + * @see https://url.spec.whatwg.org/#concept-url-equals + * @param {URL} A + * @param {URL} B + * @param {boolean | undefined} excludeFragment + * @returns {boolean} + */ + function urlEquals (A, B, excludeFragment = false) { + const serializedA = URLSerializer(A, excludeFragment); + + const serializedB = URLSerializer(B, excludeFragment); + + return serializedA === serializedB + } + + /** + * @see https://github.com/chromium/chromium/blob/694d20d134cb553d8d89e5500b9148012b1ba299/content/browser/cache_storage/cache_storage_cache.cc#L260-L262 + * @param {string} header + */ + function getFieldValues (header) { + assert(header !== null); + + const values = []; + + for (let value of header.split(',')) { + value = value.trim(); + + if (isValidHeaderName(value)) { + values.push(value); + } + } + + return values + } + + util$3 = { + urlEquals, + getFieldValues + }; + return util$3; +} + +var cache; +var hasRequiredCache; + +function requireCache () { + if (hasRequiredCache) return cache; + hasRequiredCache = 1; + + const { kConstruct } = requireSymbols$1(); + const { urlEquals, getFieldValues } = requireUtil$3(); + const { kEnumerableProperty, isDisturbed } = requireUtil$7(); + const { webidl } = requireWebidl(); + const { Response, cloneResponse, fromInnerResponse } = requireResponse(); + const { Request, fromInnerRequest } = requireRequest(); + const { kState } = requireSymbols$3(); + const { fetching } = requireFetch(); + const { urlIsHttpHttpsScheme, createDeferredPromise, readAllBytes } = requireUtil$6(); + const assert = require$$0$4; + + /** + * @see https://w3c.github.io/ServiceWorker/#dfn-cache-batch-operation + * @typedef {Object} CacheBatchOperation + * @property {'delete' | 'put'} type + * @property {any} request + * @property {any} response + * @property {import('../../types/cache').CacheQueryOptions} options + */ + + /** + * @see https://w3c.github.io/ServiceWorker/#dfn-request-response-list + * @typedef {[any, any][]} requestResponseList + */ + + class Cache { + /** + * @see https://w3c.github.io/ServiceWorker/#dfn-relevant-request-response-list + * @type {requestResponseList} + */ + #relevantRequestResponseList + + constructor () { + if (arguments[0] !== kConstruct) { + webidl.illegalConstructor(); + } + + this.#relevantRequestResponseList = arguments[1]; + } + + async match (request, options = {}) { + webidl.brandCheck(this, Cache); + + const prefix = 'Cache.match'; + webidl.argumentLengthCheck(arguments, 1, prefix); + + request = webidl.converters.RequestInfo(request, prefix, 'request'); + options = webidl.converters.CacheQueryOptions(options, prefix, 'options'); + + const p = this.#internalMatchAll(request, options, 1); + + if (p.length === 0) { + return + } + + return p[0] + } + + async matchAll (request = undefined, options = {}) { + webidl.brandCheck(this, Cache); + + const prefix = 'Cache.matchAll'; + if (request !== undefined) request = webidl.converters.RequestInfo(request, prefix, 'request'); + options = webidl.converters.CacheQueryOptions(options, prefix, 'options'); + + return this.#internalMatchAll(request, options) + } + + async add (request) { + webidl.brandCheck(this, Cache); + + const prefix = 'Cache.add'; + webidl.argumentLengthCheck(arguments, 1, prefix); + + request = webidl.converters.RequestInfo(request, prefix, 'request'); + + // 1. + const requests = [request]; + + // 2. + const responseArrayPromise = this.addAll(requests); + + // 3. + return await responseArrayPromise + } + + async addAll (requests) { + webidl.brandCheck(this, Cache); + + const prefix = 'Cache.addAll'; + webidl.argumentLengthCheck(arguments, 1, prefix); + + // 1. + const responsePromises = []; + + // 2. + const requestList = []; + + // 3. + for (let request of requests) { + if (request === undefined) { + throw webidl.errors.conversionFailed({ + prefix, + argument: 'Argument 1', + types: ['undefined is not allowed'] + }) + } + + request = webidl.converters.RequestInfo(request); + + if (typeof request === 'string') { + continue + } + + // 3.1 + const r = request[kState]; + + // 3.2 + if (!urlIsHttpHttpsScheme(r.url) || r.method !== 'GET') { + throw webidl.errors.exception({ + header: prefix, + message: 'Expected http/s scheme when method is not GET.' + }) + } + } + + // 4. + /** @type {ReturnType[]} */ + const fetchControllers = []; + + // 5. + for (const request of requests) { + // 5.1 + const r = new Request(request)[kState]; + + // 5.2 + if (!urlIsHttpHttpsScheme(r.url)) { + throw webidl.errors.exception({ + header: prefix, + message: 'Expected http/s scheme.' + }) + } + + // 5.4 + r.initiator = 'fetch'; + r.destination = 'subresource'; + + // 5.5 + requestList.push(r); + + // 5.6 + const responsePromise = createDeferredPromise(); + + // 5.7 + fetchControllers.push(fetching({ + request: r, + processResponse (response) { + // 1. + if (response.type === 'error' || response.status === 206 || response.status < 200 || response.status > 299) { + responsePromise.reject(webidl.errors.exception({ + header: 'Cache.addAll', + message: 'Received an invalid status code or the request failed.' + })); + } else if (response.headersList.contains('vary')) { // 2. + // 2.1 + const fieldValues = getFieldValues(response.headersList.get('vary')); + + // 2.2 + for (const fieldValue of fieldValues) { + // 2.2.1 + if (fieldValue === '*') { + responsePromise.reject(webidl.errors.exception({ + header: 'Cache.addAll', + message: 'invalid vary field value' + })); + + for (const controller of fetchControllers) { + controller.abort(); + } + + return + } + } + } + }, + processResponseEndOfBody (response) { + // 1. + if (response.aborted) { + responsePromise.reject(new DOMException('aborted', 'AbortError')); + return + } + + // 2. + responsePromise.resolve(response); + } + })); + + // 5.8 + responsePromises.push(responsePromise.promise); + } + + // 6. + const p = Promise.all(responsePromises); + + // 7. + const responses = await p; + + // 7.1 + const operations = []; + + // 7.2 + let index = 0; + + // 7.3 + for (const response of responses) { + // 7.3.1 + /** @type {CacheBatchOperation} */ + const operation = { + type: 'put', // 7.3.2 + request: requestList[index], // 7.3.3 + response // 7.3.4 + }; + + operations.push(operation); // 7.3.5 + + index++; // 7.3.6 + } + + // 7.5 + const cacheJobPromise = createDeferredPromise(); + + // 7.6.1 + let errorData = null; + + // 7.6.2 + try { + this.#batchCacheOperations(operations); + } catch (e) { + errorData = e; + } + + // 7.6.3 + queueMicrotask(() => { + // 7.6.3.1 + if (errorData === null) { + cacheJobPromise.resolve(undefined); + } else { + // 7.6.3.2 + cacheJobPromise.reject(errorData); + } + }); + + // 7.7 + return cacheJobPromise.promise + } + + async put (request, response) { + webidl.brandCheck(this, Cache); + + const prefix = 'Cache.put'; + webidl.argumentLengthCheck(arguments, 2, prefix); + + request = webidl.converters.RequestInfo(request, prefix, 'request'); + response = webidl.converters.Response(response, prefix, 'response'); + + // 1. + let innerRequest = null; + + // 2. + if (request instanceof Request) { + innerRequest = request[kState]; + } else { // 3. + innerRequest = new Request(request)[kState]; + } + + // 4. + if (!urlIsHttpHttpsScheme(innerRequest.url) || innerRequest.method !== 'GET') { + throw webidl.errors.exception({ + header: prefix, + message: 'Expected an http/s scheme when method is not GET' + }) + } + + // 5. + const innerResponse = response[kState]; + + // 6. + if (innerResponse.status === 206) { + throw webidl.errors.exception({ + header: prefix, + message: 'Got 206 status' + }) + } + + // 7. + if (innerResponse.headersList.contains('vary')) { + // 7.1. + const fieldValues = getFieldValues(innerResponse.headersList.get('vary')); + + // 7.2. + for (const fieldValue of fieldValues) { + // 7.2.1 + if (fieldValue === '*') { + throw webidl.errors.exception({ + header: prefix, + message: 'Got * vary field value' + }) + } + } + } + + // 8. + if (innerResponse.body && (isDisturbed(innerResponse.body.stream) || innerResponse.body.stream.locked)) { + throw webidl.errors.exception({ + header: prefix, + message: 'Response body is locked or disturbed' + }) + } + + // 9. + const clonedResponse = cloneResponse(innerResponse); + + // 10. + const bodyReadPromise = createDeferredPromise(); + + // 11. + if (innerResponse.body != null) { + // 11.1 + const stream = innerResponse.body.stream; + + // 11.2 + const reader = stream.getReader(); + + // 11.3 + readAllBytes(reader).then(bodyReadPromise.resolve, bodyReadPromise.reject); + } else { + bodyReadPromise.resolve(undefined); + } + + // 12. + /** @type {CacheBatchOperation[]} */ + const operations = []; + + // 13. + /** @type {CacheBatchOperation} */ + const operation = { + type: 'put', // 14. + request: innerRequest, // 15. + response: clonedResponse // 16. + }; + + // 17. + operations.push(operation); + + // 19. + const bytes = await bodyReadPromise.promise; + + if (clonedResponse.body != null) { + clonedResponse.body.source = bytes; + } + + // 19.1 + const cacheJobPromise = createDeferredPromise(); + + // 19.2.1 + let errorData = null; + + // 19.2.2 + try { + this.#batchCacheOperations(operations); + } catch (e) { + errorData = e; + } + + // 19.2.3 + queueMicrotask(() => { + // 19.2.3.1 + if (errorData === null) { + cacheJobPromise.resolve(); + } else { // 19.2.3.2 + cacheJobPromise.reject(errorData); + } + }); + + return cacheJobPromise.promise + } + + async delete (request, options = {}) { + webidl.brandCheck(this, Cache); + + const prefix = 'Cache.delete'; + webidl.argumentLengthCheck(arguments, 1, prefix); + + request = webidl.converters.RequestInfo(request, prefix, 'request'); + options = webidl.converters.CacheQueryOptions(options, prefix, 'options'); + + /** + * @type {Request} + */ + let r = null; + + if (request instanceof Request) { + r = request[kState]; + + if (r.method !== 'GET' && !options.ignoreMethod) { + return false + } + } else { + assert(typeof request === 'string'); + + r = new Request(request)[kState]; + } + + /** @type {CacheBatchOperation[]} */ + const operations = []; + + /** @type {CacheBatchOperation} */ + const operation = { + type: 'delete', + request: r, + options + }; + + operations.push(operation); + + const cacheJobPromise = createDeferredPromise(); + + let errorData = null; + let requestResponses; + + try { + requestResponses = this.#batchCacheOperations(operations); + } catch (e) { + errorData = e; + } + + queueMicrotask(() => { + if (errorData === null) { + cacheJobPromise.resolve(!!requestResponses?.length); + } else { + cacheJobPromise.reject(errorData); + } + }); + + return cacheJobPromise.promise + } + + /** + * @see https://w3c.github.io/ServiceWorker/#dom-cache-keys + * @param {any} request + * @param {import('../../types/cache').CacheQueryOptions} options + * @returns {Promise} + */ + async keys (request = undefined, options = {}) { + webidl.brandCheck(this, Cache); + + const prefix = 'Cache.keys'; + + if (request !== undefined) request = webidl.converters.RequestInfo(request, prefix, 'request'); + options = webidl.converters.CacheQueryOptions(options, prefix, 'options'); + + // 1. + let r = null; + + // 2. + if (request !== undefined) { + // 2.1 + if (request instanceof Request) { + // 2.1.1 + r = request[kState]; + + // 2.1.2 + if (r.method !== 'GET' && !options.ignoreMethod) { + return [] + } + } else if (typeof request === 'string') { // 2.2 + r = new Request(request)[kState]; + } + } + + // 4. + const promise = createDeferredPromise(); + + // 5. + // 5.1 + const requests = []; + + // 5.2 + if (request === undefined) { + // 5.2.1 + for (const requestResponse of this.#relevantRequestResponseList) { + // 5.2.1.1 + requests.push(requestResponse[0]); + } + } else { // 5.3 + // 5.3.1 + const requestResponses = this.#queryCache(r, options); + + // 5.3.2 + for (const requestResponse of requestResponses) { + // 5.3.2.1 + requests.push(requestResponse[0]); + } + } + + // 5.4 + queueMicrotask(() => { + // 5.4.1 + const requestList = []; + + // 5.4.2 + for (const request of requests) { + const requestObject = fromInnerRequest( + request, + new AbortController().signal, + 'immutable' + ); + // 5.4.2.1 + requestList.push(requestObject); + } + + // 5.4.3 + promise.resolve(Object.freeze(requestList)); + }); + + return promise.promise + } + + /** + * @see https://w3c.github.io/ServiceWorker/#batch-cache-operations-algorithm + * @param {CacheBatchOperation[]} operations + * @returns {requestResponseList} + */ + #batchCacheOperations (operations) { + // 1. + const cache = this.#relevantRequestResponseList; + + // 2. + const backupCache = [...cache]; + + // 3. + const addedItems = []; + + // 4.1 + const resultList = []; + + try { + // 4.2 + for (const operation of operations) { + // 4.2.1 + if (operation.type !== 'delete' && operation.type !== 'put') { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'operation type does not match "delete" or "put"' + }) + } + + // 4.2.2 + if (operation.type === 'delete' && operation.response != null) { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'delete operation should not have an associated response' + }) + } + + // 4.2.3 + if (this.#queryCache(operation.request, operation.options, addedItems).length) { + throw new DOMException('???', 'InvalidStateError') + } + + // 4.2.4 + let requestResponses; + + // 4.2.5 + if (operation.type === 'delete') { + // 4.2.5.1 + requestResponses = this.#queryCache(operation.request, operation.options); + + // TODO: the spec is wrong, this is needed to pass WPTs + if (requestResponses.length === 0) { + return [] + } + + // 4.2.5.2 + for (const requestResponse of requestResponses) { + const idx = cache.indexOf(requestResponse); + assert(idx !== -1); + + // 4.2.5.2.1 + cache.splice(idx, 1); + } + } else if (operation.type === 'put') { // 4.2.6 + // 4.2.6.1 + if (operation.response == null) { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'put operation should have an associated response' + }) + } + + // 4.2.6.2 + const r = operation.request; + + // 4.2.6.3 + if (!urlIsHttpHttpsScheme(r.url)) { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'expected http or https scheme' + }) + } + + // 4.2.6.4 + if (r.method !== 'GET') { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'not get method' + }) + } + + // 4.2.6.5 + if (operation.options != null) { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'options must not be defined' + }) + } + + // 4.2.6.6 + requestResponses = this.#queryCache(operation.request); + + // 4.2.6.7 + for (const requestResponse of requestResponses) { + const idx = cache.indexOf(requestResponse); + assert(idx !== -1); + + // 4.2.6.7.1 + cache.splice(idx, 1); + } + + // 4.2.6.8 + cache.push([operation.request, operation.response]); + + // 4.2.6.10 + addedItems.push([operation.request, operation.response]); + } + + // 4.2.7 + resultList.push([operation.request, operation.response]); + } + + // 4.3 + return resultList + } catch (e) { // 5. + // 5.1 + this.#relevantRequestResponseList.length = 0; + + // 5.2 + this.#relevantRequestResponseList = backupCache; + + // 5.3 + throw e + } + } + + /** + * @see https://w3c.github.io/ServiceWorker/#query-cache + * @param {any} requestQuery + * @param {import('../../types/cache').CacheQueryOptions} options + * @param {requestResponseList} targetStorage + * @returns {requestResponseList} + */ + #queryCache (requestQuery, options, targetStorage) { + /** @type {requestResponseList} */ + const resultList = []; + + const storage = targetStorage ?? this.#relevantRequestResponseList; + + for (const requestResponse of storage) { + const [cachedRequest, cachedResponse] = requestResponse; + if (this.#requestMatchesCachedItem(requestQuery, cachedRequest, cachedResponse, options)) { + resultList.push(requestResponse); + } + } + + return resultList + } + + /** + * @see https://w3c.github.io/ServiceWorker/#request-matches-cached-item-algorithm + * @param {any} requestQuery + * @param {any} request + * @param {any | null} response + * @param {import('../../types/cache').CacheQueryOptions | undefined} options + * @returns {boolean} + */ + #requestMatchesCachedItem (requestQuery, request, response = null, options) { + // if (options?.ignoreMethod === false && request.method === 'GET') { + // return false + // } + + const queryURL = new URL(requestQuery.url); + + const cachedURL = new URL(request.url); + + if (options?.ignoreSearch) { + cachedURL.search = ''; + + queryURL.search = ''; + } + + if (!urlEquals(queryURL, cachedURL, true)) { + return false + } + + if ( + response == null || + options?.ignoreVary || + !response.headersList.contains('vary') + ) { + return true + } + + const fieldValues = getFieldValues(response.headersList.get('vary')); + + for (const fieldValue of fieldValues) { + if (fieldValue === '*') { + return false + } + + const requestValue = request.headersList.get(fieldValue); + const queryValue = requestQuery.headersList.get(fieldValue); + + // If one has the header and the other doesn't, or one has + // a different value than the other, return false + if (requestValue !== queryValue) { + return false + } + } + + return true + } + + #internalMatchAll (request, options, maxResponses = Infinity) { + // 1. + let r = null; + + // 2. + if (request !== undefined) { + if (request instanceof Request) { + // 2.1.1 + r = request[kState]; + + // 2.1.2 + if (r.method !== 'GET' && !options.ignoreMethod) { + return [] + } + } else if (typeof request === 'string') { + // 2.2.1 + r = new Request(request)[kState]; + } + } + + // 5. + // 5.1 + const responses = []; + + // 5.2 + if (request === undefined) { + // 5.2.1 + for (const requestResponse of this.#relevantRequestResponseList) { + responses.push(requestResponse[1]); + } + } else { // 5.3 + // 5.3.1 + const requestResponses = this.#queryCache(r, options); + + // 5.3.2 + for (const requestResponse of requestResponses) { + responses.push(requestResponse[1]); + } + } + + // 5.4 + // We don't implement CORs so we don't need to loop over the responses, yay! + + // 5.5.1 + const responseList = []; + + // 5.5.2 + for (const response of responses) { + // 5.5.2.1 + const responseObject = fromInnerResponse(response, 'immutable'); + + responseList.push(responseObject.clone()); + + if (responseList.length >= maxResponses) { + break + } + } + + // 6. + return Object.freeze(responseList) + } + } + + Object.defineProperties(Cache.prototype, { + [Symbol.toStringTag]: { + value: 'Cache', + configurable: true + }, + match: kEnumerableProperty, + matchAll: kEnumerableProperty, + add: kEnumerableProperty, + addAll: kEnumerableProperty, + put: kEnumerableProperty, + delete: kEnumerableProperty, + keys: kEnumerableProperty + }); + + const cacheQueryOptionConverters = [ + { + key: 'ignoreSearch', + converter: webidl.converters.boolean, + defaultValue: () => false + }, + { + key: 'ignoreMethod', + converter: webidl.converters.boolean, + defaultValue: () => false + }, + { + key: 'ignoreVary', + converter: webidl.converters.boolean, + defaultValue: () => false + } + ]; + + webidl.converters.CacheQueryOptions = webidl.dictionaryConverter(cacheQueryOptionConverters); + + webidl.converters.MultiCacheQueryOptions = webidl.dictionaryConverter([ + ...cacheQueryOptionConverters, + { + key: 'cacheName', + converter: webidl.converters.DOMString + } + ]); + + webidl.converters.Response = webidl.interfaceConverter(Response); + + webidl.converters['sequence'] = webidl.sequenceConverter( + webidl.converters.RequestInfo + ); + + cache = { + Cache + }; + return cache; +} + +var cachestorage; +var hasRequiredCachestorage; + +function requireCachestorage () { + if (hasRequiredCachestorage) return cachestorage; + hasRequiredCachestorage = 1; + + const { kConstruct } = requireSymbols$1(); + const { Cache } = requireCache(); + const { webidl } = requireWebidl(); + const { kEnumerableProperty } = requireUtil$7(); + + class CacheStorage { + /** + * @see https://w3c.github.io/ServiceWorker/#dfn-relevant-name-to-cache-map + * @type {Map} + */ + async has (cacheName) { + webidl.brandCheck(this, CacheStorage); + + const prefix = 'CacheStorage.has'; + webidl.argumentLengthCheck(arguments, 1, prefix); + + cacheName = webidl.converters.DOMString(cacheName, prefix, 'cacheName'); + + // 2.1.1 + // 2.2 + return this.#caches.has(cacheName) + } + + /** + * @see https://w3c.github.io/ServiceWorker/#dom-cachestorage-open + * @param {string} cacheName + * @returns {Promise} + */ + async open (cacheName) { + webidl.brandCheck(this, CacheStorage); + + const prefix = 'CacheStorage.open'; + webidl.argumentLengthCheck(arguments, 1, prefix); + + cacheName = webidl.converters.DOMString(cacheName, prefix, 'cacheName'); + + // 2.1 + if (this.#caches.has(cacheName)) { + // await caches.open('v1') !== await caches.open('v1') + + // 2.1.1 + const cache = this.#caches.get(cacheName); + + // 2.1.1.1 + return new Cache(kConstruct, cache) + } + + // 2.2 + const cache = []; + + // 2.3 + this.#caches.set(cacheName, cache); + + // 2.4 + return new Cache(kConstruct, cache) + } + + /** + * @see https://w3c.github.io/ServiceWorker/#cache-storage-delete + * @param {string} cacheName + * @returns {Promise} + */ + async delete (cacheName) { + webidl.brandCheck(this, CacheStorage); + + const prefix = 'CacheStorage.delete'; + webidl.argumentLengthCheck(arguments, 1, prefix); + + cacheName = webidl.converters.DOMString(cacheName, prefix, 'cacheName'); + + return this.#caches.delete(cacheName) + } + + /** + * @see https://w3c.github.io/ServiceWorker/#cache-storage-keys + * @returns {Promise} + */ + async keys () { + webidl.brandCheck(this, CacheStorage); + + // 2.1 + const keys = this.#caches.keys(); + + // 2.2 + return [...keys] + } + } + + Object.defineProperties(CacheStorage.prototype, { + [Symbol.toStringTag]: { + value: 'CacheStorage', + configurable: true + }, + match: kEnumerableProperty, + has: kEnumerableProperty, + open: kEnumerableProperty, + delete: kEnumerableProperty, + keys: kEnumerableProperty + }); + + cachestorage = { + CacheStorage + }; + return cachestorage; +} + +var constants$1; +var hasRequiredConstants$1; + +function requireConstants$1 () { + if (hasRequiredConstants$1) return constants$1; + hasRequiredConstants$1 = 1; + + // https://wicg.github.io/cookie-store/#cookie-maximum-attribute-value-size + const maxAttributeValueSize = 1024; + + // https://wicg.github.io/cookie-store/#cookie-maximum-name-value-pair-size + const maxNameValuePairSize = 4096; + + constants$1 = { + maxAttributeValueSize, + maxNameValuePairSize + }; + return constants$1; +} + +var util$2; +var hasRequiredUtil$2; + +function requireUtil$2 () { + if (hasRequiredUtil$2) return util$2; + hasRequiredUtil$2 = 1; + + /** + * @param {string} value + * @returns {boolean} + */ + function isCTLExcludingHtab (value) { + for (let i = 0; i < value.length; ++i) { + const code = value.charCodeAt(i); + + if ( + (code >= 0x00 && code <= 0x08) || + (code >= 0x0A && code <= 0x1F) || + code === 0x7F + ) { + return true + } + } + return false + } + + /** + CHAR = + token = 1* + separators = "(" | ")" | "<" | ">" | "@" + | "," | ";" | ":" | "\" | <"> + | "/" | "[" | "]" | "?" | "=" + | "{" | "}" | SP | HT + * @param {string} name + */ + function validateCookieName (name) { + for (let i = 0; i < name.length; ++i) { + const code = name.charCodeAt(i); + + if ( + code < 0x21 || // exclude CTLs (0-31), SP and HT + code > 0x7E || // exclude non-ascii and DEL + code === 0x22 || // " + code === 0x28 || // ( + code === 0x29 || // ) + code === 0x3C || // < + code === 0x3E || // > + code === 0x40 || // @ + code === 0x2C || // , + code === 0x3B || // ; + code === 0x3A || // : + code === 0x5C || // \ + code === 0x2F || // / + code === 0x5B || // [ + code === 0x5D || // ] + code === 0x3F || // ? + code === 0x3D || // = + code === 0x7B || // { + code === 0x7D // } + ) { + throw new Error('Invalid cookie name') + } + } + } + + /** + cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE ) + cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E + ; US-ASCII characters excluding CTLs, + ; whitespace DQUOTE, comma, semicolon, + ; and backslash + * @param {string} value + */ + function validateCookieValue (value) { + let len = value.length; + let i = 0; + + // if the value is wrapped in DQUOTE + if (value[0] === '"') { + if (len === 1 || value[len - 1] !== '"') { + throw new Error('Invalid cookie value') + } + --len; + ++i; + } + + while (i < len) { + const code = value.charCodeAt(i++); + + if ( + code < 0x21 || // exclude CTLs (0-31) + code > 0x7E || // non-ascii and DEL (127) + code === 0x22 || // " + code === 0x2C || // , + code === 0x3B || // ; + code === 0x5C // \ + ) { + throw new Error('Invalid cookie value') + } + } + } + + /** + * path-value = + * @param {string} path + */ + function validateCookiePath (path) { + for (let i = 0; i < path.length; ++i) { + const code = path.charCodeAt(i); + + if ( + code < 0x20 || // exclude CTLs (0-31) + code === 0x7F || // DEL + code === 0x3B // ; + ) { + throw new Error('Invalid cookie path') + } + } + } + + /** + * I have no idea why these values aren't allowed to be honest, + * but Deno tests these. - Khafra + * @param {string} domain + */ + function validateCookieDomain (domain) { + if ( + domain.startsWith('-') || + domain.endsWith('.') || + domain.endsWith('-') + ) { + throw new Error('Invalid cookie domain') + } + } + + const IMFDays = [ + 'Sun', 'Mon', 'Tue', 'Wed', + 'Thu', 'Fri', 'Sat' + ]; + + const IMFMonths = [ + 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' + ]; + + const IMFPaddedNumbers = Array(61).fill(0).map((_, i) => i.toString().padStart(2, '0')); + + /** + * @see https://www.rfc-editor.org/rfc/rfc7231#section-7.1.1.1 + * @param {number|Date} date + IMF-fixdate = day-name "," SP date1 SP time-of-day SP GMT + ; fixed length/zone/capitalization subset of the format + ; see Section 3.3 of [RFC5322] + + day-name = %x4D.6F.6E ; "Mon", case-sensitive + / %x54.75.65 ; "Tue", case-sensitive + / %x57.65.64 ; "Wed", case-sensitive + / %x54.68.75 ; "Thu", case-sensitive + / %x46.72.69 ; "Fri", case-sensitive + / %x53.61.74 ; "Sat", case-sensitive + / %x53.75.6E ; "Sun", case-sensitive + date1 = day SP month SP year + ; e.g., 02 Jun 1982 + + day = 2DIGIT + month = %x4A.61.6E ; "Jan", case-sensitive + / %x46.65.62 ; "Feb", case-sensitive + / %x4D.61.72 ; "Mar", case-sensitive + / %x41.70.72 ; "Apr", case-sensitive + / %x4D.61.79 ; "May", case-sensitive + / %x4A.75.6E ; "Jun", case-sensitive + / %x4A.75.6C ; "Jul", case-sensitive + / %x41.75.67 ; "Aug", case-sensitive + / %x53.65.70 ; "Sep", case-sensitive + / %x4F.63.74 ; "Oct", case-sensitive + / %x4E.6F.76 ; "Nov", case-sensitive + / %x44.65.63 ; "Dec", case-sensitive + year = 4DIGIT + + GMT = %x47.4D.54 ; "GMT", case-sensitive + + time-of-day = hour ":" minute ":" second + ; 00:00:00 - 23:59:60 (leap second) + + hour = 2DIGIT + minute = 2DIGIT + second = 2DIGIT + */ + function toIMFDate (date) { + if (typeof date === 'number') { + date = new Date(date); + } + + return `${IMFDays[date.getUTCDay()]}, ${IMFPaddedNumbers[date.getUTCDate()]} ${IMFMonths[date.getUTCMonth()]} ${date.getUTCFullYear()} ${IMFPaddedNumbers[date.getUTCHours()]}:${IMFPaddedNumbers[date.getUTCMinutes()]}:${IMFPaddedNumbers[date.getUTCSeconds()]} GMT` + } + + /** + max-age-av = "Max-Age=" non-zero-digit *DIGIT + ; In practice, both expires-av and max-age-av + ; are limited to dates representable by the + ; user agent. + * @param {number} maxAge + */ + function validateCookieMaxAge (maxAge) { + if (maxAge < 0) { + throw new Error('Invalid cookie max-age') + } + } + + /** + * @see https://www.rfc-editor.org/rfc/rfc6265#section-4.1.1 + * @param {import('./index').Cookie} cookie + */ + function stringify (cookie) { + if (cookie.name.length === 0) { + return null + } + + validateCookieName(cookie.name); + validateCookieValue(cookie.value); + + const out = [`${cookie.name}=${cookie.value}`]; + + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-cookie-prefixes-00#section-3.1 + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-cookie-prefixes-00#section-3.2 + if (cookie.name.startsWith('__Secure-')) { + cookie.secure = true; + } + + if (cookie.name.startsWith('__Host-')) { + cookie.secure = true; + cookie.domain = null; + cookie.path = '/'; + } + + if (cookie.secure) { + out.push('Secure'); + } + + if (cookie.httpOnly) { + out.push('HttpOnly'); + } + + if (typeof cookie.maxAge === 'number') { + validateCookieMaxAge(cookie.maxAge); + out.push(`Max-Age=${cookie.maxAge}`); + } + + if (cookie.domain) { + validateCookieDomain(cookie.domain); + out.push(`Domain=${cookie.domain}`); + } + + if (cookie.path) { + validateCookiePath(cookie.path); + out.push(`Path=${cookie.path}`); + } + + if (cookie.expires && cookie.expires.toString() !== 'Invalid Date') { + out.push(`Expires=${toIMFDate(cookie.expires)}`); + } + + if (cookie.sameSite) { + out.push(`SameSite=${cookie.sameSite}`); + } + + for (const part of cookie.unparsed) { + if (!part.includes('=')) { + throw new Error('Invalid unparsed') + } + + const [key, ...value] = part.split('='); + + out.push(`${key.trim()}=${value.join('=')}`); + } + + return out.join('; ') + } + + util$2 = { + isCTLExcludingHtab, + validateCookieName, + validateCookiePath, + validateCookieValue, + toIMFDate, + stringify + }; + return util$2; +} + +var parse; +var hasRequiredParse; + +function requireParse () { + if (hasRequiredParse) return parse; + hasRequiredParse = 1; + + const { maxNameValuePairSize, maxAttributeValueSize } = requireConstants$1(); + const { isCTLExcludingHtab } = requireUtil$2(); + const { collectASequenceOfCodePointsFast } = requireDataUrl(); + const assert = require$$0$4; + + /** + * @description Parses the field-value attributes of a set-cookie header string. + * @see https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4 + * @param {string} header + * @returns if the header is invalid, null will be returned + */ + function parseSetCookie (header) { + // 1. If the set-cookie-string contains a %x00-08 / %x0A-1F / %x7F + // character (CTL characters excluding HTAB): Abort these steps and + // ignore the set-cookie-string entirely. + if (isCTLExcludingHtab(header)) { + return null + } + + let nameValuePair = ''; + let unparsedAttributes = ''; + let name = ''; + let value = ''; + + // 2. If the set-cookie-string contains a %x3B (";") character: + if (header.includes(';')) { + // 1. The name-value-pair string consists of the characters up to, + // but not including, the first %x3B (";"), and the unparsed- + // attributes consist of the remainder of the set-cookie-string + // (including the %x3B (";") in question). + const position = { position: 0 }; + + nameValuePair = collectASequenceOfCodePointsFast(';', header, position); + unparsedAttributes = header.slice(position.position); + } else { + // Otherwise: + + // 1. The name-value-pair string consists of all the characters + // contained in the set-cookie-string, and the unparsed- + // attributes is the empty string. + nameValuePair = header; + } + + // 3. If the name-value-pair string lacks a %x3D ("=") character, then + // the name string is empty, and the value string is the value of + // name-value-pair. + if (!nameValuePair.includes('=')) { + value = nameValuePair; + } else { + // Otherwise, the name string consists of the characters up to, but + // not including, the first %x3D ("=") character, and the (possibly + // empty) value string consists of the characters after the first + // %x3D ("=") character. + const position = { position: 0 }; + name = collectASequenceOfCodePointsFast( + '=', + nameValuePair, + position + ); + value = nameValuePair.slice(position.position + 1); + } + + // 4. Remove any leading or trailing WSP characters from the name + // string and the value string. + name = name.trim(); + value = value.trim(); + + // 5. If the sum of the lengths of the name string and the value string + // is more than 4096 octets, abort these steps and ignore the set- + // cookie-string entirely. + if (name.length + value.length > maxNameValuePairSize) { + return null + } + + // 6. The cookie-name is the name string, and the cookie-value is the + // value string. + return { + name, value, ...parseUnparsedAttributes(unparsedAttributes) + } + } + + /** + * Parses the remaining attributes of a set-cookie header + * @see https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4 + * @param {string} unparsedAttributes + * @param {[Object.]={}} cookieAttributeList + */ + function parseUnparsedAttributes (unparsedAttributes, cookieAttributeList = {}) { + // 1. If the unparsed-attributes string is empty, skip the rest of + // these steps. + if (unparsedAttributes.length === 0) { + return cookieAttributeList + } + + // 2. Discard the first character of the unparsed-attributes (which + // will be a %x3B (";") character). + assert(unparsedAttributes[0] === ';'); + unparsedAttributes = unparsedAttributes.slice(1); + + let cookieAv = ''; + + // 3. If the remaining unparsed-attributes contains a %x3B (";") + // character: + if (unparsedAttributes.includes(';')) { + // 1. Consume the characters of the unparsed-attributes up to, but + // not including, the first %x3B (";") character. + cookieAv = collectASequenceOfCodePointsFast( + ';', + unparsedAttributes, + { position: 0 } + ); + unparsedAttributes = unparsedAttributes.slice(cookieAv.length); + } else { + // Otherwise: + + // 1. Consume the remainder of the unparsed-attributes. + cookieAv = unparsedAttributes; + unparsedAttributes = ''; + } + + // Let the cookie-av string be the characters consumed in this step. + + let attributeName = ''; + let attributeValue = ''; + + // 4. If the cookie-av string contains a %x3D ("=") character: + if (cookieAv.includes('=')) { + // 1. The (possibly empty) attribute-name string consists of the + // characters up to, but not including, the first %x3D ("=") + // character, and the (possibly empty) attribute-value string + // consists of the characters after the first %x3D ("=") + // character. + const position = { position: 0 }; + + attributeName = collectASequenceOfCodePointsFast( + '=', + cookieAv, + position + ); + attributeValue = cookieAv.slice(position.position + 1); + } else { + // Otherwise: + + // 1. The attribute-name string consists of the entire cookie-av + // string, and the attribute-value string is empty. + attributeName = cookieAv; + } + + // 5. Remove any leading or trailing WSP characters from the attribute- + // name string and the attribute-value string. + attributeName = attributeName.trim(); + attributeValue = attributeValue.trim(); + + // 6. If the attribute-value is longer than 1024 octets, ignore the + // cookie-av string and return to Step 1 of this algorithm. + if (attributeValue.length > maxAttributeValueSize) { + return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList) + } + + // 7. Process the attribute-name and attribute-value according to the + // requirements in the following subsections. (Notice that + // attributes with unrecognized attribute-names are ignored.) + const attributeNameLowercase = attributeName.toLowerCase(); + + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.1 + // If the attribute-name case-insensitively matches the string + // "Expires", the user agent MUST process the cookie-av as follows. + if (attributeNameLowercase === 'expires') { + // 1. Let the expiry-time be the result of parsing the attribute-value + // as cookie-date (see Section 5.1.1). + const expiryTime = new Date(attributeValue); + + // 2. If the attribute-value failed to parse as a cookie date, ignore + // the cookie-av. + + cookieAttributeList.expires = expiryTime; + } else if (attributeNameLowercase === 'max-age') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.2 + // If the attribute-name case-insensitively matches the string "Max- + // Age", the user agent MUST process the cookie-av as follows. + + // 1. If the first character of the attribute-value is not a DIGIT or a + // "-" character, ignore the cookie-av. + const charCode = attributeValue.charCodeAt(0); + + if ((charCode < 48 || charCode > 57) && attributeValue[0] !== '-') { + return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList) + } + + // 2. If the remainder of attribute-value contains a non-DIGIT + // character, ignore the cookie-av. + if (!/^\d+$/.test(attributeValue)) { + return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList) + } + + // 3. Let delta-seconds be the attribute-value converted to an integer. + const deltaSeconds = Number(attributeValue); + + // 4. Let cookie-age-limit be the maximum age of the cookie (which + // SHOULD be 400 days or less, see Section 4.1.2.2). + + // 5. Set delta-seconds to the smaller of its present value and cookie- + // age-limit. + // deltaSeconds = Math.min(deltaSeconds * 1000, maxExpiresMs) + + // 6. If delta-seconds is less than or equal to zero (0), let expiry- + // time be the earliest representable date and time. Otherwise, let + // the expiry-time be the current date and time plus delta-seconds + // seconds. + // const expiryTime = deltaSeconds <= 0 ? Date.now() : Date.now() + deltaSeconds + + // 7. Append an attribute to the cookie-attribute-list with an + // attribute-name of Max-Age and an attribute-value of expiry-time. + cookieAttributeList.maxAge = deltaSeconds; + } else if (attributeNameLowercase === 'domain') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.3 + // If the attribute-name case-insensitively matches the string "Domain", + // the user agent MUST process the cookie-av as follows. + + // 1. Let cookie-domain be the attribute-value. + let cookieDomain = attributeValue; + + // 2. If cookie-domain starts with %x2E ("."), let cookie-domain be + // cookie-domain without its leading %x2E ("."). + if (cookieDomain[0] === '.') { + cookieDomain = cookieDomain.slice(1); + } + + // 3. Convert the cookie-domain to lower case. + cookieDomain = cookieDomain.toLowerCase(); + + // 4. Append an attribute to the cookie-attribute-list with an + // attribute-name of Domain and an attribute-value of cookie-domain. + cookieAttributeList.domain = cookieDomain; + } else if (attributeNameLowercase === 'path') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.4 + // If the attribute-name case-insensitively matches the string "Path", + // the user agent MUST process the cookie-av as follows. + + // 1. If the attribute-value is empty or if the first character of the + // attribute-value is not %x2F ("/"): + let cookiePath = ''; + if (attributeValue.length === 0 || attributeValue[0] !== '/') { + // 1. Let cookie-path be the default-path. + cookiePath = '/'; + } else { + // Otherwise: + + // 1. Let cookie-path be the attribute-value. + cookiePath = attributeValue; + } + + // 2. Append an attribute to the cookie-attribute-list with an + // attribute-name of Path and an attribute-value of cookie-path. + cookieAttributeList.path = cookiePath; + } else if (attributeNameLowercase === 'secure') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.5 + // If the attribute-name case-insensitively matches the string "Secure", + // the user agent MUST append an attribute to the cookie-attribute-list + // with an attribute-name of Secure and an empty attribute-value. + + cookieAttributeList.secure = true; + } else if (attributeNameLowercase === 'httponly') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.6 + // If the attribute-name case-insensitively matches the string + // "HttpOnly", the user agent MUST append an attribute to the cookie- + // attribute-list with an attribute-name of HttpOnly and an empty + // attribute-value. + + cookieAttributeList.httpOnly = true; + } else if (attributeNameLowercase === 'samesite') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.7 + // If the attribute-name case-insensitively matches the string + // "SameSite", the user agent MUST process the cookie-av as follows: + + // 1. Let enforcement be "Default". + let enforcement = 'Default'; + + const attributeValueLowercase = attributeValue.toLowerCase(); + // 2. If cookie-av's attribute-value is a case-insensitive match for + // "None", set enforcement to "None". + if (attributeValueLowercase.includes('none')) { + enforcement = 'None'; + } + + // 3. If cookie-av's attribute-value is a case-insensitive match for + // "Strict", set enforcement to "Strict". + if (attributeValueLowercase.includes('strict')) { + enforcement = 'Strict'; + } + + // 4. If cookie-av's attribute-value is a case-insensitive match for + // "Lax", set enforcement to "Lax". + if (attributeValueLowercase.includes('lax')) { + enforcement = 'Lax'; + } + + // 5. Append an attribute to the cookie-attribute-list with an + // attribute-name of "SameSite" and an attribute-value of + // enforcement. + cookieAttributeList.sameSite = enforcement; + } else { + cookieAttributeList.unparsed ??= []; + + cookieAttributeList.unparsed.push(`${attributeName}=${attributeValue}`); + } + + // 8. Return to Step 1 of this algorithm. + return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList) + } + + parse = { + parseSetCookie, + parseUnparsedAttributes + }; + return parse; +} + +var cookies; +var hasRequiredCookies; + +function requireCookies () { + if (hasRequiredCookies) return cookies; + hasRequiredCookies = 1; + + const { parseSetCookie } = requireParse(); + const { stringify } = requireUtil$2(); + const { webidl } = requireWebidl(); + const { Headers } = requireHeaders(); + + /** + * @typedef {Object} Cookie + * @property {string} name + * @property {string} value + * @property {Date|number|undefined} expires + * @property {number|undefined} maxAge + * @property {string|undefined} domain + * @property {string|undefined} path + * @property {boolean|undefined} secure + * @property {boolean|undefined} httpOnly + * @property {'Strict'|'Lax'|'None'} sameSite + * @property {string[]} unparsed + */ + + /** + * @param {Headers} headers + * @returns {Record} + */ + function getCookies (headers) { + webidl.argumentLengthCheck(arguments, 1, 'getCookies'); + + webidl.brandCheck(headers, Headers, { strict: false }); + + const cookie = headers.get('cookie'); + const out = {}; + + if (!cookie) { + return out + } + + for (const piece of cookie.split(';')) { + const [name, ...value] = piece.split('='); + + out[name.trim()] = value.join('='); + } + + return out + } + + /** + * @param {Headers} headers + * @param {string} name + * @param {{ path?: string, domain?: string }|undefined} attributes + * @returns {void} + */ + function deleteCookie (headers, name, attributes) { + webidl.brandCheck(headers, Headers, { strict: false }); + + const prefix = 'deleteCookie'; + webidl.argumentLengthCheck(arguments, 2, prefix); + + name = webidl.converters.DOMString(name, prefix, 'name'); + attributes = webidl.converters.DeleteCookieAttributes(attributes); + + // Matches behavior of + // https://github.com/denoland/deno_std/blob/63827b16330b82489a04614027c33b7904e08be5/http/cookie.ts#L278 + setCookie(headers, { + name, + value: '', + expires: new Date(0), + ...attributes + }); + } + + /** + * @param {Headers} headers + * @returns {Cookie[]} + */ + function getSetCookies (headers) { + webidl.argumentLengthCheck(arguments, 1, 'getSetCookies'); + + webidl.brandCheck(headers, Headers, { strict: false }); + + const cookies = headers.getSetCookie(); + + if (!cookies) { + return [] + } + + return cookies.map((pair) => parseSetCookie(pair)) + } + + /** + * @param {Headers} headers + * @param {Cookie} cookie + * @returns {void} + */ + function setCookie (headers, cookie) { + webidl.argumentLengthCheck(arguments, 2, 'setCookie'); + + webidl.brandCheck(headers, Headers, { strict: false }); + + cookie = webidl.converters.Cookie(cookie); + + const str = stringify(cookie); + + if (str) { + headers.append('Set-Cookie', str); + } + } + + webidl.converters.DeleteCookieAttributes = webidl.dictionaryConverter([ + { + converter: webidl.nullableConverter(webidl.converters.DOMString), + key: 'path', + defaultValue: () => null + }, + { + converter: webidl.nullableConverter(webidl.converters.DOMString), + key: 'domain', + defaultValue: () => null + } + ]); + + webidl.converters.Cookie = webidl.dictionaryConverter([ + { + converter: webidl.converters.DOMString, + key: 'name' + }, + { + converter: webidl.converters.DOMString, + key: 'value' + }, + { + converter: webidl.nullableConverter((value) => { + if (typeof value === 'number') { + return webidl.converters['unsigned long long'](value) + } + + return new Date(value) + }), + key: 'expires', + defaultValue: () => null + }, + { + converter: webidl.nullableConverter(webidl.converters['long long']), + key: 'maxAge', + defaultValue: () => null + }, + { + converter: webidl.nullableConverter(webidl.converters.DOMString), + key: 'domain', + defaultValue: () => null + }, + { + converter: webidl.nullableConverter(webidl.converters.DOMString), + key: 'path', + defaultValue: () => null + }, + { + converter: webidl.nullableConverter(webidl.converters.boolean), + key: 'secure', + defaultValue: () => null + }, + { + converter: webidl.nullableConverter(webidl.converters.boolean), + key: 'httpOnly', + defaultValue: () => null + }, + { + converter: webidl.converters.USVString, + key: 'sameSite', + allowedValues: ['Strict', 'Lax', 'None'] + }, + { + converter: webidl.sequenceConverter(webidl.converters.DOMString), + key: 'unparsed', + defaultValue: () => new Array(0) + } + ]); + + cookies = { + getCookies, + deleteCookie, + getSetCookies, + setCookie + }; + return cookies; +} + +var events; +var hasRequiredEvents; + +function requireEvents () { + if (hasRequiredEvents) return events; + hasRequiredEvents = 1; + + const { webidl } = requireWebidl(); + const { kEnumerableProperty } = requireUtil$7(); + const { kConstruct } = requireSymbols$4(); + const { MessagePort } = require$$3; + + /** + * @see https://html.spec.whatwg.org/multipage/comms.html#messageevent + */ + class MessageEvent extends Event { + #eventInit + + constructor (type, eventInitDict = {}) { + if (type === kConstruct) { + super(arguments[1], arguments[2]); + return + } + + const prefix = 'MessageEvent constructor'; + webidl.argumentLengthCheck(arguments, 1, prefix); + + type = webidl.converters.DOMString(type, prefix, 'type'); + eventInitDict = webidl.converters.MessageEventInit(eventInitDict, prefix, 'eventInitDict'); + + super(type, eventInitDict); + + this.#eventInit = eventInitDict; + } + + get data () { + webidl.brandCheck(this, MessageEvent); + + return this.#eventInit.data + } + + get origin () { + webidl.brandCheck(this, MessageEvent); + + return this.#eventInit.origin + } + + get lastEventId () { + webidl.brandCheck(this, MessageEvent); + + return this.#eventInit.lastEventId + } + + get source () { + webidl.brandCheck(this, MessageEvent); + + return this.#eventInit.source + } + + get ports () { + webidl.brandCheck(this, MessageEvent); + + if (!Object.isFrozen(this.#eventInit.ports)) { + Object.freeze(this.#eventInit.ports); + } + + return this.#eventInit.ports + } + + initMessageEvent ( + type, + bubbles = false, + cancelable = false, + data = null, + origin = '', + lastEventId = '', + source = null, + ports = [] + ) { + webidl.brandCheck(this, MessageEvent); + + webidl.argumentLengthCheck(arguments, 1, 'MessageEvent.initMessageEvent'); + + return new MessageEvent(type, { + bubbles, cancelable, data, origin, lastEventId, source, ports + }) + } + + static createFastMessageEvent (type, init) { + const messageEvent = new MessageEvent(kConstruct, type, init); + messageEvent.#eventInit = init; + messageEvent.#eventInit.data ??= null; + messageEvent.#eventInit.origin ??= ''; + messageEvent.#eventInit.lastEventId ??= ''; + messageEvent.#eventInit.source ??= null; + messageEvent.#eventInit.ports ??= []; + return messageEvent + } + } + + const { createFastMessageEvent } = MessageEvent; + delete MessageEvent.createFastMessageEvent; + + /** + * @see https://websockets.spec.whatwg.org/#the-closeevent-interface + */ + class CloseEvent extends Event { + #eventInit + + constructor (type, eventInitDict = {}) { + const prefix = 'CloseEvent constructor'; + webidl.argumentLengthCheck(arguments, 1, prefix); + + type = webidl.converters.DOMString(type, prefix, 'type'); + eventInitDict = webidl.converters.CloseEventInit(eventInitDict); + + super(type, eventInitDict); + + this.#eventInit = eventInitDict; + } + + get wasClean () { + webidl.brandCheck(this, CloseEvent); + + return this.#eventInit.wasClean + } + + get code () { + webidl.brandCheck(this, CloseEvent); + + return this.#eventInit.code + } + + get reason () { + webidl.brandCheck(this, CloseEvent); + + return this.#eventInit.reason + } + } + + // https://html.spec.whatwg.org/multipage/webappapis.html#the-errorevent-interface + class ErrorEvent extends Event { + #eventInit + + constructor (type, eventInitDict) { + const prefix = 'ErrorEvent constructor'; + webidl.argumentLengthCheck(arguments, 1, prefix); + + super(type, eventInitDict); + + type = webidl.converters.DOMString(type, prefix, 'type'); + eventInitDict = webidl.converters.ErrorEventInit(eventInitDict ?? {}); + + this.#eventInit = eventInitDict; + } + + get message () { + webidl.brandCheck(this, ErrorEvent); + + return this.#eventInit.message + } + + get filename () { + webidl.brandCheck(this, ErrorEvent); + + return this.#eventInit.filename + } + + get lineno () { + webidl.brandCheck(this, ErrorEvent); + + return this.#eventInit.lineno + } + + get colno () { + webidl.brandCheck(this, ErrorEvent); + + return this.#eventInit.colno + } + + get error () { + webidl.brandCheck(this, ErrorEvent); + + return this.#eventInit.error + } + } + + Object.defineProperties(MessageEvent.prototype, { + [Symbol.toStringTag]: { + value: 'MessageEvent', + configurable: true + }, + data: kEnumerableProperty, + origin: kEnumerableProperty, + lastEventId: kEnumerableProperty, + source: kEnumerableProperty, + ports: kEnumerableProperty, + initMessageEvent: kEnumerableProperty + }); + + Object.defineProperties(CloseEvent.prototype, { + [Symbol.toStringTag]: { + value: 'CloseEvent', + configurable: true + }, + reason: kEnumerableProperty, + code: kEnumerableProperty, + wasClean: kEnumerableProperty + }); + + Object.defineProperties(ErrorEvent.prototype, { + [Symbol.toStringTag]: { + value: 'ErrorEvent', + configurable: true + }, + message: kEnumerableProperty, + filename: kEnumerableProperty, + lineno: kEnumerableProperty, + colno: kEnumerableProperty, + error: kEnumerableProperty + }); + + webidl.converters.MessagePort = webidl.interfaceConverter(MessagePort); + + webidl.converters['sequence'] = webidl.sequenceConverter( + webidl.converters.MessagePort + ); + + const eventInit = [ + { + key: 'bubbles', + converter: webidl.converters.boolean, + defaultValue: () => false + }, + { + key: 'cancelable', + converter: webidl.converters.boolean, + defaultValue: () => false + }, + { + key: 'composed', + converter: webidl.converters.boolean, + defaultValue: () => false + } + ]; + + webidl.converters.MessageEventInit = webidl.dictionaryConverter([ + ...eventInit, + { + key: 'data', + converter: webidl.converters.any, + defaultValue: () => null + }, + { + key: 'origin', + converter: webidl.converters.USVString, + defaultValue: () => '' + }, + { + key: 'lastEventId', + converter: webidl.converters.DOMString, + defaultValue: () => '' + }, + { + key: 'source', + // Node doesn't implement WindowProxy or ServiceWorker, so the only + // valid value for source is a MessagePort. + converter: webidl.nullableConverter(webidl.converters.MessagePort), + defaultValue: () => null + }, + { + key: 'ports', + converter: webidl.converters['sequence'], + defaultValue: () => new Array(0) + } + ]); + + webidl.converters.CloseEventInit = webidl.dictionaryConverter([ + ...eventInit, + { + key: 'wasClean', + converter: webidl.converters.boolean, + defaultValue: () => false + }, + { + key: 'code', + converter: webidl.converters['unsigned short'], + defaultValue: () => 0 + }, + { + key: 'reason', + converter: webidl.converters.USVString, + defaultValue: () => '' + } + ]); + + webidl.converters.ErrorEventInit = webidl.dictionaryConverter([ + ...eventInit, + { + key: 'message', + converter: webidl.converters.DOMString, + defaultValue: () => '' + }, + { + key: 'filename', + converter: webidl.converters.USVString, + defaultValue: () => '' + }, + { + key: 'lineno', + converter: webidl.converters['unsigned long'], + defaultValue: () => 0 + }, + { + key: 'colno', + converter: webidl.converters['unsigned long'], + defaultValue: () => 0 + }, + { + key: 'error', + converter: webidl.converters.any + } + ]); + + events = { + MessageEvent, + CloseEvent, + ErrorEvent, + createFastMessageEvent + }; + return events; +} + +var constants; +var hasRequiredConstants; + +function requireConstants () { + if (hasRequiredConstants) return constants; + hasRequiredConstants = 1; + + // This is a Globally Unique Identifier unique used + // to validate that the endpoint accepts websocket + // connections. + // See https://www.rfc-editor.org/rfc/rfc6455.html#section-1.3 + const uid = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'; + + /** @type {PropertyDescriptor} */ + const staticPropertyDescriptors = { + enumerable: true, + writable: false, + configurable: false + }; + + const states = { + CONNECTING: 0, + OPEN: 1, + CLOSING: 2, + CLOSED: 3 + }; + + const sentCloseFrameState = { + NOT_SENT: 0, + PROCESSING: 1, + SENT: 2 + }; + + const opcodes = { + CONTINUATION: 0x0, + TEXT: 0x1, + BINARY: 0x2, + CLOSE: 0x8, + PING: 0x9, + PONG: 0xA + }; + + const maxUnsigned16Bit = 2 ** 16 - 1; // 65535 + + const parserStates = { + INFO: 0, + PAYLOADLENGTH_16: 2, + PAYLOADLENGTH_64: 3, + READ_DATA: 4 + }; + + const emptyBuffer = Buffer.allocUnsafe(0); + + const sendHints = { + string: 1, + typedArray: 2, + arrayBuffer: 3, + blob: 4 + }; + + constants = { + uid, + sentCloseFrameState, + staticPropertyDescriptors, + states, + opcodes, + maxUnsigned16Bit, + parserStates, + emptyBuffer, + sendHints + }; + return constants; +} + +var symbols; +var hasRequiredSymbols; + +function requireSymbols () { + if (hasRequiredSymbols) return symbols; + hasRequiredSymbols = 1; + + symbols = { + kWebSocketURL: Symbol('url'), + kReadyState: Symbol('ready state'), + kController: Symbol('controller'), + kResponse: Symbol('response'), + kBinaryType: Symbol('binary type'), + kSentClose: Symbol('sent close'), + kReceivedClose: Symbol('received close'), + kByteParser: Symbol('byte parser') + }; + return symbols; +} + +var util$1; +var hasRequiredUtil$1; + +function requireUtil$1 () { + if (hasRequiredUtil$1) return util$1; + hasRequiredUtil$1 = 1; + + const { kReadyState, kController, kResponse, kBinaryType, kWebSocketURL } = requireSymbols(); + const { states, opcodes } = requireConstants(); + const { ErrorEvent, createFastMessageEvent } = requireEvents(); + const { isUtf8 } = require$$0$3; + const { collectASequenceOfCodePointsFast, removeHTTPWhitespace } = requireDataUrl(); + + /* globals Blob */ + + /** + * @param {import('./websocket').WebSocket} ws + * @returns {boolean} + */ + function isConnecting (ws) { + // If the WebSocket connection is not yet established, and the connection + // is not yet closed, then the WebSocket connection is in the CONNECTING state. + return ws[kReadyState] === states.CONNECTING + } + + /** + * @param {import('./websocket').WebSocket} ws + * @returns {boolean} + */ + function isEstablished (ws) { + // If the server's response is validated as provided for above, it is + // said that _The WebSocket Connection is Established_ and that the + // WebSocket Connection is in the OPEN state. + return ws[kReadyState] === states.OPEN + } + + /** + * @param {import('./websocket').WebSocket} ws + * @returns {boolean} + */ + function isClosing (ws) { + // Upon either sending or receiving a Close control frame, it is said + // that _The WebSocket Closing Handshake is Started_ and that the + // WebSocket connection is in the CLOSING state. + return ws[kReadyState] === states.CLOSING + } + + /** + * @param {import('./websocket').WebSocket} ws + * @returns {boolean} + */ + function isClosed (ws) { + return ws[kReadyState] === states.CLOSED + } + + /** + * @see https://dom.spec.whatwg.org/#concept-event-fire + * @param {string} e + * @param {EventTarget} target + * @param {(...args: ConstructorParameters) => Event} eventFactory + * @param {EventInit | undefined} eventInitDict + */ + function fireEvent (e, target, eventFactory = (type, init) => new Event(type, init), eventInitDict = {}) { + // 1. If eventConstructor is not given, then let eventConstructor be Event. + + // 2. Let event be the result of creating an event given eventConstructor, + // in the relevant realm of target. + // 3. Initialize event’s type attribute to e. + const event = eventFactory(e, eventInitDict); + + // 4. Initialize any other IDL attributes of event as described in the + // invocation of this algorithm. + + // 5. Return the result of dispatching event at target, with legacy target + // override flag set if set. + target.dispatchEvent(event); + } + + /** + * @see https://websockets.spec.whatwg.org/#feedback-from-the-protocol + * @param {import('./websocket').WebSocket} ws + * @param {number} type Opcode + * @param {Buffer} data application data + */ + function websocketMessageReceived (ws, type, data) { + // 1. If ready state is not OPEN (1), then return. + if (ws[kReadyState] !== states.OPEN) { + return + } + + // 2. Let dataForEvent be determined by switching on type and binary type: + let dataForEvent; + + if (type === opcodes.TEXT) { + // -> type indicates that the data is Text + // a new DOMString containing data + try { + dataForEvent = utf8Decode(data); + } catch { + failWebsocketConnection(ws, 'Received invalid UTF-8 in text frame.'); + return + } + } else if (type === opcodes.BINARY) { + if (ws[kBinaryType] === 'blob') { + // -> type indicates that the data is Binary and binary type is "blob" + // a new Blob object, created in the relevant Realm of the WebSocket + // object, that represents data as its raw data + dataForEvent = new Blob([data]); + } else { + // -> type indicates that the data is Binary and binary type is "arraybuffer" + // a new ArrayBuffer object, created in the relevant Realm of the + // WebSocket object, whose contents are data + dataForEvent = toArrayBuffer(data); + } + } + + // 3. Fire an event named message at the WebSocket object, using MessageEvent, + // with the origin attribute initialized to the serialization of the WebSocket + // object’s url's origin, and the data attribute initialized to dataForEvent. + fireEvent('message', ws, createFastMessageEvent, { + origin: ws[kWebSocketURL].origin, + data: dataForEvent + }); + } + + function toArrayBuffer (buffer) { + if (buffer.byteLength === buffer.buffer.byteLength) { + return buffer.buffer + } + return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength) + } + + /** + * @see https://datatracker.ietf.org/doc/html/rfc6455 + * @see https://datatracker.ietf.org/doc/html/rfc2616 + * @see https://bugs.chromium.org/p/chromium/issues/detail?id=398407 + * @param {string} protocol + */ + function isValidSubprotocol (protocol) { + // If present, this value indicates one + // or more comma-separated subprotocol the client wishes to speak, + // ordered by preference. The elements that comprise this value + // MUST be non-empty strings with characters in the range U+0021 to + // U+007E not including separator characters as defined in + // [RFC2616] and MUST all be unique strings. + if (protocol.length === 0) { + return false + } + + for (let i = 0; i < protocol.length; ++i) { + const code = protocol.charCodeAt(i); + + if ( + code < 0x21 || // CTL, contains SP (0x20) and HT (0x09) + code > 0x7E || + code === 0x22 || // " + code === 0x28 || // ( + code === 0x29 || // ) + code === 0x2C || // , + code === 0x2F || // / + code === 0x3A || // : + code === 0x3B || // ; + code === 0x3C || // < + code === 0x3D || // = + code === 0x3E || // > + code === 0x3F || // ? + code === 0x40 || // @ + code === 0x5B || // [ + code === 0x5C || // \ + code === 0x5D || // ] + code === 0x7B || // { + code === 0x7D // } + ) { + return false + } + } + + return true + } + + /** + * @see https://datatracker.ietf.org/doc/html/rfc6455#section-7-4 + * @param {number} code + */ + function isValidStatusCode (code) { + if (code >= 1000 && code < 1015) { + return ( + code !== 1004 && // reserved + code !== 1005 && // "MUST NOT be set as a status code" + code !== 1006 // "MUST NOT be set as a status code" + ) + } + + return code >= 3000 && code <= 4999 + } + + /** + * @param {import('./websocket').WebSocket} ws + * @param {string|undefined} reason + */ + function failWebsocketConnection (ws, reason) { + const { [kController]: controller, [kResponse]: response } = ws; + + controller.abort(); + + if (response?.socket && !response.socket.destroyed) { + response.socket.destroy(); + } + + if (reason) { + // TODO: process.nextTick + fireEvent('error', ws, (type, init) => new ErrorEvent(type, init), { + error: new Error(reason), + message: reason + }); + } + } + + /** + * @see https://datatracker.ietf.org/doc/html/rfc6455#section-5.5 + * @param {number} opcode + */ + function isControlFrame (opcode) { + return ( + opcode === opcodes.CLOSE || + opcode === opcodes.PING || + opcode === opcodes.PONG + ) + } + + function isContinuationFrame (opcode) { + return opcode === opcodes.CONTINUATION + } + + function isTextBinaryFrame (opcode) { + return opcode === opcodes.TEXT || opcode === opcodes.BINARY + } + + function isValidOpcode (opcode) { + return isTextBinaryFrame(opcode) || isContinuationFrame(opcode) || isControlFrame(opcode) + } + + /** + * Parses a Sec-WebSocket-Extensions header value. + * @param {string} extensions + * @returns {Map} + */ + // TODO(@Uzlopak, @KhafraDev): make compliant https://datatracker.ietf.org/doc/html/rfc6455#section-9.1 + function parseExtensions (extensions) { + const position = { position: 0 }; + const extensionList = new Map(); + + while (position.position < extensions.length) { + const pair = collectASequenceOfCodePointsFast(';', extensions, position); + const [name, value = ''] = pair.split('='); + + extensionList.set( + removeHTTPWhitespace(name, true, false), + removeHTTPWhitespace(value, false, true) + ); + + position.position++; + } + + return extensionList + } + + /** + * @see https://www.rfc-editor.org/rfc/rfc7692#section-7.1.2.2 + * @description "client-max-window-bits = 1*DIGIT" + * @param {string} value + */ + function isValidClientWindowBits (value) { + for (let i = 0; i < value.length; i++) { + const byte = value.charCodeAt(i); + + if (byte < 0x30 || byte > 0x39) { + return false + } + } + + return true + } + + // https://nodejs.org/api/intl.html#detecting-internationalization-support + const hasIntl = typeof process.versions.icu === 'string'; + const fatalDecoder = hasIntl ? new TextDecoder('utf-8', { fatal: true }) : undefined; + + /** + * Converts a Buffer to utf-8, even on platforms without icu. + * @param {Buffer} buffer + */ + const utf8Decode = hasIntl + ? fatalDecoder.decode.bind(fatalDecoder) + : function (buffer) { + if (isUtf8(buffer)) { + return buffer.toString('utf-8') + } + throw new TypeError('Invalid utf-8 received.') + }; + + util$1 = { + isConnecting, + isEstablished, + isClosing, + isClosed, + fireEvent, + isValidSubprotocol, + isValidStatusCode, + failWebsocketConnection, + websocketMessageReceived, + utf8Decode, + isControlFrame, + isContinuationFrame, + isTextBinaryFrame, + isValidOpcode, + parseExtensions, + isValidClientWindowBits + }; + return util$1; +} + +var frame; +var hasRequiredFrame; + +function requireFrame () { + if (hasRequiredFrame) return frame; + hasRequiredFrame = 1; + + const { maxUnsigned16Bit } = requireConstants(); + + const BUFFER_SIZE = 16386; + + /** @type {import('crypto')} */ + let crypto; + let buffer = null; + let bufIdx = BUFFER_SIZE; + + try { + crypto = require('node:crypto'); + /* c8 ignore next 3 */ + } catch { + crypto = { + // not full compatibility, but minimum. + randomFillSync: function randomFillSync (buffer, _offset, _size) { + for (let i = 0; i < buffer.length; ++i) { + buffer[i] = Math.random() * 255 | 0; + } + return buffer + } + }; + } + + function generateMask () { + if (bufIdx === BUFFER_SIZE) { + bufIdx = 0; + crypto.randomFillSync((buffer ??= Buffer.allocUnsafe(BUFFER_SIZE)), 0, BUFFER_SIZE); + } + return [buffer[bufIdx++], buffer[bufIdx++], buffer[bufIdx++], buffer[bufIdx++]] + } + + class WebsocketFrameSend { + /** + * @param {Buffer|undefined} data + */ + constructor (data) { + this.frameData = data; + } + + createFrame (opcode) { + const frameData = this.frameData; + const maskKey = generateMask(); + const bodyLength = frameData?.byteLength ?? 0; + + /** @type {number} */ + let payloadLength = bodyLength; // 0-125 + let offset = 6; + + if (bodyLength > maxUnsigned16Bit) { + offset += 8; // payload length is next 8 bytes + payloadLength = 127; + } else if (bodyLength > 125) { + offset += 2; // payload length is next 2 bytes + payloadLength = 126; + } + + const buffer = Buffer.allocUnsafe(bodyLength + offset); + + // Clear first 2 bytes, everything else is overwritten + buffer[0] = buffer[1] = 0; + buffer[0] |= 0x80; // FIN + buffer[0] = (buffer[0] & 0xF0) + opcode; // opcode + + /*! ws. MIT License. Einar Otto Stangvik */ + buffer[offset - 4] = maskKey[0]; + buffer[offset - 3] = maskKey[1]; + buffer[offset - 2] = maskKey[2]; + buffer[offset - 1] = maskKey[3]; + + buffer[1] = payloadLength; + + if (payloadLength === 126) { + buffer.writeUInt16BE(bodyLength, 2); + } else if (payloadLength === 127) { + // Clear extended payload length + buffer[2] = buffer[3] = 0; + buffer.writeUIntBE(bodyLength, 4, 6); + } + + buffer[1] |= 0x80; // MASK + + // mask body + for (let i = 0; i < bodyLength; ++i) { + buffer[offset + i] = frameData[i] ^ maskKey[i & 3]; + } + + return buffer + } + } + + frame = { + WebsocketFrameSend + }; + return frame; +} + +var connection; +var hasRequiredConnection; + +function requireConnection () { + if (hasRequiredConnection) return connection; + hasRequiredConnection = 1; + + const { uid, states, sentCloseFrameState, emptyBuffer, opcodes } = requireConstants(); + const { + kReadyState, + kSentClose, + kByteParser, + kReceivedClose, + kResponse + } = requireSymbols(); + const { fireEvent, failWebsocketConnection, isClosing, isClosed, isEstablished, parseExtensions } = requireUtil$1(); + const { channels } = requireDiagnostics(); + const { CloseEvent } = requireEvents(); + const { makeRequest } = requireRequest(); + const { fetching } = requireFetch(); + const { Headers, getHeadersList } = requireHeaders(); + const { getDecodeSplit } = requireUtil$6(); + const { WebsocketFrameSend } = requireFrame(); + + /** @type {import('crypto')} */ + let crypto; + try { + crypto = require('node:crypto'); + /* c8 ignore next 3 */ + } catch { + + } + + /** + * @see https://websockets.spec.whatwg.org/#concept-websocket-establish + * @param {URL} url + * @param {string|string[]} protocols + * @param {import('./websocket').WebSocket} ws + * @param {(response: any, extensions: string[] | undefined) => void} onEstablish + * @param {Partial} options + */ + function establishWebSocketConnection (url, protocols, client, ws, onEstablish, options) { + // 1. Let requestURL be a copy of url, with its scheme set to "http", if url’s + // scheme is "ws", and to "https" otherwise. + const requestURL = url; + + requestURL.protocol = url.protocol === 'ws:' ? 'http:' : 'https:'; + + // 2. Let request be a new request, whose URL is requestURL, client is client, + // service-workers mode is "none", referrer is "no-referrer", mode is + // "websocket", credentials mode is "include", cache mode is "no-store" , + // and redirect mode is "error". + const request = makeRequest({ + urlList: [requestURL], + client, + serviceWorkers: 'none', + referrer: 'no-referrer', + mode: 'websocket', + credentials: 'include', + cache: 'no-store', + redirect: 'error' + }); + + // Note: undici extension, allow setting custom headers. + if (options.headers) { + const headersList = getHeadersList(new Headers(options.headers)); + + request.headersList = headersList; + } + + // 3. Append (`Upgrade`, `websocket`) to request’s header list. + // 4. Append (`Connection`, `Upgrade`) to request’s header list. + // Note: both of these are handled by undici currently. + // https://github.com/nodejs/undici/blob/68c269c4144c446f3f1220951338daef4a6b5ec4/lib/client.js#L1397 + + // 5. Let keyValue be a nonce consisting of a randomly selected + // 16-byte value that has been forgiving-base64-encoded and + // isomorphic encoded. + const keyValue = crypto.randomBytes(16).toString('base64'); + + // 6. Append (`Sec-WebSocket-Key`, keyValue) to request’s + // header list. + request.headersList.append('sec-websocket-key', keyValue); + + // 7. Append (`Sec-WebSocket-Version`, `13`) to request’s + // header list. + request.headersList.append('sec-websocket-version', '13'); + + // 8. For each protocol in protocols, combine + // (`Sec-WebSocket-Protocol`, protocol) in request’s header + // list. + for (const protocol of protocols) { + request.headersList.append('sec-websocket-protocol', protocol); + } + + // 9. Let permessageDeflate be a user-agent defined + // "permessage-deflate" extension header value. + // https://github.com/mozilla/gecko-dev/blob/ce78234f5e653a5d3916813ff990f053510227bc/netwerk/protocol/websocket/WebSocketChannel.cpp#L2673 + const permessageDeflate = 'permessage-deflate; client_max_window_bits'; + + // 10. Append (`Sec-WebSocket-Extensions`, permessageDeflate) to + // request’s header list. + request.headersList.append('sec-websocket-extensions', permessageDeflate); + + // 11. Fetch request with useParallelQueue set to true, and + // processResponse given response being these steps: + const controller = fetching({ + request, + useParallelQueue: true, + dispatcher: options.dispatcher, + processResponse (response) { + // 1. If response is a network error or its status is not 101, + // fail the WebSocket connection. + if (response.type === 'error' || response.status !== 101) { + failWebsocketConnection(ws, 'Received network error or non-101 status code.'); + return + } + + // 2. If protocols is not the empty list and extracting header + // list values given `Sec-WebSocket-Protocol` and response’s + // header list results in null, failure, or the empty byte + // sequence, then fail the WebSocket connection. + if (protocols.length !== 0 && !response.headersList.get('Sec-WebSocket-Protocol')) { + failWebsocketConnection(ws, 'Server did not respond with sent protocols.'); + return + } + + // 3. Follow the requirements stated step 2 to step 6, inclusive, + // of the last set of steps in section 4.1 of The WebSocket + // Protocol to validate response. This either results in fail + // the WebSocket connection or the WebSocket connection is + // established. + + // 2. If the response lacks an |Upgrade| header field or the |Upgrade| + // header field contains a value that is not an ASCII case- + // insensitive match for the value "websocket", the client MUST + // _Fail the WebSocket Connection_. + if (response.headersList.get('Upgrade')?.toLowerCase() !== 'websocket') { + failWebsocketConnection(ws, 'Server did not set Upgrade header to "websocket".'); + return + } + + // 3. If the response lacks a |Connection| header field or the + // |Connection| header field doesn't contain a token that is an + // ASCII case-insensitive match for the value "Upgrade", the client + // MUST _Fail the WebSocket Connection_. + if (response.headersList.get('Connection')?.toLowerCase() !== 'upgrade') { + failWebsocketConnection(ws, 'Server did not set Connection header to "upgrade".'); + return + } + + // 4. If the response lacks a |Sec-WebSocket-Accept| header field or + // the |Sec-WebSocket-Accept| contains a value other than the + // base64-encoded SHA-1 of the concatenation of the |Sec-WebSocket- + // Key| (as a string, not base64-decoded) with the string "258EAFA5- + // E914-47DA-95CA-C5AB0DC85B11" but ignoring any leading and + // trailing whitespace, the client MUST _Fail the WebSocket + // Connection_. + const secWSAccept = response.headersList.get('Sec-WebSocket-Accept'); + const digest = crypto.createHash('sha1').update(keyValue + uid).digest('base64'); + if (secWSAccept !== digest) { + failWebsocketConnection(ws, 'Incorrect hash received in Sec-WebSocket-Accept header.'); + return + } + + // 5. If the response includes a |Sec-WebSocket-Extensions| header + // field and this header field indicates the use of an extension + // that was not present in the client's handshake (the server has + // indicated an extension not requested by the client), the client + // MUST _Fail the WebSocket Connection_. (The parsing of this + // header field to determine which extensions are requested is + // discussed in Section 9.1.) + const secExtension = response.headersList.get('Sec-WebSocket-Extensions'); + let extensions; + + if (secExtension !== null) { + extensions = parseExtensions(secExtension); + + if (!extensions.has('permessage-deflate')) { + failWebsocketConnection(ws, 'Sec-WebSocket-Extensions header does not match.'); + return + } + } + + // 6. If the response includes a |Sec-WebSocket-Protocol| header field + // and this header field indicates the use of a subprotocol that was + // not present in the client's handshake (the server has indicated a + // subprotocol not requested by the client), the client MUST _Fail + // the WebSocket Connection_. + const secProtocol = response.headersList.get('Sec-WebSocket-Protocol'); + + if (secProtocol !== null) { + const requestProtocols = getDecodeSplit('sec-websocket-protocol', request.headersList); + + // The client can request that the server use a specific subprotocol by + // including the |Sec-WebSocket-Protocol| field in its handshake. If it + // is specified, the server needs to include the same field and one of + // the selected subprotocol values in its response for the connection to + // be established. + if (!requestProtocols.includes(secProtocol)) { + failWebsocketConnection(ws, 'Protocol was not set in the opening handshake.'); + return + } + } + + response.socket.on('data', onSocketData); + response.socket.on('close', onSocketClose); + response.socket.on('error', onSocketError); + + if (channels.open.hasSubscribers) { + channels.open.publish({ + address: response.socket.address(), + protocol: secProtocol, + extensions: secExtension + }); + } + + onEstablish(response, extensions); + } + }); + + return controller + } + + function closeWebSocketConnection (ws, code, reason, reasonByteLength) { + if (isClosing(ws) || isClosed(ws)) ; else if (!isEstablished(ws)) { + // If the WebSocket connection is not yet established + // Fail the WebSocket connection and set this's ready state + // to CLOSING (2). + failWebsocketConnection(ws, 'Connection was closed before it was established.'); + ws[kReadyState] = states.CLOSING; + } else if (ws[kSentClose] === sentCloseFrameState.NOT_SENT) { + // If the WebSocket closing handshake has not yet been started + // Start the WebSocket closing handshake and set this's ready + // state to CLOSING (2). + // - If neither code nor reason is present, the WebSocket Close + // message must not have a body. + // - If code is present, then the status code to use in the + // WebSocket Close message must be the integer given by code. + // - If reason is also present, then reasonBytes must be + // provided in the Close message after the status code. + + ws[kSentClose] = sentCloseFrameState.PROCESSING; + + const frame = new WebsocketFrameSend(); + + // If neither code nor reason is present, the WebSocket Close + // message must not have a body. + + // If code is present, then the status code to use in the + // WebSocket Close message must be the integer given by code. + if (code !== undefined && reason === undefined) { + frame.frameData = Buffer.allocUnsafe(2); + frame.frameData.writeUInt16BE(code, 0); + } else if (code !== undefined && reason !== undefined) { + // If reason is also present, then reasonBytes must be + // provided in the Close message after the status code. + frame.frameData = Buffer.allocUnsafe(2 + reasonByteLength); + frame.frameData.writeUInt16BE(code, 0); + // the body MAY contain UTF-8-encoded data with value /reason/ + frame.frameData.write(reason, 2, 'utf-8'); + } else { + frame.frameData = emptyBuffer; + } + + /** @type {import('stream').Duplex} */ + const socket = ws[kResponse].socket; + + socket.write(frame.createFrame(opcodes.CLOSE)); + + ws[kSentClose] = sentCloseFrameState.SENT; + + // Upon either sending or receiving a Close control frame, it is said + // that _The WebSocket Closing Handshake is Started_ and that the + // WebSocket connection is in the CLOSING state. + ws[kReadyState] = states.CLOSING; + } else { + // Otherwise + // Set this's ready state to CLOSING (2). + ws[kReadyState] = states.CLOSING; + } + } + + /** + * @param {Buffer} chunk + */ + function onSocketData (chunk) { + if (!this.ws[kByteParser].write(chunk)) { + this.pause(); + } + } + + /** + * @see https://websockets.spec.whatwg.org/#feedback-from-the-protocol + * @see https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.4 + */ + function onSocketClose () { + const { ws } = this; + const { [kResponse]: response } = ws; + + response.socket.off('data', onSocketData); + response.socket.off('close', onSocketClose); + response.socket.off('error', onSocketError); + + // If the TCP connection was closed after the + // WebSocket closing handshake was completed, the WebSocket connection + // is said to have been closed _cleanly_. + const wasClean = ws[kSentClose] === sentCloseFrameState.SENT && ws[kReceivedClose]; + + let code = 1005; + let reason = ''; + + const result = ws[kByteParser].closingInfo; + + if (result && !result.error) { + code = result.code ?? 1005; + reason = result.reason; + } else if (!ws[kReceivedClose]) { + // If _The WebSocket + // Connection is Closed_ and no Close control frame was received by the + // endpoint (such as could occur if the underlying transport connection + // is lost), _The WebSocket Connection Close Code_ is considered to be + // 1006. + code = 1006; + } + + // 1. Change the ready state to CLOSED (3). + ws[kReadyState] = states.CLOSED; + + // 2. If the user agent was required to fail the WebSocket + // connection, or if the WebSocket connection was closed + // after being flagged as full, fire an event named error + // at the WebSocket object. + // TODO + + // 3. Fire an event named close at the WebSocket object, + // using CloseEvent, with the wasClean attribute + // initialized to true if the connection closed cleanly + // and false otherwise, the code attribute initialized to + // the WebSocket connection close code, and the reason + // attribute initialized to the result of applying UTF-8 + // decode without BOM to the WebSocket connection close + // reason. + // TODO: process.nextTick + fireEvent('close', ws, (type, init) => new CloseEvent(type, init), { + wasClean, code, reason + }); + + if (channels.close.hasSubscribers) { + channels.close.publish({ + websocket: ws, + code, + reason + }); + } + } + + function onSocketError (error) { + const { ws } = this; + + ws[kReadyState] = states.CLOSING; + + if (channels.socketError.hasSubscribers) { + channels.socketError.publish(error); + } + + this.destroy(); + } + + connection = { + establishWebSocketConnection, + closeWebSocketConnection + }; + return connection; +} + +var permessageDeflate; +var hasRequiredPermessageDeflate; + +function requirePermessageDeflate () { + if (hasRequiredPermessageDeflate) return permessageDeflate; + hasRequiredPermessageDeflate = 1; + + const { createInflateRaw, Z_DEFAULT_WINDOWBITS } = require$$1; + const { isValidClientWindowBits } = requireUtil$1(); + + const tail = Buffer.from([0x00, 0x00, 0xff, 0xff]); + const kBuffer = Symbol('kBuffer'); + const kLength = Symbol('kLength'); + + class PerMessageDeflate { + /** @type {import('node:zlib').InflateRaw} */ + #inflate + + #options = {} + + constructor (extensions) { + this.#options.serverNoContextTakeover = extensions.has('server_no_context_takeover'); + this.#options.serverMaxWindowBits = extensions.get('server_max_window_bits'); + } + + decompress (chunk, fin, callback) { + // An endpoint uses the following algorithm to decompress a message. + // 1. Append 4 octets of 0x00 0x00 0xff 0xff to the tail end of the + // payload of the message. + // 2. Decompress the resulting data using DEFLATE. + + if (!this.#inflate) { + let windowBits = Z_DEFAULT_WINDOWBITS; + + if (this.#options.serverMaxWindowBits) { // empty values default to Z_DEFAULT_WINDOWBITS + if (!isValidClientWindowBits(this.#options.serverMaxWindowBits)) { + callback(new Error('Invalid server_max_window_bits')); + return + } + + windowBits = Number.parseInt(this.#options.serverMaxWindowBits); + } + + this.#inflate = createInflateRaw({ windowBits }); + this.#inflate[kBuffer] = []; + this.#inflate[kLength] = 0; + + this.#inflate.on('data', (data) => { + this.#inflate[kBuffer].push(data); + this.#inflate[kLength] += data.length; + }); + + this.#inflate.on('error', (err) => { + this.#inflate = null; + callback(err); + }); + } + + this.#inflate.write(chunk); + if (fin) { + this.#inflate.write(tail); + } + + this.#inflate.flush(() => { + const full = Buffer.concat(this.#inflate[kBuffer], this.#inflate[kLength]); + + this.#inflate[kBuffer].length = 0; + this.#inflate[kLength] = 0; + + callback(null, full); + }); + } + } + + permessageDeflate = { PerMessageDeflate }; + return permessageDeflate; +} + +var receiver; +var hasRequiredReceiver; + +function requireReceiver () { + if (hasRequiredReceiver) return receiver; + hasRequiredReceiver = 1; + + const { Writable } = require$$0$5; + const assert = require$$0$4; + const { parserStates, opcodes, states, emptyBuffer, sentCloseFrameState } = requireConstants(); + const { kReadyState, kSentClose, kResponse, kReceivedClose } = requireSymbols(); + const { channels } = requireDiagnostics(); + const { + isValidStatusCode, + isValidOpcode, + failWebsocketConnection, + websocketMessageReceived, + utf8Decode, + isControlFrame, + isTextBinaryFrame, + isContinuationFrame + } = requireUtil$1(); + const { WebsocketFrameSend } = requireFrame(); + const { closeWebSocketConnection } = requireConnection(); + const { PerMessageDeflate } = requirePermessageDeflate(); + + // This code was influenced by ws released under the MIT license. + // Copyright (c) 2011 Einar Otto Stangvik + // Copyright (c) 2013 Arnout Kazemier and contributors + // Copyright (c) 2016 Luigi Pinca and contributors + + class ByteParser extends Writable { + #buffers = [] + #byteOffset = 0 + #loop = false + + #state = parserStates.INFO + + #info = {} + #fragments = [] + + /** @type {Map} */ + #extensions + + constructor (ws, extensions) { + super(); + + this.ws = ws; + this.#extensions = extensions == null ? new Map() : extensions; + + if (this.#extensions.has('permessage-deflate')) { + this.#extensions.set('permessage-deflate', new PerMessageDeflate(extensions)); + } + } + + /** + * @param {Buffer} chunk + * @param {() => void} callback + */ + _write (chunk, _, callback) { + this.#buffers.push(chunk); + this.#byteOffset += chunk.length; + this.#loop = true; + + this.run(callback); + } + + /** + * Runs whenever a new chunk is received. + * Callback is called whenever there are no more chunks buffering, + * or not enough bytes are buffered to parse. + */ + run (callback) { + while (this.#loop) { + if (this.#state === parserStates.INFO) { + // If there aren't enough bytes to parse the payload length, etc. + if (this.#byteOffset < 2) { + return callback() + } + + const buffer = this.consume(2); + const fin = (buffer[0] & 0x80) !== 0; + const opcode = buffer[0] & 0x0F; + const masked = (buffer[1] & 0x80) === 0x80; + + const fragmented = !fin && opcode !== opcodes.CONTINUATION; + const payloadLength = buffer[1] & 0x7F; + + const rsv1 = buffer[0] & 0x40; + const rsv2 = buffer[0] & 0x20; + const rsv3 = buffer[0] & 0x10; + + if (!isValidOpcode(opcode)) { + failWebsocketConnection(this.ws, 'Invalid opcode received'); + return callback() + } + + if (masked) { + failWebsocketConnection(this.ws, 'Frame cannot be masked'); + return callback() + } + + // MUST be 0 unless an extension is negotiated that defines meanings + // for non-zero values. If a nonzero value is received and none of + // the negotiated extensions defines the meaning of such a nonzero + // value, the receiving endpoint MUST _Fail the WebSocket + // Connection_. + // This document allocates the RSV1 bit of the WebSocket header for + // PMCEs and calls the bit the "Per-Message Compressed" bit. On a + // WebSocket connection where a PMCE is in use, this bit indicates + // whether a message is compressed or not. + if (rsv1 !== 0 && !this.#extensions.has('permessage-deflate')) { + failWebsocketConnection(this.ws, 'Expected RSV1 to be clear.'); + return + } + + if (rsv2 !== 0 || rsv3 !== 0) { + failWebsocketConnection(this.ws, 'RSV1, RSV2, RSV3 must be clear'); + return + } + + if (fragmented && !isTextBinaryFrame(opcode)) { + // Only text and binary frames can be fragmented + failWebsocketConnection(this.ws, 'Invalid frame type was fragmented.'); + return + } + + // If we are already parsing a text/binary frame and do not receive either + // a continuation frame or close frame, fail the connection. + if (isTextBinaryFrame(opcode) && this.#fragments.length > 0) { + failWebsocketConnection(this.ws, 'Expected continuation frame'); + return + } + + if (this.#info.fragmented && fragmented) { + // A fragmented frame can't be fragmented itself + failWebsocketConnection(this.ws, 'Fragmented frame exceeded 125 bytes.'); + return + } + + // "All control frames MUST have a payload length of 125 bytes or less + // and MUST NOT be fragmented." + if ((payloadLength > 125 || fragmented) && isControlFrame(opcode)) { + failWebsocketConnection(this.ws, 'Control frame either too large or fragmented'); + return + } + + if (isContinuationFrame(opcode) && this.#fragments.length === 0 && !this.#info.compressed) { + failWebsocketConnection(this.ws, 'Unexpected continuation frame'); + return + } + + if (payloadLength <= 125) { + this.#info.payloadLength = payloadLength; + this.#state = parserStates.READ_DATA; + } else if (payloadLength === 126) { + this.#state = parserStates.PAYLOADLENGTH_16; + } else if (payloadLength === 127) { + this.#state = parserStates.PAYLOADLENGTH_64; + } + + if (isTextBinaryFrame(opcode)) { + this.#info.binaryType = opcode; + this.#info.compressed = rsv1 !== 0; + } + + this.#info.opcode = opcode; + this.#info.masked = masked; + this.#info.fin = fin; + this.#info.fragmented = fragmented; + } else if (this.#state === parserStates.PAYLOADLENGTH_16) { + if (this.#byteOffset < 2) { + return callback() + } + + const buffer = this.consume(2); + + this.#info.payloadLength = buffer.readUInt16BE(0); + this.#state = parserStates.READ_DATA; + } else if (this.#state === parserStates.PAYLOADLENGTH_64) { + if (this.#byteOffset < 8) { + return callback() + } + + const buffer = this.consume(8); + const upper = buffer.readUInt32BE(0); + + // 2^31 is the maximum bytes an arraybuffer can contain + // on 32-bit systems. Although, on 64-bit systems, this is + // 2^53-1 bytes. + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Invalid_array_length + // https://source.chromium.org/chromium/chromium/src/+/main:v8/src/common/globals.h;drc=1946212ac0100668f14eb9e2843bdd846e510a1e;bpv=1;bpt=1;l=1275 + // https://source.chromium.org/chromium/chromium/src/+/main:v8/src/objects/js-array-buffer.h;l=34;drc=1946212ac0100668f14eb9e2843bdd846e510a1e + if (upper > 2 ** 31 - 1) { + failWebsocketConnection(this.ws, 'Received payload length > 2^31 bytes.'); + return + } + + const lower = buffer.readUInt32BE(4); + + this.#info.payloadLength = (upper << 8) + lower; + this.#state = parserStates.READ_DATA; + } else if (this.#state === parserStates.READ_DATA) { + if (this.#byteOffset < this.#info.payloadLength) { + return callback() + } + + const body = this.consume(this.#info.payloadLength); + + if (isControlFrame(this.#info.opcode)) { + this.#loop = this.parseControlFrame(body); + this.#state = parserStates.INFO; + } else { + if (!this.#info.compressed) { + this.#fragments.push(body); + + // If the frame is not fragmented, a message has been received. + // If the frame is fragmented, it will terminate with a fin bit set + // and an opcode of 0 (continuation), therefore we handle that when + // parsing continuation frames, not here. + if (!this.#info.fragmented && this.#info.fin) { + const fullMessage = Buffer.concat(this.#fragments); + websocketMessageReceived(this.ws, this.#info.binaryType, fullMessage); + this.#fragments.length = 0; + } + + this.#state = parserStates.INFO; + } else { + this.#extensions.get('permessage-deflate').decompress(body, this.#info.fin, (error, data) => { + if (error) { + closeWebSocketConnection(this.ws, 1007, error.message, error.message.length); + return + } + + this.#fragments.push(data); + + if (!this.#info.fin) { + this.#state = parserStates.INFO; + this.#loop = true; + this.run(callback); + return + } + + websocketMessageReceived(this.ws, this.#info.binaryType, Buffer.concat(this.#fragments)); + + this.#loop = true; + this.#state = parserStates.INFO; + this.#fragments.length = 0; + this.run(callback); + }); + + this.#loop = false; + break + } + } + } + } + } + + /** + * Take n bytes from the buffered Buffers + * @param {number} n + * @returns {Buffer} + */ + consume (n) { + if (n > this.#byteOffset) { + throw new Error('Called consume() before buffers satiated.') + } else if (n === 0) { + return emptyBuffer + } + + if (this.#buffers[0].length === n) { + this.#byteOffset -= this.#buffers[0].length; + return this.#buffers.shift() + } + + const buffer = Buffer.allocUnsafe(n); + let offset = 0; + + while (offset !== n) { + const next = this.#buffers[0]; + const { length } = next; + + if (length + offset === n) { + buffer.set(this.#buffers.shift(), offset); + break + } else if (length + offset > n) { + buffer.set(next.subarray(0, n - offset), offset); + this.#buffers[0] = next.subarray(n - offset); + break + } else { + buffer.set(this.#buffers.shift(), offset); + offset += next.length; + } + } + + this.#byteOffset -= n; + + return buffer + } + + parseCloseBody (data) { + assert(data.length !== 1); + + // https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.5 + /** @type {number|undefined} */ + let code; + + if (data.length >= 2) { + // _The WebSocket Connection Close Code_ is + // defined as the status code (Section 7.4) contained in the first Close + // control frame received by the application + code = data.readUInt16BE(0); + } + + if (code !== undefined && !isValidStatusCode(code)) { + return { code: 1002, reason: 'Invalid status code', error: true } + } + + // https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.6 + /** @type {Buffer} */ + let reason = data.subarray(2); + + // Remove BOM + if (reason[0] === 0xEF && reason[1] === 0xBB && reason[2] === 0xBF) { + reason = reason.subarray(3); + } + + try { + reason = utf8Decode(reason); + } catch { + return { code: 1007, reason: 'Invalid UTF-8', error: true } + } + + return { code, reason, error: false } + } + + /** + * Parses control frames. + * @param {Buffer} body + */ + parseControlFrame (body) { + const { opcode, payloadLength } = this.#info; + + if (opcode === opcodes.CLOSE) { + if (payloadLength === 1) { + failWebsocketConnection(this.ws, 'Received close frame with a 1-byte body.'); + return false + } + + this.#info.closeInfo = this.parseCloseBody(body); + + if (this.#info.closeInfo.error) { + const { code, reason } = this.#info.closeInfo; + + closeWebSocketConnection(this.ws, code, reason, reason.length); + failWebsocketConnection(this.ws, reason); + return false + } + + if (this.ws[kSentClose] !== sentCloseFrameState.SENT) { + // If an endpoint receives a Close frame and did not previously send a + // Close frame, the endpoint MUST send a Close frame in response. (When + // sending a Close frame in response, the endpoint typically echos the + // status code it received.) + let body = emptyBuffer; + if (this.#info.closeInfo.code) { + body = Buffer.allocUnsafe(2); + body.writeUInt16BE(this.#info.closeInfo.code, 0); + } + const closeFrame = new WebsocketFrameSend(body); + + this.ws[kResponse].socket.write( + closeFrame.createFrame(opcodes.CLOSE), + (err) => { + if (!err) { + this.ws[kSentClose] = sentCloseFrameState.SENT; + } + } + ); + } + + // Upon either sending or receiving a Close control frame, it is said + // that _The WebSocket Closing Handshake is Started_ and that the + // WebSocket connection is in the CLOSING state. + this.ws[kReadyState] = states.CLOSING; + this.ws[kReceivedClose] = true; + + return false + } else if (opcode === opcodes.PING) { + // Upon receipt of a Ping frame, an endpoint MUST send a Pong frame in + // response, unless it already received a Close frame. + // A Pong frame sent in response to a Ping frame must have identical + // "Application data" + + if (!this.ws[kReceivedClose]) { + const frame = new WebsocketFrameSend(body); + + this.ws[kResponse].socket.write(frame.createFrame(opcodes.PONG)); + + if (channels.ping.hasSubscribers) { + channels.ping.publish({ + payload: body + }); + } + } + } else if (opcode === opcodes.PONG) { + // A Pong frame MAY be sent unsolicited. This serves as a + // unidirectional heartbeat. A response to an unsolicited Pong frame is + // not expected. + + if (channels.pong.hasSubscribers) { + channels.pong.publish({ + payload: body + }); + } + } + + return true + } + + get closingInfo () { + return this.#info.closeInfo + } + } + + receiver = { + ByteParser + }; + return receiver; +} + +var sender; +var hasRequiredSender; + +function requireSender () { + if (hasRequiredSender) return sender; + hasRequiredSender = 1; + + const { WebsocketFrameSend } = requireFrame(); + const { opcodes, sendHints } = requireConstants(); + const FixedQueue = requireFixedQueue(); + + /** @type {typeof Uint8Array} */ + const FastBuffer = Buffer[Symbol.species]; + + /** + * @typedef {object} SendQueueNode + * @property {Promise | null} promise + * @property {((...args: any[]) => any)} callback + * @property {Buffer | null} frame + */ + + class SendQueue { + /** + * @type {FixedQueue} + */ + #queue = new FixedQueue() + + /** + * @type {boolean} + */ + #running = false + + /** @type {import('node:net').Socket} */ + #socket + + constructor (socket) { + this.#socket = socket; + } + + add (item, cb, hint) { + if (hint !== sendHints.blob) { + const frame = createFrame(item, hint); + if (!this.#running) { + // fast-path + this.#socket.write(frame, cb); + } else { + /** @type {SendQueueNode} */ + const node = { + promise: null, + callback: cb, + frame + }; + this.#queue.push(node); + } + return + } + + /** @type {SendQueueNode} */ + const node = { + promise: item.arrayBuffer().then((ab) => { + node.promise = null; + node.frame = createFrame(ab, hint); + }), + callback: cb, + frame: null + }; + + this.#queue.push(node); + + if (!this.#running) { + this.#run(); + } + } + + async #run () { + this.#running = true; + const queue = this.#queue; + while (!queue.isEmpty()) { + const node = queue.shift(); + // wait pending promise + if (node.promise !== null) { + await node.promise; + } + // write + this.#socket.write(node.frame, node.callback); + // cleanup + node.callback = node.frame = null; + } + this.#running = false; + } + } + + function createFrame (data, hint) { + return new WebsocketFrameSend(toBuffer(data, hint)).createFrame(hint === sendHints.string ? opcodes.TEXT : opcodes.BINARY) + } + + function toBuffer (data, hint) { + switch (hint) { + case sendHints.string: + return Buffer.from(data) + case sendHints.arrayBuffer: + case sendHints.blob: + return new FastBuffer(data) + case sendHints.typedArray: + return new FastBuffer(data.buffer, data.byteOffset, data.byteLength) + } + } + + sender = { SendQueue }; + return sender; +} + +var websocket; +var hasRequiredWebsocket; + +function requireWebsocket () { + if (hasRequiredWebsocket) return websocket; + hasRequiredWebsocket = 1; + + const { webidl } = requireWebidl(); + const { URLSerializer } = requireDataUrl(); + const { environmentSettingsObject } = requireUtil$6(); + const { staticPropertyDescriptors, states, sentCloseFrameState, sendHints } = requireConstants(); + const { + kWebSocketURL, + kReadyState, + kController, + kBinaryType, + kResponse, + kSentClose, + kByteParser + } = requireSymbols(); + const { + isConnecting, + isEstablished, + isClosing, + isValidSubprotocol, + fireEvent + } = requireUtil$1(); + const { establishWebSocketConnection, closeWebSocketConnection } = requireConnection(); + const { ByteParser } = requireReceiver(); + const { kEnumerableProperty, isBlobLike } = requireUtil$7(); + const { getGlobalDispatcher } = requireGlobal(); + const { types } = require$$0$6; + const { ErrorEvent, CloseEvent } = requireEvents(); + const { SendQueue } = requireSender(); + + // https://websockets.spec.whatwg.org/#interface-definition + class WebSocket extends EventTarget { + #events = { + open: null, + error: null, + close: null, + message: null + } + + #bufferedAmount = 0 + #protocol = '' + #extensions = '' + + /** @type {SendQueue} */ + #sendQueue + + /** + * @param {string} url + * @param {string|string[]} protocols + */ + constructor (url, protocols = []) { + super(); + + const prefix = 'WebSocket constructor'; + webidl.argumentLengthCheck(arguments, 1, prefix); + + const options = webidl.converters['DOMString or sequence or WebSocketInit'](protocols, prefix, 'options'); + + url = webidl.converters.USVString(url, prefix, 'url'); + protocols = options.protocols; + + // 1. Let baseURL be this's relevant settings object's API base URL. + const baseURL = environmentSettingsObject.settingsObject.baseUrl; + + // 1. Let urlRecord be the result of applying the URL parser to url with baseURL. + let urlRecord; + + try { + urlRecord = new URL(url, baseURL); + } catch (e) { + // 3. If urlRecord is failure, then throw a "SyntaxError" DOMException. + throw new DOMException(e, 'SyntaxError') + } + + // 4. If urlRecord’s scheme is "http", then set urlRecord’s scheme to "ws". + if (urlRecord.protocol === 'http:') { + urlRecord.protocol = 'ws:'; + } else if (urlRecord.protocol === 'https:') { + // 5. Otherwise, if urlRecord’s scheme is "https", set urlRecord’s scheme to "wss". + urlRecord.protocol = 'wss:'; + } + + // 6. If urlRecord’s scheme is not "ws" or "wss", then throw a "SyntaxError" DOMException. + if (urlRecord.protocol !== 'ws:' && urlRecord.protocol !== 'wss:') { + throw new DOMException( + `Expected a ws: or wss: protocol, got ${urlRecord.protocol}`, + 'SyntaxError' + ) + } + + // 7. If urlRecord’s fragment is non-null, then throw a "SyntaxError" + // DOMException. + if (urlRecord.hash || urlRecord.href.endsWith('#')) { + throw new DOMException('Got fragment', 'SyntaxError') + } + + // 8. If protocols is a string, set protocols to a sequence consisting + // of just that string. + if (typeof protocols === 'string') { + protocols = [protocols]; + } + + // 9. If any of the values in protocols occur more than once or otherwise + // fail to match the requirements for elements that comprise the value + // of `Sec-WebSocket-Protocol` fields as defined by The WebSocket + // protocol, then throw a "SyntaxError" DOMException. + if (protocols.length !== new Set(protocols.map(p => p.toLowerCase())).size) { + throw new DOMException('Invalid Sec-WebSocket-Protocol value', 'SyntaxError') + } + + if (protocols.length > 0 && !protocols.every(p => isValidSubprotocol(p))) { + throw new DOMException('Invalid Sec-WebSocket-Protocol value', 'SyntaxError') + } + + // 10. Set this's url to urlRecord. + this[kWebSocketURL] = new URL(urlRecord.href); + + // 11. Let client be this's relevant settings object. + const client = environmentSettingsObject.settingsObject; + + // 12. Run this step in parallel: + + // 1. Establish a WebSocket connection given urlRecord, protocols, + // and client. + this[kController] = establishWebSocketConnection( + urlRecord, + protocols, + client, + this, + (response, extensions) => this.#onConnectionEstablished(response, extensions), + options + ); + + // Each WebSocket object has an associated ready state, which is a + // number representing the state of the connection. Initially it must + // be CONNECTING (0). + this[kReadyState] = WebSocket.CONNECTING; + + this[kSentClose] = sentCloseFrameState.NOT_SENT; + + // The extensions attribute must initially return the empty string. + + // The protocol attribute must initially return the empty string. + + // Each WebSocket object has an associated binary type, which is a + // BinaryType. Initially it must be "blob". + this[kBinaryType] = 'blob'; + } + + /** + * @see https://websockets.spec.whatwg.org/#dom-websocket-close + * @param {number|undefined} code + * @param {string|undefined} reason + */ + close (code = undefined, reason = undefined) { + webidl.brandCheck(this, WebSocket); + + const prefix = 'WebSocket.close'; + + if (code !== undefined) { + code = webidl.converters['unsigned short'](code, prefix, 'code', { clamp: true }); + } + + if (reason !== undefined) { + reason = webidl.converters.USVString(reason, prefix, 'reason'); + } + + // 1. If code is present, but is neither an integer equal to 1000 nor an + // integer in the range 3000 to 4999, inclusive, throw an + // "InvalidAccessError" DOMException. + if (code !== undefined) { + if (code !== 1000 && (code < 3000 || code > 4999)) { + throw new DOMException('invalid code', 'InvalidAccessError') + } + } + + let reasonByteLength = 0; + + // 2. If reason is present, then run these substeps: + if (reason !== undefined) { + // 1. Let reasonBytes be the result of encoding reason. + // 2. If reasonBytes is longer than 123 bytes, then throw a + // "SyntaxError" DOMException. + reasonByteLength = Buffer.byteLength(reason); + + if (reasonByteLength > 123) { + throw new DOMException( + `Reason must be less than 123 bytes; received ${reasonByteLength}`, + 'SyntaxError' + ) + } + } + + // 3. Run the first matching steps from the following list: + closeWebSocketConnection(this, code, reason, reasonByteLength); + } + + /** + * @see https://websockets.spec.whatwg.org/#dom-websocket-send + * @param {NodeJS.TypedArray|ArrayBuffer|Blob|string} data + */ + send (data) { + webidl.brandCheck(this, WebSocket); + + const prefix = 'WebSocket.send'; + webidl.argumentLengthCheck(arguments, 1, prefix); + + data = webidl.converters.WebSocketSendData(data, prefix, 'data'); + + // 1. If this's ready state is CONNECTING, then throw an + // "InvalidStateError" DOMException. + if (isConnecting(this)) { + throw new DOMException('Sent before connected.', 'InvalidStateError') + } + + // 2. Run the appropriate set of steps from the following list: + // https://datatracker.ietf.org/doc/html/rfc6455#section-6.1 + // https://datatracker.ietf.org/doc/html/rfc6455#section-5.2 + + if (!isEstablished(this) || isClosing(this)) { + return + } + + // If data is a string + if (typeof data === 'string') { + // If the WebSocket connection is established and the WebSocket + // closing handshake has not yet started, then the user agent + // must send a WebSocket Message comprised of the data argument + // using a text frame opcode; if the data cannot be sent, e.g. + // because it would need to be buffered but the buffer is full, + // the user agent must flag the WebSocket as full and then close + // the WebSocket connection. Any invocation of this method with a + // string argument that does not throw an exception must increase + // the bufferedAmount attribute by the number of bytes needed to + // express the argument as UTF-8. + + const length = Buffer.byteLength(data); + + this.#bufferedAmount += length; + this.#sendQueue.add(data, () => { + this.#bufferedAmount -= length; + }, sendHints.string); + } else if (types.isArrayBuffer(data)) { + // If the WebSocket connection is established, and the WebSocket + // closing handshake has not yet started, then the user agent must + // send a WebSocket Message comprised of data using a binary frame + // opcode; if the data cannot be sent, e.g. because it would need + // to be buffered but the buffer is full, the user agent must flag + // the WebSocket as full and then close the WebSocket connection. + // The data to be sent is the data stored in the buffer described + // by the ArrayBuffer object. Any invocation of this method with an + // ArrayBuffer argument that does not throw an exception must + // increase the bufferedAmount attribute by the length of the + // ArrayBuffer in bytes. + + this.#bufferedAmount += data.byteLength; + this.#sendQueue.add(data, () => { + this.#bufferedAmount -= data.byteLength; + }, sendHints.arrayBuffer); + } else if (ArrayBuffer.isView(data)) { + // If the WebSocket connection is established, and the WebSocket + // closing handshake has not yet started, then the user agent must + // send a WebSocket Message comprised of data using a binary frame + // opcode; if the data cannot be sent, e.g. because it would need to + // be buffered but the buffer is full, the user agent must flag the + // WebSocket as full and then close the WebSocket connection. The + // data to be sent is the data stored in the section of the buffer + // described by the ArrayBuffer object that data references. Any + // invocation of this method with this kind of argument that does + // not throw an exception must increase the bufferedAmount attribute + // by the length of data’s buffer in bytes. + + this.#bufferedAmount += data.byteLength; + this.#sendQueue.add(data, () => { + this.#bufferedAmount -= data.byteLength; + }, sendHints.typedArray); + } else if (isBlobLike(data)) { + // If the WebSocket connection is established, and the WebSocket + // closing handshake has not yet started, then the user agent must + // send a WebSocket Message comprised of data using a binary frame + // opcode; if the data cannot be sent, e.g. because it would need to + // be buffered but the buffer is full, the user agent must flag the + // WebSocket as full and then close the WebSocket connection. The data + // to be sent is the raw data represented by the Blob object. Any + // invocation of this method with a Blob argument that does not throw + // an exception must increase the bufferedAmount attribute by the size + // of the Blob object’s raw data, in bytes. + + this.#bufferedAmount += data.size; + this.#sendQueue.add(data, () => { + this.#bufferedAmount -= data.size; + }, sendHints.blob); + } + } + + get readyState () { + webidl.brandCheck(this, WebSocket); + + // The readyState getter steps are to return this's ready state. + return this[kReadyState] + } + + get bufferedAmount () { + webidl.brandCheck(this, WebSocket); + + return this.#bufferedAmount + } + + get url () { + webidl.brandCheck(this, WebSocket); + + // The url getter steps are to return this's url, serialized. + return URLSerializer(this[kWebSocketURL]) + } + + get extensions () { + webidl.brandCheck(this, WebSocket); + + return this.#extensions + } + + get protocol () { + webidl.brandCheck(this, WebSocket); + + return this.#protocol + } + + get onopen () { + webidl.brandCheck(this, WebSocket); + + return this.#events.open + } + + set onopen (fn) { + webidl.brandCheck(this, WebSocket); + + if (this.#events.open) { + this.removeEventListener('open', this.#events.open); + } + + if (typeof fn === 'function') { + this.#events.open = fn; + this.addEventListener('open', fn); + } else { + this.#events.open = null; + } + } + + get onerror () { + webidl.brandCheck(this, WebSocket); + + return this.#events.error + } + + set onerror (fn) { + webidl.brandCheck(this, WebSocket); + + if (this.#events.error) { + this.removeEventListener('error', this.#events.error); + } + + if (typeof fn === 'function') { + this.#events.error = fn; + this.addEventListener('error', fn); + } else { + this.#events.error = null; + } + } + + get onclose () { + webidl.brandCheck(this, WebSocket); + + return this.#events.close + } + + set onclose (fn) { + webidl.brandCheck(this, WebSocket); + + if (this.#events.close) { + this.removeEventListener('close', this.#events.close); + } + + if (typeof fn === 'function') { + this.#events.close = fn; + this.addEventListener('close', fn); + } else { + this.#events.close = null; + } + } + + get onmessage () { + webidl.brandCheck(this, WebSocket); + + return this.#events.message + } + + set onmessage (fn) { + webidl.brandCheck(this, WebSocket); + + if (this.#events.message) { + this.removeEventListener('message', this.#events.message); + } + + if (typeof fn === 'function') { + this.#events.message = fn; + this.addEventListener('message', fn); + } else { + this.#events.message = null; + } + } + + get binaryType () { + webidl.brandCheck(this, WebSocket); + + return this[kBinaryType] + } + + set binaryType (type) { + webidl.brandCheck(this, WebSocket); + + if (type !== 'blob' && type !== 'arraybuffer') { + this[kBinaryType] = 'blob'; + } else { + this[kBinaryType] = type; + } + } + + /** + * @see https://websockets.spec.whatwg.org/#feedback-from-the-protocol + */ + #onConnectionEstablished (response, parsedExtensions) { + // processResponse is called when the "response’s header list has been received and initialized." + // once this happens, the connection is open + this[kResponse] = response; + + const parser = new ByteParser(this, parsedExtensions); + parser.on('drain', onParserDrain); + parser.on('error', onParserError.bind(this)); + + response.socket.ws = this; + this[kByteParser] = parser; + + this.#sendQueue = new SendQueue(response.socket); + + // 1. Change the ready state to OPEN (1). + this[kReadyState] = states.OPEN; + + // 2. Change the extensions attribute’s value to the extensions in use, if + // it is not the null value. + // https://datatracker.ietf.org/doc/html/rfc6455#section-9.1 + const extensions = response.headersList.get('sec-websocket-extensions'); + + if (extensions !== null) { + this.#extensions = extensions; + } + + // 3. Change the protocol attribute’s value to the subprotocol in use, if + // it is not the null value. + // https://datatracker.ietf.org/doc/html/rfc6455#section-1.9 + const protocol = response.headersList.get('sec-websocket-protocol'); + + if (protocol !== null) { + this.#protocol = protocol; + } + + // 4. Fire an event named open at the WebSocket object. + fireEvent('open', this); + } + } + + // https://websockets.spec.whatwg.org/#dom-websocket-connecting + WebSocket.CONNECTING = WebSocket.prototype.CONNECTING = states.CONNECTING; + // https://websockets.spec.whatwg.org/#dom-websocket-open + WebSocket.OPEN = WebSocket.prototype.OPEN = states.OPEN; + // https://websockets.spec.whatwg.org/#dom-websocket-closing + WebSocket.CLOSING = WebSocket.prototype.CLOSING = states.CLOSING; + // https://websockets.spec.whatwg.org/#dom-websocket-closed + WebSocket.CLOSED = WebSocket.prototype.CLOSED = states.CLOSED; + + Object.defineProperties(WebSocket.prototype, { + CONNECTING: staticPropertyDescriptors, + OPEN: staticPropertyDescriptors, + CLOSING: staticPropertyDescriptors, + CLOSED: staticPropertyDescriptors, + url: kEnumerableProperty, + readyState: kEnumerableProperty, + bufferedAmount: kEnumerableProperty, + onopen: kEnumerableProperty, + onerror: kEnumerableProperty, + onclose: kEnumerableProperty, + close: kEnumerableProperty, + onmessage: kEnumerableProperty, + binaryType: kEnumerableProperty, + send: kEnumerableProperty, + extensions: kEnumerableProperty, + protocol: kEnumerableProperty, + [Symbol.toStringTag]: { + value: 'WebSocket', + writable: false, + enumerable: false, + configurable: true + } + }); + + Object.defineProperties(WebSocket, { + CONNECTING: staticPropertyDescriptors, + OPEN: staticPropertyDescriptors, + CLOSING: staticPropertyDescriptors, + CLOSED: staticPropertyDescriptors + }); + + webidl.converters['sequence'] = webidl.sequenceConverter( + webidl.converters.DOMString + ); + + webidl.converters['DOMString or sequence'] = function (V, prefix, argument) { + if (webidl.util.Type(V) === 'Object' && Symbol.iterator in V) { + return webidl.converters['sequence'](V) + } + + return webidl.converters.DOMString(V, prefix, argument) + }; + + // This implements the proposal made in https://github.com/whatwg/websockets/issues/42 + webidl.converters.WebSocketInit = webidl.dictionaryConverter([ + { + key: 'protocols', + converter: webidl.converters['DOMString or sequence'], + defaultValue: () => new Array(0) + }, + { + key: 'dispatcher', + converter: webidl.converters.any, + defaultValue: () => getGlobalDispatcher() + }, + { + key: 'headers', + converter: webidl.nullableConverter(webidl.converters.HeadersInit) + } + ]); + + webidl.converters['DOMString or sequence or WebSocketInit'] = function (V) { + if (webidl.util.Type(V) === 'Object' && !(Symbol.iterator in V)) { + return webidl.converters.WebSocketInit(V) + } + + return { protocols: webidl.converters['DOMString or sequence'](V) } + }; + + webidl.converters.WebSocketSendData = function (V) { + if (webidl.util.Type(V) === 'Object') { + if (isBlobLike(V)) { + return webidl.converters.Blob(V, { strict: false }) + } + + if (ArrayBuffer.isView(V) || types.isArrayBuffer(V)) { + return webidl.converters.BufferSource(V) + } + } + + return webidl.converters.USVString(V) + }; + + function onParserDrain () { + this.ws[kResponse].socket.resume(); + } + + function onParserError (err) { + let message; + let code; + + if (err instanceof CloseEvent) { + message = err.reason; + code = err.code; + } else { + message = err.message; + } + + fireEvent('error', this, () => new ErrorEvent('error', { error: err, message })); + + closeWebSocketConnection(this, code); + } + + websocket = { + WebSocket + }; + return websocket; +} + +var util; +var hasRequiredUtil; + +function requireUtil () { + if (hasRequiredUtil) return util; + hasRequiredUtil = 1; + + /** + * Checks if the given value is a valid LastEventId. + * @param {string} value + * @returns {boolean} + */ + function isValidLastEventId (value) { + // LastEventId should not contain U+0000 NULL + return value.indexOf('\u0000') === -1 + } + + /** + * Checks if the given value is a base 10 digit. + * @param {string} value + * @returns {boolean} + */ + function isASCIINumber (value) { + if (value.length === 0) return false + for (let i = 0; i < value.length; i++) { + if (value.charCodeAt(i) < 0x30 || value.charCodeAt(i) > 0x39) return false + } + return true + } + + // https://github.com/nodejs/undici/issues/2664 + function delay (ms) { + return new Promise((resolve) => { + setTimeout(resolve, ms).unref(); + }) + } + + util = { + isValidLastEventId, + isASCIINumber, + delay + }; + return util; +} + +var eventsourceStream; +var hasRequiredEventsourceStream; + +function requireEventsourceStream () { + if (hasRequiredEventsourceStream) return eventsourceStream; + hasRequiredEventsourceStream = 1; + const { Transform } = require$$0$5; + const { isASCIINumber, isValidLastEventId } = requireUtil(); + + /** + * @type {number[]} BOM + */ + const BOM = [0xEF, 0xBB, 0xBF]; + /** + * @type {10} LF + */ + const LF = 0x0A; + /** + * @type {13} CR + */ + const CR = 0x0D; + /** + * @type {58} COLON + */ + const COLON = 0x3A; + /** + * @type {32} SPACE + */ + const SPACE = 0x20; + + /** + * @typedef {object} EventSourceStreamEvent + * @type {object} + * @property {string} [event] The event type. + * @property {string} [data] The data of the message. + * @property {string} [id] A unique ID for the event. + * @property {string} [retry] The reconnection time, in milliseconds. + */ + + /** + * @typedef eventSourceSettings + * @type {object} + * @property {string} lastEventId The last event ID received from the server. + * @property {string} origin The origin of the event source. + * @property {number} reconnectionTime The reconnection time, in milliseconds. + */ + + class EventSourceStream extends Transform { + /** + * @type {eventSourceSettings} + */ + state = null + + /** + * Leading byte-order-mark check. + * @type {boolean} + */ + checkBOM = true + + /** + * @type {boolean} + */ + crlfCheck = false + + /** + * @type {boolean} + */ + eventEndCheck = false + + /** + * @type {Buffer} + */ + buffer = null + + pos = 0 + + event = { + data: undefined, + event: undefined, + id: undefined, + retry: undefined + } + + /** + * @param {object} options + * @param {eventSourceSettings} options.eventSourceSettings + * @param {Function} [options.push] + */ + constructor (options = {}) { + // Enable object mode as EventSourceStream emits objects of shape + // EventSourceStreamEvent + options.readableObjectMode = true; + + super(options); + + this.state = options.eventSourceSettings || {}; + if (options.push) { + this.push = options.push; + } + } + + /** + * @param {Buffer} chunk + * @param {string} _encoding + * @param {Function} callback + * @returns {void} + */ + _transform (chunk, _encoding, callback) { + if (chunk.length === 0) { + callback(); + return + } + + // Cache the chunk in the buffer, as the data might not be complete while + // processing it + // TODO: Investigate if there is a more performant way to handle + // incoming chunks + // see: https://github.com/nodejs/undici/issues/2630 + if (this.buffer) { + this.buffer = Buffer.concat([this.buffer, chunk]); + } else { + this.buffer = chunk; + } + + // Strip leading byte-order-mark if we opened the stream and started + // the processing of the incoming data + if (this.checkBOM) { + switch (this.buffer.length) { + case 1: + // Check if the first byte is the same as the first byte of the BOM + if (this.buffer[0] === BOM[0]) { + // If it is, we need to wait for more data + callback(); + return + } + // Set the checkBOM flag to false as we don't need to check for the + // BOM anymore + this.checkBOM = false; + + // The buffer only contains one byte so we need to wait for more data + callback(); + return + case 2: + // Check if the first two bytes are the same as the first two bytes + // of the BOM + if ( + this.buffer[0] === BOM[0] && + this.buffer[1] === BOM[1] + ) { + // If it is, we need to wait for more data, because the third byte + // is needed to determine if it is the BOM or not + callback(); + return + } + + // Set the checkBOM flag to false as we don't need to check for the + // BOM anymore + this.checkBOM = false; + break + case 3: + // Check if the first three bytes are the same as the first three + // bytes of the BOM + if ( + this.buffer[0] === BOM[0] && + this.buffer[1] === BOM[1] && + this.buffer[2] === BOM[2] + ) { + // If it is, we can drop the buffered data, as it is only the BOM + this.buffer = Buffer.alloc(0); + // Set the checkBOM flag to false as we don't need to check for the + // BOM anymore + this.checkBOM = false; + + // Await more data + callback(); + return + } + // If it is not the BOM, we can start processing the data + this.checkBOM = false; + break + default: + // The buffer is longer than 3 bytes, so we can drop the BOM if it is + // present + if ( + this.buffer[0] === BOM[0] && + this.buffer[1] === BOM[1] && + this.buffer[2] === BOM[2] + ) { + // Remove the BOM from the buffer + this.buffer = this.buffer.subarray(3); + } + + // Set the checkBOM flag to false as we don't need to check for the + this.checkBOM = false; + break + } + } + + while (this.pos < this.buffer.length) { + // If the previous line ended with an end-of-line, we need to check + // if the next character is also an end-of-line. + if (this.eventEndCheck) { + // If the the current character is an end-of-line, then the event + // is finished and we can process it + + // If the previous line ended with a carriage return, we need to + // check if the current character is a line feed and remove it + // from the buffer. + if (this.crlfCheck) { + // If the current character is a line feed, we can remove it + // from the buffer and reset the crlfCheck flag + if (this.buffer[this.pos] === LF) { + this.buffer = this.buffer.subarray(this.pos + 1); + this.pos = 0; + this.crlfCheck = false; + + // It is possible that the line feed is not the end of the + // event. We need to check if the next character is an + // end-of-line character to determine if the event is + // finished. We simply continue the loop to check the next + // character. + + // As we removed the line feed from the buffer and set the + // crlfCheck flag to false, we basically don't make any + // distinction between a line feed and a carriage return. + continue + } + this.crlfCheck = false; + } + + if (this.buffer[this.pos] === LF || this.buffer[this.pos] === CR) { + // If the current character is a carriage return, we need to + // set the crlfCheck flag to true, as we need to check if the + // next character is a line feed so we can remove it from the + // buffer + if (this.buffer[this.pos] === CR) { + this.crlfCheck = true; + } + + this.buffer = this.buffer.subarray(this.pos + 1); + this.pos = 0; + if ( + this.event.data !== undefined || this.event.event || this.event.id || this.event.retry) { + this.processEvent(this.event); + } + this.clearEvent(); + continue + } + // If the current character is not an end-of-line, then the event + // is not finished and we have to reset the eventEndCheck flag + this.eventEndCheck = false; + continue + } + + // If the current character is an end-of-line, we can process the + // line + if (this.buffer[this.pos] === LF || this.buffer[this.pos] === CR) { + // If the current character is a carriage return, we need to + // set the crlfCheck flag to true, as we need to check if the + // next character is a line feed + if (this.buffer[this.pos] === CR) { + this.crlfCheck = true; + } + + // In any case, we can process the line as we reached an + // end-of-line character + this.parseLine(this.buffer.subarray(0, this.pos), this.event); + + // Remove the processed line from the buffer + this.buffer = this.buffer.subarray(this.pos + 1); + // Reset the position as we removed the processed line from the buffer + this.pos = 0; + // A line was processed and this could be the end of the event. We need + // to check if the next line is empty to determine if the event is + // finished. + this.eventEndCheck = true; + continue + } + + this.pos++; + } + + callback(); + } + + /** + * @param {Buffer} line + * @param {EventStreamEvent} event + */ + parseLine (line, event) { + // If the line is empty (a blank line) + // Dispatch the event, as defined below. + // This will be handled in the _transform method + if (line.length === 0) { + return + } + + // If the line starts with a U+003A COLON character (:) + // Ignore the line. + const colonPosition = line.indexOf(COLON); + if (colonPosition === 0) { + return + } + + let field = ''; + let value = ''; + + // If the line contains a U+003A COLON character (:) + if (colonPosition !== -1) { + // Collect the characters on the line before the first U+003A COLON + // character (:), and let field be that string. + // TODO: Investigate if there is a more performant way to extract the + // field + // see: https://github.com/nodejs/undici/issues/2630 + field = line.subarray(0, colonPosition).toString('utf8'); + + // Collect the characters on the line after the first U+003A COLON + // character (:), and let value be that string. + // If value starts with a U+0020 SPACE character, remove it from value. + let valueStart = colonPosition + 1; + if (line[valueStart] === SPACE) { + ++valueStart; + } + // TODO: Investigate if there is a more performant way to extract the + // value + // see: https://github.com/nodejs/undici/issues/2630 + value = line.subarray(valueStart).toString('utf8'); + + // Otherwise, the string is not empty but does not contain a U+003A COLON + // character (:) + } else { + // Process the field using the steps described below, using the whole + // line as the field name, and the empty string as the field value. + field = line.toString('utf8'); + value = ''; + } + + // Modify the event with the field name and value. The value is also + // decoded as UTF-8 + switch (field) { + case 'data': + if (event[field] === undefined) { + event[field] = value; + } else { + event[field] += `\n${value}`; + } + break + case 'retry': + if (isASCIINumber(value)) { + event[field] = value; + } + break + case 'id': + if (isValidLastEventId(value)) { + event[field] = value; + } + break + case 'event': + if (value.length > 0) { + event[field] = value; + } + break + } + } + + /** + * @param {EventSourceStreamEvent} event + */ + processEvent (event) { + if (event.retry && isASCIINumber(event.retry)) { + this.state.reconnectionTime = parseInt(event.retry, 10); + } + + if (event.id && isValidLastEventId(event.id)) { + this.state.lastEventId = event.id; + } + + // only dispatch event, when data is provided + if (event.data !== undefined) { + this.push({ + type: event.event || 'message', + options: { + data: event.data, + lastEventId: this.state.lastEventId, + origin: this.state.origin + } + }); + } + } + + clearEvent () { + this.event = { + data: undefined, + event: undefined, + id: undefined, + retry: undefined + }; + } + } + + eventsourceStream = { + EventSourceStream + }; + return eventsourceStream; +} + +var eventsource; +var hasRequiredEventsource; + +function requireEventsource () { + if (hasRequiredEventsource) return eventsource; + hasRequiredEventsource = 1; + + const { pipeline } = require$$0$5; + const { fetching } = requireFetch(); + const { makeRequest } = requireRequest(); + const { webidl } = requireWebidl(); + const { EventSourceStream } = requireEventsourceStream(); + const { parseMIMEType } = requireDataUrl(); + const { createFastMessageEvent } = requireEvents(); + const { isNetworkError } = requireResponse(); + const { delay } = requireUtil(); + const { kEnumerableProperty } = requireUtil$7(); + const { environmentSettingsObject } = requireUtil$6(); + + let experimentalWarned = false; + + /** + * A reconnection time, in milliseconds. This must initially be an implementation-defined value, + * probably in the region of a few seconds. + * + * In Comparison: + * - Chrome uses 3000ms. + * - Deno uses 5000ms. + * + * @type {3000} + */ + const defaultReconnectionTime = 3000; + + /** + * The readyState attribute represents the state of the connection. + * @enum + * @readonly + * @see https://html.spec.whatwg.org/multipage/server-sent-events.html#dom-eventsource-readystate-dev + */ + + /** + * The connection has not yet been established, or it was closed and the user + * agent is reconnecting. + * @type {0} + */ + const CONNECTING = 0; + + /** + * The user agent has an open connection and is dispatching events as it + * receives them. + * @type {1} + */ + const OPEN = 1; + + /** + * The connection is not open, and the user agent is not trying to reconnect. + * @type {2} + */ + const CLOSED = 2; + + /** + * Requests for the element will have their mode set to "cors" and their credentials mode set to "same-origin". + * @type {'anonymous'} + */ + const ANONYMOUS = 'anonymous'; + + /** + * Requests for the element will have their mode set to "cors" and their credentials mode set to "include". + * @type {'use-credentials'} + */ + const USE_CREDENTIALS = 'use-credentials'; + + /** + * The EventSource interface is used to receive server-sent events. It + * connects to a server over HTTP and receives events in text/event-stream + * format without closing the connection. + * @extends {EventTarget} + * @see https://html.spec.whatwg.org/multipage/server-sent-events.html#server-sent-events + * @api public + */ + class EventSource extends EventTarget { + #events = { + open: null, + error: null, + message: null + } + + #url = null + #withCredentials = false + + #readyState = CONNECTING + + #request = null + #controller = null + + #dispatcher + + /** + * @type {import('./eventsource-stream').eventSourceSettings} + */ + #state + + /** + * Creates a new EventSource object. + * @param {string} url + * @param {EventSourceInit} [eventSourceInitDict] + * @see https://html.spec.whatwg.org/multipage/server-sent-events.html#the-eventsource-interface + */ + constructor (url, eventSourceInitDict = {}) { + // 1. Let ev be a new EventSource object. + super(); + + const prefix = 'EventSource constructor'; + webidl.argumentLengthCheck(arguments, 1, prefix); + + if (!experimentalWarned) { + experimentalWarned = true; + process.emitWarning('EventSource is experimental, expect them to change at any time.', { + code: 'UNDICI-ES' + }); + } + + url = webidl.converters.USVString(url, prefix, 'url'); + eventSourceInitDict = webidl.converters.EventSourceInitDict(eventSourceInitDict, prefix, 'eventSourceInitDict'); + + this.#dispatcher = eventSourceInitDict.dispatcher; + this.#state = { + lastEventId: '', + reconnectionTime: defaultReconnectionTime + }; + + // 2. Let settings be ev's relevant settings object. + // https://html.spec.whatwg.org/multipage/webappapis.html#environment-settings-object + const settings = environmentSettingsObject; + + let urlRecord; + + try { + // 3. Let urlRecord be the result of encoding-parsing a URL given url, relative to settings. + urlRecord = new URL(url, settings.settingsObject.baseUrl); + this.#state.origin = urlRecord.origin; + } catch (e) { + // 4. If urlRecord is failure, then throw a "SyntaxError" DOMException. + throw new DOMException(e, 'SyntaxError') + } + + // 5. Set ev's url to urlRecord. + this.#url = urlRecord.href; + + // 6. Let corsAttributeState be Anonymous. + let corsAttributeState = ANONYMOUS; + + // 7. If the value of eventSourceInitDict's withCredentials member is true, + // then set corsAttributeState to Use Credentials and set ev's + // withCredentials attribute to true. + if (eventSourceInitDict.withCredentials) { + corsAttributeState = USE_CREDENTIALS; + this.#withCredentials = true; + } + + // 8. Let request be the result of creating a potential-CORS request given + // urlRecord, the empty string, and corsAttributeState. + const initRequest = { + redirect: 'follow', + keepalive: true, + // @see https://html.spec.whatwg.org/multipage/urls-and-fetching.html#cors-settings-attributes + mode: 'cors', + credentials: corsAttributeState === 'anonymous' + ? 'same-origin' + : 'omit', + referrer: 'no-referrer' + }; + + // 9. Set request's client to settings. + initRequest.client = environmentSettingsObject.settingsObject; + + // 10. User agents may set (`Accept`, `text/event-stream`) in request's header list. + initRequest.headersList = [['accept', { name: 'accept', value: 'text/event-stream' }]]; + + // 11. Set request's cache mode to "no-store". + initRequest.cache = 'no-store'; + + // 12. Set request's initiator type to "other". + initRequest.initiator = 'other'; + + initRequest.urlList = [new URL(this.#url)]; + + // 13. Set ev's request to request. + this.#request = makeRequest(initRequest); + + this.#connect(); + } + + /** + * Returns the state of this EventSource object's connection. It can have the + * values described below. + * @returns {0|1|2} + * @readonly + */ + get readyState () { + return this.#readyState + } + + /** + * Returns the URL providing the event stream. + * @readonly + * @returns {string} + */ + get url () { + return this.#url + } + + /** + * Returns a boolean indicating whether the EventSource object was + * instantiated with CORS credentials set (true), or not (false, the default). + */ + get withCredentials () { + return this.#withCredentials + } + + #connect () { + if (this.#readyState === CLOSED) return + + this.#readyState = CONNECTING; + + const fetchParams = { + request: this.#request, + dispatcher: this.#dispatcher + }; + + // 14. Let processEventSourceEndOfBody given response res be the following step: if res is not a network error, then reestablish the connection. + const processEventSourceEndOfBody = (response) => { + if (isNetworkError(response)) { + this.dispatchEvent(new Event('error')); + this.close(); + } + + this.#reconnect(); + }; + + // 15. Fetch request, with processResponseEndOfBody set to processEventSourceEndOfBody... + fetchParams.processResponseEndOfBody = processEventSourceEndOfBody; + + // and processResponse set to the following steps given response res: + fetchParams.processResponse = (response) => { + // 1. If res is an aborted network error, then fail the connection. + + if (isNetworkError(response)) { + // 1. When a user agent is to fail the connection, the user agent + // must queue a task which, if the readyState attribute is set to a + // value other than CLOSED, sets the readyState attribute to CLOSED + // and fires an event named error at the EventSource object. Once the + // user agent has failed the connection, it does not attempt to + // reconnect. + if (response.aborted) { + this.close(); + this.dispatchEvent(new Event('error')); + return + // 2. Otherwise, if res is a network error, then reestablish the + // connection, unless the user agent knows that to be futile, in + // which case the user agent may fail the connection. + } else { + this.#reconnect(); + return + } + } + + // 3. Otherwise, if res's status is not 200, or if res's `Content-Type` + // is not `text/event-stream`, then fail the connection. + const contentType = response.headersList.get('content-type', true); + const mimeType = contentType !== null ? parseMIMEType(contentType) : 'failure'; + const contentTypeValid = mimeType !== 'failure' && mimeType.essence === 'text/event-stream'; + if ( + response.status !== 200 || + contentTypeValid === false + ) { + this.close(); + this.dispatchEvent(new Event('error')); + return + } + + // 4. Otherwise, announce the connection and interpret res's body + // line by line. + + // When a user agent is to announce the connection, the user agent + // must queue a task which, if the readyState attribute is set to a + // value other than CLOSED, sets the readyState attribute to OPEN + // and fires an event named open at the EventSource object. + // @see https://html.spec.whatwg.org/multipage/server-sent-events.html#sse-processing-model + this.#readyState = OPEN; + this.dispatchEvent(new Event('open')); + + // If redirected to a different origin, set the origin to the new origin. + this.#state.origin = response.urlList[response.urlList.length - 1].origin; + + const eventSourceStream = new EventSourceStream({ + eventSourceSettings: this.#state, + push: (event) => { + this.dispatchEvent(createFastMessageEvent( + event.type, + event.options + )); + } + }); + + pipeline(response.body.stream, + eventSourceStream, + (error) => { + if ( + error?.aborted === false + ) { + this.close(); + this.dispatchEvent(new Event('error')); + } + }); + }; + + this.#controller = fetching(fetchParams); + } + + /** + * @see https://html.spec.whatwg.org/multipage/server-sent-events.html#sse-processing-model + * @returns {Promise} + */ + async #reconnect () { + // When a user agent is to reestablish the connection, the user agent must + // run the following steps. These steps are run in parallel, not as part of + // a task. (The tasks that it queues, of course, are run like normal tasks + // and not themselves in parallel.) + + // 1. Queue a task to run the following steps: + + // 1. If the readyState attribute is set to CLOSED, abort the task. + if (this.#readyState === CLOSED) return + + // 2. Set the readyState attribute to CONNECTING. + this.#readyState = CONNECTING; + + // 3. Fire an event named error at the EventSource object. + this.dispatchEvent(new Event('error')); + + // 2. Wait a delay equal to the reconnection time of the event source. + await delay(this.#state.reconnectionTime); + + // 5. Queue a task to run the following steps: + + // 1. If the EventSource object's readyState attribute is not set to + // CONNECTING, then return. + if (this.#readyState !== CONNECTING) return + + // 2. Let request be the EventSource object's request. + // 3. If the EventSource object's last event ID string is not the empty + // string, then: + // 1. Let lastEventIDValue be the EventSource object's last event ID + // string, encoded as UTF-8. + // 2. Set (`Last-Event-ID`, lastEventIDValue) in request's header + // list. + if (this.#state.lastEventId.length) { + this.#request.headersList.set('last-event-id', this.#state.lastEventId, true); + } + + // 4. Fetch request and process the response obtained in this fashion, if any, as described earlier in this section. + this.#connect(); + } + + /** + * Closes the connection, if any, and sets the readyState attribute to + * CLOSED. + */ + close () { + webidl.brandCheck(this, EventSource); + + if (this.#readyState === CLOSED) return + this.#readyState = CLOSED; + this.#controller.abort(); + this.#request = null; + } + + get onopen () { + return this.#events.open + } + + set onopen (fn) { + if (this.#events.open) { + this.removeEventListener('open', this.#events.open); + } + + if (typeof fn === 'function') { + this.#events.open = fn; + this.addEventListener('open', fn); + } else { + this.#events.open = null; + } + } + + get onmessage () { + return this.#events.message + } + + set onmessage (fn) { + if (this.#events.message) { + this.removeEventListener('message', this.#events.message); + } + + if (typeof fn === 'function') { + this.#events.message = fn; + this.addEventListener('message', fn); + } else { + this.#events.message = null; + } + } + + get onerror () { + return this.#events.error + } + + set onerror (fn) { + if (this.#events.error) { + this.removeEventListener('error', this.#events.error); + } + + if (typeof fn === 'function') { + this.#events.error = fn; + this.addEventListener('error', fn); + } else { + this.#events.error = null; + } + } + } + + const constantsPropertyDescriptors = { + CONNECTING: { + __proto__: null, + configurable: false, + enumerable: true, + value: CONNECTING, + writable: false + }, + OPEN: { + __proto__: null, + configurable: false, + enumerable: true, + value: OPEN, + writable: false + }, + CLOSED: { + __proto__: null, + configurable: false, + enumerable: true, + value: CLOSED, + writable: false + } + }; + + Object.defineProperties(EventSource, constantsPropertyDescriptors); + Object.defineProperties(EventSource.prototype, constantsPropertyDescriptors); + + Object.defineProperties(EventSource.prototype, { + close: kEnumerableProperty, + onerror: kEnumerableProperty, + onmessage: kEnumerableProperty, + onopen: kEnumerableProperty, + readyState: kEnumerableProperty, + url: kEnumerableProperty, + withCredentials: kEnumerableProperty + }); + + webidl.converters.EventSourceInitDict = webidl.dictionaryConverter([ + { + key: 'withCredentials', + converter: webidl.converters.boolean, + defaultValue: () => false + }, + { + key: 'dispatcher', // undici only + converter: webidl.converters.any + } + ]); + + eventsource = { + EventSource, + defaultReconnectionTime + }; + return eventsource; +} + +var hasRequiredUndici; + +function requireUndici () { + if (hasRequiredUndici) return undici; + hasRequiredUndici = 1; + + const Client = requireClient(); + const Dispatcher = requireDispatcher(); + const Pool = requirePool(); + const BalancedPool = requireBalancedPool(); + const Agent = requireAgent(); + const ProxyAgent = requireProxyAgent(); + const EnvHttpProxyAgent = requireEnvHttpProxyAgent(); + const RetryAgent = requireRetryAgent(); + const errors = requireErrors(); + const util = requireUtil$7(); + const { InvalidArgumentError } = errors; + const api = requireApi(); + const buildConnector = requireConnect(); + const MockClient = requireMockClient(); + const MockAgent = requireMockAgent(); + const MockPool = requireMockPool(); + const mockErrors = requireMockErrors(); + const RetryHandler = requireRetryHandler(); + const { getGlobalDispatcher, setGlobalDispatcher } = requireGlobal(); + const DecoratorHandler = requireDecoratorHandler(); + const RedirectHandler = requireRedirectHandler(); + const createRedirectInterceptor = requireRedirectInterceptor(); + + Object.assign(Dispatcher.prototype, api); + + undici.Dispatcher = Dispatcher; + undici.Client = Client; + undici.Pool = Pool; + undici.BalancedPool = BalancedPool; + undici.Agent = Agent; + undici.ProxyAgent = ProxyAgent; + undici.EnvHttpProxyAgent = EnvHttpProxyAgent; + undici.RetryAgent = RetryAgent; + undici.RetryHandler = RetryHandler; + + undici.DecoratorHandler = DecoratorHandler; + undici.RedirectHandler = RedirectHandler; + undici.createRedirectInterceptor = createRedirectInterceptor; + undici.interceptors = { + redirect: requireRedirect(), + retry: requireRetry(), + dump: requireDump() + }; + + undici.buildConnector = buildConnector; + undici.errors = errors; + undici.util = { + parseHeaders: util.parseHeaders, + headerNameToString: util.headerNameToString + }; + + function makeDispatcher (fn) { + return (url, opts, handler) => { + if (typeof opts === 'function') { + handler = opts; + opts = null; + } + + if (!url || (typeof url !== 'string' && typeof url !== 'object' && !(url instanceof URL))) { + throw new InvalidArgumentError('invalid url') + } + + if (opts != null && typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') + } + + if (opts && opts.path != null) { + if (typeof opts.path !== 'string') { + throw new InvalidArgumentError('invalid opts.path') + } + + let path = opts.path; + if (!opts.path.startsWith('/')) { + path = `/${path}`; + } + + url = new URL(util.parseOrigin(url).origin + path); + } else { + if (!opts) { + opts = typeof url === 'object' ? url : {}; + } + + url = util.parseURL(url); + } + + const { agent, dispatcher = getGlobalDispatcher() } = opts; + + if (agent) { + throw new InvalidArgumentError('unsupported opts.agent. Did you mean opts.client?') + } + + return fn.call(dispatcher, { + ...opts, + origin: url.origin, + path: url.search ? `${url.pathname}${url.search}` : url.pathname, + method: opts.method || (opts.body ? 'PUT' : 'GET') + }, handler) + } + } + + undici.setGlobalDispatcher = setGlobalDispatcher; + undici.getGlobalDispatcher = getGlobalDispatcher; + + const fetchImpl = requireFetch().fetch; + undici.fetch = async function fetch (init, options = undefined) { + try { + return await fetchImpl(init, options) + } catch (err) { + if (err && typeof err === 'object') { + Error.captureStackTrace(err); + } + + throw err + } + }; + undici.Headers = requireHeaders().Headers; + undici.Response = requireResponse().Response; + undici.Request = requireRequest().Request; + undici.FormData = requireFormdata().FormData; + undici.File = globalThis.File ?? require$$0$3.File; + undici.FileReader = requireFilereader().FileReader; + + const { setGlobalOrigin, getGlobalOrigin } = requireGlobal$1(); + + undici.setGlobalOrigin = setGlobalOrigin; + undici.getGlobalOrigin = getGlobalOrigin; + + const { CacheStorage } = requireCachestorage(); + const { kConstruct } = requireSymbols$1(); + + // Cache & CacheStorage are tightly coupled with fetch. Even if it may run + // in an older version of Node, it doesn't have any use without fetch. + undici.caches = new CacheStorage(kConstruct); + + const { deleteCookie, getCookies, getSetCookies, setCookie } = requireCookies(); + + undici.deleteCookie = deleteCookie; + undici.getCookies = getCookies; + undici.getSetCookies = getSetCookies; + undici.setCookie = setCookie; + + const { parseMIMEType, serializeAMimeType } = requireDataUrl(); + + undici.parseMIMEType = parseMIMEType; + undici.serializeAMimeType = serializeAMimeType; + + const { CloseEvent, ErrorEvent, MessageEvent } = requireEvents(); + undici.WebSocket = requireWebsocket().WebSocket; + undici.CloseEvent = CloseEvent; + undici.ErrorEvent = ErrorEvent; + undici.MessageEvent = MessageEvent; + + undici.request = makeDispatcher(api.request); + undici.stream = makeDispatcher(api.stream); + undici.pipeline = makeDispatcher(api.pipeline); + undici.connect = makeDispatcher(api.connect); + undici.upgrade = makeDispatcher(api.upgrade); + + undici.MockClient = MockClient; + undici.MockPool = MockPool; + undici.MockAgent = MockAgent; + undici.mockErrors = mockErrors; + + const { EventSource } = requireEventsource(); + + undici.EventSource = EventSource; + return undici; +} + +var undiciExports = requireUndici(); + +// For local queue, there is no technical limit on the message visibility lifespan, +// but the environment variable can be used for testing purposes to set a max visibility limit. +const LOCAL_QUEUE_MAX_VISIBILITY = parseInt(process.env.WORKFLOW_LOCAL_QUEUE_MAX_VISIBILITY ?? "0", 10) || + Infinity; +// Create a custom agent with unlimited headers timeout for long-running steps +const httpAgent = new undiciExports.Agent({ + headersTimeout: 0, +}); +function createQueue$1(port) { + const transport = new JsonTransport$1(); + const generateId = monotonicFactory(); + /** + * holds inflight messages by idempotency key to ensure + * that we don't queue the same message multiple times + */ + const inflightMessages = new Map(); + const queue = async (queueName, message, opts) => { + const cleanup = []; + if (opts?.idempotencyKey) { + const existing = inflightMessages.get(opts.idempotencyKey); + if (existing) { + return { messageId: existing }; + } + } + const body = transport.serialize(message); + let pathname; + if (queueName.startsWith("__wkf_step_")) { + pathname = `step`; + } + else if (queueName.startsWith("__wkf_workflow_")) { + pathname = `flow`; + } + else { + throw new Error("Unknown queue name prefix"); + } + const messageId = MessageId.parse(`msg_${generateId()}`); + if (opts?.idempotencyKey) { + const key = opts.idempotencyKey; + inflightMessages.set(key, messageId); + cleanup.push(() => { + inflightMessages.delete(key); + }); + } + (async () => { + let defaultRetriesLeft = 3; + const portToUse = port ?? (await getPort()); + for (let attempt = 0; defaultRetriesLeft > 0; attempt++) { + defaultRetriesLeft--; + const response = await fetch(`http://localhost:${portToUse}/.well-known/workflow/v1/${pathname}`, { + method: "POST", + duplex: "half", + // @ts-expect-error undici type differences + dispatcher: httpAgent, + headers: { + "content-type": "application/json", + "x-vqs-queue-name": queueName, + "x-vqs-message-id": messageId, + "x-vqs-message-attempt": String(attempt + 1), + }, + body, + }); + if (response.ok) { + return; + } + const text = await response.text(); + if (response.status === 503) { + try { + const timeoutSeconds = Number(JSON.parse(text).timeoutSeconds); + await setTimeout$1(timeoutSeconds * 1000); + defaultRetriesLeft++; + continue; + } + catch { } + } + console.error(`[embedded world] Failed to queue message`, { + queueName, + text, + status: response.status, + headers: Object.fromEntries(response.headers.entries()), + body: body.toString(), + }); + } + console.error(`[embedded world] Reached max retries of embedded world queue implementation`); + })().finally(() => { + for (const fn of cleanup) { + fn(); + } + }); + return { messageId }; + }; + const HeaderParser = z__default.object({ + "x-vqs-queue-name": ValidQueueName, + "x-vqs-message-id": MessageId, + "x-vqs-message-attempt": z__default.coerce.number(), + }); + const createQueueHandler = (prefix, handler) => { + return async (req) => { + const headers = HeaderParser.safeParse(Object.fromEntries(req.headers)); + if (!headers.success || !req.body) { + console.log(!headers.success); + console.log(!req.body); + return Response.json({ + error: !req.body + ? "Missing request body" + : "Missing required headers", + }, { status: 400 }); + } + const queueName = headers.data["x-vqs-queue-name"]; + const messageId = headers.data["x-vqs-message-id"]; + const attempt = headers.data["x-vqs-message-attempt"]; + if (!queueName.startsWith(prefix)) { + return Response.json({ error: "Unhandled queue" }, { status: 400 }); + } + const body = await new JsonTransport$1().deserialize(req.body); + try { + const result = await handler(body, { attempt, queueName, messageId }); + let timeoutSeconds = null; + if (typeof result?.timeoutSeconds === "number") { + timeoutSeconds = Math.min(result.timeoutSeconds, LOCAL_QUEUE_MAX_VISIBILITY); + } + if (timeoutSeconds) { + return Response.json({ timeoutSeconds }, { status: 503 }); + } + return Response.json({ ok: true }); + } + catch (error) { + return Response.json(String(error), { status: 500 }); + } + }; + }; + const getDeploymentId = async () => { + return "dpl_embedded"; + }; + return { queue, createQueueHandler, getDeploymentId }; +} + +const ulid = monotonicFactory(() => Math.random()); +const Ulid = z$1.string().ulid(); +function ulidToDate(maybeUlid) { + const ulid = Ulid.safeParse(maybeUlid); + if (!ulid.success) { + return null; + } + return new Date(decodeTime(ulid.data)); +} +async function ensureDir(dirPath) { + try { + await promises.mkdir(dirPath, { recursive: true }); + } + catch (_error) { + // Ignore if already exists + } +} +async function writeJSON(filePath, data, opts) { + return write(filePath, JSON.stringify(data, null, 2), opts); +} +async function write(filePath, data, opts) { + if (!opts?.overwrite) { + try { + await promises.access(filePath); + throw new WorkflowAPIError(`File ${filePath} already exists and 'overwrite' is false`, { status: 409 }); + } + catch (error) { + // If file doesn't exist (ENOENT), continue with write + if (error.code !== 'ENOENT') { + throw error; + } + } + } + const tempPath = `${filePath}.tmp.${ulid()}`; + try { + await ensureDir(path.dirname(filePath)); + await promises.writeFile(tempPath, data); + await promises.rename(tempPath, filePath); + } + catch (error) { + await promises.unlink(tempPath).catch(() => { }); + throw error; + } +} +async function readJSON(filePath, decoder) { + try { + const content = await promises.readFile(filePath, 'utf-8'); + return decoder.parse(JSON.parse(content)); + } + catch (error) { + if (error.code === 'ENOENT') + return null; + throw error; + } +} +async function readBuffer(filePath) { + const content = await promises.readFile(filePath); + return content; +} +async function deleteJSON(filePath) { + try { + await promises.unlink(filePath); + } + catch (error) { + if (error.code !== 'ENOENT') + throw error; + } +} +async function listJSONFiles(dirPath) { + try { + const files = await promises.readdir(dirPath); + return files + .filter((f) => f.endsWith('.json')) + .map((f) => f.replace('.json', '')); + } + catch (error) { + if (error.code === 'ENOENT') + return []; + throw error; + } +} +function parseCursor(cursor) { + if (!cursor) + return null; + const parts = cursor.split('|'); + return { + timestamp: new Date(parts[0]), + id: parts[1] || null, + }; +} +function createCursor(timestamp, id) { + return id ? `${timestamp.toISOString()}|${id}` : timestamp.toISOString(); +} +async function paginatedFileSystemQuery(config) { + const { directory, schema, filePrefix, filter, sortOrder = 'desc', limit = 20, cursor, getCreatedAt, getId, } = config; + // 1. Get all JSON files in directory + const fileIds = await listJSONFiles(directory); + // 2. Filter by prefix if provided + const relevantFileIds = filePrefix + ? fileIds.filter((fileId) => fileId.startsWith(filePrefix)) + : fileIds; + // 3. ULID Optimization: Filter by cursor using filename timestamps before loading JSON + const parsedCursor = parseCursor(cursor); + let candidateFileIds = relevantFileIds; + if (parsedCursor) { + candidateFileIds = relevantFileIds.filter((fileId) => { + const filenameDate = getCreatedAt(`${fileId}.json`); + if (filenameDate) { + // Use filename timestamp for cursor filtering + // We need to be careful here: if parsedCursor has an ID (for tie-breaking), + // we need to include items with the same timestamp for later ID-based filtering. + // If no ID, we can use strict inequality for optimization. + const cursorTime = parsedCursor.timestamp.getTime(); + const fileTime = filenameDate.getTime(); + if (parsedCursor.id) { + // Tie-breaking mode: include items at or near cursor timestamp + return sortOrder === 'desc' + ? fileTime <= cursorTime + : fileTime >= cursorTime; + } + else { + // No tie-breaking: strict inequality + return sortOrder === 'desc' + ? fileTime < cursorTime + : fileTime > cursorTime; + } + } + // Skip files where we can't extract timestamp - no optimization benefit + return false; + }); + } + else { + // Even without cursor, skip files where getCreatedAt returns null for consistency + candidateFileIds = relevantFileIds.filter((fileId) => { + return getCreatedAt(`${fileId}.json`) !== null; + }); + } + // 4. Load files individually and collect valid items + const validItems = []; + for (const fileId of candidateFileIds) { + const filePath = path.join(directory, `${fileId}.json`); + const item = await readJSON(filePath, schema); + if (item) { + // Apply custom filter early if provided + if (filter && !filter(item)) + continue; + // Double-check cursor filtering with actual createdAt from JSON + // (in case ULID timestamp differs from stored createdAt) + if (parsedCursor) { + const itemTime = item.createdAt.getTime(); + const cursorTime = parsedCursor.timestamp.getTime(); + if (sortOrder === 'desc') { + // For descending order, skip items >= cursor + if (itemTime > cursorTime) + continue; + // If timestamps are equal, use ID for tie-breaking (skip if ID >= cursorId) + if (itemTime === cursorTime && parsedCursor.id && getId) { + const itemId = getId(item); + if (itemId >= parsedCursor.id) + continue; + } + } + else { + // For ascending order, skip items <= cursor + if (itemTime < cursorTime) + continue; + // If timestamps are equal, use ID for tie-breaking (skip if ID <= cursorId) + if (itemTime === cursorTime && parsedCursor.id && getId) { + const itemId = getId(item); + if (itemId <= parsedCursor.id) + continue; + } + } + } + validItems.push(item); + } + } + // 5. Sort by createdAt (and by ID for tie-breaking if getId is provided) + validItems.sort((a, b) => { + const aTime = a.createdAt.getTime(); + const bTime = b.createdAt.getTime(); + const timeComparison = sortOrder === 'asc' ? aTime - bTime : bTime - aTime; + // If timestamps are equal and we have getId, use ID for stable sorting + if (timeComparison === 0 && getId) { + const aId = getId(a); + const bId = getId(b); + return sortOrder === 'asc' + ? aId.localeCompare(bId) + : bId.localeCompare(aId); + } + return timeComparison; + }); + // 6. Apply pagination + const hasMore = validItems.length > limit; + const items = hasMore ? validItems.slice(0, limit) : validItems; + const nextCursor = items.length > 0 + ? createCursor(items[items.length - 1].createdAt, getId?.(items[items.length - 1])) + : null; + return { + data: items, + cursor: nextCursor, + hasMore, + }; +} + +// Create a monotonic ULID factory that ensures ULIDs are always increasing +// even when generated within the same millisecond +const monotonicUlid$1 = monotonicFactory(() => Math.random()); +// Helper functions to filter data based on resolveData setting +function filterRunData$1(run, resolveData) { + if (resolveData === 'none') { + return { + ...run, + input: [], + output: undefined, + }; + } + return run; +} +function filterStepData$1(step, resolveData) { + if (resolveData === 'none') { + return { + ...step, + input: [], + output: undefined, + }; + } + return step; +} +function filterEventData$1(event, resolveData) { + if (resolveData === 'none') { + const { eventData: _eventData, ...rest } = event; + return rest; + } + return event; +} +function filterHookData$1(hook, resolveData) { + if (resolveData === 'none') { + const { metadata: _metadata, ...rest } = hook; + return rest; + } + return hook; +} +const getObjectCreatedAt = (idPrefix) => (filename) => { + const replaceRegex = new RegExp(`^${idPrefix}_`, 'g'); + const dashIndex = filename.indexOf('-'); + if (dashIndex === -1) { + // No dash - extract ULID from the filename (e.g., wrun_ULID.json, evnt_ULID.json) + const ulid = filename.replace(/\.json$/, '').replace(replaceRegex, ''); + return ulidToDate(ulid); + } + // For composite keys like {runId}-{stepId}, extract from the appropriate part + if (idPrefix === 'step') { + // For steps: wrun_ULID-step_123.json - extract from the runId part + const runId = filename.substring(0, dashIndex); + const ulid = runId.replace(/^wrun_/, ''); + return ulidToDate(ulid); + } + // For events: wrun_ULID-evnt_ULID.json - extract from the eventId part + const id = filename.substring(dashIndex + 1).replace(/\.json$/, ''); + const ulid = id.replace(replaceRegex, ''); + return ulidToDate(ulid); +}; +/** + * Creates a hooks storage implementation using the filesystem. + * Implements the Storage['hooks'] interface with hook CRUD operations. + */ +function createHooksStorage(basedir) { + // Helper function to find a hook by token (shared between create and getByToken) + async function findHookByToken(token) { + const hooksDir = path.join(basedir, 'hooks'); + const files = await listJSONFiles(hooksDir); + for (const file of files) { + const hookPath = path.join(hooksDir, `${file}.json`); + const hook = await readJSON(hookPath, HookSchema); + if (hook && hook.token === token) { + return hook; + } + } + return null; + } + async function create(runId, data) { + // Check if a hook with the same token already exists + // Token uniqueness is enforced globally per embedded environment + const existingHook = await findHookByToken(data.token); + if (existingHook) { + throw new Error(`Hook with token ${data.token} already exists for this project`); + } + const now = new Date(); + const result = { + runId, + hookId: data.hookId, + token: data.token, + metadata: data.metadata, + ownerId: 'embedded-owner', + projectId: 'embedded-project', + environment: 'embedded', + createdAt: now, + }; + const hookPath = path.join(basedir, 'hooks', `${data.hookId}.json`); + await writeJSON(hookPath, result); + return result; + } + async function get(hookId, params) { + const hookPath = path.join(basedir, 'hooks', `${hookId}.json`); + const hook = await readJSON(hookPath, HookSchema); + if (!hook) { + throw new Error(`Hook ${hookId} not found`); + } + const resolveData = params?.resolveData || DEFAULT_RESOLVE_DATA_OPTION$1; + return filterHookData$1(hook, resolveData); + } + async function getByToken(token) { + const hook = await findHookByToken(token); + if (!hook) { + throw new Error(`Hook with token ${token} not found`); + } + return hook; + } + async function list(params) { + const hooksDir = path.join(basedir, 'hooks'); + const resolveData = params.resolveData || DEFAULT_RESOLVE_DATA_OPTION$1; + const result = await paginatedFileSystemQuery({ + directory: hooksDir, + schema: HookSchema, + sortOrder: params.pagination?.sortOrder, + limit: params.pagination?.limit, + cursor: params.pagination?.cursor, + filePrefix: undefined, // Hooks don't have ULIDs, so we can't optimize by filename + filter: (hook) => { + // Filter by runId if provided + if (params.runId && hook.runId !== params.runId) { + return false; + } + return true; + }, + getCreatedAt: () => { + // Hook files don't have ULID timestamps in filename + // We need to read the file to get createdAt, but that's inefficient + // So we return the hook's createdAt directly (item.createdAt will be used for sorting) + // Return a dummy date to pass the null check, actual sorting uses item.createdAt + return new Date(0); + }, + getId: (hook) => hook.hookId, + }); + // Transform the data after pagination + return { + ...result, + data: result.data.map((hook) => filterHookData$1(hook, resolveData)), + }; + } + async function dispose(hookId) { + const hookPath = path.join(basedir, 'hooks', `${hookId}.json`); + const hook = await readJSON(hookPath, HookSchema); + if (!hook) { + throw new Error(`Hook ${hookId} not found`); + } + await deleteJSON(hookPath); + return hook; + } + return { create, get, getByToken, list, dispose }; +} +/** + * Helper function to delete all hooks associated with a workflow run + */ +async function deleteAllHooksForRun(basedir, runId) { + const hooksDir = path.join(basedir, 'hooks'); + const files = await listJSONFiles(hooksDir); + for (const file of files) { + const hookPath = path.join(hooksDir, `${file}.json`); + const hook = await readJSON(hookPath, HookSchema); + if (hook && hook.runId === runId) { + await deleteJSON(hookPath); + } + } +} +function createStorage$1(basedir) { + return { + runs: { + async create(data) { + const runId = `wrun_${monotonicUlid$1()}`; + const now = new Date(); + const result = { + runId, + deploymentId: data.deploymentId, + status: 'pending', + workflowName: data.workflowName, + executionContext: data.executionContext, + input: data.input || [], + output: undefined, + error: undefined, + startedAt: undefined, + completedAt: undefined, + createdAt: now, + updatedAt: now, + }; + const runPath = path.join(basedir, 'runs', `${runId}.json`); + await writeJSON(runPath, result); + return result; + }, + async get(id, params) { + const runPath = path.join(basedir, 'runs', `${id}.json`); + const run = await readJSON(runPath, WorkflowRunSchema); + if (!run) { + throw new WorkflowRunNotFoundError(id); + } + const resolveData = params?.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION$1; + return filterRunData$1(run, resolveData); + }, + async update(id, data) { + const runPath = path.join(basedir, 'runs', `${id}.json`); + const run = await readJSON(runPath, WorkflowRunSchema); + if (!run) { + throw new WorkflowRunNotFoundError(id); + } + const now = new Date(); + const updatedRun = { + ...run, + ...data, + updatedAt: now, + }; + // Only set startedAt the first time the run transitions to 'running' + if (data.status === 'running' && !updatedRun.startedAt) { + updatedRun.startedAt = now; + } + const isBecomingTerminal = data.status === 'completed' || + data.status === 'failed' || + data.status === 'cancelled'; + if (isBecomingTerminal) { + updatedRun.completedAt = now; + } + await writeJSON(runPath, updatedRun, { overwrite: true }); + // If transitioning to a terminal status, clean up all hooks for this run + if (isBecomingTerminal) { + await deleteAllHooksForRun(basedir, id); + } + return updatedRun; + }, + async list(params) { + const resolveData = params?.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION$1; + const result = await paginatedFileSystemQuery({ + directory: path.join(basedir, 'runs'), + schema: WorkflowRunSchema, + filter: (run) => { + if (params?.workflowName && + run.workflowName !== params.workflowName) { + return false; + } + if (params?.status && run.status !== params.status) { + return false; + } + return true; + }, + sortOrder: params?.pagination?.sortOrder ?? 'desc', + limit: params?.pagination?.limit, + cursor: params?.pagination?.cursor, + getCreatedAt: getObjectCreatedAt('wrun'), + getId: (run) => run.runId, + }); + // If resolveData is "none", replace input/output with empty data + if (resolveData === 'none') { + return { + ...result, + data: result.data.map((run) => ({ + ...run, + input: [], + output: undefined, + })), + }; + } + return result; + }, + async cancel(id, params) { + // This will call update which triggers hook cleanup automatically + const run = await this.update(id, { status: 'cancelled' }); + const resolveData = params?.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION$1; + return filterRunData$1(run, resolveData); + }, + async pause(id, params) { + const run = await this.update(id, { status: 'paused' }); + const resolveData = params?.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION$1; + return filterRunData$1(run, resolveData); + }, + async resume(id, params) { + const run = await this.update(id, { status: 'running' }); + const resolveData = params?.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION$1; + return filterRunData$1(run, resolveData); + }, + }, + steps: { + async create(runId, data) { + const now = new Date(); + const result = { + runId, + stepId: data.stepId, + stepName: data.stepName, + status: 'pending', + input: data.input, + output: undefined, + error: undefined, + attempt: 0, + startedAt: undefined, + completedAt: undefined, + createdAt: now, + updatedAt: now, + }; + const compositeKey = `${runId}-${data.stepId}`; + const stepPath = path.join(basedir, 'steps', `${compositeKey}.json`); + await writeJSON(stepPath, result); + return result; + }, + async get(runId, stepId, params) { + if (!runId) { + const fileIds = await listJSONFiles(path.join(basedir, 'steps')); + const fileId = fileIds.find((fileId) => fileId.endsWith(`-${stepId}`)); + if (!fileId) { + throw new Error(`Step ${stepId} not found`); + } + runId = fileId.split('-')[0]; + } + const compositeKey = `${runId}-${stepId}`; + const stepPath = path.join(basedir, 'steps', `${compositeKey}.json`); + const step = await readJSON(stepPath, StepSchema); + if (!step) { + throw new Error(`Step ${stepId} in run ${runId} not found`); + } + const resolveData = params?.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION$1; + return filterStepData$1(step, resolveData); + }, + async update(runId, stepId, data) { + const compositeKey = `${runId}-${stepId}`; + const stepPath = path.join(basedir, 'steps', `${compositeKey}.json`); + const step = await readJSON(stepPath, StepSchema); + if (!step) { + throw new Error(`Step ${stepId} in run ${runId} not found`); + } + const now = new Date(); + const updatedStep = { + ...step, + ...data, + updatedAt: now, + }; + // Only set startedAt the first time the step transitions to 'running' + if (data.status === 'running' && !updatedStep.startedAt) { + updatedStep.startedAt = now; + } + if (data.status === 'completed' || data.status === 'failed') { + updatedStep.completedAt = now; + } + await writeJSON(stepPath, updatedStep, { overwrite: true }); + return updatedStep; + }, + async list(params) { + const resolveData = params.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION$1; + const result = await paginatedFileSystemQuery({ + directory: path.join(basedir, 'steps'), + schema: StepSchema, + filePrefix: `${params.runId}-`, + sortOrder: params.pagination?.sortOrder ?? 'desc', + limit: params.pagination?.limit, + cursor: params.pagination?.cursor, + getCreatedAt: getObjectCreatedAt('step'), + getId: (step) => step.stepId, + }); + // If resolveData is "none", replace input/output with empty data + if (resolveData === 'none') { + return { + ...result, + data: result.data.map((step) => ({ + ...step, + input: [], + output: undefined, + })), + }; + } + return result; + }, + }, + // Events - filesystem-backed storage + events: { + async create(runId, data, params) { + const eventId = `evnt_${monotonicUlid$1()}`; + const now = new Date(); + const result = { + ...data, + runId, + eventId, + createdAt: now, + }; + // Store event using composite key {runId}-{eventId} + const compositeKey = `${runId}-${eventId}`; + const eventPath = path.join(basedir, 'events', `${compositeKey}.json`); + await writeJSON(eventPath, result); + const resolveData = params?.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION$1; + return filterEventData$1(result, resolveData); + }, + async list(params) { + const { runId } = params; + const resolveData = params.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION$1; + const result = await paginatedFileSystemQuery({ + directory: path.join(basedir, 'events'), + schema: EventSchema, + filePrefix: `${runId}-`, + // Events in chronological order (oldest first) by default, + // different from the default for other list calls. + sortOrder: params.pagination?.sortOrder ?? 'asc', + limit: params.pagination?.limit, + cursor: params.pagination?.cursor, + getCreatedAt: getObjectCreatedAt('evnt'), + getId: (event) => event.eventId, + }); + // If resolveData is "none", remove eventData from events + if (resolveData === 'none') { + return { + ...result, + data: result.data.map((event) => { + const { eventData: _eventData, ...rest } = event; + return rest; + }), + }; + } + return result; + }, + async listByCorrelationId(params) { + const correlationId = params.correlationId; + const resolveData = params.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION$1; + const result = await paginatedFileSystemQuery({ + directory: path.join(basedir, 'events'), + schema: EventSchema, + // No filePrefix - search all events + filter: (event) => event.correlationId === correlationId, + // Events in chronological order (oldest first) by default, + // different from the default for other list calls. + sortOrder: params.pagination?.sortOrder ?? 'asc', + limit: params.pagination?.limit, + cursor: params.pagination?.cursor, + getCreatedAt: getObjectCreatedAt('evnt'), + getId: (event) => event.eventId, + }); + // If resolveData is "none", remove eventData from events + if (resolveData === 'none') { + return { + ...result, + data: result.data.map((event) => { + const { eventData: _eventData, ...rest } = event; + return rest; + }), + }; + } + return result; + }, + }, + // Hooks + hooks: createHooksStorage(basedir), + }; +} + +// Create a monotonic ULID factory that ensures ULIDs are always increasing +// even when generated within the same millisecond +const monotonicUlid = monotonicFactory(() => Math.random()); +function serializeChunk(chunk) { + const eofByte = Buffer.from([chunk.eof ? 1 : 0]); + return Buffer.concat([eofByte, chunk.chunk]); +} +function deserializeChunk(serialized) { + const eof = serialized[0] === 1; + const chunk = serialized.subarray(1); + return { eof, chunk }; +} +function createStreamer$1(basedir) { + const streamEmitter = new EventEmitter(); + return { + async writeToStream(name, chunk) { + const chunkId = `strm_${monotonicUlid()}`; + if (typeof chunk === 'string') { + chunk = new TextEncoder().encode(chunk); + } + const serialized = serializeChunk({ + chunk: Buffer.from(chunk), + eof: false, + }); + const chunkPath = path.join(basedir, 'streams', 'chunks', `${name}-${chunkId}.json`); + await write(chunkPath, serialized); + // Emit real-time event + const chunkData = typeof chunk === 'string' + ? new TextEncoder().encode(chunk) + : chunk instanceof Buffer + ? new Uint8Array(chunk) + : chunk; + streamEmitter.emit(`chunk:${name}`, { + streamName: name, + chunkData, + chunkId, + }); + }, + async closeStream(name) { + const chunkId = `strm_${monotonicUlid()}`; + const chunkPath = path.join(basedir, 'streams', 'chunks', `${name}-${chunkId}.json`); + await write(chunkPath, serializeChunk({ chunk: Buffer.from([]), eof: true })); + streamEmitter.emit(`close:${name}`, { streamName: name }); + }, + async readFromStream(name, startIndex = 0) { + const chunksDir = path.join(basedir, 'streams', 'chunks'); + let removeListeners = () => { }; + return new ReadableStream({ + async start(controller) { + // Track chunks delivered via events to prevent duplicates and maintain order. + const deliveredChunkIds = new Set(); + // Buffer for chunks that arrive via events during disk reading + const bufferedEventChunks = []; + let isReadingFromDisk = true; + const chunkListener = (event) => { + deliveredChunkIds.add(event.chunkId); + if (isReadingFromDisk) { + // Buffer chunks that arrive during disk reading to maintain order + bufferedEventChunks.push({ + chunkId: event.chunkId, + chunkData: event.chunkData, + }); + } + else { + // After disk reading is complete, deliver chunks immediately + controller.enqueue(event.chunkData); + } + }; + const closeListener = () => { + // Remove listeners before closing + streamEmitter.off(`chunk:${name}`, chunkListener); + streamEmitter.off(`close:${name}`, closeListener); + controller.close(); + }; + removeListeners = closeListener; + // Set up listeners FIRST to avoid missing events + streamEmitter.on(`chunk:${name}`, chunkListener); + streamEmitter.on(`close:${name}`, closeListener); + // Now load existing chunks from disk + const files = await listJSONFiles(chunksDir); + const chunkFiles = files + .filter((file) => file.startsWith(`${name}-`)) + .sort(); // ULID lexicographic sort = chronological order + // Process existing chunks, skipping any already delivered via events + let isComplete = false; + for (let i = startIndex; i < chunkFiles.length; i++) { + const file = chunkFiles[i]; + // Extract chunk ID from filename: "streamName-chunkId" + const chunkId = file.substring(name.length + 1); + // Skip if already delivered via event + if (deliveredChunkIds.has(chunkId)) { + continue; + } + const chunk = deserializeChunk(await readBuffer(path.join(chunksDir, `${file}.json`))); + if (chunk?.eof === true) { + isComplete = true; + break; + } + if (chunk.chunk.byteLength) { + controller.enqueue(chunk.chunk); + } + } + // Finished reading from disk - now deliver buffered event chunks in chronological order + isReadingFromDisk = false; + // Sort buffered chunks by ULID (chronological order) + bufferedEventChunks.sort((a, b) => a.chunkId.localeCompare(b.chunkId)); + for (const buffered of bufferedEventChunks) { + controller.enqueue(buffered.chunkData); + } + if (isComplete) { + removeListeners(); + controller.close(); + return; + } + }, + cancel() { + removeListeners(); + }, + }); + }, + }; +} + +/** + * Creates an embedded world instance that combines queue, storage, and streamer functionalities. + * + * @param dataDir - The directory to use for storage. If not provided, the default data dir will be used. + * @param port - The port to use for the queue. If not provided, the default port will be used. + */ +function createEmbeddedWorld({ dataDir, port, }) { + const dir = dataDir ?? config.value.dataDir; + const queuePort = port ?? config.value.port; + return { + ...createQueue$1(queuePort), + ...createStorage$1(dir), + ...createStreamer$1(dir), + }; +} + +// src/parser.ts +var MultipartParseError = class extends Error { + constructor(message) { + super(message); + this.name = "MultipartParseError"; + } +}; +function createSearch(pattern) { + const needle = new TextEncoder().encode(pattern); + return (haystack, start = 0) => Buffer.prototype.indexOf.call(haystack, needle, start); +} +function createPartialTailSearch(pattern) { + const needle = new TextEncoder().encode(pattern); + const byteIndexes = {}; + for (let i = 0; i < needle.length; ++i) { + const byte = needle[i]; + if (byteIndexes[byte] === void 0) byteIndexes[byte] = []; + byteIndexes[byte].push(i); + } + return function(haystack) { + const haystackEnd = haystack.length - 1; + if (haystack[haystackEnd] in byteIndexes) { + const indexes = byteIndexes[haystack[haystackEnd]]; + for (let i = indexes.length - 1; i >= 0; --i) { + for (let j = indexes[i], k = haystackEnd; j >= 0 && haystack[k] === needle[j]; --j, --k) { + if (j === 0) return k; + } + } + } + return -1; + }; +} +function parseHeaders(headerBytes) { + const headerText = new TextDecoder("iso-8859-1").decode(headerBytes); + const lines = headerText.trim().split(/\r?\n/); + const headerInit = []; + for (const line of lines) { + const colonIndex = line.indexOf(":"); + if (colonIndex > 0) { + const name = line.slice(0, colonIndex).trim(); + const value = line.slice(colonIndex + 1).trim(); + headerInit.push([name, value]); + } + } + return new Headers(headerInit); +} +function extractBoundary(contentType) { + const boundaryMatch = contentType.match(/boundary=(?:"([^"]+)"|([^;]+))/i); + if (!boundaryMatch) { + throw new MultipartParseError("No boundary found in Content-Type header"); + } + return boundaryMatch[1] ?? boundaryMatch[2]; +} +var AsyncMessageQueue = class { + queue = []; + waiters = []; + finished = false; + cancelled = false; + error = null; + /** + * Producer: Enqueue a message for consumption + */ + enqueue(message) { + if (this.finished || this.cancelled) return; + if (this.waiters.length > 0) { + const waiter = this.waiters.shift(); + waiter.resolve(message); + } else { + this.queue.push(message); + } + } + /** + * Producer: Signal completion (with optional error) + */ + finish(error) { + if (this.finished) return; + this.finished = true; + this.error = error || null; + while (this.waiters.length > 0) { + const waiter = this.waiters.shift(); + if (error) { + waiter.reject(error); + } else { + waiter.resolve(null); + } + } + } + /** + * Consumer: Cancel the queue (stops accepting new messages and notifies waiters) + */ + cancel() { + if (this.cancelled || this.finished) return; + this.cancelled = true; + while (this.waiters.length > 0) { + const waiter = this.waiters.shift(); + waiter.resolve(null); + } + } + /** + * Consumer: Dequeue next message (or null if finished/cancelled) + */ + async dequeue() { + if (this.queue.length > 0) { + return this.queue.shift(); + } + if (this.finished || this.cancelled) { + if (this.error) throw this.error; + return null; + } + return new Promise((resolve, reject) => { + this.waiters.push({ resolve, reject }); + }); + } + /** + * Check if the queue is in a terminal state + */ + get isTerminal() { + return this.finished || this.cancelled; + } +}; +async function* parseMultipartStream(response, options) { + if (!response.body) { + throw new MultipartParseError("Response body is null"); + } + const contentType = response.headers.get("content-type"); + if (!contentType) { + throw new MultipartParseError("Missing Content-Type header"); + } + const boundary = extractBoundary(contentType); + const parser = new StreamingMultipartParser(boundary, options); + yield* parser.parseStream(response.body); +} +var StreamingMultipartParser = class { + boundary; + findOpeningBoundary; + openingBoundaryLength; + findBoundary; + findPartialTailBoundary; + boundaryLength; + findDoubleNewline; + // Safety limits + maxHeaderSize; + maxBoundaryBuffer; + state = 0 /* Start */; + buffer = null; + currentHeaders = new Headers(); + currentPayloadController = null; + constructor(boundary, options = {}) { + this.boundary = boundary; + this.findOpeningBoundary = createSearch(`--${boundary}`); + this.openingBoundaryLength = 2 + boundary.length; + this.findBoundary = createSearch(`\r +--${boundary}`); + this.findPartialTailBoundary = createPartialTailSearch(`\r +--${boundary}`); + this.boundaryLength = 4 + boundary.length; + this.findDoubleNewline = createSearch("\r\n\r\n"); + this.maxHeaderSize = options.maxHeaderSize ?? 65536; + this.maxBoundaryBuffer = options.maxBoundaryBuffer ?? 8192; + } + async *parseStream(stream) { + const reader = stream.getReader(); + const messageQueue = new AsyncMessageQueue(); + const producer = this.startProducer(reader, messageQueue); + try { + yield* this.consumeMessages(messageQueue); + } finally { + messageQueue.cancel(); + this.closeCurrentPayload(); + try { + await reader.cancel(); + } catch (error) { + } + await producer; + } + } + /** + * Producer: Continuously read chunks and parse messages + */ + async startProducer(reader, messageQueue) { + try { + while (!messageQueue.isTerminal) { + let result; + try { + result = await reader.read(); + } catch (readError) { + if (readError instanceof Error && (readError.name === "AbortError" || readError.constructor.name === "AbortError" || readError.name === "TimeoutError" || readError.constructor.name === "TimeoutError")) { + break; + } + throw readError; + } + const { done, value } = result; + if (done) { + if (this.buffer !== null && this.buffer.length > 0) { + const messages2 = this.write(new Uint8Array(0)); + for (const message of messages2) { + if (messageQueue.isTerminal) break; + messageQueue.enqueue(message); + } + } + if (this.state !== 4 /* Done */) { + if (this.state === 0 /* Start */) { + throw new MultipartParseError( + "Invalid multipart stream: missing initial boundary" + ); + } + throw new MultipartParseError("Unexpected end of stream"); + } + break; + } + if (!(value instanceof Uint8Array)) { + throw new MultipartParseError( + `Invalid chunk type: expected Uint8Array, got ${typeof value}` + ); + } + const messages = this.write(value); + for (const message of messages) { + if (messageQueue.isTerminal) break; + messageQueue.enqueue(message); + } + } + if (!messageQueue.isTerminal) { + messageQueue.finish(); + } + } catch (error) { + this.closeCurrentPayload(error); + if (!messageQueue.isTerminal) { + messageQueue.finish(error); + } + } finally { + try { + reader.releaseLock(); + } catch (error) { + } + } + } + /** + * Consumer: Yield messages from the queue + */ + async *consumeMessages(messageQueue) { + while (true) { + const message = await messageQueue.dequeue(); + if (message === null) { + break; + } + yield message; + } + } + /** + * Process a chunk of data through the state machine and return any complete messages. + * + * Returns an array because a single chunk can contain multiple complete messages + * when small messages with headers + body + boundary all fit in one network chunk. + * All messages must be captured and queued to maintain proper message ordering. + */ + write(chunk) { + const newMessages = []; + if (this.state === 4 /* Done */) { + throw new MultipartParseError("Unexpected data after end of stream"); + } + let index = 0; + let chunkLength = chunk.length; + if (this.buffer !== null) { + const newSize = this.buffer.length + chunkLength; + const maxAllowedSize = this.state === 2 /* Header */ ? this.maxHeaderSize : this.maxBoundaryBuffer; + if (newSize > maxAllowedSize) { + throw new MultipartParseError( + `Buffer size limit exceeded: ${newSize} bytes > ${maxAllowedSize} bytes. This may indicate malformed multipart data with ${this.state === 2 /* Header */ ? "oversized headers" : "invalid boundaries"}.` + ); + } + const newChunk = new Uint8Array(newSize); + newChunk.set(this.buffer, 0); + newChunk.set(chunk, this.buffer.length); + chunk = newChunk; + chunkLength = chunk.length; + this.buffer = null; + } + if (chunkLength === 0 && this.state === 0 /* Start */) { + throw new MultipartParseError( + "Invalid multipart stream: missing initial boundary" + ); + } + while (true) { + if (this.state === 3 /* Body */) { + if (chunkLength - index < this.boundaryLength) { + const remainingData = chunk.subarray(index); + if (remainingData.length > this.maxBoundaryBuffer) { + throw new MultipartParseError( + `Boundary buffer limit exceeded: ${remainingData.length} > ${this.maxBoundaryBuffer}` + ); + } + this.buffer = remainingData; + break; + } + const boundaryIndex = this.findBoundary(chunk, index); + if (boundaryIndex === -1) { + const partialTailIndex = this.findPartialTailBoundary(chunk); + if (partialTailIndex === -1) { + this.writeBody(index === 0 ? chunk : chunk.subarray(index)); + } else { + this.writeBody(chunk.subarray(index, partialTailIndex)); + const partialBoundary = chunk.subarray(partialTailIndex); + if (partialBoundary.length > this.maxBoundaryBuffer) { + throw new MultipartParseError( + `Partial boundary too large: ${partialBoundary.length} > ${this.maxBoundaryBuffer}` + ); + } + this.buffer = partialBoundary; + } + break; + } + this.writeBody(chunk.subarray(index, boundaryIndex)); + this.finishMessage(); + index = boundaryIndex + this.boundaryLength; + this.state = 1 /* AfterBoundary */; + } + if (this.state === 1 /* AfterBoundary */) { + if (chunkLength - index < 2) { + const remainingData = chunk.subarray(index); + if (remainingData.length > this.maxBoundaryBuffer) { + throw new MultipartParseError( + `After-boundary buffer limit exceeded: ${remainingData.length} > ${this.maxBoundaryBuffer}` + ); + } + this.buffer = remainingData; + break; + } + if (chunk[index] === 45 && chunk[index + 1] === 45) { + this.state = 4 /* Done */; + break; + } + if (chunk[index] === 13 && chunk[index + 1] === 10) { + index += 2; + } else if (chunk[index] === 10) { + index += 1; + } else { + throw new MultipartParseError( + `Invalid character after boundary: expected CRLF or LF, got 0x${chunk[index].toString(16)}` + ); + } + this.state = 2 /* Header */; + } + if (this.state === 2 /* Header */) { + if (chunkLength - index < 4) { + const remainingData = chunk.subarray(index); + if (remainingData.length > this.maxHeaderSize) { + throw new MultipartParseError( + `Header buffer limit exceeded: ${remainingData.length} > ${this.maxHeaderSize}` + ); + } + this.buffer = remainingData; + break; + } + let headerEndIndex = this.findDoubleNewline(chunk, index); + let headerEndOffset = 4; + if (headerEndIndex === -1) { + const lfDoubleNewline = createSearch("\n\n"); + headerEndIndex = lfDoubleNewline(chunk, index); + headerEndOffset = 2; + } + if (headerEndIndex === -1) { + const headerData = chunk.subarray(index); + if (headerData.length > this.maxHeaderSize) { + throw new MultipartParseError( + `Headers too large: ${headerData.length} > ${this.maxHeaderSize} bytes` + ); + } + this.buffer = headerData; + break; + } + const headerBytes = chunk.subarray(index, headerEndIndex); + this.currentHeaders = parseHeaders(headerBytes); + const message = this.createStreamingMessage(); + newMessages.push(message); + index = headerEndIndex + headerEndOffset; + this.state = 3 /* Body */; + continue; + } + if (this.state === 0 /* Start */) { + if (chunkLength < this.openingBoundaryLength) { + if (chunk.length > this.maxBoundaryBuffer) { + throw new MultipartParseError( + `Initial chunk too large for boundary detection: ${chunk.length} > ${this.maxBoundaryBuffer}` + ); + } + this.buffer = chunk; + break; + } + const boundaryIndex = this.findOpeningBoundary(chunk); + if (boundaryIndex !== 0) { + throw new MultipartParseError( + "Invalid multipart stream: missing initial boundary" + ); + } + index = this.openingBoundaryLength; + this.state = 1 /* AfterBoundary */; + } + } + return newMessages; + } + createStreamingMessage() { + const headers = new Headers(this.currentHeaders); + const payload = new ReadableStream({ + start: (controller) => { + this.currentPayloadController = controller; + } + }); + this.currentHeaders = new Headers(); + return { + headers, + payload + }; + } + writeBody(chunk) { + if (this.currentPayloadController) { + this.currentPayloadController.enqueue(chunk); + } + } + finishMessage() { + if (this.currentPayloadController) { + this.currentPayloadController.close(); + this.currentPayloadController = null; + } + } + /** + * Close current payload controller if open (used during cleanup) + * If an error is provided, forwards it to the payload consumer + */ + closeCurrentPayload(error) { + if (this.currentPayloadController) { + try { + if (error) { + this.currentPayloadController.error(error); + } else { + this.currentPayloadController.close(); + } + } catch (controllerError) { + } + this.currentPayloadController = null; + } + } +}; + +var getContext_1; +var hasRequiredGetContext; + +function requireGetContext () { + if (hasRequiredGetContext) return getContext_1; + hasRequiredGetContext = 1; + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; + var __getOwnPropNames = Object.getOwnPropertyNames; + var __hasOwnProp = Object.prototype.hasOwnProperty; + var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + var get_context_exports = {}; + __export(get_context_exports, { + SYMBOL_FOR_REQ_CONTEXT: () => SYMBOL_FOR_REQ_CONTEXT, + getContext: () => getContext + }); + getContext_1 = __toCommonJS(get_context_exports); + const SYMBOL_FOR_REQ_CONTEXT = Symbol.for("@vercel/request-context"); + function getContext() { + const fromSymbol = globalThis; + return fromSymbol[SYMBOL_FOR_REQ_CONTEXT]?.get?.() ?? {}; + } + return getContext_1; +} + +var tokenError; +var hasRequiredTokenError; + +function requireTokenError () { + if (hasRequiredTokenError) return tokenError; + hasRequiredTokenError = 1; + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; + var __getOwnPropNames = Object.getOwnPropertyNames; + var __hasOwnProp = Object.prototype.hasOwnProperty; + var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + var token_error_exports = {}; + __export(token_error_exports, { + VercelOidcTokenError: () => VercelOidcTokenError + }); + tokenError = __toCommonJS(token_error_exports); + class VercelOidcTokenError extends Error { + constructor(message, cause) { + super(message); + this.name = "VercelOidcTokenError"; + this.cause = cause; + } + toString() { + if (this.cause) { + return `${this.name}: ${this.message}: ${this.cause}`; + } + return `${this.name}: ${this.message}`; + } + } + return tokenError; +} + +var getVercelOidcToken_1; +var hasRequiredGetVercelOidcToken; + +function requireGetVercelOidcToken () { + if (hasRequiredGetVercelOidcToken) return getVercelOidcToken_1; + hasRequiredGetVercelOidcToken = 1; + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; + var __getOwnPropNames = Object.getOwnPropertyNames; + var __hasOwnProp = Object.prototype.hasOwnProperty; + var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + var get_vercel_oidc_token_exports = {}; + __export(get_vercel_oidc_token_exports, { + getVercelOidcToken: () => getVercelOidcToken, + getVercelOidcTokenSync: () => getVercelOidcTokenSync + }); + getVercelOidcToken_1 = __toCommonJS(get_vercel_oidc_token_exports); + var import_get_context = requireGetContext(); + var import_token_error = requireTokenError(); + async function getVercelOidcToken() { + let token = ""; + let err; + try { + token = getVercelOidcTokenSync(); + } catch (error) { + err = error; + } + try { + const [{ getTokenPayload, isExpired }, { refreshToken }] = await Promise.all([ + await import('./token-util_D6r3xWR2.mjs').then(n => n.t), + await import('./token_CrOFk7pc.mjs').then(n => n.t) + ]); + if (!token || isExpired(getTokenPayload(token))) { + await refreshToken(); + token = getVercelOidcTokenSync(); + } + } catch (error) { + if (err?.message && error instanceof Error) { + error.message = `${err.message} +${error.message}`; + } + throw new import_token_error.VercelOidcTokenError(`Failed to refresh OIDC token`, error); + } + return token; + } + function getVercelOidcTokenSync() { + const token = (0, import_get_context.getContext)().headers?.["x-vercel-oidc-token"] ?? process.env.VERCEL_OIDC_TOKEN; + if (!token) { + throw new Error( + `The 'x-vercel-oidc-token' header is missing from the request. Do you have the OIDC option enabled in the Vercel project settings?` + ); + } + return token; + } + return getVercelOidcToken_1; +} + +var dist; +var hasRequiredDist; + +function requireDist () { + if (hasRequiredDist) return dist; + hasRequiredDist = 1; + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; + var __getOwnPropNames = Object.getOwnPropertyNames; + var __hasOwnProp = Object.prototype.hasOwnProperty; + var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + var src_exports = {}; + __export(src_exports, { + getContext: () => import_get_context.getContext, + getVercelOidcToken: () => import_get_vercel_oidc_token.getVercelOidcToken, + getVercelOidcTokenSync: () => import_get_vercel_oidc_token.getVercelOidcTokenSync + }); + dist = __toCommonJS(src_exports); + var import_get_vercel_oidc_token = requireGetVercelOidcToken(); + var import_get_context = requireGetContext(); + return dist; +} + +var distExports = requireDist(); + +// src/transports.ts +async function streamToBuffer(stream) { + let totalLength = 0; + const reader = stream.getReader(); + const chunks = []; + try { + while (true) { + const { done, value } = await reader.read(); + if (done) break; + chunks.push(value); + totalLength += value.length; + } + } finally { + reader.releaseLock(); + } + return Buffer.concat(chunks, totalLength); +} +var JsonTransport = class { + contentType = "application/json"; + replacer; + reviver; + constructor(options = {}) { + this.replacer = options.replacer; + this.reviver = options.reviver; + } + serialize(value) { + return Buffer.from(JSON.stringify(value, this.replacer), "utf8"); + } + async deserialize(stream) { + const buffer = await streamToBuffer(stream); + return JSON.parse(buffer.toString("utf8"), this.reviver); + } +}; + +// src/types.ts +var MessageNotFoundError = class extends Error { + constructor(messageId) { + super(`Message ${messageId} not found`); + this.name = "MessageNotFoundError"; + } +}; +var MessageNotAvailableError = class extends Error { + constructor(messageId, reason) { + super( + `Message ${messageId} not available for processing${reason ? `: ${reason}` : ""}` + ); + this.name = "MessageNotAvailableError"; + } +}; +var MessageCorruptedError = class extends Error { + constructor(messageId, reason) { + super(`Message ${messageId} is corrupted: ${reason}`); + this.name = "MessageCorruptedError"; + } +}; +var QueueEmptyError = class extends Error { + constructor(queueName, consumerGroup) { + super( + `No messages available in queue "${queueName}" for consumer group "${consumerGroup}"` + ); + this.name = "QueueEmptyError"; + } +}; +var MessageLockedError = class extends Error { + retryAfter; + constructor(messageId, retryAfter) { + const retryMessage = retryAfter ? ` Retry after ${retryAfter} seconds.` : " Try again later."; + super(`Message ${messageId} is temporarily locked.${retryMessage}`); + this.name = "MessageLockedError"; + this.retryAfter = retryAfter; + } +}; +var UnauthorizedError = class extends Error { + constructor(message = "Missing or invalid authentication token") { + super(message); + this.name = "UnauthorizedError"; + } +}; +var ForbiddenError = class extends Error { + constructor(message = "Queue environment doesn't match token environment") { + super(message); + this.name = "ForbiddenError"; + } +}; +var BadRequestError = class extends Error { + constructor(message) { + super(message); + this.name = "BadRequestError"; + } +}; +var InternalServerError = class extends Error { + constructor(message = "Unexpected server error") { + super(message); + this.name = "InternalServerError"; + } +}; +var InvalidLimitError = class extends Error { + constructor(limit, min = 1, max = 10) { + super(`Invalid limit: ${limit}. Limit must be between ${min} and ${max}.`); + this.name = "InvalidLimitError"; + } +}; + +// src/client.ts +async function consumeStream(stream) { + const reader = stream.getReader(); + try { + while (true) { + const { done } = await reader.read(); + if (done) break; + } + } finally { + reader.releaseLock(); + } +} +function parseQueueHeaders(headers) { + const messageId = headers.get("Vqs-Message-Id"); + const deliveryCountStr = headers.get("Vqs-Delivery-Count") || "0"; + const timestamp = headers.get("Vqs-Timestamp"); + const contentType = headers.get("Content-Type") || "application/octet-stream"; + const ticket = headers.get("Vqs-Ticket"); + if (!messageId || !timestamp || !ticket) { + return null; + } + const deliveryCount = parseInt(deliveryCountStr, 10); + if (isNaN(deliveryCount)) { + return null; + } + return { + messageId, + deliveryCount, + createdAt: new Date(timestamp), + contentType, + ticket + }; +} +var QueueClient = class { + baseUrl; + basePath; + customHeaders = {}; + token; + /** + * Create a new Vercel Queue Service client + * @param options Client configuration options + */ + constructor(options = {}) { + this.baseUrl = options.baseUrl || process.env.VERCEL_QUEUE_BASE_URL || "https://vercel-queue.com"; + this.basePath = options.basePath || process.env.VERCEL_QUEUE_BASE_PATH || "/api/v2/messages"; + this.token = options.token || process.env.VERCEL_QUEUE_TOKEN; + const VERCEL_QUEUE_HEADER_PREFIX = "VERCEL_QUEUE_HEADER_"; + this.customHeaders = Object.fromEntries( + Object.entries(process.env).filter(([key]) => key.startsWith(VERCEL_QUEUE_HEADER_PREFIX)).map(([key, value]) => [ + // This allows headers to use dashes independent of shell used + key.replace(VERCEL_QUEUE_HEADER_PREFIX, "").replaceAll("__", "-"), + value || "" + ]) + ); + } + async getToken() { + if (this.token) { + return this.token; + } + const token = await distExports.getVercelOidcToken(); + if (!token) { + throw new Error( + "Failed to get OIDC token from Vercel Functions. Make sure you are running in a Vercel Function environment, or provide a token explicitly.\n\nTo set up your environment:\n1. Link your project: 'vercel link'\n2. Pull environment variables: 'vercel env pull'\n3. Run with environment: 'dotenv -e .env.local -- your-command'" + ); + } + return token; + } + /** + * Send a message to a queue + * @param options Send message options + * @param transport Serializer/deserializer for the payload + * @returns Promise with the message ID + * @throws {BadRequestError} When request parameters are invalid + * @throws {UnauthorizedError} When authentication fails + * @throws {ForbiddenError} When access is denied (environment mismatch) + * @throws {InternalServerError} When server encounters an error + */ + async sendMessage(options, transport) { + const { queueName, payload, idempotencyKey, retentionSeconds } = options; + const headers = new Headers({ + Authorization: `Bearer ${await this.getToken()}`, + "Vqs-Queue-Name": queueName, + "Content-Type": transport.contentType, + ...this.customHeaders + }); + const deploymentId = options.deploymentId || process.env.VERCEL_DEPLOYMENT_ID; + if (deploymentId) { + headers.set("Vqs-Deployment-Id", deploymentId); + } + if (idempotencyKey) { + headers.set("Vqs-Idempotency-Key", idempotencyKey); + } + if (retentionSeconds !== void 0) { + headers.set("Vqs-Retention-Seconds", retentionSeconds.toString()); + } + const body = transport.serialize(payload); + const response = await fetch(`${this.baseUrl}${this.basePath}`, { + method: "POST", + body, + headers + }); + if (!response.ok) { + if (response.status === 400) { + const errorText = await response.text(); + throw new BadRequestError(errorText || "Invalid parameters"); + } + if (response.status === 401) { + throw new UnauthorizedError(); + } + if (response.status === 403) { + throw new ForbiddenError(); + } + if (response.status === 409) { + throw new Error("Duplicate idempotency key detected"); + } + if (response.status >= 500) { + throw new InternalServerError( + `Server error: ${response.status} ${response.statusText}` + ); + } + throw new Error( + `Failed to send message: ${response.status} ${response.statusText}` + ); + } + const responseData = await response.json(); + return responseData; + } + /** + * Receive messages from a queue + * @param options Receive messages options + * @param transport Serializer/deserializer for the payload + * @returns AsyncGenerator that yields messages as they arrive + * @throws {InvalidLimitError} When limit parameter is not between 1 and 10 + * @throws {QueueEmptyError} When no messages are available (204) + * @throws {MessageLockedError} When messages are temporarily locked (423) + * @throws {BadRequestError} When request parameters are invalid + * @throws {UnauthorizedError} When authentication fails + * @throws {ForbiddenError} When access is denied (environment mismatch) + * @throws {InternalServerError} When server encounters an error + */ + async *receiveMessages(options, transport) { + const { queueName, consumerGroup, visibilityTimeoutSeconds, limit } = options; + if (limit !== void 0 && (limit < 1 || limit > 10)) { + throw new InvalidLimitError(limit); + } + const headers = new Headers({ + Authorization: `Bearer ${await this.getToken()}`, + "Vqs-Queue-Name": queueName, + "Vqs-Consumer-Group": consumerGroup, + Accept: "multipart/mixed", + ...this.customHeaders + }); + if (visibilityTimeoutSeconds !== void 0) { + headers.set( + "Vqs-Visibility-Timeout", + visibilityTimeoutSeconds.toString() + ); + } + if (limit !== void 0) { + headers.set("Vqs-Limit", limit.toString()); + } + const response = await fetch(`${this.baseUrl}${this.basePath}`, { + method: "GET", + headers + }); + if (response.status === 204) { + throw new QueueEmptyError(queueName, consumerGroup); + } + if (!response.ok) { + if (response.status === 400) { + const errorText = await response.text(); + throw new BadRequestError(errorText || "Invalid parameters"); + } + if (response.status === 401) { + throw new UnauthorizedError(); + } + if (response.status === 403) { + throw new ForbiddenError(); + } + if (response.status === 423) { + const retryAfterHeader = response.headers.get("Retry-After"); + let retryAfter; + if (retryAfterHeader) { + const parsed = parseInt(retryAfterHeader, 10); + retryAfter = isNaN(parsed) ? void 0 : parsed; + } + throw new MessageLockedError("next message", retryAfter); + } + if (response.status >= 500) { + throw new InternalServerError( + `Server error: ${response.status} ${response.statusText}` + ); + } + throw new Error( + `Failed to receive messages: ${response.status} ${response.statusText}` + ); + } + for await (const multipartMessage of parseMultipartStream(response)) { + try { + const parsedHeaders = parseQueueHeaders(multipartMessage.headers); + if (!parsedHeaders) { + console.warn("Missing required queue headers in multipart part"); + await consumeStream(multipartMessage.payload); + continue; + } + const deserializedPayload = await transport.deserialize( + multipartMessage.payload + ); + const message = { + ...parsedHeaders, + payload: deserializedPayload + }; + yield message; + } catch (error) { + console.warn("Failed to process multipart message:", error); + await consumeStream(multipartMessage.payload); + } + } + } + async receiveMessageById(options, transport) { + const { + queueName, + consumerGroup, + messageId, + visibilityTimeoutSeconds, + skipPayload + } = options; + const headers = new Headers({ + Authorization: `Bearer ${await this.getToken()}`, + "Vqs-Queue-Name": queueName, + "Vqs-Consumer-Group": consumerGroup, + Accept: "multipart/mixed", + ...this.customHeaders + }); + if (visibilityTimeoutSeconds !== void 0) { + headers.set( + "Vqs-Visibility-Timeout", + visibilityTimeoutSeconds.toString() + ); + } + if (skipPayload) { + headers.set("Vqs-Skip-Payload", "1"); + } + const response = await fetch( + `${this.baseUrl}${this.basePath}/${encodeURIComponent(messageId)}`, + { + method: "GET", + headers + } + ); + if (!response.ok) { + if (response.status === 400) { + const errorText = await response.text(); + throw new BadRequestError(errorText || "Invalid parameters"); + } + if (response.status === 401) { + throw new UnauthorizedError(); + } + if (response.status === 403) { + throw new ForbiddenError(); + } + if (response.status === 404) { + throw new MessageNotFoundError(messageId); + } + if (response.status === 423) { + const retryAfterHeader = response.headers.get("Retry-After"); + let retryAfter; + if (retryAfterHeader) { + const parsed = parseInt(retryAfterHeader, 10); + retryAfter = isNaN(parsed) ? void 0 : parsed; + } + throw new MessageLockedError(messageId, retryAfter); + } + if (response.status === 409) { + throw new MessageNotAvailableError(messageId); + } + if (response.status >= 500) { + throw new InternalServerError( + `Server error: ${response.status} ${response.statusText}` + ); + } + throw new Error( + `Failed to receive message by ID: ${response.status} ${response.statusText}` + ); + } + if (skipPayload && response.status === 204) { + const parsedHeaders = parseQueueHeaders(response.headers); + if (!parsedHeaders) { + throw new MessageCorruptedError( + messageId, + "Missing required queue headers in 204 response" + ); + } + const message = { + ...parsedHeaders, + payload: void 0 + }; + return { message }; + } + if (!transport) { + throw new Error("Transport is required when skipPayload is not true"); + } + try { + for await (const multipartMessage of parseMultipartStream(response)) { + try { + const parsedHeaders = parseQueueHeaders(multipartMessage.headers); + if (!parsedHeaders) { + console.warn("Missing required queue headers in multipart part"); + await consumeStream(multipartMessage.payload); + continue; + } + const deserializedPayload = await transport.deserialize( + multipartMessage.payload + ); + const message = { + ...parsedHeaders, + payload: deserializedPayload + }; + return { message }; + } catch (error) { + console.warn("Failed to deserialize message by ID:", error); + await consumeStream(multipartMessage.payload); + throw new MessageCorruptedError( + messageId, + `Failed to deserialize payload: ${error}` + ); + } + } + } catch (error) { + if (error instanceof MessageCorruptedError) { + throw error; + } + throw new MessageCorruptedError( + messageId, + `Failed to parse multipart response: ${error}` + ); + } + throw new MessageNotFoundError(messageId); + } + /** + * Delete a message (acknowledge processing) + * @param options Delete message options + * @returns Promise with delete status + * @throws {MessageNotFoundError} When the message doesn't exist (404) + * @throws {MessageNotAvailableError} When message can't be deleted (409) + * @throws {BadRequestError} When ticket is missing or invalid (400) + * @throws {UnauthorizedError} When authentication fails + * @throws {ForbiddenError} When access is denied (environment mismatch) + * @throws {InternalServerError} When server encounters an error + */ + async deleteMessage(options) { + const { queueName, consumerGroup, messageId, ticket } = options; + const response = await fetch( + `${this.baseUrl}${this.basePath}/${encodeURIComponent(messageId)}`, + { + method: "DELETE", + headers: new Headers({ + Authorization: `Bearer ${await this.getToken()}`, + "Vqs-Queue-Name": queueName, + "Vqs-Consumer-Group": consumerGroup, + "Vqs-Ticket": ticket, + ...this.customHeaders + }) + } + ); + if (!response.ok) { + if (response.status === 400) { + throw new BadRequestError("Missing or invalid ticket"); + } + if (response.status === 401) { + throw new UnauthorizedError(); + } + if (response.status === 403) { + throw new ForbiddenError(); + } + if (response.status === 404) { + throw new MessageNotFoundError(messageId); + } + if (response.status === 409) { + throw new MessageNotAvailableError( + messageId, + "Invalid ticket, message not in correct state, or already processed" + ); + } + if (response.status >= 500) { + throw new InternalServerError( + `Server error: ${response.status} ${response.statusText}` + ); + } + throw new Error( + `Failed to delete message: ${response.status} ${response.statusText}` + ); + } + return { deleted: true }; + } + /** + * Change the visibility timeout of a message + * @param options Change visibility options + * @returns Promise with update status + * @throws {MessageNotFoundError} When the message doesn't exist (404) + * @throws {MessageNotAvailableError} When message can't be updated (409) + * @throws {BadRequestError} When ticket is missing or visibility timeout invalid (400) + * @throws {UnauthorizedError} When authentication fails + * @throws {ForbiddenError} When access is denied (environment mismatch) + * @throws {InternalServerError} When server encounters an error + */ + async changeVisibility(options) { + const { + queueName, + consumerGroup, + messageId, + ticket, + visibilityTimeoutSeconds + } = options; + const response = await fetch( + `${this.baseUrl}${this.basePath}/${encodeURIComponent(messageId)}`, + { + method: "PATCH", + headers: new Headers({ + Authorization: `Bearer ${await this.getToken()}`, + "Vqs-Queue-Name": queueName, + "Vqs-Consumer-Group": consumerGroup, + "Vqs-Ticket": ticket, + "Vqs-Visibility-Timeout": visibilityTimeoutSeconds.toString(), + ...this.customHeaders + }) + } + ); + if (!response.ok) { + if (response.status === 400) { + throw new BadRequestError( + "Missing ticket or invalid visibility timeout" + ); + } + if (response.status === 401) { + throw new UnauthorizedError(); + } + if (response.status === 403) { + throw new ForbiddenError(); + } + if (response.status === 404) { + throw new MessageNotFoundError(messageId); + } + if (response.status === 409) { + throw new MessageNotAvailableError( + messageId, + "Invalid ticket, message not in correct state, or already processed" + ); + } + if (response.status >= 500) { + throw new InternalServerError( + `Server error: ${response.status} ${response.statusText}` + ); + } + throw new Error( + `Failed to change visibility: ${response.status} ${response.statusText}` + ); + } + return { updated: true }; + } +}; + +// src/callback.ts +function validateWildcardPattern(pattern) { + const firstIndex = pattern.indexOf("*"); + const lastIndex = pattern.lastIndexOf("*"); + if (firstIndex !== lastIndex) { + return false; + } + if (firstIndex === -1) { + return false; + } + if (firstIndex !== pattern.length - 1) { + return false; + } + return true; +} +function matchesWildcardPattern(topicName, pattern) { + const prefix = pattern.slice(0, -1); + return topicName.startsWith(prefix); +} +function findTopicHandler(queueName, handlers) { + const exactHandler = handlers[queueName]; + if (exactHandler) { + return exactHandler; + } + for (const pattern in handlers) { + if (pattern.includes("*") && matchesWildcardPattern(queueName, pattern)) { + return handlers[pattern]; + } + } + return null; +} +async function parseCallback(request) { + const contentType = request.headers.get("content-type"); + if (!contentType || !contentType.includes("application/cloudevents+json")) { + throw new Error( + "Invalid content type: expected 'application/cloudevents+json'" + ); + } + let cloudEvent; + try { + cloudEvent = await request.json(); + } catch (error) { + throw new Error("Failed to parse CloudEvent from request body"); + } + if (!cloudEvent.type || !cloudEvent.source || !cloudEvent.id || typeof cloudEvent.data !== "object" || cloudEvent.data == null) { + throw new Error("Invalid CloudEvent: missing required fields"); + } + if (cloudEvent.type !== "com.vercel.queue.v1beta") { + throw new Error( + `Invalid CloudEvent type: expected 'com.vercel.queue.v1beta', got '${cloudEvent.type}'` + ); + } + const missingFields = []; + if (!("queueName" in cloudEvent.data)) missingFields.push("queueName"); + if (!("consumerGroup" in cloudEvent.data)) + missingFields.push("consumerGroup"); + if (!("messageId" in cloudEvent.data)) missingFields.push("messageId"); + if (missingFields.length > 0) { + throw new Error( + `Missing required CloudEvent data fields: ${missingFields.join(", ")}` + ); + } + const { messageId, queueName, consumerGroup } = cloudEvent.data; + return { + queueName, + consumerGroup, + messageId + }; +} +function handleCallback(handlers) { + for (const topicPattern in handlers) { + if (topicPattern.includes("*")) { + if (!validateWildcardPattern(topicPattern)) { + throw new Error( + `Invalid wildcard pattern "${topicPattern}": * may only appear once and must be at the end of the topic name` + ); + } + } + } + const routeHandler = async (request) => { + try { + const { queueName, consumerGroup, messageId } = await parseCallback(request); + const topicHandler = findTopicHandler(queueName, handlers); + if (!topicHandler) { + const availableTopics = Object.keys(handlers).join(", "); + return Response.json( + { + error: `No handler found for topic: ${queueName}`, + availableTopics + }, + { status: 404 } + ); + } + const consumerGroupHandler = topicHandler[consumerGroup]; + if (!consumerGroupHandler) { + const availableGroups = Object.keys(topicHandler).join(", "); + return Response.json( + { + error: `No handler found for consumer group "${consumerGroup}" in topic "${queueName}".`, + availableGroups + }, + { status: 404 } + ); + } + const client = new QueueClient(); + const topic = new Topic(client, queueName); + const cg = topic.consumerGroup(consumerGroup); + await cg.consume(consumerGroupHandler, { messageId }); + return Response.json({ status: "success" }); + } catch (error) { + console.error("Queue callback error:", error); + if (error instanceof Error && (error.message.includes("Missing required CloudEvent data fields") || error.message.includes("Invalid CloudEvent") || error.message.includes("Invalid CloudEvent type") || error.message.includes("Invalid content type") || error.message.includes("Failed to parse CloudEvent"))) { + return Response.json({ error: error.message }, { status: 400 }); + } + return Response.json( + { error: "Failed to process queue message" }, + { status: 500 } + ); + } + }; + if (isDevMode()) { + registerDevRouteHandler(routeHandler, handlers); + } + return routeHandler; +} + +// src/dev.ts +var devRouteHandlers = /* @__PURE__ */ new Map(); +var wildcardRouteHandlers = /* @__PURE__ */ new Map(); +function cleanupDeadRefs(key, refs) { + const aliveRefs = refs.filter((ref) => ref.deref() !== void 0); + if (aliveRefs.length === 0) { + wildcardRouteHandlers.delete(key); + } else if (aliveRefs.length < refs.length) { + wildcardRouteHandlers.set(key, aliveRefs); + } +} +function isDevMode() { + return process.env.NODE_ENV === "development"; +} +function registerDevRouteHandler(routeHandler, handlers) { + for (const topicName in handlers) { + for (const consumerGroup in handlers[topicName]) { + const key = `${topicName}:${consumerGroup}`; + if (topicName.includes("*")) { + const existing = wildcardRouteHandlers.get(key) || []; + cleanupDeadRefs(key, existing); + const cleanedRefs = wildcardRouteHandlers.get(key) || []; + const weakRef = new WeakRef(routeHandler); + cleanedRefs.push(weakRef); + wildcardRouteHandlers.set(key, cleanedRefs); + } else { + devRouteHandlers.set(key, { + routeHandler, + topicPattern: topicName + }); + } + } + } +} +function findRouteHandlersForTopic(topicName) { + const handlersMap = /* @__PURE__ */ new Map(); + for (const [ + key, + { routeHandler, topicPattern } + ] of devRouteHandlers.entries()) { + const [_, consumerGroup] = key.split(":"); + if (topicPattern === topicName) { + if (!handlersMap.has(routeHandler)) { + handlersMap.set(routeHandler, /* @__PURE__ */ new Set()); + } + handlersMap.get(routeHandler).add(consumerGroup); + } + } + for (const [key, refs] of wildcardRouteHandlers.entries()) { + const [pattern, consumerGroup] = key.split(":"); + if (matchesWildcardPattern(topicName, pattern)) { + cleanupDeadRefs(key, refs); + const cleanedRefs = wildcardRouteHandlers.get(key) || []; + for (const ref of cleanedRefs) { + const routeHandler = ref.deref(); + if (routeHandler) { + if (!handlersMap.has(routeHandler)) { + handlersMap.set(routeHandler, /* @__PURE__ */ new Set()); + } + handlersMap.get(routeHandler).add(consumerGroup); + } + } + } + } + return handlersMap; +} +function createMockCloudEventRequest(topicName, consumerGroup, messageId) { + const cloudEvent = { + type: "com.vercel.queue.v1beta", + source: `/topic/${topicName}/consumer/${consumerGroup}`, + id: messageId, + datacontenttype: "application/json", + data: { + messageId, + queueName: topicName, + consumerGroup + }, + time: (/* @__PURE__ */ new Date()).toISOString(), + specversion: "1.0" + }; + return new Request("https://localhost/api/queue/callback", { + method: "POST", + headers: { + "Content-Type": "application/cloudevents+json" + }, + body: JSON.stringify(cloudEvent) + }); +} +var DEV_CALLBACK_DELAY = 1e3; +function scheduleDevTimeout(topicName, messageId, timeoutSeconds) { + console.log( + `[Dev Mode] Message ${messageId} timed out for ${timeoutSeconds}s, will re-trigger` + ); + setTimeout( + () => { + console.log( + `[Dev Mode] Re-triggering callback for timed-out message ${messageId}` + ); + triggerDevCallbacks(topicName, messageId); + }, + timeoutSeconds * 1e3 + DEV_CALLBACK_DELAY + ); +} +function triggerDevCallbacks(topicName, messageId) { + const handlersMap = findRouteHandlersForTopic(topicName); + if (handlersMap.size === 0) { + return; + } + const consumerGroups = Array.from( + new Set( + Array.from(handlersMap.values()).flatMap((groups) => Array.from(groups)) + ) + ); + console.log( + `[Dev Mode] Triggering local callbacks for topic "${topicName}" \u2192 consumers: ${consumerGroups.join(", ")}` + ); + setTimeout(async () => { + for (const [routeHandler, consumerGroups2] of handlersMap.entries()) { + for (const consumerGroup of consumerGroups2) { + try { + const request = createMockCloudEventRequest( + topicName, + consumerGroup, + messageId + ); + const response = await routeHandler(request); + if (response.ok) { + try { + const responseData = await response.json(); + if (responseData.status === "success") { + console.log( + `[Dev Mode] Message processed for ${topicName}/${consumerGroup}` + ); + } + } catch (jsonError) { + console.error( + `[Dev Mode] Failed to parse success response for ${topicName}/${consumerGroup}:`, + jsonError + ); + } + } else { + try { + const errorData = await response.json(); + console.error( + `[Dev Mode] Failed to process message for ${topicName}/${consumerGroup}:`, + errorData.error || response.statusText + ); + } catch (jsonError) { + console.error( + `[Dev Mode] Failed to process message for ${topicName}/${consumerGroup}:`, + response.statusText + ); + } + } + } catch (error) { + console.error( + `[Dev Mode] Error triggering callback for ${topicName}/${consumerGroup}:`, + error + ); + } + } + } + }, DEV_CALLBACK_DELAY); +} +function clearDevHandlers() { + devRouteHandlers.clear(); + wildcardRouteHandlers.clear(); +} +if (process.env.NODE_ENV === "test" || process.env.VITEST) { + globalThis.__clearDevHandlers = clearDevHandlers; +} + +// src/consumer-group.ts +var ConsumerGroup = class { + client; + topicName; + consumerGroupName; + visibilityTimeout; + refreshInterval; + transport; + /** + * Create a new ConsumerGroup instance + * @param client QueueClient instance to use for API calls + * @param topicName Name of the topic to consume from + * @param consumerGroupName Name of the consumer group + * @param options Optional configuration + */ + constructor(client, topicName, consumerGroupName, options = {}) { + this.client = client; + this.topicName = topicName; + this.consumerGroupName = consumerGroupName; + this.visibilityTimeout = options.visibilityTimeoutSeconds || 30; + this.refreshInterval = options.refreshInterval || 10; + this.transport = options.transport || new JsonTransport(); + } + /** + * Starts a background loop that periodically extends the visibility timeout for a message. + * This prevents the message from becoming visible to other consumers while it's being processed. + * + * The extension loop runs every `refreshInterval` seconds and updates the message's + * visibility timeout to `visibilityTimeout` seconds from the current time. + * + * @param messageId - The unique identifier of the message to extend visibility for + * @param ticket - The receipt ticket that proves ownership of the message + * @returns A function that when called will stop the extension loop + * + * @remarks + * - The first extension attempt occurs after `refreshInterval` seconds, not immediately + * - If an extension fails, the loop terminates with an error logged to console + * - The returned stop function is idempotent - calling it multiple times is safe + * - By default, the stop function returns immediately without waiting for in-flight + * - Pass `true` to the stop function to wait for any in-flight extension to complete + */ + startVisibilityExtension(messageId, ticket) { + let isRunning = true; + let resolveLifecycle; + let timeoutId = null; + const lifecyclePromise = new Promise((resolve) => { + resolveLifecycle = resolve; + }); + const extend = async () => { + if (!isRunning) { + resolveLifecycle(); + return; + } + try { + await this.client.changeVisibility({ + queueName: this.topicName, + consumerGroup: this.consumerGroupName, + messageId, + ticket, + visibilityTimeoutSeconds: this.visibilityTimeout + }); + if (isRunning) { + timeoutId = setTimeout(() => extend(), this.refreshInterval * 1e3); + } else { + resolveLifecycle(); + } + } catch (error) { + console.error( + `Failed to extend visibility for message ${messageId}:`, + error + ); + resolveLifecycle(); + } + }; + timeoutId = setTimeout(() => extend(), this.refreshInterval * 1e3); + return async (waitForCompletion = false) => { + isRunning = false; + if (timeoutId) { + clearTimeout(timeoutId); + timeoutId = null; + } + if (waitForCompletion) { + await lifecyclePromise; + } else { + resolveLifecycle(); + } + }; + } + /** + * Process a single message with the given handler + * @param message The message to process + * @param handler Function to process the message + */ + async processMessage(message, handler) { + const stopExtension = this.startVisibilityExtension( + message.messageId, + message.ticket + ); + try { + const result = await handler(message.payload, { + messageId: message.messageId, + deliveryCount: message.deliveryCount, + createdAt: message.createdAt, + topicName: this.topicName, + consumerGroup: this.consumerGroupName + }); + await stopExtension(); + if (result && "timeoutSeconds" in result) { + await this.client.changeVisibility({ + queueName: this.topicName, + consumerGroup: this.consumerGroupName, + messageId: message.messageId, + ticket: message.ticket, + visibilityTimeoutSeconds: result.timeoutSeconds + }); + if (isDevMode()) { + scheduleDevTimeout( + this.topicName, + message.messageId, + result.timeoutSeconds + ); + } + } else { + await this.client.deleteMessage({ + queueName: this.topicName, + consumerGroup: this.consumerGroupName, + messageId: message.messageId, + ticket: message.ticket + }); + } + } catch (error) { + await stopExtension(); + if (this.transport.finalize && message.payload !== void 0 && message.payload !== null) { + try { + await this.transport.finalize(message.payload); + } catch (finalizeError) { + console.warn("Failed to finalize message payload:", finalizeError); + } + } + throw error; + } + } + async consume(handler, options) { + if (options?.messageId) { + if (options.skipPayload) { + const response = await this.client.receiveMessageById( + { + queueName: this.topicName, + consumerGroup: this.consumerGroupName, + messageId: options.messageId, + visibilityTimeoutSeconds: this.visibilityTimeout, + skipPayload: true + }, + this.transport + ); + await this.processMessage( + response.message, + handler + ); + } else { + const response = await this.client.receiveMessageById( + { + queueName: this.topicName, + consumerGroup: this.consumerGroupName, + messageId: options.messageId, + visibilityTimeoutSeconds: this.visibilityTimeout + }, + this.transport + ); + await this.processMessage( + response.message, + handler + ); + } + } else { + let messageFound = false; + for await (const message of this.client.receiveMessages( + { + queueName: this.topicName, + consumerGroup: this.consumerGroupName, + visibilityTimeoutSeconds: this.visibilityTimeout, + limit: 1 + }, + this.transport + )) { + messageFound = true; + await this.processMessage(message, handler); + break; + } + if (!messageFound) { + throw new Error("No messages available"); + } + } + } + /** + * Get the consumer group name + */ + get name() { + return this.consumerGroupName; + } + /** + * Get the topic name this consumer group is subscribed to + */ + get topic() { + return this.topicName; + } +}; + +// src/topic.ts +var Topic = class { + client; + topicName; + transport; + /** + * Create a new Topic instance + * @param client QueueClient instance to use for API calls + * @param topicName Name of the topic to work with + * @param transport Optional serializer/deserializer for the payload (defaults to JSON) + */ + constructor(client, topicName, transport) { + this.client = client; + this.topicName = topicName; + this.transport = transport || new JsonTransport(); + } + /** + * Publish a message to the topic + * @param payload The data to publish + * @param options Optional publish options + * @returns An object containing the message ID + * @throws {BadRequestError} When request parameters are invalid + * @throws {UnauthorizedError} When authentication fails + * @throws {ForbiddenError} When access is denied (environment mismatch) + * @throws {InternalServerError} When server encounters an error + */ + async publish(payload, options) { + const result = await this.client.sendMessage( + { + queueName: this.topicName, + payload, + idempotencyKey: options?.idempotencyKey, + retentionSeconds: options?.retentionSeconds, + deploymentId: options?.deploymentId + }, + this.transport + ); + if (isDevMode()) { + triggerDevCallbacks(this.topicName, result.messageId); + } + return { messageId: result.messageId }; + } + /** + * Create a consumer group for this topic + * @param consumerGroupName Name of the consumer group + * @param options Optional configuration for the consumer group + * @returns A ConsumerGroup instance + */ + consumerGroup(consumerGroupName, options) { + const consumerOptions = { + ...options, + transport: options?.transport || this.transport + }; + return new ConsumerGroup( + this.client, + this.topicName, + consumerGroupName, + consumerOptions + ); + } + /** + * Get the topic name + */ + get name() { + return this.topicName; + } + /** + * Get the transport used by this topic + */ + get serializer() { + return this.transport; + } +}; + +// src/factory.ts +async function send(topicName, payload, options) { + const transport = options?.transport || new JsonTransport(); + const client = new QueueClient(); + const result = await client.sendMessage( + { + queueName: topicName, + payload, + idempotencyKey: options?.idempotencyKey, + retentionSeconds: options?.retentionSeconds, + deploymentId: options?.deploymentId + }, + transport + ); + if (isDevMode()) { + triggerDevCallbacks(topicName, result.messageId); + } + return { messageId: result.messageId }; +} + +// Generated by genversion. +const version = '4.0.1-beta.7'; + +const DEFAULT_RESOLVE_DATA_OPTION = 'all'; +function dateToStringReplacer(_key, value) { + if (value instanceof Date) { + return value.toISOString(); + } + return value; +} +/** + * Helper to serialize error into a JSON string in the error field. + * The error field can be either: + * - A plain string (legacy format, just the error message) + * - A JSON string with { message, stack, code } (new format) + */ +function serializeError(data) { + const { error, ...rest } = data; + // If we have an error, serialize as JSON string + if (error !== undefined) { + return { + ...rest, + error: JSON.stringify({ + message: error.message, + stack: error.stack, + code: error.code, + }), + }; + } + return data; +} +/** + * Helper to deserialize error field from the backend into a StructuredError object. + * Handles backwards compatibility: + * - If error is a JSON string with {message, stack, code} → parse into StructuredError + * - If error is a plain string → treat as error message with no stack + * - If no error → undefined + * + * This function transforms objects from wire format (where error is a JSON string) + * to domain format (where error is a StructuredError object). The generic type + * parameter should be the expected output type (WorkflowRun or Step). + * + * Note: The type assertion is necessary because the wire format types from Zod schemas + * have `error?: string` while the domain types have complex error types (e.g., discriminated + * unions with `error: void` or `error: StructuredError` depending on status), but the + * transformation preserves all other fields correctly. + */ +function deserializeError(obj) { + const { error, ...rest } = obj; + if (!error) { + return obj; + } + // Try to parse as structured error JSON + try { + const parsed = StructuredErrorSchema.parse(JSON.parse(error)); + return { + ...rest, + error: { + message: parsed.message, + stack: parsed.stack, + code: parsed.code, + }, + }; + } + catch { + // Backwards compatibility: error is just a plain string + return { + ...rest, + error: { + message: error, + }, + }; + } +} +const getUserAgent = () => { + return `@workflow/world-vercel/${version} node-${process.version} ${os.platform()} (${os.arch()})`; +}; +const getHttpUrl = (config) => { + const projectConfig = config?.projectConfig; + const defaultUrl = 'https://vercel-workflow.com/api'; + const defaultProxyUrl = 'https://api.vercel.com/v1/workflow'; + const usingProxy = Boolean(config?.baseUrl || (projectConfig?.projectId && projectConfig?.teamId)); + const baseUrl = config?.baseUrl || (usingProxy ? defaultProxyUrl : defaultUrl); + return { baseUrl, usingProxy }; +}; +const getHeaders = (config) => { + const projectConfig = config?.projectConfig; + const headers = new Headers(config?.headers); + headers.set('User-Agent', getUserAgent()); + if (projectConfig) { + headers.set('x-vercel-environment', projectConfig.environment || 'production'); + if (projectConfig.projectId) { + headers.set('x-vercel-project-id', projectConfig.projectId); + } + if (projectConfig.teamId) { + headers.set('x-vercel-team-id', projectConfig.teamId); + } + } + return headers; +}; +async function getHttpConfig(config) { + const headers = getHeaders(config); + const token = config?.token ?? (await distExports.getVercelOidcToken()); + if (token) { + headers.set('Authorization', `Bearer ${token}`); + } + const { baseUrl, usingProxy } = getHttpUrl(config); + return { baseUrl, headers, usingProxy }; +} +async function makeRequest({ endpoint, options = {}, config = {}, schema, }) { + const { baseUrl, headers } = await getHttpConfig(config); + headers.set('Content-Type', 'application/json'); + const url = `${baseUrl}${endpoint}`; + const response = await fetch(url, { + ...options, + headers, + }); + if (!response.ok) { + const errorData = (await response.json().catch(() => ({}))); + if (process.env.DEBUG === '1') { + const stringifiedHeaders = Array.from(headers.entries()) + .map(([key, value]) => `-H "${key}: ${value}"`) + .join(' '); + console.error(`Failed to fetch, reproduce with:\ncurl -X ${options.method} ${stringifiedHeaders} "${url}"`); + } + throw new WorkflowAPIError(errorData.message || + `${options.method ?? 'GET'} ${endpoint} -> HTTP ${response.status}: ${response.statusText}`, { url, status: response.status, code: errorData.code }); + } + try { + const text = await response.text(); + return schema.parse(JSON.parse(text)); + } + catch (error) { + if (error instanceof ZodError) { + throw new WorkflowAPIError(`Failed to parse server response for ${options.method ?? 'GET'} ${endpoint}: ${error.message}`, { url, cause: error }); + } + throw new WorkflowAPIError(`Failed to parse server response for ${options.method ?? 'GET'} ${endpoint}`, { url, cause: error }); + } +} + +const MessageWrapper = z.object({ + payload: QueuePayloadSchema, + queueName: ValidQueueName, +}); +const VERCEL_QUEUE_MAX_VISIBILITY = 82800; // 23 hours in seconds +function createQueue(config) { + const { baseUrl, usingProxy } = getHttpUrl(config); + const headers = getHeaders(config); + if (usingProxy) { + // If we're using a proxy for the Workflow API, we should also go + // through the proxy for the queues API. + process.env.VERCEL_QUEUE_BASE_URL = `${baseUrl}`; + process.env.VERCEL_QUEUE_BASE_PATH = '/queues/v2/messages'; + if (config?.token) { + process.env.VERCEL_QUEUE_TOKEN = config.token; + } + if (headers) { + headers.forEach((value, key) => { + const sanitizedKey = key.replaceAll('-', '__'); + process.env[`VERCEL_QUEUE_HEADER_${sanitizedKey}`] = value; + }); + } + } + const queue = async (queueName, x, opts) => { + const encoded = MessageWrapper.encode({ + payload: x, + queueName, + }); + const sanitizedQueueName = queueName.replace(/[^A-Za-z0-9-_]/g, '-'); + const { messageId } = await send(sanitizedQueueName, encoded, opts); + return { messageId: MessageId.parse(messageId) }; + }; + const createQueueHandler = (prefix, handler) => { + return handleCallback({ + [`${prefix}*`]: { + default: async (body, meta) => { + const { payload, queueName } = MessageWrapper.parse(body); + const result = await handler(payload, { + queueName, + messageId: MessageId.parse(meta.messageId), + attempt: meta.deliveryCount, + }); + if (typeof result?.timeoutSeconds === 'number') { + // For Vercel Queue, enforce the max visibility limit: + // - When a step function throws a `RetryableError`, the retryAfter timestamp is updated and stored on the Step document + const adjustedTimeoutSeconds = Math.min(result.timeoutSeconds, VERCEL_QUEUE_MAX_VISIBILITY); + if (adjustedTimeoutSeconds !== result.timeoutSeconds) { + result.timeoutSeconds = adjustedTimeoutSeconds; + } + } + return result; + }, + }, + }); + }; + const getDeploymentId = async () => { + const deploymentId = process.env.VERCEL_DEPLOYMENT_ID; + if (!deploymentId) { + throw new Error('VERCEL_DEPLOYMENT_ID environment variable is not set'); + } + return deploymentId; + }; + return { queue, createQueueHandler, getDeploymentId }; +} + +// Helper to filter event data based on resolveData setting +function filterEventData(event, resolveData) { + if (resolveData === 'none') { + const { eventData: _eventData, ...rest } = event; + return rest; + } + return event; +} +// Would usually "EventSchema.omit({ eventData: true })" but that doesn't work +// on zod unions. Re-creating the schema manually. +const EventWithRefsSchema = z__default.object({ + eventId: z__default.string(), + runId: z__default.string(), + eventType: EventTypeSchema, + correlationId: z__default.string().optional(), + eventDataRef: z__default.any().optional(), + createdAt: z__default.coerce.date(), +}); +// Functions +async function getWorkflowRunEvents(params, config) { + const searchParams = new URLSearchParams(); + const { pagination, resolveData = DEFAULT_RESOLVE_DATA_OPTION } = params; + let runId; + let correlationId; + if ('runId' in params) { + runId = params.runId; + } + else { + correlationId = params.correlationId; + } + if (!runId && !correlationId) { + throw new Error('Either runId or correlationId must be provided'); + } + if (pagination?.limit) + searchParams.set('limit', pagination.limit.toString()); + if (pagination?.cursor) + searchParams.set('cursor', pagination.cursor); + if (pagination?.sortOrder) + searchParams.set('sortOrder', pagination.sortOrder); + if (correlationId) + searchParams.set('correlationId', correlationId); + const remoteRefBehavior = resolveData === 'none' ? 'lazy' : 'resolve'; + searchParams.set('remoteRefBehavior', remoteRefBehavior); + const queryString = searchParams.toString(); + const query = queryString ? `?${queryString}` : ''; + const endpoint = correlationId + ? `/v1/events${query}` + : `/v1/runs/${runId}/events${query}`; + const response = (await makeRequest({ + endpoint, + options: { method: 'GET' }, + config, + schema: PaginatedResponseSchema(remoteRefBehavior === 'lazy' ? EventWithRefsSchema : EventSchema), + })); + return { + ...response, + data: response.data.map((event) => filterEventData(event, resolveData)), + }; +} +async function createWorkflowRunEvent(id, data, params, config) { + const resolveData = params?.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION; + const event = await makeRequest({ + endpoint: `/v1/runs/${id}/events`, + options: { + method: 'POST', + body: JSON.stringify(data, dateToStringReplacer), + }, + config, + schema: EventSchema, + }); + return filterEventData(event, resolveData); +} + +// Helper to filter hook data based on resolveData setting +function filterHookData(hook, resolveData) { + if (resolveData === 'none') { + const { metadataRef: _metadataRef, ...rest } = hook; + return rest; + } + return hook; +} +const HookWithRefsSchema = HookSchema.omit({ + metadata: true, +}).extend({ + metadataRef: z__default.any().optional(), +}); +async function listHooks(params, config) { + const { runId, pagination, resolveData = DEFAULT_RESOLVE_DATA_OPTION, } = params; + const searchParams = new URLSearchParams(); + if (pagination?.limit) + searchParams.set('limit', pagination.limit.toString()); + if (pagination?.cursor) + searchParams.set('cursor', pagination.cursor); + if (pagination?.sortOrder) + searchParams.set('sortOrder', pagination.sortOrder); + // Map resolveData to internal RemoteRefBehavior + const remoteRefBehavior = resolveData === 'none' ? 'lazy' : 'resolve'; + searchParams.set('remoteRefBehavior', remoteRefBehavior); + if (runId) + searchParams.set('runId', runId); + const queryString = searchParams.toString(); + const endpoint = `/v1/hooks${queryString ? `?${queryString}` : ''}`; + const response = (await makeRequest({ + endpoint, + options: { method: 'GET' }, + config, + schema: PaginatedResponseSchema(remoteRefBehavior === 'lazy' ? HookWithRefsSchema : HookSchema), + })); + return { + ...response, + data: response.data.map((hook) => filterHookData(hook, resolveData)), + }; +} +async function getHook(hookId, params, config) { + const resolveData = params?.resolveData || 'all'; + const endpoint = `/v1/hooks/${hookId}`; + const hook = await makeRequest({ + endpoint, + options: { method: 'GET' }, + config, + schema: HookSchema, + }); + return filterHookData(hook, resolveData); +} +async function createHook(runId, data, config) { + return makeRequest({ + endpoint: `/v1/hooks/create`, + options: { + method: 'POST', + body: JSON.stringify({ + runId, + ...data, + }, dateToStringReplacer), + }, + config, + schema: HookSchema, + }); +} +async function getHookByToken(token, config) { + return makeRequest({ + endpoint: `/v1/hooks/by-token?token=${encodeURIComponent(token)}`, + options: { + method: 'GET', + }, + config, + schema: HookSchema, + }); +} +async function disposeHook(hookId, config) { + return makeRequest({ + endpoint: `/v1/hooks/${hookId}`, + options: { method: 'DELETE' }, + config, + schema: HookSchema, + }); +} + +/** + * Wire format schema for workflow runs coming from the backend. + * The backend returns error as a JSON string, not an object, so we need + * a schema that accepts the wire format before deserialization. + * + * This is used for validation in makeRequest(), then deserializeError() + * transforms the string into the expected StructuredError object. + */ +const WorkflowRunWireBaseSchema = WorkflowRunBaseSchema.omit({ + error: true, +}).extend({ + // Backend returns error as a JSON string, not an object + error: z$1.string().optional(), +}); +// Wire schema for resolved data (full input/output) +const WorkflowRunWireSchema = WorkflowRunWireBaseSchema; +// Wire schema for lazy mode with refs instead of data +const WorkflowRunWireWithRefsSchema = WorkflowRunWireBaseSchema.omit({ + input: true, + output: true, +}).extend({ + // We discard the results of the refs, so we don't care about the type here + inputRef: z$1.any().optional(), + outputRef: z$1.any().optional(), + input: z$1.array(z$1.any()).optional(), + output: z$1.any().optional(), +}); +// Helper to filter run data based on resolveData setting +function filterRunData(run, resolveData) { + if (resolveData === 'none') { + const { inputRef: _inputRef, outputRef: _outputRef, ...rest } = run; + const deserialized = deserializeError(rest); + return { + ...deserialized, + input: [], + output: undefined, + }; + } + return deserializeError(run); +} +// Functions +/** + * This query technically works but should be used sparingly till the backend + * uses CH to resolve this instead of scanning a dynamo table. + */ +async function listWorkflowRuns(params = {}, config) { + const { workflowName, status, pagination, resolveData = DEFAULT_RESOLVE_DATA_OPTION, } = params; + const searchParams = new URLSearchParams(); + if (workflowName) + searchParams.set('workflowName', workflowName); + if (status) + searchParams.set('status', status); + if (pagination?.limit) + searchParams.set('limit', pagination.limit.toString()); + if (pagination?.cursor) + searchParams.set('cursor', pagination.cursor); + if (pagination?.sortOrder) + searchParams.set('sortOrder', pagination.sortOrder); + // Map resolveData to internal RemoteRefBehavior + const remoteRefBehavior = resolveData === 'none' ? 'lazy' : 'resolve'; + searchParams.set('remoteRefBehavior', remoteRefBehavior); + const queryString = searchParams.toString(); + const endpoint = `/v1/runs${queryString ? `?${queryString}` : ''}`; + const response = (await makeRequest({ + endpoint, + options: { method: 'GET' }, + config, + schema: PaginatedResponseSchema(remoteRefBehavior === 'lazy' + ? WorkflowRunWireWithRefsSchema + : WorkflowRunWireSchema), + })); + return { + ...response, + data: response.data.map((run) => filterRunData(run, resolveData)), + }; +} +async function createWorkflowRun(data, config) { + const run = await makeRequest({ + endpoint: '/v1/runs/create', + options: { + method: 'POST', + body: JSON.stringify(data, dateToStringReplacer), + }, + config, + schema: WorkflowRunWireSchema, + }); + return deserializeError(run); +} +async function getWorkflowRun(id, params, config) { + const resolveData = params?.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION; + const remoteRefBehavior = resolveData === 'none' ? 'lazy' : 'resolve'; + const searchParams = new URLSearchParams(); + searchParams.set('remoteRefBehavior', remoteRefBehavior); + const queryString = searchParams.toString(); + const endpoint = `/v1/runs/${id}${queryString ? `?${queryString}` : ''}`; + try { + const run = await makeRequest({ + endpoint, + options: { method: 'GET' }, + config, + schema: (remoteRefBehavior === 'lazy' + ? WorkflowRunWireWithRefsSchema + : WorkflowRunWireSchema), + }); + return filterRunData(run, resolveData); + } + catch (error) { + if (error instanceof WorkflowAPIError && error.status === 404) { + throw new WorkflowRunNotFoundError(id); + } + throw error; + } +} +async function updateWorkflowRun(id, data, config) { + try { + const serialized = serializeError(data); + const run = await makeRequest({ + endpoint: `/v1/runs/${id}`, + options: { + method: 'PUT', + body: JSON.stringify(serialized, dateToStringReplacer), + }, + config, + schema: WorkflowRunWireSchema, + }); + return deserializeError(run); + } + catch (error) { + if (error instanceof WorkflowAPIError && error.status === 404) { + throw new WorkflowRunNotFoundError(id); + } + throw error; + } +} +async function cancelWorkflowRun(id, params, config) { + const resolveData = params?.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION; + const remoteRefBehavior = resolveData === 'none' ? 'lazy' : 'resolve'; + const searchParams = new URLSearchParams(); + searchParams.set('remoteRefBehavior', remoteRefBehavior); + const queryString = searchParams.toString(); + const endpoint = `/v1/runs/${id}/cancel${queryString ? `?${queryString}` : ''}`; + try { + const run = await makeRequest({ + endpoint, + options: { method: 'PUT' }, + config, + schema: (remoteRefBehavior === 'lazy' + ? WorkflowRunWireWithRefsSchema + : WorkflowRunWireSchema), + }); + return filterRunData(run, resolveData); + } + catch (error) { + if (error instanceof WorkflowAPIError && error.status === 404) { + throw new WorkflowRunNotFoundError(id); + } + throw error; + } +} +async function pauseWorkflowRun(id, params, config) { + const resolveData = params?.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION; + const remoteRefBehavior = resolveData === 'none' ? 'lazy' : 'resolve'; + const searchParams = new URLSearchParams(); + searchParams.set('remoteRefBehavior', remoteRefBehavior); + const queryString = searchParams.toString(); + const endpoint = `/v1/runs/${id}/pause${queryString ? `?${queryString}` : ''}`; + try { + const run = await makeRequest({ + endpoint, + options: { method: 'PUT' }, + config, + schema: (remoteRefBehavior === 'lazy' + ? WorkflowRunWireWithRefsSchema + : WorkflowRunWireSchema), + }); + return filterRunData(run, resolveData); + } + catch (error) { + if (error instanceof WorkflowAPIError && error.status === 404) { + throw new WorkflowRunNotFoundError(id); + } + throw error; + } +} +async function resumeWorkflowRun(id, params, config) { + const resolveData = params?.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION; + const remoteRefBehavior = resolveData === 'none' ? 'lazy' : 'resolve'; + const searchParams = new URLSearchParams(); + searchParams.set('remoteRefBehavior', remoteRefBehavior); + const queryString = searchParams.toString(); + const endpoint = `/v1/runs/${id}/resume${queryString ? `?${queryString}` : ''}`; + try { + const run = await makeRequest({ + endpoint, + options: { method: 'PUT' }, + config, + schema: (remoteRefBehavior === 'lazy' + ? WorkflowRunWireWithRefsSchema + : WorkflowRunWireSchema), + }); + return filterRunData(run, resolveData); + } + catch (error) { + if (error instanceof WorkflowAPIError && error.status === 404) { + throw new WorkflowRunNotFoundError(id); + } + throw error; + } +} + +/** + * Wire format schema for steps coming from the backend. + * The backend returns error as a JSON string, not an object, so we need + * a schema that accepts the wire format before deserialization. + * + * This is used for validation in makeRequest(), then deserializeStepError() + * transforms the string into the expected StructuredError object. + */ +const StepWireSchema = StepSchema.omit({ + error: true, +}).extend({ + // Backend returns error as a JSON string, not an object + error: z$1.string().optional(), +}); +// Wire schema for lazy mode with refs instead of data +const StepWireWithRefsSchema = StepWireSchema.omit({ + input: true, + output: true, +}).extend({ + // We discard the results of the refs, so we don't care about the type here + inputRef: z$1.any().optional(), + outputRef: z$1.any().optional(), + input: z$1.array(z$1.any()).optional(), + output: z$1.any().optional(), +}); +// Helper to filter step data based on resolveData setting +function filterStepData(step, resolveData) { + if (resolveData === 'none') { + const { inputRef: _inputRef, outputRef: _outputRef, ...rest } = step; + const deserialized = deserializeError(rest); + return { + ...deserialized, + input: [], + output: undefined, + }; + } + return deserializeError(step); +} +// Functions +async function listWorkflowRunSteps(params, config) { + const { runId, pagination, resolveData = DEFAULT_RESOLVE_DATA_OPTION, } = params; + const searchParams = new URLSearchParams(); + if (pagination?.cursor) + searchParams.set('cursor', pagination.cursor); + if (pagination?.limit) + searchParams.set('limit', pagination.limit.toString()); + if (pagination?.sortOrder) + searchParams.set('sortOrder', pagination.sortOrder); + // Map resolveData to internal RemoteRefBehavior + const remoteRefBehavior = resolveData === 'none' ? 'lazy' : 'resolve'; + searchParams.set('remoteRefBehavior', remoteRefBehavior); + const queryString = searchParams.toString(); + const endpoint = `/v1/runs/${runId}/steps${queryString ? `?${queryString}` : ''}`; + const response = (await makeRequest({ + endpoint, + options: { method: 'GET' }, + config, + schema: PaginatedResponseSchema(remoteRefBehavior === 'lazy' ? StepWireWithRefsSchema : StepWireSchema), + })); + return { + ...response, + data: response.data.map((step) => filterStepData(step, resolveData)), + }; +} +async function createStep(runId, data, config) { + const step = await makeRequest({ + endpoint: `/v1/runs/${runId}/steps`, + options: { + method: 'POST', + body: JSON.stringify(data, dateToStringReplacer), + }, + config, + schema: StepWireSchema, + }); + return deserializeError(step); +} +async function updateStep(runId, stepId, data, config) { + const serialized = serializeError(data); + const step = await makeRequest({ + endpoint: `/v1/runs/${runId}/steps/${stepId}`, + options: { + method: 'PUT', + body: JSON.stringify(serialized, dateToStringReplacer), + }, + config, + schema: StepWireSchema, + }); + return deserializeError(step); +} +async function getStep(runId, stepId, params, config) { + const resolveData = params?.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION; + const remoteRefBehavior = resolveData === 'none' ? 'lazy' : 'resolve'; + const searchParams = new URLSearchParams(); + searchParams.set('remoteRefBehavior', remoteRefBehavior); + const queryString = searchParams.toString(); + const endpoint = runId + ? `/v1/runs/${runId}/steps/${stepId}${queryString ? `?${queryString}` : ''}` + : `/v1/steps/${stepId}${queryString ? `?${queryString}` : ''}`; + const step = await makeRequest({ + endpoint, + options: { method: 'GET' }, + config, + schema: (remoteRefBehavior === 'lazy' + ? StepWireWithRefsSchema + : StepWireSchema), + }); + return filterStepData(step, resolveData); +} + +function createStorage(config) { + return { + // Storage interface with namespaced methods + runs: { + create: (data) => createWorkflowRun(data, config), + get: (id, params) => getWorkflowRun(id, params, config), + update: (id, data) => updateWorkflowRun(id, data, config), + list: (params) => listWorkflowRuns(params, config), + cancel: (id, params) => cancelWorkflowRun(id, params, config), + pause: (id, params) => pauseWorkflowRun(id, params, config), + resume: (id, params) => resumeWorkflowRun(id, params, config), + }, + steps: { + create: (runId, data) => createStep(runId, data, config), + get: (runId, stepId, params) => getStep(runId, stepId, params, config), + update: (runId, stepId, data) => updateStep(runId, stepId, data, config), + list: (params) => listWorkflowRunSteps(params, config), + }, + events: { + create: (runId, data, params) => createWorkflowRunEvent(runId, data, params, config), + list: (params) => getWorkflowRunEvents(params, config), + listByCorrelationId: (params) => getWorkflowRunEvents(params, config), + }, + hooks: { + create: (runId, data) => createHook(runId, data, config), + get: (hookId, params) => getHook(hookId, params, config), + getByToken: (token) => getHookByToken(token, config), + list: (params) => listHooks(params, config), + dispose: (hookId) => disposeHook(hookId, config), + }, + }; +} + +function getStreamUrl(name, httpConfig) { + return new URL(`${httpConfig.baseUrl}/v1/stream/${encodeURIComponent(name)}`); +} +function createStreamer(config) { + return { + async writeToStream(name, chunk) { + const httpConfig = await getHttpConfig(config); + await fetch(getStreamUrl(name, httpConfig), { + method: 'PUT', + body: chunk, + headers: httpConfig.headers, + duplex: 'half', + }); + }, + async closeStream(name) { + const httpConfig = await getHttpConfig(config); + httpConfig.headers.set('X-Stream-Done', 'true'); + await fetch(getStreamUrl(name, httpConfig), { + method: 'PUT', + headers: httpConfig.headers, + }); + }, + async readFromStream(name, startIndex) { + const httpConfig = await getHttpConfig(config); + const url = getStreamUrl(name, httpConfig); + if (typeof startIndex === 'number') { + url.searchParams.set('startIndex', String(startIndex)); + } + const res = await fetch(url, { headers: httpConfig.headers }); + if (!res.ok) + throw new Error(`Failed to fetch stream: ${res.status}`); + return res.body; + }, + }; +} + +function createVercelWorld(config) { + return { + ...createQueue(config), + ...createStorage(config), + ...createStreamer(config), + }; +} + +const require$1 = createRequire(join(process.cwd(), 'index.js')); +let worldCache; +let stubbedWorldCache; +function defaultWorld() { + if (process.env.VERCEL_DEPLOYMENT_ID) { + return 'vercel'; + } + return 'embedded'; +} +/** + * Create a new world instance based on environment variables. + * WORKFLOW_TARGET_WORLD is used to determine the target world. + * All other environment variables are specific to the target world + */ +const createWorld = () => { + const targetWorld = process.env.WORKFLOW_TARGET_WORLD || defaultWorld(); + if (targetWorld === 'vercel') { + return createVercelWorld({ + baseUrl: process.env.WORKFLOW_VERCEL_PROXY_URL, + token: process.env.WORKFLOW_VERCEL_AUTH_TOKEN, + projectConfig: { + environment: process.env.WORKFLOW_VERCEL_ENV, + projectId: process.env.WORKFLOW_VERCEL_PROJECT, + teamId: process.env.WORKFLOW_VERCEL_TEAM, + }, + }); + } + if (targetWorld === 'embedded') { + return createEmbeddedWorld({ + dataDir: process.env.WORKFLOW_EMBEDDED_DATA_DIR, + }); + } + const mod = require$1(targetWorld); + if (typeof mod === 'function') { + return mod(); + } + else if (typeof mod.default === 'function') { + return mod.default(); + } + else if (typeof mod.createWorld === 'function') { + return mod.createWorld(); + } + throw new Error(`Invalid target world module: ${targetWorld}, must export a default function or createWorld function that returns a World instance.`); +}; +/** + * Some functions from the world are needed at build time, but we do NOT want + * to cache the world in those instances for general use, since we don't have + * the correct environment variables set yet. This is a safe function to + * call at build time, that only gives access to non-environment-bound world + * functions. The only binding value should be the target world. + * Once we migrate to a file-based configuration (workflow.config.ts), we should + * be able to re-combine getWorld and getWorldHandlers into one singleton. + */ +const getWorldHandlers = () => { + if (stubbedWorldCache) { + return stubbedWorldCache; + } + const _world = createWorld(); + stubbedWorldCache = _world; + return { + createQueueHandler: _world.createQueueHandler, + }; +}; +const getWorld = () => { + if (worldCache) { + return worldCache; + } + worldCache = createWorld(); + return worldCache; +}; + +// OpenTelemetry trace context for distributed tracing +const TraceCarrierSchema = z$1.record(z$1.string(), z$1.string()); +const WorkflowInvokePayloadSchema = z$1.object({ + runId: z$1.string(), + traceCarrier: TraceCarrierSchema.optional(), +}); +const StepInvokePayloadSchema = z$1.object({ + workflowName: z$1.string(), + workflowRunId: z$1.string(), + workflowStartedAt: z$1.number(), + stepId: z$1.string(), + traceCarrier: TraceCarrierSchema.optional(), +}); + +const WORKFLOW_USE_STEP = Symbol.for('WORKFLOW_USE_STEP'); +const WORKFLOW_CREATE_HOOK = Symbol.for('WORKFLOW_CREATE_HOOK'); +const WORKFLOW_SLEEP = Symbol.for('WORKFLOW_SLEEP'); +const WORKFLOW_GET_STREAM_ID = Symbol.for('WORKFLOW_GET_STREAM_ID'); +const STREAM_NAME_SYMBOL = Symbol.for('WORKFLOW_STREAM_NAME'); +const STREAM_TYPE_SYMBOL = Symbol.for('WORKFLOW_STREAM_TYPE'); +const BODY_INIT_SYMBOL = Symbol.for('BODY_INIT'); +const WEBHOOK_RESPONSE_WRITABLE = Symbol.for('WEBHOOK_RESPONSE_WRITABLE'); +const STEP_FUNCTION_NAME_SYMBOL = Symbol.for('WORKFLOW_STEP_FUNCTION_NAME'); + +/** + * Detect if a readable stream is a byte stream. + * + * @param stream + * @returns `"bytes"` if the stream is a byte stream, `undefined` otherwise + */ +function getStreamType(stream) { + try { + const reader = stream.getReader({ mode: 'byob' }); + reader.releaseLock(); + return 'bytes'; + } + catch { } +} +function getSerializeStream(reducers) { + const encoder = new TextEncoder(); + const stream = new TransformStream({ + transform(chunk, controller) { + try { + const serialized = devalue.stringify(chunk, reducers); + controller.enqueue(encoder.encode(`${serialized}\n`)); + } + catch (error) { + controller.error(new WorkflowRuntimeError("Failed to serialize stream chunk. Ensure you're passing serializable types (plain objects, arrays, primitives, Date, RegExp, Map, Set).", { slug: 'serialization-failed', cause: error })); + } + }, + }); + return stream; +} +function getDeserializeStream(revivers) { + const decoder = new TextDecoder(); + let buffer = ''; + const stream = new TransformStream({ + transform(chunk, controller) { + // Append new chunk to buffer + buffer += decoder.decode(chunk, { stream: true }); + // Process all complete lines + while (true) { + const newlineIndex = buffer.indexOf('\n'); + if (newlineIndex === -1) + break; + const line = buffer.slice(0, newlineIndex); + buffer = buffer.slice(newlineIndex + 1); + if (line.length > 0) { + const obj = devalue.parse(line, revivers); + controller.enqueue(obj); + } + } + }, + flush(controller) { + // Process any remaining data in the buffer at the end of the stream + if (buffer && buffer.length > 0) { + const obj = devalue.parse(buffer, revivers); + controller.enqueue(obj); + } + }, + }); + return stream; +} +class WorkflowServerReadableStream extends ReadableStream { + #reader; + constructor(name, startIndex) { + if (typeof name !== 'string' || name.length === 0) { + throw new Error(`"name" is required, got "${name}"`); + } + super({ + // @ts-expect-error Not sure why TypeScript is complaining about this + type: 'bytes', + pull: async (controller) => { + let reader = this.#reader; + if (!reader) { + const world = getWorld(); + const stream = await world.readFromStream(name, startIndex); + reader = this.#reader = stream.getReader(); + } + if (!reader) { + controller.error(new Error('Failed to get reader')); + return; + } + const result = await reader.read(); + if (result.done) { + this.#reader = undefined; + controller.close(); + } + else { + controller.enqueue(result.value); + } + }, + }); + } +} +class WorkflowServerWritableStream extends WritableStream { + constructor(name) { + if (typeof name !== 'string' || name.length === 0) { + throw new Error(`"name" is required, got "${name}"`); + } + const world = getWorld(); + super({ + async write(chunk) { + await world.writeToStream(name, chunk); + }, + async close() { + await world.closeStream(name); + }, + }); + } +} +function revive(str) { + // biome-ignore lint/security/noGlobalEval: Eval is safe here - we are only passing value from `devalue.stringify()` + // biome-ignore lint/complexity/noCommaOperator: This is how you do global scope eval + return (0, eval)(`(${str})`); +} +function getCommonReducers(global = globalThis) { + const abToBase64 = (value, offset, length) => { + // Avoid returning falsy value for zero-length buffers + if (length === 0) + return '.'; + return Buffer.from(value, offset, length).toString('base64'); + }; + const viewToBase64 = (value) => abToBase64(value.buffer, value.byteOffset, value.byteLength); + return { + ArrayBuffer: (value) => value instanceof global.ArrayBuffer && + abToBase64(value, 0, value.byteLength), + BigInt: (value) => typeof value === 'bigint' && value.toString(), + BigInt64Array: (value) => value instanceof global.BigInt64Array && viewToBase64(value), + BigUint64Array: (value) => value instanceof global.BigUint64Array && viewToBase64(value), + Date: (value) => { + if (!(value instanceof global.Date)) + return false; + const valid = !Number.isNaN(value.getDate()); + // Note: "." is to avoid returning a falsy value when the date is invalid + return valid ? value.toISOString() : '.'; + }, + Error: (value) => { + if (!(value instanceof global.Error)) + return false; + return { + name: value.name, + message: value.message, + stack: value.stack, + }; + }, + Float32Array: (value) => value instanceof global.Float32Array && viewToBase64(value), + Float64Array: (value) => value instanceof global.Float64Array && viewToBase64(value), + Headers: (value) => value instanceof global.Headers && Array.from(value), + Int8Array: (value) => value instanceof global.Int8Array && viewToBase64(value), + Int16Array: (value) => value instanceof global.Int16Array && viewToBase64(value), + Int32Array: (value) => value instanceof global.Int32Array && viewToBase64(value), + Map: (value) => value instanceof global.Map && Array.from(value), + RegExp: (value) => value instanceof global.RegExp && { + source: value.source, + flags: value.flags, + }, + Request: (value) => { + if (!(value instanceof global.Request)) + return false; + const data = { + method: value.method, + url: value.url, + headers: value.headers, + body: value.body, + duplex: value.duplex, + }; + const responseWritable = value[WEBHOOK_RESPONSE_WRITABLE]; + if (responseWritable) { + data.responseWritable = responseWritable; + } + return data; + }, + Response: (value) => { + if (!(value instanceof global.Response)) + return false; + return { + type: value.type, + url: value.url, + status: value.status, + statusText: value.statusText, + headers: value.headers, + body: value.body, + redirected: value.redirected, + }; + }, + Set: (value) => value instanceof global.Set && Array.from(value), + StepFunction: (value) => { + if (typeof value !== 'function') + return false; + const stepName = value[STEP_FUNCTION_NAME_SYMBOL]; + return typeof stepName === 'string' ? stepName : false; + }, + URL: (value) => value instanceof global.URL && value.href, + URLSearchParams: (value) => { + if (!(value instanceof global.URLSearchParams)) + return false; + // Avoid returning a falsy value when the URLSearchParams is empty + if (value.size === 0) + return '.'; + return String(value); + }, + Uint8Array: (value) => value instanceof global.Uint8Array && viewToBase64(value), + Uint8ClampedArray: (value) => value instanceof global.Uint8ClampedArray && viewToBase64(value), + Uint16Array: (value) => value instanceof global.Uint16Array && viewToBase64(value), + Uint32Array: (value) => value instanceof global.Uint32Array && viewToBase64(value), + }; +} +/** + * Reducers for serialization boundary from the client side, passing arguments + * to the workflow handler. + * + * @param global + * @param ops + * @returns + */ +function getExternalReducers(global = globalThis, ops) { + return { + ...getCommonReducers(global), + ReadableStream: (value) => { + if (!(value instanceof global.ReadableStream)) + return false; + // Stream must not be locked when passing across execution boundary + if (value.locked) { + throw new Error('ReadableStream is locked'); + } + const name = global.crypto.randomUUID(); + const type = getStreamType(value); + const writable = new WorkflowServerWritableStream(name); + if (type === 'bytes') { + ops.push(value.pipeTo(writable)); + } + else { + ops.push(value + .pipeThrough(getSerializeStream(getExternalReducers(global, ops))) + .pipeTo(writable)); + } + const s = { name }; + if (type) + s.type = type; + return s; + }, + WritableStream: (value) => { + if (!(value instanceof global.WritableStream)) + return false; + const name = global.crypto.randomUUID(); + ops.push(new WorkflowServerReadableStream(name) + .pipeThrough(getDeserializeStream(getExternalRevivers(global, ops))) + .pipeTo(value)); + return { name }; + }, + }; +} +/** + * Reducers for serialization boundary from within the workflow execution + * environment, passing return value to the client side and into step arguments. + * + * @param global + * @returns + */ +function getWorkflowReducers(global = globalThis) { + return { + ...getCommonReducers(global), + // Readable/Writable streams from within the workflow execution environment + // are simply "handles" that can be passed around to other steps. + ReadableStream: (value) => { + if (!(value instanceof global.ReadableStream)) + return false; + // Check if this is a fake stream storing BodyInit from Request/Response constructor + const bodyInit = value[BODY_INIT_SYMBOL]; + if (bodyInit !== undefined) { + // This is a fake stream - serialize the BodyInit directly + // devalue will handle serializing strings, Uint8Array, etc. + return { bodyInit }; + } + const name = value[STREAM_NAME_SYMBOL]; + if (!name) { + throw new Error('ReadableStream `name` is not set'); + } + const s = { name }; + const type = value[STREAM_TYPE_SYMBOL]; + if (type) + s.type = type; + return s; + }, + WritableStream: (value) => { + if (!(value instanceof global.WritableStream)) + return false; + const name = value[STREAM_NAME_SYMBOL]; + if (!name) { + throw new Error('WritableStream `name` is not set'); + } + return { name }; + }, + }; +} +/** + * Reducers for serialization boundary from within the step execution + * environment, passing return value to the workflow handler. + * + * @param global + * @param ops + * @returns + */ +function getStepReducers(global = globalThis, ops) { + return { + ...getCommonReducers(global), + ReadableStream: (value) => { + if (!(value instanceof global.ReadableStream)) + return false; + // Stream must not be locked when passing across execution boundary + if (value.locked) { + throw new Error('ReadableStream is locked'); + } + // Check if the stream already has the name symbol set, in which case + // it's already being sunk to the server and we can just return the + // name and type. + let name = value[STREAM_NAME_SYMBOL]; + let type = value[STREAM_TYPE_SYMBOL]; + if (!name) { + name = global.crypto.randomUUID(); + type = getStreamType(value); + const writable = new WorkflowServerWritableStream(name); + if (type === 'bytes') { + ops.push(value.pipeTo(writable)); + } + else { + ops.push(value + .pipeThrough(getSerializeStream(getStepReducers(global, ops))) + .pipeTo(writable)); + } + } + const s = { name }; + if (type) + s.type = type; + return s; + }, + WritableStream: (value) => { + if (!(value instanceof global.WritableStream)) + return false; + let name = value[STREAM_NAME_SYMBOL]; + if (!name) { + name = global.crypto.randomUUID(); + ops.push(new WorkflowServerReadableStream(name) + .pipeThrough(getDeserializeStream(getStepRevivers(global, ops))) + .pipeTo(value)); + } + return { name }; + }, + }; +} +function getCommonRevivers(global = globalThis) { + function reviveArrayBuffer(value) { + // Handle sentinel value for zero-length buffers + const base64 = value === '.' ? '' : value; + const buffer = Buffer.from(base64, 'base64'); + const arrayBuffer = new global.ArrayBuffer(buffer.length); + const uint8Array = new global.Uint8Array(arrayBuffer); + uint8Array.set(buffer); + return arrayBuffer; + } + return { + ArrayBuffer: reviveArrayBuffer, + BigInt: (value) => global.BigInt(value), + BigInt64Array: (value) => { + const ab = reviveArrayBuffer(value); + return new global.BigInt64Array(ab); + }, + BigUint64Array: (value) => { + const ab = reviveArrayBuffer(value); + return new global.BigUint64Array(ab); + }, + Date: (value) => new global.Date(value), + Error: (value) => { + const error = new global.Error(value.message); + error.name = value.name; + error.stack = value.stack; + return error; + }, + Float32Array: (value) => { + const ab = reviveArrayBuffer(value); + return new global.Float32Array(ab); + }, + Float64Array: (value) => { + const ab = reviveArrayBuffer(value); + return new global.Float64Array(ab); + }, + Headers: (value) => new global.Headers(value), + Int8Array: (value) => { + const ab = reviveArrayBuffer(value); + return new global.Int8Array(ab); + }, + Int16Array: (value) => { + const ab = reviveArrayBuffer(value); + return new global.Int16Array(ab); + }, + Int32Array: (value) => { + const ab = reviveArrayBuffer(value); + return new global.Int32Array(ab); + }, + Map: (value) => new global.Map(value), + RegExp: (value) => new global.RegExp(value.source, value.flags), + Set: (value) => new global.Set(value), + StepFunction: (value) => { + const stepFn = getStepFunction(value); + if (!stepFn) { + throw new Error(`Step function "${value}" not found. Make sure the step function is registered.`); + } + return stepFn; + }, + URL: (value) => new global.URL(value), + URLSearchParams: (value) => new global.URLSearchParams(value === '.' ? '' : value), + Uint8Array: (value) => { + const ab = reviveArrayBuffer(value); + return new global.Uint8Array(ab); + }, + Uint8ClampedArray: (value) => { + const ab = reviveArrayBuffer(value); + return new global.Uint8ClampedArray(ab); + }, + Uint16Array: (value) => { + const ab = reviveArrayBuffer(value); + return new global.Uint16Array(ab); + }, + Uint32Array: (value) => { + const ab = reviveArrayBuffer(value); + return new global.Uint32Array(ab); + }, + }; +} +/** + * Revivers for deserialization boundary from the client side, + * receiving the return value from the workflow handler. + * + * @param global + * @param ops + */ +function getExternalRevivers(global = globalThis, ops) { + return { + ...getCommonRevivers(global), + Request: (value) => { + return new global.Request(value.url, { + method: value.method, + headers: new global.Headers(value.headers), + body: value.body, + duplex: value.duplex, + }); + }, + Response: (value) => { + // Note: Response constructor only accepts status, statusText, and headers + // The type, url, and redirected properties are read-only and set by the constructor + return new global.Response(value.body, { + status: value.status, + statusText: value.statusText, + headers: new global.Headers(value.headers), + }); + }, + ReadableStream: (value) => { + // If this has bodyInit, it came from a Response constructor + // Convert it to a REAL stream now that we're outside the workflow + if ('bodyInit' in value) { + const bodyInit = value.bodyInit; + // Use the native Response constructor to properly convert BodyInit to ReadableStream + const response = new global.Response(bodyInit); + return response.body; + } + const readable = new WorkflowServerReadableStream(value.name, value.startIndex); + if (value.type === 'bytes') { + return readable; + } + else { + const transform = getDeserializeStream(getExternalRevivers(global, ops)); + ops.push(readable.pipeTo(transform.writable)); + return transform.readable; + } + }, + WritableStream: (value) => { + const serialize = getSerializeStream(getExternalReducers(global, ops)); + ops.push(serialize.readable.pipeTo(new WorkflowServerWritableStream(value.name))); + return serialize.writable; + }, + }; +} +/** + * Revivers for deserialization boundary from within the workflow execution + * environment, receiving arguments from the client side, and return values + * from the steps. + * + * @param global + * @returns + */ +function getWorkflowRevivers(global = globalThis) { + return { + ...getCommonRevivers(global), + Request: (value) => { + Object.setPrototypeOf(value, global.Request.prototype); + const responseWritable = value.responseWritable; + if (responseWritable) { + value[WEBHOOK_RESPONSE_WRITABLE] = responseWritable; + delete value.responseWritable; + value.respondWith = () => { + throw new Error('`respondWith()` must be called from within a step function'); + }; + } + return value; + }, + Response: (value) => { + Object.setPrototypeOf(value, global.Response.prototype); + return value; + }, + ReadableStream: (value) => { + // Check if this is a BodyInit that should be wrapped in a fake stream + if ('bodyInit' in value) { + // Recreate the fake stream with the BodyInit + return Object.create(global.ReadableStream.prototype, { + [BODY_INIT_SYMBOL]: { + value: value.bodyInit, + writable: false, + }, + }); + } + // Regular stream handling + return Object.create(global.ReadableStream.prototype, { + [STREAM_NAME_SYMBOL]: { + value: value.name, + writable: false, + }, + [STREAM_TYPE_SYMBOL]: { + value: value.type, + writable: false, + }, + }); + }, + WritableStream: (value) => { + return Object.create(global.WritableStream.prototype, { + [STREAM_NAME_SYMBOL]: { + value: value.name, + writable: false, + }, + }); + }, + }; +} +/** + * Revivers for deserialization boundary from within the step execution + * environment, receiving arguments from the workflow handler. + * + * @param global + * @param ops + * @returns + */ +function getStepRevivers(global = globalThis, ops) { + return { + ...getCommonRevivers(global), + Request: (value) => { + const responseWritable = value.responseWritable; + const request = new global.Request(value.url, { + method: value.method, + headers: new global.Headers(value.headers), + body: value.body, + duplex: value.duplex, + }); + if (responseWritable) { + request.respondWith = async (response) => { + const writer = responseWritable.getWriter(); + await writer.write(response); + await writer.close(); + }; + } + return request; + }, + Response: (value) => { + // Note: Response constructor only accepts status, statusText, and headers + // The type, url, and redirected properties are read-only and set by the constructor + return new global.Response(value.body, { + status: value.status, + statusText: value.statusText, + headers: new global.Headers(value.headers), + }); + }, + ReadableStream: (value) => { + // If this has bodyInit, it came from a Response constructor + // Convert it to a REAL stream now that we're in the step environment + if ('bodyInit' in value) { + const bodyInit = value.bodyInit; + // Use the native Response constructor to properly convert BodyInit to ReadableStream + const response = new global.Response(bodyInit); + return response.body; + } + const readable = new WorkflowServerReadableStream(value.name); + if (value.type === 'bytes') { + return readable; + } + else { + const transform = getDeserializeStream(getStepRevivers(global, ops)); + ops.push(readable.pipeTo(transform.writable)); + return transform.readable; + } + }, + WritableStream: (value) => { + const serialize = getSerializeStream(getStepReducers(global, ops)); + ops.push(serialize.readable.pipeTo(new WorkflowServerWritableStream(value.name))); + return serialize.writable; + }, + }; +} +/** + * Called from the `start()` function to serialize the workflow arguments + * into a format that can be saved to the database and then hydrated from + * within the workflow execution environment. + * + * @param value + * @param global + * @returns The dehydrated value, ready to be inserted into the database + */ +function dehydrateWorkflowArguments(value, ops, global = globalThis) { + try { + const str = devalue.stringify(value, getExternalReducers(global, ops)); + return revive(str); + } + catch (error) { + throw new WorkflowRuntimeError(`Failed to serialize workflow arguments. Ensure you're passing serializable types (plain objects, arrays, primitives, Date, RegExp, Map, Set).`, { slug: 'serialization-failed', cause: error }); + } +} +/** + * Called from workflow execution environment to hydrate the workflow + * arguments from the database at the start of workflow execution. + * + * @param value + * @param ops + * @param global + * @returns The hydrated value + */ +function hydrateWorkflowArguments(value, global = globalThis, extraRevivers = {}) { + const obj = devalue.unflatten(value, { + ...getWorkflowRevivers(global), + ...extraRevivers, + }); + return obj; +} +/** + * Called at the end of a completed workflow execution to serialize the + * return value into a format that can be saved to the database. + * + * @param value + * @param global + * @returns The dehydrated value, ready to be inserted into the database + */ +function dehydrateWorkflowReturnValue(value, global = globalThis) { + try { + const str = devalue.stringify(value, getWorkflowReducers(global)); + return revive(str); + } + catch (error) { + throw new WorkflowRuntimeError(`Failed to serialize workflow return value. Ensure you're returning serializable types (plain objects, arrays, primitives, Date, RegExp, Map, Set).`, { slug: 'serialization-failed', cause: error }); + } +} +/** + * Called from the client side (i.e. the execution environment where + * the workflow run was initiated from) to hydrate the workflow + * return value of a completed workflow run. + * + * @param value + * @param global + * @returns The hydrated return value, ready to be consumed by the client + */ +function hydrateWorkflowReturnValue(value, ops, global = globalThis, extraRevivers = {}) { + const obj = devalue.unflatten(value, { + ...getExternalRevivers(global, ops), + ...extraRevivers, + }); + return obj; +} +/** + * Called from the workflow handler when a step is being created. + * Dehydrates values from within the workflow execution environment + * into a format that can be saved to the database. + * + * @param value + * @param global + * @returns The dehydrated value, ready to be inserted into the database + */ +function dehydrateStepArguments(value, global) { + try { + const str = devalue.stringify(value, getWorkflowReducers(global)); + return revive(str); + } + catch (error) { + throw new WorkflowRuntimeError(`Failed to serialize step arguments. Ensure you're passing serializable types (plain objects, arrays, primitives, Date, RegExp, Map, Set).`, { slug: 'serialization-failed', cause: error }); + } +} +/** + * Called from the step handler to hydrate the arguments of a step + * from the database at the start of the step execution. + * + * @param value + * @param global + * @returns The hydrated value, ready to be consumed by the step user-code function + */ +function hydrateStepArguments(value, ops, global = globalThis, extraRevivers = {}) { + const obj = devalue.unflatten(value, { + ...getStepRevivers(global, ops), + ...extraRevivers, + }); + return obj; +} +/** + * Called from the step handler when a step has completed. + * Dehydrates values from within the step execution environment + * into a format that can be saved to the database. + * + * @param value + * @param global + * @returns The dehydrated value, ready to be inserted into the database + */ +function dehydrateStepReturnValue(value, ops, global = globalThis) { + try { + const str = devalue.stringify(value, getStepReducers(global, ops)); + return revive(str); + } + catch (error) { + throw new WorkflowRuntimeError(`Failed to serialize step return value. Ensure you're returning serializable types (plain objects, arrays, primitives, Date, RegExp, Map, Set).`, { slug: 'serialization-failed', cause: error }); + } +} +/** + * Called from the workflow handler when replaying the event log of a `step_completed` event. + * Hydrates the return value of a step from the database. + * + * @param value + * @param global + * @returns The hydrated return value of a step, ready to be consumed by the workflow handler + */ +function hydrateStepReturnValue(value, global = globalThis, extraRevivers = {}) { + const obj = devalue.unflatten(value, { + ...getWorkflowRevivers(global), + ...extraRevivers, + }); + return obj; +} + +/** + * OpenTelemetry semantic conventions for Vercel Workflow telemetry. + * + * This module provides standardized telemetry attributes following OpenTelemetry semantic conventions + * for instrumenting workflow execution, step processing, and related operations. Each exported function + * creates a properly formatted attribute object that can be used with OpenTelemetry spans. + * + * The semantic conventions are organized into several categories: + * - **Workflow attributes**: Track workflow lifecycle, status, and metadata + * - **Step attributes**: Monitor individual step execution, retries, and results + * - **Queue attributes**: Instrument message queue operations + * - **Deployment attributes**: Capture deployment environment information + * + * All attribute functions are type-safe and leverage existing backend types to ensure + * consistency between telemetry data and actual system state. + * + * @example + * ```typescript + * import * as Attribute from './telemetry/semantic-conventions.js'; + * + * // Set workflow attributes on a span + * span.setAttributes({ + * ...Attribute.WorkflowName('my-workflow'), + * ...Attribute.WorkflowOperation('start'), + * ...Attribute.WorkflowRunStatus('running'), + * }); + * + * // Set step attributes + * span.setAttributes({ + * ...Attribute.StepName('process-data'), + * ...Attribute.StepStatus('completed'), + * ...Attribute.StepAttempt(1), + * }); + * ``` + * + * @see {@link https://opentelemetry.io/docs/specs/semconv/} OpenTelemetry Semantic Conventions + * @packageDocumentation + */ +/** + * Creates a semantic convention function that returns an attribute object. + * @param name - The attribute name following OpenTelemetry semantic conventions + * @returns A function that takes a value and returns an attribute object + */ +function SemanticConvention(name) { + return (value) => ({ [name]: value }); +} +// Workflow attributes +/** The name of the workflow being executed */ +const WorkflowName = SemanticConvention('workflow.name'); +/** The operation being performed on the workflow */ +const WorkflowOperation = SemanticConvention('workflow.operation'); +/** Unique identifier for a specific workflow run instance */ +const WorkflowRunId = SemanticConvention('workflow.run.id'); +/** Current status of the workflow run */ +const WorkflowRunStatus = SemanticConvention('workflow.run.status'); +/** Timestamp when the workflow execution started (Unix timestamp) */ +const WorkflowStartedAt = SemanticConvention('workflow.started_at'); +/** Number of events processed during workflow execution */ +const WorkflowEventsCount = SemanticConvention('workflow.events.count'); +/** Number of arguments passed to the workflow */ +const WorkflowArgumentsCount = SemanticConvention('workflow.arguments.count'); +/** Type of the workflow result */ +const WorkflowResultType = SemanticConvention('workflow.result.type'); +/** Whether trace context was propagated to this workflow execution */ +const WorkflowTracePropagated = SemanticConvention('workflow.trace.propagated'); +/** Name of the error that caused workflow failure */ +const WorkflowErrorName = SemanticConvention('workflow.error.name'); +/** Error message when workflow fails */ +const WorkflowErrorMessage = SemanticConvention('workflow.error.message'); +/** Number of steps created during workflow execution */ +const WorkflowStepsCreated = SemanticConvention('workflow.steps.created'); +// Step attributes +/** Name of the step function being executed */ +const StepName = SemanticConvention('step.name'); +/** Unique identifier for the step instance */ +const StepId = SemanticConvention('step.id'); +/** Current attempt number for step execution (starts at 1) */ +const StepAttempt = SemanticConvention('step.attempt'); +/** Current status of the step */ +const StepStatus = SemanticConvention('step.status'); +/** Maximum number of retries allowed for this step */ +const StepMaxRetries = SemanticConvention('step.max_retries'); +/** Whether trace context was propagated to this step execution */ +const StepTracePropagated = SemanticConvention('step.trace.propagated'); +/** Whether the step was skipped during execution */ +const StepSkipped = SemanticConvention('step.skipped'); +/** Reason why the step was skipped */ +const StepSkipReason = SemanticConvention('step.skip_reason'); +/** Number of arguments passed to the step function */ +const StepArgumentsCount = SemanticConvention('step.arguments.count'); +/** Type of the step result */ +const StepResultType = SemanticConvention('step.result.type'); +/** Name of the error that caused step failure */ +const StepErrorName = SemanticConvention('step.error.name'); +/** Error message when step fails */ +const StepErrorMessage = SemanticConvention('step.error.message'); +/** Whether the step failed with a fatal error (no retries) */ +const StepFatalError = SemanticConvention('step.fatal_error'); +/** Whether all retry attempts have been exhausted */ +const StepRetryExhausted = SemanticConvention('step.retry.exhausted'); +/** Number of seconds to wait before next retry attempt */ +const StepRetryTimeoutSeconds = SemanticConvention('step.retry.timeout_seconds'); +/** Whether the step will be retried after this failure */ +const StepRetryWillRetry = SemanticConvention('step.retry.will_retry'); +// Queue attributes +/** Name of the queue being used for message processing */ +const QueueName = SemanticConvention('queue.name'); +// Deployment attributes +/** Unique identifier for the deployment environment */ +const DeploymentId = SemanticConvention('deployment.id'); +// Hook attributes +/** Token identifying a specific hook */ +const HookToken = SemanticConvention('workflow.hook.token'); +/** Unique identifier for a hook instance */ +const HookId = SemanticConvention('workflow.hook.id'); +/** Whether a hook was found by its token */ +const HookFound = SemanticConvention('workflow.hook.found'); + +/** + * Builds a workflow suspension log message based on the counts of steps, hooks, and waits. + * @param runId - The workflow run ID + * @param stepCount - Number of steps to be enqueued + * @param hookCount - Number of hooks to be enqueued + * @param waitCount - Number of waits to be enqueued + * @returns The formatted log message or null if all counts are 0 + */ +function buildWorkflowSuspensionMessage(runId, stepCount, hookCount, waitCount) { + if (stepCount === 0 && hookCount === 0 && waitCount === 0) { + return null; + } + const parts = []; + if (stepCount > 0) { + parts.push(`${stepCount} ${stepCount === 1 ? 'step' : 'steps'}`); + } + if (hookCount > 0) { + parts.push(`${hookCount} ${hookCount === 1 ? 'hook' : 'hooks'}`); + } + if (waitCount > 0) { + parts.push(`${waitCount} ${waitCount === 1 ? 'timer' : 'timers'}`); + } + const resumeMsgParts = []; + if (stepCount > 0) { + resumeMsgParts.push('steps are completed'); + } + if (hookCount > 0) { + resumeMsgParts.push('hooks are received'); + } + if (waitCount > 0) { + resumeMsgParts.push('timers have elapsed'); + } + const resumeMsg = resumeMsgParts.join(' and '); + return `[Workflows] "${runId}" - ${parts.join(' and ')} to be enqueued\n Workflow will suspend and resume when ${resumeMsg}`; +} +/** + * Generates a stream ID for a workflow run. + * User-defined streams include a "user" segment for isolation from future system-defined streams. + * Namespaces are base64-encoded to handle characters not allowed in Redis key names. + * + * @param runId - The workflow run ID + * @param namespace - Optional namespace for the stream + * @returns The stream ID in format: `strm_{ULID}_user_{base64(namespace)?}` + */ +function getWorkflowRunStreamId(runId, namespace) { + const streamId = `${runId.replace('wrun_', 'strm_')}_user`; + if (!namespace) { + return streamId; + } + // Base64 encode the namespace to handle special characters that may not be allowed in Redis keys + const encodedNamespace = Buffer.from(namespace, 'utf-8').toString('base64url'); + return `${streamId}_${encodedNamespace}`; +} +/** + * A small wrapper around `waitUntil` that also returns + * the result of the awaited promise. + */ +async function waitedUntil(fn) { + const result = fn(); + functionsExports.waitUntil(result); + return result; +} + +var EventConsumerResult; +(function (EventConsumerResult) { + /** + * Callback consumed the event, but should not be removed from the callbacks list + */ + EventConsumerResult[EventConsumerResult["Consumed"] = 0] = "Consumed"; + /** + * Callback did not consume the event, so it should be passed to the next callback + */ + EventConsumerResult[EventConsumerResult["NotConsumed"] = 1] = "NotConsumed"; + /** + * Callback consumed the event, and should be removed from the callbacks list + */ + EventConsumerResult[EventConsumerResult["Finished"] = 2] = "Finished"; +})(EventConsumerResult || (EventConsumerResult = {})); +class EventsConsumer { + eventIndex; + events = []; + callbacks = []; + constructor(events) { + this.events = events; + this.eventIndex = 0; + eventsLogger.debug('EventsConsumer initialized', { events }); + } + /** + * Registers a callback function to be called after an event has been consumed + * by a different callback. The callback can return: + * - `EventConsumerResult.Consumed` the event is considered consumed and will not be passed to any other callback, but the callback will remain in the callbacks list + * - `EventConsumerResult.NotConsumed` the event is passed to the next callback + * - `EventConsumerResult.Finished` the event is considered consumed and the callback is removed from the callbacks list + * + * @param fn - The callback function to register. + */ + subscribe(fn) { + this.callbacks.push(fn); + process.nextTick(this.consume); + } + consume = () => { + const currentEvent = this.events[this.eventIndex] ?? null; + for (let i = 0; i < this.callbacks.length; i++) { + const callback = this.callbacks[i]; + let handled = EventConsumerResult.NotConsumed; + try { + handled = callback(currentEvent); + } + catch (error) { + eventsLogger.error('EventConsumer callback threw an error', { error }); + // Hopefully shouldn't happen, but we don't want to block the workflow + console.error('EventConsumer callback threw an error', error); + } + eventsLogger.debug('EventConsumer callback result', { + handled: EventConsumerResult[handled], + eventIndex: this.eventIndex, + eventId: currentEvent?.eventId, + }); + if (handled === EventConsumerResult.Consumed || + handled === EventConsumerResult.Finished) { + // consumer handled this event, so increase the event index + this.eventIndex++; + // remove the callback if it has finished + if (handled === EventConsumerResult.Finished) { + this.callbacks.splice(i, 1); + } + // continue to the next event + process.nextTick(this.consume); + return; + } + } + }; +} + +var alea$1 = {exports: {}}; + +var alea = alea$1.exports; + +var hasRequiredAlea; + +function requireAlea () { + if (hasRequiredAlea) return alea$1.exports; + hasRequiredAlea = 1; + (function (module) { + // A port of an algorithm by Johannes Baagøe , 2010 + // http://baagoe.com/en/RandomMusings/javascript/ + // https://github.com/nquinlan/better-random-numbers-for-javascript-mirror + // Original work is under MIT license - + + // Copyright (C) 2010 by Johannes Baagøe + // + // Permission is hereby granted, free of charge, to any person obtaining a copy + // of this software and associated documentation files (the "Software"), to deal + // in the Software without restriction, including without limitation the rights + // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + // copies of the Software, and to permit persons to whom the Software is + // furnished to do so, subject to the following conditions: + // + // The above copyright notice and this permission notice shall be included in + // all copies or substantial portions of the Software. + // + // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + // THE SOFTWARE. + + + + (function(global, module, define) { + + function Alea(seed) { + var me = this, mash = Mash(); + + me.next = function() { + var t = 2091639 * me.s0 + me.c * 2.3283064365386963e-10; // 2^-32 + me.s0 = me.s1; + me.s1 = me.s2; + return me.s2 = t - (me.c = t | 0); + }; + + // Apply the seeding algorithm from Baagoe. + me.c = 1; + me.s0 = mash(' '); + me.s1 = mash(' '); + me.s2 = mash(' '); + me.s0 -= mash(seed); + if (me.s0 < 0) { me.s0 += 1; } + me.s1 -= mash(seed); + if (me.s1 < 0) { me.s1 += 1; } + me.s2 -= mash(seed); + if (me.s2 < 0) { me.s2 += 1; } + mash = null; + } + + function copy(f, t) { + t.c = f.c; + t.s0 = f.s0; + t.s1 = f.s1; + t.s2 = f.s2; + return t; + } + + function impl(seed, opts) { + var xg = new Alea(seed), + state = opts && opts.state, + prng = xg.next; + prng.int32 = function() { return (xg.next() * 0x100000000) | 0; }; + prng.double = function() { + return prng() + (prng() * 0x200000 | 0) * 1.1102230246251565e-16; // 2^-53 + }; + prng.quick = prng; + if (state) { + if (typeof(state) == 'object') copy(state, xg); + prng.state = function() { return copy(xg, {}); }; + } + return prng; + } + + function Mash() { + var n = 0xefc8249d; + + var mash = function(data) { + data = String(data); + for (var i = 0; i < data.length; i++) { + n += data.charCodeAt(i); + var h = 0.02519603282416938 * n; + n = h >>> 0; + h -= n; + h *= n; + n = h >>> 0; + h -= n; + n += h * 0x100000000; // 2^32 + } + return (n >>> 0) * 2.3283064365386963e-10; // 2^-32 + }; + + return mash; + } + + + if (module && module.exports) { + module.exports = impl; + } else { + this.alea = impl; + } + + })( + alea, + module); + } (alea$1)); + return alea$1.exports; +} + +var xor128$1 = {exports: {}}; + +var xor128 = xor128$1.exports; + +var hasRequiredXor128; + +function requireXor128 () { + if (hasRequiredXor128) return xor128$1.exports; + hasRequiredXor128 = 1; + (function (module) { + // A Javascript implementaion of the "xor128" prng algorithm by + // George Marsaglia. See http://www.jstatsoft.org/v08/i14/paper + + (function(global, module, define) { + + function XorGen(seed) { + var me = this, strseed = ''; + + me.x = 0; + me.y = 0; + me.z = 0; + me.w = 0; + + // Set up generator function. + me.next = function() { + var t = me.x ^ (me.x << 11); + me.x = me.y; + me.y = me.z; + me.z = me.w; + return me.w ^= (me.w >>> 19) ^ t ^ (t >>> 8); + }; + + if (seed === (seed | 0)) { + // Integer seed. + me.x = seed; + } else { + // String seed. + strseed += seed; + } + + // Mix in string seed, then discard an initial batch of 64 values. + for (var k = 0; k < strseed.length + 64; k++) { + me.x ^= strseed.charCodeAt(k) | 0; + me.next(); + } + } + + function copy(f, t) { + t.x = f.x; + t.y = f.y; + t.z = f.z; + t.w = f.w; + return t; + } + + function impl(seed, opts) { + var xg = new XorGen(seed), + state = opts && opts.state, + prng = function() { return (xg.next() >>> 0) / 0x100000000; }; + prng.double = function() { + do { + var top = xg.next() >>> 11, + bot = (xg.next() >>> 0) / 0x100000000, + result = (top + bot) / (1 << 21); + } while (result === 0); + return result; + }; + prng.int32 = xg.next; + prng.quick = prng; + if (state) { + if (typeof(state) == 'object') copy(state, xg); + prng.state = function() { return copy(xg, {}); }; + } + return prng; + } + + if (module && module.exports) { + module.exports = impl; + } else { + this.xor128 = impl; + } + + })( + xor128, + module); + } (xor128$1)); + return xor128$1.exports; +} + +var xorwow$1 = {exports: {}}; + +var xorwow = xorwow$1.exports; + +var hasRequiredXorwow; + +function requireXorwow () { + if (hasRequiredXorwow) return xorwow$1.exports; + hasRequiredXorwow = 1; + (function (module) { + // A Javascript implementaion of the "xorwow" prng algorithm by + // George Marsaglia. See http://www.jstatsoft.org/v08/i14/paper + + (function(global, module, define) { + + function XorGen(seed) { + var me = this, strseed = ''; + + // Set up generator function. + me.next = function() { + var t = (me.x ^ (me.x >>> 2)); + me.x = me.y; me.y = me.z; me.z = me.w; me.w = me.v; + return (me.d = (me.d + 362437 | 0)) + + (me.v = (me.v ^ (me.v << 4)) ^ (t ^ (t << 1))) | 0; + }; + + me.x = 0; + me.y = 0; + me.z = 0; + me.w = 0; + me.v = 0; + + if (seed === (seed | 0)) { + // Integer seed. + me.x = seed; + } else { + // String seed. + strseed += seed; + } + + // Mix in string seed, then discard an initial batch of 64 values. + for (var k = 0; k < strseed.length + 64; k++) { + me.x ^= strseed.charCodeAt(k) | 0; + if (k == strseed.length) { + me.d = me.x << 10 ^ me.x >>> 4; + } + me.next(); + } + } + + function copy(f, t) { + t.x = f.x; + t.y = f.y; + t.z = f.z; + t.w = f.w; + t.v = f.v; + t.d = f.d; + return t; + } + + function impl(seed, opts) { + var xg = new XorGen(seed), + state = opts && opts.state, + prng = function() { return (xg.next() >>> 0) / 0x100000000; }; + prng.double = function() { + do { + var top = xg.next() >>> 11, + bot = (xg.next() >>> 0) / 0x100000000, + result = (top + bot) / (1 << 21); + } while (result === 0); + return result; + }; + prng.int32 = xg.next; + prng.quick = prng; + if (state) { + if (typeof(state) == 'object') copy(state, xg); + prng.state = function() { return copy(xg, {}); }; + } + return prng; + } + + if (module && module.exports) { + module.exports = impl; + } else { + this.xorwow = impl; + } + + })( + xorwow, + module); + } (xorwow$1)); + return xorwow$1.exports; +} + +var xorshift7$1 = {exports: {}}; + +var xorshift7 = xorshift7$1.exports; + +var hasRequiredXorshift7; + +function requireXorshift7 () { + if (hasRequiredXorshift7) return xorshift7$1.exports; + hasRequiredXorshift7 = 1; + (function (module) { + // A Javascript implementaion of the "xorshift7" algorithm by + // François Panneton and Pierre L'ecuyer: + // "On the Xorgshift Random Number Generators" + // http://saluc.engr.uconn.edu/refs/crypto/rng/panneton05onthexorshift.pdf + + (function(global, module, define) { + + function XorGen(seed) { + var me = this; + + // Set up generator function. + me.next = function() { + // Update xor generator. + var X = me.x, i = me.i, t, v; + t = X[i]; t ^= (t >>> 7); v = t ^ (t << 24); + t = X[(i + 1) & 7]; v ^= t ^ (t >>> 10); + t = X[(i + 3) & 7]; v ^= t ^ (t >>> 3); + t = X[(i + 4) & 7]; v ^= t ^ (t << 7); + t = X[(i + 7) & 7]; t = t ^ (t << 13); v ^= t ^ (t << 9); + X[i] = v; + me.i = (i + 1) & 7; + return v; + }; + + function init(me, seed) { + var j, X = []; + + if (seed === (seed | 0)) { + // Seed state array using a 32-bit integer. + X[0] = seed; + } else { + // Seed state using a string. + seed = '' + seed; + for (j = 0; j < seed.length; ++j) { + X[j & 7] = (X[j & 7] << 15) ^ + (seed.charCodeAt(j) + X[(j + 1) & 7] << 13); + } + } + // Enforce an array length of 8, not all zeroes. + while (X.length < 8) X.push(0); + for (j = 0; j < 8 && X[j] === 0; ++j); + if (j == 8) X[7] = -1; else X[j]; + + me.x = X; + me.i = 0; + + // Discard an initial 256 values. + for (j = 256; j > 0; --j) { + me.next(); + } + } + + init(me, seed); + } + + function copy(f, t) { + t.x = f.x.slice(); + t.i = f.i; + return t; + } + + function impl(seed, opts) { + if (seed == null) seed = +(new Date); + var xg = new XorGen(seed), + state = opts && opts.state, + prng = function() { return (xg.next() >>> 0) / 0x100000000; }; + prng.double = function() { + do { + var top = xg.next() >>> 11, + bot = (xg.next() >>> 0) / 0x100000000, + result = (top + bot) / (1 << 21); + } while (result === 0); + return result; + }; + prng.int32 = xg.next; + prng.quick = prng; + if (state) { + if (state.x) copy(state, xg); + prng.state = function() { return copy(xg, {}); }; + } + return prng; + } + + if (module && module.exports) { + module.exports = impl; + } else { + this.xorshift7 = impl; + } + + })( + xorshift7, + module); + } (xorshift7$1)); + return xorshift7$1.exports; +} + +var xor4096$1 = {exports: {}}; + +var xor4096 = xor4096$1.exports; + +var hasRequiredXor4096; + +function requireXor4096 () { + if (hasRequiredXor4096) return xor4096$1.exports; + hasRequiredXor4096 = 1; + (function (module) { + // A Javascript implementaion of Richard Brent's Xorgens xor4096 algorithm. + // + // This fast non-cryptographic random number generator is designed for + // use in Monte-Carlo algorithms. It combines a long-period xorshift + // generator with a Weyl generator, and it passes all common batteries + // of stasticial tests for randomness while consuming only a few nanoseconds + // for each prng generated. For background on the generator, see Brent's + // paper: "Some long-period random number generators using shifts and xors." + // http://arxiv.org/pdf/1004.3115v1.pdf + // + // Usage: + // + // var xor4096 = require('xor4096'); + // random = xor4096(1); // Seed with int32 or string. + // assert.equal(random(), 0.1520436450538547); // (0, 1) range, 53 bits. + // assert.equal(random.int32(), 1806534897); // signed int32, 32 bits. + // + // For nonzero numeric keys, this impelementation provides a sequence + // identical to that by Brent's xorgens 3 implementaion in C. This + // implementation also provides for initalizing the generator with + // string seeds, or for saving and restoring the state of the generator. + // + // On Chrome, this prng benchmarks about 2.1 times slower than + // Javascript's built-in Math.random(). + + (function(global, module, define) { + + function XorGen(seed) { + var me = this; + + // Set up generator function. + me.next = function() { + var w = me.w, + X = me.X, i = me.i, t, v; + // Update Weyl generator. + me.w = w = (w + 0x61c88647) | 0; + // Update xor generator. + v = X[(i + 34) & 127]; + t = X[i = ((i + 1) & 127)]; + v ^= v << 13; + t ^= t << 17; + v ^= v >>> 15; + t ^= t >>> 12; + // Update Xor generator array state. + v = X[i] = v ^ t; + me.i = i; + // Result is the combination. + return (v + (w ^ (w >>> 16))) | 0; + }; + + function init(me, seed) { + var t, v, i, j, w, X = [], limit = 128; + if (seed === (seed | 0)) { + // Numeric seeds initialize v, which is used to generates X. + v = seed; + seed = null; + } else { + // String seeds are mixed into v and X one character at a time. + seed = seed + '\0'; + v = 0; + limit = Math.max(limit, seed.length); + } + // Initialize circular array and weyl value. + for (i = 0, j = -32; j < limit; ++j) { + // Put the unicode characters into the array, and shuffle them. + if (seed) v ^= seed.charCodeAt((j + 32) % seed.length); + // After 32 shuffles, take v as the starting w value. + if (j === 0) w = v; + v ^= v << 10; + v ^= v >>> 15; + v ^= v << 4; + v ^= v >>> 13; + if (j >= 0) { + w = (w + 0x61c88647) | 0; // Weyl. + t = (X[j & 127] ^= (v + w)); // Combine xor and weyl to init array. + i = (0 == t) ? i + 1 : 0; // Count zeroes. + } + } + // We have detected all zeroes; make the key nonzero. + if (i >= 128) { + X[(seed && seed.length || 0) & 127] = -1; + } + // Run the generator 512 times to further mix the state before using it. + // Factoring this as a function slows the main generator, so it is just + // unrolled here. The weyl generator is not advanced while warming up. + i = 127; + for (j = 4 * 128; j > 0; --j) { + v = X[(i + 34) & 127]; + t = X[i = ((i + 1) & 127)]; + v ^= v << 13; + t ^= t << 17; + v ^= v >>> 15; + t ^= t >>> 12; + X[i] = v ^ t; + } + // Storing state as object members is faster than using closure variables. + me.w = w; + me.X = X; + me.i = i; + } + + init(me, seed); + } + + function copy(f, t) { + t.i = f.i; + t.w = f.w; + t.X = f.X.slice(); + return t; + } + function impl(seed, opts) { + if (seed == null) seed = +(new Date); + var xg = new XorGen(seed), + state = opts && opts.state, + prng = function() { return (xg.next() >>> 0) / 0x100000000; }; + prng.double = function() { + do { + var top = xg.next() >>> 11, + bot = (xg.next() >>> 0) / 0x100000000, + result = (top + bot) / (1 << 21); + } while (result === 0); + return result; + }; + prng.int32 = xg.next; + prng.quick = prng; + if (state) { + if (state.X) copy(state, xg); + prng.state = function() { return copy(xg, {}); }; + } + return prng; + } + + if (module && module.exports) { + module.exports = impl; + } else { + this.xor4096 = impl; + } + + })( + xor4096, // window object or global + module); + } (xor4096$1)); + return xor4096$1.exports; +} + +var tychei$1 = {exports: {}}; + +var tychei = tychei$1.exports; + +var hasRequiredTychei; + +function requireTychei () { + if (hasRequiredTychei) return tychei$1.exports; + hasRequiredTychei = 1; + (function (module) { + // A Javascript implementaion of the "Tyche-i" prng algorithm by + // Samuel Neves and Filipe Araujo. + // See https://eden.dei.uc.pt/~sneves/pubs/2011-snfa2.pdf + + (function(global, module, define) { + + function XorGen(seed) { + var me = this, strseed = ''; + + // Set up generator function. + me.next = function() { + var b = me.b, c = me.c, d = me.d, a = me.a; + b = (b << 25) ^ (b >>> 7) ^ c; + c = (c - d) | 0; + d = (d << 24) ^ (d >>> 8) ^ a; + a = (a - b) | 0; + me.b = b = (b << 20) ^ (b >>> 12) ^ c; + me.c = c = (c - d) | 0; + me.d = (d << 16) ^ (c >>> 16) ^ a; + return me.a = (a - b) | 0; + }; + + /* The following is non-inverted tyche, which has better internal + * bit diffusion, but which is about 25% slower than tyche-i in JS. + me.next = function() { + var a = me.a, b = me.b, c = me.c, d = me.d; + a = (me.a + me.b | 0) >>> 0; + d = me.d ^ a; d = d << 16 ^ d >>> 16; + c = me.c + d | 0; + b = me.b ^ c; b = b << 12 ^ d >>> 20; + me.a = a = a + b | 0; + d = d ^ a; me.d = d = d << 8 ^ d >>> 24; + me.c = c = c + d | 0; + b = b ^ c; + return me.b = (b << 7 ^ b >>> 25); + } + */ + + me.a = 0; + me.b = 0; + me.c = 2654435769 | 0; + me.d = 1367130551; + + if (seed === Math.floor(seed)) { + // Integer seed. + me.a = (seed / 0x100000000) | 0; + me.b = seed | 0; + } else { + // String seed. + strseed += seed; + } + + // Mix in string seed, then discard an initial batch of 64 values. + for (var k = 0; k < strseed.length + 20; k++) { + me.b ^= strseed.charCodeAt(k) | 0; + me.next(); + } + } + + function copy(f, t) { + t.a = f.a; + t.b = f.b; + t.c = f.c; + t.d = f.d; + return t; + } + function impl(seed, opts) { + var xg = new XorGen(seed), + state = opts && opts.state, + prng = function() { return (xg.next() >>> 0) / 0x100000000; }; + prng.double = function() { + do { + var top = xg.next() >>> 11, + bot = (xg.next() >>> 0) / 0x100000000, + result = (top + bot) / (1 << 21); + } while (result === 0); + return result; + }; + prng.int32 = xg.next; + prng.quick = prng; + if (state) { + if (typeof(state) == 'object') copy(state, xg); + prng.state = function() { return copy(xg, {}); }; + } + return prng; + } + + if (module && module.exports) { + module.exports = impl; + } else { + this.tychei = impl; + } + + })( + tychei, + module); + } (tychei$1)); + return tychei$1.exports; +} + +var seedrandom$3 = {exports: {}}; + +/* +Copyright 2019 David Bau. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ +var seedrandom$2 = seedrandom$3.exports; + +var hasRequiredSeedrandom$1; + +function requireSeedrandom$1 () { + if (hasRequiredSeedrandom$1) return seedrandom$3.exports; + hasRequiredSeedrandom$1 = 1; + (function (module) { + (function (global, pool, math) { + // + // The following constants are related to IEEE 754 limits. + // + + var width = 256, // each RC4 output is 0 <= x < 256 + chunks = 6, // at least six RC4 outputs for each double + digits = 52, // there are 52 significant digits in a double + rngname = 'random', // rngname: name for Math.random and Math.seedrandom + startdenom = math.pow(width, chunks), + significance = math.pow(2, digits), + overflow = significance * 2, + mask = width - 1, + nodecrypto; // node.js crypto module, initialized at the bottom. + + // + // seedrandom() + // This is the seedrandom function described above. + // + function seedrandom(seed, options, callback) { + var key = []; + options = (options == true) ? { entropy: true } : (options || {}); + + // Flatten the seed string or build one from local entropy if needed. + var shortseed = mixkey(flatten( + options.entropy ? [seed, tostring(pool)] : + (seed == null) ? autoseed() : seed, 3), key); + + // Use the seed to initialize an ARC4 generator. + var arc4 = new ARC4(key); + + // This function returns a random double in [0, 1) that contains + // randomness in every bit of the mantissa of the IEEE 754 value. + var prng = function() { + var n = arc4.g(chunks), // Start with a numerator n < 2 ^ 48 + d = startdenom, // and denominator d = 2 ^ 48. + x = 0; // and no 'extra last byte'. + while (n < significance) { // Fill up all significant digits by + n = (n + x) * width; // shifting numerator and + d *= width; // denominator and generating a + x = arc4.g(1); // new least-significant-byte. + } + while (n >= overflow) { // To avoid rounding up, before adding + n /= 2; // last byte, shift everything + d /= 2; // right using integer math until + x >>>= 1; // we have exactly the desired bits. + } + return (n + x) / d; // Form the number within [0, 1). + }; + + prng.int32 = function() { return arc4.g(4) | 0; }; + prng.quick = function() { return arc4.g(4) / 0x100000000; }; + prng.double = prng; + + // Mix the randomness into accumulated entropy. + mixkey(tostring(arc4.S), pool); + + // Calling convention: what to return as a function of prng, seed, is_math. + return (options.pass || callback || + function(prng, seed, is_math_call, state) { + if (state) { + // Load the arc4 state from the given state if it has an S array. + if (state.S) { copy(state, arc4); } + // Only provide the .state method if requested via options.state. + prng.state = function() { return copy(arc4, {}); }; + } + + // If called as a method of Math (Math.seedrandom()), mutate + // Math.random because that is how seedrandom.js has worked since v1.0. + if (is_math_call) { math[rngname] = prng; return seed; } + + // Otherwise, it is a newer calling convention, so return the + // prng directly. + else return prng; + })( + prng, + shortseed, + 'global' in options ? options.global : (this == math), + options.state); + } + + // + // ARC4 + // + // An ARC4 implementation. The constructor takes a key in the form of + // an array of at most (width) integers that should be 0 <= x < (width). + // + // The g(count) method returns a pseudorandom integer that concatenates + // the next (count) outputs from ARC4. Its return value is a number x + // that is in the range 0 <= x < (width ^ count). + // + function ARC4(key) { + var t, keylen = key.length, + me = this, i = 0, j = me.i = me.j = 0, s = me.S = []; + + // The empty key [] is treated as [0]. + if (!keylen) { key = [keylen++]; } + + // Set up S using the standard key scheduling algorithm. + while (i < width) { + s[i] = i++; + } + for (i = 0; i < width; i++) { + s[i] = s[j = mask & (j + key[i % keylen] + (t = s[i]))]; + s[j] = t; + } + + // The "g" method returns the next (count) outputs as one number. + (me.g = function(count) { + // Using instance members instead of closure state nearly doubles speed. + var t, r = 0, + i = me.i, j = me.j, s = me.S; + while (count--) { + t = s[i = mask & (i + 1)]; + r = r * width + s[mask & ((s[i] = s[j = mask & (j + t)]) + (s[j] = t))]; + } + me.i = i; me.j = j; + return r; + // For robust unpredictability, the function call below automatically + // discards an initial batch of values. This is called RC4-drop[256]. + // See http://google.com/search?q=rsa+fluhrer+response&btnI + })(width); + } + + // + // copy() + // Copies internal state of ARC4 to or from a plain object. + // + function copy(f, t) { + t.i = f.i; + t.j = f.j; + t.S = f.S.slice(); + return t; + } + // + // flatten() + // Converts an object tree to nested arrays of strings. + // + function flatten(obj, depth) { + var result = [], typ = (typeof obj), prop; + if (depth && typ == 'object') { + for (prop in obj) { + try { result.push(flatten(obj[prop], depth - 1)); } catch (e) {} + } + } + return (result.length ? result : typ == 'string' ? obj : obj + '\0'); + } + + // + // mixkey() + // Mixes a string seed into a key that is an array of integers, and + // returns a shortened string seed that is equivalent to the result key. + // + function mixkey(seed, key) { + var stringseed = seed + '', smear, j = 0; + while (j < stringseed.length) { + key[mask & j] = + mask & ((smear ^= key[mask & j] * 19) + stringseed.charCodeAt(j++)); + } + return tostring(key); + } + + // + // autoseed() + // Returns an object for autoseeding, using window.crypto and Node crypto + // module if available. + // + function autoseed() { + try { + var out; + if (nodecrypto && (out = nodecrypto.randomBytes)) { + // The use of 'out' to remember randomBytes makes tight minified code. + out = out(width); + } else { + out = new Uint8Array(width); + (global.crypto || global.msCrypto).getRandomValues(out); + } + return tostring(out); + } catch (e) { + var browser = global.navigator, + plugins = browser && browser.plugins; + return [+new Date, global, plugins, global.screen, tostring(pool)]; + } + } + + // + // tostring() + // Converts an array of charcodes to a string + // + function tostring(a) { + return String.fromCharCode.apply(0, a); + } + + // + // When seedrandom.js is loaded, we immediately mix a few bits + // from the built-in RNG into the entropy pool. Because we do + // not want to interfere with deterministic PRNG state later, + // seedrandom will not call math.random on its own again after + // initialization. + // + mixkey(math.random(), pool); + + // + // Nodejs and AMD support: export the implementation as a module using + // either convention. + // + if (module.exports) { + module.exports = seedrandom; + // When in node.js, try using crypto package for autoseeding. + try { + nodecrypto = require('crypto'); + } catch (ex) {} + } else { + // When included as a plain script, set up Math.seedrandom global. + math['seed' + rngname] = seedrandom; + } + + + // End anonymous scope, and pass initial values. + })( + // global: `self` in browsers (including strict mode and web workers), + // otherwise `this` in Node and other environments + (typeof self !== 'undefined') ? self : seedrandom$2, + [], // pool: entropy pool starts empty + Math // math: package containing random, pow, and seedrandom + ); + } (seedrandom$3)); + return seedrandom$3.exports; +} + +var seedrandom$1; +var hasRequiredSeedrandom; + +function requireSeedrandom () { + if (hasRequiredSeedrandom) return seedrandom$1; + hasRequiredSeedrandom = 1; + // A library of seedable RNGs implemented in Javascript. + // + // Usage: + // + // var seedrandom = require('seedrandom'); + // var random = seedrandom(1); // or any seed. + // var x = random(); // 0 <= x < 1. Every bit is random. + // var x = random.quick(); // 0 <= x < 1. 32 bits of randomness. + + // alea, a 53-bit multiply-with-carry generator by Johannes Baagøe. + // Period: ~2^116 + // Reported to pass all BigCrush tests. + var alea = requireAlea(); + + // xor128, a pure xor-shift generator by George Marsaglia. + // Period: 2^128-1. + // Reported to fail: MatrixRank and LinearComp. + var xor128 = requireXor128(); + + // xorwow, George Marsaglia's 160-bit xor-shift combined plus weyl. + // Period: 2^192-2^32 + // Reported to fail: CollisionOver, SimpPoker, and LinearComp. + var xorwow = requireXorwow(); + + // xorshift7, by François Panneton and Pierre L'ecuyer, takes + // a different approach: it adds robustness by allowing more shifts + // than Marsaglia's original three. It is a 7-shift generator + // with 256 bits, that passes BigCrush with no systmatic failures. + // Period 2^256-1. + // No systematic BigCrush failures reported. + var xorshift7 = requireXorshift7(); + + // xor4096, by Richard Brent, is a 4096-bit xor-shift with a + // very long period that also adds a Weyl generator. It also passes + // BigCrush with no systematic failures. Its long period may + // be useful if you have many generators and need to avoid + // collisions. + // Period: 2^4128-2^32. + // No systematic BigCrush failures reported. + var xor4096 = requireXor4096(); + + // Tyche-i, by Samuel Neves and Filipe Araujo, is a bit-shifting random + // number generator derived from ChaCha, a modern stream cipher. + // https://eden.dei.uc.pt/~sneves/pubs/2011-snfa2.pdf + // Period: ~2^127 + // No systematic BigCrush failures reported. + var tychei = requireTychei(); + + // The original ARC4-based prng included in this library. + // Period: ~2^1600 + var sr = requireSeedrandom$1(); + + sr.alea = alea; + sr.xor128 = xor128; + sr.xorwow = xorwow; + sr.xorshift7 = xorshift7; + sr.xor4096 = xor4096; + sr.tychei = tychei; + + seedrandom$1 = sr; + return seedrandom$1; +} + +var seedrandomExports = requireSeedrandom(); +const seedrandom = /*@__PURE__*/getDefaultExportFromCjs(seedrandomExports); + +export { hydrateWorkflowReturnValue as $, stepLogger as A, EventConsumerResult as B, hydrateStepReturnValue as C, DeploymentId as D, ERROR_SLUGS as E, FatalError as F, seedrandom as G, HookId as H, webhookLogger as I, parseDurationToDate as J, WorkflowEventsCount as K, getPort as L, monotonicFactory as M, EventsConsumer as N, WORKFLOW_USE_STEP as O, WORKFLOW_CREATE_HOOK as P, WORKFLOW_SLEEP as Q, WORKFLOW_GET_STREAM_ID as R, dehydrateWorkflowReturnValue as S, WorkflowResultType as T, BODY_INIT_SYMBOL as U, getWorldHandlers as V, WorkflowServerWritableStream as W, WorkflowInvokePayloadSchema as X, withTraceContext as Y, StepInvokePayloadSchema as Z, getExternalRevivers as _, getSerializeStream as a, WorkflowRunCancelledError as a0, QueueName as a1, WorkflowTracePropagated as a2, WorkflowStartedAt as a3, buildWorkflowSuspensionMessage as a4, dehydrateStepArguments as a5, WorkflowAPIError as a6, WorkflowStepsCreated as a7, WorkflowErrorMessage as a8, WorkflowErrorName as a9, StepAttempt as aa, StepName as ab, getStepFunction as ac, StepTracePropagated as ad, StepMaxRetries as ae, StepId as af, runtimeLogger as ag, StepStatus as ah, StepRetryTimeoutSeconds as ai, StepSkipReason as aj, StepSkipped as ak, StepArgumentsCount as al, StepResultType as am, StepErrorMessage as an, StepErrorName as ao, StepFatalError as ap, StepRetryExhausted as aq, RetryableError as ar, StepRetryWillRetry as as, requireTokenError as at, getExternalReducers as b, getWorld as c, WEBHOOK_RESPONSE_WRITABLE as d, WorkflowRuntimeError as e, WorkflowRunId as f, getWorkflowRunStreamId as g, hydrateStepArguments as h, HookToken as i, dehydrateStepReturnValue as j, functionsExports as k, WorkflowName as l, getSpanContextForTraceCarrier as m, HookFound as n, WorkflowOperation as o, WorkflowArgumentsCount as p, dehydrateWorkflowArguments as q, registerStepFunction as r, serializeTraceCarrier as s, trace as t, WorkflowRunStatus as u, hydrateWorkflowArguments as v, waitedUntil as w, WorkflowRunNotCompletedError as x, WorkflowRunFailedError as y, withResolvers as z }; diff --git a/workbench/astro/dist/server/chunks/node_C2n6Z2oQ.mjs b/workbench/astro/dist/server/chunks/node_C2n6Z2oQ.mjs new file mode 100644 index 000000000..ba5c8aa58 --- /dev/null +++ b/workbench/astro/dist/server/chunks/node_C2n6Z2oQ.mjs @@ -0,0 +1,1669 @@ +import { i as isRemoteAllowed, j as joinPaths, a as isRemotePath, r as removeQueryString, b as isParentDirectory } from './remote_OOD9OFqU.mjs'; +import { A as AstroError, E as ExpectedImage, L as LocalImageUsedWrongly, M as MissingImageDimension, U as UnsupportedImageFormat, I as IncompatibleDescriptorOptions, a as UnsupportedImageConversion, t as toStyleString, N as NoImageMetadata, F as FailedToFetchRemoteImageDimensions, b as ExpectedImageOptions, c as ExpectedNotESMImage, d as InvalidImageService, e as createComponent, f as createAstro, g as ImageMissingAlt, m as maybeRenderHead, h as addAttribute, s as spreadAttributes, r as renderTemplate, i as ExperimentalFontsNotEnabled, j as FontFamilyNotFound, u as unescapeHTML } from './astro/server_DhWKww_t.mjs'; +import 'clsx'; +import * as mime from 'mrmime'; +import { readFile } from 'node:fs/promises'; +import { fileURLToPath } from 'node:url'; +import '../renderers.mjs'; + +const VALID_SUPPORTED_FORMATS = [ + "jpeg", + "jpg", + "png", + "tiff", + "webp", + "gif", + "svg", + "avif" +]; +const DEFAULT_OUTPUT_FORMAT = "webp"; +const DEFAULT_HASH_PROPS = [ + "src", + "width", + "height", + "format", + "quality", + "fit", + "position" +]; + +const DEFAULT_RESOLUTIONS = [ + 640, + // older and lower-end phones + 750, + // iPhone 6-8 + 828, + // iPhone XR/11 + 960, + // older horizontal phones + 1080, + // iPhone 6-8 Plus + 1280, + // 720p + 1668, + // Various iPads + 1920, + // 1080p + 2048, + // QXGA + 2560, + // WQXGA + 3200, + // QHD+ + 3840, + // 4K + 4480, + // 4.5K + 5120, + // 5K + 6016 + // 6K +]; +const LIMITED_RESOLUTIONS = [ + 640, + // older and lower-end phones + 750, + // iPhone 6-8 + 828, + // iPhone XR/11 + 1080, + // iPhone 6-8 Plus + 1280, + // 720p + 1668, + // Various iPads + 2048, + // QXGA + 2560 + // WQXGA +]; +const getWidths = ({ + width, + layout, + breakpoints = DEFAULT_RESOLUTIONS, + originalWidth +}) => { + const smallerThanOriginal = (w) => !originalWidth || w <= originalWidth; + if (layout === "full-width") { + return breakpoints.filter(smallerThanOriginal); + } + if (!width) { + return []; + } + const doubleWidth = width * 2; + const maxSize = originalWidth ? Math.min(doubleWidth, originalWidth) : doubleWidth; + if (layout === "fixed") { + return originalWidth && width > originalWidth ? [originalWidth] : [width, maxSize]; + } + if (layout === "constrained") { + return [ + // Always include the image at 1x and 2x the specified width + width, + doubleWidth, + ...breakpoints + ].filter((w) => w <= maxSize).sort((a, b) => a - b); + } + return []; +}; +const getSizesAttribute = ({ + width, + layout +}) => { + if (!width || !layout) { + return void 0; + } + switch (layout) { + // If screen is wider than the max size then image width is the max size, + // otherwise it's the width of the screen + case "constrained": + return `(min-width: ${width}px) ${width}px, 100vw`; + // Image is always the same width, whatever the size of the screen + case "fixed": + return `${width}px`; + // Image is always the width of the screen + case "full-width": + return `100vw`; + case "none": + default: + return void 0; + } +}; + +function isESMImportedImage(src) { + return typeof src === "object" || typeof src === "function" && "src" in src; +} +function isRemoteImage(src) { + return typeof src === "string"; +} +async function resolveSrc(src) { + if (typeof src === "object" && "then" in src) { + const resource = await src; + return resource.default ?? resource; + } + return src; +} + +function isLocalService(service) { + if (!service) { + return false; + } + return "transform" in service; +} +function parseQuality(quality) { + let result = parseInt(quality); + if (Number.isNaN(result)) { + return quality; + } + return result; +} +const sortNumeric = (a, b) => a - b; +const baseService = { + validateOptions(options) { + if (!options.src || !isRemoteImage(options.src) && !isESMImportedImage(options.src)) { + throw new AstroError({ + ...ExpectedImage, + message: ExpectedImage.message( + JSON.stringify(options.src), + typeof options.src, + JSON.stringify(options, (_, v) => v === void 0 ? null : v) + ) + }); + } + if (!isESMImportedImage(options.src)) { + if (options.src.startsWith("/@fs/") || !isRemotePath(options.src) && !options.src.startsWith("/")) { + throw new AstroError({ + ...LocalImageUsedWrongly, + message: LocalImageUsedWrongly.message(options.src) + }); + } + let missingDimension; + if (!options.width && !options.height) { + missingDimension = "both"; + } else if (!options.width && options.height) { + missingDimension = "width"; + } else if (options.width && !options.height) { + missingDimension = "height"; + } + if (missingDimension) { + throw new AstroError({ + ...MissingImageDimension, + message: MissingImageDimension.message(missingDimension, options.src) + }); + } + } else { + if (!VALID_SUPPORTED_FORMATS.includes(options.src.format)) { + throw new AstroError({ + ...UnsupportedImageFormat, + message: UnsupportedImageFormat.message( + options.src.format, + options.src.src, + VALID_SUPPORTED_FORMATS + ) + }); + } + if (options.widths && options.densities) { + throw new AstroError(IncompatibleDescriptorOptions); + } + if (options.src.format === "svg") { + options.format = "svg"; + } + if (options.src.format === "svg" && options.format !== "svg" || options.src.format !== "svg" && options.format === "svg") { + throw new AstroError(UnsupportedImageConversion); + } + } + if (!options.format) { + options.format = DEFAULT_OUTPUT_FORMAT; + } + if (options.width) options.width = Math.round(options.width); + if (options.height) options.height = Math.round(options.height); + if (options.layout && options.width && options.height) { + options.fit ??= "cover"; + delete options.layout; + } + if (options.fit === "none") { + delete options.fit; + } + return options; + }, + getHTMLAttributes(options) { + const { targetWidth, targetHeight } = getTargetDimensions(options); + const { + src, + width, + height, + format, + quality, + densities, + widths, + formats, + layout, + priority, + fit, + position, + ...attributes + } = options; + return { + ...attributes, + width: targetWidth, + height: targetHeight, + loading: attributes.loading ?? "lazy", + decoding: attributes.decoding ?? "async" + }; + }, + getSrcSet(options) { + const { targetWidth, targetHeight } = getTargetDimensions(options); + const aspectRatio = targetWidth / targetHeight; + const { widths, densities } = options; + const targetFormat = options.format ?? DEFAULT_OUTPUT_FORMAT; + let transformedWidths = (widths ?? []).sort(sortNumeric); + let imageWidth = options.width; + let maxWidth = Infinity; + if (isESMImportedImage(options.src)) { + imageWidth = options.src.width; + maxWidth = imageWidth; + if (transformedWidths.length > 0 && transformedWidths.at(-1) > maxWidth) { + transformedWidths = transformedWidths.filter((width) => width <= maxWidth); + transformedWidths.push(maxWidth); + } + } + transformedWidths = Array.from(new Set(transformedWidths)); + const { + width: transformWidth, + height: transformHeight, + ...transformWithoutDimensions + } = options; + let allWidths = []; + if (densities) { + const densityValues = densities.map((density) => { + if (typeof density === "number") { + return density; + } else { + return parseFloat(density); + } + }); + const densityWidths = densityValues.sort(sortNumeric).map((density) => Math.round(targetWidth * density)); + allWidths = densityWidths.map((width, index) => ({ + width, + descriptor: `${densityValues[index]}x` + })); + } else if (transformedWidths.length > 0) { + allWidths = transformedWidths.map((width) => ({ + width, + descriptor: `${width}w` + })); + } + return allWidths.map(({ width, descriptor }) => { + const height = Math.round(width / aspectRatio); + const transform = { ...transformWithoutDimensions, width, height }; + return { + transform, + descriptor, + attributes: { + type: `image/${targetFormat}` + } + }; + }); + }, + getURL(options, imageConfig) { + const searchParams = new URLSearchParams(); + if (isESMImportedImage(options.src)) { + searchParams.append("href", options.src.src); + } else if (isRemoteAllowed(options.src, imageConfig)) { + searchParams.append("href", options.src); + } else { + return options.src; + } + const params = { + w: "width", + h: "height", + q: "quality", + f: "format", + fit: "fit", + position: "position" + }; + Object.entries(params).forEach(([param, key]) => { + options[key] && searchParams.append(param, options[key].toString()); + }); + const imageEndpoint = joinPaths("/", imageConfig.endpoint.route); + let url = `${imageEndpoint}?${searchParams}`; + if (imageConfig.assetQueryParams) { + const assetQueryString = imageConfig.assetQueryParams.toString(); + if (assetQueryString) { + url += "&" + assetQueryString; + } + } + return url; + }, + parseURL(url) { + const params = url.searchParams; + if (!params.has("href")) { + return void 0; + } + const transform = { + src: params.get("href"), + width: params.has("w") ? parseInt(params.get("w")) : void 0, + height: params.has("h") ? parseInt(params.get("h")) : void 0, + format: params.get("f"), + quality: params.get("q"), + fit: params.get("fit"), + position: params.get("position") ?? void 0 + }; + return transform; + } +}; +function getTargetDimensions(options) { + let targetWidth = options.width; + let targetHeight = options.height; + if (isESMImportedImage(options.src)) { + const aspectRatio = options.src.width / options.src.height; + if (targetHeight && !targetWidth) { + targetWidth = Math.round(targetHeight * aspectRatio); + } else if (targetWidth && !targetHeight) { + targetHeight = Math.round(targetWidth / aspectRatio); + } else if (!targetWidth && !targetHeight) { + targetWidth = options.src.width; + targetHeight = options.src.height; + } + } + return { + targetWidth, + targetHeight + }; +} + +function isImageMetadata(src) { + return src.fsPath && !("fsPath" in src); +} + +const cssFitValues = ["fill", "contain", "cover", "scale-down"]; +function addCSSVarsToStyle(vars, styles) { + const cssVars = Object.entries(vars).filter(([_, value]) => value !== void 0 && value !== false).map(([key, value]) => `--${key}: ${value};`).join(" "); + if (!styles) { + return cssVars; + } + const style = typeof styles === "string" ? styles : toStyleString(styles); + return `${cssVars} ${style}`; +} + +const decoder = new TextDecoder(); +const toUTF8String = (input, start = 0, end = input.length) => decoder.decode(input.slice(start, end)); +const toHexString = (input, start = 0, end = input.length) => input.slice(start, end).reduce((memo, i) => memo + ("0" + i.toString(16)).slice(-2), ""); +const readInt16LE = (input, offset = 0) => { + const val = input[offset] + input[offset + 1] * 2 ** 8; + return val | (val & 2 ** 15) * 131070; +}; +const readUInt16BE = (input, offset = 0) => input[offset] * 2 ** 8 + input[offset + 1]; +const readUInt16LE = (input, offset = 0) => input[offset] + input[offset + 1] * 2 ** 8; +const readUInt24LE = (input, offset = 0) => input[offset] + input[offset + 1] * 2 ** 8 + input[offset + 2] * 2 ** 16; +const readInt32LE = (input, offset = 0) => input[offset] + input[offset + 1] * 2 ** 8 + input[offset + 2] * 2 ** 16 + (input[offset + 3] << 24); +const readUInt32BE = (input, offset = 0) => input[offset] * 2 ** 24 + input[offset + 1] * 2 ** 16 + input[offset + 2] * 2 ** 8 + input[offset + 3]; +const readUInt32LE = (input, offset = 0) => input[offset] + input[offset + 1] * 2 ** 8 + input[offset + 2] * 2 ** 16 + input[offset + 3] * 2 ** 24; +const methods = { + readUInt16BE, + readUInt16LE, + readUInt32BE, + readUInt32LE +}; +function readUInt(input, bits, offset, isBigEndian) { + offset = offset || 0; + const endian = isBigEndian ? "BE" : "LE"; + const methodName = "readUInt" + bits + endian; + return methods[methodName](input, offset); +} +function readBox(buffer, offset) { + if (buffer.length - offset < 4) return; + const boxSize = readUInt32BE(buffer, offset); + if (buffer.length - offset < boxSize) return; + return { + name: toUTF8String(buffer, 4 + offset, 8 + offset), + offset, + size: boxSize + }; +} +function findBox(buffer, boxName, offset) { + while (offset < buffer.length) { + const box = readBox(buffer, offset); + if (!box) break; + if (box.name === boxName) return box; + offset += box.size; + } +} + +const BMP = { + validate: (input) => toUTF8String(input, 0, 2) === "BM", + calculate: (input) => ({ + height: Math.abs(readInt32LE(input, 22)), + width: readUInt32LE(input, 18) + }) +}; + +const TYPE_ICON = 1; +const SIZE_HEADER$1 = 2 + 2 + 2; +const SIZE_IMAGE_ENTRY = 1 + 1 + 1 + 1 + 2 + 2 + 4 + 4; +function getSizeFromOffset(input, offset) { + const value = input[offset]; + return value === 0 ? 256 : value; +} +function getImageSize$1(input, imageIndex) { + const offset = SIZE_HEADER$1 + imageIndex * SIZE_IMAGE_ENTRY; + return { + height: getSizeFromOffset(input, offset + 1), + width: getSizeFromOffset(input, offset) + }; +} +const ICO = { + validate(input) { + const reserved = readUInt16LE(input, 0); + const imageCount = readUInt16LE(input, 4); + if (reserved !== 0 || imageCount === 0) return false; + const imageType = readUInt16LE(input, 2); + return imageType === TYPE_ICON; + }, + calculate(input) { + const nbImages = readUInt16LE(input, 4); + const imageSize = getImageSize$1(input, 0); + if (nbImages === 1) return imageSize; + const imgs = [imageSize]; + for (let imageIndex = 1; imageIndex < nbImages; imageIndex += 1) { + imgs.push(getImageSize$1(input, imageIndex)); + } + return { + height: imageSize.height, + images: imgs, + width: imageSize.width + }; + } +}; + +const TYPE_CURSOR = 2; +const CUR = { + validate(input) { + const reserved = readUInt16LE(input, 0); + const imageCount = readUInt16LE(input, 4); + if (reserved !== 0 || imageCount === 0) return false; + const imageType = readUInt16LE(input, 2); + return imageType === TYPE_CURSOR; + }, + calculate: (input) => ICO.calculate(input) +}; + +const DDS = { + validate: (input) => readUInt32LE(input, 0) === 542327876, + calculate: (input) => ({ + height: readUInt32LE(input, 12), + width: readUInt32LE(input, 16) + }) +}; + +const gifRegexp = /^GIF8[79]a/; +const GIF = { + validate: (input) => gifRegexp.test(toUTF8String(input, 0, 6)), + calculate: (input) => ({ + height: readUInt16LE(input, 8), + width: readUInt16LE(input, 6) + }) +}; + +const brandMap = { + avif: "avif", + avis: "avif", + // avif-sequence + mif1: "heif", + msf1: "heif", + // heif-sequence + heic: "heic", + heix: "heic", + hevc: "heic", + // heic-sequence + hevx: "heic" + // heic-sequence +}; +function detectBrands(buffer, start, end) { + let brandsDetected = {}; + for (let i = start; i <= end; i += 4) { + const brand = toUTF8String(buffer, i, i + 4); + if (brand in brandMap) { + brandsDetected[brand] = 1; + } + } + if ("avif" in brandsDetected || "avis" in brandsDetected) { + return "avif"; + } else if ("heic" in brandsDetected || "heix" in brandsDetected || "hevc" in brandsDetected || "hevx" in brandsDetected) { + return "heic"; + } else if ("mif1" in brandsDetected || "msf1" in brandsDetected) { + return "heif"; + } +} +const HEIF = { + validate(buffer) { + const ftype = toUTF8String(buffer, 4, 8); + const brand = toUTF8String(buffer, 8, 12); + return "ftyp" === ftype && brand in brandMap; + }, + calculate(buffer) { + const metaBox = findBox(buffer, "meta", 0); + const iprpBox = metaBox && findBox(buffer, "iprp", metaBox.offset + 12); + const ipcoBox = iprpBox && findBox(buffer, "ipco", iprpBox.offset + 8); + const ispeBox = ipcoBox && findBox(buffer, "ispe", ipcoBox.offset + 8); + if (ispeBox) { + return { + height: readUInt32BE(buffer, ispeBox.offset + 16), + width: readUInt32BE(buffer, ispeBox.offset + 12), + type: detectBrands(buffer, 8, metaBox.offset) + }; + } + throw new TypeError("Invalid HEIF, no size found"); + } +}; + +const SIZE_HEADER = 4 + 4; +const FILE_LENGTH_OFFSET = 4; +const ENTRY_LENGTH_OFFSET = 4; +const ICON_TYPE_SIZE = { + ICON: 32, + "ICN#": 32, + // m => 16 x 16 + "icm#": 16, + icm4: 16, + icm8: 16, + // s => 16 x 16 + "ics#": 16, + ics4: 16, + ics8: 16, + is32: 16, + s8mk: 16, + icp4: 16, + // l => 32 x 32 + icl4: 32, + icl8: 32, + il32: 32, + l8mk: 32, + icp5: 32, + ic11: 32, + // h => 48 x 48 + ich4: 48, + ich8: 48, + ih32: 48, + h8mk: 48, + // . => 64 x 64 + icp6: 64, + ic12: 32, + // t => 128 x 128 + it32: 128, + t8mk: 128, + ic07: 128, + // . => 256 x 256 + ic08: 256, + ic13: 256, + // . => 512 x 512 + ic09: 512, + ic14: 512, + // . => 1024 x 1024 + ic10: 1024 +}; +function readImageHeader(input, imageOffset) { + const imageLengthOffset = imageOffset + ENTRY_LENGTH_OFFSET; + return [ + toUTF8String(input, imageOffset, imageLengthOffset), + readUInt32BE(input, imageLengthOffset) + ]; +} +function getImageSize(type) { + const size = ICON_TYPE_SIZE[type]; + return { width: size, height: size, type }; +} +const ICNS = { + validate: (input) => toUTF8String(input, 0, 4) === "icns", + calculate(input) { + const inputLength = input.length; + const fileLength = readUInt32BE(input, FILE_LENGTH_OFFSET); + let imageOffset = SIZE_HEADER; + let imageHeader = readImageHeader(input, imageOffset); + let imageSize = getImageSize(imageHeader[0]); + imageOffset += imageHeader[1]; + if (imageOffset === fileLength) return imageSize; + const result = { + height: imageSize.height, + images: [imageSize], + width: imageSize.width + }; + while (imageOffset < fileLength && imageOffset < inputLength) { + imageHeader = readImageHeader(input, imageOffset); + imageSize = getImageSize(imageHeader[0]); + imageOffset += imageHeader[1]; + result.images.push(imageSize); + } + return result; + } +}; + +const J2C = { + // TODO: this doesn't seem right. SIZ marker doesn't have to be right after the SOC + validate: (input) => toHexString(input, 0, 4) === "ff4fff51", + calculate: (input) => ({ + height: readUInt32BE(input, 12), + width: readUInt32BE(input, 8) + }) +}; + +const JP2 = { + validate(input) { + if (readUInt32BE(input, 4) !== 1783636e3 || readUInt32BE(input, 0) < 1) return false; + const ftypBox = findBox(input, "ftyp", 0); + if (!ftypBox) return false; + return readUInt32BE(input, ftypBox.offset + 4) === 1718909296; + }, + calculate(input) { + const jp2hBox = findBox(input, "jp2h", 0); + const ihdrBox = jp2hBox && findBox(input, "ihdr", jp2hBox.offset + 8); + if (ihdrBox) { + return { + height: readUInt32BE(input, ihdrBox.offset + 8), + width: readUInt32BE(input, ihdrBox.offset + 12) + }; + } + throw new TypeError("Unsupported JPEG 2000 format"); + } +}; + +const EXIF_MARKER = "45786966"; +const APP1_DATA_SIZE_BYTES = 2; +const EXIF_HEADER_BYTES = 6; +const TIFF_BYTE_ALIGN_BYTES = 2; +const BIG_ENDIAN_BYTE_ALIGN = "4d4d"; +const LITTLE_ENDIAN_BYTE_ALIGN = "4949"; +const IDF_ENTRY_BYTES = 12; +const NUM_DIRECTORY_ENTRIES_BYTES = 2; +function isEXIF(input) { + return toHexString(input, 2, 6) === EXIF_MARKER; +} +function extractSize(input, index) { + return { + height: readUInt16BE(input, index), + width: readUInt16BE(input, index + 2) + }; +} +function extractOrientation(exifBlock, isBigEndian) { + const idfOffset = 8; + const offset = EXIF_HEADER_BYTES + idfOffset; + const idfDirectoryEntries = readUInt(exifBlock, 16, offset, isBigEndian); + for (let directoryEntryNumber = 0; directoryEntryNumber < idfDirectoryEntries; directoryEntryNumber++) { + const start = offset + NUM_DIRECTORY_ENTRIES_BYTES + directoryEntryNumber * IDF_ENTRY_BYTES; + const end = start + IDF_ENTRY_BYTES; + if (start > exifBlock.length) { + return; + } + const block = exifBlock.slice(start, end); + const tagNumber = readUInt(block, 16, 0, isBigEndian); + if (tagNumber === 274) { + const dataFormat = readUInt(block, 16, 2, isBigEndian); + if (dataFormat !== 3) { + return; + } + const numberOfComponents = readUInt(block, 32, 4, isBigEndian); + if (numberOfComponents !== 1) { + return; + } + return readUInt(block, 16, 8, isBigEndian); + } + } +} +function validateExifBlock(input, index) { + const exifBlock = input.slice(APP1_DATA_SIZE_BYTES, index); + const byteAlign = toHexString( + exifBlock, + EXIF_HEADER_BYTES, + EXIF_HEADER_BYTES + TIFF_BYTE_ALIGN_BYTES + ); + const isBigEndian = byteAlign === BIG_ENDIAN_BYTE_ALIGN; + const isLittleEndian = byteAlign === LITTLE_ENDIAN_BYTE_ALIGN; + if (isBigEndian || isLittleEndian) { + return extractOrientation(exifBlock, isBigEndian); + } +} +function validateInput(input, index) { + if (index > input.length) { + throw new TypeError("Corrupt JPG, exceeded buffer limits"); + } +} +const JPG = { + validate: (input) => toHexString(input, 0, 2) === "ffd8", + calculate(input) { + input = input.slice(4); + let orientation; + let next; + while (input.length) { + const i = readUInt16BE(input, 0); + if (input[i] !== 255) { + input = input.slice(i); + continue; + } + if (isEXIF(input)) { + orientation = validateExifBlock(input, i); + } + validateInput(input, i); + next = input[i + 1]; + if (next === 192 || next === 193 || next === 194) { + const size = extractSize(input, i + 5); + if (!orientation) { + return size; + } + return { + height: size.height, + orientation, + width: size.width + }; + } + input = input.slice(i + 2); + } + throw new TypeError("Invalid JPG, no size found"); + } +}; + +const KTX = { + validate: (input) => { + const signature = toUTF8String(input, 1, 7); + return ["KTX 11", "KTX 20"].includes(signature); + }, + calculate: (input) => { + const type = input[5] === 49 ? "ktx" : "ktx2"; + const offset = type === "ktx" ? 36 : 20; + return { + height: readUInt32LE(input, offset + 4), + width: readUInt32LE(input, offset), + type + }; + } +}; + +const pngSignature = "PNG\r\n\n"; +const pngImageHeaderChunkName = "IHDR"; +const pngFriedChunkName = "CgBI"; +const PNG = { + validate(input) { + if (pngSignature === toUTF8String(input, 1, 8)) { + let chunkName = toUTF8String(input, 12, 16); + if (chunkName === pngFriedChunkName) { + chunkName = toUTF8String(input, 28, 32); + } + if (chunkName !== pngImageHeaderChunkName) { + throw new TypeError("Invalid PNG"); + } + return true; + } + return false; + }, + calculate(input) { + if (toUTF8String(input, 12, 16) === pngFriedChunkName) { + return { + height: readUInt32BE(input, 36), + width: readUInt32BE(input, 32) + }; + } + return { + height: readUInt32BE(input, 20), + width: readUInt32BE(input, 16) + }; + } +}; + +const PNMTypes = { + P1: "pbm/ascii", + P2: "pgm/ascii", + P3: "ppm/ascii", + P4: "pbm", + P5: "pgm", + P6: "ppm", + P7: "pam", + PF: "pfm" +}; +const handlers = { + default: (lines) => { + let dimensions = []; + while (lines.length > 0) { + const line = lines.shift(); + if (line[0] === "#") { + continue; + } + dimensions = line.split(" "); + break; + } + if (dimensions.length === 2) { + return { + height: parseInt(dimensions[1], 10), + width: parseInt(dimensions[0], 10) + }; + } else { + throw new TypeError("Invalid PNM"); + } + }, + pam: (lines) => { + const size = {}; + while (lines.length > 0) { + const line = lines.shift(); + if (line.length > 16 || line.charCodeAt(0) > 128) { + continue; + } + const [key, value] = line.split(" "); + if (key && value) { + size[key.toLowerCase()] = parseInt(value, 10); + } + if (size.height && size.width) { + break; + } + } + if (size.height && size.width) { + return { + height: size.height, + width: size.width + }; + } else { + throw new TypeError("Invalid PAM"); + } + } +}; +const PNM = { + validate: (input) => toUTF8String(input, 0, 2) in PNMTypes, + calculate(input) { + const signature = toUTF8String(input, 0, 2); + const type = PNMTypes[signature]; + const lines = toUTF8String(input, 3).split(/[\r\n]+/); + const handler = handlers[type] || handlers.default; + return handler(lines); + } +}; + +const PSD = { + validate: (input) => toUTF8String(input, 0, 4) === "8BPS", + calculate: (input) => ({ + height: readUInt32BE(input, 14), + width: readUInt32BE(input, 18) + }) +}; + +const svgReg = /"']|"[^"]*"|'[^']*')*>/; +const extractorRegExps = { + height: /\sheight=(['"])([^%]+?)\1/, + root: svgReg, + viewbox: /\sviewBox=(['"])(.+?)\1/i, + width: /\swidth=(['"])([^%]+?)\1/ +}; +const INCH_CM = 2.54; +const units = { + in: 96, + cm: 96 / INCH_CM, + em: 16, + ex: 8, + m: 96 / INCH_CM * 100, + mm: 96 / INCH_CM / 10, + pc: 96 / 72 / 12, + pt: 96 / 72, + px: 1 +}; +const unitsReg = new RegExp( + `^([0-9.]+(?:e\\d+)?)(${Object.keys(units).join("|")})?$` +); +function parseLength(len) { + const m = unitsReg.exec(len); + if (!m) { + return void 0; + } + return Math.round(Number(m[1]) * (units[m[2]] || 1)); +} +function parseViewbox(viewbox) { + const bounds = viewbox.split(" "); + return { + height: parseLength(bounds[3]), + width: parseLength(bounds[2]) + }; +} +function parseAttributes(root) { + const width = extractorRegExps.width.exec(root); + const height = extractorRegExps.height.exec(root); + const viewbox = extractorRegExps.viewbox.exec(root); + return { + height: height && parseLength(height[2]), + viewbox: viewbox && parseViewbox(viewbox[2]), + width: width && parseLength(width[2]) + }; +} +function calculateByDimensions(attrs) { + return { + height: attrs.height, + width: attrs.width + }; +} +function calculateByViewbox(attrs, viewbox) { + const ratio = viewbox.width / viewbox.height; + if (attrs.width) { + return { + height: Math.floor(attrs.width / ratio), + width: attrs.width + }; + } + if (attrs.height) { + return { + height: attrs.height, + width: Math.floor(attrs.height * ratio) + }; + } + return { + height: viewbox.height, + width: viewbox.width + }; +} +const SVG = { + // Scan only the first kilo-byte to speed up the check on larger files + validate: (input) => svgReg.test(toUTF8String(input, 0, 1e3)), + calculate(input) { + const root = extractorRegExps.root.exec(toUTF8String(input)); + if (root) { + const attrs = parseAttributes(root[0]); + if (attrs.width && attrs.height) { + return calculateByDimensions(attrs); + } + if (attrs.viewbox) { + return calculateByViewbox(attrs, attrs.viewbox); + } + } + throw new TypeError("Invalid SVG"); + } +}; + +const TGA = { + validate(input) { + return readUInt16LE(input, 0) === 0 && readUInt16LE(input, 4) === 0; + }, + calculate(input) { + return { + height: readUInt16LE(input, 14), + width: readUInt16LE(input, 12) + }; + } +}; + +function readIFD(input, isBigEndian) { + const ifdOffset = readUInt(input, 32, 4, isBigEndian); + return input.slice(ifdOffset + 2); +} +function readValue(input, isBigEndian) { + const low = readUInt(input, 16, 8, isBigEndian); + const high = readUInt(input, 16, 10, isBigEndian); + return (high << 16) + low; +} +function nextTag(input) { + if (input.length > 24) { + return input.slice(12); + } +} +function extractTags(input, isBigEndian) { + const tags = {}; + let temp = input; + while (temp && temp.length) { + const code = readUInt(temp, 16, 0, isBigEndian); + const type = readUInt(temp, 16, 2, isBigEndian); + const length = readUInt(temp, 32, 4, isBigEndian); + if (code === 0) { + break; + } else { + if (length === 1 && (type === 3 || type === 4)) { + tags[code] = readValue(temp, isBigEndian); + } + temp = nextTag(temp); + } + } + return tags; +} +function determineEndianness(input) { + const signature = toUTF8String(input, 0, 2); + if ("II" === signature) { + return "LE"; + } else if ("MM" === signature) { + return "BE"; + } +} +const signatures = [ + // '492049', // currently not supported + "49492a00", + // Little endian + "4d4d002a" + // Big Endian + // '4d4d002a', // BigTIFF > 4GB. currently not supported +]; +const TIFF = { + validate: (input) => signatures.includes(toHexString(input, 0, 4)), + calculate(input) { + const isBigEndian = determineEndianness(input) === "BE"; + const ifdBuffer = readIFD(input, isBigEndian); + const tags = extractTags(ifdBuffer, isBigEndian); + const width = tags[256]; + const height = tags[257]; + if (!width || !height) { + throw new TypeError("Invalid Tiff. Missing tags"); + } + return { height, width }; + } +}; + +function calculateExtended(input) { + return { + height: 1 + readUInt24LE(input, 7), + width: 1 + readUInt24LE(input, 4) + }; +} +function calculateLossless(input) { + return { + height: 1 + ((input[4] & 15) << 10 | input[3] << 2 | (input[2] & 192) >> 6), + width: 1 + ((input[2] & 63) << 8 | input[1]) + }; +} +function calculateLossy(input) { + return { + height: readInt16LE(input, 8) & 16383, + width: readInt16LE(input, 6) & 16383 + }; +} +const WEBP = { + validate(input) { + const riffHeader = "RIFF" === toUTF8String(input, 0, 4); + const webpHeader = "WEBP" === toUTF8String(input, 8, 12); + const vp8Header = "VP8" === toUTF8String(input, 12, 15); + return riffHeader && webpHeader && vp8Header; + }, + calculate(input) { + const chunkHeader = toUTF8String(input, 12, 16); + input = input.slice(20, 30); + if (chunkHeader === "VP8X") { + const extendedHeader = input[0]; + const validStart = (extendedHeader & 192) === 0; + const validEnd = (extendedHeader & 1) === 0; + if (validStart && validEnd) { + return calculateExtended(input); + } else { + throw new TypeError("Invalid WebP"); + } + } + if (chunkHeader === "VP8 " && input[0] !== 47) { + return calculateLossy(input); + } + const signature = toHexString(input, 3, 6); + if (chunkHeader === "VP8L" && signature !== "9d012a") { + return calculateLossless(input); + } + throw new TypeError("Invalid WebP"); + } +}; + +const typeHandlers = /* @__PURE__ */ new Map([ + ["bmp", BMP], + ["cur", CUR], + ["dds", DDS], + ["gif", GIF], + ["heif", HEIF], + ["icns", ICNS], + ["ico", ICO], + ["j2c", J2C], + ["jp2", JP2], + ["jpg", JPG], + ["ktx", KTX], + ["png", PNG], + ["pnm", PNM], + ["psd", PSD], + ["svg", SVG], + ["tga", TGA], + ["tiff", TIFF], + ["webp", WEBP] +]); +const types = Array.from(typeHandlers.keys()); + +const firstBytes = /* @__PURE__ */ new Map([ + [56, "psd"], + [66, "bmp"], + [68, "dds"], + [71, "gif"], + [73, "tiff"], + [77, "tiff"], + [82, "webp"], + [105, "icns"], + [137, "png"], + [255, "jpg"] +]); +function detector(input) { + const byte = input[0]; + const type = firstBytes.get(byte); + if (type && typeHandlers.get(type).validate(input)) { + return type; + } + return types.find((fileType) => typeHandlers.get(fileType).validate(input)); +} + +function lookup(input) { + const type = detector(input); + if (typeof type !== "undefined") { + const size = typeHandlers.get(type).calculate(input); + if (size !== void 0) { + size.type = size.type ?? type; + return size; + } + } + throw new TypeError("unsupported file type: " + type); +} + +async function imageMetadata(data, src) { + let result; + try { + result = lookup(data); + } catch { + throw new AstroError({ + ...NoImageMetadata, + message: NoImageMetadata.message(src) + }); + } + if (!result.height || !result.width || !result.type) { + throw new AstroError({ + ...NoImageMetadata, + message: NoImageMetadata.message(src) + }); + } + const { width, height, type, orientation } = result; + const isPortrait = (orientation || 0) >= 5; + return { + width: isPortrait ? height : width, + height: isPortrait ? width : height, + format: type, + orientation + }; +} + +async function inferRemoteSize(url) { + const response = await fetch(url); + if (!response.body || !response.ok) { + throw new AstroError({ + ...FailedToFetchRemoteImageDimensions, + message: FailedToFetchRemoteImageDimensions.message(url) + }); + } + const reader = response.body.getReader(); + let done, value; + let accumulatedChunks = new Uint8Array(); + while (!done) { + const readResult = await reader.read(); + done = readResult.done; + if (done) break; + if (readResult.value) { + value = readResult.value; + let tmp = new Uint8Array(accumulatedChunks.length + value.length); + tmp.set(accumulatedChunks, 0); + tmp.set(value, accumulatedChunks.length); + accumulatedChunks = tmp; + try { + const dimensions = await imageMetadata(accumulatedChunks, url); + if (dimensions) { + await reader.cancel(); + return dimensions; + } + } catch { + } + } + } + throw new AstroError({ + ...NoImageMetadata, + message: NoImageMetadata.message(url) + }); +} + +const PLACEHOLDER_BASE = "astro://placeholder"; +function createPlaceholderURL(pathOrUrl) { + return new URL(pathOrUrl, PLACEHOLDER_BASE); +} +function stringifyPlaceholderURL(url) { + return url.href.replace(PLACEHOLDER_BASE, ""); +} + +async function getConfiguredImageService() { + if (!globalThis?.astroAsset?.imageService) { + const { default: service } = await import( + // @ts-expect-error + './sharp_CR567j69.mjs' + ).catch((e) => { + const error = new AstroError(InvalidImageService); + error.cause = e; + throw error; + }); + if (!globalThis.astroAsset) globalThis.astroAsset = {}; + globalThis.astroAsset.imageService = service; + return service; + } + return globalThis.astroAsset.imageService; +} +async function getImage$1(options, imageConfig) { + if (!options || typeof options !== "object") { + throw new AstroError({ + ...ExpectedImageOptions, + message: ExpectedImageOptions.message(JSON.stringify(options)) + }); + } + if (typeof options.src === "undefined") { + throw new AstroError({ + ...ExpectedImage, + message: ExpectedImage.message( + options.src, + "undefined", + JSON.stringify(options) + ) + }); + } + if (isImageMetadata(options)) { + throw new AstroError(ExpectedNotESMImage); + } + const service = await getConfiguredImageService(); + const resolvedOptions = { + ...options, + src: await resolveSrc(options.src) + }; + let originalWidth; + let originalHeight; + if (options.inferSize && isRemoteImage(resolvedOptions.src) && isRemotePath(resolvedOptions.src)) { + const result = await inferRemoteSize(resolvedOptions.src); + resolvedOptions.width ??= result.width; + resolvedOptions.height ??= result.height; + originalWidth = result.width; + originalHeight = result.height; + delete resolvedOptions.inferSize; + } + const originalFilePath = isESMImportedImage(resolvedOptions.src) ? resolvedOptions.src.fsPath : void 0; + const clonedSrc = isESMImportedImage(resolvedOptions.src) ? ( + // @ts-expect-error - clone is a private, hidden prop + resolvedOptions.src.clone ?? resolvedOptions.src + ) : resolvedOptions.src; + if (isESMImportedImage(clonedSrc)) { + originalWidth = clonedSrc.width; + originalHeight = clonedSrc.height; + } + if (originalWidth && originalHeight) { + const aspectRatio = originalWidth / originalHeight; + if (resolvedOptions.height && !resolvedOptions.width) { + resolvedOptions.width = Math.round(resolvedOptions.height * aspectRatio); + } else if (resolvedOptions.width && !resolvedOptions.height) { + resolvedOptions.height = Math.round(resolvedOptions.width / aspectRatio); + } else if (!resolvedOptions.width && !resolvedOptions.height) { + resolvedOptions.width = originalWidth; + resolvedOptions.height = originalHeight; + } + } + resolvedOptions.src = clonedSrc; + const layout = options.layout ?? imageConfig.layout ?? "none"; + if (resolvedOptions.priority) { + resolvedOptions.loading ??= "eager"; + resolvedOptions.decoding ??= "sync"; + resolvedOptions.fetchpriority ??= "high"; + delete resolvedOptions.priority; + } else { + resolvedOptions.loading ??= "lazy"; + resolvedOptions.decoding ??= "async"; + resolvedOptions.fetchpriority ??= "auto"; + } + if (layout !== "none") { + resolvedOptions.widths ||= getWidths({ + width: resolvedOptions.width, + layout, + originalWidth, + breakpoints: imageConfig.breakpoints?.length ? imageConfig.breakpoints : isLocalService(service) ? LIMITED_RESOLUTIONS : DEFAULT_RESOLUTIONS + }); + resolvedOptions.sizes ||= getSizesAttribute({ width: resolvedOptions.width, layout }); + delete resolvedOptions.densities; + resolvedOptions.style = addCSSVarsToStyle( + { + fit: cssFitValues.includes(resolvedOptions.fit ?? "") && resolvedOptions.fit, + pos: resolvedOptions.position + }, + resolvedOptions.style + ); + resolvedOptions["data-astro-image"] = layout; + } + const validatedOptions = service.validateOptions ? await service.validateOptions(resolvedOptions, imageConfig) : resolvedOptions; + const srcSetTransforms = service.getSrcSet ? await service.getSrcSet(validatedOptions, imageConfig) : []; + let imageURL = await service.getURL(validatedOptions, imageConfig); + const matchesValidatedTransform = (transform) => transform.width === validatedOptions.width && transform.height === validatedOptions.height && transform.format === validatedOptions.format; + let srcSets = await Promise.all( + srcSetTransforms.map(async (srcSet) => { + return { + transform: srcSet.transform, + url: matchesValidatedTransform(srcSet.transform) ? imageURL : await service.getURL(srcSet.transform, imageConfig), + descriptor: srcSet.descriptor, + attributes: srcSet.attributes + }; + }) + ); + if (isLocalService(service) && globalThis.astroAsset.addStaticImage && !(isRemoteImage(validatedOptions.src) && imageURL === validatedOptions.src)) { + const propsToHash = service.propertiesToHash ?? DEFAULT_HASH_PROPS; + imageURL = globalThis.astroAsset.addStaticImage( + validatedOptions, + propsToHash, + originalFilePath + ); + srcSets = srcSetTransforms.map((srcSet) => { + return { + transform: srcSet.transform, + url: matchesValidatedTransform(srcSet.transform) ? imageURL : globalThis.astroAsset.addStaticImage(srcSet.transform, propsToHash, originalFilePath), + descriptor: srcSet.descriptor, + attributes: srcSet.attributes + }; + }); + } else if (imageConfig.assetQueryParams) { + const imageURLObj = createPlaceholderURL(imageURL); + imageConfig.assetQueryParams.forEach((value, key) => { + imageURLObj.searchParams.set(key, value); + }); + imageURL = stringifyPlaceholderURL(imageURLObj); + srcSets = srcSets.map((srcSet) => { + const urlObj = createPlaceholderURL(srcSet.url); + imageConfig.assetQueryParams.forEach((value, key) => { + urlObj.searchParams.set(key, value); + }); + return { + ...srcSet, + url: stringifyPlaceholderURL(urlObj) + }; + }); + } + return { + rawOptions: resolvedOptions, + options: validatedOptions, + src: imageURL, + srcSet: { + values: srcSets, + attribute: srcSets.map((srcSet) => `${srcSet.url} ${srcSet.descriptor}`).join(", ") + }, + attributes: service.getHTMLAttributes !== void 0 ? await service.getHTMLAttributes(validatedOptions, imageConfig) : {} + }; +} + +const $$Astro$2 = createAstro(); +const $$Image = createComponent(async ($$result, $$props, $$slots) => { + const Astro2 = $$result.createAstro($$Astro$2, $$props, $$slots); + Astro2.self = $$Image; + const props = Astro2.props; + if (props.alt === void 0 || props.alt === null) { + throw new AstroError(ImageMissingAlt); + } + if (typeof props.width === "string") { + props.width = parseInt(props.width); + } + if (typeof props.height === "string") { + props.height = parseInt(props.height); + } + const layout = props.layout ?? imageConfig.layout ?? "none"; + if (layout !== "none") { + props.layout ??= imageConfig.layout; + props.fit ??= imageConfig.objectFit ?? "cover"; + props.position ??= imageConfig.objectPosition ?? "center"; + } + const image = await getImage(props); + const additionalAttributes = {}; + if (image.srcSet.values.length > 0) { + additionalAttributes.srcset = image.srcSet.attribute; + } + const { class: className, ...attributes } = { ...additionalAttributes, ...image.attributes }; + return renderTemplate`${maybeRenderHead()}`; +}, "/Users/adrianlam/GitHub/workflow/node_modules/.pnpm/astro@5.15.6_@netlify+blobs@9.1.2_@types+node@24.6.2_@vercel+functions@3.1.4_@aws-sdk+c_33d54f21a5540c974d08dc1b122d5cc1/node_modules/astro/components/Image.astro", void 0); + +const $$Astro$1 = createAstro(); +const $$Picture = createComponent(async ($$result, $$props, $$slots) => { + const Astro2 = $$result.createAstro($$Astro$1, $$props, $$slots); + Astro2.self = $$Picture; + const defaultFormats = ["webp"]; + const defaultFallbackFormat = "png"; + const specialFormatsFallback = ["gif", "svg", "jpg", "jpeg"]; + const { formats = defaultFormats, pictureAttributes = {}, fallbackFormat, ...props } = Astro2.props; + if (props.alt === void 0 || props.alt === null) { + throw new AstroError(ImageMissingAlt); + } + const scopedStyleClass = props.class?.match(/\bastro-\w{8}\b/)?.[0]; + if (scopedStyleClass) { + if (pictureAttributes.class) { + pictureAttributes.class = `${pictureAttributes.class} ${scopedStyleClass}`; + } else { + pictureAttributes.class = scopedStyleClass; + } + } + const layout = props.layout ?? imageConfig.layout ?? "none"; + const useResponsive = layout !== "none"; + if (useResponsive) { + props.layout ??= imageConfig.layout; + props.fit ??= imageConfig.objectFit ?? "cover"; + props.position ??= imageConfig.objectPosition ?? "center"; + } + for (const key in props) { + if (key.startsWith("data-astro-cid")) { + pictureAttributes[key] = props[key]; + } + } + const originalSrc = await resolveSrc(props.src); + const optimizedImages = await Promise.all( + formats.map( + async (format) => await getImage({ + ...props, + src: originalSrc, + format, + widths: props.widths, + densities: props.densities + }) + ) + ); + let resultFallbackFormat = fallbackFormat ?? defaultFallbackFormat; + if (!fallbackFormat && isESMImportedImage(originalSrc) && specialFormatsFallback.includes(originalSrc.format)) { + resultFallbackFormat = originalSrc.format; + } + const fallbackImage = await getImage({ + ...props, + format: resultFallbackFormat, + widths: props.widths, + densities: props.densities + }); + const imgAdditionalAttributes = {}; + const sourceAdditionalAttributes = {}; + if (props.sizes) { + sourceAdditionalAttributes.sizes = props.sizes; + } + if (fallbackImage.srcSet.values.length > 0) { + imgAdditionalAttributes.srcset = fallbackImage.srcSet.attribute; + } + const { class: className, ...attributes } = { + ...imgAdditionalAttributes, + ...fallbackImage.attributes + }; + return renderTemplate`${maybeRenderHead()} ${Object.entries(optimizedImages).map(([_, image]) => { + const srcsetAttribute = props.densities || !props.densities && !props.widths && !useResponsive ? `${image.src}${image.srcSet.values.length > 0 ? ", " + image.srcSet.attribute : ""}` : image.srcSet.attribute; + return renderTemplate``; + })} `; +}, "/Users/adrianlam/GitHub/workflow/node_modules/.pnpm/astro@5.15.6_@netlify+blobs@9.1.2_@types+node@24.6.2_@vercel+functions@3.1.4_@aws-sdk+c_33d54f21a5540c974d08dc1b122d5cc1/node_modules/astro/components/Picture.astro", void 0); + +const fontsMod = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ + __proto__: null +}, Symbol.toStringTag, { value: 'Module' })); + +function filterPreloads(data, preload) { + if (!preload) { + return null; + } + if (preload === true) { + return data; + } + return data.filter( + ({ weight, style, subset }) => preload.some((p) => { + if (p.weight !== void 0 && weight !== void 0 && !checkWeight(p.weight.toString(), weight)) { + return false; + } + if (p.style !== void 0 && p.style !== style) { + return false; + } + if (p.subset !== void 0 && p.subset !== subset) { + return false; + } + return true; + }) + ); +} +function checkWeight(input, target) { + const trimmedInput = input.trim(); + if (trimmedInput.includes(" ")) { + return trimmedInput === target; + } + if (target.includes(" ")) { + const [a, b] = target.split(" "); + const parsedInput = Number.parseInt(input); + return parsedInput >= Number.parseInt(a) && parsedInput <= Number.parseInt(b); + } + return input === target; +} + +const $$Astro = createAstro(); +const $$Font = createComponent(($$result, $$props, $$slots) => { + const Astro2 = $$result.createAstro($$Astro, $$props, $$slots); + Astro2.self = $$Font; + const { internalConsumableMap } = fontsMod; + if (!internalConsumableMap) { + throw new AstroError(ExperimentalFontsNotEnabled); + } + const { cssVariable, preload = false } = Astro2.props; + const data = internalConsumableMap.get(cssVariable); + if (!data) { + throw new AstroError({ + ...FontFamilyNotFound, + message: FontFamilyNotFound.message(cssVariable) + }); + } + const filteredPreloadData = filterPreloads(data.preloadData, preload); + return renderTemplate`${filteredPreloadData?.map(({ url, type }) => renderTemplate``)}`; +}, "/Users/adrianlam/GitHub/workflow/node_modules/.pnpm/astro@5.15.6_@netlify+blobs@9.1.2_@types+node@24.6.2_@vercel+functions@3.1.4_@aws-sdk+c_33d54f21a5540c974d08dc1b122d5cc1/node_modules/astro/components/Font.astro", void 0); + +const assetQueryParams = undefined; + const imageConfig = {"endpoint":{"route":"/_image","entrypoint":"astro/assets/endpoint/node"},"service":{"entrypoint":"astro/assets/services/sharp","config":{}},"domains":[],"remotePatterns":[],"responsiveStyles":false}; + Object.defineProperty(imageConfig, 'assetQueryParams', { + value: assetQueryParams, + enumerable: false, + configurable: true, + }); + // This is used by the @astrojs/node integration to locate images. + // It's unused on other platforms, but on some platforms like Netlify (and presumably also Vercel) + // new URL("dist/...") is interpreted by the bundler as a signal to include that directory + // in the Lambda bundle, which would bloat the bundle with images. + // To prevent this, we mark the URL construction as pure, + // so that it's tree-shaken away for all platforms that don't need it. + const outDir = /* #__PURE__ */ new URL("file:///Users/adrianlam/GitHub/workflow/workbench/astro/dist/client/"); + const getImage = async (options) => await getImage$1(options, imageConfig); + +const fnv1a52 = (str) => { + const len = str.length; + let i = 0, t0 = 0, v0 = 8997, t1 = 0, v1 = 33826, t2 = 0, v2 = 40164, t3 = 0, v3 = 52210; + while (i < len) { + v0 ^= str.charCodeAt(i++); + t0 = v0 * 435; + t1 = v1 * 435; + t2 = v2 * 435; + t3 = v3 * 435; + t2 += v0 << 8; + t3 += v1 << 8; + t1 += t0 >>> 16; + v0 = t0 & 65535; + t2 += t1 >>> 16; + v1 = t1 & 65535; + v3 = t3 + (t2 >>> 16) & 65535; + v2 = t2 & 65535; + } + return (v3 & 15) * 281474976710656 + v2 * 4294967296 + v1 * 65536 + (v0 ^ v3 >> 4); +}; +const etag = (payload, weak = false) => { + const prefix = weak ? 'W/"' : '"'; + return prefix + fnv1a52(payload).toString(36) + payload.length.toString(36) + '"'; +}; + +async function loadRemoteImage(src) { + try { + const res = await fetch(src); + if (!res.ok) { + return void 0; + } + return Buffer.from(await res.arrayBuffer()); + } catch { + return void 0; + } +} +const handleImageRequest = async ({ + request, + loadLocalImage +}) => { + const imageService = await getConfiguredImageService(); + if (!("transform" in imageService)) { + throw new Error("Configured image service is not a local service"); + } + const url = new URL(request.url); + const transform = await imageService.parseURL(url, imageConfig); + if (!transform?.src) { + return new Response("Invalid request", { status: 400 }); + } + let inputBuffer = void 0; + if (isRemotePath(transform.src)) { + if (!isRemoteAllowed(transform.src, imageConfig)) { + return new Response("Forbidden", { status: 403 }); + } + inputBuffer = await loadRemoteImage(new URL(transform.src)); + } else { + inputBuffer = await loadLocalImage(removeQueryString(transform.src), url); + } + if (!inputBuffer) { + return new Response("Internal Server Error", { status: 500 }); + } + const { data, format } = await imageService.transform(inputBuffer, transform, imageConfig); + return new Response(data, { + status: 200, + headers: { + "Content-Type": mime.lookup(format) ?? `image/${format}`, + "Cache-Control": "public, max-age=31536000", + ETag: etag(data.toString()), + Date: (/* @__PURE__ */ new Date()).toUTCString() + } + }); +}; + +async function loadLocalImage(src, url) { + const idx = url.pathname.indexOf("/_image"); + if (idx > 0) { + src = src.slice(idx); + } + if (!URL.canParse("." + src, outDir)) { + return void 0; + } + const fileUrl = new URL("." + src, outDir); + if (fileUrl.protocol !== "file:") { + return void 0; + } + if (!isParentDirectory(fileURLToPath(outDir), fileURLToPath(fileUrl))) { + return void 0; + } + try { + return await readFile(fileUrl); + } catch { + return void 0; + } +} +const GET = async ({ request }) => { + try { + return await handleImageRequest({ request, loadLocalImage }); + } catch (err) { + console.error("Could not process image request:", err); + return new Response("Internal Server Error", { + status: 500 + }); + } +}; + +const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ + __proto__: null, + GET +}, Symbol.toStringTag, { value: 'Module' })); + +const page = () => _page; + +export { page as a, baseService as b, parseQuality as p }; diff --git a/workbench/astro/dist/server/chunks/remote_OOD9OFqU.mjs b/workbench/astro/dist/server/chunks/remote_OOD9OFqU.mjs new file mode 100644 index 000000000..33d88f004 --- /dev/null +++ b/workbench/astro/dist/server/chunks/remote_OOD9OFqU.mjs @@ -0,0 +1,188 @@ +function appendForwardSlash(path) { + return path.endsWith("/") ? path : path + "/"; +} +function prependForwardSlash(path) { + return path[0] === "/" ? path : "/" + path; +} +const MANY_TRAILING_SLASHES = /\/{2,}$/g; +function collapseDuplicateTrailingSlashes(path, trailingSlash) { + if (!path) { + return path; + } + return path.replace(MANY_TRAILING_SLASHES, trailingSlash ? "/" : "") || "/"; +} +function removeTrailingForwardSlash(path) { + return path.endsWith("/") ? path.slice(0, path.length - 1) : path; +} +function removeLeadingForwardSlash(path) { + return path.startsWith("/") ? path.substring(1) : path; +} +function trimSlashes(path) { + return path.replace(/^\/|\/$/g, ""); +} +function isString(path) { + return typeof path === "string" || path instanceof String; +} +const INTERNAL_PREFIXES = /* @__PURE__ */ new Set(["/_", "/@", "/.", "//"]); +const JUST_SLASHES = /^\/{2,}$/; +function isInternalPath(path) { + return INTERNAL_PREFIXES.has(path.slice(0, 2)) && !JUST_SLASHES.test(path); +} +function joinPaths(...paths) { + return paths.filter(isString).map((path, i) => { + if (i === 0) { + return removeTrailingForwardSlash(path); + } else if (i === paths.length - 1) { + return removeLeadingForwardSlash(path); + } else { + return trimSlashes(path); + } + }).join("/"); +} +function removeQueryString(path) { + const index = path.lastIndexOf("?"); + return index > 0 ? path.substring(0, index) : path; +} +function isRemotePath(src) { + if (!src) return false; + const trimmed = src.trim(); + if (!trimmed) return false; + let decoded = trimmed; + let previousDecoded = ""; + let maxIterations = 10; + while (decoded !== previousDecoded && maxIterations > 0) { + previousDecoded = decoded; + try { + decoded = decodeURIComponent(decoded); + } catch { + break; + } + maxIterations--; + } + if (/^[a-zA-Z]:/.test(decoded)) { + return false; + } + if (decoded[0] === "/" && decoded[1] !== "/" && decoded[1] !== "\\") { + return false; + } + if (decoded[0] === "\\") { + return true; + } + if (decoded.startsWith("//")) { + return true; + } + try { + const url = new URL(decoded, "http://n"); + if (url.username || url.password) { + return true; + } + if (decoded.includes("@") && !url.pathname.includes("@") && !url.search.includes("@")) { + return true; + } + if (url.origin !== "http://n") { + const protocol = url.protocol.toLowerCase(); + if (protocol === "file:") { + return false; + } + return true; + } + if (URL.canParse(decoded)) { + return true; + } + return false; + } catch { + return true; + } +} +function isParentDirectory(parentPath, childPath) { + if (!parentPath || !childPath) { + return false; + } + if (parentPath.includes("://") || childPath.includes("://")) { + return false; + } + if (isRemotePath(parentPath) || isRemotePath(childPath)) { + return false; + } + if (parentPath.includes("..") || childPath.includes("..")) { + return false; + } + if (parentPath.includes("\0") || childPath.includes("\0")) { + return false; + } + const normalizedParent = appendForwardSlash(slash(parentPath).toLowerCase()); + const normalizedChild = slash(childPath).toLowerCase(); + if (normalizedParent === normalizedChild || normalizedParent === normalizedChild + "/") { + return false; + } + return normalizedChild.startsWith(normalizedParent); +} +function slash(path) { + return path.replace(/\\/g, "/"); +} +function fileExtension(path) { + const ext = path.split(".").pop(); + return ext !== path ? `.${ext}` : ""; +} +const WITH_FILE_EXT = /\/[^/]+\.\w+$/; +function hasFileExtension(path) { + return WITH_FILE_EXT.test(path); +} + +function matchPattern(url, remotePattern) { + return matchProtocol(url, remotePattern.protocol) && matchHostname(url, remotePattern.hostname, true) && matchPort(url, remotePattern.port) && matchPathname(url, remotePattern.pathname, true); +} +function matchPort(url, port) { + return !port || port === url.port; +} +function matchProtocol(url, protocol) { + return !protocol || protocol === url.protocol.slice(0, -1); +} +function matchHostname(url, hostname, allowWildcard = false) { + if (!hostname) { + return true; + } else if (!allowWildcard || !hostname.startsWith("*")) { + return hostname === url.hostname; + } else if (hostname.startsWith("**.")) { + const slicedHostname = hostname.slice(2); + return slicedHostname !== url.hostname && url.hostname.endsWith(slicedHostname); + } else if (hostname.startsWith("*.")) { + const slicedHostname = hostname.slice(1); + const additionalSubdomains = url.hostname.replace(slicedHostname, "").split(".").filter(Boolean); + return additionalSubdomains.length === 1; + } + return false; +} +function matchPathname(url, pathname, allowWildcard = false) { + if (!pathname) { + return true; + } else if (!allowWildcard || !pathname.endsWith("*")) { + return pathname === url.pathname; + } else if (pathname.endsWith("/**")) { + const slicedPathname = pathname.slice(0, -2); + return slicedPathname !== url.pathname && url.pathname.startsWith(slicedPathname); + } else if (pathname.endsWith("/*")) { + const slicedPathname = pathname.slice(0, -1); + const additionalPathChunks = url.pathname.replace(slicedPathname, "").split("/").filter(Boolean); + return additionalPathChunks.length === 1; + } + return false; +} +function isRemoteAllowed(src, { + domains, + remotePatterns +}) { + if (!URL.canParse(src)) { + return false; + } + const url = new URL(src); + if (url.protocol === "data:") { + return true; + } + if (!["http:", "https:"].includes(url.protocol)) { + return false; + } + return domains.some((domain) => matchHostname(url, domain)) || remotePatterns.some((remotePattern) => matchPattern(url, remotePattern)); +} + +export { isRemotePath as a, isParentDirectory as b, appendForwardSlash as c, removeTrailingForwardSlash as d, isInternalPath as e, fileExtension as f, collapseDuplicateTrailingSlashes as g, hasFileExtension as h, isRemoteAllowed as i, joinPaths as j, matchPattern as m, prependForwardSlash as p, removeQueryString as r, slash as s, trimSlashes as t }; diff --git a/workbench/astro/dist/server/chunks/resume-hook_BHshEMMl.mjs b/workbench/astro/dist/server/chunks/resume-hook_BHshEMMl.mjs new file mode 100644 index 000000000..f524da81b --- /dev/null +++ b/workbench/astro/dist/server/chunks/resume-hook_BHshEMMl.mjs @@ -0,0 +1,181 @@ +import { c as getWorld, h as hydrateStepArguments, w as waitedUntil, d as WEBHOOK_RESPONSE_WRITABLE, e as WorkflowRuntimeError, E as ERROR_SLUGS, t as trace, f as WorkflowRunId, H as HookId, i as HookToken, j as dehydrateStepReturnValue, k as functionsExports, l as WorkflowName, m as getSpanContextForTraceCarrier, n as HookFound } from './index_ePTMDSOu.mjs'; + +/** + * Get the hook by token to find the associated workflow run, + * and hydrate the `metadata` property if it was set from within + * the workflow run. + * + * @param token - The unique token identifying the hook + */ +async function getHookByToken(token) { + const world = getWorld(); + const hook = await world.hooks.getByToken(token); + if (typeof hook.metadata !== 'undefined') { + hook.metadata = hydrateStepArguments(hook.metadata, [], globalThis); + } + return hook; +} +/** + * Resumes a workflow run by sending a payload to a hook identified by its token. + * + * This function is called externally (e.g., from an API route or server action) + * to send data to a hook and resume the associated workflow run. + * + * @param token - The unique token identifying the hook + * @param payload - The data payload to send to the hook + * @returns Promise resolving to the hook + * @throws Error if the hook is not found or if there's an error during the process + * + * @example + * + * ```ts + * // In an API route + * import { resumeHook } from '@workflow/core/runtime'; + * + * export async function POST(request: Request) { + * const { token, data } = await request.json(); + * + * try { + * const hook = await resumeHook(token, data); + * return Response.json({ runId: hook.runId }); + * } catch (error) { + * return new Response('Hook not found', { status: 404 }); + * } + * } + * ``` + */ +async function resumeHook(token, payload) { + return await waitedUntil(() => { + return trace('HOOK.resume', async (span) => { + const world = getWorld(); + try { + const hook = await getHookByToken(token); + span?.setAttributes({ + ...HookToken(token), + ...HookId(hook.hookId), + ...WorkflowRunId(hook.runId), + }); + // Dehydrate the payload for storage + const ops = []; + const dehydratedPayload = dehydrateStepReturnValue(payload, ops, globalThis); + functionsExports.waitUntil(Promise.all(ops)); + // Create a hook_received event with the payload + await world.events.create(hook.runId, { + eventType: 'hook_received', + correlationId: hook.hookId, + eventData: { + payload: dehydratedPayload, + }, + }); + const workflowRun = await world.runs.get(hook.runId); + span?.setAttributes({ + ...WorkflowName(workflowRun.workflowName), + }); + const traceCarrier = workflowRun.executionContext?.traceCarrier; + if (traceCarrier) { + const context = await getSpanContextForTraceCarrier(traceCarrier); + if (context) { + span?.addLink?.({ context }); + } + } + // Re-trigger the workflow against the deployment ID associated + // with the workflow run that the hook belongs to + await world.queue(`__wkf_workflow_${workflowRun.workflowName}`, { + runId: hook.runId, + // attach the trace carrier from the workflow run + traceCarrier: workflowRun.executionContext?.traceCarrier ?? undefined, + }, { + deploymentId: workflowRun.deploymentId, + }); + return hook; + } + catch (err) { + span?.setAttributes({ + ...HookToken(token), + ...HookFound(false), + }); + throw err; + } + }); + }); +} +/** + * Resumes a webhook by sending a {@link https://developer.mozilla.org/en-US/docs/Web/API/Request | Request} + * object to a hook identified by its token. + * + * This function is called externally (e.g., from an API route or server action) + * to send a request to a webhook and resume the associated workflow run. + * + * @param token - The unique token identifying the hook + * @param request - The request to send to the hook + * @returns Promise resolving to the response + * @throws Error if the hook is not found or if there's an error during the process + * + * @example + * + * ```ts + * // In an API route + * import { resumeWebhook } from '@workflow/core/runtime'; + * + * export async function POST(request: Request) { + * const url = new URL(request.url); + * const token = url.searchParams.get('token'); + * + * if (!token) { + * return new Response('Missing token', { status: 400 }); + * } + * + * try { + * const response = await resumeWebhook(token, request); + * return response; + * } catch (error) { + * return new Response('Webhook not found', { status: 404 }); + * } + * } + * ``` + */ +async function resumeWebhook(token, request) { + const hook = await getHookByToken(token); + let response; + let responseReadable; + if (hook.metadata && + typeof hook.metadata === 'object' && + 'respondWith' in hook.metadata) { + if (hook.metadata.respondWith === 'manual') { + const { readable, writable } = new TransformStream(); + responseReadable = readable; + // The request instance includes the writable stream which will be used + // to write the response to the client from within the workflow run + request[WEBHOOK_RESPONSE_WRITABLE] = writable; + } + else if (hook.metadata.respondWith instanceof Response) { + response = hook.metadata.respondWith; + } + else { + throw new WorkflowRuntimeError(`Invalid \`respondWith\` value: ${hook.metadata.respondWith}`, { slug: ERROR_SLUGS.WEBHOOK_INVALID_RESPOND_WITH_VALUE }); + } + } + else { + // No `respondWith` value implies the default behavior of returning a 202 + response = new Response(null, { status: 202 }); + } + await resumeHook(hook.token, request); + if (responseReadable) { + // Wait for the readable stream to emit one chunk, + // which is the `Response` object + const reader = responseReadable.getReader(); + const chunk = await reader.read(); + if (chunk.value) { + response = chunk.value; + } + reader.cancel(); + } + if (!response) { + throw new WorkflowRuntimeError('Workflow run did not send a response', { + slug: ERROR_SLUGS.WEBHOOK_RESPONSE_NOT_SENT, + }); + } + return response; +} + +export { resumeHook as a, getHookByToken as g, resumeWebhook as r }; diff --git a/workbench/astro/dist/server/chunks/runtime_CxdH0OC2.mjs b/workbench/astro/dist/server/chunks/runtime_CxdH0OC2.mjs new file mode 100644 index 000000000..07a56f19e --- /dev/null +++ b/workbench/astro/dist/server/chunks/runtime_CxdH0OC2.mjs @@ -0,0 +1,2039 @@ +import { z as withResolvers, A as stepLogger, B as EventConsumerResult, e as WorkflowRuntimeError, F as FatalError, C as hydrateStepReturnValue, G as seedrandom, I as webhookLogger, J as parseDurationToDate, t as trace, K as WorkflowEventsCount, u as WorkflowRunStatus, f as WorkflowRunId, l as WorkflowName, L as getPort, M as monotonicFactory, N as EventsConsumer, O as WORKFLOW_USE_STEP, P as WORKFLOW_CREATE_HOOK, Q as WORKFLOW_SLEEP, g as getWorkflowRunStreamId, R as WORKFLOW_GET_STREAM_ID, E as ERROR_SLUGS, v as hydrateWorkflowArguments, p as WorkflowArgumentsCount, S as dehydrateWorkflowReturnValue, T as WorkflowResultType, U as BODY_INIT_SYMBOL, V as getWorldHandlers, X as WorkflowInvokePayloadSchema, Y as withTraceContext, Z as StepInvokePayloadSchema, c as getWorld, _ as getExternalRevivers, $ as hydrateWorkflowReturnValue, a0 as WorkflowRunCancelledError, y as WorkflowRunFailedError, x as WorkflowRunNotCompletedError, a1 as QueueName, o as WorkflowOperation, a2 as WorkflowTracePropagated, a3 as WorkflowStartedAt, a4 as buildWorkflowSuspensionMessage, a5 as dehydrateStepArguments, k as functionsExports, s as serializeTraceCarrier, a6 as WorkflowAPIError, a7 as WorkflowStepsCreated, a8 as WorkflowErrorMessage, a9 as WorkflowErrorName, aa as StepAttempt, ab as StepName, ac as getStepFunction, ad as StepTracePropagated, ae as StepMaxRetries, af as StepId, ag as runtimeLogger, ah as StepStatus, ai as StepRetryTimeoutSeconds, aj as StepSkipReason, ak as StepSkipped, h as hydrateStepArguments, al as StepArgumentsCount, j as dehydrateStepReturnValue, am as StepResultType, an as StepErrorMessage, ao as StepErrorName, ap as StepFatalError, aq as StepRetryExhausted, ar as RetryableError, as as StepRetryWillRetry } from './index_ePTMDSOu.mjs'; +import { decode } from '@jridgewell/sourcemap-codec'; +import { AsyncLocalStorage } from 'node:async_hooks'; +import { types } from 'node:util'; +import { createContext as createContext$1, runInContext } from 'node:vm'; +import * as nanoid from 'nanoid'; + +/** + * An error that is thrown when one or more operations (steps/hooks/etc.) are called but do + * not yet have corresponding entries in the event log. The workflow + * dispatcher will catch this error and push the operations + * onto the queue. + */ +class WorkflowSuspension extends Error { + steps; + globalThis; + stepCount; + hookCount; + waitCount; + constructor(steps, global) { + const stepCount = steps.filter((s) => s.type === 'step').length; + const hookCount = steps.filter((s) => s.type === 'hook').length; + const waitCount = steps.filter((s) => s.type === 'wait').length; + // Build description parts + const parts = []; + if (stepCount > 0) { + parts.push(`${stepCount} ${stepCount === 1 ? 'step' : 'steps'}`); + } + if (hookCount > 0) { + parts.push(`${hookCount} ${hookCount === 1 ? 'hook' : 'hooks'}`); + } + if (waitCount > 0) { + parts.push(`${waitCount} ${waitCount === 1 ? 'wait' : 'waits'}`); + } + // Determine verb (has/have) and action (run/created/received) + const totalCount = stepCount + hookCount + waitCount; + const hasOrHave = totalCount === 1 ? 'has' : 'have'; + let action; + if (stepCount > 0) { + action = 'run'; + } + else if (hookCount > 0) { + action = 'created'; + } + else if (waitCount > 0) { + action = 'created'; + } + else { + action = 'received'; + } + const description = parts.length > 0 + ? `${parts.join(' and ')} ${hasOrHave} not been ${action} yet` + : '0 steps have not been run yet'; // Default case for empty array + super(description); + this.name = 'WorkflowSuspension'; + this.steps = steps; + this.globalThis = global; + this.stepCount = stepCount; + this.hookCount = hookCount; + this.waitCount = waitCount; + } + static is(value) { + return value instanceof WorkflowSuspension; + } +} +function ENOTSUP() { + throw new Error('Not supported in workflow functions'); +} + +/** + * Parse a machine readable name. + * + * @see {@link ../../swc-plugin-workflow/transform/src/naming.rs} for the naming scheme. + */ +function parseName(tag, name) { + if (typeof name !== 'string') { + return null; + } + const [prefix, path, ...functionNameParts] = name.split('//'); + if (prefix !== tag || !path || functionNameParts.length === 0) { + return null; + } + return { + shortName: functionNameParts.at(-1) ?? '', + path, + functionName: functionNameParts.join('//'), + }; +} +/** + * Parse a workflow name into its components. + * + * @param name - The workflow name to parse. + * @returns An object with `shortName`, `path`, and `functionName` properties. + * When the name is invalid, returns `null`. + */ +function parseWorkflowName(name) { + return parseName('workflow', name); +} + +// Matches the scheme of a URL, eg "http://" +const schemeRegex = /^[\w+.-]+:\/\//; +/** + * Matches the parts of a URL: + * 1. Scheme, including ":", guaranteed. + * 2. User/password, including "@", optional. + * 3. Host, guaranteed. + * 4. Port, including ":", optional. + * 5. Path, including "/", optional. + * 6. Query, including "?", optional. + * 7. Hash, including "#", optional. + */ +const urlRegex = /^([\w+.-]+:)\/\/([^@/#?]*@)?([^:/#?]*)(:\d+)?(\/[^#?]*)?(\?[^#]*)?(#.*)?/; +/** + * File URLs are weird. They dont' need the regular `//` in the scheme, they may or may not start + * with a leading `/`, they can have a domain (but only if they don't start with a Windows drive). + * + * 1. Host, optional. + * 2. Path, which may include "/", guaranteed. + * 3. Query, including "?", optional. + * 4. Hash, including "#", optional. + */ +const fileRegex = /^file:(?:\/\/((?![a-z]:)[^/#?]*)?)?(\/?[^#?]*)(\?[^#]*)?(#.*)?/i; +function isAbsoluteUrl(input) { + return schemeRegex.test(input); +} +function isSchemeRelativeUrl(input) { + return input.startsWith('//'); +} +function isAbsolutePath(input) { + return input.startsWith('/'); +} +function isFileUrl(input) { + return input.startsWith('file:'); +} +function isRelative(input) { + return /^[.?#]/.test(input); +} +function parseAbsoluteUrl(input) { + const match = urlRegex.exec(input); + return makeUrl(match[1], match[2] || '', match[3], match[4] || '', match[5] || '/', match[6] || '', match[7] || ''); +} +function parseFileUrl(input) { + const match = fileRegex.exec(input); + const path = match[2]; + return makeUrl('file:', '', match[1] || '', '', isAbsolutePath(path) ? path : '/' + path, match[3] || '', match[4] || ''); +} +function makeUrl(scheme, user, host, port, path, query, hash) { + return { + scheme, + user, + host, + port, + path, + query, + hash, + type: 7 /* Absolute */, + }; +} +function parseUrl(input) { + if (isSchemeRelativeUrl(input)) { + const url = parseAbsoluteUrl('http:' + input); + url.scheme = ''; + url.type = 6 /* SchemeRelative */; + return url; + } + if (isAbsolutePath(input)) { + const url = parseAbsoluteUrl('http://foo.com' + input); + url.scheme = ''; + url.host = ''; + url.type = 5 /* AbsolutePath */; + return url; + } + if (isFileUrl(input)) + return parseFileUrl(input); + if (isAbsoluteUrl(input)) + return parseAbsoluteUrl(input); + const url = parseAbsoluteUrl('http://foo.com/' + input); + url.scheme = ''; + url.host = ''; + url.type = input + ? input.startsWith('?') + ? 3 /* Query */ + : input.startsWith('#') + ? 2 /* Hash */ + : 4 /* RelativePath */ + : 1 /* Empty */; + return url; +} +function stripPathFilename(path) { + // If a path ends with a parent directory "..", then it's a relative path with excess parent + // paths. It's not a file, so we can't strip it. + if (path.endsWith('/..')) + return path; + const index = path.lastIndexOf('/'); + return path.slice(0, index + 1); +} +function mergePaths(url, base) { + normalizePath(base, base.type); + // If the path is just a "/", then it was an empty path to begin with (remember, we're a relative + // path). + if (url.path === '/') { + url.path = base.path; + } + else { + // Resolution happens relative to the base path's directory, not the file. + url.path = stripPathFilename(base.path) + url.path; + } +} +/** + * The path can have empty directories "//", unneeded parents "foo/..", or current directory + * "foo/.". We need to normalize to a standard representation. + */ +function normalizePath(url, type) { + const rel = type <= 4 /* RelativePath */; + const pieces = url.path.split('/'); + // We need to preserve the first piece always, so that we output a leading slash. The item at + // pieces[0] is an empty string. + let pointer = 1; + // Positive is the number of real directories we've output, used for popping a parent directory. + // Eg, "foo/bar/.." will have a positive 2, and we can decrement to be left with just "foo". + let positive = 0; + // We need to keep a trailing slash if we encounter an empty directory (eg, splitting "foo/" will + // generate `["foo", ""]` pieces). And, if we pop a parent directory. But once we encounter a + // real directory, we won't need to append, unless the other conditions happen again. + let addTrailingSlash = false; + for (let i = 1; i < pieces.length; i++) { + const piece = pieces[i]; + // An empty directory, could be a trailing slash, or just a double "//" in the path. + if (!piece) { + addTrailingSlash = true; + continue; + } + // If we encounter a real directory, then we don't need to append anymore. + addTrailingSlash = false; + // A current directory, which we can always drop. + if (piece === '.') + continue; + // A parent directory, we need to see if there are any real directories we can pop. Else, we + // have an excess of parents, and we'll need to keep the "..". + if (piece === '..') { + if (positive) { + addTrailingSlash = true; + positive--; + pointer--; + } + else if (rel) { + // If we're in a relativePath, then we need to keep the excess parents. Else, in an absolute + // URL, protocol relative URL, or an absolute path, we don't need to keep excess. + pieces[pointer++] = piece; + } + continue; + } + // We've encountered a real directory. Move it to the next insertion pointer, which accounts for + // any popped or dropped directories. + pieces[pointer++] = piece; + positive++; + } + let path = ''; + for (let i = 1; i < pointer; i++) { + path += '/' + pieces[i]; + } + if (!path || (addTrailingSlash && !path.endsWith('/..'))) { + path += '/'; + } + url.path = path; +} +/** + * Attempts to resolve `input` URL/path relative to `base`. + */ +function resolve(input, base) { + if (!input && !base) + return ''; + const url = parseUrl(input); + let inputType = url.type; + if (base && inputType !== 7 /* Absolute */) { + const baseUrl = parseUrl(base); + const baseType = baseUrl.type; + switch (inputType) { + case 1 /* Empty */: + url.hash = baseUrl.hash; + // fall through + case 2 /* Hash */: + url.query = baseUrl.query; + // fall through + case 3 /* Query */: + case 4 /* RelativePath */: + mergePaths(url, baseUrl); + // fall through + case 5 /* AbsolutePath */: + // The host, user, and port are joined, you can't copy one without the others. + url.user = baseUrl.user; + url.host = baseUrl.host; + url.port = baseUrl.port; + // fall through + case 6 /* SchemeRelative */: + // The input doesn't have a schema at least, so we need to copy at least that over. + url.scheme = baseUrl.scheme; + } + if (baseType > inputType) + inputType = baseType; + } + normalizePath(url, inputType); + const queryHash = url.query + url.hash; + switch (inputType) { + // This is impossible, because of the empty checks at the start of the function. + // case UrlType.Empty: + case 2 /* Hash */: + case 3 /* Query */: + return queryHash; + case 4 /* RelativePath */: { + // The first char is always a "/", and we need it to be relative. + const path = url.path.slice(1); + if (!path) + return queryHash || '.'; + if (isRelative(base || input) && !isRelative(path)) { + // If base started with a leading ".", or there is no base and input started with a ".", + // then we need to ensure that the relative path starts with a ".". We don't know if + // relative starts with a "..", though, so check before prepending. + return './' + path + queryHash; + } + return path + queryHash; + } + case 5 /* AbsolutePath */: + return url.path + queryHash; + default: + return url.scheme + '//' + url.user + url.host + url.port + url.path + queryHash; + } +} + +// src/trace-mapping.ts + +// src/strip-filename.ts +function stripFilename(path) { + if (!path) return ""; + const index = path.lastIndexOf("/"); + return path.slice(0, index + 1); +} + +// src/resolve.ts +function resolver(mapUrl, sourceRoot) { + const from = stripFilename(mapUrl); + const prefix = sourceRoot ? sourceRoot + "/" : ""; + return (source) => resolve(prefix + (source || ""), from); +} + +// src/sourcemap-segment.ts +var COLUMN = 0; +var SOURCES_INDEX = 1; +var SOURCE_LINE = 2; +var SOURCE_COLUMN = 3; +var NAMES_INDEX = 4; + +// src/sort.ts +function maybeSort(mappings, owned) { + const unsortedIndex = nextUnsortedSegmentLine(mappings, 0); + if (unsortedIndex === mappings.length) return mappings; + if (!owned) mappings = mappings.slice(); + for (let i = unsortedIndex; i < mappings.length; i = nextUnsortedSegmentLine(mappings, i + 1)) { + mappings[i] = sortSegments(mappings[i], owned); + } + return mappings; +} +function nextUnsortedSegmentLine(mappings, start) { + for (let i = start; i < mappings.length; i++) { + if (!isSorted(mappings[i])) return i; + } + return mappings.length; +} +function isSorted(line) { + for (let j = 1; j < line.length; j++) { + if (line[j][COLUMN] < line[j - 1][COLUMN]) { + return false; + } + } + return true; +} +function sortSegments(line, owned) { + if (!owned) line = line.slice(); + return line.sort(sortComparator); +} +function sortComparator(a, b) { + return a[COLUMN] - b[COLUMN]; +} + +// src/binary-search.ts +var found = false; +function binarySearch(haystack, needle, low, high) { + while (low <= high) { + const mid = low + (high - low >> 1); + const cmp = haystack[mid][COLUMN] - needle; + if (cmp === 0) { + found = true; + return mid; + } + if (cmp < 0) { + low = mid + 1; + } else { + high = mid - 1; + } + } + found = false; + return low - 1; +} +function upperBound(haystack, needle, index) { + for (let i = index + 1; i < haystack.length; index = i++) { + if (haystack[i][COLUMN] !== needle) break; + } + return index; +} +function lowerBound(haystack, needle, index) { + for (let i = index - 1; i >= 0; index = i--) { + if (haystack[i][COLUMN] !== needle) break; + } + return index; +} +function memoizedState() { + return { + lastKey: -1, + lastNeedle: -1, + lastIndex: -1 + }; +} +function memoizedBinarySearch(haystack, needle, state, key) { + const { lastKey, lastNeedle, lastIndex } = state; + let low = 0; + let high = haystack.length - 1; + if (key === lastKey) { + if (needle === lastNeedle) { + found = lastIndex !== -1 && haystack[lastIndex][COLUMN] === needle; + return lastIndex; + } + if (needle >= lastNeedle) { + low = lastIndex === -1 ? 0 : lastIndex; + } else { + high = lastIndex; + } + } + state.lastKey = key; + state.lastNeedle = needle; + return state.lastIndex = binarySearch(haystack, needle, low, high); +} + +// src/types.ts +function parse(map) { + return typeof map === "string" ? JSON.parse(map) : map; +} + +// src/trace-mapping.ts +var LINE_GTR_ZERO = "`line` must be greater than 0 (lines start at line 1)"; +var COL_GTR_EQ_ZERO = "`column` must be greater than or equal to 0 (columns start at column 0)"; +var LEAST_UPPER_BOUND = -1; +var GREATEST_LOWER_BOUND = 1; +var TraceMap = class { + constructor(map, mapUrl) { + const isString = typeof map === "string"; + if (!isString && map._decodedMemo) return map; + const parsed = parse(map); + const { version, file, names, sourceRoot, sources, sourcesContent } = parsed; + this.version = version; + this.file = file; + this.names = names || []; + this.sourceRoot = sourceRoot; + this.sources = sources; + this.sourcesContent = sourcesContent; + this.ignoreList = parsed.ignoreList || parsed.x_google_ignoreList || void 0; + const resolve = resolver(mapUrl, sourceRoot); + this.resolvedSources = sources.map(resolve); + const { mappings } = parsed; + if (typeof mappings === "string") { + this._encoded = mappings; + this._decoded = void 0; + } else if (Array.isArray(mappings)) { + this._encoded = void 0; + this._decoded = maybeSort(mappings, isString); + } else if (parsed.sections) { + throw new Error(`TraceMap passed sectioned source map, please use FlattenMap export instead`); + } else { + throw new Error(`invalid source map: ${JSON.stringify(parsed)}`); + } + this._decodedMemo = memoizedState(); + this._bySources = void 0; + this._bySourceMemos = void 0; + } +}; +function cast(map) { + return map; +} +function decodedMappings(map) { + var _a; + return (_a = cast(map))._decoded || (_a._decoded = decode(cast(map)._encoded)); +} +function originalPositionFor(map, needle) { + let { line, column, bias } = needle; + line--; + if (line < 0) throw new Error(LINE_GTR_ZERO); + if (column < 0) throw new Error(COL_GTR_EQ_ZERO); + const decoded = decodedMappings(map); + if (line >= decoded.length) return OMapping(null, null, null, null); + const segments = decoded[line]; + const index = traceSegmentInternal( + segments, + cast(map)._decodedMemo, + line, + column, + bias || GREATEST_LOWER_BOUND + ); + if (index === -1) return OMapping(null, null, null, null); + const segment = segments[index]; + if (segment.length === 1) return OMapping(null, null, null, null); + const { names, resolvedSources } = map; + return OMapping( + resolvedSources[segment[SOURCES_INDEX]], + segment[SOURCE_LINE] + 1, + segment[SOURCE_COLUMN], + segment.length === 5 ? names[segment[NAMES_INDEX]] : null + ); +} +function OMapping(source, line, column, name) { + return { source, line, column, name }; +} +function traceSegmentInternal(segments, memo, line, column, bias) { + let index = memoizedBinarySearch(segments, column, memo, line); + if (found) { + index = (bias === LEAST_UPPER_BOUND ? upperBound : lowerBound)(segments, column, index); + } else if (bias === LEAST_UPPER_BOUND) index++; + if (index === -1 || index === segments.length) return -1; + return index; +} + +/** + * Remaps an error stack trace using inline source maps to show original source locations. + * + * @param stack - The error stack trace to remap + * @param filename - The workflow filename to match in stack frames + * @param workflowCode - The workflow bundle code containing inline source maps + * @returns The remapped stack trace with original source locations + */ +function remapErrorStack(stack, filename, workflowCode) { + // Extract inline source map from workflow code + const sourceMapMatch = workflowCode.match(/\/\/# sourceMappingURL=data:application\/json;base64,(.+)/); + if (!sourceMapMatch) { + return stack; // No source map found + } + try { + const base64 = sourceMapMatch[1]; + const sourceMapJson = Buffer.from(base64, 'base64').toString('utf-8'); + const sourceMapData = JSON.parse(sourceMapJson); + // Use TraceMap (pure JS, no WASM required) + const tracer = new TraceMap(sourceMapData); + // Parse and remap each line in the stack trace + const lines = stack.split('\n'); + const remappedLines = lines.map((line) => { + // Match stack frames: "at functionName (filename:line:column)" or "at filename:line:column" + const frameMatch = line.match(/^\s*at\s+(?:(.+?)\s+\()?(.+?):(\d+):(\d+)\)?$/); + if (!frameMatch) { + return line; // Not a stack frame, return as-is + } + const [, functionName, file, lineStr, colStr] = frameMatch; + // Only remap frames from our workflow file + if (!file.includes(filename)) { + return line; + } + const lineNumber = parseInt(lineStr, 10); + const columnNumber = parseInt(colStr, 10); + // Map to original source position + const original = originalPositionFor(tracer, { + line: lineNumber, + column: columnNumber, + }); + if (original.source && original.line !== null) { + const func = functionName || original.name || 'anonymous'; + const col = original.column !== null ? original.column : columnNumber; + return ` at ${func} (${original.source}:${original.line}:${col})`; + } + return line; // Couldn't map, return original + }); + return remappedLines.join('\n'); + } + catch (e) { + // If source map processing fails, return original stack + return stack; + } +} + +const contextStorage = /* @__PURE__ */ new AsyncLocalStorage(); + +function getErrorName(v) { + if (types.isNativeError(v)) { + return v.name; + } + return 'Error'; +} +function getErrorStack(v) { + if (types.isNativeError(v)) { + return v.stack ?? ''; + } + return ''; +} + +function createUseStep(ctx) { + return function useStep(stepName) { + return (...args) => { + const { promise, resolve, reject } = withResolvers(); + const correlationId = `step_${ctx.generateUlid()}`; + ctx.invocationsQueue.push({ + type: 'step', + correlationId, + stepName, + args, + }); + // Track whether we've already seen a "step_started" event for this step. + // This is important because after a retryable failure, the step moves back to + // "pending" status which causes another "step_started" event to be emitted. + let hasSeenStepStarted = false; + stepLogger.debug('Step consumer setup', { + correlationId, + stepName, + args, + }); + ctx.eventsConsumer.subscribe((event) => { + if (!event) { + // We've reached the end of the events, so this step has either not been run or is currently running. + // Crucially, if we got here, then this step Promise does + // not resolve so that the user workflow code does not proceed any further. + // Notify the workflow handler that this step has not been run / has not completed yet. + setTimeout(() => { + ctx.onWorkflowError(new WorkflowSuspension(ctx.invocationsQueue, ctx.globalThis)); + }, 0); + return EventConsumerResult.NotConsumed; + } + stepLogger.debug('Step consumer event processing', { + correlationId, + stepName, + args: args.join(', '), + incomingCorrelationId: event.correlationId, + isMatch: correlationId === event.correlationId, + eventType: event.eventType, + }); + if (event.correlationId !== correlationId) { + // We're not interested in this event - the correlationId belongs to a different step + return EventConsumerResult.NotConsumed; + } + if (event.eventType === 'step_started') { + // Step has started - so remove from the invocations queue (only on the first "step_started" event) + if (!hasSeenStepStarted) { + const invocationsQueueIndex = ctx.invocationsQueue.findIndex((invocation) => invocation.type === 'step' && + invocation.correlationId === correlationId); + if (invocationsQueueIndex !== -1) { + ctx.invocationsQueue.splice(invocationsQueueIndex, 1); + } + else { + setTimeout(() => { + reject(new WorkflowRuntimeError(`Corrupted event log: step ${correlationId} (${stepName}) started but not found in invocation queue`)); + }, 0); + return EventConsumerResult.Finished; + } + hasSeenStepStarted = true; + } + // If this is a subsequent "step_started" event (after a retry), we just consume it + // without trying to remove from the queue again or logging a warning + return EventConsumerResult.Consumed; + } + if (event.eventType === 'step_failed') { + // Step failed - bubble up to workflow + if (event.eventData.fatal) { + setTimeout(() => { + reject(new FatalError(event.eventData.error)); + }, 0); + return EventConsumerResult.Finished; + } + else { + // This is a retryable error, so nothing to do here, + // but we will consume the event + return EventConsumerResult.Consumed; + } + } + else if (event.eventType === 'step_completed') { + // Step has already completed, so resolve the Promise with the cached result + const hydratedResult = hydrateStepReturnValue(event.eventData.result, ctx.globalThis); + setTimeout(() => { + resolve(hydratedResult); + }, 0); + return EventConsumerResult.Finished; + } + else { + // An unexpected event type has been received, but it does belong to this step (matching `correlationId`) + setTimeout(() => { + reject(new WorkflowRuntimeError(`Unexpected event type: "${event.eventType}"`)); + }, 0); + return EventConsumerResult.Finished; + } + }); + return promise; + }; + }; +} + +/** + * Returns a function that generates a random UUID, based on the given RNG. + * + * `rng` is expected to be a seeded random number generator (i.e. `seedrandom.PRNG` instance). + * + * @param rng - A function that returns a random number between 0 and 1. + * @returns A `crypto.randomUUID`-like function. + */ +function createRandomUUID(rng) { + return function randomUUID() { + const chars = '0123456789abcdef'; + let uuid = ''; + for (let i = 0; i < 36; i++) { + if (i === 8 || i === 13 || i === 18 || i === 23) { + uuid += '-'; + } + else if (i === 14) { + uuid += '4'; // Version 4 UUID + } + else if (i === 19) { + uuid += chars[Math.floor(rng() * 4) + 8]; // 8, 9, a, or b + } + else { + uuid += chars[Math.floor(rng() * 16)]; + } + } + return uuid; + }; +} + +/** + * Creates a Node.js `vm.Context` configured to be usable for + * executing workflow logic in a deterministic environment. + * + * @param options - The options for the context. + * @returns The context. + */ +function createContext(options) { + let { fixedTimestamp } = options; + const { seed } = options; + const rng = seedrandom(seed); + const context = createContext$1(); + const g = runInContext('globalThis', context); + // Deterministic `Math.random()` + g.Math.random = rng; + // Override `Date` constructor to return fixed time when called without arguments + const Date_ = g.Date; + // biome-ignore lint/suspicious/noShadowRestrictedNames: We're shadowing the global `Date` property to make it deterministic. + g.Date = function Date(...args) { + if (args.length === 0) { + return new Date_(fixedTimestamp); + } + // @ts-expect-error - Args is `Date` constructor arguments + return new Date_(...args); + }; + g.Date.prototype = Date_.prototype; + // Preserve static methods + Object.setPrototypeOf(g.Date, Date_); + g.Date.now = () => fixedTimestamp; + // Deterministic `crypto` using Proxy to avoid mutating global objects + const originalCrypto = globalThis.crypto; + const originalSubtle = originalCrypto.subtle; + function getRandomValues(array) { + for (let i = 0; i < array.length; i++) { + array[i] = Math.floor(rng() * 256); + } + return array; + } + const randomUUID = createRandomUUID(rng); + const boundDigest = originalSubtle.digest.bind(originalSubtle); + g.crypto = new Proxy(originalCrypto, { + get(target, prop) { + if (prop === 'getRandomValues') { + return getRandomValues; + } + if (prop === 'randomUUID') { + return randomUUID; + } + if (prop === 'subtle') { + return new Proxy(originalSubtle, { + get(target, prop) { + if (prop === 'generateKey') { + return () => { + throw new Error('Not implemented'); + }; + } + else if (prop === 'digest') { + return boundDigest; + } + return target[prop]; + }, + }); + } + return target[prop]; + }, + }); + // Propagate environment variables + g.process = { + env: Object.freeze({ ...process.env }), + }; + // Stateless + synchronous Web APIs that are made available inside the sandbox + g.Headers = globalThis.Headers; + g.TextEncoder = globalThis.TextEncoder; + g.TextDecoder = globalThis.TextDecoder; + g.console = globalThis.console; + g.URL = globalThis.URL; + g.URLSearchParams = globalThis.URLSearchParams; + g.structuredClone = globalThis.structuredClone; + // HACK: Shim `exports` for the bundle + g.exports = {}; + g.module = { exports: g.exports }; + return { + context, + globalThis: g, + updateTimestamp: (timestamp) => { + fixedTimestamp = timestamp; + }, + }; +} + +const WORKFLOW_CONTEXT_SYMBOL = +/* @__PURE__ */ Symbol.for('WORKFLOW_CONTEXT'); + +function createCreateHook(ctx) { + return function createHookImpl(options = {}) { + // Generate hook ID and token + const correlationId = `hook_${ctx.generateUlid()}`; + const token = options.token ?? ctx.generateNanoid(); + // Add hook creation to invocations queue + ctx.invocationsQueue.push({ + type: 'hook', + correlationId, + token, + metadata: options.metadata, + }); + // Queue of hook events that have been received but not yet processed + const payloadsQueue = []; + // Queue of promises that resolve to the next hook payload + const promises = []; + let eventLogEmpty = false; + webhookLogger.debug('Hook consumer setup', { correlationId, token }); + ctx.eventsConsumer.subscribe((event) => { + // If there are no events and there are promises waiting, + // it means the hook has been awaited, but an incoming payload has not yet been received. + // In this case, the workflow should be suspended until the hook is resumed. + if (!event) { + eventLogEmpty = true; + if (promises.length > 0) { + setTimeout(() => { + ctx.onWorkflowError(new WorkflowSuspension(ctx.invocationsQueue, ctx.globalThis)); + }, 0); + return EventConsumerResult.Finished; + } + } + // Check for hook_created event to remove this hook from the queue if it was already created + if (event?.eventType === 'hook_created' && + event.correlationId === correlationId) { + // Remove this hook from the invocations queue if it exists + const index = ctx.invocationsQueue.findIndex((item) => item.type === 'hook' && item.correlationId === correlationId); + if (index !== -1) { + ctx.invocationsQueue.splice(index, 1); + } + return EventConsumerResult.Consumed; + } + if (event?.eventType === 'hook_received' && + event.correlationId === correlationId) { + if (promises.length > 0) { + const next = promises.shift(); + if (next) { + // Reconstruct the payload from the event data + const payload = hydrateStepReturnValue(event.eventData.payload, ctx.globalThis); + next.resolve(payload); + } + } + else { + payloadsQueue.push(event); + } + return EventConsumerResult.Consumed; + } + return EventConsumerResult.NotConsumed; + }); + // Helper function to create a new promise that waits for the next hook payload + function createHookPromise() { + const resolvers = withResolvers(); + if (payloadsQueue.length > 0) { + const nextPayload = payloadsQueue.shift(); + if (nextPayload) { + const payload = hydrateStepReturnValue(nextPayload.eventData.payload, ctx.globalThis); + resolvers.resolve(payload); + return resolvers.promise; + } + } + if (eventLogEmpty) { + // If the event log is already empty then we know the hook will not be resolved. + // Treat this case as a "step not run" scenario and suspend the workflow. + setTimeout(() => { + ctx.onWorkflowError(new WorkflowSuspension(ctx.invocationsQueue, ctx.globalThis)); + }, 0); + } + promises.push(resolvers); + return resolvers.promise; + } + const hook = { + token, + // biome-ignore lint/suspicious/noThenProperty: Intentionally thenable + then(onfulfilled, onrejected) { + return createHookPromise().then(onfulfilled, onrejected); + }, + // Support `for await (const payload of hook) { … }` syntax + async *[Symbol.asyncIterator]() { + while (true) { + yield await this; + } + }, + }; + return hook; + }; +} + +function createSleep(ctx) { + return async function sleepImpl(param) { + const { promise, resolve } = withResolvers(); + const correlationId = `wait_${ctx.generateUlid()}`; + // Calculate the resume time + const resumeAt = parseDurationToDate(param); + // Add wait to invocations queue + ctx.invocationsQueue.push({ + type: 'wait', + correlationId, + resumeAt, + }); + ctx.eventsConsumer.subscribe((event) => { + // If there are no events and we're waiting for wait_completed, + // suspend the workflow until the wait fires + if (!event) { + setTimeout(() => { + ctx.onWorkflowError(new WorkflowSuspension(ctx.invocationsQueue, ctx.globalThis)); + }, 0); + return EventConsumerResult.NotConsumed; + } + // Check for wait_created event to mark this wait as having the event created + if (event?.eventType === 'wait_created' && + event.correlationId === correlationId) { + // Mark this wait as having the created event, but keep it in the queue + const waitItem = ctx.invocationsQueue.find((item) => item.type === 'wait' && item.correlationId === correlationId); + if (waitItem) { + waitItem.hasCreatedEvent = true; + waitItem.resumeAt = event.eventData.resumeAt; + } + return EventConsumerResult.Consumed; + } + // Check for wait_completed event + if (event?.eventType === 'wait_completed' && + event.correlationId === correlationId) { + // Remove this wait from the invocations queue + const index = ctx.invocationsQueue.findIndex((item) => item.type === 'wait' && item.correlationId === correlationId); + if (index !== -1) { + ctx.invocationsQueue.splice(index, 1); + } + // Wait has elapsed, resolve the sleep + setTimeout(() => { + resolve(); + }, 0); + return EventConsumerResult.Finished; + } + return EventConsumerResult.NotConsumed; + }); + return promise; + }; +} + +async function runWorkflow(workflowCode, workflowRun, events) { + return trace(`WORKFLOW.run ${workflowRun.workflowName}`, async (span) => { + span?.setAttributes({ + ...WorkflowName(workflowRun.workflowName), + ...WorkflowRunId(workflowRun.runId), + ...WorkflowRunStatus(workflowRun.status), + ...WorkflowEventsCount(events.length), + }); + const startedAt = workflowRun.startedAt; + if (!startedAt) { + throw new Error(`Workflow run "${workflowRun.runId}" has no "startedAt" timestamp (should not happen)`); + } + // Get the port before creating VM context to avoid async operations + // affecting the deterministic timestamp + const port = await getPort(); + const { context, globalThis: vmGlobalThis, updateTimestamp, } = createContext({ + seed: workflowRun.runId, + fixedTimestamp: +startedAt, + }); + const workflowDiscontinuation = withResolvers(); + const ulid = monotonicFactory(() => vmGlobalThis.Math.random()); + const generateNanoid = nanoid.customRandom(nanoid.urlAlphabet, 21, (size) => new Uint8Array(size).map(() => 256 * vmGlobalThis.Math.random())); + const workflowContext = { + globalThis: vmGlobalThis, + onWorkflowError: workflowDiscontinuation.reject, + eventsConsumer: new EventsConsumer(events), + generateUlid: () => ulid(+startedAt), + generateNanoid, + invocationsQueue: [], + }; + // Subscribe to the events log to update the timestamp in the vm context + workflowContext.eventsConsumer.subscribe((event) => { + const createdAt = event?.createdAt; + if (createdAt) { + updateTimestamp(+createdAt); + } + // Never consume events - this is only a passive subscriber + return EventConsumerResult.NotConsumed; + }); + const useStep = createUseStep(workflowContext); + const createHook = createCreateHook(workflowContext); + const sleep = createSleep(workflowContext); + // @ts-expect-error - `@types/node` says symbol is not valid, but it does work + vmGlobalThis[WORKFLOW_USE_STEP] = useStep; + // @ts-expect-error - `@types/node` says symbol is not valid, but it does work + vmGlobalThis[WORKFLOW_CREATE_HOOK] = createHook; + // @ts-expect-error - `@types/node` says symbol is not valid, but it does work + vmGlobalThis[WORKFLOW_SLEEP] = sleep; + // @ts-expect-error - `@types/node` says symbol is not valid, but it does work + vmGlobalThis[WORKFLOW_GET_STREAM_ID] = (namespace) => getWorkflowRunStreamId(workflowRun.runId, namespace); + // TODO: there should be a getUrl method on the world interface itself. This + // solution only works for vercel + embedded worlds. + const url = process.env.VERCEL_URL + ? `https://${process.env.VERCEL_URL}` + : `http://localhost:${port ?? 3000}`; + // For the workflow VM, we store the context in a symbol on the `globalThis` object + const ctx = { + workflowRunId: workflowRun.runId, + workflowStartedAt: new vmGlobalThis.Date(+startedAt), + url, + }; + // @ts-expect-error - `@types/node` says symbol is not valid, but it does work + vmGlobalThis[WORKFLOW_CONTEXT_SYMBOL] = ctx; + // NOTE: Will have a config override to use the custom fetch step. + // For now `fetch` must be explicitly imported from `workflow`. + vmGlobalThis.fetch = () => { + throw new vmGlobalThis.Error(`Global "fetch" is unavailable in workflow functions. Use the "fetch" step function from "workflow" to make HTTP requests.\n\nLearn more: https://useworkflow.dev/err/${ERROR_SLUGS.FETCH_IN_WORKFLOW_FUNCTION}`); + }; + // `Request` and `Response` are special built-in classes that invoke steps + // for the `json()`, `text()` and `arrayBuffer()` instance methods + class Request { + cache; + credentials; + destination; + headers; + integrity; + method; + mode; + redirect; + referrer; + referrerPolicy; + url; + keepalive; + signal; + duplex; + body; + constructor(input, init) { + // Handle URL input + if (typeof input === 'string' || input instanceof vmGlobalThis.URL) { + const urlString = String(input); + // Validate URL format + try { + new vmGlobalThis.URL(urlString); + this.url = urlString; + } + catch (cause) { + throw new TypeError(`Failed to parse URL from ${urlString}`, { + cause, + }); + } + } + else { + // Input is a Request object - clone its properties + this.url = input.url; + if (!init) { + this.method = input.method; + this.headers = new vmGlobalThis.Headers(input.headers); + this.body = input.body; + this.mode = input.mode; + this.credentials = input.credentials; + this.cache = input.cache; + this.redirect = input.redirect; + this.referrer = input.referrer; + this.referrerPolicy = input.referrerPolicy; + this.integrity = input.integrity; + this.keepalive = input.keepalive; + this.signal = input.signal; + this.duplex = input.duplex; + this.destination = input.destination; + return; + } + // If init is provided, merge: use source properties, then override with init + // Copy all properties from the source Request first + this.method = input.method; + this.headers = new vmGlobalThis.Headers(input.headers); + this.body = input.body; + this.mode = input.mode; + this.credentials = input.credentials; + this.cache = input.cache; + this.redirect = input.redirect; + this.referrer = input.referrer; + this.referrerPolicy = input.referrerPolicy; + this.integrity = input.integrity; + this.keepalive = input.keepalive; + this.signal = input.signal; + this.duplex = input.duplex; + this.destination = input.destination; + } + // Override with init options if provided + // Set method + if (init?.method) { + this.method = init.method.toUpperCase(); + } + else if (typeof this.method !== 'string') { + // Fallback to default for string input case + this.method = 'GET'; + } + // Set headers + if (init?.headers) { + this.headers = new vmGlobalThis.Headers(init.headers); + } + else if (typeof input === 'string' || + input instanceof vmGlobalThis.URL) { + // For string/URL input, create empty headers + this.headers = new vmGlobalThis.Headers(); + } + // Set other properties with init values or defaults + if (init?.mode !== undefined) { + this.mode = init.mode; + } + else if (typeof this.mode !== 'string') { + this.mode = 'cors'; + } + if (init?.credentials !== undefined) { + this.credentials = init.credentials; + } + else if (typeof this.credentials !== 'string') { + this.credentials = 'same-origin'; + } + // `any` cast here because @types/node v22 does not yet have `cache` + if (init?.cache !== undefined) { + this.cache = init.cache; + } + else if (typeof this.cache !== 'string') { + this.cache = 'default'; + } + if (init?.redirect !== undefined) { + this.redirect = init.redirect; + } + else if (typeof this.redirect !== 'string') { + this.redirect = 'follow'; + } + if (init?.referrer !== undefined) { + this.referrer = init.referrer; + } + else if (typeof this.referrer !== 'string') { + this.referrer = 'about:client'; + } + if (init?.referrerPolicy !== undefined) { + this.referrerPolicy = init.referrerPolicy; + } + else if (typeof this.referrerPolicy !== 'string') { + this.referrerPolicy = ''; + } + if (init?.integrity !== undefined) { + this.integrity = init.integrity; + } + else if (typeof this.integrity !== 'string') { + this.integrity = ''; + } + if (init?.keepalive !== undefined) { + this.keepalive = init.keepalive; + } + else if (typeof this.keepalive !== 'boolean') { + this.keepalive = false; + } + if (init?.signal !== undefined) { + // @ts-expect-error - AbortSignal stub + this.signal = init.signal; + } + else if (!this.signal) { + // @ts-expect-error - AbortSignal stub + this.signal = { aborted: false }; + } + if (!this.duplex) { + this.duplex = 'half'; + } + if (!this.destination) { + this.destination = 'document'; + } + const body = init?.body; + // Validate that GET/HEAD methods don't have a body + if (body !== null && + body !== undefined && + (this.method === 'GET' || this.method === 'HEAD')) { + throw new TypeError(`Request with GET/HEAD method cannot have body.`); + } + // Store the original BodyInit for serialization + if (body !== null && body !== undefined) { + // Create a "fake" ReadableStream that stores the original body + // This avoids doing async work during workflow replay + this.body = Object.create(vmGlobalThis.ReadableStream.prototype, { + [BODY_INIT_SYMBOL]: { + value: body, + writable: false, + }, + }); + } + else { + this.body = null; + } + } + clone() { + ENOTSUP(); + } + get bodyUsed() { + return false; + } + // TODO: implement these + blob; + formData; + async arrayBuffer() { + return resArrayBuffer(this); + } + async bytes() { + return new Uint8Array(await resArrayBuffer(this)); + } + async json() { + return resJson(this); + } + async text() { + return resText(this); + } + } + vmGlobalThis.Request = Request; + const resJson = useStep('__builtin_response_json'); + const resText = useStep('__builtin_response_text'); + const resArrayBuffer = useStep('__builtin_response_array_buffer'); + class Response { + type; + url; + status; + statusText; + body; + headers; + redirected; + constructor(body, init) { + this.status = init?.status ?? 200; + this.statusText = init?.statusText ?? ''; + this.headers = new vmGlobalThis.Headers(init?.headers); + this.type = 'default'; + this.url = ''; + this.redirected = false; + // Validate that null-body status codes don't have a body + // Per HTTP spec: 204 (No Content), 205 (Reset Content), and 304 (Not Modified) + if (body !== null && + body !== undefined && + (this.status === 204 || this.status === 205 || this.status === 304)) { + throw new TypeError(`Response constructor: Invalid response status code ${this.status}`); + } + // Store the original BodyInit for serialization + if (body !== null && body !== undefined) { + // Create a "fake" ReadableStream that stores the original body + // This avoids doing async work during workflow replay + this.body = Object.create(vmGlobalThis.ReadableStream.prototype, { + [BODY_INIT_SYMBOL]: { + value: body, + writable: false, + }, + }); + } + else { + this.body = null; + } + } + // TODO: implement these + clone; + blob; + formData; + get ok() { + return this.status >= 200 && this.status < 300; + } + get bodyUsed() { + return false; + } + async arrayBuffer() { + return resArrayBuffer(this); + } + async bytes() { + return new Uint8Array(await resArrayBuffer(this)); + } + async json() { + return resJson(this); + } + static json(data, init) { + const body = JSON.stringify(data); + const headers = new vmGlobalThis.Headers(init?.headers); + if (!headers.has('content-type')) { + headers.set('content-type', 'application/json'); + } + return new Response(body, { ...init, headers }); + } + async text() { + return resText(this); + } + static error() { + ENOTSUP(); + } + static redirect(url, status = 302) { + // Validate status code - only specific redirect codes are allowed + if (![301, 302, 303, 307, 308].includes(status)) { + throw new RangeError(`Invalid redirect status code: ${status}. Must be one of: 301, 302, 303, 307, 308`); + } + // Create response with Location header + const headers = new vmGlobalThis.Headers(); + headers.set('Location', String(url)); + const response = Object.create(Response.prototype); + response.status = status; + response.statusText = ''; + response.headers = headers; + response.body = null; + response.type = 'default'; + response.url = ''; + response.redirected = false; + return response; + } + } + vmGlobalThis.Response = Response; + class ReadableStream { + constructor() { + ENOTSUP(); + } + get locked() { + return false; + } + cancel() { + ENOTSUP(); + } + getReader() { + ENOTSUP(); + } + pipeThrough() { + ENOTSUP(); + } + pipeTo() { + ENOTSUP(); + } + tee() { + ENOTSUP(); + } + values() { + ENOTSUP(); + } + static from() { + ENOTSUP(); + } + [Symbol.asyncIterator]() { + ENOTSUP(); + } + } + vmGlobalThis.ReadableStream = ReadableStream; + class WritableStream { + constructor() { + ENOTSUP(); + } + get locked() { + return false; + } + abort() { + ENOTSUP(); + } + close() { + ENOTSUP(); + } + getWriter() { + ENOTSUP(); + } + } + vmGlobalThis.WritableStream = WritableStream; + class TransformStream { + readable; + writable; + constructor() { + ENOTSUP(); + } + } + vmGlobalThis.TransformStream = TransformStream; + // Eventually we'll probably want to provide our own `console` object, + // but for now we'll just expose the global one. + vmGlobalThis.console = globalThis.console; + // HACK: propagate symbol needed for AI gateway usage + const SYMBOL_FOR_REQ_CONTEXT = Symbol.for('@vercel/request-context'); + // @ts-expect-error - `@types/node` says symbol is not valid, but it does work + vmGlobalThis[SYMBOL_FOR_REQ_CONTEXT] = globalThis[SYMBOL_FOR_REQ_CONTEXT]; + // Get a reference to the user-defined workflow function. + // The filename parameter ensures stack traces show a meaningful name + // (e.g., "example/workflows/99_e2e.ts") instead of "evalmachine.". + const parsedName = parseWorkflowName(workflowRun.workflowName); + const filename = parsedName?.path || workflowRun.workflowName; + const workflowFn = runInContext(`${workflowCode}; globalThis.__private_workflows?.get(${JSON.stringify(workflowRun.workflowName)})`, context, { filename }); + if (typeof workflowFn !== 'function') { + throw new ReferenceError(`Workflow ${JSON.stringify(workflowRun.workflowName)} must be a function, but got "${typeof workflowFn}" instead`); + } + const args = hydrateWorkflowArguments(workflowRun.input, vmGlobalThis); + span?.setAttributes({ + ...WorkflowArgumentsCount(args.length), + }); + // Invoke user workflow + const result = await Promise.race([ + workflowFn(...args), + workflowDiscontinuation.promise, + ]); + const dehydrated = dehydrateWorkflowReturnValue(result, vmGlobalThis); + span?.setAttributes({ + ...WorkflowResultType(typeof result), + }); + return dehydrated; + }); +} + +/** + * A handler class for a workflow run. + */ +class Run { + /** + * The ID of the workflow run. + */ + runId; + /** + * The world object. + * @internal + */ + world; + constructor(runId) { + this.runId = runId; + this.world = getWorld(); + } + /** + * Cancels the workflow run. + */ + async cancel() { + await this.world.runs.cancel(this.runId); + } + /** + * The status of the workflow run. + */ + get status() { + return this.world.runs.get(this.runId).then((run) => run.status); + } + /** + * The return value of the workflow run. + * Polls the workflow return value until it is completed. + */ + get returnValue() { + return this.pollReturnValue(); + } + /** + * The name of the workflow. + */ + get workflowName() { + return this.world.runs.get(this.runId).then((run) => run.workflowName); + } + /** + * The timestamp when the workflow run was created. + */ + get createdAt() { + return this.world.runs.get(this.runId).then((run) => run.createdAt); + } + /** + * The timestamp when the workflow run started execution. + * Returns undefined if the workflow has not started yet. + */ + get startedAt() { + return this.world.runs.get(this.runId).then((run) => run.startedAt); + } + /** + * The timestamp when the workflow run completed. + * Returns undefined if the workflow has not completed yet. + */ + get completedAt() { + return this.world.runs.get(this.runId).then((run) => run.completedAt); + } + /** + * The readable stream of the workflow run. + */ + get readable() { + return this.getReadable(); + } + /** + * Retrieves the workflow run's default readable stream, which reads chunks + * written to the corresponding writable stream {@link getWritable}. + * + * @param options - The options for the readable stream. + * @returns The `ReadableStream` for the workflow run. + */ + getReadable(options = {}) { + const { ops = [], global = globalThis, startIndex, namespace } = options; + const name = getWorkflowRunStreamId(this.runId, namespace); + return getExternalRevivers(global, ops).ReadableStream({ + name, + startIndex, + }); + } + /** + * Polls the workflow return value every 1 second until it is completed. + * @internal + * @returns The workflow return value. + */ + async pollReturnValue() { + while (true) { + try { + const run = await this.world.runs.get(this.runId); + if (run.status === 'completed') { + return hydrateWorkflowReturnValue(run.output, [], globalThis); + } + if (run.status === 'cancelled') { + throw new WorkflowRunCancelledError(this.runId); + } + if (run.status === 'failed') { + throw new WorkflowRunFailedError(this.runId, run.error); + } + throw new WorkflowRunNotCompletedError(this.runId, run.status); + } + catch (error) { + if (WorkflowRunNotCompletedError.is(error)) { + await new Promise((resolve) => setTimeout(resolve, 1_000)); + continue; + } + throw error; + } + } + } +} +/** + * Retrieves a `Run` object for a given run ID. + * + * @param runId - The workflow run ID obtained from {@link start}. + * @returns A `Run` object. + * @throws WorkflowRunNotFoundError if the run ID is not found. + */ +function getRun(runId) { + return new Run(runId); +} +/** + * Loads all workflow run events by iterating through all pages of paginated results. + * This ensures that *all* events are loaded into memory before running the workflow. + * Events must be in chronological order (ascending) for proper workflow replay. + */ +async function getAllWorkflowRunEvents(runId) { + const allEvents = []; + let cursor = null; + let hasMore = true; + const world = getWorld(); + while (hasMore) { + const response = await world.events.list({ + runId, + pagination: { + sortOrder: 'asc', // Required: events must be in chronological order for replay + cursor: cursor ?? undefined, + }, + }); + allEvents.push(...response.data); + hasMore = response.hasMore; + cursor = response.cursor; + } + return allEvents; +} +/** + * Function that creates a single route which handles any workflow execution + * request and routes to the appropriate workflow function. + * + * @param workflowCode - The workflow bundle code containing all the workflow + * functions at the top level. + * @returns A function that can be used as a Vercel API route. + */ +function workflowEntrypoint(workflowCode) { + return getWorldHandlers().createQueueHandler('__wkf_workflow_', async (message_, metadata) => { + const { runId, traceCarrier: traceContext } = WorkflowInvokePayloadSchema.parse(message_); + // Extract the workflow name from the topic name + const workflowName = metadata.queueName.slice('__wkf_workflow_'.length); + // Invoke user workflow within the propagated trace context + return await withTraceContext(traceContext, async () => { + const world = getWorld(); + return trace(`WORKFLOW ${workflowName}`, async (span) => { + span?.setAttributes({ + ...WorkflowName(workflowName), + ...WorkflowOperation('execute'), + ...QueueName(metadata.queueName), + }); + // TODO: validate `workflowName` exists before consuming message? + span?.setAttributes({ + ...WorkflowRunId(runId), + ...WorkflowTracePropagated(!!traceContext), + }); + let workflowStartedAt = -1; + try { + let workflowRun = await world.runs.get(runId); + if (workflowRun.status === 'pending') { + workflowRun = await world.runs.update(runId, { + // This sets the `startedAt` timestamp at the database level + status: 'running', + }); + } + // At this point, the workflow is "running" and `startedAt` should + // definitely be set. + if (!workflowRun.startedAt) { + throw new Error(`Workflow run "${runId}" has no "startedAt" timestamp`); + } + workflowStartedAt = +workflowRun.startedAt; + span?.setAttributes({ + ...WorkflowRunStatus(workflowRun.status), + ...WorkflowStartedAt(workflowStartedAt), + }); + if (workflowRun.status !== 'running') { + // Workflow has already completed or failed, so we can skip it + console.warn(`Workflow "${runId}" has status "${workflowRun.status}", skipping`); + // TODO: for `cancel`, we actually want to propagate a WorkflowCancelled event + // inside the workflow context so the user can gracefully exit. this is SIGTERM + // TODO: furthermore, there should be a timeout or a way to force cancel SIGKILL + // so that we actually exit here without replaying the workflow at all, in the case + // the replaying the workflow is itself failing. + return; + } + // Load all events into memory before running + const events = await getAllWorkflowRunEvents(workflowRun.runId); + // Check for any elapsed waits and create wait_completed events + const now = Date.now(); + for (const event of events) { + if (event.eventType === 'wait_created') { + const resumeAt = event.eventData.resumeAt; + const hasCompleted = events.some((e) => e.eventType === 'wait_completed' && + e.correlationId === event.correlationId); + // If wait has elapsed and hasn't been completed yet + if (!hasCompleted && now >= resumeAt.getTime()) { + const completedEvent = await world.events.create(runId, { + eventType: 'wait_completed', + correlationId: event.correlationId, + }); + // Add the event to the events array so the workflow can see it + events.push(completedEvent); + } + } + } + const result = await runWorkflow(workflowCode, workflowRun, events); + // Update the workflow run with the result + await world.runs.update(runId, { + status: 'completed', + output: result, + }); + span?.setAttributes({ + ...WorkflowRunStatus('completed'), + ...WorkflowEventsCount(events.length), + }); + } + catch (err) { + if (WorkflowSuspension.is(err)) { + buildWorkflowSuspensionMessage(runId, err.stepCount, err.hookCount, err.waitCount); + // Process each operation in the queue (steps and hooks) + let minTimeoutSeconds = null; + for (const queueItem of err.steps) { + if (queueItem.type === 'step') { + // Handle step operations + const ops = []; + const dehydratedArgs = dehydrateStepArguments(queueItem.args, err.globalThis); + try { + const step = await world.steps.create(runId, { + stepId: queueItem.correlationId, + stepName: queueItem.stepName, + input: dehydratedArgs, + }); + functionsExports.waitUntil(Promise.all(ops)); + await world.queue(`__wkf_step_${queueItem.stepName}`, { + workflowName, + workflowRunId: runId, + workflowStartedAt, + stepId: step.stepId, + traceCarrier: await serializeTraceCarrier(), + }, { + idempotencyKey: queueItem.correlationId, + }); + } + catch (err) { + if (WorkflowAPIError.is(err) && err.status === 409) { + // Step already exists, so we can skip it + console.warn(`Step "${queueItem.stepName}" with correlation ID "${queueItem.correlationId}" already exists, skipping: ${err.message}`); + continue; + } + throw err; + } + } + else if (queueItem.type === 'hook') { + // Handle hook operations + try { + // Create hook in database + const hookMetadata = typeof queueItem.metadata === 'undefined' + ? undefined + : dehydrateStepArguments(queueItem.metadata, err.globalThis); + await world.hooks.create(runId, { + hookId: queueItem.correlationId, + token: queueItem.token, + metadata: hookMetadata, + }); + // Create hook_created event in event log + await world.events.create(runId, { + eventType: 'hook_created', + correlationId: queueItem.correlationId, + }); + } + catch (err) { + if (WorkflowAPIError.is(err)) { + if (err.status === 409) { + // Hook already exists (duplicate hook_id constraint), so we can skip it + console.warn(`Hook with correlation ID "${queueItem.correlationId}" already exists, skipping: ${err.message}`); + continue; + } + else if (err.status === 410) { + // Workflow has already completed, so no-op + console.warn(`Workflow run "${runId}" has already completed, skipping hook "${queueItem.correlationId}": ${err.message}`); + continue; + } + } + throw err; + } + } + else if (queueItem.type === 'wait') { + // Handle wait operations + try { + // Only create wait_created event if it hasn't been created yet + if (!queueItem.hasCreatedEvent) { + await world.events.create(runId, { + eventType: 'wait_created', + correlationId: queueItem.correlationId, + eventData: { + resumeAt: queueItem.resumeAt, + }, + }); + } + // Calculate how long to wait before resuming + const now = Date.now(); + const resumeAtMs = queueItem.resumeAt.getTime(); + const delayMs = Math.max(1000, resumeAtMs - now); + const timeoutSeconds = Math.ceil(delayMs / 1000); + // Track the minimum timeout across all waits + if (minTimeoutSeconds === null || + timeoutSeconds < minTimeoutSeconds) { + minTimeoutSeconds = timeoutSeconds; + } + } + catch (err) { + if (WorkflowAPIError.is(err) && err.status === 409) { + // Wait already exists, so we can skip it + console.warn(`Wait with correlation ID "${queueItem.correlationId}" already exists, skipping: ${err.message}`); + continue; + } + throw err; + } + } + } + span?.setAttributes({ + ...WorkflowRunStatus('pending_steps'), + ...WorkflowStepsCreated(err.steps.length), + }); + // If we encountered any waits, return the minimum timeout + if (minTimeoutSeconds !== null) { + return { timeoutSeconds: minTimeoutSeconds }; + } + } + else { + const errorName = getErrorName(err); + const errorMessage = err instanceof Error ? err.message : String(err); + let errorStack = getErrorStack(err); + // Remap error stack using source maps to show original source locations + if (errorStack) { + const parsedName = parseWorkflowName(workflowName); + const filename = parsedName?.path || workflowName; + errorStack = remapErrorStack(errorStack, filename, workflowCode); + } + console.error(`${errorName} while running "${runId}" workflow:\n\n${errorStack}`); + await world.runs.update(runId, { + status: 'failed', + error: { + message: errorMessage, + stack: errorStack, + // TODO: include error codes when we define them + }, + }); + span?.setAttributes({ + ...WorkflowRunStatus('failed'), + ...WorkflowErrorName(errorName), + ...WorkflowErrorMessage(String(err)), + }); + } + } + }); // End withTraceContext + }); + }); +} +/** + * A single route that handles any step execution request and routes to the + * appropriate step function. We may eventually want to create different bundles + * for each step, this is temporary. + */ +const stepEntrypoint = +/* @__PURE__ */ getWorldHandlers().createQueueHandler('__wkf_step_', async (message_, metadata) => { + const { workflowName, workflowRunId, workflowStartedAt, stepId, traceCarrier: traceContext, } = StepInvokePayloadSchema.parse(message_); + // Execute step within the propagated trace context + return await withTraceContext(traceContext, async () => { + // Extract the step name from the topic name + const stepName = metadata.queueName.slice('__wkf_step_'.length); + const world = getWorld(); + // Get the port early to avoid async operations during step execution + const port = await getPort(); + return trace(`STEP ${stepName}`, async (span) => { + span?.setAttributes({ + ...StepName(stepName), + ...StepAttempt(metadata.attempt), + ...QueueName(metadata.queueName), + }); + const stepFn = getStepFunction(stepName); + if (!stepFn) { + throw new Error(`Step "${stepName}" not found`); + } + if (typeof stepFn !== 'function') { + throw new Error(`Step "${stepName}" is not a function (got ${typeof stepFn})`); + } + span?.setAttributes({ + ...WorkflowName(workflowName), + ...WorkflowRunId(workflowRunId), + ...StepId(stepId), + ...StepMaxRetries(stepFn.maxRetries ?? 3), + ...StepTracePropagated(!!traceContext), + }); + let step = await world.steps.get(workflowRunId, stepId); + runtimeLogger.debug('Step execution details', { + stepName, + stepId: step.stepId, + status: step.status, + attempt: step.attempt, + }); + span?.setAttributes({ + ...StepStatus(step.status), + }); + // Check if the step has a `retryAfter` timestamp that hasn't been reached yet + const now = Date.now(); + if (step.retryAfter && step.retryAfter.getTime() > now) { + const timeoutSeconds = Math.ceil((step.retryAfter.getTime() - now) / 1000); + span?.setAttributes({ + ...StepRetryTimeoutSeconds(timeoutSeconds), + }); + runtimeLogger.debug('Step retryAfter timestamp not yet reached', { + stepName, + stepId: step.stepId, + retryAfter: step.retryAfter, + timeoutSeconds, + }); + return { timeoutSeconds }; + } + let result; + const attempt = step.attempt + 1; + try { + if (step.status !== 'pending') { + // We should only be running the step if it's pending + // (initial state, or state set on re-try), so the step has been + // invoked erroneously. + console.error(`[Workflows] "${workflowRunId}" - Step invoked erroneously, expected status "pending", got "${step.status}" instead, skipping execution`); + span?.setAttributes({ + ...StepSkipped(true), + ...StepSkipReason(step.status), + }); + return; + } + await world.events.create(workflowRunId, { + eventType: 'step_started', // TODO: Replace with 'step_retrying' + correlationId: stepId, + }); + step = await world.steps.update(workflowRunId, stepId, { + attempt, + status: 'running', + }); + if (!step.startedAt) { + throw new WorkflowRuntimeError(`Step "${stepId}" has no "startedAt" timestamp`); + } + // Hydrate the step input arguments + const ops = []; + const args = hydrateStepArguments(step.input, ops); + span?.setAttributes({ + ...StepArgumentsCount(args.length), + }); + result = await contextStorage.run({ + stepMetadata: { + stepId, + stepStartedAt: new Date(+step.startedAt), + attempt, + }, + workflowMetadata: { + workflowRunId, + workflowStartedAt: new Date(+workflowStartedAt), + // TODO: there should be a getUrl method on the world interface itself. This + // solution only works for vercel + local worlds. + url: process.env.VERCEL_URL + ? `https://${process.env.VERCEL_URL}` + : `http://localhost:${port ?? 3000}`, + }, + ops, + }, () => stepFn(...args)); + result = dehydrateStepReturnValue(result, ops); + functionsExports.waitUntil(Promise.all(ops)); + // Update the event log with the step result + await world.events.create(workflowRunId, { + eventType: 'step_completed', + correlationId: stepId, + eventData: { + result: result, + }, + }); + await world.steps.update(workflowRunId, stepId, { + status: 'completed', + output: result, + }); + span?.setAttributes({ + ...StepStatus('completed'), + ...StepResultType(typeof result), + }); + } + catch (err) { + span?.setAttributes({ + ...StepErrorName(getErrorName(err)), + ...StepErrorMessage(String(err)), + }); + if (WorkflowAPIError.is(err)) { + if (err.status === 410) { + // Workflow has already completed, so no-op + console.warn(`Workflow run "${workflowRunId}" has already completed, skipping step "${stepId}": ${err.message}`); + return; + } + } + if (FatalError.is(err)) { + const errorStack = getErrorStack(err); + const stackLines = errorStack.split('\n').slice(0, 4); + console.error(`[Workflows] "${workflowRunId}" - Encountered \`FatalError\` while executing step "${stepName}":\n > ${stackLines.join('\n > ')}\n\nBubbling up error to parent workflow`); + // Fatal error - store the error in the event log and re-invoke the workflow + await world.events.create(workflowRunId, { + eventType: 'step_failed', + correlationId: stepId, + eventData: { + error: String(err), + stack: errorStack, + fatal: true, + }, + }); + await world.steps.update(workflowRunId, stepId, { + status: 'failed', + error: { + message: err.message || String(err), + stack: errorStack, + // TODO: include error codes when we define them + }, + }); + span?.setAttributes({ + ...StepStatus('failed'), + ...StepFatalError(true), + }); + } + else { + const maxRetries = stepFn.maxRetries ?? 3; + span?.setAttributes({ + ...StepAttempt(attempt), + ...StepMaxRetries(maxRetries), + }); + if (attempt >= maxRetries) { + // Max retries reached + const errorStack = getErrorStack(err); + const stackLines = errorStack.split('\n').slice(0, 4); + console.error(`[Workflows] "${workflowRunId}" - Encountered \`Error\` while executing step "${stepName}" (attempt ${attempt}):\n > ${stackLines.join('\n > ')}\n\n Max retries reached\n Bubbling error to parent workflow`); + const errorMessage = `Step "${stepName}" failed after max retries: ${String(err)}`; + await world.events.create(workflowRunId, { + eventType: 'step_failed', + correlationId: stepId, + eventData: { + error: errorMessage, + stack: errorStack, + fatal: true, + }, + }); + await world.steps.update(workflowRunId, stepId, { + status: 'failed', + error: { + message: errorMessage, + stack: errorStack, + }, + }); + span?.setAttributes({ + ...StepStatus('failed'), + ...StepRetryExhausted(true), + }); + } + else { + // Not at max retries yet - log as a retryable error + if (RetryableError.is(err)) { + console.warn(`[Workflows] "${workflowRunId}" - Encountered \`RetryableError\` while executing step "${stepName}" (attempt ${attempt}):\n > ${String(err.message)}\n\n This step has failed but will be retried`); + } + else { + const stackLines = getErrorStack(err).split('\n').slice(0, 4); + console.error(`[Workflows] "${workflowRunId}" - Encountered \`Error\` while executing step "${stepName}" (attempt ${attempt}):\n > ${stackLines.join('\n > ')}\n\n This step has failed but will be retried`); + } + await world.events.create(workflowRunId, { + eventType: 'step_failed', + correlationId: stepId, + eventData: { + error: String(err), + stack: getErrorStack(err), + }, + }); + await world.steps.update(workflowRunId, stepId, { + status: 'pending', // TODO: Should be "retrying" once we have that status + ...(RetryableError.is(err) && { + retryAfter: err.retryAfter, + }), + }); + const timeoutSeconds = Math.max(1, RetryableError.is(err) + ? Math.ceil((+err.retryAfter.getTime() - Date.now()) / 1000) + : 1); + span?.setAttributes({ + ...StepRetryTimeoutSeconds(timeoutSeconds), + ...StepRetryWillRetry(true), + }); + // It's a retryable error - so have the queue keep the message visible + // so that it gets retried. + return { timeoutSeconds }; + } + } + } + await world.queue(`__wkf_workflow_${workflowName}`, { + runId: workflowRunId, + traceCarrier: await serializeTraceCarrier(), + }); + }); + }); +}); + +export { Run as R, contextStorage as c, getRun as g, stepEntrypoint as s, workflowEntrypoint as w }; diff --git a/workbench/astro/dist/server/chunks/sharp_CR567j69.mjs b/workbench/astro/dist/server/chunks/sharp_CR567j69.mjs new file mode 100644 index 000000000..0efeb7f3e --- /dev/null +++ b/workbench/astro/dist/server/chunks/sharp_CR567j69.mjs @@ -0,0 +1,99 @@ +import { A as AstroError, al as MissingSharp } from './astro/server_DhWKww_t.mjs'; +import { b as baseService, p as parseQuality } from './node_C2n6Z2oQ.mjs'; + +let sharp; +const qualityTable = { + low: 25, + mid: 50, + high: 80, + max: 100 +}; +async function loadSharp() { + let sharpImport; + try { + sharpImport = (await import('sharp')).default; + } catch { + throw new AstroError(MissingSharp); + } + sharpImport.cache(false); + return sharpImport; +} +const fitMap = { + fill: "fill", + contain: "inside", + cover: "cover", + none: "outside", + "scale-down": "inside", + outside: "outside", + inside: "inside" +}; +const sharpService = { + validateOptions: baseService.validateOptions, + getURL: baseService.getURL, + parseURL: baseService.parseURL, + getHTMLAttributes: baseService.getHTMLAttributes, + getSrcSet: baseService.getSrcSet, + async transform(inputBuffer, transformOptions, config) { + if (!sharp) sharp = await loadSharp(); + const transform = transformOptions; + if (transform.format === "svg") return { data: inputBuffer, format: "svg" }; + const result = sharp(inputBuffer, { + failOnError: false, + pages: -1, + limitInputPixels: config.service.config.limitInputPixels + }); + result.rotate(); + const withoutEnlargement = Boolean(transform.fit); + if (transform.width && transform.height && transform.fit) { + const fit = fitMap[transform.fit] ?? "inside"; + result.resize({ + width: Math.round(transform.width), + height: Math.round(transform.height), + fit, + position: transform.position, + withoutEnlargement + }); + } else if (transform.height && !transform.width) { + result.resize({ + height: Math.round(transform.height), + withoutEnlargement + }); + } else if (transform.width) { + result.resize({ + width: Math.round(transform.width), + withoutEnlargement + }); + } + if (transform.format) { + let quality = void 0; + if (transform.quality) { + const parsedQuality = parseQuality(transform.quality); + if (typeof parsedQuality === "number") { + quality = parsedQuality; + } else { + quality = transform.quality in qualityTable ? qualityTable[transform.quality] : void 0; + } + } + const isGifInput = inputBuffer[0] === 71 && // 'G' + inputBuffer[1] === 73 && // 'I' + inputBuffer[2] === 70 && // 'F' + inputBuffer[3] === 56 && // '8' + (inputBuffer[4] === 57 || inputBuffer[4] === 55) && // '9' or '7' + inputBuffer[5] === 97; + if (transform.format === "webp" && isGifInput) { + result.webp({ quality: typeof quality === "number" ? quality : void 0, loop: 0 }); + } else { + result.toFormat(transform.format, { quality }); + } + } + const { data, info } = await result.toBuffer({ resolveWithObject: true }); + const needsCopy = "buffer" in data && data.buffer instanceof SharedArrayBuffer; + return { + data: needsCopy ? new Uint8Array(data) : data, + format: info.format + }; + } +}; +var sharp_default = sharpService; + +export { sharp_default as default }; diff --git a/workbench/astro/dist/server/chunks/token-util_8GTOk-OQ.mjs b/workbench/astro/dist/server/chunks/token-util_8GTOk-OQ.mjs new file mode 100644 index 000000000..39e4b353e --- /dev/null +++ b/workbench/astro/dist/server/chunks/token-util_8GTOk-OQ.mjs @@ -0,0 +1,260 @@ +import require$$0 from 'path'; +import require$$0$1 from 'fs'; +import { at as requireTokenError } from './index_ePTMDSOu.mjs'; +import require$$2 from 'os'; + +var tokenIo; +var hasRequiredTokenIo; + +function requireTokenIo () { + if (hasRequiredTokenIo) return tokenIo; + hasRequiredTokenIo = 1; + var __create = Object.create; + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; + var __getOwnPropNames = Object.getOwnPropertyNames; + var __getProtoOf = Object.getPrototypeOf; + var __hasOwnProp = Object.prototype.hasOwnProperty; + var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; + }; + var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod + )); + var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + var token_io_exports = {}; + __export(token_io_exports, { + findRootDir: () => findRootDir, + getUserDataDir: () => getUserDataDir + }); + tokenIo = __toCommonJS(token_io_exports); + var import_path = __toESM(require$$0); + var import_fs = __toESM(require$$0$1); + var import_os = __toESM(require$$2); + var import_token_error = requireTokenError(); + function findRootDir() { + try { + let dir = process.cwd(); + while (dir !== import_path.default.dirname(dir)) { + const pkgPath = import_path.default.join(dir, ".vercel"); + if (import_fs.default.existsSync(pkgPath)) { + return dir; + } + dir = import_path.default.dirname(dir); + } + } catch (e) { + throw new import_token_error.VercelOidcTokenError( + "Token refresh only supported in node server environments" + ); + } + throw new import_token_error.VercelOidcTokenError("Unable to find root directory"); + } + function getUserDataDir() { + if (process.env.XDG_DATA_HOME) { + return process.env.XDG_DATA_HOME; + } + switch (import_os.default.platform()) { + case "darwin": + return import_path.default.join(import_os.default.homedir(), "Library/Application Support"); + case "linux": + return import_path.default.join(import_os.default.homedir(), ".local/share"); + case "win32": + if (process.env.LOCALAPPDATA) { + return process.env.LOCALAPPDATA; + } + return null; + default: + return null; + } + } + return tokenIo; +} + +var tokenUtil; +var hasRequiredTokenUtil; + +function requireTokenUtil () { + if (hasRequiredTokenUtil) return tokenUtil; + hasRequiredTokenUtil = 1; + var __create = Object.create; + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; + var __getOwnPropNames = Object.getOwnPropertyNames; + var __getProtoOf = Object.getPrototypeOf; + var __hasOwnProp = Object.prototype.hasOwnProperty; + var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; + }; + var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod + )); + var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + var token_util_exports = {}; + __export(token_util_exports, { + assertVercelOidcTokenResponse: () => assertVercelOidcTokenResponse, + findProjectInfo: () => findProjectInfo, + getTokenPayload: () => getTokenPayload, + getVercelCliToken: () => getVercelCliToken, + getVercelDataDir: () => getVercelDataDir, + getVercelOidcToken: () => getVercelOidcToken, + isExpired: () => isExpired, + loadToken: () => loadToken, + saveToken: () => saveToken + }); + tokenUtil = __toCommonJS(token_util_exports); + var path = __toESM(require$$0); + var fs = __toESM(require$$0$1); + var import_token_error = requireTokenError(); + var import_token_io = requireTokenIo(); + function getVercelDataDir() { + const vercelFolder = "com.vercel.cli"; + const dataDir = (0, import_token_io.getUserDataDir)(); + if (!dataDir) { + return null; + } + return path.join(dataDir, vercelFolder); + } + function getVercelCliToken() { + const dataDir = getVercelDataDir(); + if (!dataDir) { + return null; + } + const tokenPath = path.join(dataDir, "auth.json"); + if (!fs.existsSync(tokenPath)) { + return null; + } + const token = fs.readFileSync(tokenPath, "utf8"); + if (!token) { + return null; + } + return JSON.parse(token).token; + } + async function getVercelOidcToken(authToken, projectId, teamId) { + try { + const url = `https://api.vercel.com/v1/projects/${projectId}/token?source=vercel-oidc-refresh${teamId ? `&teamId=${teamId}` : ""}`; + const res = await fetch(url, { + method: "POST", + headers: { + Authorization: `Bearer ${authToken}` + } + }); + if (!res.ok) { + throw new import_token_error.VercelOidcTokenError( + `Failed to refresh OIDC token: ${res.statusText}` + ); + } + const tokenRes = await res.json(); + assertVercelOidcTokenResponse(tokenRes); + return tokenRes; + } catch (e) { + throw new import_token_error.VercelOidcTokenError(`Failed to refresh OIDC token`, e); + } + } + function assertVercelOidcTokenResponse(res) { + if (!res || typeof res !== "object") { + throw new TypeError("Expected an object"); + } + if (!("token" in res) || typeof res.token !== "string") { + throw new TypeError("Expected a string-valued token property"); + } + } + function findProjectInfo() { + const dir = (0, import_token_io.findRootDir)(); + if (!dir) { + throw new import_token_error.VercelOidcTokenError("Unable to find root directory"); + } + try { + const prjPath = path.join(dir, ".vercel", "project.json"); + if (!fs.existsSync(prjPath)) { + throw new import_token_error.VercelOidcTokenError("project.json not found"); + } + const prj = JSON.parse(fs.readFileSync(prjPath, "utf8")); + if (typeof prj.projectId !== "string" && typeof prj.orgId !== "string") { + throw new TypeError("Expected a string-valued projectId property"); + } + return { projectId: prj.projectId, teamId: prj.orgId }; + } catch (e) { + throw new import_token_error.VercelOidcTokenError(`Unable to find project ID`, e); + } + } + function saveToken(token, projectId) { + try { + const dir = (0, import_token_io.getUserDataDir)(); + if (!dir) { + throw new import_token_error.VercelOidcTokenError("Unable to find user data directory"); + } + const tokenPath = path.join(dir, "com.vercel.token", `${projectId}.json`); + const tokenJson = JSON.stringify(token); + fs.mkdirSync(path.dirname(tokenPath), { mode: 432, recursive: true }); + fs.writeFileSync(tokenPath, tokenJson); + fs.chmodSync(tokenPath, 432); + return; + } catch (e) { + throw new import_token_error.VercelOidcTokenError(`Failed to save token`, e); + } + } + function loadToken(projectId) { + try { + const dir = (0, import_token_io.getUserDataDir)(); + if (!dir) { + return null; + } + const tokenPath = path.join(dir, "com.vercel.token", `${projectId}.json`); + if (!fs.existsSync(tokenPath)) { + return null; + } + const token = JSON.parse(fs.readFileSync(tokenPath, "utf8")); + assertVercelOidcTokenResponse(token); + return token; + } catch (e) { + throw new import_token_error.VercelOidcTokenError(`Failed to load token`, e); + } + } + function getTokenPayload(token) { + const tokenParts = token.split("."); + if (tokenParts.length !== 3) { + throw new import_token_error.VercelOidcTokenError("Invalid token"); + } + const base64 = tokenParts[1].replace(/-/g, "+").replace(/_/g, "/"); + const padded = base64.padEnd( + base64.length + (4 - base64.length % 4) % 4, + "=" + ); + return JSON.parse(Buffer.from(padded, "base64").toString("utf8")); + } + const TIME_15_MINUTES_IN_MS = 15 * 60 * 1e3; + function isExpired(token) { + return token.exp * 1e3 < Date.now() + TIME_15_MINUTES_IN_MS; + } + return tokenUtil; +} + +export { requireTokenUtil as r }; diff --git a/workbench/astro/dist/server/chunks/token-util_D6r3xWR2.mjs b/workbench/astro/dist/server/chunks/token-util_D6r3xWR2.mjs new file mode 100644 index 000000000..da9cf584d --- /dev/null +++ b/workbench/astro/dist/server/chunks/token-util_D6r3xWR2.mjs @@ -0,0 +1,30 @@ +import { g as getDefaultExportFromCjs } from './_commonjsHelpers_BFTU3MAI.mjs'; +import { r as requireTokenUtil } from './token-util_8GTOk-OQ.mjs'; + +function _mergeNamespaces(n, m) { + for (var i = 0; i < m.length; i++) { + const e = m[i]; + if (typeof e !== 'string' && !Array.isArray(e)) { for (const k in e) { + if (k !== 'default' && !(k in n)) { + const d = Object.getOwnPropertyDescriptor(e, k); + if (d) { + Object.defineProperty(n, k, d.get ? d : { + enumerable: true, + get: () => e[k] + }); + } + } + } } + } + return Object.freeze(Object.defineProperty(n, Symbol.toStringTag, { value: 'Module' })); +} + +var tokenUtilExports = requireTokenUtil(); +const tokenUtil = /*@__PURE__*/getDefaultExportFromCjs(tokenUtilExports); + +const tokenUtil$1 = /*#__PURE__*/_mergeNamespaces({ + __proto__: null, + default: tokenUtil +}, [tokenUtilExports]); + +export { tokenUtil$1 as t }; diff --git a/workbench/astro/dist/server/chunks/token_CrOFk7pc.mjs b/workbench/astro/dist/server/chunks/token_CrOFk7pc.mjs new file mode 100644 index 000000000..312b8d434 --- /dev/null +++ b/workbench/astro/dist/server/chunks/token_CrOFk7pc.mjs @@ -0,0 +1,88 @@ +import { g as getDefaultExportFromCjs } from './_commonjsHelpers_BFTU3MAI.mjs'; +import { at as requireTokenError } from './index_ePTMDSOu.mjs'; +import { r as requireTokenUtil } from './token-util_8GTOk-OQ.mjs'; + +function _mergeNamespaces(n, m) { + for (var i = 0; i < m.length; i++) { + const e = m[i]; + if (typeof e !== 'string' && !Array.isArray(e)) { for (const k in e) { + if (k !== 'default' && !(k in n)) { + const d = Object.getOwnPropertyDescriptor(e, k); + if (d) { + Object.defineProperty(n, k, d.get ? d : { + enumerable: true, + get: () => e[k] + }); + } + } + } } + } + return Object.freeze(Object.defineProperty(n, Symbol.toStringTag, { value: 'Module' })); +} + +var token$2; +var hasRequiredToken; + +function requireToken () { + if (hasRequiredToken) return token$2; + hasRequiredToken = 1; + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; + var __getOwnPropNames = Object.getOwnPropertyNames; + var __hasOwnProp = Object.prototype.hasOwnProperty; + var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + var token_exports = {}; + __export(token_exports, { + refreshToken: () => refreshToken + }); + token$2 = __toCommonJS(token_exports); + var import_token_error = requireTokenError(); + var import_token_util = requireTokenUtil(); + async function refreshToken() { + const { projectId, teamId } = (0, import_token_util.findProjectInfo)(); + let maybeToken = (0, import_token_util.loadToken)(projectId); + if (!maybeToken || (0, import_token_util.isExpired)((0, import_token_util.getTokenPayload)(maybeToken.token))) { + const authToken = (0, import_token_util.getVercelCliToken)(); + if (!authToken) { + throw new import_token_error.VercelOidcTokenError( + "Failed to refresh OIDC token: login to vercel cli" + ); + } + if (!projectId) { + throw new import_token_error.VercelOidcTokenError( + "Failed to refresh OIDC token: project id not found" + ); + } + maybeToken = await (0, import_token_util.getVercelOidcToken)(authToken, projectId, teamId); + if (!maybeToken) { + throw new import_token_error.VercelOidcTokenError("Failed to refresh OIDC token"); + } + (0, import_token_util.saveToken)(maybeToken, projectId); + } + process.env.VERCEL_OIDC_TOKEN = maybeToken.token; + return; + } + return token$2; +} + +var tokenExports = requireToken(); +const token = /*@__PURE__*/getDefaultExportFromCjs(tokenExports); + +const token$1 = /*#__PURE__*/_mergeNamespaces({ + __proto__: null, + default: token +}, [tokenExports]); + +export { token$1 as t }; diff --git a/workbench/astro/dist/server/entry.mjs b/workbench/astro/dist/server/entry.mjs new file mode 100644 index 000000000..4688832ce --- /dev/null +++ b/workbench/astro/dist/server/entry.mjs @@ -0,0 +1,51 @@ +import { renderers } from './renderers.mjs'; +import { c as createExports, s as serverEntrypointModule } from './chunks/_@astrojs-ssr-adapter_9__r_ZjJ.mjs'; +import { manifest } from './manifest_Dl93wae-.mjs'; + +const serverIslandMap = new Map();; + +const _page0 = () => import('./pages/_image.astro.mjs'); +const _page1 = () => import('./pages/.well-known/workflow/v1/flow.astro.mjs'); +const _page2 = () => import('./pages/.well-known/workflow/v1/step.astro.mjs'); +const _page3 = () => import('./pages/.well-known/workflow/v1/webhook/_token_.astro.mjs'); +const _page4 = () => import('./pages/api/hook.astro.mjs'); +const _page5 = () => import('./pages/api/test-direct-step-call.astro.mjs'); +const _page6 = () => import('./pages/api/trigger.astro.mjs'); +const _page7 = () => import('./pages/index.astro.mjs'); +const pageMap = new Map([ + ["../../node_modules/.pnpm/astro@5.15.6_@netlify+blobs@9.1.2_@types+node@24.6.2_@vercel+functions@3.1.4_@aws-sdk+c_33d54f21a5540c974d08dc1b122d5cc1/node_modules/astro/dist/assets/endpoint/node.js", _page0], + ["src/pages/.well-known/workflow/v1/flow.js", _page1], + ["src/pages/.well-known/workflow/v1/step.js", _page2], + ["src/pages/.well-known/workflow/v1/webhook/[token].js", _page3], + ["src/pages/api/hook.ts", _page4], + ["src/pages/api/test-direct-step-call.ts", _page5], + ["src/pages/api/trigger.ts", _page6], + ["src/pages/index.astro", _page7] +]); + +const _manifest = Object.assign(manifest, { + pageMap, + serverIslandMap, + renderers, + actions: () => import('./noop-entrypoint.mjs'), + middleware: () => import('./_noop-middleware.mjs') +}); +const _args = { + "mode": "standalone", + "client": "file:///Users/adrianlam/GitHub/workflow/workbench/astro/dist/client/", + "server": "file:///Users/adrianlam/GitHub/workflow/workbench/astro/dist/server/", + "host": false, + "port": 4321, + "assets": "_astro", + "experimentalStaticHeaders": false +}; +const _exports = createExports(_manifest, _args); +const handler = _exports['handler']; +const startServer = _exports['startServer']; +const options = _exports['options']; +const _start = 'start'; +if (Object.prototype.hasOwnProperty.call(serverEntrypointModule, _start)) { + serverEntrypointModule[_start](_manifest, _args); +} + +export { handler, options, pageMap, startServer }; diff --git a/workbench/astro/dist/server/manifest_Dl93wae-.mjs b/workbench/astro/dist/server/manifest_Dl93wae-.mjs new file mode 100644 index 000000000..71fbed9a3 --- /dev/null +++ b/workbench/astro/dist/server/manifest_Dl93wae-.mjs @@ -0,0 +1,101 @@ +import { l as decodeKey } from './chunks/astro/server_DhWKww_t.mjs'; +import 'clsx'; +import 'cookie'; +import { N as NOOP_MIDDLEWARE_FN } from './chunks/astro-designed-error-pages_pFA87nEA.mjs'; +import 'es-module-lexer'; + +function sanitizeParams(params) { + return Object.fromEntries( + Object.entries(params).map(([key, value]) => { + if (typeof value === "string") { + return [key, value.normalize().replace(/#/g, "%23").replace(/\?/g, "%3F")]; + } + return [key, value]; + }) + ); +} +function getParameter(part, params) { + if (part.spread) { + return params[part.content.slice(3)] || ""; + } + if (part.dynamic) { + if (!params[part.content]) { + throw new TypeError(`Missing parameter: ${part.content}`); + } + return params[part.content]; + } + return part.content.normalize().replace(/\?/g, "%3F").replace(/#/g, "%23").replace(/%5B/g, "[").replace(/%5D/g, "]"); +} +function getSegment(segment, params) { + const segmentPath = segment.map((part) => getParameter(part, params)).join(""); + return segmentPath ? "/" + segmentPath : ""; +} +function getRouteGenerator(segments, addTrailingSlash) { + return (params) => { + const sanitizedParams = sanitizeParams(params); + let trailing = ""; + if (addTrailingSlash === "always" && segments.length) { + trailing = "/"; + } + const path = segments.map((segment) => getSegment(segment, sanitizedParams)).join("") + trailing; + return path || "/"; + }; +} + +function deserializeRouteData(rawRouteData) { + return { + route: rawRouteData.route, + type: rawRouteData.type, + pattern: new RegExp(rawRouteData.pattern), + params: rawRouteData.params, + component: rawRouteData.component, + generate: getRouteGenerator(rawRouteData.segments, rawRouteData._meta.trailingSlash), + pathname: rawRouteData.pathname || void 0, + segments: rawRouteData.segments, + prerender: rawRouteData.prerender, + redirect: rawRouteData.redirect, + redirectRoute: rawRouteData.redirectRoute ? deserializeRouteData(rawRouteData.redirectRoute) : void 0, + fallbackRoutes: rawRouteData.fallbackRoutes.map((fallback) => { + return deserializeRouteData(fallback); + }), + isIndex: rawRouteData.isIndex, + origin: rawRouteData.origin + }; +} + +function deserializeManifest(serializedManifest) { + const routes = []; + for (const serializedRoute of serializedManifest.routes) { + routes.push({ + ...serializedRoute, + routeData: deserializeRouteData(serializedRoute.routeData) + }); + const route = serializedRoute; + route.routeData = deserializeRouteData(serializedRoute.routeData); + } + const assets = new Set(serializedManifest.assets); + const componentMetadata = new Map(serializedManifest.componentMetadata); + const inlinedScripts = new Map(serializedManifest.inlinedScripts); + const clientDirectives = new Map(serializedManifest.clientDirectives); + const serverIslandNameMap = new Map(serializedManifest.serverIslandNameMap); + const key = decodeKey(serializedManifest.key); + return { + // in case user middleware exists, this no-op middleware will be reassigned (see plugin-ssr.ts) + middleware() { + return { onRequest: NOOP_MIDDLEWARE_FN }; + }, + ...serializedManifest, + assets, + componentMetadata, + inlinedScripts, + clientDirectives, + routes, + serverIslandNameMap, + key + }; +} + +const manifest = deserializeManifest({"hrefRoot":"file:///Users/adrianlam/GitHub/workflow/workbench/astro/","cacheDir":"file:///Users/adrianlam/GitHub/workflow/workbench/astro/node_modules/.astro/","outDir":"file:///Users/adrianlam/GitHub/workflow/workbench/astro/dist/","srcDir":"file:///Users/adrianlam/GitHub/workflow/workbench/astro/src/","publicDir":"file:///Users/adrianlam/GitHub/workflow/workbench/astro/public/","buildClientDir":"file:///Users/adrianlam/GitHub/workflow/workbench/astro/dist/client/","buildServerDir":"file:///Users/adrianlam/GitHub/workflow/workbench/astro/dist/server/","adapterName":"@astrojs/node","routes":[{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"type":"page","component":"_server-islands.astro","params":["name"],"segments":[[{"content":"_server-islands","dynamic":false,"spread":false}],[{"content":"name","dynamic":true,"spread":false}]],"pattern":"^\\/_server-islands\\/([^/]+?)\\/?$","prerender":false,"isIndex":false,"fallbackRoutes":[],"route":"/_server-islands/[name]","origin":"internal","_meta":{"trailingSlash":"ignore"}}},{"file":"index.html","links":[],"scripts":[],"styles":[],"routeData":{"route":"/","isIndex":true,"type":"page","pattern":"^\\/$","segments":[],"params":[],"component":"src/pages/index.astro","pathname":"/","prerender":true,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"type":"endpoint","isIndex":false,"route":"/_image","pattern":"^\\/_image\\/?$","segments":[[{"content":"_image","dynamic":false,"spread":false}]],"params":[],"component":"../../node_modules/.pnpm/astro@5.15.6_@netlify+blobs@9.1.2_@types+node@24.6.2_@vercel+functions@3.1.4_@aws-sdk+c_33d54f21a5540c974d08dc1b122d5cc1/node_modules/astro/dist/assets/endpoint/node.js","pathname":"/_image","prerender":false,"fallbackRoutes":[],"origin":"internal","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"route":"/.well-known/workflow/v1/flow","isIndex":false,"type":"endpoint","pattern":"^\\/\\.well-known\\/workflow\\/v1\\/flow\\/?$","segments":[[{"content":".well-known","dynamic":false,"spread":false}],[{"content":"workflow","dynamic":false,"spread":false}],[{"content":"v1","dynamic":false,"spread":false}],[{"content":"flow","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/.well-known/workflow/v1/flow.js","pathname":"/.well-known/workflow/v1/flow","prerender":false,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"route":"/.well-known/workflow/v1/step","isIndex":false,"type":"endpoint","pattern":"^\\/\\.well-known\\/workflow\\/v1\\/step\\/?$","segments":[[{"content":".well-known","dynamic":false,"spread":false}],[{"content":"workflow","dynamic":false,"spread":false}],[{"content":"v1","dynamic":false,"spread":false}],[{"content":"step","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/.well-known/workflow/v1/step.js","pathname":"/.well-known/workflow/v1/step","prerender":false,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"route":"/.well-known/workflow/v1/webhook/[token]","isIndex":false,"type":"endpoint","pattern":"^\\/\\.well-known\\/workflow\\/v1\\/webhook\\/([^/]+?)\\/?$","segments":[[{"content":".well-known","dynamic":false,"spread":false}],[{"content":"workflow","dynamic":false,"spread":false}],[{"content":"v1","dynamic":false,"spread":false}],[{"content":"webhook","dynamic":false,"spread":false}],[{"content":"token","dynamic":true,"spread":false}]],"params":["token"],"component":"src/pages/.well-known/workflow/v1/webhook/[token].js","prerender":false,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"route":"/api/hook","isIndex":false,"type":"endpoint","pattern":"^\\/api\\/hook\\/?$","segments":[[{"content":"api","dynamic":false,"spread":false}],[{"content":"hook","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/api/hook.ts","pathname":"/api/hook","prerender":false,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"route":"/api/test-direct-step-call","isIndex":false,"type":"endpoint","pattern":"^\\/api\\/test-direct-step-call\\/?$","segments":[[{"content":"api","dynamic":false,"spread":false}],[{"content":"test-direct-step-call","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/api/test-direct-step-call.ts","pathname":"/api/test-direct-step-call","prerender":false,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"route":"/api/trigger","isIndex":false,"type":"endpoint","pattern":"^\\/api\\/trigger\\/?$","segments":[[{"content":"api","dynamic":false,"spread":false}],[{"content":"trigger","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/api/trigger.ts","pathname":"/api/trigger","prerender":false,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}}],"base":"/","trailingSlash":"ignore","compressHTML":true,"componentMetadata":[["/Users/adrianlam/GitHub/workflow/workbench/astro/src/pages/index.astro",{"propagation":"none","containsHead":true}]],"renderers":[],"clientDirectives":[["idle","(()=>{var l=(n,t)=>{let i=async()=>{await(await n())()},e=typeof t.value==\"object\"?t.value:void 0,s={timeout:e==null?void 0:e.timeout};\"requestIdleCallback\"in window?window.requestIdleCallback(i,s):setTimeout(i,s.timeout||200)};(self.Astro||(self.Astro={})).idle=l;window.dispatchEvent(new Event(\"astro:idle\"));})();"],["load","(()=>{var e=async t=>{await(await t())()};(self.Astro||(self.Astro={})).load=e;window.dispatchEvent(new Event(\"astro:load\"));})();"],["media","(()=>{var n=(a,t)=>{let i=async()=>{await(await a())()};if(t.value){let e=matchMedia(t.value);e.matches?i():e.addEventListener(\"change\",i,{once:!0})}};(self.Astro||(self.Astro={})).media=n;window.dispatchEvent(new Event(\"astro:media\"));})();"],["only","(()=>{var e=async t=>{await(await t())()};(self.Astro||(self.Astro={})).only=e;window.dispatchEvent(new Event(\"astro:only\"));})();"],["visible","(()=>{var a=(s,i,o)=>{let r=async()=>{await(await s())()},t=typeof i.value==\"object\"?i.value:void 0,c={rootMargin:t==null?void 0:t.rootMargin},n=new IntersectionObserver(e=>{for(let l of e)if(l.isIntersecting){n.disconnect(),r();break}},c);for(let e of o.children)n.observe(e)};(self.Astro||(self.Astro={})).visible=a;window.dispatchEvent(new Event(\"astro:visible\"));})();"]],"entryModules":{"\u0000noop-middleware":"_noop-middleware.mjs","\u0000virtual:astro:actions/noop-entrypoint":"noop-entrypoint.mjs","\u0000@astro-page:src/pages/.well-known/workflow/v1/flow@_@js":"pages/.well-known/workflow/v1/flow.astro.mjs","\u0000@astro-page:src/pages/.well-known/workflow/v1/step@_@js":"pages/.well-known/workflow/v1/step.astro.mjs","\u0000@astro-page:src/pages/.well-known/workflow/v1/webhook/[token]@_@js":"pages/.well-known/workflow/v1/webhook/_token_.astro.mjs","\u0000@astro-page:src/pages/api/hook@_@ts":"pages/api/hook.astro.mjs","\u0000@astro-page:src/pages/api/test-direct-step-call@_@ts":"pages/api/test-direct-step-call.astro.mjs","\u0000@astro-page:src/pages/api/trigger@_@ts":"pages/api/trigger.astro.mjs","\u0000@astro-page:src/pages/index@_@astro":"pages/index.astro.mjs","\u0000@astrojs-ssr-virtual-entry":"entry.mjs","\u0000@astro-renderers":"renderers.mjs","\u0000@astro-page:../../node_modules/.pnpm/astro@5.15.6_@netlify+blobs@9.1.2_@types+node@24.6.2_@vercel+functions@3.1.4_@aws-sdk+c_33d54f21a5540c974d08dc1b122d5cc1/node_modules/astro/dist/assets/endpoint/node@_@js":"pages/_image.astro.mjs","\u0000@astrojs-ssr-adapter":"_@astrojs-ssr-adapter.mjs","\u0000@astrojs-manifest":"manifest_Dl93wae-.mjs","/Users/adrianlam/GitHub/workflow/node_modules/.pnpm/unstorage@1.17.2_@netlify+blobs@9.1.2_@vercel+functions@3.1.4_@aws-sdk+credential-provi_3128ad0acdbf5fcd10d3fd4ae6facc53/node_modules/unstorage/drivers/fs-lite.mjs":"chunks/fs-lite_COtHaKzy.mjs","/Users/adrianlam/GitHub/workflow/node_modules/.pnpm/astro@5.15.6_@netlify+blobs@9.1.2_@types+node@24.6.2_@vercel+functions@3.1.4_@aws-sdk+c_33d54f21a5540c974d08dc1b122d5cc1/node_modules/astro/dist/assets/services/sharp.js":"chunks/sharp_CR567j69.mjs","/Users/adrianlam/GitHub/workflow/node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/esm/index.js":"chunks/index_DqQ8k47W.mjs","astro:scripts/before-hydration.js":""},"inlinedScripts":[],"assets":["/favicon.svg","/index.html"],"buildFormat":"directory","checkOrigin":true,"allowedDomains":[],"serverIslandNameMap":[],"key":"HL0UuLEHejpYckGtqBgG3AGwkjtu7IQ2osDhkMDvjVM=","sessionConfig":{"driver":"fs-lite","options":{"base":"/Users/adrianlam/GitHub/workflow/workbench/astro/node_modules/.astro/sessions"}}}); +if (manifest.sessionConfig) manifest.sessionConfig.driverModule = () => import('./chunks/fs-lite_COtHaKzy.mjs'); + +export { manifest }; diff --git a/workbench/astro/dist/server/noop-entrypoint.mjs b/workbench/astro/dist/server/noop-entrypoint.mjs new file mode 100644 index 000000000..f30dc327c --- /dev/null +++ b/workbench/astro/dist/server/noop-entrypoint.mjs @@ -0,0 +1,3 @@ +const server = {}; + +export { server }; diff --git a/workbench/astro/dist/server/pages/.well-known/workflow/v1/flow.astro.mjs b/workbench/astro/dist/server/pages/.well-known/workflow/v1/flow.astro.mjs new file mode 100644 index 000000000..26c14c40d --- /dev/null +++ b/workbench/astro/dist/server/pages/.well-known/workflow/v1/flow.astro.mjs @@ -0,0 +1,27439 @@ +import { w as workflowEntrypoint } from '../../../../chunks/runtime_CxdH0OC2.mjs'; +export { renderers } from '../../../../renderers.mjs'; + +// biome-ignore-all lint: generated file +/* eslint-disable */ + +const workflowCode = `var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); +var __commonJS = (cb, mod) => function __require() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; +}; +var __export = (target, all) => { + for (var name17 in all) + __defProp(target, name17, { get: all[name17], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); + +// ../../node_modules/.pnpm/ms@2.1.3/node_modules/ms/index.js +var require_ms = __commonJS({ + "../../node_modules/.pnpm/ms@2.1.3/node_modules/ms/index.js"(exports, module2) { + var s = 1e3; + var m = s * 60; + var h = m * 60; + var d = h * 24; + var w = d * 7; + var y = d * 365.25; + module2.exports = function(val, options) { + options = options || {}; + var type = typeof val; + if (type === "string" && val.length > 0) { + return parse3(val); + } else if (type === "number" && isFinite(val)) { + return options.long ? fmtLong(val) : fmtShort(val); + } + throw new Error("val is not a non-empty string or a valid number. val=" + JSON.stringify(val)); + }; + function parse3(str) { + str = String(str); + if (str.length > 100) { + return; + } + var match = /^(-?(?:\\d+)?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?\$/i.exec(str); + if (!match) { + return; + } + var n = parseFloat(match[1]); + var type = (match[2] || "ms").toLowerCase(); + switch (type) { + case "years": + case "year": + case "yrs": + case "yr": + case "y": + return n * y; + case "weeks": + case "week": + case "w": + return n * w; + case "days": + case "day": + case "d": + return n * d; + case "hours": + case "hour": + case "hrs": + case "hr": + case "h": + return n * h; + case "minutes": + case "minute": + case "mins": + case "min": + case "m": + return n * m; + case "seconds": + case "second": + case "secs": + case "sec": + case "s": + return n * s; + case "milliseconds": + case "millisecond": + case "msecs": + case "msec": + case "ms": + return n; + default: + return void 0; + } + } + __name(parse3, "parse"); + function fmtShort(ms2) { + var msAbs = Math.abs(ms2); + if (msAbs >= d) { + return Math.round(ms2 / d) + "d"; + } + if (msAbs >= h) { + return Math.round(ms2 / h) + "h"; + } + if (msAbs >= m) { + return Math.round(ms2 / m) + "m"; + } + if (msAbs >= s) { + return Math.round(ms2 / s) + "s"; + } + return ms2 + "ms"; + } + __name(fmtShort, "fmtShort"); + function fmtLong(ms2) { + var msAbs = Math.abs(ms2); + if (msAbs >= d) { + return plural(ms2, msAbs, d, "day"); + } + if (msAbs >= h) { + return plural(ms2, msAbs, h, "hour"); + } + if (msAbs >= m) { + return plural(ms2, msAbs, m, "minute"); + } + if (msAbs >= s) { + return plural(ms2, msAbs, s, "second"); + } + return ms2 + " ms"; + } + __name(fmtLong, "fmtLong"); + function plural(ms2, msAbs, n, name17) { + var isPlural = msAbs >= n * 1.5; + return Math.round(ms2 / n) + " " + name17 + (isPlural ? "s" : ""); + } + __name(plural, "plural"); + } +}); + +// ../../node_modules/.pnpm/lodash.chunk@4.2.0/node_modules/lodash.chunk/index.js +var require_lodash = __commonJS({ + "../../node_modules/.pnpm/lodash.chunk@4.2.0/node_modules/lodash.chunk/index.js"(exports, module2) { + var INFINITY = 1 / 0; + var MAX_SAFE_INTEGER = 9007199254740991; + var MAX_INTEGER = 17976931348623157e292; + var NAN = 0 / 0; + var funcTag = "[object Function]"; + var genTag = "[object GeneratorFunction]"; + var symbolTag = "[object Symbol]"; + var reTrim = /^\\s+|\\s+\$/g; + var reIsBadHex = /^[-+]0x[0-9a-f]+\$/i; + var reIsBinary = /^0b[01]+\$/i; + var reIsOctal = /^0o[0-7]+\$/i; + var reIsUint = /^(?:0|[1-9]\\d*)\$/; + var freeParseInt = parseInt; + var objectProto = Object.prototype; + var objectToString = objectProto.toString; + var nativeCeil = Math.ceil; + var nativeMax = Math.max; + function baseSlice(array2, start, end) { + var index = -1, length = array2.length; + if (start < 0) { + start = -start > length ? 0 : length + start; + } + end = end > length ? length : end; + if (end < 0) { + end += length; + } + length = start > end ? 0 : end - start >>> 0; + start >>>= 0; + var result = Array(length); + while (++index < length) { + result[index] = array2[index + start]; + } + return result; + } + __name(baseSlice, "baseSlice"); + function isIndex(value, length) { + length = length == null ? MAX_SAFE_INTEGER : length; + return !!length && (typeof value == "number" || reIsUint.test(value)) && value > -1 && value % 1 == 0 && value < length; + } + __name(isIndex, "isIndex"); + function isIterateeCall(value, index, object3) { + if (!isObject2(object3)) { + return false; + } + var type = typeof index; + if (type == "number" ? isArrayLike(object3) && isIndex(index, object3.length) : type == "string" && index in object3) { + return eq(object3[index], value); + } + return false; + } + __name(isIterateeCall, "isIterateeCall"); + function chunk2(array2, size, guard) { + if (guard ? isIterateeCall(array2, size, guard) : size === void 0) { + size = 1; + } else { + size = nativeMax(toInteger(size), 0); + } + var length = array2 ? array2.length : 0; + if (!length || size < 1) { + return []; + } + var index = 0, resIndex = 0, result = Array(nativeCeil(length / size)); + while (index < length) { + result[resIndex++] = baseSlice(array2, index, index += size); + } + return result; + } + __name(chunk2, "chunk"); + function eq(value, other) { + return value === other || value !== value && other !== other; + } + __name(eq, "eq"); + function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); + } + __name(isArrayLike, "isArrayLike"); + function isFunction(value) { + var tag = isObject2(value) ? objectToString.call(value) : ""; + return tag == funcTag || tag == genTag; + } + __name(isFunction, "isFunction"); + function isLength(value) { + return typeof value == "number" && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + __name(isLength, "isLength"); + function isObject2(value) { + var type = typeof value; + return !!value && (type == "object" || type == "function"); + } + __name(isObject2, "isObject"); + function isObjectLike(value) { + return !!value && typeof value == "object"; + } + __name(isObjectLike, "isObjectLike"); + function isSymbol(value) { + return typeof value == "symbol" || isObjectLike(value) && objectToString.call(value) == symbolTag; + } + __name(isSymbol, "isSymbol"); + function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = value < 0 ? -1 : 1; + return sign * MAX_INTEGER; + } + return value === value ? value : 0; + } + __name(toFinite, "toFinite"); + function toInteger(value) { + var result = toFinite(value), remainder = result % 1; + return result === result ? remainder ? result - remainder : result : 0; + } + __name(toInteger, "toInteger"); + function toNumber(value) { + if (typeof value == "number") { + return value; + } + if (isSymbol(value)) { + return NAN; + } + if (isObject2(value)) { + var other = typeof value.valueOf == "function" ? value.valueOf() : value; + value = isObject2(other) ? other + "" : other; + } + if (typeof value != "string") { + return value === 0 ? value : +value; + } + value = value.replace(reTrim, ""); + var isBinary = reIsBinary.test(value); + return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value; + } + __name(toNumber, "toNumber"); + module2.exports = chunk2; + } +}); + +// ../../node_modules/.pnpm/@vercel+oidc@3.0.3/node_modules/@vercel/oidc/dist/get-context.js +var require_get_context = __commonJS({ + "../../node_modules/.pnpm/@vercel+oidc@3.0.3/node_modules/@vercel/oidc/dist/get-context.js"(exports, module2) { + "use strict"; + var __defProp3 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export3 = /* @__PURE__ */ __name((target, all) => { + for (var name17 in all) __defProp3(target, name17, { + get: all[name17], + enumerable: true + }); + }, "__export"); + var __copyProps2 = /* @__PURE__ */ __name((to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) if (!__hasOwnProp2.call(to, key) && key !== except) __defProp3(to, key, { + get: /* @__PURE__ */ __name(() => from[key], "get"), + enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable + }); + } + return to; + }, "__copyProps"); + var __toCommonJS = /* @__PURE__ */ __name((mod) => __copyProps2(__defProp3({}, "__esModule", { + value: true + }), mod), "__toCommonJS"); + var get_context_exports = {}; + __export3(get_context_exports, { + SYMBOL_FOR_REQ_CONTEXT: /* @__PURE__ */ __name(() => SYMBOL_FOR_REQ_CONTEXT, "SYMBOL_FOR_REQ_CONTEXT"), + getContext: /* @__PURE__ */ __name(() => getContext3, "getContext") + }); + module2.exports = __toCommonJS(get_context_exports); + var SYMBOL_FOR_REQ_CONTEXT = Symbol.for("@vercel/request-context"); + function getContext3() { + const fromSymbol = globalThis; + return fromSymbol[SYMBOL_FOR_REQ_CONTEXT]?.get?.() ?? {}; + } + __name(getContext3, "getContext"); + } +}); + +// ../../node_modules/.pnpm/@vercel+oidc@3.0.3/node_modules/@vercel/oidc/dist/index-browser.js +var require_index_browser = __commonJS({ + "../../node_modules/.pnpm/@vercel+oidc@3.0.3/node_modules/@vercel/oidc/dist/index-browser.js"(exports, module2) { + "use strict"; + var __defProp3 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export3 = /* @__PURE__ */ __name((target, all) => { + for (var name17 in all) __defProp3(target, name17, { + get: all[name17], + enumerable: true + }); + }, "__export"); + var __copyProps2 = /* @__PURE__ */ __name((to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) if (!__hasOwnProp2.call(to, key) && key !== except) __defProp3(to, key, { + get: /* @__PURE__ */ __name(() => from[key], "get"), + enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable + }); + } + return to; + }, "__copyProps"); + var __toCommonJS = /* @__PURE__ */ __name((mod) => __copyProps2(__defProp3({}, "__esModule", { + value: true + }), mod), "__toCommonJS"); + var index_browser_exports = {}; + __export3(index_browser_exports, { + getContext: /* @__PURE__ */ __name(() => import_get_context.getContext, "getContext"), + getVercelOidcToken: /* @__PURE__ */ __name(() => getVercelOidcToken2, "getVercelOidcToken"), + getVercelOidcTokenSync: /* @__PURE__ */ __name(() => getVercelOidcTokenSync, "getVercelOidcTokenSync") + }); + module2.exports = __toCommonJS(index_browser_exports); + var import_get_context = require_get_context(); + async function getVercelOidcToken2() { + return ""; + } + __name(getVercelOidcToken2, "getVercelOidcToken"); + function getVercelOidcTokenSync() { + return ""; + } + __name(getVercelOidcTokenSync, "getVercelOidcTokenSync"); + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/platform/node/globalThis.js +var require_globalThis = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/platform/node/globalThis.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports._globalThis = void 0; + exports._globalThis = typeof globalThis === "object" ? globalThis : global; + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/platform/node/index.js +var require_node = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/platform/node/index.js"(exports) { + "use strict"; + var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + Object.defineProperty(o, k2, { + enumerable: true, + get: /* @__PURE__ */ __name(function() { + return m[k]; + }, "get") + }); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __exportStar = exports && exports.__exportStar || function(m, exports1) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports1, p)) __createBinding(exports1, m, p); + }; + Object.defineProperty(exports, "__esModule", { + value: true + }); + __exportStar(require_globalThis(), exports); + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/platform/index.js +var require_platform = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/platform/index.js"(exports) { + "use strict"; + var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + Object.defineProperty(o, k2, { + enumerable: true, + get: /* @__PURE__ */ __name(function() { + return m[k]; + }, "get") + }); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __exportStar = exports && exports.__exportStar || function(m, exports1) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports1, p)) __createBinding(exports1, m, p); + }; + Object.defineProperty(exports, "__esModule", { + value: true + }); + __exportStar(require_node(), exports); + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/version.js +var require_version = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/version.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.VERSION = void 0; + exports.VERSION = "1.9.0"; + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/internal/semver.js +var require_semver = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/internal/semver.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.isCompatible = exports._makeCompatibilityCheck = void 0; + var version_1 = require_version(); + var re = /^(\\d+)\\.(\\d+)\\.(\\d+)(-(.+))?\$/; + function _makeCompatibilityCheck(ownVersion) { + const acceptedVersions = /* @__PURE__ */ new Set([ + ownVersion + ]); + const rejectedVersions = /* @__PURE__ */ new Set(); + const myVersionMatch = ownVersion.match(re); + if (!myVersionMatch) { + return () => false; + } + const ownVersionParsed = { + major: +myVersionMatch[1], + minor: +myVersionMatch[2], + patch: +myVersionMatch[3], + prerelease: myVersionMatch[4] + }; + if (ownVersionParsed.prerelease != null) { + return /* @__PURE__ */ __name(function isExactmatch(globalVersion) { + return globalVersion === ownVersion; + }, "isExactmatch"); + } + function _reject(v) { + rejectedVersions.add(v); + return false; + } + __name(_reject, "_reject"); + function _accept(v) { + acceptedVersions.add(v); + return true; + } + __name(_accept, "_accept"); + return /* @__PURE__ */ __name(function isCompatible(globalVersion) { + if (acceptedVersions.has(globalVersion)) { + return true; + } + if (rejectedVersions.has(globalVersion)) { + return false; + } + const globalVersionMatch = globalVersion.match(re); + if (!globalVersionMatch) { + return _reject(globalVersion); + } + const globalVersionParsed = { + major: +globalVersionMatch[1], + minor: +globalVersionMatch[2], + patch: +globalVersionMatch[3], + prerelease: globalVersionMatch[4] + }; + if (globalVersionParsed.prerelease != null) { + return _reject(globalVersion); + } + if (ownVersionParsed.major !== globalVersionParsed.major) { + return _reject(globalVersion); + } + if (ownVersionParsed.major === 0) { + if (ownVersionParsed.minor === globalVersionParsed.minor && ownVersionParsed.patch <= globalVersionParsed.patch) { + return _accept(globalVersion); + } + return _reject(globalVersion); + } + if (ownVersionParsed.minor <= globalVersionParsed.minor) { + return _accept(globalVersion); + } + return _reject(globalVersion); + }, "isCompatible"); + } + __name(_makeCompatibilityCheck, "_makeCompatibilityCheck"); + exports._makeCompatibilityCheck = _makeCompatibilityCheck; + exports.isCompatible = _makeCompatibilityCheck(version_1.VERSION); + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/internal/global-utils.js +var require_global_utils = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/internal/global-utils.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.unregisterGlobal = exports.getGlobal = exports.registerGlobal = void 0; + var platform_1 = require_platform(); + var version_1 = require_version(); + var semver_1 = require_semver(); + var major = version_1.VERSION.split(".")[0]; + var GLOBAL_OPENTELEMETRY_API_KEY = Symbol.for(\`opentelemetry.js.api.\${major}\`); + var _global = platform_1._globalThis; + function registerGlobal(type, instance, diag, allowOverride = false) { + var _a17; + const api = _global[GLOBAL_OPENTELEMETRY_API_KEY] = (_a17 = _global[GLOBAL_OPENTELEMETRY_API_KEY]) !== null && _a17 !== void 0 ? _a17 : { + version: version_1.VERSION + }; + if (!allowOverride && api[type]) { + const err = new Error(\`@opentelemetry/api: Attempted duplicate registration of API: \${type}\`); + diag.error(err.stack || err.message); + return false; + } + if (api.version !== version_1.VERSION) { + const err = new Error(\`@opentelemetry/api: Registration of version v\${api.version} for \${type} does not match previously registered API v\${version_1.VERSION}\`); + diag.error(err.stack || err.message); + return false; + } + api[type] = instance; + diag.debug(\`@opentelemetry/api: Registered a global for \${type} v\${version_1.VERSION}.\`); + return true; + } + __name(registerGlobal, "registerGlobal"); + exports.registerGlobal = registerGlobal; + function getGlobal(type) { + var _a17, _b8; + const globalVersion = (_a17 = _global[GLOBAL_OPENTELEMETRY_API_KEY]) === null || _a17 === void 0 ? void 0 : _a17.version; + if (!globalVersion || !(0, semver_1.isCompatible)(globalVersion)) { + return; + } + return (_b8 = _global[GLOBAL_OPENTELEMETRY_API_KEY]) === null || _b8 === void 0 ? void 0 : _b8[type]; + } + __name(getGlobal, "getGlobal"); + exports.getGlobal = getGlobal; + function unregisterGlobal(type, diag) { + diag.debug(\`@opentelemetry/api: Unregistering a global for \${type} v\${version_1.VERSION}.\`); + const api = _global[GLOBAL_OPENTELEMETRY_API_KEY]; + if (api) { + delete api[type]; + } + } + __name(unregisterGlobal, "unregisterGlobal"); + exports.unregisterGlobal = unregisterGlobal; + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/diag/ComponentLogger.js +var require_ComponentLogger = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/diag/ComponentLogger.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.DiagComponentLogger = void 0; + var global_utils_1 = require_global_utils(); + var DiagComponentLogger = class { + static { + __name(this, "DiagComponentLogger"); + } + constructor(props) { + this._namespace = props.namespace || "DiagComponentLogger"; + } + debug(...args) { + return logProxy("debug", this._namespace, args); + } + error(...args) { + return logProxy("error", this._namespace, args); + } + info(...args) { + return logProxy("info", this._namespace, args); + } + warn(...args) { + return logProxy("warn", this._namespace, args); + } + verbose(...args) { + return logProxy("verbose", this._namespace, args); + } + }; + exports.DiagComponentLogger = DiagComponentLogger; + function logProxy(funcName, namespace, args) { + const logger = (0, global_utils_1.getGlobal)("diag"); + if (!logger) { + return; + } + args.unshift(namespace); + return logger[funcName](...args); + } + __name(logProxy, "logProxy"); + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/diag/types.js +var require_types = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/diag/types.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.DiagLogLevel = void 0; + var DiagLogLevel; + (function(DiagLogLevel2) { + DiagLogLevel2[DiagLogLevel2["NONE"] = 0] = "NONE"; + DiagLogLevel2[DiagLogLevel2["ERROR"] = 30] = "ERROR"; + DiagLogLevel2[DiagLogLevel2["WARN"] = 50] = "WARN"; + DiagLogLevel2[DiagLogLevel2["INFO"] = 60] = "INFO"; + DiagLogLevel2[DiagLogLevel2["DEBUG"] = 70] = "DEBUG"; + DiagLogLevel2[DiagLogLevel2["VERBOSE"] = 80] = "VERBOSE"; + DiagLogLevel2[DiagLogLevel2["ALL"] = 9999] = "ALL"; + })(DiagLogLevel = exports.DiagLogLevel || (exports.DiagLogLevel = {})); + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/diag/internal/logLevelLogger.js +var require_logLevelLogger = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/diag/internal/logLevelLogger.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.createLogLevelDiagLogger = void 0; + var types_1 = require_types(); + function createLogLevelDiagLogger(maxLevel, logger) { + if (maxLevel < types_1.DiagLogLevel.NONE) { + maxLevel = types_1.DiagLogLevel.NONE; + } else if (maxLevel > types_1.DiagLogLevel.ALL) { + maxLevel = types_1.DiagLogLevel.ALL; + } + logger = logger || {}; + function _filterFunc(funcName, theLevel) { + const theFunc = logger[funcName]; + if (typeof theFunc === "function" && maxLevel >= theLevel) { + return theFunc.bind(logger); + } + return function() { + }; + } + __name(_filterFunc, "_filterFunc"); + return { + error: _filterFunc("error", types_1.DiagLogLevel.ERROR), + warn: _filterFunc("warn", types_1.DiagLogLevel.WARN), + info: _filterFunc("info", types_1.DiagLogLevel.INFO), + debug: _filterFunc("debug", types_1.DiagLogLevel.DEBUG), + verbose: _filterFunc("verbose", types_1.DiagLogLevel.VERBOSE) + }; + } + __name(createLogLevelDiagLogger, "createLogLevelDiagLogger"); + exports.createLogLevelDiagLogger = createLogLevelDiagLogger; + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/api/diag.js +var require_diag = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/api/diag.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.DiagAPI = void 0; + var ComponentLogger_1 = require_ComponentLogger(); + var logLevelLogger_1 = require_logLevelLogger(); + var types_1 = require_types(); + var global_utils_1 = require_global_utils(); + var API_NAME = "diag"; + var DiagAPI = class _DiagAPI { + static { + __name(this, "DiagAPI"); + } + /** + * Private internal constructor + * @private + */ + constructor() { + function _logProxy(funcName) { + return function(...args) { + const logger = (0, global_utils_1.getGlobal)("diag"); + if (!logger) return; + return logger[funcName](...args); + }; + } + __name(_logProxy, "_logProxy"); + const self = this; + const setLogger = /* @__PURE__ */ __name((logger, optionsOrLogLevel = { + logLevel: types_1.DiagLogLevel.INFO + }) => { + var _a17, _b8, _c; + if (logger === self) { + const err = new Error("Cannot use diag as the logger for itself. Please use a DiagLogger implementation like ConsoleDiagLogger or a custom implementation"); + self.error((_a17 = err.stack) !== null && _a17 !== void 0 ? _a17 : err.message); + return false; + } + if (typeof optionsOrLogLevel === "number") { + optionsOrLogLevel = { + logLevel: optionsOrLogLevel + }; + } + const oldLogger = (0, global_utils_1.getGlobal)("diag"); + const newLogger = (0, logLevelLogger_1.createLogLevelDiagLogger)((_b8 = optionsOrLogLevel.logLevel) !== null && _b8 !== void 0 ? _b8 : types_1.DiagLogLevel.INFO, logger); + if (oldLogger && !optionsOrLogLevel.suppressOverrideMessage) { + const stack = (_c = new Error().stack) !== null && _c !== void 0 ? _c : ""; + oldLogger.warn(\`Current logger will be overwritten from \${stack}\`); + newLogger.warn(\`Current logger will overwrite one already registered from \${stack}\`); + } + return (0, global_utils_1.registerGlobal)("diag", newLogger, self, true); + }, "setLogger"); + self.setLogger = setLogger; + self.disable = () => { + (0, global_utils_1.unregisterGlobal)(API_NAME, self); + }; + self.createComponentLogger = (options) => { + return new ComponentLogger_1.DiagComponentLogger(options); + }; + self.verbose = _logProxy("verbose"); + self.debug = _logProxy("debug"); + self.info = _logProxy("info"); + self.warn = _logProxy("warn"); + self.error = _logProxy("error"); + } + /** Get the singleton instance of the DiagAPI API */ + static instance() { + if (!this._instance) { + this._instance = new _DiagAPI(); + } + return this._instance; + } + }; + exports.DiagAPI = DiagAPI; + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/baggage/internal/baggage-impl.js +var require_baggage_impl = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/baggage/internal/baggage-impl.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.BaggageImpl = void 0; + var BaggageImpl = class _BaggageImpl { + static { + __name(this, "BaggageImpl"); + } + constructor(entries) { + this._entries = entries ? new Map(entries) : /* @__PURE__ */ new Map(); + } + getEntry(key) { + const entry = this._entries.get(key); + if (!entry) { + return void 0; + } + return Object.assign({}, entry); + } + getAllEntries() { + return Array.from(this._entries.entries()).map(([k, v]) => [ + k, + v + ]); + } + setEntry(key, entry) { + const newBaggage = new _BaggageImpl(this._entries); + newBaggage._entries.set(key, entry); + return newBaggage; + } + removeEntry(key) { + const newBaggage = new _BaggageImpl(this._entries); + newBaggage._entries.delete(key); + return newBaggage; + } + removeEntries(...keys) { + const newBaggage = new _BaggageImpl(this._entries); + for (const key of keys) { + newBaggage._entries.delete(key); + } + return newBaggage; + } + clear() { + return new _BaggageImpl(); + } + }; + exports.BaggageImpl = BaggageImpl; + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/baggage/internal/symbol.js +var require_symbol = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/baggage/internal/symbol.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.baggageEntryMetadataSymbol = void 0; + exports.baggageEntryMetadataSymbol = Symbol("BaggageEntryMetadata"); + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/baggage/utils.js +var require_utils = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/baggage/utils.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.baggageEntryMetadataFromString = exports.createBaggage = void 0; + var diag_1 = require_diag(); + var baggage_impl_1 = require_baggage_impl(); + var symbol_1 = require_symbol(); + var diag = diag_1.DiagAPI.instance(); + function createBaggage(entries = {}) { + return new baggage_impl_1.BaggageImpl(new Map(Object.entries(entries))); + } + __name(createBaggage, "createBaggage"); + exports.createBaggage = createBaggage; + function baggageEntryMetadataFromString(str) { + if (typeof str !== "string") { + diag.error(\`Cannot create baggage metadata from unknown type: \${typeof str}\`); + str = ""; + } + return { + __TYPE__: symbol_1.baggageEntryMetadataSymbol, + toString() { + return str; + } + }; + } + __name(baggageEntryMetadataFromString, "baggageEntryMetadataFromString"); + exports.baggageEntryMetadataFromString = baggageEntryMetadataFromString; + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/context/context.js +var require_context = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/context/context.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.ROOT_CONTEXT = exports.createContextKey = void 0; + function createContextKey(description) { + return Symbol.for(description); + } + __name(createContextKey, "createContextKey"); + exports.createContextKey = createContextKey; + var BaseContext = class _BaseContext { + static { + __name(this, "BaseContext"); + } + /** + * Construct a new context which inherits values from an optional parent context. + * + * @param parentContext a context from which to inherit values + */ + constructor(parentContext) { + const self = this; + self._currentContext = parentContext ? new Map(parentContext) : /* @__PURE__ */ new Map(); + self.getValue = (key) => self._currentContext.get(key); + self.setValue = (key, value) => { + const context = new _BaseContext(self._currentContext); + context._currentContext.set(key, value); + return context; + }; + self.deleteValue = (key) => { + const context = new _BaseContext(self._currentContext); + context._currentContext.delete(key); + return context; + }; + } + }; + exports.ROOT_CONTEXT = new BaseContext(); + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/diag/consoleLogger.js +var require_consoleLogger = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/diag/consoleLogger.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.DiagConsoleLogger = void 0; + var consoleMap = [ + { + n: "error", + c: "error" + }, + { + n: "warn", + c: "warn" + }, + { + n: "info", + c: "info" + }, + { + n: "debug", + c: "debug" + }, + { + n: "verbose", + c: "trace" + } + ]; + var DiagConsoleLogger = class { + static { + __name(this, "DiagConsoleLogger"); + } + constructor() { + function _consoleFunc(funcName) { + return function(...args) { + if (console) { + let theFunc = console[funcName]; + if (typeof theFunc !== "function") { + theFunc = console.log; + } + if (typeof theFunc === "function") { + return theFunc.apply(console, args); + } + } + }; + } + __name(_consoleFunc, "_consoleFunc"); + for (let i = 0; i < consoleMap.length; i++) { + this[consoleMap[i].n] = _consoleFunc(consoleMap[i].c); + } + } + }; + exports.DiagConsoleLogger = DiagConsoleLogger; + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/metrics/NoopMeter.js +var require_NoopMeter = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/metrics/NoopMeter.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.createNoopMeter = exports.NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC = exports.NOOP_OBSERVABLE_GAUGE_METRIC = exports.NOOP_OBSERVABLE_COUNTER_METRIC = exports.NOOP_UP_DOWN_COUNTER_METRIC = exports.NOOP_HISTOGRAM_METRIC = exports.NOOP_GAUGE_METRIC = exports.NOOP_COUNTER_METRIC = exports.NOOP_METER = exports.NoopObservableUpDownCounterMetric = exports.NoopObservableGaugeMetric = exports.NoopObservableCounterMetric = exports.NoopObservableMetric = exports.NoopHistogramMetric = exports.NoopGaugeMetric = exports.NoopUpDownCounterMetric = exports.NoopCounterMetric = exports.NoopMetric = exports.NoopMeter = void 0; + var NoopMeter = class { + static { + __name(this, "NoopMeter"); + } + constructor() { + } + /** + * @see {@link Meter.createGauge} + */ + createGauge(_name, _options) { + return exports.NOOP_GAUGE_METRIC; + } + /** + * @see {@link Meter.createHistogram} + */ + createHistogram(_name, _options) { + return exports.NOOP_HISTOGRAM_METRIC; + } + /** + * @see {@link Meter.createCounter} + */ + createCounter(_name, _options) { + return exports.NOOP_COUNTER_METRIC; + } + /** + * @see {@link Meter.createUpDownCounter} + */ + createUpDownCounter(_name, _options) { + return exports.NOOP_UP_DOWN_COUNTER_METRIC; + } + /** + * @see {@link Meter.createObservableGauge} + */ + createObservableGauge(_name, _options) { + return exports.NOOP_OBSERVABLE_GAUGE_METRIC; + } + /** + * @see {@link Meter.createObservableCounter} + */ + createObservableCounter(_name, _options) { + return exports.NOOP_OBSERVABLE_COUNTER_METRIC; + } + /** + * @see {@link Meter.createObservableUpDownCounter} + */ + createObservableUpDownCounter(_name, _options) { + return exports.NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC; + } + /** + * @see {@link Meter.addBatchObservableCallback} + */ + addBatchObservableCallback(_callback, _observables) { + } + /** + * @see {@link Meter.removeBatchObservableCallback} + */ + removeBatchObservableCallback(_callback) { + } + }; + exports.NoopMeter = NoopMeter; + var NoopMetric = class { + static { + __name(this, "NoopMetric"); + } + }; + exports.NoopMetric = NoopMetric; + var NoopCounterMetric = class extends NoopMetric { + static { + __name(this, "NoopCounterMetric"); + } + add(_value, _attributes) { + } + }; + exports.NoopCounterMetric = NoopCounterMetric; + var NoopUpDownCounterMetric = class extends NoopMetric { + static { + __name(this, "NoopUpDownCounterMetric"); + } + add(_value, _attributes) { + } + }; + exports.NoopUpDownCounterMetric = NoopUpDownCounterMetric; + var NoopGaugeMetric = class extends NoopMetric { + static { + __name(this, "NoopGaugeMetric"); + } + record(_value, _attributes) { + } + }; + exports.NoopGaugeMetric = NoopGaugeMetric; + var NoopHistogramMetric = class extends NoopMetric { + static { + __name(this, "NoopHistogramMetric"); + } + record(_value, _attributes) { + } + }; + exports.NoopHistogramMetric = NoopHistogramMetric; + var NoopObservableMetric = class { + static { + __name(this, "NoopObservableMetric"); + } + addCallback(_callback) { + } + removeCallback(_callback) { + } + }; + exports.NoopObservableMetric = NoopObservableMetric; + var NoopObservableCounterMetric = class extends NoopObservableMetric { + static { + __name(this, "NoopObservableCounterMetric"); + } + }; + exports.NoopObservableCounterMetric = NoopObservableCounterMetric; + var NoopObservableGaugeMetric = class extends NoopObservableMetric { + static { + __name(this, "NoopObservableGaugeMetric"); + } + }; + exports.NoopObservableGaugeMetric = NoopObservableGaugeMetric; + var NoopObservableUpDownCounterMetric = class extends NoopObservableMetric { + static { + __name(this, "NoopObservableUpDownCounterMetric"); + } + }; + exports.NoopObservableUpDownCounterMetric = NoopObservableUpDownCounterMetric; + exports.NOOP_METER = new NoopMeter(); + exports.NOOP_COUNTER_METRIC = new NoopCounterMetric(); + exports.NOOP_GAUGE_METRIC = new NoopGaugeMetric(); + exports.NOOP_HISTOGRAM_METRIC = new NoopHistogramMetric(); + exports.NOOP_UP_DOWN_COUNTER_METRIC = new NoopUpDownCounterMetric(); + exports.NOOP_OBSERVABLE_COUNTER_METRIC = new NoopObservableCounterMetric(); + exports.NOOP_OBSERVABLE_GAUGE_METRIC = new NoopObservableGaugeMetric(); + exports.NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC = new NoopObservableUpDownCounterMetric(); + function createNoopMeter() { + return exports.NOOP_METER; + } + __name(createNoopMeter, "createNoopMeter"); + exports.createNoopMeter = createNoopMeter; + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/metrics/Metric.js +var require_Metric = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/metrics/Metric.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.ValueType = void 0; + var ValueType; + (function(ValueType2) { + ValueType2[ValueType2["INT"] = 0] = "INT"; + ValueType2[ValueType2["DOUBLE"] = 1] = "DOUBLE"; + })(ValueType = exports.ValueType || (exports.ValueType = {})); + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/propagation/TextMapPropagator.js +var require_TextMapPropagator = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/propagation/TextMapPropagator.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.defaultTextMapSetter = exports.defaultTextMapGetter = void 0; + exports.defaultTextMapGetter = { + get(carrier, key) { + if (carrier == null) { + return void 0; + } + return carrier[key]; + }, + keys(carrier) { + if (carrier == null) { + return []; + } + return Object.keys(carrier); + } + }; + exports.defaultTextMapSetter = { + set(carrier, key, value) { + if (carrier == null) { + return; + } + carrier[key] = value; + } + }; + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/context/NoopContextManager.js +var require_NoopContextManager = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/context/NoopContextManager.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.NoopContextManager = void 0; + var context_1 = require_context(); + var NoopContextManager = class { + static { + __name(this, "NoopContextManager"); + } + active() { + return context_1.ROOT_CONTEXT; + } + with(_context, fn, thisArg, ...args) { + return fn.call(thisArg, ...args); + } + bind(_context, target) { + return target; + } + enable() { + return this; + } + disable() { + return this; + } + }; + exports.NoopContextManager = NoopContextManager; + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/api/context.js +var require_context2 = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/api/context.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.ContextAPI = void 0; + var NoopContextManager_1 = require_NoopContextManager(); + var global_utils_1 = require_global_utils(); + var diag_1 = require_diag(); + var API_NAME = "context"; + var NOOP_CONTEXT_MANAGER = new NoopContextManager_1.NoopContextManager(); + var ContextAPI = class _ContextAPI { + static { + __name(this, "ContextAPI"); + } + /** Empty private constructor prevents end users from constructing a new instance of the API */ + constructor() { + } + /** Get the singleton instance of the Context API */ + static getInstance() { + if (!this._instance) { + this._instance = new _ContextAPI(); + } + return this._instance; + } + /** + * Set the current context manager. + * + * @returns true if the context manager was successfully registered, else false + */ + setGlobalContextManager(contextManager) { + return (0, global_utils_1.registerGlobal)(API_NAME, contextManager, diag_1.DiagAPI.instance()); + } + /** + * Get the currently active context + */ + active() { + return this._getContextManager().active(); + } + /** + * Execute a function with an active context + * + * @param context context to be active during function execution + * @param fn function to execute in a context + * @param thisArg optional receiver to be used for calling fn + * @param args optional arguments forwarded to fn + */ + with(context, fn, thisArg, ...args) { + return this._getContextManager().with(context, fn, thisArg, ...args); + } + /** + * Bind a context to a target function or event emitter + * + * @param context context to bind to the event emitter or function. Defaults to the currently active context + * @param target function or event emitter to bind + */ + bind(context, target) { + return this._getContextManager().bind(context, target); + } + _getContextManager() { + return (0, global_utils_1.getGlobal)(API_NAME) || NOOP_CONTEXT_MANAGER; + } + /** Disable and remove the global context manager */ + disable() { + this._getContextManager().disable(); + (0, global_utils_1.unregisterGlobal)(API_NAME, diag_1.DiagAPI.instance()); + } + }; + exports.ContextAPI = ContextAPI; + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/trace_flags.js +var require_trace_flags = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/trace_flags.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.TraceFlags = void 0; + var TraceFlags; + (function(TraceFlags2) { + TraceFlags2[TraceFlags2["NONE"] = 0] = "NONE"; + TraceFlags2[TraceFlags2["SAMPLED"] = 1] = "SAMPLED"; + })(TraceFlags = exports.TraceFlags || (exports.TraceFlags = {})); + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/invalid-span-constants.js +var require_invalid_span_constants = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/invalid-span-constants.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.INVALID_SPAN_CONTEXT = exports.INVALID_TRACEID = exports.INVALID_SPANID = void 0; + var trace_flags_1 = require_trace_flags(); + exports.INVALID_SPANID = "0000000000000000"; + exports.INVALID_TRACEID = "00000000000000000000000000000000"; + exports.INVALID_SPAN_CONTEXT = { + traceId: exports.INVALID_TRACEID, + spanId: exports.INVALID_SPANID, + traceFlags: trace_flags_1.TraceFlags.NONE + }; + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/NonRecordingSpan.js +var require_NonRecordingSpan = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/NonRecordingSpan.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.NonRecordingSpan = void 0; + var invalid_span_constants_1 = require_invalid_span_constants(); + var NonRecordingSpan = class { + static { + __name(this, "NonRecordingSpan"); + } + constructor(_spanContext = invalid_span_constants_1.INVALID_SPAN_CONTEXT) { + this._spanContext = _spanContext; + } + // Returns a SpanContext. + spanContext() { + return this._spanContext; + } + // By default does nothing + setAttribute(_key, _value) { + return this; + } + // By default does nothing + setAttributes(_attributes) { + return this; + } + // By default does nothing + addEvent(_name, _attributes) { + return this; + } + addLink(_link) { + return this; + } + addLinks(_links) { + return this; + } + // By default does nothing + setStatus(_status) { + return this; + } + // By default does nothing + updateName(_name) { + return this; + } + // By default does nothing + end(_endTime) { + } + // isRecording always returns false for NonRecordingSpan. + isRecording() { + return false; + } + // By default does nothing + recordException(_exception, _time) { + } + }; + exports.NonRecordingSpan = NonRecordingSpan; + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/context-utils.js +var require_context_utils = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/context-utils.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.getSpanContext = exports.setSpanContext = exports.deleteSpan = exports.setSpan = exports.getActiveSpan = exports.getSpan = void 0; + var context_1 = require_context(); + var NonRecordingSpan_1 = require_NonRecordingSpan(); + var context_2 = require_context2(); + var SPAN_KEY = (0, context_1.createContextKey)("OpenTelemetry Context Key SPAN"); + function getSpan(context) { + return context.getValue(SPAN_KEY) || void 0; + } + __name(getSpan, "getSpan"); + exports.getSpan = getSpan; + function getActiveSpan() { + return getSpan(context_2.ContextAPI.getInstance().active()); + } + __name(getActiveSpan, "getActiveSpan"); + exports.getActiveSpan = getActiveSpan; + function setSpan(context, span) { + return context.setValue(SPAN_KEY, span); + } + __name(setSpan, "setSpan"); + exports.setSpan = setSpan; + function deleteSpan(context) { + return context.deleteValue(SPAN_KEY); + } + __name(deleteSpan, "deleteSpan"); + exports.deleteSpan = deleteSpan; + function setSpanContext(context, spanContext) { + return setSpan(context, new NonRecordingSpan_1.NonRecordingSpan(spanContext)); + } + __name(setSpanContext, "setSpanContext"); + exports.setSpanContext = setSpanContext; + function getSpanContext(context) { + var _a17; + return (_a17 = getSpan(context)) === null || _a17 === void 0 ? void 0 : _a17.spanContext(); + } + __name(getSpanContext, "getSpanContext"); + exports.getSpanContext = getSpanContext; + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/spancontext-utils.js +var require_spancontext_utils = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/spancontext-utils.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.wrapSpanContext = exports.isSpanContextValid = exports.isValidSpanId = exports.isValidTraceId = void 0; + var invalid_span_constants_1 = require_invalid_span_constants(); + var NonRecordingSpan_1 = require_NonRecordingSpan(); + var VALID_TRACEID_REGEX = /^([0-9a-f]{32})\$/i; + var VALID_SPANID_REGEX = /^[0-9a-f]{16}\$/i; + function isValidTraceId(traceId) { + return VALID_TRACEID_REGEX.test(traceId) && traceId !== invalid_span_constants_1.INVALID_TRACEID; + } + __name(isValidTraceId, "isValidTraceId"); + exports.isValidTraceId = isValidTraceId; + function isValidSpanId(spanId) { + return VALID_SPANID_REGEX.test(spanId) && spanId !== invalid_span_constants_1.INVALID_SPANID; + } + __name(isValidSpanId, "isValidSpanId"); + exports.isValidSpanId = isValidSpanId; + function isSpanContextValid(spanContext) { + return isValidTraceId(spanContext.traceId) && isValidSpanId(spanContext.spanId); + } + __name(isSpanContextValid, "isSpanContextValid"); + exports.isSpanContextValid = isSpanContextValid; + function wrapSpanContext(spanContext) { + return new NonRecordingSpan_1.NonRecordingSpan(spanContext); + } + __name(wrapSpanContext, "wrapSpanContext"); + exports.wrapSpanContext = wrapSpanContext; + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/NoopTracer.js +var require_NoopTracer = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/NoopTracer.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.NoopTracer = void 0; + var context_1 = require_context2(); + var context_utils_1 = require_context_utils(); + var NonRecordingSpan_1 = require_NonRecordingSpan(); + var spancontext_utils_1 = require_spancontext_utils(); + var contextApi = context_1.ContextAPI.getInstance(); + var NoopTracer = class { + static { + __name(this, "NoopTracer"); + } + // startSpan starts a noop span. + startSpan(name17, options, context = contextApi.active()) { + const root = Boolean(options === null || options === void 0 ? void 0 : options.root); + if (root) { + return new NonRecordingSpan_1.NonRecordingSpan(); + } + const parentFromContext = context && (0, context_utils_1.getSpanContext)(context); + if (isSpanContext(parentFromContext) && (0, spancontext_utils_1.isSpanContextValid)(parentFromContext)) { + return new NonRecordingSpan_1.NonRecordingSpan(parentFromContext); + } else { + return new NonRecordingSpan_1.NonRecordingSpan(); + } + } + startActiveSpan(name17, arg2, arg3, arg4) { + let opts; + let ctx; + let fn; + if (arguments.length < 2) { + return; + } else if (arguments.length === 2) { + fn = arg2; + } else if (arguments.length === 3) { + opts = arg2; + fn = arg3; + } else { + opts = arg2; + ctx = arg3; + fn = arg4; + } + const parentContext = ctx !== null && ctx !== void 0 ? ctx : contextApi.active(); + const span = this.startSpan(name17, opts, parentContext); + const contextWithSpanSet = (0, context_utils_1.setSpan)(parentContext, span); + return contextApi.with(contextWithSpanSet, fn, void 0, span); + } + }; + exports.NoopTracer = NoopTracer; + function isSpanContext(spanContext) { + return typeof spanContext === "object" && typeof spanContext["spanId"] === "string" && typeof spanContext["traceId"] === "string" && typeof spanContext["traceFlags"] === "number"; + } + __name(isSpanContext, "isSpanContext"); + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/ProxyTracer.js +var require_ProxyTracer = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/ProxyTracer.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.ProxyTracer = void 0; + var NoopTracer_1 = require_NoopTracer(); + var NOOP_TRACER = new NoopTracer_1.NoopTracer(); + var ProxyTracer = class { + static { + __name(this, "ProxyTracer"); + } + constructor(_provider, name17, version2, options) { + this._provider = _provider; + this.name = name17; + this.version = version2; + this.options = options; + } + startSpan(name17, options, context) { + return this._getTracer().startSpan(name17, options, context); + } + startActiveSpan(_name, _options, _context, _fn) { + const tracer = this._getTracer(); + return Reflect.apply(tracer.startActiveSpan, tracer, arguments); + } + /** + * Try to get a tracer from the proxy tracer provider. + * If the proxy tracer provider has no delegate, return a noop tracer. + */ + _getTracer() { + if (this._delegate) { + return this._delegate; + } + const tracer = this._provider.getDelegateTracer(this.name, this.version, this.options); + if (!tracer) { + return NOOP_TRACER; + } + this._delegate = tracer; + return this._delegate; + } + }; + exports.ProxyTracer = ProxyTracer; + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/NoopTracerProvider.js +var require_NoopTracerProvider = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/NoopTracerProvider.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.NoopTracerProvider = void 0; + var NoopTracer_1 = require_NoopTracer(); + var NoopTracerProvider = class { + static { + __name(this, "NoopTracerProvider"); + } + getTracer(_name, _version, _options) { + return new NoopTracer_1.NoopTracer(); + } + }; + exports.NoopTracerProvider = NoopTracerProvider; + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/ProxyTracerProvider.js +var require_ProxyTracerProvider = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/ProxyTracerProvider.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.ProxyTracerProvider = void 0; + var ProxyTracer_1 = require_ProxyTracer(); + var NoopTracerProvider_1 = require_NoopTracerProvider(); + var NOOP_TRACER_PROVIDER = new NoopTracerProvider_1.NoopTracerProvider(); + var ProxyTracerProvider = class { + static { + __name(this, "ProxyTracerProvider"); + } + /** + * Get a {@link ProxyTracer} + */ + getTracer(name17, version2, options) { + var _a17; + return (_a17 = this.getDelegateTracer(name17, version2, options)) !== null && _a17 !== void 0 ? _a17 : new ProxyTracer_1.ProxyTracer(this, name17, version2, options); + } + getDelegate() { + var _a17; + return (_a17 = this._delegate) !== null && _a17 !== void 0 ? _a17 : NOOP_TRACER_PROVIDER; + } + /** + * Set the delegate tracer provider + */ + setDelegate(delegate) { + this._delegate = delegate; + } + getDelegateTracer(name17, version2, options) { + var _a17; + return (_a17 = this._delegate) === null || _a17 === void 0 ? void 0 : _a17.getTracer(name17, version2, options); + } + }; + exports.ProxyTracerProvider = ProxyTracerProvider; + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/SamplingResult.js +var require_SamplingResult = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/SamplingResult.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.SamplingDecision = void 0; + var SamplingDecision; + (function(SamplingDecision2) { + SamplingDecision2[SamplingDecision2["NOT_RECORD"] = 0] = "NOT_RECORD"; + SamplingDecision2[SamplingDecision2["RECORD"] = 1] = "RECORD"; + SamplingDecision2[SamplingDecision2["RECORD_AND_SAMPLED"] = 2] = "RECORD_AND_SAMPLED"; + })(SamplingDecision = exports.SamplingDecision || (exports.SamplingDecision = {})); + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/span_kind.js +var require_span_kind = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/span_kind.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.SpanKind = void 0; + var SpanKind; + (function(SpanKind2) { + SpanKind2[SpanKind2["INTERNAL"] = 0] = "INTERNAL"; + SpanKind2[SpanKind2["SERVER"] = 1] = "SERVER"; + SpanKind2[SpanKind2["CLIENT"] = 2] = "CLIENT"; + SpanKind2[SpanKind2["PRODUCER"] = 3] = "PRODUCER"; + SpanKind2[SpanKind2["CONSUMER"] = 4] = "CONSUMER"; + })(SpanKind = exports.SpanKind || (exports.SpanKind = {})); + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/status.js +var require_status = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/status.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.SpanStatusCode = void 0; + var SpanStatusCode2; + (function(SpanStatusCode3) { + SpanStatusCode3[SpanStatusCode3["UNSET"] = 0] = "UNSET"; + SpanStatusCode3[SpanStatusCode3["OK"] = 1] = "OK"; + SpanStatusCode3[SpanStatusCode3["ERROR"] = 2] = "ERROR"; + })(SpanStatusCode2 = exports.SpanStatusCode || (exports.SpanStatusCode = {})); + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/internal/tracestate-validators.js +var require_tracestate_validators = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/internal/tracestate-validators.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.validateValue = exports.validateKey = void 0; + var VALID_KEY_CHAR_RANGE = "[_0-9a-z-*/]"; + var VALID_KEY = \`[a-z]\${VALID_KEY_CHAR_RANGE}{0,255}\`; + var VALID_VENDOR_KEY = \`[a-z0-9]\${VALID_KEY_CHAR_RANGE}{0,240}@[a-z]\${VALID_KEY_CHAR_RANGE}{0,13}\`; + var VALID_KEY_REGEX = new RegExp(\`^(?:\${VALID_KEY}|\${VALID_VENDOR_KEY})\$\`); + var VALID_VALUE_BASE_REGEX = /^[ -~]{0,255}[!-~]\$/; + var INVALID_VALUE_COMMA_EQUAL_REGEX = /,|=/; + function validateKey(key) { + return VALID_KEY_REGEX.test(key); + } + __name(validateKey, "validateKey"); + exports.validateKey = validateKey; + function validateValue(value) { + return VALID_VALUE_BASE_REGEX.test(value) && !INVALID_VALUE_COMMA_EQUAL_REGEX.test(value); + } + __name(validateValue, "validateValue"); + exports.validateValue = validateValue; + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/internal/tracestate-impl.js +var require_tracestate_impl = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/internal/tracestate-impl.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.TraceStateImpl = void 0; + var tracestate_validators_1 = require_tracestate_validators(); + var MAX_TRACE_STATE_ITEMS = 32; + var MAX_TRACE_STATE_LEN = 512; + var LIST_MEMBERS_SEPARATOR = ","; + var LIST_MEMBER_KEY_VALUE_SPLITTER = "="; + var TraceStateImpl = class _TraceStateImpl { + static { + __name(this, "TraceStateImpl"); + } + constructor(rawTraceState) { + this._internalState = /* @__PURE__ */ new Map(); + if (rawTraceState) this._parse(rawTraceState); + } + set(key, value) { + const traceState = this._clone(); + if (traceState._internalState.has(key)) { + traceState._internalState.delete(key); + } + traceState._internalState.set(key, value); + return traceState; + } + unset(key) { + const traceState = this._clone(); + traceState._internalState.delete(key); + return traceState; + } + get(key) { + return this._internalState.get(key); + } + serialize() { + return this._keys().reduce((agg, key) => { + agg.push(key + LIST_MEMBER_KEY_VALUE_SPLITTER + this.get(key)); + return agg; + }, []).join(LIST_MEMBERS_SEPARATOR); + } + _parse(rawTraceState) { + if (rawTraceState.length > MAX_TRACE_STATE_LEN) return; + this._internalState = rawTraceState.split(LIST_MEMBERS_SEPARATOR).reverse().reduce((agg, part) => { + const listMember = part.trim(); + const i = listMember.indexOf(LIST_MEMBER_KEY_VALUE_SPLITTER); + if (i !== -1) { + const key = listMember.slice(0, i); + const value = listMember.slice(i + 1, part.length); + if ((0, tracestate_validators_1.validateKey)(key) && (0, tracestate_validators_1.validateValue)(value)) { + agg.set(key, value); + } else { + } + } + return agg; + }, /* @__PURE__ */ new Map()); + if (this._internalState.size > MAX_TRACE_STATE_ITEMS) { + this._internalState = new Map(Array.from(this._internalState.entries()).reverse().slice(0, MAX_TRACE_STATE_ITEMS)); + } + } + _keys() { + return Array.from(this._internalState.keys()).reverse(); + } + _clone() { + const traceState = new _TraceStateImpl(); + traceState._internalState = new Map(this._internalState); + return traceState; + } + }; + exports.TraceStateImpl = TraceStateImpl; + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/internal/utils.js +var require_utils2 = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/internal/utils.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.createTraceState = void 0; + var tracestate_impl_1 = require_tracestate_impl(); + function createTraceState(rawTraceState) { + return new tracestate_impl_1.TraceStateImpl(rawTraceState); + } + __name(createTraceState, "createTraceState"); + exports.createTraceState = createTraceState; + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/context-api.js +var require_context_api = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/context-api.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.context = void 0; + var context_1 = require_context2(); + exports.context = context_1.ContextAPI.getInstance(); + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/diag-api.js +var require_diag_api = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/diag-api.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.diag = void 0; + var diag_1 = require_diag(); + exports.diag = diag_1.DiagAPI.instance(); + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/metrics/NoopMeterProvider.js +var require_NoopMeterProvider = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/metrics/NoopMeterProvider.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.NOOP_METER_PROVIDER = exports.NoopMeterProvider = void 0; + var NoopMeter_1 = require_NoopMeter(); + var NoopMeterProvider = class { + static { + __name(this, "NoopMeterProvider"); + } + getMeter(_name, _version, _options) { + return NoopMeter_1.NOOP_METER; + } + }; + exports.NoopMeterProvider = NoopMeterProvider; + exports.NOOP_METER_PROVIDER = new NoopMeterProvider(); + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/api/metrics.js +var require_metrics = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/api/metrics.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.MetricsAPI = void 0; + var NoopMeterProvider_1 = require_NoopMeterProvider(); + var global_utils_1 = require_global_utils(); + var diag_1 = require_diag(); + var API_NAME = "metrics"; + var MetricsAPI = class _MetricsAPI { + static { + __name(this, "MetricsAPI"); + } + /** Empty private constructor prevents end users from constructing a new instance of the API */ + constructor() { + } + /** Get the singleton instance of the Metrics API */ + static getInstance() { + if (!this._instance) { + this._instance = new _MetricsAPI(); + } + return this._instance; + } + /** + * Set the current global meter provider. + * Returns true if the meter provider was successfully registered, else false. + */ + setGlobalMeterProvider(provider) { + return (0, global_utils_1.registerGlobal)(API_NAME, provider, diag_1.DiagAPI.instance()); + } + /** + * Returns the global meter provider. + */ + getMeterProvider() { + return (0, global_utils_1.getGlobal)(API_NAME) || NoopMeterProvider_1.NOOP_METER_PROVIDER; + } + /** + * Returns a meter from the global meter provider. + */ + getMeter(name17, version2, options) { + return this.getMeterProvider().getMeter(name17, version2, options); + } + /** Remove the global meter provider */ + disable() { + (0, global_utils_1.unregisterGlobal)(API_NAME, diag_1.DiagAPI.instance()); + } + }; + exports.MetricsAPI = MetricsAPI; + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/metrics-api.js +var require_metrics_api = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/metrics-api.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.metrics = void 0; + var metrics_1 = require_metrics(); + exports.metrics = metrics_1.MetricsAPI.getInstance(); + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/propagation/NoopTextMapPropagator.js +var require_NoopTextMapPropagator = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/propagation/NoopTextMapPropagator.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.NoopTextMapPropagator = void 0; + var NoopTextMapPropagator = class { + static { + __name(this, "NoopTextMapPropagator"); + } + /** Noop inject function does nothing */ + inject(_context, _carrier) { + } + /** Noop extract function does nothing and returns the input context */ + extract(context, _carrier) { + return context; + } + fields() { + return []; + } + }; + exports.NoopTextMapPropagator = NoopTextMapPropagator; + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/baggage/context-helpers.js +var require_context_helpers = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/baggage/context-helpers.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.deleteBaggage = exports.setBaggage = exports.getActiveBaggage = exports.getBaggage = void 0; + var context_1 = require_context2(); + var context_2 = require_context(); + var BAGGAGE_KEY = (0, context_2.createContextKey)("OpenTelemetry Baggage Key"); + function getBaggage(context) { + return context.getValue(BAGGAGE_KEY) || void 0; + } + __name(getBaggage, "getBaggage"); + exports.getBaggage = getBaggage; + function getActiveBaggage() { + return getBaggage(context_1.ContextAPI.getInstance().active()); + } + __name(getActiveBaggage, "getActiveBaggage"); + exports.getActiveBaggage = getActiveBaggage; + function setBaggage(context, baggage) { + return context.setValue(BAGGAGE_KEY, baggage); + } + __name(setBaggage, "setBaggage"); + exports.setBaggage = setBaggage; + function deleteBaggage(context) { + return context.deleteValue(BAGGAGE_KEY); + } + __name(deleteBaggage, "deleteBaggage"); + exports.deleteBaggage = deleteBaggage; + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/api/propagation.js +var require_propagation = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/api/propagation.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.PropagationAPI = void 0; + var global_utils_1 = require_global_utils(); + var NoopTextMapPropagator_1 = require_NoopTextMapPropagator(); + var TextMapPropagator_1 = require_TextMapPropagator(); + var context_helpers_1 = require_context_helpers(); + var utils_1 = require_utils(); + var diag_1 = require_diag(); + var API_NAME = "propagation"; + var NOOP_TEXT_MAP_PROPAGATOR = new NoopTextMapPropagator_1.NoopTextMapPropagator(); + var PropagationAPI = class _PropagationAPI { + static { + __name(this, "PropagationAPI"); + } + /** Empty private constructor prevents end users from constructing a new instance of the API */ + constructor() { + this.createBaggage = utils_1.createBaggage; + this.getBaggage = context_helpers_1.getBaggage; + this.getActiveBaggage = context_helpers_1.getActiveBaggage; + this.setBaggage = context_helpers_1.setBaggage; + this.deleteBaggage = context_helpers_1.deleteBaggage; + } + /** Get the singleton instance of the Propagator API */ + static getInstance() { + if (!this._instance) { + this._instance = new _PropagationAPI(); + } + return this._instance; + } + /** + * Set the current propagator. + * + * @returns true if the propagator was successfully registered, else false + */ + setGlobalPropagator(propagator) { + return (0, global_utils_1.registerGlobal)(API_NAME, propagator, diag_1.DiagAPI.instance()); + } + /** + * Inject context into a carrier to be propagated inter-process + * + * @param context Context carrying tracing data to inject + * @param carrier carrier to inject context into + * @param setter Function used to set values on the carrier + */ + inject(context, carrier, setter = TextMapPropagator_1.defaultTextMapSetter) { + return this._getGlobalPropagator().inject(context, carrier, setter); + } + /** + * Extract context from a carrier + * + * @param context Context which the newly created context will inherit from + * @param carrier Carrier to extract context from + * @param getter Function used to extract keys from a carrier + */ + extract(context, carrier, getter = TextMapPropagator_1.defaultTextMapGetter) { + return this._getGlobalPropagator().extract(context, carrier, getter); + } + /** + * Return a list of all fields which may be used by the propagator. + */ + fields() { + return this._getGlobalPropagator().fields(); + } + /** Remove the global propagator */ + disable() { + (0, global_utils_1.unregisterGlobal)(API_NAME, diag_1.DiagAPI.instance()); + } + _getGlobalPropagator() { + return (0, global_utils_1.getGlobal)(API_NAME) || NOOP_TEXT_MAP_PROPAGATOR; + } + }; + exports.PropagationAPI = PropagationAPI; + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/propagation-api.js +var require_propagation_api = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/propagation-api.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.propagation = void 0; + var propagation_1 = require_propagation(); + exports.propagation = propagation_1.PropagationAPI.getInstance(); + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/api/trace.js +var require_trace = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/api/trace.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.TraceAPI = void 0; + var global_utils_1 = require_global_utils(); + var ProxyTracerProvider_1 = require_ProxyTracerProvider(); + var spancontext_utils_1 = require_spancontext_utils(); + var context_utils_1 = require_context_utils(); + var diag_1 = require_diag(); + var API_NAME = "trace"; + var TraceAPI = class _TraceAPI { + static { + __name(this, "TraceAPI"); + } + /** Empty private constructor prevents end users from constructing a new instance of the API */ + constructor() { + this._proxyTracerProvider = new ProxyTracerProvider_1.ProxyTracerProvider(); + this.wrapSpanContext = spancontext_utils_1.wrapSpanContext; + this.isSpanContextValid = spancontext_utils_1.isSpanContextValid; + this.deleteSpan = context_utils_1.deleteSpan; + this.getSpan = context_utils_1.getSpan; + this.getActiveSpan = context_utils_1.getActiveSpan; + this.getSpanContext = context_utils_1.getSpanContext; + this.setSpan = context_utils_1.setSpan; + this.setSpanContext = context_utils_1.setSpanContext; + } + /** Get the singleton instance of the Trace API */ + static getInstance() { + if (!this._instance) { + this._instance = new _TraceAPI(); + } + return this._instance; + } + /** + * Set the current global tracer. + * + * @returns true if the tracer provider was successfully registered, else false + */ + setGlobalTracerProvider(provider) { + const success2 = (0, global_utils_1.registerGlobal)(API_NAME, this._proxyTracerProvider, diag_1.DiagAPI.instance()); + if (success2) { + this._proxyTracerProvider.setDelegate(provider); + } + return success2; + } + /** + * Returns the global tracer provider. + */ + getTracerProvider() { + return (0, global_utils_1.getGlobal)(API_NAME) || this._proxyTracerProvider; + } + /** + * Returns a tracer from the global tracer provider. + */ + getTracer(name17, version2) { + return this.getTracerProvider().getTracer(name17, version2); + } + /** Remove the global tracer provider */ + disable() { + (0, global_utils_1.unregisterGlobal)(API_NAME, diag_1.DiagAPI.instance()); + this._proxyTracerProvider = new ProxyTracerProvider_1.ProxyTracerProvider(); + } + }; + exports.TraceAPI = TraceAPI; + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace-api.js +var require_trace_api = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace-api.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.trace = void 0; + var trace_1 = require_trace(); + exports.trace = trace_1.TraceAPI.getInstance(); + } +}); + +// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/index.js +var require_src = __commonJS({ + "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/index.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.trace = exports.propagation = exports.metrics = exports.diag = exports.context = exports.INVALID_SPAN_CONTEXT = exports.INVALID_TRACEID = exports.INVALID_SPANID = exports.isValidSpanId = exports.isValidTraceId = exports.isSpanContextValid = exports.createTraceState = exports.TraceFlags = exports.SpanStatusCode = exports.SpanKind = exports.SamplingDecision = exports.ProxyTracerProvider = exports.ProxyTracer = exports.defaultTextMapSetter = exports.defaultTextMapGetter = exports.ValueType = exports.createNoopMeter = exports.DiagLogLevel = exports.DiagConsoleLogger = exports.ROOT_CONTEXT = exports.createContextKey = exports.baggageEntryMetadataFromString = void 0; + var utils_1 = require_utils(); + Object.defineProperty(exports, "baggageEntryMetadataFromString", { + enumerable: true, + get: /* @__PURE__ */ __name(function() { + return utils_1.baggageEntryMetadataFromString; + }, "get") + }); + var context_1 = require_context(); + Object.defineProperty(exports, "createContextKey", { + enumerable: true, + get: /* @__PURE__ */ __name(function() { + return context_1.createContextKey; + }, "get") + }); + Object.defineProperty(exports, "ROOT_CONTEXT", { + enumerable: true, + get: /* @__PURE__ */ __name(function() { + return context_1.ROOT_CONTEXT; + }, "get") + }); + var consoleLogger_1 = require_consoleLogger(); + Object.defineProperty(exports, "DiagConsoleLogger", { + enumerable: true, + get: /* @__PURE__ */ __name(function() { + return consoleLogger_1.DiagConsoleLogger; + }, "get") + }); + var types_1 = require_types(); + Object.defineProperty(exports, "DiagLogLevel", { + enumerable: true, + get: /* @__PURE__ */ __name(function() { + return types_1.DiagLogLevel; + }, "get") + }); + var NoopMeter_1 = require_NoopMeter(); + Object.defineProperty(exports, "createNoopMeter", { + enumerable: true, + get: /* @__PURE__ */ __name(function() { + return NoopMeter_1.createNoopMeter; + }, "get") + }); + var Metric_1 = require_Metric(); + Object.defineProperty(exports, "ValueType", { + enumerable: true, + get: /* @__PURE__ */ __name(function() { + return Metric_1.ValueType; + }, "get") + }); + var TextMapPropagator_1 = require_TextMapPropagator(); + Object.defineProperty(exports, "defaultTextMapGetter", { + enumerable: true, + get: /* @__PURE__ */ __name(function() { + return TextMapPropagator_1.defaultTextMapGetter; + }, "get") + }); + Object.defineProperty(exports, "defaultTextMapSetter", { + enumerable: true, + get: /* @__PURE__ */ __name(function() { + return TextMapPropagator_1.defaultTextMapSetter; + }, "get") + }); + var ProxyTracer_1 = require_ProxyTracer(); + Object.defineProperty(exports, "ProxyTracer", { + enumerable: true, + get: /* @__PURE__ */ __name(function() { + return ProxyTracer_1.ProxyTracer; + }, "get") + }); + var ProxyTracerProvider_1 = require_ProxyTracerProvider(); + Object.defineProperty(exports, "ProxyTracerProvider", { + enumerable: true, + get: /* @__PURE__ */ __name(function() { + return ProxyTracerProvider_1.ProxyTracerProvider; + }, "get") + }); + var SamplingResult_1 = require_SamplingResult(); + Object.defineProperty(exports, "SamplingDecision", { + enumerable: true, + get: /* @__PURE__ */ __name(function() { + return SamplingResult_1.SamplingDecision; + }, "get") + }); + var span_kind_1 = require_span_kind(); + Object.defineProperty(exports, "SpanKind", { + enumerable: true, + get: /* @__PURE__ */ __name(function() { + return span_kind_1.SpanKind; + }, "get") + }); + var status_1 = require_status(); + Object.defineProperty(exports, "SpanStatusCode", { + enumerable: true, + get: /* @__PURE__ */ __name(function() { + return status_1.SpanStatusCode; + }, "get") + }); + var trace_flags_1 = require_trace_flags(); + Object.defineProperty(exports, "TraceFlags", { + enumerable: true, + get: /* @__PURE__ */ __name(function() { + return trace_flags_1.TraceFlags; + }, "get") + }); + var utils_2 = require_utils2(); + Object.defineProperty(exports, "createTraceState", { + enumerable: true, + get: /* @__PURE__ */ __name(function() { + return utils_2.createTraceState; + }, "get") + }); + var spancontext_utils_1 = require_spancontext_utils(); + Object.defineProperty(exports, "isSpanContextValid", { + enumerable: true, + get: /* @__PURE__ */ __name(function() { + return spancontext_utils_1.isSpanContextValid; + }, "get") + }); + Object.defineProperty(exports, "isValidTraceId", { + enumerable: true, + get: /* @__PURE__ */ __name(function() { + return spancontext_utils_1.isValidTraceId; + }, "get") + }); + Object.defineProperty(exports, "isValidSpanId", { + enumerable: true, + get: /* @__PURE__ */ __name(function() { + return spancontext_utils_1.isValidSpanId; + }, "get") + }); + var invalid_span_constants_1 = require_invalid_span_constants(); + Object.defineProperty(exports, "INVALID_SPANID", { + enumerable: true, + get: /* @__PURE__ */ __name(function() { + return invalid_span_constants_1.INVALID_SPANID; + }, "get") + }); + Object.defineProperty(exports, "INVALID_TRACEID", { + enumerable: true, + get: /* @__PURE__ */ __name(function() { + return invalid_span_constants_1.INVALID_TRACEID; + }, "get") + }); + Object.defineProperty(exports, "INVALID_SPAN_CONTEXT", { + enumerable: true, + get: /* @__PURE__ */ __name(function() { + return invalid_span_constants_1.INVALID_SPAN_CONTEXT; + }, "get") + }); + var context_api_1 = require_context_api(); + Object.defineProperty(exports, "context", { + enumerable: true, + get: /* @__PURE__ */ __name(function() { + return context_api_1.context; + }, "get") + }); + var diag_api_1 = require_diag_api(); + Object.defineProperty(exports, "diag", { + enumerable: true, + get: /* @__PURE__ */ __name(function() { + return diag_api_1.diag; + }, "get") + }); + var metrics_api_1 = require_metrics_api(); + Object.defineProperty(exports, "metrics", { + enumerable: true, + get: /* @__PURE__ */ __name(function() { + return metrics_api_1.metrics; + }, "get") + }); + var propagation_api_1 = require_propagation_api(); + Object.defineProperty(exports, "propagation", { + enumerable: true, + get: /* @__PURE__ */ __name(function() { + return propagation_api_1.propagation; + }, "get") + }); + var trace_api_1 = require_trace_api(); + Object.defineProperty(exports, "trace", { + enumerable: true, + get: /* @__PURE__ */ __name(function() { + return trace_api_1.trace; + }, "get") + }); + exports.default = { + context: context_api_1.context, + diag: diag_api_1.diag, + metrics: metrics_api_1.metrics, + propagation: propagation_api_1.propagation, + trace: trace_api_1.trace + }; + } +}); + +// ../example/workflows/99_e2e.ts +var e2e_exports = {}; +__export(e2e_exports, { + add: () => add, + addTenWorkflow: () => addTenWorkflow, + crossFileErrorWorkflow: () => crossFileErrorWorkflow, + fetchWorkflow: () => fetchWorkflow, + hookCleanupTestWorkflow: () => hookCleanupTestWorkflow, + hookWorkflow: () => hookWorkflow, + nestedErrorWorkflow: () => nestedErrorWorkflow, + nullByteWorkflow: () => nullByteWorkflow, + outputStreamInsideStepWorkflow: () => outputStreamInsideStepWorkflow, + outputStreamWorkflow: () => outputStreamWorkflow, + promiseAllWorkflow: () => promiseAllWorkflow, + promiseAnyWorkflow: () => promiseAnyWorkflow, + promiseRaceStressTestDelayStep: () => promiseRaceStressTestDelayStep, + promiseRaceStressTestWorkflow: () => promiseRaceStressTestWorkflow, + promiseRaceWorkflow: () => promiseRaceWorkflow, + readableStreamWorkflow: () => readableStreamWorkflow, + retryAttemptCounterWorkflow: () => retryAttemptCounterWorkflow, + retryableAndFatalErrorWorkflow: () => retryableAndFatalErrorWorkflow, + sleepingWorkflow: () => sleepingWorkflow, + stepFunctionPassingWorkflow: () => stepFunctionPassingWorkflow, + webhookWorkflow: () => webhookWorkflow, + workflowAndStepMetadataWorkflow: () => workflowAndStepMetadataWorkflow +}); + +// ../../packages/utils/dist/index.js +var import_ms = __toESM(require_ms(), 1); + +// ../../packages/errors/dist/index.js +function isError(value) { + return typeof value === "object" && value !== null && "name" in value && "message" in value; +} +__name(isError, "isError"); +var FatalError = class extends Error { + static { + __name(this, "FatalError"); + } + fatal = true; + constructor(message) { + super(message); + this.name = "FatalError"; + } + static is(value) { + return isError(value) && value.name === "FatalError"; + } +}; + +// ../../packages/core/dist/symbols.js +var WORKFLOW_USE_STEP = Symbol.for("WORKFLOW_USE_STEP"); +var WORKFLOW_CREATE_HOOK = Symbol.for("WORKFLOW_CREATE_HOOK"); +var WORKFLOW_SLEEP = Symbol.for("WORKFLOW_SLEEP"); +var WORKFLOW_CONTEXT = Symbol.for("WORKFLOW_CONTEXT"); +var WORKFLOW_GET_STREAM_ID = Symbol.for("WORKFLOW_GET_STREAM_ID"); +var STREAM_NAME_SYMBOL = Symbol.for("WORKFLOW_STREAM_NAME"); +var STREAM_TYPE_SYMBOL = Symbol.for("WORKFLOW_STREAM_TYPE"); +var BODY_INIT_SYMBOL = Symbol.for("BODY_INIT"); +var WEBHOOK_RESPONSE_WRITABLE = Symbol.for("WEBHOOK_RESPONSE_WRITABLE"); +var STEP_FUNCTION_NAME_SYMBOL = Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"); + +// ../../packages/core/dist/workflow/get-workflow-metadata.js +var WORKFLOW_CONTEXT_SYMBOL = /* @__PURE__ */ Symbol.for("WORKFLOW_CONTEXT"); +function getWorkflowMetadata() { + const ctx = globalThis[WORKFLOW_CONTEXT_SYMBOL]; + if (!ctx) { + throw new Error("\`getWorkflowMetadata()\` can only be called inside a workflow or step function"); + } + return ctx; +} +__name(getWorkflowMetadata, "getWorkflowMetadata"); + +// ../../packages/core/dist/workflow/create-hook.js +function createHook(options) { + const createHookFn = globalThis[WORKFLOW_CREATE_HOOK]; + if (!createHookFn) { + throw new Error("\`createHook()\` can only be called inside a workflow function"); + } + return createHookFn(options); +} +__name(createHook, "createHook"); +function createWebhook(options) { + const { respondWith, ...rest } = options ?? {}; + let metadata; + if (typeof respondWith !== "undefined") { + metadata = { + respondWith + }; + } + const hook = createHook({ + ...rest, + metadata + }); + const { url: url2 } = getWorkflowMetadata(); + hook.url = \`\${url2}/.well-known/workflow/v1/webhook/\${encodeURIComponent(hook.token)}\`; + return hook; +} +__name(createWebhook, "createWebhook"); + +// ../../packages/core/dist/sleep.js +async function sleep(param) { + const sleepFn = globalThis[WORKFLOW_SLEEP]; + if (!sleepFn) { + throw new Error("\`sleep()\` can only be called inside a workflow function"); + } + return sleepFn(param); +} +__name(sleep, "sleep"); + +// ../../packages/core/dist/workflow/writable-stream.js +function getWritable(options = {}) { + const { namespace } = options; + const name17 = globalThis[WORKFLOW_GET_STREAM_ID](namespace); + return Object.create(globalThis.WritableStream.prototype, { + [STREAM_NAME_SYMBOL]: { + value: name17, + writable: false + } + }); +} +__name(getWritable, "getWritable"); + +// ../../packages/workflow/dist/stdlib.js +async function fetch2(...args) { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//packages/workflow/dist/stdlib.js//fetch")(...args); +} +__name(fetch2, "fetch"); +Object.defineProperty(fetch2, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//packages/workflow/dist/stdlib.js//fetch", + writable: false, + enumerable: false, + configurable: false +}); + +// ../example/workflows/helpers.ts +function throwError() { + throw new Error("Error from imported helper module"); +} +__name(throwError, "throwError"); +function callThrower() { + throwError(); +} +__name(callThrower, "callThrower"); + +// ../example/workflows/99_e2e.ts +async function add(a, b) { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//add")(a, b); +} +__name(add, "add"); +async function addTenWorkflow(input) { + const a = await add(input, 2); + const b = await add(a, 3); + const c = await add(b, 5); + return c; +} +__name(addTenWorkflow, "addTenWorkflow"); +function deepFunction() { + throw new Error("Error from deeply nested function"); +} +__name(deepFunction, "deepFunction"); +function middleFunction() { + deepFunction(); +} +__name(middleFunction, "middleFunction"); +function topLevelHelper() { + middleFunction(); +} +__name(topLevelHelper, "topLevelHelper"); +async function nestedErrorWorkflow() { + topLevelHelper(); + return "never reached"; +} +__name(nestedErrorWorkflow, "nestedErrorWorkflow"); +async function randomDelay(v) { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//randomDelay")(v); +} +__name(randomDelay, "randomDelay"); +async function promiseAllWorkflow() { + const [a, b, c] = await Promise.all([ + randomDelay("a"), + randomDelay("b"), + randomDelay("c") + ]); + return a + b + c; +} +__name(promiseAllWorkflow, "promiseAllWorkflow"); +async function specificDelay(delay2, v) { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//specificDelay")(delay2, v); +} +__name(specificDelay, "specificDelay"); +async function promiseRaceWorkflow() { + const winner = await Promise.race([ + specificDelay(1e4, "a"), + specificDelay(100, "b"), + specificDelay(2e4, "c") + ]); + return winner; +} +__name(promiseRaceWorkflow, "promiseRaceWorkflow"); +async function stepThatFails() { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//stepThatFails")(); +} +__name(stepThatFails, "stepThatFails"); +async function promiseAnyWorkflow() { + const winner = await Promise.any([ + stepThatFails(), + specificDelay(1e3, "b"), + specificDelay(3e3, "c") + ]); + return winner; +} +__name(promiseAnyWorkflow, "promiseAnyWorkflow"); +async function genReadableStream() { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//genReadableStream")(); +} +__name(genReadableStream, "genReadableStream"); +async function readableStreamWorkflow() { + console.log("calling genReadableStream"); + const stream = await genReadableStream(); + console.log("genReadableStream returned", stream); + return stream; +} +__name(readableStreamWorkflow, "readableStreamWorkflow"); +async function hookWorkflow(token, customData) { + const hook = createHook({ + token, + metadata: { + customData + } + }); + const payloads = []; + for await (const payload of hook) { + payloads.push(payload); + if (payload.done) { + break; + } + } + return payloads; +} +__name(hookWorkflow, "hookWorkflow"); +async function sendWebhookResponse(req) { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//sendWebhookResponse")(req); +} +__name(sendWebhookResponse, "sendWebhookResponse"); +async function webhookWorkflow(token, token2, token3) { + const payloads = []; + const webhookWithDefaultResponse = createWebhook({ + token + }); + const res = new Response("Hello from static response!", { + status: 402 + }); + console.log("res", res); + const webhookWithStaticResponse = createWebhook({ + token: token2, + respondWith: res + }); + const webhookWithManualResponse = createWebhook({ + token: token3, + respondWith: "manual" + }); + { + const req = await webhookWithDefaultResponse; + const body = await req.text(); + payloads.push({ + url: req.url, + method: req.method, + body + }); + } + { + const req = await webhookWithStaticResponse; + const body = await req.text(); + payloads.push({ + url: req.url, + method: req.method, + body + }); + } + { + const req = await webhookWithManualResponse; + const body = await sendWebhookResponse(req); + payloads.push({ + url: req.url, + method: req.method, + body + }); + } + return payloads; +} +__name(webhookWorkflow, "webhookWorkflow"); +async function sleepingWorkflow() { + const startTime = Date.now(); + await sleep("10s"); + const endTime = Date.now(); + return { + startTime, + endTime + }; +} +__name(sleepingWorkflow, "sleepingWorkflow"); +async function nullByteStep() { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//nullByteStep")(); +} +__name(nullByteStep, "nullByteStep"); +async function nullByteWorkflow() { + const a = await nullByteStep(); + return a; +} +__name(nullByteWorkflow, "nullByteWorkflow"); +async function stepWithMetadata() { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//stepWithMetadata")(); +} +__name(stepWithMetadata, "stepWithMetadata"); +async function workflowAndStepMetadataWorkflow() { + const workflowMetadata = getWorkflowMetadata(); + const { stepMetadata, workflowMetadata: innerWorkflowMetadata } = await stepWithMetadata(); + return { + workflowMetadata: { + workflowRunId: workflowMetadata.workflowRunId, + workflowStartedAt: workflowMetadata.workflowStartedAt, + url: workflowMetadata.url + }, + stepMetadata, + innerWorkflowMetadata + }; +} +__name(workflowAndStepMetadataWorkflow, "workflowAndStepMetadataWorkflow"); +async function stepWithOutputStreamBinary(writable, text2) { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//stepWithOutputStreamBinary")(writable, text2); +} +__name(stepWithOutputStreamBinary, "stepWithOutputStreamBinary"); +async function stepWithOutputStreamObject(writable, obj) { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//stepWithOutputStreamObject")(writable, obj); +} +__name(stepWithOutputStreamObject, "stepWithOutputStreamObject"); +async function stepCloseOutputStream(writable) { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//stepCloseOutputStream")(writable); +} +__name(stepCloseOutputStream, "stepCloseOutputStream"); +async function outputStreamWorkflow() { + const writable = getWritable(); + const namedWritable = getWritable({ + namespace: "test" + }); + await sleep("1s"); + await stepWithOutputStreamBinary(writable, "Hello, world!"); + await sleep("1s"); + await stepWithOutputStreamBinary(namedWritable, "Hello, named stream!"); + await sleep("1s"); + await stepWithOutputStreamObject(writable, { + foo: "test" + }); + await sleep("1s"); + await stepWithOutputStreamObject(namedWritable, { + foo: "bar" + }); + await sleep("1s"); + await stepCloseOutputStream(writable); + await stepCloseOutputStream(namedWritable); + return "done"; +} +__name(outputStreamWorkflow, "outputStreamWorkflow"); +async function stepWithOutputStreamInsideStep(text2) { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//stepWithOutputStreamInsideStep")(text2); +} +__name(stepWithOutputStreamInsideStep, "stepWithOutputStreamInsideStep"); +async function stepWithNamedOutputStreamInsideStep(namespace, obj) { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//stepWithNamedOutputStreamInsideStep")(namespace, obj); +} +__name(stepWithNamedOutputStreamInsideStep, "stepWithNamedOutputStreamInsideStep"); +async function stepCloseOutputStreamInsideStep(namespace) { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//stepCloseOutputStreamInsideStep")(namespace); +} +__name(stepCloseOutputStreamInsideStep, "stepCloseOutputStreamInsideStep"); +async function outputStreamInsideStepWorkflow() { + await sleep("1s"); + await stepWithOutputStreamInsideStep("Hello from step!"); + await sleep("1s"); + await stepWithNamedOutputStreamInsideStep("step-ns", { + message: "Hello from named stream in step!" + }); + await sleep("1s"); + await stepWithOutputStreamInsideStep("Second message"); + await sleep("1s"); + await stepWithNamedOutputStreamInsideStep("step-ns", { + counter: 42 + }); + await sleep("1s"); + await stepCloseOutputStreamInsideStep(); + await stepCloseOutputStreamInsideStep("step-ns"); + return "done"; +} +__name(outputStreamInsideStepWorkflow, "outputStreamInsideStepWorkflow"); +async function fetchWorkflow() { + const response = await fetch2("https://jsonplaceholder.typicode.com/todos/1"); + const data = await response.json(); + return data; +} +__name(fetchWorkflow, "fetchWorkflow"); +async function promiseRaceStressTestDelayStep(dur, resp) { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//promiseRaceStressTestDelayStep")(dur, resp); +} +__name(promiseRaceStressTestDelayStep, "promiseRaceStressTestDelayStep"); +async function promiseRaceStressTestWorkflow() { + const promises = /* @__PURE__ */ new Map(); + const done = []; + for (let i = 0; i < 5; i++) { + const resp = i; + const dur = 1e3 * 5 * i; + console.log(\`sched\`, resp, \`/\`, dur); + promises.set(i, promiseRaceStressTestDelayStep(dur, resp)); + } + while (promises.size > 0) { + console.log(\`promises.size\`, promises.size); + const res = await Promise.race(promises.values()); + console.log(res); + done.push(res); + promises.delete(res); + } + return done; +} +__name(promiseRaceStressTestWorkflow, "promiseRaceStressTestWorkflow"); +async function stepThatRetriesAndSucceeds() { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//stepThatRetriesAndSucceeds")(); +} +__name(stepThatRetriesAndSucceeds, "stepThatRetriesAndSucceeds"); +async function retryAttemptCounterWorkflow() { + console.log("Starting retry attempt counter workflow"); + const finalAttempt = await stepThatRetriesAndSucceeds(); + console.log(\`Workflow completed with final attempt: \${finalAttempt}\`); + return { + finalAttempt + }; +} +__name(retryAttemptCounterWorkflow, "retryAttemptCounterWorkflow"); +async function stepThatThrowsRetryableError() { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//stepThatThrowsRetryableError")(); +} +__name(stepThatThrowsRetryableError, "stepThatThrowsRetryableError"); +async function crossFileErrorWorkflow() { + callThrower(); + return "never reached"; +} +__name(crossFileErrorWorkflow, "crossFileErrorWorkflow"); +async function retryableAndFatalErrorWorkflow() { + const retryableResult = await stepThatThrowsRetryableError(); + let gotFatalError = false; + try { + await stepThatFails(); + } catch (error45) { + if (FatalError.is(error45)) { + gotFatalError = true; + } + } + return { + retryableResult, + gotFatalError + }; +} +__name(retryableAndFatalErrorWorkflow, "retryableAndFatalErrorWorkflow"); +async function hookCleanupTestWorkflow(token, customData) { + const hook = createHook({ + token, + metadata: { + customData + } + }); + const payload = await hook; + return { + message: payload.message, + customData: payload.customData, + hookCleanupTestData: "workflow_completed" + }; +} +__name(hookCleanupTestWorkflow, "hookCleanupTestWorkflow"); +async function stepFunctionPassingWorkflow() { + const result = await stepWithStepFunctionArg(doubleNumber); + return result; +} +__name(stepFunctionPassingWorkflow, "stepFunctionPassingWorkflow"); +async function stepWithStepFunctionArg(stepFn) { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//stepWithStepFunctionArg")(stepFn); +} +__name(stepWithStepFunctionArg, "stepWithStepFunctionArg"); +async function doubleNumber(x) { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//doubleNumber")(x); +} +__name(doubleNumber, "doubleNumber"); +addTenWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//addTenWorkflow"; +nestedErrorWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//nestedErrorWorkflow"; +promiseAllWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//promiseAllWorkflow"; +promiseRaceWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//promiseRaceWorkflow"; +promiseAnyWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//promiseAnyWorkflow"; +readableStreamWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//readableStreamWorkflow"; +hookWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//hookWorkflow"; +webhookWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//webhookWorkflow"; +sleepingWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//sleepingWorkflow"; +nullByteWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//nullByteWorkflow"; +workflowAndStepMetadataWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//workflowAndStepMetadataWorkflow"; +outputStreamWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//outputStreamWorkflow"; +outputStreamInsideStepWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//outputStreamInsideStepWorkflow"; +fetchWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//fetchWorkflow"; +promiseRaceStressTestWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//promiseRaceStressTestWorkflow"; +retryAttemptCounterWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//retryAttemptCounterWorkflow"; +crossFileErrorWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//crossFileErrorWorkflow"; +retryableAndFatalErrorWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//retryableAndFatalErrorWorkflow"; +hookCleanupTestWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//hookCleanupTestWorkflow"; +stepFunctionPassingWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//stepFunctionPassingWorkflow"; +Object.defineProperty(add, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/99_e2e.ts//add", + writable: false, + enumerable: false, + configurable: false +}); +Object.defineProperty(randomDelay, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/99_e2e.ts//randomDelay", + writable: false, + enumerable: false, + configurable: false +}); +Object.defineProperty(specificDelay, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/99_e2e.ts//specificDelay", + writable: false, + enumerable: false, + configurable: false +}); +Object.defineProperty(stepThatFails, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/99_e2e.ts//stepThatFails", + writable: false, + enumerable: false, + configurable: false +}); +Object.defineProperty(genReadableStream, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/99_e2e.ts//genReadableStream", + writable: false, + enumerable: false, + configurable: false +}); +Object.defineProperty(sendWebhookResponse, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/99_e2e.ts//sendWebhookResponse", + writable: false, + enumerable: false, + configurable: false +}); +Object.defineProperty(nullByteStep, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/99_e2e.ts//nullByteStep", + writable: false, + enumerable: false, + configurable: false +}); +Object.defineProperty(stepWithMetadata, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/99_e2e.ts//stepWithMetadata", + writable: false, + enumerable: false, + configurable: false +}); +Object.defineProperty(stepWithOutputStreamBinary, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/99_e2e.ts//stepWithOutputStreamBinary", + writable: false, + enumerable: false, + configurable: false +}); +Object.defineProperty(stepWithOutputStreamObject, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/99_e2e.ts//stepWithOutputStreamObject", + writable: false, + enumerable: false, + configurable: false +}); +Object.defineProperty(stepCloseOutputStream, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/99_e2e.ts//stepCloseOutputStream", + writable: false, + enumerable: false, + configurable: false +}); +Object.defineProperty(stepWithOutputStreamInsideStep, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/99_e2e.ts//stepWithOutputStreamInsideStep", + writable: false, + enumerable: false, + configurable: false +}); +Object.defineProperty(stepWithNamedOutputStreamInsideStep, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/99_e2e.ts//stepWithNamedOutputStreamInsideStep", + writable: false, + enumerable: false, + configurable: false +}); +Object.defineProperty(stepCloseOutputStreamInsideStep, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/99_e2e.ts//stepCloseOutputStreamInsideStep", + writable: false, + enumerable: false, + configurable: false +}); +Object.defineProperty(promiseRaceStressTestDelayStep, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/99_e2e.ts//promiseRaceStressTestDelayStep", + writable: false, + enumerable: false, + configurable: false +}); +Object.defineProperty(stepThatRetriesAndSucceeds, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/99_e2e.ts//stepThatRetriesAndSucceeds", + writable: false, + enumerable: false, + configurable: false +}); +Object.defineProperty(stepThatThrowsRetryableError, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/99_e2e.ts//stepThatThrowsRetryableError", + writable: false, + enumerable: false, + configurable: false +}); +Object.defineProperty(stepWithStepFunctionArg, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/99_e2e.ts//stepWithStepFunctionArg", + writable: false, + enumerable: false, + configurable: false +}); +Object.defineProperty(doubleNumber, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/99_e2e.ts//doubleNumber", + writable: false, + enumerable: false, + configurable: false +}); + +// ../example/workflows/2_control_flow.ts +var control_flow_exports = {}; +__export(control_flow_exports, { + control_flow: () => control_flow +}); +async function delayedMessage(ms2, message) { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/2_control_flow.ts//delayedMessage")(ms2, message); +} +__name(delayedMessage, "delayedMessage"); +async function add2(a, b) { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/2_control_flow.ts//add")(a, b); +} +__name(add2, "add"); +async function failingStep() { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/2_control_flow.ts//failingStep")(); +} +__name(failingStep, "failingStep"); +async function retryableStep() { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/2_control_flow.ts//retryableStep")(); +} +__name(retryableStep, "retryableStep"); +async function control_flow() { + console.log("Control flow workflow started"); + const raceResult = await Promise.race([ + delayedMessage(2e3, "I won the race!"), + delayedMessage(1e4, "I lost the race") + ]); + console.log("Race result:", raceResult); + const allResults = await Promise.all([ + delayedMessage(1e3, "First task"), + delayedMessage(2e3, "Second task"), + add2(10, 20) + ]); + console.log("All results:", allResults); + const backgroundPromise = delayedMessage(5e3, "Background task completed"); + const foregroundResults = await Promise.all([ + delayedMessage(1e3, "First task"), + delayedMessage(2e3, "Second task") + ]); + console.log("Foreground response:", foregroundResults); + const backgroundResult = await backgroundPromise; + console.log("Background response:", backgroundResult); + try { + await failingStep(); + } catch (error45) { + console.log("Caught error:", String(error45)); + } + await retryableStep(); + console.log("Control flow workflow completed. See logs for results."); + return { + raceResult, + allResults, + foregroundResults, + backgroundResult + }; +} +__name(control_flow, "control_flow"); +control_flow.workflowId = "workflow//example/workflows/2_control_flow.ts//control_flow"; +Object.defineProperty(delayedMessage, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/2_control_flow.ts//delayedMessage", + writable: false, + enumerable: false, + configurable: false +}); +Object.defineProperty(add2, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/2_control_flow.ts//add", + writable: false, + enumerable: false, + configurable: false +}); +Object.defineProperty(failingStep, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/2_control_flow.ts//failingStep", + writable: false, + enumerable: false, + configurable: false +}); +Object.defineProperty(retryableStep, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/2_control_flow.ts//retryableStep", + writable: false, + enumerable: false, + configurable: false +}); + +// ../nitro-v3/workflows/0_demo.ts +var demo_exports = {}; +__export(demo_exports, { + calc: () => calc +}); +async function calc(n) { + console.log("Simple workflow started"); + n = await pow(n); + console.log("Simple workflow finished"); + return n; +} +__name(calc, "calc"); +async function pow(a) { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//nitro-v3/workflows/0_demo.ts//pow")(a); +} +__name(pow, "pow"); +calc.workflowId = "workflow//nitro-v3/workflows/0_demo.ts//calc"; +Object.defineProperty(pow, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//nitro-v3/workflows/0_demo.ts//pow", + writable: false, + enumerable: false, + configurable: false +}); + +// ../example/workflows/98_duplicate_case.ts +var duplicate_case_exports = {}; +__export(duplicate_case_exports, { + add: () => add3, + addTenWorkflow: () => addTenWorkflow2 +}); +async function addTenWorkflow2(input) { + const a = await add3(input, 2); + const b = await add3(a, 3); + const c = await add3(b, 5); + return c; +} +__name(addTenWorkflow2, "addTenWorkflow"); +async function add3(a, b) { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/98_duplicate_case.ts//add")(a, b); +} +__name(add3, "add"); +addTenWorkflow2.workflowId = "workflow//example/workflows/98_duplicate_case.ts//addTenWorkflow"; +Object.defineProperty(add3, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/98_duplicate_case.ts//add", + writable: false, + enumerable: false, + configurable: false +}); + +// ../example/workflows/6_batching.ts +var batching_exports = {}; +__export(batching_exports, { + batchInStep: () => batchInStep, + batchOverSteps: () => batchOverSteps +}); +var import_lodash = __toESM(require_lodash(), 1); +var ARRAY_LENGTH = 250; +var CHUNK_SIZE = 50; +async function batchOverSteps() { + console.log("Workflow started"); + const arr = Array.from({ + length: ARRAY_LENGTH + }, (_, i) => i + 1); + const chunkSize = CHUNK_SIZE; + console.log(\`Chunking array with size: \${arr.length} and chunk size: \${chunkSize}\`); + const chunks = (0, import_lodash.default)(arr, chunkSize); + console.log(\`Created \${chunks.length} chunks (\${chunks[0].length} items each)\`); + console.log("Starting batch processing"); + for (const [index, batch] of chunks.entries()) { + console.log(\`Batch \${index + 1}/\${chunks.length}\`); + await Promise.all(batch.map(logItem)); + } + console.log("Batch processing completed"); + console.log("Workflow completed"); +} +__name(batchOverSteps, "batchOverSteps"); +async function logItem(item) { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/6_batching.ts//logItem")(item); +} +__name(logItem, "logItem"); +async function batchInStep() { + console.log("Workflow started"); + const arr = Array.from({ + length: ARRAY_LENGTH + }, (_, i) => i + 1); + const chunkSize = CHUNK_SIZE; + console.log(\`Chunking array with size: \${arr.length} and chunk size: \${chunkSize}\`); + const chunks = (0, import_lodash.default)(arr, chunkSize); + console.log(\`Created \${chunks.length} chunks (\${chunks[0].length} items each)\`); + console.log("Starting batch processing"); + for (const [index, batch] of chunks.entries()) { + console.log(\`Batch \${index + 1}/\${chunks.length}\`); + await processItems(batch); + } + console.log("Batch processing completed"); + console.log("Workflow completed"); +} +__name(batchInStep, "batchInStep"); +async function processItems(items) { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/6_batching.ts//processItems")(items); +} +__name(processItems, "processItems"); +batchOverSteps.workflowId = "workflow//example/workflows/6_batching.ts//batchOverSteps"; +batchInStep.workflowId = "workflow//example/workflows/6_batching.ts//batchInStep"; +Object.defineProperty(logItem, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/6_batching.ts//logItem", + writable: false, + enumerable: false, + configurable: false +}); +Object.defineProperty(processItems, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/6_batching.ts//processItems", + writable: false, + enumerable: false, + configurable: false +}); + +// ../example/workflows/1_simple.ts +var simple_exports = {}; +__export(simple_exports, { + simple: () => simple +}); +async function add4(a, b) { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/1_simple.ts//add")(a, b); +} +__name(add4, "add"); +async function simple(i) { + console.log("Simple workflow started"); + const a = await add4(i, 7); + console.log("Workflow step 1 completed - Result:", a); + const b = await add4(a, 8); + console.log("Simple workflow completed. Result:", b); + return b; +} +__name(simple, "simple"); +simple.workflowId = "workflow//example/workflows/1_simple.ts//simple"; +Object.defineProperty(add4, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/1_simple.ts//add", + writable: false, + enumerable: false, + configurable: false +}); + +// ../example/workflows/5_hooks.ts +var hooks_exports = {}; +__export(hooks_exports, { + withCreateHook: () => withCreateHook, + withWorkflowMetadata: () => withWorkflowMetadata +}); +async function stepWithGetMetadata() { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/5_hooks.ts//stepWithGetMetadata")(); +} +__name(stepWithGetMetadata, "stepWithGetMetadata"); +async function withWorkflowMetadata() { + const ctx = getWorkflowMetadata(); + console.log("workflow context", ctx); + await stepWithGetMetadata(); +} +__name(withWorkflowMetadata, "withWorkflowMetadata"); +async function initiateOpenAIResponse() { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/5_hooks.ts//initiateOpenAIResponse")(); +} +__name(initiateOpenAIResponse, "initiateOpenAIResponse"); +async function getOpenAIResponse(respId) { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/5_hooks.ts//getOpenAIResponse")(respId); +} +__name(getOpenAIResponse, "getOpenAIResponse"); +async function withCreateHook() { + const respId = await initiateOpenAIResponse(); + const hook = createHook({ + token: \`openai:\${respId}\` + }); + console.log("Registered hook:", hook.token); + const payload = await hook; + console.log("Received hook payload:", payload); + if (payload.type === "response.completed") { + const text2 = await getOpenAIResponse(payload.data.id); + console.log("OpenAI response text:", text2); + } + console.log("Hook demo workflow completed"); +} +__name(withCreateHook, "withCreateHook"); +withWorkflowMetadata.workflowId = "workflow//example/workflows/5_hooks.ts//withWorkflowMetadata"; +withCreateHook.workflowId = "workflow//example/workflows/5_hooks.ts//withCreateHook"; +Object.defineProperty(stepWithGetMetadata, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/5_hooks.ts//stepWithGetMetadata", + writable: false, + enumerable: false, + configurable: false +}); +Object.defineProperty(initiateOpenAIResponse, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/5_hooks.ts//initiateOpenAIResponse", + writable: false, + enumerable: false, + configurable: false +}); +Object.defineProperty(getOpenAIResponse, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/5_hooks.ts//getOpenAIResponse", + writable: false, + enumerable: false, + configurable: false +}); + +// ../example/workflows/4_ai.ts +var ai_exports = {}; +__export(ai_exports, { + agent: () => agent, + ai: () => ai +}); + +// ../../node_modules/.pnpm/@ai-sdk+provider@2.0.0/node_modules/@ai-sdk/provider/dist/index.mjs +var marker = "vercel.ai.error"; +var symbol = Symbol.for(marker); +var _a; +var _AISDKError = class _AISDKError2 extends Error { + static { + __name(this, "_AISDKError"); + } + /** + * Creates an AI SDK Error. + * + * @param {Object} params - The parameters for creating the error. + * @param {string} params.name - The name of the error. + * @param {string} params.message - The error message. + * @param {unknown} [params.cause] - The underlying cause of the error. + */ + constructor({ name: name143, message, cause }) { + super(message); + this[_a] = true; + this.name = name143; + this.cause = cause; + } + /** + * Checks if the given error is an AI SDK Error. + * @param {unknown} error - The error to check. + * @returns {boolean} True if the error is an AI SDK Error, false otherwise. + */ + static isInstance(error45) { + return _AISDKError2.hasMarker(error45, marker); + } + static hasMarker(error45, marker153) { + const markerSymbol = Symbol.for(marker153); + return error45 != null && typeof error45 === "object" && markerSymbol in error45 && typeof error45[markerSymbol] === "boolean" && error45[markerSymbol] === true; + } +}; +_a = symbol; +var AISDKError = _AISDKError; +var name = "AI_APICallError"; +var marker2 = \`vercel.ai.error.\${name}\`; +var symbol2 = Symbol.for(marker2); +var _a2; +var APICallError = class extends AISDKError { + static { + __name(this, "APICallError"); + } + constructor({ + message, + url: url2, + requestBodyValues, + statusCode, + responseHeaders, + responseBody, + cause, + isRetryable = statusCode != null && (statusCode === 408 || // request timeout + statusCode === 409 || // conflict + statusCode === 429 || // too many requests + statusCode >= 500), + // server error + data + }) { + super({ + name, + message, + cause + }); + this[_a2] = true; + this.url = url2; + this.requestBodyValues = requestBodyValues; + this.statusCode = statusCode; + this.responseHeaders = responseHeaders; + this.responseBody = responseBody; + this.isRetryable = isRetryable; + this.data = data; + } + static isInstance(error45) { + return AISDKError.hasMarker(error45, marker2); + } +}; +_a2 = symbol2; +var name2 = "AI_EmptyResponseBodyError"; +var marker3 = \`vercel.ai.error.\${name2}\`; +var symbol3 = Symbol.for(marker3); +var _a3; +var EmptyResponseBodyError = class extends AISDKError { + static { + __name(this, "EmptyResponseBodyError"); + } + // used in isInstance + constructor({ message = "Empty response body" } = {}) { + super({ + name: name2, + message + }); + this[_a3] = true; + } + static isInstance(error45) { + return AISDKError.hasMarker(error45, marker3); + } +}; +_a3 = symbol3; +function getErrorMessage(error45) { + if (error45 == null) { + return "unknown error"; + } + if (typeof error45 === "string") { + return error45; + } + if (error45 instanceof Error) { + return error45.message; + } + return JSON.stringify(error45); +} +__name(getErrorMessage, "getErrorMessage"); +var name3 = "AI_InvalidArgumentError"; +var marker4 = \`vercel.ai.error.\${name3}\`; +var symbol4 = Symbol.for(marker4); +var _a4; +var InvalidArgumentError = class extends AISDKError { + static { + __name(this, "InvalidArgumentError"); + } + constructor({ message, cause, argument }) { + super({ + name: name3, + message, + cause + }); + this[_a4] = true; + this.argument = argument; + } + static isInstance(error45) { + return AISDKError.hasMarker(error45, marker4); + } +}; +_a4 = symbol4; +var name4 = "AI_InvalidPromptError"; +var marker5 = \`vercel.ai.error.\${name4}\`; +var symbol5 = Symbol.for(marker5); +var _a5; +var InvalidPromptError = class extends AISDKError { + static { + __name(this, "InvalidPromptError"); + } + constructor({ prompt, message, cause }) { + super({ + name: name4, + message: \`Invalid prompt: \${message}\`, + cause + }); + this[_a5] = true; + this.prompt = prompt; + } + static isInstance(error45) { + return AISDKError.hasMarker(error45, marker5); + } +}; +_a5 = symbol5; +var name5 = "AI_InvalidResponseDataError"; +var marker6 = \`vercel.ai.error.\${name5}\`; +var symbol6 = Symbol.for(marker6); +var _a6; +_a6 = symbol6; +var name6 = "AI_JSONParseError"; +var marker7 = \`vercel.ai.error.\${name6}\`; +var symbol7 = Symbol.for(marker7); +var _a7; +var JSONParseError = class extends AISDKError { + static { + __name(this, "JSONParseError"); + } + constructor({ text: text2, cause }) { + super({ + name: name6, + message: \`JSON parsing failed: Text: \${text2}. +Error message: \${getErrorMessage(cause)}\`, + cause + }); + this[_a7] = true; + this.text = text2; + } + static isInstance(error45) { + return AISDKError.hasMarker(error45, marker7); + } +}; +_a7 = symbol7; +var name7 = "AI_LoadAPIKeyError"; +var marker8 = \`vercel.ai.error.\${name7}\`; +var symbol8 = Symbol.for(marker8); +var _a8; +_a8 = symbol8; +var name8 = "AI_LoadSettingError"; +var marker9 = \`vercel.ai.error.\${name8}\`; +var symbol9 = Symbol.for(marker9); +var _a9; +_a9 = symbol9; +var name9 = "AI_NoContentGeneratedError"; +var marker10 = \`vercel.ai.error.\${name9}\`; +var symbol10 = Symbol.for(marker10); +var _a10; +_a10 = symbol10; +var name10 = "AI_NoSuchModelError"; +var marker11 = \`vercel.ai.error.\${name10}\`; +var symbol11 = Symbol.for(marker11); +var _a11; +var NoSuchModelError = class extends AISDKError { + static { + __name(this, "NoSuchModelError"); + } + constructor({ errorName = name10, modelId, modelType, message = \`No such \${modelType}: \${modelId}\` }) { + super({ + name: errorName, + message + }); + this[_a11] = true; + this.modelId = modelId; + this.modelType = modelType; + } + static isInstance(error45) { + return AISDKError.hasMarker(error45, marker11); + } +}; +_a11 = symbol11; +var name11 = "AI_TooManyEmbeddingValuesForCallError"; +var marker12 = \`vercel.ai.error.\${name11}\`; +var symbol12 = Symbol.for(marker12); +var _a12; +_a12 = symbol12; +var name12 = "AI_TypeValidationError"; +var marker13 = \`vercel.ai.error.\${name12}\`; +var symbol13 = Symbol.for(marker13); +var _a13; +var _TypeValidationError = class _TypeValidationError2 extends AISDKError { + static { + __name(this, "_TypeValidationError"); + } + constructor({ value, cause }) { + super({ + name: name12, + message: \`Type validation failed: Value: \${JSON.stringify(value)}. +Error message: \${getErrorMessage(cause)}\`, + cause + }); + this[_a13] = true; + this.value = value; + } + static isInstance(error45) { + return AISDKError.hasMarker(error45, marker13); + } + /** + * Wraps an error into a TypeValidationError. + * If the cause is already a TypeValidationError with the same value, it returns the cause. + * Otherwise, it creates a new TypeValidationError. + * + * @param {Object} params - The parameters for wrapping the error. + * @param {unknown} params.value - The value that failed validation. + * @param {unknown} params.cause - The original error or cause of the validation failure. + * @returns {TypeValidationError} A TypeValidationError instance. + */ + static wrap({ value, cause }) { + return _TypeValidationError2.isInstance(cause) && cause.value === value ? cause : new _TypeValidationError2({ + value, + cause + }); + } +}; +_a13 = symbol13; +var TypeValidationError = _TypeValidationError; +var name13 = "AI_UnsupportedFunctionalityError"; +var marker14 = \`vercel.ai.error.\${name13}\`; +var symbol14 = Symbol.for(marker14); +var _a14; +_a14 = symbol14; + +// ../../node_modules/.pnpm/eventsource-parser@3.0.6/node_modules/eventsource-parser/dist/index.js +var ParseError = class extends Error { + static { + __name(this, "ParseError"); + } + constructor(message, options) { + super(message), this.name = "ParseError", this.type = options.type, this.field = options.field, this.value = options.value, this.line = options.line; + } +}; +function createParser(callbacks) { + if (typeof callbacks == "function") throw new TypeError("\`callbacks\` must be an object, got a function instead. Did you mean \`{onEvent: fn}\`?"); + const { onEvent = noop, onError = noop, onRetry = noop, onComment } = callbacks; + let incompleteLine = "", isFirstChunk = true, id, data = "", eventType = ""; + function feed(newChunk) { + const chunk2 = isFirstChunk ? newChunk.replace(/^\\xEF\\xBB\\xBF/, "") : newChunk, [complete, incomplete] = splitLines(\`\${incompleteLine}\${chunk2}\`); + for (const line of complete) parseLine(line); + incompleteLine = incomplete, isFirstChunk = false; + } + __name(feed, "feed"); + function parseLine(line) { + if (line === "") { + dispatchEvent(); + return; + } + if (line.startsWith(":")) { + onComment && onComment(line.slice(line.startsWith(": ") ? 2 : 1)); + return; + } + const fieldSeparatorIndex = line.indexOf(":"); + if (fieldSeparatorIndex !== -1) { + const field = line.slice(0, fieldSeparatorIndex), offset = line[fieldSeparatorIndex + 1] === " " ? 2 : 1, value = line.slice(fieldSeparatorIndex + offset); + processField(field, value, line); + return; + } + processField(line, "", line); + } + __name(parseLine, "parseLine"); + function processField(field, value, line) { + switch (field) { + case "event": + eventType = value; + break; + case "data": + data = \`\${data}\${value} +\`; + break; + case "id": + id = value.includes("\\0") ? void 0 : value; + break; + case "retry": + /^\\d+\$/.test(value) ? onRetry(parseInt(value, 10)) : onError(new ParseError(\`Invalid \\\`retry\\\` value: "\${value}"\`, { + type: "invalid-retry", + value, + line + })); + break; + default: + onError(new ParseError(\`Unknown field "\${field.length > 20 ? \`\${field.slice(0, 20)}\\u2026\` : field}"\`, { + type: "unknown-field", + field, + value, + line + })); + break; + } + } + __name(processField, "processField"); + function dispatchEvent() { + data.length > 0 && onEvent({ + id, + event: eventType || void 0, + // If the data buffer's last character is a U+000A LINE FEED (LF) character, + // then remove the last character from the data buffer. + data: data.endsWith(\` +\`) ? data.slice(0, -1) : data + }), id = void 0, data = "", eventType = ""; + } + __name(dispatchEvent, "dispatchEvent"); + function reset(options = {}) { + incompleteLine && options.consume && parseLine(incompleteLine), isFirstChunk = true, id = void 0, data = "", eventType = "", incompleteLine = ""; + } + __name(reset, "reset"); + return { + feed, + reset + }; +} +__name(createParser, "createParser"); +function splitLines(chunk2) { + const lines = []; + let incompleteLine = "", searchIndex = 0; + for (; searchIndex < chunk2.length; ) { + const crIndex = chunk2.indexOf("\\r", searchIndex), lfIndex = chunk2.indexOf(\` +\`, searchIndex); + let lineEnd = -1; + if (crIndex !== -1 && lfIndex !== -1 ? lineEnd = Math.min(crIndex, lfIndex) : crIndex !== -1 ? crIndex === chunk2.length - 1 ? lineEnd = -1 : lineEnd = crIndex : lfIndex !== -1 && (lineEnd = lfIndex), lineEnd === -1) { + incompleteLine = chunk2.slice(searchIndex); + break; + } else { + const line = chunk2.slice(searchIndex, lineEnd); + lines.push(line), searchIndex = lineEnd + 1, chunk2[searchIndex - 1] === "\\r" && chunk2[searchIndex] === \` +\` && searchIndex++; + } + } + return [ + lines, + incompleteLine + ]; +} +__name(splitLines, "splitLines"); + +// ../../node_modules/.pnpm/eventsource-parser@3.0.6/node_modules/eventsource-parser/dist/stream.js +var EventSourceParserStream = class extends TransformStream { + static { + __name(this, "EventSourceParserStream"); + } + constructor({ onError, onRetry, onComment } = {}) { + let parser; + super({ + start(controller) { + parser = createParser({ + onEvent: /* @__PURE__ */ __name((event) => { + controller.enqueue(event); + }, "onEvent"), + onError(error45) { + onError === "terminate" ? controller.error(error45) : typeof onError == "function" && onError(error45); + }, + onRetry, + onComment + }); + }, + transform(chunk2) { + parser.feed(chunk2); + } + }); + } +}; + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/classic/external.js +var external_exports = {}; +__export(external_exports, { + \$brand: () => \$brand, + \$input: () => \$input, + \$output: () => \$output, + NEVER: () => NEVER, + TimePrecision: () => TimePrecision, + ZodAny: () => ZodAny, + ZodArray: () => ZodArray, + ZodBase64: () => ZodBase64, + ZodBase64URL: () => ZodBase64URL, + ZodBigInt: () => ZodBigInt, + ZodBigIntFormat: () => ZodBigIntFormat, + ZodBoolean: () => ZodBoolean, + ZodCIDRv4: () => ZodCIDRv4, + ZodCIDRv6: () => ZodCIDRv6, + ZodCUID: () => ZodCUID, + ZodCUID2: () => ZodCUID2, + ZodCatch: () => ZodCatch, + ZodCodec: () => ZodCodec, + ZodCustom: () => ZodCustom, + ZodCustomStringFormat: () => ZodCustomStringFormat, + ZodDate: () => ZodDate, + ZodDefault: () => ZodDefault, + ZodDiscriminatedUnion: () => ZodDiscriminatedUnion, + ZodE164: () => ZodE164, + ZodEmail: () => ZodEmail, + ZodEmoji: () => ZodEmoji, + ZodEnum: () => ZodEnum, + ZodError: () => ZodError, + ZodFile: () => ZodFile, + ZodFirstPartyTypeKind: () => ZodFirstPartyTypeKind, + ZodFunction: () => ZodFunction, + ZodGUID: () => ZodGUID, + ZodIPv4: () => ZodIPv4, + ZodIPv6: () => ZodIPv6, + ZodISODate: () => ZodISODate, + ZodISODateTime: () => ZodISODateTime, + ZodISODuration: () => ZodISODuration, + ZodISOTime: () => ZodISOTime, + ZodIntersection: () => ZodIntersection, + ZodIssueCode: () => ZodIssueCode, + ZodJWT: () => ZodJWT, + ZodKSUID: () => ZodKSUID, + ZodLazy: () => ZodLazy, + ZodLiteral: () => ZodLiteral, + ZodMap: () => ZodMap, + ZodNaN: () => ZodNaN, + ZodNanoID: () => ZodNanoID, + ZodNever: () => ZodNever, + ZodNonOptional: () => ZodNonOptional, + ZodNull: () => ZodNull, + ZodNullable: () => ZodNullable, + ZodNumber: () => ZodNumber, + ZodNumberFormat: () => ZodNumberFormat, + ZodObject: () => ZodObject, + ZodOptional: () => ZodOptional, + ZodPipe: () => ZodPipe, + ZodPrefault: () => ZodPrefault, + ZodPromise: () => ZodPromise, + ZodReadonly: () => ZodReadonly, + ZodRealError: () => ZodRealError, + ZodRecord: () => ZodRecord, + ZodSet: () => ZodSet, + ZodString: () => ZodString, + ZodStringFormat: () => ZodStringFormat, + ZodSuccess: () => ZodSuccess, + ZodSymbol: () => ZodSymbol, + ZodTemplateLiteral: () => ZodTemplateLiteral, + ZodTransform: () => ZodTransform, + ZodTuple: () => ZodTuple, + ZodType: () => ZodType, + ZodULID: () => ZodULID, + ZodURL: () => ZodURL, + ZodUUID: () => ZodUUID, + ZodUndefined: () => ZodUndefined, + ZodUnion: () => ZodUnion, + ZodUnknown: () => ZodUnknown, + ZodVoid: () => ZodVoid, + ZodXID: () => ZodXID, + _ZodString: () => _ZodString, + _default: () => _default2, + _function: () => _function, + any: () => any, + array: () => array, + base64: () => base642, + base64url: () => base64url2, + bigint: () => bigint2, + boolean: () => boolean2, + catch: () => _catch2, + check: () => check, + cidrv4: () => cidrv42, + cidrv6: () => cidrv62, + clone: () => clone, + codec: () => codec, + coerce: () => coerce_exports, + config: () => config, + core: () => core_exports2, + cuid: () => cuid3, + cuid2: () => cuid22, + custom: () => custom, + date: () => date3, + decode: () => decode2, + decodeAsync: () => decodeAsync2, + discriminatedUnion: () => discriminatedUnion, + e164: () => e1642, + email: () => email2, + emoji: () => emoji2, + encode: () => encode2, + encodeAsync: () => encodeAsync2, + endsWith: () => _endsWith, + enum: () => _enum2, + file: () => file, + flattenError: () => flattenError, + float32: () => float32, + float64: () => float64, + formatError: () => formatError, + function: () => _function, + getErrorMap: () => getErrorMap, + globalRegistry: () => globalRegistry, + gt: () => _gt, + gte: () => _gte, + guid: () => guid2, + hash: () => hash, + hex: () => hex2, + hostname: () => hostname2, + httpUrl: () => httpUrl, + includes: () => _includes, + instanceof: () => _instanceof, + int: () => int, + int32: () => int32, + int64: () => int64, + intersection: () => intersection, + ipv4: () => ipv42, + ipv6: () => ipv62, + iso: () => iso_exports, + json: () => json, + jwt: () => jwt, + keyof: () => keyof, + ksuid: () => ksuid2, + lazy: () => lazy, + length: () => _length, + literal: () => literal, + locales: () => locales_exports, + looseObject: () => looseObject, + lowercase: () => _lowercase, + lt: () => _lt, + lte: () => _lte, + map: () => map, + maxLength: () => _maxLength, + maxSize: () => _maxSize, + mime: () => _mime, + minLength: () => _minLength, + minSize: () => _minSize, + multipleOf: () => _multipleOf, + nan: () => nan, + nanoid: () => nanoid2, + nativeEnum: () => nativeEnum, + negative: () => _negative, + never: () => never, + nonnegative: () => _nonnegative, + nonoptional: () => nonoptional, + nonpositive: () => _nonpositive, + normalize: () => _normalize, + null: () => _null3, + nullable: () => nullable, + nullish: () => nullish2, + number: () => number2, + object: () => object, + optional: () => optional, + overwrite: () => _overwrite, + parse: () => parse2, + parseAsync: () => parseAsync2, + partialRecord: () => partialRecord, + pipe: () => pipe, + positive: () => _positive, + prefault: () => prefault, + preprocess: () => preprocess, + prettifyError: () => prettifyError, + promise: () => promise, + property: () => _property, + readonly: () => readonly, + record: () => record, + refine: () => refine, + regex: () => _regex, + regexes: () => regexes_exports, + registry: () => registry, + safeDecode: () => safeDecode2, + safeDecodeAsync: () => safeDecodeAsync2, + safeEncode: () => safeEncode2, + safeEncodeAsync: () => safeEncodeAsync2, + safeParse: () => safeParse2, + safeParseAsync: () => safeParseAsync2, + set: () => set, + setErrorMap: () => setErrorMap, + size: () => _size, + startsWith: () => _startsWith, + strictObject: () => strictObject, + string: () => string2, + stringFormat: () => stringFormat, + stringbool: () => stringbool, + success: () => success, + superRefine: () => superRefine, + symbol: () => symbol15, + templateLiteral: () => templateLiteral, + toJSONSchema: () => toJSONSchema, + toLowerCase: () => _toLowerCase, + toUpperCase: () => _toUpperCase, + transform: () => transform, + treeifyError: () => treeifyError, + trim: () => _trim, + tuple: () => tuple, + uint32: () => uint32, + uint64: () => uint64, + ulid: () => ulid2, + undefined: () => _undefined3, + union: () => union, + unknown: () => unknown, + uppercase: () => _uppercase, + url: () => url, + util: () => util_exports, + uuid: () => uuid2, + uuidv4: () => uuidv4, + uuidv6: () => uuidv6, + uuidv7: () => uuidv7, + void: () => _void2, + xid: () => xid2 +}); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/core/index.js +var core_exports2 = {}; +__export(core_exports2, { + \$ZodAny: () => \$ZodAny, + \$ZodArray: () => \$ZodArray, + \$ZodAsyncError: () => \$ZodAsyncError, + \$ZodBase64: () => \$ZodBase64, + \$ZodBase64URL: () => \$ZodBase64URL, + \$ZodBigInt: () => \$ZodBigInt, + \$ZodBigIntFormat: () => \$ZodBigIntFormat, + \$ZodBoolean: () => \$ZodBoolean, + \$ZodCIDRv4: () => \$ZodCIDRv4, + \$ZodCIDRv6: () => \$ZodCIDRv6, + \$ZodCUID: () => \$ZodCUID, + \$ZodCUID2: () => \$ZodCUID2, + \$ZodCatch: () => \$ZodCatch, + \$ZodCheck: () => \$ZodCheck, + \$ZodCheckBigIntFormat: () => \$ZodCheckBigIntFormat, + \$ZodCheckEndsWith: () => \$ZodCheckEndsWith, + \$ZodCheckGreaterThan: () => \$ZodCheckGreaterThan, + \$ZodCheckIncludes: () => \$ZodCheckIncludes, + \$ZodCheckLengthEquals: () => \$ZodCheckLengthEquals, + \$ZodCheckLessThan: () => \$ZodCheckLessThan, + \$ZodCheckLowerCase: () => \$ZodCheckLowerCase, + \$ZodCheckMaxLength: () => \$ZodCheckMaxLength, + \$ZodCheckMaxSize: () => \$ZodCheckMaxSize, + \$ZodCheckMimeType: () => \$ZodCheckMimeType, + \$ZodCheckMinLength: () => \$ZodCheckMinLength, + \$ZodCheckMinSize: () => \$ZodCheckMinSize, + \$ZodCheckMultipleOf: () => \$ZodCheckMultipleOf, + \$ZodCheckNumberFormat: () => \$ZodCheckNumberFormat, + \$ZodCheckOverwrite: () => \$ZodCheckOverwrite, + \$ZodCheckProperty: () => \$ZodCheckProperty, + \$ZodCheckRegex: () => \$ZodCheckRegex, + \$ZodCheckSizeEquals: () => \$ZodCheckSizeEquals, + \$ZodCheckStartsWith: () => \$ZodCheckStartsWith, + \$ZodCheckStringFormat: () => \$ZodCheckStringFormat, + \$ZodCheckUpperCase: () => \$ZodCheckUpperCase, + \$ZodCodec: () => \$ZodCodec, + \$ZodCustom: () => \$ZodCustom, + \$ZodCustomStringFormat: () => \$ZodCustomStringFormat, + \$ZodDate: () => \$ZodDate, + \$ZodDefault: () => \$ZodDefault, + \$ZodDiscriminatedUnion: () => \$ZodDiscriminatedUnion, + \$ZodE164: () => \$ZodE164, + \$ZodEmail: () => \$ZodEmail, + \$ZodEmoji: () => \$ZodEmoji, + \$ZodEncodeError: () => \$ZodEncodeError, + \$ZodEnum: () => \$ZodEnum, + \$ZodError: () => \$ZodError, + \$ZodFile: () => \$ZodFile, + \$ZodFunction: () => \$ZodFunction, + \$ZodGUID: () => \$ZodGUID, + \$ZodIPv4: () => \$ZodIPv4, + \$ZodIPv6: () => \$ZodIPv6, + \$ZodISODate: () => \$ZodISODate, + \$ZodISODateTime: () => \$ZodISODateTime, + \$ZodISODuration: () => \$ZodISODuration, + \$ZodISOTime: () => \$ZodISOTime, + \$ZodIntersection: () => \$ZodIntersection, + \$ZodJWT: () => \$ZodJWT, + \$ZodKSUID: () => \$ZodKSUID, + \$ZodLazy: () => \$ZodLazy, + \$ZodLiteral: () => \$ZodLiteral, + \$ZodMap: () => \$ZodMap, + \$ZodNaN: () => \$ZodNaN, + \$ZodNanoID: () => \$ZodNanoID, + \$ZodNever: () => \$ZodNever, + \$ZodNonOptional: () => \$ZodNonOptional, + \$ZodNull: () => \$ZodNull, + \$ZodNullable: () => \$ZodNullable, + \$ZodNumber: () => \$ZodNumber, + \$ZodNumberFormat: () => \$ZodNumberFormat, + \$ZodObject: () => \$ZodObject, + \$ZodObjectJIT: () => \$ZodObjectJIT, + \$ZodOptional: () => \$ZodOptional, + \$ZodPipe: () => \$ZodPipe, + \$ZodPrefault: () => \$ZodPrefault, + \$ZodPromise: () => \$ZodPromise, + \$ZodReadonly: () => \$ZodReadonly, + \$ZodRealError: () => \$ZodRealError, + \$ZodRecord: () => \$ZodRecord, + \$ZodRegistry: () => \$ZodRegistry, + \$ZodSet: () => \$ZodSet, + \$ZodString: () => \$ZodString, + \$ZodStringFormat: () => \$ZodStringFormat, + \$ZodSuccess: () => \$ZodSuccess, + \$ZodSymbol: () => \$ZodSymbol, + \$ZodTemplateLiteral: () => \$ZodTemplateLiteral, + \$ZodTransform: () => \$ZodTransform, + \$ZodTuple: () => \$ZodTuple, + \$ZodType: () => \$ZodType, + \$ZodULID: () => \$ZodULID, + \$ZodURL: () => \$ZodURL, + \$ZodUUID: () => \$ZodUUID, + \$ZodUndefined: () => \$ZodUndefined, + \$ZodUnion: () => \$ZodUnion, + \$ZodUnknown: () => \$ZodUnknown, + \$ZodVoid: () => \$ZodVoid, + \$ZodXID: () => \$ZodXID, + \$brand: () => \$brand, + \$constructor: () => \$constructor, + \$input: () => \$input, + \$output: () => \$output, + Doc: () => Doc, + JSONSchema: () => json_schema_exports, + JSONSchemaGenerator: () => JSONSchemaGenerator, + NEVER: () => NEVER, + TimePrecision: () => TimePrecision, + _any: () => _any, + _array: () => _array, + _base64: () => _base64, + _base64url: () => _base64url, + _bigint: () => _bigint, + _boolean: () => _boolean, + _catch: () => _catch, + _check: () => _check, + _cidrv4: () => _cidrv4, + _cidrv6: () => _cidrv6, + _coercedBigint: () => _coercedBigint, + _coercedBoolean: () => _coercedBoolean, + _coercedDate: () => _coercedDate, + _coercedNumber: () => _coercedNumber, + _coercedString: () => _coercedString, + _cuid: () => _cuid, + _cuid2: () => _cuid2, + _custom: () => _custom, + _date: () => _date, + _decode: () => _decode, + _decodeAsync: () => _decodeAsync, + _default: () => _default, + _discriminatedUnion: () => _discriminatedUnion, + _e164: () => _e164, + _email: () => _email, + _emoji: () => _emoji2, + _encode: () => _encode, + _encodeAsync: () => _encodeAsync, + _endsWith: () => _endsWith, + _enum: () => _enum, + _file: () => _file, + _float32: () => _float32, + _float64: () => _float64, + _gt: () => _gt, + _gte: () => _gte, + _guid: () => _guid, + _includes: () => _includes, + _int: () => _int, + _int32: () => _int32, + _int64: () => _int64, + _intersection: () => _intersection, + _ipv4: () => _ipv4, + _ipv6: () => _ipv6, + _isoDate: () => _isoDate, + _isoDateTime: () => _isoDateTime, + _isoDuration: () => _isoDuration, + _isoTime: () => _isoTime, + _jwt: () => _jwt, + _ksuid: () => _ksuid, + _lazy: () => _lazy, + _length: () => _length, + _literal: () => _literal, + _lowercase: () => _lowercase, + _lt: () => _lt, + _lte: () => _lte, + _map: () => _map, + _max: () => _lte, + _maxLength: () => _maxLength, + _maxSize: () => _maxSize, + _mime: () => _mime, + _min: () => _gte, + _minLength: () => _minLength, + _minSize: () => _minSize, + _multipleOf: () => _multipleOf, + _nan: () => _nan, + _nanoid: () => _nanoid, + _nativeEnum: () => _nativeEnum, + _negative: () => _negative, + _never: () => _never, + _nonnegative: () => _nonnegative, + _nonoptional: () => _nonoptional, + _nonpositive: () => _nonpositive, + _normalize: () => _normalize, + _null: () => _null2, + _nullable: () => _nullable, + _number: () => _number, + _optional: () => _optional, + _overwrite: () => _overwrite, + _parse: () => _parse, + _parseAsync: () => _parseAsync, + _pipe: () => _pipe, + _positive: () => _positive, + _promise: () => _promise, + _property: () => _property, + _readonly: () => _readonly, + _record: () => _record, + _refine: () => _refine, + _regex: () => _regex, + _safeDecode: () => _safeDecode, + _safeDecodeAsync: () => _safeDecodeAsync, + _safeEncode: () => _safeEncode, + _safeEncodeAsync: () => _safeEncodeAsync, + _safeParse: () => _safeParse, + _safeParseAsync: () => _safeParseAsync, + _set: () => _set, + _size: () => _size, + _startsWith: () => _startsWith, + _string: () => _string, + _stringFormat: () => _stringFormat, + _stringbool: () => _stringbool, + _success: () => _success, + _superRefine: () => _superRefine, + _symbol: () => _symbol, + _templateLiteral: () => _templateLiteral, + _toLowerCase: () => _toLowerCase, + _toUpperCase: () => _toUpperCase, + _transform: () => _transform, + _trim: () => _trim, + _tuple: () => _tuple, + _uint32: () => _uint32, + _uint64: () => _uint64, + _ulid: () => _ulid, + _undefined: () => _undefined2, + _union: () => _union, + _unknown: () => _unknown, + _uppercase: () => _uppercase, + _url: () => _url, + _uuid: () => _uuid, + _uuidv4: () => _uuidv4, + _uuidv6: () => _uuidv6, + _uuidv7: () => _uuidv7, + _void: () => _void, + _xid: () => _xid, + clone: () => clone, + config: () => config, + decode: () => decode, + decodeAsync: () => decodeAsync, + encode: () => encode, + encodeAsync: () => encodeAsync, + flattenError: () => flattenError, + formatError: () => formatError, + globalConfig: () => globalConfig, + globalRegistry: () => globalRegistry, + isValidBase64: () => isValidBase64, + isValidBase64URL: () => isValidBase64URL, + isValidJWT: () => isValidJWT, + locales: () => locales_exports, + parse: () => parse, + parseAsync: () => parseAsync, + prettifyError: () => prettifyError, + regexes: () => regexes_exports, + registry: () => registry, + safeDecode: () => safeDecode, + safeDecodeAsync: () => safeDecodeAsync, + safeEncode: () => safeEncode, + safeEncodeAsync: () => safeEncodeAsync, + safeParse: () => safeParse, + safeParseAsync: () => safeParseAsync, + toDotPath: () => toDotPath, + toJSONSchema: () => toJSONSchema, + treeifyError: () => treeifyError, + util: () => util_exports, + version: () => version +}); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/core/core.js +var NEVER = Object.freeze({ + status: "aborted" +}); +// @__NO_SIDE_EFFECTS__ +function \$constructor(name17, initializer3, params) { + function init(inst, def) { + var _a17; + Object.defineProperty(inst, "_zod", { + value: inst._zod ?? {}, + enumerable: false + }); + (_a17 = inst._zod).traits ?? (_a17.traits = /* @__PURE__ */ new Set()); + inst._zod.traits.add(name17); + initializer3(inst, def); + for (const k in _.prototype) { + if (!(k in inst)) Object.defineProperty(inst, k, { + value: _.prototype[k].bind(inst) + }); + } + inst._zod.constr = _; + inst._zod.def = def; + } + __name(init, "init"); + const Parent = params?.Parent ?? Object; + class Definition extends Parent { + static { + __name(this, "Definition"); + } + } + Object.defineProperty(Definition, "name", { + value: name17 + }); + function _(def) { + var _a17; + const inst = params?.Parent ? new Definition() : this; + init(inst, def); + (_a17 = inst._zod).deferred ?? (_a17.deferred = []); + for (const fn of inst._zod.deferred) { + fn(); + } + return inst; + } + __name(_, "_"); + Object.defineProperty(_, "init", { + value: init + }); + Object.defineProperty(_, Symbol.hasInstance, { + value: /* @__PURE__ */ __name((inst) => { + if (params?.Parent && inst instanceof params.Parent) return true; + return inst?._zod?.traits?.has(name17); + }, "value") + }); + Object.defineProperty(_, "name", { + value: name17 + }); + return _; +} +__name(\$constructor, "\$constructor"); +var \$brand = Symbol("zod_brand"); +var \$ZodAsyncError = class extends Error { + static { + __name(this, "\$ZodAsyncError"); + } + constructor() { + super(\`Encountered Promise during synchronous parse. Use .parseAsync() instead.\`); + } +}; +var \$ZodEncodeError = class extends Error { + static { + __name(this, "\$ZodEncodeError"); + } + constructor(name17) { + super(\`Encountered unidirectional transform during encode: \${name17}\`); + this.name = "ZodEncodeError"; + } +}; +var globalConfig = {}; +function config(newConfig) { + if (newConfig) Object.assign(globalConfig, newConfig); + return globalConfig; +} +__name(config, "config"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/core/util.js +var util_exports = {}; +__export(util_exports, { + BIGINT_FORMAT_RANGES: () => BIGINT_FORMAT_RANGES, + Class: () => Class, + NUMBER_FORMAT_RANGES: () => NUMBER_FORMAT_RANGES, + aborted: () => aborted, + allowsEval: () => allowsEval, + assert: () => assert, + assertEqual: () => assertEqual, + assertIs: () => assertIs, + assertNever: () => assertNever, + assertNotEqual: () => assertNotEqual, + assignProp: () => assignProp, + base64ToUint8Array: () => base64ToUint8Array, + base64urlToUint8Array: () => base64urlToUint8Array, + cached: () => cached, + captureStackTrace: () => captureStackTrace, + cleanEnum: () => cleanEnum, + cleanRegex: () => cleanRegex, + clone: () => clone, + cloneDef: () => cloneDef, + createTransparentProxy: () => createTransparentProxy, + defineLazy: () => defineLazy, + esc: () => esc, + escapeRegex: () => escapeRegex, + extend: () => extend, + finalizeIssue: () => finalizeIssue, + floatSafeRemainder: () => floatSafeRemainder, + getElementAtPath: () => getElementAtPath, + getEnumValues: () => getEnumValues, + getLengthableOrigin: () => getLengthableOrigin, + getParsedType: () => getParsedType, + getSizableOrigin: () => getSizableOrigin, + hexToUint8Array: () => hexToUint8Array, + isObject: () => isObject, + isPlainObject: () => isPlainObject, + issue: () => issue, + joinValues: () => joinValues, + jsonStringifyReplacer: () => jsonStringifyReplacer, + merge: () => merge, + mergeDefs: () => mergeDefs, + normalizeParams: () => normalizeParams, + nullish: () => nullish, + numKeys: () => numKeys, + objectClone: () => objectClone, + omit: () => omit, + optionalKeys: () => optionalKeys, + partial: () => partial, + pick: () => pick, + prefixIssues: () => prefixIssues, + primitiveTypes: () => primitiveTypes, + promiseAllObject: () => promiseAllObject, + propertyKeyTypes: () => propertyKeyTypes, + randomString: () => randomString, + required: () => required, + safeExtend: () => safeExtend, + shallowClone: () => shallowClone, + stringifyPrimitive: () => stringifyPrimitive, + uint8ArrayToBase64: () => uint8ArrayToBase64, + uint8ArrayToBase64url: () => uint8ArrayToBase64url, + uint8ArrayToHex: () => uint8ArrayToHex, + unwrapMessage: () => unwrapMessage +}); +function assertEqual(val) { + return val; +} +__name(assertEqual, "assertEqual"); +function assertNotEqual(val) { + return val; +} +__name(assertNotEqual, "assertNotEqual"); +function assertIs(_arg) { +} +__name(assertIs, "assertIs"); +function assertNever(_x) { + throw new Error(); +} +__name(assertNever, "assertNever"); +function assert(_) { +} +__name(assert, "assert"); +function getEnumValues(entries) { + const numericValues = Object.values(entries).filter((v) => typeof v === "number"); + const values = Object.entries(entries).filter(([k, _]) => numericValues.indexOf(+k) === -1).map(([_, v]) => v); + return values; +} +__name(getEnumValues, "getEnumValues"); +function joinValues(array2, separator = "|") { + return array2.map((val) => stringifyPrimitive(val)).join(separator); +} +__name(joinValues, "joinValues"); +function jsonStringifyReplacer(_, value) { + if (typeof value === "bigint") return value.toString(); + return value; +} +__name(jsonStringifyReplacer, "jsonStringifyReplacer"); +function cached(getter) { + const set2 = false; + return { + get value() { + if (!set2) { + const value = getter(); + Object.defineProperty(this, "value", { + value + }); + return value; + } + throw new Error("cached value already set"); + } + }; +} +__name(cached, "cached"); +function nullish(input) { + return input === null || input === void 0; +} +__name(nullish, "nullish"); +function cleanRegex(source) { + const start = source.startsWith("^") ? 1 : 0; + const end = source.endsWith("\$") ? source.length - 1 : source.length; + return source.slice(start, end); +} +__name(cleanRegex, "cleanRegex"); +function floatSafeRemainder(val, step) { + const valDecCount = (val.toString().split(".")[1] || "").length; + const stepString = step.toString(); + let stepDecCount = (stepString.split(".")[1] || "").length; + if (stepDecCount === 0 && /\\d?e-\\d?/.test(stepString)) { + const match = stepString.match(/\\d?e-(\\d?)/); + if (match?.[1]) { + stepDecCount = Number.parseInt(match[1]); + } + } + const decCount = valDecCount > stepDecCount ? valDecCount : stepDecCount; + const valInt = Number.parseInt(val.toFixed(decCount).replace(".", "")); + const stepInt = Number.parseInt(step.toFixed(decCount).replace(".", "")); + return valInt % stepInt / 10 ** decCount; +} +__name(floatSafeRemainder, "floatSafeRemainder"); +var EVALUATING = Symbol("evaluating"); +function defineLazy(object3, key, getter) { + let value = void 0; + Object.defineProperty(object3, key, { + get() { + if (value === EVALUATING) { + return void 0; + } + if (value === void 0) { + value = EVALUATING; + value = getter(); + } + return value; + }, + set(v) { + Object.defineProperty(object3, key, { + value: v + }); + }, + configurable: true + }); +} +__name(defineLazy, "defineLazy"); +function objectClone(obj) { + return Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj)); +} +__name(objectClone, "objectClone"); +function assignProp(target, prop, value) { + Object.defineProperty(target, prop, { + value, + writable: true, + enumerable: true, + configurable: true + }); +} +__name(assignProp, "assignProp"); +function mergeDefs(...defs) { + const mergedDescriptors = {}; + for (const def of defs) { + const descriptors = Object.getOwnPropertyDescriptors(def); + Object.assign(mergedDescriptors, descriptors); + } + return Object.defineProperties({}, mergedDescriptors); +} +__name(mergeDefs, "mergeDefs"); +function cloneDef(schema) { + return mergeDefs(schema._zod.def); +} +__name(cloneDef, "cloneDef"); +function getElementAtPath(obj, path) { + if (!path) return obj; + return path.reduce((acc, key) => acc?.[key], obj); +} +__name(getElementAtPath, "getElementAtPath"); +function promiseAllObject(promisesObj) { + const keys = Object.keys(promisesObj); + const promises = keys.map((key) => promisesObj[key]); + return Promise.all(promises).then((results) => { + const resolvedObj = {}; + for (let i = 0; i < keys.length; i++) { + resolvedObj[keys[i]] = results[i]; + } + return resolvedObj; + }); +} +__name(promiseAllObject, "promiseAllObject"); +function randomString(length = 10) { + const chars = "abcdefghijklmnopqrstuvwxyz"; + let str = ""; + for (let i = 0; i < length; i++) { + str += chars[Math.floor(Math.random() * chars.length)]; + } + return str; +} +__name(randomString, "randomString"); +function esc(str) { + return JSON.stringify(str); +} +__name(esc, "esc"); +var captureStackTrace = "captureStackTrace" in Error ? Error.captureStackTrace : (..._args) => { +}; +function isObject(data) { + return typeof data === "object" && data !== null && !Array.isArray(data); +} +__name(isObject, "isObject"); +var allowsEval = cached(() => { + if (typeof navigator !== "undefined" && navigator?.userAgent?.includes("Cloudflare")) { + return false; + } + try { + const F = Function; + new F(""); + return true; + } catch (_) { + return false; + } +}); +function isPlainObject(o) { + if (isObject(o) === false) return false; + const ctor = o.constructor; + if (ctor === void 0) return true; + const prot = ctor.prototype; + if (isObject(prot) === false) return false; + if (Object.prototype.hasOwnProperty.call(prot, "isPrototypeOf") === false) { + return false; + } + return true; +} +__name(isPlainObject, "isPlainObject"); +function shallowClone(o) { + if (isPlainObject(o)) return { + ...o + }; + if (Array.isArray(o)) return [ + ...o + ]; + return o; +} +__name(shallowClone, "shallowClone"); +function numKeys(data) { + let keyCount = 0; + for (const key in data) { + if (Object.prototype.hasOwnProperty.call(data, key)) { + keyCount++; + } + } + return keyCount; +} +__name(numKeys, "numKeys"); +var getParsedType = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "undefined": + return "undefined"; + case "string": + return "string"; + case "number": + return Number.isNaN(data) ? "nan" : "number"; + case "boolean": + return "boolean"; + case "function": + return "function"; + case "bigint": + return "bigint"; + case "symbol": + return "symbol"; + case "object": + if (Array.isArray(data)) { + return "array"; + } + if (data === null) { + return "null"; + } + if (data.then && typeof data.then === "function" && data.catch && typeof data.catch === "function") { + return "promise"; + } + if (typeof Map !== "undefined" && data instanceof Map) { + return "map"; + } + if (typeof Set !== "undefined" && data instanceof Set) { + return "set"; + } + if (typeof Date !== "undefined" && data instanceof Date) { + return "date"; + } + if (typeof File !== "undefined" && data instanceof File) { + return "file"; + } + return "object"; + default: + throw new Error(\`Unknown data type: \${t}\`); + } +}, "getParsedType"); +var propertyKeyTypes = /* @__PURE__ */ new Set([ + "string", + "number", + "symbol" +]); +var primitiveTypes = /* @__PURE__ */ new Set([ + "string", + "number", + "bigint", + "boolean", + "symbol", + "undefined" +]); +function escapeRegex(str) { + return str.replace(/[.*+?^\${}()|[\\]\\\\]/g, "\\\\\$&"); +} +__name(escapeRegex, "escapeRegex"); +function clone(inst, def, params) { + const cl = new inst._zod.constr(def ?? inst._zod.def); + if (!def || params?.parent) cl._zod.parent = inst; + return cl; +} +__name(clone, "clone"); +function normalizeParams(_params) { + const params = _params; + if (!params) return {}; + if (typeof params === "string") return { + error: /* @__PURE__ */ __name(() => params, "error") + }; + if (params?.message !== void 0) { + if (params?.error !== void 0) throw new Error("Cannot specify both \`message\` and \`error\` params"); + params.error = params.message; + } + delete params.message; + if (typeof params.error === "string") return { + ...params, + error: /* @__PURE__ */ __name(() => params.error, "error") + }; + return params; +} +__name(normalizeParams, "normalizeParams"); +function createTransparentProxy(getter) { + let target; + return new Proxy({}, { + get(_, prop, receiver) { + target ?? (target = getter()); + return Reflect.get(target, prop, receiver); + }, + set(_, prop, value, receiver) { + target ?? (target = getter()); + return Reflect.set(target, prop, value, receiver); + }, + has(_, prop) { + target ?? (target = getter()); + return Reflect.has(target, prop); + }, + deleteProperty(_, prop) { + target ?? (target = getter()); + return Reflect.deleteProperty(target, prop); + }, + ownKeys(_) { + target ?? (target = getter()); + return Reflect.ownKeys(target); + }, + getOwnPropertyDescriptor(_, prop) { + target ?? (target = getter()); + return Reflect.getOwnPropertyDescriptor(target, prop); + }, + defineProperty(_, prop, descriptor) { + target ?? (target = getter()); + return Reflect.defineProperty(target, prop, descriptor); + } + }); +} +__name(createTransparentProxy, "createTransparentProxy"); +function stringifyPrimitive(value) { + if (typeof value === "bigint") return value.toString() + "n"; + if (typeof value === "string") return \`"\${value}"\`; + return \`\${value}\`; +} +__name(stringifyPrimitive, "stringifyPrimitive"); +function optionalKeys(shape) { + return Object.keys(shape).filter((k) => { + return shape[k]._zod.optin === "optional" && shape[k]._zod.optout === "optional"; + }); +} +__name(optionalKeys, "optionalKeys"); +var NUMBER_FORMAT_RANGES = { + safeint: [ + Number.MIN_SAFE_INTEGER, + Number.MAX_SAFE_INTEGER + ], + int32: [ + -2147483648, + 2147483647 + ], + uint32: [ + 0, + 4294967295 + ], + float32: [ + -34028234663852886e22, + 34028234663852886e22 + ], + float64: [ + -Number.MAX_VALUE, + Number.MAX_VALUE + ] +}; +var BIGINT_FORMAT_RANGES = { + int64: [ + /* @__PURE__ */ BigInt("-9223372036854775808"), + /* @__PURE__ */ BigInt("9223372036854775807") + ], + uint64: [ + /* @__PURE__ */ BigInt(0), + /* @__PURE__ */ BigInt("18446744073709551615") + ] +}; +function pick(schema, mask) { + const currDef = schema._zod.def; + const def = mergeDefs(schema._zod.def, { + get shape() { + const newShape = {}; + for (const key in mask) { + if (!(key in currDef.shape)) { + throw new Error(\`Unrecognized key: "\${key}"\`); + } + if (!mask[key]) continue; + newShape[key] = currDef.shape[key]; + } + assignProp(this, "shape", newShape); + return newShape; + }, + checks: [] + }); + return clone(schema, def); +} +__name(pick, "pick"); +function omit(schema, mask) { + const currDef = schema._zod.def; + const def = mergeDefs(schema._zod.def, { + get shape() { + const newShape = { + ...schema._zod.def.shape + }; + for (const key in mask) { + if (!(key in currDef.shape)) { + throw new Error(\`Unrecognized key: "\${key}"\`); + } + if (!mask[key]) continue; + delete newShape[key]; + } + assignProp(this, "shape", newShape); + return newShape; + }, + checks: [] + }); + return clone(schema, def); +} +__name(omit, "omit"); +function extend(schema, shape) { + if (!isPlainObject(shape)) { + throw new Error("Invalid input to extend: expected a plain object"); + } + const checks = schema._zod.def.checks; + const hasChecks = checks && checks.length > 0; + if (hasChecks) { + throw new Error("Object schemas containing refinements cannot be extended. Use \`.safeExtend()\` instead."); + } + const def = mergeDefs(schema._zod.def, { + get shape() { + const _shape = { + ...schema._zod.def.shape, + ...shape + }; + assignProp(this, "shape", _shape); + return _shape; + }, + checks: [] + }); + return clone(schema, def); +} +__name(extend, "extend"); +function safeExtend(schema, shape) { + if (!isPlainObject(shape)) { + throw new Error("Invalid input to safeExtend: expected a plain object"); + } + const def = { + ...schema._zod.def, + get shape() { + const _shape = { + ...schema._zod.def.shape, + ...shape + }; + assignProp(this, "shape", _shape); + return _shape; + }, + checks: schema._zod.def.checks + }; + return clone(schema, def); +} +__name(safeExtend, "safeExtend"); +function merge(a, b) { + const def = mergeDefs(a._zod.def, { + get shape() { + const _shape = { + ...a._zod.def.shape, + ...b._zod.def.shape + }; + assignProp(this, "shape", _shape); + return _shape; + }, + get catchall() { + return b._zod.def.catchall; + }, + checks: [] + }); + return clone(a, def); +} +__name(merge, "merge"); +function partial(Class2, schema, mask) { + const def = mergeDefs(schema._zod.def, { + get shape() { + const oldShape = schema._zod.def.shape; + const shape = { + ...oldShape + }; + if (mask) { + for (const key in mask) { + if (!(key in oldShape)) { + throw new Error(\`Unrecognized key: "\${key}"\`); + } + if (!mask[key]) continue; + shape[key] = Class2 ? new Class2({ + type: "optional", + innerType: oldShape[key] + }) : oldShape[key]; + } + } else { + for (const key in oldShape) { + shape[key] = Class2 ? new Class2({ + type: "optional", + innerType: oldShape[key] + }) : oldShape[key]; + } + } + assignProp(this, "shape", shape); + return shape; + }, + checks: [] + }); + return clone(schema, def); +} +__name(partial, "partial"); +function required(Class2, schema, mask) { + const def = mergeDefs(schema._zod.def, { + get shape() { + const oldShape = schema._zod.def.shape; + const shape = { + ...oldShape + }; + if (mask) { + for (const key in mask) { + if (!(key in shape)) { + throw new Error(\`Unrecognized key: "\${key}"\`); + } + if (!mask[key]) continue; + shape[key] = new Class2({ + type: "nonoptional", + innerType: oldShape[key] + }); + } + } else { + for (const key in oldShape) { + shape[key] = new Class2({ + type: "nonoptional", + innerType: oldShape[key] + }); + } + } + assignProp(this, "shape", shape); + return shape; + }, + checks: [] + }); + return clone(schema, def); +} +__name(required, "required"); +function aborted(x, startIndex = 0) { + if (x.aborted === true) return true; + for (let i = startIndex; i < x.issues.length; i++) { + if (x.issues[i]?.continue !== true) { + return true; + } + } + return false; +} +__name(aborted, "aborted"); +function prefixIssues(path, issues) { + return issues.map((iss) => { + var _a17; + (_a17 = iss).path ?? (_a17.path = []); + iss.path.unshift(path); + return iss; + }); +} +__name(prefixIssues, "prefixIssues"); +function unwrapMessage(message) { + return typeof message === "string" ? message : message?.message; +} +__name(unwrapMessage, "unwrapMessage"); +function finalizeIssue(iss, ctx, config2) { + const full = { + ...iss, + path: iss.path ?? [] + }; + if (!iss.message) { + const message = unwrapMessage(iss.inst?._zod.def?.error?.(iss)) ?? unwrapMessage(ctx?.error?.(iss)) ?? unwrapMessage(config2.customError?.(iss)) ?? unwrapMessage(config2.localeError?.(iss)) ?? "Invalid input"; + full.message = message; + } + delete full.inst; + delete full.continue; + if (!ctx?.reportInput) { + delete full.input; + } + return full; +} +__name(finalizeIssue, "finalizeIssue"); +function getSizableOrigin(input) { + if (input instanceof Set) return "set"; + if (input instanceof Map) return "map"; + if (input instanceof File) return "file"; + return "unknown"; +} +__name(getSizableOrigin, "getSizableOrigin"); +function getLengthableOrigin(input) { + if (Array.isArray(input)) return "array"; + if (typeof input === "string") return "string"; + return "unknown"; +} +__name(getLengthableOrigin, "getLengthableOrigin"); +function issue(...args) { + const [iss, input, inst] = args; + if (typeof iss === "string") { + return { + message: iss, + code: "custom", + input, + inst + }; + } + return { + ...iss + }; +} +__name(issue, "issue"); +function cleanEnum(obj) { + return Object.entries(obj).filter(([k, _]) => { + return Number.isNaN(Number.parseInt(k, 10)); + }).map((el) => el[1]); +} +__name(cleanEnum, "cleanEnum"); +function base64ToUint8Array(base643) { + const binaryString = atob(base643); + const bytes = new Uint8Array(binaryString.length); + for (let i = 0; i < binaryString.length; i++) { + bytes[i] = binaryString.charCodeAt(i); + } + return bytes; +} +__name(base64ToUint8Array, "base64ToUint8Array"); +function uint8ArrayToBase64(bytes) { + let binaryString = ""; + for (let i = 0; i < bytes.length; i++) { + binaryString += String.fromCharCode(bytes[i]); + } + return btoa(binaryString); +} +__name(uint8ArrayToBase64, "uint8ArrayToBase64"); +function base64urlToUint8Array(base64url3) { + const base643 = base64url3.replace(/-/g, "+").replace(/_/g, "/"); + const padding = "=".repeat((4 - base643.length % 4) % 4); + return base64ToUint8Array(base643 + padding); +} +__name(base64urlToUint8Array, "base64urlToUint8Array"); +function uint8ArrayToBase64url(bytes) { + return uint8ArrayToBase64(bytes).replace(/\\+/g, "-").replace(/\\//g, "_").replace(/=/g, ""); +} +__name(uint8ArrayToBase64url, "uint8ArrayToBase64url"); +function hexToUint8Array(hex3) { + const cleanHex = hex3.replace(/^0x/, ""); + if (cleanHex.length % 2 !== 0) { + throw new Error("Invalid hex string length"); + } + const bytes = new Uint8Array(cleanHex.length / 2); + for (let i = 0; i < cleanHex.length; i += 2) { + bytes[i / 2] = Number.parseInt(cleanHex.slice(i, i + 2), 16); + } + return bytes; +} +__name(hexToUint8Array, "hexToUint8Array"); +function uint8ArrayToHex(bytes) { + return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join(""); +} +__name(uint8ArrayToHex, "uint8ArrayToHex"); +var Class = class { + static { + __name(this, "Class"); + } + constructor(..._args) { + } +}; + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/core/errors.js +var initializer = /* @__PURE__ */ __name((inst, def) => { + inst.name = "\$ZodError"; + Object.defineProperty(inst, "_zod", { + value: inst._zod, + enumerable: false + }); + Object.defineProperty(inst, "issues", { + value: def, + enumerable: false + }); + inst.message = JSON.stringify(def, jsonStringifyReplacer, 2); + Object.defineProperty(inst, "toString", { + value: /* @__PURE__ */ __name(() => inst.message, "value"), + enumerable: false + }); +}, "initializer"); +var \$ZodError = \$constructor("\$ZodError", initializer); +var \$ZodRealError = \$constructor("\$ZodError", initializer, { + Parent: Error +}); +function flattenError(error45, mapper = (issue2) => issue2.message) { + const fieldErrors = {}; + const formErrors = []; + for (const sub of error45.issues) { + if (sub.path.length > 0) { + fieldErrors[sub.path[0]] = fieldErrors[sub.path[0]] || []; + fieldErrors[sub.path[0]].push(mapper(sub)); + } else { + formErrors.push(mapper(sub)); + } + } + return { + formErrors, + fieldErrors + }; +} +__name(flattenError, "flattenError"); +function formatError(error45, _mapper) { + const mapper = _mapper || function(issue2) { + return issue2.message; + }; + const fieldErrors = { + _errors: [] + }; + const processError = /* @__PURE__ */ __name((error46) => { + for (const issue2 of error46.issues) { + if (issue2.code === "invalid_union" && issue2.errors.length) { + issue2.errors.map((issues) => processError({ + issues + })); + } else if (issue2.code === "invalid_key") { + processError({ + issues: issue2.issues + }); + } else if (issue2.code === "invalid_element") { + processError({ + issues: issue2.issues + }); + } else if (issue2.path.length === 0) { + fieldErrors._errors.push(mapper(issue2)); + } else { + let curr = fieldErrors; + let i = 0; + while (i < issue2.path.length) { + const el = issue2.path[i]; + const terminal = i === issue2.path.length - 1; + if (!terminal) { + curr[el] = curr[el] || { + _errors: [] + }; + } else { + curr[el] = curr[el] || { + _errors: [] + }; + curr[el]._errors.push(mapper(issue2)); + } + curr = curr[el]; + i++; + } + } + } + }, "processError"); + processError(error45); + return fieldErrors; +} +__name(formatError, "formatError"); +function treeifyError(error45, _mapper) { + const mapper = _mapper || function(issue2) { + return issue2.message; + }; + const result = { + errors: [] + }; + const processError = /* @__PURE__ */ __name((error46, path = []) => { + var _a17, _b8; + for (const issue2 of error46.issues) { + if (issue2.code === "invalid_union" && issue2.errors.length) { + issue2.errors.map((issues) => processError({ + issues + }, issue2.path)); + } else if (issue2.code === "invalid_key") { + processError({ + issues: issue2.issues + }, issue2.path); + } else if (issue2.code === "invalid_element") { + processError({ + issues: issue2.issues + }, issue2.path); + } else { + const fullpath = [ + ...path, + ...issue2.path + ]; + if (fullpath.length === 0) { + result.errors.push(mapper(issue2)); + continue; + } + let curr = result; + let i = 0; + while (i < fullpath.length) { + const el = fullpath[i]; + const terminal = i === fullpath.length - 1; + if (typeof el === "string") { + curr.properties ?? (curr.properties = {}); + (_a17 = curr.properties)[el] ?? (_a17[el] = { + errors: [] + }); + curr = curr.properties[el]; + } else { + curr.items ?? (curr.items = []); + (_b8 = curr.items)[el] ?? (_b8[el] = { + errors: [] + }); + curr = curr.items[el]; + } + if (terminal) { + curr.errors.push(mapper(issue2)); + } + i++; + } + } + } + }, "processError"); + processError(error45); + return result; +} +__name(treeifyError, "treeifyError"); +function toDotPath(_path) { + const segs = []; + const path = _path.map((seg) => typeof seg === "object" ? seg.key : seg); + for (const seg of path) { + if (typeof seg === "number") segs.push(\`[\${seg}]\`); + else if (typeof seg === "symbol") segs.push(\`[\${JSON.stringify(String(seg))}]\`); + else if (/[^\\w\$]/.test(seg)) segs.push(\`[\${JSON.stringify(seg)}]\`); + else { + if (segs.length) segs.push("."); + segs.push(seg); + } + } + return segs.join(""); +} +__name(toDotPath, "toDotPath"); +function prettifyError(error45) { + const lines = []; + const issues = [ + ...error45.issues + ].sort((a, b) => (a.path ?? []).length - (b.path ?? []).length); + for (const issue2 of issues) { + lines.push(\`\\u2716 \${issue2.message}\`); + if (issue2.path?.length) lines.push(\` \\u2192 at \${toDotPath(issue2.path)}\`); + } + return lines.join("\\n"); +} +__name(prettifyError, "prettifyError"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/core/parse.js +var _parse = /* @__PURE__ */ __name((_Err) => (schema, value, _ctx, _params) => { + const ctx = _ctx ? Object.assign(_ctx, { + async: false + }) : { + async: false + }; + const result = schema._zod.run({ + value, + issues: [] + }, ctx); + if (result instanceof Promise) { + throw new \$ZodAsyncError(); + } + if (result.issues.length) { + const e = new (_params?.Err ?? _Err)(result.issues.map((iss) => finalizeIssue(iss, ctx, config()))); + captureStackTrace(e, _params?.callee); + throw e; + } + return result.value; +}, "_parse"); +var parse = /* @__PURE__ */ _parse(\$ZodRealError); +var _parseAsync = /* @__PURE__ */ __name((_Err) => async (schema, value, _ctx, params) => { + const ctx = _ctx ? Object.assign(_ctx, { + async: true + }) : { + async: true + }; + let result = schema._zod.run({ + value, + issues: [] + }, ctx); + if (result instanceof Promise) result = await result; + if (result.issues.length) { + const e = new (params?.Err ?? _Err)(result.issues.map((iss) => finalizeIssue(iss, ctx, config()))); + captureStackTrace(e, params?.callee); + throw e; + } + return result.value; +}, "_parseAsync"); +var parseAsync = /* @__PURE__ */ _parseAsync(\$ZodRealError); +var _safeParse = /* @__PURE__ */ __name((_Err) => (schema, value, _ctx) => { + const ctx = _ctx ? { + ..._ctx, + async: false + } : { + async: false + }; + const result = schema._zod.run({ + value, + issues: [] + }, ctx); + if (result instanceof Promise) { + throw new \$ZodAsyncError(); + } + return result.issues.length ? { + success: false, + error: new (_Err ?? \$ZodError)(result.issues.map((iss) => finalizeIssue(iss, ctx, config()))) + } : { + success: true, + data: result.value + }; +}, "_safeParse"); +var safeParse = /* @__PURE__ */ _safeParse(\$ZodRealError); +var _safeParseAsync = /* @__PURE__ */ __name((_Err) => async (schema, value, _ctx) => { + const ctx = _ctx ? Object.assign(_ctx, { + async: true + }) : { + async: true + }; + let result = schema._zod.run({ + value, + issues: [] + }, ctx); + if (result instanceof Promise) result = await result; + return result.issues.length ? { + success: false, + error: new _Err(result.issues.map((iss) => finalizeIssue(iss, ctx, config()))) + } : { + success: true, + data: result.value + }; +}, "_safeParseAsync"); +var safeParseAsync = /* @__PURE__ */ _safeParseAsync(\$ZodRealError); +var _encode = /* @__PURE__ */ __name((_Err) => (schema, value, _ctx) => { + const ctx = _ctx ? Object.assign(_ctx, { + direction: "backward" + }) : { + direction: "backward" + }; + return _parse(_Err)(schema, value, ctx); +}, "_encode"); +var encode = /* @__PURE__ */ _encode(\$ZodRealError); +var _decode = /* @__PURE__ */ __name((_Err) => (schema, value, _ctx) => { + return _parse(_Err)(schema, value, _ctx); +}, "_decode"); +var decode = /* @__PURE__ */ _decode(\$ZodRealError); +var _encodeAsync = /* @__PURE__ */ __name((_Err) => async (schema, value, _ctx) => { + const ctx = _ctx ? Object.assign(_ctx, { + direction: "backward" + }) : { + direction: "backward" + }; + return _parseAsync(_Err)(schema, value, ctx); +}, "_encodeAsync"); +var encodeAsync = /* @__PURE__ */ _encodeAsync(\$ZodRealError); +var _decodeAsync = /* @__PURE__ */ __name((_Err) => async (schema, value, _ctx) => { + return _parseAsync(_Err)(schema, value, _ctx); +}, "_decodeAsync"); +var decodeAsync = /* @__PURE__ */ _decodeAsync(\$ZodRealError); +var _safeEncode = /* @__PURE__ */ __name((_Err) => (schema, value, _ctx) => { + const ctx = _ctx ? Object.assign(_ctx, { + direction: "backward" + }) : { + direction: "backward" + }; + return _safeParse(_Err)(schema, value, ctx); +}, "_safeEncode"); +var safeEncode = /* @__PURE__ */ _safeEncode(\$ZodRealError); +var _safeDecode = /* @__PURE__ */ __name((_Err) => (schema, value, _ctx) => { + return _safeParse(_Err)(schema, value, _ctx); +}, "_safeDecode"); +var safeDecode = /* @__PURE__ */ _safeDecode(\$ZodRealError); +var _safeEncodeAsync = /* @__PURE__ */ __name((_Err) => async (schema, value, _ctx) => { + const ctx = _ctx ? Object.assign(_ctx, { + direction: "backward" + }) : { + direction: "backward" + }; + return _safeParseAsync(_Err)(schema, value, ctx); +}, "_safeEncodeAsync"); +var safeEncodeAsync = /* @__PURE__ */ _safeEncodeAsync(\$ZodRealError); +var _safeDecodeAsync = /* @__PURE__ */ __name((_Err) => async (schema, value, _ctx) => { + return _safeParseAsync(_Err)(schema, value, _ctx); +}, "_safeDecodeAsync"); +var safeDecodeAsync = /* @__PURE__ */ _safeDecodeAsync(\$ZodRealError); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/core/regexes.js +var regexes_exports = {}; +__export(regexes_exports, { + base64: () => base64, + base64url: () => base64url, + bigint: () => bigint, + boolean: () => boolean, + browserEmail: () => browserEmail, + cidrv4: () => cidrv4, + cidrv6: () => cidrv6, + cuid: () => cuid, + cuid2: () => cuid2, + date: () => date, + datetime: () => datetime, + domain: () => domain, + duration: () => duration, + e164: () => e164, + email: () => email, + emoji: () => emoji, + extendedDuration: () => extendedDuration, + guid: () => guid, + hex: () => hex, + hostname: () => hostname, + html5Email: () => html5Email, + idnEmail: () => idnEmail, + integer: () => integer, + ipv4: () => ipv4, + ipv6: () => ipv6, + ksuid: () => ksuid, + lowercase: () => lowercase, + md5_base64: () => md5_base64, + md5_base64url: () => md5_base64url, + md5_hex: () => md5_hex, + nanoid: () => nanoid, + null: () => _null, + number: () => number, + rfc5322Email: () => rfc5322Email, + sha1_base64: () => sha1_base64, + sha1_base64url: () => sha1_base64url, + sha1_hex: () => sha1_hex, + sha256_base64: () => sha256_base64, + sha256_base64url: () => sha256_base64url, + sha256_hex: () => sha256_hex, + sha384_base64: () => sha384_base64, + sha384_base64url: () => sha384_base64url, + sha384_hex: () => sha384_hex, + sha512_base64: () => sha512_base64, + sha512_base64url: () => sha512_base64url, + sha512_hex: () => sha512_hex, + string: () => string, + time: () => time, + ulid: () => ulid, + undefined: () => _undefined, + unicodeEmail: () => unicodeEmail, + uppercase: () => uppercase, + uuid: () => uuid, + uuid4: () => uuid4, + uuid6: () => uuid6, + uuid7: () => uuid7, + xid: () => xid +}); +var cuid = /^[cC][^\\s-]{8,}\$/; +var cuid2 = /^[0-9a-z]+\$/; +var ulid = /^[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}\$/; +var xid = /^[0-9a-vA-V]{20}\$/; +var ksuid = /^[A-Za-z0-9]{27}\$/; +var nanoid = /^[a-zA-Z0-9_-]{21}\$/; +var duration = /^P(?:(\\d+W)|(?!.*W)(?=\\d|T\\d)(\\d+Y)?(\\d+M)?(\\d+D)?(T(?=\\d)(\\d+H)?(\\d+M)?(\\d+([.,]\\d+)?S)?)?)\$/; +var extendedDuration = /^[-+]?P(?!\$)(?:(?:[-+]?\\d+Y)|(?:[-+]?\\d+[.,]\\d+Y\$))?(?:(?:[-+]?\\d+M)|(?:[-+]?\\d+[.,]\\d+M\$))?(?:(?:[-+]?\\d+W)|(?:[-+]?\\d+[.,]\\d+W\$))?(?:(?:[-+]?\\d+D)|(?:[-+]?\\d+[.,]\\d+D\$))?(?:T(?=[\\d+-])(?:(?:[-+]?\\d+H)|(?:[-+]?\\d+[.,]\\d+H\$))?(?:(?:[-+]?\\d+M)|(?:[-+]?\\d+[.,]\\d+M\$))?(?:[-+]?\\d+(?:[.,]\\d+)?S)?)??\$/; +var guid = /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})\$/; +var uuid = /* @__PURE__ */ __name((version2) => { + if (!version2) return /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)\$/; + return new RegExp(\`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-\${version2}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})\$\`); +}, "uuid"); +var uuid4 = /* @__PURE__ */ uuid(4); +var uuid6 = /* @__PURE__ */ uuid(6); +var uuid7 = /* @__PURE__ */ uuid(7); +var email = /^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}\$/; +var html5Email = /^[a-zA-Z0-9.!#\$%&'*+/=?^_\`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\$/; +var rfc5322Email = /^(([^<>()\\[\\]\\\\.,;:\\s@"]+(\\.[^<>()\\[\\]\\\\.,;:\\s@"]+)*)|(".+"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))\$/; +var unicodeEmail = /^[^\\s@"]{1,64}@[^\\s@]{1,255}\$/u; +var idnEmail = unicodeEmail; +var browserEmail = /^[a-zA-Z0-9.!#\$%&'*+/=?^_\`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\$/; +var _emoji = \`^(\\\\p{Extended_Pictographic}|\\\\p{Emoji_Component})+\$\`; +function emoji() { + return new RegExp(_emoji, "u"); +} +__name(emoji, "emoji"); +var ipv4 = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\$/; +var ipv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))\$/; +var cidrv4 = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\/([0-9]|[1-2][0-9]|3[0-2])\$/; +var cidrv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::|([0-9a-fA-F]{1,4})?::([0-9a-fA-F]{1,4}:?){0,6})\\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])\$/; +var base64 = /^\$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?\$/; +var base64url = /^[A-Za-z0-9_-]*\$/; +var hostname = /^(?=.{1,253}\\.?\$)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[-0-9a-zA-Z]{0,61}[0-9a-zA-Z])?)*\\.?\$/; +var domain = /^([a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,}\$/; +var e164 = /^\\+(?:[0-9]){6,14}[0-9]\$/; +var dateSource = \`(?:(?:\\\\d\\\\d[2468][048]|\\\\d\\\\d[13579][26]|\\\\d\\\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\\\d|30)|(?:02)-(?:0[1-9]|1\\\\d|2[0-8])))\`; +var date = /* @__PURE__ */ new RegExp(\`^\${dateSource}\$\`); +function timeSource(args) { + const hhmm = \`(?:[01]\\\\d|2[0-3]):[0-5]\\\\d\`; + const regex = typeof args.precision === "number" ? args.precision === -1 ? \`\${hhmm}\` : args.precision === 0 ? \`\${hhmm}:[0-5]\\\\d\` : \`\${hhmm}:[0-5]\\\\d\\\\.\\\\d{\${args.precision}}\` : \`\${hhmm}(?::[0-5]\\\\d(?:\\\\.\\\\d+)?)?\`; + return regex; +} +__name(timeSource, "timeSource"); +function time(args) { + return new RegExp(\`^\${timeSource(args)}\$\`); +} +__name(time, "time"); +function datetime(args) { + const time3 = timeSource({ + precision: args.precision + }); + const opts = [ + "Z" + ]; + if (args.local) opts.push(""); + if (args.offset) opts.push(\`([+-](?:[01]\\\\d|2[0-3]):[0-5]\\\\d)\`); + const timeRegex2 = \`\${time3}(?:\${opts.join("|")})\`; + return new RegExp(\`^\${dateSource}T(?:\${timeRegex2})\$\`); +} +__name(datetime, "datetime"); +var string = /* @__PURE__ */ __name((params) => { + const regex = params ? \`[\\\\s\\\\S]{\${params?.minimum ?? 0},\${params?.maximum ?? ""}}\` : \`[\\\\s\\\\S]*\`; + return new RegExp(\`^\${regex}\$\`); +}, "string"); +var bigint = /^-?\\d+n?\$/; +var integer = /^-?\\d+\$/; +var number = /^-?\\d+(?:\\.\\d+)?/; +var boolean = /^(?:true|false)\$/i; +var _null = /^null\$/i; +var _undefined = /^undefined\$/i; +var lowercase = /^[^A-Z]*\$/; +var uppercase = /^[^a-z]*\$/; +var hex = /^[0-9a-fA-F]*\$/; +function fixedBase64(bodyLength, padding) { + return new RegExp(\`^[A-Za-z0-9+/]{\${bodyLength}}\${padding}\$\`); +} +__name(fixedBase64, "fixedBase64"); +function fixedBase64url(length) { + return new RegExp(\`^[A-Za-z0-9_-]{\${length}}\$\`); +} +__name(fixedBase64url, "fixedBase64url"); +var md5_hex = /^[0-9a-fA-F]{32}\$/; +var md5_base64 = /* @__PURE__ */ fixedBase64(22, "=="); +var md5_base64url = /* @__PURE__ */ fixedBase64url(22); +var sha1_hex = /^[0-9a-fA-F]{40}\$/; +var sha1_base64 = /* @__PURE__ */ fixedBase64(27, "="); +var sha1_base64url = /* @__PURE__ */ fixedBase64url(27); +var sha256_hex = /^[0-9a-fA-F]{64}\$/; +var sha256_base64 = /* @__PURE__ */ fixedBase64(43, "="); +var sha256_base64url = /* @__PURE__ */ fixedBase64url(43); +var sha384_hex = /^[0-9a-fA-F]{96}\$/; +var sha384_base64 = /* @__PURE__ */ fixedBase64(64, ""); +var sha384_base64url = /* @__PURE__ */ fixedBase64url(64); +var sha512_hex = /^[0-9a-fA-F]{128}\$/; +var sha512_base64 = /* @__PURE__ */ fixedBase64(86, "=="); +var sha512_base64url = /* @__PURE__ */ fixedBase64url(86); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/core/checks.js +var \$ZodCheck = /* @__PURE__ */ \$constructor("\$ZodCheck", (inst, def) => { + var _a17; + inst._zod ?? (inst._zod = {}); + inst._zod.def = def; + (_a17 = inst._zod).onattach ?? (_a17.onattach = []); +}); +var numericOriginMap = { + number: "number", + bigint: "bigint", + object: "date" +}; +var \$ZodCheckLessThan = /* @__PURE__ */ \$constructor("\$ZodCheckLessThan", (inst, def) => { + \$ZodCheck.init(inst, def); + const origin = numericOriginMap[typeof def.value]; + inst._zod.onattach.push((inst2) => { + const bag = inst2._zod.bag; + const curr = (def.inclusive ? bag.maximum : bag.exclusiveMaximum) ?? Number.POSITIVE_INFINITY; + if (def.value < curr) { + if (def.inclusive) bag.maximum = def.value; + else bag.exclusiveMaximum = def.value; + } + }); + inst._zod.check = (payload) => { + if (def.inclusive ? payload.value <= def.value : payload.value < def.value) { + return; + } + payload.issues.push({ + origin, + code: "too_big", + maximum: def.value, + input: payload.value, + inclusive: def.inclusive, + inst, + continue: !def.abort + }); + }; +}); +var \$ZodCheckGreaterThan = /* @__PURE__ */ \$constructor("\$ZodCheckGreaterThan", (inst, def) => { + \$ZodCheck.init(inst, def); + const origin = numericOriginMap[typeof def.value]; + inst._zod.onattach.push((inst2) => { + const bag = inst2._zod.bag; + const curr = (def.inclusive ? bag.minimum : bag.exclusiveMinimum) ?? Number.NEGATIVE_INFINITY; + if (def.value > curr) { + if (def.inclusive) bag.minimum = def.value; + else bag.exclusiveMinimum = def.value; + } + }); + inst._zod.check = (payload) => { + if (def.inclusive ? payload.value >= def.value : payload.value > def.value) { + return; + } + payload.issues.push({ + origin, + code: "too_small", + minimum: def.value, + input: payload.value, + inclusive: def.inclusive, + inst, + continue: !def.abort + }); + }; +}); +var \$ZodCheckMultipleOf = /* @__PURE__ */ \$constructor("\$ZodCheckMultipleOf", (inst, def) => { + \$ZodCheck.init(inst, def); + inst._zod.onattach.push((inst2) => { + var _a17; + (_a17 = inst2._zod.bag).multipleOf ?? (_a17.multipleOf = def.value); + }); + inst._zod.check = (payload) => { + if (typeof payload.value !== typeof def.value) throw new Error("Cannot mix number and bigint in multiple_of check."); + const isMultiple = typeof payload.value === "bigint" ? payload.value % def.value === BigInt(0) : floatSafeRemainder(payload.value, def.value) === 0; + if (isMultiple) return; + payload.issues.push({ + origin: typeof payload.value, + code: "not_multiple_of", + divisor: def.value, + input: payload.value, + inst, + continue: !def.abort + }); + }; +}); +var \$ZodCheckNumberFormat = /* @__PURE__ */ \$constructor("\$ZodCheckNumberFormat", (inst, def) => { + \$ZodCheck.init(inst, def); + def.format = def.format || "float64"; + const isInt = def.format?.includes("int"); + const origin = isInt ? "int" : "number"; + const [minimum, maximum] = NUMBER_FORMAT_RANGES[def.format]; + inst._zod.onattach.push((inst2) => { + const bag = inst2._zod.bag; + bag.format = def.format; + bag.minimum = minimum; + bag.maximum = maximum; + if (isInt) bag.pattern = integer; + }); + inst._zod.check = (payload) => { + const input = payload.value; + if (isInt) { + if (!Number.isInteger(input)) { + payload.issues.push({ + expected: origin, + format: def.format, + code: "invalid_type", + continue: false, + input, + inst + }); + return; + } + if (!Number.isSafeInteger(input)) { + if (input > 0) { + payload.issues.push({ + input, + code: "too_big", + maximum: Number.MAX_SAFE_INTEGER, + note: "Integers must be within the safe integer range.", + inst, + origin, + continue: !def.abort + }); + } else { + payload.issues.push({ + input, + code: "too_small", + minimum: Number.MIN_SAFE_INTEGER, + note: "Integers must be within the safe integer range.", + inst, + origin, + continue: !def.abort + }); + } + return; + } + } + if (input < minimum) { + payload.issues.push({ + origin: "number", + input, + code: "too_small", + minimum, + inclusive: true, + inst, + continue: !def.abort + }); + } + if (input > maximum) { + payload.issues.push({ + origin: "number", + input, + code: "too_big", + maximum, + inst + }); + } + }; +}); +var \$ZodCheckBigIntFormat = /* @__PURE__ */ \$constructor("\$ZodCheckBigIntFormat", (inst, def) => { + \$ZodCheck.init(inst, def); + const [minimum, maximum] = BIGINT_FORMAT_RANGES[def.format]; + inst._zod.onattach.push((inst2) => { + const bag = inst2._zod.bag; + bag.format = def.format; + bag.minimum = minimum; + bag.maximum = maximum; + }); + inst._zod.check = (payload) => { + const input = payload.value; + if (input < minimum) { + payload.issues.push({ + origin: "bigint", + input, + code: "too_small", + minimum, + inclusive: true, + inst, + continue: !def.abort + }); + } + if (input > maximum) { + payload.issues.push({ + origin: "bigint", + input, + code: "too_big", + maximum, + inst + }); + } + }; +}); +var \$ZodCheckMaxSize = /* @__PURE__ */ \$constructor("\$ZodCheckMaxSize", (inst, def) => { + var _a17; + \$ZodCheck.init(inst, def); + (_a17 = inst._zod.def).when ?? (_a17.when = (payload) => { + const val = payload.value; + return !nullish(val) && val.size !== void 0; + }); + inst._zod.onattach.push((inst2) => { + const curr = inst2._zod.bag.maximum ?? Number.POSITIVE_INFINITY; + if (def.maximum < curr) inst2._zod.bag.maximum = def.maximum; + }); + inst._zod.check = (payload) => { + const input = payload.value; + const size = input.size; + if (size <= def.maximum) return; + payload.issues.push({ + origin: getSizableOrigin(input), + code: "too_big", + maximum: def.maximum, + inclusive: true, + input, + inst, + continue: !def.abort + }); + }; +}); +var \$ZodCheckMinSize = /* @__PURE__ */ \$constructor("\$ZodCheckMinSize", (inst, def) => { + var _a17; + \$ZodCheck.init(inst, def); + (_a17 = inst._zod.def).when ?? (_a17.when = (payload) => { + const val = payload.value; + return !nullish(val) && val.size !== void 0; + }); + inst._zod.onattach.push((inst2) => { + const curr = inst2._zod.bag.minimum ?? Number.NEGATIVE_INFINITY; + if (def.minimum > curr) inst2._zod.bag.minimum = def.minimum; + }); + inst._zod.check = (payload) => { + const input = payload.value; + const size = input.size; + if (size >= def.minimum) return; + payload.issues.push({ + origin: getSizableOrigin(input), + code: "too_small", + minimum: def.minimum, + inclusive: true, + input, + inst, + continue: !def.abort + }); + }; +}); +var \$ZodCheckSizeEquals = /* @__PURE__ */ \$constructor("\$ZodCheckSizeEquals", (inst, def) => { + var _a17; + \$ZodCheck.init(inst, def); + (_a17 = inst._zod.def).when ?? (_a17.when = (payload) => { + const val = payload.value; + return !nullish(val) && val.size !== void 0; + }); + inst._zod.onattach.push((inst2) => { + const bag = inst2._zod.bag; + bag.minimum = def.size; + bag.maximum = def.size; + bag.size = def.size; + }); + inst._zod.check = (payload) => { + const input = payload.value; + const size = input.size; + if (size === def.size) return; + const tooBig = size > def.size; + payload.issues.push({ + origin: getSizableOrigin(input), + ...tooBig ? { + code: "too_big", + maximum: def.size + } : { + code: "too_small", + minimum: def.size + }, + inclusive: true, + exact: true, + input: payload.value, + inst, + continue: !def.abort + }); + }; +}); +var \$ZodCheckMaxLength = /* @__PURE__ */ \$constructor("\$ZodCheckMaxLength", (inst, def) => { + var _a17; + \$ZodCheck.init(inst, def); + (_a17 = inst._zod.def).when ?? (_a17.when = (payload) => { + const val = payload.value; + return !nullish(val) && val.length !== void 0; + }); + inst._zod.onattach.push((inst2) => { + const curr = inst2._zod.bag.maximum ?? Number.POSITIVE_INFINITY; + if (def.maximum < curr) inst2._zod.bag.maximum = def.maximum; + }); + inst._zod.check = (payload) => { + const input = payload.value; + const length = input.length; + if (length <= def.maximum) return; + const origin = getLengthableOrigin(input); + payload.issues.push({ + origin, + code: "too_big", + maximum: def.maximum, + inclusive: true, + input, + inst, + continue: !def.abort + }); + }; +}); +var \$ZodCheckMinLength = /* @__PURE__ */ \$constructor("\$ZodCheckMinLength", (inst, def) => { + var _a17; + \$ZodCheck.init(inst, def); + (_a17 = inst._zod.def).when ?? (_a17.when = (payload) => { + const val = payload.value; + return !nullish(val) && val.length !== void 0; + }); + inst._zod.onattach.push((inst2) => { + const curr = inst2._zod.bag.minimum ?? Number.NEGATIVE_INFINITY; + if (def.minimum > curr) inst2._zod.bag.minimum = def.minimum; + }); + inst._zod.check = (payload) => { + const input = payload.value; + const length = input.length; + if (length >= def.minimum) return; + const origin = getLengthableOrigin(input); + payload.issues.push({ + origin, + code: "too_small", + minimum: def.minimum, + inclusive: true, + input, + inst, + continue: !def.abort + }); + }; +}); +var \$ZodCheckLengthEquals = /* @__PURE__ */ \$constructor("\$ZodCheckLengthEquals", (inst, def) => { + var _a17; + \$ZodCheck.init(inst, def); + (_a17 = inst._zod.def).when ?? (_a17.when = (payload) => { + const val = payload.value; + return !nullish(val) && val.length !== void 0; + }); + inst._zod.onattach.push((inst2) => { + const bag = inst2._zod.bag; + bag.minimum = def.length; + bag.maximum = def.length; + bag.length = def.length; + }); + inst._zod.check = (payload) => { + const input = payload.value; + const length = input.length; + if (length === def.length) return; + const origin = getLengthableOrigin(input); + const tooBig = length > def.length; + payload.issues.push({ + origin, + ...tooBig ? { + code: "too_big", + maximum: def.length + } : { + code: "too_small", + minimum: def.length + }, + inclusive: true, + exact: true, + input: payload.value, + inst, + continue: !def.abort + }); + }; +}); +var \$ZodCheckStringFormat = /* @__PURE__ */ \$constructor("\$ZodCheckStringFormat", (inst, def) => { + var _a17, _b8; + \$ZodCheck.init(inst, def); + inst._zod.onattach.push((inst2) => { + const bag = inst2._zod.bag; + bag.format = def.format; + if (def.pattern) { + bag.patterns ?? (bag.patterns = /* @__PURE__ */ new Set()); + bag.patterns.add(def.pattern); + } + }); + if (def.pattern) (_a17 = inst._zod).check ?? (_a17.check = (payload) => { + def.pattern.lastIndex = 0; + if (def.pattern.test(payload.value)) return; + payload.issues.push({ + origin: "string", + code: "invalid_format", + format: def.format, + input: payload.value, + ...def.pattern ? { + pattern: def.pattern.toString() + } : {}, + inst, + continue: !def.abort + }); + }); + else (_b8 = inst._zod).check ?? (_b8.check = () => { + }); +}); +var \$ZodCheckRegex = /* @__PURE__ */ \$constructor("\$ZodCheckRegex", (inst, def) => { + \$ZodCheckStringFormat.init(inst, def); + inst._zod.check = (payload) => { + def.pattern.lastIndex = 0; + if (def.pattern.test(payload.value)) return; + payload.issues.push({ + origin: "string", + code: "invalid_format", + format: "regex", + input: payload.value, + pattern: def.pattern.toString(), + inst, + continue: !def.abort + }); + }; +}); +var \$ZodCheckLowerCase = /* @__PURE__ */ \$constructor("\$ZodCheckLowerCase", (inst, def) => { + def.pattern ?? (def.pattern = lowercase); + \$ZodCheckStringFormat.init(inst, def); +}); +var \$ZodCheckUpperCase = /* @__PURE__ */ \$constructor("\$ZodCheckUpperCase", (inst, def) => { + def.pattern ?? (def.pattern = uppercase); + \$ZodCheckStringFormat.init(inst, def); +}); +var \$ZodCheckIncludes = /* @__PURE__ */ \$constructor("\$ZodCheckIncludes", (inst, def) => { + \$ZodCheck.init(inst, def); + const escapedRegex = escapeRegex(def.includes); + const pattern = new RegExp(typeof def.position === "number" ? \`^.{\${def.position}}\${escapedRegex}\` : escapedRegex); + def.pattern = pattern; + inst._zod.onattach.push((inst2) => { + const bag = inst2._zod.bag; + bag.patterns ?? (bag.patterns = /* @__PURE__ */ new Set()); + bag.patterns.add(pattern); + }); + inst._zod.check = (payload) => { + if (payload.value.includes(def.includes, def.position)) return; + payload.issues.push({ + origin: "string", + code: "invalid_format", + format: "includes", + includes: def.includes, + input: payload.value, + inst, + continue: !def.abort + }); + }; +}); +var \$ZodCheckStartsWith = /* @__PURE__ */ \$constructor("\$ZodCheckStartsWith", (inst, def) => { + \$ZodCheck.init(inst, def); + const pattern = new RegExp(\`^\${escapeRegex(def.prefix)}.*\`); + def.pattern ?? (def.pattern = pattern); + inst._zod.onattach.push((inst2) => { + const bag = inst2._zod.bag; + bag.patterns ?? (bag.patterns = /* @__PURE__ */ new Set()); + bag.patterns.add(pattern); + }); + inst._zod.check = (payload) => { + if (payload.value.startsWith(def.prefix)) return; + payload.issues.push({ + origin: "string", + code: "invalid_format", + format: "starts_with", + prefix: def.prefix, + input: payload.value, + inst, + continue: !def.abort + }); + }; +}); +var \$ZodCheckEndsWith = /* @__PURE__ */ \$constructor("\$ZodCheckEndsWith", (inst, def) => { + \$ZodCheck.init(inst, def); + const pattern = new RegExp(\`.*\${escapeRegex(def.suffix)}\$\`); + def.pattern ?? (def.pattern = pattern); + inst._zod.onattach.push((inst2) => { + const bag = inst2._zod.bag; + bag.patterns ?? (bag.patterns = /* @__PURE__ */ new Set()); + bag.patterns.add(pattern); + }); + inst._zod.check = (payload) => { + if (payload.value.endsWith(def.suffix)) return; + payload.issues.push({ + origin: "string", + code: "invalid_format", + format: "ends_with", + suffix: def.suffix, + input: payload.value, + inst, + continue: !def.abort + }); + }; +}); +function handleCheckPropertyResult(result, payload, property) { + if (result.issues.length) { + payload.issues.push(...prefixIssues(property, result.issues)); + } +} +__name(handleCheckPropertyResult, "handleCheckPropertyResult"); +var \$ZodCheckProperty = /* @__PURE__ */ \$constructor("\$ZodCheckProperty", (inst, def) => { + \$ZodCheck.init(inst, def); + inst._zod.check = (payload) => { + const result = def.schema._zod.run({ + value: payload.value[def.property], + issues: [] + }, {}); + if (result instanceof Promise) { + return result.then((result2) => handleCheckPropertyResult(result2, payload, def.property)); + } + handleCheckPropertyResult(result, payload, def.property); + return; + }; +}); +var \$ZodCheckMimeType = /* @__PURE__ */ \$constructor("\$ZodCheckMimeType", (inst, def) => { + \$ZodCheck.init(inst, def); + const mimeSet = new Set(def.mime); + inst._zod.onattach.push((inst2) => { + inst2._zod.bag.mime = def.mime; + }); + inst._zod.check = (payload) => { + if (mimeSet.has(payload.value.type)) return; + payload.issues.push({ + code: "invalid_value", + values: def.mime, + input: payload.value.type, + inst, + continue: !def.abort + }); + }; +}); +var \$ZodCheckOverwrite = /* @__PURE__ */ \$constructor("\$ZodCheckOverwrite", (inst, def) => { + \$ZodCheck.init(inst, def); + inst._zod.check = (payload) => { + payload.value = def.tx(payload.value); + }; +}); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/core/doc.js +var Doc = class { + static { + __name(this, "Doc"); + } + constructor(args = []) { + this.content = []; + this.indent = 0; + if (this) this.args = args; + } + indented(fn) { + this.indent += 1; + fn(this); + this.indent -= 1; + } + write(arg) { + if (typeof arg === "function") { + arg(this, { + execution: "sync" + }); + arg(this, { + execution: "async" + }); + return; + } + const content = arg; + const lines = content.split("\\n").filter((x) => x); + const minIndent = Math.min(...lines.map((x) => x.length - x.trimStart().length)); + const dedented = lines.map((x) => x.slice(minIndent)).map((x) => " ".repeat(this.indent * 2) + x); + for (const line of dedented) { + this.content.push(line); + } + } + compile() { + const F = Function; + const args = this?.args; + const content = this?.content ?? [ + \`\` + ]; + const lines = [ + ...content.map((x) => \` \${x}\`) + ]; + return new F(...args, lines.join("\\n")); + } +}; + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/core/versions.js +var version = { + major: 4, + minor: 1, + patch: 11 +}; + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/core/schemas.js +var \$ZodType = /* @__PURE__ */ \$constructor("\$ZodType", (inst, def) => { + var _a17; + inst ?? (inst = {}); + inst._zod.def = def; + inst._zod.bag = inst._zod.bag || {}; + inst._zod.version = version; + const checks = [ + ...inst._zod.def.checks ?? [] + ]; + if (inst._zod.traits.has("\$ZodCheck")) { + checks.unshift(inst); + } + for (const ch of checks) { + for (const fn of ch._zod.onattach) { + fn(inst); + } + } + if (checks.length === 0) { + (_a17 = inst._zod).deferred ?? (_a17.deferred = []); + inst._zod.deferred?.push(() => { + inst._zod.run = inst._zod.parse; + }); + } else { + const runChecks = /* @__PURE__ */ __name((payload, checks2, ctx) => { + let isAborted2 = aborted(payload); + let asyncResult; + for (const ch of checks2) { + if (ch._zod.def.when) { + const shouldRun = ch._zod.def.when(payload); + if (!shouldRun) continue; + } else if (isAborted2) { + continue; + } + const currLen = payload.issues.length; + const _ = ch._zod.check(payload); + if (_ instanceof Promise && ctx?.async === false) { + throw new \$ZodAsyncError(); + } + if (asyncResult || _ instanceof Promise) { + asyncResult = (asyncResult ?? Promise.resolve()).then(async () => { + await _; + const nextLen = payload.issues.length; + if (nextLen === currLen) return; + if (!isAborted2) isAborted2 = aborted(payload, currLen); + }); + } else { + const nextLen = payload.issues.length; + if (nextLen === currLen) continue; + if (!isAborted2) isAborted2 = aborted(payload, currLen); + } + } + if (asyncResult) { + return asyncResult.then(() => { + return payload; + }); + } + return payload; + }, "runChecks"); + const handleCanaryResult = /* @__PURE__ */ __name((canary, payload, ctx) => { + if (aborted(canary)) { + canary.aborted = true; + return canary; + } + const checkResult = runChecks(payload, checks, ctx); + if (checkResult instanceof Promise) { + if (ctx.async === false) throw new \$ZodAsyncError(); + return checkResult.then((checkResult2) => inst._zod.parse(checkResult2, ctx)); + } + return inst._zod.parse(checkResult, ctx); + }, "handleCanaryResult"); + inst._zod.run = (payload, ctx) => { + if (ctx.skipChecks) { + return inst._zod.parse(payload, ctx); + } + if (ctx.direction === "backward") { + const canary = inst._zod.parse({ + value: payload.value, + issues: [] + }, { + ...ctx, + skipChecks: true + }); + if (canary instanceof Promise) { + return canary.then((canary2) => { + return handleCanaryResult(canary2, payload, ctx); + }); + } + return handleCanaryResult(canary, payload, ctx); + } + const result = inst._zod.parse(payload, ctx); + if (result instanceof Promise) { + if (ctx.async === false) throw new \$ZodAsyncError(); + return result.then((result2) => runChecks(result2, checks, ctx)); + } + return runChecks(result, checks, ctx); + }; + } + inst["~standard"] = { + validate: /* @__PURE__ */ __name((value) => { + try { + const r = safeParse(inst, value); + return r.success ? { + value: r.data + } : { + issues: r.error?.issues + }; + } catch (_) { + return safeParseAsync(inst, value).then((r) => r.success ? { + value: r.data + } : { + issues: r.error?.issues + }); + } + }, "validate"), + vendor: "zod", + version: 1 + }; +}); +var \$ZodString = /* @__PURE__ */ \$constructor("\$ZodString", (inst, def) => { + \$ZodType.init(inst, def); + inst._zod.pattern = [ + ...inst?._zod.bag?.patterns ?? [] + ].pop() ?? string(inst._zod.bag); + inst._zod.parse = (payload, _) => { + if (def.coerce) try { + payload.value = String(payload.value); + } catch (_2) { + } + if (typeof payload.value === "string") return payload; + payload.issues.push({ + expected: "string", + code: "invalid_type", + input: payload.value, + inst + }); + return payload; + }; +}); +var \$ZodStringFormat = /* @__PURE__ */ \$constructor("\$ZodStringFormat", (inst, def) => { + \$ZodCheckStringFormat.init(inst, def); + \$ZodString.init(inst, def); +}); +var \$ZodGUID = /* @__PURE__ */ \$constructor("\$ZodGUID", (inst, def) => { + def.pattern ?? (def.pattern = guid); + \$ZodStringFormat.init(inst, def); +}); +var \$ZodUUID = /* @__PURE__ */ \$constructor("\$ZodUUID", (inst, def) => { + if (def.version) { + const versionMap = { + v1: 1, + v2: 2, + v3: 3, + v4: 4, + v5: 5, + v6: 6, + v7: 7, + v8: 8 + }; + const v = versionMap[def.version]; + if (v === void 0) throw new Error(\`Invalid UUID version: "\${def.version}"\`); + def.pattern ?? (def.pattern = uuid(v)); + } else def.pattern ?? (def.pattern = uuid()); + \$ZodStringFormat.init(inst, def); +}); +var \$ZodEmail = /* @__PURE__ */ \$constructor("\$ZodEmail", (inst, def) => { + def.pattern ?? (def.pattern = email); + \$ZodStringFormat.init(inst, def); +}); +var \$ZodURL = /* @__PURE__ */ \$constructor("\$ZodURL", (inst, def) => { + \$ZodStringFormat.init(inst, def); + inst._zod.check = (payload) => { + try { + const trimmed = payload.value.trim(); + const url2 = new URL(trimmed); + if (def.hostname) { + def.hostname.lastIndex = 0; + if (!def.hostname.test(url2.hostname)) { + payload.issues.push({ + code: "invalid_format", + format: "url", + note: "Invalid hostname", + pattern: hostname.source, + input: payload.value, + inst, + continue: !def.abort + }); + } + } + if (def.protocol) { + def.protocol.lastIndex = 0; + if (!def.protocol.test(url2.protocol.endsWith(":") ? url2.protocol.slice(0, -1) : url2.protocol)) { + payload.issues.push({ + code: "invalid_format", + format: "url", + note: "Invalid protocol", + pattern: def.protocol.source, + input: payload.value, + inst, + continue: !def.abort + }); + } + } + if (def.normalize) { + payload.value = url2.href; + } else { + payload.value = trimmed; + } + return; + } catch (_) { + payload.issues.push({ + code: "invalid_format", + format: "url", + input: payload.value, + inst, + continue: !def.abort + }); + } + }; +}); +var \$ZodEmoji = /* @__PURE__ */ \$constructor("\$ZodEmoji", (inst, def) => { + def.pattern ?? (def.pattern = emoji()); + \$ZodStringFormat.init(inst, def); +}); +var \$ZodNanoID = /* @__PURE__ */ \$constructor("\$ZodNanoID", (inst, def) => { + def.pattern ?? (def.pattern = nanoid); + \$ZodStringFormat.init(inst, def); +}); +var \$ZodCUID = /* @__PURE__ */ \$constructor("\$ZodCUID", (inst, def) => { + def.pattern ?? (def.pattern = cuid); + \$ZodStringFormat.init(inst, def); +}); +var \$ZodCUID2 = /* @__PURE__ */ \$constructor("\$ZodCUID2", (inst, def) => { + def.pattern ?? (def.pattern = cuid2); + \$ZodStringFormat.init(inst, def); +}); +var \$ZodULID = /* @__PURE__ */ \$constructor("\$ZodULID", (inst, def) => { + def.pattern ?? (def.pattern = ulid); + \$ZodStringFormat.init(inst, def); +}); +var \$ZodXID = /* @__PURE__ */ \$constructor("\$ZodXID", (inst, def) => { + def.pattern ?? (def.pattern = xid); + \$ZodStringFormat.init(inst, def); +}); +var \$ZodKSUID = /* @__PURE__ */ \$constructor("\$ZodKSUID", (inst, def) => { + def.pattern ?? (def.pattern = ksuid); + \$ZodStringFormat.init(inst, def); +}); +var \$ZodISODateTime = /* @__PURE__ */ \$constructor("\$ZodISODateTime", (inst, def) => { + def.pattern ?? (def.pattern = datetime(def)); + \$ZodStringFormat.init(inst, def); +}); +var \$ZodISODate = /* @__PURE__ */ \$constructor("\$ZodISODate", (inst, def) => { + def.pattern ?? (def.pattern = date); + \$ZodStringFormat.init(inst, def); +}); +var \$ZodISOTime = /* @__PURE__ */ \$constructor("\$ZodISOTime", (inst, def) => { + def.pattern ?? (def.pattern = time(def)); + \$ZodStringFormat.init(inst, def); +}); +var \$ZodISODuration = /* @__PURE__ */ \$constructor("\$ZodISODuration", (inst, def) => { + def.pattern ?? (def.pattern = duration); + \$ZodStringFormat.init(inst, def); +}); +var \$ZodIPv4 = /* @__PURE__ */ \$constructor("\$ZodIPv4", (inst, def) => { + def.pattern ?? (def.pattern = ipv4); + \$ZodStringFormat.init(inst, def); + inst._zod.onattach.push((inst2) => { + const bag = inst2._zod.bag; + bag.format = \`ipv4\`; + }); +}); +var \$ZodIPv6 = /* @__PURE__ */ \$constructor("\$ZodIPv6", (inst, def) => { + def.pattern ?? (def.pattern = ipv6); + \$ZodStringFormat.init(inst, def); + inst._zod.onattach.push((inst2) => { + const bag = inst2._zod.bag; + bag.format = \`ipv6\`; + }); + inst._zod.check = (payload) => { + try { + new URL(\`http://[\${payload.value}]\`); + } catch { + payload.issues.push({ + code: "invalid_format", + format: "ipv6", + input: payload.value, + inst, + continue: !def.abort + }); + } + }; +}); +var \$ZodCIDRv4 = /* @__PURE__ */ \$constructor("\$ZodCIDRv4", (inst, def) => { + def.pattern ?? (def.pattern = cidrv4); + \$ZodStringFormat.init(inst, def); +}); +var \$ZodCIDRv6 = /* @__PURE__ */ \$constructor("\$ZodCIDRv6", (inst, def) => { + def.pattern ?? (def.pattern = cidrv6); + \$ZodStringFormat.init(inst, def); + inst._zod.check = (payload) => { + const parts = payload.value.split("/"); + try { + if (parts.length !== 2) throw new Error(); + const [address, prefix] = parts; + if (!prefix) throw new Error(); + const prefixNum = Number(prefix); + if (\`\${prefixNum}\` !== prefix) throw new Error(); + if (prefixNum < 0 || prefixNum > 128) throw new Error(); + new URL(\`http://[\${address}]\`); + } catch { + payload.issues.push({ + code: "invalid_format", + format: "cidrv6", + input: payload.value, + inst, + continue: !def.abort + }); + } + }; +}); +function isValidBase64(data) { + if (data === "") return true; + if (data.length % 4 !== 0) return false; + try { + atob(data); + return true; + } catch { + return false; + } +} +__name(isValidBase64, "isValidBase64"); +var \$ZodBase64 = /* @__PURE__ */ \$constructor("\$ZodBase64", (inst, def) => { + def.pattern ?? (def.pattern = base64); + \$ZodStringFormat.init(inst, def); + inst._zod.onattach.push((inst2) => { + inst2._zod.bag.contentEncoding = "base64"; + }); + inst._zod.check = (payload) => { + if (isValidBase64(payload.value)) return; + payload.issues.push({ + code: "invalid_format", + format: "base64", + input: payload.value, + inst, + continue: !def.abort + }); + }; +}); +function isValidBase64URL(data) { + if (!base64url.test(data)) return false; + const base643 = data.replace(/[-_]/g, (c) => c === "-" ? "+" : "/"); + const padded = base643.padEnd(Math.ceil(base643.length / 4) * 4, "="); + return isValidBase64(padded); +} +__name(isValidBase64URL, "isValidBase64URL"); +var \$ZodBase64URL = /* @__PURE__ */ \$constructor("\$ZodBase64URL", (inst, def) => { + def.pattern ?? (def.pattern = base64url); + \$ZodStringFormat.init(inst, def); + inst._zod.onattach.push((inst2) => { + inst2._zod.bag.contentEncoding = "base64url"; + }); + inst._zod.check = (payload) => { + if (isValidBase64URL(payload.value)) return; + payload.issues.push({ + code: "invalid_format", + format: "base64url", + input: payload.value, + inst, + continue: !def.abort + }); + }; +}); +var \$ZodE164 = /* @__PURE__ */ \$constructor("\$ZodE164", (inst, def) => { + def.pattern ?? (def.pattern = e164); + \$ZodStringFormat.init(inst, def); +}); +function isValidJWT(token, algorithm = null) { + try { + const tokensParts = token.split("."); + if (tokensParts.length !== 3) return false; + const [header] = tokensParts; + if (!header) return false; + const parsedHeader = JSON.parse(atob(header)); + if ("typ" in parsedHeader && parsedHeader?.typ !== "JWT") return false; + if (!parsedHeader.alg) return false; + if (algorithm && (!("alg" in parsedHeader) || parsedHeader.alg !== algorithm)) return false; + return true; + } catch { + return false; + } +} +__name(isValidJWT, "isValidJWT"); +var \$ZodJWT = /* @__PURE__ */ \$constructor("\$ZodJWT", (inst, def) => { + \$ZodStringFormat.init(inst, def); + inst._zod.check = (payload) => { + if (isValidJWT(payload.value, def.alg)) return; + payload.issues.push({ + code: "invalid_format", + format: "jwt", + input: payload.value, + inst, + continue: !def.abort + }); + }; +}); +var \$ZodCustomStringFormat = /* @__PURE__ */ \$constructor("\$ZodCustomStringFormat", (inst, def) => { + \$ZodStringFormat.init(inst, def); + inst._zod.check = (payload) => { + if (def.fn(payload.value)) return; + payload.issues.push({ + code: "invalid_format", + format: def.format, + input: payload.value, + inst, + continue: !def.abort + }); + }; +}); +var \$ZodNumber = /* @__PURE__ */ \$constructor("\$ZodNumber", (inst, def) => { + \$ZodType.init(inst, def); + inst._zod.pattern = inst._zod.bag.pattern ?? number; + inst._zod.parse = (payload, _ctx) => { + if (def.coerce) try { + payload.value = Number(payload.value); + } catch (_) { + } + const input = payload.value; + if (typeof input === "number" && !Number.isNaN(input) && Number.isFinite(input)) { + return payload; + } + const received = typeof input === "number" ? Number.isNaN(input) ? "NaN" : !Number.isFinite(input) ? "Infinity" : void 0 : void 0; + payload.issues.push({ + expected: "number", + code: "invalid_type", + input, + inst, + ...received ? { + received + } : {} + }); + return payload; + }; +}); +var \$ZodNumberFormat = /* @__PURE__ */ \$constructor("\$ZodNumber", (inst, def) => { + \$ZodCheckNumberFormat.init(inst, def); + \$ZodNumber.init(inst, def); +}); +var \$ZodBoolean = /* @__PURE__ */ \$constructor("\$ZodBoolean", (inst, def) => { + \$ZodType.init(inst, def); + inst._zod.pattern = boolean; + inst._zod.parse = (payload, _ctx) => { + if (def.coerce) try { + payload.value = Boolean(payload.value); + } catch (_) { + } + const input = payload.value; + if (typeof input === "boolean") return payload; + payload.issues.push({ + expected: "boolean", + code: "invalid_type", + input, + inst + }); + return payload; + }; +}); +var \$ZodBigInt = /* @__PURE__ */ \$constructor("\$ZodBigInt", (inst, def) => { + \$ZodType.init(inst, def); + inst._zod.pattern = bigint; + inst._zod.parse = (payload, _ctx) => { + if (def.coerce) try { + payload.value = BigInt(payload.value); + } catch (_) { + } + if (typeof payload.value === "bigint") return payload; + payload.issues.push({ + expected: "bigint", + code: "invalid_type", + input: payload.value, + inst + }); + return payload; + }; +}); +var \$ZodBigIntFormat = /* @__PURE__ */ \$constructor("\$ZodBigInt", (inst, def) => { + \$ZodCheckBigIntFormat.init(inst, def); + \$ZodBigInt.init(inst, def); +}); +var \$ZodSymbol = /* @__PURE__ */ \$constructor("\$ZodSymbol", (inst, def) => { + \$ZodType.init(inst, def); + inst._zod.parse = (payload, _ctx) => { + const input = payload.value; + if (typeof input === "symbol") return payload; + payload.issues.push({ + expected: "symbol", + code: "invalid_type", + input, + inst + }); + return payload; + }; +}); +var \$ZodUndefined = /* @__PURE__ */ \$constructor("\$ZodUndefined", (inst, def) => { + \$ZodType.init(inst, def); + inst._zod.pattern = _undefined; + inst._zod.values = /* @__PURE__ */ new Set([ + void 0 + ]); + inst._zod.optin = "optional"; + inst._zod.optout = "optional"; + inst._zod.parse = (payload, _ctx) => { + const input = payload.value; + if (typeof input === "undefined") return payload; + payload.issues.push({ + expected: "undefined", + code: "invalid_type", + input, + inst + }); + return payload; + }; +}); +var \$ZodNull = /* @__PURE__ */ \$constructor("\$ZodNull", (inst, def) => { + \$ZodType.init(inst, def); + inst._zod.pattern = _null; + inst._zod.values = /* @__PURE__ */ new Set([ + null + ]); + inst._zod.parse = (payload, _ctx) => { + const input = payload.value; + if (input === null) return payload; + payload.issues.push({ + expected: "null", + code: "invalid_type", + input, + inst + }); + return payload; + }; +}); +var \$ZodAny = /* @__PURE__ */ \$constructor("\$ZodAny", (inst, def) => { + \$ZodType.init(inst, def); + inst._zod.parse = (payload) => payload; +}); +var \$ZodUnknown = /* @__PURE__ */ \$constructor("\$ZodUnknown", (inst, def) => { + \$ZodType.init(inst, def); + inst._zod.parse = (payload) => payload; +}); +var \$ZodNever = /* @__PURE__ */ \$constructor("\$ZodNever", (inst, def) => { + \$ZodType.init(inst, def); + inst._zod.parse = (payload, _ctx) => { + payload.issues.push({ + expected: "never", + code: "invalid_type", + input: payload.value, + inst + }); + return payload; + }; +}); +var \$ZodVoid = /* @__PURE__ */ \$constructor("\$ZodVoid", (inst, def) => { + \$ZodType.init(inst, def); + inst._zod.parse = (payload, _ctx) => { + const input = payload.value; + if (typeof input === "undefined") return payload; + payload.issues.push({ + expected: "void", + code: "invalid_type", + input, + inst + }); + return payload; + }; +}); +var \$ZodDate = /* @__PURE__ */ \$constructor("\$ZodDate", (inst, def) => { + \$ZodType.init(inst, def); + inst._zod.parse = (payload, _ctx) => { + if (def.coerce) { + try { + payload.value = new Date(payload.value); + } catch (_err) { + } + } + const input = payload.value; + const isDate = input instanceof Date; + const isValidDate = isDate && !Number.isNaN(input.getTime()); + if (isValidDate) return payload; + payload.issues.push({ + expected: "date", + code: "invalid_type", + input, + ...isDate ? { + received: "Invalid Date" + } : {}, + inst + }); + return payload; + }; +}); +function handleArrayResult(result, final, index) { + if (result.issues.length) { + final.issues.push(...prefixIssues(index, result.issues)); + } + final.value[index] = result.value; +} +__name(handleArrayResult, "handleArrayResult"); +var \$ZodArray = /* @__PURE__ */ \$constructor("\$ZodArray", (inst, def) => { + \$ZodType.init(inst, def); + inst._zod.parse = (payload, ctx) => { + const input = payload.value; + if (!Array.isArray(input)) { + payload.issues.push({ + expected: "array", + code: "invalid_type", + input, + inst + }); + return payload; + } + payload.value = Array(input.length); + const proms = []; + for (let i = 0; i < input.length; i++) { + const item = input[i]; + const result = def.element._zod.run({ + value: item, + issues: [] + }, ctx); + if (result instanceof Promise) { + proms.push(result.then((result2) => handleArrayResult(result2, payload, i))); + } else { + handleArrayResult(result, payload, i); + } + } + if (proms.length) { + return Promise.all(proms).then(() => payload); + } + return payload; + }; +}); +function handlePropertyResult(result, final, key, input) { + if (result.issues.length) { + final.issues.push(...prefixIssues(key, result.issues)); + } + if (result.value === void 0) { + if (key in input) { + final.value[key] = void 0; + } + } else { + final.value[key] = result.value; + } +} +__name(handlePropertyResult, "handlePropertyResult"); +function normalizeDef(def) { + const keys = Object.keys(def.shape); + for (const k of keys) { + if (!def.shape?.[k]?._zod?.traits?.has("\$ZodType")) { + throw new Error(\`Invalid element at key "\${k}": expected a Zod schema\`); + } + } + const okeys = optionalKeys(def.shape); + return { + ...def, + keys, + keySet: new Set(keys), + numKeys: keys.length, + optionalKeys: new Set(okeys) + }; +} +__name(normalizeDef, "normalizeDef"); +function handleCatchall(proms, input, payload, ctx, def, inst) { + const unrecognized = []; + const keySet = def.keySet; + const _catchall = def.catchall._zod; + const t = _catchall.def.type; + for (const key of Object.keys(input)) { + if (keySet.has(key)) continue; + if (t === "never") { + unrecognized.push(key); + continue; + } + const r = _catchall.run({ + value: input[key], + issues: [] + }, ctx); + if (r instanceof Promise) { + proms.push(r.then((r2) => handlePropertyResult(r2, payload, key, input))); + } else { + handlePropertyResult(r, payload, key, input); + } + } + if (unrecognized.length) { + payload.issues.push({ + code: "unrecognized_keys", + keys: unrecognized, + input, + inst + }); + } + if (!proms.length) return payload; + return Promise.all(proms).then(() => { + return payload; + }); +} +__name(handleCatchall, "handleCatchall"); +var \$ZodObject = /* @__PURE__ */ \$constructor("\$ZodObject", (inst, def) => { + \$ZodType.init(inst, def); + const desc = Object.getOwnPropertyDescriptor(def, "shape"); + if (!desc?.get) { + const sh = def.shape; + Object.defineProperty(def, "shape", { + get: /* @__PURE__ */ __name(() => { + const newSh = { + ...sh + }; + Object.defineProperty(def, "shape", { + value: newSh + }); + return newSh; + }, "get") + }); + } + const _normalized = cached(() => normalizeDef(def)); + defineLazy(inst._zod, "propValues", () => { + const shape = def.shape; + const propValues = {}; + for (const key in shape) { + const field = shape[key]._zod; + if (field.values) { + propValues[key] ?? (propValues[key] = /* @__PURE__ */ new Set()); + for (const v of field.values) propValues[key].add(v); + } + } + return propValues; + }); + const isObject2 = isObject; + const catchall = def.catchall; + let value; + inst._zod.parse = (payload, ctx) => { + value ?? (value = _normalized.value); + const input = payload.value; + if (!isObject2(input)) { + payload.issues.push({ + expected: "object", + code: "invalid_type", + input, + inst + }); + return payload; + } + payload.value = {}; + const proms = []; + const shape = value.shape; + for (const key of value.keys) { + const el = shape[key]; + const r = el._zod.run({ + value: input[key], + issues: [] + }, ctx); + if (r instanceof Promise) { + proms.push(r.then((r2) => handlePropertyResult(r2, payload, key, input))); + } else { + handlePropertyResult(r, payload, key, input); + } + } + if (!catchall) { + return proms.length ? Promise.all(proms).then(() => payload) : payload; + } + return handleCatchall(proms, input, payload, ctx, _normalized.value, inst); + }; +}); +var \$ZodObjectJIT = /* @__PURE__ */ \$constructor("\$ZodObjectJIT", (inst, def) => { + \$ZodObject.init(inst, def); + const superParse = inst._zod.parse; + const _normalized = cached(() => normalizeDef(def)); + const generateFastpass = /* @__PURE__ */ __name((shape) => { + const doc = new Doc([ + "shape", + "payload", + "ctx" + ]); + const normalized = _normalized.value; + const parseStr = /* @__PURE__ */ __name((key) => { + const k = esc(key); + return \`shape[\${k}]._zod.run({ value: input[\${k}], issues: [] }, ctx)\`; + }, "parseStr"); + doc.write(\`const input = payload.value;\`); + const ids = /* @__PURE__ */ Object.create(null); + let counter = 0; + for (const key of normalized.keys) { + ids[key] = \`key_\${counter++}\`; + } + doc.write(\`const newResult = {};\`); + for (const key of normalized.keys) { + const id = ids[key]; + const k = esc(key); + doc.write(\`const \${id} = \${parseStr(key)};\`); + doc.write(\` + if (\${id}.issues.length) { + payload.issues = payload.issues.concat(\${id}.issues.map(iss => ({ + ...iss, + path: iss.path ? [\${k}, ...iss.path] : [\${k}] + }))); + } + + + if (\${id}.value === undefined) { + if (\${k} in input) { + newResult[\${k}] = undefined; + } + } else { + newResult[\${k}] = \${id}.value; + } + + \`); + } + doc.write(\`payload.value = newResult;\`); + doc.write(\`return payload;\`); + const fn = doc.compile(); + return (payload, ctx) => fn(shape, payload, ctx); + }, "generateFastpass"); + let fastpass; + const isObject2 = isObject; + const jit = !globalConfig.jitless; + const allowsEval2 = allowsEval; + const fastEnabled = jit && allowsEval2.value; + const catchall = def.catchall; + let value; + inst._zod.parse = (payload, ctx) => { + value ?? (value = _normalized.value); + const input = payload.value; + if (!isObject2(input)) { + payload.issues.push({ + expected: "object", + code: "invalid_type", + input, + inst + }); + return payload; + } + if (jit && fastEnabled && ctx?.async === false && ctx.jitless !== true) { + if (!fastpass) fastpass = generateFastpass(def.shape); + payload = fastpass(payload, ctx); + if (!catchall) return payload; + return handleCatchall([], input, payload, ctx, value, inst); + } + return superParse(payload, ctx); + }; +}); +function handleUnionResults(results, final, inst, ctx) { + for (const result of results) { + if (result.issues.length === 0) { + final.value = result.value; + return final; + } + } + const nonaborted = results.filter((r) => !aborted(r)); + if (nonaborted.length === 1) { + final.value = nonaborted[0].value; + return nonaborted[0]; + } + final.issues.push({ + code: "invalid_union", + input: final.value, + inst, + errors: results.map((result) => result.issues.map((iss) => finalizeIssue(iss, ctx, config()))) + }); + return final; +} +__name(handleUnionResults, "handleUnionResults"); +var \$ZodUnion = /* @__PURE__ */ \$constructor("\$ZodUnion", (inst, def) => { + \$ZodType.init(inst, def); + defineLazy(inst._zod, "optin", () => def.options.some((o) => o._zod.optin === "optional") ? "optional" : void 0); + defineLazy(inst._zod, "optout", () => def.options.some((o) => o._zod.optout === "optional") ? "optional" : void 0); + defineLazy(inst._zod, "values", () => { + if (def.options.every((o) => o._zod.values)) { + return new Set(def.options.flatMap((option) => Array.from(option._zod.values))); + } + return void 0; + }); + defineLazy(inst._zod, "pattern", () => { + if (def.options.every((o) => o._zod.pattern)) { + const patterns = def.options.map((o) => o._zod.pattern); + return new RegExp(\`^(\${patterns.map((p) => cleanRegex(p.source)).join("|")})\$\`); + } + return void 0; + }); + const single = def.options.length === 1; + const first = def.options[0]._zod.run; + inst._zod.parse = (payload, ctx) => { + if (single) { + return first(payload, ctx); + } + let async = false; + const results = []; + for (const option of def.options) { + const result = option._zod.run({ + value: payload.value, + issues: [] + }, ctx); + if (result instanceof Promise) { + results.push(result); + async = true; + } else { + if (result.issues.length === 0) return result; + results.push(result); + } + } + if (!async) return handleUnionResults(results, payload, inst, ctx); + return Promise.all(results).then((results2) => { + return handleUnionResults(results2, payload, inst, ctx); + }); + }; +}); +var \$ZodDiscriminatedUnion = /* @__PURE__ */ \$constructor("\$ZodDiscriminatedUnion", (inst, def) => { + \$ZodUnion.init(inst, def); + const _super = inst._zod.parse; + defineLazy(inst._zod, "propValues", () => { + const propValues = {}; + for (const option of def.options) { + const pv = option._zod.propValues; + if (!pv || Object.keys(pv).length === 0) throw new Error(\`Invalid discriminated union option at index "\${def.options.indexOf(option)}"\`); + for (const [k, v] of Object.entries(pv)) { + if (!propValues[k]) propValues[k] = /* @__PURE__ */ new Set(); + for (const val of v) { + propValues[k].add(val); + } + } + } + return propValues; + }); + const disc = cached(() => { + const opts = def.options; + const map2 = /* @__PURE__ */ new Map(); + for (const o of opts) { + const values = o._zod.propValues?.[def.discriminator]; + if (!values || values.size === 0) throw new Error(\`Invalid discriminated union option at index "\${def.options.indexOf(o)}"\`); + for (const v of values) { + if (map2.has(v)) { + throw new Error(\`Duplicate discriminator value "\${String(v)}"\`); + } + map2.set(v, o); + } + } + return map2; + }); + inst._zod.parse = (payload, ctx) => { + const input = payload.value; + if (!isObject(input)) { + payload.issues.push({ + code: "invalid_type", + expected: "object", + input, + inst + }); + return payload; + } + const opt = disc.value.get(input?.[def.discriminator]); + if (opt) { + return opt._zod.run(payload, ctx); + } + if (def.unionFallback) { + return _super(payload, ctx); + } + payload.issues.push({ + code: "invalid_union", + errors: [], + note: "No matching discriminator", + discriminator: def.discriminator, + input, + path: [ + def.discriminator + ], + inst + }); + return payload; + }; +}); +var \$ZodIntersection = /* @__PURE__ */ \$constructor("\$ZodIntersection", (inst, def) => { + \$ZodType.init(inst, def); + inst._zod.parse = (payload, ctx) => { + const input = payload.value; + const left = def.left._zod.run({ + value: input, + issues: [] + }, ctx); + const right = def.right._zod.run({ + value: input, + issues: [] + }, ctx); + const async = left instanceof Promise || right instanceof Promise; + if (async) { + return Promise.all([ + left, + right + ]).then(([left2, right2]) => { + return handleIntersectionResults(payload, left2, right2); + }); + } + return handleIntersectionResults(payload, left, right); + }; +}); +function mergeValues(a, b) { + if (a === b) { + return { + valid: true, + data: a + }; + } + if (a instanceof Date && b instanceof Date && +a === +b) { + return { + valid: true, + data: a + }; + } + if (isPlainObject(a) && isPlainObject(b)) { + const bKeys = Object.keys(b); + const sharedKeys = Object.keys(a).filter((key) => bKeys.indexOf(key) !== -1); + const newObj = { + ...a, + ...b + }; + for (const key of sharedKeys) { + const sharedValue = mergeValues(a[key], b[key]); + if (!sharedValue.valid) { + return { + valid: false, + mergeErrorPath: [ + key, + ...sharedValue.mergeErrorPath + ] + }; + } + newObj[key] = sharedValue.data; + } + return { + valid: true, + data: newObj + }; + } + if (Array.isArray(a) && Array.isArray(b)) { + if (a.length !== b.length) { + return { + valid: false, + mergeErrorPath: [] + }; + } + const newArray = []; + for (let index = 0; index < a.length; index++) { + const itemA = a[index]; + const itemB = b[index]; + const sharedValue = mergeValues(itemA, itemB); + if (!sharedValue.valid) { + return { + valid: false, + mergeErrorPath: [ + index, + ...sharedValue.mergeErrorPath + ] + }; + } + newArray.push(sharedValue.data); + } + return { + valid: true, + data: newArray + }; + } + return { + valid: false, + mergeErrorPath: [] + }; +} +__name(mergeValues, "mergeValues"); +function handleIntersectionResults(result, left, right) { + if (left.issues.length) { + result.issues.push(...left.issues); + } + if (right.issues.length) { + result.issues.push(...right.issues); + } + if (aborted(result)) return result; + const merged = mergeValues(left.value, right.value); + if (!merged.valid) { + throw new Error(\`Unmergable intersection. Error path: \${JSON.stringify(merged.mergeErrorPath)}\`); + } + result.value = merged.data; + return result; +} +__name(handleIntersectionResults, "handleIntersectionResults"); +var \$ZodTuple = /* @__PURE__ */ \$constructor("\$ZodTuple", (inst, def) => { + \$ZodType.init(inst, def); + const items = def.items; + const optStart = items.length - [ + ...items + ].reverse().findIndex((item) => item._zod.optin !== "optional"); + inst._zod.parse = (payload, ctx) => { + const input = payload.value; + if (!Array.isArray(input)) { + payload.issues.push({ + input, + inst, + expected: "tuple", + code: "invalid_type" + }); + return payload; + } + payload.value = []; + const proms = []; + if (!def.rest) { + const tooBig = input.length > items.length; + const tooSmall = input.length < optStart - 1; + if (tooBig || tooSmall) { + payload.issues.push({ + ...tooBig ? { + code: "too_big", + maximum: items.length + } : { + code: "too_small", + minimum: items.length + }, + input, + inst, + origin: "array" + }); + return payload; + } + } + let i = -1; + for (const item of items) { + i++; + if (i >= input.length) { + if (i >= optStart) continue; + } + const result = item._zod.run({ + value: input[i], + issues: [] + }, ctx); + if (result instanceof Promise) { + proms.push(result.then((result2) => handleTupleResult(result2, payload, i))); + } else { + handleTupleResult(result, payload, i); + } + } + if (def.rest) { + const rest = input.slice(items.length); + for (const el of rest) { + i++; + const result = def.rest._zod.run({ + value: el, + issues: [] + }, ctx); + if (result instanceof Promise) { + proms.push(result.then((result2) => handleTupleResult(result2, payload, i))); + } else { + handleTupleResult(result, payload, i); + } + } + } + if (proms.length) return Promise.all(proms).then(() => payload); + return payload; + }; +}); +function handleTupleResult(result, final, index) { + if (result.issues.length) { + final.issues.push(...prefixIssues(index, result.issues)); + } + final.value[index] = result.value; +} +__name(handleTupleResult, "handleTupleResult"); +var \$ZodRecord = /* @__PURE__ */ \$constructor("\$ZodRecord", (inst, def) => { + \$ZodType.init(inst, def); + inst._zod.parse = (payload, ctx) => { + const input = payload.value; + if (!isPlainObject(input)) { + payload.issues.push({ + expected: "record", + code: "invalid_type", + input, + inst + }); + return payload; + } + const proms = []; + if (def.keyType._zod.values) { + const values = def.keyType._zod.values; + payload.value = {}; + for (const key of values) { + if (typeof key === "string" || typeof key === "number" || typeof key === "symbol") { + const result = def.valueType._zod.run({ + value: input[key], + issues: [] + }, ctx); + if (result instanceof Promise) { + proms.push(result.then((result2) => { + if (result2.issues.length) { + payload.issues.push(...prefixIssues(key, result2.issues)); + } + payload.value[key] = result2.value; + })); + } else { + if (result.issues.length) { + payload.issues.push(...prefixIssues(key, result.issues)); + } + payload.value[key] = result.value; + } + } + } + let unrecognized; + for (const key in input) { + if (!values.has(key)) { + unrecognized = unrecognized ?? []; + unrecognized.push(key); + } + } + if (unrecognized && unrecognized.length > 0) { + payload.issues.push({ + code: "unrecognized_keys", + input, + inst, + keys: unrecognized + }); + } + } else { + payload.value = {}; + for (const key of Reflect.ownKeys(input)) { + if (key === "__proto__") continue; + const keyResult = def.keyType._zod.run({ + value: key, + issues: [] + }, ctx); + if (keyResult instanceof Promise) { + throw new Error("Async schemas not supported in object keys currently"); + } + if (keyResult.issues.length) { + payload.issues.push({ + code: "invalid_key", + origin: "record", + issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config())), + input: key, + path: [ + key + ], + inst + }); + payload.value[keyResult.value] = keyResult.value; + continue; + } + const result = def.valueType._zod.run({ + value: input[key], + issues: [] + }, ctx); + if (result instanceof Promise) { + proms.push(result.then((result2) => { + if (result2.issues.length) { + payload.issues.push(...prefixIssues(key, result2.issues)); + } + payload.value[keyResult.value] = result2.value; + })); + } else { + if (result.issues.length) { + payload.issues.push(...prefixIssues(key, result.issues)); + } + payload.value[keyResult.value] = result.value; + } + } + } + if (proms.length) { + return Promise.all(proms).then(() => payload); + } + return payload; + }; +}); +var \$ZodMap = /* @__PURE__ */ \$constructor("\$ZodMap", (inst, def) => { + \$ZodType.init(inst, def); + inst._zod.parse = (payload, ctx) => { + const input = payload.value; + if (!(input instanceof Map)) { + payload.issues.push({ + expected: "map", + code: "invalid_type", + input, + inst + }); + return payload; + } + const proms = []; + payload.value = /* @__PURE__ */ new Map(); + for (const [key, value] of input) { + const keyResult = def.keyType._zod.run({ + value: key, + issues: [] + }, ctx); + const valueResult = def.valueType._zod.run({ + value, + issues: [] + }, ctx); + if (keyResult instanceof Promise || valueResult instanceof Promise) { + proms.push(Promise.all([ + keyResult, + valueResult + ]).then(([keyResult2, valueResult2]) => { + handleMapResult(keyResult2, valueResult2, payload, key, input, inst, ctx); + })); + } else { + handleMapResult(keyResult, valueResult, payload, key, input, inst, ctx); + } + } + if (proms.length) return Promise.all(proms).then(() => payload); + return payload; + }; +}); +function handleMapResult(keyResult, valueResult, final, key, input, inst, ctx) { + if (keyResult.issues.length) { + if (propertyKeyTypes.has(typeof key)) { + final.issues.push(...prefixIssues(key, keyResult.issues)); + } else { + final.issues.push({ + code: "invalid_key", + origin: "map", + input, + inst, + issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config())) + }); + } + } + if (valueResult.issues.length) { + if (propertyKeyTypes.has(typeof key)) { + final.issues.push(...prefixIssues(key, valueResult.issues)); + } else { + final.issues.push({ + origin: "map", + code: "invalid_element", + input, + inst, + key, + issues: valueResult.issues.map((iss) => finalizeIssue(iss, ctx, config())) + }); + } + } + final.value.set(keyResult.value, valueResult.value); +} +__name(handleMapResult, "handleMapResult"); +var \$ZodSet = /* @__PURE__ */ \$constructor("\$ZodSet", (inst, def) => { + \$ZodType.init(inst, def); + inst._zod.parse = (payload, ctx) => { + const input = payload.value; + if (!(input instanceof Set)) { + payload.issues.push({ + input, + inst, + expected: "set", + code: "invalid_type" + }); + return payload; + } + const proms = []; + payload.value = /* @__PURE__ */ new Set(); + for (const item of input) { + const result = def.valueType._zod.run({ + value: item, + issues: [] + }, ctx); + if (result instanceof Promise) { + proms.push(result.then((result2) => handleSetResult(result2, payload))); + } else handleSetResult(result, payload); + } + if (proms.length) return Promise.all(proms).then(() => payload); + return payload; + }; +}); +function handleSetResult(result, final) { + if (result.issues.length) { + final.issues.push(...result.issues); + } + final.value.add(result.value); +} +__name(handleSetResult, "handleSetResult"); +var \$ZodEnum = /* @__PURE__ */ \$constructor("\$ZodEnum", (inst, def) => { + \$ZodType.init(inst, def); + const values = getEnumValues(def.entries); + const valuesSet = new Set(values); + inst._zod.values = valuesSet; + inst._zod.pattern = new RegExp(\`^(\${values.filter((k) => propertyKeyTypes.has(typeof k)).map((o) => typeof o === "string" ? escapeRegex(o) : o.toString()).join("|")})\$\`); + inst._zod.parse = (payload, _ctx) => { + const input = payload.value; + if (valuesSet.has(input)) { + return payload; + } + payload.issues.push({ + code: "invalid_value", + values, + input, + inst + }); + return payload; + }; +}); +var \$ZodLiteral = /* @__PURE__ */ \$constructor("\$ZodLiteral", (inst, def) => { + \$ZodType.init(inst, def); + if (def.values.length === 0) { + throw new Error("Cannot create literal schema with no valid values"); + } + inst._zod.values = new Set(def.values); + inst._zod.pattern = new RegExp(\`^(\${def.values.map((o) => typeof o === "string" ? escapeRegex(o) : o ? escapeRegex(o.toString()) : String(o)).join("|")})\$\`); + inst._zod.parse = (payload, _ctx) => { + const input = payload.value; + if (inst._zod.values.has(input)) { + return payload; + } + payload.issues.push({ + code: "invalid_value", + values: def.values, + input, + inst + }); + return payload; + }; +}); +var \$ZodFile = /* @__PURE__ */ \$constructor("\$ZodFile", (inst, def) => { + \$ZodType.init(inst, def); + inst._zod.parse = (payload, _ctx) => { + const input = payload.value; + if (input instanceof File) return payload; + payload.issues.push({ + expected: "file", + code: "invalid_type", + input, + inst + }); + return payload; + }; +}); +var \$ZodTransform = /* @__PURE__ */ \$constructor("\$ZodTransform", (inst, def) => { + \$ZodType.init(inst, def); + inst._zod.parse = (payload, ctx) => { + if (ctx.direction === "backward") { + throw new \$ZodEncodeError(inst.constructor.name); + } + const _out = def.transform(payload.value, payload); + if (ctx.async) { + const output = _out instanceof Promise ? _out : Promise.resolve(_out); + return output.then((output2) => { + payload.value = output2; + return payload; + }); + } + if (_out instanceof Promise) { + throw new \$ZodAsyncError(); + } + payload.value = _out; + return payload; + }; +}); +function handleOptionalResult(result, input) { + if (result.issues.length && input === void 0) { + return { + issues: [], + value: void 0 + }; + } + return result; +} +__name(handleOptionalResult, "handleOptionalResult"); +var \$ZodOptional = /* @__PURE__ */ \$constructor("\$ZodOptional", (inst, def) => { + \$ZodType.init(inst, def); + inst._zod.optin = "optional"; + inst._zod.optout = "optional"; + defineLazy(inst._zod, "values", () => { + return def.innerType._zod.values ? /* @__PURE__ */ new Set([ + ...def.innerType._zod.values, + void 0 + ]) : void 0; + }); + defineLazy(inst._zod, "pattern", () => { + const pattern = def.innerType._zod.pattern; + return pattern ? new RegExp(\`^(\${cleanRegex(pattern.source)})?\$\`) : void 0; + }); + inst._zod.parse = (payload, ctx) => { + if (def.innerType._zod.optin === "optional") { + const result = def.innerType._zod.run(payload, ctx); + if (result instanceof Promise) return result.then((r) => handleOptionalResult(r, payload.value)); + return handleOptionalResult(result, payload.value); + } + if (payload.value === void 0) { + return payload; + } + return def.innerType._zod.run(payload, ctx); + }; +}); +var \$ZodNullable = /* @__PURE__ */ \$constructor("\$ZodNullable", (inst, def) => { + \$ZodType.init(inst, def); + defineLazy(inst._zod, "optin", () => def.innerType._zod.optin); + defineLazy(inst._zod, "optout", () => def.innerType._zod.optout); + defineLazy(inst._zod, "pattern", () => { + const pattern = def.innerType._zod.pattern; + return pattern ? new RegExp(\`^(\${cleanRegex(pattern.source)}|null)\$\`) : void 0; + }); + defineLazy(inst._zod, "values", () => { + return def.innerType._zod.values ? /* @__PURE__ */ new Set([ + ...def.innerType._zod.values, + null + ]) : void 0; + }); + inst._zod.parse = (payload, ctx) => { + if (payload.value === null) return payload; + return def.innerType._zod.run(payload, ctx); + }; +}); +var \$ZodDefault = /* @__PURE__ */ \$constructor("\$ZodDefault", (inst, def) => { + \$ZodType.init(inst, def); + inst._zod.optin = "optional"; + defineLazy(inst._zod, "values", () => def.innerType._zod.values); + inst._zod.parse = (payload, ctx) => { + if (ctx.direction === "backward") { + return def.innerType._zod.run(payload, ctx); + } + if (payload.value === void 0) { + payload.value = def.defaultValue; + return payload; + } + const result = def.innerType._zod.run(payload, ctx); + if (result instanceof Promise) { + return result.then((result2) => handleDefaultResult(result2, def)); + } + return handleDefaultResult(result, def); + }; +}); +function handleDefaultResult(payload, def) { + if (payload.value === void 0) { + payload.value = def.defaultValue; + } + return payload; +} +__name(handleDefaultResult, "handleDefaultResult"); +var \$ZodPrefault = /* @__PURE__ */ \$constructor("\$ZodPrefault", (inst, def) => { + \$ZodType.init(inst, def); + inst._zod.optin = "optional"; + defineLazy(inst._zod, "values", () => def.innerType._zod.values); + inst._zod.parse = (payload, ctx) => { + if (ctx.direction === "backward") { + return def.innerType._zod.run(payload, ctx); + } + if (payload.value === void 0) { + payload.value = def.defaultValue; + } + return def.innerType._zod.run(payload, ctx); + }; +}); +var \$ZodNonOptional = /* @__PURE__ */ \$constructor("\$ZodNonOptional", (inst, def) => { + \$ZodType.init(inst, def); + defineLazy(inst._zod, "values", () => { + const v = def.innerType._zod.values; + return v ? new Set([ + ...v + ].filter((x) => x !== void 0)) : void 0; + }); + inst._zod.parse = (payload, ctx) => { + const result = def.innerType._zod.run(payload, ctx); + if (result instanceof Promise) { + return result.then((result2) => handleNonOptionalResult(result2, inst)); + } + return handleNonOptionalResult(result, inst); + }; +}); +function handleNonOptionalResult(payload, inst) { + if (!payload.issues.length && payload.value === void 0) { + payload.issues.push({ + code: "invalid_type", + expected: "nonoptional", + input: payload.value, + inst + }); + } + return payload; +} +__name(handleNonOptionalResult, "handleNonOptionalResult"); +var \$ZodSuccess = /* @__PURE__ */ \$constructor("\$ZodSuccess", (inst, def) => { + \$ZodType.init(inst, def); + inst._zod.parse = (payload, ctx) => { + if (ctx.direction === "backward") { + throw new \$ZodEncodeError("ZodSuccess"); + } + const result = def.innerType._zod.run(payload, ctx); + if (result instanceof Promise) { + return result.then((result2) => { + payload.value = result2.issues.length === 0; + return payload; + }); + } + payload.value = result.issues.length === 0; + return payload; + }; +}); +var \$ZodCatch = /* @__PURE__ */ \$constructor("\$ZodCatch", (inst, def) => { + \$ZodType.init(inst, def); + defineLazy(inst._zod, "optin", () => def.innerType._zod.optin); + defineLazy(inst._zod, "optout", () => def.innerType._zod.optout); + defineLazy(inst._zod, "values", () => def.innerType._zod.values); + inst._zod.parse = (payload, ctx) => { + if (ctx.direction === "backward") { + return def.innerType._zod.run(payload, ctx); + } + const result = def.innerType._zod.run(payload, ctx); + if (result instanceof Promise) { + return result.then((result2) => { + payload.value = result2.value; + if (result2.issues.length) { + payload.value = def.catchValue({ + ...payload, + error: { + issues: result2.issues.map((iss) => finalizeIssue(iss, ctx, config())) + }, + input: payload.value + }); + payload.issues = []; + } + return payload; + }); + } + payload.value = result.value; + if (result.issues.length) { + payload.value = def.catchValue({ + ...payload, + error: { + issues: result.issues.map((iss) => finalizeIssue(iss, ctx, config())) + }, + input: payload.value + }); + payload.issues = []; + } + return payload; + }; +}); +var \$ZodNaN = /* @__PURE__ */ \$constructor("\$ZodNaN", (inst, def) => { + \$ZodType.init(inst, def); + inst._zod.parse = (payload, _ctx) => { + if (typeof payload.value !== "number" || !Number.isNaN(payload.value)) { + payload.issues.push({ + input: payload.value, + inst, + expected: "nan", + code: "invalid_type" + }); + return payload; + } + return payload; + }; +}); +var \$ZodPipe = /* @__PURE__ */ \$constructor("\$ZodPipe", (inst, def) => { + \$ZodType.init(inst, def); + defineLazy(inst._zod, "values", () => def.in._zod.values); + defineLazy(inst._zod, "optin", () => def.in._zod.optin); + defineLazy(inst._zod, "optout", () => def.out._zod.optout); + defineLazy(inst._zod, "propValues", () => def.in._zod.propValues); + inst._zod.parse = (payload, ctx) => { + if (ctx.direction === "backward") { + const right = def.out._zod.run(payload, ctx); + if (right instanceof Promise) { + return right.then((right2) => handlePipeResult(right2, def.in, ctx)); + } + return handlePipeResult(right, def.in, ctx); + } + const left = def.in._zod.run(payload, ctx); + if (left instanceof Promise) { + return left.then((left2) => handlePipeResult(left2, def.out, ctx)); + } + return handlePipeResult(left, def.out, ctx); + }; +}); +function handlePipeResult(left, next, ctx) { + if (left.issues.length) { + left.aborted = true; + return left; + } + return next._zod.run({ + value: left.value, + issues: left.issues + }, ctx); +} +__name(handlePipeResult, "handlePipeResult"); +var \$ZodCodec = /* @__PURE__ */ \$constructor("\$ZodCodec", (inst, def) => { + \$ZodType.init(inst, def); + defineLazy(inst._zod, "values", () => def.in._zod.values); + defineLazy(inst._zod, "optin", () => def.in._zod.optin); + defineLazy(inst._zod, "optout", () => def.out._zod.optout); + defineLazy(inst._zod, "propValues", () => def.in._zod.propValues); + inst._zod.parse = (payload, ctx) => { + const direction = ctx.direction || "forward"; + if (direction === "forward") { + const left = def.in._zod.run(payload, ctx); + if (left instanceof Promise) { + return left.then((left2) => handleCodecAResult(left2, def, ctx)); + } + return handleCodecAResult(left, def, ctx); + } else { + const right = def.out._zod.run(payload, ctx); + if (right instanceof Promise) { + return right.then((right2) => handleCodecAResult(right2, def, ctx)); + } + return handleCodecAResult(right, def, ctx); + } + }; +}); +function handleCodecAResult(result, def, ctx) { + if (result.issues.length) { + result.aborted = true; + return result; + } + const direction = ctx.direction || "forward"; + if (direction === "forward") { + const transformed = def.transform(result.value, result); + if (transformed instanceof Promise) { + return transformed.then((value) => handleCodecTxResult(result, value, def.out, ctx)); + } + return handleCodecTxResult(result, transformed, def.out, ctx); + } else { + const transformed = def.reverseTransform(result.value, result); + if (transformed instanceof Promise) { + return transformed.then((value) => handleCodecTxResult(result, value, def.in, ctx)); + } + return handleCodecTxResult(result, transformed, def.in, ctx); + } +} +__name(handleCodecAResult, "handleCodecAResult"); +function handleCodecTxResult(left, value, nextSchema, ctx) { + if (left.issues.length) { + left.aborted = true; + return left; + } + return nextSchema._zod.run({ + value, + issues: left.issues + }, ctx); +} +__name(handleCodecTxResult, "handleCodecTxResult"); +var \$ZodReadonly = /* @__PURE__ */ \$constructor("\$ZodReadonly", (inst, def) => { + \$ZodType.init(inst, def); + defineLazy(inst._zod, "propValues", () => def.innerType._zod.propValues); + defineLazy(inst._zod, "values", () => def.innerType._zod.values); + defineLazy(inst._zod, "optin", () => def.innerType._zod.optin); + defineLazy(inst._zod, "optout", () => def.innerType._zod.optout); + inst._zod.parse = (payload, ctx) => { + if (ctx.direction === "backward") { + return def.innerType._zod.run(payload, ctx); + } + const result = def.innerType._zod.run(payload, ctx); + if (result instanceof Promise) { + return result.then(handleReadonlyResult); + } + return handleReadonlyResult(result); + }; +}); +function handleReadonlyResult(payload) { + payload.value = Object.freeze(payload.value); + return payload; +} +__name(handleReadonlyResult, "handleReadonlyResult"); +var \$ZodTemplateLiteral = /* @__PURE__ */ \$constructor("\$ZodTemplateLiteral", (inst, def) => { + \$ZodType.init(inst, def); + const regexParts = []; + for (const part of def.parts) { + if (typeof part === "object" && part !== null) { + if (!part._zod.pattern) { + throw new Error(\`Invalid template literal part, no pattern found: \${[ + ...part._zod.traits + ].shift()}\`); + } + const source = part._zod.pattern instanceof RegExp ? part._zod.pattern.source : part._zod.pattern; + if (!source) throw new Error(\`Invalid template literal part: \${part._zod.traits}\`); + const start = source.startsWith("^") ? 1 : 0; + const end = source.endsWith("\$") ? source.length - 1 : source.length; + regexParts.push(source.slice(start, end)); + } else if (part === null || primitiveTypes.has(typeof part)) { + regexParts.push(escapeRegex(\`\${part}\`)); + } else { + throw new Error(\`Invalid template literal part: \${part}\`); + } + } + inst._zod.pattern = new RegExp(\`^\${regexParts.join("")}\$\`); + inst._zod.parse = (payload, _ctx) => { + if (typeof payload.value !== "string") { + payload.issues.push({ + input: payload.value, + inst, + expected: "template_literal", + code: "invalid_type" + }); + return payload; + } + inst._zod.pattern.lastIndex = 0; + if (!inst._zod.pattern.test(payload.value)) { + payload.issues.push({ + input: payload.value, + inst, + code: "invalid_format", + format: def.format ?? "template_literal", + pattern: inst._zod.pattern.source + }); + return payload; + } + return payload; + }; +}); +var \$ZodFunction = /* @__PURE__ */ \$constructor("\$ZodFunction", (inst, def) => { + \$ZodType.init(inst, def); + inst._def = def; + inst._zod.def = def; + inst.implement = (func) => { + if (typeof func !== "function") { + throw new Error("implement() must be called with a function"); + } + return function(...args) { + const parsedArgs = inst._def.input ? parse(inst._def.input, args) : args; + const result = Reflect.apply(func, this, parsedArgs); + if (inst._def.output) { + return parse(inst._def.output, result); + } + return result; + }; + }; + inst.implementAsync = (func) => { + if (typeof func !== "function") { + throw new Error("implementAsync() must be called with a function"); + } + return async function(...args) { + const parsedArgs = inst._def.input ? await parseAsync(inst._def.input, args) : args; + const result = await Reflect.apply(func, this, parsedArgs); + if (inst._def.output) { + return await parseAsync(inst._def.output, result); + } + return result; + }; + }; + inst._zod.parse = (payload, _ctx) => { + if (typeof payload.value !== "function") { + payload.issues.push({ + code: "invalid_type", + expected: "function", + input: payload.value, + inst + }); + return payload; + } + const hasPromiseOutput = inst._def.output && inst._def.output._zod.def.type === "promise"; + if (hasPromiseOutput) { + payload.value = inst.implementAsync(payload.value); + } else { + payload.value = inst.implement(payload.value); + } + return payload; + }; + inst.input = (...args) => { + const F = inst.constructor; + if (Array.isArray(args[0])) { + return new F({ + type: "function", + input: new \$ZodTuple({ + type: "tuple", + items: args[0], + rest: args[1] + }), + output: inst._def.output + }); + } + return new F({ + type: "function", + input: args[0], + output: inst._def.output + }); + }; + inst.output = (output) => { + const F = inst.constructor; + return new F({ + type: "function", + input: inst._def.input, + output + }); + }; + return inst; +}); +var \$ZodPromise = /* @__PURE__ */ \$constructor("\$ZodPromise", (inst, def) => { + \$ZodType.init(inst, def); + inst._zod.parse = (payload, ctx) => { + return Promise.resolve(payload.value).then((inner) => def.innerType._zod.run({ + value: inner, + issues: [] + }, ctx)); + }; +}); +var \$ZodLazy = /* @__PURE__ */ \$constructor("\$ZodLazy", (inst, def) => { + \$ZodType.init(inst, def); + defineLazy(inst._zod, "innerType", () => def.getter()); + defineLazy(inst._zod, "pattern", () => inst._zod.innerType._zod.pattern); + defineLazy(inst._zod, "propValues", () => inst._zod.innerType._zod.propValues); + defineLazy(inst._zod, "optin", () => inst._zod.innerType._zod.optin ?? void 0); + defineLazy(inst._zod, "optout", () => inst._zod.innerType._zod.optout ?? void 0); + inst._zod.parse = (payload, ctx) => { + const inner = inst._zod.innerType; + return inner._zod.run(payload, ctx); + }; +}); +var \$ZodCustom = /* @__PURE__ */ \$constructor("\$ZodCustom", (inst, def) => { + \$ZodCheck.init(inst, def); + \$ZodType.init(inst, def); + inst._zod.parse = (payload, _) => { + return payload; + }; + inst._zod.check = (payload) => { + const input = payload.value; + const r = def.fn(input); + if (r instanceof Promise) { + return r.then((r2) => handleRefineResult(r2, payload, input, inst)); + } + handleRefineResult(r, payload, input, inst); + return; + }; +}); +function handleRefineResult(result, payload, input, inst) { + if (!result) { + const _iss = { + code: "custom", + input, + inst, + path: [ + ...inst._zod.def.path ?? [] + ], + continue: !inst._zod.def.abort + }; + if (inst._zod.def.params) _iss.params = inst._zod.def.params; + payload.issues.push(issue(_iss)); + } +} +__name(handleRefineResult, "handleRefineResult"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/index.js +var locales_exports = {}; +__export(locales_exports, { + ar: () => ar_default, + az: () => az_default, + be: () => be_default, + ca: () => ca_default, + cs: () => cs_default, + da: () => da_default, + de: () => de_default, + en: () => en_default, + eo: () => eo_default, + es: () => es_default, + fa: () => fa_default, + fi: () => fi_default, + fr: () => fr_default, + frCA: () => fr_CA_default, + he: () => he_default, + hu: () => hu_default, + id: () => id_default, + is: () => is_default, + it: () => it_default, + ja: () => ja_default, + ka: () => ka_default, + kh: () => kh_default, + km: () => km_default, + ko: () => ko_default, + lt: () => lt_default, + mk: () => mk_default, + ms: () => ms_default, + nl: () => nl_default, + no: () => no_default, + ota: () => ota_default, + pl: () => pl_default, + ps: () => ps_default, + pt: () => pt_default, + ru: () => ru_default, + sl: () => sl_default, + sv: () => sv_default, + ta: () => ta_default, + th: () => th_default, + tr: () => tr_default, + ua: () => ua_default, + uk: () => uk_default, + ur: () => ur_default, + vi: () => vi_default, + yo: () => yo_default, + zhCN: () => zh_CN_default, + zhTW: () => zh_TW_default +}); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/ar.js +var error = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "\\u062D\\u0631\\u0641", + verb: "\\u0623\\u0646 \\u064A\\u062D\\u0648\\u064A" + }, + file: { + unit: "\\u0628\\u0627\\u064A\\u062A", + verb: "\\u0623\\u0646 \\u064A\\u062D\\u0648\\u064A" + }, + array: { + unit: "\\u0639\\u0646\\u0635\\u0631", + verb: "\\u0623\\u0646 \\u064A\\u062D\\u0648\\u064A" + }, + set: { + unit: "\\u0639\\u0646\\u0635\\u0631", + verb: "\\u0623\\u0646 \\u064A\\u062D\\u0648\\u064A" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "number"; + } + case "object": { + if (Array.isArray(data)) { + return "array"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "\\u0645\\u062F\\u062E\\u0644", + email: "\\u0628\\u0631\\u064A\\u062F \\u0625\\u0644\\u0643\\u062A\\u0631\\u0648\\u0646\\u064A", + url: "\\u0631\\u0627\\u0628\\u0637", + emoji: "\\u0625\\u064A\\u0645\\u0648\\u062C\\u064A", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "\\u062A\\u0627\\u0631\\u064A\\u062E \\u0648\\u0648\\u0642\\u062A \\u0628\\u0645\\u0639\\u064A\\u0627\\u0631 ISO", + date: "\\u062A\\u0627\\u0631\\u064A\\u062E \\u0628\\u0645\\u0639\\u064A\\u0627\\u0631 ISO", + time: "\\u0648\\u0642\\u062A \\u0628\\u0645\\u0639\\u064A\\u0627\\u0631 ISO", + duration: "\\u0645\\u062F\\u0629 \\u0628\\u0645\\u0639\\u064A\\u0627\\u0631 ISO", + ipv4: "\\u0639\\u0646\\u0648\\u0627\\u0646 IPv4", + ipv6: "\\u0639\\u0646\\u0648\\u0627\\u0646 IPv6", + cidrv4: "\\u0645\\u062F\\u0649 \\u0639\\u0646\\u0627\\u0648\\u064A\\u0646 \\u0628\\u0635\\u064A\\u063A\\u0629 IPv4", + cidrv6: "\\u0645\\u062F\\u0649 \\u0639\\u0646\\u0627\\u0648\\u064A\\u0646 \\u0628\\u0635\\u064A\\u063A\\u0629 IPv6", + base64: "\\u0646\\u064E\\u0635 \\u0628\\u062A\\u0631\\u0645\\u064A\\u0632 base64-encoded", + base64url: "\\u0646\\u064E\\u0635 \\u0628\\u062A\\u0631\\u0645\\u064A\\u0632 base64url-encoded", + json_string: "\\u0646\\u064E\\u0635 \\u0639\\u0644\\u0649 \\u0647\\u064A\\u0626\\u0629 JSON", + e164: "\\u0631\\u0642\\u0645 \\u0647\\u0627\\u062A\\u0641 \\u0628\\u0645\\u0639\\u064A\\u0627\\u0631 E.164", + jwt: "JWT", + template_literal: "\\u0645\\u062F\\u062E\\u0644" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`\\u0645\\u062F\\u062E\\u0644\\u0627\\u062A \\u063A\\u064A\\u0631 \\u0645\\u0642\\u0628\\u0648\\u0644\\u0629: \\u064A\\u0641\\u062A\\u0631\\u0636 \\u0625\\u062F\\u062E\\u0627\\u0644 \${issue2.expected}\\u060C \\u0648\\u0644\\u0643\\u0646 \\u062A\\u0645 \\u0625\\u062F\\u062E\\u0627\\u0644 \${parsedType7(issue2.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`\\u0645\\u062F\\u062E\\u0644\\u0627\\u062A \\u063A\\u064A\\u0631 \\u0645\\u0642\\u0628\\u0648\\u0644\\u0629: \\u064A\\u0641\\u062A\\u0631\\u0636 \\u0625\\u062F\\u062E\\u0627\\u0644 \${stringifyPrimitive(issue2.values[0])}\`; + return \`\\u0627\\u062E\\u062A\\u064A\\u0627\\u0631 \\u063A\\u064A\\u0631 \\u0645\\u0642\\u0628\\u0648\\u0644: \\u064A\\u062A\\u0648\\u0642\\u0639 \\u0627\\u0646\\u062A\\u0642\\u0627\\u0621 \\u0623\\u062D\\u062F \\u0647\\u0630\\u0647 \\u0627\\u0644\\u062E\\u064A\\u0627\\u0631\\u0627\\u062A: \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) return \` \\u0623\\u0643\\u0628\\u0631 \\u0645\\u0646 \\u0627\\u0644\\u0644\\u0627\\u0632\\u0645: \\u064A\\u0641\\u062A\\u0631\\u0636 \\u0623\\u0646 \\u062A\\u0643\\u0648\\u0646 \${issue2.origin ?? "\\u0627\\u0644\\u0642\\u064A\\u0645\\u0629"} \${adj} \${issue2.maximum.toString()} \${sizing.unit ?? "\\u0639\\u0646\\u0635\\u0631"}\`; + return \`\\u0623\\u0643\\u0628\\u0631 \\u0645\\u0646 \\u0627\\u0644\\u0644\\u0627\\u0632\\u0645: \\u064A\\u0641\\u062A\\u0631\\u0636 \\u0623\\u0646 \\u062A\\u0643\\u0648\\u0646 \${issue2.origin ?? "\\u0627\\u0644\\u0642\\u064A\\u0645\\u0629"} \${adj} \${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`\\u0623\\u0635\\u063A\\u0631 \\u0645\\u0646 \\u0627\\u0644\\u0644\\u0627\\u0632\\u0645: \\u064A\\u0641\\u062A\\u0631\\u0636 \\u0644\\u0640 \${issue2.origin} \\u0623\\u0646 \\u064A\\u0643\\u0648\\u0646 \${adj} \${issue2.minimum.toString()} \${sizing.unit}\`; + } + return \`\\u0623\\u0635\\u063A\\u0631 \\u0645\\u0646 \\u0627\\u0644\\u0644\\u0627\\u0632\\u0645: \\u064A\\u0641\\u062A\\u0631\\u0636 \\u0644\\u0640 \${issue2.origin} \\u0623\\u0646 \\u064A\\u0643\\u0648\\u0646 \${adj} \${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") return \`\\u0646\\u064E\\u0635 \\u063A\\u064A\\u0631 \\u0645\\u0642\\u0628\\u0648\\u0644: \\u064A\\u062C\\u0628 \\u0623\\u0646 \\u064A\\u0628\\u062F\\u0623 \\u0628\\u0640 "\${issue2.prefix}"\`; + if (_issue.format === "ends_with") return \`\\u0646\\u064E\\u0635 \\u063A\\u064A\\u0631 \\u0645\\u0642\\u0628\\u0648\\u0644: \\u064A\\u062C\\u0628 \\u0623\\u0646 \\u064A\\u0646\\u062A\\u0647\\u064A \\u0628\\u0640 "\${_issue.suffix}"\`; + if (_issue.format === "includes") return \`\\u0646\\u064E\\u0635 \\u063A\\u064A\\u0631 \\u0645\\u0642\\u0628\\u0648\\u0644: \\u064A\\u062C\\u0628 \\u0623\\u0646 \\u064A\\u062A\\u0636\\u0645\\u0651\\u064E\\u0646 "\${_issue.includes}"\`; + if (_issue.format === "regex") return \`\\u0646\\u064E\\u0635 \\u063A\\u064A\\u0631 \\u0645\\u0642\\u0628\\u0648\\u0644: \\u064A\\u062C\\u0628 \\u0623\\u0646 \\u064A\\u0637\\u0627\\u0628\\u0642 \\u0627\\u0644\\u0646\\u0645\\u0637 \${_issue.pattern}\`; + return \`\${Nouns[_issue.format] ?? issue2.format} \\u063A\\u064A\\u0631 \\u0645\\u0642\\u0628\\u0648\\u0644\`; + } + case "not_multiple_of": + return \`\\u0631\\u0642\\u0645 \\u063A\\u064A\\u0631 \\u0645\\u0642\\u0628\\u0648\\u0644: \\u064A\\u062C\\u0628 \\u0623\\u0646 \\u064A\\u0643\\u0648\\u0646 \\u0645\\u0646 \\u0645\\u0636\\u0627\\u0639\\u0641\\u0627\\u062A \${issue2.divisor}\`; + case "unrecognized_keys": + return \`\\u0645\\u0639\\u0631\\u0641\${issue2.keys.length > 1 ? "\\u0627\\u062A" : ""} \\u063A\\u0631\\u064A\\u0628\${issue2.keys.length > 1 ? "\\u0629" : ""}: \${joinValues(issue2.keys, "\\u060C ")}\`; + case "invalid_key": + return \`\\u0645\\u0639\\u0631\\u0641 \\u063A\\u064A\\u0631 \\u0645\\u0642\\u0628\\u0648\\u0644 \\u0641\\u064A \${issue2.origin}\`; + case "invalid_union": + return "\\u0645\\u062F\\u062E\\u0644 \\u063A\\u064A\\u0631 \\u0645\\u0642\\u0628\\u0648\\u0644"; + case "invalid_element": + return \`\\u0645\\u062F\\u062E\\u0644 \\u063A\\u064A\\u0631 \\u0645\\u0642\\u0628\\u0648\\u0644 \\u0641\\u064A \${issue2.origin}\`; + default: + return "\\u0645\\u062F\\u062E\\u0644 \\u063A\\u064A\\u0631 \\u0645\\u0642\\u0628\\u0648\\u0644"; + } + }; +}, "error"); +function ar_default() { + return { + localeError: error() + }; +} +__name(ar_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/az.js +var error2 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "simvol", + verb: "olmal\\u0131d\\u0131r" + }, + file: { + unit: "bayt", + verb: "olmal\\u0131d\\u0131r" + }, + array: { + unit: "element", + verb: "olmal\\u0131d\\u0131r" + }, + set: { + unit: "element", + verb: "olmal\\u0131d\\u0131r" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "number"; + } + case "object": { + if (Array.isArray(data)) { + return "array"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "input", + email: "email address", + url: "URL", + emoji: "emoji", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "ISO datetime", + date: "ISO date", + time: "ISO time", + duration: "ISO duration", + ipv4: "IPv4 address", + ipv6: "IPv6 address", + cidrv4: "IPv4 range", + cidrv6: "IPv6 range", + base64: "base64-encoded string", + base64url: "base64url-encoded string", + json_string: "JSON string", + e164: "E.164 number", + jwt: "JWT", + template_literal: "input" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`Yanl\\u0131\\u015F d\\u0259y\\u0259r: g\\xF6zl\\u0259nil\\u0259n \${issue2.expected}, daxil olan \${parsedType7(issue2.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`Yanl\\u0131\\u015F d\\u0259y\\u0259r: g\\xF6zl\\u0259nil\\u0259n \${stringifyPrimitive(issue2.values[0])}\`; + return \`Yanl\\u0131\\u015F se\\xE7im: a\\u015Fa\\u011F\\u0131dak\\u0131lardan biri olmal\\u0131d\\u0131r: \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`\\xC7ox b\\xF6y\\xFCk: g\\xF6zl\\u0259nil\\u0259n \${issue2.origin ?? "d\\u0259y\\u0259r"} \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "element"}\`; + return \`\\xC7ox b\\xF6y\\xFCk: g\\xF6zl\\u0259nil\\u0259n \${issue2.origin ?? "d\\u0259y\\u0259r"} \${adj}\${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`\\xC7ox ki\\xE7ik: g\\xF6zl\\u0259nil\\u0259n \${issue2.origin} \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; + return \`\\xC7ox ki\\xE7ik: g\\xF6zl\\u0259nil\\u0259n \${issue2.origin} \${adj}\${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") return \`Yanl\\u0131\\u015F m\\u0259tn: "\${_issue.prefix}" il\\u0259 ba\\u015Flamal\\u0131d\\u0131r\`; + if (_issue.format === "ends_with") return \`Yanl\\u0131\\u015F m\\u0259tn: "\${_issue.suffix}" il\\u0259 bitm\\u0259lidir\`; + if (_issue.format === "includes") return \`Yanl\\u0131\\u015F m\\u0259tn: "\${_issue.includes}" daxil olmal\\u0131d\\u0131r\`; + if (_issue.format === "regex") return \`Yanl\\u0131\\u015F m\\u0259tn: \${_issue.pattern} \\u015Fablonuna uy\\u011Fun olmal\\u0131d\\u0131r\`; + return \`Yanl\\u0131\\u015F \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`Yanl\\u0131\\u015F \\u0259d\\u0259d: \${issue2.divisor} il\\u0259 b\\xF6l\\xFCn\\u0259 bil\\u0259n olmal\\u0131d\\u0131r\`; + case "unrecognized_keys": + return \`Tan\\u0131nmayan a\\xE7ar\${issue2.keys.length > 1 ? "lar" : ""}: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`\${issue2.origin} daxilind\\u0259 yanl\\u0131\\u015F a\\xE7ar\`; + case "invalid_union": + return "Yanl\\u0131\\u015F d\\u0259y\\u0259r"; + case "invalid_element": + return \`\${issue2.origin} daxilind\\u0259 yanl\\u0131\\u015F d\\u0259y\\u0259r\`; + default: + return \`Yanl\\u0131\\u015F d\\u0259y\\u0259r\`; + } + }; +}, "error"); +function az_default() { + return { + localeError: error2() + }; +} +__name(az_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/be.js +function getBelarusianPlural(count, one, few, many) { + const absCount = Math.abs(count); + const lastDigit = absCount % 10; + const lastTwoDigits = absCount % 100; + if (lastTwoDigits >= 11 && lastTwoDigits <= 19) { + return many; + } + if (lastDigit === 1) { + return one; + } + if (lastDigit >= 2 && lastDigit <= 4) { + return few; + } + return many; +} +__name(getBelarusianPlural, "getBelarusianPlural"); +var error3 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: { + one: "\\u0441\\u0456\\u043C\\u0432\\u0430\\u043B", + few: "\\u0441\\u0456\\u043C\\u0432\\u0430\\u043B\\u044B", + many: "\\u0441\\u0456\\u043C\\u0432\\u0430\\u043B\\u0430\\u045E" + }, + verb: "\\u043C\\u0435\\u0446\\u044C" + }, + array: { + unit: { + one: "\\u044D\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442", + few: "\\u044D\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442\\u044B", + many: "\\u044D\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442\\u0430\\u045E" + }, + verb: "\\u043C\\u0435\\u0446\\u044C" + }, + set: { + unit: { + one: "\\u044D\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442", + few: "\\u044D\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442\\u044B", + many: "\\u044D\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442\\u0430\\u045E" + }, + verb: "\\u043C\\u0435\\u0446\\u044C" + }, + file: { + unit: { + one: "\\u0431\\u0430\\u0439\\u0442", + few: "\\u0431\\u0430\\u0439\\u0442\\u044B", + many: "\\u0431\\u0430\\u0439\\u0442\\u0430\\u045E" + }, + verb: "\\u043C\\u0435\\u0446\\u044C" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "\\u043B\\u0456\\u043A"; + } + case "object": { + if (Array.isArray(data)) { + return "\\u043C\\u0430\\u0441\\u0456\\u045E"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "\\u0443\\u0432\\u043E\\u0434", + email: "email \\u0430\\u0434\\u0440\\u0430\\u0441", + url: "URL", + emoji: "\\u044D\\u043C\\u043E\\u0434\\u0437\\u0456", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "ISO \\u0434\\u0430\\u0442\\u0430 \\u0456 \\u0447\\u0430\\u0441", + date: "ISO \\u0434\\u0430\\u0442\\u0430", + time: "ISO \\u0447\\u0430\\u0441", + duration: "ISO \\u043F\\u0440\\u0430\\u0446\\u044F\\u0433\\u043B\\u0430\\u0441\\u0446\\u044C", + ipv4: "IPv4 \\u0430\\u0434\\u0440\\u0430\\u0441", + ipv6: "IPv6 \\u0430\\u0434\\u0440\\u0430\\u0441", + cidrv4: "IPv4 \\u0434\\u044B\\u044F\\u043F\\u0430\\u0437\\u043E\\u043D", + cidrv6: "IPv6 \\u0434\\u044B\\u044F\\u043F\\u0430\\u0437\\u043E\\u043D", + base64: "\\u0440\\u0430\\u0434\\u043E\\u043A \\u0443 \\u0444\\u0430\\u0440\\u043C\\u0430\\u0446\\u0435 base64", + base64url: "\\u0440\\u0430\\u0434\\u043E\\u043A \\u0443 \\u0444\\u0430\\u0440\\u043C\\u0430\\u0446\\u0435 base64url", + json_string: "JSON \\u0440\\u0430\\u0434\\u043E\\u043A", + e164: "\\u043D\\u0443\\u043C\\u0430\\u0440 E.164", + jwt: "JWT", + template_literal: "\\u0443\\u0432\\u043E\\u0434" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`\\u041D\\u044F\\u043F\\u0440\\u0430\\u0432\\u0456\\u043B\\u044C\\u043D\\u044B \\u045E\\u0432\\u043E\\u0434: \\u0447\\u0430\\u043A\\u0430\\u045E\\u0441\\u044F \${issue2.expected}, \\u0430\\u0442\\u0440\\u044B\\u043C\\u0430\\u043D\\u0430 \${parsedType7(issue2.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`\\u041D\\u044F\\u043F\\u0440\\u0430\\u0432\\u0456\\u043B\\u044C\\u043D\\u044B \\u045E\\u0432\\u043E\\u0434: \\u0447\\u0430\\u043A\\u0430\\u043B\\u0430\\u0441\\u044F \${stringifyPrimitive(issue2.values[0])}\`; + return \`\\u041D\\u044F\\u043F\\u0440\\u0430\\u0432\\u0456\\u043B\\u044C\\u043D\\u044B \\u0432\\u0430\\u0440\\u044B\\u044F\\u043D\\u0442: \\u0447\\u0430\\u043A\\u0430\\u045E\\u0441\\u044F \\u0430\\u0434\\u0437\\u0456\\u043D \\u0437 \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) { + const maxValue = Number(issue2.maximum); + const unit = getBelarusianPlural(maxValue, sizing.unit.one, sizing.unit.few, sizing.unit.many); + return \`\\u0417\\u0430\\u043D\\u0430\\u0434\\u0442\\u0430 \\u0432\\u044F\\u043B\\u0456\\u043A\\u0456: \\u0447\\u0430\\u043A\\u0430\\u043B\\u0430\\u0441\\u044F, \\u0448\\u0442\\u043E \${issue2.origin ?? "\\u0437\\u043D\\u0430\\u0447\\u044D\\u043D\\u043D\\u0435"} \\u043F\\u0430\\u0432\\u0456\\u043D\\u043D\\u0430 \${sizing.verb} \${adj}\${issue2.maximum.toString()} \${unit}\`; + } + return \`\\u0417\\u0430\\u043D\\u0430\\u0434\\u0442\\u0430 \\u0432\\u044F\\u043B\\u0456\\u043A\\u0456: \\u0447\\u0430\\u043A\\u0430\\u043B\\u0430\\u0441\\u044F, \\u0448\\u0442\\u043E \${issue2.origin ?? "\\u0437\\u043D\\u0430\\u0447\\u044D\\u043D\\u043D\\u0435"} \\u043F\\u0430\\u0432\\u0456\\u043D\\u043D\\u0430 \\u0431\\u044B\\u0446\\u044C \${adj}\${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + const minValue = Number(issue2.minimum); + const unit = getBelarusianPlural(minValue, sizing.unit.one, sizing.unit.few, sizing.unit.many); + return \`\\u0417\\u0430\\u043D\\u0430\\u0434\\u0442\\u0430 \\u043C\\u0430\\u043B\\u044B: \\u0447\\u0430\\u043A\\u0430\\u043B\\u0430\\u0441\\u044F, \\u0448\\u0442\\u043E \${issue2.origin} \\u043F\\u0430\\u0432\\u0456\\u043D\\u043D\\u0430 \${sizing.verb} \${adj}\${issue2.minimum.toString()} \${unit}\`; + } + return \`\\u0417\\u0430\\u043D\\u0430\\u0434\\u0442\\u0430 \\u043C\\u0430\\u043B\\u044B: \\u0447\\u0430\\u043A\\u0430\\u043B\\u0430\\u0441\\u044F, \\u0448\\u0442\\u043E \${issue2.origin} \\u043F\\u0430\\u0432\\u0456\\u043D\\u043D\\u0430 \\u0431\\u044B\\u0446\\u044C \${adj}\${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") return \`\\u041D\\u044F\\u043F\\u0440\\u0430\\u0432\\u0456\\u043B\\u044C\\u043D\\u044B \\u0440\\u0430\\u0434\\u043E\\u043A: \\u043F\\u0430\\u0432\\u0456\\u043D\\u0435\\u043D \\u043F\\u0430\\u0447\\u044B\\u043D\\u0430\\u0446\\u0446\\u0430 \\u0437 "\${_issue.prefix}"\`; + if (_issue.format === "ends_with") return \`\\u041D\\u044F\\u043F\\u0440\\u0430\\u0432\\u0456\\u043B\\u044C\\u043D\\u044B \\u0440\\u0430\\u0434\\u043E\\u043A: \\u043F\\u0430\\u0432\\u0456\\u043D\\u0435\\u043D \\u0437\\u0430\\u043A\\u0430\\u043D\\u0447\\u0432\\u0430\\u0446\\u0446\\u0430 \\u043D\\u0430 "\${_issue.suffix}"\`; + if (_issue.format === "includes") return \`\\u041D\\u044F\\u043F\\u0440\\u0430\\u0432\\u0456\\u043B\\u044C\\u043D\\u044B \\u0440\\u0430\\u0434\\u043E\\u043A: \\u043F\\u0430\\u0432\\u0456\\u043D\\u0435\\u043D \\u0437\\u043C\\u044F\\u0448\\u0447\\u0430\\u0446\\u044C "\${_issue.includes}"\`; + if (_issue.format === "regex") return \`\\u041D\\u044F\\u043F\\u0440\\u0430\\u0432\\u0456\\u043B\\u044C\\u043D\\u044B \\u0440\\u0430\\u0434\\u043E\\u043A: \\u043F\\u0430\\u0432\\u0456\\u043D\\u0435\\u043D \\u0430\\u0434\\u043F\\u0430\\u0432\\u044F\\u0434\\u0430\\u0446\\u044C \\u0448\\u0430\\u0431\\u043B\\u043E\\u043D\\u0443 \${_issue.pattern}\`; + return \`\\u041D\\u044F\\u043F\\u0440\\u0430\\u0432\\u0456\\u043B\\u044C\\u043D\\u044B \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`\\u041D\\u044F\\u043F\\u0440\\u0430\\u0432\\u0456\\u043B\\u044C\\u043D\\u044B \\u043B\\u0456\\u043A: \\u043F\\u0430\\u0432\\u0456\\u043D\\u0435\\u043D \\u0431\\u044B\\u0446\\u044C \\u043A\\u0440\\u0430\\u0442\\u043D\\u044B\\u043C \${issue2.divisor}\`; + case "unrecognized_keys": + return \`\\u041D\\u0435\\u0440\\u0430\\u0441\\u043F\\u0430\\u0437\\u043D\\u0430\\u043D\\u044B \${issue2.keys.length > 1 ? "\\u043A\\u043B\\u044E\\u0447\\u044B" : "\\u043A\\u043B\\u044E\\u0447"}: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`\\u041D\\u044F\\u043F\\u0440\\u0430\\u0432\\u0456\\u043B\\u044C\\u043D\\u044B \\u043A\\u043B\\u044E\\u0447 \\u0443 \${issue2.origin}\`; + case "invalid_union": + return "\\u041D\\u044F\\u043F\\u0440\\u0430\\u0432\\u0456\\u043B\\u044C\\u043D\\u044B \\u045E\\u0432\\u043E\\u0434"; + case "invalid_element": + return \`\\u041D\\u044F\\u043F\\u0440\\u0430\\u0432\\u0456\\u043B\\u044C\\u043D\\u0430\\u0435 \\u0437\\u043D\\u0430\\u0447\\u044D\\u043D\\u043D\\u0435 \\u045E \${issue2.origin}\`; + default: + return \`\\u041D\\u044F\\u043F\\u0440\\u0430\\u0432\\u0456\\u043B\\u044C\\u043D\\u044B \\u045E\\u0432\\u043E\\u0434\`; + } + }; +}, "error"); +function be_default() { + return { + localeError: error3() + }; +} +__name(be_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/ca.js +var error4 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "car\\xE0cters", + verb: "contenir" + }, + file: { + unit: "bytes", + verb: "contenir" + }, + array: { + unit: "elements", + verb: "contenir" + }, + set: { + unit: "elements", + verb: "contenir" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "number"; + } + case "object": { + if (Array.isArray(data)) { + return "array"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "entrada", + email: "adre\\xE7a electr\\xF2nica", + url: "URL", + emoji: "emoji", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "data i hora ISO", + date: "data ISO", + time: "hora ISO", + duration: "durada ISO", + ipv4: "adre\\xE7a IPv4", + ipv6: "adre\\xE7a IPv6", + cidrv4: "rang IPv4", + cidrv6: "rang IPv6", + base64: "cadena codificada en base64", + base64url: "cadena codificada en base64url", + json_string: "cadena JSON", + e164: "n\\xFAmero E.164", + jwt: "JWT", + template_literal: "entrada" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`Tipus inv\\xE0lid: s'esperava \${issue2.expected}, s'ha rebut \${parsedType7(issue2.input)}\`; + // return \`Tipus invàlid: s'esperava \${issue.expected}, s'ha rebut \${util.getParsedType(issue.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`Valor inv\\xE0lid: s'esperava \${stringifyPrimitive(issue2.values[0])}\`; + return \`Opci\\xF3 inv\\xE0lida: s'esperava una de \${joinValues(issue2.values, " o ")}\`; + case "too_big": { + const adj = issue2.inclusive ? "com a m\\xE0xim" : "menys de"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`Massa gran: s'esperava que \${issue2.origin ?? "el valor"} contingu\\xE9s \${adj} \${issue2.maximum.toString()} \${sizing.unit ?? "elements"}\`; + return \`Massa gran: s'esperava que \${issue2.origin ?? "el valor"} fos \${adj} \${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? "com a m\\xEDnim" : "m\\xE9s de"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`Massa petit: s'esperava que \${issue2.origin} contingu\\xE9s \${adj} \${issue2.minimum.toString()} \${sizing.unit}\`; + } + return \`Massa petit: s'esperava que \${issue2.origin} fos \${adj} \${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") { + return \`Format inv\\xE0lid: ha de comen\\xE7ar amb "\${_issue.prefix}"\`; + } + if (_issue.format === "ends_with") return \`Format inv\\xE0lid: ha d'acabar amb "\${_issue.suffix}"\`; + if (_issue.format === "includes") return \`Format inv\\xE0lid: ha d'incloure "\${_issue.includes}"\`; + if (_issue.format === "regex") return \`Format inv\\xE0lid: ha de coincidir amb el patr\\xF3 \${_issue.pattern}\`; + return \`Format inv\\xE0lid per a \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`N\\xFAmero inv\\xE0lid: ha de ser m\\xFAltiple de \${issue2.divisor}\`; + case "unrecognized_keys": + return \`Clau\${issue2.keys.length > 1 ? "s" : ""} no reconeguda\${issue2.keys.length > 1 ? "s" : ""}: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`Clau inv\\xE0lida a \${issue2.origin}\`; + case "invalid_union": + return "Entrada inv\\xE0lida"; + // Could also be "Tipus d'unió invàlid" but "Entrada invàlida" is more general + case "invalid_element": + return \`Element inv\\xE0lid a \${issue2.origin}\`; + default: + return \`Entrada inv\\xE0lida\`; + } + }; +}, "error"); +function ca_default() { + return { + localeError: error4() + }; +} +__name(ca_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/cs.js +var error5 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "znak\\u016F", + verb: "m\\xEDt" + }, + file: { + unit: "bajt\\u016F", + verb: "m\\xEDt" + }, + array: { + unit: "prvk\\u016F", + verb: "m\\xEDt" + }, + set: { + unit: "prvk\\u016F", + verb: "m\\xEDt" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "\\u010D\\xEDslo"; + } + case "string": { + return "\\u0159et\\u011Bzec"; + } + case "boolean": { + return "boolean"; + } + case "bigint": { + return "bigint"; + } + case "function": { + return "funkce"; + } + case "symbol": { + return "symbol"; + } + case "undefined": { + return "undefined"; + } + case "object": { + if (Array.isArray(data)) { + return "pole"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "regul\\xE1rn\\xED v\\xFDraz", + email: "e-mailov\\xE1 adresa", + url: "URL", + emoji: "emoji", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "datum a \\u010Das ve form\\xE1tu ISO", + date: "datum ve form\\xE1tu ISO", + time: "\\u010Das ve form\\xE1tu ISO", + duration: "doba trv\\xE1n\\xED ISO", + ipv4: "IPv4 adresa", + ipv6: "IPv6 adresa", + cidrv4: "rozsah IPv4", + cidrv6: "rozsah IPv6", + base64: "\\u0159et\\u011Bzec zak\\xF3dovan\\xFD ve form\\xE1tu base64", + base64url: "\\u0159et\\u011Bzec zak\\xF3dovan\\xFD ve form\\xE1tu base64url", + json_string: "\\u0159et\\u011Bzec ve form\\xE1tu JSON", + e164: "\\u010D\\xEDslo E.164", + jwt: "JWT", + template_literal: "vstup" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`Neplatn\\xFD vstup: o\\u010Dek\\xE1v\\xE1no \${issue2.expected}, obdr\\u017Eeno \${parsedType7(issue2.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`Neplatn\\xFD vstup: o\\u010Dek\\xE1v\\xE1no \${stringifyPrimitive(issue2.values[0])}\`; + return \`Neplatn\\xE1 mo\\u017Enost: o\\u010Dek\\xE1v\\xE1na jedna z hodnot \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`Hodnota je p\\u0159\\xEDli\\u0161 velk\\xE1: \${issue2.origin ?? "hodnota"} mus\\xED m\\xEDt \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "prvk\\u016F"}\`; + } + return \`Hodnota je p\\u0159\\xEDli\\u0161 velk\\xE1: \${issue2.origin ?? "hodnota"} mus\\xED b\\xFDt \${adj}\${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`Hodnota je p\\u0159\\xEDli\\u0161 mal\\xE1: \${issue2.origin ?? "hodnota"} mus\\xED m\\xEDt \${adj}\${issue2.minimum.toString()} \${sizing.unit ?? "prvk\\u016F"}\`; + } + return \`Hodnota je p\\u0159\\xEDli\\u0161 mal\\xE1: \${issue2.origin ?? "hodnota"} mus\\xED b\\xFDt \${adj}\${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") return \`Neplatn\\xFD \\u0159et\\u011Bzec: mus\\xED za\\u010D\\xEDnat na "\${_issue.prefix}"\`; + if (_issue.format === "ends_with") return \`Neplatn\\xFD \\u0159et\\u011Bzec: mus\\xED kon\\u010Dit na "\${_issue.suffix}"\`; + if (_issue.format === "includes") return \`Neplatn\\xFD \\u0159et\\u011Bzec: mus\\xED obsahovat "\${_issue.includes}"\`; + if (_issue.format === "regex") return \`Neplatn\\xFD \\u0159et\\u011Bzec: mus\\xED odpov\\xEDdat vzoru \${_issue.pattern}\`; + return \`Neplatn\\xFD form\\xE1t \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`Neplatn\\xE9 \\u010D\\xEDslo: mus\\xED b\\xFDt n\\xE1sobkem \${issue2.divisor}\`; + case "unrecognized_keys": + return \`Nezn\\xE1m\\xE9 kl\\xED\\u010De: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`Neplatn\\xFD kl\\xED\\u010D v \${issue2.origin}\`; + case "invalid_union": + return "Neplatn\\xFD vstup"; + case "invalid_element": + return \`Neplatn\\xE1 hodnota v \${issue2.origin}\`; + default: + return \`Neplatn\\xFD vstup\`; + } + }; +}, "error"); +function cs_default() { + return { + localeError: error5() + }; +} +__name(cs_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/da.js +var error6 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "tegn", + verb: "havde" + }, + file: { + unit: "bytes", + verb: "havde" + }, + array: { + unit: "elementer", + verb: "indeholdt" + }, + set: { + unit: "elementer", + verb: "indeholdt" + } + }; + const TypeNames = { + string: "streng", + number: "tal", + boolean: "boolean", + array: "liste", + object: "objekt", + set: "s\\xE6t", + file: "fil" + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + function getTypeName(type) { + return TypeNames[type] ?? type; + } + __name(getTypeName, "getTypeName"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "tal"; + } + case "object": { + if (Array.isArray(data)) { + return "liste"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + return "objekt"; + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "input", + email: "e-mailadresse", + url: "URL", + emoji: "emoji", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "ISO dato- og klokkesl\\xE6t", + date: "ISO-dato", + time: "ISO-klokkesl\\xE6t", + duration: "ISO-varighed", + ipv4: "IPv4-omr\\xE5de", + ipv6: "IPv6-omr\\xE5de", + cidrv4: "IPv4-spektrum", + cidrv6: "IPv6-spektrum", + base64: "base64-kodet streng", + base64url: "base64url-kodet streng", + json_string: "JSON-streng", + e164: "E.164-nummer", + jwt: "JWT", + template_literal: "input" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`Ugyldigt input: forventede \${getTypeName(issue2.expected)}, fik \${getTypeName(parsedType7(issue2.input))}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`Ugyldig v\\xE6rdi: forventede \${stringifyPrimitive(issue2.values[0])}\`; + return \`Ugyldigt valg: forventede en af f\\xF8lgende \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + const origin = getTypeName(issue2.origin); + if (sizing) return \`For stor: forventede \${origin ?? "value"} \${sizing.verb} \${adj} \${issue2.maximum.toString()} \${sizing.unit ?? "elementer"}\`; + return \`For stor: forventede \${origin ?? "value"} havde \${adj} \${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + const origin = getTypeName(issue2.origin); + if (sizing) { + return \`For lille: forventede \${origin} \${sizing.verb} \${adj} \${issue2.minimum.toString()} \${sizing.unit}\`; + } + return \`For lille: forventede \${origin} havde \${adj} \${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") return \`Ugyldig streng: skal starte med "\${_issue.prefix}"\`; + if (_issue.format === "ends_with") return \`Ugyldig streng: skal ende med "\${_issue.suffix}"\`; + if (_issue.format === "includes") return \`Ugyldig streng: skal indeholde "\${_issue.includes}"\`; + if (_issue.format === "regex") return \`Ugyldig streng: skal matche m\\xF8nsteret \${_issue.pattern}\`; + return \`Ugyldig \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`Ugyldigt tal: skal v\\xE6re deleligt med \${issue2.divisor}\`; + case "unrecognized_keys": + return \`\${issue2.keys.length > 1 ? "Ukendte n\\xF8gler" : "Ukendt n\\xF8gle"}: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`Ugyldig n\\xF8gle i \${issue2.origin}\`; + case "invalid_union": + return "Ugyldigt input: matcher ingen af de tilladte typer"; + case "invalid_element": + return \`Ugyldig v\\xE6rdi i \${issue2.origin}\`; + default: + return \`Ugyldigt input\`; + } + }; +}, "error"); +function da_default() { + return { + localeError: error6() + }; +} +__name(da_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/de.js +var error7 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "Zeichen", + verb: "zu haben" + }, + file: { + unit: "Bytes", + verb: "zu haben" + }, + array: { + unit: "Elemente", + verb: "zu haben" + }, + set: { + unit: "Elemente", + verb: "zu haben" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "Zahl"; + } + case "object": { + if (Array.isArray(data)) { + return "Array"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "Eingabe", + email: "E-Mail-Adresse", + url: "URL", + emoji: "Emoji", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "ISO-Datum und -Uhrzeit", + date: "ISO-Datum", + time: "ISO-Uhrzeit", + duration: "ISO-Dauer", + ipv4: "IPv4-Adresse", + ipv6: "IPv6-Adresse", + cidrv4: "IPv4-Bereich", + cidrv6: "IPv6-Bereich", + base64: "Base64-codierter String", + base64url: "Base64-URL-codierter String", + json_string: "JSON-String", + e164: "E.164-Nummer", + jwt: "JWT", + template_literal: "Eingabe" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`Ung\\xFCltige Eingabe: erwartet \${issue2.expected}, erhalten \${parsedType7(issue2.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`Ung\\xFCltige Eingabe: erwartet \${stringifyPrimitive(issue2.values[0])}\`; + return \`Ung\\xFCltige Option: erwartet eine von \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`Zu gro\\xDF: erwartet, dass \${issue2.origin ?? "Wert"} \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "Elemente"} hat\`; + return \`Zu gro\\xDF: erwartet, dass \${issue2.origin ?? "Wert"} \${adj}\${issue2.maximum.toString()} ist\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`Zu klein: erwartet, dass \${issue2.origin} \${adj}\${issue2.minimum.toString()} \${sizing.unit} hat\`; + } + return \`Zu klein: erwartet, dass \${issue2.origin} \${adj}\${issue2.minimum.toString()} ist\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") return \`Ung\\xFCltiger String: muss mit "\${_issue.prefix}" beginnen\`; + if (_issue.format === "ends_with") return \`Ung\\xFCltiger String: muss mit "\${_issue.suffix}" enden\`; + if (_issue.format === "includes") return \`Ung\\xFCltiger String: muss "\${_issue.includes}" enthalten\`; + if (_issue.format === "regex") return \`Ung\\xFCltiger String: muss dem Muster \${_issue.pattern} entsprechen\`; + return \`Ung\\xFCltig: \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`Ung\\xFCltige Zahl: muss ein Vielfaches von \${issue2.divisor} sein\`; + case "unrecognized_keys": + return \`\${issue2.keys.length > 1 ? "Unbekannte Schl\\xFCssel" : "Unbekannter Schl\\xFCssel"}: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`Ung\\xFCltiger Schl\\xFCssel in \${issue2.origin}\`; + case "invalid_union": + return "Ung\\xFCltige Eingabe"; + case "invalid_element": + return \`Ung\\xFCltiger Wert in \${issue2.origin}\`; + default: + return \`Ung\\xFCltige Eingabe\`; + } + }; +}, "error"); +function de_default() { + return { + localeError: error7() + }; +} +__name(de_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/en.js +var parsedType = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "number"; + } + case "object": { + if (Array.isArray(data)) { + return "array"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; +}, "parsedType"); +var error8 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "characters", + verb: "to have" + }, + file: { + unit: "bytes", + verb: "to have" + }, + array: { + unit: "items", + verb: "to have" + }, + set: { + unit: "items", + verb: "to have" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const Nouns = { + regex: "input", + email: "email address", + url: "URL", + emoji: "emoji", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "ISO datetime", + date: "ISO date", + time: "ISO time", + duration: "ISO duration", + ipv4: "IPv4 address", + ipv6: "IPv6 address", + cidrv4: "IPv4 range", + cidrv6: "IPv6 range", + base64: "base64-encoded string", + base64url: "base64url-encoded string", + json_string: "JSON string", + e164: "E.164 number", + jwt: "JWT", + template_literal: "input" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`Invalid input: expected \${issue2.expected}, received \${parsedType(issue2.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`Invalid input: expected \${stringifyPrimitive(issue2.values[0])}\`; + return \`Invalid option: expected one of \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`Too big: expected \${issue2.origin ?? "value"} to have \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "elements"}\`; + return \`Too big: expected \${issue2.origin ?? "value"} to be \${adj}\${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`Too small: expected \${issue2.origin} to have \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; + } + return \`Too small: expected \${issue2.origin} to be \${adj}\${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") { + return \`Invalid string: must start with "\${_issue.prefix}"\`; + } + if (_issue.format === "ends_with") return \`Invalid string: must end with "\${_issue.suffix}"\`; + if (_issue.format === "includes") return \`Invalid string: must include "\${_issue.includes}"\`; + if (_issue.format === "regex") return \`Invalid string: must match pattern \${_issue.pattern}\`; + return \`Invalid \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`Invalid number: must be a multiple of \${issue2.divisor}\`; + case "unrecognized_keys": + return \`Unrecognized key\${issue2.keys.length > 1 ? "s" : ""}: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`Invalid key in \${issue2.origin}\`; + case "invalid_union": + return "Invalid input"; + case "invalid_element": + return \`Invalid value in \${issue2.origin}\`; + default: + return \`Invalid input\`; + } + }; +}, "error"); +function en_default() { + return { + localeError: error8() + }; +} +__name(en_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/eo.js +var parsedType2 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "nombro"; + } + case "object": { + if (Array.isArray(data)) { + return "tabelo"; + } + if (data === null) { + return "senvalora"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; +}, "parsedType"); +var error9 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "karaktrojn", + verb: "havi" + }, + file: { + unit: "bajtojn", + verb: "havi" + }, + array: { + unit: "elementojn", + verb: "havi" + }, + set: { + unit: "elementojn", + verb: "havi" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const Nouns = { + regex: "enigo", + email: "retadreso", + url: "URL", + emoji: "emo\\u011Dio", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "ISO-datotempo", + date: "ISO-dato", + time: "ISO-tempo", + duration: "ISO-da\\u016Dro", + ipv4: "IPv4-adreso", + ipv6: "IPv6-adreso", + cidrv4: "IPv4-rango", + cidrv6: "IPv6-rango", + base64: "64-ume kodita karaktraro", + base64url: "URL-64-ume kodita karaktraro", + json_string: "JSON-karaktraro", + e164: "E.164-nombro", + jwt: "JWT", + template_literal: "enigo" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`Nevalida enigo: atendi\\u011Dis \${issue2.expected}, ricevi\\u011Dis \${parsedType2(issue2.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`Nevalida enigo: atendi\\u011Dis \${stringifyPrimitive(issue2.values[0])}\`; + return \`Nevalida opcio: atendi\\u011Dis unu el \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`Tro granda: atendi\\u011Dis ke \${issue2.origin ?? "valoro"} havu \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "elementojn"}\`; + return \`Tro granda: atendi\\u011Dis ke \${issue2.origin ?? "valoro"} havu \${adj}\${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`Tro malgranda: atendi\\u011Dis ke \${issue2.origin} havu \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; + } + return \`Tro malgranda: atendi\\u011Dis ke \${issue2.origin} estu \${adj}\${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") return \`Nevalida karaktraro: devas komenci\\u011Di per "\${_issue.prefix}"\`; + if (_issue.format === "ends_with") return \`Nevalida karaktraro: devas fini\\u011Di per "\${_issue.suffix}"\`; + if (_issue.format === "includes") return \`Nevalida karaktraro: devas inkluzivi "\${_issue.includes}"\`; + if (_issue.format === "regex") return \`Nevalida karaktraro: devas kongrui kun la modelo \${_issue.pattern}\`; + return \`Nevalida \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`Nevalida nombro: devas esti oblo de \${issue2.divisor}\`; + case "unrecognized_keys": + return \`Nekonata\${issue2.keys.length > 1 ? "j" : ""} \\u015Dlosilo\${issue2.keys.length > 1 ? "j" : ""}: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`Nevalida \\u015Dlosilo en \${issue2.origin}\`; + case "invalid_union": + return "Nevalida enigo"; + case "invalid_element": + return \`Nevalida valoro en \${issue2.origin}\`; + default: + return \`Nevalida enigo\`; + } + }; +}, "error"); +function eo_default() { + return { + localeError: error9() + }; +} +__name(eo_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/es.js +var error10 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "caracteres", + verb: "tener" + }, + file: { + unit: "bytes", + verb: "tener" + }, + array: { + unit: "elementos", + verb: "tener" + }, + set: { + unit: "elementos", + verb: "tener" + } + }; + const TypeNames = { + string: "texto", + number: "n\\xFAmero", + boolean: "booleano", + array: "arreglo", + object: "objeto", + set: "conjunto", + file: "archivo", + date: "fecha", + bigint: "n\\xFAmero grande", + symbol: "s\\xEDmbolo", + undefined: "indefinido", + null: "nulo", + function: "funci\\xF3n", + map: "mapa", + record: "registro", + tuple: "tupla", + enum: "enumeraci\\xF3n", + union: "uni\\xF3n", + literal: "literal", + promise: "promesa", + void: "vac\\xEDo", + never: "nunca", + unknown: "desconocido", + any: "cualquiera" + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + function getTypeName(type) { + return TypeNames[type] ?? type; + } + __name(getTypeName, "getTypeName"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "number"; + } + case "object": { + if (Array.isArray(data)) { + return "array"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype) { + return data.constructor.name; + } + return "object"; + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "entrada", + email: "direcci\\xF3n de correo electr\\xF3nico", + url: "URL", + emoji: "emoji", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "fecha y hora ISO", + date: "fecha ISO", + time: "hora ISO", + duration: "duraci\\xF3n ISO", + ipv4: "direcci\\xF3n IPv4", + ipv6: "direcci\\xF3n IPv6", + cidrv4: "rango IPv4", + cidrv6: "rango IPv6", + base64: "cadena codificada en base64", + base64url: "URL codificada en base64", + json_string: "cadena JSON", + e164: "n\\xFAmero E.164", + jwt: "JWT", + template_literal: "entrada" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`Entrada inv\\xE1lida: se esperaba \${getTypeName(issue2.expected)}, recibido \${getTypeName(parsedType7(issue2.input))}\`; + // return \`Entrada inválida: se esperaba \${issue.expected}, recibido \${util.getParsedType(issue.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`Entrada inv\\xE1lida: se esperaba \${stringifyPrimitive(issue2.values[0])}\`; + return \`Opci\\xF3n inv\\xE1lida: se esperaba una de \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + const origin = getTypeName(issue2.origin); + if (sizing) return \`Demasiado grande: se esperaba que \${origin ?? "valor"} tuviera \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "elementos"}\`; + return \`Demasiado grande: se esperaba que \${origin ?? "valor"} fuera \${adj}\${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + const origin = getTypeName(issue2.origin); + if (sizing) { + return \`Demasiado peque\\xF1o: se esperaba que \${origin} tuviera \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; + } + return \`Demasiado peque\\xF1o: se esperaba que \${origin} fuera \${adj}\${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") return \`Cadena inv\\xE1lida: debe comenzar con "\${_issue.prefix}"\`; + if (_issue.format === "ends_with") return \`Cadena inv\\xE1lida: debe terminar en "\${_issue.suffix}"\`; + if (_issue.format === "includes") return \`Cadena inv\\xE1lida: debe incluir "\${_issue.includes}"\`; + if (_issue.format === "regex") return \`Cadena inv\\xE1lida: debe coincidir con el patr\\xF3n \${_issue.pattern}\`; + return \`Inv\\xE1lido \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`N\\xFAmero inv\\xE1lido: debe ser m\\xFAltiplo de \${issue2.divisor}\`; + case "unrecognized_keys": + return \`Llave\${issue2.keys.length > 1 ? "s" : ""} desconocida\${issue2.keys.length > 1 ? "s" : ""}: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`Llave inv\\xE1lida en \${getTypeName(issue2.origin)}\`; + case "invalid_union": + return "Entrada inv\\xE1lida"; + case "invalid_element": + return \`Valor inv\\xE1lido en \${getTypeName(issue2.origin)}\`; + default: + return \`Entrada inv\\xE1lida\`; + } + }; +}, "error"); +function es_default() { + return { + localeError: error10() + }; +} +__name(es_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/fa.js +var error11 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "\\u06A9\\u0627\\u0631\\u0627\\u06A9\\u062A\\u0631", + verb: "\\u062F\\u0627\\u0634\\u062A\\u0647 \\u0628\\u0627\\u0634\\u062F" + }, + file: { + unit: "\\u0628\\u0627\\u06CC\\u062A", + verb: "\\u062F\\u0627\\u0634\\u062A\\u0647 \\u0628\\u0627\\u0634\\u062F" + }, + array: { + unit: "\\u0622\\u06CC\\u062A\\u0645", + verb: "\\u062F\\u0627\\u0634\\u062A\\u0647 \\u0628\\u0627\\u0634\\u062F" + }, + set: { + unit: "\\u0622\\u06CC\\u062A\\u0645", + verb: "\\u062F\\u0627\\u0634\\u062A\\u0647 \\u0628\\u0627\\u0634\\u062F" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "\\u0639\\u062F\\u062F"; + } + case "object": { + if (Array.isArray(data)) { + return "\\u0622\\u0631\\u0627\\u06CC\\u0647"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "\\u0648\\u0631\\u0648\\u062F\\u06CC", + email: "\\u0622\\u062F\\u0631\\u0633 \\u0627\\u06CC\\u0645\\u06CC\\u0644", + url: "URL", + emoji: "\\u0627\\u06CC\\u0645\\u0648\\u062C\\u06CC", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "\\u062A\\u0627\\u0631\\u06CC\\u062E \\u0648 \\u0632\\u0645\\u0627\\u0646 \\u0627\\u06CC\\u0632\\u0648", + date: "\\u062A\\u0627\\u0631\\u06CC\\u062E \\u0627\\u06CC\\u0632\\u0648", + time: "\\u0632\\u0645\\u0627\\u0646 \\u0627\\u06CC\\u0632\\u0648", + duration: "\\u0645\\u062F\\u062A \\u0632\\u0645\\u0627\\u0646 \\u0627\\u06CC\\u0632\\u0648", + ipv4: "IPv4 \\u0622\\u062F\\u0631\\u0633", + ipv6: "IPv6 \\u0622\\u062F\\u0631\\u0633", + cidrv4: "IPv4 \\u062F\\u0627\\u0645\\u0646\\u0647", + cidrv6: "IPv6 \\u062F\\u0627\\u0645\\u0646\\u0647", + base64: "base64-encoded \\u0631\\u0634\\u062A\\u0647", + base64url: "base64url-encoded \\u0631\\u0634\\u062A\\u0647", + json_string: "JSON \\u0631\\u0634\\u062A\\u0647", + e164: "E.164 \\u0639\\u062F\\u062F", + jwt: "JWT", + template_literal: "\\u0648\\u0631\\u0648\\u062F\\u06CC" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`\\u0648\\u0631\\u0648\\u062F\\u06CC \\u0646\\u0627\\u0645\\u0639\\u062A\\u0628\\u0631: \\u0645\\u06CC\\u200C\\u0628\\u0627\\u06CC\\u0633\\u062A \${issue2.expected} \\u0645\\u06CC\\u200C\\u0628\\u0648\\u062F\\u060C \${parsedType7(issue2.input)} \\u062F\\u0631\\u06CC\\u0627\\u0641\\u062A \\u0634\\u062F\`; + case "invalid_value": + if (issue2.values.length === 1) { + return \`\\u0648\\u0631\\u0648\\u062F\\u06CC \\u0646\\u0627\\u0645\\u0639\\u062A\\u0628\\u0631: \\u0645\\u06CC\\u200C\\u0628\\u0627\\u06CC\\u0633\\u062A \${stringifyPrimitive(issue2.values[0])} \\u0645\\u06CC\\u200C\\u0628\\u0648\\u062F\`; + } + return \`\\u06AF\\u0632\\u06CC\\u0646\\u0647 \\u0646\\u0627\\u0645\\u0639\\u062A\\u0628\\u0631: \\u0645\\u06CC\\u200C\\u0628\\u0627\\u06CC\\u0633\\u062A \\u06CC\\u06A9\\u06CC \\u0627\\u0632 \${joinValues(issue2.values, "|")} \\u0645\\u06CC\\u200C\\u0628\\u0648\\u062F\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`\\u062E\\u06CC\\u0644\\u06CC \\u0628\\u0632\\u0631\\u06AF: \${issue2.origin ?? "\\u0645\\u0642\\u062F\\u0627\\u0631"} \\u0628\\u0627\\u06CC\\u062F \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "\\u0639\\u0646\\u0635\\u0631"} \\u0628\\u0627\\u0634\\u062F\`; + } + return \`\\u062E\\u06CC\\u0644\\u06CC \\u0628\\u0632\\u0631\\u06AF: \${issue2.origin ?? "\\u0645\\u0642\\u062F\\u0627\\u0631"} \\u0628\\u0627\\u06CC\\u062F \${adj}\${issue2.maximum.toString()} \\u0628\\u0627\\u0634\\u062F\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`\\u062E\\u06CC\\u0644\\u06CC \\u06A9\\u0648\\u0686\\u06A9: \${issue2.origin} \\u0628\\u0627\\u06CC\\u062F \${adj}\${issue2.minimum.toString()} \${sizing.unit} \\u0628\\u0627\\u0634\\u062F\`; + } + return \`\\u062E\\u06CC\\u0644\\u06CC \\u06A9\\u0648\\u0686\\u06A9: \${issue2.origin} \\u0628\\u0627\\u06CC\\u062F \${adj}\${issue2.minimum.toString()} \\u0628\\u0627\\u0634\\u062F\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") { + return \`\\u0631\\u0634\\u062A\\u0647 \\u0646\\u0627\\u0645\\u0639\\u062A\\u0628\\u0631: \\u0628\\u0627\\u06CC\\u062F \\u0628\\u0627 "\${_issue.prefix}" \\u0634\\u0631\\u0648\\u0639 \\u0634\\u0648\\u062F\`; + } + if (_issue.format === "ends_with") { + return \`\\u0631\\u0634\\u062A\\u0647 \\u0646\\u0627\\u0645\\u0639\\u062A\\u0628\\u0631: \\u0628\\u0627\\u06CC\\u062F \\u0628\\u0627 "\${_issue.suffix}" \\u062A\\u0645\\u0627\\u0645 \\u0634\\u0648\\u062F\`; + } + if (_issue.format === "includes") { + return \`\\u0631\\u0634\\u062A\\u0647 \\u0646\\u0627\\u0645\\u0639\\u062A\\u0628\\u0631: \\u0628\\u0627\\u06CC\\u062F \\u0634\\u0627\\u0645\\u0644 "\${_issue.includes}" \\u0628\\u0627\\u0634\\u062F\`; + } + if (_issue.format === "regex") { + return \`\\u0631\\u0634\\u062A\\u0647 \\u0646\\u0627\\u0645\\u0639\\u062A\\u0628\\u0631: \\u0628\\u0627\\u06CC\\u062F \\u0628\\u0627 \\u0627\\u0644\\u06AF\\u0648\\u06CC \${_issue.pattern} \\u0645\\u0637\\u0627\\u0628\\u0642\\u062A \\u062F\\u0627\\u0634\\u062A\\u0647 \\u0628\\u0627\\u0634\\u062F\`; + } + return \`\${Nouns[_issue.format] ?? issue2.format} \\u0646\\u0627\\u0645\\u0639\\u062A\\u0628\\u0631\`; + } + case "not_multiple_of": + return \`\\u0639\\u062F\\u062F \\u0646\\u0627\\u0645\\u0639\\u062A\\u0628\\u0631: \\u0628\\u0627\\u06CC\\u062F \\u0645\\u0636\\u0631\\u0628 \${issue2.divisor} \\u0628\\u0627\\u0634\\u062F\`; + case "unrecognized_keys": + return \`\\u06A9\\u0644\\u06CC\\u062F\${issue2.keys.length > 1 ? "\\u0647\\u0627\\u06CC" : ""} \\u0646\\u0627\\u0634\\u0646\\u0627\\u0633: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`\\u06A9\\u0644\\u06CC\\u062F \\u0646\\u0627\\u0634\\u0646\\u0627\\u0633 \\u062F\\u0631 \${issue2.origin}\`; + case "invalid_union": + return \`\\u0648\\u0631\\u0648\\u062F\\u06CC \\u0646\\u0627\\u0645\\u0639\\u062A\\u0628\\u0631\`; + case "invalid_element": + return \`\\u0645\\u0642\\u062F\\u0627\\u0631 \\u0646\\u0627\\u0645\\u0639\\u062A\\u0628\\u0631 \\u062F\\u0631 \${issue2.origin}\`; + default: + return \`\\u0648\\u0631\\u0648\\u062F\\u06CC \\u0646\\u0627\\u0645\\u0639\\u062A\\u0628\\u0631\`; + } + }; +}, "error"); +function fa_default() { + return { + localeError: error11() + }; +} +__name(fa_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/fi.js +var error12 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "merkki\\xE4", + subject: "merkkijonon" + }, + file: { + unit: "tavua", + subject: "tiedoston" + }, + array: { + unit: "alkiota", + subject: "listan" + }, + set: { + unit: "alkiota", + subject: "joukon" + }, + number: { + unit: "", + subject: "luvun" + }, + bigint: { + unit: "", + subject: "suuren kokonaisluvun" + }, + int: { + unit: "", + subject: "kokonaisluvun" + }, + date: { + unit: "", + subject: "p\\xE4iv\\xE4m\\xE4\\xE4r\\xE4n" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "number"; + } + case "object": { + if (Array.isArray(data)) { + return "array"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "s\\xE4\\xE4nn\\xF6llinen lauseke", + email: "s\\xE4hk\\xF6postiosoite", + url: "URL-osoite", + emoji: "emoji", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "ISO-aikaleima", + date: "ISO-p\\xE4iv\\xE4m\\xE4\\xE4r\\xE4", + time: "ISO-aika", + duration: "ISO-kesto", + ipv4: "IPv4-osoite", + ipv6: "IPv6-osoite", + cidrv4: "IPv4-alue", + cidrv6: "IPv6-alue", + base64: "base64-koodattu merkkijono", + base64url: "base64url-koodattu merkkijono", + json_string: "JSON-merkkijono", + e164: "E.164-luku", + jwt: "JWT", + template_literal: "templaattimerkkijono" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`Virheellinen tyyppi: odotettiin \${issue2.expected}, oli \${parsedType7(issue2.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`Virheellinen sy\\xF6te: t\\xE4ytyy olla \${stringifyPrimitive(issue2.values[0])}\`; + return \`Virheellinen valinta: t\\xE4ytyy olla yksi seuraavista: \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`Liian suuri: \${sizing.subject} t\\xE4ytyy olla \${adj}\${issue2.maximum.toString()} \${sizing.unit}\`.trim(); + } + return \`Liian suuri: arvon t\\xE4ytyy olla \${adj}\${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`Liian pieni: \${sizing.subject} t\\xE4ytyy olla \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`.trim(); + } + return \`Liian pieni: arvon t\\xE4ytyy olla \${adj}\${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") return \`Virheellinen sy\\xF6te: t\\xE4ytyy alkaa "\${_issue.prefix}"\`; + if (_issue.format === "ends_with") return \`Virheellinen sy\\xF6te: t\\xE4ytyy loppua "\${_issue.suffix}"\`; + if (_issue.format === "includes") return \`Virheellinen sy\\xF6te: t\\xE4ytyy sis\\xE4lt\\xE4\\xE4 "\${_issue.includes}"\`; + if (_issue.format === "regex") { + return \`Virheellinen sy\\xF6te: t\\xE4ytyy vastata s\\xE4\\xE4nn\\xF6llist\\xE4 lauseketta \${_issue.pattern}\`; + } + return \`Virheellinen \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`Virheellinen luku: t\\xE4ytyy olla luvun \${issue2.divisor} monikerta\`; + case "unrecognized_keys": + return \`\${issue2.keys.length > 1 ? "Tuntemattomat avaimet" : "Tuntematon avain"}: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return "Virheellinen avain tietueessa"; + case "invalid_union": + return "Virheellinen unioni"; + case "invalid_element": + return "Virheellinen arvo joukossa"; + default: + return \`Virheellinen sy\\xF6te\`; + } + }; +}, "error"); +function fi_default() { + return { + localeError: error12() + }; +} +__name(fi_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/fr.js +var error13 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "caract\\xE8res", + verb: "avoir" + }, + file: { + unit: "octets", + verb: "avoir" + }, + array: { + unit: "\\xE9l\\xE9ments", + verb: "avoir" + }, + set: { + unit: "\\xE9l\\xE9ments", + verb: "avoir" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "nombre"; + } + case "object": { + if (Array.isArray(data)) { + return "tableau"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "entr\\xE9e", + email: "adresse e-mail", + url: "URL", + emoji: "emoji", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "date et heure ISO", + date: "date ISO", + time: "heure ISO", + duration: "dur\\xE9e ISO", + ipv4: "adresse IPv4", + ipv6: "adresse IPv6", + cidrv4: "plage IPv4", + cidrv6: "plage IPv6", + base64: "cha\\xEEne encod\\xE9e en base64", + base64url: "cha\\xEEne encod\\xE9e en base64url", + json_string: "cha\\xEEne JSON", + e164: "num\\xE9ro E.164", + jwt: "JWT", + template_literal: "entr\\xE9e" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`Entr\\xE9e invalide : \${issue2.expected} attendu, \${parsedType7(issue2.input)} re\\xE7u\`; + case "invalid_value": + if (issue2.values.length === 1) return \`Entr\\xE9e invalide : \${stringifyPrimitive(issue2.values[0])} attendu\`; + return \`Option invalide : une valeur parmi \${joinValues(issue2.values, "|")} attendue\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`Trop grand : \${issue2.origin ?? "valeur"} doit \${sizing.verb} \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "\\xE9l\\xE9ment(s)"}\`; + return \`Trop grand : \${issue2.origin ?? "valeur"} doit \\xEAtre \${adj}\${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`Trop petit : \${issue2.origin} doit \${sizing.verb} \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; + } + return \`Trop petit : \${issue2.origin} doit \\xEAtre \${adj}\${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") return \`Cha\\xEEne invalide : doit commencer par "\${_issue.prefix}"\`; + if (_issue.format === "ends_with") return \`Cha\\xEEne invalide : doit se terminer par "\${_issue.suffix}"\`; + if (_issue.format === "includes") return \`Cha\\xEEne invalide : doit inclure "\${_issue.includes}"\`; + if (_issue.format === "regex") return \`Cha\\xEEne invalide : doit correspondre au mod\\xE8le \${_issue.pattern}\`; + return \`\${Nouns[_issue.format] ?? issue2.format} invalide\`; + } + case "not_multiple_of": + return \`Nombre invalide : doit \\xEAtre un multiple de \${issue2.divisor}\`; + case "unrecognized_keys": + return \`Cl\\xE9\${issue2.keys.length > 1 ? "s" : ""} non reconnue\${issue2.keys.length > 1 ? "s" : ""} : \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`Cl\\xE9 invalide dans \${issue2.origin}\`; + case "invalid_union": + return "Entr\\xE9e invalide"; + case "invalid_element": + return \`Valeur invalide dans \${issue2.origin}\`; + default: + return \`Entr\\xE9e invalide\`; + } + }; +}, "error"); +function fr_default() { + return { + localeError: error13() + }; +} +__name(fr_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/fr-CA.js +var error14 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "caract\\xE8res", + verb: "avoir" + }, + file: { + unit: "octets", + verb: "avoir" + }, + array: { + unit: "\\xE9l\\xE9ments", + verb: "avoir" + }, + set: { + unit: "\\xE9l\\xE9ments", + verb: "avoir" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "number"; + } + case "object": { + if (Array.isArray(data)) { + return "array"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "entr\\xE9e", + email: "adresse courriel", + url: "URL", + emoji: "emoji", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "date-heure ISO", + date: "date ISO", + time: "heure ISO", + duration: "dur\\xE9e ISO", + ipv4: "adresse IPv4", + ipv6: "adresse IPv6", + cidrv4: "plage IPv4", + cidrv6: "plage IPv6", + base64: "cha\\xEEne encod\\xE9e en base64", + base64url: "cha\\xEEne encod\\xE9e en base64url", + json_string: "cha\\xEEne JSON", + e164: "num\\xE9ro E.164", + jwt: "JWT", + template_literal: "entr\\xE9e" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`Entr\\xE9e invalide : attendu \${issue2.expected}, re\\xE7u \${parsedType7(issue2.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`Entr\\xE9e invalide : attendu \${stringifyPrimitive(issue2.values[0])}\`; + return \`Option invalide : attendu l'une des valeurs suivantes \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "\\u2264" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`Trop grand : attendu que \${issue2.origin ?? "la valeur"} ait \${adj}\${issue2.maximum.toString()} \${sizing.unit}\`; + return \`Trop grand : attendu que \${issue2.origin ?? "la valeur"} soit \${adj}\${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? "\\u2265" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`Trop petit : attendu que \${issue2.origin} ait \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; + } + return \`Trop petit : attendu que \${issue2.origin} soit \${adj}\${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") { + return \`Cha\\xEEne invalide : doit commencer par "\${_issue.prefix}"\`; + } + if (_issue.format === "ends_with") return \`Cha\\xEEne invalide : doit se terminer par "\${_issue.suffix}"\`; + if (_issue.format === "includes") return \`Cha\\xEEne invalide : doit inclure "\${_issue.includes}"\`; + if (_issue.format === "regex") return \`Cha\\xEEne invalide : doit correspondre au motif \${_issue.pattern}\`; + return \`\${Nouns[_issue.format] ?? issue2.format} invalide\`; + } + case "not_multiple_of": + return \`Nombre invalide : doit \\xEAtre un multiple de \${issue2.divisor}\`; + case "unrecognized_keys": + return \`Cl\\xE9\${issue2.keys.length > 1 ? "s" : ""} non reconnue\${issue2.keys.length > 1 ? "s" : ""} : \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`Cl\\xE9 invalide dans \${issue2.origin}\`; + case "invalid_union": + return "Entr\\xE9e invalide"; + case "invalid_element": + return \`Valeur invalide dans \${issue2.origin}\`; + default: + return \`Entr\\xE9e invalide\`; + } + }; +}, "error"); +function fr_CA_default() { + return { + localeError: error14() + }; +} +__name(fr_CA_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/he.js +var error15 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "\\u05D0\\u05D5\\u05EA\\u05D9\\u05D5\\u05EA", + verb: "\\u05DC\\u05DB\\u05DC\\u05D5\\u05DC" + }, + file: { + unit: "\\u05D1\\u05D9\\u05D9\\u05D8\\u05D9\\u05DD", + verb: "\\u05DC\\u05DB\\u05DC\\u05D5\\u05DC" + }, + array: { + unit: "\\u05E4\\u05E8\\u05D9\\u05D8\\u05D9\\u05DD", + verb: "\\u05DC\\u05DB\\u05DC\\u05D5\\u05DC" + }, + set: { + unit: "\\u05E4\\u05E8\\u05D9\\u05D8\\u05D9\\u05DD", + verb: "\\u05DC\\u05DB\\u05DC\\u05D5\\u05DC" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "number"; + } + case "object": { + if (Array.isArray(data)) { + return "array"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "\\u05E7\\u05DC\\u05D8", + email: "\\u05DB\\u05EA\\u05D5\\u05D1\\u05EA \\u05D0\\u05D9\\u05DE\\u05D9\\u05D9\\u05DC", + url: "\\u05DB\\u05EA\\u05D5\\u05D1\\u05EA \\u05E8\\u05E9\\u05EA", + emoji: "\\u05D0\\u05D9\\u05DE\\u05D5\\u05D2'\\u05D9", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "\\u05EA\\u05D0\\u05E8\\u05D9\\u05DA \\u05D5\\u05D6\\u05DE\\u05DF ISO", + date: "\\u05EA\\u05D0\\u05E8\\u05D9\\u05DA ISO", + time: "\\u05D6\\u05DE\\u05DF ISO", + duration: "\\u05DE\\u05E9\\u05DA \\u05D6\\u05DE\\u05DF ISO", + ipv4: "\\u05DB\\u05EA\\u05D5\\u05D1\\u05EA IPv4", + ipv6: "\\u05DB\\u05EA\\u05D5\\u05D1\\u05EA IPv6", + cidrv4: "\\u05D8\\u05D5\\u05D5\\u05D7 IPv4", + cidrv6: "\\u05D8\\u05D5\\u05D5\\u05D7 IPv6", + base64: "\\u05DE\\u05D7\\u05E8\\u05D5\\u05D6\\u05EA \\u05D1\\u05D1\\u05E1\\u05D9\\u05E1 64", + base64url: "\\u05DE\\u05D7\\u05E8\\u05D5\\u05D6\\u05EA \\u05D1\\u05D1\\u05E1\\u05D9\\u05E1 64 \\u05DC\\u05DB\\u05EA\\u05D5\\u05D1\\u05D5\\u05EA \\u05E8\\u05E9\\u05EA", + json_string: "\\u05DE\\u05D7\\u05E8\\u05D5\\u05D6\\u05EA JSON", + e164: "\\u05DE\\u05E1\\u05E4\\u05E8 E.164", + jwt: "JWT", + template_literal: "\\u05E7\\u05DC\\u05D8" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`\\u05E7\\u05DC\\u05D8 \\u05DC\\u05D0 \\u05EA\\u05E7\\u05D9\\u05DF: \\u05E6\\u05E8\\u05D9\\u05DA \${issue2.expected}, \\u05D4\\u05EA\\u05E7\\u05D1\\u05DC \${parsedType7(issue2.input)}\`; + // return \`Invalid input: expected \${issue.expected}, received \${util.getParsedType(issue.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`\\u05E7\\u05DC\\u05D8 \\u05DC\\u05D0 \\u05EA\\u05E7\\u05D9\\u05DF: \\u05E6\\u05E8\\u05D9\\u05DA \${stringifyPrimitive(issue2.values[0])}\`; + return \`\\u05E7\\u05DC\\u05D8 \\u05DC\\u05D0 \\u05EA\\u05E7\\u05D9\\u05DF: \\u05E6\\u05E8\\u05D9\\u05DA \\u05D0\\u05D7\\u05EA \\u05DE\\u05D4\\u05D0\\u05E4\\u05E9\\u05E8\\u05D5\\u05D9\\u05D5\\u05EA \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`\\u05D2\\u05D3\\u05D5\\u05DC \\u05DE\\u05D3\\u05D9: \${issue2.origin ?? "value"} \\u05E6\\u05E8\\u05D9\\u05DA \\u05DC\\u05D4\\u05D9\\u05D5\\u05EA \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "elements"}\`; + return \`\\u05D2\\u05D3\\u05D5\\u05DC \\u05DE\\u05D3\\u05D9: \${issue2.origin ?? "value"} \\u05E6\\u05E8\\u05D9\\u05DA \\u05DC\\u05D4\\u05D9\\u05D5\\u05EA \${adj}\${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`\\u05E7\\u05D8\\u05DF \\u05DE\\u05D3\\u05D9: \${issue2.origin} \\u05E6\\u05E8\\u05D9\\u05DA \\u05DC\\u05D4\\u05D9\\u05D5\\u05EA \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; + } + return \`\\u05E7\\u05D8\\u05DF \\u05DE\\u05D3\\u05D9: \${issue2.origin} \\u05E6\\u05E8\\u05D9\\u05DA \\u05DC\\u05D4\\u05D9\\u05D5\\u05EA \${adj}\${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") return \`\\u05DE\\u05D7\\u05E8\\u05D5\\u05D6\\u05EA \\u05DC\\u05D0 \\u05EA\\u05E7\\u05D9\\u05E0\\u05D4: \\u05D7\\u05D9\\u05D9\\u05D1\\u05EA \\u05DC\\u05D4\\u05EA\\u05D7\\u05D9\\u05DC \\u05D1"\${_issue.prefix}"\`; + if (_issue.format === "ends_with") return \`\\u05DE\\u05D7\\u05E8\\u05D5\\u05D6\\u05EA \\u05DC\\u05D0 \\u05EA\\u05E7\\u05D9\\u05E0\\u05D4: \\u05D7\\u05D9\\u05D9\\u05D1\\u05EA \\u05DC\\u05D4\\u05E1\\u05EA\\u05D9\\u05D9\\u05DD \\u05D1 "\${_issue.suffix}"\`; + if (_issue.format === "includes") return \`\\u05DE\\u05D7\\u05E8\\u05D5\\u05D6\\u05EA \\u05DC\\u05D0 \\u05EA\\u05E7\\u05D9\\u05E0\\u05D4: \\u05D7\\u05D9\\u05D9\\u05D1\\u05EA \\u05DC\\u05DB\\u05DC\\u05D5\\u05DC "\${_issue.includes}"\`; + if (_issue.format === "regex") return \`\\u05DE\\u05D7\\u05E8\\u05D5\\u05D6\\u05EA \\u05DC\\u05D0 \\u05EA\\u05E7\\u05D9\\u05E0\\u05D4: \\u05D7\\u05D9\\u05D9\\u05D1\\u05EA \\u05DC\\u05D4\\u05EA\\u05D0\\u05D9\\u05DD \\u05DC\\u05EA\\u05D1\\u05E0\\u05D9\\u05EA \${_issue.pattern}\`; + return \`\${Nouns[_issue.format] ?? issue2.format} \\u05DC\\u05D0 \\u05EA\\u05E7\\u05D9\\u05DF\`; + } + case "not_multiple_of": + return \`\\u05DE\\u05E1\\u05E4\\u05E8 \\u05DC\\u05D0 \\u05EA\\u05E7\\u05D9\\u05DF: \\u05D7\\u05D9\\u05D9\\u05D1 \\u05DC\\u05D4\\u05D9\\u05D5\\u05EA \\u05DE\\u05DB\\u05E4\\u05DC\\u05D4 \\u05E9\\u05DC \${issue2.divisor}\`; + case "unrecognized_keys": + return \`\\u05DE\\u05E4\\u05EA\\u05D7\${issue2.keys.length > 1 ? "\\u05D5\\u05EA" : ""} \\u05DC\\u05D0 \\u05DE\\u05D6\\u05D5\\u05D4\${issue2.keys.length > 1 ? "\\u05D9\\u05DD" : "\\u05D4"}: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`\\u05DE\\u05E4\\u05EA\\u05D7 \\u05DC\\u05D0 \\u05EA\\u05E7\\u05D9\\u05DF \\u05D1\${issue2.origin}\`; + case "invalid_union": + return "\\u05E7\\u05DC\\u05D8 \\u05DC\\u05D0 \\u05EA\\u05E7\\u05D9\\u05DF"; + case "invalid_element": + return \`\\u05E2\\u05E8\\u05DA \\u05DC\\u05D0 \\u05EA\\u05E7\\u05D9\\u05DF \\u05D1\${issue2.origin}\`; + default: + return \`\\u05E7\\u05DC\\u05D8 \\u05DC\\u05D0 \\u05EA\\u05E7\\u05D9\\u05DF\`; + } + }; +}, "error"); +function he_default() { + return { + localeError: error15() + }; +} +__name(he_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/hu.js +var error16 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "karakter", + verb: "legyen" + }, + file: { + unit: "byte", + verb: "legyen" + }, + array: { + unit: "elem", + verb: "legyen" + }, + set: { + unit: "elem", + verb: "legyen" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "sz\\xE1m"; + } + case "object": { + if (Array.isArray(data)) { + return "t\\xF6mb"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "bemenet", + email: "email c\\xEDm", + url: "URL", + emoji: "emoji", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "ISO id\\u0151b\\xE9lyeg", + date: "ISO d\\xE1tum", + time: "ISO id\\u0151", + duration: "ISO id\\u0151intervallum", + ipv4: "IPv4 c\\xEDm", + ipv6: "IPv6 c\\xEDm", + cidrv4: "IPv4 tartom\\xE1ny", + cidrv6: "IPv6 tartom\\xE1ny", + base64: "base64-k\\xF3dolt string", + base64url: "base64url-k\\xF3dolt string", + json_string: "JSON string", + e164: "E.164 sz\\xE1m", + jwt: "JWT", + template_literal: "bemenet" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`\\xC9rv\\xE9nytelen bemenet: a v\\xE1rt \\xE9rt\\xE9k \${issue2.expected}, a kapott \\xE9rt\\xE9k \${parsedType7(issue2.input)}\`; + // return \`Invalid input: expected \${issue.expected}, received \${util.getParsedType(issue.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`\\xC9rv\\xE9nytelen bemenet: a v\\xE1rt \\xE9rt\\xE9k \${stringifyPrimitive(issue2.values[0])}\`; + return \`\\xC9rv\\xE9nytelen opci\\xF3: valamelyik \\xE9rt\\xE9k v\\xE1rt \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`T\\xFAl nagy: \${issue2.origin ?? "\\xE9rt\\xE9k"} m\\xE9rete t\\xFAl nagy \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "elem"}\`; + return \`T\\xFAl nagy: a bemeneti \\xE9rt\\xE9k \${issue2.origin ?? "\\xE9rt\\xE9k"} t\\xFAl nagy: \${adj}\${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`T\\xFAl kicsi: a bemeneti \\xE9rt\\xE9k \${issue2.origin} m\\xE9rete t\\xFAl kicsi \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; + } + return \`T\\xFAl kicsi: a bemeneti \\xE9rt\\xE9k \${issue2.origin} t\\xFAl kicsi \${adj}\${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") return \`\\xC9rv\\xE9nytelen string: "\${_issue.prefix}" \\xE9rt\\xE9kkel kell kezd\\u0151dnie\`; + if (_issue.format === "ends_with") return \`\\xC9rv\\xE9nytelen string: "\${_issue.suffix}" \\xE9rt\\xE9kkel kell v\\xE9gz\\u0151dnie\`; + if (_issue.format === "includes") return \`\\xC9rv\\xE9nytelen string: "\${_issue.includes}" \\xE9rt\\xE9ket kell tartalmaznia\`; + if (_issue.format === "regex") return \`\\xC9rv\\xE9nytelen string: \${_issue.pattern} mint\\xE1nak kell megfelelnie\`; + return \`\\xC9rv\\xE9nytelen \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`\\xC9rv\\xE9nytelen sz\\xE1m: \${issue2.divisor} t\\xF6bbsz\\xF6r\\xF6s\\xE9nek kell lennie\`; + case "unrecognized_keys": + return \`Ismeretlen kulcs\${issue2.keys.length > 1 ? "s" : ""}: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`\\xC9rv\\xE9nytelen kulcs \${issue2.origin}\`; + case "invalid_union": + return "\\xC9rv\\xE9nytelen bemenet"; + case "invalid_element": + return \`\\xC9rv\\xE9nytelen \\xE9rt\\xE9k: \${issue2.origin}\`; + default: + return \`\\xC9rv\\xE9nytelen bemenet\`; + } + }; +}, "error"); +function hu_default() { + return { + localeError: error16() + }; +} +__name(hu_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/id.js +var error17 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "karakter", + verb: "memiliki" + }, + file: { + unit: "byte", + verb: "memiliki" + }, + array: { + unit: "item", + verb: "memiliki" + }, + set: { + unit: "item", + verb: "memiliki" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "number"; + } + case "object": { + if (Array.isArray(data)) { + return "array"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "input", + email: "alamat email", + url: "URL", + emoji: "emoji", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "tanggal dan waktu format ISO", + date: "tanggal format ISO", + time: "jam format ISO", + duration: "durasi format ISO", + ipv4: "alamat IPv4", + ipv6: "alamat IPv6", + cidrv4: "rentang alamat IPv4", + cidrv6: "rentang alamat IPv6", + base64: "string dengan enkode base64", + base64url: "string dengan enkode base64url", + json_string: "string JSON", + e164: "angka E.164", + jwt: "JWT", + template_literal: "input" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`Input tidak valid: diharapkan \${issue2.expected}, diterima \${parsedType7(issue2.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`Input tidak valid: diharapkan \${stringifyPrimitive(issue2.values[0])}\`; + return \`Pilihan tidak valid: diharapkan salah satu dari \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`Terlalu besar: diharapkan \${issue2.origin ?? "value"} memiliki \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "elemen"}\`; + return \`Terlalu besar: diharapkan \${issue2.origin ?? "value"} menjadi \${adj}\${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`Terlalu kecil: diharapkan \${issue2.origin} memiliki \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; + } + return \`Terlalu kecil: diharapkan \${issue2.origin} menjadi \${adj}\${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") return \`String tidak valid: harus dimulai dengan "\${_issue.prefix}"\`; + if (_issue.format === "ends_with") return \`String tidak valid: harus berakhir dengan "\${_issue.suffix}"\`; + if (_issue.format === "includes") return \`String tidak valid: harus menyertakan "\${_issue.includes}"\`; + if (_issue.format === "regex") return \`String tidak valid: harus sesuai pola \${_issue.pattern}\`; + return \`\${Nouns[_issue.format] ?? issue2.format} tidak valid\`; + } + case "not_multiple_of": + return \`Angka tidak valid: harus kelipatan dari \${issue2.divisor}\`; + case "unrecognized_keys": + return \`Kunci tidak dikenali \${issue2.keys.length > 1 ? "s" : ""}: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`Kunci tidak valid di \${issue2.origin}\`; + case "invalid_union": + return "Input tidak valid"; + case "invalid_element": + return \`Nilai tidak valid di \${issue2.origin}\`; + default: + return \`Input tidak valid\`; + } + }; +}, "error"); +function id_default() { + return { + localeError: error17() + }; +} +__name(id_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/is.js +var parsedType3 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "n\\xFAmer"; + } + case "object": { + if (Array.isArray(data)) { + return "fylki"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; +}, "parsedType"); +var error18 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "stafi", + verb: "a\\xF0 hafa" + }, + file: { + unit: "b\\xE6ti", + verb: "a\\xF0 hafa" + }, + array: { + unit: "hluti", + verb: "a\\xF0 hafa" + }, + set: { + unit: "hluti", + verb: "a\\xF0 hafa" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const Nouns = { + regex: "gildi", + email: "netfang", + url: "vefsl\\xF3\\xF0", + emoji: "emoji", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "ISO dagsetning og t\\xEDmi", + date: "ISO dagsetning", + time: "ISO t\\xEDmi", + duration: "ISO t\\xEDmalengd", + ipv4: "IPv4 address", + ipv6: "IPv6 address", + cidrv4: "IPv4 range", + cidrv6: "IPv6 range", + base64: "base64-encoded strengur", + base64url: "base64url-encoded strengur", + json_string: "JSON strengur", + e164: "E.164 t\\xF6lugildi", + jwt: "JWT", + template_literal: "gildi" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`Rangt gildi: \\xDE\\xFA sl\\xF3st inn \${parsedType3(issue2.input)} \\xFEar sem \\xE1 a\\xF0 vera \${issue2.expected}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`Rangt gildi: gert r\\xE1\\xF0 fyrir \${stringifyPrimitive(issue2.values[0])}\`; + return \`\\xD3gilt val: m\\xE1 vera eitt af eftirfarandi \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`Of st\\xF3rt: gert er r\\xE1\\xF0 fyrir a\\xF0 \${issue2.origin ?? "gildi"} hafi \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "hluti"}\`; + return \`Of st\\xF3rt: gert er r\\xE1\\xF0 fyrir a\\xF0 \${issue2.origin ?? "gildi"} s\\xE9 \${adj}\${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`Of l\\xEDti\\xF0: gert er r\\xE1\\xF0 fyrir a\\xF0 \${issue2.origin} hafi \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; + } + return \`Of l\\xEDti\\xF0: gert er r\\xE1\\xF0 fyrir a\\xF0 \${issue2.origin} s\\xE9 \${adj}\${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") { + return \`\\xD3gildur strengur: ver\\xF0ur a\\xF0 byrja \\xE1 "\${_issue.prefix}"\`; + } + if (_issue.format === "ends_with") return \`\\xD3gildur strengur: ver\\xF0ur a\\xF0 enda \\xE1 "\${_issue.suffix}"\`; + if (_issue.format === "includes") return \`\\xD3gildur strengur: ver\\xF0ur a\\xF0 innihalda "\${_issue.includes}"\`; + if (_issue.format === "regex") return \`\\xD3gildur strengur: ver\\xF0ur a\\xF0 fylgja mynstri \${_issue.pattern}\`; + return \`Rangt \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`R\\xF6ng tala: ver\\xF0ur a\\xF0 vera margfeldi af \${issue2.divisor}\`; + case "unrecognized_keys": + return \`\\xD3\\xFEekkt \${issue2.keys.length > 1 ? "ir lyklar" : "ur lykill"}: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`Rangur lykill \\xED \${issue2.origin}\`; + case "invalid_union": + return "Rangt gildi"; + case "invalid_element": + return \`Rangt gildi \\xED \${issue2.origin}\`; + default: + return \`Rangt gildi\`; + } + }; +}, "error"); +function is_default() { + return { + localeError: error18() + }; +} +__name(is_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/it.js +var error19 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "caratteri", + verb: "avere" + }, + file: { + unit: "byte", + verb: "avere" + }, + array: { + unit: "elementi", + verb: "avere" + }, + set: { + unit: "elementi", + verb: "avere" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "numero"; + } + case "object": { + if (Array.isArray(data)) { + return "vettore"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "input", + email: "indirizzo email", + url: "URL", + emoji: "emoji", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "data e ora ISO", + date: "data ISO", + time: "ora ISO", + duration: "durata ISO", + ipv4: "indirizzo IPv4", + ipv6: "indirizzo IPv6", + cidrv4: "intervallo IPv4", + cidrv6: "intervallo IPv6", + base64: "stringa codificata in base64", + base64url: "URL codificata in base64", + json_string: "stringa JSON", + e164: "numero E.164", + jwt: "JWT", + template_literal: "input" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`Input non valido: atteso \${issue2.expected}, ricevuto \${parsedType7(issue2.input)}\`; + // return \`Input non valido: atteso \${issue.expected}, ricevuto \${util.getParsedType(issue.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`Input non valido: atteso \${stringifyPrimitive(issue2.values[0])}\`; + return \`Opzione non valida: atteso uno tra \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`Troppo grande: \${issue2.origin ?? "valore"} deve avere \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "elementi"}\`; + return \`Troppo grande: \${issue2.origin ?? "valore"} deve essere \${adj}\${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`Troppo piccolo: \${issue2.origin} deve avere \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; + } + return \`Troppo piccolo: \${issue2.origin} deve essere \${adj}\${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") return \`Stringa non valida: deve iniziare con "\${_issue.prefix}"\`; + if (_issue.format === "ends_with") return \`Stringa non valida: deve terminare con "\${_issue.suffix}"\`; + if (_issue.format === "includes") return \`Stringa non valida: deve includere "\${_issue.includes}"\`; + if (_issue.format === "regex") return \`Stringa non valida: deve corrispondere al pattern \${_issue.pattern}\`; + return \`Invalid \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`Numero non valido: deve essere un multiplo di \${issue2.divisor}\`; + case "unrecognized_keys": + return \`Chiav\${issue2.keys.length > 1 ? "i" : "e"} non riconosciut\${issue2.keys.length > 1 ? "e" : "a"}: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`Chiave non valida in \${issue2.origin}\`; + case "invalid_union": + return "Input non valido"; + case "invalid_element": + return \`Valore non valido in \${issue2.origin}\`; + default: + return \`Input non valido\`; + } + }; +}, "error"); +function it_default() { + return { + localeError: error19() + }; +} +__name(it_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/ja.js +var error20 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "\\u6587\\u5B57", + verb: "\\u3067\\u3042\\u308B" + }, + file: { + unit: "\\u30D0\\u30A4\\u30C8", + verb: "\\u3067\\u3042\\u308B" + }, + array: { + unit: "\\u8981\\u7D20", + verb: "\\u3067\\u3042\\u308B" + }, + set: { + unit: "\\u8981\\u7D20", + verb: "\\u3067\\u3042\\u308B" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "\\u6570\\u5024"; + } + case "object": { + if (Array.isArray(data)) { + return "\\u914D\\u5217"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "\\u5165\\u529B\\u5024", + email: "\\u30E1\\u30FC\\u30EB\\u30A2\\u30C9\\u30EC\\u30B9", + url: "URL", + emoji: "\\u7D75\\u6587\\u5B57", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "ISO\\u65E5\\u6642", + date: "ISO\\u65E5\\u4ED8", + time: "ISO\\u6642\\u523B", + duration: "ISO\\u671F\\u9593", + ipv4: "IPv4\\u30A2\\u30C9\\u30EC\\u30B9", + ipv6: "IPv6\\u30A2\\u30C9\\u30EC\\u30B9", + cidrv4: "IPv4\\u7BC4\\u56F2", + cidrv6: "IPv6\\u7BC4\\u56F2", + base64: "base64\\u30A8\\u30F3\\u30B3\\u30FC\\u30C9\\u6587\\u5B57\\u5217", + base64url: "base64url\\u30A8\\u30F3\\u30B3\\u30FC\\u30C9\\u6587\\u5B57\\u5217", + json_string: "JSON\\u6587\\u5B57\\u5217", + e164: "E.164\\u756A\\u53F7", + jwt: "JWT", + template_literal: "\\u5165\\u529B\\u5024" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`\\u7121\\u52B9\\u306A\\u5165\\u529B: \${issue2.expected}\\u304C\\u671F\\u5F85\\u3055\\u308C\\u307E\\u3057\\u305F\\u304C\\u3001\${parsedType7(issue2.input)}\\u304C\\u5165\\u529B\\u3055\\u308C\\u307E\\u3057\\u305F\`; + case "invalid_value": + if (issue2.values.length === 1) return \`\\u7121\\u52B9\\u306A\\u5165\\u529B: \${stringifyPrimitive(issue2.values[0])}\\u304C\\u671F\\u5F85\\u3055\\u308C\\u307E\\u3057\\u305F\`; + return \`\\u7121\\u52B9\\u306A\\u9078\\u629E: \${joinValues(issue2.values, "\\u3001")}\\u306E\\u3044\\u305A\\u308C\\u304B\\u3067\\u3042\\u308B\\u5FC5\\u8981\\u304C\\u3042\\u308A\\u307E\\u3059\`; + case "too_big": { + const adj = issue2.inclusive ? "\\u4EE5\\u4E0B\\u3067\\u3042\\u308B" : "\\u3088\\u308A\\u5C0F\\u3055\\u3044"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`\\u5927\\u304D\\u3059\\u304E\\u308B\\u5024: \${issue2.origin ?? "\\u5024"}\\u306F\${issue2.maximum.toString()}\${sizing.unit ?? "\\u8981\\u7D20"}\${adj}\\u5FC5\\u8981\\u304C\\u3042\\u308A\\u307E\\u3059\`; + return \`\\u5927\\u304D\\u3059\\u304E\\u308B\\u5024: \${issue2.origin ?? "\\u5024"}\\u306F\${issue2.maximum.toString()}\${adj}\\u5FC5\\u8981\\u304C\\u3042\\u308A\\u307E\\u3059\`; + } + case "too_small": { + const adj = issue2.inclusive ? "\\u4EE5\\u4E0A\\u3067\\u3042\\u308B" : "\\u3088\\u308A\\u5927\\u304D\\u3044"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`\\u5C0F\\u3055\\u3059\\u304E\\u308B\\u5024: \${issue2.origin}\\u306F\${issue2.minimum.toString()}\${sizing.unit}\${adj}\\u5FC5\\u8981\\u304C\\u3042\\u308A\\u307E\\u3059\`; + return \`\\u5C0F\\u3055\\u3059\\u304E\\u308B\\u5024: \${issue2.origin}\\u306F\${issue2.minimum.toString()}\${adj}\\u5FC5\\u8981\\u304C\\u3042\\u308A\\u307E\\u3059\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") return \`\\u7121\\u52B9\\u306A\\u6587\\u5B57\\u5217: "\${_issue.prefix}"\\u3067\\u59CB\\u307E\\u308B\\u5FC5\\u8981\\u304C\\u3042\\u308A\\u307E\\u3059\`; + if (_issue.format === "ends_with") return \`\\u7121\\u52B9\\u306A\\u6587\\u5B57\\u5217: "\${_issue.suffix}"\\u3067\\u7D42\\u308F\\u308B\\u5FC5\\u8981\\u304C\\u3042\\u308A\\u307E\\u3059\`; + if (_issue.format === "includes") return \`\\u7121\\u52B9\\u306A\\u6587\\u5B57\\u5217: "\${_issue.includes}"\\u3092\\u542B\\u3080\\u5FC5\\u8981\\u304C\\u3042\\u308A\\u307E\\u3059\`; + if (_issue.format === "regex") return \`\\u7121\\u52B9\\u306A\\u6587\\u5B57\\u5217: \\u30D1\\u30BF\\u30FC\\u30F3\${_issue.pattern}\\u306B\\u4E00\\u81F4\\u3059\\u308B\\u5FC5\\u8981\\u304C\\u3042\\u308A\\u307E\\u3059\`; + return \`\\u7121\\u52B9\\u306A\${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`\\u7121\\u52B9\\u306A\\u6570\\u5024: \${issue2.divisor}\\u306E\\u500D\\u6570\\u3067\\u3042\\u308B\\u5FC5\\u8981\\u304C\\u3042\\u308A\\u307E\\u3059\`; + case "unrecognized_keys": + return \`\\u8A8D\\u8B58\\u3055\\u308C\\u3066\\u3044\\u306A\\u3044\\u30AD\\u30FC\${issue2.keys.length > 1 ? "\\u7FA4" : ""}: \${joinValues(issue2.keys, "\\u3001")}\`; + case "invalid_key": + return \`\${issue2.origin}\\u5185\\u306E\\u7121\\u52B9\\u306A\\u30AD\\u30FC\`; + case "invalid_union": + return "\\u7121\\u52B9\\u306A\\u5165\\u529B"; + case "invalid_element": + return \`\${issue2.origin}\\u5185\\u306E\\u7121\\u52B9\\u306A\\u5024\`; + default: + return \`\\u7121\\u52B9\\u306A\\u5165\\u529B\`; + } + }; +}, "error"); +function ja_default() { + return { + localeError: error20() + }; +} +__name(ja_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/ka.js +var parsedType4 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "\\u10E0\\u10D8\\u10EA\\u10EE\\u10D5\\u10D8"; + } + case "object": { + if (Array.isArray(data)) { + return "\\u10DB\\u10D0\\u10E1\\u10D8\\u10D5\\u10D8"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + const typeMap = { + string: "\\u10E1\\u10E2\\u10E0\\u10D8\\u10DC\\u10D2\\u10D8", + boolean: "\\u10D1\\u10E3\\u10DA\\u10D4\\u10D0\\u10DC\\u10D8", + undefined: "undefined", + bigint: "bigint", + symbol: "symbol", + function: "\\u10E4\\u10E3\\u10DC\\u10E5\\u10EA\\u10D8\\u10D0" + }; + return typeMap[t] ?? t; +}, "parsedType"); +var error21 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "\\u10E1\\u10D8\\u10DB\\u10D1\\u10DD\\u10DA\\u10DD", + verb: "\\u10E3\\u10DC\\u10D3\\u10D0 \\u10E8\\u10D4\\u10D8\\u10EA\\u10D0\\u10D5\\u10D3\\u10D4\\u10E1" + }, + file: { + unit: "\\u10D1\\u10D0\\u10D8\\u10E2\\u10D8", + verb: "\\u10E3\\u10DC\\u10D3\\u10D0 \\u10E8\\u10D4\\u10D8\\u10EA\\u10D0\\u10D5\\u10D3\\u10D4\\u10E1" + }, + array: { + unit: "\\u10D4\\u10DA\\u10D4\\u10DB\\u10D4\\u10DC\\u10E2\\u10D8", + verb: "\\u10E3\\u10DC\\u10D3\\u10D0 \\u10E8\\u10D4\\u10D8\\u10EA\\u10D0\\u10D5\\u10D3\\u10D4\\u10E1" + }, + set: { + unit: "\\u10D4\\u10DA\\u10D4\\u10DB\\u10D4\\u10DC\\u10E2\\u10D8", + verb: "\\u10E3\\u10DC\\u10D3\\u10D0 \\u10E8\\u10D4\\u10D8\\u10EA\\u10D0\\u10D5\\u10D3\\u10D4\\u10E1" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const Nouns = { + regex: "\\u10E8\\u10D4\\u10E7\\u10D5\\u10D0\\u10DC\\u10D0", + email: "\\u10D4\\u10DA-\\u10E4\\u10DD\\u10E1\\u10E2\\u10D8\\u10E1 \\u10DB\\u10D8\\u10E1\\u10D0\\u10DB\\u10D0\\u10E0\\u10D7\\u10D8", + url: "URL", + emoji: "\\u10D4\\u10DB\\u10DD\\u10EF\\u10D8", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "\\u10D7\\u10D0\\u10E0\\u10D8\\u10E6\\u10D8-\\u10D3\\u10E0\\u10DD", + date: "\\u10D7\\u10D0\\u10E0\\u10D8\\u10E6\\u10D8", + time: "\\u10D3\\u10E0\\u10DD", + duration: "\\u10EE\\u10D0\\u10DC\\u10D2\\u10E0\\u10EB\\u10DA\\u10D8\\u10D5\\u10DD\\u10D1\\u10D0", + ipv4: "IPv4 \\u10DB\\u10D8\\u10E1\\u10D0\\u10DB\\u10D0\\u10E0\\u10D7\\u10D8", + ipv6: "IPv6 \\u10DB\\u10D8\\u10E1\\u10D0\\u10DB\\u10D0\\u10E0\\u10D7\\u10D8", + cidrv4: "IPv4 \\u10D3\\u10D8\\u10D0\\u10DE\\u10D0\\u10D6\\u10DD\\u10DC\\u10D8", + cidrv6: "IPv6 \\u10D3\\u10D8\\u10D0\\u10DE\\u10D0\\u10D6\\u10DD\\u10DC\\u10D8", + base64: "base64-\\u10D9\\u10DD\\u10D3\\u10D8\\u10E0\\u10D4\\u10D1\\u10E3\\u10DA\\u10D8 \\u10E1\\u10E2\\u10E0\\u10D8\\u10DC\\u10D2\\u10D8", + base64url: "base64url-\\u10D9\\u10DD\\u10D3\\u10D8\\u10E0\\u10D4\\u10D1\\u10E3\\u10DA\\u10D8 \\u10E1\\u10E2\\u10E0\\u10D8\\u10DC\\u10D2\\u10D8", + json_string: "JSON \\u10E1\\u10E2\\u10E0\\u10D8\\u10DC\\u10D2\\u10D8", + e164: "E.164 \\u10DC\\u10DD\\u10DB\\u10D4\\u10E0\\u10D8", + jwt: "JWT", + template_literal: "\\u10E8\\u10D4\\u10E7\\u10D5\\u10D0\\u10DC\\u10D0" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`\\u10D0\\u10E0\\u10D0\\u10E1\\u10EC\\u10DD\\u10E0\\u10D8 \\u10E8\\u10D4\\u10E7\\u10D5\\u10D0\\u10DC\\u10D0: \\u10DB\\u10DD\\u10E1\\u10D0\\u10DA\\u10DD\\u10D3\\u10DC\\u10D4\\u10DA\\u10D8 \${issue2.expected}, \\u10DB\\u10D8\\u10E6\\u10D4\\u10D1\\u10E3\\u10DA\\u10D8 \${parsedType4(issue2.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`\\u10D0\\u10E0\\u10D0\\u10E1\\u10EC\\u10DD\\u10E0\\u10D8 \\u10E8\\u10D4\\u10E7\\u10D5\\u10D0\\u10DC\\u10D0: \\u10DB\\u10DD\\u10E1\\u10D0\\u10DA\\u10DD\\u10D3\\u10DC\\u10D4\\u10DA\\u10D8 \${stringifyPrimitive(issue2.values[0])}\`; + return \`\\u10D0\\u10E0\\u10D0\\u10E1\\u10EC\\u10DD\\u10E0\\u10D8 \\u10D5\\u10D0\\u10E0\\u10D8\\u10D0\\u10DC\\u10E2\\u10D8: \\u10DB\\u10DD\\u10E1\\u10D0\\u10DA\\u10DD\\u10D3\\u10DC\\u10D4\\u10DA\\u10D8\\u10D0 \\u10D4\\u10E0\\u10D7-\\u10D4\\u10E0\\u10D7\\u10D8 \${joinValues(issue2.values, "|")}-\\u10D3\\u10D0\\u10DC\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`\\u10D6\\u10D4\\u10D3\\u10DB\\u10D4\\u10E2\\u10D0\\u10D3 \\u10D3\\u10D8\\u10D3\\u10D8: \\u10DB\\u10DD\\u10E1\\u10D0\\u10DA\\u10DD\\u10D3\\u10DC\\u10D4\\u10DA\\u10D8 \${issue2.origin ?? "\\u10DB\\u10DC\\u10D8\\u10E8\\u10D5\\u10DC\\u10D4\\u10DA\\u10DD\\u10D1\\u10D0"} \${sizing.verb} \${adj}\${issue2.maximum.toString()} \${sizing.unit}\`; + return \`\\u10D6\\u10D4\\u10D3\\u10DB\\u10D4\\u10E2\\u10D0\\u10D3 \\u10D3\\u10D8\\u10D3\\u10D8: \\u10DB\\u10DD\\u10E1\\u10D0\\u10DA\\u10DD\\u10D3\\u10DC\\u10D4\\u10DA\\u10D8 \${issue2.origin ?? "\\u10DB\\u10DC\\u10D8\\u10E8\\u10D5\\u10DC\\u10D4\\u10DA\\u10DD\\u10D1\\u10D0"} \\u10D8\\u10E7\\u10DD\\u10E1 \${adj}\${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`\\u10D6\\u10D4\\u10D3\\u10DB\\u10D4\\u10E2\\u10D0\\u10D3 \\u10DE\\u10D0\\u10E2\\u10D0\\u10E0\\u10D0: \\u10DB\\u10DD\\u10E1\\u10D0\\u10DA\\u10DD\\u10D3\\u10DC\\u10D4\\u10DA\\u10D8 \${issue2.origin} \${sizing.verb} \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; + } + return \`\\u10D6\\u10D4\\u10D3\\u10DB\\u10D4\\u10E2\\u10D0\\u10D3 \\u10DE\\u10D0\\u10E2\\u10D0\\u10E0\\u10D0: \\u10DB\\u10DD\\u10E1\\u10D0\\u10DA\\u10DD\\u10D3\\u10DC\\u10D4\\u10DA\\u10D8 \${issue2.origin} \\u10D8\\u10E7\\u10DD\\u10E1 \${adj}\${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") { + return \`\\u10D0\\u10E0\\u10D0\\u10E1\\u10EC\\u10DD\\u10E0\\u10D8 \\u10E1\\u10E2\\u10E0\\u10D8\\u10DC\\u10D2\\u10D8: \\u10E3\\u10DC\\u10D3\\u10D0 \\u10D8\\u10EC\\u10E7\\u10D4\\u10D1\\u10DD\\u10D3\\u10D4\\u10E1 "\${_issue.prefix}"-\\u10D8\\u10D7\`; + } + if (_issue.format === "ends_with") return \`\\u10D0\\u10E0\\u10D0\\u10E1\\u10EC\\u10DD\\u10E0\\u10D8 \\u10E1\\u10E2\\u10E0\\u10D8\\u10DC\\u10D2\\u10D8: \\u10E3\\u10DC\\u10D3\\u10D0 \\u10DB\\u10D7\\u10D0\\u10D5\\u10E0\\u10D3\\u10D4\\u10D1\\u10DD\\u10D3\\u10D4\\u10E1 "\${_issue.suffix}"-\\u10D8\\u10D7\`; + if (_issue.format === "includes") return \`\\u10D0\\u10E0\\u10D0\\u10E1\\u10EC\\u10DD\\u10E0\\u10D8 \\u10E1\\u10E2\\u10E0\\u10D8\\u10DC\\u10D2\\u10D8: \\u10E3\\u10DC\\u10D3\\u10D0 \\u10E8\\u10D4\\u10D8\\u10EA\\u10D0\\u10D5\\u10D3\\u10D4\\u10E1 "\${_issue.includes}"-\\u10E1\`; + if (_issue.format === "regex") return \`\\u10D0\\u10E0\\u10D0\\u10E1\\u10EC\\u10DD\\u10E0\\u10D8 \\u10E1\\u10E2\\u10E0\\u10D8\\u10DC\\u10D2\\u10D8: \\u10E3\\u10DC\\u10D3\\u10D0 \\u10E8\\u10D4\\u10D4\\u10E1\\u10D0\\u10D1\\u10D0\\u10DB\\u10D4\\u10D1\\u10DD\\u10D3\\u10D4\\u10E1 \\u10E8\\u10D0\\u10D1\\u10DA\\u10DD\\u10DC\\u10E1 \${_issue.pattern}\`; + return \`\\u10D0\\u10E0\\u10D0\\u10E1\\u10EC\\u10DD\\u10E0\\u10D8 \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`\\u10D0\\u10E0\\u10D0\\u10E1\\u10EC\\u10DD\\u10E0\\u10D8 \\u10E0\\u10D8\\u10EA\\u10EE\\u10D5\\u10D8: \\u10E3\\u10DC\\u10D3\\u10D0 \\u10D8\\u10E7\\u10DD\\u10E1 \${issue2.divisor}-\\u10D8\\u10E1 \\u10EF\\u10D4\\u10E0\\u10D0\\u10D3\\u10D8\`; + case "unrecognized_keys": + return \`\\u10E3\\u10EA\\u10DC\\u10DD\\u10D1\\u10D8 \\u10D2\\u10D0\\u10E1\\u10D0\\u10E6\\u10D4\\u10D1\${issue2.keys.length > 1 ? "\\u10D4\\u10D1\\u10D8" : "\\u10D8"}: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`\\u10D0\\u10E0\\u10D0\\u10E1\\u10EC\\u10DD\\u10E0\\u10D8 \\u10D2\\u10D0\\u10E1\\u10D0\\u10E6\\u10D4\\u10D1\\u10D8 \${issue2.origin}-\\u10E8\\u10D8\`; + case "invalid_union": + return "\\u10D0\\u10E0\\u10D0\\u10E1\\u10EC\\u10DD\\u10E0\\u10D8 \\u10E8\\u10D4\\u10E7\\u10D5\\u10D0\\u10DC\\u10D0"; + case "invalid_element": + return \`\\u10D0\\u10E0\\u10D0\\u10E1\\u10EC\\u10DD\\u10E0\\u10D8 \\u10DB\\u10DC\\u10D8\\u10E8\\u10D5\\u10DC\\u10D4\\u10DA\\u10DD\\u10D1\\u10D0 \${issue2.origin}-\\u10E8\\u10D8\`; + default: + return \`\\u10D0\\u10E0\\u10D0\\u10E1\\u10EC\\u10DD\\u10E0\\u10D8 \\u10E8\\u10D4\\u10E7\\u10D5\\u10D0\\u10DC\\u10D0\`; + } + }; +}, "error"); +function ka_default() { + return { + localeError: error21() + }; +} +__name(ka_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/km.js +var error22 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "\\u178F\\u17BD\\u17A2\\u1780\\u17D2\\u179F\\u179A", + verb: "\\u1782\\u17BD\\u179A\\u1798\\u17B6\\u1793" + }, + file: { + unit: "\\u1794\\u17C3", + verb: "\\u1782\\u17BD\\u179A\\u1798\\u17B6\\u1793" + }, + array: { + unit: "\\u1792\\u17B6\\u178F\\u17BB", + verb: "\\u1782\\u17BD\\u179A\\u1798\\u17B6\\u1793" + }, + set: { + unit: "\\u1792\\u17B6\\u178F\\u17BB", + verb: "\\u1782\\u17BD\\u179A\\u1798\\u17B6\\u1793" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "\\u1798\\u17B7\\u1793\\u1798\\u17C2\\u1793\\u1787\\u17B6\\u179B\\u17C1\\u1781 (NaN)" : "\\u179B\\u17C1\\u1781"; + } + case "object": { + if (Array.isArray(data)) { + return "\\u17A2\\u17B6\\u179A\\u17C1 (Array)"; + } + if (data === null) { + return "\\u1782\\u17D2\\u1798\\u17B6\\u1793\\u178F\\u1798\\u17D2\\u179B\\u17C3 (null)"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "\\u1791\\u17B7\\u1793\\u17D2\\u1793\\u1793\\u17D0\\u1799\\u1794\\u1789\\u17D2\\u1785\\u17BC\\u179B", + email: "\\u17A2\\u17B6\\u179F\\u1799\\u178A\\u17D2\\u178B\\u17B6\\u1793\\u17A2\\u17CA\\u17B8\\u1798\\u17C2\\u179B", + url: "URL", + emoji: "\\u179F\\u1789\\u17D2\\u1789\\u17B6\\u17A2\\u17B6\\u179A\\u1798\\u17D2\\u1798\\u178E\\u17CD", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "\\u1780\\u17B6\\u179B\\u1794\\u179A\\u17B7\\u1785\\u17D2\\u1786\\u17C1\\u1791 \\u1793\\u17B7\\u1784\\u1798\\u17C9\\u17C4\\u1784 ISO", + date: "\\u1780\\u17B6\\u179B\\u1794\\u179A\\u17B7\\u1785\\u17D2\\u1786\\u17C1\\u1791 ISO", + time: "\\u1798\\u17C9\\u17C4\\u1784 ISO", + duration: "\\u179A\\u1799\\u17C8\\u1796\\u17C1\\u179B ISO", + ipv4: "\\u17A2\\u17B6\\u179F\\u1799\\u178A\\u17D2\\u178B\\u17B6\\u1793 IPv4", + ipv6: "\\u17A2\\u17B6\\u179F\\u1799\\u178A\\u17D2\\u178B\\u17B6\\u1793 IPv6", + cidrv4: "\\u178A\\u17C2\\u1793\\u17A2\\u17B6\\u179F\\u1799\\u178A\\u17D2\\u178B\\u17B6\\u1793 IPv4", + cidrv6: "\\u178A\\u17C2\\u1793\\u17A2\\u17B6\\u179F\\u1799\\u178A\\u17D2\\u178B\\u17B6\\u1793 IPv6", + base64: "\\u1781\\u17D2\\u179F\\u17C2\\u17A2\\u1780\\u17D2\\u179F\\u179A\\u17A2\\u17CA\\u17B7\\u1780\\u17BC\\u178A base64", + base64url: "\\u1781\\u17D2\\u179F\\u17C2\\u17A2\\u1780\\u17D2\\u179F\\u179A\\u17A2\\u17CA\\u17B7\\u1780\\u17BC\\u178A base64url", + json_string: "\\u1781\\u17D2\\u179F\\u17C2\\u17A2\\u1780\\u17D2\\u179F\\u179A JSON", + e164: "\\u179B\\u17C1\\u1781 E.164", + jwt: "JWT", + template_literal: "\\u1791\\u17B7\\u1793\\u17D2\\u1793\\u1793\\u17D0\\u1799\\u1794\\u1789\\u17D2\\u1785\\u17BC\\u179B" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`\\u1791\\u17B7\\u1793\\u17D2\\u1793\\u1793\\u17D0\\u1799\\u1794\\u1789\\u17D2\\u1785\\u17BC\\u179B\\u1798\\u17B7\\u1793\\u178F\\u17D2\\u179A\\u17B9\\u1798\\u178F\\u17D2\\u179A\\u17BC\\u179C\\u17D6 \\u178F\\u17D2\\u179A\\u17BC\\u179C\\u1780\\u17B6\\u179A \${issue2.expected} \\u1794\\u17C9\\u17BB\\u1793\\u17D2\\u178F\\u17C2\\u1791\\u1791\\u17BD\\u179B\\u1794\\u17B6\\u1793 \${parsedType7(issue2.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`\\u1791\\u17B7\\u1793\\u17D2\\u1793\\u1793\\u17D0\\u1799\\u1794\\u1789\\u17D2\\u1785\\u17BC\\u179B\\u1798\\u17B7\\u1793\\u178F\\u17D2\\u179A\\u17B9\\u1798\\u178F\\u17D2\\u179A\\u17BC\\u179C\\u17D6 \\u178F\\u17D2\\u179A\\u17BC\\u179C\\u1780\\u17B6\\u179A \${stringifyPrimitive(issue2.values[0])}\`; + return \`\\u1787\\u1798\\u17D2\\u179A\\u17BE\\u179F\\u1798\\u17B7\\u1793\\u178F\\u17D2\\u179A\\u17B9\\u1798\\u178F\\u17D2\\u179A\\u17BC\\u179C\\u17D6 \\u178F\\u17D2\\u179A\\u17BC\\u179C\\u1787\\u17B6\\u1798\\u17BD\\u1799\\u1780\\u17D2\\u1793\\u17BB\\u1784\\u1785\\u17C6\\u178E\\u17C4\\u1798 \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`\\u1792\\u17C6\\u1796\\u17C1\\u1780\\u17D6 \\u178F\\u17D2\\u179A\\u17BC\\u179C\\u1780\\u17B6\\u179A \${issue2.origin ?? "\\u178F\\u1798\\u17D2\\u179B\\u17C3"} \${adj} \${issue2.maximum.toString()} \${sizing.unit ?? "\\u1792\\u17B6\\u178F\\u17BB"}\`; + return \`\\u1792\\u17C6\\u1796\\u17C1\\u1780\\u17D6 \\u178F\\u17D2\\u179A\\u17BC\\u179C\\u1780\\u17B6\\u179A \${issue2.origin ?? "\\u178F\\u1798\\u17D2\\u179B\\u17C3"} \${adj} \${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`\\u178F\\u17BC\\u1785\\u1796\\u17C1\\u1780\\u17D6 \\u178F\\u17D2\\u179A\\u17BC\\u179C\\u1780\\u17B6\\u179A \${issue2.origin} \${adj} \${issue2.minimum.toString()} \${sizing.unit}\`; + } + return \`\\u178F\\u17BC\\u1785\\u1796\\u17C1\\u1780\\u17D6 \\u178F\\u17D2\\u179A\\u17BC\\u179C\\u1780\\u17B6\\u179A \${issue2.origin} \${adj} \${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") { + return \`\\u1781\\u17D2\\u179F\\u17C2\\u17A2\\u1780\\u17D2\\u179F\\u179A\\u1798\\u17B7\\u1793\\u178F\\u17D2\\u179A\\u17B9\\u1798\\u178F\\u17D2\\u179A\\u17BC\\u179C\\u17D6 \\u178F\\u17D2\\u179A\\u17BC\\u179C\\u1785\\u17B6\\u1794\\u17CB\\u1795\\u17D2\\u178F\\u17BE\\u1798\\u178A\\u17C4\\u1799 "\${_issue.prefix}"\`; + } + if (_issue.format === "ends_with") return \`\\u1781\\u17D2\\u179F\\u17C2\\u17A2\\u1780\\u17D2\\u179F\\u179A\\u1798\\u17B7\\u1793\\u178F\\u17D2\\u179A\\u17B9\\u1798\\u178F\\u17D2\\u179A\\u17BC\\u179C\\u17D6 \\u178F\\u17D2\\u179A\\u17BC\\u179C\\u1794\\u1789\\u17D2\\u1785\\u1794\\u17CB\\u178A\\u17C4\\u1799 "\${_issue.suffix}"\`; + if (_issue.format === "includes") return \`\\u1781\\u17D2\\u179F\\u17C2\\u17A2\\u1780\\u17D2\\u179F\\u179A\\u1798\\u17B7\\u1793\\u178F\\u17D2\\u179A\\u17B9\\u1798\\u178F\\u17D2\\u179A\\u17BC\\u179C\\u17D6 \\u178F\\u17D2\\u179A\\u17BC\\u179C\\u1798\\u17B6\\u1793 "\${_issue.includes}"\`; + if (_issue.format === "regex") return \`\\u1781\\u17D2\\u179F\\u17C2\\u17A2\\u1780\\u17D2\\u179F\\u179A\\u1798\\u17B7\\u1793\\u178F\\u17D2\\u179A\\u17B9\\u1798\\u178F\\u17D2\\u179A\\u17BC\\u179C\\u17D6 \\u178F\\u17D2\\u179A\\u17BC\\u179C\\u178F\\u17C2\\u1795\\u17D2\\u1782\\u17BC\\u1795\\u17D2\\u1782\\u1784\\u1793\\u17B9\\u1784\\u1791\\u1798\\u17D2\\u179A\\u1784\\u17CB\\u178A\\u17C2\\u179B\\u1794\\u17B6\\u1793\\u1780\\u17C6\\u178E\\u178F\\u17CB \${_issue.pattern}\`; + return \`\\u1798\\u17B7\\u1793\\u178F\\u17D2\\u179A\\u17B9\\u1798\\u178F\\u17D2\\u179A\\u17BC\\u179C\\u17D6 \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`\\u179B\\u17C1\\u1781\\u1798\\u17B7\\u1793\\u178F\\u17D2\\u179A\\u17B9\\u1798\\u178F\\u17D2\\u179A\\u17BC\\u179C\\u17D6 \\u178F\\u17D2\\u179A\\u17BC\\u179C\\u178F\\u17C2\\u1787\\u17B6\\u1796\\u17A0\\u17BB\\u1782\\u17BB\\u178E\\u1793\\u17C3 \${issue2.divisor}\`; + case "unrecognized_keys": + return \`\\u179A\\u1780\\u1783\\u17BE\\u1789\\u179F\\u17C4\\u1798\\u17B7\\u1793\\u179F\\u17D2\\u1782\\u17B6\\u179B\\u17CB\\u17D6 \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`\\u179F\\u17C4\\u1798\\u17B7\\u1793\\u178F\\u17D2\\u179A\\u17B9\\u1798\\u178F\\u17D2\\u179A\\u17BC\\u179C\\u1793\\u17C5\\u1780\\u17D2\\u1793\\u17BB\\u1784 \${issue2.origin}\`; + case "invalid_union": + return \`\\u1791\\u17B7\\u1793\\u17D2\\u1793\\u1793\\u17D0\\u1799\\u1798\\u17B7\\u1793\\u178F\\u17D2\\u179A\\u17B9\\u1798\\u178F\\u17D2\\u179A\\u17BC\\u179C\`; + case "invalid_element": + return \`\\u1791\\u17B7\\u1793\\u17D2\\u1793\\u1793\\u17D0\\u1799\\u1798\\u17B7\\u1793\\u178F\\u17D2\\u179A\\u17B9\\u1798\\u178F\\u17D2\\u179A\\u17BC\\u179C\\u1793\\u17C5\\u1780\\u17D2\\u1793\\u17BB\\u1784 \${issue2.origin}\`; + default: + return \`\\u1791\\u17B7\\u1793\\u17D2\\u1793\\u1793\\u17D0\\u1799\\u1798\\u17B7\\u1793\\u178F\\u17D2\\u179A\\u17B9\\u1798\\u178F\\u17D2\\u179A\\u17BC\\u179C\`; + } + }; +}, "error"); +function km_default() { + return { + localeError: error22() + }; +} +__name(km_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/kh.js +function kh_default() { + return km_default(); +} +__name(kh_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/ko.js +var error23 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "\\uBB38\\uC790", + verb: "to have" + }, + file: { + unit: "\\uBC14\\uC774\\uD2B8", + verb: "to have" + }, + array: { + unit: "\\uAC1C", + verb: "to have" + }, + set: { + unit: "\\uAC1C", + verb: "to have" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "number"; + } + case "object": { + if (Array.isArray(data)) { + return "array"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "\\uC785\\uB825", + email: "\\uC774\\uBA54\\uC77C \\uC8FC\\uC18C", + url: "URL", + emoji: "\\uC774\\uBAA8\\uC9C0", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "ISO \\uB0A0\\uC9DC\\uC2DC\\uAC04", + date: "ISO \\uB0A0\\uC9DC", + time: "ISO \\uC2DC\\uAC04", + duration: "ISO \\uAE30\\uAC04", + ipv4: "IPv4 \\uC8FC\\uC18C", + ipv6: "IPv6 \\uC8FC\\uC18C", + cidrv4: "IPv4 \\uBC94\\uC704", + cidrv6: "IPv6 \\uBC94\\uC704", + base64: "base64 \\uC778\\uCF54\\uB529 \\uBB38\\uC790\\uC5F4", + base64url: "base64url \\uC778\\uCF54\\uB529 \\uBB38\\uC790\\uC5F4", + json_string: "JSON \\uBB38\\uC790\\uC5F4", + e164: "E.164 \\uBC88\\uD638", + jwt: "JWT", + template_literal: "\\uC785\\uB825" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`\\uC798\\uBABB\\uB41C \\uC785\\uB825: \\uC608\\uC0C1 \\uD0C0\\uC785\\uC740 \${issue2.expected}, \\uBC1B\\uC740 \\uD0C0\\uC785\\uC740 \${parsedType7(issue2.input)}\\uC785\\uB2C8\\uB2E4\`; + case "invalid_value": + if (issue2.values.length === 1) return \`\\uC798\\uBABB\\uB41C \\uC785\\uB825: \\uAC12\\uC740 \${stringifyPrimitive(issue2.values[0])} \\uC774\\uC5B4\\uC57C \\uD569\\uB2C8\\uB2E4\`; + return \`\\uC798\\uBABB\\uB41C \\uC635\\uC158: \${joinValues(issue2.values, "\\uB610\\uB294 ")} \\uC911 \\uD558\\uB098\\uC5EC\\uC57C \\uD569\\uB2C8\\uB2E4\`; + case "too_big": { + const adj = issue2.inclusive ? "\\uC774\\uD558" : "\\uBBF8\\uB9CC"; + const suffix = adj === "\\uBBF8\\uB9CC" ? "\\uC774\\uC5B4\\uC57C \\uD569\\uB2C8\\uB2E4" : "\\uC5EC\\uC57C \\uD569\\uB2C8\\uB2E4"; + const sizing = getSizing(issue2.origin); + const unit = sizing?.unit ?? "\\uC694\\uC18C"; + if (sizing) return \`\${issue2.origin ?? "\\uAC12"}\\uC774 \\uB108\\uBB34 \\uD07D\\uB2C8\\uB2E4: \${issue2.maximum.toString()}\${unit} \${adj}\${suffix}\`; + return \`\${issue2.origin ?? "\\uAC12"}\\uC774 \\uB108\\uBB34 \\uD07D\\uB2C8\\uB2E4: \${issue2.maximum.toString()} \${adj}\${suffix}\`; + } + case "too_small": { + const adj = issue2.inclusive ? "\\uC774\\uC0C1" : "\\uCD08\\uACFC"; + const suffix = adj === "\\uC774\\uC0C1" ? "\\uC774\\uC5B4\\uC57C \\uD569\\uB2C8\\uB2E4" : "\\uC5EC\\uC57C \\uD569\\uB2C8\\uB2E4"; + const sizing = getSizing(issue2.origin); + const unit = sizing?.unit ?? "\\uC694\\uC18C"; + if (sizing) { + return \`\${issue2.origin ?? "\\uAC12"}\\uC774 \\uB108\\uBB34 \\uC791\\uC2B5\\uB2C8\\uB2E4: \${issue2.minimum.toString()}\${unit} \${adj}\${suffix}\`; + } + return \`\${issue2.origin ?? "\\uAC12"}\\uC774 \\uB108\\uBB34 \\uC791\\uC2B5\\uB2C8\\uB2E4: \${issue2.minimum.toString()} \${adj}\${suffix}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") { + return \`\\uC798\\uBABB\\uB41C \\uBB38\\uC790\\uC5F4: "\${_issue.prefix}"(\\uC73C)\\uB85C \\uC2DC\\uC791\\uD574\\uC57C \\uD569\\uB2C8\\uB2E4\`; + } + if (_issue.format === "ends_with") return \`\\uC798\\uBABB\\uB41C \\uBB38\\uC790\\uC5F4: "\${_issue.suffix}"(\\uC73C)\\uB85C \\uB05D\\uB098\\uC57C \\uD569\\uB2C8\\uB2E4\`; + if (_issue.format === "includes") return \`\\uC798\\uBABB\\uB41C \\uBB38\\uC790\\uC5F4: "\${_issue.includes}"\\uC744(\\uB97C) \\uD3EC\\uD568\\uD574\\uC57C \\uD569\\uB2C8\\uB2E4\`; + if (_issue.format === "regex") return \`\\uC798\\uBABB\\uB41C \\uBB38\\uC790\\uC5F4: \\uC815\\uADDC\\uC2DD \${_issue.pattern} \\uD328\\uD134\\uACFC \\uC77C\\uCE58\\uD574\\uC57C \\uD569\\uB2C8\\uB2E4\`; + return \`\\uC798\\uBABB\\uB41C \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`\\uC798\\uBABB\\uB41C \\uC22B\\uC790: \${issue2.divisor}\\uC758 \\uBC30\\uC218\\uC5EC\\uC57C \\uD569\\uB2C8\\uB2E4\`; + case "unrecognized_keys": + return \`\\uC778\\uC2DD\\uD560 \\uC218 \\uC5C6\\uB294 \\uD0A4: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`\\uC798\\uBABB\\uB41C \\uD0A4: \${issue2.origin}\`; + case "invalid_union": + return \`\\uC798\\uBABB\\uB41C \\uC785\\uB825\`; + case "invalid_element": + return \`\\uC798\\uBABB\\uB41C \\uAC12: \${issue2.origin}\`; + default: + return \`\\uC798\\uBABB\\uB41C \\uC785\\uB825\`; + } + }; +}, "error"); +function ko_default() { + return { + localeError: error23() + }; +} +__name(ko_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/lt.js +var parsedType5 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + return parsedTypeFromType(t, data); +}, "parsedType"); +var parsedTypeFromType = /* @__PURE__ */ __name((t, data = void 0) => { + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "skai\\u010Dius"; + } + case "bigint": { + return "sveikasis skai\\u010Dius"; + } + case "string": { + return "eilut\\u0117"; + } + case "boolean": { + return "login\\u0117 reik\\u0161m\\u0117"; + } + case "undefined": + case "void": { + return "neapibr\\u0117\\u017Eta reik\\u0161m\\u0117"; + } + case "function": { + return "funkcija"; + } + case "symbol": { + return "simbolis"; + } + case "object": { + if (data === void 0) return "ne\\u017Einomas objektas"; + if (data === null) return "nulin\\u0117 reik\\u0161m\\u0117"; + if (Array.isArray(data)) return "masyvas"; + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + return "objektas"; + } + //Zod types below + case "null": { + return "nulin\\u0117 reik\\u0161m\\u0117"; + } + } + return t; +}, "parsedTypeFromType"); +var capitalizeFirstCharacter = /* @__PURE__ */ __name((text2) => { + return text2.charAt(0).toUpperCase() + text2.slice(1); +}, "capitalizeFirstCharacter"); +function getUnitTypeFromNumber(number4) { + const abs = Math.abs(number4); + const last = abs % 10; + const last2 = abs % 100; + if (last2 >= 11 && last2 <= 19 || last === 0) return "many"; + if (last === 1) return "one"; + return "few"; +} +__name(getUnitTypeFromNumber, "getUnitTypeFromNumber"); +var error24 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: { + one: "simbolis", + few: "simboliai", + many: "simboli\\u0173" + }, + verb: { + smaller: { + inclusive: "turi b\\u016Bti ne ilgesn\\u0117 kaip", + notInclusive: "turi b\\u016Bti trumpesn\\u0117 kaip" + }, + bigger: { + inclusive: "turi b\\u016Bti ne trumpesn\\u0117 kaip", + notInclusive: "turi b\\u016Bti ilgesn\\u0117 kaip" + } + } + }, + file: { + unit: { + one: "baitas", + few: "baitai", + many: "bait\\u0173" + }, + verb: { + smaller: { + inclusive: "turi b\\u016Bti ne didesnis kaip", + notInclusive: "turi b\\u016Bti ma\\u017Eesnis kaip" + }, + bigger: { + inclusive: "turi b\\u016Bti ne ma\\u017Eesnis kaip", + notInclusive: "turi b\\u016Bti didesnis kaip" + } + } + }, + array: { + unit: { + one: "element\\u0105", + few: "elementus", + many: "element\\u0173" + }, + verb: { + smaller: { + inclusive: "turi tur\\u0117ti ne daugiau kaip", + notInclusive: "turi tur\\u0117ti ma\\u017Eiau kaip" + }, + bigger: { + inclusive: "turi tur\\u0117ti ne ma\\u017Eiau kaip", + notInclusive: "turi tur\\u0117ti daugiau kaip" + } + } + }, + set: { + unit: { + one: "element\\u0105", + few: "elementus", + many: "element\\u0173" + }, + verb: { + smaller: { + inclusive: "turi tur\\u0117ti ne daugiau kaip", + notInclusive: "turi tur\\u0117ti ma\\u017Eiau kaip" + }, + bigger: { + inclusive: "turi tur\\u0117ti ne ma\\u017Eiau kaip", + notInclusive: "turi tur\\u0117ti daugiau kaip" + } + } + } + }; + function getSizing(origin, unitType, inclusive, targetShouldBe) { + const result = Sizable[origin] ?? null; + if (result === null) return result; + return { + unit: result.unit[unitType], + verb: result.verb[targetShouldBe][inclusive ? "inclusive" : "notInclusive"] + }; + } + __name(getSizing, "getSizing"); + const Nouns = { + regex: "\\u012Fvestis", + email: "el. pa\\u0161to adresas", + url: "URL", + emoji: "jaustukas", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "ISO data ir laikas", + date: "ISO data", + time: "ISO laikas", + duration: "ISO trukm\\u0117", + ipv4: "IPv4 adresas", + ipv6: "IPv6 adresas", + cidrv4: "IPv4 tinklo prefiksas (CIDR)", + cidrv6: "IPv6 tinklo prefiksas (CIDR)", + base64: "base64 u\\u017Ekoduota eilut\\u0117", + base64url: "base64url u\\u017Ekoduota eilut\\u0117", + json_string: "JSON eilut\\u0117", + e164: "E.164 numeris", + jwt: "JWT", + template_literal: "\\u012Fvestis" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`Gautas tipas \${parsedType5(issue2.input)}, o tik\\u0117tasi - \${parsedTypeFromType(issue2.expected)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`Privalo b\\u016Bti \${stringifyPrimitive(issue2.values[0])}\`; + return \`Privalo b\\u016Bti vienas i\\u0161 \${joinValues(issue2.values, "|")} pasirinkim\\u0173\`; + case "too_big": { + const origin = parsedTypeFromType(issue2.origin); + const sizing = getSizing(issue2.origin, getUnitTypeFromNumber(Number(issue2.maximum)), issue2.inclusive ?? false, "smaller"); + if (sizing?.verb) return \`\${capitalizeFirstCharacter(origin ?? issue2.origin ?? "reik\\u0161m\\u0117")} \${sizing.verb} \${issue2.maximum.toString()} \${sizing.unit ?? "element\\u0173"}\`; + const adj = issue2.inclusive ? "ne didesnis kaip" : "ma\\u017Eesnis kaip"; + return \`\${capitalizeFirstCharacter(origin ?? issue2.origin ?? "reik\\u0161m\\u0117")} turi b\\u016Bti \${adj} \${issue2.maximum.toString()} \${sizing?.unit}\`; + } + case "too_small": { + const origin = parsedTypeFromType(issue2.origin); + const sizing = getSizing(issue2.origin, getUnitTypeFromNumber(Number(issue2.minimum)), issue2.inclusive ?? false, "bigger"); + if (sizing?.verb) return \`\${capitalizeFirstCharacter(origin ?? issue2.origin ?? "reik\\u0161m\\u0117")} \${sizing.verb} \${issue2.minimum.toString()} \${sizing.unit ?? "element\\u0173"}\`; + const adj = issue2.inclusive ? "ne ma\\u017Eesnis kaip" : "didesnis kaip"; + return \`\${capitalizeFirstCharacter(origin ?? issue2.origin ?? "reik\\u0161m\\u0117")} turi b\\u016Bti \${adj} \${issue2.minimum.toString()} \${sizing?.unit}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") { + return \`Eilut\\u0117 privalo prasid\\u0117ti "\${_issue.prefix}"\`; + } + if (_issue.format === "ends_with") return \`Eilut\\u0117 privalo pasibaigti "\${_issue.suffix}"\`; + if (_issue.format === "includes") return \`Eilut\\u0117 privalo \\u012Ftraukti "\${_issue.includes}"\`; + if (_issue.format === "regex") return \`Eilut\\u0117 privalo atitikti \${_issue.pattern}\`; + return \`Neteisingas \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`Skai\\u010Dius privalo b\\u016Bti \${issue2.divisor} kartotinis.\`; + case "unrecognized_keys": + return \`Neatpa\\u017Eint\${issue2.keys.length > 1 ? "i" : "as"} rakt\${issue2.keys.length > 1 ? "ai" : "as"}: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return "Rastas klaidingas raktas"; + case "invalid_union": + return "Klaidinga \\u012Fvestis"; + case "invalid_element": { + const origin = parsedTypeFromType(issue2.origin); + return \`\${capitalizeFirstCharacter(origin ?? issue2.origin ?? "reik\\u0161m\\u0117")} turi klaiding\\u0105 \\u012Fvest\\u012F\`; + } + default: + return "Klaidinga \\u012Fvestis"; + } + }; +}, "error"); +function lt_default() { + return { + localeError: error24() + }; +} +__name(lt_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/mk.js +var error25 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "\\u0437\\u043D\\u0430\\u0446\\u0438", + verb: "\\u0434\\u0430 \\u0438\\u043C\\u0430\\u0430\\u0442" + }, + file: { + unit: "\\u0431\\u0430\\u0458\\u0442\\u0438", + verb: "\\u0434\\u0430 \\u0438\\u043C\\u0430\\u0430\\u0442" + }, + array: { + unit: "\\u0441\\u0442\\u0430\\u0432\\u043A\\u0438", + verb: "\\u0434\\u0430 \\u0438\\u043C\\u0430\\u0430\\u0442" + }, + set: { + unit: "\\u0441\\u0442\\u0430\\u0432\\u043A\\u0438", + verb: "\\u0434\\u0430 \\u0438\\u043C\\u0430\\u0430\\u0442" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "\\u0431\\u0440\\u043E\\u0458"; + } + case "object": { + if (Array.isArray(data)) { + return "\\u043D\\u0438\\u0437\\u0430"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "\\u0432\\u043D\\u0435\\u0441", + email: "\\u0430\\u0434\\u0440\\u0435\\u0441\\u0430 \\u043D\\u0430 \\u0435-\\u043F\\u043E\\u0448\\u0442\\u0430", + url: "URL", + emoji: "\\u0435\\u043C\\u043E\\u045F\\u0438", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "ISO \\u0434\\u0430\\u0442\\u0443\\u043C \\u0438 \\u0432\\u0440\\u0435\\u043C\\u0435", + date: "ISO \\u0434\\u0430\\u0442\\u0443\\u043C", + time: "ISO \\u0432\\u0440\\u0435\\u043C\\u0435", + duration: "ISO \\u0432\\u0440\\u0435\\u043C\\u0435\\u0442\\u0440\\u0430\\u0435\\u045A\\u0435", + ipv4: "IPv4 \\u0430\\u0434\\u0440\\u0435\\u0441\\u0430", + ipv6: "IPv6 \\u0430\\u0434\\u0440\\u0435\\u0441\\u0430", + cidrv4: "IPv4 \\u043E\\u043F\\u0441\\u0435\\u0433", + cidrv6: "IPv6 \\u043E\\u043F\\u0441\\u0435\\u0433", + base64: "base64-\\u0435\\u043D\\u043A\\u043E\\u0434\\u0438\\u0440\\u0430\\u043D\\u0430 \\u043D\\u0438\\u0437\\u0430", + base64url: "base64url-\\u0435\\u043D\\u043A\\u043E\\u0434\\u0438\\u0440\\u0430\\u043D\\u0430 \\u043D\\u0438\\u0437\\u0430", + json_string: "JSON \\u043D\\u0438\\u0437\\u0430", + e164: "E.164 \\u0431\\u0440\\u043E\\u0458", + jwt: "JWT", + template_literal: "\\u0432\\u043D\\u0435\\u0441" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`\\u0413\\u0440\\u0435\\u0448\\u0435\\u043D \\u0432\\u043D\\u0435\\u0441: \\u0441\\u0435 \\u043E\\u0447\\u0435\\u043A\\u0443\\u0432\\u0430 \${issue2.expected}, \\u043F\\u0440\\u0438\\u043C\\u0435\\u043D\\u043E \${parsedType7(issue2.input)}\`; + // return \`Invalid input: expected \${issue.expected}, received \${util.getParsedType(issue.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`Invalid input: expected \${stringifyPrimitive(issue2.values[0])}\`; + return \`\\u0413\\u0440\\u0435\\u0448\\u0430\\u043D\\u0430 \\u043E\\u043F\\u0446\\u0438\\u0458\\u0430: \\u0441\\u0435 \\u043E\\u0447\\u0435\\u043A\\u0443\\u0432\\u0430 \\u0435\\u0434\\u043D\\u0430 \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`\\u041F\\u0440\\u0435\\u043C\\u043D\\u043E\\u0433\\u0443 \\u0433\\u043E\\u043B\\u0435\\u043C: \\u0441\\u0435 \\u043E\\u0447\\u0435\\u043A\\u0443\\u0432\\u0430 \${issue2.origin ?? "\\u0432\\u0440\\u0435\\u0434\\u043D\\u043E\\u0441\\u0442\\u0430"} \\u0434\\u0430 \\u0438\\u043C\\u0430 \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "\\u0435\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442\\u0438"}\`; + return \`\\u041F\\u0440\\u0435\\u043C\\u043D\\u043E\\u0433\\u0443 \\u0433\\u043E\\u043B\\u0435\\u043C: \\u0441\\u0435 \\u043E\\u0447\\u0435\\u043A\\u0443\\u0432\\u0430 \${issue2.origin ?? "\\u0432\\u0440\\u0435\\u0434\\u043D\\u043E\\u0441\\u0442\\u0430"} \\u0434\\u0430 \\u0431\\u0438\\u0434\\u0435 \${adj}\${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`\\u041F\\u0440\\u0435\\u043C\\u043D\\u043E\\u0433\\u0443 \\u043C\\u0430\\u043B: \\u0441\\u0435 \\u043E\\u0447\\u0435\\u043A\\u0443\\u0432\\u0430 \${issue2.origin} \\u0434\\u0430 \\u0438\\u043C\\u0430 \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; + } + return \`\\u041F\\u0440\\u0435\\u043C\\u043D\\u043E\\u0433\\u0443 \\u043C\\u0430\\u043B: \\u0441\\u0435 \\u043E\\u0447\\u0435\\u043A\\u0443\\u0432\\u0430 \${issue2.origin} \\u0434\\u0430 \\u0431\\u0438\\u0434\\u0435 \${adj}\${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") { + return \`\\u041D\\u0435\\u0432\\u0430\\u0436\\u0435\\u0447\\u043A\\u0430 \\u043D\\u0438\\u0437\\u0430: \\u043C\\u043E\\u0440\\u0430 \\u0434\\u0430 \\u0437\\u0430\\u043F\\u043E\\u0447\\u043D\\u0443\\u0432\\u0430 \\u0441\\u043E "\${_issue.prefix}"\`; + } + if (_issue.format === "ends_with") return \`\\u041D\\u0435\\u0432\\u0430\\u0436\\u0435\\u0447\\u043A\\u0430 \\u043D\\u0438\\u0437\\u0430: \\u043C\\u043E\\u0440\\u0430 \\u0434\\u0430 \\u0437\\u0430\\u0432\\u0440\\u0448\\u0443\\u0432\\u0430 \\u0441\\u043E "\${_issue.suffix}"\`; + if (_issue.format === "includes") return \`\\u041D\\u0435\\u0432\\u0430\\u0436\\u0435\\u0447\\u043A\\u0430 \\u043D\\u0438\\u0437\\u0430: \\u043C\\u043E\\u0440\\u0430 \\u0434\\u0430 \\u0432\\u043A\\u043B\\u0443\\u0447\\u0443\\u0432\\u0430 "\${_issue.includes}"\`; + if (_issue.format === "regex") return \`\\u041D\\u0435\\u0432\\u0430\\u0436\\u0435\\u0447\\u043A\\u0430 \\u043D\\u0438\\u0437\\u0430: \\u043C\\u043E\\u0440\\u0430 \\u0434\\u0430 \\u043E\\u0434\\u0433\\u043E\\u0430\\u0440\\u0430 \\u043D\\u0430 \\u043F\\u0430\\u0442\\u0435\\u0440\\u043D\\u043E\\u0442 \${_issue.pattern}\`; + return \`Invalid \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`\\u0413\\u0440\\u0435\\u0448\\u0435\\u043D \\u0431\\u0440\\u043E\\u0458: \\u043C\\u043E\\u0440\\u0430 \\u0434\\u0430 \\u0431\\u0438\\u0434\\u0435 \\u0434\\u0435\\u043B\\u0438\\u0432 \\u0441\\u043E \${issue2.divisor}\`; + case "unrecognized_keys": + return \`\${issue2.keys.length > 1 ? "\\u041D\\u0435\\u043F\\u0440\\u0435\\u043F\\u043E\\u0437\\u043D\\u0430\\u0435\\u043D\\u0438 \\u043A\\u043B\\u0443\\u0447\\u0435\\u0432\\u0438" : "\\u041D\\u0435\\u043F\\u0440\\u0435\\u043F\\u043E\\u0437\\u043D\\u0430\\u0435\\u043D \\u043A\\u043B\\u0443\\u0447"}: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`\\u0413\\u0440\\u0435\\u0448\\u0435\\u043D \\u043A\\u043B\\u0443\\u0447 \\u0432\\u043E \${issue2.origin}\`; + case "invalid_union": + return "\\u0413\\u0440\\u0435\\u0448\\u0435\\u043D \\u0432\\u043D\\u0435\\u0441"; + case "invalid_element": + return \`\\u0413\\u0440\\u0435\\u0448\\u043D\\u0430 \\u0432\\u0440\\u0435\\u0434\\u043D\\u043E\\u0441\\u0442 \\u0432\\u043E \${issue2.origin}\`; + default: + return \`\\u0413\\u0440\\u0435\\u0448\\u0435\\u043D \\u0432\\u043D\\u0435\\u0441\`; + } + }; +}, "error"); +function mk_default() { + return { + localeError: error25() + }; +} +__name(mk_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/ms.js +var error26 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "aksara", + verb: "mempunyai" + }, + file: { + unit: "bait", + verb: "mempunyai" + }, + array: { + unit: "elemen", + verb: "mempunyai" + }, + set: { + unit: "elemen", + verb: "mempunyai" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "nombor"; + } + case "object": { + if (Array.isArray(data)) { + return "array"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "input", + email: "alamat e-mel", + url: "URL", + emoji: "emoji", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "tarikh masa ISO", + date: "tarikh ISO", + time: "masa ISO", + duration: "tempoh ISO", + ipv4: "alamat IPv4", + ipv6: "alamat IPv6", + cidrv4: "julat IPv4", + cidrv6: "julat IPv6", + base64: "string dikodkan base64", + base64url: "string dikodkan base64url", + json_string: "string JSON", + e164: "nombor E.164", + jwt: "JWT", + template_literal: "input" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`Input tidak sah: dijangka \${issue2.expected}, diterima \${parsedType7(issue2.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`Input tidak sah: dijangka \${stringifyPrimitive(issue2.values[0])}\`; + return \`Pilihan tidak sah: dijangka salah satu daripada \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`Terlalu besar: dijangka \${issue2.origin ?? "nilai"} \${sizing.verb} \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "elemen"}\`; + return \`Terlalu besar: dijangka \${issue2.origin ?? "nilai"} adalah \${adj}\${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`Terlalu kecil: dijangka \${issue2.origin} \${sizing.verb} \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; + } + return \`Terlalu kecil: dijangka \${issue2.origin} adalah \${adj}\${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") return \`String tidak sah: mesti bermula dengan "\${_issue.prefix}"\`; + if (_issue.format === "ends_with") return \`String tidak sah: mesti berakhir dengan "\${_issue.suffix}"\`; + if (_issue.format === "includes") return \`String tidak sah: mesti mengandungi "\${_issue.includes}"\`; + if (_issue.format === "regex") return \`String tidak sah: mesti sepadan dengan corak \${_issue.pattern}\`; + return \`\${Nouns[_issue.format] ?? issue2.format} tidak sah\`; + } + case "not_multiple_of": + return \`Nombor tidak sah: perlu gandaan \${issue2.divisor}\`; + case "unrecognized_keys": + return \`Kunci tidak dikenali: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`Kunci tidak sah dalam \${issue2.origin}\`; + case "invalid_union": + return "Input tidak sah"; + case "invalid_element": + return \`Nilai tidak sah dalam \${issue2.origin}\`; + default: + return \`Input tidak sah\`; + } + }; +}, "error"); +function ms_default() { + return { + localeError: error26() + }; +} +__name(ms_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/nl.js +var error27 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "tekens" + }, + file: { + unit: "bytes" + }, + array: { + unit: "elementen" + }, + set: { + unit: "elementen" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "getal"; + } + case "object": { + if (Array.isArray(data)) { + return "array"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "invoer", + email: "emailadres", + url: "URL", + emoji: "emoji", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "ISO datum en tijd", + date: "ISO datum", + time: "ISO tijd", + duration: "ISO duur", + ipv4: "IPv4-adres", + ipv6: "IPv6-adres", + cidrv4: "IPv4-bereik", + cidrv6: "IPv6-bereik", + base64: "base64-gecodeerde tekst", + base64url: "base64 URL-gecodeerde tekst", + json_string: "JSON string", + e164: "E.164-nummer", + jwt: "JWT", + template_literal: "invoer" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`Ongeldige invoer: verwacht \${issue2.expected}, ontving \${parsedType7(issue2.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`Ongeldige invoer: verwacht \${stringifyPrimitive(issue2.values[0])}\`; + return \`Ongeldige optie: verwacht \\xE9\\xE9n van \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`Te lang: verwacht dat \${issue2.origin ?? "waarde"} \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "elementen"} bevat\`; + return \`Te lang: verwacht dat \${issue2.origin ?? "waarde"} \${adj}\${issue2.maximum.toString()} is\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`Te kort: verwacht dat \${issue2.origin} \${adj}\${issue2.minimum.toString()} \${sizing.unit} bevat\`; + } + return \`Te kort: verwacht dat \${issue2.origin} \${adj}\${issue2.minimum.toString()} is\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") { + return \`Ongeldige tekst: moet met "\${_issue.prefix}" beginnen\`; + } + if (_issue.format === "ends_with") return \`Ongeldige tekst: moet op "\${_issue.suffix}" eindigen\`; + if (_issue.format === "includes") return \`Ongeldige tekst: moet "\${_issue.includes}" bevatten\`; + if (_issue.format === "regex") return \`Ongeldige tekst: moet overeenkomen met patroon \${_issue.pattern}\`; + return \`Ongeldig: \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`Ongeldig getal: moet een veelvoud van \${issue2.divisor} zijn\`; + case "unrecognized_keys": + return \`Onbekende key\${issue2.keys.length > 1 ? "s" : ""}: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`Ongeldige key in \${issue2.origin}\`; + case "invalid_union": + return "Ongeldige invoer"; + case "invalid_element": + return \`Ongeldige waarde in \${issue2.origin}\`; + default: + return \`Ongeldige invoer\`; + } + }; +}, "error"); +function nl_default() { + return { + localeError: error27() + }; +} +__name(nl_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/no.js +var error28 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "tegn", + verb: "\\xE5 ha" + }, + file: { + unit: "bytes", + verb: "\\xE5 ha" + }, + array: { + unit: "elementer", + verb: "\\xE5 inneholde" + }, + set: { + unit: "elementer", + verb: "\\xE5 inneholde" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "tall"; + } + case "object": { + if (Array.isArray(data)) { + return "liste"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "input", + email: "e-postadresse", + url: "URL", + emoji: "emoji", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "ISO dato- og klokkeslett", + date: "ISO-dato", + time: "ISO-klokkeslett", + duration: "ISO-varighet", + ipv4: "IPv4-omr\\xE5de", + ipv6: "IPv6-omr\\xE5de", + cidrv4: "IPv4-spekter", + cidrv6: "IPv6-spekter", + base64: "base64-enkodet streng", + base64url: "base64url-enkodet streng", + json_string: "JSON-streng", + e164: "E.164-nummer", + jwt: "JWT", + template_literal: "input" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`Ugyldig input: forventet \${issue2.expected}, fikk \${parsedType7(issue2.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`Ugyldig verdi: forventet \${stringifyPrimitive(issue2.values[0])}\`; + return \`Ugyldig valg: forventet en av \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`For stor(t): forventet \${issue2.origin ?? "value"} til \\xE5 ha \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "elementer"}\`; + return \`For stor(t): forventet \${issue2.origin ?? "value"} til \\xE5 ha \${adj}\${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`For lite(n): forventet \${issue2.origin} til \\xE5 ha \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; + } + return \`For lite(n): forventet \${issue2.origin} til \\xE5 ha \${adj}\${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") return \`Ugyldig streng: m\\xE5 starte med "\${_issue.prefix}"\`; + if (_issue.format === "ends_with") return \`Ugyldig streng: m\\xE5 ende med "\${_issue.suffix}"\`; + if (_issue.format === "includes") return \`Ugyldig streng: m\\xE5 inneholde "\${_issue.includes}"\`; + if (_issue.format === "regex") return \`Ugyldig streng: m\\xE5 matche m\\xF8nsteret \${_issue.pattern}\`; + return \`Ugyldig \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`Ugyldig tall: m\\xE5 v\\xE6re et multiplum av \${issue2.divisor}\`; + case "unrecognized_keys": + return \`\${issue2.keys.length > 1 ? "Ukjente n\\xF8kler" : "Ukjent n\\xF8kkel"}: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`Ugyldig n\\xF8kkel i \${issue2.origin}\`; + case "invalid_union": + return "Ugyldig input"; + case "invalid_element": + return \`Ugyldig verdi i \${issue2.origin}\`; + default: + return \`Ugyldig input\`; + } + }; +}, "error"); +function no_default() { + return { + localeError: error28() + }; +} +__name(no_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/ota.js +var error29 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "harf", + verb: "olmal\\u0131d\\u0131r" + }, + file: { + unit: "bayt", + verb: "olmal\\u0131d\\u0131r" + }, + array: { + unit: "unsur", + verb: "olmal\\u0131d\\u0131r" + }, + set: { + unit: "unsur", + verb: "olmal\\u0131d\\u0131r" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "numara"; + } + case "object": { + if (Array.isArray(data)) { + return "saf"; + } + if (data === null) { + return "gayb"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "giren", + email: "epostag\\xE2h", + url: "URL", + emoji: "emoji", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "ISO heng\\xE2m\\u0131", + date: "ISO tarihi", + time: "ISO zaman\\u0131", + duration: "ISO m\\xFCddeti", + ipv4: "IPv4 ni\\u015F\\xE2n\\u0131", + ipv6: "IPv6 ni\\u015F\\xE2n\\u0131", + cidrv4: "IPv4 menzili", + cidrv6: "IPv6 menzili", + base64: "base64-\\u015Fifreli metin", + base64url: "base64url-\\u015Fifreli metin", + json_string: "JSON metin", + e164: "E.164 say\\u0131s\\u0131", + jwt: "JWT", + template_literal: "giren" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`F\\xE2sit giren: umulan \${issue2.expected}, al\\u0131nan \${parsedType7(issue2.input)}\`; + // return \`Fâsit giren: umulan \${issue.expected}, alınan \${util.getParsedType(issue.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`F\\xE2sit giren: umulan \${stringifyPrimitive(issue2.values[0])}\`; + return \`F\\xE2sit tercih: m\\xFBteberler \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`Fazla b\\xFCy\\xFCk: \${issue2.origin ?? "value"}, \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "elements"} sahip olmal\\u0131yd\\u0131.\`; + return \`Fazla b\\xFCy\\xFCk: \${issue2.origin ?? "value"}, \${adj}\${issue2.maximum.toString()} olmal\\u0131yd\\u0131.\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`Fazla k\\xFC\\xE7\\xFCk: \${issue2.origin}, \${adj}\${issue2.minimum.toString()} \${sizing.unit} sahip olmal\\u0131yd\\u0131.\`; + } + return \`Fazla k\\xFC\\xE7\\xFCk: \${issue2.origin}, \${adj}\${issue2.minimum.toString()} olmal\\u0131yd\\u0131.\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") return \`F\\xE2sit metin: "\${_issue.prefix}" ile ba\\u015Flamal\\u0131.\`; + if (_issue.format === "ends_with") return \`F\\xE2sit metin: "\${_issue.suffix}" ile bitmeli.\`; + if (_issue.format === "includes") return \`F\\xE2sit metin: "\${_issue.includes}" ihtiv\\xE2 etmeli.\`; + if (_issue.format === "regex") return \`F\\xE2sit metin: \${_issue.pattern} nak\\u015F\\u0131na uymal\\u0131.\`; + return \`F\\xE2sit \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`F\\xE2sit say\\u0131: \${issue2.divisor} kat\\u0131 olmal\\u0131yd\\u0131.\`; + case "unrecognized_keys": + return \`Tan\\u0131nmayan anahtar \${issue2.keys.length > 1 ? "s" : ""}: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`\${issue2.origin} i\\xE7in tan\\u0131nmayan anahtar var.\`; + case "invalid_union": + return "Giren tan\\u0131namad\\u0131."; + case "invalid_element": + return \`\${issue2.origin} i\\xE7in tan\\u0131nmayan k\\u0131ymet var.\`; + default: + return \`K\\u0131ymet tan\\u0131namad\\u0131.\`; + } + }; +}, "error"); +function ota_default() { + return { + localeError: error29() + }; +} +__name(ota_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/ps.js +var error30 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "\\u062A\\u0648\\u06A9\\u064A", + verb: "\\u0648\\u0644\\u0631\\u064A" + }, + file: { + unit: "\\u0628\\u0627\\u06CC\\u067C\\u0633", + verb: "\\u0648\\u0644\\u0631\\u064A" + }, + array: { + unit: "\\u062A\\u0648\\u06A9\\u064A", + verb: "\\u0648\\u0644\\u0631\\u064A" + }, + set: { + unit: "\\u062A\\u0648\\u06A9\\u064A", + verb: "\\u0648\\u0644\\u0631\\u064A" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "\\u0639\\u062F\\u062F"; + } + case "object": { + if (Array.isArray(data)) { + return "\\u0627\\u0631\\u06D0"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "\\u0648\\u0631\\u0648\\u062F\\u064A", + email: "\\u0628\\u0631\\u06CC\\u069A\\u0646\\u0627\\u0644\\u06CC\\u06A9", + url: "\\u06CC\\u0648 \\u0622\\u0631 \\u0627\\u0644", + emoji: "\\u0627\\u06CC\\u0645\\u0648\\u062C\\u064A", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "\\u0646\\u06CC\\u067C\\u0647 \\u0627\\u0648 \\u0648\\u062E\\u062A", + date: "\\u0646\\u06D0\\u067C\\u0647", + time: "\\u0648\\u062E\\u062A", + duration: "\\u0645\\u0648\\u062F\\u0647", + ipv4: "\\u062F IPv4 \\u067E\\u062A\\u0647", + ipv6: "\\u062F IPv6 \\u067E\\u062A\\u0647", + cidrv4: "\\u062F IPv4 \\u0633\\u0627\\u062D\\u0647", + cidrv6: "\\u062F IPv6 \\u0633\\u0627\\u062D\\u0647", + base64: "base64-encoded \\u0645\\u062A\\u0646", + base64url: "base64url-encoded \\u0645\\u062A\\u0646", + json_string: "JSON \\u0645\\u062A\\u0646", + e164: "\\u062F E.164 \\u0634\\u0645\\u06D0\\u0631\\u0647", + jwt: "JWT", + template_literal: "\\u0648\\u0631\\u0648\\u062F\\u064A" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`\\u0646\\u0627\\u0633\\u0645 \\u0648\\u0631\\u0648\\u062F\\u064A: \\u0628\\u0627\\u06CC\\u062F \${issue2.expected} \\u0648\\u0627\\u06CC, \\u0645\\u06AB\\u0631 \${parsedType7(issue2.input)} \\u062A\\u0631\\u0644\\u0627\\u0633\\u0647 \\u0634\\u0648\`; + case "invalid_value": + if (issue2.values.length === 1) { + return \`\\u0646\\u0627\\u0633\\u0645 \\u0648\\u0631\\u0648\\u062F\\u064A: \\u0628\\u0627\\u06CC\\u062F \${stringifyPrimitive(issue2.values[0])} \\u0648\\u0627\\u06CC\`; + } + return \`\\u0646\\u0627\\u0633\\u0645 \\u0627\\u0646\\u062A\\u062E\\u0627\\u0628: \\u0628\\u0627\\u06CC\\u062F \\u06CC\\u0648 \\u0644\\u0647 \${joinValues(issue2.values, "|")} \\u0685\\u062E\\u0647 \\u0648\\u0627\\u06CC\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`\\u0689\\u06CC\\u0631 \\u0644\\u0648\\u06CC: \${issue2.origin ?? "\\u0627\\u0631\\u0632\\u069A\\u062A"} \\u0628\\u0627\\u06CC\\u062F \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "\\u0639\\u0646\\u0635\\u0631\\u0648\\u0646\\u0647"} \\u0648\\u0644\\u0631\\u064A\`; + } + return \`\\u0689\\u06CC\\u0631 \\u0644\\u0648\\u06CC: \${issue2.origin ?? "\\u0627\\u0631\\u0632\\u069A\\u062A"} \\u0628\\u0627\\u06CC\\u062F \${adj}\${issue2.maximum.toString()} \\u0648\\u064A\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`\\u0689\\u06CC\\u0631 \\u06A9\\u0648\\u0686\\u0646\\u06CC: \${issue2.origin} \\u0628\\u0627\\u06CC\\u062F \${adj}\${issue2.minimum.toString()} \${sizing.unit} \\u0648\\u0644\\u0631\\u064A\`; + } + return \`\\u0689\\u06CC\\u0631 \\u06A9\\u0648\\u0686\\u0646\\u06CC: \${issue2.origin} \\u0628\\u0627\\u06CC\\u062F \${adj}\${issue2.minimum.toString()} \\u0648\\u064A\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") { + return \`\\u0646\\u0627\\u0633\\u0645 \\u0645\\u062A\\u0646: \\u0628\\u0627\\u06CC\\u062F \\u062F "\${_issue.prefix}" \\u0633\\u0631\\u0647 \\u067E\\u06CC\\u0644 \\u0634\\u064A\`; + } + if (_issue.format === "ends_with") { + return \`\\u0646\\u0627\\u0633\\u0645 \\u0645\\u062A\\u0646: \\u0628\\u0627\\u06CC\\u062F \\u062F "\${_issue.suffix}" \\u0633\\u0631\\u0647 \\u067E\\u0627\\u06CC \\u062A\\u0647 \\u0648\\u0631\\u0633\\u064A\\u0696\\u064A\`; + } + if (_issue.format === "includes") { + return \`\\u0646\\u0627\\u0633\\u0645 \\u0645\\u062A\\u0646: \\u0628\\u0627\\u06CC\\u062F "\${_issue.includes}" \\u0648\\u0644\\u0631\\u064A\`; + } + if (_issue.format === "regex") { + return \`\\u0646\\u0627\\u0633\\u0645 \\u0645\\u062A\\u0646: \\u0628\\u0627\\u06CC\\u062F \\u062F \${_issue.pattern} \\u0633\\u0631\\u0647 \\u0645\\u0637\\u0627\\u0628\\u0642\\u062A \\u0648\\u0644\\u0631\\u064A\`; + } + return \`\${Nouns[_issue.format] ?? issue2.format} \\u0646\\u0627\\u0633\\u0645 \\u062F\\u06CC\`; + } + case "not_multiple_of": + return \`\\u0646\\u0627\\u0633\\u0645 \\u0639\\u062F\\u062F: \\u0628\\u0627\\u06CC\\u062F \\u062F \${issue2.divisor} \\u0645\\u0636\\u0631\\u0628 \\u0648\\u064A\`; + case "unrecognized_keys": + return \`\\u0646\\u0627\\u0633\\u0645 \${issue2.keys.length > 1 ? "\\u06A9\\u0644\\u06CC\\u0689\\u0648\\u0646\\u0647" : "\\u06A9\\u0644\\u06CC\\u0689"}: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`\\u0646\\u0627\\u0633\\u0645 \\u06A9\\u0644\\u06CC\\u0689 \\u067E\\u0647 \${issue2.origin} \\u06A9\\u06D0\`; + case "invalid_union": + return \`\\u0646\\u0627\\u0633\\u0645\\u0647 \\u0648\\u0631\\u0648\\u062F\\u064A\`; + case "invalid_element": + return \`\\u0646\\u0627\\u0633\\u0645 \\u0639\\u0646\\u0635\\u0631 \\u067E\\u0647 \${issue2.origin} \\u06A9\\u06D0\`; + default: + return \`\\u0646\\u0627\\u0633\\u0645\\u0647 \\u0648\\u0631\\u0648\\u062F\\u064A\`; + } + }; +}, "error"); +function ps_default() { + return { + localeError: error30() + }; +} +__name(ps_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/pl.js +var error31 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "znak\\xF3w", + verb: "mie\\u0107" + }, + file: { + unit: "bajt\\xF3w", + verb: "mie\\u0107" + }, + array: { + unit: "element\\xF3w", + verb: "mie\\u0107" + }, + set: { + unit: "element\\xF3w", + verb: "mie\\u0107" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "liczba"; + } + case "object": { + if (Array.isArray(data)) { + return "tablica"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "wyra\\u017Cenie", + email: "adres email", + url: "URL", + emoji: "emoji", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "data i godzina w formacie ISO", + date: "data w formacie ISO", + time: "godzina w formacie ISO", + duration: "czas trwania ISO", + ipv4: "adres IPv4", + ipv6: "adres IPv6", + cidrv4: "zakres IPv4", + cidrv6: "zakres IPv6", + base64: "ci\\u0105g znak\\xF3w zakodowany w formacie base64", + base64url: "ci\\u0105g znak\\xF3w zakodowany w formacie base64url", + json_string: "ci\\u0105g znak\\xF3w w formacie JSON", + e164: "liczba E.164", + jwt: "JWT", + template_literal: "wej\\u015Bcie" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`Nieprawid\\u0142owe dane wej\\u015Bciowe: oczekiwano \${issue2.expected}, otrzymano \${parsedType7(issue2.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`Nieprawid\\u0142owe dane wej\\u015Bciowe: oczekiwano \${stringifyPrimitive(issue2.values[0])}\`; + return \`Nieprawid\\u0142owa opcja: oczekiwano jednej z warto\\u015Bci \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`Za du\\u017Ca warto\\u015B\\u0107: oczekiwano, \\u017Ce \${issue2.origin ?? "warto\\u015B\\u0107"} b\\u0119dzie mie\\u0107 \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "element\\xF3w"}\`; + } + return \`Zbyt du\\u017C(y/a/e): oczekiwano, \\u017Ce \${issue2.origin ?? "warto\\u015B\\u0107"} b\\u0119dzie wynosi\\u0107 \${adj}\${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`Za ma\\u0142a warto\\u015B\\u0107: oczekiwano, \\u017Ce \${issue2.origin ?? "warto\\u015B\\u0107"} b\\u0119dzie mie\\u0107 \${adj}\${issue2.minimum.toString()} \${sizing.unit ?? "element\\xF3w"}\`; + } + return \`Zbyt ma\\u0142(y/a/e): oczekiwano, \\u017Ce \${issue2.origin ?? "warto\\u015B\\u0107"} b\\u0119dzie wynosi\\u0107 \${adj}\${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") return \`Nieprawid\\u0142owy ci\\u0105g znak\\xF3w: musi zaczyna\\u0107 si\\u0119 od "\${_issue.prefix}"\`; + if (_issue.format === "ends_with") return \`Nieprawid\\u0142owy ci\\u0105g znak\\xF3w: musi ko\\u0144czy\\u0107 si\\u0119 na "\${_issue.suffix}"\`; + if (_issue.format === "includes") return \`Nieprawid\\u0142owy ci\\u0105g znak\\xF3w: musi zawiera\\u0107 "\${_issue.includes}"\`; + if (_issue.format === "regex") return \`Nieprawid\\u0142owy ci\\u0105g znak\\xF3w: musi odpowiada\\u0107 wzorcowi \${_issue.pattern}\`; + return \`Nieprawid\\u0142ow(y/a/e) \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`Nieprawid\\u0142owa liczba: musi by\\u0107 wielokrotno\\u015Bci\\u0105 \${issue2.divisor}\`; + case "unrecognized_keys": + return \`Nierozpoznane klucze\${issue2.keys.length > 1 ? "s" : ""}: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`Nieprawid\\u0142owy klucz w \${issue2.origin}\`; + case "invalid_union": + return "Nieprawid\\u0142owe dane wej\\u015Bciowe"; + case "invalid_element": + return \`Nieprawid\\u0142owa warto\\u015B\\u0107 w \${issue2.origin}\`; + default: + return \`Nieprawid\\u0142owe dane wej\\u015Bciowe\`; + } + }; +}, "error"); +function pl_default() { + return { + localeError: error31() + }; +} +__name(pl_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/pt.js +var error32 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "caracteres", + verb: "ter" + }, + file: { + unit: "bytes", + verb: "ter" + }, + array: { + unit: "itens", + verb: "ter" + }, + set: { + unit: "itens", + verb: "ter" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "n\\xFAmero"; + } + case "object": { + if (Array.isArray(data)) { + return "array"; + } + if (data === null) { + return "nulo"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "padr\\xE3o", + email: "endere\\xE7o de e-mail", + url: "URL", + emoji: "emoji", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "data e hora ISO", + date: "data ISO", + time: "hora ISO", + duration: "dura\\xE7\\xE3o ISO", + ipv4: "endere\\xE7o IPv4", + ipv6: "endere\\xE7o IPv6", + cidrv4: "faixa de IPv4", + cidrv6: "faixa de IPv6", + base64: "texto codificado em base64", + base64url: "URL codificada em base64", + json_string: "texto JSON", + e164: "n\\xFAmero E.164", + jwt: "JWT", + template_literal: "entrada" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`Tipo inv\\xE1lido: esperado \${issue2.expected}, recebido \${parsedType7(issue2.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`Entrada inv\\xE1lida: esperado \${stringifyPrimitive(issue2.values[0])}\`; + return \`Op\\xE7\\xE3o inv\\xE1lida: esperada uma das \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`Muito grande: esperado que \${issue2.origin ?? "valor"} tivesse \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "elementos"}\`; + return \`Muito grande: esperado que \${issue2.origin ?? "valor"} fosse \${adj}\${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`Muito pequeno: esperado que \${issue2.origin} tivesse \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; + } + return \`Muito pequeno: esperado que \${issue2.origin} fosse \${adj}\${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") return \`Texto inv\\xE1lido: deve come\\xE7ar com "\${_issue.prefix}"\`; + if (_issue.format === "ends_with") return \`Texto inv\\xE1lido: deve terminar com "\${_issue.suffix}"\`; + if (_issue.format === "includes") return \`Texto inv\\xE1lido: deve incluir "\${_issue.includes}"\`; + if (_issue.format === "regex") return \`Texto inv\\xE1lido: deve corresponder ao padr\\xE3o \${_issue.pattern}\`; + return \`\${Nouns[_issue.format] ?? issue2.format} inv\\xE1lido\`; + } + case "not_multiple_of": + return \`N\\xFAmero inv\\xE1lido: deve ser m\\xFAltiplo de \${issue2.divisor}\`; + case "unrecognized_keys": + return \`Chave\${issue2.keys.length > 1 ? "s" : ""} desconhecida\${issue2.keys.length > 1 ? "s" : ""}: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`Chave inv\\xE1lida em \${issue2.origin}\`; + case "invalid_union": + return "Entrada inv\\xE1lida"; + case "invalid_element": + return \`Valor inv\\xE1lido em \${issue2.origin}\`; + default: + return \`Campo inv\\xE1lido\`; + } + }; +}, "error"); +function pt_default() { + return { + localeError: error32() + }; +} +__name(pt_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/ru.js +function getRussianPlural(count, one, few, many) { + const absCount = Math.abs(count); + const lastDigit = absCount % 10; + const lastTwoDigits = absCount % 100; + if (lastTwoDigits >= 11 && lastTwoDigits <= 19) { + return many; + } + if (lastDigit === 1) { + return one; + } + if (lastDigit >= 2 && lastDigit <= 4) { + return few; + } + return many; +} +__name(getRussianPlural, "getRussianPlural"); +var error33 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: { + one: "\\u0441\\u0438\\u043C\\u0432\\u043E\\u043B", + few: "\\u0441\\u0438\\u043C\\u0432\\u043E\\u043B\\u0430", + many: "\\u0441\\u0438\\u043C\\u0432\\u043E\\u043B\\u043E\\u0432" + }, + verb: "\\u0438\\u043C\\u0435\\u0442\\u044C" + }, + file: { + unit: { + one: "\\u0431\\u0430\\u0439\\u0442", + few: "\\u0431\\u0430\\u0439\\u0442\\u0430", + many: "\\u0431\\u0430\\u0439\\u0442" + }, + verb: "\\u0438\\u043C\\u0435\\u0442\\u044C" + }, + array: { + unit: { + one: "\\u044D\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442", + few: "\\u044D\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442\\u0430", + many: "\\u044D\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442\\u043E\\u0432" + }, + verb: "\\u0438\\u043C\\u0435\\u0442\\u044C" + }, + set: { + unit: { + one: "\\u044D\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442", + few: "\\u044D\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442\\u0430", + many: "\\u044D\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442\\u043E\\u0432" + }, + verb: "\\u0438\\u043C\\u0435\\u0442\\u044C" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "\\u0447\\u0438\\u0441\\u043B\\u043E"; + } + case "object": { + if (Array.isArray(data)) { + return "\\u043C\\u0430\\u0441\\u0441\\u0438\\u0432"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "\\u0432\\u0432\\u043E\\u0434", + email: "email \\u0430\\u0434\\u0440\\u0435\\u0441", + url: "URL", + emoji: "\\u044D\\u043C\\u043E\\u0434\\u0437\\u0438", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "ISO \\u0434\\u0430\\u0442\\u0430 \\u0438 \\u0432\\u0440\\u0435\\u043C\\u044F", + date: "ISO \\u0434\\u0430\\u0442\\u0430", + time: "ISO \\u0432\\u0440\\u0435\\u043C\\u044F", + duration: "ISO \\u0434\\u043B\\u0438\\u0442\\u0435\\u043B\\u044C\\u043D\\u043E\\u0441\\u0442\\u044C", + ipv4: "IPv4 \\u0430\\u0434\\u0440\\u0435\\u0441", + ipv6: "IPv6 \\u0430\\u0434\\u0440\\u0435\\u0441", + cidrv4: "IPv4 \\u0434\\u0438\\u0430\\u043F\\u0430\\u0437\\u043E\\u043D", + cidrv6: "IPv6 \\u0434\\u0438\\u0430\\u043F\\u0430\\u0437\\u043E\\u043D", + base64: "\\u0441\\u0442\\u0440\\u043E\\u043A\\u0430 \\u0432 \\u0444\\u043E\\u0440\\u043C\\u0430\\u0442\\u0435 base64", + base64url: "\\u0441\\u0442\\u0440\\u043E\\u043A\\u0430 \\u0432 \\u0444\\u043E\\u0440\\u043C\\u0430\\u0442\\u0435 base64url", + json_string: "JSON \\u0441\\u0442\\u0440\\u043E\\u043A\\u0430", + e164: "\\u043D\\u043E\\u043C\\u0435\\u0440 E.164", + jwt: "JWT", + template_literal: "\\u0432\\u0432\\u043E\\u0434" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`\\u041D\\u0435\\u0432\\u0435\\u0440\\u043D\\u044B\\u0439 \\u0432\\u0432\\u043E\\u0434: \\u043E\\u0436\\u0438\\u0434\\u0430\\u043B\\u043E\\u0441\\u044C \${issue2.expected}, \\u043F\\u043E\\u043B\\u0443\\u0447\\u0435\\u043D\\u043E \${parsedType7(issue2.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`\\u041D\\u0435\\u0432\\u0435\\u0440\\u043D\\u044B\\u0439 \\u0432\\u0432\\u043E\\u0434: \\u043E\\u0436\\u0438\\u0434\\u0430\\u043B\\u043E\\u0441\\u044C \${stringifyPrimitive(issue2.values[0])}\`; + return \`\\u041D\\u0435\\u0432\\u0435\\u0440\\u043D\\u044B\\u0439 \\u0432\\u0430\\u0440\\u0438\\u0430\\u043D\\u0442: \\u043E\\u0436\\u0438\\u0434\\u0430\\u043B\\u043E\\u0441\\u044C \\u043E\\u0434\\u043D\\u043E \\u0438\\u0437 \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) { + const maxValue = Number(issue2.maximum); + const unit = getRussianPlural(maxValue, sizing.unit.one, sizing.unit.few, sizing.unit.many); + return \`\\u0421\\u043B\\u0438\\u0448\\u043A\\u043E\\u043C \\u0431\\u043E\\u043B\\u044C\\u0448\\u043E\\u0435 \\u0437\\u043D\\u0430\\u0447\\u0435\\u043D\\u0438\\u0435: \\u043E\\u0436\\u0438\\u0434\\u0430\\u043B\\u043E\\u0441\\u044C, \\u0447\\u0442\\u043E \${issue2.origin ?? "\\u0437\\u043D\\u0430\\u0447\\u0435\\u043D\\u0438\\u0435"} \\u0431\\u0443\\u0434\\u0435\\u0442 \\u0438\\u043C\\u0435\\u0442\\u044C \${adj}\${issue2.maximum.toString()} \${unit}\`; + } + return \`\\u0421\\u043B\\u0438\\u0448\\u043A\\u043E\\u043C \\u0431\\u043E\\u043B\\u044C\\u0448\\u043E\\u0435 \\u0437\\u043D\\u0430\\u0447\\u0435\\u043D\\u0438\\u0435: \\u043E\\u0436\\u0438\\u0434\\u0430\\u043B\\u043E\\u0441\\u044C, \\u0447\\u0442\\u043E \${issue2.origin ?? "\\u0437\\u043D\\u0430\\u0447\\u0435\\u043D\\u0438\\u0435"} \\u0431\\u0443\\u0434\\u0435\\u0442 \${adj}\${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + const minValue = Number(issue2.minimum); + const unit = getRussianPlural(minValue, sizing.unit.one, sizing.unit.few, sizing.unit.many); + return \`\\u0421\\u043B\\u0438\\u0448\\u043A\\u043E\\u043C \\u043C\\u0430\\u043B\\u0435\\u043D\\u044C\\u043A\\u043E\\u0435 \\u0437\\u043D\\u0430\\u0447\\u0435\\u043D\\u0438\\u0435: \\u043E\\u0436\\u0438\\u0434\\u0430\\u043B\\u043E\\u0441\\u044C, \\u0447\\u0442\\u043E \${issue2.origin} \\u0431\\u0443\\u0434\\u0435\\u0442 \\u0438\\u043C\\u0435\\u0442\\u044C \${adj}\${issue2.minimum.toString()} \${unit}\`; + } + return \`\\u0421\\u043B\\u0438\\u0448\\u043A\\u043E\\u043C \\u043C\\u0430\\u043B\\u0435\\u043D\\u044C\\u043A\\u043E\\u0435 \\u0437\\u043D\\u0430\\u0447\\u0435\\u043D\\u0438\\u0435: \\u043E\\u0436\\u0438\\u0434\\u0430\\u043B\\u043E\\u0441\\u044C, \\u0447\\u0442\\u043E \${issue2.origin} \\u0431\\u0443\\u0434\\u0435\\u0442 \${adj}\${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") return \`\\u041D\\u0435\\u0432\\u0435\\u0440\\u043D\\u0430\\u044F \\u0441\\u0442\\u0440\\u043E\\u043A\\u0430: \\u0434\\u043E\\u043B\\u0436\\u043D\\u0430 \\u043D\\u0430\\u0447\\u0438\\u043D\\u0430\\u0442\\u044C\\u0441\\u044F \\u0441 "\${_issue.prefix}"\`; + if (_issue.format === "ends_with") return \`\\u041D\\u0435\\u0432\\u0435\\u0440\\u043D\\u0430\\u044F \\u0441\\u0442\\u0440\\u043E\\u043A\\u0430: \\u0434\\u043E\\u043B\\u0436\\u043D\\u0430 \\u0437\\u0430\\u043A\\u0430\\u043D\\u0447\\u0438\\u0432\\u0430\\u0442\\u044C\\u0441\\u044F \\u043D\\u0430 "\${_issue.suffix}"\`; + if (_issue.format === "includes") return \`\\u041D\\u0435\\u0432\\u0435\\u0440\\u043D\\u0430\\u044F \\u0441\\u0442\\u0440\\u043E\\u043A\\u0430: \\u0434\\u043E\\u043B\\u0436\\u043D\\u0430 \\u0441\\u043E\\u0434\\u0435\\u0440\\u0436\\u0430\\u0442\\u044C "\${_issue.includes}"\`; + if (_issue.format === "regex") return \`\\u041D\\u0435\\u0432\\u0435\\u0440\\u043D\\u0430\\u044F \\u0441\\u0442\\u0440\\u043E\\u043A\\u0430: \\u0434\\u043E\\u043B\\u0436\\u043D\\u0430 \\u0441\\u043E\\u043E\\u0442\\u0432\\u0435\\u0442\\u0441\\u0442\\u0432\\u043E\\u0432\\u0430\\u0442\\u044C \\u0448\\u0430\\u0431\\u043B\\u043E\\u043D\\u0443 \${_issue.pattern}\`; + return \`\\u041D\\u0435\\u0432\\u0435\\u0440\\u043D\\u044B\\u0439 \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`\\u041D\\u0435\\u0432\\u0435\\u0440\\u043D\\u043E\\u0435 \\u0447\\u0438\\u0441\\u043B\\u043E: \\u0434\\u043E\\u043B\\u0436\\u043D\\u043E \\u0431\\u044B\\u0442\\u044C \\u043A\\u0440\\u0430\\u0442\\u043D\\u044B\\u043C \${issue2.divisor}\`; + case "unrecognized_keys": + return \`\\u041D\\u0435\\u0440\\u0430\\u0441\\u043F\\u043E\\u0437\\u043D\\u0430\\u043D\\u043D\${issue2.keys.length > 1 ? "\\u044B\\u0435" : "\\u044B\\u0439"} \\u043A\\u043B\\u044E\\u0447\${issue2.keys.length > 1 ? "\\u0438" : ""}: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`\\u041D\\u0435\\u0432\\u0435\\u0440\\u043D\\u044B\\u0439 \\u043A\\u043B\\u044E\\u0447 \\u0432 \${issue2.origin}\`; + case "invalid_union": + return "\\u041D\\u0435\\u0432\\u0435\\u0440\\u043D\\u044B\\u0435 \\u0432\\u0445\\u043E\\u0434\\u043D\\u044B\\u0435 \\u0434\\u0430\\u043D\\u043D\\u044B\\u0435"; + case "invalid_element": + return \`\\u041D\\u0435\\u0432\\u0435\\u0440\\u043D\\u043E\\u0435 \\u0437\\u043D\\u0430\\u0447\\u0435\\u043D\\u0438\\u0435 \\u0432 \${issue2.origin}\`; + default: + return \`\\u041D\\u0435\\u0432\\u0435\\u0440\\u043D\\u044B\\u0435 \\u0432\\u0445\\u043E\\u0434\\u043D\\u044B\\u0435 \\u0434\\u0430\\u043D\\u043D\\u044B\\u0435\`; + } + }; +}, "error"); +function ru_default() { + return { + localeError: error33() + }; +} +__name(ru_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/sl.js +var error34 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "znakov", + verb: "imeti" + }, + file: { + unit: "bajtov", + verb: "imeti" + }, + array: { + unit: "elementov", + verb: "imeti" + }, + set: { + unit: "elementov", + verb: "imeti" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "\\u0161tevilo"; + } + case "object": { + if (Array.isArray(data)) { + return "tabela"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "vnos", + email: "e-po\\u0161tni naslov", + url: "URL", + emoji: "emoji", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "ISO datum in \\u010Das", + date: "ISO datum", + time: "ISO \\u010Das", + duration: "ISO trajanje", + ipv4: "IPv4 naslov", + ipv6: "IPv6 naslov", + cidrv4: "obseg IPv4", + cidrv6: "obseg IPv6", + base64: "base64 kodiran niz", + base64url: "base64url kodiran niz", + json_string: "JSON niz", + e164: "E.164 \\u0161tevilka", + jwt: "JWT", + template_literal: "vnos" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`Neveljaven vnos: pri\\u010Dakovano \${issue2.expected}, prejeto \${parsedType7(issue2.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`Neveljaven vnos: pri\\u010Dakovano \${stringifyPrimitive(issue2.values[0])}\`; + return \`Neveljavna mo\\u017Enost: pri\\u010Dakovano eno izmed \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`Preveliko: pri\\u010Dakovano, da bo \${issue2.origin ?? "vrednost"} imelo \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "elementov"}\`; + return \`Preveliko: pri\\u010Dakovano, da bo \${issue2.origin ?? "vrednost"} \${adj}\${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`Premajhno: pri\\u010Dakovano, da bo \${issue2.origin} imelo \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; + } + return \`Premajhno: pri\\u010Dakovano, da bo \${issue2.origin} \${adj}\${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") { + return \`Neveljaven niz: mora se za\\u010Deti z "\${_issue.prefix}"\`; + } + if (_issue.format === "ends_with") return \`Neveljaven niz: mora se kon\\u010Dati z "\${_issue.suffix}"\`; + if (_issue.format === "includes") return \`Neveljaven niz: mora vsebovati "\${_issue.includes}"\`; + if (_issue.format === "regex") return \`Neveljaven niz: mora ustrezati vzorcu \${_issue.pattern}\`; + return \`Neveljaven \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`Neveljavno \\u0161tevilo: mora biti ve\\u010Dkratnik \${issue2.divisor}\`; + case "unrecognized_keys": + return \`Neprepoznan\${issue2.keys.length > 1 ? "i klju\\u010Di" : " klju\\u010D"}: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`Neveljaven klju\\u010D v \${issue2.origin}\`; + case "invalid_union": + return "Neveljaven vnos"; + case "invalid_element": + return \`Neveljavna vrednost v \${issue2.origin}\`; + default: + return "Neveljaven vnos"; + } + }; +}, "error"); +function sl_default() { + return { + localeError: error34() + }; +} +__name(sl_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/sv.js +var error35 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "tecken", + verb: "att ha" + }, + file: { + unit: "bytes", + verb: "att ha" + }, + array: { + unit: "objekt", + verb: "att inneh\\xE5lla" + }, + set: { + unit: "objekt", + verb: "att inneh\\xE5lla" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "antal"; + } + case "object": { + if (Array.isArray(data)) { + return "lista"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "regulj\\xE4rt uttryck", + email: "e-postadress", + url: "URL", + emoji: "emoji", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "ISO-datum och tid", + date: "ISO-datum", + time: "ISO-tid", + duration: "ISO-varaktighet", + ipv4: "IPv4-intervall", + ipv6: "IPv6-intervall", + cidrv4: "IPv4-spektrum", + cidrv6: "IPv6-spektrum", + base64: "base64-kodad str\\xE4ng", + base64url: "base64url-kodad str\\xE4ng", + json_string: "JSON-str\\xE4ng", + e164: "E.164-nummer", + jwt: "JWT", + template_literal: "mall-literal" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`Ogiltig inmatning: f\\xF6rv\\xE4ntat \${issue2.expected}, fick \${parsedType7(issue2.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`Ogiltig inmatning: f\\xF6rv\\xE4ntat \${stringifyPrimitive(issue2.values[0])}\`; + return \`Ogiltigt val: f\\xF6rv\\xE4ntade en av \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`F\\xF6r stor(t): f\\xF6rv\\xE4ntade \${issue2.origin ?? "v\\xE4rdet"} att ha \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "element"}\`; + } + return \`F\\xF6r stor(t): f\\xF6rv\\xE4ntat \${issue2.origin ?? "v\\xE4rdet"} att ha \${adj}\${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`F\\xF6r lite(t): f\\xF6rv\\xE4ntade \${issue2.origin ?? "v\\xE4rdet"} att ha \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; + } + return \`F\\xF6r lite(t): f\\xF6rv\\xE4ntade \${issue2.origin ?? "v\\xE4rdet"} att ha \${adj}\${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") { + return \`Ogiltig str\\xE4ng: m\\xE5ste b\\xF6rja med "\${_issue.prefix}"\`; + } + if (_issue.format === "ends_with") return \`Ogiltig str\\xE4ng: m\\xE5ste sluta med "\${_issue.suffix}"\`; + if (_issue.format === "includes") return \`Ogiltig str\\xE4ng: m\\xE5ste inneh\\xE5lla "\${_issue.includes}"\`; + if (_issue.format === "regex") return \`Ogiltig str\\xE4ng: m\\xE5ste matcha m\\xF6nstret "\${_issue.pattern}"\`; + return \`Ogiltig(t) \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`Ogiltigt tal: m\\xE5ste vara en multipel av \${issue2.divisor}\`; + case "unrecognized_keys": + return \`\${issue2.keys.length > 1 ? "Ok\\xE4nda nycklar" : "Ok\\xE4nd nyckel"}: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`Ogiltig nyckel i \${issue2.origin ?? "v\\xE4rdet"}\`; + case "invalid_union": + return "Ogiltig input"; + case "invalid_element": + return \`Ogiltigt v\\xE4rde i \${issue2.origin ?? "v\\xE4rdet"}\`; + default: + return \`Ogiltig input\`; + } + }; +}, "error"); +function sv_default() { + return { + localeError: error35() + }; +} +__name(sv_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/ta.js +var error36 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "\\u0B8E\\u0BB4\\u0BC1\\u0BA4\\u0BCD\\u0BA4\\u0BC1\\u0B95\\u0BCD\\u0B95\\u0BB3\\u0BCD", + verb: "\\u0B95\\u0BCA\\u0BA3\\u0BCD\\u0B9F\\u0BBF\\u0BB0\\u0BC1\\u0B95\\u0BCD\\u0B95 \\u0BB5\\u0BC7\\u0BA3\\u0BCD\\u0B9F\\u0BC1\\u0BAE\\u0BCD" + }, + file: { + unit: "\\u0BAA\\u0BC8\\u0B9F\\u0BCD\\u0B9F\\u0BC1\\u0B95\\u0BB3\\u0BCD", + verb: "\\u0B95\\u0BCA\\u0BA3\\u0BCD\\u0B9F\\u0BBF\\u0BB0\\u0BC1\\u0B95\\u0BCD\\u0B95 \\u0BB5\\u0BC7\\u0BA3\\u0BCD\\u0B9F\\u0BC1\\u0BAE\\u0BCD" + }, + array: { + unit: "\\u0B89\\u0BB1\\u0BC1\\u0BAA\\u0BCD\\u0BAA\\u0BC1\\u0B95\\u0BB3\\u0BCD", + verb: "\\u0B95\\u0BCA\\u0BA3\\u0BCD\\u0B9F\\u0BBF\\u0BB0\\u0BC1\\u0B95\\u0BCD\\u0B95 \\u0BB5\\u0BC7\\u0BA3\\u0BCD\\u0B9F\\u0BC1\\u0BAE\\u0BCD" + }, + set: { + unit: "\\u0B89\\u0BB1\\u0BC1\\u0BAA\\u0BCD\\u0BAA\\u0BC1\\u0B95\\u0BB3\\u0BCD", + verb: "\\u0B95\\u0BCA\\u0BA3\\u0BCD\\u0B9F\\u0BBF\\u0BB0\\u0BC1\\u0B95\\u0BCD\\u0B95 \\u0BB5\\u0BC7\\u0BA3\\u0BCD\\u0B9F\\u0BC1\\u0BAE\\u0BCD" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "\\u0B8E\\u0BA3\\u0BCD \\u0B85\\u0BB2\\u0BCD\\u0BB2\\u0BBE\\u0BA4\\u0BA4\\u0BC1" : "\\u0B8E\\u0BA3\\u0BCD"; + } + case "object": { + if (Array.isArray(data)) { + return "\\u0B85\\u0BA3\\u0BBF"; + } + if (data === null) { + return "\\u0BB5\\u0BC6\\u0BB1\\u0BC1\\u0BAE\\u0BC8"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "\\u0B89\\u0BB3\\u0BCD\\u0BB3\\u0BC0\\u0B9F\\u0BC1", + email: "\\u0BAE\\u0BBF\\u0BA9\\u0BCD\\u0BA9\\u0B9E\\u0BCD\\u0B9A\\u0BB2\\u0BCD \\u0BAE\\u0BC1\\u0B95\\u0BB5\\u0BB0\\u0BBF", + url: "URL", + emoji: "emoji", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "ISO \\u0BA4\\u0BC7\\u0BA4\\u0BBF \\u0BA8\\u0BC7\\u0BB0\\u0BAE\\u0BCD", + date: "ISO \\u0BA4\\u0BC7\\u0BA4\\u0BBF", + time: "ISO \\u0BA8\\u0BC7\\u0BB0\\u0BAE\\u0BCD", + duration: "ISO \\u0B95\\u0BBE\\u0BB2 \\u0B85\\u0BB3\\u0BB5\\u0BC1", + ipv4: "IPv4 \\u0BAE\\u0BC1\\u0B95\\u0BB5\\u0BB0\\u0BBF", + ipv6: "IPv6 \\u0BAE\\u0BC1\\u0B95\\u0BB5\\u0BB0\\u0BBF", + cidrv4: "IPv4 \\u0BB5\\u0BB0\\u0BAE\\u0BCD\\u0BAA\\u0BC1", + cidrv6: "IPv6 \\u0BB5\\u0BB0\\u0BAE\\u0BCD\\u0BAA\\u0BC1", + base64: "base64-encoded \\u0B9A\\u0BB0\\u0BAE\\u0BCD", + base64url: "base64url-encoded \\u0B9A\\u0BB0\\u0BAE\\u0BCD", + json_string: "JSON \\u0B9A\\u0BB0\\u0BAE\\u0BCD", + e164: "E.164 \\u0B8E\\u0BA3\\u0BCD", + jwt: "JWT", + template_literal: "input" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`\\u0BA4\\u0BB5\\u0BB1\\u0BBE\\u0BA9 \\u0B89\\u0BB3\\u0BCD\\u0BB3\\u0BC0\\u0B9F\\u0BC1: \\u0B8E\\u0BA4\\u0BBF\\u0BB0\\u0BCD\\u0BAA\\u0BBE\\u0BB0\\u0BCD\\u0B95\\u0BCD\\u0B95\\u0BAA\\u0BCD\\u0BAA\\u0B9F\\u0BCD\\u0B9F\\u0BA4\\u0BC1 \${issue2.expected}, \\u0BAA\\u0BC6\\u0BB1\\u0BAA\\u0BCD\\u0BAA\\u0B9F\\u0BCD\\u0B9F\\u0BA4\\u0BC1 \${parsedType7(issue2.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`\\u0BA4\\u0BB5\\u0BB1\\u0BBE\\u0BA9 \\u0B89\\u0BB3\\u0BCD\\u0BB3\\u0BC0\\u0B9F\\u0BC1: \\u0B8E\\u0BA4\\u0BBF\\u0BB0\\u0BCD\\u0BAA\\u0BBE\\u0BB0\\u0BCD\\u0B95\\u0BCD\\u0B95\\u0BAA\\u0BCD\\u0BAA\\u0B9F\\u0BCD\\u0B9F\\u0BA4\\u0BC1 \${stringifyPrimitive(issue2.values[0])}\`; + return \`\\u0BA4\\u0BB5\\u0BB1\\u0BBE\\u0BA9 \\u0BB5\\u0BBF\\u0BB0\\u0BC1\\u0BAA\\u0BCD\\u0BAA\\u0BAE\\u0BCD: \\u0B8E\\u0BA4\\u0BBF\\u0BB0\\u0BCD\\u0BAA\\u0BBE\\u0BB0\\u0BCD\\u0B95\\u0BCD\\u0B95\\u0BAA\\u0BCD\\u0BAA\\u0B9F\\u0BCD\\u0B9F\\u0BA4\\u0BC1 \${joinValues(issue2.values, "|")} \\u0B87\\u0BB2\\u0BCD \\u0B92\\u0BA9\\u0BCD\\u0BB1\\u0BC1\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`\\u0BAE\\u0BBF\\u0B95 \\u0BAA\\u0BC6\\u0BB0\\u0BBF\\u0BAF\\u0BA4\\u0BC1: \\u0B8E\\u0BA4\\u0BBF\\u0BB0\\u0BCD\\u0BAA\\u0BBE\\u0BB0\\u0BCD\\u0B95\\u0BCD\\u0B95\\u0BAA\\u0BCD\\u0BAA\\u0B9F\\u0BCD\\u0B9F\\u0BA4\\u0BC1 \${issue2.origin ?? "\\u0BAE\\u0BA4\\u0BBF\\u0BAA\\u0BCD\\u0BAA\\u0BC1"} \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "\\u0B89\\u0BB1\\u0BC1\\u0BAA\\u0BCD\\u0BAA\\u0BC1\\u0B95\\u0BB3\\u0BCD"} \\u0B86\\u0B95 \\u0B87\\u0BB0\\u0BC1\\u0B95\\u0BCD\\u0B95 \\u0BB5\\u0BC7\\u0BA3\\u0BCD\\u0B9F\\u0BC1\\u0BAE\\u0BCD\`; + } + return \`\\u0BAE\\u0BBF\\u0B95 \\u0BAA\\u0BC6\\u0BB0\\u0BBF\\u0BAF\\u0BA4\\u0BC1: \\u0B8E\\u0BA4\\u0BBF\\u0BB0\\u0BCD\\u0BAA\\u0BBE\\u0BB0\\u0BCD\\u0B95\\u0BCD\\u0B95\\u0BAA\\u0BCD\\u0BAA\\u0B9F\\u0BCD\\u0B9F\\u0BA4\\u0BC1 \${issue2.origin ?? "\\u0BAE\\u0BA4\\u0BBF\\u0BAA\\u0BCD\\u0BAA\\u0BC1"} \${adj}\${issue2.maximum.toString()} \\u0B86\\u0B95 \\u0B87\\u0BB0\\u0BC1\\u0B95\\u0BCD\\u0B95 \\u0BB5\\u0BC7\\u0BA3\\u0BCD\\u0B9F\\u0BC1\\u0BAE\\u0BCD\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`\\u0BAE\\u0BBF\\u0B95\\u0B9A\\u0BCD \\u0B9A\\u0BBF\\u0BB1\\u0BBF\\u0BAF\\u0BA4\\u0BC1: \\u0B8E\\u0BA4\\u0BBF\\u0BB0\\u0BCD\\u0BAA\\u0BBE\\u0BB0\\u0BCD\\u0B95\\u0BCD\\u0B95\\u0BAA\\u0BCD\\u0BAA\\u0B9F\\u0BCD\\u0B9F\\u0BA4\\u0BC1 \${issue2.origin} \${adj}\${issue2.minimum.toString()} \${sizing.unit} \\u0B86\\u0B95 \\u0B87\\u0BB0\\u0BC1\\u0B95\\u0BCD\\u0B95 \\u0BB5\\u0BC7\\u0BA3\\u0BCD\\u0B9F\\u0BC1\\u0BAE\\u0BCD\`; + } + return \`\\u0BAE\\u0BBF\\u0B95\\u0B9A\\u0BCD \\u0B9A\\u0BBF\\u0BB1\\u0BBF\\u0BAF\\u0BA4\\u0BC1: \\u0B8E\\u0BA4\\u0BBF\\u0BB0\\u0BCD\\u0BAA\\u0BBE\\u0BB0\\u0BCD\\u0B95\\u0BCD\\u0B95\\u0BAA\\u0BCD\\u0BAA\\u0B9F\\u0BCD\\u0B9F\\u0BA4\\u0BC1 \${issue2.origin} \${adj}\${issue2.minimum.toString()} \\u0B86\\u0B95 \\u0B87\\u0BB0\\u0BC1\\u0B95\\u0BCD\\u0B95 \\u0BB5\\u0BC7\\u0BA3\\u0BCD\\u0B9F\\u0BC1\\u0BAE\\u0BCD\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") return \`\\u0BA4\\u0BB5\\u0BB1\\u0BBE\\u0BA9 \\u0B9A\\u0BB0\\u0BAE\\u0BCD: "\${_issue.prefix}" \\u0B87\\u0BB2\\u0BCD \\u0BA4\\u0BCA\\u0B9F\\u0B99\\u0BCD\\u0B95 \\u0BB5\\u0BC7\\u0BA3\\u0BCD\\u0B9F\\u0BC1\\u0BAE\\u0BCD\`; + if (_issue.format === "ends_with") return \`\\u0BA4\\u0BB5\\u0BB1\\u0BBE\\u0BA9 \\u0B9A\\u0BB0\\u0BAE\\u0BCD: "\${_issue.suffix}" \\u0B87\\u0BB2\\u0BCD \\u0BAE\\u0BC1\\u0B9F\\u0BBF\\u0BB5\\u0B9F\\u0BC8\\u0BAF \\u0BB5\\u0BC7\\u0BA3\\u0BCD\\u0B9F\\u0BC1\\u0BAE\\u0BCD\`; + if (_issue.format === "includes") return \`\\u0BA4\\u0BB5\\u0BB1\\u0BBE\\u0BA9 \\u0B9A\\u0BB0\\u0BAE\\u0BCD: "\${_issue.includes}" \\u0B90 \\u0B89\\u0BB3\\u0BCD\\u0BB3\\u0B9F\\u0B95\\u0BCD\\u0B95 \\u0BB5\\u0BC7\\u0BA3\\u0BCD\\u0B9F\\u0BC1\\u0BAE\\u0BCD\`; + if (_issue.format === "regex") return \`\\u0BA4\\u0BB5\\u0BB1\\u0BBE\\u0BA9 \\u0B9A\\u0BB0\\u0BAE\\u0BCD: \${_issue.pattern} \\u0BAE\\u0BC1\\u0BB1\\u0BC8\\u0BAA\\u0BBE\\u0B9F\\u0BCD\\u0B9F\\u0BC1\\u0B9F\\u0BA9\\u0BCD \\u0BAA\\u0BCA\\u0BB0\\u0BC1\\u0BA8\\u0BCD\\u0BA4 \\u0BB5\\u0BC7\\u0BA3\\u0BCD\\u0B9F\\u0BC1\\u0BAE\\u0BCD\`; + return \`\\u0BA4\\u0BB5\\u0BB1\\u0BBE\\u0BA9 \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`\\u0BA4\\u0BB5\\u0BB1\\u0BBE\\u0BA9 \\u0B8E\\u0BA3\\u0BCD: \${issue2.divisor} \\u0B87\\u0BA9\\u0BCD \\u0BAA\\u0BB2\\u0BAE\\u0BBE\\u0B95 \\u0B87\\u0BB0\\u0BC1\\u0B95\\u0BCD\\u0B95 \\u0BB5\\u0BC7\\u0BA3\\u0BCD\\u0B9F\\u0BC1\\u0BAE\\u0BCD\`; + case "unrecognized_keys": + return \`\\u0B85\\u0B9F\\u0BC8\\u0BAF\\u0BBE\\u0BB3\\u0BAE\\u0BCD \\u0BA4\\u0BC6\\u0BB0\\u0BBF\\u0BAF\\u0BBE\\u0BA4 \\u0BB5\\u0BBF\\u0B9A\\u0BC8\${issue2.keys.length > 1 ? "\\u0B95\\u0BB3\\u0BCD" : ""}: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`\${issue2.origin} \\u0B87\\u0BB2\\u0BCD \\u0BA4\\u0BB5\\u0BB1\\u0BBE\\u0BA9 \\u0BB5\\u0BBF\\u0B9A\\u0BC8\`; + case "invalid_union": + return "\\u0BA4\\u0BB5\\u0BB1\\u0BBE\\u0BA9 \\u0B89\\u0BB3\\u0BCD\\u0BB3\\u0BC0\\u0B9F\\u0BC1"; + case "invalid_element": + return \`\${issue2.origin} \\u0B87\\u0BB2\\u0BCD \\u0BA4\\u0BB5\\u0BB1\\u0BBE\\u0BA9 \\u0BAE\\u0BA4\\u0BBF\\u0BAA\\u0BCD\\u0BAA\\u0BC1\`; + default: + return \`\\u0BA4\\u0BB5\\u0BB1\\u0BBE\\u0BA9 \\u0B89\\u0BB3\\u0BCD\\u0BB3\\u0BC0\\u0B9F\\u0BC1\`; + } + }; +}, "error"); +function ta_default() { + return { + localeError: error36() + }; +} +__name(ta_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/th.js +var error37 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "\\u0E15\\u0E31\\u0E27\\u0E2D\\u0E31\\u0E01\\u0E29\\u0E23", + verb: "\\u0E04\\u0E27\\u0E23\\u0E21\\u0E35" + }, + file: { + unit: "\\u0E44\\u0E1A\\u0E15\\u0E4C", + verb: "\\u0E04\\u0E27\\u0E23\\u0E21\\u0E35" + }, + array: { + unit: "\\u0E23\\u0E32\\u0E22\\u0E01\\u0E32\\u0E23", + verb: "\\u0E04\\u0E27\\u0E23\\u0E21\\u0E35" + }, + set: { + unit: "\\u0E23\\u0E32\\u0E22\\u0E01\\u0E32\\u0E23", + verb: "\\u0E04\\u0E27\\u0E23\\u0E21\\u0E35" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "\\u0E44\\u0E21\\u0E48\\u0E43\\u0E0A\\u0E48\\u0E15\\u0E31\\u0E27\\u0E40\\u0E25\\u0E02 (NaN)" : "\\u0E15\\u0E31\\u0E27\\u0E40\\u0E25\\u0E02"; + } + case "object": { + if (Array.isArray(data)) { + return "\\u0E2D\\u0E32\\u0E23\\u0E4C\\u0E40\\u0E23\\u0E22\\u0E4C (Array)"; + } + if (data === null) { + return "\\u0E44\\u0E21\\u0E48\\u0E21\\u0E35\\u0E04\\u0E48\\u0E32 (null)"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "\\u0E02\\u0E49\\u0E2D\\u0E21\\u0E39\\u0E25\\u0E17\\u0E35\\u0E48\\u0E1B\\u0E49\\u0E2D\\u0E19", + email: "\\u0E17\\u0E35\\u0E48\\u0E2D\\u0E22\\u0E39\\u0E48\\u0E2D\\u0E35\\u0E40\\u0E21\\u0E25", + url: "URL", + emoji: "\\u0E2D\\u0E34\\u0E42\\u0E21\\u0E08\\u0E34", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "\\u0E27\\u0E31\\u0E19\\u0E17\\u0E35\\u0E48\\u0E40\\u0E27\\u0E25\\u0E32\\u0E41\\u0E1A\\u0E1A ISO", + date: "\\u0E27\\u0E31\\u0E19\\u0E17\\u0E35\\u0E48\\u0E41\\u0E1A\\u0E1A ISO", + time: "\\u0E40\\u0E27\\u0E25\\u0E32\\u0E41\\u0E1A\\u0E1A ISO", + duration: "\\u0E0A\\u0E48\\u0E27\\u0E07\\u0E40\\u0E27\\u0E25\\u0E32\\u0E41\\u0E1A\\u0E1A ISO", + ipv4: "\\u0E17\\u0E35\\u0E48\\u0E2D\\u0E22\\u0E39\\u0E48 IPv4", + ipv6: "\\u0E17\\u0E35\\u0E48\\u0E2D\\u0E22\\u0E39\\u0E48 IPv6", + cidrv4: "\\u0E0A\\u0E48\\u0E27\\u0E07 IP \\u0E41\\u0E1A\\u0E1A IPv4", + cidrv6: "\\u0E0A\\u0E48\\u0E27\\u0E07 IP \\u0E41\\u0E1A\\u0E1A IPv6", + base64: "\\u0E02\\u0E49\\u0E2D\\u0E04\\u0E27\\u0E32\\u0E21\\u0E41\\u0E1A\\u0E1A Base64", + base64url: "\\u0E02\\u0E49\\u0E2D\\u0E04\\u0E27\\u0E32\\u0E21\\u0E41\\u0E1A\\u0E1A Base64 \\u0E2A\\u0E33\\u0E2B\\u0E23\\u0E31\\u0E1A URL", + json_string: "\\u0E02\\u0E49\\u0E2D\\u0E04\\u0E27\\u0E32\\u0E21\\u0E41\\u0E1A\\u0E1A JSON", + e164: "\\u0E40\\u0E1A\\u0E2D\\u0E23\\u0E4C\\u0E42\\u0E17\\u0E23\\u0E28\\u0E31\\u0E1E\\u0E17\\u0E4C\\u0E23\\u0E30\\u0E2B\\u0E27\\u0E48\\u0E32\\u0E07\\u0E1B\\u0E23\\u0E30\\u0E40\\u0E17\\u0E28 (E.164)", + jwt: "\\u0E42\\u0E17\\u0E40\\u0E04\\u0E19 JWT", + template_literal: "\\u0E02\\u0E49\\u0E2D\\u0E21\\u0E39\\u0E25\\u0E17\\u0E35\\u0E48\\u0E1B\\u0E49\\u0E2D\\u0E19" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`\\u0E1B\\u0E23\\u0E30\\u0E40\\u0E20\\u0E17\\u0E02\\u0E49\\u0E2D\\u0E21\\u0E39\\u0E25\\u0E44\\u0E21\\u0E48\\u0E16\\u0E39\\u0E01\\u0E15\\u0E49\\u0E2D\\u0E07: \\u0E04\\u0E27\\u0E23\\u0E40\\u0E1B\\u0E47\\u0E19 \${issue2.expected} \\u0E41\\u0E15\\u0E48\\u0E44\\u0E14\\u0E49\\u0E23\\u0E31\\u0E1A \${parsedType7(issue2.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`\\u0E04\\u0E48\\u0E32\\u0E44\\u0E21\\u0E48\\u0E16\\u0E39\\u0E01\\u0E15\\u0E49\\u0E2D\\u0E07: \\u0E04\\u0E27\\u0E23\\u0E40\\u0E1B\\u0E47\\u0E19 \${stringifyPrimitive(issue2.values[0])}\`; + return \`\\u0E15\\u0E31\\u0E27\\u0E40\\u0E25\\u0E37\\u0E2D\\u0E01\\u0E44\\u0E21\\u0E48\\u0E16\\u0E39\\u0E01\\u0E15\\u0E49\\u0E2D\\u0E07: \\u0E04\\u0E27\\u0E23\\u0E40\\u0E1B\\u0E47\\u0E19\\u0E2B\\u0E19\\u0E36\\u0E48\\u0E07\\u0E43\\u0E19 \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "\\u0E44\\u0E21\\u0E48\\u0E40\\u0E01\\u0E34\\u0E19" : "\\u0E19\\u0E49\\u0E2D\\u0E22\\u0E01\\u0E27\\u0E48\\u0E32"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`\\u0E40\\u0E01\\u0E34\\u0E19\\u0E01\\u0E33\\u0E2B\\u0E19\\u0E14: \${issue2.origin ?? "\\u0E04\\u0E48\\u0E32"} \\u0E04\\u0E27\\u0E23\\u0E21\\u0E35\${adj} \${issue2.maximum.toString()} \${sizing.unit ?? "\\u0E23\\u0E32\\u0E22\\u0E01\\u0E32\\u0E23"}\`; + return \`\\u0E40\\u0E01\\u0E34\\u0E19\\u0E01\\u0E33\\u0E2B\\u0E19\\u0E14: \${issue2.origin ?? "\\u0E04\\u0E48\\u0E32"} \\u0E04\\u0E27\\u0E23\\u0E21\\u0E35\${adj} \${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? "\\u0E2D\\u0E22\\u0E48\\u0E32\\u0E07\\u0E19\\u0E49\\u0E2D\\u0E22" : "\\u0E21\\u0E32\\u0E01\\u0E01\\u0E27\\u0E48\\u0E32"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`\\u0E19\\u0E49\\u0E2D\\u0E22\\u0E01\\u0E27\\u0E48\\u0E32\\u0E01\\u0E33\\u0E2B\\u0E19\\u0E14: \${issue2.origin} \\u0E04\\u0E27\\u0E23\\u0E21\\u0E35\${adj} \${issue2.minimum.toString()} \${sizing.unit}\`; + } + return \`\\u0E19\\u0E49\\u0E2D\\u0E22\\u0E01\\u0E27\\u0E48\\u0E32\\u0E01\\u0E33\\u0E2B\\u0E19\\u0E14: \${issue2.origin} \\u0E04\\u0E27\\u0E23\\u0E21\\u0E35\${adj} \${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") { + return \`\\u0E23\\u0E39\\u0E1B\\u0E41\\u0E1A\\u0E1A\\u0E44\\u0E21\\u0E48\\u0E16\\u0E39\\u0E01\\u0E15\\u0E49\\u0E2D\\u0E07: \\u0E02\\u0E49\\u0E2D\\u0E04\\u0E27\\u0E32\\u0E21\\u0E15\\u0E49\\u0E2D\\u0E07\\u0E02\\u0E36\\u0E49\\u0E19\\u0E15\\u0E49\\u0E19\\u0E14\\u0E49\\u0E27\\u0E22 "\${_issue.prefix}"\`; + } + if (_issue.format === "ends_with") return \`\\u0E23\\u0E39\\u0E1B\\u0E41\\u0E1A\\u0E1A\\u0E44\\u0E21\\u0E48\\u0E16\\u0E39\\u0E01\\u0E15\\u0E49\\u0E2D\\u0E07: \\u0E02\\u0E49\\u0E2D\\u0E04\\u0E27\\u0E32\\u0E21\\u0E15\\u0E49\\u0E2D\\u0E07\\u0E25\\u0E07\\u0E17\\u0E49\\u0E32\\u0E22\\u0E14\\u0E49\\u0E27\\u0E22 "\${_issue.suffix}"\`; + if (_issue.format === "includes") return \`\\u0E23\\u0E39\\u0E1B\\u0E41\\u0E1A\\u0E1A\\u0E44\\u0E21\\u0E48\\u0E16\\u0E39\\u0E01\\u0E15\\u0E49\\u0E2D\\u0E07: \\u0E02\\u0E49\\u0E2D\\u0E04\\u0E27\\u0E32\\u0E21\\u0E15\\u0E49\\u0E2D\\u0E07\\u0E21\\u0E35 "\${_issue.includes}" \\u0E2D\\u0E22\\u0E39\\u0E48\\u0E43\\u0E19\\u0E02\\u0E49\\u0E2D\\u0E04\\u0E27\\u0E32\\u0E21\`; + if (_issue.format === "regex") return \`\\u0E23\\u0E39\\u0E1B\\u0E41\\u0E1A\\u0E1A\\u0E44\\u0E21\\u0E48\\u0E16\\u0E39\\u0E01\\u0E15\\u0E49\\u0E2D\\u0E07: \\u0E15\\u0E49\\u0E2D\\u0E07\\u0E15\\u0E23\\u0E07\\u0E01\\u0E31\\u0E1A\\u0E23\\u0E39\\u0E1B\\u0E41\\u0E1A\\u0E1A\\u0E17\\u0E35\\u0E48\\u0E01\\u0E33\\u0E2B\\u0E19\\u0E14 \${_issue.pattern}\`; + return \`\\u0E23\\u0E39\\u0E1B\\u0E41\\u0E1A\\u0E1A\\u0E44\\u0E21\\u0E48\\u0E16\\u0E39\\u0E01\\u0E15\\u0E49\\u0E2D\\u0E07: \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`\\u0E15\\u0E31\\u0E27\\u0E40\\u0E25\\u0E02\\u0E44\\u0E21\\u0E48\\u0E16\\u0E39\\u0E01\\u0E15\\u0E49\\u0E2D\\u0E07: \\u0E15\\u0E49\\u0E2D\\u0E07\\u0E40\\u0E1B\\u0E47\\u0E19\\u0E08\\u0E33\\u0E19\\u0E27\\u0E19\\u0E17\\u0E35\\u0E48\\u0E2B\\u0E32\\u0E23\\u0E14\\u0E49\\u0E27\\u0E22 \${issue2.divisor} \\u0E44\\u0E14\\u0E49\\u0E25\\u0E07\\u0E15\\u0E31\\u0E27\`; + case "unrecognized_keys": + return \`\\u0E1E\\u0E1A\\u0E04\\u0E35\\u0E22\\u0E4C\\u0E17\\u0E35\\u0E48\\u0E44\\u0E21\\u0E48\\u0E23\\u0E39\\u0E49\\u0E08\\u0E31\\u0E01: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`\\u0E04\\u0E35\\u0E22\\u0E4C\\u0E44\\u0E21\\u0E48\\u0E16\\u0E39\\u0E01\\u0E15\\u0E49\\u0E2D\\u0E07\\u0E43\\u0E19 \${issue2.origin}\`; + case "invalid_union": + return "\\u0E02\\u0E49\\u0E2D\\u0E21\\u0E39\\u0E25\\u0E44\\u0E21\\u0E48\\u0E16\\u0E39\\u0E01\\u0E15\\u0E49\\u0E2D\\u0E07: \\u0E44\\u0E21\\u0E48\\u0E15\\u0E23\\u0E07\\u0E01\\u0E31\\u0E1A\\u0E23\\u0E39\\u0E1B\\u0E41\\u0E1A\\u0E1A\\u0E22\\u0E39\\u0E40\\u0E19\\u0E35\\u0E22\\u0E19\\u0E17\\u0E35\\u0E48\\u0E01\\u0E33\\u0E2B\\u0E19\\u0E14\\u0E44\\u0E27\\u0E49"; + case "invalid_element": + return \`\\u0E02\\u0E49\\u0E2D\\u0E21\\u0E39\\u0E25\\u0E44\\u0E21\\u0E48\\u0E16\\u0E39\\u0E01\\u0E15\\u0E49\\u0E2D\\u0E07\\u0E43\\u0E19 \${issue2.origin}\`; + default: + return \`\\u0E02\\u0E49\\u0E2D\\u0E21\\u0E39\\u0E25\\u0E44\\u0E21\\u0E48\\u0E16\\u0E39\\u0E01\\u0E15\\u0E49\\u0E2D\\u0E07\`; + } + }; +}, "error"); +function th_default() { + return { + localeError: error37() + }; +} +__name(th_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/tr.js +var parsedType6 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "number"; + } + case "object": { + if (Array.isArray(data)) { + return "array"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; +}, "parsedType"); +var error38 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "karakter", + verb: "olmal\\u0131" + }, + file: { + unit: "bayt", + verb: "olmal\\u0131" + }, + array: { + unit: "\\xF6\\u011Fe", + verb: "olmal\\u0131" + }, + set: { + unit: "\\xF6\\u011Fe", + verb: "olmal\\u0131" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const Nouns = { + regex: "girdi", + email: "e-posta adresi", + url: "URL", + emoji: "emoji", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "ISO tarih ve saat", + date: "ISO tarih", + time: "ISO saat", + duration: "ISO s\\xFCre", + ipv4: "IPv4 adresi", + ipv6: "IPv6 adresi", + cidrv4: "IPv4 aral\\u0131\\u011F\\u0131", + cidrv6: "IPv6 aral\\u0131\\u011F\\u0131", + base64: "base64 ile \\u015Fifrelenmi\\u015F metin", + base64url: "base64url ile \\u015Fifrelenmi\\u015F metin", + json_string: "JSON dizesi", + e164: "E.164 say\\u0131s\\u0131", + jwt: "JWT", + template_literal: "\\u015Eablon dizesi" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`Ge\\xE7ersiz de\\u011Fer: beklenen \${issue2.expected}, al\\u0131nan \${parsedType6(issue2.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`Ge\\xE7ersiz de\\u011Fer: beklenen \${stringifyPrimitive(issue2.values[0])}\`; + return \`Ge\\xE7ersiz se\\xE7enek: a\\u015Fa\\u011F\\u0131dakilerden biri olmal\\u0131: \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`\\xC7ok b\\xFCy\\xFCk: beklenen \${issue2.origin ?? "de\\u011Fer"} \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "\\xF6\\u011Fe"}\`; + return \`\\xC7ok b\\xFCy\\xFCk: beklenen \${issue2.origin ?? "de\\u011Fer"} \${adj}\${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`\\xC7ok k\\xFC\\xE7\\xFCk: beklenen \${issue2.origin} \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; + return \`\\xC7ok k\\xFC\\xE7\\xFCk: beklenen \${issue2.origin} \${adj}\${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") return \`Ge\\xE7ersiz metin: "\${_issue.prefix}" ile ba\\u015Flamal\\u0131\`; + if (_issue.format === "ends_with") return \`Ge\\xE7ersiz metin: "\${_issue.suffix}" ile bitmeli\`; + if (_issue.format === "includes") return \`Ge\\xE7ersiz metin: "\${_issue.includes}" i\\xE7ermeli\`; + if (_issue.format === "regex") return \`Ge\\xE7ersiz metin: \${_issue.pattern} desenine uymal\\u0131\`; + return \`Ge\\xE7ersiz \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`Ge\\xE7ersiz say\\u0131: \${issue2.divisor} ile tam b\\xF6l\\xFCnebilmeli\`; + case "unrecognized_keys": + return \`Tan\\u0131nmayan anahtar\${issue2.keys.length > 1 ? "lar" : ""}: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`\${issue2.origin} i\\xE7inde ge\\xE7ersiz anahtar\`; + case "invalid_union": + return "Ge\\xE7ersiz de\\u011Fer"; + case "invalid_element": + return \`\${issue2.origin} i\\xE7inde ge\\xE7ersiz de\\u011Fer\`; + default: + return \`Ge\\xE7ersiz de\\u011Fer\`; + } + }; +}, "error"); +function tr_default() { + return { + localeError: error38() + }; +} +__name(tr_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/uk.js +var error39 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "\\u0441\\u0438\\u043C\\u0432\\u043E\\u043B\\u0456\\u0432", + verb: "\\u043C\\u0430\\u0442\\u0438\\u043C\\u0435" + }, + file: { + unit: "\\u0431\\u0430\\u0439\\u0442\\u0456\\u0432", + verb: "\\u043C\\u0430\\u0442\\u0438\\u043C\\u0435" + }, + array: { + unit: "\\u0435\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442\\u0456\\u0432", + verb: "\\u043C\\u0430\\u0442\\u0438\\u043C\\u0435" + }, + set: { + unit: "\\u0435\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442\\u0456\\u0432", + verb: "\\u043C\\u0430\\u0442\\u0438\\u043C\\u0435" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "\\u0447\\u0438\\u0441\\u043B\\u043E"; + } + case "object": { + if (Array.isArray(data)) { + return "\\u043C\\u0430\\u0441\\u0438\\u0432"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "\\u0432\\u0445\\u0456\\u0434\\u043D\\u0456 \\u0434\\u0430\\u043D\\u0456", + email: "\\u0430\\u0434\\u0440\\u0435\\u0441\\u0430 \\u0435\\u043B\\u0435\\u043A\\u0442\\u0440\\u043E\\u043D\\u043D\\u043E\\u0457 \\u043F\\u043E\\u0448\\u0442\\u0438", + url: "URL", + emoji: "\\u0435\\u043C\\u043E\\u0434\\u0437\\u0456", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "\\u0434\\u0430\\u0442\\u0430 \\u0442\\u0430 \\u0447\\u0430\\u0441 ISO", + date: "\\u0434\\u0430\\u0442\\u0430 ISO", + time: "\\u0447\\u0430\\u0441 ISO", + duration: "\\u0442\\u0440\\u0438\\u0432\\u0430\\u043B\\u0456\\u0441\\u0442\\u044C ISO", + ipv4: "\\u0430\\u0434\\u0440\\u0435\\u0441\\u0430 IPv4", + ipv6: "\\u0430\\u0434\\u0440\\u0435\\u0441\\u0430 IPv6", + cidrv4: "\\u0434\\u0456\\u0430\\u043F\\u0430\\u0437\\u043E\\u043D IPv4", + cidrv6: "\\u0434\\u0456\\u0430\\u043F\\u0430\\u0437\\u043E\\u043D IPv6", + base64: "\\u0440\\u044F\\u0434\\u043E\\u043A \\u0443 \\u043A\\u043E\\u0434\\u0443\\u0432\\u0430\\u043D\\u043D\\u0456 base64", + base64url: "\\u0440\\u044F\\u0434\\u043E\\u043A \\u0443 \\u043A\\u043E\\u0434\\u0443\\u0432\\u0430\\u043D\\u043D\\u0456 base64url", + json_string: "\\u0440\\u044F\\u0434\\u043E\\u043A JSON", + e164: "\\u043D\\u043E\\u043C\\u0435\\u0440 E.164", + jwt: "JWT", + template_literal: "\\u0432\\u0445\\u0456\\u0434\\u043D\\u0456 \\u0434\\u0430\\u043D\\u0456" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`\\u041D\\u0435\\u043F\\u0440\\u0430\\u0432\\u0438\\u043B\\u044C\\u043D\\u0456 \\u0432\\u0445\\u0456\\u0434\\u043D\\u0456 \\u0434\\u0430\\u043D\\u0456: \\u043E\\u0447\\u0456\\u043A\\u0443\\u0454\\u0442\\u044C\\u0441\\u044F \${issue2.expected}, \\u043E\\u0442\\u0440\\u0438\\u043C\\u0430\\u043D\\u043E \${parsedType7(issue2.input)}\`; + // return \`Неправильні вхідні дані: очікується \${issue.expected}, отримано \${util.getParsedType(issue.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`\\u041D\\u0435\\u043F\\u0440\\u0430\\u0432\\u0438\\u043B\\u044C\\u043D\\u0456 \\u0432\\u0445\\u0456\\u0434\\u043D\\u0456 \\u0434\\u0430\\u043D\\u0456: \\u043E\\u0447\\u0456\\u043A\\u0443\\u0454\\u0442\\u044C\\u0441\\u044F \${stringifyPrimitive(issue2.values[0])}\`; + return \`\\u041D\\u0435\\u043F\\u0440\\u0430\\u0432\\u0438\\u043B\\u044C\\u043D\\u0430 \\u043E\\u043F\\u0446\\u0456\\u044F: \\u043E\\u0447\\u0456\\u043A\\u0443\\u0454\\u0442\\u044C\\u0441\\u044F \\u043E\\u0434\\u043D\\u0435 \\u0437 \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`\\u0417\\u0430\\u043D\\u0430\\u0434\\u0442\\u043E \\u0432\\u0435\\u043B\\u0438\\u043A\\u0435: \\u043E\\u0447\\u0456\\u043A\\u0443\\u0454\\u0442\\u044C\\u0441\\u044F, \\u0449\\u043E \${issue2.origin ?? "\\u0437\\u043D\\u0430\\u0447\\u0435\\u043D\\u043D\\u044F"} \${sizing.verb} \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "\\u0435\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442\\u0456\\u0432"}\`; + return \`\\u0417\\u0430\\u043D\\u0430\\u0434\\u0442\\u043E \\u0432\\u0435\\u043B\\u0438\\u043A\\u0435: \\u043E\\u0447\\u0456\\u043A\\u0443\\u0454\\u0442\\u044C\\u0441\\u044F, \\u0449\\u043E \${issue2.origin ?? "\\u0437\\u043D\\u0430\\u0447\\u0435\\u043D\\u043D\\u044F"} \\u0431\\u0443\\u0434\\u0435 \${adj}\${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`\\u0417\\u0430\\u043D\\u0430\\u0434\\u0442\\u043E \\u043C\\u0430\\u043B\\u0435: \\u043E\\u0447\\u0456\\u043A\\u0443\\u0454\\u0442\\u044C\\u0441\\u044F, \\u0449\\u043E \${issue2.origin} \${sizing.verb} \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; + } + return \`\\u0417\\u0430\\u043D\\u0430\\u0434\\u0442\\u043E \\u043C\\u0430\\u043B\\u0435: \\u043E\\u0447\\u0456\\u043A\\u0443\\u0454\\u0442\\u044C\\u0441\\u044F, \\u0449\\u043E \${issue2.origin} \\u0431\\u0443\\u0434\\u0435 \${adj}\${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") return \`\\u041D\\u0435\\u043F\\u0440\\u0430\\u0432\\u0438\\u043B\\u044C\\u043D\\u0438\\u0439 \\u0440\\u044F\\u0434\\u043E\\u043A: \\u043F\\u043E\\u0432\\u0438\\u043D\\u0435\\u043D \\u043F\\u043E\\u0447\\u0438\\u043D\\u0430\\u0442\\u0438\\u0441\\u044F \\u0437 "\${_issue.prefix}"\`; + if (_issue.format === "ends_with") return \`\\u041D\\u0435\\u043F\\u0440\\u0430\\u0432\\u0438\\u043B\\u044C\\u043D\\u0438\\u0439 \\u0440\\u044F\\u0434\\u043E\\u043A: \\u043F\\u043E\\u0432\\u0438\\u043D\\u0435\\u043D \\u0437\\u0430\\u043A\\u0456\\u043D\\u0447\\u0443\\u0432\\u0430\\u0442\\u0438\\u0441\\u044F \\u043D\\u0430 "\${_issue.suffix}"\`; + if (_issue.format === "includes") return \`\\u041D\\u0435\\u043F\\u0440\\u0430\\u0432\\u0438\\u043B\\u044C\\u043D\\u0438\\u0439 \\u0440\\u044F\\u0434\\u043E\\u043A: \\u043F\\u043E\\u0432\\u0438\\u043D\\u0435\\u043D \\u043C\\u0456\\u0441\\u0442\\u0438\\u0442\\u0438 "\${_issue.includes}"\`; + if (_issue.format === "regex") return \`\\u041D\\u0435\\u043F\\u0440\\u0430\\u0432\\u0438\\u043B\\u044C\\u043D\\u0438\\u0439 \\u0440\\u044F\\u0434\\u043E\\u043A: \\u043F\\u043E\\u0432\\u0438\\u043D\\u0435\\u043D \\u0432\\u0456\\u0434\\u043F\\u043E\\u0432\\u0456\\u0434\\u0430\\u0442\\u0438 \\u0448\\u0430\\u0431\\u043B\\u043E\\u043D\\u0443 \${_issue.pattern}\`; + return \`\\u041D\\u0435\\u043F\\u0440\\u0430\\u0432\\u0438\\u043B\\u044C\\u043D\\u0438\\u0439 \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`\\u041D\\u0435\\u043F\\u0440\\u0430\\u0432\\u0438\\u043B\\u044C\\u043D\\u0435 \\u0447\\u0438\\u0441\\u043B\\u043E: \\u043F\\u043E\\u0432\\u0438\\u043D\\u043D\\u043E \\u0431\\u0443\\u0442\\u0438 \\u043A\\u0440\\u0430\\u0442\\u043D\\u0438\\u043C \${issue2.divisor}\`; + case "unrecognized_keys": + return \`\\u041D\\u0435\\u0440\\u043E\\u0437\\u043F\\u0456\\u0437\\u043D\\u0430\\u043D\\u0438\\u0439 \\u043A\\u043B\\u044E\\u0447\${issue2.keys.length > 1 ? "\\u0456" : ""}: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`\\u041D\\u0435\\u043F\\u0440\\u0430\\u0432\\u0438\\u043B\\u044C\\u043D\\u0438\\u0439 \\u043A\\u043B\\u044E\\u0447 \\u0443 \${issue2.origin}\`; + case "invalid_union": + return "\\u041D\\u0435\\u043F\\u0440\\u0430\\u0432\\u0438\\u043B\\u044C\\u043D\\u0456 \\u0432\\u0445\\u0456\\u0434\\u043D\\u0456 \\u0434\\u0430\\u043D\\u0456"; + case "invalid_element": + return \`\\u041D\\u0435\\u043F\\u0440\\u0430\\u0432\\u0438\\u043B\\u044C\\u043D\\u0435 \\u0437\\u043D\\u0430\\u0447\\u0435\\u043D\\u043D\\u044F \\u0443 \${issue2.origin}\`; + default: + return \`\\u041D\\u0435\\u043F\\u0440\\u0430\\u0432\\u0438\\u043B\\u044C\\u043D\\u0456 \\u0432\\u0445\\u0456\\u0434\\u043D\\u0456 \\u0434\\u0430\\u043D\\u0456\`; + } + }; +}, "error"); +function uk_default() { + return { + localeError: error39() + }; +} +__name(uk_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/ua.js +function ua_default() { + return uk_default(); +} +__name(ua_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/ur.js +var error40 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "\\u062D\\u0631\\u0648\\u0641", + verb: "\\u06C1\\u0648\\u0646\\u0627" + }, + file: { + unit: "\\u0628\\u0627\\u0626\\u0679\\u0633", + verb: "\\u06C1\\u0648\\u0646\\u0627" + }, + array: { + unit: "\\u0622\\u0626\\u0679\\u0645\\u0632", + verb: "\\u06C1\\u0648\\u0646\\u0627" + }, + set: { + unit: "\\u0622\\u0626\\u0679\\u0645\\u0632", + verb: "\\u06C1\\u0648\\u0646\\u0627" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "\\u0646\\u0645\\u0628\\u0631"; + } + case "object": { + if (Array.isArray(data)) { + return "\\u0622\\u0631\\u06D2"; + } + if (data === null) { + return "\\u0646\\u0644"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "\\u0627\\u0646 \\u067E\\u0679", + email: "\\u0627\\u06CC \\u0645\\u06CC\\u0644 \\u0627\\u06CC\\u0688\\u0631\\u06CC\\u0633", + url: "\\u06CC\\u0648 \\u0622\\u0631 \\u0627\\u06CC\\u0644", + emoji: "\\u0627\\u06CC\\u0645\\u0648\\u062C\\u06CC", + uuid: "\\u06CC\\u0648 \\u06CC\\u0648 \\u0622\\u0626\\u06CC \\u0688\\u06CC", + uuidv4: "\\u06CC\\u0648 \\u06CC\\u0648 \\u0622\\u0626\\u06CC \\u0688\\u06CC \\u0648\\u06CC 4", + uuidv6: "\\u06CC\\u0648 \\u06CC\\u0648 \\u0622\\u0626\\u06CC \\u0688\\u06CC \\u0648\\u06CC 6", + nanoid: "\\u0646\\u06CC\\u0646\\u0648 \\u0622\\u0626\\u06CC \\u0688\\u06CC", + guid: "\\u062C\\u06CC \\u06CC\\u0648 \\u0622\\u0626\\u06CC \\u0688\\u06CC", + cuid: "\\u0633\\u06CC \\u06CC\\u0648 \\u0622\\u0626\\u06CC \\u0688\\u06CC", + cuid2: "\\u0633\\u06CC \\u06CC\\u0648 \\u0622\\u0626\\u06CC \\u0688\\u06CC 2", + ulid: "\\u06CC\\u0648 \\u0627\\u06CC\\u0644 \\u0622\\u0626\\u06CC \\u0688\\u06CC", + xid: "\\u0627\\u06CC\\u06A9\\u0633 \\u0622\\u0626\\u06CC \\u0688\\u06CC", + ksuid: "\\u06A9\\u06D2 \\u0627\\u06CC\\u0633 \\u06CC\\u0648 \\u0622\\u0626\\u06CC \\u0688\\u06CC", + datetime: "\\u0622\\u0626\\u06CC \\u0627\\u06CC\\u0633 \\u0627\\u0648 \\u0688\\u06CC\\u0679 \\u0679\\u0627\\u0626\\u0645", + date: "\\u0622\\u0626\\u06CC \\u0627\\u06CC\\u0633 \\u0627\\u0648 \\u062A\\u0627\\u0631\\u06CC\\u062E", + time: "\\u0622\\u0626\\u06CC \\u0627\\u06CC\\u0633 \\u0627\\u0648 \\u0648\\u0642\\u062A", + duration: "\\u0622\\u0626\\u06CC \\u0627\\u06CC\\u0633 \\u0627\\u0648 \\u0645\\u062F\\u062A", + ipv4: "\\u0622\\u0626\\u06CC \\u067E\\u06CC \\u0648\\u06CC 4 \\u0627\\u06CC\\u0688\\u0631\\u06CC\\u0633", + ipv6: "\\u0622\\u0626\\u06CC \\u067E\\u06CC \\u0648\\u06CC 6 \\u0627\\u06CC\\u0688\\u0631\\u06CC\\u0633", + cidrv4: "\\u0622\\u0626\\u06CC \\u067E\\u06CC \\u0648\\u06CC 4 \\u0631\\u06CC\\u0646\\u062C", + cidrv6: "\\u0622\\u0626\\u06CC \\u067E\\u06CC \\u0648\\u06CC 6 \\u0631\\u06CC\\u0646\\u062C", + base64: "\\u0628\\u06CC\\u0633 64 \\u0627\\u0646 \\u06A9\\u0648\\u0688\\u0688 \\u0633\\u0679\\u0631\\u0646\\u06AF", + base64url: "\\u0628\\u06CC\\u0633 64 \\u06CC\\u0648 \\u0622\\u0631 \\u0627\\u06CC\\u0644 \\u0627\\u0646 \\u06A9\\u0648\\u0688\\u0688 \\u0633\\u0679\\u0631\\u0646\\u06AF", + json_string: "\\u062C\\u06D2 \\u0627\\u06CC\\u0633 \\u0627\\u0648 \\u0627\\u06CC\\u0646 \\u0633\\u0679\\u0631\\u0646\\u06AF", + e164: "\\u0627\\u06CC 164 \\u0646\\u0645\\u0628\\u0631", + jwt: "\\u062C\\u06D2 \\u0688\\u0628\\u0644\\u06CC\\u0648 \\u0679\\u06CC", + template_literal: "\\u0627\\u0646 \\u067E\\u0679" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`\\u063A\\u0644\\u0637 \\u0627\\u0646 \\u067E\\u0679: \${issue2.expected} \\u0645\\u062A\\u0648\\u0642\\u0639 \\u062A\\u06BE\\u0627\\u060C \${parsedType7(issue2.input)} \\u0645\\u0648\\u0635\\u0648\\u0644 \\u06C1\\u0648\\u0627\`; + case "invalid_value": + if (issue2.values.length === 1) return \`\\u063A\\u0644\\u0637 \\u0627\\u0646 \\u067E\\u0679: \${stringifyPrimitive(issue2.values[0])} \\u0645\\u062A\\u0648\\u0642\\u0639 \\u062A\\u06BE\\u0627\`; + return \`\\u063A\\u0644\\u0637 \\u0622\\u067E\\u0634\\u0646: \${joinValues(issue2.values, "|")} \\u0645\\u06CC\\u06BA \\u0633\\u06D2 \\u0627\\u06CC\\u06A9 \\u0645\\u062A\\u0648\\u0642\\u0639 \\u062A\\u06BE\\u0627\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`\\u0628\\u06C1\\u062A \\u0628\\u0691\\u0627: \${issue2.origin ?? "\\u0648\\u06CC\\u0644\\u06CC\\u0648"} \\u06A9\\u06D2 \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "\\u0639\\u0646\\u0627\\u0635\\u0631"} \\u06C1\\u0648\\u0646\\u06D2 \\u0645\\u062A\\u0648\\u0642\\u0639 \\u062A\\u06BE\\u06D2\`; + return \`\\u0628\\u06C1\\u062A \\u0628\\u0691\\u0627: \${issue2.origin ?? "\\u0648\\u06CC\\u0644\\u06CC\\u0648"} \\u06A9\\u0627 \${adj}\${issue2.maximum.toString()} \\u06C1\\u0648\\u0646\\u0627 \\u0645\\u062A\\u0648\\u0642\\u0639 \\u062A\\u06BE\\u0627\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`\\u0628\\u06C1\\u062A \\u0686\\u06BE\\u0648\\u0679\\u0627: \${issue2.origin} \\u06A9\\u06D2 \${adj}\${issue2.minimum.toString()} \${sizing.unit} \\u06C1\\u0648\\u0646\\u06D2 \\u0645\\u062A\\u0648\\u0642\\u0639 \\u062A\\u06BE\\u06D2\`; + } + return \`\\u0628\\u06C1\\u062A \\u0686\\u06BE\\u0648\\u0679\\u0627: \${issue2.origin} \\u06A9\\u0627 \${adj}\${issue2.minimum.toString()} \\u06C1\\u0648\\u0646\\u0627 \\u0645\\u062A\\u0648\\u0642\\u0639 \\u062A\\u06BE\\u0627\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") { + return \`\\u063A\\u0644\\u0637 \\u0633\\u0679\\u0631\\u0646\\u06AF: "\${_issue.prefix}" \\u0633\\u06D2 \\u0634\\u0631\\u0648\\u0639 \\u06C1\\u0648\\u0646\\u0627 \\u0686\\u0627\\u06C1\\u06CC\\u06D2\`; + } + if (_issue.format === "ends_with") return \`\\u063A\\u0644\\u0637 \\u0633\\u0679\\u0631\\u0646\\u06AF: "\${_issue.suffix}" \\u067E\\u0631 \\u062E\\u062A\\u0645 \\u06C1\\u0648\\u0646\\u0627 \\u0686\\u0627\\u06C1\\u06CC\\u06D2\`; + if (_issue.format === "includes") return \`\\u063A\\u0644\\u0637 \\u0633\\u0679\\u0631\\u0646\\u06AF: "\${_issue.includes}" \\u0634\\u0627\\u0645\\u0644 \\u06C1\\u0648\\u0646\\u0627 \\u0686\\u0627\\u06C1\\u06CC\\u06D2\`; + if (_issue.format === "regex") return \`\\u063A\\u0644\\u0637 \\u0633\\u0679\\u0631\\u0646\\u06AF: \\u067E\\u06CC\\u0679\\u0631\\u0646 \${_issue.pattern} \\u0633\\u06D2 \\u0645\\u06CC\\u0686 \\u06C1\\u0648\\u0646\\u0627 \\u0686\\u0627\\u06C1\\u06CC\\u06D2\`; + return \`\\u063A\\u0644\\u0637 \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`\\u063A\\u0644\\u0637 \\u0646\\u0645\\u0628\\u0631: \${issue2.divisor} \\u06A9\\u0627 \\u0645\\u0636\\u0627\\u0639\\u0641 \\u06C1\\u0648\\u0646\\u0627 \\u0686\\u0627\\u06C1\\u06CC\\u06D2\`; + case "unrecognized_keys": + return \`\\u063A\\u06CC\\u0631 \\u062A\\u0633\\u0644\\u06CC\\u0645 \\u0634\\u062F\\u06C1 \\u06A9\\u06CC\${issue2.keys.length > 1 ? "\\u0632" : ""}: \${joinValues(issue2.keys, "\\u060C ")}\`; + case "invalid_key": + return \`\${issue2.origin} \\u0645\\u06CC\\u06BA \\u063A\\u0644\\u0637 \\u06A9\\u06CC\`; + case "invalid_union": + return "\\u063A\\u0644\\u0637 \\u0627\\u0646 \\u067E\\u0679"; + case "invalid_element": + return \`\${issue2.origin} \\u0645\\u06CC\\u06BA \\u063A\\u0644\\u0637 \\u0648\\u06CC\\u0644\\u06CC\\u0648\`; + default: + return \`\\u063A\\u0644\\u0637 \\u0627\\u0646 \\u067E\\u0679\`; + } + }; +}, "error"); +function ur_default() { + return { + localeError: error40() + }; +} +__name(ur_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/vi.js +var error41 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "k\\xFD t\\u1EF1", + verb: "c\\xF3" + }, + file: { + unit: "byte", + verb: "c\\xF3" + }, + array: { + unit: "ph\\u1EA7n t\\u1EED", + verb: "c\\xF3" + }, + set: { + unit: "ph\\u1EA7n t\\u1EED", + verb: "c\\xF3" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "s\\u1ED1"; + } + case "object": { + if (Array.isArray(data)) { + return "m\\u1EA3ng"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "\\u0111\\u1EA7u v\\xE0o", + email: "\\u0111\\u1ECBa ch\\u1EC9 email", + url: "URL", + emoji: "emoji", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "ng\\xE0y gi\\u1EDD ISO", + date: "ng\\xE0y ISO", + time: "gi\\u1EDD ISO", + duration: "kho\\u1EA3ng th\\u1EDDi gian ISO", + ipv4: "\\u0111\\u1ECBa ch\\u1EC9 IPv4", + ipv6: "\\u0111\\u1ECBa ch\\u1EC9 IPv6", + cidrv4: "d\\u1EA3i IPv4", + cidrv6: "d\\u1EA3i IPv6", + base64: "chu\\u1ED7i m\\xE3 h\\xF3a base64", + base64url: "chu\\u1ED7i m\\xE3 h\\xF3a base64url", + json_string: "chu\\u1ED7i JSON", + e164: "s\\u1ED1 E.164", + jwt: "JWT", + template_literal: "\\u0111\\u1EA7u v\\xE0o" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`\\u0110\\u1EA7u v\\xE0o kh\\xF4ng h\\u1EE3p l\\u1EC7: mong \\u0111\\u1EE3i \${issue2.expected}, nh\\u1EADn \\u0111\\u01B0\\u1EE3c \${parsedType7(issue2.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`\\u0110\\u1EA7u v\\xE0o kh\\xF4ng h\\u1EE3p l\\u1EC7: mong \\u0111\\u1EE3i \${stringifyPrimitive(issue2.values[0])}\`; + return \`T\\xF9y ch\\u1ECDn kh\\xF4ng h\\u1EE3p l\\u1EC7: mong \\u0111\\u1EE3i m\\u1ED9t trong c\\xE1c gi\\xE1 tr\\u1ECB \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`Qu\\xE1 l\\u1EDBn: mong \\u0111\\u1EE3i \${issue2.origin ?? "gi\\xE1 tr\\u1ECB"} \${sizing.verb} \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "ph\\u1EA7n t\\u1EED"}\`; + return \`Qu\\xE1 l\\u1EDBn: mong \\u0111\\u1EE3i \${issue2.origin ?? "gi\\xE1 tr\\u1ECB"} \${adj}\${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`Qu\\xE1 nh\\u1ECF: mong \\u0111\\u1EE3i \${issue2.origin} \${sizing.verb} \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; + } + return \`Qu\\xE1 nh\\u1ECF: mong \\u0111\\u1EE3i \${issue2.origin} \${adj}\${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") return \`Chu\\u1ED7i kh\\xF4ng h\\u1EE3p l\\u1EC7: ph\\u1EA3i b\\u1EAFt \\u0111\\u1EA7u b\\u1EB1ng "\${_issue.prefix}"\`; + if (_issue.format === "ends_with") return \`Chu\\u1ED7i kh\\xF4ng h\\u1EE3p l\\u1EC7: ph\\u1EA3i k\\u1EBFt th\\xFAc b\\u1EB1ng "\${_issue.suffix}"\`; + if (_issue.format === "includes") return \`Chu\\u1ED7i kh\\xF4ng h\\u1EE3p l\\u1EC7: ph\\u1EA3i bao g\\u1ED3m "\${_issue.includes}"\`; + if (_issue.format === "regex") return \`Chu\\u1ED7i kh\\xF4ng h\\u1EE3p l\\u1EC7: ph\\u1EA3i kh\\u1EDBp v\\u1EDBi m\\u1EABu \${_issue.pattern}\`; + return \`\${Nouns[_issue.format] ?? issue2.format} kh\\xF4ng h\\u1EE3p l\\u1EC7\`; + } + case "not_multiple_of": + return \`S\\u1ED1 kh\\xF4ng h\\u1EE3p l\\u1EC7: ph\\u1EA3i l\\xE0 b\\u1ED9i s\\u1ED1 c\\u1EE7a \${issue2.divisor}\`; + case "unrecognized_keys": + return \`Kh\\xF3a kh\\xF4ng \\u0111\\u01B0\\u1EE3c nh\\u1EADn d\\u1EA1ng: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`Kh\\xF3a kh\\xF4ng h\\u1EE3p l\\u1EC7 trong \${issue2.origin}\`; + case "invalid_union": + return "\\u0110\\u1EA7u v\\xE0o kh\\xF4ng h\\u1EE3p l\\u1EC7"; + case "invalid_element": + return \`Gi\\xE1 tr\\u1ECB kh\\xF4ng h\\u1EE3p l\\u1EC7 trong \${issue2.origin}\`; + default: + return \`\\u0110\\u1EA7u v\\xE0o kh\\xF4ng h\\u1EE3p l\\u1EC7\`; + } + }; +}, "error"); +function vi_default() { + return { + localeError: error41() + }; +} +__name(vi_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/zh-CN.js +var error42 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "\\u5B57\\u7B26", + verb: "\\u5305\\u542B" + }, + file: { + unit: "\\u5B57\\u8282", + verb: "\\u5305\\u542B" + }, + array: { + unit: "\\u9879", + verb: "\\u5305\\u542B" + }, + set: { + unit: "\\u9879", + verb: "\\u5305\\u542B" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "\\u975E\\u6570\\u5B57(NaN)" : "\\u6570\\u5B57"; + } + case "object": { + if (Array.isArray(data)) { + return "\\u6570\\u7EC4"; + } + if (data === null) { + return "\\u7A7A\\u503C(null)"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "\\u8F93\\u5165", + email: "\\u7535\\u5B50\\u90AE\\u4EF6", + url: "URL", + emoji: "\\u8868\\u60C5\\u7B26\\u53F7", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "ISO\\u65E5\\u671F\\u65F6\\u95F4", + date: "ISO\\u65E5\\u671F", + time: "ISO\\u65F6\\u95F4", + duration: "ISO\\u65F6\\u957F", + ipv4: "IPv4\\u5730\\u5740", + ipv6: "IPv6\\u5730\\u5740", + cidrv4: "IPv4\\u7F51\\u6BB5", + cidrv6: "IPv6\\u7F51\\u6BB5", + base64: "base64\\u7F16\\u7801\\u5B57\\u7B26\\u4E32", + base64url: "base64url\\u7F16\\u7801\\u5B57\\u7B26\\u4E32", + json_string: "JSON\\u5B57\\u7B26\\u4E32", + e164: "E.164\\u53F7\\u7801", + jwt: "JWT", + template_literal: "\\u8F93\\u5165" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`\\u65E0\\u6548\\u8F93\\u5165\\uFF1A\\u671F\\u671B \${issue2.expected}\\uFF0C\\u5B9E\\u9645\\u63A5\\u6536 \${parsedType7(issue2.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`\\u65E0\\u6548\\u8F93\\u5165\\uFF1A\\u671F\\u671B \${stringifyPrimitive(issue2.values[0])}\`; + return \`\\u65E0\\u6548\\u9009\\u9879\\uFF1A\\u671F\\u671B\\u4EE5\\u4E0B\\u4E4B\\u4E00 \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`\\u6570\\u503C\\u8FC7\\u5927\\uFF1A\\u671F\\u671B \${issue2.origin ?? "\\u503C"} \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "\\u4E2A\\u5143\\u7D20"}\`; + return \`\\u6570\\u503C\\u8FC7\\u5927\\uFF1A\\u671F\\u671B \${issue2.origin ?? "\\u503C"} \${adj}\${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`\\u6570\\u503C\\u8FC7\\u5C0F\\uFF1A\\u671F\\u671B \${issue2.origin} \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; + } + return \`\\u6570\\u503C\\u8FC7\\u5C0F\\uFF1A\\u671F\\u671B \${issue2.origin} \${adj}\${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") return \`\\u65E0\\u6548\\u5B57\\u7B26\\u4E32\\uFF1A\\u5FC5\\u987B\\u4EE5 "\${_issue.prefix}" \\u5F00\\u5934\`; + if (_issue.format === "ends_with") return \`\\u65E0\\u6548\\u5B57\\u7B26\\u4E32\\uFF1A\\u5FC5\\u987B\\u4EE5 "\${_issue.suffix}" \\u7ED3\\u5C3E\`; + if (_issue.format === "includes") return \`\\u65E0\\u6548\\u5B57\\u7B26\\u4E32\\uFF1A\\u5FC5\\u987B\\u5305\\u542B "\${_issue.includes}"\`; + if (_issue.format === "regex") return \`\\u65E0\\u6548\\u5B57\\u7B26\\u4E32\\uFF1A\\u5FC5\\u987B\\u6EE1\\u8DB3\\u6B63\\u5219\\u8868\\u8FBE\\u5F0F \${_issue.pattern}\`; + return \`\\u65E0\\u6548\${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`\\u65E0\\u6548\\u6570\\u5B57\\uFF1A\\u5FC5\\u987B\\u662F \${issue2.divisor} \\u7684\\u500D\\u6570\`; + case "unrecognized_keys": + return \`\\u51FA\\u73B0\\u672A\\u77E5\\u7684\\u952E(key): \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`\${issue2.origin} \\u4E2D\\u7684\\u952E(key)\\u65E0\\u6548\`; + case "invalid_union": + return "\\u65E0\\u6548\\u8F93\\u5165"; + case "invalid_element": + return \`\${issue2.origin} \\u4E2D\\u5305\\u542B\\u65E0\\u6548\\u503C(value)\`; + default: + return \`\\u65E0\\u6548\\u8F93\\u5165\`; + } + }; +}, "error"); +function zh_CN_default() { + return { + localeError: error42() + }; +} +__name(zh_CN_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/zh-TW.js +var error43 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "\\u5B57\\u5143", + verb: "\\u64C1\\u6709" + }, + file: { + unit: "\\u4F4D\\u5143\\u7D44", + verb: "\\u64C1\\u6709" + }, + array: { + unit: "\\u9805\\u76EE", + verb: "\\u64C1\\u6709" + }, + set: { + unit: "\\u9805\\u76EE", + verb: "\\u64C1\\u6709" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "number"; + } + case "object": { + if (Array.isArray(data)) { + return "array"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "\\u8F38\\u5165", + email: "\\u90F5\\u4EF6\\u5730\\u5740", + url: "URL", + emoji: "emoji", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "ISO \\u65E5\\u671F\\u6642\\u9593", + date: "ISO \\u65E5\\u671F", + time: "ISO \\u6642\\u9593", + duration: "ISO \\u671F\\u9593", + ipv4: "IPv4 \\u4F4D\\u5740", + ipv6: "IPv6 \\u4F4D\\u5740", + cidrv4: "IPv4 \\u7BC4\\u570D", + cidrv6: "IPv6 \\u7BC4\\u570D", + base64: "base64 \\u7DE8\\u78BC\\u5B57\\u4E32", + base64url: "base64url \\u7DE8\\u78BC\\u5B57\\u4E32", + json_string: "JSON \\u5B57\\u4E32", + e164: "E.164 \\u6578\\u503C", + jwt: "JWT", + template_literal: "\\u8F38\\u5165" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`\\u7121\\u6548\\u7684\\u8F38\\u5165\\u503C\\uFF1A\\u9810\\u671F\\u70BA \${issue2.expected}\\uFF0C\\u4F46\\u6536\\u5230 \${parsedType7(issue2.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`\\u7121\\u6548\\u7684\\u8F38\\u5165\\u503C\\uFF1A\\u9810\\u671F\\u70BA \${stringifyPrimitive(issue2.values[0])}\`; + return \`\\u7121\\u6548\\u7684\\u9078\\u9805\\uFF1A\\u9810\\u671F\\u70BA\\u4EE5\\u4E0B\\u5176\\u4E2D\\u4E4B\\u4E00 \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`\\u6578\\u503C\\u904E\\u5927\\uFF1A\\u9810\\u671F \${issue2.origin ?? "\\u503C"} \\u61C9\\u70BA \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "\\u500B\\u5143\\u7D20"}\`; + return \`\\u6578\\u503C\\u904E\\u5927\\uFF1A\\u9810\\u671F \${issue2.origin ?? "\\u503C"} \\u61C9\\u70BA \${adj}\${issue2.maximum.toString()}\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) { + return \`\\u6578\\u503C\\u904E\\u5C0F\\uFF1A\\u9810\\u671F \${issue2.origin} \\u61C9\\u70BA \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; + } + return \`\\u6578\\u503C\\u904E\\u5C0F\\uFF1A\\u9810\\u671F \${issue2.origin} \\u61C9\\u70BA \${adj}\${issue2.minimum.toString()}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") { + return \`\\u7121\\u6548\\u7684\\u5B57\\u4E32\\uFF1A\\u5FC5\\u9808\\u4EE5 "\${_issue.prefix}" \\u958B\\u982D\`; + } + if (_issue.format === "ends_with") return \`\\u7121\\u6548\\u7684\\u5B57\\u4E32\\uFF1A\\u5FC5\\u9808\\u4EE5 "\${_issue.suffix}" \\u7D50\\u5C3E\`; + if (_issue.format === "includes") return \`\\u7121\\u6548\\u7684\\u5B57\\u4E32\\uFF1A\\u5FC5\\u9808\\u5305\\u542B "\${_issue.includes}"\`; + if (_issue.format === "regex") return \`\\u7121\\u6548\\u7684\\u5B57\\u4E32\\uFF1A\\u5FC5\\u9808\\u7B26\\u5408\\u683C\\u5F0F \${_issue.pattern}\`; + return \`\\u7121\\u6548\\u7684 \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`\\u7121\\u6548\\u7684\\u6578\\u5B57\\uFF1A\\u5FC5\\u9808\\u70BA \${issue2.divisor} \\u7684\\u500D\\u6578\`; + case "unrecognized_keys": + return \`\\u7121\\u6CD5\\u8B58\\u5225\\u7684\\u9375\\u503C\${issue2.keys.length > 1 ? "\\u5011" : ""}\\uFF1A\${joinValues(issue2.keys, "\\u3001")}\`; + case "invalid_key": + return \`\${issue2.origin} \\u4E2D\\u6709\\u7121\\u6548\\u7684\\u9375\\u503C\`; + case "invalid_union": + return "\\u7121\\u6548\\u7684\\u8F38\\u5165\\u503C"; + case "invalid_element": + return \`\${issue2.origin} \\u4E2D\\u6709\\u7121\\u6548\\u7684\\u503C\`; + default: + return \`\\u7121\\u6548\\u7684\\u8F38\\u5165\\u503C\`; + } + }; +}, "error"); +function zh_TW_default() { + return { + localeError: error43() + }; +} +__name(zh_TW_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/yo.js +var error44 = /* @__PURE__ */ __name(() => { + const Sizable = { + string: { + unit: "\\xE0mi", + verb: "n\\xED" + }, + file: { + unit: "bytes", + verb: "n\\xED" + }, + array: { + unit: "nkan", + verb: "n\\xED" + }, + set: { + unit: "nkan", + verb: "n\\xED" + } + }; + function getSizing(origin) { + return Sizable[origin] ?? null; + } + __name(getSizing, "getSizing"); + const parsedType7 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "number": { + return Number.isNaN(data) ? "NaN" : "n\\u1ECD\\u0301mb\\xE0"; + } + case "object": { + if (Array.isArray(data)) { + return "akop\\u1ECD"; + } + if (data === null) { + return "null"; + } + if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { + return data.constructor.name; + } + } + } + return t; + }, "parsedType"); + const Nouns = { + regex: "\\u1EB9\\u0300r\\u1ECD \\xECb\\xE1w\\u1ECDl\\xE9", + email: "\\xE0d\\xEDr\\u1EB9\\u0301s\\xEC \\xECm\\u1EB9\\u0301l\\xEC", + url: "URL", + emoji: "emoji", + uuid: "UUID", + uuidv4: "UUIDv4", + uuidv6: "UUIDv6", + nanoid: "nanoid", + guid: "GUID", + cuid: "cuid", + cuid2: "cuid2", + ulid: "ULID", + xid: "XID", + ksuid: "KSUID", + datetime: "\\xE0k\\xF3k\\xF2 ISO", + date: "\\u1ECDj\\u1ECD\\u0301 ISO", + time: "\\xE0k\\xF3k\\xF2 ISO", + duration: "\\xE0k\\xF3k\\xF2 t\\xF3 p\\xE9 ISO", + ipv4: "\\xE0d\\xEDr\\u1EB9\\u0301s\\xEC IPv4", + ipv6: "\\xE0d\\xEDr\\u1EB9\\u0301s\\xEC IPv6", + cidrv4: "\\xE0gb\\xE8gb\\xE8 IPv4", + cidrv6: "\\xE0gb\\xE8gb\\xE8 IPv6", + base64: "\\u1ECD\\u0300r\\u1ECD\\u0300 t\\xED a k\\u1ECD\\u0301 n\\xED base64", + base64url: "\\u1ECD\\u0300r\\u1ECD\\u0300 base64url", + json_string: "\\u1ECD\\u0300r\\u1ECD\\u0300 JSON", + e164: "n\\u1ECD\\u0301mb\\xE0 E.164", + jwt: "JWT", + template_literal: "\\u1EB9\\u0300r\\u1ECD \\xECb\\xE1w\\u1ECDl\\xE9" + }; + return (issue2) => { + switch (issue2.code) { + case "invalid_type": + return \`\\xCCb\\xE1w\\u1ECDl\\xE9 a\\u1E63\\xEC\\u1E63e: a n\\xED l\\xE1ti fi \${issue2.expected}, \\xE0m\\u1ECD\\u0300 a r\\xED \${parsedType7(issue2.input)}\`; + case "invalid_value": + if (issue2.values.length === 1) return \`\\xCCb\\xE1w\\u1ECDl\\xE9 a\\u1E63\\xEC\\u1E63e: a n\\xED l\\xE1ti fi \${stringifyPrimitive(issue2.values[0])}\`; + return \`\\xC0\\u1E63\\xE0y\\xE0n a\\u1E63\\xEC\\u1E63e: yan \\u1ECD\\u0300kan l\\xE1ra \${joinValues(issue2.values, "|")}\`; + case "too_big": { + const adj = issue2.inclusive ? "<=" : "<"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`T\\xF3 p\\u1ECD\\u0300 j\\xF9: a n\\xED l\\xE1ti j\\u1EB9\\u0301 p\\xE9 \${issue2.origin ?? "iye"} \${sizing.verb} \${adj}\${issue2.maximum} \${sizing.unit}\`; + return \`T\\xF3 p\\u1ECD\\u0300 j\\xF9: a n\\xED l\\xE1ti j\\u1EB9\\u0301 \${adj}\${issue2.maximum}\`; + } + case "too_small": { + const adj = issue2.inclusive ? ">=" : ">"; + const sizing = getSizing(issue2.origin); + if (sizing) return \`K\\xE9r\\xE9 ju: a n\\xED l\\xE1ti j\\u1EB9\\u0301 p\\xE9 \${issue2.origin} \${sizing.verb} \${adj}\${issue2.minimum} \${sizing.unit}\`; + return \`K\\xE9r\\xE9 ju: a n\\xED l\\xE1ti j\\u1EB9\\u0301 \${adj}\${issue2.minimum}\`; + } + case "invalid_format": { + const _issue = issue2; + if (_issue.format === "starts_with") return \`\\u1ECC\\u0300r\\u1ECD\\u0300 a\\u1E63\\xEC\\u1E63e: gb\\u1ECD\\u0301d\\u1ECD\\u0300 b\\u1EB9\\u0300r\\u1EB9\\u0300 p\\u1EB9\\u0300l\\xFA "\${_issue.prefix}"\`; + if (_issue.format === "ends_with") return \`\\u1ECC\\u0300r\\u1ECD\\u0300 a\\u1E63\\xEC\\u1E63e: gb\\u1ECD\\u0301d\\u1ECD\\u0300 par\\xED p\\u1EB9\\u0300l\\xFA "\${_issue.suffix}"\`; + if (_issue.format === "includes") return \`\\u1ECC\\u0300r\\u1ECD\\u0300 a\\u1E63\\xEC\\u1E63e: gb\\u1ECD\\u0301d\\u1ECD\\u0300 n\\xED "\${_issue.includes}"\`; + if (_issue.format === "regex") return \`\\u1ECC\\u0300r\\u1ECD\\u0300 a\\u1E63\\xEC\\u1E63e: gb\\u1ECD\\u0301d\\u1ECD\\u0300 b\\xE1 \\xE0p\\u1EB9\\u1EB9r\\u1EB9 mu \${_issue.pattern}\`; + return \`A\\u1E63\\xEC\\u1E63e: \${Nouns[_issue.format] ?? issue2.format}\`; + } + case "not_multiple_of": + return \`N\\u1ECD\\u0301mb\\xE0 a\\u1E63\\xEC\\u1E63e: gb\\u1ECD\\u0301d\\u1ECD\\u0300 j\\u1EB9\\u0301 \\xE8y\\xE0 p\\xEDp\\xEDn ti \${issue2.divisor}\`; + case "unrecognized_keys": + return \`B\\u1ECDt\\xECn\\xEC \\xE0\\xECm\\u1ECD\\u0300: \${joinValues(issue2.keys, ", ")}\`; + case "invalid_key": + return \`B\\u1ECDt\\xECn\\xEC a\\u1E63\\xEC\\u1E63e n\\xEDn\\xFA \${issue2.origin}\`; + case "invalid_union": + return "\\xCCb\\xE1w\\u1ECDl\\xE9 a\\u1E63\\xEC\\u1E63e"; + case "invalid_element": + return \`Iye a\\u1E63\\xEC\\u1E63e n\\xEDn\\xFA \${issue2.origin}\`; + default: + return "\\xCCb\\xE1w\\u1ECDl\\xE9 a\\u1E63\\xEC\\u1E63e"; + } + }; +}, "error"); +function yo_default() { + return { + localeError: error44() + }; +} +__name(yo_default, "default"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/core/registries.js +var \$output = Symbol("ZodOutput"); +var \$input = Symbol("ZodInput"); +var \$ZodRegistry = class { + static { + __name(this, "\$ZodRegistry"); + } + constructor() { + this._map = /* @__PURE__ */ new WeakMap(); + this._idmap = /* @__PURE__ */ new Map(); + } + add(schema, ..._meta) { + const meta = _meta[0]; + this._map.set(schema, meta); + if (meta && typeof meta === "object" && "id" in meta) { + if (this._idmap.has(meta.id)) { + throw new Error(\`ID \${meta.id} already exists in the registry\`); + } + this._idmap.set(meta.id, schema); + } + return this; + } + clear() { + this._map = /* @__PURE__ */ new WeakMap(); + this._idmap = /* @__PURE__ */ new Map(); + return this; + } + remove(schema) { + const meta = this._map.get(schema); + if (meta && typeof meta === "object" && "id" in meta) { + this._idmap.delete(meta.id); + } + this._map.delete(schema); + return this; + } + get(schema) { + const p = schema._zod.parent; + if (p) { + const pm = { + ...this.get(p) ?? {} + }; + delete pm.id; + const f = { + ...pm, + ...this._map.get(schema) + }; + return Object.keys(f).length ? f : void 0; + } + return this._map.get(schema); + } + has(schema) { + return this._map.has(schema); + } +}; +function registry() { + return new \$ZodRegistry(); +} +__name(registry, "registry"); +var globalRegistry = /* @__PURE__ */ registry(); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/core/api.js +function _string(Class2, params) { + return new Class2({ + type: "string", + ...normalizeParams(params) + }); +} +__name(_string, "_string"); +function _coercedString(Class2, params) { + return new Class2({ + type: "string", + coerce: true, + ...normalizeParams(params) + }); +} +__name(_coercedString, "_coercedString"); +function _email(Class2, params) { + return new Class2({ + type: "string", + format: "email", + check: "string_format", + abort: false, + ...normalizeParams(params) + }); +} +__name(_email, "_email"); +function _guid(Class2, params) { + return new Class2({ + type: "string", + format: "guid", + check: "string_format", + abort: false, + ...normalizeParams(params) + }); +} +__name(_guid, "_guid"); +function _uuid(Class2, params) { + return new Class2({ + type: "string", + format: "uuid", + check: "string_format", + abort: false, + ...normalizeParams(params) + }); +} +__name(_uuid, "_uuid"); +function _uuidv4(Class2, params) { + return new Class2({ + type: "string", + format: "uuid", + check: "string_format", + abort: false, + version: "v4", + ...normalizeParams(params) + }); +} +__name(_uuidv4, "_uuidv4"); +function _uuidv6(Class2, params) { + return new Class2({ + type: "string", + format: "uuid", + check: "string_format", + abort: false, + version: "v6", + ...normalizeParams(params) + }); +} +__name(_uuidv6, "_uuidv6"); +function _uuidv7(Class2, params) { + return new Class2({ + type: "string", + format: "uuid", + check: "string_format", + abort: false, + version: "v7", + ...normalizeParams(params) + }); +} +__name(_uuidv7, "_uuidv7"); +function _url(Class2, params) { + return new Class2({ + type: "string", + format: "url", + check: "string_format", + abort: false, + ...normalizeParams(params) + }); +} +__name(_url, "_url"); +function _emoji2(Class2, params) { + return new Class2({ + type: "string", + format: "emoji", + check: "string_format", + abort: false, + ...normalizeParams(params) + }); +} +__name(_emoji2, "_emoji"); +function _nanoid(Class2, params) { + return new Class2({ + type: "string", + format: "nanoid", + check: "string_format", + abort: false, + ...normalizeParams(params) + }); +} +__name(_nanoid, "_nanoid"); +function _cuid(Class2, params) { + return new Class2({ + type: "string", + format: "cuid", + check: "string_format", + abort: false, + ...normalizeParams(params) + }); +} +__name(_cuid, "_cuid"); +function _cuid2(Class2, params) { + return new Class2({ + type: "string", + format: "cuid2", + check: "string_format", + abort: false, + ...normalizeParams(params) + }); +} +__name(_cuid2, "_cuid2"); +function _ulid(Class2, params) { + return new Class2({ + type: "string", + format: "ulid", + check: "string_format", + abort: false, + ...normalizeParams(params) + }); +} +__name(_ulid, "_ulid"); +function _xid(Class2, params) { + return new Class2({ + type: "string", + format: "xid", + check: "string_format", + abort: false, + ...normalizeParams(params) + }); +} +__name(_xid, "_xid"); +function _ksuid(Class2, params) { + return new Class2({ + type: "string", + format: "ksuid", + check: "string_format", + abort: false, + ...normalizeParams(params) + }); +} +__name(_ksuid, "_ksuid"); +function _ipv4(Class2, params) { + return new Class2({ + type: "string", + format: "ipv4", + check: "string_format", + abort: false, + ...normalizeParams(params) + }); +} +__name(_ipv4, "_ipv4"); +function _ipv6(Class2, params) { + return new Class2({ + type: "string", + format: "ipv6", + check: "string_format", + abort: false, + ...normalizeParams(params) + }); +} +__name(_ipv6, "_ipv6"); +function _cidrv4(Class2, params) { + return new Class2({ + type: "string", + format: "cidrv4", + check: "string_format", + abort: false, + ...normalizeParams(params) + }); +} +__name(_cidrv4, "_cidrv4"); +function _cidrv6(Class2, params) { + return new Class2({ + type: "string", + format: "cidrv6", + check: "string_format", + abort: false, + ...normalizeParams(params) + }); +} +__name(_cidrv6, "_cidrv6"); +function _base64(Class2, params) { + return new Class2({ + type: "string", + format: "base64", + check: "string_format", + abort: false, + ...normalizeParams(params) + }); +} +__name(_base64, "_base64"); +function _base64url(Class2, params) { + return new Class2({ + type: "string", + format: "base64url", + check: "string_format", + abort: false, + ...normalizeParams(params) + }); +} +__name(_base64url, "_base64url"); +function _e164(Class2, params) { + return new Class2({ + type: "string", + format: "e164", + check: "string_format", + abort: false, + ...normalizeParams(params) + }); +} +__name(_e164, "_e164"); +function _jwt(Class2, params) { + return new Class2({ + type: "string", + format: "jwt", + check: "string_format", + abort: false, + ...normalizeParams(params) + }); +} +__name(_jwt, "_jwt"); +var TimePrecision = { + Any: null, + Minute: -1, + Second: 0, + Millisecond: 3, + Microsecond: 6 +}; +function _isoDateTime(Class2, params) { + return new Class2({ + type: "string", + format: "datetime", + check: "string_format", + offset: false, + local: false, + precision: null, + ...normalizeParams(params) + }); +} +__name(_isoDateTime, "_isoDateTime"); +function _isoDate(Class2, params) { + return new Class2({ + type: "string", + format: "date", + check: "string_format", + ...normalizeParams(params) + }); +} +__name(_isoDate, "_isoDate"); +function _isoTime(Class2, params) { + return new Class2({ + type: "string", + format: "time", + check: "string_format", + precision: null, + ...normalizeParams(params) + }); +} +__name(_isoTime, "_isoTime"); +function _isoDuration(Class2, params) { + return new Class2({ + type: "string", + format: "duration", + check: "string_format", + ...normalizeParams(params) + }); +} +__name(_isoDuration, "_isoDuration"); +function _number(Class2, params) { + return new Class2({ + type: "number", + checks: [], + ...normalizeParams(params) + }); +} +__name(_number, "_number"); +function _coercedNumber(Class2, params) { + return new Class2({ + type: "number", + coerce: true, + checks: [], + ...normalizeParams(params) + }); +} +__name(_coercedNumber, "_coercedNumber"); +function _int(Class2, params) { + return new Class2({ + type: "number", + check: "number_format", + abort: false, + format: "safeint", + ...normalizeParams(params) + }); +} +__name(_int, "_int"); +function _float32(Class2, params) { + return new Class2({ + type: "number", + check: "number_format", + abort: false, + format: "float32", + ...normalizeParams(params) + }); +} +__name(_float32, "_float32"); +function _float64(Class2, params) { + return new Class2({ + type: "number", + check: "number_format", + abort: false, + format: "float64", + ...normalizeParams(params) + }); +} +__name(_float64, "_float64"); +function _int32(Class2, params) { + return new Class2({ + type: "number", + check: "number_format", + abort: false, + format: "int32", + ...normalizeParams(params) + }); +} +__name(_int32, "_int32"); +function _uint32(Class2, params) { + return new Class2({ + type: "number", + check: "number_format", + abort: false, + format: "uint32", + ...normalizeParams(params) + }); +} +__name(_uint32, "_uint32"); +function _boolean(Class2, params) { + return new Class2({ + type: "boolean", + ...normalizeParams(params) + }); +} +__name(_boolean, "_boolean"); +function _coercedBoolean(Class2, params) { + return new Class2({ + type: "boolean", + coerce: true, + ...normalizeParams(params) + }); +} +__name(_coercedBoolean, "_coercedBoolean"); +function _bigint(Class2, params) { + return new Class2({ + type: "bigint", + ...normalizeParams(params) + }); +} +__name(_bigint, "_bigint"); +function _coercedBigint(Class2, params) { + return new Class2({ + type: "bigint", + coerce: true, + ...normalizeParams(params) + }); +} +__name(_coercedBigint, "_coercedBigint"); +function _int64(Class2, params) { + return new Class2({ + type: "bigint", + check: "bigint_format", + abort: false, + format: "int64", + ...normalizeParams(params) + }); +} +__name(_int64, "_int64"); +function _uint64(Class2, params) { + return new Class2({ + type: "bigint", + check: "bigint_format", + abort: false, + format: "uint64", + ...normalizeParams(params) + }); +} +__name(_uint64, "_uint64"); +function _symbol(Class2, params) { + return new Class2({ + type: "symbol", + ...normalizeParams(params) + }); +} +__name(_symbol, "_symbol"); +function _undefined2(Class2, params) { + return new Class2({ + type: "undefined", + ...normalizeParams(params) + }); +} +__name(_undefined2, "_undefined"); +function _null2(Class2, params) { + return new Class2({ + type: "null", + ...normalizeParams(params) + }); +} +__name(_null2, "_null"); +function _any(Class2) { + return new Class2({ + type: "any" + }); +} +__name(_any, "_any"); +function _unknown(Class2) { + return new Class2({ + type: "unknown" + }); +} +__name(_unknown, "_unknown"); +function _never(Class2, params) { + return new Class2({ + type: "never", + ...normalizeParams(params) + }); +} +__name(_never, "_never"); +function _void(Class2, params) { + return new Class2({ + type: "void", + ...normalizeParams(params) + }); +} +__name(_void, "_void"); +function _date(Class2, params) { + return new Class2({ + type: "date", + ...normalizeParams(params) + }); +} +__name(_date, "_date"); +function _coercedDate(Class2, params) { + return new Class2({ + type: "date", + coerce: true, + ...normalizeParams(params) + }); +} +__name(_coercedDate, "_coercedDate"); +function _nan(Class2, params) { + return new Class2({ + type: "nan", + ...normalizeParams(params) + }); +} +__name(_nan, "_nan"); +function _lt(value, params) { + return new \$ZodCheckLessThan({ + check: "less_than", + ...normalizeParams(params), + value, + inclusive: false + }); +} +__name(_lt, "_lt"); +function _lte(value, params) { + return new \$ZodCheckLessThan({ + check: "less_than", + ...normalizeParams(params), + value, + inclusive: true + }); +} +__name(_lte, "_lte"); +function _gt(value, params) { + return new \$ZodCheckGreaterThan({ + check: "greater_than", + ...normalizeParams(params), + value, + inclusive: false + }); +} +__name(_gt, "_gt"); +function _gte(value, params) { + return new \$ZodCheckGreaterThan({ + check: "greater_than", + ...normalizeParams(params), + value, + inclusive: true + }); +} +__name(_gte, "_gte"); +function _positive(params) { + return _gt(0, params); +} +__name(_positive, "_positive"); +function _negative(params) { + return _lt(0, params); +} +__name(_negative, "_negative"); +function _nonpositive(params) { + return _lte(0, params); +} +__name(_nonpositive, "_nonpositive"); +function _nonnegative(params) { + return _gte(0, params); +} +__name(_nonnegative, "_nonnegative"); +function _multipleOf(value, params) { + return new \$ZodCheckMultipleOf({ + check: "multiple_of", + ...normalizeParams(params), + value + }); +} +__name(_multipleOf, "_multipleOf"); +function _maxSize(maximum, params) { + return new \$ZodCheckMaxSize({ + check: "max_size", + ...normalizeParams(params), + maximum + }); +} +__name(_maxSize, "_maxSize"); +function _minSize(minimum, params) { + return new \$ZodCheckMinSize({ + check: "min_size", + ...normalizeParams(params), + minimum + }); +} +__name(_minSize, "_minSize"); +function _size(size, params) { + return new \$ZodCheckSizeEquals({ + check: "size_equals", + ...normalizeParams(params), + size + }); +} +__name(_size, "_size"); +function _maxLength(maximum, params) { + const ch = new \$ZodCheckMaxLength({ + check: "max_length", + ...normalizeParams(params), + maximum + }); + return ch; +} +__name(_maxLength, "_maxLength"); +function _minLength(minimum, params) { + return new \$ZodCheckMinLength({ + check: "min_length", + ...normalizeParams(params), + minimum + }); +} +__name(_minLength, "_minLength"); +function _length(length, params) { + return new \$ZodCheckLengthEquals({ + check: "length_equals", + ...normalizeParams(params), + length + }); +} +__name(_length, "_length"); +function _regex(pattern, params) { + return new \$ZodCheckRegex({ + check: "string_format", + format: "regex", + ...normalizeParams(params), + pattern + }); +} +__name(_regex, "_regex"); +function _lowercase(params) { + return new \$ZodCheckLowerCase({ + check: "string_format", + format: "lowercase", + ...normalizeParams(params) + }); +} +__name(_lowercase, "_lowercase"); +function _uppercase(params) { + return new \$ZodCheckUpperCase({ + check: "string_format", + format: "uppercase", + ...normalizeParams(params) + }); +} +__name(_uppercase, "_uppercase"); +function _includes(includes, params) { + return new \$ZodCheckIncludes({ + check: "string_format", + format: "includes", + ...normalizeParams(params), + includes + }); +} +__name(_includes, "_includes"); +function _startsWith(prefix, params) { + return new \$ZodCheckStartsWith({ + check: "string_format", + format: "starts_with", + ...normalizeParams(params), + prefix + }); +} +__name(_startsWith, "_startsWith"); +function _endsWith(suffix, params) { + return new \$ZodCheckEndsWith({ + check: "string_format", + format: "ends_with", + ...normalizeParams(params), + suffix + }); +} +__name(_endsWith, "_endsWith"); +function _property(property, schema, params) { + return new \$ZodCheckProperty({ + check: "property", + property, + schema, + ...normalizeParams(params) + }); +} +__name(_property, "_property"); +function _mime(types, params) { + return new \$ZodCheckMimeType({ + check: "mime_type", + mime: types, + ...normalizeParams(params) + }); +} +__name(_mime, "_mime"); +function _overwrite(tx) { + return new \$ZodCheckOverwrite({ + check: "overwrite", + tx + }); +} +__name(_overwrite, "_overwrite"); +function _normalize(form) { + return _overwrite((input) => input.normalize(form)); +} +__name(_normalize, "_normalize"); +function _trim() { + return _overwrite((input) => input.trim()); +} +__name(_trim, "_trim"); +function _toLowerCase() { + return _overwrite((input) => input.toLowerCase()); +} +__name(_toLowerCase, "_toLowerCase"); +function _toUpperCase() { + return _overwrite((input) => input.toUpperCase()); +} +__name(_toUpperCase, "_toUpperCase"); +function _array(Class2, element, params) { + return new Class2({ + type: "array", + element, + // get element() { + // return element; + // }, + ...normalizeParams(params) + }); +} +__name(_array, "_array"); +function _union(Class2, options, params) { + return new Class2({ + type: "union", + options, + ...normalizeParams(params) + }); +} +__name(_union, "_union"); +function _discriminatedUnion(Class2, discriminator, options, params) { + return new Class2({ + type: "union", + options, + discriminator, + ...normalizeParams(params) + }); +} +__name(_discriminatedUnion, "_discriminatedUnion"); +function _intersection(Class2, left, right) { + return new Class2({ + type: "intersection", + left, + right + }); +} +__name(_intersection, "_intersection"); +function _tuple(Class2, items, _paramsOrRest, _params) { + const hasRest = _paramsOrRest instanceof \$ZodType; + const params = hasRest ? _params : _paramsOrRest; + const rest = hasRest ? _paramsOrRest : null; + return new Class2({ + type: "tuple", + items, + rest, + ...normalizeParams(params) + }); +} +__name(_tuple, "_tuple"); +function _record(Class2, keyType, valueType, params) { + return new Class2({ + type: "record", + keyType, + valueType, + ...normalizeParams(params) + }); +} +__name(_record, "_record"); +function _map(Class2, keyType, valueType, params) { + return new Class2({ + type: "map", + keyType, + valueType, + ...normalizeParams(params) + }); +} +__name(_map, "_map"); +function _set(Class2, valueType, params) { + return new Class2({ + type: "set", + valueType, + ...normalizeParams(params) + }); +} +__name(_set, "_set"); +function _enum(Class2, values, params) { + const entries = Array.isArray(values) ? Object.fromEntries(values.map((v) => [ + v, + v + ])) : values; + return new Class2({ + type: "enum", + entries, + ...normalizeParams(params) + }); +} +__name(_enum, "_enum"); +function _nativeEnum(Class2, entries, params) { + return new Class2({ + type: "enum", + entries, + ...normalizeParams(params) + }); +} +__name(_nativeEnum, "_nativeEnum"); +function _literal(Class2, value, params) { + return new Class2({ + type: "literal", + values: Array.isArray(value) ? value : [ + value + ], + ...normalizeParams(params) + }); +} +__name(_literal, "_literal"); +function _file(Class2, params) { + return new Class2({ + type: "file", + ...normalizeParams(params) + }); +} +__name(_file, "_file"); +function _transform(Class2, fn) { + return new Class2({ + type: "transform", + transform: fn + }); +} +__name(_transform, "_transform"); +function _optional(Class2, innerType) { + return new Class2({ + type: "optional", + innerType + }); +} +__name(_optional, "_optional"); +function _nullable(Class2, innerType) { + return new Class2({ + type: "nullable", + innerType + }); +} +__name(_nullable, "_nullable"); +function _default(Class2, innerType, defaultValue) { + return new Class2({ + type: "default", + innerType, + get defaultValue() { + return typeof defaultValue === "function" ? defaultValue() : shallowClone(defaultValue); + } + }); +} +__name(_default, "_default"); +function _nonoptional(Class2, innerType, params) { + return new Class2({ + type: "nonoptional", + innerType, + ...normalizeParams(params) + }); +} +__name(_nonoptional, "_nonoptional"); +function _success(Class2, innerType) { + return new Class2({ + type: "success", + innerType + }); +} +__name(_success, "_success"); +function _catch(Class2, innerType, catchValue) { + return new Class2({ + type: "catch", + innerType, + catchValue: typeof catchValue === "function" ? catchValue : () => catchValue + }); +} +__name(_catch, "_catch"); +function _pipe(Class2, in_, out) { + return new Class2({ + type: "pipe", + in: in_, + out + }); +} +__name(_pipe, "_pipe"); +function _readonly(Class2, innerType) { + return new Class2({ + type: "readonly", + innerType + }); +} +__name(_readonly, "_readonly"); +function _templateLiteral(Class2, parts, params) { + return new Class2({ + type: "template_literal", + parts, + ...normalizeParams(params) + }); +} +__name(_templateLiteral, "_templateLiteral"); +function _lazy(Class2, getter) { + return new Class2({ + type: "lazy", + getter + }); +} +__name(_lazy, "_lazy"); +function _promise(Class2, innerType) { + return new Class2({ + type: "promise", + innerType + }); +} +__name(_promise, "_promise"); +function _custom(Class2, fn, _params) { + const norm = normalizeParams(_params); + norm.abort ?? (norm.abort = true); + const schema = new Class2({ + type: "custom", + check: "custom", + fn, + ...norm + }); + return schema; +} +__name(_custom, "_custom"); +function _refine(Class2, fn, _params) { + const schema = new Class2({ + type: "custom", + check: "custom", + fn, + ...normalizeParams(_params) + }); + return schema; +} +__name(_refine, "_refine"); +function _superRefine(fn) { + const ch = _check((payload) => { + payload.addIssue = (issue2) => { + if (typeof issue2 === "string") { + payload.issues.push(issue(issue2, payload.value, ch._zod.def)); + } else { + const _issue = issue2; + if (_issue.fatal) _issue.continue = false; + _issue.code ?? (_issue.code = "custom"); + _issue.input ?? (_issue.input = payload.value); + _issue.inst ?? (_issue.inst = ch); + _issue.continue ?? (_issue.continue = !ch._zod.def.abort); + payload.issues.push(issue(_issue)); + } + }; + return fn(payload.value, payload); + }); + return ch; +} +__name(_superRefine, "_superRefine"); +function _check(fn, params) { + const ch = new \$ZodCheck({ + check: "custom", + ...normalizeParams(params) + }); + ch._zod.check = fn; + return ch; +} +__name(_check, "_check"); +function _stringbool(Classes, _params) { + const params = normalizeParams(_params); + let truthyArray = params.truthy ?? [ + "true", + "1", + "yes", + "on", + "y", + "enabled" + ]; + let falsyArray = params.falsy ?? [ + "false", + "0", + "no", + "off", + "n", + "disabled" + ]; + if (params.case !== "sensitive") { + truthyArray = truthyArray.map((v) => typeof v === "string" ? v.toLowerCase() : v); + falsyArray = falsyArray.map((v) => typeof v === "string" ? v.toLowerCase() : v); + } + const truthySet = new Set(truthyArray); + const falsySet = new Set(falsyArray); + const _Codec = Classes.Codec ?? \$ZodCodec; + const _Boolean = Classes.Boolean ?? \$ZodBoolean; + const _String = Classes.String ?? \$ZodString; + const stringSchema = new _String({ + type: "string", + error: params.error + }); + const booleanSchema = new _Boolean({ + type: "boolean", + error: params.error + }); + const codec2 = new _Codec({ + type: "pipe", + in: stringSchema, + out: booleanSchema, + transform: /* @__PURE__ */ __name((input, payload) => { + let data = input; + if (params.case !== "sensitive") data = data.toLowerCase(); + if (truthySet.has(data)) { + return true; + } else if (falsySet.has(data)) { + return false; + } else { + payload.issues.push({ + code: "invalid_value", + expected: "stringbool", + values: [ + ...truthySet, + ...falsySet + ], + input: payload.value, + inst: codec2, + continue: false + }); + return {}; + } + }, "transform"), + reverseTransform: /* @__PURE__ */ __name((input, _payload) => { + if (input === true) { + return truthyArray[0] || "true"; + } else { + return falsyArray[0] || "false"; + } + }, "reverseTransform"), + error: params.error + }); + return codec2; +} +__name(_stringbool, "_stringbool"); +function _stringFormat(Class2, format, fnOrRegex, _params = {}) { + const params = normalizeParams(_params); + const def = { + ...normalizeParams(_params), + check: "string_format", + type: "string", + format, + fn: typeof fnOrRegex === "function" ? fnOrRegex : (val) => fnOrRegex.test(val), + ...params + }; + if (fnOrRegex instanceof RegExp) { + def.pattern = fnOrRegex; + } + const inst = new Class2(def); + return inst; +} +__name(_stringFormat, "_stringFormat"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/core/to-json-schema.js +var JSONSchemaGenerator = class { + static { + __name(this, "JSONSchemaGenerator"); + } + constructor(params) { + this.counter = 0; + this.metadataRegistry = params?.metadata ?? globalRegistry; + this.target = params?.target ?? "draft-2020-12"; + this.unrepresentable = params?.unrepresentable ?? "throw"; + this.override = params?.override ?? (() => { + }); + this.io = params?.io ?? "output"; + this.seen = /* @__PURE__ */ new Map(); + } + process(schema, _params = { + path: [], + schemaPath: [] + }) { + var _a17; + const def = schema._zod.def; + const formatMap = { + guid: "uuid", + url: "uri", + datetime: "date-time", + json_string: "json-string", + regex: "" + }; + const seen = this.seen.get(schema); + if (seen) { + seen.count++; + const isCycle = _params.schemaPath.includes(schema); + if (isCycle) { + seen.cycle = _params.path; + } + return seen.schema; + } + const result = { + schema: {}, + count: 1, + cycle: void 0, + path: _params.path + }; + this.seen.set(schema, result); + const overrideSchema = schema._zod.toJSONSchema?.(); + if (overrideSchema) { + result.schema = overrideSchema; + } else { + const params = { + ..._params, + schemaPath: [ + ..._params.schemaPath, + schema + ], + path: _params.path + }; + const parent = schema._zod.parent; + if (parent) { + result.ref = parent; + this.process(parent, params); + this.seen.get(parent).isParent = true; + } else { + const _json = result.schema; + switch (def.type) { + case "string": { + const json2 = _json; + json2.type = "string"; + const { minimum, maximum, format, patterns, contentEncoding } = schema._zod.bag; + if (typeof minimum === "number") json2.minLength = minimum; + if (typeof maximum === "number") json2.maxLength = maximum; + if (format) { + json2.format = formatMap[format] ?? format; + if (json2.format === "") delete json2.format; + } + if (contentEncoding) json2.contentEncoding = contentEncoding; + if (patterns && patterns.size > 0) { + const regexes = [ + ...patterns + ]; + if (regexes.length === 1) json2.pattern = regexes[0].source; + else if (regexes.length > 1) { + result.schema.allOf = [ + ...regexes.map((regex) => ({ + ...this.target === "draft-7" || this.target === "draft-4" || this.target === "openapi-3.0" ? { + type: "string" + } : {}, + pattern: regex.source + })) + ]; + } + } + break; + } + case "number": { + const json2 = _json; + const { minimum, maximum, format, multipleOf, exclusiveMaximum, exclusiveMinimum } = schema._zod.bag; + if (typeof format === "string" && format.includes("int")) json2.type = "integer"; + else json2.type = "number"; + if (typeof exclusiveMinimum === "number") { + if (this.target === "draft-4" || this.target === "openapi-3.0") { + json2.minimum = exclusiveMinimum; + json2.exclusiveMinimum = true; + } else { + json2.exclusiveMinimum = exclusiveMinimum; + } + } + if (typeof minimum === "number") { + json2.minimum = minimum; + if (typeof exclusiveMinimum === "number" && this.target !== "draft-4") { + if (exclusiveMinimum >= minimum) delete json2.minimum; + else delete json2.exclusiveMinimum; + } + } + if (typeof exclusiveMaximum === "number") { + if (this.target === "draft-4" || this.target === "openapi-3.0") { + json2.maximum = exclusiveMaximum; + json2.exclusiveMaximum = true; + } else { + json2.exclusiveMaximum = exclusiveMaximum; + } + } + if (typeof maximum === "number") { + json2.maximum = maximum; + if (typeof exclusiveMaximum === "number" && this.target !== "draft-4") { + if (exclusiveMaximum <= maximum) delete json2.maximum; + else delete json2.exclusiveMaximum; + } + } + if (typeof multipleOf === "number") json2.multipleOf = multipleOf; + break; + } + case "boolean": { + const json2 = _json; + json2.type = "boolean"; + break; + } + case "bigint": { + if (this.unrepresentable === "throw") { + throw new Error("BigInt cannot be represented in JSON Schema"); + } + break; + } + case "symbol": { + if (this.unrepresentable === "throw") { + throw new Error("Symbols cannot be represented in JSON Schema"); + } + break; + } + case "null": { + if (this.target === "openapi-3.0") { + _json.type = "string"; + _json.nullable = true; + _json.enum = [ + null + ]; + } else _json.type = "null"; + break; + } + case "any": { + break; + } + case "unknown": { + break; + } + case "undefined": { + if (this.unrepresentable === "throw") { + throw new Error("Undefined cannot be represented in JSON Schema"); + } + break; + } + case "void": { + if (this.unrepresentable === "throw") { + throw new Error("Void cannot be represented in JSON Schema"); + } + break; + } + case "never": { + _json.not = {}; + break; + } + case "date": { + if (this.unrepresentable === "throw") { + throw new Error("Date cannot be represented in JSON Schema"); + } + break; + } + case "array": { + const json2 = _json; + const { minimum, maximum } = schema._zod.bag; + if (typeof minimum === "number") json2.minItems = minimum; + if (typeof maximum === "number") json2.maxItems = maximum; + json2.type = "array"; + json2.items = this.process(def.element, { + ...params, + path: [ + ...params.path, + "items" + ] + }); + break; + } + case "object": { + const json2 = _json; + json2.type = "object"; + json2.properties = {}; + const shape = def.shape; + for (const key in shape) { + json2.properties[key] = this.process(shape[key], { + ...params, + path: [ + ...params.path, + "properties", + key + ] + }); + } + const allKeys = new Set(Object.keys(shape)); + const requiredKeys = new Set([ + ...allKeys + ].filter((key) => { + const v = def.shape[key]._zod; + if (this.io === "input") { + return v.optin === void 0; + } else { + return v.optout === void 0; + } + })); + if (requiredKeys.size > 0) { + json2.required = Array.from(requiredKeys); + } + if (def.catchall?._zod.def.type === "never") { + json2.additionalProperties = false; + } else if (!def.catchall) { + if (this.io === "output") json2.additionalProperties = false; + } else if (def.catchall) { + json2.additionalProperties = this.process(def.catchall, { + ...params, + path: [ + ...params.path, + "additionalProperties" + ] + }); + } + break; + } + case "union": { + const json2 = _json; + const options = def.options.map((x, i) => this.process(x, { + ...params, + path: [ + ...params.path, + "anyOf", + i + ] + })); + json2.anyOf = options; + break; + } + case "intersection": { + const json2 = _json; + const a = this.process(def.left, { + ...params, + path: [ + ...params.path, + "allOf", + 0 + ] + }); + const b = this.process(def.right, { + ...params, + path: [ + ...params.path, + "allOf", + 1 + ] + }); + const isSimpleIntersection = /* @__PURE__ */ __name((val) => "allOf" in val && Object.keys(val).length === 1, "isSimpleIntersection"); + const allOf = [ + ...isSimpleIntersection(a) ? a.allOf : [ + a + ], + ...isSimpleIntersection(b) ? b.allOf : [ + b + ] + ]; + json2.allOf = allOf; + break; + } + case "tuple": { + const json2 = _json; + json2.type = "array"; + const prefixPath = this.target === "draft-2020-12" ? "prefixItems" : "items"; + const restPath = this.target === "draft-2020-12" ? "items" : this.target === "openapi-3.0" ? "items" : "additionalItems"; + const prefixItems = def.items.map((x, i) => this.process(x, { + ...params, + path: [ + ...params.path, + prefixPath, + i + ] + })); + const rest = def.rest ? this.process(def.rest, { + ...params, + path: [ + ...params.path, + restPath, + ...this.target === "openapi-3.0" ? [ + def.items.length + ] : [] + ] + }) : null; + if (this.target === "draft-2020-12") { + json2.prefixItems = prefixItems; + if (rest) { + json2.items = rest; + } + } else if (this.target === "openapi-3.0") { + json2.items = { + anyOf: prefixItems + }; + if (rest) { + json2.items.anyOf.push(rest); + } + json2.minItems = prefixItems.length; + if (!rest) { + json2.maxItems = prefixItems.length; + } + } else { + json2.items = prefixItems; + if (rest) { + json2.additionalItems = rest; + } + } + const { minimum, maximum } = schema._zod.bag; + if (typeof minimum === "number") json2.minItems = minimum; + if (typeof maximum === "number") json2.maxItems = maximum; + break; + } + case "record": { + const json2 = _json; + json2.type = "object"; + if (this.target === "draft-7" || this.target === "draft-2020-12") { + json2.propertyNames = this.process(def.keyType, { + ...params, + path: [ + ...params.path, + "propertyNames" + ] + }); + } + json2.additionalProperties = this.process(def.valueType, { + ...params, + path: [ + ...params.path, + "additionalProperties" + ] + }); + break; + } + case "map": { + if (this.unrepresentable === "throw") { + throw new Error("Map cannot be represented in JSON Schema"); + } + break; + } + case "set": { + if (this.unrepresentable === "throw") { + throw new Error("Set cannot be represented in JSON Schema"); + } + break; + } + case "enum": { + const json2 = _json; + const values = getEnumValues(def.entries); + if (values.every((v) => typeof v === "number")) json2.type = "number"; + if (values.every((v) => typeof v === "string")) json2.type = "string"; + json2.enum = values; + break; + } + case "literal": { + const json2 = _json; + const vals = []; + for (const val of def.values) { + if (val === void 0) { + if (this.unrepresentable === "throw") { + throw new Error("Literal \`undefined\` cannot be represented in JSON Schema"); + } else { + } + } else if (typeof val === "bigint") { + if (this.unrepresentable === "throw") { + throw new Error("BigInt literals cannot be represented in JSON Schema"); + } else { + vals.push(Number(val)); + } + } else { + vals.push(val); + } + } + if (vals.length === 0) { + } else if (vals.length === 1) { + const val = vals[0]; + json2.type = val === null ? "null" : typeof val; + if (this.target === "draft-4" || this.target === "openapi-3.0") { + json2.enum = [ + val + ]; + } else { + json2.const = val; + } + } else { + if (vals.every((v) => typeof v === "number")) json2.type = "number"; + if (vals.every((v) => typeof v === "string")) json2.type = "string"; + if (vals.every((v) => typeof v === "boolean")) json2.type = "string"; + if (vals.every((v) => v === null)) json2.type = "null"; + json2.enum = vals; + } + break; + } + case "file": { + const json2 = _json; + const file2 = { + type: "string", + format: "binary", + contentEncoding: "binary" + }; + const { minimum, maximum, mime } = schema._zod.bag; + if (minimum !== void 0) file2.minLength = minimum; + if (maximum !== void 0) file2.maxLength = maximum; + if (mime) { + if (mime.length === 1) { + file2.contentMediaType = mime[0]; + Object.assign(json2, file2); + } else { + json2.anyOf = mime.map((m) => { + const mFile = { + ...file2, + contentMediaType: m + }; + return mFile; + }); + } + } else { + Object.assign(json2, file2); + } + break; + } + case "transform": { + if (this.unrepresentable === "throw") { + throw new Error("Transforms cannot be represented in JSON Schema"); + } + break; + } + case "nullable": { + const inner = this.process(def.innerType, params); + if (this.target === "openapi-3.0") { + result.ref = def.innerType; + _json.nullable = true; + } else { + _json.anyOf = [ + inner, + { + type: "null" + } + ]; + } + break; + } + case "nonoptional": { + this.process(def.innerType, params); + result.ref = def.innerType; + break; + } + case "success": { + const json2 = _json; + json2.type = "boolean"; + break; + } + case "default": { + this.process(def.innerType, params); + result.ref = def.innerType; + _json.default = JSON.parse(JSON.stringify(def.defaultValue)); + break; + } + case "prefault": { + this.process(def.innerType, params); + result.ref = def.innerType; + if (this.io === "input") _json._prefault = JSON.parse(JSON.stringify(def.defaultValue)); + break; + } + case "catch": { + this.process(def.innerType, params); + result.ref = def.innerType; + let catchValue; + try { + catchValue = def.catchValue(void 0); + } catch { + throw new Error("Dynamic catch values are not supported in JSON Schema"); + } + _json.default = catchValue; + break; + } + case "nan": { + if (this.unrepresentable === "throw") { + throw new Error("NaN cannot be represented in JSON Schema"); + } + break; + } + case "template_literal": { + const json2 = _json; + const pattern = schema._zod.pattern; + if (!pattern) throw new Error("Pattern not found in template literal"); + json2.type = "string"; + json2.pattern = pattern.source; + break; + } + case "pipe": { + const innerType = this.io === "input" ? def.in._zod.def.type === "transform" ? def.out : def.in : def.out; + this.process(innerType, params); + result.ref = innerType; + break; + } + case "readonly": { + this.process(def.innerType, params); + result.ref = def.innerType; + _json.readOnly = true; + break; + } + // passthrough types + case "promise": { + this.process(def.innerType, params); + result.ref = def.innerType; + break; + } + case "optional": { + this.process(def.innerType, params); + result.ref = def.innerType; + break; + } + case "lazy": { + const innerType = schema._zod.innerType; + this.process(innerType, params); + result.ref = innerType; + break; + } + case "custom": { + if (this.unrepresentable === "throw") { + throw new Error("Custom types cannot be represented in JSON Schema"); + } + break; + } + case "function": { + if (this.unrepresentable === "throw") { + throw new Error("Function types cannot be represented in JSON Schema"); + } + break; + } + default: { + def; + } + } + } + } + const meta = this.metadataRegistry.get(schema); + if (meta) Object.assign(result.schema, meta); + if (this.io === "input" && isTransforming(schema)) { + delete result.schema.examples; + delete result.schema.default; + } + if (this.io === "input" && result.schema._prefault) (_a17 = result.schema).default ?? (_a17.default = result.schema._prefault); + delete result.schema._prefault; + const _result = this.seen.get(schema); + return _result.schema; + } + emit(schema, _params) { + const params = { + cycles: _params?.cycles ?? "ref", + reused: _params?.reused ?? "inline", + // unrepresentable: _params?.unrepresentable ?? "throw", + // uri: _params?.uri ?? ((id) => \`\${id}\`), + external: _params?.external ?? void 0 + }; + const root = this.seen.get(schema); + if (!root) throw new Error("Unprocessed schema. This is a bug in Zod."); + const makeURI = /* @__PURE__ */ __name((entry) => { + const defsSegment = this.target === "draft-2020-12" ? "\$defs" : "definitions"; + if (params.external) { + const externalId = params.external.registry.get(entry[0])?.id; + const uriGenerator = params.external.uri ?? ((id2) => id2); + if (externalId) { + return { + ref: uriGenerator(externalId) + }; + } + const id = entry[1].defId ?? entry[1].schema.id ?? \`schema\${this.counter++}\`; + entry[1].defId = id; + return { + defId: id, + ref: \`\${uriGenerator("__shared")}#/\${defsSegment}/\${id}\` + }; + } + if (entry[1] === root) { + return { + ref: "#" + }; + } + const uriPrefix = \`#\`; + const defUriPrefix = \`\${uriPrefix}/\${defsSegment}/\`; + const defId = entry[1].schema.id ?? \`__schema\${this.counter++}\`; + return { + defId, + ref: defUriPrefix + defId + }; + }, "makeURI"); + const extractToDef = /* @__PURE__ */ __name((entry) => { + if (entry[1].schema.\$ref) { + return; + } + const seen = entry[1]; + const { ref, defId } = makeURI(entry); + seen.def = { + ...seen.schema + }; + if (defId) seen.defId = defId; + const schema2 = seen.schema; + for (const key in schema2) { + delete schema2[key]; + } + schema2.\$ref = ref; + }, "extractToDef"); + if (params.cycles === "throw") { + for (const entry of this.seen.entries()) { + const seen = entry[1]; + if (seen.cycle) { + throw new Error(\`Cycle detected: #/\${seen.cycle?.join("/")}/ + +Set the \\\`cycles\\\` parameter to \\\`"ref"\\\` to resolve cyclical schemas with defs.\`); + } + } + } + for (const entry of this.seen.entries()) { + const seen = entry[1]; + if (schema === entry[0]) { + extractToDef(entry); + continue; + } + if (params.external) { + const ext = params.external.registry.get(entry[0])?.id; + if (schema !== entry[0] && ext) { + extractToDef(entry); + continue; + } + } + const id = this.metadataRegistry.get(entry[0])?.id; + if (id) { + extractToDef(entry); + continue; + } + if (seen.cycle) { + extractToDef(entry); + continue; + } + if (seen.count > 1) { + if (params.reused === "ref") { + extractToDef(entry); + continue; + } + } + } + const flattenRef = /* @__PURE__ */ __name((zodSchema2, params2) => { + const seen = this.seen.get(zodSchema2); + const schema2 = seen.def ?? seen.schema; + const _cached = { + ...schema2 + }; + if (seen.ref === null) { + return; + } + const ref = seen.ref; + seen.ref = null; + if (ref) { + flattenRef(ref, params2); + const refSchema = this.seen.get(ref).schema; + if (refSchema.\$ref && (params2.target === "draft-7" || params2.target === "draft-4" || params2.target === "openapi-3.0")) { + schema2.allOf = schema2.allOf ?? []; + schema2.allOf.push(refSchema); + } else { + Object.assign(schema2, refSchema); + Object.assign(schema2, _cached); + } + } + if (!seen.isParent) this.override({ + zodSchema: zodSchema2, + jsonSchema: schema2, + path: seen.path ?? [] + }); + }, "flattenRef"); + for (const entry of [ + ...this.seen.entries() + ].reverse()) { + flattenRef(entry[0], { + target: this.target + }); + } + const result = {}; + if (this.target === "draft-2020-12") { + result.\$schema = "https://json-schema.org/draft/2020-12/schema"; + } else if (this.target === "draft-7") { + result.\$schema = "http://json-schema.org/draft-07/schema#"; + } else if (this.target === "draft-4") { + result.\$schema = "http://json-schema.org/draft-04/schema#"; + } else if (this.target === "openapi-3.0") { + } else { + console.warn(\`Invalid target: \${this.target}\`); + } + if (params.external?.uri) { + const id = params.external.registry.get(schema)?.id; + if (!id) throw new Error("Schema is missing an \`id\` property"); + result.\$id = params.external.uri(id); + } + Object.assign(result, root.def); + const defs = params.external?.defs ?? {}; + for (const entry of this.seen.entries()) { + const seen = entry[1]; + if (seen.def && seen.defId) { + defs[seen.defId] = seen.def; + } + } + if (params.external) { + } else { + if (Object.keys(defs).length > 0) { + if (this.target === "draft-2020-12") { + result.\$defs = defs; + } else { + result.definitions = defs; + } + } + } + try { + return JSON.parse(JSON.stringify(result)); + } catch (_err) { + throw new Error("Error converting schema to JSON."); + } + } +}; +function toJSONSchema(input, _params) { + if (input instanceof \$ZodRegistry) { + const gen2 = new JSONSchemaGenerator(_params); + const defs = {}; + for (const entry of input._idmap.entries()) { + const [_, schema] = entry; + gen2.process(schema); + } + const schemas = {}; + const external = { + registry: input, + uri: _params?.uri, + defs + }; + for (const entry of input._idmap.entries()) { + const [key, schema] = entry; + schemas[key] = gen2.emit(schema, { + ..._params, + external + }); + } + if (Object.keys(defs).length > 0) { + const defsSegment = gen2.target === "draft-2020-12" ? "\$defs" : "definitions"; + schemas.__shared = { + [defsSegment]: defs + }; + } + return { + schemas + }; + } + const gen = new JSONSchemaGenerator(_params); + gen.process(input); + return gen.emit(input, _params); +} +__name(toJSONSchema, "toJSONSchema"); +function isTransforming(_schema, _ctx) { + const ctx = _ctx ?? { + seen: /* @__PURE__ */ new Set() + }; + if (ctx.seen.has(_schema)) return false; + ctx.seen.add(_schema); + const schema = _schema; + const def = schema._zod.def; + switch (def.type) { + case "string": + case "number": + case "bigint": + case "boolean": + case "date": + case "symbol": + case "undefined": + case "null": + case "any": + case "unknown": + case "never": + case "void": + case "literal": + case "enum": + case "nan": + case "file": + case "template_literal": + return false; + case "array": { + return isTransforming(def.element, ctx); + } + case "object": { + for (const key in def.shape) { + if (isTransforming(def.shape[key], ctx)) return true; + } + return false; + } + case "union": { + for (const option of def.options) { + if (isTransforming(option, ctx)) return true; + } + return false; + } + case "intersection": { + return isTransforming(def.left, ctx) || isTransforming(def.right, ctx); + } + case "tuple": { + for (const item of def.items) { + if (isTransforming(item, ctx)) return true; + } + if (def.rest && isTransforming(def.rest, ctx)) return true; + return false; + } + case "record": { + return isTransforming(def.keyType, ctx) || isTransforming(def.valueType, ctx); + } + case "map": { + return isTransforming(def.keyType, ctx) || isTransforming(def.valueType, ctx); + } + case "set": { + return isTransforming(def.valueType, ctx); + } + // inner types + case "promise": + case "optional": + case "nonoptional": + case "nullable": + case "readonly": + return isTransforming(def.innerType, ctx); + case "lazy": + return isTransforming(def.getter(), ctx); + case "default": { + return isTransforming(def.innerType, ctx); + } + case "prefault": { + return isTransforming(def.innerType, ctx); + } + case "custom": { + return false; + } + case "transform": { + return true; + } + case "pipe": { + return isTransforming(def.in, ctx) || isTransforming(def.out, ctx); + } + case "success": { + return false; + } + case "catch": { + return false; + } + case "function": { + return false; + } + default: + def; + } + throw new Error(\`Unknown schema type: \${def.type}\`); +} +__name(isTransforming, "isTransforming"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/core/json-schema.js +var json_schema_exports = {}; + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/classic/iso.js +var iso_exports = {}; +__export(iso_exports, { + ZodISODate: () => ZodISODate, + ZodISODateTime: () => ZodISODateTime, + ZodISODuration: () => ZodISODuration, + ZodISOTime: () => ZodISOTime, + date: () => date2, + datetime: () => datetime2, + duration: () => duration2, + time: () => time2 +}); +var ZodISODateTime = /* @__PURE__ */ \$constructor("ZodISODateTime", (inst, def) => { + \$ZodISODateTime.init(inst, def); + ZodStringFormat.init(inst, def); +}); +function datetime2(params) { + return _isoDateTime(ZodISODateTime, params); +} +__name(datetime2, "datetime"); +var ZodISODate = /* @__PURE__ */ \$constructor("ZodISODate", (inst, def) => { + \$ZodISODate.init(inst, def); + ZodStringFormat.init(inst, def); +}); +function date2(params) { + return _isoDate(ZodISODate, params); +} +__name(date2, "date"); +var ZodISOTime = /* @__PURE__ */ \$constructor("ZodISOTime", (inst, def) => { + \$ZodISOTime.init(inst, def); + ZodStringFormat.init(inst, def); +}); +function time2(params) { + return _isoTime(ZodISOTime, params); +} +__name(time2, "time"); +var ZodISODuration = /* @__PURE__ */ \$constructor("ZodISODuration", (inst, def) => { + \$ZodISODuration.init(inst, def); + ZodStringFormat.init(inst, def); +}); +function duration2(params) { + return _isoDuration(ZodISODuration, params); +} +__name(duration2, "duration"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/classic/errors.js +var initializer2 = /* @__PURE__ */ __name((inst, issues) => { + \$ZodError.init(inst, issues); + inst.name = "ZodError"; + Object.defineProperties(inst, { + format: { + value: /* @__PURE__ */ __name((mapper) => formatError(inst, mapper), "value") + }, + flatten: { + value: /* @__PURE__ */ __name((mapper) => flattenError(inst, mapper), "value") + }, + addIssue: { + value: /* @__PURE__ */ __name((issue2) => { + inst.issues.push(issue2); + inst.message = JSON.stringify(inst.issues, jsonStringifyReplacer, 2); + }, "value") + }, + addIssues: { + value: /* @__PURE__ */ __name((issues2) => { + inst.issues.push(...issues2); + inst.message = JSON.stringify(inst.issues, jsonStringifyReplacer, 2); + }, "value") + }, + isEmpty: { + get() { + return inst.issues.length === 0; + } + } + }); +}, "initializer"); +var ZodError = \$constructor("ZodError", initializer2); +var ZodRealError = \$constructor("ZodError", initializer2, { + Parent: Error +}); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/classic/parse.js +var parse2 = /* @__PURE__ */ _parse(ZodRealError); +var parseAsync2 = /* @__PURE__ */ _parseAsync(ZodRealError); +var safeParse2 = /* @__PURE__ */ _safeParse(ZodRealError); +var safeParseAsync2 = /* @__PURE__ */ _safeParseAsync(ZodRealError); +var encode2 = /* @__PURE__ */ _encode(ZodRealError); +var decode2 = /* @__PURE__ */ _decode(ZodRealError); +var encodeAsync2 = /* @__PURE__ */ _encodeAsync(ZodRealError); +var decodeAsync2 = /* @__PURE__ */ _decodeAsync(ZodRealError); +var safeEncode2 = /* @__PURE__ */ _safeEncode(ZodRealError); +var safeDecode2 = /* @__PURE__ */ _safeDecode(ZodRealError); +var safeEncodeAsync2 = /* @__PURE__ */ _safeEncodeAsync(ZodRealError); +var safeDecodeAsync2 = /* @__PURE__ */ _safeDecodeAsync(ZodRealError); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/classic/schemas.js +var ZodType = /* @__PURE__ */ \$constructor("ZodType", (inst, def) => { + \$ZodType.init(inst, def); + inst.def = def; + inst.type = def.type; + Object.defineProperty(inst, "_def", { + value: def + }); + inst.check = (...checks) => { + return inst.clone(util_exports.mergeDefs(def, { + checks: [ + ...def.checks ?? [], + ...checks.map((ch) => typeof ch === "function" ? { + _zod: { + check: ch, + def: { + check: "custom" + }, + onattach: [] + } + } : ch) + ] + })); + }; + inst.clone = (def2, params) => clone(inst, def2, params); + inst.brand = () => inst; + inst.register = (reg, meta) => { + reg.add(inst, meta); + return inst; + }; + inst.parse = (data, params) => parse2(inst, data, params, { + callee: inst.parse + }); + inst.safeParse = (data, params) => safeParse2(inst, data, params); + inst.parseAsync = async (data, params) => parseAsync2(inst, data, params, { + callee: inst.parseAsync + }); + inst.safeParseAsync = async (data, params) => safeParseAsync2(inst, data, params); + inst.spa = inst.safeParseAsync; + inst.encode = (data, params) => encode2(inst, data, params); + inst.decode = (data, params) => decode2(inst, data, params); + inst.encodeAsync = async (data, params) => encodeAsync2(inst, data, params); + inst.decodeAsync = async (data, params) => decodeAsync2(inst, data, params); + inst.safeEncode = (data, params) => safeEncode2(inst, data, params); + inst.safeDecode = (data, params) => safeDecode2(inst, data, params); + inst.safeEncodeAsync = async (data, params) => safeEncodeAsync2(inst, data, params); + inst.safeDecodeAsync = async (data, params) => safeDecodeAsync2(inst, data, params); + inst.refine = (check2, params) => inst.check(refine(check2, params)); + inst.superRefine = (refinement) => inst.check(superRefine(refinement)); + inst.overwrite = (fn) => inst.check(_overwrite(fn)); + inst.optional = () => optional(inst); + inst.nullable = () => nullable(inst); + inst.nullish = () => optional(nullable(inst)); + inst.nonoptional = (params) => nonoptional(inst, params); + inst.array = () => array(inst); + inst.or = (arg) => union([ + inst, + arg + ]); + inst.and = (arg) => intersection(inst, arg); + inst.transform = (tx) => pipe(inst, transform(tx)); + inst.default = (def2) => _default2(inst, def2); + inst.prefault = (def2) => prefault(inst, def2); + inst.catch = (params) => _catch2(inst, params); + inst.pipe = (target) => pipe(inst, target); + inst.readonly = () => readonly(inst); + inst.describe = (description) => { + const cl = inst.clone(); + globalRegistry.add(cl, { + description + }); + return cl; + }; + Object.defineProperty(inst, "description", { + get() { + return globalRegistry.get(inst)?.description; + }, + configurable: true + }); + inst.meta = (...args) => { + if (args.length === 0) { + return globalRegistry.get(inst); + } + const cl = inst.clone(); + globalRegistry.add(cl, args[0]); + return cl; + }; + inst.isOptional = () => inst.safeParse(void 0).success; + inst.isNullable = () => inst.safeParse(null).success; + return inst; +}); +var _ZodString = /* @__PURE__ */ \$constructor("_ZodString", (inst, def) => { + \$ZodString.init(inst, def); + ZodType.init(inst, def); + const bag = inst._zod.bag; + inst.format = bag.format ?? null; + inst.minLength = bag.minimum ?? null; + inst.maxLength = bag.maximum ?? null; + inst.regex = (...args) => inst.check(_regex(...args)); + inst.includes = (...args) => inst.check(_includes(...args)); + inst.startsWith = (...args) => inst.check(_startsWith(...args)); + inst.endsWith = (...args) => inst.check(_endsWith(...args)); + inst.min = (...args) => inst.check(_minLength(...args)); + inst.max = (...args) => inst.check(_maxLength(...args)); + inst.length = (...args) => inst.check(_length(...args)); + inst.nonempty = (...args) => inst.check(_minLength(1, ...args)); + inst.lowercase = (params) => inst.check(_lowercase(params)); + inst.uppercase = (params) => inst.check(_uppercase(params)); + inst.trim = () => inst.check(_trim()); + inst.normalize = (...args) => inst.check(_normalize(...args)); + inst.toLowerCase = () => inst.check(_toLowerCase()); + inst.toUpperCase = () => inst.check(_toUpperCase()); +}); +var ZodString = /* @__PURE__ */ \$constructor("ZodString", (inst, def) => { + \$ZodString.init(inst, def); + _ZodString.init(inst, def); + inst.email = (params) => inst.check(_email(ZodEmail, params)); + inst.url = (params) => inst.check(_url(ZodURL, params)); + inst.jwt = (params) => inst.check(_jwt(ZodJWT, params)); + inst.emoji = (params) => inst.check(_emoji2(ZodEmoji, params)); + inst.guid = (params) => inst.check(_guid(ZodGUID, params)); + inst.uuid = (params) => inst.check(_uuid(ZodUUID, params)); + inst.uuidv4 = (params) => inst.check(_uuidv4(ZodUUID, params)); + inst.uuidv6 = (params) => inst.check(_uuidv6(ZodUUID, params)); + inst.uuidv7 = (params) => inst.check(_uuidv7(ZodUUID, params)); + inst.nanoid = (params) => inst.check(_nanoid(ZodNanoID, params)); + inst.guid = (params) => inst.check(_guid(ZodGUID, params)); + inst.cuid = (params) => inst.check(_cuid(ZodCUID, params)); + inst.cuid2 = (params) => inst.check(_cuid2(ZodCUID2, params)); + inst.ulid = (params) => inst.check(_ulid(ZodULID, params)); + inst.base64 = (params) => inst.check(_base64(ZodBase64, params)); + inst.base64url = (params) => inst.check(_base64url(ZodBase64URL, params)); + inst.xid = (params) => inst.check(_xid(ZodXID, params)); + inst.ksuid = (params) => inst.check(_ksuid(ZodKSUID, params)); + inst.ipv4 = (params) => inst.check(_ipv4(ZodIPv4, params)); + inst.ipv6 = (params) => inst.check(_ipv6(ZodIPv6, params)); + inst.cidrv4 = (params) => inst.check(_cidrv4(ZodCIDRv4, params)); + inst.cidrv6 = (params) => inst.check(_cidrv6(ZodCIDRv6, params)); + inst.e164 = (params) => inst.check(_e164(ZodE164, params)); + inst.datetime = (params) => inst.check(datetime2(params)); + inst.date = (params) => inst.check(date2(params)); + inst.time = (params) => inst.check(time2(params)); + inst.duration = (params) => inst.check(duration2(params)); +}); +function string2(params) { + return _string(ZodString, params); +} +__name(string2, "string"); +var ZodStringFormat = /* @__PURE__ */ \$constructor("ZodStringFormat", (inst, def) => { + \$ZodStringFormat.init(inst, def); + _ZodString.init(inst, def); +}); +var ZodEmail = /* @__PURE__ */ \$constructor("ZodEmail", (inst, def) => { + \$ZodEmail.init(inst, def); + ZodStringFormat.init(inst, def); +}); +function email2(params) { + return _email(ZodEmail, params); +} +__name(email2, "email"); +var ZodGUID = /* @__PURE__ */ \$constructor("ZodGUID", (inst, def) => { + \$ZodGUID.init(inst, def); + ZodStringFormat.init(inst, def); +}); +function guid2(params) { + return _guid(ZodGUID, params); +} +__name(guid2, "guid"); +var ZodUUID = /* @__PURE__ */ \$constructor("ZodUUID", (inst, def) => { + \$ZodUUID.init(inst, def); + ZodStringFormat.init(inst, def); +}); +function uuid2(params) { + return _uuid(ZodUUID, params); +} +__name(uuid2, "uuid"); +function uuidv4(params) { + return _uuidv4(ZodUUID, params); +} +__name(uuidv4, "uuidv4"); +function uuidv6(params) { + return _uuidv6(ZodUUID, params); +} +__name(uuidv6, "uuidv6"); +function uuidv7(params) { + return _uuidv7(ZodUUID, params); +} +__name(uuidv7, "uuidv7"); +var ZodURL = /* @__PURE__ */ \$constructor("ZodURL", (inst, def) => { + \$ZodURL.init(inst, def); + ZodStringFormat.init(inst, def); +}); +function url(params) { + return _url(ZodURL, params); +} +__name(url, "url"); +function httpUrl(params) { + return _url(ZodURL, { + protocol: /^https?\$/, + hostname: regexes_exports.domain, + ...util_exports.normalizeParams(params) + }); +} +__name(httpUrl, "httpUrl"); +var ZodEmoji = /* @__PURE__ */ \$constructor("ZodEmoji", (inst, def) => { + \$ZodEmoji.init(inst, def); + ZodStringFormat.init(inst, def); +}); +function emoji2(params) { + return _emoji2(ZodEmoji, params); +} +__name(emoji2, "emoji"); +var ZodNanoID = /* @__PURE__ */ \$constructor("ZodNanoID", (inst, def) => { + \$ZodNanoID.init(inst, def); + ZodStringFormat.init(inst, def); +}); +function nanoid2(params) { + return _nanoid(ZodNanoID, params); +} +__name(nanoid2, "nanoid"); +var ZodCUID = /* @__PURE__ */ \$constructor("ZodCUID", (inst, def) => { + \$ZodCUID.init(inst, def); + ZodStringFormat.init(inst, def); +}); +function cuid3(params) { + return _cuid(ZodCUID, params); +} +__name(cuid3, "cuid"); +var ZodCUID2 = /* @__PURE__ */ \$constructor("ZodCUID2", (inst, def) => { + \$ZodCUID2.init(inst, def); + ZodStringFormat.init(inst, def); +}); +function cuid22(params) { + return _cuid2(ZodCUID2, params); +} +__name(cuid22, "cuid2"); +var ZodULID = /* @__PURE__ */ \$constructor("ZodULID", (inst, def) => { + \$ZodULID.init(inst, def); + ZodStringFormat.init(inst, def); +}); +function ulid2(params) { + return _ulid(ZodULID, params); +} +__name(ulid2, "ulid"); +var ZodXID = /* @__PURE__ */ \$constructor("ZodXID", (inst, def) => { + \$ZodXID.init(inst, def); + ZodStringFormat.init(inst, def); +}); +function xid2(params) { + return _xid(ZodXID, params); +} +__name(xid2, "xid"); +var ZodKSUID = /* @__PURE__ */ \$constructor("ZodKSUID", (inst, def) => { + \$ZodKSUID.init(inst, def); + ZodStringFormat.init(inst, def); +}); +function ksuid2(params) { + return _ksuid(ZodKSUID, params); +} +__name(ksuid2, "ksuid"); +var ZodIPv4 = /* @__PURE__ */ \$constructor("ZodIPv4", (inst, def) => { + \$ZodIPv4.init(inst, def); + ZodStringFormat.init(inst, def); +}); +function ipv42(params) { + return _ipv4(ZodIPv4, params); +} +__name(ipv42, "ipv4"); +var ZodIPv6 = /* @__PURE__ */ \$constructor("ZodIPv6", (inst, def) => { + \$ZodIPv6.init(inst, def); + ZodStringFormat.init(inst, def); +}); +function ipv62(params) { + return _ipv6(ZodIPv6, params); +} +__name(ipv62, "ipv6"); +var ZodCIDRv4 = /* @__PURE__ */ \$constructor("ZodCIDRv4", (inst, def) => { + \$ZodCIDRv4.init(inst, def); + ZodStringFormat.init(inst, def); +}); +function cidrv42(params) { + return _cidrv4(ZodCIDRv4, params); +} +__name(cidrv42, "cidrv4"); +var ZodCIDRv6 = /* @__PURE__ */ \$constructor("ZodCIDRv6", (inst, def) => { + \$ZodCIDRv6.init(inst, def); + ZodStringFormat.init(inst, def); +}); +function cidrv62(params) { + return _cidrv6(ZodCIDRv6, params); +} +__name(cidrv62, "cidrv6"); +var ZodBase64 = /* @__PURE__ */ \$constructor("ZodBase64", (inst, def) => { + \$ZodBase64.init(inst, def); + ZodStringFormat.init(inst, def); +}); +function base642(params) { + return _base64(ZodBase64, params); +} +__name(base642, "base64"); +var ZodBase64URL = /* @__PURE__ */ \$constructor("ZodBase64URL", (inst, def) => { + \$ZodBase64URL.init(inst, def); + ZodStringFormat.init(inst, def); +}); +function base64url2(params) { + return _base64url(ZodBase64URL, params); +} +__name(base64url2, "base64url"); +var ZodE164 = /* @__PURE__ */ \$constructor("ZodE164", (inst, def) => { + \$ZodE164.init(inst, def); + ZodStringFormat.init(inst, def); +}); +function e1642(params) { + return _e164(ZodE164, params); +} +__name(e1642, "e164"); +var ZodJWT = /* @__PURE__ */ \$constructor("ZodJWT", (inst, def) => { + \$ZodJWT.init(inst, def); + ZodStringFormat.init(inst, def); +}); +function jwt(params) { + return _jwt(ZodJWT, params); +} +__name(jwt, "jwt"); +var ZodCustomStringFormat = /* @__PURE__ */ \$constructor("ZodCustomStringFormat", (inst, def) => { + \$ZodCustomStringFormat.init(inst, def); + ZodStringFormat.init(inst, def); +}); +function stringFormat(format, fnOrRegex, _params = {}) { + return _stringFormat(ZodCustomStringFormat, format, fnOrRegex, _params); +} +__name(stringFormat, "stringFormat"); +function hostname2(_params) { + return _stringFormat(ZodCustomStringFormat, "hostname", regexes_exports.hostname, _params); +} +__name(hostname2, "hostname"); +function hex2(_params) { + return _stringFormat(ZodCustomStringFormat, "hex", regexes_exports.hex, _params); +} +__name(hex2, "hex"); +function hash(alg, params) { + const enc = params?.enc ?? "hex"; + const format = \`\${alg}_\${enc}\`; + const regex = regexes_exports[format]; + if (!regex) throw new Error(\`Unrecognized hash format: \${format}\`); + return _stringFormat(ZodCustomStringFormat, format, regex, params); +} +__name(hash, "hash"); +var ZodNumber = /* @__PURE__ */ \$constructor("ZodNumber", (inst, def) => { + \$ZodNumber.init(inst, def); + ZodType.init(inst, def); + inst.gt = (value, params) => inst.check(_gt(value, params)); + inst.gte = (value, params) => inst.check(_gte(value, params)); + inst.min = (value, params) => inst.check(_gte(value, params)); + inst.lt = (value, params) => inst.check(_lt(value, params)); + inst.lte = (value, params) => inst.check(_lte(value, params)); + inst.max = (value, params) => inst.check(_lte(value, params)); + inst.int = (params) => inst.check(int(params)); + inst.safe = (params) => inst.check(int(params)); + inst.positive = (params) => inst.check(_gt(0, params)); + inst.nonnegative = (params) => inst.check(_gte(0, params)); + inst.negative = (params) => inst.check(_lt(0, params)); + inst.nonpositive = (params) => inst.check(_lte(0, params)); + inst.multipleOf = (value, params) => inst.check(_multipleOf(value, params)); + inst.step = (value, params) => inst.check(_multipleOf(value, params)); + inst.finite = () => inst; + const bag = inst._zod.bag; + inst.minValue = Math.max(bag.minimum ?? Number.NEGATIVE_INFINITY, bag.exclusiveMinimum ?? Number.NEGATIVE_INFINITY) ?? null; + inst.maxValue = Math.min(bag.maximum ?? Number.POSITIVE_INFINITY, bag.exclusiveMaximum ?? Number.POSITIVE_INFINITY) ?? null; + inst.isInt = (bag.format ?? "").includes("int") || Number.isSafeInteger(bag.multipleOf ?? 0.5); + inst.isFinite = true; + inst.format = bag.format ?? null; +}); +function number2(params) { + return _number(ZodNumber, params); +} +__name(number2, "number"); +var ZodNumberFormat = /* @__PURE__ */ \$constructor("ZodNumberFormat", (inst, def) => { + \$ZodNumberFormat.init(inst, def); + ZodNumber.init(inst, def); +}); +function int(params) { + return _int(ZodNumberFormat, params); +} +__name(int, "int"); +function float32(params) { + return _float32(ZodNumberFormat, params); +} +__name(float32, "float32"); +function float64(params) { + return _float64(ZodNumberFormat, params); +} +__name(float64, "float64"); +function int32(params) { + return _int32(ZodNumberFormat, params); +} +__name(int32, "int32"); +function uint32(params) { + return _uint32(ZodNumberFormat, params); +} +__name(uint32, "uint32"); +var ZodBoolean = /* @__PURE__ */ \$constructor("ZodBoolean", (inst, def) => { + \$ZodBoolean.init(inst, def); + ZodType.init(inst, def); +}); +function boolean2(params) { + return _boolean(ZodBoolean, params); +} +__name(boolean2, "boolean"); +var ZodBigInt = /* @__PURE__ */ \$constructor("ZodBigInt", (inst, def) => { + \$ZodBigInt.init(inst, def); + ZodType.init(inst, def); + inst.gte = (value, params) => inst.check(_gte(value, params)); + inst.min = (value, params) => inst.check(_gte(value, params)); + inst.gt = (value, params) => inst.check(_gt(value, params)); + inst.gte = (value, params) => inst.check(_gte(value, params)); + inst.min = (value, params) => inst.check(_gte(value, params)); + inst.lt = (value, params) => inst.check(_lt(value, params)); + inst.lte = (value, params) => inst.check(_lte(value, params)); + inst.max = (value, params) => inst.check(_lte(value, params)); + inst.positive = (params) => inst.check(_gt(BigInt(0), params)); + inst.negative = (params) => inst.check(_lt(BigInt(0), params)); + inst.nonpositive = (params) => inst.check(_lte(BigInt(0), params)); + inst.nonnegative = (params) => inst.check(_gte(BigInt(0), params)); + inst.multipleOf = (value, params) => inst.check(_multipleOf(value, params)); + const bag = inst._zod.bag; + inst.minValue = bag.minimum ?? null; + inst.maxValue = bag.maximum ?? null; + inst.format = bag.format ?? null; +}); +function bigint2(params) { + return _bigint(ZodBigInt, params); +} +__name(bigint2, "bigint"); +var ZodBigIntFormat = /* @__PURE__ */ \$constructor("ZodBigIntFormat", (inst, def) => { + \$ZodBigIntFormat.init(inst, def); + ZodBigInt.init(inst, def); +}); +function int64(params) { + return _int64(ZodBigIntFormat, params); +} +__name(int64, "int64"); +function uint64(params) { + return _uint64(ZodBigIntFormat, params); +} +__name(uint64, "uint64"); +var ZodSymbol = /* @__PURE__ */ \$constructor("ZodSymbol", (inst, def) => { + \$ZodSymbol.init(inst, def); + ZodType.init(inst, def); +}); +function symbol15(params) { + return _symbol(ZodSymbol, params); +} +__name(symbol15, "symbol"); +var ZodUndefined = /* @__PURE__ */ \$constructor("ZodUndefined", (inst, def) => { + \$ZodUndefined.init(inst, def); + ZodType.init(inst, def); +}); +function _undefined3(params) { + return _undefined2(ZodUndefined, params); +} +__name(_undefined3, "_undefined"); +var ZodNull = /* @__PURE__ */ \$constructor("ZodNull", (inst, def) => { + \$ZodNull.init(inst, def); + ZodType.init(inst, def); +}); +function _null3(params) { + return _null2(ZodNull, params); +} +__name(_null3, "_null"); +var ZodAny = /* @__PURE__ */ \$constructor("ZodAny", (inst, def) => { + \$ZodAny.init(inst, def); + ZodType.init(inst, def); +}); +function any() { + return _any(ZodAny); +} +__name(any, "any"); +var ZodUnknown = /* @__PURE__ */ \$constructor("ZodUnknown", (inst, def) => { + \$ZodUnknown.init(inst, def); + ZodType.init(inst, def); +}); +function unknown() { + return _unknown(ZodUnknown); +} +__name(unknown, "unknown"); +var ZodNever = /* @__PURE__ */ \$constructor("ZodNever", (inst, def) => { + \$ZodNever.init(inst, def); + ZodType.init(inst, def); +}); +function never(params) { + return _never(ZodNever, params); +} +__name(never, "never"); +var ZodVoid = /* @__PURE__ */ \$constructor("ZodVoid", (inst, def) => { + \$ZodVoid.init(inst, def); + ZodType.init(inst, def); +}); +function _void2(params) { + return _void(ZodVoid, params); +} +__name(_void2, "_void"); +var ZodDate = /* @__PURE__ */ \$constructor("ZodDate", (inst, def) => { + \$ZodDate.init(inst, def); + ZodType.init(inst, def); + inst.min = (value, params) => inst.check(_gte(value, params)); + inst.max = (value, params) => inst.check(_lte(value, params)); + const c = inst._zod.bag; + inst.minDate = c.minimum ? new Date(c.minimum) : null; + inst.maxDate = c.maximum ? new Date(c.maximum) : null; +}); +function date3(params) { + return _date(ZodDate, params); +} +__name(date3, "date"); +var ZodArray = /* @__PURE__ */ \$constructor("ZodArray", (inst, def) => { + \$ZodArray.init(inst, def); + ZodType.init(inst, def); + inst.element = def.element; + inst.min = (minLength, params) => inst.check(_minLength(minLength, params)); + inst.nonempty = (params) => inst.check(_minLength(1, params)); + inst.max = (maxLength, params) => inst.check(_maxLength(maxLength, params)); + inst.length = (len, params) => inst.check(_length(len, params)); + inst.unwrap = () => inst.element; +}); +function array(element, params) { + return _array(ZodArray, element, params); +} +__name(array, "array"); +function keyof(schema) { + const shape = schema._zod.def.shape; + return _enum2(Object.keys(shape)); +} +__name(keyof, "keyof"); +var ZodObject = /* @__PURE__ */ \$constructor("ZodObject", (inst, def) => { + \$ZodObjectJIT.init(inst, def); + ZodType.init(inst, def); + util_exports.defineLazy(inst, "shape", () => { + return def.shape; + }); + inst.keyof = () => _enum2(Object.keys(inst._zod.def.shape)); + inst.catchall = (catchall) => inst.clone({ + ...inst._zod.def, + catchall + }); + inst.passthrough = () => inst.clone({ + ...inst._zod.def, + catchall: unknown() + }); + inst.loose = () => inst.clone({ + ...inst._zod.def, + catchall: unknown() + }); + inst.strict = () => inst.clone({ + ...inst._zod.def, + catchall: never() + }); + inst.strip = () => inst.clone({ + ...inst._zod.def, + catchall: void 0 + }); + inst.extend = (incoming) => { + return util_exports.extend(inst, incoming); + }; + inst.safeExtend = (incoming) => { + return util_exports.safeExtend(inst, incoming); + }; + inst.merge = (other) => util_exports.merge(inst, other); + inst.pick = (mask) => util_exports.pick(inst, mask); + inst.omit = (mask) => util_exports.omit(inst, mask); + inst.partial = (...args) => util_exports.partial(ZodOptional, inst, args[0]); + inst.required = (...args) => util_exports.required(ZodNonOptional, inst, args[0]); +}); +function object(shape, params) { + const def = { + type: "object", + shape: shape ?? {}, + ...util_exports.normalizeParams(params) + }; + return new ZodObject(def); +} +__name(object, "object"); +function strictObject(shape, params) { + return new ZodObject({ + type: "object", + shape, + catchall: never(), + ...util_exports.normalizeParams(params) + }); +} +__name(strictObject, "strictObject"); +function looseObject(shape, params) { + return new ZodObject({ + type: "object", + shape, + catchall: unknown(), + ...util_exports.normalizeParams(params) + }); +} +__name(looseObject, "looseObject"); +var ZodUnion = /* @__PURE__ */ \$constructor("ZodUnion", (inst, def) => { + \$ZodUnion.init(inst, def); + ZodType.init(inst, def); + inst.options = def.options; +}); +function union(options, params) { + return new ZodUnion({ + type: "union", + options, + ...util_exports.normalizeParams(params) + }); +} +__name(union, "union"); +var ZodDiscriminatedUnion = /* @__PURE__ */ \$constructor("ZodDiscriminatedUnion", (inst, def) => { + ZodUnion.init(inst, def); + \$ZodDiscriminatedUnion.init(inst, def); +}); +function discriminatedUnion(discriminator, options, params) { + return new ZodDiscriminatedUnion({ + type: "union", + options, + discriminator, + ...util_exports.normalizeParams(params) + }); +} +__name(discriminatedUnion, "discriminatedUnion"); +var ZodIntersection = /* @__PURE__ */ \$constructor("ZodIntersection", (inst, def) => { + \$ZodIntersection.init(inst, def); + ZodType.init(inst, def); +}); +function intersection(left, right) { + return new ZodIntersection({ + type: "intersection", + left, + right + }); +} +__name(intersection, "intersection"); +var ZodTuple = /* @__PURE__ */ \$constructor("ZodTuple", (inst, def) => { + \$ZodTuple.init(inst, def); + ZodType.init(inst, def); + inst.rest = (rest) => inst.clone({ + ...inst._zod.def, + rest + }); +}); +function tuple(items, _paramsOrRest, _params) { + const hasRest = _paramsOrRest instanceof \$ZodType; + const params = hasRest ? _params : _paramsOrRest; + const rest = hasRest ? _paramsOrRest : null; + return new ZodTuple({ + type: "tuple", + items, + rest, + ...util_exports.normalizeParams(params) + }); +} +__name(tuple, "tuple"); +var ZodRecord = /* @__PURE__ */ \$constructor("ZodRecord", (inst, def) => { + \$ZodRecord.init(inst, def); + ZodType.init(inst, def); + inst.keyType = def.keyType; + inst.valueType = def.valueType; +}); +function record(keyType, valueType, params) { + return new ZodRecord({ + type: "record", + keyType, + valueType, + ...util_exports.normalizeParams(params) + }); +} +__name(record, "record"); +function partialRecord(keyType, valueType, params) { + const k = clone(keyType); + k._zod.values = void 0; + return new ZodRecord({ + type: "record", + keyType: k, + valueType, + ...util_exports.normalizeParams(params) + }); +} +__name(partialRecord, "partialRecord"); +var ZodMap = /* @__PURE__ */ \$constructor("ZodMap", (inst, def) => { + \$ZodMap.init(inst, def); + ZodType.init(inst, def); + inst.keyType = def.keyType; + inst.valueType = def.valueType; +}); +function map(keyType, valueType, params) { + return new ZodMap({ + type: "map", + keyType, + valueType, + ...util_exports.normalizeParams(params) + }); +} +__name(map, "map"); +var ZodSet = /* @__PURE__ */ \$constructor("ZodSet", (inst, def) => { + \$ZodSet.init(inst, def); + ZodType.init(inst, def); + inst.min = (...args) => inst.check(_minSize(...args)); + inst.nonempty = (params) => inst.check(_minSize(1, params)); + inst.max = (...args) => inst.check(_maxSize(...args)); + inst.size = (...args) => inst.check(_size(...args)); +}); +function set(valueType, params) { + return new ZodSet({ + type: "set", + valueType, + ...util_exports.normalizeParams(params) + }); +} +__name(set, "set"); +var ZodEnum = /* @__PURE__ */ \$constructor("ZodEnum", (inst, def) => { + \$ZodEnum.init(inst, def); + ZodType.init(inst, def); + inst.enum = def.entries; + inst.options = Object.values(def.entries); + const keys = new Set(Object.keys(def.entries)); + inst.extract = (values, params) => { + const newEntries = {}; + for (const value of values) { + if (keys.has(value)) { + newEntries[value] = def.entries[value]; + } else throw new Error(\`Key \${value} not found in enum\`); + } + return new ZodEnum({ + ...def, + checks: [], + ...util_exports.normalizeParams(params), + entries: newEntries + }); + }; + inst.exclude = (values, params) => { + const newEntries = { + ...def.entries + }; + for (const value of values) { + if (keys.has(value)) { + delete newEntries[value]; + } else throw new Error(\`Key \${value} not found in enum\`); + } + return new ZodEnum({ + ...def, + checks: [], + ...util_exports.normalizeParams(params), + entries: newEntries + }); + }; +}); +function _enum2(values, params) { + const entries = Array.isArray(values) ? Object.fromEntries(values.map((v) => [ + v, + v + ])) : values; + return new ZodEnum({ + type: "enum", + entries, + ...util_exports.normalizeParams(params) + }); +} +__name(_enum2, "_enum"); +function nativeEnum(entries, params) { + return new ZodEnum({ + type: "enum", + entries, + ...util_exports.normalizeParams(params) + }); +} +__name(nativeEnum, "nativeEnum"); +var ZodLiteral = /* @__PURE__ */ \$constructor("ZodLiteral", (inst, def) => { + \$ZodLiteral.init(inst, def); + ZodType.init(inst, def); + inst.values = new Set(def.values); + Object.defineProperty(inst, "value", { + get() { + if (def.values.length > 1) { + throw new Error("This schema contains multiple valid literal values. Use \`.values\` instead."); + } + return def.values[0]; + } + }); +}); +function literal(value, params) { + return new ZodLiteral({ + type: "literal", + values: Array.isArray(value) ? value : [ + value + ], + ...util_exports.normalizeParams(params) + }); +} +__name(literal, "literal"); +var ZodFile = /* @__PURE__ */ \$constructor("ZodFile", (inst, def) => { + \$ZodFile.init(inst, def); + ZodType.init(inst, def); + inst.min = (size, params) => inst.check(_minSize(size, params)); + inst.max = (size, params) => inst.check(_maxSize(size, params)); + inst.mime = (types, params) => inst.check(_mime(Array.isArray(types) ? types : [ + types + ], params)); +}); +function file(params) { + return _file(ZodFile, params); +} +__name(file, "file"); +var ZodTransform = /* @__PURE__ */ \$constructor("ZodTransform", (inst, def) => { + \$ZodTransform.init(inst, def); + ZodType.init(inst, def); + inst._zod.parse = (payload, _ctx) => { + if (_ctx.direction === "backward") { + throw new \$ZodEncodeError(inst.constructor.name); + } + payload.addIssue = (issue2) => { + if (typeof issue2 === "string") { + payload.issues.push(util_exports.issue(issue2, payload.value, def)); + } else { + const _issue = issue2; + if (_issue.fatal) _issue.continue = false; + _issue.code ?? (_issue.code = "custom"); + _issue.input ?? (_issue.input = payload.value); + _issue.inst ?? (_issue.inst = inst); + payload.issues.push(util_exports.issue(_issue)); + } + }; + const output = def.transform(payload.value, payload); + if (output instanceof Promise) { + return output.then((output2) => { + payload.value = output2; + return payload; + }); + } + payload.value = output; + return payload; + }; +}); +function transform(fn) { + return new ZodTransform({ + type: "transform", + transform: fn + }); +} +__name(transform, "transform"); +var ZodOptional = /* @__PURE__ */ \$constructor("ZodOptional", (inst, def) => { + \$ZodOptional.init(inst, def); + ZodType.init(inst, def); + inst.unwrap = () => inst._zod.def.innerType; +}); +function optional(innerType) { + return new ZodOptional({ + type: "optional", + innerType + }); +} +__name(optional, "optional"); +var ZodNullable = /* @__PURE__ */ \$constructor("ZodNullable", (inst, def) => { + \$ZodNullable.init(inst, def); + ZodType.init(inst, def); + inst.unwrap = () => inst._zod.def.innerType; +}); +function nullable(innerType) { + return new ZodNullable({ + type: "nullable", + innerType + }); +} +__name(nullable, "nullable"); +function nullish2(innerType) { + return optional(nullable(innerType)); +} +__name(nullish2, "nullish"); +var ZodDefault = /* @__PURE__ */ \$constructor("ZodDefault", (inst, def) => { + \$ZodDefault.init(inst, def); + ZodType.init(inst, def); + inst.unwrap = () => inst._zod.def.innerType; + inst.removeDefault = inst.unwrap; +}); +function _default2(innerType, defaultValue) { + return new ZodDefault({ + type: "default", + innerType, + get defaultValue() { + return typeof defaultValue === "function" ? defaultValue() : util_exports.shallowClone(defaultValue); + } + }); +} +__name(_default2, "_default"); +var ZodPrefault = /* @__PURE__ */ \$constructor("ZodPrefault", (inst, def) => { + \$ZodPrefault.init(inst, def); + ZodType.init(inst, def); + inst.unwrap = () => inst._zod.def.innerType; +}); +function prefault(innerType, defaultValue) { + return new ZodPrefault({ + type: "prefault", + innerType, + get defaultValue() { + return typeof defaultValue === "function" ? defaultValue() : util_exports.shallowClone(defaultValue); + } + }); +} +__name(prefault, "prefault"); +var ZodNonOptional = /* @__PURE__ */ \$constructor("ZodNonOptional", (inst, def) => { + \$ZodNonOptional.init(inst, def); + ZodType.init(inst, def); + inst.unwrap = () => inst._zod.def.innerType; +}); +function nonoptional(innerType, params) { + return new ZodNonOptional({ + type: "nonoptional", + innerType, + ...util_exports.normalizeParams(params) + }); +} +__name(nonoptional, "nonoptional"); +var ZodSuccess = /* @__PURE__ */ \$constructor("ZodSuccess", (inst, def) => { + \$ZodSuccess.init(inst, def); + ZodType.init(inst, def); + inst.unwrap = () => inst._zod.def.innerType; +}); +function success(innerType) { + return new ZodSuccess({ + type: "success", + innerType + }); +} +__name(success, "success"); +var ZodCatch = /* @__PURE__ */ \$constructor("ZodCatch", (inst, def) => { + \$ZodCatch.init(inst, def); + ZodType.init(inst, def); + inst.unwrap = () => inst._zod.def.innerType; + inst.removeCatch = inst.unwrap; +}); +function _catch2(innerType, catchValue) { + return new ZodCatch({ + type: "catch", + innerType, + catchValue: typeof catchValue === "function" ? catchValue : () => catchValue + }); +} +__name(_catch2, "_catch"); +var ZodNaN = /* @__PURE__ */ \$constructor("ZodNaN", (inst, def) => { + \$ZodNaN.init(inst, def); + ZodType.init(inst, def); +}); +function nan(params) { + return _nan(ZodNaN, params); +} +__name(nan, "nan"); +var ZodPipe = /* @__PURE__ */ \$constructor("ZodPipe", (inst, def) => { + \$ZodPipe.init(inst, def); + ZodType.init(inst, def); + inst.in = def.in; + inst.out = def.out; +}); +function pipe(in_, out) { + return new ZodPipe({ + type: "pipe", + in: in_, + out + }); +} +__name(pipe, "pipe"); +var ZodCodec = /* @__PURE__ */ \$constructor("ZodCodec", (inst, def) => { + ZodPipe.init(inst, def); + \$ZodCodec.init(inst, def); +}); +function codec(in_, out, params) { + return new ZodCodec({ + type: "pipe", + in: in_, + out, + transform: params.decode, + reverseTransform: params.encode + }); +} +__name(codec, "codec"); +var ZodReadonly = /* @__PURE__ */ \$constructor("ZodReadonly", (inst, def) => { + \$ZodReadonly.init(inst, def); + ZodType.init(inst, def); + inst.unwrap = () => inst._zod.def.innerType; +}); +function readonly(innerType) { + return new ZodReadonly({ + type: "readonly", + innerType + }); +} +__name(readonly, "readonly"); +var ZodTemplateLiteral = /* @__PURE__ */ \$constructor("ZodTemplateLiteral", (inst, def) => { + \$ZodTemplateLiteral.init(inst, def); + ZodType.init(inst, def); +}); +function templateLiteral(parts, params) { + return new ZodTemplateLiteral({ + type: "template_literal", + parts, + ...util_exports.normalizeParams(params) + }); +} +__name(templateLiteral, "templateLiteral"); +var ZodLazy = /* @__PURE__ */ \$constructor("ZodLazy", (inst, def) => { + \$ZodLazy.init(inst, def); + ZodType.init(inst, def); + inst.unwrap = () => inst._zod.def.getter(); +}); +function lazy(getter) { + return new ZodLazy({ + type: "lazy", + getter + }); +} +__name(lazy, "lazy"); +var ZodPromise = /* @__PURE__ */ \$constructor("ZodPromise", (inst, def) => { + \$ZodPromise.init(inst, def); + ZodType.init(inst, def); + inst.unwrap = () => inst._zod.def.innerType; +}); +function promise(innerType) { + return new ZodPromise({ + type: "promise", + innerType + }); +} +__name(promise, "promise"); +var ZodFunction = /* @__PURE__ */ \$constructor("ZodFunction", (inst, def) => { + \$ZodFunction.init(inst, def); + ZodType.init(inst, def); +}); +function _function(params) { + return new ZodFunction({ + type: "function", + input: Array.isArray(params?.input) ? tuple(params?.input) : params?.input ?? array(unknown()), + output: params?.output ?? unknown() + }); +} +__name(_function, "_function"); +var ZodCustom = /* @__PURE__ */ \$constructor("ZodCustom", (inst, def) => { + \$ZodCustom.init(inst, def); + ZodType.init(inst, def); +}); +function check(fn) { + const ch = new \$ZodCheck({ + check: "custom" + }); + ch._zod.check = fn; + return ch; +} +__name(check, "check"); +function custom(fn, _params) { + return _custom(ZodCustom, fn ?? (() => true), _params); +} +__name(custom, "custom"); +function refine(fn, _params = {}) { + return _refine(ZodCustom, fn, _params); +} +__name(refine, "refine"); +function superRefine(fn) { + return _superRefine(fn); +} +__name(superRefine, "superRefine"); +function _instanceof(cls, params = { + error: \`Input not instance of \${cls.name}\` +}) { + const inst = new ZodCustom({ + type: "custom", + check: "custom", + fn: /* @__PURE__ */ __name((data) => data instanceof cls, "fn"), + abort: true, + ...util_exports.normalizeParams(params) + }); + inst._zod.bag.Class = cls; + return inst; +} +__name(_instanceof, "_instanceof"); +var stringbool = /* @__PURE__ */ __name((...args) => _stringbool({ + Codec: ZodCodec, + Boolean: ZodBoolean, + String: ZodString +}, ...args), "stringbool"); +function json(params) { + const jsonSchema2 = lazy(() => { + return union([ + string2(params), + number2(), + boolean2(), + _null3(), + array(jsonSchema2), + record(string2(), jsonSchema2) + ]); + }); + return jsonSchema2; +} +__name(json, "json"); +function preprocess(fn, schema) { + return pipe(transform(fn), schema); +} +__name(preprocess, "preprocess"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/classic/compat.js +var ZodIssueCode = { + invalid_type: "invalid_type", + too_big: "too_big", + too_small: "too_small", + invalid_format: "invalid_format", + not_multiple_of: "not_multiple_of", + unrecognized_keys: "unrecognized_keys", + invalid_union: "invalid_union", + invalid_key: "invalid_key", + invalid_element: "invalid_element", + invalid_value: "invalid_value", + custom: "custom" +}; +function setErrorMap(map2) { + config({ + customError: map2 + }); +} +__name(setErrorMap, "setErrorMap"); +function getErrorMap() { + return config().customError; +} +__name(getErrorMap, "getErrorMap"); +var ZodFirstPartyTypeKind; +/* @__PURE__ */ (function(ZodFirstPartyTypeKind3) { +})(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {})); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/classic/coerce.js +var coerce_exports = {}; +__export(coerce_exports, { + bigint: () => bigint3, + boolean: () => boolean3, + date: () => date4, + number: () => number3, + string: () => string3 +}); +function string3(params) { + return _coercedString(ZodString, params); +} +__name(string3, "string"); +function number3(params) { + return _coercedNumber(ZodNumber, params); +} +__name(number3, "number"); +function boolean3(params) { + return _coercedBoolean(ZodBoolean, params); +} +__name(boolean3, "boolean"); +function bigint3(params) { + return _coercedBigint(ZodBigInt, params); +} +__name(bigint3, "bigint"); +function date4(params) { + return _coercedDate(ZodDate, params); +} +__name(date4, "date"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/classic/external.js +config(en_default()); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/classic/index.js +var classic_default = external_exports; + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/index.js +var v4_default = classic_default; + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v3/helpers/util.js +var util; +(function(util2) { + util2.assertEqual = (_) => { + }; + function assertIs2(_arg) { + } + __name(assertIs2, "assertIs"); + util2.assertIs = assertIs2; + function assertNever2(_x) { + throw new Error(); + } + __name(assertNever2, "assertNever"); + util2.assertNever = assertNever2; + util2.arrayToEnum = (items) => { + const obj = {}; + for (const item of items) { + obj[item] = item; + } + return obj; + }; + util2.getValidEnumValues = (obj) => { + const validKeys = util2.objectKeys(obj).filter((k) => typeof obj[obj[k]] !== "number"); + const filtered = {}; + for (const k of validKeys) { + filtered[k] = obj[k]; + } + return util2.objectValues(filtered); + }; + util2.objectValues = (obj) => { + return util2.objectKeys(obj).map(function(e) { + return obj[e]; + }); + }; + util2.objectKeys = typeof Object.keys === "function" ? (obj) => Object.keys(obj) : (object3) => { + const keys = []; + for (const key in object3) { + if (Object.prototype.hasOwnProperty.call(object3, key)) { + keys.push(key); + } + } + return keys; + }; + util2.find = (arr, checker) => { + for (const item of arr) { + if (checker(item)) return item; + } + return void 0; + }; + util2.isInteger = typeof Number.isInteger === "function" ? (val) => Number.isInteger(val) : (val) => typeof val === "number" && Number.isFinite(val) && Math.floor(val) === val; + function joinValues2(array2, separator = " | ") { + return array2.map((val) => typeof val === "string" ? \`'\${val}'\` : val).join(separator); + } + __name(joinValues2, "joinValues"); + util2.joinValues = joinValues2; + util2.jsonStringifyReplacer = (_, value) => { + if (typeof value === "bigint") { + return value.toString(); + } + return value; + }; +})(util || (util = {})); +var objectUtil; +(function(objectUtil2) { + objectUtil2.mergeShapes = (first, second) => { + return { + ...first, + ...second + }; + }; +})(objectUtil || (objectUtil = {})); +var ZodParsedType = util.arrayToEnum([ + "string", + "nan", + "number", + "integer", + "float", + "boolean", + "date", + "bigint", + "symbol", + "function", + "undefined", + "null", + "array", + "object", + "unknown", + "promise", + "void", + "never", + "map", + "set" +]); +var getParsedType2 = /* @__PURE__ */ __name((data) => { + const t = typeof data; + switch (t) { + case "undefined": + return ZodParsedType.undefined; + case "string": + return ZodParsedType.string; + case "number": + return Number.isNaN(data) ? ZodParsedType.nan : ZodParsedType.number; + case "boolean": + return ZodParsedType.boolean; + case "function": + return ZodParsedType.function; + case "bigint": + return ZodParsedType.bigint; + case "symbol": + return ZodParsedType.symbol; + case "object": + if (Array.isArray(data)) { + return ZodParsedType.array; + } + if (data === null) { + return ZodParsedType.null; + } + if (data.then && typeof data.then === "function" && data.catch && typeof data.catch === "function") { + return ZodParsedType.promise; + } + if (typeof Map !== "undefined" && data instanceof Map) { + return ZodParsedType.map; + } + if (typeof Set !== "undefined" && data instanceof Set) { + return ZodParsedType.set; + } + if (typeof Date !== "undefined" && data instanceof Date) { + return ZodParsedType.date; + } + return ZodParsedType.object; + default: + return ZodParsedType.unknown; + } +}, "getParsedType"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v3/ZodError.js +var ZodIssueCode2 = util.arrayToEnum([ + "invalid_type", + "invalid_literal", + "custom", + "invalid_union", + "invalid_union_discriminator", + "invalid_enum_value", + "unrecognized_keys", + "invalid_arguments", + "invalid_return_type", + "invalid_date", + "invalid_string", + "too_small", + "too_big", + "invalid_intersection_types", + "not_multiple_of", + "not_finite" +]); +var ZodError2 = class _ZodError extends Error { + static { + __name(this, "ZodError"); + } + get errors() { + return this.issues; + } + constructor(issues) { + super(); + this.issues = []; + this.addIssue = (sub) => { + this.issues = [ + ...this.issues, + sub + ]; + }; + this.addIssues = (subs = []) => { + this.issues = [ + ...this.issues, + ...subs + ]; + }; + const actualProto = new.target.prototype; + if (Object.setPrototypeOf) { + Object.setPrototypeOf(this, actualProto); + } else { + this.__proto__ = actualProto; + } + this.name = "ZodError"; + this.issues = issues; + } + format(_mapper) { + const mapper = _mapper || function(issue2) { + return issue2.message; + }; + const fieldErrors = { + _errors: [] + }; + const processError = /* @__PURE__ */ __name((error45) => { + for (const issue2 of error45.issues) { + if (issue2.code === "invalid_union") { + issue2.unionErrors.map(processError); + } else if (issue2.code === "invalid_return_type") { + processError(issue2.returnTypeError); + } else if (issue2.code === "invalid_arguments") { + processError(issue2.argumentsError); + } else if (issue2.path.length === 0) { + fieldErrors._errors.push(mapper(issue2)); + } else { + let curr = fieldErrors; + let i = 0; + while (i < issue2.path.length) { + const el = issue2.path[i]; + const terminal = i === issue2.path.length - 1; + if (!terminal) { + curr[el] = curr[el] || { + _errors: [] + }; + } else { + curr[el] = curr[el] || { + _errors: [] + }; + curr[el]._errors.push(mapper(issue2)); + } + curr = curr[el]; + i++; + } + } + } + }, "processError"); + processError(this); + return fieldErrors; + } + static assert(value) { + if (!(value instanceof _ZodError)) { + throw new Error(\`Not a ZodError: \${value}\`); + } + } + toString() { + return this.message; + } + get message() { + return JSON.stringify(this.issues, util.jsonStringifyReplacer, 2); + } + get isEmpty() { + return this.issues.length === 0; + } + flatten(mapper = (issue2) => issue2.message) { + const fieldErrors = {}; + const formErrors = []; + for (const sub of this.issues) { + if (sub.path.length > 0) { + const firstEl = sub.path[0]; + fieldErrors[firstEl] = fieldErrors[firstEl] || []; + fieldErrors[firstEl].push(mapper(sub)); + } else { + formErrors.push(mapper(sub)); + } + } + return { + formErrors, + fieldErrors + }; + } + get formErrors() { + return this.flatten(); + } +}; +ZodError2.create = (issues) => { + const error45 = new ZodError2(issues); + return error45; +}; + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v3/locales/en.js +var errorMap = /* @__PURE__ */ __name((issue2, _ctx) => { + let message; + switch (issue2.code) { + case ZodIssueCode2.invalid_type: + if (issue2.received === ZodParsedType.undefined) { + message = "Required"; + } else { + message = \`Expected \${issue2.expected}, received \${issue2.received}\`; + } + break; + case ZodIssueCode2.invalid_literal: + message = \`Invalid literal value, expected \${JSON.stringify(issue2.expected, util.jsonStringifyReplacer)}\`; + break; + case ZodIssueCode2.unrecognized_keys: + message = \`Unrecognized key(s) in object: \${util.joinValues(issue2.keys, ", ")}\`; + break; + case ZodIssueCode2.invalid_union: + message = \`Invalid input\`; + break; + case ZodIssueCode2.invalid_union_discriminator: + message = \`Invalid discriminator value. Expected \${util.joinValues(issue2.options)}\`; + break; + case ZodIssueCode2.invalid_enum_value: + message = \`Invalid enum value. Expected \${util.joinValues(issue2.options)}, received '\${issue2.received}'\`; + break; + case ZodIssueCode2.invalid_arguments: + message = \`Invalid function arguments\`; + break; + case ZodIssueCode2.invalid_return_type: + message = \`Invalid function return type\`; + break; + case ZodIssueCode2.invalid_date: + message = \`Invalid date\`; + break; + case ZodIssueCode2.invalid_string: + if (typeof issue2.validation === "object") { + if ("includes" in issue2.validation) { + message = \`Invalid input: must include "\${issue2.validation.includes}"\`; + if (typeof issue2.validation.position === "number") { + message = \`\${message} at one or more positions greater than or equal to \${issue2.validation.position}\`; + } + } else if ("startsWith" in issue2.validation) { + message = \`Invalid input: must start with "\${issue2.validation.startsWith}"\`; + } else if ("endsWith" in issue2.validation) { + message = \`Invalid input: must end with "\${issue2.validation.endsWith}"\`; + } else { + util.assertNever(issue2.validation); + } + } else if (issue2.validation !== "regex") { + message = \`Invalid \${issue2.validation}\`; + } else { + message = "Invalid"; + } + break; + case ZodIssueCode2.too_small: + if (issue2.type === "array") message = \`Array must contain \${issue2.exact ? "exactly" : issue2.inclusive ? \`at least\` : \`more than\`} \${issue2.minimum} element(s)\`; + else if (issue2.type === "string") message = \`String must contain \${issue2.exact ? "exactly" : issue2.inclusive ? \`at least\` : \`over\`} \${issue2.minimum} character(s)\`; + else if (issue2.type === "number") message = \`Number must be \${issue2.exact ? \`exactly equal to \` : issue2.inclusive ? \`greater than or equal to \` : \`greater than \`}\${issue2.minimum}\`; + else if (issue2.type === "bigint") message = \`Number must be \${issue2.exact ? \`exactly equal to \` : issue2.inclusive ? \`greater than or equal to \` : \`greater than \`}\${issue2.minimum}\`; + else if (issue2.type === "date") message = \`Date must be \${issue2.exact ? \`exactly equal to \` : issue2.inclusive ? \`greater than or equal to \` : \`greater than \`}\${new Date(Number(issue2.minimum))}\`; + else message = "Invalid input"; + break; + case ZodIssueCode2.too_big: + if (issue2.type === "array") message = \`Array must contain \${issue2.exact ? \`exactly\` : issue2.inclusive ? \`at most\` : \`less than\`} \${issue2.maximum} element(s)\`; + else if (issue2.type === "string") message = \`String must contain \${issue2.exact ? \`exactly\` : issue2.inclusive ? \`at most\` : \`under\`} \${issue2.maximum} character(s)\`; + else if (issue2.type === "number") message = \`Number must be \${issue2.exact ? \`exactly\` : issue2.inclusive ? \`less than or equal to\` : \`less than\`} \${issue2.maximum}\`; + else if (issue2.type === "bigint") message = \`BigInt must be \${issue2.exact ? \`exactly\` : issue2.inclusive ? \`less than or equal to\` : \`less than\`} \${issue2.maximum}\`; + else if (issue2.type === "date") message = \`Date must be \${issue2.exact ? \`exactly\` : issue2.inclusive ? \`smaller than or equal to\` : \`smaller than\`} \${new Date(Number(issue2.maximum))}\`; + else message = "Invalid input"; + break; + case ZodIssueCode2.custom: + message = \`Invalid input\`; + break; + case ZodIssueCode2.invalid_intersection_types: + message = \`Intersection results could not be merged\`; + break; + case ZodIssueCode2.not_multiple_of: + message = \`Number must be a multiple of \${issue2.multipleOf}\`; + break; + case ZodIssueCode2.not_finite: + message = "Number must be finite"; + break; + default: + message = _ctx.defaultError; + util.assertNever(issue2); + } + return { + message + }; +}, "errorMap"); +var en_default2 = errorMap; + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v3/errors.js +var overrideErrorMap = en_default2; +function getErrorMap2() { + return overrideErrorMap; +} +__name(getErrorMap2, "getErrorMap"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v3/helpers/parseUtil.js +var makeIssue = /* @__PURE__ */ __name((params) => { + const { data, path, errorMaps, issueData } = params; + const fullPath = [ + ...path, + ...issueData.path || [] + ]; + const fullIssue = { + ...issueData, + path: fullPath + }; + if (issueData.message !== void 0) { + return { + ...issueData, + path: fullPath, + message: issueData.message + }; + } + let errorMessage = ""; + const maps = errorMaps.filter((m) => !!m).slice().reverse(); + for (const map2 of maps) { + errorMessage = map2(fullIssue, { + data, + defaultError: errorMessage + }).message; + } + return { + ...issueData, + path: fullPath, + message: errorMessage + }; +}, "makeIssue"); +function addIssueToContext(ctx, issueData) { + const overrideMap = getErrorMap2(); + const issue2 = makeIssue({ + issueData, + data: ctx.data, + path: ctx.path, + errorMaps: [ + ctx.common.contextualErrorMap, + ctx.schemaErrorMap, + overrideMap, + overrideMap === en_default2 ? void 0 : en_default2 + ].filter((x) => !!x) + }); + ctx.common.issues.push(issue2); +} +__name(addIssueToContext, "addIssueToContext"); +var ParseStatus = class _ParseStatus { + static { + __name(this, "ParseStatus"); + } + constructor() { + this.value = "valid"; + } + dirty() { + if (this.value === "valid") this.value = "dirty"; + } + abort() { + if (this.value !== "aborted") this.value = "aborted"; + } + static mergeArray(status, results) { + const arrayValue = []; + for (const s of results) { + if (s.status === "aborted") return INVALID; + if (s.status === "dirty") status.dirty(); + arrayValue.push(s.value); + } + return { + status: status.value, + value: arrayValue + }; + } + static async mergeObjectAsync(status, pairs) { + const syncPairs = []; + for (const pair of pairs) { + const key = await pair.key; + const value = await pair.value; + syncPairs.push({ + key, + value + }); + } + return _ParseStatus.mergeObjectSync(status, syncPairs); + } + static mergeObjectSync(status, pairs) { + const finalObject = {}; + for (const pair of pairs) { + const { key, value } = pair; + if (key.status === "aborted") return INVALID; + if (value.status === "aborted") return INVALID; + if (key.status === "dirty") status.dirty(); + if (value.status === "dirty") status.dirty(); + if (key.value !== "__proto__" && (typeof value.value !== "undefined" || pair.alwaysSet)) { + finalObject[key.value] = value.value; + } + } + return { + status: status.value, + value: finalObject + }; + } +}; +var INVALID = Object.freeze({ + status: "aborted" +}); +var DIRTY = /* @__PURE__ */ __name((value) => ({ + status: "dirty", + value +}), "DIRTY"); +var OK = /* @__PURE__ */ __name((value) => ({ + status: "valid", + value +}), "OK"); +var isAborted = /* @__PURE__ */ __name((x) => x.status === "aborted", "isAborted"); +var isDirty = /* @__PURE__ */ __name((x) => x.status === "dirty", "isDirty"); +var isValid = /* @__PURE__ */ __name((x) => x.status === "valid", "isValid"); +var isAsync = /* @__PURE__ */ __name((x) => typeof Promise !== "undefined" && x instanceof Promise, "isAsync"); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v3/helpers/errorUtil.js +var errorUtil; +(function(errorUtil2) { + errorUtil2.errToObj = (message) => typeof message === "string" ? { + message + } : message || {}; + errorUtil2.toString = (message) => typeof message === "string" ? message : message?.message; +})(errorUtil || (errorUtil = {})); + +// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v3/types.js +var ParseInputLazyPath = class { + static { + __name(this, "ParseInputLazyPath"); + } + constructor(parent, value, path, key) { + this._cachedPath = []; + this.parent = parent; + this.data = value; + this._path = path; + this._key = key; + } + get path() { + if (!this._cachedPath.length) { + if (Array.isArray(this._key)) { + this._cachedPath.push(...this._path, ...this._key); + } else { + this._cachedPath.push(...this._path, this._key); + } + } + return this._cachedPath; + } +}; +var handleResult = /* @__PURE__ */ __name((ctx, result) => { + if (isValid(result)) { + return { + success: true, + data: result.value + }; + } else { + if (!ctx.common.issues.length) { + throw new Error("Validation failed but no issues detected."); + } + return { + success: false, + get error() { + if (this._error) return this._error; + const error45 = new ZodError2(ctx.common.issues); + this._error = error45; + return this._error; + } + }; + } +}, "handleResult"); +function processCreateParams(params) { + if (!params) return {}; + const { errorMap: errorMap2, invalid_type_error, required_error, description } = params; + if (errorMap2 && (invalid_type_error || required_error)) { + throw new Error(\`Can't use "invalid_type_error" or "required_error" in conjunction with custom error map.\`); + } + if (errorMap2) return { + errorMap: errorMap2, + description + }; + const customMap = /* @__PURE__ */ __name((iss, ctx) => { + const { message } = params; + if (iss.code === "invalid_enum_value") { + return { + message: message ?? ctx.defaultError + }; + } + if (typeof ctx.data === "undefined") { + return { + message: message ?? required_error ?? ctx.defaultError + }; + } + if (iss.code !== "invalid_type") return { + message: ctx.defaultError + }; + return { + message: message ?? invalid_type_error ?? ctx.defaultError + }; + }, "customMap"); + return { + errorMap: customMap, + description + }; +} +__name(processCreateParams, "processCreateParams"); +var ZodType2 = class { + static { + __name(this, "ZodType"); + } + get description() { + return this._def.description; + } + _getType(input) { + return getParsedType2(input.data); + } + _getOrReturnCtx(input, ctx) { + return ctx || { + common: input.parent.common, + data: input.data, + parsedType: getParsedType2(input.data), + schemaErrorMap: this._def.errorMap, + path: input.path, + parent: input.parent + }; + } + _processInputParams(input) { + return { + status: new ParseStatus(), + ctx: { + common: input.parent.common, + data: input.data, + parsedType: getParsedType2(input.data), + schemaErrorMap: this._def.errorMap, + path: input.path, + parent: input.parent + } + }; + } + _parseSync(input) { + const result = this._parse(input); + if (isAsync(result)) { + throw new Error("Synchronous parse encountered promise."); + } + return result; + } + _parseAsync(input) { + const result = this._parse(input); + return Promise.resolve(result); + } + parse(data, params) { + const result = this.safeParse(data, params); + if (result.success) return result.data; + throw result.error; + } + safeParse(data, params) { + const ctx = { + common: { + issues: [], + async: params?.async ?? false, + contextualErrorMap: params?.errorMap + }, + path: params?.path || [], + schemaErrorMap: this._def.errorMap, + parent: null, + data, + parsedType: getParsedType2(data) + }; + const result = this._parseSync({ + data, + path: ctx.path, + parent: ctx + }); + return handleResult(ctx, result); + } + "~validate"(data) { + const ctx = { + common: { + issues: [], + async: !!this["~standard"].async + }, + path: [], + schemaErrorMap: this._def.errorMap, + parent: null, + data, + parsedType: getParsedType2(data) + }; + if (!this["~standard"].async) { + try { + const result = this._parseSync({ + data, + path: [], + parent: ctx + }); + return isValid(result) ? { + value: result.value + } : { + issues: ctx.common.issues + }; + } catch (err) { + if (err?.message?.toLowerCase()?.includes("encountered")) { + this["~standard"].async = true; + } + ctx.common = { + issues: [], + async: true + }; + } + } + return this._parseAsync({ + data, + path: [], + parent: ctx + }).then((result) => isValid(result) ? { + value: result.value + } : { + issues: ctx.common.issues + }); + } + async parseAsync(data, params) { + const result = await this.safeParseAsync(data, params); + if (result.success) return result.data; + throw result.error; + } + async safeParseAsync(data, params) { + const ctx = { + common: { + issues: [], + contextualErrorMap: params?.errorMap, + async: true + }, + path: params?.path || [], + schemaErrorMap: this._def.errorMap, + parent: null, + data, + parsedType: getParsedType2(data) + }; + const maybeAsyncResult = this._parse({ + data, + path: ctx.path, + parent: ctx + }); + const result = await (isAsync(maybeAsyncResult) ? maybeAsyncResult : Promise.resolve(maybeAsyncResult)); + return handleResult(ctx, result); + } + refine(check2, message) { + const getIssueProperties = /* @__PURE__ */ __name((val) => { + if (typeof message === "string" || typeof message === "undefined") { + return { + message + }; + } else if (typeof message === "function") { + return message(val); + } else { + return message; + } + }, "getIssueProperties"); + return this._refinement((val, ctx) => { + const result = check2(val); + const setError = /* @__PURE__ */ __name(() => ctx.addIssue({ + code: ZodIssueCode2.custom, + ...getIssueProperties(val) + }), "setError"); + if (typeof Promise !== "undefined" && result instanceof Promise) { + return result.then((data) => { + if (!data) { + setError(); + return false; + } else { + return true; + } + }); + } + if (!result) { + setError(); + return false; + } else { + return true; + } + }); + } + refinement(check2, refinementData) { + return this._refinement((val, ctx) => { + if (!check2(val)) { + ctx.addIssue(typeof refinementData === "function" ? refinementData(val, ctx) : refinementData); + return false; + } else { + return true; + } + }); + } + _refinement(refinement) { + return new ZodEffects({ + schema: this, + typeName: ZodFirstPartyTypeKind2.ZodEffects, + effect: { + type: "refinement", + refinement + } + }); + } + superRefine(refinement) { + return this._refinement(refinement); + } + constructor(def) { + this.spa = this.safeParseAsync; + this._def = def; + this.parse = this.parse.bind(this); + this.safeParse = this.safeParse.bind(this); + this.parseAsync = this.parseAsync.bind(this); + this.safeParseAsync = this.safeParseAsync.bind(this); + this.spa = this.spa.bind(this); + this.refine = this.refine.bind(this); + this.refinement = this.refinement.bind(this); + this.superRefine = this.superRefine.bind(this); + this.optional = this.optional.bind(this); + this.nullable = this.nullable.bind(this); + this.nullish = this.nullish.bind(this); + this.array = this.array.bind(this); + this.promise = this.promise.bind(this); + this.or = this.or.bind(this); + this.and = this.and.bind(this); + this.transform = this.transform.bind(this); + this.brand = this.brand.bind(this); + this.default = this.default.bind(this); + this.catch = this.catch.bind(this); + this.describe = this.describe.bind(this); + this.pipe = this.pipe.bind(this); + this.readonly = this.readonly.bind(this); + this.isNullable = this.isNullable.bind(this); + this.isOptional = this.isOptional.bind(this); + this["~standard"] = { + version: 1, + vendor: "zod", + validate: /* @__PURE__ */ __name((data) => this["~validate"](data), "validate") + }; + } + optional() { + return ZodOptional2.create(this, this._def); + } + nullable() { + return ZodNullable2.create(this, this._def); + } + nullish() { + return this.nullable().optional(); + } + array() { + return ZodArray2.create(this); + } + promise() { + return ZodPromise2.create(this, this._def); + } + or(option) { + return ZodUnion2.create([ + this, + option + ], this._def); + } + and(incoming) { + return ZodIntersection2.create(this, incoming, this._def); + } + transform(transform2) { + return new ZodEffects({ + ...processCreateParams(this._def), + schema: this, + typeName: ZodFirstPartyTypeKind2.ZodEffects, + effect: { + type: "transform", + transform: transform2 + } + }); + } + default(def) { + const defaultValueFunc = typeof def === "function" ? def : () => def; + return new ZodDefault2({ + ...processCreateParams(this._def), + innerType: this, + defaultValue: defaultValueFunc, + typeName: ZodFirstPartyTypeKind2.ZodDefault + }); + } + brand() { + return new ZodBranded({ + typeName: ZodFirstPartyTypeKind2.ZodBranded, + type: this, + ...processCreateParams(this._def) + }); + } + catch(def) { + const catchValueFunc = typeof def === "function" ? def : () => def; + return new ZodCatch2({ + ...processCreateParams(this._def), + innerType: this, + catchValue: catchValueFunc, + typeName: ZodFirstPartyTypeKind2.ZodCatch + }); + } + describe(description) { + const This = this.constructor; + return new This({ + ...this._def, + description + }); + } + pipe(target) { + return ZodPipeline.create(this, target); + } + readonly() { + return ZodReadonly2.create(this); + } + isOptional() { + return this.safeParse(void 0).success; + } + isNullable() { + return this.safeParse(null).success; + } +}; +var cuidRegex = /^c[^\\s-]{8,}\$/i; +var cuid2Regex = /^[0-9a-z]+\$/; +var ulidRegex = /^[0-9A-HJKMNP-TV-Z]{26}\$/i; +var uuidRegex = /^[0-9a-fA-F]{8}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{12}\$/i; +var nanoidRegex = /^[a-z0-9_-]{21}\$/i; +var jwtRegex = /^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*\$/; +var durationRegex = /^[-+]?P(?!\$)(?:(?:[-+]?\\d+Y)|(?:[-+]?\\d+[.,]\\d+Y\$))?(?:(?:[-+]?\\d+M)|(?:[-+]?\\d+[.,]\\d+M\$))?(?:(?:[-+]?\\d+W)|(?:[-+]?\\d+[.,]\\d+W\$))?(?:(?:[-+]?\\d+D)|(?:[-+]?\\d+[.,]\\d+D\$))?(?:T(?=[\\d+-])(?:(?:[-+]?\\d+H)|(?:[-+]?\\d+[.,]\\d+H\$))?(?:(?:[-+]?\\d+M)|(?:[-+]?\\d+[.,]\\d+M\$))?(?:[-+]?\\d+(?:[.,]\\d+)?S)?)??\$/; +var emailRegex = /^(?!\\.)(?!.*\\.\\.)([A-Z0-9_'+\\-\\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\\-]*\\.)+[A-Z]{2,}\$/i; +var _emojiRegex = \`^(\\\\p{Extended_Pictographic}|\\\\p{Emoji_Component})+\$\`; +var emojiRegex; +var ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\$/; +var ipv4CidrRegex = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\/(3[0-2]|[12]?[0-9])\$/; +var ipv6Regex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\$/; +var ipv6CidrRegex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])\$/; +var base64Regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?\$/; +var base64urlRegex = /^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?\$/; +var dateRegexSource = \`((\\\\d\\\\d[2468][048]|\\\\d\\\\d[13579][26]|\\\\d\\\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\\\d|30)|(02)-(0[1-9]|1\\\\d|2[0-8])))\`; +var dateRegex = new RegExp(\`^\${dateRegexSource}\$\`); +function timeRegexSource(args) { + let secondsRegexSource = \`[0-5]\\\\d\`; + if (args.precision) { + secondsRegexSource = \`\${secondsRegexSource}\\\\.\\\\d{\${args.precision}}\`; + } else if (args.precision == null) { + secondsRegexSource = \`\${secondsRegexSource}(\\\\.\\\\d+)?\`; + } + const secondsQuantifier = args.precision ? "+" : "?"; + return \`([01]\\\\d|2[0-3]):[0-5]\\\\d(:\${secondsRegexSource})\${secondsQuantifier}\`; +} +__name(timeRegexSource, "timeRegexSource"); +function timeRegex(args) { + return new RegExp(\`^\${timeRegexSource(args)}\$\`); +} +__name(timeRegex, "timeRegex"); +function datetimeRegex(args) { + let regex = \`\${dateRegexSource}T\${timeRegexSource(args)}\`; + const opts = []; + opts.push(args.local ? \`Z?\` : \`Z\`); + if (args.offset) opts.push(\`([+-]\\\\d{2}:?\\\\d{2})\`); + regex = \`\${regex}(\${opts.join("|")})\`; + return new RegExp(\`^\${regex}\$\`); +} +__name(datetimeRegex, "datetimeRegex"); +function isValidIP(ip, version2) { + if ((version2 === "v4" || !version2) && ipv4Regex.test(ip)) { + return true; + } + if ((version2 === "v6" || !version2) && ipv6Regex.test(ip)) { + return true; + } + return false; +} +__name(isValidIP, "isValidIP"); +function isValidJWT2(jwt2, alg) { + if (!jwtRegex.test(jwt2)) return false; + try { + const [header] = jwt2.split("."); + if (!header) return false; + const base643 = header.replace(/-/g, "+").replace(/_/g, "/").padEnd(header.length + (4 - header.length % 4) % 4, "="); + const decoded = JSON.parse(atob(base643)); + if (typeof decoded !== "object" || decoded === null) return false; + if ("typ" in decoded && decoded?.typ !== "JWT") return false; + if (!decoded.alg) return false; + if (alg && decoded.alg !== alg) return false; + return true; + } catch { + return false; + } +} +__name(isValidJWT2, "isValidJWT"); +function isValidCidr(ip, version2) { + if ((version2 === "v4" || !version2) && ipv4CidrRegex.test(ip)) { + return true; + } + if ((version2 === "v6" || !version2) && ipv6CidrRegex.test(ip)) { + return true; + } + return false; +} +__name(isValidCidr, "isValidCidr"); +var ZodString2 = class _ZodString2 extends ZodType2 { + static { + __name(this, "ZodString"); + } + _parse(input) { + if (this._def.coerce) { + input.data = String(input.data); + } + const parsedType7 = this._getType(input); + if (parsedType7 !== ZodParsedType.string) { + const ctx2 = this._getOrReturnCtx(input); + addIssueToContext(ctx2, { + code: ZodIssueCode2.invalid_type, + expected: ZodParsedType.string, + received: ctx2.parsedType + }); + return INVALID; + } + const status = new ParseStatus(); + let ctx = void 0; + for (const check2 of this._def.checks) { + if (check2.kind === "min") { + if (input.data.length < check2.value) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode2.too_small, + minimum: check2.value, + type: "string", + inclusive: true, + exact: false, + message: check2.message + }); + status.dirty(); + } + } else if (check2.kind === "max") { + if (input.data.length > check2.value) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode2.too_big, + maximum: check2.value, + type: "string", + inclusive: true, + exact: false, + message: check2.message + }); + status.dirty(); + } + } else if (check2.kind === "length") { + const tooBig = input.data.length > check2.value; + const tooSmall = input.data.length < check2.value; + if (tooBig || tooSmall) { + ctx = this._getOrReturnCtx(input, ctx); + if (tooBig) { + addIssueToContext(ctx, { + code: ZodIssueCode2.too_big, + maximum: check2.value, + type: "string", + inclusive: true, + exact: true, + message: check2.message + }); + } else if (tooSmall) { + addIssueToContext(ctx, { + code: ZodIssueCode2.too_small, + minimum: check2.value, + type: "string", + inclusive: true, + exact: true, + message: check2.message + }); + } + status.dirty(); + } + } else if (check2.kind === "email") { + if (!emailRegex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + validation: "email", + code: ZodIssueCode2.invalid_string, + message: check2.message + }); + status.dirty(); + } + } else if (check2.kind === "emoji") { + if (!emojiRegex) { + emojiRegex = new RegExp(_emojiRegex, "u"); + } + if (!emojiRegex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + validation: "emoji", + code: ZodIssueCode2.invalid_string, + message: check2.message + }); + status.dirty(); + } + } else if (check2.kind === "uuid") { + if (!uuidRegex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + validation: "uuid", + code: ZodIssueCode2.invalid_string, + message: check2.message + }); + status.dirty(); + } + } else if (check2.kind === "nanoid") { + if (!nanoidRegex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + validation: "nanoid", + code: ZodIssueCode2.invalid_string, + message: check2.message + }); + status.dirty(); + } + } else if (check2.kind === "cuid") { + if (!cuidRegex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + validation: "cuid", + code: ZodIssueCode2.invalid_string, + message: check2.message + }); + status.dirty(); + } + } else if (check2.kind === "cuid2") { + if (!cuid2Regex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + validation: "cuid2", + code: ZodIssueCode2.invalid_string, + message: check2.message + }); + status.dirty(); + } + } else if (check2.kind === "ulid") { + if (!ulidRegex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + validation: "ulid", + code: ZodIssueCode2.invalid_string, + message: check2.message + }); + status.dirty(); + } + } else if (check2.kind === "url") { + try { + new URL(input.data); + } catch { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + validation: "url", + code: ZodIssueCode2.invalid_string, + message: check2.message + }); + status.dirty(); + } + } else if (check2.kind === "regex") { + check2.regex.lastIndex = 0; + const testResult = check2.regex.test(input.data); + if (!testResult) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + validation: "regex", + code: ZodIssueCode2.invalid_string, + message: check2.message + }); + status.dirty(); + } + } else if (check2.kind === "trim") { + input.data = input.data.trim(); + } else if (check2.kind === "includes") { + if (!input.data.includes(check2.value, check2.position)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode2.invalid_string, + validation: { + includes: check2.value, + position: check2.position + }, + message: check2.message + }); + status.dirty(); + } + } else if (check2.kind === "toLowerCase") { + input.data = input.data.toLowerCase(); + } else if (check2.kind === "toUpperCase") { + input.data = input.data.toUpperCase(); + } else if (check2.kind === "startsWith") { + if (!input.data.startsWith(check2.value)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode2.invalid_string, + validation: { + startsWith: check2.value + }, + message: check2.message + }); + status.dirty(); + } + } else if (check2.kind === "endsWith") { + if (!input.data.endsWith(check2.value)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode2.invalid_string, + validation: { + endsWith: check2.value + }, + message: check2.message + }); + status.dirty(); + } + } else if (check2.kind === "datetime") { + const regex = datetimeRegex(check2); + if (!regex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode2.invalid_string, + validation: "datetime", + message: check2.message + }); + status.dirty(); + } + } else if (check2.kind === "date") { + const regex = dateRegex; + if (!regex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode2.invalid_string, + validation: "date", + message: check2.message + }); + status.dirty(); + } + } else if (check2.kind === "time") { + const regex = timeRegex(check2); + if (!regex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode2.invalid_string, + validation: "time", + message: check2.message + }); + status.dirty(); + } + } else if (check2.kind === "duration") { + if (!durationRegex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + validation: "duration", + code: ZodIssueCode2.invalid_string, + message: check2.message + }); + status.dirty(); + } + } else if (check2.kind === "ip") { + if (!isValidIP(input.data, check2.version)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + validation: "ip", + code: ZodIssueCode2.invalid_string, + message: check2.message + }); + status.dirty(); + } + } else if (check2.kind === "jwt") { + if (!isValidJWT2(input.data, check2.alg)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + validation: "jwt", + code: ZodIssueCode2.invalid_string, + message: check2.message + }); + status.dirty(); + } + } else if (check2.kind === "cidr") { + if (!isValidCidr(input.data, check2.version)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + validation: "cidr", + code: ZodIssueCode2.invalid_string, + message: check2.message + }); + status.dirty(); + } + } else if (check2.kind === "base64") { + if (!base64Regex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + validation: "base64", + code: ZodIssueCode2.invalid_string, + message: check2.message + }); + status.dirty(); + } + } else if (check2.kind === "base64url") { + if (!base64urlRegex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + validation: "base64url", + code: ZodIssueCode2.invalid_string, + message: check2.message + }); + status.dirty(); + } + } else { + util.assertNever(check2); + } + } + return { + status: status.value, + value: input.data + }; + } + _regex(regex, validation, message) { + return this.refinement((data) => regex.test(data), { + validation, + code: ZodIssueCode2.invalid_string, + ...errorUtil.errToObj(message) + }); + } + _addCheck(check2) { + return new _ZodString2({ + ...this._def, + checks: [ + ...this._def.checks, + check2 + ] + }); + } + email(message) { + return this._addCheck({ + kind: "email", + ...errorUtil.errToObj(message) + }); + } + url(message) { + return this._addCheck({ + kind: "url", + ...errorUtil.errToObj(message) + }); + } + emoji(message) { + return this._addCheck({ + kind: "emoji", + ...errorUtil.errToObj(message) + }); + } + uuid(message) { + return this._addCheck({ + kind: "uuid", + ...errorUtil.errToObj(message) + }); + } + nanoid(message) { + return this._addCheck({ + kind: "nanoid", + ...errorUtil.errToObj(message) + }); + } + cuid(message) { + return this._addCheck({ + kind: "cuid", + ...errorUtil.errToObj(message) + }); + } + cuid2(message) { + return this._addCheck({ + kind: "cuid2", + ...errorUtil.errToObj(message) + }); + } + ulid(message) { + return this._addCheck({ + kind: "ulid", + ...errorUtil.errToObj(message) + }); + } + base64(message) { + return this._addCheck({ + kind: "base64", + ...errorUtil.errToObj(message) + }); + } + base64url(message) { + return this._addCheck({ + kind: "base64url", + ...errorUtil.errToObj(message) + }); + } + jwt(options) { + return this._addCheck({ + kind: "jwt", + ...errorUtil.errToObj(options) + }); + } + ip(options) { + return this._addCheck({ + kind: "ip", + ...errorUtil.errToObj(options) + }); + } + cidr(options) { + return this._addCheck({ + kind: "cidr", + ...errorUtil.errToObj(options) + }); + } + datetime(options) { + if (typeof options === "string") { + return this._addCheck({ + kind: "datetime", + precision: null, + offset: false, + local: false, + message: options + }); + } + return this._addCheck({ + kind: "datetime", + precision: typeof options?.precision === "undefined" ? null : options?.precision, + offset: options?.offset ?? false, + local: options?.local ?? false, + ...errorUtil.errToObj(options?.message) + }); + } + date(message) { + return this._addCheck({ + kind: "date", + message + }); + } + time(options) { + if (typeof options === "string") { + return this._addCheck({ + kind: "time", + precision: null, + message: options + }); + } + return this._addCheck({ + kind: "time", + precision: typeof options?.precision === "undefined" ? null : options?.precision, + ...errorUtil.errToObj(options?.message) + }); + } + duration(message) { + return this._addCheck({ + kind: "duration", + ...errorUtil.errToObj(message) + }); + } + regex(regex, message) { + return this._addCheck({ + kind: "regex", + regex, + ...errorUtil.errToObj(message) + }); + } + includes(value, options) { + return this._addCheck({ + kind: "includes", + value, + position: options?.position, + ...errorUtil.errToObj(options?.message) + }); + } + startsWith(value, message) { + return this._addCheck({ + kind: "startsWith", + value, + ...errorUtil.errToObj(message) + }); + } + endsWith(value, message) { + return this._addCheck({ + kind: "endsWith", + value, + ...errorUtil.errToObj(message) + }); + } + min(minLength, message) { + return this._addCheck({ + kind: "min", + value: minLength, + ...errorUtil.errToObj(message) + }); + } + max(maxLength, message) { + return this._addCheck({ + kind: "max", + value: maxLength, + ...errorUtil.errToObj(message) + }); + } + length(len, message) { + return this._addCheck({ + kind: "length", + value: len, + ...errorUtil.errToObj(message) + }); + } + /** + * Equivalent to \`.min(1)\` + */ + nonempty(message) { + return this.min(1, errorUtil.errToObj(message)); + } + trim() { + return new _ZodString2({ + ...this._def, + checks: [ + ...this._def.checks, + { + kind: "trim" + } + ] + }); + } + toLowerCase() { + return new _ZodString2({ + ...this._def, + checks: [ + ...this._def.checks, + { + kind: "toLowerCase" + } + ] + }); + } + toUpperCase() { + return new _ZodString2({ + ...this._def, + checks: [ + ...this._def.checks, + { + kind: "toUpperCase" + } + ] + }); + } + get isDatetime() { + return !!this._def.checks.find((ch) => ch.kind === "datetime"); + } + get isDate() { + return !!this._def.checks.find((ch) => ch.kind === "date"); + } + get isTime() { + return !!this._def.checks.find((ch) => ch.kind === "time"); + } + get isDuration() { + return !!this._def.checks.find((ch) => ch.kind === "duration"); + } + get isEmail() { + return !!this._def.checks.find((ch) => ch.kind === "email"); + } + get isURL() { + return !!this._def.checks.find((ch) => ch.kind === "url"); + } + get isEmoji() { + return !!this._def.checks.find((ch) => ch.kind === "emoji"); + } + get isUUID() { + return !!this._def.checks.find((ch) => ch.kind === "uuid"); + } + get isNANOID() { + return !!this._def.checks.find((ch) => ch.kind === "nanoid"); + } + get isCUID() { + return !!this._def.checks.find((ch) => ch.kind === "cuid"); + } + get isCUID2() { + return !!this._def.checks.find((ch) => ch.kind === "cuid2"); + } + get isULID() { + return !!this._def.checks.find((ch) => ch.kind === "ulid"); + } + get isIP() { + return !!this._def.checks.find((ch) => ch.kind === "ip"); + } + get isCIDR() { + return !!this._def.checks.find((ch) => ch.kind === "cidr"); + } + get isBase64() { + return !!this._def.checks.find((ch) => ch.kind === "base64"); + } + get isBase64url() { + return !!this._def.checks.find((ch) => ch.kind === "base64url"); + } + get minLength() { + let min = null; + for (const ch of this._def.checks) { + if (ch.kind === "min") { + if (min === null || ch.value > min) min = ch.value; + } + } + return min; + } + get maxLength() { + let max = null; + for (const ch of this._def.checks) { + if (ch.kind === "max") { + if (max === null || ch.value < max) max = ch.value; + } + } + return max; + } +}; +ZodString2.create = (params) => { + return new ZodString2({ + checks: [], + typeName: ZodFirstPartyTypeKind2.ZodString, + coerce: params?.coerce ?? false, + ...processCreateParams(params) + }); +}; +function floatSafeRemainder2(val, step) { + const valDecCount = (val.toString().split(".")[1] || "").length; + const stepDecCount = (step.toString().split(".")[1] || "").length; + const decCount = valDecCount > stepDecCount ? valDecCount : stepDecCount; + const valInt = Number.parseInt(val.toFixed(decCount).replace(".", "")); + const stepInt = Number.parseInt(step.toFixed(decCount).replace(".", "")); + return valInt % stepInt / 10 ** decCount; +} +__name(floatSafeRemainder2, "floatSafeRemainder"); +var ZodNumber2 = class _ZodNumber extends ZodType2 { + static { + __name(this, "ZodNumber"); + } + constructor() { + super(...arguments); + this.min = this.gte; + this.max = this.lte; + this.step = this.multipleOf; + } + _parse(input) { + if (this._def.coerce) { + input.data = Number(input.data); + } + const parsedType7 = this._getType(input); + if (parsedType7 !== ZodParsedType.number) { + const ctx2 = this._getOrReturnCtx(input); + addIssueToContext(ctx2, { + code: ZodIssueCode2.invalid_type, + expected: ZodParsedType.number, + received: ctx2.parsedType + }); + return INVALID; + } + let ctx = void 0; + const status = new ParseStatus(); + for (const check2 of this._def.checks) { + if (check2.kind === "int") { + if (!util.isInteger(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode2.invalid_type, + expected: "integer", + received: "float", + message: check2.message + }); + status.dirty(); + } + } else if (check2.kind === "min") { + const tooSmall = check2.inclusive ? input.data < check2.value : input.data <= check2.value; + if (tooSmall) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode2.too_small, + minimum: check2.value, + type: "number", + inclusive: check2.inclusive, + exact: false, + message: check2.message + }); + status.dirty(); + } + } else if (check2.kind === "max") { + const tooBig = check2.inclusive ? input.data > check2.value : input.data >= check2.value; + if (tooBig) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode2.too_big, + maximum: check2.value, + type: "number", + inclusive: check2.inclusive, + exact: false, + message: check2.message + }); + status.dirty(); + } + } else if (check2.kind === "multipleOf") { + if (floatSafeRemainder2(input.data, check2.value) !== 0) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode2.not_multiple_of, + multipleOf: check2.value, + message: check2.message + }); + status.dirty(); + } + } else if (check2.kind === "finite") { + if (!Number.isFinite(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode2.not_finite, + message: check2.message + }); + status.dirty(); + } + } else { + util.assertNever(check2); + } + } + return { + status: status.value, + value: input.data + }; + } + gte(value, message) { + return this.setLimit("min", value, true, errorUtil.toString(message)); + } + gt(value, message) { + return this.setLimit("min", value, false, errorUtil.toString(message)); + } + lte(value, message) { + return this.setLimit("max", value, true, errorUtil.toString(message)); + } + lt(value, message) { + return this.setLimit("max", value, false, errorUtil.toString(message)); + } + setLimit(kind, value, inclusive, message) { + return new _ZodNumber({ + ...this._def, + checks: [ + ...this._def.checks, + { + kind, + value, + inclusive, + message: errorUtil.toString(message) + } + ] + }); + } + _addCheck(check2) { + return new _ZodNumber({ + ...this._def, + checks: [ + ...this._def.checks, + check2 + ] + }); + } + int(message) { + return this._addCheck({ + kind: "int", + message: errorUtil.toString(message) + }); + } + positive(message) { + return this._addCheck({ + kind: "min", + value: 0, + inclusive: false, + message: errorUtil.toString(message) + }); + } + negative(message) { + return this._addCheck({ + kind: "max", + value: 0, + inclusive: false, + message: errorUtil.toString(message) + }); + } + nonpositive(message) { + return this._addCheck({ + kind: "max", + value: 0, + inclusive: true, + message: errorUtil.toString(message) + }); + } + nonnegative(message) { + return this._addCheck({ + kind: "min", + value: 0, + inclusive: true, + message: errorUtil.toString(message) + }); + } + multipleOf(value, message) { + return this._addCheck({ + kind: "multipleOf", + value, + message: errorUtil.toString(message) + }); + } + finite(message) { + return this._addCheck({ + kind: "finite", + message: errorUtil.toString(message) + }); + } + safe(message) { + return this._addCheck({ + kind: "min", + inclusive: true, + value: Number.MIN_SAFE_INTEGER, + message: errorUtil.toString(message) + })._addCheck({ + kind: "max", + inclusive: true, + value: Number.MAX_SAFE_INTEGER, + message: errorUtil.toString(message) + }); + } + get minValue() { + let min = null; + for (const ch of this._def.checks) { + if (ch.kind === "min") { + if (min === null || ch.value > min) min = ch.value; + } + } + return min; + } + get maxValue() { + let max = null; + for (const ch of this._def.checks) { + if (ch.kind === "max") { + if (max === null || ch.value < max) max = ch.value; + } + } + return max; + } + get isInt() { + return !!this._def.checks.find((ch) => ch.kind === "int" || ch.kind === "multipleOf" && util.isInteger(ch.value)); + } + get isFinite() { + let max = null; + let min = null; + for (const ch of this._def.checks) { + if (ch.kind === "finite" || ch.kind === "int" || ch.kind === "multipleOf") { + return true; + } else if (ch.kind === "min") { + if (min === null || ch.value > min) min = ch.value; + } else if (ch.kind === "max") { + if (max === null || ch.value < max) max = ch.value; + } + } + return Number.isFinite(min) && Number.isFinite(max); + } +}; +ZodNumber2.create = (params) => { + return new ZodNumber2({ + checks: [], + typeName: ZodFirstPartyTypeKind2.ZodNumber, + coerce: params?.coerce || false, + ...processCreateParams(params) + }); +}; +var ZodBigInt2 = class _ZodBigInt extends ZodType2 { + static { + __name(this, "ZodBigInt"); + } + constructor() { + super(...arguments); + this.min = this.gte; + this.max = this.lte; + } + _parse(input) { + if (this._def.coerce) { + try { + input.data = BigInt(input.data); + } catch { + return this._getInvalidInput(input); + } + } + const parsedType7 = this._getType(input); + if (parsedType7 !== ZodParsedType.bigint) { + return this._getInvalidInput(input); + } + let ctx = void 0; + const status = new ParseStatus(); + for (const check2 of this._def.checks) { + if (check2.kind === "min") { + const tooSmall = check2.inclusive ? input.data < check2.value : input.data <= check2.value; + if (tooSmall) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode2.too_small, + type: "bigint", + minimum: check2.value, + inclusive: check2.inclusive, + message: check2.message + }); + status.dirty(); + } + } else if (check2.kind === "max") { + const tooBig = check2.inclusive ? input.data > check2.value : input.data >= check2.value; + if (tooBig) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode2.too_big, + type: "bigint", + maximum: check2.value, + inclusive: check2.inclusive, + message: check2.message + }); + status.dirty(); + } + } else if (check2.kind === "multipleOf") { + if (input.data % check2.value !== BigInt(0)) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode2.not_multiple_of, + multipleOf: check2.value, + message: check2.message + }); + status.dirty(); + } + } else { + util.assertNever(check2); + } + } + return { + status: status.value, + value: input.data + }; + } + _getInvalidInput(input) { + const ctx = this._getOrReturnCtx(input); + addIssueToContext(ctx, { + code: ZodIssueCode2.invalid_type, + expected: ZodParsedType.bigint, + received: ctx.parsedType + }); + return INVALID; + } + gte(value, message) { + return this.setLimit("min", value, true, errorUtil.toString(message)); + } + gt(value, message) { + return this.setLimit("min", value, false, errorUtil.toString(message)); + } + lte(value, message) { + return this.setLimit("max", value, true, errorUtil.toString(message)); + } + lt(value, message) { + return this.setLimit("max", value, false, errorUtil.toString(message)); + } + setLimit(kind, value, inclusive, message) { + return new _ZodBigInt({ + ...this._def, + checks: [ + ...this._def.checks, + { + kind, + value, + inclusive, + message: errorUtil.toString(message) + } + ] + }); + } + _addCheck(check2) { + return new _ZodBigInt({ + ...this._def, + checks: [ + ...this._def.checks, + check2 + ] + }); + } + positive(message) { + return this._addCheck({ + kind: "min", + value: BigInt(0), + inclusive: false, + message: errorUtil.toString(message) + }); + } + negative(message) { + return this._addCheck({ + kind: "max", + value: BigInt(0), + inclusive: false, + message: errorUtil.toString(message) + }); + } + nonpositive(message) { + return this._addCheck({ + kind: "max", + value: BigInt(0), + inclusive: true, + message: errorUtil.toString(message) + }); + } + nonnegative(message) { + return this._addCheck({ + kind: "min", + value: BigInt(0), + inclusive: true, + message: errorUtil.toString(message) + }); + } + multipleOf(value, message) { + return this._addCheck({ + kind: "multipleOf", + value, + message: errorUtil.toString(message) + }); + } + get minValue() { + let min = null; + for (const ch of this._def.checks) { + if (ch.kind === "min") { + if (min === null || ch.value > min) min = ch.value; + } + } + return min; + } + get maxValue() { + let max = null; + for (const ch of this._def.checks) { + if (ch.kind === "max") { + if (max === null || ch.value < max) max = ch.value; + } + } + return max; + } +}; +ZodBigInt2.create = (params) => { + return new ZodBigInt2({ + checks: [], + typeName: ZodFirstPartyTypeKind2.ZodBigInt, + coerce: params?.coerce ?? false, + ...processCreateParams(params) + }); +}; +var ZodBoolean2 = class extends ZodType2 { + static { + __name(this, "ZodBoolean"); + } + _parse(input) { + if (this._def.coerce) { + input.data = Boolean(input.data); + } + const parsedType7 = this._getType(input); + if (parsedType7 !== ZodParsedType.boolean) { + const ctx = this._getOrReturnCtx(input); + addIssueToContext(ctx, { + code: ZodIssueCode2.invalid_type, + expected: ZodParsedType.boolean, + received: ctx.parsedType + }); + return INVALID; + } + return OK(input.data); + } +}; +ZodBoolean2.create = (params) => { + return new ZodBoolean2({ + typeName: ZodFirstPartyTypeKind2.ZodBoolean, + coerce: params?.coerce || false, + ...processCreateParams(params) + }); +}; +var ZodDate2 = class _ZodDate extends ZodType2 { + static { + __name(this, "ZodDate"); + } + _parse(input) { + if (this._def.coerce) { + input.data = new Date(input.data); + } + const parsedType7 = this._getType(input); + if (parsedType7 !== ZodParsedType.date) { + const ctx2 = this._getOrReturnCtx(input); + addIssueToContext(ctx2, { + code: ZodIssueCode2.invalid_type, + expected: ZodParsedType.date, + received: ctx2.parsedType + }); + return INVALID; + } + if (Number.isNaN(input.data.getTime())) { + const ctx2 = this._getOrReturnCtx(input); + addIssueToContext(ctx2, { + code: ZodIssueCode2.invalid_date + }); + return INVALID; + } + const status = new ParseStatus(); + let ctx = void 0; + for (const check2 of this._def.checks) { + if (check2.kind === "min") { + if (input.data.getTime() < check2.value) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode2.too_small, + message: check2.message, + inclusive: true, + exact: false, + minimum: check2.value, + type: "date" + }); + status.dirty(); + } + } else if (check2.kind === "max") { + if (input.data.getTime() > check2.value) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode2.too_big, + message: check2.message, + inclusive: true, + exact: false, + maximum: check2.value, + type: "date" + }); + status.dirty(); + } + } else { + util.assertNever(check2); + } + } + return { + status: status.value, + value: new Date(input.data.getTime()) + }; + } + _addCheck(check2) { + return new _ZodDate({ + ...this._def, + checks: [ + ...this._def.checks, + check2 + ] + }); + } + min(minDate, message) { + return this._addCheck({ + kind: "min", + value: minDate.getTime(), + message: errorUtil.toString(message) + }); + } + max(maxDate, message) { + return this._addCheck({ + kind: "max", + value: maxDate.getTime(), + message: errorUtil.toString(message) + }); + } + get minDate() { + let min = null; + for (const ch of this._def.checks) { + if (ch.kind === "min") { + if (min === null || ch.value > min) min = ch.value; + } + } + return min != null ? new Date(min) : null; + } + get maxDate() { + let max = null; + for (const ch of this._def.checks) { + if (ch.kind === "max") { + if (max === null || ch.value < max) max = ch.value; + } + } + return max != null ? new Date(max) : null; + } +}; +ZodDate2.create = (params) => { + return new ZodDate2({ + checks: [], + coerce: params?.coerce || false, + typeName: ZodFirstPartyTypeKind2.ZodDate, + ...processCreateParams(params) + }); +}; +var ZodSymbol2 = class extends ZodType2 { + static { + __name(this, "ZodSymbol"); + } + _parse(input) { + const parsedType7 = this._getType(input); + if (parsedType7 !== ZodParsedType.symbol) { + const ctx = this._getOrReturnCtx(input); + addIssueToContext(ctx, { + code: ZodIssueCode2.invalid_type, + expected: ZodParsedType.symbol, + received: ctx.parsedType + }); + return INVALID; + } + return OK(input.data); + } +}; +ZodSymbol2.create = (params) => { + return new ZodSymbol2({ + typeName: ZodFirstPartyTypeKind2.ZodSymbol, + ...processCreateParams(params) + }); +}; +var ZodUndefined2 = class extends ZodType2 { + static { + __name(this, "ZodUndefined"); + } + _parse(input) { + const parsedType7 = this._getType(input); + if (parsedType7 !== ZodParsedType.undefined) { + const ctx = this._getOrReturnCtx(input); + addIssueToContext(ctx, { + code: ZodIssueCode2.invalid_type, + expected: ZodParsedType.undefined, + received: ctx.parsedType + }); + return INVALID; + } + return OK(input.data); + } +}; +ZodUndefined2.create = (params) => { + return new ZodUndefined2({ + typeName: ZodFirstPartyTypeKind2.ZodUndefined, + ...processCreateParams(params) + }); +}; +var ZodNull2 = class extends ZodType2 { + static { + __name(this, "ZodNull"); + } + _parse(input) { + const parsedType7 = this._getType(input); + if (parsedType7 !== ZodParsedType.null) { + const ctx = this._getOrReturnCtx(input); + addIssueToContext(ctx, { + code: ZodIssueCode2.invalid_type, + expected: ZodParsedType.null, + received: ctx.parsedType + }); + return INVALID; + } + return OK(input.data); + } +}; +ZodNull2.create = (params) => { + return new ZodNull2({ + typeName: ZodFirstPartyTypeKind2.ZodNull, + ...processCreateParams(params) + }); +}; +var ZodAny2 = class extends ZodType2 { + static { + __name(this, "ZodAny"); + } + constructor() { + super(...arguments); + this._any = true; + } + _parse(input) { + return OK(input.data); + } +}; +ZodAny2.create = (params) => { + return new ZodAny2({ + typeName: ZodFirstPartyTypeKind2.ZodAny, + ...processCreateParams(params) + }); +}; +var ZodUnknown2 = class extends ZodType2 { + static { + __name(this, "ZodUnknown"); + } + constructor() { + super(...arguments); + this._unknown = true; + } + _parse(input) { + return OK(input.data); + } +}; +ZodUnknown2.create = (params) => { + return new ZodUnknown2({ + typeName: ZodFirstPartyTypeKind2.ZodUnknown, + ...processCreateParams(params) + }); +}; +var ZodNever2 = class extends ZodType2 { + static { + __name(this, "ZodNever"); + } + _parse(input) { + const ctx = this._getOrReturnCtx(input); + addIssueToContext(ctx, { + code: ZodIssueCode2.invalid_type, + expected: ZodParsedType.never, + received: ctx.parsedType + }); + return INVALID; + } +}; +ZodNever2.create = (params) => { + return new ZodNever2({ + typeName: ZodFirstPartyTypeKind2.ZodNever, + ...processCreateParams(params) + }); +}; +var ZodVoid2 = class extends ZodType2 { + static { + __name(this, "ZodVoid"); + } + _parse(input) { + const parsedType7 = this._getType(input); + if (parsedType7 !== ZodParsedType.undefined) { + const ctx = this._getOrReturnCtx(input); + addIssueToContext(ctx, { + code: ZodIssueCode2.invalid_type, + expected: ZodParsedType.void, + received: ctx.parsedType + }); + return INVALID; + } + return OK(input.data); + } +}; +ZodVoid2.create = (params) => { + return new ZodVoid2({ + typeName: ZodFirstPartyTypeKind2.ZodVoid, + ...processCreateParams(params) + }); +}; +var ZodArray2 = class _ZodArray extends ZodType2 { + static { + __name(this, "ZodArray"); + } + _parse(input) { + const { ctx, status } = this._processInputParams(input); + const def = this._def; + if (ctx.parsedType !== ZodParsedType.array) { + addIssueToContext(ctx, { + code: ZodIssueCode2.invalid_type, + expected: ZodParsedType.array, + received: ctx.parsedType + }); + return INVALID; + } + if (def.exactLength !== null) { + const tooBig = ctx.data.length > def.exactLength.value; + const tooSmall = ctx.data.length < def.exactLength.value; + if (tooBig || tooSmall) { + addIssueToContext(ctx, { + code: tooBig ? ZodIssueCode2.too_big : ZodIssueCode2.too_small, + minimum: tooSmall ? def.exactLength.value : void 0, + maximum: tooBig ? def.exactLength.value : void 0, + type: "array", + inclusive: true, + exact: true, + message: def.exactLength.message + }); + status.dirty(); + } + } + if (def.minLength !== null) { + if (ctx.data.length < def.minLength.value) { + addIssueToContext(ctx, { + code: ZodIssueCode2.too_small, + minimum: def.minLength.value, + type: "array", + inclusive: true, + exact: false, + message: def.minLength.message + }); + status.dirty(); + } + } + if (def.maxLength !== null) { + if (ctx.data.length > def.maxLength.value) { + addIssueToContext(ctx, { + code: ZodIssueCode2.too_big, + maximum: def.maxLength.value, + type: "array", + inclusive: true, + exact: false, + message: def.maxLength.message + }); + status.dirty(); + } + } + if (ctx.common.async) { + return Promise.all([ + ...ctx.data + ].map((item, i) => { + return def.type._parseAsync(new ParseInputLazyPath(ctx, item, ctx.path, i)); + })).then((result2) => { + return ParseStatus.mergeArray(status, result2); + }); + } + const result = [ + ...ctx.data + ].map((item, i) => { + return def.type._parseSync(new ParseInputLazyPath(ctx, item, ctx.path, i)); + }); + return ParseStatus.mergeArray(status, result); + } + get element() { + return this._def.type; + } + min(minLength, message) { + return new _ZodArray({ + ...this._def, + minLength: { + value: minLength, + message: errorUtil.toString(message) + } + }); + } + max(maxLength, message) { + return new _ZodArray({ + ...this._def, + maxLength: { + value: maxLength, + message: errorUtil.toString(message) + } + }); + } + length(len, message) { + return new _ZodArray({ + ...this._def, + exactLength: { + value: len, + message: errorUtil.toString(message) + } + }); + } + nonempty(message) { + return this.min(1, message); + } +}; +ZodArray2.create = (schema, params) => { + return new ZodArray2({ + type: schema, + minLength: null, + maxLength: null, + exactLength: null, + typeName: ZodFirstPartyTypeKind2.ZodArray, + ...processCreateParams(params) + }); +}; +function deepPartialify(schema) { + if (schema instanceof ZodObject2) { + const newShape = {}; + for (const key in schema.shape) { + const fieldSchema = schema.shape[key]; + newShape[key] = ZodOptional2.create(deepPartialify(fieldSchema)); + } + return new ZodObject2({ + ...schema._def, + shape: /* @__PURE__ */ __name(() => newShape, "shape") + }); + } else if (schema instanceof ZodArray2) { + return new ZodArray2({ + ...schema._def, + type: deepPartialify(schema.element) + }); + } else if (schema instanceof ZodOptional2) { + return ZodOptional2.create(deepPartialify(schema.unwrap())); + } else if (schema instanceof ZodNullable2) { + return ZodNullable2.create(deepPartialify(schema.unwrap())); + } else if (schema instanceof ZodTuple2) { + return ZodTuple2.create(schema.items.map((item) => deepPartialify(item))); + } else { + return schema; + } +} +__name(deepPartialify, "deepPartialify"); +var ZodObject2 = class _ZodObject extends ZodType2 { + static { + __name(this, "ZodObject"); + } + constructor() { + super(...arguments); + this._cached = null; + this.nonstrict = this.passthrough; + this.augment = this.extend; + } + _getCached() { + if (this._cached !== null) return this._cached; + const shape = this._def.shape(); + const keys = util.objectKeys(shape); + this._cached = { + shape, + keys + }; + return this._cached; + } + _parse(input) { + const parsedType7 = this._getType(input); + if (parsedType7 !== ZodParsedType.object) { + const ctx2 = this._getOrReturnCtx(input); + addIssueToContext(ctx2, { + code: ZodIssueCode2.invalid_type, + expected: ZodParsedType.object, + received: ctx2.parsedType + }); + return INVALID; + } + const { status, ctx } = this._processInputParams(input); + const { shape, keys: shapeKeys } = this._getCached(); + const extraKeys = []; + if (!(this._def.catchall instanceof ZodNever2 && this._def.unknownKeys === "strip")) { + for (const key in ctx.data) { + if (!shapeKeys.includes(key)) { + extraKeys.push(key); + } + } + } + const pairs = []; + for (const key of shapeKeys) { + const keyValidator = shape[key]; + const value = ctx.data[key]; + pairs.push({ + key: { + status: "valid", + value: key + }, + value: keyValidator._parse(new ParseInputLazyPath(ctx, value, ctx.path, key)), + alwaysSet: key in ctx.data + }); + } + if (this._def.catchall instanceof ZodNever2) { + const unknownKeys = this._def.unknownKeys; + if (unknownKeys === "passthrough") { + for (const key of extraKeys) { + pairs.push({ + key: { + status: "valid", + value: key + }, + value: { + status: "valid", + value: ctx.data[key] + } + }); + } + } else if (unknownKeys === "strict") { + if (extraKeys.length > 0) { + addIssueToContext(ctx, { + code: ZodIssueCode2.unrecognized_keys, + keys: extraKeys + }); + status.dirty(); + } + } else if (unknownKeys === "strip") { + } else { + throw new Error(\`Internal ZodObject error: invalid unknownKeys value.\`); + } + } else { + const catchall = this._def.catchall; + for (const key of extraKeys) { + const value = ctx.data[key]; + pairs.push({ + key: { + status: "valid", + value: key + }, + value: catchall._parse( + new ParseInputLazyPath(ctx, value, ctx.path, key) + //, ctx.child(key), value, getParsedType(value) + ), + alwaysSet: key in ctx.data + }); + } + } + if (ctx.common.async) { + return Promise.resolve().then(async () => { + const syncPairs = []; + for (const pair of pairs) { + const key = await pair.key; + const value = await pair.value; + syncPairs.push({ + key, + value, + alwaysSet: pair.alwaysSet + }); + } + return syncPairs; + }).then((syncPairs) => { + return ParseStatus.mergeObjectSync(status, syncPairs); + }); + } else { + return ParseStatus.mergeObjectSync(status, pairs); + } + } + get shape() { + return this._def.shape(); + } + strict(message) { + errorUtil.errToObj; + return new _ZodObject({ + ...this._def, + unknownKeys: "strict", + ...message !== void 0 ? { + errorMap: /* @__PURE__ */ __name((issue2, ctx) => { + const defaultError = this._def.errorMap?.(issue2, ctx).message ?? ctx.defaultError; + if (issue2.code === "unrecognized_keys") return { + message: errorUtil.errToObj(message).message ?? defaultError + }; + return { + message: defaultError + }; + }, "errorMap") + } : {} + }); + } + strip() { + return new _ZodObject({ + ...this._def, + unknownKeys: "strip" + }); + } + passthrough() { + return new _ZodObject({ + ...this._def, + unknownKeys: "passthrough" + }); + } + // const AugmentFactory = + // (def: Def) => + // ( + // augmentation: Augmentation + // ): ZodObject< + // extendShape, Augmentation>, + // Def["unknownKeys"], + // Def["catchall"] + // > => { + // return new ZodObject({ + // ...def, + // shape: () => ({ + // ...def.shape(), + // ...augmentation, + // }), + // }) as any; + // }; + extend(augmentation) { + return new _ZodObject({ + ...this._def, + shape: /* @__PURE__ */ __name(() => ({ + ...this._def.shape(), + ...augmentation + }), "shape") + }); + } + /** + * Prior to zod@1.0.12 there was a bug in the + * inferred type of merged objects. Please + * upgrade if you are experiencing issues. + */ + merge(merging) { + const merged = new _ZodObject({ + unknownKeys: merging._def.unknownKeys, + catchall: merging._def.catchall, + shape: /* @__PURE__ */ __name(() => ({ + ...this._def.shape(), + ...merging._def.shape() + }), "shape"), + typeName: ZodFirstPartyTypeKind2.ZodObject + }); + return merged; + } + // merge< + // Incoming extends AnyZodObject, + // Augmentation extends Incoming["shape"], + // NewOutput extends { + // [k in keyof Augmentation | keyof Output]: k extends keyof Augmentation + // ? Augmentation[k]["_output"] + // : k extends keyof Output + // ? Output[k] + // : never; + // }, + // NewInput extends { + // [k in keyof Augmentation | keyof Input]: k extends keyof Augmentation + // ? Augmentation[k]["_input"] + // : k extends keyof Input + // ? Input[k] + // : never; + // } + // >( + // merging: Incoming + // ): ZodObject< + // extendShape>, + // Incoming["_def"]["unknownKeys"], + // Incoming["_def"]["catchall"], + // NewOutput, + // NewInput + // > { + // const merged: any = new ZodObject({ + // unknownKeys: merging._def.unknownKeys, + // catchall: merging._def.catchall, + // shape: () => + // objectUtil.mergeShapes(this._def.shape(), merging._def.shape()), + // typeName: ZodFirstPartyTypeKind.ZodObject, + // }) as any; + // return merged; + // } + setKey(key, schema) { + return this.augment({ + [key]: schema + }); + } + // merge( + // merging: Incoming + // ): //ZodObject = (merging) => { + // ZodObject< + // extendShape>, + // Incoming["_def"]["unknownKeys"], + // Incoming["_def"]["catchall"] + // > { + // // const mergedShape = objectUtil.mergeShapes( + // // this._def.shape(), + // // merging._def.shape() + // // ); + // const merged: any = new ZodObject({ + // unknownKeys: merging._def.unknownKeys, + // catchall: merging._def.catchall, + // shape: () => + // objectUtil.mergeShapes(this._def.shape(), merging._def.shape()), + // typeName: ZodFirstPartyTypeKind.ZodObject, + // }) as any; + // return merged; + // } + catchall(index) { + return new _ZodObject({ + ...this._def, + catchall: index + }); + } + pick(mask) { + const shape = {}; + for (const key of util.objectKeys(mask)) { + if (mask[key] && this.shape[key]) { + shape[key] = this.shape[key]; + } + } + return new _ZodObject({ + ...this._def, + shape: /* @__PURE__ */ __name(() => shape, "shape") + }); + } + omit(mask) { + const shape = {}; + for (const key of util.objectKeys(this.shape)) { + if (!mask[key]) { + shape[key] = this.shape[key]; + } + } + return new _ZodObject({ + ...this._def, + shape: /* @__PURE__ */ __name(() => shape, "shape") + }); + } + /** + * @deprecated + */ + deepPartial() { + return deepPartialify(this); + } + partial(mask) { + const newShape = {}; + for (const key of util.objectKeys(this.shape)) { + const fieldSchema = this.shape[key]; + if (mask && !mask[key]) { + newShape[key] = fieldSchema; + } else { + newShape[key] = fieldSchema.optional(); + } + } + return new _ZodObject({ + ...this._def, + shape: /* @__PURE__ */ __name(() => newShape, "shape") + }); + } + required(mask) { + const newShape = {}; + for (const key of util.objectKeys(this.shape)) { + if (mask && !mask[key]) { + newShape[key] = this.shape[key]; + } else { + const fieldSchema = this.shape[key]; + let newField = fieldSchema; + while (newField instanceof ZodOptional2) { + newField = newField._def.innerType; + } + newShape[key] = newField; + } + } + return new _ZodObject({ + ...this._def, + shape: /* @__PURE__ */ __name(() => newShape, "shape") + }); + } + keyof() { + return createZodEnum(util.objectKeys(this.shape)); + } +}; +ZodObject2.create = (shape, params) => { + return new ZodObject2({ + shape: /* @__PURE__ */ __name(() => shape, "shape"), + unknownKeys: "strip", + catchall: ZodNever2.create(), + typeName: ZodFirstPartyTypeKind2.ZodObject, + ...processCreateParams(params) + }); +}; +ZodObject2.strictCreate = (shape, params) => { + return new ZodObject2({ + shape: /* @__PURE__ */ __name(() => shape, "shape"), + unknownKeys: "strict", + catchall: ZodNever2.create(), + typeName: ZodFirstPartyTypeKind2.ZodObject, + ...processCreateParams(params) + }); +}; +ZodObject2.lazycreate = (shape, params) => { + return new ZodObject2({ + shape, + unknownKeys: "strip", + catchall: ZodNever2.create(), + typeName: ZodFirstPartyTypeKind2.ZodObject, + ...processCreateParams(params) + }); +}; +var ZodUnion2 = class extends ZodType2 { + static { + __name(this, "ZodUnion"); + } + _parse(input) { + const { ctx } = this._processInputParams(input); + const options = this._def.options; + function handleResults(results) { + for (const result of results) { + if (result.result.status === "valid") { + return result.result; + } + } + for (const result of results) { + if (result.result.status === "dirty") { + ctx.common.issues.push(...result.ctx.common.issues); + return result.result; + } + } + const unionErrors = results.map((result) => new ZodError2(result.ctx.common.issues)); + addIssueToContext(ctx, { + code: ZodIssueCode2.invalid_union, + unionErrors + }); + return INVALID; + } + __name(handleResults, "handleResults"); + if (ctx.common.async) { + return Promise.all(options.map(async (option) => { + const childCtx = { + ...ctx, + common: { + ...ctx.common, + issues: [] + }, + parent: null + }; + return { + result: await option._parseAsync({ + data: ctx.data, + path: ctx.path, + parent: childCtx + }), + ctx: childCtx + }; + })).then(handleResults); + } else { + let dirty = void 0; + const issues = []; + for (const option of options) { + const childCtx = { + ...ctx, + common: { + ...ctx.common, + issues: [] + }, + parent: null + }; + const result = option._parseSync({ + data: ctx.data, + path: ctx.path, + parent: childCtx + }); + if (result.status === "valid") { + return result; + } else if (result.status === "dirty" && !dirty) { + dirty = { + result, + ctx: childCtx + }; + } + if (childCtx.common.issues.length) { + issues.push(childCtx.common.issues); + } + } + if (dirty) { + ctx.common.issues.push(...dirty.ctx.common.issues); + return dirty.result; + } + const unionErrors = issues.map((issues2) => new ZodError2(issues2)); + addIssueToContext(ctx, { + code: ZodIssueCode2.invalid_union, + unionErrors + }); + return INVALID; + } + } + get options() { + return this._def.options; + } +}; +ZodUnion2.create = (types, params) => { + return new ZodUnion2({ + options: types, + typeName: ZodFirstPartyTypeKind2.ZodUnion, + ...processCreateParams(params) + }); +}; +var getDiscriminator = /* @__PURE__ */ __name((type) => { + if (type instanceof ZodLazy2) { + return getDiscriminator(type.schema); + } else if (type instanceof ZodEffects) { + return getDiscriminator(type.innerType()); + } else if (type instanceof ZodLiteral2) { + return [ + type.value + ]; + } else if (type instanceof ZodEnum2) { + return type.options; + } else if (type instanceof ZodNativeEnum) { + return util.objectValues(type.enum); + } else if (type instanceof ZodDefault2) { + return getDiscriminator(type._def.innerType); + } else if (type instanceof ZodUndefined2) { + return [ + void 0 + ]; + } else if (type instanceof ZodNull2) { + return [ + null + ]; + } else if (type instanceof ZodOptional2) { + return [ + void 0, + ...getDiscriminator(type.unwrap()) + ]; + } else if (type instanceof ZodNullable2) { + return [ + null, + ...getDiscriminator(type.unwrap()) + ]; + } else if (type instanceof ZodBranded) { + return getDiscriminator(type.unwrap()); + } else if (type instanceof ZodReadonly2) { + return getDiscriminator(type.unwrap()); + } else if (type instanceof ZodCatch2) { + return getDiscriminator(type._def.innerType); + } else { + return []; + } +}, "getDiscriminator"); +var ZodDiscriminatedUnion2 = class _ZodDiscriminatedUnion extends ZodType2 { + static { + __name(this, "ZodDiscriminatedUnion"); + } + _parse(input) { + const { ctx } = this._processInputParams(input); + if (ctx.parsedType !== ZodParsedType.object) { + addIssueToContext(ctx, { + code: ZodIssueCode2.invalid_type, + expected: ZodParsedType.object, + received: ctx.parsedType + }); + return INVALID; + } + const discriminator = this.discriminator; + const discriminatorValue = ctx.data[discriminator]; + const option = this.optionsMap.get(discriminatorValue); + if (!option) { + addIssueToContext(ctx, { + code: ZodIssueCode2.invalid_union_discriminator, + options: Array.from(this.optionsMap.keys()), + path: [ + discriminator + ] + }); + return INVALID; + } + if (ctx.common.async) { + return option._parseAsync({ + data: ctx.data, + path: ctx.path, + parent: ctx + }); + } else { + return option._parseSync({ + data: ctx.data, + path: ctx.path, + parent: ctx + }); + } + } + get discriminator() { + return this._def.discriminator; + } + get options() { + return this._def.options; + } + get optionsMap() { + return this._def.optionsMap; + } + /** + * The constructor of the discriminated union schema. Its behaviour is very similar to that of the normal z.union() constructor. + * However, it only allows a union of objects, all of which need to share a discriminator property. This property must + * have a different value for each object in the union. + * @param discriminator the name of the discriminator property + * @param types an array of object schemas + * @param params + */ + static create(discriminator, options, params) { + const optionsMap = /* @__PURE__ */ new Map(); + for (const type of options) { + const discriminatorValues = getDiscriminator(type.shape[discriminator]); + if (!discriminatorValues.length) { + throw new Error(\`A discriminator value for key \\\`\${discriminator}\\\` could not be extracted from all schema options\`); + } + for (const value of discriminatorValues) { + if (optionsMap.has(value)) { + throw new Error(\`Discriminator property \${String(discriminator)} has duplicate value \${String(value)}\`); + } + optionsMap.set(value, type); + } + } + return new _ZodDiscriminatedUnion({ + typeName: ZodFirstPartyTypeKind2.ZodDiscriminatedUnion, + discriminator, + options, + optionsMap, + ...processCreateParams(params) + }); + } +}; +function mergeValues2(a, b) { + const aType = getParsedType2(a); + const bType = getParsedType2(b); + if (a === b) { + return { + valid: true, + data: a + }; + } else if (aType === ZodParsedType.object && bType === ZodParsedType.object) { + const bKeys = util.objectKeys(b); + const sharedKeys = util.objectKeys(a).filter((key) => bKeys.indexOf(key) !== -1); + const newObj = { + ...a, + ...b + }; + for (const key of sharedKeys) { + const sharedValue = mergeValues2(a[key], b[key]); + if (!sharedValue.valid) { + return { + valid: false + }; + } + newObj[key] = sharedValue.data; + } + return { + valid: true, + data: newObj + }; + } else if (aType === ZodParsedType.array && bType === ZodParsedType.array) { + if (a.length !== b.length) { + return { + valid: false + }; + } + const newArray = []; + for (let index = 0; index < a.length; index++) { + const itemA = a[index]; + const itemB = b[index]; + const sharedValue = mergeValues2(itemA, itemB); + if (!sharedValue.valid) { + return { + valid: false + }; + } + newArray.push(sharedValue.data); + } + return { + valid: true, + data: newArray + }; + } else if (aType === ZodParsedType.date && bType === ZodParsedType.date && +a === +b) { + return { + valid: true, + data: a + }; + } else { + return { + valid: false + }; + } +} +__name(mergeValues2, "mergeValues"); +var ZodIntersection2 = class extends ZodType2 { + static { + __name(this, "ZodIntersection"); + } + _parse(input) { + const { status, ctx } = this._processInputParams(input); + const handleParsed = /* @__PURE__ */ __name((parsedLeft, parsedRight) => { + if (isAborted(parsedLeft) || isAborted(parsedRight)) { + return INVALID; + } + const merged = mergeValues2(parsedLeft.value, parsedRight.value); + if (!merged.valid) { + addIssueToContext(ctx, { + code: ZodIssueCode2.invalid_intersection_types + }); + return INVALID; + } + if (isDirty(parsedLeft) || isDirty(parsedRight)) { + status.dirty(); + } + return { + status: status.value, + value: merged.data + }; + }, "handleParsed"); + if (ctx.common.async) { + return Promise.all([ + this._def.left._parseAsync({ + data: ctx.data, + path: ctx.path, + parent: ctx + }), + this._def.right._parseAsync({ + data: ctx.data, + path: ctx.path, + parent: ctx + }) + ]).then(([left, right]) => handleParsed(left, right)); + } else { + return handleParsed(this._def.left._parseSync({ + data: ctx.data, + path: ctx.path, + parent: ctx + }), this._def.right._parseSync({ + data: ctx.data, + path: ctx.path, + parent: ctx + })); + } + } +}; +ZodIntersection2.create = (left, right, params) => { + return new ZodIntersection2({ + left, + right, + typeName: ZodFirstPartyTypeKind2.ZodIntersection, + ...processCreateParams(params) + }); +}; +var ZodTuple2 = class _ZodTuple extends ZodType2 { + static { + __name(this, "ZodTuple"); + } + _parse(input) { + const { status, ctx } = this._processInputParams(input); + if (ctx.parsedType !== ZodParsedType.array) { + addIssueToContext(ctx, { + code: ZodIssueCode2.invalid_type, + expected: ZodParsedType.array, + received: ctx.parsedType + }); + return INVALID; + } + if (ctx.data.length < this._def.items.length) { + addIssueToContext(ctx, { + code: ZodIssueCode2.too_small, + minimum: this._def.items.length, + inclusive: true, + exact: false, + type: "array" + }); + return INVALID; + } + const rest = this._def.rest; + if (!rest && ctx.data.length > this._def.items.length) { + addIssueToContext(ctx, { + code: ZodIssueCode2.too_big, + maximum: this._def.items.length, + inclusive: true, + exact: false, + type: "array" + }); + status.dirty(); + } + const items = [ + ...ctx.data + ].map((item, itemIndex) => { + const schema = this._def.items[itemIndex] || this._def.rest; + if (!schema) return null; + return schema._parse(new ParseInputLazyPath(ctx, item, ctx.path, itemIndex)); + }).filter((x) => !!x); + if (ctx.common.async) { + return Promise.all(items).then((results) => { + return ParseStatus.mergeArray(status, results); + }); + } else { + return ParseStatus.mergeArray(status, items); + } + } + get items() { + return this._def.items; + } + rest(rest) { + return new _ZodTuple({ + ...this._def, + rest + }); + } +}; +ZodTuple2.create = (schemas, params) => { + if (!Array.isArray(schemas)) { + throw new Error("You must pass an array of schemas to z.tuple([ ... ])"); + } + return new ZodTuple2({ + items: schemas, + typeName: ZodFirstPartyTypeKind2.ZodTuple, + rest: null, + ...processCreateParams(params) + }); +}; +var ZodRecord2 = class _ZodRecord extends ZodType2 { + static { + __name(this, "ZodRecord"); + } + get keySchema() { + return this._def.keyType; + } + get valueSchema() { + return this._def.valueType; + } + _parse(input) { + const { status, ctx } = this._processInputParams(input); + if (ctx.parsedType !== ZodParsedType.object) { + addIssueToContext(ctx, { + code: ZodIssueCode2.invalid_type, + expected: ZodParsedType.object, + received: ctx.parsedType + }); + return INVALID; + } + const pairs = []; + const keyType = this._def.keyType; + const valueType = this._def.valueType; + for (const key in ctx.data) { + pairs.push({ + key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, key)), + value: valueType._parse(new ParseInputLazyPath(ctx, ctx.data[key], ctx.path, key)), + alwaysSet: key in ctx.data + }); + } + if (ctx.common.async) { + return ParseStatus.mergeObjectAsync(status, pairs); + } else { + return ParseStatus.mergeObjectSync(status, pairs); + } + } + get element() { + return this._def.valueType; + } + static create(first, second, third) { + if (second instanceof ZodType2) { + return new _ZodRecord({ + keyType: first, + valueType: second, + typeName: ZodFirstPartyTypeKind2.ZodRecord, + ...processCreateParams(third) + }); + } + return new _ZodRecord({ + keyType: ZodString2.create(), + valueType: first, + typeName: ZodFirstPartyTypeKind2.ZodRecord, + ...processCreateParams(second) + }); + } +}; +var ZodMap2 = class extends ZodType2 { + static { + __name(this, "ZodMap"); + } + get keySchema() { + return this._def.keyType; + } + get valueSchema() { + return this._def.valueType; + } + _parse(input) { + const { status, ctx } = this._processInputParams(input); + if (ctx.parsedType !== ZodParsedType.map) { + addIssueToContext(ctx, { + code: ZodIssueCode2.invalid_type, + expected: ZodParsedType.map, + received: ctx.parsedType + }); + return INVALID; + } + const keyType = this._def.keyType; + const valueType = this._def.valueType; + const pairs = [ + ...ctx.data.entries() + ].map(([key, value], index) => { + return { + key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, [ + index, + "key" + ])), + value: valueType._parse(new ParseInputLazyPath(ctx, value, ctx.path, [ + index, + "value" + ])) + }; + }); + if (ctx.common.async) { + const finalMap = /* @__PURE__ */ new Map(); + return Promise.resolve().then(async () => { + for (const pair of pairs) { + const key = await pair.key; + const value = await pair.value; + if (key.status === "aborted" || value.status === "aborted") { + return INVALID; + } + if (key.status === "dirty" || value.status === "dirty") { + status.dirty(); + } + finalMap.set(key.value, value.value); + } + return { + status: status.value, + value: finalMap + }; + }); + } else { + const finalMap = /* @__PURE__ */ new Map(); + for (const pair of pairs) { + const key = pair.key; + const value = pair.value; + if (key.status === "aborted" || value.status === "aborted") { + return INVALID; + } + if (key.status === "dirty" || value.status === "dirty") { + status.dirty(); + } + finalMap.set(key.value, value.value); + } + return { + status: status.value, + value: finalMap + }; + } + } +}; +ZodMap2.create = (keyType, valueType, params) => { + return new ZodMap2({ + valueType, + keyType, + typeName: ZodFirstPartyTypeKind2.ZodMap, + ...processCreateParams(params) + }); +}; +var ZodSet2 = class _ZodSet extends ZodType2 { + static { + __name(this, "ZodSet"); + } + _parse(input) { + const { status, ctx } = this._processInputParams(input); + if (ctx.parsedType !== ZodParsedType.set) { + addIssueToContext(ctx, { + code: ZodIssueCode2.invalid_type, + expected: ZodParsedType.set, + received: ctx.parsedType + }); + return INVALID; + } + const def = this._def; + if (def.minSize !== null) { + if (ctx.data.size < def.minSize.value) { + addIssueToContext(ctx, { + code: ZodIssueCode2.too_small, + minimum: def.minSize.value, + type: "set", + inclusive: true, + exact: false, + message: def.minSize.message + }); + status.dirty(); + } + } + if (def.maxSize !== null) { + if (ctx.data.size > def.maxSize.value) { + addIssueToContext(ctx, { + code: ZodIssueCode2.too_big, + maximum: def.maxSize.value, + type: "set", + inclusive: true, + exact: false, + message: def.maxSize.message + }); + status.dirty(); + } + } + const valueType = this._def.valueType; + function finalizeSet(elements2) { + const parsedSet = /* @__PURE__ */ new Set(); + for (const element of elements2) { + if (element.status === "aborted") return INVALID; + if (element.status === "dirty") status.dirty(); + parsedSet.add(element.value); + } + return { + status: status.value, + value: parsedSet + }; + } + __name(finalizeSet, "finalizeSet"); + const elements = [ + ...ctx.data.values() + ].map((item, i) => valueType._parse(new ParseInputLazyPath(ctx, item, ctx.path, i))); + if (ctx.common.async) { + return Promise.all(elements).then((elements2) => finalizeSet(elements2)); + } else { + return finalizeSet(elements); + } + } + min(minSize, message) { + return new _ZodSet({ + ...this._def, + minSize: { + value: minSize, + message: errorUtil.toString(message) + } + }); + } + max(maxSize, message) { + return new _ZodSet({ + ...this._def, + maxSize: { + value: maxSize, + message: errorUtil.toString(message) + } + }); + } + size(size, message) { + return this.min(size, message).max(size, message); + } + nonempty(message) { + return this.min(1, message); + } +}; +ZodSet2.create = (valueType, params) => { + return new ZodSet2({ + valueType, + minSize: null, + maxSize: null, + typeName: ZodFirstPartyTypeKind2.ZodSet, + ...processCreateParams(params) + }); +}; +var ZodFunction2 = class _ZodFunction extends ZodType2 { + static { + __name(this, "ZodFunction"); + } + constructor() { + super(...arguments); + this.validate = this.implement; + } + _parse(input) { + const { ctx } = this._processInputParams(input); + if (ctx.parsedType !== ZodParsedType.function) { + addIssueToContext(ctx, { + code: ZodIssueCode2.invalid_type, + expected: ZodParsedType.function, + received: ctx.parsedType + }); + return INVALID; + } + function makeArgsIssue(args, error45) { + return makeIssue({ + data: args, + path: ctx.path, + errorMaps: [ + ctx.common.contextualErrorMap, + ctx.schemaErrorMap, + getErrorMap2(), + en_default2 + ].filter((x) => !!x), + issueData: { + code: ZodIssueCode2.invalid_arguments, + argumentsError: error45 + } + }); + } + __name(makeArgsIssue, "makeArgsIssue"); + function makeReturnsIssue(returns, error45) { + return makeIssue({ + data: returns, + path: ctx.path, + errorMaps: [ + ctx.common.contextualErrorMap, + ctx.schemaErrorMap, + getErrorMap2(), + en_default2 + ].filter((x) => !!x), + issueData: { + code: ZodIssueCode2.invalid_return_type, + returnTypeError: error45 + } + }); + } + __name(makeReturnsIssue, "makeReturnsIssue"); + const params = { + errorMap: ctx.common.contextualErrorMap + }; + const fn = ctx.data; + if (this._def.returns instanceof ZodPromise2) { + const me = this; + return OK(async function(...args) { + const error45 = new ZodError2([]); + const parsedArgs = await me._def.args.parseAsync(args, params).catch((e) => { + error45.addIssue(makeArgsIssue(args, e)); + throw error45; + }); + const result = await Reflect.apply(fn, this, parsedArgs); + const parsedReturns = await me._def.returns._def.type.parseAsync(result, params).catch((e) => { + error45.addIssue(makeReturnsIssue(result, e)); + throw error45; + }); + return parsedReturns; + }); + } else { + const me = this; + return OK(function(...args) { + const parsedArgs = me._def.args.safeParse(args, params); + if (!parsedArgs.success) { + throw new ZodError2([ + makeArgsIssue(args, parsedArgs.error) + ]); + } + const result = Reflect.apply(fn, this, parsedArgs.data); + const parsedReturns = me._def.returns.safeParse(result, params); + if (!parsedReturns.success) { + throw new ZodError2([ + makeReturnsIssue(result, parsedReturns.error) + ]); + } + return parsedReturns.data; + }); + } + } + parameters() { + return this._def.args; + } + returnType() { + return this._def.returns; + } + args(...items) { + return new _ZodFunction({ + ...this._def, + args: ZodTuple2.create(items).rest(ZodUnknown2.create()) + }); + } + returns(returnType) { + return new _ZodFunction({ + ...this._def, + returns: returnType + }); + } + implement(func) { + const validatedFunc = this.parse(func); + return validatedFunc; + } + strictImplement(func) { + const validatedFunc = this.parse(func); + return validatedFunc; + } + static create(args, returns, params) { + return new _ZodFunction({ + args: args ? args : ZodTuple2.create([]).rest(ZodUnknown2.create()), + returns: returns || ZodUnknown2.create(), + typeName: ZodFirstPartyTypeKind2.ZodFunction, + ...processCreateParams(params) + }); + } +}; +var ZodLazy2 = class extends ZodType2 { + static { + __name(this, "ZodLazy"); + } + get schema() { + return this._def.getter(); + } + _parse(input) { + const { ctx } = this._processInputParams(input); + const lazySchema = this._def.getter(); + return lazySchema._parse({ + data: ctx.data, + path: ctx.path, + parent: ctx + }); + } +}; +ZodLazy2.create = (getter, params) => { + return new ZodLazy2({ + getter, + typeName: ZodFirstPartyTypeKind2.ZodLazy, + ...processCreateParams(params) + }); +}; +var ZodLiteral2 = class extends ZodType2 { + static { + __name(this, "ZodLiteral"); + } + _parse(input) { + if (input.data !== this._def.value) { + const ctx = this._getOrReturnCtx(input); + addIssueToContext(ctx, { + received: ctx.data, + code: ZodIssueCode2.invalid_literal, + expected: this._def.value + }); + return INVALID; + } + return { + status: "valid", + value: input.data + }; + } + get value() { + return this._def.value; + } +}; +ZodLiteral2.create = (value, params) => { + return new ZodLiteral2({ + value, + typeName: ZodFirstPartyTypeKind2.ZodLiteral, + ...processCreateParams(params) + }); +}; +function createZodEnum(values, params) { + return new ZodEnum2({ + values, + typeName: ZodFirstPartyTypeKind2.ZodEnum, + ...processCreateParams(params) + }); +} +__name(createZodEnum, "createZodEnum"); +var ZodEnum2 = class _ZodEnum extends ZodType2 { + static { + __name(this, "ZodEnum"); + } + _parse(input) { + if (typeof input.data !== "string") { + const ctx = this._getOrReturnCtx(input); + const expectedValues = this._def.values; + addIssueToContext(ctx, { + expected: util.joinValues(expectedValues), + received: ctx.parsedType, + code: ZodIssueCode2.invalid_type + }); + return INVALID; + } + if (!this._cache) { + this._cache = new Set(this._def.values); + } + if (!this._cache.has(input.data)) { + const ctx = this._getOrReturnCtx(input); + const expectedValues = this._def.values; + addIssueToContext(ctx, { + received: ctx.data, + code: ZodIssueCode2.invalid_enum_value, + options: expectedValues + }); + return INVALID; + } + return OK(input.data); + } + get options() { + return this._def.values; + } + get enum() { + const enumValues = {}; + for (const val of this._def.values) { + enumValues[val] = val; + } + return enumValues; + } + get Values() { + const enumValues = {}; + for (const val of this._def.values) { + enumValues[val] = val; + } + return enumValues; + } + get Enum() { + const enumValues = {}; + for (const val of this._def.values) { + enumValues[val] = val; + } + return enumValues; + } + extract(values, newDef = this._def) { + return _ZodEnum.create(values, { + ...this._def, + ...newDef + }); + } + exclude(values, newDef = this._def) { + return _ZodEnum.create(this.options.filter((opt) => !values.includes(opt)), { + ...this._def, + ...newDef + }); + } +}; +ZodEnum2.create = createZodEnum; +var ZodNativeEnum = class extends ZodType2 { + static { + __name(this, "ZodNativeEnum"); + } + _parse(input) { + const nativeEnumValues = util.getValidEnumValues(this._def.values); + const ctx = this._getOrReturnCtx(input); + if (ctx.parsedType !== ZodParsedType.string && ctx.parsedType !== ZodParsedType.number) { + const expectedValues = util.objectValues(nativeEnumValues); + addIssueToContext(ctx, { + expected: util.joinValues(expectedValues), + received: ctx.parsedType, + code: ZodIssueCode2.invalid_type + }); + return INVALID; + } + if (!this._cache) { + this._cache = new Set(util.getValidEnumValues(this._def.values)); + } + if (!this._cache.has(input.data)) { + const expectedValues = util.objectValues(nativeEnumValues); + addIssueToContext(ctx, { + received: ctx.data, + code: ZodIssueCode2.invalid_enum_value, + options: expectedValues + }); + return INVALID; + } + return OK(input.data); + } + get enum() { + return this._def.values; + } +}; +ZodNativeEnum.create = (values, params) => { + return new ZodNativeEnum({ + values, + typeName: ZodFirstPartyTypeKind2.ZodNativeEnum, + ...processCreateParams(params) + }); +}; +var ZodPromise2 = class extends ZodType2 { + static { + __name(this, "ZodPromise"); + } + unwrap() { + return this._def.type; + } + _parse(input) { + const { ctx } = this._processInputParams(input); + if (ctx.parsedType !== ZodParsedType.promise && ctx.common.async === false) { + addIssueToContext(ctx, { + code: ZodIssueCode2.invalid_type, + expected: ZodParsedType.promise, + received: ctx.parsedType + }); + return INVALID; + } + const promisified = ctx.parsedType === ZodParsedType.promise ? ctx.data : Promise.resolve(ctx.data); + return OK(promisified.then((data) => { + return this._def.type.parseAsync(data, { + path: ctx.path, + errorMap: ctx.common.contextualErrorMap + }); + })); + } +}; +ZodPromise2.create = (schema, params) => { + return new ZodPromise2({ + type: schema, + typeName: ZodFirstPartyTypeKind2.ZodPromise, + ...processCreateParams(params) + }); +}; +var ZodEffects = class extends ZodType2 { + static { + __name(this, "ZodEffects"); + } + innerType() { + return this._def.schema; + } + sourceType() { + return this._def.schema._def.typeName === ZodFirstPartyTypeKind2.ZodEffects ? this._def.schema.sourceType() : this._def.schema; + } + _parse(input) { + const { status, ctx } = this._processInputParams(input); + const effect = this._def.effect || null; + const checkCtx = { + addIssue: /* @__PURE__ */ __name((arg) => { + addIssueToContext(ctx, arg); + if (arg.fatal) { + status.abort(); + } else { + status.dirty(); + } + }, "addIssue"), + get path() { + return ctx.path; + } + }; + checkCtx.addIssue = checkCtx.addIssue.bind(checkCtx); + if (effect.type === "preprocess") { + const processed = effect.transform(ctx.data, checkCtx); + if (ctx.common.async) { + return Promise.resolve(processed).then(async (processed2) => { + if (status.value === "aborted") return INVALID; + const result = await this._def.schema._parseAsync({ + data: processed2, + path: ctx.path, + parent: ctx + }); + if (result.status === "aborted") return INVALID; + if (result.status === "dirty") return DIRTY(result.value); + if (status.value === "dirty") return DIRTY(result.value); + return result; + }); + } else { + if (status.value === "aborted") return INVALID; + const result = this._def.schema._parseSync({ + data: processed, + path: ctx.path, + parent: ctx + }); + if (result.status === "aborted") return INVALID; + if (result.status === "dirty") return DIRTY(result.value); + if (status.value === "dirty") return DIRTY(result.value); + return result; + } + } + if (effect.type === "refinement") { + const executeRefinement = /* @__PURE__ */ __name((acc) => { + const result = effect.refinement(acc, checkCtx); + if (ctx.common.async) { + return Promise.resolve(result); + } + if (result instanceof Promise) { + throw new Error("Async refinement encountered during synchronous parse operation. Use .parseAsync instead."); + } + return acc; + }, "executeRefinement"); + if (ctx.common.async === false) { + const inner = this._def.schema._parseSync({ + data: ctx.data, + path: ctx.path, + parent: ctx + }); + if (inner.status === "aborted") return INVALID; + if (inner.status === "dirty") status.dirty(); + executeRefinement(inner.value); + return { + status: status.value, + value: inner.value + }; + } else { + return this._def.schema._parseAsync({ + data: ctx.data, + path: ctx.path, + parent: ctx + }).then((inner) => { + if (inner.status === "aborted") return INVALID; + if (inner.status === "dirty") status.dirty(); + return executeRefinement(inner.value).then(() => { + return { + status: status.value, + value: inner.value + }; + }); + }); + } + } + if (effect.type === "transform") { + if (ctx.common.async === false) { + const base = this._def.schema._parseSync({ + data: ctx.data, + path: ctx.path, + parent: ctx + }); + if (!isValid(base)) return INVALID; + const result = effect.transform(base.value, checkCtx); + if (result instanceof Promise) { + throw new Error(\`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.\`); + } + return { + status: status.value, + value: result + }; + } else { + return this._def.schema._parseAsync({ + data: ctx.data, + path: ctx.path, + parent: ctx + }).then((base) => { + if (!isValid(base)) return INVALID; + return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({ + status: status.value, + value: result + })); + }); + } + } + util.assertNever(effect); + } +}; +ZodEffects.create = (schema, effect, params) => { + return new ZodEffects({ + schema, + typeName: ZodFirstPartyTypeKind2.ZodEffects, + effect, + ...processCreateParams(params) + }); +}; +ZodEffects.createWithPreprocess = (preprocess2, schema, params) => { + return new ZodEffects({ + schema, + effect: { + type: "preprocess", + transform: preprocess2 + }, + typeName: ZodFirstPartyTypeKind2.ZodEffects, + ...processCreateParams(params) + }); +}; +var ZodOptional2 = class extends ZodType2 { + static { + __name(this, "ZodOptional"); + } + _parse(input) { + const parsedType7 = this._getType(input); + if (parsedType7 === ZodParsedType.undefined) { + return OK(void 0); + } + return this._def.innerType._parse(input); + } + unwrap() { + return this._def.innerType; + } +}; +ZodOptional2.create = (type, params) => { + return new ZodOptional2({ + innerType: type, + typeName: ZodFirstPartyTypeKind2.ZodOptional, + ...processCreateParams(params) + }); +}; +var ZodNullable2 = class extends ZodType2 { + static { + __name(this, "ZodNullable"); + } + _parse(input) { + const parsedType7 = this._getType(input); + if (parsedType7 === ZodParsedType.null) { + return OK(null); + } + return this._def.innerType._parse(input); + } + unwrap() { + return this._def.innerType; + } +}; +ZodNullable2.create = (type, params) => { + return new ZodNullable2({ + innerType: type, + typeName: ZodFirstPartyTypeKind2.ZodNullable, + ...processCreateParams(params) + }); +}; +var ZodDefault2 = class extends ZodType2 { + static { + __name(this, "ZodDefault"); + } + _parse(input) { + const { ctx } = this._processInputParams(input); + let data = ctx.data; + if (ctx.parsedType === ZodParsedType.undefined) { + data = this._def.defaultValue(); + } + return this._def.innerType._parse({ + data, + path: ctx.path, + parent: ctx + }); + } + removeDefault() { + return this._def.innerType; + } +}; +ZodDefault2.create = (type, params) => { + return new ZodDefault2({ + innerType: type, + typeName: ZodFirstPartyTypeKind2.ZodDefault, + defaultValue: typeof params.default === "function" ? params.default : () => params.default, + ...processCreateParams(params) + }); +}; +var ZodCatch2 = class extends ZodType2 { + static { + __name(this, "ZodCatch"); + } + _parse(input) { + const { ctx } = this._processInputParams(input); + const newCtx = { + ...ctx, + common: { + ...ctx.common, + issues: [] + } + }; + const result = this._def.innerType._parse({ + data: newCtx.data, + path: newCtx.path, + parent: { + ...newCtx + } + }); + if (isAsync(result)) { + return result.then((result2) => { + return { + status: "valid", + value: result2.status === "valid" ? result2.value : this._def.catchValue({ + get error() { + return new ZodError2(newCtx.common.issues); + }, + input: newCtx.data + }) + }; + }); + } else { + return { + status: "valid", + value: result.status === "valid" ? result.value : this._def.catchValue({ + get error() { + return new ZodError2(newCtx.common.issues); + }, + input: newCtx.data + }) + }; + } + } + removeCatch() { + return this._def.innerType; + } +}; +ZodCatch2.create = (type, params) => { + return new ZodCatch2({ + innerType: type, + typeName: ZodFirstPartyTypeKind2.ZodCatch, + catchValue: typeof params.catch === "function" ? params.catch : () => params.catch, + ...processCreateParams(params) + }); +}; +var ZodNaN2 = class extends ZodType2 { + static { + __name(this, "ZodNaN"); + } + _parse(input) { + const parsedType7 = this._getType(input); + if (parsedType7 !== ZodParsedType.nan) { + const ctx = this._getOrReturnCtx(input); + addIssueToContext(ctx, { + code: ZodIssueCode2.invalid_type, + expected: ZodParsedType.nan, + received: ctx.parsedType + }); + return INVALID; + } + return { + status: "valid", + value: input.data + }; + } +}; +ZodNaN2.create = (params) => { + return new ZodNaN2({ + typeName: ZodFirstPartyTypeKind2.ZodNaN, + ...processCreateParams(params) + }); +}; +var BRAND = Symbol("zod_brand"); +var ZodBranded = class extends ZodType2 { + static { + __name(this, "ZodBranded"); + } + _parse(input) { + const { ctx } = this._processInputParams(input); + const data = ctx.data; + return this._def.type._parse({ + data, + path: ctx.path, + parent: ctx + }); + } + unwrap() { + return this._def.type; + } +}; +var ZodPipeline = class _ZodPipeline extends ZodType2 { + static { + __name(this, "ZodPipeline"); + } + _parse(input) { + const { status, ctx } = this._processInputParams(input); + if (ctx.common.async) { + const handleAsync = /* @__PURE__ */ __name(async () => { + const inResult = await this._def.in._parseAsync({ + data: ctx.data, + path: ctx.path, + parent: ctx + }); + if (inResult.status === "aborted") return INVALID; + if (inResult.status === "dirty") { + status.dirty(); + return DIRTY(inResult.value); + } else { + return this._def.out._parseAsync({ + data: inResult.value, + path: ctx.path, + parent: ctx + }); + } + }, "handleAsync"); + return handleAsync(); + } else { + const inResult = this._def.in._parseSync({ + data: ctx.data, + path: ctx.path, + parent: ctx + }); + if (inResult.status === "aborted") return INVALID; + if (inResult.status === "dirty") { + status.dirty(); + return { + status: "dirty", + value: inResult.value + }; + } else { + return this._def.out._parseSync({ + data: inResult.value, + path: ctx.path, + parent: ctx + }); + } + } + } + static create(a, b) { + return new _ZodPipeline({ + in: a, + out: b, + typeName: ZodFirstPartyTypeKind2.ZodPipeline + }); + } +}; +var ZodReadonly2 = class extends ZodType2 { + static { + __name(this, "ZodReadonly"); + } + _parse(input) { + const result = this._def.innerType._parse(input); + const freeze = /* @__PURE__ */ __name((data) => { + if (isValid(data)) { + data.value = Object.freeze(data.value); + } + return data; + }, "freeze"); + return isAsync(result) ? result.then((data) => freeze(data)) : freeze(result); + } + unwrap() { + return this._def.innerType; + } +}; +ZodReadonly2.create = (type, params) => { + return new ZodReadonly2({ + innerType: type, + typeName: ZodFirstPartyTypeKind2.ZodReadonly, + ...processCreateParams(params) + }); +}; +var late = { + object: ZodObject2.lazycreate +}; +var ZodFirstPartyTypeKind2; +(function(ZodFirstPartyTypeKind3) { + ZodFirstPartyTypeKind3["ZodString"] = "ZodString"; + ZodFirstPartyTypeKind3["ZodNumber"] = "ZodNumber"; + ZodFirstPartyTypeKind3["ZodNaN"] = "ZodNaN"; + ZodFirstPartyTypeKind3["ZodBigInt"] = "ZodBigInt"; + ZodFirstPartyTypeKind3["ZodBoolean"] = "ZodBoolean"; + ZodFirstPartyTypeKind3["ZodDate"] = "ZodDate"; + ZodFirstPartyTypeKind3["ZodSymbol"] = "ZodSymbol"; + ZodFirstPartyTypeKind3["ZodUndefined"] = "ZodUndefined"; + ZodFirstPartyTypeKind3["ZodNull"] = "ZodNull"; + ZodFirstPartyTypeKind3["ZodAny"] = "ZodAny"; + ZodFirstPartyTypeKind3["ZodUnknown"] = "ZodUnknown"; + ZodFirstPartyTypeKind3["ZodNever"] = "ZodNever"; + ZodFirstPartyTypeKind3["ZodVoid"] = "ZodVoid"; + ZodFirstPartyTypeKind3["ZodArray"] = "ZodArray"; + ZodFirstPartyTypeKind3["ZodObject"] = "ZodObject"; + ZodFirstPartyTypeKind3["ZodUnion"] = "ZodUnion"; + ZodFirstPartyTypeKind3["ZodDiscriminatedUnion"] = "ZodDiscriminatedUnion"; + ZodFirstPartyTypeKind3["ZodIntersection"] = "ZodIntersection"; + ZodFirstPartyTypeKind3["ZodTuple"] = "ZodTuple"; + ZodFirstPartyTypeKind3["ZodRecord"] = "ZodRecord"; + ZodFirstPartyTypeKind3["ZodMap"] = "ZodMap"; + ZodFirstPartyTypeKind3["ZodSet"] = "ZodSet"; + ZodFirstPartyTypeKind3["ZodFunction"] = "ZodFunction"; + ZodFirstPartyTypeKind3["ZodLazy"] = "ZodLazy"; + ZodFirstPartyTypeKind3["ZodLiteral"] = "ZodLiteral"; + ZodFirstPartyTypeKind3["ZodEnum"] = "ZodEnum"; + ZodFirstPartyTypeKind3["ZodEffects"] = "ZodEffects"; + ZodFirstPartyTypeKind3["ZodNativeEnum"] = "ZodNativeEnum"; + ZodFirstPartyTypeKind3["ZodOptional"] = "ZodOptional"; + ZodFirstPartyTypeKind3["ZodNullable"] = "ZodNullable"; + ZodFirstPartyTypeKind3["ZodDefault"] = "ZodDefault"; + ZodFirstPartyTypeKind3["ZodCatch"] = "ZodCatch"; + ZodFirstPartyTypeKind3["ZodPromise"] = "ZodPromise"; + ZodFirstPartyTypeKind3["ZodBranded"] = "ZodBranded"; + ZodFirstPartyTypeKind3["ZodPipeline"] = "ZodPipeline"; + ZodFirstPartyTypeKind3["ZodReadonly"] = "ZodReadonly"; +})(ZodFirstPartyTypeKind2 || (ZodFirstPartyTypeKind2 = {})); +var stringType = ZodString2.create; +var numberType = ZodNumber2.create; +var nanType = ZodNaN2.create; +var bigIntType = ZodBigInt2.create; +var booleanType = ZodBoolean2.create; +var dateType = ZodDate2.create; +var symbolType = ZodSymbol2.create; +var undefinedType = ZodUndefined2.create; +var nullType = ZodNull2.create; +var anyType = ZodAny2.create; +var unknownType = ZodUnknown2.create; +var neverType = ZodNever2.create; +var voidType = ZodVoid2.create; +var arrayType = ZodArray2.create; +var objectType = ZodObject2.create; +var strictObjectType = ZodObject2.strictCreate; +var unionType = ZodUnion2.create; +var discriminatedUnionType = ZodDiscriminatedUnion2.create; +var intersectionType = ZodIntersection2.create; +var tupleType = ZodTuple2.create; +var recordType = ZodRecord2.create; +var mapType = ZodMap2.create; +var setType = ZodSet2.create; +var functionType = ZodFunction2.create; +var lazyType = ZodLazy2.create; +var literalType = ZodLiteral2.create; +var enumType = ZodEnum2.create; +var nativeEnumType = ZodNativeEnum.create; +var promiseType = ZodPromise2.create; +var effectsType = ZodEffects.create; +var optionalType = ZodOptional2.create; +var nullableType = ZodNullable2.create; +var preprocessType = ZodEffects.createWithPreprocess; +var pipelineType = ZodPipeline.create; + +// ../../node_modules/.pnpm/@ai-sdk+provider-utils@3.0.12_zod@4.1.11/node_modules/@ai-sdk/provider-utils/dist/index.mjs +function combineHeaders(...headers) { + return headers.reduce((combinedHeaders, currentHeaders) => ({ + ...combinedHeaders, + ...currentHeaders != null ? currentHeaders : {} + }), {}); +} +__name(combineHeaders, "combineHeaders"); +async function delay(delayInMs, options) { + if (delayInMs == null) { + return Promise.resolve(); + } + const signal = options == null ? void 0 : options.abortSignal; + return new Promise((resolve2, reject) => { + if (signal == null ? void 0 : signal.aborted) { + reject(createAbortError()); + return; + } + const timeoutId = setTimeout(() => { + cleanup(); + resolve2(); + }, delayInMs); + const cleanup = /* @__PURE__ */ __name(() => { + clearTimeout(timeoutId); + signal == null ? void 0 : signal.removeEventListener("abort", onAbort); + }, "cleanup"); + const onAbort = /* @__PURE__ */ __name(() => { + cleanup(); + reject(createAbortError()); + }, "onAbort"); + signal == null ? void 0 : signal.addEventListener("abort", onAbort); + }); +} +__name(delay, "delay"); +function createAbortError() { + return new DOMException("Delay was aborted", "AbortError"); +} +__name(createAbortError, "createAbortError"); +function extractResponseHeaders(response) { + return Object.fromEntries([ + ...response.headers + ]); +} +__name(extractResponseHeaders, "extractResponseHeaders"); +var createIdGenerator = /* @__PURE__ */ __name(({ prefix, size = 16, alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", separator = "-" } = {}) => { + const generator = /* @__PURE__ */ __name(() => { + const alphabetLength = alphabet.length; + const chars = new Array(size); + for (let i = 0; i < size; i++) { + chars[i] = alphabet[Math.random() * alphabetLength | 0]; + } + return chars.join(""); + }, "generator"); + if (prefix == null) { + return generator; + } + if (alphabet.includes(separator)) { + throw new InvalidArgumentError({ + argument: "separator", + message: \`The separator "\${separator}" must not be part of the alphabet "\${alphabet}".\` + }); + } + return () => \`\${prefix}\${separator}\${generator()}\`; +}, "createIdGenerator"); +var generateId = createIdGenerator(); +function getErrorMessage2(error45) { + if (error45 == null) { + return "unknown error"; + } + if (typeof error45 === "string") { + return error45; + } + if (error45 instanceof Error) { + return error45.message; + } + return JSON.stringify(error45); +} +__name(getErrorMessage2, "getErrorMessage"); +function isAbortError(error45) { + return (error45 instanceof Error || error45 instanceof DOMException) && (error45.name === "AbortError" || error45.name === "ResponseAborted" || // Next.js + error45.name === "TimeoutError"); +} +__name(isAbortError, "isAbortError"); +var FETCH_FAILED_ERROR_MESSAGES = [ + "fetch failed", + "failed to fetch" +]; +function handleFetchError({ error: error45, url: url2, requestBodyValues }) { + if (isAbortError(error45)) { + return error45; + } + if (error45 instanceof TypeError && FETCH_FAILED_ERROR_MESSAGES.includes(error45.message.toLowerCase())) { + const cause = error45.cause; + if (cause != null) { + return new APICallError({ + message: \`Cannot connect to API: \${cause.message}\`, + cause, + url: url2, + requestBodyValues, + isRetryable: true + }); + } + } + return error45; +} +__name(handleFetchError, "handleFetchError"); +function getRuntimeEnvironmentUserAgent(globalThisAny = globalThis) { + var _a17, _b8, _c; + if (globalThisAny.window) { + return \`runtime/browser\`; + } + if ((_a17 = globalThisAny.navigator) == null ? void 0 : _a17.userAgent) { + return \`runtime/\${globalThisAny.navigator.userAgent.toLowerCase()}\`; + } + if ((_c = (_b8 = globalThisAny.process) == null ? void 0 : _b8.versions) == null ? void 0 : _c.node) { + return \`runtime/node.js/\${globalThisAny.process.version.substring(0)}\`; + } + if (globalThisAny.EdgeRuntime) { + return \`runtime/vercel-edge\`; + } + return "runtime/unknown"; +} +__name(getRuntimeEnvironmentUserAgent, "getRuntimeEnvironmentUserAgent"); +function removeUndefinedEntries(record2) { + return Object.fromEntries(Object.entries(record2).filter(([_key, value]) => value != null)); +} +__name(removeUndefinedEntries, "removeUndefinedEntries"); +function withUserAgentSuffix(headers, ...userAgentSuffixParts) { + const cleanedHeaders = removeUndefinedEntries(headers != null ? headers : {}); + const normalizedHeaders = new Headers(cleanedHeaders); + const currentUserAgentHeader = normalizedHeaders.get("user-agent") || ""; + normalizedHeaders.set("user-agent", [ + currentUserAgentHeader, + ...userAgentSuffixParts + ].filter(Boolean).join(" ")); + return Object.fromEntries(normalizedHeaders); +} +__name(withUserAgentSuffix, "withUserAgentSuffix"); +var VERSION = true ? "3.0.12" : "0.0.0-test"; +var getOriginalFetch = /* @__PURE__ */ __name(() => globalThis.fetch, "getOriginalFetch"); +var getFromApi = /* @__PURE__ */ __name(async ({ url: url2, headers = {}, successfulResponseHandler, failedResponseHandler, abortSignal, fetch: fetch3 = getOriginalFetch() }) => { + try { + const response = await fetch3(url2, { + method: "GET", + headers: withUserAgentSuffix(headers, \`ai-sdk/provider-utils/\${VERSION}\`, getRuntimeEnvironmentUserAgent()), + signal: abortSignal + }); + const responseHeaders = extractResponseHeaders(response); + if (!response.ok) { + let errorInformation; + try { + errorInformation = await failedResponseHandler({ + response, + url: url2, + requestBodyValues: {} + }); + } catch (error45) { + if (isAbortError(error45) || APICallError.isInstance(error45)) { + throw error45; + } + throw new APICallError({ + message: "Failed to process error response", + cause: error45, + statusCode: response.status, + url: url2, + responseHeaders, + requestBodyValues: {} + }); + } + throw errorInformation.value; + } + try { + return await successfulResponseHandler({ + response, + url: url2, + requestBodyValues: {} + }); + } catch (error45) { + if (error45 instanceof Error) { + if (isAbortError(error45) || APICallError.isInstance(error45)) { + throw error45; + } + } + throw new APICallError({ + message: "Failed to process successful response", + cause: error45, + statusCode: response.status, + url: url2, + responseHeaders, + requestBodyValues: {} + }); + } + } catch (error45) { + throw handleFetchError({ + error: error45, + url: url2, + requestBodyValues: {} + }); + } +}, "getFromApi"); +function isUrlSupported({ mediaType, url: url2, supportedUrls }) { + url2 = url2.toLowerCase(); + mediaType = mediaType.toLowerCase(); + return Object.entries(supportedUrls).map(([key, value]) => { + const mediaType2 = key.toLowerCase(); + return mediaType2 === "*" || mediaType2 === "*/*" ? { + mediaTypePrefix: "", + regexes: value + } : { + mediaTypePrefix: mediaType2.replace(/\\*/, ""), + regexes: value + }; + }).filter(({ mediaTypePrefix }) => mediaType.startsWith(mediaTypePrefix)).flatMap(({ regexes }) => regexes).some((pattern) => pattern.test(url2)); +} +__name(isUrlSupported, "isUrlSupported"); +function loadOptionalSetting({ settingValue, environmentVariableName }) { + if (typeof settingValue === "string") { + return settingValue; + } + if (settingValue != null || typeof process === "undefined") { + return void 0; + } + settingValue = process.env[environmentVariableName]; + if (settingValue == null || typeof settingValue !== "string") { + return void 0; + } + return settingValue; +} +__name(loadOptionalSetting, "loadOptionalSetting"); +var suspectProtoRx = /"__proto__"\\s*:/; +var suspectConstructorRx = /"constructor"\\s*:/; +function _parse2(text2) { + const obj = JSON.parse(text2); + if (obj === null || typeof obj !== "object") { + return obj; + } + if (suspectProtoRx.test(text2) === false && suspectConstructorRx.test(text2) === false) { + return obj; + } + return filter(obj); +} +__name(_parse2, "_parse"); +function filter(obj) { + let next = [ + obj + ]; + while (next.length) { + const nodes = next; + next = []; + for (const node of nodes) { + if (Object.prototype.hasOwnProperty.call(node, "__proto__")) { + throw new SyntaxError("Object contains forbidden prototype property"); + } + if (Object.prototype.hasOwnProperty.call(node, "constructor") && Object.prototype.hasOwnProperty.call(node.constructor, "prototype")) { + throw new SyntaxError("Object contains forbidden prototype property"); + } + for (const key in node) { + const value = node[key]; + if (value && typeof value === "object") { + next.push(value); + } + } + } + } + return obj; +} +__name(filter, "filter"); +function secureJsonParse(text2) { + const { stackTraceLimit } = Error; + Error.stackTraceLimit = 0; + try { + return _parse2(text2); + } finally { + Error.stackTraceLimit = stackTraceLimit; + } +} +__name(secureJsonParse, "secureJsonParse"); +var validatorSymbol = Symbol.for("vercel.ai.validator"); +function validator(validate) { + return { + [validatorSymbol]: true, + validate + }; +} +__name(validator, "validator"); +function isValidator(value) { + return typeof value === "object" && value !== null && validatorSymbol in value && value[validatorSymbol] === true && "validate" in value; +} +__name(isValidator, "isValidator"); +function lazyValidator(createValidator) { + let validator2; + return () => { + if (validator2 == null) { + validator2 = createValidator(); + } + return validator2; + }; +} +__name(lazyValidator, "lazyValidator"); +function asValidator(value) { + return isValidator(value) ? value : typeof value === "function" ? value() : standardSchemaValidator(value); +} +__name(asValidator, "asValidator"); +function standardSchemaValidator(standardSchema) { + return validator(async (value) => { + const result = await standardSchema["~standard"].validate(value); + return result.issues == null ? { + success: true, + value: result.value + } : { + success: false, + error: new TypeValidationError({ + value, + cause: result.issues + }) + }; + }); +} +__name(standardSchemaValidator, "standardSchemaValidator"); +async function validateTypes({ value, schema }) { + const result = await safeValidateTypes({ + value, + schema + }); + if (!result.success) { + throw TypeValidationError.wrap({ + value, + cause: result.error + }); + } + return result.value; +} +__name(validateTypes, "validateTypes"); +async function safeValidateTypes({ value, schema }) { + const validator2 = asValidator(schema); + try { + if (validator2.validate == null) { + return { + success: true, + value, + rawValue: value + }; + } + const result = await validator2.validate(value); + if (result.success) { + return { + success: true, + value: result.value, + rawValue: value + }; + } + return { + success: false, + error: TypeValidationError.wrap({ + value, + cause: result.error + }), + rawValue: value + }; + } catch (error45) { + return { + success: false, + error: TypeValidationError.wrap({ + value, + cause: error45 + }), + rawValue: value + }; + } +} +__name(safeValidateTypes, "safeValidateTypes"); +async function parseJSON({ text: text2, schema }) { + try { + const value = secureJsonParse(text2); + if (schema == null) { + return value; + } + return validateTypes({ + value, + schema + }); + } catch (error45) { + if (JSONParseError.isInstance(error45) || TypeValidationError.isInstance(error45)) { + throw error45; + } + throw new JSONParseError({ + text: text2, + cause: error45 + }); + } +} +__name(parseJSON, "parseJSON"); +async function safeParseJSON({ text: text2, schema }) { + try { + const value = secureJsonParse(text2); + if (schema == null) { + return { + success: true, + value, + rawValue: value + }; + } + return await safeValidateTypes({ + value, + schema + }); + } catch (error45) { + return { + success: false, + error: JSONParseError.isInstance(error45) ? error45 : new JSONParseError({ + text: text2, + cause: error45 + }), + rawValue: void 0 + }; + } +} +__name(safeParseJSON, "safeParseJSON"); +function parseJsonEventStream({ stream, schema }) { + return stream.pipeThrough(new TextDecoderStream()).pipeThrough(new EventSourceParserStream()).pipeThrough(new TransformStream({ + async transform({ data }, controller) { + if (data === "[DONE]") { + return; + } + controller.enqueue(await safeParseJSON({ + text: data, + schema + })); + } + })); +} +__name(parseJsonEventStream, "parseJsonEventStream"); +var getOriginalFetch2 = /* @__PURE__ */ __name(() => globalThis.fetch, "getOriginalFetch2"); +var postJsonToApi = /* @__PURE__ */ __name(async ({ url: url2, headers, body, failedResponseHandler, successfulResponseHandler, abortSignal, fetch: fetch3 }) => postToApi({ + url: url2, + headers: { + "Content-Type": "application/json", + ...headers + }, + body: { + content: JSON.stringify(body), + values: body + }, + failedResponseHandler, + successfulResponseHandler, + abortSignal, + fetch: fetch3 +}), "postJsonToApi"); +var postToApi = /* @__PURE__ */ __name(async ({ url: url2, headers = {}, body, successfulResponseHandler, failedResponseHandler, abortSignal, fetch: fetch3 = getOriginalFetch2() }) => { + try { + const response = await fetch3(url2, { + method: "POST", + headers: withUserAgentSuffix(headers, \`ai-sdk/provider-utils/\${VERSION}\`, getRuntimeEnvironmentUserAgent()), + body: body.content, + signal: abortSignal + }); + const responseHeaders = extractResponseHeaders(response); + if (!response.ok) { + let errorInformation; + try { + errorInformation = await failedResponseHandler({ + response, + url: url2, + requestBodyValues: body.values + }); + } catch (error45) { + if (isAbortError(error45) || APICallError.isInstance(error45)) { + throw error45; + } + throw new APICallError({ + message: "Failed to process error response", + cause: error45, + statusCode: response.status, + url: url2, + responseHeaders, + requestBodyValues: body.values + }); + } + throw errorInformation.value; + } + try { + return await successfulResponseHandler({ + response, + url: url2, + requestBodyValues: body.values + }); + } catch (error45) { + if (error45 instanceof Error) { + if (isAbortError(error45) || APICallError.isInstance(error45)) { + throw error45; + } + } + throw new APICallError({ + message: "Failed to process successful response", + cause: error45, + statusCode: response.status, + url: url2, + responseHeaders, + requestBodyValues: body.values + }); + } + } catch (error45) { + throw handleFetchError({ + error: error45, + url: url2, + requestBodyValues: body.values + }); + } +}, "postToApi"); +async function resolve(value) { + if (typeof value === "function") { + value = value(); + } + return Promise.resolve(value); +} +__name(resolve, "resolve"); +var createJsonErrorResponseHandler = /* @__PURE__ */ __name(({ errorSchema, errorToMessage, isRetryable }) => async ({ response, url: url2, requestBodyValues }) => { + const responseBody = await response.text(); + const responseHeaders = extractResponseHeaders(response); + if (responseBody.trim() === "") { + return { + responseHeaders, + value: new APICallError({ + message: response.statusText, + url: url2, + requestBodyValues, + statusCode: response.status, + responseHeaders, + responseBody, + isRetryable: isRetryable == null ? void 0 : isRetryable(response) + }) + }; + } + try { + const parsedError = await parseJSON({ + text: responseBody, + schema: errorSchema + }); + return { + responseHeaders, + value: new APICallError({ + message: errorToMessage(parsedError), + url: url2, + requestBodyValues, + statusCode: response.status, + responseHeaders, + responseBody, + data: parsedError, + isRetryable: isRetryable == null ? void 0 : isRetryable(response, parsedError) + }) + }; + } catch (parseError) { + return { + responseHeaders, + value: new APICallError({ + message: response.statusText, + url: url2, + requestBodyValues, + statusCode: response.status, + responseHeaders, + responseBody, + isRetryable: isRetryable == null ? void 0 : isRetryable(response) + }) + }; + } +}, "createJsonErrorResponseHandler"); +var createEventSourceResponseHandler = /* @__PURE__ */ __name((chunkSchema) => async ({ response }) => { + const responseHeaders = extractResponseHeaders(response); + if (response.body == null) { + throw new EmptyResponseBodyError({}); + } + return { + responseHeaders, + value: parseJsonEventStream({ + stream: response.body, + schema: chunkSchema + }) + }; +}, "createEventSourceResponseHandler"); +var createJsonResponseHandler = /* @__PURE__ */ __name((responseSchema) => async ({ response, url: url2, requestBodyValues }) => { + const responseBody = await response.text(); + const parsedResult = await safeParseJSON({ + text: responseBody, + schema: responseSchema + }); + const responseHeaders = extractResponseHeaders(response); + if (!parsedResult.success) { + throw new APICallError({ + message: "Invalid JSON response", + cause: parsedResult.error, + statusCode: response.status, + responseHeaders, + responseBody, + url: url2, + requestBodyValues + }); + } + return { + responseHeaders, + value: parsedResult.value, + rawValue: parsedResult.rawValue + }; +}, "createJsonResponseHandler"); +var getRelativePath = /* @__PURE__ */ __name((pathA, pathB) => { + let i = 0; + for (; i < pathA.length && i < pathB.length; i++) { + if (pathA[i] !== pathB[i]) break; + } + return [ + (pathA.length - i).toString(), + ...pathB.slice(i) + ].join("/"); +}, "getRelativePath"); +var ignoreOverride = Symbol("Let zodToJsonSchema decide on which parser to use"); +var defaultOptions = { + name: void 0, + \$refStrategy: "root", + basePath: [ + "#" + ], + effectStrategy: "input", + pipeStrategy: "all", + dateStrategy: "format:date-time", + mapStrategy: "entries", + removeAdditionalStrategy: "passthrough", + allowedAdditionalProperties: true, + rejectedAdditionalProperties: false, + definitionPath: "definitions", + strictUnions: false, + definitions: {}, + errorMessages: false, + patternStrategy: "escape", + applyRegexFlags: false, + emailStrategy: "format:email", + base64Strategy: "contentEncoding:base64", + nameStrategy: "ref" +}; +var getDefaultOptions = /* @__PURE__ */ __name((options) => typeof options === "string" ? { + ...defaultOptions, + name: options +} : { + ...defaultOptions, + ...options +}, "getDefaultOptions"); +function parseAnyDef() { + return {}; +} +__name(parseAnyDef, "parseAnyDef"); +function parseArrayDef(def, refs) { + var _a17, _b8, _c; + const res = { + type: "array" + }; + if (((_a17 = def.type) == null ? void 0 : _a17._def) && ((_c = (_b8 = def.type) == null ? void 0 : _b8._def) == null ? void 0 : _c.typeName) !== ZodFirstPartyTypeKind2.ZodAny) { + res.items = parseDef(def.type._def, { + ...refs, + currentPath: [ + ...refs.currentPath, + "items" + ] + }); + } + if (def.minLength) { + res.minItems = def.minLength.value; + } + if (def.maxLength) { + res.maxItems = def.maxLength.value; + } + if (def.exactLength) { + res.minItems = def.exactLength.value; + res.maxItems = def.exactLength.value; + } + return res; +} +__name(parseArrayDef, "parseArrayDef"); +function parseBigintDef(def) { + const res = { + type: "integer", + format: "int64" + }; + if (!def.checks) return res; + for (const check2 of def.checks) { + switch (check2.kind) { + case "min": + if (check2.inclusive) { + res.minimum = check2.value; + } else { + res.exclusiveMinimum = check2.value; + } + break; + case "max": + if (check2.inclusive) { + res.maximum = check2.value; + } else { + res.exclusiveMaximum = check2.value; + } + break; + case "multipleOf": + res.multipleOf = check2.value; + break; + } + } + return res; +} +__name(parseBigintDef, "parseBigintDef"); +function parseBooleanDef() { + return { + type: "boolean" + }; +} +__name(parseBooleanDef, "parseBooleanDef"); +function parseBrandedDef(_def, refs) { + return parseDef(_def.type._def, refs); +} +__name(parseBrandedDef, "parseBrandedDef"); +var parseCatchDef = /* @__PURE__ */ __name((def, refs) => { + return parseDef(def.innerType._def, refs); +}, "parseCatchDef"); +function parseDateDef(def, refs, overrideDateStrategy) { + const strategy = overrideDateStrategy != null ? overrideDateStrategy : refs.dateStrategy; + if (Array.isArray(strategy)) { + return { + anyOf: strategy.map((item, i) => parseDateDef(def, refs, item)) + }; + } + switch (strategy) { + case "string": + case "format:date-time": + return { + type: "string", + format: "date-time" + }; + case "format:date": + return { + type: "string", + format: "date" + }; + case "integer": + return integerDateParser(def); + } +} +__name(parseDateDef, "parseDateDef"); +var integerDateParser = /* @__PURE__ */ __name((def) => { + const res = { + type: "integer", + format: "unix-time" + }; + for (const check2 of def.checks) { + switch (check2.kind) { + case "min": + res.minimum = check2.value; + break; + case "max": + res.maximum = check2.value; + break; + } + } + return res; +}, "integerDateParser"); +function parseDefaultDef(_def, refs) { + return { + ...parseDef(_def.innerType._def, refs), + default: _def.defaultValue() + }; +} +__name(parseDefaultDef, "parseDefaultDef"); +function parseEffectsDef(_def, refs) { + return refs.effectStrategy === "input" ? parseDef(_def.schema._def, refs) : parseAnyDef(); +} +__name(parseEffectsDef, "parseEffectsDef"); +function parseEnumDef(def) { + return { + type: "string", + enum: Array.from(def.values) + }; +} +__name(parseEnumDef, "parseEnumDef"); +var isJsonSchema7AllOfType = /* @__PURE__ */ __name((type) => { + if ("type" in type && type.type === "string") return false; + return "allOf" in type; +}, "isJsonSchema7AllOfType"); +function parseIntersectionDef(def, refs) { + const allOf = [ + parseDef(def.left._def, { + ...refs, + currentPath: [ + ...refs.currentPath, + "allOf", + "0" + ] + }), + parseDef(def.right._def, { + ...refs, + currentPath: [ + ...refs.currentPath, + "allOf", + "1" + ] + }) + ].filter((x) => !!x); + const mergedAllOf = []; + allOf.forEach((schema) => { + if (isJsonSchema7AllOfType(schema)) { + mergedAllOf.push(...schema.allOf); + } else { + let nestedSchema = schema; + if ("additionalProperties" in schema && schema.additionalProperties === false) { + const { additionalProperties, ...rest } = schema; + nestedSchema = rest; + } + mergedAllOf.push(nestedSchema); + } + }); + return mergedAllOf.length ? { + allOf: mergedAllOf + } : void 0; +} +__name(parseIntersectionDef, "parseIntersectionDef"); +function parseLiteralDef(def) { + const parsedType7 = typeof def.value; + if (parsedType7 !== "bigint" && parsedType7 !== "number" && parsedType7 !== "boolean" && parsedType7 !== "string") { + return { + type: Array.isArray(def.value) ? "array" : "object" + }; + } + return { + type: parsedType7 === "bigint" ? "integer" : parsedType7, + const: def.value + }; +} +__name(parseLiteralDef, "parseLiteralDef"); +var emojiRegex2 = void 0; +var zodPatterns = { + /** + * \`c\` was changed to \`[cC]\` to replicate /i flag + */ + cuid: /^[cC][^\\s-]{8,}\$/, + cuid2: /^[0-9a-z]+\$/, + ulid: /^[0-9A-HJKMNP-TV-Z]{26}\$/, + /** + * \`a-z\` was added to replicate /i flag + */ + email: /^(?!\\.)(?!.*\\.\\.)([a-zA-Z0-9_'+\\-\\.]*)[a-zA-Z0-9_+-]@([a-zA-Z0-9][a-zA-Z0-9\\-]*\\.)+[a-zA-Z]{2,}\$/, + /** + * Constructed a valid Unicode RegExp + * + * Lazily instantiate since this type of regex isn't supported + * in all envs (e.g. React Native). + * + * See: + * https://github.com/colinhacks/zod/issues/2433 + * Fix in Zod: + * https://github.com/colinhacks/zod/commit/9340fd51e48576a75adc919bff65dbc4a5d4c99b + */ + emoji: /* @__PURE__ */ __name(() => { + if (emojiRegex2 === void 0) { + emojiRegex2 = RegExp("^(\\\\p{Extended_Pictographic}|\\\\p{Emoji_Component})+\$", "u"); + } + return emojiRegex2; + }, "emoji"), + /** + * Unused + */ + uuid: /^[0-9a-fA-F]{8}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{12}\$/, + /** + * Unused + */ + ipv4: /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\$/, + ipv4Cidr: /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\/(3[0-2]|[12]?[0-9])\$/, + /** + * Unused + */ + ipv6: /^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))\$/, + ipv6Cidr: /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])\$/, + base64: /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?\$/, + base64url: /^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?\$/, + nanoid: /^[a-zA-Z0-9_-]{21}\$/, + jwt: /^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*\$/ +}; +function parseStringDef(def, refs) { + const res = { + type: "string" + }; + if (def.checks) { + for (const check2 of def.checks) { + switch (check2.kind) { + case "min": + res.minLength = typeof res.minLength === "number" ? Math.max(res.minLength, check2.value) : check2.value; + break; + case "max": + res.maxLength = typeof res.maxLength === "number" ? Math.min(res.maxLength, check2.value) : check2.value; + break; + case "email": + switch (refs.emailStrategy) { + case "format:email": + addFormat(res, "email", check2.message, refs); + break; + case "format:idn-email": + addFormat(res, "idn-email", check2.message, refs); + break; + case "pattern:zod": + addPattern(res, zodPatterns.email, check2.message, refs); + break; + } + break; + case "url": + addFormat(res, "uri", check2.message, refs); + break; + case "uuid": + addFormat(res, "uuid", check2.message, refs); + break; + case "regex": + addPattern(res, check2.regex, check2.message, refs); + break; + case "cuid": + addPattern(res, zodPatterns.cuid, check2.message, refs); + break; + case "cuid2": + addPattern(res, zodPatterns.cuid2, check2.message, refs); + break; + case "startsWith": + addPattern(res, RegExp(\`^\${escapeLiteralCheckValue(check2.value, refs)}\`), check2.message, refs); + break; + case "endsWith": + addPattern(res, RegExp(\`\${escapeLiteralCheckValue(check2.value, refs)}\$\`), check2.message, refs); + break; + case "datetime": + addFormat(res, "date-time", check2.message, refs); + break; + case "date": + addFormat(res, "date", check2.message, refs); + break; + case "time": + addFormat(res, "time", check2.message, refs); + break; + case "duration": + addFormat(res, "duration", check2.message, refs); + break; + case "length": + res.minLength = typeof res.minLength === "number" ? Math.max(res.minLength, check2.value) : check2.value; + res.maxLength = typeof res.maxLength === "number" ? Math.min(res.maxLength, check2.value) : check2.value; + break; + case "includes": { + addPattern(res, RegExp(escapeLiteralCheckValue(check2.value, refs)), check2.message, refs); + break; + } + case "ip": { + if (check2.version !== "v6") { + addFormat(res, "ipv4", check2.message, refs); + } + if (check2.version !== "v4") { + addFormat(res, "ipv6", check2.message, refs); + } + break; + } + case "base64url": + addPattern(res, zodPatterns.base64url, check2.message, refs); + break; + case "jwt": + addPattern(res, zodPatterns.jwt, check2.message, refs); + break; + case "cidr": { + if (check2.version !== "v6") { + addPattern(res, zodPatterns.ipv4Cidr, check2.message, refs); + } + if (check2.version !== "v4") { + addPattern(res, zodPatterns.ipv6Cidr, check2.message, refs); + } + break; + } + case "emoji": + addPattern(res, zodPatterns.emoji(), check2.message, refs); + break; + case "ulid": { + addPattern(res, zodPatterns.ulid, check2.message, refs); + break; + } + case "base64": { + switch (refs.base64Strategy) { + case "format:binary": { + addFormat(res, "binary", check2.message, refs); + break; + } + case "contentEncoding:base64": { + res.contentEncoding = "base64"; + break; + } + case "pattern:zod": { + addPattern(res, zodPatterns.base64, check2.message, refs); + break; + } + } + break; + } + case "nanoid": { + addPattern(res, zodPatterns.nanoid, check2.message, refs); + } + case "toLowerCase": + case "toUpperCase": + case "trim": + break; + default: + /* @__PURE__ */ ((_) => { + })(check2); + } + } + } + return res; +} +__name(parseStringDef, "parseStringDef"); +function escapeLiteralCheckValue(literal2, refs) { + return refs.patternStrategy === "escape" ? escapeNonAlphaNumeric(literal2) : literal2; +} +__name(escapeLiteralCheckValue, "escapeLiteralCheckValue"); +var ALPHA_NUMERIC = new Set("ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz0123456789"); +function escapeNonAlphaNumeric(source) { + let result = ""; + for (let i = 0; i < source.length; i++) { + if (!ALPHA_NUMERIC.has(source[i])) { + result += "\\\\"; + } + result += source[i]; + } + return result; +} +__name(escapeNonAlphaNumeric, "escapeNonAlphaNumeric"); +function addFormat(schema, value, message, refs) { + var _a17; + if (schema.format || ((_a17 = schema.anyOf) == null ? void 0 : _a17.some((x) => x.format))) { + if (!schema.anyOf) { + schema.anyOf = []; + } + if (schema.format) { + schema.anyOf.push({ + format: schema.format + }); + delete schema.format; + } + schema.anyOf.push({ + format: value, + ...message && refs.errorMessages && { + errorMessage: { + format: message + } + } + }); + } else { + schema.format = value; + } +} +__name(addFormat, "addFormat"); +function addPattern(schema, regex, message, refs) { + var _a17; + if (schema.pattern || ((_a17 = schema.allOf) == null ? void 0 : _a17.some((x) => x.pattern))) { + if (!schema.allOf) { + schema.allOf = []; + } + if (schema.pattern) { + schema.allOf.push({ + pattern: schema.pattern + }); + delete schema.pattern; + } + schema.allOf.push({ + pattern: stringifyRegExpWithFlags(regex, refs), + ...message && refs.errorMessages && { + errorMessage: { + pattern: message + } + } + }); + } else { + schema.pattern = stringifyRegExpWithFlags(regex, refs); + } +} +__name(addPattern, "addPattern"); +function stringifyRegExpWithFlags(regex, refs) { + var _a17; + if (!refs.applyRegexFlags || !regex.flags) { + return regex.source; + } + const flags = { + i: regex.flags.includes("i"), + // Case-insensitive + m: regex.flags.includes("m"), + // \`^\` and \`\$\` matches adjacent to newline characters + s: regex.flags.includes("s") + }; + const source = flags.i ? regex.source.toLowerCase() : regex.source; + let pattern = ""; + let isEscaped = false; + let inCharGroup = false; + let inCharRange = false; + for (let i = 0; i < source.length; i++) { + if (isEscaped) { + pattern += source[i]; + isEscaped = false; + continue; + } + if (flags.i) { + if (inCharGroup) { + if (source[i].match(/[a-z]/)) { + if (inCharRange) { + pattern += source[i]; + pattern += \`\${source[i - 2]}-\${source[i]}\`.toUpperCase(); + inCharRange = false; + } else if (source[i + 1] === "-" && ((_a17 = source[i + 2]) == null ? void 0 : _a17.match(/[a-z]/))) { + pattern += source[i]; + inCharRange = true; + } else { + pattern += \`\${source[i]}\${source[i].toUpperCase()}\`; + } + continue; + } + } else if (source[i].match(/[a-z]/)) { + pattern += \`[\${source[i]}\${source[i].toUpperCase()}]\`; + continue; + } + } + if (flags.m) { + if (source[i] === "^") { + pattern += \`(^|(?<=[\\r +]))\`; + continue; + } else if (source[i] === "\$") { + pattern += \`(\$|(?=[\\r +]))\`; + continue; + } + } + if (flags.s && source[i] === ".") { + pattern += inCharGroup ? \`\${source[i]}\\r +\` : \`[\${source[i]}\\r +]\`; + continue; + } + pattern += source[i]; + if (source[i] === "\\\\") { + isEscaped = true; + } else if (inCharGroup && source[i] === "]") { + inCharGroup = false; + } else if (!inCharGroup && source[i] === "[") { + inCharGroup = true; + } + } + try { + new RegExp(pattern); + } catch (e) { + console.warn(\`Could not convert regex pattern at \${refs.currentPath.join("/")} to a flag-independent form! Falling back to the flag-ignorant source\`); + return regex.source; + } + return pattern; +} +__name(stringifyRegExpWithFlags, "stringifyRegExpWithFlags"); +function parseRecordDef(def, refs) { + var _a17, _b8, _c, _d, _e, _f; + const schema = { + type: "object", + additionalProperties: (_a17 = parseDef(def.valueType._def, { + ...refs, + currentPath: [ + ...refs.currentPath, + "additionalProperties" + ] + })) != null ? _a17 : refs.allowedAdditionalProperties + }; + if (((_b8 = def.keyType) == null ? void 0 : _b8._def.typeName) === ZodFirstPartyTypeKind2.ZodString && ((_c = def.keyType._def.checks) == null ? void 0 : _c.length)) { + const { type, ...keyType } = parseStringDef(def.keyType._def, refs); + return { + ...schema, + propertyNames: keyType + }; + } else if (((_d = def.keyType) == null ? void 0 : _d._def.typeName) === ZodFirstPartyTypeKind2.ZodEnum) { + return { + ...schema, + propertyNames: { + enum: def.keyType._def.values + } + }; + } else if (((_e = def.keyType) == null ? void 0 : _e._def.typeName) === ZodFirstPartyTypeKind2.ZodBranded && def.keyType._def.type._def.typeName === ZodFirstPartyTypeKind2.ZodString && ((_f = def.keyType._def.type._def.checks) == null ? void 0 : _f.length)) { + const { type, ...keyType } = parseBrandedDef(def.keyType._def, refs); + return { + ...schema, + propertyNames: keyType + }; + } + return schema; +} +__name(parseRecordDef, "parseRecordDef"); +function parseMapDef(def, refs) { + if (refs.mapStrategy === "record") { + return parseRecordDef(def, refs); + } + const keys = parseDef(def.keyType._def, { + ...refs, + currentPath: [ + ...refs.currentPath, + "items", + "items", + "0" + ] + }) || parseAnyDef(); + const values = parseDef(def.valueType._def, { + ...refs, + currentPath: [ + ...refs.currentPath, + "items", + "items", + "1" + ] + }) || parseAnyDef(); + return { + type: "array", + maxItems: 125, + items: { + type: "array", + items: [ + keys, + values + ], + minItems: 2, + maxItems: 2 + } + }; +} +__name(parseMapDef, "parseMapDef"); +function parseNativeEnumDef(def) { + const object3 = def.values; + const actualKeys = Object.keys(def.values).filter((key) => { + return typeof object3[object3[key]] !== "number"; + }); + const actualValues = actualKeys.map((key) => object3[key]); + const parsedTypes = Array.from(new Set(actualValues.map((values) => typeof values))); + return { + type: parsedTypes.length === 1 ? parsedTypes[0] === "string" ? "string" : "number" : [ + "string", + "number" + ], + enum: actualValues + }; +} +__name(parseNativeEnumDef, "parseNativeEnumDef"); +function parseNeverDef() { + return { + not: parseAnyDef() + }; +} +__name(parseNeverDef, "parseNeverDef"); +function parseNullDef() { + return { + type: "null" + }; +} +__name(parseNullDef, "parseNullDef"); +var primitiveMappings = { + ZodString: "string", + ZodNumber: "number", + ZodBigInt: "integer", + ZodBoolean: "boolean", + ZodNull: "null" +}; +function parseUnionDef(def, refs) { + const options = def.options instanceof Map ? Array.from(def.options.values()) : def.options; + if (options.every((x) => x._def.typeName in primitiveMappings && (!x._def.checks || !x._def.checks.length))) { + const types = options.reduce((types2, x) => { + const type = primitiveMappings[x._def.typeName]; + return type && !types2.includes(type) ? [ + ...types2, + type + ] : types2; + }, []); + return { + type: types.length > 1 ? types : types[0] + }; + } else if (options.every((x) => x._def.typeName === "ZodLiteral" && !x.description)) { + const types = options.reduce((acc, x) => { + const type = typeof x._def.value; + switch (type) { + case "string": + case "number": + case "boolean": + return [ + ...acc, + type + ]; + case "bigint": + return [ + ...acc, + "integer" + ]; + case "object": + if (x._def.value === null) return [ + ...acc, + "null" + ]; + case "symbol": + case "undefined": + case "function": + default: + return acc; + } + }, []); + if (types.length === options.length) { + const uniqueTypes = types.filter((x, i, a) => a.indexOf(x) === i); + return { + type: uniqueTypes.length > 1 ? uniqueTypes : uniqueTypes[0], + enum: options.reduce((acc, x) => { + return acc.includes(x._def.value) ? acc : [ + ...acc, + x._def.value + ]; + }, []) + }; + } + } else if (options.every((x) => x._def.typeName === "ZodEnum")) { + return { + type: "string", + enum: options.reduce((acc, x) => [ + ...acc, + ...x._def.values.filter((x2) => !acc.includes(x2)) + ], []) + }; + } + return asAnyOf(def, refs); +} +__name(parseUnionDef, "parseUnionDef"); +var asAnyOf = /* @__PURE__ */ __name((def, refs) => { + const anyOf = (def.options instanceof Map ? Array.from(def.options.values()) : def.options).map((x, i) => parseDef(x._def, { + ...refs, + currentPath: [ + ...refs.currentPath, + "anyOf", + \`\${i}\` + ] + })).filter((x) => !!x && (!refs.strictUnions || typeof x === "object" && Object.keys(x).length > 0)); + return anyOf.length ? { + anyOf + } : void 0; +}, "asAnyOf"); +function parseNullableDef(def, refs) { + if ([ + "ZodString", + "ZodNumber", + "ZodBigInt", + "ZodBoolean", + "ZodNull" + ].includes(def.innerType._def.typeName) && (!def.innerType._def.checks || !def.innerType._def.checks.length)) { + return { + type: [ + primitiveMappings[def.innerType._def.typeName], + "null" + ] + }; + } + const base = parseDef(def.innerType._def, { + ...refs, + currentPath: [ + ...refs.currentPath, + "anyOf", + "0" + ] + }); + return base && { + anyOf: [ + base, + { + type: "null" + } + ] + }; +} +__name(parseNullableDef, "parseNullableDef"); +function parseNumberDef(def) { + const res = { + type: "number" + }; + if (!def.checks) return res; + for (const check2 of def.checks) { + switch (check2.kind) { + case "int": + res.type = "integer"; + break; + case "min": + if (check2.inclusive) { + res.minimum = check2.value; + } else { + res.exclusiveMinimum = check2.value; + } + break; + case "max": + if (check2.inclusive) { + res.maximum = check2.value; + } else { + res.exclusiveMaximum = check2.value; + } + break; + case "multipleOf": + res.multipleOf = check2.value; + break; + } + } + return res; +} +__name(parseNumberDef, "parseNumberDef"); +function parseObjectDef(def, refs) { + const result = { + type: "object", + properties: {} + }; + const required2 = []; + const shape = def.shape(); + for (const propName in shape) { + let propDef = shape[propName]; + if (propDef === void 0 || propDef._def === void 0) { + continue; + } + const propOptional = safeIsOptional(propDef); + const parsedDef = parseDef(propDef._def, { + ...refs, + currentPath: [ + ...refs.currentPath, + "properties", + propName + ], + propertyPath: [ + ...refs.currentPath, + "properties", + propName + ] + }); + if (parsedDef === void 0) { + continue; + } + result.properties[propName] = parsedDef; + if (!propOptional) { + required2.push(propName); + } + } + if (required2.length) { + result.required = required2; + } + const additionalProperties = decideAdditionalProperties(def, refs); + if (additionalProperties !== void 0) { + result.additionalProperties = additionalProperties; + } + return result; +} +__name(parseObjectDef, "parseObjectDef"); +function decideAdditionalProperties(def, refs) { + if (def.catchall._def.typeName !== "ZodNever") { + return parseDef(def.catchall._def, { + ...refs, + currentPath: [ + ...refs.currentPath, + "additionalProperties" + ] + }); + } + switch (def.unknownKeys) { + case "passthrough": + return refs.allowedAdditionalProperties; + case "strict": + return refs.rejectedAdditionalProperties; + case "strip": + return refs.removeAdditionalStrategy === "strict" ? refs.allowedAdditionalProperties : refs.rejectedAdditionalProperties; + } +} +__name(decideAdditionalProperties, "decideAdditionalProperties"); +function safeIsOptional(schema) { + try { + return schema.isOptional(); + } catch (e) { + return true; + } +} +__name(safeIsOptional, "safeIsOptional"); +var parseOptionalDef = /* @__PURE__ */ __name((def, refs) => { + var _a17; + if (refs.currentPath.toString() === ((_a17 = refs.propertyPath) == null ? void 0 : _a17.toString())) { + return parseDef(def.innerType._def, refs); + } + const innerSchema = parseDef(def.innerType._def, { + ...refs, + currentPath: [ + ...refs.currentPath, + "anyOf", + "1" + ] + }); + return innerSchema ? { + anyOf: [ + { + not: parseAnyDef() + }, + innerSchema + ] + } : parseAnyDef(); +}, "parseOptionalDef"); +var parsePipelineDef = /* @__PURE__ */ __name((def, refs) => { + if (refs.pipeStrategy === "input") { + return parseDef(def.in._def, refs); + } else if (refs.pipeStrategy === "output") { + return parseDef(def.out._def, refs); + } + const a = parseDef(def.in._def, { + ...refs, + currentPath: [ + ...refs.currentPath, + "allOf", + "0" + ] + }); + const b = parseDef(def.out._def, { + ...refs, + currentPath: [ + ...refs.currentPath, + "allOf", + a ? "1" : "0" + ] + }); + return { + allOf: [ + a, + b + ].filter((x) => x !== void 0) + }; +}, "parsePipelineDef"); +function parsePromiseDef(def, refs) { + return parseDef(def.type._def, refs); +} +__name(parsePromiseDef, "parsePromiseDef"); +function parseSetDef(def, refs) { + const items = parseDef(def.valueType._def, { + ...refs, + currentPath: [ + ...refs.currentPath, + "items" + ] + }); + const schema = { + type: "array", + uniqueItems: true, + items + }; + if (def.minSize) { + schema.minItems = def.minSize.value; + } + if (def.maxSize) { + schema.maxItems = def.maxSize.value; + } + return schema; +} +__name(parseSetDef, "parseSetDef"); +function parseTupleDef(def, refs) { + if (def.rest) { + return { + type: "array", + minItems: def.items.length, + items: def.items.map((x, i) => parseDef(x._def, { + ...refs, + currentPath: [ + ...refs.currentPath, + "items", + \`\${i}\` + ] + })).reduce((acc, x) => x === void 0 ? acc : [ + ...acc, + x + ], []), + additionalItems: parseDef(def.rest._def, { + ...refs, + currentPath: [ + ...refs.currentPath, + "additionalItems" + ] + }) + }; + } else { + return { + type: "array", + minItems: def.items.length, + maxItems: def.items.length, + items: def.items.map((x, i) => parseDef(x._def, { + ...refs, + currentPath: [ + ...refs.currentPath, + "items", + \`\${i}\` + ] + })).reduce((acc, x) => x === void 0 ? acc : [ + ...acc, + x + ], []) + }; + } +} +__name(parseTupleDef, "parseTupleDef"); +function parseUndefinedDef() { + return { + not: parseAnyDef() + }; +} +__name(parseUndefinedDef, "parseUndefinedDef"); +function parseUnknownDef() { + return parseAnyDef(); +} +__name(parseUnknownDef, "parseUnknownDef"); +var parseReadonlyDef = /* @__PURE__ */ __name((def, refs) => { + return parseDef(def.innerType._def, refs); +}, "parseReadonlyDef"); +var selectParser = /* @__PURE__ */ __name((def, typeName, refs) => { + switch (typeName) { + case ZodFirstPartyTypeKind2.ZodString: + return parseStringDef(def, refs); + case ZodFirstPartyTypeKind2.ZodNumber: + return parseNumberDef(def); + case ZodFirstPartyTypeKind2.ZodObject: + return parseObjectDef(def, refs); + case ZodFirstPartyTypeKind2.ZodBigInt: + return parseBigintDef(def); + case ZodFirstPartyTypeKind2.ZodBoolean: + return parseBooleanDef(); + case ZodFirstPartyTypeKind2.ZodDate: + return parseDateDef(def, refs); + case ZodFirstPartyTypeKind2.ZodUndefined: + return parseUndefinedDef(); + case ZodFirstPartyTypeKind2.ZodNull: + return parseNullDef(); + case ZodFirstPartyTypeKind2.ZodArray: + return parseArrayDef(def, refs); + case ZodFirstPartyTypeKind2.ZodUnion: + case ZodFirstPartyTypeKind2.ZodDiscriminatedUnion: + return parseUnionDef(def, refs); + case ZodFirstPartyTypeKind2.ZodIntersection: + return parseIntersectionDef(def, refs); + case ZodFirstPartyTypeKind2.ZodTuple: + return parseTupleDef(def, refs); + case ZodFirstPartyTypeKind2.ZodRecord: + return parseRecordDef(def, refs); + case ZodFirstPartyTypeKind2.ZodLiteral: + return parseLiteralDef(def); + case ZodFirstPartyTypeKind2.ZodEnum: + return parseEnumDef(def); + case ZodFirstPartyTypeKind2.ZodNativeEnum: + return parseNativeEnumDef(def); + case ZodFirstPartyTypeKind2.ZodNullable: + return parseNullableDef(def, refs); + case ZodFirstPartyTypeKind2.ZodOptional: + return parseOptionalDef(def, refs); + case ZodFirstPartyTypeKind2.ZodMap: + return parseMapDef(def, refs); + case ZodFirstPartyTypeKind2.ZodSet: + return parseSetDef(def, refs); + case ZodFirstPartyTypeKind2.ZodLazy: + return () => def.getter()._def; + case ZodFirstPartyTypeKind2.ZodPromise: + return parsePromiseDef(def, refs); + case ZodFirstPartyTypeKind2.ZodNaN: + case ZodFirstPartyTypeKind2.ZodNever: + return parseNeverDef(); + case ZodFirstPartyTypeKind2.ZodEffects: + return parseEffectsDef(def, refs); + case ZodFirstPartyTypeKind2.ZodAny: + return parseAnyDef(); + case ZodFirstPartyTypeKind2.ZodUnknown: + return parseUnknownDef(); + case ZodFirstPartyTypeKind2.ZodDefault: + return parseDefaultDef(def, refs); + case ZodFirstPartyTypeKind2.ZodBranded: + return parseBrandedDef(def, refs); + case ZodFirstPartyTypeKind2.ZodReadonly: + return parseReadonlyDef(def, refs); + case ZodFirstPartyTypeKind2.ZodCatch: + return parseCatchDef(def, refs); + case ZodFirstPartyTypeKind2.ZodPipeline: + return parsePipelineDef(def, refs); + case ZodFirstPartyTypeKind2.ZodFunction: + case ZodFirstPartyTypeKind2.ZodVoid: + case ZodFirstPartyTypeKind2.ZodSymbol: + return void 0; + default: + return /* @__PURE__ */ ((_) => void 0)(typeName); + } +}, "selectParser"); +function parseDef(def, refs, forceResolution = false) { + var _a17; + const seenItem = refs.seen.get(def); + if (refs.override) { + const overrideResult = (_a17 = refs.override) == null ? void 0 : _a17.call(refs, def, refs, seenItem, forceResolution); + if (overrideResult !== ignoreOverride) { + return overrideResult; + } + } + if (seenItem && !forceResolution) { + const seenSchema = get\$ref(seenItem, refs); + if (seenSchema !== void 0) { + return seenSchema; + } + } + const newItem = { + def, + path: refs.currentPath, + jsonSchema: void 0 + }; + refs.seen.set(def, newItem); + const jsonSchemaOrGetter = selectParser(def, def.typeName, refs); + const jsonSchema2 = typeof jsonSchemaOrGetter === "function" ? parseDef(jsonSchemaOrGetter(), refs) : jsonSchemaOrGetter; + if (jsonSchema2) { + addMeta(def, refs, jsonSchema2); + } + if (refs.postProcess) { + const postProcessResult = refs.postProcess(jsonSchema2, def, refs); + newItem.jsonSchema = jsonSchema2; + return postProcessResult; + } + newItem.jsonSchema = jsonSchema2; + return jsonSchema2; +} +__name(parseDef, "parseDef"); +var get\$ref = /* @__PURE__ */ __name((item, refs) => { + switch (refs.\$refStrategy) { + case "root": + return { + \$ref: item.path.join("/") + }; + case "relative": + return { + \$ref: getRelativePath(refs.currentPath, item.path) + }; + case "none": + case "seen": { + if (item.path.length < refs.currentPath.length && item.path.every((value, index) => refs.currentPath[index] === value)) { + console.warn(\`Recursive reference detected at \${refs.currentPath.join("/")}! Defaulting to any\`); + return parseAnyDef(); + } + return refs.\$refStrategy === "seen" ? parseAnyDef() : void 0; + } + } +}, "get\$ref"); +var addMeta = /* @__PURE__ */ __name((def, refs, jsonSchema2) => { + if (def.description) { + jsonSchema2.description = def.description; + } + return jsonSchema2; +}, "addMeta"); +var getRefs = /* @__PURE__ */ __name((options) => { + const _options = getDefaultOptions(options); + const currentPath = _options.name !== void 0 ? [ + ..._options.basePath, + _options.definitionPath, + _options.name + ] : _options.basePath; + return { + ..._options, + currentPath, + propertyPath: void 0, + seen: new Map(Object.entries(_options.definitions).map(([name17, def]) => [ + def._def, + { + def: def._def, + path: [ + ..._options.basePath, + _options.definitionPath, + name17 + ], + // Resolution of references will be forced even though seen, so it's ok that the schema is undefined here for now. + jsonSchema: void 0 + } + ])) + }; +}, "getRefs"); +var zodToJsonSchema = /* @__PURE__ */ __name((schema, options) => { + var _a17; + const refs = getRefs(options); + let definitions = typeof options === "object" && options.definitions ? Object.entries(options.definitions).reduce((acc, [name24, schema2]) => { + var _a24; + return { + ...acc, + [name24]: (_a24 = parseDef(schema2._def, { + ...refs, + currentPath: [ + ...refs.basePath, + refs.definitionPath, + name24 + ] + }, true)) != null ? _a24 : parseAnyDef() + }; + }, {}) : void 0; + const name17 = typeof options === "string" ? options : (options == null ? void 0 : options.nameStrategy) === "title" ? void 0 : options == null ? void 0 : options.name; + const main = (_a17 = parseDef(schema._def, name17 === void 0 ? refs : { + ...refs, + currentPath: [ + ...refs.basePath, + refs.definitionPath, + name17 + ] + }, false)) != null ? _a17 : parseAnyDef(); + const title = typeof options === "object" && options.name !== void 0 && options.nameStrategy === "title" ? options.name : void 0; + if (title !== void 0) { + main.title = title; + } + const combined = name17 === void 0 ? definitions ? { + ...main, + [refs.definitionPath]: definitions + } : main : { + \$ref: [ + ...refs.\$refStrategy === "relative" ? [] : refs.basePath, + refs.definitionPath, + name17 + ].join("/"), + [refs.definitionPath]: { + ...definitions, + [name17]: main + } + }; + combined.\$schema = "http://json-schema.org/draft-07/schema#"; + return combined; +}, "zodToJsonSchema"); +var zod_to_json_schema_default = zodToJsonSchema; +function zod3Schema(zodSchema2, options) { + var _a17; + const useReferences = (_a17 = options == null ? void 0 : options.useReferences) != null ? _a17 : false; + return jsonSchema( + // defer json schema creation to avoid unnecessary computation when only validation is needed + () => zod_to_json_schema_default(zodSchema2, { + \$refStrategy: useReferences ? "root" : "none" + }), + { + validate: /* @__PURE__ */ __name(async (value) => { + const result = await zodSchema2.safeParseAsync(value); + return result.success ? { + success: true, + value: result.data + } : { + success: false, + error: result.error + }; + }, "validate") + } + ); +} +__name(zod3Schema, "zod3Schema"); +function zod4Schema(zodSchema2, options) { + var _a17; + const useReferences = (_a17 = options == null ? void 0 : options.useReferences) != null ? _a17 : false; + return jsonSchema( + // defer json schema creation to avoid unnecessary computation when only validation is needed + () => toJSONSchema(zodSchema2, { + target: "draft-7", + io: "output", + reused: useReferences ? "ref" : "inline" + }), + { + validate: /* @__PURE__ */ __name(async (value) => { + const result = await safeParseAsync2(zodSchema2, value); + return result.success ? { + success: true, + value: result.data + } : { + success: false, + error: result.error + }; + }, "validate") + } + ); +} +__name(zod4Schema, "zod4Schema"); +function isZod4Schema(zodSchema2) { + return "_zod" in zodSchema2; +} +__name(isZod4Schema, "isZod4Schema"); +function zodSchema(zodSchema2, options) { + if (isZod4Schema(zodSchema2)) { + return zod4Schema(zodSchema2, options); + } else { + return zod3Schema(zodSchema2, options); + } +} +__name(zodSchema, "zodSchema"); +var schemaSymbol = Symbol.for("vercel.ai.schema"); +function jsonSchema(jsonSchema2, { validate } = {}) { + return { + [schemaSymbol]: true, + _type: void 0, + // should never be used directly + [validatorSymbol]: true, + get jsonSchema() { + if (typeof jsonSchema2 === "function") { + jsonSchema2 = jsonSchema2(); + } + return jsonSchema2; + }, + validate + }; +} +__name(jsonSchema, "jsonSchema"); +function isSchema(value) { + return typeof value === "object" && value !== null && schemaSymbol in value && value[schemaSymbol] === true && "jsonSchema" in value && "validate" in value; +} +__name(isSchema, "isSchema"); +function asSchema(schema) { + return schema == null ? jsonSchema({ + properties: {}, + additionalProperties: false + }) : isSchema(schema) ? schema : typeof schema === "function" ? schema() : zodSchema(schema); +} +__name(asSchema, "asSchema"); +var { btoa: btoa2, atob: atob2 } = globalThis; +function convertBase64ToUint8Array(base64String) { + const base64Url = base64String.replace(/-/g, "+").replace(/_/g, "/"); + const latin1string = atob2(base64Url); + return Uint8Array.from(latin1string, (byte) => byte.codePointAt(0)); +} +__name(convertBase64ToUint8Array, "convertBase64ToUint8Array"); +function convertUint8ArrayToBase64(array2) { + let latin1string = ""; + for (let i = 0; i < array2.length; i++) { + latin1string += String.fromCodePoint(array2[i]); + } + return btoa2(latin1string); +} +__name(convertUint8ArrayToBase64, "convertUint8ArrayToBase64"); +function withoutTrailingSlash(url2) { + return url2 == null ? void 0 : url2.replace(/\\/\$/, ""); +} +__name(withoutTrailingSlash, "withoutTrailingSlash"); +function isAsyncIterable(obj) { + return obj != null && typeof obj[Symbol.asyncIterator] === "function"; +} +__name(isAsyncIterable, "isAsyncIterable"); +async function* executeTool({ execute, input, options }) { + const result = execute(input, options); + if (isAsyncIterable(result)) { + let lastOutput; + for await (const output of result) { + lastOutput = output; + yield { + type: "preliminary", + output + }; + } + yield { + type: "final", + output: lastOutput + }; + } else { + yield { + type: "final", + output: await result + }; + } +} +__name(executeTool, "executeTool"); + +// ../../node_modules/.pnpm/@ai-sdk+gateway@2.0.0_zod@4.1.11/node_modules/@ai-sdk/gateway/dist/index.mjs +var import_oidc = __toESM(require_index_browser(), 1); +var import_oidc2 = __toESM(require_index_browser(), 1); +var marker15 = "vercel.ai.gateway.error"; +var symbol16 = Symbol.for(marker15); +var _a15; +var _b; +var GatewayError = class _GatewayError extends (_b = Error, _a15 = symbol16, _b) { + static { + __name(this, "_GatewayError"); + } + constructor({ message, statusCode = 500, cause }) { + super(message); + this[_a15] = true; + this.statusCode = statusCode; + this.cause = cause; + } + /** + * Checks if the given error is a Gateway Error. + * @param {unknown} error - The error to check. + * @returns {boolean} True if the error is a Gateway Error, false otherwise. + */ + static isInstance(error45) { + return _GatewayError.hasMarker(error45); + } + static hasMarker(error45) { + return typeof error45 === "object" && error45 !== null && symbol16 in error45 && error45[symbol16] === true; + } +}; +var name14 = "GatewayAuthenticationError"; +var marker22 = \`vercel.ai.gateway.error.\${name14}\`; +var symbol22 = Symbol.for(marker22); +var _a22; +var _b2; +var GatewayAuthenticationError = class _GatewayAuthenticationError extends (_b2 = GatewayError, _a22 = symbol22, _b2) { + static { + __name(this, "_GatewayAuthenticationError"); + } + constructor({ message = "Authentication failed", statusCode = 401, cause } = {}) { + super({ + message, + statusCode, + cause + }); + this[_a22] = true; + this.name = name14; + this.type = "authentication_error"; + } + static isInstance(error45) { + return GatewayError.hasMarker(error45) && symbol22 in error45; + } + /** + * Creates a contextual error message when authentication fails + */ + static createContextualError({ apiKeyProvided, oidcTokenProvided, message = "Authentication failed", statusCode = 401, cause }) { + let contextualMessage; + if (apiKeyProvided) { + contextualMessage = \`AI Gateway authentication failed: Invalid API key. + +Create a new API key: https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fai%2Fapi-keys + +Provide via 'apiKey' option or 'AI_GATEWAY_API_KEY' environment variable.\`; + } else if (oidcTokenProvided) { + contextualMessage = \`AI Gateway authentication failed: Invalid OIDC token. + +Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the token. + +Alternatively, use an API key: https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fai%2Fapi-keys\`; + } else { + contextualMessage = \`AI Gateway authentication failed: No authentication provided. + +Option 1 - API key: +Create an API key: https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fai%2Fapi-keys +Provide via 'apiKey' option or 'AI_GATEWAY_API_KEY' environment variable. + +Option 2 - OIDC token: +Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the token.\`; + } + return new _GatewayAuthenticationError({ + message: contextualMessage, + statusCode, + cause + }); + } +}; +var name22 = "GatewayInvalidRequestError"; +var marker32 = \`vercel.ai.gateway.error.\${name22}\`; +var symbol32 = Symbol.for(marker32); +var _a32; +var _b3; +var GatewayInvalidRequestError = class extends (_b3 = GatewayError, _a32 = symbol32, _b3) { + static { + __name(this, "GatewayInvalidRequestError"); + } + constructor({ message = "Invalid request", statusCode = 400, cause } = {}) { + super({ + message, + statusCode, + cause + }); + this[_a32] = true; + this.name = name22; + this.type = "invalid_request_error"; + } + static isInstance(error45) { + return GatewayError.hasMarker(error45) && symbol32 in error45; + } +}; +var name32 = "GatewayRateLimitError"; +var marker42 = \`vercel.ai.gateway.error.\${name32}\`; +var symbol42 = Symbol.for(marker42); +var _a42; +var _b4; +var GatewayRateLimitError = class extends (_b4 = GatewayError, _a42 = symbol42, _b4) { + static { + __name(this, "GatewayRateLimitError"); + } + constructor({ message = "Rate limit exceeded", statusCode = 429, cause } = {}) { + super({ + message, + statusCode, + cause + }); + this[_a42] = true; + this.name = name32; + this.type = "rate_limit_exceeded"; + } + static isInstance(error45) { + return GatewayError.hasMarker(error45) && symbol42 in error45; + } +}; +var name42 = "GatewayModelNotFoundError"; +var marker52 = \`vercel.ai.gateway.error.\${name42}\`; +var symbol52 = Symbol.for(marker52); +var modelNotFoundParamSchema = lazyValidator(() => zodSchema(external_exports.object({ + modelId: external_exports.string() +}))); +var _a52; +var _b5; +var GatewayModelNotFoundError = class extends (_b5 = GatewayError, _a52 = symbol52, _b5) { + static { + __name(this, "GatewayModelNotFoundError"); + } + constructor({ message = "Model not found", statusCode = 404, modelId, cause } = {}) { + super({ + message, + statusCode, + cause + }); + this[_a52] = true; + this.name = name42; + this.type = "model_not_found"; + this.modelId = modelId; + } + static isInstance(error45) { + return GatewayError.hasMarker(error45) && symbol52 in error45; + } +}; +var name52 = "GatewayInternalServerError"; +var marker62 = \`vercel.ai.gateway.error.\${name52}\`; +var symbol62 = Symbol.for(marker62); +var _a62; +var _b6; +var GatewayInternalServerError = class extends (_b6 = GatewayError, _a62 = symbol62, _b6) { + static { + __name(this, "GatewayInternalServerError"); + } + constructor({ message = "Internal server error", statusCode = 500, cause } = {}) { + super({ + message, + statusCode, + cause + }); + this[_a62] = true; + this.name = name52; + this.type = "internal_server_error"; + } + static isInstance(error45) { + return GatewayError.hasMarker(error45) && symbol62 in error45; + } +}; +var name62 = "GatewayResponseError"; +var marker72 = \`vercel.ai.gateway.error.\${name62}\`; +var symbol72 = Symbol.for(marker72); +var _a72; +var _b7; +var GatewayResponseError = class extends (_b7 = GatewayError, _a72 = symbol72, _b7) { + static { + __name(this, "GatewayResponseError"); + } + constructor({ message = "Invalid response from Gateway", statusCode = 502, response, validationError, cause } = {}) { + super({ + message, + statusCode, + cause + }); + this[_a72] = true; + this.name = name62; + this.type = "response_error"; + this.response = response; + this.validationError = validationError; + } + static isInstance(error45) { + return GatewayError.hasMarker(error45) && symbol72 in error45; + } +}; +async function createGatewayErrorFromResponse({ response, statusCode, defaultMessage = "Gateway request failed", cause, authMethod }) { + const parseResult = await safeValidateTypes({ + value: response, + schema: gatewayErrorResponseSchema + }); + if (!parseResult.success) { + return new GatewayResponseError({ + message: \`Invalid error response format: \${defaultMessage}\`, + statusCode, + response, + validationError: parseResult.error, + cause + }); + } + const validatedResponse = parseResult.value; + const errorType = validatedResponse.error.type; + const message = validatedResponse.error.message; + switch (errorType) { + case "authentication_error": + return GatewayAuthenticationError.createContextualError({ + apiKeyProvided: authMethod === "api-key", + oidcTokenProvided: authMethod === "oidc", + statusCode, + cause + }); + case "invalid_request_error": + return new GatewayInvalidRequestError({ + message, + statusCode, + cause + }); + case "rate_limit_exceeded": + return new GatewayRateLimitError({ + message, + statusCode, + cause + }); + case "model_not_found": { + const modelResult = await safeValidateTypes({ + value: validatedResponse.error.param, + schema: modelNotFoundParamSchema + }); + return new GatewayModelNotFoundError({ + message, + statusCode, + modelId: modelResult.success ? modelResult.value.modelId : void 0, + cause + }); + } + case "internal_server_error": + return new GatewayInternalServerError({ + message, + statusCode, + cause + }); + default: + return new GatewayInternalServerError({ + message, + statusCode, + cause + }); + } +} +__name(createGatewayErrorFromResponse, "createGatewayErrorFromResponse"); +var gatewayErrorResponseSchema = lazyValidator(() => zodSchema(external_exports.object({ + error: external_exports.object({ + message: external_exports.string(), + type: external_exports.string().nullish(), + param: external_exports.unknown().nullish(), + code: external_exports.union([ + external_exports.string(), + external_exports.number() + ]).nullish() + }) +}))); +function asGatewayError(error45, authMethod) { + var _a83; + if (GatewayError.isInstance(error45)) { + return error45; + } + if (APICallError.isInstance(error45)) { + return createGatewayErrorFromResponse({ + response: extractApiCallResponse(error45), + statusCode: (_a83 = error45.statusCode) != null ? _a83 : 500, + defaultMessage: "Gateway request failed", + cause: error45, + authMethod + }); + } + return createGatewayErrorFromResponse({ + response: {}, + statusCode: 500, + defaultMessage: error45 instanceof Error ? \`Gateway request failed: \${error45.message}\` : "Unknown Gateway error", + cause: error45, + authMethod + }); +} +__name(asGatewayError, "asGatewayError"); +function extractApiCallResponse(error45) { + if (error45.data !== void 0) { + return error45.data; + } + if (error45.responseBody != null) { + try { + return JSON.parse(error45.responseBody); + } catch (e) { + return error45.responseBody; + } + } + return {}; +} +__name(extractApiCallResponse, "extractApiCallResponse"); +var GATEWAY_AUTH_METHOD_HEADER = "ai-gateway-auth-method"; +async function parseAuthMethod(headers) { + const result = await safeValidateTypes({ + value: headers[GATEWAY_AUTH_METHOD_HEADER], + schema: gatewayAuthMethodSchema + }); + return result.success ? result.value : void 0; +} +__name(parseAuthMethod, "parseAuthMethod"); +var gatewayAuthMethodSchema = lazyValidator(() => zodSchema(external_exports.union([ + external_exports.literal("api-key"), + external_exports.literal("oidc") +]))); +var GatewayFetchMetadata = class { + static { + __name(this, "GatewayFetchMetadata"); + } + constructor(config2) { + this.config = config2; + } + async getAvailableModels() { + try { + const { value } = await getFromApi({ + url: \`\${this.config.baseURL}/config\`, + headers: await resolve(this.config.headers()), + successfulResponseHandler: createJsonResponseHandler(gatewayAvailableModelsResponseSchema), + failedResponseHandler: createJsonErrorResponseHandler({ + errorSchema: external_exports.any(), + errorToMessage: /* @__PURE__ */ __name((data) => data, "errorToMessage") + }), + fetch: this.config.fetch + }); + return value; + } catch (error45) { + throw await asGatewayError(error45); + } + } + async getCredits() { + try { + const baseUrl = new URL(this.config.baseURL); + const { value } = await getFromApi({ + url: \`\${baseUrl.origin}/v1/credits\`, + headers: await resolve(this.config.headers()), + successfulResponseHandler: createJsonResponseHandler(gatewayCreditsResponseSchema), + failedResponseHandler: createJsonErrorResponseHandler({ + errorSchema: external_exports.any(), + errorToMessage: /* @__PURE__ */ __name((data) => data, "errorToMessage") + }), + fetch: this.config.fetch + }); + return value; + } catch (error45) { + throw await asGatewayError(error45); + } + } +}; +var gatewayAvailableModelsResponseSchema = lazyValidator(() => zodSchema(external_exports.object({ + models: external_exports.array(external_exports.object({ + id: external_exports.string(), + name: external_exports.string(), + description: external_exports.string().nullish(), + pricing: external_exports.object({ + input: external_exports.string(), + output: external_exports.string(), + input_cache_read: external_exports.string().nullish(), + input_cache_write: external_exports.string().nullish() + }).transform(({ input, output, input_cache_read, input_cache_write }) => ({ + input, + output, + ...input_cache_read ? { + cachedInputTokens: input_cache_read + } : {}, + ...input_cache_write ? { + cacheCreationInputTokens: input_cache_write + } : {} + })).nullish(), + specification: external_exports.object({ + specificationVersion: external_exports.literal("v2"), + provider: external_exports.string(), + modelId: external_exports.string() + }), + modelType: external_exports.enum([ + "language", + "embedding", + "image" + ]).nullish() + })) +}))); +var gatewayCreditsResponseSchema = lazyValidator(() => zodSchema(external_exports.object({ + balance: external_exports.string(), + total_used: external_exports.string() +}).transform(({ balance, total_used }) => ({ + balance, + totalUsed: total_used +})))); +var GatewayLanguageModel = class { + static { + __name(this, "GatewayLanguageModel"); + } + constructor(modelId, config2) { + this.modelId = modelId; + this.config = config2; + this.specificationVersion = "v2"; + this.supportedUrls = { + "*/*": [ + /.*/ + ] + }; + } + get provider() { + return this.config.provider; + } + async getArgs(options) { + const { abortSignal: _abortSignal, ...optionsWithoutSignal } = options; + return { + args: this.maybeEncodeFileParts(optionsWithoutSignal), + warnings: [] + }; + } + async doGenerate(options) { + const { args, warnings } = await this.getArgs(options); + const { abortSignal } = options; + const resolvedHeaders = await resolve(this.config.headers()); + try { + const { responseHeaders, value: responseBody, rawValue: rawResponse } = await postJsonToApi({ + url: this.getUrl(), + headers: combineHeaders(resolvedHeaders, options.headers, this.getModelConfigHeaders(this.modelId, false), await resolve(this.config.o11yHeaders)), + body: args, + successfulResponseHandler: createJsonResponseHandler(external_exports.any()), + failedResponseHandler: createJsonErrorResponseHandler({ + errorSchema: external_exports.any(), + errorToMessage: /* @__PURE__ */ __name((data) => data, "errorToMessage") + }), + ...abortSignal && { + abortSignal + }, + fetch: this.config.fetch + }); + return { + ...responseBody, + request: { + body: args + }, + response: { + headers: responseHeaders, + body: rawResponse + }, + warnings + }; + } catch (error45) { + throw await asGatewayError(error45, await parseAuthMethod(resolvedHeaders)); + } + } + async doStream(options) { + const { args, warnings } = await this.getArgs(options); + const { abortSignal } = options; + const resolvedHeaders = await resolve(this.config.headers()); + try { + const { value: response, responseHeaders } = await postJsonToApi({ + url: this.getUrl(), + headers: combineHeaders(resolvedHeaders, options.headers, this.getModelConfigHeaders(this.modelId, true), await resolve(this.config.o11yHeaders)), + body: args, + successfulResponseHandler: createEventSourceResponseHandler(external_exports.any()), + failedResponseHandler: createJsonErrorResponseHandler({ + errorSchema: external_exports.any(), + errorToMessage: /* @__PURE__ */ __name((data) => data, "errorToMessage") + }), + ...abortSignal && { + abortSignal + }, + fetch: this.config.fetch + }); + return { + stream: response.pipeThrough(new TransformStream({ + start(controller) { + if (warnings.length > 0) { + controller.enqueue({ + type: "stream-start", + warnings + }); + } + }, + transform(chunk2, controller) { + if (chunk2.success) { + const streamPart = chunk2.value; + if (streamPart.type === "raw" && !options.includeRawChunks) { + return; + } + if (streamPart.type === "response-metadata" && streamPart.timestamp && typeof streamPart.timestamp === "string") { + streamPart.timestamp = new Date(streamPart.timestamp); + } + controller.enqueue(streamPart); + } else { + controller.error(chunk2.error); + } + } + })), + request: { + body: args + }, + response: { + headers: responseHeaders + } + }; + } catch (error45) { + throw await asGatewayError(error45, await parseAuthMethod(resolvedHeaders)); + } + } + isFilePart(part) { + return part && typeof part === "object" && "type" in part && part.type === "file"; + } + /** + * Encodes file parts in the prompt to base64. Mutates the passed options + * instance directly to avoid copying the file data. + * @param options - The options to encode. + * @returns The options with the file parts encoded. + */ + maybeEncodeFileParts(options) { + for (const message of options.prompt) { + for (const part of message.content) { + if (this.isFilePart(part)) { + const filePart = part; + if (filePart.data instanceof Uint8Array) { + const buffer = Uint8Array.from(filePart.data); + const base64Data = Buffer.from(buffer).toString("base64"); + filePart.data = new URL(\`data:\${filePart.mediaType || "application/octet-stream"};base64,\${base64Data}\`); + } + } + } + } + return options; + } + getUrl() { + return \`\${this.config.baseURL}/language-model\`; + } + getModelConfigHeaders(modelId, streaming) { + return { + "ai-language-model-specification-version": "2", + "ai-language-model-id": modelId, + "ai-language-model-streaming": String(streaming) + }; + } +}; +var GatewayEmbeddingModel = class { + static { + __name(this, "GatewayEmbeddingModel"); + } + constructor(modelId, config2) { + this.modelId = modelId; + this.config = config2; + this.specificationVersion = "v2"; + this.maxEmbeddingsPerCall = 2048; + this.supportsParallelCalls = true; + } + get provider() { + return this.config.provider; + } + async doEmbed({ values, headers, abortSignal, providerOptions }) { + var _a83; + const resolvedHeaders = await resolve(this.config.headers()); + try { + const { responseHeaders, value: responseBody, rawValue } = await postJsonToApi({ + url: this.getUrl(), + headers: combineHeaders(resolvedHeaders, headers != null ? headers : {}, this.getModelConfigHeaders(), await resolve(this.config.o11yHeaders)), + body: { + input: values.length === 1 ? values[0] : values, + ...providerOptions ? { + providerOptions + } : {} + }, + successfulResponseHandler: createJsonResponseHandler(gatewayEmbeddingResponseSchema), + failedResponseHandler: createJsonErrorResponseHandler({ + errorSchema: external_exports.any(), + errorToMessage: /* @__PURE__ */ __name((data) => data, "errorToMessage") + }), + ...abortSignal && { + abortSignal + }, + fetch: this.config.fetch + }); + return { + embeddings: responseBody.embeddings, + usage: (_a83 = responseBody.usage) != null ? _a83 : void 0, + providerMetadata: responseBody.providerMetadata, + response: { + headers: responseHeaders, + body: rawValue + } + }; + } catch (error45) { + throw await asGatewayError(error45, await parseAuthMethod(resolvedHeaders)); + } + } + getUrl() { + return \`\${this.config.baseURL}/embedding-model\`; + } + getModelConfigHeaders() { + return { + "ai-embedding-model-specification-version": "2", + "ai-model-id": this.modelId + }; + } +}; +var gatewayEmbeddingResponseSchema = lazyValidator(() => zodSchema(external_exports.object({ + embeddings: external_exports.array(external_exports.array(external_exports.number())), + usage: external_exports.object({ + tokens: external_exports.number() + }).nullish(), + providerMetadata: external_exports.record(external_exports.string(), external_exports.record(external_exports.string(), external_exports.unknown())).optional() +}))); +async function getVercelRequestId() { + var _a83; + return (_a83 = (0, import_oidc.getContext)().headers) == null ? void 0 : _a83["x-vercel-id"]; +} +__name(getVercelRequestId, "getVercelRequestId"); +var VERSION2 = true ? "2.0.0" : "0.0.0-test"; +var AI_GATEWAY_PROTOCOL_VERSION = "0.0.1"; +function createGatewayProvider(options = {}) { + var _a83, _b8; + let pendingMetadata = null; + let metadataCache = null; + const cacheRefreshMillis = (_a83 = options.metadataCacheRefreshMillis) != null ? _a83 : 1e3 * 60 * 5; + let lastFetchTime = 0; + const baseURL = (_b8 = withoutTrailingSlash(options.baseURL)) != null ? _b8 : "https://ai-gateway.vercel.sh/v1/ai"; + const getHeaders = /* @__PURE__ */ __name(async () => { + const auth = await getGatewayAuthToken(options); + if (auth) { + return withUserAgentSuffix({ + Authorization: \`Bearer \${auth.token}\`, + "ai-gateway-protocol-version": AI_GATEWAY_PROTOCOL_VERSION, + [GATEWAY_AUTH_METHOD_HEADER]: auth.authMethod, + ...options.headers + }, \`ai-sdk/gateway/\${VERSION2}\`); + } + throw GatewayAuthenticationError.createContextualError({ + apiKeyProvided: false, + oidcTokenProvided: false, + statusCode: 401 + }); + }, "getHeaders"); + const createO11yHeaders = /* @__PURE__ */ __name(() => { + const deploymentId = loadOptionalSetting({ + settingValue: void 0, + environmentVariableName: "VERCEL_DEPLOYMENT_ID" + }); + const environment = loadOptionalSetting({ + settingValue: void 0, + environmentVariableName: "VERCEL_ENV" + }); + const region = loadOptionalSetting({ + settingValue: void 0, + environmentVariableName: "VERCEL_REGION" + }); + return async () => { + const requestId = await getVercelRequestId(); + return { + ...deploymentId && { + "ai-o11y-deployment-id": deploymentId + }, + ...environment && { + "ai-o11y-environment": environment + }, + ...region && { + "ai-o11y-region": region + }, + ...requestId && { + "ai-o11y-request-id": requestId + } + }; + }; + }, "createO11yHeaders"); + const createLanguageModel = /* @__PURE__ */ __name((modelId) => { + return new GatewayLanguageModel(modelId, { + provider: "gateway", + baseURL, + headers: getHeaders, + fetch: options.fetch, + o11yHeaders: createO11yHeaders() + }); + }, "createLanguageModel"); + const getAvailableModels = /* @__PURE__ */ __name(async () => { + var _a93, _b9, _c; + const now2 = (_c = (_b9 = (_a93 = options._internal) == null ? void 0 : _a93.currentDate) == null ? void 0 : _b9.call(_a93).getTime()) != null ? _c : Date.now(); + if (!pendingMetadata || now2 - lastFetchTime > cacheRefreshMillis) { + lastFetchTime = now2; + pendingMetadata = new GatewayFetchMetadata({ + baseURL, + headers: getHeaders, + fetch: options.fetch + }).getAvailableModels().then((metadata) => { + metadataCache = metadata; + return metadata; + }).catch(async (error45) => { + throw await asGatewayError(error45, await parseAuthMethod(await getHeaders())); + }); + } + return metadataCache ? Promise.resolve(metadataCache) : pendingMetadata; + }, "getAvailableModels"); + const getCredits = /* @__PURE__ */ __name(async () => { + return new GatewayFetchMetadata({ + baseURL, + headers: getHeaders, + fetch: options.fetch + }).getCredits().catch(async (error45) => { + throw await asGatewayError(error45, await parseAuthMethod(await getHeaders())); + }); + }, "getCredits"); + const provider = /* @__PURE__ */ __name(function(modelId) { + if (new.target) { + throw new Error("The Gateway Provider model function cannot be called with the new keyword."); + } + return createLanguageModel(modelId); + }, "provider"); + provider.getAvailableModels = getAvailableModels; + provider.getCredits = getCredits; + provider.imageModel = (modelId) => { + throw new NoSuchModelError({ + modelId, + modelType: "imageModel" + }); + }; + provider.languageModel = createLanguageModel; + provider.textEmbeddingModel = (modelId) => { + return new GatewayEmbeddingModel(modelId, { + provider: "gateway", + baseURL, + headers: getHeaders, + fetch: options.fetch, + o11yHeaders: createO11yHeaders() + }); + }; + return provider; +} +__name(createGatewayProvider, "createGatewayProvider"); +var gateway = createGatewayProvider(); +async function getGatewayAuthToken(options) { + const apiKey = loadOptionalSetting({ + settingValue: options.apiKey, + environmentVariableName: "AI_GATEWAY_API_KEY" + }); + if (apiKey) { + return { + token: apiKey, + authMethod: "api-key" + }; + } + try { + const oidcToken = await (0, import_oidc2.getVercelOidcToken)(); + return { + token: oidcToken, + authMethod: "oidc" + }; + } catch (e) { + return null; + } +} +__name(getGatewayAuthToken, "getGatewayAuthToken"); + +// ../../node_modules/.pnpm/ai@5.0.76_zod@4.1.11/node_modules/ai/dist/index.mjs +var import_api = __toESM(require_src(), 1); +var import_api2 = __toESM(require_src(), 1); +var __defProp2 = Object.defineProperty; +var __export2 = /* @__PURE__ */ __name((target, all) => { + for (var name17 in all) __defProp2(target, name17, { + get: all[name17], + enumerable: true + }); +}, "__export"); +var name15 = "AI_NoOutputSpecifiedError"; +var marker16 = \`vercel.ai.error.\${name15}\`; +var symbol17 = Symbol.for(marker16); +var _a16; +var NoOutputSpecifiedError = class extends AISDKError { + static { + __name(this, "NoOutputSpecifiedError"); + } + // used in isInstance + constructor({ message = "No output specified." } = {}) { + super({ + name: name15, + message + }); + this[_a16] = true; + } + static isInstance(error45) { + return AISDKError.hasMarker(error45, marker16); + } +}; +_a16 = symbol17; +function formatWarning(warning) { + const prefix = "AI SDK Warning:"; + switch (warning.type) { + case "unsupported-setting": { + let message = \`\${prefix} The "\${warning.setting}" setting is not supported by this model\`; + if (warning.details) { + message += \` - \${warning.details}\`; + } + return message; + } + case "unsupported-tool": { + const toolName = "name" in warning.tool ? warning.tool.name : "unknown tool"; + let message = \`\${prefix} The tool "\${toolName}" is not supported by this model\`; + if (warning.details) { + message += \` - \${warning.details}\`; + } + return message; + } + case "other": { + return \`\${prefix} \${warning.message}\`; + } + default: { + return \`\${prefix} \${JSON.stringify(warning, null, 2)}\`; + } + } +} +__name(formatWarning, "formatWarning"); +var FIRST_WARNING_INFO_MESSAGE = "AI SDK Warning System: To turn off warning logging, set the AI_SDK_LOG_WARNINGS global to false."; +var hasLoggedBefore = false; +var logWarnings = /* @__PURE__ */ __name((warnings) => { + if (warnings.length === 0) { + return; + } + const logger = globalThis.AI_SDK_LOG_WARNINGS; + if (logger === false) { + return; + } + if (typeof logger === "function") { + logger(warnings); + return; + } + if (!hasLoggedBefore) { + hasLoggedBefore = true; + console.info(FIRST_WARNING_INFO_MESSAGE); + } + for (const warning of warnings) { + console.warn(formatWarning(warning)); + } +}, "logWarnings"); +var name23 = "AI_InvalidArgumentError"; +var marker23 = \`vercel.ai.error.\${name23}\`; +var symbol23 = Symbol.for(marker23); +var _a23; +var InvalidArgumentError2 = class extends AISDKError { + static { + __name(this, "InvalidArgumentError"); + } + constructor({ parameter, value, message }) { + super({ + name: name23, + message: \`Invalid argument for parameter \${parameter}: \${message}\` + }); + this[_a23] = true; + this.parameter = parameter; + this.value = value; + } + static isInstance(error45) { + return AISDKError.hasMarker(error45, marker23); + } +}; +_a23 = symbol23; +var name33 = "AI_InvalidStreamPartError"; +var marker33 = \`vercel.ai.error.\${name33}\`; +var symbol33 = Symbol.for(marker33); +var _a33; +_a33 = symbol33; +var name43 = "AI_InvalidToolInputError"; +var marker43 = \`vercel.ai.error.\${name43}\`; +var symbol43 = Symbol.for(marker43); +var _a43; +var InvalidToolInputError = class extends AISDKError { + static { + __name(this, "InvalidToolInputError"); + } + constructor({ toolInput, toolName, cause, message = \`Invalid input for tool \${toolName}: \${getErrorMessage(cause)}\` }) { + super({ + name: name43, + message, + cause + }); + this[_a43] = true; + this.toolInput = toolInput; + this.toolName = toolName; + } + static isInstance(error45) { + return AISDKError.hasMarker(error45, marker43); + } +}; +_a43 = symbol43; +var name53 = "AI_MCPClientError"; +var marker53 = \`vercel.ai.error.\${name53}\`; +var symbol53 = Symbol.for(marker53); +var _a53; +_a53 = symbol53; +var name63 = "AI_NoImageGeneratedError"; +var marker63 = \`vercel.ai.error.\${name63}\`; +var symbol63 = Symbol.for(marker63); +var _a63; +_a63 = symbol63; +var name72 = "AI_NoObjectGeneratedError"; +var marker73 = \`vercel.ai.error.\${name72}\`; +var symbol73 = Symbol.for(marker73); +var _a73; +var NoObjectGeneratedError = class extends AISDKError { + static { + __name(this, "NoObjectGeneratedError"); + } + constructor({ message = "No object generated.", cause, text: text2, response, usage, finishReason }) { + super({ + name: name72, + message, + cause + }); + this[_a73] = true; + this.text = text2; + this.response = response; + this.usage = usage; + this.finishReason = finishReason; + } + static isInstance(error45) { + return AISDKError.hasMarker(error45, marker73); + } +}; +_a73 = symbol73; +var name82 = "AI_NoOutputGeneratedError"; +var marker82 = \`vercel.ai.error.\${name82}\`; +var symbol82 = Symbol.for(marker82); +var _a82; +_a82 = symbol82; +var name92 = "AI_NoSuchToolError"; +var marker92 = \`vercel.ai.error.\${name92}\`; +var symbol92 = Symbol.for(marker92); +var _a92; +var NoSuchToolError = class extends AISDKError { + static { + __name(this, "NoSuchToolError"); + } + constructor({ toolName, availableTools = void 0, message = \`Model tried to call unavailable tool '\${toolName}'. \${availableTools === void 0 ? "No tools are available." : \`Available tools: \${availableTools.join(", ")}.\`}\` }) { + super({ + name: name92, + message + }); + this[_a92] = true; + this.toolName = toolName; + this.availableTools = availableTools; + } + static isInstance(error45) { + return AISDKError.hasMarker(error45, marker92); + } +}; +_a92 = symbol92; +var name102 = "AI_ToolCallRepairError"; +var marker102 = \`vercel.ai.error.\${name102}\`; +var symbol102 = Symbol.for(marker102); +var _a102; +var ToolCallRepairError = class extends AISDKError { + static { + __name(this, "ToolCallRepairError"); + } + constructor({ cause, originalError, message = \`Error repairing tool call: \${getErrorMessage(cause)}\` }) { + super({ + name: name102, + message, + cause + }); + this[_a102] = true; + this.originalError = originalError; + } + static isInstance(error45) { + return AISDKError.hasMarker(error45, marker102); + } +}; +_a102 = symbol102; +var UnsupportedModelVersionError = class extends AISDKError { + static { + __name(this, "UnsupportedModelVersionError"); + } + constructor(options) { + super({ + name: "AI_UnsupportedModelVersionError", + message: \`Unsupported model version \${options.version} for provider "\${options.provider}" and model "\${options.modelId}". AI SDK 5 only supports models that implement specification version "v2".\` + }); + this.version = options.version; + this.provider = options.provider; + this.modelId = options.modelId; + } +}; +var name112 = "AI_InvalidDataContentError"; +var marker112 = \`vercel.ai.error.\${name112}\`; +var symbol112 = Symbol.for(marker112); +var _a112; +_a112 = symbol112; +var name122 = "AI_InvalidMessageRoleError"; +var marker122 = \`vercel.ai.error.\${name122}\`; +var symbol122 = Symbol.for(marker122); +var _a122; +var InvalidMessageRoleError = class extends AISDKError { + static { + __name(this, "InvalidMessageRoleError"); + } + constructor({ role, message = \`Invalid message role: '\${role}'. Must be one of: "system", "user", "assistant", "tool".\` }) { + super({ + name: name122, + message + }); + this[_a122] = true; + this.role = role; + } + static isInstance(error45) { + return AISDKError.hasMarker(error45, marker122); + } +}; +_a122 = symbol122; +var name132 = "AI_MessageConversionError"; +var marker132 = \`vercel.ai.error.\${name132}\`; +var symbol132 = Symbol.for(marker132); +var _a132; +_a132 = symbol132; +var name142 = "AI_DownloadError"; +var marker142 = \`vercel.ai.error.\${name142}\`; +var symbol142 = Symbol.for(marker142); +var _a142; +var DownloadError = class extends AISDKError { + static { + __name(this, "DownloadError"); + } + constructor({ url: url2, statusCode, statusText, cause, message = cause == null ? \`Failed to download \${url2}: \${statusCode} \${statusText}\` : \`Failed to download \${url2}: \${cause}\` }) { + super({ + name: name142, + message, + cause + }); + this[_a142] = true; + this.url = url2; + this.statusCode = statusCode; + this.statusText = statusText; + } + static isInstance(error45) { + return AISDKError.hasMarker(error45, marker142); + } +}; +_a142 = symbol142; +var name152 = "AI_RetryError"; +var marker152 = \`vercel.ai.error.\${name152}\`; +var symbol152 = Symbol.for(marker152); +var _a152; +var RetryError = class extends AISDKError { + static { + __name(this, "RetryError"); + } + constructor({ message, reason, errors }) { + super({ + name: name152, + message + }); + this[_a152] = true; + this.reason = reason; + this.errors = errors; + this.lastError = errors[errors.length - 1]; + } + static isInstance(error45) { + return AISDKError.hasMarker(error45, marker152); + } +}; +_a152 = symbol152; +function resolveLanguageModel(model) { + if (typeof model !== "string") { + if (model.specificationVersion !== "v2") { + throw new UnsupportedModelVersionError({ + version: model.specificationVersion, + provider: model.provider, + modelId: model.modelId + }); + } + return model; + } + return getGlobalProvider().languageModel(model); +} +__name(resolveLanguageModel, "resolveLanguageModel"); +function getGlobalProvider() { + var _a17; + return (_a17 = globalThis.AI_SDK_DEFAULT_PROVIDER) != null ? _a17 : gateway; +} +__name(getGlobalProvider, "getGlobalProvider"); +var imageMediaTypeSignatures = [ + { + mediaType: "image/gif", + bytesPrefix: [ + 71, + 73, + 70 + ] + }, + { + mediaType: "image/png", + bytesPrefix: [ + 137, + 80, + 78, + 71 + ] + }, + { + mediaType: "image/jpeg", + bytesPrefix: [ + 255, + 216 + ] + }, + { + mediaType: "image/webp", + bytesPrefix: [ + 82, + 73, + 70, + 70, + // "RIFF" + null, + null, + null, + null, + // file size (variable) + 87, + 69, + 66, + 80 + ] + }, + { + mediaType: "image/bmp", + bytesPrefix: [ + 66, + 77 + ] + }, + { + mediaType: "image/tiff", + bytesPrefix: [ + 73, + 73, + 42, + 0 + ] + }, + { + mediaType: "image/tiff", + bytesPrefix: [ + 77, + 77, + 0, + 42 + ] + }, + { + mediaType: "image/avif", + bytesPrefix: [ + 0, + 0, + 0, + 32, + 102, + 116, + 121, + 112, + 97, + 118, + 105, + 102 + ] + }, + { + mediaType: "image/heic", + bytesPrefix: [ + 0, + 0, + 0, + 32, + 102, + 116, + 121, + 112, + 104, + 101, + 105, + 99 + ] + } +]; +var stripID3 = /* @__PURE__ */ __name((data) => { + const bytes = typeof data === "string" ? convertBase64ToUint8Array(data) : data; + const id3Size = (bytes[6] & 127) << 21 | (bytes[7] & 127) << 14 | (bytes[8] & 127) << 7 | bytes[9] & 127; + return bytes.slice(id3Size + 10); +}, "stripID3"); +function stripID3TagsIfPresent(data) { + const hasId3 = typeof data === "string" && data.startsWith("SUQz") || typeof data !== "string" && data.length > 10 && data[0] === 73 && // 'I' + data[1] === 68 && // 'D' + data[2] === 51; + return hasId3 ? stripID3(data) : data; +} +__name(stripID3TagsIfPresent, "stripID3TagsIfPresent"); +function detectMediaType({ data, signatures }) { + const processedData = stripID3TagsIfPresent(data); + const bytes = typeof processedData === "string" ? convertBase64ToUint8Array(processedData.substring(0, Math.min(processedData.length, 24))) : processedData; + for (const signature of signatures) { + if (bytes.length >= signature.bytesPrefix.length && signature.bytesPrefix.every((byte, index) => byte === null || bytes[index] === byte)) { + return signature.mediaType; + } + } + return void 0; +} +__name(detectMediaType, "detectMediaType"); +var VERSION3 = true ? "5.0.76" : "0.0.0-test"; +var download = /* @__PURE__ */ __name(async ({ url: url2 }) => { + var _a17; + const urlText = url2.toString(); + try { + const response = await fetch(urlText, { + headers: withUserAgentSuffix({}, \`ai-sdk/\${VERSION3}\`, getRuntimeEnvironmentUserAgent()) + }); + if (!response.ok) { + throw new DownloadError({ + url: urlText, + statusCode: response.status, + statusText: response.statusText + }); + } + return { + data: new Uint8Array(await response.arrayBuffer()), + mediaType: (_a17 = response.headers.get("content-type")) != null ? _a17 : void 0 + }; + } catch (error45) { + if (DownloadError.isInstance(error45)) { + throw error45; + } + throw new DownloadError({ + url: urlText, + cause: error45 + }); + } +}, "download"); +var createDefaultDownloadFunction = /* @__PURE__ */ __name((download2 = download) => (requestedDownloads) => Promise.all(requestedDownloads.map(async (requestedDownload) => requestedDownload.isUrlSupportedByModel ? null : download2(requestedDownload))), "createDefaultDownloadFunction"); +function splitDataUrl(dataUrl) { + try { + const [header, base64Content] = dataUrl.split(","); + return { + mediaType: header.split(";")[0].split(":")[1], + base64Content + }; + } catch (error45) { + return { + mediaType: void 0, + base64Content: void 0 + }; + } +} +__name(splitDataUrl, "splitDataUrl"); +var dataContentSchema = external_exports.union([ + external_exports.string(), + external_exports.instanceof(Uint8Array), + external_exports.instanceof(ArrayBuffer), + external_exports.custom( + // Buffer might not be available in some environments such as CloudFlare: + (value) => { + var _a17, _b8; + return (_b8 = (_a17 = globalThis.Buffer) == null ? void 0 : _a17.isBuffer(value)) != null ? _b8 : false; + }, + { + message: "Must be a Buffer" + } + ) +]); +function convertToLanguageModelV2DataContent(content) { + if (content instanceof Uint8Array) { + return { + data: content, + mediaType: void 0 + }; + } + if (content instanceof ArrayBuffer) { + return { + data: new Uint8Array(content), + mediaType: void 0 + }; + } + if (typeof content === "string") { + try { + content = new URL(content); + } catch (error45) { + } + } + if (content instanceof URL && content.protocol === "data:") { + const { mediaType: dataUrlMediaType, base64Content } = splitDataUrl(content.toString()); + if (dataUrlMediaType == null || base64Content == null) { + throw new AISDKError({ + name: "InvalidDataContentError", + message: \`Invalid data URL format in content \${content.toString()}\` + }); + } + return { + data: base64Content, + mediaType: dataUrlMediaType + }; + } + return { + data: content, + mediaType: void 0 + }; +} +__name(convertToLanguageModelV2DataContent, "convertToLanguageModelV2DataContent"); +function convertDataContentToBase64String(content) { + if (typeof content === "string") { + return content; + } + if (content instanceof ArrayBuffer) { + return convertUint8ArrayToBase64(new Uint8Array(content)); + } + return convertUint8ArrayToBase64(content); +} +__name(convertDataContentToBase64String, "convertDataContentToBase64String"); +async function convertToLanguageModelPrompt({ prompt, supportedUrls, download: download2 = createDefaultDownloadFunction() }) { + const downloadedAssets = await downloadAssets(prompt.messages, download2, supportedUrls); + return [ + ...prompt.system != null ? [ + { + role: "system", + content: prompt.system + } + ] : [], + ...prompt.messages.map((message) => convertToLanguageModelMessage({ + message, + downloadedAssets + })) + ]; +} +__name(convertToLanguageModelPrompt, "convertToLanguageModelPrompt"); +function convertToLanguageModelMessage({ message, downloadedAssets }) { + const role = message.role; + switch (role) { + case "system": { + return { + role: "system", + content: message.content, + providerOptions: message.providerOptions + }; + } + case "user": { + if (typeof message.content === "string") { + return { + role: "user", + content: [ + { + type: "text", + text: message.content + } + ], + providerOptions: message.providerOptions + }; + } + return { + role: "user", + content: message.content.map((part) => convertPartToLanguageModelPart(part, downloadedAssets)).filter((part) => part.type !== "text" || part.text !== ""), + providerOptions: message.providerOptions + }; + } + case "assistant": { + if (typeof message.content === "string") { + return { + role: "assistant", + content: [ + { + type: "text", + text: message.content + } + ], + providerOptions: message.providerOptions + }; + } + return { + role: "assistant", + content: message.content.filter( + // remove empty text parts (no text, and no provider options): + (part) => part.type !== "text" || part.text !== "" || part.providerOptions != null + ).map((part) => { + const providerOptions = part.providerOptions; + switch (part.type) { + case "file": { + const { data, mediaType } = convertToLanguageModelV2DataContent(part.data); + return { + type: "file", + data, + filename: part.filename, + mediaType: mediaType != null ? mediaType : part.mediaType, + providerOptions + }; + } + case "reasoning": { + return { + type: "reasoning", + text: part.text, + providerOptions + }; + } + case "text": { + return { + type: "text", + text: part.text, + providerOptions + }; + } + case "tool-call": { + return { + type: "tool-call", + toolCallId: part.toolCallId, + toolName: part.toolName, + input: part.input, + providerExecuted: part.providerExecuted, + providerOptions + }; + } + case "tool-result": { + return { + type: "tool-result", + toolCallId: part.toolCallId, + toolName: part.toolName, + output: part.output, + providerOptions + }; + } + } + }), + providerOptions: message.providerOptions + }; + } + case "tool": { + return { + role: "tool", + content: message.content.map((part) => ({ + type: "tool-result", + toolCallId: part.toolCallId, + toolName: part.toolName, + output: part.output, + providerOptions: part.providerOptions + })), + providerOptions: message.providerOptions + }; + } + default: { + const _exhaustiveCheck = role; + throw new InvalidMessageRoleError({ + role: _exhaustiveCheck + }); + } + } +} +__name(convertToLanguageModelMessage, "convertToLanguageModelMessage"); +async function downloadAssets(messages, download2, supportedUrls) { + const plannedDownloads = messages.filter((message) => message.role === "user").map((message) => message.content).filter((content) => Array.isArray(content)).flat().filter((part) => part.type === "image" || part.type === "file").map((part) => { + var _a17; + const mediaType = (_a17 = part.mediaType) != null ? _a17 : part.type === "image" ? "image/*" : void 0; + let data = part.type === "image" ? part.image : part.data; + if (typeof data === "string") { + try { + data = new URL(data); + } catch (ignored) { + } + } + return { + mediaType, + data + }; + }).filter((part) => part.data instanceof URL).map((part) => ({ + url: part.data, + isUrlSupportedByModel: part.mediaType != null && isUrlSupported({ + url: part.data.toString(), + mediaType: part.mediaType, + supportedUrls + }) + })); + const downloadedFiles = await download2(plannedDownloads); + return Object.fromEntries(downloadedFiles.map((file2, index) => file2 == null ? null : [ + plannedDownloads[index].url.toString(), + { + data: file2.data, + mediaType: file2.mediaType + } + ]).filter((file2) => file2 != null)); +} +__name(downloadAssets, "downloadAssets"); +function convertPartToLanguageModelPart(part, downloadedAssets) { + var _a17; + if (part.type === "text") { + return { + type: "text", + text: part.text, + providerOptions: part.providerOptions + }; + } + let originalData; + const type = part.type; + switch (type) { + case "image": + originalData = part.image; + break; + case "file": + originalData = part.data; + break; + default: + throw new Error(\`Unsupported part type: \${type}\`); + } + const { data: convertedData, mediaType: convertedMediaType } = convertToLanguageModelV2DataContent(originalData); + let mediaType = convertedMediaType != null ? convertedMediaType : part.mediaType; + let data = convertedData; + if (data instanceof URL) { + const downloadedFile = downloadedAssets[data.toString()]; + if (downloadedFile) { + data = downloadedFile.data; + mediaType != null ? mediaType : mediaType = downloadedFile.mediaType; + } + } + switch (type) { + case "image": { + if (data instanceof Uint8Array || typeof data === "string") { + mediaType = (_a17 = detectMediaType({ + data, + signatures: imageMediaTypeSignatures + })) != null ? _a17 : mediaType; + } + return { + type: "file", + mediaType: mediaType != null ? mediaType : "image/*", + // any image + filename: void 0, + data, + providerOptions: part.providerOptions + }; + } + case "file": { + if (mediaType == null) { + throw new Error(\`Media type is missing for file part\`); + } + return { + type: "file", + mediaType, + filename: part.filename, + data, + providerOptions: part.providerOptions + }; + } + } +} +__name(convertPartToLanguageModelPart, "convertPartToLanguageModelPart"); +function prepareCallSettings({ maxOutputTokens, temperature, topP, topK, presencePenalty, frequencyPenalty, seed, stopSequences }) { + if (maxOutputTokens != null) { + if (!Number.isInteger(maxOutputTokens)) { + throw new InvalidArgumentError2({ + parameter: "maxOutputTokens", + value: maxOutputTokens, + message: "maxOutputTokens must be an integer" + }); + } + if (maxOutputTokens < 1) { + throw new InvalidArgumentError2({ + parameter: "maxOutputTokens", + value: maxOutputTokens, + message: "maxOutputTokens must be >= 1" + }); + } + } + if (temperature != null) { + if (typeof temperature !== "number") { + throw new InvalidArgumentError2({ + parameter: "temperature", + value: temperature, + message: "temperature must be a number" + }); + } + } + if (topP != null) { + if (typeof topP !== "number") { + throw new InvalidArgumentError2({ + parameter: "topP", + value: topP, + message: "topP must be a number" + }); + } + } + if (topK != null) { + if (typeof topK !== "number") { + throw new InvalidArgumentError2({ + parameter: "topK", + value: topK, + message: "topK must be a number" + }); + } + } + if (presencePenalty != null) { + if (typeof presencePenalty !== "number") { + throw new InvalidArgumentError2({ + parameter: "presencePenalty", + value: presencePenalty, + message: "presencePenalty must be a number" + }); + } + } + if (frequencyPenalty != null) { + if (typeof frequencyPenalty !== "number") { + throw new InvalidArgumentError2({ + parameter: "frequencyPenalty", + value: frequencyPenalty, + message: "frequencyPenalty must be a number" + }); + } + } + if (seed != null) { + if (!Number.isInteger(seed)) { + throw new InvalidArgumentError2({ + parameter: "seed", + value: seed, + message: "seed must be an integer" + }); + } + } + return { + maxOutputTokens, + temperature, + topP, + topK, + presencePenalty, + frequencyPenalty, + stopSequences, + seed + }; +} +__name(prepareCallSettings, "prepareCallSettings"); +function isNonEmptyObject(object22) { + return object22 != null && Object.keys(object22).length > 0; +} +__name(isNonEmptyObject, "isNonEmptyObject"); +function prepareToolsAndToolChoice({ tools, toolChoice, activeTools }) { + if (!isNonEmptyObject(tools)) { + return { + tools: void 0, + toolChoice: void 0 + }; + } + const filteredTools = activeTools != null ? Object.entries(tools).filter(([name17]) => activeTools.includes(name17)) : Object.entries(tools); + return { + tools: filteredTools.map(([name17, tool3]) => { + const toolType = tool3.type; + switch (toolType) { + case void 0: + case "dynamic": + case "function": + return { + type: "function", + name: name17, + description: tool3.description, + inputSchema: asSchema(tool3.inputSchema).jsonSchema, + providerOptions: tool3.providerOptions + }; + case "provider-defined": + return { + type: "provider-defined", + name: name17, + id: tool3.id, + args: tool3.args + }; + default: { + const exhaustiveCheck = toolType; + throw new Error(\`Unsupported tool type: \${exhaustiveCheck}\`); + } + } + }), + toolChoice: toolChoice == null ? { + type: "auto" + } : typeof toolChoice === "string" ? { + type: toolChoice + } : { + type: "tool", + toolName: toolChoice.toolName + } + }; +} +__name(prepareToolsAndToolChoice, "prepareToolsAndToolChoice"); +var jsonValueSchema = external_exports.lazy(() => external_exports.union([ + external_exports.null(), + external_exports.string(), + external_exports.number(), + external_exports.boolean(), + external_exports.record(external_exports.string(), jsonValueSchema), + external_exports.array(jsonValueSchema) +])); +var providerMetadataSchema = external_exports.record(external_exports.string(), external_exports.record(external_exports.string(), jsonValueSchema)); +var textPartSchema = external_exports.object({ + type: external_exports.literal("text"), + text: external_exports.string(), + providerOptions: providerMetadataSchema.optional() +}); +var imagePartSchema = external_exports.object({ + type: external_exports.literal("image"), + image: external_exports.union([ + dataContentSchema, + external_exports.instanceof(URL) + ]), + mediaType: external_exports.string().optional(), + providerOptions: providerMetadataSchema.optional() +}); +var filePartSchema = external_exports.object({ + type: external_exports.literal("file"), + data: external_exports.union([ + dataContentSchema, + external_exports.instanceof(URL) + ]), + filename: external_exports.string().optional(), + mediaType: external_exports.string(), + providerOptions: providerMetadataSchema.optional() +}); +var reasoningPartSchema = external_exports.object({ + type: external_exports.literal("reasoning"), + text: external_exports.string(), + providerOptions: providerMetadataSchema.optional() +}); +var toolCallPartSchema = external_exports.object({ + type: external_exports.literal("tool-call"), + toolCallId: external_exports.string(), + toolName: external_exports.string(), + input: external_exports.unknown(), + providerOptions: providerMetadataSchema.optional(), + providerExecuted: external_exports.boolean().optional() +}); +var outputSchema = external_exports.discriminatedUnion("type", [ + external_exports.object({ + type: external_exports.literal("text"), + value: external_exports.string() + }), + external_exports.object({ + type: external_exports.literal("json"), + value: jsonValueSchema + }), + external_exports.object({ + type: external_exports.literal("error-text"), + value: external_exports.string() + }), + external_exports.object({ + type: external_exports.literal("error-json"), + value: jsonValueSchema + }), + external_exports.object({ + type: external_exports.literal("content"), + value: external_exports.array(external_exports.union([ + external_exports.object({ + type: external_exports.literal("text"), + text: external_exports.string() + }), + external_exports.object({ + type: external_exports.literal("media"), + data: external_exports.string(), + mediaType: external_exports.string() + }) + ])) + }) +]); +var toolResultPartSchema = external_exports.object({ + type: external_exports.literal("tool-result"), + toolCallId: external_exports.string(), + toolName: external_exports.string(), + output: outputSchema, + providerOptions: providerMetadataSchema.optional() +}); +var systemModelMessageSchema = external_exports.object({ + role: external_exports.literal("system"), + content: external_exports.string(), + providerOptions: providerMetadataSchema.optional() +}); +var userModelMessageSchema = external_exports.object({ + role: external_exports.literal("user"), + content: external_exports.union([ + external_exports.string(), + external_exports.array(external_exports.union([ + textPartSchema, + imagePartSchema, + filePartSchema + ])) + ]), + providerOptions: providerMetadataSchema.optional() +}); +var assistantModelMessageSchema = external_exports.object({ + role: external_exports.literal("assistant"), + content: external_exports.union([ + external_exports.string(), + external_exports.array(external_exports.union([ + textPartSchema, + filePartSchema, + reasoningPartSchema, + toolCallPartSchema, + toolResultPartSchema + ])) + ]), + providerOptions: providerMetadataSchema.optional() +}); +var toolModelMessageSchema = external_exports.object({ + role: external_exports.literal("tool"), + content: external_exports.array(toolResultPartSchema), + providerOptions: providerMetadataSchema.optional() +}); +var modelMessageSchema = external_exports.union([ + systemModelMessageSchema, + userModelMessageSchema, + assistantModelMessageSchema, + toolModelMessageSchema +]); +async function standardizePrompt(prompt) { + if (prompt.prompt == null && prompt.messages == null) { + throw new InvalidPromptError({ + prompt, + message: "prompt or messages must be defined" + }); + } + if (prompt.prompt != null && prompt.messages != null) { + throw new InvalidPromptError({ + prompt, + message: "prompt and messages cannot be defined at the same time" + }); + } + if (prompt.system != null && typeof prompt.system !== "string") { + throw new InvalidPromptError({ + prompt, + message: "system must be a string" + }); + } + let messages; + if (prompt.prompt != null && typeof prompt.prompt === "string") { + messages = [ + { + role: "user", + content: prompt.prompt + } + ]; + } else if (prompt.prompt != null && Array.isArray(prompt.prompt)) { + messages = prompt.prompt; + } else if (prompt.messages != null) { + messages = prompt.messages; + } else { + throw new InvalidPromptError({ + prompt, + message: "prompt or messages must be defined" + }); + } + if (messages.length === 0) { + throw new InvalidPromptError({ + prompt, + message: "messages must not be empty" + }); + } + const validationResult = await safeValidateTypes({ + value: messages, + schema: external_exports.array(modelMessageSchema) + }); + if (!validationResult.success) { + throw new InvalidPromptError({ + prompt, + message: "The messages must be a ModelMessage[]. If you have passed a UIMessage[], you can use convertToModelMessages to convert them.", + cause: validationResult.error + }); + } + return { + messages, + system: prompt.system + }; +} +__name(standardizePrompt, "standardizePrompt"); +function wrapGatewayError(error45) { + if (GatewayAuthenticationError.isInstance(error45) || GatewayModelNotFoundError.isInstance(error45)) { + return new AISDKError({ + name: "GatewayError", + message: "Vercel AI Gateway access failed. If you want to use AI SDK providers directly, use the providers, e.g. @ai-sdk/openai, or register a different global default provider.", + cause: error45 + }); + } + return error45; +} +__name(wrapGatewayError, "wrapGatewayError"); +function assembleOperationName({ operationId, telemetry }) { + return { + // standardized operation and resource name: + "operation.name": \`\${operationId}\${(telemetry == null ? void 0 : telemetry.functionId) != null ? \` \${telemetry.functionId}\` : ""}\`, + "resource.name": telemetry == null ? void 0 : telemetry.functionId, + // detailed, AI SDK specific data: + "ai.operationId": operationId, + "ai.telemetry.functionId": telemetry == null ? void 0 : telemetry.functionId + }; +} +__name(assembleOperationName, "assembleOperationName"); +function getBaseTelemetryAttributes({ model, settings, telemetry, headers }) { + var _a17; + return { + "ai.model.provider": model.provider, + "ai.model.id": model.modelId, + // settings: + ...Object.entries(settings).reduce((attributes, [key, value]) => { + attributes[\`ai.settings.\${key}\`] = value; + return attributes; + }, {}), + // add metadata as attributes: + ...Object.entries((_a17 = telemetry == null ? void 0 : telemetry.metadata) != null ? _a17 : {}).reduce((attributes, [key, value]) => { + attributes[\`ai.telemetry.metadata.\${key}\`] = value; + return attributes; + }, {}), + // request headers + ...Object.entries(headers != null ? headers : {}).reduce((attributes, [key, value]) => { + if (value !== void 0) { + attributes[\`ai.request.headers.\${key}\`] = value; + } + return attributes; + }, {}) + }; +} +__name(getBaseTelemetryAttributes, "getBaseTelemetryAttributes"); +var noopTracer = { + startSpan() { + return noopSpan; + }, + startActiveSpan(name17, arg1, arg2, arg3) { + if (typeof arg1 === "function") { + return arg1(noopSpan); + } + if (typeof arg2 === "function") { + return arg2(noopSpan); + } + if (typeof arg3 === "function") { + return arg3(noopSpan); + } + } +}; +var noopSpan = { + spanContext() { + return noopSpanContext; + }, + setAttribute() { + return this; + }, + setAttributes() { + return this; + }, + addEvent() { + return this; + }, + addLink() { + return this; + }, + addLinks() { + return this; + }, + setStatus() { + return this; + }, + updateName() { + return this; + }, + end() { + return this; + }, + isRecording() { + return false; + }, + recordException() { + return this; + } +}; +var noopSpanContext = { + traceId: "", + spanId: "", + traceFlags: 0 +}; +function getTracer({ isEnabled = false, tracer } = {}) { + if (!isEnabled) { + return noopTracer; + } + if (tracer) { + return tracer; + } + return import_api.trace.getTracer("ai"); +} +__name(getTracer, "getTracer"); +function recordSpan({ name: name17, tracer, attributes, fn, endWhenDone = true }) { + return tracer.startActiveSpan(name17, { + attributes + }, async (span) => { + try { + const result = await fn(span); + if (endWhenDone) { + span.end(); + } + return result; + } catch (error45) { + try { + recordErrorOnSpan(span, error45); + } finally { + span.end(); + } + throw error45; + } + }); +} +__name(recordSpan, "recordSpan"); +function recordErrorOnSpan(span, error45) { + if (error45 instanceof Error) { + span.recordException({ + name: error45.name, + message: error45.message, + stack: error45.stack + }); + span.setStatus({ + code: import_api2.SpanStatusCode.ERROR, + message: error45.message + }); + } else { + span.setStatus({ + code: import_api2.SpanStatusCode.ERROR + }); + } +} +__name(recordErrorOnSpan, "recordErrorOnSpan"); +function selectTelemetryAttributes({ telemetry, attributes }) { + if ((telemetry == null ? void 0 : telemetry.isEnabled) !== true) { + return {}; + } + return Object.entries(attributes).reduce((attributes2, [key, value]) => { + if (value == null) { + return attributes2; + } + if (typeof value === "object" && "input" in value && typeof value.input === "function") { + if ((telemetry == null ? void 0 : telemetry.recordInputs) === false) { + return attributes2; + } + const result = value.input(); + return result == null ? attributes2 : { + ...attributes2, + [key]: result + }; + } + if (typeof value === "object" && "output" in value && typeof value.output === "function") { + if ((telemetry == null ? void 0 : telemetry.recordOutputs) === false) { + return attributes2; + } + const result = value.output(); + return result == null ? attributes2 : { + ...attributes2, + [key]: result + }; + } + return { + ...attributes2, + [key]: value + }; + }, {}); +} +__name(selectTelemetryAttributes, "selectTelemetryAttributes"); +function stringifyForTelemetry(prompt) { + return JSON.stringify(prompt.map((message) => ({ + ...message, + content: typeof message.content === "string" ? message.content : message.content.map((part) => part.type === "file" ? { + ...part, + data: part.data instanceof Uint8Array ? convertDataContentToBase64String(part.data) : part.data + } : part) + }))); +} +__name(stringifyForTelemetry, "stringifyForTelemetry"); +function addLanguageModelUsage(usage1, usage2) { + return { + inputTokens: addTokenCounts(usage1.inputTokens, usage2.inputTokens), + outputTokens: addTokenCounts(usage1.outputTokens, usage2.outputTokens), + totalTokens: addTokenCounts(usage1.totalTokens, usage2.totalTokens), + reasoningTokens: addTokenCounts(usage1.reasoningTokens, usage2.reasoningTokens), + cachedInputTokens: addTokenCounts(usage1.cachedInputTokens, usage2.cachedInputTokens) + }; +} +__name(addLanguageModelUsage, "addLanguageModelUsage"); +function addTokenCounts(tokenCount1, tokenCount2) { + return tokenCount1 == null && tokenCount2 == null ? void 0 : (tokenCount1 != null ? tokenCount1 : 0) + (tokenCount2 != null ? tokenCount2 : 0); +} +__name(addTokenCounts, "addTokenCounts"); +function asArray(value) { + return value === void 0 ? [] : Array.isArray(value) ? value : [ + value + ]; +} +__name(asArray, "asArray"); +function getRetryDelayInMs({ error: error45, exponentialBackoffDelay }) { + const headers = error45.responseHeaders; + if (!headers) return exponentialBackoffDelay; + let ms2; + const retryAfterMs = headers["retry-after-ms"]; + if (retryAfterMs) { + const timeoutMs = parseFloat(retryAfterMs); + if (!Number.isNaN(timeoutMs)) { + ms2 = timeoutMs; + } + } + const retryAfter = headers["retry-after"]; + if (retryAfter && ms2 === void 0) { + const timeoutSeconds = parseFloat(retryAfter); + if (!Number.isNaN(timeoutSeconds)) { + ms2 = timeoutSeconds * 1e3; + } else { + ms2 = Date.parse(retryAfter) - Date.now(); + } + } + if (ms2 != null && !Number.isNaN(ms2) && 0 <= ms2 && (ms2 < 60 * 1e3 || ms2 < exponentialBackoffDelay)) { + return ms2; + } + return exponentialBackoffDelay; +} +__name(getRetryDelayInMs, "getRetryDelayInMs"); +var retryWithExponentialBackoffRespectingRetryHeaders = /* @__PURE__ */ __name(({ maxRetries = 2, initialDelayInMs = 2e3, backoffFactor = 2, abortSignal } = {}) => async (f) => _retryWithExponentialBackoff(f, { + maxRetries, + delayInMs: initialDelayInMs, + backoffFactor, + abortSignal +}), "retryWithExponentialBackoffRespectingRetryHeaders"); +async function _retryWithExponentialBackoff(f, { maxRetries, delayInMs, backoffFactor, abortSignal }, errors = []) { + try { + return await f(); + } catch (error45) { + if (isAbortError(error45)) { + throw error45; + } + if (maxRetries === 0) { + throw error45; + } + const errorMessage = getErrorMessage2(error45); + const newErrors = [ + ...errors, + error45 + ]; + const tryNumber = newErrors.length; + if (tryNumber > maxRetries) { + throw new RetryError({ + message: \`Failed after \${tryNumber} attempts. Last error: \${errorMessage}\`, + reason: "maxRetriesExceeded", + errors: newErrors + }); + } + if (error45 instanceof Error && APICallError.isInstance(error45) && error45.isRetryable === true && tryNumber <= maxRetries) { + await delay(getRetryDelayInMs({ + error: error45, + exponentialBackoffDelay: delayInMs + }), { + abortSignal + }); + return _retryWithExponentialBackoff(f, { + maxRetries, + delayInMs: backoffFactor * delayInMs, + backoffFactor, + abortSignal + }, newErrors); + } + if (tryNumber === 1) { + throw error45; + } + throw new RetryError({ + message: \`Failed after \${tryNumber} attempts with non-retryable error: '\${errorMessage}'\`, + reason: "errorNotRetryable", + errors: newErrors + }); + } +} +__name(_retryWithExponentialBackoff, "_retryWithExponentialBackoff"); +function prepareRetries({ maxRetries, abortSignal }) { + if (maxRetries != null) { + if (!Number.isInteger(maxRetries)) { + throw new InvalidArgumentError2({ + parameter: "maxRetries", + value: maxRetries, + message: "maxRetries must be an integer" + }); + } + if (maxRetries < 0) { + throw new InvalidArgumentError2({ + parameter: "maxRetries", + value: maxRetries, + message: "maxRetries must be >= 0" + }); + } + } + const maxRetriesResult = maxRetries != null ? maxRetries : 2; + return { + maxRetries: maxRetriesResult, + retry: retryWithExponentialBackoffRespectingRetryHeaders({ + maxRetries: maxRetriesResult, + abortSignal + }) + }; +} +__name(prepareRetries, "prepareRetries"); +function extractTextContent(content) { + const parts = content.filter((content2) => content2.type === "text"); + if (parts.length === 0) { + return void 0; + } + return parts.map((content2) => content2.text).join(""); +} +__name(extractTextContent, "extractTextContent"); +var DefaultGeneratedFile = class { + static { + __name(this, "DefaultGeneratedFile"); + } + constructor({ data, mediaType }) { + const isUint8Array = data instanceof Uint8Array; + this.base64Data = isUint8Array ? void 0 : data; + this.uint8ArrayData = isUint8Array ? data : void 0; + this.mediaType = mediaType; + } + // lazy conversion with caching to avoid unnecessary conversion overhead: + get base64() { + if (this.base64Data == null) { + this.base64Data = convertUint8ArrayToBase64(this.uint8ArrayData); + } + return this.base64Data; + } + // lazy conversion with caching to avoid unnecessary conversion overhead: + get uint8Array() { + if (this.uint8ArrayData == null) { + this.uint8ArrayData = convertBase64ToUint8Array(this.base64Data); + } + return this.uint8ArrayData; + } +}; +async function parseToolCall({ toolCall, tools, repairToolCall, system, messages }) { + try { + if (tools == null) { + throw new NoSuchToolError({ + toolName: toolCall.toolName + }); + } + try { + return await doParseToolCall({ + toolCall, + tools + }); + } catch (error45) { + if (repairToolCall == null || !(NoSuchToolError.isInstance(error45) || InvalidToolInputError.isInstance(error45))) { + throw error45; + } + let repairedToolCall = null; + try { + repairedToolCall = await repairToolCall({ + toolCall, + tools, + inputSchema: /* @__PURE__ */ __name(({ toolName }) => { + const { inputSchema } = tools[toolName]; + return asSchema(inputSchema).jsonSchema; + }, "inputSchema"), + system, + messages, + error: error45 + }); + } catch (repairError) { + throw new ToolCallRepairError({ + cause: repairError, + originalError: error45 + }); + } + if (repairedToolCall == null) { + throw error45; + } + return await doParseToolCall({ + toolCall: repairedToolCall, + tools + }); + } + } catch (error45) { + const parsedInput = await safeParseJSON({ + text: toolCall.input + }); + const input = parsedInput.success ? parsedInput.value : toolCall.input; + return { + type: "tool-call", + toolCallId: toolCall.toolCallId, + toolName: toolCall.toolName, + input, + dynamic: true, + invalid: true, + error: error45 + }; + } +} +__name(parseToolCall, "parseToolCall"); +async function doParseToolCall({ toolCall, tools }) { + const toolName = toolCall.toolName; + const tool3 = tools[toolName]; + if (tool3 == null) { + throw new NoSuchToolError({ + toolName: toolCall.toolName, + availableTools: Object.keys(tools) + }); + } + const schema = asSchema(tool3.inputSchema); + const parseResult = toolCall.input.trim() === "" ? await safeValidateTypes({ + value: {}, + schema + }) : await safeParseJSON({ + text: toolCall.input, + schema + }); + if (parseResult.success === false) { + throw new InvalidToolInputError({ + toolName, + toolInput: toolCall.input, + cause: parseResult.error + }); + } + return tool3.type === "dynamic" ? { + type: "tool-call", + toolCallId: toolCall.toolCallId, + toolName: toolCall.toolName, + input: parseResult.value, + providerExecuted: toolCall.providerExecuted, + providerMetadata: toolCall.providerMetadata, + dynamic: true + } : { + type: "tool-call", + toolCallId: toolCall.toolCallId, + toolName, + input: parseResult.value, + providerExecuted: toolCall.providerExecuted, + providerMetadata: toolCall.providerMetadata + }; +} +__name(doParseToolCall, "doParseToolCall"); +var DefaultStepResult = class { + static { + __name(this, "DefaultStepResult"); + } + constructor({ content, finishReason, usage, warnings, request, response, providerMetadata }) { + this.content = content; + this.finishReason = finishReason; + this.usage = usage; + this.warnings = warnings; + this.request = request; + this.response = response; + this.providerMetadata = providerMetadata; + } + get text() { + return this.content.filter((part) => part.type === "text").map((part) => part.text).join(""); + } + get reasoning() { + return this.content.filter((part) => part.type === "reasoning"); + } + get reasoningText() { + return this.reasoning.length === 0 ? void 0 : this.reasoning.map((part) => part.text).join(""); + } + get files() { + return this.content.filter((part) => part.type === "file").map((part) => part.file); + } + get sources() { + return this.content.filter((part) => part.type === "source"); + } + get toolCalls() { + return this.content.filter((part) => part.type === "tool-call"); + } + get staticToolCalls() { + return this.toolCalls.filter((toolCall) => toolCall.dynamic !== true); + } + get dynamicToolCalls() { + return this.toolCalls.filter((toolCall) => toolCall.dynamic === true); + } + get toolResults() { + return this.content.filter((part) => part.type === "tool-result"); + } + get staticToolResults() { + return this.toolResults.filter((toolResult) => toolResult.dynamic !== true); + } + get dynamicToolResults() { + return this.toolResults.filter((toolResult) => toolResult.dynamic === true); + } +}; +function stepCountIs(stepCount) { + return ({ steps }) => steps.length === stepCount; +} +__name(stepCountIs, "stepCountIs"); +async function isStopConditionMet({ stopConditions, steps }) { + return (await Promise.all(stopConditions.map((condition) => condition({ + steps + })))).some((result) => result); +} +__name(isStopConditionMet, "isStopConditionMet"); +function createToolModelOutput({ output, tool: tool3, errorMode }) { + if (errorMode === "text") { + return { + type: "error-text", + value: getErrorMessage(output) + }; + } else if (errorMode === "json") { + return { + type: "error-json", + value: toJSONValue(output) + }; + } + if (tool3 == null ? void 0 : tool3.toModelOutput) { + return tool3.toModelOutput(output); + } + return typeof output === "string" ? { + type: "text", + value: output + } : { + type: "json", + value: toJSONValue(output) + }; +} +__name(createToolModelOutput, "createToolModelOutput"); +function toJSONValue(value) { + return value === void 0 ? null : value; +} +__name(toJSONValue, "toJSONValue"); +function toResponseMessages({ content: inputContent, tools }) { + const responseMessages = []; + const content = inputContent.filter((part) => part.type !== "source").filter((part) => (part.type !== "tool-result" || part.providerExecuted) && (part.type !== "tool-error" || part.providerExecuted)).filter((part) => part.type !== "text" || part.text.length > 0).map((part) => { + switch (part.type) { + case "text": + return { + type: "text", + text: part.text, + providerOptions: part.providerMetadata + }; + case "reasoning": + return { + type: "reasoning", + text: part.text, + providerOptions: part.providerMetadata + }; + case "file": + return { + type: "file", + data: part.file.base64, + mediaType: part.file.mediaType, + providerOptions: part.providerMetadata + }; + case "tool-call": + return { + type: "tool-call", + toolCallId: part.toolCallId, + toolName: part.toolName, + input: part.input, + providerExecuted: part.providerExecuted, + providerOptions: part.providerMetadata + }; + case "tool-result": + return { + type: "tool-result", + toolCallId: part.toolCallId, + toolName: part.toolName, + output: createToolModelOutput({ + tool: tools == null ? void 0 : tools[part.toolName], + output: part.output, + errorMode: "none" + }), + providerExecuted: true, + providerOptions: part.providerMetadata + }; + case "tool-error": + return { + type: "tool-result", + toolCallId: part.toolCallId, + toolName: part.toolName, + output: createToolModelOutput({ + tool: tools == null ? void 0 : tools[part.toolName], + output: part.error, + errorMode: "json" + }), + providerOptions: part.providerMetadata + }; + } + }); + if (content.length > 0) { + responseMessages.push({ + role: "assistant", + content + }); + } + const toolResultContent = inputContent.filter((part) => part.type === "tool-result" || part.type === "tool-error").filter((part) => !part.providerExecuted).map((toolResult) => ({ + type: "tool-result", + toolCallId: toolResult.toolCallId, + toolName: toolResult.toolName, + output: createToolModelOutput({ + tool: tools == null ? void 0 : tools[toolResult.toolName], + output: toolResult.type === "tool-result" ? toolResult.output : toolResult.error, + errorMode: toolResult.type === "tool-error" ? "text" : "none" + }) + })); + if (toolResultContent.length > 0) { + responseMessages.push({ + role: "tool", + content: toolResultContent + }); + } + return responseMessages; +} +__name(toResponseMessages, "toResponseMessages"); +async function generateText({ model: modelArg, tools, toolChoice, system, prompt, messages, maxRetries: maxRetriesArg, abortSignal, headers, stopWhen = stepCountIs(1), experimental_output: output, experimental_telemetry: telemetry, providerOptions, experimental_activeTools, activeTools = experimental_activeTools, experimental_prepareStep, prepareStep = experimental_prepareStep, experimental_repairToolCall: repairToolCall, experimental_download: download2, experimental_context, _internal: { generateId: generateId3 = originalGenerateId, currentDate = /* @__PURE__ */ __name(() => /* @__PURE__ */ new Date(), "currentDate") } = {}, onStepFinish, ...settings }) { + const model = resolveLanguageModel(modelArg); + const stopConditions = asArray(stopWhen); + const { maxRetries, retry } = prepareRetries({ + maxRetries: maxRetriesArg, + abortSignal + }); + const callSettings = prepareCallSettings(settings); + const headersWithUserAgent = withUserAgentSuffix(headers != null ? headers : {}, \`ai/\${VERSION3}\`); + const baseTelemetryAttributes = getBaseTelemetryAttributes({ + model, + telemetry, + headers: headersWithUserAgent, + settings: { + ...callSettings, + maxRetries + } + }); + const initialPrompt = await standardizePrompt({ + system, + prompt, + messages + }); + const tracer = getTracer(telemetry); + try { + return await recordSpan({ + name: "ai.generateText", + attributes: selectTelemetryAttributes({ + telemetry, + attributes: { + ...assembleOperationName({ + operationId: "ai.generateText", + telemetry + }), + ...baseTelemetryAttributes, + // model: + "ai.model.provider": model.provider, + "ai.model.id": model.modelId, + // specific settings that only make sense on the outer level: + "ai.prompt": { + input: /* @__PURE__ */ __name(() => JSON.stringify({ + system, + prompt, + messages + }), "input") + } + } + }), + tracer, + fn: /* @__PURE__ */ __name(async (span) => { + var _a17, _b8, _c, _d, _e, _f, _g; + const callSettings2 = prepareCallSettings(settings); + let currentModelResponse; + let clientToolCalls = []; + let clientToolOutputs = []; + const responseMessages = []; + const steps = []; + do { + const stepInputMessages = [ + ...initialPrompt.messages, + ...responseMessages + ]; + const prepareStepResult = await (prepareStep == null ? void 0 : prepareStep({ + model, + steps, + stepNumber: steps.length, + messages: stepInputMessages + })); + const stepModel = resolveLanguageModel((_a17 = prepareStepResult == null ? void 0 : prepareStepResult.model) != null ? _a17 : model); + const promptMessages = await convertToLanguageModelPrompt({ + prompt: { + system: (_b8 = prepareStepResult == null ? void 0 : prepareStepResult.system) != null ? _b8 : initialPrompt.system, + messages: (_c = prepareStepResult == null ? void 0 : prepareStepResult.messages) != null ? _c : stepInputMessages + }, + supportedUrls: await stepModel.supportedUrls, + download: download2 + }); + const { toolChoice: stepToolChoice, tools: stepTools } = prepareToolsAndToolChoice({ + tools, + toolChoice: (_d = prepareStepResult == null ? void 0 : prepareStepResult.toolChoice) != null ? _d : toolChoice, + activeTools: (_e = prepareStepResult == null ? void 0 : prepareStepResult.activeTools) != null ? _e : activeTools + }); + currentModelResponse = await retry(() => { + var _a18; + return recordSpan({ + name: "ai.generateText.doGenerate", + attributes: selectTelemetryAttributes({ + telemetry, + attributes: { + ...assembleOperationName({ + operationId: "ai.generateText.doGenerate", + telemetry + }), + ...baseTelemetryAttributes, + // model: + "ai.model.provider": stepModel.provider, + "ai.model.id": stepModel.modelId, + // prompt: + "ai.prompt.messages": { + input: /* @__PURE__ */ __name(() => stringifyForTelemetry(promptMessages), "input") + }, + "ai.prompt.tools": { + // convert the language model level tools: + input: /* @__PURE__ */ __name(() => stepTools == null ? void 0 : stepTools.map((tool3) => JSON.stringify(tool3)), "input") + }, + "ai.prompt.toolChoice": { + input: /* @__PURE__ */ __name(() => stepToolChoice != null ? JSON.stringify(stepToolChoice) : void 0, "input") + }, + // standardized gen-ai llm span attributes: + "gen_ai.system": stepModel.provider, + "gen_ai.request.model": stepModel.modelId, + "gen_ai.request.frequency_penalty": settings.frequencyPenalty, + "gen_ai.request.max_tokens": settings.maxOutputTokens, + "gen_ai.request.presence_penalty": settings.presencePenalty, + "gen_ai.request.stop_sequences": settings.stopSequences, + "gen_ai.request.temperature": (_a18 = settings.temperature) != null ? _a18 : void 0, + "gen_ai.request.top_k": settings.topK, + "gen_ai.request.top_p": settings.topP + } + }), + tracer, + fn: /* @__PURE__ */ __name(async (span2) => { + var _a19, _b22, _c2, _d2, _e2, _f2, _g2, _h; + const result = await stepModel.doGenerate({ + ...callSettings2, + tools: stepTools, + toolChoice: stepToolChoice, + responseFormat: output == null ? void 0 : output.responseFormat, + prompt: promptMessages, + providerOptions, + abortSignal, + headers: headersWithUserAgent + }); + const responseData = { + id: (_b22 = (_a19 = result.response) == null ? void 0 : _a19.id) != null ? _b22 : generateId3(), + timestamp: (_d2 = (_c2 = result.response) == null ? void 0 : _c2.timestamp) != null ? _d2 : currentDate(), + modelId: (_f2 = (_e2 = result.response) == null ? void 0 : _e2.modelId) != null ? _f2 : stepModel.modelId, + headers: (_g2 = result.response) == null ? void 0 : _g2.headers, + body: (_h = result.response) == null ? void 0 : _h.body + }; + span2.setAttributes(selectTelemetryAttributes({ + telemetry, + attributes: { + "ai.response.finishReason": result.finishReason, + "ai.response.text": { + output: /* @__PURE__ */ __name(() => extractTextContent(result.content), "output") + }, + "ai.response.toolCalls": { + output: /* @__PURE__ */ __name(() => { + const toolCalls = asToolCalls(result.content); + return toolCalls == null ? void 0 : JSON.stringify(toolCalls); + }, "output") + }, + "ai.response.id": responseData.id, + "ai.response.model": responseData.modelId, + "ai.response.timestamp": responseData.timestamp.toISOString(), + "ai.response.providerMetadata": JSON.stringify(result.providerMetadata), + // TODO rename telemetry attributes to inputTokens and outputTokens + "ai.usage.promptTokens": result.usage.inputTokens, + "ai.usage.completionTokens": result.usage.outputTokens, + // standardized gen-ai llm span attributes: + "gen_ai.response.finish_reasons": [ + result.finishReason + ], + "gen_ai.response.id": responseData.id, + "gen_ai.response.model": responseData.modelId, + "gen_ai.usage.input_tokens": result.usage.inputTokens, + "gen_ai.usage.output_tokens": result.usage.outputTokens + } + })); + return { + ...result, + response: responseData + }; + }, "fn") + }); + }); + const stepToolCalls = await Promise.all(currentModelResponse.content.filter((part) => part.type === "tool-call").map((toolCall) => parseToolCall({ + toolCall, + tools, + repairToolCall, + system, + messages: stepInputMessages + }))); + for (const toolCall of stepToolCalls) { + if (toolCall.invalid) { + continue; + } + const tool3 = tools[toolCall.toolName]; + if ((tool3 == null ? void 0 : tool3.onInputAvailable) != null) { + await tool3.onInputAvailable({ + input: toolCall.input, + toolCallId: toolCall.toolCallId, + messages: stepInputMessages, + abortSignal, + experimental_context + }); + } + } + const invalidToolCalls = stepToolCalls.filter((toolCall) => toolCall.invalid && toolCall.dynamic); + clientToolOutputs = []; + for (const toolCall of invalidToolCalls) { + clientToolOutputs.push({ + type: "tool-error", + toolCallId: toolCall.toolCallId, + toolName: toolCall.toolName, + input: toolCall.input, + error: getErrorMessage2(toolCall.error), + dynamic: true + }); + } + clientToolCalls = stepToolCalls.filter((toolCall) => !toolCall.providerExecuted); + if (tools != null) { + clientToolOutputs.push(...await executeTools({ + toolCalls: clientToolCalls.filter((toolCall) => !toolCall.invalid), + tools, + tracer, + telemetry, + messages: stepInputMessages, + abortSignal, + experimental_context + })); + } + const stepContent = asContent({ + content: currentModelResponse.content, + toolCalls: stepToolCalls, + toolOutputs: clientToolOutputs + }); + responseMessages.push(...toResponseMessages({ + content: stepContent, + tools + })); + const currentStepResult = new DefaultStepResult({ + content: stepContent, + finishReason: currentModelResponse.finishReason, + usage: currentModelResponse.usage, + warnings: currentModelResponse.warnings, + providerMetadata: currentModelResponse.providerMetadata, + request: (_f = currentModelResponse.request) != null ? _f : {}, + response: { + ...currentModelResponse.response, + // deep clone msgs to avoid mutating past messages in multi-step: + messages: structuredClone(responseMessages) + } + }); + logWarnings((_g = currentModelResponse.warnings) != null ? _g : []); + steps.push(currentStepResult); + await (onStepFinish == null ? void 0 : onStepFinish(currentStepResult)); + } while ( + // there are tool calls: + clientToolCalls.length > 0 && // all current tool calls have outputs (incl. execution errors): + clientToolOutputs.length === clientToolCalls.length && // continue until a stop condition is met: + !await isStopConditionMet({ + stopConditions, + steps + }) + ); + span.setAttributes(selectTelemetryAttributes({ + telemetry, + attributes: { + "ai.response.finishReason": currentModelResponse.finishReason, + "ai.response.text": { + output: /* @__PURE__ */ __name(() => extractTextContent(currentModelResponse.content), "output") + }, + "ai.response.toolCalls": { + output: /* @__PURE__ */ __name(() => { + const toolCalls = asToolCalls(currentModelResponse.content); + return toolCalls == null ? void 0 : JSON.stringify(toolCalls); + }, "output") + }, + "ai.response.providerMetadata": JSON.stringify(currentModelResponse.providerMetadata), + // TODO rename telemetry attributes to inputTokens and outputTokens + "ai.usage.promptTokens": currentModelResponse.usage.inputTokens, + "ai.usage.completionTokens": currentModelResponse.usage.outputTokens + } + })); + const lastStep = steps[steps.length - 1]; + let resolvedOutput; + if (lastStep.finishReason === "stop") { + resolvedOutput = await (output == null ? void 0 : output.parseOutput({ + text: lastStep.text + }, { + response: lastStep.response, + usage: lastStep.usage, + finishReason: lastStep.finishReason + })); + } + return new DefaultGenerateTextResult({ + steps, + resolvedOutput + }); + }, "fn") + }); + } catch (error45) { + throw wrapGatewayError(error45); + } +} +__name(generateText, "generateText"); +async function executeTools({ toolCalls, tools, tracer, telemetry, messages, abortSignal, experimental_context }) { + const toolOutputs = await Promise.all(toolCalls.map(async ({ toolCallId, toolName, input }) => { + const tool3 = tools[toolName]; + if ((tool3 == null ? void 0 : tool3.execute) == null) { + return void 0; + } + return recordSpan({ + name: "ai.toolCall", + attributes: selectTelemetryAttributes({ + telemetry, + attributes: { + ...assembleOperationName({ + operationId: "ai.toolCall", + telemetry + }), + "ai.toolCall.name": toolName, + "ai.toolCall.id": toolCallId, + "ai.toolCall.args": { + output: /* @__PURE__ */ __name(() => JSON.stringify(input), "output") + } + } + }), + tracer, + fn: /* @__PURE__ */ __name(async (span) => { + try { + const stream = executeTool({ + execute: tool3.execute.bind(tool3), + input, + options: { + toolCallId, + messages, + abortSignal, + experimental_context + } + }); + let output; + for await (const part of stream) { + if (part.type === "final") { + output = part.output; + } + } + try { + span.setAttributes(selectTelemetryAttributes({ + telemetry, + attributes: { + "ai.toolCall.result": { + output: /* @__PURE__ */ __name(() => JSON.stringify(output), "output") + } + } + })); + } catch (ignored) { + } + return { + type: "tool-result", + toolCallId, + toolName, + input, + output, + dynamic: tool3.type === "dynamic" + }; + } catch (error45) { + recordErrorOnSpan(span, error45); + return { + type: "tool-error", + toolCallId, + toolName, + input, + error: error45, + dynamic: tool3.type === "dynamic" + }; + } + }, "fn") + }); + })); + return toolOutputs.filter((output) => output != null); +} +__name(executeTools, "executeTools"); +var DefaultGenerateTextResult = class { + static { + __name(this, "DefaultGenerateTextResult"); + } + constructor(options) { + this.steps = options.steps; + this.resolvedOutput = options.resolvedOutput; + } + get finalStep() { + return this.steps[this.steps.length - 1]; + } + get content() { + return this.finalStep.content; + } + get text() { + return this.finalStep.text; + } + get files() { + return this.finalStep.files; + } + get reasoningText() { + return this.finalStep.reasoningText; + } + get reasoning() { + return this.finalStep.reasoning; + } + get toolCalls() { + return this.finalStep.toolCalls; + } + get staticToolCalls() { + return this.finalStep.staticToolCalls; + } + get dynamicToolCalls() { + return this.finalStep.dynamicToolCalls; + } + get toolResults() { + return this.finalStep.toolResults; + } + get staticToolResults() { + return this.finalStep.staticToolResults; + } + get dynamicToolResults() { + return this.finalStep.dynamicToolResults; + } + get sources() { + return this.finalStep.sources; + } + get finishReason() { + return this.finalStep.finishReason; + } + get warnings() { + return this.finalStep.warnings; + } + get providerMetadata() { + return this.finalStep.providerMetadata; + } + get response() { + return this.finalStep.response; + } + get request() { + return this.finalStep.request; + } + get usage() { + return this.finalStep.usage; + } + get totalUsage() { + return this.steps.reduce((totalUsage, step) => { + return addLanguageModelUsage(totalUsage, step.usage); + }, { + inputTokens: void 0, + outputTokens: void 0, + totalTokens: void 0, + reasoningTokens: void 0, + cachedInputTokens: void 0 + }); + } + get experimental_output() { + if (this.resolvedOutput == null) { + throw new NoOutputSpecifiedError(); + } + return this.resolvedOutput; + } +}; +function asToolCalls(content) { + const parts = content.filter((part) => part.type === "tool-call"); + if (parts.length === 0) { + return void 0; + } + return parts.map((toolCall) => ({ + toolCallId: toolCall.toolCallId, + toolName: toolCall.toolName, + input: toolCall.input + })); +} +__name(asToolCalls, "asToolCalls"); +function asContent({ content, toolCalls, toolOutputs }) { + return [ + ...content.map((part) => { + switch (part.type) { + case "text": + case "reasoning": + case "source": + return part; + case "file": { + return { + type: "file", + file: new DefaultGeneratedFile(part) + }; + } + case "tool-call": { + return toolCalls.find((toolCall) => toolCall.toolCallId === part.toolCallId); + } + case "tool-result": { + const toolCall = toolCalls.find((toolCall2) => toolCall2.toolCallId === part.toolCallId); + if (toolCall == null) { + throw new Error(\`Tool call \${part.toolCallId} not found.\`); + } + if (part.isError) { + return { + type: "tool-error", + toolCallId: part.toolCallId, + toolName: part.toolName, + input: toolCall.input, + error: part.result, + providerExecuted: true, + dynamic: toolCall.dynamic + }; + } + return { + type: "tool-result", + toolCallId: part.toolCallId, + toolName: part.toolName, + input: toolCall.input, + output: part.result, + providerExecuted: true, + dynamic: toolCall.dynamic + }; + } + } + }), + ...toolOutputs + ]; +} +__name(asContent, "asContent"); +var JsonToSseTransformStream = class extends TransformStream { + static { + __name(this, "JsonToSseTransformStream"); + } + constructor() { + super({ + transform(part, controller) { + controller.enqueue(\`data: \${JSON.stringify(part)} + +\`); + }, + flush(controller) { + controller.enqueue("data: [DONE]\\n\\n"); + } + }); + } +}; +var uiMessageChunkSchema = lazyValidator(() => zodSchema(external_exports.union([ + external_exports.strictObject({ + type: external_exports.literal("text-start"), + id: external_exports.string(), + providerMetadata: providerMetadataSchema.optional() + }), + external_exports.strictObject({ + type: external_exports.literal("text-delta"), + id: external_exports.string(), + delta: external_exports.string(), + providerMetadata: providerMetadataSchema.optional() + }), + external_exports.strictObject({ + type: external_exports.literal("text-end"), + id: external_exports.string(), + providerMetadata: providerMetadataSchema.optional() + }), + external_exports.strictObject({ + type: external_exports.literal("error"), + errorText: external_exports.string() + }), + external_exports.strictObject({ + type: external_exports.literal("tool-input-start"), + toolCallId: external_exports.string(), + toolName: external_exports.string(), + providerExecuted: external_exports.boolean().optional(), + dynamic: external_exports.boolean().optional() + }), + external_exports.strictObject({ + type: external_exports.literal("tool-input-delta"), + toolCallId: external_exports.string(), + inputTextDelta: external_exports.string() + }), + external_exports.strictObject({ + type: external_exports.literal("tool-input-available"), + toolCallId: external_exports.string(), + toolName: external_exports.string(), + input: external_exports.unknown(), + providerExecuted: external_exports.boolean().optional(), + providerMetadata: providerMetadataSchema.optional(), + dynamic: external_exports.boolean().optional() + }), + external_exports.strictObject({ + type: external_exports.literal("tool-input-error"), + toolCallId: external_exports.string(), + toolName: external_exports.string(), + input: external_exports.unknown(), + providerExecuted: external_exports.boolean().optional(), + providerMetadata: providerMetadataSchema.optional(), + dynamic: external_exports.boolean().optional(), + errorText: external_exports.string() + }), + external_exports.strictObject({ + type: external_exports.literal("tool-output-available"), + toolCallId: external_exports.string(), + output: external_exports.unknown(), + providerExecuted: external_exports.boolean().optional(), + dynamic: external_exports.boolean().optional(), + preliminary: external_exports.boolean().optional() + }), + external_exports.strictObject({ + type: external_exports.literal("tool-output-error"), + toolCallId: external_exports.string(), + errorText: external_exports.string(), + providerExecuted: external_exports.boolean().optional(), + dynamic: external_exports.boolean().optional() + }), + external_exports.strictObject({ + type: external_exports.literal("reasoning-start"), + id: external_exports.string(), + providerMetadata: providerMetadataSchema.optional() + }), + external_exports.strictObject({ + type: external_exports.literal("reasoning-delta"), + id: external_exports.string(), + delta: external_exports.string(), + providerMetadata: providerMetadataSchema.optional() + }), + external_exports.strictObject({ + type: external_exports.literal("reasoning-end"), + id: external_exports.string(), + providerMetadata: providerMetadataSchema.optional() + }), + external_exports.strictObject({ + type: external_exports.literal("source-url"), + sourceId: external_exports.string(), + url: external_exports.string(), + title: external_exports.string().optional(), + providerMetadata: providerMetadataSchema.optional() + }), + external_exports.strictObject({ + type: external_exports.literal("source-document"), + sourceId: external_exports.string(), + mediaType: external_exports.string(), + title: external_exports.string(), + filename: external_exports.string().optional(), + providerMetadata: providerMetadataSchema.optional() + }), + external_exports.strictObject({ + type: external_exports.literal("file"), + url: external_exports.string(), + mediaType: external_exports.string(), + providerMetadata: providerMetadataSchema.optional() + }), + external_exports.strictObject({ + type: external_exports.custom((value) => typeof value === "string" && value.startsWith("data-"), { + message: 'Type must start with "data-"' + }), + id: external_exports.string().optional(), + data: external_exports.unknown(), + transient: external_exports.boolean().optional() + }), + external_exports.strictObject({ + type: external_exports.literal("start-step") + }), + external_exports.strictObject({ + type: external_exports.literal("finish-step") + }), + external_exports.strictObject({ + type: external_exports.literal("start"), + messageId: external_exports.string().optional(), + messageMetadata: external_exports.unknown().optional() + }), + external_exports.strictObject({ + type: external_exports.literal("finish"), + messageMetadata: external_exports.unknown().optional() + }), + external_exports.strictObject({ + type: external_exports.literal("abort") + }), + external_exports.strictObject({ + type: external_exports.literal("message-metadata"), + messageMetadata: external_exports.unknown() + }) +]))); +function fixJson(input) { + const stack = [ + "ROOT" + ]; + let lastValidIndex = -1; + let literalStart = null; + function processValueStart(char, i, swapState) { + { + switch (char) { + case '"': { + lastValidIndex = i; + stack.pop(); + stack.push(swapState); + stack.push("INSIDE_STRING"); + break; + } + case "f": + case "t": + case "n": { + lastValidIndex = i; + literalStart = i; + stack.pop(); + stack.push(swapState); + stack.push("INSIDE_LITERAL"); + break; + } + case "-": { + stack.pop(); + stack.push(swapState); + stack.push("INSIDE_NUMBER"); + break; + } + case "0": + case "1": + case "2": + case "3": + case "4": + case "5": + case "6": + case "7": + case "8": + case "9": { + lastValidIndex = i; + stack.pop(); + stack.push(swapState); + stack.push("INSIDE_NUMBER"); + break; + } + case "{": { + lastValidIndex = i; + stack.pop(); + stack.push(swapState); + stack.push("INSIDE_OBJECT_START"); + break; + } + case "[": { + lastValidIndex = i; + stack.pop(); + stack.push(swapState); + stack.push("INSIDE_ARRAY_START"); + break; + } + } + } + } + __name(processValueStart, "processValueStart"); + function processAfterObjectValue(char, i) { + switch (char) { + case ",": { + stack.pop(); + stack.push("INSIDE_OBJECT_AFTER_COMMA"); + break; + } + case "}": { + lastValidIndex = i; + stack.pop(); + break; + } + } + } + __name(processAfterObjectValue, "processAfterObjectValue"); + function processAfterArrayValue(char, i) { + switch (char) { + case ",": { + stack.pop(); + stack.push("INSIDE_ARRAY_AFTER_COMMA"); + break; + } + case "]": { + lastValidIndex = i; + stack.pop(); + break; + } + } + } + __name(processAfterArrayValue, "processAfterArrayValue"); + for (let i = 0; i < input.length; i++) { + const char = input[i]; + const currentState = stack[stack.length - 1]; + switch (currentState) { + case "ROOT": + processValueStart(char, i, "FINISH"); + break; + case "INSIDE_OBJECT_START": { + switch (char) { + case '"': { + stack.pop(); + stack.push("INSIDE_OBJECT_KEY"); + break; + } + case "}": { + lastValidIndex = i; + stack.pop(); + break; + } + } + break; + } + case "INSIDE_OBJECT_AFTER_COMMA": { + switch (char) { + case '"': { + stack.pop(); + stack.push("INSIDE_OBJECT_KEY"); + break; + } + } + break; + } + case "INSIDE_OBJECT_KEY": { + switch (char) { + case '"': { + stack.pop(); + stack.push("INSIDE_OBJECT_AFTER_KEY"); + break; + } + } + break; + } + case "INSIDE_OBJECT_AFTER_KEY": { + switch (char) { + case ":": { + stack.pop(); + stack.push("INSIDE_OBJECT_BEFORE_VALUE"); + break; + } + } + break; + } + case "INSIDE_OBJECT_BEFORE_VALUE": { + processValueStart(char, i, "INSIDE_OBJECT_AFTER_VALUE"); + break; + } + case "INSIDE_OBJECT_AFTER_VALUE": { + processAfterObjectValue(char, i); + break; + } + case "INSIDE_STRING": { + switch (char) { + case '"': { + stack.pop(); + lastValidIndex = i; + break; + } + case "\\\\": { + stack.push("INSIDE_STRING_ESCAPE"); + break; + } + default: { + lastValidIndex = i; + } + } + break; + } + case "INSIDE_ARRAY_START": { + switch (char) { + case "]": { + lastValidIndex = i; + stack.pop(); + break; + } + default: { + lastValidIndex = i; + processValueStart(char, i, "INSIDE_ARRAY_AFTER_VALUE"); + break; + } + } + break; + } + case "INSIDE_ARRAY_AFTER_VALUE": { + switch (char) { + case ",": { + stack.pop(); + stack.push("INSIDE_ARRAY_AFTER_COMMA"); + break; + } + case "]": { + lastValidIndex = i; + stack.pop(); + break; + } + default: { + lastValidIndex = i; + break; + } + } + break; + } + case "INSIDE_ARRAY_AFTER_COMMA": { + processValueStart(char, i, "INSIDE_ARRAY_AFTER_VALUE"); + break; + } + case "INSIDE_STRING_ESCAPE": { + stack.pop(); + lastValidIndex = i; + break; + } + case "INSIDE_NUMBER": { + switch (char) { + case "0": + case "1": + case "2": + case "3": + case "4": + case "5": + case "6": + case "7": + case "8": + case "9": { + lastValidIndex = i; + break; + } + case "e": + case "E": + case "-": + case ".": { + break; + } + case ",": { + stack.pop(); + if (stack[stack.length - 1] === "INSIDE_ARRAY_AFTER_VALUE") { + processAfterArrayValue(char, i); + } + if (stack[stack.length - 1] === "INSIDE_OBJECT_AFTER_VALUE") { + processAfterObjectValue(char, i); + } + break; + } + case "}": { + stack.pop(); + if (stack[stack.length - 1] === "INSIDE_OBJECT_AFTER_VALUE") { + processAfterObjectValue(char, i); + } + break; + } + case "]": { + stack.pop(); + if (stack[stack.length - 1] === "INSIDE_ARRAY_AFTER_VALUE") { + processAfterArrayValue(char, i); + } + break; + } + default: { + stack.pop(); + break; + } + } + break; + } + case "INSIDE_LITERAL": { + const partialLiteral = input.substring(literalStart, i + 1); + if (!"false".startsWith(partialLiteral) && !"true".startsWith(partialLiteral) && !"null".startsWith(partialLiteral)) { + stack.pop(); + if (stack[stack.length - 1] === "INSIDE_OBJECT_AFTER_VALUE") { + processAfterObjectValue(char, i); + } else if (stack[stack.length - 1] === "INSIDE_ARRAY_AFTER_VALUE") { + processAfterArrayValue(char, i); + } + } else { + lastValidIndex = i; + } + break; + } + } + } + let result = input.slice(0, lastValidIndex + 1); + for (let i = stack.length - 1; i >= 0; i--) { + const state = stack[i]; + switch (state) { + case "INSIDE_STRING": { + result += '"'; + break; + } + case "INSIDE_OBJECT_KEY": + case "INSIDE_OBJECT_AFTER_KEY": + case "INSIDE_OBJECT_AFTER_COMMA": + case "INSIDE_OBJECT_START": + case "INSIDE_OBJECT_BEFORE_VALUE": + case "INSIDE_OBJECT_AFTER_VALUE": { + result += "}"; + break; + } + case "INSIDE_ARRAY_START": + case "INSIDE_ARRAY_AFTER_COMMA": + case "INSIDE_ARRAY_AFTER_VALUE": { + result += "]"; + break; + } + case "INSIDE_LITERAL": { + const partialLiteral = input.substring(literalStart, input.length); + if ("true".startsWith(partialLiteral)) { + result += "true".slice(partialLiteral.length); + } else if ("false".startsWith(partialLiteral)) { + result += "false".slice(partialLiteral.length); + } else if ("null".startsWith(partialLiteral)) { + result += "null".slice(partialLiteral.length); + } + } + } + } + return result; +} +__name(fixJson, "fixJson"); +async function parsePartialJson(jsonText) { + if (jsonText === void 0) { + return { + value: void 0, + state: "undefined-input" + }; + } + let result = await safeParseJSON({ + text: jsonText + }); + if (result.success) { + return { + value: result.value, + state: "successful-parse" + }; + } + result = await safeParseJSON({ + text: fixJson(jsonText) + }); + if (result.success) { + return { + value: result.value, + state: "repaired-parse" + }; + } + return { + value: void 0, + state: "failed-parse" + }; +} +__name(parsePartialJson, "parsePartialJson"); +var output_exports = {}; +__export2(output_exports, { + object: /* @__PURE__ */ __name(() => object2, "object"), + text: /* @__PURE__ */ __name(() => text, "text") +}); +var text = /* @__PURE__ */ __name(() => ({ + type: "text", + responseFormat: { + type: "text" + }, + async parsePartial({ text: text2 }) { + return { + partial: text2 + }; + }, + async parseOutput({ text: text2 }) { + return text2; + } +}), "text"); +var object2 = /* @__PURE__ */ __name(({ schema: inputSchema }) => { + const schema = asSchema(inputSchema); + return { + type: "object", + responseFormat: { + type: "json", + schema: schema.jsonSchema + }, + async parsePartial({ text: text2 }) { + const result = await parsePartialJson(text2); + switch (result.state) { + case "failed-parse": + case "undefined-input": + return void 0; + case "repaired-parse": + case "successful-parse": + return { + // Note: currently no validation of partial results: + partial: result.value + }; + default: { + const _exhaustiveCheck = result.state; + throw new Error(\`Unsupported parse state: \${_exhaustiveCheck}\`); + } + } + }, + async parseOutput({ text: text2 }, context) { + const parseResult = await safeParseJSON({ + text: text2 + }); + if (!parseResult.success) { + throw new NoObjectGeneratedError({ + message: "No object generated: could not parse the response.", + cause: parseResult.error, + text: text2, + response: context.response, + usage: context.usage, + finishReason: context.finishReason + }); + } + const validationResult = await safeValidateTypes({ + value: parseResult.value, + schema + }); + if (!validationResult.success) { + throw new NoObjectGeneratedError({ + message: "No object generated: response did not match schema.", + cause: validationResult.error, + text: text2, + response: context.response, + usage: context.usage, + finishReason: context.finishReason + }); + } + return validationResult.value; + } + }; +}, "object"); +var name16 = "AI_NoSuchProviderError"; +var marker162 = \`vercel.ai.error.\${name16}\`; +var symbol162 = Symbol.for(marker162); +var _a162; +_a162 = symbol162; +var ClientOrServerImplementationSchema = external_exports.looseObject({ + name: external_exports.string(), + version: external_exports.string() +}); +var BaseParamsSchema = external_exports.looseObject({ + _meta: external_exports.optional(external_exports.object({}).loose()) +}); +var ResultSchema = BaseParamsSchema; +var RequestSchema = external_exports.object({ + method: external_exports.string(), + params: external_exports.optional(BaseParamsSchema) +}); +var ServerCapabilitiesSchema = external_exports.looseObject({ + experimental: external_exports.optional(external_exports.object({}).loose()), + logging: external_exports.optional(external_exports.object({}).loose()), + prompts: external_exports.optional(external_exports.looseObject({ + listChanged: external_exports.optional(external_exports.boolean()) + })), + resources: external_exports.optional(external_exports.looseObject({ + subscribe: external_exports.optional(external_exports.boolean()), + listChanged: external_exports.optional(external_exports.boolean()) + })), + tools: external_exports.optional(external_exports.looseObject({ + listChanged: external_exports.optional(external_exports.boolean()) + })) +}); +var InitializeResultSchema = ResultSchema.extend({ + protocolVersion: external_exports.string(), + capabilities: ServerCapabilitiesSchema, + serverInfo: ClientOrServerImplementationSchema, + instructions: external_exports.optional(external_exports.string()) +}); +var PaginatedResultSchema = ResultSchema.extend({ + nextCursor: external_exports.optional(external_exports.string()) +}); +var ToolSchema = external_exports.object({ + name: external_exports.string(), + description: external_exports.optional(external_exports.string()), + inputSchema: external_exports.object({ + type: external_exports.literal("object"), + properties: external_exports.optional(external_exports.object({}).loose()) + }).loose() +}).loose(); +var ListToolsResultSchema = PaginatedResultSchema.extend({ + tools: external_exports.array(ToolSchema) +}); +var TextContentSchema = external_exports.object({ + type: external_exports.literal("text"), + text: external_exports.string() +}).loose(); +var ImageContentSchema = external_exports.object({ + type: external_exports.literal("image"), + data: external_exports.base64(), + mimeType: external_exports.string() +}).loose(); +var ResourceContentsSchema = external_exports.object({ + /** + * The URI of this resource. + */ + uri: external_exports.string(), + /** + * The MIME type of this resource, if known. + */ + mimeType: external_exports.optional(external_exports.string()) +}).loose(); +var TextResourceContentsSchema = ResourceContentsSchema.extend({ + text: external_exports.string() +}); +var BlobResourceContentsSchema = ResourceContentsSchema.extend({ + blob: external_exports.base64() +}); +var EmbeddedResourceSchema = external_exports.object({ + type: external_exports.literal("resource"), + resource: external_exports.union([ + TextResourceContentsSchema, + BlobResourceContentsSchema + ]) +}).loose(); +var CallToolResultSchema = ResultSchema.extend({ + content: external_exports.array(external_exports.union([ + TextContentSchema, + ImageContentSchema, + EmbeddedResourceSchema + ])), + isError: external_exports.boolean().default(false).optional() +}).or(ResultSchema.extend({ + toolResult: external_exports.unknown() +})); +var JSONRPC_VERSION = "2.0"; +var JSONRPCRequestSchema = external_exports.object({ + jsonrpc: external_exports.literal(JSONRPC_VERSION), + id: external_exports.union([ + external_exports.string(), + external_exports.number().int() + ]) +}).merge(RequestSchema).strict(); +var JSONRPCResponseSchema = external_exports.object({ + jsonrpc: external_exports.literal(JSONRPC_VERSION), + id: external_exports.union([ + external_exports.string(), + external_exports.number().int() + ]), + result: ResultSchema +}).strict(); +var JSONRPCErrorSchema = external_exports.object({ + jsonrpc: external_exports.literal(JSONRPC_VERSION), + id: external_exports.union([ + external_exports.string(), + external_exports.number().int() + ]), + error: external_exports.object({ + code: external_exports.number().int(), + message: external_exports.string(), + data: external_exports.optional(external_exports.unknown()) + }) +}).strict(); +var JSONRPCNotificationSchema = external_exports.object({ + jsonrpc: external_exports.literal(JSONRPC_VERSION) +}).merge(external_exports.object({ + method: external_exports.string(), + params: external_exports.optional(BaseParamsSchema) +})).strict(); +var JSONRPCMessageSchema = external_exports.union([ + JSONRPCRequestSchema, + JSONRPCNotificationSchema, + JSONRPCResponseSchema, + JSONRPCErrorSchema +]); +var uiMessagesSchema = lazyValidator(() => zodSchema(external_exports.array(external_exports.object({ + id: external_exports.string(), + role: external_exports.enum([ + "system", + "user", + "assistant" + ]), + metadata: external_exports.unknown().optional(), + parts: external_exports.array(external_exports.union([ + external_exports.object({ + type: external_exports.literal("text"), + text: external_exports.string(), + state: external_exports.enum([ + "streaming", + "done" + ]).optional(), + providerMetadata: providerMetadataSchema.optional() + }), + external_exports.object({ + type: external_exports.literal("reasoning"), + text: external_exports.string(), + state: external_exports.enum([ + "streaming", + "done" + ]).optional(), + providerMetadata: providerMetadataSchema.optional() + }), + external_exports.object({ + type: external_exports.literal("source-url"), + sourceId: external_exports.string(), + url: external_exports.string(), + title: external_exports.string().optional(), + providerMetadata: providerMetadataSchema.optional() + }), + external_exports.object({ + type: external_exports.literal("source-document"), + sourceId: external_exports.string(), + mediaType: external_exports.string(), + title: external_exports.string(), + filename: external_exports.string().optional(), + providerMetadata: providerMetadataSchema.optional() + }), + external_exports.object({ + type: external_exports.literal("file"), + mediaType: external_exports.string(), + filename: external_exports.string().optional(), + url: external_exports.string(), + providerMetadata: providerMetadataSchema.optional() + }), + external_exports.object({ + type: external_exports.literal("step-start") + }), + external_exports.object({ + type: external_exports.string().startsWith("data-"), + id: external_exports.string().optional(), + data: external_exports.unknown() + }), + external_exports.object({ + type: external_exports.literal("dynamic-tool"), + toolName: external_exports.string(), + toolCallId: external_exports.string(), + state: external_exports.literal("input-streaming"), + input: external_exports.unknown().optional(), + output: external_exports.never().optional(), + errorText: external_exports.never().optional() + }), + external_exports.object({ + type: external_exports.literal("dynamic-tool"), + toolName: external_exports.string(), + toolCallId: external_exports.string(), + state: external_exports.literal("input-available"), + input: external_exports.unknown(), + output: external_exports.never().optional(), + errorText: external_exports.never().optional(), + callProviderMetadata: providerMetadataSchema.optional() + }), + external_exports.object({ + type: external_exports.literal("dynamic-tool"), + toolName: external_exports.string(), + toolCallId: external_exports.string(), + state: external_exports.literal("output-available"), + input: external_exports.unknown(), + output: external_exports.unknown(), + errorText: external_exports.never().optional(), + callProviderMetadata: providerMetadataSchema.optional(), + preliminary: external_exports.boolean().optional() + }), + external_exports.object({ + type: external_exports.literal("dynamic-tool"), + toolName: external_exports.string(), + toolCallId: external_exports.string(), + state: external_exports.literal("output-error"), + input: external_exports.unknown(), + output: external_exports.never().optional(), + errorText: external_exports.string(), + callProviderMetadata: providerMetadataSchema.optional() + }), + external_exports.object({ + type: external_exports.string().startsWith("tool-"), + toolCallId: external_exports.string(), + state: external_exports.literal("input-streaming"), + providerExecuted: external_exports.boolean().optional(), + input: external_exports.unknown().optional(), + output: external_exports.never().optional(), + errorText: external_exports.never().optional(), + approval: external_exports.never().optional() + }), + external_exports.object({ + type: external_exports.string().startsWith("tool-"), + toolCallId: external_exports.string(), + state: external_exports.literal("input-available"), + providerExecuted: external_exports.boolean().optional(), + input: external_exports.unknown(), + output: external_exports.never().optional(), + errorText: external_exports.never().optional(), + callProviderMetadata: providerMetadataSchema.optional(), + approval: external_exports.never().optional() + }), + external_exports.object({ + type: external_exports.string().startsWith("tool-"), + toolCallId: external_exports.string(), + state: external_exports.literal("approval-requested"), + input: external_exports.unknown(), + providerExecuted: external_exports.boolean().optional(), + output: external_exports.never().optional(), + errorText: external_exports.never().optional(), + callProviderMetadata: providerMetadataSchema.optional(), + approval: external_exports.object({ + id: external_exports.string(), + approved: external_exports.never().optional(), + reason: external_exports.never().optional() + }) + }), + external_exports.object({ + type: external_exports.string().startsWith("tool-"), + toolCallId: external_exports.string(), + state: external_exports.literal("approval-responded"), + input: external_exports.unknown(), + providerExecuted: external_exports.boolean().optional(), + output: external_exports.never().optional(), + errorText: external_exports.never().optional(), + callProviderMetadata: providerMetadataSchema.optional(), + approval: external_exports.object({ + id: external_exports.string(), + approved: external_exports.boolean(), + reason: external_exports.string().optional() + }) + }), + external_exports.object({ + type: external_exports.string().startsWith("tool-"), + toolCallId: external_exports.string(), + state: external_exports.literal("output-available"), + providerExecuted: external_exports.boolean().optional(), + input: external_exports.unknown(), + output: external_exports.unknown(), + errorText: external_exports.never().optional(), + callProviderMetadata: providerMetadataSchema.optional(), + preliminary: external_exports.boolean().optional(), + approval: external_exports.object({ + id: external_exports.string(), + approved: external_exports.literal(true), + reason: external_exports.string().optional() + }).optional() + }), + external_exports.object({ + type: external_exports.string().startsWith("tool-"), + toolCallId: external_exports.string(), + state: external_exports.literal("output-error"), + providerExecuted: external_exports.boolean().optional(), + input: external_exports.unknown(), + output: external_exports.never().optional(), + errorText: external_exports.string(), + callProviderMetadata: providerMetadataSchema.optional(), + approval: external_exports.object({ + id: external_exports.string(), + approved: external_exports.literal(true), + reason: external_exports.string().optional() + }).optional() + }), + external_exports.object({ + type: external_exports.string().startsWith("tool-"), + toolCallId: external_exports.string(), + state: external_exports.literal("output-denied"), + providerExecuted: external_exports.boolean().optional(), + input: external_exports.unknown(), + output: external_exports.never().optional(), + errorText: external_exports.never().optional(), + callProviderMetadata: providerMetadataSchema.optional(), + approval: external_exports.object({ + id: external_exports.string(), + approved: external_exports.literal(false), + reason: external_exports.string().optional() + }) + }) + ])) +})))); + +// ../example/workflows/4_ai.ts +async function getWeatherInformation({ city }) { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/4_ai.ts//getWeatherInformation")({ + city + }); +} +__name(getWeatherInformation, "getWeatherInformation"); +async function ai(prompt) { + console.log("AI workflow started"); + const { text: text2 } = await generateText({ + model: "openai/o3", + prompt + }); + console.log(\`AI workflow completed. Result: \${text2}\`); + return text2; +} +__name(ai, "ai"); +async function agent(prompt) { + console.log("Agent workflow started"); + const { text: text2 } = await generateText({ + model: "anthropic/claude-4-opus-20250514", + prompt, + tools: { + getWeatherInformation: { + description: "show the weather in a given city to the user", + inputSchema: v4_default.object({ + city: v4_default.string() + }), + execute: getWeatherInformation + } + }, + // This can be a high as you want - no restriction on the lambda workflow runtime + stopWhen: stepCountIs(10) + }); + console.log(\`Agent workflow completed. Result: \${text2}\`); + return text2; +} +__name(agent, "agent"); +ai.workflowId = "workflow//example/workflows/4_ai.ts//ai"; +agent.workflowId = "workflow//example/workflows/4_ai.ts//agent"; +Object.defineProperty(getWeatherInformation, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/4_ai.ts//getWeatherInformation", + writable: false, + enumerable: false, + configurable: false +}); + +// ../example/workflows/3_streams.ts +var streams_exports = {}; +__export(streams_exports, { + consumeStreams: () => consumeStreams, + genStream: () => genStream, + streams: () => streams +}); +async function genStream() { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/3_streams.ts//genStream")(); +} +__name(genStream, "genStream"); +async function consumeStreams(...streams2) { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/3_streams.ts//consumeStreams")(...streams2); +} +__name(consumeStreams, "consumeStreams"); +async function streams() { + console.log("Streams workflow started"); + const [s1, s2] = await Promise.all([ + genStream(), + genStream() + ]); + const result = await consumeStreams(s1, s2); + console.log(\`Streams workflow completed. Result: \${result.slice(0, 100)}\`); + return { + message: "Streams processed successfully", + dataLength: result.length, + preview: result.slice(0, 100) + }; +} +__name(streams, "streams"); +streams.workflowId = "workflow//example/workflows/3_streams.ts//streams"; +Object.defineProperty(genStream, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/3_streams.ts//genStream", + writable: false, + enumerable: false, + configurable: false +}); +Object.defineProperty(consumeStreams, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/3_streams.ts//consumeStreams", + writable: false, + enumerable: false, + configurable: false +}); + +// ../example/workflows/7_full.ts +var full_exports = {}; +__export(full_exports, { + handleUserSignup: () => handleUserSignup +}); +async function handleUserSignup(email3) { + const user = await createUser(email3); + await sendWelcomeEmail(user); + await sleep("5s"); + const webhook = createWebhook(); + await sendOnboardingEmail(user, webhook.url); + await webhook; + console.log("Webhook Resolved"); + return { + userId: user.id, + status: "onboarded" + }; +} +__name(handleUserSignup, "handleUserSignup"); +async function createUser(email3) { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/7_full.ts//createUser")(email3); +} +__name(createUser, "createUser"); +async function sendWelcomeEmail(user) { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/7_full.ts//sendWelcomeEmail")(user); +} +__name(sendWelcomeEmail, "sendWelcomeEmail"); +async function sendOnboardingEmail(user, callback) { + return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/7_full.ts//sendOnboardingEmail")(user, callback); +} +__name(sendOnboardingEmail, "sendOnboardingEmail"); +handleUserSignup.workflowId = "workflow//example/workflows/7_full.ts//handleUserSignup"; +Object.defineProperty(createUser, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/7_full.ts//createUser", + writable: false, + enumerable: false, + configurable: false +}); +Object.defineProperty(sendWelcomeEmail, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/7_full.ts//sendWelcomeEmail", + writable: false, + enumerable: false, + configurable: false +}); +Object.defineProperty(sendOnboardingEmail, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { + value: "step//example/workflows/7_full.ts//sendOnboardingEmail", + writable: false, + enumerable: false, + configurable: false +}); + +// virtual-entry.js +globalThis.__private_workflows = /* @__PURE__ */ new Map(); +Object.values(e2e_exports).map((item) => item?.workflowId && globalThis.__private_workflows.set(item.workflowId, item)); +Object.values(control_flow_exports).map((item) => item?.workflowId && globalThis.__private_workflows.set(item.workflowId, item)); +Object.values(demo_exports).map((item) => item?.workflowId && globalThis.__private_workflows.set(item.workflowId, item)); +Object.values(duplicate_case_exports).map((item) => item?.workflowId && globalThis.__private_workflows.set(item.workflowId, item)); +Object.values(batching_exports).map((item) => item?.workflowId && globalThis.__private_workflows.set(item.workflowId, item)); +Object.values(simple_exports).map((item) => item?.workflowId && globalThis.__private_workflows.set(item.workflowId, item)); +Object.values(hooks_exports).map((item) => item?.workflowId && globalThis.__private_workflows.set(item.workflowId, item)); +Object.values(ai_exports).map((item) => item?.workflowId && globalThis.__private_workflows.set(item.workflowId, item)); +Object.values(streams_exports).map((item) => item?.workflowId && globalThis.__private_workflows.set(item.workflowId, item)); +Object.values(full_exports).map((item) => item?.workflowId && globalThis.__private_workflows.set(item.workflowId, item)); +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL21zQDIuMS4zL25vZGVfbW9kdWxlcy9tcy9pbmRleC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vbG9kYXNoLmNodW5rQDQuMi4wL25vZGVfbW9kdWxlcy9sb2Rhc2guY2h1bmsvaW5kZXguanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B2ZXJjZWwrb2lkY0AzLjAuMy9ub2RlX21vZHVsZXMvQHZlcmNlbC9vaWRjL2Rpc3QvZ2V0LWNvbnRleHQuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B2ZXJjZWwrb2lkY0AzLjAuMy9ub2RlX21vZHVsZXMvQHZlcmNlbC9vaWRjL2Rpc3QvaW5kZXgtYnJvd3Nlci5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL3BsYXRmb3JtL25vZGUvZ2xvYmFsVGhpcy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL3BsYXRmb3JtL25vZGUvaW5kZXgudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BvcGVudGVsZW1ldHJ5K2FwaUAxLjkuMC9ub2RlX21vZHVsZXMvQG9wZW50ZWxlbWV0cnkvYXBpL3NyYy9wbGF0Zm9ybS9pbmRleC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL3ZlcnNpb24udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BvcGVudGVsZW1ldHJ5K2FwaUAxLjkuMC9ub2RlX21vZHVsZXMvQG9wZW50ZWxlbWV0cnkvYXBpL3NyYy9pbnRlcm5hbC9zZW12ZXIudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BvcGVudGVsZW1ldHJ5K2FwaUAxLjkuMC9ub2RlX21vZHVsZXMvQG9wZW50ZWxlbWV0cnkvYXBpL3NyYy9pbnRlcm5hbC9nbG9iYWwtdXRpbHMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BvcGVudGVsZW1ldHJ5K2FwaUAxLjkuMC9ub2RlX21vZHVsZXMvQG9wZW50ZWxlbWV0cnkvYXBpL3NyYy9kaWFnL0NvbXBvbmVudExvZ2dlci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL2RpYWcvdHlwZXMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BvcGVudGVsZW1ldHJ5K2FwaUAxLjkuMC9ub2RlX21vZHVsZXMvQG9wZW50ZWxlbWV0cnkvYXBpL3NyYy9kaWFnL2ludGVybmFsL2xvZ0xldmVsTG9nZ2VyLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjAvbm9kZV9tb2R1bGVzL0BvcGVudGVsZW1ldHJ5L2FwaS9zcmMvYXBpL2RpYWcudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BvcGVudGVsZW1ldHJ5K2FwaUAxLjkuMC9ub2RlX21vZHVsZXMvQG9wZW50ZWxlbWV0cnkvYXBpL3NyYy9iYWdnYWdlL2ludGVybmFsL2JhZ2dhZ2UtaW1wbC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL2JhZ2dhZ2UvaW50ZXJuYWwvc3ltYm9sLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjAvbm9kZV9tb2R1bGVzL0BvcGVudGVsZW1ldHJ5L2FwaS9zcmMvYmFnZ2FnZS91dGlscy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL2NvbnRleHQvY29udGV4dC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL2RpYWcvY29uc29sZUxvZ2dlci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL21ldHJpY3MvTm9vcE1ldGVyLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjAvbm9kZV9tb2R1bGVzL0BvcGVudGVsZW1ldHJ5L2FwaS9zcmMvbWV0cmljcy9NZXRyaWMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BvcGVudGVsZW1ldHJ5K2FwaUAxLjkuMC9ub2RlX21vZHVsZXMvQG9wZW50ZWxlbWV0cnkvYXBpL3NyYy9wcm9wYWdhdGlvbi9UZXh0TWFwUHJvcGFnYXRvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL2NvbnRleHQvTm9vcENvbnRleHRNYW5hZ2VyLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjAvbm9kZV9tb2R1bGVzL0BvcGVudGVsZW1ldHJ5L2FwaS9zcmMvYXBpL2NvbnRleHQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BvcGVudGVsZW1ldHJ5K2FwaUAxLjkuMC9ub2RlX21vZHVsZXMvQG9wZW50ZWxlbWV0cnkvYXBpL3NyYy90cmFjZS90cmFjZV9mbGFncy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL3RyYWNlL2ludmFsaWQtc3Bhbi1jb25zdGFudHMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BvcGVudGVsZW1ldHJ5K2FwaUAxLjkuMC9ub2RlX21vZHVsZXMvQG9wZW50ZWxlbWV0cnkvYXBpL3NyYy90cmFjZS9Ob25SZWNvcmRpbmdTcGFuLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjAvbm9kZV9tb2R1bGVzL0BvcGVudGVsZW1ldHJ5L2FwaS9zcmMvdHJhY2UvY29udGV4dC11dGlscy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL3RyYWNlL3NwYW5jb250ZXh0LXV0aWxzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjAvbm9kZV9tb2R1bGVzL0BvcGVudGVsZW1ldHJ5L2FwaS9zcmMvdHJhY2UvTm9vcFRyYWNlci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL3RyYWNlL1Byb3h5VHJhY2VyLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjAvbm9kZV9tb2R1bGVzL0BvcGVudGVsZW1ldHJ5L2FwaS9zcmMvdHJhY2UvTm9vcFRyYWNlclByb3ZpZGVyLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjAvbm9kZV9tb2R1bGVzL0BvcGVudGVsZW1ldHJ5L2FwaS9zcmMvdHJhY2UvUHJveHlUcmFjZXJQcm92aWRlci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL3RyYWNlL1NhbXBsaW5nUmVzdWx0LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjAvbm9kZV9tb2R1bGVzL0BvcGVudGVsZW1ldHJ5L2FwaS9zcmMvdHJhY2Uvc3Bhbl9raW5kLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjAvbm9kZV9tb2R1bGVzL0BvcGVudGVsZW1ldHJ5L2FwaS9zcmMvdHJhY2Uvc3RhdHVzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjAvbm9kZV9tb2R1bGVzL0BvcGVudGVsZW1ldHJ5L2FwaS9zcmMvdHJhY2UvaW50ZXJuYWwvdHJhY2VzdGF0ZS12YWxpZGF0b3JzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjAvbm9kZV9tb2R1bGVzL0BvcGVudGVsZW1ldHJ5L2FwaS9zcmMvdHJhY2UvaW50ZXJuYWwvdHJhY2VzdGF0ZS1pbXBsLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjAvbm9kZV9tb2R1bGVzL0BvcGVudGVsZW1ldHJ5L2FwaS9zcmMvdHJhY2UvaW50ZXJuYWwvdXRpbHMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BvcGVudGVsZW1ldHJ5K2FwaUAxLjkuMC9ub2RlX21vZHVsZXMvQG9wZW50ZWxlbWV0cnkvYXBpL3NyYy9jb250ZXh0LWFwaS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL2RpYWctYXBpLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjAvbm9kZV9tb2R1bGVzL0BvcGVudGVsZW1ldHJ5L2FwaS9zcmMvbWV0cmljcy9Ob29wTWV0ZXJQcm92aWRlci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL2FwaS9tZXRyaWNzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjAvbm9kZV9tb2R1bGVzL0BvcGVudGVsZW1ldHJ5L2FwaS9zcmMvbWV0cmljcy1hcGkudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BvcGVudGVsZW1ldHJ5K2FwaUAxLjkuMC9ub2RlX21vZHVsZXMvQG9wZW50ZWxlbWV0cnkvYXBpL3NyYy9wcm9wYWdhdGlvbi9Ob29wVGV4dE1hcFByb3BhZ2F0b3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BvcGVudGVsZW1ldHJ5K2FwaUAxLjkuMC9ub2RlX21vZHVsZXMvQG9wZW50ZWxlbWV0cnkvYXBpL3NyYy9iYWdnYWdlL2NvbnRleHQtaGVscGVycy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL2FwaS9wcm9wYWdhdGlvbi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL3Byb3BhZ2F0aW9uLWFwaS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL2FwaS90cmFjZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL3RyYWNlLWFwaS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL2luZGV4LnRzIiwgIi4uL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cyIsICIuLi8uLi9wYWNrYWdlcy91dGlscy9zcmMvaW5kZXgudHMiLCAiLi4vLi4vcGFja2FnZXMvZXJyb3JzL3NyYy9pbmRleC50cyIsICIuLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy9zeW1ib2xzLnRzIiwgIi4uLy4uL3BhY2thZ2VzL2NvcmUvc3JjL3dvcmtmbG93L2dldC13b3JrZmxvdy1tZXRhZGF0YS50cyIsICIuLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy93b3JrZmxvdy9jcmVhdGUtaG9vay50cyIsICIuLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy9zbGVlcC50cyIsICIuLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy93b3JrZmxvdy93cml0YWJsZS1zdHJlYW0udHMiLCAiLi4vLi4vcGFja2FnZXMvd29ya2Zsb3cvc3JjL3N0ZGxpYi50cyIsICIuLi9leGFtcGxlL3dvcmtmbG93cy9oZWxwZXJzLnRzIiwgIi4uL2V4YW1wbGUvd29ya2Zsb3dzLzJfY29udHJvbF9mbG93LnRzIiwgIi4uL25pdHJvLXYzL3dvcmtmbG93cy8wX2RlbW8udHMiLCAiLi4vZXhhbXBsZS93b3JrZmxvd3MvOThfZHVwbGljYXRlX2Nhc2UudHMiLCAiLi4vZXhhbXBsZS93b3JrZmxvd3MvNl9iYXRjaGluZy50cyIsICIuLi9leGFtcGxlL3dvcmtmbG93cy8xX3NpbXBsZS50cyIsICIuLi9leGFtcGxlL3dvcmtmbG93cy81X2hvb2tzLnRzIiwgIi4uL2V4YW1wbGUvd29ya2Zsb3dzLzRfYWkudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXJAMi4wLjAvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXIvc3JjL2Vycm9ycy9haS1zZGstZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXJAMi4wLjAvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXIvc3JjL2Vycm9ycy9hcGktY2FsbC1lcnJvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlckAyLjAuMC9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci9zcmMvZXJyb3JzL2VtcHR5LXJlc3BvbnNlLWJvZHktZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXJAMi4wLjAvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXIvc3JjL2Vycm9ycy9nZXQtZXJyb3ItbWVzc2FnZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlckAyLjAuMC9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci9zcmMvZXJyb3JzL2ludmFsaWQtYXJndW1lbnQtZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXJAMi4wLjAvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXIvc3JjL2Vycm9ycy9pbnZhbGlkLXByb21wdC1lcnJvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlckAyLjAuMC9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci9zcmMvZXJyb3JzL2ludmFsaWQtcmVzcG9uc2UtZGF0YS1lcnJvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlckAyLjAuMC9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci9zcmMvZXJyb3JzL2pzb24tcGFyc2UtZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXJAMi4wLjAvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXIvc3JjL2Vycm9ycy9sb2FkLWFwaS1rZXktZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXJAMi4wLjAvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXIvc3JjL2Vycm9ycy9sb2FkLXNldHRpbmctZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXJAMi4wLjAvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXIvc3JjL2Vycm9ycy9uby1jb250ZW50LWdlbmVyYXRlZC1lcnJvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlckAyLjAuMC9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci9zcmMvZXJyb3JzL25vLXN1Y2gtbW9kZWwtZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXJAMi4wLjAvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXIvc3JjL2Vycm9ycy90b28tbWFueS1lbWJlZGRpbmctdmFsdWVzLWZvci1jYWxsLWVycm9yLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyQDIuMC4wL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyL3NyYy9lcnJvcnMvdHlwZS12YWxpZGF0aW9uLWVycm9yLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyQDIuMC4wL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyL3NyYy9lcnJvcnMvdW5zdXBwb3J0ZWQtZnVuY3Rpb25hbGl0eS1lcnJvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlckAyLjAuMC9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci9zcmMvanNvbi12YWx1ZS9pcy1qc29uLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9ldmVudHNvdXJjZS1wYXJzZXJAMy4wLjYvbm9kZV9tb2R1bGVzL2V2ZW50c291cmNlLXBhcnNlci9zcmMvZXJyb3JzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9ldmVudHNvdXJjZS1wYXJzZXJAMy4wLjYvbm9kZV9tb2R1bGVzL2V2ZW50c291cmNlLXBhcnNlci9zcmMvcGFyc2UudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2V2ZW50c291cmNlLXBhcnNlckAzLjAuNi9ub2RlX21vZHVsZXMvZXZlbnRzb3VyY2UtcGFyc2VyL3NyYy9zdHJlYW0udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9jbGFzc2ljL2V4dGVybmFsLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvY29yZS9pbmRleC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2NvcmUvY29yZS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2NvcmUvdXRpbC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2NvcmUvZXJyb3JzLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvY29yZS9wYXJzZS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2NvcmUvcmVnZXhlcy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2NvcmUvY2hlY2tzLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvY29yZS9kb2MuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9jb3JlL3ZlcnNpb25zLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvY29yZS9zY2hlbWFzLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy9pbmRleC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2xvY2FsZXMvYXIuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL2F6LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy9iZS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2xvY2FsZXMvY2EuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL2NzLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy9kYS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2xvY2FsZXMvZGUuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL2VuLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy9lby5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2xvY2FsZXMvZXMuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL2ZhLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy9maS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2xvY2FsZXMvZnIuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL2ZyLUNBLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy9oZS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2xvY2FsZXMvaHUuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL2lkLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy9pcy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2xvY2FsZXMvaXQuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL2phLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy9rYS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2xvY2FsZXMva20uanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL2toLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy9rby5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2xvY2FsZXMvbHQuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL21rLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy9tcy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2xvY2FsZXMvbmwuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL25vLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy9vdGEuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL3BzLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy9wbC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2xvY2FsZXMvcHQuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL3J1LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy9zbC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2xvY2FsZXMvc3YuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL3RhLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy90aC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2xvY2FsZXMvdHIuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL3VrLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy91YS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2xvY2FsZXMvdXIuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL3ZpLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy96aC1DTi5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2xvY2FsZXMvemgtVFcuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL3lvLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvY29yZS9yZWdpc3RyaWVzLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvY29yZS9hcGkuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9jb3JlL3RvLWpzb24tc2NoZW1hLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvY29yZS9qc29uLXNjaGVtYS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2NsYXNzaWMvaXNvLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvY2xhc3NpYy9lcnJvcnMuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9jbGFzc2ljL3BhcnNlLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvY2xhc3NpYy9zY2hlbWFzLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvY2xhc3NpYy9jb21wYXQuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9jbGFzc2ljL2NvZXJjZS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2NsYXNzaWMvaW5kZXguanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9pbmRleC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3YzL2hlbHBlcnMvdXRpbC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3YzL1pvZEVycm9yLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjMvbG9jYWxlcy9lbi5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3YzL2Vycm9ycy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3YzL2hlbHBlcnMvcGFyc2VVdGlsLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjMvaGVscGVycy9lcnJvclV0aWwuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92My90eXBlcy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvY29tYmluZS1oZWFkZXJzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyLXV0aWxzQDMuMC4xMl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyLXV0aWxzL3NyYy9jb252ZXJ0LWFzeW5jLWl0ZXJhdG9yLXRvLXJlYWRhYmxlLXN0cmVhbS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvZGVsYXkudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL2V4dHJhY3QtcmVzcG9uc2UtaGVhZGVycy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvZ2VuZXJhdGUtaWQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL2dldC1lcnJvci1tZXNzYWdlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyLXV0aWxzQDMuMC4xMl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyLXV0aWxzL3NyYy9nZXQtZnJvbS1hcGkudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL2hhbmRsZS1mZXRjaC1lcnJvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvaXMtYWJvcnQtZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL2dldC1ydW50aW1lLWVudmlyb25tZW50LXVzZXItYWdlbnQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3JlbW92ZS11bmRlZmluZWQtZW50cmllcy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvd2l0aC11c2VyLWFnZW50LXN1ZmZpeC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvdmVyc2lvbi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvaW5qZWN0LWpzb24taW5zdHJ1Y3Rpb24udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL2lzLXVybC1zdXBwb3J0ZWQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL2xvYWQtYXBpLWtleS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvbG9hZC1vcHRpb25hbC1zZXR0aW5nLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyLXV0aWxzQDMuMC4xMl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyLXV0aWxzL3NyYy9sb2FkLXNldHRpbmcudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL21lZGlhLXR5cGUtdG8tZXh0ZW5zaW9uLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyLXV0aWxzQDMuMC4xMl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyLXV0aWxzL3NyYy9wYXJzZS1qc29uLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyLXV0aWxzQDMuMC4xMl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyLXV0aWxzL3NyYy9zZWN1cmUtanNvbi1wYXJzZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvdmFsaWRhdGUtdHlwZXMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3ZhbGlkYXRvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvcGFyc2UtanNvbi1ldmVudC1zdHJlYW0udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3BhcnNlLXByb3ZpZGVyLW9wdGlvbnMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3Bvc3QtdG8tYXBpLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyLXV0aWxzQDMuMC4xMl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyLXV0aWxzL3NyYy90eXBlcy90b29sLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyLXV0aWxzQDMuMC4xMl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyLXV0aWxzL3NyYy9wcm92aWRlci1kZWZpbmVkLXRvb2wtZmFjdG9yeS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvcmVzb2x2ZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvcmVzcG9uc2UtaGFuZGxlci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXNjaGVtYS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXRvLWpzb24tc2NoZW1hL2dldC1yZWxhdGl2ZS1wYXRoLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyLXV0aWxzQDMuMC4xMl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyLXV0aWxzL3NyYy96b2QtdG8tanNvbi1zY2hlbWEvb3B0aW9ucy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXRvLWpzb24tc2NoZW1hL3NlbGVjdC1wYXJzZXIudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3pvZC10by1qc29uLXNjaGVtYS9wYXJzZXJzL2FueS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXRvLWpzb24tc2NoZW1hL3BhcnNlcnMvYXJyYXkudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3pvZC10by1qc29uLXNjaGVtYS9wYXJzZXJzL2JpZ2ludC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXRvLWpzb24tc2NoZW1hL3BhcnNlcnMvYm9vbGVhbi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXRvLWpzb24tc2NoZW1hL3BhcnNlcnMvYnJhbmRlZC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXRvLWpzb24tc2NoZW1hL3BhcnNlcnMvY2F0Y2gudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3pvZC10by1qc29uLXNjaGVtYS9wYXJzZXJzL2RhdGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3pvZC10by1qc29uLXNjaGVtYS9wYXJzZXJzL2RlZmF1bHQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3pvZC10by1qc29uLXNjaGVtYS9wYXJzZXJzL2VmZmVjdHMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3pvZC10by1qc29uLXNjaGVtYS9wYXJzZXJzL2VudW0udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3pvZC10by1qc29uLXNjaGVtYS9wYXJzZXJzL2ludGVyc2VjdGlvbi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXRvLWpzb24tc2NoZW1hL3BhcnNlcnMvbGl0ZXJhbC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXRvLWpzb24tc2NoZW1hL3BhcnNlcnMvcmVjb3JkLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyLXV0aWxzQDMuMC4xMl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyLXV0aWxzL3NyYy96b2QtdG8tanNvbi1zY2hlbWEvcGFyc2Vycy9zdHJpbmcudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3pvZC10by1qc29uLXNjaGVtYS9wYXJzZXJzL21hcC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXRvLWpzb24tc2NoZW1hL3BhcnNlcnMvbmF0aXZlLWVudW0udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3pvZC10by1qc29uLXNjaGVtYS9wYXJzZXJzL25ldmVyLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyLXV0aWxzQDMuMC4xMl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyLXV0aWxzL3NyYy96b2QtdG8tanNvbi1zY2hlbWEvcGFyc2Vycy9udWxsLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyLXV0aWxzQDMuMC4xMl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyLXV0aWxzL3NyYy96b2QtdG8tanNvbi1zY2hlbWEvcGFyc2Vycy91bmlvbi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXRvLWpzb24tc2NoZW1hL3BhcnNlcnMvbnVsbGFibGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3pvZC10by1qc29uLXNjaGVtYS9wYXJzZXJzL251bWJlci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXRvLWpzb24tc2NoZW1hL3BhcnNlcnMvb2JqZWN0LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyLXV0aWxzQDMuMC4xMl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyLXV0aWxzL3NyYy96b2QtdG8tanNvbi1zY2hlbWEvcGFyc2Vycy9vcHRpb25hbC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXRvLWpzb24tc2NoZW1hL3BhcnNlcnMvcGlwZWxpbmUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3pvZC10by1qc29uLXNjaGVtYS9wYXJzZXJzL3Byb21pc2UudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3pvZC10by1qc29uLXNjaGVtYS9wYXJzZXJzL3NldC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXRvLWpzb24tc2NoZW1hL3BhcnNlcnMvdHVwbGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3pvZC10by1qc29uLXNjaGVtYS9wYXJzZXJzL3VuZGVmaW5lZC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXRvLWpzb24tc2NoZW1hL3BhcnNlcnMvdW5rbm93bi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXRvLWpzb24tc2NoZW1hL3BhcnNlcnMvcmVhZG9ubHkudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3pvZC10by1qc29uLXNjaGVtYS9wYXJzZS1kZWYudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3pvZC10by1qc29uLXNjaGVtYS9yZWZzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyLXV0aWxzQDMuMC4xMl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyLXV0aWxzL3NyYy96b2QtdG8tanNvbi1zY2hlbWEvem9kLXRvLWpzb24tc2NoZW1hLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyLXV0aWxzQDMuMC4xMl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyLXV0aWxzL3NyYy96b2QtdG8tanNvbi1zY2hlbWEvaW5kZXgudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3NjaGVtYS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvdWludDgtdXRpbHMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3dpdGhvdXQtdHJhaWxpbmctc2xhc2gudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL2lzLWFzeW5jLWl0ZXJhYmxlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyLXV0aWxzQDMuMC4xMl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyLXV0aWxzL3NyYy90eXBlcy9leGVjdXRlLXRvb2wudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL2luZGV4LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK2dhdGV3YXlAMi4wLjBfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9nYXRld2F5L3NyYy9nYXRld2F5LXByb3ZpZGVyLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK2dhdGV3YXlAMi4wLjBfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9nYXRld2F5L3NyYy9lcnJvcnMvYXMtZ2F0ZXdheS1lcnJvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytnYXRld2F5QDIuMC4wX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvZ2F0ZXdheS9zcmMvZXJyb3JzL2NyZWF0ZS1nYXRld2F5LWVycm9yLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK2dhdGV3YXlAMi4wLjBfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9nYXRld2F5L3NyYy9lcnJvcnMvZ2F0ZXdheS1lcnJvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytnYXRld2F5QDIuMC4wX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvZ2F0ZXdheS9zcmMvZXJyb3JzL2dhdGV3YXktYXV0aGVudGljYXRpb24tZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrZ2F0ZXdheUAyLjAuMF96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL2dhdGV3YXkvc3JjL2Vycm9ycy9nYXRld2F5LWludmFsaWQtcmVxdWVzdC1lcnJvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytnYXRld2F5QDIuMC4wX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvZ2F0ZXdheS9zcmMvZXJyb3JzL2dhdGV3YXktcmF0ZS1saW1pdC1lcnJvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytnYXRld2F5QDIuMC4wX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvZ2F0ZXdheS9zcmMvZXJyb3JzL2dhdGV3YXktbW9kZWwtbm90LWZvdW5kLWVycm9yLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK2dhdGV3YXlAMi4wLjBfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9nYXRld2F5L3NyYy9lcnJvcnMvZ2F0ZXdheS1pbnRlcm5hbC1zZXJ2ZXItZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrZ2F0ZXdheUAyLjAuMF96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL2dhdGV3YXkvc3JjL2Vycm9ycy9nYXRld2F5LXJlc3BvbnNlLWVycm9yLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK2dhdGV3YXlAMi4wLjBfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9nYXRld2F5L3NyYy9lcnJvcnMvZXh0cmFjdC1hcGktY2FsbC1yZXNwb25zZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytnYXRld2F5QDIuMC4wX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvZ2F0ZXdheS9zcmMvZXJyb3JzL3BhcnNlLWF1dGgtbWV0aG9kLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK2dhdGV3YXlAMi4wLjBfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9nYXRld2F5L3NyYy9nYXRld2F5LWZldGNoLW1ldGFkYXRhLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK2dhdGV3YXlAMi4wLjBfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9nYXRld2F5L3NyYy9nYXRld2F5LWxhbmd1YWdlLW1vZGVsLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK2dhdGV3YXlAMi4wLjBfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9nYXRld2F5L3NyYy9nYXRld2F5LWVtYmVkZGluZy1tb2RlbC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytnYXRld2F5QDIuMC4wX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvZ2F0ZXdheS9zcmMvdmVyY2VsLWVudmlyb25tZW50LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK2dhdGV3YXlAMi4wLjBfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9nYXRld2F5L3NyYy92ZXJzaW9uLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL2luZGV4LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL2dlbmVyYXRlLXRleHQvZ2VuZXJhdGUtdGV4dC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9lcnJvci9uby1vdXRwdXQtc3BlY2lmaWVkLWVycm9yLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL2xvZ2dlci9sb2ctd2FybmluZ3MudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvbW9kZWwvcmVzb2x2ZS1tb2RlbC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9lcnJvci9pbmRleC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9lcnJvci9pbnZhbGlkLWFyZ3VtZW50LWVycm9yLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL2Vycm9yL2ludmFsaWQtc3RyZWFtLXBhcnQtZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvZXJyb3IvaW52YWxpZC10b29sLWlucHV0LWVycm9yLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL2Vycm9yL21jcC1jbGllbnQtZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvZXJyb3Ivbm8taW1hZ2UtZ2VuZXJhdGVkLWVycm9yLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL2Vycm9yL25vLW9iamVjdC1nZW5lcmF0ZWQtZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvZXJyb3Ivbm8tb3V0cHV0LWdlbmVyYXRlZC1lcnJvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9lcnJvci9uby1zcGVlY2gtZ2VuZXJhdGVkLWVycm9yLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL2Vycm9yL25vLXN1Y2gtdG9vbC1lcnJvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9lcnJvci90b29sLWNhbGwtcmVwYWlyLWVycm9yLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL2Vycm9yL3Vuc3VwcG9ydGVkLW1vZGVsLXZlcnNpb24tZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvcHJvbXB0L2ludmFsaWQtZGF0YS1jb250ZW50LWVycm9yLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3Byb21wdC9pbnZhbGlkLW1lc3NhZ2Utcm9sZS1lcnJvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9wcm9tcHQvbWVzc2FnZS1jb252ZXJzaW9uLWVycm9yLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3V0aWwvZG93bmxvYWQvZG93bmxvYWQtZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdXRpbC9yZXRyeS1lcnJvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9wcm9tcHQvY29udmVydC10by1sYW5ndWFnZS1tb2RlbC1wcm9tcHQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdXRpbC9kZXRlY3QtbWVkaWEtdHlwZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91dGlsL2Rvd25sb2FkL2Rvd25sb2FkLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3ZlcnNpb24udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdXRpbC9kb3dubG9hZC9kb3dubG9hZC1mdW5jdGlvbi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9wcm9tcHQvZGF0YS1jb250ZW50LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3Byb21wdC9zcGxpdC1kYXRhLXVybC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9wcm9tcHQvcHJlcGFyZS1jYWxsLXNldHRpbmdzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3Byb21wdC9wcmVwYXJlLXRvb2xzLWFuZC10b29sLWNob2ljZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91dGlsL2lzLW5vbi1lbXB0eS1vYmplY3QudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvcHJvbXB0L3N0YW5kYXJkaXplLXByb21wdC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9wcm9tcHQvbWVzc2FnZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy90eXBlcy9wcm92aWRlci1tZXRhZGF0YS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy90eXBlcy9qc29uLXZhbHVlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3Byb21wdC9jb250ZW50LXBhcnQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvcHJvbXB0L3dyYXAtZ2F0ZXdheS1lcnJvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy90ZWxlbWV0cnkvYXNzZW1ibGUtb3BlcmF0aW9uLW5hbWUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdGVsZW1ldHJ5L2dldC1iYXNlLXRlbGVtZXRyeS1hdHRyaWJ1dGVzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3RlbGVtZXRyeS9nZXQtdHJhY2VyLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3RlbGVtZXRyeS9ub29wLXRyYWNlci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy90ZWxlbWV0cnkvcmVjb3JkLXNwYW4udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdGVsZW1ldHJ5L3NlbGVjdC10ZWxlbWV0cnktYXR0cmlidXRlcy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy90ZWxlbWV0cnkvc3RyaW5naWZ5LWZvci10ZWxlbWV0cnkudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdHlwZXMvdXNhZ2UudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdXRpbC9hcy1hcnJheS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91dGlsL3JldHJ5LXdpdGgtZXhwb25lbnRpYWwtYmFja29mZi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91dGlsL3ByZXBhcmUtcmV0cmllcy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9nZW5lcmF0ZS10ZXh0L2V4dHJhY3QtdGV4dC1jb250ZW50LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL2dlbmVyYXRlLXRleHQvZ2VuZXJhdGVkLWZpbGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvZ2VuZXJhdGUtdGV4dC9wYXJzZS10b29sLWNhbGwudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvZ2VuZXJhdGUtdGV4dC9zdGVwLXJlc3VsdC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9nZW5lcmF0ZS10ZXh0L3N0b3AtY29uZGl0aW9uLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3Byb21wdC9jcmVhdGUtdG9vbC1tb2RlbC1vdXRwdXQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvZ2VuZXJhdGUtdGV4dC90by1yZXNwb25zZS1tZXNzYWdlcy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9nZW5lcmF0ZS10ZXh0L3N0cmVhbS10ZXh0LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3V0aWwvcHJlcGFyZS1oZWFkZXJzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3RleHQtc3RyZWFtL2NyZWF0ZS10ZXh0LXN0cmVhbS1yZXNwb25zZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91dGlsL3dyaXRlLXRvLXNlcnZlci1yZXNwb25zZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy90ZXh0LXN0cmVhbS9waXBlLXRleHQtc3RyZWFtLXRvLXJlc3BvbnNlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3VpLW1lc3NhZ2Utc3RyZWFtL2pzb24tdG8tc3NlLXRyYW5zZm9ybS1zdHJlYW0udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdWktbWVzc2FnZS1zdHJlYW0vdWktbWVzc2FnZS1zdHJlYW0taGVhZGVycy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91aS1tZXNzYWdlLXN0cmVhbS9jcmVhdGUtdWktbWVzc2FnZS1zdHJlYW0tcmVzcG9uc2UudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdWktbWVzc2FnZS1zdHJlYW0vZ2V0LXJlc3BvbnNlLXVpLW1lc3NhZ2UtaWQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdWkvcHJvY2Vzcy11aS1tZXNzYWdlLXN0cmVhbS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91aS1tZXNzYWdlLXN0cmVhbS91aS1tZXNzYWdlLWNodW5rcy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91dGlsL21lcmdlLW9iamVjdHMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdXRpbC9wYXJzZS1wYXJ0aWFsLWpzb24udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdXRpbC9maXgtanNvbi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91aS91aS1tZXNzYWdlcy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91aS1tZXNzYWdlLXN0cmVhbS9oYW5kbGUtdWktbWVzc2FnZS1zdHJlYW0tZmluaXNoLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3VpLW1lc3NhZ2Utc3RyZWFtL3BpcGUtdWktbWVzc2FnZS1zdHJlYW0tdG8tcmVzcG9uc2UudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdXRpbC9hc3luYy1pdGVyYWJsZS1zdHJlYW0udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdXRpbC9jb25zdW1lLXN0cmVhbS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91dGlsL2NyZWF0ZS1yZXNvbHZhYmxlLXByb21pc2UudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdXRpbC9jcmVhdGUtc3RpdGNoYWJsZS1zdHJlYW0udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdXRpbC9kZWxheWVkLXByb21pc2UudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdXRpbC9ub3cudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvZ2VuZXJhdGUtdGV4dC9ydW4tdG9vbHMtdHJhbnNmb3JtYXRpb24udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdWkvY29udmVydC10by1tb2RlbC1tZXNzYWdlcy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9hZ2VudC9hZ2VudC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9lbWJlZC9lbWJlZC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9lbWJlZC9lbWJlZC1tYW55LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3V0aWwvc3BsaXQtYXJyYXkudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvZ2VuZXJhdGUtaW1hZ2UvZ2VuZXJhdGUtaW1hZ2UudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvZ2VuZXJhdGUtb2JqZWN0L2dlbmVyYXRlLW9iamVjdC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9nZW5lcmF0ZS10ZXh0L2V4dHJhY3QtcmVhc29uaW5nLWNvbnRlbnQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvZ2VuZXJhdGUtb2JqZWN0L291dHB1dC1zdHJhdGVneS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9nZW5lcmF0ZS1vYmplY3QvcGFyc2UtYW5kLXZhbGlkYXRlLW9iamVjdC1yZXN1bHQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvZ2VuZXJhdGUtb2JqZWN0L3ZhbGlkYXRlLW9iamVjdC1nZW5lcmF0aW9uLWlucHV0LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL2dlbmVyYXRlLW9iamVjdC9zdHJlYW0tb2JqZWN0LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3V0aWwvY29zaW5lLXNpbWlsYXJpdHkudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdXRpbC9kYXRhLXVybC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91dGlsL2lzLWRlZXAtZXF1YWwtZGF0YS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91dGlsL3NlcmlhbC1qb2ItZXhlY3V0b3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdXRpbC9zaW11bGF0ZS1yZWFkYWJsZS1zdHJlYW0udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvZ2VuZXJhdGUtc3BlZWNoL2dlbmVyYXRlLXNwZWVjaC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9nZW5lcmF0ZS1zcGVlY2gvZ2VuZXJhdGVkLWF1ZGlvLWZpbGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvZ2VuZXJhdGUtdGV4dC9vdXRwdXQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvZ2VuZXJhdGUtdGV4dC9wcnVuZS1tZXNzYWdlcy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9nZW5lcmF0ZS10ZXh0L3Ntb290aC1zdHJlYW0udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvbWlkZGxld2FyZS9kZWZhdWx0LXNldHRpbmdzLW1pZGRsZXdhcmUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdXRpbC9nZXQtcG90ZW50aWFsLXN0YXJ0LWluZGV4LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL21pZGRsZXdhcmUvZXh0cmFjdC1yZWFzb25pbmctbWlkZGxld2FyZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9taWRkbGV3YXJlL3NpbXVsYXRlLXN0cmVhbWluZy1taWRkbGV3YXJlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL21pZGRsZXdhcmUvd3JhcC1sYW5ndWFnZS1tb2RlbC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9taWRkbGV3YXJlL3dyYXAtcHJvdmlkZXIudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvcmVnaXN0cnkvY3VzdG9tLXByb3ZpZGVyLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3JlZ2lzdHJ5L25vLXN1Y2gtcHJvdmlkZXItZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvcmVnaXN0cnkvcHJvdmlkZXItcmVnaXN0cnkudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdG9vbC9tY3AvbWNwLWNsaWVudC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy90b29sL21jcC9tY3Atc3NlLXRyYW5zcG9ydC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy90b29sL21jcC9qc29uLXJwYy1tZXNzYWdlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3Rvb2wvbWNwL3R5cGVzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3Rvb2wvbWNwL21jcC10cmFuc3BvcnQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdHJhbnNjcmliZS90cmFuc2NyaWJlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL2Vycm9yL25vLXRyYW5zY3JpcHQtZ2VuZXJhdGVkLWVycm9yLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3VpL2NhbGwtY29tcGxldGlvbi1hcGkudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdWkvcHJvY2Vzcy10ZXh0LXN0cmVhbS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91aS9jaGF0LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3VpL2NvbnZlcnQtZmlsZS1saXN0LXRvLWZpbGUtdWktcGFydHMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdWkvZGVmYXVsdC1jaGF0LXRyYW5zcG9ydC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91aS9odHRwLWNoYXQtdHJhbnNwb3J0LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3VpL2xhc3QtYXNzaXN0YW50LW1lc3NhZ2UtaXMtY29tcGxldGUtd2l0aC10b29sLWNhbGxzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3VpL3RyYW5zZm9ybS10ZXh0LXRvLXVpLW1lc3NhZ2Utc3RyZWFtLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3VpL3RleHQtc3RyZWFtLWNoYXQtdHJhbnNwb3J0LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3VpL3ZhbGlkYXRlLXVpLW1lc3NhZ2VzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3VpLW1lc3NhZ2Utc3RyZWFtL2NyZWF0ZS11aS1tZXNzYWdlLXN0cmVhbS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91aS1tZXNzYWdlLXN0cmVhbS9yZWFkLXVpLW1lc3NhZ2Utc3RyZWFtLnRzIiwgIi4uL2V4YW1wbGUvd29ya2Zsb3dzLzNfc3RyZWFtcy50cyIsICIuLi9leGFtcGxlL3dvcmtmbG93cy83X2Z1bGwudHMiLCAidmlydHVhbC1lbnRyeS5qcyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBIZWxwZXJzLlxuICovIHZhciBzID0gMTAwMDtcbnZhciBtID0gcyAqIDYwO1xudmFyIGggPSBtICogNjA7XG52YXIgZCA9IGggKiAyNDtcbnZhciB3ID0gZCAqIDc7XG52YXIgeSA9IGQgKiAzNjUuMjU7XG4vKipcbiAqIFBhcnNlIG9yIGZvcm1hdCB0aGUgZ2l2ZW4gYHZhbGAuXG4gKlxuICogT3B0aW9uczpcbiAqXG4gKiAgLSBgbG9uZ2AgdmVyYm9zZSBmb3JtYXR0aW5nIFtmYWxzZV1cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ3xOdW1iZXJ9IHZhbFxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICogQHRocm93cyB7RXJyb3J9IHRocm93IGFuIGVycm9yIGlmIHZhbCBpcyBub3QgYSBub24tZW1wdHkgc3RyaW5nIG9yIGEgbnVtYmVyXG4gKiBAcmV0dXJuIHtTdHJpbmd8TnVtYmVyfVxuICogQGFwaSBwdWJsaWNcbiAqLyBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKHZhbCwgb3B0aW9ucykge1xuICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICAgIHZhciB0eXBlID0gdHlwZW9mIHZhbDtcbiAgICBpZiAodHlwZSA9PT0gJ3N0cmluZycgJiYgdmFsLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmV0dXJuIHBhcnNlKHZhbCk7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJyAmJiBpc0Zpbml0ZSh2YWwpKSB7XG4gICAgICAgIHJldHVybiBvcHRpb25zLmxvbmcgPyBmbXRMb25nKHZhbCkgOiBmbXRTaG9ydCh2YWwpO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3ZhbCBpcyBub3QgYSBub24tZW1wdHkgc3RyaW5nIG9yIGEgdmFsaWQgbnVtYmVyLiB2YWw9JyArIEpTT04uc3RyaW5naWZ5KHZhbCkpO1xufTtcbi8qKlxuICogUGFyc2UgdGhlIGdpdmVuIGBzdHJgIGFuZCByZXR1cm4gbWlsbGlzZWNvbmRzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge051bWJlcn1cbiAqIEBhcGkgcHJpdmF0ZVxuICovIGZ1bmN0aW9uIHBhcnNlKHN0cikge1xuICAgIHN0ciA9IFN0cmluZyhzdHIpO1xuICAgIGlmIChzdHIubGVuZ3RoID4gMTAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIG1hdGNoID0gL14oLT8oPzpcXGQrKT9cXC4/XFxkKykgKihtaWxsaXNlY29uZHM/fG1zZWNzP3xtc3xzZWNvbmRzP3xzZWNzP3xzfG1pbnV0ZXM/fG1pbnM/fG18aG91cnM/fGhycz98aHxkYXlzP3xkfHdlZWtzP3x3fHllYXJzP3x5cnM/fHkpPyQvaS5leGVjKHN0cik7XG4gICAgaWYgKCFtYXRjaCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciBuID0gcGFyc2VGbG9hdChtYXRjaFsxXSk7XG4gICAgdmFyIHR5cGUgPSAobWF0Y2hbMl0gfHwgJ21zJykudG9Mb3dlckNhc2UoKTtcbiAgICBzd2l0Y2godHlwZSl7XG4gICAgICAgIGNhc2UgJ3llYXJzJzpcbiAgICAgICAgY2FzZSAneWVhcic6XG4gICAgICAgIGNhc2UgJ3lycyc6XG4gICAgICAgIGNhc2UgJ3lyJzpcbiAgICAgICAgY2FzZSAneSc6XG4gICAgICAgICAgICByZXR1cm4gbiAqIHk7XG4gICAgICAgIGNhc2UgJ3dlZWtzJzpcbiAgICAgICAgY2FzZSAnd2Vlayc6XG4gICAgICAgIGNhc2UgJ3cnOlxuICAgICAgICAgICAgcmV0dXJuIG4gKiB3O1xuICAgICAgICBjYXNlICdkYXlzJzpcbiAgICAgICAgY2FzZSAnZGF5JzpcbiAgICAgICAgY2FzZSAnZCc6XG4gICAgICAgICAgICByZXR1cm4gbiAqIGQ7XG4gICAgICAgIGNhc2UgJ2hvdXJzJzpcbiAgICAgICAgY2FzZSAnaG91cic6XG4gICAgICAgIGNhc2UgJ2hycyc6XG4gICAgICAgIGNhc2UgJ2hyJzpcbiAgICAgICAgY2FzZSAnaCc6XG4gICAgICAgICAgICByZXR1cm4gbiAqIGg7XG4gICAgICAgIGNhc2UgJ21pbnV0ZXMnOlxuICAgICAgICBjYXNlICdtaW51dGUnOlxuICAgICAgICBjYXNlICdtaW5zJzpcbiAgICAgICAgY2FzZSAnbWluJzpcbiAgICAgICAgY2FzZSAnbSc6XG4gICAgICAgICAgICByZXR1cm4gbiAqIG07XG4gICAgICAgIGNhc2UgJ3NlY29uZHMnOlxuICAgICAgICBjYXNlICdzZWNvbmQnOlxuICAgICAgICBjYXNlICdzZWNzJzpcbiAgICAgICAgY2FzZSAnc2VjJzpcbiAgICAgICAgY2FzZSAncyc6XG4gICAgICAgICAgICByZXR1cm4gbiAqIHM7XG4gICAgICAgIGNhc2UgJ21pbGxpc2Vjb25kcyc6XG4gICAgICAgIGNhc2UgJ21pbGxpc2Vjb25kJzpcbiAgICAgICAgY2FzZSAnbXNlY3MnOlxuICAgICAgICBjYXNlICdtc2VjJzpcbiAgICAgICAgY2FzZSAnbXMnOlxuICAgICAgICAgICAgcmV0dXJuIG47XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbn1cbi8qKlxuICogU2hvcnQgZm9ybWF0IGZvciBgbXNgLlxuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSBtc1xuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwcml2YXRlXG4gKi8gZnVuY3Rpb24gZm10U2hvcnQobXMpIHtcbiAgICB2YXIgbXNBYnMgPSBNYXRoLmFicyhtcyk7XG4gICAgaWYgKG1zQWJzID49IGQpIHtcbiAgICAgICAgcmV0dXJuIE1hdGgucm91bmQobXMgLyBkKSArICdkJztcbiAgICB9XG4gICAgaWYgKG1zQWJzID49IGgpIHtcbiAgICAgICAgcmV0dXJuIE1hdGgucm91bmQobXMgLyBoKSArICdoJztcbiAgICB9XG4gICAgaWYgKG1zQWJzID49IG0pIHtcbiAgICAgICAgcmV0dXJuIE1hdGgucm91bmQobXMgLyBtKSArICdtJztcbiAgICB9XG4gICAgaWYgKG1zQWJzID49IHMpIHtcbiAgICAgICAgcmV0dXJuIE1hdGgucm91bmQobXMgLyBzKSArICdzJztcbiAgICB9XG4gICAgcmV0dXJuIG1zICsgJ21zJztcbn1cbi8qKlxuICogTG9uZyBmb3JtYXQgZm9yIGBtc2AuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IG1zXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqLyBmdW5jdGlvbiBmbXRMb25nKG1zKSB7XG4gICAgdmFyIG1zQWJzID0gTWF0aC5hYnMobXMpO1xuICAgIGlmIChtc0FicyA+PSBkKSB7XG4gICAgICAgIHJldHVybiBwbHVyYWwobXMsIG1zQWJzLCBkLCAnZGF5Jyk7XG4gICAgfVxuICAgIGlmIChtc0FicyA+PSBoKSB7XG4gICAgICAgIHJldHVybiBwbHVyYWwobXMsIG1zQWJzLCBoLCAnaG91cicpO1xuICAgIH1cbiAgICBpZiAobXNBYnMgPj0gbSkge1xuICAgICAgICByZXR1cm4gcGx1cmFsKG1zLCBtc0FicywgbSwgJ21pbnV0ZScpO1xuICAgIH1cbiAgICBpZiAobXNBYnMgPj0gcykge1xuICAgICAgICByZXR1cm4gcGx1cmFsKG1zLCBtc0FicywgcywgJ3NlY29uZCcpO1xuICAgIH1cbiAgICByZXR1cm4gbXMgKyAnIG1zJztcbn1cbi8qKlxuICogUGx1cmFsaXphdGlvbiBoZWxwZXIuXG4gKi8gZnVuY3Rpb24gcGx1cmFsKG1zLCBtc0FicywgbiwgbmFtZSkge1xuICAgIHZhciBpc1BsdXJhbCA9IG1zQWJzID49IG4gKiAxLjU7XG4gICAgcmV0dXJuIE1hdGgucm91bmQobXMgLyBuKSArICcgJyArIG5hbWUgKyAoaXNQbHVyYWwgPyAncycgOiAnJyk7XG59XG4iLCAiLyoqXG4gKiBsb2Rhc2ggKEN1c3RvbSBCdWlsZCkgPGh0dHBzOi8vbG9kYXNoLmNvbS8+XG4gKiBCdWlsZDogYGxvZGFzaCBtb2R1bGFyaXplIGV4cG9ydHM9XCJucG1cIiAtbyAuL2BcbiAqIENvcHlyaWdodCBqUXVlcnkgRm91bmRhdGlvbiBhbmQgb3RoZXIgY29udHJpYnV0b3JzIDxodHRwczovL2pxdWVyeS5vcmcvPlxuICogUmVsZWFzZWQgdW5kZXIgTUlUIGxpY2Vuc2UgPGh0dHBzOi8vbG9kYXNoLmNvbS9saWNlbnNlPlxuICogQmFzZWQgb24gVW5kZXJzY29yZS5qcyAxLjguMyA8aHR0cDovL3VuZGVyc2NvcmVqcy5vcmcvTElDRU5TRT5cbiAqIENvcHlyaWdodCBKZXJlbXkgQXNoa2VuYXMsIERvY3VtZW50Q2xvdWQgYW5kIEludmVzdGlnYXRpdmUgUmVwb3J0ZXJzICYgRWRpdG9yc1xuICovIC8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqLyB2YXIgSU5GSU5JVFkgPSAxIC8gMCwgTUFYX1NBRkVfSU5URUdFUiA9IDkwMDcxOTkyNTQ3NDA5OTEsIE1BWF9JTlRFR0VSID0gMS43OTc2OTMxMzQ4NjIzMTU3ZSszMDgsIE5BTiA9IDAgLyAwO1xuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqLyB2YXIgZnVuY1RhZyA9ICdbb2JqZWN0IEZ1bmN0aW9uXScsIGdlblRhZyA9ICdbb2JqZWN0IEdlbmVyYXRvckZ1bmN0aW9uXScsIHN5bWJvbFRhZyA9ICdbb2JqZWN0IFN5bWJvbF0nO1xuLyoqIFVzZWQgdG8gbWF0Y2ggbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZS4gKi8gdmFyIHJlVHJpbSA9IC9eXFxzK3xcXHMrJC9nO1xuLyoqIFVzZWQgdG8gZGV0ZWN0IGJhZCBzaWduZWQgaGV4YWRlY2ltYWwgc3RyaW5nIHZhbHVlcy4gKi8gdmFyIHJlSXNCYWRIZXggPSAvXlstK10weFswLTlhLWZdKyQvaTtcbi8qKiBVc2VkIHRvIGRldGVjdCBiaW5hcnkgc3RyaW5nIHZhbHVlcy4gKi8gdmFyIHJlSXNCaW5hcnkgPSAvXjBiWzAxXSskL2k7XG4vKiogVXNlZCB0byBkZXRlY3Qgb2N0YWwgc3RyaW5nIHZhbHVlcy4gKi8gdmFyIHJlSXNPY3RhbCA9IC9eMG9bMC03XSskL2k7XG4vKiogVXNlZCB0byBkZXRlY3QgdW5zaWduZWQgaW50ZWdlciB2YWx1ZXMuICovIHZhciByZUlzVWludCA9IC9eKD86MHxbMS05XVxcZCopJC87XG4vKiogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgd2l0aG91dCBhIGRlcGVuZGVuY3kgb24gYHJvb3RgLiAqLyB2YXIgZnJlZVBhcnNlSW50ID0gcGFyc2VJbnQ7XG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovIHZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGVcbiAqIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovIHZhciBvYmplY3RUb1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqLyB2YXIgbmF0aXZlQ2VpbCA9IE1hdGguY2VpbCwgbmF0aXZlTWF4ID0gTWF0aC5tYXg7XG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnNsaWNlYCB3aXRob3V0IGFuIGl0ZXJhdGVlIGNhbGwgZ3VhcmQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzbGljZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9MF0gVGhlIHN0YXJ0IHBvc2l0aW9uLlxuICogQHBhcmFtIHtudW1iZXJ9IFtlbmQ9YXJyYXkubGVuZ3RoXSBUaGUgZW5kIHBvc2l0aW9uLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBzbGljZSBvZiBgYXJyYXlgLlxuICovIGZ1bmN0aW9uIGJhc2VTbGljZShhcnJheSwgc3RhcnQsIGVuZCkge1xuICAgIHZhciBpbmRleCA9IC0xLCBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG4gICAgaWYgKHN0YXJ0IDwgMCkge1xuICAgICAgICBzdGFydCA9IC1zdGFydCA+IGxlbmd0aCA/IDAgOiBsZW5ndGggKyBzdGFydDtcbiAgICB9XG4gICAgZW5kID0gZW5kID4gbGVuZ3RoID8gbGVuZ3RoIDogZW5kO1xuICAgIGlmIChlbmQgPCAwKSB7XG4gICAgICAgIGVuZCArPSBsZW5ndGg7XG4gICAgfVxuICAgIGxlbmd0aCA9IHN0YXJ0ID4gZW5kID8gMCA6IGVuZCAtIHN0YXJ0ID4+PiAwO1xuICAgIHN0YXJ0ID4+Pj0gMDtcbiAgICB2YXIgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKTtcbiAgICB3aGlsZSgrK2luZGV4IDwgbGVuZ3RoKXtcbiAgICAgICAgcmVzdWx0W2luZGV4XSA9IGFycmF5W2luZGV4ICsgc3RhcnRdO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGFycmF5LWxpa2UgaW5kZXguXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGg9TUFYX1NBRkVfSU5URUdFUl0gVGhlIHVwcGVyIGJvdW5kcyBvZiBhIHZhbGlkIGluZGV4LlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBpbmRleCwgZWxzZSBgZmFsc2VgLlxuICovIGZ1bmN0aW9uIGlzSW5kZXgodmFsdWUsIGxlbmd0aCkge1xuICAgIGxlbmd0aCA9IGxlbmd0aCA9PSBudWxsID8gTUFYX1NBRkVfSU5URUdFUiA6IGxlbmd0aDtcbiAgICByZXR1cm4gISFsZW5ndGggJiYgKHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyB8fCByZUlzVWludC50ZXN0KHZhbHVlKSkgJiYgdmFsdWUgPiAtMSAmJiB2YWx1ZSAlIDEgPT0gMCAmJiB2YWx1ZSA8IGxlbmd0aDtcbn1cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBhcmd1bWVudHMgYXJlIGZyb20gYW4gaXRlcmF0ZWUgY2FsbC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgcG90ZW50aWFsIGl0ZXJhdGVlIHZhbHVlIGFyZ3VtZW50LlxuICogQHBhcmFtIHsqfSBpbmRleCBUaGUgcG90ZW50aWFsIGl0ZXJhdGVlIGluZGV4IG9yIGtleSBhcmd1bWVudC5cbiAqIEBwYXJhbSB7Kn0gb2JqZWN0IFRoZSBwb3RlbnRpYWwgaXRlcmF0ZWUgb2JqZWN0IGFyZ3VtZW50LlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBhcmd1bWVudHMgYXJlIGZyb20gYW4gaXRlcmF0ZWUgY2FsbCxcbiAqICBlbHNlIGBmYWxzZWAuXG4gKi8gZnVuY3Rpb24gaXNJdGVyYXRlZUNhbGwodmFsdWUsIGluZGV4LCBvYmplY3QpIHtcbiAgICBpZiAoIWlzT2JqZWN0KG9iamVjdCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB2YXIgdHlwZSA9IHR5cGVvZiBpbmRleDtcbiAgICBpZiAodHlwZSA9PSAnbnVtYmVyJyA/IGlzQXJyYXlMaWtlKG9iamVjdCkgJiYgaXNJbmRleChpbmRleCwgb2JqZWN0Lmxlbmd0aCkgOiB0eXBlID09ICdzdHJpbmcnICYmIGluZGV4IGluIG9iamVjdCkge1xuICAgICAgICByZXR1cm4gZXEob2JqZWN0W2luZGV4XSwgdmFsdWUpO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgZWxlbWVudHMgc3BsaXQgaW50byBncm91cHMgdGhlIGxlbmd0aCBvZiBgc2l6ZWAuXG4gKiBJZiBgYXJyYXlgIGNhbid0IGJlIHNwbGl0IGV2ZW5seSwgdGhlIGZpbmFsIGNodW5rIHdpbGwgYmUgdGhlIHJlbWFpbmluZ1xuICogZWxlbWVudHMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAzLjAuMFxuICogQGNhdGVnb3J5IEFycmF5XG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcHJvY2Vzcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbc2l6ZT0xXSBUaGUgbGVuZ3RoIG9mIGVhY2ggY2h1bmtcbiAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBjaHVua3MuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uY2h1bmsoWydhJywgJ2InLCAnYycsICdkJ10sIDIpO1xuICogLy8gPT4gW1snYScsICdiJ10sIFsnYycsICdkJ11dXG4gKlxuICogXy5jaHVuayhbJ2EnLCAnYicsICdjJywgJ2QnXSwgMyk7XG4gKiAvLyA9PiBbWydhJywgJ2InLCAnYyddLCBbJ2QnXV1cbiAqLyBmdW5jdGlvbiBjaHVuayhhcnJheSwgc2l6ZSwgZ3VhcmQpIHtcbiAgICBpZiAoZ3VhcmQgPyBpc0l0ZXJhdGVlQ2FsbChhcnJheSwgc2l6ZSwgZ3VhcmQpIDogc2l6ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHNpemUgPSAxO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHNpemUgPSBuYXRpdmVNYXgodG9JbnRlZ2VyKHNpemUpLCAwKTtcbiAgICB9XG4gICAgdmFyIGxlbmd0aCA9IGFycmF5ID8gYXJyYXkubGVuZ3RoIDogMDtcbiAgICBpZiAoIWxlbmd0aCB8fCBzaXplIDwgMSkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIHZhciBpbmRleCA9IDAsIHJlc0luZGV4ID0gMCwgcmVzdWx0ID0gQXJyYXkobmF0aXZlQ2VpbChsZW5ndGggLyBzaXplKSk7XG4gICAgd2hpbGUoaW5kZXggPCBsZW5ndGgpe1xuICAgICAgICByZXN1bHRbcmVzSW5kZXgrK10gPSBiYXNlU2xpY2UoYXJyYXksIGluZGV4LCBpbmRleCArPSBzaXplKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbi8qKlxuICogUGVyZm9ybXMgYVxuICogW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAqIGNvbXBhcmlzb24gYmV0d2VlbiB0d28gdmFsdWVzIHRvIGRldGVybWluZSBpZiB0aGV5IGFyZSBlcXVpdmFsZW50LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4wLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgdmFsdWVzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBvYmplY3QgPSB7ICdhJzogMSB9O1xuICogdmFyIG90aGVyID0geyAnYSc6IDEgfTtcbiAqXG4gKiBfLmVxKG9iamVjdCwgb2JqZWN0KTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmVxKG9iamVjdCwgb3RoZXIpO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmVxKCdhJywgJ2EnKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmVxKCdhJywgT2JqZWN0KCdhJykpO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmVxKE5hTiwgTmFOKTtcbiAqIC8vID0+IHRydWVcbiAqLyBmdW5jdGlvbiBlcSh2YWx1ZSwgb3RoZXIpIHtcbiAgICByZXR1cm4gdmFsdWUgPT09IG90aGVyIHx8IHZhbHVlICE9PSB2YWx1ZSAmJiBvdGhlciAhPT0gb3RoZXI7XG59XG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGFycmF5LWxpa2UuIEEgdmFsdWUgaXMgY29uc2lkZXJlZCBhcnJheS1saWtlIGlmIGl0J3NcbiAqIG5vdCBhIGZ1bmN0aW9uIGFuZCBoYXMgYSBgdmFsdWUubGVuZ3RoYCB0aGF0J3MgYW4gaW50ZWdlciBncmVhdGVyIHRoYW4gb3JcbiAqIGVxdWFsIHRvIGAwYCBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIGBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUmAuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYXJyYXktbGlrZSwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzQXJyYXlMaWtlKFsxLCAyLCAzXSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0FycmF5TGlrZShkb2N1bWVudC5ib2R5LmNoaWxkcmVuKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzQXJyYXlMaWtlKCdhYmMnKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzQXJyYXlMaWtlKF8ubm9vcCk7XG4gKiAvLyA9PiBmYWxzZVxuICovIGZ1bmN0aW9uIGlzQXJyYXlMaWtlKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlICE9IG51bGwgJiYgaXNMZW5ndGgodmFsdWUubGVuZ3RoKSAmJiAhaXNGdW5jdGlvbih2YWx1ZSk7XG59XG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgRnVuY3Rpb25gIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMS4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIGZ1bmN0aW9uLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNGdW5jdGlvbihfKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzRnVuY3Rpb24oL2FiYy8pO1xuICogLy8gPT4gZmFsc2VcbiAqLyBmdW5jdGlvbiBpc0Z1bmN0aW9uKHZhbHVlKSB7XG4gICAgLy8gVGhlIHVzZSBvZiBgT2JqZWN0I3RvU3RyaW5nYCBhdm9pZHMgaXNzdWVzIHdpdGggdGhlIGB0eXBlb2ZgIG9wZXJhdG9yXG4gICAgLy8gaW4gU2FmYXJpIDgtOSB3aGljaCByZXR1cm5zICdvYmplY3QnIGZvciB0eXBlZCBhcnJheSBhbmQgb3RoZXIgY29uc3RydWN0b3JzLlxuICAgIHZhciB0YWcgPSBpc09iamVjdCh2YWx1ZSkgPyBvYmplY3RUb1N0cmluZy5jYWxsKHZhbHVlKSA6ICcnO1xuICAgIHJldHVybiB0YWcgPT0gZnVuY1RhZyB8fCB0YWcgPT0gZ2VuVGFnO1xufVxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGFycmF5LWxpa2UgbGVuZ3RoLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBsb29zZWx5IGJhc2VkIG9uXG4gKiBbYFRvTGVuZ3RoYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtdG9sZW5ndGgpLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4wLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgbGVuZ3RoLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNMZW5ndGgoMyk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0xlbmd0aChOdW1iZXIuTUlOX1ZBTFVFKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc0xlbmd0aChJbmZpbml0eSk7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uaXNMZW5ndGgoJzMnKTtcbiAqIC8vID0+IGZhbHNlXG4gKi8gZnVuY3Rpb24gaXNMZW5ndGgodmFsdWUpIHtcbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09ICdudW1iZXInICYmIHZhbHVlID4gLTEgJiYgdmFsdWUgJSAxID09IDAgJiYgdmFsdWUgPD0gTUFYX1NBRkVfSU5URUdFUjtcbn1cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgdGhlXG4gKiBbbGFuZ3VhZ2UgdHlwZV0oaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLWVjbWFzY3JpcHQtbGFuZ3VhZ2UtdHlwZXMpXG4gKiBvZiBgT2JqZWN0YC4gKGUuZy4gYXJyYXlzLCBmdW5jdGlvbnMsIG9iamVjdHMsIHJlZ2V4ZXMsIGBuZXcgTnVtYmVyKDApYCwgYW5kIGBuZXcgU3RyaW5nKCcnKWApXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAwLjEuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNPYmplY3Qoe30pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3QoWzEsIDIsIDNdKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0KF8ubm9vcCk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdChudWxsKTtcbiAqIC8vID0+IGZhbHNlXG4gKi8gZnVuY3Rpb24gaXNPYmplY3QodmFsdWUpIHtcbiAgICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgICByZXR1cm4gISF2YWx1ZSAmJiAodHlwZSA9PSAnb2JqZWN0JyB8fCB0eXBlID09ICdmdW5jdGlvbicpO1xufVxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBvYmplY3QtbGlrZS4gQSB2YWx1ZSBpcyBvYmplY3QtbGlrZSBpZiBpdCdzIG5vdCBgbnVsbGBcbiAqIGFuZCBoYXMgYSBgdHlwZW9mYCByZXN1bHQgb2YgXCJvYmplY3RcIi5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMC4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBvYmplY3QtbGlrZSwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzT2JqZWN0TGlrZSh7fSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdExpa2UoWzEsIDIsIDNdKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0TGlrZShfLm5vb3ApO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzT2JqZWN0TGlrZShudWxsKTtcbiAqIC8vID0+IGZhbHNlXG4gKi8gZnVuY3Rpb24gaXNPYmplY3RMaWtlKHZhbHVlKSB7XG4gICAgcmV0dXJuICEhdmFsdWUgJiYgdHlwZW9mIHZhbHVlID09ICdvYmplY3QnO1xufVxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYFN5bWJvbGAgcHJpbWl0aXZlIG9yIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMC4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHN5bWJvbCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzU3ltYm9sKFN5bWJvbC5pdGVyYXRvcik7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc1N5bWJvbCgnYWJjJyk7XG4gKiAvLyA9PiBmYWxzZVxuICovIGZ1bmN0aW9uIGlzU3ltYm9sKHZhbHVlKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnc3ltYm9sJyB8fCBpc09iamVjdExpa2UodmFsdWUpICYmIG9iamVjdFRvU3RyaW5nLmNhbGwodmFsdWUpID09IHN5bWJvbFRhZztcbn1cbi8qKlxuICogQ29udmVydHMgYHZhbHVlYCB0byBhIGZpbml0ZSBudW1iZXIuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjEyLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb252ZXJ0LlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgY29udmVydGVkIG51bWJlci5cbiAqIEBleGFtcGxlXG4gKlxuICogXy50b0Zpbml0ZSgzLjIpO1xuICogLy8gPT4gMy4yXG4gKlxuICogXy50b0Zpbml0ZShOdW1iZXIuTUlOX1ZBTFVFKTtcbiAqIC8vID0+IDVlLTMyNFxuICpcbiAqIF8udG9GaW5pdGUoSW5maW5pdHkpO1xuICogLy8gPT4gMS43OTc2OTMxMzQ4NjIzMTU3ZSszMDhcbiAqXG4gKiBfLnRvRmluaXRlKCczLjInKTtcbiAqIC8vID0+IDMuMlxuICovIGZ1bmN0aW9uIHRvRmluaXRlKHZhbHVlKSB7XG4gICAgaWYgKCF2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdmFsdWUgPT09IDAgPyB2YWx1ZSA6IDA7XG4gICAgfVxuICAgIHZhbHVlID0gdG9OdW1iZXIodmFsdWUpO1xuICAgIGlmICh2YWx1ZSA9PT0gSU5GSU5JVFkgfHwgdmFsdWUgPT09IC1JTkZJTklUWSkge1xuICAgICAgICB2YXIgc2lnbiA9IHZhbHVlIDwgMCA/IC0xIDogMTtcbiAgICAgICAgcmV0dXJuIHNpZ24gKiBNQVhfSU5URUdFUjtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlID09PSB2YWx1ZSA/IHZhbHVlIDogMDtcbn1cbi8qKlxuICogQ29udmVydHMgYHZhbHVlYCB0byBhbiBpbnRlZ2VyLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBsb29zZWx5IGJhc2VkIG9uXG4gKiBbYFRvSW50ZWdlcmBdKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy10b2ludGVnZXIpLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4wLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb252ZXJ0LlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgY29udmVydGVkIGludGVnZXIuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8udG9JbnRlZ2VyKDMuMik7XG4gKiAvLyA9PiAzXG4gKlxuICogXy50b0ludGVnZXIoTnVtYmVyLk1JTl9WQUxVRSk7XG4gKiAvLyA9PiAwXG4gKlxuICogXy50b0ludGVnZXIoSW5maW5pdHkpO1xuICogLy8gPT4gMS43OTc2OTMxMzQ4NjIzMTU3ZSszMDhcbiAqXG4gKiBfLnRvSW50ZWdlcignMy4yJyk7XG4gKiAvLyA9PiAzXG4gKi8gZnVuY3Rpb24gdG9JbnRlZ2VyKHZhbHVlKSB7XG4gICAgdmFyIHJlc3VsdCA9IHRvRmluaXRlKHZhbHVlKSwgcmVtYWluZGVyID0gcmVzdWx0ICUgMTtcbiAgICByZXR1cm4gcmVzdWx0ID09PSByZXN1bHQgPyByZW1haW5kZXIgPyByZXN1bHQgLSByZW1haW5kZXIgOiByZXN1bHQgOiAwO1xufVxuLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgbnVtYmVyLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4wLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwcm9jZXNzLlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgbnVtYmVyLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLnRvTnVtYmVyKDMuMik7XG4gKiAvLyA9PiAzLjJcbiAqXG4gKiBfLnRvTnVtYmVyKE51bWJlci5NSU5fVkFMVUUpO1xuICogLy8gPT4gNWUtMzI0XG4gKlxuICogXy50b051bWJlcihJbmZpbml0eSk7XG4gKiAvLyA9PiBJbmZpbml0eVxuICpcbiAqIF8udG9OdW1iZXIoJzMuMicpO1xuICogLy8gPT4gMy4yXG4gKi8gZnVuY3Rpb24gdG9OdW1iZXIodmFsdWUpIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09ICdudW1iZXInKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gICAgaWYgKGlzU3ltYm9sKHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gTkFOO1xuICAgIH1cbiAgICBpZiAoaXNPYmplY3QodmFsdWUpKSB7XG4gICAgICAgIHZhciBvdGhlciA9IHR5cGVvZiB2YWx1ZS52YWx1ZU9mID09ICdmdW5jdGlvbicgPyB2YWx1ZS52YWx1ZU9mKCkgOiB2YWx1ZTtcbiAgICAgICAgdmFsdWUgPSBpc09iamVjdChvdGhlcikgPyBvdGhlciArICcnIDogb3RoZXI7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdmFsdWUgIT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlID09PSAwID8gdmFsdWUgOiArdmFsdWU7XG4gICAgfVxuICAgIHZhbHVlID0gdmFsdWUucmVwbGFjZShyZVRyaW0sICcnKTtcbiAgICB2YXIgaXNCaW5hcnkgPSByZUlzQmluYXJ5LnRlc3QodmFsdWUpO1xuICAgIHJldHVybiBpc0JpbmFyeSB8fCByZUlzT2N0YWwudGVzdCh2YWx1ZSkgPyBmcmVlUGFyc2VJbnQodmFsdWUuc2xpY2UoMiksIGlzQmluYXJ5ID8gMiA6IDgpIDogcmVJc0JhZEhleC50ZXN0KHZhbHVlKSA/IE5BTiA6ICt2YWx1ZTtcbn1cbm1vZHVsZS5leHBvcnRzID0gY2h1bms7XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgX19kZWZQcm9wID0gT2JqZWN0LmRlZmluZVByb3BlcnR5O1xudmFyIF9fZ2V0T3duUHJvcERlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yO1xudmFyIF9fZ2V0T3duUHJvcE5hbWVzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXM7XG52YXIgX19oYXNPd25Qcm9wID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbnZhciBfX2V4cG9ydCA9ICh0YXJnZXQsIGFsbCk9PntcbiAgICBmb3IodmFyIG5hbWUgaW4gYWxsKV9fZGVmUHJvcCh0YXJnZXQsIG5hbWUsIHtcbiAgICAgICAgZ2V0OiBhbGxbbmFtZV0sXG4gICAgICAgIGVudW1lcmFibGU6IHRydWVcbiAgICB9KTtcbn07XG52YXIgX19jb3B5UHJvcHMgPSAodG8sIGZyb20sIGV4Y2VwdCwgZGVzYyk9PntcbiAgICBpZiAoZnJvbSAmJiB0eXBlb2YgZnJvbSA9PT0gXCJvYmplY3RcIiB8fCB0eXBlb2YgZnJvbSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGZvciAobGV0IGtleSBvZiBfX2dldE93blByb3BOYW1lcyhmcm9tKSlpZiAoIV9faGFzT3duUHJvcC5jYWxsKHRvLCBrZXkpICYmIGtleSAhPT0gZXhjZXB0KSBfX2RlZlByb3AodG8sIGtleSwge1xuICAgICAgICAgICAgZ2V0OiAoKT0+ZnJvbVtrZXldLFxuICAgICAgICAgICAgZW51bWVyYWJsZTogIShkZXNjID0gX19nZXRPd25Qcm9wRGVzYyhmcm9tLCBrZXkpKSB8fCBkZXNjLmVudW1lcmFibGVcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiB0bztcbn07XG52YXIgX190b0NvbW1vbkpTID0gKG1vZCk9Pl9fY29weVByb3BzKF9fZGVmUHJvcCh7fSwgXCJfX2VzTW9kdWxlXCIsIHtcbiAgICAgICAgdmFsdWU6IHRydWVcbiAgICB9KSwgbW9kKTtcbnZhciBnZXRfY29udGV4dF9leHBvcnRzID0ge307XG5fX2V4cG9ydChnZXRfY29udGV4dF9leHBvcnRzLCB7XG4gICAgU1lNQk9MX0ZPUl9SRVFfQ09OVEVYVDogKCk9PlNZTUJPTF9GT1JfUkVRX0NPTlRFWFQsXG4gICAgZ2V0Q29udGV4dDogKCk9PmdldENvbnRleHRcbn0pO1xubW9kdWxlLmV4cG9ydHMgPSBfX3RvQ29tbW9uSlMoZ2V0X2NvbnRleHRfZXhwb3J0cyk7XG5jb25zdCBTWU1CT0xfRk9SX1JFUV9DT05URVhUID0gU3ltYm9sLmZvcihcIkB2ZXJjZWwvcmVxdWVzdC1jb250ZXh0XCIpO1xuZnVuY3Rpb24gZ2V0Q29udGV4dCgpIHtcbiAgICBjb25zdCBmcm9tU3ltYm9sID0gZ2xvYmFsVGhpcztcbiAgICByZXR1cm4gZnJvbVN5bWJvbFtTWU1CT0xfRk9SX1JFUV9DT05URVhUXT8uZ2V0Py4oKSA/PyB7fTtcbn1cbi8vIEFubm90YXRlIHRoZSBDb21tb25KUyBleHBvcnQgbmFtZXMgZm9yIEVTTSBpbXBvcnQgaW4gbm9kZTpcbjAgJiYgKG1vZHVsZS5leHBvcnRzID0ge1xuICAgIFNZTUJPTF9GT1JfUkVRX0NPTlRFWFQsXG4gICAgZ2V0Q29udGV4dFxufSk7XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgX19kZWZQcm9wID0gT2JqZWN0LmRlZmluZVByb3BlcnR5O1xudmFyIF9fZ2V0T3duUHJvcERlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yO1xudmFyIF9fZ2V0T3duUHJvcE5hbWVzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXM7XG52YXIgX19oYXNPd25Qcm9wID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbnZhciBfX2V4cG9ydCA9ICh0YXJnZXQsIGFsbCk9PntcbiAgICBmb3IodmFyIG5hbWUgaW4gYWxsKV9fZGVmUHJvcCh0YXJnZXQsIG5hbWUsIHtcbiAgICAgICAgZ2V0OiBhbGxbbmFtZV0sXG4gICAgICAgIGVudW1lcmFibGU6IHRydWVcbiAgICB9KTtcbn07XG52YXIgX19jb3B5UHJvcHMgPSAodG8sIGZyb20sIGV4Y2VwdCwgZGVzYyk9PntcbiAgICBpZiAoZnJvbSAmJiB0eXBlb2YgZnJvbSA9PT0gXCJvYmplY3RcIiB8fCB0eXBlb2YgZnJvbSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGZvciAobGV0IGtleSBvZiBfX2dldE93blByb3BOYW1lcyhmcm9tKSlpZiAoIV9faGFzT3duUHJvcC5jYWxsKHRvLCBrZXkpICYmIGtleSAhPT0gZXhjZXB0KSBfX2RlZlByb3AodG8sIGtleSwge1xuICAgICAgICAgICAgZ2V0OiAoKT0+ZnJvbVtrZXldLFxuICAgICAgICAgICAgZW51bWVyYWJsZTogIShkZXNjID0gX19nZXRPd25Qcm9wRGVzYyhmcm9tLCBrZXkpKSB8fCBkZXNjLmVudW1lcmFibGVcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiB0bztcbn07XG52YXIgX190b0NvbW1vbkpTID0gKG1vZCk9Pl9fY29weVByb3BzKF9fZGVmUHJvcCh7fSwgXCJfX2VzTW9kdWxlXCIsIHtcbiAgICAgICAgdmFsdWU6IHRydWVcbiAgICB9KSwgbW9kKTtcbnZhciBpbmRleF9icm93c2VyX2V4cG9ydHMgPSB7fTtcbl9fZXhwb3J0KGluZGV4X2Jyb3dzZXJfZXhwb3J0cywge1xuICAgIGdldENvbnRleHQ6ICgpPT5pbXBvcnRfZ2V0X2NvbnRleHQuZ2V0Q29udGV4dCxcbiAgICBnZXRWZXJjZWxPaWRjVG9rZW46ICgpPT5nZXRWZXJjZWxPaWRjVG9rZW4sXG4gICAgZ2V0VmVyY2VsT2lkY1Rva2VuU3luYzogKCk9PmdldFZlcmNlbE9pZGNUb2tlblN5bmNcbn0pO1xubW9kdWxlLmV4cG9ydHMgPSBfX3RvQ29tbW9uSlMoaW5kZXhfYnJvd3Nlcl9leHBvcnRzKTtcbnZhciBpbXBvcnRfZ2V0X2NvbnRleHQgPSByZXF1aXJlKFwiLi9nZXQtY29udGV4dFwiKTtcbmFzeW5jIGZ1bmN0aW9uIGdldFZlcmNlbE9pZGNUb2tlbigpIHtcbiAgICByZXR1cm4gXCJcIjtcbn1cbmZ1bmN0aW9uIGdldFZlcmNlbE9pZGNUb2tlblN5bmMoKSB7XG4gICAgcmV0dXJuIFwiXCI7XG59XG4vLyBBbm5vdGF0ZSB0aGUgQ29tbW9uSlMgZXhwb3J0IG5hbWVzIGZvciBFU00gaW1wb3J0IGluIG5vZGU6XG4wICYmIChtb2R1bGUuZXhwb3J0cyA9IHtcbiAgICBnZXRDb250ZXh0LFxuICAgIGdldFZlcmNlbE9pZGNUb2tlbixcbiAgICBnZXRWZXJjZWxPaWRjVG9rZW5TeW5jXG59KTtcbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG4vKiogb25seSBnbG9iYWxzIHRoYXQgY29tbW9uIHRvIG5vZGUgYW5kIGJyb3dzZXJzIGFyZSBhbGxvd2VkICovXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm9kZS9uby11bnN1cHBvcnRlZC1mZWF0dXJlcy9lcy1idWlsdGluc1xuZXhwb3J0IGNvbnN0IF9nbG9iYWxUaGlzID0gdHlwZW9mIGdsb2JhbFRoaXMgPT09ICdvYmplY3QnID8gZ2xvYmFsVGhpcyA6IGdsb2JhbDtcbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5leHBvcnQgKiBmcm9tICcuL2dsb2JhbFRoaXMnO1xuIiwgIi8qXG4gKiBDb3B5cmlnaHQgVGhlIE9wZW5UZWxlbWV0cnkgQXV0aG9yc1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgIGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vbm9kZSc7XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuLy8gdGhpcyBpcyBhdXRvZ2VuZXJhdGVkIGZpbGUsIHNlZSBzY3JpcHRzL3ZlcnNpb24tdXBkYXRlLmpzXG5leHBvcnQgY29uc3QgVkVSU0lPTiA9ICcxLjkuMCc7XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuaW1wb3J0IHsgVkVSU0lPTiB9IGZyb20gJy4uL3ZlcnNpb24nO1xuXG5jb25zdCByZSA9IC9eKFxcZCspXFwuKFxcZCspXFwuKFxcZCspKC0oLispKT8kLztcblxuLyoqXG4gKiBDcmVhdGUgYSBmdW5jdGlvbiB0byB0ZXN0IGFuIEFQSSB2ZXJzaW9uIHRvIHNlZSBpZiBpdCBpcyBjb21wYXRpYmxlIHdpdGggdGhlIHByb3ZpZGVkIG93blZlcnNpb24uXG4gKlxuICogVGhlIHJldHVybmVkIGZ1bmN0aW9uIGhhcyB0aGUgZm9sbG93aW5nIHNlbWFudGljczpcbiAqIC0gRXhhY3QgbWF0Y2ggaXMgYWx3YXlzIGNvbXBhdGlibGVcbiAqIC0gTWFqb3IgdmVyc2lvbnMgbXVzdCBtYXRjaCBleGFjdGx5XG4gKiAgICAtIDEueCBwYWNrYWdlIGNhbm5vdCB1c2UgZ2xvYmFsIDIueCBwYWNrYWdlXG4gKiAgICAtIDIueCBwYWNrYWdlIGNhbm5vdCB1c2UgZ2xvYmFsIDEueCBwYWNrYWdlXG4gKiAtIFRoZSBtaW5vciB2ZXJzaW9uIG9mIHRoZSBBUEkgbW9kdWxlIHJlcXVlc3RpbmcgYWNjZXNzIHRvIHRoZSBnbG9iYWwgQVBJIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHRoZSBtaW5vciB2ZXJzaW9uIG9mIHRoaXMgQVBJXG4gKiAgICAtIDEuMyBwYWNrYWdlIG1heSB1c2UgMS40IGdsb2JhbCBiZWNhdXNlIHRoZSBsYXRlciBnbG9iYWwgY29udGFpbnMgYWxsIGZ1bmN0aW9ucyAxLjMgZXhwZWN0c1xuICogICAgLSAxLjQgcGFja2FnZSBtYXkgTk9UIHVzZSAxLjMgZ2xvYmFsIGJlY2F1c2UgaXQgbWF5IHRyeSB0byBjYWxsIGZ1bmN0aW9ucyB3aGljaCBkb24ndCBleGlzdCBvbiAxLjNcbiAqIC0gSWYgdGhlIG1ham9yIHZlcnNpb24gaXMgMCwgdGhlIG1pbm9yIHZlcnNpb24gaXMgdHJlYXRlZCBhcyB0aGUgbWFqb3IgYW5kIHRoZSBwYXRjaCBpcyB0cmVhdGVkIGFzIHRoZSBtaW5vclxuICogLSBQYXRjaCBhbmQgYnVpbGQgdGFnIGRpZmZlcmVuY2VzIGFyZSBub3QgY29uc2lkZXJlZCBhdCB0aGlzIHRpbWVcbiAqXG4gKiBAcGFyYW0gb3duVmVyc2lvbiB2ZXJzaW9uIHdoaWNoIHNob3VsZCBiZSBjaGVja2VkIGFnYWluc3RcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9tYWtlQ29tcGF0aWJpbGl0eUNoZWNrKFxuICBvd25WZXJzaW9uOiBzdHJpbmdcbik6IChnbG9iYWxWZXJzaW9uOiBzdHJpbmcpID0+IGJvb2xlYW4ge1xuICBjb25zdCBhY2NlcHRlZFZlcnNpb25zID0gbmV3IFNldDxzdHJpbmc+KFtvd25WZXJzaW9uXSk7XG4gIGNvbnN0IHJlamVjdGVkVmVyc2lvbnMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuICBjb25zdCBteVZlcnNpb25NYXRjaCA9IG93blZlcnNpb24ubWF0Y2gocmUpO1xuICBpZiAoIW15VmVyc2lvbk1hdGNoKSB7XG4gICAgLy8gd2UgY2Fubm90IGd1YXJhbnRlZSBjb21wYXRpYmlsaXR5IHNvIHdlIGFsd2F5cyByZXR1cm4gbm9vcFxuICAgIHJldHVybiAoKSA9PiBmYWxzZTtcbiAgfVxuXG4gIGNvbnN0IG93blZlcnNpb25QYXJzZWQgPSB7XG4gICAgbWFqb3I6ICtteVZlcnNpb25NYXRjaFsxXSxcbiAgICBtaW5vcjogK215VmVyc2lvbk1hdGNoWzJdLFxuICAgIHBhdGNoOiArbXlWZXJzaW9uTWF0Y2hbM10sXG4gICAgcHJlcmVsZWFzZTogbXlWZXJzaW9uTWF0Y2hbNF0sXG4gIH07XG5cbiAgLy8gaWYgb3duVmVyc2lvbiBoYXMgYSBwcmVyZWxlYXNlIHRhZywgdmVyc2lvbnMgbXVzdCBtYXRjaCBleGFjdGx5XG4gIGlmIChvd25WZXJzaW9uUGFyc2VkLnByZXJlbGVhc2UgIT0gbnVsbCkge1xuICAgIHJldHVybiBmdW5jdGlvbiBpc0V4YWN0bWF0Y2goZ2xvYmFsVmVyc2lvbjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICByZXR1cm4gZ2xvYmFsVmVyc2lvbiA9PT0gb3duVmVyc2lvbjtcbiAgICB9O1xuICB9XG5cbiAgZnVuY3Rpb24gX3JlamVjdCh2OiBzdHJpbmcpIHtcbiAgICByZWplY3RlZFZlcnNpb25zLmFkZCh2KTtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBmdW5jdGlvbiBfYWNjZXB0KHY6IHN0cmluZykge1xuICAgIGFjY2VwdGVkVmVyc2lvbnMuYWRkKHYpO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIGlzQ29tcGF0aWJsZShnbG9iYWxWZXJzaW9uOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBpZiAoYWNjZXB0ZWRWZXJzaW9ucy5oYXMoZ2xvYmFsVmVyc2lvbikpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGlmIChyZWplY3RlZFZlcnNpb25zLmhhcyhnbG9iYWxWZXJzaW9uKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IGdsb2JhbFZlcnNpb25NYXRjaCA9IGdsb2JhbFZlcnNpb24ubWF0Y2gocmUpO1xuICAgIGlmICghZ2xvYmFsVmVyc2lvbk1hdGNoKSB7XG4gICAgICAvLyBjYW5ub3QgcGFyc2Ugb3RoZXIgdmVyc2lvblxuICAgICAgLy8gd2UgY2Fubm90IGd1YXJhbnRlZSBjb21wYXRpYmlsaXR5IHNvIHdlIGFsd2F5cyBub29wXG4gICAgICByZXR1cm4gX3JlamVjdChnbG9iYWxWZXJzaW9uKTtcbiAgICB9XG5cbiAgICBjb25zdCBnbG9iYWxWZXJzaW9uUGFyc2VkID0ge1xuICAgICAgbWFqb3I6ICtnbG9iYWxWZXJzaW9uTWF0Y2hbMV0sXG4gICAgICBtaW5vcjogK2dsb2JhbFZlcnNpb25NYXRjaFsyXSxcbiAgICAgIHBhdGNoOiArZ2xvYmFsVmVyc2lvbk1hdGNoWzNdLFxuICAgICAgcHJlcmVsZWFzZTogZ2xvYmFsVmVyc2lvbk1hdGNoWzRdLFxuICAgIH07XG5cbiAgICAvLyBpZiBnbG9iYWxWZXJzaW9uIGhhcyBhIHByZXJlbGVhc2UgdGFnLCB2ZXJzaW9ucyBtdXN0IG1hdGNoIGV4YWN0bHlcbiAgICBpZiAoZ2xvYmFsVmVyc2lvblBhcnNlZC5wcmVyZWxlYXNlICE9IG51bGwpIHtcbiAgICAgIHJldHVybiBfcmVqZWN0KGdsb2JhbFZlcnNpb24pO1xuICAgIH1cblxuICAgIC8vIG1ham9yIHZlcnNpb25zIG11c3QgbWF0Y2hcbiAgICBpZiAob3duVmVyc2lvblBhcnNlZC5tYWpvciAhPT0gZ2xvYmFsVmVyc2lvblBhcnNlZC5tYWpvcikge1xuICAgICAgcmV0dXJuIF9yZWplY3QoZ2xvYmFsVmVyc2lvbik7XG4gICAgfVxuXG4gICAgaWYgKG93blZlcnNpb25QYXJzZWQubWFqb3IgPT09IDApIHtcbiAgICAgIGlmIChcbiAgICAgICAgb3duVmVyc2lvblBhcnNlZC5taW5vciA9PT0gZ2xvYmFsVmVyc2lvblBhcnNlZC5taW5vciAmJlxuICAgICAgICBvd25WZXJzaW9uUGFyc2VkLnBhdGNoIDw9IGdsb2JhbFZlcnNpb25QYXJzZWQucGF0Y2hcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gX2FjY2VwdChnbG9iYWxWZXJzaW9uKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIF9yZWplY3QoZ2xvYmFsVmVyc2lvbik7XG4gICAgfVxuXG4gICAgaWYgKG93blZlcnNpb25QYXJzZWQubWlub3IgPD0gZ2xvYmFsVmVyc2lvblBhcnNlZC5taW5vcikge1xuICAgICAgcmV0dXJuIF9hY2NlcHQoZ2xvYmFsVmVyc2lvbik7XG4gICAgfVxuXG4gICAgcmV0dXJuIF9yZWplY3QoZ2xvYmFsVmVyc2lvbik7XG4gIH07XG59XG5cbi8qKlxuICogVGVzdCBhbiBBUEkgdmVyc2lvbiB0byBzZWUgaWYgaXQgaXMgY29tcGF0aWJsZSB3aXRoIHRoaXMgQVBJLlxuICpcbiAqIC0gRXhhY3QgbWF0Y2ggaXMgYWx3YXlzIGNvbXBhdGlibGVcbiAqIC0gTWFqb3IgdmVyc2lvbnMgbXVzdCBtYXRjaCBleGFjdGx5XG4gKiAgICAtIDEueCBwYWNrYWdlIGNhbm5vdCB1c2UgZ2xvYmFsIDIueCBwYWNrYWdlXG4gKiAgICAtIDIueCBwYWNrYWdlIGNhbm5vdCB1c2UgZ2xvYmFsIDEueCBwYWNrYWdlXG4gKiAtIFRoZSBtaW5vciB2ZXJzaW9uIG9mIHRoZSBBUEkgbW9kdWxlIHJlcXVlc3RpbmcgYWNjZXNzIHRvIHRoZSBnbG9iYWwgQVBJIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHRoZSBtaW5vciB2ZXJzaW9uIG9mIHRoaXMgQVBJXG4gKiAgICAtIDEuMyBwYWNrYWdlIG1heSB1c2UgMS40IGdsb2JhbCBiZWNhdXNlIHRoZSBsYXRlciBnbG9iYWwgY29udGFpbnMgYWxsIGZ1bmN0aW9ucyAxLjMgZXhwZWN0c1xuICogICAgLSAxLjQgcGFja2FnZSBtYXkgTk9UIHVzZSAxLjMgZ2xvYmFsIGJlY2F1c2UgaXQgbWF5IHRyeSB0byBjYWxsIGZ1bmN0aW9ucyB3aGljaCBkb24ndCBleGlzdCBvbiAxLjNcbiAqIC0gSWYgdGhlIG1ham9yIHZlcnNpb24gaXMgMCwgdGhlIG1pbm9yIHZlcnNpb24gaXMgdHJlYXRlZCBhcyB0aGUgbWFqb3IgYW5kIHRoZSBwYXRjaCBpcyB0cmVhdGVkIGFzIHRoZSBtaW5vclxuICogLSBQYXRjaCBhbmQgYnVpbGQgdGFnIGRpZmZlcmVuY2VzIGFyZSBub3QgY29uc2lkZXJlZCBhdCB0aGlzIHRpbWVcbiAqXG4gKiBAcGFyYW0gdmVyc2lvbiB2ZXJzaW9uIG9mIHRoZSBBUEkgcmVxdWVzdGluZyBhbiBpbnN0YW5jZSBvZiB0aGUgZ2xvYmFsIEFQSVxuICovXG5leHBvcnQgY29uc3QgaXNDb21wYXRpYmxlID0gX21ha2VDb21wYXRpYmlsaXR5Q2hlY2soVkVSU0lPTik7XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuaW1wb3J0IHsgTWV0ZXJQcm92aWRlciB9IGZyb20gJy4uL21ldHJpY3MvTWV0ZXJQcm92aWRlcic7XG5pbXBvcnQgeyBDb250ZXh0TWFuYWdlciB9IGZyb20gJy4uL2NvbnRleHQvdHlwZXMnO1xuaW1wb3J0IHsgRGlhZ0xvZ2dlciB9IGZyb20gJy4uL2RpYWcvdHlwZXMnO1xuaW1wb3J0IHsgX2dsb2JhbFRoaXMgfSBmcm9tICcuLi9wbGF0Zm9ybSc7XG5pbXBvcnQgeyBUZXh0TWFwUHJvcGFnYXRvciB9IGZyb20gJy4uL3Byb3BhZ2F0aW9uL1RleHRNYXBQcm9wYWdhdG9yJztcbmltcG9ydCB0eXBlIHsgVHJhY2VyUHJvdmlkZXIgfSBmcm9tICcuLi90cmFjZS90cmFjZXJfcHJvdmlkZXInO1xuaW1wb3J0IHsgVkVSU0lPTiB9IGZyb20gJy4uL3ZlcnNpb24nO1xuaW1wb3J0IHsgaXNDb21wYXRpYmxlIH0gZnJvbSAnLi9zZW12ZXInO1xuXG5jb25zdCBtYWpvciA9IFZFUlNJT04uc3BsaXQoJy4nKVswXTtcbmNvbnN0IEdMT0JBTF9PUEVOVEVMRU1FVFJZX0FQSV9LRVkgPSBTeW1ib2wuZm9yKFxuICBgb3BlbnRlbGVtZXRyeS5qcy5hcGkuJHttYWpvcn1gXG4pO1xuXG5jb25zdCBfZ2xvYmFsID0gX2dsb2JhbFRoaXMgYXMgT1RlbEdsb2JhbDtcblxuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyR2xvYmFsPFR5cGUgZXh0ZW5kcyBrZXlvZiBPVGVsR2xvYmFsQVBJPihcbiAgdHlwZTogVHlwZSxcbiAgaW5zdGFuY2U6IE9UZWxHbG9iYWxBUElbVHlwZV0sXG4gIGRpYWc6IERpYWdMb2dnZXIsXG4gIGFsbG93T3ZlcnJpZGUgPSBmYWxzZVxuKTogYm9vbGVhbiB7XG4gIGNvbnN0IGFwaSA9IChfZ2xvYmFsW0dMT0JBTF9PUEVOVEVMRU1FVFJZX0FQSV9LRVldID0gX2dsb2JhbFtcbiAgICBHTE9CQUxfT1BFTlRFTEVNRVRSWV9BUElfS0VZXG4gIF0gPz8ge1xuICAgIHZlcnNpb246IFZFUlNJT04sXG4gIH0pO1xuXG4gIGlmICghYWxsb3dPdmVycmlkZSAmJiBhcGlbdHlwZV0pIHtcbiAgICAvLyBhbHJlYWR5IHJlZ2lzdGVyZWQgYW4gQVBJIG9mIHRoaXMgdHlwZVxuICAgIGNvbnN0IGVyciA9IG5ldyBFcnJvcihcbiAgICAgIGBAb3BlbnRlbGVtZXRyeS9hcGk6IEF0dGVtcHRlZCBkdXBsaWNhdGUgcmVnaXN0cmF0aW9uIG9mIEFQSTogJHt0eXBlfWBcbiAgICApO1xuICAgIGRpYWcuZXJyb3IoZXJyLnN0YWNrIHx8IGVyci5tZXNzYWdlKTtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAoYXBpLnZlcnNpb24gIT09IFZFUlNJT04pIHtcbiAgICAvLyBBbGwgcmVnaXN0ZXJlZCBBUElzIG11c3QgYmUgb2YgdGhlIHNhbWUgdmVyc2lvbiBleGFjdGx5XG4gICAgY29uc3QgZXJyID0gbmV3IEVycm9yKFxuICAgICAgYEBvcGVudGVsZW1ldHJ5L2FwaTogUmVnaXN0cmF0aW9uIG9mIHZlcnNpb24gdiR7YXBpLnZlcnNpb259IGZvciAke3R5cGV9IGRvZXMgbm90IG1hdGNoIHByZXZpb3VzbHkgcmVnaXN0ZXJlZCBBUEkgdiR7VkVSU0lPTn1gXG4gICAgKTtcbiAgICBkaWFnLmVycm9yKGVyci5zdGFjayB8fCBlcnIubWVzc2FnZSk7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgYXBpW3R5cGVdID0gaW5zdGFuY2U7XG4gIGRpYWcuZGVidWcoXG4gICAgYEBvcGVudGVsZW1ldHJ5L2FwaTogUmVnaXN0ZXJlZCBhIGdsb2JhbCBmb3IgJHt0eXBlfSB2JHtWRVJTSU9OfS5gXG4gICk7XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRHbG9iYWw8VHlwZSBleHRlbmRzIGtleW9mIE9UZWxHbG9iYWxBUEk+KFxuICB0eXBlOiBUeXBlXG4pOiBPVGVsR2xvYmFsQVBJW1R5cGVdIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgZ2xvYmFsVmVyc2lvbiA9IF9nbG9iYWxbR0xPQkFMX09QRU5URUxFTUVUUllfQVBJX0tFWV0/LnZlcnNpb247XG4gIGlmICghZ2xvYmFsVmVyc2lvbiB8fCAhaXNDb21wYXRpYmxlKGdsb2JhbFZlcnNpb24pKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHJldHVybiBfZ2xvYmFsW0dMT0JBTF9PUEVOVEVMRU1FVFJZX0FQSV9LRVldPy5bdHlwZV07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB1bnJlZ2lzdGVyR2xvYmFsKHR5cGU6IGtleW9mIE9UZWxHbG9iYWxBUEksIGRpYWc6IERpYWdMb2dnZXIpIHtcbiAgZGlhZy5kZWJ1ZyhcbiAgICBgQG9wZW50ZWxlbWV0cnkvYXBpOiBVbnJlZ2lzdGVyaW5nIGEgZ2xvYmFsIGZvciAke3R5cGV9IHYke1ZFUlNJT059LmBcbiAgKTtcbiAgY29uc3QgYXBpID0gX2dsb2JhbFtHTE9CQUxfT1BFTlRFTEVNRVRSWV9BUElfS0VZXTtcblxuICBpZiAoYXBpKSB7XG4gICAgZGVsZXRlIGFwaVt0eXBlXTtcbiAgfVxufVxuXG50eXBlIE9UZWxHbG9iYWwgPSB7XG4gIFtHTE9CQUxfT1BFTlRFTEVNRVRSWV9BUElfS0VZXT86IE9UZWxHbG9iYWxBUEk7XG59O1xuXG50eXBlIE9UZWxHbG9iYWxBUEkgPSB7XG4gIHZlcnNpb246IHN0cmluZztcblxuICBkaWFnPzogRGlhZ0xvZ2dlcjtcbiAgdHJhY2U/OiBUcmFjZXJQcm92aWRlcjtcbiAgY29udGV4dD86IENvbnRleHRNYW5hZ2VyO1xuICBtZXRyaWNzPzogTWV0ZXJQcm92aWRlcjtcbiAgcHJvcGFnYXRpb24/OiBUZXh0TWFwUHJvcGFnYXRvcjtcbn07XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuaW1wb3J0IHsgZ2V0R2xvYmFsIH0gZnJvbSAnLi4vaW50ZXJuYWwvZ2xvYmFsLXV0aWxzJztcbmltcG9ydCB7IENvbXBvbmVudExvZ2dlck9wdGlvbnMsIERpYWdMb2dnZXIsIERpYWdMb2dGdW5jdGlvbiB9IGZyb20gJy4vdHlwZXMnO1xuXG4vKipcbiAqIENvbXBvbmVudCBMb2dnZXIgd2hpY2ggaXMgbWVhbnQgdG8gYmUgdXNlZCBhcyBwYXJ0IG9mIGFueSBjb21wb25lbnQgd2hpY2hcbiAqIHdpbGwgYWRkIGF1dG9tYXRpY2FsbHkgYWRkaXRpb25hbCBuYW1lc3BhY2UgaW4gZnJvbnQgb2YgdGhlIGxvZyBtZXNzYWdlLlxuICogSXQgd2lsbCB0aGVuIGZvcndhcmQgYWxsIG1lc3NhZ2UgdG8gZ2xvYmFsIGRpYWcgbG9nZ2VyXG4gKiBAZXhhbXBsZVxuICogY29uc3QgY0xvZ2dlciA9IGRpYWcuY3JlYXRlQ29tcG9uZW50TG9nZ2VyKHsgbmFtZXNwYWNlOiAnQG9wZW50ZWxlbWV0cnkvaW5zdHJ1bWVudGF0aW9uLWh0dHAnIH0pO1xuICogY0xvZ2dlci5kZWJ1ZygndGVzdCcpO1xuICogLy8gQG9wZW50ZWxlbWV0cnkvaW5zdHJ1bWVudGF0aW9uLWh0dHAgdGVzdFxuICovXG5leHBvcnQgY2xhc3MgRGlhZ0NvbXBvbmVudExvZ2dlciBpbXBsZW1lbnRzIERpYWdMb2dnZXIge1xuICBwcml2YXRlIF9uYW1lc3BhY2U6IHN0cmluZztcblxuICBjb25zdHJ1Y3Rvcihwcm9wczogQ29tcG9uZW50TG9nZ2VyT3B0aW9ucykge1xuICAgIHRoaXMuX25hbWVzcGFjZSA9IHByb3BzLm5hbWVzcGFjZSB8fCAnRGlhZ0NvbXBvbmVudExvZ2dlcic7XG4gIH1cblxuICBwdWJsaWMgZGVidWcoLi4uYXJnczogYW55W10pOiB2b2lkIHtcbiAgICByZXR1cm4gbG9nUHJveHkoJ2RlYnVnJywgdGhpcy5fbmFtZXNwYWNlLCBhcmdzKTtcbiAgfVxuXG4gIHB1YmxpYyBlcnJvciguLi5hcmdzOiBhbnlbXSk6IHZvaWQge1xuICAgIHJldHVybiBsb2dQcm94eSgnZXJyb3InLCB0aGlzLl9uYW1lc3BhY2UsIGFyZ3MpO1xuICB9XG5cbiAgcHVibGljIGluZm8oLi4uYXJnczogYW55W10pOiB2b2lkIHtcbiAgICByZXR1cm4gbG9nUHJveHkoJ2luZm8nLCB0aGlzLl9uYW1lc3BhY2UsIGFyZ3MpO1xuICB9XG5cbiAgcHVibGljIHdhcm4oLi4uYXJnczogYW55W10pOiB2b2lkIHtcbiAgICByZXR1cm4gbG9nUHJveHkoJ3dhcm4nLCB0aGlzLl9uYW1lc3BhY2UsIGFyZ3MpO1xuICB9XG5cbiAgcHVibGljIHZlcmJvc2UoLi4uYXJnczogYW55W10pOiB2b2lkIHtcbiAgICByZXR1cm4gbG9nUHJveHkoJ3ZlcmJvc2UnLCB0aGlzLl9uYW1lc3BhY2UsIGFyZ3MpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGxvZ1Byb3h5KFxuICBmdW5jTmFtZToga2V5b2YgRGlhZ0xvZ2dlcixcbiAgbmFtZXNwYWNlOiBzdHJpbmcsXG4gIGFyZ3M6IGFueVxuKTogdm9pZCB7XG4gIGNvbnN0IGxvZ2dlciA9IGdldEdsb2JhbCgnZGlhZycpO1xuICAvLyBzaG9ydGN1dCBpZiBsb2dnZXIgbm90IHNldFxuICBpZiAoIWxvZ2dlcikge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGFyZ3MudW5zaGlmdChuYW1lc3BhY2UpO1xuICByZXR1cm4gbG9nZ2VyW2Z1bmNOYW1lXSguLi4oYXJncyBhcyBQYXJhbWV0ZXJzPERpYWdMb2dGdW5jdGlvbj4pKTtcbn1cbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5leHBvcnQgdHlwZSBEaWFnTG9nRnVuY3Rpb24gPSAobWVzc2FnZTogc3RyaW5nLCAuLi5hcmdzOiB1bmtub3duW10pID0+IHZvaWQ7XG5cbi8qKlxuICogRGVmaW5lcyBhbiBpbnRlcm5hbCBkaWFnbm9zdGljIGxvZ2dlciBpbnRlcmZhY2Ugd2hpY2ggaXMgdXNlZCB0byBsb2cgaW50ZXJuYWwgZGlhZ25vc3RpY1xuICogbWVzc2FnZXMsIHlvdSBjYW4gc2V0IHRoZSBkZWZhdWx0IGRpYWdub3N0aWMgbG9nZ2VyIHZpYSB0aGUge0BsaW5rIERpYWdBUEl9IHNldExvZ2dlciBmdW5jdGlvbi5cbiAqIEFQSSBwcm92aWRlZCBpbXBsZW1lbnRhdGlvbnMgaW5jbHVkZSA6LVxuICogLSBhIE5vLU9wIHtAbGluayBjcmVhdGVOb29wRGlhZ0xvZ2dlcn1cbiAqIC0gYSB7QGxpbmsgRGlhZ0xvZ0xldmVsfSBmaWx0ZXJpbmcgd3JhcHBlciB7QGxpbmsgY3JlYXRlTG9nTGV2ZWxEaWFnTG9nZ2VyfVxuICogLSBhIGdlbmVyYWwgQ29uc29sZSB7QGxpbmsgRGlhZ0NvbnNvbGVMb2dnZXJ9IHZlcnNpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRGlhZ0xvZ2dlciB7XG4gIC8qKiBMb2cgYW4gZXJyb3Igc2NlbmFyaW8gdGhhdCB3YXMgbm90IGV4cGVjdGVkIGFuZCBjYXVzZWQgdGhlIHJlcXVlc3RlZCBvcGVyYXRpb24gdG8gZmFpbC4gKi9cbiAgZXJyb3I6IERpYWdMb2dGdW5jdGlvbjtcblxuICAvKipcbiAgICogTG9nIGEgd2FybmluZyBzY2VuYXJpbyB0byBpbmZvcm0gdGhlIGRldmVsb3BlciBvZiBhbiBpc3N1ZXMgdGhhdCBzaG91bGQgYmUgaW52ZXN0aWdhdGVkLlxuICAgKiBUaGUgcmVxdWVzdGVkIG9wZXJhdGlvbiBtYXkgb3IgbWF5IG5vdCBoYXZlIHN1Y2NlZWRlZCBvciBjb21wbGV0ZWQuXG4gICAqL1xuICB3YXJuOiBEaWFnTG9nRnVuY3Rpb247XG5cbiAgLyoqXG4gICAqIExvZyBhIGdlbmVyYWwgaW5mb3JtYXRpb25hbCBtZXNzYWdlLCB0aGlzIHNob3VsZCBub3QgYWZmZWN0IGZ1bmN0aW9uYWxpdHkuXG4gICAqIFRoaXMgaXMgYWxzbyB0aGUgZGVmYXVsdCBsb2dnaW5nIGxldmVsIHNvIHRoaXMgc2hvdWxkIE5PVCBiZSB1c2VkIGZvciBsb2dnaW5nXG4gICAqIGRlYnVnZ2luZyBsZXZlbCBpbmZvcm1hdGlvbi5cbiAgICovXG4gIGluZm86IERpYWdMb2dGdW5jdGlvbjtcblxuICAvKipcbiAgICogTG9nIGEgZ2VuZXJhbCBkZWJ1ZyBtZXNzYWdlIHRoYXQgY2FuIGJlIHVzZWZ1bCBmb3IgaWRlbnRpZnlpbmcgYSBmYWlsdXJlLlxuICAgKiBJbmZvcm1hdGlvbiBsb2dnZWQgYXQgdGhpcyBsZXZlbCBtYXkgaW5jbHVkZSBkaWFnbm9zdGljIGRldGFpbHMgdGhhdCB3b3VsZFxuICAgKiBoZWxwIGlkZW50aWZ5IGEgZmFpbHVyZSBzY2VuYXJpby5cbiAgICogRm9yIGV4YW1wbGU6IExvZ2dpbmcgdGhlIG9yZGVyIG9mIGV4ZWN1dGlvbiBvZiBhc3luYyBvcGVyYXRpb25zLlxuICAgKi9cbiAgZGVidWc6IERpYWdMb2dGdW5jdGlvbjtcblxuICAvKipcbiAgICogTG9nIGEgZGV0YWlsZWQgKHZlcmJvc2UpIHRyYWNlIGxldmVsIGxvZ2dpbmcgdGhhdCBjYW4gYmUgdXNlZCB0byBpZGVudGlmeSBmYWlsdXJlc1xuICAgKiB3aGVyZSBkZWJ1ZyBsZXZlbCBsb2dnaW5nIHdvdWxkIGJlIGluc3VmZmljaWVudCwgdGhpcyBsZXZlbCBvZiB0cmFjaW5nIGNhbiBpbmNsdWRlXG4gICAqIGlucHV0IGFuZCBvdXRwdXQgcGFyYW1ldGVycyBhbmQgYXMgc3VjaCBtYXkgaW5jbHVkZSBQSUkgaW5mb3JtYXRpb24gcGFzc2luZyB0aHJvdWdoXG4gICAqIHRoZSBBUEkuIEFzIHN1Y2ggaXQgaXMgcmVjb21tZW5kZWQgdGhhdCB0aGlzIGxldmVsIG9mIHRyYWNpbmcgc2hvdWxkIG5vdCBiZSBlbmFibGVkXG4gICAqIGluIGEgcHJvZHVjdGlvbiBlbnZpcm9ubWVudC5cbiAgICovXG4gIHZlcmJvc2U6IERpYWdMb2dGdW5jdGlvbjtcbn1cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBhdmFpbGFibGUgaW50ZXJuYWwgbG9nZ2luZyBsZXZlbHMgZm9yIHRoZSBkaWFnbm9zdGljIGxvZ2dlciwgdGhlIG51bWVyaWMgdmFsdWVzXG4gKiBvZiB0aGUgbGV2ZWxzIGFyZSBkZWZpbmVkIHRvIG1hdGNoIHRoZSBvcmlnaW5hbCB2YWx1ZXMgZnJvbSB0aGUgaW5pdGlhbCBMb2dMZXZlbCB0byBhdm9pZFxuICogY29tcGF0aWJpbGl0eS9taWdyYXRpb24gaXNzdWVzIGZvciBhbnkgaW1wbGVtZW50YXRpb24gdGhhdCBhc3N1bWUgdGhlIG51bWVyaWMgb3JkZXJpbmcuXG4gKi9cbmV4cG9ydCBlbnVtIERpYWdMb2dMZXZlbCB7XG4gIC8qKiBEaWFnbm9zdGljIExvZ2dpbmcgbGV2ZWwgc2V0dGluZyB0byBkaXNhYmxlIGFsbCBsb2dnaW5nIChleGNlcHQgYW5kIGZvcmNlZCBsb2dzKSAqL1xuICBOT05FID0gMCxcblxuICAvKiogSWRlbnRpZmllcyBhbiBlcnJvciBzY2VuYXJpbyAqL1xuICBFUlJPUiA9IDMwLFxuXG4gIC8qKiBJZGVudGlmaWVzIGEgd2FybmluZyBzY2VuYXJpbyAqL1xuICBXQVJOID0gNTAsXG5cbiAgLyoqIEdlbmVyYWwgaW5mb3JtYXRpb25hbCBsb2cgbWVzc2FnZSAqL1xuICBJTkZPID0gNjAsXG5cbiAgLyoqIEdlbmVyYWwgZGVidWcgbG9nIG1lc3NhZ2UgKi9cbiAgREVCVUcgPSA3MCxcblxuICAvKipcbiAgICogRGV0YWlsZWQgdHJhY2UgbGV2ZWwgbG9nZ2luZyBzaG91bGQgb25seSBiZSB1c2VkIGZvciBkZXZlbG9wbWVudCwgc2hvdWxkIG9ubHkgYmUgc2V0XG4gICAqIGluIGEgZGV2ZWxvcG1lbnQgZW52aXJvbm1lbnQuXG4gICAqL1xuICBWRVJCT1NFID0gODAsXG5cbiAgLyoqIFVzZWQgdG8gc2V0IHRoZSBsb2dnaW5nIGxldmVsIHRvIGluY2x1ZGUgYWxsIGxvZ2dpbmcgKi9cbiAgQUxMID0gOTk5OSxcbn1cblxuLyoqXG4gKiBEZWZpbmVzIG9wdGlvbnMgZm9yIENvbXBvbmVudExvZ2dlclxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvbXBvbmVudExvZ2dlck9wdGlvbnMge1xuICBuYW1lc3BhY2U6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBEaWFnTG9nZ2VyT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUge0BsaW5rIERpYWdMb2dMZXZlbH0gdXNlZCB0byBmaWx0ZXIgbG9ncyBzZW50IHRvIHRoZSBsb2dnZXIuXG4gICAqXG4gICAqIEBkZWZhdWx0VmFsdWUgRGlhZ0xvZ0xldmVsLklORk9cbiAgICovXG4gIGxvZ0xldmVsPzogRGlhZ0xvZ0xldmVsO1xuXG4gIC8qKlxuICAgKiBTZXR0aW5nIHRoaXMgdmFsdWUgdG8gYHRydWVgIHdpbGwgc3VwcHJlc3MgdGhlIHdhcm5pbmcgbWVzc2FnZSBub3JtYWxseSBlbWl0dGVkIHdoZW4gcmVnaXN0ZXJpbmcgYSBsb2dnZXIgd2hlbiBhbm90aGVyIGxvZ2dlciBpcyBhbHJlYWR5IHJlZ2lzdGVyZWQuXG4gICAqL1xuICBzdXBwcmVzc092ZXJyaWRlTWVzc2FnZT86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGlhZ0xvZ2dlckFwaSB7XG4gIC8qKlxuICAgKiBTZXQgdGhlIGdsb2JhbCBEaWFnTG9nZ2VyIGFuZCBEaWFnTG9nTGV2ZWwuXG4gICAqIElmIGEgZ2xvYmFsIGRpYWcgbG9nZ2VyIGlzIGFscmVhZHkgc2V0LCB0aGlzIHdpbGwgb3ZlcnJpZGUgaXQuXG4gICAqXG4gICAqIEBwYXJhbSBsb2dnZXIgLSBUaGUge0BsaW5rIERpYWdMb2dnZXJ9IGluc3RhbmNlIHRvIHNldCBhcyB0aGUgZGVmYXVsdCBsb2dnZXIuXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gQSB7QGxpbmsgRGlhZ0xvZ2dlck9wdGlvbnN9IG9iamVjdC4gSWYgbm90IHByb3ZpZGVkLCBkZWZhdWx0IHZhbHVlcyB3aWxsIGJlIHNldC5cbiAgICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBsb2dnZXIgd2FzIHN1Y2Nlc3NmdWxseSByZWdpc3RlcmVkLCBlbHNlIGBmYWxzZWBcbiAgICovXG4gIHNldExvZ2dlcihsb2dnZXI6IERpYWdMb2dnZXIsIG9wdGlvbnM/OiBEaWFnTG9nZ2VyT3B0aW9ucyk6IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqXG4gICAqIEBwYXJhbSBsb2dnZXIgLSBUaGUge0BsaW5rIERpYWdMb2dnZXJ9IGluc3RhbmNlIHRvIHNldCBhcyB0aGUgZGVmYXVsdCBsb2dnZXIuXG4gICAqIEBwYXJhbSBsb2dMZXZlbCAtIFRoZSB7QGxpbmsgRGlhZ0xvZ0xldmVsfSB1c2VkIHRvIGZpbHRlciBsb2dzIHNlbnQgdG8gdGhlIGxvZ2dlci4gSWYgbm90IHByb3ZpZGVkIGl0IHdpbGwgZGVmYXVsdCB0byB7QGxpbmsgRGlhZ0xvZ0xldmVsLklORk99LlxuICAgKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGxvZ2dlciB3YXMgc3VjY2Vzc2Z1bGx5IHJlZ2lzdGVyZWQsIGVsc2UgYGZhbHNlYFxuICAgKi9cbiAgc2V0TG9nZ2VyKGxvZ2dlcjogRGlhZ0xvZ2dlciwgbG9nTGV2ZWw/OiBEaWFnTG9nTGV2ZWwpOiBib29sZWFuO1xufVxuIiwgIi8qXG4gKiBDb3B5cmlnaHQgVGhlIE9wZW5UZWxlbWV0cnkgQXV0aG9yc1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgIGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IERpYWdMb2dGdW5jdGlvbiwgRGlhZ0xvZ2dlciwgRGlhZ0xvZ0xldmVsIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlTG9nTGV2ZWxEaWFnTG9nZ2VyKFxuICBtYXhMZXZlbDogRGlhZ0xvZ0xldmVsLFxuICBsb2dnZXI6IERpYWdMb2dnZXJcbik6IERpYWdMb2dnZXIge1xuICBpZiAobWF4TGV2ZWwgPCBEaWFnTG9nTGV2ZWwuTk9ORSkge1xuICAgIG1heExldmVsID0gRGlhZ0xvZ0xldmVsLk5PTkU7XG4gIH0gZWxzZSBpZiAobWF4TGV2ZWwgPiBEaWFnTG9nTGV2ZWwuQUxMKSB7XG4gICAgbWF4TGV2ZWwgPSBEaWFnTG9nTGV2ZWwuQUxMO1xuICB9XG5cbiAgLy8gSW4gY2FzZSB0aGUgbG9nZ2VyIGlzIG51bGwgb3IgdW5kZWZpbmVkXG4gIGxvZ2dlciA9IGxvZ2dlciB8fCB7fTtcblxuICBmdW5jdGlvbiBfZmlsdGVyRnVuYyhcbiAgICBmdW5jTmFtZToga2V5b2YgRGlhZ0xvZ2dlcixcbiAgICB0aGVMZXZlbDogRGlhZ0xvZ0xldmVsXG4gICk6IERpYWdMb2dGdW5jdGlvbiB7XG4gICAgY29uc3QgdGhlRnVuYyA9IGxvZ2dlcltmdW5jTmFtZV07XG5cbiAgICBpZiAodHlwZW9mIHRoZUZ1bmMgPT09ICdmdW5jdGlvbicgJiYgbWF4TGV2ZWwgPj0gdGhlTGV2ZWwpIHtcbiAgICAgIHJldHVybiB0aGVGdW5jLmJpbmQobG9nZ2VyKTtcbiAgICB9XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHt9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBlcnJvcjogX2ZpbHRlckZ1bmMoJ2Vycm9yJywgRGlhZ0xvZ0xldmVsLkVSUk9SKSxcbiAgICB3YXJuOiBfZmlsdGVyRnVuYygnd2FybicsIERpYWdMb2dMZXZlbC5XQVJOKSxcbiAgICBpbmZvOiBfZmlsdGVyRnVuYygnaW5mbycsIERpYWdMb2dMZXZlbC5JTkZPKSxcbiAgICBkZWJ1ZzogX2ZpbHRlckZ1bmMoJ2RlYnVnJywgRGlhZ0xvZ0xldmVsLkRFQlVHKSxcbiAgICB2ZXJib3NlOiBfZmlsdGVyRnVuYygndmVyYm9zZScsIERpYWdMb2dMZXZlbC5WRVJCT1NFKSxcbiAgfTtcbn1cbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5pbXBvcnQgeyBEaWFnQ29tcG9uZW50TG9nZ2VyIH0gZnJvbSAnLi4vZGlhZy9Db21wb25lbnRMb2dnZXInO1xuaW1wb3J0IHsgY3JlYXRlTG9nTGV2ZWxEaWFnTG9nZ2VyIH0gZnJvbSAnLi4vZGlhZy9pbnRlcm5hbC9sb2dMZXZlbExvZ2dlcic7XG5pbXBvcnQge1xuICBDb21wb25lbnRMb2dnZXJPcHRpb25zLFxuICBEaWFnTG9nRnVuY3Rpb24sXG4gIERpYWdMb2dnZXIsXG4gIERpYWdMb2dnZXJBcGksXG4gIERpYWdMb2dMZXZlbCxcbn0gZnJvbSAnLi4vZGlhZy90eXBlcyc7XG5pbXBvcnQge1xuICBnZXRHbG9iYWwsXG4gIHJlZ2lzdGVyR2xvYmFsLFxuICB1bnJlZ2lzdGVyR2xvYmFsLFxufSBmcm9tICcuLi9pbnRlcm5hbC9nbG9iYWwtdXRpbHMnO1xuXG5jb25zdCBBUElfTkFNRSA9ICdkaWFnJztcblxuLyoqXG4gKiBTaW5nbGV0b24gb2JqZWN0IHdoaWNoIHJlcHJlc2VudHMgdGhlIGVudHJ5IHBvaW50IHRvIHRoZSBPcGVuVGVsZW1ldHJ5IGludGVybmFsXG4gKiBkaWFnbm9zdGljIEFQSVxuICovXG5leHBvcnQgY2xhc3MgRGlhZ0FQSSBpbXBsZW1lbnRzIERpYWdMb2dnZXIsIERpYWdMb2dnZXJBcGkge1xuICBwcml2YXRlIHN0YXRpYyBfaW5zdGFuY2U/OiBEaWFnQVBJO1xuXG4gIC8qKiBHZXQgdGhlIHNpbmdsZXRvbiBpbnN0YW5jZSBvZiB0aGUgRGlhZ0FQSSBBUEkgKi9cbiAgcHVibGljIHN0YXRpYyBpbnN0YW5jZSgpOiBEaWFnQVBJIHtcbiAgICBpZiAoIXRoaXMuX2luc3RhbmNlKSB7XG4gICAgICB0aGlzLl9pbnN0YW5jZSA9IG5ldyBEaWFnQVBJKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX2luc3RhbmNlO1xuICB9XG5cbiAgLyoqXG4gICAqIFByaXZhdGUgaW50ZXJuYWwgY29uc3RydWN0b3JcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgY29uc3RydWN0b3IoKSB7XG4gICAgZnVuY3Rpb24gX2xvZ1Byb3h5KGZ1bmNOYW1lOiBrZXlvZiBEaWFnTG9nZ2VyKTogRGlhZ0xvZ0Z1bmN0aW9uIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbiAoLi4uYXJncykge1xuICAgICAgICBjb25zdCBsb2dnZXIgPSBnZXRHbG9iYWwoJ2RpYWcnKTtcbiAgICAgICAgLy8gc2hvcnRjdXQgaWYgbG9nZ2VyIG5vdCBzZXRcbiAgICAgICAgaWYgKCFsb2dnZXIpIHJldHVybjtcbiAgICAgICAgcmV0dXJuIGxvZ2dlcltmdW5jTmFtZV0oLi4uYXJncyk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIFVzaW5nIHNlbGYgbG9jYWwgdmFyaWFibGUgZm9yIG1pbmlmaWNhdGlvbiBwdXJwb3NlcyBhcyAndGhpcycgY2Fubm90IGJlIG1pbmlmaWVkXG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICAvLyBEaWFnQVBJIHNwZWNpZmljIGZ1bmN0aW9uc1xuXG4gICAgY29uc3Qgc2V0TG9nZ2VyOiBEaWFnTG9nZ2VyQXBpWydzZXRMb2dnZXInXSA9IChcbiAgICAgIGxvZ2dlcixcbiAgICAgIG9wdGlvbnNPckxvZ0xldmVsID0geyBsb2dMZXZlbDogRGlhZ0xvZ0xldmVsLklORk8gfVxuICAgICkgPT4ge1xuICAgICAgaWYgKGxvZ2dlciA9PT0gc2VsZikge1xuICAgICAgICAvLyBUaGVyZSBpc24ndCBtdWNoIHdlIGNhbiBkbyBoZXJlLlxuICAgICAgICAvLyBMb2dnaW5nIHRvIHRoZSBjb25zb2xlIG1pZ2h0IGJyZWFrIHRoZSB1c2VyIGFwcGxpY2F0aW9uLlxuICAgICAgICAvLyBUcnkgdG8gbG9nIHRvIHNlbGYuIElmIGEgbG9nZ2VyIHdhcyBwcmV2aW91c2x5IHJlZ2lzdGVyZWQgaXQgd2lsbCByZWNlaXZlIHRoZSBsb2cuXG4gICAgICAgIGNvbnN0IGVyciA9IG5ldyBFcnJvcihcbiAgICAgICAgICAnQ2Fubm90IHVzZSBkaWFnIGFzIHRoZSBsb2dnZXIgZm9yIGl0c2VsZi4gUGxlYXNlIHVzZSBhIERpYWdMb2dnZXIgaW1wbGVtZW50YXRpb24gbGlrZSBDb25zb2xlRGlhZ0xvZ2dlciBvciBhIGN1c3RvbSBpbXBsZW1lbnRhdGlvbidcbiAgICAgICAgKTtcbiAgICAgICAgc2VsZi5lcnJvcihlcnIuc3RhY2sgPz8gZXJyLm1lc3NhZ2UpO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9uc09yTG9nTGV2ZWwgPT09ICdudW1iZXInKSB7XG4gICAgICAgIG9wdGlvbnNPckxvZ0xldmVsID0ge1xuICAgICAgICAgIGxvZ0xldmVsOiBvcHRpb25zT3JMb2dMZXZlbCxcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgb2xkTG9nZ2VyID0gZ2V0R2xvYmFsKCdkaWFnJyk7XG4gICAgICBjb25zdCBuZXdMb2dnZXIgPSBjcmVhdGVMb2dMZXZlbERpYWdMb2dnZXIoXG4gICAgICAgIG9wdGlvbnNPckxvZ0xldmVsLmxvZ0xldmVsID8/IERpYWdMb2dMZXZlbC5JTkZPLFxuICAgICAgICBsb2dnZXJcbiAgICAgICk7XG4gICAgICAvLyBUaGVyZSBhbHJlYWR5IGlzIGFuIGxvZ2dlciByZWdpc3RlcmVkLiBXZSdsbCBsZXQgaXQga25vdyBiZWZvcmUgb3ZlcndyaXRpbmcgaXQuXG4gICAgICBpZiAob2xkTG9nZ2VyICYmICFvcHRpb25zT3JMb2dMZXZlbC5zdXBwcmVzc092ZXJyaWRlTWVzc2FnZSkge1xuICAgICAgICBjb25zdCBzdGFjayA9IG5ldyBFcnJvcigpLnN0YWNrID8/ICc8ZmFpbGVkIHRvIGdlbmVyYXRlIHN0YWNrdHJhY2U+JztcbiAgICAgICAgb2xkTG9nZ2VyLndhcm4oYEN1cnJlbnQgbG9nZ2VyIHdpbGwgYmUgb3ZlcndyaXR0ZW4gZnJvbSAke3N0YWNrfWApO1xuICAgICAgICBuZXdMb2dnZXIud2FybihcbiAgICAgICAgICBgQ3VycmVudCBsb2dnZXIgd2lsbCBvdmVyd3JpdGUgb25lIGFscmVhZHkgcmVnaXN0ZXJlZCBmcm9tICR7c3RhY2t9YFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVnaXN0ZXJHbG9iYWwoJ2RpYWcnLCBuZXdMb2dnZXIsIHNlbGYsIHRydWUpO1xuICAgIH07XG5cbiAgICBzZWxmLnNldExvZ2dlciA9IHNldExvZ2dlcjtcblxuICAgIHNlbGYuZGlzYWJsZSA9ICgpID0+IHtcbiAgICAgIHVucmVnaXN0ZXJHbG9iYWwoQVBJX05BTUUsIHNlbGYpO1xuICAgIH07XG5cbiAgICBzZWxmLmNyZWF0ZUNvbXBvbmVudExvZ2dlciA9IChvcHRpb25zOiBDb21wb25lbnRMb2dnZXJPcHRpb25zKSA9PiB7XG4gICAgICByZXR1cm4gbmV3IERpYWdDb21wb25lbnRMb2dnZXIob3B0aW9ucyk7XG4gICAgfTtcblxuICAgIHNlbGYudmVyYm9zZSA9IF9sb2dQcm94eSgndmVyYm9zZScpO1xuICAgIHNlbGYuZGVidWcgPSBfbG9nUHJveHkoJ2RlYnVnJyk7XG4gICAgc2VsZi5pbmZvID0gX2xvZ1Byb3h5KCdpbmZvJyk7XG4gICAgc2VsZi53YXJuID0gX2xvZ1Byb3h5KCd3YXJuJyk7XG4gICAgc2VsZi5lcnJvciA9IF9sb2dQcm94eSgnZXJyb3InKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRMb2dnZXIhOiBEaWFnTG9nZ2VyQXBpWydzZXRMb2dnZXInXTtcbiAgLyoqXG4gICAqXG4gICAqL1xuICBwdWJsaWMgY3JlYXRlQ29tcG9uZW50TG9nZ2VyITogKFxuICAgIG9wdGlvbnM6IENvbXBvbmVudExvZ2dlck9wdGlvbnNcbiAgKSA9PiBEaWFnTG9nZ2VyO1xuXG4gIC8vIERpYWdMb2dnZXIgaW1wbGVtZW50YXRpb25cbiAgcHVibGljIHZlcmJvc2UhOiBEaWFnTG9nRnVuY3Rpb247XG4gIHB1YmxpYyBkZWJ1ZyE6IERpYWdMb2dGdW5jdGlvbjtcbiAgcHVibGljIGluZm8hOiBEaWFnTG9nRnVuY3Rpb247XG4gIHB1YmxpYyB3YXJuITogRGlhZ0xvZ0Z1bmN0aW9uO1xuICBwdWJsaWMgZXJyb3IhOiBEaWFnTG9nRnVuY3Rpb247XG5cbiAgLyoqXG4gICAqIFVucmVnaXN0ZXIgdGhlIGdsb2JhbCBsb2dnZXIgYW5kIHJldHVybiB0byBOb29wXG4gICAqL1xuICBwdWJsaWMgZGlzYWJsZSE6ICgpID0+IHZvaWQ7XG59XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBCYWdnYWdlLCBCYWdnYWdlRW50cnkgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBjbGFzcyBCYWdnYWdlSW1wbCBpbXBsZW1lbnRzIEJhZ2dhZ2Uge1xuICBwcml2YXRlIF9lbnRyaWVzOiBNYXA8c3RyaW5nLCBCYWdnYWdlRW50cnk+O1xuXG4gIGNvbnN0cnVjdG9yKGVudHJpZXM/OiBNYXA8c3RyaW5nLCBCYWdnYWdlRW50cnk+KSB7XG4gICAgdGhpcy5fZW50cmllcyA9IGVudHJpZXMgPyBuZXcgTWFwKGVudHJpZXMpIDogbmV3IE1hcCgpO1xuICB9XG5cbiAgZ2V0RW50cnkoa2V5OiBzdHJpbmcpOiBCYWdnYWdlRW50cnkgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGVudHJ5ID0gdGhpcy5fZW50cmllcy5nZXQoa2V5KTtcbiAgICBpZiAoIWVudHJ5KSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBlbnRyeSk7XG4gIH1cblxuICBnZXRBbGxFbnRyaWVzKCk6IFtzdHJpbmcsIEJhZ2dhZ2VFbnRyeV1bXSB7XG4gICAgcmV0dXJuIEFycmF5LmZyb20odGhpcy5fZW50cmllcy5lbnRyaWVzKCkpLm1hcCgoW2ssIHZdKSA9PiBbaywgdl0pO1xuICB9XG5cbiAgc2V0RW50cnkoa2V5OiBzdHJpbmcsIGVudHJ5OiBCYWdnYWdlRW50cnkpOiBCYWdnYWdlSW1wbCB7XG4gICAgY29uc3QgbmV3QmFnZ2FnZSA9IG5ldyBCYWdnYWdlSW1wbCh0aGlzLl9lbnRyaWVzKTtcbiAgICBuZXdCYWdnYWdlLl9lbnRyaWVzLnNldChrZXksIGVudHJ5KTtcbiAgICByZXR1cm4gbmV3QmFnZ2FnZTtcbiAgfVxuXG4gIHJlbW92ZUVudHJ5KGtleTogc3RyaW5nKTogQmFnZ2FnZUltcGwge1xuICAgIGNvbnN0IG5ld0JhZ2dhZ2UgPSBuZXcgQmFnZ2FnZUltcGwodGhpcy5fZW50cmllcyk7XG4gICAgbmV3QmFnZ2FnZS5fZW50cmllcy5kZWxldGUoa2V5KTtcbiAgICByZXR1cm4gbmV3QmFnZ2FnZTtcbiAgfVxuXG4gIHJlbW92ZUVudHJpZXMoLi4ua2V5czogc3RyaW5nW10pOiBCYWdnYWdlSW1wbCB7XG4gICAgY29uc3QgbmV3QmFnZ2FnZSA9IG5ldyBCYWdnYWdlSW1wbCh0aGlzLl9lbnRyaWVzKTtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzKSB7XG4gICAgICBuZXdCYWdnYWdlLl9lbnRyaWVzLmRlbGV0ZShrZXkpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3QmFnZ2FnZTtcbiAgfVxuXG4gIGNsZWFyKCk6IEJhZ2dhZ2VJbXBsIHtcbiAgICByZXR1cm4gbmV3IEJhZ2dhZ2VJbXBsKCk7XG4gIH1cbn1cbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG4vKipcbiAqIFN5bWJvbCB1c2VkIHRvIG1ha2UgQmFnZ2FnZUVudHJ5TWV0YWRhdGEgYW4gb3BhcXVlIHR5cGVcbiAqL1xuZXhwb3J0IGNvbnN0IGJhZ2dhZ2VFbnRyeU1ldGFkYXRhU3ltYm9sID0gU3ltYm9sKCdCYWdnYWdlRW50cnlNZXRhZGF0YScpO1xuIiwgIi8qXG4gKiBDb3B5cmlnaHQgVGhlIE9wZW5UZWxlbWV0cnkgQXV0aG9yc1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgIGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IERpYWdBUEkgfSBmcm9tICcuLi9hcGkvZGlhZyc7XG5pbXBvcnQgeyBCYWdnYWdlSW1wbCB9IGZyb20gJy4vaW50ZXJuYWwvYmFnZ2FnZS1pbXBsJztcbmltcG9ydCB7IGJhZ2dhZ2VFbnRyeU1ldGFkYXRhU3ltYm9sIH0gZnJvbSAnLi9pbnRlcm5hbC9zeW1ib2wnO1xuaW1wb3J0IHsgQmFnZ2FnZSwgQmFnZ2FnZUVudHJ5LCBCYWdnYWdlRW50cnlNZXRhZGF0YSB9IGZyb20gJy4vdHlwZXMnO1xuXG5jb25zdCBkaWFnID0gRGlhZ0FQSS5pbnN0YW5jZSgpO1xuXG4vKipcbiAqIENyZWF0ZSBhIG5ldyBCYWdnYWdlIHdpdGggb3B0aW9uYWwgZW50cmllc1xuICpcbiAqIEBwYXJhbSBlbnRyaWVzIEFuIGFycmF5IG9mIGJhZ2dhZ2UgZW50cmllcyB0aGUgbmV3IGJhZ2dhZ2Ugc2hvdWxkIGNvbnRhaW5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUJhZ2dhZ2UoXG4gIGVudHJpZXM6IFJlY29yZDxzdHJpbmcsIEJhZ2dhZ2VFbnRyeT4gPSB7fVxuKTogQmFnZ2FnZSB7XG4gIHJldHVybiBuZXcgQmFnZ2FnZUltcGwobmV3IE1hcChPYmplY3QuZW50cmllcyhlbnRyaWVzKSkpO1xufVxuXG4vKipcbiAqIENyZWF0ZSBhIHNlcmlhbGl6YWJsZSBCYWdnYWdlRW50cnlNZXRhZGF0YSBvYmplY3QgZnJvbSBhIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0gc3RyIHN0cmluZyBtZXRhZGF0YS4gRm9ybWF0IGlzIGN1cnJlbnRseSBub3QgZGVmaW5lZCBieSB0aGUgc3BlYyBhbmQgaGFzIG5vIHNwZWNpYWwgbWVhbmluZy5cbiAqXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBiYWdnYWdlRW50cnlNZXRhZGF0YUZyb21TdHJpbmcoXG4gIHN0cjogc3RyaW5nXG4pOiBCYWdnYWdlRW50cnlNZXRhZGF0YSB7XG4gIGlmICh0eXBlb2Ygc3RyICE9PSAnc3RyaW5nJykge1xuICAgIGRpYWcuZXJyb3IoXG4gICAgICBgQ2Fubm90IGNyZWF0ZSBiYWdnYWdlIG1ldGFkYXRhIGZyb20gdW5rbm93biB0eXBlOiAke3R5cGVvZiBzdHJ9YFxuICAgICk7XG4gICAgc3RyID0gJyc7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIF9fVFlQRV9fOiBiYWdnYWdlRW50cnlNZXRhZGF0YVN5bWJvbCxcbiAgICB0b1N0cmluZygpIHtcbiAgICAgIHJldHVybiBzdHI7XG4gICAgfSxcbiAgfTtcbn1cbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5pbXBvcnQgeyBDb250ZXh0IH0gZnJvbSAnLi90eXBlcyc7XG5cbi8qKiBHZXQgYSBrZXkgdG8gdW5pcXVlbHkgaWRlbnRpZnkgYSBjb250ZXh0IHZhbHVlICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQ29udGV4dEtleShkZXNjcmlwdGlvbjogc3RyaW5nKSB7XG4gIC8vIFRoZSBzcGVjaWZpY2F0aW9uIHN0YXRlcyB0aGF0IGZvciB0aGUgc2FtZSBpbnB1dCwgbXVsdGlwbGUgY2FsbHMgc2hvdWxkXG4gIC8vIHJldHVybiBkaWZmZXJlbnQga2V5cy4gRHVlIHRvIHRoZSBuYXR1cmUgb2YgdGhlIEpTIGRlcGVuZGVuY3kgbWFuYWdlbWVudFxuICAvLyBzeXN0ZW0sIHRoaXMgY3JlYXRlcyBwcm9ibGVtcyB3aGVyZSBtdWx0aXBsZSB2ZXJzaW9ucyBvZiBzb21lIHBhY2thZ2VcbiAgLy8gY291bGQgaG9sZCBkaWZmZXJlbnQga2V5cyBmb3IgdGhlIHNhbWUgcHJvcGVydHkuXG4gIC8vXG4gIC8vIFRoZXJlZm9yZSwgd2UgdXNlIFN5bWJvbC5mb3Igd2hpY2ggcmV0dXJucyB0aGUgc2FtZSBrZXkgZm9yIHRoZSBzYW1lIGlucHV0LlxuICByZXR1cm4gU3ltYm9sLmZvcihkZXNjcmlwdGlvbik7XG59XG5cbmNsYXNzIEJhc2VDb250ZXh0IGltcGxlbWVudHMgQ29udGV4dCB7XG4gIHByaXZhdGUgX2N1cnJlbnRDb250ZXh0ITogTWFwPHN5bWJvbCwgdW5rbm93bj47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBjb250ZXh0IHdoaWNoIGluaGVyaXRzIHZhbHVlcyBmcm9tIGFuIG9wdGlvbmFsIHBhcmVudCBjb250ZXh0LlxuICAgKlxuICAgKiBAcGFyYW0gcGFyZW50Q29udGV4dCBhIGNvbnRleHQgZnJvbSB3aGljaCB0byBpbmhlcml0IHZhbHVlc1xuICAgKi9cbiAgY29uc3RydWN0b3IocGFyZW50Q29udGV4dD86IE1hcDxzeW1ib2wsIHVua25vd24+KSB7XG4gICAgLy8gZm9yIG1pbmlmaWNhdGlvblxuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgc2VsZi5fY3VycmVudENvbnRleHQgPSBwYXJlbnRDb250ZXh0ID8gbmV3IE1hcChwYXJlbnRDb250ZXh0KSA6IG5ldyBNYXAoKTtcblxuICAgIHNlbGYuZ2V0VmFsdWUgPSAoa2V5OiBzeW1ib2wpID0+IHNlbGYuX2N1cnJlbnRDb250ZXh0LmdldChrZXkpO1xuXG4gICAgc2VsZi5zZXRWYWx1ZSA9IChrZXk6IHN5bWJvbCwgdmFsdWU6IHVua25vd24pOiBDb250ZXh0ID0+IHtcbiAgICAgIGNvbnN0IGNvbnRleHQgPSBuZXcgQmFzZUNvbnRleHQoc2VsZi5fY3VycmVudENvbnRleHQpO1xuICAgICAgY29udGV4dC5fY3VycmVudENvbnRleHQuc2V0KGtleSwgdmFsdWUpO1xuICAgICAgcmV0dXJuIGNvbnRleHQ7XG4gICAgfTtcblxuICAgIHNlbGYuZGVsZXRlVmFsdWUgPSAoa2V5OiBzeW1ib2wpOiBDb250ZXh0ID0+IHtcbiAgICAgIGNvbnN0IGNvbnRleHQgPSBuZXcgQmFzZUNvbnRleHQoc2VsZi5fY3VycmVudENvbnRleHQpO1xuICAgICAgY29udGV4dC5fY3VycmVudENvbnRleHQuZGVsZXRlKGtleSk7XG4gICAgICByZXR1cm4gY29udGV4dDtcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhIHZhbHVlIGZyb20gdGhlIGNvbnRleHQuXG4gICAqXG4gICAqIEBwYXJhbSBrZXkga2V5IHdoaWNoIGlkZW50aWZpZXMgYSBjb250ZXh0IHZhbHVlXG4gICAqL1xuICBwdWJsaWMgZ2V0VmFsdWUhOiAoa2V5OiBzeW1ib2wpID0+IHVua25vd247XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIG5ldyBjb250ZXh0IHdoaWNoIGluaGVyaXRzIGZyb20gdGhpcyBjb250ZXh0IGFuZCBoYXNcbiAgICogdGhlIGdpdmVuIGtleSBzZXQgdG8gdGhlIGdpdmVuIHZhbHVlLlxuICAgKlxuICAgKiBAcGFyYW0ga2V5IGNvbnRleHQga2V5IGZvciB3aGljaCB0byBzZXQgdGhlIHZhbHVlXG4gICAqIEBwYXJhbSB2YWx1ZSB2YWx1ZSB0byBzZXQgZm9yIHRoZSBnaXZlbiBrZXlcbiAgICovXG4gIHB1YmxpYyBzZXRWYWx1ZSE6IChrZXk6IHN5bWJvbCwgdmFsdWU6IHVua25vd24pID0+IENvbnRleHQ7XG5cbiAgLyoqXG4gICAqIFJldHVybiBhIG5ldyBjb250ZXh0IHdoaWNoIGluaGVyaXRzIGZyb20gdGhpcyBjb250ZXh0IGJ1dCBkb2VzXG4gICAqIG5vdCBjb250YWluIGEgdmFsdWUgZm9yIHRoZSBnaXZlbiBrZXkuXG4gICAqXG4gICAqIEBwYXJhbSBrZXkgY29udGV4dCBrZXkgZm9yIHdoaWNoIHRvIGNsZWFyIGEgdmFsdWVcbiAgICovXG4gIHB1YmxpYyBkZWxldGVWYWx1ZSE6IChrZXk6IHN5bWJvbCkgPT4gQ29udGV4dDtcbn1cblxuLyoqIFRoZSByb290IGNvbnRleHQgaXMgdXNlZCBhcyB0aGUgZGVmYXVsdCBwYXJlbnQgY29udGV4dCB3aGVuIHRoZXJlIGlzIG5vIGFjdGl2ZSBjb250ZXh0ICovXG5leHBvcnQgY29uc3QgUk9PVF9DT05URVhUOiBDb250ZXh0ID0gbmV3IEJhc2VDb250ZXh0KCk7XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuaW1wb3J0IHsgRGlhZ0xvZ2dlciwgRGlhZ0xvZ0Z1bmN0aW9uIH0gZnJvbSAnLi90eXBlcyc7XG5cbnR5cGUgQ29uc29sZU1hcEtleXMgPSAnZXJyb3InIHwgJ3dhcm4nIHwgJ2luZm8nIHwgJ2RlYnVnJyB8ICd0cmFjZSc7XG5jb25zdCBjb25zb2xlTWFwOiB7IG46IGtleW9mIERpYWdMb2dnZXI7IGM6IENvbnNvbGVNYXBLZXlzIH1bXSA9IFtcbiAgeyBuOiAnZXJyb3InLCBjOiAnZXJyb3InIH0sXG4gIHsgbjogJ3dhcm4nLCBjOiAnd2FybicgfSxcbiAgeyBuOiAnaW5mbycsIGM6ICdpbmZvJyB9LFxuICB7IG46ICdkZWJ1ZycsIGM6ICdkZWJ1ZycgfSxcbiAgeyBuOiAndmVyYm9zZScsIGM6ICd0cmFjZScgfSxcbl07XG5cbi8qKlxuICogQSBzaW1wbGUgSW1tdXRhYmxlIENvbnNvbGUgYmFzZWQgZGlhZ25vc3RpYyBsb2dnZXIgd2hpY2ggd2lsbCBvdXRwdXQgYW55IG1lc3NhZ2VzIHRvIHRoZSBDb25zb2xlLlxuICogSWYgeW91IHdhbnQgdG8gbGltaXQgdGhlIGFtb3VudCBvZiBsb2dnaW5nIHRvIGEgc3BlY2lmaWMgbGV2ZWwgb3IgbG93ZXIgdXNlIHRoZVxuICoge0BsaW5rIGNyZWF0ZUxvZ0xldmVsRGlhZ0xvZ2dlcn1cbiAqL1xuZXhwb3J0IGNsYXNzIERpYWdDb25zb2xlTG9nZ2VyIGltcGxlbWVudHMgRGlhZ0xvZ2dlciB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIGZ1bmN0aW9uIF9jb25zb2xlRnVuYyhmdW5jTmFtZTogQ29uc29sZU1hcEtleXMpOiBEaWFnTG9nRnVuY3Rpb24ge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uICguLi5hcmdzKSB7XG4gICAgICAgIGlmIChjb25zb2xlKSB7XG4gICAgICAgICAgLy8gU29tZSBlbnZpcm9ubWVudHMgb25seSBleHBvc2UgdGhlIGNvbnNvbGUgd2hlbiB0aGUgRjEyIGRldmVsb3BlciBjb25zb2xlIGlzIG9wZW5cbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgICAgIGxldCB0aGVGdW5jID0gY29uc29sZVtmdW5jTmFtZV07XG4gICAgICAgICAgaWYgKHR5cGVvZiB0aGVGdW5jICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAvLyBOb3QgYWxsIGVudmlyb25tZW50cyBzdXBwb3J0IGFsbCBmdW5jdGlvbnNcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgICAgICB0aGVGdW5jID0gY29uc29sZS5sb2c7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gT25lIGxhc3QgZmluYWwgY2hlY2tcbiAgICAgICAgICBpZiAodHlwZW9mIHRoZUZ1bmMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGVGdW5jLmFwcGx5KGNvbnNvbGUsIGFyZ3MpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbnNvbGVNYXAubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXNbY29uc29sZU1hcFtpXS5uXSA9IF9jb25zb2xlRnVuYyhjb25zb2xlTWFwW2ldLmMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBMb2cgYW4gZXJyb3Igc2NlbmFyaW8gdGhhdCB3YXMgbm90IGV4cGVjdGVkIGFuZCBjYXVzZWQgdGhlIHJlcXVlc3RlZCBvcGVyYXRpb24gdG8gZmFpbC4gKi9cbiAgcHVibGljIGVycm9yITogRGlhZ0xvZ0Z1bmN0aW9uO1xuXG4gIC8qKlxuICAgKiBMb2cgYSB3YXJuaW5nIHNjZW5hcmlvIHRvIGluZm9ybSB0aGUgZGV2ZWxvcGVyIG9mIGFuIGlzc3VlcyB0aGF0IHNob3VsZCBiZSBpbnZlc3RpZ2F0ZWQuXG4gICAqIFRoZSByZXF1ZXN0ZWQgb3BlcmF0aW9uIG1heSBvciBtYXkgbm90IGhhdmUgc3VjY2VlZGVkIG9yIGNvbXBsZXRlZC5cbiAgICovXG4gIHB1YmxpYyB3YXJuITogRGlhZ0xvZ0Z1bmN0aW9uO1xuXG4gIC8qKlxuICAgKiBMb2cgYSBnZW5lcmFsIGluZm9ybWF0aW9uYWwgbWVzc2FnZSwgdGhpcyBzaG91bGQgbm90IGFmZmVjdCBmdW5jdGlvbmFsaXR5LlxuICAgKiBUaGlzIGlzIGFsc28gdGhlIGRlZmF1bHQgbG9nZ2luZyBsZXZlbCBzbyB0aGlzIHNob3VsZCBOT1QgYmUgdXNlZCBmb3IgbG9nZ2luZ1xuICAgKiBkZWJ1Z2dpbmcgbGV2ZWwgaW5mb3JtYXRpb24uXG4gICAqL1xuICBwdWJsaWMgaW5mbyE6IERpYWdMb2dGdW5jdGlvbjtcblxuICAvKipcbiAgICogTG9nIGEgZ2VuZXJhbCBkZWJ1ZyBtZXNzYWdlIHRoYXQgY2FuIGJlIHVzZWZ1bCBmb3IgaWRlbnRpZnlpbmcgYSBmYWlsdXJlLlxuICAgKiBJbmZvcm1hdGlvbiBsb2dnZWQgYXQgdGhpcyBsZXZlbCBtYXkgaW5jbHVkZSBkaWFnbm9zdGljIGRldGFpbHMgdGhhdCB3b3VsZFxuICAgKiBoZWxwIGlkZW50aWZ5IGEgZmFpbHVyZSBzY2VuYXJpby4gVXNlZnVsIHNjZW5hcmlvcyB3b3VsZCBiZSB0byBsb2cgdGhlIGV4ZWN1dGlvblxuICAgKiBvcmRlciBvZiBhc3luYyBvcGVyYXRpb25zXG4gICAqL1xuICBwdWJsaWMgZGVidWchOiBEaWFnTG9nRnVuY3Rpb247XG5cbiAgLyoqXG4gICAqIExvZyBhIGRldGFpbGVkICh2ZXJib3NlKSB0cmFjZSBsZXZlbCBsb2dnaW5nIHRoYXQgY2FuIGJlIHVzZWQgdG8gaWRlbnRpZnkgZmFpbHVyZXNcbiAgICogd2hlcmUgZGVidWcgbGV2ZWwgbG9nZ2luZyB3b3VsZCBiZSBpbnN1ZmZpY2llbnQsIHRoaXMgbGV2ZWwgb2YgdHJhY2luZyBjYW4gaW5jbHVkZVxuICAgKiBpbnB1dCBhbmQgb3V0cHV0IHBhcmFtZXRlcnMgYW5kIGFzIHN1Y2ggbWF5IGluY2x1ZGUgUElJIGluZm9ybWF0aW9uIHBhc3NpbmcgdGhyb3VnaFxuICAgKiB0aGUgQVBJLiBBcyBzdWNoIGl0IGlzIHJlY29tbWVuZGVkIHRoYXQgdGhpcyBsZXZlbCBvZiB0cmFjaW5nIHNob3VsZCBub3QgYmUgZW5hYmxlZFxuICAgKiBpbiBhIHByb2R1Y3Rpb24gZW52aXJvbm1lbnQuXG4gICAqL1xuICBwdWJsaWMgdmVyYm9zZSE6IERpYWdMb2dGdW5jdGlvbjtcbn1cbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5pbXBvcnQgeyBNZXRlciB9IGZyb20gJy4vTWV0ZXInO1xuaW1wb3J0IHtcbiAgQmF0Y2hPYnNlcnZhYmxlQ2FsbGJhY2ssXG4gIENvdW50ZXIsXG4gIEdhdWdlLFxuICBIaXN0b2dyYW0sXG4gIE1ldHJpY0F0dHJpYnV0ZXMsXG4gIE1ldHJpY09wdGlvbnMsXG4gIE9ic2VydmFibGUsXG4gIE9ic2VydmFibGVDYWxsYmFjayxcbiAgT2JzZXJ2YWJsZUNvdW50ZXIsXG4gIE9ic2VydmFibGVHYXVnZSxcbiAgT2JzZXJ2YWJsZVVwRG93bkNvdW50ZXIsXG4gIFVwRG93bkNvdW50ZXIsXG59IGZyb20gJy4vTWV0cmljJztcblxuLyoqXG4gKiBOb29wTWV0ZXIgaXMgYSBub29wIGltcGxlbWVudGF0aW9uIG9mIHRoZSB7QGxpbmsgTWV0ZXJ9IGludGVyZmFjZS4gSXQgcmV1c2VzXG4gKiBjb25zdGFudCBOb29wTWV0cmljcyBmb3IgYWxsIG9mIGl0cyBtZXRob2RzLlxuICovXG5leHBvcnQgY2xhc3MgTm9vcE1ldGVyIGltcGxlbWVudHMgTWV0ZXIge1xuICBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgLyoqXG4gICAqIEBzZWUge0BsaW5rIE1ldGVyLmNyZWF0ZUdhdWdlfVxuICAgKi9cbiAgY3JlYXRlR2F1Z2UoX25hbWU6IHN0cmluZywgX29wdGlvbnM/OiBNZXRyaWNPcHRpb25zKTogR2F1Z2Uge1xuICAgIHJldHVybiBOT09QX0dBVUdFX01FVFJJQztcbiAgfVxuXG4gIC8qKlxuICAgKiBAc2VlIHtAbGluayBNZXRlci5jcmVhdGVIaXN0b2dyYW19XG4gICAqL1xuICBjcmVhdGVIaXN0b2dyYW0oX25hbWU6IHN0cmluZywgX29wdGlvbnM/OiBNZXRyaWNPcHRpb25zKTogSGlzdG9ncmFtIHtcbiAgICByZXR1cm4gTk9PUF9ISVNUT0dSQU1fTUVUUklDO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzZWUge0BsaW5rIE1ldGVyLmNyZWF0ZUNvdW50ZXJ9XG4gICAqL1xuICBjcmVhdGVDb3VudGVyKF9uYW1lOiBzdHJpbmcsIF9vcHRpb25zPzogTWV0cmljT3B0aW9ucyk6IENvdW50ZXIge1xuICAgIHJldHVybiBOT09QX0NPVU5URVJfTUVUUklDO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzZWUge0BsaW5rIE1ldGVyLmNyZWF0ZVVwRG93bkNvdW50ZXJ9XG4gICAqL1xuICBjcmVhdGVVcERvd25Db3VudGVyKF9uYW1lOiBzdHJpbmcsIF9vcHRpb25zPzogTWV0cmljT3B0aW9ucyk6IFVwRG93bkNvdW50ZXIge1xuICAgIHJldHVybiBOT09QX1VQX0RPV05fQ09VTlRFUl9NRVRSSUM7XG4gIH1cblxuICAvKipcbiAgICogQHNlZSB7QGxpbmsgTWV0ZXIuY3JlYXRlT2JzZXJ2YWJsZUdhdWdlfVxuICAgKi9cbiAgY3JlYXRlT2JzZXJ2YWJsZUdhdWdlKFxuICAgIF9uYW1lOiBzdHJpbmcsXG4gICAgX29wdGlvbnM/OiBNZXRyaWNPcHRpb25zXG4gICk6IE9ic2VydmFibGVHYXVnZSB7XG4gICAgcmV0dXJuIE5PT1BfT0JTRVJWQUJMRV9HQVVHRV9NRVRSSUM7XG4gIH1cblxuICAvKipcbiAgICogQHNlZSB7QGxpbmsgTWV0ZXIuY3JlYXRlT2JzZXJ2YWJsZUNvdW50ZXJ9XG4gICAqL1xuICBjcmVhdGVPYnNlcnZhYmxlQ291bnRlcihcbiAgICBfbmFtZTogc3RyaW5nLFxuICAgIF9vcHRpb25zPzogTWV0cmljT3B0aW9uc1xuICApOiBPYnNlcnZhYmxlQ291bnRlciB7XG4gICAgcmV0dXJuIE5PT1BfT0JTRVJWQUJMRV9DT1VOVEVSX01FVFJJQztcbiAgfVxuXG4gIC8qKlxuICAgKiBAc2VlIHtAbGluayBNZXRlci5jcmVhdGVPYnNlcnZhYmxlVXBEb3duQ291bnRlcn1cbiAgICovXG4gIGNyZWF0ZU9ic2VydmFibGVVcERvd25Db3VudGVyKFxuICAgIF9uYW1lOiBzdHJpbmcsXG4gICAgX29wdGlvbnM/OiBNZXRyaWNPcHRpb25zXG4gICk6IE9ic2VydmFibGVVcERvd25Db3VudGVyIHtcbiAgICByZXR1cm4gTk9PUF9PQlNFUlZBQkxFX1VQX0RPV05fQ09VTlRFUl9NRVRSSUM7XG4gIH1cblxuICAvKipcbiAgICogQHNlZSB7QGxpbmsgTWV0ZXIuYWRkQmF0Y2hPYnNlcnZhYmxlQ2FsbGJhY2t9XG4gICAqL1xuICBhZGRCYXRjaE9ic2VydmFibGVDYWxsYmFjayhcbiAgICBfY2FsbGJhY2s6IEJhdGNoT2JzZXJ2YWJsZUNhbGxiYWNrLFxuICAgIF9vYnNlcnZhYmxlczogT2JzZXJ2YWJsZVtdXG4gICk6IHZvaWQge31cblxuICAvKipcbiAgICogQHNlZSB7QGxpbmsgTWV0ZXIucmVtb3ZlQmF0Y2hPYnNlcnZhYmxlQ2FsbGJhY2t9XG4gICAqL1xuICByZW1vdmVCYXRjaE9ic2VydmFibGVDYWxsYmFjayhfY2FsbGJhY2s6IEJhdGNoT2JzZXJ2YWJsZUNhbGxiYWNrKTogdm9pZCB7fVxufVxuXG5leHBvcnQgY2xhc3MgTm9vcE1ldHJpYyB7fVxuXG5leHBvcnQgY2xhc3MgTm9vcENvdW50ZXJNZXRyaWMgZXh0ZW5kcyBOb29wTWV0cmljIGltcGxlbWVudHMgQ291bnRlciB7XG4gIGFkZChfdmFsdWU6IG51bWJlciwgX2F0dHJpYnV0ZXM6IE1ldHJpY0F0dHJpYnV0ZXMpOiB2b2lkIHt9XG59XG5cbmV4cG9ydCBjbGFzcyBOb29wVXBEb3duQ291bnRlck1ldHJpY1xuICBleHRlbmRzIE5vb3BNZXRyaWNcbiAgaW1wbGVtZW50cyBVcERvd25Db3VudGVyXG57XG4gIGFkZChfdmFsdWU6IG51bWJlciwgX2F0dHJpYnV0ZXM6IE1ldHJpY0F0dHJpYnV0ZXMpOiB2b2lkIHt9XG59XG5cbmV4cG9ydCBjbGFzcyBOb29wR2F1Z2VNZXRyaWMgZXh0ZW5kcyBOb29wTWV0cmljIGltcGxlbWVudHMgR2F1Z2Uge1xuICByZWNvcmQoX3ZhbHVlOiBudW1iZXIsIF9hdHRyaWJ1dGVzOiBNZXRyaWNBdHRyaWJ1dGVzKTogdm9pZCB7fVxufVxuXG5leHBvcnQgY2xhc3MgTm9vcEhpc3RvZ3JhbU1ldHJpYyBleHRlbmRzIE5vb3BNZXRyaWMgaW1wbGVtZW50cyBIaXN0b2dyYW0ge1xuICByZWNvcmQoX3ZhbHVlOiBudW1iZXIsIF9hdHRyaWJ1dGVzOiBNZXRyaWNBdHRyaWJ1dGVzKTogdm9pZCB7fVxufVxuXG5leHBvcnQgY2xhc3MgTm9vcE9ic2VydmFibGVNZXRyaWMge1xuICBhZGRDYWxsYmFjayhfY2FsbGJhY2s6IE9ic2VydmFibGVDYWxsYmFjaykge31cblxuICByZW1vdmVDYWxsYmFjayhfY2FsbGJhY2s6IE9ic2VydmFibGVDYWxsYmFjaykge31cbn1cblxuZXhwb3J0IGNsYXNzIE5vb3BPYnNlcnZhYmxlQ291bnRlck1ldHJpY1xuICBleHRlbmRzIE5vb3BPYnNlcnZhYmxlTWV0cmljXG4gIGltcGxlbWVudHMgT2JzZXJ2YWJsZUNvdW50ZXIge31cblxuZXhwb3J0IGNsYXNzIE5vb3BPYnNlcnZhYmxlR2F1Z2VNZXRyaWNcbiAgZXh0ZW5kcyBOb29wT2JzZXJ2YWJsZU1ldHJpY1xuICBpbXBsZW1lbnRzIE9ic2VydmFibGVHYXVnZSB7fVxuXG5leHBvcnQgY2xhc3MgTm9vcE9ic2VydmFibGVVcERvd25Db3VudGVyTWV0cmljXG4gIGV4dGVuZHMgTm9vcE9ic2VydmFibGVNZXRyaWNcbiAgaW1wbGVtZW50cyBPYnNlcnZhYmxlVXBEb3duQ291bnRlciB7fVxuXG5leHBvcnQgY29uc3QgTk9PUF9NRVRFUiA9IG5ldyBOb29wTWV0ZXIoKTtcblxuLy8gU3luY2hyb25vdXMgaW5zdHJ1bWVudHNcbmV4cG9ydCBjb25zdCBOT09QX0NPVU5URVJfTUVUUklDID0gbmV3IE5vb3BDb3VudGVyTWV0cmljKCk7XG5leHBvcnQgY29uc3QgTk9PUF9HQVVHRV9NRVRSSUMgPSBuZXcgTm9vcEdhdWdlTWV0cmljKCk7XG5leHBvcnQgY29uc3QgTk9PUF9ISVNUT0dSQU1fTUVUUklDID0gbmV3IE5vb3BIaXN0b2dyYW1NZXRyaWMoKTtcbmV4cG9ydCBjb25zdCBOT09QX1VQX0RPV05fQ09VTlRFUl9NRVRSSUMgPSBuZXcgTm9vcFVwRG93bkNvdW50ZXJNZXRyaWMoKTtcblxuLy8gQXN5bmNocm9ub3VzIGluc3RydW1lbnRzXG5leHBvcnQgY29uc3QgTk9PUF9PQlNFUlZBQkxFX0NPVU5URVJfTUVUUklDID0gbmV3IE5vb3BPYnNlcnZhYmxlQ291bnRlck1ldHJpYygpO1xuZXhwb3J0IGNvbnN0IE5PT1BfT0JTRVJWQUJMRV9HQVVHRV9NRVRSSUMgPSBuZXcgTm9vcE9ic2VydmFibGVHYXVnZU1ldHJpYygpO1xuZXhwb3J0IGNvbnN0IE5PT1BfT0JTRVJWQUJMRV9VUF9ET1dOX0NPVU5URVJfTUVUUklDID1cbiAgbmV3IE5vb3BPYnNlcnZhYmxlVXBEb3duQ291bnRlck1ldHJpYygpO1xuXG4vKipcbiAqIENyZWF0ZSBhIG5vLW9wIE1ldGVyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVOb29wTWV0ZXIoKTogTWV0ZXIge1xuICByZXR1cm4gTk9PUF9NRVRFUjtcbn1cbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5pbXBvcnQgeyBBdHRyaWJ1dGVzLCBBdHRyaWJ1dGVWYWx1ZSB9IGZyb20gJy4uL2NvbW1vbi9BdHRyaWJ1dGVzJztcbmltcG9ydCB7IENvbnRleHQgfSBmcm9tICcuLi9jb250ZXh0L3R5cGVzJztcbmltcG9ydCB7IEJhdGNoT2JzZXJ2YWJsZVJlc3VsdCwgT2JzZXJ2YWJsZVJlc3VsdCB9IGZyb20gJy4vT2JzZXJ2YWJsZVJlc3VsdCc7XG5cbi8qKlxuICogQWR2aXNvcnkgb3B0aW9ucyBpbmZsdWVuY2luZyBhZ2dyZWdhdGlvbiBjb25maWd1cmF0aW9uIHBhcmFtZXRlcnMuXG4gKiBAZXhwZXJpbWVudGFsXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWV0cmljQWR2aWNlIHtcbiAgLyoqXG4gICAqIEhpbnQgdGhlIGV4cGxpY2l0IGJ1Y2tldCBib3VuZGFyaWVzIGZvciBTREsgaWYgdGhlIG1ldHJpYyBpcyBiZWVuXG4gICAqIGFnZ3JlZ2F0ZWQgd2l0aCBhIEhpc3RvZ3JhbUFnZ3JlZ2F0b3IuXG4gICAqL1xuICBleHBsaWNpdEJ1Y2tldEJvdW5kYXJpZXM/OiBudW1iZXJbXTtcbn1cblxuLyoqXG4gKiBPcHRpb25zIG5lZWRlZCBmb3IgbWV0cmljIGNyZWF0aW9uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWV0cmljT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgZGVzY3JpcHRpb24gb2YgdGhlIE1ldHJpYy5cbiAgICogQGRlZmF1bHQgJydcbiAgICovXG4gIGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgdW5pdCBvZiB0aGUgTWV0cmljIHZhbHVlcy5cbiAgICogQGRlZmF1bHQgJydcbiAgICovXG4gIHVuaXQ/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyB0aGUgdHlwZSBvZiB0aGUgcmVjb3JkZWQgdmFsdWUuXG4gICAqIEBkZWZhdWx0IHtAbGluayBWYWx1ZVR5cGUuRE9VQkxFfVxuICAgKi9cbiAgdmFsdWVUeXBlPzogVmFsdWVUeXBlO1xuXG4gIC8qKlxuICAgKiBUaGUgYWR2aWNlIGluZmx1ZW5jaW5nIGFnZ3JlZ2F0aW9uIGNvbmZpZ3VyYXRpb24gcGFyYW1ldGVycy5cbiAgICogQGV4cGVyaW1lbnRhbFxuICAgKi9cbiAgYWR2aWNlPzogTWV0cmljQWR2aWNlO1xufVxuXG4vKiogVGhlIFR5cGUgb2YgdmFsdWUuIEl0IGRlc2NyaWJlcyBob3cgdGhlIGRhdGEgaXMgcmVwb3J0ZWQuICovXG5leHBvcnQgZW51bSBWYWx1ZVR5cGUge1xuICBJTlQsXG4gIERPVUJMRSxcbn1cblxuLyoqXG4gKiBDb3VudGVyIGlzIHRoZSBtb3N0IGNvbW1vbiBzeW5jaHJvbm91cyBpbnN0cnVtZW50LiBUaGlzIGluc3RydW1lbnQgc3VwcG9ydHNcbiAqIGFuIGBBZGQoaW5jcmVtZW50KWAgZnVuY3Rpb24gZm9yIHJlcG9ydGluZyBhIHN1bSwgYW5kIGlzIHJlc3RyaWN0ZWQgdG9cbiAqIG5vbi1uZWdhdGl2ZSBpbmNyZW1lbnRzLiBUaGUgZGVmYXVsdCBhZ2dyZWdhdGlvbiBpcyBTdW0sIGFzIGZvciBhbnkgYWRkaXRpdmVcbiAqIGluc3RydW1lbnQuXG4gKlxuICogRXhhbXBsZSB1c2VzIGZvciBDb3VudGVyOlxuICogPG9sPlxuICogICA8bGk+IGNvdW50IHRoZSBudW1iZXIgb2YgYnl0ZXMgcmVjZWl2ZWQuIDwvbGk+XG4gKiAgIDxsaT4gY291bnQgdGhlIG51bWJlciBvZiByZXF1ZXN0cyBjb21wbGV0ZWQuIDwvbGk+XG4gKiAgIDxsaT4gY291bnQgdGhlIG51bWJlciBvZiBhY2NvdW50cyBjcmVhdGVkLiA8L2xpPlxuICogICA8bGk+IGNvdW50IHRoZSBudW1iZXIgb2YgY2hlY2twb2ludHMgcnVuLiA8L2xpPlxuICogICA8bGk+IGNvdW50IHRoZSBudW1iZXIgb2YgNXh4IGVycm9ycy4gPC9saT5cbiAqIDxvbD5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDb3VudGVyPFxuICBBdHRyaWJ1dGVzVHlwZXMgZXh0ZW5kcyBNZXRyaWNBdHRyaWJ1dGVzID0gTWV0cmljQXR0cmlidXRlcyxcbj4ge1xuICAvKipcbiAgICogSW5jcmVtZW50IHZhbHVlIG9mIGNvdW50ZXIgYnkgdGhlIGlucHV0LiBJbnB1dHMgbXVzdCBub3QgYmUgbmVnYXRpdmUuXG4gICAqL1xuICBhZGQodmFsdWU6IG51bWJlciwgYXR0cmlidXRlcz86IEF0dHJpYnV0ZXNUeXBlcywgY29udGV4dD86IENvbnRleHQpOiB2b2lkO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFVwRG93bkNvdW50ZXI8XG4gIEF0dHJpYnV0ZXNUeXBlcyBleHRlbmRzIE1ldHJpY0F0dHJpYnV0ZXMgPSBNZXRyaWNBdHRyaWJ1dGVzLFxuPiB7XG4gIC8qKlxuICAgKiBJbmNyZW1lbnQgdmFsdWUgb2YgY291bnRlciBieSB0aGUgaW5wdXQuIElucHV0cyBtYXkgYmUgbmVnYXRpdmUuXG4gICAqL1xuICBhZGQodmFsdWU6IG51bWJlciwgYXR0cmlidXRlcz86IEF0dHJpYnV0ZXNUeXBlcywgY29udGV4dD86IENvbnRleHQpOiB2b2lkO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEdhdWdlPFxuICBBdHRyaWJ1dGVzVHlwZXMgZXh0ZW5kcyBNZXRyaWNBdHRyaWJ1dGVzID0gTWV0cmljQXR0cmlidXRlcyxcbj4ge1xuICAvKipcbiAgICogUmVjb3JkcyBhIG1lYXN1cmVtZW50LlxuICAgKi9cbiAgcmVjb3JkKHZhbHVlOiBudW1iZXIsIGF0dHJpYnV0ZXM/OiBBdHRyaWJ1dGVzVHlwZXMsIGNvbnRleHQ/OiBDb250ZXh0KTogdm9pZDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBIaXN0b2dyYW08XG4gIEF0dHJpYnV0ZXNUeXBlcyBleHRlbmRzIE1ldHJpY0F0dHJpYnV0ZXMgPSBNZXRyaWNBdHRyaWJ1dGVzLFxuPiB7XG4gIC8qKlxuICAgKiBSZWNvcmRzIGEgbWVhc3VyZW1lbnQuIFZhbHVlIG9mIHRoZSBtZWFzdXJlbWVudCBtdXN0IG5vdCBiZSBuZWdhdGl2ZS5cbiAgICovXG4gIHJlY29yZCh2YWx1ZTogbnVtYmVyLCBhdHRyaWJ1dGVzPzogQXR0cmlidXRlc1R5cGVzLCBjb250ZXh0PzogQ29udGV4dCk6IHZvaWQ7XG59XG5cbi8qKlxuICogQGRlcHJlY2F0ZWQgcGxlYXNlIHVzZSB7QGxpbmsgQXR0cmlidXRlc31cbiAqL1xuZXhwb3J0IHR5cGUgTWV0cmljQXR0cmlidXRlcyA9IEF0dHJpYnV0ZXM7XG5cbi8qKlxuICogQGRlcHJlY2F0ZWQgcGxlYXNlIHVzZSB7QGxpbmsgQXR0cmlidXRlVmFsdWV9XG4gKi9cbmV4cG9ydCB0eXBlIE1ldHJpY0F0dHJpYnV0ZVZhbHVlID0gQXR0cmlidXRlVmFsdWU7XG5cbi8qKlxuICogVGhlIG9ic2VydmFibGUgY2FsbGJhY2sgZm9yIE9ic2VydmFibGUgaW5zdHJ1bWVudHMuXG4gKi9cbmV4cG9ydCB0eXBlIE9ic2VydmFibGVDYWxsYmFjazxcbiAgQXR0cmlidXRlc1R5cGVzIGV4dGVuZHMgTWV0cmljQXR0cmlidXRlcyA9IE1ldHJpY0F0dHJpYnV0ZXMsXG4+ID0gKFxuICBvYnNlcnZhYmxlUmVzdWx0OiBPYnNlcnZhYmxlUmVzdWx0PEF0dHJpYnV0ZXNUeXBlcz5cbikgPT4gdm9pZCB8IFByb21pc2U8dm9pZD47XG5cbi8qKlxuICogVGhlIG9ic2VydmFibGUgY2FsbGJhY2sgZm9yIGEgYmF0Y2ggb2YgT2JzZXJ2YWJsZSBpbnN0cnVtZW50cy5cbiAqL1xuZXhwb3J0IHR5cGUgQmF0Y2hPYnNlcnZhYmxlQ2FsbGJhY2s8XG4gIEF0dHJpYnV0ZXNUeXBlcyBleHRlbmRzIE1ldHJpY0F0dHJpYnV0ZXMgPSBNZXRyaWNBdHRyaWJ1dGVzLFxuPiA9IChcbiAgb2JzZXJ2YWJsZVJlc3VsdDogQmF0Y2hPYnNlcnZhYmxlUmVzdWx0PEF0dHJpYnV0ZXNUeXBlcz5cbikgPT4gdm9pZCB8IFByb21pc2U8dm9pZD47XG5cbmV4cG9ydCBpbnRlcmZhY2UgT2JzZXJ2YWJsZTxcbiAgQXR0cmlidXRlc1R5cGVzIGV4dGVuZHMgTWV0cmljQXR0cmlidXRlcyA9IE1ldHJpY0F0dHJpYnV0ZXMsXG4+IHtcbiAgLyoqXG4gICAqIFNldHMgdXAgYSBmdW5jdGlvbiB0aGF0IHdpbGwgYmUgY2FsbGVkIHdoZW5ldmVyIGEgbWV0cmljIGNvbGxlY3Rpb24gaXMgaW5pdGlhdGVkLlxuICAgKlxuICAgKiBJZiB0aGUgZnVuY3Rpb24gaXMgYWxyZWFkeSBpbiB0aGUgbGlzdCBvZiBjYWxsYmFja3MgZm9yIHRoaXMgT2JzZXJ2YWJsZSwgdGhlIGZ1bmN0aW9uIGlzIG5vdCBhZGRlZCBhIHNlY29uZCB0aW1lLlxuICAgKi9cbiAgYWRkQ2FsbGJhY2soY2FsbGJhY2s6IE9ic2VydmFibGVDYWxsYmFjazxBdHRyaWJ1dGVzVHlwZXM+KTogdm9pZDtcblxuICAvKipcbiAgICogUmVtb3ZlcyBhIGNhbGxiYWNrIHByZXZpb3VzbHkgcmVnaXN0ZXJlZCB3aXRoIHtAbGluayBPYnNlcnZhYmxlLmFkZENhbGxiYWNrfS5cbiAgICovXG4gIHJlbW92ZUNhbGxiYWNrKGNhbGxiYWNrOiBPYnNlcnZhYmxlQ2FsbGJhY2s8QXR0cmlidXRlc1R5cGVzPik6IHZvaWQ7XG59XG5cbmV4cG9ydCB0eXBlIE9ic2VydmFibGVDb3VudGVyPFxuICBBdHRyaWJ1dGVzVHlwZXMgZXh0ZW5kcyBNZXRyaWNBdHRyaWJ1dGVzID0gTWV0cmljQXR0cmlidXRlcyxcbj4gPSBPYnNlcnZhYmxlPEF0dHJpYnV0ZXNUeXBlcz47XG5leHBvcnQgdHlwZSBPYnNlcnZhYmxlVXBEb3duQ291bnRlcjxcbiAgQXR0cmlidXRlc1R5cGVzIGV4dGVuZHMgTWV0cmljQXR0cmlidXRlcyA9IE1ldHJpY0F0dHJpYnV0ZXMsXG4+ID0gT2JzZXJ2YWJsZTxBdHRyaWJ1dGVzVHlwZXM+O1xuZXhwb3J0IHR5cGUgT2JzZXJ2YWJsZUdhdWdlPFxuICBBdHRyaWJ1dGVzVHlwZXMgZXh0ZW5kcyBNZXRyaWNBdHRyaWJ1dGVzID0gTWV0cmljQXR0cmlidXRlcyxcbj4gPSBPYnNlcnZhYmxlPEF0dHJpYnV0ZXNUeXBlcz47XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuaW1wb3J0IHsgQ29udGV4dCB9IGZyb20gJy4uL2NvbnRleHQvdHlwZXMnO1xuXG4vKipcbiAqIEluamVjdHMgYENvbnRleHRgIGludG8gYW5kIGV4dHJhY3RzIGl0IGZyb20gY2FycmllcnMgdGhhdCB0cmF2ZWxcbiAqIGluLWJhbmQgYWNyb3NzIHByb2Nlc3MgYm91bmRhcmllcy4gRW5jb2RpbmcgaXMgZXhwZWN0ZWQgdG8gY29uZm9ybSB0byB0aGVcbiAqIEhUVFAgSGVhZGVyIEZpZWxkIHNlbWFudGljcy4gVmFsdWVzIGFyZSBvZnRlbiBlbmNvZGVkIGFzIFJQQy9IVFRQIHJlcXVlc3RcbiAqIGhlYWRlcnMuXG4gKlxuICogVGhlIGNhcnJpZXIgb2YgcHJvcGFnYXRlZCBkYXRhIG9uIGJvdGggdGhlIGNsaWVudCAoaW5qZWN0b3IpIGFuZCBzZXJ2ZXJcbiAqIChleHRyYWN0b3IpIHNpZGUgaXMgdXN1YWxseSBhbiBvYmplY3Qgc3VjaCBhcyBodHRwIGhlYWRlcnMuIFByb3BhZ2F0aW9uIGlzXG4gKiB1c3VhbGx5IGltcGxlbWVudGVkIHZpYSBsaWJyYXJ5LXNwZWNpZmljIHJlcXVlc3QgaW50ZXJjZXB0b3JzLCB3aGVyZSB0aGVcbiAqIGNsaWVudC1zaWRlIGluamVjdHMgdmFsdWVzIGFuZCB0aGUgc2VydmVyLXNpZGUgZXh0cmFjdHMgdGhlbS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBUZXh0TWFwUHJvcGFnYXRvcjxDYXJyaWVyID0gYW55PiB7XG4gIC8qKlxuICAgKiBJbmplY3RzIHZhbHVlcyBmcm9tIGEgZ2l2ZW4gYENvbnRleHRgIGludG8gYSBjYXJyaWVyLlxuICAgKlxuICAgKiBPcGVuVGVsZW1ldHJ5IGRlZmluZXMgYSBjb21tb24gc2V0IG9mIGZvcm1hdCB2YWx1ZXMgKFRleHRNYXBQcm9wYWdhdG9yKSxcbiAgICogYW5kIGVhY2ggaGFzIGFuIGV4cGVjdGVkIGBjYXJyaWVyYCB0eXBlLlxuICAgKlxuICAgKiBAcGFyYW0gY29udGV4dCB0aGUgQ29udGV4dCBmcm9tIHdoaWNoIHRvIGV4dHJhY3QgdmFsdWVzIHRvIHRyYW5zbWl0IG92ZXJcbiAgICogICAgIHRoZSB3aXJlLlxuICAgKiBAcGFyYW0gY2FycmllciB0aGUgY2FycmllciBvZiBwcm9wYWdhdGlvbiBmaWVsZHMsIHN1Y2ggYXMgaHR0cCByZXF1ZXN0XG4gICAqICAgICBoZWFkZXJzLlxuICAgKiBAcGFyYW0gc2V0dGVyIGFuIG9wdGlvbmFsIHtAbGluayBUZXh0TWFwU2V0dGVyfS4gSWYgdW5kZWZpbmVkLCB2YWx1ZXMgd2lsbCBiZVxuICAgKiAgICAgc2V0IGJ5IGRpcmVjdCBvYmplY3QgYXNzaWdubWVudC5cbiAgICovXG4gIGluamVjdChcbiAgICBjb250ZXh0OiBDb250ZXh0LFxuICAgIGNhcnJpZXI6IENhcnJpZXIsXG4gICAgc2V0dGVyOiBUZXh0TWFwU2V0dGVyPENhcnJpZXI+XG4gICk6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIEdpdmVuIGEgYENvbnRleHRgIGFuZCBhIGNhcnJpZXIsIGV4dHJhY3QgY29udGV4dCB2YWx1ZXMgZnJvbSBhXG4gICAqIGNhcnJpZXIgYW5kIHJldHVybiBhIG5ldyBjb250ZXh0LCBjcmVhdGVkIGZyb20gdGhlIG9sZCBjb250ZXh0LCB3aXRoIHRoZVxuICAgKiBleHRyYWN0ZWQgdmFsdWVzLlxuICAgKlxuICAgKiBAcGFyYW0gY29udGV4dCB0aGUgQ29udGV4dCBmcm9tIHdoaWNoIHRvIGV4dHJhY3QgdmFsdWVzIHRvIHRyYW5zbWl0IG92ZXJcbiAgICogICAgIHRoZSB3aXJlLlxuICAgKiBAcGFyYW0gY2FycmllciB0aGUgY2FycmllciBvZiBwcm9wYWdhdGlvbiBmaWVsZHMsIHN1Y2ggYXMgaHR0cCByZXF1ZXN0XG4gICAqICAgICBoZWFkZXJzLlxuICAgKiBAcGFyYW0gZ2V0dGVyIGFuIG9wdGlvbmFsIHtAbGluayBUZXh0TWFwR2V0dGVyfS4gSWYgdW5kZWZpbmVkLCBrZXlzIHdpbGwgYmUgYWxsXG4gICAqICAgICBvd24gcHJvcGVydGllcywgYW5kIGtleXMgd2lsbCBiZSBhY2Nlc3NlZCBieSBkaXJlY3Qgb2JqZWN0IGFjY2Vzcy5cbiAgICovXG4gIGV4dHJhY3QoXG4gICAgY29udGV4dDogQ29udGV4dCxcbiAgICBjYXJyaWVyOiBDYXJyaWVyLFxuICAgIGdldHRlcjogVGV4dE1hcEdldHRlcjxDYXJyaWVyPlxuICApOiBDb250ZXh0O1xuXG4gIC8qKlxuICAgKiBSZXR1cm4gYSBsaXN0IG9mIGFsbCBmaWVsZHMgd2hpY2ggbWF5IGJlIHVzZWQgYnkgdGhlIHByb3BhZ2F0b3IuXG4gICAqL1xuICBmaWVsZHMoKTogc3RyaW5nW107XG59XG5cbi8qKlxuICogQSBzZXR0ZXIgaXMgc3BlY2lmaWVkIGJ5IHRoZSBjYWxsZXIgdG8gZGVmaW5lIGEgc3BlY2lmaWMgbWV0aG9kXG4gKiB0byBzZXQga2V5L3ZhbHVlIHBhaXJzIG9uIHRoZSBjYXJyaWVyIHdpdGhpbiBhIHByb3BhZ2F0b3IuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGV4dE1hcFNldHRlcjxDYXJyaWVyID0gYW55PiB7XG4gIC8qKlxuICAgKiBDYWxsYmFjayB1c2VkIHRvIHNldCBhIGtleS92YWx1ZSBwYWlyIG9uIGFuIG9iamVjdC5cbiAgICpcbiAgICogU2hvdWxkIGJlIGNhbGxlZCBieSB0aGUgcHJvcGFnYXRvciBlYWNoIHRpbWUgYSBrZXkvdmFsdWUgcGFpclxuICAgKiBzaG91bGQgYmUgc2V0LCBhbmQgc2hvdWxkIHNldCB0aGF0IGtleS92YWx1ZSBwYWlyIG9uIHRoZSBwcm9wYWdhdG9yLlxuICAgKlxuICAgKiBAcGFyYW0gY2FycmllciBvYmplY3Qgb3IgY2xhc3Mgd2hpY2ggY2FycmllcyBrZXkvdmFsdWUgcGFpcnNcbiAgICogQHBhcmFtIGtleSBzdHJpbmcga2V5IHRvIG1vZGlmeVxuICAgKiBAcGFyYW0gdmFsdWUgdmFsdWUgdG8gYmUgc2V0IHRvIHRoZSBrZXkgb24gdGhlIGNhcnJpZXJcbiAgICovXG4gIHNldChjYXJyaWVyOiBDYXJyaWVyLCBrZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZyk6IHZvaWQ7XG59XG5cbi8qKlxuICogQSBnZXR0ZXIgaXMgc3BlY2lmaWVkIGJ5IHRoZSBjYWxsZXIgdG8gZGVmaW5lIGEgc3BlY2lmaWMgbWV0aG9kXG4gKiB0byBnZXQgdGhlIHZhbHVlIG9mIGEga2V5IGZyb20gYSBjYXJyaWVyLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRleHRNYXBHZXR0ZXI8Q2FycmllciA9IGFueT4ge1xuICAvKipcbiAgICogR2V0IGEgbGlzdCBvZiBhbGwga2V5cyBhdmFpbGFibGUgb24gdGhlIGNhcnJpZXIuXG4gICAqXG4gICAqIEBwYXJhbSBjYXJyaWVyXG4gICAqL1xuICBrZXlzKGNhcnJpZXI6IENhcnJpZXIpOiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogR2V0IHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmljIGtleSBmcm9tIHRoZSBjYXJyaWVyLlxuICAgKlxuICAgKiBAcGFyYW0gY2FycmllclxuICAgKiBAcGFyYW0ga2V5XG4gICAqL1xuICBnZXQoY2FycmllcjogQ2Fycmllciwga2V5OiBzdHJpbmcpOiB1bmRlZmluZWQgfCBzdHJpbmcgfCBzdHJpbmdbXTtcbn1cblxuZXhwb3J0IGNvbnN0IGRlZmF1bHRUZXh0TWFwR2V0dGVyOiBUZXh0TWFwR2V0dGVyID0ge1xuICBnZXQoY2Fycmllciwga2V5KSB7XG4gICAgaWYgKGNhcnJpZXIgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcmV0dXJuIGNhcnJpZXJba2V5XTtcbiAgfSxcblxuICBrZXlzKGNhcnJpZXIpIHtcbiAgICBpZiAoY2FycmllciA9PSBudWxsKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIHJldHVybiBPYmplY3Qua2V5cyhjYXJyaWVyKTtcbiAgfSxcbn07XG5cbmV4cG9ydCBjb25zdCBkZWZhdWx0VGV4dE1hcFNldHRlcjogVGV4dE1hcFNldHRlciA9IHtcbiAgc2V0KGNhcnJpZXIsIGtleSwgdmFsdWUpIHtcbiAgICBpZiAoY2FycmllciA9PSBudWxsKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY2FycmllcltrZXldID0gdmFsdWU7XG4gIH0sXG59O1xuIiwgIi8qXG4gKiBDb3B5cmlnaHQgVGhlIE9wZW5UZWxlbWV0cnkgQXV0aG9yc1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgIGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IFJPT1RfQ09OVEVYVCB9IGZyb20gJy4vY29udGV4dCc7XG5pbXBvcnQgKiBhcyB0eXBlcyBmcm9tICcuL3R5cGVzJztcblxuZXhwb3J0IGNsYXNzIE5vb3BDb250ZXh0TWFuYWdlciBpbXBsZW1lbnRzIHR5cGVzLkNvbnRleHRNYW5hZ2VyIHtcbiAgYWN0aXZlKCk6IHR5cGVzLkNvbnRleHQge1xuICAgIHJldHVybiBST09UX0NPTlRFWFQ7XG4gIH1cblxuICB3aXRoPEEgZXh0ZW5kcyB1bmtub3duW10sIEYgZXh0ZW5kcyAoLi4uYXJnczogQSkgPT4gUmV0dXJuVHlwZTxGPj4oXG4gICAgX2NvbnRleHQ6IHR5cGVzLkNvbnRleHQsXG4gICAgZm46IEYsXG4gICAgdGhpc0FyZz86IFRoaXNQYXJhbWV0ZXJUeXBlPEY+LFxuICAgIC4uLmFyZ3M6IEFcbiAgKTogUmV0dXJuVHlwZTxGPiB7XG4gICAgcmV0dXJuIGZuLmNhbGwodGhpc0FyZywgLi4uYXJncyk7XG4gIH1cblxuICBiaW5kPFQ+KF9jb250ZXh0OiB0eXBlcy5Db250ZXh0LCB0YXJnZXQ6IFQpOiBUIHtcbiAgICByZXR1cm4gdGFyZ2V0O1xuICB9XG5cbiAgZW5hYmxlKCk6IHRoaXMge1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgZGlzYWJsZSgpOiB0aGlzIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxufVxuIiwgIi8qXG4gKiBDb3B5cmlnaHQgVGhlIE9wZW5UZWxlbWV0cnkgQXV0aG9yc1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgIGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IE5vb3BDb250ZXh0TWFuYWdlciB9IGZyb20gJy4uL2NvbnRleHQvTm9vcENvbnRleHRNYW5hZ2VyJztcbmltcG9ydCB7IENvbnRleHQsIENvbnRleHRNYW5hZ2VyIH0gZnJvbSAnLi4vY29udGV4dC90eXBlcyc7XG5pbXBvcnQge1xuICBnZXRHbG9iYWwsXG4gIHJlZ2lzdGVyR2xvYmFsLFxuICB1bnJlZ2lzdGVyR2xvYmFsLFxufSBmcm9tICcuLi9pbnRlcm5hbC9nbG9iYWwtdXRpbHMnO1xuaW1wb3J0IHsgRGlhZ0FQSSB9IGZyb20gJy4vZGlhZyc7XG5cbmNvbnN0IEFQSV9OQU1FID0gJ2NvbnRleHQnO1xuY29uc3QgTk9PUF9DT05URVhUX01BTkFHRVIgPSBuZXcgTm9vcENvbnRleHRNYW5hZ2VyKCk7XG5cbi8qKlxuICogU2luZ2xldG9uIG9iamVjdCB3aGljaCByZXByZXNlbnRzIHRoZSBlbnRyeSBwb2ludCB0byB0aGUgT3BlblRlbGVtZXRyeSBDb250ZXh0IEFQSVxuICovXG5leHBvcnQgY2xhc3MgQ29udGV4dEFQSSB7XG4gIHByaXZhdGUgc3RhdGljIF9pbnN0YW5jZT86IENvbnRleHRBUEk7XG5cbiAgLyoqIEVtcHR5IHByaXZhdGUgY29uc3RydWN0b3IgcHJldmVudHMgZW5kIHVzZXJzIGZyb20gY29uc3RydWN0aW5nIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBBUEkgKi9cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgLyoqIEdldCB0aGUgc2luZ2xldG9uIGluc3RhbmNlIG9mIHRoZSBDb250ZXh0IEFQSSAqL1xuICBwdWJsaWMgc3RhdGljIGdldEluc3RhbmNlKCk6IENvbnRleHRBUEkge1xuICAgIGlmICghdGhpcy5faW5zdGFuY2UpIHtcbiAgICAgIHRoaXMuX2luc3RhbmNlID0gbmV3IENvbnRleHRBUEkoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5faW5zdGFuY2U7XG4gIH1cblxuICAvKipcbiAgICogU2V0IHRoZSBjdXJyZW50IGNvbnRleHQgbWFuYWdlci5cbiAgICpcbiAgICogQHJldHVybnMgdHJ1ZSBpZiB0aGUgY29udGV4dCBtYW5hZ2VyIHdhcyBzdWNjZXNzZnVsbHkgcmVnaXN0ZXJlZCwgZWxzZSBmYWxzZVxuICAgKi9cbiAgcHVibGljIHNldEdsb2JhbENvbnRleHRNYW5hZ2VyKGNvbnRleHRNYW5hZ2VyOiBDb250ZXh0TWFuYWdlcik6IGJvb2xlYW4ge1xuICAgIHJldHVybiByZWdpc3Rlckdsb2JhbChBUElfTkFNRSwgY29udGV4dE1hbmFnZXIsIERpYWdBUEkuaW5zdGFuY2UoKSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBjdXJyZW50bHkgYWN0aXZlIGNvbnRleHRcbiAgICovXG4gIHB1YmxpYyBhY3RpdmUoKTogQ29udGV4dCB7XG4gICAgcmV0dXJuIHRoaXMuX2dldENvbnRleHRNYW5hZ2VyKCkuYWN0aXZlKCk7XG4gIH1cblxuICAvKipcbiAgICogRXhlY3V0ZSBhIGZ1bmN0aW9uIHdpdGggYW4gYWN0aXZlIGNvbnRleHRcbiAgICpcbiAgICogQHBhcmFtIGNvbnRleHQgY29udGV4dCB0byBiZSBhY3RpdmUgZHVyaW5nIGZ1bmN0aW9uIGV4ZWN1dGlvblxuICAgKiBAcGFyYW0gZm4gZnVuY3Rpb24gdG8gZXhlY3V0ZSBpbiBhIGNvbnRleHRcbiAgICogQHBhcmFtIHRoaXNBcmcgb3B0aW9uYWwgcmVjZWl2ZXIgdG8gYmUgdXNlZCBmb3IgY2FsbGluZyBmblxuICAgKiBAcGFyYW0gYXJncyBvcHRpb25hbCBhcmd1bWVudHMgZm9yd2FyZGVkIHRvIGZuXG4gICAqL1xuICBwdWJsaWMgd2l0aDxBIGV4dGVuZHMgdW5rbm93bltdLCBGIGV4dGVuZHMgKC4uLmFyZ3M6IEEpID0+IFJldHVyblR5cGU8Rj4+KFxuICAgIGNvbnRleHQ6IENvbnRleHQsXG4gICAgZm46IEYsXG4gICAgdGhpc0FyZz86IFRoaXNQYXJhbWV0ZXJUeXBlPEY+LFxuICAgIC4uLmFyZ3M6IEFcbiAgKTogUmV0dXJuVHlwZTxGPiB7XG4gICAgcmV0dXJuIHRoaXMuX2dldENvbnRleHRNYW5hZ2VyKCkud2l0aChjb250ZXh0LCBmbiwgdGhpc0FyZywgLi4uYXJncyk7XG4gIH1cblxuICAvKipcbiAgICogQmluZCBhIGNvbnRleHQgdG8gYSB0YXJnZXQgZnVuY3Rpb24gb3IgZXZlbnQgZW1pdHRlclxuICAgKlxuICAgKiBAcGFyYW0gY29udGV4dCBjb250ZXh0IHRvIGJpbmQgdG8gdGhlIGV2ZW50IGVtaXR0ZXIgb3IgZnVuY3Rpb24uIERlZmF1bHRzIHRvIHRoZSBjdXJyZW50bHkgYWN0aXZlIGNvbnRleHRcbiAgICogQHBhcmFtIHRhcmdldCBmdW5jdGlvbiBvciBldmVudCBlbWl0dGVyIHRvIGJpbmRcbiAgICovXG4gIHB1YmxpYyBiaW5kPFQ+KGNvbnRleHQ6IENvbnRleHQsIHRhcmdldDogVCk6IFQge1xuICAgIHJldHVybiB0aGlzLl9nZXRDb250ZXh0TWFuYWdlcigpLmJpbmQoY29udGV4dCwgdGFyZ2V0KTtcbiAgfVxuXG4gIHByaXZhdGUgX2dldENvbnRleHRNYW5hZ2VyKCk6IENvbnRleHRNYW5hZ2VyIHtcbiAgICByZXR1cm4gZ2V0R2xvYmFsKEFQSV9OQU1FKSB8fCBOT09QX0NPTlRFWFRfTUFOQUdFUjtcbiAgfVxuXG4gIC8qKiBEaXNhYmxlIGFuZCByZW1vdmUgdGhlIGdsb2JhbCBjb250ZXh0IG1hbmFnZXIgKi9cbiAgcHVibGljIGRpc2FibGUoKSB7XG4gICAgdGhpcy5fZ2V0Q29udGV4dE1hbmFnZXIoKS5kaXNhYmxlKCk7XG4gICAgdW5yZWdpc3Rlckdsb2JhbChBUElfTkFNRSwgRGlhZ0FQSS5pbnN0YW5jZSgpKTtcbiAgfVxufVxuIiwgIi8qXG4gKiBDb3B5cmlnaHQgVGhlIE9wZW5UZWxlbWV0cnkgQXV0aG9yc1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgIGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5leHBvcnQgZW51bSBUcmFjZUZsYWdzIHtcbiAgLyoqIFJlcHJlc2VudHMgbm8gZmxhZyBzZXQuICovXG4gIE5PTkUgPSAweDAsXG4gIC8qKiBCaXQgdG8gcmVwcmVzZW50IHdoZXRoZXIgdHJhY2UgaXMgc2FtcGxlZCBpbiB0cmFjZSBmbGFncy4gKi9cbiAgU0FNUExFRCA9IDB4MSA8PCAwLFxufVxuIiwgIi8qXG4gKiBDb3B5cmlnaHQgVGhlIE9wZW5UZWxlbWV0cnkgQXV0aG9yc1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgIGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IFNwYW5Db250ZXh0IH0gZnJvbSAnLi9zcGFuX2NvbnRleHQnO1xuaW1wb3J0IHsgVHJhY2VGbGFncyB9IGZyb20gJy4vdHJhY2VfZmxhZ3MnO1xuXG5leHBvcnQgY29uc3QgSU5WQUxJRF9TUEFOSUQgPSAnMDAwMDAwMDAwMDAwMDAwMCc7XG5leHBvcnQgY29uc3QgSU5WQUxJRF9UUkFDRUlEID0gJzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwJztcbmV4cG9ydCBjb25zdCBJTlZBTElEX1NQQU5fQ09OVEVYVDogU3BhbkNvbnRleHQgPSB7XG4gIHRyYWNlSWQ6IElOVkFMSURfVFJBQ0VJRCxcbiAgc3BhbklkOiBJTlZBTElEX1NQQU5JRCxcbiAgdHJhY2VGbGFnczogVHJhY2VGbGFncy5OT05FLFxufTtcbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5pbXBvcnQgeyBFeGNlcHRpb24gfSBmcm9tICcuLi9jb21tb24vRXhjZXB0aW9uJztcbmltcG9ydCB7IFRpbWVJbnB1dCB9IGZyb20gJy4uL2NvbW1vbi9UaW1lJztcbmltcG9ydCB7IFNwYW5BdHRyaWJ1dGVzIH0gZnJvbSAnLi9hdHRyaWJ1dGVzJztcbmltcG9ydCB7IElOVkFMSURfU1BBTl9DT05URVhUIH0gZnJvbSAnLi9pbnZhbGlkLXNwYW4tY29uc3RhbnRzJztcbmltcG9ydCB7IFNwYW4gfSBmcm9tICcuL3NwYW4nO1xuaW1wb3J0IHsgU3BhbkNvbnRleHQgfSBmcm9tICcuL3NwYW5fY29udGV4dCc7XG5pbXBvcnQgeyBTcGFuU3RhdHVzIH0gZnJvbSAnLi9zdGF0dXMnO1xuaW1wb3J0IHsgTGluayB9IGZyb20gJy4vbGluayc7XG5cbi8qKlxuICogVGhlIE5vblJlY29yZGluZ1NwYW4gaXMgdGhlIGRlZmF1bHQge0BsaW5rIFNwYW59IHRoYXQgaXMgdXNlZCB3aGVuIG5vIFNwYW5cbiAqIGltcGxlbWVudGF0aW9uIGlzIGF2YWlsYWJsZS4gQWxsIG9wZXJhdGlvbnMgYXJlIG5vLW9wIGluY2x1ZGluZyBjb250ZXh0XG4gKiBwcm9wYWdhdGlvbi5cbiAqL1xuZXhwb3J0IGNsYXNzIE5vblJlY29yZGluZ1NwYW4gaW1wbGVtZW50cyBTcGFuIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBfc3BhbkNvbnRleHQ6IFNwYW5Db250ZXh0ID0gSU5WQUxJRF9TUEFOX0NPTlRFWFRcbiAgKSB7fVxuXG4gIC8vIFJldHVybnMgYSBTcGFuQ29udGV4dC5cbiAgc3BhbkNvbnRleHQoKTogU3BhbkNvbnRleHQge1xuICAgIHJldHVybiB0aGlzLl9zcGFuQ29udGV4dDtcbiAgfVxuXG4gIC8vIEJ5IGRlZmF1bHQgZG9lcyBub3RoaW5nXG4gIHNldEF0dHJpYnV0ZShfa2V5OiBzdHJpbmcsIF92YWx1ZTogdW5rbm93bik6IHRoaXMge1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gQnkgZGVmYXVsdCBkb2VzIG5vdGhpbmdcbiAgc2V0QXR0cmlidXRlcyhfYXR0cmlidXRlczogU3BhbkF0dHJpYnV0ZXMpOiB0aGlzIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIEJ5IGRlZmF1bHQgZG9lcyBub3RoaW5nXG4gIGFkZEV2ZW50KF9uYW1lOiBzdHJpbmcsIF9hdHRyaWJ1dGVzPzogU3BhbkF0dHJpYnV0ZXMpOiB0aGlzIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGFkZExpbmsoX2xpbms6IExpbmspOiB0aGlzIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGFkZExpbmtzKF9saW5rczogTGlua1tdKTogdGhpcyB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBCeSBkZWZhdWx0IGRvZXMgbm90aGluZ1xuICBzZXRTdGF0dXMoX3N0YXR1czogU3BhblN0YXR1cyk6IHRoaXMge1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gQnkgZGVmYXVsdCBkb2VzIG5vdGhpbmdcbiAgdXBkYXRlTmFtZShfbmFtZTogc3RyaW5nKTogdGhpcyB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBCeSBkZWZhdWx0IGRvZXMgbm90aGluZ1xuICBlbmQoX2VuZFRpbWU/OiBUaW1lSW5wdXQpOiB2b2lkIHt9XG5cbiAgLy8gaXNSZWNvcmRpbmcgYWx3YXlzIHJldHVybnMgZmFsc2UgZm9yIE5vblJlY29yZGluZ1NwYW4uXG4gIGlzUmVjb3JkaW5nKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIEJ5IGRlZmF1bHQgZG9lcyBub3RoaW5nXG4gIHJlY29yZEV4Y2VwdGlvbihfZXhjZXB0aW9uOiBFeGNlcHRpb24sIF90aW1lPzogVGltZUlucHV0KTogdm9pZCB7fVxufVxuIiwgIi8qXG4gKiBDb3B5cmlnaHQgVGhlIE9wZW5UZWxlbWV0cnkgQXV0aG9yc1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgIGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IGNyZWF0ZUNvbnRleHRLZXkgfSBmcm9tICcuLi9jb250ZXh0L2NvbnRleHQnO1xuaW1wb3J0IHsgQ29udGV4dCB9IGZyb20gJy4uL2NvbnRleHQvdHlwZXMnO1xuaW1wb3J0IHsgU3BhbiB9IGZyb20gJy4vc3Bhbic7XG5pbXBvcnQgeyBTcGFuQ29udGV4dCB9IGZyb20gJy4vc3Bhbl9jb250ZXh0JztcbmltcG9ydCB7IE5vblJlY29yZGluZ1NwYW4gfSBmcm9tICcuL05vblJlY29yZGluZ1NwYW4nO1xuaW1wb3J0IHsgQ29udGV4dEFQSSB9IGZyb20gJy4uL2FwaS9jb250ZXh0JztcblxuLyoqXG4gKiBzcGFuIGtleVxuICovXG5jb25zdCBTUEFOX0tFWSA9IGNyZWF0ZUNvbnRleHRLZXkoJ09wZW5UZWxlbWV0cnkgQ29udGV4dCBLZXkgU1BBTicpO1xuXG4vKipcbiAqIFJldHVybiB0aGUgc3BhbiBpZiBvbmUgZXhpc3RzXG4gKlxuICogQHBhcmFtIGNvbnRleHQgY29udGV4dCB0byBnZXQgc3BhbiBmcm9tXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRTcGFuKGNvbnRleHQ6IENvbnRleHQpOiBTcGFuIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIChjb250ZXh0LmdldFZhbHVlKFNQQU5fS0VZKSBhcyBTcGFuKSB8fCB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogR2V0cyB0aGUgc3BhbiBmcm9tIHRoZSBjdXJyZW50IGNvbnRleHQsIGlmIG9uZSBleGlzdHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRBY3RpdmVTcGFuKCk6IFNwYW4gfCB1bmRlZmluZWQge1xuICByZXR1cm4gZ2V0U3BhbihDb250ZXh0QVBJLmdldEluc3RhbmNlKCkuYWN0aXZlKCkpO1xufVxuXG4vKipcbiAqIFNldCB0aGUgc3BhbiBvbiBhIGNvbnRleHRcbiAqXG4gKiBAcGFyYW0gY29udGV4dCBjb250ZXh0IHRvIHVzZSBhcyBwYXJlbnRcbiAqIEBwYXJhbSBzcGFuIHNwYW4gdG8gc2V0IGFjdGl2ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0U3Bhbihjb250ZXh0OiBDb250ZXh0LCBzcGFuOiBTcGFuKTogQ29udGV4dCB7XG4gIHJldHVybiBjb250ZXh0LnNldFZhbHVlKFNQQU5fS0VZLCBzcGFuKTtcbn1cblxuLyoqXG4gKiBSZW1vdmUgY3VycmVudCBzcGFuIHN0b3JlZCBpbiB0aGUgY29udGV4dFxuICpcbiAqIEBwYXJhbSBjb250ZXh0IGNvbnRleHQgdG8gZGVsZXRlIHNwYW4gZnJvbVxuICovXG5leHBvcnQgZnVuY3Rpb24gZGVsZXRlU3Bhbihjb250ZXh0OiBDb250ZXh0KTogQ29udGV4dCB7XG4gIHJldHVybiBjb250ZXh0LmRlbGV0ZVZhbHVlKFNQQU5fS0VZKTtcbn1cblxuLyoqXG4gKiBXcmFwIHNwYW4gY29udGV4dCBpbiBhIE5vb3BTcGFuIGFuZCBzZXQgYXMgc3BhbiBpbiBhIG5ld1xuICogY29udGV4dFxuICpcbiAqIEBwYXJhbSBjb250ZXh0IGNvbnRleHQgdG8gc2V0IGFjdGl2ZSBzcGFuIG9uXG4gKiBAcGFyYW0gc3BhbkNvbnRleHQgc3BhbiBjb250ZXh0IHRvIGJlIHdyYXBwZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldFNwYW5Db250ZXh0KFxuICBjb250ZXh0OiBDb250ZXh0LFxuICBzcGFuQ29udGV4dDogU3BhbkNvbnRleHRcbik6IENvbnRleHQge1xuICByZXR1cm4gc2V0U3Bhbihjb250ZXh0LCBuZXcgTm9uUmVjb3JkaW5nU3BhbihzcGFuQ29udGV4dCkpO1xufVxuXG4vKipcbiAqIEdldCB0aGUgc3BhbiBjb250ZXh0IG9mIHRoZSBzcGFuIGlmIGl0IGV4aXN0cy5cbiAqXG4gKiBAcGFyYW0gY29udGV4dCBjb250ZXh0IHRvIGdldCB2YWx1ZXMgZnJvbVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0U3BhbkNvbnRleHQoY29udGV4dDogQ29udGV4dCk6IFNwYW5Db250ZXh0IHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIGdldFNwYW4oY29udGV4dCk/LnNwYW5Db250ZXh0KCk7XG59XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbmltcG9ydCB7IElOVkFMSURfU1BBTklELCBJTlZBTElEX1RSQUNFSUQgfSBmcm9tICcuL2ludmFsaWQtc3Bhbi1jb25zdGFudHMnO1xuaW1wb3J0IHsgTm9uUmVjb3JkaW5nU3BhbiB9IGZyb20gJy4vTm9uUmVjb3JkaW5nU3Bhbic7XG5pbXBvcnQgeyBTcGFuIH0gZnJvbSAnLi9zcGFuJztcbmltcG9ydCB7IFNwYW5Db250ZXh0IH0gZnJvbSAnLi9zcGFuX2NvbnRleHQnO1xuXG5jb25zdCBWQUxJRF9UUkFDRUlEX1JFR0VYID0gL14oWzAtOWEtZl17MzJ9KSQvaTtcbmNvbnN0IFZBTElEX1NQQU5JRF9SRUdFWCA9IC9eWzAtOWEtZl17MTZ9JC9pO1xuXG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZFRyYWNlSWQodHJhY2VJZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBWQUxJRF9UUkFDRUlEX1JFR0VYLnRlc3QodHJhY2VJZCkgJiYgdHJhY2VJZCAhPT0gSU5WQUxJRF9UUkFDRUlEO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZFNwYW5JZChzcGFuSWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gVkFMSURfU1BBTklEX1JFR0VYLnRlc3Qoc3BhbklkKSAmJiBzcGFuSWQgIT09IElOVkFMSURfU1BBTklEO1xufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIHtAbGluayBTcGFuQ29udGV4dH0gaXMgdmFsaWQuXG4gKiBAcmV0dXJuIHRydWUgaWYgdGhpcyB7QGxpbmsgU3BhbkNvbnRleHR9IGlzIHZhbGlkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNTcGFuQ29udGV4dFZhbGlkKHNwYW5Db250ZXh0OiBTcGFuQ29udGV4dCk6IGJvb2xlYW4ge1xuICByZXR1cm4gKFxuICAgIGlzVmFsaWRUcmFjZUlkKHNwYW5Db250ZXh0LnRyYWNlSWQpICYmIGlzVmFsaWRTcGFuSWQoc3BhbkNvbnRleHQuc3BhbklkKVxuICApO1xufVxuXG4vKipcbiAqIFdyYXAgdGhlIGdpdmVuIHtAbGluayBTcGFuQ29udGV4dH0gaW4gYSBuZXcgbm9uLXJlY29yZGluZyB7QGxpbmsgU3Bhbn1cbiAqXG4gKiBAcGFyYW0gc3BhbkNvbnRleHQgc3BhbiBjb250ZXh0IHRvIGJlIHdyYXBwZWRcbiAqIEByZXR1cm5zIGEgbmV3IG5vbi1yZWNvcmRpbmcge0BsaW5rIFNwYW59IHdpdGggdGhlIHByb3ZpZGVkIGNvbnRleHRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdyYXBTcGFuQ29udGV4dChzcGFuQ29udGV4dDogU3BhbkNvbnRleHQpOiBTcGFuIHtcbiAgcmV0dXJuIG5ldyBOb25SZWNvcmRpbmdTcGFuKHNwYW5Db250ZXh0KTtcbn1cbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5pbXBvcnQgeyBDb250ZXh0QVBJIH0gZnJvbSAnLi4vYXBpL2NvbnRleHQnO1xuaW1wb3J0IHsgQ29udGV4dCB9IGZyb20gJy4uL2NvbnRleHQvdHlwZXMnO1xuaW1wb3J0IHsgZ2V0U3BhbkNvbnRleHQsIHNldFNwYW4gfSBmcm9tICcuLi90cmFjZS9jb250ZXh0LXV0aWxzJztcbmltcG9ydCB7IE5vblJlY29yZGluZ1NwYW4gfSBmcm9tICcuL05vblJlY29yZGluZ1NwYW4nO1xuaW1wb3J0IHsgU3BhbiB9IGZyb20gJy4vc3Bhbic7XG5pbXBvcnQgeyBpc1NwYW5Db250ZXh0VmFsaWQgfSBmcm9tICcuL3NwYW5jb250ZXh0LXV0aWxzJztcbmltcG9ydCB7IFNwYW5PcHRpb25zIH0gZnJvbSAnLi9TcGFuT3B0aW9ucyc7XG5pbXBvcnQgeyBTcGFuQ29udGV4dCB9IGZyb20gJy4vc3Bhbl9jb250ZXh0JztcbmltcG9ydCB7IFRyYWNlciB9IGZyb20gJy4vdHJhY2VyJztcblxuY29uc3QgY29udGV4dEFwaSA9IENvbnRleHRBUEkuZ2V0SW5zdGFuY2UoKTtcblxuLyoqXG4gKiBOby1vcCBpbXBsZW1lbnRhdGlvbnMgb2Yge0BsaW5rIFRyYWNlcn0uXG4gKi9cbmV4cG9ydCBjbGFzcyBOb29wVHJhY2VyIGltcGxlbWVudHMgVHJhY2VyIHtcbiAgLy8gc3RhcnRTcGFuIHN0YXJ0cyBhIG5vb3Agc3Bhbi5cbiAgc3RhcnRTcGFuKFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBvcHRpb25zPzogU3Bhbk9wdGlvbnMsXG4gICAgY29udGV4dCA9IGNvbnRleHRBcGkuYWN0aXZlKClcbiAgKTogU3BhbiB7XG4gICAgY29uc3Qgcm9vdCA9IEJvb2xlYW4ob3B0aW9ucz8ucm9vdCk7XG4gICAgaWYgKHJvb3QpIHtcbiAgICAgIHJldHVybiBuZXcgTm9uUmVjb3JkaW5nU3BhbigpO1xuICAgIH1cblxuICAgIGNvbnN0IHBhcmVudEZyb21Db250ZXh0ID0gY29udGV4dCAmJiBnZXRTcGFuQ29udGV4dChjb250ZXh0KTtcblxuICAgIGlmIChcbiAgICAgIGlzU3BhbkNvbnRleHQocGFyZW50RnJvbUNvbnRleHQpICYmXG4gICAgICBpc1NwYW5Db250ZXh0VmFsaWQocGFyZW50RnJvbUNvbnRleHQpXG4gICAgKSB7XG4gICAgICByZXR1cm4gbmV3IE5vblJlY29yZGluZ1NwYW4ocGFyZW50RnJvbUNvbnRleHQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbmV3IE5vblJlY29yZGluZ1NwYW4oKTtcbiAgICB9XG4gIH1cblxuICBzdGFydEFjdGl2ZVNwYW48RiBleHRlbmRzIChzcGFuOiBTcGFuKSA9PiBSZXR1cm5UeXBlPEY+PihcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgZm46IEZcbiAgKTogUmV0dXJuVHlwZTxGPjtcbiAgc3RhcnRBY3RpdmVTcGFuPEYgZXh0ZW5kcyAoc3BhbjogU3BhbikgPT4gUmV0dXJuVHlwZTxGPj4oXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIG9wdHM6IFNwYW5PcHRpb25zIHwgdW5kZWZpbmVkLFxuICAgIGZuOiBGXG4gICk6IFJldHVyblR5cGU8Rj47XG4gIHN0YXJ0QWN0aXZlU3BhbjxGIGV4dGVuZHMgKHNwYW46IFNwYW4pID0+IFJldHVyblR5cGU8Rj4+KFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBvcHRzOiBTcGFuT3B0aW9ucyB8IHVuZGVmaW5lZCxcbiAgICBjdHg6IENvbnRleHQgfCB1bmRlZmluZWQsXG4gICAgZm46IEZcbiAgKTogUmV0dXJuVHlwZTxGPjtcbiAgc3RhcnRBY3RpdmVTcGFuPEYgZXh0ZW5kcyAoc3BhbjogU3BhbikgPT4gUmV0dXJuVHlwZTxGPj4oXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIGFyZzI/OiBGIHwgU3Bhbk9wdGlvbnMsXG4gICAgYXJnMz86IEYgfCBDb250ZXh0LFxuICAgIGFyZzQ/OiBGXG4gICk6IFJldHVyblR5cGU8Rj4gfCB1bmRlZmluZWQge1xuICAgIGxldCBvcHRzOiBTcGFuT3B0aW9ucyB8IHVuZGVmaW5lZDtcbiAgICBsZXQgY3R4OiBDb250ZXh0IHwgdW5kZWZpbmVkO1xuICAgIGxldCBmbjogRjtcblxuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMikge1xuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMikge1xuICAgICAgZm4gPSBhcmcyIGFzIEY7XG4gICAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAzKSB7XG4gICAgICBvcHRzID0gYXJnMiBhcyBTcGFuT3B0aW9ucyB8IHVuZGVmaW5lZDtcbiAgICAgIGZuID0gYXJnMyBhcyBGO1xuICAgIH0gZWxzZSB7XG4gICAgICBvcHRzID0gYXJnMiBhcyBTcGFuT3B0aW9ucyB8IHVuZGVmaW5lZDtcbiAgICAgIGN0eCA9IGFyZzMgYXMgQ29udGV4dCB8IHVuZGVmaW5lZDtcbiAgICAgIGZuID0gYXJnNCBhcyBGO1xuICAgIH1cblxuICAgIGNvbnN0IHBhcmVudENvbnRleHQgPSBjdHggPz8gY29udGV4dEFwaS5hY3RpdmUoKTtcbiAgICBjb25zdCBzcGFuID0gdGhpcy5zdGFydFNwYW4obmFtZSwgb3B0cywgcGFyZW50Q29udGV4dCk7XG4gICAgY29uc3QgY29udGV4dFdpdGhTcGFuU2V0ID0gc2V0U3BhbihwYXJlbnRDb250ZXh0LCBzcGFuKTtcblxuICAgIHJldHVybiBjb250ZXh0QXBpLndpdGgoY29udGV4dFdpdGhTcGFuU2V0LCBmbiwgdW5kZWZpbmVkLCBzcGFuKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpc1NwYW5Db250ZXh0KHNwYW5Db250ZXh0OiBhbnkpOiBzcGFuQ29udGV4dCBpcyBTcGFuQ29udGV4dCB7XG4gIHJldHVybiAoXG4gICAgdHlwZW9mIHNwYW5Db250ZXh0ID09PSAnb2JqZWN0JyAmJlxuICAgIHR5cGVvZiBzcGFuQ29udGV4dFsnc3BhbklkJ10gPT09ICdzdHJpbmcnICYmXG4gICAgdHlwZW9mIHNwYW5Db250ZXh0Wyd0cmFjZUlkJ10gPT09ICdzdHJpbmcnICYmXG4gICAgdHlwZW9mIHNwYW5Db250ZXh0Wyd0cmFjZUZsYWdzJ10gPT09ICdudW1iZXInXG4gICk7XG59XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuaW1wb3J0IHsgQ29udGV4dCB9IGZyb20gJy4uL2NvbnRleHQvdHlwZXMnO1xuaW1wb3J0IHsgTm9vcFRyYWNlciB9IGZyb20gJy4vTm9vcFRyYWNlcic7XG5pbXBvcnQgeyBTcGFuIH0gZnJvbSAnLi9zcGFuJztcbmltcG9ydCB7IFNwYW5PcHRpb25zIH0gZnJvbSAnLi9TcGFuT3B0aW9ucyc7XG5pbXBvcnQgeyBUcmFjZXIgfSBmcm9tICcuL3RyYWNlcic7XG5pbXBvcnQgeyBUcmFjZXJPcHRpb25zIH0gZnJvbSAnLi90cmFjZXJfb3B0aW9ucyc7XG5cbmNvbnN0IE5PT1BfVFJBQ0VSID0gbmV3IE5vb3BUcmFjZXIoKTtcblxuLyoqXG4gKiBQcm94eSB0cmFjZXIgcHJvdmlkZWQgYnkgdGhlIHByb3h5IHRyYWNlciBwcm92aWRlclxuICovXG5leHBvcnQgY2xhc3MgUHJveHlUcmFjZXIgaW1wbGVtZW50cyBUcmFjZXIge1xuICAvLyBXaGVuIGEgcmVhbCBpbXBsZW1lbnRhdGlvbiBpcyBwcm92aWRlZCwgdGhpcyB3aWxsIGJlIGl0XG4gIHByaXZhdGUgX2RlbGVnYXRlPzogVHJhY2VyO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgX3Byb3ZpZGVyOiBUcmFjZXJEZWxlZ2F0b3IsXG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWU6IHN0cmluZyxcbiAgICBwdWJsaWMgcmVhZG9ubHkgdmVyc2lvbj86IHN0cmluZyxcbiAgICBwdWJsaWMgcmVhZG9ubHkgb3B0aW9ucz86IFRyYWNlck9wdGlvbnNcbiAgKSB7fVxuXG4gIHN0YXJ0U3BhbihuYW1lOiBzdHJpbmcsIG9wdGlvbnM/OiBTcGFuT3B0aW9ucywgY29udGV4dD86IENvbnRleHQpOiBTcGFuIHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0VHJhY2VyKCkuc3RhcnRTcGFuKG5hbWUsIG9wdGlvbnMsIGNvbnRleHQpO1xuICB9XG5cbiAgc3RhcnRBY3RpdmVTcGFuPEYgZXh0ZW5kcyAoc3BhbjogU3BhbikgPT4gdW5rbm93bj4oXG4gICAgX25hbWU6IHN0cmluZyxcbiAgICBfb3B0aW9uczogRiB8IFNwYW5PcHRpb25zLFxuICAgIF9jb250ZXh0PzogRiB8IENvbnRleHQsXG4gICAgX2ZuPzogRlxuICApOiBSZXR1cm5UeXBlPEY+IHtcbiAgICBjb25zdCB0cmFjZXIgPSB0aGlzLl9nZXRUcmFjZXIoKTtcbiAgICByZXR1cm4gUmVmbGVjdC5hcHBseSh0cmFjZXIuc3RhcnRBY3RpdmVTcGFuLCB0cmFjZXIsIGFyZ3VtZW50cyk7XG4gIH1cblxuICAvKipcbiAgICogVHJ5IHRvIGdldCBhIHRyYWNlciBmcm9tIHRoZSBwcm94eSB0cmFjZXIgcHJvdmlkZXIuXG4gICAqIElmIHRoZSBwcm94eSB0cmFjZXIgcHJvdmlkZXIgaGFzIG5vIGRlbGVnYXRlLCByZXR1cm4gYSBub29wIHRyYWNlci5cbiAgICovXG4gIHByaXZhdGUgX2dldFRyYWNlcigpIHtcbiAgICBpZiAodGhpcy5fZGVsZWdhdGUpIHtcbiAgICAgIHJldHVybiB0aGlzLl9kZWxlZ2F0ZTtcbiAgICB9XG5cbiAgICBjb25zdCB0cmFjZXIgPSB0aGlzLl9wcm92aWRlci5nZXREZWxlZ2F0ZVRyYWNlcihcbiAgICAgIHRoaXMubmFtZSxcbiAgICAgIHRoaXMudmVyc2lvbixcbiAgICAgIHRoaXMub3B0aW9uc1xuICAgICk7XG5cbiAgICBpZiAoIXRyYWNlcikge1xuICAgICAgcmV0dXJuIE5PT1BfVFJBQ0VSO1xuICAgIH1cblxuICAgIHRoaXMuX2RlbGVnYXRlID0gdHJhY2VyO1xuICAgIHJldHVybiB0aGlzLl9kZWxlZ2F0ZTtcbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRyYWNlckRlbGVnYXRvciB7XG4gIGdldERlbGVnYXRlVHJhY2VyKFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICB2ZXJzaW9uPzogc3RyaW5nLFxuICAgIG9wdGlvbnM/OiBUcmFjZXJPcHRpb25zXG4gICk6IFRyYWNlciB8IHVuZGVmaW5lZDtcbn1cbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5pbXBvcnQgeyBOb29wVHJhY2VyIH0gZnJvbSAnLi9Ob29wVHJhY2VyJztcbmltcG9ydCB7IFRyYWNlciB9IGZyb20gJy4vdHJhY2VyJztcbmltcG9ydCB7IFRyYWNlck9wdGlvbnMgfSBmcm9tICcuL3RyYWNlcl9vcHRpb25zJztcbmltcG9ydCB7IFRyYWNlclByb3ZpZGVyIH0gZnJvbSAnLi90cmFjZXJfcHJvdmlkZXInO1xuXG4vKipcbiAqIEFuIGltcGxlbWVudGF0aW9uIG9mIHRoZSB7QGxpbmsgVHJhY2VyUHJvdmlkZXJ9IHdoaWNoIHJldHVybnMgYW4gaW1wb3RlbnRcbiAqIFRyYWNlciBmb3IgYWxsIGNhbGxzIHRvIGBnZXRUcmFjZXJgLlxuICpcbiAqIEFsbCBvcGVyYXRpb25zIGFyZSBuby1vcC5cbiAqL1xuZXhwb3J0IGNsYXNzIE5vb3BUcmFjZXJQcm92aWRlciBpbXBsZW1lbnRzIFRyYWNlclByb3ZpZGVyIHtcbiAgZ2V0VHJhY2VyKFxuICAgIF9uYW1lPzogc3RyaW5nLFxuICAgIF92ZXJzaW9uPzogc3RyaW5nLFxuICAgIF9vcHRpb25zPzogVHJhY2VyT3B0aW9uc1xuICApOiBUcmFjZXIge1xuICAgIHJldHVybiBuZXcgTm9vcFRyYWNlcigpO1xuICB9XG59XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuaW1wb3J0IHsgVHJhY2VyIH0gZnJvbSAnLi90cmFjZXInO1xuaW1wb3J0IHsgVHJhY2VyUHJvdmlkZXIgfSBmcm9tICcuL3RyYWNlcl9wcm92aWRlcic7XG5pbXBvcnQgeyBQcm94eVRyYWNlciB9IGZyb20gJy4vUHJveHlUcmFjZXInO1xuaW1wb3J0IHsgTm9vcFRyYWNlclByb3ZpZGVyIH0gZnJvbSAnLi9Ob29wVHJhY2VyUHJvdmlkZXInO1xuaW1wb3J0IHsgVHJhY2VyT3B0aW9ucyB9IGZyb20gJy4vdHJhY2VyX29wdGlvbnMnO1xuXG5jb25zdCBOT09QX1RSQUNFUl9QUk9WSURFUiA9IG5ldyBOb29wVHJhY2VyUHJvdmlkZXIoKTtcblxuLyoqXG4gKiBUcmFjZXIgcHJvdmlkZXIgd2hpY2ggcHJvdmlkZXMge0BsaW5rIFByb3h5VHJhY2VyfXMuXG4gKlxuICogQmVmb3JlIGEgZGVsZWdhdGUgaXMgc2V0LCB0cmFjZXJzIHByb3ZpZGVkIGFyZSBOb09wLlxuICogICBXaGVuIGEgZGVsZWdhdGUgaXMgc2V0LCB0cmFjZXMgYXJlIHByb3ZpZGVkIGZyb20gdGhlIGRlbGVnYXRlLlxuICogICBXaGVuIGEgZGVsZWdhdGUgaXMgc2V0IGFmdGVyIHRyYWNlcnMgaGF2ZSBhbHJlYWR5IGJlZW4gcHJvdmlkZWQsXG4gKiAgIGFsbCB0cmFjZXJzIGFscmVhZHkgcHJvdmlkZWQgd2lsbCB1c2UgdGhlIHByb3ZpZGVkIGRlbGVnYXRlIGltcGxlbWVudGF0aW9uLlxuICovXG5leHBvcnQgY2xhc3MgUHJveHlUcmFjZXJQcm92aWRlciBpbXBsZW1lbnRzIFRyYWNlclByb3ZpZGVyIHtcbiAgcHJpdmF0ZSBfZGVsZWdhdGU/OiBUcmFjZXJQcm92aWRlcjtcblxuICAvKipcbiAgICogR2V0IGEge0BsaW5rIFByb3h5VHJhY2VyfVxuICAgKi9cbiAgZ2V0VHJhY2VyKG5hbWU6IHN0cmluZywgdmVyc2lvbj86IHN0cmluZywgb3B0aW9ucz86IFRyYWNlck9wdGlvbnMpOiBUcmFjZXIge1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLmdldERlbGVnYXRlVHJhY2VyKG5hbWUsIHZlcnNpb24sIG9wdGlvbnMpID8/XG4gICAgICBuZXcgUHJveHlUcmFjZXIodGhpcywgbmFtZSwgdmVyc2lvbiwgb3B0aW9ucylcbiAgICApO1xuICB9XG5cbiAgZ2V0RGVsZWdhdGUoKTogVHJhY2VyUHJvdmlkZXIge1xuICAgIHJldHVybiB0aGlzLl9kZWxlZ2F0ZSA/PyBOT09QX1RSQUNFUl9QUk9WSURFUjtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgdGhlIGRlbGVnYXRlIHRyYWNlciBwcm92aWRlclxuICAgKi9cbiAgc2V0RGVsZWdhdGUoZGVsZWdhdGU6IFRyYWNlclByb3ZpZGVyKSB7XG4gICAgdGhpcy5fZGVsZWdhdGUgPSBkZWxlZ2F0ZTtcbiAgfVxuXG4gIGdldERlbGVnYXRlVHJhY2VyKFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICB2ZXJzaW9uPzogc3RyaW5nLFxuICAgIG9wdGlvbnM/OiBUcmFjZXJPcHRpb25zXG4gICk6IFRyYWNlciB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuX2RlbGVnYXRlPy5nZXRUcmFjZXIobmFtZSwgdmVyc2lvbiwgb3B0aW9ucyk7XG4gIH1cbn1cbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5pbXBvcnQgeyBTcGFuQXR0cmlidXRlcyB9IGZyb20gJy4vYXR0cmlidXRlcyc7XG5pbXBvcnQgeyBUcmFjZVN0YXRlIH0gZnJvbSAnLi90cmFjZV9zdGF0ZSc7XG5cbi8qKlxuICogQGRlcHJlY2F0ZWQgdXNlIHRoZSBvbmUgZGVjbGFyZWQgaW4gQG9wZW50ZWxlbWV0cnkvc2RrLXRyYWNlLWJhc2UgaW5zdGVhZC5cbiAqIEEgc2FtcGxpbmcgZGVjaXNpb24gdGhhdCBkZXRlcm1pbmVzIGhvdyBhIHtAbGluayBTcGFufSB3aWxsIGJlIHJlY29yZGVkXG4gKiBhbmQgY29sbGVjdGVkLlxuICovXG5leHBvcnQgZW51bSBTYW1wbGluZ0RlY2lzaW9uIHtcbiAgLyoqXG4gICAqIGBTcGFuLmlzUmVjb3JkaW5nKCkgPT09IGZhbHNlYCwgc3BhbiB3aWxsIG5vdCBiZSByZWNvcmRlZCBhbmQgYWxsIGV2ZW50c1xuICAgKiBhbmQgYXR0cmlidXRlcyB3aWxsIGJlIGRyb3BwZWQuXG4gICAqL1xuICBOT1RfUkVDT1JELFxuICAvKipcbiAgICogYFNwYW4uaXNSZWNvcmRpbmcoKSA9PT0gdHJ1ZWAsIGJ1dCBgU2FtcGxlZGAgZmxhZyBpbiB7QGxpbmsgVHJhY2VGbGFnc31cbiAgICogTVVTVCBOT1QgYmUgc2V0LlxuICAgKi9cbiAgUkVDT1JELFxuICAvKipcbiAgICogYFNwYW4uaXNSZWNvcmRpbmcoKSA9PT0gdHJ1ZWAgQU5EIGBTYW1wbGVkYCBmbGFnIGluIHtAbGluayBUcmFjZUZsYWdzfVxuICAgKiBNVVNUIGJlIHNldC5cbiAgICovXG4gIFJFQ09SRF9BTkRfU0FNUExFRCxcbn1cblxuLyoqXG4gKiBAZGVwcmVjYXRlZCB1c2UgdGhlIG9uZSBkZWNsYXJlZCBpbiBAb3BlbnRlbGVtZXRyeS9zZGstdHJhY2UtYmFzZSBpbnN0ZWFkLlxuICogQSBzYW1wbGluZyByZXN1bHQgY29udGFpbnMgYSBkZWNpc2lvbiBmb3IgYSB7QGxpbmsgU3Bhbn0gYW5kIGFkZGl0aW9uYWxcbiAqIGF0dHJpYnV0ZXMgdGhlIHNhbXBsZXIgd291bGQgbGlrZSB0byBhZGRlZCB0byB0aGUgU3Bhbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTYW1wbGluZ1Jlc3VsdCB7XG4gIC8qKlxuICAgKiBBIHNhbXBsaW5nIGRlY2lzaW9uLCByZWZlciB0byB7QGxpbmsgU2FtcGxpbmdEZWNpc2lvbn0gZm9yIGRldGFpbHMuXG4gICAqL1xuICBkZWNpc2lvbjogU2FtcGxpbmdEZWNpc2lvbjtcbiAgLyoqXG4gICAqIFRoZSBsaXN0IG9mIGF0dHJpYnV0ZXMgcmV0dXJuZWQgYnkgU2FtcGxpbmdSZXN1bHQgTVVTVCBiZSBpbW11dGFibGUuXG4gICAqIENhbGxlciBtYXkgY2FsbCB7QGxpbmsgU2FtcGxlcn0uc2hvdWxkU2FtcGxlIGFueSBudW1iZXIgb2YgdGltZXMgYW5kXG4gICAqIGNhbiBzYWZlbHkgY2FjaGUgdGhlIHJldHVybmVkIHZhbHVlLlxuICAgKi9cbiAgYXR0cmlidXRlcz86IFJlYWRvbmx5PFNwYW5BdHRyaWJ1dGVzPjtcbiAgLyoqXG4gICAqIEEge0BsaW5rIFRyYWNlU3RhdGV9IHRoYXQgd2lsbCBiZSBhc3NvY2lhdGVkIHdpdGggdGhlIHtAbGluayBTcGFufSB0aHJvdWdoXG4gICAqIHRoZSBuZXcge0BsaW5rIFNwYW5Db250ZXh0fS4gU2FtcGxlcnMgU0hPVUxEIHJldHVybiB0aGUgVHJhY2VTdGF0ZSBmcm9tXG4gICAqIHRoZSBwYXNzZWQtaW4ge0BsaW5rIENvbnRleHR9IGlmIHRoZXkgZG8gbm90IGludGVuZCB0byBjaGFuZ2UgaXQuIExlYXZpbmdcbiAgICogdGhlIHZhbHVlIHVuZGVmaW5lZCB3aWxsIGFsc28gbGVhdmUgdGhlIFRyYWNlU3RhdGUgdW5jaGFuZ2VkLlxuICAgKi9cbiAgdHJhY2VTdGF0ZT86IFRyYWNlU3RhdGU7XG59XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbmV4cG9ydCBlbnVtIFNwYW5LaW5kIHtcbiAgLyoqIERlZmF1bHQgdmFsdWUuIEluZGljYXRlcyB0aGF0IHRoZSBzcGFuIGlzIHVzZWQgaW50ZXJuYWxseS4gKi9cbiAgSU5URVJOQUwgPSAwLFxuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgdGhhdCB0aGUgc3BhbiBjb3ZlcnMgc2VydmVyLXNpZGUgaGFuZGxpbmcgb2YgYW4gUlBDIG9yIG90aGVyXG4gICAqIHJlbW90ZSByZXF1ZXN0LlxuICAgKi9cbiAgU0VSVkVSID0gMSxcblxuICAvKipcbiAgICogSW5kaWNhdGVzIHRoYXQgdGhlIHNwYW4gY292ZXJzIHRoZSBjbGllbnQtc2lkZSB3cmFwcGVyIGFyb3VuZCBhbiBSUEMgb3JcbiAgICogb3RoZXIgcmVtb3RlIHJlcXVlc3QuXG4gICAqL1xuICBDTElFTlQgPSAyLFxuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgdGhhdCB0aGUgc3BhbiBkZXNjcmliZXMgcHJvZHVjZXIgc2VuZGluZyBhIG1lc3NhZ2UgdG8gYVxuICAgKiBicm9rZXIuIFVubGlrZSBjbGllbnQgYW5kIHNlcnZlciwgdGhlcmUgaXMgbm8gZGlyZWN0IGNyaXRpY2FsIHBhdGggbGF0ZW5jeVxuICAgKiByZWxhdGlvbnNoaXAgYmV0d2VlbiBwcm9kdWNlciBhbmQgY29uc3VtZXIgc3BhbnMuXG4gICAqL1xuICBQUk9EVUNFUiA9IDMsXG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyB0aGF0IHRoZSBzcGFuIGRlc2NyaWJlcyBjb25zdW1lciByZWNlaXZpbmcgYSBtZXNzYWdlIGZyb20gYVxuICAgKiBicm9rZXIuIFVubGlrZSBjbGllbnQgYW5kIHNlcnZlciwgdGhlcmUgaXMgbm8gZGlyZWN0IGNyaXRpY2FsIHBhdGggbGF0ZW5jeVxuICAgKiByZWxhdGlvbnNoaXAgYmV0d2VlbiBwcm9kdWNlciBhbmQgY29uc3VtZXIgc3BhbnMuXG4gICAqL1xuICBDT05TVU1FUiA9IDQsXG59XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3BhblN0YXR1cyB7XG4gIC8qKiBUaGUgc3RhdHVzIGNvZGUgb2YgdGhpcyBtZXNzYWdlLiAqL1xuICBjb2RlOiBTcGFuU3RhdHVzQ29kZTtcbiAgLyoqIEEgZGV2ZWxvcGVyLWZhY2luZyBlcnJvciBtZXNzYWdlLiAqL1xuICBtZXNzYWdlPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIEFuIGVudW1lcmF0aW9uIG9mIHN0YXR1cyBjb2Rlcy5cbiAqL1xuZXhwb3J0IGVudW0gU3BhblN0YXR1c0NvZGUge1xuICAvKipcbiAgICogVGhlIGRlZmF1bHQgc3RhdHVzLlxuICAgKi9cbiAgVU5TRVQgPSAwLFxuICAvKipcbiAgICogVGhlIG9wZXJhdGlvbiBoYXMgYmVlbiB2YWxpZGF0ZWQgYnkgYW4gQXBwbGljYXRpb24gZGV2ZWxvcGVyIG9yXG4gICAqIE9wZXJhdG9yIHRvIGhhdmUgY29tcGxldGVkIHN1Y2Nlc3NmdWxseS5cbiAgICovXG4gIE9LID0gMSxcbiAgLyoqXG4gICAqIFRoZSBvcGVyYXRpb24gY29udGFpbnMgYW4gZXJyb3IuXG4gICAqL1xuICBFUlJPUiA9IDIsXG59XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuY29uc3QgVkFMSURfS0VZX0NIQVJfUkFOR0UgPSAnW18wLTlhLXotKi9dJztcbmNvbnN0IFZBTElEX0tFWSA9IGBbYS16XSR7VkFMSURfS0VZX0NIQVJfUkFOR0V9ezAsMjU1fWA7XG5jb25zdCBWQUxJRF9WRU5ET1JfS0VZID0gYFthLXowLTldJHtWQUxJRF9LRVlfQ0hBUl9SQU5HRX17MCwyNDB9QFthLXpdJHtWQUxJRF9LRVlfQ0hBUl9SQU5HRX17MCwxM31gO1xuY29uc3QgVkFMSURfS0VZX1JFR0VYID0gbmV3IFJlZ0V4cChgXig/OiR7VkFMSURfS0VZfXwke1ZBTElEX1ZFTkRPUl9LRVl9KSRgKTtcbmNvbnN0IFZBTElEX1ZBTFVFX0JBU0VfUkVHRVggPSAvXlsgLX5dezAsMjU1fVshLX5dJC87XG5jb25zdCBJTlZBTElEX1ZBTFVFX0NPTU1BX0VRVUFMX1JFR0VYID0gLyx8PS87XG5cbi8qKlxuICogS2V5IGlzIG9wYXF1ZSBzdHJpbmcgdXAgdG8gMjU2IGNoYXJhY3RlcnMgcHJpbnRhYmxlLiBJdCBNVVNUIGJlZ2luIHdpdGggYVxuICogbG93ZXJjYXNlIGxldHRlciwgYW5kIGNhbiBvbmx5IGNvbnRhaW4gbG93ZXJjYXNlIGxldHRlcnMgYS16LCBkaWdpdHMgMC05LFxuICogdW5kZXJzY29yZXMgXywgZGFzaGVzIC0sIGFzdGVyaXNrcyAqLCBhbmQgZm9yd2FyZCBzbGFzaGVzIC8uXG4gKiBGb3IgbXVsdGktdGVuYW50IHZlbmRvciBzY2VuYXJpb3MsIGFuIGF0IHNpZ24gKEApIGNhbiBiZSB1c2VkIHRvIHByZWZpeCB0aGVcbiAqIHZlbmRvciBuYW1lLiBWZW5kb3JzIFNIT1VMRCBzZXQgdGhlIHRlbmFudCBJRCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBrZXkuXG4gKiBzZWUgaHR0cHM6Ly93d3cudzMub3JnL1RSL3RyYWNlLWNvbnRleHQvI2tleVxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVLZXkoa2V5OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIFZBTElEX0tFWV9SRUdFWC50ZXN0KGtleSk7XG59XG5cbi8qKlxuICogVmFsdWUgaXMgb3BhcXVlIHN0cmluZyB1cCB0byAyNTYgY2hhcmFjdGVycyBwcmludGFibGUgQVNDSUkgUkZDMDAyMFxuICogY2hhcmFjdGVycyAoaS5lLiwgdGhlIHJhbmdlIDB4MjAgdG8gMHg3RSkgZXhjZXB0IGNvbW1hICwgYW5kID0uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZVZhbHVlKHZhbHVlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIChcbiAgICBWQUxJRF9WQUxVRV9CQVNFX1JFR0VYLnRlc3QodmFsdWUpICYmXG4gICAgIUlOVkFMSURfVkFMVUVfQ09NTUFfRVFVQUxfUkVHRVgudGVzdCh2YWx1ZSlcbiAgKTtcbn1cbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5pbXBvcnQgeyBUcmFjZVN0YXRlIH0gZnJvbSAnLi4vdHJhY2Vfc3RhdGUnO1xuaW1wb3J0IHsgdmFsaWRhdGVLZXksIHZhbGlkYXRlVmFsdWUgfSBmcm9tICcuL3RyYWNlc3RhdGUtdmFsaWRhdG9ycyc7XG5cbmNvbnN0IE1BWF9UUkFDRV9TVEFURV9JVEVNUyA9IDMyO1xuY29uc3QgTUFYX1RSQUNFX1NUQVRFX0xFTiA9IDUxMjtcbmNvbnN0IExJU1RfTUVNQkVSU19TRVBBUkFUT1IgPSAnLCc7XG5jb25zdCBMSVNUX01FTUJFUl9LRVlfVkFMVUVfU1BMSVRURVIgPSAnPSc7XG5cbi8qKlxuICogVHJhY2VTdGF0ZSBtdXN0IGJlIGEgY2xhc3MgYW5kIG5vdCBhIHNpbXBsZSBvYmplY3QgdHlwZSBiZWNhdXNlIG9mIHRoZSBzcGVjXG4gKiByZXF1aXJlbWVudCAoaHR0cHM6Ly93d3cudzMub3JnL1RSL3RyYWNlLWNvbnRleHQvI3RyYWNlc3RhdGUtZmllbGQpLlxuICpcbiAqIEhlcmUgaXMgdGhlIGxpc3Qgb2YgYWxsb3dlZCBtdXRhdGlvbnM6XG4gKiAtIE5ldyBrZXktdmFsdWUgcGFpciBzaG91bGQgYmUgYWRkZWQgaW50byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBsaXN0XG4gKiAtIFRoZSB2YWx1ZSBvZiBhbnkga2V5IGNhbiBiZSB1cGRhdGVkLiBNb2RpZmllZCBrZXlzIE1VU1QgYmUgbW92ZWQgdG8gdGhlXG4gKiBiZWdpbm5pbmcgb2YgdGhlIGxpc3QuXG4gKi9cbmV4cG9ydCBjbGFzcyBUcmFjZVN0YXRlSW1wbCBpbXBsZW1lbnRzIFRyYWNlU3RhdGUge1xuICBwcml2YXRlIF9pbnRlcm5hbFN0YXRlOiBNYXA8c3RyaW5nLCBzdHJpbmc+ID0gbmV3IE1hcCgpO1xuXG4gIGNvbnN0cnVjdG9yKHJhd1RyYWNlU3RhdGU/OiBzdHJpbmcpIHtcbiAgICBpZiAocmF3VHJhY2VTdGF0ZSkgdGhpcy5fcGFyc2UocmF3VHJhY2VTdGF0ZSk7XG4gIH1cblxuICBzZXQoa2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpOiBUcmFjZVN0YXRlSW1wbCB7XG4gICAgLy8gVE9ETzogQmVuY2htYXJrIHRoZSBkaWZmZXJlbnQgYXBwcm9hY2hlcyhtYXAgdnMgbGlzdCkgYW5kXG4gICAgLy8gdXNlIHRoZSBmYXN0ZXIgb25lLlxuICAgIGNvbnN0IHRyYWNlU3RhdGUgPSB0aGlzLl9jbG9uZSgpO1xuICAgIGlmICh0cmFjZVN0YXRlLl9pbnRlcm5hbFN0YXRlLmhhcyhrZXkpKSB7XG4gICAgICB0cmFjZVN0YXRlLl9pbnRlcm5hbFN0YXRlLmRlbGV0ZShrZXkpO1xuICAgIH1cbiAgICB0cmFjZVN0YXRlLl9pbnRlcm5hbFN0YXRlLnNldChrZXksIHZhbHVlKTtcbiAgICByZXR1cm4gdHJhY2VTdGF0ZTtcbiAgfVxuXG4gIHVuc2V0KGtleTogc3RyaW5nKTogVHJhY2VTdGF0ZUltcGwge1xuICAgIGNvbnN0IHRyYWNlU3RhdGUgPSB0aGlzLl9jbG9uZSgpO1xuICAgIHRyYWNlU3RhdGUuX2ludGVybmFsU3RhdGUuZGVsZXRlKGtleSk7XG4gICAgcmV0dXJuIHRyYWNlU3RhdGU7XG4gIH1cblxuICBnZXQoa2V5OiBzdHJpbmcpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLl9pbnRlcm5hbFN0YXRlLmdldChrZXkpO1xuICB9XG5cbiAgc2VyaWFsaXplKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuX2tleXMoKVxuICAgICAgLnJlZHVjZSgoYWdnOiBzdHJpbmdbXSwga2V5KSA9PiB7XG4gICAgICAgIGFnZy5wdXNoKGtleSArIExJU1RfTUVNQkVSX0tFWV9WQUxVRV9TUExJVFRFUiArIHRoaXMuZ2V0KGtleSkpO1xuICAgICAgICByZXR1cm4gYWdnO1xuICAgICAgfSwgW10pXG4gICAgICAuam9pbihMSVNUX01FTUJFUlNfU0VQQVJBVE9SKTtcbiAgfVxuXG4gIHByaXZhdGUgX3BhcnNlKHJhd1RyYWNlU3RhdGU6IHN0cmluZykge1xuICAgIGlmIChyYXdUcmFjZVN0YXRlLmxlbmd0aCA+IE1BWF9UUkFDRV9TVEFURV9MRU4pIHJldHVybjtcbiAgICB0aGlzLl9pbnRlcm5hbFN0YXRlID0gcmF3VHJhY2VTdGF0ZVxuICAgICAgLnNwbGl0KExJU1RfTUVNQkVSU19TRVBBUkFUT1IpXG4gICAgICAucmV2ZXJzZSgpIC8vIFN0b3JlIGluIHJldmVyc2Ugc28gbmV3IGtleXMgKC5zZXQoLi4uKSkgd2lsbCBiZSBwbGFjZWQgYXQgdGhlIGJlZ2lubmluZ1xuICAgICAgLnJlZHVjZSgoYWdnOiBNYXA8c3RyaW5nLCBzdHJpbmc+LCBwYXJ0OiBzdHJpbmcpID0+IHtcbiAgICAgICAgY29uc3QgbGlzdE1lbWJlciA9IHBhcnQudHJpbSgpOyAvLyBPcHRpb25hbCBXaGl0ZXNwYWNlIChPV1MpIGhhbmRsaW5nXG4gICAgICAgIGNvbnN0IGkgPSBsaXN0TWVtYmVyLmluZGV4T2YoTElTVF9NRU1CRVJfS0VZX1ZBTFVFX1NQTElUVEVSKTtcbiAgICAgICAgaWYgKGkgIT09IC0xKSB7XG4gICAgICAgICAgY29uc3Qga2V5ID0gbGlzdE1lbWJlci5zbGljZSgwLCBpKTtcbiAgICAgICAgICBjb25zdCB2YWx1ZSA9IGxpc3RNZW1iZXIuc2xpY2UoaSArIDEsIHBhcnQubGVuZ3RoKTtcbiAgICAgICAgICBpZiAodmFsaWRhdGVLZXkoa2V5KSAmJiB2YWxpZGF0ZVZhbHVlKHZhbHVlKSkge1xuICAgICAgICAgICAgYWdnLnNldChrZXksIHZhbHVlKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gVE9ETzogQ29uc2lkZXIgdG8gYWRkIHdhcm5pbmcgbG9nXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhZ2c7XG4gICAgICB9LCBuZXcgTWFwKCkpO1xuXG4gICAgLy8gQmVjYXVzZSBvZiB0aGUgcmV2ZXJzZSgpIHJlcXVpcmVtZW50LCB0cnVuYyBtdXN0IGJlIGRvbmUgYWZ0ZXIgbWFwIGlzIGNyZWF0ZWRcbiAgICBpZiAodGhpcy5faW50ZXJuYWxTdGF0ZS5zaXplID4gTUFYX1RSQUNFX1NUQVRFX0lURU1TKSB7XG4gICAgICB0aGlzLl9pbnRlcm5hbFN0YXRlID0gbmV3IE1hcChcbiAgICAgICAgQXJyYXkuZnJvbSh0aGlzLl9pbnRlcm5hbFN0YXRlLmVudHJpZXMoKSlcbiAgICAgICAgICAucmV2ZXJzZSgpIC8vIFVzZSByZXZlcnNlIHNhbWUgYXMgb3JpZ2luYWwgdHJhY2VzdGF0ZSBwYXJzZSBjaGFpblxuICAgICAgICAgIC5zbGljZSgwLCBNQVhfVFJBQ0VfU1RBVEVfSVRFTVMpXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2tleXMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMuX2ludGVybmFsU3RhdGUua2V5cygpKS5yZXZlcnNlKCk7XG4gIH1cblxuICBwcml2YXRlIF9jbG9uZSgpOiBUcmFjZVN0YXRlSW1wbCB7XG4gICAgY29uc3QgdHJhY2VTdGF0ZSA9IG5ldyBUcmFjZVN0YXRlSW1wbCgpO1xuICAgIHRyYWNlU3RhdGUuX2ludGVybmFsU3RhdGUgPSBuZXcgTWFwKHRoaXMuX2ludGVybmFsU3RhdGUpO1xuICAgIHJldHVybiB0cmFjZVN0YXRlO1xuICB9XG59XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuaW1wb3J0IHsgVHJhY2VTdGF0ZSB9IGZyb20gJy4uL3RyYWNlX3N0YXRlJztcbmltcG9ydCB7IFRyYWNlU3RhdGVJbXBsIH0gZnJvbSAnLi90cmFjZXN0YXRlLWltcGwnO1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlVHJhY2VTdGF0ZShyYXdUcmFjZVN0YXRlPzogc3RyaW5nKTogVHJhY2VTdGF0ZSB7XG4gIHJldHVybiBuZXcgVHJhY2VTdGF0ZUltcGwocmF3VHJhY2VTdGF0ZSk7XG59XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuLy8gU3BsaXQgbW9kdWxlLWxldmVsIHZhcmlhYmxlIGRlZmluaXRpb24gaW50byBzZXBhcmF0ZSBmaWxlcyB0byBhbGxvd1xuLy8gdHJlZS1zaGFraW5nIG9uIGVhY2ggYXBpIGluc3RhbmNlLlxuaW1wb3J0IHsgQ29udGV4dEFQSSB9IGZyb20gJy4vYXBpL2NvbnRleHQnO1xuLyoqIEVudHJ5cG9pbnQgZm9yIGNvbnRleHQgQVBJICovXG5leHBvcnQgY29uc3QgY29udGV4dCA9IENvbnRleHRBUEkuZ2V0SW5zdGFuY2UoKTtcbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG4vLyBTcGxpdCBtb2R1bGUtbGV2ZWwgdmFyaWFibGUgZGVmaW5pdGlvbiBpbnRvIHNlcGFyYXRlIGZpbGVzIHRvIGFsbG93XG4vLyB0cmVlLXNoYWtpbmcgb24gZWFjaCBhcGkgaW5zdGFuY2UuXG5pbXBvcnQgeyBEaWFnQVBJIH0gZnJvbSAnLi9hcGkvZGlhZyc7XG4vKipcbiAqIEVudHJ5cG9pbnQgZm9yIERpYWcgQVBJLlxuICogRGVmaW5lcyBEaWFnbm9zdGljIGhhbmRsZXIgdXNlZCBmb3IgaW50ZXJuYWwgZGlhZ25vc3RpYyBsb2dnaW5nIG9wZXJhdGlvbnMuXG4gKiBUaGUgZGVmYXVsdCBwcm92aWRlcyBhIE5vb3AgRGlhZ0xvZ2dlciBpbXBsZW1lbnRhdGlvbiB3aGljaCBtYXkgYmUgY2hhbmdlZCB2aWEgdGhlXG4gKiBkaWFnLnNldExvZ2dlcihsb2dnZXI6IERpYWdMb2dnZXIpIGZ1bmN0aW9uLlxuICovXG5leHBvcnQgY29uc3QgZGlhZyA9IERpYWdBUEkuaW5zdGFuY2UoKTtcbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5pbXBvcnQgeyBNZXRlciwgTWV0ZXJPcHRpb25zIH0gZnJvbSAnLi9NZXRlcic7XG5pbXBvcnQgeyBNZXRlclByb3ZpZGVyIH0gZnJvbSAnLi9NZXRlclByb3ZpZGVyJztcbmltcG9ydCB7IE5PT1BfTUVURVIgfSBmcm9tICcuL05vb3BNZXRlcic7XG5cbi8qKlxuICogQW4gaW1wbGVtZW50YXRpb24gb2YgdGhlIHtAbGluayBNZXRlclByb3ZpZGVyfSB3aGljaCByZXR1cm5zIGFuIGltcG90ZW50IE1ldGVyXG4gKiBmb3IgYWxsIGNhbGxzIHRvIGBnZXRNZXRlcmBcbiAqL1xuZXhwb3J0IGNsYXNzIE5vb3BNZXRlclByb3ZpZGVyIGltcGxlbWVudHMgTWV0ZXJQcm92aWRlciB7XG4gIGdldE1ldGVyKF9uYW1lOiBzdHJpbmcsIF92ZXJzaW9uPzogc3RyaW5nLCBfb3B0aW9ucz86IE1ldGVyT3B0aW9ucyk6IE1ldGVyIHtcbiAgICByZXR1cm4gTk9PUF9NRVRFUjtcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgTk9PUF9NRVRFUl9QUk9WSURFUiA9IG5ldyBOb29wTWV0ZXJQcm92aWRlcigpO1xuIiwgIi8qXG4gKiBDb3B5cmlnaHQgVGhlIE9wZW5UZWxlbWV0cnkgQXV0aG9yc1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgIGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IE1ldGVyLCBNZXRlck9wdGlvbnMgfSBmcm9tICcuLi9tZXRyaWNzL01ldGVyJztcbmltcG9ydCB7IE1ldGVyUHJvdmlkZXIgfSBmcm9tICcuLi9tZXRyaWNzL01ldGVyUHJvdmlkZXInO1xuaW1wb3J0IHsgTk9PUF9NRVRFUl9QUk9WSURFUiB9IGZyb20gJy4uL21ldHJpY3MvTm9vcE1ldGVyUHJvdmlkZXInO1xuaW1wb3J0IHtcbiAgZ2V0R2xvYmFsLFxuICByZWdpc3Rlckdsb2JhbCxcbiAgdW5yZWdpc3Rlckdsb2JhbCxcbn0gZnJvbSAnLi4vaW50ZXJuYWwvZ2xvYmFsLXV0aWxzJztcbmltcG9ydCB7IERpYWdBUEkgfSBmcm9tICcuL2RpYWcnO1xuXG5jb25zdCBBUElfTkFNRSA9ICdtZXRyaWNzJztcblxuLyoqXG4gKiBTaW5nbGV0b24gb2JqZWN0IHdoaWNoIHJlcHJlc2VudHMgdGhlIGVudHJ5IHBvaW50IHRvIHRoZSBPcGVuVGVsZW1ldHJ5IE1ldHJpY3MgQVBJXG4gKi9cbmV4cG9ydCBjbGFzcyBNZXRyaWNzQVBJIHtcbiAgcHJpdmF0ZSBzdGF0aWMgX2luc3RhbmNlPzogTWV0cmljc0FQSTtcblxuICAvKiogRW1wdHkgcHJpdmF0ZSBjb25zdHJ1Y3RvciBwcmV2ZW50cyBlbmQgdXNlcnMgZnJvbSBjb25zdHJ1Y3RpbmcgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIEFQSSAqL1xuICBwcml2YXRlIGNvbnN0cnVjdG9yKCkge31cblxuICAvKiogR2V0IHRoZSBzaW5nbGV0b24gaW5zdGFuY2Ugb2YgdGhlIE1ldHJpY3MgQVBJICovXG4gIHB1YmxpYyBzdGF0aWMgZ2V0SW5zdGFuY2UoKTogTWV0cmljc0FQSSB7XG4gICAgaWYgKCF0aGlzLl9pbnN0YW5jZSkge1xuICAgICAgdGhpcy5faW5zdGFuY2UgPSBuZXcgTWV0cmljc0FQSSgpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9pbnN0YW5jZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgdGhlIGN1cnJlbnQgZ2xvYmFsIG1ldGVyIHByb3ZpZGVyLlxuICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIG1ldGVyIHByb3ZpZGVyIHdhcyBzdWNjZXNzZnVsbHkgcmVnaXN0ZXJlZCwgZWxzZSBmYWxzZS5cbiAgICovXG4gIHB1YmxpYyBzZXRHbG9iYWxNZXRlclByb3ZpZGVyKHByb3ZpZGVyOiBNZXRlclByb3ZpZGVyKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHJlZ2lzdGVyR2xvYmFsKEFQSV9OQU1FLCBwcm92aWRlciwgRGlhZ0FQSS5pbnN0YW5jZSgpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBnbG9iYWwgbWV0ZXIgcHJvdmlkZXIuXG4gICAqL1xuICBwdWJsaWMgZ2V0TWV0ZXJQcm92aWRlcigpOiBNZXRlclByb3ZpZGVyIHtcbiAgICByZXR1cm4gZ2V0R2xvYmFsKEFQSV9OQU1FKSB8fCBOT09QX01FVEVSX1BST1ZJREVSO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBtZXRlciBmcm9tIHRoZSBnbG9iYWwgbWV0ZXIgcHJvdmlkZXIuXG4gICAqL1xuICBwdWJsaWMgZ2V0TWV0ZXIoXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIHZlcnNpb24/OiBzdHJpbmcsXG4gICAgb3B0aW9ucz86IE1ldGVyT3B0aW9uc1xuICApOiBNZXRlciB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0TWV0ZXJQcm92aWRlcigpLmdldE1ldGVyKG5hbWUsIHZlcnNpb24sIG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqIFJlbW92ZSB0aGUgZ2xvYmFsIG1ldGVyIHByb3ZpZGVyICovXG4gIHB1YmxpYyBkaXNhYmxlKCk6IHZvaWQge1xuICAgIHVucmVnaXN0ZXJHbG9iYWwoQVBJX05BTUUsIERpYWdBUEkuaW5zdGFuY2UoKSk7XG4gIH1cbn1cbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG4vLyBTcGxpdCBtb2R1bGUtbGV2ZWwgdmFyaWFibGUgZGVmaW5pdGlvbiBpbnRvIHNlcGFyYXRlIGZpbGVzIHRvIGFsbG93XG4vLyB0cmVlLXNoYWtpbmcgb24gZWFjaCBhcGkgaW5zdGFuY2UuXG5pbXBvcnQgeyBNZXRyaWNzQVBJIH0gZnJvbSAnLi9hcGkvbWV0cmljcyc7XG4vKiogRW50cnlwb2ludCBmb3IgbWV0cmljcyBBUEkgKi9cbmV4cG9ydCBjb25zdCBtZXRyaWNzID0gTWV0cmljc0FQSS5nZXRJbnN0YW5jZSgpO1xuIiwgIi8qXG4gKiBDb3B5cmlnaHQgVGhlIE9wZW5UZWxlbWV0cnkgQXV0aG9yc1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgIGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IENvbnRleHQgfSBmcm9tICcuLi9jb250ZXh0L3R5cGVzJztcbmltcG9ydCB7IFRleHRNYXBQcm9wYWdhdG9yIH0gZnJvbSAnLi9UZXh0TWFwUHJvcGFnYXRvcic7XG5cbi8qKlxuICogTm8tb3AgaW1wbGVtZW50YXRpb25zIG9mIHtAbGluayBUZXh0TWFwUHJvcGFnYXRvcn0uXG4gKi9cbmV4cG9ydCBjbGFzcyBOb29wVGV4dE1hcFByb3BhZ2F0b3IgaW1wbGVtZW50cyBUZXh0TWFwUHJvcGFnYXRvciB7XG4gIC8qKiBOb29wIGluamVjdCBmdW5jdGlvbiBkb2VzIG5vdGhpbmcgKi9cbiAgaW5qZWN0KF9jb250ZXh0OiBDb250ZXh0LCBfY2FycmllcjogdW5rbm93bik6IHZvaWQge31cbiAgLyoqIE5vb3AgZXh0cmFjdCBmdW5jdGlvbiBkb2VzIG5vdGhpbmcgYW5kIHJldHVybnMgdGhlIGlucHV0IGNvbnRleHQgKi9cbiAgZXh0cmFjdChjb250ZXh0OiBDb250ZXh0LCBfY2FycmllcjogdW5rbm93bik6IENvbnRleHQge1xuICAgIHJldHVybiBjb250ZXh0O1xuICB9XG4gIGZpZWxkcygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG59XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuaW1wb3J0IHsgQ29udGV4dEFQSSB9IGZyb20gJy4uL2FwaS9jb250ZXh0JztcbmltcG9ydCB7IGNyZWF0ZUNvbnRleHRLZXkgfSBmcm9tICcuLi9jb250ZXh0L2NvbnRleHQnO1xuaW1wb3J0IHsgQ29udGV4dCB9IGZyb20gJy4uL2NvbnRleHQvdHlwZXMnO1xuaW1wb3J0IHsgQmFnZ2FnZSB9IGZyb20gJy4vdHlwZXMnO1xuXG4vKipcbiAqIEJhZ2dhZ2Uga2V5XG4gKi9cbmNvbnN0IEJBR0dBR0VfS0VZID0gY3JlYXRlQ29udGV4dEtleSgnT3BlblRlbGVtZXRyeSBCYWdnYWdlIEtleScpO1xuXG4vKipcbiAqIFJldHJpZXZlIHRoZSBjdXJyZW50IGJhZ2dhZ2UgZnJvbSB0aGUgZ2l2ZW4gY29udGV4dFxuICpcbiAqIEBwYXJhbSB7Q29udGV4dH0gQ29udGV4dCB0aGF0IG1hbmFnZSBhbGwgY29udGV4dCB2YWx1ZXNcbiAqIEByZXR1cm5zIHtCYWdnYWdlfSBFeHRyYWN0ZWQgYmFnZ2FnZSBmcm9tIHRoZSBjb250ZXh0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRCYWdnYWdlKGNvbnRleHQ6IENvbnRleHQpOiBCYWdnYWdlIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIChjb250ZXh0LmdldFZhbHVlKEJBR0dBR0VfS0VZKSBhcyBCYWdnYWdlKSB8fCB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogUmV0cmlldmUgdGhlIGN1cnJlbnQgYmFnZ2FnZSBmcm9tIHRoZSBhY3RpdmUvY3VycmVudCBjb250ZXh0XG4gKlxuICogQHJldHVybnMge0JhZ2dhZ2V9IEV4dHJhY3RlZCBiYWdnYWdlIGZyb20gdGhlIGNvbnRleHRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEFjdGl2ZUJhZ2dhZ2UoKTogQmFnZ2FnZSB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiBnZXRCYWdnYWdlKENvbnRleHRBUEkuZ2V0SW5zdGFuY2UoKS5hY3RpdmUoKSk7XG59XG5cbi8qKlxuICogU3RvcmUgYSBiYWdnYWdlIGluIHRoZSBnaXZlbiBjb250ZXh0XG4gKlxuICogQHBhcmFtIHtDb250ZXh0fSBDb250ZXh0IHRoYXQgbWFuYWdlIGFsbCBjb250ZXh0IHZhbHVlc1xuICogQHBhcmFtIHtCYWdnYWdlfSBiYWdnYWdlIHRoYXQgd2lsbCBiZSBzZXQgaW4gdGhlIGFjdHVhbCBjb250ZXh0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRCYWdnYWdlKGNvbnRleHQ6IENvbnRleHQsIGJhZ2dhZ2U6IEJhZ2dhZ2UpOiBDb250ZXh0IHtcbiAgcmV0dXJuIGNvbnRleHQuc2V0VmFsdWUoQkFHR0FHRV9LRVksIGJhZ2dhZ2UpO1xufVxuXG4vKipcbiAqIERlbGV0ZSB0aGUgYmFnZ2FnZSBzdG9yZWQgaW4gdGhlIGdpdmVuIGNvbnRleHRcbiAqXG4gKiBAcGFyYW0ge0NvbnRleHR9IENvbnRleHQgdGhhdCBtYW5hZ2UgYWxsIGNvbnRleHQgdmFsdWVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWxldGVCYWdnYWdlKGNvbnRleHQ6IENvbnRleHQpOiBDb250ZXh0IHtcbiAgcmV0dXJuIGNvbnRleHQuZGVsZXRlVmFsdWUoQkFHR0FHRV9LRVkpO1xufVxuIiwgIi8qXG4gKiBDb3B5cmlnaHQgVGhlIE9wZW5UZWxlbWV0cnkgQXV0aG9yc1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgIGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IENvbnRleHQgfSBmcm9tICcuLi9jb250ZXh0L3R5cGVzJztcbmltcG9ydCB7XG4gIGdldEdsb2JhbCxcbiAgcmVnaXN0ZXJHbG9iYWwsXG4gIHVucmVnaXN0ZXJHbG9iYWwsXG59IGZyb20gJy4uL2ludGVybmFsL2dsb2JhbC11dGlscyc7XG5pbXBvcnQgeyBOb29wVGV4dE1hcFByb3BhZ2F0b3IgfSBmcm9tICcuLi9wcm9wYWdhdGlvbi9Ob29wVGV4dE1hcFByb3BhZ2F0b3InO1xuaW1wb3J0IHtcbiAgZGVmYXVsdFRleHRNYXBHZXR0ZXIsXG4gIGRlZmF1bHRUZXh0TWFwU2V0dGVyLFxuICBUZXh0TWFwR2V0dGVyLFxuICBUZXh0TWFwUHJvcGFnYXRvcixcbiAgVGV4dE1hcFNldHRlcixcbn0gZnJvbSAnLi4vcHJvcGFnYXRpb24vVGV4dE1hcFByb3BhZ2F0b3InO1xuaW1wb3J0IHtcbiAgZ2V0QmFnZ2FnZSxcbiAgZ2V0QWN0aXZlQmFnZ2FnZSxcbiAgc2V0QmFnZ2FnZSxcbiAgZGVsZXRlQmFnZ2FnZSxcbn0gZnJvbSAnLi4vYmFnZ2FnZS9jb250ZXh0LWhlbHBlcnMnO1xuaW1wb3J0IHsgY3JlYXRlQmFnZ2FnZSB9IGZyb20gJy4uL2JhZ2dhZ2UvdXRpbHMnO1xuaW1wb3J0IHsgRGlhZ0FQSSB9IGZyb20gJy4vZGlhZyc7XG5cbmNvbnN0IEFQSV9OQU1FID0gJ3Byb3BhZ2F0aW9uJztcbmNvbnN0IE5PT1BfVEVYVF9NQVBfUFJPUEFHQVRPUiA9IG5ldyBOb29wVGV4dE1hcFByb3BhZ2F0b3IoKTtcblxuLyoqXG4gKiBTaW5nbGV0b24gb2JqZWN0IHdoaWNoIHJlcHJlc2VudHMgdGhlIGVudHJ5IHBvaW50IHRvIHRoZSBPcGVuVGVsZW1ldHJ5IFByb3BhZ2F0aW9uIEFQSVxuICovXG5leHBvcnQgY2xhc3MgUHJvcGFnYXRpb25BUEkge1xuICBwcml2YXRlIHN0YXRpYyBfaW5zdGFuY2U/OiBQcm9wYWdhdGlvbkFQSTtcblxuICAvKiogRW1wdHkgcHJpdmF0ZSBjb25zdHJ1Y3RvciBwcmV2ZW50cyBlbmQgdXNlcnMgZnJvbSBjb25zdHJ1Y3RpbmcgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIEFQSSAqL1xuICBwcml2YXRlIGNvbnN0cnVjdG9yKCkge31cblxuICAvKiogR2V0IHRoZSBzaW5nbGV0b24gaW5zdGFuY2Ugb2YgdGhlIFByb3BhZ2F0b3IgQVBJICovXG4gIHB1YmxpYyBzdGF0aWMgZ2V0SW5zdGFuY2UoKTogUHJvcGFnYXRpb25BUEkge1xuICAgIGlmICghdGhpcy5faW5zdGFuY2UpIHtcbiAgICAgIHRoaXMuX2luc3RhbmNlID0gbmV3IFByb3BhZ2F0aW9uQVBJKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX2luc3RhbmNlO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldCB0aGUgY3VycmVudCBwcm9wYWdhdG9yLlxuICAgKlxuICAgKiBAcmV0dXJucyB0cnVlIGlmIHRoZSBwcm9wYWdhdG9yIHdhcyBzdWNjZXNzZnVsbHkgcmVnaXN0ZXJlZCwgZWxzZSBmYWxzZVxuICAgKi9cbiAgcHVibGljIHNldEdsb2JhbFByb3BhZ2F0b3IocHJvcGFnYXRvcjogVGV4dE1hcFByb3BhZ2F0b3IpOiBib29sZWFuIHtcbiAgICByZXR1cm4gcmVnaXN0ZXJHbG9iYWwoQVBJX05BTUUsIHByb3BhZ2F0b3IsIERpYWdBUEkuaW5zdGFuY2UoKSk7XG4gIH1cblxuICAvKipcbiAgICogSW5qZWN0IGNvbnRleHQgaW50byBhIGNhcnJpZXIgdG8gYmUgcHJvcGFnYXRlZCBpbnRlci1wcm9jZXNzXG4gICAqXG4gICAqIEBwYXJhbSBjb250ZXh0IENvbnRleHQgY2FycnlpbmcgdHJhY2luZyBkYXRhIHRvIGluamVjdFxuICAgKiBAcGFyYW0gY2FycmllciBjYXJyaWVyIHRvIGluamVjdCBjb250ZXh0IGludG9cbiAgICogQHBhcmFtIHNldHRlciBGdW5jdGlvbiB1c2VkIHRvIHNldCB2YWx1ZXMgb24gdGhlIGNhcnJpZXJcbiAgICovXG4gIHB1YmxpYyBpbmplY3Q8Q2Fycmllcj4oXG4gICAgY29udGV4dDogQ29udGV4dCxcbiAgICBjYXJyaWVyOiBDYXJyaWVyLFxuICAgIHNldHRlcjogVGV4dE1hcFNldHRlcjxDYXJyaWVyPiA9IGRlZmF1bHRUZXh0TWFwU2V0dGVyXG4gICk6IHZvaWQge1xuICAgIHJldHVybiB0aGlzLl9nZXRHbG9iYWxQcm9wYWdhdG9yKCkuaW5qZWN0KGNvbnRleHQsIGNhcnJpZXIsIHNldHRlcik7XG4gIH1cblxuICAvKipcbiAgICogRXh0cmFjdCBjb250ZXh0IGZyb20gYSBjYXJyaWVyXG4gICAqXG4gICAqIEBwYXJhbSBjb250ZXh0IENvbnRleHQgd2hpY2ggdGhlIG5ld2x5IGNyZWF0ZWQgY29udGV4dCB3aWxsIGluaGVyaXQgZnJvbVxuICAgKiBAcGFyYW0gY2FycmllciBDYXJyaWVyIHRvIGV4dHJhY3QgY29udGV4dCBmcm9tXG4gICAqIEBwYXJhbSBnZXR0ZXIgRnVuY3Rpb24gdXNlZCB0byBleHRyYWN0IGtleXMgZnJvbSBhIGNhcnJpZXJcbiAgICovXG4gIHB1YmxpYyBleHRyYWN0PENhcnJpZXI+KFxuICAgIGNvbnRleHQ6IENvbnRleHQsXG4gICAgY2FycmllcjogQ2FycmllcixcbiAgICBnZXR0ZXI6IFRleHRNYXBHZXR0ZXI8Q2Fycmllcj4gPSBkZWZhdWx0VGV4dE1hcEdldHRlclxuICApOiBDb250ZXh0IHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0R2xvYmFsUHJvcGFnYXRvcigpLmV4dHJhY3QoY29udGV4dCwgY2FycmllciwgZ2V0dGVyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYSBsaXN0IG9mIGFsbCBmaWVsZHMgd2hpY2ggbWF5IGJlIHVzZWQgYnkgdGhlIHByb3BhZ2F0b3IuXG4gICAqL1xuICBwdWJsaWMgZmllbGRzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0R2xvYmFsUHJvcGFnYXRvcigpLmZpZWxkcygpO1xuICB9XG5cbiAgLyoqIFJlbW92ZSB0aGUgZ2xvYmFsIHByb3BhZ2F0b3IgKi9cbiAgcHVibGljIGRpc2FibGUoKSB7XG4gICAgdW5yZWdpc3Rlckdsb2JhbChBUElfTkFNRSwgRGlhZ0FQSS5pbnN0YW5jZSgpKTtcbiAgfVxuXG4gIHB1YmxpYyBjcmVhdGVCYWdnYWdlID0gY3JlYXRlQmFnZ2FnZTtcblxuICBwdWJsaWMgZ2V0QmFnZ2FnZSA9IGdldEJhZ2dhZ2U7XG5cbiAgcHVibGljIGdldEFjdGl2ZUJhZ2dhZ2UgPSBnZXRBY3RpdmVCYWdnYWdlO1xuXG4gIHB1YmxpYyBzZXRCYWdnYWdlID0gc2V0QmFnZ2FnZTtcblxuICBwdWJsaWMgZGVsZXRlQmFnZ2FnZSA9IGRlbGV0ZUJhZ2dhZ2U7XG5cbiAgcHJpdmF0ZSBfZ2V0R2xvYmFsUHJvcGFnYXRvcigpOiBUZXh0TWFwUHJvcGFnYXRvciB7XG4gICAgcmV0dXJuIGdldEdsb2JhbChBUElfTkFNRSkgfHwgTk9PUF9URVhUX01BUF9QUk9QQUdBVE9SO1xuICB9XG59XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuLy8gU3BsaXQgbW9kdWxlLWxldmVsIHZhcmlhYmxlIGRlZmluaXRpb24gaW50byBzZXBhcmF0ZSBmaWxlcyB0byBhbGxvd1xuLy8gdHJlZS1zaGFraW5nIG9uIGVhY2ggYXBpIGluc3RhbmNlLlxuaW1wb3J0IHsgUHJvcGFnYXRpb25BUEkgfSBmcm9tICcuL2FwaS9wcm9wYWdhdGlvbic7XG4vKiogRW50cnlwb2ludCBmb3IgcHJvcGFnYXRpb24gQVBJICovXG5leHBvcnQgY29uc3QgcHJvcGFnYXRpb24gPSBQcm9wYWdhdGlvbkFQSS5nZXRJbnN0YW5jZSgpO1xuIiwgIi8qXG4gKiBDb3B5cmlnaHQgVGhlIE9wZW5UZWxlbWV0cnkgQXV0aG9yc1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgIGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7XG4gIGdldEdsb2JhbCxcbiAgcmVnaXN0ZXJHbG9iYWwsXG4gIHVucmVnaXN0ZXJHbG9iYWwsXG59IGZyb20gJy4uL2ludGVybmFsL2dsb2JhbC11dGlscyc7XG5pbXBvcnQgeyBQcm94eVRyYWNlclByb3ZpZGVyIH0gZnJvbSAnLi4vdHJhY2UvUHJveHlUcmFjZXJQcm92aWRlcic7XG5pbXBvcnQge1xuICBpc1NwYW5Db250ZXh0VmFsaWQsXG4gIHdyYXBTcGFuQ29udGV4dCxcbn0gZnJvbSAnLi4vdHJhY2Uvc3BhbmNvbnRleHQtdXRpbHMnO1xuaW1wb3J0IHsgVHJhY2VyIH0gZnJvbSAnLi4vdHJhY2UvdHJhY2VyJztcbmltcG9ydCB7IFRyYWNlclByb3ZpZGVyIH0gZnJvbSAnLi4vdHJhY2UvdHJhY2VyX3Byb3ZpZGVyJztcbmltcG9ydCB7XG4gIGRlbGV0ZVNwYW4sXG4gIGdldEFjdGl2ZVNwYW4sXG4gIGdldFNwYW4sXG4gIGdldFNwYW5Db250ZXh0LFxuICBzZXRTcGFuLFxuICBzZXRTcGFuQ29udGV4dCxcbn0gZnJvbSAnLi4vdHJhY2UvY29udGV4dC11dGlscyc7XG5pbXBvcnQgeyBEaWFnQVBJIH0gZnJvbSAnLi9kaWFnJztcblxuY29uc3QgQVBJX05BTUUgPSAndHJhY2UnO1xuXG4vKipcbiAqIFNpbmdsZXRvbiBvYmplY3Qgd2hpY2ggcmVwcmVzZW50cyB0aGUgZW50cnkgcG9pbnQgdG8gdGhlIE9wZW5UZWxlbWV0cnkgVHJhY2luZyBBUElcbiAqL1xuZXhwb3J0IGNsYXNzIFRyYWNlQVBJIHtcbiAgcHJpdmF0ZSBzdGF0aWMgX2luc3RhbmNlPzogVHJhY2VBUEk7XG5cbiAgcHJpdmF0ZSBfcHJveHlUcmFjZXJQcm92aWRlciA9IG5ldyBQcm94eVRyYWNlclByb3ZpZGVyKCk7XG5cbiAgLyoqIEVtcHR5IHByaXZhdGUgY29uc3RydWN0b3IgcHJldmVudHMgZW5kIHVzZXJzIGZyb20gY29uc3RydWN0aW5nIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBBUEkgKi9cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgLyoqIEdldCB0aGUgc2luZ2xldG9uIGluc3RhbmNlIG9mIHRoZSBUcmFjZSBBUEkgKi9cbiAgcHVibGljIHN0YXRpYyBnZXRJbnN0YW5jZSgpOiBUcmFjZUFQSSB7XG4gICAgaWYgKCF0aGlzLl9pbnN0YW5jZSkge1xuICAgICAgdGhpcy5faW5zdGFuY2UgPSBuZXcgVHJhY2VBUEkoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5faW5zdGFuY2U7XG4gIH1cblxuICAvKipcbiAgICogU2V0IHRoZSBjdXJyZW50IGdsb2JhbCB0cmFjZXIuXG4gICAqXG4gICAqIEByZXR1cm5zIHRydWUgaWYgdGhlIHRyYWNlciBwcm92aWRlciB3YXMgc3VjY2Vzc2Z1bGx5IHJlZ2lzdGVyZWQsIGVsc2UgZmFsc2VcbiAgICovXG4gIHB1YmxpYyBzZXRHbG9iYWxUcmFjZXJQcm92aWRlcihwcm92aWRlcjogVHJhY2VyUHJvdmlkZXIpOiBib29sZWFuIHtcbiAgICBjb25zdCBzdWNjZXNzID0gcmVnaXN0ZXJHbG9iYWwoXG4gICAgICBBUElfTkFNRSxcbiAgICAgIHRoaXMuX3Byb3h5VHJhY2VyUHJvdmlkZXIsXG4gICAgICBEaWFnQVBJLmluc3RhbmNlKClcbiAgICApO1xuICAgIGlmIChzdWNjZXNzKSB7XG4gICAgICB0aGlzLl9wcm94eVRyYWNlclByb3ZpZGVyLnNldERlbGVnYXRlKHByb3ZpZGVyKTtcbiAgICB9XG4gICAgcmV0dXJuIHN1Y2Nlc3M7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgZ2xvYmFsIHRyYWNlciBwcm92aWRlci5cbiAgICovXG4gIHB1YmxpYyBnZXRUcmFjZXJQcm92aWRlcigpOiBUcmFjZXJQcm92aWRlciB7XG4gICAgcmV0dXJuIGdldEdsb2JhbChBUElfTkFNRSkgfHwgdGhpcy5fcHJveHlUcmFjZXJQcm92aWRlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgdHJhY2VyIGZyb20gdGhlIGdsb2JhbCB0cmFjZXIgcHJvdmlkZXIuXG4gICAqL1xuICBwdWJsaWMgZ2V0VHJhY2VyKG5hbWU6IHN0cmluZywgdmVyc2lvbj86IHN0cmluZyk6IFRyYWNlciB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0VHJhY2VyUHJvdmlkZXIoKS5nZXRUcmFjZXIobmFtZSwgdmVyc2lvbik7XG4gIH1cblxuICAvKiogUmVtb3ZlIHRoZSBnbG9iYWwgdHJhY2VyIHByb3ZpZGVyICovXG4gIHB1YmxpYyBkaXNhYmxlKCkge1xuICAgIHVucmVnaXN0ZXJHbG9iYWwoQVBJX05BTUUsIERpYWdBUEkuaW5zdGFuY2UoKSk7XG4gICAgdGhpcy5fcHJveHlUcmFjZXJQcm92aWRlciA9IG5ldyBQcm94eVRyYWNlclByb3ZpZGVyKCk7XG4gIH1cblxuICBwdWJsaWMgd3JhcFNwYW5Db250ZXh0ID0gd3JhcFNwYW5Db250ZXh0O1xuXG4gIHB1YmxpYyBpc1NwYW5Db250ZXh0VmFsaWQgPSBpc1NwYW5Db250ZXh0VmFsaWQ7XG5cbiAgcHVibGljIGRlbGV0ZVNwYW4gPSBkZWxldGVTcGFuO1xuXG4gIHB1YmxpYyBnZXRTcGFuID0gZ2V0U3BhbjtcblxuICBwdWJsaWMgZ2V0QWN0aXZlU3BhbiA9IGdldEFjdGl2ZVNwYW47XG5cbiAgcHVibGljIGdldFNwYW5Db250ZXh0ID0gZ2V0U3BhbkNvbnRleHQ7XG5cbiAgcHVibGljIHNldFNwYW4gPSBzZXRTcGFuO1xuXG4gIHB1YmxpYyBzZXRTcGFuQ29udGV4dCA9IHNldFNwYW5Db250ZXh0O1xufVxuIiwgIi8qXG4gKiBDb3B5cmlnaHQgVGhlIE9wZW5UZWxlbWV0cnkgQXV0aG9yc1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgIGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbi8vIFNwbGl0IG1vZHVsZS1sZXZlbCB2YXJpYWJsZSBkZWZpbml0aW9uIGludG8gc2VwYXJhdGUgZmlsZXMgdG8gYWxsb3dcbi8vIHRyZWUtc2hha2luZyBvbiBlYWNoIGFwaSBpbnN0YW5jZS5cbmltcG9ydCB7IFRyYWNlQVBJIH0gZnJvbSAnLi9hcGkvdHJhY2UnO1xuLyoqIEVudHJ5cG9pbnQgZm9yIHRyYWNlIEFQSSAqL1xuZXhwb3J0IGNvbnN0IHRyYWNlID0gVHJhY2VBUEkuZ2V0SW5zdGFuY2UoKTtcbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5leHBvcnQgeyBCYWdnYWdlRW50cnksIEJhZ2dhZ2VFbnRyeU1ldGFkYXRhLCBCYWdnYWdlIH0gZnJvbSAnLi9iYWdnYWdlL3R5cGVzJztcbmV4cG9ydCB7IGJhZ2dhZ2VFbnRyeU1ldGFkYXRhRnJvbVN0cmluZyB9IGZyb20gJy4vYmFnZ2FnZS91dGlscyc7XG5leHBvcnQgeyBFeGNlcHRpb24gfSBmcm9tICcuL2NvbW1vbi9FeGNlcHRpb24nO1xuZXhwb3J0IHsgSHJUaW1lLCBUaW1lSW5wdXQgfSBmcm9tICcuL2NvbW1vbi9UaW1lJztcbmV4cG9ydCB7IEF0dHJpYnV0ZXMsIEF0dHJpYnV0ZVZhbHVlIH0gZnJvbSAnLi9jb21tb24vQXR0cmlidXRlcyc7XG5cbi8vIENvbnRleHQgQVBJc1xuZXhwb3J0IHsgY3JlYXRlQ29udGV4dEtleSwgUk9PVF9DT05URVhUIH0gZnJvbSAnLi9jb250ZXh0L2NvbnRleHQnO1xuZXhwb3J0IHsgQ29udGV4dCwgQ29udGV4dE1hbmFnZXIgfSBmcm9tICcuL2NvbnRleHQvdHlwZXMnO1xuZXhwb3J0IHR5cGUgeyBDb250ZXh0QVBJIH0gZnJvbSAnLi9hcGkvY29udGV4dCc7XG5cbi8vIERpYWcgQVBJc1xuZXhwb3J0IHsgRGlhZ0NvbnNvbGVMb2dnZXIgfSBmcm9tICcuL2RpYWcvY29uc29sZUxvZ2dlcic7XG5leHBvcnQge1xuICBEaWFnTG9nRnVuY3Rpb24sXG4gIERpYWdMb2dnZXIsXG4gIERpYWdMb2dMZXZlbCxcbiAgQ29tcG9uZW50TG9nZ2VyT3B0aW9ucyxcbiAgRGlhZ0xvZ2dlck9wdGlvbnMsXG59IGZyb20gJy4vZGlhZy90eXBlcyc7XG5leHBvcnQgdHlwZSB7IERpYWdBUEkgfSBmcm9tICcuL2FwaS9kaWFnJztcblxuLy8gTWV0cmljcyBBUElzXG5leHBvcnQgeyBjcmVhdGVOb29wTWV0ZXIgfSBmcm9tICcuL21ldHJpY3MvTm9vcE1ldGVyJztcbmV4cG9ydCB7IE1ldGVyT3B0aW9ucywgTWV0ZXIgfSBmcm9tICcuL21ldHJpY3MvTWV0ZXInO1xuZXhwb3J0IHsgTWV0ZXJQcm92aWRlciB9IGZyb20gJy4vbWV0cmljcy9NZXRlclByb3ZpZGVyJztcbmV4cG9ydCB7XG4gIFZhbHVlVHlwZSxcbiAgQ291bnRlcixcbiAgR2F1Z2UsXG4gIEhpc3RvZ3JhbSxcbiAgTWV0cmljT3B0aW9ucyxcbiAgT2JzZXJ2YWJsZSxcbiAgT2JzZXJ2YWJsZUNvdW50ZXIsXG4gIE9ic2VydmFibGVHYXVnZSxcbiAgT2JzZXJ2YWJsZVVwRG93bkNvdW50ZXIsXG4gIFVwRG93bkNvdW50ZXIsXG4gIEJhdGNoT2JzZXJ2YWJsZUNhbGxiYWNrLFxuICBNZXRyaWNBZHZpY2UsXG4gIE1ldHJpY0F0dHJpYnV0ZXMsXG4gIE1ldHJpY0F0dHJpYnV0ZVZhbHVlLFxuICBPYnNlcnZhYmxlQ2FsbGJhY2ssXG59IGZyb20gJy4vbWV0cmljcy9NZXRyaWMnO1xuZXhwb3J0IHtcbiAgQmF0Y2hPYnNlcnZhYmxlUmVzdWx0LFxuICBPYnNlcnZhYmxlUmVzdWx0LFxufSBmcm9tICcuL21ldHJpY3MvT2JzZXJ2YWJsZVJlc3VsdCc7XG5leHBvcnQgdHlwZSB7IE1ldHJpY3NBUEkgfSBmcm9tICcuL2FwaS9tZXRyaWNzJztcblxuLy8gUHJvcGFnYXRpb24gQVBJc1xuZXhwb3J0IHtcbiAgVGV4dE1hcFByb3BhZ2F0b3IsXG4gIFRleHRNYXBTZXR0ZXIsXG4gIFRleHRNYXBHZXR0ZXIsXG4gIGRlZmF1bHRUZXh0TWFwR2V0dGVyLFxuICBkZWZhdWx0VGV4dE1hcFNldHRlcixcbn0gZnJvbSAnLi9wcm9wYWdhdGlvbi9UZXh0TWFwUHJvcGFnYXRvcic7XG5leHBvcnQgdHlwZSB7IFByb3BhZ2F0aW9uQVBJIH0gZnJvbSAnLi9hcGkvcHJvcGFnYXRpb24nO1xuXG4vLyBUcmFjZSBBUElzXG5leHBvcnQgeyBTcGFuQXR0cmlidXRlcywgU3BhbkF0dHJpYnV0ZVZhbHVlIH0gZnJvbSAnLi90cmFjZS9hdHRyaWJ1dGVzJztcbmV4cG9ydCB7IExpbmsgfSBmcm9tICcuL3RyYWNlL2xpbmsnO1xuZXhwb3J0IHsgUHJveHlUcmFjZXIsIFRyYWNlckRlbGVnYXRvciB9IGZyb20gJy4vdHJhY2UvUHJveHlUcmFjZXInO1xuZXhwb3J0IHsgUHJveHlUcmFjZXJQcm92aWRlciB9IGZyb20gJy4vdHJhY2UvUHJveHlUcmFjZXJQcm92aWRlcic7XG5leHBvcnQgeyBTYW1wbGVyIH0gZnJvbSAnLi90cmFjZS9TYW1wbGVyJztcbmV4cG9ydCB7IFNhbXBsaW5nRGVjaXNpb24sIFNhbXBsaW5nUmVzdWx0IH0gZnJvbSAnLi90cmFjZS9TYW1wbGluZ1Jlc3VsdCc7XG5leHBvcnQgeyBTcGFuQ29udGV4dCB9IGZyb20gJy4vdHJhY2Uvc3Bhbl9jb250ZXh0JztcbmV4cG9ydCB7IFNwYW5LaW5kIH0gZnJvbSAnLi90cmFjZS9zcGFuX2tpbmQnO1xuZXhwb3J0IHsgU3BhbiB9IGZyb20gJy4vdHJhY2Uvc3Bhbic7XG5leHBvcnQgeyBTcGFuT3B0aW9ucyB9IGZyb20gJy4vdHJhY2UvU3Bhbk9wdGlvbnMnO1xuZXhwb3J0IHsgU3BhblN0YXR1cywgU3BhblN0YXR1c0NvZGUgfSBmcm9tICcuL3RyYWNlL3N0YXR1cyc7XG5leHBvcnQgeyBUcmFjZUZsYWdzIH0gZnJvbSAnLi90cmFjZS90cmFjZV9mbGFncyc7XG5leHBvcnQgeyBUcmFjZVN0YXRlIH0gZnJvbSAnLi90cmFjZS90cmFjZV9zdGF0ZSc7XG5leHBvcnQgeyBjcmVhdGVUcmFjZVN0YXRlIH0gZnJvbSAnLi90cmFjZS9pbnRlcm5hbC91dGlscyc7XG5leHBvcnQgeyBUcmFjZXJQcm92aWRlciB9IGZyb20gJy4vdHJhY2UvdHJhY2VyX3Byb3ZpZGVyJztcbmV4cG9ydCB7IFRyYWNlciB9IGZyb20gJy4vdHJhY2UvdHJhY2VyJztcbmV4cG9ydCB7IFRyYWNlck9wdGlvbnMgfSBmcm9tICcuL3RyYWNlL3RyYWNlcl9vcHRpb25zJztcbmV4cG9ydCB7XG4gIGlzU3BhbkNvbnRleHRWYWxpZCxcbiAgaXNWYWxpZFRyYWNlSWQsXG4gIGlzVmFsaWRTcGFuSWQsXG59IGZyb20gJy4vdHJhY2Uvc3BhbmNvbnRleHQtdXRpbHMnO1xuZXhwb3J0IHtcbiAgSU5WQUxJRF9TUEFOSUQsXG4gIElOVkFMSURfVFJBQ0VJRCxcbiAgSU5WQUxJRF9TUEFOX0NPTlRFWFQsXG59IGZyb20gJy4vdHJhY2UvaW52YWxpZC1zcGFuLWNvbnN0YW50cyc7XG5leHBvcnQgdHlwZSB7IFRyYWNlQVBJIH0gZnJvbSAnLi9hcGkvdHJhY2UnO1xuXG4vLyBTcGxpdCBtb2R1bGUtbGV2ZWwgdmFyaWFibGUgZGVmaW5pdGlvbiBpbnRvIHNlcGFyYXRlIGZpbGVzIHRvIGFsbG93XG4vLyB0cmVlLXNoYWtpbmcgb24gZWFjaCBhcGkgaW5zdGFuY2UuXG5pbXBvcnQgeyBjb250ZXh0IH0gZnJvbSAnLi9jb250ZXh0LWFwaSc7XG5pbXBvcnQgeyBkaWFnIH0gZnJvbSAnLi9kaWFnLWFwaSc7XG5pbXBvcnQgeyBtZXRyaWNzIH0gZnJvbSAnLi9tZXRyaWNzLWFwaSc7XG5pbXBvcnQgeyBwcm9wYWdhdGlvbiB9IGZyb20gJy4vcHJvcGFnYXRpb24tYXBpJztcbmltcG9ydCB7IHRyYWNlIH0gZnJvbSAnLi90cmFjZS1hcGknO1xuXG4vLyBOYW1lZCBleHBvcnQuXG5leHBvcnQgeyBjb250ZXh0LCBkaWFnLCBtZXRyaWNzLCBwcm9wYWdhdGlvbiwgdHJhY2UgfTtcbi8vIERlZmF1bHQgZXhwb3J0LlxuZXhwb3J0IGRlZmF1bHQge1xuICBjb250ZXh0LFxuICBkaWFnLFxuICBtZXRyaWNzLFxuICBwcm9wYWdhdGlvbixcbiAgdHJhY2UsXG59O1xuIiwgImltcG9ydCB7IGNyZWF0ZUhvb2ssIGNyZWF0ZVdlYmhvb2ssIEZhdGFsRXJyb3IsIGZldGNoLCBnZXRXb3JrZmxvd01ldGFkYXRhLCBnZXRXcml0YWJsZSwgc2xlZXAgfSBmcm9tIFwid29ya2Zsb3dcIjtcbmltcG9ydCB7IGNhbGxUaHJvd2VyIH0gZnJvbSBcIi4vaGVscGVycy5qc1wiO1xuLyoqX19pbnRlcm5hbF93b3JrZmxvd3N7XCJ3b3JrZmxvd3NcIjp7XCJleGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHNcIjp7XCJhZGRUZW5Xb3JrZmxvd1wiOntcIndvcmtmbG93SWRcIjpcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL2FkZFRlbldvcmtmbG93XCJ9LFwiY3Jvc3NGaWxlRXJyb3JXb3JrZmxvd1wiOntcIndvcmtmbG93SWRcIjpcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL2Nyb3NzRmlsZUVycm9yV29ya2Zsb3dcIn0sXCJmZXRjaFdvcmtmbG93XCI6e1wid29ya2Zsb3dJZFwiOlwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vZmV0Y2hXb3JrZmxvd1wifSxcImhvb2tDbGVhbnVwVGVzdFdvcmtmbG93XCI6e1wid29ya2Zsb3dJZFwiOlwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vaG9va0NsZWFudXBUZXN0V29ya2Zsb3dcIn0sXCJob29rV29ya2Zsb3dcIjp7XCJ3b3JrZmxvd0lkXCI6XCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9ob29rV29ya2Zsb3dcIn0sXCJuZXN0ZWRFcnJvcldvcmtmbG93XCI6e1wid29ya2Zsb3dJZFwiOlwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vbmVzdGVkRXJyb3JXb3JrZmxvd1wifSxcIm51bGxCeXRlV29ya2Zsb3dcIjp7XCJ3b3JrZmxvd0lkXCI6XCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9udWxsQnl0ZVdvcmtmbG93XCJ9LFwib3V0cHV0U3RyZWFtSW5zaWRlU3RlcFdvcmtmbG93XCI6e1wid29ya2Zsb3dJZFwiOlwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vb3V0cHV0U3RyZWFtSW5zaWRlU3RlcFdvcmtmbG93XCJ9LFwib3V0cHV0U3RyZWFtV29ya2Zsb3dcIjp7XCJ3b3JrZmxvd0lkXCI6XCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9vdXRwdXRTdHJlYW1Xb3JrZmxvd1wifSxcInByb21pc2VBbGxXb3JrZmxvd1wiOntcIndvcmtmbG93SWRcIjpcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3Byb21pc2VBbGxXb3JrZmxvd1wifSxcInByb21pc2VBbnlXb3JrZmxvd1wiOntcIndvcmtmbG93SWRcIjpcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3Byb21pc2VBbnlXb3JrZmxvd1wifSxcInByb21pc2VSYWNlU3RyZXNzVGVzdFdvcmtmbG93XCI6e1wid29ya2Zsb3dJZFwiOlwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vcHJvbWlzZVJhY2VTdHJlc3NUZXN0V29ya2Zsb3dcIn0sXCJwcm9taXNlUmFjZVdvcmtmbG93XCI6e1wid29ya2Zsb3dJZFwiOlwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vcHJvbWlzZVJhY2VXb3JrZmxvd1wifSxcInJlYWRhYmxlU3RyZWFtV29ya2Zsb3dcIjp7XCJ3b3JrZmxvd0lkXCI6XCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9yZWFkYWJsZVN0cmVhbVdvcmtmbG93XCJ9LFwicmV0cnlBdHRlbXB0Q291bnRlcldvcmtmbG93XCI6e1wid29ya2Zsb3dJZFwiOlwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vcmV0cnlBdHRlbXB0Q291bnRlcldvcmtmbG93XCJ9LFwicmV0cnlhYmxlQW5kRmF0YWxFcnJvcldvcmtmbG93XCI6e1wid29ya2Zsb3dJZFwiOlwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vcmV0cnlhYmxlQW5kRmF0YWxFcnJvcldvcmtmbG93XCJ9LFwic2xlZXBpbmdXb3JrZmxvd1wiOntcIndvcmtmbG93SWRcIjpcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3NsZWVwaW5nV29ya2Zsb3dcIn0sXCJzdGVwRnVuY3Rpb25QYXNzaW5nV29ya2Zsb3dcIjp7XCJ3b3JrZmxvd0lkXCI6XCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9zdGVwRnVuY3Rpb25QYXNzaW5nV29ya2Zsb3dcIn0sXCJ3ZWJob29rV29ya2Zsb3dcIjp7XCJ3b3JrZmxvd0lkXCI6XCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy93ZWJob29rV29ya2Zsb3dcIn0sXCJ3b3JrZmxvd0FuZFN0ZXBNZXRhZGF0YVdvcmtmbG93XCI6e1wid29ya2Zsb3dJZFwiOlwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vd29ya2Zsb3dBbmRTdGVwTWV0YWRhdGFXb3JrZmxvd1wifX19LFwic3RlcHNcIjp7XCJleGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHNcIjp7XCJhZGRcIjp7XCJzdGVwSWRcIjpcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vYWRkXCJ9LFwiZG91YmxlTnVtYmVyXCI6e1wic3RlcElkXCI6XCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL2RvdWJsZU51bWJlclwifSxcImdlblJlYWRhYmxlU3RyZWFtXCI6e1wic3RlcElkXCI6XCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL2dlblJlYWRhYmxlU3RyZWFtXCJ9LFwibnVsbEJ5dGVTdGVwXCI6e1wic3RlcElkXCI6XCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL251bGxCeXRlU3RlcFwifSxcInByb21pc2VSYWNlU3RyZXNzVGVzdERlbGF5U3RlcFwiOntcInN0ZXBJZFwiOlwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9wcm9taXNlUmFjZVN0cmVzc1Rlc3REZWxheVN0ZXBcIn0sXCJyYW5kb21EZWxheVwiOntcInN0ZXBJZFwiOlwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9yYW5kb21EZWxheVwifSxcInNlbmRXZWJob29rUmVzcG9uc2VcIjp7XCJzdGVwSWRcIjpcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc2VuZFdlYmhvb2tSZXNwb25zZVwifSxcInNwZWNpZmljRGVsYXlcIjp7XCJzdGVwSWRcIjpcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc3BlY2lmaWNEZWxheVwifSxcInN0ZXBDbG9zZU91dHB1dFN0cmVhbVwiOntcInN0ZXBJZFwiOlwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9zdGVwQ2xvc2VPdXRwdXRTdHJlYW1cIn0sXCJzdGVwQ2xvc2VPdXRwdXRTdHJlYW1JbnNpZGVTdGVwXCI6e1wic3RlcElkXCI6XCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3N0ZXBDbG9zZU91dHB1dFN0cmVhbUluc2lkZVN0ZXBcIn0sXCJzdGVwVGhhdEZhaWxzXCI6e1wic3RlcElkXCI6XCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3N0ZXBUaGF0RmFpbHNcIn0sXCJzdGVwVGhhdFJldHJpZXNBbmRTdWNjZWVkc1wiOntcInN0ZXBJZFwiOlwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9zdGVwVGhhdFJldHJpZXNBbmRTdWNjZWVkc1wifSxcInN0ZXBUaGF0VGhyb3dzUmV0cnlhYmxlRXJyb3JcIjp7XCJzdGVwSWRcIjpcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc3RlcFRoYXRUaHJvd3NSZXRyeWFibGVFcnJvclwifSxcInN0ZXBXaXRoTWV0YWRhdGFcIjp7XCJzdGVwSWRcIjpcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc3RlcFdpdGhNZXRhZGF0YVwifSxcInN0ZXBXaXRoTmFtZWRPdXRwdXRTdHJlYW1JbnNpZGVTdGVwXCI6e1wic3RlcElkXCI6XCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3N0ZXBXaXRoTmFtZWRPdXRwdXRTdHJlYW1JbnNpZGVTdGVwXCJ9LFwic3RlcFdpdGhPdXRwdXRTdHJlYW1CaW5hcnlcIjp7XCJzdGVwSWRcIjpcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc3RlcFdpdGhPdXRwdXRTdHJlYW1CaW5hcnlcIn0sXCJzdGVwV2l0aE91dHB1dFN0cmVhbUluc2lkZVN0ZXBcIjp7XCJzdGVwSWRcIjpcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc3RlcFdpdGhPdXRwdXRTdHJlYW1JbnNpZGVTdGVwXCJ9LFwic3RlcFdpdGhPdXRwdXRTdHJlYW1PYmplY3RcIjp7XCJzdGVwSWRcIjpcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc3RlcFdpdGhPdXRwdXRTdHJlYW1PYmplY3RcIn0sXCJzdGVwV2l0aFN0ZXBGdW5jdGlvbkFyZ1wiOntcInN0ZXBJZFwiOlwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9zdGVwV2l0aFN0ZXBGdW5jdGlvbkFyZ1wifX19fSovO1xuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGFkZChhLCBiKSB7XG4gICAgcmV0dXJuIGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1VTRV9TVEVQXCIpXShcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vYWRkXCIpKGEsIGIpO1xufVxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGFkZFRlbldvcmtmbG93KGlucHV0KSB7XG4gICAgY29uc3QgYSA9IGF3YWl0IGFkZChpbnB1dCwgMik7XG4gICAgY29uc3QgYiA9IGF3YWl0IGFkZChhLCAzKTtcbiAgICBjb25zdCBjID0gYXdhaXQgYWRkKGIsIDUpO1xuICAgIHJldHVybiBjO1xufVxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gSGVscGVyIGZ1bmN0aW9ucyB0byB0ZXN0IG5lc3RlZCBzdGFjayB0cmFjZXNcbmZ1bmN0aW9uIGRlZXBGdW5jdGlvbigpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0Vycm9yIGZyb20gZGVlcGx5IG5lc3RlZCBmdW5jdGlvbicpO1xufVxuZnVuY3Rpb24gbWlkZGxlRnVuY3Rpb24oKSB7XG4gICAgZGVlcEZ1bmN0aW9uKCk7XG59XG5mdW5jdGlvbiB0b3BMZXZlbEhlbHBlcigpIHtcbiAgICBtaWRkbGVGdW5jdGlvbigpO1xufVxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG5lc3RlZEVycm9yV29ya2Zsb3coKSB7XG4gICAgdG9wTGV2ZWxIZWxwZXIoKTtcbiAgICByZXR1cm4gJ25ldmVyIHJlYWNoZWQnO1xufVxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuYXN5bmMgZnVuY3Rpb24gcmFuZG9tRGVsYXkodikge1xuICAgIHJldHVybiBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19VU0VfU1RFUFwiKV0oXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3JhbmRvbURlbGF5XCIpKHYpO1xufVxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHByb21pc2VBbGxXb3JrZmxvdygpIHtcbiAgICBjb25zdCBbYSwgYiwgY10gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgIHJhbmRvbURlbGF5KCdhJyksXG4gICAgICAgIHJhbmRvbURlbGF5KCdiJyksXG4gICAgICAgIHJhbmRvbURlbGF5KCdjJylcbiAgICBdKTtcbiAgICByZXR1cm4gYSArIGIgKyBjO1xufVxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuYXN5bmMgZnVuY3Rpb24gc3BlY2lmaWNEZWxheShkZWxheSwgdikge1xuICAgIHJldHVybiBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19VU0VfU1RFUFwiKV0oXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3NwZWNpZmljRGVsYXlcIikoZGVsYXksIHYpO1xufVxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHByb21pc2VSYWNlV29ya2Zsb3coKSB7XG4gICAgY29uc3Qgd2lubmVyID0gYXdhaXQgUHJvbWlzZS5yYWNlKFtcbiAgICAgICAgc3BlY2lmaWNEZWxheSgxMDAwMCwgJ2EnKSxcbiAgICAgICAgc3BlY2lmaWNEZWxheSgxMDAsICdiJyksXG4gICAgICAgIHNwZWNpZmljRGVsYXkoMjAwMDAsICdjJylcbiAgICBdKTtcbiAgICByZXR1cm4gd2lubmVyO1xufVxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuYXN5bmMgZnVuY3Rpb24gc3RlcFRoYXRGYWlscygpIHtcbiAgICByZXR1cm4gZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildKFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9zdGVwVGhhdEZhaWxzXCIpKCk7XG59XG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcHJvbWlzZUFueVdvcmtmbG93KCkge1xuICAgIGNvbnN0IHdpbm5lciA9IGF3YWl0IFByb21pc2UuYW55KFtcbiAgICAgICAgc3RlcFRoYXRGYWlscygpLFxuICAgICAgICBzcGVjaWZpY0RlbGF5KDEwMDAsICdiJyksXG4gICAgICAgIHNwZWNpZmljRGVsYXkoMzAwMCwgJ2MnKVxuICAgIF0pO1xuICAgIHJldHVybiB3aW5uZXI7XG59XG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBOYW1lIHNob3VsZCBub3QgY29uZmxpY3Qgd2l0aCBnZW5TdHJlYW0gaW4gM19zdHJlYW1zLnRzXG4vLyBUT0RPOiBzd2MgdHJhbnNmb3JtIHNob3VsZCBtYW5nbGUgbmFtZXMgdG8gYXZvaWQgY29uZmxpY3RzXG5hc3luYyBmdW5jdGlvbiBnZW5SZWFkYWJsZVN0cmVhbSgpIHtcbiAgICByZXR1cm4gZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildKFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9nZW5SZWFkYWJsZVN0cmVhbVwiKSgpO1xufVxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlYWRhYmxlU3RyZWFtV29ya2Zsb3coKSB7XG4gICAgY29uc29sZS5sb2coJ2NhbGxpbmcgZ2VuUmVhZGFibGVTdHJlYW0nKTtcbiAgICBjb25zdCBzdHJlYW0gPSBhd2FpdCBnZW5SZWFkYWJsZVN0cmVhbSgpO1xuICAgIGNvbnNvbGUubG9nKCdnZW5SZWFkYWJsZVN0cmVhbSByZXR1cm5lZCcsIHN0cmVhbSk7XG4gICAgcmV0dXJuIHN0cmVhbTtcbn1cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBob29rV29ya2Zsb3codG9rZW4sIGN1c3RvbURhdGEpIHtcbiAgICBjb25zdCBob29rID0gY3JlYXRlSG9vayh7XG4gICAgICAgIHRva2VuLFxuICAgICAgICBtZXRhZGF0YToge1xuICAgICAgICAgICAgY3VzdG9tRGF0YVxuICAgICAgICB9XG4gICAgfSk7XG4gICAgY29uc3QgcGF5bG9hZHMgPSBbXTtcbiAgICBmb3IgYXdhaXQgKGNvbnN0IHBheWxvYWQgb2YgaG9vayl7XG4gICAgICAgIHBheWxvYWRzLnB1c2gocGF5bG9hZCk7XG4gICAgICAgIGlmIChwYXlsb2FkLmRvbmUpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBwYXlsb2Fkcztcbn1cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbmFzeW5jIGZ1bmN0aW9uIHNlbmRXZWJob29rUmVzcG9uc2UocmVxKSB7XG4gICAgcmV0dXJuIGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1VTRV9TVEVQXCIpXShcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc2VuZFdlYmhvb2tSZXNwb25zZVwiKShyZXEpO1xufVxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdlYmhvb2tXb3JrZmxvdyh0b2tlbiwgdG9rZW4yLCB0b2tlbjMpIHtcbiAgICBjb25zdCBwYXlsb2FkcyA9IFtdO1xuICAgIGNvbnN0IHdlYmhvb2tXaXRoRGVmYXVsdFJlc3BvbnNlID0gY3JlYXRlV2ViaG9vayh7XG4gICAgICAgIHRva2VuXG4gICAgfSk7XG4gICAgY29uc3QgcmVzID0gbmV3IFJlc3BvbnNlKCdIZWxsbyBmcm9tIHN0YXRpYyByZXNwb25zZSEnLCB7XG4gICAgICAgIHN0YXR1czogNDAyXG4gICAgfSk7XG4gICAgY29uc29sZS5sb2coJ3JlcycsIHJlcyk7XG4gICAgY29uc3Qgd2ViaG9va1dpdGhTdGF0aWNSZXNwb25zZSA9IGNyZWF0ZVdlYmhvb2soe1xuICAgICAgICB0b2tlbjogdG9rZW4yLFxuICAgICAgICByZXNwb25kV2l0aDogcmVzXG4gICAgfSk7XG4gICAgY29uc3Qgd2ViaG9va1dpdGhNYW51YWxSZXNwb25zZSA9IGNyZWF0ZVdlYmhvb2soe1xuICAgICAgICB0b2tlbjogdG9rZW4zLFxuICAgICAgICByZXNwb25kV2l0aDogJ21hbnVhbCdcbiAgICB9KTtcbiAgICAvLyBXZWJob29rIHdpdGggZGVmYXVsdCByZXNwb25zZVxuICAgIHtcbiAgICAgICAgY29uc3QgcmVxID0gYXdhaXQgd2ViaG9va1dpdGhEZWZhdWx0UmVzcG9uc2U7XG4gICAgICAgIGNvbnN0IGJvZHkgPSBhd2FpdCByZXEudGV4dCgpO1xuICAgICAgICBwYXlsb2Fkcy5wdXNoKHtcbiAgICAgICAgICAgIHVybDogcmVxLnVybCxcbiAgICAgICAgICAgIG1ldGhvZDogcmVxLm1ldGhvZCxcbiAgICAgICAgICAgIGJvZHlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8vIFdlYmhvb2sgd2l0aCBzdGF0aWMgcmVzcG9uc2VcbiAgICB7XG4gICAgICAgIGNvbnN0IHJlcSA9IGF3YWl0IHdlYmhvb2tXaXRoU3RhdGljUmVzcG9uc2U7XG4gICAgICAgIGNvbnN0IGJvZHkgPSBhd2FpdCByZXEudGV4dCgpO1xuICAgICAgICBwYXlsb2Fkcy5wdXNoKHtcbiAgICAgICAgICAgIHVybDogcmVxLnVybCxcbiAgICAgICAgICAgIG1ldGhvZDogcmVxLm1ldGhvZCxcbiAgICAgICAgICAgIGJvZHlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8vIFdlYmhvb2sgd2l0aCBtYW51YWwgcmVzcG9uc2VcbiAgICB7XG4gICAgICAgIGNvbnN0IHJlcSA9IGF3YWl0IHdlYmhvb2tXaXRoTWFudWFsUmVzcG9uc2U7XG4gICAgICAgIGNvbnN0IGJvZHkgPSBhd2FpdCBzZW5kV2ViaG9va1Jlc3BvbnNlKHJlcSk7XG4gICAgICAgIHBheWxvYWRzLnB1c2goe1xuICAgICAgICAgICAgdXJsOiByZXEudXJsLFxuICAgICAgICAgICAgbWV0aG9kOiByZXEubWV0aG9kLFxuICAgICAgICAgICAgYm9keVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHBheWxvYWRzO1xufVxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNsZWVwaW5nV29ya2Zsb3coKSB7XG4gICAgY29uc3Qgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICBhd2FpdCBzbGVlcCgnMTBzJyk7XG4gICAgY29uc3QgZW5kVGltZSA9IERhdGUubm93KCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgc3RhcnRUaW1lLFxuICAgICAgICBlbmRUaW1lXG4gICAgfTtcbn1cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbmFzeW5jIGZ1bmN0aW9uIG51bGxCeXRlU3RlcCgpIHtcbiAgICByZXR1cm4gZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildKFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9udWxsQnl0ZVN0ZXBcIikoKTtcbn1cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBudWxsQnl0ZVdvcmtmbG93KCkge1xuICAgIGNvbnN0IGEgPSBhd2FpdCBudWxsQnl0ZVN0ZXAoKTtcbiAgICByZXR1cm4gYTtcbn1cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbmFzeW5jIGZ1bmN0aW9uIHN0ZXBXaXRoTWV0YWRhdGEoKSB7XG4gICAgcmV0dXJuIGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1VTRV9TVEVQXCIpXShcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc3RlcFdpdGhNZXRhZGF0YVwiKSgpO1xufVxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdvcmtmbG93QW5kU3RlcE1ldGFkYXRhV29ya2Zsb3coKSB7XG4gICAgY29uc3Qgd29ya2Zsb3dNZXRhZGF0YSA9IGdldFdvcmtmbG93TWV0YWRhdGEoKTtcbiAgICBjb25zdCB7IHN0ZXBNZXRhZGF0YSwgd29ya2Zsb3dNZXRhZGF0YTogaW5uZXJXb3JrZmxvd01ldGFkYXRhIH0gPSBhd2FpdCBzdGVwV2l0aE1ldGFkYXRhKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgd29ya2Zsb3dNZXRhZGF0YToge1xuICAgICAgICAgICAgd29ya2Zsb3dSdW5JZDogd29ya2Zsb3dNZXRhZGF0YS53b3JrZmxvd1J1bklkLFxuICAgICAgICAgICAgd29ya2Zsb3dTdGFydGVkQXQ6IHdvcmtmbG93TWV0YWRhdGEud29ya2Zsb3dTdGFydGVkQXQsXG4gICAgICAgICAgICB1cmw6IHdvcmtmbG93TWV0YWRhdGEudXJsXG4gICAgICAgIH0sXG4gICAgICAgIHN0ZXBNZXRhZGF0YSxcbiAgICAgICAgaW5uZXJXb3JrZmxvd01ldGFkYXRhXG4gICAgfTtcbn1cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbmFzeW5jIGZ1bmN0aW9uIHN0ZXBXaXRoT3V0cHV0U3RyZWFtQmluYXJ5KHdyaXRhYmxlLCB0ZXh0KSB7XG4gICAgcmV0dXJuIGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1VTRV9TVEVQXCIpXShcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc3RlcFdpdGhPdXRwdXRTdHJlYW1CaW5hcnlcIikod3JpdGFibGUsIHRleHQpO1xufVxuYXN5bmMgZnVuY3Rpb24gc3RlcFdpdGhPdXRwdXRTdHJlYW1PYmplY3Qod3JpdGFibGUsIG9iaikge1xuICAgIHJldHVybiBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19VU0VfU1RFUFwiKV0oXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3N0ZXBXaXRoT3V0cHV0U3RyZWFtT2JqZWN0XCIpKHdyaXRhYmxlLCBvYmopO1xufVxuYXN5bmMgZnVuY3Rpb24gc3RlcENsb3NlT3V0cHV0U3RyZWFtKHdyaXRhYmxlKSB7XG4gICAgcmV0dXJuIGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1VTRV9TVEVQXCIpXShcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc3RlcENsb3NlT3V0cHV0U3RyZWFtXCIpKHdyaXRhYmxlKTtcbn1cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvdXRwdXRTdHJlYW1Xb3JrZmxvdygpIHtcbiAgICBjb25zdCB3cml0YWJsZSA9IGdldFdyaXRhYmxlKCk7XG4gICAgY29uc3QgbmFtZWRXcml0YWJsZSA9IGdldFdyaXRhYmxlKHtcbiAgICAgICAgbmFtZXNwYWNlOiAndGVzdCdcbiAgICB9KTtcbiAgICBhd2FpdCBzbGVlcCgnMXMnKTtcbiAgICBhd2FpdCBzdGVwV2l0aE91dHB1dFN0cmVhbUJpbmFyeSh3cml0YWJsZSwgJ0hlbGxvLCB3b3JsZCEnKTtcbiAgICBhd2FpdCBzbGVlcCgnMXMnKTtcbiAgICBhd2FpdCBzdGVwV2l0aE91dHB1dFN0cmVhbUJpbmFyeShuYW1lZFdyaXRhYmxlLCAnSGVsbG8sIG5hbWVkIHN0cmVhbSEnKTtcbiAgICBhd2FpdCBzbGVlcCgnMXMnKTtcbiAgICBhd2FpdCBzdGVwV2l0aE91dHB1dFN0cmVhbU9iamVjdCh3cml0YWJsZSwge1xuICAgICAgICBmb286ICd0ZXN0J1xuICAgIH0pO1xuICAgIGF3YWl0IHNsZWVwKCcxcycpO1xuICAgIGF3YWl0IHN0ZXBXaXRoT3V0cHV0U3RyZWFtT2JqZWN0KG5hbWVkV3JpdGFibGUsIHtcbiAgICAgICAgZm9vOiAnYmFyJ1xuICAgIH0pO1xuICAgIGF3YWl0IHNsZWVwKCcxcycpO1xuICAgIGF3YWl0IHN0ZXBDbG9zZU91dHB1dFN0cmVhbSh3cml0YWJsZSk7XG4gICAgYXdhaXQgc3RlcENsb3NlT3V0cHV0U3RyZWFtKG5hbWVkV3JpdGFibGUpO1xuICAgIHJldHVybiAnZG9uZSc7XG59XG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5hc3luYyBmdW5jdGlvbiBzdGVwV2l0aE91dHB1dFN0cmVhbUluc2lkZVN0ZXAodGV4dCkge1xuICAgIHJldHVybiBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19VU0VfU1RFUFwiKV0oXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3N0ZXBXaXRoT3V0cHV0U3RyZWFtSW5zaWRlU3RlcFwiKSh0ZXh0KTtcbn1cbmFzeW5jIGZ1bmN0aW9uIHN0ZXBXaXRoTmFtZWRPdXRwdXRTdHJlYW1JbnNpZGVTdGVwKG5hbWVzcGFjZSwgb2JqKSB7XG4gICAgcmV0dXJuIGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1VTRV9TVEVQXCIpXShcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc3RlcFdpdGhOYW1lZE91dHB1dFN0cmVhbUluc2lkZVN0ZXBcIikobmFtZXNwYWNlLCBvYmopO1xufVxuYXN5bmMgZnVuY3Rpb24gc3RlcENsb3NlT3V0cHV0U3RyZWFtSW5zaWRlU3RlcChuYW1lc3BhY2UpIHtcbiAgICByZXR1cm4gZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildKFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9zdGVwQ2xvc2VPdXRwdXRTdHJlYW1JbnNpZGVTdGVwXCIpKG5hbWVzcGFjZSk7XG59XG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gb3V0cHV0U3RyZWFtSW5zaWRlU3RlcFdvcmtmbG93KCkge1xuICAgIGF3YWl0IHNsZWVwKCcxcycpO1xuICAgIGF3YWl0IHN0ZXBXaXRoT3V0cHV0U3RyZWFtSW5zaWRlU3RlcCgnSGVsbG8gZnJvbSBzdGVwIScpO1xuICAgIGF3YWl0IHNsZWVwKCcxcycpO1xuICAgIGF3YWl0IHN0ZXBXaXRoTmFtZWRPdXRwdXRTdHJlYW1JbnNpZGVTdGVwKCdzdGVwLW5zJywge1xuICAgICAgICBtZXNzYWdlOiAnSGVsbG8gZnJvbSBuYW1lZCBzdHJlYW0gaW4gc3RlcCEnXG4gICAgfSk7XG4gICAgYXdhaXQgc2xlZXAoJzFzJyk7XG4gICAgYXdhaXQgc3RlcFdpdGhPdXRwdXRTdHJlYW1JbnNpZGVTdGVwKCdTZWNvbmQgbWVzc2FnZScpO1xuICAgIGF3YWl0IHNsZWVwKCcxcycpO1xuICAgIGF3YWl0IHN0ZXBXaXRoTmFtZWRPdXRwdXRTdHJlYW1JbnNpZGVTdGVwKCdzdGVwLW5zJywge1xuICAgICAgICBjb3VudGVyOiA0MlxuICAgIH0pO1xuICAgIGF3YWl0IHNsZWVwKCcxcycpO1xuICAgIGF3YWl0IHN0ZXBDbG9zZU91dHB1dFN0cmVhbUluc2lkZVN0ZXAoKTtcbiAgICBhd2FpdCBzdGVwQ2xvc2VPdXRwdXRTdHJlYW1JbnNpZGVTdGVwKCdzdGVwLW5zJyk7XG4gICAgcmV0dXJuICdkb25lJztcbn1cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBmZXRjaFdvcmtmbG93KCkge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goJ2h0dHBzOi8vanNvbnBsYWNlaG9sZGVyLnR5cGljb2RlLmNvbS90b2Rvcy8xJyk7XG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICByZXR1cm4gZGF0YTtcbn1cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwcm9taXNlUmFjZVN0cmVzc1Rlc3REZWxheVN0ZXAoZHVyLCByZXNwKSB7XG4gICAgcmV0dXJuIGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1VTRV9TVEVQXCIpXShcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vcHJvbWlzZVJhY2VTdHJlc3NUZXN0RGVsYXlTdGVwXCIpKGR1ciwgcmVzcCk7XG59XG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcHJvbWlzZVJhY2VTdHJlc3NUZXN0V29ya2Zsb3coKSB7XG4gICAgY29uc3QgcHJvbWlzZXMgPSBuZXcgTWFwKCk7XG4gICAgY29uc3QgZG9uZSA9IFtdO1xuICAgIGZvcihsZXQgaSA9IDA7IGkgPCA1OyBpKyspe1xuICAgICAgICBjb25zdCByZXNwID0gaTtcbiAgICAgICAgY29uc3QgZHVyID0gMTAwMCAqIDUgKiBpOyAvLyA1IHNlY29uZHMgYXBhcnRcbiAgICAgICAgY29uc29sZS5sb2coYHNjaGVkYCwgcmVzcCwgYC9gLCBkdXIpO1xuICAgICAgICBwcm9taXNlcy5zZXQoaSwgcHJvbWlzZVJhY2VTdHJlc3NUZXN0RGVsYXlTdGVwKGR1ciwgcmVzcCkpO1xuICAgIH1cbiAgICB3aGlsZShwcm9taXNlcy5zaXplID4gMCl7XG4gICAgICAgIGNvbnNvbGUubG9nKGBwcm9taXNlcy5zaXplYCwgcHJvbWlzZXMuc2l6ZSk7XG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IFByb21pc2UucmFjZShwcm9taXNlcy52YWx1ZXMoKSk7XG4gICAgICAgIGNvbnNvbGUubG9nKHJlcyk7XG4gICAgICAgIGRvbmUucHVzaChyZXMpO1xuICAgICAgICBwcm9taXNlcy5kZWxldGUocmVzKTtcbiAgICB9XG4gICAgcmV0dXJuIGRvbmU7XG59XG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5hc3luYyBmdW5jdGlvbiBzdGVwVGhhdFJldHJpZXNBbmRTdWNjZWVkcygpIHtcbiAgICByZXR1cm4gZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildKFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9zdGVwVGhhdFJldHJpZXNBbmRTdWNjZWVkc1wiKSgpO1xufVxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJldHJ5QXR0ZW1wdENvdW50ZXJXb3JrZmxvdygpIHtcbiAgICBjb25zb2xlLmxvZygnU3RhcnRpbmcgcmV0cnkgYXR0ZW1wdCBjb3VudGVyIHdvcmtmbG93Jyk7XG4gICAgLy8gVGhpcyBzdGVwIHNob3VsZCBmYWlsIHR3aWNlIGFuZCBzdWNjZWVkIG9uIHRoZSB0aGlyZCBhdHRlbXB0XG4gICAgY29uc3QgZmluYWxBdHRlbXB0ID0gYXdhaXQgc3RlcFRoYXRSZXRyaWVzQW5kU3VjY2VlZHMoKTtcbiAgICBjb25zb2xlLmxvZyhgV29ya2Zsb3cgY29tcGxldGVkIHdpdGggZmluYWwgYXR0ZW1wdDogJHtmaW5hbEF0dGVtcHR9YCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgZmluYWxBdHRlbXB0XG4gICAgfTtcbn1cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbmFzeW5jIGZ1bmN0aW9uIHN0ZXBUaGF0VGhyb3dzUmV0cnlhYmxlRXJyb3IoKSB7XG4gICAgcmV0dXJuIGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1VTRV9TVEVQXCIpXShcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc3RlcFRoYXRUaHJvd3NSZXRyeWFibGVFcnJvclwiKSgpO1xufVxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNyb3NzRmlsZUVycm9yV29ya2Zsb3coKSB7XG4gICAgLy8gVGhpcyB3aWxsIHRocm93IGFuIGVycm9yIGZyb20gdGhlIGltcG9ydGVkIGhlbHBlcnMudHMgZmlsZVxuICAgIGNhbGxUaHJvd2VyKCk7XG4gICAgcmV0dXJuICduZXZlciByZWFjaGVkJztcbn1cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZXRyeWFibGVBbmRGYXRhbEVycm9yV29ya2Zsb3coKSB7XG4gICAgY29uc3QgcmV0cnlhYmxlUmVzdWx0ID0gYXdhaXQgc3RlcFRoYXRUaHJvd3NSZXRyeWFibGVFcnJvcigpO1xuICAgIGxldCBnb3RGYXRhbEVycm9yID0gZmFsc2U7XG4gICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgc3RlcFRoYXRGYWlscygpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGlmIChGYXRhbEVycm9yLmlzKGVycm9yKSkge1xuICAgICAgICAgICAgZ290RmF0YWxFcnJvciA9IHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgcmV0cnlhYmxlUmVzdWx0LFxuICAgICAgICBnb3RGYXRhbEVycm9yXG4gICAgfTtcbn1cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBob29rQ2xlYW51cFRlc3RXb3JrZmxvdyh0b2tlbiwgY3VzdG9tRGF0YSkge1xuICAgIGNvbnN0IGhvb2sgPSBjcmVhdGVIb29rKHtcbiAgICAgICAgdG9rZW4sXG4gICAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgICAgICBjdXN0b21EYXRhXG4gICAgICAgIH1cbiAgICB9KTtcbiAgICAvLyBXYWl0IGZvciBleGFjdGx5IG9uZSBwYXlsb2FkXG4gICAgY29uc3QgcGF5bG9hZCA9IGF3YWl0IGhvb2s7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbWVzc2FnZTogcGF5bG9hZC5tZXNzYWdlLFxuICAgICAgICBjdXN0b21EYXRhOiBwYXlsb2FkLmN1c3RvbURhdGEsXG4gICAgICAgIGhvb2tDbGVhbnVwVGVzdERhdGE6ICd3b3JrZmxvd19jb21wbGV0ZWQnXG4gICAgfTtcbn1cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzdGVwRnVuY3Rpb25QYXNzaW5nV29ya2Zsb3coKSB7XG4gICAgLy8gUGFzcyBhIHN0ZXAgZnVuY3Rpb24gcmVmZXJlbmNlIHRvIGFub3RoZXIgc3RlcFxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHN0ZXBXaXRoU3RlcEZ1bmN0aW9uQXJnKGRvdWJsZU51bWJlcik7XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbmFzeW5jIGZ1bmN0aW9uIHN0ZXBXaXRoU3RlcEZ1bmN0aW9uQXJnKHN0ZXBGbikge1xuICAgIHJldHVybiBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19VU0VfU1RFUFwiKV0oXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3N0ZXBXaXRoU3RlcEZ1bmN0aW9uQXJnXCIpKHN0ZXBGbik7XG59XG5hc3luYyBmdW5jdGlvbiBkb3VibGVOdW1iZXIoeCkge1xuICAgIHJldHVybiBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19VU0VfU1RFUFwiKV0oXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL2RvdWJsZU51bWJlclwiKSh4KTtcbn1cbmFkZFRlbldvcmtmbG93LndvcmtmbG93SWQgPSBcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL2FkZFRlbldvcmtmbG93XCI7XG5uZXN0ZWRFcnJvcldvcmtmbG93LndvcmtmbG93SWQgPSBcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL25lc3RlZEVycm9yV29ya2Zsb3dcIjtcbnByb21pc2VBbGxXb3JrZmxvdy53b3JrZmxvd0lkID0gXCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9wcm9taXNlQWxsV29ya2Zsb3dcIjtcbnByb21pc2VSYWNlV29ya2Zsb3cud29ya2Zsb3dJZCA9IFwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vcHJvbWlzZVJhY2VXb3JrZmxvd1wiO1xucHJvbWlzZUFueVdvcmtmbG93LndvcmtmbG93SWQgPSBcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3Byb21pc2VBbnlXb3JrZmxvd1wiO1xucmVhZGFibGVTdHJlYW1Xb3JrZmxvdy53b3JrZmxvd0lkID0gXCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9yZWFkYWJsZVN0cmVhbVdvcmtmbG93XCI7XG5ob29rV29ya2Zsb3cud29ya2Zsb3dJZCA9IFwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vaG9va1dvcmtmbG93XCI7XG53ZWJob29rV29ya2Zsb3cud29ya2Zsb3dJZCA9IFwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vd2ViaG9va1dvcmtmbG93XCI7XG5zbGVlcGluZ1dvcmtmbG93LndvcmtmbG93SWQgPSBcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3NsZWVwaW5nV29ya2Zsb3dcIjtcbm51bGxCeXRlV29ya2Zsb3cud29ya2Zsb3dJZCA9IFwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vbnVsbEJ5dGVXb3JrZmxvd1wiO1xud29ya2Zsb3dBbmRTdGVwTWV0YWRhdGFXb3JrZmxvdy53b3JrZmxvd0lkID0gXCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy93b3JrZmxvd0FuZFN0ZXBNZXRhZGF0YVdvcmtmbG93XCI7XG5vdXRwdXRTdHJlYW1Xb3JrZmxvdy53b3JrZmxvd0lkID0gXCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9vdXRwdXRTdHJlYW1Xb3JrZmxvd1wiO1xub3V0cHV0U3RyZWFtSW5zaWRlU3RlcFdvcmtmbG93LndvcmtmbG93SWQgPSBcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL291dHB1dFN0cmVhbUluc2lkZVN0ZXBXb3JrZmxvd1wiO1xuZmV0Y2hXb3JrZmxvdy53b3JrZmxvd0lkID0gXCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9mZXRjaFdvcmtmbG93XCI7XG5wcm9taXNlUmFjZVN0cmVzc1Rlc3RXb3JrZmxvdy53b3JrZmxvd0lkID0gXCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9wcm9taXNlUmFjZVN0cmVzc1Rlc3RXb3JrZmxvd1wiO1xucmV0cnlBdHRlbXB0Q291bnRlcldvcmtmbG93LndvcmtmbG93SWQgPSBcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3JldHJ5QXR0ZW1wdENvdW50ZXJXb3JrZmxvd1wiO1xuY3Jvc3NGaWxlRXJyb3JXb3JrZmxvdy53b3JrZmxvd0lkID0gXCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9jcm9zc0ZpbGVFcnJvcldvcmtmbG93XCI7XG5yZXRyeWFibGVBbmRGYXRhbEVycm9yV29ya2Zsb3cud29ya2Zsb3dJZCA9IFwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vcmV0cnlhYmxlQW5kRmF0YWxFcnJvcldvcmtmbG93XCI7XG5ob29rQ2xlYW51cFRlc3RXb3JrZmxvdy53b3JrZmxvd0lkID0gXCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9ob29rQ2xlYW51cFRlc3RXb3JrZmxvd1wiO1xuc3RlcEZ1bmN0aW9uUGFzc2luZ1dvcmtmbG93LndvcmtmbG93SWQgPSBcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3N0ZXBGdW5jdGlvblBhc3NpbmdXb3JrZmxvd1wiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGFkZCwgU3ltYm9sLmZvcihcIldPUktGTE9XX1NURVBfRlVOQ1RJT05fTkFNRVwiKSwge1xuICAgIHZhbHVlOiBcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vYWRkXCIsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2Vcbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHJhbmRvbURlbGF5LCBTeW1ib2wuZm9yKFwiV09SS0ZMT1dfU1RFUF9GVU5DVElPTl9OQU1FXCIpLCB7XG4gICAgdmFsdWU6IFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9yYW5kb21EZWxheVwiLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlXG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShzcGVjaWZpY0RlbGF5LCBTeW1ib2wuZm9yKFwiV09SS0ZMT1dfU1RFUF9GVU5DVElPTl9OQU1FXCIpLCB7XG4gICAgdmFsdWU6IFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9zcGVjaWZpY0RlbGF5XCIsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2Vcbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHN0ZXBUaGF0RmFpbHMsIFN5bWJvbC5mb3IoXCJXT1JLRkxPV19TVEVQX0ZVTkNUSU9OX05BTUVcIiksIHtcbiAgICB2YWx1ZTogXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3N0ZXBUaGF0RmFpbHNcIixcbiAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiBmYWxzZVxufSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZ2VuUmVhZGFibGVTdHJlYW0sIFN5bWJvbC5mb3IoXCJXT1JLRkxPV19TVEVQX0ZVTkNUSU9OX05BTUVcIiksIHtcbiAgICB2YWx1ZTogXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL2dlblJlYWRhYmxlU3RyZWFtXCIsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2Vcbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHNlbmRXZWJob29rUmVzcG9uc2UsIFN5bWJvbC5mb3IoXCJXT1JLRkxPV19TVEVQX0ZVTkNUSU9OX05BTUVcIiksIHtcbiAgICB2YWx1ZTogXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3NlbmRXZWJob29rUmVzcG9uc2VcIixcbiAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiBmYWxzZVxufSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkobnVsbEJ5dGVTdGVwLCBTeW1ib2wuZm9yKFwiV09SS0ZMT1dfU1RFUF9GVU5DVElPTl9OQU1FXCIpLCB7XG4gICAgdmFsdWU6IFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9udWxsQnl0ZVN0ZXBcIixcbiAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiBmYWxzZVxufSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoc3RlcFdpdGhNZXRhZGF0YSwgU3ltYm9sLmZvcihcIldPUktGTE9XX1NURVBfRlVOQ1RJT05fTkFNRVwiKSwge1xuICAgIHZhbHVlOiBcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc3RlcFdpdGhNZXRhZGF0YVwiLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlXG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShzdGVwV2l0aE91dHB1dFN0cmVhbUJpbmFyeSwgU3ltYm9sLmZvcihcIldPUktGTE9XX1NURVBfRlVOQ1RJT05fTkFNRVwiKSwge1xuICAgIHZhbHVlOiBcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc3RlcFdpdGhPdXRwdXRTdHJlYW1CaW5hcnlcIixcbiAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiBmYWxzZVxufSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoc3RlcFdpdGhPdXRwdXRTdHJlYW1PYmplY3QsIFN5bWJvbC5mb3IoXCJXT1JLRkxPV19TVEVQX0ZVTkNUSU9OX05BTUVcIiksIHtcbiAgICB2YWx1ZTogXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3N0ZXBXaXRoT3V0cHV0U3RyZWFtT2JqZWN0XCIsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2Vcbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHN0ZXBDbG9zZU91dHB1dFN0cmVhbSwgU3ltYm9sLmZvcihcIldPUktGTE9XX1NURVBfRlVOQ1RJT05fTkFNRVwiKSwge1xuICAgIHZhbHVlOiBcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc3RlcENsb3NlT3V0cHV0U3RyZWFtXCIsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2Vcbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHN0ZXBXaXRoT3V0cHV0U3RyZWFtSW5zaWRlU3RlcCwgU3ltYm9sLmZvcihcIldPUktGTE9XX1NURVBfRlVOQ1RJT05fTkFNRVwiKSwge1xuICAgIHZhbHVlOiBcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc3RlcFdpdGhPdXRwdXRTdHJlYW1JbnNpZGVTdGVwXCIsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2Vcbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHN0ZXBXaXRoTmFtZWRPdXRwdXRTdHJlYW1JbnNpZGVTdGVwLCBTeW1ib2wuZm9yKFwiV09SS0ZMT1dfU1RFUF9GVU5DVElPTl9OQU1FXCIpLCB7XG4gICAgdmFsdWU6IFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9zdGVwV2l0aE5hbWVkT3V0cHV0U3RyZWFtSW5zaWRlU3RlcFwiLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlXG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShzdGVwQ2xvc2VPdXRwdXRTdHJlYW1JbnNpZGVTdGVwLCBTeW1ib2wuZm9yKFwiV09SS0ZMT1dfU1RFUF9GVU5DVElPTl9OQU1FXCIpLCB7XG4gICAgdmFsdWU6IFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9zdGVwQ2xvc2VPdXRwdXRTdHJlYW1JbnNpZGVTdGVwXCIsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2Vcbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHByb21pc2VSYWNlU3RyZXNzVGVzdERlbGF5U3RlcCwgU3ltYm9sLmZvcihcIldPUktGTE9XX1NURVBfRlVOQ1RJT05fTkFNRVwiKSwge1xuICAgIHZhbHVlOiBcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vcHJvbWlzZVJhY2VTdHJlc3NUZXN0RGVsYXlTdGVwXCIsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2Vcbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHN0ZXBUaGF0UmV0cmllc0FuZFN1Y2NlZWRzLCBTeW1ib2wuZm9yKFwiV09SS0ZMT1dfU1RFUF9GVU5DVElPTl9OQU1FXCIpLCB7XG4gICAgdmFsdWU6IFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9zdGVwVGhhdFJldHJpZXNBbmRTdWNjZWVkc1wiLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlXG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShzdGVwVGhhdFRocm93c1JldHJ5YWJsZUVycm9yLCBTeW1ib2wuZm9yKFwiV09SS0ZMT1dfU1RFUF9GVU5DVElPTl9OQU1FXCIpLCB7XG4gICAgdmFsdWU6IFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9zdGVwVGhhdFRocm93c1JldHJ5YWJsZUVycm9yXCIsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2Vcbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHN0ZXBXaXRoU3RlcEZ1bmN0aW9uQXJnLCBTeW1ib2wuZm9yKFwiV09SS0ZMT1dfU1RFUF9GVU5DVElPTl9OQU1FXCIpLCB7XG4gICAgdmFsdWU6IFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9zdGVwV2l0aFN0ZXBGdW5jdGlvbkFyZ1wiLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlXG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShkb3VibGVOdW1iZXIsIFN5bWJvbC5mb3IoXCJXT1JLRkxPV19TVEVQX0ZVTkNUSU9OX05BTUVcIiksIHtcbiAgICB2YWx1ZTogXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL2RvdWJsZU51bWJlclwiLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlXG59KTtcbiIsICJpbXBvcnQgdHlwZSB7IFN0cmluZ1ZhbHVlIH0gZnJvbSAnbXMnO1xuaW1wb3J0IG1zIGZyb20gJ21zJztcblxuZXhwb3J0IGludGVyZmFjZSBQcm9taXNlV2l0aFJlc29sdmVyczxUPiB7XG4gIHByb21pc2U6IFByb21pc2U8VD47XG4gIHJlc29sdmU6ICh2YWx1ZTogVCkgPT4gdm9pZDtcbiAgcmVqZWN0OiAocmVhc29uPzogYW55KSA9PiB2b2lkO1xufVxuXG4vKipcbiAqIFBvbHlmaWxsIGZvciBgUHJvbWlzZS53aXRoUmVzb2x2ZXJzKClgLlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvUHJvbWlzZS93aXRoUmVzb2x2ZXJzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3aXRoUmVzb2x2ZXJzPFQ+KCk6IFByb21pc2VXaXRoUmVzb2x2ZXJzPFQ+IHtcbiAgbGV0IHJlc29sdmUhOiAodmFsdWU6IFQpID0+IHZvaWQ7XG4gIGxldCByZWplY3QhOiAocmVhc29uPzogYW55KSA9PiB2b2lkO1xuICBjb25zdCBwcm9taXNlID0gbmV3IFByb21pc2U8VD4oKF9yZXNvbHZlLCBfcmVqZWN0KSA9PiB7XG4gICAgcmVzb2x2ZSA9IF9yZXNvbHZlO1xuICAgIHJlamVjdCA9IF9yZWplY3Q7XG4gIH0pO1xuICByZXR1cm4geyBwcm9taXNlLCByZXNvbHZlLCByZWplY3QgfTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbGF6aWx5LWV2YWx1YXRlZCwgbWVtb2l6ZWQgdmVyc2lvbiBvZiB0aGUgcHJvdmlkZWQgZnVuY3Rpb24uXG4gKlxuICogVGhlIHJldHVybmVkIG9iamVjdCBleHBvc2VzIGEgYHZhbHVlYCBnZXR0ZXIgdGhhdCBjYWxscyBgZm5gIG9ubHkgb25jZSxcbiAqIGNhY2hlcyBpdHMgcmVzdWx0LCBhbmQgcmV0dXJucyB0aGUgY2FjaGVkIHZhbHVlIG9uIHN1YnNlcXVlbnQgYWNjZXNzZXMuXG4gKlxuICogQHR5cGVQYXJhbSBUIC0gVGhlIHJldHVybiB0eXBlIG9mIHRoZSBwcm92aWRlZCBmdW5jdGlvbi5cbiAqIEBwYXJhbSBmbiAtIFRoZSBmdW5jdGlvbiB0byBiZSBjYWxsZWQgb25jZSBhbmQgd2hvc2UgcmVzdWx0IHdpbGwgYmUgY2FjaGVkLlxuICogQHJldHVybnMgQW4gb2JqZWN0IHdpdGggYSBgdmFsdWVgIHByb3BlcnR5IHRoYXQgcmV0dXJucyB0aGUgbWVtb2l6ZWQgcmVzdWx0IG9mIGBmbmAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvbmNlPFQ+KGZuOiAoKSA9PiBUKSB7XG4gIGNvbnN0IHJlc3VsdCA9IHtcbiAgICBnZXQgdmFsdWUoKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IGZuKCk7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocmVzdWx0LCAndmFsdWUnLCB7IHZhbHVlIH0pO1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH0sXG4gIH07XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogUGFyc2VzIGEgZHVyYXRpb24gcGFyYW1ldGVyIChzdHJpbmcsIG51bWJlciwgb3IgRGF0ZSkgYW5kIHJldHVybnMgYSBEYXRlIG9iamVjdFxuICogcmVwcmVzZW50aW5nIHdoZW4gdGhlIGR1cmF0aW9uIHNob3VsZCBlbGFwc2UuXG4gKlxuICogLSBGb3Igc3RyaW5nczogUGFyc2VzIGR1cmF0aW9uIHN0cmluZ3MgbGlrZSBcIjFzXCIsIFwiNW1cIiwgXCIxaFwiLCBldGMuIHVzaW5nIHRoZSBgbXNgIGxpYnJhcnlcbiAqIC0gRm9yIG51bWJlcnM6IFRyZWF0cyBhcyBtaWxsaXNlY29uZHMgZnJvbSBub3dcbiAqIC0gRm9yIERhdGUgb2JqZWN0czogUmV0dXJucyB0aGUgZGF0ZSBkaXJlY3RseSAoaGFuZGxlcyBib3RoIERhdGUgaW5zdGFuY2VzIGFuZCBkYXRlLWxpa2Ugb2JqZWN0cyBmcm9tIGRlc2VyaWFsaXphdGlvbilcbiAqXG4gKiBAcGFyYW0gcGFyYW0gLSBUaGUgZHVyYXRpb24gcGFyYW1ldGVyIChTdHJpbmdWYWx1ZSwgRGF0ZSwgb3IgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcylcbiAqIEByZXR1cm5zIEEgRGF0ZSBvYmplY3QgcmVwcmVzZW50aW5nIHdoZW4gdGhlIGR1cmF0aW9uIHNob3VsZCBlbGFwc2VcbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGFyYW1ldGVyIGlzIGludmFsaWQgb3IgY2Fubm90IGJlIHBhcnNlZFxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VEdXJhdGlvblRvRGF0ZShwYXJhbTogU3RyaW5nVmFsdWUgfCBEYXRlIHwgbnVtYmVyKTogRGF0ZSB7XG4gIGlmICh0eXBlb2YgcGFyYW0gPT09ICdzdHJpbmcnKSB7XG4gICAgY29uc3QgZHVyYXRpb25NcyA9IG1zKHBhcmFtKTtcbiAgICBpZiAodHlwZW9mIGR1cmF0aW9uTXMgIT09ICdudW1iZXInIHx8IGR1cmF0aW9uTXMgPCAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBJbnZhbGlkIGR1cmF0aW9uOiBcIiR7cGFyYW19XCIuIEV4cGVjdGVkIGEgdmFsaWQgZHVyYXRpb24gc3RyaW5nIGxpa2UgXCIxc1wiLCBcIjFtXCIsIFwiMWhcIiwgZXRjLmBcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgRGF0ZShEYXRlLm5vdygpICsgZHVyYXRpb25Ncyk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIHBhcmFtID09PSAnbnVtYmVyJykge1xuICAgIGlmIChwYXJhbSA8IDAgfHwgIU51bWJlci5pc0Zpbml0ZShwYXJhbSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEludmFsaWQgZHVyYXRpb246ICR7cGFyYW19LiBFeHBlY3RlZCBhIG5vbi1uZWdhdGl2ZSBmaW5pdGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcy5gXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IERhdGUoRGF0ZS5ub3coKSArIHBhcmFtKTtcbiAgfSBlbHNlIGlmIChcbiAgICBwYXJhbSBpbnN0YW5jZW9mIERhdGUgfHxcbiAgICAocGFyYW0gJiZcbiAgICAgIHR5cGVvZiBwYXJhbSA9PT0gJ29iamVjdCcgJiZcbiAgICAgIHR5cGVvZiAocGFyYW0gYXMgYW55KS5nZXRUaW1lID09PSAnZnVuY3Rpb24nKVxuICApIHtcbiAgICAvLyBIYW5kbGUgYm90aCBEYXRlIGluc3RhbmNlcyBhbmQgZGF0ZS1saWtlIG9iamVjdHMgKGZyb20gZGVzZXJpYWxpemF0aW9uKVxuICAgIHJldHVybiBwYXJhbSBpbnN0YW5jZW9mIERhdGUgPyBwYXJhbSA6IG5ldyBEYXRlKChwYXJhbSBhcyBhbnkpLmdldFRpbWUoKSk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYEludmFsaWQgZHVyYXRpb24gcGFyYW1ldGVyLiBFeHBlY3RlZCBhIGR1cmF0aW9uIHN0cmluZywgbnVtYmVyIChtaWxsaXNlY29uZHMpLCBvciBEYXRlIG9iamVjdC5gXG4gICAgKTtcbiAgfVxufVxuIiwgImltcG9ydCB7IHBhcnNlRHVyYXRpb25Ub0RhdGUgfSBmcm9tICdAd29ya2Zsb3cvdXRpbHMnO1xuaW1wb3J0IHR5cGUgeyBTdHJ1Y3R1cmVkRXJyb3IgfSBmcm9tICdAd29ya2Zsb3cvd29ybGQnO1xuaW1wb3J0IHR5cGUgeyBTdHJpbmdWYWx1ZSB9IGZyb20gJ21zJztcblxuY29uc3QgQkFTRV9VUkwgPSAnaHR0cHM6Ly91c2V3b3JrZmxvdy5kZXYvZXJyJztcblxuLyoqXG4gKiBAaW50ZXJuYWxcbiAqIENoZWNrIGlmIGEgdmFsdWUgaXMgYW4gRXJyb3Igd2l0aG91dCByZWx5aW5nIG9uIE5vZGUuanMgdXRpbGl0aWVzLlxuICogVGhpcyBpcyBuZWVkZWQgZm9yIGVycm9yIGNsYXNzZXMgdGhhdCBjYW4gYmUgdXNlZCBpbiBWTSBjb250ZXh0cyB3aGVyZVxuICogTm9kZS5qcyBpbXBvcnRzIGFyZSBub3QgYXZhaWxhYmxlLlxuICovXG5mdW5jdGlvbiBpc0Vycm9yKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgeyBuYW1lOiBzdHJpbmc7IG1lc3NhZ2U6IHN0cmluZyB9IHtcbiAgcmV0dXJuIChcbiAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXG4gICAgdmFsdWUgIT09IG51bGwgJiZcbiAgICAnbmFtZScgaW4gdmFsdWUgJiZcbiAgICAnbWVzc2FnZScgaW4gdmFsdWVcbiAgKTtcbn1cblxuLyoqXG4gKiBAaW50ZXJuYWxcbiAqIEFsbCB0aGUgc2x1Z3Mgb2YgdGhlIGVycm9ycyB1c2VkIGZvciBkb2N1bWVudGF0aW9uIGxpbmtzLlxuICovXG5leHBvcnQgY29uc3QgRVJST1JfU0xVR1MgPSB7XG4gIE5PREVfSlNfTU9EVUxFX0lOX1dPUktGTE9XOiAnbm9kZS1qcy1tb2R1bGUtaW4td29ya2Zsb3cnLFxuICBTVEFSVF9JTlZBTElEX1dPUktGTE9XX0ZVTkNUSU9OOiAnc3RhcnQtaW52YWxpZC13b3JrZmxvdy1mdW5jdGlvbicsXG4gIFNFUklBTElaQVRJT05fRkFJTEVEOiAnc2VyaWFsaXphdGlvbi1mYWlsZWQnLFxuICBXRUJIT09LX0lOVkFMSURfUkVTUE9ORF9XSVRIX1ZBTFVFOiAnd2ViaG9vay1pbnZhbGlkLXJlc3BvbmQtd2l0aC12YWx1ZScsXG4gIFdFQkhPT0tfUkVTUE9OU0VfTk9UX1NFTlQ6ICd3ZWJob29rLXJlc3BvbnNlLW5vdC1zZW50JyxcbiAgRkVUQ0hfSU5fV09SS0ZMT1dfRlVOQ1RJT046ICdmZXRjaC1pbi13b3JrZmxvdycsXG59IGFzIGNvbnN0O1xuXG50eXBlIEVycm9yU2x1ZyA9ICh0eXBlb2YgRVJST1JfU0xVR1MpW2tleW9mIHR5cGVvZiBFUlJPUl9TTFVHU107XG5cbmludGVyZmFjZSBXb3JrZmxvd0Vycm9yT3B0aW9ucyBleHRlbmRzIEVycm9yT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgc2x1ZyBvZiB0aGUgZXJyb3IuIFRoaXMgd2lsbCBiZSB1c2VkIHRvIGdlbmVyYXRlIGEgbGluayB0byB0aGUgZXJyb3IgZG9jdW1lbnRhdGlvbi5cbiAgICovXG4gIHNsdWc/OiBFcnJvclNsdWc7XG59XG5cbi8qKlxuICogVGhlIGJhc2UgY2xhc3MgZm9yIGFsbCBXb3JrZmxvdy1yZWxhdGVkIGVycm9ycy5cbiAqXG4gKiBUaGlzIGVycm9yIGlzIHRocm93biBieSB0aGUgV29ya2Zsb3cgRGV2S2l0IHdoZW4gaW50ZXJuYWwgb3BlcmF0aW9ucyBmYWlsLlxuICogWW91IGNhbiB1c2UgdGhpcyBjbGFzcyB3aXRoIGBpbnN0YW5jZW9mYCB0byBjYXRjaCBhbnkgV29ya2Zsb3cgRGV2S2l0IGVycm9yLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0c1xuICogdHJ5IHtcbiAqICAgYXdhaXQgZ2V0UnVuKHJ1bklkKTtcbiAqIH0gY2F0Y2ggKGVycm9yKSB7XG4gKiAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFdvcmtmbG93RXJyb3IpIHtcbiAqICAgICBjb25zb2xlLmVycm9yKCdXb3JrZmxvdyBEZXZLaXQgZXJyb3I6JywgZXJyb3IubWVzc2FnZSk7XG4gKiAgIH1cbiAqIH1cbiAqIGBgYFxuICovXG5leHBvcnQgY2xhc3MgV29ya2Zsb3dFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgcmVhZG9ubHkgY2F1c2U/OiB1bmtub3duO1xuXG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZywgb3B0aW9ucz86IFdvcmtmbG93RXJyb3JPcHRpb25zKSB7XG4gICAgY29uc3QgbXNnRG9jcyA9IG9wdGlvbnM/LnNsdWdcbiAgICAgID8gYCR7bWVzc2FnZX1cXG5cXG5MZWFybiBtb3JlOiAke0JBU0VfVVJMfS8ke29wdGlvbnMuc2x1Z31gXG4gICAgICA6IG1lc3NhZ2U7XG4gICAgc3VwZXIobXNnRG9jcywgeyBjYXVzZTogb3B0aW9ucz8uY2F1c2UgfSk7XG4gICAgdGhpcy5jYXVzZSA9IG9wdGlvbnM/LmNhdXNlO1xuXG4gICAgaWYgKG9wdGlvbnM/LmNhdXNlIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIHRoaXMuc3RhY2sgPSBgJHt0aGlzLnN0YWNrfVxcbkNhdXNlZCBieTogJHtvcHRpb25zLmNhdXNlLnN0YWNrfWA7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIGlzKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgV29ya2Zsb3dFcnJvciB7XG4gICAgcmV0dXJuIGlzRXJyb3IodmFsdWUpICYmIHZhbHVlLm5hbWUgPT09ICdXb3JrZmxvd0Vycm9yJztcbiAgfVxufVxuXG4vKipcbiAqIFRocm93biB3aGVuIGEgV29ya2Zsb3cgQVBJIHJlcXVlc3QgZmFpbHMuXG4gKlxuICogVGhpcyBlcnJvciBpcyB0aHJvd24gd2hlbiBIVFRQIHJlcXVlc3RzIHRvIHRoZSBXb3JrZmxvdyBiYWNrZW5kIGZhaWwsXG4gKiB0eXBpY2FsbHkgZHVlIHRvIG5ldHdvcmsgaXNzdWVzLCBpbnZhbGlkIHJlcXVlc3RzLCBvciBzZXJ2ZXIgZXJyb3JzLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0c1xuICogdHJ5IHtcbiAqICAgYXdhaXQgc3RhcnRXb3JrZmxvdygnbXlXb3JrZmxvdycsIGlucHV0KTtcbiAqIH0gY2F0Y2ggKGVycm9yKSB7XG4gKiAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFdvcmtmbG93QVBJRXJyb3IpIHtcbiAqICAgICBjb25zb2xlLmVycm9yKGBBUEkgZXJyb3IgKCR7ZXJyb3Iuc3RhdHVzfSk6YCwgZXJyb3IubWVzc2FnZSk7XG4gKiAgIH1cbiAqIH1cbiAqIGBgYFxuICovXG5leHBvcnQgY2xhc3MgV29ya2Zsb3dBUElFcnJvciBleHRlbmRzIFdvcmtmbG93RXJyb3Ige1xuICBzdGF0dXM/OiBudW1iZXI7XG4gIGNvZGU/OiBzdHJpbmc7XG4gIHVybD86IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBtZXNzYWdlOiBzdHJpbmcsXG4gICAgb3B0aW9ucz86IHsgc3RhdHVzPzogbnVtYmVyOyB1cmw/OiBzdHJpbmc7IGNvZGU/OiBzdHJpbmc7IGNhdXNlPzogdW5rbm93biB9XG4gICkge1xuICAgIHN1cGVyKG1lc3NhZ2UsIHtcbiAgICAgIGNhdXNlOiBvcHRpb25zPy5jYXVzZSxcbiAgICB9KTtcbiAgICB0aGlzLm5hbWUgPSAnV29ya2Zsb3dBUElFcnJvcic7XG4gICAgdGhpcy5zdGF0dXMgPSBvcHRpb25zPy5zdGF0dXM7XG4gICAgdGhpcy5jb2RlID0gb3B0aW9ucz8uY29kZTtcbiAgICB0aGlzLnVybCA9IG9wdGlvbnM/LnVybDtcbiAgfVxuXG4gIHN0YXRpYyBpcyh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIFdvcmtmbG93QVBJRXJyb3Ige1xuICAgIHJldHVybiBpc0Vycm9yKHZhbHVlKSAmJiB2YWx1ZS5uYW1lID09PSAnV29ya2Zsb3dBUElFcnJvcic7XG4gIH1cbn1cblxuLyoqXG4gKiBUaHJvd24gd2hlbiBhIHdvcmtmbG93IHJ1biBmYWlscyBkdXJpbmcgZXhlY3V0aW9uLlxuICpcbiAqIFRoaXMgZXJyb3IgaW5kaWNhdGVzIHRoYXQgdGhlIHdvcmtmbG93IGVuY291bnRlcmVkIGEgZmF0YWwgZXJyb3JcbiAqIGFuZCBjYW5ub3QgY29udGludWUuIFRoZSBgY2F1c2VgIHByb3BlcnR5IGNvbnRhaW5zIHRoZSB1bmRlcmx5aW5nXG4gKiBlcnJvciB3aXRoIGl0cyBtZXNzYWdlLCBzdGFjayB0cmFjZSwgYW5kIG9wdGlvbmFsIGVycm9yIGNvZGUuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYFxuICogY29uc3QgcnVuID0gYXdhaXQgZ2V0UnVuKHJ1bklkKTtcbiAqIGlmIChydW4uc3RhdHVzID09PSAnZmFpbGVkJykge1xuICogICAvLyBXb3JrZmxvd1J1bkZhaWxlZEVycm9yIHdpbGwgYmUgdGhyb3duXG4gKiB9XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNsYXNzIFdvcmtmbG93UnVuRmFpbGVkRXJyb3IgZXh0ZW5kcyBXb3JrZmxvd0Vycm9yIHtcbiAgcnVuSWQ6IHN0cmluZztcbiAgZGVjbGFyZSBjYXVzZTogRXJyb3IgJiB7IGNvZGU/OiBzdHJpbmcgfTtcblxuICBjb25zdHJ1Y3RvcihydW5JZDogc3RyaW5nLCBlcnJvcjogU3RydWN0dXJlZEVycm9yKSB7XG4gICAgLy8gQ3JlYXRlIGEgcHJvcGVyIEVycm9yIGluc3RhbmNlIGZyb20gdGhlIFN0cnVjdHVyZWRFcnJvciB0byBzZXQgYXMgY2F1c2VcbiAgICAvLyBOT1RFOiBjdXN0b20gZXJyb3IgdHlwZXMgZG8gbm90IGdldCBzZXJpYWxpemVkL2Rlc2VyaWFsaXplZC4gRXZlcnl0aGluZyBpcyBhbiBFcnJvclxuICAgIGNvbnN0IGNhdXNlRXJyb3IgPSBuZXcgRXJyb3IoZXJyb3IubWVzc2FnZSk7XG4gICAgaWYgKGVycm9yLnN0YWNrKSB7XG4gICAgICBjYXVzZUVycm9yLnN0YWNrID0gZXJyb3Iuc3RhY2s7XG4gICAgfVxuICAgIGlmIChlcnJvci5jb2RlKSB7XG4gICAgICAoY2F1c2VFcnJvciBhcyBhbnkpLmNvZGUgPSBlcnJvci5jb2RlO1xuICAgIH1cblxuICAgIHN1cGVyKGBXb3JrZmxvdyBydW4gXCIke3J1bklkfVwiIGZhaWxlZDogJHtlcnJvci5tZXNzYWdlfWAsIHtcbiAgICAgIGNhdXNlOiBjYXVzZUVycm9yLFxuICAgIH0pO1xuICAgIHRoaXMubmFtZSA9ICdXb3JrZmxvd1J1bkZhaWxlZEVycm9yJztcbiAgICB0aGlzLnJ1bklkID0gcnVuSWQ7XG4gIH1cblxuICBzdGF0aWMgaXModmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBXb3JrZmxvd1J1bkZhaWxlZEVycm9yIHtcbiAgICByZXR1cm4gaXNFcnJvcih2YWx1ZSkgJiYgdmFsdWUubmFtZSA9PT0gJ1dvcmtmbG93UnVuRmFpbGVkRXJyb3InO1xuICB9XG59XG5cbi8qKlxuICogVGhyb3duIHdoZW4gYXR0ZW1wdGluZyB0byBnZXQgcmVzdWx0cyBmcm9tIGFuIGluY29tcGxldGUgd29ya2Zsb3cgcnVuLlxuICpcbiAqIFRoaXMgZXJyb3Igb2NjdXJzIHdoZW4geW91IHRyeSB0byBhY2Nlc3MgdGhlIHJlc3VsdCBvZiBhIHdvcmtmbG93XG4gKiB0aGF0IGlzIHN0aWxsIHJ1bm5pbmcgb3IgaGFzbid0IGNvbXBsZXRlZCB5ZXQuXG4gKi9cbmV4cG9ydCBjbGFzcyBXb3JrZmxvd1J1bk5vdENvbXBsZXRlZEVycm9yIGV4dGVuZHMgV29ya2Zsb3dFcnJvciB7XG4gIHJ1bklkOiBzdHJpbmc7XG4gIHN0YXR1czogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHJ1bklkOiBzdHJpbmcsIHN0YXR1czogc3RyaW5nKSB7XG4gICAgc3VwZXIoYFdvcmtmbG93IHJ1biBcIiR7cnVuSWR9XCIgaGFzIG5vdCBjb21wbGV0ZWRgLCB7fSk7XG4gICAgdGhpcy5uYW1lID0gJ1dvcmtmbG93UnVuTm90Q29tcGxldGVkRXJyb3InO1xuICAgIHRoaXMucnVuSWQgPSBydW5JZDtcbiAgICB0aGlzLnN0YXR1cyA9IHN0YXR1cztcbiAgfVxuXG4gIHN0YXRpYyBpcyh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIFdvcmtmbG93UnVuTm90Q29tcGxldGVkRXJyb3Ige1xuICAgIHJldHVybiBpc0Vycm9yKHZhbHVlKSAmJiB2YWx1ZS5uYW1lID09PSAnV29ya2Zsb3dSdW5Ob3RDb21wbGV0ZWRFcnJvcic7XG4gIH1cbn1cblxuLyoqXG4gKiBUaHJvd24gd2hlbiB0aGUgV29ya2Zsb3cgcnVudGltZSBlbmNvdW50ZXJzIGFuIGludGVybmFsIGVycm9yLlxuICpcbiAqIFRoaXMgZXJyb3IgaW5kaWNhdGVzIGFuIGlzc3VlIHdpdGggd29ya2Zsb3cgZXhlY3V0aW9uLCBzdWNoIGFzXG4gKiBzZXJpYWxpemF0aW9uIGZhaWx1cmVzLCBzdGFydGluZyBhbiBpbnZhbGlkIHdvcmtmbG93IGZ1bmN0aW9uLCBvclxuICogb3RoZXIgcnVudGltZSBwcm9ibGVtcy5cbiAqL1xuZXhwb3J0IGNsYXNzIFdvcmtmbG93UnVudGltZUVycm9yIGV4dGVuZHMgV29ya2Zsb3dFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZywgb3B0aW9ucz86IFdvcmtmbG93RXJyb3JPcHRpb25zKSB7XG4gICAgc3VwZXIobWVzc2FnZSwge1xuICAgICAgLi4ub3B0aW9ucyxcbiAgICB9KTtcbiAgICB0aGlzLm5hbWUgPSAnV29ya2Zsb3dSdW50aW1lRXJyb3InO1xuICB9XG5cbiAgc3RhdGljIGlzKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgV29ya2Zsb3dSdW50aW1lRXJyb3Ige1xuICAgIHJldHVybiBpc0Vycm9yKHZhbHVlKSAmJiB2YWx1ZS5uYW1lID09PSAnV29ya2Zsb3dSdW50aW1lRXJyb3InO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBXb3JrZmxvd1J1bk5vdEZvdW5kRXJyb3IgZXh0ZW5kcyBXb3JrZmxvd0Vycm9yIHtcbiAgcnVuSWQ6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihydW5JZDogc3RyaW5nKSB7XG4gICAgc3VwZXIoYFdvcmtmbG93IHJ1biBcIiR7cnVuSWR9XCIgbm90IGZvdW5kYCwge30pO1xuICAgIHRoaXMubmFtZSA9ICdXb3JrZmxvd1J1bk5vdEZvdW5kRXJyb3InO1xuICAgIHRoaXMucnVuSWQgPSBydW5JZDtcbiAgfVxuXG4gIHN0YXRpYyBpcyh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIFdvcmtmbG93UnVuTm90Rm91bmRFcnJvciB7XG4gICAgcmV0dXJuIGlzRXJyb3IodmFsdWUpICYmIHZhbHVlLm5hbWUgPT09ICdXb3JrZmxvd1J1bk5vdEZvdW5kRXJyb3InO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBXb3JrZmxvd1J1bkNhbmNlbGxlZEVycm9yIGV4dGVuZHMgV29ya2Zsb3dFcnJvciB7XG4gIHJ1bklkOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IocnVuSWQ6IHN0cmluZykge1xuICAgIHN1cGVyKGBXb3JrZmxvdyBydW4gXCIke3J1bklkfVwiIGNhbmNlbGxlZGAsIHt9KTtcbiAgICB0aGlzLm5hbWUgPSAnV29ya2Zsb3dSdW5DYW5jZWxsZWRFcnJvcic7XG4gICAgdGhpcy5ydW5JZCA9IHJ1bklkO1xuICB9XG5cbiAgc3RhdGljIGlzKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgV29ya2Zsb3dSdW5DYW5jZWxsZWRFcnJvciB7XG4gICAgcmV0dXJuIGlzRXJyb3IodmFsdWUpICYmIHZhbHVlLm5hbWUgPT09ICdXb3JrZmxvd1J1bkNhbmNlbGxlZEVycm9yJztcbiAgfVxufVxuXG4vKipcbiAqIEEgZmF0YWwgZXJyb3IgaXMgYW4gZXJyb3IgdGhhdCBjYW5ub3QgYmUgcmV0cmllZC5cbiAqIEl0IHdpbGwgY2F1c2UgdGhlIHN0ZXAgdG8gZmFpbCBhbmQgdGhlIGVycm9yIHdpbGxcbiAqIGJlIGJ1YmJsZWQgdXAgdG8gdGhlIHdvcmtmbG93IGxvZ2ljLlxuICovXG5leHBvcnQgY2xhc3MgRmF0YWxFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgZmF0YWwgPSB0cnVlO1xuXG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZykge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIHRoaXMubmFtZSA9ICdGYXRhbEVycm9yJztcbiAgfVxuXG4gIHN0YXRpYyBpcyh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIEZhdGFsRXJyb3Ige1xuICAgIHJldHVybiBpc0Vycm9yKHZhbHVlKSAmJiB2YWx1ZS5uYW1lID09PSAnRmF0YWxFcnJvcic7XG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZXRyeWFibGVFcnJvck9wdGlvbnMge1xuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgdG8gd2FpdCBiZWZvcmUgcmV0cnlpbmcgdGhlIHN0ZXAuXG4gICAqIENhbiBhbHNvIGJlIGEgZHVyYXRpb24gc3RyaW5nIChlLmcuLCBcIjVzXCIsIFwiMm1cIikgb3IgYSBEYXRlIG9iamVjdC5cbiAgICogSWYgbm90IHByb3ZpZGVkLCB0aGUgc3RlcCB3aWxsIGJlIHJldHJpZWQgYWZ0ZXIgMSBzZWNvbmQgKDEwMDAgbWlsbGlzZWNvbmRzKS5cbiAgICovXG4gIHJldHJ5QWZ0ZXI/OiBudW1iZXIgfCBTdHJpbmdWYWx1ZSB8IERhdGU7XG59XG5cbi8qKlxuICogQW4gZXJyb3IgdGhhdCBjYW4gaGFwcGVuIGR1cmluZyBhIHN0ZXAgZXhlY3V0aW9uLCBhbGxvd2luZ1xuICogZm9yIGNvbmZpZ3VyYXRpb24gb2YgdGhlIHJldHJ5IGJlaGF2aW9yLlxuICovXG5leHBvcnQgY2xhc3MgUmV0cnlhYmxlRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIC8qKlxuICAgKiBUaGUgRGF0ZSB3aGVuIHRoZSBzdGVwIHNob3VsZCBiZSByZXRyaWVkLlxuICAgKi9cbiAgcmV0cnlBZnRlcjogRGF0ZTtcblxuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcsIG9wdGlvbnM6IFJldHJ5YWJsZUVycm9yT3B0aW9ucyA9IHt9KSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gICAgdGhpcy5uYW1lID0gJ1JldHJ5YWJsZUVycm9yJztcblxuICAgIGlmIChvcHRpb25zLnJldHJ5QWZ0ZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5yZXRyeUFmdGVyID0gcGFyc2VEdXJhdGlvblRvRGF0ZShvcHRpb25zLnJldHJ5QWZ0ZXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBEZWZhdWx0IHRvIDEgc2Vjb25kICgxMDAwIG1pbGxpc2Vjb25kcylcbiAgICAgIHRoaXMucmV0cnlBZnRlciA9IG5ldyBEYXRlKERhdGUubm93KCkgKyAxMDAwKTtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgaXModmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBSZXRyeWFibGVFcnJvciB7XG4gICAgcmV0dXJuIGlzRXJyb3IodmFsdWUpICYmIHZhbHVlLm5hbWUgPT09ICdSZXRyeWFibGVFcnJvcic7XG4gIH1cbn1cbiIsICJleHBvcnQgY29uc3QgV09SS0ZMT1dfVVNFX1NURVAgPSBTeW1ib2wuZm9yKCdXT1JLRkxPV19VU0VfU1RFUCcpO1xuZXhwb3J0IGNvbnN0IFdPUktGTE9XX0NSRUFURV9IT09LID0gU3ltYm9sLmZvcignV09SS0ZMT1dfQ1JFQVRFX0hPT0snKTtcbmV4cG9ydCBjb25zdCBXT1JLRkxPV19TTEVFUCA9IFN5bWJvbC5mb3IoJ1dPUktGTE9XX1NMRUVQJyk7XG5leHBvcnQgY29uc3QgV09SS0ZMT1dfQ09OVEVYVCA9IFN5bWJvbC5mb3IoJ1dPUktGTE9XX0NPTlRFWFQnKTtcbmV4cG9ydCBjb25zdCBXT1JLRkxPV19HRVRfU1RSRUFNX0lEID0gU3ltYm9sLmZvcignV09SS0ZMT1dfR0VUX1NUUkVBTV9JRCcpO1xuZXhwb3J0IGNvbnN0IFNUUkVBTV9OQU1FX1NZTUJPTCA9IFN5bWJvbC5mb3IoJ1dPUktGTE9XX1NUUkVBTV9OQU1FJyk7XG5leHBvcnQgY29uc3QgU1RSRUFNX1RZUEVfU1lNQk9MID0gU3ltYm9sLmZvcignV09SS0ZMT1dfU1RSRUFNX1RZUEUnKTtcbmV4cG9ydCBjb25zdCBCT0RZX0lOSVRfU1lNQk9MID0gU3ltYm9sLmZvcignQk9EWV9JTklUJyk7XG5leHBvcnQgY29uc3QgV0VCSE9PS19SRVNQT05TRV9XUklUQUJMRSA9IFN5bWJvbC5mb3IoXG4gICdXRUJIT09LX1JFU1BPTlNFX1dSSVRBQkxFJ1xuKTtcbmV4cG9ydCBjb25zdCBTVEVQX0ZVTkNUSU9OX05BTUVfU1lNQk9MID0gU3ltYm9sLmZvcihcbiAgJ1dPUktGTE9XX1NURVBfRlVOQ1RJT05fTkFNRSdcbik7XG4iLCAiZXhwb3J0IGludGVyZmFjZSBXb3JrZmxvd01ldGFkYXRhIHtcbiAgLyoqXG4gICAqIFVuaXF1ZSBpZGVudGlmaWVyIGZvciB0aGUgd29ya2Zsb3cgcnVuLlxuICAgKi9cbiAgd29ya2Zsb3dSdW5JZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaW1lc3RhbXAgd2hlbiB0aGUgd29ya2Zsb3cgcnVuIHN0YXJ0ZWQuXG4gICAqL1xuICB3b3JrZmxvd1N0YXJ0ZWRBdDogRGF0ZTtcblxuICAvKipcbiAgICogVGhlIFVSTCB3aGVyZSB0aGUgd29ya2Zsb3cgY2FuIGJlIHRyaWdnZXJlZC5cbiAgICovXG4gIHVybDogc3RyaW5nO1xufVxuXG5leHBvcnQgY29uc3QgV09SS0ZMT1dfQ09OVEVYVF9TWU1CT0wgPVxuICAvKiBAX19QVVJFX18gKi8gU3ltYm9sLmZvcignV09SS0ZMT1dfQ09OVEVYVCcpO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0V29ya2Zsb3dNZXRhZGF0YSgpOiBXb3JrZmxvd01ldGFkYXRhIHtcbiAgLy8gSW5zaWRlIHRoZSB3b3JrZmxvdyBWTSwgdGhlIGNvbnRleHQgaXMgc3RvcmVkIGluIHRoZSBnbG9iYWxUaGlzIG9iamVjdCBiZWhpbmQgYSBzeW1ib2xcbiAgY29uc3QgY3R4ID0gKGdsb2JhbFRoaXMgYXMgYW55KVtXT1JLRkxPV19DT05URVhUX1NZTUJPTF0gYXMgV29ya2Zsb3dNZXRhZGF0YTtcbiAgaWYgKCFjdHgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnYGdldFdvcmtmbG93TWV0YWRhdGEoKWAgY2FuIG9ubHkgYmUgY2FsbGVkIGluc2lkZSBhIHdvcmtmbG93IG9yIHN0ZXAgZnVuY3Rpb24nXG4gICAgKTtcbiAgfVxuICByZXR1cm4gY3R4O1xufVxuIiwgImltcG9ydCB0eXBlIHtcbiAgSG9vayxcbiAgSG9va09wdGlvbnMsXG4gIFJlcXVlc3RXaXRoUmVzcG9uc2UsXG4gIFdlYmhvb2ssXG4gIFdlYmhvb2tPcHRpb25zLFxufSBmcm9tICcuLi9jcmVhdGUtaG9vay5qcyc7XG5pbXBvcnQgeyBXT1JLRkxPV19DUkVBVEVfSE9PSyB9IGZyb20gJy4uL3N5bWJvbHMuanMnO1xuaW1wb3J0IHsgZ2V0V29ya2Zsb3dNZXRhZGF0YSB9IGZyb20gJy4vZ2V0LXdvcmtmbG93LW1ldGFkYXRhLmpzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUhvb2s8VCA9IGFueT4ob3B0aW9ucz86IEhvb2tPcHRpb25zKTogSG9vazxUPiB7XG4gIC8vIEluc2lkZSB0aGUgd29ya2Zsb3cgVk0sIHRoZSBob29rIGZ1bmN0aW9uIGlzIHN0b3JlZCBpbiB0aGUgZ2xvYmFsVGhpcyBvYmplY3QgYmVoaW5kIGEgc3ltYm9sXG4gIGNvbnN0IGNyZWF0ZUhvb2tGbiA9IChnbG9iYWxUaGlzIGFzIGFueSlbXG4gICAgV09SS0ZMT1dfQ1JFQVRFX0hPT0tcbiAgXSBhcyB0eXBlb2YgY3JlYXRlSG9vazxUPjtcbiAgaWYgKCFjcmVhdGVIb29rRm4pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnYGNyZWF0ZUhvb2soKWAgY2FuIG9ubHkgYmUgY2FsbGVkIGluc2lkZSBhIHdvcmtmbG93IGZ1bmN0aW9uJ1xuICAgICk7XG4gIH1cbiAgcmV0dXJuIGNyZWF0ZUhvb2tGbihvcHRpb25zKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVdlYmhvb2soXG4gIG9wdGlvbnM6IFdlYmhvb2tPcHRpb25zICYgeyByZXNwb25kV2l0aDogJ21hbnVhbCcgfVxuKTogV2ViaG9vazxSZXF1ZXN0V2l0aFJlc3BvbnNlPjtcbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVXZWJob29rKG9wdGlvbnM/OiBXZWJob29rT3B0aW9ucyk6IFdlYmhvb2s8UmVxdWVzdD47XG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlV2ViaG9vayhcbiAgb3B0aW9ucz86IFdlYmhvb2tPcHRpb25zXG4pOiBXZWJob29rPFJlcXVlc3Q+IHwgV2ViaG9vazxSZXF1ZXN0V2l0aFJlc3BvbnNlPiB7XG4gIGNvbnN0IHsgcmVzcG9uZFdpdGgsIC4uLnJlc3QgfSA9IG9wdGlvbnMgPz8ge307XG4gIGxldCBtZXRhZGF0YTogUGljazxXZWJob29rT3B0aW9ucywgJ3Jlc3BvbmRXaXRoJz4gfCB1bmRlZmluZWQ7XG4gIGlmICh0eXBlb2YgcmVzcG9uZFdpdGggIT09ICd1bmRlZmluZWQnKSB7XG4gICAgbWV0YWRhdGEgPSB7IHJlc3BvbmRXaXRoIH07XG4gIH1cblxuICBjb25zdCBob29rID0gY3JlYXRlSG9vayh7IC4uLnJlc3QsIG1ldGFkYXRhIH0pIGFzXG4gICAgfCBXZWJob29rPFJlcXVlc3Q+XG4gICAgfCBXZWJob29rPFJlcXVlc3RXaXRoUmVzcG9uc2U+O1xuXG4gIGNvbnN0IHsgdXJsIH0gPSBnZXRXb3JrZmxvd01ldGFkYXRhKCk7XG4gIGhvb2sudXJsID0gYCR7dXJsfS8ud2VsbC1rbm93bi93b3JrZmxvdy92MS93ZWJob29rLyR7ZW5jb2RlVVJJQ29tcG9uZW50KGhvb2sudG9rZW4pfWA7XG5cbiAgcmV0dXJuIGhvb2s7XG59XG4iLCAiaW1wb3J0IHR5cGUgeyBTdHJpbmdWYWx1ZSB9IGZyb20gJ21zJztcbmltcG9ydCB7IFdPUktGTE9XX1NMRUVQIH0gZnJvbSAnLi9zeW1ib2xzLmpzJztcblxuLyoqXG4gKiBTbGVlcCB3aXRoaW4gYSB3b3JrZmxvdyBmb3IgYSBnaXZlbiBkdXJhdGlvbi5cbiAqXG4gKiBUaGlzIGlzIGEgYnVpbHQtaW4gcnVudGltZSBmdW5jdGlvbiB0aGF0IHVzZXMgdGltZXIgZXZlbnRzIGluIHRoZSBldmVudCBsb2cuXG4gKlxuICogQHBhcmFtIGR1cmF0aW9uIC0gVGhlIGR1cmF0aW9uIHRvIHNsZWVwIGZvciwgdGhpcyBpcyBhIHN0cmluZyBpbiB0aGUgZm9ybWF0XG4gKiBvZiBgXCIxMDAwbXNcImAsIGBcIjFzXCJgLCBgXCIxbVwiYCwgYFwiMWhcImAsIG9yIGBcIjFkXCJgLlxuICogQG92ZXJsb2FkXG4gKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBzbGVlcCBpcyBjb21wbGV0ZS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNsZWVwKGR1cmF0aW9uOiBTdHJpbmdWYWx1ZSk6IFByb21pc2U8dm9pZD47XG5cbi8qKlxuICogU2xlZXAgd2l0aGluIGEgd29ya2Zsb3cgdW50aWwgYSBzcGVjaWZpYyBkYXRlLlxuICpcbiAqIFRoaXMgaXMgYSBidWlsdC1pbiBydW50aW1lIGZ1bmN0aW9uIHRoYXQgdXNlcyB0aW1lciBldmVudHMgaW4gdGhlIGV2ZW50IGxvZy5cbiAqXG4gKiBAcGFyYW0gZGF0ZSAtIFRoZSBkYXRlIHRvIHNsZWVwIHVudGlsLCB0aGlzIG11c3QgYmUgYSBmdXR1cmUgZGF0ZS5cbiAqIEBvdmVybG9hZFxuICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgc2xlZXAgaXMgY29tcGxldGUuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzbGVlcChkYXRlOiBEYXRlKTogUHJvbWlzZTx2b2lkPjtcblxuLyoqXG4gKiBTbGVlcCB3aXRoaW4gYSB3b3JrZmxvdyBmb3IgYSBnaXZlbiBkdXJhdGlvbiBpbiBtaWxsaXNlY29uZHMuXG4gKlxuICogVGhpcyBpcyBhIGJ1aWx0LWluIHJ1bnRpbWUgZnVuY3Rpb24gdGhhdCB1c2VzIHRpbWVyIGV2ZW50cyBpbiB0aGUgZXZlbnQgbG9nLlxuICpcbiAqIEBwYXJhbSBkdXJhdGlvbk1zIC0gVGhlIGR1cmF0aW9uIHRvIHNsZWVwIGZvciBpbiBtaWxsaXNlY29uZHMuXG4gKiBAb3ZlcmxvYWRcbiAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIHNsZWVwIGlzIGNvbXBsZXRlLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc2xlZXAoZHVyYXRpb25NczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPjtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNsZWVwKHBhcmFtOiBTdHJpbmdWYWx1ZSB8IERhdGUgfCBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgLy8gSW5zaWRlIHRoZSB3b3JrZmxvdyBWTSwgdGhlIHNsZWVwIGZ1bmN0aW9uIGlzIHN0b3JlZCBpbiB0aGUgZ2xvYmFsVGhpcyBvYmplY3QgYmVoaW5kIGEgc3ltYm9sXG4gIGNvbnN0IHNsZWVwRm4gPSAoZ2xvYmFsVGhpcyBhcyBhbnkpW1dPUktGTE9XX1NMRUVQXTtcbiAgaWYgKCFzbGVlcEZuKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdgc2xlZXAoKWAgY2FuIG9ubHkgYmUgY2FsbGVkIGluc2lkZSBhIHdvcmtmbG93IGZ1bmN0aW9uJyk7XG4gIH1cbiAgcmV0dXJuIHNsZWVwRm4ocGFyYW0pO1xufVxuIiwgImltcG9ydCB7IFNUUkVBTV9OQU1FX1NZTUJPTCwgV09SS0ZMT1dfR0VUX1NUUkVBTV9JRCB9IGZyb20gJy4uL3N5bWJvbHMuanMnO1xuaW1wb3J0IHR5cGUgeyBXb3JrZmxvd1dyaXRhYmxlU3RyZWFtT3B0aW9ucyB9IGZyb20gJy4uL3dyaXRhYmxlLXN0cmVhbS5qcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRXcml0YWJsZTxXID0gYW55PihcbiAgb3B0aW9uczogV29ya2Zsb3dXcml0YWJsZVN0cmVhbU9wdGlvbnMgPSB7fVxuKTogV3JpdGFibGVTdHJlYW08Vz4ge1xuICBjb25zdCB7IG5hbWVzcGFjZSB9ID0gb3B0aW9ucztcbiAgY29uc3QgbmFtZSA9IChnbG9iYWxUaGlzIGFzIGFueSlbV09SS0ZMT1dfR0VUX1NUUkVBTV9JRF0obmFtZXNwYWNlKTtcbiAgcmV0dXJuIE9iamVjdC5jcmVhdGUoZ2xvYmFsVGhpcy5Xcml0YWJsZVN0cmVhbS5wcm90b3R5cGUsIHtcbiAgICBbU1RSRUFNX05BTUVfU1lNQk9MXToge1xuICAgICAgdmFsdWU6IG5hbWUsXG4gICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgfSxcbiAgfSk7XG59XG4iLCAiLyoqXG4gKiBUaGlzIGlzIHRoZSBcInN0YW5kYXJkIGxpYnJhcnlcIiBvZiBzdGVwcyB0aGF0IHdlIG1ha2UgYXZhaWxhYmxlIHRvIGFsbCB3b3JrZmxvdyB1c2Vycy5cbiAqIFRoZSBjYW4gYmUgaW1wb3J0ZWQgbGlrZSBzbzogYGltcG9ydCB7IGZldGNoIH0gZnJvbSAnd29ya2Zsb3cnYC4gYW5kIHVzZWQgaW4gd29ya2Zsb3cuXG4gKiBUaGUgbmVlZCB0byBiZSBleHBvcnRlZCBkaXJlY3RseSBpbiB0aGlzIHBhY2thZ2UgYW5kIGNhbm5vdCBsaXZlIGluIGBjb3JlYCB0byBwcmV2ZW50XG4gKiBjaXJjdWxhciBkZXBlbmRlbmNpZXMgcG9zdC1jb21waWxhdGlvbi5cbiAqL1xuXG4vKipcbiAqIEEgaG9pc3RlZCBgZmV0Y2goKWAgZnVuY3Rpb24gdGhhdCBpcyBleGVjdXRlZCBhcyBhIFwic3RlcFwiIGZ1bmN0aW9uLFxuICogZm9yIHVzZSB3aXRoaW4gd29ya2Zsb3cgZnVuY3Rpb25zLlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0ZldGNoX0FQSVxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZmV0Y2goLi4uYXJnczogUGFyYW1ldGVyczx0eXBlb2YgZ2xvYmFsVGhpcy5mZXRjaD4pIHtcbiAgJ3VzZSBzdGVwJztcbiAgcmV0dXJuIGdsb2JhbFRoaXMuZmV0Y2goLi4uYXJncyk7XG59XG4iLCAiLy8gU2hhcmVkIGhlbHBlciBmdW5jdGlvbnMgdGhhdCBjYW4gYmUgaW1wb3J0ZWQgYnkgd29ya2Zsb3dzXG5leHBvcnQgZnVuY3Rpb24gdGhyb3dFcnJvcigpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0Vycm9yIGZyb20gaW1wb3J0ZWQgaGVscGVyIG1vZHVsZScpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGNhbGxUaHJvd2VyKCkge1xuICAgIHRocm93RXJyb3IoKTtcbn1cbiIsICIvKipfX2ludGVybmFsX3dvcmtmbG93c3tcIndvcmtmbG93c1wiOntcImV4YW1wbGUvd29ya2Zsb3dzLzJfY29udHJvbF9mbG93LnRzXCI6e1wiY29udHJvbF9mbG93XCI6e1wid29ya2Zsb3dJZFwiOlwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzJfY29udHJvbF9mbG93LnRzLy9jb250cm9sX2Zsb3dcIn19fSxcInN0ZXBzXCI6e1wiZXhhbXBsZS93b3JrZmxvd3MvMl9jb250cm9sX2Zsb3cudHNcIjp7XCJhZGRcIjp7XCJzdGVwSWRcIjpcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzJfY29udHJvbF9mbG93LnRzLy9hZGRcIn0sXCJkZWxheWVkTWVzc2FnZVwiOntcInN0ZXBJZFwiOlwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvMl9jb250cm9sX2Zsb3cudHMvL2RlbGF5ZWRNZXNzYWdlXCJ9LFwiZmFpbGluZ1N0ZXBcIjp7XCJzdGVwSWRcIjpcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzJfY29udHJvbF9mbG93LnRzLy9mYWlsaW5nU3RlcFwifSxcInJldHJ5YWJsZVN0ZXBcIjp7XCJzdGVwSWRcIjpcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzJfY29udHJvbF9mbG93LnRzLy9yZXRyeWFibGVTdGVwXCJ9fX19Ki87XG5hc3luYyBmdW5jdGlvbiBkZWxheWVkTWVzc2FnZShtcywgbWVzc2FnZSkge1xuICAgIHJldHVybiBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19VU0VfU1RFUFwiKV0oXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy8yX2NvbnRyb2xfZmxvdy50cy8vZGVsYXllZE1lc3NhZ2VcIikobXMsIG1lc3NhZ2UpO1xufVxuYXN5bmMgZnVuY3Rpb24gYWRkKGEsIGIpIHtcbiAgICByZXR1cm4gZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildKFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvMl9jb250cm9sX2Zsb3cudHMvL2FkZFwiKShhLCBiKTtcbn1cbmFzeW5jIGZ1bmN0aW9uIGZhaWxpbmdTdGVwKCkge1xuICAgIHJldHVybiBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19VU0VfU1RFUFwiKV0oXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy8yX2NvbnRyb2xfZmxvdy50cy8vZmFpbGluZ1N0ZXBcIikoKTtcbn1cbmFzeW5jIGZ1bmN0aW9uIHJldHJ5YWJsZVN0ZXAoKSB7XG4gICAgcmV0dXJuIGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1VTRV9TVEVQXCIpXShcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzJfY29udHJvbF9mbG93LnRzLy9yZXRyeWFibGVTdGVwXCIpKCk7XG59XG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY29udHJvbF9mbG93KCkge1xuICAgIGNvbnNvbGUubG9nKCdDb250cm9sIGZsb3cgd29ya2Zsb3cgc3RhcnRlZCcpO1xuICAgIC8vIERlbW8gUHJvbWlzZS5yYWNlXG4gICAgY29uc3QgcmFjZVJlc3VsdCA9IGF3YWl0IFByb21pc2UucmFjZShbXG4gICAgICAgIGRlbGF5ZWRNZXNzYWdlKDIwMDAsICdJIHdvbiB0aGUgcmFjZSEnKSxcbiAgICAgICAgZGVsYXllZE1lc3NhZ2UoMTAwMDAsICdJIGxvc3QgdGhlIHJhY2UnKVxuICAgIF0pO1xuICAgIGNvbnNvbGUubG9nKCdSYWNlIHJlc3VsdDonLCByYWNlUmVzdWx0KTtcbiAgICAvLyBEZW1vIFByb21pc2UuYWxsXG4gICAgY29uc3QgYWxsUmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgZGVsYXllZE1lc3NhZ2UoMTAwMCwgJ0ZpcnN0IHRhc2snKSxcbiAgICAgICAgZGVsYXllZE1lc3NhZ2UoMjAwMCwgJ1NlY29uZCB0YXNrJyksXG4gICAgICAgIGFkZCgxMCwgMjApXG4gICAgXSk7XG4gICAgY29uc29sZS5sb2coJ0FsbCByZXN1bHRzOicsIGFsbFJlc3VsdHMpO1xuICAgIC8vIEtpY2sgb2ZmIGEgc3RlcCBub3csIGFuZCByZXNvbHZlIGl0IGxhdGVyXG4gICAgY29uc3QgYmFja2dyb3VuZFByb21pc2UgPSBkZWxheWVkTWVzc2FnZSg1MDAwLCAnQmFja2dyb3VuZCB0YXNrIGNvbXBsZXRlZCcpO1xuICAgIGNvbnN0IGZvcmVncm91bmRSZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICBkZWxheWVkTWVzc2FnZSgxMDAwLCAnRmlyc3QgdGFzaycpLFxuICAgICAgICBkZWxheWVkTWVzc2FnZSgyMDAwLCAnU2Vjb25kIHRhc2snKVxuICAgIF0pO1xuICAgIGNvbnNvbGUubG9nKCdGb3JlZ3JvdW5kIHJlc3BvbnNlOicsIGZvcmVncm91bmRSZXN1bHRzKTtcbiAgICBjb25zdCBiYWNrZ3JvdW5kUmVzdWx0ID0gYXdhaXQgYmFja2dyb3VuZFByb21pc2U7XG4gICAgY29uc29sZS5sb2coJ0JhY2tncm91bmQgcmVzcG9uc2U6JywgYmFja2dyb3VuZFJlc3VsdCk7XG4gICAgLy8gRGVtbyBlcnJvciBoYW5kbGluZyAtIGNhdGNoIHJlZ3VsYXIgZXJyb3JzIGJ1dCBsZXQgRmF0YWxFcnJvcnMgYnViYmxlIHVwXG4gICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgZmFpbGluZ1N0ZXAoKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBPbmx5IEZhdGFsRXJyb3JzIHdpbGwgYnViYmxlIHVwIGhlcmUuIE5vbi1mYXRhbCBlcnJvcnMgYXJlIHJldHJpZWRcbiAgICAgICAgY29uc29sZS5sb2coJ0NhdWdodCBlcnJvcjonLCBTdHJpbmcoZXJyb3IpKTtcbiAgICB9XG4gICAgLy8gRGVtbyByZXRyeWFibGUgZXJyb3IgLSB0aGlzIHdpbGwgZmFpbCB0aGUgZmlyc3QgdGltZSxcbiAgICAvLyBhbmQgd2lsbCBiZSByZXRyaWVkIGFmdGVyIG9uZSBtaW51dGUuXG4gICAgYXdhaXQgcmV0cnlhYmxlU3RlcCgpO1xuICAgIGNvbnNvbGUubG9nKCdDb250cm9sIGZsb3cgd29ya2Zsb3cgY29tcGxldGVkLiBTZWUgbG9ncyBmb3IgcmVzdWx0cy4nKTtcbiAgICByZXR1cm4ge1xuICAgICAgICByYWNlUmVzdWx0LFxuICAgICAgICBhbGxSZXN1bHRzLFxuICAgICAgICBmb3JlZ3JvdW5kUmVzdWx0cyxcbiAgICAgICAgYmFja2dyb3VuZFJlc3VsdFxuICAgIH07XG59XG5jb250cm9sX2Zsb3cud29ya2Zsb3dJZCA9IFwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzJfY29udHJvbF9mbG93LnRzLy9jb250cm9sX2Zsb3dcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShkZWxheWVkTWVzc2FnZSwgU3ltYm9sLmZvcihcIldPUktGTE9XX1NURVBfRlVOQ1RJT05fTkFNRVwiKSwge1xuICAgIHZhbHVlOiBcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzJfY29udHJvbF9mbG93LnRzLy9kZWxheWVkTWVzc2FnZVwiLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlXG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShhZGQsIFN5bWJvbC5mb3IoXCJXT1JLRkxPV19TVEVQX0ZVTkNUSU9OX05BTUVcIiksIHtcbiAgICB2YWx1ZTogXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy8yX2NvbnRyb2xfZmxvdy50cy8vYWRkXCIsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2Vcbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGZhaWxpbmdTdGVwLCBTeW1ib2wuZm9yKFwiV09SS0ZMT1dfU1RFUF9GVU5DVElPTl9OQU1FXCIpLCB7XG4gICAgdmFsdWU6IFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvMl9jb250cm9sX2Zsb3cudHMvL2ZhaWxpbmdTdGVwXCIsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2Vcbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHJldHJ5YWJsZVN0ZXAsIFN5bWJvbC5mb3IoXCJXT1JLRkxPV19TVEVQX0ZVTkNUSU9OX05BTUVcIiksIHtcbiAgICB2YWx1ZTogXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy8yX2NvbnRyb2xfZmxvdy50cy8vcmV0cnlhYmxlU3RlcFwiLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlXG59KTtcbiIsICIvLyBpbXBvcnQgeyBGYXRhbEVycm9yIH0gZnJvbSAnd29ya2Zsb3cnO1xuLyoqX19pbnRlcm5hbF93b3JrZmxvd3N7XCJ3b3JrZmxvd3NcIjp7XCJuaXRyby12My93b3JrZmxvd3MvMF9kZW1vLnRzXCI6e1wiY2FsY1wiOntcIndvcmtmbG93SWRcIjpcIndvcmtmbG93Ly9uaXRyby12My93b3JrZmxvd3MvMF9kZW1vLnRzLy9jYWxjXCJ9fX0sXCJzdGVwc1wiOntcIm5pdHJvLXYzL3dvcmtmbG93cy8wX2RlbW8udHNcIjp7XCJwb3dcIjp7XCJzdGVwSWRcIjpcInN0ZXAvL25pdHJvLXYzL3dvcmtmbG93cy8wX2RlbW8udHMvL3Bvd1wifX19fSovO1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNhbGMobikge1xuICAgIGNvbnNvbGUubG9nKCdTaW1wbGUgd29ya2Zsb3cgc3RhcnRlZCcpO1xuICAgIG4gPSBhd2FpdCBwb3cobik7XG4gICAgY29uc29sZS5sb2coJ1NpbXBsZSB3b3JrZmxvdyBmaW5pc2hlZCcpO1xuICAgIHJldHVybiBuO1xufVxuYXN5bmMgZnVuY3Rpb24gcG93KGEpIHtcbiAgICByZXR1cm4gZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildKFwic3RlcC8vbml0cm8tdjMvd29ya2Zsb3dzLzBfZGVtby50cy8vcG93XCIpKGEpO1xufVxuY2FsYy53b3JrZmxvd0lkID0gXCJ3b3JrZmxvdy8vbml0cm8tdjMvd29ya2Zsb3dzLzBfZGVtby50cy8vY2FsY1wiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHBvdywgU3ltYm9sLmZvcihcIldPUktGTE9XX1NURVBfRlVOQ1RJT05fTkFNRVwiKSwge1xuICAgIHZhbHVlOiBcInN0ZXAvL25pdHJvLXYzL3dvcmtmbG93cy8wX2RlbW8udHMvL3Bvd1wiLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlXG59KTtcbiIsICIvLyBEdXBsaWNhdGUgd29ya2Zsb3cgZnJvbSA5OV9lMmUudHMgdG8gZW5zdXJlIHdlIGhhbmRsZSB1bmlxdWUgSURzXG4vLyBhbmQgdGhlIGZ1bmN0aW9uIGlzbid0IGRyb3BwZWQgZnJvbSBjb2xsaWRpbmcgZXhwb3J0IG5hbWVzXG4vKipfX2ludGVybmFsX3dvcmtmbG93c3tcIndvcmtmbG93c1wiOntcImV4YW1wbGUvd29ya2Zsb3dzLzk4X2R1cGxpY2F0ZV9jYXNlLnRzXCI6e1wiYWRkVGVuV29ya2Zsb3dcIjp7XCJ3b3JrZmxvd0lkXCI6XCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvOThfZHVwbGljYXRlX2Nhc2UudHMvL2FkZFRlbldvcmtmbG93XCJ9fX0sXCJzdGVwc1wiOntcImV4YW1wbGUvd29ya2Zsb3dzLzk4X2R1cGxpY2F0ZV9jYXNlLnRzXCI6e1wiYWRkXCI6e1wic3RlcElkXCI6XCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OF9kdXBsaWNhdGVfY2FzZS50cy8vYWRkXCJ9fX19Ki87XG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYWRkVGVuV29ya2Zsb3coaW5wdXQpIHtcbiAgICBjb25zdCBhID0gYXdhaXQgYWRkKGlucHV0LCAyKTtcbiAgICBjb25zdCBiID0gYXdhaXQgYWRkKGEsIDMpO1xuICAgIGNvbnN0IGMgPSBhd2FpdCBhZGQoYiwgNSk7XG4gICAgcmV0dXJuIGM7XG59XG4vLyBEdXBsaWNhdGUgc3RlcCBmcm9tIDk5X2UyZS50cyB0byBlbnN1cmUgd2UgaGFuZGxlIHVuaXF1ZSBJRHNcbi8vIGFuZCB0aGUgZnVuY3Rpb24gaXNuJ3QgZHJvcHBlZCBmcm9tIGNvbGxpZGluZyBleHBvcnQgbmFtZXNcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhZGQoYSwgYikge1xuICAgIHJldHVybiBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19VU0VfU1RFUFwiKV0oXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OF9kdXBsaWNhdGVfY2FzZS50cy8vYWRkXCIpKGEsIGIpO1xufVxuYWRkVGVuV29ya2Zsb3cud29ya2Zsb3dJZCA9IFwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzk4X2R1cGxpY2F0ZV9jYXNlLnRzLy9hZGRUZW5Xb3JrZmxvd1wiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGFkZCwgU3ltYm9sLmZvcihcIldPUktGTE9XX1NURVBfRlVOQ1RJT05fTkFNRVwiKSwge1xuICAgIHZhbHVlOiBcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk4X2R1cGxpY2F0ZV9jYXNlLnRzLy9hZGRcIixcbiAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiBmYWxzZVxufSk7XG4iLCAiaW1wb3J0IGNodW5rIGZyb20gXCJsb2Rhc2guY2h1bmtcIjtcbi8qKl9faW50ZXJuYWxfd29ya2Zsb3dze1wid29ya2Zsb3dzXCI6e1wiZXhhbXBsZS93b3JrZmxvd3MvNl9iYXRjaGluZy50c1wiOntcImJhdGNoSW5TdGVwXCI6e1wid29ya2Zsb3dJZFwiOlwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzZfYmF0Y2hpbmcudHMvL2JhdGNoSW5TdGVwXCJ9LFwiYmF0Y2hPdmVyU3RlcHNcIjp7XCJ3b3JrZmxvd0lkXCI6XCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvNl9iYXRjaGluZy50cy8vYmF0Y2hPdmVyU3RlcHNcIn19fSxcInN0ZXBzXCI6e1wiZXhhbXBsZS93b3JrZmxvd3MvNl9iYXRjaGluZy50c1wiOntcImxvZ0l0ZW1cIjp7XCJzdGVwSWRcIjpcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzZfYmF0Y2hpbmcudHMvL2xvZ0l0ZW1cIn0sXCJwcm9jZXNzSXRlbXNcIjp7XCJzdGVwSWRcIjpcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzZfYmF0Y2hpbmcudHMvL3Byb2Nlc3NJdGVtc1wifX19fSovO1xuY29uc3QgQVJSQVlfTEVOR1RIID0gMjUwO1xuY29uc3QgQ0hVTktfU0laRSA9IDUwO1xuLyoqXG4gKiBQYXR0ZXJuIDE6IEVhY2ggaXRlbSBpbiBhIGJhdGNoIGdldHMgcHJvY2Vzc2VkIGluIGEgc3RlcCBmdW5jdGlvblxuICpcbiAqIElmIGEgc3RlcCBmYWlscywgZG9lc24ndCBmYWlsIHRoZSBlbnRpcmUgYmF0Y2guXG4gKi8gZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGJhdGNoT3ZlclN0ZXBzKCkge1xuICAgIGNvbnNvbGUubG9nKCdXb3JrZmxvdyBzdGFydGVkJyk7XG4gICAgY29uc3QgYXJyID0gQXJyYXkuZnJvbSh7XG4gICAgICAgIGxlbmd0aDogQVJSQVlfTEVOR1RIXG4gICAgfSwgKF8sIGkpPT5pICsgMSk7XG4gICAgY29uc3QgY2h1bmtTaXplID0gQ0hVTktfU0laRTtcbiAgICBjb25zb2xlLmxvZyhgQ2h1bmtpbmcgYXJyYXkgd2l0aCBzaXplOiAke2Fyci5sZW5ndGh9IGFuZCBjaHVuayBzaXplOiAke2NodW5rU2l6ZX1gKTtcbiAgICBjb25zdCBjaHVua3MgPSBjaHVuayhhcnIsIGNodW5rU2l6ZSk7IC8vIENyZWF0ZSB0aGUgYmF0Y2hlc1xuICAgIGNvbnNvbGUubG9nKGBDcmVhdGVkICR7Y2h1bmtzLmxlbmd0aH0gY2h1bmtzICgke2NodW5rc1swXS5sZW5ndGh9IGl0ZW1zIGVhY2gpYCk7XG4gICAgY29uc29sZS5sb2coJ1N0YXJ0aW5nIGJhdGNoIHByb2Nlc3NpbmcnKTtcbiAgICBmb3IgKGNvbnN0IFtpbmRleCwgYmF0Y2hdIG9mIGNodW5rcy5lbnRyaWVzKCkpe1xuICAgICAgICBjb25zb2xlLmxvZyhgQmF0Y2ggJHtpbmRleCArIDF9LyR7Y2h1bmtzLmxlbmd0aH1gKTtcbiAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoYmF0Y2gubWFwKGxvZ0l0ZW0pKTtcbiAgICB9XG4gICAgY29uc29sZS5sb2coJ0JhdGNoIHByb2Nlc3NpbmcgY29tcGxldGVkJyk7XG4gICAgY29uc29sZS5sb2coJ1dvcmtmbG93IGNvbXBsZXRlZCcpO1xufVxuYXN5bmMgZnVuY3Rpb24gbG9nSXRlbShpdGVtKSB7XG4gICAgcmV0dXJuIGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1VTRV9TVEVQXCIpXShcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzZfYmF0Y2hpbmcudHMvL2xvZ0l0ZW1cIikoaXRlbSk7XG59XG4vKipcbiAqIFBhdHRlcm4gMjogRWFjaCBiYXRjaCBnZXRzIHByb2Nlc3NlZCBpbiBhIHN0ZXAgZnVuY3Rpb25cbiAqXG4gKiBOT1RFOiBJZiBhIGJhdGNoIGZhaWxzLCB0aGUgZW50aXJlIGJhdGNoIHdpbGwgYmUgcmV0cmllZCBmcm9tIHRoZSBiZWdpbm5pbmcuXG4gKi8gZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGJhdGNoSW5TdGVwKCkge1xuICAgIGNvbnNvbGUubG9nKCdXb3JrZmxvdyBzdGFydGVkJyk7XG4gICAgY29uc3QgYXJyID0gQXJyYXkuZnJvbSh7XG4gICAgICAgIGxlbmd0aDogQVJSQVlfTEVOR1RIXG4gICAgfSwgKF8sIGkpPT5pICsgMSk7XG4gICAgY29uc3QgY2h1bmtTaXplID0gQ0hVTktfU0laRTtcbiAgICBjb25zb2xlLmxvZyhgQ2h1bmtpbmcgYXJyYXkgd2l0aCBzaXplOiAke2Fyci5sZW5ndGh9IGFuZCBjaHVuayBzaXplOiAke2NodW5rU2l6ZX1gKTtcbiAgICBjb25zdCBjaHVua3MgPSBjaHVuayhhcnIsIGNodW5rU2l6ZSk7IC8vIENyZWF0ZSB0aGUgYmF0Y2hlc1xuICAgIGNvbnNvbGUubG9nKGBDcmVhdGVkICR7Y2h1bmtzLmxlbmd0aH0gY2h1bmtzICgke2NodW5rc1swXS5sZW5ndGh9IGl0ZW1zIGVhY2gpYCk7XG4gICAgY29uc29sZS5sb2coJ1N0YXJ0aW5nIGJhdGNoIHByb2Nlc3NpbmcnKTtcbiAgICBmb3IgKGNvbnN0IFtpbmRleCwgYmF0Y2hdIG9mIGNodW5rcy5lbnRyaWVzKCkpe1xuICAgICAgICBjb25zb2xlLmxvZyhgQmF0Y2ggJHtpbmRleCArIDF9LyR7Y2h1bmtzLmxlbmd0aH1gKTtcbiAgICAgICAgYXdhaXQgcHJvY2Vzc0l0ZW1zKGJhdGNoKTtcbiAgICB9XG4gICAgY29uc29sZS5sb2coJ0JhdGNoIHByb2Nlc3NpbmcgY29tcGxldGVkJyk7XG4gICAgY29uc29sZS5sb2coJ1dvcmtmbG93IGNvbXBsZXRlZCcpO1xufVxuLyoqXG4gKiBTdGVwIGZ1bmN0aW9uIHRoYXQgcHJvY2Vzc2VzIGEgYmF0Y2ggb2YgaXRlbXMgd2l0aCBpbnRlcm5hbCBwYXJhbGxlbGlzbS5cbiAqIENhbGxlZCBvbmNlIHBlciBiYXRjaCwgd2l0aCBhbGwgaXRlbXMgcHJvY2Vzc2VkIGluIHBhcmFsbGVsIGluc2lkZSB0aGUgc3RlcC5cbiAqLyBhc3luYyBmdW5jdGlvbiBwcm9jZXNzSXRlbXMoaXRlbXMpIHtcbiAgICByZXR1cm4gZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildKFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvNl9iYXRjaGluZy50cy8vcHJvY2Vzc0l0ZW1zXCIpKGl0ZW1zKTtcbn1cbmJhdGNoT3ZlclN0ZXBzLndvcmtmbG93SWQgPSBcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy82X2JhdGNoaW5nLnRzLy9iYXRjaE92ZXJTdGVwc1wiO1xuYmF0Y2hJblN0ZXAud29ya2Zsb3dJZCA9IFwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzZfYmF0Y2hpbmcudHMvL2JhdGNoSW5TdGVwXCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkobG9nSXRlbSwgU3ltYm9sLmZvcihcIldPUktGTE9XX1NURVBfRlVOQ1RJT05fTkFNRVwiKSwge1xuICAgIHZhbHVlOiBcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzZfYmF0Y2hpbmcudHMvL2xvZ0l0ZW1cIixcbiAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiBmYWxzZVxufSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkocHJvY2Vzc0l0ZW1zLCBTeW1ib2wuZm9yKFwiV09SS0ZMT1dfU1RFUF9GVU5DVElPTl9OQU1FXCIpLCB7XG4gICAgdmFsdWU6IFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvNl9iYXRjaGluZy50cy8vcHJvY2Vzc0l0ZW1zXCIsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2Vcbn0pO1xuIiwgIi8qKl9faW50ZXJuYWxfd29ya2Zsb3dze1wid29ya2Zsb3dzXCI6e1wiZXhhbXBsZS93b3JrZmxvd3MvMV9zaW1wbGUudHNcIjp7XCJzaW1wbGVcIjp7XCJ3b3JrZmxvd0lkXCI6XCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvMV9zaW1wbGUudHMvL3NpbXBsZVwifX19LFwic3RlcHNcIjp7XCJleGFtcGxlL3dvcmtmbG93cy8xX3NpbXBsZS50c1wiOntcImFkZFwiOntcInN0ZXBJZFwiOlwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvMV9zaW1wbGUudHMvL2FkZFwifX19fSovO1xuYXN5bmMgZnVuY3Rpb24gYWRkKGEsIGIpIHtcbiAgICByZXR1cm4gZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildKFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvMV9zaW1wbGUudHMvL2FkZFwiKShhLCBiKTtcbn1cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzaW1wbGUoaSkge1xuICAgIGNvbnNvbGUubG9nKCdTaW1wbGUgd29ya2Zsb3cgc3RhcnRlZCcpO1xuICAgIGNvbnN0IGEgPSBhd2FpdCBhZGQoaSwgNyk7XG4gICAgY29uc29sZS5sb2coJ1dvcmtmbG93IHN0ZXAgMSBjb21wbGV0ZWQgLSBSZXN1bHQ6JywgYSk7XG4gICAgY29uc3QgYiA9IGF3YWl0IGFkZChhLCA4KTtcbiAgICBjb25zb2xlLmxvZygnU2ltcGxlIHdvcmtmbG93IGNvbXBsZXRlZC4gUmVzdWx0OicsIGIpO1xuICAgIHJldHVybiBiO1xufVxuc2ltcGxlLndvcmtmbG93SWQgPSBcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy8xX3NpbXBsZS50cy8vc2ltcGxlXCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoYWRkLCBTeW1ib2wuZm9yKFwiV09SS0ZMT1dfU1RFUF9GVU5DVElPTl9OQU1FXCIpLCB7XG4gICAgdmFsdWU6IFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvMV9zaW1wbGUudHMvL2FkZFwiLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlXG59KTtcbiIsICJpbXBvcnQgeyBjcmVhdGVIb29rLCBnZXRXb3JrZmxvd01ldGFkYXRhIH0gZnJvbSBcIndvcmtmbG93XCI7XG4vKipfX2ludGVybmFsX3dvcmtmbG93c3tcIndvcmtmbG93c1wiOntcImV4YW1wbGUvd29ya2Zsb3dzLzVfaG9va3MudHNcIjp7XCJ3aXRoQ3JlYXRlSG9va1wiOntcIndvcmtmbG93SWRcIjpcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy81X2hvb2tzLnRzLy93aXRoQ3JlYXRlSG9va1wifSxcIndpdGhXb3JrZmxvd01ldGFkYXRhXCI6e1wid29ya2Zsb3dJZFwiOlwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzVfaG9va3MudHMvL3dpdGhXb3JrZmxvd01ldGFkYXRhXCJ9fX0sXCJzdGVwc1wiOntcImV4YW1wbGUvd29ya2Zsb3dzLzVfaG9va3MudHNcIjp7XCJnZXRPcGVuQUlSZXNwb25zZVwiOntcInN0ZXBJZFwiOlwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvNV9ob29rcy50cy8vZ2V0T3BlbkFJUmVzcG9uc2VcIn0sXCJpbml0aWF0ZU9wZW5BSVJlc3BvbnNlXCI6e1wic3RlcElkXCI6XCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy81X2hvb2tzLnRzLy9pbml0aWF0ZU9wZW5BSVJlc3BvbnNlXCJ9LFwic3RlcFdpdGhHZXRNZXRhZGF0YVwiOntcInN0ZXBJZFwiOlwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvNV9ob29rcy50cy8vc3RlcFdpdGhHZXRNZXRhZGF0YVwifX19fSovO1xuLyoqXG4gKiBgZ2V0U3RlcE1ldGFkYXRhKClgIGlzIGEgaG9vayB0aGF0IGFsbG93cyB5b3UgdG8gYWNjZXNzIHRoZSBzdGVwJ3MgY29udGV4dFxuICogb2YgdGhlIGN1cnJlbnQgd29ya2Zsb3cgcnVuLlxuICpcbiAqIEl0IGlzIHVzZWZ1bCBmb3IgYWNjZXNzaW5nIHRoZSBjb250ZXh0IG9mIHRoZSBjdXJyZW50IHdvcmtmbG93IHJ1biwgc3VjaCBhc1xuICogdGhlIHdvcmtmbG93IHJ1biBJRCwgdGhlIHdvcmtmbG93IHN0YXJ0ZWQgYXQsIGFuZCB0aGUgYXR0ZW1wdCBudW1iZXIuXG4gKi8gYXN5bmMgZnVuY3Rpb24gc3RlcFdpdGhHZXRNZXRhZGF0YSgpIHtcbiAgICByZXR1cm4gZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildKFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvNV9ob29rcy50cy8vc3RlcFdpdGhHZXRNZXRhZGF0YVwiKSgpO1xufVxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdpdGhXb3JrZmxvd01ldGFkYXRhKCkge1xuICAgIGNvbnN0IGN0eCA9IGdldFdvcmtmbG93TWV0YWRhdGEoKTtcbiAgICBjb25zb2xlLmxvZygnd29ya2Zsb3cgY29udGV4dCcsIGN0eCk7XG4gICAgYXdhaXQgc3RlcFdpdGhHZXRNZXRhZGF0YSgpO1xufVxuYXN5bmMgZnVuY3Rpb24gaW5pdGlhdGVPcGVuQUlSZXNwb25zZSgpIHtcbiAgICByZXR1cm4gZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildKFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvNV9ob29rcy50cy8vaW5pdGlhdGVPcGVuQUlSZXNwb25zZVwiKSgpO1xufVxuYXN5bmMgZnVuY3Rpb24gZ2V0T3BlbkFJUmVzcG9uc2UocmVzcElkKSB7XG4gICAgcmV0dXJuIGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1VTRV9TVEVQXCIpXShcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzVfaG9va3MudHMvL2dldE9wZW5BSVJlc3BvbnNlXCIpKHJlc3BJZCk7XG59XG4vKipcbiAqIGBjcmVhdGVIb29rKClgIHJlZ2lzdGVycyBhIHRva2VuIHRoYXQgY2FuIGJlIHVzZWQgdG8gcmVzdW1lIHRoZSB3b3JrZmxvdyBydW4uXG4gKiBUaGUgdG9rZW4gY2FuIGJlIHBhc3NlZCB0byBleHRlcm5hbCBzZXJ2aWNlcyBhcyBhIGNhbGxiYWNrIFVSTCwgb3IgdXNlZFxuICogZm9yIGh1bWFuLWluLXRoZS1sb29wIHdvcmtmbG93cyBieSwgZm9yIGV4YW1wbGUsIGluY2x1ZGluZyBpbiBhbiBlbWFpbC5cbiAqXG4gKiBUaGUgd29ya2Zsb3cgcnVuIHdpbGwgYmUgc3VzcGVuZGVkIHVudGlsIHRoZSBob29rIGlzIGludm9rZWQuXG4gKi8gZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdpdGhDcmVhdGVIb29rKCkge1xuICAgIC8vIEluaXRpYXRlIGEgYmFja2dyb3VuZCBcIlJlc3BvbnNlXCIgcmVxdWVzdCB0byBPcGVuQUksXG4gICAgLy8gd2hpY2ggd2lsbCBpbnZva2UgdGhlIGhvb2sgd2hlbiBpdCdzIGRvbmUuXG4gICAgY29uc3QgcmVzcElkID0gYXdhaXQgaW5pdGlhdGVPcGVuQUlSZXNwb25zZSgpO1xuICAgIC8vIFJlZ2lzdGVyIHRoZSBob29rIHdpdGggdGhlIHRva2VuIHRoYXQgaXMgc3BlY2lmaWNcbiAgICAvLyB0byB0aGUgcmVzcG9uc2UgSUQgdGhhdCB3ZSBhcmUgaW50ZXJlc3RlZCBpbi5cbiAgICBjb25zdCBob29rID0gY3JlYXRlSG9vayh7XG4gICAgICAgIHRva2VuOiBgb3BlbmFpOiR7cmVzcElkfWBcbiAgICB9KTtcbiAgICBjb25zb2xlLmxvZygnUmVnaXN0ZXJlZCBob29rOicsIGhvb2sudG9rZW4pO1xuICAgIC8vIFdhaXQgZm9yIHRoZSBob29rIHRvIGJlIGNhbGxlZC5cbiAgICBjb25zdCBwYXlsb2FkID0gYXdhaXQgaG9vaztcbiAgICBjb25zb2xlLmxvZygnUmVjZWl2ZWQgaG9vayBwYXlsb2FkOicsIHBheWxvYWQpO1xuICAgIGlmIChwYXlsb2FkLnR5cGUgPT09ICdyZXNwb25zZS5jb21wbGV0ZWQnKSB7XG4gICAgICAgIGNvbnN0IHRleHQgPSBhd2FpdCBnZXRPcGVuQUlSZXNwb25zZShwYXlsb2FkLmRhdGEuaWQpO1xuICAgICAgICBjb25zb2xlLmxvZygnT3BlbkFJIHJlc3BvbnNlIHRleHQ6JywgdGV4dCk7XG4gICAgfVxuICAgIGNvbnNvbGUubG9nKCdIb29rIGRlbW8gd29ya2Zsb3cgY29tcGxldGVkJyk7XG59XG53aXRoV29ya2Zsb3dNZXRhZGF0YS53b3JrZmxvd0lkID0gXCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvNV9ob29rcy50cy8vd2l0aFdvcmtmbG93TWV0YWRhdGFcIjtcbndpdGhDcmVhdGVIb29rLndvcmtmbG93SWQgPSBcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy81X2hvb2tzLnRzLy93aXRoQ3JlYXRlSG9va1wiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHN0ZXBXaXRoR2V0TWV0YWRhdGEsIFN5bWJvbC5mb3IoXCJXT1JLRkxPV19TVEVQX0ZVTkNUSU9OX05BTUVcIiksIHtcbiAgICB2YWx1ZTogXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy81X2hvb2tzLnRzLy9zdGVwV2l0aEdldE1ldGFkYXRhXCIsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2Vcbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGluaXRpYXRlT3BlbkFJUmVzcG9uc2UsIFN5bWJvbC5mb3IoXCJXT1JLRkxPV19TVEVQX0ZVTkNUSU9OX05BTUVcIiksIHtcbiAgICB2YWx1ZTogXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy81X2hvb2tzLnRzLy9pbml0aWF0ZU9wZW5BSVJlc3BvbnNlXCIsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2Vcbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGdldE9wZW5BSVJlc3BvbnNlLCBTeW1ib2wuZm9yKFwiV09SS0ZMT1dfU1RFUF9GVU5DVElPTl9OQU1FXCIpLCB7XG4gICAgdmFsdWU6IFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvNV9ob29rcy50cy8vZ2V0T3BlbkFJUmVzcG9uc2VcIixcbiAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiBmYWxzZVxufSk7XG4iLCAiaW1wb3J0IHsgZ2VuZXJhdGVUZXh0LCBzdGVwQ291bnRJcyB9IGZyb20gXCJhaVwiO1xuaW1wb3J0IHogZnJvbSBcInpvZC92NFwiO1xuLyoqX19pbnRlcm5hbF93b3JrZmxvd3N7XCJ3b3JrZmxvd3NcIjp7XCJleGFtcGxlL3dvcmtmbG93cy80X2FpLnRzXCI6e1wiYWdlbnRcIjp7XCJ3b3JrZmxvd0lkXCI6XCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvNF9haS50cy8vYWdlbnRcIn0sXCJhaVwiOntcIndvcmtmbG93SWRcIjpcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy80X2FpLnRzLy9haVwifX19LFwic3RlcHNcIjp7XCJleGFtcGxlL3dvcmtmbG93cy80X2FpLnRzXCI6e1wiZ2V0V2VhdGhlckluZm9ybWF0aW9uXCI6e1wic3RlcElkXCI6XCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy80X2FpLnRzLy9nZXRXZWF0aGVySW5mb3JtYXRpb25cIn19fX0qLztcbmFzeW5jIGZ1bmN0aW9uIGdldFdlYXRoZXJJbmZvcm1hdGlvbih7IGNpdHkgfSkge1xuICAgIHJldHVybiBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19VU0VfU1RFUFwiKV0oXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy80X2FpLnRzLy9nZXRXZWF0aGVySW5mb3JtYXRpb25cIikoe1xuICAgICAgICBjaXR5XG4gICAgfSk7XG59XG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYWkocHJvbXB0KSB7XG4gICAgY29uc29sZS5sb2coJ0FJIHdvcmtmbG93IHN0YXJ0ZWQnKTtcbiAgICAvLyBBSSBTREsncyBgZ2VuZXJhdGVUZXh0YCBqdXN0IHdvcmtzIG5hdGl2ZWx5IGluIGEgd29ya2Zsb3cgdGhhbmtzIHRvXG4gICAgLy8gd29ya2Zsb3cncyBhdXRvbWF0aWMgZmV0Y2ggaG9pc3RpbmcgZnVuY3Rpb25hbGl0eVxuICAgIGNvbnN0IHsgdGV4dCB9ID0gYXdhaXQgZ2VuZXJhdGVUZXh0KHtcbiAgICAgICAgbW9kZWw6ICdvcGVuYWkvbzMnLFxuICAgICAgICBwcm9tcHRcbiAgICB9KTtcbiAgICBjb25zb2xlLmxvZyhgQUkgd29ya2Zsb3cgY29tcGxldGVkLiBSZXN1bHQ6ICR7dGV4dH1gKTtcbiAgICByZXR1cm4gdGV4dDtcbn1cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhZ2VudChwcm9tcHQpIHtcbiAgICBjb25zb2xlLmxvZygnQWdlbnQgd29ya2Zsb3cgc3RhcnRlZCcpO1xuICAgIC8vIFlvdSBjYW4gYWxzbyBwcm92aWRlIHRvb2xzLCBhbmQgaWYgdGhvc2UgdG9vbHMgYXJlIGBzdGVwc2AgLSB2b2lsYSwgeW91IGhhdmUgeW91cnNlbGZcbiAgICAvLyBhIGR1cmFibGUgYWdlbnQgd2l0aCBmZXRjaGVzIGFuZCBzdGVwcyBiZWluZyBvZmZsb2FkZWRcbiAgICBjb25zdCB7IHRleHQgfSA9IGF3YWl0IGdlbmVyYXRlVGV4dCh7XG4gICAgICAgIG1vZGVsOiAnYW50aHJvcGljL2NsYXVkZS00LW9wdXMtMjAyNTA1MTQnLFxuICAgICAgICBwcm9tcHQsXG4gICAgICAgIHRvb2xzOiB7XG4gICAgICAgICAgICBnZXRXZWF0aGVySW5mb3JtYXRpb246IHtcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogJ3Nob3cgdGhlIHdlYXRoZXIgaW4gYSBnaXZlbiBjaXR5IHRvIHRoZSB1c2VyJyxcbiAgICAgICAgICAgICAgICBpbnB1dFNjaGVtYTogei5vYmplY3Qoe1xuICAgICAgICAgICAgICAgICAgICBjaXR5OiB6LnN0cmluZygpXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgZXhlY3V0ZTogZ2V0V2VhdGhlckluZm9ybWF0aW9uXG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIC8vIFRoaXMgY2FuIGJlIGEgaGlnaCBhcyB5b3Ugd2FudCAtIG5vIHJlc3RyaWN0aW9uIG9uIHRoZSBsYW1iZGEgd29ya2Zsb3cgcnVudGltZVxuICAgICAgICBzdG9wV2hlbjogc3RlcENvdW50SXMoMTApXG4gICAgfSk7XG4gICAgY29uc29sZS5sb2coYEFnZW50IHdvcmtmbG93IGNvbXBsZXRlZC4gUmVzdWx0OiAke3RleHR9YCk7XG4gICAgcmV0dXJuIHRleHQ7XG59XG5haS53b3JrZmxvd0lkID0gXCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvNF9haS50cy8vYWlcIjtcbmFnZW50LndvcmtmbG93SWQgPSBcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy80X2FpLnRzLy9hZ2VudFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGdldFdlYXRoZXJJbmZvcm1hdGlvbiwgU3ltYm9sLmZvcihcIldPUktGTE9XX1NURVBfRlVOQ1RJT05fTkFNRVwiKSwge1xuICAgIHZhbHVlOiBcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzRfYWkudHMvL2dldFdlYXRoZXJJbmZvcm1hdGlvblwiLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlXG59KTtcbiIsICIvKipcbiAqIFN5bWJvbCB1c2VkIGZvciBpZGVudGlmeWluZyBBSSBTREsgRXJyb3IgaW5zdGFuY2VzLlxuICogRW5hYmxlcyBjaGVja2luZyBpZiBhbiBlcnJvciBpcyBhbiBpbnN0YW5jZSBvZiBBSVNES0Vycm9yIGFjcm9zcyBwYWNrYWdlIHZlcnNpb25zLlxuICovXG5jb25zdCBtYXJrZXIgPSAndmVyY2VsLmFpLmVycm9yJztcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuLyoqXG4gKiBDdXN0b20gZXJyb3IgY2xhc3MgZm9yIEFJIFNESyByZWxhdGVkIGVycm9ycy5cbiAqIEBleHRlbmRzIEVycm9yXG4gKi9cbmV4cG9ydCBjbGFzcyBBSVNES0Vycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBwcml2YXRlIHJlYWRvbmx5IFtzeW1ib2xdID0gdHJ1ZTsgLy8gdXNlZCBpbiBpc0luc3RhbmNlXG5cbiAgLyoqXG4gICAqIFRoZSB1bmRlcmx5aW5nIGNhdXNlIG9mIHRoZSBlcnJvciwgaWYgYW55LlxuICAgKi9cbiAgcmVhZG9ubHkgY2F1c2U/OiB1bmtub3duO1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIEFJIFNESyBFcnJvci5cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciBjcmVhdGluZyB0aGUgZXJyb3IuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwYXJhbXMubmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBlcnJvci5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHBhcmFtcy5tZXNzYWdlIC0gVGhlIGVycm9yIG1lc3NhZ2UuXG4gICAqIEBwYXJhbSB7dW5rbm93bn0gW3BhcmFtcy5jYXVzZV0gLSBUaGUgdW5kZXJseWluZyBjYXVzZSBvZiB0aGUgZXJyb3IuXG4gICAqL1xuICBjb25zdHJ1Y3Rvcih7XG4gICAgbmFtZSxcbiAgICBtZXNzYWdlLFxuICAgIGNhdXNlLFxuICB9OiB7XG4gICAgbmFtZTogc3RyaW5nO1xuICAgIG1lc3NhZ2U6IHN0cmluZztcbiAgICBjYXVzZT86IHVua25vd247XG4gIH0pIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcblxuICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgdGhpcy5jYXVzZSA9IGNhdXNlO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gZXJyb3IgaXMgYW4gQUkgU0RLIEVycm9yLlxuICAgKiBAcGFyYW0ge3Vua25vd259IGVycm9yIC0gVGhlIGVycm9yIHRvIGNoZWNrLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgZXJyb3IgaXMgYW4gQUkgU0RLIEVycm9yLCBmYWxzZSBvdGhlcndpc2UuXG4gICAqL1xuICBzdGF0aWMgaXNJbnN0YW5jZShlcnJvcjogdW5rbm93bik6IGVycm9yIGlzIEFJU0RLRXJyb3Ige1xuICAgIHJldHVybiBBSVNES0Vycm9yLmhhc01hcmtlcihlcnJvciwgbWFya2VyKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBzdGF0aWMgaGFzTWFya2VyKGVycm9yOiB1bmtub3duLCBtYXJrZXI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IG1hcmtlclN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcbiAgICByZXR1cm4gKFxuICAgICAgZXJyb3IgIT0gbnVsbCAmJlxuICAgICAgdHlwZW9mIGVycm9yID09PSAnb2JqZWN0JyAmJlxuICAgICAgbWFya2VyU3ltYm9sIGluIGVycm9yICYmXG4gICAgICB0eXBlb2YgZXJyb3JbbWFya2VyU3ltYm9sXSA9PT0gJ2Jvb2xlYW4nICYmXG4gICAgICBlcnJvclttYXJrZXJTeW1ib2xdID09PSB0cnVlXG4gICAgKTtcbiAgfVxufVxuIiwgImltcG9ydCB7IEFJU0RLRXJyb3IgfSBmcm9tICcuL2FpLXNkay1lcnJvcic7XG5cbmNvbnN0IG5hbWUgPSAnQUlfQVBJQ2FsbEVycm9yJztcbmNvbnN0IG1hcmtlciA9IGB2ZXJjZWwuYWkuZXJyb3IuJHtuYW1lfWA7XG5jb25zdCBzeW1ib2wgPSBTeW1ib2wuZm9yKG1hcmtlcik7XG5cbmV4cG9ydCBjbGFzcyBBUElDYWxsRXJyb3IgZXh0ZW5kcyBBSVNES0Vycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7IC8vIHVzZWQgaW4gaXNJbnN0YW5jZVxuXG4gIHJlYWRvbmx5IHVybDogc3RyaW5nO1xuICByZWFkb25seSByZXF1ZXN0Qm9keVZhbHVlczogdW5rbm93bjtcbiAgcmVhZG9ubHkgc3RhdHVzQ29kZT86IG51bWJlcjtcblxuICByZWFkb25seSByZXNwb25zZUhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICByZWFkb25seSByZXNwb25zZUJvZHk/OiBzdHJpbmc7XG5cbiAgcmVhZG9ubHkgaXNSZXRyeWFibGU6IGJvb2xlYW47XG4gIHJlYWRvbmx5IGRhdGE/OiB1bmtub3duO1xuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICBtZXNzYWdlLFxuICAgIHVybCxcbiAgICByZXF1ZXN0Qm9keVZhbHVlcyxcbiAgICBzdGF0dXNDb2RlLFxuICAgIHJlc3BvbnNlSGVhZGVycyxcbiAgICByZXNwb25zZUJvZHksXG4gICAgY2F1c2UsXG4gICAgaXNSZXRyeWFibGUgPSBzdGF0dXNDb2RlICE9IG51bGwgJiZcbiAgICAgIChzdGF0dXNDb2RlID09PSA0MDggfHwgLy8gcmVxdWVzdCB0aW1lb3V0XG4gICAgICAgIHN0YXR1c0NvZGUgPT09IDQwOSB8fCAvLyBjb25mbGljdFxuICAgICAgICBzdGF0dXNDb2RlID09PSA0MjkgfHwgLy8gdG9vIG1hbnkgcmVxdWVzdHNcbiAgICAgICAgc3RhdHVzQ29kZSA+PSA1MDApLCAvLyBzZXJ2ZXIgZXJyb3JcbiAgICBkYXRhLFxuICB9OiB7XG4gICAgbWVzc2FnZTogc3RyaW5nO1xuICAgIHVybDogc3RyaW5nO1xuICAgIHJlcXVlc3RCb2R5VmFsdWVzOiB1bmtub3duO1xuICAgIHN0YXR1c0NvZGU/OiBudW1iZXI7XG4gICAgcmVzcG9uc2VIZWFkZXJzPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgICByZXNwb25zZUJvZHk/OiBzdHJpbmc7XG4gICAgY2F1c2U/OiB1bmtub3duO1xuICAgIGlzUmV0cnlhYmxlPzogYm9vbGVhbjtcbiAgICBkYXRhPzogdW5rbm93bjtcbiAgfSkge1xuICAgIHN1cGVyKHsgbmFtZSwgbWVzc2FnZSwgY2F1c2UgfSk7XG5cbiAgICB0aGlzLnVybCA9IHVybDtcbiAgICB0aGlzLnJlcXVlc3RCb2R5VmFsdWVzID0gcmVxdWVzdEJvZHlWYWx1ZXM7XG4gICAgdGhpcy5zdGF0dXNDb2RlID0gc3RhdHVzQ29kZTtcbiAgICB0aGlzLnJlc3BvbnNlSGVhZGVycyA9IHJlc3BvbnNlSGVhZGVycztcbiAgICB0aGlzLnJlc3BvbnNlQm9keSA9IHJlc3BvbnNlQm9keTtcbiAgICB0aGlzLmlzUmV0cnlhYmxlID0gaXNSZXRyeWFibGU7XG4gICAgdGhpcy5kYXRhID0gZGF0YTtcbiAgfVxuXG4gIHN0YXRpYyBpc0luc3RhbmNlKGVycm9yOiB1bmtub3duKTogZXJyb3IgaXMgQVBJQ2FsbEVycm9yIHtcbiAgICByZXR1cm4gQUlTREtFcnJvci5oYXNNYXJrZXIoZXJyb3IsIG1hcmtlcik7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBBSVNES0Vycm9yIH0gZnJvbSAnLi9haS1zZGstZXJyb3InO1xuXG5jb25zdCBuYW1lID0gJ0FJX0VtcHR5UmVzcG9uc2VCb2R5RXJyb3InO1xuY29uc3QgbWFya2VyID0gYHZlcmNlbC5haS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuZXhwb3J0IGNsYXNzIEVtcHR5UmVzcG9uc2VCb2R5RXJyb3IgZXh0ZW5kcyBBSVNES0Vycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7IC8vIHVzZWQgaW4gaXNJbnN0YW5jZVxuXG4gIGNvbnN0cnVjdG9yKHsgbWVzc2FnZSA9ICdFbXB0eSByZXNwb25zZSBib2R5JyB9OiB7IG1lc3NhZ2U/OiBzdHJpbmcgfSA9IHt9KSB7XG4gICAgc3VwZXIoeyBuYW1lLCBtZXNzYWdlIH0pO1xuICB9XG5cbiAgc3RhdGljIGlzSW5zdGFuY2UoZXJyb3I6IHVua25vd24pOiBlcnJvciBpcyBFbXB0eVJlc3BvbnNlQm9keUVycm9yIHtcbiAgICByZXR1cm4gQUlTREtFcnJvci5oYXNNYXJrZXIoZXJyb3IsIG1hcmtlcik7XG4gIH1cbn1cbiIsICJleHBvcnQgZnVuY3Rpb24gZ2V0RXJyb3JNZXNzYWdlKGVycm9yOiB1bmtub3duIHwgdW5kZWZpbmVkKSB7XG4gIGlmIChlcnJvciA9PSBudWxsKSB7XG4gICAgcmV0dXJuICd1bmtub3duIGVycm9yJztcbiAgfVxuXG4gIGlmICh0eXBlb2YgZXJyb3IgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGVycm9yO1xuICB9XG5cbiAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICByZXR1cm4gZXJyb3IubWVzc2FnZTtcbiAgfVxuXG4gIHJldHVybiBKU09OLnN0cmluZ2lmeShlcnJvcik7XG59XG4iLCAiaW1wb3J0IHsgQUlTREtFcnJvciB9IGZyb20gJy4vYWktc2RrLWVycm9yJztcblxuY29uc3QgbmFtZSA9ICdBSV9JbnZhbGlkQXJndW1lbnRFcnJvcic7XG5jb25zdCBtYXJrZXIgPSBgdmVyY2VsLmFpLmVycm9yLiR7bmFtZX1gO1xuY29uc3Qgc3ltYm9sID0gU3ltYm9sLmZvcihtYXJrZXIpO1xuXG4vKipcbiAqIEEgZnVuY3Rpb24gYXJndW1lbnQgaXMgaW52YWxpZC5cbiAqL1xuZXhwb3J0IGNsYXNzIEludmFsaWRBcmd1bWVudEVycm9yIGV4dGVuZHMgQUlTREtFcnJvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgW3N5bWJvbF0gPSB0cnVlOyAvLyB1c2VkIGluIGlzSW5zdGFuY2VcblxuICByZWFkb25seSBhcmd1bWVudDogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICBtZXNzYWdlLFxuICAgIGNhdXNlLFxuICAgIGFyZ3VtZW50LFxuICB9OiB7XG4gICAgYXJndW1lbnQ6IHN0cmluZztcbiAgICBtZXNzYWdlOiBzdHJpbmc7XG4gICAgY2F1c2U/OiB1bmtub3duO1xuICB9KSB7XG4gICAgc3VwZXIoeyBuYW1lLCBtZXNzYWdlLCBjYXVzZSB9KTtcblxuICAgIHRoaXMuYXJndW1lbnQgPSBhcmd1bWVudDtcbiAgfVxuXG4gIHN0YXRpYyBpc0luc3RhbmNlKGVycm9yOiB1bmtub3duKTogZXJyb3IgaXMgSW52YWxpZEFyZ3VtZW50RXJyb3Ige1xuICAgIHJldHVybiBBSVNES0Vycm9yLmhhc01hcmtlcihlcnJvciwgbWFya2VyKTtcbiAgfVxufVxuIiwgImltcG9ydCB7IEFJU0RLRXJyb3IgfSBmcm9tICcuL2FpLXNkay1lcnJvcic7XG5cbmNvbnN0IG5hbWUgPSAnQUlfSW52YWxpZFByb21wdEVycm9yJztcbmNvbnN0IG1hcmtlciA9IGB2ZXJjZWwuYWkuZXJyb3IuJHtuYW1lfWA7XG5jb25zdCBzeW1ib2wgPSBTeW1ib2wuZm9yKG1hcmtlcik7XG5cbi8qKlxuICogQSBwcm9tcHQgaXMgaW52YWxpZC4gVGhpcyBlcnJvciBzaG91bGQgYmUgdGhyb3duIGJ5IHByb3ZpZGVycyB3aGVuIHRoZXkgY2Fubm90XG4gKiBwcm9jZXNzIGEgcHJvbXB0LlxuICovXG5leHBvcnQgY2xhc3MgSW52YWxpZFByb21wdEVycm9yIGV4dGVuZHMgQUlTREtFcnJvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgW3N5bWJvbF0gPSB0cnVlOyAvLyB1c2VkIGluIGlzSW5zdGFuY2VcblxuICByZWFkb25seSBwcm9tcHQ6IHVua25vd247XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIHByb21wdCxcbiAgICBtZXNzYWdlLFxuICAgIGNhdXNlLFxuICB9OiB7XG4gICAgcHJvbXB0OiB1bmtub3duO1xuICAgIG1lc3NhZ2U6IHN0cmluZztcbiAgICBjYXVzZT86IHVua25vd247XG4gIH0pIHtcbiAgICBzdXBlcih7IG5hbWUsIG1lc3NhZ2U6IGBJbnZhbGlkIHByb21wdDogJHttZXNzYWdlfWAsIGNhdXNlIH0pO1xuXG4gICAgdGhpcy5wcm9tcHQgPSBwcm9tcHQ7XG4gIH1cblxuICBzdGF0aWMgaXNJbnN0YW5jZShlcnJvcjogdW5rbm93bik6IGVycm9yIGlzIEludmFsaWRQcm9tcHRFcnJvciB7XG4gICAgcmV0dXJuIEFJU0RLRXJyb3IuaGFzTWFya2VyKGVycm9yLCBtYXJrZXIpO1xuICB9XG59XG4iLCAiaW1wb3J0IHsgQUlTREtFcnJvciB9IGZyb20gJy4vYWktc2RrLWVycm9yJztcblxuY29uc3QgbmFtZSA9ICdBSV9JbnZhbGlkUmVzcG9uc2VEYXRhRXJyb3InO1xuY29uc3QgbWFya2VyID0gYHZlcmNlbC5haS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuLyoqXG4gKiBTZXJ2ZXIgcmV0dXJuZWQgYSByZXNwb25zZSB3aXRoIGludmFsaWQgZGF0YSBjb250ZW50LlxuICogVGhpcyBzaG91bGQgYmUgdGhyb3duIGJ5IHByb3ZpZGVycyB3aGVuIHRoZXkgY2Fubm90IHBhcnNlIHRoZSByZXNwb25zZSBmcm9tIHRoZSBBUEkuXG4gKi9cbmV4cG9ydCBjbGFzcyBJbnZhbGlkUmVzcG9uc2VEYXRhRXJyb3IgZXh0ZW5kcyBBSVNES0Vycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7IC8vIHVzZWQgaW4gaXNJbnN0YW5jZVxuXG4gIHJlYWRvbmx5IGRhdGE6IHVua25vd247XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIGRhdGEsXG4gICAgbWVzc2FnZSA9IGBJbnZhbGlkIHJlc3BvbnNlIGRhdGE6ICR7SlNPTi5zdHJpbmdpZnkoZGF0YSl9LmAsXG4gIH06IHtcbiAgICBkYXRhOiB1bmtub3duO1xuICAgIG1lc3NhZ2U/OiBzdHJpbmc7XG4gIH0pIHtcbiAgICBzdXBlcih7IG5hbWUsIG1lc3NhZ2UgfSk7XG5cbiAgICB0aGlzLmRhdGEgPSBkYXRhO1xuICB9XG5cbiAgc3RhdGljIGlzSW5zdGFuY2UoZXJyb3I6IHVua25vd24pOiBlcnJvciBpcyBJbnZhbGlkUmVzcG9uc2VEYXRhRXJyb3Ige1xuICAgIHJldHVybiBBSVNES0Vycm9yLmhhc01hcmtlcihlcnJvciwgbWFya2VyKTtcbiAgfVxufVxuIiwgImltcG9ydCB7IEFJU0RLRXJyb3IgfSBmcm9tICcuL2FpLXNkay1lcnJvcic7XG5pbXBvcnQgeyBnZXRFcnJvck1lc3NhZ2UgfSBmcm9tICcuL2dldC1lcnJvci1tZXNzYWdlJztcblxuY29uc3QgbmFtZSA9ICdBSV9KU09OUGFyc2VFcnJvcic7XG5jb25zdCBtYXJrZXIgPSBgdmVyY2VsLmFpLmVycm9yLiR7bmFtZX1gO1xuY29uc3Qgc3ltYm9sID0gU3ltYm9sLmZvcihtYXJrZXIpO1xuXG4vLyBUT0RPIHY1OiByZW5hbWUgdG8gUGFyc2VFcnJvclxuZXhwb3J0IGNsYXNzIEpTT05QYXJzZUVycm9yIGV4dGVuZHMgQUlTREtFcnJvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgW3N5bWJvbF0gPSB0cnVlOyAvLyB1c2VkIGluIGlzSW5zdGFuY2VcblxuICByZWFkb25seSB0ZXh0OiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoeyB0ZXh0LCBjYXVzZSB9OiB7IHRleHQ6IHN0cmluZzsgY2F1c2U6IHVua25vd24gfSkge1xuICAgIHN1cGVyKHtcbiAgICAgIG5hbWUsXG4gICAgICBtZXNzYWdlOlxuICAgICAgICBgSlNPTiBwYXJzaW5nIGZhaWxlZDogYCArXG4gICAgICAgIGBUZXh0OiAke3RleHR9LlxcbmAgK1xuICAgICAgICBgRXJyb3IgbWVzc2FnZTogJHtnZXRFcnJvck1lc3NhZ2UoY2F1c2UpfWAsXG4gICAgICBjYXVzZSxcbiAgICB9KTtcblxuICAgIHRoaXMudGV4dCA9IHRleHQ7XG4gIH1cblxuICBzdGF0aWMgaXNJbnN0YW5jZShlcnJvcjogdW5rbm93bik6IGVycm9yIGlzIEpTT05QYXJzZUVycm9yIHtcbiAgICByZXR1cm4gQUlTREtFcnJvci5oYXNNYXJrZXIoZXJyb3IsIG1hcmtlcik7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBBSVNES0Vycm9yIH0gZnJvbSAnLi9haS1zZGstZXJyb3InO1xuXG5jb25zdCBuYW1lID0gJ0FJX0xvYWRBUElLZXlFcnJvcic7XG5jb25zdCBtYXJrZXIgPSBgdmVyY2VsLmFpLmVycm9yLiR7bmFtZX1gO1xuY29uc3Qgc3ltYm9sID0gU3ltYm9sLmZvcihtYXJrZXIpO1xuXG5leHBvcnQgY2xhc3MgTG9hZEFQSUtleUVycm9yIGV4dGVuZHMgQUlTREtFcnJvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgW3N5bWJvbF0gPSB0cnVlOyAvLyB1c2VkIGluIGlzSW5zdGFuY2VcblxuICBjb25zdHJ1Y3Rvcih7IG1lc3NhZ2UgfTogeyBtZXNzYWdlOiBzdHJpbmcgfSkge1xuICAgIHN1cGVyKHsgbmFtZSwgbWVzc2FnZSB9KTtcbiAgfVxuXG4gIHN0YXRpYyBpc0luc3RhbmNlKGVycm9yOiB1bmtub3duKTogZXJyb3IgaXMgTG9hZEFQSUtleUVycm9yIHtcbiAgICByZXR1cm4gQUlTREtFcnJvci5oYXNNYXJrZXIoZXJyb3IsIG1hcmtlcik7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBBSVNES0Vycm9yIH0gZnJvbSAnLi9haS1zZGstZXJyb3InO1xuXG5jb25zdCBuYW1lID0gJ0FJX0xvYWRTZXR0aW5nRXJyb3InO1xuY29uc3QgbWFya2VyID0gYHZlcmNlbC5haS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuZXhwb3J0IGNsYXNzIExvYWRTZXR0aW5nRXJyb3IgZXh0ZW5kcyBBSVNES0Vycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7IC8vIHVzZWQgaW4gaXNJbnN0YW5jZVxuXG4gIGNvbnN0cnVjdG9yKHsgbWVzc2FnZSB9OiB7IG1lc3NhZ2U6IHN0cmluZyB9KSB7XG4gICAgc3VwZXIoeyBuYW1lLCBtZXNzYWdlIH0pO1xuICB9XG5cbiAgc3RhdGljIGlzSW5zdGFuY2UoZXJyb3I6IHVua25vd24pOiBlcnJvciBpcyBMb2FkU2V0dGluZ0Vycm9yIHtcbiAgICByZXR1cm4gQUlTREtFcnJvci5oYXNNYXJrZXIoZXJyb3IsIG1hcmtlcik7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBBSVNES0Vycm9yIH0gZnJvbSAnLi9haS1zZGstZXJyb3InO1xuXG5jb25zdCBuYW1lID0gJ0FJX05vQ29udGVudEdlbmVyYXRlZEVycm9yJztcbmNvbnN0IG1hcmtlciA9IGB2ZXJjZWwuYWkuZXJyb3IuJHtuYW1lfWA7XG5jb25zdCBzeW1ib2wgPSBTeW1ib2wuZm9yKG1hcmtlcik7XG5cbi8qKlxuVGhyb3duIHdoZW4gdGhlIEFJIHByb3ZpZGVyIGZhaWxzIHRvIGdlbmVyYXRlIGFueSBjb250ZW50LlxuICovXG5leHBvcnQgY2xhc3MgTm9Db250ZW50R2VuZXJhdGVkRXJyb3IgZXh0ZW5kcyBBSVNES0Vycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7IC8vIHVzZWQgaW4gaXNJbnN0YW5jZVxuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICBtZXNzYWdlID0gJ05vIGNvbnRlbnQgZ2VuZXJhdGVkLicsXG4gIH06IHsgbWVzc2FnZT86IHN0cmluZyB9ID0ge30pIHtcbiAgICBzdXBlcih7IG5hbWUsIG1lc3NhZ2UgfSk7XG4gIH1cblxuICBzdGF0aWMgaXNJbnN0YW5jZShlcnJvcjogdW5rbm93bik6IGVycm9yIGlzIE5vQ29udGVudEdlbmVyYXRlZEVycm9yIHtcbiAgICByZXR1cm4gQUlTREtFcnJvci5oYXNNYXJrZXIoZXJyb3IsIG1hcmtlcik7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBBSVNES0Vycm9yIH0gZnJvbSAnLi9haS1zZGstZXJyb3InO1xuXG5jb25zdCBuYW1lID0gJ0FJX05vU3VjaE1vZGVsRXJyb3InO1xuY29uc3QgbWFya2VyID0gYHZlcmNlbC5haS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuZXhwb3J0IGNsYXNzIE5vU3VjaE1vZGVsRXJyb3IgZXh0ZW5kcyBBSVNES0Vycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7IC8vIHVzZWQgaW4gaXNJbnN0YW5jZVxuXG4gIHJlYWRvbmx5IG1vZGVsSWQ6IHN0cmluZztcbiAgcmVhZG9ubHkgbW9kZWxUeXBlOlxuICAgIHwgJ2xhbmd1YWdlTW9kZWwnXG4gICAgfCAndGV4dEVtYmVkZGluZ01vZGVsJ1xuICAgIHwgJ2ltYWdlTW9kZWwnXG4gICAgfCAndHJhbnNjcmlwdGlvbk1vZGVsJ1xuICAgIHwgJ3NwZWVjaE1vZGVsJztcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgZXJyb3JOYW1lID0gbmFtZSxcbiAgICBtb2RlbElkLFxuICAgIG1vZGVsVHlwZSxcbiAgICBtZXNzYWdlID0gYE5vIHN1Y2ggJHttb2RlbFR5cGV9OiAke21vZGVsSWR9YCxcbiAgfToge1xuICAgIGVycm9yTmFtZT86IHN0cmluZztcbiAgICBtb2RlbElkOiBzdHJpbmc7XG4gICAgbW9kZWxUeXBlOlxuICAgICAgfCAnbGFuZ3VhZ2VNb2RlbCdcbiAgICAgIHwgJ3RleHRFbWJlZGRpbmdNb2RlbCdcbiAgICAgIHwgJ2ltYWdlTW9kZWwnXG4gICAgICB8ICd0cmFuc2NyaXB0aW9uTW9kZWwnXG4gICAgICB8ICdzcGVlY2hNb2RlbCc7XG4gICAgbWVzc2FnZT86IHN0cmluZztcbiAgfSkge1xuICAgIHN1cGVyKHsgbmFtZTogZXJyb3JOYW1lLCBtZXNzYWdlIH0pO1xuXG4gICAgdGhpcy5tb2RlbElkID0gbW9kZWxJZDtcbiAgICB0aGlzLm1vZGVsVHlwZSA9IG1vZGVsVHlwZTtcbiAgfVxuXG4gIHN0YXRpYyBpc0luc3RhbmNlKGVycm9yOiB1bmtub3duKTogZXJyb3IgaXMgTm9TdWNoTW9kZWxFcnJvciB7XG4gICAgcmV0dXJuIEFJU0RLRXJyb3IuaGFzTWFya2VyKGVycm9yLCBtYXJrZXIpO1xuICB9XG59XG4iLCAiaW1wb3J0IHsgQUlTREtFcnJvciB9IGZyb20gJy4vYWktc2RrLWVycm9yJztcblxuY29uc3QgbmFtZSA9ICdBSV9Ub29NYW55RW1iZWRkaW5nVmFsdWVzRm9yQ2FsbEVycm9yJztcbmNvbnN0IG1hcmtlciA9IGB2ZXJjZWwuYWkuZXJyb3IuJHtuYW1lfWA7XG5jb25zdCBzeW1ib2wgPSBTeW1ib2wuZm9yKG1hcmtlcik7XG5cbmV4cG9ydCBjbGFzcyBUb29NYW55RW1iZWRkaW5nVmFsdWVzRm9yQ2FsbEVycm9yIGV4dGVuZHMgQUlTREtFcnJvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgW3N5bWJvbF0gPSB0cnVlOyAvLyB1c2VkIGluIGlzSW5zdGFuY2VcblxuICByZWFkb25seSBwcm92aWRlcjogc3RyaW5nO1xuICByZWFkb25seSBtb2RlbElkOiBzdHJpbmc7XG4gIHJlYWRvbmx5IG1heEVtYmVkZGluZ3NQZXJDYWxsOiBudW1iZXI7XG4gIHJlYWRvbmx5IHZhbHVlczogQXJyYXk8dW5rbm93bj47XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczoge1xuICAgIHByb3ZpZGVyOiBzdHJpbmc7XG4gICAgbW9kZWxJZDogc3RyaW5nO1xuICAgIG1heEVtYmVkZGluZ3NQZXJDYWxsOiBudW1iZXI7XG4gICAgdmFsdWVzOiBBcnJheTx1bmtub3duPjtcbiAgfSkge1xuICAgIHN1cGVyKHtcbiAgICAgIG5hbWUsXG4gICAgICBtZXNzYWdlOlxuICAgICAgICBgVG9vIG1hbnkgdmFsdWVzIGZvciBhIHNpbmdsZSBlbWJlZGRpbmcgY2FsbC4gYCArXG4gICAgICAgIGBUaGUgJHtvcHRpb25zLnByb3ZpZGVyfSBtb2RlbCBcIiR7b3B0aW9ucy5tb2RlbElkfVwiIGNhbiBvbmx5IGVtYmVkIHVwIHRvIGAgK1xuICAgICAgICBgJHtvcHRpb25zLm1heEVtYmVkZGluZ3NQZXJDYWxsfSB2YWx1ZXMgcGVyIGNhbGwsIGJ1dCAke29wdGlvbnMudmFsdWVzLmxlbmd0aH0gdmFsdWVzIHdlcmUgcHJvdmlkZWQuYCxcbiAgICB9KTtcblxuICAgIHRoaXMucHJvdmlkZXIgPSBvcHRpb25zLnByb3ZpZGVyO1xuICAgIHRoaXMubW9kZWxJZCA9IG9wdGlvbnMubW9kZWxJZDtcbiAgICB0aGlzLm1heEVtYmVkZGluZ3NQZXJDYWxsID0gb3B0aW9ucy5tYXhFbWJlZGRpbmdzUGVyQ2FsbDtcbiAgICB0aGlzLnZhbHVlcyA9IG9wdGlvbnMudmFsdWVzO1xuICB9XG5cbiAgc3RhdGljIGlzSW5zdGFuY2UoXG4gICAgZXJyb3I6IHVua25vd24sXG4gICk6IGVycm9yIGlzIFRvb01hbnlFbWJlZGRpbmdWYWx1ZXNGb3JDYWxsRXJyb3Ige1xuICAgIHJldHVybiBBSVNES0Vycm9yLmhhc01hcmtlcihlcnJvciwgbWFya2VyKTtcbiAgfVxufVxuIiwgImltcG9ydCB7IEFJU0RLRXJyb3IgfSBmcm9tICcuL2FpLXNkay1lcnJvcic7XG5pbXBvcnQgeyBnZXRFcnJvck1lc3NhZ2UgfSBmcm9tICcuL2dldC1lcnJvci1tZXNzYWdlJztcblxuY29uc3QgbmFtZSA9ICdBSV9UeXBlVmFsaWRhdGlvbkVycm9yJztcbmNvbnN0IG1hcmtlciA9IGB2ZXJjZWwuYWkuZXJyb3IuJHtuYW1lfWA7XG5jb25zdCBzeW1ib2wgPSBTeW1ib2wuZm9yKG1hcmtlcik7XG5cbmV4cG9ydCBjbGFzcyBUeXBlVmFsaWRhdGlvbkVycm9yIGV4dGVuZHMgQUlTREtFcnJvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgW3N5bWJvbF0gPSB0cnVlOyAvLyB1c2VkIGluIGlzSW5zdGFuY2VcblxuICByZWFkb25seSB2YWx1ZTogdW5rbm93bjtcblxuICBjb25zdHJ1Y3Rvcih7IHZhbHVlLCBjYXVzZSB9OiB7IHZhbHVlOiB1bmtub3duOyBjYXVzZTogdW5rbm93biB9KSB7XG4gICAgc3VwZXIoe1xuICAgICAgbmFtZSxcbiAgICAgIG1lc3NhZ2U6XG4gICAgICAgIGBUeXBlIHZhbGlkYXRpb24gZmFpbGVkOiBgICtcbiAgICAgICAgYFZhbHVlOiAke0pTT04uc3RyaW5naWZ5KHZhbHVlKX0uXFxuYCArXG4gICAgICAgIGBFcnJvciBtZXNzYWdlOiAke2dldEVycm9yTWVzc2FnZShjYXVzZSl9YCxcbiAgICAgIGNhdXNlLFxuICAgIH0pO1xuXG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICB9XG5cbiAgc3RhdGljIGlzSW5zdGFuY2UoZXJyb3I6IHVua25vd24pOiBlcnJvciBpcyBUeXBlVmFsaWRhdGlvbkVycm9yIHtcbiAgICByZXR1cm4gQUlTREtFcnJvci5oYXNNYXJrZXIoZXJyb3IsIG1hcmtlcik7XG4gIH1cblxuICAvKipcbiAgICogV3JhcHMgYW4gZXJyb3IgaW50byBhIFR5cGVWYWxpZGF0aW9uRXJyb3IuXG4gICAqIElmIHRoZSBjYXVzZSBpcyBhbHJlYWR5IGEgVHlwZVZhbGlkYXRpb25FcnJvciB3aXRoIHRoZSBzYW1lIHZhbHVlLCBpdCByZXR1cm5zIHRoZSBjYXVzZS5cbiAgICogT3RoZXJ3aXNlLCBpdCBjcmVhdGVzIGEgbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IuXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwYXJhbXMgLSBUaGUgcGFyYW1ldGVycyBmb3Igd3JhcHBpbmcgdGhlIGVycm9yLlxuICAgKiBAcGFyYW0ge3Vua25vd259IHBhcmFtcy52YWx1ZSAtIFRoZSB2YWx1ZSB0aGF0IGZhaWxlZCB2YWxpZGF0aW9uLlxuICAgKiBAcGFyYW0ge3Vua25vd259IHBhcmFtcy5jYXVzZSAtIFRoZSBvcmlnaW5hbCBlcnJvciBvciBjYXVzZSBvZiB0aGUgdmFsaWRhdGlvbiBmYWlsdXJlLlxuICAgKiBAcmV0dXJucyB7VHlwZVZhbGlkYXRpb25FcnJvcn0gQSBUeXBlVmFsaWRhdGlvbkVycm9yIGluc3RhbmNlLlxuICAgKi9cbiAgc3RhdGljIHdyYXAoe1xuICAgIHZhbHVlLFxuICAgIGNhdXNlLFxuICB9OiB7XG4gICAgdmFsdWU6IHVua25vd247XG4gICAgY2F1c2U6IHVua25vd247XG4gIH0pOiBUeXBlVmFsaWRhdGlvbkVycm9yIHtcbiAgICByZXR1cm4gVHlwZVZhbGlkYXRpb25FcnJvci5pc0luc3RhbmNlKGNhdXNlKSAmJiBjYXVzZS52YWx1ZSA9PT0gdmFsdWVcbiAgICAgID8gY2F1c2VcbiAgICAgIDogbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IoeyB2YWx1ZSwgY2F1c2UgfSk7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBBSVNES0Vycm9yIH0gZnJvbSAnLi9haS1zZGstZXJyb3InO1xuXG5jb25zdCBuYW1lID0gJ0FJX1Vuc3VwcG9ydGVkRnVuY3Rpb25hbGl0eUVycm9yJztcbmNvbnN0IG1hcmtlciA9IGB2ZXJjZWwuYWkuZXJyb3IuJHtuYW1lfWA7XG5jb25zdCBzeW1ib2wgPSBTeW1ib2wuZm9yKG1hcmtlcik7XG5cbmV4cG9ydCBjbGFzcyBVbnN1cHBvcnRlZEZ1bmN0aW9uYWxpdHlFcnJvciBleHRlbmRzIEFJU0RLRXJyb3Ige1xuICBwcml2YXRlIHJlYWRvbmx5IFtzeW1ib2xdID0gdHJ1ZTsgLy8gdXNlZCBpbiBpc0luc3RhbmNlXG5cbiAgcmVhZG9ubHkgZnVuY3Rpb25hbGl0eTogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICBmdW5jdGlvbmFsaXR5LFxuICAgIG1lc3NhZ2UgPSBgJyR7ZnVuY3Rpb25hbGl0eX0nIGZ1bmN0aW9uYWxpdHkgbm90IHN1cHBvcnRlZC5gLFxuICB9OiB7XG4gICAgZnVuY3Rpb25hbGl0eTogc3RyaW5nO1xuICAgIG1lc3NhZ2U/OiBzdHJpbmc7XG4gIH0pIHtcbiAgICBzdXBlcih7IG5hbWUsIG1lc3NhZ2UgfSk7XG4gICAgdGhpcy5mdW5jdGlvbmFsaXR5ID0gZnVuY3Rpb25hbGl0eTtcbiAgfVxuXG4gIHN0YXRpYyBpc0luc3RhbmNlKGVycm9yOiB1bmtub3duKTogZXJyb3IgaXMgVW5zdXBwb3J0ZWRGdW5jdGlvbmFsaXR5RXJyb3Ige1xuICAgIHJldHVybiBBSVNES0Vycm9yLmhhc01hcmtlcihlcnJvciwgbWFya2VyKTtcbiAgfVxufVxuIiwgImltcG9ydCB7IEpTT05BcnJheSwgSlNPTk9iamVjdCwgSlNPTlZhbHVlIH0gZnJvbSAnLi9qc29uLXZhbHVlJztcblxuZXhwb3J0IGZ1bmN0aW9uIGlzSlNPTlZhbHVlKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgSlNPTlZhbHVlIHtcbiAgaWYgKFxuICAgIHZhbHVlID09PSBudWxsIHx8XG4gICAgdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyB8fFxuICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgfHxcbiAgICB0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJ1xuICApIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgIHJldHVybiB2YWx1ZS5ldmVyeShpc0pTT05WYWx1ZSk7XG4gIH1cblxuICBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jykge1xuICAgIHJldHVybiBPYmplY3QuZW50cmllcyh2YWx1ZSkuZXZlcnkoXG4gICAgICAoW2tleSwgdmFsXSkgPT4gdHlwZW9mIGtleSA9PT0gJ3N0cmluZycgJiYgaXNKU09OVmFsdWUodmFsKSxcbiAgICApO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNKU09OQXJyYXkodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBKU09OQXJyYXkge1xuICByZXR1cm4gQXJyYXkuaXNBcnJheSh2YWx1ZSkgJiYgdmFsdWUuZXZlcnkoaXNKU09OVmFsdWUpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNKU09OT2JqZWN0KHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgSlNPTk9iamVjdCB7XG4gIHJldHVybiAoXG4gICAgdmFsdWUgIT0gbnVsbCAmJlxuICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiZcbiAgICBPYmplY3QuZW50cmllcyh2YWx1ZSkuZXZlcnkoXG4gICAgICAoW2tleSwgdmFsXSkgPT4gdHlwZW9mIGtleSA9PT0gJ3N0cmluZycgJiYgaXNKU09OVmFsdWUodmFsKSxcbiAgICApXG4gICk7XG59XG4iLCAiLyoqXG4gKiBUaGUgdHlwZSBvZiBlcnJvciB0aGF0IG9jY3VycmVkLlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgdHlwZSBFcnJvclR5cGUgPSAnaW52YWxpZC1yZXRyeScgfCAndW5rbm93bi1maWVsZCdcblxuLyoqXG4gKiBFcnJvciB0aHJvd24gd2hlbiBlbmNvdW50ZXJpbmcgYW4gaXNzdWUgZHVyaW5nIHBhcnNpbmcuXG4gKlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY2xhc3MgUGFyc2VFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgLyoqXG4gICAqIFRoZSB0eXBlIG9mIGVycm9yIHRoYXQgb2NjdXJyZWQuXG4gICAqL1xuICB0eXBlOiBFcnJvclR5cGVcblxuICAvKipcbiAgICogSW4gdGhlIGNhc2Ugb2YgYW4gdW5rbm93biBmaWVsZCBlbmNvdW50ZXJlZCBpbiB0aGUgc3RyZWFtLCB0aGlzIHdpbGwgYmUgdGhlIGZpZWxkIG5hbWUuXG4gICAqL1xuICBmaWVsZD86IHN0cmluZyB8IHVuZGVmaW5lZFxuXG4gIC8qKlxuICAgKiBJbiB0aGUgY2FzZSBvZiBhbiB1bmtub3duIGZpZWxkIGVuY291bnRlcmVkIGluIHRoZSBzdHJlYW0sIHRoaXMgd2lsbCBiZSB0aGUgdmFsdWUgb2YgdGhlIGZpZWxkLlxuICAgKi9cbiAgdmFsdWU/OiBzdHJpbmcgfCB1bmRlZmluZWRcblxuICAvKipcbiAgICogVGhlIGxpbmUgdGhhdCBjYXVzZWQgdGhlIGVycm9yLCBpZiBhdmFpbGFibGUuXG4gICAqL1xuICBsaW5lPzogc3RyaW5nIHwgdW5kZWZpbmVkXG5cbiAgY29uc3RydWN0b3IoXG4gICAgbWVzc2FnZTogc3RyaW5nLFxuICAgIG9wdGlvbnM6IHt0eXBlOiBFcnJvclR5cGU7IGZpZWxkPzogc3RyaW5nOyB2YWx1ZT86IHN0cmluZzsgbGluZT86IHN0cmluZ30sXG4gICkge1xuICAgIHN1cGVyKG1lc3NhZ2UpXG4gICAgdGhpcy5uYW1lID0gJ1BhcnNlRXJyb3InXG4gICAgdGhpcy50eXBlID0gb3B0aW9ucy50eXBlXG4gICAgdGhpcy5maWVsZCA9IG9wdGlvbnMuZmllbGRcbiAgICB0aGlzLnZhbHVlID0gb3B0aW9ucy52YWx1ZVxuICAgIHRoaXMubGluZSA9IG9wdGlvbnMubGluZVxuICB9XG59XG4iLCAiLyoqXG4gKiBFdmVudFNvdXJjZS9TZXJ2ZXItU2VudCBFdmVudHMgcGFyc2VyXG4gKiBAc2VlIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3NlcnZlci1zZW50LWV2ZW50cy5odG1sXG4gKi9cbmltcG9ydCB7UGFyc2VFcnJvcn0gZnJvbSAnLi9lcnJvcnMudHMnXG5pbXBvcnQgdHlwZSB7RXZlbnRTb3VyY2VQYXJzZXIsIFBhcnNlckNhbGxiYWNrc30gZnJvbSAnLi90eXBlcy50cydcblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuZnVuY3Rpb24gbm9vcChfYXJnOiB1bmtub3duKSB7XG4gIC8vIGludGVudGlvbmFsIG5vb3Bcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IEV2ZW50U291cmNlIHBhcnNlci5cbiAqXG4gKiBAcGFyYW0gY2FsbGJhY2tzIC0gQ2FsbGJhY2tzIHRvIGludm9rZSBvbiBkaWZmZXJlbnQgcGFyc2luZyBldmVudHM6XG4gKiAgIC0gYG9uRXZlbnRgIHdoZW4gYSBuZXcgZXZlbnQgaXMgcGFyc2VkXG4gKiAgIC0gYG9uRXJyb3JgIHdoZW4gYW4gZXJyb3Igb2NjdXJzXG4gKiAgIC0gYG9uUmV0cnlgIHdoZW4gYSBuZXcgcmVjb25uZWN0aW9uIGludGVydmFsIGhhcyBiZWVuIHNlbnQgZnJvbSB0aGUgc2VydmVyXG4gKiAgIC0gYG9uQ29tbWVudGAgd2hlbiBhIGNvbW1lbnQgaXMgZW5jb3VudGVyZWQgaW4gdGhlIHN0cmVhbVxuICpcbiAqIEByZXR1cm5zIEEgbmV3IEV2ZW50U291cmNlIHBhcnNlciwgd2l0aCBgcGFyc2VgIGFuZCBgcmVzZXRgIG1ldGhvZHMuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVQYXJzZXIoY2FsbGJhY2tzOiBQYXJzZXJDYWxsYmFja3MpOiBFdmVudFNvdXJjZVBhcnNlciB7XG4gIGlmICh0eXBlb2YgY2FsbGJhY2tzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICdgY2FsbGJhY2tzYCBtdXN0IGJlIGFuIG9iamVjdCwgZ290IGEgZnVuY3Rpb24gaW5zdGVhZC4gRGlkIHlvdSBtZWFuIGB7b25FdmVudDogZm59YD8nLFxuICAgIClcbiAgfVxuXG4gIGNvbnN0IHtvbkV2ZW50ID0gbm9vcCwgb25FcnJvciA9IG5vb3AsIG9uUmV0cnkgPSBub29wLCBvbkNvbW1lbnR9ID0gY2FsbGJhY2tzXG5cbiAgbGV0IGluY29tcGxldGVMaW5lID0gJydcblxuICBsZXQgaXNGaXJzdENodW5rID0gdHJ1ZVxuICBsZXQgaWQ6IHN0cmluZyB8IHVuZGVmaW5lZFxuICBsZXQgZGF0YSA9ICcnXG4gIGxldCBldmVudFR5cGUgPSAnJ1xuXG4gIGZ1bmN0aW9uIGZlZWQobmV3Q2h1bms6IHN0cmluZykge1xuICAgIC8vIFN0cmlwIGFueSBVVEY4IGJ5dGUgb3JkZXIgbWFyayAoQk9NKSBhdCB0aGUgc3RhcnQgb2YgdGhlIHN0cmVhbVxuICAgIGNvbnN0IGNodW5rID0gaXNGaXJzdENodW5rID8gbmV3Q2h1bmsucmVwbGFjZSgvXlxceEVGXFx4QkJcXHhCRi8sICcnKSA6IG5ld0NodW5rXG5cbiAgICAvLyBJZiB0aGVyZSB3YXMgYSBwcmV2aW91cyBpbmNvbXBsZXRlIGxpbmUsIGFwcGVuZCBpdCB0byB0aGUgbmV3IGNodW5rLFxuICAgIC8vIHNvIHdlIG1heSBwcm9jZXNzIGl0IHRvZ2V0aGVyIGFzIGEgbmV3IChob3BlZnVsbHkgY29tcGxldGUpIGNodW5rLlxuICAgIGNvbnN0IFtjb21wbGV0ZSwgaW5jb21wbGV0ZV0gPSBzcGxpdExpbmVzKGAke2luY29tcGxldGVMaW5lfSR7Y2h1bmt9YClcblxuICAgIGZvciAoY29uc3QgbGluZSBvZiBjb21wbGV0ZSkge1xuICAgICAgcGFyc2VMaW5lKGxpbmUpXG4gICAgfVxuXG4gICAgaW5jb21wbGV0ZUxpbmUgPSBpbmNvbXBsZXRlXG4gICAgaXNGaXJzdENodW5rID0gZmFsc2VcbiAgfVxuXG4gIGZ1bmN0aW9uIHBhcnNlTGluZShsaW5lOiBzdHJpbmcpIHtcbiAgICAvLyBJZiB0aGUgbGluZSBpcyBlbXB0eSAoYSBibGFuayBsaW5lKSwgZGlzcGF0Y2ggdGhlIGV2ZW50XG4gICAgaWYgKGxpbmUgPT09ICcnKSB7XG4gICAgICBkaXNwYXRjaEV2ZW50KClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIC8vIElmIHRoZSBsaW5lIHN0YXJ0cyB3aXRoIGEgVSswMDNBIENPTE9OIGNoYXJhY3RlciAoOiksIGlnbm9yZSB0aGUgbGluZS5cbiAgICBpZiAobGluZS5zdGFydHNXaXRoKCc6JykpIHtcbiAgICAgIGlmIChvbkNvbW1lbnQpIHtcbiAgICAgICAgb25Db21tZW50KGxpbmUuc2xpY2UobGluZS5zdGFydHNXaXRoKCc6ICcpID8gMiA6IDEpKVxuICAgICAgfVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLy8gSWYgdGhlIGxpbmUgY29udGFpbnMgYSBVKzAwM0EgQ09MT04gY2hhcmFjdGVyICg6KVxuICAgIGNvbnN0IGZpZWxkU2VwYXJhdG9ySW5kZXggPSBsaW5lLmluZGV4T2YoJzonKVxuICAgIGlmIChmaWVsZFNlcGFyYXRvckluZGV4ICE9PSAtMSkge1xuICAgICAgLy8gQ29sbGVjdCB0aGUgY2hhcmFjdGVycyBvbiB0aGUgbGluZSBiZWZvcmUgdGhlIGZpcnN0IFUrMDAzQSBDT0xPTiBjaGFyYWN0ZXIgKDopLFxuICAgICAgLy8gYW5kIGxldCBgZmllbGRgIGJlIHRoYXQgc3RyaW5nLlxuICAgICAgY29uc3QgZmllbGQgPSBsaW5lLnNsaWNlKDAsIGZpZWxkU2VwYXJhdG9ySW5kZXgpXG5cbiAgICAgIC8vIENvbGxlY3QgdGhlIGNoYXJhY3RlcnMgb24gdGhlIGxpbmUgYWZ0ZXIgdGhlIGZpcnN0IFUrMDAzQSBDT0xPTiBjaGFyYWN0ZXIgKDopLFxuICAgICAgLy8gYW5kIGxldCBgdmFsdWVgIGJlIHRoYXQgc3RyaW5nLiBJZiB2YWx1ZSBzdGFydHMgd2l0aCBhIFUrMDAyMCBTUEFDRSBjaGFyYWN0ZXIsXG4gICAgICAvLyByZW1vdmUgaXQgZnJvbSB2YWx1ZS5cbiAgICAgIGNvbnN0IG9mZnNldCA9IGxpbmVbZmllbGRTZXBhcmF0b3JJbmRleCArIDFdID09PSAnICcgPyAyIDogMVxuICAgICAgY29uc3QgdmFsdWUgPSBsaW5lLnNsaWNlKGZpZWxkU2VwYXJhdG9ySW5kZXggKyBvZmZzZXQpXG5cbiAgICAgIHByb2Nlc3NGaWVsZChmaWVsZCwgdmFsdWUsIGxpbmUpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyBPdGhlcndpc2UsIHRoZSBzdHJpbmcgaXMgbm90IGVtcHR5IGJ1dCBkb2VzIG5vdCBjb250YWluIGEgVSswMDNBIENPTE9OIGNoYXJhY3RlciAoOilcbiAgICAvLyBQcm9jZXNzIHRoZSBmaWVsZCB1c2luZyB0aGUgd2hvbGUgbGluZSBhcyB0aGUgZmllbGQgbmFtZSwgYW5kIGFuIGVtcHR5IHN0cmluZyBhcyB0aGUgZmllbGQgdmFsdWUuXG4gICAgLy8g8J+RhiBUaGlzIGlzIGFjY29yZGluZyB0byBzcGVjLiBUaGF0IG1lYW5zIHRoYXQgYSBsaW5lIHRoYXQgaGFzIHRoZSB2YWx1ZSBgZGF0YWAgd2lsbCByZXN1bHQgaW5cbiAgICAvLyBhIG5ld2xpbmUgYmVpbmcgYWRkZWQgdG8gdGhlIGN1cnJlbnQgYGRhdGFgIGJ1ZmZlciwgZm9yIGluc3RhbmNlLlxuICAgIHByb2Nlc3NGaWVsZChsaW5lLCAnJywgbGluZSlcbiAgfVxuXG4gIGZ1bmN0aW9uIHByb2Nlc3NGaWVsZChmaWVsZDogc3RyaW5nLCB2YWx1ZTogc3RyaW5nLCBsaW5lOiBzdHJpbmcpIHtcbiAgICAvLyBGaWVsZCBuYW1lcyBtdXN0IGJlIGNvbXBhcmVkIGxpdGVyYWxseSwgd2l0aCBubyBjYXNlIGZvbGRpbmcgcGVyZm9ybWVkLlxuICAgIHN3aXRjaCAoZmllbGQpIHtcbiAgICAgIGNhc2UgJ2V2ZW50JzpcbiAgICAgICAgLy8gU2V0IHRoZSBgZXZlbnQgdHlwZWAgYnVmZmVyIHRvIGZpZWxkIHZhbHVlXG4gICAgICAgIGV2ZW50VHlwZSA9IHZhbHVlXG4gICAgICAgIGJyZWFrXG4gICAgICBjYXNlICdkYXRhJzpcbiAgICAgICAgLy8gQXBwZW5kIHRoZSBmaWVsZCB2YWx1ZSB0byB0aGUgYGRhdGFgIGJ1ZmZlciwgdGhlbiBhcHBlbmQgYSBzaW5nbGUgVSswMDBBIExJTkUgRkVFRChMRilcbiAgICAgICAgLy8gY2hhcmFjdGVyIHRvIHRoZSBgZGF0YWAgYnVmZmVyLlxuICAgICAgICBkYXRhID0gYCR7ZGF0YX0ke3ZhbHVlfVxcbmBcbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgJ2lkJzpcbiAgICAgICAgLy8gSWYgdGhlIGZpZWxkIHZhbHVlIGRvZXMgbm90IGNvbnRhaW4gVSswMDAwIE5VTEwsIHRoZW4gc2V0IHRoZSBgSURgIGJ1ZmZlciB0b1xuICAgICAgICAvLyB0aGUgZmllbGQgdmFsdWUuIE90aGVyd2lzZSwgaWdub3JlIHRoZSBmaWVsZC5cbiAgICAgICAgaWQgPSB2YWx1ZS5pbmNsdWRlcygnXFwwJykgPyB1bmRlZmluZWQgOiB2YWx1ZVxuICAgICAgICBicmVha1xuICAgICAgY2FzZSAncmV0cnknOlxuICAgICAgICAvLyBJZiB0aGUgZmllbGQgdmFsdWUgY29uc2lzdHMgb2Ygb25seSBBU0NJSSBkaWdpdHMsIHRoZW4gaW50ZXJwcmV0IHRoZSBmaWVsZCB2YWx1ZSBhcyBhblxuICAgICAgICAvLyBpbnRlZ2VyIGluIGJhc2UgdGVuLCBhbmQgc2V0IHRoZSBldmVudCBzdHJlYW0ncyByZWNvbm5lY3Rpb24gdGltZSB0byB0aGF0IGludGVnZXIuXG4gICAgICAgIC8vIE90aGVyd2lzZSwgaWdub3JlIHRoZSBmaWVsZC5cbiAgICAgICAgaWYgKC9eXFxkKyQvLnRlc3QodmFsdWUpKSB7XG4gICAgICAgICAgb25SZXRyeShwYXJzZUludCh2YWx1ZSwgMTApKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG9uRXJyb3IoXG4gICAgICAgICAgICBuZXcgUGFyc2VFcnJvcihgSW52YWxpZCBcXGByZXRyeVxcYCB2YWx1ZTogXCIke3ZhbHVlfVwiYCwge1xuICAgICAgICAgICAgICB0eXBlOiAnaW52YWxpZC1yZXRyeScsXG4gICAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgICBsaW5lLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKVxuICAgICAgICB9XG4gICAgICAgIGJyZWFrXG4gICAgICBkZWZhdWx0OlxuICAgICAgICAvLyBPdGhlcndpc2UsIHRoZSBmaWVsZCBpcyBpZ25vcmVkLlxuICAgICAgICBvbkVycm9yKFxuICAgICAgICAgIG5ldyBQYXJzZUVycm9yKFxuICAgICAgICAgICAgYFVua25vd24gZmllbGQgXCIke2ZpZWxkLmxlbmd0aCA+IDIwID8gYCR7ZmllbGQuc2xpY2UoMCwgMjApfeKApmAgOiBmaWVsZH1cImAsXG4gICAgICAgICAgICB7dHlwZTogJ3Vua25vd24tZmllbGQnLCBmaWVsZCwgdmFsdWUsIGxpbmV9LFxuICAgICAgICAgICksXG4gICAgICAgIClcbiAgICAgICAgYnJlYWtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBkaXNwYXRjaEV2ZW50KCkge1xuICAgIGNvbnN0IHNob3VsZERpc3BhdGNoID0gZGF0YS5sZW5ndGggPiAwXG4gICAgaWYgKHNob3VsZERpc3BhdGNoKSB7XG4gICAgICBvbkV2ZW50KHtcbiAgICAgICAgaWQsXG4gICAgICAgIGV2ZW50OiBldmVudFR5cGUgfHwgdW5kZWZpbmVkLFxuICAgICAgICAvLyBJZiB0aGUgZGF0YSBidWZmZXIncyBsYXN0IGNoYXJhY3RlciBpcyBhIFUrMDAwQSBMSU5FIEZFRUQgKExGKSBjaGFyYWN0ZXIsXG4gICAgICAgIC8vIHRoZW4gcmVtb3ZlIHRoZSBsYXN0IGNoYXJhY3RlciBmcm9tIHRoZSBkYXRhIGJ1ZmZlci5cbiAgICAgICAgZGF0YTogZGF0YS5lbmRzV2l0aCgnXFxuJykgPyBkYXRhLnNsaWNlKDAsIC0xKSA6IGRhdGEsXG4gICAgICB9KVxuICAgIH1cblxuICAgIC8vIFJlc2V0IGZvciB0aGUgbmV4dCBldmVudFxuICAgIGlkID0gdW5kZWZpbmVkXG4gICAgZGF0YSA9ICcnXG4gICAgZXZlbnRUeXBlID0gJydcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlc2V0KG9wdGlvbnM6IHtjb25zdW1lPzogYm9vbGVhbn0gPSB7fSkge1xuICAgIGlmIChpbmNvbXBsZXRlTGluZSAmJiBvcHRpb25zLmNvbnN1bWUpIHtcbiAgICAgIHBhcnNlTGluZShpbmNvbXBsZXRlTGluZSlcbiAgICB9XG5cbiAgICBpc0ZpcnN0Q2h1bmsgPSB0cnVlXG4gICAgaWQgPSB1bmRlZmluZWRcbiAgICBkYXRhID0gJydcbiAgICBldmVudFR5cGUgPSAnJ1xuICAgIGluY29tcGxldGVMaW5lID0gJydcbiAgfVxuXG4gIHJldHVybiB7ZmVlZCwgcmVzZXR9XG59XG5cbi8qKlxuICogRm9yIHRoZSBnaXZlbiBgY2h1bmtgLCBzcGxpdCBpdCBpbnRvIGxpbmVzIGFjY29yZGluZyB0byBzcGVjLCBhbmQgcmV0dXJuIGFueSByZW1haW5pbmcgaW5jb21wbGV0ZSBsaW5lLlxuICpcbiAqIEBwYXJhbSBjaHVuayAtIFRoZSBjaHVuayB0byBzcGxpdCBpbnRvIGxpbmVzXG4gKiBAcmV0dXJucyBBIHR1cGxlIGNvbnRhaW5pbmcgYW4gYXJyYXkgb2YgY29tcGxldGUgbGluZXMsIGFuZCBhbnkgcmVtYWluaW5nIGluY29tcGxldGUgbGluZVxuICogQGludGVybmFsXG4gKi9cbmZ1bmN0aW9uIHNwbGl0TGluZXMoY2h1bms6IHN0cmluZyk6IFtjb21wbGV0ZTogQXJyYXk8c3RyaW5nPiwgaW5jb21wbGV0ZTogc3RyaW5nXSB7XG4gIC8qKlxuICAgKiBBY2NvcmRpbmcgdG8gdGhlIHNwZWMsIGEgbGluZSBpcyB0ZXJtaW5hdGVkIGJ5IGVpdGhlcjpcbiAgICogLSBVKzAwMEQgQ0FSUklBR0UgUkVUVVJOIFUrMDAwQSBMSU5FIEZFRUQgKENSTEYpIGNoYXJhY3RlciBwYWlyXG4gICAqIC0gYSBzaW5nbGUgVSswMDBBIExJTkUgRkVFRChMRikgY2hhcmFjdGVyIG5vdCBwcmVjZWRlZCBieSBhIFUrMDAwRCBDQVJSSUFHRSBSRVRVUk4oQ1IpIGNoYXJhY3RlclxuICAgKiAtIGEgc2luZ2xlIFUrMDAwRCBDQVJSSUFHRSBSRVRVUk4oQ1IpIGNoYXJhY3RlciBub3QgZm9sbG93ZWQgYnkgYSBVKzAwMEEgTElORSBGRUVEKExGKSBjaGFyYWN0ZXJcbiAgICovXG4gIGNvbnN0IGxpbmVzOiBBcnJheTxzdHJpbmc+ID0gW11cbiAgbGV0IGluY29tcGxldGVMaW5lID0gJydcbiAgbGV0IHNlYXJjaEluZGV4ID0gMFxuXG4gIHdoaWxlIChzZWFyY2hJbmRleCA8IGNodW5rLmxlbmd0aCkge1xuICAgIC8vIEZpbmQgbmV4dCBsaW5lIHRlcm1pbmF0b3JcbiAgICBjb25zdCBjckluZGV4ID0gY2h1bmsuaW5kZXhPZignXFxyJywgc2VhcmNoSW5kZXgpXG4gICAgY29uc3QgbGZJbmRleCA9IGNodW5rLmluZGV4T2YoJ1xcbicsIHNlYXJjaEluZGV4KVxuXG4gICAgLy8gRGV0ZXJtaW5lIGxpbmUgZW5kXG4gICAgbGV0IGxpbmVFbmQgPSAtMVxuICAgIGlmIChjckluZGV4ICE9PSAtMSAmJiBsZkluZGV4ICE9PSAtMSkge1xuICAgICAgLy8gQ1JMRiBjYXNlXG4gICAgICBsaW5lRW5kID0gTWF0aC5taW4oY3JJbmRleCwgbGZJbmRleClcbiAgICB9IGVsc2UgaWYgKGNySW5kZXggIT09IC0xKSB7XG4gICAgICAvLyBDUiBhdCB0aGUgZW5kIG9mIGEgY2h1bmsgbWlnaHQgYmUgcGFydCBvZiBhIENSTEYgc2VxdWVuY2UgdGhhdCBzcGFucyBjaHVua3MsXG4gICAgICAvLyBzbyB3ZSBzaG91bGRuJ3QgdHJlYXQgaXQgYXMgYSBsaW5lIHRlcm1pbmF0b3IgKHlldClcbiAgICAgIGlmIChjckluZGV4ID09PSBjaHVuay5sZW5ndGggLSAxKSB7XG4gICAgICAgIGxpbmVFbmQgPSAtMVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGluZUVuZCA9IGNySW5kZXhcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGxmSW5kZXggIT09IC0xKSB7XG4gICAgICBsaW5lRW5kID0gbGZJbmRleFxuICAgIH1cblxuICAgIC8vIEV4dHJhY3QgbGluZSBpZiB0ZXJtaW5hdG9yIGZvdW5kXG4gICAgaWYgKGxpbmVFbmQgPT09IC0xKSB7XG4gICAgICAvLyBObyB0ZXJtaW5hdG9yIGZvdW5kLCByZXN0IGlzIGluY29tcGxldGVcbiAgICAgIGluY29tcGxldGVMaW5lID0gY2h1bmsuc2xpY2Uoc2VhcmNoSW5kZXgpXG4gICAgICBicmVha1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBsaW5lID0gY2h1bmsuc2xpY2Uoc2VhcmNoSW5kZXgsIGxpbmVFbmQpXG4gICAgICBsaW5lcy5wdXNoKGxpbmUpXG5cbiAgICAgIC8vIE1vdmUgcGFzdCBsaW5lIHRlcm1pbmF0b3JcbiAgICAgIHNlYXJjaEluZGV4ID0gbGluZUVuZCArIDFcbiAgICAgIGlmIChjaHVua1tzZWFyY2hJbmRleCAtIDFdID09PSAnXFxyJyAmJiBjaHVua1tzZWFyY2hJbmRleF0gPT09ICdcXG4nKSB7XG4gICAgICAgIHNlYXJjaEluZGV4KytcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gW2xpbmVzLCBpbmNvbXBsZXRlTGluZV1cbn1cbiIsICJpbXBvcnQge2NyZWF0ZVBhcnNlcn0gZnJvbSAnLi9wYXJzZS50cydcbmltcG9ydCB0eXBlIHtFdmVudFNvdXJjZU1lc3NhZ2UsIEV2ZW50U291cmNlUGFyc2VyfSBmcm9tICcuL3R5cGVzLnRzJ1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHRoZSBFdmVudFNvdXJjZVBhcnNlclN0cmVhbS5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RyZWFtT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBCZWhhdmlvciB3aGVuIGEgcGFyc2luZyBlcnJvciBvY2N1cnMuXG4gICAqXG4gICAqIC0gQSBjdXN0b20gZnVuY3Rpb24gY2FuIGJlIHByb3ZpZGVkIHRvIGhhbmRsZSB0aGUgZXJyb3IuXG4gICAqIC0gYCd0ZXJtaW5hdGUnYCB3aWxsIGVycm9yIHRoZSBzdHJlYW0gYW5kIHN0b3AgcGFyc2luZy5cbiAgICogLSBBbnkgb3RoZXIgdmFsdWUgd2lsbCBpZ25vcmUgdGhlIGVycm9yIGFuZCBjb250aW51ZSBwYXJzaW5nLlxuICAgKlxuICAgKiBAZGVmYXVsdFZhbHVlIGB1bmRlZmluZWRgXG4gICAqL1xuICBvbkVycm9yPzogKCd0ZXJtaW5hdGUnIHwgKChlcnJvcjogRXJyb3IpID0+IHZvaWQpKSB8IHVuZGVmaW5lZFxuXG4gIC8qKlxuICAgKiBDYWxsYmFjayBmb3Igd2hlbiBhIHJlY29ubmVjdGlvbiBpbnRlcnZhbCBpcyBzZW50IGZyb20gdGhlIHNlcnZlci5cbiAgICpcbiAgICogQHBhcmFtIHJldHJ5IC0gVGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgdG8gd2FpdCBiZWZvcmUgcmVjb25uZWN0aW5nLlxuICAgKi9cbiAgb25SZXRyeT86ICgocmV0cnk6IG51bWJlcikgPT4gdm9pZCkgfCB1bmRlZmluZWRcblxuICAvKipcbiAgICogQ2FsbGJhY2sgZm9yIHdoZW4gYSBjb21tZW50IGlzIGVuY291bnRlcmVkIGluIHRoZSBzdHJlYW0uXG4gICAqXG4gICAqIEBwYXJhbSBjb21tZW50IC0gVGhlIGNvbW1lbnQgZW5jb3VudGVyZWQgaW4gdGhlIHN0cmVhbS5cbiAgICovXG4gIG9uQ29tbWVudD86ICgoY29tbWVudDogc3RyaW5nKSA9PiB2b2lkKSB8IHVuZGVmaW5lZFxufVxuXG4vKipcbiAqIEEgVHJhbnNmb3JtU3RyZWFtIHRoYXQgaW5nZXN0cyBhIHN0cmVhbSBvZiBzdHJpbmdzIGFuZCBwcm9kdWNlcyBhIHN0cmVhbSBvZiBgRXZlbnRTb3VyY2VNZXNzYWdlYC5cbiAqXG4gKiBAZXhhbXBsZSBCYXNpYyB1c2FnZVxuICogYGBgXG4gKiBjb25zdCBldmVudFN0cmVhbSA9XG4gKiAgIHJlc3BvbnNlLmJvZHlcbiAqICAgICAucGlwZVRocm91Z2gobmV3IFRleHREZWNvZGVyU3RyZWFtKCkpXG4gKiAgICAgLnBpcGVUaHJvdWdoKG5ldyBFdmVudFNvdXJjZVBhcnNlclN0cmVhbSgpKVxuICogYGBgXG4gKlxuICogQGV4YW1wbGUgVGVybWluYXRlIHN0cmVhbSBvbiBwYXJzaW5nIGVycm9yc1xuICogYGBgXG4gKiBjb25zdCBldmVudFN0cmVhbSA9XG4gKiAgcmVzcG9uc2UuYm9keVxuICogICAucGlwZVRocm91Z2gobmV3IFRleHREZWNvZGVyU3RyZWFtKCkpXG4gKiAgIC5waXBlVGhyb3VnaChuZXcgRXZlbnRTb3VyY2VQYXJzZXJTdHJlYW0oe3Rlcm1pbmF0ZU9uRXJyb3I6IHRydWV9KSlcbiAqIGBgYFxuICpcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNsYXNzIEV2ZW50U291cmNlUGFyc2VyU3RyZWFtIGV4dGVuZHMgVHJhbnNmb3JtU3RyZWFtPHN0cmluZywgRXZlbnRTb3VyY2VNZXNzYWdlPiB7XG4gIGNvbnN0cnVjdG9yKHtvbkVycm9yLCBvblJldHJ5LCBvbkNvbW1lbnR9OiBTdHJlYW1PcHRpb25zID0ge30pIHtcbiAgICBsZXQgcGFyc2VyITogRXZlbnRTb3VyY2VQYXJzZXJcblxuICAgIHN1cGVyKHtcbiAgICAgIHN0YXJ0KGNvbnRyb2xsZXIpIHtcbiAgICAgICAgcGFyc2VyID0gY3JlYXRlUGFyc2VyKHtcbiAgICAgICAgICBvbkV2ZW50OiAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShldmVudClcbiAgICAgICAgICB9LFxuICAgICAgICAgIG9uRXJyb3IoZXJyb3IpIHtcbiAgICAgICAgICAgIGlmIChvbkVycm9yID09PSAndGVybWluYXRlJykge1xuICAgICAgICAgICAgICBjb250cm9sbGVyLmVycm9yKGVycm9yKVxuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2Ygb25FcnJvciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICBvbkVycm9yKGVycm9yKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBJZ25vcmUgYnkgZGVmYXVsdFxuICAgICAgICAgIH0sXG4gICAgICAgICAgb25SZXRyeSxcbiAgICAgICAgICBvbkNvbW1lbnQsXG4gICAgICAgIH0pXG4gICAgICB9LFxuICAgICAgdHJhbnNmb3JtKGNodW5rKSB7XG4gICAgICAgIHBhcnNlci5mZWVkKGNodW5rKVxuICAgICAgfSxcbiAgICB9KVxuICB9XG59XG5cbmV4cG9ydCB7dHlwZSBFcnJvclR5cGUsIFBhcnNlRXJyb3J9IGZyb20gJy4vZXJyb3JzLnRzJ1xuZXhwb3J0IHR5cGUge0V2ZW50U291cmNlTWVzc2FnZX0gZnJvbSAnLi90eXBlcy50cydcbiIsICJleHBvcnQgKiBhcyBjb3JlIGZyb20gXCIuLi9jb3JlL2luZGV4LmpzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9zY2hlbWFzLmpzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGVja3MuanNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2Vycm9ycy5qc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vcGFyc2UuanNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvbXBhdC5qc1wiO1xuLy8gem9kLXNwZWNpZmllZFxuaW1wb3J0IHsgY29uZmlnIH0gZnJvbSBcIi4uL2NvcmUvaW5kZXguanNcIjtcbmltcG9ydCBlbiBmcm9tIFwiLi4vbG9jYWxlcy9lbi5qc1wiO1xuY29uZmlnKGVuKCkpO1xuZXhwb3J0IHsgZ2xvYmFsUmVnaXN0cnksIHJlZ2lzdHJ5LCBjb25maWcsICRvdXRwdXQsICRpbnB1dCwgJGJyYW5kLCBjbG9uZSwgcmVnZXhlcywgdHJlZWlmeUVycm9yLCBwcmV0dGlmeUVycm9yLCBmb3JtYXRFcnJvciwgZmxhdHRlbkVycm9yLCB0b0pTT05TY2hlbWEsIFRpbWVQcmVjaXNpb24sIHV0aWwsIE5FVkVSIH0gZnJvbSBcIi4uL2NvcmUvaW5kZXguanNcIjtcbmV4cG9ydCAqIGFzIGxvY2FsZXMgZnJvbSBcIi4uL2xvY2FsZXMvaW5kZXguanNcIjtcbi8vIGlzb1xuLy8gbXVzdCBiZSBleHBvcnRlZCBmcm9tIHRvcC1sZXZlbFxuLy8gaHR0cHM6Ly9naXRodWIuY29tL2NvbGluaGFja3Mvem9kL2lzc3Vlcy80NDkxXG5leHBvcnQgeyBab2RJU09EYXRlVGltZSwgWm9kSVNPRGF0ZSwgWm9kSVNPVGltZSwgWm9kSVNPRHVyYXRpb24gfSBmcm9tIFwiLi9pc28uanNcIjtcbmV4cG9ydCAqIGFzIGlzbyBmcm9tIFwiLi9pc28uanNcIjtcbmV4cG9ydCAqIGFzIGNvZXJjZSBmcm9tIFwiLi9jb2VyY2UuanNcIjtcbiIsICJleHBvcnQgKiBmcm9tIFwiLi9jb3JlLmpzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9wYXJzZS5qc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vZXJyb3JzLmpzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9zY2hlbWFzLmpzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGVja3MuanNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3ZlcnNpb25zLmpzXCI7XG5leHBvcnQgKiBhcyB1dGlsIGZyb20gXCIuL3V0aWwuanNcIjtcbmV4cG9ydCAqIGFzIHJlZ2V4ZXMgZnJvbSBcIi4vcmVnZXhlcy5qc1wiO1xuZXhwb3J0ICogYXMgbG9jYWxlcyBmcm9tIFwiLi4vbG9jYWxlcy9pbmRleC5qc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vcmVnaXN0cmllcy5qc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vZG9jLmpzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9hcGkuanNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3RvLWpzb24tc2NoZW1hLmpzXCI7XG5leHBvcnQgKiBhcyBKU09OU2NoZW1hIGZyb20gXCIuL2pzb24tc2NoZW1hLmpzXCI7XG4iLCAiLyoqIEEgc3BlY2lhbCBjb25zdGFudCB3aXRoIHR5cGUgYG5ldmVyYCAqLyBleHBvcnQgY29uc3QgTkVWRVIgPSBPYmplY3QuZnJlZXplKHtcbiAgICBzdGF0dXM6IFwiYWJvcnRlZFwiXG59KTtcbmV4cG9ydCAvKkBfX05PX1NJREVfRUZGRUNUU19fKi8gZnVuY3Rpb24gJGNvbnN0cnVjdG9yKG5hbWUsIGluaXRpYWxpemVyLCBwYXJhbXMpIHtcbiAgICBmdW5jdGlvbiBpbml0KGluc3QsIGRlZikge1xuICAgICAgICB2YXIgX2E7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShpbnN0LCBcIl96b2RcIiwge1xuICAgICAgICAgICAgdmFsdWU6IGluc3QuX3pvZCA/PyB7fSxcbiAgICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlXG4gICAgICAgIH0pO1xuICAgICAgICAoX2EgPSBpbnN0Ll96b2QpLnRyYWl0cyA/PyAoX2EudHJhaXRzID0gbmV3IFNldCgpKTtcbiAgICAgICAgaW5zdC5fem9kLnRyYWl0cy5hZGQobmFtZSk7XG4gICAgICAgIGluaXRpYWxpemVyKGluc3QsIGRlZik7XG4gICAgICAgIC8vIHN1cHBvcnQgcHJvdG90eXBlIG1vZGlmaWNhdGlvbnNcbiAgICAgICAgZm9yKGNvbnN0IGsgaW4gXy5wcm90b3R5cGUpe1xuICAgICAgICAgICAgaWYgKCEoayBpbiBpbnN0KSkgT2JqZWN0LmRlZmluZVByb3BlcnR5KGluc3QsIGssIHtcbiAgICAgICAgICAgICAgICB2YWx1ZTogXy5wcm90b3R5cGVba10uYmluZChpbnN0KVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaW5zdC5fem9kLmNvbnN0ciA9IF87XG4gICAgICAgIGluc3QuX3pvZC5kZWYgPSBkZWY7XG4gICAgfVxuICAgIC8vIGRvZXNuJ3Qgd29yayBpZiBQYXJlbnQgaGFzIGEgY29uc3RydWN0b3Igd2l0aCBhcmd1bWVudHNcbiAgICBjb25zdCBQYXJlbnQgPSBwYXJhbXM/LlBhcmVudCA/PyBPYmplY3Q7XG4gICAgY2xhc3MgRGVmaW5pdGlvbiBleHRlbmRzIFBhcmVudCB7XG4gICAgfVxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShEZWZpbml0aW9uLCBcIm5hbWVcIiwge1xuICAgICAgICB2YWx1ZTogbmFtZVxuICAgIH0pO1xuICAgIGZ1bmN0aW9uIF8oZGVmKSB7XG4gICAgICAgIHZhciBfYTtcbiAgICAgICAgY29uc3QgaW5zdCA9IHBhcmFtcz8uUGFyZW50ID8gbmV3IERlZmluaXRpb24oKSA6IHRoaXM7XG4gICAgICAgIGluaXQoaW5zdCwgZGVmKTtcbiAgICAgICAgKF9hID0gaW5zdC5fem9kKS5kZWZlcnJlZCA/PyAoX2EuZGVmZXJyZWQgPSBbXSk7XG4gICAgICAgIGZvciAoY29uc3QgZm4gb2YgaW5zdC5fem9kLmRlZmVycmVkKXtcbiAgICAgICAgICAgIGZuKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGluc3Q7XG4gICAgfVxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShfLCBcImluaXRcIiwge1xuICAgICAgICB2YWx1ZTogaW5pdFxuICAgIH0pO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShfLCBTeW1ib2wuaGFzSW5zdGFuY2UsIHtcbiAgICAgICAgdmFsdWU6IChpbnN0KT0+e1xuICAgICAgICAgICAgaWYgKHBhcmFtcz8uUGFyZW50ICYmIGluc3QgaW5zdGFuY2VvZiBwYXJhbXMuUGFyZW50KSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIHJldHVybiBpbnN0Py5fem9kPy50cmFpdHM/LmhhcyhuYW1lKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShfLCBcIm5hbWVcIiwge1xuICAgICAgICB2YWx1ZTogbmFtZVxuICAgIH0pO1xuICAgIHJldHVybiBfO1xufVxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vICAgVVRJTElUSUVTICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5leHBvcnQgY29uc3QgJGJyYW5kID0gU3ltYm9sKFwiem9kX2JyYW5kXCIpO1xuZXhwb3J0IGNsYXNzICRab2RBc3luY0Vycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAgIGNvbnN0cnVjdG9yKCl7XG4gICAgICAgIHN1cGVyKGBFbmNvdW50ZXJlZCBQcm9taXNlIGR1cmluZyBzeW5jaHJvbm91cyBwYXJzZS4gVXNlIC5wYXJzZUFzeW5jKCkgaW5zdGVhZC5gKTtcbiAgICB9XG59XG5leHBvcnQgY2xhc3MgJFpvZEVuY29kZUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAgIGNvbnN0cnVjdG9yKG5hbWUpe1xuICAgICAgICBzdXBlcihgRW5jb3VudGVyZWQgdW5pZGlyZWN0aW9uYWwgdHJhbnNmb3JtIGR1cmluZyBlbmNvZGU6ICR7bmFtZX1gKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJab2RFbmNvZGVFcnJvclwiO1xuICAgIH1cbn1cbmV4cG9ydCBjb25zdCBnbG9iYWxDb25maWcgPSB7fTtcbmV4cG9ydCBmdW5jdGlvbiBjb25maWcobmV3Q29uZmlnKSB7XG4gICAgaWYgKG5ld0NvbmZpZykgT2JqZWN0LmFzc2lnbihnbG9iYWxDb25maWcsIG5ld0NvbmZpZyk7XG4gICAgcmV0dXJuIGdsb2JhbENvbmZpZztcbn1cbiIsICIvLyBmdW5jdGlvbnNcbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnRFcXVhbCh2YWwpIHtcbiAgICByZXR1cm4gdmFsO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydE5vdEVxdWFsKHZhbCkge1xuICAgIHJldHVybiB2YWw7XG59XG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0SXMoX2FyZykge31cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnROZXZlcihfeCkge1xuICAgIHRocm93IG5ldyBFcnJvcigpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydChfKSB7fVxuZXhwb3J0IGZ1bmN0aW9uIGdldEVudW1WYWx1ZXMoZW50cmllcykge1xuICAgIGNvbnN0IG51bWVyaWNWYWx1ZXMgPSBPYmplY3QudmFsdWVzKGVudHJpZXMpLmZpbHRlcigodik9PnR5cGVvZiB2ID09PSBcIm51bWJlclwiKTtcbiAgICBjb25zdCB2YWx1ZXMgPSBPYmplY3QuZW50cmllcyhlbnRyaWVzKS5maWx0ZXIoKFtrLCBfXSk9Pm51bWVyaWNWYWx1ZXMuaW5kZXhPZigraykgPT09IC0xKS5tYXAoKFtfLCB2XSk9PnYpO1xuICAgIHJldHVybiB2YWx1ZXM7XG59XG5leHBvcnQgZnVuY3Rpb24gam9pblZhbHVlcyhhcnJheSwgc2VwYXJhdG9yID0gXCJ8XCIpIHtcbiAgICByZXR1cm4gYXJyYXkubWFwKCh2YWwpPT5zdHJpbmdpZnlQcmltaXRpdmUodmFsKSkuam9pbihzZXBhcmF0b3IpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGpzb25TdHJpbmdpZnlSZXBsYWNlcihfLCB2YWx1ZSkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwiYmlnaW50XCIpIHJldHVybiB2YWx1ZS50b1N0cmluZygpO1xuICAgIHJldHVybiB2YWx1ZTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBjYWNoZWQoZ2V0dGVyKSB7XG4gICAgY29uc3Qgc2V0ID0gZmFsc2U7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgZ2V0IHZhbHVlICgpIHtcbiAgICAgICAgICAgIGlmICghc2V0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBnZXR0ZXIoKTtcbiAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgXCJ2YWx1ZVwiLCB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiY2FjaGVkIHZhbHVlIGFscmVhZHkgc2V0XCIpO1xuICAgICAgICB9XG4gICAgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBudWxsaXNoKGlucHV0KSB7XG4gICAgcmV0dXJuIGlucHV0ID09PSBudWxsIHx8IGlucHV0ID09PSB1bmRlZmluZWQ7XG59XG5leHBvcnQgZnVuY3Rpb24gY2xlYW5SZWdleChzb3VyY2UpIHtcbiAgICBjb25zdCBzdGFydCA9IHNvdXJjZS5zdGFydHNXaXRoKFwiXlwiKSA/IDEgOiAwO1xuICAgIGNvbnN0IGVuZCA9IHNvdXJjZS5lbmRzV2l0aChcIiRcIikgPyBzb3VyY2UubGVuZ3RoIC0gMSA6IHNvdXJjZS5sZW5ndGg7XG4gICAgcmV0dXJuIHNvdXJjZS5zbGljZShzdGFydCwgZW5kKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBmbG9hdFNhZmVSZW1haW5kZXIodmFsLCBzdGVwKSB7XG4gICAgY29uc3QgdmFsRGVjQ291bnQgPSAodmFsLnRvU3RyaW5nKCkuc3BsaXQoXCIuXCIpWzFdIHx8IFwiXCIpLmxlbmd0aDtcbiAgICBjb25zdCBzdGVwU3RyaW5nID0gc3RlcC50b1N0cmluZygpO1xuICAgIGxldCBzdGVwRGVjQ291bnQgPSAoc3RlcFN0cmluZy5zcGxpdChcIi5cIilbMV0gfHwgXCJcIikubGVuZ3RoO1xuICAgIGlmIChzdGVwRGVjQ291bnQgPT09IDAgJiYgL1xcZD9lLVxcZD8vLnRlc3Qoc3RlcFN0cmluZykpIHtcbiAgICAgICAgY29uc3QgbWF0Y2ggPSBzdGVwU3RyaW5nLm1hdGNoKC9cXGQ/ZS0oXFxkPykvKTtcbiAgICAgICAgaWYgKG1hdGNoPy5bMV0pIHtcbiAgICAgICAgICAgIHN0ZXBEZWNDb3VudCA9IE51bWJlci5wYXJzZUludChtYXRjaFsxXSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgZGVjQ291bnQgPSB2YWxEZWNDb3VudCA+IHN0ZXBEZWNDb3VudCA/IHZhbERlY0NvdW50IDogc3RlcERlY0NvdW50O1xuICAgIGNvbnN0IHZhbEludCA9IE51bWJlci5wYXJzZUludCh2YWwudG9GaXhlZChkZWNDb3VudCkucmVwbGFjZShcIi5cIiwgXCJcIikpO1xuICAgIGNvbnN0IHN0ZXBJbnQgPSBOdW1iZXIucGFyc2VJbnQoc3RlcC50b0ZpeGVkKGRlY0NvdW50KS5yZXBsYWNlKFwiLlwiLCBcIlwiKSk7XG4gICAgcmV0dXJuIHZhbEludCAlIHN0ZXBJbnQgLyAxMCAqKiBkZWNDb3VudDtcbn1cbmNvbnN0IEVWQUxVQVRJTkcgPSBTeW1ib2woXCJldmFsdWF0aW5nXCIpO1xuZXhwb3J0IGZ1bmN0aW9uIGRlZmluZUxhenkob2JqZWN0LCBrZXksIGdldHRlcikge1xuICAgIGxldCB2YWx1ZSA9IHVuZGVmaW5lZDtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqZWN0LCBrZXksIHtcbiAgICAgICAgZ2V0ICgpIHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gRVZBTFVBVElORykge1xuICAgICAgICAgICAgICAgIC8vIENpcmN1bGFyIHJlZmVyZW5jZSBkZXRlY3RlZCwgcmV0dXJuIHVuZGVmaW5lZCB0byBicmVhayB0aGUgY3ljbGVcbiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IEVWQUxVQVRJTkc7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBnZXR0ZXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfSxcbiAgICAgICAgc2V0ICh2KSB7XG4gICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqZWN0LCBrZXksIHtcbiAgICAgICAgICAgICAgICB2YWx1ZTogdlxuICAgICAgICAgICAgfSk7XG4gICAgICAgIC8vIG9iamVjdFtrZXldID0gdjtcbiAgICAgICAgfSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gb2JqZWN0Q2xvbmUob2JqKSB7XG4gICAgcmV0dXJuIE9iamVjdC5jcmVhdGUoT2JqZWN0LmdldFByb3RvdHlwZU9mKG9iaiksIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKG9iaikpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGFzc2lnblByb3AodGFyZ2V0LCBwcm9wLCB2YWx1ZSkge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIHByb3AsIHtcbiAgICAgICAgdmFsdWUsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBtZXJnZURlZnMoLi4uZGVmcykge1xuICAgIGNvbnN0IG1lcmdlZERlc2NyaXB0b3JzID0ge307XG4gICAgZm9yIChjb25zdCBkZWYgb2YgZGVmcyl7XG4gICAgICAgIGNvbnN0IGRlc2NyaXB0b3JzID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMoZGVmKTtcbiAgICAgICAgT2JqZWN0LmFzc2lnbihtZXJnZWREZXNjcmlwdG9ycywgZGVzY3JpcHRvcnMpO1xuICAgIH1cbiAgICByZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoe30sIG1lcmdlZERlc2NyaXB0b3JzKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBjbG9uZURlZihzY2hlbWEpIHtcbiAgICByZXR1cm4gbWVyZ2VEZWZzKHNjaGVtYS5fem9kLmRlZik7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2V0RWxlbWVudEF0UGF0aChvYmosIHBhdGgpIHtcbiAgICBpZiAoIXBhdGgpIHJldHVybiBvYmo7XG4gICAgcmV0dXJuIHBhdGgucmVkdWNlKChhY2MsIGtleSk9PmFjYz8uW2tleV0sIG9iaik7XG59XG5leHBvcnQgZnVuY3Rpb24gcHJvbWlzZUFsbE9iamVjdChwcm9taXNlc09iaikge1xuICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhwcm9taXNlc09iaik7XG4gICAgY29uc3QgcHJvbWlzZXMgPSBrZXlzLm1hcCgoa2V5KT0+cHJvbWlzZXNPYmpba2V5XSk7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKChyZXN1bHRzKT0+e1xuICAgICAgICBjb25zdCByZXNvbHZlZE9iaiA9IHt9O1xuICAgICAgICBmb3IobGV0IGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKyl7XG4gICAgICAgICAgICByZXNvbHZlZE9ialtrZXlzW2ldXSA9IHJlc3VsdHNbaV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc29sdmVkT2JqO1xuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHJhbmRvbVN0cmluZyhsZW5ndGggPSAxMCkge1xuICAgIGNvbnN0IGNoYXJzID0gXCJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5elwiO1xuICAgIGxldCBzdHIgPSBcIlwiO1xuICAgIGZvcihsZXQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKyl7XG4gICAgICAgIHN0ciArPSBjaGFyc1tNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBjaGFycy5sZW5ndGgpXTtcbiAgICB9XG4gICAgcmV0dXJuIHN0cjtcbn1cbmV4cG9ydCBmdW5jdGlvbiBlc2Moc3RyKSB7XG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHN0cik7XG59XG5leHBvcnQgY29uc3QgY2FwdHVyZVN0YWNrVHJhY2UgPSBcImNhcHR1cmVTdGFja1RyYWNlXCIgaW4gRXJyb3IgPyBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSA6ICguLi5fYXJncyk9Pnt9O1xuZXhwb3J0IGZ1bmN0aW9uIGlzT2JqZWN0KGRhdGEpIHtcbiAgICByZXR1cm4gdHlwZW9mIGRhdGEgPT09IFwib2JqZWN0XCIgJiYgZGF0YSAhPT0gbnVsbCAmJiAhQXJyYXkuaXNBcnJheShkYXRhKTtcbn1cbmV4cG9ydCBjb25zdCBhbGxvd3NFdmFsID0gY2FjaGVkKCgpPT57XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIGlmICh0eXBlb2YgbmF2aWdhdG9yICE9PSBcInVuZGVmaW5lZFwiICYmIG5hdmlnYXRvcj8udXNlckFnZW50Py5pbmNsdWRlcyhcIkNsb3VkZmxhcmVcIikpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICBjb25zdCBGID0gRnVuY3Rpb247XG4gICAgICAgIG5ldyBGKFwiXCIpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChfKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBpc1BsYWluT2JqZWN0KG8pIHtcbiAgICBpZiAoaXNPYmplY3QobykgPT09IGZhbHNlKSByZXR1cm4gZmFsc2U7XG4gICAgLy8gbW9kaWZpZWQgY29uc3RydWN0b3JcbiAgICBjb25zdCBjdG9yID0gby5jb25zdHJ1Y3RvcjtcbiAgICBpZiAoY3RvciA9PT0gdW5kZWZpbmVkKSByZXR1cm4gdHJ1ZTtcbiAgICAvLyBtb2RpZmllZCBwcm90b3R5cGVcbiAgICBjb25zdCBwcm90ID0gY3Rvci5wcm90b3R5cGU7XG4gICAgaWYgKGlzT2JqZWN0KHByb3QpID09PSBmYWxzZSkgcmV0dXJuIGZhbHNlO1xuICAgIC8vIGN0b3IgZG9lc24ndCBoYXZlIHN0YXRpYyBgaXNQcm90b3R5cGVPZmBcbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHByb3QsIFwiaXNQcm90b3R5cGVPZlwiKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBzaGFsbG93Q2xvbmUobykge1xuICAgIGlmIChpc1BsYWluT2JqZWN0KG8pKSByZXR1cm4ge1xuICAgICAgICAuLi5vXG4gICAgfTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShvKSkgcmV0dXJuIFtcbiAgICAgICAgLi4ub1xuICAgIF07XG4gICAgcmV0dXJuIG87XG59XG5leHBvcnQgZnVuY3Rpb24gbnVtS2V5cyhkYXRhKSB7XG4gICAgbGV0IGtleUNvdW50ID0gMDtcbiAgICBmb3IoY29uc3Qga2V5IGluIGRhdGEpe1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGRhdGEsIGtleSkpIHtcbiAgICAgICAgICAgIGtleUNvdW50Kys7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGtleUNvdW50O1xufVxuZXhwb3J0IGNvbnN0IGdldFBhcnNlZFR5cGUgPSAoZGF0YSk9PntcbiAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgc3dpdGNoKHQpe1xuICAgICAgICBjYXNlIFwidW5kZWZpbmVkXCI6XG4gICAgICAgICAgICByZXR1cm4gXCJ1bmRlZmluZWRcIjtcbiAgICAgICAgY2FzZSBcInN0cmluZ1wiOlxuICAgICAgICAgICAgcmV0dXJuIFwic3RyaW5nXCI7XG4gICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIm5hblwiIDogXCJudW1iZXJcIjtcbiAgICAgICAgY2FzZSBcImJvb2xlYW5cIjpcbiAgICAgICAgICAgIHJldHVybiBcImJvb2xlYW5cIjtcbiAgICAgICAgY2FzZSBcImZ1bmN0aW9uXCI6XG4gICAgICAgICAgICByZXR1cm4gXCJmdW5jdGlvblwiO1xuICAgICAgICBjYXNlIFwiYmlnaW50XCI6XG4gICAgICAgICAgICByZXR1cm4gXCJiaWdpbnRcIjtcbiAgICAgICAgY2FzZSBcInN5bWJvbFwiOlxuICAgICAgICAgICAgcmV0dXJuIFwic3ltYm9sXCI7XG4gICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiYXJyYXlcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGRhdGEudGhlbiAmJiB0eXBlb2YgZGF0YS50aGVuID09PSBcImZ1bmN0aW9uXCIgJiYgZGF0YS5jYXRjaCAmJiB0eXBlb2YgZGF0YS5jYXRjaCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwicHJvbWlzZVwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGVvZiBNYXAgIT09IFwidW5kZWZpbmVkXCIgJiYgZGF0YSBpbnN0YW5jZW9mIE1hcCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBcIm1hcFwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGVvZiBTZXQgIT09IFwidW5kZWZpbmVkXCIgJiYgZGF0YSBpbnN0YW5jZW9mIFNldCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBcInNldFwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGVvZiBEYXRlICE9PSBcInVuZGVmaW5lZFwiICYmIGRhdGEgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiZGF0ZVwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgaWYgKHR5cGVvZiBGaWxlICE9PSBcInVuZGVmaW5lZFwiICYmIGRhdGEgaW5zdGFuY2VvZiBGaWxlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiZmlsZVwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIFwib2JqZWN0XCI7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gZGF0YSB0eXBlOiAke3R9YCk7XG4gICAgfVxufTtcbmV4cG9ydCBjb25zdCBwcm9wZXJ0eUtleVR5cGVzID0gbmV3IFNldChbXG4gICAgXCJzdHJpbmdcIixcbiAgICBcIm51bWJlclwiLFxuICAgIFwic3ltYm9sXCJcbl0pO1xuZXhwb3J0IGNvbnN0IHByaW1pdGl2ZVR5cGVzID0gbmV3IFNldChbXG4gICAgXCJzdHJpbmdcIixcbiAgICBcIm51bWJlclwiLFxuICAgIFwiYmlnaW50XCIsXG4gICAgXCJib29sZWFuXCIsXG4gICAgXCJzeW1ib2xcIixcbiAgICBcInVuZGVmaW5lZFwiXG5dKTtcbmV4cG9ydCBmdW5jdGlvbiBlc2NhcGVSZWdleChzdHIpIHtcbiAgICByZXR1cm4gc3RyLnJlcGxhY2UoL1suKis/XiR7fSgpfFtcXF1cXFxcXS9nLCBcIlxcXFwkJlwiKTtcbn1cbi8vIHpvZC1zcGVjaWZpYyB1dGlsc1xuZXhwb3J0IGZ1bmN0aW9uIGNsb25lKGluc3QsIGRlZiwgcGFyYW1zKSB7XG4gICAgY29uc3QgY2wgPSBuZXcgaW5zdC5fem9kLmNvbnN0cihkZWYgPz8gaW5zdC5fem9kLmRlZik7XG4gICAgaWYgKCFkZWYgfHwgcGFyYW1zPy5wYXJlbnQpIGNsLl96b2QucGFyZW50ID0gaW5zdDtcbiAgICByZXR1cm4gY2w7XG59XG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplUGFyYW1zKF9wYXJhbXMpIHtcbiAgICBjb25zdCBwYXJhbXMgPSBfcGFyYW1zO1xuICAgIGlmICghcGFyYW1zKSByZXR1cm4ge307XG4gICAgaWYgKHR5cGVvZiBwYXJhbXMgPT09IFwic3RyaW5nXCIpIHJldHVybiB7XG4gICAgICAgIGVycm9yOiAoKT0+cGFyYW1zXG4gICAgfTtcbiAgICBpZiAocGFyYW1zPy5tZXNzYWdlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKHBhcmFtcz8uZXJyb3IgIT09IHVuZGVmaW5lZCkgdGhyb3cgbmV3IEVycm9yKFwiQ2Fubm90IHNwZWNpZnkgYm90aCBgbWVzc2FnZWAgYW5kIGBlcnJvcmAgcGFyYW1zXCIpO1xuICAgICAgICBwYXJhbXMuZXJyb3IgPSBwYXJhbXMubWVzc2FnZTtcbiAgICB9XG4gICAgZGVsZXRlIHBhcmFtcy5tZXNzYWdlO1xuICAgIGlmICh0eXBlb2YgcGFyYW1zLmVycm9yID09PSBcInN0cmluZ1wiKSByZXR1cm4ge1xuICAgICAgICAuLi5wYXJhbXMsXG4gICAgICAgIGVycm9yOiAoKT0+cGFyYW1zLmVycm9yXG4gICAgfTtcbiAgICByZXR1cm4gcGFyYW1zO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVRyYW5zcGFyZW50UHJveHkoZ2V0dGVyKSB7XG4gICAgbGV0IHRhcmdldDtcbiAgICByZXR1cm4gbmV3IFByb3h5KHt9LCB7XG4gICAgICAgIGdldCAoXywgcHJvcCwgcmVjZWl2ZXIpIHtcbiAgICAgICAgICAgIHRhcmdldCA/PyAodGFyZ2V0ID0gZ2V0dGVyKCkpO1xuICAgICAgICAgICAgcmV0dXJuIFJlZmxlY3QuZ2V0KHRhcmdldCwgcHJvcCwgcmVjZWl2ZXIpO1xuICAgICAgICB9LFxuICAgICAgICBzZXQgKF8sIHByb3AsIHZhbHVlLCByZWNlaXZlcikge1xuICAgICAgICAgICAgdGFyZ2V0ID8/ICh0YXJnZXQgPSBnZXR0ZXIoKSk7XG4gICAgICAgICAgICByZXR1cm4gUmVmbGVjdC5zZXQodGFyZ2V0LCBwcm9wLCB2YWx1ZSwgcmVjZWl2ZXIpO1xuICAgICAgICB9LFxuICAgICAgICBoYXMgKF8sIHByb3ApIHtcbiAgICAgICAgICAgIHRhcmdldCA/PyAodGFyZ2V0ID0gZ2V0dGVyKCkpO1xuICAgICAgICAgICAgcmV0dXJuIFJlZmxlY3QuaGFzKHRhcmdldCwgcHJvcCk7XG4gICAgICAgIH0sXG4gICAgICAgIGRlbGV0ZVByb3BlcnR5IChfLCBwcm9wKSB7XG4gICAgICAgICAgICB0YXJnZXQgPz8gKHRhcmdldCA9IGdldHRlcigpKTtcbiAgICAgICAgICAgIHJldHVybiBSZWZsZWN0LmRlbGV0ZVByb3BlcnR5KHRhcmdldCwgcHJvcCk7XG4gICAgICAgIH0sXG4gICAgICAgIG93bktleXMgKF8pIHtcbiAgICAgICAgICAgIHRhcmdldCA/PyAodGFyZ2V0ID0gZ2V0dGVyKCkpO1xuICAgICAgICAgICAgcmV0dXJuIFJlZmxlY3Qub3duS2V5cyh0YXJnZXQpO1xuICAgICAgICB9LFxuICAgICAgICBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgKF8sIHByb3ApIHtcbiAgICAgICAgICAgIHRhcmdldCA/PyAodGFyZ2V0ID0gZ2V0dGVyKCkpO1xuICAgICAgICAgICAgcmV0dXJuIFJlZmxlY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwgcHJvcCk7XG4gICAgICAgIH0sXG4gICAgICAgIGRlZmluZVByb3BlcnR5IChfLCBwcm9wLCBkZXNjcmlwdG9yKSB7XG4gICAgICAgICAgICB0YXJnZXQgPz8gKHRhcmdldCA9IGdldHRlcigpKTtcbiAgICAgICAgICAgIHJldHVybiBSZWZsZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgcHJvcCwgZGVzY3JpcHRvcik7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBzdHJpbmdpZnlQcmltaXRpdmUodmFsdWUpIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcImJpZ2ludFwiKSByZXR1cm4gdmFsdWUudG9TdHJpbmcoKSArIFwiblwiO1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIpIHJldHVybiBgXCIke3ZhbHVlfVwiYDtcbiAgICByZXR1cm4gYCR7dmFsdWV9YDtcbn1cbmV4cG9ydCBmdW5jdGlvbiBvcHRpb25hbEtleXMoc2hhcGUpIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXMoc2hhcGUpLmZpbHRlcigoayk9PntcbiAgICAgICAgcmV0dXJuIHNoYXBlW2tdLl96b2Qub3B0aW4gPT09IFwib3B0aW9uYWxcIiAmJiBzaGFwZVtrXS5fem9kLm9wdG91dCA9PT0gXCJvcHRpb25hbFwiO1xuICAgIH0pO1xufVxuZXhwb3J0IGNvbnN0IE5VTUJFUl9GT1JNQVRfUkFOR0VTID0ge1xuICAgIHNhZmVpbnQ6IFtcbiAgICAgICAgTnVtYmVyLk1JTl9TQUZFX0lOVEVHRVIsXG4gICAgICAgIE51bWJlci5NQVhfU0FGRV9JTlRFR0VSXG4gICAgXSxcbiAgICBpbnQzMjogW1xuICAgICAgICAtMjE0NzQ4MzY0OCxcbiAgICAgICAgMjE0NzQ4MzY0N1xuICAgIF0sXG4gICAgdWludDMyOiBbXG4gICAgICAgIDAsXG4gICAgICAgIDQyOTQ5NjcyOTVcbiAgICBdLFxuICAgIGZsb2F0MzI6IFtcbiAgICAgICAgLTMuNDAyODIzNDY2Mzg1Mjg4NmUzOCxcbiAgICAgICAgMy40MDI4MjM0NjYzODUyODg2ZTM4XG4gICAgXSxcbiAgICBmbG9hdDY0OiBbXG4gICAgICAgIC1OdW1iZXIuTUFYX1ZBTFVFLFxuICAgICAgICBOdW1iZXIuTUFYX1ZBTFVFXG4gICAgXVxufTtcbmV4cG9ydCBjb25zdCBCSUdJTlRfRk9STUFUX1JBTkdFUyA9IHtcbiAgICBpbnQ2NDogW1xuICAgICAgICAvKiBAX19QVVJFX18qLyBCaWdJbnQoXCItOTIyMzM3MjAzNjg1NDc3NTgwOFwiKSxcbiAgICAgICAgLyogQF9fUFVSRV9fKi8gQmlnSW50KFwiOTIyMzM3MjAzNjg1NDc3NTgwN1wiKVxuICAgIF0sXG4gICAgdWludDY0OiBbXG4gICAgICAgIC8qIEBfX1BVUkVfXyovIEJpZ0ludCgwKSxcbiAgICAgICAgLyogQF9fUFVSRV9fKi8gQmlnSW50KFwiMTg0NDY3NDQwNzM3MDk1NTE2MTVcIilcbiAgICBdXG59O1xuZXhwb3J0IGZ1bmN0aW9uIHBpY2soc2NoZW1hLCBtYXNrKSB7XG4gICAgY29uc3QgY3VyckRlZiA9IHNjaGVtYS5fem9kLmRlZjtcbiAgICBjb25zdCBkZWYgPSBtZXJnZURlZnMoc2NoZW1hLl96b2QuZGVmLCB7XG4gICAgICAgIGdldCBzaGFwZSAoKSB7XG4gICAgICAgICAgICBjb25zdCBuZXdTaGFwZSA9IHt9O1xuICAgICAgICAgICAgZm9yKGNvbnN0IGtleSBpbiBtYXNrKXtcbiAgICAgICAgICAgICAgICBpZiAoIShrZXkgaW4gY3VyckRlZi5zaGFwZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnJlY29nbml6ZWQga2V5OiBcIiR7a2V5fVwiYCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghbWFza1trZXldKSBjb250aW51ZTtcbiAgICAgICAgICAgICAgICBuZXdTaGFwZVtrZXldID0gY3VyckRlZi5zaGFwZVtrZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXNzaWduUHJvcCh0aGlzLCBcInNoYXBlXCIsIG5ld1NoYXBlKTsgLy8gc2VsZi1jYWNoaW5nXG4gICAgICAgICAgICByZXR1cm4gbmV3U2hhcGU7XG4gICAgICAgIH0sXG4gICAgICAgIGNoZWNrczogW11cbiAgICB9KTtcbiAgICByZXR1cm4gY2xvbmUoc2NoZW1hLCBkZWYpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIG9taXQoc2NoZW1hLCBtYXNrKSB7XG4gICAgY29uc3QgY3VyckRlZiA9IHNjaGVtYS5fem9kLmRlZjtcbiAgICBjb25zdCBkZWYgPSBtZXJnZURlZnMoc2NoZW1hLl96b2QuZGVmLCB7XG4gICAgICAgIGdldCBzaGFwZSAoKSB7XG4gICAgICAgICAgICBjb25zdCBuZXdTaGFwZSA9IHtcbiAgICAgICAgICAgICAgICAuLi5zY2hlbWEuX3pvZC5kZWYuc2hhcGVcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBmb3IoY29uc3Qga2V5IGluIG1hc2spe1xuICAgICAgICAgICAgICAgIGlmICghKGtleSBpbiBjdXJyRGVmLnNoYXBlKSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVucmVjb2duaXplZCBrZXk6IFwiJHtrZXl9XCJgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCFtYXNrW2tleV0pIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBuZXdTaGFwZVtrZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXNzaWduUHJvcCh0aGlzLCBcInNoYXBlXCIsIG5ld1NoYXBlKTsgLy8gc2VsZi1jYWNoaW5nXG4gICAgICAgICAgICByZXR1cm4gbmV3U2hhcGU7XG4gICAgICAgIH0sXG4gICAgICAgIGNoZWNrczogW11cbiAgICB9KTtcbiAgICByZXR1cm4gY2xvbmUoc2NoZW1hLCBkZWYpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGV4dGVuZChzY2hlbWEsIHNoYXBlKSB7XG4gICAgaWYgKCFpc1BsYWluT2JqZWN0KHNoYXBlKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGlucHV0IHRvIGV4dGVuZDogZXhwZWN0ZWQgYSBwbGFpbiBvYmplY3RcIik7XG4gICAgfVxuICAgIGNvbnN0IGNoZWNrcyA9IHNjaGVtYS5fem9kLmRlZi5jaGVja3M7XG4gICAgY29uc3QgaGFzQ2hlY2tzID0gY2hlY2tzICYmIGNoZWNrcy5sZW5ndGggPiAwO1xuICAgIGlmIChoYXNDaGVja3MpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiT2JqZWN0IHNjaGVtYXMgY29udGFpbmluZyByZWZpbmVtZW50cyBjYW5ub3QgYmUgZXh0ZW5kZWQuIFVzZSBgLnNhZmVFeHRlbmQoKWAgaW5zdGVhZC5cIik7XG4gICAgfVxuICAgIGNvbnN0IGRlZiA9IG1lcmdlRGVmcyhzY2hlbWEuX3pvZC5kZWYsIHtcbiAgICAgICAgZ2V0IHNoYXBlICgpIHtcbiAgICAgICAgICAgIGNvbnN0IF9zaGFwZSA9IHtcbiAgICAgICAgICAgICAgICAuLi5zY2hlbWEuX3pvZC5kZWYuc2hhcGUsXG4gICAgICAgICAgICAgICAgLi4uc2hhcGVcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBhc3NpZ25Qcm9wKHRoaXMsIFwic2hhcGVcIiwgX3NoYXBlKTsgLy8gc2VsZi1jYWNoaW5nXG4gICAgICAgICAgICByZXR1cm4gX3NoYXBlO1xuICAgICAgICB9LFxuICAgICAgICBjaGVja3M6IFtdXG4gICAgfSk7XG4gICAgcmV0dXJuIGNsb25lKHNjaGVtYSwgZGVmKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBzYWZlRXh0ZW5kKHNjaGVtYSwgc2hhcGUpIHtcbiAgICBpZiAoIWlzUGxhaW5PYmplY3Qoc2hhcGUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgaW5wdXQgdG8gc2FmZUV4dGVuZDogZXhwZWN0ZWQgYSBwbGFpbiBvYmplY3RcIik7XG4gICAgfVxuICAgIGNvbnN0IGRlZiA9IHtcbiAgICAgICAgLi4uc2NoZW1hLl96b2QuZGVmLFxuICAgICAgICBnZXQgc2hhcGUgKCkge1xuICAgICAgICAgICAgY29uc3QgX3NoYXBlID0ge1xuICAgICAgICAgICAgICAgIC4uLnNjaGVtYS5fem9kLmRlZi5zaGFwZSxcbiAgICAgICAgICAgICAgICAuLi5zaGFwZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGFzc2lnblByb3AodGhpcywgXCJzaGFwZVwiLCBfc2hhcGUpOyAvLyBzZWxmLWNhY2hpbmdcbiAgICAgICAgICAgIHJldHVybiBfc2hhcGU7XG4gICAgICAgIH0sXG4gICAgICAgIGNoZWNrczogc2NoZW1hLl96b2QuZGVmLmNoZWNrc1xuICAgIH07XG4gICAgcmV0dXJuIGNsb25lKHNjaGVtYSwgZGVmKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBtZXJnZShhLCBiKSB7XG4gICAgY29uc3QgZGVmID0gbWVyZ2VEZWZzKGEuX3pvZC5kZWYsIHtcbiAgICAgICAgZ2V0IHNoYXBlICgpIHtcbiAgICAgICAgICAgIGNvbnN0IF9zaGFwZSA9IHtcbiAgICAgICAgICAgICAgICAuLi5hLl96b2QuZGVmLnNoYXBlLFxuICAgICAgICAgICAgICAgIC4uLmIuX3pvZC5kZWYuc2hhcGVcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBhc3NpZ25Qcm9wKHRoaXMsIFwic2hhcGVcIiwgX3NoYXBlKTsgLy8gc2VsZi1jYWNoaW5nXG4gICAgICAgICAgICByZXR1cm4gX3NoYXBlO1xuICAgICAgICB9LFxuICAgICAgICBnZXQgY2F0Y2hhbGwgKCkge1xuICAgICAgICAgICAgcmV0dXJuIGIuX3pvZC5kZWYuY2F0Y2hhbGw7XG4gICAgICAgIH0sXG4gICAgICAgIGNoZWNrczogW11cbiAgICB9KTtcbiAgICByZXR1cm4gY2xvbmUoYSwgZGVmKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBwYXJ0aWFsKENsYXNzLCBzY2hlbWEsIG1hc2spIHtcbiAgICBjb25zdCBkZWYgPSBtZXJnZURlZnMoc2NoZW1hLl96b2QuZGVmLCB7XG4gICAgICAgIGdldCBzaGFwZSAoKSB7XG4gICAgICAgICAgICBjb25zdCBvbGRTaGFwZSA9IHNjaGVtYS5fem9kLmRlZi5zaGFwZTtcbiAgICAgICAgICAgIGNvbnN0IHNoYXBlID0ge1xuICAgICAgICAgICAgICAgIC4uLm9sZFNoYXBlXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKG1hc2spIHtcbiAgICAgICAgICAgICAgICBmb3IoY29uc3Qga2V5IGluIG1hc2spe1xuICAgICAgICAgICAgICAgICAgICBpZiAoIShrZXkgaW4gb2xkU2hhcGUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVucmVjb2duaXplZCBrZXk6IFwiJHtrZXl9XCJgKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoIW1hc2tba2V5XSkgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgIC8vIGlmIChvbGRTaGFwZVtrZXldIS5fem9kLm9wdGluID09PSBcIm9wdGlvbmFsXCIpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgICBzaGFwZVtrZXldID0gQ2xhc3MgPyBuZXcgQ2xhc3Moe1xuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJvcHRpb25hbFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgaW5uZXJUeXBlOiBvbGRTaGFwZVtrZXldXG4gICAgICAgICAgICAgICAgICAgIH0pIDogb2xkU2hhcGVba2V5XTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGZvcihjb25zdCBrZXkgaW4gb2xkU2hhcGUpe1xuICAgICAgICAgICAgICAgICAgICAvLyBpZiAob2xkU2hhcGVba2V5XSEuX3pvZC5vcHRpbiA9PT0gXCJvcHRpb25hbFwiKSBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgc2hhcGVba2V5XSA9IENsYXNzID8gbmV3IENsYXNzKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IFwib3B0aW9uYWxcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGlubmVyVHlwZTogb2xkU2hhcGVba2V5XVxuICAgICAgICAgICAgICAgICAgICB9KSA6IG9sZFNoYXBlW2tleV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXNzaWduUHJvcCh0aGlzLCBcInNoYXBlXCIsIHNoYXBlKTsgLy8gc2VsZi1jYWNoaW5nXG4gICAgICAgICAgICByZXR1cm4gc2hhcGU7XG4gICAgICAgIH0sXG4gICAgICAgIGNoZWNrczogW11cbiAgICB9KTtcbiAgICByZXR1cm4gY2xvbmUoc2NoZW1hLCBkZWYpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVkKENsYXNzLCBzY2hlbWEsIG1hc2spIHtcbiAgICBjb25zdCBkZWYgPSBtZXJnZURlZnMoc2NoZW1hLl96b2QuZGVmLCB7XG4gICAgICAgIGdldCBzaGFwZSAoKSB7XG4gICAgICAgICAgICBjb25zdCBvbGRTaGFwZSA9IHNjaGVtYS5fem9kLmRlZi5zaGFwZTtcbiAgICAgICAgICAgIGNvbnN0IHNoYXBlID0ge1xuICAgICAgICAgICAgICAgIC4uLm9sZFNoYXBlXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKG1hc2spIHtcbiAgICAgICAgICAgICAgICBmb3IoY29uc3Qga2V5IGluIG1hc2spe1xuICAgICAgICAgICAgICAgICAgICBpZiAoIShrZXkgaW4gc2hhcGUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVucmVjb2duaXplZCBrZXk6IFwiJHtrZXl9XCJgKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoIW1hc2tba2V5XSkgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgIC8vIG92ZXJ3cml0ZSB3aXRoIG5vbi1vcHRpb25hbFxuICAgICAgICAgICAgICAgICAgICBzaGFwZVtrZXldID0gbmV3IENsYXNzKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IFwibm9ub3B0aW9uYWxcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGlubmVyVHlwZTogb2xkU2hhcGVba2V5XVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGZvcihjb25zdCBrZXkgaW4gb2xkU2hhcGUpe1xuICAgICAgICAgICAgICAgICAgICAvLyBvdmVyd3JpdGUgd2l0aCBub24tb3B0aW9uYWxcbiAgICAgICAgICAgICAgICAgICAgc2hhcGVba2V5XSA9IG5ldyBDbGFzcyh7XG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiBcIm5vbm9wdGlvbmFsXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbm5lclR5cGU6IG9sZFNoYXBlW2tleV1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXNzaWduUHJvcCh0aGlzLCBcInNoYXBlXCIsIHNoYXBlKTsgLy8gc2VsZi1jYWNoaW5nXG4gICAgICAgICAgICByZXR1cm4gc2hhcGU7XG4gICAgICAgIH0sXG4gICAgICAgIGNoZWNrczogW11cbiAgICB9KTtcbiAgICByZXR1cm4gY2xvbmUoc2NoZW1hLCBkZWYpO1xufVxuLy8gaW52YWxpZF90eXBlIHwgdG9vX2JpZyB8IHRvb19zbWFsbCB8IGludmFsaWRfZm9ybWF0IHwgbm90X211bHRpcGxlX29mIHwgdW5yZWNvZ25pemVkX2tleXMgfCBpbnZhbGlkX3VuaW9uIHwgaW52YWxpZF9rZXkgfCBpbnZhbGlkX2VsZW1lbnQgfCBpbnZhbGlkX3ZhbHVlIHwgY3VzdG9tXG5leHBvcnQgZnVuY3Rpb24gYWJvcnRlZCh4LCBzdGFydEluZGV4ID0gMCkge1xuICAgIGlmICh4LmFib3J0ZWQgPT09IHRydWUpIHJldHVybiB0cnVlO1xuICAgIGZvcihsZXQgaSA9IHN0YXJ0SW5kZXg7IGkgPCB4Lmlzc3Vlcy5sZW5ndGg7IGkrKyl7XG4gICAgICAgIGlmICh4Lmlzc3Vlc1tpXT8uY29udGludWUgIT09IHRydWUpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBwcmVmaXhJc3N1ZXMocGF0aCwgaXNzdWVzKSB7XG4gICAgcmV0dXJuIGlzc3Vlcy5tYXAoKGlzcyk9PntcbiAgICAgICAgdmFyIF9hO1xuICAgICAgICAoX2EgPSBpc3MpLnBhdGggPz8gKF9hLnBhdGggPSBbXSk7XG4gICAgICAgIGlzcy5wYXRoLnVuc2hpZnQocGF0aCk7XG4gICAgICAgIHJldHVybiBpc3M7XG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gdW53cmFwTWVzc2FnZShtZXNzYWdlKSB7XG4gICAgcmV0dXJuIHR5cGVvZiBtZXNzYWdlID09PSBcInN0cmluZ1wiID8gbWVzc2FnZSA6IG1lc3NhZ2U/Lm1lc3NhZ2U7XG59XG5leHBvcnQgZnVuY3Rpb24gZmluYWxpemVJc3N1ZShpc3MsIGN0eCwgY29uZmlnKSB7XG4gICAgY29uc3QgZnVsbCA9IHtcbiAgICAgICAgLi4uaXNzLFxuICAgICAgICBwYXRoOiBpc3MucGF0aCA/PyBbXVxuICAgIH07XG4gICAgLy8gZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5XG4gICAgaWYgKCFpc3MubWVzc2FnZSkge1xuICAgICAgICBjb25zdCBtZXNzYWdlID0gdW53cmFwTWVzc2FnZShpc3MuaW5zdD8uX3pvZC5kZWY/LmVycm9yPy4oaXNzKSkgPz8gdW53cmFwTWVzc2FnZShjdHg/LmVycm9yPy4oaXNzKSkgPz8gdW53cmFwTWVzc2FnZShjb25maWcuY3VzdG9tRXJyb3I/Lihpc3MpKSA/PyB1bndyYXBNZXNzYWdlKGNvbmZpZy5sb2NhbGVFcnJvcj8uKGlzcykpID8/IFwiSW52YWxpZCBpbnB1dFwiO1xuICAgICAgICBmdWxsLm1lc3NhZ2UgPSBtZXNzYWdlO1xuICAgIH1cbiAgICAvLyBkZWxldGUgKGZ1bGwgYXMgYW55KS5kZWY7XG4gICAgZGVsZXRlIGZ1bGwuaW5zdDtcbiAgICBkZWxldGUgZnVsbC5jb250aW51ZTtcbiAgICBpZiAoIWN0eD8ucmVwb3J0SW5wdXQpIHtcbiAgICAgICAgZGVsZXRlIGZ1bGwuaW5wdXQ7XG4gICAgfVxuICAgIHJldHVybiBmdWxsO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdldFNpemFibGVPcmlnaW4oaW5wdXQpIHtcbiAgICBpZiAoaW5wdXQgaW5zdGFuY2VvZiBTZXQpIHJldHVybiBcInNldFwiO1xuICAgIGlmIChpbnB1dCBpbnN0YW5jZW9mIE1hcCkgcmV0dXJuIFwibWFwXCI7XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIGlmIChpbnB1dCBpbnN0YW5jZW9mIEZpbGUpIHJldHVybiBcImZpbGVcIjtcbiAgICByZXR1cm4gXCJ1bmtub3duXCI7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2V0TGVuZ3RoYWJsZU9yaWdpbihpbnB1dCkge1xuICAgIGlmIChBcnJheS5pc0FycmF5KGlucHV0KSkgcmV0dXJuIFwiYXJyYXlcIjtcbiAgICBpZiAodHlwZW9mIGlucHV0ID09PSBcInN0cmluZ1wiKSByZXR1cm4gXCJzdHJpbmdcIjtcbiAgICByZXR1cm4gXCJ1bmtub3duXCI7XG59XG5leHBvcnQgZnVuY3Rpb24gaXNzdWUoLi4uYXJncykge1xuICAgIGNvbnN0IFtpc3MsIGlucHV0LCBpbnN0XSA9IGFyZ3M7XG4gICAgaWYgKHR5cGVvZiBpc3MgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG1lc3NhZ2U6IGlzcyxcbiAgICAgICAgICAgIGNvZGU6IFwiY3VzdG9tXCIsXG4gICAgICAgICAgICBpbnB1dCxcbiAgICAgICAgICAgIGluc3RcbiAgICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgLi4uaXNzXG4gICAgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBjbGVhbkVudW0ob2JqKSB7XG4gICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKG9iaikuZmlsdGVyKChbaywgX10pPT57XG4gICAgICAgIC8vIHJldHVybiB0cnVlIGlmIE5hTiwgbWVhbmluZyBpdCdzIG5vdCBhIG51bWJlciwgdGh1cyBhIHN0cmluZyBrZXlcbiAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihOdW1iZXIucGFyc2VJbnQoaywgMTApKTtcbiAgICB9KS5tYXAoKGVsKT0+ZWxbMV0pO1xufVxuLy8gQ29kZWMgdXRpbGl0eSBmdW5jdGlvbnNcbmV4cG9ydCBmdW5jdGlvbiBiYXNlNjRUb1VpbnQ4QXJyYXkoYmFzZTY0KSB7XG4gICAgY29uc3QgYmluYXJ5U3RyaW5nID0gYXRvYihiYXNlNjQpO1xuICAgIGNvbnN0IGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoYmluYXJ5U3RyaW5nLmxlbmd0aCk7XG4gICAgZm9yKGxldCBpID0gMDsgaSA8IGJpbmFyeVN0cmluZy5sZW5ndGg7IGkrKyl7XG4gICAgICAgIGJ5dGVzW2ldID0gYmluYXJ5U3RyaW5nLmNoYXJDb2RlQXQoaSk7XG4gICAgfVxuICAgIHJldHVybiBieXRlcztcbn1cbmV4cG9ydCBmdW5jdGlvbiB1aW50OEFycmF5VG9CYXNlNjQoYnl0ZXMpIHtcbiAgICBsZXQgYmluYXJ5U3RyaW5nID0gXCJcIjtcbiAgICBmb3IobGV0IGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpKyspe1xuICAgICAgICBiaW5hcnlTdHJpbmcgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSk7XG4gICAgfVxuICAgIHJldHVybiBidG9hKGJpbmFyeVN0cmluZyk7XG59XG5leHBvcnQgZnVuY3Rpb24gYmFzZTY0dXJsVG9VaW50OEFycmF5KGJhc2U2NHVybCkge1xuICAgIGNvbnN0IGJhc2U2NCA9IGJhc2U2NHVybC5yZXBsYWNlKC8tL2csIFwiK1wiKS5yZXBsYWNlKC9fL2csIFwiL1wiKTtcbiAgICBjb25zdCBwYWRkaW5nID0gXCI9XCIucmVwZWF0KCg0IC0gYmFzZTY0Lmxlbmd0aCAlIDQpICUgNCk7XG4gICAgcmV0dXJuIGJhc2U2NFRvVWludDhBcnJheShiYXNlNjQgKyBwYWRkaW5nKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiB1aW50OEFycmF5VG9CYXNlNjR1cmwoYnl0ZXMpIHtcbiAgICByZXR1cm4gdWludDhBcnJheVRvQmFzZTY0KGJ5dGVzKS5yZXBsYWNlKC9cXCsvZywgXCItXCIpLnJlcGxhY2UoL1xcLy9nLCBcIl9cIikucmVwbGFjZSgvPS9nLCBcIlwiKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBoZXhUb1VpbnQ4QXJyYXkoaGV4KSB7XG4gICAgY29uc3QgY2xlYW5IZXggPSBoZXgucmVwbGFjZSgvXjB4LywgXCJcIik7XG4gICAgaWYgKGNsZWFuSGV4Lmxlbmd0aCAlIDIgIT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBoZXggc3RyaW5nIGxlbmd0aFwiKTtcbiAgICB9XG4gICAgY29uc3QgYnl0ZXMgPSBuZXcgVWludDhBcnJheShjbGVhbkhleC5sZW5ndGggLyAyKTtcbiAgICBmb3IobGV0IGkgPSAwOyBpIDwgY2xlYW5IZXgubGVuZ3RoOyBpICs9IDIpe1xuICAgICAgICBieXRlc1tpIC8gMl0gPSBOdW1iZXIucGFyc2VJbnQoY2xlYW5IZXguc2xpY2UoaSwgaSArIDIpLCAxNik7XG4gICAgfVxuICAgIHJldHVybiBieXRlcztcbn1cbmV4cG9ydCBmdW5jdGlvbiB1aW50OEFycmF5VG9IZXgoYnl0ZXMpIHtcbiAgICByZXR1cm4gQXJyYXkuZnJvbShieXRlcykubWFwKChiKT0+Yi50b1N0cmluZygxNikucGFkU3RhcnQoMiwgXCIwXCIpKS5qb2luKFwiXCIpO1xufVxuLy8gaW5zdGFuY2VvZlxuZXhwb3J0IGNsYXNzIENsYXNzIHtcbiAgICBjb25zdHJ1Y3RvciguLi5fYXJncyl7fVxufVxuIiwgImltcG9ydCB7ICRjb25zdHJ1Y3RvciB9IGZyb20gXCIuL2NvcmUuanNcIjtcbmltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4vdXRpbC5qc1wiO1xuY29uc3QgaW5pdGlhbGl6ZXIgPSAoaW5zdCwgZGVmKT0+e1xuICAgIGluc3QubmFtZSA9IFwiJFpvZEVycm9yXCI7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGluc3QsIFwiX3pvZFwiLCB7XG4gICAgICAgIHZhbHVlOiBpbnN0Ll96b2QsXG4gICAgICAgIGVudW1lcmFibGU6IGZhbHNlXG4gICAgfSk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGluc3QsIFwiaXNzdWVzXCIsIHtcbiAgICAgICAgdmFsdWU6IGRlZixcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2VcbiAgICB9KTtcbiAgICBpbnN0Lm1lc3NhZ2UgPSBKU09OLnN0cmluZ2lmeShkZWYsIHV0aWwuanNvblN0cmluZ2lmeVJlcGxhY2VyLCAyKTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoaW5zdCwgXCJ0b1N0cmluZ1wiLCB7XG4gICAgICAgIHZhbHVlOiAoKT0+aW5zdC5tZXNzYWdlLFxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZVxuICAgIH0pO1xufTtcbmV4cG9ydCBjb25zdCAkWm9kRXJyb3IgPSAkY29uc3RydWN0b3IoXCIkWm9kRXJyb3JcIiwgaW5pdGlhbGl6ZXIpO1xuZXhwb3J0IGNvbnN0ICRab2RSZWFsRXJyb3IgPSAkY29uc3RydWN0b3IoXCIkWm9kRXJyb3JcIiwgaW5pdGlhbGl6ZXIsIHtcbiAgICBQYXJlbnQ6IEVycm9yXG59KTtcbmV4cG9ydCBmdW5jdGlvbiBmbGF0dGVuRXJyb3IoZXJyb3IsIG1hcHBlciA9IChpc3N1ZSk9Pmlzc3VlLm1lc3NhZ2UpIHtcbiAgICBjb25zdCBmaWVsZEVycm9ycyA9IHt9O1xuICAgIGNvbnN0IGZvcm1FcnJvcnMgPSBbXTtcbiAgICBmb3IgKGNvbnN0IHN1YiBvZiBlcnJvci5pc3N1ZXMpe1xuICAgICAgICBpZiAoc3ViLnBhdGgubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgZmllbGRFcnJvcnNbc3ViLnBhdGhbMF1dID0gZmllbGRFcnJvcnNbc3ViLnBhdGhbMF1dIHx8IFtdO1xuICAgICAgICAgICAgZmllbGRFcnJvcnNbc3ViLnBhdGhbMF1dLnB1c2gobWFwcGVyKHN1YikpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZm9ybUVycm9ycy5wdXNoKG1hcHBlcihzdWIpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBmb3JtRXJyb3JzLFxuICAgICAgICBmaWVsZEVycm9yc1xuICAgIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZm9ybWF0RXJyb3IoZXJyb3IsIF9tYXBwZXIpIHtcbiAgICBjb25zdCBtYXBwZXIgPSBfbWFwcGVyIHx8IGZ1bmN0aW9uKGlzc3VlKSB7XG4gICAgICAgIHJldHVybiBpc3N1ZS5tZXNzYWdlO1xuICAgIH07XG4gICAgY29uc3QgZmllbGRFcnJvcnMgPSB7XG4gICAgICAgIF9lcnJvcnM6IFtdXG4gICAgfTtcbiAgICBjb25zdCBwcm9jZXNzRXJyb3IgPSAoZXJyb3IpPT57XG4gICAgICAgIGZvciAoY29uc3QgaXNzdWUgb2YgZXJyb3IuaXNzdWVzKXtcbiAgICAgICAgICAgIGlmIChpc3N1ZS5jb2RlID09PSBcImludmFsaWRfdW5pb25cIiAmJiBpc3N1ZS5lcnJvcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgaXNzdWUuZXJyb3JzLm1hcCgoaXNzdWVzKT0+cHJvY2Vzc0Vycm9yKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzc3Vlc1xuICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGlzc3VlLmNvZGUgPT09IFwiaW52YWxpZF9rZXlcIikge1xuICAgICAgICAgICAgICAgIHByb2Nlc3NFcnJvcih7XG4gICAgICAgICAgICAgICAgICAgIGlzc3VlczogaXNzdWUuaXNzdWVzXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGlzc3VlLmNvZGUgPT09IFwiaW52YWxpZF9lbGVtZW50XCIpIHtcbiAgICAgICAgICAgICAgICBwcm9jZXNzRXJyb3Ioe1xuICAgICAgICAgICAgICAgICAgICBpc3N1ZXM6IGlzc3VlLmlzc3Vlc1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChpc3N1ZS5wYXRoLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGZpZWxkRXJyb3JzLl9lcnJvcnMucHVzaChtYXBwZXIoaXNzdWUpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbGV0IGN1cnIgPSBmaWVsZEVycm9ycztcbiAgICAgICAgICAgICAgICBsZXQgaSA9IDA7XG4gICAgICAgICAgICAgICAgd2hpbGUoaSA8IGlzc3VlLnBhdGgubGVuZ3RoKXtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZWwgPSBpc3N1ZS5wYXRoW2ldO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB0ZXJtaW5hbCA9IGkgPT09IGlzc3VlLnBhdGgubGVuZ3RoIC0gMTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0ZXJtaW5hbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY3VycltlbF0gPSBjdXJyW2VsXSB8fCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2Vycm9yczogW11cbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJyW2VsXSA9IGN1cnJbZWxdIHx8IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfZXJyb3JzOiBbXVxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJbZWxdLl9lcnJvcnMucHVzaChtYXBwZXIoaXNzdWUpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjdXJyID0gY3VycltlbF07XG4gICAgICAgICAgICAgICAgICAgIGkrKztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHByb2Nlc3NFcnJvcihlcnJvcik7XG4gICAgcmV0dXJuIGZpZWxkRXJyb3JzO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHRyZWVpZnlFcnJvcihlcnJvciwgX21hcHBlcikge1xuICAgIGNvbnN0IG1hcHBlciA9IF9tYXBwZXIgfHwgZnVuY3Rpb24oaXNzdWUpIHtcbiAgICAgICAgcmV0dXJuIGlzc3VlLm1lc3NhZ2U7XG4gICAgfTtcbiAgICBjb25zdCByZXN1bHQgPSB7XG4gICAgICAgIGVycm9yczogW11cbiAgICB9O1xuICAgIGNvbnN0IHByb2Nlc3NFcnJvciA9IChlcnJvciwgcGF0aCA9IFtdKT0+e1xuICAgICAgICB2YXIgX2EsIF9iO1xuICAgICAgICBmb3IgKGNvbnN0IGlzc3VlIG9mIGVycm9yLmlzc3Vlcyl7XG4gICAgICAgICAgICBpZiAoaXNzdWUuY29kZSA9PT0gXCJpbnZhbGlkX3VuaW9uXCIgJiYgaXNzdWUuZXJyb3JzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIC8vIHJlZ3VsYXIgdW5pb24gZXJyb3JcbiAgICAgICAgICAgICAgICBpc3N1ZS5lcnJvcnMubWFwKChpc3N1ZXMpPT5wcm9jZXNzRXJyb3Ioe1xuICAgICAgICAgICAgICAgICAgICAgICAgaXNzdWVzXG4gICAgICAgICAgICAgICAgICAgIH0sIGlzc3VlLnBhdGgpKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNzdWUuY29kZSA9PT0gXCJpbnZhbGlkX2tleVwiKSB7XG4gICAgICAgICAgICAgICAgcHJvY2Vzc0Vycm9yKHtcbiAgICAgICAgICAgICAgICAgICAgaXNzdWVzOiBpc3N1ZS5pc3N1ZXNcbiAgICAgICAgICAgICAgICB9LCBpc3N1ZS5wYXRoKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNzdWUuY29kZSA9PT0gXCJpbnZhbGlkX2VsZW1lbnRcIikge1xuICAgICAgICAgICAgICAgIHByb2Nlc3NFcnJvcih7XG4gICAgICAgICAgICAgICAgICAgIGlzc3VlczogaXNzdWUuaXNzdWVzXG4gICAgICAgICAgICAgICAgfSwgaXNzdWUucGF0aCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IGZ1bGxwYXRoID0gW1xuICAgICAgICAgICAgICAgICAgICAuLi5wYXRoLFxuICAgICAgICAgICAgICAgICAgICAuLi5pc3N1ZS5wYXRoXG4gICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICAgICBpZiAoZnVsbHBhdGgubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdC5lcnJvcnMucHVzaChtYXBwZXIoaXNzdWUpKTtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxldCBjdXJyID0gcmVzdWx0O1xuICAgICAgICAgICAgICAgIGxldCBpID0gMDtcbiAgICAgICAgICAgICAgICB3aGlsZShpIDwgZnVsbHBhdGgubGVuZ3RoKXtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZWwgPSBmdWxscGF0aFtpXTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdGVybWluYWwgPSBpID09PSBmdWxscGF0aC5sZW5ndGggLSAxO1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGVsID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJyLnByb3BlcnRpZXMgPz8gKGN1cnIucHJvcGVydGllcyA9IHt9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIChfYSA9IGN1cnIucHJvcGVydGllcylbZWxdID8/IChfYVtlbF0gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JzOiBbXVxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJyID0gY3Vyci5wcm9wZXJ0aWVzW2VsXTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnIuaXRlbXMgPz8gKGN1cnIuaXRlbXMgPSBbXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAoX2IgPSBjdXJyLml0ZW1zKVtlbF0gPz8gKF9iW2VsXSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcnM6IFtdXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnIgPSBjdXJyLml0ZW1zW2VsXTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAodGVybWluYWwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnIuZXJyb3JzLnB1c2gobWFwcGVyKGlzc3VlKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaSsrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgcHJvY2Vzc0Vycm9yKGVycm9yKTtcbiAgICByZXR1cm4gcmVzdWx0O1xufVxuLyoqIEZvcm1hdCBhIFpvZEVycm9yIGFzIGEgaHVtYW4tcmVhZGFibGUgc3RyaW5nIGluIHRoZSBmb2xsb3dpbmcgZm9ybS5cbiAqXG4gKiBGcm9tXG4gKlxuICogYGBgdHNcbiAqIFpvZEVycm9yIHtcbiAqICAgaXNzdWVzOiBbXG4gKiAgICAge1xuICogICAgICAgZXhwZWN0ZWQ6ICdzdHJpbmcnLFxuICogICAgICAgY29kZTogJ2ludmFsaWRfdHlwZScsXG4gKiAgICAgICBwYXRoOiBbICd1c2VybmFtZScgXSxcbiAqICAgICAgIG1lc3NhZ2U6ICdJbnZhbGlkIGlucHV0OiBleHBlY3RlZCBzdHJpbmcnXG4gKiAgICAgfSxcbiAqICAgICB7XG4gKiAgICAgICBleHBlY3RlZDogJ251bWJlcicsXG4gKiAgICAgICBjb2RlOiAnaW52YWxpZF90eXBlJyxcbiAqICAgICAgIHBhdGg6IFsgJ2Zhdm9yaXRlTnVtYmVycycsIDEgXSxcbiAqICAgICAgIG1lc3NhZ2U6ICdJbnZhbGlkIGlucHV0OiBleHBlY3RlZCBudW1iZXInXG4gKiAgICAgfVxuICogICBdO1xuICogfVxuICogYGBgXG4gKlxuICogdG9cbiAqXG4gKiBgYGBcbiAqIHVzZXJuYW1lXG4gKiAgIFx1MjcxNiBFeHBlY3RlZCBudW1iZXIsIHJlY2VpdmVkIHN0cmluZyBhdCBcInVzZXJuYW1lXG4gKiBmYXZvcml0ZU51bWJlcnNbMF1cbiAqICAgXHUyNzE2IEludmFsaWQgaW5wdXQ6IGV4cGVjdGVkIG51bWJlclxuICogYGBgXG4gKi8gZXhwb3J0IGZ1bmN0aW9uIHRvRG90UGF0aChfcGF0aCkge1xuICAgIGNvbnN0IHNlZ3MgPSBbXTtcbiAgICBjb25zdCBwYXRoID0gX3BhdGgubWFwKChzZWcpPT50eXBlb2Ygc2VnID09PSBcIm9iamVjdFwiID8gc2VnLmtleSA6IHNlZyk7XG4gICAgZm9yIChjb25zdCBzZWcgb2YgcGF0aCl7XG4gICAgICAgIGlmICh0eXBlb2Ygc2VnID09PSBcIm51bWJlclwiKSBzZWdzLnB1c2goYFske3NlZ31dYCk7XG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiBzZWcgPT09IFwic3ltYm9sXCIpIHNlZ3MucHVzaChgWyR7SlNPTi5zdHJpbmdpZnkoU3RyaW5nKHNlZykpfV1gKTtcbiAgICAgICAgZWxzZSBpZiAoL1teXFx3JF0vLnRlc3Qoc2VnKSkgc2Vncy5wdXNoKGBbJHtKU09OLnN0cmluZ2lmeShzZWcpfV1gKTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpZiAoc2Vncy5sZW5ndGgpIHNlZ3MucHVzaChcIi5cIik7XG4gICAgICAgICAgICBzZWdzLnB1c2goc2VnKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gc2Vncy5qb2luKFwiXCIpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHByZXR0aWZ5RXJyb3IoZXJyb3IpIHtcbiAgICBjb25zdCBsaW5lcyA9IFtdO1xuICAgIC8vIHNvcnQgYnkgcGF0aCBsZW5ndGhcbiAgICBjb25zdCBpc3N1ZXMgPSBbXG4gICAgICAgIC4uLmVycm9yLmlzc3Vlc1xuICAgIF0uc29ydCgoYSwgYik9PihhLnBhdGggPz8gW10pLmxlbmd0aCAtIChiLnBhdGggPz8gW10pLmxlbmd0aCk7XG4gICAgLy8gUHJvY2VzcyBlYWNoIGlzc3VlXG4gICAgZm9yIChjb25zdCBpc3N1ZSBvZiBpc3N1ZXMpe1xuICAgICAgICBsaW5lcy5wdXNoKGBcdTI3MTYgJHtpc3N1ZS5tZXNzYWdlfWApO1xuICAgICAgICBpZiAoaXNzdWUucGF0aD8ubGVuZ3RoKSBsaW5lcy5wdXNoKGAgIFx1MjE5MiBhdCAke3RvRG90UGF0aChpc3N1ZS5wYXRoKX1gKTtcbiAgICB9XG4gICAgLy8gQ29udmVydCBNYXAgdG8gZm9ybWF0dGVkIHN0cmluZ1xuICAgIHJldHVybiBsaW5lcy5qb2luKFwiXFxuXCIpO1xufVxuIiwgImltcG9ydCAqIGFzIGNvcmUgZnJvbSBcIi4vY29yZS5qc1wiO1xuaW1wb3J0ICogYXMgZXJyb3JzIGZyb20gXCIuL2Vycm9ycy5qc1wiO1xuaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi91dGlsLmpzXCI7XG5leHBvcnQgY29uc3QgX3BhcnNlID0gKF9FcnIpPT4oc2NoZW1hLCB2YWx1ZSwgX2N0eCwgX3BhcmFtcyk9PntcbiAgICAgICAgY29uc3QgY3R4ID0gX2N0eCA/IE9iamVjdC5hc3NpZ24oX2N0eCwge1xuICAgICAgICAgICAgYXN5bmM6IGZhbHNlXG4gICAgICAgIH0pIDoge1xuICAgICAgICAgICAgYXN5bmM6IGZhbHNlXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHNjaGVtYS5fem9kLnJ1bih7XG4gICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgIGlzc3VlczogW11cbiAgICAgICAgfSwgY3R4KTtcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBjb3JlLiRab2RBc3luY0Vycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlc3VsdC5pc3N1ZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICBjb25zdCBlID0gbmV3IChfcGFyYW1zPy5FcnIgPz8gX0VycikocmVzdWx0Lmlzc3Vlcy5tYXAoKGlzcyk9PnV0aWwuZmluYWxpemVJc3N1ZShpc3MsIGN0eCwgY29yZS5jb25maWcoKSkpKTtcbiAgICAgICAgICAgIHV0aWwuY2FwdHVyZVN0YWNrVHJhY2UoZSwgX3BhcmFtcz8uY2FsbGVlKTtcbiAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdC52YWx1ZTtcbiAgICB9O1xuZXhwb3J0IGNvbnN0IHBhcnNlID0gLyogQF9fUFVSRV9fKi8gX3BhcnNlKGVycm9ycy4kWm9kUmVhbEVycm9yKTtcbmV4cG9ydCBjb25zdCBfcGFyc2VBc3luYyA9IChfRXJyKT0+YXN5bmMgKHNjaGVtYSwgdmFsdWUsIF9jdHgsIHBhcmFtcyk9PntcbiAgICAgICAgY29uc3QgY3R4ID0gX2N0eCA/IE9iamVjdC5hc3NpZ24oX2N0eCwge1xuICAgICAgICAgICAgYXN5bmM6IHRydWVcbiAgICAgICAgfSkgOiB7XG4gICAgICAgICAgICBhc3luYzogdHJ1ZVxuICAgICAgICB9O1xuICAgICAgICBsZXQgcmVzdWx0ID0gc2NoZW1hLl96b2QucnVuKHtcbiAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgaXNzdWVzOiBbXVxuICAgICAgICB9LCBjdHgpO1xuICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkgcmVzdWx0ID0gYXdhaXQgcmVzdWx0O1xuICAgICAgICBpZiAocmVzdWx0Lmlzc3Vlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNvbnN0IGUgPSBuZXcgKHBhcmFtcz8uRXJyID8/IF9FcnIpKHJlc3VsdC5pc3N1ZXMubWFwKChpc3MpPT51dGlsLmZpbmFsaXplSXNzdWUoaXNzLCBjdHgsIGNvcmUuY29uZmlnKCkpKSk7XG4gICAgICAgICAgICB1dGlsLmNhcHR1cmVTdGFja1RyYWNlKGUsIHBhcmFtcz8uY2FsbGVlKTtcbiAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdC52YWx1ZTtcbiAgICB9O1xuZXhwb3J0IGNvbnN0IHBhcnNlQXN5bmMgPSAvKiBAX19QVVJFX18qLyBfcGFyc2VBc3luYyhlcnJvcnMuJFpvZFJlYWxFcnJvcik7XG5leHBvcnQgY29uc3QgX3NhZmVQYXJzZSA9IChfRXJyKT0+KHNjaGVtYSwgdmFsdWUsIF9jdHgpPT57XG4gICAgICAgIGNvbnN0IGN0eCA9IF9jdHggPyB7XG4gICAgICAgICAgICAuLi5fY3R4LFxuICAgICAgICAgICAgYXN5bmM6IGZhbHNlXG4gICAgICAgIH0gOiB7XG4gICAgICAgICAgICBhc3luYzogZmFsc2VcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gc2NoZW1hLl96b2QucnVuKHtcbiAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgaXNzdWVzOiBbXVxuICAgICAgICB9LCBjdHgpO1xuICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IGNvcmUuJFpvZEFzeW5jRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0Lmlzc3Vlcy5sZW5ndGggPyB7XG4gICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgIGVycm9yOiBuZXcgKF9FcnIgPz8gZXJyb3JzLiRab2RFcnJvcikocmVzdWx0Lmlzc3Vlcy5tYXAoKGlzcyk9PnV0aWwuZmluYWxpemVJc3N1ZShpc3MsIGN0eCwgY29yZS5jb25maWcoKSkpKVxuICAgICAgICB9IDoge1xuICAgICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICAgIGRhdGE6IHJlc3VsdC52YWx1ZVxuICAgICAgICB9O1xuICAgIH07XG5leHBvcnQgY29uc3Qgc2FmZVBhcnNlID0gLyogQF9fUFVSRV9fKi8gX3NhZmVQYXJzZShlcnJvcnMuJFpvZFJlYWxFcnJvcik7XG5leHBvcnQgY29uc3QgX3NhZmVQYXJzZUFzeW5jID0gKF9FcnIpPT5hc3luYyAoc2NoZW1hLCB2YWx1ZSwgX2N0eCk9PntcbiAgICAgICAgY29uc3QgY3R4ID0gX2N0eCA/IE9iamVjdC5hc3NpZ24oX2N0eCwge1xuICAgICAgICAgICAgYXN5bmM6IHRydWVcbiAgICAgICAgfSkgOiB7XG4gICAgICAgICAgICBhc3luYzogdHJ1ZVxuICAgICAgICB9O1xuICAgICAgICBsZXQgcmVzdWx0ID0gc2NoZW1hLl96b2QucnVuKHtcbiAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgaXNzdWVzOiBbXVxuICAgICAgICB9LCBjdHgpO1xuICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkgcmVzdWx0ID0gYXdhaXQgcmVzdWx0O1xuICAgICAgICByZXR1cm4gcmVzdWx0Lmlzc3Vlcy5sZW5ndGggPyB7XG4gICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgIGVycm9yOiBuZXcgX0VycihyZXN1bHQuaXNzdWVzLm1hcCgoaXNzKT0+dXRpbC5maW5hbGl6ZUlzc3VlKGlzcywgY3R4LCBjb3JlLmNvbmZpZygpKSkpXG4gICAgICAgIH0gOiB7XG4gICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgZGF0YTogcmVzdWx0LnZhbHVlXG4gICAgICAgIH07XG4gICAgfTtcbmV4cG9ydCBjb25zdCBzYWZlUGFyc2VBc3luYyA9IC8qIEBfX1BVUkVfXyovIF9zYWZlUGFyc2VBc3luYyhlcnJvcnMuJFpvZFJlYWxFcnJvcik7XG5leHBvcnQgY29uc3QgX2VuY29kZSA9IChfRXJyKT0+KHNjaGVtYSwgdmFsdWUsIF9jdHgpPT57XG4gICAgICAgIGNvbnN0IGN0eCA9IF9jdHggPyBPYmplY3QuYXNzaWduKF9jdHgsIHtcbiAgICAgICAgICAgIGRpcmVjdGlvbjogXCJiYWNrd2FyZFwiXG4gICAgICAgIH0pIDoge1xuICAgICAgICAgICAgZGlyZWN0aW9uOiBcImJhY2t3YXJkXCJcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIF9wYXJzZShfRXJyKShzY2hlbWEsIHZhbHVlLCBjdHgpO1xuICAgIH07XG5leHBvcnQgY29uc3QgZW5jb2RlID0gLyogQF9fUFVSRV9fKi8gX2VuY29kZShlcnJvcnMuJFpvZFJlYWxFcnJvcik7XG5leHBvcnQgY29uc3QgX2RlY29kZSA9IChfRXJyKT0+KHNjaGVtYSwgdmFsdWUsIF9jdHgpPT57XG4gICAgICAgIHJldHVybiBfcGFyc2UoX0Vycikoc2NoZW1hLCB2YWx1ZSwgX2N0eCk7XG4gICAgfTtcbmV4cG9ydCBjb25zdCBkZWNvZGUgPSAvKiBAX19QVVJFX18qLyBfZGVjb2RlKGVycm9ycy4kWm9kUmVhbEVycm9yKTtcbmV4cG9ydCBjb25zdCBfZW5jb2RlQXN5bmMgPSAoX0Vycik9PmFzeW5jIChzY2hlbWEsIHZhbHVlLCBfY3R4KT0+e1xuICAgICAgICBjb25zdCBjdHggPSBfY3R4ID8gT2JqZWN0LmFzc2lnbihfY3R4LCB7XG4gICAgICAgICAgICBkaXJlY3Rpb246IFwiYmFja3dhcmRcIlxuICAgICAgICB9KSA6IHtcbiAgICAgICAgICAgIGRpcmVjdGlvbjogXCJiYWNrd2FyZFwiXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBfcGFyc2VBc3luYyhfRXJyKShzY2hlbWEsIHZhbHVlLCBjdHgpO1xuICAgIH07XG5leHBvcnQgY29uc3QgZW5jb2RlQXN5bmMgPSAvKiBAX19QVVJFX18qLyBfZW5jb2RlQXN5bmMoZXJyb3JzLiRab2RSZWFsRXJyb3IpO1xuZXhwb3J0IGNvbnN0IF9kZWNvZGVBc3luYyA9IChfRXJyKT0+YXN5bmMgKHNjaGVtYSwgdmFsdWUsIF9jdHgpPT57XG4gICAgICAgIHJldHVybiBfcGFyc2VBc3luYyhfRXJyKShzY2hlbWEsIHZhbHVlLCBfY3R4KTtcbiAgICB9O1xuZXhwb3J0IGNvbnN0IGRlY29kZUFzeW5jID0gLyogQF9fUFVSRV9fKi8gX2RlY29kZUFzeW5jKGVycm9ycy4kWm9kUmVhbEVycm9yKTtcbmV4cG9ydCBjb25zdCBfc2FmZUVuY29kZSA9IChfRXJyKT0+KHNjaGVtYSwgdmFsdWUsIF9jdHgpPT57XG4gICAgICAgIGNvbnN0IGN0eCA9IF9jdHggPyBPYmplY3QuYXNzaWduKF9jdHgsIHtcbiAgICAgICAgICAgIGRpcmVjdGlvbjogXCJiYWNrd2FyZFwiXG4gICAgICAgIH0pIDoge1xuICAgICAgICAgICAgZGlyZWN0aW9uOiBcImJhY2t3YXJkXCJcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIF9zYWZlUGFyc2UoX0Vycikoc2NoZW1hLCB2YWx1ZSwgY3R4KTtcbiAgICB9O1xuZXhwb3J0IGNvbnN0IHNhZmVFbmNvZGUgPSAvKiBAX19QVVJFX18qLyBfc2FmZUVuY29kZShlcnJvcnMuJFpvZFJlYWxFcnJvcik7XG5leHBvcnQgY29uc3QgX3NhZmVEZWNvZGUgPSAoX0Vycik9PihzY2hlbWEsIHZhbHVlLCBfY3R4KT0+e1xuICAgICAgICByZXR1cm4gX3NhZmVQYXJzZShfRXJyKShzY2hlbWEsIHZhbHVlLCBfY3R4KTtcbiAgICB9O1xuZXhwb3J0IGNvbnN0IHNhZmVEZWNvZGUgPSAvKiBAX19QVVJFX18qLyBfc2FmZURlY29kZShlcnJvcnMuJFpvZFJlYWxFcnJvcik7XG5leHBvcnQgY29uc3QgX3NhZmVFbmNvZGVBc3luYyA9IChfRXJyKT0+YXN5bmMgKHNjaGVtYSwgdmFsdWUsIF9jdHgpPT57XG4gICAgICAgIGNvbnN0IGN0eCA9IF9jdHggPyBPYmplY3QuYXNzaWduKF9jdHgsIHtcbiAgICAgICAgICAgIGRpcmVjdGlvbjogXCJiYWNrd2FyZFwiXG4gICAgICAgIH0pIDoge1xuICAgICAgICAgICAgZGlyZWN0aW9uOiBcImJhY2t3YXJkXCJcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIF9zYWZlUGFyc2VBc3luYyhfRXJyKShzY2hlbWEsIHZhbHVlLCBjdHgpO1xuICAgIH07XG5leHBvcnQgY29uc3Qgc2FmZUVuY29kZUFzeW5jID0gLyogQF9fUFVSRV9fKi8gX3NhZmVFbmNvZGVBc3luYyhlcnJvcnMuJFpvZFJlYWxFcnJvcik7XG5leHBvcnQgY29uc3QgX3NhZmVEZWNvZGVBc3luYyA9IChfRXJyKT0+YXN5bmMgKHNjaGVtYSwgdmFsdWUsIF9jdHgpPT57XG4gICAgICAgIHJldHVybiBfc2FmZVBhcnNlQXN5bmMoX0Vycikoc2NoZW1hLCB2YWx1ZSwgX2N0eCk7XG4gICAgfTtcbmV4cG9ydCBjb25zdCBzYWZlRGVjb2RlQXN5bmMgPSAvKiBAX19QVVJFX18qLyBfc2FmZURlY29kZUFzeW5jKGVycm9ycy4kWm9kUmVhbEVycm9yKTtcbiIsICJleHBvcnQgY29uc3QgY3VpZCA9IC9eW2NDXVteXFxzLV17OCx9JC87XG5leHBvcnQgY29uc3QgY3VpZDIgPSAvXlswLTlhLXpdKyQvO1xuZXhwb3J0IGNvbnN0IHVsaWQgPSAvXlswLTlBLUhKS01OUC1UVi1aYS1oamttbnAtdHYtel17MjZ9JC87XG5leHBvcnQgY29uc3QgeGlkID0gL15bMC05YS12QS1WXXsyMH0kLztcbmV4cG9ydCBjb25zdCBrc3VpZCA9IC9eW0EtWmEtejAtOV17Mjd9JC87XG5leHBvcnQgY29uc3QgbmFub2lkID0gL15bYS16QS1aMC05Xy1dezIxfSQvO1xuLyoqIElTTyA4NjAxLTEgZHVyYXRpb24gcmVnZXguIERvZXMgbm90IHN1cHBvcnQgdGhlIDg2MDEtMiBleHRlbnNpb25zIGxpa2UgbmVnYXRpdmUgZHVyYXRpb25zIG9yIGZyYWN0aW9uYWwvbmVnYXRpdmUgY29tcG9uZW50cy4gKi8gZXhwb3J0IGNvbnN0IGR1cmF0aW9uID0gL15QKD86KFxcZCtXKXwoPyEuKlcpKD89XFxkfFRcXGQpKFxcZCtZKT8oXFxkK00pPyhcXGQrRCk/KFQoPz1cXGQpKFxcZCtIKT8oXFxkK00pPyhcXGQrKFsuLF1cXGQrKT9TKT8pPykkLztcbi8qKiBJbXBsZW1lbnRzIElTTyA4NjAxLTIgZXh0ZW5zaW9ucyBsaWtlIGV4cGxpY2l0ICstIHByZWZpeGVzLCBtaXhpbmcgd2Vla3Mgd2l0aCBvdGhlciB1bml0cywgYW5kIGZyYWN0aW9uYWwvbmVnYXRpdmUgY29tcG9uZW50cy4gKi8gZXhwb3J0IGNvbnN0IGV4dGVuZGVkRHVyYXRpb24gPSAvXlstK10/UCg/ISQpKD86KD86Wy0rXT9cXGQrWSl8KD86Wy0rXT9cXGQrWy4sXVxcZCtZJCkpPyg/Oig/OlstK10/XFxkK00pfCg/OlstK10/XFxkK1suLF1cXGQrTSQpKT8oPzooPzpbLStdP1xcZCtXKXwoPzpbLStdP1xcZCtbLixdXFxkK1ckKSk/KD86KD86Wy0rXT9cXGQrRCl8KD86Wy0rXT9cXGQrWy4sXVxcZCtEJCkpPyg/OlQoPz1bXFxkKy1dKSg/Oig/OlstK10/XFxkK0gpfCg/OlstK10/XFxkK1suLF1cXGQrSCQpKT8oPzooPzpbLStdP1xcZCtNKXwoPzpbLStdP1xcZCtbLixdXFxkK00kKSk/KD86Wy0rXT9cXGQrKD86Wy4sXVxcZCspP1MpPyk/PyQvO1xuLyoqIEEgcmVnZXggZm9yIGFueSBVVUlELWxpa2UgaWRlbnRpZmllcjogOC00LTQtNC0xMiBoZXggcGF0dGVybiAqLyBleHBvcnQgY29uc3QgZ3VpZCA9IC9eKFswLTlhLWZBLUZdezh9LVswLTlhLWZBLUZdezR9LVswLTlhLWZBLUZdezR9LVswLTlhLWZBLUZdezR9LVswLTlhLWZBLUZdezEyfSkkLztcbi8qKiBSZXR1cm5zIGEgcmVnZXggZm9yIHZhbGlkYXRpbmcgYW4gUkZDIDk1NjIvNDEyMiBVVUlELlxuICpcbiAqIEBwYXJhbSB2ZXJzaW9uIE9wdGlvbmFsbHkgc3BlY2lmeSBhIHZlcnNpb24gMS04LiBJZiBubyB2ZXJzaW9uIGlzIHNwZWNpZmllZCwgYWxsIHZlcnNpb25zIGFyZSBzdXBwb3J0ZWQuICovIGV4cG9ydCBjb25zdCB1dWlkID0gKHZlcnNpb24pPT57XG4gICAgaWYgKCF2ZXJzaW9uKSByZXR1cm4gL14oWzAtOWEtZkEtRl17OH0tWzAtOWEtZkEtRl17NH0tWzEtOF1bMC05YS1mQS1GXXszfS1bODlhYkFCXVswLTlhLWZBLUZdezN9LVswLTlhLWZBLUZdezEyfXwwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDB8ZmZmZmZmZmYtZmZmZi1mZmZmLWZmZmYtZmZmZmZmZmZmZmZmKSQvO1xuICAgIHJldHVybiBuZXcgUmVnRXhwKGBeKFswLTlhLWZBLUZdezh9LVswLTlhLWZBLUZdezR9LSR7dmVyc2lvbn1bMC05YS1mQS1GXXszfS1bODlhYkFCXVswLTlhLWZBLUZdezN9LVswLTlhLWZBLUZdezEyfSkkYCk7XG59O1xuZXhwb3J0IGNvbnN0IHV1aWQ0ID0gLypAX19QVVJFX18qLyB1dWlkKDQpO1xuZXhwb3J0IGNvbnN0IHV1aWQ2ID0gLypAX19QVVJFX18qLyB1dWlkKDYpO1xuZXhwb3J0IGNvbnN0IHV1aWQ3ID0gLypAX19QVVJFX18qLyB1dWlkKDcpO1xuLyoqIFByYWN0aWNhbCBlbWFpbCB2YWxpZGF0aW9uICovIGV4cG9ydCBjb25zdCBlbWFpbCA9IC9eKD8hXFwuKSg/IS4qXFwuXFwuKShbQS1aYS16MC05XycrXFwtXFwuXSopW0EtWmEtejAtOV8rLV1AKFtBLVphLXowLTldW0EtWmEtejAtOVxcLV0qXFwuKStbQS1aYS16XXsyLH0kLztcbi8qKiBFcXVpdmFsZW50IHRvIHRoZSBIVE1MNSBpbnB1dFt0eXBlPWVtYWlsXSB2YWxpZGF0aW9uIGltcGxlbWVudGVkIGJ5IGJyb3dzZXJzLiBTb3VyY2U6IGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvRWxlbWVudC9pbnB1dC9lbWFpbCAqLyBleHBvcnQgY29uc3QgaHRtbDVFbWFpbCA9IC9eW2EtekEtWjAtOS4hIyQlJicqKy89P15fYHt8fX4tXStAW2EtekEtWjAtOV0oPzpbYS16QS1aMC05LV17MCw2MX1bYS16QS1aMC05XSk/KD86XFwuW2EtekEtWjAtOV0oPzpbYS16QS1aMC05LV17MCw2MX1bYS16QS1aMC05XSk/KSokLztcbi8qKiBUaGUgY2xhc3NpYyBlbWFpbHJlZ2V4LmNvbSByZWdleCBmb3IgUkZDIDUzMjItY29tcGxpYW50IGVtYWlscyAqLyBleHBvcnQgY29uc3QgcmZjNTMyMkVtYWlsID0gL14oKFtePD4oKVxcW1xcXVxcXFwuLDs6XFxzQFwiXSsoXFwuW148PigpXFxbXFxdXFxcXC4sOzpcXHNAXCJdKykqKXwoXCIuK1wiKSlAKChcXFtbMC05XXsxLDN9XFwuWzAtOV17MSwzfVxcLlswLTldezEsM31cXC5bMC05XXsxLDN9XSl8KChbYS16QS1aXFwtMC05XStcXC4pK1thLXpBLVpdezIsfSkpJC87XG4vKiogQSBsb29zZSByZWdleCB0aGF0IGFsbG93cyBVbmljb2RlIGNoYXJhY3RlcnMsIGVuZm9yY2VzIGxlbmd0aCBsaW1pdHMsIGFuZCB0aGF0J3MgYWJvdXQgaXQuICovIGV4cG9ydCBjb25zdCB1bmljb2RlRW1haWwgPSAvXlteXFxzQFwiXXsxLDY0fUBbXlxcc0BdezEsMjU1fSQvdTtcbmV4cG9ydCBjb25zdCBpZG5FbWFpbCA9IHVuaWNvZGVFbWFpbDtcbmV4cG9ydCBjb25zdCBicm93c2VyRW1haWwgPSAvXlthLXpBLVowLTkuISMkJSYnKisvPT9eX2B7fH1+LV0rQFthLXpBLVowLTldKD86W2EtekEtWjAtOS1dezAsNjF9W2EtekEtWjAtOV0pPyg/OlxcLlthLXpBLVowLTldKD86W2EtekEtWjAtOS1dezAsNjF9W2EtekEtWjAtOV0pPykqJC87XG4vLyBmcm9tIGh0dHBzOi8vdGhla2V2aW5zY290dC5jb20vZW1vamlzLWluLWphdmFzY3JpcHQvI3dyaXRpbmctYS1yZWd1bGFyLWV4cHJlc3Npb25cbmNvbnN0IF9lbW9qaSA9IGBeKFxcXFxwe0V4dGVuZGVkX1BpY3RvZ3JhcGhpY318XFxcXHB7RW1vamlfQ29tcG9uZW50fSkrJGA7XG5leHBvcnQgZnVuY3Rpb24gZW1vamkoKSB7XG4gICAgcmV0dXJuIG5ldyBSZWdFeHAoX2Vtb2ppLCBcInVcIik7XG59XG5leHBvcnQgY29uc3QgaXB2NCA9IC9eKD86KD86MjVbMC01XXwyWzAtNF1bMC05XXwxWzAtOV1bMC05XXxbMS05XVswLTldfFswLTldKVxcLil7M30oPzoyNVswLTVdfDJbMC00XVswLTldfDFbMC05XVswLTldfFsxLTldWzAtOV18WzAtOV0pJC87XG5leHBvcnQgY29uc3QgaXB2NiA9IC9eKChbMC05YS1mQS1GXXsxLDR9Oil7N31bMC05YS1mQS1GXXsxLDR9fChbMC05YS1mQS1GXXsxLDR9Oil7MSw3fTp8KFswLTlhLWZBLUZdezEsNH06KXsxLDZ9OlswLTlhLWZBLUZdezEsNH18KFswLTlhLWZBLUZdezEsNH06KXsxLDV9KDpbMC05YS1mQS1GXXsxLDR9KXsxLDJ9fChbMC05YS1mQS1GXXsxLDR9Oil7MSw0fSg6WzAtOWEtZkEtRl17MSw0fSl7MSwzfXwoWzAtOWEtZkEtRl17MSw0fTopezEsM30oOlswLTlhLWZBLUZdezEsNH0pezEsNH18KFswLTlhLWZBLUZdezEsNH06KXsxLDJ9KDpbMC05YS1mQS1GXXsxLDR9KXsxLDV9fFswLTlhLWZBLUZdezEsNH06KCg6WzAtOWEtZkEtRl17MSw0fSl7MSw2fSl8OigoOlswLTlhLWZBLUZdezEsNH0pezEsN318OikpJC87XG5leHBvcnQgY29uc3QgY2lkcnY0ID0gL14oKDI1WzAtNV18MlswLTRdWzAtOV18MVswLTldWzAtOV18WzEtOV1bMC05XXxbMC05XSlcXC4pezN9KDI1WzAtNV18MlswLTRdWzAtOV18MVswLTldWzAtOV18WzEtOV1bMC05XXxbMC05XSlcXC8oWzAtOV18WzEtMl1bMC05XXwzWzAtMl0pJC87XG5leHBvcnQgY29uc3QgY2lkcnY2ID0gL14oKFswLTlhLWZBLUZdezEsNH06KXs3fVswLTlhLWZBLUZdezEsNH18Ojp8KFswLTlhLWZBLUZdezEsNH0pPzo6KFswLTlhLWZBLUZdezEsNH06Pyl7MCw2fSlcXC8oMTJbMC04XXwxWzAxXVswLTldfFsxLTldP1swLTldKSQvO1xuLy8gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNzg2MDM5Mi9kZXRlcm1pbmUtaWYtc3RyaW5nLWlzLWluLWJhc2U2NC11c2luZy1qYXZhc2NyaXB0XG5leHBvcnQgY29uc3QgYmFzZTY0ID0gL14kfF4oPzpbMC05YS16QS1aKy9dezR9KSooPzooPzpbMC05YS16QS1aKy9dezJ9PT0pfCg/OlswLTlhLXpBLVorL117M309KSk/JC87XG5leHBvcnQgY29uc3QgYmFzZTY0dXJsID0gL15bQS1aYS16MC05Xy1dKiQvO1xuLy8gYmFzZWQgb24gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTA2MTc5L3JlZ3VsYXItZXhwcmVzc2lvbi10by1tYXRjaC1kbnMtaG9zdG5hbWUtb3ItaXAtYWRkcmVzc1xuLy8gZXhwb3J0IGNvbnN0IGhvc3RuYW1lOiBSZWdFeHAgPSAvXihbYS16QS1aMC05LV0rXFwuKSpbYS16QS1aMC05LV0rJC87XG5leHBvcnQgY29uc3QgaG9zdG5hbWUgPSAvXig/PS57MSwyNTN9XFwuPyQpW2EtekEtWjAtOV0oPzpbYS16QS1aMC05LV17MCw2MX1bYS16QS1aMC05XSk/KD86XFwuW2EtekEtWjAtOV0oPzpbLTAtOWEtekEtWl17MCw2MX1bMC05YS16QS1aXSk/KSpcXC4/JC87XG5leHBvcnQgY29uc3QgZG9tYWluID0gL14oW2EtekEtWjAtOV0oPzpbYS16QS1aMC05LV17MCw2MX1bYS16QS1aMC05XSk/XFwuKStbYS16QS1aXXsyLH0kLztcbi8vIGh0dHBzOi8vYmxvZy5zdGV2ZW5sZXZpdGhhbi5jb20vYXJjaGl2ZXMvdmFsaWRhdGUtcGhvbmUtbnVtYmVyI3I0LTMgKHJlZ2V4IHNhbnMgc3BhY2VzKVxuZXhwb3J0IGNvbnN0IGUxNjQgPSAvXlxcKyg/OlswLTldKXs2LDE0fVswLTldJC87XG4vLyBjb25zdCBkYXRlU291cmNlID0gYCgoXFxcXGRcXFxcZFsyNDY4XVswNDhdfFxcXFxkXFxcXGRbMTM1NzldWzI2XXxcXFxcZFxcXFxkMFs0OF18WzAyNDY4XVswNDhdMDB8WzEzNTc5XVsyNl0wMCktMDItMjl8XFxcXGR7NH0tKCgwWzEzNTc4XXwxWzAyXSktKDBbMS05XXxbMTJdXFxcXGR8M1swMV0pfCgwWzQ2OV18MTEpLSgwWzEtOV18WzEyXVxcXFxkfDMwKXwoMDIpLSgwWzEtOV18MVxcXFxkfDJbMC04XSkpKWA7XG5jb25zdCBkYXRlU291cmNlID0gYCg/Oig/OlxcXFxkXFxcXGRbMjQ2OF1bMDQ4XXxcXFxcZFxcXFxkWzEzNTc5XVsyNl18XFxcXGRcXFxcZDBbNDhdfFswMjQ2OF1bMDQ4XTAwfFsxMzU3OV1bMjZdMDApLTAyLTI5fFxcXFxkezR9LSg/Oig/OjBbMTM1NzhdfDFbMDJdKS0oPzowWzEtOV18WzEyXVxcXFxkfDNbMDFdKXwoPzowWzQ2OV18MTEpLSg/OjBbMS05XXxbMTJdXFxcXGR8MzApfCg/OjAyKS0oPzowWzEtOV18MVxcXFxkfDJbMC04XSkpKWA7XG5leHBvcnQgY29uc3QgZGF0ZSA9IC8qQF9fUFVSRV9fKi8gbmV3IFJlZ0V4cChgXiR7ZGF0ZVNvdXJjZX0kYCk7XG5mdW5jdGlvbiB0aW1lU291cmNlKGFyZ3MpIHtcbiAgICBjb25zdCBoaG1tID0gYCg/OlswMV1cXFxcZHwyWzAtM10pOlswLTVdXFxcXGRgO1xuICAgIGNvbnN0IHJlZ2V4ID0gdHlwZW9mIGFyZ3MucHJlY2lzaW9uID09PSBcIm51bWJlclwiID8gYXJncy5wcmVjaXNpb24gPT09IC0xID8gYCR7aGhtbX1gIDogYXJncy5wcmVjaXNpb24gPT09IDAgPyBgJHtoaG1tfTpbMC01XVxcXFxkYCA6IGAke2hobW19OlswLTVdXFxcXGRcXFxcLlxcXFxkeyR7YXJncy5wcmVjaXNpb259fWAgOiBgJHtoaG1tfSg/OjpbMC01XVxcXFxkKD86XFxcXC5cXFxcZCspPyk/YDtcbiAgICByZXR1cm4gcmVnZXg7XG59XG5leHBvcnQgZnVuY3Rpb24gdGltZShhcmdzKSB7XG4gICAgcmV0dXJuIG5ldyBSZWdFeHAoYF4ke3RpbWVTb3VyY2UoYXJncyl9JGApO1xufVxuLy8gQWRhcHRlZCBmcm9tIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8zMTQzMjMxXG5leHBvcnQgZnVuY3Rpb24gZGF0ZXRpbWUoYXJncykge1xuICAgIGNvbnN0IHRpbWUgPSB0aW1lU291cmNlKHtcbiAgICAgICAgcHJlY2lzaW9uOiBhcmdzLnByZWNpc2lvblxuICAgIH0pO1xuICAgIGNvbnN0IG9wdHMgPSBbXG4gICAgICAgIFwiWlwiXG4gICAgXTtcbiAgICBpZiAoYXJncy5sb2NhbCkgb3B0cy5wdXNoKFwiXCIpO1xuICAgIC8vIGlmIChhcmdzLm9mZnNldCkgb3B0cy5wdXNoKGAoWystXVxcXFxkezJ9OlxcXFxkezJ9KWApO1xuICAgIGlmIChhcmdzLm9mZnNldCkgb3B0cy5wdXNoKGAoWystXSg/OlswMV1cXFxcZHwyWzAtM10pOlswLTVdXFxcXGQpYCk7XG4gICAgY29uc3QgdGltZVJlZ2V4ID0gYCR7dGltZX0oPzoke29wdHMuam9pbihcInxcIil9KWA7XG4gICAgcmV0dXJuIG5ldyBSZWdFeHAoYF4ke2RhdGVTb3VyY2V9VCg/OiR7dGltZVJlZ2V4fSkkYCk7XG59XG5leHBvcnQgY29uc3Qgc3RyaW5nID0gKHBhcmFtcyk9PntcbiAgICBjb25zdCByZWdleCA9IHBhcmFtcyA/IGBbXFxcXHNcXFxcU117JHtwYXJhbXM/Lm1pbmltdW0gPz8gMH0sJHtwYXJhbXM/Lm1heGltdW0gPz8gXCJcIn19YCA6IGBbXFxcXHNcXFxcU10qYDtcbiAgICByZXR1cm4gbmV3IFJlZ0V4cChgXiR7cmVnZXh9JGApO1xufTtcbmV4cG9ydCBjb25zdCBiaWdpbnQgPSAvXi0/XFxkK24/JC87XG5leHBvcnQgY29uc3QgaW50ZWdlciA9IC9eLT9cXGQrJC87XG5leHBvcnQgY29uc3QgbnVtYmVyID0gL14tP1xcZCsoPzpcXC5cXGQrKT8vO1xuZXhwb3J0IGNvbnN0IGJvb2xlYW4gPSAvXig/OnRydWV8ZmFsc2UpJC9pO1xuY29uc3QgX251bGwgPSAvXm51bGwkL2k7XG5leHBvcnQgeyBfbnVsbCBhcyBudWxsIH07XG5jb25zdCBfdW5kZWZpbmVkID0gL151bmRlZmluZWQkL2k7XG5leHBvcnQgeyBfdW5kZWZpbmVkIGFzIHVuZGVmaW5lZCB9O1xuLy8gcmVnZXggZm9yIHN0cmluZyB3aXRoIG5vIHVwcGVyY2FzZSBsZXR0ZXJzXG5leHBvcnQgY29uc3QgbG93ZXJjYXNlID0gL15bXkEtWl0qJC87XG4vLyByZWdleCBmb3Igc3RyaW5nIHdpdGggbm8gbG93ZXJjYXNlIGxldHRlcnNcbmV4cG9ydCBjb25zdCB1cHBlcmNhc2UgPSAvXlteYS16XSokLztcbi8vIHJlZ2V4IGZvciBoZXhhZGVjaW1hbCBzdHJpbmdzIChhbnkgbGVuZ3RoKVxuZXhwb3J0IGNvbnN0IGhleCA9IC9eWzAtOWEtZkEtRl0qJC87XG4vLyBIYXNoIHJlZ2V4ZXMgZm9yIGRpZmZlcmVudCBhbGdvcml0aG1zIGFuZCBlbmNvZGluZ3Ncbi8vIEhlbHBlciBmdW5jdGlvbiB0byBjcmVhdGUgYmFzZTY0IHJlZ2V4IHdpdGggZXhhY3QgbGVuZ3RoIGFuZCBwYWRkaW5nXG5mdW5jdGlvbiBmaXhlZEJhc2U2NChib2R5TGVuZ3RoLCBwYWRkaW5nKSB7XG4gICAgcmV0dXJuIG5ldyBSZWdFeHAoYF5bQS1aYS16MC05Ky9deyR7Ym9keUxlbmd0aH19JHtwYWRkaW5nfSRgKTtcbn1cbi8vIEhlbHBlciBmdW5jdGlvbiB0byBjcmVhdGUgYmFzZTY0dXJsIHJlZ2V4IHdpdGggZXhhY3QgbGVuZ3RoIChubyBwYWRkaW5nKVxuZnVuY3Rpb24gZml4ZWRCYXNlNjR1cmwobGVuZ3RoKSB7XG4gICAgcmV0dXJuIG5ldyBSZWdFeHAoYF5bQS1aYS16MC05Xy1deyR7bGVuZ3RofX0kYCk7XG59XG4vLyBNRDUgKDE2IGJ5dGVzKTogYmFzZTY0ID0gMjQgY2hhcnMgdG90YWwgKDIyICsgXCI9PVwiKVxuZXhwb3J0IGNvbnN0IG1kNV9oZXggPSAvXlswLTlhLWZBLUZdezMyfSQvO1xuZXhwb3J0IGNvbnN0IG1kNV9iYXNlNjQgPSAvKkBfX1BVUkVfXyovIGZpeGVkQmFzZTY0KDIyLCBcIj09XCIpO1xuZXhwb3J0IGNvbnN0IG1kNV9iYXNlNjR1cmwgPSAvKkBfX1BVUkVfXyovIGZpeGVkQmFzZTY0dXJsKDIyKTtcbi8vIFNIQTEgKDIwIGJ5dGVzKTogYmFzZTY0ID0gMjggY2hhcnMgdG90YWwgKDI3ICsgXCI9XCIpXG5leHBvcnQgY29uc3Qgc2hhMV9oZXggPSAvXlswLTlhLWZBLUZdezQwfSQvO1xuZXhwb3J0IGNvbnN0IHNoYTFfYmFzZTY0ID0gLypAX19QVVJFX18qLyBmaXhlZEJhc2U2NCgyNywgXCI9XCIpO1xuZXhwb3J0IGNvbnN0IHNoYTFfYmFzZTY0dXJsID0gLypAX19QVVJFX18qLyBmaXhlZEJhc2U2NHVybCgyNyk7XG4vLyBTSEEyNTYgKDMyIGJ5dGVzKTogYmFzZTY0ID0gNDQgY2hhcnMgdG90YWwgKDQzICsgXCI9XCIpXG5leHBvcnQgY29uc3Qgc2hhMjU2X2hleCA9IC9eWzAtOWEtZkEtRl17NjR9JC87XG5leHBvcnQgY29uc3Qgc2hhMjU2X2Jhc2U2NCA9IC8qQF9fUFVSRV9fKi8gZml4ZWRCYXNlNjQoNDMsIFwiPVwiKTtcbmV4cG9ydCBjb25zdCBzaGEyNTZfYmFzZTY0dXJsID0gLypAX19QVVJFX18qLyBmaXhlZEJhc2U2NHVybCg0Myk7XG4vLyBTSEEzODQgKDQ4IGJ5dGVzKTogYmFzZTY0ID0gNjQgY2hhcnMgdG90YWwgKG5vIHBhZGRpbmcpXG5leHBvcnQgY29uc3Qgc2hhMzg0X2hleCA9IC9eWzAtOWEtZkEtRl17OTZ9JC87XG5leHBvcnQgY29uc3Qgc2hhMzg0X2Jhc2U2NCA9IC8qQF9fUFVSRV9fKi8gZml4ZWRCYXNlNjQoNjQsIFwiXCIpO1xuZXhwb3J0IGNvbnN0IHNoYTM4NF9iYXNlNjR1cmwgPSAvKkBfX1BVUkVfXyovIGZpeGVkQmFzZTY0dXJsKDY0KTtcbi8vIFNIQTUxMiAoNjQgYnl0ZXMpOiBiYXNlNjQgPSA4OCBjaGFycyB0b3RhbCAoODYgKyBcIj09XCIpXG5leHBvcnQgY29uc3Qgc2hhNTEyX2hleCA9IC9eWzAtOWEtZkEtRl17MTI4fSQvO1xuZXhwb3J0IGNvbnN0IHNoYTUxMl9iYXNlNjQgPSAvKkBfX1BVUkVfXyovIGZpeGVkQmFzZTY0KDg2LCBcIj09XCIpO1xuZXhwb3J0IGNvbnN0IHNoYTUxMl9iYXNlNjR1cmwgPSAvKkBfX1BVUkVfXyovIGZpeGVkQmFzZTY0dXJsKDg2KTtcbiIsICIvLyBpbXBvcnQgeyAkWm9kVHlwZSB9IGZyb20gXCIuL3NjaGVtYXMuanNcIjtcbmltcG9ydCAqIGFzIGNvcmUgZnJvbSBcIi4vY29yZS5qc1wiO1xuaW1wb3J0ICogYXMgcmVnZXhlcyBmcm9tIFwiLi9yZWdleGVzLmpzXCI7XG5pbXBvcnQgKiBhcyB1dGlsIGZyb20gXCIuL3V0aWwuanNcIjtcbmV4cG9ydCBjb25zdCAkWm9kQ2hlY2sgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZENoZWNrXCIsIChpbnN0LCBkZWYpPT57XG4gICAgdmFyIF9hO1xuICAgIGluc3QuX3pvZCA/PyAoaW5zdC5fem9kID0ge30pO1xuICAgIGluc3QuX3pvZC5kZWYgPSBkZWY7XG4gICAgKF9hID0gaW5zdC5fem9kKS5vbmF0dGFjaCA/PyAoX2Eub25hdHRhY2ggPSBbXSk7XG59KTtcbmNvbnN0IG51bWVyaWNPcmlnaW5NYXAgPSB7XG4gICAgbnVtYmVyOiBcIm51bWJlclwiLFxuICAgIGJpZ2ludDogXCJiaWdpbnRcIixcbiAgICBvYmplY3Q6IFwiZGF0ZVwiXG59O1xuZXhwb3J0IGNvbnN0ICRab2RDaGVja0xlc3NUaGFuID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RDaGVja0xlc3NUaGFuXCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZENoZWNrLmluaXQoaW5zdCwgZGVmKTtcbiAgICBjb25zdCBvcmlnaW4gPSBudW1lcmljT3JpZ2luTWFwW3R5cGVvZiBkZWYudmFsdWVdO1xuICAgIGluc3QuX3pvZC5vbmF0dGFjaC5wdXNoKChpbnN0KT0+e1xuICAgICAgICBjb25zdCBiYWcgPSBpbnN0Ll96b2QuYmFnO1xuICAgICAgICBjb25zdCBjdXJyID0gKGRlZi5pbmNsdXNpdmUgPyBiYWcubWF4aW11bSA6IGJhZy5leGNsdXNpdmVNYXhpbXVtKSA/PyBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7XG4gICAgICAgIGlmIChkZWYudmFsdWUgPCBjdXJyKSB7XG4gICAgICAgICAgICBpZiAoZGVmLmluY2x1c2l2ZSkgYmFnLm1heGltdW0gPSBkZWYudmFsdWU7XG4gICAgICAgICAgICBlbHNlIGJhZy5leGNsdXNpdmVNYXhpbXVtID0gZGVmLnZhbHVlO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgaW5zdC5fem9kLmNoZWNrID0gKHBheWxvYWQpPT57XG4gICAgICAgIGlmIChkZWYuaW5jbHVzaXZlID8gcGF5bG9hZC52YWx1ZSA8PSBkZWYudmFsdWUgOiBwYXlsb2FkLnZhbHVlIDwgZGVmLnZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICBvcmlnaW4sXG4gICAgICAgICAgICBjb2RlOiBcInRvb19iaWdcIixcbiAgICAgICAgICAgIG1heGltdW06IGRlZi52YWx1ZSxcbiAgICAgICAgICAgIGlucHV0OiBwYXlsb2FkLnZhbHVlLFxuICAgICAgICAgICAgaW5jbHVzaXZlOiBkZWYuaW5jbHVzaXZlLFxuICAgICAgICAgICAgaW5zdCxcbiAgICAgICAgICAgIGNvbnRpbnVlOiAhZGVmLmFib3J0XG4gICAgICAgIH0pO1xuICAgIH07XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kQ2hlY2tHcmVhdGVyVGhhbiA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kQ2hlY2tHcmVhdGVyVGhhblwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RDaGVjay5pbml0KGluc3QsIGRlZik7XG4gICAgY29uc3Qgb3JpZ2luID0gbnVtZXJpY09yaWdpbk1hcFt0eXBlb2YgZGVmLnZhbHVlXTtcbiAgICBpbnN0Ll96b2Qub25hdHRhY2gucHVzaCgoaW5zdCk9PntcbiAgICAgICAgY29uc3QgYmFnID0gaW5zdC5fem9kLmJhZztcbiAgICAgICAgY29uc3QgY3VyciA9IChkZWYuaW5jbHVzaXZlID8gYmFnLm1pbmltdW0gOiBiYWcuZXhjbHVzaXZlTWluaW11bSkgPz8gTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZO1xuICAgICAgICBpZiAoZGVmLnZhbHVlID4gY3Vycikge1xuICAgICAgICAgICAgaWYgKGRlZi5pbmNsdXNpdmUpIGJhZy5taW5pbXVtID0gZGVmLnZhbHVlO1xuICAgICAgICAgICAgZWxzZSBiYWcuZXhjbHVzaXZlTWluaW11bSA9IGRlZi52YWx1ZTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIGluc3QuX3pvZC5jaGVjayA9IChwYXlsb2FkKT0+e1xuICAgICAgICBpZiAoZGVmLmluY2x1c2l2ZSA/IHBheWxvYWQudmFsdWUgPj0gZGVmLnZhbHVlIDogcGF5bG9hZC52YWx1ZSA+IGRlZi52YWx1ZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgb3JpZ2luLFxuICAgICAgICAgICAgY29kZTogXCJ0b29fc21hbGxcIixcbiAgICAgICAgICAgIG1pbmltdW06IGRlZi52YWx1ZSxcbiAgICAgICAgICAgIGlucHV0OiBwYXlsb2FkLnZhbHVlLFxuICAgICAgICAgICAgaW5jbHVzaXZlOiBkZWYuaW5jbHVzaXZlLFxuICAgICAgICAgICAgaW5zdCxcbiAgICAgICAgICAgIGNvbnRpbnVlOiAhZGVmLmFib3J0XG4gICAgICAgIH0pO1xuICAgIH07XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kQ2hlY2tNdWx0aXBsZU9mID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RDaGVja011bHRpcGxlT2ZcIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kQ2hlY2suaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5vbmF0dGFjaC5wdXNoKChpbnN0KT0+e1xuICAgICAgICB2YXIgX2E7XG4gICAgICAgIChfYSA9IGluc3QuX3pvZC5iYWcpLm11bHRpcGxlT2YgPz8gKF9hLm11bHRpcGxlT2YgPSBkZWYudmFsdWUpO1xuICAgIH0pO1xuICAgIGluc3QuX3pvZC5jaGVjayA9IChwYXlsb2FkKT0+e1xuICAgICAgICBpZiAodHlwZW9mIHBheWxvYWQudmFsdWUgIT09IHR5cGVvZiBkZWYudmFsdWUpIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBtaXggbnVtYmVyIGFuZCBiaWdpbnQgaW4gbXVsdGlwbGVfb2YgY2hlY2suXCIpO1xuICAgICAgICBjb25zdCBpc011bHRpcGxlID0gdHlwZW9mIHBheWxvYWQudmFsdWUgPT09IFwiYmlnaW50XCIgPyBwYXlsb2FkLnZhbHVlICUgZGVmLnZhbHVlID09PSBCaWdJbnQoMCkgOiB1dGlsLmZsb2F0U2FmZVJlbWFpbmRlcihwYXlsb2FkLnZhbHVlLCBkZWYudmFsdWUpID09PSAwO1xuICAgICAgICBpZiAoaXNNdWx0aXBsZSkgcmV0dXJuO1xuICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICAgIG9yaWdpbjogdHlwZW9mIHBheWxvYWQudmFsdWUsXG4gICAgICAgICAgICBjb2RlOiBcIm5vdF9tdWx0aXBsZV9vZlwiLFxuICAgICAgICAgICAgZGl2aXNvcjogZGVmLnZhbHVlLFxuICAgICAgICAgICAgaW5wdXQ6IHBheWxvYWQudmFsdWUsXG4gICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgfSk7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RDaGVja051bWJlckZvcm1hdCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kQ2hlY2tOdW1iZXJGb3JtYXRcIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kQ2hlY2suaW5pdChpbnN0LCBkZWYpOyAvLyBubyBmb3JtYXQgY2hlY2tzXG4gICAgZGVmLmZvcm1hdCA9IGRlZi5mb3JtYXQgfHwgXCJmbG9hdDY0XCI7XG4gICAgY29uc3QgaXNJbnQgPSBkZWYuZm9ybWF0Py5pbmNsdWRlcyhcImludFwiKTtcbiAgICBjb25zdCBvcmlnaW4gPSBpc0ludCA/IFwiaW50XCIgOiBcIm51bWJlclwiO1xuICAgIGNvbnN0IFttaW5pbXVtLCBtYXhpbXVtXSA9IHV0aWwuTlVNQkVSX0ZPUk1BVF9SQU5HRVNbZGVmLmZvcm1hdF07XG4gICAgaW5zdC5fem9kLm9uYXR0YWNoLnB1c2goKGluc3QpPT57XG4gICAgICAgIGNvbnN0IGJhZyA9IGluc3QuX3pvZC5iYWc7XG4gICAgICAgIGJhZy5mb3JtYXQgPSBkZWYuZm9ybWF0O1xuICAgICAgICBiYWcubWluaW11bSA9IG1pbmltdW07XG4gICAgICAgIGJhZy5tYXhpbXVtID0gbWF4aW11bTtcbiAgICAgICAgaWYgKGlzSW50KSBiYWcucGF0dGVybiA9IHJlZ2V4ZXMuaW50ZWdlcjtcbiAgICB9KTtcbiAgICBpbnN0Ll96b2QuY2hlY2sgPSAocGF5bG9hZCk9PntcbiAgICAgICAgY29uc3QgaW5wdXQgPSBwYXlsb2FkLnZhbHVlO1xuICAgICAgICBpZiAoaXNJbnQpIHtcbiAgICAgICAgICAgIGlmICghTnVtYmVyLmlzSW50ZWdlcihpbnB1dCkpIHtcbiAgICAgICAgICAgICAgICAvLyBpbnZhbGlkX2Zvcm1hdCBpc3N1ZVxuICAgICAgICAgICAgICAgIC8vIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgICAgIC8vICAgZXhwZWN0ZWQ6IGRlZi5mb3JtYXQsXG4gICAgICAgICAgICAgICAgLy8gICBmb3JtYXQ6IGRlZi5mb3JtYXQsXG4gICAgICAgICAgICAgICAgLy8gICBjb2RlOiBcImludmFsaWRfZm9ybWF0XCIsXG4gICAgICAgICAgICAgICAgLy8gICBpbnB1dCxcbiAgICAgICAgICAgICAgICAvLyAgIGluc3QsXG4gICAgICAgICAgICAgICAgLy8gfSk7XG4gICAgICAgICAgICAgICAgLy8gaW52YWxpZF90eXBlIGlzc3VlXG4gICAgICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBvcmlnaW4sXG4gICAgICAgICAgICAgICAgICAgIGZvcm1hdDogZGVmLmZvcm1hdCxcbiAgICAgICAgICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX3R5cGVcIixcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBpbnB1dCxcbiAgICAgICAgICAgICAgICAgICAgaW5zdFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIC8vIG5vdF9tdWx0aXBsZV9vZiBpc3N1ZVxuICAgICAgICAgICAgLy8gcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAvLyAgIGNvZGU6IFwibm90X211bHRpcGxlX29mXCIsXG4gICAgICAgICAgICAvLyAgIG9yaWdpbjogXCJudW1iZXJcIixcbiAgICAgICAgICAgIC8vICAgaW5wdXQsXG4gICAgICAgICAgICAvLyAgIGluc3QsXG4gICAgICAgICAgICAvLyAgIGRpdmlzb3I6IDEsXG4gICAgICAgICAgICAvLyB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghTnVtYmVyLmlzU2FmZUludGVnZXIoaW5wdXQpKSB7XG4gICAgICAgICAgICAgICAgaWYgKGlucHV0ID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAvLyB0b29fYmlnXG4gICAgICAgICAgICAgICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBcInRvb19iaWdcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIG1heGltdW06IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSLFxuICAgICAgICAgICAgICAgICAgICAgICAgbm90ZTogXCJJbnRlZ2VycyBtdXN0IGJlIHdpdGhpbiB0aGUgc2FmZSBpbnRlZ2VyIHJhbmdlLlwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgaW5zdCxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbixcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOiAhZGVmLmFib3J0XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHRvb19zbWFsbFxuICAgICAgICAgICAgICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogXCJ0b29fc21hbGxcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIG1pbmltdW06IE51bWJlci5NSU5fU0FGRV9JTlRFR0VSLFxuICAgICAgICAgICAgICAgICAgICAgICAgbm90ZTogXCJJbnRlZ2VycyBtdXN0IGJlIHdpdGhpbiB0aGUgc2FmZSBpbnRlZ2VyIHJhbmdlLlwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgaW5zdCxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbixcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOiAhZGVmLmFib3J0XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlucHV0IDwgbWluaW11bSkge1xuICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgb3JpZ2luOiBcIm51bWJlclwiLFxuICAgICAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgICAgIGNvZGU6IFwidG9vX3NtYWxsXCIsXG4gICAgICAgICAgICAgICAgbWluaW11bSxcbiAgICAgICAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsXG4gICAgICAgICAgICAgICAgaW5zdCxcbiAgICAgICAgICAgICAgICBjb250aW51ZTogIWRlZi5hYm9ydFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlucHV0ID4gbWF4aW11bSkge1xuICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgb3JpZ2luOiBcIm51bWJlclwiLFxuICAgICAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgICAgIGNvZGU6IFwidG9vX2JpZ1wiLFxuICAgICAgICAgICAgICAgIG1heGltdW0sXG4gICAgICAgICAgICAgICAgaW5zdFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZENoZWNrQmlnSW50Rm9ybWF0ID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RDaGVja0JpZ0ludEZvcm1hdFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RDaGVjay5pbml0KGluc3QsIGRlZik7IC8vIG5vIGZvcm1hdCBjaGVja3NcbiAgICBjb25zdCBbbWluaW11bSwgbWF4aW11bV0gPSB1dGlsLkJJR0lOVF9GT1JNQVRfUkFOR0VTW2RlZi5mb3JtYXRdO1xuICAgIGluc3QuX3pvZC5vbmF0dGFjaC5wdXNoKChpbnN0KT0+e1xuICAgICAgICBjb25zdCBiYWcgPSBpbnN0Ll96b2QuYmFnO1xuICAgICAgICBiYWcuZm9ybWF0ID0gZGVmLmZvcm1hdDtcbiAgICAgICAgYmFnLm1pbmltdW0gPSBtaW5pbXVtO1xuICAgICAgICBiYWcubWF4aW11bSA9IG1heGltdW07XG4gICAgfSk7XG4gICAgaW5zdC5fem9kLmNoZWNrID0gKHBheWxvYWQpPT57XG4gICAgICAgIGNvbnN0IGlucHV0ID0gcGF5bG9hZC52YWx1ZTtcbiAgICAgICAgaWYgKGlucHV0IDwgbWluaW11bSkge1xuICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgb3JpZ2luOiBcImJpZ2ludFwiLFxuICAgICAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgICAgIGNvZGU6IFwidG9vX3NtYWxsXCIsXG4gICAgICAgICAgICAgICAgbWluaW11bTogbWluaW11bSxcbiAgICAgICAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsXG4gICAgICAgICAgICAgICAgaW5zdCxcbiAgICAgICAgICAgICAgICBjb250aW51ZTogIWRlZi5hYm9ydFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlucHV0ID4gbWF4aW11bSkge1xuICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgb3JpZ2luOiBcImJpZ2ludFwiLFxuICAgICAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgICAgIGNvZGU6IFwidG9vX2JpZ1wiLFxuICAgICAgICAgICAgICAgIG1heGltdW0sXG4gICAgICAgICAgICAgICAgaW5zdFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZENoZWNrTWF4U2l6ZSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kQ2hlY2tNYXhTaXplXCIsIChpbnN0LCBkZWYpPT57XG4gICAgdmFyIF9hO1xuICAgICRab2RDaGVjay5pbml0KGluc3QsIGRlZik7XG4gICAgKF9hID0gaW5zdC5fem9kLmRlZikud2hlbiA/PyAoX2Eud2hlbiA9IChwYXlsb2FkKT0+e1xuICAgICAgICBjb25zdCB2YWwgPSBwYXlsb2FkLnZhbHVlO1xuICAgICAgICByZXR1cm4gIXV0aWwubnVsbGlzaCh2YWwpICYmIHZhbC5zaXplICE9PSB1bmRlZmluZWQ7XG4gICAgfSk7XG4gICAgaW5zdC5fem9kLm9uYXR0YWNoLnB1c2goKGluc3QpPT57XG4gICAgICAgIGNvbnN0IGN1cnIgPSBpbnN0Ll96b2QuYmFnLm1heGltdW0gPz8gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZO1xuICAgICAgICBpZiAoZGVmLm1heGltdW0gPCBjdXJyKSBpbnN0Ll96b2QuYmFnLm1heGltdW0gPSBkZWYubWF4aW11bTtcbiAgICB9KTtcbiAgICBpbnN0Ll96b2QuY2hlY2sgPSAocGF5bG9hZCk9PntcbiAgICAgICAgY29uc3QgaW5wdXQgPSBwYXlsb2FkLnZhbHVlO1xuICAgICAgICBjb25zdCBzaXplID0gaW5wdXQuc2l6ZTtcbiAgICAgICAgaWYgKHNpemUgPD0gZGVmLm1heGltdW0pIHJldHVybjtcbiAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICBvcmlnaW46IHV0aWwuZ2V0U2l6YWJsZU9yaWdpbihpbnB1dCksXG4gICAgICAgICAgICBjb2RlOiBcInRvb19iaWdcIixcbiAgICAgICAgICAgIG1heGltdW06IGRlZi5tYXhpbXVtLFxuICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgfSk7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RDaGVja01pblNpemUgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZENoZWNrTWluU2l6ZVwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIHZhciBfYTtcbiAgICAkWm9kQ2hlY2suaW5pdChpbnN0LCBkZWYpO1xuICAgIChfYSA9IGluc3QuX3pvZC5kZWYpLndoZW4gPz8gKF9hLndoZW4gPSAocGF5bG9hZCk9PntcbiAgICAgICAgY29uc3QgdmFsID0gcGF5bG9hZC52YWx1ZTtcbiAgICAgICAgcmV0dXJuICF1dGlsLm51bGxpc2godmFsKSAmJiB2YWwuc2l6ZSAhPT0gdW5kZWZpbmVkO1xuICAgIH0pO1xuICAgIGluc3QuX3pvZC5vbmF0dGFjaC5wdXNoKChpbnN0KT0+e1xuICAgICAgICBjb25zdCBjdXJyID0gaW5zdC5fem9kLmJhZy5taW5pbXVtID8/IE51bWJlci5ORUdBVElWRV9JTkZJTklUWTtcbiAgICAgICAgaWYgKGRlZi5taW5pbXVtID4gY3VycikgaW5zdC5fem9kLmJhZy5taW5pbXVtID0gZGVmLm1pbmltdW07XG4gICAgfSk7XG4gICAgaW5zdC5fem9kLmNoZWNrID0gKHBheWxvYWQpPT57XG4gICAgICAgIGNvbnN0IGlucHV0ID0gcGF5bG9hZC52YWx1ZTtcbiAgICAgICAgY29uc3Qgc2l6ZSA9IGlucHV0LnNpemU7XG4gICAgICAgIGlmIChzaXplID49IGRlZi5taW5pbXVtKSByZXR1cm47XG4gICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgb3JpZ2luOiB1dGlsLmdldFNpemFibGVPcmlnaW4oaW5wdXQpLFxuICAgICAgICAgICAgY29kZTogXCJ0b29fc21hbGxcIixcbiAgICAgICAgICAgIG1pbmltdW06IGRlZi5taW5pbXVtLFxuICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgfSk7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RDaGVja1NpemVFcXVhbHMgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZENoZWNrU2l6ZUVxdWFsc1wiLCAoaW5zdCwgZGVmKT0+e1xuICAgIHZhciBfYTtcbiAgICAkWm9kQ2hlY2suaW5pdChpbnN0LCBkZWYpO1xuICAgIChfYSA9IGluc3QuX3pvZC5kZWYpLndoZW4gPz8gKF9hLndoZW4gPSAocGF5bG9hZCk9PntcbiAgICAgICAgY29uc3QgdmFsID0gcGF5bG9hZC52YWx1ZTtcbiAgICAgICAgcmV0dXJuICF1dGlsLm51bGxpc2godmFsKSAmJiB2YWwuc2l6ZSAhPT0gdW5kZWZpbmVkO1xuICAgIH0pO1xuICAgIGluc3QuX3pvZC5vbmF0dGFjaC5wdXNoKChpbnN0KT0+e1xuICAgICAgICBjb25zdCBiYWcgPSBpbnN0Ll96b2QuYmFnO1xuICAgICAgICBiYWcubWluaW11bSA9IGRlZi5zaXplO1xuICAgICAgICBiYWcubWF4aW11bSA9IGRlZi5zaXplO1xuICAgICAgICBiYWcuc2l6ZSA9IGRlZi5zaXplO1xuICAgIH0pO1xuICAgIGluc3QuX3pvZC5jaGVjayA9IChwYXlsb2FkKT0+e1xuICAgICAgICBjb25zdCBpbnB1dCA9IHBheWxvYWQudmFsdWU7XG4gICAgICAgIGNvbnN0IHNpemUgPSBpbnB1dC5zaXplO1xuICAgICAgICBpZiAoc2l6ZSA9PT0gZGVmLnNpemUpIHJldHVybjtcbiAgICAgICAgY29uc3QgdG9vQmlnID0gc2l6ZSA+IGRlZi5zaXplO1xuICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICAgIG9yaWdpbjogdXRpbC5nZXRTaXphYmxlT3JpZ2luKGlucHV0KSxcbiAgICAgICAgICAgIC4uLnRvb0JpZyA/IHtcbiAgICAgICAgICAgICAgICBjb2RlOiBcInRvb19iaWdcIixcbiAgICAgICAgICAgICAgICBtYXhpbXVtOiBkZWYuc2l6ZVxuICAgICAgICAgICAgfSA6IHtcbiAgICAgICAgICAgICAgICBjb2RlOiBcInRvb19zbWFsbFwiLFxuICAgICAgICAgICAgICAgIG1pbmltdW06IGRlZi5zaXplXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgZXhhY3Q6IHRydWUsXG4gICAgICAgICAgICBpbnB1dDogcGF5bG9hZC52YWx1ZSxcbiAgICAgICAgICAgIGluc3QsXG4gICAgICAgICAgICBjb250aW51ZTogIWRlZi5hYm9ydFxuICAgICAgICB9KTtcbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZENoZWNrTWF4TGVuZ3RoID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RDaGVja01heExlbmd0aFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIHZhciBfYTtcbiAgICAkWm9kQ2hlY2suaW5pdChpbnN0LCBkZWYpO1xuICAgIChfYSA9IGluc3QuX3pvZC5kZWYpLndoZW4gPz8gKF9hLndoZW4gPSAocGF5bG9hZCk9PntcbiAgICAgICAgY29uc3QgdmFsID0gcGF5bG9hZC52YWx1ZTtcbiAgICAgICAgcmV0dXJuICF1dGlsLm51bGxpc2godmFsKSAmJiB2YWwubGVuZ3RoICE9PSB1bmRlZmluZWQ7XG4gICAgfSk7XG4gICAgaW5zdC5fem9kLm9uYXR0YWNoLnB1c2goKGluc3QpPT57XG4gICAgICAgIGNvbnN0IGN1cnIgPSBpbnN0Ll96b2QuYmFnLm1heGltdW0gPz8gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZO1xuICAgICAgICBpZiAoZGVmLm1heGltdW0gPCBjdXJyKSBpbnN0Ll96b2QuYmFnLm1heGltdW0gPSBkZWYubWF4aW11bTtcbiAgICB9KTtcbiAgICBpbnN0Ll96b2QuY2hlY2sgPSAocGF5bG9hZCk9PntcbiAgICAgICAgY29uc3QgaW5wdXQgPSBwYXlsb2FkLnZhbHVlO1xuICAgICAgICBjb25zdCBsZW5ndGggPSBpbnB1dC5sZW5ndGg7XG4gICAgICAgIGlmIChsZW5ndGggPD0gZGVmLm1heGltdW0pIHJldHVybjtcbiAgICAgICAgY29uc3Qgb3JpZ2luID0gdXRpbC5nZXRMZW5ndGhhYmxlT3JpZ2luKGlucHV0KTtcbiAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICBvcmlnaW4sXG4gICAgICAgICAgICBjb2RlOiBcInRvb19iaWdcIixcbiAgICAgICAgICAgIG1heGltdW06IGRlZi5tYXhpbXVtLFxuICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgfSk7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RDaGVja01pbkxlbmd0aCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kQ2hlY2tNaW5MZW5ndGhcIiwgKGluc3QsIGRlZik9PntcbiAgICB2YXIgX2E7XG4gICAgJFpvZENoZWNrLmluaXQoaW5zdCwgZGVmKTtcbiAgICAoX2EgPSBpbnN0Ll96b2QuZGVmKS53aGVuID8/IChfYS53aGVuID0gKHBheWxvYWQpPT57XG4gICAgICAgIGNvbnN0IHZhbCA9IHBheWxvYWQudmFsdWU7XG4gICAgICAgIHJldHVybiAhdXRpbC5udWxsaXNoKHZhbCkgJiYgdmFsLmxlbmd0aCAhPT0gdW5kZWZpbmVkO1xuICAgIH0pO1xuICAgIGluc3QuX3pvZC5vbmF0dGFjaC5wdXNoKChpbnN0KT0+e1xuICAgICAgICBjb25zdCBjdXJyID0gaW5zdC5fem9kLmJhZy5taW5pbXVtID8/IE51bWJlci5ORUdBVElWRV9JTkZJTklUWTtcbiAgICAgICAgaWYgKGRlZi5taW5pbXVtID4gY3VycikgaW5zdC5fem9kLmJhZy5taW5pbXVtID0gZGVmLm1pbmltdW07XG4gICAgfSk7XG4gICAgaW5zdC5fem9kLmNoZWNrID0gKHBheWxvYWQpPT57XG4gICAgICAgIGNvbnN0IGlucHV0ID0gcGF5bG9hZC52YWx1ZTtcbiAgICAgICAgY29uc3QgbGVuZ3RoID0gaW5wdXQubGVuZ3RoO1xuICAgICAgICBpZiAobGVuZ3RoID49IGRlZi5taW5pbXVtKSByZXR1cm47XG4gICAgICAgIGNvbnN0IG9yaWdpbiA9IHV0aWwuZ2V0TGVuZ3RoYWJsZU9yaWdpbihpbnB1dCk7XG4gICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgb3JpZ2luLFxuICAgICAgICAgICAgY29kZTogXCJ0b29fc21hbGxcIixcbiAgICAgICAgICAgIG1pbmltdW06IGRlZi5taW5pbXVtLFxuICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgfSk7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RDaGVja0xlbmd0aEVxdWFscyA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kQ2hlY2tMZW5ndGhFcXVhbHNcIiwgKGluc3QsIGRlZik9PntcbiAgICB2YXIgX2E7XG4gICAgJFpvZENoZWNrLmluaXQoaW5zdCwgZGVmKTtcbiAgICAoX2EgPSBpbnN0Ll96b2QuZGVmKS53aGVuID8/IChfYS53aGVuID0gKHBheWxvYWQpPT57XG4gICAgICAgIGNvbnN0IHZhbCA9IHBheWxvYWQudmFsdWU7XG4gICAgICAgIHJldHVybiAhdXRpbC5udWxsaXNoKHZhbCkgJiYgdmFsLmxlbmd0aCAhPT0gdW5kZWZpbmVkO1xuICAgIH0pO1xuICAgIGluc3QuX3pvZC5vbmF0dGFjaC5wdXNoKChpbnN0KT0+e1xuICAgICAgICBjb25zdCBiYWcgPSBpbnN0Ll96b2QuYmFnO1xuICAgICAgICBiYWcubWluaW11bSA9IGRlZi5sZW5ndGg7XG4gICAgICAgIGJhZy5tYXhpbXVtID0gZGVmLmxlbmd0aDtcbiAgICAgICAgYmFnLmxlbmd0aCA9IGRlZi5sZW5ndGg7XG4gICAgfSk7XG4gICAgaW5zdC5fem9kLmNoZWNrID0gKHBheWxvYWQpPT57XG4gICAgICAgIGNvbnN0IGlucHV0ID0gcGF5bG9hZC52YWx1ZTtcbiAgICAgICAgY29uc3QgbGVuZ3RoID0gaW5wdXQubGVuZ3RoO1xuICAgICAgICBpZiAobGVuZ3RoID09PSBkZWYubGVuZ3RoKSByZXR1cm47XG4gICAgICAgIGNvbnN0IG9yaWdpbiA9IHV0aWwuZ2V0TGVuZ3RoYWJsZU9yaWdpbihpbnB1dCk7XG4gICAgICAgIGNvbnN0IHRvb0JpZyA9IGxlbmd0aCA+IGRlZi5sZW5ndGg7XG4gICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgb3JpZ2luLFxuICAgICAgICAgICAgLi4udG9vQmlnID8ge1xuICAgICAgICAgICAgICAgIGNvZGU6IFwidG9vX2JpZ1wiLFxuICAgICAgICAgICAgICAgIG1heGltdW06IGRlZi5sZW5ndGhcbiAgICAgICAgICAgIH0gOiB7XG4gICAgICAgICAgICAgICAgY29kZTogXCJ0b29fc21hbGxcIixcbiAgICAgICAgICAgICAgICBtaW5pbXVtOiBkZWYubGVuZ3RoXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgZXhhY3Q6IHRydWUsXG4gICAgICAgICAgICBpbnB1dDogcGF5bG9hZC52YWx1ZSxcbiAgICAgICAgICAgIGluc3QsXG4gICAgICAgICAgICBjb250aW51ZTogIWRlZi5hYm9ydFxuICAgICAgICB9KTtcbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZENoZWNrU3RyaW5nRm9ybWF0ID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RDaGVja1N0cmluZ0Zvcm1hdFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIHZhciBfYSwgX2I7XG4gICAgJFpvZENoZWNrLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0Ll96b2Qub25hdHRhY2gucHVzaCgoaW5zdCk9PntcbiAgICAgICAgY29uc3QgYmFnID0gaW5zdC5fem9kLmJhZztcbiAgICAgICAgYmFnLmZvcm1hdCA9IGRlZi5mb3JtYXQ7XG4gICAgICAgIGlmIChkZWYucGF0dGVybikge1xuICAgICAgICAgICAgYmFnLnBhdHRlcm5zID8/IChiYWcucGF0dGVybnMgPSBuZXcgU2V0KCkpO1xuICAgICAgICAgICAgYmFnLnBhdHRlcm5zLmFkZChkZWYucGF0dGVybik7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICBpZiAoZGVmLnBhdHRlcm4pIChfYSA9IGluc3QuX3pvZCkuY2hlY2sgPz8gKF9hLmNoZWNrID0gKHBheWxvYWQpPT57XG4gICAgICAgIGRlZi5wYXR0ZXJuLmxhc3RJbmRleCA9IDA7XG4gICAgICAgIGlmIChkZWYucGF0dGVybi50ZXN0KHBheWxvYWQudmFsdWUpKSByZXR1cm47XG4gICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgb3JpZ2luOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX2Zvcm1hdFwiLFxuICAgICAgICAgICAgZm9ybWF0OiBkZWYuZm9ybWF0LFxuICAgICAgICAgICAgaW5wdXQ6IHBheWxvYWQudmFsdWUsXG4gICAgICAgICAgICAuLi5kZWYucGF0dGVybiA/IHtcbiAgICAgICAgICAgICAgICBwYXR0ZXJuOiBkZWYucGF0dGVybi50b1N0cmluZygpXG4gICAgICAgICAgICB9IDoge30sXG4gICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gICAgZWxzZSAoX2IgPSBpbnN0Ll96b2QpLmNoZWNrID8/IChfYi5jaGVjayA9ICgpPT57fSk7XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kQ2hlY2tSZWdleCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kQ2hlY2tSZWdleFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RDaGVja1N0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5fem9kLmNoZWNrID0gKHBheWxvYWQpPT57XG4gICAgICAgIGRlZi5wYXR0ZXJuLmxhc3RJbmRleCA9IDA7XG4gICAgICAgIGlmIChkZWYucGF0dGVybi50ZXN0KHBheWxvYWQudmFsdWUpKSByZXR1cm47XG4gICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgb3JpZ2luOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX2Zvcm1hdFwiLFxuICAgICAgICAgICAgZm9ybWF0OiBcInJlZ2V4XCIsXG4gICAgICAgICAgICBpbnB1dDogcGF5bG9hZC52YWx1ZSxcbiAgICAgICAgICAgIHBhdHRlcm46IGRlZi5wYXR0ZXJuLnRvU3RyaW5nKCksXG4gICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgfSk7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RDaGVja0xvd2VyQ2FzZSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kQ2hlY2tMb3dlckNhc2VcIiwgKGluc3QsIGRlZik9PntcbiAgICBkZWYucGF0dGVybiA/PyAoZGVmLnBhdHRlcm4gPSByZWdleGVzLmxvd2VyY2FzZSk7XG4gICAgJFpvZENoZWNrU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RDaGVja1VwcGVyQ2FzZSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kQ2hlY2tVcHBlckNhc2VcIiwgKGluc3QsIGRlZik9PntcbiAgICBkZWYucGF0dGVybiA/PyAoZGVmLnBhdHRlcm4gPSByZWdleGVzLnVwcGVyY2FzZSk7XG4gICAgJFpvZENoZWNrU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RDaGVja0luY2x1ZGVzID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RDaGVja0luY2x1ZGVzXCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZENoZWNrLmluaXQoaW5zdCwgZGVmKTtcbiAgICBjb25zdCBlc2NhcGVkUmVnZXggPSB1dGlsLmVzY2FwZVJlZ2V4KGRlZi5pbmNsdWRlcyk7XG4gICAgY29uc3QgcGF0dGVybiA9IG5ldyBSZWdFeHAodHlwZW9mIGRlZi5wb3NpdGlvbiA9PT0gXCJudW1iZXJcIiA/IGBeLnske2RlZi5wb3NpdGlvbn19JHtlc2NhcGVkUmVnZXh9YCA6IGVzY2FwZWRSZWdleCk7XG4gICAgZGVmLnBhdHRlcm4gPSBwYXR0ZXJuO1xuICAgIGluc3QuX3pvZC5vbmF0dGFjaC5wdXNoKChpbnN0KT0+e1xuICAgICAgICBjb25zdCBiYWcgPSBpbnN0Ll96b2QuYmFnO1xuICAgICAgICBiYWcucGF0dGVybnMgPz8gKGJhZy5wYXR0ZXJucyA9IG5ldyBTZXQoKSk7XG4gICAgICAgIGJhZy5wYXR0ZXJucy5hZGQocGF0dGVybik7XG4gICAgfSk7XG4gICAgaW5zdC5fem9kLmNoZWNrID0gKHBheWxvYWQpPT57XG4gICAgICAgIGlmIChwYXlsb2FkLnZhbHVlLmluY2x1ZGVzKGRlZi5pbmNsdWRlcywgZGVmLnBvc2l0aW9uKSkgcmV0dXJuO1xuICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICAgIG9yaWdpbjogXCJzdHJpbmdcIixcbiAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF9mb3JtYXRcIixcbiAgICAgICAgICAgIGZvcm1hdDogXCJpbmNsdWRlc1wiLFxuICAgICAgICAgICAgaW5jbHVkZXM6IGRlZi5pbmNsdWRlcyxcbiAgICAgICAgICAgIGlucHV0OiBwYXlsb2FkLnZhbHVlLFxuICAgICAgICAgICAgaW5zdCxcbiAgICAgICAgICAgIGNvbnRpbnVlOiAhZGVmLmFib3J0XG4gICAgICAgIH0pO1xuICAgIH07XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kQ2hlY2tTdGFydHNXaXRoID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RDaGVja1N0YXJ0c1dpdGhcIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kQ2hlY2suaW5pdChpbnN0LCBkZWYpO1xuICAgIGNvbnN0IHBhdHRlcm4gPSBuZXcgUmVnRXhwKGBeJHt1dGlsLmVzY2FwZVJlZ2V4KGRlZi5wcmVmaXgpfS4qYCk7XG4gICAgZGVmLnBhdHRlcm4gPz8gKGRlZi5wYXR0ZXJuID0gcGF0dGVybik7XG4gICAgaW5zdC5fem9kLm9uYXR0YWNoLnB1c2goKGluc3QpPT57XG4gICAgICAgIGNvbnN0IGJhZyA9IGluc3QuX3pvZC5iYWc7XG4gICAgICAgIGJhZy5wYXR0ZXJucyA/PyAoYmFnLnBhdHRlcm5zID0gbmV3IFNldCgpKTtcbiAgICAgICAgYmFnLnBhdHRlcm5zLmFkZChwYXR0ZXJuKTtcbiAgICB9KTtcbiAgICBpbnN0Ll96b2QuY2hlY2sgPSAocGF5bG9hZCk9PntcbiAgICAgICAgaWYgKHBheWxvYWQudmFsdWUuc3RhcnRzV2l0aChkZWYucHJlZml4KSkgcmV0dXJuO1xuICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICAgIG9yaWdpbjogXCJzdHJpbmdcIixcbiAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF9mb3JtYXRcIixcbiAgICAgICAgICAgIGZvcm1hdDogXCJzdGFydHNfd2l0aFwiLFxuICAgICAgICAgICAgcHJlZml4OiBkZWYucHJlZml4LFxuICAgICAgICAgICAgaW5wdXQ6IHBheWxvYWQudmFsdWUsXG4gICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgfSk7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RDaGVja0VuZHNXaXRoID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RDaGVja0VuZHNXaXRoXCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZENoZWNrLmluaXQoaW5zdCwgZGVmKTtcbiAgICBjb25zdCBwYXR0ZXJuID0gbmV3IFJlZ0V4cChgLioke3V0aWwuZXNjYXBlUmVnZXgoZGVmLnN1ZmZpeCl9JGApO1xuICAgIGRlZi5wYXR0ZXJuID8/IChkZWYucGF0dGVybiA9IHBhdHRlcm4pO1xuICAgIGluc3QuX3pvZC5vbmF0dGFjaC5wdXNoKChpbnN0KT0+e1xuICAgICAgICBjb25zdCBiYWcgPSBpbnN0Ll96b2QuYmFnO1xuICAgICAgICBiYWcucGF0dGVybnMgPz8gKGJhZy5wYXR0ZXJucyA9IG5ldyBTZXQoKSk7XG4gICAgICAgIGJhZy5wYXR0ZXJucy5hZGQocGF0dGVybik7XG4gICAgfSk7XG4gICAgaW5zdC5fem9kLmNoZWNrID0gKHBheWxvYWQpPT57XG4gICAgICAgIGlmIChwYXlsb2FkLnZhbHVlLmVuZHNXaXRoKGRlZi5zdWZmaXgpKSByZXR1cm47XG4gICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgb3JpZ2luOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX2Zvcm1hdFwiLFxuICAgICAgICAgICAgZm9ybWF0OiBcImVuZHNfd2l0aFwiLFxuICAgICAgICAgICAgc3VmZml4OiBkZWYuc3VmZml4LFxuICAgICAgICAgICAgaW5wdXQ6IHBheWxvYWQudmFsdWUsXG4gICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgfSk7XG4gICAgfTtcbn0pO1xuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vLy8vICAgICRab2RDaGVja1Byb3BlcnR5ICAgIC8vLy8vXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuZnVuY3Rpb24gaGFuZGxlQ2hlY2tQcm9wZXJ0eVJlc3VsdChyZXN1bHQsIHBheWxvYWQsIHByb3BlcnR5KSB7XG4gICAgaWYgKHJlc3VsdC5pc3N1ZXMubGVuZ3RoKSB7XG4gICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goLi4udXRpbC5wcmVmaXhJc3N1ZXMocHJvcGVydHksIHJlc3VsdC5pc3N1ZXMpKTtcbiAgICB9XG59XG5leHBvcnQgY29uc3QgJFpvZENoZWNrUHJvcGVydHkgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZENoZWNrUHJvcGVydHlcIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kQ2hlY2suaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5jaGVjayA9IChwYXlsb2FkKT0+e1xuICAgICAgICBjb25zdCByZXN1bHQgPSBkZWYuc2NoZW1hLl96b2QucnVuKHtcbiAgICAgICAgICAgIHZhbHVlOiBwYXlsb2FkLnZhbHVlW2RlZi5wcm9wZXJ0eV0sXG4gICAgICAgICAgICBpc3N1ZXM6IFtdXG4gICAgICAgIH0sIHt9KTtcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQudGhlbigocmVzdWx0KT0+aGFuZGxlQ2hlY2tQcm9wZXJ0eVJlc3VsdChyZXN1bHQsIHBheWxvYWQsIGRlZi5wcm9wZXJ0eSkpO1xuICAgICAgICB9XG4gICAgICAgIGhhbmRsZUNoZWNrUHJvcGVydHlSZXN1bHQocmVzdWx0LCBwYXlsb2FkLCBkZWYucHJvcGVydHkpO1xuICAgICAgICByZXR1cm47XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RDaGVja01pbWVUeXBlID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RDaGVja01pbWVUeXBlXCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZENoZWNrLmluaXQoaW5zdCwgZGVmKTtcbiAgICBjb25zdCBtaW1lU2V0ID0gbmV3IFNldChkZWYubWltZSk7XG4gICAgaW5zdC5fem9kLm9uYXR0YWNoLnB1c2goKGluc3QpPT57XG4gICAgICAgIGluc3QuX3pvZC5iYWcubWltZSA9IGRlZi5taW1lO1xuICAgIH0pO1xuICAgIGluc3QuX3pvZC5jaGVjayA9IChwYXlsb2FkKT0+e1xuICAgICAgICBpZiAobWltZVNldC5oYXMocGF5bG9hZC52YWx1ZS50eXBlKSkgcmV0dXJuO1xuICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF92YWx1ZVwiLFxuICAgICAgICAgICAgdmFsdWVzOiBkZWYubWltZSxcbiAgICAgICAgICAgIGlucHV0OiBwYXlsb2FkLnZhbHVlLnR5cGUsXG4gICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgfSk7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RDaGVja092ZXJ3cml0ZSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kQ2hlY2tPdmVyd3JpdGVcIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kQ2hlY2suaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5jaGVjayA9IChwYXlsb2FkKT0+e1xuICAgICAgICBwYXlsb2FkLnZhbHVlID0gZGVmLnR4KHBheWxvYWQudmFsdWUpO1xuICAgIH07XG59KTtcbiIsICJleHBvcnQgY2xhc3MgRG9jIHtcbiAgICBjb25zdHJ1Y3RvcihhcmdzID0gW10pe1xuICAgICAgICB0aGlzLmNvbnRlbnQgPSBbXTtcbiAgICAgICAgdGhpcy5pbmRlbnQgPSAwO1xuICAgICAgICBpZiAodGhpcykgdGhpcy5hcmdzID0gYXJncztcbiAgICB9XG4gICAgaW5kZW50ZWQoZm4pIHtcbiAgICAgICAgdGhpcy5pbmRlbnQgKz0gMTtcbiAgICAgICAgZm4odGhpcyk7XG4gICAgICAgIHRoaXMuaW5kZW50IC09IDE7XG4gICAgfVxuICAgIHdyaXRlKGFyZykge1xuICAgICAgICBpZiAodHlwZW9mIGFyZyA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICBhcmcodGhpcywge1xuICAgICAgICAgICAgICAgIGV4ZWN1dGlvbjogXCJzeW5jXCJcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgYXJnKHRoaXMsIHtcbiAgICAgICAgICAgICAgICBleGVjdXRpb246IFwiYXN5bmNcIlxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY29udGVudCA9IGFyZztcbiAgICAgICAgY29uc3QgbGluZXMgPSBjb250ZW50LnNwbGl0KFwiXFxuXCIpLmZpbHRlcigoeCk9PngpO1xuICAgICAgICBjb25zdCBtaW5JbmRlbnQgPSBNYXRoLm1pbiguLi5saW5lcy5tYXAoKHgpPT54Lmxlbmd0aCAtIHgudHJpbVN0YXJ0KCkubGVuZ3RoKSk7XG4gICAgICAgIGNvbnN0IGRlZGVudGVkID0gbGluZXMubWFwKCh4KT0+eC5zbGljZShtaW5JbmRlbnQpKS5tYXAoKHgpPT5cIiBcIi5yZXBlYXQodGhpcy5pbmRlbnQgKiAyKSArIHgpO1xuICAgICAgICBmb3IgKGNvbnN0IGxpbmUgb2YgZGVkZW50ZWQpe1xuICAgICAgICAgICAgdGhpcy5jb250ZW50LnB1c2gobGluZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY29tcGlsZSgpIHtcbiAgICAgICAgY29uc3QgRiA9IEZ1bmN0aW9uO1xuICAgICAgICBjb25zdCBhcmdzID0gdGhpcz8uYXJncztcbiAgICAgICAgY29uc3QgY29udGVudCA9IHRoaXM/LmNvbnRlbnQgPz8gW1xuICAgICAgICAgICAgYGBcbiAgICAgICAgXTtcbiAgICAgICAgY29uc3QgbGluZXMgPSBbXG4gICAgICAgICAgICAuLi5jb250ZW50Lm1hcCgoeCk9PmAgICR7eH1gKVxuICAgICAgICBdO1xuICAgICAgICAvLyBjb25zb2xlLmxvZyhsaW5lcy5qb2luKFwiXFxuXCIpKTtcbiAgICAgICAgcmV0dXJuIG5ldyBGKC4uLmFyZ3MsIGxpbmVzLmpvaW4oXCJcXG5cIikpO1xuICAgIH1cbn1cbiIsICJleHBvcnQgY29uc3QgdmVyc2lvbiA9IHtcbiAgICBtYWpvcjogNCxcbiAgICBtaW5vcjogMSxcbiAgICBwYXRjaDogMTFcbn07XG4iLCAiaW1wb3J0ICogYXMgY2hlY2tzIGZyb20gXCIuL2NoZWNrcy5qc1wiO1xuaW1wb3J0ICogYXMgY29yZSBmcm9tIFwiLi9jb3JlLmpzXCI7XG5pbXBvcnQgeyBEb2MgfSBmcm9tIFwiLi9kb2MuanNcIjtcbmltcG9ydCB7IHBhcnNlLCBwYXJzZUFzeW5jLCBzYWZlUGFyc2UsIHNhZmVQYXJzZUFzeW5jIH0gZnJvbSBcIi4vcGFyc2UuanNcIjtcbmltcG9ydCAqIGFzIHJlZ2V4ZXMgZnJvbSBcIi4vcmVnZXhlcy5qc1wiO1xuaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi91dGlsLmpzXCI7XG5pbXBvcnQgeyB2ZXJzaW9uIH0gZnJvbSBcIi4vdmVyc2lvbnMuanNcIjtcbmV4cG9ydCBjb25zdCAkWm9kVHlwZSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kVHlwZVwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIHZhciBfYTtcbiAgICBpbnN0ID8/IChpbnN0ID0ge30pO1xuICAgIGluc3QuX3pvZC5kZWYgPSBkZWY7IC8vIHNldCBfZGVmIHByb3BlcnR5XG4gICAgaW5zdC5fem9kLmJhZyA9IGluc3QuX3pvZC5iYWcgfHwge307IC8vIGluaXRpYWxpemUgX2JhZyBvYmplY3RcbiAgICBpbnN0Ll96b2QudmVyc2lvbiA9IHZlcnNpb247XG4gICAgY29uc3QgY2hlY2tzID0gW1xuICAgICAgICAuLi5pbnN0Ll96b2QuZGVmLmNoZWNrcyA/PyBbXVxuICAgIF07XG4gICAgLy8gaWYgaW5zdCBpcyBpdHNlbGYgYSBjaGVja3MuJFpvZENoZWNrLCBydW4gaXQgYXMgYSBjaGVja1xuICAgIGlmIChpbnN0Ll96b2QudHJhaXRzLmhhcyhcIiRab2RDaGVja1wiKSkge1xuICAgICAgICBjaGVja3MudW5zaGlmdChpbnN0KTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBjaCBvZiBjaGVja3Mpe1xuICAgICAgICBmb3IgKGNvbnN0IGZuIG9mIGNoLl96b2Qub25hdHRhY2gpe1xuICAgICAgICAgICAgZm4oaW5zdCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKGNoZWNrcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgLy8gZGVmZXJyZWQgaW5pdGlhbGl6ZXJcbiAgICAgICAgLy8gaW5zdC5fem9kLnBhcnNlIGlzIG5vdCB5ZXQgZGVmaW5lZFxuICAgICAgICAoX2EgPSBpbnN0Ll96b2QpLmRlZmVycmVkID8/IChfYS5kZWZlcnJlZCA9IFtdKTtcbiAgICAgICAgaW5zdC5fem9kLmRlZmVycmVkPy5wdXNoKCgpPT57XG4gICAgICAgICAgICBpbnN0Ll96b2QucnVuID0gaW5zdC5fem9kLnBhcnNlO1xuICAgICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBydW5DaGVja3MgPSAocGF5bG9hZCwgY2hlY2tzLCBjdHgpPT57XG4gICAgICAgICAgICBsZXQgaXNBYm9ydGVkID0gdXRpbC5hYm9ydGVkKHBheWxvYWQpO1xuICAgICAgICAgICAgbGV0IGFzeW5jUmVzdWx0O1xuICAgICAgICAgICAgZm9yIChjb25zdCBjaCBvZiBjaGVja3Mpe1xuICAgICAgICAgICAgICAgIGlmIChjaC5fem9kLmRlZi53aGVuKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNob3VsZFJ1biA9IGNoLl96b2QuZGVmLndoZW4ocGF5bG9hZCk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghc2hvdWxkUnVuKSBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGlzQWJvcnRlZCkge1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgY3VyckxlbiA9IHBheWxvYWQuaXNzdWVzLmxlbmd0aDtcbiAgICAgICAgICAgICAgICBjb25zdCBfID0gY2guX3pvZC5jaGVjayhwYXlsb2FkKTtcbiAgICAgICAgICAgICAgICBpZiAoXyBpbnN0YW5jZW9mIFByb21pc2UgJiYgY3R4Py5hc3luYyA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IGNvcmUuJFpvZEFzeW5jRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGFzeW5jUmVzdWx0IHx8IF8gaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICAgICAgICAgIGFzeW5jUmVzdWx0ID0gKGFzeW5jUmVzdWx0ID8/IFByb21pc2UucmVzb2x2ZSgpKS50aGVuKGFzeW5jICgpPT57XG4gICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCBfO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV4dExlbiA9IHBheWxvYWQuaXNzdWVzLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXh0TGVuID09PSBjdXJyTGVuKSByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlzQWJvcnRlZCkgaXNBYm9ydGVkID0gdXRpbC5hYm9ydGVkKHBheWxvYWQsIGN1cnJMZW4pO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXh0TGVuID0gcGF5bG9hZC5pc3N1ZXMubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICBpZiAobmV4dExlbiA9PT0gY3VyckxlbikgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgIGlmICghaXNBYm9ydGVkKSBpc0Fib3J0ZWQgPSB1dGlsLmFib3J0ZWQocGF5bG9hZCwgY3Vyckxlbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGFzeW5jUmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFzeW5jUmVzdWx0LnRoZW4oKCk9PntcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgfTtcbiAgICAgICAgLy8gY29uc3QgaGFuZGxlQ2hlY2tzUmVzdWx0ID0gKFxuICAgICAgICAvLyAgIGNoZWNrUmVzdWx0OiBQYXJzZVBheWxvYWQsXG4gICAgICAgIC8vICAgb3JpZ2luYWxSZXN1bHQ6IFBhcnNlUGF5bG9hZCxcbiAgICAgICAgLy8gICBjdHg6IFBhcnNlQ29udGV4dEludGVybmFsXG4gICAgICAgIC8vICk6IHV0aWwuTWF5YmVBc3luYzxQYXJzZVBheWxvYWQ+ID0+IHtcbiAgICAgICAgLy8gICAvLyBpZiB0aGUgY2hlY2tzIG11dGF0ZWQgdGhlIHZhbHVlICYmIHRoZXJlIGFyZSBubyBpc3N1ZXMsIHJlLXBhcnNlIHRoZSByZXN1bHRcbiAgICAgICAgLy8gICBpZiAoY2hlY2tSZXN1bHQudmFsdWUgIT09IG9yaWdpbmFsUmVzdWx0LnZhbHVlICYmICFjaGVja1Jlc3VsdC5pc3N1ZXMubGVuZ3RoKVxuICAgICAgICAvLyAgICAgcmV0dXJuIGluc3QuX3pvZC5wYXJzZShjaGVja1Jlc3VsdCwgY3R4KTtcbiAgICAgICAgLy8gICByZXR1cm4gb3JpZ2luYWxSZXN1bHQ7XG4gICAgICAgIC8vIH07XG4gICAgICAgIGNvbnN0IGhhbmRsZUNhbmFyeVJlc3VsdCA9IChjYW5hcnksIHBheWxvYWQsIGN0eCk9PntcbiAgICAgICAgICAgIC8vIGFib3J0IGlmIHRoZSBjYW5hcnkgaXMgYWJvcnRlZFxuICAgICAgICAgICAgaWYgKHV0aWwuYWJvcnRlZChjYW5hcnkpKSB7XG4gICAgICAgICAgICAgICAgY2FuYXJ5LmFib3J0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHJldHVybiBjYW5hcnk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBydW4gY2hlY2tzIGZpcnN0LCB0aGVuXG4gICAgICAgICAgICBjb25zdCBjaGVja1Jlc3VsdCA9IHJ1bkNoZWNrcyhwYXlsb2FkLCBjaGVja3MsIGN0eCk7XG4gICAgICAgICAgICBpZiAoY2hlY2tSZXN1bHQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICAgICAgaWYgKGN0eC5hc3luYyA9PT0gZmFsc2UpIHRocm93IG5ldyBjb3JlLiRab2RBc3luY0Vycm9yKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNoZWNrUmVzdWx0LnRoZW4oKGNoZWNrUmVzdWx0KT0+aW5zdC5fem9kLnBhcnNlKGNoZWNrUmVzdWx0LCBjdHgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBpbnN0Ll96b2QucGFyc2UoY2hlY2tSZXN1bHQsIGN0eCk7XG4gICAgICAgIH07XG4gICAgICAgIGluc3QuX3pvZC5ydW4gPSAocGF5bG9hZCwgY3R4KT0+e1xuICAgICAgICAgICAgaWYgKGN0eC5za2lwQ2hlY2tzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGluc3QuX3pvZC5wYXJzZShwYXlsb2FkLCBjdHgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGN0eC5kaXJlY3Rpb24gPT09IFwiYmFja3dhcmRcIikge1xuICAgICAgICAgICAgICAgIC8vIHJ1biBjYW5hcnlcbiAgICAgICAgICAgICAgICAvLyBpbml0aWFsIHBhc3MgKG5vIGNoZWNrcylcbiAgICAgICAgICAgICAgICBjb25zdCBjYW5hcnkgPSBpbnN0Ll96b2QucGFyc2Uoe1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogcGF5bG9hZC52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgaXNzdWVzOiBbXVxuICAgICAgICAgICAgICAgIH0sIHtcbiAgICAgICAgICAgICAgICAgICAgLi4uY3R4LFxuICAgICAgICAgICAgICAgICAgICBza2lwQ2hlY2tzOiB0cnVlXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgaWYgKGNhbmFyeSBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNhbmFyeS50aGVuKChjYW5hcnkpPT57XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlQ2FuYXJ5UmVzdWx0KGNhbmFyeSwgcGF5bG9hZCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBoYW5kbGVDYW5hcnlSZXN1bHQoY2FuYXJ5LCBwYXlsb2FkLCBjdHgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gZm9yd2FyZFxuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gaW5zdC5fem9kLnBhcnNlKHBheWxvYWQsIGN0eCk7XG4gICAgICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgICAgIGlmIChjdHguYXN5bmMgPT09IGZhbHNlKSB0aHJvdyBuZXcgY29yZS4kWm9kQXN5bmNFcnJvcigpO1xuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQudGhlbigocmVzdWx0KT0+cnVuQ2hlY2tzKHJlc3VsdCwgY2hlY2tzLCBjdHgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBydW5DaGVja3MocmVzdWx0LCBjaGVja3MsIGN0eCk7XG4gICAgICAgIH07XG4gICAgfVxuICAgIGluc3RbXCJ+c3RhbmRhcmRcIl0gPSB7XG4gICAgICAgIHZhbGlkYXRlOiAodmFsdWUpPT57XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHIgPSBzYWZlUGFyc2UoaW5zdCwgdmFsdWUpO1xuICAgICAgICAgICAgICAgIHJldHVybiByLnN1Y2Nlc3MgPyB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiByLmRhdGFcbiAgICAgICAgICAgICAgICB9IDoge1xuICAgICAgICAgICAgICAgICAgICBpc3N1ZXM6IHIuZXJyb3I/Lmlzc3Vlc1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9IGNhdGNoIChfKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNhZmVQYXJzZUFzeW5jKGluc3QsIHZhbHVlKS50aGVuKChyKT0+ci5zdWNjZXNzID8ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHIuZGF0YVxuICAgICAgICAgICAgICAgICAgICB9IDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgaXNzdWVzOiByLmVycm9yPy5pc3N1ZXNcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIHZlbmRvcjogXCJ6b2RcIixcbiAgICAgICAgdmVyc2lvbjogMVxuICAgIH07XG59KTtcbmV4cG9ydCB7IGNsb25lIH0gZnJvbSBcIi4vdXRpbC5qc1wiO1xuZXhwb3J0IGNvbnN0ICRab2RTdHJpbmcgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZFN0cmluZ1wiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0Ll96b2QucGF0dGVybiA9IFtcbiAgICAgICAgLi4uaW5zdD8uX3pvZC5iYWc/LnBhdHRlcm5zID8/IFtdXG4gICAgXS5wb3AoKSA/PyByZWdleGVzLnN0cmluZyhpbnN0Ll96b2QuYmFnKTtcbiAgICBpbnN0Ll96b2QucGFyc2UgPSAocGF5bG9hZCwgXyk9PntcbiAgICAgICAgaWYgKGRlZi5jb2VyY2UpIHRyeSB7XG4gICAgICAgICAgICBwYXlsb2FkLnZhbHVlID0gU3RyaW5nKHBheWxvYWQudmFsdWUpO1xuICAgICAgICB9IGNhdGNoIChfKSB7fVxuICAgICAgICBpZiAodHlwZW9mIHBheWxvYWQudmFsdWUgPT09IFwic3RyaW5nXCIpIHJldHVybiBwYXlsb2FkO1xuICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICAgIGV4cGVjdGVkOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX3R5cGVcIixcbiAgICAgICAgICAgIGlucHV0OiBwYXlsb2FkLnZhbHVlLFxuICAgICAgICAgICAgaW5zdFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RTdHJpbmdGb3JtYXQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZFN0cmluZ0Zvcm1hdFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIC8vIGNoZWNrIGluaXRpYWxpemF0aW9uIG11c3QgY29tZSBmaXJzdFxuICAgIGNoZWNrcy4kWm9kQ2hlY2tTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xuICAgICRab2RTdHJpbmcuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgY29uc3QgJFpvZEdVSUQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZEdVSURcIiwgKGluc3QsIGRlZik9PntcbiAgICBkZWYucGF0dGVybiA/PyAoZGVmLnBhdHRlcm4gPSByZWdleGVzLmd1aWQpO1xuICAgICRab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgY29uc3QgJFpvZFVVSUQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZFVVSURcIiwgKGluc3QsIGRlZik9PntcbiAgICBpZiAoZGVmLnZlcnNpb24pIHtcbiAgICAgICAgY29uc3QgdmVyc2lvbk1hcCA9IHtcbiAgICAgICAgICAgIHYxOiAxLFxuICAgICAgICAgICAgdjI6IDIsXG4gICAgICAgICAgICB2MzogMyxcbiAgICAgICAgICAgIHY0OiA0LFxuICAgICAgICAgICAgdjU6IDUsXG4gICAgICAgICAgICB2NjogNixcbiAgICAgICAgICAgIHY3OiA3LFxuICAgICAgICAgICAgdjg6IDhcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgdiA9IHZlcnNpb25NYXBbZGVmLnZlcnNpb25dO1xuICAgICAgICBpZiAodiA9PT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgVVVJRCB2ZXJzaW9uOiBcIiR7ZGVmLnZlcnNpb259XCJgKTtcbiAgICAgICAgZGVmLnBhdHRlcm4gPz8gKGRlZi5wYXR0ZXJuID0gcmVnZXhlcy51dWlkKHYpKTtcbiAgICB9IGVsc2UgZGVmLnBhdHRlcm4gPz8gKGRlZi5wYXR0ZXJuID0gcmVnZXhlcy51dWlkKCkpO1xuICAgICRab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgY29uc3QgJFpvZEVtYWlsID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RFbWFpbFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGRlZi5wYXR0ZXJuID8/IChkZWYucGF0dGVybiA9IHJlZ2V4ZXMuZW1haWwpO1xuICAgICRab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgY29uc3QgJFpvZFVSTCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kVVJMXCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5fem9kLmNoZWNrID0gKHBheWxvYWQpPT57XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBUcmltIHdoaXRlc3BhY2UgZnJvbSBpbnB1dFxuICAgICAgICAgICAgY29uc3QgdHJpbW1lZCA9IHBheWxvYWQudmFsdWUudHJpbSgpO1xuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgY29uc3QgdXJsID0gbmV3IFVSTCh0cmltbWVkKTtcbiAgICAgICAgICAgIGlmIChkZWYuaG9zdG5hbWUpIHtcbiAgICAgICAgICAgICAgICBkZWYuaG9zdG5hbWUubGFzdEluZGV4ID0gMDtcbiAgICAgICAgICAgICAgICBpZiAoIWRlZi5ob3N0bmFtZS50ZXN0KHVybC5ob3N0bmFtZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBcImludmFsaWRfZm9ybWF0XCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3JtYXQ6IFwidXJsXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBub3RlOiBcIkludmFsaWQgaG9zdG5hbWVcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhdHRlcm46IHJlZ2V4ZXMuaG9zdG5hbWUuc291cmNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQ6IHBheWxvYWQudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGRlZi5wcm90b2NvbCkge1xuICAgICAgICAgICAgICAgIGRlZi5wcm90b2NvbC5sYXN0SW5kZXggPSAwO1xuICAgICAgICAgICAgICAgIGlmICghZGVmLnByb3RvY29sLnRlc3QodXJsLnByb3RvY29sLmVuZHNXaXRoKFwiOlwiKSA/IHVybC5wcm90b2NvbC5zbGljZSgwLCAtMSkgOiB1cmwucHJvdG9jb2wpKSB7XG4gICAgICAgICAgICAgICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX2Zvcm1hdFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0OiBcInVybFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgbm90ZTogXCJJbnZhbGlkIHByb3RvY29sXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuOiBkZWYucHJvdG9jb2wuc291cmNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQ6IHBheWxvYWQudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gU2V0IHRoZSBvdXRwdXQgdmFsdWUgYmFzZWQgb24gbm9ybWFsaXplIGZsYWdcbiAgICAgICAgICAgIGlmIChkZWYubm9ybWFsaXplKSB7XG4gICAgICAgICAgICAgICAgLy8gVXNlIG5vcm1hbGl6ZWQgVVJMXG4gICAgICAgICAgICAgICAgcGF5bG9hZC52YWx1ZSA9IHVybC5ocmVmO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBQcmVzZXJ2ZSB0aGUgb3JpZ2luYWwgaW5wdXQgKHRyaW1tZWQpXG4gICAgICAgICAgICAgICAgcGF5bG9hZC52YWx1ZSA9IHRyaW1tZWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gY2F0Y2ggKF8pIHtcbiAgICAgICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF9mb3JtYXRcIixcbiAgICAgICAgICAgICAgICBmb3JtYXQ6IFwidXJsXCIsXG4gICAgICAgICAgICAgICAgaW5wdXQ6IHBheWxvYWQudmFsdWUsXG4gICAgICAgICAgICAgICAgaW5zdCxcbiAgICAgICAgICAgICAgICBjb250aW51ZTogIWRlZi5hYm9ydFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZEVtb2ppID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RFbW9qaVwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGRlZi5wYXR0ZXJuID8/IChkZWYucGF0dGVybiA9IHJlZ2V4ZXMuZW1vamkoKSk7XG4gICAgJFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kTmFub0lEID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2ROYW5vSURcIiwgKGluc3QsIGRlZik9PntcbiAgICBkZWYucGF0dGVybiA/PyAoZGVmLnBhdHRlcm4gPSByZWdleGVzLm5hbm9pZCk7XG4gICAgJFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kQ1VJRCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kQ1VJRFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGRlZi5wYXR0ZXJuID8/IChkZWYucGF0dGVybiA9IHJlZ2V4ZXMuY3VpZCk7XG4gICAgJFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kQ1VJRDIgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZENVSUQyXCIsIChpbnN0LCBkZWYpPT57XG4gICAgZGVmLnBhdHRlcm4gPz8gKGRlZi5wYXR0ZXJuID0gcmVnZXhlcy5jdWlkMik7XG4gICAgJFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kVUxJRCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kVUxJRFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGRlZi5wYXR0ZXJuID8/IChkZWYucGF0dGVybiA9IHJlZ2V4ZXMudWxpZCk7XG4gICAgJFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kWElEID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RYSURcIiwgKGluc3QsIGRlZik9PntcbiAgICBkZWYucGF0dGVybiA/PyAoZGVmLnBhdHRlcm4gPSByZWdleGVzLnhpZCk7XG4gICAgJFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kS1NVSUQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZEtTVUlEXCIsIChpbnN0LCBkZWYpPT57XG4gICAgZGVmLnBhdHRlcm4gPz8gKGRlZi5wYXR0ZXJuID0gcmVnZXhlcy5rc3VpZCk7XG4gICAgJFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kSVNPRGF0ZVRpbWUgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZElTT0RhdGVUaW1lXCIsIChpbnN0LCBkZWYpPT57XG4gICAgZGVmLnBhdHRlcm4gPz8gKGRlZi5wYXR0ZXJuID0gcmVnZXhlcy5kYXRldGltZShkZWYpKTtcbiAgICAkWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RJU09EYXRlID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RJU09EYXRlXCIsIChpbnN0LCBkZWYpPT57XG4gICAgZGVmLnBhdHRlcm4gPz8gKGRlZi5wYXR0ZXJuID0gcmVnZXhlcy5kYXRlKTtcbiAgICAkWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RJU09UaW1lID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RJU09UaW1lXCIsIChpbnN0LCBkZWYpPT57XG4gICAgZGVmLnBhdHRlcm4gPz8gKGRlZi5wYXR0ZXJuID0gcmVnZXhlcy50aW1lKGRlZikpO1xuICAgICRab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgY29uc3QgJFpvZElTT0R1cmF0aW9uID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RJU09EdXJhdGlvblwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGRlZi5wYXR0ZXJuID8/IChkZWYucGF0dGVybiA9IHJlZ2V4ZXMuZHVyYXRpb24pO1xuICAgICRab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgY29uc3QgJFpvZElQdjQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZElQdjRcIiwgKGluc3QsIGRlZik9PntcbiAgICBkZWYucGF0dGVybiA/PyAoZGVmLnBhdHRlcm4gPSByZWdleGVzLmlwdjQpO1xuICAgICRab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5vbmF0dGFjaC5wdXNoKChpbnN0KT0+e1xuICAgICAgICBjb25zdCBiYWcgPSBpbnN0Ll96b2QuYmFnO1xuICAgICAgICBiYWcuZm9ybWF0ID0gYGlwdjRgO1xuICAgIH0pO1xufSk7XG5leHBvcnQgY29uc3QgJFpvZElQdjYgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZElQdjZcIiwgKGluc3QsIGRlZik9PntcbiAgICBkZWYucGF0dGVybiA/PyAoZGVmLnBhdHRlcm4gPSByZWdleGVzLmlwdjYpO1xuICAgICRab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5vbmF0dGFjaC5wdXNoKChpbnN0KT0+e1xuICAgICAgICBjb25zdCBiYWcgPSBpbnN0Ll96b2QuYmFnO1xuICAgICAgICBiYWcuZm9ybWF0ID0gYGlwdjZgO1xuICAgIH0pO1xuICAgIGluc3QuX3pvZC5jaGVjayA9IChwYXlsb2FkKT0+e1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgbmV3IFVSTChgaHR0cDovL1ske3BheWxvYWQudmFsdWV9XWApO1xuICAgICAgICAvLyByZXR1cm47XG4gICAgICAgIH0gY2F0Y2ggIHtcbiAgICAgICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF9mb3JtYXRcIixcbiAgICAgICAgICAgICAgICBmb3JtYXQ6IFwiaXB2NlwiLFxuICAgICAgICAgICAgICAgIGlucHV0OiBwYXlsb2FkLnZhbHVlLFxuICAgICAgICAgICAgICAgIGluc3QsXG4gICAgICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RDSURSdjQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZENJRFJ2NFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGRlZi5wYXR0ZXJuID8/IChkZWYucGF0dGVybiA9IHJlZ2V4ZXMuY2lkcnY0KTtcbiAgICAkWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RDSURSdjYgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZENJRFJ2NlwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGRlZi5wYXR0ZXJuID8/IChkZWYucGF0dGVybiA9IHJlZ2V4ZXMuY2lkcnY2KTsgLy8gbm90IHVzZWQgZm9yIHZhbGlkYXRpb25cbiAgICAkWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0Ll96b2QuY2hlY2sgPSAocGF5bG9hZCk9PntcbiAgICAgICAgY29uc3QgcGFydHMgPSBwYXlsb2FkLnZhbHVlLnNwbGl0KFwiL1wiKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmIChwYXJ0cy5sZW5ndGggIT09IDIpIHRocm93IG5ldyBFcnJvcigpO1xuICAgICAgICAgICAgY29uc3QgW2FkZHJlc3MsIHByZWZpeF0gPSBwYXJ0cztcbiAgICAgICAgICAgIGlmICghcHJlZml4KSB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgICAgICAgICAgIGNvbnN0IHByZWZpeE51bSA9IE51bWJlcihwcmVmaXgpO1xuICAgICAgICAgICAgaWYgKGAke3ByZWZpeE51bX1gICE9PSBwcmVmaXgpIHRocm93IG5ldyBFcnJvcigpO1xuICAgICAgICAgICAgaWYgKHByZWZpeE51bSA8IDAgfHwgcHJlZml4TnVtID4gMTI4KSB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgIG5ldyBVUkwoYGh0dHA6Ly9bJHthZGRyZXNzfV1gKTtcbiAgICAgICAgfSBjYXRjaCAge1xuICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX2Zvcm1hdFwiLFxuICAgICAgICAgICAgICAgIGZvcm1hdDogXCJjaWRydjZcIixcbiAgICAgICAgICAgICAgICBpbnB1dDogcGF5bG9hZC52YWx1ZSxcbiAgICAgICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgICAgIGNvbnRpbnVlOiAhZGVmLmFib3J0XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG59KTtcbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyAgIFpvZEJhc2U2NCAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVmFsaWRCYXNlNjQoZGF0YSkge1xuICAgIGlmIChkYXRhID09PSBcIlwiKSByZXR1cm4gdHJ1ZTtcbiAgICBpZiAoZGF0YS5sZW5ndGggJSA0ICE9PSAwKSByZXR1cm4gZmFsc2U7XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICBhdG9iKGRhdGEpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoICB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG59XG5leHBvcnQgY29uc3QgJFpvZEJhc2U2NCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kQmFzZTY0XCIsIChpbnN0LCBkZWYpPT57XG4gICAgZGVmLnBhdHRlcm4gPz8gKGRlZi5wYXR0ZXJuID0gcmVnZXhlcy5iYXNlNjQpO1xuICAgICRab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5vbmF0dGFjaC5wdXNoKChpbnN0KT0+e1xuICAgICAgICBpbnN0Ll96b2QuYmFnLmNvbnRlbnRFbmNvZGluZyA9IFwiYmFzZTY0XCI7XG4gICAgfSk7XG4gICAgaW5zdC5fem9kLmNoZWNrID0gKHBheWxvYWQpPT57XG4gICAgICAgIGlmIChpc1ZhbGlkQmFzZTY0KHBheWxvYWQudmFsdWUpKSByZXR1cm47XG4gICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX2Zvcm1hdFwiLFxuICAgICAgICAgICAgZm9ybWF0OiBcImJhc2U2NFwiLFxuICAgICAgICAgICAgaW5wdXQ6IHBheWxvYWQudmFsdWUsXG4gICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgfSk7XG4gICAgfTtcbn0pO1xuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vICAgWm9kQmFzZTY0ICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZEJhc2U2NFVSTChkYXRhKSB7XG4gICAgaWYgKCFyZWdleGVzLmJhc2U2NHVybC50ZXN0KGRhdGEpKSByZXR1cm4gZmFsc2U7XG4gICAgY29uc3QgYmFzZTY0ID0gZGF0YS5yZXBsYWNlKC9bLV9dL2csIChjKT0+YyA9PT0gXCItXCIgPyBcIitcIiA6IFwiL1wiKTtcbiAgICBjb25zdCBwYWRkZWQgPSBiYXNlNjQucGFkRW5kKE1hdGguY2VpbChiYXNlNjQubGVuZ3RoIC8gNCkgKiA0LCBcIj1cIik7XG4gICAgcmV0dXJuIGlzVmFsaWRCYXNlNjQocGFkZGVkKTtcbn1cbmV4cG9ydCBjb25zdCAkWm9kQmFzZTY0VVJMID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RCYXNlNjRVUkxcIiwgKGluc3QsIGRlZik9PntcbiAgICBkZWYucGF0dGVybiA/PyAoZGVmLnBhdHRlcm4gPSByZWdleGVzLmJhc2U2NHVybCk7XG4gICAgJFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5fem9kLm9uYXR0YWNoLnB1c2goKGluc3QpPT57XG4gICAgICAgIGluc3QuX3pvZC5iYWcuY29udGVudEVuY29kaW5nID0gXCJiYXNlNjR1cmxcIjtcbiAgICB9KTtcbiAgICBpbnN0Ll96b2QuY2hlY2sgPSAocGF5bG9hZCk9PntcbiAgICAgICAgaWYgKGlzVmFsaWRCYXNlNjRVUkwocGF5bG9hZC52YWx1ZSkpIHJldHVybjtcbiAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICBjb2RlOiBcImludmFsaWRfZm9ybWF0XCIsXG4gICAgICAgICAgICBmb3JtYXQ6IFwiYmFzZTY0dXJsXCIsXG4gICAgICAgICAgICBpbnB1dDogcGF5bG9hZC52YWx1ZSxcbiAgICAgICAgICAgIGluc3QsXG4gICAgICAgICAgICBjb250aW51ZTogIWRlZi5hYm9ydFxuICAgICAgICB9KTtcbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZEUxNjQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZEUxNjRcIiwgKGluc3QsIGRlZik9PntcbiAgICBkZWYucGF0dGVybiA/PyAoZGVmLnBhdHRlcm4gPSByZWdleGVzLmUxNjQpO1xuICAgICRab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8gICBab2RKV1QgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkSldUKHRva2VuLCBhbGdvcml0aG0gPSBudWxsKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgY29uc3QgdG9rZW5zUGFydHMgPSB0b2tlbi5zcGxpdChcIi5cIik7XG4gICAgICAgIGlmICh0b2tlbnNQYXJ0cy5sZW5ndGggIT09IDMpIHJldHVybiBmYWxzZTtcbiAgICAgICAgY29uc3QgW2hlYWRlcl0gPSB0b2tlbnNQYXJ0cztcbiAgICAgICAgaWYgKCFoZWFkZXIpIHJldHVybiBmYWxzZTtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICBjb25zdCBwYXJzZWRIZWFkZXIgPSBKU09OLnBhcnNlKGF0b2IoaGVhZGVyKSk7XG4gICAgICAgIGlmIChcInR5cFwiIGluIHBhcnNlZEhlYWRlciAmJiBwYXJzZWRIZWFkZXI/LnR5cCAhPT0gXCJKV1RcIikgcmV0dXJuIGZhbHNlO1xuICAgICAgICBpZiAoIXBhcnNlZEhlYWRlci5hbGcpIHJldHVybiBmYWxzZTtcbiAgICAgICAgaWYgKGFsZ29yaXRobSAmJiAoIShcImFsZ1wiIGluIHBhcnNlZEhlYWRlcikgfHwgcGFyc2VkSGVhZGVyLmFsZyAhPT0gYWxnb3JpdGhtKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoICB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG59XG5leHBvcnQgY29uc3QgJFpvZEpXVCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kSldUXCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5fem9kLmNoZWNrID0gKHBheWxvYWQpPT57XG4gICAgICAgIGlmIChpc1ZhbGlkSldUKHBheWxvYWQudmFsdWUsIGRlZi5hbGcpKSByZXR1cm47XG4gICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX2Zvcm1hdFwiLFxuICAgICAgICAgICAgZm9ybWF0OiBcImp3dFwiLFxuICAgICAgICAgICAgaW5wdXQ6IHBheWxvYWQudmFsdWUsXG4gICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgfSk7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RDdXN0b21TdHJpbmdGb3JtYXQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZEN1c3RvbVN0cmluZ0Zvcm1hdFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5jaGVjayA9IChwYXlsb2FkKT0+e1xuICAgICAgICBpZiAoZGVmLmZuKHBheWxvYWQudmFsdWUpKSByZXR1cm47XG4gICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX2Zvcm1hdFwiLFxuICAgICAgICAgICAgZm9ybWF0OiBkZWYuZm9ybWF0LFxuICAgICAgICAgICAgaW5wdXQ6IHBheWxvYWQudmFsdWUsXG4gICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgfSk7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2ROdW1iZXIgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZE51bWJlclwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0Ll96b2QucGF0dGVybiA9IGluc3QuX3pvZC5iYWcucGF0dGVybiA/PyByZWdleGVzLm51bWJlcjtcbiAgICBpbnN0Ll96b2QucGFyc2UgPSAocGF5bG9hZCwgX2N0eCk9PntcbiAgICAgICAgaWYgKGRlZi5jb2VyY2UpIHRyeSB7XG4gICAgICAgICAgICBwYXlsb2FkLnZhbHVlID0gTnVtYmVyKHBheWxvYWQudmFsdWUpO1xuICAgICAgICB9IGNhdGNoIChfKSB7fVxuICAgICAgICBjb25zdCBpbnB1dCA9IHBheWxvYWQudmFsdWU7XG4gICAgICAgIGlmICh0eXBlb2YgaW5wdXQgPT09IFwibnVtYmVyXCIgJiYgIU51bWJlci5pc05hTihpbnB1dCkgJiYgTnVtYmVyLmlzRmluaXRlKGlucHV0KSkge1xuICAgICAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVjZWl2ZWQgPSB0eXBlb2YgaW5wdXQgPT09IFwibnVtYmVyXCIgPyBOdW1iZXIuaXNOYU4oaW5wdXQpID8gXCJOYU5cIiA6ICFOdW1iZXIuaXNGaW5pdGUoaW5wdXQpID8gXCJJbmZpbml0eVwiIDogdW5kZWZpbmVkIDogdW5kZWZpbmVkO1xuICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICAgIGV4cGVjdGVkOiBcIm51bWJlclwiLFxuICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX3R5cGVcIixcbiAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgaW5zdCxcbiAgICAgICAgICAgIC4uLnJlY2VpdmVkID8ge1xuICAgICAgICAgICAgICAgIHJlY2VpdmVkXG4gICAgICAgICAgICB9IDoge31cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgIH07XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kTnVtYmVyRm9ybWF0ID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2ROdW1iZXJcIiwgKGluc3QsIGRlZik9PntcbiAgICBjaGVja3MuJFpvZENoZWNrTnVtYmVyRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbiAgICAkWm9kTnVtYmVyLmluaXQoaW5zdCwgZGVmKTsgLy8gbm8gZm9ybWF0IGNoZWNrc3Bcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RCb29sZWFuID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RCb29sZWFuXCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5wYXR0ZXJuID0gcmVnZXhlcy5ib29sZWFuO1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkLCBfY3R4KT0+e1xuICAgICAgICBpZiAoZGVmLmNvZXJjZSkgdHJ5IHtcbiAgICAgICAgICAgIHBheWxvYWQudmFsdWUgPSBCb29sZWFuKHBheWxvYWQudmFsdWUpO1xuICAgICAgICB9IGNhdGNoIChfKSB7fVxuICAgICAgICBjb25zdCBpbnB1dCA9IHBheWxvYWQudmFsdWU7XG4gICAgICAgIGlmICh0eXBlb2YgaW5wdXQgPT09IFwiYm9vbGVhblwiKSByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICBleHBlY3RlZDogXCJib29sZWFuXCIsXG4gICAgICAgICAgICBjb2RlOiBcImludmFsaWRfdHlwZVwiLFxuICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICBpbnN0XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZEJpZ0ludCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kQmlnSW50XCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5wYXR0ZXJuID0gcmVnZXhlcy5iaWdpbnQ7XG4gICAgaW5zdC5fem9kLnBhcnNlID0gKHBheWxvYWQsIF9jdHgpPT57XG4gICAgICAgIGlmIChkZWYuY29lcmNlKSB0cnkge1xuICAgICAgICAgICAgcGF5bG9hZC52YWx1ZSA9IEJpZ0ludChwYXlsb2FkLnZhbHVlKTtcbiAgICAgICAgfSBjYXRjaCAoXykge31cbiAgICAgICAgaWYgKHR5cGVvZiBwYXlsb2FkLnZhbHVlID09PSBcImJpZ2ludFwiKSByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICBleHBlY3RlZDogXCJiaWdpbnRcIixcbiAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF90eXBlXCIsXG4gICAgICAgICAgICBpbnB1dDogcGF5bG9hZC52YWx1ZSxcbiAgICAgICAgICAgIGluc3RcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgIH07XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kQmlnSW50Rm9ybWF0ID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RCaWdJbnRcIiwgKGluc3QsIGRlZik9PntcbiAgICBjaGVja3MuJFpvZENoZWNrQmlnSW50Rm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbiAgICAkWm9kQmlnSW50LmluaXQoaW5zdCwgZGVmKTsgLy8gbm8gZm9ybWF0IGNoZWNrc1xufSk7XG5leHBvcnQgY29uc3QgJFpvZFN5bWJvbCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kU3ltYm9sXCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkLCBfY3R4KT0+e1xuICAgICAgICBjb25zdCBpbnB1dCA9IHBheWxvYWQudmFsdWU7XG4gICAgICAgIGlmICh0eXBlb2YgaW5wdXQgPT09IFwic3ltYm9sXCIpIHJldHVybiBwYXlsb2FkO1xuICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICAgIGV4cGVjdGVkOiBcInN5bWJvbFwiLFxuICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX3R5cGVcIixcbiAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgaW5zdFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RVbmRlZmluZWQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZFVuZGVmaW5lZFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0Ll96b2QucGF0dGVybiA9IHJlZ2V4ZXMudW5kZWZpbmVkO1xuICAgIGluc3QuX3pvZC52YWx1ZXMgPSBuZXcgU2V0KFtcbiAgICAgICAgdW5kZWZpbmVkXG4gICAgXSk7XG4gICAgaW5zdC5fem9kLm9wdGluID0gXCJvcHRpb25hbFwiO1xuICAgIGluc3QuX3pvZC5vcHRvdXQgPSBcIm9wdGlvbmFsXCI7XG4gICAgaW5zdC5fem9kLnBhcnNlID0gKHBheWxvYWQsIF9jdHgpPT57XG4gICAgICAgIGNvbnN0IGlucHV0ID0gcGF5bG9hZC52YWx1ZTtcbiAgICAgICAgaWYgKHR5cGVvZiBpbnB1dCA9PT0gXCJ1bmRlZmluZWRcIikgcmV0dXJuIHBheWxvYWQ7XG4gICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgZXhwZWN0ZWQ6IFwidW5kZWZpbmVkXCIsXG4gICAgICAgICAgICBjb2RlOiBcImludmFsaWRfdHlwZVwiLFxuICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICBpbnN0XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZE51bGwgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZE51bGxcIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5fem9kLnBhdHRlcm4gPSByZWdleGVzLm51bGw7XG4gICAgaW5zdC5fem9kLnZhbHVlcyA9IG5ldyBTZXQoW1xuICAgICAgICBudWxsXG4gICAgXSk7XG4gICAgaW5zdC5fem9kLnBhcnNlID0gKHBheWxvYWQsIF9jdHgpPT57XG4gICAgICAgIGNvbnN0IGlucHV0ID0gcGF5bG9hZC52YWx1ZTtcbiAgICAgICAgaWYgKGlucHV0ID09PSBudWxsKSByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICBleHBlY3RlZDogXCJudWxsXCIsXG4gICAgICAgICAgICBjb2RlOiBcImludmFsaWRfdHlwZVwiLFxuICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICBpbnN0XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZEFueSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kQW55XCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkKT0+cGF5bG9hZDtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RVbmtub3duID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RVbmtub3duXCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkKT0+cGF5bG9hZDtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2ROZXZlciA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kTmV2ZXJcIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5fem9kLnBhcnNlID0gKHBheWxvYWQsIF9jdHgpPT57XG4gICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgZXhwZWN0ZWQ6IFwibmV2ZXJcIixcbiAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF90eXBlXCIsXG4gICAgICAgICAgICBpbnB1dDogcGF5bG9hZC52YWx1ZSxcbiAgICAgICAgICAgIGluc3RcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgIH07XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kVm9pZCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kVm9pZFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0Ll96b2QucGFyc2UgPSAocGF5bG9hZCwgX2N0eCk9PntcbiAgICAgICAgY29uc3QgaW5wdXQgPSBwYXlsb2FkLnZhbHVlO1xuICAgICAgICBpZiAodHlwZW9mIGlucHV0ID09PSBcInVuZGVmaW5lZFwiKSByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICBleHBlY3RlZDogXCJ2b2lkXCIsXG4gICAgICAgICAgICBjb2RlOiBcImludmFsaWRfdHlwZVwiLFxuICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICBpbnN0XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZERhdGUgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZERhdGVcIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5fem9kLnBhcnNlID0gKHBheWxvYWQsIF9jdHgpPT57XG4gICAgICAgIGlmIChkZWYuY29lcmNlKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHBheWxvYWQudmFsdWUgPSBuZXcgRGF0ZShwYXlsb2FkLnZhbHVlKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKF9lcnIpIHt9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaW5wdXQgPSBwYXlsb2FkLnZhbHVlO1xuICAgICAgICBjb25zdCBpc0RhdGUgPSBpbnB1dCBpbnN0YW5jZW9mIERhdGU7XG4gICAgICAgIGNvbnN0IGlzVmFsaWREYXRlID0gaXNEYXRlICYmICFOdW1iZXIuaXNOYU4oaW5wdXQuZ2V0VGltZSgpKTtcbiAgICAgICAgaWYgKGlzVmFsaWREYXRlKSByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICBleHBlY3RlZDogXCJkYXRlXCIsXG4gICAgICAgICAgICBjb2RlOiBcImludmFsaWRfdHlwZVwiLFxuICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICAuLi5pc0RhdGUgPyB7XG4gICAgICAgICAgICAgICAgcmVjZWl2ZWQ6IFwiSW52YWxpZCBEYXRlXCJcbiAgICAgICAgICAgIH0gOiB7fSxcbiAgICAgICAgICAgIGluc3RcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgIH07XG59KTtcbmZ1bmN0aW9uIGhhbmRsZUFycmF5UmVzdWx0KHJlc3VsdCwgZmluYWwsIGluZGV4KSB7XG4gICAgaWYgKHJlc3VsdC5pc3N1ZXMubGVuZ3RoKSB7XG4gICAgICAgIGZpbmFsLmlzc3Vlcy5wdXNoKC4uLnV0aWwucHJlZml4SXNzdWVzKGluZGV4LCByZXN1bHQuaXNzdWVzKSk7XG4gICAgfVxuICAgIGZpbmFsLnZhbHVlW2luZGV4XSA9IHJlc3VsdC52YWx1ZTtcbn1cbmV4cG9ydCBjb25zdCAkWm9kQXJyYXkgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZEFycmF5XCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkLCBjdHgpPT57XG4gICAgICAgIGNvbnN0IGlucHV0ID0gcGF5bG9hZC52YWx1ZTtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGlucHV0KSkge1xuICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IFwiYXJyYXlcIixcbiAgICAgICAgICAgICAgICBjb2RlOiBcImludmFsaWRfdHlwZVwiLFxuICAgICAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgICAgIGluc3RcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgICAgIH1cbiAgICAgICAgcGF5bG9hZC52YWx1ZSA9IEFycmF5KGlucHV0Lmxlbmd0aCk7XG4gICAgICAgIGNvbnN0IHByb21zID0gW107XG4gICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCBpbnB1dC5sZW5ndGg7IGkrKyl7XG4gICAgICAgICAgICBjb25zdCBpdGVtID0gaW5wdXRbaV07XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBkZWYuZWxlbWVudC5fem9kLnJ1bih7XG4gICAgICAgICAgICAgICAgdmFsdWU6IGl0ZW0sXG4gICAgICAgICAgICAgICAgaXNzdWVzOiBbXVxuICAgICAgICAgICAgfSwgY3R4KTtcbiAgICAgICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICAgICAgcHJvbXMucHVzaChyZXN1bHQudGhlbigocmVzdWx0KT0+aGFuZGxlQXJyYXlSZXN1bHQocmVzdWx0LCBwYXlsb2FkLCBpKSkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBoYW5kbGVBcnJheVJlc3VsdChyZXN1bHQsIHBheWxvYWQsIGkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9tcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9tcykudGhlbigoKT0+cGF5bG9hZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBheWxvYWQ7IC8vaGFuZGxlQXJyYXlSZXN1bHRzQXN5bmMocGFyc2VSZXN1bHRzLCBmaW5hbCk7XG4gICAgfTtcbn0pO1xuZnVuY3Rpb24gaGFuZGxlUHJvcGVydHlSZXN1bHQocmVzdWx0LCBmaW5hbCwga2V5LCBpbnB1dCkge1xuICAgIGlmIChyZXN1bHQuaXNzdWVzLmxlbmd0aCkge1xuICAgICAgICBmaW5hbC5pc3N1ZXMucHVzaCguLi51dGlsLnByZWZpeElzc3VlcyhrZXksIHJlc3VsdC5pc3N1ZXMpKTtcbiAgICB9XG4gICAgaWYgKHJlc3VsdC52YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmIChrZXkgaW4gaW5wdXQpIHtcbiAgICAgICAgICAgIGZpbmFsLnZhbHVlW2tleV0gPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICBmaW5hbC52YWx1ZVtrZXldID0gcmVzdWx0LnZhbHVlO1xuICAgIH1cbn1cbmZ1bmN0aW9uIG5vcm1hbGl6ZURlZihkZWYpIHtcbiAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoZGVmLnNoYXBlKTtcbiAgICBmb3IgKGNvbnN0IGsgb2Yga2V5cyl7XG4gICAgICAgIGlmICghZGVmLnNoYXBlPy5ba10/Ll96b2Q/LnRyYWl0cz8uaGFzKFwiJFpvZFR5cGVcIikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBlbGVtZW50IGF0IGtleSBcIiR7a31cIjogZXhwZWN0ZWQgYSBab2Qgc2NoZW1hYCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY29uc3Qgb2tleXMgPSB1dGlsLm9wdGlvbmFsS2V5cyhkZWYuc2hhcGUpO1xuICAgIHJldHVybiB7XG4gICAgICAgIC4uLmRlZixcbiAgICAgICAga2V5cyxcbiAgICAgICAga2V5U2V0OiBuZXcgU2V0KGtleXMpLFxuICAgICAgICBudW1LZXlzOiBrZXlzLmxlbmd0aCxcbiAgICAgICAgb3B0aW9uYWxLZXlzOiBuZXcgU2V0KG9rZXlzKVxuICAgIH07XG59XG5mdW5jdGlvbiBoYW5kbGVDYXRjaGFsbChwcm9tcywgaW5wdXQsIHBheWxvYWQsIGN0eCwgZGVmLCBpbnN0KSB7XG4gICAgY29uc3QgdW5yZWNvZ25pemVkID0gW107XG4gICAgLy8gaXRlcmF0ZSBvdmVyIGlucHV0IGtleXNcbiAgICBjb25zdCBrZXlTZXQgPSBkZWYua2V5U2V0O1xuICAgIGNvbnN0IF9jYXRjaGFsbCA9IGRlZi5jYXRjaGFsbC5fem9kO1xuICAgIGNvbnN0IHQgPSBfY2F0Y2hhbGwuZGVmLnR5cGU7XG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoaW5wdXQpKXtcbiAgICAgICAgaWYgKGtleVNldC5oYXMoa2V5KSkgY29udGludWU7XG4gICAgICAgIGlmICh0ID09PSBcIm5ldmVyXCIpIHtcbiAgICAgICAgICAgIHVucmVjb2duaXplZC5wdXNoKGtleSk7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByID0gX2NhdGNoYWxsLnJ1bih7XG4gICAgICAgICAgICB2YWx1ZTogaW5wdXRba2V5XSxcbiAgICAgICAgICAgIGlzc3VlczogW11cbiAgICAgICAgfSwgY3R4KTtcbiAgICAgICAgaWYgKHIgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICBwcm9tcy5wdXNoKHIudGhlbigocik9PmhhbmRsZVByb3BlcnR5UmVzdWx0KHIsIHBheWxvYWQsIGtleSwgaW5wdXQpKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBoYW5kbGVQcm9wZXJ0eVJlc3VsdChyLCBwYXlsb2FkLCBrZXksIGlucHV0KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAodW5yZWNvZ25pemVkLmxlbmd0aCkge1xuICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICAgIGNvZGU6IFwidW5yZWNvZ25pemVkX2tleXNcIixcbiAgICAgICAgICAgIGtleXM6IHVucmVjb2duaXplZCxcbiAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgaW5zdFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgaWYgKCFwcm9tcy5sZW5ndGgpIHJldHVybiBwYXlsb2FkO1xuICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9tcykudGhlbigoKT0+e1xuICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICB9KTtcbn1cbmV4cG9ydCBjb25zdCAkWm9kT2JqZWN0ID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RPYmplY3RcIiwgKGluc3QsIGRlZik9PntcbiAgICAvLyByZXF1aXJlcyBjYXN0IGJlY2F1c2UgdGVjaG5pY2FsbHkgJFpvZE9iamVjdCBkb2Vzbid0IGV4dGVuZFxuICAgICRab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICAvLyBjb25zdCBzaCA9IGRlZi5zaGFwZTtcbiAgICBjb25zdCBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihkZWYsIFwic2hhcGVcIik7XG4gICAgaWYgKCFkZXNjPy5nZXQpIHtcbiAgICAgICAgY29uc3Qgc2ggPSBkZWYuc2hhcGU7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShkZWYsIFwic2hhcGVcIiwge1xuICAgICAgICAgICAgZ2V0OiAoKT0+e1xuICAgICAgICAgICAgICAgIGNvbnN0IG5ld1NoID0ge1xuICAgICAgICAgICAgICAgICAgICAuLi5zaFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGRlZiwgXCJzaGFwZVwiLCB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiBuZXdTaFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXdTaDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGNvbnN0IF9ub3JtYWxpemVkID0gdXRpbC5jYWNoZWQoKCk9Pm5vcm1hbGl6ZURlZihkZWYpKTtcbiAgICB1dGlsLmRlZmluZUxhenkoaW5zdC5fem9kLCBcInByb3BWYWx1ZXNcIiwgKCk9PntcbiAgICAgICAgY29uc3Qgc2hhcGUgPSBkZWYuc2hhcGU7XG4gICAgICAgIGNvbnN0IHByb3BWYWx1ZXMgPSB7fTtcbiAgICAgICAgZm9yKGNvbnN0IGtleSBpbiBzaGFwZSl7XG4gICAgICAgICAgICBjb25zdCBmaWVsZCA9IHNoYXBlW2tleV0uX3pvZDtcbiAgICAgICAgICAgIGlmIChmaWVsZC52YWx1ZXMpIHtcbiAgICAgICAgICAgICAgICBwcm9wVmFsdWVzW2tleV0gPz8gKHByb3BWYWx1ZXNba2V5XSA9IG5ldyBTZXQoKSk7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCB2IG9mIGZpZWxkLnZhbHVlcylwcm9wVmFsdWVzW2tleV0uYWRkKHYpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwcm9wVmFsdWVzO1xuICAgIH0pO1xuICAgIGNvbnN0IGlzT2JqZWN0ID0gdXRpbC5pc09iamVjdDtcbiAgICBjb25zdCBjYXRjaGFsbCA9IGRlZi5jYXRjaGFsbDtcbiAgICBsZXQgdmFsdWU7XG4gICAgaW5zdC5fem9kLnBhcnNlID0gKHBheWxvYWQsIGN0eCk9PntcbiAgICAgICAgdmFsdWUgPz8gKHZhbHVlID0gX25vcm1hbGl6ZWQudmFsdWUpO1xuICAgICAgICBjb25zdCBpbnB1dCA9IHBheWxvYWQudmFsdWU7XG4gICAgICAgIGlmICghaXNPYmplY3QoaW5wdXQpKSB7XG4gICAgICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogXCJvYmplY3RcIixcbiAgICAgICAgICAgICAgICBjb2RlOiBcImludmFsaWRfdHlwZVwiLFxuICAgICAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgICAgIGluc3RcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgICAgIH1cbiAgICAgICAgcGF5bG9hZC52YWx1ZSA9IHt9O1xuICAgICAgICBjb25zdCBwcm9tcyA9IFtdO1xuICAgICAgICBjb25zdCBzaGFwZSA9IHZhbHVlLnNoYXBlO1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiB2YWx1ZS5rZXlzKXtcbiAgICAgICAgICAgIGNvbnN0IGVsID0gc2hhcGVba2V5XTtcbiAgICAgICAgICAgIGNvbnN0IHIgPSBlbC5fem9kLnJ1bih7XG4gICAgICAgICAgICAgICAgdmFsdWU6IGlucHV0W2tleV0sXG4gICAgICAgICAgICAgICAgaXNzdWVzOiBbXVxuICAgICAgICAgICAgfSwgY3R4KTtcbiAgICAgICAgICAgIGlmIChyIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgICAgIHByb21zLnB1c2goci50aGVuKChyKT0+aGFuZGxlUHJvcGVydHlSZXN1bHQociwgcGF5bG9hZCwga2V5LCBpbnB1dCkpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaGFuZGxlUHJvcGVydHlSZXN1bHQociwgcGF5bG9hZCwga2V5LCBpbnB1dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFjYXRjaGFsbCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21zLmxlbmd0aCA/IFByb21pc2UuYWxsKHByb21zKS50aGVuKCgpPT5wYXlsb2FkKSA6IHBheWxvYWQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGhhbmRsZUNhdGNoYWxsKHByb21zLCBpbnB1dCwgcGF5bG9hZCwgY3R4LCBfbm9ybWFsaXplZC52YWx1ZSwgaW5zdCk7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RPYmplY3RKSVQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZE9iamVjdEpJVFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIC8vIHJlcXVpcmVzIGNhc3QgYmVjYXVzZSB0ZWNobmljYWxseSAkWm9kT2JqZWN0IGRvZXNuJ3QgZXh0ZW5kXG4gICAgJFpvZE9iamVjdC5pbml0KGluc3QsIGRlZik7XG4gICAgY29uc3Qgc3VwZXJQYXJzZSA9IGluc3QuX3pvZC5wYXJzZTtcbiAgICBjb25zdCBfbm9ybWFsaXplZCA9IHV0aWwuY2FjaGVkKCgpPT5ub3JtYWxpemVEZWYoZGVmKSk7XG4gICAgY29uc3QgZ2VuZXJhdGVGYXN0cGFzcyA9IChzaGFwZSk9PntcbiAgICAgICAgY29uc3QgZG9jID0gbmV3IERvYyhbXG4gICAgICAgICAgICBcInNoYXBlXCIsXG4gICAgICAgICAgICBcInBheWxvYWRcIixcbiAgICAgICAgICAgIFwiY3R4XCJcbiAgICAgICAgXSk7XG4gICAgICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSBfbm9ybWFsaXplZC52YWx1ZTtcbiAgICAgICAgY29uc3QgcGFyc2VTdHIgPSAoa2V5KT0+e1xuICAgICAgICAgICAgY29uc3QgayA9IHV0aWwuZXNjKGtleSk7XG4gICAgICAgICAgICByZXR1cm4gYHNoYXBlWyR7a31dLl96b2QucnVuKHsgdmFsdWU6IGlucHV0WyR7a31dLCBpc3N1ZXM6IFtdIH0sIGN0eClgO1xuICAgICAgICB9O1xuICAgICAgICBkb2Mud3JpdGUoYGNvbnN0IGlucHV0ID0gcGF5bG9hZC52YWx1ZTtgKTtcbiAgICAgICAgY29uc3QgaWRzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgbGV0IGNvdW50ZXIgPSAwO1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBub3JtYWxpemVkLmtleXMpe1xuICAgICAgICAgICAgaWRzW2tleV0gPSBga2V5XyR7Y291bnRlcisrfWA7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQTogcHJlc2VydmUga2V5IG9yZGVyIHtcbiAgICAgICAgZG9jLndyaXRlKGBjb25zdCBuZXdSZXN1bHQgPSB7fTtgKTtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2Ygbm9ybWFsaXplZC5rZXlzKXtcbiAgICAgICAgICAgIGNvbnN0IGlkID0gaWRzW2tleV07XG4gICAgICAgICAgICBjb25zdCBrID0gdXRpbC5lc2Moa2V5KTtcbiAgICAgICAgICAgIGRvYy53cml0ZShgY29uc3QgJHtpZH0gPSAke3BhcnNlU3RyKGtleSl9O2ApO1xuICAgICAgICAgICAgZG9jLndyaXRlKGBcbiAgICAgICAgaWYgKCR7aWR9Lmlzc3Vlcy5sZW5ndGgpIHtcbiAgICAgICAgICBwYXlsb2FkLmlzc3VlcyA9IHBheWxvYWQuaXNzdWVzLmNvbmNhdCgke2lkfS5pc3N1ZXMubWFwKGlzcyA9PiAoe1xuICAgICAgICAgICAgLi4uaXNzLFxuICAgICAgICAgICAgcGF0aDogaXNzLnBhdGggPyBbJHtrfSwgLi4uaXNzLnBhdGhdIDogWyR7a31dXG4gICAgICAgICAgfSkpKTtcbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgXG4gICAgICAgIGlmICgke2lkfS52YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaWYgKCR7a30gaW4gaW5wdXQpIHtcbiAgICAgICAgICAgIG5ld1Jlc3VsdFske2t9XSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbmV3UmVzdWx0WyR7a31dID0gJHtpZH0udmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICBgKTtcbiAgICAgICAgfVxuICAgICAgICBkb2Mud3JpdGUoYHBheWxvYWQudmFsdWUgPSBuZXdSZXN1bHQ7YCk7XG4gICAgICAgIGRvYy53cml0ZShgcmV0dXJuIHBheWxvYWQ7YCk7XG4gICAgICAgIGNvbnN0IGZuID0gZG9jLmNvbXBpbGUoKTtcbiAgICAgICAgcmV0dXJuIChwYXlsb2FkLCBjdHgpPT5mbihzaGFwZSwgcGF5bG9hZCwgY3R4KTtcbiAgICB9O1xuICAgIGxldCBmYXN0cGFzcztcbiAgICBjb25zdCBpc09iamVjdCA9IHV0aWwuaXNPYmplY3Q7XG4gICAgY29uc3Qgaml0ID0gIWNvcmUuZ2xvYmFsQ29uZmlnLmppdGxlc3M7XG4gICAgY29uc3QgYWxsb3dzRXZhbCA9IHV0aWwuYWxsb3dzRXZhbDtcbiAgICBjb25zdCBmYXN0RW5hYmxlZCA9IGppdCAmJiBhbGxvd3NFdmFsLnZhbHVlOyAvLyAmJiAhZGVmLmNhdGNoYWxsO1xuICAgIGNvbnN0IGNhdGNoYWxsID0gZGVmLmNhdGNoYWxsO1xuICAgIGxldCB2YWx1ZTtcbiAgICBpbnN0Ll96b2QucGFyc2UgPSAocGF5bG9hZCwgY3R4KT0+e1xuICAgICAgICB2YWx1ZSA/PyAodmFsdWUgPSBfbm9ybWFsaXplZC52YWx1ZSk7XG4gICAgICAgIGNvbnN0IGlucHV0ID0gcGF5bG9hZC52YWx1ZTtcbiAgICAgICAgaWYgKCFpc09iamVjdChpbnB1dCkpIHtcbiAgICAgICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBcIm9iamVjdFwiLFxuICAgICAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF90eXBlXCIsXG4gICAgICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICAgICAgaW5zdFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaml0ICYmIGZhc3RFbmFibGVkICYmIGN0eD8uYXN5bmMgPT09IGZhbHNlICYmIGN0eC5qaXRsZXNzICE9PSB0cnVlKSB7XG4gICAgICAgICAgICAvLyBhbHdheXMgc3luY2hyb25vdXNcbiAgICAgICAgICAgIGlmICghZmFzdHBhc3MpIGZhc3RwYXNzID0gZ2VuZXJhdGVGYXN0cGFzcyhkZWYuc2hhcGUpO1xuICAgICAgICAgICAgcGF5bG9hZCA9IGZhc3RwYXNzKHBheWxvYWQsIGN0eCk7XG4gICAgICAgICAgICBpZiAoIWNhdGNoYWxsKSByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgICAgIHJldHVybiBoYW5kbGVDYXRjaGFsbChbXSwgaW5wdXQsIHBheWxvYWQsIGN0eCwgdmFsdWUsIGluc3QpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzdXBlclBhcnNlKHBheWxvYWQsIGN0eCk7XG4gICAgfTtcbn0pO1xuZnVuY3Rpb24gaGFuZGxlVW5pb25SZXN1bHRzKHJlc3VsdHMsIGZpbmFsLCBpbnN0LCBjdHgpIHtcbiAgICBmb3IgKGNvbnN0IHJlc3VsdCBvZiByZXN1bHRzKXtcbiAgICAgICAgaWYgKHJlc3VsdC5pc3N1ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICBmaW5hbC52YWx1ZSA9IHJlc3VsdC52YWx1ZTtcbiAgICAgICAgICAgIHJldHVybiBmaW5hbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBub25hYm9ydGVkID0gcmVzdWx0cy5maWx0ZXIoKHIpPT4hdXRpbC5hYm9ydGVkKHIpKTtcbiAgICBpZiAobm9uYWJvcnRlZC5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgZmluYWwudmFsdWUgPSBub25hYm9ydGVkWzBdLnZhbHVlO1xuICAgICAgICByZXR1cm4gbm9uYWJvcnRlZFswXTtcbiAgICB9XG4gICAgZmluYWwuaXNzdWVzLnB1c2goe1xuICAgICAgICBjb2RlOiBcImludmFsaWRfdW5pb25cIixcbiAgICAgICAgaW5wdXQ6IGZpbmFsLnZhbHVlLFxuICAgICAgICBpbnN0LFxuICAgICAgICBlcnJvcnM6IHJlc3VsdHMubWFwKChyZXN1bHQpPT5yZXN1bHQuaXNzdWVzLm1hcCgoaXNzKT0+dXRpbC5maW5hbGl6ZUlzc3VlKGlzcywgY3R4LCBjb3JlLmNvbmZpZygpKSkpXG4gICAgfSk7XG4gICAgcmV0dXJuIGZpbmFsO1xufVxuZXhwb3J0IGNvbnN0ICRab2RVbmlvbiA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kVW5pb25cIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgdXRpbC5kZWZpbmVMYXp5KGluc3QuX3pvZCwgXCJvcHRpblwiLCAoKT0+ZGVmLm9wdGlvbnMuc29tZSgobyk9Pm8uX3pvZC5vcHRpbiA9PT0gXCJvcHRpb25hbFwiKSA/IFwib3B0aW9uYWxcIiA6IHVuZGVmaW5lZCk7XG4gICAgdXRpbC5kZWZpbmVMYXp5KGluc3QuX3pvZCwgXCJvcHRvdXRcIiwgKCk9PmRlZi5vcHRpb25zLnNvbWUoKG8pPT5vLl96b2Qub3B0b3V0ID09PSBcIm9wdGlvbmFsXCIpID8gXCJvcHRpb25hbFwiIDogdW5kZWZpbmVkKTtcbiAgICB1dGlsLmRlZmluZUxhenkoaW5zdC5fem9kLCBcInZhbHVlc1wiLCAoKT0+e1xuICAgICAgICBpZiAoZGVmLm9wdGlvbnMuZXZlcnkoKG8pPT5vLl96b2QudmFsdWVzKSkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBTZXQoZGVmLm9wdGlvbnMuZmxhdE1hcCgob3B0aW9uKT0+QXJyYXkuZnJvbShvcHRpb24uX3pvZC52YWx1ZXMpKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9KTtcbiAgICB1dGlsLmRlZmluZUxhenkoaW5zdC5fem9kLCBcInBhdHRlcm5cIiwgKCk9PntcbiAgICAgICAgaWYgKGRlZi5vcHRpb25zLmV2ZXJ5KChvKT0+by5fem9kLnBhdHRlcm4pKSB7XG4gICAgICAgICAgICBjb25zdCBwYXR0ZXJucyA9IGRlZi5vcHRpb25zLm1hcCgobyk9Pm8uX3pvZC5wYXR0ZXJuKTtcbiAgICAgICAgICAgIHJldHVybiBuZXcgUmVnRXhwKGBeKCR7cGF0dGVybnMubWFwKChwKT0+dXRpbC5jbGVhblJlZ2V4KHAuc291cmNlKSkuam9pbihcInxcIil9KSRgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH0pO1xuICAgIGNvbnN0IHNpbmdsZSA9IGRlZi5vcHRpb25zLmxlbmd0aCA9PT0gMTtcbiAgICBjb25zdCBmaXJzdCA9IGRlZi5vcHRpb25zWzBdLl96b2QucnVuO1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkLCBjdHgpPT57XG4gICAgICAgIGlmIChzaW5nbGUpIHtcbiAgICAgICAgICAgIHJldHVybiBmaXJzdChwYXlsb2FkLCBjdHgpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBhc3luYyA9IGZhbHNlO1xuICAgICAgICBjb25zdCByZXN1bHRzID0gW107XG4gICAgICAgIGZvciAoY29uc3Qgb3B0aW9uIG9mIGRlZi5vcHRpb25zKXtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IG9wdGlvbi5fem9kLnJ1bih7XG4gICAgICAgICAgICAgICAgdmFsdWU6IHBheWxvYWQudmFsdWUsXG4gICAgICAgICAgICAgICAgaXNzdWVzOiBbXVxuICAgICAgICAgICAgfSwgY3R4KTtcbiAgICAgICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0cy5wdXNoKHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgYXN5bmMgPSB0cnVlO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0Lmlzc3Vlcy5sZW5ndGggPT09IDApIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICAgICAgcmVzdWx0cy5wdXNoKHJlc3VsdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFhc3luYykgcmV0dXJuIGhhbmRsZVVuaW9uUmVzdWx0cyhyZXN1bHRzLCBwYXlsb2FkLCBpbnN0LCBjdHgpO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocmVzdWx0cykudGhlbigocmVzdWx0cyk9PntcbiAgICAgICAgICAgIHJldHVybiBoYW5kbGVVbmlvblJlc3VsdHMocmVzdWx0cywgcGF5bG9hZCwgaW5zdCwgY3R4KTtcbiAgICAgICAgfSk7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2REaXNjcmltaW5hdGVkVW5pb24gPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZERpc2NyaW1pbmF0ZWRVbmlvblwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RVbmlvbi5pbml0KGluc3QsIGRlZik7XG4gICAgY29uc3QgX3N1cGVyID0gaW5zdC5fem9kLnBhcnNlO1xuICAgIHV0aWwuZGVmaW5lTGF6eShpbnN0Ll96b2QsIFwicHJvcFZhbHVlc1wiLCAoKT0+e1xuICAgICAgICBjb25zdCBwcm9wVmFsdWVzID0ge307XG4gICAgICAgIGZvciAoY29uc3Qgb3B0aW9uIG9mIGRlZi5vcHRpb25zKXtcbiAgICAgICAgICAgIGNvbnN0IHB2ID0gb3B0aW9uLl96b2QucHJvcFZhbHVlcztcbiAgICAgICAgICAgIGlmICghcHYgfHwgT2JqZWN0LmtleXMocHYpLmxlbmd0aCA9PT0gMCkgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGRpc2NyaW1pbmF0ZWQgdW5pb24gb3B0aW9uIGF0IGluZGV4IFwiJHtkZWYub3B0aW9ucy5pbmRleE9mKG9wdGlvbil9XCJgKTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgW2ssIHZdIG9mIE9iamVjdC5lbnRyaWVzKHB2KSl7XG4gICAgICAgICAgICAgICAgaWYgKCFwcm9wVmFsdWVzW2tdKSBwcm9wVmFsdWVzW2tdID0gbmV3IFNldCgpO1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgdmFsIG9mIHYpe1xuICAgICAgICAgICAgICAgICAgICBwcm9wVmFsdWVzW2tdLmFkZCh2YWwpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcHJvcFZhbHVlcztcbiAgICB9KTtcbiAgICBjb25zdCBkaXNjID0gdXRpbC5jYWNoZWQoKCk9PntcbiAgICAgICAgY29uc3Qgb3B0cyA9IGRlZi5vcHRpb25zO1xuICAgICAgICBjb25zdCBtYXAgPSBuZXcgTWFwKCk7XG4gICAgICAgIGZvciAoY29uc3QgbyBvZiBvcHRzKXtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlcyA9IG8uX3pvZC5wcm9wVmFsdWVzPy5bZGVmLmRpc2NyaW1pbmF0b3JdO1xuICAgICAgICAgICAgaWYgKCF2YWx1ZXMgfHwgdmFsdWVzLnNpemUgPT09IDApIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBkaXNjcmltaW5hdGVkIHVuaW9uIG9wdGlvbiBhdCBpbmRleCBcIiR7ZGVmLm9wdGlvbnMuaW5kZXhPZihvKX1cImApO1xuICAgICAgICAgICAgZm9yIChjb25zdCB2IG9mIHZhbHVlcyl7XG4gICAgICAgICAgICAgICAgaWYgKG1hcC5oYXModikpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBEdXBsaWNhdGUgZGlzY3JpbWluYXRvciB2YWx1ZSBcIiR7U3RyaW5nKHYpfVwiYCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG1hcC5zZXQodiwgbyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1hcDtcbiAgICB9KTtcbiAgICBpbnN0Ll96b2QucGFyc2UgPSAocGF5bG9hZCwgY3R4KT0+e1xuICAgICAgICBjb25zdCBpbnB1dCA9IHBheWxvYWQudmFsdWU7XG4gICAgICAgIGlmICghdXRpbC5pc09iamVjdChpbnB1dCkpIHtcbiAgICAgICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF90eXBlXCIsXG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IFwib2JqZWN0XCIsXG4gICAgICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICAgICAgaW5zdFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBvcHQgPSBkaXNjLnZhbHVlLmdldChpbnB1dD8uW2RlZi5kaXNjcmltaW5hdG9yXSk7XG4gICAgICAgIGlmIChvcHQpIHtcbiAgICAgICAgICAgIHJldHVybiBvcHQuX3pvZC5ydW4ocGF5bG9hZCwgY3R4KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGVmLnVuaW9uRmFsbGJhY2spIHtcbiAgICAgICAgICAgIHJldHVybiBfc3VwZXIocGF5bG9hZCwgY3R4KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBubyBtYXRjaGluZyBkaXNjcmltaW5hdG9yXG4gICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX3VuaW9uXCIsXG4gICAgICAgICAgICBlcnJvcnM6IFtdLFxuICAgICAgICAgICAgbm90ZTogXCJObyBtYXRjaGluZyBkaXNjcmltaW5hdG9yXCIsXG4gICAgICAgICAgICBkaXNjcmltaW5hdG9yOiBkZWYuZGlzY3JpbWluYXRvcixcbiAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgcGF0aDogW1xuICAgICAgICAgICAgICAgIGRlZi5kaXNjcmltaW5hdG9yXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgaW5zdFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RJbnRlcnNlY3Rpb24gPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZEludGVyc2VjdGlvblwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0Ll96b2QucGFyc2UgPSAocGF5bG9hZCwgY3R4KT0+e1xuICAgICAgICBjb25zdCBpbnB1dCA9IHBheWxvYWQudmFsdWU7XG4gICAgICAgIGNvbnN0IGxlZnQgPSBkZWYubGVmdC5fem9kLnJ1bih7XG4gICAgICAgICAgICB2YWx1ZTogaW5wdXQsXG4gICAgICAgICAgICBpc3N1ZXM6IFtdXG4gICAgICAgIH0sIGN0eCk7XG4gICAgICAgIGNvbnN0IHJpZ2h0ID0gZGVmLnJpZ2h0Ll96b2QucnVuKHtcbiAgICAgICAgICAgIHZhbHVlOiBpbnB1dCxcbiAgICAgICAgICAgIGlzc3VlczogW11cbiAgICAgICAgfSwgY3R4KTtcbiAgICAgICAgY29uc3QgYXN5bmMgPSBsZWZ0IGluc3RhbmNlb2YgUHJvbWlzZSB8fCByaWdodCBpbnN0YW5jZW9mIFByb21pc2U7XG4gICAgICAgIGlmIChhc3luYykge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFtcbiAgICAgICAgICAgICAgICBsZWZ0LFxuICAgICAgICAgICAgICAgIHJpZ2h0XG4gICAgICAgICAgICBdKS50aGVuKChbbGVmdCwgcmlnaHRdKT0+e1xuICAgICAgICAgICAgICAgIHJldHVybiBoYW5kbGVJbnRlcnNlY3Rpb25SZXN1bHRzKHBheWxvYWQsIGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBoYW5kbGVJbnRlcnNlY3Rpb25SZXN1bHRzKHBheWxvYWQsIGxlZnQsIHJpZ2h0KTtcbiAgICB9O1xufSk7XG5mdW5jdGlvbiBtZXJnZVZhbHVlcyhhLCBiKSB7XG4gICAgLy8gY29uc3QgYVR5cGUgPSBwYXJzZS50KGEpO1xuICAgIC8vIGNvbnN0IGJUeXBlID0gcGFyc2UudChiKTtcbiAgICBpZiAoYSA9PT0gYikge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdmFsaWQ6IHRydWUsXG4gICAgICAgICAgICBkYXRhOiBhXG4gICAgICAgIH07XG4gICAgfVxuICAgIGlmIChhIGluc3RhbmNlb2YgRGF0ZSAmJiBiIGluc3RhbmNlb2YgRGF0ZSAmJiArYSA9PT0gK2IpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHZhbGlkOiB0cnVlLFxuICAgICAgICAgICAgZGF0YTogYVxuICAgICAgICB9O1xuICAgIH1cbiAgICBpZiAodXRpbC5pc1BsYWluT2JqZWN0KGEpICYmIHV0aWwuaXNQbGFpbk9iamVjdChiKSkge1xuICAgICAgICBjb25zdCBiS2V5cyA9IE9iamVjdC5rZXlzKGIpO1xuICAgICAgICBjb25zdCBzaGFyZWRLZXlzID0gT2JqZWN0LmtleXMoYSkuZmlsdGVyKChrZXkpPT5iS2V5cy5pbmRleE9mKGtleSkgIT09IC0xKTtcbiAgICAgICAgY29uc3QgbmV3T2JqID0ge1xuICAgICAgICAgICAgLi4uYSxcbiAgICAgICAgICAgIC4uLmJcbiAgICAgICAgfTtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2Ygc2hhcmVkS2V5cyl7XG4gICAgICAgICAgICBjb25zdCBzaGFyZWRWYWx1ZSA9IG1lcmdlVmFsdWVzKGFba2V5XSwgYltrZXldKTtcbiAgICAgICAgICAgIGlmICghc2hhcmVkVmFsdWUudmFsaWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICB2YWxpZDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIG1lcmdlRXJyb3JQYXRoOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgICAgICAgICAuLi5zaGFyZWRWYWx1ZS5tZXJnZUVycm9yUGF0aFxuICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG5ld09ialtrZXldID0gc2hhcmVkVmFsdWUuZGF0YTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdmFsaWQ6IHRydWUsXG4gICAgICAgICAgICBkYXRhOiBuZXdPYmpcbiAgICAgICAgfTtcbiAgICB9XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoYSkgJiYgQXJyYXkuaXNBcnJheShiKSkge1xuICAgICAgICBpZiAoYS5sZW5ndGggIT09IGIubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHZhbGlkOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBtZXJnZUVycm9yUGF0aDogW11cbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmV3QXJyYXkgPSBbXTtcbiAgICAgICAgZm9yKGxldCBpbmRleCA9IDA7IGluZGV4IDwgYS5sZW5ndGg7IGluZGV4Kyspe1xuICAgICAgICAgICAgY29uc3QgaXRlbUEgPSBhW2luZGV4XTtcbiAgICAgICAgICAgIGNvbnN0IGl0ZW1CID0gYltpbmRleF07XG4gICAgICAgICAgICBjb25zdCBzaGFyZWRWYWx1ZSA9IG1lcmdlVmFsdWVzKGl0ZW1BLCBpdGVtQik7XG4gICAgICAgICAgICBpZiAoIXNoYXJlZFZhbHVlLnZhbGlkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsaWQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBtZXJnZUVycm9yUGF0aDogW1xuICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXgsXG4gICAgICAgICAgICAgICAgICAgICAgICAuLi5zaGFyZWRWYWx1ZS5tZXJnZUVycm9yUGF0aFxuICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG5ld0FycmF5LnB1c2goc2hhcmVkVmFsdWUuZGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHZhbGlkOiB0cnVlLFxuICAgICAgICAgICAgZGF0YTogbmV3QXJyYXlcbiAgICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgdmFsaWQ6IGZhbHNlLFxuICAgICAgICBtZXJnZUVycm9yUGF0aDogW11cbiAgICB9O1xufVxuZnVuY3Rpb24gaGFuZGxlSW50ZXJzZWN0aW9uUmVzdWx0cyhyZXN1bHQsIGxlZnQsIHJpZ2h0KSB7XG4gICAgaWYgKGxlZnQuaXNzdWVzLmxlbmd0aCkge1xuICAgICAgICByZXN1bHQuaXNzdWVzLnB1c2goLi4ubGVmdC5pc3N1ZXMpO1xuICAgIH1cbiAgICBpZiAocmlnaHQuaXNzdWVzLmxlbmd0aCkge1xuICAgICAgICByZXN1bHQuaXNzdWVzLnB1c2goLi4ucmlnaHQuaXNzdWVzKTtcbiAgICB9XG4gICAgaWYgKHV0aWwuYWJvcnRlZChyZXN1bHQpKSByZXR1cm4gcmVzdWx0O1xuICAgIGNvbnN0IG1lcmdlZCA9IG1lcmdlVmFsdWVzKGxlZnQudmFsdWUsIHJpZ2h0LnZhbHVlKTtcbiAgICBpZiAoIW1lcmdlZC52YWxpZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVubWVyZ2FibGUgaW50ZXJzZWN0aW9uLiBFcnJvciBwYXRoOiBgICsgYCR7SlNPTi5zdHJpbmdpZnkobWVyZ2VkLm1lcmdlRXJyb3JQYXRoKX1gKTtcbiAgICB9XG4gICAgcmVzdWx0LnZhbHVlID0gbWVyZ2VkLmRhdGE7XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbmV4cG9ydCBjb25zdCAkWm9kVHVwbGUgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZFR1cGxlXCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGNvbnN0IGl0ZW1zID0gZGVmLml0ZW1zO1xuICAgIGNvbnN0IG9wdFN0YXJ0ID0gaXRlbXMubGVuZ3RoIC0gW1xuICAgICAgICAuLi5pdGVtc1xuICAgIF0ucmV2ZXJzZSgpLmZpbmRJbmRleCgoaXRlbSk9Pml0ZW0uX3pvZC5vcHRpbiAhPT0gXCJvcHRpb25hbFwiKTtcbiAgICBpbnN0Ll96b2QucGFyc2UgPSAocGF5bG9hZCwgY3R4KT0+e1xuICAgICAgICBjb25zdCBpbnB1dCA9IHBheWxvYWQudmFsdWU7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShpbnB1dCkpIHtcbiAgICAgICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgICAgIGluc3QsXG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IFwidHVwbGVcIixcbiAgICAgICAgICAgICAgICBjb2RlOiBcImludmFsaWRfdHlwZVwiXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgICAgICB9XG4gICAgICAgIHBheWxvYWQudmFsdWUgPSBbXTtcbiAgICAgICAgY29uc3QgcHJvbXMgPSBbXTtcbiAgICAgICAgaWYgKCFkZWYucmVzdCkge1xuICAgICAgICAgICAgY29uc3QgdG9vQmlnID0gaW5wdXQubGVuZ3RoID4gaXRlbXMubGVuZ3RoO1xuICAgICAgICAgICAgY29uc3QgdG9vU21hbGwgPSBpbnB1dC5sZW5ndGggPCBvcHRTdGFydCAtIDE7XG4gICAgICAgICAgICBpZiAodG9vQmlnIHx8IHRvb1NtYWxsKSB7XG4gICAgICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIC4uLnRvb0JpZyA/IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFwidG9vX2JpZ1wiLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWF4aW11bTogaXRlbXMubGVuZ3RoXG4gICAgICAgICAgICAgICAgICAgIH0gOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBcInRvb19zbWFsbFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWluaW11bTogaXRlbXMubGVuZ3RoXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgICAgICAgICBvcmlnaW46IFwiYXJyYXlcIlxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxldCBpID0gLTE7XG4gICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcyl7XG4gICAgICAgICAgICBpKys7XG4gICAgICAgICAgICBpZiAoaSA+PSBpbnB1dC5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBpZiAoaSA+PSBvcHRTdGFydCkgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBpdGVtLl96b2QucnVuKHtcbiAgICAgICAgICAgICAgICB2YWx1ZTogaW5wdXRbaV0sXG4gICAgICAgICAgICAgICAgaXNzdWVzOiBbXVxuICAgICAgICAgICAgfSwgY3R4KTtcbiAgICAgICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICAgICAgcHJvbXMucHVzaChyZXN1bHQudGhlbigocmVzdWx0KT0+aGFuZGxlVHVwbGVSZXN1bHQocmVzdWx0LCBwYXlsb2FkLCBpKSkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBoYW5kbGVUdXBsZVJlc3VsdChyZXN1bHQsIHBheWxvYWQsIGkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChkZWYucmVzdCkge1xuICAgICAgICAgICAgY29uc3QgcmVzdCA9IGlucHV0LnNsaWNlKGl0ZW1zLmxlbmd0aCk7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGVsIG9mIHJlc3Qpe1xuICAgICAgICAgICAgICAgIGkrKztcbiAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSBkZWYucmVzdC5fem9kLnJ1bih7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiBlbCxcbiAgICAgICAgICAgICAgICAgICAgaXNzdWVzOiBbXVxuICAgICAgICAgICAgICAgIH0sIGN0eCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgcHJvbXMucHVzaChyZXN1bHQudGhlbigocmVzdWx0KT0+aGFuZGxlVHVwbGVSZXN1bHQocmVzdWx0LCBwYXlsb2FkLCBpKSkpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGhhbmRsZVR1cGxlUmVzdWx0KHJlc3VsdCwgcGF5bG9hZCwgaSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9tcy5sZW5ndGgpIHJldHVybiBQcm9taXNlLmFsbChwcm9tcykudGhlbigoKT0+cGF5bG9hZCk7XG4gICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgIH07XG59KTtcbmZ1bmN0aW9uIGhhbmRsZVR1cGxlUmVzdWx0KHJlc3VsdCwgZmluYWwsIGluZGV4KSB7XG4gICAgaWYgKHJlc3VsdC5pc3N1ZXMubGVuZ3RoKSB7XG4gICAgICAgIGZpbmFsLmlzc3Vlcy5wdXNoKC4uLnV0aWwucHJlZml4SXNzdWVzKGluZGV4LCByZXN1bHQuaXNzdWVzKSk7XG4gICAgfVxuICAgIGZpbmFsLnZhbHVlW2luZGV4XSA9IHJlc3VsdC52YWx1ZTtcbn1cbmV4cG9ydCBjb25zdCAkWm9kUmVjb3JkID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RSZWNvcmRcIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5fem9kLnBhcnNlID0gKHBheWxvYWQsIGN0eCk9PntcbiAgICAgICAgY29uc3QgaW5wdXQgPSBwYXlsb2FkLnZhbHVlO1xuICAgICAgICBpZiAoIXV0aWwuaXNQbGFpbk9iamVjdChpbnB1dCkpIHtcbiAgICAgICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBcInJlY29yZFwiLFxuICAgICAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF90eXBlXCIsXG4gICAgICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICAgICAgaW5zdFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwcm9tcyA9IFtdO1xuICAgICAgICBpZiAoZGVmLmtleVR5cGUuX3pvZC52YWx1ZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlcyA9IGRlZi5rZXlUeXBlLl96b2QudmFsdWVzO1xuICAgICAgICAgICAgcGF5bG9hZC52YWx1ZSA9IHt9O1xuICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgdmFsdWVzKXtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGtleSA9PT0gXCJzdHJpbmdcIiB8fCB0eXBlb2Yga2V5ID09PSBcIm51bWJlclwiIHx8IHR5cGVvZiBrZXkgPT09IFwic3ltYm9sXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gZGVmLnZhbHVlVHlwZS5fem9kLnJ1bih7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogaW5wdXRba2V5XSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzc3VlczogW11cbiAgICAgICAgICAgICAgICAgICAgfSwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb21zLnB1c2gocmVzdWx0LnRoZW4oKHJlc3VsdCk9PntcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0Lmlzc3Vlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCguLi51dGlsLnByZWZpeElzc3VlcyhrZXksIHJlc3VsdC5pc3N1ZXMpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF5bG9hZC52YWx1ZVtrZXldID0gcmVzdWx0LnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5pc3N1ZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCguLi51dGlsLnByZWZpeElzc3VlcyhrZXksIHJlc3VsdC5pc3N1ZXMpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHBheWxvYWQudmFsdWVba2V5XSA9IHJlc3VsdC52YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCB1bnJlY29nbml6ZWQ7XG4gICAgICAgICAgICBmb3IoY29uc3Qga2V5IGluIGlucHV0KXtcbiAgICAgICAgICAgICAgICBpZiAoIXZhbHVlcy5oYXMoa2V5KSkge1xuICAgICAgICAgICAgICAgICAgICB1bnJlY29nbml6ZWQgPSB1bnJlY29nbml6ZWQgPz8gW107XG4gICAgICAgICAgICAgICAgICAgIHVucmVjb2duaXplZC5wdXNoKGtleSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHVucmVjb2duaXplZCAmJiB1bnJlY29nbml6ZWQubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBjb2RlOiBcInVucmVjb2duaXplZF9rZXlzXCIsXG4gICAgICAgICAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgICAgICAgICBrZXlzOiB1bnJlY29nbml6ZWRcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBheWxvYWQudmFsdWUgPSB7fTtcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IG9mIFJlZmxlY3Qub3duS2V5cyhpbnB1dCkpe1xuICAgICAgICAgICAgICAgIGlmIChrZXkgPT09IFwiX19wcm90b19fXCIpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIGNvbnN0IGtleVJlc3VsdCA9IGRlZi5rZXlUeXBlLl96b2QucnVuKHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGtleSxcbiAgICAgICAgICAgICAgICAgICAgaXNzdWVzOiBbXVxuICAgICAgICAgICAgICAgIH0sIGN0eCk7XG4gICAgICAgICAgICAgICAgaWYgKGtleVJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQXN5bmMgc2NoZW1hcyBub3Qgc3VwcG9ydGVkIGluIG9iamVjdCBrZXlzIGN1cnJlbnRseVwiKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGtleVJlc3VsdC5pc3N1ZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX2tleVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luOiBcInJlY29yZFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgaXNzdWVzOiBrZXlSZXN1bHQuaXNzdWVzLm1hcCgoaXNzKT0+dXRpbC5maW5hbGl6ZUlzc3VlKGlzcywgY3R4LCBjb3JlLmNvbmZpZygpKSksXG4gICAgICAgICAgICAgICAgICAgICAgICBpbnB1dDoga2V5LFxuICAgICAgICAgICAgICAgICAgICAgICAgcGF0aDogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleVxuICAgICAgICAgICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGluc3RcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHBheWxvYWQudmFsdWVba2V5UmVzdWx0LnZhbHVlXSA9IGtleVJlc3VsdC52YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGRlZi52YWx1ZVR5cGUuX3pvZC5ydW4oe1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogaW5wdXRba2V5XSxcbiAgICAgICAgICAgICAgICAgICAgaXNzdWVzOiBbXVxuICAgICAgICAgICAgICAgIH0sIGN0eCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgcHJvbXMucHVzaChyZXN1bHQudGhlbigocmVzdWx0KT0+e1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5pc3N1ZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCguLi51dGlsLnByZWZpeElzc3VlcyhrZXksIHJlc3VsdC5pc3N1ZXMpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHBheWxvYWQudmFsdWVba2V5UmVzdWx0LnZhbHVlXSA9IHJlc3VsdC52YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQuaXNzdWVzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCguLi51dGlsLnByZWZpeElzc3VlcyhrZXksIHJlc3VsdC5pc3N1ZXMpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBwYXlsb2FkLnZhbHVlW2tleVJlc3VsdC52YWx1ZV0gPSByZXN1bHQudmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9tcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9tcykudGhlbigoKT0+cGF5bG9hZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RNYXAgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZE1hcFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0Ll96b2QucGFyc2UgPSAocGF5bG9hZCwgY3R4KT0+e1xuICAgICAgICBjb25zdCBpbnB1dCA9IHBheWxvYWQudmFsdWU7XG4gICAgICAgIGlmICghKGlucHV0IGluc3RhbmNlb2YgTWFwKSkge1xuICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IFwibWFwXCIsXG4gICAgICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX3R5cGVcIixcbiAgICAgICAgICAgICAgICBpbnB1dCxcbiAgICAgICAgICAgICAgICBpbnN0XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHByb21zID0gW107XG4gICAgICAgIHBheWxvYWQudmFsdWUgPSBuZXcgTWFwKCk7XG4gICAgICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIGlucHV0KXtcbiAgICAgICAgICAgIGNvbnN0IGtleVJlc3VsdCA9IGRlZi5rZXlUeXBlLl96b2QucnVuKHtcbiAgICAgICAgICAgICAgICB2YWx1ZToga2V5LFxuICAgICAgICAgICAgICAgIGlzc3VlczogW11cbiAgICAgICAgICAgIH0sIGN0eCk7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZVJlc3VsdCA9IGRlZi52YWx1ZVR5cGUuX3pvZC5ydW4oe1xuICAgICAgICAgICAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICBpc3N1ZXM6IFtdXG4gICAgICAgICAgICB9LCBjdHgpO1xuICAgICAgICAgICAgaWYgKGtleVJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UgfHwgdmFsdWVSZXN1bHQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICAgICAgcHJvbXMucHVzaChQcm9taXNlLmFsbChbXG4gICAgICAgICAgICAgICAgICAgIGtleVJlc3VsdCxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWVSZXN1bHRcbiAgICAgICAgICAgICAgICBdKS50aGVuKChba2V5UmVzdWx0LCB2YWx1ZVJlc3VsdF0pPT57XG4gICAgICAgICAgICAgICAgICAgIGhhbmRsZU1hcFJlc3VsdChrZXlSZXN1bHQsIHZhbHVlUmVzdWx0LCBwYXlsb2FkLCBrZXksIGlucHV0LCBpbnN0LCBjdHgpO1xuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaGFuZGxlTWFwUmVzdWx0KGtleVJlc3VsdCwgdmFsdWVSZXN1bHQsIHBheWxvYWQsIGtleSwgaW5wdXQsIGluc3QsIGN0eCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb21zLmxlbmd0aCkgcmV0dXJuIFByb21pc2UuYWxsKHByb21zKS50aGVuKCgpPT5wYXlsb2FkKTtcbiAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgfTtcbn0pO1xuZnVuY3Rpb24gaGFuZGxlTWFwUmVzdWx0KGtleVJlc3VsdCwgdmFsdWVSZXN1bHQsIGZpbmFsLCBrZXksIGlucHV0LCBpbnN0LCBjdHgpIHtcbiAgICBpZiAoa2V5UmVzdWx0Lmlzc3Vlcy5sZW5ndGgpIHtcbiAgICAgICAgaWYgKHV0aWwucHJvcGVydHlLZXlUeXBlcy5oYXModHlwZW9mIGtleSkpIHtcbiAgICAgICAgICAgIGZpbmFsLmlzc3Vlcy5wdXNoKC4uLnV0aWwucHJlZml4SXNzdWVzKGtleSwga2V5UmVzdWx0Lmlzc3VlcykpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZmluYWwuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF9rZXlcIixcbiAgICAgICAgICAgICAgICBvcmlnaW46IFwibWFwXCIsXG4gICAgICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICAgICAgaW5zdCxcbiAgICAgICAgICAgICAgICBpc3N1ZXM6IGtleVJlc3VsdC5pc3N1ZXMubWFwKChpc3MpPT51dGlsLmZpbmFsaXplSXNzdWUoaXNzLCBjdHgsIGNvcmUuY29uZmlnKCkpKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKHZhbHVlUmVzdWx0Lmlzc3Vlcy5sZW5ndGgpIHtcbiAgICAgICAgaWYgKHV0aWwucHJvcGVydHlLZXlUeXBlcy5oYXModHlwZW9mIGtleSkpIHtcbiAgICAgICAgICAgIGZpbmFsLmlzc3Vlcy5wdXNoKC4uLnV0aWwucHJlZml4SXNzdWVzKGtleSwgdmFsdWVSZXN1bHQuaXNzdWVzKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmaW5hbC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgb3JpZ2luOiBcIm1hcFwiLFxuICAgICAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF9lbGVtZW50XCIsXG4gICAgICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICAgICAgaW5zdCxcbiAgICAgICAgICAgICAgICBrZXk6IGtleSxcbiAgICAgICAgICAgICAgICBpc3N1ZXM6IHZhbHVlUmVzdWx0Lmlzc3Vlcy5tYXAoKGlzcyk9PnV0aWwuZmluYWxpemVJc3N1ZShpc3MsIGN0eCwgY29yZS5jb25maWcoKSkpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBmaW5hbC52YWx1ZS5zZXQoa2V5UmVzdWx0LnZhbHVlLCB2YWx1ZVJlc3VsdC52YWx1ZSk7XG59XG5leHBvcnQgY29uc3QgJFpvZFNldCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kU2V0XCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkLCBjdHgpPT57XG4gICAgICAgIGNvbnN0IGlucHV0ID0gcGF5bG9hZC52YWx1ZTtcbiAgICAgICAgaWYgKCEoaW5wdXQgaW5zdGFuY2VvZiBTZXQpKSB7XG4gICAgICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICBpbnB1dCxcbiAgICAgICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBcInNldFwiLFxuICAgICAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF90eXBlXCJcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcHJvbXMgPSBbXTtcbiAgICAgICAgcGF5bG9hZC52YWx1ZSA9IG5ldyBTZXQoKTtcbiAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIGlucHV0KXtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGRlZi52YWx1ZVR5cGUuX3pvZC5ydW4oe1xuICAgICAgICAgICAgICAgIHZhbHVlOiBpdGVtLFxuICAgICAgICAgICAgICAgIGlzc3VlczogW11cbiAgICAgICAgICAgIH0sIGN0eCk7XG4gICAgICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgICAgIHByb21zLnB1c2gocmVzdWx0LnRoZW4oKHJlc3VsdCk9PmhhbmRsZVNldFJlc3VsdChyZXN1bHQsIHBheWxvYWQpKSk7XG4gICAgICAgICAgICB9IGVsc2UgaGFuZGxlU2V0UmVzdWx0KHJlc3VsdCwgcGF5bG9hZCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb21zLmxlbmd0aCkgcmV0dXJuIFByb21pc2UuYWxsKHByb21zKS50aGVuKCgpPT5wYXlsb2FkKTtcbiAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgfTtcbn0pO1xuZnVuY3Rpb24gaGFuZGxlU2V0UmVzdWx0KHJlc3VsdCwgZmluYWwpIHtcbiAgICBpZiAocmVzdWx0Lmlzc3Vlcy5sZW5ndGgpIHtcbiAgICAgICAgZmluYWwuaXNzdWVzLnB1c2goLi4ucmVzdWx0Lmlzc3Vlcyk7XG4gICAgfVxuICAgIGZpbmFsLnZhbHVlLmFkZChyZXN1bHQudmFsdWUpO1xufVxuZXhwb3J0IGNvbnN0ICRab2RFbnVtID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RFbnVtXCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGNvbnN0IHZhbHVlcyA9IHV0aWwuZ2V0RW51bVZhbHVlcyhkZWYuZW50cmllcyk7XG4gICAgY29uc3QgdmFsdWVzU2V0ID0gbmV3IFNldCh2YWx1ZXMpO1xuICAgIGluc3QuX3pvZC52YWx1ZXMgPSB2YWx1ZXNTZXQ7XG4gICAgaW5zdC5fem9kLnBhdHRlcm4gPSBuZXcgUmVnRXhwKGBeKCR7dmFsdWVzLmZpbHRlcigoayk9PnV0aWwucHJvcGVydHlLZXlUeXBlcy5oYXModHlwZW9mIGspKS5tYXAoKG8pPT50eXBlb2YgbyA9PT0gXCJzdHJpbmdcIiA/IHV0aWwuZXNjYXBlUmVnZXgobykgOiBvLnRvU3RyaW5nKCkpLmpvaW4oXCJ8XCIpfSkkYCk7XG4gICAgaW5zdC5fem9kLnBhcnNlID0gKHBheWxvYWQsIF9jdHgpPT57XG4gICAgICAgIGNvbnN0IGlucHV0ID0gcGF5bG9hZC52YWx1ZTtcbiAgICAgICAgaWYgKHZhbHVlc1NldC5oYXMoaW5wdXQpKSB7XG4gICAgICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgfVxuICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF92YWx1ZVwiLFxuICAgICAgICAgICAgdmFsdWVzLFxuICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICBpbnN0XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZExpdGVyYWwgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZExpdGVyYWxcIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaWYgKGRlZi52YWx1ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBjcmVhdGUgbGl0ZXJhbCBzY2hlbWEgd2l0aCBubyB2YWxpZCB2YWx1ZXNcIik7XG4gICAgfVxuICAgIGluc3QuX3pvZC52YWx1ZXMgPSBuZXcgU2V0KGRlZi52YWx1ZXMpO1xuICAgIGluc3QuX3pvZC5wYXR0ZXJuID0gbmV3IFJlZ0V4cChgXigke2RlZi52YWx1ZXMubWFwKChvKT0+dHlwZW9mIG8gPT09IFwic3RyaW5nXCIgPyB1dGlsLmVzY2FwZVJlZ2V4KG8pIDogbyA/IHV0aWwuZXNjYXBlUmVnZXgoby50b1N0cmluZygpKSA6IFN0cmluZyhvKSkuam9pbihcInxcIil9KSRgKTtcbiAgICBpbnN0Ll96b2QucGFyc2UgPSAocGF5bG9hZCwgX2N0eCk9PntcbiAgICAgICAgY29uc3QgaW5wdXQgPSBwYXlsb2FkLnZhbHVlO1xuICAgICAgICBpZiAoaW5zdC5fem9kLnZhbHVlcy5oYXMoaW5wdXQpKSB7XG4gICAgICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgfVxuICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF92YWx1ZVwiLFxuICAgICAgICAgICAgdmFsdWVzOiBkZWYudmFsdWVzLFxuICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICBpbnN0XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZEZpbGUgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZEZpbGVcIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5fem9kLnBhcnNlID0gKHBheWxvYWQsIF9jdHgpPT57XG4gICAgICAgIGNvbnN0IGlucHV0ID0gcGF5bG9hZC52YWx1ZTtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICBpZiAoaW5wdXQgaW5zdGFuY2VvZiBGaWxlKSByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICBleHBlY3RlZDogXCJmaWxlXCIsXG4gICAgICAgICAgICBjb2RlOiBcImludmFsaWRfdHlwZVwiLFxuICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICBpbnN0XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZFRyYW5zZm9ybSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kVHJhbnNmb3JtXCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkLCBjdHgpPT57XG4gICAgICAgIGlmIChjdHguZGlyZWN0aW9uID09PSBcImJhY2t3YXJkXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBjb3JlLiRab2RFbmNvZGVFcnJvcihpbnN0LmNvbnN0cnVjdG9yLm5hbWUpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IF9vdXQgPSBkZWYudHJhbnNmb3JtKHBheWxvYWQudmFsdWUsIHBheWxvYWQpO1xuICAgICAgICBpZiAoY3R4LmFzeW5jKSB7XG4gICAgICAgICAgICBjb25zdCBvdXRwdXQgPSBfb3V0IGluc3RhbmNlb2YgUHJvbWlzZSA/IF9vdXQgOiBQcm9taXNlLnJlc29sdmUoX291dCk7XG4gICAgICAgICAgICByZXR1cm4gb3V0cHV0LnRoZW4oKG91dHB1dCk9PntcbiAgICAgICAgICAgICAgICBwYXlsb2FkLnZhbHVlID0gb3V0cHV0O1xuICAgICAgICAgICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKF9vdXQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgY29yZS4kWm9kQXN5bmNFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIHBheWxvYWQudmFsdWUgPSBfb3V0O1xuICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICB9O1xufSk7XG5mdW5jdGlvbiBoYW5kbGVPcHRpb25hbFJlc3VsdChyZXN1bHQsIGlucHV0KSB7XG4gICAgaWYgKHJlc3VsdC5pc3N1ZXMubGVuZ3RoICYmIGlucHV0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGlzc3VlczogW10sXG4gICAgICAgICAgICB2YWx1ZTogdW5kZWZpbmVkXG4gICAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59XG5leHBvcnQgY29uc3QgJFpvZE9wdGlvbmFsID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RPcHRpb25hbFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0Ll96b2Qub3B0aW4gPSBcIm9wdGlvbmFsXCI7XG4gICAgaW5zdC5fem9kLm9wdG91dCA9IFwib3B0aW9uYWxcIjtcbiAgICB1dGlsLmRlZmluZUxhenkoaW5zdC5fem9kLCBcInZhbHVlc1wiLCAoKT0+e1xuICAgICAgICByZXR1cm4gZGVmLmlubmVyVHlwZS5fem9kLnZhbHVlcyA/IG5ldyBTZXQoW1xuICAgICAgICAgICAgLi4uZGVmLmlubmVyVHlwZS5fem9kLnZhbHVlcyxcbiAgICAgICAgICAgIHVuZGVmaW5lZFxuICAgICAgICBdKSA6IHVuZGVmaW5lZDtcbiAgICB9KTtcbiAgICB1dGlsLmRlZmluZUxhenkoaW5zdC5fem9kLCBcInBhdHRlcm5cIiwgKCk9PntcbiAgICAgICAgY29uc3QgcGF0dGVybiA9IGRlZi5pbm5lclR5cGUuX3pvZC5wYXR0ZXJuO1xuICAgICAgICByZXR1cm4gcGF0dGVybiA/IG5ldyBSZWdFeHAoYF4oJHt1dGlsLmNsZWFuUmVnZXgocGF0dGVybi5zb3VyY2UpfSk/JGApIDogdW5kZWZpbmVkO1xuICAgIH0pO1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkLCBjdHgpPT57XG4gICAgICAgIGlmIChkZWYuaW5uZXJUeXBlLl96b2Qub3B0aW4gPT09IFwib3B0aW9uYWxcIikge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gZGVmLmlubmVyVHlwZS5fem9kLnJ1bihwYXlsb2FkLCBjdHgpO1xuICAgICAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHJldHVybiByZXN1bHQudGhlbigocik9PmhhbmRsZU9wdGlvbmFsUmVzdWx0KHIsIHBheWxvYWQudmFsdWUpKTtcbiAgICAgICAgICAgIHJldHVybiBoYW5kbGVPcHRpb25hbFJlc3VsdChyZXN1bHQsIHBheWxvYWQudmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwYXlsb2FkLnZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkZWYuaW5uZXJUeXBlLl96b2QucnVuKHBheWxvYWQsIGN0eCk7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2ROdWxsYWJsZSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kTnVsbGFibGVcIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgdXRpbC5kZWZpbmVMYXp5KGluc3QuX3pvZCwgXCJvcHRpblwiLCAoKT0+ZGVmLmlubmVyVHlwZS5fem9kLm9wdGluKTtcbiAgICB1dGlsLmRlZmluZUxhenkoaW5zdC5fem9kLCBcIm9wdG91dFwiLCAoKT0+ZGVmLmlubmVyVHlwZS5fem9kLm9wdG91dCk7XG4gICAgdXRpbC5kZWZpbmVMYXp5KGluc3QuX3pvZCwgXCJwYXR0ZXJuXCIsICgpPT57XG4gICAgICAgIGNvbnN0IHBhdHRlcm4gPSBkZWYuaW5uZXJUeXBlLl96b2QucGF0dGVybjtcbiAgICAgICAgcmV0dXJuIHBhdHRlcm4gPyBuZXcgUmVnRXhwKGBeKCR7dXRpbC5jbGVhblJlZ2V4KHBhdHRlcm4uc291cmNlKX18bnVsbCkkYCkgOiB1bmRlZmluZWQ7XG4gICAgfSk7XG4gICAgdXRpbC5kZWZpbmVMYXp5KGluc3QuX3pvZCwgXCJ2YWx1ZXNcIiwgKCk9PntcbiAgICAgICAgcmV0dXJuIGRlZi5pbm5lclR5cGUuX3pvZC52YWx1ZXMgPyBuZXcgU2V0KFtcbiAgICAgICAgICAgIC4uLmRlZi5pbm5lclR5cGUuX3pvZC52YWx1ZXMsXG4gICAgICAgICAgICBudWxsXG4gICAgICAgIF0pIDogdW5kZWZpbmVkO1xuICAgIH0pO1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkLCBjdHgpPT57XG4gICAgICAgIC8vIEZvcndhcmQgZGlyZWN0aW9uIChkZWNvZGUpOiBhbGxvdyBudWxsIHRvIHBhc3MgdGhyb3VnaFxuICAgICAgICBpZiAocGF5bG9hZC52YWx1ZSA9PT0gbnVsbCkgcmV0dXJuIHBheWxvYWQ7XG4gICAgICAgIHJldHVybiBkZWYuaW5uZXJUeXBlLl96b2QucnVuKHBheWxvYWQsIGN0eCk7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2REZWZhdWx0ID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2REZWZhdWx0XCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIC8vIGluc3QuX3pvZC5xaW4gPSBcInRydWVcIjtcbiAgICBpbnN0Ll96b2Qub3B0aW4gPSBcIm9wdGlvbmFsXCI7XG4gICAgdXRpbC5kZWZpbmVMYXp5KGluc3QuX3pvZCwgXCJ2YWx1ZXNcIiwgKCk9PmRlZi5pbm5lclR5cGUuX3pvZC52YWx1ZXMpO1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkLCBjdHgpPT57XG4gICAgICAgIGlmIChjdHguZGlyZWN0aW9uID09PSBcImJhY2t3YXJkXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBkZWYuaW5uZXJUeXBlLl96b2QucnVuKHBheWxvYWQsIGN0eCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRm9yd2FyZCBkaXJlY3Rpb24gKGRlY29kZSk6IGFwcGx5IGRlZmF1bHRzIGZvciB1bmRlZmluZWQgaW5wdXRcbiAgICAgICAgaWYgKHBheWxvYWQudmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcGF5bG9hZC52YWx1ZSA9IGRlZi5kZWZhdWx0VmFsdWU7XG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqICRab2REZWZhdWx0IHJldHVybnMgdGhlIGRlZmF1bHQgdmFsdWUgaW1tZWRpYXRlbHkgaW4gZm9yd2FyZCBkaXJlY3Rpb24uXG4gICAgICAgICAgICAgKiBJdCBkb2Vzbid0IHBhc3MgdGhlIGRlZmF1bHQgdmFsdWUgaW50byB0aGUgdmFsaWRhdG9yIChcInByZWZhdWx0XCIpLiBUaGVyZSdzIG5vIHJlYXNvbiB0byBwYXNzIHRoZSBkZWZhdWx0IHZhbHVlIHRocm91Z2ggdmFsaWRhdGlvbi4gVGhlIHZhbGlkaXR5IG9mIHRoZSBkZWZhdWx0IGlzIGVuZm9yY2VkIGJ5IFR5cGVTY3JpcHQgc3RhdGljYWxseS4gT3RoZXJ3aXNlLCBpdCdzIHRoZSByZXNwb25zaWJpbGl0eSBvZiB0aGUgdXNlciB0byBlbnN1cmUgdGhlIGRlZmF1bHQgaXMgdmFsaWQuIEluIHRoZSBjYXNlIG9mIHBpcGVzIHdpdGggZGl2ZXJnZW50IGluL291dCB0eXBlcywgeW91IGNhbiBzcGVjaWZ5IHRoZSBkZWZhdWx0IG9uIHRoZSBgaW5gIHNjaGVtYSBvZiB5b3VyIFpvZFBpcGUgdG8gc2V0IGEgXCJwcmVmYXVsdFwiIGZvciB0aGUgcGlwZS4gICAqLyByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgfVxuICAgICAgICAvLyBGb3J3YXJkIGRpcmVjdGlvbjogY29udGludWUgd2l0aCBkZWZhdWx0IGhhbmRsaW5nXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGRlZi5pbm5lclR5cGUuX3pvZC5ydW4ocGF5bG9hZCwgY3R4KTtcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQudGhlbigocmVzdWx0KT0+aGFuZGxlRGVmYXVsdFJlc3VsdChyZXN1bHQsIGRlZikpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBoYW5kbGVEZWZhdWx0UmVzdWx0KHJlc3VsdCwgZGVmKTtcbiAgICB9O1xufSk7XG5mdW5jdGlvbiBoYW5kbGVEZWZhdWx0UmVzdWx0KHBheWxvYWQsIGRlZikge1xuICAgIGlmIChwYXlsb2FkLnZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcGF5bG9hZC52YWx1ZSA9IGRlZi5kZWZhdWx0VmFsdWU7XG4gICAgfVxuICAgIHJldHVybiBwYXlsb2FkO1xufVxuZXhwb3J0IGNvbnN0ICRab2RQcmVmYXVsdCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kUHJlZmF1bHRcIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5fem9kLm9wdGluID0gXCJvcHRpb25hbFwiO1xuICAgIHV0aWwuZGVmaW5lTGF6eShpbnN0Ll96b2QsIFwidmFsdWVzXCIsICgpPT5kZWYuaW5uZXJUeXBlLl96b2QudmFsdWVzKTtcbiAgICBpbnN0Ll96b2QucGFyc2UgPSAocGF5bG9hZCwgY3R4KT0+e1xuICAgICAgICBpZiAoY3R4LmRpcmVjdGlvbiA9PT0gXCJiYWNrd2FyZFwiKSB7XG4gICAgICAgICAgICByZXR1cm4gZGVmLmlubmVyVHlwZS5fem9kLnJ1bihwYXlsb2FkLCBjdHgpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEZvcndhcmQgZGlyZWN0aW9uIChkZWNvZGUpOiBhcHBseSBwcmVmYXVsdCBmb3IgdW5kZWZpbmVkIGlucHV0XG4gICAgICAgIGlmIChwYXlsb2FkLnZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHBheWxvYWQudmFsdWUgPSBkZWYuZGVmYXVsdFZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkZWYuaW5uZXJUeXBlLl96b2QucnVuKHBheWxvYWQsIGN0eCk7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2ROb25PcHRpb25hbCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kTm9uT3B0aW9uYWxcIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgdXRpbC5kZWZpbmVMYXp5KGluc3QuX3pvZCwgXCJ2YWx1ZXNcIiwgKCk9PntcbiAgICAgICAgY29uc3QgdiA9IGRlZi5pbm5lclR5cGUuX3pvZC52YWx1ZXM7XG4gICAgICAgIHJldHVybiB2ID8gbmV3IFNldChbXG4gICAgICAgICAgICAuLi52XG4gICAgICAgIF0uZmlsdGVyKCh4KT0+eCAhPT0gdW5kZWZpbmVkKSkgOiB1bmRlZmluZWQ7XG4gICAgfSk7XG4gICAgaW5zdC5fem9kLnBhcnNlID0gKHBheWxvYWQsIGN0eCk9PntcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gZGVmLmlubmVyVHlwZS5fem9kLnJ1bihwYXlsb2FkLCBjdHgpO1xuICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC50aGVuKChyZXN1bHQpPT5oYW5kbGVOb25PcHRpb25hbFJlc3VsdChyZXN1bHQsIGluc3QpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaGFuZGxlTm9uT3B0aW9uYWxSZXN1bHQocmVzdWx0LCBpbnN0KTtcbiAgICB9O1xufSk7XG5mdW5jdGlvbiBoYW5kbGVOb25PcHRpb25hbFJlc3VsdChwYXlsb2FkLCBpbnN0KSB7XG4gICAgaWYgKCFwYXlsb2FkLmlzc3Vlcy5sZW5ndGggJiYgcGF5bG9hZC52YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX3R5cGVcIixcbiAgICAgICAgICAgIGV4cGVjdGVkOiBcIm5vbm9wdGlvbmFsXCIsXG4gICAgICAgICAgICBpbnB1dDogcGF5bG9hZC52YWx1ZSxcbiAgICAgICAgICAgIGluc3RcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBwYXlsb2FkO1xufVxuZXhwb3J0IGNvbnN0ICRab2RTdWNjZXNzID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RTdWNjZXNzXCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkLCBjdHgpPT57XG4gICAgICAgIGlmIChjdHguZGlyZWN0aW9uID09PSBcImJhY2t3YXJkXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBjb3JlLiRab2RFbmNvZGVFcnJvcihcIlpvZFN1Y2Nlc3NcIik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gZGVmLmlubmVyVHlwZS5fem9kLnJ1bihwYXlsb2FkLCBjdHgpO1xuICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC50aGVuKChyZXN1bHQpPT57XG4gICAgICAgICAgICAgICAgcGF5bG9hZC52YWx1ZSA9IHJlc3VsdC5pc3N1ZXMubGVuZ3RoID09PSAwO1xuICAgICAgICAgICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcGF5bG9hZC52YWx1ZSA9IHJlc3VsdC5pc3N1ZXMubGVuZ3RoID09PSAwO1xuICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZENhdGNoID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RDYXRjaFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICB1dGlsLmRlZmluZUxhenkoaW5zdC5fem9kLCBcIm9wdGluXCIsICgpPT5kZWYuaW5uZXJUeXBlLl96b2Qub3B0aW4pO1xuICAgIHV0aWwuZGVmaW5lTGF6eShpbnN0Ll96b2QsIFwib3B0b3V0XCIsICgpPT5kZWYuaW5uZXJUeXBlLl96b2Qub3B0b3V0KTtcbiAgICB1dGlsLmRlZmluZUxhenkoaW5zdC5fem9kLCBcInZhbHVlc1wiLCAoKT0+ZGVmLmlubmVyVHlwZS5fem9kLnZhbHVlcyk7XG4gICAgaW5zdC5fem9kLnBhcnNlID0gKHBheWxvYWQsIGN0eCk9PntcbiAgICAgICAgaWYgKGN0eC5kaXJlY3Rpb24gPT09IFwiYmFja3dhcmRcIikge1xuICAgICAgICAgICAgcmV0dXJuIGRlZi5pbm5lclR5cGUuX3pvZC5ydW4ocGF5bG9hZCwgY3R4KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBGb3J3YXJkIGRpcmVjdGlvbiAoZGVjb2RlKTogYXBwbHkgY2F0Y2ggbG9naWNcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gZGVmLmlubmVyVHlwZS5fem9kLnJ1bihwYXlsb2FkLCBjdHgpO1xuICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC50aGVuKChyZXN1bHQpPT57XG4gICAgICAgICAgICAgICAgcGF5bG9hZC52YWx1ZSA9IHJlc3VsdC52YWx1ZTtcbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0Lmlzc3Vlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgcGF5bG9hZC52YWx1ZSA9IGRlZi5jYXRjaFZhbHVlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC4uLnBheWxvYWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvcjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzc3VlczogcmVzdWx0Lmlzc3Vlcy5tYXAoKGlzcyk9PnV0aWwuZmluYWxpemVJc3N1ZShpc3MsIGN0eCwgY29yZS5jb25maWcoKSkpXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQ6IHBheWxvYWQudmFsdWVcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHBheWxvYWQuaXNzdWVzID0gW107XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcGF5bG9hZC52YWx1ZSA9IHJlc3VsdC52YWx1ZTtcbiAgICAgICAgaWYgKHJlc3VsdC5pc3N1ZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICBwYXlsb2FkLnZhbHVlID0gZGVmLmNhdGNoVmFsdWUoe1xuICAgICAgICAgICAgICAgIC4uLnBheWxvYWQsXG4gICAgICAgICAgICAgICAgZXJyb3I6IHtcbiAgICAgICAgICAgICAgICAgICAgaXNzdWVzOiByZXN1bHQuaXNzdWVzLm1hcCgoaXNzKT0+dXRpbC5maW5hbGl6ZUlzc3VlKGlzcywgY3R4LCBjb3JlLmNvbmZpZygpKSlcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGlucHV0OiBwYXlsb2FkLnZhbHVlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHBheWxvYWQuaXNzdWVzID0gW107XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2ROYU4gPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZE5hTlwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0Ll96b2QucGFyc2UgPSAocGF5bG9hZCwgX2N0eCk9PntcbiAgICAgICAgaWYgKHR5cGVvZiBwYXlsb2FkLnZhbHVlICE9PSBcIm51bWJlclwiIHx8ICFOdW1iZXIuaXNOYU4ocGF5bG9hZC52YWx1ZSkpIHtcbiAgICAgICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgICAgIGlucHV0OiBwYXlsb2FkLnZhbHVlLFxuICAgICAgICAgICAgICAgIGluc3QsXG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IFwibmFuXCIsXG4gICAgICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX3R5cGVcIlxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZFBpcGUgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZFBpcGVcIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgdXRpbC5kZWZpbmVMYXp5KGluc3QuX3pvZCwgXCJ2YWx1ZXNcIiwgKCk9PmRlZi5pbi5fem9kLnZhbHVlcyk7XG4gICAgdXRpbC5kZWZpbmVMYXp5KGluc3QuX3pvZCwgXCJvcHRpblwiLCAoKT0+ZGVmLmluLl96b2Qub3B0aW4pO1xuICAgIHV0aWwuZGVmaW5lTGF6eShpbnN0Ll96b2QsIFwib3B0b3V0XCIsICgpPT5kZWYub3V0Ll96b2Qub3B0b3V0KTtcbiAgICB1dGlsLmRlZmluZUxhenkoaW5zdC5fem9kLCBcInByb3BWYWx1ZXNcIiwgKCk9PmRlZi5pbi5fem9kLnByb3BWYWx1ZXMpO1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkLCBjdHgpPT57XG4gICAgICAgIGlmIChjdHguZGlyZWN0aW9uID09PSBcImJhY2t3YXJkXCIpIHtcbiAgICAgICAgICAgIGNvbnN0IHJpZ2h0ID0gZGVmLm91dC5fem9kLnJ1bihwYXlsb2FkLCBjdHgpO1xuICAgICAgICAgICAgaWYgKHJpZ2h0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiByaWdodC50aGVuKChyaWdodCk9PmhhbmRsZVBpcGVSZXN1bHQocmlnaHQsIGRlZi5pbiwgY3R4KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gaGFuZGxlUGlwZVJlc3VsdChyaWdodCwgZGVmLmluLCBjdHgpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGxlZnQgPSBkZWYuaW4uX3pvZC5ydW4ocGF5bG9hZCwgY3R4KTtcbiAgICAgICAgaWYgKGxlZnQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm4gbGVmdC50aGVuKChsZWZ0KT0+aGFuZGxlUGlwZVJlc3VsdChsZWZ0LCBkZWYub3V0LCBjdHgpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaGFuZGxlUGlwZVJlc3VsdChsZWZ0LCBkZWYub3V0LCBjdHgpO1xuICAgIH07XG59KTtcbmZ1bmN0aW9uIGhhbmRsZVBpcGVSZXN1bHQobGVmdCwgbmV4dCwgY3R4KSB7XG4gICAgaWYgKGxlZnQuaXNzdWVzLmxlbmd0aCkge1xuICAgICAgICAvLyBwcmV2ZW50IGZ1cnRoZXIgY2hlY2tzXG4gICAgICAgIGxlZnQuYWJvcnRlZCA9IHRydWU7XG4gICAgICAgIHJldHVybiBsZWZ0O1xuICAgIH1cbiAgICByZXR1cm4gbmV4dC5fem9kLnJ1bih7XG4gICAgICAgIHZhbHVlOiBsZWZ0LnZhbHVlLFxuICAgICAgICBpc3N1ZXM6IGxlZnQuaXNzdWVzXG4gICAgfSwgY3R4KTtcbn1cbmV4cG9ydCBjb25zdCAkWm9kQ29kZWMgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZENvZGVjXCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIHV0aWwuZGVmaW5lTGF6eShpbnN0Ll96b2QsIFwidmFsdWVzXCIsICgpPT5kZWYuaW4uX3pvZC52YWx1ZXMpO1xuICAgIHV0aWwuZGVmaW5lTGF6eShpbnN0Ll96b2QsIFwib3B0aW5cIiwgKCk9PmRlZi5pbi5fem9kLm9wdGluKTtcbiAgICB1dGlsLmRlZmluZUxhenkoaW5zdC5fem9kLCBcIm9wdG91dFwiLCAoKT0+ZGVmLm91dC5fem9kLm9wdG91dCk7XG4gICAgdXRpbC5kZWZpbmVMYXp5KGluc3QuX3pvZCwgXCJwcm9wVmFsdWVzXCIsICgpPT5kZWYuaW4uX3pvZC5wcm9wVmFsdWVzKTtcbiAgICBpbnN0Ll96b2QucGFyc2UgPSAocGF5bG9hZCwgY3R4KT0+e1xuICAgICAgICBjb25zdCBkaXJlY3Rpb24gPSBjdHguZGlyZWN0aW9uIHx8IFwiZm9yd2FyZFwiO1xuICAgICAgICBpZiAoZGlyZWN0aW9uID09PSBcImZvcndhcmRcIikge1xuICAgICAgICAgICAgY29uc3QgbGVmdCA9IGRlZi5pbi5fem9kLnJ1bihwYXlsb2FkLCBjdHgpO1xuICAgICAgICAgICAgaWYgKGxlZnQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGxlZnQudGhlbigobGVmdCk9PmhhbmRsZUNvZGVjQVJlc3VsdChsZWZ0LCBkZWYsIGN0eCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGhhbmRsZUNvZGVjQVJlc3VsdChsZWZ0LCBkZWYsIGN0eCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCByaWdodCA9IGRlZi5vdXQuX3pvZC5ydW4ocGF5bG9hZCwgY3R4KTtcbiAgICAgICAgICAgIGlmIChyaWdodCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmlnaHQudGhlbigocmlnaHQpPT5oYW5kbGVDb2RlY0FSZXN1bHQocmlnaHQsIGRlZiwgY3R4KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gaGFuZGxlQ29kZWNBUmVzdWx0KHJpZ2h0LCBkZWYsIGN0eCk7XG4gICAgICAgIH1cbiAgICB9O1xufSk7XG5mdW5jdGlvbiBoYW5kbGVDb2RlY0FSZXN1bHQocmVzdWx0LCBkZWYsIGN0eCkge1xuICAgIGlmIChyZXN1bHQuaXNzdWVzLmxlbmd0aCkge1xuICAgICAgICAvLyBwcmV2ZW50IGZ1cnRoZXIgY2hlY2tzXG4gICAgICAgIHJlc3VsdC5hYm9ydGVkID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgY29uc3QgZGlyZWN0aW9uID0gY3R4LmRpcmVjdGlvbiB8fCBcImZvcndhcmRcIjtcbiAgICBpZiAoZGlyZWN0aW9uID09PSBcImZvcndhcmRcIikge1xuICAgICAgICBjb25zdCB0cmFuc2Zvcm1lZCA9IGRlZi50cmFuc2Zvcm0ocmVzdWx0LnZhbHVlLCByZXN1bHQpO1xuICAgICAgICBpZiAodHJhbnNmb3JtZWQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJhbnNmb3JtZWQudGhlbigodmFsdWUpPT5oYW5kbGVDb2RlY1R4UmVzdWx0KHJlc3VsdCwgdmFsdWUsIGRlZi5vdXQsIGN0eCkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBoYW5kbGVDb2RlY1R4UmVzdWx0KHJlc3VsdCwgdHJhbnNmb3JtZWQsIGRlZi5vdXQsIGN0eCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgdHJhbnNmb3JtZWQgPSBkZWYucmV2ZXJzZVRyYW5zZm9ybShyZXN1bHQudmFsdWUsIHJlc3VsdCk7XG4gICAgICAgIGlmICh0cmFuc2Zvcm1lZCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybiB0cmFuc2Zvcm1lZC50aGVuKCh2YWx1ZSk9PmhhbmRsZUNvZGVjVHhSZXN1bHQocmVzdWx0LCB2YWx1ZSwgZGVmLmluLCBjdHgpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaGFuZGxlQ29kZWNUeFJlc3VsdChyZXN1bHQsIHRyYW5zZm9ybWVkLCBkZWYuaW4sIGN0eCk7XG4gICAgfVxufVxuZnVuY3Rpb24gaGFuZGxlQ29kZWNUeFJlc3VsdChsZWZ0LCB2YWx1ZSwgbmV4dFNjaGVtYSwgY3R4KSB7XG4gICAgLy8gQ2hlY2sgaWYgdHJhbnNmb3JtIGFkZGVkIGFueSBpc3N1ZXNcbiAgICBpZiAobGVmdC5pc3N1ZXMubGVuZ3RoKSB7XG4gICAgICAgIGxlZnQuYWJvcnRlZCA9IHRydWU7XG4gICAgICAgIHJldHVybiBsZWZ0O1xuICAgIH1cbiAgICByZXR1cm4gbmV4dFNjaGVtYS5fem9kLnJ1bih7XG4gICAgICAgIHZhbHVlLFxuICAgICAgICBpc3N1ZXM6IGxlZnQuaXNzdWVzXG4gICAgfSwgY3R4KTtcbn1cbmV4cG9ydCBjb25zdCAkWm9kUmVhZG9ubHkgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZFJlYWRvbmx5XCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIHV0aWwuZGVmaW5lTGF6eShpbnN0Ll96b2QsIFwicHJvcFZhbHVlc1wiLCAoKT0+ZGVmLmlubmVyVHlwZS5fem9kLnByb3BWYWx1ZXMpO1xuICAgIHV0aWwuZGVmaW5lTGF6eShpbnN0Ll96b2QsIFwidmFsdWVzXCIsICgpPT5kZWYuaW5uZXJUeXBlLl96b2QudmFsdWVzKTtcbiAgICB1dGlsLmRlZmluZUxhenkoaW5zdC5fem9kLCBcIm9wdGluXCIsICgpPT5kZWYuaW5uZXJUeXBlLl96b2Qub3B0aW4pO1xuICAgIHV0aWwuZGVmaW5lTGF6eShpbnN0Ll96b2QsIFwib3B0b3V0XCIsICgpPT5kZWYuaW5uZXJUeXBlLl96b2Qub3B0b3V0KTtcbiAgICBpbnN0Ll96b2QucGFyc2UgPSAocGF5bG9hZCwgY3R4KT0+e1xuICAgICAgICBpZiAoY3R4LmRpcmVjdGlvbiA9PT0gXCJiYWNrd2FyZFwiKSB7XG4gICAgICAgICAgICByZXR1cm4gZGVmLmlubmVyVHlwZS5fem9kLnJ1bihwYXlsb2FkLCBjdHgpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGRlZi5pbm5lclR5cGUuX3pvZC5ydW4ocGF5bG9hZCwgY3R4KTtcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQudGhlbihoYW5kbGVSZWFkb25seVJlc3VsdCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGhhbmRsZVJlYWRvbmx5UmVzdWx0KHJlc3VsdCk7XG4gICAgfTtcbn0pO1xuZnVuY3Rpb24gaGFuZGxlUmVhZG9ubHlSZXN1bHQocGF5bG9hZCkge1xuICAgIHBheWxvYWQudmFsdWUgPSBPYmplY3QuZnJlZXplKHBheWxvYWQudmFsdWUpO1xuICAgIHJldHVybiBwYXlsb2FkO1xufVxuZXhwb3J0IGNvbnN0ICRab2RUZW1wbGF0ZUxpdGVyYWwgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZFRlbXBsYXRlTGl0ZXJhbFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBjb25zdCByZWdleFBhcnRzID0gW107XG4gICAgZm9yIChjb25zdCBwYXJ0IG9mIGRlZi5wYXJ0cyl7XG4gICAgICAgIGlmICh0eXBlb2YgcGFydCA9PT0gXCJvYmplY3RcIiAmJiBwYXJ0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAvLyBpcyBab2Qgc2NoZW1hXG4gICAgICAgICAgICBpZiAoIXBhcnQuX3pvZC5wYXR0ZXJuKSB7XG4gICAgICAgICAgICAgICAgLy8gaWYgKCFzb3VyY2UpXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHRlbXBsYXRlIGxpdGVyYWwgcGFydCwgbm8gcGF0dGVybiBmb3VuZDogJHtbXG4gICAgICAgICAgICAgICAgICAgIC4uLnBhcnQuX3pvZC50cmFpdHNcbiAgICAgICAgICAgICAgICBdLnNoaWZ0KCl9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBzb3VyY2UgPSBwYXJ0Ll96b2QucGF0dGVybiBpbnN0YW5jZW9mIFJlZ0V4cCA/IHBhcnQuX3pvZC5wYXR0ZXJuLnNvdXJjZSA6IHBhcnQuX3pvZC5wYXR0ZXJuO1xuICAgICAgICAgICAgaWYgKCFzb3VyY2UpIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCB0ZW1wbGF0ZSBsaXRlcmFsIHBhcnQ6ICR7cGFydC5fem9kLnRyYWl0c31gKTtcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0ID0gc291cmNlLnN0YXJ0c1dpdGgoXCJeXCIpID8gMSA6IDA7XG4gICAgICAgICAgICBjb25zdCBlbmQgPSBzb3VyY2UuZW5kc1dpdGgoXCIkXCIpID8gc291cmNlLmxlbmd0aCAtIDEgOiBzb3VyY2UubGVuZ3RoO1xuICAgICAgICAgICAgcmVnZXhQYXJ0cy5wdXNoKHNvdXJjZS5zbGljZShzdGFydCwgZW5kKSk7XG4gICAgICAgIH0gZWxzZSBpZiAocGFydCA9PT0gbnVsbCB8fCB1dGlsLnByaW1pdGl2ZVR5cGVzLmhhcyh0eXBlb2YgcGFydCkpIHtcbiAgICAgICAgICAgIHJlZ2V4UGFydHMucHVzaCh1dGlsLmVzY2FwZVJlZ2V4KGAke3BhcnR9YCkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHRlbXBsYXRlIGxpdGVyYWwgcGFydDogJHtwYXJ0fWApO1xuICAgICAgICB9XG4gICAgfVxuICAgIGluc3QuX3pvZC5wYXR0ZXJuID0gbmV3IFJlZ0V4cChgXiR7cmVnZXhQYXJ0cy5qb2luKFwiXCIpfSRgKTtcbiAgICBpbnN0Ll96b2QucGFyc2UgPSAocGF5bG9hZCwgX2N0eCk9PntcbiAgICAgICAgaWYgKHR5cGVvZiBwYXlsb2FkLnZhbHVlICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICBpbnB1dDogcGF5bG9hZC52YWx1ZSxcbiAgICAgICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBcInRlbXBsYXRlX2xpdGVyYWxcIixcbiAgICAgICAgICAgICAgICBjb2RlOiBcImludmFsaWRfdHlwZVwiXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgICAgICB9XG4gICAgICAgIGluc3QuX3pvZC5wYXR0ZXJuLmxhc3RJbmRleCA9IDA7XG4gICAgICAgIGlmICghaW5zdC5fem9kLnBhdHRlcm4udGVzdChwYXlsb2FkLnZhbHVlKSkge1xuICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgaW5wdXQ6IHBheWxvYWQudmFsdWUsXG4gICAgICAgICAgICAgICAgaW5zdCxcbiAgICAgICAgICAgICAgICBjb2RlOiBcImludmFsaWRfZm9ybWF0XCIsXG4gICAgICAgICAgICAgICAgZm9ybWF0OiBkZWYuZm9ybWF0ID8/IFwidGVtcGxhdGVfbGl0ZXJhbFwiLFxuICAgICAgICAgICAgICAgIHBhdHRlcm46IGluc3QuX3pvZC5wYXR0ZXJuLnNvdXJjZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZEZ1bmN0aW9uID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RGdW5jdGlvblwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0Ll9kZWYgPSBkZWY7XG4gICAgaW5zdC5fem9kLmRlZiA9IGRlZjtcbiAgICBpbnN0LmltcGxlbWVudCA9IChmdW5jKT0+e1xuICAgICAgICBpZiAodHlwZW9mIGZ1bmMgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiaW1wbGVtZW50KCkgbXVzdCBiZSBjYWxsZWQgd2l0aCBhIGZ1bmN0aW9uXCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiguLi5hcmdzKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJzZWRBcmdzID0gaW5zdC5fZGVmLmlucHV0ID8gcGFyc2UoaW5zdC5fZGVmLmlucHV0LCBhcmdzKSA6IGFyZ3M7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBSZWZsZWN0LmFwcGx5KGZ1bmMsIHRoaXMsIHBhcnNlZEFyZ3MpO1xuICAgICAgICAgICAgaWYgKGluc3QuX2RlZi5vdXRwdXQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2UoaW5zdC5fZGVmLm91dHB1dCwgcmVzdWx0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH07XG4gICAgfTtcbiAgICBpbnN0LmltcGxlbWVudEFzeW5jID0gKGZ1bmMpPT57XG4gICAgICAgIGlmICh0eXBlb2YgZnVuYyAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJpbXBsZW1lbnRBc3luYygpIG11c3QgYmUgY2FsbGVkIHdpdGggYSBmdW5jdGlvblwiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYXN5bmMgZnVuY3Rpb24oLi4uYXJncykge1xuICAgICAgICAgICAgY29uc3QgcGFyc2VkQXJncyA9IGluc3QuX2RlZi5pbnB1dCA/IGF3YWl0IHBhcnNlQXN5bmMoaW5zdC5fZGVmLmlucHV0LCBhcmdzKSA6IGFyZ3M7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBSZWZsZWN0LmFwcGx5KGZ1bmMsIHRoaXMsIHBhcnNlZEFyZ3MpO1xuICAgICAgICAgICAgaWYgKGluc3QuX2RlZi5vdXRwdXQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXdhaXQgcGFyc2VBc3luYyhpbnN0Ll9kZWYub3V0cHV0LCByZXN1bHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkLCBfY3R4KT0+e1xuICAgICAgICBpZiAodHlwZW9mIHBheWxvYWQudmFsdWUgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX3R5cGVcIixcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogXCJmdW5jdGlvblwiLFxuICAgICAgICAgICAgICAgIGlucHV0OiBwYXlsb2FkLnZhbHVlLFxuICAgICAgICAgICAgICAgIGluc3RcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQ2hlY2sgaWYgb3V0cHV0IGlzIGEgcHJvbWlzZSB0eXBlIHRvIGRldGVybWluZSBpZiB3ZSBzaG91bGQgdXNlIGFzeW5jIGltcGxlbWVudGF0aW9uXG4gICAgICAgIGNvbnN0IGhhc1Byb21pc2VPdXRwdXQgPSBpbnN0Ll9kZWYub3V0cHV0ICYmIGluc3QuX2RlZi5vdXRwdXQuX3pvZC5kZWYudHlwZSA9PT0gXCJwcm9taXNlXCI7XG4gICAgICAgIGlmIChoYXNQcm9taXNlT3V0cHV0KSB7XG4gICAgICAgICAgICBwYXlsb2FkLnZhbHVlID0gaW5zdC5pbXBsZW1lbnRBc3luYyhwYXlsb2FkLnZhbHVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBheWxvYWQudmFsdWUgPSBpbnN0LmltcGxlbWVudChwYXlsb2FkLnZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICB9O1xuICAgIGluc3QuaW5wdXQgPSAoLi4uYXJncyk9PntcbiAgICAgICAgY29uc3QgRiA9IGluc3QuY29uc3RydWN0b3I7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGFyZ3NbMF0pKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEYoe1xuICAgICAgICAgICAgICAgIHR5cGU6IFwiZnVuY3Rpb25cIixcbiAgICAgICAgICAgICAgICBpbnB1dDogbmV3ICRab2RUdXBsZSh7XG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IFwidHVwbGVcIixcbiAgICAgICAgICAgICAgICAgICAgaXRlbXM6IGFyZ3NbMF0sXG4gICAgICAgICAgICAgICAgICAgIHJlc3Q6IGFyZ3NbMV1cbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICBvdXRwdXQ6IGluc3QuX2RlZi5vdXRwdXRcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgRih7XG4gICAgICAgICAgICB0eXBlOiBcImZ1bmN0aW9uXCIsXG4gICAgICAgICAgICBpbnB1dDogYXJnc1swXSxcbiAgICAgICAgICAgIG91dHB1dDogaW5zdC5fZGVmLm91dHB1dFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIGluc3Qub3V0cHV0ID0gKG91dHB1dCk9PntcbiAgICAgICAgY29uc3QgRiA9IGluc3QuY29uc3RydWN0b3I7XG4gICAgICAgIHJldHVybiBuZXcgRih7XG4gICAgICAgICAgICB0eXBlOiBcImZ1bmN0aW9uXCIsXG4gICAgICAgICAgICBpbnB1dDogaW5zdC5fZGVmLmlucHV0LFxuICAgICAgICAgICAgb3V0cHV0XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgcmV0dXJuIGluc3Q7XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kUHJvbWlzZSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kUHJvbWlzZVwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0Ll96b2QucGFyc2UgPSAocGF5bG9hZCwgY3R4KT0+e1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHBheWxvYWQudmFsdWUpLnRoZW4oKGlubmVyKT0+ZGVmLmlubmVyVHlwZS5fem9kLnJ1bih7XG4gICAgICAgICAgICAgICAgdmFsdWU6IGlubmVyLFxuICAgICAgICAgICAgICAgIGlzc3VlczogW11cbiAgICAgICAgICAgIH0sIGN0eCkpO1xuICAgIH07XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kTGF6eSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kTGF6eVwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICAvLyBsZXQgX2lubmVyVHlwZSE6IGFueTtcbiAgICAvLyB1dGlsLmRlZmluZUxhenkoZGVmLCBcImdldHRlclwiLCAoKSA9PiB7XG4gICAgLy8gICBpZiAoIV9pbm5lclR5cGUpIHtcbiAgICAvLyAgICAgX2lubmVyVHlwZSA9IGRlZi5nZXR0ZXIoKTtcbiAgICAvLyAgIH1cbiAgICAvLyAgIHJldHVybiAoKSA9PiBfaW5uZXJUeXBlO1xuICAgIC8vIH0pO1xuICAgIHV0aWwuZGVmaW5lTGF6eShpbnN0Ll96b2QsIFwiaW5uZXJUeXBlXCIsICgpPT5kZWYuZ2V0dGVyKCkpO1xuICAgIHV0aWwuZGVmaW5lTGF6eShpbnN0Ll96b2QsIFwicGF0dGVyblwiLCAoKT0+aW5zdC5fem9kLmlubmVyVHlwZS5fem9kLnBhdHRlcm4pO1xuICAgIHV0aWwuZGVmaW5lTGF6eShpbnN0Ll96b2QsIFwicHJvcFZhbHVlc1wiLCAoKT0+aW5zdC5fem9kLmlubmVyVHlwZS5fem9kLnByb3BWYWx1ZXMpO1xuICAgIHV0aWwuZGVmaW5lTGF6eShpbnN0Ll96b2QsIFwib3B0aW5cIiwgKCk9Pmluc3QuX3pvZC5pbm5lclR5cGUuX3pvZC5vcHRpbiA/PyB1bmRlZmluZWQpO1xuICAgIHV0aWwuZGVmaW5lTGF6eShpbnN0Ll96b2QsIFwib3B0b3V0XCIsICgpPT5pbnN0Ll96b2QuaW5uZXJUeXBlLl96b2Qub3B0b3V0ID8/IHVuZGVmaW5lZCk7XG4gICAgaW5zdC5fem9kLnBhcnNlID0gKHBheWxvYWQsIGN0eCk9PntcbiAgICAgICAgY29uc3QgaW5uZXIgPSBpbnN0Ll96b2QuaW5uZXJUeXBlO1xuICAgICAgICByZXR1cm4gaW5uZXIuX3pvZC5ydW4ocGF5bG9hZCwgY3R4KTtcbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZEN1c3RvbSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kQ3VzdG9tXCIsIChpbnN0LCBkZWYpPT57XG4gICAgY2hlY2tzLiRab2RDaGVjay5pbml0KGluc3QsIGRlZik7XG4gICAgJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkLCBfKT0+e1xuICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICB9O1xuICAgIGluc3QuX3pvZC5jaGVjayA9IChwYXlsb2FkKT0+e1xuICAgICAgICBjb25zdCBpbnB1dCA9IHBheWxvYWQudmFsdWU7XG4gICAgICAgIGNvbnN0IHIgPSBkZWYuZm4oaW5wdXQpO1xuICAgICAgICBpZiAociBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybiByLnRoZW4oKHIpPT5oYW5kbGVSZWZpbmVSZXN1bHQociwgcGF5bG9hZCwgaW5wdXQsIGluc3QpKTtcbiAgICAgICAgfVxuICAgICAgICBoYW5kbGVSZWZpbmVSZXN1bHQociwgcGF5bG9hZCwgaW5wdXQsIGluc3QpO1xuICAgICAgICByZXR1cm47XG4gICAgfTtcbn0pO1xuZnVuY3Rpb24gaGFuZGxlUmVmaW5lUmVzdWx0KHJlc3VsdCwgcGF5bG9hZCwgaW5wdXQsIGluc3QpIHtcbiAgICBpZiAoIXJlc3VsdCkge1xuICAgICAgICBjb25zdCBfaXNzID0ge1xuICAgICAgICAgICAgY29kZTogXCJjdXN0b21cIixcbiAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgaW5zdCxcbiAgICAgICAgICAgIHBhdGg6IFtcbiAgICAgICAgICAgICAgICAuLi5pbnN0Ll96b2QuZGVmLnBhdGggPz8gW11cbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBjb250aW51ZTogIWluc3QuX3pvZC5kZWYuYWJvcnRcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKGluc3QuX3pvZC5kZWYucGFyYW1zKSBfaXNzLnBhcmFtcyA9IGluc3QuX3pvZC5kZWYucGFyYW1zO1xuICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHV0aWwuaXNzdWUoX2lzcykpO1xuICAgIH1cbn1cbiIsICJleHBvcnQgeyBkZWZhdWx0IGFzIGFyIH0gZnJvbSBcIi4vYXIuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgYXogfSBmcm9tIFwiLi9hei5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBiZSB9IGZyb20gXCIuL2JlLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGNhIH0gZnJvbSBcIi4vY2EuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgY3MgfSBmcm9tIFwiLi9jcy5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBkYSB9IGZyb20gXCIuL2RhLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGRlIH0gZnJvbSBcIi4vZGUuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgZW4gfSBmcm9tIFwiLi9lbi5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBlbyB9IGZyb20gXCIuL2VvLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGVzIH0gZnJvbSBcIi4vZXMuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgZmEgfSBmcm9tIFwiLi9mYS5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBmaSB9IGZyb20gXCIuL2ZpLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGZyIH0gZnJvbSBcIi4vZnIuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgZnJDQSB9IGZyb20gXCIuL2ZyLUNBLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGhlIH0gZnJvbSBcIi4vaGUuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgaHUgfSBmcm9tIFwiLi9odS5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBpZCB9IGZyb20gXCIuL2lkLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGlzIH0gZnJvbSBcIi4vaXMuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgaXQgfSBmcm9tIFwiLi9pdC5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBqYSB9IGZyb20gXCIuL2phLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGthIH0gZnJvbSBcIi4va2EuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMga2ggfSBmcm9tIFwiLi9raC5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBrbSB9IGZyb20gXCIuL2ttLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGtvIH0gZnJvbSBcIi4va28uanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgbHQgfSBmcm9tIFwiLi9sdC5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBtayB9IGZyb20gXCIuL21rLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIG1zIH0gZnJvbSBcIi4vbXMuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgbmwgfSBmcm9tIFwiLi9ubC5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBubyB9IGZyb20gXCIuL25vLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIG90YSB9IGZyb20gXCIuL290YS5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBwcyB9IGZyb20gXCIuL3BzLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIHBsIH0gZnJvbSBcIi4vcGwuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgcHQgfSBmcm9tIFwiLi9wdC5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBydSB9IGZyb20gXCIuL3J1LmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIHNsIH0gZnJvbSBcIi4vc2wuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgc3YgfSBmcm9tIFwiLi9zdi5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyB0YSB9IGZyb20gXCIuL3RhLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIHRoIH0gZnJvbSBcIi4vdGguanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgdHIgfSBmcm9tIFwiLi90ci5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyB1YSB9IGZyb20gXCIuL3VhLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIHVrIH0gZnJvbSBcIi4vdWsuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgdXIgfSBmcm9tIFwiLi91ci5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyB2aSB9IGZyb20gXCIuL3ZpLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIHpoQ04gfSBmcm9tIFwiLi96aC1DTi5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyB6aFRXIH0gZnJvbSBcIi4vemgtVFcuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgeW8gfSBmcm9tIFwiLi95by5qc1wiO1xuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJcdTA2MkRcdTA2MzFcdTA2NDFcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwNjIzXHUwNjQ2IFx1MDY0QVx1MDYyRFx1MDY0OFx1MDY0QVwiXG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHUwNjI4XHUwNjI3XHUwNjRBXHUwNjJBXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MDYyM1x1MDY0NiBcdTA2NEFcdTA2MkRcdTA2NDhcdTA2NEFcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJcdTA2MzlcdTA2NDZcdTA2MzVcdTA2MzFcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwNjIzXHUwNjQ2IFx1MDY0QVx1MDYyRFx1MDY0OFx1MDY0QVwiXG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDogXCJcdTA2MzlcdTA2NDZcdTA2MzVcdTA2MzFcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwNjIzXHUwNjQ2IFx1MDY0QVx1MDYyRFx1MDY0OFx1MDY0QVwiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4pIHtcbiAgICAgICAgcmV0dXJuIFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWRUeXBlID0gKGRhdGEpPT57XG4gICAgICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICAgICAgc3dpdGNoKHQpe1xuICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIm51bWJlclwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJhcnJheVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJudWxsXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcIlx1MDY0NVx1MDYyRlx1MDYyRVx1MDY0NFwiLFxuICAgICAgICBlbWFpbDogXCJcdTA2MjhcdTA2MzFcdTA2NEFcdTA2MkYgXHUwNjI1XHUwNjQ0XHUwNjQzXHUwNjJBXHUwNjMxXHUwNjQ4XHUwNjQ2XHUwNjRBXCIsXG4gICAgICAgIHVybDogXCJcdTA2MzFcdTA2MjdcdTA2MjhcdTA2MzdcIixcbiAgICAgICAgZW1vamk6IFwiXHUwNjI1XHUwNjRBXHUwNjQ1XHUwNjQ4XHUwNjJDXHUwNjRBXCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcIlx1MDYyQVx1MDYyN1x1MDYzMVx1MDY0QVx1MDYyRSBcdTA2NDhcdTA2NDhcdTA2NDJcdTA2MkEgXHUwNjI4XHUwNjQ1XHUwNjM5XHUwNjRBXHUwNjI3XHUwNjMxIElTT1wiLFxuICAgICAgICBkYXRlOiBcIlx1MDYyQVx1MDYyN1x1MDYzMVx1MDY0QVx1MDYyRSBcdTA2MjhcdTA2NDVcdTA2MzlcdTA2NEFcdTA2MjdcdTA2MzEgSVNPXCIsXG4gICAgICAgIHRpbWU6IFwiXHUwNjQ4XHUwNjQyXHUwNjJBIFx1MDYyOFx1MDY0NVx1MDYzOVx1MDY0QVx1MDYyN1x1MDYzMSBJU09cIixcbiAgICAgICAgZHVyYXRpb246IFwiXHUwNjQ1XHUwNjJGXHUwNjI5IFx1MDYyOFx1MDY0NVx1MDYzOVx1MDY0QVx1MDYyN1x1MDYzMSBJU09cIixcbiAgICAgICAgaXB2NDogXCJcdTA2MzlcdTA2NDZcdTA2NDhcdTA2MjdcdTA2NDYgSVB2NFwiLFxuICAgICAgICBpcHY2OiBcIlx1MDYzOVx1MDY0Nlx1MDY0OFx1MDYyN1x1MDY0NiBJUHY2XCIsXG4gICAgICAgIGNpZHJ2NDogXCJcdTA2NDVcdTA2MkZcdTA2NDkgXHUwNjM5XHUwNjQ2XHUwNjI3XHUwNjQ4XHUwNjRBXHUwNjQ2IFx1MDYyOFx1MDYzNVx1MDY0QVx1MDYzQVx1MDYyOSBJUHY0XCIsXG4gICAgICAgIGNpZHJ2NjogXCJcdTA2NDVcdTA2MkZcdTA2NDkgXHUwNjM5XHUwNjQ2XHUwNjI3XHUwNjQ4XHUwNjRBXHUwNjQ2IFx1MDYyOFx1MDYzNVx1MDY0QVx1MDYzQVx1MDYyOSBJUHY2XCIsXG4gICAgICAgIGJhc2U2NDogXCJcdTA2NDZcdTA2NEVcdTA2MzUgXHUwNjI4XHUwNjJBXHUwNjMxXHUwNjQ1XHUwNjRBXHUwNjMyIGJhc2U2NC1lbmNvZGVkXCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJcdTA2NDZcdTA2NEVcdTA2MzUgXHUwNjI4XHUwNjJBXHUwNjMxXHUwNjQ1XHUwNjRBXHUwNjMyIGJhc2U2NHVybC1lbmNvZGVkXCIsXG4gICAgICAgIGpzb25fc3RyaW5nOiBcIlx1MDY0Nlx1MDY0RVx1MDYzNSBcdTA2MzlcdTA2NDRcdTA2NDkgXHUwNjQ3XHUwNjRBXHUwNjI2XHUwNjI5IEpTT05cIixcbiAgICAgICAgZTE2NDogXCJcdTA2MzFcdTA2NDJcdTA2NDUgXHUwNjQ3XHUwNjI3XHUwNjJBXHUwNjQxIFx1MDYyOFx1MDY0NVx1MDYzOVx1MDY0QVx1MDYyN1x1MDYzMSBFLjE2NFwiLFxuICAgICAgICBqd3Q6IFwiSldUXCIsXG4gICAgICAgIHRlbXBsYXRlX2xpdGVyYWw6IFwiXHUwNjQ1XHUwNjJGXHUwNjJFXHUwNjQ0XCJcbiAgICB9O1xuICAgIHJldHVybiAoaXNzdWUpPT57XG4gICAgICAgIHN3aXRjaChpc3N1ZS5jb2RlKXtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3R5cGVcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDY0NVx1MDYyRlx1MDYyRVx1MDY0NFx1MDYyN1x1MDYyQSBcdTA2M0FcdTA2NEFcdTA2MzEgXHUwNjQ1XHUwNjQyXHUwNjI4XHUwNjQ4XHUwNjQ0XHUwNjI5OiBcdTA2NEFcdTA2NDFcdTA2MkFcdTA2MzFcdTA2MzYgXHUwNjI1XHUwNjJGXHUwNjJFXHUwNjI3XHUwNjQ0ICR7aXNzdWUuZXhwZWN0ZWR9XHUwNjBDIFx1MDY0OFx1MDY0NFx1MDY0M1x1MDY0NiBcdTA2MkFcdTA2NDUgXHUwNjI1XHUwNjJGXHUwNjJFXHUwNjI3XHUwNjQ0ICR7cGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgXHUwNjQ1XHUwNjJGXHUwNjJFXHUwNjQ0XHUwNjI3XHUwNjJBIFx1MDYzQVx1MDY0QVx1MDYzMSBcdTA2NDVcdTA2NDJcdTA2MjhcdTA2NDhcdTA2NDRcdTA2Mjk6IFx1MDY0QVx1MDY0MVx1MDYyQVx1MDYzMVx1MDYzNiBcdTA2MjVcdTA2MkZcdTA2MkVcdTA2MjdcdTA2NDQgJHt1dGlsLnN0cmluZ2lmeVByaW1pdGl2ZShpc3N1ZS52YWx1ZXNbMF0pfWA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2MjdcdTA2MkVcdTA2MkFcdTA2NEFcdTA2MjdcdTA2MzEgXHUwNjNBXHUwNjRBXHUwNjMxIFx1MDY0NVx1MDY0Mlx1MDYyOFx1MDY0OFx1MDY0NDogXHUwNjRBXHUwNjJBXHUwNjQ4XHUwNjQyXHUwNjM5IFx1MDYyN1x1MDY0Nlx1MDYyQVx1MDY0Mlx1MDYyN1x1MDYyMSBcdTA2MjNcdTA2MkRcdTA2MkYgXHUwNjQ3XHUwNjMwXHUwNjQ3IFx1MDYyN1x1MDY0NFx1MDYyRVx1MDY0QVx1MDYyN1x1MDYzMVx1MDYyN1x1MDYyQTogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIjw9XCIgOiBcIjxcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgIFx1MDYyM1x1MDY0M1x1MDYyOFx1MDYzMSBcdTA2NDVcdTA2NDYgXHUwNjI3XHUwNjQ0XHUwNjQ0XHUwNjI3XHUwNjMyXHUwNjQ1OiBcdTA2NEFcdTA2NDFcdTA2MkFcdTA2MzFcdTA2MzYgXHUwNjIzXHUwNjQ2IFx1MDYyQVx1MDY0M1x1MDY0OFx1MDY0NiAke2lzc3VlLm9yaWdpbiA/PyBcIlx1MDYyN1x1MDY0NFx1MDY0Mlx1MDY0QVx1MDY0NVx1MDYyOVwifSAke2Fkan0gJHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXQgPz8gXCJcdTA2MzlcdTA2NDZcdTA2MzVcdTA2MzFcIn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDYyM1x1MDY0M1x1MDYyOFx1MDYzMSBcdTA2NDVcdTA2NDYgXHUwNjI3XHUwNjQ0XHUwNjQ0XHUwNjI3XHUwNjMyXHUwNjQ1OiBcdTA2NEFcdTA2NDFcdTA2MkFcdTA2MzFcdTA2MzYgXHUwNjIzXHUwNjQ2IFx1MDYyQVx1MDY0M1x1MDY0OFx1MDY0NiAke2lzc3VlLm9yaWdpbiA/PyBcIlx1MDYyN1x1MDY0NFx1MDY0Mlx1MDY0QVx1MDY0NVx1MDYyOVwifSAke2Fkan0gJHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIj49XCIgOiBcIj5cIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjIzXHUwNjM1XHUwNjNBXHUwNjMxIFx1MDY0NVx1MDY0NiBcdTA2MjdcdTA2NDRcdTA2NDRcdTA2MjdcdTA2MzJcdTA2NDU6IFx1MDY0QVx1MDY0MVx1MDYyQVx1MDYzMVx1MDYzNiBcdTA2NDRcdTA2NDAgJHtpc3N1ZS5vcmlnaW59IFx1MDYyM1x1MDY0NiBcdTA2NEFcdTA2NDNcdTA2NDhcdTA2NDYgJHthZGp9ICR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0fWA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2MjNcdTA2MzVcdTA2M0FcdTA2MzEgXHUwNjQ1XHUwNjQ2IFx1MDYyN1x1MDY0NFx1MDY0NFx1MDYyN1x1MDYzMlx1MDY0NTogXHUwNjRBXHUwNjQxXHUwNjJBXHUwNjMxXHUwNjM2IFx1MDY0NFx1MDY0MCAke2lzc3VlLm9yaWdpbn0gXHUwNjIzXHUwNjQ2IFx1MDY0QVx1MDY0M1x1MDY0OFx1MDY0NiAke2Fkan0gJHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSByZXR1cm4gYFx1MDY0Nlx1MDY0RVx1MDYzNSBcdTA2M0FcdTA2NEFcdTA2MzEgXHUwNjQ1XHUwNjQyXHUwNjI4XHUwNjQ4XHUwNjQ0OiBcdTA2NEFcdTA2MkNcdTA2MjggXHUwNjIzXHUwNjQ2IFx1MDY0QVx1MDYyOFx1MDYyRlx1MDYyMyBcdTA2MjhcdTA2NDAgXCIke2lzc3VlLnByZWZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYFx1MDY0Nlx1MDY0RVx1MDYzNSBcdTA2M0FcdTA2NEFcdTA2MzEgXHUwNjQ1XHUwNjQyXHUwNjI4XHUwNjQ4XHUwNjQ0OiBcdTA2NEFcdTA2MkNcdTA2MjggXHUwNjIzXHUwNjQ2IFx1MDY0QVx1MDY0Nlx1MDYyQVx1MDY0N1x1MDY0QSBcdTA2MjhcdTA2NDAgXCIke19pc3N1ZS5zdWZmaXh9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJpbmNsdWRlc1wiKSByZXR1cm4gYFx1MDY0Nlx1MDY0RVx1MDYzNSBcdTA2M0FcdTA2NEFcdTA2MzEgXHUwNjQ1XHUwNjQyXHUwNjI4XHUwNjQ4XHUwNjQ0OiBcdTA2NEFcdTA2MkNcdTA2MjggXHUwNjIzXHUwNjQ2IFx1MDY0QVx1MDYyQVx1MDYzNlx1MDY0NVx1MDY1MVx1MDY0RVx1MDY0NiBcIiR7X2lzc3VlLmluY2x1ZGVzfVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBcdTA2NDZcdTA2NEVcdTA2MzUgXHUwNjNBXHUwNjRBXHUwNjMxIFx1MDY0NVx1MDY0Mlx1MDYyOFx1MDY0OFx1MDY0NDogXHUwNjRBXHUwNjJDXHUwNjI4IFx1MDYyM1x1MDY0NiBcdTA2NEFcdTA2MzdcdTA2MjdcdTA2MjhcdTA2NDIgXHUwNjI3XHUwNjQ0XHUwNjQ2XHUwNjQ1XHUwNjM3ICR7X2lzc3VlLnBhdHRlcm59YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGAke05vdW5zW19pc3N1ZS5mb3JtYXRdID8/IGlzc3VlLmZvcm1hdH0gXHUwNjNBXHUwNjRBXHUwNjMxIFx1MDY0NVx1MDY0Mlx1MDYyOFx1MDY0OFx1MDY0NGA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm5vdF9tdWx0aXBsZV9vZlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjMxXHUwNjQyXHUwNjQ1IFx1MDYzQVx1MDY0QVx1MDYzMSBcdTA2NDVcdTA2NDJcdTA2MjhcdTA2NDhcdTA2NDQ6IFx1MDY0QVx1MDYyQ1x1MDYyOCBcdTA2MjNcdTA2NDYgXHUwNjRBXHUwNjQzXHUwNjQ4XHUwNjQ2IFx1MDY0NVx1MDY0NiBcdTA2NDVcdTA2MzZcdTA2MjdcdTA2MzlcdTA2NDFcdTA2MjdcdTA2MkEgJHtpc3N1ZS5kaXZpc29yfWA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDY0NVx1MDYzOVx1MDYzMVx1MDY0MSR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJcdTA2MjdcdTA2MkFcIiA6IFwiXCJ9IFx1MDYzQVx1MDYzMVx1MDY0QVx1MDYyOCR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJcdTA2MjlcIiA6IFwiXCJ9OiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIlx1MDYwQyBcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2tleVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjQ1XHUwNjM5XHUwNjMxXHUwNjQxIFx1MDYzQVx1MDY0QVx1MDYzMSBcdTA2NDVcdTA2NDJcdTA2MjhcdTA2NDhcdTA2NDQgXHUwNjQxXHUwNjRBICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF91bmlvblwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIlx1MDY0NVx1MDYyRlx1MDYyRVx1MDY0NCBcdTA2M0FcdTA2NEFcdTA2MzEgXHUwNjQ1XHUwNjQyXHUwNjI4XHUwNjQ4XHUwNjQ0XCI7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9lbGVtZW50XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2NDVcdTA2MkZcdTA2MkVcdTA2NDQgXHUwNjNBXHUwNjRBXHUwNjMxIFx1MDY0NVx1MDY0Mlx1MDYyOFx1MDY0OFx1MDY0NCBcdTA2NDFcdTA2NEEgJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiXHUwNjQ1XHUwNjJGXHUwNjJFXHUwNjQ0IFx1MDYzQVx1MDY0QVx1MDYzMSBcdTA2NDVcdTA2NDJcdTA2MjhcdTA2NDhcdTA2NDRcIjtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJzaW12b2xcIixcbiAgICAgICAgICAgIHZlcmI6IFwib2xtYWxcdTAxMzFkXHUwMTMxclwiXG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiYmF5dFwiLFxuICAgICAgICAgICAgdmVyYjogXCJvbG1hbFx1MDEzMWRcdTAxMzFyXCJcbiAgICAgICAgfSxcbiAgICAgICAgYXJyYXk6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiZWxlbWVudFwiLFxuICAgICAgICAgICAgdmVyYjogXCJvbG1hbFx1MDEzMWRcdTAxMzFyXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcImVsZW1lbnRcIixcbiAgICAgICAgICAgIHZlcmI6IFwib2xtYWxcdTAxMzFkXHUwMTMxclwiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4pIHtcbiAgICAgICAgcmV0dXJuIFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWRUeXBlID0gKGRhdGEpPT57XG4gICAgICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICAgICAgc3dpdGNoKHQpe1xuICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIm51bWJlclwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJhcnJheVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJudWxsXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcImlucHV0XCIsXG4gICAgICAgIGVtYWlsOiBcImVtYWlsIGFkZHJlc3NcIixcbiAgICAgICAgdXJsOiBcIlVSTFwiLFxuICAgICAgICBlbW9qaTogXCJlbW9qaVwiLFxuICAgICAgICB1dWlkOiBcIlVVSURcIixcbiAgICAgICAgdXVpZHY0OiBcIlVVSUR2NFwiLFxuICAgICAgICB1dWlkdjY6IFwiVVVJRHY2XCIsXG4gICAgICAgIG5hbm9pZDogXCJuYW5vaWRcIixcbiAgICAgICAgZ3VpZDogXCJHVUlEXCIsXG4gICAgICAgIGN1aWQ6IFwiY3VpZFwiLFxuICAgICAgICBjdWlkMjogXCJjdWlkMlwiLFxuICAgICAgICB1bGlkOiBcIlVMSURcIixcbiAgICAgICAgeGlkOiBcIlhJRFwiLFxuICAgICAgICBrc3VpZDogXCJLU1VJRFwiLFxuICAgICAgICBkYXRldGltZTogXCJJU08gZGF0ZXRpbWVcIixcbiAgICAgICAgZGF0ZTogXCJJU08gZGF0ZVwiLFxuICAgICAgICB0aW1lOiBcIklTTyB0aW1lXCIsXG4gICAgICAgIGR1cmF0aW9uOiBcIklTTyBkdXJhdGlvblwiLFxuICAgICAgICBpcHY0OiBcIklQdjQgYWRkcmVzc1wiLFxuICAgICAgICBpcHY2OiBcIklQdjYgYWRkcmVzc1wiLFxuICAgICAgICBjaWRydjQ6IFwiSVB2NCByYW5nZVwiLFxuICAgICAgICBjaWRydjY6IFwiSVB2NiByYW5nZVwiLFxuICAgICAgICBiYXNlNjQ6IFwiYmFzZTY0LWVuY29kZWQgc3RyaW5nXCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJiYXNlNjR1cmwtZW5jb2RlZCBzdHJpbmdcIixcbiAgICAgICAganNvbl9zdHJpbmc6IFwiSlNPTiBzdHJpbmdcIixcbiAgICAgICAgZTE2NDogXCJFLjE2NCBudW1iZXJcIixcbiAgICAgICAgand0OiBcIkpXVFwiLFxuICAgICAgICB0ZW1wbGF0ZV9saXRlcmFsOiBcImlucHV0XCJcbiAgICB9O1xuICAgIHJldHVybiAoaXNzdWUpPT57XG4gICAgICAgIHN3aXRjaChpc3N1ZS5jb2RlKXtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3R5cGVcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFlhbmxcdTAxMzFcdTAxNUYgZFx1MDI1OXlcdTAyNTlyOiBnXHUwMEY2emxcdTAyNTluaWxcdTAyNTluICR7aXNzdWUuZXhwZWN0ZWR9LCBkYXhpbCBvbGFuICR7cGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgWWFubFx1MDEzMVx1MDE1RiBkXHUwMjU5eVx1MDI1OXI6IGdcdTAwRjZ6bFx1MDI1OW5pbFx1MDI1OW4gJHt1dGlsLnN0cmluZ2lmeVByaW1pdGl2ZShpc3N1ZS52YWx1ZXNbMF0pfWA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBZYW5sXHUwMTMxXHUwMTVGIHNlXHUwMEU3aW06IGFcdTAxNUZhXHUwMTFGXHUwMTMxZGFrXHUwMTMxbGFyZGFuIGJpcmkgb2xtYWxcdTAxMzFkXHUwMTMxcjogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIjw9XCIgOiBcIjxcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgXHUwMEM3b3ggYlx1MDBGNnlcdTAwRkNrOiBnXHUwMEY2emxcdTAyNTluaWxcdTAyNTluICR7aXNzdWUub3JpZ2luID8/IFwiZFx1MDI1OXlcdTAyNTlyXCJ9ICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0ID8/IFwiZWxlbWVudFwifWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwMEM3b3ggYlx1MDBGNnlcdTAwRkNrOiBnXHUwMEY2emxcdTAyNTluaWxcdTAyNTluICR7aXNzdWUub3JpZ2luID8/IFwiZFx1MDI1OXlcdTAyNTlyXCJ9ICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInRvb19zbWFsbFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI+PVwiIDogXCI+XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSByZXR1cm4gYFx1MDBDN294IGtpXHUwMEU3aWs6IGdcdTAwRjZ6bFx1MDI1OW5pbFx1MDI1OW4gJHtpc3N1ZS5vcmlnaW59ICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0fWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwMEM3b3gga2lcdTAwRTdpazogZ1x1MDBGNnpsXHUwMjU5bmlsXHUwMjU5biAke2lzc3VlLm9yaWdpbn0gJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSByZXR1cm4gYFlhbmxcdTAxMzFcdTAxNUYgbVx1MDI1OXRuOiBcIiR7X2lzc3VlLnByZWZpeH1cIiBpbFx1MDI1OSBiYVx1MDE1RmxhbWFsXHUwMTMxZFx1MDEzMXJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJlbmRzX3dpdGhcIikgcmV0dXJuIGBZYW5sXHUwMTMxXHUwMTVGIG1cdTAyNTl0bjogXCIke19pc3N1ZS5zdWZmaXh9XCIgaWxcdTAyNTkgYml0bVx1MDI1OWxpZGlyYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBZYW5sXHUwMTMxXHUwMTVGIG1cdTAyNTl0bjogXCIke19pc3N1ZS5pbmNsdWRlc31cIiBkYXhpbCBvbG1hbFx1MDEzMWRcdTAxMzFyYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBZYW5sXHUwMTMxXHUwMTVGIG1cdTAyNTl0bjogJHtfaXNzdWUucGF0dGVybn0gXHUwMTVGYWJsb251bmEgdXlcdTAxMUZ1biBvbG1hbFx1MDEzMWRcdTAxMzFyYDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBZYW5sXHUwMTMxXHUwMTVGICR7Tm91bnNbX2lzc3VlLmZvcm1hdF0gPz8gaXNzdWUuZm9ybWF0fWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm5vdF9tdWx0aXBsZV9vZlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgWWFubFx1MDEzMVx1MDE1RiBcdTAyNTlkXHUwMjU5ZDogJHtpc3N1ZS5kaXZpc29yfSBpbFx1MDI1OSBiXHUwMEY2bFx1MDBGQ25cdTAyNTkgYmlsXHUwMjU5biBvbG1hbFx1MDEzMWRcdTAxMzFyYDtcbiAgICAgICAgICAgIGNhc2UgXCJ1bnJlY29nbml6ZWRfa2V5c1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgVGFuXHUwMTMxbm1heWFuIGFcdTAwRTdhciR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJsYXJcIiA6IFwiXCJ9OiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIiwgXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYCR7aXNzdWUub3JpZ2lufSBkYXhpbGluZFx1MDI1OSB5YW5sXHUwMTMxXHUwMTVGIGFcdTAwRTdhcmA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF91bmlvblwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIllhbmxcdTAxMzFcdTAxNUYgZFx1MDI1OXlcdTAyNTlyXCI7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9lbGVtZW50XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGAke2lzc3VlLm9yaWdpbn0gZGF4aWxpbmRcdTAyNTkgeWFubFx1MDEzMVx1MDE1RiBkXHUwMjU5eVx1MDI1OXJgO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFlhbmxcdTAxMzFcdTAxNUYgZFx1MDI1OXlcdTAyNTlyYDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuZnVuY3Rpb24gZ2V0QmVsYXJ1c2lhblBsdXJhbChjb3VudCwgb25lLCBmZXcsIG1hbnkpIHtcbiAgICBjb25zdCBhYnNDb3VudCA9IE1hdGguYWJzKGNvdW50KTtcbiAgICBjb25zdCBsYXN0RGlnaXQgPSBhYnNDb3VudCAlIDEwO1xuICAgIGNvbnN0IGxhc3RUd29EaWdpdHMgPSBhYnNDb3VudCAlIDEwMDtcbiAgICBpZiAobGFzdFR3b0RpZ2l0cyA+PSAxMSAmJiBsYXN0VHdvRGlnaXRzIDw9IDE5KSB7XG4gICAgICAgIHJldHVybiBtYW55O1xuICAgIH1cbiAgICBpZiAobGFzdERpZ2l0ID09PSAxKSB7XG4gICAgICAgIHJldHVybiBvbmU7XG4gICAgfVxuICAgIGlmIChsYXN0RGlnaXQgPj0gMiAmJiBsYXN0RGlnaXQgPD0gNCkge1xuICAgICAgICByZXR1cm4gZmV3O1xuICAgIH1cbiAgICByZXR1cm4gbWFueTtcbn1cbmNvbnN0IGVycm9yID0gKCk9PntcbiAgICBjb25zdCBTaXphYmxlID0ge1xuICAgICAgICBzdHJpbmc6IHtcbiAgICAgICAgICAgIHVuaXQ6IHtcbiAgICAgICAgICAgICAgICBvbmU6IFwiXHUwNDQxXHUwNDU2XHUwNDNDXHUwNDMyXHUwNDMwXHUwNDNCXCIsXG4gICAgICAgICAgICAgICAgZmV3OiBcIlx1MDQ0MVx1MDQ1Nlx1MDQzQ1x1MDQzMlx1MDQzMFx1MDQzQlx1MDQ0QlwiLFxuICAgICAgICAgICAgICAgIG1hbnk6IFwiXHUwNDQxXHUwNDU2XHUwNDNDXHUwNDMyXHUwNDMwXHUwNDNCXHUwNDMwXHUwNDVFXCJcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MDQzQ1x1MDQzNVx1MDQ0Nlx1MDQ0Q1wiXG4gICAgICAgIH0sXG4gICAgICAgIGFycmF5OiB7XG4gICAgICAgICAgICB1bml0OiB7XG4gICAgICAgICAgICAgICAgb25lOiBcIlx1MDQ0RFx1MDQzQlx1MDQzNVx1MDQzQ1x1MDQzNVx1MDQzRFx1MDQ0MlwiLFxuICAgICAgICAgICAgICAgIGZldzogXCJcdTA0NERcdTA0M0JcdTA0MzVcdTA0M0NcdTA0MzVcdTA0M0RcdTA0NDJcdTA0NEJcIixcbiAgICAgICAgICAgICAgICBtYW55OiBcIlx1MDQ0RFx1MDQzQlx1MDQzNVx1MDQzQ1x1MDQzNVx1MDQzRFx1MDQ0Mlx1MDQzMFx1MDQ1RVwiXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdmVyYjogXCJcdTA0M0NcdTA0MzVcdTA0NDZcdTA0NENcIlxuICAgICAgICB9LFxuICAgICAgICBzZXQ6IHtcbiAgICAgICAgICAgIHVuaXQ6IHtcbiAgICAgICAgICAgICAgICBvbmU6IFwiXHUwNDREXHUwNDNCXHUwNDM1XHUwNDNDXHUwNDM1XHUwNDNEXHUwNDQyXCIsXG4gICAgICAgICAgICAgICAgZmV3OiBcIlx1MDQ0RFx1MDQzQlx1MDQzNVx1MDQzQ1x1MDQzNVx1MDQzRFx1MDQ0Mlx1MDQ0QlwiLFxuICAgICAgICAgICAgICAgIG1hbnk6IFwiXHUwNDREXHUwNDNCXHUwNDM1XHUwNDNDXHUwNDM1XHUwNDNEXHUwNDQyXHUwNDMwXHUwNDVFXCJcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MDQzQ1x1MDQzNVx1MDQ0Nlx1MDQ0Q1wiXG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IHtcbiAgICAgICAgICAgICAgICBvbmU6IFwiXHUwNDMxXHUwNDMwXHUwNDM5XHUwNDQyXCIsXG4gICAgICAgICAgICAgICAgZmV3OiBcIlx1MDQzMVx1MDQzMFx1MDQzOVx1MDQ0Mlx1MDQ0QlwiLFxuICAgICAgICAgICAgICAgIG1hbnk6IFwiXHUwNDMxXHUwNDMwXHUwNDM5XHUwNDQyXHUwNDMwXHUwNDVFXCJcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MDQzQ1x1MDQzNVx1MDQ0Nlx1MDQ0Q1wiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4pIHtcbiAgICAgICAgcmV0dXJuIFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWRUeXBlID0gKGRhdGEpPT57XG4gICAgICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICAgICAgc3dpdGNoKHQpe1xuICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIlx1MDQzQlx1MDQ1Nlx1MDQzQVwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTA0M0NcdTA0MzBcdTA0NDFcdTA0NTZcdTA0NUVcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YoZGF0YSkgIT09IE9iamVjdC5wcm90b3R5cGUgJiYgZGF0YS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdDtcbiAgICB9O1xuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJcdTA0NDNcdTA0MzJcdTA0M0VcdTA0MzRcIixcbiAgICAgICAgZW1haWw6IFwiZW1haWwgXHUwNDMwXHUwNDM0XHUwNDQwXHUwNDMwXHUwNDQxXCIsXG4gICAgICAgIHVybDogXCJVUkxcIixcbiAgICAgICAgZW1vamk6IFwiXHUwNDREXHUwNDNDXHUwNDNFXHUwNDM0XHUwNDM3XHUwNDU2XCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcIklTTyBcdTA0MzRcdTA0MzBcdTA0NDJcdTA0MzAgXHUwNDU2IFx1MDQ0N1x1MDQzMFx1MDQ0MVwiLFxuICAgICAgICBkYXRlOiBcIklTTyBcdTA0MzRcdTA0MzBcdTA0NDJcdTA0MzBcIixcbiAgICAgICAgdGltZTogXCJJU08gXHUwNDQ3XHUwNDMwXHUwNDQxXCIsXG4gICAgICAgIGR1cmF0aW9uOiBcIklTTyBcdTA0M0ZcdTA0NDBcdTA0MzBcdTA0NDZcdTA0NEZcdTA0MzNcdTA0M0JcdTA0MzBcdTA0NDFcdTA0NDZcdTA0NENcIixcbiAgICAgICAgaXB2NDogXCJJUHY0IFx1MDQzMFx1MDQzNFx1MDQ0MFx1MDQzMFx1MDQ0MVwiLFxuICAgICAgICBpcHY2OiBcIklQdjYgXHUwNDMwXHUwNDM0XHUwNDQwXHUwNDMwXHUwNDQxXCIsXG4gICAgICAgIGNpZHJ2NDogXCJJUHY0IFx1MDQzNFx1MDQ0Qlx1MDQ0Rlx1MDQzRlx1MDQzMFx1MDQzN1x1MDQzRVx1MDQzRFwiLFxuICAgICAgICBjaWRydjY6IFwiSVB2NiBcdTA0MzRcdTA0NEJcdTA0NEZcdTA0M0ZcdTA0MzBcdTA0MzdcdTA0M0VcdTA0M0RcIixcbiAgICAgICAgYmFzZTY0OiBcIlx1MDQ0MFx1MDQzMFx1MDQzNFx1MDQzRVx1MDQzQSBcdTA0NDMgXHUwNDQ0XHUwNDMwXHUwNDQwXHUwNDNDXHUwNDMwXHUwNDQ2XHUwNDM1IGJhc2U2NFwiLFxuICAgICAgICBiYXNlNjR1cmw6IFwiXHUwNDQwXHUwNDMwXHUwNDM0XHUwNDNFXHUwNDNBIFx1MDQ0MyBcdTA0NDRcdTA0MzBcdTA0NDBcdTA0M0NcdTA0MzBcdTA0NDZcdTA0MzUgYmFzZTY0dXJsXCIsXG4gICAgICAgIGpzb25fc3RyaW5nOiBcIkpTT04gXHUwNDQwXHUwNDMwXHUwNDM0XHUwNDNFXHUwNDNBXCIsXG4gICAgICAgIGUxNjQ6IFwiXHUwNDNEXHUwNDQzXHUwNDNDXHUwNDMwXHUwNDQwIEUuMTY0XCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJcdTA0NDNcdTA0MzJcdTA0M0VcdTA0MzRcIlxuICAgIH07XG4gICAgcmV0dXJuIChpc3N1ZSk9PntcbiAgICAgICAgc3dpdGNoKGlzc3VlLmNvZGUpe1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdHlwZVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNDFEXHUwNDRGXHUwNDNGXHUwNDQwXHUwNDMwXHUwNDMyXHUwNDU2XHUwNDNCXHUwNDRDXHUwNDNEXHUwNDRCIFx1MDQ1RVx1MDQzMlx1MDQzRVx1MDQzNDogXHUwNDQ3XHUwNDMwXHUwNDNBXHUwNDMwXHUwNDVFXHUwNDQxXHUwNDRGICR7aXNzdWUuZXhwZWN0ZWR9LCBcdTA0MzBcdTA0NDJcdTA0NDBcdTA0NEJcdTA0M0NcdTA0MzBcdTA0M0RcdTA0MzAgJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBcdTA0MURcdTA0NEZcdTA0M0ZcdTA0NDBcdTA0MzBcdTA0MzJcdTA0NTZcdTA0M0JcdTA0NENcdTA0M0RcdTA0NEIgXHUwNDVFXHUwNDMyXHUwNDNFXHUwNDM0OiBcdTA0NDdcdTA0MzBcdTA0M0FcdTA0MzBcdTA0M0JcdTA0MzBcdTA0NDFcdTA0NEYgJHt1dGlsLnN0cmluZ2lmeVByaW1pdGl2ZShpc3N1ZS52YWx1ZXNbMF0pfWA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MURcdTA0NEZcdTA0M0ZcdTA0NDBcdTA0MzBcdTA0MzJcdTA0NTZcdTA0M0JcdTA0NENcdTA0M0RcdTA0NEIgXHUwNDMyXHUwNDMwXHUwNDQwXHUwNDRCXHUwNDRGXHUwNDNEXHUwNDQyOiBcdTA0NDdcdTA0MzBcdTA0M0FcdTA0MzBcdTA0NUVcdTA0NDFcdTA0NEYgXHUwNDMwXHUwNDM0XHUwNDM3XHUwNDU2XHUwNDNEIFx1MDQzNyAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS52YWx1ZXMsIFwifFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPD1cIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF4VmFsdWUgPSBOdW1iZXIoaXNzdWUubWF4aW11bSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bml0ID0gZ2V0QmVsYXJ1c2lhblBsdXJhbChtYXhWYWx1ZSwgc2l6aW5nLnVuaXQub25lLCBzaXppbmcudW5pdC5mZXcsIHNpemluZy51bml0Lm1hbnkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MTdcdTA0MzBcdTA0M0RcdTA0MzBcdTA0MzRcdTA0NDJcdTA0MzAgXHUwNDMyXHUwNDRGXHUwNDNCXHUwNDU2XHUwNDNBXHUwNDU2OiBcdTA0NDdcdTA0MzBcdTA0M0FcdTA0MzBcdTA0M0JcdTA0MzBcdTA0NDFcdTA0NEYsIFx1MDQ0OFx1MDQ0Mlx1MDQzRSAke2lzc3VlLm9yaWdpbiA/PyBcIlx1MDQzN1x1MDQzRFx1MDQzMFx1MDQ0N1x1MDQ0RFx1MDQzRFx1MDQzRFx1MDQzNVwifSBcdTA0M0ZcdTA0MzBcdTA0MzJcdTA0NTZcdTA0M0RcdTA0M0RcdTA0MzAgJHtzaXppbmcudmVyYn0gJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7dW5pdH1gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNDE3XHUwNDMwXHUwNDNEXHUwNDMwXHUwNDM0XHUwNDQyXHUwNDMwIFx1MDQzMlx1MDQ0Rlx1MDQzQlx1MDQ1Nlx1MDQzQVx1MDQ1NjogXHUwNDQ3XHUwNDMwXHUwNDNBXHUwNDMwXHUwNDNCXHUwNDMwXHUwNDQxXHUwNDRGLCBcdTA0NDhcdTA0NDJcdTA0M0UgJHtpc3N1ZS5vcmlnaW4gPz8gXCJcdTA0MzdcdTA0M0RcdTA0MzBcdTA0NDdcdTA0NERcdTA0M0RcdTA0M0RcdTA0MzVcIn0gXHUwNDNGXHUwNDMwXHUwNDMyXHUwNDU2XHUwNDNEXHUwNDNEXHUwNDMwIFx1MDQzMVx1MDQ0Qlx1MDQ0Nlx1MDQ0QyAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJ0b29fc21hbGxcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPj1cIiA6IFwiPlwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWluVmFsdWUgPSBOdW1iZXIoaXNzdWUubWluaW11bSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bml0ID0gZ2V0QmVsYXJ1c2lhblBsdXJhbChtaW5WYWx1ZSwgc2l6aW5nLnVuaXQub25lLCBzaXppbmcudW5pdC5mZXcsIHNpemluZy51bml0Lm1hbnkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MTdcdTA0MzBcdTA0M0RcdTA0MzBcdTA0MzRcdTA0NDJcdTA0MzAgXHUwNDNDXHUwNDMwXHUwNDNCXHUwNDRCOiBcdTA0NDdcdTA0MzBcdTA0M0FcdTA0MzBcdTA0M0JcdTA0MzBcdTA0NDFcdTA0NEYsIFx1MDQ0OFx1MDQ0Mlx1MDQzRSAke2lzc3VlLm9yaWdpbn0gXHUwNDNGXHUwNDMwXHUwNDMyXHUwNDU2XHUwNDNEXHUwNDNEXHUwNDMwICR7c2l6aW5nLnZlcmJ9ICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3VuaXR9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDQxN1x1MDQzMFx1MDQzRFx1MDQzMFx1MDQzNFx1MDQ0Mlx1MDQzMCBcdTA0M0NcdTA0MzBcdTA0M0JcdTA0NEI6IFx1MDQ0N1x1MDQzMFx1MDQzQVx1MDQzMFx1MDQzQlx1MDQzMFx1MDQ0MVx1MDQ0RiwgXHUwNDQ4XHUwNDQyXHUwNDNFICR7aXNzdWUub3JpZ2lufSBcdTA0M0ZcdTA0MzBcdTA0MzJcdTA0NTZcdTA0M0RcdTA0M0RcdTA0MzAgXHUwNDMxXHUwNDRCXHUwNDQ2XHUwNDRDICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZm9ybWF0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBfaXNzdWUgPSBpc3N1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwic3RhcnRzX3dpdGhcIikgcmV0dXJuIGBcdTA0MURcdTA0NEZcdTA0M0ZcdTA0NDBcdTA0MzBcdTA0MzJcdTA0NTZcdTA0M0JcdTA0NENcdTA0M0RcdTA0NEIgXHUwNDQwXHUwNDMwXHUwNDM0XHUwNDNFXHUwNDNBOiBcdTA0M0ZcdTA0MzBcdTA0MzJcdTA0NTZcdTA0M0RcdTA0MzVcdTA0M0QgXHUwNDNGXHUwNDMwXHUwNDQ3XHUwNDRCXHUwNDNEXHUwNDMwXHUwNDQ2XHUwNDQ2XHUwNDMwIFx1MDQzNyBcIiR7X2lzc3VlLnByZWZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYFx1MDQxRFx1MDQ0Rlx1MDQzRlx1MDQ0MFx1MDQzMFx1MDQzMlx1MDQ1Nlx1MDQzQlx1MDQ0Q1x1MDQzRFx1MDQ0QiBcdTA0NDBcdTA0MzBcdTA0MzRcdTA0M0VcdTA0M0E6IFx1MDQzRlx1MDQzMFx1MDQzMlx1MDQ1Nlx1MDQzRFx1MDQzNVx1MDQzRCBcdTA0MzdcdTA0MzBcdTA0M0FcdTA0MzBcdTA0M0RcdTA0NDdcdTA0MzJcdTA0MzBcdTA0NDZcdTA0NDZcdTA0MzAgXHUwNDNEXHUwNDMwIFwiJHtfaXNzdWUuc3VmZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBcdTA0MURcdTA0NEZcdTA0M0ZcdTA0NDBcdTA0MzBcdTA0MzJcdTA0NTZcdTA0M0JcdTA0NENcdTA0M0RcdTA0NEIgXHUwNDQwXHUwNDMwXHUwNDM0XHUwNDNFXHUwNDNBOiBcdTA0M0ZcdTA0MzBcdTA0MzJcdTA0NTZcdTA0M0RcdTA0MzVcdTA0M0QgXHUwNDM3XHUwNDNDXHUwNDRGXHUwNDQ4XHUwNDQ3XHUwNDMwXHUwNDQ2XHUwNDRDIFwiJHtfaXNzdWUuaW5jbHVkZXN9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYFx1MDQxRFx1MDQ0Rlx1MDQzRlx1MDQ0MFx1MDQzMFx1MDQzMlx1MDQ1Nlx1MDQzQlx1MDQ0Q1x1MDQzRFx1MDQ0QiBcdTA0NDBcdTA0MzBcdTA0MzRcdTA0M0VcdTA0M0E6IFx1MDQzRlx1MDQzMFx1MDQzMlx1MDQ1Nlx1MDQzRFx1MDQzNVx1MDQzRCBcdTA0MzBcdTA0MzRcdTA0M0ZcdTA0MzBcdTA0MzJcdTA0NEZcdTA0MzRcdTA0MzBcdTA0NDZcdTA0NEMgXHUwNDQ4XHUwNDMwXHUwNDMxXHUwNDNCXHUwNDNFXHUwNDNEXHUwNDQzICR7X2lzc3VlLnBhdHRlcm59YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MURcdTA0NEZcdTA0M0ZcdTA0NDBcdTA0MzBcdTA0MzJcdTA0NTZcdTA0M0JcdTA0NENcdTA0M0RcdTA0NEIgJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MURcdTA0NEZcdTA0M0ZcdTA0NDBcdTA0MzBcdTA0MzJcdTA0NTZcdTA0M0JcdTA0NENcdTA0M0RcdTA0NEIgXHUwNDNCXHUwNDU2XHUwNDNBOiBcdTA0M0ZcdTA0MzBcdTA0MzJcdTA0NTZcdTA0M0RcdTA0MzVcdTA0M0QgXHUwNDMxXHUwNDRCXHUwNDQ2XHUwNDRDIFx1MDQzQVx1MDQ0MFx1MDQzMFx1MDQ0Mlx1MDQzRFx1MDQ0Qlx1MDQzQyAke2lzc3VlLmRpdmlzb3J9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ1bnJlY29nbml6ZWRfa2V5c1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNDFEXHUwNDM1XHUwNDQwXHUwNDMwXHUwNDQxXHUwNDNGXHUwNDMwXHUwNDM3XHUwNDNEXHUwNDMwXHUwNDNEXHUwNDRCICR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJcdTA0M0FcdTA0M0JcdTA0NEVcdTA0NDdcdTA0NEJcIiA6IFwiXHUwNDNBXHUwNDNCXHUwNDRFXHUwNDQ3XCJ9OiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIiwgXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDQxRFx1MDQ0Rlx1MDQzRlx1MDQ0MFx1MDQzMFx1MDQzMlx1MDQ1Nlx1MDQzQlx1MDQ0Q1x1MDQzRFx1MDQ0QiBcdTA0M0FcdTA0M0JcdTA0NEVcdTA0NDcgXHUwNDQzICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF91bmlvblwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIlx1MDQxRFx1MDQ0Rlx1MDQzRlx1MDQ0MFx1MDQzMFx1MDQzMlx1MDQ1Nlx1MDQzQlx1MDQ0Q1x1MDQzRFx1MDQ0QiBcdTA0NUVcdTA0MzJcdTA0M0VcdTA0MzRcIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDQxRFx1MDQ0Rlx1MDQzRlx1MDQ0MFx1MDQzMFx1MDQzMlx1MDQ1Nlx1MDQzQlx1MDQ0Q1x1MDQzRFx1MDQzMFx1MDQzNSBcdTA0MzdcdTA0M0RcdTA0MzBcdTA0NDdcdTA0NERcdTA0M0RcdTA0M0RcdTA0MzUgXHUwNDVFICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNDFEXHUwNDRGXHUwNDNGXHUwNDQwXHUwNDMwXHUwNDMyXHUwNDU2XHUwNDNCXHUwNDRDXHUwNDNEXHUwNDRCIFx1MDQ1RVx1MDQzMlx1MDQzRVx1MDQzNGA7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGxvY2FsZUVycm9yOiBlcnJvcigpXG4gICAgfTtcbn1cbiIsICJpbXBvcnQgKiBhcyB1dGlsIGZyb20gXCIuLi9jb3JlL3V0aWwuanNcIjtcbmNvbnN0IGVycm9yID0gKCk9PntcbiAgICBjb25zdCBTaXphYmxlID0ge1xuICAgICAgICBzdHJpbmc6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiY2FyXHUwMEUwY3RlcnNcIixcbiAgICAgICAgICAgIHZlcmI6IFwiY29udGVuaXJcIlxuICAgICAgICB9LFxuICAgICAgICBmaWxlOiB7XG4gICAgICAgICAgICB1bml0OiBcImJ5dGVzXCIsXG4gICAgICAgICAgICB2ZXJiOiBcImNvbnRlbmlyXCJcbiAgICAgICAgfSxcbiAgICAgICAgYXJyYXk6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiZWxlbWVudHNcIixcbiAgICAgICAgICAgIHZlcmI6IFwiY29udGVuaXJcIlxuICAgICAgICB9LFxuICAgICAgICBzZXQ6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiZWxlbWVudHNcIixcbiAgICAgICAgICAgIHZlcmI6IFwiY29udGVuaXJcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIk5hTlwiIDogXCJudW1iZXJcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiYXJyYXlcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YoZGF0YSkgIT09IE9iamVjdC5wcm90b3R5cGUgJiYgZGF0YS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdDtcbiAgICB9O1xuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJlbnRyYWRhXCIsXG4gICAgICAgIGVtYWlsOiBcImFkcmVcdTAwRTdhIGVsZWN0clx1MDBGMm5pY2FcIixcbiAgICAgICAgdXJsOiBcIlVSTFwiLFxuICAgICAgICBlbW9qaTogXCJlbW9qaVwiLFxuICAgICAgICB1dWlkOiBcIlVVSURcIixcbiAgICAgICAgdXVpZHY0OiBcIlVVSUR2NFwiLFxuICAgICAgICB1dWlkdjY6IFwiVVVJRHY2XCIsXG4gICAgICAgIG5hbm9pZDogXCJuYW5vaWRcIixcbiAgICAgICAgZ3VpZDogXCJHVUlEXCIsXG4gICAgICAgIGN1aWQ6IFwiY3VpZFwiLFxuICAgICAgICBjdWlkMjogXCJjdWlkMlwiLFxuICAgICAgICB1bGlkOiBcIlVMSURcIixcbiAgICAgICAgeGlkOiBcIlhJRFwiLFxuICAgICAgICBrc3VpZDogXCJLU1VJRFwiLFxuICAgICAgICBkYXRldGltZTogXCJkYXRhIGkgaG9yYSBJU09cIixcbiAgICAgICAgZGF0ZTogXCJkYXRhIElTT1wiLFxuICAgICAgICB0aW1lOiBcImhvcmEgSVNPXCIsXG4gICAgICAgIGR1cmF0aW9uOiBcImR1cmFkYSBJU09cIixcbiAgICAgICAgaXB2NDogXCJhZHJlXHUwMEU3YSBJUHY0XCIsXG4gICAgICAgIGlwdjY6IFwiYWRyZVx1MDBFN2EgSVB2NlwiLFxuICAgICAgICBjaWRydjQ6IFwicmFuZyBJUHY0XCIsXG4gICAgICAgIGNpZHJ2NjogXCJyYW5nIElQdjZcIixcbiAgICAgICAgYmFzZTY0OiBcImNhZGVuYSBjb2RpZmljYWRhIGVuIGJhc2U2NFwiLFxuICAgICAgICBiYXNlNjR1cmw6IFwiY2FkZW5hIGNvZGlmaWNhZGEgZW4gYmFzZTY0dXJsXCIsXG4gICAgICAgIGpzb25fc3RyaW5nOiBcImNhZGVuYSBKU09OXCIsXG4gICAgICAgIGUxNjQ6IFwiblx1MDBGQW1lcm8gRS4xNjRcIixcbiAgICAgICAgand0OiBcIkpXVFwiLFxuICAgICAgICB0ZW1wbGF0ZV9saXRlcmFsOiBcImVudHJhZGFcIlxuICAgIH07XG4gICAgcmV0dXJuIChpc3N1ZSk9PntcbiAgICAgICAgc3dpdGNoKGlzc3VlLmNvZGUpe1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdHlwZVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgVGlwdXMgaW52XHUwMEUwbGlkOiBzJ2VzcGVyYXZhICR7aXNzdWUuZXhwZWN0ZWR9LCBzJ2hhIHJlYnV0ICR7cGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9YDtcbiAgICAgICAgICAgIC8vIHJldHVybiBgVGlwdXMgaW52XHUwMEUwbGlkOiBzJ2VzcGVyYXZhICR7aXNzdWUuZXhwZWN0ZWR9LCBzJ2hhIHJlYnV0ICR7dXRpbC5nZXRQYXJzZWRUeXBlKGlzc3VlLmlucHV0KX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBWYWxvciBpbnZcdTAwRTBsaWQ6IHMnZXNwZXJhdmEgJHt1dGlsLnN0cmluZ2lmeVByaW1pdGl2ZShpc3N1ZS52YWx1ZXNbMF0pfWA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBPcGNpXHUwMEYzIGludlx1MDBFMGxpZGE6IHMnZXNwZXJhdmEgdW5hIGRlICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLnZhbHVlcywgXCIgbyBcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcImNvbSBhIG1cdTAwRTB4aW1cIiA6IFwibWVueXMgZGVcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgTWFzc2EgZ3Jhbjogcydlc3BlcmF2YSBxdWUgJHtpc3N1ZS5vcmlnaW4gPz8gXCJlbCB2YWxvclwifSBjb250aW5ndVx1MDBFOXMgJHthZGp9ICR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0ID8/IFwiZWxlbWVudHNcIn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYE1hc3NhIGdyYW46IHMnZXNwZXJhdmEgcXVlICR7aXNzdWUub3JpZ2luID8/IFwiZWwgdmFsb3JcIn0gZm9zICR7YWRqfSAke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJ0b29fc21hbGxcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiY29tIGEgbVx1MDBFRG5pbVwiIDogXCJtXHUwMEU5cyBkZVwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBNYXNzYSBwZXRpdDogcydlc3BlcmF2YSBxdWUgJHtpc3N1ZS5vcmlnaW59IGNvbnRpbmd1XHUwMEU5cyAke2Fkan0gJHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXR9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYE1hc3NhIHBldGl0OiBzJ2VzcGVyYXZhIHF1ZSAke2lzc3VlLm9yaWdpbn0gZm9zICR7YWRqfSAke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2Zvcm1hdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgX2lzc3VlID0gaXNzdWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInN0YXJ0c193aXRoXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgRm9ybWF0IGludlx1MDBFMGxpZDogaGEgZGUgY29tZW5cdTAwRTdhciBhbWIgXCIke19pc3N1ZS5wcmVmaXh9XCJgO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYEZvcm1hdCBpbnZcdTAwRTBsaWQ6IGhhIGQnYWNhYmFyIGFtYiBcIiR7X2lzc3VlLnN1ZmZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImluY2x1ZGVzXCIpIHJldHVybiBgRm9ybWF0IGludlx1MDBFMGxpZDogaGEgZCdpbmNsb3VyZSBcIiR7X2lzc3VlLmluY2x1ZGVzfVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBGb3JtYXQgaW52XHUwMEUwbGlkOiBoYSBkZSBjb2luY2lkaXIgYW1iIGVsIHBhdHJcdTAwRjMgJHtfaXNzdWUucGF0dGVybn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYEZvcm1hdCBpbnZcdTAwRTBsaWQgcGVyIGEgJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOXHUwMEZBbWVybyBpbnZcdTAwRTBsaWQ6IGhhIGRlIHNlciBtXHUwMEZBbHRpcGxlIGRlICR7aXNzdWUuZGl2aXNvcn1gO1xuICAgICAgICAgICAgY2FzZSBcInVucmVjb2duaXplZF9rZXlzXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBDbGF1JHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcInNcIiA6IFwiXCJ9IG5vIHJlY29uZWd1ZGEke2lzc3VlLmtleXMubGVuZ3RoID4gMSA/IFwic1wiIDogXCJcIn06ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLmtleXMsIFwiLCBcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2tleVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgQ2xhdSBpbnZcdTAwRTBsaWRhIGEgJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3VuaW9uXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiRW50cmFkYSBpbnZcdTAwRTBsaWRhXCI7IC8vIENvdWxkIGFsc28gYmUgXCJUaXB1cyBkJ3VuaVx1MDBGMyBpbnZcdTAwRTBsaWRcIiBidXQgXCJFbnRyYWRhIGludlx1MDBFMGxpZGFcIiBpcyBtb3JlIGdlbmVyYWxcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYEVsZW1lbnQgaW52XHUwMEUwbGlkIGEgJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBFbnRyYWRhIGludlx1MDBFMGxpZGFgO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBsb2NhbGVFcnJvcjogZXJyb3IoKVxuICAgIH07XG59XG4iLCAiaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi4vY29yZS91dGlsLmpzXCI7XG5jb25zdCBlcnJvciA9ICgpPT57XG4gICAgY29uc3QgU2l6YWJsZSA9IHtcbiAgICAgICAgc3RyaW5nOiB7XG4gICAgICAgICAgICB1bml0OiBcInpuYWtcdTAxNkZcIixcbiAgICAgICAgICAgIHZlcmI6IFwibVx1MDBFRHRcIlxuICAgICAgICB9LFxuICAgICAgICBmaWxlOiB7XG4gICAgICAgICAgICB1bml0OiBcImJhanRcdTAxNkZcIixcbiAgICAgICAgICAgIHZlcmI6IFwibVx1MDBFRHRcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJwcnZrXHUwMTZGXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIm1cdTAwRUR0XCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcInBydmtcdTAxNkZcIixcbiAgICAgICAgICAgIHZlcmI6IFwibVx1MDBFRHRcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIk5hTlwiIDogXCJcdTAxMERcdTAwRURzbG9cIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwic3RyaW5nXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTAxNTlldFx1MDExQnplY1wiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJib29sZWFuXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJib29sZWFuXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImJpZ2ludFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiYmlnaW50XCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImZ1bmN0aW9uXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJmdW5rY2VcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwic3ltYm9sXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJzeW1ib2xcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidW5kZWZpbmVkXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJ1bmRlZmluZWRcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwicG9sZVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJudWxsXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcInJlZ3VsXHUwMEUxcm5cdTAwRUQgdlx1MDBGRHJhelwiLFxuICAgICAgICBlbWFpbDogXCJlLW1haWxvdlx1MDBFMSBhZHJlc2FcIixcbiAgICAgICAgdXJsOiBcIlVSTFwiLFxuICAgICAgICBlbW9qaTogXCJlbW9qaVwiLFxuICAgICAgICB1dWlkOiBcIlVVSURcIixcbiAgICAgICAgdXVpZHY0OiBcIlVVSUR2NFwiLFxuICAgICAgICB1dWlkdjY6IFwiVVVJRHY2XCIsXG4gICAgICAgIG5hbm9pZDogXCJuYW5vaWRcIixcbiAgICAgICAgZ3VpZDogXCJHVUlEXCIsXG4gICAgICAgIGN1aWQ6IFwiY3VpZFwiLFxuICAgICAgICBjdWlkMjogXCJjdWlkMlwiLFxuICAgICAgICB1bGlkOiBcIlVMSURcIixcbiAgICAgICAgeGlkOiBcIlhJRFwiLFxuICAgICAgICBrc3VpZDogXCJLU1VJRFwiLFxuICAgICAgICBkYXRldGltZTogXCJkYXR1bSBhIFx1MDEwRGFzIHZlIGZvcm1cdTAwRTF0dSBJU09cIixcbiAgICAgICAgZGF0ZTogXCJkYXR1bSB2ZSBmb3JtXHUwMEUxdHUgSVNPXCIsXG4gICAgICAgIHRpbWU6IFwiXHUwMTBEYXMgdmUgZm9ybVx1MDBFMXR1IElTT1wiLFxuICAgICAgICBkdXJhdGlvbjogXCJkb2JhIHRydlx1MDBFMW5cdTAwRUQgSVNPXCIsXG4gICAgICAgIGlwdjQ6IFwiSVB2NCBhZHJlc2FcIixcbiAgICAgICAgaXB2NjogXCJJUHY2IGFkcmVzYVwiLFxuICAgICAgICBjaWRydjQ6IFwicm96c2FoIElQdjRcIixcbiAgICAgICAgY2lkcnY2OiBcInJvenNhaCBJUHY2XCIsXG4gICAgICAgIGJhc2U2NDogXCJcdTAxNTlldFx1MDExQnplYyB6YWtcdTAwRjNkb3Zhblx1MDBGRCB2ZSBmb3JtXHUwMEUxdHUgYmFzZTY0XCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJcdTAxNTlldFx1MDExQnplYyB6YWtcdTAwRjNkb3Zhblx1MDBGRCB2ZSBmb3JtXHUwMEUxdHUgYmFzZTY0dXJsXCIsXG4gICAgICAgIGpzb25fc3RyaW5nOiBcIlx1MDE1OWV0XHUwMTFCemVjIHZlIGZvcm1cdTAwRTF0dSBKU09OXCIsXG4gICAgICAgIGUxNjQ6IFwiXHUwMTBEXHUwMEVEc2xvIEUuMTY0XCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJ2c3R1cFwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOZXBsYXRuXHUwMEZEIHZzdHVwOiBvXHUwMTBEZWtcdTAwRTF2XHUwMEUxbm8gJHtpc3N1ZS5leHBlY3RlZH0sIG9iZHJcdTAxN0Vlbm8gJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBOZXBsYXRuXHUwMEZEIHZzdHVwOiBvXHUwMTBEZWtcdTAwRTF2XHUwMEUxbm8gJHt1dGlsLnN0cmluZ2lmeVByaW1pdGl2ZShpc3N1ZS52YWx1ZXNbMF0pfWA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOZXBsYXRuXHUwMEUxIG1vXHUwMTdFbm9zdDogb1x1MDEwRGVrXHUwMEUxdlx1MDBFMW5hIGplZG5hIHogaG9kbm90ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLnZhbHVlcywgXCJ8XCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwidG9vX2JpZ1wiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI8PVwiIDogXCI8XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYEhvZG5vdGEgamUgcFx1MDE1OVx1MDBFRGxpXHUwMTYxIHZlbGtcdTAwRTE6ICR7aXNzdWUub3JpZ2luID8/IFwiaG9kbm90YVwifSBtdXNcdTAwRUQgbVx1MDBFRHQgJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXQgPz8gXCJwcnZrXHUwMTZGXCJ9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYEhvZG5vdGEgamUgcFx1MDE1OVx1MDBFRGxpXHUwMTYxIHZlbGtcdTAwRTE6ICR7aXNzdWUub3JpZ2luID8/IFwiaG9kbm90YVwifSBtdXNcdTAwRUQgYlx1MDBGRHQgJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIj49XCIgOiBcIj5cIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgSG9kbm90YSBqZSBwXHUwMTU5XHUwMEVEbGlcdTAxNjEgbWFsXHUwMEUxOiAke2lzc3VlLm9yaWdpbiA/PyBcImhvZG5vdGFcIn0gbXVzXHUwMEVEIG1cdTAwRUR0ICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0ID8/IFwicHJ2a1x1MDE2RlwifWA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBIb2Rub3RhIGplIHBcdTAxNTlcdTAwRURsaVx1MDE2MSBtYWxcdTAwRTE6ICR7aXNzdWUub3JpZ2luID8/IFwiaG9kbm90YVwifSBtdXNcdTAwRUQgYlx1MDBGRHQgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSByZXR1cm4gYE5lcGxhdG5cdTAwRkQgXHUwMTU5ZXRcdTAxMUJ6ZWM6IG11c1x1MDBFRCB6YVx1MDEwRFx1MDBFRG5hdCBuYSBcIiR7X2lzc3VlLnByZWZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYE5lcGxhdG5cdTAwRkQgXHUwMTU5ZXRcdTAxMUJ6ZWM6IG11c1x1MDBFRCBrb25cdTAxMERpdCBuYSBcIiR7X2lzc3VlLnN1ZmZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImluY2x1ZGVzXCIpIHJldHVybiBgTmVwbGF0blx1MDBGRCBcdTAxNTlldFx1MDExQnplYzogbXVzXHUwMEVEIG9ic2Fob3ZhdCBcIiR7X2lzc3VlLmluY2x1ZGVzfVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBOZXBsYXRuXHUwMEZEIFx1MDE1OWV0XHUwMTFCemVjOiBtdXNcdTAwRUQgb2Rwb3ZcdTAwRURkYXQgdnpvcnUgJHtfaXNzdWUucGF0dGVybn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYE5lcGxhdG5cdTAwRkQgZm9ybVx1MDBFMXQgJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOZXBsYXRuXHUwMEU5IFx1MDEwRFx1MDBFRHNsbzogbXVzXHUwMEVEIGJcdTAwRkR0IG5cdTAwRTFzb2JrZW0gJHtpc3N1ZS5kaXZpc29yfWA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYE5lem5cdTAwRTFtXHUwMEU5IGtsXHUwMEVEXHUwMTBEZTogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgXCIsIFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfa2V5XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOZXBsYXRuXHUwMEZEIGtsXHUwMEVEXHUwMTBEIHYgJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3VuaW9uXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiTmVwbGF0blx1MDBGRCB2c3R1cFwiO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZWxlbWVudFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgTmVwbGF0blx1MDBFMSBob2Rub3RhIHYgJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOZXBsYXRuXHUwMEZEIHZzdHVwYDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJ0ZWduXCIsXG4gICAgICAgICAgICB2ZXJiOiBcImhhdmRlXCJcbiAgICAgICAgfSxcbiAgICAgICAgZmlsZToge1xuICAgICAgICAgICAgdW5pdDogXCJieXRlc1wiLFxuICAgICAgICAgICAgdmVyYjogXCJoYXZkZVwiXG4gICAgICAgIH0sXG4gICAgICAgIGFycmF5OiB7XG4gICAgICAgICAgICB1bml0OiBcImVsZW1lbnRlclwiLFxuICAgICAgICAgICAgdmVyYjogXCJpbmRlaG9sZHRcIlxuICAgICAgICB9LFxuICAgICAgICBzZXQ6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiZWxlbWVudGVyXCIsXG4gICAgICAgICAgICB2ZXJiOiBcImluZGVob2xkdFwiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGNvbnN0IFR5cGVOYW1lcyA9IHtcbiAgICAgICAgc3RyaW5nOiBcInN0cmVuZ1wiLFxuICAgICAgICBudW1iZXI6IFwidGFsXCIsXG4gICAgICAgIGJvb2xlYW46IFwiYm9vbGVhblwiLFxuICAgICAgICBhcnJheTogXCJsaXN0ZVwiLFxuICAgICAgICBvYmplY3Q6IFwib2JqZWt0XCIsXG4gICAgICAgIHNldDogXCJzXHUwMEU2dFwiLFxuICAgICAgICBmaWxlOiBcImZpbFwiXG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgZnVuY3Rpb24gZ2V0VHlwZU5hbWUodHlwZSkge1xuICAgICAgICByZXR1cm4gVHlwZU5hbWVzW3R5cGVdID8/IHR5cGU7XG4gICAgfVxuICAgIGNvbnN0IHBhcnNlZFR5cGUgPSAoZGF0YSk9PntcbiAgICAgICAgY29uc3QgdCA9IHR5cGVvZiBkYXRhO1xuICAgICAgICBzd2l0Y2godCl7XG4gICAgICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gTnVtYmVyLmlzTmFOKGRhdGEpID8gXCJOYU5cIiA6IFwidGFsXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm9iamVjdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcImxpc3RlXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGEgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm51bGxcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKGRhdGEpICE9PSBPYmplY3QucHJvdG90eXBlICYmIGRhdGEuY29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwib2JqZWt0XCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcImlucHV0XCIsXG4gICAgICAgIGVtYWlsOiBcImUtbWFpbGFkcmVzc2VcIixcbiAgICAgICAgdXJsOiBcIlVSTFwiLFxuICAgICAgICBlbW9qaTogXCJlbW9qaVwiLFxuICAgICAgICB1dWlkOiBcIlVVSURcIixcbiAgICAgICAgdXVpZHY0OiBcIlVVSUR2NFwiLFxuICAgICAgICB1dWlkdjY6IFwiVVVJRHY2XCIsXG4gICAgICAgIG5hbm9pZDogXCJuYW5vaWRcIixcbiAgICAgICAgZ3VpZDogXCJHVUlEXCIsXG4gICAgICAgIGN1aWQ6IFwiY3VpZFwiLFxuICAgICAgICBjdWlkMjogXCJjdWlkMlwiLFxuICAgICAgICB1bGlkOiBcIlVMSURcIixcbiAgICAgICAgeGlkOiBcIlhJRFwiLFxuICAgICAgICBrc3VpZDogXCJLU1VJRFwiLFxuICAgICAgICBkYXRldGltZTogXCJJU08gZGF0by0gb2cga2xva2tlc2xcdTAwRTZ0XCIsXG4gICAgICAgIGRhdGU6IFwiSVNPLWRhdG9cIixcbiAgICAgICAgdGltZTogXCJJU08ta2xva2tlc2xcdTAwRTZ0XCIsXG4gICAgICAgIGR1cmF0aW9uOiBcIklTTy12YXJpZ2hlZFwiLFxuICAgICAgICBpcHY0OiBcIklQdjQtb21yXHUwMEU1ZGVcIixcbiAgICAgICAgaXB2NjogXCJJUHY2LW9tclx1MDBFNWRlXCIsXG4gICAgICAgIGNpZHJ2NDogXCJJUHY0LXNwZWt0cnVtXCIsXG4gICAgICAgIGNpZHJ2NjogXCJJUHY2LXNwZWt0cnVtXCIsXG4gICAgICAgIGJhc2U2NDogXCJiYXNlNjQta29kZXQgc3RyZW5nXCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJiYXNlNjR1cmwta29kZXQgc3RyZW5nXCIsXG4gICAgICAgIGpzb25fc3RyaW5nOiBcIkpTT04tc3RyZW5nXCIsXG4gICAgICAgIGUxNjQ6IFwiRS4xNjQtbnVtbWVyXCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJpbnB1dFwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBVZ3lsZGlndCBpbnB1dDogZm9ydmVudGVkZSAke2dldFR5cGVOYW1lKGlzc3VlLmV4cGVjdGVkKX0sIGZpayAke2dldFR5cGVOYW1lKHBhcnNlZFR5cGUoaXNzdWUuaW5wdXQpKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBVZ3lsZGlnIHZcdTAwRTZyZGk6IGZvcnZlbnRlZGUgJHt1dGlsLnN0cmluZ2lmeVByaW1pdGl2ZShpc3N1ZS52YWx1ZXNbMF0pfWA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBVZ3lsZGlndCB2YWxnOiBmb3J2ZW50ZWRlIGVuIGFmIGZcdTAwRjhsZ2VuZGUgJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIjw9XCIgOiBcIjxcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG9yaWdpbiA9IGdldFR5cGVOYW1lKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgRm9yIHN0b3I6IGZvcnZlbnRlZGUgJHtvcmlnaW4gPz8gXCJ2YWx1ZVwifSAke3NpemluZy52ZXJifSAke2Fkan0gJHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXQgPz8gXCJlbGVtZW50ZXJcIn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYEZvciBzdG9yOiBmb3J2ZW50ZWRlICR7b3JpZ2luID8/IFwidmFsdWVcIn0gaGF2ZGUgJHthZGp9ICR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInRvb19zbWFsbFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI+PVwiIDogXCI+XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBvcmlnaW4gPSBnZXRUeXBlTmFtZShpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYEZvciBsaWxsZTogZm9ydmVudGVkZSAke29yaWdpbn0gJHtzaXppbmcudmVyYn0gJHthZGp9ICR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0fWA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBGb3IgbGlsbGU6IGZvcnZlbnRlZGUgJHtvcmlnaW59IGhhdmRlICR7YWRqfSAke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2Zvcm1hdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgX2lzc3VlID0gaXNzdWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInN0YXJ0c193aXRoXCIpIHJldHVybiBgVWd5bGRpZyBzdHJlbmc6IHNrYWwgc3RhcnRlIG1lZCBcIiR7X2lzc3VlLnByZWZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYFVneWxkaWcgc3RyZW5nOiBza2FsIGVuZGUgbWVkIFwiJHtfaXNzdWUuc3VmZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBVZ3lsZGlnIHN0cmVuZzogc2thbCBpbmRlaG9sZGUgXCIke19pc3N1ZS5pbmNsdWRlc31cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInJlZ2V4XCIpIHJldHVybiBgVWd5bGRpZyBzdHJlbmc6IHNrYWwgbWF0Y2hlIG1cdTAwRjhuc3RlcmV0ICR7X2lzc3VlLnBhdHRlcm59YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBVZ3lsZGlnICR7Tm91bnNbX2lzc3VlLmZvcm1hdF0gPz8gaXNzdWUuZm9ybWF0fWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm5vdF9tdWx0aXBsZV9vZlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgVWd5bGRpZ3QgdGFsOiBza2FsIHZcdTAwRTZyZSBkZWxlbGlndCBtZWQgJHtpc3N1ZS5kaXZpc29yfWA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYCR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJVa2VuZHRlIG5cdTAwRjhnbGVyXCIgOiBcIlVrZW5kdCBuXHUwMEY4Z2xlXCJ9OiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIiwgXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFVneWxkaWcgblx1MDBGOGdsZSBpICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF91bmlvblwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIlVneWxkaWd0IGlucHV0OiBtYXRjaGVyIGluZ2VuIGFmIGRlIHRpbGxhZHRlIHR5cGVyXCI7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9lbGVtZW50XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBVZ3lsZGlnIHZcdTAwRTZyZGkgaSAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFVneWxkaWd0IGlucHV0YDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJaZWljaGVuXCIsXG4gICAgICAgICAgICB2ZXJiOiBcInp1IGhhYmVuXCJcbiAgICAgICAgfSxcbiAgICAgICAgZmlsZToge1xuICAgICAgICAgICAgdW5pdDogXCJCeXRlc1wiLFxuICAgICAgICAgICAgdmVyYjogXCJ6dSBoYWJlblwiXG4gICAgICAgIH0sXG4gICAgICAgIGFycmF5OiB7XG4gICAgICAgICAgICB1bml0OiBcIkVsZW1lbnRlXCIsXG4gICAgICAgICAgICB2ZXJiOiBcInp1IGhhYmVuXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcIkVsZW1lbnRlXCIsXG4gICAgICAgICAgICB2ZXJiOiBcInp1IGhhYmVuXCJcbiAgICAgICAgfVxuICAgIH07XG4gICAgZnVuY3Rpb24gZ2V0U2l6aW5nKG9yaWdpbikge1xuICAgICAgICByZXR1cm4gU2l6YWJsZVtvcmlnaW5dID8/IG51bGw7XG4gICAgfVxuICAgIGNvbnN0IHBhcnNlZFR5cGUgPSAoZGF0YSk9PntcbiAgICAgICAgY29uc3QgdCA9IHR5cGVvZiBkYXRhO1xuICAgICAgICBzd2l0Y2godCl7XG4gICAgICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gTnVtYmVyLmlzTmFOKGRhdGEpID8gXCJOYU5cIiA6IFwiWmFobFwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJBcnJheVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJudWxsXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcIkVpbmdhYmVcIixcbiAgICAgICAgZW1haWw6IFwiRS1NYWlsLUFkcmVzc2VcIixcbiAgICAgICAgdXJsOiBcIlVSTFwiLFxuICAgICAgICBlbW9qaTogXCJFbW9qaVwiLFxuICAgICAgICB1dWlkOiBcIlVVSURcIixcbiAgICAgICAgdXVpZHY0OiBcIlVVSUR2NFwiLFxuICAgICAgICB1dWlkdjY6IFwiVVVJRHY2XCIsXG4gICAgICAgIG5hbm9pZDogXCJuYW5vaWRcIixcbiAgICAgICAgZ3VpZDogXCJHVUlEXCIsXG4gICAgICAgIGN1aWQ6IFwiY3VpZFwiLFxuICAgICAgICBjdWlkMjogXCJjdWlkMlwiLFxuICAgICAgICB1bGlkOiBcIlVMSURcIixcbiAgICAgICAgeGlkOiBcIlhJRFwiLFxuICAgICAgICBrc3VpZDogXCJLU1VJRFwiLFxuICAgICAgICBkYXRldGltZTogXCJJU08tRGF0dW0gdW5kIC1VaHJ6ZWl0XCIsXG4gICAgICAgIGRhdGU6IFwiSVNPLURhdHVtXCIsXG4gICAgICAgIHRpbWU6IFwiSVNPLVVocnplaXRcIixcbiAgICAgICAgZHVyYXRpb246IFwiSVNPLURhdWVyXCIsXG4gICAgICAgIGlwdjQ6IFwiSVB2NC1BZHJlc3NlXCIsXG4gICAgICAgIGlwdjY6IFwiSVB2Ni1BZHJlc3NlXCIsXG4gICAgICAgIGNpZHJ2NDogXCJJUHY0LUJlcmVpY2hcIixcbiAgICAgICAgY2lkcnY2OiBcIklQdjYtQmVyZWljaFwiLFxuICAgICAgICBiYXNlNjQ6IFwiQmFzZTY0LWNvZGllcnRlciBTdHJpbmdcIixcbiAgICAgICAgYmFzZTY0dXJsOiBcIkJhc2U2NC1VUkwtY29kaWVydGVyIFN0cmluZ1wiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJKU09OLVN0cmluZ1wiLFxuICAgICAgICBlMTY0OiBcIkUuMTY0LU51bW1lclwiLFxuICAgICAgICBqd3Q6IFwiSldUXCIsXG4gICAgICAgIHRlbXBsYXRlX2xpdGVyYWw6IFwiRWluZ2FiZVwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBVbmdcdTAwRkNsdGlnZSBFaW5nYWJlOiBlcndhcnRldCAke2lzc3VlLmV4cGVjdGVkfSwgZXJoYWx0ZW4gJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBVbmdcdTAwRkNsdGlnZSBFaW5nYWJlOiBlcndhcnRldCAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYFVuZ1x1MDBGQ2x0aWdlIE9wdGlvbjogZXJ3YXJ0ZXQgZWluZSB2b24gJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIjw9XCIgOiBcIjxcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgWnUgZ3JvXHUwMERGOiBlcndhcnRldCwgZGFzcyAke2lzc3VlLm9yaWdpbiA/PyBcIldlcnRcIn0gJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXQgPz8gXCJFbGVtZW50ZVwifSBoYXRgO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFp1IGdyb1x1MDBERjogZXJ3YXJ0ZXQsIGRhc3MgJHtpc3N1ZS5vcmlnaW4gPz8gXCJXZXJ0XCJ9ICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSBpc3RgO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJ0b29fc21hbGxcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPj1cIiA6IFwiPlwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBadSBrbGVpbjogZXJ3YXJ0ZXQsIGRhc3MgJHtpc3N1ZS5vcmlnaW59ICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0fSBoYXRgO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgWnUga2xlaW46IGVyd2FydGV0LCBkYXNzICR7aXNzdWUub3JpZ2lufSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gaXN0YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSByZXR1cm4gYFVuZ1x1MDBGQ2x0aWdlciBTdHJpbmc6IG11c3MgbWl0IFwiJHtfaXNzdWUucHJlZml4fVwiIGJlZ2lubmVuYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiZW5kc193aXRoXCIpIHJldHVybiBgVW5nXHUwMEZDbHRpZ2VyIFN0cmluZzogbXVzcyBtaXQgXCIke19pc3N1ZS5zdWZmaXh9XCIgZW5kZW5gO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJpbmNsdWRlc1wiKSByZXR1cm4gYFVuZ1x1MDBGQ2x0aWdlciBTdHJpbmc6IG11c3MgXCIke19pc3N1ZS5pbmNsdWRlc31cIiBlbnRoYWx0ZW5gO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYFVuZ1x1MDBGQ2x0aWdlciBTdHJpbmc6IG11c3MgZGVtIE11c3RlciAke19pc3N1ZS5wYXR0ZXJufSBlbnRzcHJlY2hlbmA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgVW5nXHUwMEZDbHRpZzogJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBVbmdcdTAwRkNsdGlnZSBaYWhsOiBtdXNzIGVpbiBWaWVsZmFjaGVzIHZvbiAke2lzc3VlLmRpdmlzb3J9IHNlaW5gO1xuICAgICAgICAgICAgY2FzZSBcInVucmVjb2duaXplZF9rZXlzXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGAke2lzc3VlLmtleXMubGVuZ3RoID4gMSA/IFwiVW5iZWthbm50ZSBTY2hsXHUwMEZDc3NlbFwiIDogXCJVbmJla2FubnRlciBTY2hsXHUwMEZDc3NlbFwifTogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgXCIsIFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfa2V5XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBVbmdcdTAwRkNsdGlnZXIgU2NobFx1MDBGQ3NzZWwgaW4gJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3VuaW9uXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiVW5nXHUwMEZDbHRpZ2UgRWluZ2FiZVwiO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZWxlbWVudFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgVW5nXHUwMEZDbHRpZ2VyIFdlcnQgaW4gJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBVbmdcdTAwRkNsdGlnZSBFaW5nYWJlYDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuZXhwb3J0IGNvbnN0IHBhcnNlZFR5cGUgPSAoZGF0YSk9PntcbiAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgc3dpdGNoKHQpe1xuICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIm51bWJlclwiO1xuICAgICAgICAgICAgfVxuICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiYXJyYXlcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGRhdGEgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKGRhdGEpICE9PSBPYmplY3QucHJvdG90eXBlICYmIGRhdGEuY29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0O1xufTtcbmNvbnN0IGVycm9yID0gKCk9PntcbiAgICBjb25zdCBTaXphYmxlID0ge1xuICAgICAgICBzdHJpbmc6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiY2hhcmFjdGVyc1wiLFxuICAgICAgICAgICAgdmVyYjogXCJ0byBoYXZlXCJcbiAgICAgICAgfSxcbiAgICAgICAgZmlsZToge1xuICAgICAgICAgICAgdW5pdDogXCJieXRlc1wiLFxuICAgICAgICAgICAgdmVyYjogXCJ0byBoYXZlXCJcbiAgICAgICAgfSxcbiAgICAgICAgYXJyYXk6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiaXRlbXNcIixcbiAgICAgICAgICAgIHZlcmI6IFwidG8gaGF2ZVwiXG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDogXCJpdGVtc1wiLFxuICAgICAgICAgICAgdmVyYjogXCJ0byBoYXZlXCJcbiAgICAgICAgfVxuICAgIH07XG4gICAgZnVuY3Rpb24gZ2V0U2l6aW5nKG9yaWdpbikge1xuICAgICAgICByZXR1cm4gU2l6YWJsZVtvcmlnaW5dID8/IG51bGw7XG4gICAgfVxuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJpbnB1dFwiLFxuICAgICAgICBlbWFpbDogXCJlbWFpbCBhZGRyZXNzXCIsXG4gICAgICAgIHVybDogXCJVUkxcIixcbiAgICAgICAgZW1vamk6IFwiZW1vamlcIixcbiAgICAgICAgdXVpZDogXCJVVUlEXCIsXG4gICAgICAgIHV1aWR2NDogXCJVVUlEdjRcIixcbiAgICAgICAgdXVpZHY2OiBcIlVVSUR2NlwiLFxuICAgICAgICBuYW5vaWQ6IFwibmFub2lkXCIsXG4gICAgICAgIGd1aWQ6IFwiR1VJRFwiLFxuICAgICAgICBjdWlkOiBcImN1aWRcIixcbiAgICAgICAgY3VpZDI6IFwiY3VpZDJcIixcbiAgICAgICAgdWxpZDogXCJVTElEXCIsXG4gICAgICAgIHhpZDogXCJYSURcIixcbiAgICAgICAga3N1aWQ6IFwiS1NVSURcIixcbiAgICAgICAgZGF0ZXRpbWU6IFwiSVNPIGRhdGV0aW1lXCIsXG4gICAgICAgIGRhdGU6IFwiSVNPIGRhdGVcIixcbiAgICAgICAgdGltZTogXCJJU08gdGltZVwiLFxuICAgICAgICBkdXJhdGlvbjogXCJJU08gZHVyYXRpb25cIixcbiAgICAgICAgaXB2NDogXCJJUHY0IGFkZHJlc3NcIixcbiAgICAgICAgaXB2NjogXCJJUHY2IGFkZHJlc3NcIixcbiAgICAgICAgY2lkcnY0OiBcIklQdjQgcmFuZ2VcIixcbiAgICAgICAgY2lkcnY2OiBcIklQdjYgcmFuZ2VcIixcbiAgICAgICAgYmFzZTY0OiBcImJhc2U2NC1lbmNvZGVkIHN0cmluZ1wiLFxuICAgICAgICBiYXNlNjR1cmw6IFwiYmFzZTY0dXJsLWVuY29kZWQgc3RyaW5nXCIsXG4gICAgICAgIGpzb25fc3RyaW5nOiBcIkpTT04gc3RyaW5nXCIsXG4gICAgICAgIGUxNjQ6IFwiRS4xNjQgbnVtYmVyXCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJpbnB1dFwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBJbnZhbGlkIGlucHV0OiBleHBlY3RlZCAke2lzc3VlLmV4cGVjdGVkfSwgcmVjZWl2ZWQgJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBJbnZhbGlkIGlucHV0OiBleHBlY3RlZCAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYEludmFsaWQgb3B0aW9uOiBleHBlY3RlZCBvbmUgb2YgJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIjw9XCIgOiBcIjxcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgVG9vIGJpZzogZXhwZWN0ZWQgJHtpc3N1ZS5vcmlnaW4gPz8gXCJ2YWx1ZVwifSB0byBoYXZlICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0ID8/IFwiZWxlbWVudHNcIn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFRvbyBiaWc6IGV4cGVjdGVkICR7aXNzdWUub3JpZ2luID8/IFwidmFsdWVcIn0gdG8gYmUgJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIj49XCIgOiBcIj5cIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgVG9vIHNtYWxsOiBleHBlY3RlZCAke2lzc3VlLm9yaWdpbn0gdG8gaGF2ZSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdH1gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgVG9vIHNtYWxsOiBleHBlY3RlZCAke2lzc3VlLm9yaWdpbn0gdG8gYmUgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYEludmFsaWQgc3RyaW5nOiBtdXN0IHN0YXJ0IHdpdGggXCIke19pc3N1ZS5wcmVmaXh9XCJgO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYEludmFsaWQgc3RyaW5nOiBtdXN0IGVuZCB3aXRoIFwiJHtfaXNzdWUuc3VmZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBJbnZhbGlkIHN0cmluZzogbXVzdCBpbmNsdWRlIFwiJHtfaXNzdWUuaW5jbHVkZXN9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYEludmFsaWQgc3RyaW5nOiBtdXN0IG1hdGNoIHBhdHRlcm4gJHtfaXNzdWUucGF0dGVybn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYEludmFsaWQgJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBJbnZhbGlkIG51bWJlcjogbXVzdCBiZSBhIG11bHRpcGxlIG9mICR7aXNzdWUuZGl2aXNvcn1gO1xuICAgICAgICAgICAgY2FzZSBcInVucmVjb2duaXplZF9rZXlzXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBVbnJlY29nbml6ZWQga2V5JHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcInNcIiA6IFwiXCJ9OiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIiwgXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYEludmFsaWQga2V5IGluICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF91bmlvblwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIkludmFsaWQgaW5wdXRcIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYEludmFsaWQgdmFsdWUgaW4gJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBJbnZhbGlkIGlucHV0YDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuZXhwb3J0IGNvbnN0IHBhcnNlZFR5cGUgPSAoZGF0YSk9PntcbiAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgc3dpdGNoKHQpe1xuICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIm5vbWJyb1wiO1xuICAgICAgICAgICAgfVxuICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwidGFiZWxvXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcInNlbnZhbG9yYVwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKGRhdGEpICE9PSBPYmplY3QucHJvdG90eXBlICYmIGRhdGEuY29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0O1xufTtcbmNvbnN0IGVycm9yID0gKCk9PntcbiAgICBjb25zdCBTaXphYmxlID0ge1xuICAgICAgICBzdHJpbmc6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwia2FyYWt0cm9qblwiLFxuICAgICAgICAgICAgdmVyYjogXCJoYXZpXCJcbiAgICAgICAgfSxcbiAgICAgICAgZmlsZToge1xuICAgICAgICAgICAgdW5pdDogXCJiYWp0b2puXCIsXG4gICAgICAgICAgICB2ZXJiOiBcImhhdmlcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJlbGVtZW50b2puXCIsXG4gICAgICAgICAgICB2ZXJiOiBcImhhdmlcIlxuICAgICAgICB9LFxuICAgICAgICBzZXQ6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiZWxlbWVudG9qblwiLFxuICAgICAgICAgICAgdmVyYjogXCJoYXZpXCJcbiAgICAgICAgfVxuICAgIH07XG4gICAgZnVuY3Rpb24gZ2V0U2l6aW5nKG9yaWdpbikge1xuICAgICAgICByZXR1cm4gU2l6YWJsZVtvcmlnaW5dID8/IG51bGw7XG4gICAgfVxuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJlbmlnb1wiLFxuICAgICAgICBlbWFpbDogXCJyZXRhZHJlc29cIixcbiAgICAgICAgdXJsOiBcIlVSTFwiLFxuICAgICAgICBlbW9qaTogXCJlbW9cdTAxMURpb1wiLFxuICAgICAgICB1dWlkOiBcIlVVSURcIixcbiAgICAgICAgdXVpZHY0OiBcIlVVSUR2NFwiLFxuICAgICAgICB1dWlkdjY6IFwiVVVJRHY2XCIsXG4gICAgICAgIG5hbm9pZDogXCJuYW5vaWRcIixcbiAgICAgICAgZ3VpZDogXCJHVUlEXCIsXG4gICAgICAgIGN1aWQ6IFwiY3VpZFwiLFxuICAgICAgICBjdWlkMjogXCJjdWlkMlwiLFxuICAgICAgICB1bGlkOiBcIlVMSURcIixcbiAgICAgICAgeGlkOiBcIlhJRFwiLFxuICAgICAgICBrc3VpZDogXCJLU1VJRFwiLFxuICAgICAgICBkYXRldGltZTogXCJJU08tZGF0b3RlbXBvXCIsXG4gICAgICAgIGRhdGU6IFwiSVNPLWRhdG9cIixcbiAgICAgICAgdGltZTogXCJJU08tdGVtcG9cIixcbiAgICAgICAgZHVyYXRpb246IFwiSVNPLWRhXHUwMTZEcm9cIixcbiAgICAgICAgaXB2NDogXCJJUHY0LWFkcmVzb1wiLFxuICAgICAgICBpcHY2OiBcIklQdjYtYWRyZXNvXCIsXG4gICAgICAgIGNpZHJ2NDogXCJJUHY0LXJhbmdvXCIsXG4gICAgICAgIGNpZHJ2NjogXCJJUHY2LXJhbmdvXCIsXG4gICAgICAgIGJhc2U2NDogXCI2NC11bWUga29kaXRhIGthcmFrdHJhcm9cIixcbiAgICAgICAgYmFzZTY0dXJsOiBcIlVSTC02NC11bWUga29kaXRhIGthcmFrdHJhcm9cIixcbiAgICAgICAganNvbl9zdHJpbmc6IFwiSlNPTi1rYXJha3RyYXJvXCIsXG4gICAgICAgIGUxNjQ6IFwiRS4xNjQtbm9tYnJvXCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJlbmlnb1wiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOZXZhbGlkYSBlbmlnbzogYXRlbmRpXHUwMTFEaXMgJHtpc3N1ZS5leHBlY3RlZH0sIHJpY2V2aVx1MDExRGlzICR7cGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgTmV2YWxpZGEgZW5pZ286IGF0ZW5kaVx1MDExRGlzICR7dXRpbC5zdHJpbmdpZnlQcmltaXRpdmUoaXNzdWUudmFsdWVzWzBdKX1gO1xuICAgICAgICAgICAgICAgIHJldHVybiBgTmV2YWxpZGEgb3BjaW86IGF0ZW5kaVx1MDExRGlzIHVudSBlbCAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS52YWx1ZXMsIFwifFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPD1cIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykgcmV0dXJuIGBUcm8gZ3JhbmRhOiBhdGVuZGlcdTAxMURpcyBrZSAke2lzc3VlLm9yaWdpbiA/PyBcInZhbG9yb1wifSBoYXZ1ICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0ID8/IFwiZWxlbWVudG9qblwifWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgVHJvIGdyYW5kYTogYXRlbmRpXHUwMTFEaXMga2UgJHtpc3N1ZS5vcmlnaW4gPz8gXCJ2YWxvcm9cIn0gaGF2dSAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJ0b29fc21hbGxcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPj1cIiA6IFwiPlwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBUcm8gbWFsZ3JhbmRhOiBhdGVuZGlcdTAxMURpcyBrZSAke2lzc3VlLm9yaWdpbn0gaGF2dSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdH1gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgVHJvIG1hbGdyYW5kYTogYXRlbmRpXHUwMTFEaXMga2UgJHtpc3N1ZS5vcmlnaW59IGVzdHUgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSByZXR1cm4gYE5ldmFsaWRhIGthcmFrdHJhcm86IGRldmFzIGtvbWVuY2lcdTAxMURpIHBlciBcIiR7X2lzc3VlLnByZWZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYE5ldmFsaWRhIGthcmFrdHJhcm86IGRldmFzIGZpbmlcdTAxMURpIHBlciBcIiR7X2lzc3VlLnN1ZmZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImluY2x1ZGVzXCIpIHJldHVybiBgTmV2YWxpZGEga2FyYWt0cmFybzogZGV2YXMgaW5rbHV6aXZpIFwiJHtfaXNzdWUuaW5jbHVkZXN9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYE5ldmFsaWRhIGthcmFrdHJhcm86IGRldmFzIGtvbmdydWkga3VuIGxhIG1vZGVsbyAke19pc3N1ZS5wYXR0ZXJufWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgTmV2YWxpZGEgJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOZXZhbGlkYSBub21icm86IGRldmFzIGVzdGkgb2JsbyBkZSAke2lzc3VlLmRpdmlzb3J9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ1bnJlY29nbml6ZWRfa2V5c1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgTmVrb25hdGEke2lzc3VlLmtleXMubGVuZ3RoID4gMSA/IFwialwiIDogXCJcIn0gXHUwMTVEbG9zaWxvJHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcImpcIiA6IFwiXCJ9OiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIiwgXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYE5ldmFsaWRhIFx1MDE1RGxvc2lsbyBlbiAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJOZXZhbGlkYSBlbmlnb1wiO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZWxlbWVudFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgTmV2YWxpZGEgdmFsb3JvIGVuICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBgTmV2YWxpZGEgZW5pZ29gO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBsb2NhbGVFcnJvcjogZXJyb3IoKVxuICAgIH07XG59XG4iLCAiaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi4vY29yZS91dGlsLmpzXCI7XG5jb25zdCBlcnJvciA9ICgpPT57XG4gICAgY29uc3QgU2l6YWJsZSA9IHtcbiAgICAgICAgc3RyaW5nOiB7XG4gICAgICAgICAgICB1bml0OiBcImNhcmFjdGVyZXNcIixcbiAgICAgICAgICAgIHZlcmI6IFwidGVuZXJcIlxuICAgICAgICB9LFxuICAgICAgICBmaWxlOiB7XG4gICAgICAgICAgICB1bml0OiBcImJ5dGVzXCIsXG4gICAgICAgICAgICB2ZXJiOiBcInRlbmVyXCJcbiAgICAgICAgfSxcbiAgICAgICAgYXJyYXk6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiZWxlbWVudG9zXCIsXG4gICAgICAgICAgICB2ZXJiOiBcInRlbmVyXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcImVsZW1lbnRvc1wiLFxuICAgICAgICAgICAgdmVyYjogXCJ0ZW5lclwiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGNvbnN0IFR5cGVOYW1lcyA9IHtcbiAgICAgICAgc3RyaW5nOiBcInRleHRvXCIsXG4gICAgICAgIG51bWJlcjogXCJuXHUwMEZBbWVyb1wiLFxuICAgICAgICBib29sZWFuOiBcImJvb2xlYW5vXCIsXG4gICAgICAgIGFycmF5OiBcImFycmVnbG9cIixcbiAgICAgICAgb2JqZWN0OiBcIm9iamV0b1wiLFxuICAgICAgICBzZXQ6IFwiY29uanVudG9cIixcbiAgICAgICAgZmlsZTogXCJhcmNoaXZvXCIsXG4gICAgICAgIGRhdGU6IFwiZmVjaGFcIixcbiAgICAgICAgYmlnaW50OiBcIm5cdTAwRkFtZXJvIGdyYW5kZVwiLFxuICAgICAgICBzeW1ib2w6IFwic1x1MDBFRG1ib2xvXCIsXG4gICAgICAgIHVuZGVmaW5lZDogXCJpbmRlZmluaWRvXCIsXG4gICAgICAgIG51bGw6IFwibnVsb1wiLFxuICAgICAgICBmdW5jdGlvbjogXCJmdW5jaVx1MDBGM25cIixcbiAgICAgICAgbWFwOiBcIm1hcGFcIixcbiAgICAgICAgcmVjb3JkOiBcInJlZ2lzdHJvXCIsXG4gICAgICAgIHR1cGxlOiBcInR1cGxhXCIsXG4gICAgICAgIGVudW06IFwiZW51bWVyYWNpXHUwMEYzblwiLFxuICAgICAgICB1bmlvbjogXCJ1bmlcdTAwRjNuXCIsXG4gICAgICAgIGxpdGVyYWw6IFwibGl0ZXJhbFwiLFxuICAgICAgICBwcm9taXNlOiBcInByb21lc2FcIixcbiAgICAgICAgdm9pZDogXCJ2YWNcdTAwRURvXCIsXG4gICAgICAgIG5ldmVyOiBcIm51bmNhXCIsXG4gICAgICAgIHVua25vd246IFwiZGVzY29ub2NpZG9cIixcbiAgICAgICAgYW55OiBcImN1YWxxdWllcmFcIlxuICAgIH07XG4gICAgZnVuY3Rpb24gZ2V0U2l6aW5nKG9yaWdpbikge1xuICAgICAgICByZXR1cm4gU2l6YWJsZVtvcmlnaW5dID8/IG51bGw7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGdldFR5cGVOYW1lKHR5cGUpIHtcbiAgICAgICAgcmV0dXJuIFR5cGVOYW1lc1t0eXBlXSA/PyB0eXBlO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWRUeXBlID0gKGRhdGEpPT57XG4gICAgICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICAgICAgc3dpdGNoKHQpe1xuICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIm51bWJlclwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJhcnJheVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJudWxsXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJvYmplY3RcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHQ7XG4gICAgfTtcbiAgICBjb25zdCBOb3VucyA9IHtcbiAgICAgICAgcmVnZXg6IFwiZW50cmFkYVwiLFxuICAgICAgICBlbWFpbDogXCJkaXJlY2NpXHUwMEYzbiBkZSBjb3JyZW8gZWxlY3RyXHUwMEYzbmljb1wiLFxuICAgICAgICB1cmw6IFwiVVJMXCIsXG4gICAgICAgIGVtb2ppOiBcImVtb2ppXCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcImZlY2hhIHkgaG9yYSBJU09cIixcbiAgICAgICAgZGF0ZTogXCJmZWNoYSBJU09cIixcbiAgICAgICAgdGltZTogXCJob3JhIElTT1wiLFxuICAgICAgICBkdXJhdGlvbjogXCJkdXJhY2lcdTAwRjNuIElTT1wiLFxuICAgICAgICBpcHY0OiBcImRpcmVjY2lcdTAwRjNuIElQdjRcIixcbiAgICAgICAgaXB2NjogXCJkaXJlY2NpXHUwMEYzbiBJUHY2XCIsXG4gICAgICAgIGNpZHJ2NDogXCJyYW5nbyBJUHY0XCIsXG4gICAgICAgIGNpZHJ2NjogXCJyYW5nbyBJUHY2XCIsXG4gICAgICAgIGJhc2U2NDogXCJjYWRlbmEgY29kaWZpY2FkYSBlbiBiYXNlNjRcIixcbiAgICAgICAgYmFzZTY0dXJsOiBcIlVSTCBjb2RpZmljYWRhIGVuIGJhc2U2NFwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJjYWRlbmEgSlNPTlwiLFxuICAgICAgICBlMTY0OiBcIm5cdTAwRkFtZXJvIEUuMTY0XCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJlbnRyYWRhXCJcbiAgICB9O1xuICAgIHJldHVybiAoaXNzdWUpPT57XG4gICAgICAgIHN3aXRjaChpc3N1ZS5jb2RlKXtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3R5cGVcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYEVudHJhZGEgaW52XHUwMEUxbGlkYTogc2UgZXNwZXJhYmEgJHtnZXRUeXBlTmFtZShpc3N1ZS5leHBlY3RlZCl9LCByZWNpYmlkbyAke2dldFR5cGVOYW1lKHBhcnNlZFR5cGUoaXNzdWUuaW5wdXQpKX1gO1xuICAgICAgICAgICAgLy8gcmV0dXJuIGBFbnRyYWRhIGludlx1MDBFMWxpZGE6IHNlIGVzcGVyYWJhICR7aXNzdWUuZXhwZWN0ZWR9LCByZWNpYmlkbyAke3V0aWwuZ2V0UGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgRW50cmFkYSBpbnZcdTAwRTFsaWRhOiBzZSBlc3BlcmFiYSAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYE9wY2lcdTAwRjNuIGludlx1MDBFMWxpZGE6IHNlIGVzcGVyYWJhIHVuYSBkZSAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS52YWx1ZXMsIFwifFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPD1cIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3JpZ2luID0gZ2V0VHlwZU5hbWUoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykgcmV0dXJuIGBEZW1hc2lhZG8gZ3JhbmRlOiBzZSBlc3BlcmFiYSBxdWUgJHtvcmlnaW4gPz8gXCJ2YWxvclwifSB0dXZpZXJhICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0ID8/IFwiZWxlbWVudG9zXCJ9YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBEZW1hc2lhZG8gZ3JhbmRlOiBzZSBlc3BlcmFiYSBxdWUgJHtvcmlnaW4gPz8gXCJ2YWxvclwifSBmdWVyYSAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJ0b29fc21hbGxcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPj1cIiA6IFwiPlwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3JpZ2luID0gZ2V0VHlwZU5hbWUoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBEZW1hc2lhZG8gcGVxdWVcdTAwRjFvOiBzZSBlc3BlcmFiYSBxdWUgJHtvcmlnaW59IHR1dmllcmEgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXR9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYERlbWFzaWFkbyBwZXF1ZVx1MDBGMW86IHNlIGVzcGVyYWJhIHF1ZSAke29yaWdpbn0gZnVlcmEgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSByZXR1cm4gYENhZGVuYSBpbnZcdTAwRTFsaWRhOiBkZWJlIGNvbWVuemFyIGNvbiBcIiR7X2lzc3VlLnByZWZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYENhZGVuYSBpbnZcdTAwRTFsaWRhOiBkZWJlIHRlcm1pbmFyIGVuIFwiJHtfaXNzdWUuc3VmZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBDYWRlbmEgaW52XHUwMEUxbGlkYTogZGViZSBpbmNsdWlyIFwiJHtfaXNzdWUuaW5jbHVkZXN9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYENhZGVuYSBpbnZcdTAwRTFsaWRhOiBkZWJlIGNvaW5jaWRpciBjb24gZWwgcGF0clx1MDBGM24gJHtfaXNzdWUucGF0dGVybn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYEludlx1MDBFMWxpZG8gJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOXHUwMEZBbWVybyBpbnZcdTAwRTFsaWRvOiBkZWJlIHNlciBtXHUwMEZBbHRpcGxvIGRlICR7aXNzdWUuZGl2aXNvcn1gO1xuICAgICAgICAgICAgY2FzZSBcInVucmVjb2duaXplZF9rZXlzXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBMbGF2ZSR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJzXCIgOiBcIlwifSBkZXNjb25vY2lkYSR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJzXCIgOiBcIlwifTogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgXCIsIFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfa2V5XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBMbGF2ZSBpbnZcdTAwRTFsaWRhIGVuICR7Z2V0VHlwZU5hbWUoaXNzdWUub3JpZ2luKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJFbnRyYWRhIGludlx1MDBFMWxpZGFcIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFZhbG9yIGludlx1MDBFMWxpZG8gZW4gJHtnZXRUeXBlTmFtZShpc3N1ZS5vcmlnaW4pfWA7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBgRW50cmFkYSBpbnZcdTAwRTFsaWRhYDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJcdTA2QTlcdTA2MjdcdTA2MzFcdTA2MjdcdTA2QTlcdTA2MkFcdTA2MzFcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwNjJGXHUwNjI3XHUwNjM0XHUwNjJBXHUwNjQ3IFx1MDYyOFx1MDYyN1x1MDYzNFx1MDYyRlwiXG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHUwNjI4XHUwNjI3XHUwNkNDXHUwNjJBXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MDYyRlx1MDYyN1x1MDYzNFx1MDYyQVx1MDY0NyBcdTA2MjhcdTA2MjdcdTA2MzRcdTA2MkZcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJcdTA2MjJcdTA2Q0NcdTA2MkFcdTA2NDVcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwNjJGXHUwNjI3XHUwNjM0XHUwNjJBXHUwNjQ3IFx1MDYyOFx1MDYyN1x1MDYzNFx1MDYyRlwiXG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDogXCJcdTA2MjJcdTA2Q0NcdTA2MkFcdTA2NDVcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwNjJGXHUwNjI3XHUwNjM0XHUwNjJBXHUwNjQ3IFx1MDYyOFx1MDYyN1x1MDYzNFx1MDYyRlwiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4pIHtcbiAgICAgICAgcmV0dXJuIFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWRUeXBlID0gKGRhdGEpPT57XG4gICAgICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICAgICAgc3dpdGNoKHQpe1xuICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIlx1MDYzOVx1MDYyRlx1MDYyRlwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTA2MjJcdTA2MzFcdTA2MjdcdTA2Q0NcdTA2NDdcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YoZGF0YSkgIT09IE9iamVjdC5wcm90b3R5cGUgJiYgZGF0YS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdDtcbiAgICB9O1xuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJcdTA2NDhcdTA2MzFcdTA2NDhcdTA2MkZcdTA2Q0NcIixcbiAgICAgICAgZW1haWw6IFwiXHUwNjIyXHUwNjJGXHUwNjMxXHUwNjMzIFx1MDYyN1x1MDZDQ1x1MDY0NVx1MDZDQ1x1MDY0NFwiLFxuICAgICAgICB1cmw6IFwiVVJMXCIsXG4gICAgICAgIGVtb2ppOiBcIlx1MDYyN1x1MDZDQ1x1MDY0NVx1MDY0OFx1MDYyQ1x1MDZDQ1wiLFxuICAgICAgICB1dWlkOiBcIlVVSURcIixcbiAgICAgICAgdXVpZHY0OiBcIlVVSUR2NFwiLFxuICAgICAgICB1dWlkdjY6IFwiVVVJRHY2XCIsXG4gICAgICAgIG5hbm9pZDogXCJuYW5vaWRcIixcbiAgICAgICAgZ3VpZDogXCJHVUlEXCIsXG4gICAgICAgIGN1aWQ6IFwiY3VpZFwiLFxuICAgICAgICBjdWlkMjogXCJjdWlkMlwiLFxuICAgICAgICB1bGlkOiBcIlVMSURcIixcbiAgICAgICAgeGlkOiBcIlhJRFwiLFxuICAgICAgICBrc3VpZDogXCJLU1VJRFwiLFxuICAgICAgICBkYXRldGltZTogXCJcdTA2MkFcdTA2MjdcdTA2MzFcdTA2Q0NcdTA2MkUgXHUwNjQ4IFx1MDYzMlx1MDY0NVx1MDYyN1x1MDY0NiBcdTA2MjdcdTA2Q0NcdTA2MzJcdTA2NDhcIixcbiAgICAgICAgZGF0ZTogXCJcdTA2MkFcdTA2MjdcdTA2MzFcdTA2Q0NcdTA2MkUgXHUwNjI3XHUwNkNDXHUwNjMyXHUwNjQ4XCIsXG4gICAgICAgIHRpbWU6IFwiXHUwNjMyXHUwNjQ1XHUwNjI3XHUwNjQ2IFx1MDYyN1x1MDZDQ1x1MDYzMlx1MDY0OFwiLFxuICAgICAgICBkdXJhdGlvbjogXCJcdTA2NDVcdTA2MkZcdTA2MkEgXHUwNjMyXHUwNjQ1XHUwNjI3XHUwNjQ2IFx1MDYyN1x1MDZDQ1x1MDYzMlx1MDY0OFwiLFxuICAgICAgICBpcHY0OiBcIklQdjQgXHUwNjIyXHUwNjJGXHUwNjMxXHUwNjMzXCIsXG4gICAgICAgIGlwdjY6IFwiSVB2NiBcdTA2MjJcdTA2MkZcdTA2MzFcdTA2MzNcIixcbiAgICAgICAgY2lkcnY0OiBcIklQdjQgXHUwNjJGXHUwNjI3XHUwNjQ1XHUwNjQ2XHUwNjQ3XCIsXG4gICAgICAgIGNpZHJ2NjogXCJJUHY2IFx1MDYyRlx1MDYyN1x1MDY0NVx1MDY0Nlx1MDY0N1wiLFxuICAgICAgICBiYXNlNjQ6IFwiYmFzZTY0LWVuY29kZWQgXHUwNjMxXHUwNjM0XHUwNjJBXHUwNjQ3XCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJiYXNlNjR1cmwtZW5jb2RlZCBcdTA2MzFcdTA2MzRcdTA2MkFcdTA2NDdcIixcbiAgICAgICAganNvbl9zdHJpbmc6IFwiSlNPTiBcdTA2MzFcdTA2MzRcdTA2MkFcdTA2NDdcIixcbiAgICAgICAgZTE2NDogXCJFLjE2NCBcdTA2MzlcdTA2MkZcdTA2MkZcIixcbiAgICAgICAgand0OiBcIkpXVFwiLFxuICAgICAgICB0ZW1wbGF0ZV9saXRlcmFsOiBcIlx1MDY0OFx1MDYzMVx1MDY0OFx1MDYyRlx1MDZDQ1wiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2NDhcdTA2MzFcdTA2NDhcdTA2MkZcdTA2Q0MgXHUwNjQ2XHUwNjI3XHUwNjQ1XHUwNjM5XHUwNjJBXHUwNjI4XHUwNjMxOiBcdTA2NDVcdTA2Q0NcdTIwMENcdTA2MjhcdTA2MjdcdTA2Q0NcdTA2MzNcdTA2MkEgJHtpc3N1ZS5leHBlY3RlZH0gXHUwNjQ1XHUwNkNDXHUyMDBDXHUwNjI4XHUwNjQ4XHUwNjJGXHUwNjBDICR7cGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9IFx1MDYyRlx1MDYzMVx1MDZDQ1x1MDYyN1x1MDY0MVx1MDYyQSBcdTA2MzRcdTA2MkZgO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDY0OFx1MDYzMVx1MDY0OFx1MDYyRlx1MDZDQyBcdTA2NDZcdTA2MjdcdTA2NDVcdTA2MzlcdTA2MkFcdTA2MjhcdTA2MzE6IFx1MDY0NVx1MDZDQ1x1MjAwQ1x1MDYyOFx1MDYyN1x1MDZDQ1x1MDYzM1x1MDYyQSAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9IFx1MDY0NVx1MDZDQ1x1MjAwQ1x1MDYyOFx1MDY0OFx1MDYyRmA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNkFGXHUwNjMyXHUwNkNDXHUwNjQ2XHUwNjQ3IFx1MDY0Nlx1MDYyN1x1MDY0NVx1MDYzOVx1MDYyQVx1MDYyOFx1MDYzMTogXHUwNjQ1XHUwNkNDXHUyMDBDXHUwNjI4XHUwNjI3XHUwNkNDXHUwNjMzXHUwNjJBIFx1MDZDQ1x1MDZBOVx1MDZDQyBcdTA2MjdcdTA2MzIgJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9IFx1MDY0NVx1MDZDQ1x1MjAwQ1x1MDYyOFx1MDY0OFx1MDYyRmA7XG4gICAgICAgICAgICBjYXNlIFwidG9vX2JpZ1wiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI8PVwiIDogXCI8XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDYyRVx1MDZDQ1x1MDY0NFx1MDZDQyBcdTA2MjhcdTA2MzJcdTA2MzFcdTA2QUY6ICR7aXNzdWUub3JpZ2luID8/IFwiXHUwNjQ1XHUwNjQyXHUwNjJGXHUwNjI3XHUwNjMxXCJ9IFx1MDYyOFx1MDYyN1x1MDZDQ1x1MDYyRiAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdCA/PyBcIlx1MDYzOVx1MDY0Nlx1MDYzNVx1MDYzMVwifSBcdTA2MjhcdTA2MjdcdTA2MzRcdTA2MkZgO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjJFXHUwNkNDXHUwNjQ0XHUwNkNDIFx1MDYyOFx1MDYzMlx1MDYzMVx1MDZBRjogJHtpc3N1ZS5vcmlnaW4gPz8gXCJcdTA2NDVcdTA2NDJcdTA2MkZcdTA2MjdcdTA2MzFcIn0gXHUwNjI4XHUwNjI3XHUwNkNDXHUwNjJGICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSBcdTA2MjhcdTA2MjdcdTA2MzRcdTA2MkZgO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJ0b29fc21hbGxcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPj1cIiA6IFwiPlwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2MkVcdTA2Q0NcdTA2NDRcdTA2Q0MgXHUwNkE5XHUwNjQ4XHUwNjg2XHUwNkE5OiAke2lzc3VlLm9yaWdpbn0gXHUwNjI4XHUwNjI3XHUwNkNDXHUwNjJGICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0fSBcdTA2MjhcdTA2MjdcdTA2MzRcdTA2MkZgO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjJFXHUwNkNDXHUwNjQ0XHUwNkNDIFx1MDZBOVx1MDY0OFx1MDY4Nlx1MDZBOTogJHtpc3N1ZS5vcmlnaW59IFx1MDYyOFx1MDYyN1x1MDZDQ1x1MDYyRiAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gXHUwNjI4XHUwNjI3XHUwNjM0XHUwNjJGYDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDYzMVx1MDYzNFx1MDYyQVx1MDY0NyBcdTA2NDZcdTA2MjdcdTA2NDVcdTA2MzlcdTA2MkFcdTA2MjhcdTA2MzE6IFx1MDYyOFx1MDYyN1x1MDZDQ1x1MDYyRiBcdTA2MjhcdTA2MjcgXCIke19pc3N1ZS5wcmVmaXh9XCIgXHUwNjM0XHUwNjMxXHUwNjQ4XHUwNjM5IFx1MDYzNFx1MDY0OFx1MDYyRmA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiZW5kc193aXRoXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjMxXHUwNjM0XHUwNjJBXHUwNjQ3IFx1MDY0Nlx1MDYyN1x1MDY0NVx1MDYzOVx1MDYyQVx1MDYyOFx1MDYzMTogXHUwNjI4XHUwNjI3XHUwNkNDXHUwNjJGIFx1MDYyOFx1MDYyNyBcIiR7X2lzc3VlLnN1ZmZpeH1cIiBcdTA2MkFcdTA2NDVcdTA2MjdcdTA2NDUgXHUwNjM0XHUwNjQ4XHUwNjJGYDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJpbmNsdWRlc1wiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDYzMVx1MDYzNFx1MDYyQVx1MDY0NyBcdTA2NDZcdTA2MjdcdTA2NDVcdTA2MzlcdTA2MkFcdTA2MjhcdTA2MzE6IFx1MDYyOFx1MDYyN1x1MDZDQ1x1MDYyRiBcdTA2MzRcdTA2MjdcdTA2NDVcdTA2NDQgXCIke19pc3N1ZS5pbmNsdWRlc31cIiBcdTA2MjhcdTA2MjdcdTA2MzRcdTA2MkZgO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInJlZ2V4XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjMxXHUwNjM0XHUwNjJBXHUwNjQ3IFx1MDY0Nlx1MDYyN1x1MDY0NVx1MDYzOVx1MDYyQVx1MDYyOFx1MDYzMTogXHUwNjI4XHUwNjI3XHUwNkNDXHUwNjJGIFx1MDYyOFx1MDYyNyBcdTA2MjdcdTA2NDRcdTA2QUZcdTA2NDhcdTA2Q0MgJHtfaXNzdWUucGF0dGVybn0gXHUwNjQ1XHUwNjM3XHUwNjI3XHUwNjI4XHUwNjQyXHUwNjJBIFx1MDYyRlx1MDYyN1x1MDYzNFx1MDYyQVx1MDY0NyBcdTA2MjhcdTA2MjdcdTA2MzRcdTA2MkZgO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9IFx1MDY0Nlx1MDYyN1x1MDY0NVx1MDYzOVx1MDYyQVx1MDYyOFx1MDYzMWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm5vdF9tdWx0aXBsZV9vZlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjM5XHUwNjJGXHUwNjJGIFx1MDY0Nlx1MDYyN1x1MDY0NVx1MDYzOVx1MDYyQVx1MDYyOFx1MDYzMTogXHUwNjI4XHUwNjI3XHUwNkNDXHUwNjJGIFx1MDY0NVx1MDYzNlx1MDYzMVx1MDYyOCAke2lzc3VlLmRpdmlzb3J9IFx1MDYyOFx1MDYyN1x1MDYzNFx1MDYyRmA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDZBOVx1MDY0NFx1MDZDQ1x1MDYyRiR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJcdTA2NDdcdTA2MjdcdTA2Q0NcIiA6IFwiXCJ9IFx1MDY0Nlx1MDYyN1x1MDYzNFx1MDY0Nlx1MDYyN1x1MDYzMzogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgXCIsIFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfa2V5XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2QTlcdTA2NDRcdTA2Q0NcdTA2MkYgXHUwNjQ2XHUwNjI3XHUwNjM0XHUwNjQ2XHUwNjI3XHUwNjMzIFx1MDYyRlx1MDYzMSAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDY0OFx1MDYzMVx1MDY0OFx1MDYyRlx1MDZDQyBcdTA2NDZcdTA2MjdcdTA2NDVcdTA2MzlcdTA2MkFcdTA2MjhcdTA2MzFgO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZWxlbWVudFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjQ1XHUwNjQyXHUwNjJGXHUwNjI3XHUwNjMxIFx1MDY0Nlx1MDYyN1x1MDY0NVx1MDYzOVx1MDYyQVx1MDYyOFx1MDYzMSBcdTA2MkZcdTA2MzEgJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2NDhcdTA2MzFcdTA2NDhcdTA2MkZcdTA2Q0MgXHUwNjQ2XHUwNjI3XHUwNjQ1XHUwNjM5XHUwNjJBXHUwNjI4XHUwNjMxYDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJtZXJra2lcdTAwRTRcIixcbiAgICAgICAgICAgIHN1YmplY3Q6IFwibWVya2tpam9ub25cIlxuICAgICAgICB9LFxuICAgICAgICBmaWxlOiB7XG4gICAgICAgICAgICB1bml0OiBcInRhdnVhXCIsXG4gICAgICAgICAgICBzdWJqZWN0OiBcInRpZWRvc3RvblwiXG4gICAgICAgIH0sXG4gICAgICAgIGFycmF5OiB7XG4gICAgICAgICAgICB1bml0OiBcImFsa2lvdGFcIixcbiAgICAgICAgICAgIHN1YmplY3Q6IFwibGlzdGFuXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcImFsa2lvdGFcIixcbiAgICAgICAgICAgIHN1YmplY3Q6IFwiam91a29uXCJcbiAgICAgICAgfSxcbiAgICAgICAgbnVtYmVyOiB7XG4gICAgICAgICAgICB1bml0OiBcIlwiLFxuICAgICAgICAgICAgc3ViamVjdDogXCJsdXZ1blwiXG4gICAgICAgIH0sXG4gICAgICAgIGJpZ2ludDoge1xuICAgICAgICAgICAgdW5pdDogXCJcIixcbiAgICAgICAgICAgIHN1YmplY3Q6IFwic3V1cmVuIGtva29uYWlzbHV2dW5cIlxuICAgICAgICB9LFxuICAgICAgICBpbnQ6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXCIsXG4gICAgICAgICAgICBzdWJqZWN0OiBcImtva29uYWlzbHV2dW5cIlxuICAgICAgICB9LFxuICAgICAgICBkYXRlOiB7XG4gICAgICAgICAgICB1bml0OiBcIlwiLFxuICAgICAgICAgICAgc3ViamVjdDogXCJwXHUwMEU0aXZcdTAwRTRtXHUwMEU0XHUwMEU0clx1MDBFNG5cIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIk5hTlwiIDogXCJudW1iZXJcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiYXJyYXlcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YoZGF0YSkgIT09IE9iamVjdC5wcm90b3R5cGUgJiYgZGF0YS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdDtcbiAgICB9O1xuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJzXHUwMEU0XHUwMEU0bm5cdTAwRjZsbGluZW4gbGF1c2VrZVwiLFxuICAgICAgICBlbWFpbDogXCJzXHUwMEU0aGtcdTAwRjZwb3N0aW9zb2l0ZVwiLFxuICAgICAgICB1cmw6IFwiVVJMLW9zb2l0ZVwiLFxuICAgICAgICBlbW9qaTogXCJlbW9qaVwiLFxuICAgICAgICB1dWlkOiBcIlVVSURcIixcbiAgICAgICAgdXVpZHY0OiBcIlVVSUR2NFwiLFxuICAgICAgICB1dWlkdjY6IFwiVVVJRHY2XCIsXG4gICAgICAgIG5hbm9pZDogXCJuYW5vaWRcIixcbiAgICAgICAgZ3VpZDogXCJHVUlEXCIsXG4gICAgICAgIGN1aWQ6IFwiY3VpZFwiLFxuICAgICAgICBjdWlkMjogXCJjdWlkMlwiLFxuICAgICAgICB1bGlkOiBcIlVMSURcIixcbiAgICAgICAgeGlkOiBcIlhJRFwiLFxuICAgICAgICBrc3VpZDogXCJLU1VJRFwiLFxuICAgICAgICBkYXRldGltZTogXCJJU08tYWlrYWxlaW1hXCIsXG4gICAgICAgIGRhdGU6IFwiSVNPLXBcdTAwRTRpdlx1MDBFNG1cdTAwRTRcdTAwRTRyXHUwMEU0XCIsXG4gICAgICAgIHRpbWU6IFwiSVNPLWFpa2FcIixcbiAgICAgICAgZHVyYXRpb246IFwiSVNPLWtlc3RvXCIsXG4gICAgICAgIGlwdjQ6IFwiSVB2NC1vc29pdGVcIixcbiAgICAgICAgaXB2NjogXCJJUHY2LW9zb2l0ZVwiLFxuICAgICAgICBjaWRydjQ6IFwiSVB2NC1hbHVlXCIsXG4gICAgICAgIGNpZHJ2NjogXCJJUHY2LWFsdWVcIixcbiAgICAgICAgYmFzZTY0OiBcImJhc2U2NC1rb29kYXR0dSBtZXJra2lqb25vXCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJiYXNlNjR1cmwta29vZGF0dHUgbWVya2tpam9ub1wiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJKU09OLW1lcmtraWpvbm9cIixcbiAgICAgICAgZTE2NDogXCJFLjE2NC1sdWt1XCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJ0ZW1wbGFhdHRpbWVya2tpam9ub1wiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBWaXJoZWVsbGluZW4gdHl5cHBpOiBvZG90ZXR0aWluICR7aXNzdWUuZXhwZWN0ZWR9LCBvbGkgJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBWaXJoZWVsbGluZW4gc3lcdTAwRjZ0ZTogdFx1MDBFNHl0eXkgb2xsYSAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYFZpcmhlZWxsaW5lbiB2YWxpbnRhOiB0XHUwMEU0eXR5eSBvbGxhIHlrc2kgc2V1cmFhdmlzdGE6ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLnZhbHVlcywgXCJ8XCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwidG9vX2JpZ1wiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI8PVwiIDogXCI8XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYExpaWFuIHN1dXJpOiAke3NpemluZy5zdWJqZWN0fSB0XHUwMEU0eXR5eSBvbGxhICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0fWAudHJpbSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgTGlpYW4gc3V1cmk6IGFydm9uIHRcdTAwRTR5dHl5IG9sbGEgJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIj49XCIgOiBcIj5cIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgTGlpYW4gcGllbmk6ICR7c2l6aW5nLnN1YmplY3R9IHRcdTAwRTR5dHl5IG9sbGEgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXR9YC50cmltKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBMaWlhbiBwaWVuaTogYXJ2b24gdFx1MDBFNHl0eXkgb2xsYSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2Zvcm1hdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgX2lzc3VlID0gaXNzdWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInN0YXJ0c193aXRoXCIpIHJldHVybiBgVmlyaGVlbGxpbmVuIHN5XHUwMEY2dGU6IHRcdTAwRTR5dHl5IGFsa2FhIFwiJHtfaXNzdWUucHJlZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiZW5kc193aXRoXCIpIHJldHVybiBgVmlyaGVlbGxpbmVuIHN5XHUwMEY2dGU6IHRcdTAwRTR5dHl5IGxvcHB1YSBcIiR7X2lzc3VlLnN1ZmZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImluY2x1ZGVzXCIpIHJldHVybiBgVmlyaGVlbGxpbmVuIHN5XHUwMEY2dGU6IHRcdTAwRTR5dHl5IHNpc1x1MDBFNGx0XHUwMEU0XHUwMEU0IFwiJHtfaXNzdWUuaW5jbHVkZXN9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFZpcmhlZWxsaW5lbiBzeVx1MDBGNnRlOiB0XHUwMEU0eXR5eSB2YXN0YXRhIHNcdTAwRTRcdTAwRTRublx1MDBGNmxsaXN0XHUwMEU0IGxhdXNla2V0dGEgJHtfaXNzdWUucGF0dGVybn1gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgVmlyaGVlbGxpbmVuICR7Tm91bnNbX2lzc3VlLmZvcm1hdF0gPz8gaXNzdWUuZm9ybWF0fWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm5vdF9tdWx0aXBsZV9vZlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgVmlyaGVlbGxpbmVuIGx1a3U6IHRcdTAwRTR5dHl5IG9sbGEgbHV2dW4gJHtpc3N1ZS5kaXZpc29yfSBtb25pa2VydGFgO1xuICAgICAgICAgICAgY2FzZSBcInVucmVjb2duaXplZF9rZXlzXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGAke2lzc3VlLmtleXMubGVuZ3RoID4gMSA/IFwiVHVudGVtYXR0b21hdCBhdmFpbWV0XCIgOiBcIlR1bnRlbWF0b24gYXZhaW5cIn06ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLmtleXMsIFwiLCBcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2tleVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIlZpcmhlZWxsaW5lbiBhdmFpbiB0aWV0dWVlc3NhXCI7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF91bmlvblwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIlZpcmhlZWxsaW5lbiB1bmlvbmlcIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJWaXJoZWVsbGluZW4gYXJ2byBqb3Vrb3NzYVwiO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFZpcmhlZWxsaW5lbiBzeVx1MDBGNnRlYDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJjYXJhY3RcdTAwRThyZXNcIixcbiAgICAgICAgICAgIHZlcmI6IFwiYXZvaXJcIlxuICAgICAgICB9LFxuICAgICAgICBmaWxlOiB7XG4gICAgICAgICAgICB1bml0OiBcIm9jdGV0c1wiLFxuICAgICAgICAgICAgdmVyYjogXCJhdm9pclwiXG4gICAgICAgIH0sXG4gICAgICAgIGFycmF5OiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MDBFOWxcdTAwRTltZW50c1wiLFxuICAgICAgICAgICAgdmVyYjogXCJhdm9pclwiXG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDogXCJcdTAwRTlsXHUwMEU5bWVudHNcIixcbiAgICAgICAgICAgIHZlcmI6IFwiYXZvaXJcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIk5hTlwiIDogXCJub21icmVcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwidGFibGVhdVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJudWxsXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcImVudHJcdTAwRTllXCIsXG4gICAgICAgIGVtYWlsOiBcImFkcmVzc2UgZS1tYWlsXCIsXG4gICAgICAgIHVybDogXCJVUkxcIixcbiAgICAgICAgZW1vamk6IFwiZW1vamlcIixcbiAgICAgICAgdXVpZDogXCJVVUlEXCIsXG4gICAgICAgIHV1aWR2NDogXCJVVUlEdjRcIixcbiAgICAgICAgdXVpZHY2OiBcIlVVSUR2NlwiLFxuICAgICAgICBuYW5vaWQ6IFwibmFub2lkXCIsXG4gICAgICAgIGd1aWQ6IFwiR1VJRFwiLFxuICAgICAgICBjdWlkOiBcImN1aWRcIixcbiAgICAgICAgY3VpZDI6IFwiY3VpZDJcIixcbiAgICAgICAgdWxpZDogXCJVTElEXCIsXG4gICAgICAgIHhpZDogXCJYSURcIixcbiAgICAgICAga3N1aWQ6IFwiS1NVSURcIixcbiAgICAgICAgZGF0ZXRpbWU6IFwiZGF0ZSBldCBoZXVyZSBJU09cIixcbiAgICAgICAgZGF0ZTogXCJkYXRlIElTT1wiLFxuICAgICAgICB0aW1lOiBcImhldXJlIElTT1wiLFxuICAgICAgICBkdXJhdGlvbjogXCJkdXJcdTAwRTllIElTT1wiLFxuICAgICAgICBpcHY0OiBcImFkcmVzc2UgSVB2NFwiLFxuICAgICAgICBpcHY2OiBcImFkcmVzc2UgSVB2NlwiLFxuICAgICAgICBjaWRydjQ6IFwicGxhZ2UgSVB2NFwiLFxuICAgICAgICBjaWRydjY6IFwicGxhZ2UgSVB2NlwiLFxuICAgICAgICBiYXNlNjQ6IFwiY2hhXHUwMEVFbmUgZW5jb2RcdTAwRTllIGVuIGJhc2U2NFwiLFxuICAgICAgICBiYXNlNjR1cmw6IFwiY2hhXHUwMEVFbmUgZW5jb2RcdTAwRTllIGVuIGJhc2U2NHVybFwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJjaGFcdTAwRUVuZSBKU09OXCIsXG4gICAgICAgIGUxNjQ6IFwibnVtXHUwMEU5cm8gRS4xNjRcIixcbiAgICAgICAgand0OiBcIkpXVFwiLFxuICAgICAgICB0ZW1wbGF0ZV9saXRlcmFsOiBcImVudHJcdTAwRTllXCJcbiAgICB9O1xuICAgIHJldHVybiAoaXNzdWUpPT57XG4gICAgICAgIHN3aXRjaChpc3N1ZS5jb2RlKXtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3R5cGVcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYEVudHJcdTAwRTllIGludmFsaWRlIDogJHtpc3N1ZS5leHBlY3RlZH0gYXR0ZW5kdSwgJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX0gcmVcdTAwRTd1YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgRW50clx1MDBFOWUgaW52YWxpZGUgOiAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9IGF0dGVuZHVgO1xuICAgICAgICAgICAgICAgIHJldHVybiBgT3B0aW9uIGludmFsaWRlIDogdW5lIHZhbGV1ciBwYXJtaSAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS52YWx1ZXMsIFwifFwiKX0gYXR0ZW5kdWVgO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPD1cIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykgcmV0dXJuIGBUcm9wIGdyYW5kIDogJHtpc3N1ZS5vcmlnaW4gPz8gXCJ2YWxldXJcIn0gZG9pdCAke3NpemluZy52ZXJifSAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdCA/PyBcIlx1MDBFOWxcdTAwRTltZW50KHMpXCJ9YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBUcm9wIGdyYW5kIDogJHtpc3N1ZS5vcmlnaW4gPz8gXCJ2YWxldXJcIn0gZG9pdCBcdTAwRUF0cmUgJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIj49XCIgOiBcIj5cIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgVHJvcCBwZXRpdCA6ICR7aXNzdWUub3JpZ2lufSBkb2l0ICR7c2l6aW5nLnZlcmJ9ICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0fWA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBUcm9wIHBldGl0IDogJHtpc3N1ZS5vcmlnaW59IGRvaXQgXHUwMEVBdHJlICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZm9ybWF0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBfaXNzdWUgPSBpc3N1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwic3RhcnRzX3dpdGhcIikgcmV0dXJuIGBDaGFcdTAwRUVuZSBpbnZhbGlkZSA6IGRvaXQgY29tbWVuY2VyIHBhciBcIiR7X2lzc3VlLnByZWZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYENoYVx1MDBFRW5lIGludmFsaWRlIDogZG9pdCBzZSB0ZXJtaW5lciBwYXIgXCIke19pc3N1ZS5zdWZmaXh9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJpbmNsdWRlc1wiKSByZXR1cm4gYENoYVx1MDBFRW5lIGludmFsaWRlIDogZG9pdCBpbmNsdXJlIFwiJHtfaXNzdWUuaW5jbHVkZXN9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYENoYVx1MDBFRW5lIGludmFsaWRlIDogZG9pdCBjb3JyZXNwb25kcmUgYXUgbW9kXHUwMEU4bGUgJHtfaXNzdWUucGF0dGVybn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYCR7Tm91bnNbX2lzc3VlLmZvcm1hdF0gPz8gaXNzdWUuZm9ybWF0fSBpbnZhbGlkZWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm5vdF9tdWx0aXBsZV9vZlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgTm9tYnJlIGludmFsaWRlIDogZG9pdCBcdTAwRUF0cmUgdW4gbXVsdGlwbGUgZGUgJHtpc3N1ZS5kaXZpc29yfWA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYENsXHUwMEU5JHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcInNcIiA6IFwiXCJ9IG5vbiByZWNvbm51ZSR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJzXCIgOiBcIlwifSA6ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLmtleXMsIFwiLCBcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2tleVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgQ2xcdTAwRTkgaW52YWxpZGUgZGFucyAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJFbnRyXHUwMEU5ZSBpbnZhbGlkZVwiO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZWxlbWVudFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgVmFsZXVyIGludmFsaWRlIGRhbnMgJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBFbnRyXHUwMEU5ZSBpbnZhbGlkZWA7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGxvY2FsZUVycm9yOiBlcnJvcigpXG4gICAgfTtcbn1cbiIsICJpbXBvcnQgKiBhcyB1dGlsIGZyb20gXCIuLi9jb3JlL3V0aWwuanNcIjtcbmNvbnN0IGVycm9yID0gKCk9PntcbiAgICBjb25zdCBTaXphYmxlID0ge1xuICAgICAgICBzdHJpbmc6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiY2FyYWN0XHUwMEU4cmVzXCIsXG4gICAgICAgICAgICB2ZXJiOiBcImF2b2lyXCJcbiAgICAgICAgfSxcbiAgICAgICAgZmlsZToge1xuICAgICAgICAgICAgdW5pdDogXCJvY3RldHNcIixcbiAgICAgICAgICAgIHZlcmI6IFwiYXZvaXJcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJcdTAwRTlsXHUwMEU5bWVudHNcIixcbiAgICAgICAgICAgIHZlcmI6IFwiYXZvaXJcIlxuICAgICAgICB9LFxuICAgICAgICBzZXQ6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHUwMEU5bFx1MDBFOW1lbnRzXCIsXG4gICAgICAgICAgICB2ZXJiOiBcImF2b2lyXCJcbiAgICAgICAgfVxuICAgIH07XG4gICAgZnVuY3Rpb24gZ2V0U2l6aW5nKG9yaWdpbikge1xuICAgICAgICByZXR1cm4gU2l6YWJsZVtvcmlnaW5dID8/IG51bGw7XG4gICAgfVxuICAgIGNvbnN0IHBhcnNlZFR5cGUgPSAoZGF0YSk9PntcbiAgICAgICAgY29uc3QgdCA9IHR5cGVvZiBkYXRhO1xuICAgICAgICBzd2l0Y2godCl7XG4gICAgICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gTnVtYmVyLmlzTmFOKGRhdGEpID8gXCJOYU5cIiA6IFwibnVtYmVyXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm9iamVjdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcImFycmF5XCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGEgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm51bGxcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKGRhdGEpICE9PSBPYmplY3QucHJvdG90eXBlICYmIGRhdGEuY29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHQ7XG4gICAgfTtcbiAgICBjb25zdCBOb3VucyA9IHtcbiAgICAgICAgcmVnZXg6IFwiZW50clx1MDBFOWVcIixcbiAgICAgICAgZW1haWw6IFwiYWRyZXNzZSBjb3VycmllbFwiLFxuICAgICAgICB1cmw6IFwiVVJMXCIsXG4gICAgICAgIGVtb2ppOiBcImVtb2ppXCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcImRhdGUtaGV1cmUgSVNPXCIsXG4gICAgICAgIGRhdGU6IFwiZGF0ZSBJU09cIixcbiAgICAgICAgdGltZTogXCJoZXVyZSBJU09cIixcbiAgICAgICAgZHVyYXRpb246IFwiZHVyXHUwMEU5ZSBJU09cIixcbiAgICAgICAgaXB2NDogXCJhZHJlc3NlIElQdjRcIixcbiAgICAgICAgaXB2NjogXCJhZHJlc3NlIElQdjZcIixcbiAgICAgICAgY2lkcnY0OiBcInBsYWdlIElQdjRcIixcbiAgICAgICAgY2lkcnY2OiBcInBsYWdlIElQdjZcIixcbiAgICAgICAgYmFzZTY0OiBcImNoYVx1MDBFRW5lIGVuY29kXHUwMEU5ZSBlbiBiYXNlNjRcIixcbiAgICAgICAgYmFzZTY0dXJsOiBcImNoYVx1MDBFRW5lIGVuY29kXHUwMEU5ZSBlbiBiYXNlNjR1cmxcIixcbiAgICAgICAganNvbl9zdHJpbmc6IFwiY2hhXHUwMEVFbmUgSlNPTlwiLFxuICAgICAgICBlMTY0OiBcIm51bVx1MDBFOXJvIEUuMTY0XCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJlbnRyXHUwMEU5ZVwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBFbnRyXHUwMEU5ZSBpbnZhbGlkZSA6IGF0dGVuZHUgJHtpc3N1ZS5leHBlY3RlZH0sIHJlXHUwMEU3dSAke3BhcnNlZFR5cGUoaXNzdWUuaW5wdXQpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF92YWx1ZVwiOlxuICAgICAgICAgICAgICAgIGlmIChpc3N1ZS52YWx1ZXMubGVuZ3RoID09PSAxKSByZXR1cm4gYEVudHJcdTAwRTllIGludmFsaWRlIDogYXR0ZW5kdSAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYE9wdGlvbiBpbnZhbGlkZSA6IGF0dGVuZHUgbCd1bmUgZGVzIHZhbGV1cnMgc3VpdmFudGVzICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLnZhbHVlcywgXCJ8XCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwidG9vX2JpZ1wiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCJcdTIyNjRcIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykgcmV0dXJuIGBUcm9wIGdyYW5kIDogYXR0ZW5kdSBxdWUgJHtpc3N1ZS5vcmlnaW4gPz8gXCJsYSB2YWxldXJcIn0gYWl0ICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0fWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgVHJvcCBncmFuZCA6IGF0dGVuZHUgcXVlICR7aXNzdWUub3JpZ2luID8/IFwibGEgdmFsZXVyXCJ9IHNvaXQgJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIlx1MjI2NVwiIDogXCI+XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFRyb3AgcGV0aXQgOiBhdHRlbmR1IHF1ZSAke2lzc3VlLm9yaWdpbn0gYWl0ICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0fWA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBUcm9wIHBldGl0IDogYXR0ZW5kdSBxdWUgJHtpc3N1ZS5vcmlnaW59IHNvaXQgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYENoYVx1MDBFRW5lIGludmFsaWRlIDogZG9pdCBjb21tZW5jZXIgcGFyIFwiJHtfaXNzdWUucHJlZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJlbmRzX3dpdGhcIikgcmV0dXJuIGBDaGFcdTAwRUVuZSBpbnZhbGlkZSA6IGRvaXQgc2UgdGVybWluZXIgcGFyIFwiJHtfaXNzdWUuc3VmZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBDaGFcdTAwRUVuZSBpbnZhbGlkZSA6IGRvaXQgaW5jbHVyZSBcIiR7X2lzc3VlLmluY2x1ZGVzfVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBDaGFcdTAwRUVuZSBpbnZhbGlkZSA6IGRvaXQgY29ycmVzcG9uZHJlIGF1IG1vdGlmICR7X2lzc3VlLnBhdHRlcm59YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGAke05vdW5zW19pc3N1ZS5mb3JtYXRdID8/IGlzc3VlLmZvcm1hdH0gaW52YWxpZGVgO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJub3RfbXVsdGlwbGVfb2ZcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYE5vbWJyZSBpbnZhbGlkZSA6IGRvaXQgXHUwMEVBdHJlIHVuIG11bHRpcGxlIGRlICR7aXNzdWUuZGl2aXNvcn1gO1xuICAgICAgICAgICAgY2FzZSBcInVucmVjb2duaXplZF9rZXlzXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBDbFx1MDBFOSR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJzXCIgOiBcIlwifSBub24gcmVjb25udWUke2lzc3VlLmtleXMubGVuZ3RoID4gMSA/IFwic1wiIDogXCJcIn0gOiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIiwgXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYENsXHUwMEU5IGludmFsaWRlIGRhbnMgJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3VuaW9uXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiRW50clx1MDBFOWUgaW52YWxpZGVcIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFZhbGV1ciBpbnZhbGlkZSBkYW5zICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBgRW50clx1MDBFOWUgaW52YWxpZGVgO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBsb2NhbGVFcnJvcjogZXJyb3IoKVxuICAgIH07XG59XG4iLCAiaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi4vY29yZS91dGlsLmpzXCI7XG5jb25zdCBlcnJvciA9ICgpPT57XG4gICAgY29uc3QgU2l6YWJsZSA9IHtcbiAgICAgICAgc3RyaW5nOiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MDVEMFx1MDVENVx1MDVFQVx1MDVEOVx1MDVENVx1MDVFQVwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTA1RENcdTA1REJcdTA1RENcdTA1RDVcdTA1RENcIlxuICAgICAgICB9LFxuICAgICAgICBmaWxlOiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MDVEMVx1MDVEOVx1MDVEOVx1MDVEOFx1MDVEOVx1MDVERFwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTA1RENcdTA1REJcdTA1RENcdTA1RDVcdTA1RENcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJcdTA1RTRcdTA1RThcdTA1RDlcdTA1RDhcdTA1RDlcdTA1RERcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwNURDXHUwNURCXHUwNURDXHUwNUQ1XHUwNURDXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MDVFNFx1MDVFOFx1MDVEOVx1MDVEOFx1MDVEOVx1MDVERFwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTA1RENcdTA1REJcdTA1RENcdTA1RDVcdTA1RENcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIk5hTlwiIDogXCJudW1iZXJcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiYXJyYXlcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YoZGF0YSkgIT09IE9iamVjdC5wcm90b3R5cGUgJiYgZGF0YS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdDtcbiAgICB9O1xuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJcdTA1RTdcdTA1RENcdTA1RDhcIixcbiAgICAgICAgZW1haWw6IFwiXHUwNURCXHUwNUVBXHUwNUQ1XHUwNUQxXHUwNUVBIFx1MDVEMFx1MDVEOVx1MDVERVx1MDVEOVx1MDVEOVx1MDVEQ1wiLFxuICAgICAgICB1cmw6IFwiXHUwNURCXHUwNUVBXHUwNUQ1XHUwNUQxXHUwNUVBIFx1MDVFOFx1MDVFOVx1MDVFQVwiLFxuICAgICAgICBlbW9qaTogXCJcdTA1RDBcdTA1RDlcdTA1REVcdTA1RDVcdTA1RDInXHUwNUQ5XCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcIlx1MDVFQVx1MDVEMFx1MDVFOFx1MDVEOVx1MDVEQSBcdTA1RDVcdTA1RDZcdTA1REVcdTA1REYgSVNPXCIsXG4gICAgICAgIGRhdGU6IFwiXHUwNUVBXHUwNUQwXHUwNUU4XHUwNUQ5XHUwNURBIElTT1wiLFxuICAgICAgICB0aW1lOiBcIlx1MDVENlx1MDVERVx1MDVERiBJU09cIixcbiAgICAgICAgZHVyYXRpb246IFwiXHUwNURFXHUwNUU5XHUwNURBIFx1MDVENlx1MDVERVx1MDVERiBJU09cIixcbiAgICAgICAgaXB2NDogXCJcdTA1REJcdTA1RUFcdTA1RDVcdTA1RDFcdTA1RUEgSVB2NFwiLFxuICAgICAgICBpcHY2OiBcIlx1MDVEQlx1MDVFQVx1MDVENVx1MDVEMVx1MDVFQSBJUHY2XCIsXG4gICAgICAgIGNpZHJ2NDogXCJcdTA1RDhcdTA1RDVcdTA1RDVcdTA1RDcgSVB2NFwiLFxuICAgICAgICBjaWRydjY6IFwiXHUwNUQ4XHUwNUQ1XHUwNUQ1XHUwNUQ3IElQdjZcIixcbiAgICAgICAgYmFzZTY0OiBcIlx1MDVERVx1MDVEN1x1MDVFOFx1MDVENVx1MDVENlx1MDVFQSBcdTA1RDFcdTA1RDFcdTA1RTFcdTA1RDlcdTA1RTEgNjRcIixcbiAgICAgICAgYmFzZTY0dXJsOiBcIlx1MDVERVx1MDVEN1x1MDVFOFx1MDVENVx1MDVENlx1MDVFQSBcdTA1RDFcdTA1RDFcdTA1RTFcdTA1RDlcdTA1RTEgNjQgXHUwNURDXHUwNURCXHUwNUVBXHUwNUQ1XHUwNUQxXHUwNUQ1XHUwNUVBIFx1MDVFOFx1MDVFOVx1MDVFQVwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJcdTA1REVcdTA1RDdcdTA1RThcdTA1RDVcdTA1RDZcdTA1RUEgSlNPTlwiLFxuICAgICAgICBlMTY0OiBcIlx1MDVERVx1MDVFMVx1MDVFNFx1MDVFOCBFLjE2NFwiLFxuICAgICAgICBqd3Q6IFwiSldUXCIsXG4gICAgICAgIHRlbXBsYXRlX2xpdGVyYWw6IFwiXHUwNUU3XHUwNURDXHUwNUQ4XCJcbiAgICB9O1xuICAgIHJldHVybiAoaXNzdWUpPT57XG4gICAgICAgIHN3aXRjaChpc3N1ZS5jb2RlKXtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3R5cGVcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDVFN1x1MDVEQ1x1MDVEOCBcdTA1RENcdTA1RDAgXHUwNUVBXHUwNUU3XHUwNUQ5XHUwNURGOiBcdTA1RTZcdTA1RThcdTA1RDlcdTA1REEgJHtpc3N1ZS5leHBlY3RlZH0sIFx1MDVENFx1MDVFQVx1MDVFN1x1MDVEMVx1MDVEQyAke3BhcnNlZFR5cGUoaXNzdWUuaW5wdXQpfWA7XG4gICAgICAgICAgICAvLyByZXR1cm4gYEludmFsaWQgaW5wdXQ6IGV4cGVjdGVkICR7aXNzdWUuZXhwZWN0ZWR9LCByZWNlaXZlZCAke3V0aWwuZ2V0UGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgXHUwNUU3XHUwNURDXHUwNUQ4IFx1MDVEQ1x1MDVEMCBcdTA1RUFcdTA1RTdcdTA1RDlcdTA1REY6IFx1MDVFNlx1MDVFOFx1MDVEOVx1MDVEQSAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDVFN1x1MDVEQ1x1MDVEOCBcdTA1RENcdTA1RDAgXHUwNUVBXHUwNUU3XHUwNUQ5XHUwNURGOiBcdTA1RTZcdTA1RThcdTA1RDlcdTA1REEgXHUwNUQwXHUwNUQ3XHUwNUVBIFx1MDVERVx1MDVENFx1MDVEMFx1MDVFNFx1MDVFOVx1MDVFOFx1MDVENVx1MDVEOVx1MDVENVx1MDVFQSAgJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIjw9XCIgOiBcIjxcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgXHUwNUQyXHUwNUQzXHUwNUQ1XHUwNURDIFx1MDVERVx1MDVEM1x1MDVEOTogJHtpc3N1ZS5vcmlnaW4gPz8gXCJ2YWx1ZVwifSBcdTA1RTZcdTA1RThcdTA1RDlcdTA1REEgXHUwNURDXHUwNUQ0XHUwNUQ5XHUwNUQ1XHUwNUVBICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0ID8/IFwiZWxlbWVudHNcIn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDVEMlx1MDVEM1x1MDVENVx1MDVEQyBcdTA1REVcdTA1RDNcdTA1RDk6ICR7aXNzdWUub3JpZ2luID8/IFwidmFsdWVcIn0gXHUwNUU2XHUwNUU4XHUwNUQ5XHUwNURBIFx1MDVEQ1x1MDVENFx1MDVEOVx1MDVENVx1MDVFQSAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJ0b29fc21hbGxcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPj1cIiA6IFwiPlwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA1RTdcdTA1RDhcdTA1REYgXHUwNURFXHUwNUQzXHUwNUQ5OiAke2lzc3VlLm9yaWdpbn0gXHUwNUU2XHUwNUU4XHUwNUQ5XHUwNURBIFx1MDVEQ1x1MDVENFx1MDVEOVx1MDVENVx1MDVFQSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdH1gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNUU3XHUwNUQ4XHUwNURGIFx1MDVERVx1MDVEM1x1MDVEOTogJHtpc3N1ZS5vcmlnaW59IFx1MDVFNlx1MDVFOFx1MDVEOVx1MDVEQSBcdTA1RENcdTA1RDRcdTA1RDlcdTA1RDVcdTA1RUEgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSByZXR1cm4gYFx1MDVERVx1MDVEN1x1MDVFOFx1MDVENVx1MDVENlx1MDVFQSBcdTA1RENcdTA1RDAgXHUwNUVBXHUwNUU3XHUwNUQ5XHUwNUUwXHUwNUQ0OiBcdTA1RDdcdTA1RDlcdTA1RDlcdTA1RDFcdTA1RUEgXHUwNURDXHUwNUQ0XHUwNUVBXHUwNUQ3XHUwNUQ5XHUwNURDIFx1MDVEMVwiJHtfaXNzdWUucHJlZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiZW5kc193aXRoXCIpIHJldHVybiBgXHUwNURFXHUwNUQ3XHUwNUU4XHUwNUQ1XHUwNUQ2XHUwNUVBIFx1MDVEQ1x1MDVEMCBcdTA1RUFcdTA1RTdcdTA1RDlcdTA1RTBcdTA1RDQ6IFx1MDVEN1x1MDVEOVx1MDVEOVx1MDVEMVx1MDVFQSBcdTA1RENcdTA1RDRcdTA1RTFcdTA1RUFcdTA1RDlcdTA1RDlcdTA1REQgXHUwNUQxIFwiJHtfaXNzdWUuc3VmZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBcdTA1REVcdTA1RDdcdTA1RThcdTA1RDVcdTA1RDZcdTA1RUEgXHUwNURDXHUwNUQwIFx1MDVFQVx1MDVFN1x1MDVEOVx1MDVFMFx1MDVENDogXHUwNUQ3XHUwNUQ5XHUwNUQ5XHUwNUQxXHUwNUVBIFx1MDVEQ1x1MDVEQlx1MDVEQ1x1MDVENVx1MDVEQyBcIiR7X2lzc3VlLmluY2x1ZGVzfVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBcdTA1REVcdTA1RDdcdTA1RThcdTA1RDVcdTA1RDZcdTA1RUEgXHUwNURDXHUwNUQwIFx1MDVFQVx1MDVFN1x1MDVEOVx1MDVFMFx1MDVENDogXHUwNUQ3XHUwNUQ5XHUwNUQ5XHUwNUQxXHUwNUVBIFx1MDVEQ1x1MDVENFx1MDVFQVx1MDVEMFx1MDVEOVx1MDVERCBcdTA1RENcdTA1RUFcdTA1RDFcdTA1RTBcdTA1RDlcdTA1RUEgJHtfaXNzdWUucGF0dGVybn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYCR7Tm91bnNbX2lzc3VlLmZvcm1hdF0gPz8gaXNzdWUuZm9ybWF0fSBcdTA1RENcdTA1RDAgXHUwNUVBXHUwNUU3XHUwNUQ5XHUwNURGYDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA1REVcdTA1RTFcdTA1RTRcdTA1RTggXHUwNURDXHUwNUQwIFx1MDVFQVx1MDVFN1x1MDVEOVx1MDVERjogXHUwNUQ3XHUwNUQ5XHUwNUQ5XHUwNUQxIFx1MDVEQ1x1MDVENFx1MDVEOVx1MDVENVx1MDVFQSBcdTA1REVcdTA1REJcdTA1RTRcdTA1RENcdTA1RDQgXHUwNUU5XHUwNURDICR7aXNzdWUuZGl2aXNvcn1gO1xuICAgICAgICAgICAgY2FzZSBcInVucmVjb2duaXplZF9rZXlzXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA1REVcdTA1RTRcdTA1RUFcdTA1RDcke2lzc3VlLmtleXMubGVuZ3RoID4gMSA/IFwiXHUwNUQ1XHUwNUVBXCIgOiBcIlwifSBcdTA1RENcdTA1RDAgXHUwNURFXHUwNUQ2XHUwNUQ1XHUwNUQ0JHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcIlx1MDVEOVx1MDVERFwiIDogXCJcdTA1RDRcIn06ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLmtleXMsIFwiLCBcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2tleVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNURFXHUwNUU0XHUwNUVBXHUwNUQ3IFx1MDVEQ1x1MDVEMCBcdTA1RUFcdTA1RTdcdTA1RDlcdTA1REYgXHUwNUQxJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3VuaW9uXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiXHUwNUU3XHUwNURDXHUwNUQ4IFx1MDVEQ1x1MDVEMCBcdTA1RUFcdTA1RTdcdTA1RDlcdTA1REZcIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDVFMlx1MDVFOFx1MDVEQSBcdTA1RENcdTA1RDAgXHUwNUVBXHUwNUU3XHUwNUQ5XHUwNURGIFx1MDVEMSR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNUU3XHUwNURDXHUwNUQ4IFx1MDVEQ1x1MDVEMCBcdTA1RUFcdTA1RTdcdTA1RDlcdTA1REZgO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBsb2NhbGVFcnJvcjogZXJyb3IoKVxuICAgIH07XG59XG4iLCAiaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi4vY29yZS91dGlsLmpzXCI7XG5jb25zdCBlcnJvciA9ICgpPT57XG4gICAgY29uc3QgU2l6YWJsZSA9IHtcbiAgICAgICAgc3RyaW5nOiB7XG4gICAgICAgICAgICB1bml0OiBcImthcmFrdGVyXCIsXG4gICAgICAgICAgICB2ZXJiOiBcImxlZ3llblwiXG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiYnl0ZVwiLFxuICAgICAgICAgICAgdmVyYjogXCJsZWd5ZW5cIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJlbGVtXCIsXG4gICAgICAgICAgICB2ZXJiOiBcImxlZ3llblwiXG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDogXCJlbGVtXCIsXG4gICAgICAgICAgICB2ZXJiOiBcImxlZ3llblwiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4pIHtcbiAgICAgICAgcmV0dXJuIFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWRUeXBlID0gKGRhdGEpPT57XG4gICAgICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICAgICAgc3dpdGNoKHQpe1xuICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcInN6XHUwMEUxbVwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJ0XHUwMEY2bWJcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YoZGF0YSkgIT09IE9iamVjdC5wcm90b3R5cGUgJiYgZGF0YS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdDtcbiAgICB9O1xuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJiZW1lbmV0XCIsXG4gICAgICAgIGVtYWlsOiBcImVtYWlsIGNcdTAwRURtXCIsXG4gICAgICAgIHVybDogXCJVUkxcIixcbiAgICAgICAgZW1vamk6IFwiZW1vamlcIixcbiAgICAgICAgdXVpZDogXCJVVUlEXCIsXG4gICAgICAgIHV1aWR2NDogXCJVVUlEdjRcIixcbiAgICAgICAgdXVpZHY2OiBcIlVVSUR2NlwiLFxuICAgICAgICBuYW5vaWQ6IFwibmFub2lkXCIsXG4gICAgICAgIGd1aWQ6IFwiR1VJRFwiLFxuICAgICAgICBjdWlkOiBcImN1aWRcIixcbiAgICAgICAgY3VpZDI6IFwiY3VpZDJcIixcbiAgICAgICAgdWxpZDogXCJVTElEXCIsXG4gICAgICAgIHhpZDogXCJYSURcIixcbiAgICAgICAga3N1aWQ6IFwiS1NVSURcIixcbiAgICAgICAgZGF0ZXRpbWU6IFwiSVNPIGlkXHUwMTUxYlx1MDBFOWx5ZWdcIixcbiAgICAgICAgZGF0ZTogXCJJU08gZFx1MDBFMXR1bVwiLFxuICAgICAgICB0aW1lOiBcIklTTyBpZFx1MDE1MVwiLFxuICAgICAgICBkdXJhdGlvbjogXCJJU08gaWRcdTAxNTFpbnRlcnZhbGx1bVwiLFxuICAgICAgICBpcHY0OiBcIklQdjQgY1x1MDBFRG1cIixcbiAgICAgICAgaXB2NjogXCJJUHY2IGNcdTAwRURtXCIsXG4gICAgICAgIGNpZHJ2NDogXCJJUHY0IHRhcnRvbVx1MDBFMW55XCIsXG4gICAgICAgIGNpZHJ2NjogXCJJUHY2IHRhcnRvbVx1MDBFMW55XCIsXG4gICAgICAgIGJhc2U2NDogXCJiYXNlNjQta1x1MDBGM2RvbHQgc3RyaW5nXCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJiYXNlNjR1cmwta1x1MDBGM2RvbHQgc3RyaW5nXCIsXG4gICAgICAgIGpzb25fc3RyaW5nOiBcIkpTT04gc3RyaW5nXCIsXG4gICAgICAgIGUxNjQ6IFwiRS4xNjQgc3pcdTAwRTFtXCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJiZW1lbmV0XCJcbiAgICB9O1xuICAgIHJldHVybiAoaXNzdWUpPT57XG4gICAgICAgIHN3aXRjaChpc3N1ZS5jb2RlKXtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3R5cGVcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDBDOXJ2XHUwMEU5bnl0ZWxlbiBiZW1lbmV0OiBhIHZcdTAwRTFydCBcdTAwRTlydFx1MDBFOWsgJHtpc3N1ZS5leHBlY3RlZH0sIGEga2Fwb3R0IFx1MDBFOXJ0XHUwMEU5ayAke3BhcnNlZFR5cGUoaXNzdWUuaW5wdXQpfWA7XG4gICAgICAgICAgICAvLyByZXR1cm4gYEludmFsaWQgaW5wdXQ6IGV4cGVjdGVkICR7aXNzdWUuZXhwZWN0ZWR9LCByZWNlaXZlZCAke3V0aWwuZ2V0UGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgXHUwMEM5cnZcdTAwRTlueXRlbGVuIGJlbWVuZXQ6IGEgdlx1MDBFMXJ0IFx1MDBFOXJ0XHUwMEU5ayAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDBDOXJ2XHUwMEU5bnl0ZWxlbiBvcGNpXHUwMEYzOiB2YWxhbWVseWlrIFx1MDBFOXJ0XHUwMEU5ayB2XHUwMEUxcnQgJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIjw9XCIgOiBcIjxcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgVFx1MDBGQWwgbmFneTogJHtpc3N1ZS5vcmlnaW4gPz8gXCJcdTAwRTlydFx1MDBFOWtcIn0gbVx1MDBFOXJldGUgdFx1MDBGQWwgbmFneSAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdCA/PyBcImVsZW1cIn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFRcdTAwRkFsIG5hZ3k6IGEgYmVtZW5ldGkgXHUwMEU5cnRcdTAwRTlrICR7aXNzdWUub3JpZ2luID8/IFwiXHUwMEU5cnRcdTAwRTlrXCJ9IHRcdTAwRkFsIG5hZ3k6ICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInRvb19zbWFsbFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI+PVwiIDogXCI+XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFRcdTAwRkFsIGtpY3NpOiBhIGJlbWVuZXRpIFx1MDBFOXJ0XHUwMEU5ayAke2lzc3VlLm9yaWdpbn0gbVx1MDBFOXJldGUgdFx1MDBGQWwga2ljc2kgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXR9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFRcdTAwRkFsIGtpY3NpOiBhIGJlbWVuZXRpIFx1MDBFOXJ0XHUwMEU5ayAke2lzc3VlLm9yaWdpbn0gdFx1MDBGQWwga2ljc2kgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSByZXR1cm4gYFx1MDBDOXJ2XHUwMEU5bnl0ZWxlbiBzdHJpbmc6IFwiJHtfaXNzdWUucHJlZml4fVwiIFx1MDBFOXJ0XHUwMEU5a2tlbCBrZWxsIGtlemRcdTAxNTFkbmllYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiZW5kc193aXRoXCIpIHJldHVybiBgXHUwMEM5cnZcdTAwRTlueXRlbGVuIHN0cmluZzogXCIke19pc3N1ZS5zdWZmaXh9XCIgXHUwMEU5cnRcdTAwRTlra2VsIGtlbGwgdlx1MDBFOWd6XHUwMTUxZG5pZWA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImluY2x1ZGVzXCIpIHJldHVybiBgXHUwMEM5cnZcdTAwRTlueXRlbGVuIHN0cmluZzogXCIke19pc3N1ZS5pbmNsdWRlc31cIiBcdTAwRTlydFx1MDBFOWtldCBrZWxsIHRhcnRhbG1hem5pYWA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInJlZ2V4XCIpIHJldHVybiBgXHUwMEM5cnZcdTAwRTlueXRlbGVuIHN0cmluZzogJHtfaXNzdWUucGF0dGVybn0gbWludFx1MDBFMW5hayBrZWxsIG1lZ2ZlbGVsbmllYDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTAwQzlydlx1MDBFOW55dGVsZW4gJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTAwQzlydlx1MDBFOW55dGVsZW4gc3pcdTAwRTFtOiAke2lzc3VlLmRpdmlzb3J9IHRcdTAwRjZiYnN6XHUwMEY2clx1MDBGNnNcdTAwRTluZWsga2VsbCBsZW5uaWVgO1xuICAgICAgICAgICAgY2FzZSBcInVucmVjb2duaXplZF9rZXlzXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBJc21lcmV0bGVuIGt1bGNzJHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcInNcIiA6IFwiXCJ9OiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIiwgXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDBDOXJ2XHUwMEU5bnl0ZWxlbiBrdWxjcyAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTAwQzlydlx1MDBFOW55dGVsZW4gYmVtZW5ldFwiO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZWxlbWVudFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwMEM5cnZcdTAwRTlueXRlbGVuIFx1MDBFOXJ0XHUwMEU5azogJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTAwQzlydlx1MDBFOW55dGVsZW4gYmVtZW5ldGA7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGxvY2FsZUVycm9yOiBlcnJvcigpXG4gICAgfTtcbn1cbiIsICJpbXBvcnQgKiBhcyB1dGlsIGZyb20gXCIuLi9jb3JlL3V0aWwuanNcIjtcbmNvbnN0IGVycm9yID0gKCk9PntcbiAgICBjb25zdCBTaXphYmxlID0ge1xuICAgICAgICBzdHJpbmc6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwia2FyYWt0ZXJcIixcbiAgICAgICAgICAgIHZlcmI6IFwibWVtaWxpa2lcIlxuICAgICAgICB9LFxuICAgICAgICBmaWxlOiB7XG4gICAgICAgICAgICB1bml0OiBcImJ5dGVcIixcbiAgICAgICAgICAgIHZlcmI6IFwibWVtaWxpa2lcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJpdGVtXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIm1lbWlsaWtpXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcIml0ZW1cIixcbiAgICAgICAgICAgIHZlcmI6IFwibWVtaWxpa2lcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIk5hTlwiIDogXCJudW1iZXJcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiYXJyYXlcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YoZGF0YSkgIT09IE9iamVjdC5wcm90b3R5cGUgJiYgZGF0YS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdDtcbiAgICB9O1xuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJpbnB1dFwiLFxuICAgICAgICBlbWFpbDogXCJhbGFtYXQgZW1haWxcIixcbiAgICAgICAgdXJsOiBcIlVSTFwiLFxuICAgICAgICBlbW9qaTogXCJlbW9qaVwiLFxuICAgICAgICB1dWlkOiBcIlVVSURcIixcbiAgICAgICAgdXVpZHY0OiBcIlVVSUR2NFwiLFxuICAgICAgICB1dWlkdjY6IFwiVVVJRHY2XCIsXG4gICAgICAgIG5hbm9pZDogXCJuYW5vaWRcIixcbiAgICAgICAgZ3VpZDogXCJHVUlEXCIsXG4gICAgICAgIGN1aWQ6IFwiY3VpZFwiLFxuICAgICAgICBjdWlkMjogXCJjdWlkMlwiLFxuICAgICAgICB1bGlkOiBcIlVMSURcIixcbiAgICAgICAgeGlkOiBcIlhJRFwiLFxuICAgICAgICBrc3VpZDogXCJLU1VJRFwiLFxuICAgICAgICBkYXRldGltZTogXCJ0YW5nZ2FsIGRhbiB3YWt0dSBmb3JtYXQgSVNPXCIsXG4gICAgICAgIGRhdGU6IFwidGFuZ2dhbCBmb3JtYXQgSVNPXCIsXG4gICAgICAgIHRpbWU6IFwiamFtIGZvcm1hdCBJU09cIixcbiAgICAgICAgZHVyYXRpb246IFwiZHVyYXNpIGZvcm1hdCBJU09cIixcbiAgICAgICAgaXB2NDogXCJhbGFtYXQgSVB2NFwiLFxuICAgICAgICBpcHY2OiBcImFsYW1hdCBJUHY2XCIsXG4gICAgICAgIGNpZHJ2NDogXCJyZW50YW5nIGFsYW1hdCBJUHY0XCIsXG4gICAgICAgIGNpZHJ2NjogXCJyZW50YW5nIGFsYW1hdCBJUHY2XCIsXG4gICAgICAgIGJhc2U2NDogXCJzdHJpbmcgZGVuZ2FuIGVua29kZSBiYXNlNjRcIixcbiAgICAgICAgYmFzZTY0dXJsOiBcInN0cmluZyBkZW5nYW4gZW5rb2RlIGJhc2U2NHVybFwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJzdHJpbmcgSlNPTlwiLFxuICAgICAgICBlMTY0OiBcImFuZ2thIEUuMTY0XCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJpbnB1dFwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBJbnB1dCB0aWRhayB2YWxpZDogZGloYXJhcGthbiAke2lzc3VlLmV4cGVjdGVkfSwgZGl0ZXJpbWEgJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBJbnB1dCB0aWRhayB2YWxpZDogZGloYXJhcGthbiAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYFBpbGloYW4gdGlkYWsgdmFsaWQ6IGRpaGFyYXBrYW4gc2FsYWggc2F0dSBkYXJpICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLnZhbHVlcywgXCJ8XCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwidG9vX2JpZ1wiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI8PVwiIDogXCI8XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSByZXR1cm4gYFRlcmxhbHUgYmVzYXI6IGRpaGFyYXBrYW4gJHtpc3N1ZS5vcmlnaW4gPz8gXCJ2YWx1ZVwifSBtZW1pbGlraSAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdCA/PyBcImVsZW1lblwifWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgVGVybGFsdSBiZXNhcjogZGloYXJhcGthbiAke2lzc3VlLm9yaWdpbiA/PyBcInZhbHVlXCJ9IG1lbmphZGkgJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIj49XCIgOiBcIj5cIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgVGVybGFsdSBrZWNpbDogZGloYXJhcGthbiAke2lzc3VlLm9yaWdpbn0gbWVtaWxpa2kgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXR9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFRlcmxhbHUga2VjaWw6IGRpaGFyYXBrYW4gJHtpc3N1ZS5vcmlnaW59IG1lbmphZGkgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSByZXR1cm4gYFN0cmluZyB0aWRhayB2YWxpZDogaGFydXMgZGltdWxhaSBkZW5nYW4gXCIke19pc3N1ZS5wcmVmaXh9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJlbmRzX3dpdGhcIikgcmV0dXJuIGBTdHJpbmcgdGlkYWsgdmFsaWQ6IGhhcnVzIGJlcmFraGlyIGRlbmdhbiBcIiR7X2lzc3VlLnN1ZmZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImluY2x1ZGVzXCIpIHJldHVybiBgU3RyaW5nIHRpZGFrIHZhbGlkOiBoYXJ1cyBtZW55ZXJ0YWthbiBcIiR7X2lzc3VlLmluY2x1ZGVzfVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBTdHJpbmcgdGlkYWsgdmFsaWQ6IGhhcnVzIHNlc3VhaSBwb2xhICR7X2lzc3VlLnBhdHRlcm59YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGAke05vdW5zW19pc3N1ZS5mb3JtYXRdID8/IGlzc3VlLmZvcm1hdH0gdGlkYWsgdmFsaWRgO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJub3RfbXVsdGlwbGVfb2ZcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYEFuZ2thIHRpZGFrIHZhbGlkOiBoYXJ1cyBrZWxpcGF0YW4gZGFyaSAke2lzc3VlLmRpdmlzb3J9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ1bnJlY29nbml6ZWRfa2V5c1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgS3VuY2kgdGlkYWsgZGlrZW5hbGkgJHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcInNcIiA6IFwiXCJ9OiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIiwgXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYEt1bmNpIHRpZGFrIHZhbGlkIGRpICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF91bmlvblwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIklucHV0IHRpZGFrIHZhbGlkXCI7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9lbGVtZW50XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOaWxhaSB0aWRhayB2YWxpZCBkaSAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gYElucHV0IHRpZGFrIHZhbGlkYDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuZXhwb3J0IGNvbnN0IHBhcnNlZFR5cGUgPSAoZGF0YSk9PntcbiAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgc3dpdGNoKHQpe1xuICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIm5cdTAwRkFtZXJcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgY2FzZSBcIm9iamVjdFwiOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcImZ5bGtpXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm51bGxcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdDtcbn07XG5jb25zdCBlcnJvciA9ICgpPT57XG4gICAgY29uc3QgU2l6YWJsZSA9IHtcbiAgICAgICAgc3RyaW5nOiB7XG4gICAgICAgICAgICB1bml0OiBcInN0YWZpXCIsXG4gICAgICAgICAgICB2ZXJiOiBcImFcdTAwRjAgaGFmYVwiXG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiYlx1MDBFNnRpXCIsXG4gICAgICAgICAgICB2ZXJiOiBcImFcdTAwRjAgaGFmYVwiXG4gICAgICAgIH0sXG4gICAgICAgIGFycmF5OiB7XG4gICAgICAgICAgICB1bml0OiBcImhsdXRpXCIsXG4gICAgICAgICAgICB2ZXJiOiBcImFcdTAwRjAgaGFmYVwiXG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDogXCJobHV0aVwiLFxuICAgICAgICAgICAgdmVyYjogXCJhXHUwMEYwIGhhZmFcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcImdpbGRpXCIsXG4gICAgICAgIGVtYWlsOiBcIm5ldGZhbmdcIixcbiAgICAgICAgdXJsOiBcInZlZnNsXHUwMEYzXHUwMEYwXCIsXG4gICAgICAgIGVtb2ppOiBcImVtb2ppXCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcIklTTyBkYWdzZXRuaW5nIG9nIHRcdTAwRURtaVwiLFxuICAgICAgICBkYXRlOiBcIklTTyBkYWdzZXRuaW5nXCIsXG4gICAgICAgIHRpbWU6IFwiSVNPIHRcdTAwRURtaVwiLFxuICAgICAgICBkdXJhdGlvbjogXCJJU08gdFx1MDBFRG1hbGVuZ2RcIixcbiAgICAgICAgaXB2NDogXCJJUHY0IGFkZHJlc3NcIixcbiAgICAgICAgaXB2NjogXCJJUHY2IGFkZHJlc3NcIixcbiAgICAgICAgY2lkcnY0OiBcIklQdjQgcmFuZ2VcIixcbiAgICAgICAgY2lkcnY2OiBcIklQdjYgcmFuZ2VcIixcbiAgICAgICAgYmFzZTY0OiBcImJhc2U2NC1lbmNvZGVkIHN0cmVuZ3VyXCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJiYXNlNjR1cmwtZW5jb2RlZCBzdHJlbmd1clwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJKU09OIHN0cmVuZ3VyXCIsXG4gICAgICAgIGUxNjQ6IFwiRS4xNjQgdFx1MDBGNmx1Z2lsZGlcIixcbiAgICAgICAgand0OiBcIkpXVFwiLFxuICAgICAgICB0ZW1wbGF0ZV9saXRlcmFsOiBcImdpbGRpXCJcbiAgICB9O1xuICAgIHJldHVybiAoaXNzdWUpPT57XG4gICAgICAgIHN3aXRjaChpc3N1ZS5jb2RlKXtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3R5cGVcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFJhbmd0IGdpbGRpOiBcdTAwREVcdTAwRkEgc2xcdTAwRjNzdCBpbm4gJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX0gXHUwMEZFYXIgc2VtIFx1MDBFMSBhXHUwMEYwIHZlcmEgJHtpc3N1ZS5leHBlY3RlZH1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBSYW5ndCBnaWxkaTogZ2VydCByXHUwMEUxXHUwMEYwIGZ5cmlyICR7dXRpbC5zdHJpbmdpZnlQcmltaXRpdmUoaXNzdWUudmFsdWVzWzBdKX1gO1xuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwMEQzZ2lsdCB2YWw6IG1cdTAwRTEgdmVyYSBlaXR0IGFmIGVmdGlyZmFyYW5kaSAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS52YWx1ZXMsIFwifFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPD1cIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykgcmV0dXJuIGBPZiBzdFx1MDBGM3J0OiBnZXJ0IGVyIHJcdTAwRTFcdTAwRjAgZnlyaXIgYVx1MDBGMCAke2lzc3VlLm9yaWdpbiA/PyBcImdpbGRpXCJ9IGhhZmkgJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXQgPz8gXCJobHV0aVwifWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgT2Ygc3RcdTAwRjNydDogZ2VydCBlciByXHUwMEUxXHUwMEYwIGZ5cmlyIGFcdTAwRjAgJHtpc3N1ZS5vcmlnaW4gPz8gXCJnaWxkaVwifSBzXHUwMEU5ICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInRvb19zbWFsbFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI+PVwiIDogXCI+XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYE9mIGxcdTAwRUR0aVx1MDBGMDogZ2VydCBlciByXHUwMEUxXHUwMEYwIGZ5cmlyIGFcdTAwRjAgJHtpc3N1ZS5vcmlnaW59IGhhZmkgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXR9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYE9mIGxcdTAwRUR0aVx1MDBGMDogZ2VydCBlciByXHUwMEUxXHUwMEYwIGZ5cmlyIGFcdTAwRjAgJHtpc3N1ZS5vcmlnaW59IHNcdTAwRTkgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDBEM2dpbGR1ciBzdHJlbmd1cjogdmVyXHUwMEYwdXIgYVx1MDBGMCBieXJqYSBcdTAwRTEgXCIke19pc3N1ZS5wcmVmaXh9XCJgO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYFx1MDBEM2dpbGR1ciBzdHJlbmd1cjogdmVyXHUwMEYwdXIgYVx1MDBGMCBlbmRhIFx1MDBFMSBcIiR7X2lzc3VlLnN1ZmZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImluY2x1ZGVzXCIpIHJldHVybiBgXHUwMEQzZ2lsZHVyIHN0cmVuZ3VyOiB2ZXJcdTAwRjB1ciBhXHUwMEYwIGlubmloYWxkYSBcIiR7X2lzc3VlLmluY2x1ZGVzfVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBcdTAwRDNnaWxkdXIgc3RyZW5ndXI6IHZlclx1MDBGMHVyIGFcdTAwRjAgZnlsZ2phIG15bnN0cmkgJHtfaXNzdWUucGF0dGVybn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFJhbmd0ICR7Tm91bnNbX2lzc3VlLmZvcm1hdF0gPz8gaXNzdWUuZm9ybWF0fWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm5vdF9tdWx0aXBsZV9vZlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgUlx1MDBGNm5nIHRhbGE6IHZlclx1MDBGMHVyIGFcdTAwRjAgdmVyYSBtYXJnZmVsZGkgYWYgJHtpc3N1ZS5kaXZpc29yfWA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDBEM1x1MDBGRWVra3QgJHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcImlyIGx5a2xhclwiIDogXCJ1ciBseWtpbGxcIn06ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLmtleXMsIFwiLCBcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2tleVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgUmFuZ3VyIGx5a2lsbCBcdTAwRUQgJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3VuaW9uXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiUmFuZ3QgZ2lsZGlcIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFJhbmd0IGdpbGRpIFx1MDBFRCAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFJhbmd0IGdpbGRpYDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJjYXJhdHRlcmlcIixcbiAgICAgICAgICAgIHZlcmI6IFwiYXZlcmVcIlxuICAgICAgICB9LFxuICAgICAgICBmaWxlOiB7XG4gICAgICAgICAgICB1bml0OiBcImJ5dGVcIixcbiAgICAgICAgICAgIHZlcmI6IFwiYXZlcmVcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJlbGVtZW50aVwiLFxuICAgICAgICAgICAgdmVyYjogXCJhdmVyZVwiXG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDogXCJlbGVtZW50aVwiLFxuICAgICAgICAgICAgdmVyYjogXCJhdmVyZVwiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4pIHtcbiAgICAgICAgcmV0dXJuIFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWRUeXBlID0gKGRhdGEpPT57XG4gICAgICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICAgICAgc3dpdGNoKHQpe1xuICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIm51bWVyb1wiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJ2ZXR0b3JlXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGEgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm51bGxcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKGRhdGEpICE9PSBPYmplY3QucHJvdG90eXBlICYmIGRhdGEuY29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHQ7XG4gICAgfTtcbiAgICBjb25zdCBOb3VucyA9IHtcbiAgICAgICAgcmVnZXg6IFwiaW5wdXRcIixcbiAgICAgICAgZW1haWw6IFwiaW5kaXJpenpvIGVtYWlsXCIsXG4gICAgICAgIHVybDogXCJVUkxcIixcbiAgICAgICAgZW1vamk6IFwiZW1vamlcIixcbiAgICAgICAgdXVpZDogXCJVVUlEXCIsXG4gICAgICAgIHV1aWR2NDogXCJVVUlEdjRcIixcbiAgICAgICAgdXVpZHY2OiBcIlVVSUR2NlwiLFxuICAgICAgICBuYW5vaWQ6IFwibmFub2lkXCIsXG4gICAgICAgIGd1aWQ6IFwiR1VJRFwiLFxuICAgICAgICBjdWlkOiBcImN1aWRcIixcbiAgICAgICAgY3VpZDI6IFwiY3VpZDJcIixcbiAgICAgICAgdWxpZDogXCJVTElEXCIsXG4gICAgICAgIHhpZDogXCJYSURcIixcbiAgICAgICAga3N1aWQ6IFwiS1NVSURcIixcbiAgICAgICAgZGF0ZXRpbWU6IFwiZGF0YSBlIG9yYSBJU09cIixcbiAgICAgICAgZGF0ZTogXCJkYXRhIElTT1wiLFxuICAgICAgICB0aW1lOiBcIm9yYSBJU09cIixcbiAgICAgICAgZHVyYXRpb246IFwiZHVyYXRhIElTT1wiLFxuICAgICAgICBpcHY0OiBcImluZGlyaXp6byBJUHY0XCIsXG4gICAgICAgIGlwdjY6IFwiaW5kaXJpenpvIElQdjZcIixcbiAgICAgICAgY2lkcnY0OiBcImludGVydmFsbG8gSVB2NFwiLFxuICAgICAgICBjaWRydjY6IFwiaW50ZXJ2YWxsbyBJUHY2XCIsXG4gICAgICAgIGJhc2U2NDogXCJzdHJpbmdhIGNvZGlmaWNhdGEgaW4gYmFzZTY0XCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJVUkwgY29kaWZpY2F0YSBpbiBiYXNlNjRcIixcbiAgICAgICAganNvbl9zdHJpbmc6IFwic3RyaW5nYSBKU09OXCIsXG4gICAgICAgIGUxNjQ6IFwibnVtZXJvIEUuMTY0XCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJpbnB1dFwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBJbnB1dCBub24gdmFsaWRvOiBhdHRlc28gJHtpc3N1ZS5leHBlY3RlZH0sIHJpY2V2dXRvICR7cGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9YDtcbiAgICAgICAgICAgIC8vIHJldHVybiBgSW5wdXQgbm9uIHZhbGlkbzogYXR0ZXNvICR7aXNzdWUuZXhwZWN0ZWR9LCByaWNldnV0byAke3V0aWwuZ2V0UGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgSW5wdXQgbm9uIHZhbGlkbzogYXR0ZXNvICR7dXRpbC5zdHJpbmdpZnlQcmltaXRpdmUoaXNzdWUudmFsdWVzWzBdKX1gO1xuICAgICAgICAgICAgICAgIHJldHVybiBgT3B6aW9uZSBub24gdmFsaWRhOiBhdHRlc28gdW5vIHRyYSAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS52YWx1ZXMsIFwifFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPD1cIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykgcmV0dXJuIGBUcm9wcG8gZ3JhbmRlOiAke2lzc3VlLm9yaWdpbiA/PyBcInZhbG9yZVwifSBkZXZlIGF2ZXJlICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0ID8/IFwiZWxlbWVudGlcIn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFRyb3BwbyBncmFuZGU6ICR7aXNzdWUub3JpZ2luID8/IFwidmFsb3JlXCJ9IGRldmUgZXNzZXJlICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInRvb19zbWFsbFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI+PVwiIDogXCI+XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFRyb3BwbyBwaWNjb2xvOiAke2lzc3VlLm9yaWdpbn0gZGV2ZSBhdmVyZSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdH1gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgVHJvcHBvIHBpY2NvbG86ICR7aXNzdWUub3JpZ2lufSBkZXZlIGVzc2VyZSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2Zvcm1hdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgX2lzc3VlID0gaXNzdWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInN0YXJ0c193aXRoXCIpIHJldHVybiBgU3RyaW5nYSBub24gdmFsaWRhOiBkZXZlIGluaXppYXJlIGNvbiBcIiR7X2lzc3VlLnByZWZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYFN0cmluZ2Egbm9uIHZhbGlkYTogZGV2ZSB0ZXJtaW5hcmUgY29uIFwiJHtfaXNzdWUuc3VmZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBTdHJpbmdhIG5vbiB2YWxpZGE6IGRldmUgaW5jbHVkZXJlIFwiJHtfaXNzdWUuaW5jbHVkZXN9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYFN0cmluZ2Egbm9uIHZhbGlkYTogZGV2ZSBjb3JyaXNwb25kZXJlIGFsIHBhdHRlcm4gJHtfaXNzdWUucGF0dGVybn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYEludmFsaWQgJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOdW1lcm8gbm9uIHZhbGlkbzogZGV2ZSBlc3NlcmUgdW4gbXVsdGlwbG8gZGkgJHtpc3N1ZS5kaXZpc29yfWA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYENoaWF2JHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcImlcIiA6IFwiZVwifSBub24gcmljb25vc2NpdXQke2lzc3VlLmtleXMubGVuZ3RoID4gMSA/IFwiZVwiIDogXCJhXCJ9OiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIiwgXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYENoaWF2ZSBub24gdmFsaWRhIGluICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF91bmlvblwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIklucHV0IG5vbiB2YWxpZG9cIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFZhbG9yZSBub24gdmFsaWRvIGluICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBgSW5wdXQgbm9uIHZhbGlkb2A7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGxvY2FsZUVycm9yOiBlcnJvcigpXG4gICAgfTtcbn1cbiIsICJpbXBvcnQgKiBhcyB1dGlsIGZyb20gXCIuLi9jb3JlL3V0aWwuanNcIjtcbmNvbnN0IGVycm9yID0gKCk9PntcbiAgICBjb25zdCBTaXphYmxlID0ge1xuICAgICAgICBzdHJpbmc6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHU2NTg3XHU1QjU3XCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MzA2N1x1MzA0Mlx1MzA4QlwiXG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHUzMEQwXHUzMEE0XHUzMEM4XCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MzA2N1x1MzA0Mlx1MzA4QlwiXG4gICAgICAgIH0sXG4gICAgICAgIGFycmF5OiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1ODk4MVx1N0QyMFwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTMwNjdcdTMwNDJcdTMwOEJcIlxuICAgICAgICB9LFxuICAgICAgICBzZXQ6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHU4OTgxXHU3RDIwXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MzA2N1x1MzA0Mlx1MzA4QlwiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4pIHtcbiAgICAgICAgcmV0dXJuIFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWRUeXBlID0gKGRhdGEpPT57XG4gICAgICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICAgICAgc3dpdGNoKHQpe1xuICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIlx1NjU3MFx1NTAyNFwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTkxNERcdTUyMTdcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YoZGF0YSkgIT09IE9iamVjdC5wcm90b3R5cGUgJiYgZGF0YS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdDtcbiAgICB9O1xuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJcdTUxNjVcdTUyOUJcdTUwMjRcIixcbiAgICAgICAgZW1haWw6IFwiXHUzMEUxXHUzMEZDXHUzMEVCXHUzMEEyXHUzMEM5XHUzMEVDXHUzMEI5XCIsXG4gICAgICAgIHVybDogXCJVUkxcIixcbiAgICAgICAgZW1vamk6IFwiXHU3RDc1XHU2NTg3XHU1QjU3XCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcIklTT1x1NjVFNVx1NjY0MlwiLFxuICAgICAgICBkYXRlOiBcIklTT1x1NjVFNVx1NEVEOFwiLFxuICAgICAgICB0aW1lOiBcIklTT1x1NjY0Mlx1NTIzQlwiLFxuICAgICAgICBkdXJhdGlvbjogXCJJU09cdTY3MUZcdTk1OTNcIixcbiAgICAgICAgaXB2NDogXCJJUHY0XHUzMEEyXHUzMEM5XHUzMEVDXHUzMEI5XCIsXG4gICAgICAgIGlwdjY6IFwiSVB2Nlx1MzBBMlx1MzBDOVx1MzBFQ1x1MzBCOVwiLFxuICAgICAgICBjaWRydjQ6IFwiSVB2NFx1N0JDNFx1NTZGMlwiLFxuICAgICAgICBjaWRydjY6IFwiSVB2Nlx1N0JDNFx1NTZGMlwiLFxuICAgICAgICBiYXNlNjQ6IFwiYmFzZTY0XHUzMEE4XHUzMEYzXHUzMEIzXHUzMEZDXHUzMEM5XHU2NTg3XHU1QjU3XHU1MjE3XCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJiYXNlNjR1cmxcdTMwQThcdTMwRjNcdTMwQjNcdTMwRkNcdTMwQzlcdTY1ODdcdTVCNTdcdTUyMTdcIixcbiAgICAgICAganNvbl9zdHJpbmc6IFwiSlNPTlx1NjU4N1x1NUI1N1x1NTIxN1wiLFxuICAgICAgICBlMTY0OiBcIkUuMTY0XHU3NTZBXHU1M0Y3XCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJcdTUxNjVcdTUyOUJcdTUwMjRcIlxuICAgIH07XG4gICAgcmV0dXJuIChpc3N1ZSk9PntcbiAgICAgICAgc3dpdGNoKGlzc3VlLmNvZGUpe1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdHlwZVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHU3MTIxXHU1MkI5XHUzMDZBXHU1MTY1XHU1MjlCOiAke2lzc3VlLmV4cGVjdGVkfVx1MzA0Q1x1NjcxRlx1NUY4NVx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzA0Q1x1MzAwMSR7cGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9XHUzMDRDXHU1MTY1XHU1MjlCXHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU3XHUzMDVGYDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgXHU3MTIxXHU1MkI5XHUzMDZBXHU1MTY1XHU1MjlCOiAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9XHUzMDRDXHU2NzFGXHU1Rjg1XHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU3XHUzMDVGYDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1NzEyMVx1NTJCOVx1MzA2QVx1OTA3OFx1NjI5RTogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcIlx1MzAwMVwiKX1cdTMwNkVcdTMwNDRcdTMwNUFcdTMwOENcdTMwNEJcdTMwNjdcdTMwNDJcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlgO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiXHU0RUU1XHU0RTBCXHUzMDY3XHUzMDQyXHUzMDhCXCIgOiBcIlx1MzA4OFx1MzA4QVx1NUMwRlx1MzA1NVx1MzA0NFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykgcmV0dXJuIGBcdTU5MjdcdTMwNERcdTMwNTlcdTMwNEVcdTMwOEJcdTUwMjQ6ICR7aXNzdWUub3JpZ2luID8/IFwiXHU1MDI0XCJ9XHUzMDZGJHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9JHtzaXppbmcudW5pdCA/PyBcIlx1ODk4MVx1N0QyMFwifSR7YWRqfVx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHU1OTI3XHUzMDREXHUzMDU5XHUzMDRFXHUzMDhCXHU1MDI0OiAke2lzc3VlLm9yaWdpbiA/PyBcIlx1NTAyNFwifVx1MzA2RiR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSR7YWRqfVx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInRvb19zbWFsbFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCJcdTRFRTVcdTRFMEFcdTMwNjdcdTMwNDJcdTMwOEJcIiA6IFwiXHUzMDg4XHUzMDhBXHU1OTI3XHUzMDREXHUzMDQ0XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSByZXR1cm4gYFx1NUMwRlx1MzA1NVx1MzA1OVx1MzA0RVx1MzA4Qlx1NTAyNDogJHtpc3N1ZS5vcmlnaW59XHUzMDZGJHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9JHtzaXppbmcudW5pdH0ke2Fkan1cdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlgO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1NUMwRlx1MzA1NVx1MzA1OVx1MzA0RVx1MzA4Qlx1NTAyNDogJHtpc3N1ZS5vcmlnaW59XHUzMDZGJHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9JHthZGp9XHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSByZXR1cm4gYFx1NzEyMVx1NTJCOVx1MzA2QVx1NjU4N1x1NUI1N1x1NTIxNzogXCIke19pc3N1ZS5wcmVmaXh9XCJcdTMwNjdcdTU5Q0JcdTMwN0VcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJlbmRzX3dpdGhcIikgcmV0dXJuIGBcdTcxMjFcdTUyQjlcdTMwNkFcdTY1ODdcdTVCNTdcdTUyMTc6IFwiJHtfaXNzdWUuc3VmZml4fVwiXHUzMDY3XHU3RDQyXHUzMDhGXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5YDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBcdTcxMjFcdTUyQjlcdTMwNkFcdTY1ODdcdTVCNTdcdTUyMTc6IFwiJHtfaXNzdWUuaW5jbHVkZXN9XCJcdTMwOTJcdTU0MkJcdTMwODBcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYFx1NzEyMVx1NTJCOVx1MzA2QVx1NjU4N1x1NUI1N1x1NTIxNzogXHUzMEQxXHUzMEJGXHUzMEZDXHUzMEYzJHtfaXNzdWUucGF0dGVybn1cdTMwNkJcdTRFMDBcdTgxRjRcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlgO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1NzEyMVx1NTJCOVx1MzA2QSR7Tm91bnNbX2lzc3VlLmZvcm1hdF0gPz8gaXNzdWUuZm9ybWF0fWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm5vdF9tdWx0aXBsZV9vZlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHU3MTIxXHU1MkI5XHUzMDZBXHU2NTcwXHU1MDI0OiAke2lzc3VlLmRpdmlzb3J9XHUzMDZFXHU1MDBEXHU2NTcwXHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5YDtcbiAgICAgICAgICAgIGNhc2UgXCJ1bnJlY29nbml6ZWRfa2V5c1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHU4QThEXHU4QjU4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDZBXHUzMDQ0XHUzMEFEXHUzMEZDJHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcIlx1N0ZBNFwiIDogXCJcIn06ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLmtleXMsIFwiXHUzMDAxXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYCR7aXNzdWUub3JpZ2lufVx1NTE4NVx1MzA2RVx1NzEyMVx1NTJCOVx1MzA2QVx1MzBBRFx1MzBGQ2A7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF91bmlvblwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIlx1NzEyMVx1NTJCOVx1MzA2QVx1NTE2NVx1NTI5QlwiO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZWxlbWVudFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgJHtpc3N1ZS5vcmlnaW59XHU1MTg1XHUzMDZFXHU3MTIxXHU1MkI5XHUzMDZBXHU1MDI0YDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTcxMjFcdTUyQjlcdTMwNkFcdTUxNjVcdTUyOUJgO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBsb2NhbGVFcnJvcjogZXJyb3IoKVxuICAgIH07XG59XG4iLCAiaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi4vY29yZS91dGlsLmpzXCI7XG5leHBvcnQgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICBzd2l0Y2godCl7XG4gICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gTnVtYmVyLmlzTmFOKGRhdGEpID8gXCJOYU5cIiA6IFwiXHUxMEUwXHUxMEQ4XHUxMEVBXHUxMEVFXHUxMEQ1XHUxMEQ4XCI7XG4gICAgICAgICAgICB9XG4gICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTEwREJcdTEwRDBcdTEwRTFcdTEwRDhcdTEwRDVcdTEwRDhcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGRhdGEgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKGRhdGEpICE9PSBPYmplY3QucHJvdG90eXBlICYmIGRhdGEuY29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgfVxuICAgIGNvbnN0IHR5cGVNYXAgPSB7XG4gICAgICAgIHN0cmluZzogXCJcdTEwRTFcdTEwRTJcdTEwRTBcdTEwRDhcdTEwRENcdTEwRDJcdTEwRDhcIixcbiAgICAgICAgYm9vbGVhbjogXCJcdTEwRDFcdTEwRTNcdTEwREFcdTEwRDRcdTEwRDBcdTEwRENcdTEwRDhcIixcbiAgICAgICAgdW5kZWZpbmVkOiBcInVuZGVmaW5lZFwiLFxuICAgICAgICBiaWdpbnQ6IFwiYmlnaW50XCIsXG4gICAgICAgIHN5bWJvbDogXCJzeW1ib2xcIixcbiAgICAgICAgZnVuY3Rpb246IFwiXHUxMEU0XHUxMEUzXHUxMERDXHUxMEU1XHUxMEVBXHUxMEQ4XHUxMEQwXCJcbiAgICB9O1xuICAgIHJldHVybiB0eXBlTWFwW3RdID8/IHQ7XG59O1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJcdTEwRTFcdTEwRDhcdTEwREJcdTEwRDFcdTEwRERcdTEwREFcdTEwRERcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUxMEUzXHUxMERDXHUxMEQzXHUxMEQwIFx1MTBFOFx1MTBENFx1MTBEOFx1MTBFQVx1MTBEMFx1MTBENVx1MTBEM1x1MTBENFx1MTBFMVwiXG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHUxMEQxXHUxMEQwXHUxMEQ4XHUxMEUyXHUxMEQ4XCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MTBFM1x1MTBEQ1x1MTBEM1x1MTBEMCBcdTEwRThcdTEwRDRcdTEwRDhcdTEwRUFcdTEwRDBcdTEwRDVcdTEwRDNcdTEwRDRcdTEwRTFcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJcdTEwRDRcdTEwREFcdTEwRDRcdTEwREJcdTEwRDRcdTEwRENcdTEwRTJcdTEwRDhcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUxMEUzXHUxMERDXHUxMEQzXHUxMEQwIFx1MTBFOFx1MTBENFx1MTBEOFx1MTBFQVx1MTBEMFx1MTBENVx1MTBEM1x1MTBENFx1MTBFMVwiXG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDogXCJcdTEwRDRcdTEwREFcdTEwRDRcdTEwREJcdTEwRDRcdTEwRENcdTEwRTJcdTEwRDhcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUxMEUzXHUxMERDXHUxMEQzXHUxMEQwIFx1MTBFOFx1MTBENFx1MTBEOFx1MTBFQVx1MTBEMFx1MTBENVx1MTBEM1x1MTBENFx1MTBFMVwiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4pIHtcbiAgICAgICAgcmV0dXJuIFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgIH1cbiAgICBjb25zdCBOb3VucyA9IHtcbiAgICAgICAgcmVnZXg6IFwiXHUxMEU4XHUxMEQ0XHUxMEU3XHUxMEQ1XHUxMEQwXHUxMERDXHUxMEQwXCIsXG4gICAgICAgIGVtYWlsOiBcIlx1MTBENFx1MTBEQS1cdTEwRTRcdTEwRERcdTEwRTFcdTEwRTJcdTEwRDhcdTEwRTEgXHUxMERCXHUxMEQ4XHUxMEUxXHUxMEQwXHUxMERCXHUxMEQwXHUxMEUwXHUxMEQ3XHUxMEQ4XCIsXG4gICAgICAgIHVybDogXCJVUkxcIixcbiAgICAgICAgZW1vamk6IFwiXHUxMEQ0XHUxMERCXHUxMEREXHUxMEVGXHUxMEQ4XCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcIlx1MTBEN1x1MTBEMFx1MTBFMFx1MTBEOFx1MTBFNlx1MTBEOC1cdTEwRDNcdTEwRTBcdTEwRERcIixcbiAgICAgICAgZGF0ZTogXCJcdTEwRDdcdTEwRDBcdTEwRTBcdTEwRDhcdTEwRTZcdTEwRDhcIixcbiAgICAgICAgdGltZTogXCJcdTEwRDNcdTEwRTBcdTEwRERcIixcbiAgICAgICAgZHVyYXRpb246IFwiXHUxMEVFXHUxMEQwXHUxMERDXHUxMEQyXHUxMEUwXHUxMEVCXHUxMERBXHUxMEQ4XHUxMEQ1XHUxMEREXHUxMEQxXHUxMEQwXCIsXG4gICAgICAgIGlwdjQ6IFwiSVB2NCBcdTEwREJcdTEwRDhcdTEwRTFcdTEwRDBcdTEwREJcdTEwRDBcdTEwRTBcdTEwRDdcdTEwRDhcIixcbiAgICAgICAgaXB2NjogXCJJUHY2IFx1MTBEQlx1MTBEOFx1MTBFMVx1MTBEMFx1MTBEQlx1MTBEMFx1MTBFMFx1MTBEN1x1MTBEOFwiLFxuICAgICAgICBjaWRydjQ6IFwiSVB2NCBcdTEwRDNcdTEwRDhcdTEwRDBcdTEwREVcdTEwRDBcdTEwRDZcdTEwRERcdTEwRENcdTEwRDhcIixcbiAgICAgICAgY2lkcnY2OiBcIklQdjYgXHUxMEQzXHUxMEQ4XHUxMEQwXHUxMERFXHUxMEQwXHUxMEQ2XHUxMEREXHUxMERDXHUxMEQ4XCIsXG4gICAgICAgIGJhc2U2NDogXCJiYXNlNjQtXHUxMEQ5XHUxMEREXHUxMEQzXHUxMEQ4XHUxMEUwXHUxMEQ0XHUxMEQxXHUxMEUzXHUxMERBXHUxMEQ4IFx1MTBFMVx1MTBFMlx1MTBFMFx1MTBEOFx1MTBEQ1x1MTBEMlx1MTBEOFwiLFxuICAgICAgICBiYXNlNjR1cmw6IFwiYmFzZTY0dXJsLVx1MTBEOVx1MTBERFx1MTBEM1x1MTBEOFx1MTBFMFx1MTBENFx1MTBEMVx1MTBFM1x1MTBEQVx1MTBEOCBcdTEwRTFcdTEwRTJcdTEwRTBcdTEwRDhcdTEwRENcdTEwRDJcdTEwRDhcIixcbiAgICAgICAganNvbl9zdHJpbmc6IFwiSlNPTiBcdTEwRTFcdTEwRTJcdTEwRTBcdTEwRDhcdTEwRENcdTEwRDJcdTEwRDhcIixcbiAgICAgICAgZTE2NDogXCJFLjE2NCBcdTEwRENcdTEwRERcdTEwREJcdTEwRDRcdTEwRTBcdTEwRDhcIixcbiAgICAgICAgand0OiBcIkpXVFwiLFxuICAgICAgICB0ZW1wbGF0ZV9saXRlcmFsOiBcIlx1MTBFOFx1MTBENFx1MTBFN1x1MTBENVx1MTBEMFx1MTBEQ1x1MTBEMFwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTEwRDBcdTEwRTBcdTEwRDBcdTEwRTFcdTEwRUNcdTEwRERcdTEwRTBcdTEwRDggXHUxMEU4XHUxMEQ0XHUxMEU3XHUxMEQ1XHUxMEQwXHUxMERDXHUxMEQwOiBcdTEwREJcdTEwRERcdTEwRTFcdTEwRDBcdTEwREFcdTEwRERcdTEwRDNcdTEwRENcdTEwRDRcdTEwREFcdTEwRDggJHtpc3N1ZS5leHBlY3RlZH0sIFx1MTBEQlx1MTBEOFx1MTBFNlx1MTBENFx1MTBEMVx1MTBFM1x1MTBEQVx1MTBEOCAke3BhcnNlZFR5cGUoaXNzdWUuaW5wdXQpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF92YWx1ZVwiOlxuICAgICAgICAgICAgICAgIGlmIChpc3N1ZS52YWx1ZXMubGVuZ3RoID09PSAxKSByZXR1cm4gYFx1MTBEMFx1MTBFMFx1MTBEMFx1MTBFMVx1MTBFQ1x1MTBERFx1MTBFMFx1MTBEOCBcdTEwRThcdTEwRDRcdTEwRTdcdTEwRDVcdTEwRDBcdTEwRENcdTEwRDA6IFx1MTBEQlx1MTBERFx1MTBFMVx1MTBEMFx1MTBEQVx1MTBERFx1MTBEM1x1MTBEQ1x1MTBENFx1MTBEQVx1MTBEOCAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MTBEMFx1MTBFMFx1MTBEMFx1MTBFMVx1MTBFQ1x1MTBERFx1MTBFMFx1MTBEOCBcdTEwRDVcdTEwRDBcdTEwRTBcdTEwRDhcdTEwRDBcdTEwRENcdTEwRTJcdTEwRDg6IFx1MTBEQlx1MTBERFx1MTBFMVx1MTBEMFx1MTBEQVx1MTBERFx1MTBEM1x1MTBEQ1x1MTBENFx1MTBEQVx1MTBEOFx1MTBEMCBcdTEwRDRcdTEwRTBcdTEwRDctXHUxMEQ0XHUxMEUwXHUxMEQ3XHUxMEQ4ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLnZhbHVlcywgXCJ8XCIpfS1cdTEwRDNcdTEwRDBcdTEwRENgO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPD1cIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykgcmV0dXJuIGBcdTEwRDZcdTEwRDRcdTEwRDNcdTEwREJcdTEwRDRcdTEwRTJcdTEwRDBcdTEwRDMgXHUxMEQzXHUxMEQ4XHUxMEQzXHUxMEQ4OiBcdTEwREJcdTEwRERcdTEwRTFcdTEwRDBcdTEwREFcdTEwRERcdTEwRDNcdTEwRENcdTEwRDRcdTEwREFcdTEwRDggJHtpc3N1ZS5vcmlnaW4gPz8gXCJcdTEwREJcdTEwRENcdTEwRDhcdTEwRThcdTEwRDVcdTEwRENcdTEwRDRcdTEwREFcdTEwRERcdTEwRDFcdTEwRDBcIn0gJHtzaXppbmcudmVyYn0gJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXR9YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTEwRDZcdTEwRDRcdTEwRDNcdTEwREJcdTEwRDRcdTEwRTJcdTEwRDBcdTEwRDMgXHUxMEQzXHUxMEQ4XHUxMEQzXHUxMEQ4OiBcdTEwREJcdTEwRERcdTEwRTFcdTEwRDBcdTEwREFcdTEwRERcdTEwRDNcdTEwRENcdTEwRDRcdTEwREFcdTEwRDggJHtpc3N1ZS5vcmlnaW4gPz8gXCJcdTEwREJcdTEwRENcdTEwRDhcdTEwRThcdTEwRDVcdTEwRENcdTEwRDRcdTEwREFcdTEwRERcdTEwRDFcdTEwRDBcIn0gXHUxMEQ4XHUxMEU3XHUxMEREXHUxMEUxICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInRvb19zbWFsbFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI+PVwiIDogXCI+XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MTBENlx1MTBENFx1MTBEM1x1MTBEQlx1MTBENFx1MTBFMlx1MTBEMFx1MTBEMyBcdTEwREVcdTEwRDBcdTEwRTJcdTEwRDBcdTEwRTBcdTEwRDA6IFx1MTBEQlx1MTBERFx1MTBFMVx1MTBEMFx1MTBEQVx1MTBERFx1MTBEM1x1MTBEQ1x1MTBENFx1MTBEQVx1MTBEOCAke2lzc3VlLm9yaWdpbn0gJHtzaXppbmcudmVyYn0gJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXR9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MTBENlx1MTBENFx1MTBEM1x1MTBEQlx1MTBENFx1MTBFMlx1MTBEMFx1MTBEMyBcdTEwREVcdTEwRDBcdTEwRTJcdTEwRDBcdTEwRTBcdTEwRDA6IFx1MTBEQlx1MTBERFx1MTBFMVx1MTBEMFx1MTBEQVx1MTBERFx1MTBEM1x1MTBEQ1x1MTBENFx1MTBEQVx1MTBEOCAke2lzc3VlLm9yaWdpbn0gXHUxMEQ4XHUxMEU3XHUxMEREXHUxMEUxICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZm9ybWF0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBfaXNzdWUgPSBpc3N1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwic3RhcnRzX3dpdGhcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTEwRDBcdTEwRTBcdTEwRDBcdTEwRTFcdTEwRUNcdTEwRERcdTEwRTBcdTEwRDggXHUxMEUxXHUxMEUyXHUxMEUwXHUxMEQ4XHUxMERDXHUxMEQyXHUxMEQ4OiBcdTEwRTNcdTEwRENcdTEwRDNcdTEwRDAgXHUxMEQ4XHUxMEVDXHUxMEU3XHUxMEQ0XHUxMEQxXHUxMEREXHUxMEQzXHUxMEQ0XHUxMEUxIFwiJHtfaXNzdWUucHJlZml4fVwiLVx1MTBEOFx1MTBEN2A7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiZW5kc193aXRoXCIpIHJldHVybiBgXHUxMEQwXHUxMEUwXHUxMEQwXHUxMEUxXHUxMEVDXHUxMEREXHUxMEUwXHUxMEQ4IFx1MTBFMVx1MTBFMlx1MTBFMFx1MTBEOFx1MTBEQ1x1MTBEMlx1MTBEODogXHUxMEUzXHUxMERDXHUxMEQzXHUxMEQwIFx1MTBEQlx1MTBEN1x1MTBEMFx1MTBENVx1MTBFMFx1MTBEM1x1MTBENFx1MTBEMVx1MTBERFx1MTBEM1x1MTBENFx1MTBFMSBcIiR7X2lzc3VlLnN1ZmZpeH1cIi1cdTEwRDhcdTEwRDdgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJpbmNsdWRlc1wiKSByZXR1cm4gYFx1MTBEMFx1MTBFMFx1MTBEMFx1MTBFMVx1MTBFQ1x1MTBERFx1MTBFMFx1MTBEOCBcdTEwRTFcdTEwRTJcdTEwRTBcdTEwRDhcdTEwRENcdTEwRDJcdTEwRDg6IFx1MTBFM1x1MTBEQ1x1MTBEM1x1MTBEMCBcdTEwRThcdTEwRDRcdTEwRDhcdTEwRUFcdTEwRDBcdTEwRDVcdTEwRDNcdTEwRDRcdTEwRTEgXCIke19pc3N1ZS5pbmNsdWRlc31cIi1cdTEwRTFgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYFx1MTBEMFx1MTBFMFx1MTBEMFx1MTBFMVx1MTBFQ1x1MTBERFx1MTBFMFx1MTBEOCBcdTEwRTFcdTEwRTJcdTEwRTBcdTEwRDhcdTEwRENcdTEwRDJcdTEwRDg6IFx1MTBFM1x1MTBEQ1x1MTBEM1x1MTBEMCBcdTEwRThcdTEwRDRcdTEwRDRcdTEwRTFcdTEwRDBcdTEwRDFcdTEwRDBcdTEwREJcdTEwRDRcdTEwRDFcdTEwRERcdTEwRDNcdTEwRDRcdTEwRTEgXHUxMEU4XHUxMEQwXHUxMEQxXHUxMERBXHUxMEREXHUxMERDXHUxMEUxICR7X2lzc3VlLnBhdHRlcm59YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTEwRDBcdTEwRTBcdTEwRDBcdTEwRTFcdTEwRUNcdTEwRERcdTEwRTBcdTEwRDggJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTEwRDBcdTEwRTBcdTEwRDBcdTEwRTFcdTEwRUNcdTEwRERcdTEwRTBcdTEwRDggXHUxMEUwXHUxMEQ4XHUxMEVBXHUxMEVFXHUxMEQ1XHUxMEQ4OiBcdTEwRTNcdTEwRENcdTEwRDNcdTEwRDAgXHUxMEQ4XHUxMEU3XHUxMEREXHUxMEUxICR7aXNzdWUuZGl2aXNvcn0tXHUxMEQ4XHUxMEUxIFx1MTBFRlx1MTBENFx1MTBFMFx1MTBEMFx1MTBEM1x1MTBEOGA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MTBFM1x1MTBFQVx1MTBEQ1x1MTBERFx1MTBEMVx1MTBEOCBcdTEwRDJcdTEwRDBcdTEwRTFcdTEwRDBcdTEwRTZcdTEwRDRcdTEwRDEke2lzc3VlLmtleXMubGVuZ3RoID4gMSA/IFwiXHUxMEQ0XHUxMEQxXHUxMEQ4XCIgOiBcIlx1MTBEOFwifTogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgXCIsIFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfa2V5XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTEwRDBcdTEwRTBcdTEwRDBcdTEwRTFcdTEwRUNcdTEwRERcdTEwRTBcdTEwRDggXHUxMEQyXHUxMEQwXHUxMEUxXHUxMEQwXHUxMEU2XHUxMEQ0XHUxMEQxXHUxMEQ4ICR7aXNzdWUub3JpZ2lufS1cdTEwRThcdTEwRDhgO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTEwRDBcdTEwRTBcdTEwRDBcdTEwRTFcdTEwRUNcdTEwRERcdTEwRTBcdTEwRDggXHUxMEU4XHUxMEQ0XHUxMEU3XHUxMEQ1XHUxMEQwXHUxMERDXHUxMEQwXCI7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9lbGVtZW50XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTEwRDBcdTEwRTBcdTEwRDBcdTEwRTFcdTEwRUNcdTEwRERcdTEwRTBcdTEwRDggXHUxMERCXHUxMERDXHUxMEQ4XHUxMEU4XHUxMEQ1XHUxMERDXHUxMEQ0XHUxMERBXHUxMEREXHUxMEQxXHUxMEQwICR7aXNzdWUub3JpZ2lufS1cdTEwRThcdTEwRDhgO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MTBEMFx1MTBFMFx1MTBEMFx1MTBFMVx1MTBFQ1x1MTBERFx1MTBFMFx1MTBEOCBcdTEwRThcdTEwRDRcdTEwRTdcdTEwRDVcdTEwRDBcdTEwRENcdTEwRDBgO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBsb2NhbGVFcnJvcjogZXJyb3IoKVxuICAgIH07XG59XG4iLCAiaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi4vY29yZS91dGlsLmpzXCI7XG5jb25zdCBlcnJvciA9ICgpPT57XG4gICAgY29uc3QgU2l6YWJsZSA9IHtcbiAgICAgICAgc3RyaW5nOiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MTc4Rlx1MTdCRFx1MTdBMlx1MTc4MFx1MTdEMlx1MTc5Rlx1MTc5QVwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTE3ODJcdTE3QkRcdTE3OUFcdTE3OThcdTE3QjZcdTE3OTNcIlxuICAgICAgICB9LFxuICAgICAgICBmaWxlOiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MTc5NFx1MTdDM1wiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTE3ODJcdTE3QkRcdTE3OUFcdTE3OThcdTE3QjZcdTE3OTNcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJcdTE3OTJcdTE3QjZcdTE3OEZcdTE3QkJcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUxNzgyXHUxN0JEXHUxNzlBXHUxNzk4XHUxN0I2XHUxNzkzXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MTc5Mlx1MTdCNlx1MTc4Rlx1MTdCQlwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTE3ODJcdTE3QkRcdTE3OUFcdTE3OThcdTE3QjZcdTE3OTNcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIlx1MTc5OFx1MTdCN1x1MTc5M1x1MTc5OFx1MTdDMlx1MTc5M1x1MTc4N1x1MTdCNlx1MTc5Qlx1MTdDMVx1MTc4MSAoTmFOKVwiIDogXCJcdTE3OUJcdTE3QzFcdTE3ODFcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiXHUxN0EyXHUxN0I2XHUxNzlBXHUxN0MxIChBcnJheSlcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiXHUxNzgyXHUxN0QyXHUxNzk4XHUxN0I2XHUxNzkzXHUxNzhGXHUxNzk4XHUxN0QyXHUxNzlCXHUxN0MzIChudWxsKVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YoZGF0YSkgIT09IE9iamVjdC5wcm90b3R5cGUgJiYgZGF0YS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdDtcbiAgICB9O1xuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJcdTE3OTFcdTE3QjdcdTE3OTNcdTE3RDJcdTE3OTNcdTE3OTNcdTE3RDBcdTE3OTlcdTE3OTRcdTE3ODlcdTE3RDJcdTE3ODVcdTE3QkNcdTE3OUJcIixcbiAgICAgICAgZW1haWw6IFwiXHUxN0EyXHUxN0I2XHUxNzlGXHUxNzk5XHUxNzhBXHUxN0QyXHUxNzhCXHUxN0I2XHUxNzkzXHUxN0EyXHUxN0NBXHUxN0I4XHUxNzk4XHUxN0MyXHUxNzlCXCIsXG4gICAgICAgIHVybDogXCJVUkxcIixcbiAgICAgICAgZW1vamk6IFwiXHUxNzlGXHUxNzg5XHUxN0QyXHUxNzg5XHUxN0I2XHUxN0EyXHUxN0I2XHUxNzlBXHUxNzk4XHUxN0QyXHUxNzk4XHUxNzhFXHUxN0NEXCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcIlx1MTc4MFx1MTdCNlx1MTc5Qlx1MTc5NFx1MTc5QVx1MTdCN1x1MTc4NVx1MTdEMlx1MTc4Nlx1MTdDMVx1MTc5MSBcdTE3OTNcdTE3QjdcdTE3ODRcdTE3OThcdTE3QzlcdTE3QzRcdTE3ODQgSVNPXCIsXG4gICAgICAgIGRhdGU6IFwiXHUxNzgwXHUxN0I2XHUxNzlCXHUxNzk0XHUxNzlBXHUxN0I3XHUxNzg1XHUxN0QyXHUxNzg2XHUxN0MxXHUxNzkxIElTT1wiLFxuICAgICAgICB0aW1lOiBcIlx1MTc5OFx1MTdDOVx1MTdDNFx1MTc4NCBJU09cIixcbiAgICAgICAgZHVyYXRpb246IFwiXHUxNzlBXHUxNzk5XHUxN0M4XHUxNzk2XHUxN0MxXHUxNzlCIElTT1wiLFxuICAgICAgICBpcHY0OiBcIlx1MTdBMlx1MTdCNlx1MTc5Rlx1MTc5OVx1MTc4QVx1MTdEMlx1MTc4Qlx1MTdCNlx1MTc5MyBJUHY0XCIsXG4gICAgICAgIGlwdjY6IFwiXHUxN0EyXHUxN0I2XHUxNzlGXHUxNzk5XHUxNzhBXHUxN0QyXHUxNzhCXHUxN0I2XHUxNzkzIElQdjZcIixcbiAgICAgICAgY2lkcnY0OiBcIlx1MTc4QVx1MTdDMlx1MTc5M1x1MTdBMlx1MTdCNlx1MTc5Rlx1MTc5OVx1MTc4QVx1MTdEMlx1MTc4Qlx1MTdCNlx1MTc5MyBJUHY0XCIsXG4gICAgICAgIGNpZHJ2NjogXCJcdTE3OEFcdTE3QzJcdTE3OTNcdTE3QTJcdTE3QjZcdTE3OUZcdTE3OTlcdTE3OEFcdTE3RDJcdTE3OEJcdTE3QjZcdTE3OTMgSVB2NlwiLFxuICAgICAgICBiYXNlNjQ6IFwiXHUxNzgxXHUxN0QyXHUxNzlGXHUxN0MyXHUxN0EyXHUxNzgwXHUxN0QyXHUxNzlGXHUxNzlBXHUxN0EyXHUxN0NBXHUxN0I3XHUxNzgwXHUxN0JDXHUxNzhBIGJhc2U2NFwiLFxuICAgICAgICBiYXNlNjR1cmw6IFwiXHUxNzgxXHUxN0QyXHUxNzlGXHUxN0MyXHUxN0EyXHUxNzgwXHUxN0QyXHUxNzlGXHUxNzlBXHUxN0EyXHUxN0NBXHUxN0I3XHUxNzgwXHUxN0JDXHUxNzhBIGJhc2U2NHVybFwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJcdTE3ODFcdTE3RDJcdTE3OUZcdTE3QzJcdTE3QTJcdTE3ODBcdTE3RDJcdTE3OUZcdTE3OUEgSlNPTlwiLFxuICAgICAgICBlMTY0OiBcIlx1MTc5Qlx1MTdDMVx1MTc4MSBFLjE2NFwiLFxuICAgICAgICBqd3Q6IFwiSldUXCIsXG4gICAgICAgIHRlbXBsYXRlX2xpdGVyYWw6IFwiXHUxNzkxXHUxN0I3XHUxNzkzXHUxN0QyXHUxNzkzXHUxNzkzXHUxN0QwXHUxNzk5XHUxNzk0XHUxNzg5XHUxN0QyXHUxNzg1XHUxN0JDXHUxNzlCXCJcbiAgICB9O1xuICAgIHJldHVybiAoaXNzdWUpPT57XG4gICAgICAgIHN3aXRjaChpc3N1ZS5jb2RlKXtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3R5cGVcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MTc5MVx1MTdCN1x1MTc5M1x1MTdEMlx1MTc5M1x1MTc5M1x1MTdEMFx1MTc5OVx1MTc5NFx1MTc4OVx1MTdEMlx1MTc4NVx1MTdCQ1x1MTc5Qlx1MTc5OFx1MTdCN1x1MTc5M1x1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCOVx1MTc5OFx1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCQ1x1MTc5Q1x1MTdENiBcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QkNcdTE3OUNcdTE3ODBcdTE3QjZcdTE3OUEgJHtpc3N1ZS5leHBlY3RlZH0gXHUxNzk0XHUxN0M5XHUxN0JCXHUxNzkzXHUxN0QyXHUxNzhGXHUxN0MyXHUxNzkxXHUxNzkxXHUxN0JEXHUxNzlCXHUxNzk0XHUxN0I2XHUxNzkzICR7cGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgXHUxNzkxXHUxN0I3XHUxNzkzXHUxN0QyXHUxNzkzXHUxNzkzXHUxN0QwXHUxNzk5XHUxNzk0XHUxNzg5XHUxN0QyXHUxNzg1XHUxN0JDXHUxNzlCXHUxNzk4XHUxN0I3XHUxNzkzXHUxNzhGXHUxN0QyXHUxNzlBXHUxN0I5XHUxNzk4XHUxNzhGXHUxN0QyXHUxNzlBXHUxN0JDXHUxNzlDXHUxN0Q2IFx1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCQ1x1MTc5Q1x1MTc4MFx1MTdCNlx1MTc5QSAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MTc4N1x1MTc5OFx1MTdEMlx1MTc5QVx1MTdCRVx1MTc5Rlx1MTc5OFx1MTdCN1x1MTc5M1x1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCOVx1MTc5OFx1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCQ1x1MTc5Q1x1MTdENiBcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QkNcdTE3OUNcdTE3ODdcdTE3QjZcdTE3OThcdTE3QkRcdTE3OTlcdTE3ODBcdTE3RDJcdTE3OTNcdTE3QkJcdTE3ODRcdTE3ODVcdTE3QzZcdTE3OEVcdTE3QzRcdTE3OTggJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIjw9XCIgOiBcIjxcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgXHUxNzkyXHUxN0M2XHUxNzk2XHUxN0MxXHUxNzgwXHUxN0Q2IFx1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCQ1x1MTc5Q1x1MTc4MFx1MTdCNlx1MTc5QSAke2lzc3VlLm9yaWdpbiA/PyBcIlx1MTc4Rlx1MTc5OFx1MTdEMlx1MTc5Qlx1MTdDM1wifSAke2Fkan0gJHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXQgPz8gXCJcdTE3OTJcdTE3QjZcdTE3OEZcdTE3QkJcIn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MTc5Mlx1MTdDNlx1MTc5Nlx1MTdDMVx1MTc4MFx1MTdENiBcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QkNcdTE3OUNcdTE3ODBcdTE3QjZcdTE3OUEgJHtpc3N1ZS5vcmlnaW4gPz8gXCJcdTE3OEZcdTE3OThcdTE3RDJcdTE3OUJcdTE3QzNcIn0gJHthZGp9ICR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInRvb19zbWFsbFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI+PVwiIDogXCI+XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MTc4Rlx1MTdCQ1x1MTc4NVx1MTc5Nlx1MTdDMVx1MTc4MFx1MTdENiBcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QkNcdTE3OUNcdTE3ODBcdTE3QjZcdTE3OUEgJHtpc3N1ZS5vcmlnaW59ICR7YWRqfSAke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdH1gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUxNzhGXHUxN0JDXHUxNzg1XHUxNzk2XHUxN0MxXHUxNzgwXHUxN0Q2IFx1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCQ1x1MTc5Q1x1MTc4MFx1MTdCNlx1MTc5QSAke2lzc3VlLm9yaWdpbn0gJHthZGp9ICR7aXNzdWUubWluaW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZm9ybWF0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBfaXNzdWUgPSBpc3N1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwic3RhcnRzX3dpdGhcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTE3ODFcdTE3RDJcdTE3OUZcdTE3QzJcdTE3QTJcdTE3ODBcdTE3RDJcdTE3OUZcdTE3OUFcdTE3OThcdTE3QjdcdTE3OTNcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QjlcdTE3OThcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QkNcdTE3OUNcdTE3RDYgXHUxNzhGXHUxN0QyXHUxNzlBXHUxN0JDXHUxNzlDXHUxNzg1XHUxN0I2XHUxNzk0XHUxN0NCXHUxNzk1XHUxN0QyXHUxNzhGXHUxN0JFXHUxNzk4XHUxNzhBXHUxN0M0XHUxNzk5IFwiJHtfaXNzdWUucHJlZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJlbmRzX3dpdGhcIikgcmV0dXJuIGBcdTE3ODFcdTE3RDJcdTE3OUZcdTE3QzJcdTE3QTJcdTE3ODBcdTE3RDJcdTE3OUZcdTE3OUFcdTE3OThcdTE3QjdcdTE3OTNcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QjlcdTE3OThcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QkNcdTE3OUNcdTE3RDYgXHUxNzhGXHUxN0QyXHUxNzlBXHUxN0JDXHUxNzlDXHUxNzk0XHUxNzg5XHUxN0QyXHUxNzg1XHUxNzk0XHUxN0NCXHUxNzhBXHUxN0M0XHUxNzk5IFwiJHtfaXNzdWUuc3VmZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBcdTE3ODFcdTE3RDJcdTE3OUZcdTE3QzJcdTE3QTJcdTE3ODBcdTE3RDJcdTE3OUZcdTE3OUFcdTE3OThcdTE3QjdcdTE3OTNcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QjlcdTE3OThcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QkNcdTE3OUNcdTE3RDYgXHUxNzhGXHUxN0QyXHUxNzlBXHUxN0JDXHUxNzlDXHUxNzk4XHUxN0I2XHUxNzkzIFwiJHtfaXNzdWUuaW5jbHVkZXN9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYFx1MTc4MVx1MTdEMlx1MTc5Rlx1MTdDMlx1MTdBMlx1MTc4MFx1MTdEMlx1MTc5Rlx1MTc5QVx1MTc5OFx1MTdCN1x1MTc5M1x1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCOVx1MTc5OFx1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCQ1x1MTc5Q1x1MTdENiBcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QkNcdTE3OUNcdTE3OEZcdTE3QzJcdTE3OTVcdTE3RDJcdTE3ODJcdTE3QkNcdTE3OTVcdTE3RDJcdTE3ODJcdTE3ODRcdTE3OTNcdTE3QjlcdTE3ODRcdTE3OTFcdTE3OThcdTE3RDJcdTE3OUFcdTE3ODRcdTE3Q0JcdTE3OEFcdTE3QzJcdTE3OUJcdTE3OTRcdTE3QjZcdTE3OTNcdTE3ODBcdTE3QzZcdTE3OEVcdTE3OEZcdTE3Q0IgJHtfaXNzdWUucGF0dGVybn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MTc5OFx1MTdCN1x1MTc5M1x1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCOVx1MTc5OFx1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCQ1x1MTc5Q1x1MTdENiAke05vdW5zW19pc3N1ZS5mb3JtYXRdID8/IGlzc3VlLmZvcm1hdH1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJub3RfbXVsdGlwbGVfb2ZcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MTc5Qlx1MTdDMVx1MTc4MVx1MTc5OFx1MTdCN1x1MTc5M1x1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCOVx1MTc5OFx1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCQ1x1MTc5Q1x1MTdENiBcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QkNcdTE3OUNcdTE3OEZcdTE3QzJcdTE3ODdcdTE3QjZcdTE3OTZcdTE3QTBcdTE3QkJcdTE3ODJcdTE3QkJcdTE3OEVcdTE3OTNcdTE3QzMgJHtpc3N1ZS5kaXZpc29yfWA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MTc5QVx1MTc4MFx1MTc4M1x1MTdCRVx1MTc4OVx1MTc5Rlx1MTdDNFx1MTc5OFx1MTdCN1x1MTc5M1x1MTc5Rlx1MTdEMlx1MTc4Mlx1MTdCNlx1MTc5Qlx1MTdDQlx1MTdENiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIiwgXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MTc5Rlx1MTdDNFx1MTc5OFx1MTdCN1x1MTc5M1x1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCOVx1MTc5OFx1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCQ1x1MTc5Q1x1MTc5M1x1MTdDNVx1MTc4MFx1MTdEMlx1MTc5M1x1MTdCQlx1MTc4NCAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MTc5MVx1MTdCN1x1MTc5M1x1MTdEMlx1MTc5M1x1MTc5M1x1MTdEMFx1MTc5OVx1MTc5OFx1MTdCN1x1MTc5M1x1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCOVx1MTc5OFx1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCQ1x1MTc5Q2A7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9lbGVtZW50XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTE3OTFcdTE3QjdcdTE3OTNcdTE3RDJcdTE3OTNcdTE3OTNcdTE3RDBcdTE3OTlcdTE3OThcdTE3QjdcdTE3OTNcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QjlcdTE3OThcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QkNcdTE3OUNcdTE3OTNcdTE3QzVcdTE3ODBcdTE3RDJcdTE3OTNcdTE3QkJcdTE3ODQgJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTE3OTFcdTE3QjdcdTE3OTNcdTE3RDJcdTE3OTNcdTE3OTNcdTE3RDBcdTE3OTlcdTE3OThcdTE3QjdcdTE3OTNcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QjlcdTE3OThcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QkNcdTE3OUNgO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBsb2NhbGVFcnJvcjogZXJyb3IoKVxuICAgIH07XG59XG4iLCAiaW1wb3J0IGttIGZyb20gXCIuL2ttLmpzXCI7XG4vKiogQGRlcHJlY2F0ZWQgVXNlIGBrbWAgaW5zdGVhZC4gKi8gZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGttKCk7XG59XG4iLCAiaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi4vY29yZS91dGlsLmpzXCI7XG5jb25zdCBlcnJvciA9ICgpPT57XG4gICAgY29uc3QgU2l6YWJsZSA9IHtcbiAgICAgICAgc3RyaW5nOiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1QkIzOFx1Qzc5MFwiLFxuICAgICAgICAgICAgdmVyYjogXCJ0byBoYXZlXCJcbiAgICAgICAgfSxcbiAgICAgICAgZmlsZToge1xuICAgICAgICAgICAgdW5pdDogXCJcdUJDMTRcdUM3NzRcdUQyQjhcIixcbiAgICAgICAgICAgIHZlcmI6IFwidG8gaGF2ZVwiXG4gICAgICAgIH0sXG4gICAgICAgIGFycmF5OiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1QUMxQ1wiLFxuICAgICAgICAgICAgdmVyYjogXCJ0byBoYXZlXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1QUMxQ1wiLFxuICAgICAgICAgICAgdmVyYjogXCJ0byBoYXZlXCJcbiAgICAgICAgfVxuICAgIH07XG4gICAgZnVuY3Rpb24gZ2V0U2l6aW5nKG9yaWdpbikge1xuICAgICAgICByZXR1cm4gU2l6YWJsZVtvcmlnaW5dID8/IG51bGw7XG4gICAgfVxuICAgIGNvbnN0IHBhcnNlZFR5cGUgPSAoZGF0YSk9PntcbiAgICAgICAgY29uc3QgdCA9IHR5cGVvZiBkYXRhO1xuICAgICAgICBzd2l0Y2godCl7XG4gICAgICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gTnVtYmVyLmlzTmFOKGRhdGEpID8gXCJOYU5cIiA6IFwibnVtYmVyXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm9iamVjdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcImFycmF5XCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGEgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm51bGxcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKGRhdGEpICE9PSBPYmplY3QucHJvdG90eXBlICYmIGRhdGEuY29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHQ7XG4gICAgfTtcbiAgICBjb25zdCBOb3VucyA9IHtcbiAgICAgICAgcmVnZXg6IFwiXHVDNzg1XHVCODI1XCIsXG4gICAgICAgIGVtYWlsOiBcIlx1Qzc3NFx1QkE1NFx1Qzc3QyBcdUM4RkNcdUMxOENcIixcbiAgICAgICAgdXJsOiBcIlVSTFwiLFxuICAgICAgICBlbW9qaTogXCJcdUM3NzRcdUJBQThcdUM5QzBcIixcbiAgICAgICAgdXVpZDogXCJVVUlEXCIsXG4gICAgICAgIHV1aWR2NDogXCJVVUlEdjRcIixcbiAgICAgICAgdXVpZHY2OiBcIlVVSUR2NlwiLFxuICAgICAgICBuYW5vaWQ6IFwibmFub2lkXCIsXG4gICAgICAgIGd1aWQ6IFwiR1VJRFwiLFxuICAgICAgICBjdWlkOiBcImN1aWRcIixcbiAgICAgICAgY3VpZDI6IFwiY3VpZDJcIixcbiAgICAgICAgdWxpZDogXCJVTElEXCIsXG4gICAgICAgIHhpZDogXCJYSURcIixcbiAgICAgICAga3N1aWQ6IFwiS1NVSURcIixcbiAgICAgICAgZGF0ZXRpbWU6IFwiSVNPIFx1QjBBMFx1QzlEQ1x1QzJEQ1x1QUMwNFwiLFxuICAgICAgICBkYXRlOiBcIklTTyBcdUIwQTBcdUM5RENcIixcbiAgICAgICAgdGltZTogXCJJU08gXHVDMkRDXHVBQzA0XCIsXG4gICAgICAgIGR1cmF0aW9uOiBcIklTTyBcdUFFMzBcdUFDMDRcIixcbiAgICAgICAgaXB2NDogXCJJUHY0IFx1QzhGQ1x1QzE4Q1wiLFxuICAgICAgICBpcHY2OiBcIklQdjYgXHVDOEZDXHVDMThDXCIsXG4gICAgICAgIGNpZHJ2NDogXCJJUHY0IFx1QkM5NFx1QzcwNFwiLFxuICAgICAgICBjaWRydjY6IFwiSVB2NiBcdUJDOTRcdUM3MDRcIixcbiAgICAgICAgYmFzZTY0OiBcImJhc2U2NCBcdUM3NzhcdUNGNTRcdUI1MjkgXHVCQjM4XHVDNzkwXHVDNUY0XCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJiYXNlNjR1cmwgXHVDNzc4XHVDRjU0XHVCNTI5IFx1QkIzOFx1Qzc5MFx1QzVGNFwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJKU09OIFx1QkIzOFx1Qzc5MFx1QzVGNFwiLFxuICAgICAgICBlMTY0OiBcIkUuMTY0IFx1QkM4OFx1RDYzOFwiLFxuICAgICAgICBqd3Q6IFwiSldUXCIsXG4gICAgICAgIHRlbXBsYXRlX2xpdGVyYWw6IFwiXHVDNzg1XHVCODI1XCJcbiAgICB9O1xuICAgIHJldHVybiAoaXNzdWUpPT57XG4gICAgICAgIHN3aXRjaChpc3N1ZS5jb2RlKXtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3R5cGVcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1Qzc5OFx1QkFCQlx1QjQxQyBcdUM3ODVcdUI4MjU6IFx1QzYwOFx1QzBDMSBcdUQwQzBcdUM3ODVcdUM3NDAgJHtpc3N1ZS5leHBlY3RlZH0sIFx1QkMxQlx1Qzc0MCBcdUQwQzBcdUM3ODVcdUM3NDAgJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX1cdUM3ODVcdUIyQzhcdUIyRTRgO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBcdUM3OThcdUJBQkJcdUI0MUMgXHVDNzg1XHVCODI1OiBcdUFDMTJcdUM3NDAgJHt1dGlsLnN0cmluZ2lmeVByaW1pdGl2ZShpc3N1ZS52YWx1ZXNbMF0pfSBcdUM3NzRcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1Qzc5OFx1QkFCQlx1QjQxQyBcdUM2MzVcdUMxNTg6ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLnZhbHVlcywgXCJcdUI2MTBcdUIyOTQgXCIpfSBcdUM5MTEgXHVENTU4XHVCMDk4XHVDNUVDXHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNGA7XG4gICAgICAgICAgICBjYXNlIFwidG9vX2JpZ1wiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCJcdUM3NzRcdUQ1NThcIiA6IFwiXHVCQkY4XHVCOUNDXCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN1ZmZpeCA9IGFkaiA9PT0gXCJcdUJCRjhcdUI5Q0NcIiA/IFwiXHVDNzc0XHVDNUI0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNFwiIDogXCJcdUM1RUNcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB1bml0ID0gc2l6aW5nPy51bml0ID8/IFwiXHVDNjk0XHVDMThDXCI7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgJHtpc3N1ZS5vcmlnaW4gPz8gXCJcdUFDMTJcIn1cdUM3NzQgXHVCMTA4XHVCQjM0IFx1RDA3RFx1QjJDOFx1QjJFNDogJHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9JHt1bml0fSAke2Fkan0ke3N1ZmZpeH1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYCR7aXNzdWUub3JpZ2luID8/IFwiXHVBQzEyXCJ9XHVDNzc0IFx1QjEwOFx1QkIzNCBcdUQwN0RcdUIyQzhcdUIyRTQ6ICR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke2Fkan0ke3N1ZmZpeH1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJ0b29fc21hbGxcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiXHVDNzc0XHVDMEMxXCIgOiBcIlx1Q0QwOFx1QUNGQ1wiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdWZmaXggPSBhZGogPT09IFwiXHVDNzc0XHVDMEMxXCIgPyBcIlx1Qzc3NFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTRcIiA6IFwiXHVDNUVDXHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5pdCA9IHNpemluZz8udW5pdCA/PyBcIlx1QzY5NFx1QzE4Q1wiO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYCR7aXNzdWUub3JpZ2luID8/IFwiXHVBQzEyXCJ9XHVDNzc0IFx1QjEwOFx1QkIzNCBcdUM3OTFcdUMyQjVcdUIyQzhcdUIyRTQ6ICR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSR7dW5pdH0gJHthZGp9JHtzdWZmaXh9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYCR7aXNzdWUub3JpZ2luID8/IFwiXHVBQzEyXCJ9XHVDNzc0IFx1QjEwOFx1QkIzNCBcdUM3OTFcdUMyQjVcdUIyQzhcdUIyRTQ6ICR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke2Fkan0ke3N1ZmZpeH1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2Zvcm1hdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgX2lzc3VlID0gaXNzdWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInN0YXJ0c193aXRoXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHVDNzk4XHVCQUJCXHVCNDFDIFx1QkIzOFx1Qzc5MFx1QzVGNDogXCIke19pc3N1ZS5wcmVmaXh9XCIoXHVDNzNDKVx1Qjg1QyBcdUMyRENcdUM3OTFcdUQ1NzRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJlbmRzX3dpdGhcIikgcmV0dXJuIGBcdUM3OThcdUJBQkJcdUI0MUMgXHVCQjM4XHVDNzkwXHVDNUY0OiBcIiR7X2lzc3VlLnN1ZmZpeH1cIihcdUM3M0MpXHVCODVDIFx1QjA1RFx1QjA5OFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTRgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJpbmNsdWRlc1wiKSByZXR1cm4gYFx1Qzc5OFx1QkFCQlx1QjQxQyBcdUJCMzhcdUM3OTBcdUM1RjQ6IFwiJHtfaXNzdWUuaW5jbHVkZXN9XCJcdUM3NDQoXHVCOTdDKSBcdUQzRUNcdUQ1NjhcdUQ1NzRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0YDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBcdUM3OThcdUJBQkJcdUI0MUMgXHVCQjM4XHVDNzkwXHVDNUY0OiBcdUM4MTVcdUFERENcdUMyREQgJHtfaXNzdWUucGF0dGVybn0gXHVEMzI4XHVEMTM0XHVBQ0ZDIFx1Qzc3Q1x1Q0U1OFx1RDU3NFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTRgO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1Qzc5OFx1QkFCQlx1QjQxQyAke05vdW5zW19pc3N1ZS5mb3JtYXRdID8/IGlzc3VlLmZvcm1hdH1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJub3RfbXVsdGlwbGVfb2ZcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1Qzc5OFx1QkFCQlx1QjQxQyBcdUMyMkJcdUM3OTA6ICR7aXNzdWUuZGl2aXNvcn1cdUM3NTggXHVCQzMwXHVDMjE4XHVDNUVDXHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNGA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1Qzc3OFx1QzJERFx1RDU2MCBcdUMyMTggXHVDNUM2XHVCMjk0IFx1RDBBNDogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgXCIsIFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfa2V5XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdUM3OThcdUJBQkJcdUI0MUMgXHVEMEE0OiAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1Qzc5OFx1QkFCQlx1QjQxQyBcdUM3ODVcdUI4MjVgO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZWxlbWVudFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHVDNzk4XHVCQUJCXHVCNDFDIFx1QUMxMjogJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdUM3OThcdUJBQkJcdUI0MUMgXHVDNzg1XHVCODI1YDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuZXhwb3J0IGNvbnN0IHBhcnNlZFR5cGUgPSAoZGF0YSk9PntcbiAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgcmV0dXJuIHBhcnNlZFR5cGVGcm9tVHlwZSh0LCBkYXRhKTtcbn07XG5jb25zdCBwYXJzZWRUeXBlRnJvbVR5cGUgPSAodCwgZGF0YSA9IHVuZGVmaW5lZCk9PntcbiAgICBzd2l0Y2godCl7XG4gICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gTnVtYmVyLmlzTmFOKGRhdGEpID8gXCJOYU5cIiA6IFwic2thaVx1MDEwRGl1c1wiO1xuICAgICAgICAgICAgfVxuICAgICAgICBjYXNlIFwiYmlnaW50XCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwic3ZlaWthc2lzIHNrYWlcdTAxMERpdXNcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgY2FzZSBcInN0cmluZ1wiOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHJldHVybiBcImVpbHV0XHUwMTE3XCI7XG4gICAgICAgICAgICB9XG4gICAgICAgIGNhc2UgXCJib29sZWFuXCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwibG9naW5cdTAxMTcgcmVpa1x1MDE2MW1cdTAxMTdcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgY2FzZSBcInVuZGVmaW5lZFwiOlxuICAgICAgICBjYXNlIFwidm9pZFwiOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHJldHVybiBcIm5lYXBpYnJcdTAxMTdcdTAxN0V0YSByZWlrXHUwMTYxbVx1MDExN1wiO1xuICAgICAgICAgICAgfVxuICAgICAgICBjYXNlIFwiZnVuY3Rpb25cIjpcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJmdW5rY2lqYVwiO1xuICAgICAgICAgICAgfVxuICAgICAgICBjYXNlIFwic3ltYm9sXCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwic2ltYm9saXNcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgY2FzZSBcIm9iamVjdFwiOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSB1bmRlZmluZWQpIHJldHVybiBcIm5lXHUwMTdFaW5vbWFzIG9iamVrdGFzXCI7XG4gICAgICAgICAgICAgICAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiBcIm51bGluXHUwMTE3IHJlaWtcdTAxNjFtXHUwMTE3XCI7XG4gICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHJldHVybiBcIm1hc3l2YXNcIjtcbiAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKGRhdGEpICE9PSBPYmplY3QucHJvdG90eXBlICYmIGRhdGEuY29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwib2JqZWt0YXNcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgLy9ab2QgdHlwZXMgYmVsb3dcbiAgICAgICAgY2FzZSBcIm51bGxcIjpcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJudWxpblx1MDExNyByZWlrXHUwMTYxbVx1MDExN1wiO1xuICAgICAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdDtcbn07XG5jb25zdCBjYXBpdGFsaXplRmlyc3RDaGFyYWN0ZXIgPSAodGV4dCk9PntcbiAgICByZXR1cm4gdGV4dC5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHRleHQuc2xpY2UoMSk7XG59O1xuZnVuY3Rpb24gZ2V0VW5pdFR5cGVGcm9tTnVtYmVyKG51bWJlcikge1xuICAgIGNvbnN0IGFicyA9IE1hdGguYWJzKG51bWJlcik7XG4gICAgY29uc3QgbGFzdCA9IGFicyAlIDEwO1xuICAgIGNvbnN0IGxhc3QyID0gYWJzICUgMTAwO1xuICAgIGlmIChsYXN0MiA+PSAxMSAmJiBsYXN0MiA8PSAxOSB8fCBsYXN0ID09PSAwKSByZXR1cm4gXCJtYW55XCI7XG4gICAgaWYgKGxhc3QgPT09IDEpIHJldHVybiBcIm9uZVwiO1xuICAgIHJldHVybiBcImZld1wiO1xufVxuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDoge1xuICAgICAgICAgICAgICAgIG9uZTogXCJzaW1ib2xpc1wiLFxuICAgICAgICAgICAgICAgIGZldzogXCJzaW1ib2xpYWlcIixcbiAgICAgICAgICAgICAgICBtYW55OiBcInNpbWJvbGlcdTAxNzNcIlxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHZlcmI6IHtcbiAgICAgICAgICAgICAgICBzbWFsbGVyOiB7XG4gICAgICAgICAgICAgICAgICAgIGluY2x1c2l2ZTogXCJ0dXJpIGJcdTAxNkJ0aSBuZSBpbGdlc25cdTAxMTcga2FpcFwiLFxuICAgICAgICAgICAgICAgICAgICBub3RJbmNsdXNpdmU6IFwidHVyaSBiXHUwMTZCdGkgdHJ1bXBlc25cdTAxMTcga2FpcFwiXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBiaWdnZXI6IHtcbiAgICAgICAgICAgICAgICAgICAgaW5jbHVzaXZlOiBcInR1cmkgYlx1MDE2QnRpIG5lIHRydW1wZXNuXHUwMTE3IGthaXBcIixcbiAgICAgICAgICAgICAgICAgICAgbm90SW5jbHVzaXZlOiBcInR1cmkgYlx1MDE2QnRpIGlsZ2Vzblx1MDExNyBrYWlwXCJcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IHtcbiAgICAgICAgICAgICAgICBvbmU6IFwiYmFpdGFzXCIsXG4gICAgICAgICAgICAgICAgZmV3OiBcImJhaXRhaVwiLFxuICAgICAgICAgICAgICAgIG1hbnk6IFwiYmFpdFx1MDE3M1wiXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdmVyYjoge1xuICAgICAgICAgICAgICAgIHNtYWxsZXI6IHtcbiAgICAgICAgICAgICAgICAgICAgaW5jbHVzaXZlOiBcInR1cmkgYlx1MDE2QnRpIG5lIGRpZGVzbmlzIGthaXBcIixcbiAgICAgICAgICAgICAgICAgICAgbm90SW5jbHVzaXZlOiBcInR1cmkgYlx1MDE2QnRpIG1hXHUwMTdFZXNuaXMga2FpcFwiXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBiaWdnZXI6IHtcbiAgICAgICAgICAgICAgICAgICAgaW5jbHVzaXZlOiBcInR1cmkgYlx1MDE2QnRpIG5lIG1hXHUwMTdFZXNuaXMga2FpcFwiLFxuICAgICAgICAgICAgICAgICAgICBub3RJbmNsdXNpdmU6IFwidHVyaSBiXHUwMTZCdGkgZGlkZXNuaXMga2FpcFwiXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDoge1xuICAgICAgICAgICAgICAgIG9uZTogXCJlbGVtZW50XHUwMTA1XCIsXG4gICAgICAgICAgICAgICAgZmV3OiBcImVsZW1lbnR1c1wiLFxuICAgICAgICAgICAgICAgIG1hbnk6IFwiZWxlbWVudFx1MDE3M1wiXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdmVyYjoge1xuICAgICAgICAgICAgICAgIHNtYWxsZXI6IHtcbiAgICAgICAgICAgICAgICAgICAgaW5jbHVzaXZlOiBcInR1cmkgdHVyXHUwMTE3dGkgbmUgZGF1Z2lhdSBrYWlwXCIsXG4gICAgICAgICAgICAgICAgICAgIG5vdEluY2x1c2l2ZTogXCJ0dXJpIHR1clx1MDExN3RpIG1hXHUwMTdFaWF1IGthaXBcIlxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgYmlnZ2VyOiB7XG4gICAgICAgICAgICAgICAgICAgIGluY2x1c2l2ZTogXCJ0dXJpIHR1clx1MDExN3RpIG5lIG1hXHUwMTdFaWF1IGthaXBcIixcbiAgICAgICAgICAgICAgICAgICAgbm90SW5jbHVzaXZlOiBcInR1cmkgdHVyXHUwMTE3dGkgZGF1Z2lhdSBrYWlwXCJcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDoge1xuICAgICAgICAgICAgICAgIG9uZTogXCJlbGVtZW50XHUwMTA1XCIsXG4gICAgICAgICAgICAgICAgZmV3OiBcImVsZW1lbnR1c1wiLFxuICAgICAgICAgICAgICAgIG1hbnk6IFwiZWxlbWVudFx1MDE3M1wiXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdmVyYjoge1xuICAgICAgICAgICAgICAgIHNtYWxsZXI6IHtcbiAgICAgICAgICAgICAgICAgICAgaW5jbHVzaXZlOiBcInR1cmkgdHVyXHUwMTE3dGkgbmUgZGF1Z2lhdSBrYWlwXCIsXG4gICAgICAgICAgICAgICAgICAgIG5vdEluY2x1c2l2ZTogXCJ0dXJpIHR1clx1MDExN3RpIG1hXHUwMTdFaWF1IGthaXBcIlxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgYmlnZ2VyOiB7XG4gICAgICAgICAgICAgICAgICAgIGluY2x1c2l2ZTogXCJ0dXJpIHR1clx1MDExN3RpIG5lIG1hXHUwMTdFaWF1IGthaXBcIixcbiAgICAgICAgICAgICAgICAgICAgbm90SW5jbHVzaXZlOiBcInR1cmkgdHVyXHUwMTE3dGkgZGF1Z2lhdSBrYWlwXCJcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4sIHVuaXRUeXBlLCBpbmNsdXNpdmUsIHRhcmdldFNob3VsZEJlKSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgICAgICBpZiAocmVzdWx0ID09PSBudWxsKSByZXR1cm4gcmVzdWx0O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdW5pdDogcmVzdWx0LnVuaXRbdW5pdFR5cGVdLFxuICAgICAgICAgICAgdmVyYjogcmVzdWx0LnZlcmJbdGFyZ2V0U2hvdWxkQmVdW2luY2x1c2l2ZSA/IFwiaW5jbHVzaXZlXCIgOiBcIm5vdEluY2x1c2l2ZVwiXVxuICAgICAgICB9O1xuICAgIH1cbiAgICBjb25zdCBOb3VucyA9IHtcbiAgICAgICAgcmVnZXg6IFwiXHUwMTJGdmVzdGlzXCIsXG4gICAgICAgIGVtYWlsOiBcImVsLiBwYVx1MDE2MXRvIGFkcmVzYXNcIixcbiAgICAgICAgdXJsOiBcIlVSTFwiLFxuICAgICAgICBlbW9qaTogXCJqYXVzdHVrYXNcIixcbiAgICAgICAgdXVpZDogXCJVVUlEXCIsXG4gICAgICAgIHV1aWR2NDogXCJVVUlEdjRcIixcbiAgICAgICAgdXVpZHY2OiBcIlVVSUR2NlwiLFxuICAgICAgICBuYW5vaWQ6IFwibmFub2lkXCIsXG4gICAgICAgIGd1aWQ6IFwiR1VJRFwiLFxuICAgICAgICBjdWlkOiBcImN1aWRcIixcbiAgICAgICAgY3VpZDI6IFwiY3VpZDJcIixcbiAgICAgICAgdWxpZDogXCJVTElEXCIsXG4gICAgICAgIHhpZDogXCJYSURcIixcbiAgICAgICAga3N1aWQ6IFwiS1NVSURcIixcbiAgICAgICAgZGF0ZXRpbWU6IFwiSVNPIGRhdGEgaXIgbGFpa2FzXCIsXG4gICAgICAgIGRhdGU6IFwiSVNPIGRhdGFcIixcbiAgICAgICAgdGltZTogXCJJU08gbGFpa2FzXCIsXG4gICAgICAgIGR1cmF0aW9uOiBcIklTTyB0cnVrbVx1MDExN1wiLFxuICAgICAgICBpcHY0OiBcIklQdjQgYWRyZXNhc1wiLFxuICAgICAgICBpcHY2OiBcIklQdjYgYWRyZXNhc1wiLFxuICAgICAgICBjaWRydjQ6IFwiSVB2NCB0aW5rbG8gcHJlZmlrc2FzIChDSURSKVwiLFxuICAgICAgICBjaWRydjY6IFwiSVB2NiB0aW5rbG8gcHJlZmlrc2FzIChDSURSKVwiLFxuICAgICAgICBiYXNlNjQ6IFwiYmFzZTY0IHVcdTAxN0Vrb2R1b3RhIGVpbHV0XHUwMTE3XCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJiYXNlNjR1cmwgdVx1MDE3RWtvZHVvdGEgZWlsdXRcdTAxMTdcIixcbiAgICAgICAganNvbl9zdHJpbmc6IFwiSlNPTiBlaWx1dFx1MDExN1wiLFxuICAgICAgICBlMTY0OiBcIkUuMTY0IG51bWVyaXNcIixcbiAgICAgICAgand0OiBcIkpXVFwiLFxuICAgICAgICB0ZW1wbGF0ZV9saXRlcmFsOiBcIlx1MDEyRnZlc3Rpc1wiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBHYXV0YXMgdGlwYXMgJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX0sIG8gdGlrXHUwMTE3dGFzaSAtICR7cGFyc2VkVHlwZUZyb21UeXBlKGlzc3VlLmV4cGVjdGVkKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBQcml2YWxvIGJcdTAxNkJ0aSAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYFByaXZhbG8gYlx1MDE2QnRpIHZpZW5hcyBpXHUwMTYxICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLnZhbHVlcywgXCJ8XCIpfSBwYXNpcmlua2ltXHUwMTczYDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBvcmlnaW4gPSBwYXJzZWRUeXBlRnJvbVR5cGUoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbiwgZ2V0VW5pdFR5cGVGcm9tTnVtYmVyKE51bWJlcihpc3N1ZS5tYXhpbXVtKSksIGlzc3VlLmluY2x1c2l2ZSA/PyBmYWxzZSwgXCJzbWFsbGVyXCIpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nPy52ZXJiKSByZXR1cm4gYCR7Y2FwaXRhbGl6ZUZpcnN0Q2hhcmFjdGVyKG9yaWdpbiA/PyBpc3N1ZS5vcmlnaW4gPz8gXCJyZWlrXHUwMTYxbVx1MDExN1wiKX0gJHtzaXppbmcudmVyYn0gJHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXQgPz8gXCJlbGVtZW50XHUwMTczXCJ9YDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCJuZSBkaWRlc25pcyBrYWlwXCIgOiBcIm1hXHUwMTdFZXNuaXMga2FpcFwiO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYCR7Y2FwaXRhbGl6ZUZpcnN0Q2hhcmFjdGVyKG9yaWdpbiA/PyBpc3N1ZS5vcmlnaW4gPz8gXCJyZWlrXHUwMTYxbVx1MDExN1wiKX0gdHVyaSBiXHUwMTZCdGkgJHthZGp9ICR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke3NpemluZz8udW5pdH1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJ0b29fc21hbGxcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG9yaWdpbiA9IHBhcnNlZFR5cGVGcm9tVHlwZShpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luLCBnZXRVbml0VHlwZUZyb21OdW1iZXIoTnVtYmVyKGlzc3VlLm1pbmltdW0pKSwgaXNzdWUuaW5jbHVzaXZlID8/IGZhbHNlLCBcImJpZ2dlclwiKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZz8udmVyYikgcmV0dXJuIGAke2NhcGl0YWxpemVGaXJzdENoYXJhY3RlcihvcmlnaW4gPz8gaXNzdWUub3JpZ2luID8/IFwicmVpa1x1MDE2MW1cdTAxMTdcIil9ICR7c2l6aW5nLnZlcmJ9ICR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0ID8/IFwiZWxlbWVudFx1MDE3M1wifWA7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwibmUgbWFcdTAxN0Vlc25pcyBrYWlwXCIgOiBcImRpZGVzbmlzIGthaXBcIjtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGAke2NhcGl0YWxpemVGaXJzdENoYXJhY3RlcihvcmlnaW4gPz8gaXNzdWUub3JpZ2luID8/IFwicmVpa1x1MDE2MW1cdTAxMTdcIil9IHR1cmkgYlx1MDE2QnRpICR7YWRqfSAke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gJHtzaXppbmc/LnVuaXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYEVpbHV0XHUwMTE3IHByaXZhbG8gcHJhc2lkXHUwMTE3dGkgXCIke19pc3N1ZS5wcmVmaXh9XCJgO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYEVpbHV0XHUwMTE3IHByaXZhbG8gcGFzaWJhaWd0aSBcIiR7X2lzc3VlLnN1ZmZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImluY2x1ZGVzXCIpIHJldHVybiBgRWlsdXRcdTAxMTcgcHJpdmFsbyBcdTAxMkZ0cmF1a3RpIFwiJHtfaXNzdWUuaW5jbHVkZXN9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYEVpbHV0XHUwMTE3IHByaXZhbG8gYXRpdGlrdGkgJHtfaXNzdWUucGF0dGVybn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYE5ldGVpc2luZ2FzICR7Tm91bnNbX2lzc3VlLmZvcm1hdF0gPz8gaXNzdWUuZm9ybWF0fWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm5vdF9tdWx0aXBsZV9vZlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgU2thaVx1MDEwRGl1cyBwcml2YWxvIGJcdTAxNkJ0aSAke2lzc3VlLmRpdmlzb3J9IGthcnRvdGluaXMuYDtcbiAgICAgICAgICAgIGNhc2UgXCJ1bnJlY29nbml6ZWRfa2V5c1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgTmVhdHBhXHUwMTdFaW50JHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcImlcIiA6IFwiYXNcIn0gcmFrdCR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJhaVwiIDogXCJhc1wifTogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgXCIsIFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfa2V5XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiUmFzdGFzIGtsYWlkaW5nYXMgcmFrdGFzXCI7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF91bmlvblwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIktsYWlkaW5nYSBcdTAxMkZ2ZXN0aXNcIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG9yaWdpbiA9IHBhcnNlZFR5cGVGcm9tVHlwZShpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYCR7Y2FwaXRhbGl6ZUZpcnN0Q2hhcmFjdGVyKG9yaWdpbiA/PyBpc3N1ZS5vcmlnaW4gPz8gXCJyZWlrXHUwMTYxbVx1MDExN1wiKX0gdHVyaSBrbGFpZGluZ1x1MDEwNSBcdTAxMkZ2ZXN0XHUwMTJGYDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBcIktsYWlkaW5nYSBcdTAxMkZ2ZXN0aXNcIjtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJcdTA0MzdcdTA0M0RcdTA0MzBcdTA0NDZcdTA0MzhcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwNDM0XHUwNDMwIFx1MDQzOFx1MDQzQ1x1MDQzMFx1MDQzMFx1MDQ0MlwiXG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHUwNDMxXHUwNDMwXHUwNDU4XHUwNDQyXHUwNDM4XCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MDQzNFx1MDQzMCBcdTA0MzhcdTA0M0NcdTA0MzBcdTA0MzBcdTA0NDJcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJcdTA0NDFcdTA0NDJcdTA0MzBcdTA0MzJcdTA0M0FcdTA0MzhcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwNDM0XHUwNDMwIFx1MDQzOFx1MDQzQ1x1MDQzMFx1MDQzMFx1MDQ0MlwiXG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDogXCJcdTA0NDFcdTA0NDJcdTA0MzBcdTA0MzJcdTA0M0FcdTA0MzhcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwNDM0XHUwNDMwIFx1MDQzOFx1MDQzQ1x1MDQzMFx1MDQzMFx1MDQ0MlwiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4pIHtcbiAgICAgICAgcmV0dXJuIFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWRUeXBlID0gKGRhdGEpPT57XG4gICAgICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICAgICAgc3dpdGNoKHQpe1xuICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIlx1MDQzMVx1MDQ0MFx1MDQzRVx1MDQ1OFwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTA0M0RcdTA0MzhcdTA0MzdcdTA0MzBcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YoZGF0YSkgIT09IE9iamVjdC5wcm90b3R5cGUgJiYgZGF0YS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdDtcbiAgICB9O1xuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJcdTA0MzJcdTA0M0RcdTA0MzVcdTA0NDFcIixcbiAgICAgICAgZW1haWw6IFwiXHUwNDMwXHUwNDM0XHUwNDQwXHUwNDM1XHUwNDQxXHUwNDMwIFx1MDQzRFx1MDQzMCBcdTA0MzUtXHUwNDNGXHUwNDNFXHUwNDQ4XHUwNDQyXHUwNDMwXCIsXG4gICAgICAgIHVybDogXCJVUkxcIixcbiAgICAgICAgZW1vamk6IFwiXHUwNDM1XHUwNDNDXHUwNDNFXHUwNDVGXHUwNDM4XCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcIklTTyBcdTA0MzRcdTA0MzBcdTA0NDJcdTA0NDNcdTA0M0MgXHUwNDM4IFx1MDQzMlx1MDQ0MFx1MDQzNVx1MDQzQ1x1MDQzNVwiLFxuICAgICAgICBkYXRlOiBcIklTTyBcdTA0MzRcdTA0MzBcdTA0NDJcdTA0NDNcdTA0M0NcIixcbiAgICAgICAgdGltZTogXCJJU08gXHUwNDMyXHUwNDQwXHUwNDM1XHUwNDNDXHUwNDM1XCIsXG4gICAgICAgIGR1cmF0aW9uOiBcIklTTyBcdTA0MzJcdTA0NDBcdTA0MzVcdTA0M0NcdTA0MzVcdTA0NDJcdTA0NDBcdTA0MzBcdTA0MzVcdTA0NUFcdTA0MzVcIixcbiAgICAgICAgaXB2NDogXCJJUHY0IFx1MDQzMFx1MDQzNFx1MDQ0MFx1MDQzNVx1MDQ0MVx1MDQzMFwiLFxuICAgICAgICBpcHY2OiBcIklQdjYgXHUwNDMwXHUwNDM0XHUwNDQwXHUwNDM1XHUwNDQxXHUwNDMwXCIsXG4gICAgICAgIGNpZHJ2NDogXCJJUHY0IFx1MDQzRVx1MDQzRlx1MDQ0MVx1MDQzNVx1MDQzM1wiLFxuICAgICAgICBjaWRydjY6IFwiSVB2NiBcdTA0M0VcdTA0M0ZcdTA0NDFcdTA0MzVcdTA0MzNcIixcbiAgICAgICAgYmFzZTY0OiBcImJhc2U2NC1cdTA0MzVcdTA0M0RcdTA0M0FcdTA0M0VcdTA0MzRcdTA0MzhcdTA0NDBcdTA0MzBcdTA0M0RcdTA0MzAgXHUwNDNEXHUwNDM4XHUwNDM3XHUwNDMwXCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJiYXNlNjR1cmwtXHUwNDM1XHUwNDNEXHUwNDNBXHUwNDNFXHUwNDM0XHUwNDM4XHUwNDQwXHUwNDMwXHUwNDNEXHUwNDMwIFx1MDQzRFx1MDQzOFx1MDQzN1x1MDQzMFwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJKU09OIFx1MDQzRFx1MDQzOFx1MDQzN1x1MDQzMFwiLFxuICAgICAgICBlMTY0OiBcIkUuMTY0IFx1MDQzMVx1MDQ0MFx1MDQzRVx1MDQ1OFwiLFxuICAgICAgICBqd3Q6IFwiSldUXCIsXG4gICAgICAgIHRlbXBsYXRlX2xpdGVyYWw6IFwiXHUwNDMyXHUwNDNEXHUwNDM1XHUwNDQxXCJcbiAgICB9O1xuICAgIHJldHVybiAoaXNzdWUpPT57XG4gICAgICAgIHN3aXRjaChpc3N1ZS5jb2RlKXtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3R5cGVcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDQxM1x1MDQ0MFx1MDQzNVx1MDQ0OFx1MDQzNVx1MDQzRCBcdTA0MzJcdTA0M0RcdTA0MzVcdTA0NDE6IFx1MDQ0MVx1MDQzNSBcdTA0M0VcdTA0NDdcdTA0MzVcdTA0M0FcdTA0NDNcdTA0MzJcdTA0MzAgJHtpc3N1ZS5leHBlY3RlZH0sIFx1MDQzRlx1MDQ0MFx1MDQzOFx1MDQzQ1x1MDQzNVx1MDQzRFx1MDQzRSAke3BhcnNlZFR5cGUoaXNzdWUuaW5wdXQpfWA7XG4gICAgICAgICAgICAvLyByZXR1cm4gYEludmFsaWQgaW5wdXQ6IGV4cGVjdGVkICR7aXNzdWUuZXhwZWN0ZWR9LCByZWNlaXZlZCAke3V0aWwuZ2V0UGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgSW52YWxpZCBpbnB1dDogZXhwZWN0ZWQgJHt1dGlsLnN0cmluZ2lmeVByaW1pdGl2ZShpc3N1ZS52YWx1ZXNbMF0pfWA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MTNcdTA0NDBcdTA0MzVcdTA0NDhcdTA0MzBcdTA0M0RcdTA0MzAgXHUwNDNFXHUwNDNGXHUwNDQ2XHUwNDM4XHUwNDU4XHUwNDMwOiBcdTA0NDFcdTA0MzUgXHUwNDNFXHUwNDQ3XHUwNDM1XHUwNDNBXHUwNDQzXHUwNDMyXHUwNDMwIFx1MDQzNVx1MDQzNFx1MDQzRFx1MDQzMCAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS52YWx1ZXMsIFwifFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPD1cIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykgcmV0dXJuIGBcdTA0MUZcdTA0NDBcdTA0MzVcdTA0M0NcdTA0M0RcdTA0M0VcdTA0MzNcdTA0NDMgXHUwNDMzXHUwNDNFXHUwNDNCXHUwNDM1XHUwNDNDOiBcdTA0NDFcdTA0MzUgXHUwNDNFXHUwNDQ3XHUwNDM1XHUwNDNBXHUwNDQzXHUwNDMyXHUwNDMwICR7aXNzdWUub3JpZ2luID8/IFwiXHUwNDMyXHUwNDQwXHUwNDM1XHUwNDM0XHUwNDNEXHUwNDNFXHUwNDQxXHUwNDQyXHUwNDMwXCJ9IFx1MDQzNFx1MDQzMCBcdTA0MzhcdTA0M0NcdTA0MzAgJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXQgPz8gXCJcdTA0MzVcdTA0M0JcdTA0MzVcdTA0M0NcdTA0MzVcdTA0M0RcdTA0NDJcdTA0MzhcIn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDQxRlx1MDQ0MFx1MDQzNVx1MDQzQ1x1MDQzRFx1MDQzRVx1MDQzM1x1MDQ0MyBcdTA0MzNcdTA0M0VcdTA0M0JcdTA0MzVcdTA0M0M6IFx1MDQ0MVx1MDQzNSBcdTA0M0VcdTA0NDdcdTA0MzVcdTA0M0FcdTA0NDNcdTA0MzJcdTA0MzAgJHtpc3N1ZS5vcmlnaW4gPz8gXCJcdTA0MzJcdTA0NDBcdTA0MzVcdTA0MzRcdTA0M0RcdTA0M0VcdTA0NDFcdTA0NDJcdTA0MzBcIn0gXHUwNDM0XHUwNDMwIFx1MDQzMVx1MDQzOFx1MDQzNFx1MDQzNSAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJ0b29fc21hbGxcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPj1cIiA6IFwiPlwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MUZcdTA0NDBcdTA0MzVcdTA0M0NcdTA0M0RcdTA0M0VcdTA0MzNcdTA0NDMgXHUwNDNDXHUwNDMwXHUwNDNCOiBcdTA0NDFcdTA0MzUgXHUwNDNFXHUwNDQ3XHUwNDM1XHUwNDNBXHUwNDQzXHUwNDMyXHUwNDMwICR7aXNzdWUub3JpZ2lufSBcdTA0MzRcdTA0MzAgXHUwNDM4XHUwNDNDXHUwNDMwICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0fWA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MUZcdTA0NDBcdTA0MzVcdTA0M0NcdTA0M0RcdTA0M0VcdTA0MzNcdTA0NDMgXHUwNDNDXHUwNDMwXHUwNDNCOiBcdTA0NDFcdTA0MzUgXHUwNDNFXHUwNDQ3XHUwNDM1XHUwNDNBXHUwNDQzXHUwNDMyXHUwNDMwICR7aXNzdWUub3JpZ2lufSBcdTA0MzRcdTA0MzAgXHUwNDMxXHUwNDM4XHUwNDM0XHUwNDM1ICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZm9ybWF0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBfaXNzdWUgPSBpc3N1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwic3RhcnRzX3dpdGhcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MURcdTA0MzVcdTA0MzJcdTA0MzBcdTA0MzZcdTA0MzVcdTA0NDdcdTA0M0FcdTA0MzAgXHUwNDNEXHUwNDM4XHUwNDM3XHUwNDMwOiBcdTA0M0NcdTA0M0VcdTA0NDBcdTA0MzAgXHUwNDM0XHUwNDMwIFx1MDQzN1x1MDQzMFx1MDQzRlx1MDQzRVx1MDQ0N1x1MDQzRFx1MDQ0M1x1MDQzMlx1MDQzMCBcdTA0NDFcdTA0M0UgXCIke19pc3N1ZS5wcmVmaXh9XCJgO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYFx1MDQxRFx1MDQzNVx1MDQzMlx1MDQzMFx1MDQzNlx1MDQzNVx1MDQ0N1x1MDQzQVx1MDQzMCBcdTA0M0RcdTA0MzhcdTA0MzdcdTA0MzA6IFx1MDQzQ1x1MDQzRVx1MDQ0MFx1MDQzMCBcdTA0MzRcdTA0MzAgXHUwNDM3XHUwNDMwXHUwNDMyXHUwNDQwXHUwNDQ4XHUwNDQzXHUwNDMyXHUwNDMwIFx1MDQ0MVx1MDQzRSBcIiR7X2lzc3VlLnN1ZmZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImluY2x1ZGVzXCIpIHJldHVybiBgXHUwNDFEXHUwNDM1XHUwNDMyXHUwNDMwXHUwNDM2XHUwNDM1XHUwNDQ3XHUwNDNBXHUwNDMwIFx1MDQzRFx1MDQzOFx1MDQzN1x1MDQzMDogXHUwNDNDXHUwNDNFXHUwNDQwXHUwNDMwIFx1MDQzNFx1MDQzMCBcdTA0MzJcdTA0M0FcdTA0M0JcdTA0NDNcdTA0NDdcdTA0NDNcdTA0MzJcdTA0MzAgXCIke19pc3N1ZS5pbmNsdWRlc31cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInJlZ2V4XCIpIHJldHVybiBgXHUwNDFEXHUwNDM1XHUwNDMyXHUwNDMwXHUwNDM2XHUwNDM1XHUwNDQ3XHUwNDNBXHUwNDMwIFx1MDQzRFx1MDQzOFx1MDQzN1x1MDQzMDogXHUwNDNDXHUwNDNFXHUwNDQwXHUwNDMwIFx1MDQzNFx1MDQzMCBcdTA0M0VcdTA0MzRcdTA0MzNcdTA0M0VcdTA0MzBcdTA0NDBcdTA0MzAgXHUwNDNEXHUwNDMwIFx1MDQzRlx1MDQzMFx1MDQ0Mlx1MDQzNVx1MDQ0MFx1MDQzRFx1MDQzRVx1MDQ0MiAke19pc3N1ZS5wYXR0ZXJufWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgSW52YWxpZCAke05vdW5zW19pc3N1ZS5mb3JtYXRdID8/IGlzc3VlLmZvcm1hdH1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJub3RfbXVsdGlwbGVfb2ZcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDQxM1x1MDQ0MFx1MDQzNVx1MDQ0OFx1MDQzNVx1MDQzRCBcdTA0MzFcdTA0NDBcdTA0M0VcdTA0NTg6IFx1MDQzQ1x1MDQzRVx1MDQ0MFx1MDQzMCBcdTA0MzRcdTA0MzAgXHUwNDMxXHUwNDM4XHUwNDM0XHUwNDM1IFx1MDQzNFx1MDQzNVx1MDQzQlx1MDQzOFx1MDQzMiBcdTA0NDFcdTA0M0UgJHtpc3N1ZS5kaXZpc29yfWA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYCR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJcdTA0MURcdTA0MzVcdTA0M0ZcdTA0NDBcdTA0MzVcdTA0M0ZcdTA0M0VcdTA0MzdcdTA0M0RcdTA0MzBcdTA0MzVcdTA0M0RcdTA0MzggXHUwNDNBXHUwNDNCXHUwNDQzXHUwNDQ3XHUwNDM1XHUwNDMyXHUwNDM4XCIgOiBcIlx1MDQxRFx1MDQzNVx1MDQzRlx1MDQ0MFx1MDQzNVx1MDQzRlx1MDQzRVx1MDQzN1x1MDQzRFx1MDQzMFx1MDQzNVx1MDQzRCBcdTA0M0FcdTA0M0JcdTA0NDNcdTA0NDdcIn06ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLmtleXMsIFwiLCBcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2tleVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNDEzXHUwNDQwXHUwNDM1XHUwNDQ4XHUwNDM1XHUwNDNEIFx1MDQzQVx1MDQzQlx1MDQ0M1x1MDQ0NyBcdTA0MzJcdTA0M0UgJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3VuaW9uXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiXHUwNDEzXHUwNDQwXHUwNDM1XHUwNDQ4XHUwNDM1XHUwNDNEIFx1MDQzMlx1MDQzRFx1MDQzNVx1MDQ0MVwiO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZWxlbWVudFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNDEzXHUwNDQwXHUwNDM1XHUwNDQ4XHUwNDNEXHUwNDMwIFx1MDQzMlx1MDQ0MFx1MDQzNVx1MDQzNFx1MDQzRFx1MDQzRVx1MDQ0MVx1MDQ0MiBcdTA0MzJcdTA0M0UgJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MTNcdTA0NDBcdTA0MzVcdTA0NDhcdTA0MzVcdTA0M0QgXHUwNDMyXHUwNDNEXHUwNDM1XHUwNDQxYDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJha3NhcmFcIixcbiAgICAgICAgICAgIHZlcmI6IFwibWVtcHVueWFpXCJcbiAgICAgICAgfSxcbiAgICAgICAgZmlsZToge1xuICAgICAgICAgICAgdW5pdDogXCJiYWl0XCIsXG4gICAgICAgICAgICB2ZXJiOiBcIm1lbXB1bnlhaVwiXG4gICAgICAgIH0sXG4gICAgICAgIGFycmF5OiB7XG4gICAgICAgICAgICB1bml0OiBcImVsZW1lblwiLFxuICAgICAgICAgICAgdmVyYjogXCJtZW1wdW55YWlcIlxuICAgICAgICB9LFxuICAgICAgICBzZXQ6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiZWxlbWVuXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIm1lbXB1bnlhaVwiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4pIHtcbiAgICAgICAgcmV0dXJuIFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWRUeXBlID0gKGRhdGEpPT57XG4gICAgICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICAgICAgc3dpdGNoKHQpe1xuICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIm5vbWJvclwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJhcnJheVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJudWxsXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcImlucHV0XCIsXG4gICAgICAgIGVtYWlsOiBcImFsYW1hdCBlLW1lbFwiLFxuICAgICAgICB1cmw6IFwiVVJMXCIsXG4gICAgICAgIGVtb2ppOiBcImVtb2ppXCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcInRhcmlraCBtYXNhIElTT1wiLFxuICAgICAgICBkYXRlOiBcInRhcmlraCBJU09cIixcbiAgICAgICAgdGltZTogXCJtYXNhIElTT1wiLFxuICAgICAgICBkdXJhdGlvbjogXCJ0ZW1wb2ggSVNPXCIsXG4gICAgICAgIGlwdjQ6IFwiYWxhbWF0IElQdjRcIixcbiAgICAgICAgaXB2NjogXCJhbGFtYXQgSVB2NlwiLFxuICAgICAgICBjaWRydjQ6IFwianVsYXQgSVB2NFwiLFxuICAgICAgICBjaWRydjY6IFwianVsYXQgSVB2NlwiLFxuICAgICAgICBiYXNlNjQ6IFwic3RyaW5nIGRpa29ka2FuIGJhc2U2NFwiLFxuICAgICAgICBiYXNlNjR1cmw6IFwic3RyaW5nIGRpa29ka2FuIGJhc2U2NHVybFwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJzdHJpbmcgSlNPTlwiLFxuICAgICAgICBlMTY0OiBcIm5vbWJvciBFLjE2NFwiLFxuICAgICAgICBqd3Q6IFwiSldUXCIsXG4gICAgICAgIHRlbXBsYXRlX2xpdGVyYWw6IFwiaW5wdXRcIlxuICAgIH07XG4gICAgcmV0dXJuIChpc3N1ZSk9PntcbiAgICAgICAgc3dpdGNoKGlzc3VlLmNvZGUpe1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdHlwZVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgSW5wdXQgdGlkYWsgc2FoOiBkaWphbmdrYSAke2lzc3VlLmV4cGVjdGVkfSwgZGl0ZXJpbWEgJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBJbnB1dCB0aWRhayBzYWg6IGRpamFuZ2thICR7dXRpbC5zdHJpbmdpZnlQcmltaXRpdmUoaXNzdWUudmFsdWVzWzBdKX1gO1xuICAgICAgICAgICAgICAgIHJldHVybiBgUGlsaWhhbiB0aWRhayBzYWg6IGRpamFuZ2thIHNhbGFoIHNhdHUgZGFyaXBhZGEgJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIjw9XCIgOiBcIjxcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgVGVybGFsdSBiZXNhcjogZGlqYW5na2EgJHtpc3N1ZS5vcmlnaW4gPz8gXCJuaWxhaVwifSAke3NpemluZy52ZXJifSAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdCA/PyBcImVsZW1lblwifWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgVGVybGFsdSBiZXNhcjogZGlqYW5na2EgJHtpc3N1ZS5vcmlnaW4gPz8gXCJuaWxhaVwifSBhZGFsYWggJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIj49XCIgOiBcIj5cIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgVGVybGFsdSBrZWNpbDogZGlqYW5na2EgJHtpc3N1ZS5vcmlnaW59ICR7c2l6aW5nLnZlcmJ9ICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0fWA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBUZXJsYWx1IGtlY2lsOiBkaWphbmdrYSAke2lzc3VlLm9yaWdpbn0gYWRhbGFoICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZm9ybWF0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBfaXNzdWUgPSBpc3N1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwic3RhcnRzX3dpdGhcIikgcmV0dXJuIGBTdHJpbmcgdGlkYWsgc2FoOiBtZXN0aSBiZXJtdWxhIGRlbmdhbiBcIiR7X2lzc3VlLnByZWZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYFN0cmluZyB0aWRhayBzYWg6IG1lc3RpIGJlcmFraGlyIGRlbmdhbiBcIiR7X2lzc3VlLnN1ZmZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImluY2x1ZGVzXCIpIHJldHVybiBgU3RyaW5nIHRpZGFrIHNhaDogbWVzdGkgbWVuZ2FuZHVuZ2kgXCIke19pc3N1ZS5pbmNsdWRlc31cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInJlZ2V4XCIpIHJldHVybiBgU3RyaW5nIHRpZGFrIHNhaDogbWVzdGkgc2VwYWRhbiBkZW5nYW4gY29yYWsgJHtfaXNzdWUucGF0dGVybn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYCR7Tm91bnNbX2lzc3VlLmZvcm1hdF0gPz8gaXNzdWUuZm9ybWF0fSB0aWRhayBzYWhgO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJub3RfbXVsdGlwbGVfb2ZcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYE5vbWJvciB0aWRhayBzYWg6IHBlcmx1IGdhbmRhYW4gJHtpc3N1ZS5kaXZpc29yfWA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYEt1bmNpIHRpZGFrIGRpa2VuYWxpOiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIiwgXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYEt1bmNpIHRpZGFrIHNhaCBkYWxhbSAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJJbnB1dCB0aWRhayBzYWhcIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYE5pbGFpIHRpZGFrIHNhaCBkYWxhbSAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gYElucHV0IHRpZGFrIHNhaGA7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGxvY2FsZUVycm9yOiBlcnJvcigpXG4gICAgfTtcbn1cbiIsICJpbXBvcnQgKiBhcyB1dGlsIGZyb20gXCIuLi9jb3JlL3V0aWwuanNcIjtcbmNvbnN0IGVycm9yID0gKCk9PntcbiAgICBjb25zdCBTaXphYmxlID0ge1xuICAgICAgICBzdHJpbmc6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwidGVrZW5zXCJcbiAgICAgICAgfSxcbiAgICAgICAgZmlsZToge1xuICAgICAgICAgICAgdW5pdDogXCJieXRlc1wiXG4gICAgICAgIH0sXG4gICAgICAgIGFycmF5OiB7XG4gICAgICAgICAgICB1bml0OiBcImVsZW1lbnRlblwiXG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDogXCJlbGVtZW50ZW5cIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIk5hTlwiIDogXCJnZXRhbFwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJhcnJheVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJudWxsXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcImludm9lclwiLFxuICAgICAgICBlbWFpbDogXCJlbWFpbGFkcmVzXCIsXG4gICAgICAgIHVybDogXCJVUkxcIixcbiAgICAgICAgZW1vamk6IFwiZW1vamlcIixcbiAgICAgICAgdXVpZDogXCJVVUlEXCIsXG4gICAgICAgIHV1aWR2NDogXCJVVUlEdjRcIixcbiAgICAgICAgdXVpZHY2OiBcIlVVSUR2NlwiLFxuICAgICAgICBuYW5vaWQ6IFwibmFub2lkXCIsXG4gICAgICAgIGd1aWQ6IFwiR1VJRFwiLFxuICAgICAgICBjdWlkOiBcImN1aWRcIixcbiAgICAgICAgY3VpZDI6IFwiY3VpZDJcIixcbiAgICAgICAgdWxpZDogXCJVTElEXCIsXG4gICAgICAgIHhpZDogXCJYSURcIixcbiAgICAgICAga3N1aWQ6IFwiS1NVSURcIixcbiAgICAgICAgZGF0ZXRpbWU6IFwiSVNPIGRhdHVtIGVuIHRpamRcIixcbiAgICAgICAgZGF0ZTogXCJJU08gZGF0dW1cIixcbiAgICAgICAgdGltZTogXCJJU08gdGlqZFwiLFxuICAgICAgICBkdXJhdGlvbjogXCJJU08gZHV1clwiLFxuICAgICAgICBpcHY0OiBcIklQdjQtYWRyZXNcIixcbiAgICAgICAgaXB2NjogXCJJUHY2LWFkcmVzXCIsXG4gICAgICAgIGNpZHJ2NDogXCJJUHY0LWJlcmVpa1wiLFxuICAgICAgICBjaWRydjY6IFwiSVB2Ni1iZXJlaWtcIixcbiAgICAgICAgYmFzZTY0OiBcImJhc2U2NC1nZWNvZGVlcmRlIHRla3N0XCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJiYXNlNjQgVVJMLWdlY29kZWVyZGUgdGVrc3RcIixcbiAgICAgICAganNvbl9zdHJpbmc6IFwiSlNPTiBzdHJpbmdcIixcbiAgICAgICAgZTE2NDogXCJFLjE2NC1udW1tZXJcIixcbiAgICAgICAgand0OiBcIkpXVFwiLFxuICAgICAgICB0ZW1wbGF0ZV9saXRlcmFsOiBcImludm9lclwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBPbmdlbGRpZ2UgaW52b2VyOiB2ZXJ3YWNodCAke2lzc3VlLmV4cGVjdGVkfSwgb250dmluZyAke3BhcnNlZFR5cGUoaXNzdWUuaW5wdXQpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF92YWx1ZVwiOlxuICAgICAgICAgICAgICAgIGlmIChpc3N1ZS52YWx1ZXMubGVuZ3RoID09PSAxKSByZXR1cm4gYE9uZ2VsZGlnZSBpbnZvZXI6IHZlcndhY2h0ICR7dXRpbC5zdHJpbmdpZnlQcmltaXRpdmUoaXNzdWUudmFsdWVzWzBdKX1gO1xuICAgICAgICAgICAgICAgIHJldHVybiBgT25nZWxkaWdlIG9wdGllOiB2ZXJ3YWNodCBcdTAwRTlcdTAwRTluIHZhbiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS52YWx1ZXMsIFwifFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPD1cIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykgcmV0dXJuIGBUZSBsYW5nOiB2ZXJ3YWNodCBkYXQgJHtpc3N1ZS5vcmlnaW4gPz8gXCJ3YWFyZGVcIn0gJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXQgPz8gXCJlbGVtZW50ZW5cIn0gYmV2YXRgO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFRlIGxhbmc6IHZlcndhY2h0IGRhdCAke2lzc3VlLm9yaWdpbiA/PyBcIndhYXJkZVwifSAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX0gaXNgO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJ0b29fc21hbGxcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPj1cIiA6IFwiPlwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBUZSBrb3J0OiB2ZXJ3YWNodCBkYXQgJHtpc3N1ZS5vcmlnaW59ICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0fSBiZXZhdGA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBUZSBrb3J0OiB2ZXJ3YWNodCBkYXQgJHtpc3N1ZS5vcmlnaW59ICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSBpc2A7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZm9ybWF0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBfaXNzdWUgPSBpc3N1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwic3RhcnRzX3dpdGhcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBPbmdlbGRpZ2UgdGVrc3Q6IG1vZXQgbWV0IFwiJHtfaXNzdWUucHJlZml4fVwiIGJlZ2lubmVuYDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJlbmRzX3dpdGhcIikgcmV0dXJuIGBPbmdlbGRpZ2UgdGVrc3Q6IG1vZXQgb3AgXCIke19pc3N1ZS5zdWZmaXh9XCIgZWluZGlnZW5gO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJpbmNsdWRlc1wiKSByZXR1cm4gYE9uZ2VsZGlnZSB0ZWtzdDogbW9ldCBcIiR7X2lzc3VlLmluY2x1ZGVzfVwiIGJldmF0dGVuYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBPbmdlbGRpZ2UgdGVrc3Q6IG1vZXQgb3ZlcmVlbmtvbWVuIG1ldCBwYXRyb29uICR7X2lzc3VlLnBhdHRlcm59YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBPbmdlbGRpZzogJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBPbmdlbGRpZyBnZXRhbDogbW9ldCBlZW4gdmVlbHZvdWQgdmFuICR7aXNzdWUuZGl2aXNvcn0gemlqbmA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYE9uYmVrZW5kZSBrZXkke2lzc3VlLmtleXMubGVuZ3RoID4gMSA/IFwic1wiIDogXCJcIn06ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLmtleXMsIFwiLCBcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2tleVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgT25nZWxkaWdlIGtleSBpbiAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJPbmdlbGRpZ2UgaW52b2VyXCI7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9lbGVtZW50XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBPbmdlbGRpZ2Ugd2FhcmRlIGluICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBgT25nZWxkaWdlIGludm9lcmA7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGxvY2FsZUVycm9yOiBlcnJvcigpXG4gICAgfTtcbn1cbiIsICJpbXBvcnQgKiBhcyB1dGlsIGZyb20gXCIuLi9jb3JlL3V0aWwuanNcIjtcbmNvbnN0IGVycm9yID0gKCk9PntcbiAgICBjb25zdCBTaXphYmxlID0ge1xuICAgICAgICBzdHJpbmc6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwidGVnblwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTAwRTUgaGFcIlxuICAgICAgICB9LFxuICAgICAgICBmaWxlOiB7XG4gICAgICAgICAgICB1bml0OiBcImJ5dGVzXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MDBFNSBoYVwiXG4gICAgICAgIH0sXG4gICAgICAgIGFycmF5OiB7XG4gICAgICAgICAgICB1bml0OiBcImVsZW1lbnRlclwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTAwRTUgaW5uZWhvbGRlXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcImVsZW1lbnRlclwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTAwRTUgaW5uZWhvbGRlXCJcbiAgICAgICAgfVxuICAgIH07XG4gICAgZnVuY3Rpb24gZ2V0U2l6aW5nKG9yaWdpbikge1xuICAgICAgICByZXR1cm4gU2l6YWJsZVtvcmlnaW5dID8/IG51bGw7XG4gICAgfVxuICAgIGNvbnN0IHBhcnNlZFR5cGUgPSAoZGF0YSk9PntcbiAgICAgICAgY29uc3QgdCA9IHR5cGVvZiBkYXRhO1xuICAgICAgICBzd2l0Y2godCl7XG4gICAgICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gTnVtYmVyLmlzTmFOKGRhdGEpID8gXCJOYU5cIiA6IFwidGFsbFwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJsaXN0ZVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJudWxsXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcImlucHV0XCIsXG4gICAgICAgIGVtYWlsOiBcImUtcG9zdGFkcmVzc2VcIixcbiAgICAgICAgdXJsOiBcIlVSTFwiLFxuICAgICAgICBlbW9qaTogXCJlbW9qaVwiLFxuICAgICAgICB1dWlkOiBcIlVVSURcIixcbiAgICAgICAgdXVpZHY0OiBcIlVVSUR2NFwiLFxuICAgICAgICB1dWlkdjY6IFwiVVVJRHY2XCIsXG4gICAgICAgIG5hbm9pZDogXCJuYW5vaWRcIixcbiAgICAgICAgZ3VpZDogXCJHVUlEXCIsXG4gICAgICAgIGN1aWQ6IFwiY3VpZFwiLFxuICAgICAgICBjdWlkMjogXCJjdWlkMlwiLFxuICAgICAgICB1bGlkOiBcIlVMSURcIixcbiAgICAgICAgeGlkOiBcIlhJRFwiLFxuICAgICAgICBrc3VpZDogXCJLU1VJRFwiLFxuICAgICAgICBkYXRldGltZTogXCJJU08gZGF0by0gb2cga2xva2tlc2xldHRcIixcbiAgICAgICAgZGF0ZTogXCJJU08tZGF0b1wiLFxuICAgICAgICB0aW1lOiBcIklTTy1rbG9ra2VzbGV0dFwiLFxuICAgICAgICBkdXJhdGlvbjogXCJJU08tdmFyaWdoZXRcIixcbiAgICAgICAgaXB2NDogXCJJUHY0LW9tclx1MDBFNWRlXCIsXG4gICAgICAgIGlwdjY6IFwiSVB2Ni1vbXJcdTAwRTVkZVwiLFxuICAgICAgICBjaWRydjQ6IFwiSVB2NC1zcGVrdGVyXCIsXG4gICAgICAgIGNpZHJ2NjogXCJJUHY2LXNwZWt0ZXJcIixcbiAgICAgICAgYmFzZTY0OiBcImJhc2U2NC1lbmtvZGV0IHN0cmVuZ1wiLFxuICAgICAgICBiYXNlNjR1cmw6IFwiYmFzZTY0dXJsLWVua29kZXQgc3RyZW5nXCIsXG4gICAgICAgIGpzb25fc3RyaW5nOiBcIkpTT04tc3RyZW5nXCIsXG4gICAgICAgIGUxNjQ6IFwiRS4xNjQtbnVtbWVyXCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJpbnB1dFwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBVZ3lsZGlnIGlucHV0OiBmb3J2ZW50ZXQgJHtpc3N1ZS5leHBlY3RlZH0sIGZpa2sgJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBVZ3lsZGlnIHZlcmRpOiBmb3J2ZW50ZXQgJHt1dGlsLnN0cmluZ2lmeVByaW1pdGl2ZShpc3N1ZS52YWx1ZXNbMF0pfWA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBVZ3lsZGlnIHZhbGc6IGZvcnZlbnRldCBlbiBhdiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS52YWx1ZXMsIFwifFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPD1cIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykgcmV0dXJuIGBGb3Igc3Rvcih0KTogZm9ydmVudGV0ICR7aXNzdWUub3JpZ2luID8/IFwidmFsdWVcIn0gdGlsIFx1MDBFNSBoYSAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdCA/PyBcImVsZW1lbnRlclwifWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgRm9yIHN0b3IodCk6IGZvcnZlbnRldCAke2lzc3VlLm9yaWdpbiA/PyBcInZhbHVlXCJ9IHRpbCBcdTAwRTUgaGEgJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIj49XCIgOiBcIj5cIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgRm9yIGxpdGUobik6IGZvcnZlbnRldCAke2lzc3VlLm9yaWdpbn0gdGlsIFx1MDBFNSBoYSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdH1gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgRm9yIGxpdGUobik6IGZvcnZlbnRldCAke2lzc3VlLm9yaWdpbn0gdGlsIFx1MDBFNSBoYSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2Zvcm1hdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgX2lzc3VlID0gaXNzdWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInN0YXJ0c193aXRoXCIpIHJldHVybiBgVWd5bGRpZyBzdHJlbmc6IG1cdTAwRTUgc3RhcnRlIG1lZCBcIiR7X2lzc3VlLnByZWZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYFVneWxkaWcgc3RyZW5nOiBtXHUwMEU1IGVuZGUgbWVkIFwiJHtfaXNzdWUuc3VmZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBVZ3lsZGlnIHN0cmVuZzogbVx1MDBFNSBpbm5laG9sZGUgXCIke19pc3N1ZS5pbmNsdWRlc31cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInJlZ2V4XCIpIHJldHVybiBgVWd5bGRpZyBzdHJlbmc6IG1cdTAwRTUgbWF0Y2hlIG1cdTAwRjhuc3RlcmV0ICR7X2lzc3VlLnBhdHRlcm59YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBVZ3lsZGlnICR7Tm91bnNbX2lzc3VlLmZvcm1hdF0gPz8gaXNzdWUuZm9ybWF0fWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm5vdF9tdWx0aXBsZV9vZlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgVWd5bGRpZyB0YWxsOiBtXHUwMEU1IHZcdTAwRTZyZSBldCBtdWx0aXBsdW0gYXYgJHtpc3N1ZS5kaXZpc29yfWA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYCR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJVa2plbnRlIG5cdTAwRjhrbGVyXCIgOiBcIlVramVudCBuXHUwMEY4a2tlbFwifTogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgXCIsIFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfa2V5XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBVZ3lsZGlnIG5cdTAwRjhra2VsIGkgJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3VuaW9uXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiVWd5bGRpZyBpbnB1dFwiO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZWxlbWVudFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgVWd5bGRpZyB2ZXJkaSBpICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBgVWd5bGRpZyBpbnB1dGA7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGxvY2FsZUVycm9yOiBlcnJvcigpXG4gICAgfTtcbn1cbiIsICJpbXBvcnQgKiBhcyB1dGlsIGZyb20gXCIuLi9jb3JlL3V0aWwuanNcIjtcbmNvbnN0IGVycm9yID0gKCk9PntcbiAgICBjb25zdCBTaXphYmxlID0ge1xuICAgICAgICBzdHJpbmc6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiaGFyZlwiLFxuICAgICAgICAgICAgdmVyYjogXCJvbG1hbFx1MDEzMWRcdTAxMzFyXCJcbiAgICAgICAgfSxcbiAgICAgICAgZmlsZToge1xuICAgICAgICAgICAgdW5pdDogXCJiYXl0XCIsXG4gICAgICAgICAgICB2ZXJiOiBcIm9sbWFsXHUwMTMxZFx1MDEzMXJcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJ1bnN1clwiLFxuICAgICAgICAgICAgdmVyYjogXCJvbG1hbFx1MDEzMWRcdTAxMzFyXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcInVuc3VyXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIm9sbWFsXHUwMTMxZFx1MDEzMXJcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIk5hTlwiIDogXCJudW1hcmFcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwic2FmXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGEgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcImdheWJcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKGRhdGEpICE9PSBPYmplY3QucHJvdG90eXBlICYmIGRhdGEuY29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHQ7XG4gICAgfTtcbiAgICBjb25zdCBOb3VucyA9IHtcbiAgICAgICAgcmVnZXg6IFwiZ2lyZW5cIixcbiAgICAgICAgZW1haWw6IFwiZXBvc3RhZ1x1MDBFMmhcIixcbiAgICAgICAgdXJsOiBcIlVSTFwiLFxuICAgICAgICBlbW9qaTogXCJlbW9qaVwiLFxuICAgICAgICB1dWlkOiBcIlVVSURcIixcbiAgICAgICAgdXVpZHY0OiBcIlVVSUR2NFwiLFxuICAgICAgICB1dWlkdjY6IFwiVVVJRHY2XCIsXG4gICAgICAgIG5hbm9pZDogXCJuYW5vaWRcIixcbiAgICAgICAgZ3VpZDogXCJHVUlEXCIsXG4gICAgICAgIGN1aWQ6IFwiY3VpZFwiLFxuICAgICAgICBjdWlkMjogXCJjdWlkMlwiLFxuICAgICAgICB1bGlkOiBcIlVMSURcIixcbiAgICAgICAgeGlkOiBcIlhJRFwiLFxuICAgICAgICBrc3VpZDogXCJLU1VJRFwiLFxuICAgICAgICBkYXRldGltZTogXCJJU08gaGVuZ1x1MDBFMm1cdTAxMzFcIixcbiAgICAgICAgZGF0ZTogXCJJU08gdGFyaWhpXCIsXG4gICAgICAgIHRpbWU6IFwiSVNPIHphbWFuXHUwMTMxXCIsXG4gICAgICAgIGR1cmF0aW9uOiBcIklTTyBtXHUwMEZDZGRldGlcIixcbiAgICAgICAgaXB2NDogXCJJUHY0IG5pXHUwMTVGXHUwMEUyblx1MDEzMVwiLFxuICAgICAgICBpcHY2OiBcIklQdjYgbmlcdTAxNUZcdTAwRTJuXHUwMTMxXCIsXG4gICAgICAgIGNpZHJ2NDogXCJJUHY0IG1lbnppbGlcIixcbiAgICAgICAgY2lkcnY2OiBcIklQdjYgbWVuemlsaVwiLFxuICAgICAgICBiYXNlNjQ6IFwiYmFzZTY0LVx1MDE1RmlmcmVsaSBtZXRpblwiLFxuICAgICAgICBiYXNlNjR1cmw6IFwiYmFzZTY0dXJsLVx1MDE1RmlmcmVsaSBtZXRpblwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJKU09OIG1ldGluXCIsXG4gICAgICAgIGUxNjQ6IFwiRS4xNjQgc2F5XHUwMTMxc1x1MDEzMVwiLFxuICAgICAgICBqd3Q6IFwiSldUXCIsXG4gICAgICAgIHRlbXBsYXRlX2xpdGVyYWw6IFwiZ2lyZW5cIlxuICAgIH07XG4gICAgcmV0dXJuIChpc3N1ZSk9PntcbiAgICAgICAgc3dpdGNoKGlzc3VlLmNvZGUpe1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdHlwZVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgRlx1MDBFMnNpdCBnaXJlbjogdW11bGFuICR7aXNzdWUuZXhwZWN0ZWR9LCBhbFx1MDEzMW5hbiAke3BhcnNlZFR5cGUoaXNzdWUuaW5wdXQpfWA7XG4gICAgICAgICAgICAvLyByZXR1cm4gYEZcdTAwRTJzaXQgZ2lyZW46IHVtdWxhbiAke2lzc3VlLmV4cGVjdGVkfSwgYWxcdTAxMzFuYW4gJHt1dGlsLmdldFBhcnNlZFR5cGUoaXNzdWUuaW5wdXQpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF92YWx1ZVwiOlxuICAgICAgICAgICAgICAgIGlmIChpc3N1ZS52YWx1ZXMubGVuZ3RoID09PSAxKSByZXR1cm4gYEZcdTAwRTJzaXQgZ2lyZW46IHVtdWxhbiAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYEZcdTAwRTJzaXQgdGVyY2loOiBtXHUwMEZCdGViZXJsZXIgJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIjw9XCIgOiBcIjxcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgRmF6bGEgYlx1MDBGQ3lcdTAwRkNrOiAke2lzc3VlLm9yaWdpbiA/PyBcInZhbHVlXCJ9LCAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdCA/PyBcImVsZW1lbnRzXCJ9IHNhaGlwIG9sbWFsXHUwMTMxeWRcdTAxMzEuYDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBGYXpsYSBiXHUwMEZDeVx1MDBGQ2s6ICR7aXNzdWUub3JpZ2luID8/IFwidmFsdWVcIn0sICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSBvbG1hbFx1MDEzMXlkXHUwMTMxLmA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInRvb19zbWFsbFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI+PVwiIDogXCI+XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYEZhemxhIGtcdTAwRkNcdTAwRTdcdTAwRkNrOiAke2lzc3VlLm9yaWdpbn0sICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0fSBzYWhpcCBvbG1hbFx1MDEzMXlkXHUwMTMxLmA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBGYXpsYSBrXHUwMEZDXHUwMEU3XHUwMEZDazogJHtpc3N1ZS5vcmlnaW59LCAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gb2xtYWxcdTAxMzF5ZFx1MDEzMS5gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2Zvcm1hdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgX2lzc3VlID0gaXNzdWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInN0YXJ0c193aXRoXCIpIHJldHVybiBgRlx1MDBFMnNpdCBtZXRpbjogXCIke19pc3N1ZS5wcmVmaXh9XCIgaWxlIGJhXHUwMTVGbGFtYWxcdTAxMzEuYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiZW5kc193aXRoXCIpIHJldHVybiBgRlx1MDBFMnNpdCBtZXRpbjogXCIke19pc3N1ZS5zdWZmaXh9XCIgaWxlIGJpdG1lbGkuYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBGXHUwMEUyc2l0IG1ldGluOiBcIiR7X2lzc3VlLmluY2x1ZGVzfVwiIGlodGl2XHUwMEUyIGV0bWVsaS5gO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYEZcdTAwRTJzaXQgbWV0aW46ICR7X2lzc3VlLnBhdHRlcm59IG5ha1x1MDE1Rlx1MDEzMW5hIHV5bWFsXHUwMTMxLmA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgRlx1MDBFMnNpdCAke05vdW5zW19pc3N1ZS5mb3JtYXRdID8/IGlzc3VlLmZvcm1hdH1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJub3RfbXVsdGlwbGVfb2ZcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYEZcdTAwRTJzaXQgc2F5XHUwMTMxOiAke2lzc3VlLmRpdmlzb3J9IGthdFx1MDEzMSBvbG1hbFx1MDEzMXlkXHUwMTMxLmA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFRhblx1MDEzMW5tYXlhbiBhbmFodGFyICR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJzXCIgOiBcIlwifTogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgXCIsIFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfa2V5XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGAke2lzc3VlLm9yaWdpbn0gaVx1MDBFN2luIHRhblx1MDEzMW5tYXlhbiBhbmFodGFyIHZhci5gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJHaXJlbiB0YW5cdTAxMzFuYW1hZFx1MDEzMS5cIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYCR7aXNzdWUub3JpZ2lufSBpXHUwMEU3aW4gdGFuXHUwMTMxbm1heWFuIGtcdTAxMzF5bWV0IHZhci5gO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gYEtcdTAxMzF5bWV0IHRhblx1MDEzMW5hbWFkXHUwMTMxLmA7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGxvY2FsZUVycm9yOiBlcnJvcigpXG4gICAgfTtcbn1cbiIsICJpbXBvcnQgKiBhcyB1dGlsIGZyb20gXCIuLi9jb3JlL3V0aWwuanNcIjtcbmNvbnN0IGVycm9yID0gKCk9PntcbiAgICBjb25zdCBTaXphYmxlID0ge1xuICAgICAgICBzdHJpbmc6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHUwNjJBXHUwNjQ4XHUwNkE5XHUwNjRBXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MDY0OFx1MDY0NFx1MDYzMVx1MDY0QVwiXG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHUwNjI4XHUwNjI3XHUwNkNDXHUwNjdDXHUwNjMzXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MDY0OFx1MDY0NFx1MDYzMVx1MDY0QVwiXG4gICAgICAgIH0sXG4gICAgICAgIGFycmF5OiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MDYyQVx1MDY0OFx1MDZBOVx1MDY0QVwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTA2NDhcdTA2NDRcdTA2MzFcdTA2NEFcIlxuICAgICAgICB9LFxuICAgICAgICBzZXQ6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHUwNjJBXHUwNjQ4XHUwNkE5XHUwNjRBXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MDY0OFx1MDY0NFx1MDYzMVx1MDY0QVwiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4pIHtcbiAgICAgICAgcmV0dXJuIFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWRUeXBlID0gKGRhdGEpPT57XG4gICAgICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICAgICAgc3dpdGNoKHQpe1xuICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIlx1MDYzOVx1MDYyRlx1MDYyRlwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTA2MjdcdTA2MzFcdTA2RDBcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YoZGF0YSkgIT09IE9iamVjdC5wcm90b3R5cGUgJiYgZGF0YS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdDtcbiAgICB9O1xuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJcdTA2NDhcdTA2MzFcdTA2NDhcdTA2MkZcdTA2NEFcIixcbiAgICAgICAgZW1haWw6IFwiXHUwNjI4XHUwNjMxXHUwNkNDXHUwNjlBXHUwNjQ2XHUwNjI3XHUwNjQ0XHUwNkNDXHUwNkE5XCIsXG4gICAgICAgIHVybDogXCJcdTA2Q0NcdTA2NDggXHUwNjIyXHUwNjMxIFx1MDYyN1x1MDY0NFwiLFxuICAgICAgICBlbW9qaTogXCJcdTA2MjdcdTA2Q0NcdTA2NDVcdTA2NDhcdTA2MkNcdTA2NEFcIixcbiAgICAgICAgdXVpZDogXCJVVUlEXCIsXG4gICAgICAgIHV1aWR2NDogXCJVVUlEdjRcIixcbiAgICAgICAgdXVpZHY2OiBcIlVVSUR2NlwiLFxuICAgICAgICBuYW5vaWQ6IFwibmFub2lkXCIsXG4gICAgICAgIGd1aWQ6IFwiR1VJRFwiLFxuICAgICAgICBjdWlkOiBcImN1aWRcIixcbiAgICAgICAgY3VpZDI6IFwiY3VpZDJcIixcbiAgICAgICAgdWxpZDogXCJVTElEXCIsXG4gICAgICAgIHhpZDogXCJYSURcIixcbiAgICAgICAga3N1aWQ6IFwiS1NVSURcIixcbiAgICAgICAgZGF0ZXRpbWU6IFwiXHUwNjQ2XHUwNkNDXHUwNjdDXHUwNjQ3IFx1MDYyN1x1MDY0OCBcdTA2NDhcdTA2MkVcdTA2MkFcIixcbiAgICAgICAgZGF0ZTogXCJcdTA2NDZcdTA2RDBcdTA2N0NcdTA2NDdcIixcbiAgICAgICAgdGltZTogXCJcdTA2NDhcdTA2MkVcdTA2MkFcIixcbiAgICAgICAgZHVyYXRpb246IFwiXHUwNjQ1XHUwNjQ4XHUwNjJGXHUwNjQ3XCIsXG4gICAgICAgIGlwdjQ6IFwiXHUwNjJGIElQdjQgXHUwNjdFXHUwNjJBXHUwNjQ3XCIsXG4gICAgICAgIGlwdjY6IFwiXHUwNjJGIElQdjYgXHUwNjdFXHUwNjJBXHUwNjQ3XCIsXG4gICAgICAgIGNpZHJ2NDogXCJcdTA2MkYgSVB2NCBcdTA2MzNcdTA2MjdcdTA2MkRcdTA2NDdcIixcbiAgICAgICAgY2lkcnY2OiBcIlx1MDYyRiBJUHY2IFx1MDYzM1x1MDYyN1x1MDYyRFx1MDY0N1wiLFxuICAgICAgICBiYXNlNjQ6IFwiYmFzZTY0LWVuY29kZWQgXHUwNjQ1XHUwNjJBXHUwNjQ2XCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJiYXNlNjR1cmwtZW5jb2RlZCBcdTA2NDVcdTA2MkFcdTA2NDZcIixcbiAgICAgICAganNvbl9zdHJpbmc6IFwiSlNPTiBcdTA2NDVcdTA2MkFcdTA2NDZcIixcbiAgICAgICAgZTE2NDogXCJcdTA2MkYgRS4xNjQgXHUwNjM0XHUwNjQ1XHUwNkQwXHUwNjMxXHUwNjQ3XCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJcdTA2NDhcdTA2MzFcdTA2NDhcdTA2MkZcdTA2NEFcIlxuICAgIH07XG4gICAgcmV0dXJuIChpc3N1ZSk9PntcbiAgICAgICAgc3dpdGNoKGlzc3VlLmNvZGUpe1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdHlwZVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjQ2XHUwNjI3XHUwNjMzXHUwNjQ1IFx1MDY0OFx1MDYzMVx1MDY0OFx1MDYyRlx1MDY0QTogXHUwNjI4XHUwNjI3XHUwNkNDXHUwNjJGICR7aXNzdWUuZXhwZWN0ZWR9IFx1MDY0OFx1MDYyN1x1MDZDQywgXHUwNjQ1XHUwNkFCXHUwNjMxICR7cGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9IFx1MDYyQVx1MDYzMVx1MDY0NFx1MDYyN1x1MDYzM1x1MDY0NyBcdTA2MzRcdTA2NDhgO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDY0Nlx1MDYyN1x1MDYzM1x1MDY0NSBcdTA2NDhcdTA2MzFcdTA2NDhcdTA2MkZcdTA2NEE6IFx1MDYyOFx1MDYyN1x1MDZDQ1x1MDYyRiAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9IFx1MDY0OFx1MDYyN1x1MDZDQ2A7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjQ2XHUwNjI3XHUwNjMzXHUwNjQ1IFx1MDYyN1x1MDY0Nlx1MDYyQVx1MDYyRVx1MDYyN1x1MDYyODogXHUwNjI4XHUwNjI3XHUwNkNDXHUwNjJGIFx1MDZDQ1x1MDY0OCBcdTA2NDRcdTA2NDcgJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9IFx1MDY4NVx1MDYyRVx1MDY0NyBcdTA2NDhcdTA2MjdcdTA2Q0NgO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPD1cIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2ODlcdTA2Q0NcdTA2MzEgXHUwNjQ0XHUwNjQ4XHUwNkNDOiAke2lzc3VlLm9yaWdpbiA/PyBcIlx1MDYyN1x1MDYzMVx1MDYzMlx1MDY5QVx1MDYyQVwifSBcdTA2MjhcdTA2MjdcdTA2Q0NcdTA2MkYgJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXQgPz8gXCJcdTA2MzlcdTA2NDZcdTA2MzVcdTA2MzFcdTA2NDhcdTA2NDZcdTA2NDdcIn0gXHUwNjQ4XHUwNjQ0XHUwNjMxXHUwNjRBYDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDY4OVx1MDZDQ1x1MDYzMSBcdTA2NDRcdTA2NDhcdTA2Q0M6ICR7aXNzdWUub3JpZ2luID8/IFwiXHUwNjI3XHUwNjMxXHUwNjMyXHUwNjlBXHUwNjJBXCJ9IFx1MDYyOFx1MDYyN1x1MDZDQ1x1MDYyRiAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX0gXHUwNjQ4XHUwNjRBYDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIj49XCIgOiBcIj5cIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjg5XHUwNkNDXHUwNjMxIFx1MDZBOVx1MDY0OFx1MDY4Nlx1MDY0Nlx1MDZDQzogJHtpc3N1ZS5vcmlnaW59IFx1MDYyOFx1MDYyN1x1MDZDQ1x1MDYyRiAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdH0gXHUwNjQ4XHUwNjQ0XHUwNjMxXHUwNjRBYDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDY4OVx1MDZDQ1x1MDYzMSBcdTA2QTlcdTA2NDhcdTA2ODZcdTA2NDZcdTA2Q0M6ICR7aXNzdWUub3JpZ2lufSBcdTA2MjhcdTA2MjdcdTA2Q0NcdTA2MkYgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9IFx1MDY0OFx1MDY0QWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZm9ybWF0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBfaXNzdWUgPSBpc3N1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwic3RhcnRzX3dpdGhcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2NDZcdTA2MjdcdTA2MzNcdTA2NDUgXHUwNjQ1XHUwNjJBXHUwNjQ2OiBcdTA2MjhcdTA2MjdcdTA2Q0NcdTA2MkYgXHUwNjJGIFwiJHtfaXNzdWUucHJlZml4fVwiIFx1MDYzM1x1MDYzMVx1MDY0NyBcdTA2N0VcdTA2Q0NcdTA2NDQgXHUwNjM0XHUwNjRBYDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJlbmRzX3dpdGhcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2NDZcdTA2MjdcdTA2MzNcdTA2NDUgXHUwNjQ1XHUwNjJBXHUwNjQ2OiBcdTA2MjhcdTA2MjdcdTA2Q0NcdTA2MkYgXHUwNjJGIFwiJHtfaXNzdWUuc3VmZml4fVwiIFx1MDYzM1x1MDYzMVx1MDY0NyBcdTA2N0VcdTA2MjdcdTA2Q0MgXHUwNjJBXHUwNjQ3IFx1MDY0OFx1MDYzMVx1MDYzM1x1MDY0QVx1MDY5Nlx1MDY0QWA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2NDZcdTA2MjdcdTA2MzNcdTA2NDUgXHUwNjQ1XHUwNjJBXHUwNjQ2OiBcdTA2MjhcdTA2MjdcdTA2Q0NcdTA2MkYgXCIke19pc3N1ZS5pbmNsdWRlc31cIiBcdTA2NDhcdTA2NDRcdTA2MzFcdTA2NEFgO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInJlZ2V4XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjQ2XHUwNjI3XHUwNjMzXHUwNjQ1IFx1MDY0NVx1MDYyQVx1MDY0NjogXHUwNjI4XHUwNjI3XHUwNkNDXHUwNjJGIFx1MDYyRiAke19pc3N1ZS5wYXR0ZXJufSBcdTA2MzNcdTA2MzFcdTA2NDcgXHUwNjQ1XHUwNjM3XHUwNjI3XHUwNjI4XHUwNjQyXHUwNjJBIFx1MDY0OFx1MDY0NFx1MDYzMVx1MDY0QWA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGAke05vdW5zW19pc3N1ZS5mb3JtYXRdID8/IGlzc3VlLmZvcm1hdH0gXHUwNjQ2XHUwNjI3XHUwNjMzXHUwNjQ1IFx1MDYyRlx1MDZDQ2A7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm5vdF9tdWx0aXBsZV9vZlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjQ2XHUwNjI3XHUwNjMzXHUwNjQ1IFx1MDYzOVx1MDYyRlx1MDYyRjogXHUwNjI4XHUwNjI3XHUwNkNDXHUwNjJGIFx1MDYyRiAke2lzc3VlLmRpdmlzb3J9IFx1MDY0NVx1MDYzNlx1MDYzMVx1MDYyOCBcdTA2NDhcdTA2NEFgO1xuICAgICAgICAgICAgY2FzZSBcInVucmVjb2duaXplZF9rZXlzXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2NDZcdTA2MjdcdTA2MzNcdTA2NDUgJHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcIlx1MDZBOVx1MDY0NFx1MDZDQ1x1MDY4OVx1MDY0OFx1MDY0Nlx1MDY0N1wiIDogXCJcdTA2QTlcdTA2NDRcdTA2Q0NcdTA2ODlcIn06ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLmtleXMsIFwiLCBcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2tleVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjQ2XHUwNjI3XHUwNjMzXHUwNjQ1IFx1MDZBOVx1MDY0NFx1MDZDQ1x1MDY4OSBcdTA2N0VcdTA2NDcgJHtpc3N1ZS5vcmlnaW59IFx1MDZBOVx1MDZEMGA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF91bmlvblwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjQ2XHUwNjI3XHUwNjMzXHUwNjQ1XHUwNjQ3IFx1MDY0OFx1MDYzMVx1MDY0OFx1MDYyRlx1MDY0QWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9lbGVtZW50XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2NDZcdTA2MjdcdTA2MzNcdTA2NDUgXHUwNjM5XHUwNjQ2XHUwNjM1XHUwNjMxIFx1MDY3RVx1MDY0NyAke2lzc3VlLm9yaWdpbn0gXHUwNkE5XHUwNkQwYDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2NDZcdTA2MjdcdTA2MzNcdTA2NDVcdTA2NDcgXHUwNjQ4XHUwNjMxXHUwNjQ4XHUwNjJGXHUwNjRBYDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJ6bmFrXHUwMEYzd1wiLFxuICAgICAgICAgICAgdmVyYjogXCJtaWVcdTAxMDdcIlxuICAgICAgICB9LFxuICAgICAgICBmaWxlOiB7XG4gICAgICAgICAgICB1bml0OiBcImJhanRcdTAwRjN3XCIsXG4gICAgICAgICAgICB2ZXJiOiBcIm1pZVx1MDEwN1wiXG4gICAgICAgIH0sXG4gICAgICAgIGFycmF5OiB7XG4gICAgICAgICAgICB1bml0OiBcImVsZW1lbnRcdTAwRjN3XCIsXG4gICAgICAgICAgICB2ZXJiOiBcIm1pZVx1MDEwN1wiXG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDogXCJlbGVtZW50XHUwMEYzd1wiLFxuICAgICAgICAgICAgdmVyYjogXCJtaWVcdTAxMDdcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIk5hTlwiIDogXCJsaWN6YmFcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwidGFibGljYVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJudWxsXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcInd5cmFcdTAxN0NlbmllXCIsXG4gICAgICAgIGVtYWlsOiBcImFkcmVzIGVtYWlsXCIsXG4gICAgICAgIHVybDogXCJVUkxcIixcbiAgICAgICAgZW1vamk6IFwiZW1vamlcIixcbiAgICAgICAgdXVpZDogXCJVVUlEXCIsXG4gICAgICAgIHV1aWR2NDogXCJVVUlEdjRcIixcbiAgICAgICAgdXVpZHY2OiBcIlVVSUR2NlwiLFxuICAgICAgICBuYW5vaWQ6IFwibmFub2lkXCIsXG4gICAgICAgIGd1aWQ6IFwiR1VJRFwiLFxuICAgICAgICBjdWlkOiBcImN1aWRcIixcbiAgICAgICAgY3VpZDI6IFwiY3VpZDJcIixcbiAgICAgICAgdWxpZDogXCJVTElEXCIsXG4gICAgICAgIHhpZDogXCJYSURcIixcbiAgICAgICAga3N1aWQ6IFwiS1NVSURcIixcbiAgICAgICAgZGF0ZXRpbWU6IFwiZGF0YSBpIGdvZHppbmEgdyBmb3JtYWNpZSBJU09cIixcbiAgICAgICAgZGF0ZTogXCJkYXRhIHcgZm9ybWFjaWUgSVNPXCIsXG4gICAgICAgIHRpbWU6IFwiZ29kemluYSB3IGZvcm1hY2llIElTT1wiLFxuICAgICAgICBkdXJhdGlvbjogXCJjemFzIHRyd2FuaWEgSVNPXCIsXG4gICAgICAgIGlwdjQ6IFwiYWRyZXMgSVB2NFwiLFxuICAgICAgICBpcHY2OiBcImFkcmVzIElQdjZcIixcbiAgICAgICAgY2lkcnY0OiBcInpha3JlcyBJUHY0XCIsXG4gICAgICAgIGNpZHJ2NjogXCJ6YWtyZXMgSVB2NlwiLFxuICAgICAgICBiYXNlNjQ6IFwiY2lcdTAxMDVnIHpuYWtcdTAwRjN3IHpha29kb3dhbnkgdyBmb3JtYWNpZSBiYXNlNjRcIixcbiAgICAgICAgYmFzZTY0dXJsOiBcImNpXHUwMTA1ZyB6bmFrXHUwMEYzdyB6YWtvZG93YW55IHcgZm9ybWFjaWUgYmFzZTY0dXJsXCIsXG4gICAgICAgIGpzb25fc3RyaW5nOiBcImNpXHUwMTA1ZyB6bmFrXHUwMEYzdyB3IGZvcm1hY2llIEpTT05cIixcbiAgICAgICAgZTE2NDogXCJsaWN6YmEgRS4xNjRcIixcbiAgICAgICAgand0OiBcIkpXVFwiLFxuICAgICAgICB0ZW1wbGF0ZV9saXRlcmFsOiBcIndlalx1MDE1QmNpZVwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOaWVwcmF3aWRcdTAxNDJvd2UgZGFuZSB3ZWpcdTAxNUJjaW93ZTogb2N6ZWtpd2FubyAke2lzc3VlLmV4cGVjdGVkfSwgb3RyenltYW5vICR7cGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgTmllcHJhd2lkXHUwMTQyb3dlIGRhbmUgd2VqXHUwMTVCY2lvd2U6IG9jemVraXdhbm8gJHt1dGlsLnN0cmluZ2lmeVByaW1pdGl2ZShpc3N1ZS52YWx1ZXNbMF0pfWA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOaWVwcmF3aWRcdTAxNDJvd2Egb3BjamE6IG9jemVraXdhbm8gamVkbmVqIHogd2FydG9cdTAxNUJjaSAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS52YWx1ZXMsIFwifFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPD1cIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBaYSBkdVx1MDE3Q2Egd2FydG9cdTAxNUJcdTAxMDc6IG9jemVraXdhbm8sIFx1MDE3Q2UgJHtpc3N1ZS5vcmlnaW4gPz8gXCJ3YXJ0b1x1MDE1Qlx1MDEwN1wifSBiXHUwMTE5ZHppZSBtaWVcdTAxMDcgJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXQgPz8gXCJlbGVtZW50XHUwMEYzd1wifWA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBaYnl0IGR1XHUwMTdDKHkvYS9lKTogb2N6ZWtpd2FubywgXHUwMTdDZSAke2lzc3VlLm9yaWdpbiA/PyBcIndhcnRvXHUwMTVCXHUwMTA3XCJ9IGJcdTAxMTlkemllIHd5bm9zaVx1MDEwNyAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJ0b29fc21hbGxcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPj1cIiA6IFwiPlwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBaYSBtYVx1MDE0MmEgd2FydG9cdTAxNUJcdTAxMDc6IG9jemVraXdhbm8sIFx1MDE3Q2UgJHtpc3N1ZS5vcmlnaW4gPz8gXCJ3YXJ0b1x1MDE1Qlx1MDEwN1wifSBiXHUwMTE5ZHppZSBtaWVcdTAxMDcgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXQgPz8gXCJlbGVtZW50XHUwMEYzd1wifWA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBaYnl0IG1hXHUwMTQyKHkvYS9lKTogb2N6ZWtpd2FubywgXHUwMTdDZSAke2lzc3VlLm9yaWdpbiA/PyBcIndhcnRvXHUwMTVCXHUwMTA3XCJ9IGJcdTAxMTlkemllIHd5bm9zaVx1MDEwNyAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2Zvcm1hdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgX2lzc3VlID0gaXNzdWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInN0YXJ0c193aXRoXCIpIHJldHVybiBgTmllcHJhd2lkXHUwMTQyb3d5IGNpXHUwMTA1ZyB6bmFrXHUwMEYzdzogbXVzaSB6YWN6eW5hXHUwMTA3IHNpXHUwMTE5IG9kIFwiJHtfaXNzdWUucHJlZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiZW5kc193aXRoXCIpIHJldHVybiBgTmllcHJhd2lkXHUwMTQyb3d5IGNpXHUwMTA1ZyB6bmFrXHUwMEYzdzogbXVzaSBrb1x1MDE0NGN6eVx1MDEwNyBzaVx1MDExOSBuYSBcIiR7X2lzc3VlLnN1ZmZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImluY2x1ZGVzXCIpIHJldHVybiBgTmllcHJhd2lkXHUwMTQyb3d5IGNpXHUwMTA1ZyB6bmFrXHUwMEYzdzogbXVzaSB6YXdpZXJhXHUwMTA3IFwiJHtfaXNzdWUuaW5jbHVkZXN9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYE5pZXByYXdpZFx1MDE0Mm93eSBjaVx1MDEwNWcgem5ha1x1MDBGM3c6IG11c2kgb2Rwb3dpYWRhXHUwMTA3IHd6b3Jjb3dpICR7X2lzc3VlLnBhdHRlcm59YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBOaWVwcmF3aWRcdTAxNDJvdyh5L2EvZSkgJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOaWVwcmF3aWRcdTAxNDJvd2EgbGljemJhOiBtdXNpIGJ5XHUwMTA3IHdpZWxva3JvdG5vXHUwMTVCY2lcdTAxMDUgJHtpc3N1ZS5kaXZpc29yfWA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYE5pZXJvenBvem5hbmUga2x1Y3plJHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcInNcIiA6IFwiXCJ9OiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIiwgXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYE5pZXByYXdpZFx1MDE0Mm93eSBrbHVjeiB3ICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF91bmlvblwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIk5pZXByYXdpZFx1MDE0Mm93ZSBkYW5lIHdlalx1MDE1QmNpb3dlXCI7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9lbGVtZW50XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOaWVwcmF3aWRcdTAxNDJvd2Egd2FydG9cdTAxNUJcdTAxMDcgdyAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gYE5pZXByYXdpZFx1MDE0Mm93ZSBkYW5lIHdlalx1MDE1QmNpb3dlYDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJjYXJhY3RlcmVzXCIsXG4gICAgICAgICAgICB2ZXJiOiBcInRlclwiXG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiYnl0ZXNcIixcbiAgICAgICAgICAgIHZlcmI6IFwidGVyXCJcbiAgICAgICAgfSxcbiAgICAgICAgYXJyYXk6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiaXRlbnNcIixcbiAgICAgICAgICAgIHZlcmI6IFwidGVyXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcIml0ZW5zXCIsXG4gICAgICAgICAgICB2ZXJiOiBcInRlclwiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4pIHtcbiAgICAgICAgcmV0dXJuIFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWRUeXBlID0gKGRhdGEpPT57XG4gICAgICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICAgICAgc3dpdGNoKHQpe1xuICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIm5cdTAwRkFtZXJvXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm9iamVjdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcImFycmF5XCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGEgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm51bG9cIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKGRhdGEpICE9PSBPYmplY3QucHJvdG90eXBlICYmIGRhdGEuY29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHQ7XG4gICAgfTtcbiAgICBjb25zdCBOb3VucyA9IHtcbiAgICAgICAgcmVnZXg6IFwicGFkclx1MDBFM29cIixcbiAgICAgICAgZW1haWw6IFwiZW5kZXJlXHUwMEU3byBkZSBlLW1haWxcIixcbiAgICAgICAgdXJsOiBcIlVSTFwiLFxuICAgICAgICBlbW9qaTogXCJlbW9qaVwiLFxuICAgICAgICB1dWlkOiBcIlVVSURcIixcbiAgICAgICAgdXVpZHY0OiBcIlVVSUR2NFwiLFxuICAgICAgICB1dWlkdjY6IFwiVVVJRHY2XCIsXG4gICAgICAgIG5hbm9pZDogXCJuYW5vaWRcIixcbiAgICAgICAgZ3VpZDogXCJHVUlEXCIsXG4gICAgICAgIGN1aWQ6IFwiY3VpZFwiLFxuICAgICAgICBjdWlkMjogXCJjdWlkMlwiLFxuICAgICAgICB1bGlkOiBcIlVMSURcIixcbiAgICAgICAgeGlkOiBcIlhJRFwiLFxuICAgICAgICBrc3VpZDogXCJLU1VJRFwiLFxuICAgICAgICBkYXRldGltZTogXCJkYXRhIGUgaG9yYSBJU09cIixcbiAgICAgICAgZGF0ZTogXCJkYXRhIElTT1wiLFxuICAgICAgICB0aW1lOiBcImhvcmEgSVNPXCIsXG4gICAgICAgIGR1cmF0aW9uOiBcImR1cmFcdTAwRTdcdTAwRTNvIElTT1wiLFxuICAgICAgICBpcHY0OiBcImVuZGVyZVx1MDBFN28gSVB2NFwiLFxuICAgICAgICBpcHY2OiBcImVuZGVyZVx1MDBFN28gSVB2NlwiLFxuICAgICAgICBjaWRydjQ6IFwiZmFpeGEgZGUgSVB2NFwiLFxuICAgICAgICBjaWRydjY6IFwiZmFpeGEgZGUgSVB2NlwiLFxuICAgICAgICBiYXNlNjQ6IFwidGV4dG8gY29kaWZpY2FkbyBlbSBiYXNlNjRcIixcbiAgICAgICAgYmFzZTY0dXJsOiBcIlVSTCBjb2RpZmljYWRhIGVtIGJhc2U2NFwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJ0ZXh0byBKU09OXCIsXG4gICAgICAgIGUxNjQ6IFwiblx1MDBGQW1lcm8gRS4xNjRcIixcbiAgICAgICAgand0OiBcIkpXVFwiLFxuICAgICAgICB0ZW1wbGF0ZV9saXRlcmFsOiBcImVudHJhZGFcIlxuICAgIH07XG4gICAgcmV0dXJuIChpc3N1ZSk9PntcbiAgICAgICAgc3dpdGNoKGlzc3VlLmNvZGUpe1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdHlwZVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgVGlwbyBpbnZcdTAwRTFsaWRvOiBlc3BlcmFkbyAke2lzc3VlLmV4cGVjdGVkfSwgcmVjZWJpZG8gJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBFbnRyYWRhIGludlx1MDBFMWxpZGE6IGVzcGVyYWRvICR7dXRpbC5zdHJpbmdpZnlQcmltaXRpdmUoaXNzdWUudmFsdWVzWzBdKX1gO1xuICAgICAgICAgICAgICAgIHJldHVybiBgT3BcdTAwRTdcdTAwRTNvIGludlx1MDBFMWxpZGE6IGVzcGVyYWRhIHVtYSBkYXMgJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIjw9XCIgOiBcIjxcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgTXVpdG8gZ3JhbmRlOiBlc3BlcmFkbyBxdWUgJHtpc3N1ZS5vcmlnaW4gPz8gXCJ2YWxvclwifSB0aXZlc3NlICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0ID8/IFwiZWxlbWVudG9zXCJ9YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBNdWl0byBncmFuZGU6IGVzcGVyYWRvIHF1ZSAke2lzc3VlLm9yaWdpbiA/PyBcInZhbG9yXCJ9IGZvc3NlICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInRvb19zbWFsbFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI+PVwiIDogXCI+XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYE11aXRvIHBlcXVlbm86IGVzcGVyYWRvIHF1ZSAke2lzc3VlLm9yaWdpbn0gdGl2ZXNzZSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdH1gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgTXVpdG8gcGVxdWVubzogZXNwZXJhZG8gcXVlICR7aXNzdWUub3JpZ2lufSBmb3NzZSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2Zvcm1hdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgX2lzc3VlID0gaXNzdWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInN0YXJ0c193aXRoXCIpIHJldHVybiBgVGV4dG8gaW52XHUwMEUxbGlkbzogZGV2ZSBjb21lXHUwMEU3YXIgY29tIFwiJHtfaXNzdWUucHJlZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiZW5kc193aXRoXCIpIHJldHVybiBgVGV4dG8gaW52XHUwMEUxbGlkbzogZGV2ZSB0ZXJtaW5hciBjb20gXCIke19pc3N1ZS5zdWZmaXh9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJpbmNsdWRlc1wiKSByZXR1cm4gYFRleHRvIGludlx1MDBFMWxpZG86IGRldmUgaW5jbHVpciBcIiR7X2lzc3VlLmluY2x1ZGVzfVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBUZXh0byBpbnZcdTAwRTFsaWRvOiBkZXZlIGNvcnJlc3BvbmRlciBhbyBwYWRyXHUwMEUzbyAke19pc3N1ZS5wYXR0ZXJufWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9IGludlx1MDBFMWxpZG9gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJub3RfbXVsdGlwbGVfb2ZcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYE5cdTAwRkFtZXJvIGludlx1MDBFMWxpZG86IGRldmUgc2VyIG1cdTAwRkFsdGlwbG8gZGUgJHtpc3N1ZS5kaXZpc29yfWA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYENoYXZlJHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcInNcIiA6IFwiXCJ9IGRlc2NvbmhlY2lkYSR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJzXCIgOiBcIlwifTogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgXCIsIFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfa2V5XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBDaGF2ZSBpbnZcdTAwRTFsaWRhIGVtICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF91bmlvblwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIkVudHJhZGEgaW52XHUwMEUxbGlkYVwiO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZWxlbWVudFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgVmFsb3IgaW52XHUwMEUxbGlkbyBlbSAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gYENhbXBvIGludlx1MDBFMWxpZG9gO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBsb2NhbGVFcnJvcjogZXJyb3IoKVxuICAgIH07XG59XG4iLCAiaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi4vY29yZS91dGlsLmpzXCI7XG5mdW5jdGlvbiBnZXRSdXNzaWFuUGx1cmFsKGNvdW50LCBvbmUsIGZldywgbWFueSkge1xuICAgIGNvbnN0IGFic0NvdW50ID0gTWF0aC5hYnMoY291bnQpO1xuICAgIGNvbnN0IGxhc3REaWdpdCA9IGFic0NvdW50ICUgMTA7XG4gICAgY29uc3QgbGFzdFR3b0RpZ2l0cyA9IGFic0NvdW50ICUgMTAwO1xuICAgIGlmIChsYXN0VHdvRGlnaXRzID49IDExICYmIGxhc3RUd29EaWdpdHMgPD0gMTkpIHtcbiAgICAgICAgcmV0dXJuIG1hbnk7XG4gICAgfVxuICAgIGlmIChsYXN0RGlnaXQgPT09IDEpIHtcbiAgICAgICAgcmV0dXJuIG9uZTtcbiAgICB9XG4gICAgaWYgKGxhc3REaWdpdCA+PSAyICYmIGxhc3REaWdpdCA8PSA0KSB7XG4gICAgICAgIHJldHVybiBmZXc7XG4gICAgfVxuICAgIHJldHVybiBtYW55O1xufVxuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDoge1xuICAgICAgICAgICAgICAgIG9uZTogXCJcdTA0NDFcdTA0MzhcdTA0M0NcdTA0MzJcdTA0M0VcdTA0M0JcIixcbiAgICAgICAgICAgICAgICBmZXc6IFwiXHUwNDQxXHUwNDM4XHUwNDNDXHUwNDMyXHUwNDNFXHUwNDNCXHUwNDMwXCIsXG4gICAgICAgICAgICAgICAgbWFueTogXCJcdTA0NDFcdTA0MzhcdTA0M0NcdTA0MzJcdTA0M0VcdTA0M0JcdTA0M0VcdTA0MzJcIlxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwNDM4XHUwNDNDXHUwNDM1XHUwNDQyXHUwNDRDXCJcbiAgICAgICAgfSxcbiAgICAgICAgZmlsZToge1xuICAgICAgICAgICAgdW5pdDoge1xuICAgICAgICAgICAgICAgIG9uZTogXCJcdTA0MzFcdTA0MzBcdTA0MzlcdTA0NDJcIixcbiAgICAgICAgICAgICAgICBmZXc6IFwiXHUwNDMxXHUwNDMwXHUwNDM5XHUwNDQyXHUwNDMwXCIsXG4gICAgICAgICAgICAgICAgbWFueTogXCJcdTA0MzFcdTA0MzBcdTA0MzlcdTA0NDJcIlxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwNDM4XHUwNDNDXHUwNDM1XHUwNDQyXHUwNDRDXCJcbiAgICAgICAgfSxcbiAgICAgICAgYXJyYXk6IHtcbiAgICAgICAgICAgIHVuaXQ6IHtcbiAgICAgICAgICAgICAgICBvbmU6IFwiXHUwNDREXHUwNDNCXHUwNDM1XHUwNDNDXHUwNDM1XHUwNDNEXHUwNDQyXCIsXG4gICAgICAgICAgICAgICAgZmV3OiBcIlx1MDQ0RFx1MDQzQlx1MDQzNVx1MDQzQ1x1MDQzNVx1MDQzRFx1MDQ0Mlx1MDQzMFwiLFxuICAgICAgICAgICAgICAgIG1hbnk6IFwiXHUwNDREXHUwNDNCXHUwNDM1XHUwNDNDXHUwNDM1XHUwNDNEXHUwNDQyXHUwNDNFXHUwNDMyXCJcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MDQzOFx1MDQzQ1x1MDQzNVx1MDQ0Mlx1MDQ0Q1wiXG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDoge1xuICAgICAgICAgICAgICAgIG9uZTogXCJcdTA0NERcdTA0M0JcdTA0MzVcdTA0M0NcdTA0MzVcdTA0M0RcdTA0NDJcIixcbiAgICAgICAgICAgICAgICBmZXc6IFwiXHUwNDREXHUwNDNCXHUwNDM1XHUwNDNDXHUwNDM1XHUwNDNEXHUwNDQyXHUwNDMwXCIsXG4gICAgICAgICAgICAgICAgbWFueTogXCJcdTA0NERcdTA0M0JcdTA0MzVcdTA0M0NcdTA0MzVcdTA0M0RcdTA0NDJcdTA0M0VcdTA0MzJcIlxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwNDM4XHUwNDNDXHUwNDM1XHUwNDQyXHUwNDRDXCJcbiAgICAgICAgfVxuICAgIH07XG4gICAgZnVuY3Rpb24gZ2V0U2l6aW5nKG9yaWdpbikge1xuICAgICAgICByZXR1cm4gU2l6YWJsZVtvcmlnaW5dID8/IG51bGw7XG4gICAgfVxuICAgIGNvbnN0IHBhcnNlZFR5cGUgPSAoZGF0YSk9PntcbiAgICAgICAgY29uc3QgdCA9IHR5cGVvZiBkYXRhO1xuICAgICAgICBzd2l0Y2godCl7XG4gICAgICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gTnVtYmVyLmlzTmFOKGRhdGEpID8gXCJOYU5cIiA6IFwiXHUwNDQ3XHUwNDM4XHUwNDQxXHUwNDNCXHUwNDNFXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm9iamVjdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIlx1MDQzQ1x1MDQzMFx1MDQ0MVx1MDQ0MVx1MDQzOFx1MDQzMlwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJudWxsXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcIlx1MDQzMlx1MDQzMlx1MDQzRVx1MDQzNFwiLFxuICAgICAgICBlbWFpbDogXCJlbWFpbCBcdTA0MzBcdTA0MzRcdTA0NDBcdTA0MzVcdTA0NDFcIixcbiAgICAgICAgdXJsOiBcIlVSTFwiLFxuICAgICAgICBlbW9qaTogXCJcdTA0NERcdTA0M0NcdTA0M0VcdTA0MzRcdTA0MzdcdTA0MzhcIixcbiAgICAgICAgdXVpZDogXCJVVUlEXCIsXG4gICAgICAgIHV1aWR2NDogXCJVVUlEdjRcIixcbiAgICAgICAgdXVpZHY2OiBcIlVVSUR2NlwiLFxuICAgICAgICBuYW5vaWQ6IFwibmFub2lkXCIsXG4gICAgICAgIGd1aWQ6IFwiR1VJRFwiLFxuICAgICAgICBjdWlkOiBcImN1aWRcIixcbiAgICAgICAgY3VpZDI6IFwiY3VpZDJcIixcbiAgICAgICAgdWxpZDogXCJVTElEXCIsXG4gICAgICAgIHhpZDogXCJYSURcIixcbiAgICAgICAga3N1aWQ6IFwiS1NVSURcIixcbiAgICAgICAgZGF0ZXRpbWU6IFwiSVNPIFx1MDQzNFx1MDQzMFx1MDQ0Mlx1MDQzMCBcdTA0MzggXHUwNDMyXHUwNDQwXHUwNDM1XHUwNDNDXHUwNDRGXCIsXG4gICAgICAgIGRhdGU6IFwiSVNPIFx1MDQzNFx1MDQzMFx1MDQ0Mlx1MDQzMFwiLFxuICAgICAgICB0aW1lOiBcIklTTyBcdTA0MzJcdTA0NDBcdTA0MzVcdTA0M0NcdTA0NEZcIixcbiAgICAgICAgZHVyYXRpb246IFwiSVNPIFx1MDQzNFx1MDQzQlx1MDQzOFx1MDQ0Mlx1MDQzNVx1MDQzQlx1MDQ0Q1x1MDQzRFx1MDQzRVx1MDQ0MVx1MDQ0Mlx1MDQ0Q1wiLFxuICAgICAgICBpcHY0OiBcIklQdjQgXHUwNDMwXHUwNDM0XHUwNDQwXHUwNDM1XHUwNDQxXCIsXG4gICAgICAgIGlwdjY6IFwiSVB2NiBcdTA0MzBcdTA0MzRcdTA0NDBcdTA0MzVcdTA0NDFcIixcbiAgICAgICAgY2lkcnY0OiBcIklQdjQgXHUwNDM0XHUwNDM4XHUwNDMwXHUwNDNGXHUwNDMwXHUwNDM3XHUwNDNFXHUwNDNEXCIsXG4gICAgICAgIGNpZHJ2NjogXCJJUHY2IFx1MDQzNFx1MDQzOFx1MDQzMFx1MDQzRlx1MDQzMFx1MDQzN1x1MDQzRVx1MDQzRFwiLFxuICAgICAgICBiYXNlNjQ6IFwiXHUwNDQxXHUwNDQyXHUwNDQwXHUwNDNFXHUwNDNBXHUwNDMwIFx1MDQzMiBcdTA0NDRcdTA0M0VcdTA0NDBcdTA0M0NcdTA0MzBcdTA0NDJcdTA0MzUgYmFzZTY0XCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJcdTA0NDFcdTA0NDJcdTA0NDBcdTA0M0VcdTA0M0FcdTA0MzAgXHUwNDMyIFx1MDQ0NFx1MDQzRVx1MDQ0MFx1MDQzQ1x1MDQzMFx1MDQ0Mlx1MDQzNSBiYXNlNjR1cmxcIixcbiAgICAgICAganNvbl9zdHJpbmc6IFwiSlNPTiBcdTA0NDFcdTA0NDJcdTA0NDBcdTA0M0VcdTA0M0FcdTA0MzBcIixcbiAgICAgICAgZTE2NDogXCJcdTA0M0RcdTA0M0VcdTA0M0NcdTA0MzVcdTA0NDAgRS4xNjRcIixcbiAgICAgICAgand0OiBcIkpXVFwiLFxuICAgICAgICB0ZW1wbGF0ZV9saXRlcmFsOiBcIlx1MDQzMlx1MDQzMlx1MDQzRVx1MDQzNFwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MURcdTA0MzVcdTA0MzJcdTA0MzVcdTA0NDBcdTA0M0RcdTA0NEJcdTA0MzkgXHUwNDMyXHUwNDMyXHUwNDNFXHUwNDM0OiBcdTA0M0VcdTA0MzZcdTA0MzhcdTA0MzRcdTA0MzBcdTA0M0JcdTA0M0VcdTA0NDFcdTA0NEMgJHtpc3N1ZS5leHBlY3RlZH0sIFx1MDQzRlx1MDQzRVx1MDQzQlx1MDQ0M1x1MDQ0N1x1MDQzNVx1MDQzRFx1MDQzRSAke3BhcnNlZFR5cGUoaXNzdWUuaW5wdXQpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF92YWx1ZVwiOlxuICAgICAgICAgICAgICAgIGlmIChpc3N1ZS52YWx1ZXMubGVuZ3RoID09PSAxKSByZXR1cm4gYFx1MDQxRFx1MDQzNVx1MDQzMlx1MDQzNVx1MDQ0MFx1MDQzRFx1MDQ0Qlx1MDQzOSBcdTA0MzJcdTA0MzJcdTA0M0VcdTA0MzQ6IFx1MDQzRVx1MDQzNlx1MDQzOFx1MDQzNFx1MDQzMFx1MDQzQlx1MDQzRVx1MDQ0MVx1MDQ0QyAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDQxRFx1MDQzNVx1MDQzMlx1MDQzNVx1MDQ0MFx1MDQzRFx1MDQ0Qlx1MDQzOSBcdTA0MzJcdTA0MzBcdTA0NDBcdTA0MzhcdTA0MzBcdTA0M0RcdTA0NDI6IFx1MDQzRVx1MDQzNlx1MDQzOFx1MDQzNFx1MDQzMFx1MDQzQlx1MDQzRVx1MDQ0MVx1MDQ0QyBcdTA0M0VcdTA0MzRcdTA0M0RcdTA0M0UgXHUwNDM4XHUwNDM3ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLnZhbHVlcywgXCJ8XCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwidG9vX2JpZ1wiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI8PVwiIDogXCI8XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtYXhWYWx1ZSA9IE51bWJlcihpc3N1ZS5tYXhpbXVtKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVuaXQgPSBnZXRSdXNzaWFuUGx1cmFsKG1heFZhbHVlLCBzaXppbmcudW5pdC5vbmUsIHNpemluZy51bml0LmZldywgc2l6aW5nLnVuaXQubWFueSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDQyMVx1MDQzQlx1MDQzOFx1MDQ0OFx1MDQzQVx1MDQzRVx1MDQzQyBcdTA0MzFcdTA0M0VcdTA0M0JcdTA0NENcdTA0NDhcdTA0M0VcdTA0MzUgXHUwNDM3XHUwNDNEXHUwNDMwXHUwNDQ3XHUwNDM1XHUwNDNEXHUwNDM4XHUwNDM1OiBcdTA0M0VcdTA0MzZcdTA0MzhcdTA0MzRcdTA0MzBcdTA0M0JcdTA0M0VcdTA0NDFcdTA0NEMsIFx1MDQ0N1x1MDQ0Mlx1MDQzRSAke2lzc3VlLm9yaWdpbiA/PyBcIlx1MDQzN1x1MDQzRFx1MDQzMFx1MDQ0N1x1MDQzNVx1MDQzRFx1MDQzOFx1MDQzNVwifSBcdTA0MzFcdTA0NDNcdTA0MzRcdTA0MzVcdTA0NDIgXHUwNDM4XHUwNDNDXHUwNDM1XHUwNDQyXHUwNDRDICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke3VuaXR9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDQyMVx1MDQzQlx1MDQzOFx1MDQ0OFx1MDQzQVx1MDQzRVx1MDQzQyBcdTA0MzFcdTA0M0VcdTA0M0JcdTA0NENcdTA0NDhcdTA0M0VcdTA0MzUgXHUwNDM3XHUwNDNEXHUwNDMwXHUwNDQ3XHUwNDM1XHUwNDNEXHUwNDM4XHUwNDM1OiBcdTA0M0VcdTA0MzZcdTA0MzhcdTA0MzRcdTA0MzBcdTA0M0JcdTA0M0VcdTA0NDFcdTA0NEMsIFx1MDQ0N1x1MDQ0Mlx1MDQzRSAke2lzc3VlLm9yaWdpbiA/PyBcIlx1MDQzN1x1MDQzRFx1MDQzMFx1MDQ0N1x1MDQzNVx1MDQzRFx1MDQzOFx1MDQzNVwifSBcdTA0MzFcdTA0NDNcdTA0MzRcdTA0MzVcdTA0NDIgJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIj49XCIgOiBcIj5cIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1pblZhbHVlID0gTnVtYmVyKGlzc3VlLm1pbmltdW0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5pdCA9IGdldFJ1c3NpYW5QbHVyYWwobWluVmFsdWUsIHNpemluZy51bml0Lm9uZSwgc2l6aW5nLnVuaXQuZmV3LCBzaXppbmcudW5pdC5tYW55KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNDIxXHUwNDNCXHUwNDM4XHUwNDQ4XHUwNDNBXHUwNDNFXHUwNDNDIFx1MDQzQ1x1MDQzMFx1MDQzQlx1MDQzNVx1MDQzRFx1MDQ0Q1x1MDQzQVx1MDQzRVx1MDQzNSBcdTA0MzdcdTA0M0RcdTA0MzBcdTA0NDdcdTA0MzVcdTA0M0RcdTA0MzhcdTA0MzU6IFx1MDQzRVx1MDQzNlx1MDQzOFx1MDQzNFx1MDQzMFx1MDQzQlx1MDQzRVx1MDQ0MVx1MDQ0QywgXHUwNDQ3XHUwNDQyXHUwNDNFICR7aXNzdWUub3JpZ2lufSBcdTA0MzFcdTA0NDNcdTA0MzRcdTA0MzVcdTA0NDIgXHUwNDM4XHUwNDNDXHUwNDM1XHUwNDQyXHUwNDRDICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3VuaXR9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDQyMVx1MDQzQlx1MDQzOFx1MDQ0OFx1MDQzQVx1MDQzRVx1MDQzQyBcdTA0M0NcdTA0MzBcdTA0M0JcdTA0MzVcdTA0M0RcdTA0NENcdTA0M0FcdTA0M0VcdTA0MzUgXHUwNDM3XHUwNDNEXHUwNDMwXHUwNDQ3XHUwNDM1XHUwNDNEXHUwNDM4XHUwNDM1OiBcdTA0M0VcdTA0MzZcdTA0MzhcdTA0MzRcdTA0MzBcdTA0M0JcdTA0M0VcdTA0NDFcdTA0NEMsIFx1MDQ0N1x1MDQ0Mlx1MDQzRSAke2lzc3VlLm9yaWdpbn0gXHUwNDMxXHUwNDQzXHUwNDM0XHUwNDM1XHUwNDQyICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZm9ybWF0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBfaXNzdWUgPSBpc3N1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwic3RhcnRzX3dpdGhcIikgcmV0dXJuIGBcdTA0MURcdTA0MzVcdTA0MzJcdTA0MzVcdTA0NDBcdTA0M0RcdTA0MzBcdTA0NEYgXHUwNDQxXHUwNDQyXHUwNDQwXHUwNDNFXHUwNDNBXHUwNDMwOiBcdTA0MzRcdTA0M0VcdTA0M0JcdTA0MzZcdTA0M0RcdTA0MzAgXHUwNDNEXHUwNDMwXHUwNDQ3XHUwNDM4XHUwNDNEXHUwNDMwXHUwNDQyXHUwNDRDXHUwNDQxXHUwNDRGIFx1MDQ0MSBcIiR7X2lzc3VlLnByZWZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYFx1MDQxRFx1MDQzNVx1MDQzMlx1MDQzNVx1MDQ0MFx1MDQzRFx1MDQzMFx1MDQ0RiBcdTA0NDFcdTA0NDJcdTA0NDBcdTA0M0VcdTA0M0FcdTA0MzA6IFx1MDQzNFx1MDQzRVx1MDQzQlx1MDQzNlx1MDQzRFx1MDQzMCBcdTA0MzdcdTA0MzBcdTA0M0FcdTA0MzBcdTA0M0RcdTA0NDdcdTA0MzhcdTA0MzJcdTA0MzBcdTA0NDJcdTA0NENcdTA0NDFcdTA0NEYgXHUwNDNEXHUwNDMwIFwiJHtfaXNzdWUuc3VmZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBcdTA0MURcdTA0MzVcdTA0MzJcdTA0MzVcdTA0NDBcdTA0M0RcdTA0MzBcdTA0NEYgXHUwNDQxXHUwNDQyXHUwNDQwXHUwNDNFXHUwNDNBXHUwNDMwOiBcdTA0MzRcdTA0M0VcdTA0M0JcdTA0MzZcdTA0M0RcdTA0MzAgXHUwNDQxXHUwNDNFXHUwNDM0XHUwNDM1XHUwNDQwXHUwNDM2XHUwNDMwXHUwNDQyXHUwNDRDIFwiJHtfaXNzdWUuaW5jbHVkZXN9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYFx1MDQxRFx1MDQzNVx1MDQzMlx1MDQzNVx1MDQ0MFx1MDQzRFx1MDQzMFx1MDQ0RiBcdTA0NDFcdTA0NDJcdTA0NDBcdTA0M0VcdTA0M0FcdTA0MzA6IFx1MDQzNFx1MDQzRVx1MDQzQlx1MDQzNlx1MDQzRFx1MDQzMCBcdTA0NDFcdTA0M0VcdTA0M0VcdTA0NDJcdTA0MzJcdTA0MzVcdTA0NDJcdTA0NDFcdTA0NDJcdTA0MzJcdTA0M0VcdTA0MzJcdTA0MzBcdTA0NDJcdTA0NEMgXHUwNDQ4XHUwNDMwXHUwNDMxXHUwNDNCXHUwNDNFXHUwNDNEXHUwNDQzICR7X2lzc3VlLnBhdHRlcm59YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MURcdTA0MzVcdTA0MzJcdTA0MzVcdTA0NDBcdTA0M0RcdTA0NEJcdTA0MzkgJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MURcdTA0MzVcdTA0MzJcdTA0MzVcdTA0NDBcdTA0M0RcdTA0M0VcdTA0MzUgXHUwNDQ3XHUwNDM4XHUwNDQxXHUwNDNCXHUwNDNFOiBcdTA0MzRcdTA0M0VcdTA0M0JcdTA0MzZcdTA0M0RcdTA0M0UgXHUwNDMxXHUwNDRCXHUwNDQyXHUwNDRDIFx1MDQzQVx1MDQ0MFx1MDQzMFx1MDQ0Mlx1MDQzRFx1MDQ0Qlx1MDQzQyAke2lzc3VlLmRpdmlzb3J9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ1bnJlY29nbml6ZWRfa2V5c1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNDFEXHUwNDM1XHUwNDQwXHUwNDMwXHUwNDQxXHUwNDNGXHUwNDNFXHUwNDM3XHUwNDNEXHUwNDMwXHUwNDNEXHUwNDNEJHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcIlx1MDQ0Qlx1MDQzNVwiIDogXCJcdTA0NEJcdTA0MzlcIn0gXHUwNDNBXHUwNDNCXHUwNDRFXHUwNDQ3JHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcIlx1MDQzOFwiIDogXCJcIn06ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLmtleXMsIFwiLCBcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2tleVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNDFEXHUwNDM1XHUwNDMyXHUwNDM1XHUwNDQwXHUwNDNEXHUwNDRCXHUwNDM5IFx1MDQzQVx1MDQzQlx1MDQ0RVx1MDQ0NyBcdTA0MzIgJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3VuaW9uXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiXHUwNDFEXHUwNDM1XHUwNDMyXHUwNDM1XHUwNDQwXHUwNDNEXHUwNDRCXHUwNDM1IFx1MDQzMlx1MDQ0NVx1MDQzRVx1MDQzNFx1MDQzRFx1MDQ0Qlx1MDQzNSBcdTA0MzRcdTA0MzBcdTA0M0RcdTA0M0RcdTA0NEJcdTA0MzVcIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDQxRFx1MDQzNVx1MDQzMlx1MDQzNVx1MDQ0MFx1MDQzRFx1MDQzRVx1MDQzNSBcdTA0MzdcdTA0M0RcdTA0MzBcdTA0NDdcdTA0MzVcdTA0M0RcdTA0MzhcdTA0MzUgXHUwNDMyICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNDFEXHUwNDM1XHUwNDMyXHUwNDM1XHUwNDQwXHUwNDNEXHUwNDRCXHUwNDM1IFx1MDQzMlx1MDQ0NVx1MDQzRVx1MDQzNFx1MDQzRFx1MDQ0Qlx1MDQzNSBcdTA0MzRcdTA0MzBcdTA0M0RcdTA0M0RcdTA0NEJcdTA0MzVgO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBsb2NhbGVFcnJvcjogZXJyb3IoKVxuICAgIH07XG59XG4iLCAiaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi4vY29yZS91dGlsLmpzXCI7XG5jb25zdCBlcnJvciA9ICgpPT57XG4gICAgY29uc3QgU2l6YWJsZSA9IHtcbiAgICAgICAgc3RyaW5nOiB7XG4gICAgICAgICAgICB1bml0OiBcInpuYWtvdlwiLFxuICAgICAgICAgICAgdmVyYjogXCJpbWV0aVwiXG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiYmFqdG92XCIsXG4gICAgICAgICAgICB2ZXJiOiBcImltZXRpXCJcbiAgICAgICAgfSxcbiAgICAgICAgYXJyYXk6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiZWxlbWVudG92XCIsXG4gICAgICAgICAgICB2ZXJiOiBcImltZXRpXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcImVsZW1lbnRvdlwiLFxuICAgICAgICAgICAgdmVyYjogXCJpbWV0aVwiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4pIHtcbiAgICAgICAgcmV0dXJuIFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWRUeXBlID0gKGRhdGEpPT57XG4gICAgICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICAgICAgc3dpdGNoKHQpe1xuICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIlx1MDE2MXRldmlsb1wiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJ0YWJlbGFcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YoZGF0YSkgIT09IE9iamVjdC5wcm90b3R5cGUgJiYgZGF0YS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdDtcbiAgICB9O1xuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJ2bm9zXCIsXG4gICAgICAgIGVtYWlsOiBcImUtcG9cdTAxNjF0bmkgbmFzbG92XCIsXG4gICAgICAgIHVybDogXCJVUkxcIixcbiAgICAgICAgZW1vamk6IFwiZW1vamlcIixcbiAgICAgICAgdXVpZDogXCJVVUlEXCIsXG4gICAgICAgIHV1aWR2NDogXCJVVUlEdjRcIixcbiAgICAgICAgdXVpZHY2OiBcIlVVSUR2NlwiLFxuICAgICAgICBuYW5vaWQ6IFwibmFub2lkXCIsXG4gICAgICAgIGd1aWQ6IFwiR1VJRFwiLFxuICAgICAgICBjdWlkOiBcImN1aWRcIixcbiAgICAgICAgY3VpZDI6IFwiY3VpZDJcIixcbiAgICAgICAgdWxpZDogXCJVTElEXCIsXG4gICAgICAgIHhpZDogXCJYSURcIixcbiAgICAgICAga3N1aWQ6IFwiS1NVSURcIixcbiAgICAgICAgZGF0ZXRpbWU6IFwiSVNPIGRhdHVtIGluIFx1MDEwRGFzXCIsXG4gICAgICAgIGRhdGU6IFwiSVNPIGRhdHVtXCIsXG4gICAgICAgIHRpbWU6IFwiSVNPIFx1MDEwRGFzXCIsXG4gICAgICAgIGR1cmF0aW9uOiBcIklTTyB0cmFqYW5qZVwiLFxuICAgICAgICBpcHY0OiBcIklQdjQgbmFzbG92XCIsXG4gICAgICAgIGlwdjY6IFwiSVB2NiBuYXNsb3ZcIixcbiAgICAgICAgY2lkcnY0OiBcIm9ic2VnIElQdjRcIixcbiAgICAgICAgY2lkcnY2OiBcIm9ic2VnIElQdjZcIixcbiAgICAgICAgYmFzZTY0OiBcImJhc2U2NCBrb2RpcmFuIG5pelwiLFxuICAgICAgICBiYXNlNjR1cmw6IFwiYmFzZTY0dXJsIGtvZGlyYW4gbml6XCIsXG4gICAgICAgIGpzb25fc3RyaW5nOiBcIkpTT04gbml6XCIsXG4gICAgICAgIGUxNjQ6IFwiRS4xNjQgXHUwMTYxdGV2aWxrYVwiLFxuICAgICAgICBqd3Q6IFwiSldUXCIsXG4gICAgICAgIHRlbXBsYXRlX2xpdGVyYWw6IFwidm5vc1wiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOZXZlbGphdmVuIHZub3M6IHByaVx1MDEwRGFrb3Zhbm8gJHtpc3N1ZS5leHBlY3RlZH0sIHByZWpldG8gJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBOZXZlbGphdmVuIHZub3M6IHByaVx1MDEwRGFrb3Zhbm8gJHt1dGlsLnN0cmluZ2lmeVByaW1pdGl2ZShpc3N1ZS52YWx1ZXNbMF0pfWA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOZXZlbGphdm5hIG1vXHUwMTdFbm9zdDogcHJpXHUwMTBEYWtvdmFubyBlbm8gaXptZWQgJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIjw9XCIgOiBcIjxcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgUHJldmVsaWtvOiBwcmlcdTAxMERha292YW5vLCBkYSBibyAke2lzc3VlLm9yaWdpbiA/PyBcInZyZWRub3N0XCJ9IGltZWxvICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0ID8/IFwiZWxlbWVudG92XCJ9YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBQcmV2ZWxpa286IHByaVx1MDEwRGFrb3Zhbm8sIGRhIGJvICR7aXNzdWUub3JpZ2luID8/IFwidnJlZG5vc3RcIn0gJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIj49XCIgOiBcIj5cIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgUHJlbWFqaG5vOiBwcmlcdTAxMERha292YW5vLCBkYSBibyAke2lzc3VlLm9yaWdpbn0gaW1lbG8gJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXR9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFByZW1hamhubzogcHJpXHUwMTBEYWtvdmFubywgZGEgYm8gJHtpc3N1ZS5vcmlnaW59ICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZm9ybWF0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBfaXNzdWUgPSBpc3N1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwic3RhcnRzX3dpdGhcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBOZXZlbGphdmVuIG5pejogbW9yYSBzZSB6YVx1MDEwRGV0aSB6IFwiJHtfaXNzdWUucHJlZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJlbmRzX3dpdGhcIikgcmV0dXJuIGBOZXZlbGphdmVuIG5pejogbW9yYSBzZSBrb25cdTAxMERhdGkgeiBcIiR7X2lzc3VlLnN1ZmZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImluY2x1ZGVzXCIpIHJldHVybiBgTmV2ZWxqYXZlbiBuaXo6IG1vcmEgdnNlYm92YXRpIFwiJHtfaXNzdWUuaW5jbHVkZXN9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYE5ldmVsamF2ZW4gbml6OiBtb3JhIHVzdHJlemF0aSB2em9yY3UgJHtfaXNzdWUucGF0dGVybn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYE5ldmVsamF2ZW4gJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOZXZlbGphdm5vIFx1MDE2MXRldmlsbzogbW9yYSBiaXRpIHZlXHUwMTBEa3JhdG5payAke2lzc3VlLmRpdmlzb3J9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ1bnJlY29nbml6ZWRfa2V5c1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgTmVwcmVwb3puYW4ke2lzc3VlLmtleXMubGVuZ3RoID4gMSA/IFwiaSBrbGp1XHUwMTBEaVwiIDogXCIga2xqdVx1MDEwRFwifTogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgXCIsIFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfa2V5XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOZXZlbGphdmVuIGtsanVcdTAxMEQgdiAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJOZXZlbGphdmVuIHZub3NcIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYE5ldmVsamF2bmEgdnJlZG5vc3QgdiAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJOZXZlbGphdmVuIHZub3NcIjtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJ0ZWNrZW5cIixcbiAgICAgICAgICAgIHZlcmI6IFwiYXR0IGhhXCJcbiAgICAgICAgfSxcbiAgICAgICAgZmlsZToge1xuICAgICAgICAgICAgdW5pdDogXCJieXRlc1wiLFxuICAgICAgICAgICAgdmVyYjogXCJhdHQgaGFcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJvYmpla3RcIixcbiAgICAgICAgICAgIHZlcmI6IFwiYXR0IGlubmVoXHUwMEU1bGxhXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcIm9iamVrdFwiLFxuICAgICAgICAgICAgdmVyYjogXCJhdHQgaW5uZWhcdTAwRTVsbGFcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIk5hTlwiIDogXCJhbnRhbFwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJsaXN0YVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJudWxsXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcInJlZ3Vsalx1MDBFNHJ0IHV0dHJ5Y2tcIixcbiAgICAgICAgZW1haWw6IFwiZS1wb3N0YWRyZXNzXCIsXG4gICAgICAgIHVybDogXCJVUkxcIixcbiAgICAgICAgZW1vamk6IFwiZW1vamlcIixcbiAgICAgICAgdXVpZDogXCJVVUlEXCIsXG4gICAgICAgIHV1aWR2NDogXCJVVUlEdjRcIixcbiAgICAgICAgdXVpZHY2OiBcIlVVSUR2NlwiLFxuICAgICAgICBuYW5vaWQ6IFwibmFub2lkXCIsXG4gICAgICAgIGd1aWQ6IFwiR1VJRFwiLFxuICAgICAgICBjdWlkOiBcImN1aWRcIixcbiAgICAgICAgY3VpZDI6IFwiY3VpZDJcIixcbiAgICAgICAgdWxpZDogXCJVTElEXCIsXG4gICAgICAgIHhpZDogXCJYSURcIixcbiAgICAgICAga3N1aWQ6IFwiS1NVSURcIixcbiAgICAgICAgZGF0ZXRpbWU6IFwiSVNPLWRhdHVtIG9jaCB0aWRcIixcbiAgICAgICAgZGF0ZTogXCJJU08tZGF0dW1cIixcbiAgICAgICAgdGltZTogXCJJU08tdGlkXCIsXG4gICAgICAgIGR1cmF0aW9uOiBcIklTTy12YXJha3RpZ2hldFwiLFxuICAgICAgICBpcHY0OiBcIklQdjQtaW50ZXJ2YWxsXCIsXG4gICAgICAgIGlwdjY6IFwiSVB2Ni1pbnRlcnZhbGxcIixcbiAgICAgICAgY2lkcnY0OiBcIklQdjQtc3Bla3RydW1cIixcbiAgICAgICAgY2lkcnY2OiBcIklQdjYtc3Bla3RydW1cIixcbiAgICAgICAgYmFzZTY0OiBcImJhc2U2NC1rb2RhZCBzdHJcdTAwRTRuZ1wiLFxuICAgICAgICBiYXNlNjR1cmw6IFwiYmFzZTY0dXJsLWtvZGFkIHN0clx1MDBFNG5nXCIsXG4gICAgICAgIGpzb25fc3RyaW5nOiBcIkpTT04tc3RyXHUwMEU0bmdcIixcbiAgICAgICAgZTE2NDogXCJFLjE2NC1udW1tZXJcIixcbiAgICAgICAgand0OiBcIkpXVFwiLFxuICAgICAgICB0ZW1wbGF0ZV9saXRlcmFsOiBcIm1hbGwtbGl0ZXJhbFwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBPZ2lsdGlnIGlubWF0bmluZzogZlx1MDBGNnJ2XHUwMEU0bnRhdCAke2lzc3VlLmV4cGVjdGVkfSwgZmljayAke3BhcnNlZFR5cGUoaXNzdWUuaW5wdXQpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF92YWx1ZVwiOlxuICAgICAgICAgICAgICAgIGlmIChpc3N1ZS52YWx1ZXMubGVuZ3RoID09PSAxKSByZXR1cm4gYE9naWx0aWcgaW5tYXRuaW5nOiBmXHUwMEY2cnZcdTAwRTRudGF0ICR7dXRpbC5zdHJpbmdpZnlQcmltaXRpdmUoaXNzdWUudmFsdWVzWzBdKX1gO1xuICAgICAgICAgICAgICAgIHJldHVybiBgT2dpbHRpZ3QgdmFsOiBmXHUwMEY2cnZcdTAwRTRudGFkZSBlbiBhdiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS52YWx1ZXMsIFwifFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPD1cIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBGXHUwMEY2ciBzdG9yKHQpOiBmXHUwMEY2cnZcdTAwRTRudGFkZSAke2lzc3VlLm9yaWdpbiA/PyBcInZcdTAwRTRyZGV0XCJ9IGF0dCBoYSAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdCA/PyBcImVsZW1lbnRcIn1gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgRlx1MDBGNnIgc3Rvcih0KTogZlx1MDBGNnJ2XHUwMEU0bnRhdCAke2lzc3VlLm9yaWdpbiA/PyBcInZcdTAwRTRyZGV0XCJ9IGF0dCBoYSAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJ0b29fc21hbGxcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPj1cIiA6IFwiPlwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBGXHUwMEY2ciBsaXRlKHQpOiBmXHUwMEY2cnZcdTAwRTRudGFkZSAke2lzc3VlLm9yaWdpbiA/PyBcInZcdTAwRTRyZGV0XCJ9IGF0dCBoYSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdH1gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgRlx1MDBGNnIgbGl0ZSh0KTogZlx1MDBGNnJ2XHUwMEU0bnRhZGUgJHtpc3N1ZS5vcmlnaW4gPz8gXCJ2XHUwMEU0cmRldFwifSBhdHQgaGEgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYE9naWx0aWcgc3RyXHUwMEU0bmc6IG1cdTAwRTVzdGUgYlx1MDBGNnJqYSBtZWQgXCIke19pc3N1ZS5wcmVmaXh9XCJgO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYE9naWx0aWcgc3RyXHUwMEU0bmc6IG1cdTAwRTVzdGUgc2x1dGEgbWVkIFwiJHtfaXNzdWUuc3VmZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBPZ2lsdGlnIHN0clx1MDBFNG5nOiBtXHUwMEU1c3RlIGlubmVoXHUwMEU1bGxhIFwiJHtfaXNzdWUuaW5jbHVkZXN9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYE9naWx0aWcgc3RyXHUwMEU0bmc6IG1cdTAwRTVzdGUgbWF0Y2hhIG1cdTAwRjZuc3RyZXQgXCIke19pc3N1ZS5wYXR0ZXJufVwiYDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBPZ2lsdGlnKHQpICR7Tm91bnNbX2lzc3VlLmZvcm1hdF0gPz8gaXNzdWUuZm9ybWF0fWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm5vdF9tdWx0aXBsZV9vZlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgT2dpbHRpZ3QgdGFsOiBtXHUwMEU1c3RlIHZhcmEgZW4gbXVsdGlwZWwgYXYgJHtpc3N1ZS5kaXZpc29yfWA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYCR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJPa1x1MDBFNG5kYSBueWNrbGFyXCIgOiBcIk9rXHUwMEU0bmQgbnlja2VsXCJ9OiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIiwgXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYE9naWx0aWcgbnlja2VsIGkgJHtpc3N1ZS5vcmlnaW4gPz8gXCJ2XHUwMEU0cmRldFwifWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF91bmlvblwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIk9naWx0aWcgaW5wdXRcIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYE9naWx0aWd0IHZcdTAwRTRyZGUgaSAke2lzc3VlLm9yaWdpbiA/PyBcInZcdTAwRTRyZGV0XCJ9YDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBPZ2lsdGlnIGlucHV0YDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJcdTBCOEVcdTBCQjRcdTBCQzFcdTBCQTRcdTBCQ0RcdTBCQTRcdTBCQzFcdTBCOTVcdTBCQ0RcdTBCOTVcdTBCQjNcdTBCQ0RcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwQjk1XHUwQkNBXHUwQkEzXHUwQkNEXHUwQjlGXHUwQkJGXHUwQkIwXHUwQkMxXHUwQjk1XHUwQkNEXHUwQjk1IFx1MEJCNVx1MEJDN1x1MEJBM1x1MEJDRFx1MEI5Rlx1MEJDMVx1MEJBRVx1MEJDRFwiXG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHUwQkFBXHUwQkM4XHUwQjlGXHUwQkNEXHUwQjlGXHUwQkMxXHUwQjk1XHUwQkIzXHUwQkNEXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MEI5NVx1MEJDQVx1MEJBM1x1MEJDRFx1MEI5Rlx1MEJCRlx1MEJCMFx1MEJDMVx1MEI5NVx1MEJDRFx1MEI5NSBcdTBCQjVcdTBCQzdcdTBCQTNcdTBCQ0RcdTBCOUZcdTBCQzFcdTBCQUVcdTBCQ0RcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJcdTBCODlcdTBCQjFcdTBCQzFcdTBCQUFcdTBCQ0RcdTBCQUFcdTBCQzFcdTBCOTVcdTBCQjNcdTBCQ0RcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwQjk1XHUwQkNBXHUwQkEzXHUwQkNEXHUwQjlGXHUwQkJGXHUwQkIwXHUwQkMxXHUwQjk1XHUwQkNEXHUwQjk1IFx1MEJCNVx1MEJDN1x1MEJBM1x1MEJDRFx1MEI5Rlx1MEJDMVx1MEJBRVx1MEJDRFwiXG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDogXCJcdTBCODlcdTBCQjFcdTBCQzFcdTBCQUFcdTBCQ0RcdTBCQUFcdTBCQzFcdTBCOTVcdTBCQjNcdTBCQ0RcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwQjk1XHUwQkNBXHUwQkEzXHUwQkNEXHUwQjlGXHUwQkJGXHUwQkIwXHUwQkMxXHUwQjk1XHUwQkNEXHUwQjk1IFx1MEJCNVx1MEJDN1x1MEJBM1x1MEJDRFx1MEI5Rlx1MEJDMVx1MEJBRVx1MEJDRFwiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4pIHtcbiAgICAgICAgcmV0dXJuIFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWRUeXBlID0gKGRhdGEpPT57XG4gICAgICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICAgICAgc3dpdGNoKHQpe1xuICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiXHUwQjhFXHUwQkEzXHUwQkNEIFx1MEI4NVx1MEJCMlx1MEJDRFx1MEJCMlx1MEJCRVx1MEJBNFx1MEJBNFx1MEJDMVwiIDogXCJcdTBCOEVcdTBCQTNcdTBCQ0RcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiXHUwQjg1XHUwQkEzXHUwQkJGXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGEgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIlx1MEJCNVx1MEJDNlx1MEJCMVx1MEJDMVx1MEJBRVx1MEJDOFwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YoZGF0YSkgIT09IE9iamVjdC5wcm90b3R5cGUgJiYgZGF0YS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdDtcbiAgICB9O1xuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJcdTBCODlcdTBCQjNcdTBCQ0RcdTBCQjNcdTBCQzBcdTBCOUZcdTBCQzFcIixcbiAgICAgICAgZW1haWw6IFwiXHUwQkFFXHUwQkJGXHUwQkE5XHUwQkNEXHUwQkE5XHUwQjlFXHUwQkNEXHUwQjlBXHUwQkIyXHUwQkNEIFx1MEJBRVx1MEJDMVx1MEI5NVx1MEJCNVx1MEJCMFx1MEJCRlwiLFxuICAgICAgICB1cmw6IFwiVVJMXCIsXG4gICAgICAgIGVtb2ppOiBcImVtb2ppXCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcIklTTyBcdTBCQTRcdTBCQzdcdTBCQTRcdTBCQkYgXHUwQkE4XHUwQkM3XHUwQkIwXHUwQkFFXHUwQkNEXCIsXG4gICAgICAgIGRhdGU6IFwiSVNPIFx1MEJBNFx1MEJDN1x1MEJBNFx1MEJCRlwiLFxuICAgICAgICB0aW1lOiBcIklTTyBcdTBCQThcdTBCQzdcdTBCQjBcdTBCQUVcdTBCQ0RcIixcbiAgICAgICAgZHVyYXRpb246IFwiSVNPIFx1MEI5NVx1MEJCRVx1MEJCMiBcdTBCODVcdTBCQjNcdTBCQjVcdTBCQzFcIixcbiAgICAgICAgaXB2NDogXCJJUHY0IFx1MEJBRVx1MEJDMVx1MEI5NVx1MEJCNVx1MEJCMFx1MEJCRlwiLFxuICAgICAgICBpcHY2OiBcIklQdjYgXHUwQkFFXHUwQkMxXHUwQjk1XHUwQkI1XHUwQkIwXHUwQkJGXCIsXG4gICAgICAgIGNpZHJ2NDogXCJJUHY0IFx1MEJCNVx1MEJCMFx1MEJBRVx1MEJDRFx1MEJBQVx1MEJDMVwiLFxuICAgICAgICBjaWRydjY6IFwiSVB2NiBcdTBCQjVcdTBCQjBcdTBCQUVcdTBCQ0RcdTBCQUFcdTBCQzFcIixcbiAgICAgICAgYmFzZTY0OiBcImJhc2U2NC1lbmNvZGVkIFx1MEI5QVx1MEJCMFx1MEJBRVx1MEJDRFwiLFxuICAgICAgICBiYXNlNjR1cmw6IFwiYmFzZTY0dXJsLWVuY29kZWQgXHUwQjlBXHUwQkIwXHUwQkFFXHUwQkNEXCIsXG4gICAgICAgIGpzb25fc3RyaW5nOiBcIkpTT04gXHUwQjlBXHUwQkIwXHUwQkFFXHUwQkNEXCIsXG4gICAgICAgIGUxNjQ6IFwiRS4xNjQgXHUwQjhFXHUwQkEzXHUwQkNEXCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJpbnB1dFwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTBCQTRcdTBCQjVcdTBCQjFcdTBCQkVcdTBCQTkgXHUwQjg5XHUwQkIzXHUwQkNEXHUwQkIzXHUwQkMwXHUwQjlGXHUwQkMxOiBcdTBCOEVcdTBCQTRcdTBCQkZcdTBCQjBcdTBCQ0RcdTBCQUFcdTBCQkVcdTBCQjBcdTBCQ0RcdTBCOTVcdTBCQ0RcdTBCOTVcdTBCQUFcdTBCQ0RcdTBCQUFcdTBCOUZcdTBCQ0RcdTBCOUZcdTBCQTRcdTBCQzEgJHtpc3N1ZS5leHBlY3RlZH0sIFx1MEJBQVx1MEJDNlx1MEJCMVx1MEJBQVx1MEJDRFx1MEJBQVx1MEI5Rlx1MEJDRFx1MEI5Rlx1MEJBNFx1MEJDMSAke3BhcnNlZFR5cGUoaXNzdWUuaW5wdXQpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF92YWx1ZVwiOlxuICAgICAgICAgICAgICAgIGlmIChpc3N1ZS52YWx1ZXMubGVuZ3RoID09PSAxKSByZXR1cm4gYFx1MEJBNFx1MEJCNVx1MEJCMVx1MEJCRVx1MEJBOSBcdTBCODlcdTBCQjNcdTBCQ0RcdTBCQjNcdTBCQzBcdTBCOUZcdTBCQzE6IFx1MEI4RVx1MEJBNFx1MEJCRlx1MEJCMFx1MEJDRFx1MEJBQVx1MEJCRVx1MEJCMFx1MEJDRFx1MEI5NVx1MEJDRFx1MEI5NVx1MEJBQVx1MEJDRFx1MEJBQVx1MEI5Rlx1MEJDRFx1MEI5Rlx1MEJBNFx1MEJDMSAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MEJBNFx1MEJCNVx1MEJCMVx1MEJCRVx1MEJBOSBcdTBCQjVcdTBCQkZcdTBCQjBcdTBCQzFcdTBCQUFcdTBCQ0RcdTBCQUFcdTBCQUVcdTBCQ0Q6IFx1MEI4RVx1MEJBNFx1MEJCRlx1MEJCMFx1MEJDRFx1MEJBQVx1MEJCRVx1MEJCMFx1MEJDRFx1MEI5NVx1MEJDRFx1MEI5NVx1MEJBQVx1MEJDRFx1MEJBQVx1MEI5Rlx1MEJDRFx1MEI5Rlx1MEJBNFx1MEJDMSAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS52YWx1ZXMsIFwifFwiKX0gXHUwQjg3XHUwQkIyXHUwQkNEIFx1MEI5Mlx1MEJBOVx1MEJDRFx1MEJCMVx1MEJDMWA7XG4gICAgICAgICAgICBjYXNlIFwidG9vX2JpZ1wiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI8PVwiIDogXCI8XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MEJBRVx1MEJCRlx1MEI5NSBcdTBCQUFcdTBCQzZcdTBCQjBcdTBCQkZcdTBCQUZcdTBCQTRcdTBCQzE6IFx1MEI4RVx1MEJBNFx1MEJCRlx1MEJCMFx1MEJDRFx1MEJBQVx1MEJCRVx1MEJCMFx1MEJDRFx1MEI5NVx1MEJDRFx1MEI5NVx1MEJBQVx1MEJDRFx1MEJBQVx1MEI5Rlx1MEJDRFx1MEI5Rlx1MEJBNFx1MEJDMSAke2lzc3VlLm9yaWdpbiA/PyBcIlx1MEJBRVx1MEJBNFx1MEJCRlx1MEJBQVx1MEJDRFx1MEJBQVx1MEJDMVwifSAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdCA/PyBcIlx1MEI4OVx1MEJCMVx1MEJDMVx1MEJBQVx1MEJDRFx1MEJBQVx1MEJDMVx1MEI5NVx1MEJCM1x1MEJDRFwifSBcdTBCODZcdTBCOTUgXHUwQjg3XHUwQkIwXHUwQkMxXHUwQjk1XHUwQkNEXHUwQjk1IFx1MEJCNVx1MEJDN1x1MEJBM1x1MEJDRFx1MEI5Rlx1MEJDMVx1MEJBRVx1MEJDRGA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTBCQUVcdTBCQkZcdTBCOTUgXHUwQkFBXHUwQkM2XHUwQkIwXHUwQkJGXHUwQkFGXHUwQkE0XHUwQkMxOiBcdTBCOEVcdTBCQTRcdTBCQkZcdTBCQjBcdTBCQ0RcdTBCQUFcdTBCQkVcdTBCQjBcdTBCQ0RcdTBCOTVcdTBCQ0RcdTBCOTVcdTBCQUFcdTBCQ0RcdTBCQUFcdTBCOUZcdTBCQ0RcdTBCOUZcdTBCQTRcdTBCQzEgJHtpc3N1ZS5vcmlnaW4gPz8gXCJcdTBCQUVcdTBCQTRcdTBCQkZcdTBCQUFcdTBCQ0RcdTBCQUFcdTBCQzFcIn0gJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9IFx1MEI4Nlx1MEI5NSBcdTBCODdcdTBCQjBcdTBCQzFcdTBCOTVcdTBCQ0RcdTBCOTUgXHUwQkI1XHUwQkM3XHUwQkEzXHUwQkNEXHUwQjlGXHUwQkMxXHUwQkFFXHUwQkNEYDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIj49XCIgOiBcIj5cIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwQkFFXHUwQkJGXHUwQjk1XHUwQjlBXHUwQkNEIFx1MEI5QVx1MEJCRlx1MEJCMVx1MEJCRlx1MEJBRlx1MEJBNFx1MEJDMTogXHUwQjhFXHUwQkE0XHUwQkJGXHUwQkIwXHUwQkNEXHUwQkFBXHUwQkJFXHUwQkIwXHUwQkNEXHUwQjk1XHUwQkNEXHUwQjk1XHUwQkFBXHUwQkNEXHUwQkFBXHUwQjlGXHUwQkNEXHUwQjlGXHUwQkE0XHUwQkMxICR7aXNzdWUub3JpZ2lufSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdH0gXHUwQjg2XHUwQjk1IFx1MEI4N1x1MEJCMFx1MEJDMVx1MEI5NVx1MEJDRFx1MEI5NSBcdTBCQjVcdTBCQzdcdTBCQTNcdTBCQ0RcdTBCOUZcdTBCQzFcdTBCQUVcdTBCQ0RgOyAvL1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwQkFFXHUwQkJGXHUwQjk1XHUwQjlBXHUwQkNEIFx1MEI5QVx1MEJCRlx1MEJCMVx1MEJCRlx1MEJBRlx1MEJBNFx1MEJDMTogXHUwQjhFXHUwQkE0XHUwQkJGXHUwQkIwXHUwQkNEXHUwQkFBXHUwQkJFXHUwQkIwXHUwQkNEXHUwQjk1XHUwQkNEXHUwQjk1XHUwQkFBXHUwQkNEXHUwQkFBXHUwQjlGXHUwQkNEXHUwQjlGXHUwQkE0XHUwQkMxICR7aXNzdWUub3JpZ2lufSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gXHUwQjg2XHUwQjk1IFx1MEI4N1x1MEJCMFx1MEJDMVx1MEI5NVx1MEJDRFx1MEI5NSBcdTBCQjVcdTBCQzdcdTBCQTNcdTBCQ0RcdTBCOUZcdTBCQzFcdTBCQUVcdTBCQ0RgO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2Zvcm1hdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgX2lzc3VlID0gaXNzdWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInN0YXJ0c193aXRoXCIpIHJldHVybiBgXHUwQkE0XHUwQkI1XHUwQkIxXHUwQkJFXHUwQkE5IFx1MEI5QVx1MEJCMFx1MEJBRVx1MEJDRDogXCIke19pc3N1ZS5wcmVmaXh9XCIgXHUwQjg3XHUwQkIyXHUwQkNEIFx1MEJBNFx1MEJDQVx1MEI5Rlx1MEI5OVx1MEJDRFx1MEI5NSBcdTBCQjVcdTBCQzdcdTBCQTNcdTBCQ0RcdTBCOUZcdTBCQzFcdTBCQUVcdTBCQ0RgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJlbmRzX3dpdGhcIikgcmV0dXJuIGBcdTBCQTRcdTBCQjVcdTBCQjFcdTBCQkVcdTBCQTkgXHUwQjlBXHUwQkIwXHUwQkFFXHUwQkNEOiBcIiR7X2lzc3VlLnN1ZmZpeH1cIiBcdTBCODdcdTBCQjJcdTBCQ0QgXHUwQkFFXHUwQkMxXHUwQjlGXHUwQkJGXHUwQkI1XHUwQjlGXHUwQkM4XHUwQkFGIFx1MEJCNVx1MEJDN1x1MEJBM1x1MEJDRFx1MEI5Rlx1MEJDMVx1MEJBRVx1MEJDRGA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImluY2x1ZGVzXCIpIHJldHVybiBgXHUwQkE0XHUwQkI1XHUwQkIxXHUwQkJFXHUwQkE5IFx1MEI5QVx1MEJCMFx1MEJBRVx1MEJDRDogXCIke19pc3N1ZS5pbmNsdWRlc31cIiBcdTBCOTAgXHUwQjg5XHUwQkIzXHUwQkNEXHUwQkIzXHUwQjlGXHUwQjk1XHUwQkNEXHUwQjk1IFx1MEJCNVx1MEJDN1x1MEJBM1x1MEJDRFx1MEI5Rlx1MEJDMVx1MEJBRVx1MEJDRGA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInJlZ2V4XCIpIHJldHVybiBgXHUwQkE0XHUwQkI1XHUwQkIxXHUwQkJFXHUwQkE5IFx1MEI5QVx1MEJCMFx1MEJBRVx1MEJDRDogJHtfaXNzdWUucGF0dGVybn0gXHUwQkFFXHUwQkMxXHUwQkIxXHUwQkM4XHUwQkFBXHUwQkJFXHUwQjlGXHUwQkNEXHUwQjlGXHUwQkMxXHUwQjlGXHUwQkE5XHUwQkNEIFx1MEJBQVx1MEJDQVx1MEJCMFx1MEJDMVx1MEJBOFx1MEJDRFx1MEJBNCBcdTBCQjVcdTBCQzdcdTBCQTNcdTBCQ0RcdTBCOUZcdTBCQzFcdTBCQUVcdTBCQ0RgO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MEJBNFx1MEJCNVx1MEJCMVx1MEJCRVx1MEJBOSAke05vdW5zW19pc3N1ZS5mb3JtYXRdID8/IGlzc3VlLmZvcm1hdH1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJub3RfbXVsdGlwbGVfb2ZcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MEJBNFx1MEJCNVx1MEJCMVx1MEJCRVx1MEJBOSBcdTBCOEVcdTBCQTNcdTBCQ0Q6ICR7aXNzdWUuZGl2aXNvcn0gXHUwQjg3XHUwQkE5XHUwQkNEIFx1MEJBQVx1MEJCMlx1MEJBRVx1MEJCRVx1MEI5NSBcdTBCODdcdTBCQjBcdTBCQzFcdTBCOTVcdTBCQ0RcdTBCOTUgXHUwQkI1XHUwQkM3XHUwQkEzXHUwQkNEXHUwQjlGXHUwQkMxXHUwQkFFXHUwQkNEYDtcbiAgICAgICAgICAgIGNhc2UgXCJ1bnJlY29nbml6ZWRfa2V5c1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwQjg1XHUwQjlGXHUwQkM4XHUwQkFGXHUwQkJFXHUwQkIzXHUwQkFFXHUwQkNEIFx1MEJBNFx1MEJDNlx1MEJCMFx1MEJCRlx1MEJBRlx1MEJCRVx1MEJBNCBcdTBCQjVcdTBCQkZcdTBCOUFcdTBCQzgke2lzc3VlLmtleXMubGVuZ3RoID4gMSA/IFwiXHUwQjk1XHUwQkIzXHUwQkNEXCIgOiBcIlwifTogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgXCIsIFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfa2V5XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGAke2lzc3VlLm9yaWdpbn0gXHUwQjg3XHUwQkIyXHUwQkNEIFx1MEJBNFx1MEJCNVx1MEJCMVx1MEJCRVx1MEJBOSBcdTBCQjVcdTBCQkZcdTBCOUFcdTBCQzhgO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTBCQTRcdTBCQjVcdTBCQjFcdTBCQkVcdTBCQTkgXHUwQjg5XHUwQkIzXHUwQkNEXHUwQkIzXHUwQkMwXHUwQjlGXHUwQkMxXCI7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9lbGVtZW50XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGAke2lzc3VlLm9yaWdpbn0gXHUwQjg3XHUwQkIyXHUwQkNEIFx1MEJBNFx1MEJCNVx1MEJCMVx1MEJCRVx1MEJBOSBcdTBCQUVcdTBCQTRcdTBCQkZcdTBCQUFcdTBCQ0RcdTBCQUFcdTBCQzFgO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MEJBNFx1MEJCNVx1MEJCMVx1MEJCRVx1MEJBOSBcdTBCODlcdTBCQjNcdTBCQ0RcdTBCQjNcdTBCQzBcdTBCOUZcdTBCQzFgO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBsb2NhbGVFcnJvcjogZXJyb3IoKVxuICAgIH07XG59XG4iLCAiaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi4vY29yZS91dGlsLmpzXCI7XG5jb25zdCBlcnJvciA9ICgpPT57XG4gICAgY29uc3QgU2l6YWJsZSA9IHtcbiAgICAgICAgc3RyaW5nOiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MEUxNVx1MEUzMVx1MEUyN1x1MEUyRFx1MEUzMVx1MEUwMVx1MEUyOVx1MEUyM1wiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTBFMDRcdTBFMjdcdTBFMjNcdTBFMjFcdTBFMzVcIlxuICAgICAgICB9LFxuICAgICAgICBmaWxlOiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MEU0NFx1MEUxQVx1MEUxNVx1MEU0Q1wiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTBFMDRcdTBFMjdcdTBFMjNcdTBFMjFcdTBFMzVcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJcdTBFMjNcdTBFMzJcdTBFMjJcdTBFMDFcdTBFMzJcdTBFMjNcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwRTA0XHUwRTI3XHUwRTIzXHUwRTIxXHUwRTM1XCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MEUyM1x1MEUzMlx1MEUyMlx1MEUwMVx1MEUzMlx1MEUyM1wiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTBFMDRcdTBFMjdcdTBFMjNcdTBFMjFcdTBFMzVcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIlx1MEU0NFx1MEUyMVx1MEU0OFx1MEU0M1x1MEUwQVx1MEU0OFx1MEUxNVx1MEUzMVx1MEUyN1x1MEU0MFx1MEUyNVx1MEUwMiAoTmFOKVwiIDogXCJcdTBFMTVcdTBFMzFcdTBFMjdcdTBFNDBcdTBFMjVcdTBFMDJcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiXHUwRTJEXHUwRTMyXHUwRTIzXHUwRTRDXHUwRTQwXHUwRTIzXHUwRTIyXHUwRTRDIChBcnJheSlcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiXHUwRTQ0XHUwRTIxXHUwRTQ4XHUwRTIxXHUwRTM1XHUwRTA0XHUwRTQ4XHUwRTMyIChudWxsKVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YoZGF0YSkgIT09IE9iamVjdC5wcm90b3R5cGUgJiYgZGF0YS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdDtcbiAgICB9O1xuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJcdTBFMDJcdTBFNDlcdTBFMkRcdTBFMjFcdTBFMzlcdTBFMjVcdTBFMTdcdTBFMzVcdTBFNDhcdTBFMUJcdTBFNDlcdTBFMkRcdTBFMTlcIixcbiAgICAgICAgZW1haWw6IFwiXHUwRTE3XHUwRTM1XHUwRTQ4XHUwRTJEXHUwRTIyXHUwRTM5XHUwRTQ4XHUwRTJEXHUwRTM1XHUwRTQwXHUwRTIxXHUwRTI1XCIsXG4gICAgICAgIHVybDogXCJVUkxcIixcbiAgICAgICAgZW1vamk6IFwiXHUwRTJEXHUwRTM0XHUwRTQyXHUwRTIxXHUwRTA4XHUwRTM0XCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcIlx1MEUyN1x1MEUzMVx1MEUxOVx1MEUxN1x1MEUzNVx1MEU0OFx1MEU0MFx1MEUyN1x1MEUyNVx1MEUzMlx1MEU0MVx1MEUxQVx1MEUxQSBJU09cIixcbiAgICAgICAgZGF0ZTogXCJcdTBFMjdcdTBFMzFcdTBFMTlcdTBFMTdcdTBFMzVcdTBFNDhcdTBFNDFcdTBFMUFcdTBFMUEgSVNPXCIsXG4gICAgICAgIHRpbWU6IFwiXHUwRTQwXHUwRTI3XHUwRTI1XHUwRTMyXHUwRTQxXHUwRTFBXHUwRTFBIElTT1wiLFxuICAgICAgICBkdXJhdGlvbjogXCJcdTBFMEFcdTBFNDhcdTBFMjdcdTBFMDdcdTBFNDBcdTBFMjdcdTBFMjVcdTBFMzJcdTBFNDFcdTBFMUFcdTBFMUEgSVNPXCIsXG4gICAgICAgIGlwdjQ6IFwiXHUwRTE3XHUwRTM1XHUwRTQ4XHUwRTJEXHUwRTIyXHUwRTM5XHUwRTQ4IElQdjRcIixcbiAgICAgICAgaXB2NjogXCJcdTBFMTdcdTBFMzVcdTBFNDhcdTBFMkRcdTBFMjJcdTBFMzlcdTBFNDggSVB2NlwiLFxuICAgICAgICBjaWRydjQ6IFwiXHUwRTBBXHUwRTQ4XHUwRTI3XHUwRTA3IElQIFx1MEU0MVx1MEUxQVx1MEUxQSBJUHY0XCIsXG4gICAgICAgIGNpZHJ2NjogXCJcdTBFMEFcdTBFNDhcdTBFMjdcdTBFMDcgSVAgXHUwRTQxXHUwRTFBXHUwRTFBIElQdjZcIixcbiAgICAgICAgYmFzZTY0OiBcIlx1MEUwMlx1MEU0OVx1MEUyRFx1MEUwNFx1MEUyN1x1MEUzMlx1MEUyMVx1MEU0MVx1MEUxQVx1MEUxQSBCYXNlNjRcIixcbiAgICAgICAgYmFzZTY0dXJsOiBcIlx1MEUwMlx1MEU0OVx1MEUyRFx1MEUwNFx1MEUyN1x1MEUzMlx1MEUyMVx1MEU0MVx1MEUxQVx1MEUxQSBCYXNlNjQgXHUwRTJBXHUwRTMzXHUwRTJCXHUwRTIzXHUwRTMxXHUwRTFBIFVSTFwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJcdTBFMDJcdTBFNDlcdTBFMkRcdTBFMDRcdTBFMjdcdTBFMzJcdTBFMjFcdTBFNDFcdTBFMUFcdTBFMUEgSlNPTlwiLFxuICAgICAgICBlMTY0OiBcIlx1MEU0MFx1MEUxQVx1MEUyRFx1MEUyM1x1MEU0Q1x1MEU0Mlx1MEUxN1x1MEUyM1x1MEUyOFx1MEUzMVx1MEUxRVx1MEUxN1x1MEU0Q1x1MEUyM1x1MEUzMFx1MEUyQlx1MEUyN1x1MEU0OFx1MEUzMlx1MEUwN1x1MEUxQlx1MEUyM1x1MEUzMFx1MEU0MFx1MEUxN1x1MEUyOCAoRS4xNjQpXCIsXG4gICAgICAgIGp3dDogXCJcdTBFNDJcdTBFMTdcdTBFNDBcdTBFMDRcdTBFMTkgSldUXCIsXG4gICAgICAgIHRlbXBsYXRlX2xpdGVyYWw6IFwiXHUwRTAyXHUwRTQ5XHUwRTJEXHUwRTIxXHUwRTM5XHUwRTI1XHUwRTE3XHUwRTM1XHUwRTQ4XHUwRTFCXHUwRTQ5XHUwRTJEXHUwRTE5XCJcbiAgICB9O1xuICAgIHJldHVybiAoaXNzdWUpPT57XG4gICAgICAgIHN3aXRjaChpc3N1ZS5jb2RlKXtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3R5cGVcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MEUxQlx1MEUyM1x1MEUzMFx1MEU0MFx1MEUyMFx1MEUxN1x1MEUwMlx1MEU0OVx1MEUyRFx1MEUyMVx1MEUzOVx1MEUyNVx1MEU0NFx1MEUyMVx1MEU0OFx1MEUxNlx1MEUzOVx1MEUwMVx1MEUxNVx1MEU0OVx1MEUyRFx1MEUwNzogXHUwRTA0XHUwRTI3XHUwRTIzXHUwRTQwXHUwRTFCXHUwRTQ3XHUwRTE5ICR7aXNzdWUuZXhwZWN0ZWR9IFx1MEU0MVx1MEUxNVx1MEU0OFx1MEU0NFx1MEUxNFx1MEU0OVx1MEUyM1x1MEUzMVx1MEUxQSAke3BhcnNlZFR5cGUoaXNzdWUuaW5wdXQpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF92YWx1ZVwiOlxuICAgICAgICAgICAgICAgIGlmIChpc3N1ZS52YWx1ZXMubGVuZ3RoID09PSAxKSByZXR1cm4gYFx1MEUwNFx1MEU0OFx1MEUzMlx1MEU0NFx1MEUyMVx1MEU0OFx1MEUxNlx1MEUzOVx1MEUwMVx1MEUxNVx1MEU0OVx1MEUyRFx1MEUwNzogXHUwRTA0XHUwRTI3XHUwRTIzXHUwRTQwXHUwRTFCXHUwRTQ3XHUwRTE5ICR7dXRpbC5zdHJpbmdpZnlQcmltaXRpdmUoaXNzdWUudmFsdWVzWzBdKX1gO1xuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwRTE1XHUwRTMxXHUwRTI3XHUwRTQwXHUwRTI1XHUwRTM3XHUwRTJEXHUwRTAxXHUwRTQ0XHUwRTIxXHUwRTQ4XHUwRTE2XHUwRTM5XHUwRTAxXHUwRTE1XHUwRTQ5XHUwRTJEXHUwRTA3OiBcdTBFMDRcdTBFMjdcdTBFMjNcdTBFNDBcdTBFMUJcdTBFNDdcdTBFMTlcdTBFMkJcdTBFMTlcdTBFMzZcdTBFNDhcdTBFMDdcdTBFNDNcdTBFMTkgJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIlx1MEU0NFx1MEUyMVx1MEU0OFx1MEU0MFx1MEUwMVx1MEUzNFx1MEUxOVwiIDogXCJcdTBFMTlcdTBFNDlcdTBFMkRcdTBFMjJcdTBFMDFcdTBFMjdcdTBFNDhcdTBFMzJcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgXHUwRTQwXHUwRTAxXHUwRTM0XHUwRTE5XHUwRTAxXHUwRTMzXHUwRTJCXHUwRTE5XHUwRTE0OiAke2lzc3VlLm9yaWdpbiA/PyBcIlx1MEUwNFx1MEU0OFx1MEUzMlwifSBcdTBFMDRcdTBFMjdcdTBFMjNcdTBFMjFcdTBFMzUke2Fkan0gJHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXQgPz8gXCJcdTBFMjNcdTBFMzJcdTBFMjJcdTBFMDFcdTBFMzJcdTBFMjNcIn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MEU0MFx1MEUwMVx1MEUzNFx1MEUxOVx1MEUwMVx1MEUzM1x1MEUyQlx1MEUxOVx1MEUxNDogJHtpc3N1ZS5vcmlnaW4gPz8gXCJcdTBFMDRcdTBFNDhcdTBFMzJcIn0gXHUwRTA0XHUwRTI3XHUwRTIzXHUwRTIxXHUwRTM1JHthZGp9ICR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInRvb19zbWFsbFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCJcdTBFMkRcdTBFMjJcdTBFNDhcdTBFMzJcdTBFMDdcdTBFMTlcdTBFNDlcdTBFMkRcdTBFMjJcIiA6IFwiXHUwRTIxXHUwRTMyXHUwRTAxXHUwRTAxXHUwRTI3XHUwRTQ4XHUwRTMyXCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MEUxOVx1MEU0OVx1MEUyRFx1MEUyMlx1MEUwMVx1MEUyN1x1MEU0OFx1MEUzMlx1MEUwMVx1MEUzM1x1MEUyQlx1MEUxOVx1MEUxNDogJHtpc3N1ZS5vcmlnaW59IFx1MEUwNFx1MEUyN1x1MEUyM1x1MEUyMVx1MEUzNSR7YWRqfSAke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdH1gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwRTE5XHUwRTQ5XHUwRTJEXHUwRTIyXHUwRTAxXHUwRTI3XHUwRTQ4XHUwRTMyXHUwRTAxXHUwRTMzXHUwRTJCXHUwRTE5XHUwRTE0OiAke2lzc3VlLm9yaWdpbn0gXHUwRTA0XHUwRTI3XHUwRTIzXHUwRTIxXHUwRTM1JHthZGp9ICR7aXNzdWUubWluaW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZm9ybWF0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBfaXNzdWUgPSBpc3N1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwic3RhcnRzX3dpdGhcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTBFMjNcdTBFMzlcdTBFMUJcdTBFNDFcdTBFMUFcdTBFMUFcdTBFNDRcdTBFMjFcdTBFNDhcdTBFMTZcdTBFMzlcdTBFMDFcdTBFMTVcdTBFNDlcdTBFMkRcdTBFMDc6IFx1MEUwMlx1MEU0OVx1MEUyRFx1MEUwNFx1MEUyN1x1MEUzMlx1MEUyMVx1MEUxNVx1MEU0OVx1MEUyRFx1MEUwN1x1MEUwMlx1MEUzNlx1MEU0OVx1MEUxOVx1MEUxNVx1MEU0OVx1MEUxOVx1MEUxNFx1MEU0OVx1MEUyN1x1MEUyMiBcIiR7X2lzc3VlLnByZWZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiZW5kc193aXRoXCIpIHJldHVybiBgXHUwRTIzXHUwRTM5XHUwRTFCXHUwRTQxXHUwRTFBXHUwRTFBXHUwRTQ0XHUwRTIxXHUwRTQ4XHUwRTE2XHUwRTM5XHUwRTAxXHUwRTE1XHUwRTQ5XHUwRTJEXHUwRTA3OiBcdTBFMDJcdTBFNDlcdTBFMkRcdTBFMDRcdTBFMjdcdTBFMzJcdTBFMjFcdTBFMTVcdTBFNDlcdTBFMkRcdTBFMDdcdTBFMjVcdTBFMDdcdTBFMTdcdTBFNDlcdTBFMzJcdTBFMjJcdTBFMTRcdTBFNDlcdTBFMjdcdTBFMjIgXCIke19pc3N1ZS5zdWZmaXh9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJpbmNsdWRlc1wiKSByZXR1cm4gYFx1MEUyM1x1MEUzOVx1MEUxQlx1MEU0MVx1MEUxQVx1MEUxQVx1MEU0NFx1MEUyMVx1MEU0OFx1MEUxNlx1MEUzOVx1MEUwMVx1MEUxNVx1MEU0OVx1MEUyRFx1MEUwNzogXHUwRTAyXHUwRTQ5XHUwRTJEXHUwRTA0XHUwRTI3XHUwRTMyXHUwRTIxXHUwRTE1XHUwRTQ5XHUwRTJEXHUwRTA3XHUwRTIxXHUwRTM1IFwiJHtfaXNzdWUuaW5jbHVkZXN9XCIgXHUwRTJEXHUwRTIyXHUwRTM5XHUwRTQ4XHUwRTQzXHUwRTE5XHUwRTAyXHUwRTQ5XHUwRTJEXHUwRTA0XHUwRTI3XHUwRTMyXHUwRTIxYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBcdTBFMjNcdTBFMzlcdTBFMUJcdTBFNDFcdTBFMUFcdTBFMUFcdTBFNDRcdTBFMjFcdTBFNDhcdTBFMTZcdTBFMzlcdTBFMDFcdTBFMTVcdTBFNDlcdTBFMkRcdTBFMDc6IFx1MEUxNVx1MEU0OVx1MEUyRFx1MEUwN1x1MEUxNVx1MEUyM1x1MEUwN1x1MEUwMVx1MEUzMVx1MEUxQVx1MEUyM1x1MEUzOVx1MEUxQlx1MEU0MVx1MEUxQVx1MEUxQVx1MEUxN1x1MEUzNVx1MEU0OFx1MEUwMVx1MEUzM1x1MEUyQlx1MEUxOVx1MEUxNCAke19pc3N1ZS5wYXR0ZXJufWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwRTIzXHUwRTM5XHUwRTFCXHUwRTQxXHUwRTFBXHUwRTFBXHUwRTQ0XHUwRTIxXHUwRTQ4XHUwRTE2XHUwRTM5XHUwRTAxXHUwRTE1XHUwRTQ5XHUwRTJEXHUwRTA3OiAke05vdW5zW19pc3N1ZS5mb3JtYXRdID8/IGlzc3VlLmZvcm1hdH1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJub3RfbXVsdGlwbGVfb2ZcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MEUxNVx1MEUzMVx1MEUyN1x1MEU0MFx1MEUyNVx1MEUwMlx1MEU0NFx1MEUyMVx1MEU0OFx1MEUxNlx1MEUzOVx1MEUwMVx1MEUxNVx1MEU0OVx1MEUyRFx1MEUwNzogXHUwRTE1XHUwRTQ5XHUwRTJEXHUwRTA3XHUwRTQwXHUwRTFCXHUwRTQ3XHUwRTE5XHUwRTA4XHUwRTMzXHUwRTE5XHUwRTI3XHUwRTE5XHUwRTE3XHUwRTM1XHUwRTQ4XHUwRTJCXHUwRTMyXHUwRTIzXHUwRTE0XHUwRTQ5XHUwRTI3XHUwRTIyICR7aXNzdWUuZGl2aXNvcn0gXHUwRTQ0XHUwRTE0XHUwRTQ5XHUwRTI1XHUwRTA3XHUwRTE1XHUwRTMxXHUwRTI3YDtcbiAgICAgICAgICAgIGNhc2UgXCJ1bnJlY29nbml6ZWRfa2V5c1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwRTFFXHUwRTFBXHUwRTA0XHUwRTM1XHUwRTIyXHUwRTRDXHUwRTE3XHUwRTM1XHUwRTQ4XHUwRTQ0XHUwRTIxXHUwRTQ4XHUwRTIzXHUwRTM5XHUwRTQ5XHUwRTA4XHUwRTMxXHUwRTAxOiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIiwgXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MEUwNFx1MEUzNVx1MEUyMlx1MEU0Q1x1MEU0NFx1MEUyMVx1MEU0OFx1MEUxNlx1MEUzOVx1MEUwMVx1MEUxNVx1MEU0OVx1MEUyRFx1MEUwN1x1MEU0M1x1MEUxOSAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTBFMDJcdTBFNDlcdTBFMkRcdTBFMjFcdTBFMzlcdTBFMjVcdTBFNDRcdTBFMjFcdTBFNDhcdTBFMTZcdTBFMzlcdTBFMDFcdTBFMTVcdTBFNDlcdTBFMkRcdTBFMDc6IFx1MEU0NFx1MEUyMVx1MEU0OFx1MEUxNVx1MEUyM1x1MEUwN1x1MEUwMVx1MEUzMVx1MEUxQVx1MEUyM1x1MEUzOVx1MEUxQlx1MEU0MVx1MEUxQVx1MEUxQVx1MEUyMlx1MEUzOVx1MEU0MFx1MEUxOVx1MEUzNVx1MEUyMlx1MEUxOVx1MEUxN1x1MEUzNVx1MEU0OFx1MEUwMVx1MEUzM1x1MEUyQlx1MEUxOVx1MEUxNFx1MEU0NFx1MEUyN1x1MEU0OVwiO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZWxlbWVudFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwRTAyXHUwRTQ5XHUwRTJEXHUwRTIxXHUwRTM5XHUwRTI1XHUwRTQ0XHUwRTIxXHUwRTQ4XHUwRTE2XHUwRTM5XHUwRTAxXHUwRTE1XHUwRTQ5XHUwRTJEXHUwRTA3XHUwRTQzXHUwRTE5ICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwRTAyXHUwRTQ5XHUwRTJEXHUwRTIxXHUwRTM5XHUwRTI1XHUwRTQ0XHUwRTIxXHUwRTQ4XHUwRTE2XHUwRTM5XHUwRTAxXHUwRTE1XHUwRTQ5XHUwRTJEXHUwRTA3YDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuZXhwb3J0IGNvbnN0IHBhcnNlZFR5cGUgPSAoZGF0YSk9PntcbiAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgc3dpdGNoKHQpe1xuICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIm51bWJlclwiO1xuICAgICAgICAgICAgfVxuICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiYXJyYXlcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGRhdGEgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKGRhdGEpICE9PSBPYmplY3QucHJvdG90eXBlICYmIGRhdGEuY29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0O1xufTtcbmNvbnN0IGVycm9yID0gKCk9PntcbiAgICBjb25zdCBTaXphYmxlID0ge1xuICAgICAgICBzdHJpbmc6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwia2FyYWt0ZXJcIixcbiAgICAgICAgICAgIHZlcmI6IFwib2xtYWxcdTAxMzFcIlxuICAgICAgICB9LFxuICAgICAgICBmaWxlOiB7XG4gICAgICAgICAgICB1bml0OiBcImJheXRcIixcbiAgICAgICAgICAgIHZlcmI6IFwib2xtYWxcdTAxMzFcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJcdTAwRjZcdTAxMUZlXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIm9sbWFsXHUwMTMxXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MDBGNlx1MDExRmVcIixcbiAgICAgICAgICAgIHZlcmI6IFwib2xtYWxcdTAxMzFcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcImdpcmRpXCIsXG4gICAgICAgIGVtYWlsOiBcImUtcG9zdGEgYWRyZXNpXCIsXG4gICAgICAgIHVybDogXCJVUkxcIixcbiAgICAgICAgZW1vamk6IFwiZW1vamlcIixcbiAgICAgICAgdXVpZDogXCJVVUlEXCIsXG4gICAgICAgIHV1aWR2NDogXCJVVUlEdjRcIixcbiAgICAgICAgdXVpZHY2OiBcIlVVSUR2NlwiLFxuICAgICAgICBuYW5vaWQ6IFwibmFub2lkXCIsXG4gICAgICAgIGd1aWQ6IFwiR1VJRFwiLFxuICAgICAgICBjdWlkOiBcImN1aWRcIixcbiAgICAgICAgY3VpZDI6IFwiY3VpZDJcIixcbiAgICAgICAgdWxpZDogXCJVTElEXCIsXG4gICAgICAgIHhpZDogXCJYSURcIixcbiAgICAgICAga3N1aWQ6IFwiS1NVSURcIixcbiAgICAgICAgZGF0ZXRpbWU6IFwiSVNPIHRhcmloIHZlIHNhYXRcIixcbiAgICAgICAgZGF0ZTogXCJJU08gdGFyaWhcIixcbiAgICAgICAgdGltZTogXCJJU08gc2FhdFwiLFxuICAgICAgICBkdXJhdGlvbjogXCJJU08gc1x1MDBGQ3JlXCIsXG4gICAgICAgIGlwdjQ6IFwiSVB2NCBhZHJlc2lcIixcbiAgICAgICAgaXB2NjogXCJJUHY2IGFkcmVzaVwiLFxuICAgICAgICBjaWRydjQ6IFwiSVB2NCBhcmFsXHUwMTMxXHUwMTFGXHUwMTMxXCIsXG4gICAgICAgIGNpZHJ2NjogXCJJUHY2IGFyYWxcdTAxMzFcdTAxMUZcdTAxMzFcIixcbiAgICAgICAgYmFzZTY0OiBcImJhc2U2NCBpbGUgXHUwMTVGaWZyZWxlbm1pXHUwMTVGIG1ldGluXCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJiYXNlNjR1cmwgaWxlIFx1MDE1RmlmcmVsZW5taVx1MDE1RiBtZXRpblwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJKU09OIGRpemVzaVwiLFxuICAgICAgICBlMTY0OiBcIkUuMTY0IHNheVx1MDEzMXNcdTAxMzFcIixcbiAgICAgICAgand0OiBcIkpXVFwiLFxuICAgICAgICB0ZW1wbGF0ZV9saXRlcmFsOiBcIlx1MDE1RWFibG9uIGRpemVzaVwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBHZVx1MDBFN2Vyc2l6IGRlXHUwMTFGZXI6IGJla2xlbmVuICR7aXNzdWUuZXhwZWN0ZWR9LCBhbFx1MDEzMW5hbiAke3BhcnNlZFR5cGUoaXNzdWUuaW5wdXQpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF92YWx1ZVwiOlxuICAgICAgICAgICAgICAgIGlmIChpc3N1ZS52YWx1ZXMubGVuZ3RoID09PSAxKSByZXR1cm4gYEdlXHUwMEU3ZXJzaXogZGVcdTAxMUZlcjogYmVrbGVuZW4gJHt1dGlsLnN0cmluZ2lmeVByaW1pdGl2ZShpc3N1ZS52YWx1ZXNbMF0pfWA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBHZVx1MDBFN2Vyc2l6IHNlXHUwMEU3ZW5lazogYVx1MDE1RmFcdTAxMUZcdTAxMzFkYWtpbGVyZGVuIGJpcmkgb2xtYWxcdTAxMzE6ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLnZhbHVlcywgXCJ8XCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwidG9vX2JpZ1wiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI8PVwiIDogXCI8XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSByZXR1cm4gYFx1MDBDN29rIGJcdTAwRkN5XHUwMEZDazogYmVrbGVuZW4gJHtpc3N1ZS5vcmlnaW4gPz8gXCJkZVx1MDExRmVyXCJ9ICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0ID8/IFwiXHUwMEY2XHUwMTFGZVwifWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwMEM3b2sgYlx1MDBGQ3lcdTAwRkNrOiBiZWtsZW5lbiAke2lzc3VlLm9yaWdpbiA/PyBcImRlXHUwMTFGZXJcIn0gJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIj49XCIgOiBcIj5cIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgXHUwMEM3b2sga1x1MDBGQ1x1MDBFN1x1MDBGQ2s6IGJla2xlbmVuICR7aXNzdWUub3JpZ2lufSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdH1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDBDN29rIGtcdTAwRkNcdTAwRTdcdTAwRkNrOiBiZWtsZW5lbiAke2lzc3VlLm9yaWdpbn0gJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSByZXR1cm4gYEdlXHUwMEU3ZXJzaXogbWV0aW46IFwiJHtfaXNzdWUucHJlZml4fVwiIGlsZSBiYVx1MDE1RmxhbWFsXHUwMTMxYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiZW5kc193aXRoXCIpIHJldHVybiBgR2VcdTAwRTdlcnNpeiBtZXRpbjogXCIke19pc3N1ZS5zdWZmaXh9XCIgaWxlIGJpdG1lbGlgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJpbmNsdWRlc1wiKSByZXR1cm4gYEdlXHUwMEU3ZXJzaXogbWV0aW46IFwiJHtfaXNzdWUuaW5jbHVkZXN9XCIgaVx1MDBFN2VybWVsaWA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInJlZ2V4XCIpIHJldHVybiBgR2VcdTAwRTdlcnNpeiBtZXRpbjogJHtfaXNzdWUucGF0dGVybn0gZGVzZW5pbmUgdXltYWxcdTAxMzFgO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYEdlXHUwMEU3ZXJzaXogJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBHZVx1MDBFN2Vyc2l6IHNheVx1MDEzMTogJHtpc3N1ZS5kaXZpc29yfSBpbGUgdGFtIGJcdTAwRjZsXHUwMEZDbmViaWxtZWxpYDtcbiAgICAgICAgICAgIGNhc2UgXCJ1bnJlY29nbml6ZWRfa2V5c1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgVGFuXHUwMTMxbm1heWFuIGFuYWh0YXIke2lzc3VlLmtleXMubGVuZ3RoID4gMSA/IFwibGFyXCIgOiBcIlwifTogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgXCIsIFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfa2V5XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGAke2lzc3VlLm9yaWdpbn0gaVx1MDBFN2luZGUgZ2VcdTAwRTdlcnNpeiBhbmFodGFyYDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3VuaW9uXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiR2VcdTAwRTdlcnNpeiBkZVx1MDExRmVyXCI7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9lbGVtZW50XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGAke2lzc3VlLm9yaWdpbn0gaVx1MDBFN2luZGUgZ2VcdTAwRTdlcnNpeiBkZVx1MDExRmVyYDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBHZVx1MDBFN2Vyc2l6IGRlXHUwMTFGZXJgO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBsb2NhbGVFcnJvcjogZXJyb3IoKVxuICAgIH07XG59XG4iLCAiaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi4vY29yZS91dGlsLmpzXCI7XG5jb25zdCBlcnJvciA9ICgpPT57XG4gICAgY29uc3QgU2l6YWJsZSA9IHtcbiAgICAgICAgc3RyaW5nOiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MDQ0MVx1MDQzOFx1MDQzQ1x1MDQzMlx1MDQzRVx1MDQzQlx1MDQ1Nlx1MDQzMlwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTA0M0NcdTA0MzBcdTA0NDJcdTA0MzhcdTA0M0NcdTA0MzVcIlxuICAgICAgICB9LFxuICAgICAgICBmaWxlOiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MDQzMVx1MDQzMFx1MDQzOVx1MDQ0Mlx1MDQ1Nlx1MDQzMlwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTA0M0NcdTA0MzBcdTA0NDJcdTA0MzhcdTA0M0NcdTA0MzVcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJcdTA0MzVcdTA0M0JcdTA0MzVcdTA0M0NcdTA0MzVcdTA0M0RcdTA0NDJcdTA0NTZcdTA0MzJcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwNDNDXHUwNDMwXHUwNDQyXHUwNDM4XHUwNDNDXHUwNDM1XCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MDQzNVx1MDQzQlx1MDQzNVx1MDQzQ1x1MDQzNVx1MDQzRFx1MDQ0Mlx1MDQ1Nlx1MDQzMlwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTA0M0NcdTA0MzBcdTA0NDJcdTA0MzhcdTA0M0NcdTA0MzVcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIk5hTlwiIDogXCJcdTA0NDdcdTA0MzhcdTA0NDFcdTA0M0JcdTA0M0VcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiXHUwNDNDXHUwNDMwXHUwNDQxXHUwNDM4XHUwNDMyXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGEgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm51bGxcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKGRhdGEpICE9PSBPYmplY3QucHJvdG90eXBlICYmIGRhdGEuY29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHQ7XG4gICAgfTtcbiAgICBjb25zdCBOb3VucyA9IHtcbiAgICAgICAgcmVnZXg6IFwiXHUwNDMyXHUwNDQ1XHUwNDU2XHUwNDM0XHUwNDNEXHUwNDU2IFx1MDQzNFx1MDQzMFx1MDQzRFx1MDQ1NlwiLFxuICAgICAgICBlbWFpbDogXCJcdTA0MzBcdTA0MzRcdTA0NDBcdTA0MzVcdTA0NDFcdTA0MzAgXHUwNDM1XHUwNDNCXHUwNDM1XHUwNDNBXHUwNDQyXHUwNDQwXHUwNDNFXHUwNDNEXHUwNDNEXHUwNDNFXHUwNDU3IFx1MDQzRlx1MDQzRVx1MDQ0OFx1MDQ0Mlx1MDQzOFwiLFxuICAgICAgICB1cmw6IFwiVVJMXCIsXG4gICAgICAgIGVtb2ppOiBcIlx1MDQzNVx1MDQzQ1x1MDQzRVx1MDQzNFx1MDQzN1x1MDQ1NlwiLFxuICAgICAgICB1dWlkOiBcIlVVSURcIixcbiAgICAgICAgdXVpZHY0OiBcIlVVSUR2NFwiLFxuICAgICAgICB1dWlkdjY6IFwiVVVJRHY2XCIsXG4gICAgICAgIG5hbm9pZDogXCJuYW5vaWRcIixcbiAgICAgICAgZ3VpZDogXCJHVUlEXCIsXG4gICAgICAgIGN1aWQ6IFwiY3VpZFwiLFxuICAgICAgICBjdWlkMjogXCJjdWlkMlwiLFxuICAgICAgICB1bGlkOiBcIlVMSURcIixcbiAgICAgICAgeGlkOiBcIlhJRFwiLFxuICAgICAgICBrc3VpZDogXCJLU1VJRFwiLFxuICAgICAgICBkYXRldGltZTogXCJcdTA0MzRcdTA0MzBcdTA0NDJcdTA0MzAgXHUwNDQyXHUwNDMwIFx1MDQ0N1x1MDQzMFx1MDQ0MSBJU09cIixcbiAgICAgICAgZGF0ZTogXCJcdTA0MzRcdTA0MzBcdTA0NDJcdTA0MzAgSVNPXCIsXG4gICAgICAgIHRpbWU6IFwiXHUwNDQ3XHUwNDMwXHUwNDQxIElTT1wiLFxuICAgICAgICBkdXJhdGlvbjogXCJcdTA0NDJcdTA0NDBcdTA0MzhcdTA0MzJcdTA0MzBcdTA0M0JcdTA0NTZcdTA0NDFcdTA0NDJcdTA0NEMgSVNPXCIsXG4gICAgICAgIGlwdjQ6IFwiXHUwNDMwXHUwNDM0XHUwNDQwXHUwNDM1XHUwNDQxXHUwNDMwIElQdjRcIixcbiAgICAgICAgaXB2NjogXCJcdTA0MzBcdTA0MzRcdTA0NDBcdTA0MzVcdTA0NDFcdTA0MzAgSVB2NlwiLFxuICAgICAgICBjaWRydjQ6IFwiXHUwNDM0XHUwNDU2XHUwNDMwXHUwNDNGXHUwNDMwXHUwNDM3XHUwNDNFXHUwNDNEIElQdjRcIixcbiAgICAgICAgY2lkcnY2OiBcIlx1MDQzNFx1MDQ1Nlx1MDQzMFx1MDQzRlx1MDQzMFx1MDQzN1x1MDQzRVx1MDQzRCBJUHY2XCIsXG4gICAgICAgIGJhc2U2NDogXCJcdTA0NDBcdTA0NEZcdTA0MzRcdTA0M0VcdTA0M0EgXHUwNDQzIFx1MDQzQVx1MDQzRVx1MDQzNFx1MDQ0M1x1MDQzMlx1MDQzMFx1MDQzRFx1MDQzRFx1MDQ1NiBiYXNlNjRcIixcbiAgICAgICAgYmFzZTY0dXJsOiBcIlx1MDQ0MFx1MDQ0Rlx1MDQzNFx1MDQzRVx1MDQzQSBcdTA0NDMgXHUwNDNBXHUwNDNFXHUwNDM0XHUwNDQzXHUwNDMyXHUwNDMwXHUwNDNEXHUwNDNEXHUwNDU2IGJhc2U2NHVybFwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJcdTA0NDBcdTA0NEZcdTA0MzRcdTA0M0VcdTA0M0EgSlNPTlwiLFxuICAgICAgICBlMTY0OiBcIlx1MDQzRFx1MDQzRVx1MDQzQ1x1MDQzNVx1MDQ0MCBFLjE2NFwiLFxuICAgICAgICBqd3Q6IFwiSldUXCIsXG4gICAgICAgIHRlbXBsYXRlX2xpdGVyYWw6IFwiXHUwNDMyXHUwNDQ1XHUwNDU2XHUwNDM0XHUwNDNEXHUwNDU2IFx1MDQzNFx1MDQzMFx1MDQzRFx1MDQ1NlwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MURcdTA0MzVcdTA0M0ZcdTA0NDBcdTA0MzBcdTA0MzJcdTA0MzhcdTA0M0JcdTA0NENcdTA0M0RcdTA0NTYgXHUwNDMyXHUwNDQ1XHUwNDU2XHUwNDM0XHUwNDNEXHUwNDU2IFx1MDQzNFx1MDQzMFx1MDQzRFx1MDQ1NjogXHUwNDNFXHUwNDQ3XHUwNDU2XHUwNDNBXHUwNDQzXHUwNDU0XHUwNDQyXHUwNDRDXHUwNDQxXHUwNDRGICR7aXNzdWUuZXhwZWN0ZWR9LCBcdTA0M0VcdTA0NDJcdTA0NDBcdTA0MzhcdTA0M0NcdTA0MzBcdTA0M0RcdTA0M0UgJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX1gO1xuICAgICAgICAgICAgLy8gcmV0dXJuIGBcdTA0MURcdTA0MzVcdTA0M0ZcdTA0NDBcdTA0MzBcdTA0MzJcdTA0MzhcdTA0M0JcdTA0NENcdTA0M0RcdTA0NTYgXHUwNDMyXHUwNDQ1XHUwNDU2XHUwNDM0XHUwNDNEXHUwNDU2IFx1MDQzNFx1MDQzMFx1MDQzRFx1MDQ1NjogXHUwNDNFXHUwNDQ3XHUwNDU2XHUwNDNBXHUwNDQzXHUwNDU0XHUwNDQyXHUwNDRDXHUwNDQxXHUwNDRGICR7aXNzdWUuZXhwZWN0ZWR9LCBcdTA0M0VcdTA0NDJcdTA0NDBcdTA0MzhcdTA0M0NcdTA0MzBcdTA0M0RcdTA0M0UgJHt1dGlsLmdldFBhcnNlZFR5cGUoaXNzdWUuaW5wdXQpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF92YWx1ZVwiOlxuICAgICAgICAgICAgICAgIGlmIChpc3N1ZS52YWx1ZXMubGVuZ3RoID09PSAxKSByZXR1cm4gYFx1MDQxRFx1MDQzNVx1MDQzRlx1MDQ0MFx1MDQzMFx1MDQzMlx1MDQzOFx1MDQzQlx1MDQ0Q1x1MDQzRFx1MDQ1NiBcdTA0MzJcdTA0NDVcdTA0NTZcdTA0MzRcdTA0M0RcdTA0NTYgXHUwNDM0XHUwNDMwXHUwNDNEXHUwNDU2OiBcdTA0M0VcdTA0NDdcdTA0NTZcdTA0M0FcdTA0NDNcdTA0NTRcdTA0NDJcdTA0NENcdTA0NDFcdTA0NEYgJHt1dGlsLnN0cmluZ2lmeVByaW1pdGl2ZShpc3N1ZS52YWx1ZXNbMF0pfWA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MURcdTA0MzVcdTA0M0ZcdTA0NDBcdTA0MzBcdTA0MzJcdTA0MzhcdTA0M0JcdTA0NENcdTA0M0RcdTA0MzAgXHUwNDNFXHUwNDNGXHUwNDQ2XHUwNDU2XHUwNDRGOiBcdTA0M0VcdTA0NDdcdTA0NTZcdTA0M0FcdTA0NDNcdTA0NTRcdTA0NDJcdTA0NENcdTA0NDFcdTA0NEYgXHUwNDNFXHUwNDM0XHUwNDNEXHUwNDM1IFx1MDQzNyAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS52YWx1ZXMsIFwifFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPD1cIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykgcmV0dXJuIGBcdTA0MTdcdTA0MzBcdTA0M0RcdTA0MzBcdTA0MzRcdTA0NDJcdTA0M0UgXHUwNDMyXHUwNDM1XHUwNDNCXHUwNDM4XHUwNDNBXHUwNDM1OiBcdTA0M0VcdTA0NDdcdTA0NTZcdTA0M0FcdTA0NDNcdTA0NTRcdTA0NDJcdTA0NENcdTA0NDFcdTA0NEYsIFx1MDQ0OVx1MDQzRSAke2lzc3VlLm9yaWdpbiA/PyBcIlx1MDQzN1x1MDQzRFx1MDQzMFx1MDQ0N1x1MDQzNVx1MDQzRFx1MDQzRFx1MDQ0RlwifSAke3NpemluZy52ZXJifSAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdCA/PyBcIlx1MDQzNVx1MDQzQlx1MDQzNVx1MDQzQ1x1MDQzNVx1MDQzRFx1MDQ0Mlx1MDQ1Nlx1MDQzMlwifWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNDE3XHUwNDMwXHUwNDNEXHUwNDMwXHUwNDM0XHUwNDQyXHUwNDNFIFx1MDQzMlx1MDQzNVx1MDQzQlx1MDQzOFx1MDQzQVx1MDQzNTogXHUwNDNFXHUwNDQ3XHUwNDU2XHUwNDNBXHUwNDQzXHUwNDU0XHUwNDQyXHUwNDRDXHUwNDQxXHUwNDRGLCBcdTA0NDlcdTA0M0UgJHtpc3N1ZS5vcmlnaW4gPz8gXCJcdTA0MzdcdTA0M0RcdTA0MzBcdTA0NDdcdTA0MzVcdTA0M0RcdTA0M0RcdTA0NEZcIn0gXHUwNDMxXHUwNDQzXHUwNDM0XHUwNDM1ICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInRvb19zbWFsbFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI+PVwiIDogXCI+XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDQxN1x1MDQzMFx1MDQzRFx1MDQzMFx1MDQzNFx1MDQ0Mlx1MDQzRSBcdTA0M0NcdTA0MzBcdTA0M0JcdTA0MzU6IFx1MDQzRVx1MDQ0N1x1MDQ1Nlx1MDQzQVx1MDQ0M1x1MDQ1NFx1MDQ0Mlx1MDQ0Q1x1MDQ0MVx1MDQ0RiwgXHUwNDQ5XHUwNDNFICR7aXNzdWUub3JpZ2lufSAke3NpemluZy52ZXJifSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdH1gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNDE3XHUwNDMwXHUwNDNEXHUwNDMwXHUwNDM0XHUwNDQyXHUwNDNFIFx1MDQzQ1x1MDQzMFx1MDQzQlx1MDQzNTogXHUwNDNFXHUwNDQ3XHUwNDU2XHUwNDNBXHUwNDQzXHUwNDU0XHUwNDQyXHUwNDRDXHUwNDQxXHUwNDRGLCBcdTA0NDlcdTA0M0UgJHtpc3N1ZS5vcmlnaW59IFx1MDQzMVx1MDQ0M1x1MDQzNFx1MDQzNSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2Zvcm1hdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgX2lzc3VlID0gaXNzdWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInN0YXJ0c193aXRoXCIpIHJldHVybiBgXHUwNDFEXHUwNDM1XHUwNDNGXHUwNDQwXHUwNDMwXHUwNDMyXHUwNDM4XHUwNDNCXHUwNDRDXHUwNDNEXHUwNDM4XHUwNDM5IFx1MDQ0MFx1MDQ0Rlx1MDQzNFx1MDQzRVx1MDQzQTogXHUwNDNGXHUwNDNFXHUwNDMyXHUwNDM4XHUwNDNEXHUwNDM1XHUwNDNEIFx1MDQzRlx1MDQzRVx1MDQ0N1x1MDQzOFx1MDQzRFx1MDQzMFx1MDQ0Mlx1MDQzOFx1MDQ0MVx1MDQ0RiBcdTA0MzcgXCIke19pc3N1ZS5wcmVmaXh9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJlbmRzX3dpdGhcIikgcmV0dXJuIGBcdTA0MURcdTA0MzVcdTA0M0ZcdTA0NDBcdTA0MzBcdTA0MzJcdTA0MzhcdTA0M0JcdTA0NENcdTA0M0RcdTA0MzhcdTA0MzkgXHUwNDQwXHUwNDRGXHUwNDM0XHUwNDNFXHUwNDNBOiBcdTA0M0ZcdTA0M0VcdTA0MzJcdTA0MzhcdTA0M0RcdTA0MzVcdTA0M0QgXHUwNDM3XHUwNDMwXHUwNDNBXHUwNDU2XHUwNDNEXHUwNDQ3XHUwNDQzXHUwNDMyXHUwNDMwXHUwNDQyXHUwNDM4XHUwNDQxXHUwNDRGIFx1MDQzRFx1MDQzMCBcIiR7X2lzc3VlLnN1ZmZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImluY2x1ZGVzXCIpIHJldHVybiBgXHUwNDFEXHUwNDM1XHUwNDNGXHUwNDQwXHUwNDMwXHUwNDMyXHUwNDM4XHUwNDNCXHUwNDRDXHUwNDNEXHUwNDM4XHUwNDM5IFx1MDQ0MFx1MDQ0Rlx1MDQzNFx1MDQzRVx1MDQzQTogXHUwNDNGXHUwNDNFXHUwNDMyXHUwNDM4XHUwNDNEXHUwNDM1XHUwNDNEIFx1MDQzQ1x1MDQ1Nlx1MDQ0MVx1MDQ0Mlx1MDQzOFx1MDQ0Mlx1MDQzOCBcIiR7X2lzc3VlLmluY2x1ZGVzfVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBcdTA0MURcdTA0MzVcdTA0M0ZcdTA0NDBcdTA0MzBcdTA0MzJcdTA0MzhcdTA0M0JcdTA0NENcdTA0M0RcdTA0MzhcdTA0MzkgXHUwNDQwXHUwNDRGXHUwNDM0XHUwNDNFXHUwNDNBOiBcdTA0M0ZcdTA0M0VcdTA0MzJcdTA0MzhcdTA0M0RcdTA0MzVcdTA0M0QgXHUwNDMyXHUwNDU2XHUwNDM0XHUwNDNGXHUwNDNFXHUwNDMyXHUwNDU2XHUwNDM0XHUwNDMwXHUwNDQyXHUwNDM4IFx1MDQ0OFx1MDQzMFx1MDQzMVx1MDQzQlx1MDQzRVx1MDQzRFx1MDQ0MyAke19pc3N1ZS5wYXR0ZXJufWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNDFEXHUwNDM1XHUwNDNGXHUwNDQwXHUwNDMwXHUwNDMyXHUwNDM4XHUwNDNCXHUwNDRDXHUwNDNEXHUwNDM4XHUwNDM5ICR7Tm91bnNbX2lzc3VlLmZvcm1hdF0gPz8gaXNzdWUuZm9ybWF0fWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm5vdF9tdWx0aXBsZV9vZlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNDFEXHUwNDM1XHUwNDNGXHUwNDQwXHUwNDMwXHUwNDMyXHUwNDM4XHUwNDNCXHUwNDRDXHUwNDNEXHUwNDM1IFx1MDQ0N1x1MDQzOFx1MDQ0MVx1MDQzQlx1MDQzRTogXHUwNDNGXHUwNDNFXHUwNDMyXHUwNDM4XHUwNDNEXHUwNDNEXHUwNDNFIFx1MDQzMVx1MDQ0M1x1MDQ0Mlx1MDQzOCBcdTA0M0FcdTA0NDBcdTA0MzBcdTA0NDJcdTA0M0RcdTA0MzhcdTA0M0MgJHtpc3N1ZS5kaXZpc29yfWA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDQxRFx1MDQzNVx1MDQ0MFx1MDQzRVx1MDQzN1x1MDQzRlx1MDQ1Nlx1MDQzN1x1MDQzRFx1MDQzMFx1MDQzRFx1MDQzOFx1MDQzOSBcdTA0M0FcdTA0M0JcdTA0NEVcdTA0NDcke2lzc3VlLmtleXMubGVuZ3RoID4gMSA/IFwiXHUwNDU2XCIgOiBcIlwifTogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgXCIsIFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfa2V5XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MURcdTA0MzVcdTA0M0ZcdTA0NDBcdTA0MzBcdTA0MzJcdTA0MzhcdTA0M0JcdTA0NENcdTA0M0RcdTA0MzhcdTA0MzkgXHUwNDNBXHUwNDNCXHUwNDRFXHUwNDQ3IFx1MDQ0MyAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTA0MURcdTA0MzVcdTA0M0ZcdTA0NDBcdTA0MzBcdTA0MzJcdTA0MzhcdTA0M0JcdTA0NENcdTA0M0RcdTA0NTYgXHUwNDMyXHUwNDQ1XHUwNDU2XHUwNDM0XHUwNDNEXHUwNDU2IFx1MDQzNFx1MDQzMFx1MDQzRFx1MDQ1NlwiO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZWxlbWVudFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNDFEXHUwNDM1XHUwNDNGXHUwNDQwXHUwNDMwXHUwNDMyXHUwNDM4XHUwNDNCXHUwNDRDXHUwNDNEXHUwNDM1IFx1MDQzN1x1MDQzRFx1MDQzMFx1MDQ0N1x1MDQzNVx1MDQzRFx1MDQzRFx1MDQ0RiBcdTA0NDMgJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MURcdTA0MzVcdTA0M0ZcdTA0NDBcdTA0MzBcdTA0MzJcdTA0MzhcdTA0M0JcdTA0NENcdTA0M0RcdTA0NTYgXHUwNDMyXHUwNDQ1XHUwNDU2XHUwNDM0XHUwNDNEXHUwNDU2IFx1MDQzNFx1MDQzMFx1MDQzRFx1MDQ1NmA7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGxvY2FsZUVycm9yOiBlcnJvcigpXG4gICAgfTtcbn1cbiIsICJpbXBvcnQgdWsgZnJvbSBcIi4vdWsuanNcIjtcbi8qKiBAZGVwcmVjYXRlZCBVc2UgYHVrYCBpbnN0ZWFkLiAqLyBleHBvcnQgZGVmYXVsdCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdWsoKTtcbn1cbiIsICJpbXBvcnQgKiBhcyB1dGlsIGZyb20gXCIuLi9jb3JlL3V0aWwuanNcIjtcbmNvbnN0IGVycm9yID0gKCk9PntcbiAgICBjb25zdCBTaXphYmxlID0ge1xuICAgICAgICBzdHJpbmc6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHUwNjJEXHUwNjMxXHUwNjQ4XHUwNjQxXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MDZDMVx1MDY0OFx1MDY0Nlx1MDYyN1wiXG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHUwNjI4XHUwNjI3XHUwNjI2XHUwNjc5XHUwNjMzXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MDZDMVx1MDY0OFx1MDY0Nlx1MDYyN1wiXG4gICAgICAgIH0sXG4gICAgICAgIGFycmF5OiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MDYyMlx1MDYyNlx1MDY3OVx1MDY0NVx1MDYzMlwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTA2QzFcdTA2NDhcdTA2NDZcdTA2MjdcIlxuICAgICAgICB9LFxuICAgICAgICBzZXQ6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHUwNjIyXHUwNjI2XHUwNjc5XHUwNjQ1XHUwNjMyXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MDZDMVx1MDY0OFx1MDY0Nlx1MDYyN1wiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4pIHtcbiAgICAgICAgcmV0dXJuIFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWRUeXBlID0gKGRhdGEpPT57XG4gICAgICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICAgICAgc3dpdGNoKHQpe1xuICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIlx1MDY0Nlx1MDY0NVx1MDYyOFx1MDYzMVwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTA2MjJcdTA2MzFcdTA2RDJcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiXHUwNjQ2XHUwNjQ0XCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcIlx1MDYyN1x1MDY0NiBcdTA2N0VcdTA2NzlcIixcbiAgICAgICAgZW1haWw6IFwiXHUwNjI3XHUwNkNDIFx1MDY0NVx1MDZDQ1x1MDY0NCBcdTA2MjdcdTA2Q0NcdTA2ODhcdTA2MzFcdTA2Q0NcdTA2MzNcIixcbiAgICAgICAgdXJsOiBcIlx1MDZDQ1x1MDY0OCBcdTA2MjJcdTA2MzEgXHUwNjI3XHUwNkNDXHUwNjQ0XCIsXG4gICAgICAgIGVtb2ppOiBcIlx1MDYyN1x1MDZDQ1x1MDY0NVx1MDY0OFx1MDYyQ1x1MDZDQ1wiLFxuICAgICAgICB1dWlkOiBcIlx1MDZDQ1x1MDY0OCBcdTA2Q0NcdTA2NDggXHUwNjIyXHUwNjI2XHUwNkNDIFx1MDY4OFx1MDZDQ1wiLFxuICAgICAgICB1dWlkdjQ6IFwiXHUwNkNDXHUwNjQ4IFx1MDZDQ1x1MDY0OCBcdTA2MjJcdTA2MjZcdTA2Q0MgXHUwNjg4XHUwNkNDIFx1MDY0OFx1MDZDQyA0XCIsXG4gICAgICAgIHV1aWR2NjogXCJcdTA2Q0NcdTA2NDggXHUwNkNDXHUwNjQ4IFx1MDYyMlx1MDYyNlx1MDZDQyBcdTA2ODhcdTA2Q0MgXHUwNjQ4XHUwNkNDIDZcIixcbiAgICAgICAgbmFub2lkOiBcIlx1MDY0Nlx1MDZDQ1x1MDY0Nlx1MDY0OCBcdTA2MjJcdTA2MjZcdTA2Q0MgXHUwNjg4XHUwNkNDXCIsXG4gICAgICAgIGd1aWQ6IFwiXHUwNjJDXHUwNkNDIFx1MDZDQ1x1MDY0OCBcdTA2MjJcdTA2MjZcdTA2Q0MgXHUwNjg4XHUwNkNDXCIsXG4gICAgICAgIGN1aWQ6IFwiXHUwNjMzXHUwNkNDIFx1MDZDQ1x1MDY0OCBcdTA2MjJcdTA2MjZcdTA2Q0MgXHUwNjg4XHUwNkNDXCIsXG4gICAgICAgIGN1aWQyOiBcIlx1MDYzM1x1MDZDQyBcdTA2Q0NcdTA2NDggXHUwNjIyXHUwNjI2XHUwNkNDIFx1MDY4OFx1MDZDQyAyXCIsXG4gICAgICAgIHVsaWQ6IFwiXHUwNkNDXHUwNjQ4IFx1MDYyN1x1MDZDQ1x1MDY0NCBcdTA2MjJcdTA2MjZcdTA2Q0MgXHUwNjg4XHUwNkNDXCIsXG4gICAgICAgIHhpZDogXCJcdTA2MjdcdTA2Q0NcdTA2QTlcdTA2MzMgXHUwNjIyXHUwNjI2XHUwNkNDIFx1MDY4OFx1MDZDQ1wiLFxuICAgICAgICBrc3VpZDogXCJcdTA2QTlcdTA2RDIgXHUwNjI3XHUwNkNDXHUwNjMzIFx1MDZDQ1x1MDY0OCBcdTA2MjJcdTA2MjZcdTA2Q0MgXHUwNjg4XHUwNkNDXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcIlx1MDYyMlx1MDYyNlx1MDZDQyBcdTA2MjdcdTA2Q0NcdTA2MzMgXHUwNjI3XHUwNjQ4IFx1MDY4OFx1MDZDQ1x1MDY3OSBcdTA2NzlcdTA2MjdcdTA2MjZcdTA2NDVcIixcbiAgICAgICAgZGF0ZTogXCJcdTA2MjJcdTA2MjZcdTA2Q0MgXHUwNjI3XHUwNkNDXHUwNjMzIFx1MDYyN1x1MDY0OCBcdTA2MkFcdTA2MjdcdTA2MzFcdTA2Q0NcdTA2MkVcIixcbiAgICAgICAgdGltZTogXCJcdTA2MjJcdTA2MjZcdTA2Q0MgXHUwNjI3XHUwNkNDXHUwNjMzIFx1MDYyN1x1MDY0OCBcdTA2NDhcdTA2NDJcdTA2MkFcIixcbiAgICAgICAgZHVyYXRpb246IFwiXHUwNjIyXHUwNjI2XHUwNkNDIFx1MDYyN1x1MDZDQ1x1MDYzMyBcdTA2MjdcdTA2NDggXHUwNjQ1XHUwNjJGXHUwNjJBXCIsXG4gICAgICAgIGlwdjQ6IFwiXHUwNjIyXHUwNjI2XHUwNkNDIFx1MDY3RVx1MDZDQyBcdTA2NDhcdTA2Q0MgNCBcdTA2MjdcdTA2Q0NcdTA2ODhcdTA2MzFcdTA2Q0NcdTA2MzNcIixcbiAgICAgICAgaXB2NjogXCJcdTA2MjJcdTA2MjZcdTA2Q0MgXHUwNjdFXHUwNkNDIFx1MDY0OFx1MDZDQyA2IFx1MDYyN1x1MDZDQ1x1MDY4OFx1MDYzMVx1MDZDQ1x1MDYzM1wiLFxuICAgICAgICBjaWRydjQ6IFwiXHUwNjIyXHUwNjI2XHUwNkNDIFx1MDY3RVx1MDZDQyBcdTA2NDhcdTA2Q0MgNCBcdTA2MzFcdTA2Q0NcdTA2NDZcdTA2MkNcIixcbiAgICAgICAgY2lkcnY2OiBcIlx1MDYyMlx1MDYyNlx1MDZDQyBcdTA2N0VcdTA2Q0MgXHUwNjQ4XHUwNkNDIDYgXHUwNjMxXHUwNkNDXHUwNjQ2XHUwNjJDXCIsXG4gICAgICAgIGJhc2U2NDogXCJcdTA2MjhcdTA2Q0NcdTA2MzMgNjQgXHUwNjI3XHUwNjQ2IFx1MDZBOVx1MDY0OFx1MDY4OFx1MDY4OCBcdTA2MzNcdTA2NzlcdTA2MzFcdTA2NDZcdTA2QUZcIixcbiAgICAgICAgYmFzZTY0dXJsOiBcIlx1MDYyOFx1MDZDQ1x1MDYzMyA2NCBcdTA2Q0NcdTA2NDggXHUwNjIyXHUwNjMxIFx1MDYyN1x1MDZDQ1x1MDY0NCBcdTA2MjdcdTA2NDYgXHUwNkE5XHUwNjQ4XHUwNjg4XHUwNjg4IFx1MDYzM1x1MDY3OVx1MDYzMVx1MDY0Nlx1MDZBRlwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJcdTA2MkNcdTA2RDIgXHUwNjI3XHUwNkNDXHUwNjMzIFx1MDYyN1x1MDY0OCBcdTA2MjdcdTA2Q0NcdTA2NDYgXHUwNjMzXHUwNjc5XHUwNjMxXHUwNjQ2XHUwNkFGXCIsXG4gICAgICAgIGUxNjQ6IFwiXHUwNjI3XHUwNkNDIDE2NCBcdTA2NDZcdTA2NDVcdTA2MjhcdTA2MzFcIixcbiAgICAgICAgand0OiBcIlx1MDYyQ1x1MDZEMiBcdTA2ODhcdTA2MjhcdTA2NDRcdTA2Q0NcdTA2NDggXHUwNjc5XHUwNkNDXCIsXG4gICAgICAgIHRlbXBsYXRlX2xpdGVyYWw6IFwiXHUwNjI3XHUwNjQ2IFx1MDY3RVx1MDY3OVwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2M0FcdTA2NDRcdTA2MzcgXHUwNjI3XHUwNjQ2IFx1MDY3RVx1MDY3OTogJHtpc3N1ZS5leHBlY3RlZH0gXHUwNjQ1XHUwNjJBXHUwNjQ4XHUwNjQyXHUwNjM5IFx1MDYyQVx1MDZCRVx1MDYyN1x1MDYwQyAke3BhcnNlZFR5cGUoaXNzdWUuaW5wdXQpfSBcdTA2NDVcdTA2NDhcdTA2MzVcdTA2NDhcdTA2NDQgXHUwNkMxXHUwNjQ4XHUwNjI3YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgXHUwNjNBXHUwNjQ0XHUwNjM3IFx1MDYyN1x1MDY0NiBcdTA2N0VcdTA2Nzk6ICR7dXRpbC5zdHJpbmdpZnlQcmltaXRpdmUoaXNzdWUudmFsdWVzWzBdKX0gXHUwNjQ1XHUwNjJBXHUwNjQ4XHUwNjQyXHUwNjM5IFx1MDYyQVx1MDZCRVx1MDYyN2A7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2M0FcdTA2NDRcdTA2MzcgXHUwNjIyXHUwNjdFXHUwNjM0XHUwNjQ2OiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS52YWx1ZXMsIFwifFwiKX0gXHUwNjQ1XHUwNkNDXHUwNkJBIFx1MDYzM1x1MDZEMiBcdTA2MjdcdTA2Q0NcdTA2QTkgXHUwNjQ1XHUwNjJBXHUwNjQ4XHUwNjQyXHUwNjM5IFx1MDYyQVx1MDZCRVx1MDYyN2A7XG4gICAgICAgICAgICBjYXNlIFwidG9vX2JpZ1wiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI8PVwiIDogXCI8XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSByZXR1cm4gYFx1MDYyOFx1MDZDMVx1MDYyQSBcdTA2MjhcdTA2OTFcdTA2Mjc6ICR7aXNzdWUub3JpZ2luID8/IFwiXHUwNjQ4XHUwNkNDXHUwNjQ0XHUwNkNDXHUwNjQ4XCJ9IFx1MDZBOVx1MDZEMiAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdCA/PyBcIlx1MDYzOVx1MDY0Nlx1MDYyN1x1MDYzNVx1MDYzMVwifSBcdTA2QzFcdTA2NDhcdTA2NDZcdTA2RDIgXHUwNjQ1XHUwNjJBXHUwNjQ4XHUwNjQyXHUwNjM5IFx1MDYyQVx1MDZCRVx1MDZEMmA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjI4XHUwNkMxXHUwNjJBIFx1MDYyOFx1MDY5MVx1MDYyNzogJHtpc3N1ZS5vcmlnaW4gPz8gXCJcdTA2NDhcdTA2Q0NcdTA2NDRcdTA2Q0NcdTA2NDhcIn0gXHUwNkE5XHUwNjI3ICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSBcdTA2QzFcdTA2NDhcdTA2NDZcdTA2MjcgXHUwNjQ1XHUwNjJBXHUwNjQ4XHUwNjQyXHUwNjM5IFx1MDYyQVx1MDZCRVx1MDYyN2A7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInRvb19zbWFsbFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI+PVwiIDogXCI+XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDYyOFx1MDZDMVx1MDYyQSBcdTA2ODZcdTA2QkVcdTA2NDhcdTA2NzlcdTA2Mjc6ICR7aXNzdWUub3JpZ2lufSBcdTA2QTlcdTA2RDIgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXR9IFx1MDZDMVx1MDY0OFx1MDY0Nlx1MDZEMiBcdTA2NDVcdTA2MkFcdTA2NDhcdTA2NDJcdTA2MzkgXHUwNjJBXHUwNkJFXHUwNkQyYDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDYyOFx1MDZDMVx1MDYyQSBcdTA2ODZcdTA2QkVcdTA2NDhcdTA2NzlcdTA2Mjc6ICR7aXNzdWUub3JpZ2lufSBcdTA2QTlcdTA2MjcgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9IFx1MDZDMVx1MDY0OFx1MDY0Nlx1MDYyNyBcdTA2NDVcdTA2MkFcdTA2NDhcdTA2NDJcdTA2MzkgXHUwNjJBXHUwNkJFXHUwNjI3YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDYzQVx1MDY0NFx1MDYzNyBcdTA2MzNcdTA2NzlcdTA2MzFcdTA2NDZcdTA2QUY6IFwiJHtfaXNzdWUucHJlZml4fVwiIFx1MDYzM1x1MDZEMiBcdTA2MzRcdTA2MzFcdTA2NDhcdTA2MzkgXHUwNkMxXHUwNjQ4XHUwNjQ2XHUwNjI3IFx1MDY4Nlx1MDYyN1x1MDZDMVx1MDZDQ1x1MDZEMmA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiZW5kc193aXRoXCIpIHJldHVybiBgXHUwNjNBXHUwNjQ0XHUwNjM3IFx1MDYzM1x1MDY3OVx1MDYzMVx1MDY0Nlx1MDZBRjogXCIke19pc3N1ZS5zdWZmaXh9XCIgXHUwNjdFXHUwNjMxIFx1MDYyRVx1MDYyQVx1MDY0NSBcdTA2QzFcdTA2NDhcdTA2NDZcdTA2MjcgXHUwNjg2XHUwNjI3XHUwNkMxXHUwNkNDXHUwNkQyYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBcdTA2M0FcdTA2NDRcdTA2MzcgXHUwNjMzXHUwNjc5XHUwNjMxXHUwNjQ2XHUwNkFGOiBcIiR7X2lzc3VlLmluY2x1ZGVzfVwiIFx1MDYzNFx1MDYyN1x1MDY0NVx1MDY0NCBcdTA2QzFcdTA2NDhcdTA2NDZcdTA2MjcgXHUwNjg2XHUwNjI3XHUwNkMxXHUwNkNDXHUwNkQyYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBcdTA2M0FcdTA2NDRcdTA2MzcgXHUwNjMzXHUwNjc5XHUwNjMxXHUwNjQ2XHUwNkFGOiBcdTA2N0VcdTA2Q0NcdTA2NzlcdTA2MzFcdTA2NDYgJHtfaXNzdWUucGF0dGVybn0gXHUwNjMzXHUwNkQyIFx1MDY0NVx1MDZDQ1x1MDY4NiBcdTA2QzFcdTA2NDhcdTA2NDZcdTA2MjcgXHUwNjg2XHUwNjI3XHUwNkMxXHUwNkNDXHUwNkQyYDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2M0FcdTA2NDRcdTA2MzcgJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2M0FcdTA2NDRcdTA2MzcgXHUwNjQ2XHUwNjQ1XHUwNjI4XHUwNjMxOiAke2lzc3VlLmRpdmlzb3J9IFx1MDZBOVx1MDYyNyBcdTA2NDVcdTA2MzZcdTA2MjdcdTA2MzlcdTA2NDEgXHUwNkMxXHUwNjQ4XHUwNjQ2XHUwNjI3IFx1MDY4Nlx1MDYyN1x1MDZDMVx1MDZDQ1x1MDZEMmA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDYzQVx1MDZDQ1x1MDYzMSBcdTA2MkFcdTA2MzNcdTA2NDRcdTA2Q0NcdTA2NDUgXHUwNjM0XHUwNjJGXHUwNkMxIFx1MDZBOVx1MDZDQyR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJcdTA2MzJcIiA6IFwiXCJ9OiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIlx1MDYwQyBcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2tleVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgJHtpc3N1ZS5vcmlnaW59IFx1MDY0NVx1MDZDQ1x1MDZCQSBcdTA2M0FcdTA2NDRcdTA2MzcgXHUwNkE5XHUwNkNDYDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3VuaW9uXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiXHUwNjNBXHUwNjQ0XHUwNjM3IFx1MDYyN1x1MDY0NiBcdTA2N0VcdTA2NzlcIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYCR7aXNzdWUub3JpZ2lufSBcdTA2NDVcdTA2Q0NcdTA2QkEgXHUwNjNBXHUwNjQ0XHUwNjM3IFx1MDY0OFx1MDZDQ1x1MDY0NFx1MDZDQ1x1MDY0OGA7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjNBXHUwNjQ0XHUwNjM3IFx1MDYyN1x1MDY0NiBcdTA2N0VcdTA2NzlgO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBsb2NhbGVFcnJvcjogZXJyb3IoKVxuICAgIH07XG59XG4iLCAiaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi4vY29yZS91dGlsLmpzXCI7XG5jb25zdCBlcnJvciA9ICgpPT57XG4gICAgY29uc3QgU2l6YWJsZSA9IHtcbiAgICAgICAgc3RyaW5nOiB7XG4gICAgICAgICAgICB1bml0OiBcImtcdTAwRkQgdFx1MUVGMVwiLFxuICAgICAgICAgICAgdmVyYjogXCJjXHUwMEYzXCJcbiAgICAgICAgfSxcbiAgICAgICAgZmlsZToge1xuICAgICAgICAgICAgdW5pdDogXCJieXRlXCIsXG4gICAgICAgICAgICB2ZXJiOiBcImNcdTAwRjNcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJwaFx1MUVBN24gdFx1MUVFRFwiLFxuICAgICAgICAgICAgdmVyYjogXCJjXHUwMEYzXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcInBoXHUxRUE3biB0XHUxRUVEXCIsXG4gICAgICAgICAgICB2ZXJiOiBcImNcdTAwRjNcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIk5hTlwiIDogXCJzXHUxRUQxXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm9iamVjdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm1cdTFFQTNuZ1wiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJudWxsXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcIlx1MDExMVx1MUVBN3Ugdlx1MDBFMG9cIixcbiAgICAgICAgZW1haWw6IFwiXHUwMTExXHUxRUNCYSBjaFx1MUVDOSBlbWFpbFwiLFxuICAgICAgICB1cmw6IFwiVVJMXCIsXG4gICAgICAgIGVtb2ppOiBcImVtb2ppXCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcIm5nXHUwMEUweSBnaVx1MUVERCBJU09cIixcbiAgICAgICAgZGF0ZTogXCJuZ1x1MDBFMHkgSVNPXCIsXG4gICAgICAgIHRpbWU6IFwiZ2lcdTFFREQgSVNPXCIsXG4gICAgICAgIGR1cmF0aW9uOiBcImtob1x1MUVBM25nIHRoXHUxRUREaSBnaWFuIElTT1wiLFxuICAgICAgICBpcHY0OiBcIlx1MDExMVx1MUVDQmEgY2hcdTFFQzkgSVB2NFwiLFxuICAgICAgICBpcHY2OiBcIlx1MDExMVx1MUVDQmEgY2hcdTFFQzkgSVB2NlwiLFxuICAgICAgICBjaWRydjQ6IFwiZFx1MUVBM2kgSVB2NFwiLFxuICAgICAgICBjaWRydjY6IFwiZFx1MUVBM2kgSVB2NlwiLFxuICAgICAgICBiYXNlNjQ6IFwiY2h1XHUxRUQ3aSBtXHUwMEUzIGhcdTAwRjNhIGJhc2U2NFwiLFxuICAgICAgICBiYXNlNjR1cmw6IFwiY2h1XHUxRUQ3aSBtXHUwMEUzIGhcdTAwRjNhIGJhc2U2NHVybFwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJjaHVcdTFFRDdpIEpTT05cIixcbiAgICAgICAgZTE2NDogXCJzXHUxRUQxIEUuMTY0XCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJcdTAxMTFcdTFFQTd1IHZcdTAwRTBvXCJcbiAgICB9O1xuICAgIHJldHVybiAoaXNzdWUpPT57XG4gICAgICAgIHN3aXRjaChpc3N1ZS5jb2RlKXtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3R5cGVcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDExMFx1MUVBN3Ugdlx1MDBFMG8ga2hcdTAwRjRuZyBoXHUxRUUzcCBsXHUxRUM3OiBtb25nIFx1MDExMVx1MUVFM2kgJHtpc3N1ZS5leHBlY3RlZH0sIG5oXHUxRUFEbiBcdTAxMTFcdTAxQjBcdTFFRTNjICR7cGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgXHUwMTEwXHUxRUE3dSB2XHUwMEUwbyBraFx1MDBGNG5nIGhcdTFFRTNwIGxcdTFFQzc6IG1vbmcgXHUwMTExXHUxRUUzaSAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYFRcdTAwRjl5IGNoXHUxRUNEbiBraFx1MDBGNG5nIGhcdTFFRTNwIGxcdTFFQzc6IG1vbmcgXHUwMTExXHUxRUUzaSBtXHUxRUQ5dCB0cm9uZyBjXHUwMEUxYyBnaVx1MDBFMSB0clx1MUVDQiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS52YWx1ZXMsIFwifFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPD1cIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykgcmV0dXJuIGBRdVx1MDBFMSBsXHUxRURCbjogbW9uZyBcdTAxMTFcdTFFRTNpICR7aXNzdWUub3JpZ2luID8/IFwiZ2lcdTAwRTEgdHJcdTFFQ0JcIn0gJHtzaXppbmcudmVyYn0gJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXQgPz8gXCJwaFx1MUVBN24gdFx1MUVFRFwifWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgUXVcdTAwRTEgbFx1MUVEQm46IG1vbmcgXHUwMTExXHUxRUUzaSAke2lzc3VlLm9yaWdpbiA/PyBcImdpXHUwMEUxIHRyXHUxRUNCXCJ9ICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInRvb19zbWFsbFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI+PVwiIDogXCI+XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFF1XHUwMEUxIG5oXHUxRUNGOiBtb25nIFx1MDExMVx1MUVFM2kgJHtpc3N1ZS5vcmlnaW59ICR7c2l6aW5nLnZlcmJ9ICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0fWA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBRdVx1MDBFMSBuaFx1MUVDRjogbW9uZyBcdTAxMTFcdTFFRTNpICR7aXNzdWUub3JpZ2lufSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2Zvcm1hdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgX2lzc3VlID0gaXNzdWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInN0YXJ0c193aXRoXCIpIHJldHVybiBgQ2h1XHUxRUQ3aSBraFx1MDBGNG5nIGhcdTFFRTNwIGxcdTFFQzc6IHBoXHUxRUEzaSBiXHUxRUFGdCBcdTAxMTFcdTFFQTd1IGJcdTFFQjFuZyBcIiR7X2lzc3VlLnByZWZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYENodVx1MUVEN2kga2hcdTAwRjRuZyBoXHUxRUUzcCBsXHUxRUM3OiBwaFx1MUVBM2kga1x1MUVCRnQgdGhcdTAwRkFjIGJcdTFFQjFuZyBcIiR7X2lzc3VlLnN1ZmZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImluY2x1ZGVzXCIpIHJldHVybiBgQ2h1XHUxRUQ3aSBraFx1MDBGNG5nIGhcdTFFRTNwIGxcdTFFQzc6IHBoXHUxRUEzaSBiYW8gZ1x1MUVEM20gXCIke19pc3N1ZS5pbmNsdWRlc31cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInJlZ2V4XCIpIHJldHVybiBgQ2h1XHUxRUQ3aSBraFx1MDBGNG5nIGhcdTFFRTNwIGxcdTFFQzc6IHBoXHUxRUEzaSBraFx1MUVEQnAgdlx1MUVEQmkgbVx1MUVBQnUgJHtfaXNzdWUucGF0dGVybn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYCR7Tm91bnNbX2lzc3VlLmZvcm1hdF0gPz8gaXNzdWUuZm9ybWF0fSBraFx1MDBGNG5nIGhcdTFFRTNwIGxcdTFFQzdgO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJub3RfbXVsdGlwbGVfb2ZcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFNcdTFFRDEga2hcdTAwRjRuZyBoXHUxRUUzcCBsXHUxRUM3OiBwaFx1MUVBM2kgbFx1MDBFMCBiXHUxRUQ5aSBzXHUxRUQxIGNcdTFFRTdhICR7aXNzdWUuZGl2aXNvcn1gO1xuICAgICAgICAgICAgY2FzZSBcInVucmVjb2duaXplZF9rZXlzXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBLaFx1MDBGM2Ega2hcdTAwRjRuZyBcdTAxMTFcdTAxQjBcdTFFRTNjIG5oXHUxRUFEbiBkXHUxRUExbmc6ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLmtleXMsIFwiLCBcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2tleVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgS2hcdTAwRjNhIGtoXHUwMEY0bmcgaFx1MUVFM3AgbFx1MUVDNyB0cm9uZyAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTAxMTBcdTFFQTd1IHZcdTAwRTBvIGtoXHUwMEY0bmcgaFx1MUVFM3AgbFx1MUVDN1wiO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZWxlbWVudFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgR2lcdTAwRTEgdHJcdTFFQ0Iga2hcdTAwRjRuZyBoXHUxRUUzcCBsXHUxRUM3IHRyb25nICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwMTEwXHUxRUE3dSB2XHUwMEUwbyBraFx1MDBGNG5nIGhcdTFFRTNwIGxcdTFFQzdgO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBsb2NhbGVFcnJvcjogZXJyb3IoKVxuICAgIH07XG59XG4iLCAiaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi4vY29yZS91dGlsLmpzXCI7XG5jb25zdCBlcnJvciA9ICgpPT57XG4gICAgY29uc3QgU2l6YWJsZSA9IHtcbiAgICAgICAgc3RyaW5nOiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1NUI1N1x1N0IyNlwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTUzMDVcdTU0MkJcIlxuICAgICAgICB9LFxuICAgICAgICBmaWxlOiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1NUI1N1x1ODI4MlwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTUzMDVcdTU0MkJcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJcdTk4NzlcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHU1MzA1XHU1NDJCXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1OTg3OVwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTUzMDVcdTU0MkJcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIlx1OTc1RVx1NjU3MFx1NUI1NyhOYU4pXCIgOiBcIlx1NjU3MFx1NUI1N1wiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTY1NzBcdTdFQzRcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiXHU3QTdBXHU1MDNDKG51bGwpXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcIlx1OEY5M1x1NTE2NVwiLFxuICAgICAgICBlbWFpbDogXCJcdTc1MzVcdTVCNTBcdTkwQUVcdTRFRjZcIixcbiAgICAgICAgdXJsOiBcIlVSTFwiLFxuICAgICAgICBlbW9qaTogXCJcdTg4NjhcdTYwQzVcdTdCMjZcdTUzRjdcIixcbiAgICAgICAgdXVpZDogXCJVVUlEXCIsXG4gICAgICAgIHV1aWR2NDogXCJVVUlEdjRcIixcbiAgICAgICAgdXVpZHY2OiBcIlVVSUR2NlwiLFxuICAgICAgICBuYW5vaWQ6IFwibmFub2lkXCIsXG4gICAgICAgIGd1aWQ6IFwiR1VJRFwiLFxuICAgICAgICBjdWlkOiBcImN1aWRcIixcbiAgICAgICAgY3VpZDI6IFwiY3VpZDJcIixcbiAgICAgICAgdWxpZDogXCJVTElEXCIsXG4gICAgICAgIHhpZDogXCJYSURcIixcbiAgICAgICAga3N1aWQ6IFwiS1NVSURcIixcbiAgICAgICAgZGF0ZXRpbWU6IFwiSVNPXHU2NUU1XHU2NzFGXHU2NUY2XHU5NUY0XCIsXG4gICAgICAgIGRhdGU6IFwiSVNPXHU2NUU1XHU2NzFGXCIsXG4gICAgICAgIHRpbWU6IFwiSVNPXHU2NUY2XHU5NUY0XCIsXG4gICAgICAgIGR1cmF0aW9uOiBcIklTT1x1NjVGNlx1OTU3RlwiLFxuICAgICAgICBpcHY0OiBcIklQdjRcdTU3MzBcdTU3NDBcIixcbiAgICAgICAgaXB2NjogXCJJUHY2XHU1NzMwXHU1NzQwXCIsXG4gICAgICAgIGNpZHJ2NDogXCJJUHY0XHU3RjUxXHU2QkI1XCIsXG4gICAgICAgIGNpZHJ2NjogXCJJUHY2XHU3RjUxXHU2QkI1XCIsXG4gICAgICAgIGJhc2U2NDogXCJiYXNlNjRcdTdGMTZcdTc4MDFcdTVCNTdcdTdCMjZcdTRFMzJcIixcbiAgICAgICAgYmFzZTY0dXJsOiBcImJhc2U2NHVybFx1N0YxNlx1NzgwMVx1NUI1N1x1N0IyNlx1NEUzMlwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJKU09OXHU1QjU3XHU3QjI2XHU0RTMyXCIsXG4gICAgICAgIGUxNjQ6IFwiRS4xNjRcdTUzRjdcdTc4MDFcIixcbiAgICAgICAgand0OiBcIkpXVFwiLFxuICAgICAgICB0ZW1wbGF0ZV9saXRlcmFsOiBcIlx1OEY5M1x1NTE2NVwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTY1RTBcdTY1NDhcdThGOTNcdTUxNjVcdUZGMUFcdTY3MUZcdTY3MUIgJHtpc3N1ZS5leHBlY3RlZH1cdUZGMENcdTVCOUVcdTk2NDVcdTYzQTVcdTY1MzYgJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBcdTY1RTBcdTY1NDhcdThGOTNcdTUxNjVcdUZGMUFcdTY3MUZcdTY3MUIgJHt1dGlsLnN0cmluZ2lmeVByaW1pdGl2ZShpc3N1ZS52YWx1ZXNbMF0pfWA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTY1RTBcdTY1NDhcdTkwMDlcdTk4NzlcdUZGMUFcdTY3MUZcdTY3MUJcdTRFRTVcdTRFMEJcdTRFNEJcdTRFMDAgJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIjw9XCIgOiBcIjxcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgXHU2NTcwXHU1MDNDXHU4RkM3XHU1OTI3XHVGRjFBXHU2NzFGXHU2NzFCICR7aXNzdWUub3JpZ2luID8/IFwiXHU1MDNDXCJ9ICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0ID8/IFwiXHU0RTJBXHU1MTQzXHU3RDIwXCJ9YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTY1NzBcdTUwM0NcdThGQzdcdTU5MjdcdUZGMUFcdTY3MUZcdTY3MUIgJHtpc3N1ZS5vcmlnaW4gPz8gXCJcdTUwM0NcIn0gJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIj49XCIgOiBcIj5cIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHU2NTcwXHU1MDNDXHU4RkM3XHU1QzBGXHVGRjFBXHU2NzFGXHU2NzFCICR7aXNzdWUub3JpZ2lufSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdH1gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHU2NTcwXHU1MDNDXHU4RkM3XHU1QzBGXHVGRjFBXHU2NzFGXHU2NzFCICR7aXNzdWUub3JpZ2lufSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2Zvcm1hdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgX2lzc3VlID0gaXNzdWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInN0YXJ0c193aXRoXCIpIHJldHVybiBgXHU2NUUwXHU2NTQ4XHU1QjU3XHU3QjI2XHU0RTMyXHVGRjFBXHU1RkM1XHU5ODdCXHU0RUU1IFwiJHtfaXNzdWUucHJlZml4fVwiIFx1NUYwMFx1NTkzNGA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYFx1NjVFMFx1NjU0OFx1NUI1N1x1N0IyNlx1NEUzMlx1RkYxQVx1NUZDNVx1OTg3Qlx1NEVFNSBcIiR7X2lzc3VlLnN1ZmZpeH1cIiBcdTdFRDNcdTVDM0VgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJpbmNsdWRlc1wiKSByZXR1cm4gYFx1NjVFMFx1NjU0OFx1NUI1N1x1N0IyNlx1NEUzMlx1RkYxQVx1NUZDNVx1OTg3Qlx1NTMwNVx1NTQyQiBcIiR7X2lzc3VlLmluY2x1ZGVzfVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBcdTY1RTBcdTY1NDhcdTVCNTdcdTdCMjZcdTRFMzJcdUZGMUFcdTVGQzVcdTk4N0JcdTZFRTFcdThEQjNcdTZCNjNcdTUyMTlcdTg4NjhcdThGQkVcdTVGMEYgJHtfaXNzdWUucGF0dGVybn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1NjVFMFx1NjU0OCR7Tm91bnNbX2lzc3VlLmZvcm1hdF0gPz8gaXNzdWUuZm9ybWF0fWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm5vdF9tdWx0aXBsZV9vZlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHU2NUUwXHU2NTQ4XHU2NTcwXHU1QjU3XHVGRjFBXHU1RkM1XHU5ODdCXHU2NjJGICR7aXNzdWUuZGl2aXNvcn0gXHU3Njg0XHU1MDBEXHU2NTcwYDtcbiAgICAgICAgICAgIGNhc2UgXCJ1bnJlY29nbml6ZWRfa2V5c1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHU1MUZBXHU3M0IwXHU2NzJBXHU3N0U1XHU3Njg0XHU5NTJFKGtleSk6ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLmtleXMsIFwiLCBcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2tleVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgJHtpc3N1ZS5vcmlnaW59IFx1NEUyRFx1NzY4NFx1OTUyRShrZXkpXHU2NUUwXHU2NTQ4YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3VuaW9uXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiXHU2NUUwXHU2NTQ4XHU4RjkzXHU1MTY1XCI7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9lbGVtZW50XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGAke2lzc3VlLm9yaWdpbn0gXHU0RTJEXHU1MzA1XHU1NDJCXHU2NUUwXHU2NTQ4XHU1MDNDKHZhbHVlKWA7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHU2NUUwXHU2NTQ4XHU4RjkzXHU1MTY1YDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJcdTVCNTdcdTUxNDNcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHU2NEMxXHU2NzA5XCJcbiAgICAgICAgfSxcbiAgICAgICAgZmlsZToge1xuICAgICAgICAgICAgdW5pdDogXCJcdTRGNERcdTUxNDNcdTdENDRcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHU2NEMxXHU2NzA5XCJcbiAgICAgICAgfSxcbiAgICAgICAgYXJyYXk6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHU5ODA1XHU3NkVFXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1NjRDMVx1NjcwOVwiXG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDogXCJcdTk4MDVcdTc2RUVcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHU2NEMxXHU2NzA5XCJcbiAgICAgICAgfVxuICAgIH07XG4gICAgZnVuY3Rpb24gZ2V0U2l6aW5nKG9yaWdpbikge1xuICAgICAgICByZXR1cm4gU2l6YWJsZVtvcmlnaW5dID8/IG51bGw7XG4gICAgfVxuICAgIGNvbnN0IHBhcnNlZFR5cGUgPSAoZGF0YSk9PntcbiAgICAgICAgY29uc3QgdCA9IHR5cGVvZiBkYXRhO1xuICAgICAgICBzd2l0Y2godCl7XG4gICAgICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gTnVtYmVyLmlzTmFOKGRhdGEpID8gXCJOYU5cIiA6IFwibnVtYmVyXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm9iamVjdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcImFycmF5XCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGEgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm51bGxcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKGRhdGEpICE9PSBPYmplY3QucHJvdG90eXBlICYmIGRhdGEuY29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHQ7XG4gICAgfTtcbiAgICBjb25zdCBOb3VucyA9IHtcbiAgICAgICAgcmVnZXg6IFwiXHU4RjM4XHU1MTY1XCIsXG4gICAgICAgIGVtYWlsOiBcIlx1OTBGNVx1NEVGNlx1NTczMFx1NTc0MFwiLFxuICAgICAgICB1cmw6IFwiVVJMXCIsXG4gICAgICAgIGVtb2ppOiBcImVtb2ppXCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcIklTTyBcdTY1RTVcdTY3MUZcdTY2NDJcdTk1OTNcIixcbiAgICAgICAgZGF0ZTogXCJJU08gXHU2NUU1XHU2NzFGXCIsXG4gICAgICAgIHRpbWU6IFwiSVNPIFx1NjY0Mlx1OTU5M1wiLFxuICAgICAgICBkdXJhdGlvbjogXCJJU08gXHU2NzFGXHU5NTkzXCIsXG4gICAgICAgIGlwdjQ6IFwiSVB2NCBcdTRGNERcdTU3NDBcIixcbiAgICAgICAgaXB2NjogXCJJUHY2IFx1NEY0RFx1NTc0MFwiLFxuICAgICAgICBjaWRydjQ6IFwiSVB2NCBcdTdCQzRcdTU3MERcIixcbiAgICAgICAgY2lkcnY2OiBcIklQdjYgXHU3QkM0XHU1NzBEXCIsXG4gICAgICAgIGJhc2U2NDogXCJiYXNlNjQgXHU3REU4XHU3OEJDXHU1QjU3XHU0RTMyXCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJiYXNlNjR1cmwgXHU3REU4XHU3OEJDXHU1QjU3XHU0RTMyXCIsXG4gICAgICAgIGpzb25fc3RyaW5nOiBcIkpTT04gXHU1QjU3XHU0RTMyXCIsXG4gICAgICAgIGUxNjQ6IFwiRS4xNjQgXHU2NTc4XHU1MDNDXCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJcdThGMzhcdTUxNjVcIlxuICAgIH07XG4gICAgcmV0dXJuIChpc3N1ZSk9PntcbiAgICAgICAgc3dpdGNoKGlzc3VlLmNvZGUpe1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdHlwZVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHU3MTIxXHU2NTQ4XHU3Njg0XHU4RjM4XHU1MTY1XHU1MDNDXHVGRjFBXHU5ODEwXHU2NzFGXHU3MEJBICR7aXNzdWUuZXhwZWN0ZWR9XHVGRjBDXHU0RjQ2XHU2NTM2XHU1MjMwICR7cGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgXHU3MTIxXHU2NTQ4XHU3Njg0XHU4RjM4XHU1MTY1XHU1MDNDXHVGRjFBXHU5ODEwXHU2NzFGXHU3MEJBICR7dXRpbC5zdHJpbmdpZnlQcmltaXRpdmUoaXNzdWUudmFsdWVzWzBdKX1gO1xuICAgICAgICAgICAgICAgIHJldHVybiBgXHU3MTIxXHU2NTQ4XHU3Njg0XHU5MDc4XHU5ODA1XHVGRjFBXHU5ODEwXHU2NzFGXHU3MEJBXHU0RUU1XHU0RTBCXHU1MTc2XHU0RTJEXHU0RTRCXHU0RTAwICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLnZhbHVlcywgXCJ8XCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwidG9vX2JpZ1wiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI8PVwiIDogXCI8XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSByZXR1cm4gYFx1NjU3OFx1NTAzQ1x1OTA0RVx1NTkyN1x1RkYxQVx1OTgxMFx1NjcxRiAke2lzc3VlLm9yaWdpbiA/PyBcIlx1NTAzQ1wifSBcdTYxQzlcdTcwQkEgJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXQgPz8gXCJcdTUwMEJcdTUxNDNcdTdEMjBcIn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1NjU3OFx1NTAzQ1x1OTA0RVx1NTkyN1x1RkYxQVx1OTgxMFx1NjcxRiAke2lzc3VlLm9yaWdpbiA/PyBcIlx1NTAzQ1wifSBcdTYxQzlcdTcwQkEgJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIj49XCIgOiBcIj5cIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHU2NTc4XHU1MDNDXHU5MDRFXHU1QzBGXHVGRjFBXHU5ODEwXHU2NzFGICR7aXNzdWUub3JpZ2lufSBcdTYxQzlcdTcwQkEgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXR9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1NjU3OFx1NTAzQ1x1OTA0RVx1NUMwRlx1RkYxQVx1OTgxMFx1NjcxRiAke2lzc3VlLm9yaWdpbn0gXHU2MUM5XHU3MEJBICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZm9ybWF0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBfaXNzdWUgPSBpc3N1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwic3RhcnRzX3dpdGhcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTcxMjFcdTY1NDhcdTc2ODRcdTVCNTdcdTRFMzJcdUZGMUFcdTVGQzVcdTk4MDhcdTRFRTUgXCIke19pc3N1ZS5wcmVmaXh9XCIgXHU5NThCXHU5ODJEYDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJlbmRzX3dpdGhcIikgcmV0dXJuIGBcdTcxMjFcdTY1NDhcdTc2ODRcdTVCNTdcdTRFMzJcdUZGMUFcdTVGQzVcdTk4MDhcdTRFRTUgXCIke19pc3N1ZS5zdWZmaXh9XCIgXHU3RDUwXHU1QzNFYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBcdTcxMjFcdTY1NDhcdTc2ODRcdTVCNTdcdTRFMzJcdUZGMUFcdTVGQzVcdTk4MDhcdTUzMDVcdTU0MkIgXCIke19pc3N1ZS5pbmNsdWRlc31cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInJlZ2V4XCIpIHJldHVybiBgXHU3MTIxXHU2NTQ4XHU3Njg0XHU1QjU3XHU0RTMyXHVGRjFBXHU1RkM1XHU5ODA4XHU3QjI2XHU1NDA4XHU2ODNDXHU1RjBGICR7X2lzc3VlLnBhdHRlcm59YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTcxMjFcdTY1NDhcdTc2ODQgJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTcxMjFcdTY1NDhcdTc2ODRcdTY1NzhcdTVCNTdcdUZGMUFcdTVGQzVcdTk4MDhcdTcwQkEgJHtpc3N1ZS5kaXZpc29yfSBcdTc2ODRcdTUwMERcdTY1NzhgO1xuICAgICAgICAgICAgY2FzZSBcInVucmVjb2duaXplZF9rZXlzXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTcxMjFcdTZDRDVcdThCNThcdTUyMjVcdTc2ODRcdTkzNzVcdTUwM0Mke2lzc3VlLmtleXMubGVuZ3RoID4gMSA/IFwiXHU1MDExXCIgOiBcIlwifVx1RkYxQSR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLmtleXMsIFwiXHUzMDAxXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYCR7aXNzdWUub3JpZ2lufSBcdTRFMkRcdTY3MDlcdTcxMjFcdTY1NDhcdTc2ODRcdTkzNzVcdTUwM0NgO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTcxMjFcdTY1NDhcdTc2ODRcdThGMzhcdTUxNjVcdTUwM0NcIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYCR7aXNzdWUub3JpZ2lufSBcdTRFMkRcdTY3MDlcdTcxMjFcdTY1NDhcdTc2ODRcdTUwM0NgO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1NzEyMVx1NjU0OFx1NzY4NFx1OEYzOFx1NTE2NVx1NTAzQ2A7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGxvY2FsZUVycm9yOiBlcnJvcigpXG4gICAgfTtcbn1cbiIsICJpbXBvcnQgKiBhcyB1dGlsIGZyb20gXCIuLi9jb3JlL3V0aWwuanNcIjtcbmNvbnN0IGVycm9yID0gKCk9PntcbiAgICBjb25zdCBTaXphYmxlID0ge1xuICAgICAgICBzdHJpbmc6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHUwMEUwbWlcIixcbiAgICAgICAgICAgIHZlcmI6IFwiblx1MDBFRFwiXG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiYnl0ZXNcIixcbiAgICAgICAgICAgIHZlcmI6IFwiblx1MDBFRFwiXG4gICAgICAgIH0sXG4gICAgICAgIGFycmF5OiB7XG4gICAgICAgICAgICB1bml0OiBcIm5rYW5cIixcbiAgICAgICAgICAgIHZlcmI6IFwiblx1MDBFRFwiXG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDogXCJua2FuXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIm5cdTAwRURcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIk5hTlwiIDogXCJuXHUxRUNEXHUwMzAxbWJcdTAwRTBcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiYWtvcFx1MUVDRFwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJudWxsXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcIlx1MUVCOVx1MDMwMHJcdTFFQ0QgXHUwMEVDYlx1MDBFMXdcdTFFQ0RsXHUwMEU5XCIsXG4gICAgICAgIGVtYWlsOiBcIlx1MDBFMGRcdTAwRURyXHUxRUI5XHUwMzAxc1x1MDBFQyBcdTAwRUNtXHUxRUI5XHUwMzAxbFx1MDBFQ1wiLFxuICAgICAgICB1cmw6IFwiVVJMXCIsXG4gICAgICAgIGVtb2ppOiBcImVtb2ppXCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcIlx1MDBFMGtcdTAwRjNrXHUwMEYyIElTT1wiLFxuICAgICAgICBkYXRlOiBcIlx1MUVDRGpcdTFFQ0RcdTAzMDEgSVNPXCIsXG4gICAgICAgIHRpbWU6IFwiXHUwMEUwa1x1MDBGM2tcdTAwRjIgSVNPXCIsXG4gICAgICAgIGR1cmF0aW9uOiBcIlx1MDBFMGtcdTAwRjNrXHUwMEYyIHRcdTAwRjMgcFx1MDBFOSBJU09cIixcbiAgICAgICAgaXB2NDogXCJcdTAwRTBkXHUwMEVEclx1MUVCOVx1MDMwMXNcdTAwRUMgSVB2NFwiLFxuICAgICAgICBpcHY2OiBcIlx1MDBFMGRcdTAwRURyXHUxRUI5XHUwMzAxc1x1MDBFQyBJUHY2XCIsXG4gICAgICAgIGNpZHJ2NDogXCJcdTAwRTBnYlx1MDBFOGdiXHUwMEU4IElQdjRcIixcbiAgICAgICAgY2lkcnY2OiBcIlx1MDBFMGdiXHUwMEU4Z2JcdTAwRTggSVB2NlwiLFxuICAgICAgICBiYXNlNjQ6IFwiXHUxRUNEXHUwMzAwclx1MUVDRFx1MDMwMCB0XHUwMEVEIGEga1x1MUVDRFx1MDMwMSBuXHUwMEVEIGJhc2U2NFwiLFxuICAgICAgICBiYXNlNjR1cmw6IFwiXHUxRUNEXHUwMzAwclx1MUVDRFx1MDMwMCBiYXNlNjR1cmxcIixcbiAgICAgICAganNvbl9zdHJpbmc6IFwiXHUxRUNEXHUwMzAwclx1MUVDRFx1MDMwMCBKU09OXCIsXG4gICAgICAgIGUxNjQ6IFwiblx1MUVDRFx1MDMwMW1iXHUwMEUwIEUuMTY0XCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJcdTFFQjlcdTAzMDByXHUxRUNEIFx1MDBFQ2JcdTAwRTF3XHUxRUNEbFx1MDBFOVwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTAwQ0NiXHUwMEUxd1x1MUVDRGxcdTAwRTkgYVx1MUU2M1x1MDBFQ1x1MUU2M2U6IGEgblx1MDBFRCBsXHUwMEUxdGkgZmkgJHtpc3N1ZS5leHBlY3RlZH0sIFx1MDBFMG1cdTFFQ0RcdTAzMDAgYSByXHUwMEVEICR7cGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgXHUwMENDYlx1MDBFMXdcdTFFQ0RsXHUwMEU5IGFcdTFFNjNcdTAwRUNcdTFFNjNlOiBhIG5cdTAwRUQgbFx1MDBFMXRpIGZpICR7dXRpbC5zdHJpbmdpZnlQcmltaXRpdmUoaXNzdWUudmFsdWVzWzBdKX1gO1xuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwMEMwXHUxRTYzXHUwMEUweVx1MDBFMG4gYVx1MUU2M1x1MDBFQ1x1MUU2M2U6IHlhbiBcdTFFQ0RcdTAzMDBrYW4gbFx1MDBFMXJhICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLnZhbHVlcywgXCJ8XCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwidG9vX2JpZ1wiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI8PVwiIDogXCI8XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSByZXR1cm4gYFRcdTAwRjMgcFx1MUVDRFx1MDMwMCBqXHUwMEY5OiBhIG5cdTAwRUQgbFx1MDBFMXRpIGpcdTFFQjlcdTAzMDEgcFx1MDBFOSAke2lzc3VlLm9yaWdpbiA/PyBcIml5ZVwifSAke3NpemluZy52ZXJifSAke2Fkan0ke2lzc3VlLm1heGltdW19ICR7c2l6aW5nLnVuaXR9YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBUXHUwMEYzIHBcdTFFQ0RcdTAzMDAgalx1MDBGOTogYSBuXHUwMEVEIGxcdTAwRTF0aSBqXHUxRUI5XHUwMzAxICR7YWRqfSR7aXNzdWUubWF4aW11bX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJ0b29fc21hbGxcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPj1cIiA6IFwiPlwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykgcmV0dXJuIGBLXHUwMEU5clx1MDBFOSBqdTogYSBuXHUwMEVEIGxcdTAwRTF0aSBqXHUxRUI5XHUwMzAxIHBcdTAwRTkgJHtpc3N1ZS5vcmlnaW59ICR7c2l6aW5nLnZlcmJ9ICR7YWRqfSR7aXNzdWUubWluaW11bX0gJHtzaXppbmcudW5pdH1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYEtcdTAwRTlyXHUwMEU5IGp1OiBhIG5cdTAwRUQgbFx1MDBFMXRpIGpcdTFFQjlcdTAzMDEgJHthZGp9JHtpc3N1ZS5taW5pbXVtfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZm9ybWF0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBfaXNzdWUgPSBpc3N1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwic3RhcnRzX3dpdGhcIikgcmV0dXJuIGBcdTFFQ0NcdTAzMDByXHUxRUNEXHUwMzAwIGFcdTFFNjNcdTAwRUNcdTFFNjNlOiBnYlx1MUVDRFx1MDMwMWRcdTFFQ0RcdTAzMDAgYlx1MUVCOVx1MDMwMHJcdTFFQjlcdTAzMDAgcFx1MUVCOVx1MDMwMGxcdTAwRkEgXCIke19pc3N1ZS5wcmVmaXh9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJlbmRzX3dpdGhcIikgcmV0dXJuIGBcdTFFQ0NcdTAzMDByXHUxRUNEXHUwMzAwIGFcdTFFNjNcdTAwRUNcdTFFNjNlOiBnYlx1MUVDRFx1MDMwMWRcdTFFQ0RcdTAzMDAgcGFyXHUwMEVEIHBcdTFFQjlcdTAzMDBsXHUwMEZBIFwiJHtfaXNzdWUuc3VmZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBcdTFFQ0NcdTAzMDByXHUxRUNEXHUwMzAwIGFcdTFFNjNcdTAwRUNcdTFFNjNlOiBnYlx1MUVDRFx1MDMwMWRcdTFFQ0RcdTAzMDAgblx1MDBFRCBcIiR7X2lzc3VlLmluY2x1ZGVzfVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBcdTFFQ0NcdTAzMDByXHUxRUNEXHUwMzAwIGFcdTFFNjNcdTAwRUNcdTFFNjNlOiBnYlx1MUVDRFx1MDMwMWRcdTFFQ0RcdTAzMDAgYlx1MDBFMSBcdTAwRTBwXHUxRUI5XHUxRUI5clx1MUVCOSBtdSAke19pc3N1ZS5wYXR0ZXJufWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgQVx1MUU2M1x1MDBFQ1x1MUU2M2U6ICR7Tm91bnNbX2lzc3VlLmZvcm1hdF0gPz8gaXNzdWUuZm9ybWF0fWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm5vdF9tdWx0aXBsZV9vZlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgTlx1MUVDRFx1MDMwMW1iXHUwMEUwIGFcdTFFNjNcdTAwRUNcdTFFNjNlOiBnYlx1MUVDRFx1MDMwMWRcdTFFQ0RcdTAzMDAgalx1MUVCOVx1MDMwMSBcdTAwRTh5XHUwMEUwIHBcdTAwRURwXHUwMEVEbiB0aSAke2lzc3VlLmRpdmlzb3J9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ1bnJlY29nbml6ZWRfa2V5c1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgQlx1MUVDRHRcdTAwRUNuXHUwMEVDIFx1MDBFMFx1MDBFQ21cdTFFQ0RcdTAzMDA6ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLmtleXMsIFwiLCBcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2tleVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgQlx1MUVDRHRcdTAwRUNuXHUwMEVDIGFcdTFFNjNcdTAwRUNcdTFFNjNlIG5cdTAwRURuXHUwMEZBICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF91bmlvblwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIlx1MDBDQ2JcdTAwRTF3XHUxRUNEbFx1MDBFOSBhXHUxRTYzXHUwMEVDXHUxRTYzZVwiO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZWxlbWVudFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgSXllIGFcdTFFNjNcdTAwRUNcdTFFNjNlIG5cdTAwRURuXHUwMEZBICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBcIlx1MDBDQ2JcdTAwRTF3XHUxRUNEbFx1MDBFOSBhXHUxRTYzXHUwMEVDXHUxRTYzZVwiO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBsb2NhbGVFcnJvcjogZXJyb3IoKVxuICAgIH07XG59XG4iLCAiZXhwb3J0IGNvbnN0ICRvdXRwdXQgPSBTeW1ib2woXCJab2RPdXRwdXRcIik7XG5leHBvcnQgY29uc3QgJGlucHV0ID0gU3ltYm9sKFwiWm9kSW5wdXRcIik7XG5leHBvcnQgY2xhc3MgJFpvZFJlZ2lzdHJ5IHtcbiAgICBjb25zdHJ1Y3Rvcigpe1xuICAgICAgICB0aGlzLl9tYXAgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICB0aGlzLl9pZG1hcCA9IG5ldyBNYXAoKTtcbiAgICB9XG4gICAgYWRkKHNjaGVtYSwgLi4uX21ldGEpIHtcbiAgICAgICAgY29uc3QgbWV0YSA9IF9tZXRhWzBdO1xuICAgICAgICB0aGlzLl9tYXAuc2V0KHNjaGVtYSwgbWV0YSk7XG4gICAgICAgIGlmIChtZXRhICYmIHR5cGVvZiBtZXRhID09PSBcIm9iamVjdFwiICYmIFwiaWRcIiBpbiBtZXRhKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5faWRtYXAuaGFzKG1ldGEuaWQpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJRCAke21ldGEuaWR9IGFscmVhZHkgZXhpc3RzIGluIHRoZSByZWdpc3RyeWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5faWRtYXAuc2V0KG1ldGEuaWQsIHNjaGVtYSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGNsZWFyKCkge1xuICAgICAgICB0aGlzLl9tYXAgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICB0aGlzLl9pZG1hcCA9IG5ldyBNYXAoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHJlbW92ZShzY2hlbWEpIHtcbiAgICAgICAgY29uc3QgbWV0YSA9IHRoaXMuX21hcC5nZXQoc2NoZW1hKTtcbiAgICAgICAgaWYgKG1ldGEgJiYgdHlwZW9mIG1ldGEgPT09IFwib2JqZWN0XCIgJiYgXCJpZFwiIGluIG1ldGEpIHtcbiAgICAgICAgICAgIHRoaXMuX2lkbWFwLmRlbGV0ZShtZXRhLmlkKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9tYXAuZGVsZXRlKHNjaGVtYSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBnZXQoc2NoZW1hKSB7XG4gICAgICAgIC8vIHJldHVybiB0aGlzLl9tYXAuZ2V0KHNjaGVtYSkgYXMgYW55O1xuICAgICAgICAvLyBpbmhlcml0IG1ldGFkYXRhXG4gICAgICAgIGNvbnN0IHAgPSBzY2hlbWEuX3pvZC5wYXJlbnQ7XG4gICAgICAgIGlmIChwKSB7XG4gICAgICAgICAgICBjb25zdCBwbSA9IHtcbiAgICAgICAgICAgICAgICAuLi50aGlzLmdldChwKSA/PyB7fVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGRlbGV0ZSBwbS5pZDsgLy8gZG8gbm90IGluaGVyaXQgaWRcbiAgICAgICAgICAgIGNvbnN0IGYgPSB7XG4gICAgICAgICAgICAgICAgLi4ucG0sXG4gICAgICAgICAgICAgICAgLi4udGhpcy5fbWFwLmdldChzY2hlbWEpXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKGYpLmxlbmd0aCA/IGYgOiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX21hcC5nZXQoc2NoZW1hKTtcbiAgICB9XG4gICAgaGFzKHNjaGVtYSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWFwLmhhcyhzY2hlbWEpO1xuICAgIH1cbn1cbi8vIHJlZ2lzdHJpZXNcbmV4cG9ydCBmdW5jdGlvbiByZWdpc3RyeSgpIHtcbiAgICByZXR1cm4gbmV3ICRab2RSZWdpc3RyeSgpO1xufVxuZXhwb3J0IGNvbnN0IGdsb2JhbFJlZ2lzdHJ5ID0gLypAX19QVVJFX18qLyByZWdpc3RyeSgpO1xuIiwgImltcG9ydCAqIGFzIGNoZWNrcyBmcm9tIFwiLi9jaGVja3MuanNcIjtcbmltcG9ydCAqIGFzIHNjaGVtYXMgZnJvbSBcIi4vc2NoZW1hcy5qc1wiO1xuaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi91dGlsLmpzXCI7XG5leHBvcnQgZnVuY3Rpb24gX3N0cmluZyhDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfY29lcmNlZFN0cmluZyhDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgIGNvZXJjZTogdHJ1ZSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9lbWFpbChDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgIGZvcm1hdDogXCJlbWFpbFwiLFxuICAgICAgICBjaGVjazogXCJzdHJpbmdfZm9ybWF0XCIsXG4gICAgICAgIGFib3J0OiBmYWxzZSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9ndWlkKENsYXNzLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgZm9ybWF0OiBcImd1aWRcIixcbiAgICAgICAgY2hlY2s6IFwic3RyaW5nX2Zvcm1hdFwiLFxuICAgICAgICBhYm9ydDogZmFsc2UsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfdXVpZChDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgIGZvcm1hdDogXCJ1dWlkXCIsXG4gICAgICAgIGNoZWNrOiBcInN0cmluZ19mb3JtYXRcIixcbiAgICAgICAgYWJvcnQ6IGZhbHNlLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX3V1aWR2NChDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgIGZvcm1hdDogXCJ1dWlkXCIsXG4gICAgICAgIGNoZWNrOiBcInN0cmluZ19mb3JtYXRcIixcbiAgICAgICAgYWJvcnQ6IGZhbHNlLFxuICAgICAgICB2ZXJzaW9uOiBcInY0XCIsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfdXVpZHY2KENsYXNzLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgZm9ybWF0OiBcInV1aWRcIixcbiAgICAgICAgY2hlY2s6IFwic3RyaW5nX2Zvcm1hdFwiLFxuICAgICAgICBhYm9ydDogZmFsc2UsXG4gICAgICAgIHZlcnNpb246IFwidjZcIixcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF91dWlkdjcoQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICBmb3JtYXQ6IFwidXVpZFwiLFxuICAgICAgICBjaGVjazogXCJzdHJpbmdfZm9ybWF0XCIsXG4gICAgICAgIGFib3J0OiBmYWxzZSxcbiAgICAgICAgdmVyc2lvbjogXCJ2N1wiLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX3VybChDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgIGZvcm1hdDogXCJ1cmxcIixcbiAgICAgICAgY2hlY2s6IFwic3RyaW5nX2Zvcm1hdFwiLFxuICAgICAgICBhYm9ydDogZmFsc2UsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfZW1vamkoQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICBmb3JtYXQ6IFwiZW1vamlcIixcbiAgICAgICAgY2hlY2s6IFwic3RyaW5nX2Zvcm1hdFwiLFxuICAgICAgICBhYm9ydDogZmFsc2UsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfbmFub2lkKENsYXNzLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgZm9ybWF0OiBcIm5hbm9pZFwiLFxuICAgICAgICBjaGVjazogXCJzdHJpbmdfZm9ybWF0XCIsXG4gICAgICAgIGFib3J0OiBmYWxzZSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9jdWlkKENsYXNzLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgZm9ybWF0OiBcImN1aWRcIixcbiAgICAgICAgY2hlY2s6IFwic3RyaW5nX2Zvcm1hdFwiLFxuICAgICAgICBhYm9ydDogZmFsc2UsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfY3VpZDIoQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICBmb3JtYXQ6IFwiY3VpZDJcIixcbiAgICAgICAgY2hlY2s6IFwic3RyaW5nX2Zvcm1hdFwiLFxuICAgICAgICBhYm9ydDogZmFsc2UsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfdWxpZChDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgIGZvcm1hdDogXCJ1bGlkXCIsXG4gICAgICAgIGNoZWNrOiBcInN0cmluZ19mb3JtYXRcIixcbiAgICAgICAgYWJvcnQ6IGZhbHNlLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX3hpZChDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgIGZvcm1hdDogXCJ4aWRcIixcbiAgICAgICAgY2hlY2s6IFwic3RyaW5nX2Zvcm1hdFwiLFxuICAgICAgICBhYm9ydDogZmFsc2UsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfa3N1aWQoQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICBmb3JtYXQ6IFwia3N1aWRcIixcbiAgICAgICAgY2hlY2s6IFwic3RyaW5nX2Zvcm1hdFwiLFxuICAgICAgICBhYm9ydDogZmFsc2UsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfaXB2NChDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgIGZvcm1hdDogXCJpcHY0XCIsXG4gICAgICAgIGNoZWNrOiBcInN0cmluZ19mb3JtYXRcIixcbiAgICAgICAgYWJvcnQ6IGZhbHNlLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX2lwdjYoQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICBmb3JtYXQ6IFwiaXB2NlwiLFxuICAgICAgICBjaGVjazogXCJzdHJpbmdfZm9ybWF0XCIsXG4gICAgICAgIGFib3J0OiBmYWxzZSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9jaWRydjQoQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICBmb3JtYXQ6IFwiY2lkcnY0XCIsXG4gICAgICAgIGNoZWNrOiBcInN0cmluZ19mb3JtYXRcIixcbiAgICAgICAgYWJvcnQ6IGZhbHNlLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX2NpZHJ2NihDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgIGZvcm1hdDogXCJjaWRydjZcIixcbiAgICAgICAgY2hlY2s6IFwic3RyaW5nX2Zvcm1hdFwiLFxuICAgICAgICBhYm9ydDogZmFsc2UsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfYmFzZTY0KENsYXNzLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgZm9ybWF0OiBcImJhc2U2NFwiLFxuICAgICAgICBjaGVjazogXCJzdHJpbmdfZm9ybWF0XCIsXG4gICAgICAgIGFib3J0OiBmYWxzZSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9iYXNlNjR1cmwoQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICBmb3JtYXQ6IFwiYmFzZTY0dXJsXCIsXG4gICAgICAgIGNoZWNrOiBcInN0cmluZ19mb3JtYXRcIixcbiAgICAgICAgYWJvcnQ6IGZhbHNlLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX2UxNjQoQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICBmb3JtYXQ6IFwiZTE2NFwiLFxuICAgICAgICBjaGVjazogXCJzdHJpbmdfZm9ybWF0XCIsXG4gICAgICAgIGFib3J0OiBmYWxzZSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9qd3QoQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICBmb3JtYXQ6IFwiand0XCIsXG4gICAgICAgIGNoZWNrOiBcInN0cmluZ19mb3JtYXRcIixcbiAgICAgICAgYWJvcnQ6IGZhbHNlLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgY29uc3QgVGltZVByZWNpc2lvbiA9IHtcbiAgICBBbnk6IG51bGwsXG4gICAgTWludXRlOiAtMSxcbiAgICBTZWNvbmQ6IDAsXG4gICAgTWlsbGlzZWNvbmQ6IDMsXG4gICAgTWljcm9zZWNvbmQ6IDZcbn07XG5leHBvcnQgZnVuY3Rpb24gX2lzb0RhdGVUaW1lKENsYXNzLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgZm9ybWF0OiBcImRhdGV0aW1lXCIsXG4gICAgICAgIGNoZWNrOiBcInN0cmluZ19mb3JtYXRcIixcbiAgICAgICAgb2Zmc2V0OiBmYWxzZSxcbiAgICAgICAgbG9jYWw6IGZhbHNlLFxuICAgICAgICBwcmVjaXNpb246IG51bGwsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfaXNvRGF0ZShDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgIGZvcm1hdDogXCJkYXRlXCIsXG4gICAgICAgIGNoZWNrOiBcInN0cmluZ19mb3JtYXRcIixcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9pc29UaW1lKENsYXNzLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgZm9ybWF0OiBcInRpbWVcIixcbiAgICAgICAgY2hlY2s6IFwic3RyaW5nX2Zvcm1hdFwiLFxuICAgICAgICBwcmVjaXNpb246IG51bGwsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfaXNvRHVyYXRpb24oQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICBmb3JtYXQ6IFwiZHVyYXRpb25cIixcbiAgICAgICAgY2hlY2s6IFwic3RyaW5nX2Zvcm1hdFwiLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX251bWJlcihDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwibnVtYmVyXCIsXG4gICAgICAgIGNoZWNrczogW10sXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfY29lcmNlZE51bWJlcihDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwibnVtYmVyXCIsXG4gICAgICAgIGNvZXJjZTogdHJ1ZSxcbiAgICAgICAgY2hlY2tzOiBbXSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9pbnQoQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcIm51bWJlclwiLFxuICAgICAgICBjaGVjazogXCJudW1iZXJfZm9ybWF0XCIsXG4gICAgICAgIGFib3J0OiBmYWxzZSxcbiAgICAgICAgZm9ybWF0OiBcInNhZmVpbnRcIixcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9mbG9hdDMyKENsYXNzLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJudW1iZXJcIixcbiAgICAgICAgY2hlY2s6IFwibnVtYmVyX2Zvcm1hdFwiLFxuICAgICAgICBhYm9ydDogZmFsc2UsXG4gICAgICAgIGZvcm1hdDogXCJmbG9hdDMyXCIsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfZmxvYXQ2NChDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwibnVtYmVyXCIsXG4gICAgICAgIGNoZWNrOiBcIm51bWJlcl9mb3JtYXRcIixcbiAgICAgICAgYWJvcnQ6IGZhbHNlLFxuICAgICAgICBmb3JtYXQ6IFwiZmxvYXQ2NFwiLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX2ludDMyKENsYXNzLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJudW1iZXJcIixcbiAgICAgICAgY2hlY2s6IFwibnVtYmVyX2Zvcm1hdFwiLFxuICAgICAgICBhYm9ydDogZmFsc2UsXG4gICAgICAgIGZvcm1hdDogXCJpbnQzMlwiLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX3VpbnQzMihDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwibnVtYmVyXCIsXG4gICAgICAgIGNoZWNrOiBcIm51bWJlcl9mb3JtYXRcIixcbiAgICAgICAgYWJvcnQ6IGZhbHNlLFxuICAgICAgICBmb3JtYXQ6IFwidWludDMyXCIsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfYm9vbGVhbihDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwiYm9vbGVhblwiLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX2NvZXJjZWRCb29sZWFuKENsYXNzLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJib29sZWFuXCIsXG4gICAgICAgIGNvZXJjZTogdHJ1ZSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9iaWdpbnQoQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcImJpZ2ludFwiLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX2NvZXJjZWRCaWdpbnQoQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcImJpZ2ludFwiLFxuICAgICAgICBjb2VyY2U6IHRydWUsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfaW50NjQoQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcImJpZ2ludFwiLFxuICAgICAgICBjaGVjazogXCJiaWdpbnRfZm9ybWF0XCIsXG4gICAgICAgIGFib3J0OiBmYWxzZSxcbiAgICAgICAgZm9ybWF0OiBcImludDY0XCIsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfdWludDY0KENsYXNzLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJiaWdpbnRcIixcbiAgICAgICAgY2hlY2s6IFwiYmlnaW50X2Zvcm1hdFwiLFxuICAgICAgICBhYm9ydDogZmFsc2UsXG4gICAgICAgIGZvcm1hdDogXCJ1aW50NjRcIixcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9zeW1ib2woQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcInN5bWJvbFwiLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX3VuZGVmaW5lZChDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwidW5kZWZpbmVkXCIsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfbnVsbChDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwibnVsbFwiLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX2FueShDbGFzcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcImFueVwiXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX3Vua25vd24oQ2xhc3MpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJ1bmtub3duXCJcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfbmV2ZXIoQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcIm5ldmVyXCIsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfdm9pZChDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwidm9pZFwiLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX2RhdGUoQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcImRhdGVcIixcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9jb2VyY2VkRGF0ZShDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwiZGF0ZVwiLFxuICAgICAgICBjb2VyY2U6IHRydWUsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfbmFuKENsYXNzLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJuYW5cIixcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9sdCh2YWx1ZSwgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBjaGVja3MuJFpvZENoZWNrTGVzc1RoYW4oe1xuICAgICAgICBjaGVjazogXCJsZXNzX3RoYW5cIixcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKSxcbiAgICAgICAgdmFsdWUsXG4gICAgICAgIGluY2x1c2l2ZTogZmFsc2VcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfbHRlKHZhbHVlLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IGNoZWNrcy4kWm9kQ2hlY2tMZXNzVGhhbih7XG4gICAgICAgIGNoZWNrOiBcImxlc3NfdGhhblwiLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpLFxuICAgICAgICB2YWx1ZSxcbiAgICAgICAgaW5jbHVzaXZlOiB0cnVlXG4gICAgfSk7XG59XG5leHBvcnQgeyAvKiogQGRlcHJlY2F0ZWQgVXNlIGB6Lmx0ZSgpYCBpbnN0ZWFkLiAqLyBfbHRlIGFzIF9tYXggfTtcbmV4cG9ydCBmdW5jdGlvbiBfZ3QodmFsdWUsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgY2hlY2tzLiRab2RDaGVja0dyZWF0ZXJUaGFuKHtcbiAgICAgICAgY2hlY2s6IFwiZ3JlYXRlcl90aGFuXCIsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcyksXG4gICAgICAgIHZhbHVlLFxuICAgICAgICBpbmNsdXNpdmU6IGZhbHNlXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX2d0ZSh2YWx1ZSwgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBjaGVja3MuJFpvZENoZWNrR3JlYXRlclRoYW4oe1xuICAgICAgICBjaGVjazogXCJncmVhdGVyX3RoYW5cIixcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKSxcbiAgICAgICAgdmFsdWUsXG4gICAgICAgIGluY2x1c2l2ZTogdHJ1ZVxuICAgIH0pO1xufVxuZXhwb3J0IHsgLyoqIEBkZXByZWNhdGVkIFVzZSBgei5ndGUoKWAgaW5zdGVhZC4gKi8gX2d0ZSBhcyBfbWluIH07XG5leHBvcnQgZnVuY3Rpb24gX3Bvc2l0aXZlKHBhcmFtcykge1xuICAgIHJldHVybiBfZ3QoMCwgcGFyYW1zKTtcbn1cbi8vIG5lZ2F0aXZlXG5leHBvcnQgZnVuY3Rpb24gX25lZ2F0aXZlKHBhcmFtcykge1xuICAgIHJldHVybiBfbHQoMCwgcGFyYW1zKTtcbn1cbi8vIG5vbnBvc2l0aXZlXG5leHBvcnQgZnVuY3Rpb24gX25vbnBvc2l0aXZlKHBhcmFtcykge1xuICAgIHJldHVybiBfbHRlKDAsIHBhcmFtcyk7XG59XG4vLyBub25uZWdhdGl2ZVxuZXhwb3J0IGZ1bmN0aW9uIF9ub25uZWdhdGl2ZShwYXJhbXMpIHtcbiAgICByZXR1cm4gX2d0ZSgwLCBwYXJhbXMpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9tdWx0aXBsZU9mKHZhbHVlLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IGNoZWNrcy4kWm9kQ2hlY2tNdWx0aXBsZU9mKHtcbiAgICAgICAgY2hlY2s6IFwibXVsdGlwbGVfb2ZcIixcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKSxcbiAgICAgICAgdmFsdWVcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfbWF4U2l6ZShtYXhpbXVtLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IGNoZWNrcy4kWm9kQ2hlY2tNYXhTaXplKHtcbiAgICAgICAgY2hlY2s6IFwibWF4X3NpemVcIixcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKSxcbiAgICAgICAgbWF4aW11bVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9taW5TaXplKG1pbmltdW0sIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgY2hlY2tzLiRab2RDaGVja01pblNpemUoe1xuICAgICAgICBjaGVjazogXCJtaW5fc2l6ZVwiLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpLFxuICAgICAgICBtaW5pbXVtXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX3NpemUoc2l6ZSwgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBjaGVja3MuJFpvZENoZWNrU2l6ZUVxdWFscyh7XG4gICAgICAgIGNoZWNrOiBcInNpemVfZXF1YWxzXCIsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcyksXG4gICAgICAgIHNpemVcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfbWF4TGVuZ3RoKG1heGltdW0sIHBhcmFtcykge1xuICAgIGNvbnN0IGNoID0gbmV3IGNoZWNrcy4kWm9kQ2hlY2tNYXhMZW5ndGgoe1xuICAgICAgICBjaGVjazogXCJtYXhfbGVuZ3RoXCIsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcyksXG4gICAgICAgIG1heGltdW1cbiAgICB9KTtcbiAgICByZXR1cm4gY2g7XG59XG5leHBvcnQgZnVuY3Rpb24gX21pbkxlbmd0aChtaW5pbXVtLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IGNoZWNrcy4kWm9kQ2hlY2tNaW5MZW5ndGgoe1xuICAgICAgICBjaGVjazogXCJtaW5fbGVuZ3RoXCIsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcyksXG4gICAgICAgIG1pbmltdW1cbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfbGVuZ3RoKGxlbmd0aCwgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBjaGVja3MuJFpvZENoZWNrTGVuZ3RoRXF1YWxzKHtcbiAgICAgICAgY2hlY2s6IFwibGVuZ3RoX2VxdWFsc1wiLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpLFxuICAgICAgICBsZW5ndGhcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfcmVnZXgocGF0dGVybiwgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBjaGVja3MuJFpvZENoZWNrUmVnZXgoe1xuICAgICAgICBjaGVjazogXCJzdHJpbmdfZm9ybWF0XCIsXG4gICAgICAgIGZvcm1hdDogXCJyZWdleFwiLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpLFxuICAgICAgICBwYXR0ZXJuXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX2xvd2VyY2FzZShwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IGNoZWNrcy4kWm9kQ2hlY2tMb3dlckNhc2Uoe1xuICAgICAgICBjaGVjazogXCJzdHJpbmdfZm9ybWF0XCIsXG4gICAgICAgIGZvcm1hdDogXCJsb3dlcmNhc2VcIixcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF91cHBlcmNhc2UocGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBjaGVja3MuJFpvZENoZWNrVXBwZXJDYXNlKHtcbiAgICAgICAgY2hlY2s6IFwic3RyaW5nX2Zvcm1hdFwiLFxuICAgICAgICBmb3JtYXQ6IFwidXBwZXJjYXNlXCIsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfaW5jbHVkZXMoaW5jbHVkZXMsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgY2hlY2tzLiRab2RDaGVja0luY2x1ZGVzKHtcbiAgICAgICAgY2hlY2s6IFwic3RyaW5nX2Zvcm1hdFwiLFxuICAgICAgICBmb3JtYXQ6IFwiaW5jbHVkZXNcIixcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKSxcbiAgICAgICAgaW5jbHVkZXNcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfc3RhcnRzV2l0aChwcmVmaXgsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgY2hlY2tzLiRab2RDaGVja1N0YXJ0c1dpdGgoe1xuICAgICAgICBjaGVjazogXCJzdHJpbmdfZm9ybWF0XCIsXG4gICAgICAgIGZvcm1hdDogXCJzdGFydHNfd2l0aFwiLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpLFxuICAgICAgICBwcmVmaXhcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfZW5kc1dpdGgoc3VmZml4LCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IGNoZWNrcy4kWm9kQ2hlY2tFbmRzV2l0aCh7XG4gICAgICAgIGNoZWNrOiBcInN0cmluZ19mb3JtYXRcIixcbiAgICAgICAgZm9ybWF0OiBcImVuZHNfd2l0aFwiLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpLFxuICAgICAgICBzdWZmaXhcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfcHJvcGVydHkocHJvcGVydHksIHNjaGVtYSwgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBjaGVja3MuJFpvZENoZWNrUHJvcGVydHkoe1xuICAgICAgICBjaGVjazogXCJwcm9wZXJ0eVwiLFxuICAgICAgICBwcm9wZXJ0eSxcbiAgICAgICAgc2NoZW1hLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX21pbWUodHlwZXMsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgY2hlY2tzLiRab2RDaGVja01pbWVUeXBlKHtcbiAgICAgICAgY2hlY2s6IFwibWltZV90eXBlXCIsXG4gICAgICAgIG1pbWU6IHR5cGVzLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX292ZXJ3cml0ZSh0eCkge1xuICAgIHJldHVybiBuZXcgY2hlY2tzLiRab2RDaGVja092ZXJ3cml0ZSh7XG4gICAgICAgIGNoZWNrOiBcIm92ZXJ3cml0ZVwiLFxuICAgICAgICB0eFxuICAgIH0pO1xufVxuLy8gbm9ybWFsaXplXG5leHBvcnQgZnVuY3Rpb24gX25vcm1hbGl6ZShmb3JtKSB7XG4gICAgcmV0dXJuIF9vdmVyd3JpdGUoKGlucHV0KT0+aW5wdXQubm9ybWFsaXplKGZvcm0pKTtcbn1cbi8vIHRyaW1cbmV4cG9ydCBmdW5jdGlvbiBfdHJpbSgpIHtcbiAgICByZXR1cm4gX292ZXJ3cml0ZSgoaW5wdXQpPT5pbnB1dC50cmltKCkpO1xufVxuLy8gdG9Mb3dlckNhc2VcbmV4cG9ydCBmdW5jdGlvbiBfdG9Mb3dlckNhc2UoKSB7XG4gICAgcmV0dXJuIF9vdmVyd3JpdGUoKGlucHV0KT0+aW5wdXQudG9Mb3dlckNhc2UoKSk7XG59XG4vLyB0b1VwcGVyQ2FzZVxuZXhwb3J0IGZ1bmN0aW9uIF90b1VwcGVyQ2FzZSgpIHtcbiAgICByZXR1cm4gX292ZXJ3cml0ZSgoaW5wdXQpPT5pbnB1dC50b1VwcGVyQ2FzZSgpKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfYXJyYXkoQ2xhc3MsIGVsZW1lbnQsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcImFycmF5XCIsXG4gICAgICAgIGVsZW1lbnQsXG4gICAgICAgIC8vIGdldCBlbGVtZW50KCkge1xuICAgICAgICAvLyAgIHJldHVybiBlbGVtZW50O1xuICAgICAgICAvLyB9LFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX3VuaW9uKENsYXNzLCBvcHRpb25zLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJ1bmlvblwiLFxuICAgICAgICBvcHRpb25zLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX2Rpc2NyaW1pbmF0ZWRVbmlvbihDbGFzcywgZGlzY3JpbWluYXRvciwgb3B0aW9ucywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwidW5pb25cIixcbiAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgZGlzY3JpbWluYXRvcixcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9pbnRlcnNlY3Rpb24oQ2xhc3MsIGxlZnQsIHJpZ2h0KSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwiaW50ZXJzZWN0aW9uXCIsXG4gICAgICAgIGxlZnQsXG4gICAgICAgIHJpZ2h0XG4gICAgfSk7XG59XG4vLyBleHBvcnQgZnVuY3Rpb24gX3R1cGxlKFxuLy8gICBDbGFzczogdXRpbC5TY2hlbWFDbGFzczxzY2hlbWFzLiRab2RUdXBsZT4sXG4vLyAgIGl0ZW1zOiBbXSxcbi8vICAgcGFyYW1zPzogc3RyaW5nIHwgJFpvZFR1cGxlUGFyYW1zXG4vLyApOiBzY2hlbWFzLiRab2RUdXBsZTxbXSwgbnVsbD47XG5leHBvcnQgZnVuY3Rpb24gX3R1cGxlKENsYXNzLCBpdGVtcywgX3BhcmFtc09yUmVzdCwgX3BhcmFtcykge1xuICAgIGNvbnN0IGhhc1Jlc3QgPSBfcGFyYW1zT3JSZXN0IGluc3RhbmNlb2Ygc2NoZW1hcy4kWm9kVHlwZTtcbiAgICBjb25zdCBwYXJhbXMgPSBoYXNSZXN0ID8gX3BhcmFtcyA6IF9wYXJhbXNPclJlc3Q7XG4gICAgY29uc3QgcmVzdCA9IGhhc1Jlc3QgPyBfcGFyYW1zT3JSZXN0IDogbnVsbDtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJ0dXBsZVwiLFxuICAgICAgICBpdGVtcyxcbiAgICAgICAgcmVzdCxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9yZWNvcmQoQ2xhc3MsIGtleVR5cGUsIHZhbHVlVHlwZSwgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwicmVjb3JkXCIsXG4gICAgICAgIGtleVR5cGUsXG4gICAgICAgIHZhbHVlVHlwZSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9tYXAoQ2xhc3MsIGtleVR5cGUsIHZhbHVlVHlwZSwgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwibWFwXCIsXG4gICAgICAgIGtleVR5cGUsXG4gICAgICAgIHZhbHVlVHlwZSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9zZXQoQ2xhc3MsIHZhbHVlVHlwZSwgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwic2V0XCIsXG4gICAgICAgIHZhbHVlVHlwZSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9lbnVtKENsYXNzLCB2YWx1ZXMsIHBhcmFtcykge1xuICAgIGNvbnN0IGVudHJpZXMgPSBBcnJheS5pc0FycmF5KHZhbHVlcykgPyBPYmplY3QuZnJvbUVudHJpZXModmFsdWVzLm1hcCgodik9PltcbiAgICAgICAgICAgIHYsXG4gICAgICAgICAgICB2XG4gICAgICAgIF0pKSA6IHZhbHVlcztcbiAgICAvLyBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZXMpKSB7XG4gICAgLy8gICBmb3IgKGNvbnN0IHZhbHVlIG9mIHZhbHVlcykge1xuICAgIC8vICAgICBlbnRyaWVzW3ZhbHVlXSA9IHZhbHVlO1xuICAgIC8vICAgfVxuICAgIC8vIH0gZWxzZSB7XG4gICAgLy8gICBPYmplY3QuYXNzaWduKGVudHJpZXMsIHZhbHVlcyk7XG4gICAgLy8gfVxuICAgIC8vIGNvbnN0IGVudHJpZXM6IHV0aWwuRW51bUxpa2UgPSB7fTtcbiAgICAvLyBmb3IgKGNvbnN0IHZhbCBvZiB2YWx1ZXMpIHtcbiAgICAvLyAgIGVudHJpZXNbdmFsXSA9IHZhbDtcbiAgICAvLyB9XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwiZW51bVwiLFxuICAgICAgICBlbnRyaWVzLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG4vKiogQGRlcHJlY2F0ZWQgVGhpcyBBUEkgaGFzIGJlZW4gbWVyZ2VkIGludG8gYHouZW51bSgpYC4gVXNlIGB6LmVudW0oKWAgaW5zdGVhZC5cbiAqXG4gKiBgYGB0c1xuICogZW51bSBDb2xvcnMgeyByZWQsIGdyZWVuLCBibHVlIH1cbiAqIHouZW51bShDb2xvcnMpO1xuICogYGBgXG4gKi8gZXhwb3J0IGZ1bmN0aW9uIF9uYXRpdmVFbnVtKENsYXNzLCBlbnRyaWVzLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJlbnVtXCIsXG4gICAgICAgIGVudHJpZXMsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfbGl0ZXJhbChDbGFzcywgdmFsdWUsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcImxpdGVyYWxcIixcbiAgICAgICAgdmFsdWVzOiBBcnJheS5pc0FycmF5KHZhbHVlKSA/IHZhbHVlIDogW1xuICAgICAgICAgICAgdmFsdWVcbiAgICAgICAgXSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9maWxlKENsYXNzLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJmaWxlXCIsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfdHJhbnNmb3JtKENsYXNzLCBmbikge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcInRyYW5zZm9ybVwiLFxuICAgICAgICB0cmFuc2Zvcm06IGZuXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX29wdGlvbmFsKENsYXNzLCBpbm5lclR5cGUpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJvcHRpb25hbFwiLFxuICAgICAgICBpbm5lclR5cGVcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfbnVsbGFibGUoQ2xhc3MsIGlubmVyVHlwZSkge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcIm51bGxhYmxlXCIsXG4gICAgICAgIGlubmVyVHlwZVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9kZWZhdWx0KENsYXNzLCBpbm5lclR5cGUsIGRlZmF1bHRWYWx1ZSkge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcImRlZmF1bHRcIixcbiAgICAgICAgaW5uZXJUeXBlLFxuICAgICAgICBnZXQgZGVmYXVsdFZhbHVlICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0eXBlb2YgZGVmYXVsdFZhbHVlID09PSBcImZ1bmN0aW9uXCIgPyBkZWZhdWx0VmFsdWUoKSA6IHV0aWwuc2hhbGxvd0Nsb25lKGRlZmF1bHRWYWx1ZSk7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfbm9ub3B0aW9uYWwoQ2xhc3MsIGlubmVyVHlwZSwgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwibm9ub3B0aW9uYWxcIixcbiAgICAgICAgaW5uZXJUeXBlLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX3N1Y2Nlc3MoQ2xhc3MsIGlubmVyVHlwZSkge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcInN1Y2Nlc3NcIixcbiAgICAgICAgaW5uZXJUeXBlXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX2NhdGNoKENsYXNzLCBpbm5lclR5cGUsIGNhdGNoVmFsdWUpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJjYXRjaFwiLFxuICAgICAgICBpbm5lclR5cGUsXG4gICAgICAgIGNhdGNoVmFsdWU6IHR5cGVvZiBjYXRjaFZhbHVlID09PSBcImZ1bmN0aW9uXCIgPyBjYXRjaFZhbHVlIDogKCk9PmNhdGNoVmFsdWVcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfcGlwZShDbGFzcywgaW5fLCBvdXQpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJwaXBlXCIsXG4gICAgICAgIGluOiBpbl8sXG4gICAgICAgIG91dFxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9yZWFkb25seShDbGFzcywgaW5uZXJUeXBlKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwicmVhZG9ubHlcIixcbiAgICAgICAgaW5uZXJUeXBlXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX3RlbXBsYXRlTGl0ZXJhbChDbGFzcywgcGFydHMsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcInRlbXBsYXRlX2xpdGVyYWxcIixcbiAgICAgICAgcGFydHMsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfbGF6eShDbGFzcywgZ2V0dGVyKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwibGF6eVwiLFxuICAgICAgICBnZXR0ZXJcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfcHJvbWlzZShDbGFzcywgaW5uZXJUeXBlKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwicHJvbWlzZVwiLFxuICAgICAgICBpbm5lclR5cGVcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfY3VzdG9tKENsYXNzLCBmbiwgX3BhcmFtcykge1xuICAgIGNvbnN0IG5vcm0gPSB1dGlsLm5vcm1hbGl6ZVBhcmFtcyhfcGFyYW1zKTtcbiAgICBub3JtLmFib3J0ID8/IChub3JtLmFib3J0ID0gdHJ1ZSk7IC8vIGRlZmF1bHQgdG8gYWJvcnQ6ZmFsc2VcbiAgICBjb25zdCBzY2hlbWEgPSBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcImN1c3RvbVwiLFxuICAgICAgICBjaGVjazogXCJjdXN0b21cIixcbiAgICAgICAgZm46IGZuLFxuICAgICAgICAuLi5ub3JtXG4gICAgfSk7XG4gICAgcmV0dXJuIHNjaGVtYTtcbn1cbi8vIHNhbWUgYXMgX2N1c3RvbSBidXQgZGVmYXVsdHMgdG8gYWJvcnQ6ZmFsc2VcbmV4cG9ydCBmdW5jdGlvbiBfcmVmaW5lKENsYXNzLCBmbiwgX3BhcmFtcykge1xuICAgIGNvbnN0IHNjaGVtYSA9IG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwiY3VzdG9tXCIsXG4gICAgICAgIGNoZWNrOiBcImN1c3RvbVwiLFxuICAgICAgICBmbjogZm4sXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKF9wYXJhbXMpXG4gICAgfSk7XG4gICAgcmV0dXJuIHNjaGVtYTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfc3VwZXJSZWZpbmUoZm4pIHtcbiAgICBjb25zdCBjaCA9IF9jaGVjaygocGF5bG9hZCk9PntcbiAgICAgICAgcGF5bG9hZC5hZGRJc3N1ZSA9IChpc3N1ZSk9PntcbiAgICAgICAgICAgIGlmICh0eXBlb2YgaXNzdWUgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHV0aWwuaXNzdWUoaXNzdWUsIHBheWxvYWQudmFsdWUsIGNoLl96b2QuZGVmKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIGZvciBab2QgMyBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eVxuICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZmF0YWwpIF9pc3N1ZS5jb250aW51ZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIF9pc3N1ZS5jb2RlID8/IChfaXNzdWUuY29kZSA9IFwiY3VzdG9tXCIpO1xuICAgICAgICAgICAgICAgIF9pc3N1ZS5pbnB1dCA/PyAoX2lzc3VlLmlucHV0ID0gcGF5bG9hZC52YWx1ZSk7XG4gICAgICAgICAgICAgICAgX2lzc3VlLmluc3QgPz8gKF9pc3N1ZS5pbnN0ID0gY2gpO1xuICAgICAgICAgICAgICAgIF9pc3N1ZS5jb250aW51ZSA/PyAoX2lzc3VlLmNvbnRpbnVlID0gIWNoLl96b2QuZGVmLmFib3J0KTsgLy8gYWJvcnQgaXMgYWx3YXlzIHVuZGVmaW5lZCwgc28gdGhpcyBpcyBhbHdheXMgdHJ1ZS4uLlxuICAgICAgICAgICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2godXRpbC5pc3N1ZShfaXNzdWUpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIGZuKHBheWxvYWQudmFsdWUsIHBheWxvYWQpO1xuICAgIH0pO1xuICAgIHJldHVybiBjaDtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfY2hlY2soZm4sIHBhcmFtcykge1xuICAgIGNvbnN0IGNoID0gbmV3IGNoZWNrcy4kWm9kQ2hlY2soe1xuICAgICAgICBjaGVjazogXCJjdXN0b21cIixcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xuICAgIGNoLl96b2QuY2hlY2sgPSBmbjtcbiAgICByZXR1cm4gY2g7XG59XG5leHBvcnQgZnVuY3Rpb24gX3N0cmluZ2Jvb2woQ2xhc3NlcywgX3BhcmFtcykge1xuICAgIGNvbnN0IHBhcmFtcyA9IHV0aWwubm9ybWFsaXplUGFyYW1zKF9wYXJhbXMpO1xuICAgIGxldCB0cnV0aHlBcnJheSA9IHBhcmFtcy50cnV0aHkgPz8gW1xuICAgICAgICBcInRydWVcIixcbiAgICAgICAgXCIxXCIsXG4gICAgICAgIFwieWVzXCIsXG4gICAgICAgIFwib25cIixcbiAgICAgICAgXCJ5XCIsXG4gICAgICAgIFwiZW5hYmxlZFwiXG4gICAgXTtcbiAgICBsZXQgZmFsc3lBcnJheSA9IHBhcmFtcy5mYWxzeSA/PyBbXG4gICAgICAgIFwiZmFsc2VcIixcbiAgICAgICAgXCIwXCIsXG4gICAgICAgIFwibm9cIixcbiAgICAgICAgXCJvZmZcIixcbiAgICAgICAgXCJuXCIsXG4gICAgICAgIFwiZGlzYWJsZWRcIlxuICAgIF07XG4gICAgaWYgKHBhcmFtcy5jYXNlICE9PSBcInNlbnNpdGl2ZVwiKSB7XG4gICAgICAgIHRydXRoeUFycmF5ID0gdHJ1dGh5QXJyYXkubWFwKCh2KT0+dHlwZW9mIHYgPT09IFwic3RyaW5nXCIgPyB2LnRvTG93ZXJDYXNlKCkgOiB2KTtcbiAgICAgICAgZmFsc3lBcnJheSA9IGZhbHN5QXJyYXkubWFwKCh2KT0+dHlwZW9mIHYgPT09IFwic3RyaW5nXCIgPyB2LnRvTG93ZXJDYXNlKCkgOiB2KTtcbiAgICB9XG4gICAgY29uc3QgdHJ1dGh5U2V0ID0gbmV3IFNldCh0cnV0aHlBcnJheSk7XG4gICAgY29uc3QgZmFsc3lTZXQgPSBuZXcgU2V0KGZhbHN5QXJyYXkpO1xuICAgIGNvbnN0IF9Db2RlYyA9IENsYXNzZXMuQ29kZWMgPz8gc2NoZW1hcy4kWm9kQ29kZWM7XG4gICAgY29uc3QgX0Jvb2xlYW4gPSBDbGFzc2VzLkJvb2xlYW4gPz8gc2NoZW1hcy4kWm9kQm9vbGVhbjtcbiAgICBjb25zdCBfU3RyaW5nID0gQ2xhc3Nlcy5TdHJpbmcgPz8gc2NoZW1hcy4kWm9kU3RyaW5nO1xuICAgIGNvbnN0IHN0cmluZ1NjaGVtYSA9IG5ldyBfU3RyaW5nKHtcbiAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgZXJyb3I6IHBhcmFtcy5lcnJvclxuICAgIH0pO1xuICAgIGNvbnN0IGJvb2xlYW5TY2hlbWEgPSBuZXcgX0Jvb2xlYW4oe1xuICAgICAgICB0eXBlOiBcImJvb2xlYW5cIixcbiAgICAgICAgZXJyb3I6IHBhcmFtcy5lcnJvclxuICAgIH0pO1xuICAgIGNvbnN0IGNvZGVjID0gbmV3IF9Db2RlYyh7XG4gICAgICAgIHR5cGU6IFwicGlwZVwiLFxuICAgICAgICBpbjogc3RyaW5nU2NoZW1hLFxuICAgICAgICBvdXQ6IGJvb2xlYW5TY2hlbWEsXG4gICAgICAgIHRyYW5zZm9ybTogKGlucHV0LCBwYXlsb2FkKT0+e1xuICAgICAgICAgICAgbGV0IGRhdGEgPSBpbnB1dDtcbiAgICAgICAgICAgIGlmIChwYXJhbXMuY2FzZSAhPT0gXCJzZW5zaXRpdmVcIikgZGF0YSA9IGRhdGEudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgICAgIGlmICh0cnV0aHlTZXQuaGFzKGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGZhbHN5U2V0LmhhcyhkYXRhKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF92YWx1ZVwiLFxuICAgICAgICAgICAgICAgICAgICBleHBlY3RlZDogXCJzdHJpbmdib29sXCIsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlczogW1xuICAgICAgICAgICAgICAgICAgICAgICAgLi4udHJ1dGh5U2V0LFxuICAgICAgICAgICAgICAgICAgICAgICAgLi4uZmFsc3lTZXRcbiAgICAgICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICAgICAgaW5wdXQ6IHBheWxvYWQudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIGluc3Q6IGNvZGVjLFxuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTogZmFsc2VcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4ge307XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIHJldmVyc2VUcmFuc2Zvcm06IChpbnB1dCwgX3BheWxvYWQpPT57XG4gICAgICAgICAgICBpZiAoaW5wdXQgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1dGh5QXJyYXlbMF0gfHwgXCJ0cnVlXCI7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzeUFycmF5WzBdIHx8IFwiZmFsc2VcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6IHBhcmFtcy5lcnJvclxuICAgIH0pO1xuICAgIHJldHVybiBjb2RlYztcbn1cbmV4cG9ydCBmdW5jdGlvbiBfc3RyaW5nRm9ybWF0KENsYXNzLCBmb3JtYXQsIGZuT3JSZWdleCwgX3BhcmFtcyA9IHt9KSB7XG4gICAgY29uc3QgcGFyYW1zID0gdXRpbC5ub3JtYWxpemVQYXJhbXMoX3BhcmFtcyk7XG4gICAgY29uc3QgZGVmID0ge1xuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhfcGFyYW1zKSxcbiAgICAgICAgY2hlY2s6IFwic3RyaW5nX2Zvcm1hdFwiLFxuICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICBmb3JtYXQsXG4gICAgICAgIGZuOiB0eXBlb2YgZm5PclJlZ2V4ID09PSBcImZ1bmN0aW9uXCIgPyBmbk9yUmVnZXggOiAodmFsKT0+Zm5PclJlZ2V4LnRlc3QodmFsKSxcbiAgICAgICAgLi4ucGFyYW1zXG4gICAgfTtcbiAgICBpZiAoZm5PclJlZ2V4IGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgIGRlZi5wYXR0ZXJuID0gZm5PclJlZ2V4O1xuICAgIH1cbiAgICBjb25zdCBpbnN0ID0gbmV3IENsYXNzKGRlZik7XG4gICAgcmV0dXJuIGluc3Q7XG59XG4iLCAiaW1wb3J0IHsgJFpvZFJlZ2lzdHJ5LCBnbG9iYWxSZWdpc3RyeSB9IGZyb20gXCIuL3JlZ2lzdHJpZXMuanNcIjtcbmltcG9ydCB7IGdldEVudW1WYWx1ZXMgfSBmcm9tIFwiLi91dGlsLmpzXCI7XG5leHBvcnQgY2xhc3MgSlNPTlNjaGVtYUdlbmVyYXRvciB7XG4gICAgY29uc3RydWN0b3IocGFyYW1zKXtcbiAgICAgICAgdGhpcy5jb3VudGVyID0gMDtcbiAgICAgICAgdGhpcy5tZXRhZGF0YVJlZ2lzdHJ5ID0gcGFyYW1zPy5tZXRhZGF0YSA/PyBnbG9iYWxSZWdpc3RyeTtcbiAgICAgICAgdGhpcy50YXJnZXQgPSBwYXJhbXM/LnRhcmdldCA/PyBcImRyYWZ0LTIwMjAtMTJcIjtcbiAgICAgICAgdGhpcy51bnJlcHJlc2VudGFibGUgPSBwYXJhbXM/LnVucmVwcmVzZW50YWJsZSA/PyBcInRocm93XCI7XG4gICAgICAgIHRoaXMub3ZlcnJpZGUgPSBwYXJhbXM/Lm92ZXJyaWRlID8/ICgoKT0+e30pO1xuICAgICAgICB0aGlzLmlvID0gcGFyYW1zPy5pbyA/PyBcIm91dHB1dFwiO1xuICAgICAgICB0aGlzLnNlZW4gPSBuZXcgTWFwKCk7XG4gICAgfVxuICAgIHByb2Nlc3Moc2NoZW1hLCBfcGFyYW1zID0ge1xuICAgICAgICBwYXRoOiBbXSxcbiAgICAgICAgc2NoZW1hUGF0aDogW11cbiAgICB9KSB7XG4gICAgICAgIHZhciBfYTtcbiAgICAgICAgY29uc3QgZGVmID0gc2NoZW1hLl96b2QuZGVmO1xuICAgICAgICBjb25zdCBmb3JtYXRNYXAgPSB7XG4gICAgICAgICAgICBndWlkOiBcInV1aWRcIixcbiAgICAgICAgICAgIHVybDogXCJ1cmlcIixcbiAgICAgICAgICAgIGRhdGV0aW1lOiBcImRhdGUtdGltZVwiLFxuICAgICAgICAgICAganNvbl9zdHJpbmc6IFwianNvbi1zdHJpbmdcIixcbiAgICAgICAgICAgIHJlZ2V4OiBcIlwiXG4gICAgICAgIH07XG4gICAgICAgIC8vIGNoZWNrIGZvciBzY2hlbWEgaW4gc2VlbnNcbiAgICAgICAgY29uc3Qgc2VlbiA9IHRoaXMuc2Vlbi5nZXQoc2NoZW1hKTtcbiAgICAgICAgaWYgKHNlZW4pIHtcbiAgICAgICAgICAgIHNlZW4uY291bnQrKztcbiAgICAgICAgICAgIC8vIGNoZWNrIGlmIGN5Y2xlXG4gICAgICAgICAgICBjb25zdCBpc0N5Y2xlID0gX3BhcmFtcy5zY2hlbWFQYXRoLmluY2x1ZGVzKHNjaGVtYSk7XG4gICAgICAgICAgICBpZiAoaXNDeWNsZSkge1xuICAgICAgICAgICAgICAgIHNlZW4uY3ljbGUgPSBfcGFyYW1zLnBhdGg7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gc2Vlbi5zY2hlbWE7XG4gICAgICAgIH1cbiAgICAgICAgLy8gaW5pdGlhbGl6ZVxuICAgICAgICBjb25zdCByZXN1bHQgPSB7XG4gICAgICAgICAgICBzY2hlbWE6IHt9LFxuICAgICAgICAgICAgY291bnQ6IDEsXG4gICAgICAgICAgICBjeWNsZTogdW5kZWZpbmVkLFxuICAgICAgICAgICAgcGF0aDogX3BhcmFtcy5wYXRoXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuc2Vlbi5zZXQoc2NoZW1hLCByZXN1bHQpO1xuICAgICAgICAvLyBjdXN0b20gbWV0aG9kIG92ZXJyaWRlcyBkZWZhdWx0IGJlaGF2aW9yXG4gICAgICAgIGNvbnN0IG92ZXJyaWRlU2NoZW1hID0gc2NoZW1hLl96b2QudG9KU09OU2NoZW1hPy4oKTtcbiAgICAgICAgaWYgKG92ZXJyaWRlU2NoZW1hKSB7XG4gICAgICAgICAgICByZXN1bHQuc2NoZW1hID0gb3ZlcnJpZGVTY2hlbWE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgICAgICAgLi4uX3BhcmFtcyxcbiAgICAgICAgICAgICAgICBzY2hlbWFQYXRoOiBbXG4gICAgICAgICAgICAgICAgICAgIC4uLl9wYXJhbXMuc2NoZW1hUGF0aCxcbiAgICAgICAgICAgICAgICAgICAgc2NoZW1hXG4gICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICBwYXRoOiBfcGFyYW1zLnBhdGhcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBwYXJlbnQgPSBzY2hlbWEuX3pvZC5wYXJlbnQ7XG4gICAgICAgICAgICBpZiAocGFyZW50KSB7XG4gICAgICAgICAgICAgICAgLy8gc2NoZW1hIHdhcyBjbG9uZWQgZnJvbSBhbm90aGVyIHNjaGVtYVxuICAgICAgICAgICAgICAgIHJlc3VsdC5yZWYgPSBwYXJlbnQ7XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzKHBhcmVudCwgcGFyYW1zKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlZW4uZ2V0KHBhcmVudCkuaXNQYXJlbnQgPSB0cnVlO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBfanNvbiA9IHJlc3VsdC5zY2hlbWE7XG4gICAgICAgICAgICAgICAgc3dpdGNoKGRlZi50eXBlKXtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInN0cmluZ1wiOlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGpzb24gPSBfanNvbjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uLnR5cGUgPSBcInN0cmluZ1wiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgbWluaW11bSwgbWF4aW11bSwgZm9ybWF0LCBwYXR0ZXJucywgY29udGVudEVuY29kaW5nIH0gPSBzY2hlbWEuX3pvZC5iYWc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBtaW5pbXVtID09PSBcIm51bWJlclwiKSBqc29uLm1pbkxlbmd0aCA9IG1pbmltdW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBtYXhpbXVtID09PSBcIm51bWJlclwiKSBqc29uLm1heExlbmd0aCA9IG1heGltdW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY3VzdG9tIHBhdHRlcm4gb3ZlcnJpZGVzIGZvcm1hdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmb3JtYXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi5mb3JtYXQgPSBmb3JtYXRNYXBbZm9ybWF0XSA/PyBmb3JtYXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChqc29uLmZvcm1hdCA9PT0gXCJcIikgZGVsZXRlIGpzb24uZm9ybWF0OyAvLyBlbXB0eSBmb3JtYXQgaXMgbm90IHZhbGlkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50RW5jb2RpbmcpIGpzb24uY29udGVudEVuY29kaW5nID0gY29udGVudEVuY29kaW5nO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXR0ZXJucyAmJiBwYXR0ZXJucy5zaXplID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByZWdleGVzID0gW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4ucGF0dGVybnNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlZ2V4ZXMubGVuZ3RoID09PSAxKSBqc29uLnBhdHRlcm4gPSByZWdleGVzWzBdLnNvdXJjZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAocmVnZXhlcy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuc2NoZW1hLmFsbE9mID0gW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLnJlZ2V4ZXMubWFwKChyZWdleCk9Pih7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi50aGlzLnRhcmdldCA9PT0gXCJkcmFmdC03XCIgfHwgdGhpcy50YXJnZXQgPT09IFwiZHJhZnQtNFwiIHx8IHRoaXMudGFyZ2V0ID09PSBcIm9wZW5hcGktMy4wXCIgPyB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJzdHJpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSA6IHt9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0dGVybjogcmVnZXguc291cmNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGpzb24gPSBfanNvbjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7IG1pbmltdW0sIG1heGltdW0sIGZvcm1hdCwgbXVsdGlwbGVPZiwgZXhjbHVzaXZlTWF4aW11bSwgZXhjbHVzaXZlTWluaW11bSB9ID0gc2NoZW1hLl96b2QuYmFnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgZm9ybWF0ID09PSBcInN0cmluZ1wiICYmIGZvcm1hdC5pbmNsdWRlcyhcImludFwiKSkganNvbi50eXBlID0gXCJpbnRlZ2VyXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBqc29uLnR5cGUgPSBcIm51bWJlclwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgZXhjbHVzaXZlTWluaW11bSA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy50YXJnZXQgPT09IFwiZHJhZnQtNFwiIHx8IHRoaXMudGFyZ2V0ID09PSBcIm9wZW5hcGktMy4wXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24ubWluaW11bSA9IGV4Y2x1c2l2ZU1pbmltdW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uLmV4Y2x1c2l2ZU1pbmltdW0gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi5leGNsdXNpdmVNaW5pbXVtID0gZXhjbHVzaXZlTWluaW11bTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG1pbmltdW0gPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi5taW5pbXVtID0gbWluaW11bTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBleGNsdXNpdmVNaW5pbXVtID09PSBcIm51bWJlclwiICYmIHRoaXMudGFyZ2V0ICE9PSBcImRyYWZ0LTRcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV4Y2x1c2l2ZU1pbmltdW0gPj0gbWluaW11bSkgZGVsZXRlIGpzb24ubWluaW11bTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZGVsZXRlIGpzb24uZXhjbHVzaXZlTWluaW11bTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGV4Y2x1c2l2ZU1heGltdW0gPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMudGFyZ2V0ID09PSBcImRyYWZ0LTRcIiB8fCB0aGlzLnRhcmdldCA9PT0gXCJvcGVuYXBpLTMuMFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uLm1heGltdW0gPSBleGNsdXNpdmVNYXhpbXVtO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi5leGNsdXNpdmVNYXhpbXVtID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24uZXhjbHVzaXZlTWF4aW11bSA9IGV4Y2x1c2l2ZU1heGltdW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBtYXhpbXVtID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24ubWF4aW11bSA9IG1heGltdW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgZXhjbHVzaXZlTWF4aW11bSA9PT0gXCJudW1iZXJcIiAmJiB0aGlzLnRhcmdldCAhPT0gXCJkcmFmdC00XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChleGNsdXNpdmVNYXhpbXVtIDw9IG1heGltdW0pIGRlbGV0ZSBqc29uLm1heGltdW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGRlbGV0ZSBqc29uLmV4Y2x1c2l2ZU1heGltdW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBtdWx0aXBsZU9mID09PSBcIm51bWJlclwiKSBqc29uLm11bHRpcGxlT2YgPSBtdWx0aXBsZU9mO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiYm9vbGVhblwiOlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGpzb24gPSBfanNvbjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uLnR5cGUgPSBcImJvb2xlYW5cIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImJpZ2ludFwiOlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnVucmVwcmVzZW50YWJsZSA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkJpZ0ludCBjYW5ub3QgYmUgcmVwcmVzZW50ZWQgaW4gSlNPTiBTY2hlbWFcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwic3ltYm9sXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMudW5yZXByZXNlbnRhYmxlID09PSBcInRocm93XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU3ltYm9scyBjYW5ub3QgYmUgcmVwcmVzZW50ZWQgaW4gSlNPTiBTY2hlbWFcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwibnVsbFwiOlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnRhcmdldCA9PT0gXCJvcGVuYXBpLTMuMFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9qc29uLnR5cGUgPSBcInN0cmluZ1wiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfanNvbi5udWxsYWJsZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9qc29uLmVudW0gPSBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIF9qc29uLnR5cGUgPSBcIm51bGxcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImFueVwiOlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwidW5rbm93blwiOlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwidW5kZWZpbmVkXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMudW5yZXByZXNlbnRhYmxlID09PSBcInRocm93XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5kZWZpbmVkIGNhbm5vdCBiZSByZXByZXNlbnRlZCBpbiBKU09OIFNjaGVtYVwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJ2b2lkXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMudW5yZXByZXNlbnRhYmxlID09PSBcInRocm93XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVm9pZCBjYW5ub3QgYmUgcmVwcmVzZW50ZWQgaW4gSlNPTiBTY2hlbWFcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwibmV2ZXJcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfanNvbi5ub3QgPSB7fTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImRhdGVcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy51bnJlcHJlc2VudGFibGUgPT09IFwidGhyb3dcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJEYXRlIGNhbm5vdCBiZSByZXByZXNlbnRlZCBpbiBKU09OIFNjaGVtYVwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJhcnJheVwiOlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGpzb24gPSBfanNvbjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7IG1pbmltdW0sIG1heGltdW0gfSA9IHNjaGVtYS5fem9kLmJhZztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG1pbmltdW0gPT09IFwibnVtYmVyXCIpIGpzb24ubWluSXRlbXMgPSBtaW5pbXVtO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgbWF4aW11bSA9PT0gXCJudW1iZXJcIikganNvbi5tYXhJdGVtcyA9IG1heGltdW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi50eXBlID0gXCJhcnJheVwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24uaXRlbXMgPSB0aGlzLnByb2Nlc3MoZGVmLmVsZW1lbnQsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4ucGFyYW1zLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXRoOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5wYXJhbXMucGF0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiaXRlbXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBqc29uID0gX2pzb247XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi50eXBlID0gXCJvYmplY3RcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uLnByb3BlcnRpZXMgPSB7fTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzaGFwZSA9IGRlZi5zaGFwZTsgLy8gcGFyYW1zLnNoYXBlQ2FjaGUuZ2V0KHNjaGVtYSkhO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcihjb25zdCBrZXkgaW4gc2hhcGUpe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uLnByb3BlcnRpZXNba2V5XSA9IHRoaXMucHJvY2VzcyhzaGFwZVtrZXldLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5wYXJhbXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXRoOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4ucGFyYW1zLnBhdGgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJwcm9wZXJ0aWVzXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyByZXF1aXJlZCBrZXlzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYWxsS2V5cyA9IG5ldyBTZXQoT2JqZWN0LmtleXMoc2hhcGUpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjb25zdCBvcHRpb25hbEtleXMgPSBuZXcgU2V0KGRlZi5vcHRpb25hbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVxdWlyZWRLZXlzID0gbmV3IFNldChbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLmFsbEtleXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLmZpbHRlcigoa2V5KT0+e1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2ID0gZGVmLnNoYXBlW2tleV0uX3pvZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuaW8gPT09IFwiaW5wdXRcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHYub3B0aW4gPT09IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2Lm9wdG91dCA9PT0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXF1aXJlZEtleXMuc2l6ZSA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi5yZXF1aXJlZCA9IEFycmF5LmZyb20ocmVxdWlyZWRLZXlzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2F0Y2hhbGxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGVmLmNhdGNoYWxsPy5fem9kLmRlZi50eXBlID09PSBcIm5ldmVyXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3RyaWN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24uYWRkaXRpb25hbFByb3BlcnRpZXMgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFkZWYuY2F0Y2hhbGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVndWxhclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pbyA9PT0gXCJvdXRwdXRcIikganNvbi5hZGRpdGlvbmFsUHJvcGVydGllcyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZGVmLmNhdGNoYWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24uYWRkaXRpb25hbFByb3BlcnRpZXMgPSB0aGlzLnByb2Nlc3MoZGVmLmNhdGNoYWxsLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5wYXJhbXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXRoOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4ucGFyYW1zLnBhdGgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJhZGRpdGlvbmFsUHJvcGVydGllc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInVuaW9uXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QganNvbiA9IF9qc29uO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSBkZWYub3B0aW9ucy5tYXAoKHgsIGkpPT50aGlzLnByb2Nlc3MoeCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4ucGFyYW1zLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aDogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLnBhcmFtcy5wYXRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiYW55T2ZcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uLmFueU9mID0gb3B0aW9ucztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImludGVyc2VjdGlvblwiOlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGpzb24gPSBfanNvbjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhID0gdGhpcy5wcm9jZXNzKGRlZi5sZWZ0LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLnBhcmFtcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aDogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4ucGFyYW1zLnBhdGgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImFsbE9mXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBiID0gdGhpcy5wcm9jZXNzKGRlZi5yaWdodCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5wYXJhbXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGg6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLnBhcmFtcy5wYXRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJhbGxPZlwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaXNTaW1wbGVJbnRlcnNlY3Rpb24gPSAodmFsKT0+XCJhbGxPZlwiIGluIHZhbCAmJiBPYmplY3Qua2V5cyh2YWwpLmxlbmd0aCA9PT0gMTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhbGxPZiA9IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4uaXNTaW1wbGVJbnRlcnNlY3Rpb24oYSkgPyBhLmFsbE9mIDogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5pc1NpbXBsZUludGVyc2VjdGlvbihiKSA/IGIuYWxsT2YgOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24uYWxsT2YgPSBhbGxPZjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInR1cGxlXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QganNvbiA9IF9qc29uO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24udHlwZSA9IFwiYXJyYXlcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwcmVmaXhQYXRoID0gdGhpcy50YXJnZXQgPT09IFwiZHJhZnQtMjAyMC0xMlwiID8gXCJwcmVmaXhJdGVtc1wiIDogXCJpdGVtc1wiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc3RQYXRoID0gdGhpcy50YXJnZXQgPT09IFwiZHJhZnQtMjAyMC0xMlwiID8gXCJpdGVtc1wiIDogdGhpcy50YXJnZXQgPT09IFwib3BlbmFwaS0zLjBcIiA/IFwiaXRlbXNcIiA6IFwiYWRkaXRpb25hbEl0ZW1zXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcHJlZml4SXRlbXMgPSBkZWYuaXRlbXMubWFwKCh4LCBpKT0+dGhpcy5wcm9jZXNzKHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLnBhcmFtcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGg6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5wYXJhbXMucGF0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXhQYXRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc3QgPSBkZWYucmVzdCA/IHRoaXMucHJvY2VzcyhkZWYucmVzdCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5wYXJhbXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGg6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLnBhcmFtcy5wYXRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdFBhdGgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi50aGlzLnRhcmdldCA9PT0gXCJvcGVuYXBpLTMuMFwiID8gW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZi5pdGVtcy5sZW5ndGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0gOiBbXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkgOiBudWxsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnRhcmdldCA9PT0gXCJkcmFmdC0yMDIwLTEyXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi5wcmVmaXhJdGVtcyA9IHByZWZpeEl0ZW1zO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi5pdGVtcyA9IHJlc3Q7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMudGFyZ2V0ID09PSBcIm9wZW5hcGktMy4wXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi5pdGVtcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFueU9mOiBwcmVmaXhJdGVtc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi5pdGVtcy5hbnlPZi5wdXNoKHJlc3QpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24ubWluSXRlbXMgPSBwcmVmaXhJdGVtcy5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghcmVzdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi5tYXhJdGVtcyA9IHByZWZpeEl0ZW1zLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24uaXRlbXMgPSBwcmVmaXhJdGVtcztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3QpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24uYWRkaXRpb25hbEl0ZW1zID0gcmVzdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBsZW5ndGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7IG1pbmltdW0sIG1heGltdW0gfSA9IHNjaGVtYS5fem9kLmJhZztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG1pbmltdW0gPT09IFwibnVtYmVyXCIpIGpzb24ubWluSXRlbXMgPSBtaW5pbXVtO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgbWF4aW11bSA9PT0gXCJudW1iZXJcIikganNvbi5tYXhJdGVtcyA9IG1heGltdW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJyZWNvcmRcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBqc29uID0gX2pzb247XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi50eXBlID0gXCJvYmplY3RcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy50YXJnZXQgPT09IFwiZHJhZnQtN1wiIHx8IHRoaXMudGFyZ2V0ID09PSBcImRyYWZ0LTIwMjAtMTJcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uLnByb3BlcnR5TmFtZXMgPSB0aGlzLnByb2Nlc3MoZGVmLmtleVR5cGUsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLnBhcmFtcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGg6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5wYXJhbXMucGF0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcInByb3BlcnR5TmFtZXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi5hZGRpdGlvbmFsUHJvcGVydGllcyA9IHRoaXMucHJvY2VzcyhkZWYudmFsdWVUeXBlLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLnBhcmFtcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aDogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4ucGFyYW1zLnBhdGgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImFkZGl0aW9uYWxQcm9wZXJ0aWVzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwibWFwXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMudW5yZXByZXNlbnRhYmxlID09PSBcInRocm93XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWFwIGNhbm5vdCBiZSByZXByZXNlbnRlZCBpbiBKU09OIFNjaGVtYVwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJzZXRcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy51bnJlcHJlc2VudGFibGUgPT09IFwidGhyb3dcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTZXQgY2Fubm90IGJlIHJlcHJlc2VudGVkIGluIEpTT04gU2NoZW1hXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImVudW1cIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBqc29uID0gX2pzb247XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWVzID0gZ2V0RW51bVZhbHVlcyhkZWYuZW50cmllcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTnVtYmVyIGVudW1zIGNhbiBoYXZlIGJvdGggc3RyaW5nIGFuZCBudW1iZXIgdmFsdWVzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlcy5ldmVyeSgodik9PnR5cGVvZiB2ID09PSBcIm51bWJlclwiKSkganNvbi50eXBlID0gXCJudW1iZXJcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWVzLmV2ZXJ5KCh2KT0+dHlwZW9mIHYgPT09IFwic3RyaW5nXCIpKSBqc29uLnR5cGUgPSBcInN0cmluZ1wiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24uZW51bSA9IHZhbHVlcztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImxpdGVyYWxcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBqc29uID0gX2pzb247XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFscyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgdmFsIG9mIGRlZi52YWx1ZXMpe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnVucmVwcmVzZW50YWJsZSA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTGl0ZXJhbCBgdW5kZWZpbmVkYCBjYW5ub3QgYmUgcmVwcmVzZW50ZWQgaW4gSlNPTiBTY2hlbWFcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZG8gbm90IGFkZCB0byB2YWxzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbCA9PT0gXCJiaWdpbnRcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMudW5yZXByZXNlbnRhYmxlID09PSBcInRocm93XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJCaWdJbnQgbGl0ZXJhbHMgY2Fubm90IGJlIHJlcHJlc2VudGVkIGluIEpTT04gU2NoZW1hXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWxzLnB1c2goTnVtYmVyKHZhbCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFscy5wdXNoKHZhbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZG8gbm90aGluZyAoYW4gdW5kZWZpbmVkIGxpdGVyYWwgd2FzIHN0cmlwcGVkKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodmFscy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsID0gdmFsc1swXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi50eXBlID0gdmFsID09PSBudWxsID8gXCJudWxsXCIgOiB0eXBlb2YgdmFsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy50YXJnZXQgPT09IFwiZHJhZnQtNFwiIHx8IHRoaXMudGFyZ2V0ID09PSBcIm9wZW5hcGktMy4wXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24uZW51bSA9IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uLmNvbnN0ID0gdmFsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHMuZXZlcnkoKHYpPT50eXBlb2YgdiA9PT0gXCJudW1iZXJcIikpIGpzb24udHlwZSA9IFwibnVtYmVyXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWxzLmV2ZXJ5KCh2KT0+dHlwZW9mIHYgPT09IFwic3RyaW5nXCIpKSBqc29uLnR5cGUgPSBcInN0cmluZ1wiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFscy5ldmVyeSgodik9PnR5cGVvZiB2ID09PSBcImJvb2xlYW5cIikpIGpzb24udHlwZSA9IFwic3RyaW5nXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWxzLmV2ZXJ5KCh2KT0+diA9PT0gbnVsbCkpIGpzb24udHlwZSA9IFwibnVsbFwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uLmVudW0gPSB2YWxzO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImZpbGVcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBqc29uID0gX2pzb247XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlsZSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0OiBcImJpbmFyeVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50RW5jb2Rpbmc6IFwiYmluYXJ5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgbWluaW11bSwgbWF4aW11bSwgbWltZSB9ID0gc2NoZW1hLl96b2QuYmFnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtaW5pbXVtICE9PSB1bmRlZmluZWQpIGZpbGUubWluTGVuZ3RoID0gbWluaW11bTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobWF4aW11bSAhPT0gdW5kZWZpbmVkKSBmaWxlLm1heExlbmd0aCA9IG1heGltdW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1pbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1pbWUubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlLmNvbnRlbnRNZWRpYVR5cGUgPSBtaW1lWzBdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0LmFzc2lnbihqc29uLCBmaWxlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24uYW55T2YgPSBtaW1lLm1hcCgobSk9PntcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtRmlsZSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4uZmlsZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudE1lZGlhVHlwZTogbVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1GaWxlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QuYXNzaWduKGpzb24sIGZpbGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInRyYW5zZm9ybVwiOlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnVucmVwcmVzZW50YWJsZSA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRyYW5zZm9ybXMgY2Fubm90IGJlIHJlcHJlc2VudGVkIGluIEpTT04gU2NoZW1hXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcIm51bGxhYmxlXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5uZXIgPSB0aGlzLnByb2Nlc3MoZGVmLmlubmVyVHlwZSwgcGFyYW1zKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy50YXJnZXQgPT09IFwib3BlbmFwaS0zLjBcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQucmVmID0gZGVmLmlubmVyVHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2pzb24ubnVsbGFibGUgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9qc29uLmFueU9mID0gW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5uZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJudWxsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJub25vcHRpb25hbFwiOlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJvY2VzcyhkZWYuaW5uZXJUeXBlLCBwYXJhbXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5yZWYgPSBkZWYuaW5uZXJUeXBlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwic3VjY2Vzc1wiOlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGpzb24gPSBfanNvbjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uLnR5cGUgPSBcImJvb2xlYW5cIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImRlZmF1bHRcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnByb2Nlc3MoZGVmLmlubmVyVHlwZSwgcGFyYW1zKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQucmVmID0gZGVmLmlubmVyVHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfanNvbi5kZWZhdWx0ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShkZWYuZGVmYXVsdFZhbHVlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJwcmVmYXVsdFwiOlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJvY2VzcyhkZWYuaW5uZXJUeXBlLCBwYXJhbXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5yZWYgPSBkZWYuaW5uZXJUeXBlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmlvID09PSBcImlucHV0XCIpIF9qc29uLl9wcmVmYXVsdCA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoZGVmLmRlZmF1bHRWYWx1ZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiY2F0Y2hcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB1c2UgY29uZGl0aW9uYWxzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzKGRlZi5pbm5lclR5cGUsIHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LnJlZiA9IGRlZi5pbm5lclR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNhdGNoVmFsdWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2hWYWx1ZSA9IGRlZi5jYXRjaFZhbHVlKHVuZGVmaW5lZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJEeW5hbWljIGNhdGNoIHZhbHVlcyBhcmUgbm90IHN1cHBvcnRlZCBpbiBKU09OIFNjaGVtYVwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2pzb24uZGVmYXVsdCA9IGNhdGNoVmFsdWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJuYW5cIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy51bnJlcHJlc2VudGFibGUgPT09IFwidGhyb3dcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJOYU4gY2Fubm90IGJlIHJlcHJlc2VudGVkIGluIEpTT04gU2NoZW1hXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInRlbXBsYXRlX2xpdGVyYWxcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBqc29uID0gX2pzb247XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcGF0dGVybiA9IHNjaGVtYS5fem9kLnBhdHRlcm47XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFwYXR0ZXJuKSB0aHJvdyBuZXcgRXJyb3IoXCJQYXR0ZXJuIG5vdCBmb3VuZCBpbiB0ZW1wbGF0ZSBsaXRlcmFsXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24udHlwZSA9IFwic3RyaW5nXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi5wYXR0ZXJuID0gcGF0dGVybi5zb3VyY2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJwaXBlXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5uZXJUeXBlID0gdGhpcy5pbyA9PT0gXCJpbnB1dFwiID8gZGVmLmluLl96b2QuZGVmLnR5cGUgPT09IFwidHJhbnNmb3JtXCIgPyBkZWYub3V0IDogZGVmLmluIDogZGVmLm91dDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnByb2Nlc3MoaW5uZXJUeXBlLCBwYXJhbXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5yZWYgPSBpbm5lclR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJyZWFkb25seVwiOlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJvY2VzcyhkZWYuaW5uZXJUeXBlLCBwYXJhbXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5yZWYgPSBkZWYuaW5uZXJUeXBlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9qc29uLnJlYWRPbmx5ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gcGFzc3Rocm91Z2ggdHlwZXNcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInByb21pc2VcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnByb2Nlc3MoZGVmLmlubmVyVHlwZSwgcGFyYW1zKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQucmVmID0gZGVmLmlubmVyVHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcIm9wdGlvbmFsXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzKGRlZi5pbm5lclR5cGUsIHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LnJlZiA9IGRlZi5pbm5lclR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJsYXp5XCI6XG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5uZXJUeXBlID0gc2NoZW1hLl96b2QuaW5uZXJUeXBlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJvY2Vzcyhpbm5lclR5cGUsIHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LnJlZiA9IGlubmVyVHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImN1c3RvbVwiOlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnVucmVwcmVzZW50YWJsZSA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkN1c3RvbSB0eXBlcyBjYW5ub3QgYmUgcmVwcmVzZW50ZWQgaW4gSlNPTiBTY2hlbWFcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiZnVuY3Rpb25cIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy51bnJlcHJlc2VudGFibGUgPT09IFwidGhyb3dcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJGdW5jdGlvbiB0eXBlcyBjYW5ub3QgYmUgcmVwcmVzZW50ZWQgaW4gSlNPTiBTY2hlbWFcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gbWV0YWRhdGFcbiAgICAgICAgY29uc3QgbWV0YSA9IHRoaXMubWV0YWRhdGFSZWdpc3RyeS5nZXQoc2NoZW1hKTtcbiAgICAgICAgaWYgKG1ldGEpIE9iamVjdC5hc3NpZ24ocmVzdWx0LnNjaGVtYSwgbWV0YSk7XG4gICAgICAgIGlmICh0aGlzLmlvID09PSBcImlucHV0XCIgJiYgaXNUcmFuc2Zvcm1pbmcoc2NoZW1hKSkge1xuICAgICAgICAgICAgLy8gZXhhbXBsZXMvZGVmYXVsdHMgb25seSBhcHBseSB0byBvdXRwdXQgdHlwZSBvZiBwaXBlXG4gICAgICAgICAgICBkZWxldGUgcmVzdWx0LnNjaGVtYS5leGFtcGxlcztcbiAgICAgICAgICAgIGRlbGV0ZSByZXN1bHQuc2NoZW1hLmRlZmF1bHQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gc2V0IHByZWZhdWx0IGFzIGRlZmF1bHRcbiAgICAgICAgaWYgKHRoaXMuaW8gPT09IFwiaW5wdXRcIiAmJiByZXN1bHQuc2NoZW1hLl9wcmVmYXVsdCkgKF9hID0gcmVzdWx0LnNjaGVtYSkuZGVmYXVsdCA/PyAoX2EuZGVmYXVsdCA9IHJlc3VsdC5zY2hlbWEuX3ByZWZhdWx0KTtcbiAgICAgICAgZGVsZXRlIHJlc3VsdC5zY2hlbWEuX3ByZWZhdWx0O1xuICAgICAgICAvLyBwdWxsaW5nIGZyZXNoIGZyb20gdGhpcy5zZWVuIGluIGNhc2UgaXQgd2FzIG92ZXJ3cml0dGVuXG4gICAgICAgIGNvbnN0IF9yZXN1bHQgPSB0aGlzLnNlZW4uZ2V0KHNjaGVtYSk7XG4gICAgICAgIHJldHVybiBfcmVzdWx0LnNjaGVtYTtcbiAgICB9XG4gICAgZW1pdChzY2hlbWEsIF9wYXJhbXMpIHtcbiAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgICAgY3ljbGVzOiBfcGFyYW1zPy5jeWNsZXMgPz8gXCJyZWZcIixcbiAgICAgICAgICAgIHJldXNlZDogX3BhcmFtcz8ucmV1c2VkID8/IFwiaW5saW5lXCIsXG4gICAgICAgICAgICAvLyB1bnJlcHJlc2VudGFibGU6IF9wYXJhbXM/LnVucmVwcmVzZW50YWJsZSA/PyBcInRocm93XCIsXG4gICAgICAgICAgICAvLyB1cmk6IF9wYXJhbXM/LnVyaSA/PyAoKGlkKSA9PiBgJHtpZH1gKSxcbiAgICAgICAgICAgIGV4dGVybmFsOiBfcGFyYW1zPy5leHRlcm5hbCA/PyB1bmRlZmluZWRcbiAgICAgICAgfTtcbiAgICAgICAgLy8gaXRlcmF0ZSBvdmVyIHNlZW4gbWFwO1xuICAgICAgICBjb25zdCByb290ID0gdGhpcy5zZWVuLmdldChzY2hlbWEpO1xuICAgICAgICBpZiAoIXJvb3QpIHRocm93IG5ldyBFcnJvcihcIlVucHJvY2Vzc2VkIHNjaGVtYS4gVGhpcyBpcyBhIGJ1ZyBpbiBab2QuXCIpO1xuICAgICAgICAvLyBpbml0aWFsaXplIHJlc3VsdCB3aXRoIHJvb3Qgc2NoZW1hIGZpZWxkc1xuICAgICAgICAvLyBPYmplY3QuYXNzaWduKHJlc3VsdCwgc2Vlbi5jYWNoZWQpO1xuICAgICAgICAvLyByZXR1cm5zIGEgcmVmIHRvIHRoZSBzY2hlbWFcbiAgICAgICAgLy8gZGVmSWQgd2lsbCBiZSBlbXB0eSBpZiB0aGUgcmVmIHBvaW50cyB0byBhbiBleHRlcm5hbCBzY2hlbWEgKG9yICMpXG4gICAgICAgIGNvbnN0IG1ha2VVUkkgPSAoZW50cnkpPT57XG4gICAgICAgICAgICAvLyBjb21wYXJpbmcgdGhlIHNlZW4gb2JqZWN0cyBiZWNhdXNlIHNvbWV0aW1lc1xuICAgICAgICAgICAgLy8gbXVsdGlwbGUgc2NoZW1hcyBtYXAgdG8gdGhlIHNhbWUgc2VlbiBvYmplY3QuXG4gICAgICAgICAgICAvLyBlLmcuIGxhenlcbiAgICAgICAgICAgIC8vIGV4dGVybmFsIGlzIGNvbmZpZ3VyZWRcbiAgICAgICAgICAgIGNvbnN0IGRlZnNTZWdtZW50ID0gdGhpcy50YXJnZXQgPT09IFwiZHJhZnQtMjAyMC0xMlwiID8gXCIkZGVmc1wiIDogXCJkZWZpbml0aW9uc1wiO1xuICAgICAgICAgICAgaWYgKHBhcmFtcy5leHRlcm5hbCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGV4dGVybmFsSWQgPSBwYXJhbXMuZXh0ZXJuYWwucmVnaXN0cnkuZ2V0KGVudHJ5WzBdKT8uaWQ7IC8vID8/IFwiX19zaGFyZWRcIjsvLyBgX19zY2hlbWEke3RoaXMuY291bnRlcisrfWA7XG4gICAgICAgICAgICAgICAgLy8gY2hlY2sgaWYgc2NoZW1hIGlzIGluIHRoZSBleHRlcm5hbCByZWdpc3RyeVxuICAgICAgICAgICAgICAgIGNvbnN0IHVyaUdlbmVyYXRvciA9IHBhcmFtcy5leHRlcm5hbC51cmkgPz8gKChpZCk9PmlkKTtcbiAgICAgICAgICAgICAgICBpZiAoZXh0ZXJuYWxJZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVmOiB1cmlHZW5lcmF0b3IoZXh0ZXJuYWxJZClcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gb3RoZXJ3aXNlLCBhZGQgdG8gX19zaGFyZWRcbiAgICAgICAgICAgICAgICBjb25zdCBpZCA9IGVudHJ5WzFdLmRlZklkID8/IGVudHJ5WzFdLnNjaGVtYS5pZCA/PyBgc2NoZW1hJHt0aGlzLmNvdW50ZXIrK31gO1xuICAgICAgICAgICAgICAgIGVudHJ5WzFdLmRlZklkID0gaWQ7IC8vIHNldCBkZWZJZCBzbyBpdCB3aWxsIGJlIHJldXNlZCBpZiBuZWVkZWRcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBkZWZJZDogaWQsXG4gICAgICAgICAgICAgICAgICAgIHJlZjogYCR7dXJpR2VuZXJhdG9yKFwiX19zaGFyZWRcIil9Iy8ke2RlZnNTZWdtZW50fS8ke2lkfWBcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGVudHJ5WzFdID09PSByb290KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgcmVmOiBcIiNcIlxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBzZWxmLWNvbnRhaW5lZCBzY2hlbWFcbiAgICAgICAgICAgIGNvbnN0IHVyaVByZWZpeCA9IGAjYDtcbiAgICAgICAgICAgIGNvbnN0IGRlZlVyaVByZWZpeCA9IGAke3VyaVByZWZpeH0vJHtkZWZzU2VnbWVudH0vYDtcbiAgICAgICAgICAgIGNvbnN0IGRlZklkID0gZW50cnlbMV0uc2NoZW1hLmlkID8/IGBfX3NjaGVtYSR7dGhpcy5jb3VudGVyKyt9YDtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgZGVmSWQsXG4gICAgICAgICAgICAgICAgcmVmOiBkZWZVcmlQcmVmaXggKyBkZWZJZFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfTtcbiAgICAgICAgLy8gc3RvcmVkIGNhY2hlZCB2ZXJzaW9uIGluIGBkZWZgIHByb3BlcnR5XG4gICAgICAgIC8vIHJlbW92ZSBhbGwgcHJvcGVydGllcywgc2V0ICRyZWZcbiAgICAgICAgY29uc3QgZXh0cmFjdFRvRGVmID0gKGVudHJ5KT0+e1xuICAgICAgICAgICAgLy8gaWYgdGhlIHNjaGVtYSBpcyBhbHJlYWR5IGEgcmVmZXJlbmNlLCBkbyBub3QgZXh0cmFjdCBpdFxuICAgICAgICAgICAgaWYgKGVudHJ5WzFdLnNjaGVtYS4kcmVmKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3Qgc2VlbiA9IGVudHJ5WzFdO1xuICAgICAgICAgICAgY29uc3QgeyByZWYsIGRlZklkIH0gPSBtYWtlVVJJKGVudHJ5KTtcbiAgICAgICAgICAgIHNlZW4uZGVmID0ge1xuICAgICAgICAgICAgICAgIC4uLnNlZW4uc2NoZW1hXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgLy8gZGVmSWQgd29uJ3QgYmUgc2V0IGlmIHRoZSBzY2hlbWEgaXMgYSByZWZlcmVuY2UgdG8gYW4gZXh0ZXJuYWwgc2NoZW1hXG4gICAgICAgICAgICBpZiAoZGVmSWQpIHNlZW4uZGVmSWQgPSBkZWZJZDtcbiAgICAgICAgICAgIC8vIHdpcGUgYXdheSBhbGwgcHJvcGVydGllcyBleGNlcHQgJHJlZlxuICAgICAgICAgICAgY29uc3Qgc2NoZW1hID0gc2Vlbi5zY2hlbWE7XG4gICAgICAgICAgICBmb3IoY29uc3Qga2V5IGluIHNjaGVtYSl7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHNjaGVtYVtrZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc2NoZW1hLiRyZWYgPSByZWY7XG4gICAgICAgIH07XG4gICAgICAgIC8vIHRocm93IG9uIGN5Y2xlc1xuICAgICAgICAvLyBicmVhayBjeWNsZXNcbiAgICAgICAgaWYgKHBhcmFtcy5jeWNsZXMgPT09IFwidGhyb3dcIikge1xuICAgICAgICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiB0aGlzLnNlZW4uZW50cmllcygpKXtcbiAgICAgICAgICAgICAgICBjb25zdCBzZWVuID0gZW50cnlbMV07XG4gICAgICAgICAgICAgICAgaWYgKHNlZW4uY3ljbGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ3ljbGUgZGV0ZWN0ZWQ6IFwiICsgYCMvJHtzZWVuLmN5Y2xlPy5qb2luKFwiL1wiKX0vPHJvb3Q+YCArICdcXG5cXG5TZXQgdGhlIGBjeWNsZXNgIHBhcmFtZXRlciB0byBgXCJyZWZcImAgdG8gcmVzb2x2ZSBjeWNsaWNhbCBzY2hlbWFzIHdpdGggZGVmcy4nKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gZXh0cmFjdCBzY2hlbWFzIGludG8gJGRlZnNcbiAgICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiB0aGlzLnNlZW4uZW50cmllcygpKXtcbiAgICAgICAgICAgIGNvbnN0IHNlZW4gPSBlbnRyeVsxXTtcbiAgICAgICAgICAgIC8vIGNvbnZlcnQgcm9vdCBzY2hlbWEgdG8gIyAkcmVmXG4gICAgICAgICAgICBpZiAoc2NoZW1hID09PSBlbnRyeVswXSkge1xuICAgICAgICAgICAgICAgIGV4dHJhY3RUb0RlZihlbnRyeSk7IC8vIHRoaXMgaGFzIHNwZWNpYWwgaGFuZGxpbmcgZm9yIHRoZSByb290IHNjaGVtYVxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gZXh0cmFjdCBzY2hlbWFzIHRoYXQgYXJlIGluIHRoZSBleHRlcm5hbCByZWdpc3RyeVxuICAgICAgICAgICAgaWYgKHBhcmFtcy5leHRlcm5hbCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGV4dCA9IHBhcmFtcy5leHRlcm5hbC5yZWdpc3RyeS5nZXQoZW50cnlbMF0pPy5pZDtcbiAgICAgICAgICAgICAgICBpZiAoc2NoZW1hICE9PSBlbnRyeVswXSAmJiBleHQpIHtcbiAgICAgICAgICAgICAgICAgICAgZXh0cmFjdFRvRGVmKGVudHJ5KTtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gZXh0cmFjdCBzY2hlbWFzIHdpdGggYGlkYCBtZXRhXG4gICAgICAgICAgICBjb25zdCBpZCA9IHRoaXMubWV0YWRhdGFSZWdpc3RyeS5nZXQoZW50cnlbMF0pPy5pZDtcbiAgICAgICAgICAgIGlmIChpZCkge1xuICAgICAgICAgICAgICAgIGV4dHJhY3RUb0RlZihlbnRyeSk7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBicmVhayBjeWNsZXNcbiAgICAgICAgICAgIGlmIChzZWVuLmN5Y2xlKSB7XG4gICAgICAgICAgICAgICAgLy8gYW55XG4gICAgICAgICAgICAgICAgZXh0cmFjdFRvRGVmKGVudHJ5KTtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIGV4dHJhY3QgcmV1c2VkIHNjaGVtYXNcbiAgICAgICAgICAgIGlmIChzZWVuLmNvdW50ID4gMSkge1xuICAgICAgICAgICAgICAgIGlmIChwYXJhbXMucmV1c2VkID09PSBcInJlZlwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGV4dHJhY3RUb0RlZihlbnRyeSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBmbGF0dGVuIF9yZWZzXG4gICAgICAgIGNvbnN0IGZsYXR0ZW5SZWYgPSAoem9kU2NoZW1hLCBwYXJhbXMpPT57XG4gICAgICAgICAgICBjb25zdCBzZWVuID0gdGhpcy5zZWVuLmdldCh6b2RTY2hlbWEpO1xuICAgICAgICAgICAgY29uc3Qgc2NoZW1hID0gc2Vlbi5kZWYgPz8gc2Vlbi5zY2hlbWE7XG4gICAgICAgICAgICBjb25zdCBfY2FjaGVkID0ge1xuICAgICAgICAgICAgICAgIC4uLnNjaGVtYVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIC8vIGFscmVhZHkgc2VlblxuICAgICAgICAgICAgaWYgKHNlZW4ucmVmID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gZmxhdHRlbiByZWYgaWYgZGVmaW5lZFxuICAgICAgICAgICAgY29uc3QgcmVmID0gc2Vlbi5yZWY7XG4gICAgICAgICAgICBzZWVuLnJlZiA9IG51bGw7IC8vIHByZXZlbnQgcmVjdXJzaW9uXG4gICAgICAgICAgICBpZiAocmVmKSB7XG4gICAgICAgICAgICAgICAgZmxhdHRlblJlZihyZWYsIHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgLy8gbWVyZ2UgcmVmZXJlbmNlZCBzY2hlbWEgaW50byBjdXJyZW50XG4gICAgICAgICAgICAgICAgY29uc3QgcmVmU2NoZW1hID0gdGhpcy5zZWVuLmdldChyZWYpLnNjaGVtYTtcbiAgICAgICAgICAgICAgICBpZiAocmVmU2NoZW1hLiRyZWYgJiYgKHBhcmFtcy50YXJnZXQgPT09IFwiZHJhZnQtN1wiIHx8IHBhcmFtcy50YXJnZXQgPT09IFwiZHJhZnQtNFwiIHx8IHBhcmFtcy50YXJnZXQgPT09IFwib3BlbmFwaS0zLjBcIikpIHtcbiAgICAgICAgICAgICAgICAgICAgc2NoZW1hLmFsbE9mID0gc2NoZW1hLmFsbE9mID8/IFtdO1xuICAgICAgICAgICAgICAgICAgICBzY2hlbWEuYWxsT2YucHVzaChyZWZTY2hlbWEpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIE9iamVjdC5hc3NpZ24oc2NoZW1hLCByZWZTY2hlbWEpO1xuICAgICAgICAgICAgICAgICAgICBPYmplY3QuYXNzaWduKHNjaGVtYSwgX2NhY2hlZCk7IC8vIHByZXZlbnQgb3ZlcndyaXRpbmcgYW55IGZpZWxkcyBpbiB0aGUgb3JpZ2luYWwgc2NoZW1hXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gZXhlY3V0ZSBvdmVycmlkZXNcbiAgICAgICAgICAgIGlmICghc2Vlbi5pc1BhcmVudCkgdGhpcy5vdmVycmlkZSh7XG4gICAgICAgICAgICAgICAgem9kU2NoZW1hOiB6b2RTY2hlbWEsXG4gICAgICAgICAgICAgICAganNvblNjaGVtYTogc2NoZW1hLFxuICAgICAgICAgICAgICAgIHBhdGg6IHNlZW4ucGF0aCA/PyBbXVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG4gICAgICAgIGZvciAoY29uc3QgZW50cnkgb2YgW1xuICAgICAgICAgICAgLi4udGhpcy5zZWVuLmVudHJpZXMoKVxuICAgICAgICBdLnJldmVyc2UoKSl7XG4gICAgICAgICAgICBmbGF0dGVuUmVmKGVudHJ5WzBdLCB7XG4gICAgICAgICAgICAgICAgdGFyZ2V0OiB0aGlzLnRhcmdldFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVzdWx0ID0ge307XG4gICAgICAgIGlmICh0aGlzLnRhcmdldCA9PT0gXCJkcmFmdC0yMDIwLTEyXCIpIHtcbiAgICAgICAgICAgIHJlc3VsdC4kc2NoZW1hID0gXCJodHRwczovL2pzb24tc2NoZW1hLm9yZy9kcmFmdC8yMDIwLTEyL3NjaGVtYVwiO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMudGFyZ2V0ID09PSBcImRyYWZ0LTdcIikge1xuICAgICAgICAgICAgcmVzdWx0LiRzY2hlbWEgPSBcImh0dHA6Ly9qc29uLXNjaGVtYS5vcmcvZHJhZnQtMDcvc2NoZW1hI1wiO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMudGFyZ2V0ID09PSBcImRyYWZ0LTRcIikge1xuICAgICAgICAgICAgcmVzdWx0LiRzY2hlbWEgPSBcImh0dHA6Ly9qc29uLXNjaGVtYS5vcmcvZHJhZnQtMDQvc2NoZW1hI1wiO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMudGFyZ2V0ID09PSBcIm9wZW5hcGktMy4wXCIpIHtcbiAgICAgICAgLy8gT3BlbkFQSSAzLjAgc2NoZW1hIG9iamVjdHMgc2hvdWxkIG5vdCBpbmNsdWRlIGEgJHNjaGVtYSBwcm9wZXJ0eVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgY29uc29sZS53YXJuKGBJbnZhbGlkIHRhcmdldDogJHt0aGlzLnRhcmdldH1gKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocGFyYW1zLmV4dGVybmFsPy51cmkpIHtcbiAgICAgICAgICAgIGNvbnN0IGlkID0gcGFyYW1zLmV4dGVybmFsLnJlZ2lzdHJ5LmdldChzY2hlbWEpPy5pZDtcbiAgICAgICAgICAgIGlmICghaWQpIHRocm93IG5ldyBFcnJvcihcIlNjaGVtYSBpcyBtaXNzaW5nIGFuIGBpZGAgcHJvcGVydHlcIik7XG4gICAgICAgICAgICByZXN1bHQuJGlkID0gcGFyYW1zLmV4dGVybmFsLnVyaShpZCk7XG4gICAgICAgIH1cbiAgICAgICAgT2JqZWN0LmFzc2lnbihyZXN1bHQsIHJvb3QuZGVmKTtcbiAgICAgICAgLy8gYnVpbGQgZGVmcyBvYmplY3RcbiAgICAgICAgY29uc3QgZGVmcyA9IHBhcmFtcy5leHRlcm5hbD8uZGVmcyA/PyB7fTtcbiAgICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiB0aGlzLnNlZW4uZW50cmllcygpKXtcbiAgICAgICAgICAgIGNvbnN0IHNlZW4gPSBlbnRyeVsxXTtcbiAgICAgICAgICAgIGlmIChzZWVuLmRlZiAmJiBzZWVuLmRlZklkKSB7XG4gICAgICAgICAgICAgICAgZGVmc1tzZWVuLmRlZklkXSA9IHNlZW4uZGVmO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIHNldCBkZWZpbml0aW9ucyBpbiByZXN1bHRcbiAgICAgICAgaWYgKHBhcmFtcy5leHRlcm5hbCkge30gZWxzZSB7XG4gICAgICAgICAgICBpZiAoT2JqZWN0LmtleXMoZGVmcykubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnRhcmdldCA9PT0gXCJkcmFmdC0yMDIwLTEyXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0LiRkZWZzID0gZGVmcztcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQuZGVmaW5pdGlvbnMgPSBkZWZzO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gdGhpcyBcImZpbmFsaXplc1wiIHRoaXMgc2NoZW1hIGFuZCBlbnN1cmVzIGFsbCBjeWNsZXMgYXJlIHJlbW92ZWRcbiAgICAgICAgICAgIC8vIGVhY2ggY2FsbCB0byAuZW1pdCgpIGlzIGZ1bmN0aW9uYWxseSBpbmRlcGVuZGVudFxuICAgICAgICAgICAgLy8gdGhvdWdoIHRoZSBzZWVuIG1hcCBpcyBzaGFyZWRcbiAgICAgICAgICAgIHJldHVybiBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHJlc3VsdCkpO1xuICAgICAgICB9IGNhdGNoIChfZXJyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJFcnJvciBjb252ZXJ0aW5nIHNjaGVtYSB0byBKU09OLlwiKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmV4cG9ydCBmdW5jdGlvbiB0b0pTT05TY2hlbWEoaW5wdXQsIF9wYXJhbXMpIHtcbiAgICBpZiAoaW5wdXQgaW5zdGFuY2VvZiAkWm9kUmVnaXN0cnkpIHtcbiAgICAgICAgY29uc3QgZ2VuID0gbmV3IEpTT05TY2hlbWFHZW5lcmF0b3IoX3BhcmFtcyk7XG4gICAgICAgIGNvbnN0IGRlZnMgPSB7fTtcbiAgICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiBpbnB1dC5faWRtYXAuZW50cmllcygpKXtcbiAgICAgICAgICAgIGNvbnN0IFtfLCBzY2hlbWFdID0gZW50cnk7XG4gICAgICAgICAgICBnZW4ucHJvY2VzcyhzY2hlbWEpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHNjaGVtYXMgPSB7fTtcbiAgICAgICAgY29uc3QgZXh0ZXJuYWwgPSB7XG4gICAgICAgICAgICByZWdpc3RyeTogaW5wdXQsXG4gICAgICAgICAgICB1cmk6IF9wYXJhbXM/LnVyaSxcbiAgICAgICAgICAgIGRlZnNcbiAgICAgICAgfTtcbiAgICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiBpbnB1dC5faWRtYXAuZW50cmllcygpKXtcbiAgICAgICAgICAgIGNvbnN0IFtrZXksIHNjaGVtYV0gPSBlbnRyeTtcbiAgICAgICAgICAgIHNjaGVtYXNba2V5XSA9IGdlbi5lbWl0KHNjaGVtYSwge1xuICAgICAgICAgICAgICAgIC4uLl9wYXJhbXMsXG4gICAgICAgICAgICAgICAgZXh0ZXJuYWxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChPYmplY3Qua2V5cyhkZWZzKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBjb25zdCBkZWZzU2VnbWVudCA9IGdlbi50YXJnZXQgPT09IFwiZHJhZnQtMjAyMC0xMlwiID8gXCIkZGVmc1wiIDogXCJkZWZpbml0aW9uc1wiO1xuICAgICAgICAgICAgc2NoZW1hcy5fX3NoYXJlZCA9IHtcbiAgICAgICAgICAgICAgICBbZGVmc1NlZ21lbnRdOiBkZWZzXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzY2hlbWFzXG4gICAgICAgIH07XG4gICAgfVxuICAgIGNvbnN0IGdlbiA9IG5ldyBKU09OU2NoZW1hR2VuZXJhdG9yKF9wYXJhbXMpO1xuICAgIGdlbi5wcm9jZXNzKGlucHV0KTtcbiAgICByZXR1cm4gZ2VuLmVtaXQoaW5wdXQsIF9wYXJhbXMpO1xufVxuZnVuY3Rpb24gaXNUcmFuc2Zvcm1pbmcoX3NjaGVtYSwgX2N0eCkge1xuICAgIGNvbnN0IGN0eCA9IF9jdHggPz8ge1xuICAgICAgICBzZWVuOiBuZXcgU2V0KClcbiAgICB9O1xuICAgIGlmIChjdHguc2Vlbi5oYXMoX3NjaGVtYSkpIHJldHVybiBmYWxzZTtcbiAgICBjdHguc2Vlbi5hZGQoX3NjaGVtYSk7XG4gICAgY29uc3Qgc2NoZW1hID0gX3NjaGVtYTtcbiAgICBjb25zdCBkZWYgPSBzY2hlbWEuX3pvZC5kZWY7XG4gICAgc3dpdGNoKGRlZi50eXBlKXtcbiAgICAgICAgY2FzZSBcInN0cmluZ1wiOlxuICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgIGNhc2UgXCJiaWdpbnRcIjpcbiAgICAgICAgY2FzZSBcImJvb2xlYW5cIjpcbiAgICAgICAgY2FzZSBcImRhdGVcIjpcbiAgICAgICAgY2FzZSBcInN5bWJvbFwiOlxuICAgICAgICBjYXNlIFwidW5kZWZpbmVkXCI6XG4gICAgICAgIGNhc2UgXCJudWxsXCI6XG4gICAgICAgIGNhc2UgXCJhbnlcIjpcbiAgICAgICAgY2FzZSBcInVua25vd25cIjpcbiAgICAgICAgY2FzZSBcIm5ldmVyXCI6XG4gICAgICAgIGNhc2UgXCJ2b2lkXCI6XG4gICAgICAgIGNhc2UgXCJsaXRlcmFsXCI6XG4gICAgICAgIGNhc2UgXCJlbnVtXCI6XG4gICAgICAgIGNhc2UgXCJuYW5cIjpcbiAgICAgICAgY2FzZSBcImZpbGVcIjpcbiAgICAgICAgY2FzZSBcInRlbXBsYXRlX2xpdGVyYWxcIjpcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgY2FzZSBcImFycmF5XCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlzVHJhbnNmb3JtaW5nKGRlZi5lbGVtZW50LCBjdHgpO1xuICAgICAgICAgICAgfVxuICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZm9yKGNvbnN0IGtleSBpbiBkZWYuc2hhcGUpe1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNUcmFuc2Zvcm1pbmcoZGVmLnNoYXBlW2tleV0sIGN0eCkpIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIGNhc2UgXCJ1bmlvblwiOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3Qgb3B0aW9uIG9mIGRlZi5vcHRpb25zKXtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzVHJhbnNmb3JtaW5nKG9wdGlvbiwgY3R4KSkgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgY2FzZSBcImludGVyc2VjdGlvblwiOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHJldHVybiBpc1RyYW5zZm9ybWluZyhkZWYubGVmdCwgY3R4KSB8fCBpc1RyYW5zZm9ybWluZyhkZWYucmlnaHQsIGN0eCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIGNhc2UgXCJ0dXBsZVwiOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBkZWYuaXRlbXMpe1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNUcmFuc2Zvcm1pbmcoaXRlbSwgY3R4KSkgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChkZWYucmVzdCAmJiBpc1RyYW5zZm9ybWluZyhkZWYucmVzdCwgY3R4KSkgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICBjYXNlIFwicmVjb3JkXCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlzVHJhbnNmb3JtaW5nKGRlZi5rZXlUeXBlLCBjdHgpIHx8IGlzVHJhbnNmb3JtaW5nKGRlZi52YWx1ZVR5cGUsIGN0eCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIGNhc2UgXCJtYXBcIjpcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaXNUcmFuc2Zvcm1pbmcoZGVmLmtleVR5cGUsIGN0eCkgfHwgaXNUcmFuc2Zvcm1pbmcoZGVmLnZhbHVlVHlwZSwgY3R4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgY2FzZSBcInNldFwiOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHJldHVybiBpc1RyYW5zZm9ybWluZyhkZWYudmFsdWVUeXBlLCBjdHgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAvLyBpbm5lciB0eXBlc1xuICAgICAgICBjYXNlIFwicHJvbWlzZVwiOlxuICAgICAgICBjYXNlIFwib3B0aW9uYWxcIjpcbiAgICAgICAgY2FzZSBcIm5vbm9wdGlvbmFsXCI6XG4gICAgICAgIGNhc2UgXCJudWxsYWJsZVwiOlxuICAgICAgICBjYXNlIFwicmVhZG9ubHlcIjpcbiAgICAgICAgICAgIHJldHVybiBpc1RyYW5zZm9ybWluZyhkZWYuaW5uZXJUeXBlLCBjdHgpO1xuICAgICAgICBjYXNlIFwibGF6eVwiOlxuICAgICAgICAgICAgcmV0dXJuIGlzVHJhbnNmb3JtaW5nKGRlZi5nZXR0ZXIoKSwgY3R4KTtcbiAgICAgICAgY2FzZSBcImRlZmF1bHRcIjpcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaXNUcmFuc2Zvcm1pbmcoZGVmLmlubmVyVHlwZSwgY3R4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgY2FzZSBcInByZWZhdWx0XCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlzVHJhbnNmb3JtaW5nKGRlZi5pbm5lclR5cGUsIGN0eCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIGNhc2UgXCJjdXN0b21cIjpcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIGNhc2UgXCJ0cmFuc2Zvcm1cIjpcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgY2FzZSBcInBpcGVcIjpcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaXNUcmFuc2Zvcm1pbmcoZGVmLmluLCBjdHgpIHx8IGlzVHJhbnNmb3JtaW5nKGRlZi5vdXQsIGN0eCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIGNhc2UgXCJzdWNjZXNzXCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICBjYXNlIFwiY2F0Y2hcIjpcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIGNhc2UgXCJmdW5jdGlvblwiOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIGRlZjtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIHNjaGVtYSB0eXBlOiAke2RlZi50eXBlfWApO1xufVxuIiwgImV4cG9ydCB7IH07XG4iLCAiaW1wb3J0ICogYXMgY29yZSBmcm9tIFwiLi4vY29yZS9pbmRleC5qc1wiO1xuaW1wb3J0ICogYXMgc2NoZW1hcyBmcm9tIFwiLi9zY2hlbWFzLmpzXCI7XG5leHBvcnQgY29uc3QgWm9kSVNPRGF0ZVRpbWUgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kSVNPRGF0ZVRpbWVcIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RJU09EYXRlVGltZS5pbml0KGluc3QsIGRlZik7XG4gICAgc2NoZW1hcy5ab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gZGF0ZXRpbWUocGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX2lzb0RhdGVUaW1lKFpvZElTT0RhdGVUaW1lLCBwYXJhbXMpO1xufVxuZXhwb3J0IGNvbnN0IFpvZElTT0RhdGUgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kSVNPRGF0ZVwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZElTT0RhdGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIHNjaGVtYXMuWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIGRhdGUocGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX2lzb0RhdGUoWm9kSVNPRGF0ZSwgcGFyYW1zKTtcbn1cbmV4cG9ydCBjb25zdCBab2RJU09UaW1lID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZElTT1RpbWVcIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RJU09UaW1lLmluaXQoaW5zdCwgZGVmKTtcbiAgICBzY2hlbWFzLlpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiB0aW1lKHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9pc29UaW1lKFpvZElTT1RpbWUsIHBhcmFtcyk7XG59XG5leHBvcnQgY29uc3QgWm9kSVNPRHVyYXRpb24gPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kSVNPRHVyYXRpb25cIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RJU09EdXJhdGlvbi5pbml0KGluc3QsIGRlZik7XG4gICAgc2NoZW1hcy5ab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gZHVyYXRpb24ocGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX2lzb0R1cmF0aW9uKFpvZElTT0R1cmF0aW9uLCBwYXJhbXMpO1xufVxuIiwgImltcG9ydCAqIGFzIGNvcmUgZnJvbSBcIi4uL2NvcmUvaW5kZXguanNcIjtcbmltcG9ydCB7ICRab2RFcnJvciB9IGZyb20gXCIuLi9jb3JlL2luZGV4LmpzXCI7XG5pbXBvcnQgKiBhcyB1dGlsIGZyb20gXCIuLi9jb3JlL3V0aWwuanNcIjtcbmNvbnN0IGluaXRpYWxpemVyID0gKGluc3QsIGlzc3Vlcyk9PntcbiAgICAkWm9kRXJyb3IuaW5pdChpbnN0LCBpc3N1ZXMpO1xuICAgIGluc3QubmFtZSA9IFwiWm9kRXJyb3JcIjtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhpbnN0LCB7XG4gICAgICAgIGZvcm1hdDoge1xuICAgICAgICAgICAgdmFsdWU6IChtYXBwZXIpPT5jb3JlLmZvcm1hdEVycm9yKGluc3QsIG1hcHBlcilcbiAgICAgICAgfSxcbiAgICAgICAgZmxhdHRlbjoge1xuICAgICAgICAgICAgdmFsdWU6IChtYXBwZXIpPT5jb3JlLmZsYXR0ZW5FcnJvcihpbnN0LCBtYXBwZXIpXG4gICAgICAgIH0sXG4gICAgICAgIGFkZElzc3VlOiB7XG4gICAgICAgICAgICB2YWx1ZTogKGlzc3VlKT0+e1xuICAgICAgICAgICAgICAgIGluc3QuaXNzdWVzLnB1c2goaXNzdWUpO1xuICAgICAgICAgICAgICAgIGluc3QubWVzc2FnZSA9IEpTT04uc3RyaW5naWZ5KGluc3QuaXNzdWVzLCB1dGlsLmpzb25TdHJpbmdpZnlSZXBsYWNlciwgMik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGFkZElzc3Vlczoge1xuICAgICAgICAgICAgdmFsdWU6IChpc3N1ZXMpPT57XG4gICAgICAgICAgICAgICAgaW5zdC5pc3N1ZXMucHVzaCguLi5pc3N1ZXMpO1xuICAgICAgICAgICAgICAgIGluc3QubWVzc2FnZSA9IEpTT04uc3RyaW5naWZ5KGluc3QuaXNzdWVzLCB1dGlsLmpzb25TdHJpbmdpZnlSZXBsYWNlciwgMik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGlzRW1wdHk6IHtcbiAgICAgICAgICAgIGdldCAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGluc3QuaXNzdWVzLmxlbmd0aCA9PT0gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0pO1xuLy8gT2JqZWN0LmRlZmluZVByb3BlcnR5KGluc3QsIFwiaXNFbXB0eVwiLCB7XG4vLyAgIGdldCgpIHtcbi8vICAgICByZXR1cm4gaW5zdC5pc3N1ZXMubGVuZ3RoID09PSAwO1xuLy8gICB9LFxuLy8gfSk7XG59O1xuZXhwb3J0IGNvbnN0IFpvZEVycm9yID0gY29yZS4kY29uc3RydWN0b3IoXCJab2RFcnJvclwiLCBpbml0aWFsaXplcik7XG5leHBvcnQgY29uc3QgWm9kUmVhbEVycm9yID0gY29yZS4kY29uc3RydWN0b3IoXCJab2RFcnJvclwiLCBpbml0aWFsaXplciwge1xuICAgIFBhcmVudDogRXJyb3Jcbn0pOyAvLyAvKiogQGRlcHJlY2F0ZWQgVXNlIGB6LmNvcmUuJFpvZEVycm9yTWFwQ3R4YCBpbnN0ZWFkLiAqL1xuIC8vIGV4cG9ydCB0eXBlIEVycm9yTWFwQ3R4ID0gY29yZS4kWm9kRXJyb3JNYXBDdHg7XG4iLCAiaW1wb3J0ICogYXMgY29yZSBmcm9tIFwiLi4vY29yZS9pbmRleC5qc1wiO1xuaW1wb3J0IHsgWm9kUmVhbEVycm9yIH0gZnJvbSBcIi4vZXJyb3JzLmpzXCI7XG5leHBvcnQgY29uc3QgcGFyc2UgPSAvKiBAX19QVVJFX18gKi8gY29yZS5fcGFyc2UoWm9kUmVhbEVycm9yKTtcbmV4cG9ydCBjb25zdCBwYXJzZUFzeW5jID0gLyogQF9fUFVSRV9fICovIGNvcmUuX3BhcnNlQXN5bmMoWm9kUmVhbEVycm9yKTtcbmV4cG9ydCBjb25zdCBzYWZlUGFyc2UgPSAvKiBAX19QVVJFX18gKi8gY29yZS5fc2FmZVBhcnNlKFpvZFJlYWxFcnJvcik7XG5leHBvcnQgY29uc3Qgc2FmZVBhcnNlQXN5bmMgPSAvKiBAX19QVVJFX18gKi8gY29yZS5fc2FmZVBhcnNlQXN5bmMoWm9kUmVhbEVycm9yKTtcbi8vIENvZGVjIGZ1bmN0aW9uc1xuZXhwb3J0IGNvbnN0IGVuY29kZSA9IC8qIEBfX1BVUkVfXyAqLyBjb3JlLl9lbmNvZGUoWm9kUmVhbEVycm9yKTtcbmV4cG9ydCBjb25zdCBkZWNvZGUgPSAvKiBAX19QVVJFX18gKi8gY29yZS5fZGVjb2RlKFpvZFJlYWxFcnJvcik7XG5leHBvcnQgY29uc3QgZW5jb2RlQXN5bmMgPSAvKiBAX19QVVJFX18gKi8gY29yZS5fZW5jb2RlQXN5bmMoWm9kUmVhbEVycm9yKTtcbmV4cG9ydCBjb25zdCBkZWNvZGVBc3luYyA9IC8qIEBfX1BVUkVfXyAqLyBjb3JlLl9kZWNvZGVBc3luYyhab2RSZWFsRXJyb3IpO1xuZXhwb3J0IGNvbnN0IHNhZmVFbmNvZGUgPSAvKiBAX19QVVJFX18gKi8gY29yZS5fc2FmZUVuY29kZShab2RSZWFsRXJyb3IpO1xuZXhwb3J0IGNvbnN0IHNhZmVEZWNvZGUgPSAvKiBAX19QVVJFX18gKi8gY29yZS5fc2FmZURlY29kZShab2RSZWFsRXJyb3IpO1xuZXhwb3J0IGNvbnN0IHNhZmVFbmNvZGVBc3luYyA9IC8qIEBfX1BVUkVfXyAqLyBjb3JlLl9zYWZlRW5jb2RlQXN5bmMoWm9kUmVhbEVycm9yKTtcbmV4cG9ydCBjb25zdCBzYWZlRGVjb2RlQXN5bmMgPSAvKiBAX19QVVJFX18gKi8gY29yZS5fc2FmZURlY29kZUFzeW5jKFpvZFJlYWxFcnJvcik7XG4iLCAiaW1wb3J0ICogYXMgY29yZSBmcm9tIFwiLi4vY29yZS9pbmRleC5qc1wiO1xuaW1wb3J0IHsgdXRpbCB9IGZyb20gXCIuLi9jb3JlL2luZGV4LmpzXCI7XG5pbXBvcnQgKiBhcyBjaGVja3MgZnJvbSBcIi4vY2hlY2tzLmpzXCI7XG5pbXBvcnQgKiBhcyBpc28gZnJvbSBcIi4vaXNvLmpzXCI7XG5pbXBvcnQgKiBhcyBwYXJzZSBmcm9tIFwiLi9wYXJzZS5qc1wiO1xuZXhwb3J0IGNvbnN0IFpvZFR5cGUgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kVHlwZVwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuZGVmID0gZGVmO1xuICAgIGluc3QudHlwZSA9IGRlZi50eXBlO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShpbnN0LCBcIl9kZWZcIiwge1xuICAgICAgICB2YWx1ZTogZGVmXG4gICAgfSk7XG4gICAgLy8gYmFzZSBtZXRob2RzXG4gICAgaW5zdC5jaGVjayA9ICguLi5jaGVja3MpPT57XG4gICAgICAgIHJldHVybiBpbnN0LmNsb25lKHV0aWwubWVyZ2VEZWZzKGRlZiwge1xuICAgICAgICAgICAgY2hlY2tzOiBbXG4gICAgICAgICAgICAgICAgLi4uZGVmLmNoZWNrcyA/PyBbXSxcbiAgICAgICAgICAgICAgICAuLi5jaGVja3MubWFwKChjaCk9PnR5cGVvZiBjaCA9PT0gXCJmdW5jdGlvblwiID8ge1xuICAgICAgICAgICAgICAgICAgICAgICAgX3pvZDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrOiBjaCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWY6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2s6IFwiY3VzdG9tXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uYXR0YWNoOiBbXVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IDogY2gpXG4gICAgICAgICAgICBdXG4gICAgICAgIH0pKTtcbiAgICB9O1xuICAgIGluc3QuY2xvbmUgPSAoZGVmLCBwYXJhbXMpPT5jb3JlLmNsb25lKGluc3QsIGRlZiwgcGFyYW1zKTtcbiAgICBpbnN0LmJyYW5kID0gKCk9Pmluc3Q7XG4gICAgaW5zdC5yZWdpc3RlciA9IChyZWcsIG1ldGEpPT57XG4gICAgICAgIHJlZy5hZGQoaW5zdCwgbWV0YSk7XG4gICAgICAgIHJldHVybiBpbnN0O1xuICAgIH07XG4gICAgLy8gcGFyc2luZ1xuICAgIGluc3QucGFyc2UgPSAoZGF0YSwgcGFyYW1zKT0+cGFyc2UucGFyc2UoaW5zdCwgZGF0YSwgcGFyYW1zLCB7XG4gICAgICAgICAgICBjYWxsZWU6IGluc3QucGFyc2VcbiAgICAgICAgfSk7XG4gICAgaW5zdC5zYWZlUGFyc2UgPSAoZGF0YSwgcGFyYW1zKT0+cGFyc2Uuc2FmZVBhcnNlKGluc3QsIGRhdGEsIHBhcmFtcyk7XG4gICAgaW5zdC5wYXJzZUFzeW5jID0gYXN5bmMgKGRhdGEsIHBhcmFtcyk9PnBhcnNlLnBhcnNlQXN5bmMoaW5zdCwgZGF0YSwgcGFyYW1zLCB7XG4gICAgICAgICAgICBjYWxsZWU6IGluc3QucGFyc2VBc3luY1xuICAgICAgICB9KTtcbiAgICBpbnN0LnNhZmVQYXJzZUFzeW5jID0gYXN5bmMgKGRhdGEsIHBhcmFtcyk9PnBhcnNlLnNhZmVQYXJzZUFzeW5jKGluc3QsIGRhdGEsIHBhcmFtcyk7XG4gICAgaW5zdC5zcGEgPSBpbnN0LnNhZmVQYXJzZUFzeW5jO1xuICAgIC8vIGVuY29kaW5nL2RlY29kaW5nXG4gICAgaW5zdC5lbmNvZGUgPSAoZGF0YSwgcGFyYW1zKT0+cGFyc2UuZW5jb2RlKGluc3QsIGRhdGEsIHBhcmFtcyk7XG4gICAgaW5zdC5kZWNvZGUgPSAoZGF0YSwgcGFyYW1zKT0+cGFyc2UuZGVjb2RlKGluc3QsIGRhdGEsIHBhcmFtcyk7XG4gICAgaW5zdC5lbmNvZGVBc3luYyA9IGFzeW5jIChkYXRhLCBwYXJhbXMpPT5wYXJzZS5lbmNvZGVBc3luYyhpbnN0LCBkYXRhLCBwYXJhbXMpO1xuICAgIGluc3QuZGVjb2RlQXN5bmMgPSBhc3luYyAoZGF0YSwgcGFyYW1zKT0+cGFyc2UuZGVjb2RlQXN5bmMoaW5zdCwgZGF0YSwgcGFyYW1zKTtcbiAgICBpbnN0LnNhZmVFbmNvZGUgPSAoZGF0YSwgcGFyYW1zKT0+cGFyc2Uuc2FmZUVuY29kZShpbnN0LCBkYXRhLCBwYXJhbXMpO1xuICAgIGluc3Quc2FmZURlY29kZSA9IChkYXRhLCBwYXJhbXMpPT5wYXJzZS5zYWZlRGVjb2RlKGluc3QsIGRhdGEsIHBhcmFtcyk7XG4gICAgaW5zdC5zYWZlRW5jb2RlQXN5bmMgPSBhc3luYyAoZGF0YSwgcGFyYW1zKT0+cGFyc2Uuc2FmZUVuY29kZUFzeW5jKGluc3QsIGRhdGEsIHBhcmFtcyk7XG4gICAgaW5zdC5zYWZlRGVjb2RlQXN5bmMgPSBhc3luYyAoZGF0YSwgcGFyYW1zKT0+cGFyc2Uuc2FmZURlY29kZUFzeW5jKGluc3QsIGRhdGEsIHBhcmFtcyk7XG4gICAgLy8gcmVmaW5lbWVudHNcbiAgICBpbnN0LnJlZmluZSA9IChjaGVjaywgcGFyYW1zKT0+aW5zdC5jaGVjayhyZWZpbmUoY2hlY2ssIHBhcmFtcykpO1xuICAgIGluc3Quc3VwZXJSZWZpbmUgPSAocmVmaW5lbWVudCk9Pmluc3QuY2hlY2soc3VwZXJSZWZpbmUocmVmaW5lbWVudCkpO1xuICAgIGluc3Qub3ZlcndyaXRlID0gKGZuKT0+aW5zdC5jaGVjayhjaGVja3Mub3ZlcndyaXRlKGZuKSk7XG4gICAgLy8gd3JhcHBlcnNcbiAgICBpbnN0Lm9wdGlvbmFsID0gKCk9Pm9wdGlvbmFsKGluc3QpO1xuICAgIGluc3QubnVsbGFibGUgPSAoKT0+bnVsbGFibGUoaW5zdCk7XG4gICAgaW5zdC5udWxsaXNoID0gKCk9Pm9wdGlvbmFsKG51bGxhYmxlKGluc3QpKTtcbiAgICBpbnN0Lm5vbm9wdGlvbmFsID0gKHBhcmFtcyk9Pm5vbm9wdGlvbmFsKGluc3QsIHBhcmFtcyk7XG4gICAgaW5zdC5hcnJheSA9ICgpPT5hcnJheShpbnN0KTtcbiAgICBpbnN0Lm9yID0gKGFyZyk9PnVuaW9uKFtcbiAgICAgICAgICAgIGluc3QsXG4gICAgICAgICAgICBhcmdcbiAgICAgICAgXSk7XG4gICAgaW5zdC5hbmQgPSAoYXJnKT0+aW50ZXJzZWN0aW9uKGluc3QsIGFyZyk7XG4gICAgaW5zdC50cmFuc2Zvcm0gPSAodHgpPT5waXBlKGluc3QsIHRyYW5zZm9ybSh0eCkpO1xuICAgIGluc3QuZGVmYXVsdCA9IChkZWYpPT5fZGVmYXVsdChpbnN0LCBkZWYpO1xuICAgIGluc3QucHJlZmF1bHQgPSAoZGVmKT0+cHJlZmF1bHQoaW5zdCwgZGVmKTtcbiAgICAvLyBpbnN0LmNvYWxlc2NlID0gKGRlZiwgcGFyYW1zKSA9PiBjb2FsZXNjZShpbnN0LCBkZWYsIHBhcmFtcyk7XG4gICAgaW5zdC5jYXRjaCA9IChwYXJhbXMpPT5fY2F0Y2goaW5zdCwgcGFyYW1zKTtcbiAgICBpbnN0LnBpcGUgPSAodGFyZ2V0KT0+cGlwZShpbnN0LCB0YXJnZXQpO1xuICAgIGluc3QucmVhZG9ubHkgPSAoKT0+cmVhZG9ubHkoaW5zdCk7XG4gICAgLy8gbWV0YVxuICAgIGluc3QuZGVzY3JpYmUgPSAoZGVzY3JpcHRpb24pPT57XG4gICAgICAgIGNvbnN0IGNsID0gaW5zdC5jbG9uZSgpO1xuICAgICAgICBjb3JlLmdsb2JhbFJlZ2lzdHJ5LmFkZChjbCwge1xuICAgICAgICAgICAgZGVzY3JpcHRpb25cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBjbDtcbiAgICB9O1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShpbnN0LCBcImRlc2NyaXB0aW9uXCIsIHtcbiAgICAgICAgZ2V0ICgpIHtcbiAgICAgICAgICAgIHJldHVybiBjb3JlLmdsb2JhbFJlZ2lzdHJ5LmdldChpbnN0KT8uZGVzY3JpcHRpb247XG4gICAgICAgIH0sXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH0pO1xuICAgIGluc3QubWV0YSA9ICguLi5hcmdzKT0+e1xuICAgICAgICBpZiAoYXJncy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBjb3JlLmdsb2JhbFJlZ2lzdHJ5LmdldChpbnN0KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjbCA9IGluc3QuY2xvbmUoKTtcbiAgICAgICAgY29yZS5nbG9iYWxSZWdpc3RyeS5hZGQoY2wsIGFyZ3NbMF0pO1xuICAgICAgICByZXR1cm4gY2w7XG4gICAgfTtcbiAgICAvLyBoZWxwZXJzXG4gICAgaW5zdC5pc09wdGlvbmFsID0gKCk9Pmluc3Quc2FmZVBhcnNlKHVuZGVmaW5lZCkuc3VjY2VzcztcbiAgICBpbnN0LmlzTnVsbGFibGUgPSAoKT0+aW5zdC5zYWZlUGFyc2UobnVsbCkuc3VjY2VzcztcbiAgICByZXR1cm4gaW5zdDtcbn0pO1xuLyoqIEBpbnRlcm5hbCAqLyBleHBvcnQgY29uc3QgX1pvZFN0cmluZyA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJfWm9kU3RyaW5nXCIsIChpbnN0LCBkZWYpPT57XG4gICAgY29yZS4kWm9kU3RyaW5nLmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBjb25zdCBiYWcgPSBpbnN0Ll96b2QuYmFnO1xuICAgIGluc3QuZm9ybWF0ID0gYmFnLmZvcm1hdCA/PyBudWxsO1xuICAgIGluc3QubWluTGVuZ3RoID0gYmFnLm1pbmltdW0gPz8gbnVsbDtcbiAgICBpbnN0Lm1heExlbmd0aCA9IGJhZy5tYXhpbXVtID8/IG51bGw7XG4gICAgLy8gdmFsaWRhdGlvbnNcbiAgICBpbnN0LnJlZ2V4ID0gKC4uLmFyZ3MpPT5pbnN0LmNoZWNrKGNoZWNrcy5yZWdleCguLi5hcmdzKSk7XG4gICAgaW5zdC5pbmNsdWRlcyA9ICguLi5hcmdzKT0+aW5zdC5jaGVjayhjaGVja3MuaW5jbHVkZXMoLi4uYXJncykpO1xuICAgIGluc3Quc3RhcnRzV2l0aCA9ICguLi5hcmdzKT0+aW5zdC5jaGVjayhjaGVja3Muc3RhcnRzV2l0aCguLi5hcmdzKSk7XG4gICAgaW5zdC5lbmRzV2l0aCA9ICguLi5hcmdzKT0+aW5zdC5jaGVjayhjaGVja3MuZW5kc1dpdGgoLi4uYXJncykpO1xuICAgIGluc3QubWluID0gKC4uLmFyZ3MpPT5pbnN0LmNoZWNrKGNoZWNrcy5taW5MZW5ndGgoLi4uYXJncykpO1xuICAgIGluc3QubWF4ID0gKC4uLmFyZ3MpPT5pbnN0LmNoZWNrKGNoZWNrcy5tYXhMZW5ndGgoLi4uYXJncykpO1xuICAgIGluc3QubGVuZ3RoID0gKC4uLmFyZ3MpPT5pbnN0LmNoZWNrKGNoZWNrcy5sZW5ndGgoLi4uYXJncykpO1xuICAgIGluc3Qubm9uZW1wdHkgPSAoLi4uYXJncyk9Pmluc3QuY2hlY2soY2hlY2tzLm1pbkxlbmd0aCgxLCAuLi5hcmdzKSk7XG4gICAgaW5zdC5sb3dlcmNhc2UgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhjaGVja3MubG93ZXJjYXNlKHBhcmFtcykpO1xuICAgIGluc3QudXBwZXJjYXNlID0gKHBhcmFtcyk9Pmluc3QuY2hlY2soY2hlY2tzLnVwcGVyY2FzZShwYXJhbXMpKTtcbiAgICAvLyB0cmFuc2Zvcm1zXG4gICAgaW5zdC50cmltID0gKCk9Pmluc3QuY2hlY2soY2hlY2tzLnRyaW0oKSk7XG4gICAgaW5zdC5ub3JtYWxpemUgPSAoLi4uYXJncyk9Pmluc3QuY2hlY2soY2hlY2tzLm5vcm1hbGl6ZSguLi5hcmdzKSk7XG4gICAgaW5zdC50b0xvd2VyQ2FzZSA9ICgpPT5pbnN0LmNoZWNrKGNoZWNrcy50b0xvd2VyQ2FzZSgpKTtcbiAgICBpbnN0LnRvVXBwZXJDYXNlID0gKCk9Pmluc3QuY2hlY2soY2hlY2tzLnRvVXBwZXJDYXNlKCkpO1xufSk7XG5leHBvcnQgY29uc3QgWm9kU3RyaW5nID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZFN0cmluZ1wiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZFN0cmluZy5pbml0KGluc3QsIGRlZik7XG4gICAgX1pvZFN0cmluZy5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5lbWFpbCA9IChwYXJhbXMpPT5pbnN0LmNoZWNrKGNvcmUuX2VtYWlsKFpvZEVtYWlsLCBwYXJhbXMpKTtcbiAgICBpbnN0LnVybCA9IChwYXJhbXMpPT5pbnN0LmNoZWNrKGNvcmUuX3VybChab2RVUkwsIHBhcmFtcykpO1xuICAgIGluc3Quand0ID0gKHBhcmFtcyk9Pmluc3QuY2hlY2soY29yZS5fand0KFpvZEpXVCwgcGFyYW1zKSk7XG4gICAgaW5zdC5lbW9qaSA9IChwYXJhbXMpPT5pbnN0LmNoZWNrKGNvcmUuX2Vtb2ppKFpvZEVtb2ppLCBwYXJhbXMpKTtcbiAgICBpbnN0Lmd1aWQgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhjb3JlLl9ndWlkKFpvZEdVSUQsIHBhcmFtcykpO1xuICAgIGluc3QudXVpZCA9IChwYXJhbXMpPT5pbnN0LmNoZWNrKGNvcmUuX3V1aWQoWm9kVVVJRCwgcGFyYW1zKSk7XG4gICAgaW5zdC51dWlkdjQgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhjb3JlLl91dWlkdjQoWm9kVVVJRCwgcGFyYW1zKSk7XG4gICAgaW5zdC51dWlkdjYgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhjb3JlLl91dWlkdjYoWm9kVVVJRCwgcGFyYW1zKSk7XG4gICAgaW5zdC51dWlkdjcgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhjb3JlLl91dWlkdjcoWm9kVVVJRCwgcGFyYW1zKSk7XG4gICAgaW5zdC5uYW5vaWQgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhjb3JlLl9uYW5vaWQoWm9kTmFub0lELCBwYXJhbXMpKTtcbiAgICBpbnN0Lmd1aWQgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhjb3JlLl9ndWlkKFpvZEdVSUQsIHBhcmFtcykpO1xuICAgIGluc3QuY3VpZCA9IChwYXJhbXMpPT5pbnN0LmNoZWNrKGNvcmUuX2N1aWQoWm9kQ1VJRCwgcGFyYW1zKSk7XG4gICAgaW5zdC5jdWlkMiA9IChwYXJhbXMpPT5pbnN0LmNoZWNrKGNvcmUuX2N1aWQyKFpvZENVSUQyLCBwYXJhbXMpKTtcbiAgICBpbnN0LnVsaWQgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhjb3JlLl91bGlkKFpvZFVMSUQsIHBhcmFtcykpO1xuICAgIGluc3QuYmFzZTY0ID0gKHBhcmFtcyk9Pmluc3QuY2hlY2soY29yZS5fYmFzZTY0KFpvZEJhc2U2NCwgcGFyYW1zKSk7XG4gICAgaW5zdC5iYXNlNjR1cmwgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhjb3JlLl9iYXNlNjR1cmwoWm9kQmFzZTY0VVJMLCBwYXJhbXMpKTtcbiAgICBpbnN0LnhpZCA9IChwYXJhbXMpPT5pbnN0LmNoZWNrKGNvcmUuX3hpZChab2RYSUQsIHBhcmFtcykpO1xuICAgIGluc3Qua3N1aWQgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhjb3JlLl9rc3VpZChab2RLU1VJRCwgcGFyYW1zKSk7XG4gICAgaW5zdC5pcHY0ID0gKHBhcmFtcyk9Pmluc3QuY2hlY2soY29yZS5faXB2NChab2RJUHY0LCBwYXJhbXMpKTtcbiAgICBpbnN0LmlwdjYgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhjb3JlLl9pcHY2KFpvZElQdjYsIHBhcmFtcykpO1xuICAgIGluc3QuY2lkcnY0ID0gKHBhcmFtcyk9Pmluc3QuY2hlY2soY29yZS5fY2lkcnY0KFpvZENJRFJ2NCwgcGFyYW1zKSk7XG4gICAgaW5zdC5jaWRydjYgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhjb3JlLl9jaWRydjYoWm9kQ0lEUnY2LCBwYXJhbXMpKTtcbiAgICBpbnN0LmUxNjQgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhjb3JlLl9lMTY0KFpvZEUxNjQsIHBhcmFtcykpO1xuICAgIC8vIGlzb1xuICAgIGluc3QuZGF0ZXRpbWUgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhpc28uZGF0ZXRpbWUocGFyYW1zKSk7XG4gICAgaW5zdC5kYXRlID0gKHBhcmFtcyk9Pmluc3QuY2hlY2soaXNvLmRhdGUocGFyYW1zKSk7XG4gICAgaW5zdC50aW1lID0gKHBhcmFtcyk9Pmluc3QuY2hlY2soaXNvLnRpbWUocGFyYW1zKSk7XG4gICAgaW5zdC5kdXJhdGlvbiA9IChwYXJhbXMpPT5pbnN0LmNoZWNrKGlzby5kdXJhdGlvbihwYXJhbXMpKTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIHN0cmluZyhwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fc3RyaW5nKFpvZFN0cmluZywgcGFyYW1zKTtcbn1cbmV4cG9ydCBjb25zdCBab2RTdHJpbmdGb3JtYXQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kU3RyaW5nRm9ybWF0XCIsIChpbnN0LCBkZWYpPT57XG4gICAgY29yZS4kWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbiAgICBfWm9kU3RyaW5nLmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGNvbnN0IFpvZEVtYWlsID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZEVtYWlsXCIsIChpbnN0LCBkZWYpPT57XG4gICAgLy8gWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbiAgICBjb3JlLiRab2RFbWFpbC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIGVtYWlsKHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9lbWFpbChab2RFbWFpbCwgcGFyYW1zKTtcbn1cbmV4cG9ydCBjb25zdCBab2RHVUlEID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZEdVSURcIiwgKGluc3QsIGRlZik9PntcbiAgICAvLyBab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xuICAgIGNvcmUuJFpvZEdVSUQuaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBndWlkKHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9ndWlkKFpvZEdVSUQsIHBhcmFtcyk7XG59XG5leHBvcnQgY29uc3QgWm9kVVVJRCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2RVVUlEXCIsIChpbnN0LCBkZWYpPT57XG4gICAgLy8gWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbiAgICBjb3JlLiRab2RVVUlELmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gdXVpZChwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fdXVpZChab2RVVUlELCBwYXJhbXMpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHV1aWR2NChwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fdXVpZHY0KFpvZFVVSUQsIHBhcmFtcyk7XG59XG4vLyBab2RVVUlEdjZcbmV4cG9ydCBmdW5jdGlvbiB1dWlkdjYocGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX3V1aWR2Nihab2RVVUlELCBwYXJhbXMpO1xufVxuLy8gWm9kVVVJRHY3XG5leHBvcnQgZnVuY3Rpb24gdXVpZHY3KHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl91dWlkdjcoWm9kVVVJRCwgcGFyYW1zKTtcbn1cbmV4cG9ydCBjb25zdCBab2RVUkwgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kVVJMXCIsIChpbnN0LCBkZWYpPT57XG4gICAgLy8gWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbiAgICBjb3JlLiRab2RVUkwuaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiB1cmwocGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX3VybChab2RVUkwsIHBhcmFtcyk7XG59XG5leHBvcnQgZnVuY3Rpb24gaHR0cFVybChwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fdXJsKFpvZFVSTCwge1xuICAgICAgICBwcm90b2NvbDogL15odHRwcz8kLyxcbiAgICAgICAgaG9zdG5hbWU6IGNvcmUucmVnZXhlcy5kb21haW4sXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBjb25zdCBab2RFbW9qaSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2RFbW9qaVwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIC8vIFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG4gICAgY29yZS4kWm9kRW1vamkuaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBlbW9qaShwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fZW1vamkoWm9kRW1vamksIHBhcmFtcyk7XG59XG5leHBvcnQgY29uc3QgWm9kTmFub0lEID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZE5hbm9JRFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIC8vIFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG4gICAgY29yZS4kWm9kTmFub0lELmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gbmFub2lkKHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9uYW5vaWQoWm9kTmFub0lELCBwYXJhbXMpO1xufVxuZXhwb3J0IGNvbnN0IFpvZENVSUQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kQ1VJRFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIC8vIFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG4gICAgY29yZS4kWm9kQ1VJRC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIGN1aWQocGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX2N1aWQoWm9kQ1VJRCwgcGFyYW1zKTtcbn1cbmV4cG9ydCBjb25zdCBab2RDVUlEMiA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2RDVUlEMlwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIC8vIFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG4gICAgY29yZS4kWm9kQ1VJRDIuaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBjdWlkMihwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fY3VpZDIoWm9kQ1VJRDIsIHBhcmFtcyk7XG59XG5leHBvcnQgY29uc3QgWm9kVUxJRCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2RVTElEXCIsIChpbnN0LCBkZWYpPT57XG4gICAgLy8gWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbiAgICBjb3JlLiRab2RVTElELmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gdWxpZChwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fdWxpZChab2RVTElELCBwYXJhbXMpO1xufVxuZXhwb3J0IGNvbnN0IFpvZFhJRCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2RYSURcIiwgKGluc3QsIGRlZik9PntcbiAgICAvLyBab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xuICAgIGNvcmUuJFpvZFhJRC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIHhpZChwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5feGlkKFpvZFhJRCwgcGFyYW1zKTtcbn1cbmV4cG9ydCBjb25zdCBab2RLU1VJRCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2RLU1VJRFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIC8vIFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG4gICAgY29yZS4kWm9kS1NVSUQuaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBrc3VpZChwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fa3N1aWQoWm9kS1NVSUQsIHBhcmFtcyk7XG59XG5leHBvcnQgY29uc3QgWm9kSVB2NCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2RJUHY0XCIsIChpbnN0LCBkZWYpPT57XG4gICAgLy8gWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbiAgICBjb3JlLiRab2RJUHY0LmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gaXB2NChwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5faXB2NChab2RJUHY0LCBwYXJhbXMpO1xufVxuZXhwb3J0IGNvbnN0IFpvZElQdjYgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kSVB2NlwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIC8vIFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG4gICAgY29yZS4kWm9kSVB2Ni5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIGlwdjYocGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX2lwdjYoWm9kSVB2NiwgcGFyYW1zKTtcbn1cbmV4cG9ydCBjb25zdCBab2RDSURSdjQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kQ0lEUnY0XCIsIChpbnN0LCBkZWYpPT57XG4gICAgY29yZS4kWm9kQ0lEUnY0LmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gY2lkcnY0KHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9jaWRydjQoWm9kQ0lEUnY0LCBwYXJhbXMpO1xufVxuZXhwb3J0IGNvbnN0IFpvZENJRFJ2NiA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2RDSURSdjZcIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RDSURSdjYuaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBjaWRydjYocGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX2NpZHJ2Nihab2RDSURSdjYsIHBhcmFtcyk7XG59XG5leHBvcnQgY29uc3QgWm9kQmFzZTY0ID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZEJhc2U2NFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIC8vIFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG4gICAgY29yZS4kWm9kQmFzZTY0LmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gYmFzZTY0KHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9iYXNlNjQoWm9kQmFzZTY0LCBwYXJhbXMpO1xufVxuZXhwb3J0IGNvbnN0IFpvZEJhc2U2NFVSTCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2RCYXNlNjRVUkxcIiwgKGluc3QsIGRlZik9PntcbiAgICAvLyBab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xuICAgIGNvcmUuJFpvZEJhc2U2NFVSTC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIGJhc2U2NHVybChwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fYmFzZTY0dXJsKFpvZEJhc2U2NFVSTCwgcGFyYW1zKTtcbn1cbmV4cG9ydCBjb25zdCBab2RFMTY0ID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZEUxNjRcIiwgKGluc3QsIGRlZik9PntcbiAgICAvLyBab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xuICAgIGNvcmUuJFpvZEUxNjQuaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBlMTY0KHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9lMTY0KFpvZEUxNjQsIHBhcmFtcyk7XG59XG5leHBvcnQgY29uc3QgWm9kSldUID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZEpXVFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIC8vIFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG4gICAgY29yZS4kWm9kSldULmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gand0KHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9qd3QoWm9kSldULCBwYXJhbXMpO1xufVxuZXhwb3J0IGNvbnN0IFpvZEN1c3RvbVN0cmluZ0Zvcm1hdCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2RDdXN0b21TdHJpbmdGb3JtYXRcIiwgKGluc3QsIGRlZik9PntcbiAgICAvLyBab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xuICAgIGNvcmUuJFpvZEN1c3RvbVN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIHN0cmluZ0Zvcm1hdChmb3JtYXQsIGZuT3JSZWdleCwgX3BhcmFtcyA9IHt9KSB7XG4gICAgcmV0dXJuIGNvcmUuX3N0cmluZ0Zvcm1hdChab2RDdXN0b21TdHJpbmdGb3JtYXQsIGZvcm1hdCwgZm5PclJlZ2V4LCBfcGFyYW1zKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBob3N0bmFtZShfcGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX3N0cmluZ0Zvcm1hdChab2RDdXN0b21TdHJpbmdGb3JtYXQsIFwiaG9zdG5hbWVcIiwgY29yZS5yZWdleGVzLmhvc3RuYW1lLCBfcGFyYW1zKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBoZXgoX3BhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9zdHJpbmdGb3JtYXQoWm9kQ3VzdG9tU3RyaW5nRm9ybWF0LCBcImhleFwiLCBjb3JlLnJlZ2V4ZXMuaGV4LCBfcGFyYW1zKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBoYXNoKGFsZywgcGFyYW1zKSB7XG4gICAgY29uc3QgZW5jID0gcGFyYW1zPy5lbmMgPz8gXCJoZXhcIjtcbiAgICBjb25zdCBmb3JtYXQgPSBgJHthbGd9XyR7ZW5jfWA7XG4gICAgY29uc3QgcmVnZXggPSBjb3JlLnJlZ2V4ZXNbZm9ybWF0XTtcbiAgICBpZiAoIXJlZ2V4KSB0aHJvdyBuZXcgRXJyb3IoYFVucmVjb2duaXplZCBoYXNoIGZvcm1hdDogJHtmb3JtYXR9YCk7XG4gICAgcmV0dXJuIGNvcmUuX3N0cmluZ0Zvcm1hdChab2RDdXN0b21TdHJpbmdGb3JtYXQsIGZvcm1hdCwgcmVnZXgsIHBhcmFtcyk7XG59XG5leHBvcnQgY29uc3QgWm9kTnVtYmVyID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZE51bWJlclwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZE51bWJlci5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5ndCA9ICh2YWx1ZSwgcGFyYW1zKT0+aW5zdC5jaGVjayhjaGVja3MuZ3QodmFsdWUsIHBhcmFtcykpO1xuICAgIGluc3QuZ3RlID0gKHZhbHVlLCBwYXJhbXMpPT5pbnN0LmNoZWNrKGNoZWNrcy5ndGUodmFsdWUsIHBhcmFtcykpO1xuICAgIGluc3QubWluID0gKHZhbHVlLCBwYXJhbXMpPT5pbnN0LmNoZWNrKGNoZWNrcy5ndGUodmFsdWUsIHBhcmFtcykpO1xuICAgIGluc3QubHQgPSAodmFsdWUsIHBhcmFtcyk9Pmluc3QuY2hlY2soY2hlY2tzLmx0KHZhbHVlLCBwYXJhbXMpKTtcbiAgICBpbnN0Lmx0ZSA9ICh2YWx1ZSwgcGFyYW1zKT0+aW5zdC5jaGVjayhjaGVja3MubHRlKHZhbHVlLCBwYXJhbXMpKTtcbiAgICBpbnN0Lm1heCA9ICh2YWx1ZSwgcGFyYW1zKT0+aW5zdC5jaGVjayhjaGVja3MubHRlKHZhbHVlLCBwYXJhbXMpKTtcbiAgICBpbnN0LmludCA9IChwYXJhbXMpPT5pbnN0LmNoZWNrKGludChwYXJhbXMpKTtcbiAgICBpbnN0LnNhZmUgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhpbnQocGFyYW1zKSk7XG4gICAgaW5zdC5wb3NpdGl2ZSA9IChwYXJhbXMpPT5pbnN0LmNoZWNrKGNoZWNrcy5ndCgwLCBwYXJhbXMpKTtcbiAgICBpbnN0Lm5vbm5lZ2F0aXZlID0gKHBhcmFtcyk9Pmluc3QuY2hlY2soY2hlY2tzLmd0ZSgwLCBwYXJhbXMpKTtcbiAgICBpbnN0Lm5lZ2F0aXZlID0gKHBhcmFtcyk9Pmluc3QuY2hlY2soY2hlY2tzLmx0KDAsIHBhcmFtcykpO1xuICAgIGluc3Qubm9ucG9zaXRpdmUgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhjaGVja3MubHRlKDAsIHBhcmFtcykpO1xuICAgIGluc3QubXVsdGlwbGVPZiA9ICh2YWx1ZSwgcGFyYW1zKT0+aW5zdC5jaGVjayhjaGVja3MubXVsdGlwbGVPZih2YWx1ZSwgcGFyYW1zKSk7XG4gICAgaW5zdC5zdGVwID0gKHZhbHVlLCBwYXJhbXMpPT5pbnN0LmNoZWNrKGNoZWNrcy5tdWx0aXBsZU9mKHZhbHVlLCBwYXJhbXMpKTtcbiAgICAvLyBpbnN0LmZpbml0ZSA9IChwYXJhbXMpID0+IGluc3QuY2hlY2soY29yZS5maW5pdGUocGFyYW1zKSk7XG4gICAgaW5zdC5maW5pdGUgPSAoKT0+aW5zdDtcbiAgICBjb25zdCBiYWcgPSBpbnN0Ll96b2QuYmFnO1xuICAgIGluc3QubWluVmFsdWUgPSBNYXRoLm1heChiYWcubWluaW11bSA/PyBOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFksIGJhZy5leGNsdXNpdmVNaW5pbXVtID8/IE51bWJlci5ORUdBVElWRV9JTkZJTklUWSkgPz8gbnVsbDtcbiAgICBpbnN0Lm1heFZhbHVlID0gTWF0aC5taW4oYmFnLm1heGltdW0gPz8gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZLCBiYWcuZXhjbHVzaXZlTWF4aW11bSA/PyBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkpID8/IG51bGw7XG4gICAgaW5zdC5pc0ludCA9IChiYWcuZm9ybWF0ID8/IFwiXCIpLmluY2x1ZGVzKFwiaW50XCIpIHx8IE51bWJlci5pc1NhZmVJbnRlZ2VyKGJhZy5tdWx0aXBsZU9mID8/IDAuNSk7XG4gICAgaW5zdC5pc0Zpbml0ZSA9IHRydWU7XG4gICAgaW5zdC5mb3JtYXQgPSBiYWcuZm9ybWF0ID8/IG51bGw7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBudW1iZXIocGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX251bWJlcihab2ROdW1iZXIsIHBhcmFtcyk7XG59XG5leHBvcnQgY29uc3QgWm9kTnVtYmVyRm9ybWF0ID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZE51bWJlckZvcm1hdFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZE51bWJlckZvcm1hdC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kTnVtYmVyLmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIGludChwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5faW50KFpvZE51bWJlckZvcm1hdCwgcGFyYW1zKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBmbG9hdDMyKHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9mbG9hdDMyKFpvZE51bWJlckZvcm1hdCwgcGFyYW1zKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBmbG9hdDY0KHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9mbG9hdDY0KFpvZE51bWJlckZvcm1hdCwgcGFyYW1zKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBpbnQzMihwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5faW50MzIoWm9kTnVtYmVyRm9ybWF0LCBwYXJhbXMpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHVpbnQzMihwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fdWludDMyKFpvZE51bWJlckZvcm1hdCwgcGFyYW1zKTtcbn1cbmV4cG9ydCBjb25zdCBab2RCb29sZWFuID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZEJvb2xlYW5cIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RCb29sZWFuLmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIGJvb2xlYW4ocGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX2Jvb2xlYW4oWm9kQm9vbGVhbiwgcGFyYW1zKTtcbn1cbmV4cG9ydCBjb25zdCBab2RCaWdJbnQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kQmlnSW50XCIsIChpbnN0LCBkZWYpPT57XG4gICAgY29yZS4kWm9kQmlnSW50LmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0Lmd0ZSA9ICh2YWx1ZSwgcGFyYW1zKT0+aW5zdC5jaGVjayhjaGVja3MuZ3RlKHZhbHVlLCBwYXJhbXMpKTtcbiAgICBpbnN0Lm1pbiA9ICh2YWx1ZSwgcGFyYW1zKT0+aW5zdC5jaGVjayhjaGVja3MuZ3RlKHZhbHVlLCBwYXJhbXMpKTtcbiAgICBpbnN0Lmd0ID0gKHZhbHVlLCBwYXJhbXMpPT5pbnN0LmNoZWNrKGNoZWNrcy5ndCh2YWx1ZSwgcGFyYW1zKSk7XG4gICAgaW5zdC5ndGUgPSAodmFsdWUsIHBhcmFtcyk9Pmluc3QuY2hlY2soY2hlY2tzLmd0ZSh2YWx1ZSwgcGFyYW1zKSk7XG4gICAgaW5zdC5taW4gPSAodmFsdWUsIHBhcmFtcyk9Pmluc3QuY2hlY2soY2hlY2tzLmd0ZSh2YWx1ZSwgcGFyYW1zKSk7XG4gICAgaW5zdC5sdCA9ICh2YWx1ZSwgcGFyYW1zKT0+aW5zdC5jaGVjayhjaGVja3MubHQodmFsdWUsIHBhcmFtcykpO1xuICAgIGluc3QubHRlID0gKHZhbHVlLCBwYXJhbXMpPT5pbnN0LmNoZWNrKGNoZWNrcy5sdGUodmFsdWUsIHBhcmFtcykpO1xuICAgIGluc3QubWF4ID0gKHZhbHVlLCBwYXJhbXMpPT5pbnN0LmNoZWNrKGNoZWNrcy5sdGUodmFsdWUsIHBhcmFtcykpO1xuICAgIGluc3QucG9zaXRpdmUgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhjaGVja3MuZ3QoQmlnSW50KDApLCBwYXJhbXMpKTtcbiAgICBpbnN0Lm5lZ2F0aXZlID0gKHBhcmFtcyk9Pmluc3QuY2hlY2soY2hlY2tzLmx0KEJpZ0ludCgwKSwgcGFyYW1zKSk7XG4gICAgaW5zdC5ub25wb3NpdGl2ZSA9IChwYXJhbXMpPT5pbnN0LmNoZWNrKGNoZWNrcy5sdGUoQmlnSW50KDApLCBwYXJhbXMpKTtcbiAgICBpbnN0Lm5vbm5lZ2F0aXZlID0gKHBhcmFtcyk9Pmluc3QuY2hlY2soY2hlY2tzLmd0ZShCaWdJbnQoMCksIHBhcmFtcykpO1xuICAgIGluc3QubXVsdGlwbGVPZiA9ICh2YWx1ZSwgcGFyYW1zKT0+aW5zdC5jaGVjayhjaGVja3MubXVsdGlwbGVPZih2YWx1ZSwgcGFyYW1zKSk7XG4gICAgY29uc3QgYmFnID0gaW5zdC5fem9kLmJhZztcbiAgICBpbnN0Lm1pblZhbHVlID0gYmFnLm1pbmltdW0gPz8gbnVsbDtcbiAgICBpbnN0Lm1heFZhbHVlID0gYmFnLm1heGltdW0gPz8gbnVsbDtcbiAgICBpbnN0LmZvcm1hdCA9IGJhZy5mb3JtYXQgPz8gbnVsbDtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIGJpZ2ludChwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fYmlnaW50KFpvZEJpZ0ludCwgcGFyYW1zKTtcbn1cbmV4cG9ydCBjb25zdCBab2RCaWdJbnRGb3JtYXQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kQmlnSW50Rm9ybWF0XCIsIChpbnN0LCBkZWYpPT57XG4gICAgY29yZS4kWm9kQmlnSW50Rm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RCaWdJbnQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG4vLyBpbnQ2NFxuZXhwb3J0IGZ1bmN0aW9uIGludDY0KHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9pbnQ2NChab2RCaWdJbnRGb3JtYXQsIHBhcmFtcyk7XG59XG4vLyB1aW50NjRcbmV4cG9ydCBmdW5jdGlvbiB1aW50NjQocGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX3VpbnQ2NChab2RCaWdJbnRGb3JtYXQsIHBhcmFtcyk7XG59XG5leHBvcnQgY29uc3QgWm9kU3ltYm9sID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZFN5bWJvbFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZFN5bWJvbC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBzeW1ib2wocGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX3N5bWJvbChab2RTeW1ib2wsIHBhcmFtcyk7XG59XG5leHBvcnQgY29uc3QgWm9kVW5kZWZpbmVkID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZFVuZGVmaW5lZFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZFVuZGVmaW5lZC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG59KTtcbmZ1bmN0aW9uIF91bmRlZmluZWQocGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX3VuZGVmaW5lZChab2RVbmRlZmluZWQsIHBhcmFtcyk7XG59XG5leHBvcnQgeyBfdW5kZWZpbmVkIGFzIHVuZGVmaW5lZCB9O1xuZXhwb3J0IGNvbnN0IFpvZE51bGwgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kTnVsbFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZE51bGwuaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5mdW5jdGlvbiBfbnVsbChwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fbnVsbChab2ROdWxsLCBwYXJhbXMpO1xufVxuZXhwb3J0IHsgX251bGwgYXMgbnVsbCB9O1xuZXhwb3J0IGNvbnN0IFpvZEFueSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2RBbnlcIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RBbnkuaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gYW55KCkge1xuICAgIHJldHVybiBjb3JlLl9hbnkoWm9kQW55KTtcbn1cbmV4cG9ydCBjb25zdCBab2RVbmtub3duID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZFVua25vd25cIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RVbmtub3duLmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIHVua25vd24oKSB7XG4gICAgcmV0dXJuIGNvcmUuX3Vua25vd24oWm9kVW5rbm93bik7XG59XG5leHBvcnQgY29uc3QgWm9kTmV2ZXIgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kTmV2ZXJcIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2ROZXZlci5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBuZXZlcihwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fbmV2ZXIoWm9kTmV2ZXIsIHBhcmFtcyk7XG59XG5leHBvcnQgY29uc3QgWm9kVm9pZCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2RWb2lkXCIsIChpbnN0LCBkZWYpPT57XG4gICAgY29yZS4kWm9kVm9pZC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG59KTtcbmZ1bmN0aW9uIF92b2lkKHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl92b2lkKFpvZFZvaWQsIHBhcmFtcyk7XG59XG5leHBvcnQgeyBfdm9pZCBhcyB2b2lkIH07XG5leHBvcnQgY29uc3QgWm9kRGF0ZSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2REYXRlXCIsIChpbnN0LCBkZWYpPT57XG4gICAgY29yZS4kWm9kRGF0ZS5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5taW4gPSAodmFsdWUsIHBhcmFtcyk9Pmluc3QuY2hlY2soY2hlY2tzLmd0ZSh2YWx1ZSwgcGFyYW1zKSk7XG4gICAgaW5zdC5tYXggPSAodmFsdWUsIHBhcmFtcyk9Pmluc3QuY2hlY2soY2hlY2tzLmx0ZSh2YWx1ZSwgcGFyYW1zKSk7XG4gICAgY29uc3QgYyA9IGluc3QuX3pvZC5iYWc7XG4gICAgaW5zdC5taW5EYXRlID0gYy5taW5pbXVtID8gbmV3IERhdGUoYy5taW5pbXVtKSA6IG51bGw7XG4gICAgaW5zdC5tYXhEYXRlID0gYy5tYXhpbXVtID8gbmV3IERhdGUoYy5tYXhpbXVtKSA6IG51bGw7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBkYXRlKHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9kYXRlKFpvZERhdGUsIHBhcmFtcyk7XG59XG5leHBvcnQgY29uc3QgWm9kQXJyYXkgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kQXJyYXlcIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RBcnJheS5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5lbGVtZW50ID0gZGVmLmVsZW1lbnQ7XG4gICAgaW5zdC5taW4gPSAobWluTGVuZ3RoLCBwYXJhbXMpPT5pbnN0LmNoZWNrKGNoZWNrcy5taW5MZW5ndGgobWluTGVuZ3RoLCBwYXJhbXMpKTtcbiAgICBpbnN0Lm5vbmVtcHR5ID0gKHBhcmFtcyk9Pmluc3QuY2hlY2soY2hlY2tzLm1pbkxlbmd0aCgxLCBwYXJhbXMpKTtcbiAgICBpbnN0Lm1heCA9IChtYXhMZW5ndGgsIHBhcmFtcyk9Pmluc3QuY2hlY2soY2hlY2tzLm1heExlbmd0aChtYXhMZW5ndGgsIHBhcmFtcykpO1xuICAgIGluc3QubGVuZ3RoID0gKGxlbiwgcGFyYW1zKT0+aW5zdC5jaGVjayhjaGVja3MubGVuZ3RoKGxlbiwgcGFyYW1zKSk7XG4gICAgaW5zdC51bndyYXAgPSAoKT0+aW5zdC5lbGVtZW50O1xufSk7XG5leHBvcnQgZnVuY3Rpb24gYXJyYXkoZWxlbWVudCwgcGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX2FycmF5KFpvZEFycmF5LCBlbGVtZW50LCBwYXJhbXMpO1xufVxuLy8gLmtleW9mXG5leHBvcnQgZnVuY3Rpb24ga2V5b2Yoc2NoZW1hKSB7XG4gICAgY29uc3Qgc2hhcGUgPSBzY2hlbWEuX3pvZC5kZWYuc2hhcGU7XG4gICAgcmV0dXJuIF9lbnVtKE9iamVjdC5rZXlzKHNoYXBlKSk7XG59XG5leHBvcnQgY29uc3QgWm9kT2JqZWN0ID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZE9iamVjdFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZE9iamVjdEpJVC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgdXRpbC5kZWZpbmVMYXp5KGluc3QsIFwic2hhcGVcIiwgKCk9PntcbiAgICAgICAgcmV0dXJuIGRlZi5zaGFwZTtcbiAgICB9KTtcbiAgICBpbnN0LmtleW9mID0gKCk9Pl9lbnVtKE9iamVjdC5rZXlzKGluc3QuX3pvZC5kZWYuc2hhcGUpKTtcbiAgICBpbnN0LmNhdGNoYWxsID0gKGNhdGNoYWxsKT0+aW5zdC5jbG9uZSh7XG4gICAgICAgICAgICAuLi5pbnN0Ll96b2QuZGVmLFxuICAgICAgICAgICAgY2F0Y2hhbGw6IGNhdGNoYWxsXG4gICAgICAgIH0pO1xuICAgIGluc3QucGFzc3Rocm91Z2ggPSAoKT0+aW5zdC5jbG9uZSh7XG4gICAgICAgICAgICAuLi5pbnN0Ll96b2QuZGVmLFxuICAgICAgICAgICAgY2F0Y2hhbGw6IHVua25vd24oKVxuICAgICAgICB9KTtcbiAgICBpbnN0Lmxvb3NlID0gKCk9Pmluc3QuY2xvbmUoe1xuICAgICAgICAgICAgLi4uaW5zdC5fem9kLmRlZixcbiAgICAgICAgICAgIGNhdGNoYWxsOiB1bmtub3duKClcbiAgICAgICAgfSk7XG4gICAgaW5zdC5zdHJpY3QgPSAoKT0+aW5zdC5jbG9uZSh7XG4gICAgICAgICAgICAuLi5pbnN0Ll96b2QuZGVmLFxuICAgICAgICAgICAgY2F0Y2hhbGw6IG5ldmVyKClcbiAgICAgICAgfSk7XG4gICAgaW5zdC5zdHJpcCA9ICgpPT5pbnN0LmNsb25lKHtcbiAgICAgICAgICAgIC4uLmluc3QuX3pvZC5kZWYsXG4gICAgICAgICAgICBjYXRjaGFsbDogdW5kZWZpbmVkXG4gICAgICAgIH0pO1xuICAgIGluc3QuZXh0ZW5kID0gKGluY29taW5nKT0+e1xuICAgICAgICByZXR1cm4gdXRpbC5leHRlbmQoaW5zdCwgaW5jb21pbmcpO1xuICAgIH07XG4gICAgaW5zdC5zYWZlRXh0ZW5kID0gKGluY29taW5nKT0+e1xuICAgICAgICByZXR1cm4gdXRpbC5zYWZlRXh0ZW5kKGluc3QsIGluY29taW5nKTtcbiAgICB9O1xuICAgIGluc3QubWVyZ2UgPSAob3RoZXIpPT51dGlsLm1lcmdlKGluc3QsIG90aGVyKTtcbiAgICBpbnN0LnBpY2sgPSAobWFzayk9PnV0aWwucGljayhpbnN0LCBtYXNrKTtcbiAgICBpbnN0Lm9taXQgPSAobWFzayk9PnV0aWwub21pdChpbnN0LCBtYXNrKTtcbiAgICBpbnN0LnBhcnRpYWwgPSAoLi4uYXJncyk9PnV0aWwucGFydGlhbChab2RPcHRpb25hbCwgaW5zdCwgYXJnc1swXSk7XG4gICAgaW5zdC5yZXF1aXJlZCA9ICguLi5hcmdzKT0+dXRpbC5yZXF1aXJlZChab2ROb25PcHRpb25hbCwgaW5zdCwgYXJnc1swXSk7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBvYmplY3Qoc2hhcGUsIHBhcmFtcykge1xuICAgIGNvbnN0IGRlZiA9IHtcbiAgICAgICAgdHlwZTogXCJvYmplY3RcIixcbiAgICAgICAgc2hhcGU6IHNoYXBlID8/IHt9LFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfTtcbiAgICByZXR1cm4gbmV3IFpvZE9iamVjdChkZWYpO1xufVxuLy8gc3RyaWN0T2JqZWN0XG5leHBvcnQgZnVuY3Rpb24gc3RyaWN0T2JqZWN0KHNoYXBlLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IFpvZE9iamVjdCh7XG4gICAgICAgIHR5cGU6IFwib2JqZWN0XCIsXG4gICAgICAgIHNoYXBlLFxuICAgICAgICBjYXRjaGFsbDogbmV2ZXIoKSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuLy8gbG9vc2VPYmplY3RcbmV4cG9ydCBmdW5jdGlvbiBsb29zZU9iamVjdChzaGFwZSwgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBab2RPYmplY3Qoe1xuICAgICAgICB0eXBlOiBcIm9iamVjdFwiLFxuICAgICAgICBzaGFwZSxcbiAgICAgICAgY2F0Y2hhbGw6IHVua25vd24oKSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGNvbnN0IFpvZFVuaW9uID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZFVuaW9uXCIsIChpbnN0LCBkZWYpPT57XG4gICAgY29yZS4kWm9kVW5pb24uaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3Qub3B0aW9ucyA9IGRlZi5vcHRpb25zO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gdW5pb24ob3B0aW9ucywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBab2RVbmlvbih7XG4gICAgICAgIHR5cGU6IFwidW5pb25cIixcbiAgICAgICAgb3B0aW9uczogb3B0aW9ucyxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGNvbnN0IFpvZERpc2NyaW1pbmF0ZWRVbmlvbiA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2REaXNjcmltaW5hdGVkVW5pb25cIiwgKGluc3QsIGRlZik9PntcbiAgICBab2RVbmlvbi5pbml0KGluc3QsIGRlZik7XG4gICAgY29yZS4kWm9kRGlzY3JpbWluYXRlZFVuaW9uLmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIGRpc2NyaW1pbmF0ZWRVbmlvbihkaXNjcmltaW5hdG9yLCBvcHRpb25zLCBwYXJhbXMpIHtcbiAgICAvLyBjb25zdCBbb3B0aW9ucywgcGFyYW1zXSA9IGFyZ3M7XG4gICAgcmV0dXJuIG5ldyBab2REaXNjcmltaW5hdGVkVW5pb24oe1xuICAgICAgICB0eXBlOiBcInVuaW9uXCIsXG4gICAgICAgIG9wdGlvbnMsXG4gICAgICAgIGRpc2NyaW1pbmF0b3IsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBjb25zdCBab2RJbnRlcnNlY3Rpb24gPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kSW50ZXJzZWN0aW9uXCIsIChpbnN0LCBkZWYpPT57XG4gICAgY29yZS4kWm9kSW50ZXJzZWN0aW9uLmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIGludGVyc2VjdGlvbihsZWZ0LCByaWdodCkge1xuICAgIHJldHVybiBuZXcgWm9kSW50ZXJzZWN0aW9uKHtcbiAgICAgICAgdHlwZTogXCJpbnRlcnNlY3Rpb25cIixcbiAgICAgICAgbGVmdDogbGVmdCxcbiAgICAgICAgcmlnaHQ6IHJpZ2h0XG4gICAgfSk7XG59XG5leHBvcnQgY29uc3QgWm9kVHVwbGUgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kVHVwbGVcIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RUdXBsZS5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5yZXN0ID0gKHJlc3QpPT5pbnN0LmNsb25lKHtcbiAgICAgICAgICAgIC4uLmluc3QuX3pvZC5kZWYsXG4gICAgICAgICAgICByZXN0OiByZXN0XG4gICAgICAgIH0pO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gdHVwbGUoaXRlbXMsIF9wYXJhbXNPclJlc3QsIF9wYXJhbXMpIHtcbiAgICBjb25zdCBoYXNSZXN0ID0gX3BhcmFtc09yUmVzdCBpbnN0YW5jZW9mIGNvcmUuJFpvZFR5cGU7XG4gICAgY29uc3QgcGFyYW1zID0gaGFzUmVzdCA/IF9wYXJhbXMgOiBfcGFyYW1zT3JSZXN0O1xuICAgIGNvbnN0IHJlc3QgPSBoYXNSZXN0ID8gX3BhcmFtc09yUmVzdCA6IG51bGw7XG4gICAgcmV0dXJuIG5ldyBab2RUdXBsZSh7XG4gICAgICAgIHR5cGU6IFwidHVwbGVcIixcbiAgICAgICAgaXRlbXM6IGl0ZW1zLFxuICAgICAgICByZXN0LFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgY29uc3QgWm9kUmVjb3JkID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZFJlY29yZFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZFJlY29yZC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5rZXlUeXBlID0gZGVmLmtleVR5cGU7XG4gICAgaW5zdC52YWx1ZVR5cGUgPSBkZWYudmFsdWVUeXBlO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gcmVjb3JkKGtleVR5cGUsIHZhbHVlVHlwZSwgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBab2RSZWNvcmQoe1xuICAgICAgICB0eXBlOiBcInJlY29yZFwiLFxuICAgICAgICBrZXlUeXBlLFxuICAgICAgICB2YWx1ZVR5cGU6IHZhbHVlVHlwZSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuLy8gdHlwZSBhbGtzamYgPSBjb3JlLm91dHB1dDxjb3JlLiRab2RSZWNvcmRLZXk+O1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnRpYWxSZWNvcmQoa2V5VHlwZSwgdmFsdWVUeXBlLCBwYXJhbXMpIHtcbiAgICBjb25zdCBrID0gY29yZS5jbG9uZShrZXlUeXBlKTtcbiAgICBrLl96b2QudmFsdWVzID0gdW5kZWZpbmVkO1xuICAgIHJldHVybiBuZXcgWm9kUmVjb3JkKHtcbiAgICAgICAgdHlwZTogXCJyZWNvcmRcIixcbiAgICAgICAga2V5VHlwZTogayxcbiAgICAgICAgdmFsdWVUeXBlOiB2YWx1ZVR5cGUsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBjb25zdCBab2RNYXAgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kTWFwXCIsIChpbnN0LCBkZWYpPT57XG4gICAgY29yZS4kWm9kTWFwLmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0LmtleVR5cGUgPSBkZWYua2V5VHlwZTtcbiAgICBpbnN0LnZhbHVlVHlwZSA9IGRlZi52YWx1ZVR5cGU7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBtYXAoa2V5VHlwZSwgdmFsdWVUeXBlLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IFpvZE1hcCh7XG4gICAgICAgIHR5cGU6IFwibWFwXCIsXG4gICAgICAgIGtleVR5cGU6IGtleVR5cGUsXG4gICAgICAgIHZhbHVlVHlwZTogdmFsdWVUeXBlLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgY29uc3QgWm9kU2V0ID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZFNldFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZFNldC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5taW4gPSAoLi4uYXJncyk9Pmluc3QuY2hlY2soY29yZS5fbWluU2l6ZSguLi5hcmdzKSk7XG4gICAgaW5zdC5ub25lbXB0eSA9IChwYXJhbXMpPT5pbnN0LmNoZWNrKGNvcmUuX21pblNpemUoMSwgcGFyYW1zKSk7XG4gICAgaW5zdC5tYXggPSAoLi4uYXJncyk9Pmluc3QuY2hlY2soY29yZS5fbWF4U2l6ZSguLi5hcmdzKSk7XG4gICAgaW5zdC5zaXplID0gKC4uLmFyZ3MpPT5pbnN0LmNoZWNrKGNvcmUuX3NpemUoLi4uYXJncykpO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gc2V0KHZhbHVlVHlwZSwgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBab2RTZXQoe1xuICAgICAgICB0eXBlOiBcInNldFwiLFxuICAgICAgICB2YWx1ZVR5cGU6IHZhbHVlVHlwZSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGNvbnN0IFpvZEVudW0gPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kRW51bVwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZEVudW0uaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuZW51bSA9IGRlZi5lbnRyaWVzO1xuICAgIGluc3Qub3B0aW9ucyA9IE9iamVjdC52YWx1ZXMoZGVmLmVudHJpZXMpO1xuICAgIGNvbnN0IGtleXMgPSBuZXcgU2V0KE9iamVjdC5rZXlzKGRlZi5lbnRyaWVzKSk7XG4gICAgaW5zdC5leHRyYWN0ID0gKHZhbHVlcywgcGFyYW1zKT0+e1xuICAgICAgICBjb25zdCBuZXdFbnRyaWVzID0ge307XG4gICAgICAgIGZvciAoY29uc3QgdmFsdWUgb2YgdmFsdWVzKXtcbiAgICAgICAgICAgIGlmIChrZXlzLmhhcyh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICBuZXdFbnRyaWVzW3ZhbHVlXSA9IGRlZi5lbnRyaWVzW3ZhbHVlXTtcbiAgICAgICAgICAgIH0gZWxzZSB0aHJvdyBuZXcgRXJyb3IoYEtleSAke3ZhbHVlfSBub3QgZm91bmQgaW4gZW51bWApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgWm9kRW51bSh7XG4gICAgICAgICAgICAuLi5kZWYsXG4gICAgICAgICAgICBjaGVja3M6IFtdLFxuICAgICAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKSxcbiAgICAgICAgICAgIGVudHJpZXM6IG5ld0VudHJpZXNcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBpbnN0LmV4Y2x1ZGUgPSAodmFsdWVzLCBwYXJhbXMpPT57XG4gICAgICAgIGNvbnN0IG5ld0VudHJpZXMgPSB7XG4gICAgICAgICAgICAuLi5kZWYuZW50cmllc1xuICAgICAgICB9O1xuICAgICAgICBmb3IgKGNvbnN0IHZhbHVlIG9mIHZhbHVlcyl7XG4gICAgICAgICAgICBpZiAoa2V5cy5oYXModmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIG5ld0VudHJpZXNbdmFsdWVdO1xuICAgICAgICAgICAgfSBlbHNlIHRocm93IG5ldyBFcnJvcihgS2V5ICR7dmFsdWV9IG5vdCBmb3VuZCBpbiBlbnVtYCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBab2RFbnVtKHtcbiAgICAgICAgICAgIC4uLmRlZixcbiAgICAgICAgICAgIGNoZWNrczogW10sXG4gICAgICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpLFxuICAgICAgICAgICAgZW50cmllczogbmV3RW50cmllc1xuICAgICAgICB9KTtcbiAgICB9O1xufSk7XG5mdW5jdGlvbiBfZW51bSh2YWx1ZXMsIHBhcmFtcykge1xuICAgIGNvbnN0IGVudHJpZXMgPSBBcnJheS5pc0FycmF5KHZhbHVlcykgPyBPYmplY3QuZnJvbUVudHJpZXModmFsdWVzLm1hcCgodik9PltcbiAgICAgICAgICAgIHYsXG4gICAgICAgICAgICB2XG4gICAgICAgIF0pKSA6IHZhbHVlcztcbiAgICByZXR1cm4gbmV3IFpvZEVudW0oe1xuICAgICAgICB0eXBlOiBcImVudW1cIixcbiAgICAgICAgZW50cmllcyxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IHsgX2VudW0gYXMgZW51bSB9O1xuLyoqIEBkZXByZWNhdGVkIFRoaXMgQVBJIGhhcyBiZWVuIG1lcmdlZCBpbnRvIGB6LmVudW0oKWAuIFVzZSBgei5lbnVtKClgIGluc3RlYWQuXG4gKlxuICogYGBgdHNcbiAqIGVudW0gQ29sb3JzIHsgcmVkLCBncmVlbiwgYmx1ZSB9XG4gKiB6LmVudW0oQ29sb3JzKTtcbiAqIGBgYFxuICovIGV4cG9ydCBmdW5jdGlvbiBuYXRpdmVFbnVtKGVudHJpZXMsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgWm9kRW51bSh7XG4gICAgICAgIHR5cGU6IFwiZW51bVwiLFxuICAgICAgICBlbnRyaWVzLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgY29uc3QgWm9kTGl0ZXJhbCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2RMaXRlcmFsXCIsIChpbnN0LCBkZWYpPT57XG4gICAgY29yZS4kWm9kTGl0ZXJhbC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC52YWx1ZXMgPSBuZXcgU2V0KGRlZi52YWx1ZXMpO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShpbnN0LCBcInZhbHVlXCIsIHtcbiAgICAgICAgZ2V0ICgpIHtcbiAgICAgICAgICAgIGlmIChkZWYudmFsdWVzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIHNjaGVtYSBjb250YWlucyBtdWx0aXBsZSB2YWxpZCBsaXRlcmFsIHZhbHVlcy4gVXNlIGAudmFsdWVzYCBpbnN0ZWFkLlwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBkZWYudmFsdWVzWzBdO1xuICAgICAgICB9XG4gICAgfSk7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBsaXRlcmFsKHZhbHVlLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IFpvZExpdGVyYWwoe1xuICAgICAgICB0eXBlOiBcImxpdGVyYWxcIixcbiAgICAgICAgdmFsdWVzOiBBcnJheS5pc0FycmF5KHZhbHVlKSA/IHZhbHVlIDogW1xuICAgICAgICAgICAgdmFsdWVcbiAgICAgICAgXSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGNvbnN0IFpvZEZpbGUgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kRmlsZVwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZEZpbGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QubWluID0gKHNpemUsIHBhcmFtcyk9Pmluc3QuY2hlY2soY29yZS5fbWluU2l6ZShzaXplLCBwYXJhbXMpKTtcbiAgICBpbnN0Lm1heCA9IChzaXplLCBwYXJhbXMpPT5pbnN0LmNoZWNrKGNvcmUuX21heFNpemUoc2l6ZSwgcGFyYW1zKSk7XG4gICAgaW5zdC5taW1lID0gKHR5cGVzLCBwYXJhbXMpPT5pbnN0LmNoZWNrKGNvcmUuX21pbWUoQXJyYXkuaXNBcnJheSh0eXBlcykgPyB0eXBlcyA6IFtcbiAgICAgICAgICAgIHR5cGVzXG4gICAgICAgIF0sIHBhcmFtcykpO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gZmlsZShwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fZmlsZShab2RGaWxlLCBwYXJhbXMpO1xufVxuZXhwb3J0IGNvbnN0IFpvZFRyYW5zZm9ybSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2RUcmFuc2Zvcm1cIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RUcmFuc2Zvcm0uaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkLCBfY3R4KT0+e1xuICAgICAgICBpZiAoX2N0eC5kaXJlY3Rpb24gPT09IFwiYmFja3dhcmRcIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IGNvcmUuJFpvZEVuY29kZUVycm9yKGluc3QuY29uc3RydWN0b3IubmFtZSk7XG4gICAgICAgIH1cbiAgICAgICAgcGF5bG9hZC5hZGRJc3N1ZSA9IChpc3N1ZSk9PntcbiAgICAgICAgICAgIGlmICh0eXBlb2YgaXNzdWUgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHV0aWwuaXNzdWUoaXNzdWUsIHBheWxvYWQudmFsdWUsIGRlZikpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBmb3IgWm9kIDMgYmFja3dhcmRzIGNvbXBhdGliaWxpdHlcbiAgICAgICAgICAgICAgICBjb25zdCBfaXNzdWUgPSBpc3N1ZTtcbiAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZhdGFsKSBfaXNzdWUuY29udGludWUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBfaXNzdWUuY29kZSA/PyAoX2lzc3VlLmNvZGUgPSBcImN1c3RvbVwiKTtcbiAgICAgICAgICAgICAgICBfaXNzdWUuaW5wdXQgPz8gKF9pc3N1ZS5pbnB1dCA9IHBheWxvYWQudmFsdWUpO1xuICAgICAgICAgICAgICAgIF9pc3N1ZS5pbnN0ID8/IChfaXNzdWUuaW5zdCA9IGluc3QpO1xuICAgICAgICAgICAgICAgIC8vIF9pc3N1ZS5jb250aW51ZSA/Pz0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHV0aWwuaXNzdWUoX2lzc3VlKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IG91dHB1dCA9IGRlZi50cmFuc2Zvcm0ocGF5bG9hZC52YWx1ZSwgcGF5bG9hZCk7XG4gICAgICAgIGlmIChvdXRwdXQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm4gb3V0cHV0LnRoZW4oKG91dHB1dCk9PntcbiAgICAgICAgICAgICAgICBwYXlsb2FkLnZhbHVlID0gb3V0cHV0O1xuICAgICAgICAgICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcGF5bG9hZC52YWx1ZSA9IG91dHB1dDtcbiAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zZm9ybShmbikge1xuICAgIHJldHVybiBuZXcgWm9kVHJhbnNmb3JtKHtcbiAgICAgICAgdHlwZTogXCJ0cmFuc2Zvcm1cIixcbiAgICAgICAgdHJhbnNmb3JtOiBmblxuICAgIH0pO1xufVxuZXhwb3J0IGNvbnN0IFpvZE9wdGlvbmFsID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZE9wdGlvbmFsXCIsIChpbnN0LCBkZWYpPT57XG4gICAgY29yZS4kWm9kT3B0aW9uYWwuaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QudW53cmFwID0gKCk9Pmluc3QuX3pvZC5kZWYuaW5uZXJUeXBlO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gb3B0aW9uYWwoaW5uZXJUeXBlKSB7XG4gICAgcmV0dXJuIG5ldyBab2RPcHRpb25hbCh7XG4gICAgICAgIHR5cGU6IFwib3B0aW9uYWxcIixcbiAgICAgICAgaW5uZXJUeXBlOiBpbm5lclR5cGVcbiAgICB9KTtcbn1cbmV4cG9ydCBjb25zdCBab2ROdWxsYWJsZSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2ROdWxsYWJsZVwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZE51bGxhYmxlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0LnVud3JhcCA9ICgpPT5pbnN0Ll96b2QuZGVmLmlubmVyVHlwZTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIG51bGxhYmxlKGlubmVyVHlwZSkge1xuICAgIHJldHVybiBuZXcgWm9kTnVsbGFibGUoe1xuICAgICAgICB0eXBlOiBcIm51bGxhYmxlXCIsXG4gICAgICAgIGlubmVyVHlwZTogaW5uZXJUeXBlXG4gICAgfSk7XG59XG4vLyBudWxsaXNoXG5leHBvcnQgZnVuY3Rpb24gbnVsbGlzaChpbm5lclR5cGUpIHtcbiAgICByZXR1cm4gb3B0aW9uYWwobnVsbGFibGUoaW5uZXJUeXBlKSk7XG59XG5leHBvcnQgY29uc3QgWm9kRGVmYXVsdCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2REZWZhdWx0XCIsIChpbnN0LCBkZWYpPT57XG4gICAgY29yZS4kWm9kRGVmYXVsdC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC51bndyYXAgPSAoKT0+aW5zdC5fem9kLmRlZi5pbm5lclR5cGU7XG4gICAgaW5zdC5yZW1vdmVEZWZhdWx0ID0gaW5zdC51bndyYXA7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBfZGVmYXVsdChpbm5lclR5cGUsIGRlZmF1bHRWYWx1ZSkge1xuICAgIHJldHVybiBuZXcgWm9kRGVmYXVsdCh7XG4gICAgICAgIHR5cGU6IFwiZGVmYXVsdFwiLFxuICAgICAgICBpbm5lclR5cGU6IGlubmVyVHlwZSxcbiAgICAgICAgZ2V0IGRlZmF1bHRWYWx1ZSAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdHlwZW9mIGRlZmF1bHRWYWx1ZSA9PT0gXCJmdW5jdGlvblwiID8gZGVmYXVsdFZhbHVlKCkgOiB1dGlsLnNoYWxsb3dDbG9uZShkZWZhdWx0VmFsdWUpO1xuICAgICAgICB9XG4gICAgfSk7XG59XG5leHBvcnQgY29uc3QgWm9kUHJlZmF1bHQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kUHJlZmF1bHRcIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RQcmVmYXVsdC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC51bndyYXAgPSAoKT0+aW5zdC5fem9kLmRlZi5pbm5lclR5cGU7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBwcmVmYXVsdChpbm5lclR5cGUsIGRlZmF1bHRWYWx1ZSkge1xuICAgIHJldHVybiBuZXcgWm9kUHJlZmF1bHQoe1xuICAgICAgICB0eXBlOiBcInByZWZhdWx0XCIsXG4gICAgICAgIGlubmVyVHlwZTogaW5uZXJUeXBlLFxuICAgICAgICBnZXQgZGVmYXVsdFZhbHVlICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0eXBlb2YgZGVmYXVsdFZhbHVlID09PSBcImZ1bmN0aW9uXCIgPyBkZWZhdWx0VmFsdWUoKSA6IHV0aWwuc2hhbGxvd0Nsb25lKGRlZmF1bHRWYWx1ZSk7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cbmV4cG9ydCBjb25zdCBab2ROb25PcHRpb25hbCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2ROb25PcHRpb25hbFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZE5vbk9wdGlvbmFsLmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0LnVud3JhcCA9ICgpPT5pbnN0Ll96b2QuZGVmLmlubmVyVHlwZTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIG5vbm9wdGlvbmFsKGlubmVyVHlwZSwgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBab2ROb25PcHRpb25hbCh7XG4gICAgICAgIHR5cGU6IFwibm9ub3B0aW9uYWxcIixcbiAgICAgICAgaW5uZXJUeXBlOiBpbm5lclR5cGUsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBjb25zdCBab2RTdWNjZXNzID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZFN1Y2Nlc3NcIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RTdWNjZXNzLmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0LnVud3JhcCA9ICgpPT5pbnN0Ll96b2QuZGVmLmlubmVyVHlwZTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIHN1Y2Nlc3MoaW5uZXJUeXBlKSB7XG4gICAgcmV0dXJuIG5ldyBab2RTdWNjZXNzKHtcbiAgICAgICAgdHlwZTogXCJzdWNjZXNzXCIsXG4gICAgICAgIGlubmVyVHlwZTogaW5uZXJUeXBlXG4gICAgfSk7XG59XG5leHBvcnQgY29uc3QgWm9kQ2F0Y2ggPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kQ2F0Y2hcIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RDYXRjaC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC51bndyYXAgPSAoKT0+aW5zdC5fem9kLmRlZi5pbm5lclR5cGU7XG4gICAgaW5zdC5yZW1vdmVDYXRjaCA9IGluc3QudW53cmFwO1xufSk7XG5mdW5jdGlvbiBfY2F0Y2goaW5uZXJUeXBlLCBjYXRjaFZhbHVlKSB7XG4gICAgcmV0dXJuIG5ldyBab2RDYXRjaCh7XG4gICAgICAgIHR5cGU6IFwiY2F0Y2hcIixcbiAgICAgICAgaW5uZXJUeXBlOiBpbm5lclR5cGUsXG4gICAgICAgIGNhdGNoVmFsdWU6IHR5cGVvZiBjYXRjaFZhbHVlID09PSBcImZ1bmN0aW9uXCIgPyBjYXRjaFZhbHVlIDogKCk9PmNhdGNoVmFsdWVcbiAgICB9KTtcbn1cbmV4cG9ydCB7IF9jYXRjaCBhcyBjYXRjaCB9O1xuZXhwb3J0IGNvbnN0IFpvZE5hTiA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2ROYU5cIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2ROYU4uaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gbmFuKHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9uYW4oWm9kTmFOLCBwYXJhbXMpO1xufVxuZXhwb3J0IGNvbnN0IFpvZFBpcGUgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kUGlwZVwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZFBpcGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuaW4gPSBkZWYuaW47XG4gICAgaW5zdC5vdXQgPSBkZWYub3V0O1xufSk7XG5leHBvcnQgZnVuY3Rpb24gcGlwZShpbl8sIG91dCkge1xuICAgIHJldHVybiBuZXcgWm9kUGlwZSh7XG4gICAgICAgIHR5cGU6IFwicGlwZVwiLFxuICAgICAgICBpbjogaW5fLFxuICAgICAgICBvdXQ6IG91dFxuICAgIH0pO1xufVxuZXhwb3J0IGNvbnN0IFpvZENvZGVjID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZENvZGVjXCIsIChpbnN0LCBkZWYpPT57XG4gICAgWm9kUGlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgY29yZS4kWm9kQ29kZWMuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gY29kZWMoaW5fLCBvdXQsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgWm9kQ29kZWMoe1xuICAgICAgICB0eXBlOiBcInBpcGVcIixcbiAgICAgICAgaW46IGluXyxcbiAgICAgICAgb3V0OiBvdXQsXG4gICAgICAgIHRyYW5zZm9ybTogcGFyYW1zLmRlY29kZSxcbiAgICAgICAgcmV2ZXJzZVRyYW5zZm9ybTogcGFyYW1zLmVuY29kZVxuICAgIH0pO1xufVxuZXhwb3J0IGNvbnN0IFpvZFJlYWRvbmx5ID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZFJlYWRvbmx5XCIsIChpbnN0LCBkZWYpPT57XG4gICAgY29yZS4kWm9kUmVhZG9ubHkuaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QudW53cmFwID0gKCk9Pmluc3QuX3pvZC5kZWYuaW5uZXJUeXBlO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gcmVhZG9ubHkoaW5uZXJUeXBlKSB7XG4gICAgcmV0dXJuIG5ldyBab2RSZWFkb25seSh7XG4gICAgICAgIHR5cGU6IFwicmVhZG9ubHlcIixcbiAgICAgICAgaW5uZXJUeXBlOiBpbm5lclR5cGVcbiAgICB9KTtcbn1cbmV4cG9ydCBjb25zdCBab2RUZW1wbGF0ZUxpdGVyYWwgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kVGVtcGxhdGVMaXRlcmFsXCIsIChpbnN0LCBkZWYpPT57XG4gICAgY29yZS4kWm9kVGVtcGxhdGVMaXRlcmFsLmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIHRlbXBsYXRlTGl0ZXJhbChwYXJ0cywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBab2RUZW1wbGF0ZUxpdGVyYWwoe1xuICAgICAgICB0eXBlOiBcInRlbXBsYXRlX2xpdGVyYWxcIixcbiAgICAgICAgcGFydHMsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBjb25zdCBab2RMYXp5ID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZExhenlcIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RMYXp5LmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0LnVud3JhcCA9ICgpPT5pbnN0Ll96b2QuZGVmLmdldHRlcigpO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gbGF6eShnZXR0ZXIpIHtcbiAgICByZXR1cm4gbmV3IFpvZExhenkoe1xuICAgICAgICB0eXBlOiBcImxhenlcIixcbiAgICAgICAgZ2V0dGVyOiBnZXR0ZXJcbiAgICB9KTtcbn1cbmV4cG9ydCBjb25zdCBab2RQcm9taXNlID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZFByb21pc2VcIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RQcm9taXNlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0LnVud3JhcCA9ICgpPT5pbnN0Ll96b2QuZGVmLmlubmVyVHlwZTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIHByb21pc2UoaW5uZXJUeXBlKSB7XG4gICAgcmV0dXJuIG5ldyBab2RQcm9taXNlKHtcbiAgICAgICAgdHlwZTogXCJwcm9taXNlXCIsXG4gICAgICAgIGlubmVyVHlwZTogaW5uZXJUeXBlXG4gICAgfSk7XG59XG5leHBvcnQgY29uc3QgWm9kRnVuY3Rpb24gPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kRnVuY3Rpb25cIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RGdW5jdGlvbi5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBfZnVuY3Rpb24ocGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBab2RGdW5jdGlvbih7XG4gICAgICAgIHR5cGU6IFwiZnVuY3Rpb25cIixcbiAgICAgICAgaW5wdXQ6IEFycmF5LmlzQXJyYXkocGFyYW1zPy5pbnB1dCkgPyB0dXBsZShwYXJhbXM/LmlucHV0KSA6IHBhcmFtcz8uaW5wdXQgPz8gYXJyYXkodW5rbm93bigpKSxcbiAgICAgICAgb3V0cHV0OiBwYXJhbXM/Lm91dHB1dCA/PyB1bmtub3duKClcbiAgICB9KTtcbn1cbmV4cG9ydCB7IF9mdW5jdGlvbiBhcyBmdW5jdGlvbiB9O1xuZXhwb3J0IGNvbnN0IFpvZEN1c3RvbSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2RDdXN0b21cIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RDdXN0b20uaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xufSk7XG4vLyBjdXN0b20gY2hlY2tzXG5leHBvcnQgZnVuY3Rpb24gY2hlY2soZm4pIHtcbiAgICBjb25zdCBjaCA9IG5ldyBjb3JlLiRab2RDaGVjayh7XG4gICAgICAgIGNoZWNrOiBcImN1c3RvbVwiXG4gICAgfSk7XG4gICAgY2guX3pvZC5jaGVjayA9IGZuO1xuICAgIHJldHVybiBjaDtcbn1cbmV4cG9ydCBmdW5jdGlvbiBjdXN0b20oZm4sIF9wYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fY3VzdG9tKFpvZEN1c3RvbSwgZm4gPz8gKCgpPT50cnVlKSwgX3BhcmFtcyk7XG59XG5leHBvcnQgZnVuY3Rpb24gcmVmaW5lKGZuLCBfcGFyYW1zID0ge30pIHtcbiAgICByZXR1cm4gY29yZS5fcmVmaW5lKFpvZEN1c3RvbSwgZm4sIF9wYXJhbXMpO1xufVxuLy8gc3VwZXJSZWZpbmVcbmV4cG9ydCBmdW5jdGlvbiBzdXBlclJlZmluZShmbikge1xuICAgIHJldHVybiBjb3JlLl9zdXBlclJlZmluZShmbik7XG59XG5mdW5jdGlvbiBfaW5zdGFuY2VvZihjbHMsIHBhcmFtcyA9IHtcbiAgICBlcnJvcjogYElucHV0IG5vdCBpbnN0YW5jZSBvZiAke2Nscy5uYW1lfWBcbn0pIHtcbiAgICBjb25zdCBpbnN0ID0gbmV3IFpvZEN1c3RvbSh7XG4gICAgICAgIHR5cGU6IFwiY3VzdG9tXCIsXG4gICAgICAgIGNoZWNrOiBcImN1c3RvbVwiLFxuICAgICAgICBmbjogKGRhdGEpPT5kYXRhIGluc3RhbmNlb2YgY2xzLFxuICAgICAgICBhYm9ydDogdHJ1ZSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xuICAgIGluc3QuX3pvZC5iYWcuQ2xhc3MgPSBjbHM7XG4gICAgcmV0dXJuIGluc3Q7XG59XG5leHBvcnQgeyBfaW5zdGFuY2VvZiBhcyBpbnN0YW5jZW9mIH07XG4vLyBzdHJpbmdib29sXG5leHBvcnQgY29uc3Qgc3RyaW5nYm9vbCA9ICguLi5hcmdzKT0+Y29yZS5fc3RyaW5nYm9vbCh7XG4gICAgICAgIENvZGVjOiBab2RDb2RlYyxcbiAgICAgICAgQm9vbGVhbjogWm9kQm9vbGVhbixcbiAgICAgICAgU3RyaW5nOiBab2RTdHJpbmdcbiAgICB9LCAuLi5hcmdzKTtcbmV4cG9ydCBmdW5jdGlvbiBqc29uKHBhcmFtcykge1xuICAgIGNvbnN0IGpzb25TY2hlbWEgPSBsYXp5KCgpPT57XG4gICAgICAgIHJldHVybiB1bmlvbihbXG4gICAgICAgICAgICBzdHJpbmcocGFyYW1zKSxcbiAgICAgICAgICAgIG51bWJlcigpLFxuICAgICAgICAgICAgYm9vbGVhbigpLFxuICAgICAgICAgICAgX251bGwoKSxcbiAgICAgICAgICAgIGFycmF5KGpzb25TY2hlbWEpLFxuICAgICAgICAgICAgcmVjb3JkKHN0cmluZygpLCBqc29uU2NoZW1hKVxuICAgICAgICBdKTtcbiAgICB9KTtcbiAgICByZXR1cm4ganNvblNjaGVtYTtcbn1cbi8vIHByZXByb2Nlc3Ncbi8vIC8qKiBAZGVwcmVjYXRlZCBVc2UgYHoucGlwZSgpYCBhbmQgYHoudHJhbnNmb3JtKClgIGluc3RlYWQuICovXG5leHBvcnQgZnVuY3Rpb24gcHJlcHJvY2Vzcyhmbiwgc2NoZW1hKSB7XG4gICAgcmV0dXJuIHBpcGUodHJhbnNmb3JtKGZuKSwgc2NoZW1hKTtcbn1cbiIsICIvLyBab2QgMyBjb21wYXQgbGF5ZXJcbmltcG9ydCAqIGFzIGNvcmUgZnJvbSBcIi4uL2NvcmUvaW5kZXguanNcIjtcbi8qKiBAZGVwcmVjYXRlZCBVc2UgdGhlIHJhdyBzdHJpbmcgbGl0ZXJhbCBjb2RlcyBpbnN0ZWFkLCBlLmcuIFwiaW52YWxpZF90eXBlXCIuICovIGV4cG9ydCBjb25zdCBab2RJc3N1ZUNvZGUgPSB7XG4gICAgaW52YWxpZF90eXBlOiBcImludmFsaWRfdHlwZVwiLFxuICAgIHRvb19iaWc6IFwidG9vX2JpZ1wiLFxuICAgIHRvb19zbWFsbDogXCJ0b29fc21hbGxcIixcbiAgICBpbnZhbGlkX2Zvcm1hdDogXCJpbnZhbGlkX2Zvcm1hdFwiLFxuICAgIG5vdF9tdWx0aXBsZV9vZjogXCJub3RfbXVsdGlwbGVfb2ZcIixcbiAgICB1bnJlY29nbml6ZWRfa2V5czogXCJ1bnJlY29nbml6ZWRfa2V5c1wiLFxuICAgIGludmFsaWRfdW5pb246IFwiaW52YWxpZF91bmlvblwiLFxuICAgIGludmFsaWRfa2V5OiBcImludmFsaWRfa2V5XCIsXG4gICAgaW52YWxpZF9lbGVtZW50OiBcImludmFsaWRfZWxlbWVudFwiLFxuICAgIGludmFsaWRfdmFsdWU6IFwiaW52YWxpZF92YWx1ZVwiLFxuICAgIGN1c3RvbTogXCJjdXN0b21cIlxufTtcbmV4cG9ydCB7ICRicmFuZCwgY29uZmlnIH0gZnJvbSBcIi4uL2NvcmUvaW5kZXguanNcIjtcbi8qKiBAZGVwcmVjYXRlZCBVc2UgYHouY29uZmlnKHBhcmFtcylgIGluc3RlYWQuICovIGV4cG9ydCBmdW5jdGlvbiBzZXRFcnJvck1hcChtYXApIHtcbiAgICBjb3JlLmNvbmZpZyh7XG4gICAgICAgIGN1c3RvbUVycm9yOiBtYXBcbiAgICB9KTtcbn1cbi8qKiBAZGVwcmVjYXRlZCBVc2UgYHouY29uZmlnKClgIGluc3RlYWQuICovIGV4cG9ydCBmdW5jdGlvbiBnZXRFcnJvck1hcCgpIHtcbiAgICByZXR1cm4gY29yZS5jb25maWcoKS5jdXN0b21FcnJvcjtcbn1cbi8qKiBAZGVwcmVjYXRlZCBEbyBub3QgdXNlLiBTdHViIGRlZmluaXRpb24sIG9ubHkgaW5jbHVkZWQgZm9yIHpvZC10by1qc29uLXNjaGVtYSBjb21wYXRpYmlsaXR5LiAqLyBleHBvcnQgdmFyIFpvZEZpcnN0UGFydHlUeXBlS2luZDtcbihmdW5jdGlvbihab2RGaXJzdFBhcnR5VHlwZUtpbmQpIHt9KShab2RGaXJzdFBhcnR5VHlwZUtpbmQgfHwgKFpvZEZpcnN0UGFydHlUeXBlS2luZCA9IHt9KSk7XG4iLCAiaW1wb3J0ICogYXMgY29yZSBmcm9tIFwiLi4vY29yZS9pbmRleC5qc1wiO1xuaW1wb3J0ICogYXMgc2NoZW1hcyBmcm9tIFwiLi9zY2hlbWFzLmpzXCI7XG5leHBvcnQgZnVuY3Rpb24gc3RyaW5nKHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9jb2VyY2VkU3RyaW5nKHNjaGVtYXMuWm9kU3RyaW5nLCBwYXJhbXMpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIG51bWJlcihwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fY29lcmNlZE51bWJlcihzY2hlbWFzLlpvZE51bWJlciwgcGFyYW1zKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBib29sZWFuKHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9jb2VyY2VkQm9vbGVhbihzY2hlbWFzLlpvZEJvb2xlYW4sIHBhcmFtcyk7XG59XG5leHBvcnQgZnVuY3Rpb24gYmlnaW50KHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9jb2VyY2VkQmlnaW50KHNjaGVtYXMuWm9kQmlnSW50LCBwYXJhbXMpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGRhdGUocGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX2NvZXJjZWREYXRlKHNjaGVtYXMuWm9kRGF0ZSwgcGFyYW1zKTtcbn1cbiIsICJpbXBvcnQgKiBhcyB6IGZyb20gXCIuL2V4dGVybmFsLmpzXCI7XG5leHBvcnQgeyB6IH07XG5leHBvcnQgKiBmcm9tIFwiLi9leHRlcm5hbC5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgejtcbiIsICJpbXBvcnQgejQgZnJvbSBcIi4vY2xhc3NpYy9pbmRleC5qc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2xhc3NpYy9pbmRleC5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgejQ7XG4iLCAiZXhwb3J0IHZhciB1dGlsO1xuKGZ1bmN0aW9uKHV0aWwpIHtcbiAgICB1dGlsLmFzc2VydEVxdWFsID0gKF8pPT57fTtcbiAgICBmdW5jdGlvbiBhc3NlcnRJcyhfYXJnKSB7fVxuICAgIHV0aWwuYXNzZXJ0SXMgPSBhc3NlcnRJcztcbiAgICBmdW5jdGlvbiBhc3NlcnROZXZlcihfeCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgICB9XG4gICAgdXRpbC5hc3NlcnROZXZlciA9IGFzc2VydE5ldmVyO1xuICAgIHV0aWwuYXJyYXlUb0VudW0gPSAoaXRlbXMpPT57XG4gICAgICAgIGNvbnN0IG9iaiA9IHt9O1xuICAgICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgaXRlbXMpe1xuICAgICAgICAgICAgb2JqW2l0ZW1dID0gaXRlbTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb2JqO1xuICAgIH07XG4gICAgdXRpbC5nZXRWYWxpZEVudW1WYWx1ZXMgPSAob2JqKT0+e1xuICAgICAgICBjb25zdCB2YWxpZEtleXMgPSB1dGlsLm9iamVjdEtleXMob2JqKS5maWx0ZXIoKGspPT50eXBlb2Ygb2JqW29ialtrXV0gIT09IFwibnVtYmVyXCIpO1xuICAgICAgICBjb25zdCBmaWx0ZXJlZCA9IHt9O1xuICAgICAgICBmb3IgKGNvbnN0IGsgb2YgdmFsaWRLZXlzKXtcbiAgICAgICAgICAgIGZpbHRlcmVkW2tdID0gb2JqW2tdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB1dGlsLm9iamVjdFZhbHVlcyhmaWx0ZXJlZCk7XG4gICAgfTtcbiAgICB1dGlsLm9iamVjdFZhbHVlcyA9IChvYmopPT57XG4gICAgICAgIHJldHVybiB1dGlsLm9iamVjdEtleXMob2JqKS5tYXAoZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgcmV0dXJuIG9ialtlXTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICB1dGlsLm9iamVjdEtleXMgPSB0eXBlb2YgT2JqZWN0LmtleXMgPT09IFwiZnVuY3Rpb25cIiAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGJhbi9iYW5cbiAgICAgPyAob2JqKT0+T2JqZWN0LmtleXMob2JqKSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGJhbi9iYW5cbiAgICAgOiAob2JqZWN0KT0+e1xuICAgICAgICBjb25zdCBrZXlzID0gW107XG4gICAgICAgIGZvcihjb25zdCBrZXkgaW4gb2JqZWN0KXtcbiAgICAgICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSB7XG4gICAgICAgICAgICAgICAga2V5cy5wdXNoKGtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGtleXM7XG4gICAgfTtcbiAgICB1dGlsLmZpbmQgPSAoYXJyLCBjaGVja2VyKT0+e1xuICAgICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgYXJyKXtcbiAgICAgICAgICAgIGlmIChjaGVja2VyKGl0ZW0pKSByZXR1cm4gaXRlbTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH07XG4gICAgdXRpbC5pc0ludGVnZXIgPSB0eXBlb2YgTnVtYmVyLmlzSW50ZWdlciA9PT0gXCJmdW5jdGlvblwiID8gKHZhbCk9Pk51bWJlci5pc0ludGVnZXIodmFsKSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGJhbi9iYW5cbiAgICAgOiAodmFsKT0+dHlwZW9mIHZhbCA9PT0gXCJudW1iZXJcIiAmJiBOdW1iZXIuaXNGaW5pdGUodmFsKSAmJiBNYXRoLmZsb29yKHZhbCkgPT09IHZhbDtcbiAgICBmdW5jdGlvbiBqb2luVmFsdWVzKGFycmF5LCBzZXBhcmF0b3IgPSBcIiB8IFwiKSB7XG4gICAgICAgIHJldHVybiBhcnJheS5tYXAoKHZhbCk9PnR5cGVvZiB2YWwgPT09IFwic3RyaW5nXCIgPyBgJyR7dmFsfSdgIDogdmFsKS5qb2luKHNlcGFyYXRvcik7XG4gICAgfVxuICAgIHV0aWwuam9pblZhbHVlcyA9IGpvaW5WYWx1ZXM7XG4gICAgdXRpbC5qc29uU3RyaW5naWZ5UmVwbGFjZXIgPSAoXywgdmFsdWUpPT57XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwiYmlnaW50XCIpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZS50b1N0cmluZygpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9O1xufSkodXRpbCB8fCAodXRpbCA9IHt9KSk7XG5leHBvcnQgdmFyIG9iamVjdFV0aWw7XG4oZnVuY3Rpb24ob2JqZWN0VXRpbCkge1xuICAgIG9iamVjdFV0aWwubWVyZ2VTaGFwZXMgPSAoZmlyc3QsIHNlY29uZCk9PntcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLmZpcnN0LFxuICAgICAgICAgICAgLi4uc2Vjb25kXG4gICAgICAgIH07XG4gICAgfTtcbn0pKG9iamVjdFV0aWwgfHwgKG9iamVjdFV0aWwgPSB7fSkpO1xuZXhwb3J0IGNvbnN0IFpvZFBhcnNlZFR5cGUgPSB1dGlsLmFycmF5VG9FbnVtKFtcbiAgICBcInN0cmluZ1wiLFxuICAgIFwibmFuXCIsXG4gICAgXCJudW1iZXJcIixcbiAgICBcImludGVnZXJcIixcbiAgICBcImZsb2F0XCIsXG4gICAgXCJib29sZWFuXCIsXG4gICAgXCJkYXRlXCIsXG4gICAgXCJiaWdpbnRcIixcbiAgICBcInN5bWJvbFwiLFxuICAgIFwiZnVuY3Rpb25cIixcbiAgICBcInVuZGVmaW5lZFwiLFxuICAgIFwibnVsbFwiLFxuICAgIFwiYXJyYXlcIixcbiAgICBcIm9iamVjdFwiLFxuICAgIFwidW5rbm93blwiLFxuICAgIFwicHJvbWlzZVwiLFxuICAgIFwidm9pZFwiLFxuICAgIFwibmV2ZXJcIixcbiAgICBcIm1hcFwiLFxuICAgIFwic2V0XCJcbl0pO1xuZXhwb3J0IGNvbnN0IGdldFBhcnNlZFR5cGUgPSAoZGF0YSk9PntcbiAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgc3dpdGNoKHQpe1xuICAgICAgICBjYXNlIFwidW5kZWZpbmVkXCI6XG4gICAgICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS51bmRlZmluZWQ7XG4gICAgICAgIGNhc2UgXCJzdHJpbmdcIjpcbiAgICAgICAgICAgIHJldHVybiBab2RQYXJzZWRUeXBlLnN0cmluZztcbiAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFpvZFBhcnNlZFR5cGUubmFuIDogWm9kUGFyc2VkVHlwZS5udW1iZXI7XG4gICAgICAgIGNhc2UgXCJib29sZWFuXCI6XG4gICAgICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS5ib29sZWFuO1xuICAgICAgICBjYXNlIFwiZnVuY3Rpb25cIjpcbiAgICAgICAgICAgIHJldHVybiBab2RQYXJzZWRUeXBlLmZ1bmN0aW9uO1xuICAgICAgICBjYXNlIFwiYmlnaW50XCI6XG4gICAgICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS5iaWdpbnQ7XG4gICAgICAgIGNhc2UgXCJzeW1ib2xcIjpcbiAgICAgICAgICAgIHJldHVybiBab2RQYXJzZWRUeXBlLnN5bWJvbDtcbiAgICAgICAgY2FzZSBcIm9iamVjdFwiOlxuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS5hcnJheTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFpvZFBhcnNlZFR5cGUubnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChkYXRhLnRoZW4gJiYgdHlwZW9mIGRhdGEudGhlbiA9PT0gXCJmdW5jdGlvblwiICYmIGRhdGEuY2F0Y2ggJiYgdHlwZW9mIGRhdGEuY2F0Y2ggPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgICAgIHJldHVybiBab2RQYXJzZWRUeXBlLnByb21pc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodHlwZW9mIE1hcCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBkYXRhIGluc3RhbmNlb2YgTWFwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFpvZFBhcnNlZFR5cGUubWFwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGVvZiBTZXQgIT09IFwidW5kZWZpbmVkXCIgJiYgZGF0YSBpbnN0YW5jZW9mIFNldCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBab2RQYXJzZWRUeXBlLnNldDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0eXBlb2YgRGF0ZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBkYXRhIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBab2RQYXJzZWRUeXBlLmRhdGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS5vYmplY3Q7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS51bmtub3duO1xuICAgIH1cbn07XG4iLCAiaW1wb3J0IHsgdXRpbCB9IGZyb20gXCIuL2hlbHBlcnMvdXRpbC5qc1wiO1xuZXhwb3J0IGNvbnN0IFpvZElzc3VlQ29kZSA9IHV0aWwuYXJyYXlUb0VudW0oW1xuICAgIFwiaW52YWxpZF90eXBlXCIsXG4gICAgXCJpbnZhbGlkX2xpdGVyYWxcIixcbiAgICBcImN1c3RvbVwiLFxuICAgIFwiaW52YWxpZF91bmlvblwiLFxuICAgIFwiaW52YWxpZF91bmlvbl9kaXNjcmltaW5hdG9yXCIsXG4gICAgXCJpbnZhbGlkX2VudW1fdmFsdWVcIixcbiAgICBcInVucmVjb2duaXplZF9rZXlzXCIsXG4gICAgXCJpbnZhbGlkX2FyZ3VtZW50c1wiLFxuICAgIFwiaW52YWxpZF9yZXR1cm5fdHlwZVwiLFxuICAgIFwiaW52YWxpZF9kYXRlXCIsXG4gICAgXCJpbnZhbGlkX3N0cmluZ1wiLFxuICAgIFwidG9vX3NtYWxsXCIsXG4gICAgXCJ0b29fYmlnXCIsXG4gICAgXCJpbnZhbGlkX2ludGVyc2VjdGlvbl90eXBlc1wiLFxuICAgIFwibm90X211bHRpcGxlX29mXCIsXG4gICAgXCJub3RfZmluaXRlXCJcbl0pO1xuZXhwb3J0IGNvbnN0IHF1b3RlbGVzc0pzb24gPSAob2JqKT0+e1xuICAgIGNvbnN0IGpzb24gPSBKU09OLnN0cmluZ2lmeShvYmosIG51bGwsIDIpO1xuICAgIHJldHVybiBqc29uLnJlcGxhY2UoL1wiKFteXCJdKylcIjovZywgXCIkMTpcIik7XG59O1xuZXhwb3J0IGNsYXNzIFpvZEVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAgIGdldCBlcnJvcnMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmlzc3VlcztcbiAgICB9XG4gICAgY29uc3RydWN0b3IoaXNzdWVzKXtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5pc3N1ZXMgPSBbXTtcbiAgICAgICAgdGhpcy5hZGRJc3N1ZSA9IChzdWIpPT57XG4gICAgICAgICAgICB0aGlzLmlzc3VlcyA9IFtcbiAgICAgICAgICAgICAgICAuLi50aGlzLmlzc3VlcyxcbiAgICAgICAgICAgICAgICBzdWJcbiAgICAgICAgICAgIF07XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuYWRkSXNzdWVzID0gKHN1YnMgPSBbXSk9PntcbiAgICAgICAgICAgIHRoaXMuaXNzdWVzID0gW1xuICAgICAgICAgICAgICAgIC4uLnRoaXMuaXNzdWVzLFxuICAgICAgICAgICAgICAgIC4uLnN1YnNcbiAgICAgICAgICAgIF07XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGFjdHVhbFByb3RvID0gbmV3LnRhcmdldC5wcm90b3R5cGU7XG4gICAgICAgIGlmIChPYmplY3Quc2V0UHJvdG90eXBlT2YpIHtcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBiYW4vYmFuXG4gICAgICAgICAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgYWN0dWFsUHJvdG8pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fX3Byb3RvX18gPSBhY3R1YWxQcm90bztcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm5hbWUgPSBcIlpvZEVycm9yXCI7XG4gICAgICAgIHRoaXMuaXNzdWVzID0gaXNzdWVzO1xuICAgIH1cbiAgICBmb3JtYXQoX21hcHBlcikge1xuICAgICAgICBjb25zdCBtYXBwZXIgPSBfbWFwcGVyIHx8IGZ1bmN0aW9uKGlzc3VlKSB7XG4gICAgICAgICAgICByZXR1cm4gaXNzdWUubWVzc2FnZTtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgZmllbGRFcnJvcnMgPSB7XG4gICAgICAgICAgICBfZXJyb3JzOiBbXVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBwcm9jZXNzRXJyb3IgPSAoZXJyb3IpPT57XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGlzc3VlIG9mIGVycm9yLmlzc3Vlcyl7XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLmNvZGUgPT09IFwiaW52YWxpZF91bmlvblwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGlzc3VlLnVuaW9uRXJyb3JzLm1hcChwcm9jZXNzRXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNzdWUuY29kZSA9PT0gXCJpbnZhbGlkX3JldHVybl90eXBlXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc0Vycm9yKGlzc3VlLnJldHVyblR5cGVFcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpc3N1ZS5jb2RlID09PSBcImludmFsaWRfYXJndW1lbnRzXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc0Vycm9yKGlzc3VlLmFyZ3VtZW50c0Vycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGlzc3VlLnBhdGgubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGZpZWxkRXJyb3JzLl9lcnJvcnMucHVzaChtYXBwZXIoaXNzdWUpKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBsZXQgY3VyciA9IGZpZWxkRXJyb3JzO1xuICAgICAgICAgICAgICAgICAgICBsZXQgaSA9IDA7XG4gICAgICAgICAgICAgICAgICAgIHdoaWxlKGkgPCBpc3N1ZS5wYXRoLmxlbmd0aCl7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlbCA9IGlzc3VlLnBhdGhbaV07XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0ZXJtaW5hbCA9IGkgPT09IGlzc3VlLnBhdGgubGVuZ3RoIC0gMTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdGVybWluYWwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyW2VsXSA9IGN1cnJbZWxdIHx8IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2Vycm9yczogW11cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgKHR5cGVvZiBlbCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gICBjdXJyW2VsXSA9IGN1cnJbZWxdIHx8IHsgX2Vycm9yczogW10gfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIH0gZWxzZSBpZiAodHlwZW9mIGVsID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyAgIGNvbnN0IGVycm9yQXJyYXk6IGFueSA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gICBlcnJvckFycmF5Ll9lcnJvcnMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgY3VycltlbF0gPSBjdXJyW2VsXSB8fCBlcnJvckFycmF5O1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gfVxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyW2VsXSA9IGN1cnJbZWxdIHx8IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2Vycm9yczogW11cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJbZWxdLl9lcnJvcnMucHVzaChtYXBwZXIoaXNzdWUpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnIgPSBjdXJyW2VsXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGkrKztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgcHJvY2Vzc0Vycm9yKHRoaXMpO1xuICAgICAgICByZXR1cm4gZmllbGRFcnJvcnM7XG4gICAgfVxuICAgIHN0YXRpYyBhc3NlcnQodmFsdWUpIHtcbiAgICAgICAgaWYgKCEodmFsdWUgaW5zdGFuY2VvZiBab2RFcnJvcikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgTm90IGEgWm9kRXJyb3I6ICR7dmFsdWV9YCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgdG9TdHJpbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1lc3NhZ2U7XG4gICAgfVxuICAgIGdldCBtZXNzYWdlKCkge1xuICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodGhpcy5pc3N1ZXMsIHV0aWwuanNvblN0cmluZ2lmeVJlcGxhY2VyLCAyKTtcbiAgICB9XG4gICAgZ2V0IGlzRW1wdHkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmlzc3Vlcy5sZW5ndGggPT09IDA7XG4gICAgfVxuICAgIGZsYXR0ZW4obWFwcGVyID0gKGlzc3VlKT0+aXNzdWUubWVzc2FnZSkge1xuICAgICAgICBjb25zdCBmaWVsZEVycm9ycyA9IHt9O1xuICAgICAgICBjb25zdCBmb3JtRXJyb3JzID0gW107XG4gICAgICAgIGZvciAoY29uc3Qgc3ViIG9mIHRoaXMuaXNzdWVzKXtcbiAgICAgICAgICAgIGlmIChzdWIucGF0aC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZmlyc3RFbCA9IHN1Yi5wYXRoWzBdO1xuICAgICAgICAgICAgICAgIGZpZWxkRXJyb3JzW2ZpcnN0RWxdID0gZmllbGRFcnJvcnNbZmlyc3RFbF0gfHwgW107XG4gICAgICAgICAgICAgICAgZmllbGRFcnJvcnNbZmlyc3RFbF0ucHVzaChtYXBwZXIoc3ViKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGZvcm1FcnJvcnMucHVzaChtYXBwZXIoc3ViKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGZvcm1FcnJvcnMsXG4gICAgICAgICAgICBmaWVsZEVycm9yc1xuICAgICAgICB9O1xuICAgIH1cbiAgICBnZXQgZm9ybUVycm9ycygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZmxhdHRlbigpO1xuICAgIH1cbn1cblpvZEVycm9yLmNyZWF0ZSA9IChpc3N1ZXMpPT57XG4gICAgY29uc3QgZXJyb3IgPSBuZXcgWm9kRXJyb3IoaXNzdWVzKTtcbiAgICByZXR1cm4gZXJyb3I7XG59O1xuIiwgImltcG9ydCB7IFpvZElzc3VlQ29kZSB9IGZyb20gXCIuLi9ab2RFcnJvci5qc1wiO1xuaW1wb3J0IHsgdXRpbCwgWm9kUGFyc2VkVHlwZSB9IGZyb20gXCIuLi9oZWxwZXJzL3V0aWwuanNcIjtcbmNvbnN0IGVycm9yTWFwID0gKGlzc3VlLCBfY3R4KT0+e1xuICAgIGxldCBtZXNzYWdlO1xuICAgIHN3aXRjaChpc3N1ZS5jb2RlKXtcbiAgICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlOlxuICAgICAgICAgICAgaWYgKGlzc3VlLnJlY2VpdmVkID09PSBab2RQYXJzZWRUeXBlLnVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBcIlJlcXVpcmVkXCI7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBgRXhwZWN0ZWQgJHtpc3N1ZS5leHBlY3RlZH0sIHJlY2VpdmVkICR7aXNzdWUucmVjZWl2ZWR9YDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFpvZElzc3VlQ29kZS5pbnZhbGlkX2xpdGVyYWw6XG4gICAgICAgICAgICBtZXNzYWdlID0gYEludmFsaWQgbGl0ZXJhbCB2YWx1ZSwgZXhwZWN0ZWQgJHtKU09OLnN0cmluZ2lmeShpc3N1ZS5leHBlY3RlZCwgdXRpbC5qc29uU3RyaW5naWZ5UmVwbGFjZXIpfWA7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBab2RJc3N1ZUNvZGUudW5yZWNvZ25pemVkX2tleXM6XG4gICAgICAgICAgICBtZXNzYWdlID0gYFVucmVjb2duaXplZCBrZXkocykgaW4gb2JqZWN0OiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIiwgXCIpfWA7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF91bmlvbjpcbiAgICAgICAgICAgIG1lc3NhZ2UgPSBgSW52YWxpZCBpbnB1dGA7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF91bmlvbl9kaXNjcmltaW5hdG9yOlxuICAgICAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkIGRpc2NyaW1pbmF0b3IgdmFsdWUuIEV4cGVjdGVkICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLm9wdGlvbnMpfWA7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF9lbnVtX3ZhbHVlOlxuICAgICAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkIGVudW0gdmFsdWUuIEV4cGVjdGVkICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLm9wdGlvbnMpfSwgcmVjZWl2ZWQgJyR7aXNzdWUucmVjZWl2ZWR9J2A7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF9hcmd1bWVudHM6XG4gICAgICAgICAgICBtZXNzYWdlID0gYEludmFsaWQgZnVuY3Rpb24gYXJndW1lbnRzYDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFpvZElzc3VlQ29kZS5pbnZhbGlkX3JldHVybl90eXBlOlxuICAgICAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkIGZ1bmN0aW9uIHJldHVybiB0eXBlYDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFpvZElzc3VlQ29kZS5pbnZhbGlkX2RhdGU6XG4gICAgICAgICAgICBtZXNzYWdlID0gYEludmFsaWQgZGF0ZWA7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmc6XG4gICAgICAgICAgICBpZiAodHlwZW9mIGlzc3VlLnZhbGlkYXRpb24gPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgICAgICBpZiAoXCJpbmNsdWRlc1wiIGluIGlzc3VlLnZhbGlkYXRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkIGlucHV0OiBtdXN0IGluY2x1ZGUgXCIke2lzc3VlLnZhbGlkYXRpb24uaW5jbHVkZXN9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGlzc3VlLnZhbGlkYXRpb24ucG9zaXRpb24gPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBgJHttZXNzYWdlfSBhdCBvbmUgb3IgbW9yZSBwb3NpdGlvbnMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICR7aXNzdWUudmFsaWRhdGlvbi5wb3NpdGlvbn1gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChcInN0YXJ0c1dpdGhcIiBpbiBpc3N1ZS52YWxpZGF0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBgSW52YWxpZCBpbnB1dDogbXVzdCBzdGFydCB3aXRoIFwiJHtpc3N1ZS52YWxpZGF0aW9uLnN0YXJ0c1dpdGh9XCJgO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoXCJlbmRzV2l0aFwiIGluIGlzc3VlLnZhbGlkYXRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkIGlucHV0OiBtdXN0IGVuZCB3aXRoIFwiJHtpc3N1ZS52YWxpZGF0aW9uLmVuZHNXaXRofVwiYDtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB1dGlsLmFzc2VydE5ldmVyKGlzc3VlLnZhbGlkYXRpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNzdWUudmFsaWRhdGlvbiAhPT0gXCJyZWdleFwiKSB7XG4gICAgICAgICAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkICR7aXNzdWUudmFsaWRhdGlvbn1gO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlID0gXCJJbnZhbGlkXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBab2RJc3N1ZUNvZGUudG9vX3NtYWxsOlxuICAgICAgICAgICAgaWYgKGlzc3VlLnR5cGUgPT09IFwiYXJyYXlcIikgbWVzc2FnZSA9IGBBcnJheSBtdXN0IGNvbnRhaW4gJHtpc3N1ZS5leGFjdCA/IFwiZXhhY3RseVwiIDogaXNzdWUuaW5jbHVzaXZlID8gYGF0IGxlYXN0YCA6IGBtb3JlIHRoYW5gfSAke2lzc3VlLm1pbmltdW19IGVsZW1lbnQocylgO1xuICAgICAgICAgICAgZWxzZSBpZiAoaXNzdWUudHlwZSA9PT0gXCJzdHJpbmdcIikgbWVzc2FnZSA9IGBTdHJpbmcgbXVzdCBjb250YWluICR7aXNzdWUuZXhhY3QgPyBcImV4YWN0bHlcIiA6IGlzc3VlLmluY2x1c2l2ZSA/IGBhdCBsZWFzdGAgOiBgb3ZlcmB9ICR7aXNzdWUubWluaW11bX0gY2hhcmFjdGVyKHMpYDtcbiAgICAgICAgICAgIGVsc2UgaWYgKGlzc3VlLnR5cGUgPT09IFwibnVtYmVyXCIpIG1lc3NhZ2UgPSBgTnVtYmVyIG11c3QgYmUgJHtpc3N1ZS5leGFjdCA/IGBleGFjdGx5IGVxdWFsIHRvIGAgOiBpc3N1ZS5pbmNsdXNpdmUgPyBgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIGAgOiBgZ3JlYXRlciB0aGFuIGB9JHtpc3N1ZS5taW5pbXVtfWA7XG4gICAgICAgICAgICBlbHNlIGlmIChpc3N1ZS50eXBlID09PSBcImJpZ2ludFwiKSBtZXNzYWdlID0gYE51bWJlciBtdXN0IGJlICR7aXNzdWUuZXhhY3QgPyBgZXhhY3RseSBlcXVhbCB0byBgIDogaXNzdWUuaW5jbHVzaXZlID8gYGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBgIDogYGdyZWF0ZXIgdGhhbiBgfSR7aXNzdWUubWluaW11bX1gO1xuICAgICAgICAgICAgZWxzZSBpZiAoaXNzdWUudHlwZSA9PT0gXCJkYXRlXCIpIG1lc3NhZ2UgPSBgRGF0ZSBtdXN0IGJlICR7aXNzdWUuZXhhY3QgPyBgZXhhY3RseSBlcXVhbCB0byBgIDogaXNzdWUuaW5jbHVzaXZlID8gYGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBgIDogYGdyZWF0ZXIgdGhhbiBgfSR7bmV3IERhdGUoTnVtYmVyKGlzc3VlLm1pbmltdW0pKX1gO1xuICAgICAgICAgICAgZWxzZSBtZXNzYWdlID0gXCJJbnZhbGlkIGlucHV0XCI7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBab2RJc3N1ZUNvZGUudG9vX2JpZzpcbiAgICAgICAgICAgIGlmIChpc3N1ZS50eXBlID09PSBcImFycmF5XCIpIG1lc3NhZ2UgPSBgQXJyYXkgbXVzdCBjb250YWluICR7aXNzdWUuZXhhY3QgPyBgZXhhY3RseWAgOiBpc3N1ZS5pbmNsdXNpdmUgPyBgYXQgbW9zdGAgOiBgbGVzcyB0aGFuYH0gJHtpc3N1ZS5tYXhpbXVtfSBlbGVtZW50KHMpYDtcbiAgICAgICAgICAgIGVsc2UgaWYgKGlzc3VlLnR5cGUgPT09IFwic3RyaW5nXCIpIG1lc3NhZ2UgPSBgU3RyaW5nIG11c3QgY29udGFpbiAke2lzc3VlLmV4YWN0ID8gYGV4YWN0bHlgIDogaXNzdWUuaW5jbHVzaXZlID8gYGF0IG1vc3RgIDogYHVuZGVyYH0gJHtpc3N1ZS5tYXhpbXVtfSBjaGFyYWN0ZXIocylgO1xuICAgICAgICAgICAgZWxzZSBpZiAoaXNzdWUudHlwZSA9PT0gXCJudW1iZXJcIikgbWVzc2FnZSA9IGBOdW1iZXIgbXVzdCBiZSAke2lzc3VlLmV4YWN0ID8gYGV4YWN0bHlgIDogaXNzdWUuaW5jbHVzaXZlID8gYGxlc3MgdGhhbiBvciBlcXVhbCB0b2AgOiBgbGVzcyB0aGFuYH0gJHtpc3N1ZS5tYXhpbXVtfWA7XG4gICAgICAgICAgICBlbHNlIGlmIChpc3N1ZS50eXBlID09PSBcImJpZ2ludFwiKSBtZXNzYWdlID0gYEJpZ0ludCBtdXN0IGJlICR7aXNzdWUuZXhhY3QgPyBgZXhhY3RseWAgOiBpc3N1ZS5pbmNsdXNpdmUgPyBgbGVzcyB0aGFuIG9yIGVxdWFsIHRvYCA6IGBsZXNzIHRoYW5gfSAke2lzc3VlLm1heGltdW19YDtcbiAgICAgICAgICAgIGVsc2UgaWYgKGlzc3VlLnR5cGUgPT09IFwiZGF0ZVwiKSBtZXNzYWdlID0gYERhdGUgbXVzdCBiZSAke2lzc3VlLmV4YWN0ID8gYGV4YWN0bHlgIDogaXNzdWUuaW5jbHVzaXZlID8gYHNtYWxsZXIgdGhhbiBvciBlcXVhbCB0b2AgOiBgc21hbGxlciB0aGFuYH0gJHtuZXcgRGF0ZShOdW1iZXIoaXNzdWUubWF4aW11bSkpfWA7XG4gICAgICAgICAgICBlbHNlIG1lc3NhZ2UgPSBcIkludmFsaWQgaW5wdXRcIjtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFpvZElzc3VlQ29kZS5jdXN0b206XG4gICAgICAgICAgICBtZXNzYWdlID0gYEludmFsaWQgaW5wdXRgO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgWm9kSXNzdWVDb2RlLmludmFsaWRfaW50ZXJzZWN0aW9uX3R5cGVzOlxuICAgICAgICAgICAgbWVzc2FnZSA9IGBJbnRlcnNlY3Rpb24gcmVzdWx0cyBjb3VsZCBub3QgYmUgbWVyZ2VkYDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFpvZElzc3VlQ29kZS5ub3RfbXVsdGlwbGVfb2Y6XG4gICAgICAgICAgICBtZXNzYWdlID0gYE51bWJlciBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgJHtpc3N1ZS5tdWx0aXBsZU9mfWA7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBab2RJc3N1ZUNvZGUubm90X2Zpbml0ZTpcbiAgICAgICAgICAgIG1lc3NhZ2UgPSBcIk51bWJlciBtdXN0IGJlIGZpbml0ZVwiO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBtZXNzYWdlID0gX2N0eC5kZWZhdWx0RXJyb3I7XG4gICAgICAgICAgICB1dGlsLmFzc2VydE5ldmVyKGlzc3VlKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbWVzc2FnZVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZXJyb3JNYXA7XG4iLCAiaW1wb3J0IGRlZmF1bHRFcnJvck1hcCBmcm9tIFwiLi9sb2NhbGVzL2VuLmpzXCI7XG5sZXQgb3ZlcnJpZGVFcnJvck1hcCA9IGRlZmF1bHRFcnJvck1hcDtcbmV4cG9ydCB7IGRlZmF1bHRFcnJvck1hcCB9O1xuZXhwb3J0IGZ1bmN0aW9uIHNldEVycm9yTWFwKG1hcCkge1xuICAgIG92ZXJyaWRlRXJyb3JNYXAgPSBtYXA7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2V0RXJyb3JNYXAoKSB7XG4gICAgcmV0dXJuIG92ZXJyaWRlRXJyb3JNYXA7XG59XG4iLCAiaW1wb3J0IHsgZ2V0RXJyb3JNYXAgfSBmcm9tIFwiLi4vZXJyb3JzLmpzXCI7XG5pbXBvcnQgZGVmYXVsdEVycm9yTWFwIGZyb20gXCIuLi9sb2NhbGVzL2VuLmpzXCI7XG5leHBvcnQgY29uc3QgbWFrZUlzc3VlID0gKHBhcmFtcyk9PntcbiAgICBjb25zdCB7IGRhdGEsIHBhdGgsIGVycm9yTWFwcywgaXNzdWVEYXRhIH0gPSBwYXJhbXM7XG4gICAgY29uc3QgZnVsbFBhdGggPSBbXG4gICAgICAgIC4uLnBhdGgsXG4gICAgICAgIC4uLmlzc3VlRGF0YS5wYXRoIHx8IFtdXG4gICAgXTtcbiAgICBjb25zdCBmdWxsSXNzdWUgPSB7XG4gICAgICAgIC4uLmlzc3VlRGF0YSxcbiAgICAgICAgcGF0aDogZnVsbFBhdGhcbiAgICB9O1xuICAgIGlmIChpc3N1ZURhdGEubWVzc2FnZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi5pc3N1ZURhdGEsXG4gICAgICAgICAgICBwYXRoOiBmdWxsUGF0aCxcbiAgICAgICAgICAgIG1lc3NhZ2U6IGlzc3VlRGF0YS5tZXNzYWdlXG4gICAgICAgIH07XG4gICAgfVxuICAgIGxldCBlcnJvck1lc3NhZ2UgPSBcIlwiO1xuICAgIGNvbnN0IG1hcHMgPSBlcnJvck1hcHMuZmlsdGVyKChtKT0+ISFtKS5zbGljZSgpLnJldmVyc2UoKTtcbiAgICBmb3IgKGNvbnN0IG1hcCBvZiBtYXBzKXtcbiAgICAgICAgZXJyb3JNZXNzYWdlID0gbWFwKGZ1bGxJc3N1ZSwge1xuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgIGRlZmF1bHRFcnJvcjogZXJyb3JNZXNzYWdlXG4gICAgICAgIH0pLm1lc3NhZ2U7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIC4uLmlzc3VlRGF0YSxcbiAgICAgICAgcGF0aDogZnVsbFBhdGgsXG4gICAgICAgIG1lc3NhZ2U6IGVycm9yTWVzc2FnZVxuICAgIH07XG59O1xuZXhwb3J0IGNvbnN0IEVNUFRZX1BBVEggPSBbXTtcbmV4cG9ydCBmdW5jdGlvbiBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIGlzc3VlRGF0YSkge1xuICAgIGNvbnN0IG92ZXJyaWRlTWFwID0gZ2V0RXJyb3JNYXAoKTtcbiAgICBjb25zdCBpc3N1ZSA9IG1ha2VJc3N1ZSh7XG4gICAgICAgIGlzc3VlRGF0YTogaXNzdWVEYXRhLFxuICAgICAgICBkYXRhOiBjdHguZGF0YSxcbiAgICAgICAgcGF0aDogY3R4LnBhdGgsXG4gICAgICAgIGVycm9yTWFwczogW1xuICAgICAgICAgICAgY3R4LmNvbW1vbi5jb250ZXh0dWFsRXJyb3JNYXAsXG4gICAgICAgICAgICBjdHguc2NoZW1hRXJyb3JNYXAsXG4gICAgICAgICAgICBvdmVycmlkZU1hcCxcbiAgICAgICAgICAgIG92ZXJyaWRlTWFwID09PSBkZWZhdWx0RXJyb3JNYXAgPyB1bmRlZmluZWQgOiBkZWZhdWx0RXJyb3JNYXBcbiAgICAgICAgXS5maWx0ZXIoKHgpPT4hIXgpXG4gICAgfSk7XG4gICAgY3R4LmNvbW1vbi5pc3N1ZXMucHVzaChpc3N1ZSk7XG59XG5leHBvcnQgY2xhc3MgUGFyc2VTdGF0dXMge1xuICAgIGNvbnN0cnVjdG9yKCl7XG4gICAgICAgIHRoaXMudmFsdWUgPSBcInZhbGlkXCI7XG4gICAgfVxuICAgIGRpcnR5KCkge1xuICAgICAgICBpZiAodGhpcy52YWx1ZSA9PT0gXCJ2YWxpZFwiKSB0aGlzLnZhbHVlID0gXCJkaXJ0eVwiO1xuICAgIH1cbiAgICBhYm9ydCgpIHtcbiAgICAgICAgaWYgKHRoaXMudmFsdWUgIT09IFwiYWJvcnRlZFwiKSB0aGlzLnZhbHVlID0gXCJhYm9ydGVkXCI7XG4gICAgfVxuICAgIHN0YXRpYyBtZXJnZUFycmF5KHN0YXR1cywgcmVzdWx0cykge1xuICAgICAgICBjb25zdCBhcnJheVZhbHVlID0gW107XG4gICAgICAgIGZvciAoY29uc3QgcyBvZiByZXN1bHRzKXtcbiAgICAgICAgICAgIGlmIChzLnN0YXR1cyA9PT0gXCJhYm9ydGVkXCIpIHJldHVybiBJTlZBTElEO1xuICAgICAgICAgICAgaWYgKHMuc3RhdHVzID09PSBcImRpcnR5XCIpIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgYXJyYXlWYWx1ZS5wdXNoKHMudmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdGF0dXM6IHN0YXR1cy52YWx1ZSxcbiAgICAgICAgICAgIHZhbHVlOiBhcnJheVZhbHVlXG4gICAgICAgIH07XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyBtZXJnZU9iamVjdEFzeW5jKHN0YXR1cywgcGFpcnMpIHtcbiAgICAgICAgY29uc3Qgc3luY1BhaXJzID0gW107XG4gICAgICAgIGZvciAoY29uc3QgcGFpciBvZiBwYWlycyl7XG4gICAgICAgICAgICBjb25zdCBrZXkgPSBhd2FpdCBwYWlyLmtleTtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gYXdhaXQgcGFpci52YWx1ZTtcbiAgICAgICAgICAgIHN5bmNQYWlycy5wdXNoKHtcbiAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgdmFsdWVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBQYXJzZVN0YXR1cy5tZXJnZU9iamVjdFN5bmMoc3RhdHVzLCBzeW5jUGFpcnMpO1xuICAgIH1cbiAgICBzdGF0aWMgbWVyZ2VPYmplY3RTeW5jKHN0YXR1cywgcGFpcnMpIHtcbiAgICAgICAgY29uc3QgZmluYWxPYmplY3QgPSB7fTtcbiAgICAgICAgZm9yIChjb25zdCBwYWlyIG9mIHBhaXJzKXtcbiAgICAgICAgICAgIGNvbnN0IHsga2V5LCB2YWx1ZSB9ID0gcGFpcjtcbiAgICAgICAgICAgIGlmIChrZXkuc3RhdHVzID09PSBcImFib3J0ZWRcIikgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgICAgICBpZiAodmFsdWUuc3RhdHVzID09PSBcImFib3J0ZWRcIikgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgICAgICBpZiAoa2V5LnN0YXR1cyA9PT0gXCJkaXJ0eVwiKSBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgIGlmICh2YWx1ZS5zdGF0dXMgPT09IFwiZGlydHlcIikgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICBpZiAoa2V5LnZhbHVlICE9PSBcIl9fcHJvdG9fX1wiICYmICh0eXBlb2YgdmFsdWUudmFsdWUgIT09IFwidW5kZWZpbmVkXCIgfHwgcGFpci5hbHdheXNTZXQpKSB7XG4gICAgICAgICAgICAgICAgZmluYWxPYmplY3Rba2V5LnZhbHVlXSA9IHZhbHVlLnZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdGF0dXM6IHN0YXR1cy52YWx1ZSxcbiAgICAgICAgICAgIHZhbHVlOiBmaW5hbE9iamVjdFxuICAgICAgICB9O1xuICAgIH1cbn1cbmV4cG9ydCBjb25zdCBJTlZBTElEID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgc3RhdHVzOiBcImFib3J0ZWRcIlxufSk7XG5leHBvcnQgY29uc3QgRElSVFkgPSAodmFsdWUpPT4oe1xuICAgICAgICBzdGF0dXM6IFwiZGlydHlcIixcbiAgICAgICAgdmFsdWVcbiAgICB9KTtcbmV4cG9ydCBjb25zdCBPSyA9ICh2YWx1ZSk9Pih7XG4gICAgICAgIHN0YXR1czogXCJ2YWxpZFwiLFxuICAgICAgICB2YWx1ZVxuICAgIH0pO1xuZXhwb3J0IGNvbnN0IGlzQWJvcnRlZCA9ICh4KT0+eC5zdGF0dXMgPT09IFwiYWJvcnRlZFwiO1xuZXhwb3J0IGNvbnN0IGlzRGlydHkgPSAoeCk9Pnguc3RhdHVzID09PSBcImRpcnR5XCI7XG5leHBvcnQgY29uc3QgaXNWYWxpZCA9ICh4KT0+eC5zdGF0dXMgPT09IFwidmFsaWRcIjtcbmV4cG9ydCBjb25zdCBpc0FzeW5jID0gKHgpPT50eXBlb2YgUHJvbWlzZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiB4IGluc3RhbmNlb2YgUHJvbWlzZTtcbiIsICJleHBvcnQgdmFyIGVycm9yVXRpbDtcbihmdW5jdGlvbihlcnJvclV0aWwpIHtcbiAgICBlcnJvclV0aWwuZXJyVG9PYmogPSAobWVzc2FnZSk9PnR5cGVvZiBtZXNzYWdlID09PSBcInN0cmluZ1wiID8ge1xuICAgICAgICAgICAgbWVzc2FnZVxuICAgICAgICB9IDogbWVzc2FnZSB8fCB7fTtcbiAgICAvLyBiaW9tZS1pZ25vcmUgbGludDpcbiAgICBlcnJvclV0aWwudG9TdHJpbmcgPSAobWVzc2FnZSk9PnR5cGVvZiBtZXNzYWdlID09PSBcInN0cmluZ1wiID8gbWVzc2FnZSA6IG1lc3NhZ2U/Lm1lc3NhZ2U7XG59KShlcnJvclV0aWwgfHwgKGVycm9yVXRpbCA9IHt9KSk7XG4iLCAiaW1wb3J0IHsgWm9kRXJyb3IsIFpvZElzc3VlQ29kZSB9IGZyb20gXCIuL1pvZEVycm9yLmpzXCI7XG5pbXBvcnQgeyBkZWZhdWx0RXJyb3JNYXAsIGdldEVycm9yTWFwIH0gZnJvbSBcIi4vZXJyb3JzLmpzXCI7XG5pbXBvcnQgeyBlcnJvclV0aWwgfSBmcm9tIFwiLi9oZWxwZXJzL2Vycm9yVXRpbC5qc1wiO1xuaW1wb3J0IHsgRElSVFksIElOVkFMSUQsIE9LLCBQYXJzZVN0YXR1cywgYWRkSXNzdWVUb0NvbnRleHQsIGlzQWJvcnRlZCwgaXNBc3luYywgaXNEaXJ0eSwgaXNWYWxpZCwgbWFrZUlzc3VlIH0gZnJvbSBcIi4vaGVscGVycy9wYXJzZVV0aWwuanNcIjtcbmltcG9ydCB7IHV0aWwsIFpvZFBhcnNlZFR5cGUsIGdldFBhcnNlZFR5cGUgfSBmcm9tIFwiLi9oZWxwZXJzL3V0aWwuanNcIjtcbmNsYXNzIFBhcnNlSW5wdXRMYXp5UGF0aCB7XG4gICAgY29uc3RydWN0b3IocGFyZW50LCB2YWx1ZSwgcGF0aCwga2V5KXtcbiAgICAgICAgdGhpcy5fY2FjaGVkUGF0aCA9IFtdO1xuICAgICAgICB0aGlzLnBhcmVudCA9IHBhcmVudDtcbiAgICAgICAgdGhpcy5kYXRhID0gdmFsdWU7XG4gICAgICAgIHRoaXMuX3BhdGggPSBwYXRoO1xuICAgICAgICB0aGlzLl9rZXkgPSBrZXk7XG4gICAgfVxuICAgIGdldCBwYXRoKCkge1xuICAgICAgICBpZiAoIXRoaXMuX2NhY2hlZFBhdGgubGVuZ3RoKSB7XG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh0aGlzLl9rZXkpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fY2FjaGVkUGF0aC5wdXNoKC4uLnRoaXMuX3BhdGgsIC4uLnRoaXMuX2tleSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX2NhY2hlZFBhdGgucHVzaCguLi50aGlzLl9wYXRoLCB0aGlzLl9rZXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9jYWNoZWRQYXRoO1xuICAgIH1cbn1cbmNvbnN0IGhhbmRsZVJlc3VsdCA9IChjdHgsIHJlc3VsdCk9PntcbiAgICBpZiAoaXNWYWxpZChyZXN1bHQpKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgZGF0YTogcmVzdWx0LnZhbHVlXG4gICAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKCFjdHguY29tbW9uLmlzc3Vlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlZhbGlkYXRpb24gZmFpbGVkIGJ1dCBubyBpc3N1ZXMgZGV0ZWN0ZWQuXCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgIGdldCBlcnJvciAoKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2Vycm9yKSByZXR1cm4gdGhpcy5fZXJyb3I7XG4gICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgWm9kRXJyb3IoY3R4LmNvbW1vbi5pc3N1ZXMpO1xuICAgICAgICAgICAgICAgIHRoaXMuX2Vycm9yID0gZXJyb3I7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2Vycm9yO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cbn07XG5mdW5jdGlvbiBwcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykge1xuICAgIGlmICghcGFyYW1zKSByZXR1cm4ge307XG4gICAgY29uc3QgeyBlcnJvck1hcCwgaW52YWxpZF90eXBlX2Vycm9yLCByZXF1aXJlZF9lcnJvciwgZGVzY3JpcHRpb24gfSA9IHBhcmFtcztcbiAgICBpZiAoZXJyb3JNYXAgJiYgKGludmFsaWRfdHlwZV9lcnJvciB8fCByZXF1aXJlZF9lcnJvcikpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW4ndCB1c2UgXCJpbnZhbGlkX3R5cGVfZXJyb3JcIiBvciBcInJlcXVpcmVkX2Vycm9yXCIgaW4gY29uanVuY3Rpb24gd2l0aCBjdXN0b20gZXJyb3IgbWFwLmApO1xuICAgIH1cbiAgICBpZiAoZXJyb3JNYXApIHJldHVybiB7XG4gICAgICAgIGVycm9yTWFwOiBlcnJvck1hcCxcbiAgICAgICAgZGVzY3JpcHRpb25cbiAgICB9O1xuICAgIGNvbnN0IGN1c3RvbU1hcCA9IChpc3MsIGN0eCk9PntcbiAgICAgICAgY29uc3QgeyBtZXNzYWdlIH0gPSBwYXJhbXM7XG4gICAgICAgIGlmIChpc3MuY29kZSA9PT0gXCJpbnZhbGlkX2VudW1fdmFsdWVcIikge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBtZXNzYWdlID8/IGN0eC5kZWZhdWx0RXJyb3JcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBjdHguZGF0YSA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBtZXNzYWdlID8/IHJlcXVpcmVkX2Vycm9yID8/IGN0eC5kZWZhdWx0RXJyb3JcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzcy5jb2RlICE9PSBcImludmFsaWRfdHlwZVwiKSByZXR1cm4ge1xuICAgICAgICAgICAgbWVzc2FnZTogY3R4LmRlZmF1bHRFcnJvclxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbWVzc2FnZTogbWVzc2FnZSA/PyBpbnZhbGlkX3R5cGVfZXJyb3IgPz8gY3R4LmRlZmF1bHRFcnJvclxuICAgICAgICB9O1xuICAgIH07XG4gICAgcmV0dXJuIHtcbiAgICAgICAgZXJyb3JNYXA6IGN1c3RvbU1hcCxcbiAgICAgICAgZGVzY3JpcHRpb25cbiAgICB9O1xufVxuZXhwb3J0IGNsYXNzIFpvZFR5cGUge1xuICAgIGdldCBkZXNjcmlwdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi5kZXNjcmlwdGlvbjtcbiAgICB9XG4gICAgX2dldFR5cGUoaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIGdldFBhcnNlZFR5cGUoaW5wdXQuZGF0YSk7XG4gICAgfVxuICAgIF9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KSB7XG4gICAgICAgIHJldHVybiBjdHggfHwge1xuICAgICAgICAgICAgY29tbW9uOiBpbnB1dC5wYXJlbnQuY29tbW9uLFxuICAgICAgICAgICAgZGF0YTogaW5wdXQuZGF0YSxcbiAgICAgICAgICAgIHBhcnNlZFR5cGU6IGdldFBhcnNlZFR5cGUoaW5wdXQuZGF0YSksXG4gICAgICAgICAgICBzY2hlbWFFcnJvck1hcDogdGhpcy5fZGVmLmVycm9yTWFwLFxuICAgICAgICAgICAgcGF0aDogaW5wdXQucGF0aCxcbiAgICAgICAgICAgIHBhcmVudDogaW5wdXQucGFyZW50XG4gICAgICAgIH07XG4gICAgfVxuICAgIF9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN0YXR1czogbmV3IFBhcnNlU3RhdHVzKCksXG4gICAgICAgICAgICBjdHg6IHtcbiAgICAgICAgICAgICAgICBjb21tb246IGlucHV0LnBhcmVudC5jb21tb24sXG4gICAgICAgICAgICAgICAgZGF0YTogaW5wdXQuZGF0YSxcbiAgICAgICAgICAgICAgICBwYXJzZWRUeXBlOiBnZXRQYXJzZWRUeXBlKGlucHV0LmRhdGEpLFxuICAgICAgICAgICAgICAgIHNjaGVtYUVycm9yTWFwOiB0aGlzLl9kZWYuZXJyb3JNYXAsXG4gICAgICAgICAgICAgICAgcGF0aDogaW5wdXQucGF0aCxcbiAgICAgICAgICAgICAgICBwYXJlbnQ6IGlucHV0LnBhcmVudFxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cbiAgICBfcGFyc2VTeW5jKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuX3BhcnNlKGlucHV0KTtcbiAgICAgICAgaWYgKGlzQXN5bmMocmVzdWx0KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU3luY2hyb25vdXMgcGFyc2UgZW5jb3VudGVyZWQgcHJvbWlzZS5cIik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgX3BhcnNlQXN5bmMoaW5wdXQpIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5fcGFyc2UoaW5wdXQpO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlc3VsdCk7XG4gICAgfVxuICAgIHBhcnNlKGRhdGEsIHBhcmFtcykge1xuICAgICAgICBjb25zdCByZXN1bHQgPSB0aGlzLnNhZmVQYXJzZShkYXRhLCBwYXJhbXMpO1xuICAgICAgICBpZiAocmVzdWx0LnN1Y2Nlc3MpIHJldHVybiByZXN1bHQuZGF0YTtcbiAgICAgICAgdGhyb3cgcmVzdWx0LmVycm9yO1xuICAgIH1cbiAgICBzYWZlUGFyc2UoZGF0YSwgcGFyYW1zKSB7XG4gICAgICAgIGNvbnN0IGN0eCA9IHtcbiAgICAgICAgICAgIGNvbW1vbjoge1xuICAgICAgICAgICAgICAgIGlzc3VlczogW10sXG4gICAgICAgICAgICAgICAgYXN5bmM6IHBhcmFtcz8uYXN5bmMgPz8gZmFsc2UsXG4gICAgICAgICAgICAgICAgY29udGV4dHVhbEVycm9yTWFwOiBwYXJhbXM/LmVycm9yTWFwXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcGF0aDogcGFyYW1zPy5wYXRoIHx8IFtdLFxuICAgICAgICAgICAgc2NoZW1hRXJyb3JNYXA6IHRoaXMuX2RlZi5lcnJvck1hcCxcbiAgICAgICAgICAgIHBhcmVudDogbnVsbCxcbiAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICBwYXJzZWRUeXBlOiBnZXRQYXJzZWRUeXBlKGRhdGEpXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuX3BhcnNlU3luYyh7XG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgcGF0aDogY3R4LnBhdGgsXG4gICAgICAgICAgICBwYXJlbnQ6IGN0eFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGhhbmRsZVJlc3VsdChjdHgsIHJlc3VsdCk7XG4gICAgfVxuICAgIFwifnZhbGlkYXRlXCIoZGF0YSkge1xuICAgICAgICBjb25zdCBjdHggPSB7XG4gICAgICAgICAgICBjb21tb246IHtcbiAgICAgICAgICAgICAgICBpc3N1ZXM6IFtdLFxuICAgICAgICAgICAgICAgIGFzeW5jOiAhIXRoaXNbXCJ+c3RhbmRhcmRcIl0uYXN5bmNcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBwYXRoOiBbXSxcbiAgICAgICAgICAgIHNjaGVtYUVycm9yTWFwOiB0aGlzLl9kZWYuZXJyb3JNYXAsXG4gICAgICAgICAgICBwYXJlbnQ6IG51bGwsXG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgcGFyc2VkVHlwZTogZ2V0UGFyc2VkVHlwZShkYXRhKVxuICAgICAgICB9O1xuICAgICAgICBpZiAoIXRoaXNbXCJ+c3RhbmRhcmRcIl0uYXN5bmMpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5fcGFyc2VTeW5jKHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgICAgICAgICAgcGF0aDogW10sXG4gICAgICAgICAgICAgICAgICAgIHBhcmVudDogY3R4XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlzVmFsaWQocmVzdWx0KSA/IHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHJlc3VsdC52YWx1ZVxuICAgICAgICAgICAgICAgIH0gOiB7XG4gICAgICAgICAgICAgICAgICAgIGlzc3VlczogY3R4LmNvbW1vbi5pc3N1ZXNcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgaWYgKGVycj8ubWVzc2FnZT8udG9Mb3dlckNhc2UoKT8uaW5jbHVkZXMoXCJlbmNvdW50ZXJlZFwiKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzW1wifnN0YW5kYXJkXCJdLmFzeW5jID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY3R4LmNvbW1vbiA9IHtcbiAgICAgICAgICAgICAgICAgICAgaXNzdWVzOiBbXSxcbiAgICAgICAgICAgICAgICAgICAgYXN5bmM6IHRydWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJzZUFzeW5jKHtcbiAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICBwYXRoOiBbXSxcbiAgICAgICAgICAgIHBhcmVudDogY3R4XG4gICAgICAgIH0pLnRoZW4oKHJlc3VsdCk9PmlzVmFsaWQocmVzdWx0KSA/IHtcbiAgICAgICAgICAgICAgICB2YWx1ZTogcmVzdWx0LnZhbHVlXG4gICAgICAgICAgICB9IDoge1xuICAgICAgICAgICAgICAgIGlzc3VlczogY3R4LmNvbW1vbi5pc3N1ZXNcbiAgICAgICAgICAgIH0pO1xuICAgIH1cbiAgICBhc3luYyBwYXJzZUFzeW5jKGRhdGEsIHBhcmFtcykge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnNhZmVQYXJzZUFzeW5jKGRhdGEsIHBhcmFtcyk7XG4gICAgICAgIGlmIChyZXN1bHQuc3VjY2VzcykgcmV0dXJuIHJlc3VsdC5kYXRhO1xuICAgICAgICB0aHJvdyByZXN1bHQuZXJyb3I7XG4gICAgfVxuICAgIGFzeW5jIHNhZmVQYXJzZUFzeW5jKGRhdGEsIHBhcmFtcykge1xuICAgICAgICBjb25zdCBjdHggPSB7XG4gICAgICAgICAgICBjb21tb246IHtcbiAgICAgICAgICAgICAgICBpc3N1ZXM6IFtdLFxuICAgICAgICAgICAgICAgIGNvbnRleHR1YWxFcnJvck1hcDogcGFyYW1zPy5lcnJvck1hcCxcbiAgICAgICAgICAgICAgICBhc3luYzogdHJ1ZVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHBhdGg6IHBhcmFtcz8ucGF0aCB8fCBbXSxcbiAgICAgICAgICAgIHNjaGVtYUVycm9yTWFwOiB0aGlzLl9kZWYuZXJyb3JNYXAsXG4gICAgICAgICAgICBwYXJlbnQ6IG51bGwsXG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgcGFyc2VkVHlwZTogZ2V0UGFyc2VkVHlwZShkYXRhKVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBtYXliZUFzeW5jUmVzdWx0ID0gdGhpcy5fcGFyc2Uoe1xuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgcGFyZW50OiBjdHhcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IChpc0FzeW5jKG1heWJlQXN5bmNSZXN1bHQpID8gbWF5YmVBc3luY1Jlc3VsdCA6IFByb21pc2UucmVzb2x2ZShtYXliZUFzeW5jUmVzdWx0KSk7XG4gICAgICAgIHJldHVybiBoYW5kbGVSZXN1bHQoY3R4LCByZXN1bHQpO1xuICAgIH1cbiAgICByZWZpbmUoY2hlY2ssIG1lc3NhZ2UpIHtcbiAgICAgICAgY29uc3QgZ2V0SXNzdWVQcm9wZXJ0aWVzID0gKHZhbCk9PntcbiAgICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSA9PT0gXCJzdHJpbmdcIiB8fCB0eXBlb2YgbWVzc2FnZSA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgbWVzc2FnZSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2UodmFsKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB0aGlzLl9yZWZpbmVtZW50KCh2YWwsIGN0eCk9PntcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGNoZWNrKHZhbCk7XG4gICAgICAgICAgICBjb25zdCBzZXRFcnJvciA9ICgpPT5jdHguYWRkSXNzdWUoe1xuICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuY3VzdG9tLFxuICAgICAgICAgICAgICAgICAgICAuLi5nZXRJc3N1ZVByb3BlcnRpZXModmFsKVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBQcm9taXNlICE9PSBcInVuZGVmaW5lZFwiICYmIHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0LnRoZW4oKGRhdGEpPT57XG4gICAgICAgICAgICAgICAgICAgIGlmICghZGF0YSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0RXJyb3IoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXJlc3VsdCkge1xuICAgICAgICAgICAgICAgIHNldEVycm9yKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJlZmluZW1lbnQoY2hlY2ssIHJlZmluZW1lbnREYXRhKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9yZWZpbmVtZW50KCh2YWwsIGN0eCk9PntcbiAgICAgICAgICAgIGlmICghY2hlY2sodmFsKSkge1xuICAgICAgICAgICAgICAgIGN0eC5hZGRJc3N1ZSh0eXBlb2YgcmVmaW5lbWVudERhdGEgPT09IFwiZnVuY3Rpb25cIiA/IHJlZmluZW1lbnREYXRhKHZhbCwgY3R4KSA6IHJlZmluZW1lbnREYXRhKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgX3JlZmluZW1lbnQocmVmaW5lbWVudCkge1xuICAgICAgICByZXR1cm4gbmV3IFpvZEVmZmVjdHMoe1xuICAgICAgICAgICAgc2NoZW1hOiB0aGlzLFxuICAgICAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RFZmZlY3RzLFxuICAgICAgICAgICAgZWZmZWN0OiB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJyZWZpbmVtZW50XCIsXG4gICAgICAgICAgICAgICAgcmVmaW5lbWVudFxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgc3VwZXJSZWZpbmUocmVmaW5lbWVudCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcmVmaW5lbWVudChyZWZpbmVtZW50KTtcbiAgICB9XG4gICAgY29uc3RydWN0b3IoZGVmKXtcbiAgICAgICAgLyoqIEFsaWFzIG9mIHNhZmVQYXJzZUFzeW5jICovIHRoaXMuc3BhID0gdGhpcy5zYWZlUGFyc2VBc3luYztcbiAgICAgICAgdGhpcy5fZGVmID0gZGVmO1xuICAgICAgICB0aGlzLnBhcnNlID0gdGhpcy5wYXJzZS5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLnNhZmVQYXJzZSA9IHRoaXMuc2FmZVBhcnNlLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMucGFyc2VBc3luYyA9IHRoaXMucGFyc2VBc3luYy5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLnNhZmVQYXJzZUFzeW5jID0gdGhpcy5zYWZlUGFyc2VBc3luYy5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLnNwYSA9IHRoaXMuc3BhLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMucmVmaW5lID0gdGhpcy5yZWZpbmUuYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5yZWZpbmVtZW50ID0gdGhpcy5yZWZpbmVtZW50LmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMuc3VwZXJSZWZpbmUgPSB0aGlzLnN1cGVyUmVmaW5lLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMub3B0aW9uYWwgPSB0aGlzLm9wdGlvbmFsLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMubnVsbGFibGUgPSB0aGlzLm51bGxhYmxlLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMubnVsbGlzaCA9IHRoaXMubnVsbGlzaC5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLmFycmF5ID0gdGhpcy5hcnJheS5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLnByb21pc2UgPSB0aGlzLnByb21pc2UuYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5vciA9IHRoaXMub3IuYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5hbmQgPSB0aGlzLmFuZC5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLnRyYW5zZm9ybSA9IHRoaXMudHJhbnNmb3JtLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMuYnJhbmQgPSB0aGlzLmJyYW5kLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMuZGVmYXVsdCA9IHRoaXMuZGVmYXVsdC5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLmNhdGNoID0gdGhpcy5jYXRjaC5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLmRlc2NyaWJlID0gdGhpcy5kZXNjcmliZS5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLnBpcGUgPSB0aGlzLnBpcGUuYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5yZWFkb25seSA9IHRoaXMucmVhZG9ubHkuYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5pc051bGxhYmxlID0gdGhpcy5pc051bGxhYmxlLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMuaXNPcHRpb25hbCA9IHRoaXMuaXNPcHRpb25hbC5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzW1wifnN0YW5kYXJkXCJdID0ge1xuICAgICAgICAgICAgdmVyc2lvbjogMSxcbiAgICAgICAgICAgIHZlbmRvcjogXCJ6b2RcIixcbiAgICAgICAgICAgIHZhbGlkYXRlOiAoZGF0YSk9PnRoaXNbXCJ+dmFsaWRhdGVcIl0oZGF0YSlcbiAgICAgICAgfTtcbiAgICB9XG4gICAgb3B0aW9uYWwoKSB7XG4gICAgICAgIHJldHVybiBab2RPcHRpb25hbC5jcmVhdGUodGhpcywgdGhpcy5fZGVmKTtcbiAgICB9XG4gICAgbnVsbGFibGUoKSB7XG4gICAgICAgIHJldHVybiBab2ROdWxsYWJsZS5jcmVhdGUodGhpcywgdGhpcy5fZGVmKTtcbiAgICB9XG4gICAgbnVsbGlzaCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubnVsbGFibGUoKS5vcHRpb25hbCgpO1xuICAgIH1cbiAgICBhcnJheSgpIHtcbiAgICAgICAgcmV0dXJuIFpvZEFycmF5LmNyZWF0ZSh0aGlzKTtcbiAgICB9XG4gICAgcHJvbWlzZSgpIHtcbiAgICAgICAgcmV0dXJuIFpvZFByb21pc2UuY3JlYXRlKHRoaXMsIHRoaXMuX2RlZik7XG4gICAgfVxuICAgIG9yKG9wdGlvbikge1xuICAgICAgICByZXR1cm4gWm9kVW5pb24uY3JlYXRlKFtcbiAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICBvcHRpb25cbiAgICAgICAgXSwgdGhpcy5fZGVmKTtcbiAgICB9XG4gICAgYW5kKGluY29taW5nKSB7XG4gICAgICAgIHJldHVybiBab2RJbnRlcnNlY3Rpb24uY3JlYXRlKHRoaXMsIGluY29taW5nLCB0aGlzLl9kZWYpO1xuICAgIH1cbiAgICB0cmFuc2Zvcm0odHJhbnNmb3JtKSB7XG4gICAgICAgIHJldHVybiBuZXcgWm9kRWZmZWN0cyh7XG4gICAgICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHRoaXMuX2RlZiksXG4gICAgICAgICAgICBzY2hlbWE6IHRoaXMsXG4gICAgICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEVmZmVjdHMsXG4gICAgICAgICAgICBlZmZlY3Q6IHtcbiAgICAgICAgICAgICAgICB0eXBlOiBcInRyYW5zZm9ybVwiLFxuICAgICAgICAgICAgICAgIHRyYW5zZm9ybVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGVmYXVsdChkZWYpIHtcbiAgICAgICAgY29uc3QgZGVmYXVsdFZhbHVlRnVuYyA9IHR5cGVvZiBkZWYgPT09IFwiZnVuY3Rpb25cIiA/IGRlZiA6ICgpPT5kZWY7XG4gICAgICAgIHJldHVybiBuZXcgWm9kRGVmYXVsdCh7XG4gICAgICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHRoaXMuX2RlZiksXG4gICAgICAgICAgICBpbm5lclR5cGU6IHRoaXMsXG4gICAgICAgICAgICBkZWZhdWx0VmFsdWU6IGRlZmF1bHRWYWx1ZUZ1bmMsXG4gICAgICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZERlZmF1bHRcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGJyYW5kKCkge1xuICAgICAgICByZXR1cm4gbmV3IFpvZEJyYW5kZWQoe1xuICAgICAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RCcmFuZGVkLFxuICAgICAgICAgICAgdHlwZTogdGhpcyxcbiAgICAgICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXModGhpcy5fZGVmKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgY2F0Y2goZGVmKSB7XG4gICAgICAgIGNvbnN0IGNhdGNoVmFsdWVGdW5jID0gdHlwZW9mIGRlZiA9PT0gXCJmdW5jdGlvblwiID8gZGVmIDogKCk9PmRlZjtcbiAgICAgICAgcmV0dXJuIG5ldyBab2RDYXRjaCh7XG4gICAgICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHRoaXMuX2RlZiksXG4gICAgICAgICAgICBpbm5lclR5cGU6IHRoaXMsXG4gICAgICAgICAgICBjYXRjaFZhbHVlOiBjYXRjaFZhbHVlRnVuYyxcbiAgICAgICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kQ2F0Y2hcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRlc2NyaWJlKGRlc2NyaXB0aW9uKSB7XG4gICAgICAgIGNvbnN0IFRoaXMgPSB0aGlzLmNvbnN0cnVjdG9yO1xuICAgICAgICByZXR1cm4gbmV3IFRoaXMoe1xuICAgICAgICAgICAgLi4udGhpcy5fZGVmLFxuICAgICAgICAgICAgZGVzY3JpcHRpb25cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHBpcGUodGFyZ2V0KSB7XG4gICAgICAgIHJldHVybiBab2RQaXBlbGluZS5jcmVhdGUodGhpcywgdGFyZ2V0KTtcbiAgICB9XG4gICAgcmVhZG9ubHkoKSB7XG4gICAgICAgIHJldHVybiBab2RSZWFkb25seS5jcmVhdGUodGhpcyk7XG4gICAgfVxuICAgIGlzT3B0aW9uYWwoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNhZmVQYXJzZSh1bmRlZmluZWQpLnN1Y2Nlc3M7XG4gICAgfVxuICAgIGlzTnVsbGFibGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNhZmVQYXJzZShudWxsKS5zdWNjZXNzO1xuICAgIH1cbn1cbmNvbnN0IGN1aWRSZWdleCA9IC9eY1teXFxzLV17OCx9JC9pO1xuY29uc3QgY3VpZDJSZWdleCA9IC9eWzAtOWEtel0rJC87XG5jb25zdCB1bGlkUmVnZXggPSAvXlswLTlBLUhKS01OUC1UVi1aXXsyNn0kL2k7XG4vLyBjb25zdCB1dWlkUmVnZXggPVxuLy8gICAvXihbYS1mMC05XXs4fS1bYS1mMC05XXs0fS1bMS01XVthLWYwLTldezN9LVthLWYwLTldezR9LVthLWYwLTldezEyfXwwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDApJC9pO1xuY29uc3QgdXVpZFJlZ2V4ID0gL15bMC05YS1mQS1GXXs4fVxcYi1bMC05YS1mQS1GXXs0fVxcYi1bMC05YS1mQS1GXXs0fVxcYi1bMC05YS1mQS1GXXs0fVxcYi1bMC05YS1mQS1GXXsxMn0kL2k7XG5jb25zdCBuYW5vaWRSZWdleCA9IC9eW2EtejAtOV8tXXsyMX0kL2k7XG5jb25zdCBqd3RSZWdleCA9IC9eW0EtWmEtejAtOS1fXStcXC5bQS1aYS16MC05LV9dK1xcLltBLVphLXowLTktX10qJC87XG5jb25zdCBkdXJhdGlvblJlZ2V4ID0gL15bLStdP1AoPyEkKSg/Oig/OlstK10/XFxkK1kpfCg/OlstK10/XFxkK1suLF1cXGQrWSQpKT8oPzooPzpbLStdP1xcZCtNKXwoPzpbLStdP1xcZCtbLixdXFxkK00kKSk/KD86KD86Wy0rXT9cXGQrVyl8KD86Wy0rXT9cXGQrWy4sXVxcZCtXJCkpPyg/Oig/OlstK10/XFxkK0QpfCg/OlstK10/XFxkK1suLF1cXGQrRCQpKT8oPzpUKD89W1xcZCstXSkoPzooPzpbLStdP1xcZCtIKXwoPzpbLStdP1xcZCtbLixdXFxkK0gkKSk/KD86KD86Wy0rXT9cXGQrTSl8KD86Wy0rXT9cXGQrWy4sXVxcZCtNJCkpPyg/OlstK10/XFxkKyg/OlsuLF1cXGQrKT9TKT8pPz8kLztcbi8vIGZyb20gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzQ2MTgxLzE1NTAxNTVcbi8vIG9sZCB2ZXJzaW9uOiB0b28gc2xvdywgZGlkbid0IHN1cHBvcnQgdW5pY29kZVxuLy8gY29uc3QgZW1haWxSZWdleCA9IC9eKCgoW2Etel18XFxkfFshI1xcJCUmJ1xcKlxcK1xcLVxcLz1cXD9cXF5fYHtcXHx9fl18W1xcdTAwQTAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRl0pKyhcXC4oW2Etel18XFxkfFshI1xcJCUmJ1xcKlxcK1xcLVxcLz1cXD9cXF5fYHtcXHx9fl18W1xcdTAwQTAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRl0pKykqKXwoKFxceDIyKSgoKChcXHgyMHxcXHgwOSkqKFxceDBkXFx4MGEpKT8oXFx4MjB8XFx4MDkpKyk/KChbXFx4MDEtXFx4MDhcXHgwYlxceDBjXFx4MGUtXFx4MWZcXHg3Zl18XFx4MjF8W1xceDIzLVxceDViXXxbXFx4NWQtXFx4N2VdfFtcXHUwMEEwLVxcdUQ3RkZcXHVGOTAwLVxcdUZEQ0ZcXHVGREYwLVxcdUZGRUZdKXwoXFxcXChbXFx4MDEtXFx4MDlcXHgwYlxceDBjXFx4MGQtXFx4N2ZdfFtcXHUwMEEwLVxcdUQ3RkZcXHVGOTAwLVxcdUZEQ0ZcXHVGREYwLVxcdUZGRUZdKSkpKSooKChcXHgyMHxcXHgwOSkqKFxceDBkXFx4MGEpKT8oXFx4MjB8XFx4MDkpKyk/KFxceDIyKSkpQCgoKFthLXpdfFxcZHxbXFx1MDBBMC1cXHVEN0ZGXFx1RjkwMC1cXHVGRENGXFx1RkRGMC1cXHVGRkVGXSl8KChbYS16XXxcXGR8W1xcdTAwQTAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRl0pKFthLXpdfFxcZHwtfFxcLnxffH58W1xcdTAwQTAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRl0pKihbYS16XXxcXGR8W1xcdTAwQTAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRl0pKSlcXC4pKygoW2Etel18W1xcdTAwQTAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRl0pfCgoW2Etel18W1xcdTAwQTAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRl0pKFthLXpdfFxcZHwtfFxcLnxffH58W1xcdTAwQTAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRl0pKihbYS16XXxbXFx1MDBBMC1cXHVEN0ZGXFx1RjkwMC1cXHVGRENGXFx1RkRGMC1cXHVGRkVGXSkpKSQvaTtcbi8vb2xkIGVtYWlsIHJlZ2V4XG4vLyBjb25zdCBlbWFpbFJlZ2V4ID0gL14oKFtePD4oKVtcXF0uLDs6XFxzQFwiXSsoXFwuW148PigpW1xcXS4sOzpcXHNAXCJdKykqKXwoXCIuK1wiKSlAKCg/IS0pKFtePD4oKVtcXF0uLDs6XFxzQFwiXStcXC4pK1tePD4oKVtcXF0uLDs6XFxzQFwiXXsxLH0pW14tPD4oKVtcXF0uLDs6XFxzQFwiXSQvaTtcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuLy8gY29uc3QgZW1haWxSZWdleCA9XG4vLyAgIC9eKChbXjw+KClbXFxdXFxcXC4sOzpcXHNAXFxcIl0rKFxcLltePD4oKVtcXF1cXFxcLiw7Olxcc0BcXFwiXSspKil8KFxcXCIuK1xcXCIpKUAoKFxcWygoKDI1WzAtNV0pfCgyWzAtNF1bMC05XSl8KDFbMC05XXsyfSl8KFswLTldezEsMn0pKVxcLil7M30oKDI1WzAtNV0pfCgyWzAtNF1bMC05XSl8KDFbMC05XXsyfSl8KFswLTldezEsMn0pKVxcXSl8KFxcW0lQdjY6KChbYS1mMC05XXsxLDR9Oil7N318OjooW2EtZjAtOV17MSw0fTopezAsNn18KFthLWYwLTldezEsNH06KXsxfTooW2EtZjAtOV17MSw0fTopezAsNX18KFthLWYwLTldezEsNH06KXsyfTooW2EtZjAtOV17MSw0fTopezAsNH18KFthLWYwLTldezEsNH06KXszfTooW2EtZjAtOV17MSw0fTopezAsM318KFthLWYwLTldezEsNH06KXs0fTooW2EtZjAtOV17MSw0fTopezAsMn18KFthLWYwLTldezEsNH06KXs1fTooW2EtZjAtOV17MSw0fTopezAsMX0pKFthLWYwLTldezEsNH18KCgoMjVbMC01XSl8KDJbMC00XVswLTldKXwoMVswLTldezJ9KXwoWzAtOV17MSwyfSkpXFwuKXszfSgoMjVbMC01XSl8KDJbMC00XVswLTldKXwoMVswLTldezJ9KXwoWzAtOV17MSwyfSkpKVxcXSl8KFtBLVphLXowLTldKFtBLVphLXowLTktXSpbQS1aYS16MC05XSkqKFxcLltBLVphLXpdezIsfSkrKSkkLztcbi8vIGNvbnN0IGVtYWlsUmVnZXggPVxuLy8gICAvXlthLXpBLVowLTlcXC5cXCFcXCNcXCRcXCVcXCZcXCdcXCpcXCtcXC9cXD1cXD9cXF5cXF9cXGBcXHtcXHxcXH1cXH5cXC1dK0BbYS16QS1aMC05XSg/OlthLXpBLVowLTktXXswLDYxfVthLXpBLVowLTldKT8oPzpcXC5bYS16QS1aMC05XSg/OlthLXpBLVowLTktXXswLDYxfVthLXpBLVowLTldKT8pKiQvO1xuLy8gY29uc3QgZW1haWxSZWdleCA9XG4vLyAgIC9eKD86W2EtejAtOSEjJCUmJyorLz0/Xl9ge3x9fi1dKyg/OlxcLlthLXowLTkhIyQlJicqKy89P15fYHt8fX4tXSspKnxcIig/OltcXHgwMS1cXHgwOFxceDBiXFx4MGNcXHgwZS1cXHgxZlxceDIxXFx4MjMtXFx4NWJcXHg1ZC1cXHg3Zl18XFxcXFtcXHgwMS1cXHgwOVxceDBiXFx4MGNcXHgwZS1cXHg3Zl0pKlwiKUAoPzooPzpbYS16MC05XSg/OlthLXowLTktXSpbYS16MC05XSk/XFwuKStbYS16MC05XSg/OlthLXowLTktXSpbYS16MC05XSk/fFxcWyg/Oig/OjI1WzAtNV18MlswLTRdWzAtOV18WzAxXT9bMC05XVswLTldPylcXC4pezN9KD86MjVbMC01XXwyWzAtNF1bMC05XXxbMDFdP1swLTldWzAtOV0/fFthLXowLTktXSpbYS16MC05XTooPzpbXFx4MDEtXFx4MDhcXHgwYlxceDBjXFx4MGUtXFx4MWZcXHgyMS1cXHg1YVxceDUzLVxceDdmXXxcXFxcW1xceDAxLVxceDA5XFx4MGJcXHgwY1xceDBlLVxceDdmXSkrKVxcXSkkL2k7XG5jb25zdCBlbWFpbFJlZ2V4ID0gL14oPyFcXC4pKD8hLipcXC5cXC4pKFtBLVowLTlfJytcXC1cXC5dKilbQS1aMC05XystXUAoW0EtWjAtOV1bQS1aMC05XFwtXSpcXC4pK1tBLVpdezIsfSQvaTtcbi8vIGNvbnN0IGVtYWlsUmVnZXggPVxuLy8gICAvXlthLXowLTkuISMkJSZcdTIwMTkqKy89P15fYHt8fX4tXStAW2EtejAtOS1dKyg/OlxcLlthLXowLTlcXC1dKykqJC9pO1xuLy8gZnJvbSBodHRwczovL3RoZWtldmluc2NvdHQuY29tL2Vtb2ppcy1pbi1qYXZhc2NyaXB0LyN3cml0aW5nLWEtcmVndWxhci1leHByZXNzaW9uXG5jb25zdCBfZW1vamlSZWdleCA9IGBeKFxcXFxwe0V4dGVuZGVkX1BpY3RvZ3JhcGhpY318XFxcXHB7RW1vamlfQ29tcG9uZW50fSkrJGA7XG5sZXQgZW1vamlSZWdleDtcbi8vIGZhc3Rlciwgc2ltcGxlciwgc2FmZXJcbmNvbnN0IGlwdjRSZWdleCA9IC9eKD86KD86MjVbMC01XXwyWzAtNF1bMC05XXwxWzAtOV1bMC05XXxbMS05XVswLTldfFswLTldKVxcLil7M30oPzoyNVswLTVdfDJbMC00XVswLTldfDFbMC05XVswLTldfFsxLTldWzAtOV18WzAtOV0pJC87XG5jb25zdCBpcHY0Q2lkclJlZ2V4ID0gL14oPzooPzoyNVswLTVdfDJbMC00XVswLTldfDFbMC05XVswLTldfFsxLTldWzAtOV18WzAtOV0pXFwuKXszfSg/OjI1WzAtNV18MlswLTRdWzAtOV18MVswLTldWzAtOV18WzEtOV1bMC05XXxbMC05XSlcXC8oM1swLTJdfFsxMl0/WzAtOV0pJC87XG4vLyBjb25zdCBpcHY2UmVnZXggPVxuLy8gL14oKFthLWYwLTldezEsNH06KXs3fXw6OihbYS1mMC05XXsxLDR9Oil7MCw2fXwoW2EtZjAtOV17MSw0fTopezF9OihbYS1mMC05XXsxLDR9Oil7MCw1fXwoW2EtZjAtOV17MSw0fTopezJ9OihbYS1mMC05XXsxLDR9Oil7MCw0fXwoW2EtZjAtOV17MSw0fTopezN9OihbYS1mMC05XXsxLDR9Oil7MCwzfXwoW2EtZjAtOV17MSw0fTopezR9OihbYS1mMC05XXsxLDR9Oil7MCwyfXwoW2EtZjAtOV17MSw0fTopezV9OihbYS1mMC05XXsxLDR9Oil7MCwxfSkoW2EtZjAtOV17MSw0fXwoKCgyNVswLTVdKXwoMlswLTRdWzAtOV0pfCgxWzAtOV17Mn0pfChbMC05XXsxLDJ9KSlcXC4pezN9KCgyNVswLTVdKXwoMlswLTRdWzAtOV0pfCgxWzAtOV17Mn0pfChbMC05XXsxLDJ9KSkpJC87XG5jb25zdCBpcHY2UmVnZXggPSAvXigoWzAtOWEtZkEtRl17MSw0fTopezcsN31bMC05YS1mQS1GXXsxLDR9fChbMC05YS1mQS1GXXsxLDR9Oil7MSw3fTp8KFswLTlhLWZBLUZdezEsNH06KXsxLDZ9OlswLTlhLWZBLUZdezEsNH18KFswLTlhLWZBLUZdezEsNH06KXsxLDV9KDpbMC05YS1mQS1GXXsxLDR9KXsxLDJ9fChbMC05YS1mQS1GXXsxLDR9Oil7MSw0fSg6WzAtOWEtZkEtRl17MSw0fSl7MSwzfXwoWzAtOWEtZkEtRl17MSw0fTopezEsM30oOlswLTlhLWZBLUZdezEsNH0pezEsNH18KFswLTlhLWZBLUZdezEsNH06KXsxLDJ9KDpbMC05YS1mQS1GXXsxLDR9KXsxLDV9fFswLTlhLWZBLUZdezEsNH06KCg6WzAtOWEtZkEtRl17MSw0fSl7MSw2fSl8OigoOlswLTlhLWZBLUZdezEsNH0pezEsN318Oil8ZmU4MDooOlswLTlhLWZBLUZdezAsNH0pezAsNH0lWzAtOWEtekEtWl17MSx9fDo6KGZmZmYoOjB7MSw0fSl7MCwxfTopezAsMX0oKDI1WzAtNV18KDJbMC00XXwxezAsMX1bMC05XSl7MCwxfVswLTldKVxcLil7MywzfSgyNVswLTVdfCgyWzAtNF18MXswLDF9WzAtOV0pezAsMX1bMC05XSl8KFswLTlhLWZBLUZdezEsNH06KXsxLDR9OigoMjVbMC01XXwoMlswLTRdfDF7MCwxfVswLTldKXswLDF9WzAtOV0pXFwuKXszLDN9KDI1WzAtNV18KDJbMC00XXwxezAsMX1bMC05XSl7MCwxfVswLTldKSkkLztcbmNvbnN0IGlwdjZDaWRyUmVnZXggPSAvXigoWzAtOWEtZkEtRl17MSw0fTopezcsN31bMC05YS1mQS1GXXsxLDR9fChbMC05YS1mQS1GXXsxLDR9Oil7MSw3fTp8KFswLTlhLWZBLUZdezEsNH06KXsxLDZ9OlswLTlhLWZBLUZdezEsNH18KFswLTlhLWZBLUZdezEsNH06KXsxLDV9KDpbMC05YS1mQS1GXXsxLDR9KXsxLDJ9fChbMC05YS1mQS1GXXsxLDR9Oil7MSw0fSg6WzAtOWEtZkEtRl17MSw0fSl7MSwzfXwoWzAtOWEtZkEtRl17MSw0fTopezEsM30oOlswLTlhLWZBLUZdezEsNH0pezEsNH18KFswLTlhLWZBLUZdezEsNH06KXsxLDJ9KDpbMC05YS1mQS1GXXsxLDR9KXsxLDV9fFswLTlhLWZBLUZdezEsNH06KCg6WzAtOWEtZkEtRl17MSw0fSl7MSw2fSl8OigoOlswLTlhLWZBLUZdezEsNH0pezEsN318Oil8ZmU4MDooOlswLTlhLWZBLUZdezAsNH0pezAsNH0lWzAtOWEtekEtWl17MSx9fDo6KGZmZmYoOjB7MSw0fSl7MCwxfTopezAsMX0oKDI1WzAtNV18KDJbMC00XXwxezAsMX1bMC05XSl7MCwxfVswLTldKVxcLil7MywzfSgyNVswLTVdfCgyWzAtNF18MXswLDF9WzAtOV0pezAsMX1bMC05XSl8KFswLTlhLWZBLUZdezEsNH06KXsxLDR9OigoMjVbMC01XXwoMlswLTRdfDF7MCwxfVswLTldKXswLDF9WzAtOV0pXFwuKXszLDN9KDI1WzAtNV18KDJbMC00XXwxezAsMX1bMC05XSl7MCwxfVswLTldKSlcXC8oMTJbMC04XXwxWzAxXVswLTldfFsxLTldP1swLTldKSQvO1xuLy8gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNzg2MDM5Mi9kZXRlcm1pbmUtaWYtc3RyaW5nLWlzLWluLWJhc2U2NC11c2luZy1qYXZhc2NyaXB0XG5jb25zdCBiYXNlNjRSZWdleCA9IC9eKFswLTlhLXpBLVorL117NH0pKigoWzAtOWEtekEtWisvXXsyfT09KXwoWzAtOWEtekEtWisvXXszfT0pKT8kLztcbi8vIGh0dHBzOi8vYmFzZTY0Lmd1cnUvc3RhbmRhcmRzL2Jhc2U2NHVybFxuY29uc3QgYmFzZTY0dXJsUmVnZXggPSAvXihbMC05YS16QS1aLV9dezR9KSooKFswLTlhLXpBLVotX117Mn0oPT0pPyl8KFswLTlhLXpBLVotX117M30oPSk/KSk/JC87XG4vLyBzaW1wbGVcbi8vIGNvbnN0IGRhdGVSZWdleFNvdXJjZSA9IGBcXFxcZHs0fS1cXFxcZHsyfS1cXFxcZHsyfWA7XG4vLyBubyBsZWFwIHllYXIgdmFsaWRhdGlvblxuLy8gY29uc3QgZGF0ZVJlZ2V4U291cmNlID0gYFxcXFxkezR9LSgoMFsxMzU3OF18MTB8MTIpLTMxfCgwWzEzLTldfDFbMC0yXSktMzB8KDBbMS05XXwxWzAtMl0pLSgwWzEtOV18MVxcXFxkfDJcXFxcZCkpYDtcbi8vIHdpdGggbGVhcCB5ZWFyIHZhbGlkYXRpb25cbmNvbnN0IGRhdGVSZWdleFNvdXJjZSA9IGAoKFxcXFxkXFxcXGRbMjQ2OF1bMDQ4XXxcXFxcZFxcXFxkWzEzNTc5XVsyNl18XFxcXGRcXFxcZDBbNDhdfFswMjQ2OF1bMDQ4XTAwfFsxMzU3OV1bMjZdMDApLTAyLTI5fFxcXFxkezR9LSgoMFsxMzU3OF18MVswMl0pLSgwWzEtOV18WzEyXVxcXFxkfDNbMDFdKXwoMFs0NjldfDExKS0oMFsxLTldfFsxMl1cXFxcZHwzMCl8KDAyKS0oMFsxLTldfDFcXFxcZHwyWzAtOF0pKSlgO1xuY29uc3QgZGF0ZVJlZ2V4ID0gbmV3IFJlZ0V4cChgXiR7ZGF0ZVJlZ2V4U291cmNlfSRgKTtcbmZ1bmN0aW9uIHRpbWVSZWdleFNvdXJjZShhcmdzKSB7XG4gICAgbGV0IHNlY29uZHNSZWdleFNvdXJjZSA9IGBbMC01XVxcXFxkYDtcbiAgICBpZiAoYXJncy5wcmVjaXNpb24pIHtcbiAgICAgICAgc2Vjb25kc1JlZ2V4U291cmNlID0gYCR7c2Vjb25kc1JlZ2V4U291cmNlfVxcXFwuXFxcXGR7JHthcmdzLnByZWNpc2lvbn19YDtcbiAgICB9IGVsc2UgaWYgKGFyZ3MucHJlY2lzaW9uID09IG51bGwpIHtcbiAgICAgICAgc2Vjb25kc1JlZ2V4U291cmNlID0gYCR7c2Vjb25kc1JlZ2V4U291cmNlfShcXFxcLlxcXFxkKyk/YDtcbiAgICB9XG4gICAgY29uc3Qgc2Vjb25kc1F1YW50aWZpZXIgPSBhcmdzLnByZWNpc2lvbiA/IFwiK1wiIDogXCI/XCI7IC8vIHJlcXVpcmUgc2Vjb25kcyBpZiBwcmVjaXNpb24gaXMgbm9uemVyb1xuICAgIHJldHVybiBgKFswMV1cXFxcZHwyWzAtM10pOlswLTVdXFxcXGQoOiR7c2Vjb25kc1JlZ2V4U291cmNlfSkke3NlY29uZHNRdWFudGlmaWVyfWA7XG59XG5mdW5jdGlvbiB0aW1lUmVnZXgoYXJncykge1xuICAgIHJldHVybiBuZXcgUmVnRXhwKGBeJHt0aW1lUmVnZXhTb3VyY2UoYXJncyl9JGApO1xufVxuLy8gQWRhcHRlZCBmcm9tIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8zMTQzMjMxXG5leHBvcnQgZnVuY3Rpb24gZGF0ZXRpbWVSZWdleChhcmdzKSB7XG4gICAgbGV0IHJlZ2V4ID0gYCR7ZGF0ZVJlZ2V4U291cmNlfVQke3RpbWVSZWdleFNvdXJjZShhcmdzKX1gO1xuICAgIGNvbnN0IG9wdHMgPSBbXTtcbiAgICBvcHRzLnB1c2goYXJncy5sb2NhbCA/IGBaP2AgOiBgWmApO1xuICAgIGlmIChhcmdzLm9mZnNldCkgb3B0cy5wdXNoKGAoWystXVxcXFxkezJ9Oj9cXFxcZHsyfSlgKTtcbiAgICByZWdleCA9IGAke3JlZ2V4fSgke29wdHMuam9pbihcInxcIil9KWA7XG4gICAgcmV0dXJuIG5ldyBSZWdFeHAoYF4ke3JlZ2V4fSRgKTtcbn1cbmZ1bmN0aW9uIGlzVmFsaWRJUChpcCwgdmVyc2lvbikge1xuICAgIGlmICgodmVyc2lvbiA9PT0gXCJ2NFwiIHx8ICF2ZXJzaW9uKSAmJiBpcHY0UmVnZXgudGVzdChpcCkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmICgodmVyc2lvbiA9PT0gXCJ2NlwiIHx8ICF2ZXJzaW9uKSAmJiBpcHY2UmVnZXgudGVzdChpcCkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cbmZ1bmN0aW9uIGlzVmFsaWRKV1Qoand0LCBhbGcpIHtcbiAgICBpZiAoIWp3dFJlZ2V4LnRlc3Qoand0KSkgcmV0dXJuIGZhbHNlO1xuICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IFtoZWFkZXJdID0gand0LnNwbGl0KFwiLlwiKTtcbiAgICAgICAgaWYgKCFoZWFkZXIpIHJldHVybiBmYWxzZTtcbiAgICAgICAgLy8gQ29udmVydCBiYXNlNjR1cmwgdG8gYmFzZTY0XG4gICAgICAgIGNvbnN0IGJhc2U2NCA9IGhlYWRlci5yZXBsYWNlKC8tL2csIFwiK1wiKS5yZXBsYWNlKC9fL2csIFwiL1wiKS5wYWRFbmQoaGVhZGVyLmxlbmd0aCArICg0IC0gaGVhZGVyLmxlbmd0aCAlIDQpICUgNCwgXCI9XCIpO1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIGNvbnN0IGRlY29kZWQgPSBKU09OLnBhcnNlKGF0b2IoYmFzZTY0KSk7XG4gICAgICAgIGlmICh0eXBlb2YgZGVjb2RlZCAhPT0gXCJvYmplY3RcIiB8fCBkZWNvZGVkID09PSBudWxsKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIGlmIChcInR5cFwiIGluIGRlY29kZWQgJiYgZGVjb2RlZD8udHlwICE9PSBcIkpXVFwiKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIGlmICghZGVjb2RlZC5hbGcpIHJldHVybiBmYWxzZTtcbiAgICAgICAgaWYgKGFsZyAmJiBkZWNvZGVkLmFsZyAhPT0gYWxnKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGlzVmFsaWRDaWRyKGlwLCB2ZXJzaW9uKSB7XG4gICAgaWYgKCh2ZXJzaW9uID09PSBcInY0XCIgfHwgIXZlcnNpb24pICYmIGlwdjRDaWRyUmVnZXgudGVzdChpcCkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmICgodmVyc2lvbiA9PT0gXCJ2NlwiIHx8ICF2ZXJzaW9uKSAmJiBpcHY2Q2lkclJlZ2V4LnRlc3QoaXApKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5leHBvcnQgY2xhc3MgWm9kU3RyaW5nIGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGlmICh0aGlzLl9kZWYuY29lcmNlKSB7XG4gICAgICAgICAgICBpbnB1dC5kYXRhID0gU3RyaW5nKGlucHV0LmRhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHBhcnNlZFR5cGUgPSB0aGlzLl9nZXRUeXBlKGlucHV0KTtcbiAgICAgICAgaWYgKHBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUuc3RyaW5nKSB7XG4gICAgICAgICAgICBjb25zdCBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7XG4gICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLnN0cmluZyxcbiAgICAgICAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc3RhdHVzID0gbmV3IFBhcnNlU3RhdHVzKCk7XG4gICAgICAgIGxldCBjdHggPSB1bmRlZmluZWQ7XG4gICAgICAgIGZvciAoY29uc3QgY2hlY2sgb2YgdGhpcy5fZGVmLmNoZWNrcyl7XG4gICAgICAgICAgICBpZiAoY2hlY2sua2luZCA9PT0gXCJtaW5cIikge1xuICAgICAgICAgICAgICAgIGlmIChpbnB1dC5kYXRhLmxlbmd0aCA8IGNoZWNrLnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS50b29fc21hbGwsXG4gICAgICAgICAgICAgICAgICAgICAgICBtaW5pbXVtOiBjaGVjay52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBleGFjdDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwibWF4XCIpIHtcbiAgICAgICAgICAgICAgICBpZiAoaW5wdXQuZGF0YS5sZW5ndGggPiBjaGVjay52YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX2JpZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1heGltdW06IGNoZWNrLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGluY2x1c2l2ZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4YWN0OiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJsZW5ndGhcIikge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRvb0JpZyA9IGlucHV0LmRhdGEubGVuZ3RoID4gY2hlY2sudmFsdWU7XG4gICAgICAgICAgICAgICAgY29uc3QgdG9vU21hbGwgPSBpbnB1dC5kYXRhLmxlbmd0aCA8IGNoZWNrLnZhbHVlO1xuICAgICAgICAgICAgICAgIGlmICh0b29CaWcgfHwgdG9vU21hbGwpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0b29CaWcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS50b29fYmlnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heGltdW06IGNoZWNrLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4YWN0OiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRvb1NtYWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX3NtYWxsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbmltdW06IGNoZWNrLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4YWN0OiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJlbWFpbFwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFlbWFpbFJlZ2V4LnRlc3QoaW5wdXQuZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGlvbjogXCJlbWFpbFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSBcImVtb2ppXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWVtb2ppUmVnZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgZW1vamlSZWdleCA9IG5ldyBSZWdFeHAoX2Vtb2ppUmVnZXgsIFwidVwiKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCFlbW9qaVJlZ2V4LnRlc3QoaW5wdXQuZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGlvbjogXCJlbW9qaVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSBcInV1aWRcIikge1xuICAgICAgICAgICAgICAgIGlmICghdXVpZFJlZ2V4LnRlc3QoaW5wdXQuZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGlvbjogXCJ1dWlkXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwibmFub2lkXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAoIW5hbm9pZFJlZ2V4LnRlc3QoaW5wdXQuZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGlvbjogXCJuYW5vaWRcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3N0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJjdWlkXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWN1aWRSZWdleC50ZXN0KGlucHV0LmRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb246IFwiY3VpZFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSBcImN1aWQyXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWN1aWQyUmVnZXgudGVzdChpbnB1dC5kYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uOiBcImN1aWQyXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwidWxpZFwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF1bGlkUmVnZXgudGVzdChpbnB1dC5kYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uOiBcInVsaWRcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3N0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJ1cmxcIikge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICAgICAgbmV3IFVSTChpbnB1dC5kYXRhKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoICB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb246IFwidXJsXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwicmVnZXhcIikge1xuICAgICAgICAgICAgICAgIGNoZWNrLnJlZ2V4Lmxhc3RJbmRleCA9IDA7XG4gICAgICAgICAgICAgICAgY29uc3QgdGVzdFJlc3VsdCA9IGNoZWNrLnJlZ2V4LnRlc3QoaW5wdXQuZGF0YSk7XG4gICAgICAgICAgICAgICAgaWYgKCF0ZXN0UmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb246IFwicmVnZXhcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3N0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJ0cmltXCIpIHtcbiAgICAgICAgICAgICAgICBpbnB1dC5kYXRhID0gaW5wdXQuZGF0YS50cmltKCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwiaW5jbHVkZXNcIikge1xuICAgICAgICAgICAgICAgIGlmICghaW5wdXQuZGF0YS5pbmNsdWRlcyhjaGVjay52YWx1ZSwgY2hlY2sucG9zaXRpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3N0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb246IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmNsdWRlczogY2hlY2sudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpb246IGNoZWNrLnBvc2l0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSBcInRvTG93ZXJDYXNlXCIpIHtcbiAgICAgICAgICAgICAgICBpbnB1dC5kYXRhID0gaW5wdXQuZGF0YS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSBcInRvVXBwZXJDYXNlXCIpIHtcbiAgICAgICAgICAgICAgICBpbnB1dC5kYXRhID0gaW5wdXQuZGF0YS50b1VwcGVyQ2FzZSgpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSBcInN0YXJ0c1dpdGhcIikge1xuICAgICAgICAgICAgICAgIGlmICghaW5wdXQuZGF0YS5zdGFydHNXaXRoKGNoZWNrLnZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRzV2l0aDogY2hlY2sudmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwiZW5kc1dpdGhcIikge1xuICAgICAgICAgICAgICAgIGlmICghaW5wdXQuZGF0YS5lbmRzV2l0aChjaGVjay52YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGlvbjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZHNXaXRoOiBjaGVjay52YWx1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJkYXRldGltZVwiKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVnZXggPSBkYXRldGltZVJlZ2V4KGNoZWNrKTtcbiAgICAgICAgICAgICAgICBpZiAoIXJlZ2V4LnRlc3QoaW5wdXQuZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGlvbjogXCJkYXRldGltZVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSBcImRhdGVcIikge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlZ2V4ID0gZGF0ZVJlZ2V4O1xuICAgICAgICAgICAgICAgIGlmICghcmVnZXgudGVzdChpbnB1dC5kYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uOiBcImRhdGVcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJ0aW1lXCIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZWdleCA9IHRpbWVSZWdleChjaGVjayk7XG4gICAgICAgICAgICAgICAgaWYgKCFyZWdleC50ZXN0KGlucHV0LmRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3N0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb246IFwidGltZVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSBcImR1cmF0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWR1cmF0aW9uUmVnZXgudGVzdChpbnB1dC5kYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uOiBcImR1cmF0aW9uXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwiaXBcIikge1xuICAgICAgICAgICAgICAgIGlmICghaXNWYWxpZElQKGlucHV0LmRhdGEsIGNoZWNrLnZlcnNpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb246IFwiaXBcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3N0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJqd3RcIikge1xuICAgICAgICAgICAgICAgIGlmICghaXNWYWxpZEpXVChpbnB1dC5kYXRhLCBjaGVjay5hbGcpKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb246IFwiand0XCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwiY2lkclwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFpc1ZhbGlkQ2lkcihpbnB1dC5kYXRhLCBjaGVjay52ZXJzaW9uKSkge1xuICAgICAgICAgICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uOiBcImNpZHJcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3N0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJiYXNlNjRcIikge1xuICAgICAgICAgICAgICAgIGlmICghYmFzZTY0UmVnZXgudGVzdChpbnB1dC5kYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uOiBcImJhc2U2NFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSBcImJhc2U2NHVybFwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFiYXNlNjR1cmxSZWdleC50ZXN0KGlucHV0LmRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb246IFwiYmFzZTY0dXJsXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHV0aWwuYXNzZXJ0TmV2ZXIoY2hlY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdGF0dXM6IHN0YXR1cy52YWx1ZSxcbiAgICAgICAgICAgIHZhbHVlOiBpbnB1dC5kYXRhXG4gICAgICAgIH07XG4gICAgfVxuICAgIF9yZWdleChyZWdleCwgdmFsaWRhdGlvbiwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWZpbmVtZW50KChkYXRhKT0+cmVnZXgudGVzdChkYXRhKSwge1xuICAgICAgICAgICAgdmFsaWRhdGlvbixcbiAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3N0cmluZyxcbiAgICAgICAgICAgIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgX2FkZENoZWNrKGNoZWNrKSB7XG4gICAgICAgIHJldHVybiBuZXcgWm9kU3RyaW5nKHtcbiAgICAgICAgICAgIC4uLnRoaXMuX2RlZixcbiAgICAgICAgICAgIGNoZWNrczogW1xuICAgICAgICAgICAgICAgIC4uLnRoaXMuX2RlZi5jaGVja3MsXG4gICAgICAgICAgICAgICAgY2hlY2tcbiAgICAgICAgICAgIF1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGVtYWlsKG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgIGtpbmQ6IFwiZW1haWxcIixcbiAgICAgICAgICAgIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgdXJsKG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgIGtpbmQ6IFwidXJsXCIsXG4gICAgICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGVtb2ppKG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgIGtpbmQ6IFwiZW1vamlcIixcbiAgICAgICAgICAgIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgdXVpZChtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcInV1aWRcIixcbiAgICAgICAgICAgIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgbmFub2lkKG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgIGtpbmQ6IFwibmFub2lkXCIsXG4gICAgICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGN1aWQobWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJjdWlkXCIsXG4gICAgICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGN1aWQyKG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgIGtpbmQ6IFwiY3VpZDJcIixcbiAgICAgICAgICAgIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgdWxpZChtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcInVsaWRcIixcbiAgICAgICAgICAgIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgYmFzZTY0KG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgIGtpbmQ6IFwiYmFzZTY0XCIsXG4gICAgICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGJhc2U2NHVybChtZXNzYWdlKSB7XG4gICAgICAgIC8vIGJhc2U2NHVybCBlbmNvZGluZyBpcyBhIG1vZGlmaWNhdGlvbiBvZiBiYXNlNjQgdGhhdCBjYW4gc2FmZWx5IGJlIHVzZWQgaW4gVVJMcyBhbmQgZmlsZW5hbWVzXG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcImJhc2U2NHVybFwiLFxuICAgICAgICAgICAgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBqd3Qob3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJqd3RcIixcbiAgICAgICAgICAgIC4uLmVycm9yVXRpbC5lcnJUb09iaihvcHRpb25zKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgaXAob3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJpcFwiLFxuICAgICAgICAgICAgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG9wdGlvbnMpXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBjaWRyKG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgIGtpbmQ6IFwiY2lkclwiLFxuICAgICAgICAgICAgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG9wdGlvbnMpXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkYXRldGltZShvcHRpb25zKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgICAgICBraW5kOiBcImRhdGV0aW1lXCIsXG4gICAgICAgICAgICAgICAgcHJlY2lzaW9uOiBudWxsLFxuICAgICAgICAgICAgICAgIG9mZnNldDogZmFsc2UsXG4gICAgICAgICAgICAgICAgbG9jYWw6IGZhbHNlLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IG9wdGlvbnNcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcImRhdGV0aW1lXCIsXG4gICAgICAgICAgICBwcmVjaXNpb246IHR5cGVvZiBvcHRpb25zPy5wcmVjaXNpb24gPT09IFwidW5kZWZpbmVkXCIgPyBudWxsIDogb3B0aW9ucz8ucHJlY2lzaW9uLFxuICAgICAgICAgICAgb2Zmc2V0OiBvcHRpb25zPy5vZmZzZXQgPz8gZmFsc2UsXG4gICAgICAgICAgICBsb2NhbDogb3B0aW9ucz8ubG9jYWwgPz8gZmFsc2UsXG4gICAgICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoob3B0aW9ucz8ubWVzc2FnZSlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRhdGUobWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJkYXRlXCIsXG4gICAgICAgICAgICBtZXNzYWdlXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICB0aW1lKG9wdGlvbnMpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvcHRpb25zID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAgICAgIGtpbmQ6IFwidGltZVwiLFxuICAgICAgICAgICAgICAgIHByZWNpc2lvbjogbnVsbCxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBvcHRpb25zXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJ0aW1lXCIsXG4gICAgICAgICAgICBwcmVjaXNpb246IHR5cGVvZiBvcHRpb25zPy5wcmVjaXNpb24gPT09IFwidW5kZWZpbmVkXCIgPyBudWxsIDogb3B0aW9ucz8ucHJlY2lzaW9uLFxuICAgICAgICAgICAgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG9wdGlvbnM/Lm1lc3NhZ2UpXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkdXJhdGlvbihtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcImR1cmF0aW9uXCIsXG4gICAgICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJlZ2V4KHJlZ2V4LCBtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcInJlZ2V4XCIsXG4gICAgICAgICAgICByZWdleDogcmVnZXgsXG4gICAgICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGluY2x1ZGVzKHZhbHVlLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcImluY2x1ZGVzXCIsXG4gICAgICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgICAgICBwb3NpdGlvbjogb3B0aW9ucz8ucG9zaXRpb24sXG4gICAgICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoob3B0aW9ucz8ubWVzc2FnZSlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHN0YXJ0c1dpdGgodmFsdWUsIG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgIGtpbmQ6IFwic3RhcnRzV2l0aFwiLFxuICAgICAgICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgICAgICAgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBlbmRzV2l0aCh2YWx1ZSwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJlbmRzV2l0aFwiLFxuICAgICAgICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgICAgICAgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBtaW4obWluTGVuZ3RoLCBtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcIm1pblwiLFxuICAgICAgICAgICAgdmFsdWU6IG1pbkxlbmd0aCxcbiAgICAgICAgICAgIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgbWF4KG1heExlbmd0aCwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJtYXhcIixcbiAgICAgICAgICAgIHZhbHVlOiBtYXhMZW5ndGgsXG4gICAgICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGxlbmd0aChsZW4sIG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgIGtpbmQ6IFwibGVuZ3RoXCIsXG4gICAgICAgICAgICB2YWx1ZTogbGVuLFxuICAgICAgICAgICAgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBFcXVpdmFsZW50IHRvIGAubWluKDEpYFxuICAgICAqLyBub25lbXB0eShtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1pbigxLCBlcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSkpO1xuICAgIH1cbiAgICB0cmltKCkge1xuICAgICAgICByZXR1cm4gbmV3IFpvZFN0cmluZyh7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICBjaGVja3M6IFtcbiAgICAgICAgICAgICAgICAuLi50aGlzLl9kZWYuY2hlY2tzLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAga2luZDogXCJ0cmltXCJcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICB0b0xvd2VyQ2FzZSgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBab2RTdHJpbmcoe1xuICAgICAgICAgICAgLi4udGhpcy5fZGVmLFxuICAgICAgICAgICAgY2hlY2tzOiBbXG4gICAgICAgICAgICAgICAgLi4udGhpcy5fZGVmLmNoZWNrcyxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGtpbmQ6IFwidG9Mb3dlckNhc2VcIlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHRvVXBwZXJDYXNlKCkge1xuICAgICAgICByZXR1cm4gbmV3IFpvZFN0cmluZyh7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICBjaGVja3M6IFtcbiAgICAgICAgICAgICAgICAuLi50aGlzLl9kZWYuY2hlY2tzLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAga2luZDogXCJ0b1VwcGVyQ2FzZVwiXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgXVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZ2V0IGlzRGF0ZXRpbWUoKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuX2RlZi5jaGVja3MuZmluZCgoY2gpPT5jaC5raW5kID09PSBcImRhdGV0aW1lXCIpO1xuICAgIH1cbiAgICBnZXQgaXNEYXRlKCkge1xuICAgICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKT0+Y2gua2luZCA9PT0gXCJkYXRlXCIpO1xuICAgIH1cbiAgICBnZXQgaXNUaW1lKCkge1xuICAgICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKT0+Y2gua2luZCA9PT0gXCJ0aW1lXCIpO1xuICAgIH1cbiAgICBnZXQgaXNEdXJhdGlvbigpIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCk9PmNoLmtpbmQgPT09IFwiZHVyYXRpb25cIik7XG4gICAgfVxuICAgIGdldCBpc0VtYWlsKCkge1xuICAgICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKT0+Y2gua2luZCA9PT0gXCJlbWFpbFwiKTtcbiAgICB9XG4gICAgZ2V0IGlzVVJMKCkge1xuICAgICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKT0+Y2gua2luZCA9PT0gXCJ1cmxcIik7XG4gICAgfVxuICAgIGdldCBpc0Vtb2ppKCkge1xuICAgICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKT0+Y2gua2luZCA9PT0gXCJlbW9qaVwiKTtcbiAgICB9XG4gICAgZ2V0IGlzVVVJRCgpIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCk9PmNoLmtpbmQgPT09IFwidXVpZFwiKTtcbiAgICB9XG4gICAgZ2V0IGlzTkFOT0lEKCkge1xuICAgICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKT0+Y2gua2luZCA9PT0gXCJuYW5vaWRcIik7XG4gICAgfVxuICAgIGdldCBpc0NVSUQoKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuX2RlZi5jaGVja3MuZmluZCgoY2gpPT5jaC5raW5kID09PSBcImN1aWRcIik7XG4gICAgfVxuICAgIGdldCBpc0NVSUQyKCkge1xuICAgICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKT0+Y2gua2luZCA9PT0gXCJjdWlkMlwiKTtcbiAgICB9XG4gICAgZ2V0IGlzVUxJRCgpIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCk9PmNoLmtpbmQgPT09IFwidWxpZFwiKTtcbiAgICB9XG4gICAgZ2V0IGlzSVAoKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuX2RlZi5jaGVja3MuZmluZCgoY2gpPT5jaC5raW5kID09PSBcImlwXCIpO1xuICAgIH1cbiAgICBnZXQgaXNDSURSKCkge1xuICAgICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKT0+Y2gua2luZCA9PT0gXCJjaWRyXCIpO1xuICAgIH1cbiAgICBnZXQgaXNCYXNlNjQoKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuX2RlZi5jaGVja3MuZmluZCgoY2gpPT5jaC5raW5kID09PSBcImJhc2U2NFwiKTtcbiAgICB9XG4gICAgZ2V0IGlzQmFzZTY0dXJsKCkge1xuICAgICAgICAvLyBiYXNlNjR1cmwgZW5jb2RpbmcgaXMgYSBtb2RpZmljYXRpb24gb2YgYmFzZTY0IHRoYXQgY2FuIHNhZmVseSBiZSB1c2VkIGluIFVSTHMgYW5kIGZpbGVuYW1lc1xuICAgICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKT0+Y2gua2luZCA9PT0gXCJiYXNlNjR1cmxcIik7XG4gICAgfVxuICAgIGdldCBtaW5MZW5ndGgoKSB7XG4gICAgICAgIGxldCBtaW4gPSBudWxsO1xuICAgICAgICBmb3IgKGNvbnN0IGNoIG9mIHRoaXMuX2RlZi5jaGVja3Mpe1xuICAgICAgICAgICAgaWYgKGNoLmtpbmQgPT09IFwibWluXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAobWluID09PSBudWxsIHx8IGNoLnZhbHVlID4gbWluKSBtaW4gPSBjaC52YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWluO1xuICAgIH1cbiAgICBnZXQgbWF4TGVuZ3RoKCkge1xuICAgICAgICBsZXQgbWF4ID0gbnVsbDtcbiAgICAgICAgZm9yIChjb25zdCBjaCBvZiB0aGlzLl9kZWYuY2hlY2tzKXtcbiAgICAgICAgICAgIGlmIChjaC5raW5kID09PSBcIm1heFwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKG1heCA9PT0gbnVsbCB8fCBjaC52YWx1ZSA8IG1heCkgbWF4ID0gY2gudmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1heDtcbiAgICB9XG59XG5ab2RTdHJpbmcuY3JlYXRlID0gKHBhcmFtcyk9PntcbiAgICByZXR1cm4gbmV3IFpvZFN0cmluZyh7XG4gICAgICAgIGNoZWNrczogW10sXG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kU3RyaW5nLFxuICAgICAgICBjb2VyY2U6IHBhcmFtcz8uY29lcmNlID8/IGZhbHNlLFxuICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn07XG4vLyBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8zOTY2NDg0L3doeS1kb2VzLW1vZHVsdXMtb3BlcmF0b3ItcmV0dXJuLWZyYWN0aW9uYWwtbnVtYmVyLWluLWphdmFzY3JpcHQvMzE3MTEwMzQjMzE3MTEwMzRcbmZ1bmN0aW9uIGZsb2F0U2FmZVJlbWFpbmRlcih2YWwsIHN0ZXApIHtcbiAgICBjb25zdCB2YWxEZWNDb3VudCA9ICh2YWwudG9TdHJpbmcoKS5zcGxpdChcIi5cIilbMV0gfHwgXCJcIikubGVuZ3RoO1xuICAgIGNvbnN0IHN0ZXBEZWNDb3VudCA9IChzdGVwLnRvU3RyaW5nKCkuc3BsaXQoXCIuXCIpWzFdIHx8IFwiXCIpLmxlbmd0aDtcbiAgICBjb25zdCBkZWNDb3VudCA9IHZhbERlY0NvdW50ID4gc3RlcERlY0NvdW50ID8gdmFsRGVjQ291bnQgOiBzdGVwRGVjQ291bnQ7XG4gICAgY29uc3QgdmFsSW50ID0gTnVtYmVyLnBhcnNlSW50KHZhbC50b0ZpeGVkKGRlY0NvdW50KS5yZXBsYWNlKFwiLlwiLCBcIlwiKSk7XG4gICAgY29uc3Qgc3RlcEludCA9IE51bWJlci5wYXJzZUludChzdGVwLnRvRml4ZWQoZGVjQ291bnQpLnJlcGxhY2UoXCIuXCIsIFwiXCIpKTtcbiAgICByZXR1cm4gdmFsSW50ICUgc3RlcEludCAvIDEwICoqIGRlY0NvdW50O1xufVxuZXhwb3J0IGNsYXNzIFpvZE51bWJlciBleHRlbmRzIFpvZFR5cGUge1xuICAgIGNvbnN0cnVjdG9yKCl7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubWluID0gdGhpcy5ndGU7XG4gICAgICAgIHRoaXMubWF4ID0gdGhpcy5sdGU7XG4gICAgICAgIHRoaXMuc3RlcCA9IHRoaXMubXVsdGlwbGVPZjtcbiAgICB9XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGlmICh0aGlzLl9kZWYuY29lcmNlKSB7XG4gICAgICAgICAgICBpbnB1dC5kYXRhID0gTnVtYmVyKGlucHV0LmRhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHBhcnNlZFR5cGUgPSB0aGlzLl9nZXRUeXBlKGlucHV0KTtcbiAgICAgICAgaWYgKHBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUubnVtYmVyKSB7XG4gICAgICAgICAgICBjb25zdCBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7XG4gICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLm51bWJlcixcbiAgICAgICAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGN0eCA9IHVuZGVmaW5lZDtcbiAgICAgICAgY29uc3Qgc3RhdHVzID0gbmV3IFBhcnNlU3RhdHVzKCk7XG4gICAgICAgIGZvciAoY29uc3QgY2hlY2sgb2YgdGhpcy5fZGVmLmNoZWNrcyl7XG4gICAgICAgICAgICBpZiAoY2hlY2sua2luZCA9PT0gXCJpbnRcIikge1xuICAgICAgICAgICAgICAgIGlmICghdXRpbC5pc0ludGVnZXIoaW5wdXQuZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBcImludGVnZXJcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlY2VpdmVkOiBcImZsb2F0XCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwibWluXCIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB0b29TbWFsbCA9IGNoZWNrLmluY2x1c2l2ZSA/IGlucHV0LmRhdGEgPCBjaGVjay52YWx1ZSA6IGlucHV0LmRhdGEgPD0gY2hlY2sudmFsdWU7XG4gICAgICAgICAgICAgICAgaWYgKHRvb1NtYWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS50b29fc21hbGwsXG4gICAgICAgICAgICAgICAgICAgICAgICBtaW5pbXVtOiBjaGVjay52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IFwibnVtYmVyXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmNsdXNpdmU6IGNoZWNrLmluY2x1c2l2ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4YWN0OiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJtYXhcIikge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRvb0JpZyA9IGNoZWNrLmluY2x1c2l2ZSA/IGlucHV0LmRhdGEgPiBjaGVjay52YWx1ZSA6IGlucHV0LmRhdGEgPj0gY2hlY2sudmFsdWU7XG4gICAgICAgICAgICAgICAgaWYgKHRvb0JpZykge1xuICAgICAgICAgICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX2JpZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1heGltdW06IGNoZWNrLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJudW1iZXJcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGluY2x1c2l2ZTogY2hlY2suaW5jbHVzaXZlLFxuICAgICAgICAgICAgICAgICAgICAgICAgZXhhY3Q6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSBcIm11bHRpcGxlT2ZcIikge1xuICAgICAgICAgICAgICAgIGlmIChmbG9hdFNhZmVSZW1haW5kZXIoaW5wdXQuZGF0YSwgY2hlY2sudmFsdWUpICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5ub3RfbXVsdGlwbGVfb2YsXG4gICAgICAgICAgICAgICAgICAgICAgICBtdWx0aXBsZU9mOiBjaGVjay52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJmaW5pdGVcIikge1xuICAgICAgICAgICAgICAgIGlmICghTnVtYmVyLmlzRmluaXRlKGlucHV0LmRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5ub3RfZmluaXRlLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB1dGlsLmFzc2VydE5ldmVyKGNoZWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3RhdHVzOiBzdGF0dXMudmFsdWUsXG4gICAgICAgICAgICB2YWx1ZTogaW5wdXQuZGF0YVxuICAgICAgICB9O1xuICAgIH1cbiAgICBndGUodmFsdWUsIG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2V0TGltaXQoXCJtaW5cIiwgdmFsdWUsIHRydWUsIGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKSk7XG4gICAgfVxuICAgIGd0KHZhbHVlLCBtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNldExpbWl0KFwibWluXCIsIHZhbHVlLCBmYWxzZSwgZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpKTtcbiAgICB9XG4gICAgbHRlKHZhbHVlLCBtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNldExpbWl0KFwibWF4XCIsIHZhbHVlLCB0cnVlLCBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkpO1xuICAgIH1cbiAgICBsdCh2YWx1ZSwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5zZXRMaW1pdChcIm1heFwiLCB2YWx1ZSwgZmFsc2UsIGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKSk7XG4gICAgfVxuICAgIHNldExpbWl0KGtpbmQsIHZhbHVlLCBpbmNsdXNpdmUsIG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBab2ROdW1iZXIoe1xuICAgICAgICAgICAgLi4udGhpcy5fZGVmLFxuICAgICAgICAgICAgY2hlY2tzOiBbXG4gICAgICAgICAgICAgICAgLi4udGhpcy5fZGVmLmNoZWNrcyxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGtpbmQsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBpbmNsdXNpdmUsXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIF9hZGRDaGVjayhjaGVjaykge1xuICAgICAgICByZXR1cm4gbmV3IFpvZE51bWJlcih7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICBjaGVja3M6IFtcbiAgICAgICAgICAgICAgICAuLi50aGlzLl9kZWYuY2hlY2tzLFxuICAgICAgICAgICAgICAgIGNoZWNrXG4gICAgICAgICAgICBdXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBpbnQobWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJpbnRcIixcbiAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgcG9zaXRpdmUobWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJtaW5cIixcbiAgICAgICAgICAgIHZhbHVlOiAwLFxuICAgICAgICAgICAgaW5jbHVzaXZlOiBmYWxzZSxcbiAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgbmVnYXRpdmUobWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJtYXhcIixcbiAgICAgICAgICAgIHZhbHVlOiAwLFxuICAgICAgICAgICAgaW5jbHVzaXZlOiBmYWxzZSxcbiAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgbm9ucG9zaXRpdmUobWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJtYXhcIixcbiAgICAgICAgICAgIHZhbHVlOiAwLFxuICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBub25uZWdhdGl2ZShtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcIm1pblwiLFxuICAgICAgICAgICAgdmFsdWU6IDAsXG4gICAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsXG4gICAgICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIG11bHRpcGxlT2YodmFsdWUsIG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgIGtpbmQ6IFwibXVsdGlwbGVPZlwiLFxuICAgICAgICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBmaW5pdGUobWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJmaW5pdGVcIixcbiAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgc2FmZShtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcIm1pblwiLFxuICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgdmFsdWU6IE51bWJlci5NSU5fU0FGRV9JTlRFR0VSLFxuICAgICAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpXG4gICAgICAgIH0pLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcIm1heFwiLFxuICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgdmFsdWU6IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSLFxuICAgICAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBnZXQgbWluVmFsdWUoKSB7XG4gICAgICAgIGxldCBtaW4gPSBudWxsO1xuICAgICAgICBmb3IgKGNvbnN0IGNoIG9mIHRoaXMuX2RlZi5jaGVja3Mpe1xuICAgICAgICAgICAgaWYgKGNoLmtpbmQgPT09IFwibWluXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAobWluID09PSBudWxsIHx8IGNoLnZhbHVlID4gbWluKSBtaW4gPSBjaC52YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWluO1xuICAgIH1cbiAgICBnZXQgbWF4VmFsdWUoKSB7XG4gICAgICAgIGxldCBtYXggPSBudWxsO1xuICAgICAgICBmb3IgKGNvbnN0IGNoIG9mIHRoaXMuX2RlZi5jaGVja3Mpe1xuICAgICAgICAgICAgaWYgKGNoLmtpbmQgPT09IFwibWF4XCIpIHtcbiAgICAgICAgICAgICAgICBpZiAobWF4ID09PSBudWxsIHx8IGNoLnZhbHVlIDwgbWF4KSBtYXggPSBjaC52YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWF4O1xuICAgIH1cbiAgICBnZXQgaXNJbnQoKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuX2RlZi5jaGVja3MuZmluZCgoY2gpPT5jaC5raW5kID09PSBcImludFwiIHx8IGNoLmtpbmQgPT09IFwibXVsdGlwbGVPZlwiICYmIHV0aWwuaXNJbnRlZ2VyKGNoLnZhbHVlKSk7XG4gICAgfVxuICAgIGdldCBpc0Zpbml0ZSgpIHtcbiAgICAgICAgbGV0IG1heCA9IG51bGw7XG4gICAgICAgIGxldCBtaW4gPSBudWxsO1xuICAgICAgICBmb3IgKGNvbnN0IGNoIG9mIHRoaXMuX2RlZi5jaGVja3Mpe1xuICAgICAgICAgICAgaWYgKGNoLmtpbmQgPT09IFwiZmluaXRlXCIgfHwgY2gua2luZCA9PT0gXCJpbnRcIiB8fCBjaC5raW5kID09PSBcIm11bHRpcGxlT2ZcIikge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChjaC5raW5kID09PSBcIm1pblwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKG1pbiA9PT0gbnVsbCB8fCBjaC52YWx1ZSA+IG1pbikgbWluID0gY2gudmFsdWU7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNoLmtpbmQgPT09IFwibWF4XCIpIHtcbiAgICAgICAgICAgICAgICBpZiAobWF4ID09PSBudWxsIHx8IGNoLnZhbHVlIDwgbWF4KSBtYXggPSBjaC52YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gTnVtYmVyLmlzRmluaXRlKG1pbikgJiYgTnVtYmVyLmlzRmluaXRlKG1heCk7XG4gICAgfVxufVxuWm9kTnVtYmVyLmNyZWF0ZSA9IChwYXJhbXMpPT57XG4gICAgcmV0dXJuIG5ldyBab2ROdW1iZXIoe1xuICAgICAgICBjaGVja3M6IFtdLFxuICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE51bWJlcixcbiAgICAgICAgY29lcmNlOiBwYXJhbXM/LmNvZXJjZSB8fCBmYWxzZSxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59O1xuZXhwb3J0IGNsYXNzIFpvZEJpZ0ludCBleHRlbmRzIFpvZFR5cGUge1xuICAgIGNvbnN0cnVjdG9yKCl7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubWluID0gdGhpcy5ndGU7XG4gICAgICAgIHRoaXMubWF4ID0gdGhpcy5sdGU7XG4gICAgfVxuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBpZiAodGhpcy5fZGVmLmNvZXJjZSkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBpbnB1dC5kYXRhID0gQmlnSW50KGlucHV0LmRhdGEpO1xuICAgICAgICAgICAgfSBjYXRjaCAge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRJbnZhbGlkSW5wdXQoaW5wdXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHBhcnNlZFR5cGUgPSB0aGlzLl9nZXRUeXBlKGlucHV0KTtcbiAgICAgICAgaWYgKHBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUuYmlnaW50KSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZ2V0SW52YWxpZElucHV0KGlucHV0KTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgY3R4ID0gdW5kZWZpbmVkO1xuICAgICAgICBjb25zdCBzdGF0dXMgPSBuZXcgUGFyc2VTdGF0dXMoKTtcbiAgICAgICAgZm9yIChjb25zdCBjaGVjayBvZiB0aGlzLl9kZWYuY2hlY2tzKXtcbiAgICAgICAgICAgIGlmIChjaGVjay5raW5kID09PSBcIm1pblwiKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdG9vU21hbGwgPSBjaGVjay5pbmNsdXNpdmUgPyBpbnB1dC5kYXRhIDwgY2hlY2sudmFsdWUgOiBpbnB1dC5kYXRhIDw9IGNoZWNrLnZhbHVlO1xuICAgICAgICAgICAgICAgIGlmICh0b29TbWFsbCkge1xuICAgICAgICAgICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX3NtYWxsLFxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJiaWdpbnRcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIG1pbmltdW06IGNoZWNrLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgaW5jbHVzaXZlOiBjaGVjay5pbmNsdXNpdmUsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwibWF4XCIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB0b29CaWcgPSBjaGVjay5pbmNsdXNpdmUgPyBpbnB1dC5kYXRhID4gY2hlY2sudmFsdWUgOiBpbnB1dC5kYXRhID49IGNoZWNrLnZhbHVlO1xuICAgICAgICAgICAgICAgIGlmICh0b29CaWcpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLnRvb19iaWcsXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiBcImJpZ2ludFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWF4aW11bTogY2hlY2sudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmNsdXNpdmU6IGNoZWNrLmluY2x1c2l2ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJtdWx0aXBsZU9mXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAoaW5wdXQuZGF0YSAlIGNoZWNrLnZhbHVlICE9PSBCaWdJbnQoMCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLm5vdF9tdWx0aXBsZV9vZixcbiAgICAgICAgICAgICAgICAgICAgICAgIG11bHRpcGxlT2Y6IGNoZWNrLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB1dGlsLmFzc2VydE5ldmVyKGNoZWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3RhdHVzOiBzdGF0dXMudmFsdWUsXG4gICAgICAgICAgICB2YWx1ZTogaW5wdXQuZGF0YVxuICAgICAgICB9O1xuICAgIH1cbiAgICBfZ2V0SW52YWxpZElucHV0KGlucHV0KSB7XG4gICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTtcbiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLFxuICAgICAgICAgICAgZXhwZWN0ZWQ6IFpvZFBhcnNlZFR5cGUuYmlnaW50LFxuICAgICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICB9XG4gICAgZ3RlKHZhbHVlLCBtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNldExpbWl0KFwibWluXCIsIHZhbHVlLCB0cnVlLCBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkpO1xuICAgIH1cbiAgICBndCh2YWx1ZSwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5zZXRMaW1pdChcIm1pblwiLCB2YWx1ZSwgZmFsc2UsIGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKSk7XG4gICAgfVxuICAgIGx0ZSh2YWx1ZSwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5zZXRMaW1pdChcIm1heFwiLCB2YWx1ZSwgdHJ1ZSwgZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpKTtcbiAgICB9XG4gICAgbHQodmFsdWUsIG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2V0TGltaXQoXCJtYXhcIiwgdmFsdWUsIGZhbHNlLCBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkpO1xuICAgIH1cbiAgICBzZXRMaW1pdChraW5kLCB2YWx1ZSwgaW5jbHVzaXZlLCBtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiBuZXcgWm9kQmlnSW50KHtcbiAgICAgICAgICAgIC4uLnRoaXMuX2RlZixcbiAgICAgICAgICAgIGNoZWNrczogW1xuICAgICAgICAgICAgICAgIC4uLnRoaXMuX2RlZi5jaGVja3MsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBraW5kLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgaW5jbHVzaXZlLFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSlcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBfYWRkQ2hlY2soY2hlY2spIHtcbiAgICAgICAgcmV0dXJuIG5ldyBab2RCaWdJbnQoe1xuICAgICAgICAgICAgLi4udGhpcy5fZGVmLFxuICAgICAgICAgICAgY2hlY2tzOiBbXG4gICAgICAgICAgICAgICAgLi4udGhpcy5fZGVmLmNoZWNrcyxcbiAgICAgICAgICAgICAgICBjaGVja1xuICAgICAgICAgICAgXVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgcG9zaXRpdmUobWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJtaW5cIixcbiAgICAgICAgICAgIHZhbHVlOiBCaWdJbnQoMCksXG4gICAgICAgICAgICBpbmNsdXNpdmU6IGZhbHNlLFxuICAgICAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBuZWdhdGl2ZShtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcIm1heFwiLFxuICAgICAgICAgICAgdmFsdWU6IEJpZ0ludCgwKSxcbiAgICAgICAgICAgIGluY2x1c2l2ZTogZmFsc2UsXG4gICAgICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIG5vbnBvc2l0aXZlKG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgIGtpbmQ6IFwibWF4XCIsXG4gICAgICAgICAgICB2YWx1ZTogQmlnSW50KDApLFxuICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBub25uZWdhdGl2ZShtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcIm1pblwiLFxuICAgICAgICAgICAgdmFsdWU6IEJpZ0ludCgwKSxcbiAgICAgICAgICAgIGluY2x1c2l2ZTogdHJ1ZSxcbiAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgbXVsdGlwbGVPZih2YWx1ZSwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJtdWx0aXBsZU9mXCIsXG4gICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZ2V0IG1pblZhbHVlKCkge1xuICAgICAgICBsZXQgbWluID0gbnVsbDtcbiAgICAgICAgZm9yIChjb25zdCBjaCBvZiB0aGlzLl9kZWYuY2hlY2tzKXtcbiAgICAgICAgICAgIGlmIChjaC5raW5kID09PSBcIm1pblwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKG1pbiA9PT0gbnVsbCB8fCBjaC52YWx1ZSA+IG1pbikgbWluID0gY2gudmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1pbjtcbiAgICB9XG4gICAgZ2V0IG1heFZhbHVlKCkge1xuICAgICAgICBsZXQgbWF4ID0gbnVsbDtcbiAgICAgICAgZm9yIChjb25zdCBjaCBvZiB0aGlzLl9kZWYuY2hlY2tzKXtcbiAgICAgICAgICAgIGlmIChjaC5raW5kID09PSBcIm1heFwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKG1heCA9PT0gbnVsbCB8fCBjaC52YWx1ZSA8IG1heCkgbWF4ID0gY2gudmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1heDtcbiAgICB9XG59XG5ab2RCaWdJbnQuY3JlYXRlID0gKHBhcmFtcyk9PntcbiAgICByZXR1cm4gbmV3IFpvZEJpZ0ludCh7XG4gICAgICAgIGNoZWNrczogW10sXG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kQmlnSW50LFxuICAgICAgICBjb2VyY2U6IHBhcmFtcz8uY29lcmNlID8/IGZhbHNlLFxuICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn07XG5leHBvcnQgY2xhc3MgWm9kQm9vbGVhbiBleHRlbmRzIFpvZFR5cGUge1xuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBpZiAodGhpcy5fZGVmLmNvZXJjZSkge1xuICAgICAgICAgICAgaW5wdXQuZGF0YSA9IEJvb2xlYW4oaW5wdXQuZGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcGFyc2VkVHlwZSA9IHRoaXMuX2dldFR5cGUoaW5wdXQpO1xuICAgICAgICBpZiAocGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS5ib29sZWFuKSB7XG4gICAgICAgICAgICBjb25zdCBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7XG4gICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLmJvb2xlYW4sXG4gICAgICAgICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBPSyhpbnB1dC5kYXRhKTtcbiAgICB9XG59XG5ab2RCb29sZWFuLmNyZWF0ZSA9IChwYXJhbXMpPT57XG4gICAgcmV0dXJuIG5ldyBab2RCb29sZWFuKHtcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RCb29sZWFuLFxuICAgICAgICBjb2VyY2U6IHBhcmFtcz8uY29lcmNlIHx8IGZhbHNlLFxuICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn07XG5leHBvcnQgY2xhc3MgWm9kRGF0ZSBleHRlbmRzIFpvZFR5cGUge1xuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBpZiAodGhpcy5fZGVmLmNvZXJjZSkge1xuICAgICAgICAgICAgaW5wdXQuZGF0YSA9IG5ldyBEYXRlKGlucHV0LmRhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHBhcnNlZFR5cGUgPSB0aGlzLl9nZXRUeXBlKGlucHV0KTtcbiAgICAgICAgaWYgKHBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUuZGF0ZSkge1xuICAgICAgICAgICAgY29uc3QgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQpO1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSxcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5kYXRlLFxuICAgICAgICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoTnVtYmVyLmlzTmFOKGlucHV0LmRhdGEuZ2V0VGltZSgpKSkge1xuICAgICAgICAgICAgY29uc3QgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQpO1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfZGF0ZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzdGF0dXMgPSBuZXcgUGFyc2VTdGF0dXMoKTtcbiAgICAgICAgbGV0IGN0eCA9IHVuZGVmaW5lZDtcbiAgICAgICAgZm9yIChjb25zdCBjaGVjayBvZiB0aGlzLl9kZWYuY2hlY2tzKXtcbiAgICAgICAgICAgIGlmIChjaGVjay5raW5kID09PSBcIm1pblwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKGlucHV0LmRhdGEuZ2V0VGltZSgpIDwgY2hlY2sudmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLnRvb19zbWFsbCxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBleGFjdDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICBtaW5pbXVtOiBjaGVjay52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IFwiZGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwibWF4XCIpIHtcbiAgICAgICAgICAgICAgICBpZiAoaW5wdXQuZGF0YS5nZXRUaW1lKCkgPiBjaGVjay52YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX2JpZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBleGFjdDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICBtYXhpbXVtOiBjaGVjay52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IFwiZGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHV0aWwuYXNzZXJ0TmV2ZXIoY2hlY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdGF0dXM6IHN0YXR1cy52YWx1ZSxcbiAgICAgICAgICAgIHZhbHVlOiBuZXcgRGF0ZShpbnB1dC5kYXRhLmdldFRpbWUoKSlcbiAgICAgICAgfTtcbiAgICB9XG4gICAgX2FkZENoZWNrKGNoZWNrKSB7XG4gICAgICAgIHJldHVybiBuZXcgWm9kRGF0ZSh7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICBjaGVja3M6IFtcbiAgICAgICAgICAgICAgICAuLi50aGlzLl9kZWYuY2hlY2tzLFxuICAgICAgICAgICAgICAgIGNoZWNrXG4gICAgICAgICAgICBdXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBtaW4obWluRGF0ZSwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJtaW5cIixcbiAgICAgICAgICAgIHZhbHVlOiBtaW5EYXRlLmdldFRpbWUoKSxcbiAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgbWF4KG1heERhdGUsIG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgIGtpbmQ6IFwibWF4XCIsXG4gICAgICAgICAgICB2YWx1ZTogbWF4RGF0ZS5nZXRUaW1lKCksXG4gICAgICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGdldCBtaW5EYXRlKCkge1xuICAgICAgICBsZXQgbWluID0gbnVsbDtcbiAgICAgICAgZm9yIChjb25zdCBjaCBvZiB0aGlzLl9kZWYuY2hlY2tzKXtcbiAgICAgICAgICAgIGlmIChjaC5raW5kID09PSBcIm1pblwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKG1pbiA9PT0gbnVsbCB8fCBjaC52YWx1ZSA+IG1pbikgbWluID0gY2gudmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1pbiAhPSBudWxsID8gbmV3IERhdGUobWluKSA6IG51bGw7XG4gICAgfVxuICAgIGdldCBtYXhEYXRlKCkge1xuICAgICAgICBsZXQgbWF4ID0gbnVsbDtcbiAgICAgICAgZm9yIChjb25zdCBjaCBvZiB0aGlzLl9kZWYuY2hlY2tzKXtcbiAgICAgICAgICAgIGlmIChjaC5raW5kID09PSBcIm1heFwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKG1heCA9PT0gbnVsbCB8fCBjaC52YWx1ZSA8IG1heCkgbWF4ID0gY2gudmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1heCAhPSBudWxsID8gbmV3IERhdGUobWF4KSA6IG51bGw7XG4gICAgfVxufVxuWm9kRGF0ZS5jcmVhdGUgPSAocGFyYW1zKT0+e1xuICAgIHJldHVybiBuZXcgWm9kRGF0ZSh7XG4gICAgICAgIGNoZWNrczogW10sXG4gICAgICAgIGNvZXJjZTogcGFyYW1zPy5jb2VyY2UgfHwgZmFsc2UsXG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kRGF0ZSxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59O1xuZXhwb3J0IGNsYXNzIFpvZFN5bWJvbCBleHRlbmRzIFpvZFR5cGUge1xuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBjb25zdCBwYXJzZWRUeXBlID0gdGhpcy5fZ2V0VHlwZShpbnB1dCk7XG4gICAgICAgIGlmIChwYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLnN5bWJvbCkge1xuICAgICAgICAgICAgY29uc3QgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQpO1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSxcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5zeW1ib2wsXG4gICAgICAgICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBPSyhpbnB1dC5kYXRhKTtcbiAgICB9XG59XG5ab2RTeW1ib2wuY3JlYXRlID0gKHBhcmFtcyk9PntcbiAgICByZXR1cm4gbmV3IFpvZFN5bWJvbCh7XG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kU3ltYm9sLFxuICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn07XG5leHBvcnQgY2xhc3MgWm9kVW5kZWZpbmVkIGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHBhcnNlZFR5cGUgPSB0aGlzLl9nZXRUeXBlKGlucHV0KTtcbiAgICAgICAgaWYgKHBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUudW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBjb25zdCBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7XG4gICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLnVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIE9LKGlucHV0LmRhdGEpO1xuICAgIH1cbn1cblpvZFVuZGVmaW5lZC5jcmVhdGUgPSAocGFyYW1zKT0+e1xuICAgIHJldHVybiBuZXcgWm9kVW5kZWZpbmVkKHtcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RVbmRlZmluZWQsXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufTtcbmV4cG9ydCBjbGFzcyBab2ROdWxsIGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHBhcnNlZFR5cGUgPSB0aGlzLl9nZXRUeXBlKGlucHV0KTtcbiAgICAgICAgaWYgKHBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUubnVsbCkge1xuICAgICAgICAgICAgY29uc3QgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQpO1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSxcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5udWxsLFxuICAgICAgICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gT0soaW5wdXQuZGF0YSk7XG4gICAgfVxufVxuWm9kTnVsbC5jcmVhdGUgPSAocGFyYW1zKT0+e1xuICAgIHJldHVybiBuZXcgWm9kTnVsbCh7XG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kTnVsbCxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59O1xuZXhwb3J0IGNsYXNzIFpvZEFueSBleHRlbmRzIFpvZFR5cGUge1xuICAgIGNvbnN0cnVjdG9yKCl7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIC8vIHRvIHByZXZlbnQgaW5zdGFuY2VzIG9mIG90aGVyIGNsYXNzZXMgZnJvbSBleHRlbmRpbmcgWm9kQW55LiB0aGlzIGNhdXNlcyBpc3N1ZXMgd2l0aCBjYXRjaGFsbCBpbiBab2RPYmplY3QuXG4gICAgICAgIHRoaXMuX2FueSA9IHRydWU7XG4gICAgfVxuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICByZXR1cm4gT0soaW5wdXQuZGF0YSk7XG4gICAgfVxufVxuWm9kQW55LmNyZWF0ZSA9IChwYXJhbXMpPT57XG4gICAgcmV0dXJuIG5ldyBab2RBbnkoe1xuICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEFueSxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59O1xuZXhwb3J0IGNsYXNzIFpvZFVua25vd24gZXh0ZW5kcyBab2RUeXBlIHtcbiAgICBjb25zdHJ1Y3Rvcigpe1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICAvLyByZXF1aXJlZFxuICAgICAgICB0aGlzLl91bmtub3duID0gdHJ1ZTtcbiAgICB9XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIHJldHVybiBPSyhpbnB1dC5kYXRhKTtcbiAgICB9XG59XG5ab2RVbmtub3duLmNyZWF0ZSA9IChwYXJhbXMpPT57XG4gICAgcmV0dXJuIG5ldyBab2RVbmtub3duKHtcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RVbmtub3duLFxuICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn07XG5leHBvcnQgY2xhc3MgWm9kTmV2ZXIgZXh0ZW5kcyBab2RUeXBlIHtcbiAgICBfcGFyc2UoaW5wdXQpIHtcbiAgICAgICAgY29uc3QgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQpO1xuICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3R5cGUsXG4gICAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5uZXZlcixcbiAgICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgfVxufVxuWm9kTmV2ZXIuY3JlYXRlID0gKHBhcmFtcyk9PntcbiAgICByZXR1cm4gbmV3IFpvZE5ldmVyKHtcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2ROZXZlcixcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59O1xuZXhwb3J0IGNsYXNzIFpvZFZvaWQgZXh0ZW5kcyBab2RUeXBlIHtcbiAgICBfcGFyc2UoaW5wdXQpIHtcbiAgICAgICAgY29uc3QgcGFyc2VkVHlwZSA9IHRoaXMuX2dldFR5cGUoaW5wdXQpO1xuICAgICAgICBpZiAocGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS51bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTtcbiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3R5cGUsXG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IFpvZFBhcnNlZFR5cGUudm9pZCxcbiAgICAgICAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIE9LKGlucHV0LmRhdGEpO1xuICAgIH1cbn1cblpvZFZvaWQuY3JlYXRlID0gKHBhcmFtcyk9PntcbiAgICByZXR1cm4gbmV3IFpvZFZvaWQoe1xuICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZFZvaWQsXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufTtcbmV4cG9ydCBjbGFzcyBab2RBcnJheSBleHRlbmRzIFpvZFR5cGUge1xuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBjb25zdCB7IGN0eCwgc3RhdHVzIH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpO1xuICAgICAgICBjb25zdCBkZWYgPSB0aGlzLl9kZWY7XG4gICAgICAgIGlmIChjdHgucGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS5hcnJheSkge1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSxcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5hcnJheSxcbiAgICAgICAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRlZi5leGFjdExlbmd0aCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgY29uc3QgdG9vQmlnID0gY3R4LmRhdGEubGVuZ3RoID4gZGVmLmV4YWN0TGVuZ3RoLnZhbHVlO1xuICAgICAgICAgICAgY29uc3QgdG9vU21hbGwgPSBjdHguZGF0YS5sZW5ndGggPCBkZWYuZXhhY3RMZW5ndGgudmFsdWU7XG4gICAgICAgICAgICBpZiAodG9vQmlnIHx8IHRvb1NtYWxsKSB7XG4gICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgIGNvZGU6IHRvb0JpZyA/IFpvZElzc3VlQ29kZS50b29fYmlnIDogWm9kSXNzdWVDb2RlLnRvb19zbWFsbCxcbiAgICAgICAgICAgICAgICAgICAgbWluaW11bTogdG9vU21hbGwgPyBkZWYuZXhhY3RMZW5ndGgudmFsdWUgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgIG1heGltdW06IHRvb0JpZyA/IGRlZi5leGFjdExlbmd0aC52YWx1ZSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJhcnJheVwiLFxuICAgICAgICAgICAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGV4YWN0OiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBkZWYuZXhhY3RMZW5ndGgubWVzc2FnZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChkZWYubWluTGVuZ3RoICE9PSBudWxsKSB7XG4gICAgICAgICAgICBpZiAoY3R4LmRhdGEubGVuZ3RoIDwgZGVmLm1pbkxlbmd0aC52YWx1ZSkge1xuICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX3NtYWxsLFxuICAgICAgICAgICAgICAgICAgICBtaW5pbXVtOiBkZWYubWluTGVuZ3RoLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiBcImFycmF5XCIsXG4gICAgICAgICAgICAgICAgICAgIGluY2x1c2l2ZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgZXhhY3Q6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBkZWYubWluTGVuZ3RoLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoZGVmLm1heExlbmd0aCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKGN0eC5kYXRhLmxlbmd0aCA+IGRlZi5tYXhMZW5ndGgudmFsdWUpIHtcbiAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLnRvb19iaWcsXG4gICAgICAgICAgICAgICAgICAgIG1heGltdW06IGRlZi5tYXhMZW5ndGgudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IFwiYXJyYXlcIixcbiAgICAgICAgICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBleGFjdDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGRlZi5tYXhMZW5ndGgubWVzc2FnZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChjdHguY29tbW9uLmFzeW5jKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoW1xuICAgICAgICAgICAgICAgIC4uLmN0eC5kYXRhXG4gICAgICAgICAgICBdLm1hcCgoaXRlbSwgaSk9PntcbiAgICAgICAgICAgICAgICByZXR1cm4gZGVmLnR5cGUuX3BhcnNlQXN5bmMobmV3IFBhcnNlSW5wdXRMYXp5UGF0aChjdHgsIGl0ZW0sIGN0eC5wYXRoLCBpKSk7XG4gICAgICAgICAgICB9KSkudGhlbigocmVzdWx0KT0+e1xuICAgICAgICAgICAgICAgIHJldHVybiBQYXJzZVN0YXR1cy5tZXJnZUFycmF5KHN0YXR1cywgcmVzdWx0KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IFtcbiAgICAgICAgICAgIC4uLmN0eC5kYXRhXG4gICAgICAgIF0ubWFwKChpdGVtLCBpKT0+e1xuICAgICAgICAgICAgcmV0dXJuIGRlZi50eXBlLl9wYXJzZVN5bmMobmV3IFBhcnNlSW5wdXRMYXp5UGF0aChjdHgsIGl0ZW0sIGN0eC5wYXRoLCBpKSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gUGFyc2VTdGF0dXMubWVyZ2VBcnJheShzdGF0dXMsIHJlc3VsdCk7XG4gICAgfVxuICAgIGdldCBlbGVtZW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmLnR5cGU7XG4gICAgfVxuICAgIG1pbihtaW5MZW5ndGgsIG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBab2RBcnJheSh7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICBtaW5MZW5ndGg6IHtcbiAgICAgICAgICAgICAgICB2YWx1ZTogbWluTGVuZ3RoLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgbWF4KG1heExlbmd0aCwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gbmV3IFpvZEFycmF5KHtcbiAgICAgICAgICAgIC4uLnRoaXMuX2RlZixcbiAgICAgICAgICAgIG1heExlbmd0aDoge1xuICAgICAgICAgICAgICAgIHZhbHVlOiBtYXhMZW5ndGgsXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBsZW5ndGgobGVuLCBtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiBuZXcgWm9kQXJyYXkoe1xuICAgICAgICAgICAgLi4udGhpcy5fZGVmLFxuICAgICAgICAgICAgZXhhY3RMZW5ndGg6IHtcbiAgICAgICAgICAgICAgICB2YWx1ZTogbGVuLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgbm9uZW1wdHkobWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5taW4oMSwgbWVzc2FnZSk7XG4gICAgfVxufVxuWm9kQXJyYXkuY3JlYXRlID0gKHNjaGVtYSwgcGFyYW1zKT0+e1xuICAgIHJldHVybiBuZXcgWm9kQXJyYXkoe1xuICAgICAgICB0eXBlOiBzY2hlbWEsXG4gICAgICAgIG1pbkxlbmd0aDogbnVsbCxcbiAgICAgICAgbWF4TGVuZ3RoOiBudWxsLFxuICAgICAgICBleGFjdExlbmd0aDogbnVsbCxcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RBcnJheSxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59O1xuZnVuY3Rpb24gZGVlcFBhcnRpYWxpZnkoc2NoZW1hKSB7XG4gICAgaWYgKHNjaGVtYSBpbnN0YW5jZW9mIFpvZE9iamVjdCkge1xuICAgICAgICBjb25zdCBuZXdTaGFwZSA9IHt9O1xuICAgICAgICBmb3IoY29uc3Qga2V5IGluIHNjaGVtYS5zaGFwZSl7XG4gICAgICAgICAgICBjb25zdCBmaWVsZFNjaGVtYSA9IHNjaGVtYS5zaGFwZVtrZXldO1xuICAgICAgICAgICAgbmV3U2hhcGVba2V5XSA9IFpvZE9wdGlvbmFsLmNyZWF0ZShkZWVwUGFydGlhbGlmeShmaWVsZFNjaGVtYSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHtcbiAgICAgICAgICAgIC4uLnNjaGVtYS5fZGVmLFxuICAgICAgICAgICAgc2hhcGU6ICgpPT5uZXdTaGFwZVxuICAgICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHNjaGVtYSBpbnN0YW5jZW9mIFpvZEFycmF5KSB7XG4gICAgICAgIHJldHVybiBuZXcgWm9kQXJyYXkoe1xuICAgICAgICAgICAgLi4uc2NoZW1hLl9kZWYsXG4gICAgICAgICAgICB0eXBlOiBkZWVwUGFydGlhbGlmeShzY2hlbWEuZWxlbWVudClcbiAgICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChzY2hlbWEgaW5zdGFuY2VvZiBab2RPcHRpb25hbCkge1xuICAgICAgICByZXR1cm4gWm9kT3B0aW9uYWwuY3JlYXRlKGRlZXBQYXJ0aWFsaWZ5KHNjaGVtYS51bndyYXAoKSkpO1xuICAgIH0gZWxzZSBpZiAoc2NoZW1hIGluc3RhbmNlb2YgWm9kTnVsbGFibGUpIHtcbiAgICAgICAgcmV0dXJuIFpvZE51bGxhYmxlLmNyZWF0ZShkZWVwUGFydGlhbGlmeShzY2hlbWEudW53cmFwKCkpKTtcbiAgICB9IGVsc2UgaWYgKHNjaGVtYSBpbnN0YW5jZW9mIFpvZFR1cGxlKSB7XG4gICAgICAgIHJldHVybiBab2RUdXBsZS5jcmVhdGUoc2NoZW1hLml0ZW1zLm1hcCgoaXRlbSk9PmRlZXBQYXJ0aWFsaWZ5KGl0ZW0pKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHNjaGVtYTtcbiAgICB9XG59XG5leHBvcnQgY2xhc3MgWm9kT2JqZWN0IGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgY29uc3RydWN0b3IoKXtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5fY2FjaGVkID0gbnVsbDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBkZXByZWNhdGVkIEluIG1vc3QgY2FzZXMsIHRoaXMgaXMgbm8gbG9uZ2VyIG5lZWRlZCAtIHVua25vd24gcHJvcGVydGllcyBhcmUgbm93IHNpbGVudGx5IHN0cmlwcGVkLlxuICAgICAgICAgKiBJZiB5b3Ugd2FudCB0byBwYXNzIHRocm91Z2ggdW5rbm93biBwcm9wZXJ0aWVzLCB1c2UgYC5wYXNzdGhyb3VnaCgpYCBpbnN0ZWFkLlxuICAgICAgICAgKi8gdGhpcy5ub25zdHJpY3QgPSB0aGlzLnBhc3N0aHJvdWdoO1xuICAgICAgICAvLyBleHRlbmQ8XG4gICAgICAgIC8vICAgQXVnbWVudGF0aW9uIGV4dGVuZHMgWm9kUmF3U2hhcGUsXG4gICAgICAgIC8vICAgTmV3T3V0cHV0IGV4dGVuZHMgdXRpbC5mbGF0dGVuPHtcbiAgICAgICAgLy8gICAgIFtrIGluIGtleW9mIEF1Z21lbnRhdGlvbiB8IGtleW9mIE91dHB1dF06IGsgZXh0ZW5kcyBrZXlvZiBBdWdtZW50YXRpb25cbiAgICAgICAgLy8gICAgICAgPyBBdWdtZW50YXRpb25ba11bXCJfb3V0cHV0XCJdXG4gICAgICAgIC8vICAgICAgIDogayBleHRlbmRzIGtleW9mIE91dHB1dFxuICAgICAgICAvLyAgICAgICA/IE91dHB1dFtrXVxuICAgICAgICAvLyAgICAgICA6IG5ldmVyO1xuICAgICAgICAvLyAgIH0+LFxuICAgICAgICAvLyAgIE5ld0lucHV0IGV4dGVuZHMgdXRpbC5mbGF0dGVuPHtcbiAgICAgICAgLy8gICAgIFtrIGluIGtleW9mIEF1Z21lbnRhdGlvbiB8IGtleW9mIElucHV0XTogayBleHRlbmRzIGtleW9mIEF1Z21lbnRhdGlvblxuICAgICAgICAvLyAgICAgICA/IEF1Z21lbnRhdGlvbltrXVtcIl9pbnB1dFwiXVxuICAgICAgICAvLyAgICAgICA6IGsgZXh0ZW5kcyBrZXlvZiBJbnB1dFxuICAgICAgICAvLyAgICAgICA/IElucHV0W2tdXG4gICAgICAgIC8vICAgICAgIDogbmV2ZXI7XG4gICAgICAgIC8vICAgfT5cbiAgICAgICAgLy8gPihcbiAgICAgICAgLy8gICBhdWdtZW50YXRpb246IEF1Z21lbnRhdGlvblxuICAgICAgICAvLyApOiBab2RPYmplY3Q8XG4gICAgICAgIC8vICAgZXh0ZW5kU2hhcGU8VCwgQXVnbWVudGF0aW9uPixcbiAgICAgICAgLy8gICBVbmtub3duS2V5cyxcbiAgICAgICAgLy8gICBDYXRjaGFsbCxcbiAgICAgICAgLy8gICBOZXdPdXRwdXQsXG4gICAgICAgIC8vICAgTmV3SW5wdXRcbiAgICAgICAgLy8gPiB7XG4gICAgICAgIC8vICAgcmV0dXJuIG5ldyBab2RPYmplY3Qoe1xuICAgICAgICAvLyAgICAgLi4udGhpcy5fZGVmLFxuICAgICAgICAvLyAgICAgc2hhcGU6ICgpID0+ICh7XG4gICAgICAgIC8vICAgICAgIC4uLnRoaXMuX2RlZi5zaGFwZSgpLFxuICAgICAgICAvLyAgICAgICAuLi5hdWdtZW50YXRpb24sXG4gICAgICAgIC8vICAgICB9KSxcbiAgICAgICAgLy8gICB9KSBhcyBhbnk7XG4gICAgICAgIC8vIH1cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBkZXByZWNhdGVkIFVzZSBgLmV4dGVuZGAgaW5zdGVhZFxuICAgICAgICAgKiAgKi8gdGhpcy5hdWdtZW50ID0gdGhpcy5leHRlbmQ7XG4gICAgfVxuICAgIF9nZXRDYWNoZWQoKSB7XG4gICAgICAgIGlmICh0aGlzLl9jYWNoZWQgIT09IG51bGwpIHJldHVybiB0aGlzLl9jYWNoZWQ7XG4gICAgICAgIGNvbnN0IHNoYXBlID0gdGhpcy5fZGVmLnNoYXBlKCk7XG4gICAgICAgIGNvbnN0IGtleXMgPSB1dGlsLm9iamVjdEtleXMoc2hhcGUpO1xuICAgICAgICB0aGlzLl9jYWNoZWQgPSB7XG4gICAgICAgICAgICBzaGFwZSxcbiAgICAgICAgICAgIGtleXNcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlZDtcbiAgICB9XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHBhcnNlZFR5cGUgPSB0aGlzLl9nZXRUeXBlKGlucHV0KTtcbiAgICAgICAgaWYgKHBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUub2JqZWN0KSB7XG4gICAgICAgICAgICBjb25zdCBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7XG4gICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLm9iamVjdCxcbiAgICAgICAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgeyBzdGF0dXMsIGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTtcbiAgICAgICAgY29uc3QgeyBzaGFwZSwga2V5czogc2hhcGVLZXlzIH0gPSB0aGlzLl9nZXRDYWNoZWQoKTtcbiAgICAgICAgY29uc3QgZXh0cmFLZXlzID0gW107XG4gICAgICAgIGlmICghKHRoaXMuX2RlZi5jYXRjaGFsbCBpbnN0YW5jZW9mIFpvZE5ldmVyICYmIHRoaXMuX2RlZi51bmtub3duS2V5cyA9PT0gXCJzdHJpcFwiKSkge1xuICAgICAgICAgICAgZm9yKGNvbnN0IGtleSBpbiBjdHguZGF0YSl7XG4gICAgICAgICAgICAgICAgaWYgKCFzaGFwZUtleXMuaW5jbHVkZXMoa2V5KSkge1xuICAgICAgICAgICAgICAgICAgICBleHRyYUtleXMucHVzaChrZXkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwYWlycyA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBzaGFwZUtleXMpe1xuICAgICAgICAgICAgY29uc3Qga2V5VmFsaWRhdG9yID0gc2hhcGVba2V5XTtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gY3R4LmRhdGFba2V5XTtcbiAgICAgICAgICAgIHBhaXJzLnB1c2goe1xuICAgICAgICAgICAgICAgIGtleToge1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXM6IFwidmFsaWRcIixcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGtleVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdmFsdWU6IGtleVZhbGlkYXRvci5fcGFyc2UobmV3IFBhcnNlSW5wdXRMYXp5UGF0aChjdHgsIHZhbHVlLCBjdHgucGF0aCwga2V5KSksXG4gICAgICAgICAgICAgICAgYWx3YXlzU2V0OiBrZXkgaW4gY3R4LmRhdGFcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9kZWYuY2F0Y2hhbGwgaW5zdGFuY2VvZiBab2ROZXZlcikge1xuICAgICAgICAgICAgY29uc3QgdW5rbm93bktleXMgPSB0aGlzLl9kZWYudW5rbm93bktleXM7XG4gICAgICAgICAgICBpZiAodW5rbm93bktleXMgPT09IFwicGFzc3Rocm91Z2hcIikge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IG9mIGV4dHJhS2V5cyl7XG4gICAgICAgICAgICAgICAgICAgIHBhaXJzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAga2V5OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzOiBcInZhbGlkXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGtleVxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzOiBcInZhbGlkXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGN0eC5kYXRhW2tleV1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmICh1bmtub3duS2V5cyA9PT0gXCJzdHJpY3RcIikge1xuICAgICAgICAgICAgICAgIGlmIChleHRyYUtleXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS51bnJlY29nbml6ZWRfa2V5cyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleXM6IGV4dHJhS2V5c1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmICh1bmtub3duS2V5cyA9PT0gXCJzdHJpcFwiKSB7fSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludGVybmFsIFpvZE9iamVjdCBlcnJvcjogaW52YWxpZCB1bmtub3duS2V5cyB2YWx1ZS5gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIHJ1biBjYXRjaGFsbCB2YWxpZGF0aW9uXG4gICAgICAgICAgICBjb25zdCBjYXRjaGFsbCA9IHRoaXMuX2RlZi5jYXRjaGFsbDtcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IG9mIGV4dHJhS2V5cyl7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBjdHguZGF0YVtrZXldO1xuICAgICAgICAgICAgICAgIHBhaXJzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBrZXk6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1czogXCJ2YWxpZFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGtleVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogY2F0Y2hhbGwuX3BhcnNlKG5ldyBQYXJzZUlucHV0TGF6eVBhdGgoY3R4LCB2YWx1ZSwgY3R4LnBhdGgsIGtleSkgLy8sIGN0eC5jaGlsZChrZXkpLCB2YWx1ZSwgZ2V0UGFyc2VkVHlwZSh2YWx1ZSlcbiAgICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgICAgYWx3YXlzU2V0OiBrZXkgaW4gY3R4LmRhdGFcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoY3R4LmNvbW1vbi5hc3luYykge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpLnRoZW4oYXN5bmMgKCk9PntcbiAgICAgICAgICAgICAgICBjb25zdCBzeW5jUGFpcnMgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHBhaXIgb2YgcGFpcnMpe1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBrZXkgPSBhd2FpdCBwYWlyLmtleTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBhd2FpdCBwYWlyLnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICBzeW5jUGFpcnMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGFsd2F5c1NldDogcGFpci5hbHdheXNTZXRcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBzeW5jUGFpcnM7XG4gICAgICAgICAgICB9KS50aGVuKChzeW5jUGFpcnMpPT57XG4gICAgICAgICAgICAgICAgcmV0dXJuIFBhcnNlU3RhdHVzLm1lcmdlT2JqZWN0U3luYyhzdGF0dXMsIHN5bmNQYWlycyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBQYXJzZVN0YXR1cy5tZXJnZU9iamVjdFN5bmMoc3RhdHVzLCBwYWlycyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IHNoYXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmLnNoYXBlKCk7XG4gICAgfVxuICAgIHN0cmljdChtZXNzYWdlKSB7XG4gICAgICAgIGVycm9yVXRpbC5lcnJUb09iajtcbiAgICAgICAgcmV0dXJuIG5ldyBab2RPYmplY3Qoe1xuICAgICAgICAgICAgLi4udGhpcy5fZGVmLFxuICAgICAgICAgICAgdW5rbm93bktleXM6IFwic3RyaWN0XCIsXG4gICAgICAgICAgICAuLi5tZXNzYWdlICE9PSB1bmRlZmluZWQgPyB7XG4gICAgICAgICAgICAgICAgZXJyb3JNYXA6IChpc3N1ZSwgY3R4KT0+e1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWZhdWx0RXJyb3IgPSB0aGlzLl9kZWYuZXJyb3JNYXA/Lihpc3N1ZSwgY3R4KS5tZXNzYWdlID8/IGN0eC5kZWZhdWx0RXJyb3I7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc3N1ZS5jb2RlID09PSBcInVucmVjb2duaXplZF9rZXlzXCIpIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSkubWVzc2FnZSA/PyBkZWZhdWx0RXJyb3JcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGRlZmF1bHRFcnJvclxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gOiB7fVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgc3RyaXAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHtcbiAgICAgICAgICAgIC4uLnRoaXMuX2RlZixcbiAgICAgICAgICAgIHVua25vd25LZXlzOiBcInN0cmlwXCJcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHBhc3N0aHJvdWdoKCkge1xuICAgICAgICByZXR1cm4gbmV3IFpvZE9iamVjdCh7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICB1bmtub3duS2V5czogXCJwYXNzdGhyb3VnaFwiXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvLyBjb25zdCBBdWdtZW50RmFjdG9yeSA9XG4gICAgLy8gICA8RGVmIGV4dGVuZHMgWm9kT2JqZWN0RGVmPihkZWY6IERlZikgPT5cbiAgICAvLyAgIDxBdWdtZW50YXRpb24gZXh0ZW5kcyBab2RSYXdTaGFwZT4oXG4gICAgLy8gICAgIGF1Z21lbnRhdGlvbjogQXVnbWVudGF0aW9uXG4gICAgLy8gICApOiBab2RPYmplY3Q8XG4gICAgLy8gICAgIGV4dGVuZFNoYXBlPFJldHVyblR5cGU8RGVmW1wic2hhcGVcIl0+LCBBdWdtZW50YXRpb24+LFxuICAgIC8vICAgICBEZWZbXCJ1bmtub3duS2V5c1wiXSxcbiAgICAvLyAgICAgRGVmW1wiY2F0Y2hhbGxcIl1cbiAgICAvLyAgID4gPT4ge1xuICAgIC8vICAgICByZXR1cm4gbmV3IFpvZE9iamVjdCh7XG4gICAgLy8gICAgICAgLi4uZGVmLFxuICAgIC8vICAgICAgIHNoYXBlOiAoKSA9PiAoe1xuICAgIC8vICAgICAgICAgLi4uZGVmLnNoYXBlKCksXG4gICAgLy8gICAgICAgICAuLi5hdWdtZW50YXRpb24sXG4gICAgLy8gICAgICAgfSksXG4gICAgLy8gICAgIH0pIGFzIGFueTtcbiAgICAvLyAgIH07XG4gICAgZXh0ZW5kKGF1Z21lbnRhdGlvbikge1xuICAgICAgICByZXR1cm4gbmV3IFpvZE9iamVjdCh7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICBzaGFwZTogKCk9Pih7XG4gICAgICAgICAgICAgICAgICAgIC4uLnRoaXMuX2RlZi5zaGFwZSgpLFxuICAgICAgICAgICAgICAgICAgICAuLi5hdWdtZW50YXRpb25cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUHJpb3IgdG8gem9kQDEuMC4xMiB0aGVyZSB3YXMgYSBidWcgaW4gdGhlXG4gICAgICogaW5mZXJyZWQgdHlwZSBvZiBtZXJnZWQgb2JqZWN0cy4gUGxlYXNlXG4gICAgICogdXBncmFkZSBpZiB5b3UgYXJlIGV4cGVyaWVuY2luZyBpc3N1ZXMuXG4gICAgICovIG1lcmdlKG1lcmdpbmcpIHtcbiAgICAgICAgY29uc3QgbWVyZ2VkID0gbmV3IFpvZE9iamVjdCh7XG4gICAgICAgICAgICB1bmtub3duS2V5czogbWVyZ2luZy5fZGVmLnVua25vd25LZXlzLFxuICAgICAgICAgICAgY2F0Y2hhbGw6IG1lcmdpbmcuX2RlZi5jYXRjaGFsbCxcbiAgICAgICAgICAgIHNoYXBlOiAoKT0+KHtcbiAgICAgICAgICAgICAgICAgICAgLi4udGhpcy5fZGVmLnNoYXBlKCksXG4gICAgICAgICAgICAgICAgICAgIC4uLm1lcmdpbmcuX2RlZi5zaGFwZSgpXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE9iamVjdFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG1lcmdlZDtcbiAgICB9XG4gICAgLy8gbWVyZ2U8XG4gICAgLy8gICBJbmNvbWluZyBleHRlbmRzIEFueVpvZE9iamVjdCxcbiAgICAvLyAgIEF1Z21lbnRhdGlvbiBleHRlbmRzIEluY29taW5nW1wic2hhcGVcIl0sXG4gICAgLy8gICBOZXdPdXRwdXQgZXh0ZW5kcyB7XG4gICAgLy8gICAgIFtrIGluIGtleW9mIEF1Z21lbnRhdGlvbiB8IGtleW9mIE91dHB1dF06IGsgZXh0ZW5kcyBrZXlvZiBBdWdtZW50YXRpb25cbiAgICAvLyAgICAgICA/IEF1Z21lbnRhdGlvbltrXVtcIl9vdXRwdXRcIl1cbiAgICAvLyAgICAgICA6IGsgZXh0ZW5kcyBrZXlvZiBPdXRwdXRcbiAgICAvLyAgICAgICA/IE91dHB1dFtrXVxuICAgIC8vICAgICAgIDogbmV2ZXI7XG4gICAgLy8gICB9LFxuICAgIC8vICAgTmV3SW5wdXQgZXh0ZW5kcyB7XG4gICAgLy8gICAgIFtrIGluIGtleW9mIEF1Z21lbnRhdGlvbiB8IGtleW9mIElucHV0XTogayBleHRlbmRzIGtleW9mIEF1Z21lbnRhdGlvblxuICAgIC8vICAgICAgID8gQXVnbWVudGF0aW9uW2tdW1wiX2lucHV0XCJdXG4gICAgLy8gICAgICAgOiBrIGV4dGVuZHMga2V5b2YgSW5wdXRcbiAgICAvLyAgICAgICA/IElucHV0W2tdXG4gICAgLy8gICAgICAgOiBuZXZlcjtcbiAgICAvLyAgIH1cbiAgICAvLyA+KFxuICAgIC8vICAgbWVyZ2luZzogSW5jb21pbmdcbiAgICAvLyApOiBab2RPYmplY3Q8XG4gICAgLy8gICBleHRlbmRTaGFwZTxULCBSZXR1cm5UeXBlPEluY29taW5nW1wiX2RlZlwiXVtcInNoYXBlXCJdPj4sXG4gICAgLy8gICBJbmNvbWluZ1tcIl9kZWZcIl1bXCJ1bmtub3duS2V5c1wiXSxcbiAgICAvLyAgIEluY29taW5nW1wiX2RlZlwiXVtcImNhdGNoYWxsXCJdLFxuICAgIC8vICAgTmV3T3V0cHV0LFxuICAgIC8vICAgTmV3SW5wdXRcbiAgICAvLyA+IHtcbiAgICAvLyAgIGNvbnN0IG1lcmdlZDogYW55ID0gbmV3IFpvZE9iamVjdCh7XG4gICAgLy8gICAgIHVua25vd25LZXlzOiBtZXJnaW5nLl9kZWYudW5rbm93bktleXMsXG4gICAgLy8gICAgIGNhdGNoYWxsOiBtZXJnaW5nLl9kZWYuY2F0Y2hhbGwsXG4gICAgLy8gICAgIHNoYXBlOiAoKSA9PlxuICAgIC8vICAgICAgIG9iamVjdFV0aWwubWVyZ2VTaGFwZXModGhpcy5fZGVmLnNoYXBlKCksIG1lcmdpbmcuX2RlZi5zaGFwZSgpKSxcbiAgICAvLyAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RPYmplY3QsXG4gICAgLy8gICB9KSBhcyBhbnk7XG4gICAgLy8gICByZXR1cm4gbWVyZ2VkO1xuICAgIC8vIH1cbiAgICBzZXRLZXkoa2V5LCBzY2hlbWEpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXVnbWVudCh7XG4gICAgICAgICAgICBba2V5XTogc2NoZW1hXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvLyBtZXJnZTxJbmNvbWluZyBleHRlbmRzIEFueVpvZE9iamVjdD4oXG4gICAgLy8gICBtZXJnaW5nOiBJbmNvbWluZ1xuICAgIC8vICk6IC8vWm9kT2JqZWN0PFQgJiBJbmNvbWluZ1tcIl9zaGFwZVwiXSwgVW5rbm93bktleXMsIENhdGNoYWxsPiA9IChtZXJnaW5nKSA9PiB7XG4gICAgLy8gWm9kT2JqZWN0PFxuICAgIC8vICAgZXh0ZW5kU2hhcGU8VCwgUmV0dXJuVHlwZTxJbmNvbWluZ1tcIl9kZWZcIl1bXCJzaGFwZVwiXT4+LFxuICAgIC8vICAgSW5jb21pbmdbXCJfZGVmXCJdW1widW5rbm93bktleXNcIl0sXG4gICAgLy8gICBJbmNvbWluZ1tcIl9kZWZcIl1bXCJjYXRjaGFsbFwiXVxuICAgIC8vID4ge1xuICAgIC8vICAgLy8gY29uc3QgbWVyZ2VkU2hhcGUgPSBvYmplY3RVdGlsLm1lcmdlU2hhcGVzKFxuICAgIC8vICAgLy8gICB0aGlzLl9kZWYuc2hhcGUoKSxcbiAgICAvLyAgIC8vICAgbWVyZ2luZy5fZGVmLnNoYXBlKClcbiAgICAvLyAgIC8vICk7XG4gICAgLy8gICBjb25zdCBtZXJnZWQ6IGFueSA9IG5ldyBab2RPYmplY3Qoe1xuICAgIC8vICAgICB1bmtub3duS2V5czogbWVyZ2luZy5fZGVmLnVua25vd25LZXlzLFxuICAgIC8vICAgICBjYXRjaGFsbDogbWVyZ2luZy5fZGVmLmNhdGNoYWxsLFxuICAgIC8vICAgICBzaGFwZTogKCkgPT5cbiAgICAvLyAgICAgICBvYmplY3RVdGlsLm1lcmdlU2hhcGVzKHRoaXMuX2RlZi5zaGFwZSgpLCBtZXJnaW5nLl9kZWYuc2hhcGUoKSksXG4gICAgLy8gICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kT2JqZWN0LFxuICAgIC8vICAgfSkgYXMgYW55O1xuICAgIC8vICAgcmV0dXJuIG1lcmdlZDtcbiAgICAvLyB9XG4gICAgY2F0Y2hhbGwoaW5kZXgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBab2RPYmplY3Qoe1xuICAgICAgICAgICAgLi4udGhpcy5fZGVmLFxuICAgICAgICAgICAgY2F0Y2hhbGw6IGluZGV4XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBwaWNrKG1hc2spIHtcbiAgICAgICAgY29uc3Qgc2hhcGUgPSB7fTtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgdXRpbC5vYmplY3RLZXlzKG1hc2spKXtcbiAgICAgICAgICAgIGlmIChtYXNrW2tleV0gJiYgdGhpcy5zaGFwZVtrZXldKSB7XG4gICAgICAgICAgICAgICAgc2hhcGVba2V5XSA9IHRoaXMuc2hhcGVba2V5XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFpvZE9iamVjdCh7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICBzaGFwZTogKCk9PnNoYXBlXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBvbWl0KG1hc2spIHtcbiAgICAgICAgY29uc3Qgc2hhcGUgPSB7fTtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgdXRpbC5vYmplY3RLZXlzKHRoaXMuc2hhcGUpKXtcbiAgICAgICAgICAgIGlmICghbWFza1trZXldKSB7XG4gICAgICAgICAgICAgICAgc2hhcGVba2V5XSA9IHRoaXMuc2hhcGVba2V5XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFpvZE9iamVjdCh7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICBzaGFwZTogKCk9PnNoYXBlXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBAZGVwcmVjYXRlZFxuICAgICAqLyBkZWVwUGFydGlhbCgpIHtcbiAgICAgICAgcmV0dXJuIGRlZXBQYXJ0aWFsaWZ5KHRoaXMpO1xuICAgIH1cbiAgICBwYXJ0aWFsKG1hc2spIHtcbiAgICAgICAgY29uc3QgbmV3U2hhcGUgPSB7fTtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgdXRpbC5vYmplY3RLZXlzKHRoaXMuc2hhcGUpKXtcbiAgICAgICAgICAgIGNvbnN0IGZpZWxkU2NoZW1hID0gdGhpcy5zaGFwZVtrZXldO1xuICAgICAgICAgICAgaWYgKG1hc2sgJiYgIW1hc2tba2V5XSkge1xuICAgICAgICAgICAgICAgIG5ld1NoYXBlW2tleV0gPSBmaWVsZFNjaGVtYTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbmV3U2hhcGVba2V5XSA9IGZpZWxkU2NoZW1hLm9wdGlvbmFsKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBab2RPYmplY3Qoe1xuICAgICAgICAgICAgLi4udGhpcy5fZGVmLFxuICAgICAgICAgICAgc2hhcGU6ICgpPT5uZXdTaGFwZVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmVxdWlyZWQobWFzaykge1xuICAgICAgICBjb25zdCBuZXdTaGFwZSA9IHt9O1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiB1dGlsLm9iamVjdEtleXModGhpcy5zaGFwZSkpe1xuICAgICAgICAgICAgaWYgKG1hc2sgJiYgIW1hc2tba2V5XSkge1xuICAgICAgICAgICAgICAgIG5ld1NoYXBlW2tleV0gPSB0aGlzLnNoYXBlW2tleV07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IGZpZWxkU2NoZW1hID0gdGhpcy5zaGFwZVtrZXldO1xuICAgICAgICAgICAgICAgIGxldCBuZXdGaWVsZCA9IGZpZWxkU2NoZW1hO1xuICAgICAgICAgICAgICAgIHdoaWxlKG5ld0ZpZWxkIGluc3RhbmNlb2YgWm9kT3B0aW9uYWwpe1xuICAgICAgICAgICAgICAgICAgICBuZXdGaWVsZCA9IG5ld0ZpZWxkLl9kZWYuaW5uZXJUeXBlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBuZXdTaGFwZVtrZXldID0gbmV3RmllbGQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBab2RPYmplY3Qoe1xuICAgICAgICAgICAgLi4udGhpcy5fZGVmLFxuICAgICAgICAgICAgc2hhcGU6ICgpPT5uZXdTaGFwZVxuICAgICAgICB9KTtcbiAgICB9XG4gICAga2V5b2YoKSB7XG4gICAgICAgIHJldHVybiBjcmVhdGVab2RFbnVtKHV0aWwub2JqZWN0S2V5cyh0aGlzLnNoYXBlKSk7XG4gICAgfVxufVxuWm9kT2JqZWN0LmNyZWF0ZSA9IChzaGFwZSwgcGFyYW1zKT0+e1xuICAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHtcbiAgICAgICAgc2hhcGU6ICgpPT5zaGFwZSxcbiAgICAgICAgdW5rbm93bktleXM6IFwic3RyaXBcIixcbiAgICAgICAgY2F0Y2hhbGw6IFpvZE5ldmVyLmNyZWF0ZSgpLFxuICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE9iamVjdCxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59O1xuWm9kT2JqZWN0LnN0cmljdENyZWF0ZSA9IChzaGFwZSwgcGFyYW1zKT0+e1xuICAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHtcbiAgICAgICAgc2hhcGU6ICgpPT5zaGFwZSxcbiAgICAgICAgdW5rbm93bktleXM6IFwic3RyaWN0XCIsXG4gICAgICAgIGNhdGNoYWxsOiBab2ROZXZlci5jcmVhdGUoKSxcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RPYmplY3QsXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufTtcblpvZE9iamVjdC5sYXp5Y3JlYXRlID0gKHNoYXBlLCBwYXJhbXMpPT57XG4gICAgcmV0dXJuIG5ldyBab2RPYmplY3Qoe1xuICAgICAgICBzaGFwZSxcbiAgICAgICAgdW5rbm93bktleXM6IFwic3RyaXBcIixcbiAgICAgICAgY2F0Y2hhbGw6IFpvZE5ldmVyLmNyZWF0ZSgpLFxuICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE9iamVjdCxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59O1xuZXhwb3J0IGNsYXNzIFpvZFVuaW9uIGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5fZGVmLm9wdGlvbnM7XG4gICAgICAgIGZ1bmN0aW9uIGhhbmRsZVJlc3VsdHMocmVzdWx0cykge1xuICAgICAgICAgICAgLy8gcmV0dXJuIGZpcnN0IGlzc3VlLWZyZWUgdmFsaWRhdGlvbiBpZiBpdCBleGlzdHNcbiAgICAgICAgICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIHJlc3VsdHMpe1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQucmVzdWx0LnN0YXR1cyA9PT0gXCJ2YWxpZFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQucmVzdWx0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIHJlc3VsdHMpe1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQucmVzdWx0LnN0YXR1cyA9PT0gXCJkaXJ0eVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGFkZCBpc3N1ZXMgZnJvbSBkaXJ0eSBvcHRpb25cbiAgICAgICAgICAgICAgICAgICAgY3R4LmNvbW1vbi5pc3N1ZXMucHVzaCguLi5yZXN1bHQuY3R4LmNvbW1vbi5pc3N1ZXMpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0LnJlc3VsdDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyByZXR1cm4gaW52YWxpZFxuICAgICAgICAgICAgY29uc3QgdW5pb25FcnJvcnMgPSByZXN1bHRzLm1hcCgocmVzdWx0KT0+bmV3IFpvZEVycm9yKHJlc3VsdC5jdHguY29tbW9uLmlzc3VlcykpO1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdW5pb24sXG4gICAgICAgICAgICAgICAgdW5pb25FcnJvcnNcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChvcHRpb25zLm1hcChhc3luYyAob3B0aW9uKT0+e1xuICAgICAgICAgICAgICAgIGNvbnN0IGNoaWxkQ3R4ID0ge1xuICAgICAgICAgICAgICAgICAgICAuLi5jdHgsXG4gICAgICAgICAgICAgICAgICAgIGNvbW1vbjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgLi4uY3R4LmNvbW1vbixcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzc3VlczogW11cbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgcGFyZW50OiBudWxsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQ6IGF3YWl0IG9wdGlvbi5fcGFyc2VBc3luYyh7XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhOiBjdHguZGF0YSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50OiBjaGlsZEN0eFxuICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgY3R4OiBjaGlsZEN0eFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9KSkudGhlbihoYW5kbGVSZXN1bHRzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxldCBkaXJ0eSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGNvbnN0IGlzc3VlcyA9IFtdO1xuICAgICAgICAgICAgZm9yIChjb25zdCBvcHRpb24gb2Ygb3B0aW9ucyl7XG4gICAgICAgICAgICAgICAgY29uc3QgY2hpbGRDdHggPSB7XG4gICAgICAgICAgICAgICAgICAgIC4uLmN0eCxcbiAgICAgICAgICAgICAgICAgICAgY29tbW9uOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAuLi5jdHguY29tbW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgaXNzdWVzOiBbXVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IG51bGxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IG9wdGlvbi5fcGFyc2VTeW5jKHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YTogY3R4LmRhdGEsXG4gICAgICAgICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IGNoaWxkQ3R4XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5zdGF0dXMgPT09IFwidmFsaWRcIikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocmVzdWx0LnN0YXR1cyA9PT0gXCJkaXJ0eVwiICYmICFkaXJ0eSkge1xuICAgICAgICAgICAgICAgICAgICBkaXJ0eSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGN0eDogY2hpbGRDdHhcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGNoaWxkQ3R4LmNvbW1vbi5pc3N1ZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIGlzc3Vlcy5wdXNoKGNoaWxkQ3R4LmNvbW1vbi5pc3N1ZXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChkaXJ0eSkge1xuICAgICAgICAgICAgICAgIGN0eC5jb21tb24uaXNzdWVzLnB1c2goLi4uZGlydHkuY3R4LmNvbW1vbi5pc3N1ZXMpO1xuICAgICAgICAgICAgICAgIHJldHVybiBkaXJ0eS5yZXN1bHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCB1bmlvbkVycm9ycyA9IGlzc3Vlcy5tYXAoKGlzc3Vlcyk9Pm5ldyBab2RFcnJvcihpc3N1ZXMpKTtcbiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3VuaW9uLFxuICAgICAgICAgICAgICAgIHVuaW9uRXJyb3JzXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICB9XG4gICAgfVxuICAgIGdldCBvcHRpb25zKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmLm9wdGlvbnM7XG4gICAgfVxufVxuWm9kVW5pb24uY3JlYXRlID0gKHR5cGVzLCBwYXJhbXMpPT57XG4gICAgcmV0dXJuIG5ldyBab2RVbmlvbih7XG4gICAgICAgIG9wdGlvbnM6IHR5cGVzLFxuICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZFVuaW9uLFxuICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn07XG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vLy8vLy8vLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLy8vLy8vLy8vXG4vLy8vLy8vLy8vICAgICAgWm9kRGlzY3JpbWluYXRlZFVuaW9uICAgICAgLy8vLy8vLy8vL1xuLy8vLy8vLy8vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vLy8vLy8vLy9cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuY29uc3QgZ2V0RGlzY3JpbWluYXRvciA9ICh0eXBlKT0+e1xuICAgIGlmICh0eXBlIGluc3RhbmNlb2YgWm9kTGF6eSkge1xuICAgICAgICByZXR1cm4gZ2V0RGlzY3JpbWluYXRvcih0eXBlLnNjaGVtYSk7XG4gICAgfSBlbHNlIGlmICh0eXBlIGluc3RhbmNlb2YgWm9kRWZmZWN0cykge1xuICAgICAgICByZXR1cm4gZ2V0RGlzY3JpbWluYXRvcih0eXBlLmlubmVyVHlwZSgpKTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgaW5zdGFuY2VvZiBab2RMaXRlcmFsKSB7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICB0eXBlLnZhbHVlXG4gICAgICAgIF07XG4gICAgfSBlbHNlIGlmICh0eXBlIGluc3RhbmNlb2YgWm9kRW51bSkge1xuICAgICAgICByZXR1cm4gdHlwZS5vcHRpb25zO1xuICAgIH0gZWxzZSBpZiAodHlwZSBpbnN0YW5jZW9mIFpvZE5hdGl2ZUVudW0pIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGJhbi9iYW5cbiAgICAgICAgcmV0dXJuIHV0aWwub2JqZWN0VmFsdWVzKHR5cGUuZW51bSk7XG4gICAgfSBlbHNlIGlmICh0eXBlIGluc3RhbmNlb2YgWm9kRGVmYXVsdCkge1xuICAgICAgICByZXR1cm4gZ2V0RGlzY3JpbWluYXRvcih0eXBlLl9kZWYuaW5uZXJUeXBlKTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgaW5zdGFuY2VvZiBab2RVbmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIHVuZGVmaW5lZFxuICAgICAgICBdO1xuICAgIH0gZWxzZSBpZiAodHlwZSBpbnN0YW5jZW9mIFpvZE51bGwpIHtcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIG51bGxcbiAgICAgICAgXTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgaW5zdGFuY2VvZiBab2RPcHRpb25hbCkge1xuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgLi4uZ2V0RGlzY3JpbWluYXRvcih0eXBlLnVud3JhcCgpKVxuICAgICAgICBdO1xuICAgIH0gZWxzZSBpZiAodHlwZSBpbnN0YW5jZW9mIFpvZE51bGxhYmxlKSB7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgLi4uZ2V0RGlzY3JpbWluYXRvcih0eXBlLnVud3JhcCgpKVxuICAgICAgICBdO1xuICAgIH0gZWxzZSBpZiAodHlwZSBpbnN0YW5jZW9mIFpvZEJyYW5kZWQpIHtcbiAgICAgICAgcmV0dXJuIGdldERpc2NyaW1pbmF0b3IodHlwZS51bndyYXAoKSk7XG4gICAgfSBlbHNlIGlmICh0eXBlIGluc3RhbmNlb2YgWm9kUmVhZG9ubHkpIHtcbiAgICAgICAgcmV0dXJuIGdldERpc2NyaW1pbmF0b3IodHlwZS51bndyYXAoKSk7XG4gICAgfSBlbHNlIGlmICh0eXBlIGluc3RhbmNlb2YgWm9kQ2F0Y2gpIHtcbiAgICAgICAgcmV0dXJuIGdldERpc2NyaW1pbmF0b3IodHlwZS5fZGVmLmlubmVyVHlwZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbn07XG5leHBvcnQgY2xhc3MgWm9kRGlzY3JpbWluYXRlZFVuaW9uIGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpO1xuICAgICAgICBpZiAoY3R4LnBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUub2JqZWN0KSB7XG4gICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLm9iamVjdCxcbiAgICAgICAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZGlzY3JpbWluYXRvciA9IHRoaXMuZGlzY3JpbWluYXRvcjtcbiAgICAgICAgY29uc3QgZGlzY3JpbWluYXRvclZhbHVlID0gY3R4LmRhdGFbZGlzY3JpbWluYXRvcl07XG4gICAgICAgIGNvbnN0IG9wdGlvbiA9IHRoaXMub3B0aW9uc01hcC5nZXQoZGlzY3JpbWluYXRvclZhbHVlKTtcbiAgICAgICAgaWYgKCFvcHRpb24pIHtcbiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3VuaW9uX2Rpc2NyaW1pbmF0b3IsXG4gICAgICAgICAgICAgICAgb3B0aW9uczogQXJyYXkuZnJvbSh0aGlzLm9wdGlvbnNNYXAua2V5cygpKSxcbiAgICAgICAgICAgICAgICBwYXRoOiBbXG4gICAgICAgICAgICAgICAgICAgIGRpc2NyaW1pbmF0b3JcbiAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjdHguY29tbW9uLmFzeW5jKSB7XG4gICAgICAgICAgICByZXR1cm4gb3B0aW9uLl9wYXJzZUFzeW5jKHtcbiAgICAgICAgICAgICAgICBkYXRhOiBjdHguZGF0YSxcbiAgICAgICAgICAgICAgICBwYXRoOiBjdHgucGF0aCxcbiAgICAgICAgICAgICAgICBwYXJlbnQ6IGN0eFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gb3B0aW9uLl9wYXJzZVN5bmMoe1xuICAgICAgICAgICAgICAgIGRhdGE6IGN0eC5kYXRhLFxuICAgICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgICAgIHBhcmVudDogY3R4XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgZGlzY3JpbWluYXRvcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi5kaXNjcmltaW5hdG9yO1xuICAgIH1cbiAgICBnZXQgb3B0aW9ucygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi5vcHRpb25zO1xuICAgIH1cbiAgICBnZXQgb3B0aW9uc01hcCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi5vcHRpb25zTWFwO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgY29uc3RydWN0b3Igb2YgdGhlIGRpc2NyaW1pbmF0ZWQgdW5pb24gc2NoZW1hLiBJdHMgYmVoYXZpb3VyIGlzIHZlcnkgc2ltaWxhciB0byB0aGF0IG9mIHRoZSBub3JtYWwgei51bmlvbigpIGNvbnN0cnVjdG9yLlxuICAgICAqIEhvd2V2ZXIsIGl0IG9ubHkgYWxsb3dzIGEgdW5pb24gb2Ygb2JqZWN0cywgYWxsIG9mIHdoaWNoIG5lZWQgdG8gc2hhcmUgYSBkaXNjcmltaW5hdG9yIHByb3BlcnR5LiBUaGlzIHByb3BlcnR5IG11c3RcbiAgICAgKiBoYXZlIGEgZGlmZmVyZW50IHZhbHVlIGZvciBlYWNoIG9iamVjdCBpbiB0aGUgdW5pb24uXG4gICAgICogQHBhcmFtIGRpc2NyaW1pbmF0b3IgdGhlIG5hbWUgb2YgdGhlIGRpc2NyaW1pbmF0b3IgcHJvcGVydHlcbiAgICAgKiBAcGFyYW0gdHlwZXMgYW4gYXJyYXkgb2Ygb2JqZWN0IHNjaGVtYXNcbiAgICAgKiBAcGFyYW0gcGFyYW1zXG4gICAgICovIHN0YXRpYyBjcmVhdGUoZGlzY3JpbWluYXRvciwgb3B0aW9ucywgcGFyYW1zKSB7XG4gICAgICAgIC8vIEdldCBhbGwgdGhlIHZhbGlkIGRpc2NyaW1pbmF0b3IgdmFsdWVzXG4gICAgICAgIGNvbnN0IG9wdGlvbnNNYXAgPSBuZXcgTWFwKCk7XG4gICAgICAgIC8vIHRyeSB7XG4gICAgICAgIGZvciAoY29uc3QgdHlwZSBvZiBvcHRpb25zKXtcbiAgICAgICAgICAgIGNvbnN0IGRpc2NyaW1pbmF0b3JWYWx1ZXMgPSBnZXREaXNjcmltaW5hdG9yKHR5cGUuc2hhcGVbZGlzY3JpbWluYXRvcl0pO1xuICAgICAgICAgICAgaWYgKCFkaXNjcmltaW5hdG9yVmFsdWVzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQSBkaXNjcmltaW5hdG9yIHZhbHVlIGZvciBrZXkgXFxgJHtkaXNjcmltaW5hdG9yfVxcYCBjb3VsZCBub3QgYmUgZXh0cmFjdGVkIGZyb20gYWxsIHNjaGVtYSBvcHRpb25zYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHZhbHVlIG9mIGRpc2NyaW1pbmF0b3JWYWx1ZXMpe1xuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zTWFwLmhhcyh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBEaXNjcmltaW5hdG9yIHByb3BlcnR5ICR7U3RyaW5nKGRpc2NyaW1pbmF0b3IpfSBoYXMgZHVwbGljYXRlIHZhbHVlICR7U3RyaW5nKHZhbHVlKX1gKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgb3B0aW9uc01hcC5zZXQodmFsdWUsIHR5cGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgWm9kRGlzY3JpbWluYXRlZFVuaW9uKHtcbiAgICAgICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kRGlzY3JpbWluYXRlZFVuaW9uLFxuICAgICAgICAgICAgZGlzY3JpbWluYXRvcixcbiAgICAgICAgICAgIG9wdGlvbnMsXG4gICAgICAgICAgICBvcHRpb25zTWFwLFxuICAgICAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgICAgIH0pO1xuICAgIH1cbn1cbmZ1bmN0aW9uIG1lcmdlVmFsdWVzKGEsIGIpIHtcbiAgICBjb25zdCBhVHlwZSA9IGdldFBhcnNlZFR5cGUoYSk7XG4gICAgY29uc3QgYlR5cGUgPSBnZXRQYXJzZWRUeXBlKGIpO1xuICAgIGlmIChhID09PSBiKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWxpZDogdHJ1ZSxcbiAgICAgICAgICAgIGRhdGE6IGFcbiAgICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKGFUeXBlID09PSBab2RQYXJzZWRUeXBlLm9iamVjdCAmJiBiVHlwZSA9PT0gWm9kUGFyc2VkVHlwZS5vYmplY3QpIHtcbiAgICAgICAgY29uc3QgYktleXMgPSB1dGlsLm9iamVjdEtleXMoYik7XG4gICAgICAgIGNvbnN0IHNoYXJlZEtleXMgPSB1dGlsLm9iamVjdEtleXMoYSkuZmlsdGVyKChrZXkpPT5iS2V5cy5pbmRleE9mKGtleSkgIT09IC0xKTtcbiAgICAgICAgY29uc3QgbmV3T2JqID0ge1xuICAgICAgICAgICAgLi4uYSxcbiAgICAgICAgICAgIC4uLmJcbiAgICAgICAgfTtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2Ygc2hhcmVkS2V5cyl7XG4gICAgICAgICAgICBjb25zdCBzaGFyZWRWYWx1ZSA9IG1lcmdlVmFsdWVzKGFba2V5XSwgYltrZXldKTtcbiAgICAgICAgICAgIGlmICghc2hhcmVkVmFsdWUudmFsaWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICB2YWxpZDogZmFsc2VcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbmV3T2JqW2tleV0gPSBzaGFyZWRWYWx1ZS5kYXRhO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWxpZDogdHJ1ZSxcbiAgICAgICAgICAgIGRhdGE6IG5ld09ialxuICAgICAgICB9O1xuICAgIH0gZWxzZSBpZiAoYVR5cGUgPT09IFpvZFBhcnNlZFR5cGUuYXJyYXkgJiYgYlR5cGUgPT09IFpvZFBhcnNlZFR5cGUuYXJyYXkpIHtcbiAgICAgICAgaWYgKGEubGVuZ3RoICE9PSBiLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICB2YWxpZDogZmFsc2VcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmV3QXJyYXkgPSBbXTtcbiAgICAgICAgZm9yKGxldCBpbmRleCA9IDA7IGluZGV4IDwgYS5sZW5ndGg7IGluZGV4Kyspe1xuICAgICAgICAgICAgY29uc3QgaXRlbUEgPSBhW2luZGV4XTtcbiAgICAgICAgICAgIGNvbnN0IGl0ZW1CID0gYltpbmRleF07XG4gICAgICAgICAgICBjb25zdCBzaGFyZWRWYWx1ZSA9IG1lcmdlVmFsdWVzKGl0ZW1BLCBpdGVtQik7XG4gICAgICAgICAgICBpZiAoIXNoYXJlZFZhbHVlLnZhbGlkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsaWQ6IGZhbHNlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG5ld0FycmF5LnB1c2goc2hhcmVkVmFsdWUuZGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHZhbGlkOiB0cnVlLFxuICAgICAgICAgICAgZGF0YTogbmV3QXJyYXlcbiAgICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKGFUeXBlID09PSBab2RQYXJzZWRUeXBlLmRhdGUgJiYgYlR5cGUgPT09IFpvZFBhcnNlZFR5cGUuZGF0ZSAmJiArYSA9PT0gK2IpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHZhbGlkOiB0cnVlLFxuICAgICAgICAgICAgZGF0YTogYVxuICAgICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWxpZDogZmFsc2VcbiAgICAgICAgfTtcbiAgICB9XG59XG5leHBvcnQgY2xhc3MgWm9kSW50ZXJzZWN0aW9uIGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHsgc3RhdHVzLCBjdHggfSA9IHRoaXMuX3Byb2Nlc3NJbnB1dFBhcmFtcyhpbnB1dCk7XG4gICAgICAgIGNvbnN0IGhhbmRsZVBhcnNlZCA9IChwYXJzZWRMZWZ0LCBwYXJzZWRSaWdodCk9PntcbiAgICAgICAgICAgIGlmIChpc0Fib3J0ZWQocGFyc2VkTGVmdCkgfHwgaXNBYm9ydGVkKHBhcnNlZFJpZ2h0KSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgbWVyZ2VkID0gbWVyZ2VWYWx1ZXMocGFyc2VkTGVmdC52YWx1ZSwgcGFyc2VkUmlnaHQudmFsdWUpO1xuICAgICAgICAgICAgaWYgKCFtZXJnZWQudmFsaWQpIHtcbiAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfaW50ZXJzZWN0aW9uX3R5cGVzXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNEaXJ0eShwYXJzZWRMZWZ0KSB8fCBpc0RpcnR5KHBhcnNlZFJpZ2h0KSkge1xuICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBzdGF0dXM6IHN0YXR1cy52YWx1ZSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogbWVyZ2VkLmRhdGFcbiAgICAgICAgICAgIH07XG4gICAgICAgIH07XG4gICAgICAgIGlmIChjdHguY29tbW9uLmFzeW5jKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoW1xuICAgICAgICAgICAgICAgIHRoaXMuX2RlZi5sZWZ0Ll9wYXJzZUFzeW5jKHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YTogY3R4LmRhdGEsXG4gICAgICAgICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IGN0eFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIHRoaXMuX2RlZi5yaWdodC5fcGFyc2VBc3luYyh7XG4gICAgICAgICAgICAgICAgICAgIGRhdGE6IGN0eC5kYXRhLFxuICAgICAgICAgICAgICAgICAgICBwYXRoOiBjdHgucGF0aCxcbiAgICAgICAgICAgICAgICAgICAgcGFyZW50OiBjdHhcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgXSkudGhlbigoW2xlZnQsIHJpZ2h0XSk9PmhhbmRsZVBhcnNlZChsZWZ0LCByaWdodCkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGhhbmRsZVBhcnNlZCh0aGlzLl9kZWYubGVmdC5fcGFyc2VTeW5jKHtcbiAgICAgICAgICAgICAgICBkYXRhOiBjdHguZGF0YSxcbiAgICAgICAgICAgICAgICBwYXRoOiBjdHgucGF0aCxcbiAgICAgICAgICAgICAgICBwYXJlbnQ6IGN0eFxuICAgICAgICAgICAgfSksIHRoaXMuX2RlZi5yaWdodC5fcGFyc2VTeW5jKHtcbiAgICAgICAgICAgICAgICBkYXRhOiBjdHguZGF0YSxcbiAgICAgICAgICAgICAgICBwYXRoOiBjdHgucGF0aCxcbiAgICAgICAgICAgICAgICBwYXJlbnQ6IGN0eFxuICAgICAgICAgICAgfSkpO1xuICAgICAgICB9XG4gICAgfVxufVxuWm9kSW50ZXJzZWN0aW9uLmNyZWF0ZSA9IChsZWZ0LCByaWdodCwgcGFyYW1zKT0+e1xuICAgIHJldHVybiBuZXcgWm9kSW50ZXJzZWN0aW9uKHtcbiAgICAgICAgbGVmdDogbGVmdCxcbiAgICAgICAgcmlnaHQ6IHJpZ2h0LFxuICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEludGVyc2VjdGlvbixcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59O1xuLy8gdHlwZSBab2RUdXBsZUl0ZW1zID0gW1pvZFR5cGVBbnksIC4uLlpvZFR5cGVBbnlbXV07XG5leHBvcnQgY2xhc3MgWm9kVHVwbGUgZXh0ZW5kcyBab2RUeXBlIHtcbiAgICBfcGFyc2UoaW5wdXQpIHtcbiAgICAgICAgY29uc3QgeyBzdGF0dXMsIGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTtcbiAgICAgICAgaWYgKGN0eC5wYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLmFycmF5KSB7XG4gICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLmFycmF5LFxuICAgICAgICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY3R4LmRhdGEubGVuZ3RoIDwgdGhpcy5fZGVmLml0ZW1zLmxlbmd0aCkge1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLnRvb19zbWFsbCxcbiAgICAgICAgICAgICAgICBtaW5pbXVtOiB0aGlzLl9kZWYuaXRlbXMubGVuZ3RoLFxuICAgICAgICAgICAgICAgIGluY2x1c2l2ZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBleGFjdDogZmFsc2UsXG4gICAgICAgICAgICAgICAgdHlwZTogXCJhcnJheVwiXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlc3QgPSB0aGlzLl9kZWYucmVzdDtcbiAgICAgICAgaWYgKCFyZXN0ICYmIGN0eC5kYXRhLmxlbmd0aCA+IHRoaXMuX2RlZi5pdGVtcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS50b29fYmlnLFxuICAgICAgICAgICAgICAgIG1heGltdW06IHRoaXMuX2RlZi5pdGVtcy5sZW5ndGgsXG4gICAgICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgICAgIGV4YWN0OiBmYWxzZSxcbiAgICAgICAgICAgICAgICB0eXBlOiBcImFycmF5XCJcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaXRlbXMgPSBbXG4gICAgICAgICAgICAuLi5jdHguZGF0YVxuICAgICAgICBdLm1hcCgoaXRlbSwgaXRlbUluZGV4KT0+e1xuICAgICAgICAgICAgY29uc3Qgc2NoZW1hID0gdGhpcy5fZGVmLml0ZW1zW2l0ZW1JbmRleF0gfHwgdGhpcy5fZGVmLnJlc3Q7XG4gICAgICAgICAgICBpZiAoIXNjaGVtYSkgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICByZXR1cm4gc2NoZW1hLl9wYXJzZShuZXcgUGFyc2VJbnB1dExhenlQYXRoKGN0eCwgaXRlbSwgY3R4LnBhdGgsIGl0ZW1JbmRleCkpO1xuICAgICAgICB9KS5maWx0ZXIoKHgpPT4hIXgpOyAvLyBmaWx0ZXIgbnVsbHNcbiAgICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChpdGVtcykudGhlbigocmVzdWx0cyk9PntcbiAgICAgICAgICAgICAgICByZXR1cm4gUGFyc2VTdGF0dXMubWVyZ2VBcnJheShzdGF0dXMsIHJlc3VsdHMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gUGFyc2VTdGF0dXMubWVyZ2VBcnJheShzdGF0dXMsIGl0ZW1zKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgaXRlbXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYuaXRlbXM7XG4gICAgfVxuICAgIHJlc3QocmVzdCkge1xuICAgICAgICByZXR1cm4gbmV3IFpvZFR1cGxlKHtcbiAgICAgICAgICAgIC4uLnRoaXMuX2RlZixcbiAgICAgICAgICAgIHJlc3RcbiAgICAgICAgfSk7XG4gICAgfVxufVxuWm9kVHVwbGUuY3JlYXRlID0gKHNjaGVtYXMsIHBhcmFtcyk9PntcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoc2NoZW1hcykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiWW91IG11c3QgcGFzcyBhbiBhcnJheSBvZiBzY2hlbWFzIHRvIHoudHVwbGUoWyAuLi4gXSlcIik7XG4gICAgfVxuICAgIHJldHVybiBuZXcgWm9kVHVwbGUoe1xuICAgICAgICBpdGVtczogc2NoZW1hcyxcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RUdXBsZSxcbiAgICAgICAgcmVzdDogbnVsbCxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59O1xuZXhwb3J0IGNsYXNzIFpvZFJlY29yZCBleHRlbmRzIFpvZFR5cGUge1xuICAgIGdldCBrZXlTY2hlbWEoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYua2V5VHlwZTtcbiAgICB9XG4gICAgZ2V0IHZhbHVlU2NoZW1hKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmLnZhbHVlVHlwZTtcbiAgICB9XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHsgc3RhdHVzLCBjdHggfSA9IHRoaXMuX3Byb2Nlc3NJbnB1dFBhcmFtcyhpbnB1dCk7XG4gICAgICAgIGlmIChjdHgucGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS5vYmplY3QpIHtcbiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3R5cGUsXG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IFpvZFBhcnNlZFR5cGUub2JqZWN0LFxuICAgICAgICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwYWlycyA9IFtdO1xuICAgICAgICBjb25zdCBrZXlUeXBlID0gdGhpcy5fZGVmLmtleVR5cGU7XG4gICAgICAgIGNvbnN0IHZhbHVlVHlwZSA9IHRoaXMuX2RlZi52YWx1ZVR5cGU7XG4gICAgICAgIGZvcihjb25zdCBrZXkgaW4gY3R4LmRhdGEpe1xuICAgICAgICAgICAgcGFpcnMucHVzaCh7XG4gICAgICAgICAgICAgICAga2V5OiBrZXlUeXBlLl9wYXJzZShuZXcgUGFyc2VJbnB1dExhenlQYXRoKGN0eCwga2V5LCBjdHgucGF0aCwga2V5KSksXG4gICAgICAgICAgICAgICAgdmFsdWU6IHZhbHVlVHlwZS5fcGFyc2UobmV3IFBhcnNlSW5wdXRMYXp5UGF0aChjdHgsIGN0eC5kYXRhW2tleV0sIGN0eC5wYXRoLCBrZXkpKSxcbiAgICAgICAgICAgICAgICBhbHdheXNTZXQ6IGtleSBpbiBjdHguZGF0YVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMpIHtcbiAgICAgICAgICAgIHJldHVybiBQYXJzZVN0YXR1cy5tZXJnZU9iamVjdEFzeW5jKHN0YXR1cywgcGFpcnMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIFBhcnNlU3RhdHVzLm1lcmdlT2JqZWN0U3luYyhzdGF0dXMsIHBhaXJzKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgZWxlbWVudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi52YWx1ZVR5cGU7XG4gICAgfVxuICAgIHN0YXRpYyBjcmVhdGUoZmlyc3QsIHNlY29uZCwgdGhpcmQpIHtcbiAgICAgICAgaWYgKHNlY29uZCBpbnN0YW5jZW9mIFpvZFR5cGUpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgWm9kUmVjb3JkKHtcbiAgICAgICAgICAgICAgICBrZXlUeXBlOiBmaXJzdCxcbiAgICAgICAgICAgICAgICB2YWx1ZVR5cGU6IHNlY29uZCxcbiAgICAgICAgICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZFJlY29yZCxcbiAgICAgICAgICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHRoaXJkKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBab2RSZWNvcmQoe1xuICAgICAgICAgICAga2V5VHlwZTogWm9kU3RyaW5nLmNyZWF0ZSgpLFxuICAgICAgICAgICAgdmFsdWVUeXBlOiBmaXJzdCxcbiAgICAgICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kUmVjb3JkLFxuICAgICAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhzZWNvbmQpXG4gICAgICAgIH0pO1xuICAgIH1cbn1cbmV4cG9ydCBjbGFzcyBab2RNYXAgZXh0ZW5kcyBab2RUeXBlIHtcbiAgICBnZXQga2V5U2NoZW1hKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmLmtleVR5cGU7XG4gICAgfVxuICAgIGdldCB2YWx1ZVNjaGVtYSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi52YWx1ZVR5cGU7XG4gICAgfVxuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBjb25zdCB7IHN0YXR1cywgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpO1xuICAgICAgICBpZiAoY3R4LnBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUubWFwKSB7XG4gICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLm1hcCxcbiAgICAgICAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qga2V5VHlwZSA9IHRoaXMuX2RlZi5rZXlUeXBlO1xuICAgICAgICBjb25zdCB2YWx1ZVR5cGUgPSB0aGlzLl9kZWYudmFsdWVUeXBlO1xuICAgICAgICBjb25zdCBwYWlycyA9IFtcbiAgICAgICAgICAgIC4uLmN0eC5kYXRhLmVudHJpZXMoKVxuICAgICAgICBdLm1hcCgoW2tleSwgdmFsdWVdLCBpbmRleCk9PntcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAga2V5OiBrZXlUeXBlLl9wYXJzZShuZXcgUGFyc2VJbnB1dExhenlQYXRoKGN0eCwga2V5LCBjdHgucGF0aCwgW1xuICAgICAgICAgICAgICAgICAgICBpbmRleCxcbiAgICAgICAgICAgICAgICAgICAgXCJrZXlcIlxuICAgICAgICAgICAgICAgIF0pKSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogdmFsdWVUeXBlLl9wYXJzZShuZXcgUGFyc2VJbnB1dExhenlQYXRoKGN0eCwgdmFsdWUsIGN0eC5wYXRoLCBbXG4gICAgICAgICAgICAgICAgICAgIGluZGV4LFxuICAgICAgICAgICAgICAgICAgICBcInZhbHVlXCJcbiAgICAgICAgICAgICAgICBdKSlcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoY3R4LmNvbW1vbi5hc3luYykge1xuICAgICAgICAgICAgY29uc3QgZmluYWxNYXAgPSBuZXcgTWFwKCk7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCkudGhlbihhc3luYyAoKT0+e1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgcGFpciBvZiBwYWlycyl7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGtleSA9IGF3YWl0IHBhaXIua2V5O1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGF3YWl0IHBhaXIudmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChrZXkuc3RhdHVzID09PSBcImFib3J0ZWRcIiB8fCB2YWx1ZS5zdGF0dXMgPT09IFwiYWJvcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoa2V5LnN0YXR1cyA9PT0gXCJkaXJ0eVwiIHx8IHZhbHVlLnN0YXR1cyA9PT0gXCJkaXJ0eVwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBmaW5hbE1hcC5zZXQoa2V5LnZhbHVlLCB2YWx1ZS52YWx1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1czogc3RhdHVzLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogZmluYWxNYXBcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBmaW5hbE1hcCA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgcGFpciBvZiBwYWlycyl7XG4gICAgICAgICAgICAgICAgY29uc3Qga2V5ID0gcGFpci5rZXk7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBwYWlyLnZhbHVlO1xuICAgICAgICAgICAgICAgIGlmIChrZXkuc3RhdHVzID09PSBcImFib3J0ZWRcIiB8fCB2YWx1ZS5zdGF0dXMgPT09IFwiYWJvcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoa2V5LnN0YXR1cyA9PT0gXCJkaXJ0eVwiIHx8IHZhbHVlLnN0YXR1cyA9PT0gXCJkaXJ0eVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBmaW5hbE1hcC5zZXQoa2V5LnZhbHVlLCB2YWx1ZS52YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHN0YXR1czogc3RhdHVzLnZhbHVlLFxuICAgICAgICAgICAgICAgIHZhbHVlOiBmaW5hbE1hcFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgIH1cbn1cblpvZE1hcC5jcmVhdGUgPSAoa2V5VHlwZSwgdmFsdWVUeXBlLCBwYXJhbXMpPT57XG4gICAgcmV0dXJuIG5ldyBab2RNYXAoe1xuICAgICAgICB2YWx1ZVR5cGUsXG4gICAgICAgIGtleVR5cGUsXG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kTWFwLFxuICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn07XG5leHBvcnQgY2xhc3MgWm9kU2V0IGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHsgc3RhdHVzLCBjdHggfSA9IHRoaXMuX3Byb2Nlc3NJbnB1dFBhcmFtcyhpbnB1dCk7XG4gICAgICAgIGlmIChjdHgucGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS5zZXQpIHtcbiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3R5cGUsXG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IFpvZFBhcnNlZFR5cGUuc2V0LFxuICAgICAgICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBkZWYgPSB0aGlzLl9kZWY7XG4gICAgICAgIGlmIChkZWYubWluU2l6ZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKGN0eC5kYXRhLnNpemUgPCBkZWYubWluU2l6ZS52YWx1ZSkge1xuICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX3NtYWxsLFxuICAgICAgICAgICAgICAgICAgICBtaW5pbXVtOiBkZWYubWluU2l6ZS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJzZXRcIixcbiAgICAgICAgICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBleGFjdDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGRlZi5taW5TaXplLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoZGVmLm1heFNpemUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGlmIChjdHguZGF0YS5zaXplID4gZGVmLm1heFNpemUudmFsdWUpIHtcbiAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLnRvb19iaWcsXG4gICAgICAgICAgICAgICAgICAgIG1heGltdW06IGRlZi5tYXhTaXplLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiBcInNldFwiLFxuICAgICAgICAgICAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGV4YWN0OiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogZGVmLm1heFNpemUubWVzc2FnZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHZhbHVlVHlwZSA9IHRoaXMuX2RlZi52YWx1ZVR5cGU7XG4gICAgICAgIGZ1bmN0aW9uIGZpbmFsaXplU2V0KGVsZW1lbnRzKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJzZWRTZXQgPSBuZXcgU2V0KCk7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgZWxlbWVudHMpe1xuICAgICAgICAgICAgICAgIGlmIChlbGVtZW50LnN0YXR1cyA9PT0gXCJhYm9ydGVkXCIpIHJldHVybiBJTlZBTElEO1xuICAgICAgICAgICAgICAgIGlmIChlbGVtZW50LnN0YXR1cyA9PT0gXCJkaXJ0eVwiKSBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICBwYXJzZWRTZXQuYWRkKGVsZW1lbnQudmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBzdGF0dXM6IHN0YXR1cy52YWx1ZSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogcGFyc2VkU2V0XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGVsZW1lbnRzID0gW1xuICAgICAgICAgICAgLi4uY3R4LmRhdGEudmFsdWVzKClcbiAgICAgICAgXS5tYXAoKGl0ZW0sIGkpPT52YWx1ZVR5cGUuX3BhcnNlKG5ldyBQYXJzZUlucHV0TGF6eVBhdGgoY3R4LCBpdGVtLCBjdHgucGF0aCwgaSkpKTtcbiAgICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChlbGVtZW50cykudGhlbigoZWxlbWVudHMpPT5maW5hbGl6ZVNldChlbGVtZW50cykpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGZpbmFsaXplU2V0KGVsZW1lbnRzKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBtaW4obWluU2l6ZSwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gbmV3IFpvZFNldCh7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICBtaW5TaXplOiB7XG4gICAgICAgICAgICAgICAgdmFsdWU6IG1pblNpemUsXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBtYXgobWF4U2l6ZSwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gbmV3IFpvZFNldCh7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICBtYXhTaXplOiB7XG4gICAgICAgICAgICAgICAgdmFsdWU6IG1heFNpemUsXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBzaXplKHNpemUsIG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWluKHNpemUsIG1lc3NhZ2UpLm1heChzaXplLCBtZXNzYWdlKTtcbiAgICB9XG4gICAgbm9uZW1wdHkobWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5taW4oMSwgbWVzc2FnZSk7XG4gICAgfVxufVxuWm9kU2V0LmNyZWF0ZSA9ICh2YWx1ZVR5cGUsIHBhcmFtcyk9PntcbiAgICByZXR1cm4gbmV3IFpvZFNldCh7XG4gICAgICAgIHZhbHVlVHlwZSxcbiAgICAgICAgbWluU2l6ZTogbnVsbCxcbiAgICAgICAgbWF4U2l6ZTogbnVsbCxcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RTZXQsXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufTtcbmV4cG9ydCBjbGFzcyBab2RGdW5jdGlvbiBleHRlbmRzIFpvZFR5cGUge1xuICAgIGNvbnN0cnVjdG9yKCl7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMudmFsaWRhdGUgPSB0aGlzLmltcGxlbWVudDtcbiAgICB9XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpO1xuICAgICAgICBpZiAoY3R4LnBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUuZnVuY3Rpb24pIHtcbiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3R5cGUsXG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IFpvZFBhcnNlZFR5cGUuZnVuY3Rpb24sXG4gICAgICAgICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIG1ha2VBcmdzSXNzdWUoYXJncywgZXJyb3IpIHtcbiAgICAgICAgICAgIHJldHVybiBtYWtlSXNzdWUoe1xuICAgICAgICAgICAgICAgIGRhdGE6IGFyZ3MsXG4gICAgICAgICAgICAgICAgcGF0aDogY3R4LnBhdGgsXG4gICAgICAgICAgICAgICAgZXJyb3JNYXBzOiBbXG4gICAgICAgICAgICAgICAgICAgIGN0eC5jb21tb24uY29udGV4dHVhbEVycm9yTWFwLFxuICAgICAgICAgICAgICAgICAgICBjdHguc2NoZW1hRXJyb3JNYXAsXG4gICAgICAgICAgICAgICAgICAgIGdldEVycm9yTWFwKCksXG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHRFcnJvck1hcFxuICAgICAgICAgICAgICAgIF0uZmlsdGVyKCh4KT0+ISF4KSxcbiAgICAgICAgICAgICAgICBpc3N1ZURhdGE6IHtcbiAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfYXJndW1lbnRzLFxuICAgICAgICAgICAgICAgICAgICBhcmd1bWVudHNFcnJvcjogZXJyb3JcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBtYWtlUmV0dXJuc0lzc3VlKHJldHVybnMsIGVycm9yKSB7XG4gICAgICAgICAgICByZXR1cm4gbWFrZUlzc3VlKHtcbiAgICAgICAgICAgICAgICBkYXRhOiByZXR1cm5zLFxuICAgICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgICAgIGVycm9yTWFwczogW1xuICAgICAgICAgICAgICAgICAgICBjdHguY29tbW9uLmNvbnRleHR1YWxFcnJvck1hcCxcbiAgICAgICAgICAgICAgICAgICAgY3R4LnNjaGVtYUVycm9yTWFwLFxuICAgICAgICAgICAgICAgICAgICBnZXRFcnJvck1hcCgpLFxuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0RXJyb3JNYXBcbiAgICAgICAgICAgICAgICBdLmZpbHRlcigoeCk9PiEheCksXG4gICAgICAgICAgICAgICAgaXNzdWVEYXRhOiB7XG4gICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3JldHVybl90eXBlLFxuICAgICAgICAgICAgICAgICAgICByZXR1cm5UeXBlRXJyb3I6IGVycm9yXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgICAgZXJyb3JNYXA6IGN0eC5jb21tb24uY29udGV4dHVhbEVycm9yTWFwXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGZuID0gY3R4LmRhdGE7XG4gICAgICAgIGlmICh0aGlzLl9kZWYucmV0dXJucyBpbnN0YW5jZW9mIFpvZFByb21pc2UpIHtcbiAgICAgICAgICAgIC8vIFdvdWxkIGxvdmUgYSB3YXkgdG8gYXZvaWQgZGlzYWJsaW5nIHRoaXMgcnVsZSwgYnV0IHdlIG5lZWRcbiAgICAgICAgICAgIC8vIGFuIGFsaWFzICh1c2luZyBhbiBhcnJvdyBmdW5jdGlvbiB3YXMgd2hhdCBjYXVzZWQgMjY1MSkuXG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXRoaXMtYWxpYXNcbiAgICAgICAgICAgIGNvbnN0IG1lID0gdGhpcztcbiAgICAgICAgICAgIHJldHVybiBPSyhhc3luYyBmdW5jdGlvbiguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgWm9kRXJyb3IoW10pO1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcnNlZEFyZ3MgPSBhd2FpdCBtZS5fZGVmLmFyZ3MucGFyc2VBc3luYyhhcmdzLCBwYXJhbXMpLmNhdGNoKChlKT0+e1xuICAgICAgICAgICAgICAgICAgICBlcnJvci5hZGRJc3N1ZShtYWtlQXJnc0lzc3VlKGFyZ3MsIGUpKTtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgUmVmbGVjdC5hcHBseShmbiwgdGhpcywgcGFyc2VkQXJncyk7XG4gICAgICAgICAgICAgICAgY29uc3QgcGFyc2VkUmV0dXJucyA9IGF3YWl0IG1lLl9kZWYucmV0dXJucy5fZGVmLnR5cGUucGFyc2VBc3luYyhyZXN1bHQsIHBhcmFtcykuY2F0Y2goKGUpPT57XG4gICAgICAgICAgICAgICAgICAgIGVycm9yLmFkZElzc3VlKG1ha2VSZXR1cm5zSXNzdWUocmVzdWx0LCBlKSk7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZWRSZXR1cm5zO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBXb3VsZCBsb3ZlIGEgd2F5IHRvIGF2b2lkIGRpc2FibGluZyB0aGlzIHJ1bGUsIGJ1dCB3ZSBuZWVkXG4gICAgICAgICAgICAvLyBhbiBhbGlhcyAodXNpbmcgYW4gYXJyb3cgZnVuY3Rpb24gd2FzIHdoYXQgY2F1c2VkIDI2NTEpLlxuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby10aGlzLWFsaWFzXG4gICAgICAgICAgICBjb25zdCBtZSA9IHRoaXM7XG4gICAgICAgICAgICByZXR1cm4gT0soZnVuY3Rpb24oLi4uYXJncykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcnNlZEFyZ3MgPSBtZS5fZGVmLmFyZ3Muc2FmZVBhcnNlKGFyZ3MsIHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgaWYgKCFwYXJzZWRBcmdzLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFpvZEVycm9yKFtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1ha2VBcmdzSXNzdWUoYXJncywgcGFyc2VkQXJncy5lcnJvcilcbiAgICAgICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IFJlZmxlY3QuYXBwbHkoZm4sIHRoaXMsIHBhcnNlZEFyZ3MuZGF0YSk7XG4gICAgICAgICAgICAgICAgY29uc3QgcGFyc2VkUmV0dXJucyA9IG1lLl9kZWYucmV0dXJucy5zYWZlUGFyc2UocmVzdWx0LCBwYXJhbXMpO1xuICAgICAgICAgICAgICAgIGlmICghcGFyc2VkUmV0dXJucy5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBab2RFcnJvcihbXG4gICAgICAgICAgICAgICAgICAgICAgICBtYWtlUmV0dXJuc0lzc3VlKHJlc3VsdCwgcGFyc2VkUmV0dXJucy5lcnJvcilcbiAgICAgICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZWRSZXR1cm5zLmRhdGE7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBwYXJhbWV0ZXJzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmLmFyZ3M7XG4gICAgfVxuICAgIHJldHVyblR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYucmV0dXJucztcbiAgICB9XG4gICAgYXJncyguLi5pdGVtcykge1xuICAgICAgICByZXR1cm4gbmV3IFpvZEZ1bmN0aW9uKHtcbiAgICAgICAgICAgIC4uLnRoaXMuX2RlZixcbiAgICAgICAgICAgIGFyZ3M6IFpvZFR1cGxlLmNyZWF0ZShpdGVtcykucmVzdChab2RVbmtub3duLmNyZWF0ZSgpKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJucyhyZXR1cm5UeXBlKSB7XG4gICAgICAgIHJldHVybiBuZXcgWm9kRnVuY3Rpb24oe1xuICAgICAgICAgICAgLi4udGhpcy5fZGVmLFxuICAgICAgICAgICAgcmV0dXJuczogcmV0dXJuVHlwZVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgaW1wbGVtZW50KGZ1bmMpIHtcbiAgICAgICAgY29uc3QgdmFsaWRhdGVkRnVuYyA9IHRoaXMucGFyc2UoZnVuYyk7XG4gICAgICAgIHJldHVybiB2YWxpZGF0ZWRGdW5jO1xuICAgIH1cbiAgICBzdHJpY3RJbXBsZW1lbnQoZnVuYykge1xuICAgICAgICBjb25zdCB2YWxpZGF0ZWRGdW5jID0gdGhpcy5wYXJzZShmdW5jKTtcbiAgICAgICAgcmV0dXJuIHZhbGlkYXRlZEZ1bmM7XG4gICAgfVxuICAgIHN0YXRpYyBjcmVhdGUoYXJncywgcmV0dXJucywgcGFyYW1zKSB7XG4gICAgICAgIHJldHVybiBuZXcgWm9kRnVuY3Rpb24oe1xuICAgICAgICAgICAgYXJnczogYXJncyA/IGFyZ3MgOiBab2RUdXBsZS5jcmVhdGUoW10pLnJlc3QoWm9kVW5rbm93bi5jcmVhdGUoKSksXG4gICAgICAgICAgICByZXR1cm5zOiByZXR1cm5zIHx8IFpvZFVua25vd24uY3JlYXRlKCksXG4gICAgICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEZ1bmN0aW9uLFxuICAgICAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgICAgIH0pO1xuICAgIH1cbn1cbmV4cG9ydCBjbGFzcyBab2RMYXp5IGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgZ2V0IHNjaGVtYSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi5nZXR0ZXIoKTtcbiAgICB9XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpO1xuICAgICAgICBjb25zdCBsYXp5U2NoZW1hID0gdGhpcy5fZGVmLmdldHRlcigpO1xuICAgICAgICByZXR1cm4gbGF6eVNjaGVtYS5fcGFyc2Uoe1xuICAgICAgICAgICAgZGF0YTogY3R4LmRhdGEsXG4gICAgICAgICAgICBwYXRoOiBjdHgucGF0aCxcbiAgICAgICAgICAgIHBhcmVudDogY3R4XG4gICAgICAgIH0pO1xuICAgIH1cbn1cblpvZExhenkuY3JlYXRlID0gKGdldHRlciwgcGFyYW1zKT0+e1xuICAgIHJldHVybiBuZXcgWm9kTGF6eSh7XG4gICAgICAgIGdldHRlcjogZ2V0dGVyLFxuICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZExhenksXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufTtcbmV4cG9ydCBjbGFzcyBab2RMaXRlcmFsIGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGlmIChpbnB1dC5kYXRhICE9PSB0aGlzLl9kZWYudmFsdWUpIHtcbiAgICAgICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTtcbiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgIHJlY2VpdmVkOiBjdHguZGF0YSxcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9saXRlcmFsLFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiB0aGlzLl9kZWYudmFsdWVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN0YXR1czogXCJ2YWxpZFwiLFxuICAgICAgICAgICAgdmFsdWU6IGlucHV0LmRhdGFcbiAgICAgICAgfTtcbiAgICB9XG4gICAgZ2V0IHZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmLnZhbHVlO1xuICAgIH1cbn1cblpvZExpdGVyYWwuY3JlYXRlID0gKHZhbHVlLCBwYXJhbXMpPT57XG4gICAgcmV0dXJuIG5ldyBab2RMaXRlcmFsKHtcbiAgICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZExpdGVyYWwsXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufTtcbmZ1bmN0aW9uIGNyZWF0ZVpvZEVudW0odmFsdWVzLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IFpvZEVudW0oe1xuICAgICAgICB2YWx1ZXMsXG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kRW51bSxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgY2xhc3MgWm9kRW51bSBleHRlbmRzIFpvZFR5cGUge1xuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBpZiAodHlwZW9mIGlucHV0LmRhdGEgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTtcbiAgICAgICAgICAgIGNvbnN0IGV4cGVjdGVkVmFsdWVzID0gdGhpcy5fZGVmLnZhbHVlcztcbiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiB1dGlsLmpvaW5WYWx1ZXMoZXhwZWN0ZWRWYWx1ZXMpLFxuICAgICAgICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZSxcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5fY2FjaGUpIHtcbiAgICAgICAgICAgIHRoaXMuX2NhY2hlID0gbmV3IFNldCh0aGlzLl9kZWYudmFsdWVzKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMuX2NhY2hlLmhhcyhpbnB1dC5kYXRhKSkge1xuICAgICAgICAgICAgY29uc3QgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQpO1xuICAgICAgICAgICAgY29uc3QgZXhwZWN0ZWRWYWx1ZXMgPSB0aGlzLl9kZWYudmFsdWVzO1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5kYXRhLFxuICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX2VudW1fdmFsdWUsXG4gICAgICAgICAgICAgICAgb3B0aW9uczogZXhwZWN0ZWRWYWx1ZXNcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIE9LKGlucHV0LmRhdGEpO1xuICAgIH1cbiAgICBnZXQgb3B0aW9ucygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi52YWx1ZXM7XG4gICAgfVxuICAgIGdldCBlbnVtKCkge1xuICAgICAgICBjb25zdCBlbnVtVmFsdWVzID0ge307XG4gICAgICAgIGZvciAoY29uc3QgdmFsIG9mIHRoaXMuX2RlZi52YWx1ZXMpe1xuICAgICAgICAgICAgZW51bVZhbHVlc1t2YWxdID0gdmFsO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBlbnVtVmFsdWVzO1xuICAgIH1cbiAgICBnZXQgVmFsdWVzKCkge1xuICAgICAgICBjb25zdCBlbnVtVmFsdWVzID0ge307XG4gICAgICAgIGZvciAoY29uc3QgdmFsIG9mIHRoaXMuX2RlZi52YWx1ZXMpe1xuICAgICAgICAgICAgZW51bVZhbHVlc1t2YWxdID0gdmFsO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBlbnVtVmFsdWVzO1xuICAgIH1cbiAgICBnZXQgRW51bSgpIHtcbiAgICAgICAgY29uc3QgZW51bVZhbHVlcyA9IHt9O1xuICAgICAgICBmb3IgKGNvbnN0IHZhbCBvZiB0aGlzLl9kZWYudmFsdWVzKXtcbiAgICAgICAgICAgIGVudW1WYWx1ZXNbdmFsXSA9IHZhbDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZW51bVZhbHVlcztcbiAgICB9XG4gICAgZXh0cmFjdCh2YWx1ZXMsIG5ld0RlZiA9IHRoaXMuX2RlZikge1xuICAgICAgICByZXR1cm4gWm9kRW51bS5jcmVhdGUodmFsdWVzLCB7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICAuLi5uZXdEZWZcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGV4Y2x1ZGUodmFsdWVzLCBuZXdEZWYgPSB0aGlzLl9kZWYpIHtcbiAgICAgICAgcmV0dXJuIFpvZEVudW0uY3JlYXRlKHRoaXMub3B0aW9ucy5maWx0ZXIoKG9wdCk9PiF2YWx1ZXMuaW5jbHVkZXMob3B0KSksIHtcbiAgICAgICAgICAgIC4uLnRoaXMuX2RlZixcbiAgICAgICAgICAgIC4uLm5ld0RlZlxuICAgICAgICB9KTtcbiAgICB9XG59XG5ab2RFbnVtLmNyZWF0ZSA9IGNyZWF0ZVpvZEVudW07XG5leHBvcnQgY2xhc3MgWm9kTmF0aXZlRW51bSBleHRlbmRzIFpvZFR5cGUge1xuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBjb25zdCBuYXRpdmVFbnVtVmFsdWVzID0gdXRpbC5nZXRWYWxpZEVudW1WYWx1ZXModGhpcy5fZGVmLnZhbHVlcyk7XG4gICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTtcbiAgICAgICAgaWYgKGN0eC5wYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLnN0cmluZyAmJiBjdHgucGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS5udW1iZXIpIHtcbiAgICAgICAgICAgIGNvbnN0IGV4cGVjdGVkVmFsdWVzID0gdXRpbC5vYmplY3RWYWx1ZXMobmF0aXZlRW51bVZhbHVlcyk7XG4gICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogdXRpbC5qb2luVmFsdWVzKGV4cGVjdGVkVmFsdWVzKSxcbiAgICAgICAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGUsXG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMuX2NhY2hlKSB7XG4gICAgICAgICAgICB0aGlzLl9jYWNoZSA9IG5ldyBTZXQodXRpbC5nZXRWYWxpZEVudW1WYWx1ZXModGhpcy5fZGVmLnZhbHVlcykpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5fY2FjaGUuaGFzKGlucHV0LmRhdGEpKSB7XG4gICAgICAgICAgICBjb25zdCBleHBlY3RlZFZhbHVlcyA9IHV0aWwub2JqZWN0VmFsdWVzKG5hdGl2ZUVudW1WYWx1ZXMpO1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5kYXRhLFxuICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX2VudW1fdmFsdWUsXG4gICAgICAgICAgICAgICAgb3B0aW9uczogZXhwZWN0ZWRWYWx1ZXNcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIE9LKGlucHV0LmRhdGEpO1xuICAgIH1cbiAgICBnZXQgZW51bSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi52YWx1ZXM7XG4gICAgfVxufVxuWm9kTmF0aXZlRW51bS5jcmVhdGUgPSAodmFsdWVzLCBwYXJhbXMpPT57XG4gICAgcmV0dXJuIG5ldyBab2ROYXRpdmVFbnVtKHtcbiAgICAgICAgdmFsdWVzOiB2YWx1ZXMsXG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kTmF0aXZlRW51bSxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59O1xuZXhwb3J0IGNsYXNzIFpvZFByb21pc2UgZXh0ZW5kcyBab2RUeXBlIHtcbiAgICB1bndyYXAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYudHlwZTtcbiAgICB9XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpO1xuICAgICAgICBpZiAoY3R4LnBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUucHJvbWlzZSAmJiBjdHguY29tbW9uLmFzeW5jID09PSBmYWxzZSkge1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSxcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5wcm9taXNlLFxuICAgICAgICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwcm9taXNpZmllZCA9IGN0eC5wYXJzZWRUeXBlID09PSBab2RQYXJzZWRUeXBlLnByb21pc2UgPyBjdHguZGF0YSA6IFByb21pc2UucmVzb2x2ZShjdHguZGF0YSk7XG4gICAgICAgIHJldHVybiBPSyhwcm9taXNpZmllZC50aGVuKChkYXRhKT0+e1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi50eXBlLnBhcnNlQXN5bmMoZGF0YSwge1xuICAgICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgICAgIGVycm9yTWFwOiBjdHguY29tbW9uLmNvbnRleHR1YWxFcnJvck1hcFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pKTtcbiAgICB9XG59XG5ab2RQcm9taXNlLmNyZWF0ZSA9IChzY2hlbWEsIHBhcmFtcyk9PntcbiAgICByZXR1cm4gbmV3IFpvZFByb21pc2Uoe1xuICAgICAgICB0eXBlOiBzY2hlbWEsXG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kUHJvbWlzZSxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59O1xuZXhwb3J0IGNsYXNzIFpvZEVmZmVjdHMgZXh0ZW5kcyBab2RUeXBlIHtcbiAgICBpbm5lclR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYuc2NoZW1hO1xuICAgIH1cbiAgICBzb3VyY2VUeXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmLnNjaGVtYS5fZGVmLnR5cGVOYW1lID09PSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kRWZmZWN0cyA/IHRoaXMuX2RlZi5zY2hlbWEuc291cmNlVHlwZSgpIDogdGhpcy5fZGVmLnNjaGVtYTtcbiAgICB9XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHsgc3RhdHVzLCBjdHggfSA9IHRoaXMuX3Byb2Nlc3NJbnB1dFBhcmFtcyhpbnB1dCk7XG4gICAgICAgIGNvbnN0IGVmZmVjdCA9IHRoaXMuX2RlZi5lZmZlY3QgfHwgbnVsbDtcbiAgICAgICAgY29uc3QgY2hlY2tDdHggPSB7XG4gICAgICAgICAgICBhZGRJc3N1ZTogKGFyZyk9PntcbiAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIGFyZyk7XG4gICAgICAgICAgICAgICAgaWYgKGFyZy5mYXRhbCkge1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuYWJvcnQoKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHBhdGggKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBjdHgucGF0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgY2hlY2tDdHguYWRkSXNzdWUgPSBjaGVja0N0eC5hZGRJc3N1ZS5iaW5kKGNoZWNrQ3R4KTtcbiAgICAgICAgaWYgKGVmZmVjdC50eXBlID09PSBcInByZXByb2Nlc3NcIikge1xuICAgICAgICAgICAgY29uc3QgcHJvY2Vzc2VkID0gZWZmZWN0LnRyYW5zZm9ybShjdHguZGF0YSwgY2hlY2tDdHgpO1xuICAgICAgICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHByb2Nlc3NlZCkudGhlbihhc3luYyAocHJvY2Vzc2VkKT0+e1xuICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdHVzLnZhbHVlID09PSBcImFib3J0ZWRcIikgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuX2RlZi5zY2hlbWEuX3BhcnNlQXN5bmMoe1xuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YTogcHJvY2Vzc2VkLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGF0aDogY3R4LnBhdGgsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IGN0eFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5zdGF0dXMgPT09IFwiYWJvcnRlZFwiKSByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5zdGF0dXMgPT09IFwiZGlydHlcIikgcmV0dXJuIERJUlRZKHJlc3VsdC52YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMudmFsdWUgPT09IFwiZGlydHlcIikgcmV0dXJuIERJUlRZKHJlc3VsdC52YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChzdGF0dXMudmFsdWUgPT09IFwiYWJvcnRlZFwiKSByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSB0aGlzLl9kZWYuc2NoZW1hLl9wYXJzZVN5bmMoe1xuICAgICAgICAgICAgICAgICAgICBkYXRhOiBwcm9jZXNzZWQsXG4gICAgICAgICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IGN0eFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQuc3RhdHVzID09PSBcImFib3J0ZWRcIikgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5zdGF0dXMgPT09IFwiZGlydHlcIikgcmV0dXJuIERJUlRZKHJlc3VsdC52YWx1ZSk7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXR1cy52YWx1ZSA9PT0gXCJkaXJ0eVwiKSByZXR1cm4gRElSVFkocmVzdWx0LnZhbHVlKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChlZmZlY3QudHlwZSA9PT0gXCJyZWZpbmVtZW50XCIpIHtcbiAgICAgICAgICAgIGNvbnN0IGV4ZWN1dGVSZWZpbmVtZW50ID0gKGFjYyk9PntcbiAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSBlZmZlY3QucmVmaW5lbWVudChhY2MsIGNoZWNrQ3R4KTtcbiAgICAgICAgICAgICAgICBpZiAoY3R4LmNvbW1vbi5hc3luYykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkFzeW5jIHJlZmluZW1lbnQgZW5jb3VudGVyZWQgZHVyaW5nIHN5bmNocm9ub3VzIHBhcnNlIG9wZXJhdGlvbi4gVXNlIC5wYXJzZUFzeW5jIGluc3RlYWQuXCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmIChjdHguY29tbW9uLmFzeW5jID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGlubmVyID0gdGhpcy5fZGVmLnNjaGVtYS5fcGFyc2VTeW5jKHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YTogY3R4LmRhdGEsXG4gICAgICAgICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IGN0eFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGlmIChpbm5lci5zdGF0dXMgPT09IFwiYWJvcnRlZFwiKSByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgICAgICAgICBpZiAoaW5uZXIuc3RhdHVzID09PSBcImRpcnR5XCIpIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIC8vIHJldHVybiB2YWx1ZSBpcyBpZ25vcmVkXG4gICAgICAgICAgICAgICAgZXhlY3V0ZVJlZmluZW1lbnQoaW5uZXIudmFsdWUpO1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1czogc3RhdHVzLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogaW5uZXIudmFsdWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fZGVmLnNjaGVtYS5fcGFyc2VBc3luYyh7XG4gICAgICAgICAgICAgICAgICAgIGRhdGE6IGN0eC5kYXRhLFxuICAgICAgICAgICAgICAgICAgICBwYXRoOiBjdHgucGF0aCxcbiAgICAgICAgICAgICAgICAgICAgcGFyZW50OiBjdHhcbiAgICAgICAgICAgICAgICB9KS50aGVuKChpbm5lcik9PntcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlubmVyLnN0YXR1cyA9PT0gXCJhYm9ydGVkXCIpIHJldHVybiBJTlZBTElEO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaW5uZXIuc3RhdHVzID09PSBcImRpcnR5XCIpIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXhlY3V0ZVJlZmluZW1lbnQoaW5uZXIudmFsdWUpLnRoZW4oKCk9PntcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzOiBzdGF0dXMudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGlubmVyLnZhbHVlXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoZWZmZWN0LnR5cGUgPT09IFwidHJhbnNmb3JtXCIpIHtcbiAgICAgICAgICAgIGlmIChjdHguY29tbW9uLmFzeW5jID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGJhc2UgPSB0aGlzLl9kZWYuc2NoZW1hLl9wYXJzZVN5bmMoe1xuICAgICAgICAgICAgICAgICAgICBkYXRhOiBjdHguZGF0YSxcbiAgICAgICAgICAgICAgICAgICAgcGF0aDogY3R4LnBhdGgsXG4gICAgICAgICAgICAgICAgICAgIHBhcmVudDogY3R4XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgaWYgKCFpc1ZhbGlkKGJhc2UpKSByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSBlZmZlY3QudHJhbnNmb3JtKGJhc2UudmFsdWUsIGNoZWNrQ3R4KTtcbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEFzeW5jaHJvbm91cyB0cmFuc2Zvcm0gZW5jb3VudGVyZWQgZHVyaW5nIHN5bmNocm9ub3VzIHBhcnNlIG9wZXJhdGlvbi4gVXNlIC5wYXJzZUFzeW5jIGluc3RlYWQuYCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1czogc3RhdHVzLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogcmVzdWx0XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi5zY2hlbWEuX3BhcnNlQXN5bmMoe1xuICAgICAgICAgICAgICAgICAgICBkYXRhOiBjdHguZGF0YSxcbiAgICAgICAgICAgICAgICAgICAgcGF0aDogY3R4LnBhdGgsXG4gICAgICAgICAgICAgICAgICAgIHBhcmVudDogY3R4XG4gICAgICAgICAgICAgICAgfSkudGhlbigoYmFzZSk9PntcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc1ZhbGlkKGJhc2UpKSByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShlZmZlY3QudHJhbnNmb3JtKGJhc2UudmFsdWUsIGNoZWNrQ3R4KSkudGhlbigocmVzdWx0KT0+KHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXM6IHN0YXR1cy52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogcmVzdWx0XG4gICAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdXRpbC5hc3NlcnROZXZlcihlZmZlY3QpO1xuICAgIH1cbn1cblpvZEVmZmVjdHMuY3JlYXRlID0gKHNjaGVtYSwgZWZmZWN0LCBwYXJhbXMpPT57XG4gICAgcmV0dXJuIG5ldyBab2RFZmZlY3RzKHtcbiAgICAgICAgc2NoZW1hLFxuICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEVmZmVjdHMsXG4gICAgICAgIGVmZmVjdCxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59O1xuWm9kRWZmZWN0cy5jcmVhdGVXaXRoUHJlcHJvY2VzcyA9IChwcmVwcm9jZXNzLCBzY2hlbWEsIHBhcmFtcyk9PntcbiAgICByZXR1cm4gbmV3IFpvZEVmZmVjdHMoe1xuICAgICAgICBzY2hlbWEsXG4gICAgICAgIGVmZmVjdDoge1xuICAgICAgICAgICAgdHlwZTogXCJwcmVwcm9jZXNzXCIsXG4gICAgICAgICAgICB0cmFuc2Zvcm06IHByZXByb2Nlc3NcbiAgICAgICAgfSxcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RFZmZlY3RzLFxuICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn07XG5leHBvcnQgeyBab2RFZmZlY3RzIGFzIFpvZFRyYW5zZm9ybWVyIH07XG5leHBvcnQgY2xhc3MgWm9kT3B0aW9uYWwgZXh0ZW5kcyBab2RUeXBlIHtcbiAgICBfcGFyc2UoaW5wdXQpIHtcbiAgICAgICAgY29uc3QgcGFyc2VkVHlwZSA9IHRoaXMuX2dldFR5cGUoaW5wdXQpO1xuICAgICAgICBpZiAocGFyc2VkVHlwZSA9PT0gWm9kUGFyc2VkVHlwZS51bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBPSyh1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYuaW5uZXJUeXBlLl9wYXJzZShpbnB1dCk7XG4gICAgfVxuICAgIHVud3JhcCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi5pbm5lclR5cGU7XG4gICAgfVxufVxuWm9kT3B0aW9uYWwuY3JlYXRlID0gKHR5cGUsIHBhcmFtcyk9PntcbiAgICByZXR1cm4gbmV3IFpvZE9wdGlvbmFsKHtcbiAgICAgICAgaW5uZXJUeXBlOiB0eXBlLFxuICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE9wdGlvbmFsLFxuICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn07XG5leHBvcnQgY2xhc3MgWm9kTnVsbGFibGUgZXh0ZW5kcyBab2RUeXBlIHtcbiAgICBfcGFyc2UoaW5wdXQpIHtcbiAgICAgICAgY29uc3QgcGFyc2VkVHlwZSA9IHRoaXMuX2dldFR5cGUoaW5wdXQpO1xuICAgICAgICBpZiAocGFyc2VkVHlwZSA9PT0gWm9kUGFyc2VkVHlwZS5udWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gT0sobnVsbCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi5pbm5lclR5cGUuX3BhcnNlKGlucHV0KTtcbiAgICB9XG4gICAgdW53cmFwKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmLmlubmVyVHlwZTtcbiAgICB9XG59XG5ab2ROdWxsYWJsZS5jcmVhdGUgPSAodHlwZSwgcGFyYW1zKT0+e1xuICAgIHJldHVybiBuZXcgWm9kTnVsbGFibGUoe1xuICAgICAgICBpbm5lclR5cGU6IHR5cGUsXG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kTnVsbGFibGUsXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufTtcbmV4cG9ydCBjbGFzcyBab2REZWZhdWx0IGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpO1xuICAgICAgICBsZXQgZGF0YSA9IGN0eC5kYXRhO1xuICAgICAgICBpZiAoY3R4LnBhcnNlZFR5cGUgPT09IFpvZFBhcnNlZFR5cGUudW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBkYXRhID0gdGhpcy5fZGVmLmRlZmF1bHRWYWx1ZSgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYuaW5uZXJUeXBlLl9wYXJzZSh7XG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgcGF0aDogY3R4LnBhdGgsXG4gICAgICAgICAgICBwYXJlbnQ6IGN0eFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmVtb3ZlRGVmYXVsdCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi5pbm5lclR5cGU7XG4gICAgfVxufVxuWm9kRGVmYXVsdC5jcmVhdGUgPSAodHlwZSwgcGFyYW1zKT0+e1xuICAgIHJldHVybiBuZXcgWm9kRGVmYXVsdCh7XG4gICAgICAgIGlubmVyVHlwZTogdHlwZSxcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2REZWZhdWx0LFxuICAgICAgICBkZWZhdWx0VmFsdWU6IHR5cGVvZiBwYXJhbXMuZGVmYXVsdCA9PT0gXCJmdW5jdGlvblwiID8gcGFyYW1zLmRlZmF1bHQgOiAoKT0+cGFyYW1zLmRlZmF1bHQsXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufTtcbmV4cG9ydCBjbGFzcyBab2RDYXRjaCBleHRlbmRzIFpvZFR5cGUge1xuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBjb25zdCB7IGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTtcbiAgICAgICAgLy8gbmV3Q3R4IGlzIHVzZWQgdG8gbm90IGNvbGxlY3QgaXNzdWVzIGZyb20gaW5uZXIgdHlwZXMgaW4gY3R4XG4gICAgICAgIGNvbnN0IG5ld0N0eCA9IHtcbiAgICAgICAgICAgIC4uLmN0eCxcbiAgICAgICAgICAgIGNvbW1vbjoge1xuICAgICAgICAgICAgICAgIC4uLmN0eC5jb21tb24sXG4gICAgICAgICAgICAgICAgaXNzdWVzOiBbXVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCByZXN1bHQgPSB0aGlzLl9kZWYuaW5uZXJUeXBlLl9wYXJzZSh7XG4gICAgICAgICAgICBkYXRhOiBuZXdDdHguZGF0YSxcbiAgICAgICAgICAgIHBhdGg6IG5ld0N0eC5wYXRoLFxuICAgICAgICAgICAgcGFyZW50OiB7XG4gICAgICAgICAgICAgICAgLi4ubmV3Q3R4XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoaXNBc3luYyhyZXN1bHQpKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0LnRoZW4oKHJlc3VsdCk9PntcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXM6IFwidmFsaWRcIixcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHJlc3VsdC5zdGF0dXMgPT09IFwidmFsaWRcIiA/IHJlc3VsdC52YWx1ZSA6IHRoaXMuX2RlZi5jYXRjaFZhbHVlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldCBlcnJvciAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBab2RFcnJvcihuZXdDdHguY29tbW9uLmlzc3Vlcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQ6IG5ld0N0eC5kYXRhXG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBzdGF0dXM6IFwidmFsaWRcIixcbiAgICAgICAgICAgICAgICB2YWx1ZTogcmVzdWx0LnN0YXR1cyA9PT0gXCJ2YWxpZFwiID8gcmVzdWx0LnZhbHVlIDogdGhpcy5fZGVmLmNhdGNoVmFsdWUoe1xuICAgICAgICAgICAgICAgICAgICBnZXQgZXJyb3IgKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBab2RFcnJvcihuZXdDdHguY29tbW9uLmlzc3Vlcyk7XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGlucHV0OiBuZXdDdHguZGF0YVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfVxuICAgIHJlbW92ZUNhdGNoKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmLmlubmVyVHlwZTtcbiAgICB9XG59XG5ab2RDYXRjaC5jcmVhdGUgPSAodHlwZSwgcGFyYW1zKT0+e1xuICAgIHJldHVybiBuZXcgWm9kQ2F0Y2goe1xuICAgICAgICBpbm5lclR5cGU6IHR5cGUsXG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kQ2F0Y2gsXG4gICAgICAgIGNhdGNoVmFsdWU6IHR5cGVvZiBwYXJhbXMuY2F0Y2ggPT09IFwiZnVuY3Rpb25cIiA/IHBhcmFtcy5jYXRjaCA6ICgpPT5wYXJhbXMuY2F0Y2gsXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufTtcbmV4cG9ydCBjbGFzcyBab2ROYU4gZXh0ZW5kcyBab2RUeXBlIHtcbiAgICBfcGFyc2UoaW5wdXQpIHtcbiAgICAgICAgY29uc3QgcGFyc2VkVHlwZSA9IHRoaXMuX2dldFR5cGUoaW5wdXQpO1xuICAgICAgICBpZiAocGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS5uYW4pIHtcbiAgICAgICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTtcbiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3R5cGUsXG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IFpvZFBhcnNlZFR5cGUubmFuLFxuICAgICAgICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3RhdHVzOiBcInZhbGlkXCIsXG4gICAgICAgICAgICB2YWx1ZTogaW5wdXQuZGF0YVxuICAgICAgICB9O1xuICAgIH1cbn1cblpvZE5hTi5jcmVhdGUgPSAocGFyYW1zKT0+e1xuICAgIHJldHVybiBuZXcgWm9kTmFOKHtcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2ROYU4sXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufTtcbmV4cG9ydCBjb25zdCBCUkFORCA9IFN5bWJvbChcInpvZF9icmFuZFwiKTtcbmV4cG9ydCBjbGFzcyBab2RCcmFuZGVkIGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpO1xuICAgICAgICBjb25zdCBkYXRhID0gY3R4LmRhdGE7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYudHlwZS5fcGFyc2Uoe1xuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgcGFyZW50OiBjdHhcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHVud3JhcCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi50eXBlO1xuICAgIH1cbn1cbmV4cG9ydCBjbGFzcyBab2RQaXBlbGluZSBleHRlbmRzIFpvZFR5cGUge1xuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBjb25zdCB7IHN0YXR1cywgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpO1xuICAgICAgICBpZiAoY3R4LmNvbW1vbi5hc3luYykge1xuICAgICAgICAgICAgY29uc3QgaGFuZGxlQXN5bmMgPSBhc3luYyAoKT0+e1xuICAgICAgICAgICAgICAgIGNvbnN0IGluUmVzdWx0ID0gYXdhaXQgdGhpcy5fZGVmLmluLl9wYXJzZUFzeW5jKHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YTogY3R4LmRhdGEsXG4gICAgICAgICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IGN0eFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGlmIChpblJlc3VsdC5zdGF0dXMgPT09IFwiYWJvcnRlZFwiKSByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgICAgICAgICBpZiAoaW5SZXN1bHQuc3RhdHVzID09PSBcImRpcnR5XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBESVJUWShpblJlc3VsdC52YWx1ZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi5vdXQuX3BhcnNlQXN5bmMoe1xuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YTogaW5SZXN1bHQudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXRoOiBjdHgucGF0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudDogY3R4XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICByZXR1cm4gaGFuZGxlQXN5bmMoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGluUmVzdWx0ID0gdGhpcy5fZGVmLmluLl9wYXJzZVN5bmMoe1xuICAgICAgICAgICAgICAgIGRhdGE6IGN0eC5kYXRhLFxuICAgICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgICAgIHBhcmVudDogY3R4XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmIChpblJlc3VsdC5zdGF0dXMgPT09IFwiYWJvcnRlZFwiKSByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgICAgIGlmIChpblJlc3VsdC5zdGF0dXMgPT09IFwiZGlydHlcIikge1xuICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1czogXCJkaXJ0eVwiLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogaW5SZXN1bHQudmFsdWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fZGVmLm91dC5fcGFyc2VTeW5jKHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YTogaW5SZXN1bHQudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IGN0eFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHN0YXRpYyBjcmVhdGUoYSwgYikge1xuICAgICAgICByZXR1cm4gbmV3IFpvZFBpcGVsaW5lKHtcbiAgICAgICAgICAgIGluOiBhLFxuICAgICAgICAgICAgb3V0OiBiLFxuICAgICAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RQaXBlbGluZVxuICAgICAgICB9KTtcbiAgICB9XG59XG5leHBvcnQgY2xhc3MgWm9kUmVhZG9ubHkgZXh0ZW5kcyBab2RUeXBlIHtcbiAgICBfcGFyc2UoaW5wdXQpIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5fZGVmLmlubmVyVHlwZS5fcGFyc2UoaW5wdXQpO1xuICAgICAgICBjb25zdCBmcmVlemUgPSAoZGF0YSk9PntcbiAgICAgICAgICAgIGlmIChpc1ZhbGlkKGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgZGF0YS52YWx1ZSA9IE9iamVjdC5mcmVlemUoZGF0YS52YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZGF0YTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIGlzQXN5bmMocmVzdWx0KSA/IHJlc3VsdC50aGVuKChkYXRhKT0+ZnJlZXplKGRhdGEpKSA6IGZyZWV6ZShyZXN1bHQpO1xuICAgIH1cbiAgICB1bndyYXAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYuaW5uZXJUeXBlO1xuICAgIH1cbn1cblpvZFJlYWRvbmx5LmNyZWF0ZSA9ICh0eXBlLCBwYXJhbXMpPT57XG4gICAgcmV0dXJuIG5ldyBab2RSZWFkb25seSh7XG4gICAgICAgIGlubmVyVHlwZTogdHlwZSxcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RSZWFkb25seSxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59O1xuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8vLy8vLy8vLyAgICAgICAgICAgICAgICAgICAgLy8vLy8vLy8vL1xuLy8vLy8vLy8vLyAgICAgIHouY3VzdG9tICAgICAgLy8vLy8vLy8vL1xuLy8vLy8vLy8vLyAgICAgICAgICAgICAgICAgICAgLy8vLy8vLy8vL1xuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuZnVuY3Rpb24gY2xlYW5QYXJhbXMocGFyYW1zLCBkYXRhKSB7XG4gICAgY29uc3QgcCA9IHR5cGVvZiBwYXJhbXMgPT09IFwiZnVuY3Rpb25cIiA/IHBhcmFtcyhkYXRhKSA6IHR5cGVvZiBwYXJhbXMgPT09IFwic3RyaW5nXCIgPyB7XG4gICAgICAgIG1lc3NhZ2U6IHBhcmFtc1xuICAgIH0gOiBwYXJhbXM7XG4gICAgY29uc3QgcDIgPSB0eXBlb2YgcCA9PT0gXCJzdHJpbmdcIiA/IHtcbiAgICAgICAgbWVzc2FnZTogcFxuICAgIH0gOiBwO1xuICAgIHJldHVybiBwMjtcbn1cbmV4cG9ydCBmdW5jdGlvbiBjdXN0b20oY2hlY2ssIF9wYXJhbXMgPSB7fSwgLyoqXG4gKiBAZGVwcmVjYXRlZFxuICpcbiAqIFBhc3MgYGZhdGFsYCBpbnRvIHRoZSBwYXJhbXMgb2JqZWN0IGluc3RlYWQ6XG4gKlxuICogYGBgdHNcbiAqIHouc3RyaW5nKCkuY3VzdG9tKCh2YWwpID0+IHZhbC5sZW5ndGggPiA1LCB7IGZhdGFsOiBmYWxzZSB9KVxuICogYGBgXG4gKlxuICovIGZhdGFsKSB7XG4gICAgaWYgKGNoZWNrKSByZXR1cm4gWm9kQW55LmNyZWF0ZSgpLnN1cGVyUmVmaW5lKChkYXRhLCBjdHgpPT57XG4gICAgICAgIGNvbnN0IHIgPSBjaGVjayhkYXRhKTtcbiAgICAgICAgaWYgKHIgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm4gci50aGVuKChyKT0+e1xuICAgICAgICAgICAgICAgIGlmICghcikge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXJhbXMgPSBjbGVhblBhcmFtcyhfcGFyYW1zLCBkYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgX2ZhdGFsID0gcGFyYW1zLmZhdGFsID8/IGZhdGFsID8/IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGN0eC5hZGRJc3N1ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBcImN1c3RvbVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgLi4ucGFyYW1zLFxuICAgICAgICAgICAgICAgICAgICAgICAgZmF0YWw6IF9mYXRhbFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXIpIHtcbiAgICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IGNsZWFuUGFyYW1zKF9wYXJhbXMsIGRhdGEpO1xuICAgICAgICAgICAgY29uc3QgX2ZhdGFsID0gcGFyYW1zLmZhdGFsID8/IGZhdGFsID8/IHRydWU7XG4gICAgICAgICAgICBjdHguYWRkSXNzdWUoe1xuICAgICAgICAgICAgICAgIGNvZGU6IFwiY3VzdG9tXCIsXG4gICAgICAgICAgICAgICAgLi4ucGFyYW1zLFxuICAgICAgICAgICAgICAgIGZhdGFsOiBfZmF0YWxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICB9KTtcbiAgICByZXR1cm4gWm9kQW55LmNyZWF0ZSgpO1xufVxuZXhwb3J0IHsgWm9kVHlwZSBhcyBTY2hlbWEsIFpvZFR5cGUgYXMgWm9kU2NoZW1hIH07XG5leHBvcnQgY29uc3QgbGF0ZSA9IHtcbiAgICBvYmplY3Q6IFpvZE9iamVjdC5sYXp5Y3JlYXRlXG59O1xuZXhwb3J0IHZhciBab2RGaXJzdFBhcnR5VHlwZUtpbmQ7XG4oZnVuY3Rpb24oWm9kRmlyc3RQYXJ0eVR5cGVLaW5kKSB7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kU3RyaW5nXCJdID0gXCJab2RTdHJpbmdcIjtcbiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmRbXCJab2ROdW1iZXJcIl0gPSBcIlpvZE51bWJlclwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZE5hTlwiXSA9IFwiWm9kTmFOXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kQmlnSW50XCJdID0gXCJab2RCaWdJbnRcIjtcbiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmRbXCJab2RCb29sZWFuXCJdID0gXCJab2RCb29sZWFuXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kRGF0ZVwiXSA9IFwiWm9kRGF0ZVwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZFN5bWJvbFwiXSA9IFwiWm9kU3ltYm9sXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kVW5kZWZpbmVkXCJdID0gXCJab2RVbmRlZmluZWRcIjtcbiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmRbXCJab2ROdWxsXCJdID0gXCJab2ROdWxsXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kQW55XCJdID0gXCJab2RBbnlcIjtcbiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmRbXCJab2RVbmtub3duXCJdID0gXCJab2RVbmtub3duXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kTmV2ZXJcIl0gPSBcIlpvZE5ldmVyXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kVm9pZFwiXSA9IFwiWm9kVm9pZFwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZEFycmF5XCJdID0gXCJab2RBcnJheVwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZE9iamVjdFwiXSA9IFwiWm9kT2JqZWN0XCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kVW5pb25cIl0gPSBcIlpvZFVuaW9uXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kRGlzY3JpbWluYXRlZFVuaW9uXCJdID0gXCJab2REaXNjcmltaW5hdGVkVW5pb25cIjtcbiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmRbXCJab2RJbnRlcnNlY3Rpb25cIl0gPSBcIlpvZEludGVyc2VjdGlvblwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZFR1cGxlXCJdID0gXCJab2RUdXBsZVwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZFJlY29yZFwiXSA9IFwiWm9kUmVjb3JkXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kTWFwXCJdID0gXCJab2RNYXBcIjtcbiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmRbXCJab2RTZXRcIl0gPSBcIlpvZFNldFwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZEZ1bmN0aW9uXCJdID0gXCJab2RGdW5jdGlvblwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZExhenlcIl0gPSBcIlpvZExhenlcIjtcbiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmRbXCJab2RMaXRlcmFsXCJdID0gXCJab2RMaXRlcmFsXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kRW51bVwiXSA9IFwiWm9kRW51bVwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZEVmZmVjdHNcIl0gPSBcIlpvZEVmZmVjdHNcIjtcbiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmRbXCJab2ROYXRpdmVFbnVtXCJdID0gXCJab2ROYXRpdmVFbnVtXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kT3B0aW9uYWxcIl0gPSBcIlpvZE9wdGlvbmFsXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kTnVsbGFibGVcIl0gPSBcIlpvZE51bGxhYmxlXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kRGVmYXVsdFwiXSA9IFwiWm9kRGVmYXVsdFwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZENhdGNoXCJdID0gXCJab2RDYXRjaFwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZFByb21pc2VcIl0gPSBcIlpvZFByb21pc2VcIjtcbiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmRbXCJab2RCcmFuZGVkXCJdID0gXCJab2RCcmFuZGVkXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kUGlwZWxpbmVcIl0gPSBcIlpvZFBpcGVsaW5lXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kUmVhZG9ubHlcIl0gPSBcIlpvZFJlYWRvbmx5XCI7XG59KShab2RGaXJzdFBhcnR5VHlwZUtpbmQgfHwgKFpvZEZpcnN0UGFydHlUeXBlS2luZCA9IHt9KSk7XG4vLyByZXF1aXJlcyBUUyA0LjQrXG5jbGFzcyBDbGFzcyB7XG4gICAgY29uc3RydWN0b3IoLi4uXyl7fVxufVxuY29uc3QgaW5zdGFuY2VPZlR5cGUgPSAoLy8gY29uc3QgaW5zdGFuY2VPZlR5cGUgPSA8VCBleHRlbmRzIG5ldyAoLi4uYXJnczogYW55W10pID0+IGFueT4oXG5jbHMsIHBhcmFtcyA9IHtcbiAgICBtZXNzYWdlOiBgSW5wdXQgbm90IGluc3RhbmNlIG9mICR7Y2xzLm5hbWV9YFxufSk9PmN1c3RvbSgoZGF0YSk9PmRhdGEgaW5zdGFuY2VvZiBjbHMsIHBhcmFtcyk7XG5jb25zdCBzdHJpbmdUeXBlID0gWm9kU3RyaW5nLmNyZWF0ZTtcbmNvbnN0IG51bWJlclR5cGUgPSBab2ROdW1iZXIuY3JlYXRlO1xuY29uc3QgbmFuVHlwZSA9IFpvZE5hTi5jcmVhdGU7XG5jb25zdCBiaWdJbnRUeXBlID0gWm9kQmlnSW50LmNyZWF0ZTtcbmNvbnN0IGJvb2xlYW5UeXBlID0gWm9kQm9vbGVhbi5jcmVhdGU7XG5jb25zdCBkYXRlVHlwZSA9IFpvZERhdGUuY3JlYXRlO1xuY29uc3Qgc3ltYm9sVHlwZSA9IFpvZFN5bWJvbC5jcmVhdGU7XG5jb25zdCB1bmRlZmluZWRUeXBlID0gWm9kVW5kZWZpbmVkLmNyZWF0ZTtcbmNvbnN0IG51bGxUeXBlID0gWm9kTnVsbC5jcmVhdGU7XG5jb25zdCBhbnlUeXBlID0gWm9kQW55LmNyZWF0ZTtcbmNvbnN0IHVua25vd25UeXBlID0gWm9kVW5rbm93bi5jcmVhdGU7XG5jb25zdCBuZXZlclR5cGUgPSBab2ROZXZlci5jcmVhdGU7XG5jb25zdCB2b2lkVHlwZSA9IFpvZFZvaWQuY3JlYXRlO1xuY29uc3QgYXJyYXlUeXBlID0gWm9kQXJyYXkuY3JlYXRlO1xuY29uc3Qgb2JqZWN0VHlwZSA9IFpvZE9iamVjdC5jcmVhdGU7XG5jb25zdCBzdHJpY3RPYmplY3RUeXBlID0gWm9kT2JqZWN0LnN0cmljdENyZWF0ZTtcbmNvbnN0IHVuaW9uVHlwZSA9IFpvZFVuaW9uLmNyZWF0ZTtcbmNvbnN0IGRpc2NyaW1pbmF0ZWRVbmlvblR5cGUgPSBab2REaXNjcmltaW5hdGVkVW5pb24uY3JlYXRlO1xuY29uc3QgaW50ZXJzZWN0aW9uVHlwZSA9IFpvZEludGVyc2VjdGlvbi5jcmVhdGU7XG5jb25zdCB0dXBsZVR5cGUgPSBab2RUdXBsZS5jcmVhdGU7XG5jb25zdCByZWNvcmRUeXBlID0gWm9kUmVjb3JkLmNyZWF0ZTtcbmNvbnN0IG1hcFR5cGUgPSBab2RNYXAuY3JlYXRlO1xuY29uc3Qgc2V0VHlwZSA9IFpvZFNldC5jcmVhdGU7XG5jb25zdCBmdW5jdGlvblR5cGUgPSBab2RGdW5jdGlvbi5jcmVhdGU7XG5jb25zdCBsYXp5VHlwZSA9IFpvZExhenkuY3JlYXRlO1xuY29uc3QgbGl0ZXJhbFR5cGUgPSBab2RMaXRlcmFsLmNyZWF0ZTtcbmNvbnN0IGVudW1UeXBlID0gWm9kRW51bS5jcmVhdGU7XG5jb25zdCBuYXRpdmVFbnVtVHlwZSA9IFpvZE5hdGl2ZUVudW0uY3JlYXRlO1xuY29uc3QgcHJvbWlzZVR5cGUgPSBab2RQcm9taXNlLmNyZWF0ZTtcbmNvbnN0IGVmZmVjdHNUeXBlID0gWm9kRWZmZWN0cy5jcmVhdGU7XG5jb25zdCBvcHRpb25hbFR5cGUgPSBab2RPcHRpb25hbC5jcmVhdGU7XG5jb25zdCBudWxsYWJsZVR5cGUgPSBab2ROdWxsYWJsZS5jcmVhdGU7XG5jb25zdCBwcmVwcm9jZXNzVHlwZSA9IFpvZEVmZmVjdHMuY3JlYXRlV2l0aFByZXByb2Nlc3M7XG5jb25zdCBwaXBlbGluZVR5cGUgPSBab2RQaXBlbGluZS5jcmVhdGU7XG5jb25zdCBvc3RyaW5nID0gKCk9PnN0cmluZ1R5cGUoKS5vcHRpb25hbCgpO1xuY29uc3Qgb251bWJlciA9ICgpPT5udW1iZXJUeXBlKCkub3B0aW9uYWwoKTtcbmNvbnN0IG9ib29sZWFuID0gKCk9PmJvb2xlYW5UeXBlKCkub3B0aW9uYWwoKTtcbmV4cG9ydCBjb25zdCBjb2VyY2UgPSB7XG4gICAgc3RyaW5nOiAoYXJnKT0+Wm9kU3RyaW5nLmNyZWF0ZSh7XG4gICAgICAgICAgICAuLi5hcmcsXG4gICAgICAgICAgICBjb2VyY2U6IHRydWVcbiAgICAgICAgfSksXG4gICAgbnVtYmVyOiAoYXJnKT0+Wm9kTnVtYmVyLmNyZWF0ZSh7XG4gICAgICAgICAgICAuLi5hcmcsXG4gICAgICAgICAgICBjb2VyY2U6IHRydWVcbiAgICAgICAgfSksXG4gICAgYm9vbGVhbjogKGFyZyk9PlpvZEJvb2xlYW4uY3JlYXRlKHtcbiAgICAgICAgICAgIC4uLmFyZyxcbiAgICAgICAgICAgIGNvZXJjZTogdHJ1ZVxuICAgICAgICB9KSxcbiAgICBiaWdpbnQ6IChhcmcpPT5ab2RCaWdJbnQuY3JlYXRlKHtcbiAgICAgICAgICAgIC4uLmFyZyxcbiAgICAgICAgICAgIGNvZXJjZTogdHJ1ZVxuICAgICAgICB9KSxcbiAgICBkYXRlOiAoYXJnKT0+Wm9kRGF0ZS5jcmVhdGUoe1xuICAgICAgICAgICAgLi4uYXJnLFxuICAgICAgICAgICAgY29lcmNlOiB0cnVlXG4gICAgICAgIH0pXG59O1xuZXhwb3J0IHsgYW55VHlwZSBhcyBhbnksIGFycmF5VHlwZSBhcyBhcnJheSwgYmlnSW50VHlwZSBhcyBiaWdpbnQsIGJvb2xlYW5UeXBlIGFzIGJvb2xlYW4sIGRhdGVUeXBlIGFzIGRhdGUsIGRpc2NyaW1pbmF0ZWRVbmlvblR5cGUgYXMgZGlzY3JpbWluYXRlZFVuaW9uLCBlZmZlY3RzVHlwZSBhcyBlZmZlY3QsIGVudW1UeXBlIGFzIGVudW0sIGZ1bmN0aW9uVHlwZSBhcyBmdW5jdGlvbiwgaW5zdGFuY2VPZlR5cGUgYXMgaW5zdGFuY2VvZiwgaW50ZXJzZWN0aW9uVHlwZSBhcyBpbnRlcnNlY3Rpb24sIGxhenlUeXBlIGFzIGxhenksIGxpdGVyYWxUeXBlIGFzIGxpdGVyYWwsIG1hcFR5cGUgYXMgbWFwLCBuYW5UeXBlIGFzIG5hbiwgbmF0aXZlRW51bVR5cGUgYXMgbmF0aXZlRW51bSwgbmV2ZXJUeXBlIGFzIG5ldmVyLCBudWxsVHlwZSBhcyBudWxsLCBudWxsYWJsZVR5cGUgYXMgbnVsbGFibGUsIG51bWJlclR5cGUgYXMgbnVtYmVyLCBvYmplY3RUeXBlIGFzIG9iamVjdCwgb2Jvb2xlYW4sIG9udW1iZXIsIG9wdGlvbmFsVHlwZSBhcyBvcHRpb25hbCwgb3N0cmluZywgcGlwZWxpbmVUeXBlIGFzIHBpcGVsaW5lLCBwcmVwcm9jZXNzVHlwZSBhcyBwcmVwcm9jZXNzLCBwcm9taXNlVHlwZSBhcyBwcm9taXNlLCByZWNvcmRUeXBlIGFzIHJlY29yZCwgc2V0VHlwZSBhcyBzZXQsIHN0cmljdE9iamVjdFR5cGUgYXMgc3RyaWN0T2JqZWN0LCBzdHJpbmdUeXBlIGFzIHN0cmluZywgc3ltYm9sVHlwZSBhcyBzeW1ib2wsIGVmZmVjdHNUeXBlIGFzIHRyYW5zZm9ybWVyLCB0dXBsZVR5cGUgYXMgdHVwbGUsIHVuZGVmaW5lZFR5cGUgYXMgdW5kZWZpbmVkLCB1bmlvblR5cGUgYXMgdW5pb24sIHVua25vd25UeXBlIGFzIHVua25vd24sIHZvaWRUeXBlIGFzIHZvaWQgfTtcbmV4cG9ydCBjb25zdCBORVZFUiA9IElOVkFMSUQ7XG4iLCAiZXhwb3J0IGZ1bmN0aW9uIGNvbWJpbmVIZWFkZXJzKFxuICAuLi5oZWFkZXJzOiBBcnJheTxSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+IHwgdW5kZWZpbmVkPlxuKTogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gIHJldHVybiBoZWFkZXJzLnJlZHVjZShcbiAgICAoY29tYmluZWRIZWFkZXJzLCBjdXJyZW50SGVhZGVycykgPT4gKHtcbiAgICAgIC4uLmNvbWJpbmVkSGVhZGVycyxcbiAgICAgIC4uLihjdXJyZW50SGVhZGVycyA/PyB7fSksXG4gICAgfSksXG4gICAge30sXG4gICkgYXMgUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPjtcbn1cbiIsICIvKipcbiAqIENvbnZlcnRzIGFuIEFzeW5jSXRlcmF0b3IgdG8gYSBSZWFkYWJsZVN0cmVhbS5cbiAqXG4gKiBAdGVtcGxhdGUgVCAtIFRoZSB0eXBlIG9mIGVsZW1lbnRzIHByb2R1Y2VkIGJ5IHRoZSBBc3luY0l0ZXJhdG9yLlxuICogQHBhcmFtIHsgPFQ+fSBpdGVyYXRvciAtIFRoZSBBc3luY0l0ZXJhdG9yIHRvIGNvbnZlcnQuXG4gKiBAcmV0dXJucyB7UmVhZGFibGVTdHJlYW08VD59IC0gQSBSZWFkYWJsZVN0cmVhbSB0aGF0IHByb3ZpZGVzIHRoZSBzYW1lIGRhdGEgYXMgdGhlIEFzeW5jSXRlcmF0b3IuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb252ZXJ0QXN5bmNJdGVyYXRvclRvUmVhZGFibGVTdHJlYW08VD4oXG4gIGl0ZXJhdG9yOiBBc3luY0l0ZXJhdG9yPFQ+LFxuKTogUmVhZGFibGVTdHJlYW08VD4ge1xuICByZXR1cm4gbmV3IFJlYWRhYmxlU3RyZWFtPFQ+KHtcbiAgICAvKipcbiAgICAgKiBDYWxsZWQgd2hlbiB0aGUgY29uc3VtZXIgd2FudHMgdG8gcHVsbCBtb3JlIGRhdGEgZnJvbSB0aGUgc3RyZWFtLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyPFQ+fSBjb250cm9sbGVyIC0gVGhlIGNvbnRyb2xsZXIgdG8gZW5xdWV1ZSBkYXRhIGludG8gdGhlIHN0cmVhbS5cbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICAgKi9cbiAgICBhc3luYyBwdWxsKGNvbnRyb2xsZXIpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHsgdmFsdWUsIGRvbmUgfSA9IGF3YWl0IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICBjb250cm9sbGVyLmNsb3NlKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgY29udHJvbGxlci5lcnJvcihlcnJvcik7XG4gICAgICB9XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBDYWxsZWQgd2hlbiB0aGUgY29uc3VtZXIgY2FuY2VscyB0aGUgc3RyZWFtLlxuICAgICAqL1xuICAgIGNhbmNlbCgpIHt9LFxuICB9KTtcbn1cbiIsICIvKipcbiAqIENyZWF0ZXMgYSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgYWZ0ZXIgYSBzcGVjaWZpZWQgZGVsYXlcbiAqIEBwYXJhbSBkZWxheUluTXMgLSBUaGUgZGVsYXkgZHVyYXRpb24gaW4gbWlsbGlzZWNvbmRzLiBJZiBudWxsIG9yIHVuZGVmaW5lZCwgcmVzb2x2ZXMgaW1tZWRpYXRlbHkuXG4gKiBAcGFyYW0gc2lnbmFsIC0gT3B0aW9uYWwgQWJvcnRTaWduYWwgdG8gY2FuY2VsIHRoZSBkZWxheVxuICogQHJldHVybnMgQSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgYWZ0ZXIgdGhlIHNwZWNpZmllZCBkZWxheVxuICogQHRocm93cyB7RE9NRXhjZXB0aW9ufSBXaGVuIHRoZSBzaWduYWwgaXMgYWJvcnRlZFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZGVsYXkoXG4gIGRlbGF5SW5Ncz86IG51bWJlciB8IG51bGwsXG4gIG9wdGlvbnM/OiB7XG4gICAgYWJvcnRTaWduYWw/OiBBYm9ydFNpZ25hbDtcbiAgfSxcbik6IFByb21pc2U8dm9pZD4ge1xuICBpZiAoZGVsYXlJbk1zID09IG51bGwpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICBjb25zdCBzaWduYWwgPSBvcHRpb25zPy5hYm9ydFNpZ25hbDtcblxuICByZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGlmIChzaWduYWw/LmFib3J0ZWQpIHtcbiAgICAgIHJlamVjdChjcmVhdGVBYm9ydEVycm9yKCkpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgY2xlYW51cCgpO1xuICAgICAgcmVzb2x2ZSgpO1xuICAgIH0sIGRlbGF5SW5Ncyk7XG5cbiAgICBjb25zdCBjbGVhbnVwID0gKCkgPT4ge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZCk7XG4gICAgICBzaWduYWw/LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2Fib3J0Jywgb25BYm9ydCk7XG4gICAgfTtcblxuICAgIGNvbnN0IG9uQWJvcnQgPSAoKSA9PiB7XG4gICAgICBjbGVhbnVwKCk7XG4gICAgICByZWplY3QoY3JlYXRlQWJvcnRFcnJvcigpKTtcbiAgICB9O1xuXG4gICAgc2lnbmFsPy5hZGRFdmVudExpc3RlbmVyKCdhYm9ydCcsIG9uQWJvcnQpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlQWJvcnRFcnJvcigpOiBET01FeGNlcHRpb24ge1xuICByZXR1cm4gbmV3IERPTUV4Y2VwdGlvbignRGVsYXkgd2FzIGFib3J0ZWQnLCAnQWJvcnRFcnJvcicpO1xufVxuIiwgIi8qKlxuRXh0cmFjdHMgdGhlIGhlYWRlcnMgZnJvbSBhIHJlc3BvbnNlIG9iamVjdCBhbmQgcmV0dXJucyB0aGVtIGFzIGEga2V5LXZhbHVlIG9iamVjdC5cblxuQHBhcmFtIHJlc3BvbnNlIC0gVGhlIHJlc3BvbnNlIG9iamVjdCB0byBleHRyYWN0IGhlYWRlcnMgZnJvbS5cbkByZXR1cm5zIFRoZSBoZWFkZXJzIGFzIGEga2V5LXZhbHVlIG9iamVjdC5cbiovXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdFJlc3BvbnNlSGVhZGVycyhyZXNwb25zZTogUmVzcG9uc2UpIHtcbiAgcmV0dXJuIE9iamVjdC5mcm9tRW50cmllczxzdHJpbmc+KFsuLi5yZXNwb25zZS5oZWFkZXJzXSk7XG59XG4iLCAiaW1wb3J0IHsgSW52YWxpZEFyZ3VtZW50RXJyb3IgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcblxuLyoqXG5DcmVhdGVzIGFuIElEIGdlbmVyYXRvci5cblRoZSB0b3RhbCBsZW5ndGggb2YgdGhlIElEIGlzIHRoZSBzdW0gb2YgdGhlIHByZWZpeCwgc2VwYXJhdG9yLCBhbmQgcmFuZG9tIHBhcnQgbGVuZ3RoLlxuTm90IGNyeXB0b2dyYXBoaWNhbGx5IHNlY3VyZS5cblxuQHBhcmFtIGFscGhhYmV0IC0gVGhlIGFscGhhYmV0IHRvIHVzZSBmb3IgdGhlIElELiBEZWZhdWx0OiAnMDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXonLlxuQHBhcmFtIHByZWZpeCAtIFRoZSBwcmVmaXggb2YgdGhlIElEIHRvIGdlbmVyYXRlLiBPcHRpb25hbC5cbkBwYXJhbSBzZXBhcmF0b3IgLSBUaGUgc2VwYXJhdG9yIGJldHdlZW4gdGhlIHByZWZpeCBhbmQgdGhlIHJhbmRvbSBwYXJ0IG9mIHRoZSBJRC4gRGVmYXVsdDogJy0nLlxuQHBhcmFtIHNpemUgLSBUaGUgc2l6ZSBvZiB0aGUgcmFuZG9tIHBhcnQgb2YgdGhlIElEIHRvIGdlbmVyYXRlLiBEZWZhdWx0OiAxNi5cbiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUlkR2VuZXJhdG9yID0gKHtcbiAgcHJlZml4LFxuICBzaXplID0gMTYsXG4gIGFscGhhYmV0ID0gJzAxMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6JyxcbiAgc2VwYXJhdG9yID0gJy0nLFxufToge1xuICBwcmVmaXg/OiBzdHJpbmc7XG4gIHNlcGFyYXRvcj86IHN0cmluZztcbiAgc2l6ZT86IG51bWJlcjtcbiAgYWxwaGFiZXQ/OiBzdHJpbmc7XG59ID0ge30pOiBJZEdlbmVyYXRvciA9PiB7XG4gIGNvbnN0IGdlbmVyYXRvciA9ICgpID0+IHtcbiAgICBjb25zdCBhbHBoYWJldExlbmd0aCA9IGFscGhhYmV0Lmxlbmd0aDtcbiAgICBjb25zdCBjaGFycyA9IG5ldyBBcnJheShzaXplKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNpemU7IGkrKykge1xuICAgICAgY2hhcnNbaV0gPSBhbHBoYWJldFsoTWF0aC5yYW5kb20oKSAqIGFscGhhYmV0TGVuZ3RoKSB8IDBdO1xuICAgIH1cbiAgICByZXR1cm4gY2hhcnMuam9pbignJyk7XG4gIH07XG5cbiAgaWYgKHByZWZpeCA9PSBudWxsKSB7XG4gICAgcmV0dXJuIGdlbmVyYXRvcjtcbiAgfVxuXG4gIC8vIGNoZWNrIHRoYXQgdGhlIHByZWZpeCBpcyBub3QgcGFydCBvZiB0aGUgYWxwaGFiZXQgKG90aGVyd2lzZSBwcmVmaXggY2hlY2tpbmcgY2FuIGZhaWwgcmFuZG9tbHkpXG4gIGlmIChhbHBoYWJldC5pbmNsdWRlcyhzZXBhcmF0b3IpKSB7XG4gICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEVycm9yKHtcbiAgICAgIGFyZ3VtZW50OiAnc2VwYXJhdG9yJyxcbiAgICAgIG1lc3NhZ2U6IGBUaGUgc2VwYXJhdG9yIFwiJHtzZXBhcmF0b3J9XCIgbXVzdCBub3QgYmUgcGFydCBvZiB0aGUgYWxwaGFiZXQgXCIke2FscGhhYmV0fVwiLmAsXG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gKCkgPT4gYCR7cHJlZml4fSR7c2VwYXJhdG9yfSR7Z2VuZXJhdG9yKCl9YDtcbn07XG5cbi8qKlxuQSBmdW5jdGlvbiB0aGF0IGdlbmVyYXRlcyBhbiBJRC5cbiAqL1xuZXhwb3J0IHR5cGUgSWRHZW5lcmF0b3IgPSAoKSA9PiBzdHJpbmc7XG5cbi8qKlxuR2VuZXJhdGVzIGEgMTYtY2hhcmFjdGVyIHJhbmRvbSBzdHJpbmcgdG8gdXNlIGZvciBJRHMuXG5Ob3QgY3J5cHRvZ3JhcGhpY2FsbHkgc2VjdXJlLlxuICovXG5leHBvcnQgY29uc3QgZ2VuZXJhdGVJZCA9IGNyZWF0ZUlkR2VuZXJhdG9yKCk7XG4iLCAiZXhwb3J0IGZ1bmN0aW9uIGdldEVycm9yTWVzc2FnZShlcnJvcjogdW5rbm93biB8IHVuZGVmaW5lZCkge1xuICBpZiAoZXJyb3IgPT0gbnVsbCkge1xuICAgIHJldHVybiAndW5rbm93biBlcnJvcic7XG4gIH1cblxuICBpZiAodHlwZW9mIGVycm9yID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBlcnJvcjtcbiAgfVxuXG4gIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgcmV0dXJuIGVycm9yLm1lc3NhZ2U7XG4gIH1cblxuICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoZXJyb3IpO1xufVxuIiwgImltcG9ydCB7IEFQSUNhbGxFcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgZXh0cmFjdFJlc3BvbnNlSGVhZGVycyB9IGZyb20gJy4vZXh0cmFjdC1yZXNwb25zZS1oZWFkZXJzJztcbmltcG9ydCB7IEZldGNoRnVuY3Rpb24gfSBmcm9tICcuL2ZldGNoLWZ1bmN0aW9uJztcbmltcG9ydCB7IGhhbmRsZUZldGNoRXJyb3IgfSBmcm9tICcuL2hhbmRsZS1mZXRjaC1lcnJvcic7XG5pbXBvcnQgeyBpc0Fib3J0RXJyb3IgfSBmcm9tICcuL2lzLWFib3J0LWVycm9yJztcbmltcG9ydCB7IFJlc3BvbnNlSGFuZGxlciB9IGZyb20gJy4vcmVzcG9uc2UtaGFuZGxlcic7XG5pbXBvcnQgeyBnZXRSdW50aW1lRW52aXJvbm1lbnRVc2VyQWdlbnQgfSBmcm9tICcuL2dldC1ydW50aW1lLWVudmlyb25tZW50LXVzZXItYWdlbnQnO1xuaW1wb3J0IHsgd2l0aFVzZXJBZ2VudFN1ZmZpeCB9IGZyb20gJy4vd2l0aC11c2VyLWFnZW50LXN1ZmZpeCc7XG5pbXBvcnQgeyBWRVJTSU9OIH0gZnJvbSAnLi92ZXJzaW9uJztcblxuLy8gdXNlIGZ1bmN0aW9uIHRvIGFsbG93IGZvciBtb2NraW5nIGluIHRlc3RzOlxuY29uc3QgZ2V0T3JpZ2luYWxGZXRjaCA9ICgpID0+IGdsb2JhbFRoaXMuZmV0Y2g7XG5cbmV4cG9ydCBjb25zdCBnZXRGcm9tQXBpID0gYXN5bmMgPFQ+KHtcbiAgdXJsLFxuICBoZWFkZXJzID0ge30sXG4gIHN1Y2Nlc3NmdWxSZXNwb25zZUhhbmRsZXIsXG4gIGZhaWxlZFJlc3BvbnNlSGFuZGxlcixcbiAgYWJvcnRTaWduYWwsXG4gIGZldGNoID0gZ2V0T3JpZ2luYWxGZXRjaCgpLFxufToge1xuICB1cmw6IHN0cmluZztcbiAgaGVhZGVycz86IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD47XG4gIGZhaWxlZFJlc3BvbnNlSGFuZGxlcjogUmVzcG9uc2VIYW5kbGVyPEVycm9yPjtcbiAgc3VjY2Vzc2Z1bFJlc3BvbnNlSGFuZGxlcjogUmVzcG9uc2VIYW5kbGVyPFQ+O1xuICBhYm9ydFNpZ25hbD86IEFib3J0U2lnbmFsO1xuICBmZXRjaD86IEZldGNoRnVuY3Rpb247XG59KSA9PiB7XG4gIHRyeSB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh1cmwsIHtcbiAgICAgIG1ldGhvZDogJ0dFVCcsXG4gICAgICBoZWFkZXJzOiB3aXRoVXNlckFnZW50U3VmZml4KFxuICAgICAgICBoZWFkZXJzLFxuICAgICAgICBgYWktc2RrL3Byb3ZpZGVyLXV0aWxzLyR7VkVSU0lPTn1gLFxuICAgICAgICBnZXRSdW50aW1lRW52aXJvbm1lbnRVc2VyQWdlbnQoKSxcbiAgICAgICksXG4gICAgICBzaWduYWw6IGFib3J0U2lnbmFsLFxuICAgIH0pO1xuXG4gICAgY29uc3QgcmVzcG9uc2VIZWFkZXJzID0gZXh0cmFjdFJlc3BvbnNlSGVhZGVycyhyZXNwb25zZSk7XG5cbiAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICBsZXQgZXJyb3JJbmZvcm1hdGlvbjoge1xuICAgICAgICB2YWx1ZTogRXJyb3I7XG4gICAgICAgIHJlc3BvbnNlSGVhZGVycz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gfCB1bmRlZmluZWQ7XG4gICAgICB9O1xuXG4gICAgICB0cnkge1xuICAgICAgICBlcnJvckluZm9ybWF0aW9uID0gYXdhaXQgZmFpbGVkUmVzcG9uc2VIYW5kbGVyKHtcbiAgICAgICAgICByZXNwb25zZSxcbiAgICAgICAgICB1cmwsXG4gICAgICAgICAgcmVxdWVzdEJvZHlWYWx1ZXM6IHt9LFxuICAgICAgICB9KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGlmIChpc0Fib3J0RXJyb3IoZXJyb3IpIHx8IEFQSUNhbGxFcnJvci5pc0luc3RhbmNlKGVycm9yKSkge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhyb3cgbmV3IEFQSUNhbGxFcnJvcih7XG4gICAgICAgICAgbWVzc2FnZTogJ0ZhaWxlZCB0byBwcm9jZXNzIGVycm9yIHJlc3BvbnNlJyxcbiAgICAgICAgICBjYXVzZTogZXJyb3IsXG4gICAgICAgICAgc3RhdHVzQ29kZTogcmVzcG9uc2Uuc3RhdHVzLFxuICAgICAgICAgIHVybCxcbiAgICAgICAgICByZXNwb25zZUhlYWRlcnMsXG4gICAgICAgICAgcmVxdWVzdEJvZHlWYWx1ZXM6IHt9LFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgdGhyb3cgZXJyb3JJbmZvcm1hdGlvbi52YWx1ZTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IHN1Y2Nlc3NmdWxSZXNwb25zZUhhbmRsZXIoe1xuICAgICAgICByZXNwb25zZSxcbiAgICAgICAgdXJsLFxuICAgICAgICByZXF1ZXN0Qm9keVZhbHVlczoge30sXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgaWYgKGlzQWJvcnRFcnJvcihlcnJvcikgfHwgQVBJQ2FsbEVycm9yLmlzSW5zdGFuY2UoZXJyb3IpKSB7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdGhyb3cgbmV3IEFQSUNhbGxFcnJvcih7XG4gICAgICAgIG1lc3NhZ2U6ICdGYWlsZWQgdG8gcHJvY2VzcyBzdWNjZXNzZnVsIHJlc3BvbnNlJyxcbiAgICAgICAgY2F1c2U6IGVycm9yLFxuICAgICAgICBzdGF0dXNDb2RlOiByZXNwb25zZS5zdGF0dXMsXG4gICAgICAgIHVybCxcbiAgICAgICAgcmVzcG9uc2VIZWFkZXJzLFxuICAgICAgICByZXF1ZXN0Qm9keVZhbHVlczoge30sXG4gICAgICB9KTtcbiAgICB9XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgdGhyb3cgaGFuZGxlRmV0Y2hFcnJvcih7IGVycm9yLCB1cmwsIHJlcXVlc3RCb2R5VmFsdWVzOiB7fSB9KTtcbiAgfVxufTtcbiIsICJpbXBvcnQgeyBBUElDYWxsRXJyb3IgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcbmltcG9ydCB7IGlzQWJvcnRFcnJvciB9IGZyb20gJy4vaXMtYWJvcnQtZXJyb3InO1xuXG5jb25zdCBGRVRDSF9GQUlMRURfRVJST1JfTUVTU0FHRVMgPSBbJ2ZldGNoIGZhaWxlZCcsICdmYWlsZWQgdG8gZmV0Y2gnXTtcblxuZXhwb3J0IGZ1bmN0aW9uIGhhbmRsZUZldGNoRXJyb3Ioe1xuICBlcnJvcixcbiAgdXJsLFxuICByZXF1ZXN0Qm9keVZhbHVlcyxcbn06IHtcbiAgZXJyb3I6IHVua25vd247XG4gIHVybDogc3RyaW5nO1xuICByZXF1ZXN0Qm9keVZhbHVlczogdW5rbm93bjtcbn0pIHtcbiAgaWYgKGlzQWJvcnRFcnJvcihlcnJvcikpIHtcbiAgICByZXR1cm4gZXJyb3I7XG4gIH1cblxuICAvLyB1bndyYXAgb3JpZ2luYWwgZXJyb3Igd2hlbiBmZXRjaCBmYWlsZWQgKGZvciBlYXNpZXIgZGVidWdnaW5nKTpcbiAgaWYgKFxuICAgIGVycm9yIGluc3RhbmNlb2YgVHlwZUVycm9yICYmXG4gICAgRkVUQ0hfRkFJTEVEX0VSUk9SX01FU1NBR0VTLmluY2x1ZGVzKGVycm9yLm1lc3NhZ2UudG9Mb3dlckNhc2UoKSlcbiAgKSB7XG4gICAgY29uc3QgY2F1c2UgPSAoZXJyb3IgYXMgYW55KS5jYXVzZTtcblxuICAgIGlmIChjYXVzZSAhPSBudWxsKSB7XG4gICAgICAvLyBGYWlsZWQgdG8gY29ubmVjdCB0byBzZXJ2ZXI6XG4gICAgICByZXR1cm4gbmV3IEFQSUNhbGxFcnJvcih7XG4gICAgICAgIG1lc3NhZ2U6IGBDYW5ub3QgY29ubmVjdCB0byBBUEk6ICR7Y2F1c2UubWVzc2FnZX1gLFxuICAgICAgICBjYXVzZSxcbiAgICAgICAgdXJsLFxuICAgICAgICByZXF1ZXN0Qm9keVZhbHVlcyxcbiAgICAgICAgaXNSZXRyeWFibGU6IHRydWUsIC8vIHJldHJ5IHdoZW4gbmV0d29yayBlcnJvclxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGVycm9yO1xufVxuIiwgImV4cG9ydCBmdW5jdGlvbiBpc0Fib3J0RXJyb3IoZXJyb3I6IHVua25vd24pOiBlcnJvciBpcyBFcnJvciB7XG4gIHJldHVybiAoXG4gICAgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IgfHwgZXJyb3IgaW5zdGFuY2VvZiBET01FeGNlcHRpb24pICYmXG4gICAgKGVycm9yLm5hbWUgPT09ICdBYm9ydEVycm9yJyB8fFxuICAgICAgZXJyb3IubmFtZSA9PT0gJ1Jlc3BvbnNlQWJvcnRlZCcgfHwgLy8gTmV4dC5qc1xuICAgICAgZXJyb3IubmFtZSA9PT0gJ1RpbWVvdXRFcnJvcicpXG4gICk7XG59XG4iLCAiZXhwb3J0IGZ1bmN0aW9uIGdldFJ1bnRpbWVFbnZpcm9ubWVudFVzZXJBZ2VudChcbiAgZ2xvYmFsVGhpc0FueTogYW55ID0gZ2xvYmFsVGhpcyBhcyBhbnksXG4pOiBzdHJpbmcge1xuICAvLyBCcm93c2Vyc1xuICBpZiAoZ2xvYmFsVGhpc0FueS53aW5kb3cpIHtcbiAgICByZXR1cm4gYHJ1bnRpbWUvYnJvd3NlcmA7XG4gIH1cblxuICAvLyBDbG91ZGZsYXJlIFdvcmtlcnMgLyBEZW5vIC8gQnVuIC8gTm9kZS5qcyA+PSAyMS4xXG4gIGlmIChnbG9iYWxUaGlzQW55Lm5hdmlnYXRvcj8udXNlckFnZW50KSB7XG4gICAgcmV0dXJuIGBydW50aW1lLyR7Z2xvYmFsVGhpc0FueS5uYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCl9YDtcbiAgfVxuXG4gIC8vIE5vZGVzLmpzIDwgMjEuMVxuICBpZiAoZ2xvYmFsVGhpc0FueS5wcm9jZXNzPy52ZXJzaW9ucz8ubm9kZSkge1xuICAgIHJldHVybiBgcnVudGltZS9ub2RlLmpzLyR7Z2xvYmFsVGhpc0FueS5wcm9jZXNzLnZlcnNpb24uc3Vic3RyaW5nKDApfWA7XG4gIH1cblxuICBpZiAoZ2xvYmFsVGhpc0FueS5FZGdlUnVudGltZSkge1xuICAgIHJldHVybiBgcnVudGltZS92ZXJjZWwtZWRnZWA7XG4gIH1cblxuICByZXR1cm4gJ3J1bnRpbWUvdW5rbm93bic7XG59XG4iLCAiLyoqXG4gKiBSZW1vdmVzIGVudHJpZXMgZnJvbSBhIHJlY29yZCB3aGVyZSB0aGUgdmFsdWUgaXMgbnVsbCBvciB1bmRlZmluZWQuXG4gKiBAcGFyYW0gcmVjb3JkIC0gVGhlIGlucHV0IG9iamVjdCB3aG9zZSBlbnRyaWVzIG1heSBiZSBudWxsIG9yIHVuZGVmaW5lZC5cbiAqIEByZXR1cm5zIEEgbmV3IG9iamVjdCBjb250YWluaW5nIG9ubHkgZW50cmllcyB3aXRoIG5vbi1udWxsIGFuZCBub24tdW5kZWZpbmVkIHZhbHVlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZVVuZGVmaW5lZEVudHJpZXM8VD4oXG4gIHJlY29yZDogUmVjb3JkPHN0cmluZywgVCB8IHVuZGVmaW5lZD4sXG4pOiBSZWNvcmQ8c3RyaW5nLCBUPiB7XG4gIHJldHVybiBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgT2JqZWN0LmVudHJpZXMocmVjb3JkKS5maWx0ZXIoKFtfa2V5LCB2YWx1ZV0pID0+IHZhbHVlICE9IG51bGwpLFxuICApIGFzIFJlY29yZDxzdHJpbmcsIFQ+O1xufVxuIiwgImltcG9ydCB7IHJlbW92ZVVuZGVmaW5lZEVudHJpZXMgfSBmcm9tICcuL3JlbW92ZS11bmRlZmluZWQtZW50cmllcyc7XG5cbi8qKlxuICogQXBwZW5kcyBzdWZmaXggcGFydHMgdG8gdGhlIGB1c2VyLWFnZW50YCBoZWFkZXIuXG4gKiBJZiBhIGB1c2VyLWFnZW50YCBoZWFkZXIgYWxyZWFkeSBleGlzdHMsIHRoZSBzdWZmaXggcGFydHMgYXJlIGFwcGVuZGVkIHRvIGl0LlxuICogSWYgbm8gYHVzZXItYWdlbnRgIGhlYWRlciBleGlzdHMsIGEgbmV3IG9uZSBpcyBjcmVhdGVkIHdpdGggdGhlIHN1ZmZpeCBwYXJ0cy5cbiAqIEF1dG9tYXRpY2FsbHkgcmVtb3ZlcyB1bmRlZmluZWQgZW50cmllcyBmcm9tIHRoZSBoZWFkZXJzLlxuICpcbiAqIEBwYXJhbSBoZWFkZXJzIC0gVGhlIG9yaWdpbmFsIGhlYWRlcnMuXG4gKiBAcGFyYW0gdXNlckFnZW50U3VmZml4UGFydHMgLSBUaGUgcGFydHMgdG8gYXBwZW5kIHRvIHRoZSBgdXNlci1hZ2VudGAgaGVhZGVyLlxuICogQHJldHVybnMgVGhlIG5ldyBoZWFkZXJzIHdpdGggdGhlIGB1c2VyLWFnZW50YCBoZWFkZXIgc2V0IG9yIHVwZGF0ZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3aXRoVXNlckFnZW50U3VmZml4KFxuICBoZWFkZXJzOiBIZWFkZXJzSW5pdCB8IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD4gfCB1bmRlZmluZWQsXG4gIC4uLnVzZXJBZ2VudFN1ZmZpeFBhcnRzOiBzdHJpbmdbXVxuKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG4gIGNvbnN0IGNsZWFuZWRIZWFkZXJzID0gcmVtb3ZlVW5kZWZpbmVkRW50cmllcyhcbiAgICAoaGVhZGVycyBhcyBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+KSA/PyB7fSxcbiAgKTtcbiAgY29uc3Qgbm9ybWFsaXplZEhlYWRlcnMgPSBuZXcgSGVhZGVycyhjbGVhbmVkSGVhZGVycyk7XG5cbiAgY29uc3QgY3VycmVudFVzZXJBZ2VudEhlYWRlciA9IG5vcm1hbGl6ZWRIZWFkZXJzLmdldCgndXNlci1hZ2VudCcpIHx8ICcnO1xuXG4gIG5vcm1hbGl6ZWRIZWFkZXJzLnNldChcbiAgICAndXNlci1hZ2VudCcsXG4gICAgW2N1cnJlbnRVc2VyQWdlbnRIZWFkZXIsIC4uLnVzZXJBZ2VudFN1ZmZpeFBhcnRzXS5maWx0ZXIoQm9vbGVhbikuam9pbignICcpLFxuICApO1xuXG4gIHJldHVybiBPYmplY3QuZnJvbUVudHJpZXMobm9ybWFsaXplZEhlYWRlcnMpO1xufVxuIiwgIi8vIFZlcnNpb24gc3RyaW5nIG9mIHRoaXMgcGFja2FnZSBpbmplY3RlZCBhdCBidWlsZCB0aW1lLlxuZGVjbGFyZSBjb25zdCBfX1BBQ0tBR0VfVkVSU0lPTl9fOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5leHBvcnQgY29uc3QgVkVSU0lPTjogc3RyaW5nID1cbiAgdHlwZW9mIF9fUEFDS0FHRV9WRVJTSU9OX18gIT09ICd1bmRlZmluZWQnXG4gICAgPyBfX1BBQ0tBR0VfVkVSU0lPTl9fXG4gICAgOiAnMC4wLjAtdGVzdCc7XG4iLCAiaW1wb3J0IHtcbiAgSlNPTlNjaGVtYTcsXG4gIExhbmd1YWdlTW9kZWxWMk1lc3NhZ2UsXG4gIExhbmd1YWdlTW9kZWxWMlByb21wdCxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5cbmNvbnN0IERFRkFVTFRfU0NIRU1BX1BSRUZJWCA9ICdKU09OIHNjaGVtYTonO1xuY29uc3QgREVGQVVMVF9TQ0hFTUFfU1VGRklYID1cbiAgJ1lvdSBNVVNUIGFuc3dlciB3aXRoIGEgSlNPTiBvYmplY3QgdGhhdCBtYXRjaGVzIHRoZSBKU09OIHNjaGVtYSBhYm92ZS4nO1xuY29uc3QgREVGQVVMVF9HRU5FUklDX1NVRkZJWCA9ICdZb3UgTVVTVCBhbnN3ZXIgd2l0aCBKU09OLic7XG5cbmV4cG9ydCBmdW5jdGlvbiBpbmplY3RKc29uSW5zdHJ1Y3Rpb24oe1xuICBwcm9tcHQsXG4gIHNjaGVtYSxcbiAgc2NoZW1hUHJlZml4ID0gc2NoZW1hICE9IG51bGwgPyBERUZBVUxUX1NDSEVNQV9QUkVGSVggOiB1bmRlZmluZWQsXG4gIHNjaGVtYVN1ZmZpeCA9IHNjaGVtYSAhPSBudWxsXG4gICAgPyBERUZBVUxUX1NDSEVNQV9TVUZGSVhcbiAgICA6IERFRkFVTFRfR0VORVJJQ19TVUZGSVgsXG59OiB7XG4gIHByb21wdD86IHN0cmluZztcbiAgc2NoZW1hPzogSlNPTlNjaGVtYTc7XG4gIHNjaGVtYVByZWZpeD86IHN0cmluZztcbiAgc2NoZW1hU3VmZml4Pzogc3RyaW5nO1xufSk6IHN0cmluZyB7XG4gIHJldHVybiBbXG4gICAgcHJvbXB0ICE9IG51bGwgJiYgcHJvbXB0Lmxlbmd0aCA+IDAgPyBwcm9tcHQgOiB1bmRlZmluZWQsXG4gICAgcHJvbXB0ICE9IG51bGwgJiYgcHJvbXB0Lmxlbmd0aCA+IDAgPyAnJyA6IHVuZGVmaW5lZCwgLy8gYWRkIGEgbmV3bGluZSBpZiBwcm9tcHQgaXMgbm90IG51bGxcbiAgICBzY2hlbWFQcmVmaXgsXG4gICAgc2NoZW1hICE9IG51bGwgPyBKU09OLnN0cmluZ2lmeShzY2hlbWEpIDogdW5kZWZpbmVkLFxuICAgIHNjaGVtYVN1ZmZpeCxcbiAgXVxuICAgIC5maWx0ZXIobGluZSA9PiBsaW5lICE9IG51bGwpXG4gICAgLmpvaW4oJ1xcbicpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaW5qZWN0SnNvbkluc3RydWN0aW9uSW50b01lc3NhZ2VzKHtcbiAgbWVzc2FnZXMsXG4gIHNjaGVtYSxcbiAgc2NoZW1hUHJlZml4LFxuICBzY2hlbWFTdWZmaXgsXG59OiB7XG4gIG1lc3NhZ2VzOiBMYW5ndWFnZU1vZGVsVjJQcm9tcHQ7XG4gIHNjaGVtYT86IEpTT05TY2hlbWE3O1xuICBzY2hlbWFQcmVmaXg/OiBzdHJpbmc7XG4gIHNjaGVtYVN1ZmZpeD86IHN0cmluZztcbn0pOiBMYW5ndWFnZU1vZGVsVjJQcm9tcHQge1xuICBjb25zdCBzeXN0ZW1NZXNzYWdlOiBMYW5ndWFnZU1vZGVsVjJNZXNzYWdlID1cbiAgICBtZXNzYWdlc1swXT8ucm9sZSA9PT0gJ3N5c3RlbSdcbiAgICAgID8geyAuLi5tZXNzYWdlc1swXSB9XG4gICAgICA6IHsgcm9sZTogJ3N5c3RlbScsIGNvbnRlbnQ6ICcnIH07XG5cbiAgc3lzdGVtTWVzc2FnZS5jb250ZW50ID0gaW5qZWN0SnNvbkluc3RydWN0aW9uKHtcbiAgICBwcm9tcHQ6IHN5c3RlbU1lc3NhZ2UuY29udGVudCxcbiAgICBzY2hlbWEsXG4gICAgc2NoZW1hUHJlZml4LFxuICAgIHNjaGVtYVN1ZmZpeCxcbiAgfSk7XG5cbiAgcmV0dXJuIFtcbiAgICBzeXN0ZW1NZXNzYWdlLFxuICAgIC4uLihtZXNzYWdlc1swXT8ucm9sZSA9PT0gJ3N5c3RlbScgPyBtZXNzYWdlcy5zbGljZSgxKSA6IG1lc3NhZ2VzKSxcbiAgXTtcbn1cbiIsICIvKipcbiAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gVVJMIGlzIHN1cHBvcnRlZCBuYXRpdmVseSBieSB0aGUgbW9kZWwuXG4gKlxuICogQHBhcmFtIG1lZGlhVHlwZSAtIFRoZSBtZWRpYSB0eXBlIG9mIHRoZSBVUkwuIENhc2Utc2Vuc2l0aXZlLlxuICogQHBhcmFtIHVybCAtIFRoZSBVUkwgdG8gY2hlY2suXG4gKiBAcGFyYW0gc3VwcG9ydGVkVXJscyAtIEEgcmVjb3JkIHdoZXJlIGtleXMgYXJlIGNhc2Utc2Vuc2l0aXZlIG1lZGlhIHR5cGVzIChvciAnKicpXG4gKiAgICAgICAgICAgICAgICAgICAgICAgIGFuZCB2YWx1ZXMgYXJlIGFycmF5cyBvZiBSZWdFeHAgcGF0dGVybnMgZm9yIFVSTHMuXG4gKlxuICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBVUkwgbWF0Y2hlcyBhIHBhdHRlcm4gdW5kZXIgdGhlIHNwZWNpZmljIG1lZGlhIHR5cGVcbiAqICAgICAgICAgIG9yIHRoZSB3aWxkY2FyZCAnKicsIGBmYWxzZWAgb3RoZXJ3aXNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNVcmxTdXBwb3J0ZWQoe1xuICBtZWRpYVR5cGUsXG4gIHVybCxcbiAgc3VwcG9ydGVkVXJscyxcbn06IHtcbiAgbWVkaWFUeXBlOiBzdHJpbmc7XG4gIHVybDogc3RyaW5nO1xuICBzdXBwb3J0ZWRVcmxzOiBSZWNvcmQ8c3RyaW5nLCBSZWdFeHBbXT47XG59KTogYm9vbGVhbiB7XG4gIC8vIHN0YW5kYXJkaXplIG1lZGlhIHR5cGUgYW5kIHVybCB0byBsb3dlciBjYXNlXG4gIHVybCA9IHVybC50b0xvd2VyQ2FzZSgpO1xuICBtZWRpYVR5cGUgPSBtZWRpYVR5cGUudG9Mb3dlckNhc2UoKTtcblxuICByZXR1cm4gKFxuICAgIE9iamVjdC5lbnRyaWVzKHN1cHBvcnRlZFVybHMpXG4gICAgICAvLyBzdGFuZGFyZGl6ZSBzdXBwb3J0ZWQgdXJsIG1hcCBpbnRvIGxvd2VyY2FzZSBwcmVmaXhlczpcbiAgICAgIC5tYXAoKFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgICBjb25zdCBtZWRpYVR5cGUgPSBrZXkudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgcmV0dXJuIG1lZGlhVHlwZSA9PT0gJyonIHx8IG1lZGlhVHlwZSA9PT0gJyovKidcbiAgICAgICAgICA/IHsgbWVkaWFUeXBlUHJlZml4OiAnJywgcmVnZXhlczogdmFsdWUgfVxuICAgICAgICAgIDogeyBtZWRpYVR5cGVQcmVmaXg6IG1lZGlhVHlwZS5yZXBsYWNlKC9cXCovLCAnJyksIHJlZ2V4ZXM6IHZhbHVlIH07XG4gICAgICB9KVxuICAgICAgLy8gZ2F0aGVyIGFsbCByZWdleHAgcGF0dGVybiBmcm9tIG1hdGNoZWQgbWVkaWEgdHlwZSBwcmVmaXhlczpcbiAgICAgIC5maWx0ZXIoKHsgbWVkaWFUeXBlUHJlZml4IH0pID0+IG1lZGlhVHlwZS5zdGFydHNXaXRoKG1lZGlhVHlwZVByZWZpeCkpXG4gICAgICAuZmxhdE1hcCgoeyByZWdleGVzIH0pID0+IHJlZ2V4ZXMpXG4gICAgICAvLyBjaGVjayBpZiBhbnkgcGF0dGVybiBtYXRjaGVzIHRoZSB1cmw6XG4gICAgICAuc29tZShwYXR0ZXJuID0+IHBhdHRlcm4udGVzdCh1cmwpKVxuICApO1xufVxuIiwgImltcG9ydCB7IExvYWRBUElLZXlFcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuXG5leHBvcnQgZnVuY3Rpb24gbG9hZEFwaUtleSh7XG4gIGFwaUtleSxcbiAgZW52aXJvbm1lbnRWYXJpYWJsZU5hbWUsXG4gIGFwaUtleVBhcmFtZXRlck5hbWUgPSAnYXBpS2V5JyxcbiAgZGVzY3JpcHRpb24sXG59OiB7XG4gIGFwaUtleTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBlbnZpcm9ubWVudFZhcmlhYmxlTmFtZTogc3RyaW5nO1xuICBhcGlLZXlQYXJhbWV0ZXJOYW1lPzogc3RyaW5nO1xuICBkZXNjcmlwdGlvbjogc3RyaW5nO1xufSk6IHN0cmluZyB7XG4gIGlmICh0eXBlb2YgYXBpS2V5ID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBhcGlLZXk7XG4gIH1cblxuICBpZiAoYXBpS2V5ICE9IG51bGwpIHtcbiAgICB0aHJvdyBuZXcgTG9hZEFQSUtleUVycm9yKHtcbiAgICAgIG1lc3NhZ2U6IGAke2Rlc2NyaXB0aW9ufSBBUEkga2V5IG11c3QgYmUgYSBzdHJpbmcuYCxcbiAgICB9KTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgcHJvY2VzcyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB0aHJvdyBuZXcgTG9hZEFQSUtleUVycm9yKHtcbiAgICAgIG1lc3NhZ2U6IGAke2Rlc2NyaXB0aW9ufSBBUEkga2V5IGlzIG1pc3NpbmcuIFBhc3MgaXQgdXNpbmcgdGhlICcke2FwaUtleVBhcmFtZXRlck5hbWV9JyBwYXJhbWV0ZXIuIEVudmlyb25tZW50IHZhcmlhYmxlcyBpcyBub3Qgc3VwcG9ydGVkIGluIHRoaXMgZW52aXJvbm1lbnQuYCxcbiAgICB9KTtcbiAgfVxuXG4gIGFwaUtleSA9IHByb2Nlc3MuZW52W2Vudmlyb25tZW50VmFyaWFibGVOYW1lXTtcblxuICBpZiAoYXBpS2V5ID09IG51bGwpIHtcbiAgICB0aHJvdyBuZXcgTG9hZEFQSUtleUVycm9yKHtcbiAgICAgIG1lc3NhZ2U6IGAke2Rlc2NyaXB0aW9ufSBBUEkga2V5IGlzIG1pc3NpbmcuIFBhc3MgaXQgdXNpbmcgdGhlICcke2FwaUtleVBhcmFtZXRlck5hbWV9JyBwYXJhbWV0ZXIgb3IgdGhlICR7ZW52aXJvbm1lbnRWYXJpYWJsZU5hbWV9IGVudmlyb25tZW50IHZhcmlhYmxlLmAsXG4gICAgfSk7XG4gIH1cblxuICBpZiAodHlwZW9mIGFwaUtleSAhPT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgTG9hZEFQSUtleUVycm9yKHtcbiAgICAgIG1lc3NhZ2U6IGAke2Rlc2NyaXB0aW9ufSBBUEkga2V5IG11c3QgYmUgYSBzdHJpbmcuIFRoZSB2YWx1ZSBvZiB0aGUgJHtlbnZpcm9ubWVudFZhcmlhYmxlTmFtZX0gZW52aXJvbm1lbnQgdmFyaWFibGUgaXMgbm90IGEgc3RyaW5nLmAsXG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gYXBpS2V5O1xufVxuIiwgIi8qKlxuICogTG9hZHMgYW4gb3B0aW9uYWwgYHN0cmluZ2Agc2V0dGluZyBmcm9tIHRoZSBlbnZpcm9ubWVudCBvciBhIHBhcmFtZXRlci5cbiAqXG4gKiBAcGFyYW0gc2V0dGluZ1ZhbHVlIC0gVGhlIHNldHRpbmcgdmFsdWUuXG4gKiBAcGFyYW0gZW52aXJvbm1lbnRWYXJpYWJsZU5hbWUgLSBUaGUgZW52aXJvbm1lbnQgdmFyaWFibGUgbmFtZS5cbiAqIEByZXR1cm5zIFRoZSBzZXR0aW5nIHZhbHVlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbG9hZE9wdGlvbmFsU2V0dGluZyh7XG4gIHNldHRpbmdWYWx1ZSxcbiAgZW52aXJvbm1lbnRWYXJpYWJsZU5hbWUsXG59OiB7XG4gIHNldHRpbmdWYWx1ZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBlbnZpcm9ubWVudFZhcmlhYmxlTmFtZTogc3RyaW5nO1xufSk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGlmICh0eXBlb2Ygc2V0dGluZ1ZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBzZXR0aW5nVmFsdWU7XG4gIH1cblxuICBpZiAoc2V0dGluZ1ZhbHVlICE9IG51bGwgfHwgdHlwZW9mIHByb2Nlc3MgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHNldHRpbmdWYWx1ZSA9IHByb2Nlc3MuZW52W2Vudmlyb25tZW50VmFyaWFibGVOYW1lXTtcblxuICBpZiAoc2V0dGluZ1ZhbHVlID09IG51bGwgfHwgdHlwZW9mIHNldHRpbmdWYWx1ZSAhPT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgcmV0dXJuIHNldHRpbmdWYWx1ZTtcbn1cbiIsICJpbXBvcnQgeyBMb2FkU2V0dGluZ0Vycm9yIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5cbi8qKlxuICogTG9hZHMgYSBgc3RyaW5nYCBzZXR0aW5nIGZyb20gdGhlIGVudmlyb25tZW50IG9yIGEgcGFyYW1ldGVyLlxuICpcbiAqIEBwYXJhbSBzZXR0aW5nVmFsdWUgLSBUaGUgc2V0dGluZyB2YWx1ZS5cbiAqIEBwYXJhbSBlbnZpcm9ubWVudFZhcmlhYmxlTmFtZSAtIFRoZSBlbnZpcm9ubWVudCB2YXJpYWJsZSBuYW1lLlxuICogQHBhcmFtIHNldHRpbmdOYW1lIC0gVGhlIHNldHRpbmcgbmFtZS5cbiAqIEBwYXJhbSBkZXNjcmlwdGlvbiAtIFRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgc2V0dGluZy5cbiAqIEByZXR1cm5zIFRoZSBzZXR0aW5nIHZhbHVlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbG9hZFNldHRpbmcoe1xuICBzZXR0aW5nVmFsdWUsXG4gIGVudmlyb25tZW50VmFyaWFibGVOYW1lLFxuICBzZXR0aW5nTmFtZSxcbiAgZGVzY3JpcHRpb24sXG59OiB7XG4gIHNldHRpbmdWYWx1ZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBlbnZpcm9ubWVudFZhcmlhYmxlTmFtZTogc3RyaW5nO1xuICBzZXR0aW5nTmFtZTogc3RyaW5nO1xuICBkZXNjcmlwdGlvbjogc3RyaW5nO1xufSk6IHN0cmluZyB7XG4gIGlmICh0eXBlb2Ygc2V0dGluZ1ZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBzZXR0aW5nVmFsdWU7XG4gIH1cblxuICBpZiAoc2V0dGluZ1ZhbHVlICE9IG51bGwpIHtcbiAgICB0aHJvdyBuZXcgTG9hZFNldHRpbmdFcnJvcih7XG4gICAgICBtZXNzYWdlOiBgJHtkZXNjcmlwdGlvbn0gc2V0dGluZyBtdXN0IGJlIGEgc3RyaW5nLmAsXG4gICAgfSk7XG4gIH1cblxuICBpZiAodHlwZW9mIHByb2Nlc3MgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgdGhyb3cgbmV3IExvYWRTZXR0aW5nRXJyb3Ioe1xuICAgICAgbWVzc2FnZTpcbiAgICAgICAgYCR7ZGVzY3JpcHRpb259IHNldHRpbmcgaXMgbWlzc2luZy4gYCArXG4gICAgICAgIGBQYXNzIGl0IHVzaW5nIHRoZSAnJHtzZXR0aW5nTmFtZX0nIHBhcmFtZXRlci4gYCArXG4gICAgICAgIGBFbnZpcm9ubWVudCB2YXJpYWJsZXMgaXMgbm90IHN1cHBvcnRlZCBpbiB0aGlzIGVudmlyb25tZW50LmAsXG4gICAgfSk7XG4gIH1cblxuICBzZXR0aW5nVmFsdWUgPSBwcm9jZXNzLmVudltlbnZpcm9ubWVudFZhcmlhYmxlTmFtZV07XG5cbiAgaWYgKHNldHRpbmdWYWx1ZSA9PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IExvYWRTZXR0aW5nRXJyb3Ioe1xuICAgICAgbWVzc2FnZTpcbiAgICAgICAgYCR7ZGVzY3JpcHRpb259IHNldHRpbmcgaXMgbWlzc2luZy4gYCArXG4gICAgICAgIGBQYXNzIGl0IHVzaW5nIHRoZSAnJHtzZXR0aW5nTmFtZX0nIHBhcmFtZXRlciBgICtcbiAgICAgICAgYG9yIHRoZSAke2Vudmlyb25tZW50VmFyaWFibGVOYW1lfSBlbnZpcm9ubWVudCB2YXJpYWJsZS5gLFxuICAgIH0pO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBzZXR0aW5nVmFsdWUgIT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IExvYWRTZXR0aW5nRXJyb3Ioe1xuICAgICAgbWVzc2FnZTpcbiAgICAgICAgYCR7ZGVzY3JpcHRpb259IHNldHRpbmcgbXVzdCBiZSBhIHN0cmluZy4gYCArXG4gICAgICAgIGBUaGUgdmFsdWUgb2YgdGhlICR7ZW52aXJvbm1lbnRWYXJpYWJsZU5hbWV9IGVudmlyb25tZW50IHZhcmlhYmxlIGlzIG5vdCBhIHN0cmluZy5gLFxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHNldHRpbmdWYWx1ZTtcbn1cbiIsICIvKipcbiAqIE1hcHMgYSBtZWRpYSB0eXBlIHRvIGl0cyBjb3JyZXNwb25kaW5nIGZpbGUgZXh0ZW5zaW9uLlxuICogSXQgd2FzIG9yaWdpbmFsbHkgaW50cm9kdWNlZCB0byBzZXQgYSBmaWxlbmFtZSBmb3IgYXVkaW8gZmlsZSB1cGxvYWRzXG4gKiBpbiBodHRwczovL2dpdGh1Yi5jb20vdmVyY2VsL2FpL3B1bGwvODE1OS5cbiAqXG4gKiBAcGFyYW0gbWVkaWFUeXBlIFRoZSBtZWRpYSB0eXBlIHRvIG1hcC5cbiAqIEByZXR1cm5zIFRoZSBjb3JyZXNwb25kaW5nIGZpbGUgZXh0ZW5zaW9uXG4gKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUVFAvR3VpZGVzL01JTUVfdHlwZXMvQ29tbW9uX3R5cGVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtZWRpYVR5cGVUb0V4dGVuc2lvbihtZWRpYVR5cGU6IHN0cmluZykge1xuICBjb25zdCBbX3R5cGUsIHN1YnR5cGUgPSAnJ10gPSBtZWRpYVR5cGUudG9Mb3dlckNhc2UoKS5zcGxpdCgnLycpO1xuXG4gIHJldHVybiAoXG4gICAge1xuICAgICAgbXBlZzogJ21wMycsXG4gICAgICAneC13YXYnOiAnd2F2JyxcbiAgICAgIG9wdXM6ICdvZ2cnLFxuICAgICAgbXA0OiAnbTRhJyxcbiAgICAgICd4LW00YSc6ICdtNGEnLFxuICAgIH1bc3VidHlwZV0gPz8gc3VidHlwZVxuICApO1xufVxuIiwgImltcG9ydCB7XG4gIEpTT05QYXJzZUVycm9yLFxuICBKU09OVmFsdWUsXG4gIFR5cGVWYWxpZGF0aW9uRXJyb3IsXG59IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgc2VjdXJlSnNvblBhcnNlIH0gZnJvbSAnLi9zZWN1cmUtanNvbi1wYXJzZSc7XG5pbXBvcnQgeyBzYWZlVmFsaWRhdGVUeXBlcywgdmFsaWRhdGVUeXBlcyB9IGZyb20gJy4vdmFsaWRhdGUtdHlwZXMnO1xuaW1wb3J0IHsgRmxleGlibGVWYWxpZGF0b3IsIFZhbGlkYXRvciB9IGZyb20gJy4vdmFsaWRhdG9yJztcblxuLyoqXG4gKiBQYXJzZXMgYSBKU09OIHN0cmluZyBpbnRvIGFuIHVua25vd24gb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB0ZXh0IC0gVGhlIEpTT04gc3RyaW5nIHRvIHBhcnNlLlxuICogQHJldHVybnMge0pTT05WYWx1ZX0gLSBUaGUgcGFyc2VkIEpTT04gb2JqZWN0LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcGFyc2VKU09OKG9wdGlvbnM6IHtcbiAgdGV4dDogc3RyaW5nO1xuICBzY2hlbWE/OiB1bmRlZmluZWQ7XG59KTogUHJvbWlzZTxKU09OVmFsdWU+O1xuLyoqXG4gKiBQYXJzZXMgYSBKU09OIHN0cmluZyBpbnRvIGEgc3Ryb25nbHktdHlwZWQgb2JqZWN0IHVzaW5nIHRoZSBwcm92aWRlZCBzY2hlbWEuXG4gKlxuICogQHRlbXBsYXRlIFQgLSBUaGUgdHlwZSBvZiB0aGUgb2JqZWN0IHRvIHBhcnNlIHRoZSBKU09OIGludG8uXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIFRoZSBKU09OIHN0cmluZyB0byBwYXJzZS5cbiAqIEBwYXJhbSB7VmFsaWRhdG9yPFQ+fSBzY2hlbWEgLSBUaGUgc2NoZW1hIHRvIHVzZSBmb3IgcGFyc2luZyB0aGUgSlNPTi5cbiAqIEByZXR1cm5zIHtQcm9taXNlPFQ+fSAtIFRoZSBwYXJzZWQgb2JqZWN0LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcGFyc2VKU09OPFQ+KG9wdGlvbnM6IHtcbiAgdGV4dDogc3RyaW5nO1xuICBzY2hlbWE6IEZsZXhpYmxlVmFsaWRhdG9yPFQ+O1xufSk6IFByb21pc2U8VD47XG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcGFyc2VKU09OPFQ+KHtcbiAgdGV4dCxcbiAgc2NoZW1hLFxufToge1xuICB0ZXh0OiBzdHJpbmc7XG4gIHNjaGVtYT86IEZsZXhpYmxlVmFsaWRhdG9yPFQ+O1xufSk6IFByb21pc2U8VD4ge1xuICB0cnkge1xuICAgIGNvbnN0IHZhbHVlID0gc2VjdXJlSnNvblBhcnNlKHRleHQpO1xuXG4gICAgaWYgKHNjaGVtYSA9PSBudWxsKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbGlkYXRlVHlwZXM8VD4oeyB2YWx1ZSwgc2NoZW1hIH0pO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmIChcbiAgICAgIEpTT05QYXJzZUVycm9yLmlzSW5zdGFuY2UoZXJyb3IpIHx8XG4gICAgICBUeXBlVmFsaWRhdGlvbkVycm9yLmlzSW5zdGFuY2UoZXJyb3IpXG4gICAgKSB7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgSlNPTlBhcnNlRXJyb3IoeyB0ZXh0LCBjYXVzZTogZXJyb3IgfSk7XG4gIH1cbn1cblxuZXhwb3J0IHR5cGUgUGFyc2VSZXN1bHQ8VD4gPVxuICB8IHsgc3VjY2VzczogdHJ1ZTsgdmFsdWU6IFQ7IHJhd1ZhbHVlOiB1bmtub3duIH1cbiAgfCB7XG4gICAgICBzdWNjZXNzOiBmYWxzZTtcbiAgICAgIGVycm9yOiBKU09OUGFyc2VFcnJvciB8IFR5cGVWYWxpZGF0aW9uRXJyb3I7XG4gICAgICByYXdWYWx1ZTogdW5rbm93bjtcbiAgICB9O1xuXG4vKipcbiAqIFNhZmVseSBwYXJzZXMgYSBKU09OIHN0cmluZyBhbmQgcmV0dXJucyB0aGUgcmVzdWx0IGFzIGFuIG9iamVjdCBvZiB0eXBlIGB1bmtub3duYC5cbiAqXG4gKiBAcGFyYW0gdGV4dCAtIFRoZSBKU09OIHN0cmluZyB0byBwYXJzZS5cbiAqIEByZXR1cm5zIHtQcm9taXNlPG9iamVjdD59IEVpdGhlciBhbiBvYmplY3Qgd2l0aCBgc3VjY2VzczogdHJ1ZWAgYW5kIHRoZSBwYXJzZWQgZGF0YSwgb3IgYW4gb2JqZWN0IHdpdGggYHN1Y2Nlc3M6IGZhbHNlYCBhbmQgdGhlIGVycm9yIHRoYXQgb2NjdXJyZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzYWZlUGFyc2VKU09OKG9wdGlvbnM6IHtcbiAgdGV4dDogc3RyaW5nO1xuICBzY2hlbWE/OiB1bmRlZmluZWQ7XG59KTogUHJvbWlzZTxQYXJzZVJlc3VsdDxKU09OVmFsdWU+Pjtcbi8qKlxuICogU2FmZWx5IHBhcnNlcyBhIEpTT04gc3RyaW5nIGludG8gYSBzdHJvbmdseS10eXBlZCBvYmplY3QsIHVzaW5nIGEgcHJvdmlkZWQgc2NoZW1hIHRvIHZhbGlkYXRlIHRoZSBvYmplY3QuXG4gKlxuICogQHRlbXBsYXRlIFQgLSBUaGUgdHlwZSBvZiB0aGUgb2JqZWN0IHRvIHBhcnNlIHRoZSBKU09OIGludG8uXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIFRoZSBKU09OIHN0cmluZyB0byBwYXJzZS5cbiAqIEBwYXJhbSB7VmFsaWRhdG9yPFQ+fSBzY2hlbWEgLSBUaGUgc2NoZW1hIHRvIHVzZSBmb3IgcGFyc2luZyB0aGUgSlNPTi5cbiAqIEByZXR1cm5zIEFuIG9iamVjdCB3aXRoIGVpdGhlciBhIGBzdWNjZXNzYCBmbGFnIGFuZCB0aGUgcGFyc2VkIGFuZCB0eXBlZCBkYXRhLCBvciBhIGBzdWNjZXNzYCBmbGFnIGFuZCBhbiBlcnJvciBvYmplY3QuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzYWZlUGFyc2VKU09OPFQ+KG9wdGlvbnM6IHtcbiAgdGV4dDogc3RyaW5nO1xuICBzY2hlbWE6IEZsZXhpYmxlVmFsaWRhdG9yPFQ+O1xufSk6IFByb21pc2U8UGFyc2VSZXN1bHQ8VD4+O1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNhZmVQYXJzZUpTT048VD4oe1xuICB0ZXh0LFxuICBzY2hlbWEsXG59OiB7XG4gIHRleHQ6IHN0cmluZztcbiAgc2NoZW1hPzogRmxleGlibGVWYWxpZGF0b3I8VD47XG59KTogUHJvbWlzZTxQYXJzZVJlc3VsdDxUPj4ge1xuICB0cnkge1xuICAgIGNvbnN0IHZhbHVlID0gc2VjdXJlSnNvblBhcnNlKHRleHQpO1xuXG4gICAgaWYgKHNjaGVtYSA9PSBudWxsKSB7XG4gICAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlLCB2YWx1ZTogdmFsdWUgYXMgVCwgcmF3VmFsdWU6IHZhbHVlIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHNhZmVWYWxpZGF0ZVR5cGVzPFQ+KHsgdmFsdWUsIHNjaGVtYSB9KTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICBlcnJvcjogSlNPTlBhcnNlRXJyb3IuaXNJbnN0YW5jZShlcnJvcilcbiAgICAgICAgPyBlcnJvclxuICAgICAgICA6IG5ldyBKU09OUGFyc2VFcnJvcih7IHRleHQsIGNhdXNlOiBlcnJvciB9KSxcbiAgICAgIHJhd1ZhbHVlOiB1bmRlZmluZWQsXG4gICAgfTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNQYXJzYWJsZUpzb24oaW5wdXQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICB0cnkge1xuICAgIHNlY3VyZUpzb25QYXJzZShpbnB1dCk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuIiwgIi8vIExpY2Vuc2VkIHVuZGVyIEJTRC0zLUNsYXVzZSAodGhpcyBmaWxlIG9ubHkpXG4vLyBDb2RlIGFkYXB0ZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vZmFzdGlmeS9zZWN1cmUtanNvbi1wYXJzZS9ibG9iLzc4M2ZjYjFiNTQzNDcwOTQ2Njc1OTg0N2NlYzk3NDM4MTkzOTY3M2EvaW5kZXguanNcbi8vXG4vLyBDb3B5cmlnaHQgKGMpIFZlcmNlbCwgSW5jLiAoaHR0cHM6Ly92ZXJjZWwuY29tKVxuLy8gQ29weXJpZ2h0IChjKSAyMDE5IFRoZSBGYXN0aWZ5IFRlYW1cbi8vIENvcHlyaWdodCAoYykgMjAxOSwgU2lkZXdheSBJbmMsIGFuZCBwcm9qZWN0IGNvbnRyaWJ1dG9yc1xuLy8gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vXG4vLyBUaGUgY29tcGxldGUgbGlzdCBvZiBjb250cmlidXRvcnMgY2FuIGJlIGZvdW5kIGF0OlxuLy8gLSBodHRwczovL2dpdGh1Yi5jb20vaGFwaWpzL2JvdXJuZS9ncmFwaHMvY29udHJpYnV0b3JzXG4vLyAtIGh0dHBzOi8vZ2l0aHViLmNvbS9mYXN0aWZ5L3NlY3VyZS1qc29uLXBhcnNlL2dyYXBocy9jb250cmlidXRvcnNcbi8vIC0gaHR0cHM6Ly9naXRodWIuY29tL3ZlcmNlbC9haS9jb21taXRzL21haW4vcGFja2FnZXMvcHJvdmlkZXItdXRpbHMvc3JjL3NlY3VyZS1wYXJzZS1qc29uLnRzXG4vL1xuLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuLy9cbi8vIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbi8vXG4vLyAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXG4vL1xuLy8gMy4gTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgY29weXJpZ2h0IGhvbGRlciBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuLy9cbi8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cblxuY29uc3Qgc3VzcGVjdFByb3RvUnggPSAvXCJfX3Byb3RvX19cIlxccyo6LztcbmNvbnN0IHN1c3BlY3RDb25zdHJ1Y3RvclJ4ID0gL1wiY29uc3RydWN0b3JcIlxccyo6LztcblxuZnVuY3Rpb24gX3BhcnNlKHRleHQ6IHN0cmluZykge1xuICAvLyBQYXJzZSBub3JtYWxseVxuICBjb25zdCBvYmogPSBKU09OLnBhcnNlKHRleHQpO1xuXG4gIC8vIElnbm9yZSBudWxsIGFuZCBub24tb2JqZWN0c1xuICBpZiAob2JqID09PSBudWxsIHx8IHR5cGVvZiBvYmogIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIG9iajtcbiAgfVxuXG4gIGlmIChcbiAgICBzdXNwZWN0UHJvdG9SeC50ZXN0KHRleHQpID09PSBmYWxzZSAmJlxuICAgIHN1c3BlY3RDb25zdHJ1Y3RvclJ4LnRlc3QodGV4dCkgPT09IGZhbHNlXG4gICkge1xuICAgIHJldHVybiBvYmo7XG4gIH1cblxuICAvLyBTY2FuIHJlc3VsdCBmb3IgcHJvdG8ga2V5c1xuICByZXR1cm4gZmlsdGVyKG9iaik7XG59XG5cbmZ1bmN0aW9uIGZpbHRlcihvYmo6IGFueSkge1xuICBsZXQgbmV4dCA9IFtvYmpdO1xuXG4gIHdoaWxlIChuZXh0Lmxlbmd0aCkge1xuICAgIGNvbnN0IG5vZGVzID0gbmV4dDtcbiAgICBuZXh0ID0gW107XG5cbiAgICBmb3IgKGNvbnN0IG5vZGUgb2Ygbm9kZXMpIHtcbiAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobm9kZSwgJ19fcHJvdG9fXycpKSB7XG4gICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcignT2JqZWN0IGNvbnRhaW5zIGZvcmJpZGRlbiBwcm90b3R5cGUgcHJvcGVydHknKTtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobm9kZSwgJ2NvbnN0cnVjdG9yJykgJiZcbiAgICAgICAgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG5vZGUuY29uc3RydWN0b3IsICdwcm90b3R5cGUnKVxuICAgICAgKSB7XG4gICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcignT2JqZWN0IGNvbnRhaW5zIGZvcmJpZGRlbiBwcm90b3R5cGUgcHJvcGVydHknKTtcbiAgICAgIH1cblxuICAgICAgZm9yIChjb25zdCBrZXkgaW4gbm9kZSkge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IG5vZGVba2V5XTtcbiAgICAgICAgaWYgKHZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICBuZXh0LnB1c2godmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBvYmo7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZWN1cmVKc29uUGFyc2UodGV4dDogc3RyaW5nKSB7XG4gIC8vIFBlcmZvcm1hbmNlIG9wdGltaXphdGlvbiwgc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9mYXN0aWZ5L3NlY3VyZS1qc29uLXBhcnNlL3B1bGwvOTBcbiAgY29uc3QgeyBzdGFja1RyYWNlTGltaXQgfSA9IEVycm9yO1xuICBFcnJvci5zdGFja1RyYWNlTGltaXQgPSAwO1xuICB0cnkge1xuICAgIHJldHVybiBfcGFyc2UodGV4dCk7XG4gIH0gZmluYWxseSB7XG4gICAgRXJyb3Iuc3RhY2tUcmFjZUxpbWl0ID0gc3RhY2tUcmFjZUxpbWl0O1xuICB9XG59XG4iLCAiaW1wb3J0IHsgVHlwZVZhbGlkYXRpb25FcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgRmxleGlibGVWYWxpZGF0b3IsIGFzVmFsaWRhdG9yIH0gZnJvbSAnLi92YWxpZGF0b3InO1xuXG4vKipcbiAqIFZhbGlkYXRlcyB0aGUgdHlwZXMgb2YgYW4gdW5rbm93biBvYmplY3QgdXNpbmcgYSBzY2hlbWEgYW5kXG4gKiByZXR1cm4gYSBzdHJvbmdseS10eXBlZCBvYmplY3QuXG4gKlxuICogQHRlbXBsYXRlIFQgLSBUaGUgdHlwZSBvZiB0aGUgb2JqZWN0IHRvIHZhbGlkYXRlLlxuICogQHBhcmFtIHtzdHJpbmd9IG9wdGlvbnMudmFsdWUgLSBUaGUgb2JqZWN0IHRvIHZhbGlkYXRlLlxuICogQHBhcmFtIHtWYWxpZGF0b3I8VD59IG9wdGlvbnMuc2NoZW1hIC0gVGhlIHNjaGVtYSB0byB1c2UgZm9yIHZhbGlkYXRpbmcgdGhlIEpTT04uXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxUPn0gLSBUaGUgdHlwZWQgb2JqZWN0LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gdmFsaWRhdGVUeXBlczxPQkpFQ1Q+KHtcbiAgdmFsdWUsXG4gIHNjaGVtYSxcbn06IHtcbiAgdmFsdWU6IHVua25vd247XG4gIHNjaGVtYTogRmxleGlibGVWYWxpZGF0b3I8T0JKRUNUPjtcbn0pOiBQcm9taXNlPE9CSkVDVD4ge1xuICBjb25zdCByZXN1bHQgPSBhd2FpdCBzYWZlVmFsaWRhdGVUeXBlcyh7IHZhbHVlLCBzY2hlbWEgfSk7XG5cbiAgaWYgKCFyZXN1bHQuc3VjY2Vzcykge1xuICAgIHRocm93IFR5cGVWYWxpZGF0aW9uRXJyb3Iud3JhcCh7IHZhbHVlLCBjYXVzZTogcmVzdWx0LmVycm9yIH0pO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdC52YWx1ZTtcbn1cblxuLyoqXG4gKiBTYWZlbHkgdmFsaWRhdGVzIHRoZSB0eXBlcyBvZiBhbiB1bmtub3duIG9iamVjdCB1c2luZyBhIHNjaGVtYSBhbmRcbiAqIHJldHVybiBhIHN0cm9uZ2x5LXR5cGVkIG9iamVjdC5cbiAqXG4gKiBAdGVtcGxhdGUgVCAtIFRoZSB0eXBlIG9mIHRoZSBvYmplY3QgdG8gdmFsaWRhdGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gb3B0aW9ucy52YWx1ZSAtIFRoZSBKU09OIG9iamVjdCB0byB2YWxpZGF0ZS5cbiAqIEBwYXJhbSB7VmFsaWRhdG9yPFQ+fSBvcHRpb25zLnNjaGVtYSAtIFRoZSBzY2hlbWEgdG8gdXNlIGZvciB2YWxpZGF0aW5nIHRoZSBKU09OLlxuICogQHJldHVybnMgQW4gb2JqZWN0IHdpdGggZWl0aGVyIGEgYHN1Y2Nlc3NgIGZsYWcgYW5kIHRoZSBwYXJzZWQgYW5kIHR5cGVkIGRhdGEsIG9yIGEgYHN1Y2Nlc3NgIGZsYWcgYW5kIGFuIGVycm9yIG9iamVjdC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNhZmVWYWxpZGF0ZVR5cGVzPE9CSkVDVD4oe1xuICB2YWx1ZSxcbiAgc2NoZW1hLFxufToge1xuICB2YWx1ZTogdW5rbm93bjtcbiAgc2NoZW1hOiBGbGV4aWJsZVZhbGlkYXRvcjxPQkpFQ1Q+O1xufSk6IFByb21pc2U8XG4gIHwge1xuICAgICAgc3VjY2VzczogdHJ1ZTtcbiAgICAgIHZhbHVlOiBPQkpFQ1Q7XG4gICAgICByYXdWYWx1ZTogdW5rbm93bjtcbiAgICB9XG4gIHwge1xuICAgICAgc3VjY2VzczogZmFsc2U7XG4gICAgICBlcnJvcjogVHlwZVZhbGlkYXRpb25FcnJvcjtcbiAgICAgIHJhd1ZhbHVlOiB1bmtub3duO1xuICAgIH1cbj4ge1xuICBjb25zdCB2YWxpZGF0b3IgPSBhc1ZhbGlkYXRvcihzY2hlbWEpO1xuXG4gIHRyeSB7XG4gICAgaWYgKHZhbGlkYXRvci52YWxpZGF0ZSA9PSBudWxsKSB7XG4gICAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlLCB2YWx1ZTogdmFsdWUgYXMgT0JKRUNULCByYXdWYWx1ZTogdmFsdWUgfTtcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB2YWxpZGF0b3IudmFsaWRhdGUodmFsdWUpO1xuXG4gICAgaWYgKHJlc3VsdC5zdWNjZXNzKSB7XG4gICAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlLCB2YWx1ZTogcmVzdWx0LnZhbHVlLCByYXdWYWx1ZTogdmFsdWUgfTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICBlcnJvcjogVHlwZVZhbGlkYXRpb25FcnJvci53cmFwKHsgdmFsdWUsIGNhdXNlOiByZXN1bHQuZXJyb3IgfSksXG4gICAgICByYXdWYWx1ZTogdmFsdWUsXG4gICAgfTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICBlcnJvcjogVHlwZVZhbGlkYXRpb25FcnJvci53cmFwKHsgdmFsdWUsIGNhdXNlOiBlcnJvciB9KSxcbiAgICAgIHJhd1ZhbHVlOiB2YWx1ZSxcbiAgICB9O1xuICB9XG59XG4iLCAiaW1wb3J0IHsgVHlwZVZhbGlkYXRpb25FcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgU3RhbmRhcmRTY2hlbWFWMSB9IGZyb20gJ0BzdGFuZGFyZC1zY2hlbWEvc3BlYyc7XG5cbi8qKlxuICogVXNlZCB0byBtYXJrIHZhbGlkYXRvciBmdW5jdGlvbnMgc28gd2UgY2FuIHN1cHBvcnQgYm90aCBab2QgYW5kIGN1c3RvbSBzY2hlbWFzLlxuICovXG5leHBvcnQgY29uc3QgdmFsaWRhdG9yU3ltYm9sID0gU3ltYm9sLmZvcigndmVyY2VsLmFpLnZhbGlkYXRvcicpO1xuXG5leHBvcnQgdHlwZSBWYWxpZGF0aW9uUmVzdWx0PE9CSkVDVD4gPVxuICB8IHsgc3VjY2VzczogdHJ1ZTsgdmFsdWU6IE9CSkVDVCB9XG4gIHwgeyBzdWNjZXNzOiBmYWxzZTsgZXJyb3I6IEVycm9yIH07XG5cbmV4cG9ydCB0eXBlIFZhbGlkYXRvcjxPQkpFQ1QgPSB1bmtub3duPiA9IHtcbiAgLyoqXG4gICAqIFVzZWQgdG8gbWFyayB2YWxpZGF0b3IgZnVuY3Rpb25zIHNvIHdlIGNhbiBzdXBwb3J0IGJvdGggWm9kIGFuZCBjdXN0b20gc2NoZW1hcy5cbiAgICovXG4gIFt2YWxpZGF0b3JTeW1ib2xdOiB0cnVlO1xuXG4gIC8qKlxuICAgKiBPcHRpb25hbC4gVmFsaWRhdGVzIHRoYXQgdGhlIHN0cnVjdHVyZSBvZiBhIHZhbHVlIG1hdGNoZXMgdGhpcyBzY2hlbWEsXG4gICAqIGFuZCByZXR1cm5zIGEgdHlwZWQgdmVyc2lvbiBvZiB0aGUgdmFsdWUgaWYgaXQgZG9lcy5cbiAgICovXG4gIHJlYWRvbmx5IHZhbGlkYXRlPzogKFxuICAgIHZhbHVlOiB1bmtub3duLFxuICApID0+IFZhbGlkYXRpb25SZXN1bHQ8T0JKRUNUPiB8IFByb21pc2VMaWtlPFZhbGlkYXRpb25SZXN1bHQ8T0JKRUNUPj47XG59O1xuXG4vKipcbiAqIENyZWF0ZSBhIHZhbGlkYXRvci5cbiAqXG4gKiBAcGFyYW0gdmFsaWRhdGUgQSB2YWxpZGF0aW9uIGZ1bmN0aW9uIGZvciB0aGUgc2NoZW1hLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdG9yPE9CSkVDVD4oXG4gIHZhbGlkYXRlPzpcbiAgICB8IHVuZGVmaW5lZFxuICAgIHwgKChcbiAgICAgICAgdmFsdWU6IHVua25vd24sXG4gICAgICApID0+IFZhbGlkYXRpb25SZXN1bHQ8T0JKRUNUPiB8IFByb21pc2VMaWtlPFZhbGlkYXRpb25SZXN1bHQ8T0JKRUNUPj4pLFxuKTogVmFsaWRhdG9yPE9CSkVDVD4ge1xuICByZXR1cm4geyBbdmFsaWRhdG9yU3ltYm9sXTogdHJ1ZSwgdmFsaWRhdGUgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzVmFsaWRhdG9yKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgVmFsaWRhdG9yIHtcbiAgcmV0dXJuIChcbiAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXG4gICAgdmFsdWUgIT09IG51bGwgJiZcbiAgICB2YWxpZGF0b3JTeW1ib2wgaW4gdmFsdWUgJiZcbiAgICB2YWx1ZVt2YWxpZGF0b3JTeW1ib2xdID09PSB0cnVlICYmXG4gICAgJ3ZhbGlkYXRlJyBpbiB2YWx1ZVxuICApO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSB2YWxpZGF0b3Igd2l0aCBkZWZlcnJlZCBjcmVhdGlvbi5cbiAqIFRoaXMgaXMgaW1wb3J0YW50IHRvIHJlZHVjZSB0aGUgc3RhcnR1cCB0aW1lIG9mIHRoZSBsaWJyYXJ5XG4gKiBhbmQgdG8gYXZvaWQgaW5pdGlhbGl6aW5nIHVudXNlZCB2YWxpZGF0b3JzLlxuICpcbiAqIEBwYXJhbSBjcmVhdGVWYWxpZGF0b3IgQSBmdW5jdGlvbiB0aGF0IGNyZWF0ZXMgYSB2YWxpZGF0b3IuXG4gKiBAcmV0dXJucyBBIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBhIHZhbGlkYXRvci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxhenlWYWxpZGF0b3I8T0JKRUNUPihcbiAgY3JlYXRlVmFsaWRhdG9yOiAoKSA9PiBWYWxpZGF0b3I8T0JKRUNUPixcbik6IExhenlWYWxpZGF0b3I8T0JKRUNUPiB7XG4gIC8vIGNhY2hlIHRoZSB2YWxpZGF0b3IgdG8gYXZvaWQgaW5pdGlhbGl6aW5nIGl0IG11bHRpcGxlIHRpbWVzXG4gIGxldCB2YWxpZGF0b3I6IFZhbGlkYXRvcjxPQkpFQ1Q+IHwgdW5kZWZpbmVkO1xuICByZXR1cm4gKCkgPT4ge1xuICAgIGlmICh2YWxpZGF0b3IgPT0gbnVsbCkge1xuICAgICAgdmFsaWRhdG9yID0gY3JlYXRlVmFsaWRhdG9yKCk7XG4gICAgfVxuICAgIHJldHVybiB2YWxpZGF0b3I7XG4gIH07XG59XG5cbmV4cG9ydCB0eXBlIExhenlWYWxpZGF0b3I8T0JKRUNUPiA9ICgpID0+IFZhbGlkYXRvcjxPQkpFQ1Q+O1xuXG5leHBvcnQgdHlwZSBGbGV4aWJsZVZhbGlkYXRvcjxPQkpFQ1Q+ID1cbiAgfCBWYWxpZGF0b3I8T0JKRUNUPlxuICB8IExhenlWYWxpZGF0b3I8T0JKRUNUPlxuICB8IFN0YW5kYXJkU2NoZW1hVjE8dW5rbm93biwgT0JKRUNUPjtcblxuZXhwb3J0IHR5cGUgSW5mZXJWYWxpZGF0b3I8U0NIRU1BPiA9XG4gIFNDSEVNQSBleHRlbmRzIFN0YW5kYXJkU2NoZW1hVjE8dW5rbm93biwgaW5mZXIgVD5cbiAgICA/IFRcbiAgICA6IFNDSEVNQSBleHRlbmRzIExhenlWYWxpZGF0b3I8aW5mZXIgVD5cbiAgICAgID8gVFxuICAgICAgOiBTQ0hFTUEgZXh0ZW5kcyBWYWxpZGF0b3I8aW5mZXIgVD5cbiAgICAgICAgPyBUXG4gICAgICAgIDogbmV2ZXI7XG5cbmV4cG9ydCBmdW5jdGlvbiBhc1ZhbGlkYXRvcjxPQkpFQ1Q+KFxuICB2YWx1ZTogRmxleGlibGVWYWxpZGF0b3I8T0JKRUNUPixcbik6IFZhbGlkYXRvcjxPQkpFQ1Q+IHtcbiAgcmV0dXJuIGlzVmFsaWRhdG9yKHZhbHVlKVxuICAgID8gdmFsdWVcbiAgICA6IHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJ1xuICAgICAgPyB2YWx1ZSgpXG4gICAgICA6IHN0YW5kYXJkU2NoZW1hVmFsaWRhdG9yKHZhbHVlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHN0YW5kYXJkU2NoZW1hVmFsaWRhdG9yPE9CSkVDVD4oXG4gIHN0YW5kYXJkU2NoZW1hOiBTdGFuZGFyZFNjaGVtYVYxPHVua25vd24sIE9CSkVDVD4sXG4pOiBWYWxpZGF0b3I8T0JKRUNUPiB7XG4gIHJldHVybiB2YWxpZGF0b3IoYXN5bmMgdmFsdWUgPT4ge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHN0YW5kYXJkU2NoZW1hWyd+c3RhbmRhcmQnXS52YWxpZGF0ZSh2YWx1ZSk7XG5cbiAgICByZXR1cm4gcmVzdWx0Lmlzc3VlcyA9PSBudWxsXG4gICAgICA/IHsgc3VjY2VzczogdHJ1ZSwgdmFsdWU6IHJlc3VsdC52YWx1ZSB9XG4gICAgICA6IHtcbiAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICBlcnJvcjogbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3Ioe1xuICAgICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgICBjYXVzZTogcmVzdWx0Lmlzc3VlcyxcbiAgICAgICAgICB9KSxcbiAgICAgICAgfTtcbiAgfSk7XG59XG4iLCAiaW1wb3J0IHtcbiAgRXZlbnRTb3VyY2VNZXNzYWdlLFxuICBFdmVudFNvdXJjZVBhcnNlclN0cmVhbSxcbn0gZnJvbSAnZXZlbnRzb3VyY2UtcGFyc2VyL3N0cmVhbSc7XG5pbXBvcnQgeyBQYXJzZVJlc3VsdCwgc2FmZVBhcnNlSlNPTiB9IGZyb20gJy4vcGFyc2UtanNvbic7XG5pbXBvcnQgeyBGbGV4aWJsZVZhbGlkYXRvciB9IGZyb20gJy4vdmFsaWRhdG9yJztcblxuLyoqXG4gKiBQYXJzZXMgYSBKU09OIGV2ZW50IHN0cmVhbSBpbnRvIGEgc3RyZWFtIG9mIHBhcnNlZCBKU09OIG9iamVjdHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUpzb25FdmVudFN0cmVhbTxUPih7XG4gIHN0cmVhbSxcbiAgc2NoZW1hLFxufToge1xuICBzdHJlYW06IFJlYWRhYmxlU3RyZWFtPFVpbnQ4QXJyYXk+O1xuICBzY2hlbWE6IEZsZXhpYmxlVmFsaWRhdG9yPFQ+O1xufSk6IFJlYWRhYmxlU3RyZWFtPFBhcnNlUmVzdWx0PFQ+PiB7XG4gIHJldHVybiBzdHJlYW1cbiAgICAucGlwZVRocm91Z2gobmV3IFRleHREZWNvZGVyU3RyZWFtKCkpXG4gICAgLnBpcGVUaHJvdWdoKG5ldyBFdmVudFNvdXJjZVBhcnNlclN0cmVhbSgpKVxuICAgIC5waXBlVGhyb3VnaChcbiAgICAgIG5ldyBUcmFuc2Zvcm1TdHJlYW08RXZlbnRTb3VyY2VNZXNzYWdlLCBQYXJzZVJlc3VsdDxUPj4oe1xuICAgICAgICBhc3luYyB0cmFuc2Zvcm0oeyBkYXRhIH0sIGNvbnRyb2xsZXIpIHtcbiAgICAgICAgICAvLyBpZ25vcmUgdGhlICdET05FJyBldmVudCB0aGF0IGUuZy4gT3BlbkFJIHNlbmRzOlxuICAgICAgICAgIGlmIChkYXRhID09PSAnW0RPTkVdJykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShhd2FpdCBzYWZlUGFyc2VKU09OKHsgdGV4dDogZGF0YSwgc2NoZW1hIH0pKTtcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgICk7XG59XG4iLCAiaW1wb3J0IHsgSW52YWxpZEFyZ3VtZW50RXJyb3IgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcbmltcG9ydCB7IHNhZmVWYWxpZGF0ZVR5cGVzIH0gZnJvbSAnLi92YWxpZGF0ZS10eXBlcyc7XG5pbXBvcnQgeyBGbGV4aWJsZVZhbGlkYXRvciB9IGZyb20gJy4vdmFsaWRhdG9yJztcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHBhcnNlUHJvdmlkZXJPcHRpb25zPE9QVElPTlM+KHtcbiAgcHJvdmlkZXIsXG4gIHByb3ZpZGVyT3B0aW9ucyxcbiAgc2NoZW1hLFxufToge1xuICBwcm92aWRlcjogc3RyaW5nO1xuICBwcm92aWRlck9wdGlvbnM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgdW5kZWZpbmVkO1xuICBzY2hlbWE6IEZsZXhpYmxlVmFsaWRhdG9yPE9QVElPTlM+O1xufSk6IFByb21pc2U8T1BUSU9OUyB8IHVuZGVmaW5lZD4ge1xuICBpZiAocHJvdmlkZXJPcHRpb25zPy5bcHJvdmlkZXJdID09IG51bGwpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgY29uc3QgcGFyc2VkUHJvdmlkZXJPcHRpb25zID0gYXdhaXQgc2FmZVZhbGlkYXRlVHlwZXM8T1BUSU9OUyB8IHVuZGVmaW5lZD4oe1xuICAgIHZhbHVlOiBwcm92aWRlck9wdGlvbnNbcHJvdmlkZXJdLFxuICAgIHNjaGVtYSxcbiAgfSk7XG5cbiAgaWYgKCFwYXJzZWRQcm92aWRlck9wdGlvbnMuc3VjY2Vzcykge1xuICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFcnJvcih7XG4gICAgICBhcmd1bWVudDogJ3Byb3ZpZGVyT3B0aW9ucycsXG4gICAgICBtZXNzYWdlOiBgaW52YWxpZCAke3Byb3ZpZGVyfSBwcm92aWRlciBvcHRpb25zYCxcbiAgICAgIGNhdXNlOiBwYXJzZWRQcm92aWRlck9wdGlvbnMuZXJyb3IsXG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gcGFyc2VkUHJvdmlkZXJPcHRpb25zLnZhbHVlO1xufVxuIiwgImltcG9ydCB7IEFQSUNhbGxFcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgZXh0cmFjdFJlc3BvbnNlSGVhZGVycyB9IGZyb20gJy4vZXh0cmFjdC1yZXNwb25zZS1oZWFkZXJzJztcbmltcG9ydCB7IEZldGNoRnVuY3Rpb24gfSBmcm9tICcuL2ZldGNoLWZ1bmN0aW9uJztcbmltcG9ydCB7IGhhbmRsZUZldGNoRXJyb3IgfSBmcm9tICcuL2hhbmRsZS1mZXRjaC1lcnJvcic7XG5pbXBvcnQgeyBpc0Fib3J0RXJyb3IgfSBmcm9tICcuL2lzLWFib3J0LWVycm9yJztcbmltcG9ydCB7IFJlc3BvbnNlSGFuZGxlciB9IGZyb20gJy4vcmVzcG9uc2UtaGFuZGxlcic7XG5pbXBvcnQgeyBnZXRSdW50aW1lRW52aXJvbm1lbnRVc2VyQWdlbnQgfSBmcm9tICcuL2dldC1ydW50aW1lLWVudmlyb25tZW50LXVzZXItYWdlbnQnO1xuaW1wb3J0IHsgd2l0aFVzZXJBZ2VudFN1ZmZpeCB9IGZyb20gJy4vd2l0aC11c2VyLWFnZW50LXN1ZmZpeCc7XG5pbXBvcnQgeyBWRVJTSU9OIH0gZnJvbSAnLi92ZXJzaW9uJztcblxuLy8gdXNlIGZ1bmN0aW9uIHRvIGFsbG93IGZvciBtb2NraW5nIGluIHRlc3RzOlxuY29uc3QgZ2V0T3JpZ2luYWxGZXRjaCA9ICgpID0+IGdsb2JhbFRoaXMuZmV0Y2g7XG5cbmV4cG9ydCBjb25zdCBwb3N0SnNvblRvQXBpID0gYXN5bmMgPFQ+KHtcbiAgdXJsLFxuICBoZWFkZXJzLFxuICBib2R5LFxuICBmYWlsZWRSZXNwb25zZUhhbmRsZXIsXG4gIHN1Y2Nlc3NmdWxSZXNwb25zZUhhbmRsZXIsXG4gIGFib3J0U2lnbmFsLFxuICBmZXRjaCxcbn06IHtcbiAgdXJsOiBzdHJpbmc7XG4gIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+O1xuICBib2R5OiB1bmtub3duO1xuICBmYWlsZWRSZXNwb25zZUhhbmRsZXI6IFJlc3BvbnNlSGFuZGxlcjxBUElDYWxsRXJyb3I+O1xuICBzdWNjZXNzZnVsUmVzcG9uc2VIYW5kbGVyOiBSZXNwb25zZUhhbmRsZXI8VD47XG4gIGFib3J0U2lnbmFsPzogQWJvcnRTaWduYWw7XG4gIGZldGNoPzogRmV0Y2hGdW5jdGlvbjtcbn0pID0+XG4gIHBvc3RUb0FwaSh7XG4gICAgdXJsLFxuICAgIGhlYWRlcnM6IHtcbiAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAuLi5oZWFkZXJzLFxuICAgIH0sXG4gICAgYm9keToge1xuICAgICAgY29udGVudDogSlNPTi5zdHJpbmdpZnkoYm9keSksXG4gICAgICB2YWx1ZXM6IGJvZHksXG4gICAgfSxcbiAgICBmYWlsZWRSZXNwb25zZUhhbmRsZXIsXG4gICAgc3VjY2Vzc2Z1bFJlc3BvbnNlSGFuZGxlcixcbiAgICBhYm9ydFNpZ25hbCxcbiAgICBmZXRjaCxcbiAgfSk7XG5cbmV4cG9ydCBjb25zdCBwb3N0Rm9ybURhdGFUb0FwaSA9IGFzeW5jIDxUPih7XG4gIHVybCxcbiAgaGVhZGVycyxcbiAgZm9ybURhdGEsXG4gIGZhaWxlZFJlc3BvbnNlSGFuZGxlcixcbiAgc3VjY2Vzc2Z1bFJlc3BvbnNlSGFuZGxlcixcbiAgYWJvcnRTaWduYWwsXG4gIGZldGNoLFxufToge1xuICB1cmw6IHN0cmluZztcbiAgaGVhZGVycz86IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD47XG4gIGZvcm1EYXRhOiBGb3JtRGF0YTtcbiAgZmFpbGVkUmVzcG9uc2VIYW5kbGVyOiBSZXNwb25zZUhhbmRsZXI8QVBJQ2FsbEVycm9yPjtcbiAgc3VjY2Vzc2Z1bFJlc3BvbnNlSGFuZGxlcjogUmVzcG9uc2VIYW5kbGVyPFQ+O1xuICBhYm9ydFNpZ25hbD86IEFib3J0U2lnbmFsO1xuICBmZXRjaD86IEZldGNoRnVuY3Rpb247XG59KSA9PlxuICBwb3N0VG9BcGkoe1xuICAgIHVybCxcbiAgICBoZWFkZXJzLFxuICAgIGJvZHk6IHtcbiAgICAgIGNvbnRlbnQ6IGZvcm1EYXRhLFxuICAgICAgdmFsdWVzOiBPYmplY3QuZnJvbUVudHJpZXMoKGZvcm1EYXRhIGFzIGFueSkuZW50cmllcygpKSxcbiAgICB9LFxuICAgIGZhaWxlZFJlc3BvbnNlSGFuZGxlcixcbiAgICBzdWNjZXNzZnVsUmVzcG9uc2VIYW5kbGVyLFxuICAgIGFib3J0U2lnbmFsLFxuICAgIGZldGNoLFxuICB9KTtcblxuZXhwb3J0IGNvbnN0IHBvc3RUb0FwaSA9IGFzeW5jIDxUPih7XG4gIHVybCxcbiAgaGVhZGVycyA9IHt9LFxuICBib2R5LFxuICBzdWNjZXNzZnVsUmVzcG9uc2VIYW5kbGVyLFxuICBmYWlsZWRSZXNwb25zZUhhbmRsZXIsXG4gIGFib3J0U2lnbmFsLFxuICBmZXRjaCA9IGdldE9yaWdpbmFsRmV0Y2goKSxcbn06IHtcbiAgdXJsOiBzdHJpbmc7XG4gIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+O1xuICBib2R5OiB7XG4gICAgY29udGVudDogc3RyaW5nIHwgRm9ybURhdGEgfCBVaW50OEFycmF5O1xuICAgIHZhbHVlczogdW5rbm93bjtcbiAgfTtcbiAgZmFpbGVkUmVzcG9uc2VIYW5kbGVyOiBSZXNwb25zZUhhbmRsZXI8RXJyb3I+O1xuICBzdWNjZXNzZnVsUmVzcG9uc2VIYW5kbGVyOiBSZXNwb25zZUhhbmRsZXI8VD47XG4gIGFib3J0U2lnbmFsPzogQWJvcnRTaWduYWw7XG4gIGZldGNoPzogRmV0Y2hGdW5jdGlvbjtcbn0pID0+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHVybCwge1xuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBoZWFkZXJzOiB3aXRoVXNlckFnZW50U3VmZml4KFxuICAgICAgICBoZWFkZXJzLFxuICAgICAgICBgYWktc2RrL3Byb3ZpZGVyLXV0aWxzLyR7VkVSU0lPTn1gLFxuICAgICAgICBnZXRSdW50aW1lRW52aXJvbm1lbnRVc2VyQWdlbnQoKSxcbiAgICAgICksXG4gICAgICBib2R5OiBib2R5LmNvbnRlbnQsXG4gICAgICBzaWduYWw6IGFib3J0U2lnbmFsLFxuICAgIH0pO1xuXG4gICAgY29uc3QgcmVzcG9uc2VIZWFkZXJzID0gZXh0cmFjdFJlc3BvbnNlSGVhZGVycyhyZXNwb25zZSk7XG5cbiAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICBsZXQgZXJyb3JJbmZvcm1hdGlvbjoge1xuICAgICAgICB2YWx1ZTogRXJyb3I7XG4gICAgICAgIHJlc3BvbnNlSGVhZGVycz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gfCB1bmRlZmluZWQ7XG4gICAgICB9O1xuXG4gICAgICB0cnkge1xuICAgICAgICBlcnJvckluZm9ybWF0aW9uID0gYXdhaXQgZmFpbGVkUmVzcG9uc2VIYW5kbGVyKHtcbiAgICAgICAgICByZXNwb25zZSxcbiAgICAgICAgICB1cmwsXG4gICAgICAgICAgcmVxdWVzdEJvZHlWYWx1ZXM6IGJvZHkudmFsdWVzLFxuICAgICAgICB9KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGlmIChpc0Fib3J0RXJyb3IoZXJyb3IpIHx8IEFQSUNhbGxFcnJvci5pc0luc3RhbmNlKGVycm9yKSkge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhyb3cgbmV3IEFQSUNhbGxFcnJvcih7XG4gICAgICAgICAgbWVzc2FnZTogJ0ZhaWxlZCB0byBwcm9jZXNzIGVycm9yIHJlc3BvbnNlJyxcbiAgICAgICAgICBjYXVzZTogZXJyb3IsXG4gICAgICAgICAgc3RhdHVzQ29kZTogcmVzcG9uc2Uuc3RhdHVzLFxuICAgICAgICAgIHVybCxcbiAgICAgICAgICByZXNwb25zZUhlYWRlcnMsXG4gICAgICAgICAgcmVxdWVzdEJvZHlWYWx1ZXM6IGJvZHkudmFsdWVzLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgdGhyb3cgZXJyb3JJbmZvcm1hdGlvbi52YWx1ZTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IHN1Y2Nlc3NmdWxSZXNwb25zZUhhbmRsZXIoe1xuICAgICAgICByZXNwb25zZSxcbiAgICAgICAgdXJsLFxuICAgICAgICByZXF1ZXN0Qm9keVZhbHVlczogYm9keS52YWx1ZXMsXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgaWYgKGlzQWJvcnRFcnJvcihlcnJvcikgfHwgQVBJQ2FsbEVycm9yLmlzSW5zdGFuY2UoZXJyb3IpKSB7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdGhyb3cgbmV3IEFQSUNhbGxFcnJvcih7XG4gICAgICAgIG1lc3NhZ2U6ICdGYWlsZWQgdG8gcHJvY2VzcyBzdWNjZXNzZnVsIHJlc3BvbnNlJyxcbiAgICAgICAgY2F1c2U6IGVycm9yLFxuICAgICAgICBzdGF0dXNDb2RlOiByZXNwb25zZS5zdGF0dXMsXG4gICAgICAgIHVybCxcbiAgICAgICAgcmVzcG9uc2VIZWFkZXJzLFxuICAgICAgICByZXF1ZXN0Qm9keVZhbHVlczogYm9keS52YWx1ZXMsXG4gICAgICB9KTtcbiAgICB9XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgdGhyb3cgaGFuZGxlRmV0Y2hFcnJvcih7IGVycm9yLCB1cmwsIHJlcXVlc3RCb2R5VmFsdWVzOiBib2R5LnZhbHVlcyB9KTtcbiAgfVxufTtcbiIsICJpbXBvcnQgeyBKU09OVmFsdWUsIExhbmd1YWdlTW9kZWxWMlRvb2xSZXN1bHRQYXJ0IH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQgeyBGbGV4aWJsZVNjaGVtYSB9IGZyb20gJy4uL3NjaGVtYSc7XG5pbXBvcnQgeyBNb2RlbE1lc3NhZ2UgfSBmcm9tICcuL21vZGVsLW1lc3NhZ2UnO1xuaW1wb3J0IHsgUHJvdmlkZXJPcHRpb25zIH0gZnJvbSAnLi9wcm92aWRlci1vcHRpb25zJztcblxuLyoqXG4gKiBBZGRpdGlvbmFsIG9wdGlvbnMgdGhhdCBhcmUgc2VudCBpbnRvIGVhY2ggdG9vbCBjYWxsLlxuICovXG4vLyBUT0RPIEFJIFNESyA2OiByZW5hbWUgdG8gVG9vbEV4ZWN1dGlvbk9wdGlvbnNcbmV4cG9ydCBpbnRlcmZhY2UgVG9vbENhbGxPcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSBJRCBvZiB0aGUgdG9vbCBjYWxsLiBZb3UgY2FuIHVzZSBpdCBlLmcuIHdoZW4gc2VuZGluZyB0b29sLWNhbGwgcmVsYXRlZCBpbmZvcm1hdGlvbiB3aXRoIHN0cmVhbSBkYXRhLlxuICAgKi9cbiAgdG9vbENhbGxJZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBNZXNzYWdlcyB0aGF0IHdlcmUgc2VudCB0byB0aGUgbGFuZ3VhZ2UgbW9kZWwgdG8gaW5pdGlhdGUgdGhlIHJlc3BvbnNlIHRoYXQgY29udGFpbmVkIHRoZSB0b29sIGNhbGwuXG4gICAqIFRoZSBtZXNzYWdlcyAqKmRvIG5vdCoqIGluY2x1ZGUgdGhlIHN5c3RlbSBwcm9tcHQgbm9yIHRoZSBhc3Npc3RhbnQgcmVzcG9uc2UgdGhhdCBjb250YWluZWQgdGhlIHRvb2wgY2FsbC5cbiAgICovXG4gIG1lc3NhZ2VzOiBNb2RlbE1lc3NhZ2VbXTtcblxuICAvKipcbiAgICogQW4gb3B0aW9uYWwgYWJvcnQgc2lnbmFsIHRoYXQgaW5kaWNhdGVzIHRoYXQgdGhlIG92ZXJhbGwgb3BlcmF0aW9uIHNob3VsZCBiZSBhYm9ydGVkLlxuICAgKi9cbiAgYWJvcnRTaWduYWw/OiBBYm9ydFNpZ25hbDtcblxuICAvKipcbiAgICogQWRkaXRpb25hbCBjb250ZXh0LlxuICAgKlxuICAgKiBFeHBlcmltZW50YWwgKGNhbiBicmVhayBpbiBwYXRjaCByZWxlYXNlcykuXG4gICAqL1xuICBleHBlcmltZW50YWxfY29udGV4dD86IHVua25vd247XG59XG5cbmV4cG9ydCB0eXBlIFRvb2xFeGVjdXRlRnVuY3Rpb248SU5QVVQsIE9VVFBVVD4gPSAoXG4gIGlucHV0OiBJTlBVVCxcbiAgb3B0aW9uczogVG9vbENhbGxPcHRpb25zLFxuKSA9PiBBc3luY0l0ZXJhYmxlPE9VVFBVVD4gfCBQcm9taXNlTGlrZTxPVVRQVVQ+IHwgT1VUUFVUO1xuXG4vLyAwIGV4dGVuZHMgMSAmIE4gY2hlY2tzIGZvciBhbnlcbi8vIFtOXSBleHRlbmRzIFtuZXZlcl0gY2hlY2tzIGZvciBuZXZlclxudHlwZSBOZXZlck9wdGlvbmFsPE4sIFQ+ID0gMCBleHRlbmRzIDEgJiBOXG4gID8gUGFydGlhbDxUPlxuICA6IFtOXSBleHRlbmRzIFtuZXZlcl1cbiAgICA/IFBhcnRpYWw8UmVjb3JkPGtleW9mIFQsIHVuZGVmaW5lZD4+XG4gICAgOiBUO1xuXG50eXBlIFRvb2xPdXRwdXRQcm9wZXJ0aWVzPElOUFVULCBPVVRQVVQ+ID0gTmV2ZXJPcHRpb25hbDxcbiAgT1VUUFVULFxuICB8IHtcbiAgICAgIC8qKlxuQW4gYXN5bmMgZnVuY3Rpb24gdGhhdCBpcyBjYWxsZWQgd2l0aCB0aGUgYXJndW1lbnRzIGZyb20gdGhlIHRvb2wgY2FsbCBhbmQgcHJvZHVjZXMgYSByZXN1bHQuXG5JZiBub3QgcHJvdmlkZWQsIHRoZSB0b29sIHdpbGwgbm90IGJlIGV4ZWN1dGVkIGF1dG9tYXRpY2FsbHkuXG5cbkBhcmdzIGlzIHRoZSBpbnB1dCBvZiB0aGUgdG9vbCBjYWxsLlxuQG9wdGlvbnMuYWJvcnRTaWduYWwgaXMgYSBzaWduYWwgdGhhdCBjYW4gYmUgdXNlZCB0byBhYm9ydCB0aGUgdG9vbCBjYWxsLlxuICAgICovXG4gICAgICBleGVjdXRlOiBUb29sRXhlY3V0ZUZ1bmN0aW9uPElOUFVULCBPVVRQVVQ+O1xuXG4gICAgICBvdXRwdXRTY2hlbWE/OiBGbGV4aWJsZVNjaGVtYTxPVVRQVVQ+O1xuICAgIH1cbiAgfCB7XG4gICAgICBvdXRwdXRTY2hlbWE6IEZsZXhpYmxlU2NoZW1hPE9VVFBVVD47XG5cbiAgICAgIGV4ZWN1dGU/OiBuZXZlcjtcbiAgICB9XG4+O1xuXG4vKipcbkEgdG9vbCBjb250YWlucyB0aGUgZGVzY3JpcHRpb24gYW5kIHRoZSBzY2hlbWEgb2YgdGhlIGlucHV0IHRoYXQgdGhlIHRvb2wgZXhwZWN0cy5cblRoaXMgZW5hYmxlcyB0aGUgbGFuZ3VhZ2UgbW9kZWwgdG8gZ2VuZXJhdGUgdGhlIGlucHV0LlxuXG5UaGUgdG9vbCBjYW4gYWxzbyBjb250YWluIGFuIG9wdGlvbmFsIGV4ZWN1dGUgZnVuY3Rpb24gZm9yIHRoZSBhY3R1YWwgZXhlY3V0aW9uIGZ1bmN0aW9uIG9mIHRoZSB0b29sLlxuICovXG5leHBvcnQgdHlwZSBUb29sPFxuICBJTlBVVCBleHRlbmRzIEpTT05WYWx1ZSB8IHVua25vd24gfCBuZXZlciA9IGFueSxcbiAgT1VUUFVUIGV4dGVuZHMgSlNPTlZhbHVlIHwgdW5rbm93biB8IG5ldmVyID0gYW55LFxuPiA9IHtcbiAgLyoqXG5BbiBvcHRpb25hbCBkZXNjcmlwdGlvbiBvZiB3aGF0IHRoZSB0b29sIGRvZXMuXG5XaWxsIGJlIHVzZWQgYnkgdGhlIGxhbmd1YWdlIG1vZGVsIHRvIGRlY2lkZSB3aGV0aGVyIHRvIHVzZSB0aGUgdG9vbC5cbk5vdCB1c2VkIGZvciBwcm92aWRlci1kZWZpbmVkIHRvb2xzLlxuICAgKi9cbiAgZGVzY3JpcHRpb24/OiBzdHJpbmc7XG5cbiAgLyoqXG5BZGRpdGlvbmFsIHByb3ZpZGVyLXNwZWNpZmljIG1ldGFkYXRhLiBUaGV5IGFyZSBwYXNzZWQgdGhyb3VnaFxudG8gdGhlIHByb3ZpZGVyIGZyb20gdGhlIEFJIFNESyBhbmQgZW5hYmxlIHByb3ZpZGVyLXNwZWNpZmljXG5mdW5jdGlvbmFsaXR5IHRoYXQgY2FuIGJlIGZ1bGx5IGVuY2Fwc3VsYXRlZCBpbiB0aGUgcHJvdmlkZXIuXG4gICAqL1xuICBwcm92aWRlck9wdGlvbnM/OiBQcm92aWRlck9wdGlvbnM7XG5cbiAgLyoqXG5UaGUgc2NoZW1hIG9mIHRoZSBpbnB1dCB0aGF0IHRoZSB0b29sIGV4cGVjdHMuIFRoZSBsYW5ndWFnZSBtb2RlbCB3aWxsIHVzZSB0aGlzIHRvIGdlbmVyYXRlIHRoZSBpbnB1dC5cbkl0IGlzIGFsc28gdXNlZCB0byB2YWxpZGF0ZSB0aGUgb3V0cHV0IG9mIHRoZSBsYW5ndWFnZSBtb2RlbC5cblVzZSBkZXNjcmlwdGlvbnMgdG8gbWFrZSB0aGUgaW5wdXQgdW5kZXJzdGFuZGFibGUgZm9yIHRoZSBsYW5ndWFnZSBtb2RlbC5cbiAgICovXG4gIGlucHV0U2NoZW1hOiBGbGV4aWJsZVNjaGVtYTxJTlBVVD47XG5cbiAgLyoqXG4gICAqIE9wdGlvbmFsIGZ1bmN0aW9uIHRoYXQgaXMgY2FsbGVkIHdoZW4gdGhlIGFyZ3VtZW50IHN0cmVhbWluZyBzdGFydHMuXG4gICAqIE9ubHkgY2FsbGVkIHdoZW4gdGhlIHRvb2wgaXMgdXNlZCBpbiBhIHN0cmVhbWluZyBjb250ZXh0LlxuICAgKi9cbiAgb25JbnB1dFN0YXJ0PzogKG9wdGlvbnM6IFRvb2xDYWxsT3B0aW9ucykgPT4gdm9pZCB8IFByb21pc2VMaWtlPHZvaWQ+O1xuXG4gIC8qKlxuICAgKiBPcHRpb25hbCBmdW5jdGlvbiB0aGF0IGlzIGNhbGxlZCB3aGVuIGFuIGFyZ3VtZW50IHN0cmVhbWluZyBkZWx0YSBpcyBhdmFpbGFibGUuXG4gICAqIE9ubHkgY2FsbGVkIHdoZW4gdGhlIHRvb2wgaXMgdXNlZCBpbiBhIHN0cmVhbWluZyBjb250ZXh0LlxuICAgKi9cbiAgb25JbnB1dERlbHRhPzogKFxuICAgIG9wdGlvbnM6IHsgaW5wdXRUZXh0RGVsdGE6IHN0cmluZyB9ICYgVG9vbENhbGxPcHRpb25zLFxuICApID0+IHZvaWQgfCBQcm9taXNlTGlrZTx2b2lkPjtcblxuICAvKipcbiAgICogT3B0aW9uYWwgZnVuY3Rpb24gdGhhdCBpcyBjYWxsZWQgd2hlbiBhIHRvb2wgY2FsbCBjYW4gYmUgc3RhcnRlZCxcbiAgICogZXZlbiBpZiB0aGUgZXhlY3V0ZSBmdW5jdGlvbiBpcyBub3QgcHJvdmlkZWQuXG4gICAqL1xuICBvbklucHV0QXZhaWxhYmxlPzogKFxuICAgIG9wdGlvbnM6IHtcbiAgICAgIGlucHV0OiBbSU5QVVRdIGV4dGVuZHMgW25ldmVyXSA/IHVuZGVmaW5lZCA6IElOUFVUO1xuICAgIH0gJiBUb29sQ2FsbE9wdGlvbnMsXG4gICkgPT4gdm9pZCB8IFByb21pc2VMaWtlPHZvaWQ+O1xufSAmIFRvb2xPdXRwdXRQcm9wZXJ0aWVzPElOUFVULCBPVVRQVVQ+ICYge1xuICAgIC8qKlxuT3B0aW9uYWwgY29udmVyc2lvbiBmdW5jdGlvbiB0aGF0IG1hcHMgdGhlIHRvb2wgcmVzdWx0IHRvIGFuIG91dHB1dCB0aGF0IGNhbiBiZSB1c2VkIGJ5IHRoZSBsYW5ndWFnZSBtb2RlbC5cblxuSWYgbm90IHByb3ZpZGVkLCB0aGUgdG9vbCByZXN1bHQgd2lsbCBiZSBzZW50IGFzIGEgSlNPTiBvYmplY3QuXG4gICovXG4gICAgdG9Nb2RlbE91dHB1dD86IChcbiAgICAgIG91dHB1dDogMCBleHRlbmRzIDEgJiBPVVRQVVRcbiAgICAgICAgPyBhbnlcbiAgICAgICAgOiBbT1VUUFVUXSBleHRlbmRzIFtuZXZlcl1cbiAgICAgICAgICA/IGFueVxuICAgICAgICAgIDogTm9JbmZlcjxPVVRQVVQ+LFxuICAgICkgPT4gTGFuZ3VhZ2VNb2RlbFYyVG9vbFJlc3VsdFBhcnRbJ291dHB1dCddO1xuICB9ICYgKFxuICAgIHwge1xuICAgICAgICAvKipcblRvb2wgd2l0aCB1c2VyLWRlZmluZWQgaW5wdXQgYW5kIG91dHB1dCBzY2hlbWFzLlxuICAgICAqL1xuICAgICAgICB0eXBlPzogdW5kZWZpbmVkIHwgJ2Z1bmN0aW9uJztcbiAgICAgIH1cbiAgICB8IHtcbiAgICAgICAgLyoqXG5Ub29sIHRoYXQgaXMgZGVmaW5lZCBhdCBydW50aW1lIChlLmcuIGFuIE1DUCB0b29sKS5cblRoZSB0eXBlcyBvZiBpbnB1dCBhbmQgb3V0cHV0IGFyZSBub3Qga25vd24gYXQgZGV2ZWxvcG1lbnQgdGltZS5cbiAgICAgICAqL1xuICAgICAgICB0eXBlOiAnZHluYW1pYyc7XG4gICAgICB9XG4gICAgfCB7XG4gICAgICAgIC8qKlxuVG9vbCB3aXRoIHByb3ZpZGVyLWRlZmluZWQgaW5wdXQgYW5kIG91dHB1dCBzY2hlbWFzLlxuICAgICAqL1xuICAgICAgICB0eXBlOiAncHJvdmlkZXItZGVmaW5lZCc7XG5cbiAgICAgICAgLyoqXG5UaGUgSUQgb2YgdGhlIHRvb2wuIFNob3VsZCBmb2xsb3cgdGhlIGZvcm1hdCBgPHByb3ZpZGVyLW5hbWU+Ljx1bmlxdWUtdG9vbC1uYW1lPmAuXG4gICAqL1xuICAgICAgICBpZDogYCR7c3RyaW5nfS4ke3N0cmluZ31gO1xuXG4gICAgICAgIC8qKlxuVGhlIG5hbWUgb2YgdGhlIHRvb2wgdGhhdCB0aGUgdXNlciBtdXN0IHVzZSBpbiB0aGUgdG9vbCBzZXQuXG4gKi9cbiAgICAgICAgbmFtZTogc3RyaW5nO1xuXG4gICAgICAgIC8qKlxuVGhlIGFyZ3VtZW50cyBmb3IgY29uZmlndXJpbmcgdGhlIHRvb2wuIE11c3QgbWF0Y2ggdGhlIGV4cGVjdGVkIGFyZ3VtZW50cyBkZWZpbmVkIGJ5IHRoZSBwcm92aWRlciBmb3IgdGhpcyB0b29sLlxuICAgICAqL1xuICAgICAgICBhcmdzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICAgIH1cbiAgKTtcblxuLyoqXG4gKiBJbmZlciB0aGUgaW5wdXQgdHlwZSBvZiBhIHRvb2wuXG4gKi9cbmV4cG9ydCB0eXBlIEluZmVyVG9vbElucHV0PFRPT0wgZXh0ZW5kcyBUb29sPiA9XG4gIFRPT0wgZXh0ZW5kcyBUb29sPGluZmVyIElOUFVULCBhbnk+ID8gSU5QVVQgOiBuZXZlcjtcblxuLyoqXG4gKiBJbmZlciB0aGUgb3V0cHV0IHR5cGUgb2YgYSB0b29sLlxuICovXG5leHBvcnQgdHlwZSBJbmZlclRvb2xPdXRwdXQ8VE9PTCBleHRlbmRzIFRvb2w+ID1cbiAgVE9PTCBleHRlbmRzIFRvb2w8YW55LCBpbmZlciBPVVRQVVQ+ID8gT1VUUFVUIDogbmV2ZXI7XG5cbi8qKlxuSGVscGVyIGZ1bmN0aW9uIGZvciBpbmZlcnJpbmcgdGhlIGV4ZWN1dGUgYXJncyBvZiBhIHRvb2wuXG4gKi9cbi8vIE5vdGU6IG92ZXJsb2FkIG9yZGVyIGlzIGltcG9ydGFudCBmb3IgYXV0by1jb21wbGV0aW9uXG5leHBvcnQgZnVuY3Rpb24gdG9vbDxJTlBVVCwgT1VUUFVUPihcbiAgdG9vbDogVG9vbDxJTlBVVCwgT1VUUFVUPixcbik6IFRvb2w8SU5QVVQsIE9VVFBVVD47XG5leHBvcnQgZnVuY3Rpb24gdG9vbDxJTlBVVD4odG9vbDogVG9vbDxJTlBVVCwgbmV2ZXI+KTogVG9vbDxJTlBVVCwgbmV2ZXI+O1xuZXhwb3J0IGZ1bmN0aW9uIHRvb2w8T1VUUFVUPih0b29sOiBUb29sPG5ldmVyLCBPVVRQVVQ+KTogVG9vbDxuZXZlciwgT1VUUFVUPjtcbmV4cG9ydCBmdW5jdGlvbiB0b29sKHRvb2w6IFRvb2w8bmV2ZXIsIG5ldmVyPik6IFRvb2w8bmV2ZXIsIG5ldmVyPjtcbmV4cG9ydCBmdW5jdGlvbiB0b29sKHRvb2w6IGFueSk6IGFueSB7XG4gIHJldHVybiB0b29sO1xufVxuXG4vKipcbkhlbHBlciBmdW5jdGlvbiBmb3IgZGVmaW5pbmcgYSBkeW5hbWljIHRvb2wuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkeW5hbWljVG9vbCh0b29sOiB7XG4gIGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuICBwcm92aWRlck9wdGlvbnM/OiBQcm92aWRlck9wdGlvbnM7XG4gIGlucHV0U2NoZW1hOiBGbGV4aWJsZVNjaGVtYTx1bmtub3duPjtcbiAgZXhlY3V0ZTogVG9vbEV4ZWN1dGVGdW5jdGlvbjx1bmtub3duLCB1bmtub3duPjtcbiAgdG9Nb2RlbE91dHB1dD86IChvdXRwdXQ6IHVua25vd24pID0+IExhbmd1YWdlTW9kZWxWMlRvb2xSZXN1bHRQYXJ0WydvdXRwdXQnXTtcbn0pOiBUb29sPHVua25vd24sIHVua25vd24+ICYge1xuICB0eXBlOiAnZHluYW1pYyc7XG59IHtcbiAgcmV0dXJuIHsgLi4udG9vbCwgdHlwZTogJ2R5bmFtaWMnIH07XG59XG4iLCAiaW1wb3J0IHsgdG9vbCwgVG9vbCwgVG9vbEV4ZWN1dGVGdW5jdGlvbiB9IGZyb20gJy4vdHlwZXMvdG9vbCc7XG5pbXBvcnQgeyBGbGV4aWJsZVNjaGVtYSB9IGZyb20gJy4vc2NoZW1hJztcblxuZXhwb3J0IHR5cGUgUHJvdmlkZXJEZWZpbmVkVG9vbEZhY3Rvcnk8SU5QVVQsIEFSR1MgZXh0ZW5kcyBvYmplY3Q+ID0gPE9VVFBVVD4oXG4gIG9wdGlvbnM6IEFSR1MgJiB7XG4gICAgZXhlY3V0ZT86IFRvb2xFeGVjdXRlRnVuY3Rpb248SU5QVVQsIE9VVFBVVD47XG4gICAgdG9Nb2RlbE91dHB1dD86IFRvb2w8SU5QVVQsIE9VVFBVVD5bJ3RvTW9kZWxPdXRwdXQnXTtcbiAgICBvbklucHV0U3RhcnQ/OiBUb29sPElOUFVULCBPVVRQVVQ+WydvbklucHV0U3RhcnQnXTtcbiAgICBvbklucHV0RGVsdGE/OiBUb29sPElOUFVULCBPVVRQVVQ+WydvbklucHV0RGVsdGEnXTtcbiAgICBvbklucHV0QXZhaWxhYmxlPzogVG9vbDxJTlBVVCwgT1VUUFVUPlsnb25JbnB1dEF2YWlsYWJsZSddO1xuICB9LFxuKSA9PiBUb29sPElOUFVULCBPVVRQVVQ+O1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUHJvdmlkZXJEZWZpbmVkVG9vbEZhY3Rvcnk8SU5QVVQsIEFSR1MgZXh0ZW5kcyBvYmplY3Q+KHtcbiAgaWQsXG4gIG5hbWUsXG4gIGlucHV0U2NoZW1hLFxufToge1xuICBpZDogYCR7c3RyaW5nfS4ke3N0cmluZ31gO1xuICBuYW1lOiBzdHJpbmc7XG4gIGlucHV0U2NoZW1hOiBGbGV4aWJsZVNjaGVtYTxJTlBVVD47XG59KTogUHJvdmlkZXJEZWZpbmVkVG9vbEZhY3Rvcnk8SU5QVVQsIEFSR1M+IHtcbiAgcmV0dXJuIDxPVVRQVVQ+KHtcbiAgICBleGVjdXRlLFxuICAgIG91dHB1dFNjaGVtYSxcbiAgICB0b01vZGVsT3V0cHV0LFxuICAgIG9uSW5wdXRTdGFydCxcbiAgICBvbklucHV0RGVsdGEsXG4gICAgb25JbnB1dEF2YWlsYWJsZSxcbiAgICAuLi5hcmdzXG4gIH06IEFSR1MgJiB7XG4gICAgZXhlY3V0ZT86IFRvb2xFeGVjdXRlRnVuY3Rpb248SU5QVVQsIE9VVFBVVD47XG4gICAgb3V0cHV0U2NoZW1hPzogRmxleGlibGVTY2hlbWE8T1VUUFVUPjtcbiAgICB0b01vZGVsT3V0cHV0PzogVG9vbDxJTlBVVCwgT1VUUFVUPlsndG9Nb2RlbE91dHB1dCddO1xuICAgIG9uSW5wdXRTdGFydD86IFRvb2w8SU5QVVQsIE9VVFBVVD5bJ29uSW5wdXRTdGFydCddO1xuICAgIG9uSW5wdXREZWx0YT86IFRvb2w8SU5QVVQsIE9VVFBVVD5bJ29uSW5wdXREZWx0YSddO1xuICAgIG9uSW5wdXRBdmFpbGFibGU/OiBUb29sPElOUFVULCBPVVRQVVQ+WydvbklucHV0QXZhaWxhYmxlJ107XG4gIH0pOiBUb29sPElOUFVULCBPVVRQVVQ+ID0+XG4gICAgdG9vbCh7XG4gICAgICB0eXBlOiAncHJvdmlkZXItZGVmaW5lZCcsXG4gICAgICBpZCxcbiAgICAgIG5hbWUsXG4gICAgICBhcmdzLFxuICAgICAgaW5wdXRTY2hlbWEsXG4gICAgICBvdXRwdXRTY2hlbWEsXG4gICAgICBleGVjdXRlLFxuICAgICAgdG9Nb2RlbE91dHB1dCxcbiAgICAgIG9uSW5wdXRTdGFydCxcbiAgICAgIG9uSW5wdXREZWx0YSxcbiAgICAgIG9uSW5wdXRBdmFpbGFibGUsXG4gICAgfSk7XG59XG5cbmV4cG9ydCB0eXBlIFByb3ZpZGVyRGVmaW5lZFRvb2xGYWN0b3J5V2l0aE91dHB1dFNjaGVtYTxcbiAgSU5QVVQsXG4gIE9VVFBVVCxcbiAgQVJHUyBleHRlbmRzIG9iamVjdCxcbj4gPSAoXG4gIG9wdGlvbnM6IEFSR1MgJiB7XG4gICAgZXhlY3V0ZT86IFRvb2xFeGVjdXRlRnVuY3Rpb248SU5QVVQsIE9VVFBVVD47XG4gICAgdG9Nb2RlbE91dHB1dD86IFRvb2w8SU5QVVQsIE9VVFBVVD5bJ3RvTW9kZWxPdXRwdXQnXTtcbiAgICBvbklucHV0U3RhcnQ/OiBUb29sPElOUFVULCBPVVRQVVQ+WydvbklucHV0U3RhcnQnXTtcbiAgICBvbklucHV0RGVsdGE/OiBUb29sPElOUFVULCBPVVRQVVQ+WydvbklucHV0RGVsdGEnXTtcbiAgICBvbklucHV0QXZhaWxhYmxlPzogVG9vbDxJTlBVVCwgT1VUUFVUPlsnb25JbnB1dEF2YWlsYWJsZSddO1xuICB9LFxuKSA9PiBUb29sPElOUFVULCBPVVRQVVQ+O1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUHJvdmlkZXJEZWZpbmVkVG9vbEZhY3RvcnlXaXRoT3V0cHV0U2NoZW1hPFxuICBJTlBVVCxcbiAgT1VUUFVULFxuICBBUkdTIGV4dGVuZHMgb2JqZWN0LFxuPih7XG4gIGlkLFxuICBuYW1lLFxuICBpbnB1dFNjaGVtYSxcbiAgb3V0cHV0U2NoZW1hLFxufToge1xuICBpZDogYCR7c3RyaW5nfS4ke3N0cmluZ31gO1xuICBuYW1lOiBzdHJpbmc7XG4gIGlucHV0U2NoZW1hOiBGbGV4aWJsZVNjaGVtYTxJTlBVVD47XG4gIG91dHB1dFNjaGVtYTogRmxleGlibGVTY2hlbWE8T1VUUFVUPjtcbn0pOiBQcm92aWRlckRlZmluZWRUb29sRmFjdG9yeVdpdGhPdXRwdXRTY2hlbWE8SU5QVVQsIE9VVFBVVCwgQVJHUz4ge1xuICByZXR1cm4gKHtcbiAgICBleGVjdXRlLFxuICAgIHRvTW9kZWxPdXRwdXQsXG4gICAgb25JbnB1dFN0YXJ0LFxuICAgIG9uSW5wdXREZWx0YSxcbiAgICBvbklucHV0QXZhaWxhYmxlLFxuICAgIC4uLmFyZ3NcbiAgfTogQVJHUyAmIHtcbiAgICBleGVjdXRlPzogVG9vbEV4ZWN1dGVGdW5jdGlvbjxJTlBVVCwgT1VUUFVUPjtcbiAgICB0b01vZGVsT3V0cHV0PzogVG9vbDxJTlBVVCwgT1VUUFVUPlsndG9Nb2RlbE91dHB1dCddO1xuICAgIG9uSW5wdXRTdGFydD86IFRvb2w8SU5QVVQsIE9VVFBVVD5bJ29uSW5wdXRTdGFydCddO1xuICAgIG9uSW5wdXREZWx0YT86IFRvb2w8SU5QVVQsIE9VVFBVVD5bJ29uSW5wdXREZWx0YSddO1xuICAgIG9uSW5wdXRBdmFpbGFibGU/OiBUb29sPElOUFVULCBPVVRQVVQ+WydvbklucHV0QXZhaWxhYmxlJ107XG4gIH0pOiBUb29sPElOUFVULCBPVVRQVVQ+ID0+XG4gICAgdG9vbCh7XG4gICAgICB0eXBlOiAncHJvdmlkZXItZGVmaW5lZCcsXG4gICAgICBpZCxcbiAgICAgIG5hbWUsXG4gICAgICBhcmdzLFxuICAgICAgaW5wdXRTY2hlbWEsXG4gICAgICBvdXRwdXRTY2hlbWEsXG4gICAgICBleGVjdXRlLFxuICAgICAgdG9Nb2RlbE91dHB1dCxcbiAgICAgIG9uSW5wdXRTdGFydCxcbiAgICAgIG9uSW5wdXREZWx0YSxcbiAgICAgIG9uSW5wdXRBdmFpbGFibGUsXG4gICAgfSk7XG59XG4iLCAiZXhwb3J0IHR5cGUgUmVzb2x2YWJsZTxUPiA9XG4gIHwgVCAvLyBSYXcgdmFsdWVcbiAgfCBQcm9taXNlPFQ+IC8vIFByb21pc2Ugb2YgdmFsdWVcbiAgfCAoKCkgPT4gVCkgLy8gRnVuY3Rpb24gcmV0dXJuaW5nIHZhbHVlXG4gIHwgKCgpID0+IFByb21pc2U8VD4pOyAvLyBGdW5jdGlvbiByZXR1cm5pbmcgcHJvbWlzZSBvZiB2YWx1ZVxuXG4vKipcbiAqIFJlc29sdmVzIGEgdmFsdWUgdGhhdCBjb3VsZCBiZSBhIHJhdyB2YWx1ZSwgYSBQcm9taXNlLCBhIGZ1bmN0aW9uIHJldHVybmluZyBhIHZhbHVlLFxuICogb3IgYSBmdW5jdGlvbiByZXR1cm5pbmcgYSBQcm9taXNlLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZTxUPih2YWx1ZTogUmVzb2x2YWJsZTxUPik6IFByb21pc2U8VD4ge1xuICAvLyBJZiBpdCdzIGEgZnVuY3Rpb24sIGNhbGwgaXQgdG8gZ2V0IHRoZSB2YWx1ZS9wcm9taXNlXG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICB2YWx1ZSA9ICh2YWx1ZSBhcyBGdW5jdGlvbikoKTtcbiAgfVxuXG4gIC8vIE90aGVyd2lzZSBqdXN0IHJlc29sdmUgd2hhdGV2ZXIgd2UgZ290ICh2YWx1ZSBvciBwcm9taXNlKVxuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHZhbHVlIGFzIFQpO1xufVxuIiwgImltcG9ydCB7IEFQSUNhbGxFcnJvciwgRW1wdHlSZXNwb25zZUJvZHlFcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgWm9kVHlwZSB9IGZyb20gJ3pvZC92NCc7XG5pbXBvcnQgeyBleHRyYWN0UmVzcG9uc2VIZWFkZXJzIH0gZnJvbSAnLi9leHRyYWN0LXJlc3BvbnNlLWhlYWRlcnMnO1xuaW1wb3J0IHsgcGFyc2VKU09OLCBQYXJzZVJlc3VsdCwgc2FmZVBhcnNlSlNPTiB9IGZyb20gJy4vcGFyc2UtanNvbic7XG5pbXBvcnQgeyBwYXJzZUpzb25FdmVudFN0cmVhbSB9IGZyb20gJy4vcGFyc2UtanNvbi1ldmVudC1zdHJlYW0nO1xuaW1wb3J0IHsgRmxleGlibGVWYWxpZGF0b3IgfSBmcm9tICcuL3ZhbGlkYXRvcic7XG5cbmV4cG9ydCB0eXBlIFJlc3BvbnNlSGFuZGxlcjxSRVRVUk5fVFlQRT4gPSAob3B0aW9uczoge1xuICB1cmw6IHN0cmluZztcbiAgcmVxdWVzdEJvZHlWYWx1ZXM6IHVua25vd247XG4gIHJlc3BvbnNlOiBSZXNwb25zZTtcbn0pID0+IFByb21pc2VMaWtlPHtcbiAgdmFsdWU6IFJFVFVSTl9UWVBFO1xuICByYXdWYWx1ZT86IHVua25vd247XG4gIHJlc3BvbnNlSGVhZGVycz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG59PjtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZUpzb25FcnJvclJlc3BvbnNlSGFuZGxlciA9XG4gIDxUPih7XG4gICAgZXJyb3JTY2hlbWEsXG4gICAgZXJyb3JUb01lc3NhZ2UsXG4gICAgaXNSZXRyeWFibGUsXG4gIH06IHtcbiAgICBlcnJvclNjaGVtYTogRmxleGlibGVWYWxpZGF0b3I8VD47XG4gICAgZXJyb3JUb01lc3NhZ2U6IChlcnJvcjogVCkgPT4gc3RyaW5nO1xuICAgIGlzUmV0cnlhYmxlPzogKHJlc3BvbnNlOiBSZXNwb25zZSwgZXJyb3I/OiBUKSA9PiBib29sZWFuO1xuICB9KTogUmVzcG9uc2VIYW5kbGVyPEFQSUNhbGxFcnJvcj4gPT5cbiAgYXN5bmMgKHsgcmVzcG9uc2UsIHVybCwgcmVxdWVzdEJvZHlWYWx1ZXMgfSkgPT4ge1xuICAgIGNvbnN0IHJlc3BvbnNlQm9keSA9IGF3YWl0IHJlc3BvbnNlLnRleHQoKTtcbiAgICBjb25zdCByZXNwb25zZUhlYWRlcnMgPSBleHRyYWN0UmVzcG9uc2VIZWFkZXJzKHJlc3BvbnNlKTtcblxuICAgIC8vIFNvbWUgcHJvdmlkZXJzIHJldHVybiBhbiBlbXB0eSByZXNwb25zZSBib2R5IGZvciBzb21lIGVycm9yczpcbiAgICBpZiAocmVzcG9uc2VCb2R5LnRyaW0oKSA9PT0gJycpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHJlc3BvbnNlSGVhZGVycyxcbiAgICAgICAgdmFsdWU6IG5ldyBBUElDYWxsRXJyb3Ioe1xuICAgICAgICAgIG1lc3NhZ2U6IHJlc3BvbnNlLnN0YXR1c1RleHQsXG4gICAgICAgICAgdXJsLFxuICAgICAgICAgIHJlcXVlc3RCb2R5VmFsdWVzLFxuICAgICAgICAgIHN0YXR1c0NvZGU6IHJlc3BvbnNlLnN0YXR1cyxcbiAgICAgICAgICByZXNwb25zZUhlYWRlcnMsXG4gICAgICAgICAgcmVzcG9uc2VCb2R5LFxuICAgICAgICAgIGlzUmV0cnlhYmxlOiBpc1JldHJ5YWJsZT8uKHJlc3BvbnNlKSxcbiAgICAgICAgfSksXG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIHJlc2lsaWVudCBwYXJzaW5nIGluIGNhc2UgdGhlIHJlc3BvbnNlIGlzIG5vdCBKU09OIG9yIGRvZXMgbm90IG1hdGNoIHRoZSBzY2hlbWE6XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBhcnNlZEVycm9yID0gYXdhaXQgcGFyc2VKU09OKHtcbiAgICAgICAgdGV4dDogcmVzcG9uc2VCb2R5LFxuICAgICAgICBzY2hlbWE6IGVycm9yU2NoZW1hLFxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHJlc3BvbnNlSGVhZGVycyxcbiAgICAgICAgdmFsdWU6IG5ldyBBUElDYWxsRXJyb3Ioe1xuICAgICAgICAgIG1lc3NhZ2U6IGVycm9yVG9NZXNzYWdlKHBhcnNlZEVycm9yKSxcbiAgICAgICAgICB1cmwsXG4gICAgICAgICAgcmVxdWVzdEJvZHlWYWx1ZXMsXG4gICAgICAgICAgc3RhdHVzQ29kZTogcmVzcG9uc2Uuc3RhdHVzLFxuICAgICAgICAgIHJlc3BvbnNlSGVhZGVycyxcbiAgICAgICAgICByZXNwb25zZUJvZHksXG4gICAgICAgICAgZGF0YTogcGFyc2VkRXJyb3IsXG4gICAgICAgICAgaXNSZXRyeWFibGU6IGlzUmV0cnlhYmxlPy4ocmVzcG9uc2UsIHBhcnNlZEVycm9yKSxcbiAgICAgICAgfSksXG4gICAgICB9O1xuICAgIH0gY2F0Y2ggKHBhcnNlRXJyb3IpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHJlc3BvbnNlSGVhZGVycyxcbiAgICAgICAgdmFsdWU6IG5ldyBBUElDYWxsRXJyb3Ioe1xuICAgICAgICAgIG1lc3NhZ2U6IHJlc3BvbnNlLnN0YXR1c1RleHQsXG4gICAgICAgICAgdXJsLFxuICAgICAgICAgIHJlcXVlc3RCb2R5VmFsdWVzLFxuICAgICAgICAgIHN0YXR1c0NvZGU6IHJlc3BvbnNlLnN0YXR1cyxcbiAgICAgICAgICByZXNwb25zZUhlYWRlcnMsXG4gICAgICAgICAgcmVzcG9uc2VCb2R5LFxuICAgICAgICAgIGlzUmV0cnlhYmxlOiBpc1JldHJ5YWJsZT8uKHJlc3BvbnNlKSxcbiAgICAgICAgfSksXG4gICAgICB9O1xuICAgIH1cbiAgfTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZUV2ZW50U291cmNlUmVzcG9uc2VIYW5kbGVyID1cbiAgPFQ+KFxuICAgIGNodW5rU2NoZW1hOiBGbGV4aWJsZVZhbGlkYXRvcjxUPixcbiAgKTogUmVzcG9uc2VIYW5kbGVyPFJlYWRhYmxlU3RyZWFtPFBhcnNlUmVzdWx0PFQ+Pj4gPT5cbiAgYXN5bmMgKHsgcmVzcG9uc2UgfTogeyByZXNwb25zZTogUmVzcG9uc2UgfSkgPT4ge1xuICAgIGNvbnN0IHJlc3BvbnNlSGVhZGVycyA9IGV4dHJhY3RSZXNwb25zZUhlYWRlcnMocmVzcG9uc2UpO1xuXG4gICAgaWYgKHJlc3BvbnNlLmJvZHkgPT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVtcHR5UmVzcG9uc2VCb2R5RXJyb3Ioe30pO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICByZXNwb25zZUhlYWRlcnMsXG4gICAgICB2YWx1ZTogcGFyc2VKc29uRXZlbnRTdHJlYW0oe1xuICAgICAgICBzdHJlYW06IHJlc3BvbnNlLmJvZHksXG4gICAgICAgIHNjaGVtYTogY2h1bmtTY2hlbWEsXG4gICAgICB9KSxcbiAgICB9O1xuICB9O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlSnNvblN0cmVhbVJlc3BvbnNlSGFuZGxlciA9XG4gIDxUPihcbiAgICBjaHVua1NjaGVtYTogWm9kVHlwZTxUPixcbiAgKTogUmVzcG9uc2VIYW5kbGVyPFJlYWRhYmxlU3RyZWFtPFBhcnNlUmVzdWx0PFQ+Pj4gPT5cbiAgYXN5bmMgKHsgcmVzcG9uc2UgfTogeyByZXNwb25zZTogUmVzcG9uc2UgfSkgPT4ge1xuICAgIGNvbnN0IHJlc3BvbnNlSGVhZGVycyA9IGV4dHJhY3RSZXNwb25zZUhlYWRlcnMocmVzcG9uc2UpO1xuXG4gICAgaWYgKHJlc3BvbnNlLmJvZHkgPT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVtcHR5UmVzcG9uc2VCb2R5RXJyb3Ioe30pO1xuICAgIH1cblxuICAgIGxldCBidWZmZXIgPSAnJztcblxuICAgIHJldHVybiB7XG4gICAgICByZXNwb25zZUhlYWRlcnMsXG4gICAgICB2YWx1ZTogcmVzcG9uc2UuYm9keS5waXBlVGhyb3VnaChuZXcgVGV4dERlY29kZXJTdHJlYW0oKSkucGlwZVRocm91Z2goXG4gICAgICAgIG5ldyBUcmFuc2Zvcm1TdHJlYW08c3RyaW5nLCBQYXJzZVJlc3VsdDxUPj4oe1xuICAgICAgICAgIGFzeW5jIHRyYW5zZm9ybShjaHVua1RleHQsIGNvbnRyb2xsZXIpIHtcbiAgICAgICAgICAgIGlmIChjaHVua1RleHQuZW5kc1dpdGgoJ1xcbicpKSB7XG4gICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShcbiAgICAgICAgICAgICAgICBhd2FpdCBzYWZlUGFyc2VKU09OKHtcbiAgICAgICAgICAgICAgICAgIHRleHQ6IGJ1ZmZlciArIGNodW5rVGV4dCxcbiAgICAgICAgICAgICAgICAgIHNjaGVtYTogY2h1bmtTY2hlbWEsXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIGJ1ZmZlciA9ICcnO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgYnVmZmVyICs9IGNodW5rVGV4dDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgICksXG4gICAgfTtcbiAgfTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZUpzb25SZXNwb25zZUhhbmRsZXIgPVxuICA8VD4ocmVzcG9uc2VTY2hlbWE6IEZsZXhpYmxlVmFsaWRhdG9yPFQ+KTogUmVzcG9uc2VIYW5kbGVyPFQ+ID0+XG4gIGFzeW5jICh7IHJlc3BvbnNlLCB1cmwsIHJlcXVlc3RCb2R5VmFsdWVzIH0pID0+IHtcbiAgICBjb25zdCByZXNwb25zZUJvZHkgPSBhd2FpdCByZXNwb25zZS50ZXh0KCk7XG5cbiAgICBjb25zdCBwYXJzZWRSZXN1bHQgPSBhd2FpdCBzYWZlUGFyc2VKU09OKHtcbiAgICAgIHRleHQ6IHJlc3BvbnNlQm9keSxcbiAgICAgIHNjaGVtYTogcmVzcG9uc2VTY2hlbWEsXG4gICAgfSk7XG5cbiAgICBjb25zdCByZXNwb25zZUhlYWRlcnMgPSBleHRyYWN0UmVzcG9uc2VIZWFkZXJzKHJlc3BvbnNlKTtcblxuICAgIGlmICghcGFyc2VkUmVzdWx0LnN1Y2Nlc3MpIHtcbiAgICAgIHRocm93IG5ldyBBUElDYWxsRXJyb3Ioe1xuICAgICAgICBtZXNzYWdlOiAnSW52YWxpZCBKU09OIHJlc3BvbnNlJyxcbiAgICAgICAgY2F1c2U6IHBhcnNlZFJlc3VsdC5lcnJvcixcbiAgICAgICAgc3RhdHVzQ29kZTogcmVzcG9uc2Uuc3RhdHVzLFxuICAgICAgICByZXNwb25zZUhlYWRlcnMsXG4gICAgICAgIHJlc3BvbnNlQm9keSxcbiAgICAgICAgdXJsLFxuICAgICAgICByZXF1ZXN0Qm9keVZhbHVlcyxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICByZXNwb25zZUhlYWRlcnMsXG4gICAgICB2YWx1ZTogcGFyc2VkUmVzdWx0LnZhbHVlLFxuICAgICAgcmF3VmFsdWU6IHBhcnNlZFJlc3VsdC5yYXdWYWx1ZSxcbiAgICB9O1xuICB9O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlQmluYXJ5UmVzcG9uc2VIYW5kbGVyID1cbiAgKCk6IFJlc3BvbnNlSGFuZGxlcjxVaW50OEFycmF5PiA9PlxuICBhc3luYyAoeyByZXNwb25zZSwgdXJsLCByZXF1ZXN0Qm9keVZhbHVlcyB9KSA9PiB7XG4gICAgY29uc3QgcmVzcG9uc2VIZWFkZXJzID0gZXh0cmFjdFJlc3BvbnNlSGVhZGVycyhyZXNwb25zZSk7XG5cbiAgICBpZiAoIXJlc3BvbnNlLmJvZHkpIHtcbiAgICAgIHRocm93IG5ldyBBUElDYWxsRXJyb3Ioe1xuICAgICAgICBtZXNzYWdlOiAnUmVzcG9uc2UgYm9keSBpcyBlbXB0eScsXG4gICAgICAgIHVybCxcbiAgICAgICAgcmVxdWVzdEJvZHlWYWx1ZXMsXG4gICAgICAgIHN0YXR1c0NvZGU6IHJlc3BvbnNlLnN0YXR1cyxcbiAgICAgICAgcmVzcG9uc2VIZWFkZXJzLFxuICAgICAgICByZXNwb25zZUJvZHk6IHVuZGVmaW5lZCxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBidWZmZXIgPSBhd2FpdCByZXNwb25zZS5hcnJheUJ1ZmZlcigpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcmVzcG9uc2VIZWFkZXJzLFxuICAgICAgICB2YWx1ZTogbmV3IFVpbnQ4QXJyYXkoYnVmZmVyKSxcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRocm93IG5ldyBBUElDYWxsRXJyb3Ioe1xuICAgICAgICBtZXNzYWdlOiAnRmFpbGVkIHRvIHJlYWQgcmVzcG9uc2UgYXMgYXJyYXkgYnVmZmVyJyxcbiAgICAgICAgdXJsLFxuICAgICAgICByZXF1ZXN0Qm9keVZhbHVlcyxcbiAgICAgICAgc3RhdHVzQ29kZTogcmVzcG9uc2Uuc3RhdHVzLFxuICAgICAgICByZXNwb25zZUhlYWRlcnMsXG4gICAgICAgIHJlc3BvbnNlQm9keTogdW5kZWZpbmVkLFxuICAgICAgICBjYXVzZTogZXJyb3IsXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVTdGF0dXNDb2RlRXJyb3JSZXNwb25zZUhhbmRsZXIgPVxuICAoKTogUmVzcG9uc2VIYW5kbGVyPEFQSUNhbGxFcnJvcj4gPT5cbiAgYXN5bmMgKHsgcmVzcG9uc2UsIHVybCwgcmVxdWVzdEJvZHlWYWx1ZXMgfSkgPT4ge1xuICAgIGNvbnN0IHJlc3BvbnNlSGVhZGVycyA9IGV4dHJhY3RSZXNwb25zZUhlYWRlcnMocmVzcG9uc2UpO1xuICAgIGNvbnN0IHJlc3BvbnNlQm9keSA9IGF3YWl0IHJlc3BvbnNlLnRleHQoKTtcblxuICAgIHJldHVybiB7XG4gICAgICByZXNwb25zZUhlYWRlcnMsXG4gICAgICB2YWx1ZTogbmV3IEFQSUNhbGxFcnJvcih7XG4gICAgICAgIG1lc3NhZ2U6IHJlc3BvbnNlLnN0YXR1c1RleHQsXG4gICAgICAgIHVybCxcbiAgICAgICAgcmVxdWVzdEJvZHlWYWx1ZXM6IHJlcXVlc3RCb2R5VmFsdWVzIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICAgICAgICBzdGF0dXNDb2RlOiByZXNwb25zZS5zdGF0dXMsXG4gICAgICAgIHJlc3BvbnNlSGVhZGVycyxcbiAgICAgICAgcmVzcG9uc2VCb2R5LFxuICAgICAgfSksXG4gICAgfTtcbiAgfTtcbiIsICJpbXBvcnQgeyBKU09OU2NoZW1hNyB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0ICogYXMgejMgZnJvbSAnem9kL3YzJztcbmltcG9ydCAqIGFzIHo0IGZyb20gJ3pvZC92NCc7XG5pbXBvcnQgem9kVG9Kc29uU2NoZW1hIGZyb20gJy4vem9kLXRvLWpzb24tc2NoZW1hJztcbmltcG9ydCB7IGpzb25TY2hlbWEsIFNjaGVtYSB9IGZyb20gJy4vc2NoZW1hJztcblxuZXhwb3J0IGZ1bmN0aW9uIHpvZDNTY2hlbWE8T0JKRUNUPihcbiAgem9kU2NoZW1hOiB6My5TY2hlbWE8T0JKRUNULCB6My5ab2RUeXBlRGVmLCBhbnk+LFxuICBvcHRpb25zPzoge1xuICAgIC8qKlxuICAgICAqIEVuYWJsZXMgc3VwcG9ydCBmb3IgcmVmZXJlbmNlcyBpbiB0aGUgc2NoZW1hLlxuICAgICAqIFRoaXMgaXMgcmVxdWlyZWQgZm9yIHJlY3Vyc2l2ZSBzY2hlbWFzLCBlLmcuIHdpdGggYHoubGF6eWAuXG4gICAgICogSG93ZXZlciwgbm90IGFsbCBsYW5ndWFnZSBtb2RlbHMgYW5kIHByb3ZpZGVycyBzdXBwb3J0IHN1Y2ggcmVmZXJlbmNlcy5cbiAgICAgKiBEZWZhdWx0cyB0byBgZmFsc2VgLlxuICAgICAqL1xuICAgIHVzZVJlZmVyZW5jZXM/OiBib29sZWFuO1xuICB9LFxuKTogU2NoZW1hPE9CSkVDVD4ge1xuICAvLyBkZWZhdWx0IHRvIG5vIHJlZmVyZW5jZXMgKHRvIHN1cHBvcnQgb3BlbmFwaSBjb252ZXJzaW9uIGZvciBnb29nbGUpXG4gIGNvbnN0IHVzZVJlZmVyZW5jZXMgPSBvcHRpb25zPy51c2VSZWZlcmVuY2VzID8/IGZhbHNlO1xuXG4gIHJldHVybiBqc29uU2NoZW1hKFxuICAgIC8vIGRlZmVyIGpzb24gc2NoZW1hIGNyZWF0aW9uIHRvIGF2b2lkIHVubmVjZXNzYXJ5IGNvbXB1dGF0aW9uIHdoZW4gb25seSB2YWxpZGF0aW9uIGlzIG5lZWRlZFxuICAgICgpID0+XG4gICAgICB6b2RUb0pzb25TY2hlbWEoem9kU2NoZW1hLCB7XG4gICAgICAgICRyZWZTdHJhdGVneTogdXNlUmVmZXJlbmNlcyA/ICdyb290JyA6ICdub25lJyxcbiAgICAgIH0pIGFzIEpTT05TY2hlbWE3LFxuICAgIHtcbiAgICAgIHZhbGlkYXRlOiBhc3luYyB2YWx1ZSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHpvZFNjaGVtYS5zYWZlUGFyc2VBc3luYyh2YWx1ZSk7XG4gICAgICAgIHJldHVybiByZXN1bHQuc3VjY2Vzc1xuICAgICAgICAgID8geyBzdWNjZXNzOiB0cnVlLCB2YWx1ZTogcmVzdWx0LmRhdGEgfVxuICAgICAgICAgIDogeyBzdWNjZXNzOiBmYWxzZSwgZXJyb3I6IHJlc3VsdC5lcnJvciB9O1xuICAgICAgfSxcbiAgICB9LFxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gem9kNFNjaGVtYTxPQkpFQ1Q+KFxuICB6b2RTY2hlbWE6IHo0LmNvcmUuJFpvZFR5cGU8T0JKRUNULCBhbnk+LFxuICBvcHRpb25zPzoge1xuICAgIC8qKlxuICAgICAqIEVuYWJsZXMgc3VwcG9ydCBmb3IgcmVmZXJlbmNlcyBpbiB0aGUgc2NoZW1hLlxuICAgICAqIFRoaXMgaXMgcmVxdWlyZWQgZm9yIHJlY3Vyc2l2ZSBzY2hlbWFzLCBlLmcuIHdpdGggYHoubGF6eWAuXG4gICAgICogSG93ZXZlciwgbm90IGFsbCBsYW5ndWFnZSBtb2RlbHMgYW5kIHByb3ZpZGVycyBzdXBwb3J0IHN1Y2ggcmVmZXJlbmNlcy5cbiAgICAgKiBEZWZhdWx0cyB0byBgZmFsc2VgLlxuICAgICAqL1xuICAgIHVzZVJlZmVyZW5jZXM/OiBib29sZWFuO1xuICB9LFxuKTogU2NoZW1hPE9CSkVDVD4ge1xuICAvLyBkZWZhdWx0IHRvIG5vIHJlZmVyZW5jZXMgKHRvIHN1cHBvcnQgb3BlbmFwaSBjb252ZXJzaW9uIGZvciBnb29nbGUpXG4gIGNvbnN0IHVzZVJlZmVyZW5jZXMgPSBvcHRpb25zPy51c2VSZWZlcmVuY2VzID8/IGZhbHNlO1xuXG4gIHJldHVybiBqc29uU2NoZW1hKFxuICAgIC8vIGRlZmVyIGpzb24gc2NoZW1hIGNyZWF0aW9uIHRvIGF2b2lkIHVubmVjZXNzYXJ5IGNvbXB1dGF0aW9uIHdoZW4gb25seSB2YWxpZGF0aW9uIGlzIG5lZWRlZFxuICAgICgpID0+XG4gICAgICB6NC50b0pTT05TY2hlbWEoem9kU2NoZW1hLCB7XG4gICAgICAgIHRhcmdldDogJ2RyYWZ0LTcnLFxuICAgICAgICBpbzogJ291dHB1dCcsXG4gICAgICAgIHJldXNlZDogdXNlUmVmZXJlbmNlcyA/ICdyZWYnIDogJ2lubGluZScsXG4gICAgICB9KSBhcyBKU09OU2NoZW1hNyxcbiAgICB7XG4gICAgICB2YWxpZGF0ZTogYXN5bmMgdmFsdWUgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB6NC5zYWZlUGFyc2VBc3luYyh6b2RTY2hlbWEsIHZhbHVlKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdC5zdWNjZXNzXG4gICAgICAgICAgPyB7IHN1Y2Nlc3M6IHRydWUsIHZhbHVlOiByZXN1bHQuZGF0YSB9XG4gICAgICAgICAgOiB7IHN1Y2Nlc3M6IGZhbHNlLCBlcnJvcjogcmVzdWx0LmVycm9yIH07XG4gICAgICB9LFxuICAgIH0sXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1pvZDRTY2hlbWEoXG4gIHpvZFNjaGVtYTogejQuY29yZS4kWm9kVHlwZTxhbnksIGFueT4gfCB6My5TY2hlbWE8YW55LCB6My5ab2RUeXBlRGVmLCBhbnk+LFxuKTogem9kU2NoZW1hIGlzIHo0LmNvcmUuJFpvZFR5cGU8YW55LCBhbnk+IHtcbiAgLy8gaHR0cHM6Ly96b2QuZGV2L2xpYnJhcnktYXV0aG9ycz9pZD1ob3ctdG8tc3VwcG9ydC16b2QtMy1hbmQtem9kLTQtc2ltdWx0YW5lb3VzbHlcbiAgcmV0dXJuICdfem9kJyBpbiB6b2RTY2hlbWE7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB6b2RTY2hlbWE8T0JKRUNUPihcbiAgem9kU2NoZW1hOlxuICAgIHwgejQuY29yZS4kWm9kVHlwZTxPQkpFQ1QsIGFueT5cbiAgICB8IHozLlNjaGVtYTxPQkpFQ1QsIHozLlpvZFR5cGVEZWYsIGFueT4sXG4gIG9wdGlvbnM/OiB7XG4gICAgLyoqXG4gICAgICogRW5hYmxlcyBzdXBwb3J0IGZvciByZWZlcmVuY2VzIGluIHRoZSBzY2hlbWEuXG4gICAgICogVGhpcyBpcyByZXF1aXJlZCBmb3IgcmVjdXJzaXZlIHNjaGVtYXMsIGUuZy4gd2l0aCBgei5sYXp5YC5cbiAgICAgKiBIb3dldmVyLCBub3QgYWxsIGxhbmd1YWdlIG1vZGVscyBhbmQgcHJvdmlkZXJzIHN1cHBvcnQgc3VjaCByZWZlcmVuY2VzLlxuICAgICAqIERlZmF1bHRzIHRvIGBmYWxzZWAuXG4gICAgICovXG4gICAgdXNlUmVmZXJlbmNlcz86IGJvb2xlYW47XG4gIH0sXG4pOiBTY2hlbWE8T0JKRUNUPiB7XG4gIGlmIChpc1pvZDRTY2hlbWEoem9kU2NoZW1hKSkge1xuICAgIHJldHVybiB6b2Q0U2NoZW1hKHpvZFNjaGVtYSwgb3B0aW9ucyk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHpvZDNTY2hlbWEoem9kU2NoZW1hLCBvcHRpb25zKTtcbiAgfVxufVxuIiwgImV4cG9ydCBjb25zdCBnZXRSZWxhdGl2ZVBhdGggPSAocGF0aEE6IHN0cmluZ1tdLCBwYXRoQjogc3RyaW5nW10pID0+IHtcbiAgbGV0IGkgPSAwO1xuICBmb3IgKDsgaSA8IHBhdGhBLmxlbmd0aCAmJiBpIDwgcGF0aEIubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAocGF0aEFbaV0gIT09IHBhdGhCW2ldKSBicmVhaztcbiAgfVxuICByZXR1cm4gWyhwYXRoQS5sZW5ndGggLSBpKS50b1N0cmluZygpLCAuLi5wYXRoQi5zbGljZShpKV0uam9pbignLycpO1xufTtcbiIsICJpbXBvcnQgeyBab2RTY2hlbWEsIFpvZFR5cGVEZWYgfSBmcm9tICd6b2QvdjMnO1xuaW1wb3J0IHsgUmVmcywgU2VlbiB9IGZyb20gJy4vcmVmcyc7XG5pbXBvcnQgeyBKc29uU2NoZW1hN1R5cGUgfSBmcm9tICcuL3BhcnNlLXR5cGVzJztcblxuZXhwb3J0IHR5cGUgRGF0ZVN0cmF0ZWd5ID1cbiAgfCAnZm9ybWF0OmRhdGUtdGltZSdcbiAgfCAnZm9ybWF0OmRhdGUnXG4gIHwgJ3N0cmluZydcbiAgfCAnaW50ZWdlcic7XG5cbmV4cG9ydCBjb25zdCBpZ25vcmVPdmVycmlkZSA9IFN5bWJvbChcbiAgJ0xldCB6b2RUb0pzb25TY2hlbWEgZGVjaWRlIG9uIHdoaWNoIHBhcnNlciB0byB1c2UnLFxuKTtcblxuZXhwb3J0IHR5cGUgT3ZlcnJpZGVDYWxsYmFjayA9IChcbiAgZGVmOiBab2RUeXBlRGVmLFxuICByZWZzOiBSZWZzLFxuICBzZWVuOiBTZWVuIHwgdW5kZWZpbmVkLFxuICBmb3JjZVJlc29sdXRpb24/OiBib29sZWFuLFxuKSA9PiBKc29uU2NoZW1hN1R5cGUgfCB1bmRlZmluZWQgfCB0eXBlb2YgaWdub3JlT3ZlcnJpZGU7XG5cbmV4cG9ydCB0eXBlIFBvc3RQcm9jZXNzQ2FsbGJhY2sgPSAoXG4gIGpzb25TY2hlbWE6IEpzb25TY2hlbWE3VHlwZSB8IHVuZGVmaW5lZCxcbiAgZGVmOiBab2RUeXBlRGVmLFxuICByZWZzOiBSZWZzLFxuKSA9PiBKc29uU2NoZW1hN1R5cGUgfCB1bmRlZmluZWQ7XG5cbmV4cG9ydCBjb25zdCBqc29uRGVzY3JpcHRpb246IFBvc3RQcm9jZXNzQ2FsbGJhY2sgPSAoanNvblNjaGVtYSwgZGVmKSA9PiB7XG4gIGlmIChkZWYuZGVzY3JpcHRpb24pIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uanNvblNjaGVtYSxcbiAgICAgICAgLi4uSlNPTi5wYXJzZShkZWYuZGVzY3JpcHRpb24pLFxuICAgICAgfTtcbiAgICB9IGNhdGNoIHt9XG4gIH1cblxuICByZXR1cm4ganNvblNjaGVtYTtcbn07XG5cbmV4cG9ydCB0eXBlIE9wdGlvbnMgPSB7XG4gIG5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgJHJlZlN0cmF0ZWd5OiAncm9vdCcgfCAncmVsYXRpdmUnIHwgJ25vbmUnIHwgJ3NlZW4nO1xuICBiYXNlUGF0aDogc3RyaW5nW107XG4gIGVmZmVjdFN0cmF0ZWd5OiAnaW5wdXQnIHwgJ2FueSc7XG4gIHBpcGVTdHJhdGVneTogJ2lucHV0JyB8ICdvdXRwdXQnIHwgJ2FsbCc7XG4gIGRhdGVTdHJhdGVneTogRGF0ZVN0cmF0ZWd5IHwgRGF0ZVN0cmF0ZWd5W107XG4gIG1hcFN0cmF0ZWd5OiAnZW50cmllcycgfCAncmVjb3JkJztcbiAgcmVtb3ZlQWRkaXRpb25hbFN0cmF0ZWd5OiAncGFzc3Rocm91Z2gnIHwgJ3N0cmljdCc7XG4gIGFsbG93ZWRBZGRpdGlvbmFsUHJvcGVydGllczogdHJ1ZSB8IHVuZGVmaW5lZDtcbiAgcmVqZWN0ZWRBZGRpdGlvbmFsUHJvcGVydGllczogZmFsc2UgfCB1bmRlZmluZWQ7XG4gIHN0cmljdFVuaW9uczogYm9vbGVhbjtcbiAgZGVmaW5pdGlvblBhdGg6IHN0cmluZztcbiAgZGVmaW5pdGlvbnM6IFJlY29yZDxzdHJpbmcsIFpvZFNjaGVtYT47XG4gIGVycm9yTWVzc2FnZXM6IGJvb2xlYW47XG4gIHBhdHRlcm5TdHJhdGVneTogJ2VzY2FwZScgfCAncHJlc2VydmUnO1xuICBhcHBseVJlZ2V4RmxhZ3M6IGJvb2xlYW47XG4gIGVtYWlsU3RyYXRlZ3k6ICdmb3JtYXQ6ZW1haWwnIHwgJ2Zvcm1hdDppZG4tZW1haWwnIHwgJ3BhdHRlcm46em9kJztcbiAgYmFzZTY0U3RyYXRlZ3k6ICdmb3JtYXQ6YmluYXJ5JyB8ICdjb250ZW50RW5jb2Rpbmc6YmFzZTY0JyB8ICdwYXR0ZXJuOnpvZCc7XG4gIG5hbWVTdHJhdGVneTogJ3JlZicgfCAndGl0bGUnO1xuICBvdmVycmlkZT86IE92ZXJyaWRlQ2FsbGJhY2s7XG4gIHBvc3RQcm9jZXNzPzogUG9zdFByb2Nlc3NDYWxsYmFjaztcbn07XG5cbmV4cG9ydCBjb25zdCBkZWZhdWx0T3B0aW9uczogT3B0aW9ucyA9IHtcbiAgbmFtZTogdW5kZWZpbmVkLFxuICAkcmVmU3RyYXRlZ3k6ICdyb290JyxcbiAgYmFzZVBhdGg6IFsnIyddLFxuICBlZmZlY3RTdHJhdGVneTogJ2lucHV0JyxcbiAgcGlwZVN0cmF0ZWd5OiAnYWxsJyxcbiAgZGF0ZVN0cmF0ZWd5OiAnZm9ybWF0OmRhdGUtdGltZScsXG4gIG1hcFN0cmF0ZWd5OiAnZW50cmllcycsXG4gIHJlbW92ZUFkZGl0aW9uYWxTdHJhdGVneTogJ3Bhc3N0aHJvdWdoJyxcbiAgYWxsb3dlZEFkZGl0aW9uYWxQcm9wZXJ0aWVzOiB0cnVlLFxuICByZWplY3RlZEFkZGl0aW9uYWxQcm9wZXJ0aWVzOiBmYWxzZSxcbiAgZGVmaW5pdGlvblBhdGg6ICdkZWZpbml0aW9ucycsXG4gIHN0cmljdFVuaW9uczogZmFsc2UsXG4gIGRlZmluaXRpb25zOiB7fSxcbiAgZXJyb3JNZXNzYWdlczogZmFsc2UsXG4gIHBhdHRlcm5TdHJhdGVneTogJ2VzY2FwZScsXG4gIGFwcGx5UmVnZXhGbGFnczogZmFsc2UsXG4gIGVtYWlsU3RyYXRlZ3k6ICdmb3JtYXQ6ZW1haWwnLFxuICBiYXNlNjRTdHJhdGVneTogJ2NvbnRlbnRFbmNvZGluZzpiYXNlNjQnLFxuICBuYW1lU3RyYXRlZ3k6ICdyZWYnLFxufTtcblxuZXhwb3J0IGNvbnN0IGdldERlZmF1bHRPcHRpb25zID0gKFxuICBvcHRpb25zOiBQYXJ0aWFsPE9wdGlvbnM+IHwgc3RyaW5nIHwgdW5kZWZpbmVkLFxuKSA9PlxuICAodHlwZW9mIG9wdGlvbnMgPT09ICdzdHJpbmcnXG4gICAgPyB7XG4gICAgICAgIC4uLmRlZmF1bHRPcHRpb25zLFxuICAgICAgICBuYW1lOiBvcHRpb25zLFxuICAgICAgfVxuICAgIDoge1xuICAgICAgICAuLi5kZWZhdWx0T3B0aW9ucyxcbiAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgIH0pIGFzIE9wdGlvbnM7XG4iLCAiaW1wb3J0IHsgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kIH0gZnJvbSAnem9kL3YzJztcbmltcG9ydCB7IHBhcnNlQW55RGVmIH0gZnJvbSAnLi9wYXJzZXJzL2FueSc7XG5pbXBvcnQgeyBwYXJzZUFycmF5RGVmIH0gZnJvbSAnLi9wYXJzZXJzL2FycmF5JztcbmltcG9ydCB7IHBhcnNlQmlnaW50RGVmIH0gZnJvbSAnLi9wYXJzZXJzL2JpZ2ludCc7XG5pbXBvcnQgeyBwYXJzZUJvb2xlYW5EZWYgfSBmcm9tICcuL3BhcnNlcnMvYm9vbGVhbic7XG5pbXBvcnQgeyBwYXJzZUJyYW5kZWREZWYgfSBmcm9tICcuL3BhcnNlcnMvYnJhbmRlZCc7XG5pbXBvcnQgeyBwYXJzZUNhdGNoRGVmIH0gZnJvbSAnLi9wYXJzZXJzL2NhdGNoJztcbmltcG9ydCB7IHBhcnNlRGF0ZURlZiB9IGZyb20gJy4vcGFyc2Vycy9kYXRlJztcbmltcG9ydCB7IHBhcnNlRGVmYXVsdERlZiB9IGZyb20gJy4vcGFyc2Vycy9kZWZhdWx0JztcbmltcG9ydCB7IHBhcnNlRWZmZWN0c0RlZiB9IGZyb20gJy4vcGFyc2Vycy9lZmZlY3RzJztcbmltcG9ydCB7IHBhcnNlRW51bURlZiB9IGZyb20gJy4vcGFyc2Vycy9lbnVtJztcbmltcG9ydCB7IHBhcnNlSW50ZXJzZWN0aW9uRGVmIH0gZnJvbSAnLi9wYXJzZXJzL2ludGVyc2VjdGlvbic7XG5pbXBvcnQgeyBwYXJzZUxpdGVyYWxEZWYgfSBmcm9tICcuL3BhcnNlcnMvbGl0ZXJhbCc7XG5pbXBvcnQgeyBwYXJzZU1hcERlZiB9IGZyb20gJy4vcGFyc2Vycy9tYXAnO1xuaW1wb3J0IHsgcGFyc2VOYXRpdmVFbnVtRGVmIH0gZnJvbSAnLi9wYXJzZXJzL25hdGl2ZS1lbnVtJztcbmltcG9ydCB7IHBhcnNlTmV2ZXJEZWYgfSBmcm9tICcuL3BhcnNlcnMvbmV2ZXInO1xuaW1wb3J0IHsgcGFyc2VOdWxsRGVmIH0gZnJvbSAnLi9wYXJzZXJzL251bGwnO1xuaW1wb3J0IHsgcGFyc2VOdWxsYWJsZURlZiB9IGZyb20gJy4vcGFyc2Vycy9udWxsYWJsZSc7XG5pbXBvcnQgeyBwYXJzZU51bWJlckRlZiB9IGZyb20gJy4vcGFyc2Vycy9udW1iZXInO1xuaW1wb3J0IHsgcGFyc2VPYmplY3REZWYgfSBmcm9tICcuL3BhcnNlcnMvb2JqZWN0JztcbmltcG9ydCB7IHBhcnNlT3B0aW9uYWxEZWYgfSBmcm9tICcuL3BhcnNlcnMvb3B0aW9uYWwnO1xuaW1wb3J0IHsgcGFyc2VQaXBlbGluZURlZiB9IGZyb20gJy4vcGFyc2Vycy9waXBlbGluZSc7XG5pbXBvcnQgeyBwYXJzZVByb21pc2VEZWYgfSBmcm9tICcuL3BhcnNlcnMvcHJvbWlzZSc7XG5pbXBvcnQgeyBwYXJzZVJlY29yZERlZiB9IGZyb20gJy4vcGFyc2Vycy9yZWNvcmQnO1xuaW1wb3J0IHsgcGFyc2VTZXREZWYgfSBmcm9tICcuL3BhcnNlcnMvc2V0JztcbmltcG9ydCB7IHBhcnNlU3RyaW5nRGVmIH0gZnJvbSAnLi9wYXJzZXJzL3N0cmluZyc7XG5pbXBvcnQgeyBwYXJzZVR1cGxlRGVmIH0gZnJvbSAnLi9wYXJzZXJzL3R1cGxlJztcbmltcG9ydCB7IHBhcnNlVW5kZWZpbmVkRGVmIH0gZnJvbSAnLi9wYXJzZXJzL3VuZGVmaW5lZCc7XG5pbXBvcnQgeyBwYXJzZVVuaW9uRGVmIH0gZnJvbSAnLi9wYXJzZXJzL3VuaW9uJztcbmltcG9ydCB7IHBhcnNlVW5rbm93bkRlZiB9IGZyb20gJy4vcGFyc2Vycy91bmtub3duJztcbmltcG9ydCB7IFJlZnMgfSBmcm9tICcuL3JlZnMnO1xuaW1wb3J0IHsgcGFyc2VSZWFkb25seURlZiB9IGZyb20gJy4vcGFyc2Vycy9yZWFkb25seSc7XG5pbXBvcnQgeyBKc29uU2NoZW1hN1R5cGUgfSBmcm9tICcuL3BhcnNlLXR5cGVzJztcblxuZXhwb3J0IHR5cGUgSW5uZXJEZWZHZXR0ZXIgPSAoKSA9PiBhbnk7XG5cbmV4cG9ydCBjb25zdCBzZWxlY3RQYXJzZXIgPSAoXG4gIGRlZjogYW55LFxuICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLFxuICByZWZzOiBSZWZzLFxuKTogSnNvblNjaGVtYTdUeXBlIHwgdW5kZWZpbmVkIHwgSW5uZXJEZWZHZXR0ZXIgPT4ge1xuICBzd2l0Y2ggKHR5cGVOYW1lKSB7XG4gICAgY2FzZSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kU3RyaW5nOlxuICAgICAgcmV0dXJuIHBhcnNlU3RyaW5nRGVmKGRlZiwgcmVmcyk7XG4gICAgY2FzZSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kTnVtYmVyOlxuICAgICAgcmV0dXJuIHBhcnNlTnVtYmVyRGVmKGRlZik7XG4gICAgY2FzZSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kT2JqZWN0OlxuICAgICAgcmV0dXJuIHBhcnNlT2JqZWN0RGVmKGRlZiwgcmVmcyk7XG4gICAgY2FzZSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kQmlnSW50OlxuICAgICAgcmV0dXJuIHBhcnNlQmlnaW50RGVmKGRlZik7XG4gICAgY2FzZSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kQm9vbGVhbjpcbiAgICAgIHJldHVybiBwYXJzZUJvb2xlYW5EZWYoKTtcbiAgICBjYXNlIFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2REYXRlOlxuICAgICAgcmV0dXJuIHBhcnNlRGF0ZURlZihkZWYsIHJlZnMpO1xuICAgIGNhc2UgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZFVuZGVmaW5lZDpcbiAgICAgIHJldHVybiBwYXJzZVVuZGVmaW5lZERlZigpO1xuICAgIGNhc2UgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE51bGw6XG4gICAgICByZXR1cm4gcGFyc2VOdWxsRGVmKCk7XG4gICAgY2FzZSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kQXJyYXk6XG4gICAgICByZXR1cm4gcGFyc2VBcnJheURlZihkZWYsIHJlZnMpO1xuICAgIGNhc2UgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZFVuaW9uOlxuICAgIGNhc2UgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZERpc2NyaW1pbmF0ZWRVbmlvbjpcbiAgICAgIHJldHVybiBwYXJzZVVuaW9uRGVmKGRlZiwgcmVmcyk7XG4gICAgY2FzZSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kSW50ZXJzZWN0aW9uOlxuICAgICAgcmV0dXJuIHBhcnNlSW50ZXJzZWN0aW9uRGVmKGRlZiwgcmVmcyk7XG4gICAgY2FzZSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kVHVwbGU6XG4gICAgICByZXR1cm4gcGFyc2VUdXBsZURlZihkZWYsIHJlZnMpO1xuICAgIGNhc2UgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZFJlY29yZDpcbiAgICAgIHJldHVybiBwYXJzZVJlY29yZERlZihkZWYsIHJlZnMpO1xuICAgIGNhc2UgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZExpdGVyYWw6XG4gICAgICByZXR1cm4gcGFyc2VMaXRlcmFsRGVmKGRlZik7XG4gICAgY2FzZSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kRW51bTpcbiAgICAgIHJldHVybiBwYXJzZUVudW1EZWYoZGVmKTtcbiAgICBjYXNlIFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2ROYXRpdmVFbnVtOlxuICAgICAgcmV0dXJuIHBhcnNlTmF0aXZlRW51bURlZihkZWYpO1xuICAgIGNhc2UgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE51bGxhYmxlOlxuICAgICAgcmV0dXJuIHBhcnNlTnVsbGFibGVEZWYoZGVmLCByZWZzKTtcbiAgICBjYXNlIFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RPcHRpb25hbDpcbiAgICAgIHJldHVybiBwYXJzZU9wdGlvbmFsRGVmKGRlZiwgcmVmcyk7XG4gICAgY2FzZSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kTWFwOlxuICAgICAgcmV0dXJuIHBhcnNlTWFwRGVmKGRlZiwgcmVmcyk7XG4gICAgY2FzZSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kU2V0OlxuICAgICAgcmV0dXJuIHBhcnNlU2V0RGVmKGRlZiwgcmVmcyk7XG4gICAgY2FzZSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kTGF6eTpcbiAgICAgIHJldHVybiAoKSA9PiAoZGVmIGFzIGFueSkuZ2V0dGVyKCkuX2RlZjtcbiAgICBjYXNlIFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RQcm9taXNlOlxuICAgICAgcmV0dXJuIHBhcnNlUHJvbWlzZURlZihkZWYsIHJlZnMpO1xuICAgIGNhc2UgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE5hTjpcbiAgICBjYXNlIFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2ROZXZlcjpcbiAgICAgIHJldHVybiBwYXJzZU5ldmVyRGVmKCk7XG4gICAgY2FzZSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kRWZmZWN0czpcbiAgICAgIHJldHVybiBwYXJzZUVmZmVjdHNEZWYoZGVmLCByZWZzKTtcbiAgICBjYXNlIFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RBbnk6XG4gICAgICByZXR1cm4gcGFyc2VBbnlEZWYoKTtcbiAgICBjYXNlIFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RVbmtub3duOlxuICAgICAgcmV0dXJuIHBhcnNlVW5rbm93bkRlZigpO1xuICAgIGNhc2UgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZERlZmF1bHQ6XG4gICAgICByZXR1cm4gcGFyc2VEZWZhdWx0RGVmKGRlZiwgcmVmcyk7XG4gICAgY2FzZSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kQnJhbmRlZDpcbiAgICAgIHJldHVybiBwYXJzZUJyYW5kZWREZWYoZGVmLCByZWZzKTtcbiAgICBjYXNlIFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RSZWFkb25seTpcbiAgICAgIHJldHVybiBwYXJzZVJlYWRvbmx5RGVmKGRlZiwgcmVmcyk7XG4gICAgY2FzZSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kQ2F0Y2g6XG4gICAgICByZXR1cm4gcGFyc2VDYXRjaERlZihkZWYsIHJlZnMpO1xuICAgIGNhc2UgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZFBpcGVsaW5lOlxuICAgICAgcmV0dXJuIHBhcnNlUGlwZWxpbmVEZWYoZGVmLCByZWZzKTtcbiAgICBjYXNlIFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RGdW5jdGlvbjpcbiAgICBjYXNlIFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RWb2lkOlxuICAgIGNhc2UgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZFN5bWJvbDpcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgZGVmYXVsdDpcbiAgICAgIC8qIGM4IGlnbm9yZSBuZXh0ICovXG4gICAgICByZXR1cm4gKChfOiBuZXZlcikgPT4gdW5kZWZpbmVkKSh0eXBlTmFtZSk7XG4gIH1cbn07XG4iLCAiZXhwb3J0IHR5cGUgSnNvblNjaGVtYTdBbnlUeXBlID0geyAkcmVmPzogc3RyaW5nIH07XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUFueURlZigpOiBKc29uU2NoZW1hN0FueVR5cGUge1xuICByZXR1cm4ge307XG59XG4iLCAiaW1wb3J0IHsgWm9kQXJyYXlEZWYsIFpvZEZpcnN0UGFydHlUeXBlS2luZCB9IGZyb20gJ3pvZC92Myc7XG5pbXBvcnQgeyBwYXJzZURlZiB9IGZyb20gJy4uL3BhcnNlLWRlZic7XG5pbXBvcnQgeyBKc29uU2NoZW1hN1R5cGUgfSBmcm9tICcuLi9wYXJzZS10eXBlcyc7XG5pbXBvcnQgeyBSZWZzIH0gZnJvbSAnLi4vcmVmcyc7XG5cbmV4cG9ydCB0eXBlIEpzb25TY2hlbWE3QXJyYXlUeXBlID0ge1xuICB0eXBlOiAnYXJyYXknO1xuICBpdGVtcz86IEpzb25TY2hlbWE3VHlwZTtcbiAgbWluSXRlbXM/OiBudW1iZXI7XG4gIG1heEl0ZW1zPzogbnVtYmVyO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlQXJyYXlEZWYoZGVmOiBab2RBcnJheURlZiwgcmVmczogUmVmcykge1xuICBjb25zdCByZXM6IEpzb25TY2hlbWE3QXJyYXlUeXBlID0ge1xuICAgIHR5cGU6ICdhcnJheScsXG4gIH07XG4gIGlmIChcbiAgICBkZWYudHlwZT8uX2RlZiAmJlxuICAgIGRlZi50eXBlPy5fZGVmPy50eXBlTmFtZSAhPT0gWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEFueVxuICApIHtcbiAgICByZXMuaXRlbXMgPSBwYXJzZURlZihkZWYudHlwZS5fZGVmLCB7XG4gICAgICAuLi5yZWZzLFxuICAgICAgY3VycmVudFBhdGg6IFsuLi5yZWZzLmN1cnJlbnRQYXRoLCAnaXRlbXMnXSxcbiAgICB9KTtcbiAgfVxuXG4gIGlmIChkZWYubWluTGVuZ3RoKSB7XG4gICAgcmVzLm1pbkl0ZW1zID0gZGVmLm1pbkxlbmd0aC52YWx1ZTtcbiAgfVxuICBpZiAoZGVmLm1heExlbmd0aCkge1xuICAgIHJlcy5tYXhJdGVtcyA9IGRlZi5tYXhMZW5ndGgudmFsdWU7XG4gIH1cbiAgaWYgKGRlZi5leGFjdExlbmd0aCkge1xuICAgIHJlcy5taW5JdGVtcyA9IGRlZi5leGFjdExlbmd0aC52YWx1ZTtcbiAgICByZXMubWF4SXRlbXMgPSBkZWYuZXhhY3RMZW5ndGgudmFsdWU7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cbiIsICJpbXBvcnQgeyBab2RCaWdJbnREZWYgfSBmcm9tICd6b2QvdjMnO1xuXG5leHBvcnQgdHlwZSBKc29uU2NoZW1hN0JpZ2ludFR5cGUgPSB7XG4gIHR5cGU6ICdpbnRlZ2VyJztcbiAgZm9ybWF0OiAnaW50NjQnO1xuICBtaW5pbXVtPzogQmlnSW50O1xuICBleGNsdXNpdmVNaW5pbXVtPzogQmlnSW50O1xuICBtYXhpbXVtPzogQmlnSW50O1xuICBleGNsdXNpdmVNYXhpbXVtPzogQmlnSW50O1xuICBtdWx0aXBsZU9mPzogQmlnSW50O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlQmlnaW50RGVmKGRlZjogWm9kQmlnSW50RGVmKTogSnNvblNjaGVtYTdCaWdpbnRUeXBlIHtcbiAgY29uc3QgcmVzOiBKc29uU2NoZW1hN0JpZ2ludFR5cGUgPSB7XG4gICAgdHlwZTogJ2ludGVnZXInLFxuICAgIGZvcm1hdDogJ2ludDY0JyxcbiAgfTtcblxuICBpZiAoIWRlZi5jaGVja3MpIHJldHVybiByZXM7XG5cbiAgZm9yIChjb25zdCBjaGVjayBvZiBkZWYuY2hlY2tzKSB7XG4gICAgc3dpdGNoIChjaGVjay5raW5kKSB7XG4gICAgICBjYXNlICdtaW4nOlxuICAgICAgICBpZiAoY2hlY2suaW5jbHVzaXZlKSB7XG4gICAgICAgICAgcmVzLm1pbmltdW0gPSBjaGVjay52YWx1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXMuZXhjbHVzaXZlTWluaW11bSA9IGNoZWNrLnZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbWF4JzpcbiAgICAgICAgaWYgKGNoZWNrLmluY2x1c2l2ZSkge1xuICAgICAgICAgIHJlcy5tYXhpbXVtID0gY2hlY2sudmFsdWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzLmV4Y2x1c2l2ZU1heGltdW0gPSBjaGVjay52YWx1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbXVsdGlwbGVPZic6XG4gICAgICAgIHJlcy5tdWx0aXBsZU9mID0gY2hlY2sudmFsdWU7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzO1xufVxuIiwgImV4cG9ydCB0eXBlIEpzb25TY2hlbWE3Qm9vbGVhblR5cGUgPSB7XG4gIHR5cGU6ICdib29sZWFuJztcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUJvb2xlYW5EZWYoKTogSnNvblNjaGVtYTdCb29sZWFuVHlwZSB7XG4gIHJldHVybiB7IHR5cGU6ICdib29sZWFuJyB9O1xufVxuIiwgImltcG9ydCB7IFpvZEJyYW5kZWREZWYgfSBmcm9tICd6b2QvdjMnO1xuaW1wb3J0IHsgcGFyc2VEZWYgfSBmcm9tICcuLi9wYXJzZS1kZWYnO1xuaW1wb3J0IHsgUmVmcyB9IGZyb20gJy4uL3JlZnMnO1xuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VCcmFuZGVkRGVmKF9kZWY6IFpvZEJyYW5kZWREZWY8YW55PiwgcmVmczogUmVmcykge1xuICByZXR1cm4gcGFyc2VEZWYoX2RlZi50eXBlLl9kZWYsIHJlZnMpO1xufVxuIiwgImltcG9ydCB7IFpvZENhdGNoRGVmIH0gZnJvbSAnem9kL3YzJztcbmltcG9ydCB7IHBhcnNlRGVmIH0gZnJvbSAnLi4vcGFyc2UtZGVmJztcbmltcG9ydCB7IFJlZnMgfSBmcm9tICcuLi9yZWZzJztcblxuZXhwb3J0IGNvbnN0IHBhcnNlQ2F0Y2hEZWYgPSAoZGVmOiBab2RDYXRjaERlZjxhbnk+LCByZWZzOiBSZWZzKSA9PiB7XG4gIHJldHVybiBwYXJzZURlZihkZWYuaW5uZXJUeXBlLl9kZWYsIHJlZnMpO1xufTtcbiIsICJpbXBvcnQgeyBab2REYXRlRGVmIH0gZnJvbSAnem9kL3YzJztcbmltcG9ydCB7IFJlZnMgfSBmcm9tICcuLi9yZWZzJztcbmltcG9ydCB7IERhdGVTdHJhdGVneSB9IGZyb20gJy4uL29wdGlvbnMnO1xuXG5leHBvcnQgdHlwZSBKc29uU2NoZW1hN0RhdGVUeXBlID1cbiAgfCB7XG4gICAgICB0eXBlOiAnaW50ZWdlcicgfCAnc3RyaW5nJztcbiAgICAgIGZvcm1hdDogJ3VuaXgtdGltZScgfCAnZGF0ZS10aW1lJyB8ICdkYXRlJztcbiAgICAgIG1pbmltdW0/OiBudW1iZXI7XG4gICAgICBtYXhpbXVtPzogbnVtYmVyO1xuICAgIH1cbiAgfCB7XG4gICAgICBhbnlPZjogSnNvblNjaGVtYTdEYXRlVHlwZVtdO1xuICAgIH07XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZURhdGVEZWYoXG4gIGRlZjogWm9kRGF0ZURlZixcbiAgcmVmczogUmVmcyxcbiAgb3ZlcnJpZGVEYXRlU3RyYXRlZ3k/OiBEYXRlU3RyYXRlZ3ksXG4pOiBKc29uU2NoZW1hN0RhdGVUeXBlIHtcbiAgY29uc3Qgc3RyYXRlZ3kgPSBvdmVycmlkZURhdGVTdHJhdGVneSA/PyByZWZzLmRhdGVTdHJhdGVneTtcblxuICBpZiAoQXJyYXkuaXNBcnJheShzdHJhdGVneSkpIHtcbiAgICByZXR1cm4ge1xuICAgICAgYW55T2Y6IHN0cmF0ZWd5Lm1hcCgoaXRlbSwgaSkgPT4gcGFyc2VEYXRlRGVmKGRlZiwgcmVmcywgaXRlbSkpLFxuICAgIH07XG4gIH1cblxuICBzd2l0Y2ggKHN0cmF0ZWd5KSB7XG4gICAgY2FzZSAnc3RyaW5nJzpcbiAgICBjYXNlICdmb3JtYXQ6ZGF0ZS10aW1lJzpcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICBmb3JtYXQ6ICdkYXRlLXRpbWUnLFxuICAgICAgfTtcbiAgICBjYXNlICdmb3JtYXQ6ZGF0ZSc6XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgZm9ybWF0OiAnZGF0ZScsXG4gICAgICB9O1xuICAgIGNhc2UgJ2ludGVnZXInOlxuICAgICAgcmV0dXJuIGludGVnZXJEYXRlUGFyc2VyKGRlZik7XG4gIH1cbn1cblxuY29uc3QgaW50ZWdlckRhdGVQYXJzZXIgPSAoZGVmOiBab2REYXRlRGVmKSA9PiB7XG4gIGNvbnN0IHJlczogSnNvblNjaGVtYTdEYXRlVHlwZSA9IHtcbiAgICB0eXBlOiAnaW50ZWdlcicsXG4gICAgZm9ybWF0OiAndW5peC10aW1lJyxcbiAgfTtcblxuICBmb3IgKGNvbnN0IGNoZWNrIG9mIGRlZi5jaGVja3MpIHtcbiAgICBzd2l0Y2ggKGNoZWNrLmtpbmQpIHtcbiAgICAgIGNhc2UgJ21pbic6XG4gICAgICAgIHJlcy5taW5pbXVtID0gY2hlY2sudmFsdWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbWF4JzpcbiAgICAgICAgcmVzLm1heGltdW0gPSBjaGVjay52YWx1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlcztcbn07XG4iLCAiaW1wb3J0IHsgWm9kRGVmYXVsdERlZiB9IGZyb20gJ3pvZC92Myc7XG5pbXBvcnQgeyBwYXJzZURlZiB9IGZyb20gJy4uL3BhcnNlLWRlZic7XG5pbXBvcnQgeyBKc29uU2NoZW1hN1R5cGUgfSBmcm9tICcuLi9wYXJzZS10eXBlcyc7XG5pbXBvcnQgeyBSZWZzIH0gZnJvbSAnLi4vcmVmcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZURlZmF1bHREZWYoXG4gIF9kZWY6IFpvZERlZmF1bHREZWYsXG4gIHJlZnM6IFJlZnMsXG4pOiBKc29uU2NoZW1hN1R5cGUgJiB7IGRlZmF1bHQ6IGFueSB9IHtcbiAgcmV0dXJuIHtcbiAgICAuLi5wYXJzZURlZihfZGVmLmlubmVyVHlwZS5fZGVmLCByZWZzKSxcbiAgICBkZWZhdWx0OiBfZGVmLmRlZmF1bHRWYWx1ZSgpLFxuICB9O1xufVxuIiwgImltcG9ydCB7IFpvZEVmZmVjdHNEZWYgfSBmcm9tICd6b2QvdjMnO1xuaW1wb3J0IHsgcGFyc2VEZWYgfSBmcm9tICcuLi9wYXJzZS1kZWYnO1xuaW1wb3J0IHsgSnNvblNjaGVtYTdUeXBlIH0gZnJvbSAnLi4vcGFyc2UtdHlwZXMnO1xuaW1wb3J0IHsgUmVmcyB9IGZyb20gJy4uL3JlZnMnO1xuaW1wb3J0IHsgcGFyc2VBbnlEZWYgfSBmcm9tICcuL2FueSc7XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUVmZmVjdHNEZWYoXG4gIF9kZWY6IFpvZEVmZmVjdHNEZWYsXG4gIHJlZnM6IFJlZnMsXG4pOiBKc29uU2NoZW1hN1R5cGUgfCB1bmRlZmluZWQge1xuICByZXR1cm4gcmVmcy5lZmZlY3RTdHJhdGVneSA9PT0gJ2lucHV0J1xuICAgID8gcGFyc2VEZWYoX2RlZi5zY2hlbWEuX2RlZiwgcmVmcylcbiAgICA6IHBhcnNlQW55RGVmKCk7XG59XG4iLCAiaW1wb3J0IHsgWm9kRW51bURlZiB9IGZyb20gJ3pvZC92Myc7XG5cbmV4cG9ydCB0eXBlIEpzb25TY2hlbWE3RW51bVR5cGUgPSB7XG4gIHR5cGU6ICdzdHJpbmcnO1xuICBlbnVtOiBzdHJpbmdbXTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUVudW1EZWYoZGVmOiBab2RFbnVtRGVmKTogSnNvblNjaGVtYTdFbnVtVHlwZSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogJ3N0cmluZycsXG4gICAgZW51bTogQXJyYXkuZnJvbShkZWYudmFsdWVzKSxcbiAgfTtcbn1cbiIsICJpbXBvcnQgeyBab2RJbnRlcnNlY3Rpb25EZWYgfSBmcm9tICd6b2QvdjMnO1xuaW1wb3J0IHsgcGFyc2VEZWYgfSBmcm9tICcuLi9wYXJzZS1kZWYnO1xuaW1wb3J0IHsgSnNvblNjaGVtYTdUeXBlIH0gZnJvbSAnLi4vcGFyc2UtdHlwZXMnO1xuaW1wb3J0IHsgUmVmcyB9IGZyb20gJy4uL3JlZnMnO1xuaW1wb3J0IHsgSnNvblNjaGVtYTdTdHJpbmdUeXBlIH0gZnJvbSAnLi9zdHJpbmcnO1xuXG5leHBvcnQgdHlwZSBKc29uU2NoZW1hN0FsbE9mVHlwZSA9IHtcbiAgYWxsT2Y6IEpzb25TY2hlbWE3VHlwZVtdO1xuICB1bmV2YWx1YXRlZFByb3BlcnRpZXM/OiBib29sZWFuO1xufTtcblxuY29uc3QgaXNKc29uU2NoZW1hN0FsbE9mVHlwZSA9IChcbiAgdHlwZTogSnNvblNjaGVtYTdUeXBlIHwgSnNvblNjaGVtYTdTdHJpbmdUeXBlLFxuKTogdHlwZSBpcyBKc29uU2NoZW1hN0FsbE9mVHlwZSA9PiB7XG4gIGlmICgndHlwZScgaW4gdHlwZSAmJiB0eXBlLnR5cGUgPT09ICdzdHJpbmcnKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiAnYWxsT2YnIGluIHR5cGU7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VJbnRlcnNlY3Rpb25EZWYoXG4gIGRlZjogWm9kSW50ZXJzZWN0aW9uRGVmLFxuICByZWZzOiBSZWZzLFxuKTogSnNvblNjaGVtYTdBbGxPZlR5cGUgfCBKc29uU2NoZW1hN1R5cGUgfCB1bmRlZmluZWQge1xuICBjb25zdCBhbGxPZiA9IFtcbiAgICBwYXJzZURlZihkZWYubGVmdC5fZGVmLCB7XG4gICAgICAuLi5yZWZzLFxuICAgICAgY3VycmVudFBhdGg6IFsuLi5yZWZzLmN1cnJlbnRQYXRoLCAnYWxsT2YnLCAnMCddLFxuICAgIH0pLFxuICAgIHBhcnNlRGVmKGRlZi5yaWdodC5fZGVmLCB7XG4gICAgICAuLi5yZWZzLFxuICAgICAgY3VycmVudFBhdGg6IFsuLi5yZWZzLmN1cnJlbnRQYXRoLCAnYWxsT2YnLCAnMSddLFxuICAgIH0pLFxuICBdLmZpbHRlcigoeCk6IHggaXMgSnNvblNjaGVtYTdUeXBlID0+ICEheCk7XG5cbiAgY29uc3QgbWVyZ2VkQWxsT2Y6IEpzb25TY2hlbWE3VHlwZVtdID0gW107XG4gIC8vIElmIGVpdGhlciBvZiB0aGUgc2NoZW1hcyBpcyBhbiBhbGxPZiwgbWVyZ2UgdGhlbSBpbnRvIGEgc2luZ2xlIGFsbE9mXG4gIGFsbE9mLmZvckVhY2goc2NoZW1hID0+IHtcbiAgICBpZiAoaXNKc29uU2NoZW1hN0FsbE9mVHlwZShzY2hlbWEpKSB7XG4gICAgICBtZXJnZWRBbGxPZi5wdXNoKC4uLnNjaGVtYS5hbGxPZik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxldCBuZXN0ZWRTY2hlbWE6IEpzb25TY2hlbWE3VHlwZSA9IHNjaGVtYTtcbiAgICAgIGlmIChcbiAgICAgICAgJ2FkZGl0aW9uYWxQcm9wZXJ0aWVzJyBpbiBzY2hlbWEgJiZcbiAgICAgICAgc2NoZW1hLmFkZGl0aW9uYWxQcm9wZXJ0aWVzID09PSBmYWxzZVxuICAgICAgKSB7XG4gICAgICAgIGNvbnN0IHsgYWRkaXRpb25hbFByb3BlcnRpZXMsIC4uLnJlc3QgfSA9IHNjaGVtYTtcbiAgICAgICAgbmVzdGVkU2NoZW1hID0gcmVzdDtcbiAgICAgIH1cbiAgICAgIG1lcmdlZEFsbE9mLnB1c2gobmVzdGVkU2NoZW1hKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gbWVyZ2VkQWxsT2YubGVuZ3RoID8geyBhbGxPZjogbWVyZ2VkQWxsT2YgfSA6IHVuZGVmaW5lZDtcbn1cbiIsICJpbXBvcnQgeyBab2RMaXRlcmFsRGVmIH0gZnJvbSAnem9kL3YzJztcblxuZXhwb3J0IHR5cGUgSnNvblNjaGVtYTdMaXRlcmFsVHlwZSA9XG4gIHwge1xuICAgICAgdHlwZTogJ3N0cmluZycgfCAnbnVtYmVyJyB8ICdpbnRlZ2VyJyB8ICdib29sZWFuJztcbiAgICAgIGNvbnN0OiBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuO1xuICAgIH1cbiAgfCB7XG4gICAgICB0eXBlOiAnb2JqZWN0JyB8ICdhcnJheSc7XG4gICAgfTtcblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlTGl0ZXJhbERlZihkZWY6IFpvZExpdGVyYWxEZWYpOiBKc29uU2NoZW1hN0xpdGVyYWxUeXBlIHtcbiAgY29uc3QgcGFyc2VkVHlwZSA9IHR5cGVvZiBkZWYudmFsdWU7XG4gIGlmIChcbiAgICBwYXJzZWRUeXBlICE9PSAnYmlnaW50JyAmJlxuICAgIHBhcnNlZFR5cGUgIT09ICdudW1iZXInICYmXG4gICAgcGFyc2VkVHlwZSAhPT0gJ2Jvb2xlYW4nICYmXG4gICAgcGFyc2VkVHlwZSAhPT0gJ3N0cmluZydcbiAgKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IEFycmF5LmlzQXJyYXkoZGVmLnZhbHVlKSA/ICdhcnJheScgOiAnb2JqZWN0JyxcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBwYXJzZWRUeXBlID09PSAnYmlnaW50JyA/ICdpbnRlZ2VyJyA6IHBhcnNlZFR5cGUsXG4gICAgY29uc3Q6IGRlZi52YWx1ZSxcbiAgfTtcbn1cbiIsICJpbXBvcnQge1xuICBab2RGaXJzdFBhcnR5VHlwZUtpbmQsXG4gIFpvZE1hcERlZixcbiAgWm9kUmVjb3JkRGVmLFxuICBab2RUeXBlQW55LFxufSBmcm9tICd6b2QvdjMnO1xuaW1wb3J0IHsgcGFyc2VEZWYgfSBmcm9tICcuLi9wYXJzZS1kZWYnO1xuaW1wb3J0IHsgSnNvblNjaGVtYTdUeXBlIH0gZnJvbSAnLi4vcGFyc2UtdHlwZXMnO1xuaW1wb3J0IHsgUmVmcyB9IGZyb20gJy4uL3JlZnMnO1xuaW1wb3J0IHsgcGFyc2VCcmFuZGVkRGVmIH0gZnJvbSAnLi9icmFuZGVkJztcbmltcG9ydCB7IEpzb25TY2hlbWE3RW51bVR5cGUgfSBmcm9tICcuL2VudW0nO1xuaW1wb3J0IHsgSnNvblNjaGVtYTdTdHJpbmdUeXBlLCBwYXJzZVN0cmluZ0RlZiB9IGZyb20gJy4vc3RyaW5nJztcblxudHlwZSBKc29uU2NoZW1hN1JlY29yZFByb3BlcnR5TmFtZXNUeXBlID1cbiAgfCBPbWl0PEpzb25TY2hlbWE3U3RyaW5nVHlwZSwgJ3R5cGUnPlxuICB8IE9taXQ8SnNvblNjaGVtYTdFbnVtVHlwZSwgJ3R5cGUnPjtcblxuZXhwb3J0IHR5cGUgSnNvblNjaGVtYTdSZWNvcmRUeXBlID0ge1xuICB0eXBlOiAnb2JqZWN0JztcbiAgYWRkaXRpb25hbFByb3BlcnRpZXM/OiBKc29uU2NoZW1hN1R5cGUgfCB0cnVlO1xuICBwcm9wZXJ0eU5hbWVzPzogSnNvblNjaGVtYTdSZWNvcmRQcm9wZXJ0eU5hbWVzVHlwZTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVJlY29yZERlZihcbiAgZGVmOiBab2RSZWNvcmREZWY8Wm9kVHlwZUFueSwgWm9kVHlwZUFueT4gfCBab2RNYXBEZWYsXG4gIHJlZnM6IFJlZnMsXG4pOiBKc29uU2NoZW1hN1JlY29yZFR5cGUge1xuICBjb25zdCBzY2hlbWE6IEpzb25TY2hlbWE3UmVjb3JkVHlwZSA9IHtcbiAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICBhZGRpdGlvbmFsUHJvcGVydGllczpcbiAgICAgIHBhcnNlRGVmKGRlZi52YWx1ZVR5cGUuX2RlZiwge1xuICAgICAgICAuLi5yZWZzLFxuICAgICAgICBjdXJyZW50UGF0aDogWy4uLnJlZnMuY3VycmVudFBhdGgsICdhZGRpdGlvbmFsUHJvcGVydGllcyddLFxuICAgICAgfSkgPz8gcmVmcy5hbGxvd2VkQWRkaXRpb25hbFByb3BlcnRpZXMsXG4gIH07XG5cbiAgaWYgKFxuICAgIGRlZi5rZXlUeXBlPy5fZGVmLnR5cGVOYW1lID09PSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kU3RyaW5nICYmXG4gICAgZGVmLmtleVR5cGUuX2RlZi5jaGVja3M/Lmxlbmd0aFxuICApIHtcbiAgICBjb25zdCB7IHR5cGUsIC4uLmtleVR5cGUgfSA9IHBhcnNlU3RyaW5nRGVmKGRlZi5rZXlUeXBlLl9kZWYsIHJlZnMpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnNjaGVtYSxcbiAgICAgIHByb3BlcnR5TmFtZXM6IGtleVR5cGUsXG4gICAgfTtcbiAgfSBlbHNlIGlmIChkZWYua2V5VHlwZT8uX2RlZi50eXBlTmFtZSA9PT0gWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEVudW0pIHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4uc2NoZW1hLFxuICAgICAgcHJvcGVydHlOYW1lczoge1xuICAgICAgICBlbnVtOiBkZWYua2V5VHlwZS5fZGVmLnZhbHVlcyxcbiAgICAgIH0sXG4gICAgfTtcbiAgfSBlbHNlIGlmIChcbiAgICBkZWYua2V5VHlwZT8uX2RlZi50eXBlTmFtZSA9PT0gWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEJyYW5kZWQgJiZcbiAgICBkZWYua2V5VHlwZS5fZGVmLnR5cGUuX2RlZi50eXBlTmFtZSA9PT0gWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZFN0cmluZyAmJlxuICAgIGRlZi5rZXlUeXBlLl9kZWYudHlwZS5fZGVmLmNoZWNrcz8ubGVuZ3RoXG4gICkge1xuICAgIGNvbnN0IHsgdHlwZSwgLi4ua2V5VHlwZSB9ID0gcGFyc2VCcmFuZGVkRGVmKFxuICAgICAgZGVmLmtleVR5cGUuX2RlZixcbiAgICAgIHJlZnMsXG4gICAgKSBhcyBKc29uU2NoZW1hN1N0cmluZ1R5cGU7XG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4uc2NoZW1hLFxuICAgICAgcHJvcGVydHlOYW1lczoga2V5VHlwZSxcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHNjaGVtYTtcbn1cbiIsICJpbXBvcnQgeyBab2RTdHJpbmdEZWYgfSBmcm9tICd6b2QvdjMnO1xuaW1wb3J0IHsgUmVmcyB9IGZyb20gJy4uL3JlZnMnO1xuXG5sZXQgZW1vamlSZWdleDogUmVnRXhwIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuXG4vKipcbiAqIEdlbmVyYXRlZCBmcm9tIHRoZSByZWd1bGFyIGV4cHJlc3Npb25zIGZvdW5kIGhlcmUgYXMgb2YgMjAyNC0wNS0yMjpcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9jb2xpbmhhY2tzL3pvZC9ibG9iL21hc3Rlci9zcmMvdHlwZXMudHMuXG4gKlxuICogRXhwcmVzc2lvbnMgd2l0aCAvaSBmbGFnIGhhdmUgYmVlbiBjaGFuZ2VkIGFjY29yZGluZ2x5LlxuICovXG5leHBvcnQgY29uc3Qgem9kUGF0dGVybnMgPSB7XG4gIC8qKlxuICAgKiBgY2Agd2FzIGNoYW5nZWQgdG8gYFtjQ11gIHRvIHJlcGxpY2F0ZSAvaSBmbGFnXG4gICAqL1xuICBjdWlkOiAvXltjQ11bXlxccy1dezgsfSQvLFxuICBjdWlkMjogL15bMC05YS16XSskLyxcbiAgdWxpZDogL15bMC05QS1ISktNTlAtVFYtWl17MjZ9JC8sXG4gIC8qKlxuICAgKiBgYS16YCB3YXMgYWRkZWQgdG8gcmVwbGljYXRlIC9pIGZsYWdcbiAgICovXG4gIGVtYWlsOlxuICAgIC9eKD8hXFwuKSg/IS4qXFwuXFwuKShbYS16QS1aMC05XycrXFwtXFwuXSopW2EtekEtWjAtOV8rLV1AKFthLXpBLVowLTldW2EtekEtWjAtOVxcLV0qXFwuKStbYS16QS1aXXsyLH0kLyxcbiAgLyoqXG4gICAqIENvbnN0cnVjdGVkIGEgdmFsaWQgVW5pY29kZSBSZWdFeHBcbiAgICpcbiAgICogTGF6aWx5IGluc3RhbnRpYXRlIHNpbmNlIHRoaXMgdHlwZSBvZiByZWdleCBpc24ndCBzdXBwb3J0ZWRcbiAgICogaW4gYWxsIGVudnMgKGUuZy4gUmVhY3QgTmF0aXZlKS5cbiAgICpcbiAgICogU2VlOlxuICAgKiBodHRwczovL2dpdGh1Yi5jb20vY29saW5oYWNrcy96b2QvaXNzdWVzLzI0MzNcbiAgICogRml4IGluIFpvZDpcbiAgICogaHR0cHM6Ly9naXRodWIuY29tL2NvbGluaGFja3Mvem9kL2NvbW1pdC85MzQwZmQ1MWU0ODU3NmE3NWFkYzkxOWJmZjY1ZGJjNGE1ZDRjOTliXG4gICAqL1xuICBlbW9qaTogKCkgPT4ge1xuICAgIGlmIChlbW9qaVJlZ2V4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGVtb2ppUmVnZXggPSBSZWdFeHAoXG4gICAgICAgICdeKFxcXFxwe0V4dGVuZGVkX1BpY3RvZ3JhcGhpY318XFxcXHB7RW1vamlfQ29tcG9uZW50fSkrJCcsXG4gICAgICAgICd1JyxcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBlbW9qaVJlZ2V4O1xuICB9LFxuICAvKipcbiAgICogVW51c2VkXG4gICAqL1xuICB1dWlkOiAvXlswLTlhLWZBLUZdezh9XFxiLVswLTlhLWZBLUZdezR9XFxiLVswLTlhLWZBLUZdezR9XFxiLVswLTlhLWZBLUZdezR9XFxiLVswLTlhLWZBLUZdezEyfSQvLFxuICAvKipcbiAgICogVW51c2VkXG4gICAqL1xuICBpcHY0OiAvXig/Oig/OjI1WzAtNV18MlswLTRdWzAtOV18MVswLTldWzAtOV18WzEtOV1bMC05XXxbMC05XSlcXC4pezN9KD86MjVbMC01XXwyWzAtNF1bMC05XXwxWzAtOV1bMC05XXxbMS05XVswLTldfFswLTldKSQvLFxuICBpcHY0Q2lkcjpcbiAgICAvXig/Oig/OjI1WzAtNV18MlswLTRdWzAtOV18MVswLTldWzAtOV18WzEtOV1bMC05XXxbMC05XSlcXC4pezN9KD86MjVbMC01XXwyWzAtNF1bMC05XXwxWzAtOV1bMC05XXxbMS05XVswLTldfFswLTldKVxcLygzWzAtMl18WzEyXT9bMC05XSkkLyxcbiAgLyoqXG4gICAqIFVudXNlZFxuICAgKi9cbiAgaXB2NjogL14oKFthLWYwLTldezEsNH06KXs3fXw6OihbYS1mMC05XXsxLDR9Oil7MCw2fXwoW2EtZjAtOV17MSw0fTopezF9OihbYS1mMC05XXsxLDR9Oil7MCw1fXwoW2EtZjAtOV17MSw0fTopezJ9OihbYS1mMC05XXsxLDR9Oil7MCw0fXwoW2EtZjAtOV17MSw0fTopezN9OihbYS1mMC05XXsxLDR9Oil7MCwzfXwoW2EtZjAtOV17MSw0fTopezR9OihbYS1mMC05XXsxLDR9Oil7MCwyfXwoW2EtZjAtOV17MSw0fTopezV9OihbYS1mMC05XXsxLDR9Oil7MCwxfSkoW2EtZjAtOV17MSw0fXwoKCgyNVswLTVdKXwoMlswLTRdWzAtOV0pfCgxWzAtOV17Mn0pfChbMC05XXsxLDJ9KSlcXC4pezN9KCgyNVswLTVdKXwoMlswLTRdWzAtOV0pfCgxWzAtOV17Mn0pfChbMC05XXsxLDJ9KSkpJC8sXG4gIGlwdjZDaWRyOlxuICAgIC9eKChbMC05YS1mQS1GXXsxLDR9Oil7Nyw3fVswLTlhLWZBLUZdezEsNH18KFswLTlhLWZBLUZdezEsNH06KXsxLDd9OnwoWzAtOWEtZkEtRl17MSw0fTopezEsNn06WzAtOWEtZkEtRl17MSw0fXwoWzAtOWEtZkEtRl17MSw0fTopezEsNX0oOlswLTlhLWZBLUZdezEsNH0pezEsMn18KFswLTlhLWZBLUZdezEsNH06KXsxLDR9KDpbMC05YS1mQS1GXXsxLDR9KXsxLDN9fChbMC05YS1mQS1GXXsxLDR9Oil7MSwzfSg6WzAtOWEtZkEtRl17MSw0fSl7MSw0fXwoWzAtOWEtZkEtRl17MSw0fTopezEsMn0oOlswLTlhLWZBLUZdezEsNH0pezEsNX18WzAtOWEtZkEtRl17MSw0fTooKDpbMC05YS1mQS1GXXsxLDR9KXsxLDZ9KXw6KCg6WzAtOWEtZkEtRl17MSw0fSl7MSw3fXw6KXxmZTgwOig6WzAtOWEtZkEtRl17MCw0fSl7MCw0fSVbMC05YS16QS1aXXsxLH18OjooZmZmZig6MHsxLDR9KXswLDF9Oil7MCwxfSgoMjVbMC01XXwoMlswLTRdfDF7MCwxfVswLTldKXswLDF9WzAtOV0pXFwuKXszLDN9KDI1WzAtNV18KDJbMC00XXwxezAsMX1bMC05XSl7MCwxfVswLTldKXwoWzAtOWEtZkEtRl17MSw0fTopezEsNH06KCgyNVswLTVdfCgyWzAtNF18MXswLDF9WzAtOV0pezAsMX1bMC05XSlcXC4pezMsM30oMjVbMC01XXwoMlswLTRdfDF7MCwxfVswLTldKXswLDF9WzAtOV0pKVxcLygxMlswLThdfDFbMDFdWzAtOV18WzEtOV0/WzAtOV0pJC8sXG4gIGJhc2U2NDogL14oWzAtOWEtekEtWisvXXs0fSkqKChbMC05YS16QS1aKy9dezJ9PT0pfChbMC05YS16QS1aKy9dezN9PSkpPyQvLFxuICBiYXNlNjR1cmw6XG4gICAgL14oWzAtOWEtekEtWi1fXXs0fSkqKChbMC05YS16QS1aLV9dezJ9KD09KT8pfChbMC05YS16QS1aLV9dezN9KD0pPykpPyQvLFxuICBuYW5vaWQ6IC9eW2EtekEtWjAtOV8tXXsyMX0kLyxcbiAgand0OiAvXltBLVphLXowLTktX10rXFwuW0EtWmEtejAtOS1fXStcXC5bQS1aYS16MC05LV9dKiQvLFxufSBhcyBjb25zdDtcblxuZXhwb3J0IHR5cGUgSnNvblNjaGVtYTdTdHJpbmdUeXBlID0ge1xuICB0eXBlOiAnc3RyaW5nJztcbiAgbWluTGVuZ3RoPzogbnVtYmVyO1xuICBtYXhMZW5ndGg/OiBudW1iZXI7XG4gIGZvcm1hdD86XG4gICAgfCAnZW1haWwnXG4gICAgfCAnaWRuLWVtYWlsJ1xuICAgIHwgJ3VyaSdcbiAgICB8ICd1dWlkJ1xuICAgIHwgJ2RhdGUtdGltZSdcbiAgICB8ICdpcHY0J1xuICAgIHwgJ2lwdjYnXG4gICAgfCAnZGF0ZSdcbiAgICB8ICd0aW1lJ1xuICAgIHwgJ2R1cmF0aW9uJztcbiAgcGF0dGVybj86IHN0cmluZztcbiAgYWxsT2Y/OiB7XG4gICAgcGF0dGVybjogc3RyaW5nO1xuICB9W107XG4gIGFueU9mPzoge1xuICAgIGZvcm1hdDogc3RyaW5nO1xuICB9W107XG4gIGNvbnRlbnRFbmNvZGluZz86IHN0cmluZztcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVN0cmluZ0RlZihcbiAgZGVmOiBab2RTdHJpbmdEZWYsXG4gIHJlZnM6IFJlZnMsXG4pOiBKc29uU2NoZW1hN1N0cmluZ1R5cGUge1xuICBjb25zdCByZXM6IEpzb25TY2hlbWE3U3RyaW5nVHlwZSA9IHtcbiAgICB0eXBlOiAnc3RyaW5nJyxcbiAgfTtcblxuICBpZiAoZGVmLmNoZWNrcykge1xuICAgIGZvciAoY29uc3QgY2hlY2sgb2YgZGVmLmNoZWNrcykge1xuICAgICAgc3dpdGNoIChjaGVjay5raW5kKSB7XG4gICAgICAgIGNhc2UgJ21pbic6XG4gICAgICAgICAgcmVzLm1pbkxlbmd0aCA9XG4gICAgICAgICAgICB0eXBlb2YgcmVzLm1pbkxlbmd0aCA9PT0gJ251bWJlcidcbiAgICAgICAgICAgICAgPyBNYXRoLm1heChyZXMubWluTGVuZ3RoLCBjaGVjay52YWx1ZSlcbiAgICAgICAgICAgICAgOiBjaGVjay52YWx1ZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnbWF4JzpcbiAgICAgICAgICByZXMubWF4TGVuZ3RoID1cbiAgICAgICAgICAgIHR5cGVvZiByZXMubWF4TGVuZ3RoID09PSAnbnVtYmVyJ1xuICAgICAgICAgICAgICA/IE1hdGgubWluKHJlcy5tYXhMZW5ndGgsIGNoZWNrLnZhbHVlKVxuICAgICAgICAgICAgICA6IGNoZWNrLnZhbHVlO1xuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2VtYWlsJzpcbiAgICAgICAgICBzd2l0Y2ggKHJlZnMuZW1haWxTdHJhdGVneSkge1xuICAgICAgICAgICAgY2FzZSAnZm9ybWF0OmVtYWlsJzpcbiAgICAgICAgICAgICAgYWRkRm9ybWF0KHJlcywgJ2VtYWlsJywgY2hlY2subWVzc2FnZSwgcmVmcyk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnZm9ybWF0Omlkbi1lbWFpbCc6XG4gICAgICAgICAgICAgIGFkZEZvcm1hdChyZXMsICdpZG4tZW1haWwnLCBjaGVjay5tZXNzYWdlLCByZWZzKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdwYXR0ZXJuOnpvZCc6XG4gICAgICAgICAgICAgIGFkZFBhdHRlcm4ocmVzLCB6b2RQYXR0ZXJucy5lbWFpbCwgY2hlY2subWVzc2FnZSwgcmVmcyk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICd1cmwnOlxuICAgICAgICAgIGFkZEZvcm1hdChyZXMsICd1cmknLCBjaGVjay5tZXNzYWdlLCByZWZzKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAndXVpZCc6XG4gICAgICAgICAgYWRkRm9ybWF0KHJlcywgJ3V1aWQnLCBjaGVjay5tZXNzYWdlLCByZWZzKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAncmVnZXgnOlxuICAgICAgICAgIGFkZFBhdHRlcm4ocmVzLCBjaGVjay5yZWdleCwgY2hlY2subWVzc2FnZSwgcmVmcyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2N1aWQnOlxuICAgICAgICAgIGFkZFBhdHRlcm4ocmVzLCB6b2RQYXR0ZXJucy5jdWlkLCBjaGVjay5tZXNzYWdlLCByZWZzKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnY3VpZDInOlxuICAgICAgICAgIGFkZFBhdHRlcm4ocmVzLCB6b2RQYXR0ZXJucy5jdWlkMiwgY2hlY2subWVzc2FnZSwgcmVmcyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3N0YXJ0c1dpdGgnOlxuICAgICAgICAgIGFkZFBhdHRlcm4oXG4gICAgICAgICAgICByZXMsXG4gICAgICAgICAgICBSZWdFeHAoYF4ke2VzY2FwZUxpdGVyYWxDaGVja1ZhbHVlKGNoZWNrLnZhbHVlLCByZWZzKX1gKSxcbiAgICAgICAgICAgIGNoZWNrLm1lc3NhZ2UsXG4gICAgICAgICAgICByZWZzLFxuICAgICAgICAgICk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2VuZHNXaXRoJzpcbiAgICAgICAgICBhZGRQYXR0ZXJuKFxuICAgICAgICAgICAgcmVzLFxuICAgICAgICAgICAgUmVnRXhwKGAke2VzY2FwZUxpdGVyYWxDaGVja1ZhbHVlKGNoZWNrLnZhbHVlLCByZWZzKX0kYCksXG4gICAgICAgICAgICBjaGVjay5tZXNzYWdlLFxuICAgICAgICAgICAgcmVmcyxcbiAgICAgICAgICApO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdkYXRldGltZSc6XG4gICAgICAgICAgYWRkRm9ybWF0KHJlcywgJ2RhdGUtdGltZScsIGNoZWNrLm1lc3NhZ2UsIHJlZnMpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdkYXRlJzpcbiAgICAgICAgICBhZGRGb3JtYXQocmVzLCAnZGF0ZScsIGNoZWNrLm1lc3NhZ2UsIHJlZnMpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICd0aW1lJzpcbiAgICAgICAgICBhZGRGb3JtYXQocmVzLCAndGltZScsIGNoZWNrLm1lc3NhZ2UsIHJlZnMpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdkdXJhdGlvbic6XG4gICAgICAgICAgYWRkRm9ybWF0KHJlcywgJ2R1cmF0aW9uJywgY2hlY2subWVzc2FnZSwgcmVmcyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2xlbmd0aCc6XG4gICAgICAgICAgcmVzLm1pbkxlbmd0aCA9XG4gICAgICAgICAgICB0eXBlb2YgcmVzLm1pbkxlbmd0aCA9PT0gJ251bWJlcidcbiAgICAgICAgICAgICAgPyBNYXRoLm1heChyZXMubWluTGVuZ3RoLCBjaGVjay52YWx1ZSlcbiAgICAgICAgICAgICAgOiBjaGVjay52YWx1ZTtcbiAgICAgICAgICByZXMubWF4TGVuZ3RoID1cbiAgICAgICAgICAgIHR5cGVvZiByZXMubWF4TGVuZ3RoID09PSAnbnVtYmVyJ1xuICAgICAgICAgICAgICA/IE1hdGgubWluKHJlcy5tYXhMZW5ndGgsIGNoZWNrLnZhbHVlKVxuICAgICAgICAgICAgICA6IGNoZWNrLnZhbHVlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdpbmNsdWRlcyc6IHtcbiAgICAgICAgICBhZGRQYXR0ZXJuKFxuICAgICAgICAgICAgcmVzLFxuICAgICAgICAgICAgUmVnRXhwKGVzY2FwZUxpdGVyYWxDaGVja1ZhbHVlKGNoZWNrLnZhbHVlLCByZWZzKSksXG4gICAgICAgICAgICBjaGVjay5tZXNzYWdlLFxuICAgICAgICAgICAgcmVmcyxcbiAgICAgICAgICApO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgJ2lwJzoge1xuICAgICAgICAgIGlmIChjaGVjay52ZXJzaW9uICE9PSAndjYnKSB7XG4gICAgICAgICAgICBhZGRGb3JtYXQocmVzLCAnaXB2NCcsIGNoZWNrLm1lc3NhZ2UsIHJlZnMpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoY2hlY2sudmVyc2lvbiAhPT0gJ3Y0Jykge1xuICAgICAgICAgICAgYWRkRm9ybWF0KHJlcywgJ2lwdjYnLCBjaGVjay5tZXNzYWdlLCByZWZzKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAnYmFzZTY0dXJsJzpcbiAgICAgICAgICBhZGRQYXR0ZXJuKHJlcywgem9kUGF0dGVybnMuYmFzZTY0dXJsLCBjaGVjay5tZXNzYWdlLCByZWZzKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnand0JzpcbiAgICAgICAgICBhZGRQYXR0ZXJuKHJlcywgem9kUGF0dGVybnMuand0LCBjaGVjay5tZXNzYWdlLCByZWZzKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnY2lkcic6IHtcbiAgICAgICAgICBpZiAoY2hlY2sudmVyc2lvbiAhPT0gJ3Y2Jykge1xuICAgICAgICAgICAgYWRkUGF0dGVybihyZXMsIHpvZFBhdHRlcm5zLmlwdjRDaWRyLCBjaGVjay5tZXNzYWdlLCByZWZzKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGNoZWNrLnZlcnNpb24gIT09ICd2NCcpIHtcbiAgICAgICAgICAgIGFkZFBhdHRlcm4ocmVzLCB6b2RQYXR0ZXJucy5pcHY2Q2lkciwgY2hlY2subWVzc2FnZSwgcmVmcyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgJ2Vtb2ppJzpcbiAgICAgICAgICBhZGRQYXR0ZXJuKHJlcywgem9kUGF0dGVybnMuZW1vamkoKSwgY2hlY2subWVzc2FnZSwgcmVmcyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3VsaWQnOiB7XG4gICAgICAgICAgYWRkUGF0dGVybihyZXMsIHpvZFBhdHRlcm5zLnVsaWQsIGNoZWNrLm1lc3NhZ2UsIHJlZnMpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgJ2Jhc2U2NCc6IHtcbiAgICAgICAgICBzd2l0Y2ggKHJlZnMuYmFzZTY0U3RyYXRlZ3kpIHtcbiAgICAgICAgICAgIGNhc2UgJ2Zvcm1hdDpiaW5hcnknOiB7XG4gICAgICAgICAgICAgIGFkZEZvcm1hdChyZXMsICdiaW5hcnknIGFzIGFueSwgY2hlY2subWVzc2FnZSwgcmVmcyk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYXNlICdjb250ZW50RW5jb2Rpbmc6YmFzZTY0Jzoge1xuICAgICAgICAgICAgICByZXMuY29udGVudEVuY29kaW5nID0gJ2Jhc2U2NCc7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYXNlICdwYXR0ZXJuOnpvZCc6IHtcbiAgICAgICAgICAgICAgYWRkUGF0dGVybihyZXMsIHpvZFBhdHRlcm5zLmJhc2U2NCwgY2hlY2subWVzc2FnZSwgcmVmcyk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlICduYW5vaWQnOiB7XG4gICAgICAgICAgYWRkUGF0dGVybihyZXMsIHpvZFBhdHRlcm5zLm5hbm9pZCwgY2hlY2subWVzc2FnZSwgcmVmcyk7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAndG9Mb3dlckNhc2UnOlxuICAgICAgICBjYXNlICd0b1VwcGVyQ2FzZSc6XG4gICAgICAgIGNhc2UgJ3RyaW0nOlxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIC8qIGM4IGlnbm9yZSBuZXh0ICovXG4gICAgICAgICAgKChfOiBuZXZlcikgPT4ge30pKGNoZWNrKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzO1xufVxuXG5mdW5jdGlvbiBlc2NhcGVMaXRlcmFsQ2hlY2tWYWx1ZShsaXRlcmFsOiBzdHJpbmcsIHJlZnM6IFJlZnMpOiBzdHJpbmcge1xuICByZXR1cm4gcmVmcy5wYXR0ZXJuU3RyYXRlZ3kgPT09ICdlc2NhcGUnXG4gICAgPyBlc2NhcGVOb25BbHBoYU51bWVyaWMobGl0ZXJhbClcbiAgICA6IGxpdGVyYWw7XG59XG5cbmNvbnN0IEFMUEhBX05VTUVSSUMgPSBuZXcgU2V0KFxuICAnQUJDREVGR0hJSktMTU5PUFFSU1RVVlhZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ4eXowMTIzNDU2Nzg5Jyxcbik7XG5cbmZ1bmN0aW9uIGVzY2FwZU5vbkFscGhhTnVtZXJpYyhzb3VyY2U6IHN0cmluZykge1xuICBsZXQgcmVzdWx0ID0gJyc7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzb3VyY2UubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoIUFMUEhBX05VTUVSSUMuaGFzKHNvdXJjZVtpXSkpIHtcbiAgICAgIHJlc3VsdCArPSAnXFxcXCc7XG4gICAgfVxuXG4gICAgcmVzdWx0ICs9IHNvdXJjZVtpXTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8vIEFkZHMgYSBcImZvcm1hdFwiIGtleXdvcmQgdG8gdGhlIHNjaGVtYS4gSWYgYSBmb3JtYXQgZXhpc3RzLCBib3RoIGZvcm1hdHMgd2lsbCBiZSBqb2luZWQgaW4gYW4gYWxsT2Ytbm9kZSwgYWxvbmcgd2l0aCBzdWJzZXF1ZW50IG9uZXMuXG5mdW5jdGlvbiBhZGRGb3JtYXQoXG4gIHNjaGVtYTogSnNvblNjaGVtYTdTdHJpbmdUeXBlLFxuICB2YWx1ZTogUmVxdWlyZWQ8SnNvblNjaGVtYTdTdHJpbmdUeXBlPlsnZm9ybWF0J10sXG4gIG1lc3NhZ2U6IHN0cmluZyB8IHVuZGVmaW5lZCxcbiAgcmVmczogUmVmcyxcbikge1xuICBpZiAoc2NoZW1hLmZvcm1hdCB8fCBzY2hlbWEuYW55T2Y/LnNvbWUoeCA9PiB4LmZvcm1hdCkpIHtcbiAgICBpZiAoIXNjaGVtYS5hbnlPZikge1xuICAgICAgc2NoZW1hLmFueU9mID0gW107XG4gICAgfVxuXG4gICAgaWYgKHNjaGVtYS5mb3JtYXQpIHtcbiAgICAgIHNjaGVtYS5hbnlPZiEucHVzaCh7XG4gICAgICAgIGZvcm1hdDogc2NoZW1hLmZvcm1hdCxcbiAgICAgIH0pO1xuICAgICAgZGVsZXRlIHNjaGVtYS5mb3JtYXQ7XG4gICAgfVxuXG4gICAgc2NoZW1hLmFueU9mIS5wdXNoKHtcbiAgICAgIGZvcm1hdDogdmFsdWUsXG4gICAgICAuLi4obWVzc2FnZSAmJlxuICAgICAgICByZWZzLmVycm9yTWVzc2FnZXMgJiYgeyBlcnJvck1lc3NhZ2U6IHsgZm9ybWF0OiBtZXNzYWdlIH0gfSksXG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgc2NoZW1hLmZvcm1hdCA9IHZhbHVlO1xuICB9XG59XG5cbi8vIEFkZHMgYSBcInBhdHRlcm5cIiBrZXl3b3JkIHRvIHRoZSBzY2hlbWEuIElmIGEgcGF0dGVybiBleGlzdHMsIGJvdGggcGF0dGVybnMgd2lsbCBiZSBqb2luZWQgaW4gYW4gYWxsT2Ytbm9kZSwgYWxvbmcgd2l0aCBzdWJzZXF1ZW50IG9uZXMuXG5mdW5jdGlvbiBhZGRQYXR0ZXJuKFxuICBzY2hlbWE6IEpzb25TY2hlbWE3U3RyaW5nVHlwZSxcbiAgcmVnZXg6IFJlZ0V4cCxcbiAgbWVzc2FnZTogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICByZWZzOiBSZWZzLFxuKSB7XG4gIGlmIChzY2hlbWEucGF0dGVybiB8fCBzY2hlbWEuYWxsT2Y/LnNvbWUoeCA9PiB4LnBhdHRlcm4pKSB7XG4gICAgaWYgKCFzY2hlbWEuYWxsT2YpIHtcbiAgICAgIHNjaGVtYS5hbGxPZiA9IFtdO1xuICAgIH1cblxuICAgIGlmIChzY2hlbWEucGF0dGVybikge1xuICAgICAgc2NoZW1hLmFsbE9mIS5wdXNoKHtcbiAgICAgICAgcGF0dGVybjogc2NoZW1hLnBhdHRlcm4sXG4gICAgICB9KTtcbiAgICAgIGRlbGV0ZSBzY2hlbWEucGF0dGVybjtcbiAgICB9XG5cbiAgICBzY2hlbWEuYWxsT2YhLnB1c2goe1xuICAgICAgcGF0dGVybjogc3RyaW5naWZ5UmVnRXhwV2l0aEZsYWdzKHJlZ2V4LCByZWZzKSxcbiAgICAgIC4uLihtZXNzYWdlICYmXG4gICAgICAgIHJlZnMuZXJyb3JNZXNzYWdlcyAmJiB7IGVycm9yTWVzc2FnZTogeyBwYXR0ZXJuOiBtZXNzYWdlIH0gfSksXG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgc2NoZW1hLnBhdHRlcm4gPSBzdHJpbmdpZnlSZWdFeHBXaXRoRmxhZ3MocmVnZXgsIHJlZnMpO1xuICB9XG59XG5cbi8vIE11dGF0ZSB6LnN0cmluZy5yZWdleCgpIGluIGEgYmVzdCBhdHRlbXB0IHRvIGFjY29tbW9kYXRlIGZvciByZWdleCBmbGFncyB3aGVuIGFwcGx5UmVnZXhGbGFncyBpcyB0cnVlXG5mdW5jdGlvbiBzdHJpbmdpZnlSZWdFeHBXaXRoRmxhZ3MocmVnZXg6IFJlZ0V4cCwgcmVmczogUmVmcyk6IHN0cmluZyB7XG4gIGlmICghcmVmcy5hcHBseVJlZ2V4RmxhZ3MgfHwgIXJlZ2V4LmZsYWdzKSB7XG4gICAgcmV0dXJuIHJlZ2V4LnNvdXJjZTtcbiAgfVxuXG4gIC8vIEN1cnJlbnRseSBoYW5kbGVkIGZsYWdzXG4gIGNvbnN0IGZsYWdzID0ge1xuICAgIGk6IHJlZ2V4LmZsYWdzLmluY2x1ZGVzKCdpJyksIC8vIENhc2UtaW5zZW5zaXRpdmVcbiAgICBtOiByZWdleC5mbGFncy5pbmNsdWRlcygnbScpLCAvLyBgXmAgYW5kIGAkYCBtYXRjaGVzIGFkamFjZW50IHRvIG5ld2xpbmUgY2hhcmFjdGVyc1xuICAgIHM6IHJlZ2V4LmZsYWdzLmluY2x1ZGVzKCdzJyksIC8vIGAuYCBtYXRjaGVzIG5ld2xpbmVzXG4gIH07XG5cbiAgLy8gVGhlIGdlbmVyYWwgcHJpbmNpcGxlIGhlcmUgaXMgdG8gc3RlcCB0aHJvdWdoIGVhY2ggY2hhcmFjdGVyLCBvbmUgYXQgYSB0aW1lLCBhcHBseWluZyBtdXRhdGlvbnMgYXMgZmxhZ3MgcmVxdWlyZS4gV2Uga2VlcCB0cmFjayB3aGVuIHRoZSBjdXJyZW50IGNoYXJhY3RlciBpcyBlc2NhcGVkLCBhbmQgd2hlbiBpdCdzIGluc2lkZSBhIGdyb3VwIC9saWtlIFt0aGlzXS8gb3IgKGFsc28pIGEgcmFuZ2UgbGlrZSAvW2Etel0vLiBUaGUgZm9sbG93aW5nIGlzIGZhaXJseSBicml0dGxlIGltcGVyYXRpdmUgY29kZTsgZWRpdCBhdCB5b3VyIHBlcmlsIVxuICBjb25zdCBzb3VyY2UgPSBmbGFncy5pID8gcmVnZXguc291cmNlLnRvTG93ZXJDYXNlKCkgOiByZWdleC5zb3VyY2U7XG4gIGxldCBwYXR0ZXJuID0gJyc7XG4gIGxldCBpc0VzY2FwZWQgPSBmYWxzZTtcbiAgbGV0IGluQ2hhckdyb3VwID0gZmFsc2U7XG4gIGxldCBpbkNoYXJSYW5nZSA9IGZhbHNlO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc291cmNlLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGlzRXNjYXBlZCkge1xuICAgICAgcGF0dGVybiArPSBzb3VyY2VbaV07XG4gICAgICBpc0VzY2FwZWQgPSBmYWxzZTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChmbGFncy5pKSB7XG4gICAgICBpZiAoaW5DaGFyR3JvdXApIHtcbiAgICAgICAgaWYgKHNvdXJjZVtpXS5tYXRjaCgvW2Etel0vKSkge1xuICAgICAgICAgIGlmIChpbkNoYXJSYW5nZSkge1xuICAgICAgICAgICAgcGF0dGVybiArPSBzb3VyY2VbaV07XG4gICAgICAgICAgICBwYXR0ZXJuICs9IGAke3NvdXJjZVtpIC0gMl19LSR7c291cmNlW2ldfWAudG9VcHBlckNhc2UoKTtcbiAgICAgICAgICAgIGluQ2hhclJhbmdlID0gZmFsc2U7XG4gICAgICAgICAgfSBlbHNlIGlmIChzb3VyY2VbaSArIDFdID09PSAnLScgJiYgc291cmNlW2kgKyAyXT8ubWF0Y2goL1thLXpdLykpIHtcbiAgICAgICAgICAgIHBhdHRlcm4gKz0gc291cmNlW2ldO1xuICAgICAgICAgICAgaW5DaGFyUmFuZ2UgPSB0cnVlO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwYXR0ZXJuICs9IGAke3NvdXJjZVtpXX0ke3NvdXJjZVtpXS50b1VwcGVyQ2FzZSgpfWA7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHNvdXJjZVtpXS5tYXRjaCgvW2Etel0vKSkge1xuICAgICAgICBwYXR0ZXJuICs9IGBbJHtzb3VyY2VbaV19JHtzb3VyY2VbaV0udG9VcHBlckNhc2UoKX1dYDtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGZsYWdzLm0pIHtcbiAgICAgIGlmIChzb3VyY2VbaV0gPT09ICdeJykge1xuICAgICAgICBwYXR0ZXJuICs9IGAoXnwoPzw9W1xcclxcbl0pKWA7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfSBlbHNlIGlmIChzb3VyY2VbaV0gPT09ICckJykge1xuICAgICAgICBwYXR0ZXJuICs9IGAoJHwoPz1bXFxyXFxuXSkpYDtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGZsYWdzLnMgJiYgc291cmNlW2ldID09PSAnLicpIHtcbiAgICAgIHBhdHRlcm4gKz0gaW5DaGFyR3JvdXAgPyBgJHtzb3VyY2VbaV19XFxyXFxuYCA6IGBbJHtzb3VyY2VbaV19XFxyXFxuXWA7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBwYXR0ZXJuICs9IHNvdXJjZVtpXTtcbiAgICBpZiAoc291cmNlW2ldID09PSAnXFxcXCcpIHtcbiAgICAgIGlzRXNjYXBlZCA9IHRydWU7XG4gICAgfSBlbHNlIGlmIChpbkNoYXJHcm91cCAmJiBzb3VyY2VbaV0gPT09ICddJykge1xuICAgICAgaW5DaGFyR3JvdXAgPSBmYWxzZTtcbiAgICB9IGVsc2UgaWYgKCFpbkNoYXJHcm91cCAmJiBzb3VyY2VbaV0gPT09ICdbJykge1xuICAgICAgaW5DaGFyR3JvdXAgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHRyeSB7XG4gICAgbmV3IFJlZ0V4cChwYXR0ZXJuKTtcbiAgfSBjYXRjaCB7XG4gICAgY29uc29sZS53YXJuKFxuICAgICAgYENvdWxkIG5vdCBjb252ZXJ0IHJlZ2V4IHBhdHRlcm4gYXQgJHtyZWZzLmN1cnJlbnRQYXRoLmpvaW4oXG4gICAgICAgICcvJyxcbiAgICAgICl9IHRvIGEgZmxhZy1pbmRlcGVuZGVudCBmb3JtISBGYWxsaW5nIGJhY2sgdG8gdGhlIGZsYWctaWdub3JhbnQgc291cmNlYCxcbiAgICApO1xuICAgIHJldHVybiByZWdleC5zb3VyY2U7XG4gIH1cblxuICByZXR1cm4gcGF0dGVybjtcbn1cbiIsICJpbXBvcnQgeyBab2RNYXBEZWYgfSBmcm9tICd6b2QvdjMnO1xuaW1wb3J0IHsgcGFyc2VEZWYgfSBmcm9tICcuLi9wYXJzZS1kZWYnO1xuaW1wb3J0IHsgSnNvblNjaGVtYTdUeXBlIH0gZnJvbSAnLi4vcGFyc2UtdHlwZXMnO1xuaW1wb3J0IHsgUmVmcyB9IGZyb20gJy4uL3JlZnMnO1xuaW1wb3J0IHsgcGFyc2VBbnlEZWYgfSBmcm9tICcuL2FueSc7XG5pbXBvcnQgeyBKc29uU2NoZW1hN1JlY29yZFR5cGUsIHBhcnNlUmVjb3JkRGVmIH0gZnJvbSAnLi9yZWNvcmQnO1xuXG5leHBvcnQgdHlwZSBKc29uU2NoZW1hN01hcFR5cGUgPSB7XG4gIHR5cGU6ICdhcnJheSc7XG4gIG1heEl0ZW1zOiAxMjU7XG4gIGl0ZW1zOiB7XG4gICAgdHlwZTogJ2FycmF5JztcbiAgICBpdGVtczogW0pzb25TY2hlbWE3VHlwZSwgSnNvblNjaGVtYTdUeXBlXTtcbiAgICBtaW5JdGVtczogMjtcbiAgICBtYXhJdGVtczogMjtcbiAgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZU1hcERlZihcbiAgZGVmOiBab2RNYXBEZWYsXG4gIHJlZnM6IFJlZnMsXG4pOiBKc29uU2NoZW1hN01hcFR5cGUgfCBKc29uU2NoZW1hN1JlY29yZFR5cGUge1xuICBpZiAocmVmcy5tYXBTdHJhdGVneSA9PT0gJ3JlY29yZCcpIHtcbiAgICByZXR1cm4gcGFyc2VSZWNvcmREZWYoZGVmLCByZWZzKTtcbiAgfVxuXG4gIGNvbnN0IGtleXMgPVxuICAgIHBhcnNlRGVmKGRlZi5rZXlUeXBlLl9kZWYsIHtcbiAgICAgIC4uLnJlZnMsXG4gICAgICBjdXJyZW50UGF0aDogWy4uLnJlZnMuY3VycmVudFBhdGgsICdpdGVtcycsICdpdGVtcycsICcwJ10sXG4gICAgfSkgfHwgcGFyc2VBbnlEZWYoKTtcbiAgY29uc3QgdmFsdWVzID1cbiAgICBwYXJzZURlZihkZWYudmFsdWVUeXBlLl9kZWYsIHtcbiAgICAgIC4uLnJlZnMsXG4gICAgICBjdXJyZW50UGF0aDogWy4uLnJlZnMuY3VycmVudFBhdGgsICdpdGVtcycsICdpdGVtcycsICcxJ10sXG4gICAgfSkgfHwgcGFyc2VBbnlEZWYoKTtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAnYXJyYXknLFxuICAgIG1heEl0ZW1zOiAxMjUsXG4gICAgaXRlbXM6IHtcbiAgICAgIHR5cGU6ICdhcnJheScsXG4gICAgICBpdGVtczogW2tleXMsIHZhbHVlc10sXG4gICAgICBtaW5JdGVtczogMixcbiAgICAgIG1heEl0ZW1zOiAyLFxuICAgIH0sXG4gIH07XG59XG4iLCAiaW1wb3J0IHsgWm9kTmF0aXZlRW51bURlZiB9IGZyb20gJ3pvZC92Myc7XG5cbmV4cG9ydCB0eXBlIEpzb25TY2hlbWE3TmF0aXZlRW51bVR5cGUgPSB7XG4gIHR5cGU6ICdzdHJpbmcnIHwgJ251bWJlcicgfCBbJ3N0cmluZycsICdudW1iZXInXTtcbiAgZW51bTogKHN0cmluZyB8IG51bWJlcilbXTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZU5hdGl2ZUVudW1EZWYoXG4gIGRlZjogWm9kTmF0aXZlRW51bURlZixcbik6IEpzb25TY2hlbWE3TmF0aXZlRW51bVR5cGUge1xuICBjb25zdCBvYmplY3QgPSBkZWYudmFsdWVzO1xuICBjb25zdCBhY3R1YWxLZXlzID0gT2JqZWN0LmtleXMoZGVmLnZhbHVlcykuZmlsdGVyKChrZXk6IHN0cmluZykgPT4ge1xuICAgIHJldHVybiB0eXBlb2Ygb2JqZWN0W29iamVjdFtrZXldXSAhPT0gJ251bWJlcic7XG4gIH0pO1xuXG4gIGNvbnN0IGFjdHVhbFZhbHVlcyA9IGFjdHVhbEtleXMubWFwKChrZXk6IHN0cmluZykgPT4gb2JqZWN0W2tleV0pO1xuXG4gIGNvbnN0IHBhcnNlZFR5cGVzID0gQXJyYXkuZnJvbShcbiAgICBuZXcgU2V0KGFjdHVhbFZhbHVlcy5tYXAoKHZhbHVlczogc3RyaW5nIHwgbnVtYmVyKSA9PiB0eXBlb2YgdmFsdWVzKSksXG4gICk7XG5cbiAgcmV0dXJuIHtcbiAgICB0eXBlOlxuICAgICAgcGFyc2VkVHlwZXMubGVuZ3RoID09PSAxXG4gICAgICAgID8gcGFyc2VkVHlwZXNbMF0gPT09ICdzdHJpbmcnXG4gICAgICAgICAgPyAnc3RyaW5nJ1xuICAgICAgICAgIDogJ251bWJlcidcbiAgICAgICAgOiBbJ3N0cmluZycsICdudW1iZXInXSxcbiAgICBlbnVtOiBhY3R1YWxWYWx1ZXMsXG4gIH07XG59XG4iLCAiaW1wb3J0IHsgSnNvblNjaGVtYTdBbnlUeXBlLCBwYXJzZUFueURlZiB9IGZyb20gJy4vYW55JztcblxuZXhwb3J0IHR5cGUgSnNvblNjaGVtYTdOZXZlclR5cGUgPSB7XG4gIG5vdDogSnNvblNjaGVtYTdBbnlUeXBlO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlTmV2ZXJEZWYoKTogSnNvblNjaGVtYTdOZXZlclR5cGUgfCB1bmRlZmluZWQge1xuICByZXR1cm4geyBub3Q6IHBhcnNlQW55RGVmKCkgfTtcbn1cbiIsICJleHBvcnQgdHlwZSBKc29uU2NoZW1hN051bGxUeXBlID0ge1xuICB0eXBlOiAnbnVsbCc7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VOdWxsRGVmKCk6IEpzb25TY2hlbWE3TnVsbFR5cGUge1xuICByZXR1cm4ge1xuICAgIHR5cGU6ICdudWxsJyxcbiAgfTtcbn1cbiIsICJpbXBvcnQge1xuICBab2REaXNjcmltaW5hdGVkVW5pb25EZWYsXG4gIFpvZExpdGVyYWxEZWYsXG4gIFpvZFR5cGVBbnksXG4gIFpvZFVuaW9uRGVmLFxufSBmcm9tICd6b2QvdjMnO1xuaW1wb3J0IHsgcGFyc2VEZWYgfSBmcm9tICcuLi9wYXJzZS1kZWYnO1xuaW1wb3J0IHsgSnNvblNjaGVtYTdUeXBlIH0gZnJvbSAnLi4vcGFyc2UtdHlwZXMnO1xuaW1wb3J0IHsgUmVmcyB9IGZyb20gJy4uL3JlZnMnO1xuXG5leHBvcnQgY29uc3QgcHJpbWl0aXZlTWFwcGluZ3MgPSB7XG4gIFpvZFN0cmluZzogJ3N0cmluZycsXG4gIFpvZE51bWJlcjogJ251bWJlcicsXG4gIFpvZEJpZ0ludDogJ2ludGVnZXInLFxuICBab2RCb29sZWFuOiAnYm9vbGVhbicsXG4gIFpvZE51bGw6ICdudWxsJyxcbn0gYXMgY29uc3Q7XG50eXBlIFpvZFByaW1pdGl2ZSA9IGtleW9mIHR5cGVvZiBwcmltaXRpdmVNYXBwaW5ncztcbnR5cGUgSnNvblNjaGVtYTdQcmltaXRpdmUgPVxuICAodHlwZW9mIHByaW1pdGl2ZU1hcHBpbmdzKVtrZXlvZiB0eXBlb2YgcHJpbWl0aXZlTWFwcGluZ3NdO1xuXG5leHBvcnQgdHlwZSBKc29uU2NoZW1hN1VuaW9uVHlwZSA9XG4gIHwgSnNvblNjaGVtYTdQcmltaXRpdmVVbmlvblR5cGVcbiAgfCBKc29uU2NoZW1hN0FueU9mVHlwZTtcblxudHlwZSBKc29uU2NoZW1hN1ByaW1pdGl2ZVVuaW9uVHlwZSA9XG4gIHwge1xuICAgICAgdHlwZTogSnNvblNjaGVtYTdQcmltaXRpdmUgfCBKc29uU2NoZW1hN1ByaW1pdGl2ZVtdO1xuICAgIH1cbiAgfCB7XG4gICAgICB0eXBlOiBKc29uU2NoZW1hN1ByaW1pdGl2ZSB8IEpzb25TY2hlbWE3UHJpbWl0aXZlW107XG4gICAgICBlbnVtOiAoc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50IHwgYm9vbGVhbiB8IG51bGwpW107XG4gICAgfTtcblxudHlwZSBKc29uU2NoZW1hN0FueU9mVHlwZSA9IHtcbiAgYW55T2Y6IEpzb25TY2hlbWE3VHlwZVtdO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlVW5pb25EZWYoXG4gIGRlZjogWm9kVW5pb25EZWYgfCBab2REaXNjcmltaW5hdGVkVW5pb25EZWY8YW55LCBhbnk+LFxuICByZWZzOiBSZWZzLFxuKTogSnNvblNjaGVtYTdQcmltaXRpdmVVbmlvblR5cGUgfCBKc29uU2NoZW1hN0FueU9mVHlwZSB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IG9wdGlvbnM6IHJlYWRvbmx5IFpvZFR5cGVBbnlbXSA9XG4gICAgZGVmLm9wdGlvbnMgaW5zdGFuY2VvZiBNYXAgPyBBcnJheS5mcm9tKGRlZi5vcHRpb25zLnZhbHVlcygpKSA6IGRlZi5vcHRpb25zO1xuXG4gIC8vIFRoaXMgYmxvY2tzIHRyaWVzIHRvIGxvb2sgYWhlYWQgYSBiaXQgdG8gcHJvZHVjZSBuaWNlciBsb29raW5nIHNjaGVtYXMgd2l0aCB0eXBlIGFycmF5IGluc3RlYWQgb2YgYW55T2YuXG4gIGlmIChcbiAgICBvcHRpb25zLmV2ZXJ5KFxuICAgICAgeCA9PlxuICAgICAgICB4Ll9kZWYudHlwZU5hbWUgaW4gcHJpbWl0aXZlTWFwcGluZ3MgJiZcbiAgICAgICAgKCF4Ll9kZWYuY2hlY2tzIHx8ICF4Ll9kZWYuY2hlY2tzLmxlbmd0aCksXG4gICAgKVxuICApIHtcbiAgICAvLyBhbGwgdHlwZXMgaW4gdW5pb24gYXJlIHByaW1pdGl2ZSBhbmQgbGFjayBjaGVja3MsIHNvIG1pZ2h0IGFzIHdlbGwgc3F1YXNoIGludG8ge3R5cGU6IFsuLi5dfVxuXG4gICAgY29uc3QgdHlwZXMgPSBvcHRpb25zLnJlZHVjZSgodHlwZXM6IEpzb25TY2hlbWE3UHJpbWl0aXZlW10sIHgpID0+IHtcbiAgICAgIGNvbnN0IHR5cGUgPSBwcmltaXRpdmVNYXBwaW5nc1t4Ll9kZWYudHlwZU5hbWUgYXMgWm9kUHJpbWl0aXZlXTsgLy9DYW4gYmUgc2FmZWx5IGNhc3RlZCBkdWUgdG8gcm93IDQzXG4gICAgICByZXR1cm4gdHlwZSAmJiAhdHlwZXMuaW5jbHVkZXModHlwZSkgPyBbLi4udHlwZXMsIHR5cGVdIDogdHlwZXM7XG4gICAgfSwgW10pO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IHR5cGVzLmxlbmd0aCA+IDEgPyB0eXBlcyA6IHR5cGVzWzBdLFxuICAgIH07XG4gIH0gZWxzZSBpZiAoXG4gICAgb3B0aW9ucy5ldmVyeSh4ID0+IHguX2RlZi50eXBlTmFtZSA9PT0gJ1pvZExpdGVyYWwnICYmICF4LmRlc2NyaXB0aW9uKVxuICApIHtcbiAgICAvLyBhbGwgb3B0aW9ucyBsaXRlcmFsc1xuXG4gICAgY29uc3QgdHlwZXMgPSBvcHRpb25zLnJlZHVjZShcbiAgICAgIChhY2M6IEpzb25TY2hlbWE3UHJpbWl0aXZlW10sIHg6IHsgX2RlZjogWm9kTGl0ZXJhbERlZiB9KSA9PiB7XG4gICAgICAgIGNvbnN0IHR5cGUgPSB0eXBlb2YgeC5fZGVmLnZhbHVlO1xuICAgICAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgICAgIGNhc2UgJ251bWJlcic6XG4gICAgICAgICAgY2FzZSAnYm9vbGVhbic6XG4gICAgICAgICAgICByZXR1cm4gWy4uLmFjYywgdHlwZV07XG4gICAgICAgICAgY2FzZSAnYmlnaW50JzpcbiAgICAgICAgICAgIHJldHVybiBbLi4uYWNjLCAnaW50ZWdlcicgYXMgY29uc3RdO1xuICAgICAgICAgIGNhc2UgJ29iamVjdCc6XG4gICAgICAgICAgICBpZiAoeC5fZGVmLnZhbHVlID09PSBudWxsKSByZXR1cm4gWy4uLmFjYywgJ251bGwnIGFzIGNvbnN0XTtcbiAgICAgICAgICBjYXNlICdzeW1ib2wnOlxuICAgICAgICAgIGNhc2UgJ3VuZGVmaW5lZCc6XG4gICAgICAgICAgY2FzZSAnZnVuY3Rpb24nOlxuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgW10sXG4gICAgKTtcblxuICAgIGlmICh0eXBlcy5sZW5ndGggPT09IG9wdGlvbnMubGVuZ3RoKSB7XG4gICAgICAvLyBhbGwgdGhlIGxpdGVyYWxzIGFyZSBwcmltaXRpdmUsIGFzIGZhciBhcyBudWxsIGNhbiBiZSBjb25zaWRlcmVkIHByaW1pdGl2ZVxuXG4gICAgICBjb25zdCB1bmlxdWVUeXBlcyA9IHR5cGVzLmZpbHRlcigoeCwgaSwgYSkgPT4gYS5pbmRleE9mKHgpID09PSBpKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6IHVuaXF1ZVR5cGVzLmxlbmd0aCA+IDEgPyB1bmlxdWVUeXBlcyA6IHVuaXF1ZVR5cGVzWzBdLFxuICAgICAgICBlbnVtOiBvcHRpb25zLnJlZHVjZShcbiAgICAgICAgICAoYWNjLCB4KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gYWNjLmluY2x1ZGVzKHguX2RlZi52YWx1ZSkgPyBhY2MgOiBbLi4uYWNjLCB4Ll9kZWYudmFsdWVdO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgW10gYXMgKHN0cmluZyB8IG51bWJlciB8IGJpZ2ludCB8IGJvb2xlYW4gfCBudWxsKVtdLFxuICAgICAgICApLFxuICAgICAgfTtcbiAgICB9XG4gIH0gZWxzZSBpZiAob3B0aW9ucy5ldmVyeSh4ID0+IHguX2RlZi50eXBlTmFtZSA9PT0gJ1pvZEVudW0nKSkge1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIGVudW06IG9wdGlvbnMucmVkdWNlKFxuICAgICAgICAoYWNjOiBzdHJpbmdbXSwgeCkgPT4gW1xuICAgICAgICAgIC4uLmFjYyxcbiAgICAgICAgICAuLi54Ll9kZWYudmFsdWVzLmZpbHRlcigoeDogc3RyaW5nKSA9PiAhYWNjLmluY2x1ZGVzKHgpKSxcbiAgICAgICAgXSxcbiAgICAgICAgW10sXG4gICAgICApLFxuICAgIH07XG4gIH1cblxuICByZXR1cm4gYXNBbnlPZihkZWYsIHJlZnMpO1xufVxuXG5jb25zdCBhc0FueU9mID0gKFxuICBkZWY6IFpvZFVuaW9uRGVmIHwgWm9kRGlzY3JpbWluYXRlZFVuaW9uRGVmPGFueSwgYW55PixcbiAgcmVmczogUmVmcyxcbik6IEpzb25TY2hlbWE3UHJpbWl0aXZlVW5pb25UeXBlIHwgSnNvblNjaGVtYTdBbnlPZlR5cGUgfCB1bmRlZmluZWQgPT4ge1xuICBjb25zdCBhbnlPZiA9IChcbiAgICAoZGVmLm9wdGlvbnMgaW5zdGFuY2VvZiBNYXBcbiAgICAgID8gQXJyYXkuZnJvbShkZWYub3B0aW9ucy52YWx1ZXMoKSlcbiAgICAgIDogZGVmLm9wdGlvbnMpIGFzIGFueVtdXG4gIClcbiAgICAubWFwKCh4LCBpKSA9PlxuICAgICAgcGFyc2VEZWYoeC5fZGVmLCB7XG4gICAgICAgIC4uLnJlZnMsXG4gICAgICAgIGN1cnJlbnRQYXRoOiBbLi4ucmVmcy5jdXJyZW50UGF0aCwgJ2FueU9mJywgYCR7aX1gXSxcbiAgICAgIH0pLFxuICAgIClcbiAgICAuZmlsdGVyKFxuICAgICAgKHgpOiB4IGlzIEpzb25TY2hlbWE3VHlwZSA9PlxuICAgICAgICAhIXggJiZcbiAgICAgICAgKCFyZWZzLnN0cmljdFVuaW9ucyB8fFxuICAgICAgICAgICh0eXBlb2YgeCA9PT0gJ29iamVjdCcgJiYgT2JqZWN0LmtleXMoeCkubGVuZ3RoID4gMCkpLFxuICAgICk7XG5cbiAgcmV0dXJuIGFueU9mLmxlbmd0aCA/IHsgYW55T2YgfSA6IHVuZGVmaW5lZDtcbn07XG4iLCAiaW1wb3J0IHsgWm9kTnVsbGFibGVEZWYgfSBmcm9tICd6b2QvdjMnO1xuaW1wb3J0IHsgcGFyc2VEZWYgfSBmcm9tICcuLi9wYXJzZS1kZWYnO1xuaW1wb3J0IHsgSnNvblNjaGVtYTdUeXBlIH0gZnJvbSAnLi4vcGFyc2UtdHlwZXMnO1xuaW1wb3J0IHsgUmVmcyB9IGZyb20gJy4uL3JlZnMnO1xuaW1wb3J0IHsgSnNvblNjaGVtYTdOdWxsVHlwZSB9IGZyb20gJy4vbnVsbCc7XG5pbXBvcnQgeyBwcmltaXRpdmVNYXBwaW5ncyB9IGZyb20gJy4vdW5pb24nO1xuXG5leHBvcnQgdHlwZSBKc29uU2NoZW1hN051bGxhYmxlVHlwZSA9XG4gIHwge1xuICAgICAgYW55T2Y6IFtKc29uU2NoZW1hN1R5cGUsIEpzb25TY2hlbWE3TnVsbFR5cGVdO1xuICAgIH1cbiAgfCB7XG4gICAgICB0eXBlOiBbc3RyaW5nLCAnbnVsbCddO1xuICAgIH07XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZU51bGxhYmxlRGVmKFxuICBkZWY6IFpvZE51bGxhYmxlRGVmLFxuICByZWZzOiBSZWZzLFxuKTogSnNvblNjaGVtYTdOdWxsYWJsZVR5cGUgfCB1bmRlZmluZWQge1xuICBpZiAoXG4gICAgWydab2RTdHJpbmcnLCAnWm9kTnVtYmVyJywgJ1pvZEJpZ0ludCcsICdab2RCb29sZWFuJywgJ1pvZE51bGwnXS5pbmNsdWRlcyhcbiAgICAgIGRlZi5pbm5lclR5cGUuX2RlZi50eXBlTmFtZSxcbiAgICApICYmXG4gICAgKCFkZWYuaW5uZXJUeXBlLl9kZWYuY2hlY2tzIHx8ICFkZWYuaW5uZXJUeXBlLl9kZWYuY2hlY2tzLmxlbmd0aClcbiAgKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IFtcbiAgICAgICAgcHJpbWl0aXZlTWFwcGluZ3NbXG4gICAgICAgICAgZGVmLmlubmVyVHlwZS5fZGVmLnR5cGVOYW1lIGFzIGtleW9mIHR5cGVvZiBwcmltaXRpdmVNYXBwaW5nc1xuICAgICAgICBdLFxuICAgICAgICAnbnVsbCcsXG4gICAgICBdLFxuICAgIH07XG4gIH1cblxuICBjb25zdCBiYXNlID0gcGFyc2VEZWYoZGVmLmlubmVyVHlwZS5fZGVmLCB7XG4gICAgLi4ucmVmcyxcbiAgICBjdXJyZW50UGF0aDogWy4uLnJlZnMuY3VycmVudFBhdGgsICdhbnlPZicsICcwJ10sXG4gIH0pO1xuXG4gIHJldHVybiBiYXNlICYmIHsgYW55T2Y6IFtiYXNlLCB7IHR5cGU6ICdudWxsJyB9XSB9O1xufVxuIiwgImltcG9ydCB7IFpvZE51bWJlckRlZiB9IGZyb20gJ3pvZC92Myc7XG5cbmV4cG9ydCB0eXBlIEpzb25TY2hlbWE3TnVtYmVyVHlwZSA9IHtcbiAgdHlwZTogJ251bWJlcicgfCAnaW50ZWdlcic7XG4gIG1pbmltdW0/OiBudW1iZXI7XG4gIGV4Y2x1c2l2ZU1pbmltdW0/OiBudW1iZXI7XG4gIG1heGltdW0/OiBudW1iZXI7XG4gIGV4Y2x1c2l2ZU1heGltdW0/OiBudW1iZXI7XG4gIG11bHRpcGxlT2Y/OiBudW1iZXI7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VOdW1iZXJEZWYoZGVmOiBab2ROdW1iZXJEZWYpOiBKc29uU2NoZW1hN051bWJlclR5cGUge1xuICBjb25zdCByZXM6IEpzb25TY2hlbWE3TnVtYmVyVHlwZSA9IHtcbiAgICB0eXBlOiAnbnVtYmVyJyxcbiAgfTtcblxuICBpZiAoIWRlZi5jaGVja3MpIHJldHVybiByZXM7XG5cbiAgZm9yIChjb25zdCBjaGVjayBvZiBkZWYuY2hlY2tzKSB7XG4gICAgc3dpdGNoIChjaGVjay5raW5kKSB7XG4gICAgICBjYXNlICdpbnQnOlxuICAgICAgICByZXMudHlwZSA9ICdpbnRlZ2VyJztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdtaW4nOlxuICAgICAgICBpZiAoY2hlY2suaW5jbHVzaXZlKSB7XG4gICAgICAgICAgcmVzLm1pbmltdW0gPSBjaGVjay52YWx1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXMuZXhjbHVzaXZlTWluaW11bSA9IGNoZWNrLnZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbWF4JzpcbiAgICAgICAgaWYgKGNoZWNrLmluY2x1c2l2ZSkge1xuICAgICAgICAgIHJlcy5tYXhpbXVtID0gY2hlY2sudmFsdWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzLmV4Y2x1c2l2ZU1heGltdW0gPSBjaGVjay52YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ211bHRpcGxlT2YnOlxuICAgICAgICByZXMubXVsdGlwbGVPZiA9IGNoZWNrLnZhbHVlO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cbiIsICJpbXBvcnQgeyBab2RPYmplY3REZWYsIFpvZFR5cGVBbnkgfSBmcm9tICd6b2QvdjMnO1xuaW1wb3J0IHsgcGFyc2VEZWYgfSBmcm9tICcuLi9wYXJzZS1kZWYnO1xuaW1wb3J0IHsgSnNvblNjaGVtYTdUeXBlIH0gZnJvbSAnLi4vcGFyc2UtdHlwZXMnO1xuaW1wb3J0IHsgUmVmcyB9IGZyb20gJy4uL3JlZnMnO1xuXG5leHBvcnQgdHlwZSBKc29uU2NoZW1hN09iamVjdFR5cGUgPSB7XG4gIHR5cGU6ICdvYmplY3QnO1xuICBwcm9wZXJ0aWVzOiBSZWNvcmQ8c3RyaW5nLCBKc29uU2NoZW1hN1R5cGU+O1xuICBhZGRpdGlvbmFsUHJvcGVydGllcz86IGJvb2xlYW4gfCBKc29uU2NoZW1hN1R5cGU7XG4gIHJlcXVpcmVkPzogc3RyaW5nW107XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VPYmplY3REZWYoZGVmOiBab2RPYmplY3REZWYsIHJlZnM6IFJlZnMpIHtcbiAgY29uc3QgcmVzdWx0OiBKc29uU2NoZW1hN09iamVjdFR5cGUgPSB7XG4gICAgdHlwZTogJ29iamVjdCcsXG4gICAgcHJvcGVydGllczoge30sXG4gIH07XG5cbiAgY29uc3QgcmVxdWlyZWQ6IHN0cmluZ1tdID0gW107XG5cbiAgY29uc3Qgc2hhcGUgPSBkZWYuc2hhcGUoKTtcblxuICBmb3IgKGNvbnN0IHByb3BOYW1lIGluIHNoYXBlKSB7XG4gICAgbGV0IHByb3BEZWYgPSBzaGFwZVtwcm9wTmFtZV07XG5cbiAgICBpZiAocHJvcERlZiA9PT0gdW5kZWZpbmVkIHx8IHByb3BEZWYuX2RlZiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBwcm9wT3B0aW9uYWwgPSBzYWZlSXNPcHRpb25hbChwcm9wRGVmKTtcblxuICAgIGNvbnN0IHBhcnNlZERlZiA9IHBhcnNlRGVmKHByb3BEZWYuX2RlZiwge1xuICAgICAgLi4ucmVmcyxcbiAgICAgIGN1cnJlbnRQYXRoOiBbLi4ucmVmcy5jdXJyZW50UGF0aCwgJ3Byb3BlcnRpZXMnLCBwcm9wTmFtZV0sXG4gICAgICBwcm9wZXJ0eVBhdGg6IFsuLi5yZWZzLmN1cnJlbnRQYXRoLCAncHJvcGVydGllcycsIHByb3BOYW1lXSxcbiAgICB9KTtcblxuICAgIGlmIChwYXJzZWREZWYgPT09IHVuZGVmaW5lZCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgcmVzdWx0LnByb3BlcnRpZXNbcHJvcE5hbWVdID0gcGFyc2VkRGVmO1xuXG4gICAgaWYgKCFwcm9wT3B0aW9uYWwpIHtcbiAgICAgIHJlcXVpcmVkLnB1c2gocHJvcE5hbWUpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChyZXF1aXJlZC5sZW5ndGgpIHtcbiAgICByZXN1bHQucmVxdWlyZWQgPSByZXF1aXJlZDtcbiAgfVxuXG4gIGNvbnN0IGFkZGl0aW9uYWxQcm9wZXJ0aWVzID0gZGVjaWRlQWRkaXRpb25hbFByb3BlcnRpZXMoZGVmLCByZWZzKTtcblxuICBpZiAoYWRkaXRpb25hbFByb3BlcnRpZXMgIT09IHVuZGVmaW5lZCkge1xuICAgIHJlc3VsdC5hZGRpdGlvbmFsUHJvcGVydGllcyA9IGFkZGl0aW9uYWxQcm9wZXJ0aWVzO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gZGVjaWRlQWRkaXRpb25hbFByb3BlcnRpZXMoZGVmOiBab2RPYmplY3REZWYsIHJlZnM6IFJlZnMpIHtcbiAgaWYgKGRlZi5jYXRjaGFsbC5fZGVmLnR5cGVOYW1lICE9PSAnWm9kTmV2ZXInKSB7XG4gICAgcmV0dXJuIHBhcnNlRGVmKGRlZi5jYXRjaGFsbC5fZGVmLCB7XG4gICAgICAuLi5yZWZzLFxuICAgICAgY3VycmVudFBhdGg6IFsuLi5yZWZzLmN1cnJlbnRQYXRoLCAnYWRkaXRpb25hbFByb3BlcnRpZXMnXSxcbiAgICB9KTtcbiAgfVxuXG4gIHN3aXRjaCAoZGVmLnVua25vd25LZXlzKSB7XG4gICAgY2FzZSAncGFzc3Rocm91Z2gnOlxuICAgICAgcmV0dXJuIHJlZnMuYWxsb3dlZEFkZGl0aW9uYWxQcm9wZXJ0aWVzO1xuICAgIGNhc2UgJ3N0cmljdCc6XG4gICAgICByZXR1cm4gcmVmcy5yZWplY3RlZEFkZGl0aW9uYWxQcm9wZXJ0aWVzO1xuICAgIGNhc2UgJ3N0cmlwJzpcbiAgICAgIHJldHVybiByZWZzLnJlbW92ZUFkZGl0aW9uYWxTdHJhdGVneSA9PT0gJ3N0cmljdCdcbiAgICAgICAgPyByZWZzLmFsbG93ZWRBZGRpdGlvbmFsUHJvcGVydGllc1xuICAgICAgICA6IHJlZnMucmVqZWN0ZWRBZGRpdGlvbmFsUHJvcGVydGllcztcbiAgfVxufVxuXG5mdW5jdGlvbiBzYWZlSXNPcHRpb25hbChzY2hlbWE6IFpvZFR5cGVBbnkpOiBib29sZWFuIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gc2NoZW1hLmlzT3B0aW9uYWwoKTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBab2RPcHRpb25hbERlZiB9IGZyb20gJ3pvZC92Myc7XG5pbXBvcnQgeyBwYXJzZURlZiB9IGZyb20gJy4uL3BhcnNlLWRlZic7XG5pbXBvcnQgeyBKc29uU2NoZW1hN1R5cGUgfSBmcm9tICcuLi9wYXJzZS10eXBlcyc7XG5pbXBvcnQgeyBSZWZzIH0gZnJvbSAnLi4vcmVmcyc7XG5pbXBvcnQgeyBwYXJzZUFueURlZiB9IGZyb20gJy4vYW55JztcblxuZXhwb3J0IGNvbnN0IHBhcnNlT3B0aW9uYWxEZWYgPSAoXG4gIGRlZjogWm9kT3B0aW9uYWxEZWYsXG4gIHJlZnM6IFJlZnMsXG4pOiBKc29uU2NoZW1hN1R5cGUgfCB1bmRlZmluZWQgPT4ge1xuICBpZiAocmVmcy5jdXJyZW50UGF0aC50b1N0cmluZygpID09PSByZWZzLnByb3BlcnR5UGF0aD8udG9TdHJpbmcoKSkge1xuICAgIHJldHVybiBwYXJzZURlZihkZWYuaW5uZXJUeXBlLl9kZWYsIHJlZnMpO1xuICB9XG5cbiAgY29uc3QgaW5uZXJTY2hlbWEgPSBwYXJzZURlZihkZWYuaW5uZXJUeXBlLl9kZWYsIHtcbiAgICAuLi5yZWZzLFxuICAgIGN1cnJlbnRQYXRoOiBbLi4ucmVmcy5jdXJyZW50UGF0aCwgJ2FueU9mJywgJzEnXSxcbiAgfSk7XG5cbiAgcmV0dXJuIGlubmVyU2NoZW1hXG4gICAgPyB7IGFueU9mOiBbeyBub3Q6IHBhcnNlQW55RGVmKCkgfSwgaW5uZXJTY2hlbWFdIH1cbiAgICA6IHBhcnNlQW55RGVmKCk7XG59O1xuIiwgImltcG9ydCB7IFpvZFBpcGVsaW5lRGVmIH0gZnJvbSAnem9kL3YzJztcbmltcG9ydCB7IHBhcnNlRGVmIH0gZnJvbSAnLi4vcGFyc2UtZGVmJztcbmltcG9ydCB7IEpzb25TY2hlbWE3VHlwZSB9IGZyb20gJy4uL3BhcnNlLXR5cGVzJztcbmltcG9ydCB7IFJlZnMgfSBmcm9tICcuLi9yZWZzJztcbmltcG9ydCB7IEpzb25TY2hlbWE3QWxsT2ZUeXBlIH0gZnJvbSAnLi9pbnRlcnNlY3Rpb24nO1xuXG5leHBvcnQgY29uc3QgcGFyc2VQaXBlbGluZURlZiA9IChcbiAgZGVmOiBab2RQaXBlbGluZURlZjxhbnksIGFueT4sXG4gIHJlZnM6IFJlZnMsXG4pOiBKc29uU2NoZW1hN0FsbE9mVHlwZSB8IEpzb25TY2hlbWE3VHlwZSB8IHVuZGVmaW5lZCA9PiB7XG4gIGlmIChyZWZzLnBpcGVTdHJhdGVneSA9PT0gJ2lucHV0Jykge1xuICAgIHJldHVybiBwYXJzZURlZihkZWYuaW4uX2RlZiwgcmVmcyk7XG4gIH0gZWxzZSBpZiAocmVmcy5waXBlU3RyYXRlZ3kgPT09ICdvdXRwdXQnKSB7XG4gICAgcmV0dXJuIHBhcnNlRGVmKGRlZi5vdXQuX2RlZiwgcmVmcyk7XG4gIH1cblxuICBjb25zdCBhID0gcGFyc2VEZWYoZGVmLmluLl9kZWYsIHtcbiAgICAuLi5yZWZzLFxuICAgIGN1cnJlbnRQYXRoOiBbLi4ucmVmcy5jdXJyZW50UGF0aCwgJ2FsbE9mJywgJzAnXSxcbiAgfSk7XG4gIGNvbnN0IGIgPSBwYXJzZURlZihkZWYub3V0Ll9kZWYsIHtcbiAgICAuLi5yZWZzLFxuICAgIGN1cnJlbnRQYXRoOiBbLi4ucmVmcy5jdXJyZW50UGF0aCwgJ2FsbE9mJywgYSA/ICcxJyA6ICcwJ10sXG4gIH0pO1xuXG4gIHJldHVybiB7XG4gICAgYWxsT2Y6IFthLCBiXS5maWx0ZXIoKHgpOiB4IGlzIEpzb25TY2hlbWE3VHlwZSA9PiB4ICE9PSB1bmRlZmluZWQpLFxuICB9O1xufTtcbiIsICJpbXBvcnQgeyBab2RQcm9taXNlRGVmIH0gZnJvbSAnem9kL3YzJztcbmltcG9ydCB7IHBhcnNlRGVmIH0gZnJvbSAnLi4vcGFyc2UtZGVmJztcbmltcG9ydCB7IEpzb25TY2hlbWE3VHlwZSB9IGZyb20gJy4uL3BhcnNlLXR5cGVzJztcbmltcG9ydCB7IFJlZnMgfSBmcm9tICcuLi9yZWZzJztcblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlUHJvbWlzZURlZihcbiAgZGVmOiBab2RQcm9taXNlRGVmLFxuICByZWZzOiBSZWZzLFxuKTogSnNvblNjaGVtYTdUeXBlIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIHBhcnNlRGVmKGRlZi50eXBlLl9kZWYsIHJlZnMpO1xufVxuIiwgImltcG9ydCB7IFpvZFNldERlZiB9IGZyb20gJ3pvZC92Myc7XG5pbXBvcnQgeyBwYXJzZURlZiB9IGZyb20gJy4uL3BhcnNlLWRlZic7XG5pbXBvcnQgeyBKc29uU2NoZW1hN1R5cGUgfSBmcm9tICcuLi9wYXJzZS10eXBlcyc7XG5pbXBvcnQgeyBSZWZzIH0gZnJvbSAnLi4vcmVmcyc7XG5cbmV4cG9ydCB0eXBlIEpzb25TY2hlbWE3U2V0VHlwZSA9IHtcbiAgdHlwZTogJ2FycmF5JztcbiAgdW5pcXVlSXRlbXM6IHRydWU7XG4gIGl0ZW1zPzogSnNvblNjaGVtYTdUeXBlO1xuICBtaW5JdGVtcz86IG51bWJlcjtcbiAgbWF4SXRlbXM/OiBudW1iZXI7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VTZXREZWYoZGVmOiBab2RTZXREZWYsIHJlZnM6IFJlZnMpOiBKc29uU2NoZW1hN1NldFR5cGUge1xuICBjb25zdCBpdGVtcyA9IHBhcnNlRGVmKGRlZi52YWx1ZVR5cGUuX2RlZiwge1xuICAgIC4uLnJlZnMsXG4gICAgY3VycmVudFBhdGg6IFsuLi5yZWZzLmN1cnJlbnRQYXRoLCAnaXRlbXMnXSxcbiAgfSk7XG5cbiAgY29uc3Qgc2NoZW1hOiBKc29uU2NoZW1hN1NldFR5cGUgPSB7XG4gICAgdHlwZTogJ2FycmF5JyxcbiAgICB1bmlxdWVJdGVtczogdHJ1ZSxcbiAgICBpdGVtcyxcbiAgfTtcblxuICBpZiAoZGVmLm1pblNpemUpIHtcbiAgICBzY2hlbWEubWluSXRlbXMgPSBkZWYubWluU2l6ZS52YWx1ZTtcbiAgfVxuXG4gIGlmIChkZWYubWF4U2l6ZSkge1xuICAgIHNjaGVtYS5tYXhJdGVtcyA9IGRlZi5tYXhTaXplLnZhbHVlO1xuICB9XG5cbiAgcmV0dXJuIHNjaGVtYTtcbn1cbiIsICJpbXBvcnQgeyBab2RUdXBsZURlZiwgWm9kVHVwbGVJdGVtcywgWm9kVHlwZUFueSB9IGZyb20gJ3pvZC92Myc7XG5pbXBvcnQgeyBwYXJzZURlZiB9IGZyb20gJy4uL3BhcnNlLWRlZic7XG5pbXBvcnQgeyBKc29uU2NoZW1hN1R5cGUgfSBmcm9tICcuLi9wYXJzZS10eXBlcyc7XG5pbXBvcnQgeyBSZWZzIH0gZnJvbSAnLi4vcmVmcyc7XG5cbmV4cG9ydCB0eXBlIEpzb25TY2hlbWE3VHVwbGVUeXBlID0ge1xuICB0eXBlOiAnYXJyYXknO1xuICBtaW5JdGVtczogbnVtYmVyO1xuICBpdGVtczogSnNvblNjaGVtYTdUeXBlW107XG59ICYgKFxuICB8IHtcbiAgICAgIG1heEl0ZW1zOiBudW1iZXI7XG4gICAgfVxuICB8IHtcbiAgICAgIGFkZGl0aW9uYWxJdGVtcz86IEpzb25TY2hlbWE3VHlwZTtcbiAgICB9XG4pO1xuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VUdXBsZURlZihcbiAgZGVmOiBab2RUdXBsZURlZjxab2RUdXBsZUl0ZW1zIHwgW10sIFpvZFR5cGVBbnkgfCBudWxsPixcbiAgcmVmczogUmVmcyxcbik6IEpzb25TY2hlbWE3VHVwbGVUeXBlIHtcbiAgaWYgKGRlZi5yZXN0KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdhcnJheScsXG4gICAgICBtaW5JdGVtczogZGVmLml0ZW1zLmxlbmd0aCxcbiAgICAgIGl0ZW1zOiBkZWYuaXRlbXNcbiAgICAgICAgLm1hcCgoeCwgaSkgPT5cbiAgICAgICAgICBwYXJzZURlZih4Ll9kZWYsIHtcbiAgICAgICAgICAgIC4uLnJlZnMsXG4gICAgICAgICAgICBjdXJyZW50UGF0aDogWy4uLnJlZnMuY3VycmVudFBhdGgsICdpdGVtcycsIGAke2l9YF0sXG4gICAgICAgICAgfSksXG4gICAgICAgIClcbiAgICAgICAgLnJlZHVjZShcbiAgICAgICAgICAoYWNjOiBKc29uU2NoZW1hN1R5cGVbXSwgeCkgPT4gKHggPT09IHVuZGVmaW5lZCA/IGFjYyA6IFsuLi5hY2MsIHhdKSxcbiAgICAgICAgICBbXSxcbiAgICAgICAgKSxcbiAgICAgIGFkZGl0aW9uYWxJdGVtczogcGFyc2VEZWYoZGVmLnJlc3QuX2RlZiwge1xuICAgICAgICAuLi5yZWZzLFxuICAgICAgICBjdXJyZW50UGF0aDogWy4uLnJlZnMuY3VycmVudFBhdGgsICdhZGRpdGlvbmFsSXRlbXMnXSxcbiAgICAgIH0pLFxuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdhcnJheScsXG4gICAgICBtaW5JdGVtczogZGVmLml0ZW1zLmxlbmd0aCxcbiAgICAgIG1heEl0ZW1zOiBkZWYuaXRlbXMubGVuZ3RoLFxuICAgICAgaXRlbXM6IGRlZi5pdGVtc1xuICAgICAgICAubWFwKCh4LCBpKSA9PlxuICAgICAgICAgIHBhcnNlRGVmKHguX2RlZiwge1xuICAgICAgICAgICAgLi4ucmVmcyxcbiAgICAgICAgICAgIGN1cnJlbnRQYXRoOiBbLi4ucmVmcy5jdXJyZW50UGF0aCwgJ2l0ZW1zJywgYCR7aX1gXSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKVxuICAgICAgICAucmVkdWNlKFxuICAgICAgICAgIChhY2M6IEpzb25TY2hlbWE3VHlwZVtdLCB4KSA9PiAoeCA9PT0gdW5kZWZpbmVkID8gYWNjIDogWy4uLmFjYywgeF0pLFxuICAgICAgICAgIFtdLFxuICAgICAgICApLFxuICAgIH07XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBKc29uU2NoZW1hN0FueVR5cGUsIHBhcnNlQW55RGVmIH0gZnJvbSAnLi9hbnknO1xuXG5leHBvcnQgdHlwZSBKc29uU2NoZW1hN1VuZGVmaW5lZFR5cGUgPSB7XG4gIG5vdDogSnNvblNjaGVtYTdBbnlUeXBlO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlVW5kZWZpbmVkRGVmKCk6IEpzb25TY2hlbWE3VW5kZWZpbmVkVHlwZSB7XG4gIHJldHVybiB7XG4gICAgbm90OiBwYXJzZUFueURlZigpLFxuICB9O1xufVxuIiwgImltcG9ydCB7IEpzb25TY2hlbWE3QW55VHlwZSwgcGFyc2VBbnlEZWYgfSBmcm9tICcuL2FueSc7XG5cbmV4cG9ydCB0eXBlIEpzb25TY2hlbWE3VW5rbm93blR5cGUgPSBKc29uU2NoZW1hN0FueVR5cGU7XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVVua25vd25EZWYoKTogSnNvblNjaGVtYTdVbmtub3duVHlwZSB7XG4gIHJldHVybiBwYXJzZUFueURlZigpO1xufVxuIiwgImltcG9ydCB7IFpvZFJlYWRvbmx5RGVmIH0gZnJvbSAnem9kL3YzJztcbmltcG9ydCB7IHBhcnNlRGVmIH0gZnJvbSAnLi4vcGFyc2UtZGVmJztcbmltcG9ydCB7IFJlZnMgfSBmcm9tICcuLi9yZWZzJztcblxuZXhwb3J0IGNvbnN0IHBhcnNlUmVhZG9ubHlEZWYgPSAoZGVmOiBab2RSZWFkb25seURlZjxhbnk+LCByZWZzOiBSZWZzKSA9PiB7XG4gIHJldHVybiBwYXJzZURlZihkZWYuaW5uZXJUeXBlLl9kZWYsIHJlZnMpO1xufTtcbiIsICJpbXBvcnQgeyBab2RUeXBlRGVmIH0gZnJvbSAnem9kL3YzJztcbmltcG9ydCB7IFJlZnMsIFNlZW4gfSBmcm9tICcuL3JlZnMnO1xuaW1wb3J0IHsgaWdub3JlT3ZlcnJpZGUgfSBmcm9tICcuL29wdGlvbnMnO1xuaW1wb3J0IHsgSnNvblNjaGVtYTdUeXBlIH0gZnJvbSAnLi9wYXJzZS10eXBlcyc7XG5pbXBvcnQgeyBzZWxlY3RQYXJzZXIgfSBmcm9tICcuL3NlbGVjdC1wYXJzZXInO1xuaW1wb3J0IHsgZ2V0UmVsYXRpdmVQYXRoIH0gZnJvbSAnLi9nZXQtcmVsYXRpdmUtcGF0aCc7XG5pbXBvcnQgeyBwYXJzZUFueURlZiB9IGZyb20gJy4vcGFyc2Vycy9hbnknO1xuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VEZWYoXG4gIGRlZjogWm9kVHlwZURlZixcbiAgcmVmczogUmVmcyxcbiAgZm9yY2VSZXNvbHV0aW9uID0gZmFsc2UsIC8vIEZvcmNlcyBhIG5ldyBzY2hlbWEgdG8gYmUgaW5zdGFudGlhdGVkIGV2ZW4gdGhvdWdoIGl0cyBkZWYgaGFzIGJlZW4gc2Vlbi4gVXNlZCBmb3IgaW1wcm92aW5nIHJlZnMgaW4gZGVmaW5pdGlvbnMuIFNlZSBodHRwczovL2dpdGh1Yi5jb20vU3RlZmFuVGVyZGVsbC96b2QtdG8tanNvbi1zY2hlbWEvcHVsbC82MS5cbik6IEpzb25TY2hlbWE3VHlwZSB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHNlZW5JdGVtID0gcmVmcy5zZWVuLmdldChkZWYpO1xuXG4gIGlmIChyZWZzLm92ZXJyaWRlKSB7XG4gICAgY29uc3Qgb3ZlcnJpZGVSZXN1bHQgPSByZWZzLm92ZXJyaWRlPy4oXG4gICAgICBkZWYsXG4gICAgICByZWZzLFxuICAgICAgc2Vlbkl0ZW0sXG4gICAgICBmb3JjZVJlc29sdXRpb24sXG4gICAgKTtcblxuICAgIGlmIChvdmVycmlkZVJlc3VsdCAhPT0gaWdub3JlT3ZlcnJpZGUpIHtcbiAgICAgIHJldHVybiBvdmVycmlkZVJlc3VsdDtcbiAgICB9XG4gIH1cblxuICBpZiAoc2Vlbkl0ZW0gJiYgIWZvcmNlUmVzb2x1dGlvbikge1xuICAgIGNvbnN0IHNlZW5TY2hlbWEgPSBnZXQkcmVmKHNlZW5JdGVtLCByZWZzKTtcblxuICAgIGlmIChzZWVuU2NoZW1hICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBzZWVuU2NoZW1hO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IG5ld0l0ZW06IFNlZW4gPSB7IGRlZiwgcGF0aDogcmVmcy5jdXJyZW50UGF0aCwganNvblNjaGVtYTogdW5kZWZpbmVkIH07XG5cbiAgcmVmcy5zZWVuLnNldChkZWYsIG5ld0l0ZW0pO1xuXG4gIGNvbnN0IGpzb25TY2hlbWFPckdldHRlciA9IHNlbGVjdFBhcnNlcihkZWYsIChkZWYgYXMgYW55KS50eXBlTmFtZSwgcmVmcyk7XG5cbiAgLy8gSWYgdGhlIHJldHVybiB3YXMgYSBmdW5jdGlvbiwgdGhlbiB0aGUgaW5uZXIgZGVmaW5pdGlvbiBuZWVkcyB0byBiZSBleHRyYWN0ZWQgYmVmb3JlIGEgY2FsbCB0byBwYXJzZURlZiAocmVjdXJzaXZlKVxuICBjb25zdCBqc29uU2NoZW1hID1cbiAgICB0eXBlb2YganNvblNjaGVtYU9yR2V0dGVyID09PSAnZnVuY3Rpb24nXG4gICAgICA/IHBhcnNlRGVmKGpzb25TY2hlbWFPckdldHRlcigpLCByZWZzKVxuICAgICAgOiBqc29uU2NoZW1hT3JHZXR0ZXI7XG5cbiAgaWYgKGpzb25TY2hlbWEpIHtcbiAgICBhZGRNZXRhKGRlZiwgcmVmcywganNvblNjaGVtYSk7XG4gIH1cblxuICBpZiAocmVmcy5wb3N0UHJvY2Vzcykge1xuICAgIGNvbnN0IHBvc3RQcm9jZXNzUmVzdWx0ID0gcmVmcy5wb3N0UHJvY2Vzcyhqc29uU2NoZW1hLCBkZWYsIHJlZnMpO1xuXG4gICAgbmV3SXRlbS5qc29uU2NoZW1hID0ganNvblNjaGVtYTtcblxuICAgIHJldHVybiBwb3N0UHJvY2Vzc1Jlc3VsdDtcbiAgfVxuXG4gIG5ld0l0ZW0uanNvblNjaGVtYSA9IGpzb25TY2hlbWE7XG5cbiAgcmV0dXJuIGpzb25TY2hlbWE7XG59XG5cbmNvbnN0IGdldCRyZWYgPSAoXG4gIGl0ZW06IFNlZW4sXG4gIHJlZnM6IFJlZnMsXG4pOlxuICB8IHtcbiAgICAgICRyZWY6IHN0cmluZztcbiAgICB9XG4gIHwge31cbiAgfCB1bmRlZmluZWQgPT4ge1xuICBzd2l0Y2ggKHJlZnMuJHJlZlN0cmF0ZWd5KSB7XG4gICAgY2FzZSAncm9vdCc6XG4gICAgICByZXR1cm4geyAkcmVmOiBpdGVtLnBhdGguam9pbignLycpIH07XG4gICAgY2FzZSAncmVsYXRpdmUnOlxuICAgICAgcmV0dXJuIHsgJHJlZjogZ2V0UmVsYXRpdmVQYXRoKHJlZnMuY3VycmVudFBhdGgsIGl0ZW0ucGF0aCkgfTtcbiAgICBjYXNlICdub25lJzpcbiAgICBjYXNlICdzZWVuJzoge1xuICAgICAgaWYgKFxuICAgICAgICBpdGVtLnBhdGgubGVuZ3RoIDwgcmVmcy5jdXJyZW50UGF0aC5sZW5ndGggJiZcbiAgICAgICAgaXRlbS5wYXRoLmV2ZXJ5KCh2YWx1ZSwgaW5kZXgpID0+IHJlZnMuY3VycmVudFBhdGhbaW5kZXhdID09PSB2YWx1ZSlcbiAgICAgICkge1xuICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgYFJlY3Vyc2l2ZSByZWZlcmVuY2UgZGV0ZWN0ZWQgYXQgJHtyZWZzLmN1cnJlbnRQYXRoLmpvaW4oXG4gICAgICAgICAgICAnLycsXG4gICAgICAgICAgKX0hIERlZmF1bHRpbmcgdG8gYW55YCxcbiAgICAgICAgKTtcblxuICAgICAgICByZXR1cm4gcGFyc2VBbnlEZWYoKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlZnMuJHJlZlN0cmF0ZWd5ID09PSAnc2VlbicgPyBwYXJzZUFueURlZigpIDogdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxufTtcblxuY29uc3QgYWRkTWV0YSA9IChcbiAgZGVmOiBab2RUeXBlRGVmLFxuICByZWZzOiBSZWZzLFxuICBqc29uU2NoZW1hOiBKc29uU2NoZW1hN1R5cGUsXG4pOiBKc29uU2NoZW1hN1R5cGUgPT4ge1xuICBpZiAoZGVmLmRlc2NyaXB0aW9uKSB7XG4gICAganNvblNjaGVtYS5kZXNjcmlwdGlvbiA9IGRlZi5kZXNjcmlwdGlvbjtcbiAgfVxuICByZXR1cm4ganNvblNjaGVtYTtcbn07XG4iLCAiaW1wb3J0IHsgWm9kVHlwZURlZiB9IGZyb20gJ3pvZC92Myc7XG5pbXBvcnQgeyBnZXREZWZhdWx0T3B0aW9ucywgT3B0aW9ucyB9IGZyb20gJy4vb3B0aW9ucyc7XG5pbXBvcnQgeyBKc29uU2NoZW1hN1R5cGUgfSBmcm9tICcuL3BhcnNlLXR5cGVzJztcblxuZXhwb3J0IHR5cGUgUmVmcyA9IHtcbiAgc2VlbjogTWFwPFpvZFR5cGVEZWYsIFNlZW4+O1xuICBjdXJyZW50UGF0aDogc3RyaW5nW107XG4gIHByb3BlcnR5UGF0aDogc3RyaW5nW10gfCB1bmRlZmluZWQ7XG59ICYgT3B0aW9ucztcblxuZXhwb3J0IHR5cGUgU2VlbiA9IHtcbiAgZGVmOiBab2RUeXBlRGVmO1xuICBwYXRoOiBzdHJpbmdbXTtcbiAganNvblNjaGVtYTogSnNvblNjaGVtYTdUeXBlIHwgdW5kZWZpbmVkO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldFJlZnMgPSAob3B0aW9ucz86IHN0cmluZyB8IFBhcnRpYWw8T3B0aW9ucz4pOiBSZWZzID0+IHtcbiAgY29uc3QgX29wdGlvbnMgPSBnZXREZWZhdWx0T3B0aW9ucyhvcHRpb25zKTtcbiAgY29uc3QgY3VycmVudFBhdGggPVxuICAgIF9vcHRpb25zLm5hbWUgIT09IHVuZGVmaW5lZFxuICAgICAgPyBbLi4uX29wdGlvbnMuYmFzZVBhdGgsIF9vcHRpb25zLmRlZmluaXRpb25QYXRoLCBfb3B0aW9ucy5uYW1lXVxuICAgICAgOiBfb3B0aW9ucy5iYXNlUGF0aDtcbiAgcmV0dXJuIHtcbiAgICAuLi5fb3B0aW9ucyxcbiAgICBjdXJyZW50UGF0aDogY3VycmVudFBhdGgsXG4gICAgcHJvcGVydHlQYXRoOiB1bmRlZmluZWQsXG4gICAgc2VlbjogbmV3IE1hcChcbiAgICAgIE9iamVjdC5lbnRyaWVzKF9vcHRpb25zLmRlZmluaXRpb25zKS5tYXAoKFtuYW1lLCBkZWZdKSA9PiBbXG4gICAgICAgIGRlZi5fZGVmLFxuICAgICAgICB7XG4gICAgICAgICAgZGVmOiBkZWYuX2RlZixcbiAgICAgICAgICBwYXRoOiBbLi4uX29wdGlvbnMuYmFzZVBhdGgsIF9vcHRpb25zLmRlZmluaXRpb25QYXRoLCBuYW1lXSxcbiAgICAgICAgICAvLyBSZXNvbHV0aW9uIG9mIHJlZmVyZW5jZXMgd2lsbCBiZSBmb3JjZWQgZXZlbiB0aG91Z2ggc2Vlbiwgc28gaXQncyBvayB0aGF0IHRoZSBzY2hlbWEgaXMgdW5kZWZpbmVkIGhlcmUgZm9yIG5vdy5cbiAgICAgICAgICBqc29uU2NoZW1hOiB1bmRlZmluZWQsXG4gICAgICAgIH0sXG4gICAgICBdKSxcbiAgICApLFxuICB9O1xufTtcbiIsICJpbXBvcnQgeyBab2RTY2hlbWEgfSBmcm9tICd6b2QvdjMnO1xuaW1wb3J0IHsgT3B0aW9ucyB9IGZyb20gJy4vb3B0aW9ucyc7XG5pbXBvcnQgeyBwYXJzZURlZiB9IGZyb20gJy4vcGFyc2UtZGVmJztcbmltcG9ydCB7IEpzb25TY2hlbWE3VHlwZSB9IGZyb20gJy4vcGFyc2UtdHlwZXMnO1xuaW1wb3J0IHsgZ2V0UmVmcyB9IGZyb20gJy4vcmVmcyc7XG5pbXBvcnQgeyBwYXJzZUFueURlZiB9IGZyb20gJy4vcGFyc2Vycy9hbnknO1xuXG5jb25zdCB6b2RUb0pzb25TY2hlbWEgPSAoXG4gIHNjaGVtYTogWm9kU2NoZW1hPGFueT4sXG4gIG9wdGlvbnM/OiBQYXJ0aWFsPE9wdGlvbnM+IHwgc3RyaW5nLFxuKTogSnNvblNjaGVtYTdUeXBlICYge1xuICAkc2NoZW1hPzogc3RyaW5nO1xuICBkZWZpbml0aW9ucz86IHtcbiAgICBba2V5OiBzdHJpbmddOiBKc29uU2NoZW1hN1R5cGU7XG4gIH07XG59ID0+IHtcbiAgY29uc3QgcmVmcyA9IGdldFJlZnMob3B0aW9ucyk7XG5cbiAgbGV0IGRlZmluaXRpb25zID1cbiAgICB0eXBlb2Ygb3B0aW9ucyA9PT0gJ29iamVjdCcgJiYgb3B0aW9ucy5kZWZpbml0aW9uc1xuICAgICAgPyBPYmplY3QuZW50cmllcyhvcHRpb25zLmRlZmluaXRpb25zKS5yZWR1Y2UoXG4gICAgICAgICAgKGFjYzogeyBba2V5OiBzdHJpbmddOiBKc29uU2NoZW1hN1R5cGUgfSwgW25hbWUsIHNjaGVtYV0pID0+ICh7XG4gICAgICAgICAgICAuLi5hY2MsXG4gICAgICAgICAgICBbbmFtZV06XG4gICAgICAgICAgICAgIHBhcnNlRGVmKFxuICAgICAgICAgICAgICAgIHNjaGVtYS5fZGVmLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIC4uLnJlZnMsXG4gICAgICAgICAgICAgICAgICBjdXJyZW50UGF0aDogWy4uLnJlZnMuYmFzZVBhdGgsIHJlZnMuZGVmaW5pdGlvblBhdGgsIG5hbWVdLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdHJ1ZSxcbiAgICAgICAgICAgICAgKSA/PyBwYXJzZUFueURlZigpLFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIHt9LFxuICAgICAgICApXG4gICAgICA6IHVuZGVmaW5lZDtcblxuICBjb25zdCBuYW1lID1cbiAgICB0eXBlb2Ygb3B0aW9ucyA9PT0gJ3N0cmluZydcbiAgICAgID8gb3B0aW9uc1xuICAgICAgOiBvcHRpb25zPy5uYW1lU3RyYXRlZ3kgPT09ICd0aXRsZSdcbiAgICAgICAgPyB1bmRlZmluZWRcbiAgICAgICAgOiBvcHRpb25zPy5uYW1lO1xuXG4gIGNvbnN0IG1haW4gPVxuICAgIHBhcnNlRGVmKFxuICAgICAgc2NoZW1hLl9kZWYsXG4gICAgICBuYW1lID09PSB1bmRlZmluZWRcbiAgICAgICAgPyByZWZzXG4gICAgICAgIDoge1xuICAgICAgICAgICAgLi4ucmVmcyxcbiAgICAgICAgICAgIGN1cnJlbnRQYXRoOiBbLi4ucmVmcy5iYXNlUGF0aCwgcmVmcy5kZWZpbml0aW9uUGF0aCwgbmFtZV0sXG4gICAgICAgICAgfSxcbiAgICAgIGZhbHNlLFxuICAgICkgPz8gKHBhcnNlQW55RGVmKCkgYXMgSnNvblNjaGVtYTdUeXBlKTtcblxuICBjb25zdCB0aXRsZSA9XG4gICAgdHlwZW9mIG9wdGlvbnMgPT09ICdvYmplY3QnICYmXG4gICAgb3B0aW9ucy5uYW1lICE9PSB1bmRlZmluZWQgJiZcbiAgICBvcHRpb25zLm5hbWVTdHJhdGVneSA9PT0gJ3RpdGxlJ1xuICAgICAgPyBvcHRpb25zLm5hbWVcbiAgICAgIDogdW5kZWZpbmVkO1xuXG4gIGlmICh0aXRsZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgbWFpbi50aXRsZSA9IHRpdGxlO1xuICB9XG5cbiAgY29uc3QgY29tYmluZWQ6IFJldHVyblR5cGU8dHlwZW9mIHpvZFRvSnNvblNjaGVtYT4gPVxuICAgIG5hbWUgPT09IHVuZGVmaW5lZFxuICAgICAgPyBkZWZpbml0aW9uc1xuICAgICAgICA/IHtcbiAgICAgICAgICAgIC4uLm1haW4sXG4gICAgICAgICAgICBbcmVmcy5kZWZpbml0aW9uUGF0aF06IGRlZmluaXRpb25zLFxuICAgICAgICAgIH1cbiAgICAgICAgOiBtYWluXG4gICAgICA6IHtcbiAgICAgICAgICAkcmVmOiBbXG4gICAgICAgICAgICAuLi4ocmVmcy4kcmVmU3RyYXRlZ3kgPT09ICdyZWxhdGl2ZScgPyBbXSA6IHJlZnMuYmFzZVBhdGgpLFxuICAgICAgICAgICAgcmVmcy5kZWZpbml0aW9uUGF0aCxcbiAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgXS5qb2luKCcvJyksXG4gICAgICAgICAgW3JlZnMuZGVmaW5pdGlvblBhdGhdOiB7XG4gICAgICAgICAgICAuLi5kZWZpbml0aW9ucyxcbiAgICAgICAgICAgIFtuYW1lXTogbWFpbixcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuXG4gIGNvbWJpbmVkLiRzY2hlbWEgPSAnaHR0cDovL2pzb24tc2NoZW1hLm9yZy9kcmFmdC0wNy9zY2hlbWEjJztcblxuICByZXR1cm4gY29tYmluZWQ7XG59O1xuXG5leHBvcnQgeyB6b2RUb0pzb25TY2hlbWEgfTtcbiIsICJleHBvcnQgKiBmcm9tICcuL2dldC1yZWxhdGl2ZS1wYXRoJztcbmV4cG9ydCAqIGZyb20gJy4vb3B0aW9ucyc7XG5leHBvcnQgKiBmcm9tICcuL3BhcnNlLWRlZic7XG5leHBvcnQgKiBmcm9tICcuL3BhcnNlLXR5cGVzJztcbmV4cG9ydCAqIGZyb20gJy4vcGFyc2Vycy9hbnknO1xuZXhwb3J0ICogZnJvbSAnLi9wYXJzZXJzL2FycmF5JztcbmV4cG9ydCAqIGZyb20gJy4vcGFyc2Vycy9iaWdpbnQnO1xuZXhwb3J0ICogZnJvbSAnLi9wYXJzZXJzL2Jvb2xlYW4nO1xuZXhwb3J0ICogZnJvbSAnLi9wYXJzZXJzL2JyYW5kZWQnO1xuZXhwb3J0ICogZnJvbSAnLi9wYXJzZXJzL2NhdGNoJztcbmV4cG9ydCAqIGZyb20gJy4vcGFyc2Vycy9kYXRlJztcbmV4cG9ydCAqIGZyb20gJy4vcGFyc2Vycy9kZWZhdWx0JztcbmV4cG9ydCAqIGZyb20gJy4vcGFyc2Vycy9lZmZlY3RzJztcbmV4cG9ydCAqIGZyb20gJy4vcGFyc2Vycy9lbnVtJztcbmV4cG9ydCAqIGZyb20gJy4vcGFyc2Vycy9pbnRlcnNlY3Rpb24nO1xuZXhwb3J0ICogZnJvbSAnLi9wYXJzZXJzL2xpdGVyYWwnO1xuZXhwb3J0ICogZnJvbSAnLi9wYXJzZXJzL21hcCc7XG5leHBvcnQgKiBmcm9tICcuL3BhcnNlcnMvbmF0aXZlLWVudW0nO1xuZXhwb3J0ICogZnJvbSAnLi9wYXJzZXJzL25ldmVyJztcbmV4cG9ydCAqIGZyb20gJy4vcGFyc2Vycy9udWxsJztcbmV4cG9ydCAqIGZyb20gJy4vcGFyc2Vycy9udWxsYWJsZSc7XG5leHBvcnQgKiBmcm9tICcuL3BhcnNlcnMvbnVtYmVyJztcbmV4cG9ydCAqIGZyb20gJy4vcGFyc2Vycy9vYmplY3QnO1xuZXhwb3J0ICogZnJvbSAnLi9wYXJzZXJzL29wdGlvbmFsJztcbmV4cG9ydCAqIGZyb20gJy4vcGFyc2Vycy9waXBlbGluZSc7XG5leHBvcnQgKiBmcm9tICcuL3BhcnNlcnMvcHJvbWlzZSc7XG5leHBvcnQgKiBmcm9tICcuL3BhcnNlcnMvcmVhZG9ubHknO1xuZXhwb3J0ICogZnJvbSAnLi9wYXJzZXJzL3JlY29yZCc7XG5leHBvcnQgKiBmcm9tICcuL3BhcnNlcnMvc2V0JztcbmV4cG9ydCAqIGZyb20gJy4vcGFyc2Vycy9zdHJpbmcnO1xuZXhwb3J0ICogZnJvbSAnLi9wYXJzZXJzL3R1cGxlJztcbmV4cG9ydCAqIGZyb20gJy4vcGFyc2Vycy91bmRlZmluZWQnO1xuZXhwb3J0ICogZnJvbSAnLi9wYXJzZXJzL3VuaW9uJztcbmV4cG9ydCAqIGZyb20gJy4vcGFyc2Vycy91bmtub3duJztcbmV4cG9ydCAqIGZyb20gJy4vcmVmcyc7XG5leHBvcnQgKiBmcm9tICcuL3NlbGVjdC1wYXJzZXInO1xuZXhwb3J0ICogZnJvbSAnLi96b2QtdG8tanNvbi1zY2hlbWEnO1xuaW1wb3J0IHsgem9kVG9Kc29uU2NoZW1hIH0gZnJvbSAnLi96b2QtdG8tanNvbi1zY2hlbWEnO1xuZXhwb3J0IGRlZmF1bHQgem9kVG9Kc29uU2NoZW1hO1xuIiwgImltcG9ydCB7IEpTT05TY2hlbWE3IH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQgKiBhcyB6MyBmcm9tICd6b2QvdjMnO1xuaW1wb3J0ICogYXMgejQgZnJvbSAnem9kL3Y0JztcbmltcG9ydCB7IFZhbGlkYXRvciwgdmFsaWRhdG9yU3ltYm9sLCB0eXBlIFZhbGlkYXRpb25SZXN1bHQgfSBmcm9tICcuL3ZhbGlkYXRvcic7XG5pbXBvcnQgeyB6b2RTY2hlbWEgfSBmcm9tICcuL3pvZC1zY2hlbWEnO1xuXG4vKipcbiAqIFVzZWQgdG8gbWFyayBzY2hlbWFzIHNvIHdlIGNhbiBzdXBwb3J0IGJvdGggWm9kIGFuZCBjdXN0b20gc2NoZW1hcy5cbiAqL1xuY29uc3Qgc2NoZW1hU3ltYm9sID0gU3ltYm9sLmZvcigndmVyY2VsLmFpLnNjaGVtYScpO1xuXG5leHBvcnQgdHlwZSBTY2hlbWE8T0JKRUNUID0gdW5rbm93bj4gPSBWYWxpZGF0b3I8T0JKRUNUPiAmIHtcbiAgLyoqXG4gICAqIFVzZWQgdG8gbWFyayBzY2hlbWFzIHNvIHdlIGNhbiBzdXBwb3J0IGJvdGggWm9kIGFuZCBjdXN0b20gc2NoZW1hcy5cbiAgICovXG4gIFtzY2hlbWFTeW1ib2xdOiB0cnVlO1xuXG4gIC8qKlxuICAgKiBTY2hlbWEgdHlwZSBmb3IgaW5mZXJlbmNlLlxuICAgKi9cbiAgX3R5cGU6IE9CSkVDVDtcblxuICAvKipcbiAgICogVGhlIEpTT04gU2NoZW1hIGZvciB0aGUgc2NoZW1hLiBJdCBpcyBwYXNzZWQgdG8gdGhlIHByb3ZpZGVycy5cbiAgICovXG4gIHJlYWRvbmx5IGpzb25TY2hlbWE6IEpTT05TY2hlbWE3O1xufTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgc2NoZW1hIHdpdGggZGVmZXJyZWQgY3JlYXRpb24uXG4gKiBUaGlzIGlzIGltcG9ydGFudCB0byByZWR1Y2UgdGhlIHN0YXJ0dXAgdGltZSBvZiB0aGUgbGlicmFyeVxuICogYW5kIHRvIGF2b2lkIGluaXRpYWxpemluZyB1bnVzZWQgdmFsaWRhdG9ycy5cbiAqXG4gKiBAcGFyYW0gY3JlYXRlVmFsaWRhdG9yIEEgZnVuY3Rpb24gdGhhdCBjcmVhdGVzIGEgc2NoZW1hLlxuICogQHJldHVybnMgQSBmdW5jdGlvbiB0aGF0IHJldHVybnMgYSBzY2hlbWEuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsYXp5U2NoZW1hPFNDSEVNQT4oXG4gIGNyZWF0ZVNjaGVtYTogKCkgPT4gU2NoZW1hPFNDSEVNQT4sXG4pOiBMYXp5U2NoZW1hPFNDSEVNQT4ge1xuICAvLyBjYWNoZSB0aGUgdmFsaWRhdG9yIHRvIGF2b2lkIGluaXRpYWxpemluZyBpdCBtdWx0aXBsZSB0aW1lc1xuICBsZXQgc2NoZW1hOiBTY2hlbWE8U0NIRU1BPiB8IHVuZGVmaW5lZDtcbiAgcmV0dXJuICgpID0+IHtcbiAgICBpZiAoc2NoZW1hID09IG51bGwpIHtcbiAgICAgIHNjaGVtYSA9IGNyZWF0ZVNjaGVtYSgpO1xuICAgIH1cbiAgICByZXR1cm4gc2NoZW1hO1xuICB9O1xufVxuXG5leHBvcnQgdHlwZSBMYXp5U2NoZW1hPFNDSEVNQT4gPSAoKSA9PiBTY2hlbWE8U0NIRU1BPjtcblxuLy8gTm90ZTogWm9kIHR5cGVzIGhlcmUgZXhhY3RseSBtYXRjaCB0aGUgdHlwZXMgaW4gem9kLXNjaGVtYS50c1xuLy8gdG8gcHJldmVudCB0eXBlIGVycm9ycyB3aGVuIHVzaW5nIHpvZCBzY2hlbWFzIHdpdGggZmxleGlibGUgc2NoZW1hcy5cbmV4cG9ydCB0eXBlIEZsZXhpYmxlU2NoZW1hPFNDSEVNQT4gPVxuICB8IHo0LmNvcmUuJFpvZFR5cGU8U0NIRU1BLCBhbnk+XG4gIHwgejMuU2NoZW1hPFNDSEVNQSwgejMuWm9kVHlwZURlZiwgYW55PlxuICB8IFNjaGVtYTxTQ0hFTUE+XG4gIHwgTGF6eVNjaGVtYTxTQ0hFTUE+O1xuXG5leHBvcnQgdHlwZSBJbmZlclNjaGVtYTxTQ0hFTUE+ID0gU0NIRU1BIGV4dGVuZHMgejMuU2NoZW1hXG4gID8gejMuaW5mZXI8U0NIRU1BPlxuICA6IFNDSEVNQSBleHRlbmRzIHo0LmNvcmUuJFpvZFR5cGVcbiAgICA/IHo0LmluZmVyPFNDSEVNQT5cbiAgICA6IFNDSEVNQSBleHRlbmRzIExhenlTY2hlbWE8aW5mZXIgVD5cbiAgICAgID8gVFxuICAgICAgOiBTQ0hFTUEgZXh0ZW5kcyBTY2hlbWE8aW5mZXIgVD5cbiAgICAgICAgPyBUXG4gICAgICAgIDogbmV2ZXI7XG5cbi8qKlxuICogQ3JlYXRlIGEgc2NoZW1hIHVzaW5nIGEgSlNPTiBTY2hlbWEuXG4gKlxuICogQHBhcmFtIGpzb25TY2hlbWEgVGhlIEpTT04gU2NoZW1hIGZvciB0aGUgc2NoZW1hLlxuICogQHBhcmFtIG9wdGlvbnMudmFsaWRhdGUgT3B0aW9uYWwuIEEgdmFsaWRhdGlvbiBmdW5jdGlvbiBmb3IgdGhlIHNjaGVtYS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGpzb25TY2hlbWE8T0JKRUNUID0gdW5rbm93bj4oXG4gIGpzb25TY2hlbWE6IEpTT05TY2hlbWE3IHwgKCgpID0+IEpTT05TY2hlbWE3KSxcbiAge1xuICAgIHZhbGlkYXRlLFxuICB9OiB7XG4gICAgdmFsaWRhdGU/OiAoXG4gICAgICB2YWx1ZTogdW5rbm93bixcbiAgICApID0+IFZhbGlkYXRpb25SZXN1bHQ8T0JKRUNUPiB8IFByb21pc2VMaWtlPFZhbGlkYXRpb25SZXN1bHQ8T0JKRUNUPj47XG4gIH0gPSB7fSxcbik6IFNjaGVtYTxPQkpFQ1Q+IHtcbiAgcmV0dXJuIHtcbiAgICBbc2NoZW1hU3ltYm9sXTogdHJ1ZSxcbiAgICBfdHlwZTogdW5kZWZpbmVkIGFzIE9CSkVDVCwgLy8gc2hvdWxkIG5ldmVyIGJlIHVzZWQgZGlyZWN0bHlcbiAgICBbdmFsaWRhdG9yU3ltYm9sXTogdHJ1ZSxcbiAgICBnZXQganNvblNjaGVtYSgpIHtcbiAgICAgIGlmICh0eXBlb2YganNvblNjaGVtYSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBqc29uU2NoZW1hID0ganNvblNjaGVtYSgpOyAvLyBjYWNoZSB0aGUgZnVuY3Rpb24gcmVzdWx0c1xuICAgICAgfVxuICAgICAgcmV0dXJuIGpzb25TY2hlbWE7XG4gICAgfSxcbiAgICB2YWxpZGF0ZSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gaXNTY2hlbWEodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBTY2hlbWEge1xuICByZXR1cm4gKFxuICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiZcbiAgICB2YWx1ZSAhPT0gbnVsbCAmJlxuICAgIHNjaGVtYVN5bWJvbCBpbiB2YWx1ZSAmJlxuICAgIHZhbHVlW3NjaGVtYVN5bWJvbF0gPT09IHRydWUgJiZcbiAgICAnanNvblNjaGVtYScgaW4gdmFsdWUgJiZcbiAgICAndmFsaWRhdGUnIGluIHZhbHVlXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhc1NjaGVtYTxPQkpFQ1Q+KFxuICBzY2hlbWE6IEZsZXhpYmxlU2NoZW1hPE9CSkVDVD4gfCB1bmRlZmluZWQsXG4pOiBTY2hlbWE8T0JKRUNUPiB7XG4gIHJldHVybiBzY2hlbWEgPT0gbnVsbFxuICAgID8ganNvblNjaGVtYSh7XG4gICAgICAgIHByb3BlcnRpZXM6IHt9LFxuICAgICAgICBhZGRpdGlvbmFsUHJvcGVydGllczogZmFsc2UsXG4gICAgICB9KVxuICAgIDogaXNTY2hlbWEoc2NoZW1hKVxuICAgICAgPyBzY2hlbWFcbiAgICAgIDogdHlwZW9mIHNjaGVtYSA9PT0gJ2Z1bmN0aW9uJ1xuICAgICAgICA/IHNjaGVtYSgpXG4gICAgICAgIDogem9kU2NoZW1hKHNjaGVtYSk7XG59XG4iLCAiLy8gYnRvYSBhbmQgYXRvYiBuZWVkIHRvIGJlIGludm9rZWQgYXMgYSBmdW5jdGlvbiBjYWxsLCBub3QgYXMgYSBtZXRob2QgY2FsbC5cbi8vIE90aGVyd2lzZSBDbG91ZEZsYXJlIHdpbGwgdGhyb3cgYVxuLy8gXCJUeXBlRXJyb3I6IElsbGVnYWwgaW52b2NhdGlvbjogZnVuY3Rpb24gY2FsbGVkIHdpdGggaW5jb3JyZWN0IHRoaXMgcmVmZXJlbmNlXCJcbmNvbnN0IHsgYnRvYSwgYXRvYiB9ID0gZ2xvYmFsVGhpcztcblxuZXhwb3J0IGZ1bmN0aW9uIGNvbnZlcnRCYXNlNjRUb1VpbnQ4QXJyYXkoYmFzZTY0U3RyaW5nOiBzdHJpbmcpIHtcbiAgY29uc3QgYmFzZTY0VXJsID0gYmFzZTY0U3RyaW5nLnJlcGxhY2UoLy0vZywgJysnKS5yZXBsYWNlKC9fL2csICcvJyk7XG4gIGNvbnN0IGxhdGluMXN0cmluZyA9IGF0b2IoYmFzZTY0VXJsKTtcbiAgcmV0dXJuIFVpbnQ4QXJyYXkuZnJvbShsYXRpbjFzdHJpbmcsIGJ5dGUgPT4gYnl0ZS5jb2RlUG9pbnRBdCgwKSEpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY29udmVydFVpbnQ4QXJyYXlUb0Jhc2U2NChhcnJheTogVWludDhBcnJheSk6IHN0cmluZyB7XG4gIGxldCBsYXRpbjFzdHJpbmcgPSAnJztcblxuICAvLyBOb3RlOiByZWd1bGFyIGZvciBsb29wIHRvIHN1cHBvcnQgb2xkZXIgSmF2YVNjcmlwdCB2ZXJzaW9ucyB0aGF0XG4gIC8vIGRvIG5vdCBzdXBwb3J0IGZvci4ub2Ygb24gVWludDhBcnJheVxuICBmb3IgKGxldCBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgbGF0aW4xc3RyaW5nICs9IFN0cmluZy5mcm9tQ29kZVBvaW50KGFycmF5W2ldKTtcbiAgfVxuXG4gIHJldHVybiBidG9hKGxhdGluMXN0cmluZyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb252ZXJ0VG9CYXNlNjQodmFsdWU6IHN0cmluZyB8IFVpbnQ4QXJyYXkpOiBzdHJpbmcge1xuICByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBVaW50OEFycmF5ID8gY29udmVydFVpbnQ4QXJyYXlUb0Jhc2U2NCh2YWx1ZSkgOiB2YWx1ZTtcbn1cbiIsICJleHBvcnQgZnVuY3Rpb24gd2l0aG91dFRyYWlsaW5nU2xhc2godXJsOiBzdHJpbmcgfCB1bmRlZmluZWQpIHtcbiAgcmV0dXJuIHVybD8ucmVwbGFjZSgvXFwvJC8sICcnKTtcbn1cbiIsICJleHBvcnQgZnVuY3Rpb24gaXNBc3luY0l0ZXJhYmxlPFQgPSBhbnk+KG9iajogYW55KTogb2JqIGlzIEFzeW5jSXRlcmFibGU8VD4ge1xuICByZXR1cm4gb2JqICE9IG51bGwgJiYgdHlwZW9mIG9ialtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPT09ICdmdW5jdGlvbic7XG59XG4iLCAiaW1wb3J0IHsgVG9vbCwgVG9vbENhbGxPcHRpb25zLCBUb29sRXhlY3V0ZUZ1bmN0aW9uIH0gZnJvbSAnLi90b29sJztcbmltcG9ydCB7IGlzQXN5bmNJdGVyYWJsZSB9IGZyb20gJy4uL2lzLWFzeW5jLWl0ZXJhYmxlJztcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uKiBleGVjdXRlVG9vbDxJTlBVVCwgT1VUUFVUPih7XG4gIGV4ZWN1dGUsXG4gIGlucHV0LFxuICBvcHRpb25zLFxufToge1xuICBleGVjdXRlOiBUb29sRXhlY3V0ZUZ1bmN0aW9uPElOUFVULCBPVVRQVVQ+O1xuICBpbnB1dDogSU5QVVQ7XG4gIG9wdGlvbnM6IFRvb2xDYWxsT3B0aW9ucztcbn0pOiBBc3luY0dlbmVyYXRvcjxcbiAgeyB0eXBlOiAncHJlbGltaW5hcnknOyBvdXRwdXQ6IE9VVFBVVCB9IHwgeyB0eXBlOiAnZmluYWwnOyBvdXRwdXQ6IE9VVFBVVCB9XG4+IHtcbiAgY29uc3QgcmVzdWx0ID0gZXhlY3V0ZShpbnB1dCwgb3B0aW9ucyk7XG5cbiAgaWYgKGlzQXN5bmNJdGVyYWJsZShyZXN1bHQpKSB7XG4gICAgbGV0IGxhc3RPdXRwdXQ6IE9VVFBVVCB8IHVuZGVmaW5lZDtcbiAgICBmb3IgYXdhaXQgKGNvbnN0IG91dHB1dCBvZiByZXN1bHQpIHtcbiAgICAgIGxhc3RPdXRwdXQgPSBvdXRwdXQ7XG4gICAgICB5aWVsZCB7IHR5cGU6ICdwcmVsaW1pbmFyeScsIG91dHB1dCB9O1xuICAgIH1cbiAgICB5aWVsZCB7IHR5cGU6ICdmaW5hbCcsIG91dHB1dDogbGFzdE91dHB1dCEgfTtcbiAgfSBlbHNlIHtcbiAgICB5aWVsZCB7IHR5cGU6ICdmaW5hbCcsIG91dHB1dDogYXdhaXQgcmVzdWx0IH07XG4gIH1cbn1cbiIsICJleHBvcnQgKiBmcm9tICcuL2NvbWJpbmUtaGVhZGVycyc7XG5leHBvcnQgeyBjb252ZXJ0QXN5bmNJdGVyYXRvclRvUmVhZGFibGVTdHJlYW0gfSBmcm9tICcuL2NvbnZlcnQtYXN5bmMtaXRlcmF0b3ItdG8tcmVhZGFibGUtc3RyZWFtJztcbmV4cG9ydCAqIGZyb20gJy4vZGVsYXknO1xuZXhwb3J0ICogZnJvbSAnLi9leHRyYWN0LXJlc3BvbnNlLWhlYWRlcnMnO1xuZXhwb3J0ICogZnJvbSAnLi9mZXRjaC1mdW5jdGlvbic7XG5leHBvcnQgeyBjcmVhdGVJZEdlbmVyYXRvciwgZ2VuZXJhdGVJZCwgdHlwZSBJZEdlbmVyYXRvciB9IGZyb20gJy4vZ2VuZXJhdGUtaWQnO1xuZXhwb3J0ICogZnJvbSAnLi9nZXQtZXJyb3ItbWVzc2FnZSc7XG5leHBvcnQgKiBmcm9tICcuL2dldC1mcm9tLWFwaSc7XG5leHBvcnQgeyBnZXRSdW50aW1lRW52aXJvbm1lbnRVc2VyQWdlbnQgfSBmcm9tICcuL2dldC1ydW50aW1lLWVudmlyb25tZW50LXVzZXItYWdlbnQnO1xuZXhwb3J0IHsgaW5qZWN0SnNvbkluc3RydWN0aW9uSW50b01lc3NhZ2VzIH0gZnJvbSAnLi9pbmplY3QtanNvbi1pbnN0cnVjdGlvbic7XG5leHBvcnQgKiBmcm9tICcuL2lzLWFib3J0LWVycm9yJztcbmV4cG9ydCB7IGlzVXJsU3VwcG9ydGVkIH0gZnJvbSAnLi9pcy11cmwtc3VwcG9ydGVkJztcbmV4cG9ydCAqIGZyb20gJy4vbG9hZC1hcGkta2V5JztcbmV4cG9ydCB7IGxvYWRPcHRpb25hbFNldHRpbmcgfSBmcm9tICcuL2xvYWQtb3B0aW9uYWwtc2V0dGluZyc7XG5leHBvcnQgeyBsb2FkU2V0dGluZyB9IGZyb20gJy4vbG9hZC1zZXR0aW5nJztcbmV4cG9ydCB7IG1lZGlhVHlwZVRvRXh0ZW5zaW9uIH0gZnJvbSAnLi9tZWRpYS10eXBlLXRvLWV4dGVuc2lvbic7XG5leHBvcnQgKiBmcm9tICcuL3BhcnNlLWpzb24nO1xuZXhwb3J0IHsgcGFyc2VKc29uRXZlbnRTdHJlYW0gfSBmcm9tICcuL3BhcnNlLWpzb24tZXZlbnQtc3RyZWFtJztcbmV4cG9ydCB7IHBhcnNlUHJvdmlkZXJPcHRpb25zIH0gZnJvbSAnLi9wYXJzZS1wcm92aWRlci1vcHRpb25zJztcbmV4cG9ydCAqIGZyb20gJy4vcG9zdC10by1hcGknO1xuZXhwb3J0IHtcbiAgY3JlYXRlUHJvdmlkZXJEZWZpbmVkVG9vbEZhY3RvcnksXG4gIGNyZWF0ZVByb3ZpZGVyRGVmaW5lZFRvb2xGYWN0b3J5V2l0aE91dHB1dFNjaGVtYSxcbiAgdHlwZSBQcm92aWRlckRlZmluZWRUb29sRmFjdG9yeSxcbiAgdHlwZSBQcm92aWRlckRlZmluZWRUb29sRmFjdG9yeVdpdGhPdXRwdXRTY2hlbWEsXG59IGZyb20gJy4vcHJvdmlkZXItZGVmaW5lZC10b29sLWZhY3RvcnknO1xuZXhwb3J0ICogZnJvbSAnLi9yZW1vdmUtdW5kZWZpbmVkLWVudHJpZXMnO1xuZXhwb3J0ICogZnJvbSAnLi9yZXNvbHZlJztcbmV4cG9ydCAqIGZyb20gJy4vcmVzcG9uc2UtaGFuZGxlcic7XG5leHBvcnQge1xuICBhc1NjaGVtYSxcbiAganNvblNjaGVtYSxcbiAgbGF6eVNjaGVtYSxcbiAgdHlwZSBGbGV4aWJsZVNjaGVtYSxcbiAgdHlwZSBJbmZlclNjaGVtYSxcbiAgdHlwZSBMYXp5U2NoZW1hLFxuICB0eXBlIFNjaGVtYSxcbn0gZnJvbSAnLi9zY2hlbWEnO1xuZXhwb3J0ICogZnJvbSAnLi91aW50OC11dGlscyc7XG5leHBvcnQgKiBmcm9tICcuL3ZhbGlkYXRlLXR5cGVzJztcbmV4cG9ydCB7XG4gIGFzVmFsaWRhdG9yLFxuICBpc1ZhbGlkYXRvcixcbiAgbGF6eVZhbGlkYXRvcixcbiAgc3RhbmRhcmRTY2hlbWFWYWxpZGF0b3IsXG4gIHZhbGlkYXRvcixcbiAgdHlwZSBGbGV4aWJsZVZhbGlkYXRvcixcbiAgdHlwZSBJbmZlclZhbGlkYXRvcixcbiAgdHlwZSBMYXp5VmFsaWRhdG9yLFxuICB0eXBlIFZhbGlkYXRpb25SZXN1bHQsXG4gIHR5cGUgVmFsaWRhdG9yLFxufSBmcm9tICcuL3ZhbGlkYXRvcic7XG5leHBvcnQgeyBWRVJTSU9OIH0gZnJvbSAnLi92ZXJzaW9uJztcbmV4cG9ydCB7IHdpdGhVc2VyQWdlbnRTdWZmaXggfSBmcm9tICcuL3dpdGgtdXNlci1hZ2VudC1zdWZmaXgnO1xuZXhwb3J0ICogZnJvbSAnLi93aXRob3V0LXRyYWlsaW5nLXNsYXNoJztcbmV4cG9ydCB7IHpvZFNjaGVtYSB9IGZyb20gJy4vem9kLXNjaGVtYSc7XG5cbi8vIGZvbGRlciByZS1leHBvcnRzXG5leHBvcnQgKiBmcm9tICcuL3R5cGVzJztcblxuLy8gZXh0ZXJuYWwgcmUtZXhwb3J0c1xuZXhwb3J0ICogZnJvbSAnQHN0YW5kYXJkLXNjaGVtYS9zcGVjJztcbmV4cG9ydCB7XG4gIEV2ZW50U291cmNlUGFyc2VyU3RyZWFtLFxuICB0eXBlIEV2ZW50U291cmNlTWVzc2FnZSxcbn0gZnJvbSAnZXZlbnRzb3VyY2UtcGFyc2VyL3N0cmVhbSc7XG4iLCAiaW1wb3J0IHsgTm9TdWNoTW9kZWxFcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHtcbiAgbG9hZE9wdGlvbmFsU2V0dGluZyxcbiAgd2l0aG91dFRyYWlsaW5nU2xhc2gsXG4gIHR5cGUgRmV0Y2hGdW5jdGlvbixcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyBhc0dhdGV3YXlFcnJvciwgR2F0ZXdheUF1dGhlbnRpY2F0aW9uRXJyb3IgfSBmcm9tICcuL2Vycm9ycyc7XG5pbXBvcnQge1xuICBHQVRFV0FZX0FVVEhfTUVUSE9EX0hFQURFUixcbiAgcGFyc2VBdXRoTWV0aG9kLFxufSBmcm9tICcuL2Vycm9ycy9wYXJzZS1hdXRoLW1ldGhvZCc7XG5pbXBvcnQge1xuICBHYXRld2F5RmV0Y2hNZXRhZGF0YSxcbiAgdHlwZSBHYXRld2F5RmV0Y2hNZXRhZGF0YVJlc3BvbnNlLFxuICB0eXBlIEdhdGV3YXlDcmVkaXRzUmVzcG9uc2UsXG59IGZyb20gJy4vZ2F0ZXdheS1mZXRjaC1tZXRhZGF0YSc7XG5pbXBvcnQgeyBHYXRld2F5TGFuZ3VhZ2VNb2RlbCB9IGZyb20gJy4vZ2F0ZXdheS1sYW5ndWFnZS1tb2RlbCc7XG5pbXBvcnQgeyBHYXRld2F5RW1iZWRkaW5nTW9kZWwgfSBmcm9tICcuL2dhdGV3YXktZW1iZWRkaW5nLW1vZGVsJztcbmltcG9ydCB0eXBlIHsgR2F0ZXdheUVtYmVkZGluZ01vZGVsSWQgfSBmcm9tICcuL2dhdGV3YXktZW1iZWRkaW5nLW1vZGVsLXNldHRpbmdzJztcbmltcG9ydCB7IGdldFZlcmNlbE9pZGNUb2tlbiwgZ2V0VmVyY2VsUmVxdWVzdElkIH0gZnJvbSAnLi92ZXJjZWwtZW52aXJvbm1lbnQnO1xuaW1wb3J0IHR5cGUgeyBHYXRld2F5TW9kZWxJZCB9IGZyb20gJy4vZ2F0ZXdheS1sYW5ndWFnZS1tb2RlbC1zZXR0aW5ncyc7XG5pbXBvcnQgdHlwZSB7XG4gIExhbmd1YWdlTW9kZWxWMixcbiAgRW1iZWRkaW5nTW9kZWxWMixcbiAgUHJvdmlkZXJWMixcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQgeyB3aXRoVXNlckFnZW50U3VmZml4IH0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyBWRVJTSU9OIH0gZnJvbSAnLi92ZXJzaW9uJztcblxuZXhwb3J0IGludGVyZmFjZSBHYXRld2F5UHJvdmlkZXIgZXh0ZW5kcyBQcm92aWRlclYyIHtcbiAgKG1vZGVsSWQ6IEdhdGV3YXlNb2RlbElkKTogTGFuZ3VhZ2VNb2RlbFYyO1xuXG4gIC8qKlxuQ3JlYXRlcyBhIG1vZGVsIGZvciB0ZXh0IGdlbmVyYXRpb24uXG4qL1xuICBsYW5ndWFnZU1vZGVsKG1vZGVsSWQ6IEdhdGV3YXlNb2RlbElkKTogTGFuZ3VhZ2VNb2RlbFYyO1xuXG4gIC8qKlxuUmV0dXJucyBhdmFpbGFibGUgcHJvdmlkZXJzIGFuZCBtb2RlbHMgZm9yIHVzZSB3aXRoIHRoZSByZW1vdGUgcHJvdmlkZXIuXG4gKi9cbiAgZ2V0QXZhaWxhYmxlTW9kZWxzKCk6IFByb21pc2U8R2F0ZXdheUZldGNoTWV0YWRhdGFSZXNwb25zZT47XG5cbiAgLyoqXG5SZXR1cm5zIGNyZWRpdCBpbmZvcm1hdGlvbiBmb3IgdGhlIGF1dGhlbnRpY2F0ZWQgdXNlci5cbiAqL1xuICBnZXRDcmVkaXRzKCk6IFByb21pc2U8R2F0ZXdheUNyZWRpdHNSZXNwb25zZT47XG5cbiAgLyoqXG5DcmVhdGVzIGEgbW9kZWwgZm9yIGdlbmVyYXRpbmcgdGV4dCBlbWJlZGRpbmdzLlxuKi9cbiAgdGV4dEVtYmVkZGluZ01vZGVsKFxuICAgIG1vZGVsSWQ6IEdhdGV3YXlFbWJlZGRpbmdNb2RlbElkLFxuICApOiBFbWJlZGRpbmdNb2RlbFYyPHN0cmluZz47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2F0ZXdheVByb3ZpZGVyU2V0dGluZ3Mge1xuICAvKipcblRoZSBiYXNlIFVSTCBwcmVmaXggZm9yIEFQSSBjYWxscy4gRGVmYXVsdHMgdG8gYGh0dHBzOi8vYWktZ2F0ZXdheS52ZXJjZWwuc2gvdjEvYWlgLlxuICAgKi9cbiAgYmFzZVVSTD86IHN0cmluZztcblxuICAvKipcbkFQSSBrZXkgdGhhdCBpcyBiZWluZyBzZW50IHVzaW5nIHRoZSBgQXV0aG9yaXphdGlvbmAgaGVhZGVyLlxuICAgKi9cbiAgYXBpS2V5Pzogc3RyaW5nO1xuXG4gIC8qKlxuQ3VzdG9tIGhlYWRlcnMgdG8gaW5jbHVkZSBpbiB0aGUgcmVxdWVzdHMuXG4gICAgICovXG4gIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuXG4gIC8qKlxuQ3VzdG9tIGZldGNoIGltcGxlbWVudGF0aW9uLiBZb3UgY2FuIHVzZSBpdCBhcyBhIG1pZGRsZXdhcmUgdG8gaW50ZXJjZXB0IHJlcXVlc3RzLFxub3IgdG8gcHJvdmlkZSBhIGN1c3RvbSBmZXRjaCBpbXBsZW1lbnRhdGlvbiBmb3IgZS5nLiB0ZXN0aW5nLlxuICAgICovXG4gIGZldGNoPzogRmV0Y2hGdW5jdGlvbjtcblxuICAvKipcbkhvdyBmcmVxdWVudGx5IHRvIHJlZnJlc2ggdGhlIG1ldGFkYXRhIGNhY2hlIGluIG1pbGxpc2Vjb25kcy5cbiAgICovXG4gIG1ldGFkYXRhQ2FjaGVSZWZyZXNoTWlsbGlzPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBAaW50ZXJuYWwgRm9yIHRlc3RpbmcgcHVycG9zZXMgb25seVxuICAgKi9cbiAgX2ludGVybmFsPzoge1xuICAgIGN1cnJlbnREYXRlPzogKCkgPT4gRGF0ZTtcbiAgfTtcbn1cblxuY29uc3QgQUlfR0FURVdBWV9QUk9UT0NPTF9WRVJTSU9OID0gJzAuMC4xJztcblxuLyoqXG5DcmVhdGUgYSByZW1vdGUgcHJvdmlkZXIgaW5zdGFuY2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVHYXRld2F5UHJvdmlkZXIoXG4gIG9wdGlvbnM6IEdhdGV3YXlQcm92aWRlclNldHRpbmdzID0ge30sXG4pOiBHYXRld2F5UHJvdmlkZXIge1xuICBsZXQgcGVuZGluZ01ldGFkYXRhOiBQcm9taXNlPEdhdGV3YXlGZXRjaE1ldGFkYXRhUmVzcG9uc2U+IHwgbnVsbCA9IG51bGw7XG4gIGxldCBtZXRhZGF0YUNhY2hlOiBHYXRld2F5RmV0Y2hNZXRhZGF0YVJlc3BvbnNlIHwgbnVsbCA9IG51bGw7XG4gIGNvbnN0IGNhY2hlUmVmcmVzaE1pbGxpcyA9XG4gICAgb3B0aW9ucy5tZXRhZGF0YUNhY2hlUmVmcmVzaE1pbGxpcyA/PyAxMDAwICogNjAgKiA1O1xuICBsZXQgbGFzdEZldGNoVGltZSA9IDA7XG5cbiAgY29uc3QgYmFzZVVSTCA9XG4gICAgd2l0aG91dFRyYWlsaW5nU2xhc2gob3B0aW9ucy5iYXNlVVJMKSA/P1xuICAgICdodHRwczovL2FpLWdhdGV3YXkudmVyY2VsLnNoL3YxL2FpJztcblxuICBjb25zdCBnZXRIZWFkZXJzID0gYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGF1dGggPSBhd2FpdCBnZXRHYXRld2F5QXV0aFRva2VuKG9wdGlvbnMpO1xuICAgIGlmIChhdXRoKSB7XG4gICAgICByZXR1cm4gd2l0aFVzZXJBZ2VudFN1ZmZpeChcbiAgICAgICAge1xuICAgICAgICAgIEF1dGhvcml6YXRpb246IGBCZWFyZXIgJHthdXRoLnRva2VufWAsXG4gICAgICAgICAgJ2FpLWdhdGV3YXktcHJvdG9jb2wtdmVyc2lvbic6IEFJX0dBVEVXQVlfUFJPVE9DT0xfVkVSU0lPTixcbiAgICAgICAgICBbR0FURVdBWV9BVVRIX01FVEhPRF9IRUFERVJdOiBhdXRoLmF1dGhNZXRob2QsXG4gICAgICAgICAgLi4ub3B0aW9ucy5oZWFkZXJzLFxuICAgICAgICB9LFxuICAgICAgICBgYWktc2RrL2dhdGV3YXkvJHtWRVJTSU9OfWAsXG4gICAgICApO1xuICAgIH1cblxuICAgIHRocm93IEdhdGV3YXlBdXRoZW50aWNhdGlvbkVycm9yLmNyZWF0ZUNvbnRleHR1YWxFcnJvcih7XG4gICAgICBhcGlLZXlQcm92aWRlZDogZmFsc2UsXG4gICAgICBvaWRjVG9rZW5Qcm92aWRlZDogZmFsc2UsXG4gICAgICBzdGF0dXNDb2RlOiA0MDEsXG4gICAgfSk7XG4gIH07XG5cbiAgY29uc3QgY3JlYXRlTzExeUhlYWRlcnMgPSAoKSA9PiB7XG4gICAgY29uc3QgZGVwbG95bWVudElkID0gbG9hZE9wdGlvbmFsU2V0dGluZyh7XG4gICAgICBzZXR0aW5nVmFsdWU6IHVuZGVmaW5lZCxcbiAgICAgIGVudmlyb25tZW50VmFyaWFibGVOYW1lOiAnVkVSQ0VMX0RFUExPWU1FTlRfSUQnLFxuICAgIH0pO1xuICAgIGNvbnN0IGVudmlyb25tZW50ID0gbG9hZE9wdGlvbmFsU2V0dGluZyh7XG4gICAgICBzZXR0aW5nVmFsdWU6IHVuZGVmaW5lZCxcbiAgICAgIGVudmlyb25tZW50VmFyaWFibGVOYW1lOiAnVkVSQ0VMX0VOVicsXG4gICAgfSk7XG4gICAgY29uc3QgcmVnaW9uID0gbG9hZE9wdGlvbmFsU2V0dGluZyh7XG4gICAgICBzZXR0aW5nVmFsdWU6IHVuZGVmaW5lZCxcbiAgICAgIGVudmlyb25tZW50VmFyaWFibGVOYW1lOiAnVkVSQ0VMX1JFR0lPTicsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcmVxdWVzdElkID0gYXdhaXQgZ2V0VmVyY2VsUmVxdWVzdElkKCk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi4oZGVwbG95bWVudElkICYmIHsgJ2FpLW8xMXktZGVwbG95bWVudC1pZCc6IGRlcGxveW1lbnRJZCB9KSxcbiAgICAgICAgLi4uKGVudmlyb25tZW50ICYmIHsgJ2FpLW8xMXktZW52aXJvbm1lbnQnOiBlbnZpcm9ubWVudCB9KSxcbiAgICAgICAgLi4uKHJlZ2lvbiAmJiB7ICdhaS1vMTF5LXJlZ2lvbic6IHJlZ2lvbiB9KSxcbiAgICAgICAgLi4uKHJlcXVlc3RJZCAmJiB7ICdhaS1vMTF5LXJlcXVlc3QtaWQnOiByZXF1ZXN0SWQgfSksXG4gICAgICB9O1xuICAgIH07XG4gIH07XG5cbiAgY29uc3QgY3JlYXRlTGFuZ3VhZ2VNb2RlbCA9IChtb2RlbElkOiBHYXRld2F5TW9kZWxJZCkgPT4ge1xuICAgIHJldHVybiBuZXcgR2F0ZXdheUxhbmd1YWdlTW9kZWwobW9kZWxJZCwge1xuICAgICAgcHJvdmlkZXI6ICdnYXRld2F5JyxcbiAgICAgIGJhc2VVUkwsXG4gICAgICBoZWFkZXJzOiBnZXRIZWFkZXJzLFxuICAgICAgZmV0Y2g6IG9wdGlvbnMuZmV0Y2gsXG4gICAgICBvMTF5SGVhZGVyczogY3JlYXRlTzExeUhlYWRlcnMoKSxcbiAgICB9KTtcbiAgfTtcblxuICBjb25zdCBnZXRBdmFpbGFibGVNb2RlbHMgPSBhc3luYyAoKSA9PiB7XG4gICAgY29uc3Qgbm93ID0gb3B0aW9ucy5faW50ZXJuYWw/LmN1cnJlbnREYXRlPy4oKS5nZXRUaW1lKCkgPz8gRGF0ZS5ub3coKTtcbiAgICBpZiAoIXBlbmRpbmdNZXRhZGF0YSB8fCBub3cgLSBsYXN0RmV0Y2hUaW1lID4gY2FjaGVSZWZyZXNoTWlsbGlzKSB7XG4gICAgICBsYXN0RmV0Y2hUaW1lID0gbm93O1xuXG4gICAgICBwZW5kaW5nTWV0YWRhdGEgPSBuZXcgR2F0ZXdheUZldGNoTWV0YWRhdGEoe1xuICAgICAgICBiYXNlVVJMLFxuICAgICAgICBoZWFkZXJzOiBnZXRIZWFkZXJzLFxuICAgICAgICBmZXRjaDogb3B0aW9ucy5mZXRjaCxcbiAgICAgIH0pXG4gICAgICAgIC5nZXRBdmFpbGFibGVNb2RlbHMoKVxuICAgICAgICAudGhlbihtZXRhZGF0YSA9PiB7XG4gICAgICAgICAgbWV0YWRhdGFDYWNoZSA9IG1ldGFkYXRhO1xuICAgICAgICAgIHJldHVybiBtZXRhZGF0YTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGFzeW5jIChlcnJvcjogdW5rbm93bikgPT4ge1xuICAgICAgICAgIHRocm93IGF3YWl0IGFzR2F0ZXdheUVycm9yKFxuICAgICAgICAgICAgZXJyb3IsXG4gICAgICAgICAgICBhd2FpdCBwYXJzZUF1dGhNZXRob2QoYXdhaXQgZ2V0SGVhZGVycygpKSxcbiAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gbWV0YWRhdGFDYWNoZSA/IFByb21pc2UucmVzb2x2ZShtZXRhZGF0YUNhY2hlKSA6IHBlbmRpbmdNZXRhZGF0YTtcbiAgfTtcblxuICBjb25zdCBnZXRDcmVkaXRzID0gYXN5bmMgKCkgPT4ge1xuICAgIHJldHVybiBuZXcgR2F0ZXdheUZldGNoTWV0YWRhdGEoe1xuICAgICAgYmFzZVVSTCxcbiAgICAgIGhlYWRlcnM6IGdldEhlYWRlcnMsXG4gICAgICBmZXRjaDogb3B0aW9ucy5mZXRjaCxcbiAgICB9KVxuICAgICAgLmdldENyZWRpdHMoKVxuICAgICAgLmNhdGNoKGFzeW5jIChlcnJvcjogdW5rbm93bikgPT4ge1xuICAgICAgICB0aHJvdyBhd2FpdCBhc0dhdGV3YXlFcnJvcihcbiAgICAgICAgICBlcnJvcixcbiAgICAgICAgICBhd2FpdCBwYXJzZUF1dGhNZXRob2QoYXdhaXQgZ2V0SGVhZGVycygpKSxcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICB9O1xuXG4gIGNvbnN0IHByb3ZpZGVyID0gZnVuY3Rpb24gKG1vZGVsSWQ6IEdhdGV3YXlNb2RlbElkKSB7XG4gICAgaWYgKG5ldy50YXJnZXQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ1RoZSBHYXRld2F5IFByb3ZpZGVyIG1vZGVsIGZ1bmN0aW9uIGNhbm5vdCBiZSBjYWxsZWQgd2l0aCB0aGUgbmV3IGtleXdvcmQuJyxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNyZWF0ZUxhbmd1YWdlTW9kZWwobW9kZWxJZCk7XG4gIH07XG5cbiAgcHJvdmlkZXIuZ2V0QXZhaWxhYmxlTW9kZWxzID0gZ2V0QXZhaWxhYmxlTW9kZWxzO1xuICBwcm92aWRlci5nZXRDcmVkaXRzID0gZ2V0Q3JlZGl0cztcbiAgcHJvdmlkZXIuaW1hZ2VNb2RlbCA9IChtb2RlbElkOiBzdHJpbmcpID0+IHtcbiAgICB0aHJvdyBuZXcgTm9TdWNoTW9kZWxFcnJvcih7IG1vZGVsSWQsIG1vZGVsVHlwZTogJ2ltYWdlTW9kZWwnIH0pO1xuICB9O1xuICBwcm92aWRlci5sYW5ndWFnZU1vZGVsID0gY3JlYXRlTGFuZ3VhZ2VNb2RlbDtcbiAgcHJvdmlkZXIudGV4dEVtYmVkZGluZ01vZGVsID0gKG1vZGVsSWQ6IEdhdGV3YXlFbWJlZGRpbmdNb2RlbElkKSA9PiB7XG4gICAgcmV0dXJuIG5ldyBHYXRld2F5RW1iZWRkaW5nTW9kZWwobW9kZWxJZCwge1xuICAgICAgcHJvdmlkZXI6ICdnYXRld2F5JyxcbiAgICAgIGJhc2VVUkwsXG4gICAgICBoZWFkZXJzOiBnZXRIZWFkZXJzLFxuICAgICAgZmV0Y2g6IG9wdGlvbnMuZmV0Y2gsXG4gICAgICBvMTF5SGVhZGVyczogY3JlYXRlTzExeUhlYWRlcnMoKSxcbiAgICB9KTtcbiAgfTtcblxuICByZXR1cm4gcHJvdmlkZXI7XG59XG5cbmV4cG9ydCBjb25zdCBnYXRld2F5ID0gY3JlYXRlR2F0ZXdheVByb3ZpZGVyKCk7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRHYXRld2F5QXV0aFRva2VuKFxuICBvcHRpb25zOiBHYXRld2F5UHJvdmlkZXJTZXR0aW5ncyxcbik6IFByb21pc2U8e1xuICB0b2tlbjogc3RyaW5nO1xuICBhdXRoTWV0aG9kOiAnYXBpLWtleScgfCAnb2lkYyc7XG59IHwgbnVsbD4ge1xuICBjb25zdCBhcGlLZXkgPSBsb2FkT3B0aW9uYWxTZXR0aW5nKHtcbiAgICBzZXR0aW5nVmFsdWU6IG9wdGlvbnMuYXBpS2V5LFxuICAgIGVudmlyb25tZW50VmFyaWFibGVOYW1lOiAnQUlfR0FURVdBWV9BUElfS0VZJyxcbiAgfSk7XG5cbiAgaWYgKGFwaUtleSkge1xuICAgIHJldHVybiB7XG4gICAgICB0b2tlbjogYXBpS2V5LFxuICAgICAgYXV0aE1ldGhvZDogJ2FwaS1rZXknLFxuICAgIH07XG4gIH1cblxuICB0cnkge1xuICAgIGNvbnN0IG9pZGNUb2tlbiA9IGF3YWl0IGdldFZlcmNlbE9pZGNUb2tlbigpO1xuICAgIHJldHVybiB7XG4gICAgICB0b2tlbjogb2lkY1Rva2VuLFxuICAgICAgYXV0aE1ldGhvZDogJ29pZGMnLFxuICAgIH07XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBudWxsO1xuICB9XG59XG4iLCAiaW1wb3J0IHsgQVBJQ2FsbEVycm9yIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQgeyBleHRyYWN0QXBpQ2FsbFJlc3BvbnNlLCBHYXRld2F5RXJyb3IgfSBmcm9tICcuJztcbmltcG9ydCB7IGNyZWF0ZUdhdGV3YXlFcnJvckZyb21SZXNwb25zZSB9IGZyb20gJy4vY3JlYXRlLWdhdGV3YXktZXJyb3InO1xuXG5leHBvcnQgZnVuY3Rpb24gYXNHYXRld2F5RXJyb3IoXG4gIGVycm9yOiB1bmtub3duLFxuICBhdXRoTWV0aG9kPzogJ2FwaS1rZXknIHwgJ29pZGMnLFxuKSB7XG4gIGlmIChHYXRld2F5RXJyb3IuaXNJbnN0YW5jZShlcnJvcikpIHtcbiAgICByZXR1cm4gZXJyb3I7XG4gIH1cblxuICBpZiAoQVBJQ2FsbEVycm9yLmlzSW5zdGFuY2UoZXJyb3IpKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUdhdGV3YXlFcnJvckZyb21SZXNwb25zZSh7XG4gICAgICByZXNwb25zZTogZXh0cmFjdEFwaUNhbGxSZXNwb25zZShlcnJvciksXG4gICAgICBzdGF0dXNDb2RlOiBlcnJvci5zdGF0dXNDb2RlID8/IDUwMCxcbiAgICAgIGRlZmF1bHRNZXNzYWdlOiAnR2F0ZXdheSByZXF1ZXN0IGZhaWxlZCcsXG4gICAgICBjYXVzZTogZXJyb3IsXG4gICAgICBhdXRoTWV0aG9kLFxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIGNyZWF0ZUdhdGV3YXlFcnJvckZyb21SZXNwb25zZSh7XG4gICAgcmVzcG9uc2U6IHt9LFxuICAgIHN0YXR1c0NvZGU6IDUwMCxcbiAgICBkZWZhdWx0TWVzc2FnZTpcbiAgICAgIGVycm9yIGluc3RhbmNlb2YgRXJyb3JcbiAgICAgICAgPyBgR2F0ZXdheSByZXF1ZXN0IGZhaWxlZDogJHtlcnJvci5tZXNzYWdlfWBcbiAgICAgICAgOiAnVW5rbm93biBHYXRld2F5IGVycm9yJyxcbiAgICBjYXVzZTogZXJyb3IsXG4gICAgYXV0aE1ldGhvZCxcbiAgfSk7XG59XG4iLCAiaW1wb3J0IHsgeiB9IGZyb20gJ3pvZC92NCc7XG5pbXBvcnQgdHlwZSB7IEdhdGV3YXlFcnJvciB9IGZyb20gJy4vZ2F0ZXdheS1lcnJvcic7XG5pbXBvcnQgeyBHYXRld2F5QXV0aGVudGljYXRpb25FcnJvciB9IGZyb20gJy4vZ2F0ZXdheS1hdXRoZW50aWNhdGlvbi1lcnJvcic7XG5pbXBvcnQgeyBHYXRld2F5SW52YWxpZFJlcXVlc3RFcnJvciB9IGZyb20gJy4vZ2F0ZXdheS1pbnZhbGlkLXJlcXVlc3QtZXJyb3InO1xuaW1wb3J0IHsgR2F0ZXdheVJhdGVMaW1pdEVycm9yIH0gZnJvbSAnLi9nYXRld2F5LXJhdGUtbGltaXQtZXJyb3InO1xuaW1wb3J0IHtcbiAgR2F0ZXdheU1vZGVsTm90Rm91bmRFcnJvcixcbiAgbW9kZWxOb3RGb3VuZFBhcmFtU2NoZW1hLFxufSBmcm9tICcuL2dhdGV3YXktbW9kZWwtbm90LWZvdW5kLWVycm9yJztcbmltcG9ydCB7IEdhdGV3YXlJbnRlcm5hbFNlcnZlckVycm9yIH0gZnJvbSAnLi9nYXRld2F5LWludGVybmFsLXNlcnZlci1lcnJvcic7XG5pbXBvcnQgeyBHYXRld2F5UmVzcG9uc2VFcnJvciB9IGZyb20gJy4vZ2F0ZXdheS1yZXNwb25zZS1lcnJvcic7XG5pbXBvcnQge1xuICBJbmZlclZhbGlkYXRvcixcbiAgbGF6eVZhbGlkYXRvcixcbiAgc2FmZVZhbGlkYXRlVHlwZXMsXG4gIHZhbGlkYXRlVHlwZXMsXG4gIHpvZFNjaGVtYSxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjcmVhdGVHYXRld2F5RXJyb3JGcm9tUmVzcG9uc2Uoe1xuICByZXNwb25zZSxcbiAgc3RhdHVzQ29kZSxcbiAgZGVmYXVsdE1lc3NhZ2UgPSAnR2F0ZXdheSByZXF1ZXN0IGZhaWxlZCcsXG4gIGNhdXNlLFxuICBhdXRoTWV0aG9kLFxufToge1xuICByZXNwb25zZTogdW5rbm93bjtcbiAgc3RhdHVzQ29kZTogbnVtYmVyO1xuICBkZWZhdWx0TWVzc2FnZT86IHN0cmluZztcbiAgY2F1c2U/OiB1bmtub3duO1xuICBhdXRoTWV0aG9kPzogJ2FwaS1rZXknIHwgJ29pZGMnO1xufSk6IFByb21pc2U8R2F0ZXdheUVycm9yPiB7XG4gIGNvbnN0IHBhcnNlUmVzdWx0ID0gYXdhaXQgc2FmZVZhbGlkYXRlVHlwZXMoe1xuICAgIHZhbHVlOiByZXNwb25zZSxcbiAgICBzY2hlbWE6IGdhdGV3YXlFcnJvclJlc3BvbnNlU2NoZW1hLFxuICB9KTtcblxuICBpZiAoIXBhcnNlUmVzdWx0LnN1Y2Nlc3MpIHtcbiAgICByZXR1cm4gbmV3IEdhdGV3YXlSZXNwb25zZUVycm9yKHtcbiAgICAgIG1lc3NhZ2U6IGBJbnZhbGlkIGVycm9yIHJlc3BvbnNlIGZvcm1hdDogJHtkZWZhdWx0TWVzc2FnZX1gLFxuICAgICAgc3RhdHVzQ29kZSxcbiAgICAgIHJlc3BvbnNlLFxuICAgICAgdmFsaWRhdGlvbkVycm9yOiBwYXJzZVJlc3VsdC5lcnJvcixcbiAgICAgIGNhdXNlLFxuICAgIH0pO1xuICB9XG5cbiAgY29uc3QgdmFsaWRhdGVkUmVzcG9uc2U6IEdhdGV3YXlFcnJvclJlc3BvbnNlID0gcGFyc2VSZXN1bHQudmFsdWU7XG4gIGNvbnN0IGVycm9yVHlwZSA9IHZhbGlkYXRlZFJlc3BvbnNlLmVycm9yLnR5cGU7XG4gIGNvbnN0IG1lc3NhZ2UgPSB2YWxpZGF0ZWRSZXNwb25zZS5lcnJvci5tZXNzYWdlO1xuXG4gIHN3aXRjaCAoZXJyb3JUeXBlKSB7XG4gICAgY2FzZSAnYXV0aGVudGljYXRpb25fZXJyb3InOlxuICAgICAgcmV0dXJuIEdhdGV3YXlBdXRoZW50aWNhdGlvbkVycm9yLmNyZWF0ZUNvbnRleHR1YWxFcnJvcih7XG4gICAgICAgIGFwaUtleVByb3ZpZGVkOiBhdXRoTWV0aG9kID09PSAnYXBpLWtleScsXG4gICAgICAgIG9pZGNUb2tlblByb3ZpZGVkOiBhdXRoTWV0aG9kID09PSAnb2lkYycsXG4gICAgICAgIHN0YXR1c0NvZGUsXG4gICAgICAgIGNhdXNlLFxuICAgICAgfSk7XG4gICAgY2FzZSAnaW52YWxpZF9yZXF1ZXN0X2Vycm9yJzpcbiAgICAgIHJldHVybiBuZXcgR2F0ZXdheUludmFsaWRSZXF1ZXN0RXJyb3IoeyBtZXNzYWdlLCBzdGF0dXNDb2RlLCBjYXVzZSB9KTtcbiAgICBjYXNlICdyYXRlX2xpbWl0X2V4Y2VlZGVkJzpcbiAgICAgIHJldHVybiBuZXcgR2F0ZXdheVJhdGVMaW1pdEVycm9yKHsgbWVzc2FnZSwgc3RhdHVzQ29kZSwgY2F1c2UgfSk7XG4gICAgY2FzZSAnbW9kZWxfbm90X2ZvdW5kJzoge1xuICAgICAgY29uc3QgbW9kZWxSZXN1bHQgPSBhd2FpdCBzYWZlVmFsaWRhdGVUeXBlcyh7XG4gICAgICAgIHZhbHVlOiB2YWxpZGF0ZWRSZXNwb25zZS5lcnJvci5wYXJhbSxcbiAgICAgICAgc2NoZW1hOiBtb2RlbE5vdEZvdW5kUGFyYW1TY2hlbWEsXG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIG5ldyBHYXRld2F5TW9kZWxOb3RGb3VuZEVycm9yKHtcbiAgICAgICAgbWVzc2FnZSxcbiAgICAgICAgc3RhdHVzQ29kZSxcbiAgICAgICAgbW9kZWxJZDogbW9kZWxSZXN1bHQuc3VjY2VzcyA/IG1vZGVsUmVzdWx0LnZhbHVlLm1vZGVsSWQgOiB1bmRlZmluZWQsXG4gICAgICAgIGNhdXNlLFxuICAgICAgfSk7XG4gICAgfVxuICAgIGNhc2UgJ2ludGVybmFsX3NlcnZlcl9lcnJvcic6XG4gICAgICByZXR1cm4gbmV3IEdhdGV3YXlJbnRlcm5hbFNlcnZlckVycm9yKHsgbWVzc2FnZSwgc3RhdHVzQ29kZSwgY2F1c2UgfSk7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBuZXcgR2F0ZXdheUludGVybmFsU2VydmVyRXJyb3IoeyBtZXNzYWdlLCBzdGF0dXNDb2RlLCBjYXVzZSB9KTtcbiAgfVxufVxuXG5jb25zdCBnYXRld2F5RXJyb3JSZXNwb25zZVNjaGVtYSA9IGxhenlWYWxpZGF0b3IoKCkgPT5cbiAgem9kU2NoZW1hKFxuICAgIHoub2JqZWN0KHtcbiAgICAgIGVycm9yOiB6Lm9iamVjdCh7XG4gICAgICAgIG1lc3NhZ2U6IHouc3RyaW5nKCksXG4gICAgICAgIHR5cGU6IHouc3RyaW5nKCkubnVsbGlzaCgpLFxuICAgICAgICBwYXJhbTogei51bmtub3duKCkubnVsbGlzaCgpLFxuICAgICAgICBjb2RlOiB6LnVuaW9uKFt6LnN0cmluZygpLCB6Lm51bWJlcigpXSkubnVsbGlzaCgpLFxuICAgICAgfSksXG4gICAgfSksXG4gICksXG4pO1xuXG5leHBvcnQgdHlwZSBHYXRld2F5RXJyb3JSZXNwb25zZSA9IEluZmVyVmFsaWRhdG9yPFxuICB0eXBlb2YgZ2F0ZXdheUVycm9yUmVzcG9uc2VTY2hlbWFcbj47XG4iLCAiY29uc3QgbWFya2VyID0gJ3ZlcmNlbC5haS5nYXRld2F5LmVycm9yJztcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEdhdGV3YXlFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7IC8vIHVzZWQgaW4gaXNJbnN0YW5jZVxuXG4gIGFic3RyYWN0IHJlYWRvbmx5IG5hbWU6IHN0cmluZztcbiAgYWJzdHJhY3QgcmVhZG9ubHkgdHlwZTogc3RyaW5nO1xuICByZWFkb25seSBzdGF0dXNDb2RlOiBudW1iZXI7XG4gIHJlYWRvbmx5IGNhdXNlPzogdW5rbm93bjtcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgbWVzc2FnZSxcbiAgICBzdGF0dXNDb2RlID0gNTAwLFxuICAgIGNhdXNlLFxuICB9OiB7XG4gICAgbWVzc2FnZTogc3RyaW5nO1xuICAgIHN0YXR1c0NvZGU/OiBudW1iZXI7XG4gICAgY2F1c2U/OiB1bmtub3duO1xuICB9KSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gICAgdGhpcy5zdGF0dXNDb2RlID0gc3RhdHVzQ29kZTtcbiAgICB0aGlzLmNhdXNlID0gY2F1c2U7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBlcnJvciBpcyBhIEdhdGV3YXkgRXJyb3IuXG4gICAqIEBwYXJhbSB7dW5rbm93bn0gZXJyb3IgLSBUaGUgZXJyb3IgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSBlcnJvciBpcyBhIEdhdGV3YXkgRXJyb3IsIGZhbHNlIG90aGVyd2lzZS5cbiAgICovXG4gIHN0YXRpYyBpc0luc3RhbmNlKGVycm9yOiB1bmtub3duKTogZXJyb3IgaXMgR2F0ZXdheUVycm9yIHtcbiAgICByZXR1cm4gR2F0ZXdheUVycm9yLmhhc01hcmtlcihlcnJvcik7XG4gIH1cblxuICBzdGF0aWMgaGFzTWFya2VyKGVycm9yOiB1bmtub3duKTogZXJyb3IgaXMgR2F0ZXdheUVycm9yIHtcbiAgICByZXR1cm4gKFxuICAgICAgdHlwZW9mIGVycm9yID09PSAnb2JqZWN0JyAmJlxuICAgICAgZXJyb3IgIT09IG51bGwgJiZcbiAgICAgIHN5bWJvbCBpbiBlcnJvciAmJlxuICAgICAgKGVycm9yIGFzIGFueSlbc3ltYm9sXSA9PT0gdHJ1ZVxuICAgICk7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBHYXRld2F5RXJyb3IgfSBmcm9tICcuL2dhdGV3YXktZXJyb3InO1xuXG5jb25zdCBuYW1lID0gJ0dhdGV3YXlBdXRoZW50aWNhdGlvbkVycm9yJztcbmNvbnN0IG1hcmtlciA9IGB2ZXJjZWwuYWkuZ2F0ZXdheS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuLyoqXG4gKiBBdXRoZW50aWNhdGlvbiBmYWlsZWQgLSBpbnZhbGlkIEFQSSBrZXkgb3IgT0lEQyB0b2tlblxuICovXG5leHBvcnQgY2xhc3MgR2F0ZXdheUF1dGhlbnRpY2F0aW9uRXJyb3IgZXh0ZW5kcyBHYXRld2F5RXJyb3Ige1xuICBwcml2YXRlIHJlYWRvbmx5IFtzeW1ib2xdID0gdHJ1ZTsgLy8gdXNlZCBpbiBpc0luc3RhbmNlXG5cbiAgcmVhZG9ubHkgbmFtZSA9IG5hbWU7XG4gIHJlYWRvbmx5IHR5cGUgPSAnYXV0aGVudGljYXRpb25fZXJyb3InO1xuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICBtZXNzYWdlID0gJ0F1dGhlbnRpY2F0aW9uIGZhaWxlZCcsXG4gICAgc3RhdHVzQ29kZSA9IDQwMSxcbiAgICBjYXVzZSxcbiAgfToge1xuICAgIG1lc3NhZ2U/OiBzdHJpbmc7XG4gICAgc3RhdHVzQ29kZT86IG51bWJlcjtcbiAgICBjYXVzZT86IHVua25vd247XG4gIH0gPSB7fSkge1xuICAgIHN1cGVyKHsgbWVzc2FnZSwgc3RhdHVzQ29kZSwgY2F1c2UgfSk7XG4gIH1cblxuICBzdGF0aWMgaXNJbnN0YW5jZShlcnJvcjogdW5rbm93bik6IGVycm9yIGlzIEdhdGV3YXlBdXRoZW50aWNhdGlvbkVycm9yIHtcbiAgICByZXR1cm4gR2F0ZXdheUVycm9yLmhhc01hcmtlcihlcnJvcikgJiYgc3ltYm9sIGluIGVycm9yO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBjb250ZXh0dWFsIGVycm9yIG1lc3NhZ2Ugd2hlbiBhdXRoZW50aWNhdGlvbiBmYWlsc1xuICAgKi9cbiAgc3RhdGljIGNyZWF0ZUNvbnRleHR1YWxFcnJvcih7XG4gICAgYXBpS2V5UHJvdmlkZWQsXG4gICAgb2lkY1Rva2VuUHJvdmlkZWQsXG4gICAgbWVzc2FnZSA9ICdBdXRoZW50aWNhdGlvbiBmYWlsZWQnLFxuICAgIHN0YXR1c0NvZGUgPSA0MDEsXG4gICAgY2F1c2UsXG4gIH06IHtcbiAgICBhcGlLZXlQcm92aWRlZDogYm9vbGVhbjtcbiAgICBvaWRjVG9rZW5Qcm92aWRlZDogYm9vbGVhbjtcbiAgICBtZXNzYWdlPzogc3RyaW5nO1xuICAgIHN0YXR1c0NvZGU/OiBudW1iZXI7XG4gICAgY2F1c2U/OiB1bmtub3duO1xuICB9KTogR2F0ZXdheUF1dGhlbnRpY2F0aW9uRXJyb3Ige1xuICAgIGxldCBjb250ZXh0dWFsTWVzc2FnZTogc3RyaW5nO1xuXG4gICAgaWYgKGFwaUtleVByb3ZpZGVkKSB7XG4gICAgICBjb250ZXh0dWFsTWVzc2FnZSA9IGBBSSBHYXRld2F5IGF1dGhlbnRpY2F0aW9uIGZhaWxlZDogSW52YWxpZCBBUEkga2V5LlxuXG5DcmVhdGUgYSBuZXcgQVBJIGtleTogaHR0cHM6Ly92ZXJjZWwuY29tL2Q/dG89JTJGJTVCdGVhbSU1RCUyRiU3RSUyRmFpJTJGYXBpLWtleXNcblxuUHJvdmlkZSB2aWEgJ2FwaUtleScgb3B0aW9uIG9yICdBSV9HQVRFV0FZX0FQSV9LRVknIGVudmlyb25tZW50IHZhcmlhYmxlLmA7XG4gICAgfSBlbHNlIGlmIChvaWRjVG9rZW5Qcm92aWRlZCkge1xuICAgICAgY29udGV4dHVhbE1lc3NhZ2UgPSBgQUkgR2F0ZXdheSBhdXRoZW50aWNhdGlvbiBmYWlsZWQ6IEludmFsaWQgT0lEQyB0b2tlbi5cblxuUnVuICducHggdmVyY2VsIGxpbmsnIHRvIGxpbmsgeW91ciBwcm9qZWN0LCB0aGVuICd2YyBlbnYgcHVsbCcgdG8gZmV0Y2ggdGhlIHRva2VuLlxuXG5BbHRlcm5hdGl2ZWx5LCB1c2UgYW4gQVBJIGtleTogaHR0cHM6Ly92ZXJjZWwuY29tL2Q/dG89JTJGJTVCdGVhbSU1RCUyRiU3RSUyRmFpJTJGYXBpLWtleXNgO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb250ZXh0dWFsTWVzc2FnZSA9IGBBSSBHYXRld2F5IGF1dGhlbnRpY2F0aW9uIGZhaWxlZDogTm8gYXV0aGVudGljYXRpb24gcHJvdmlkZWQuXG5cbk9wdGlvbiAxIC0gQVBJIGtleTpcbkNyZWF0ZSBhbiBBUEkga2V5OiBodHRwczovL3ZlcmNlbC5jb20vZD90bz0lMkYlNUJ0ZWFtJTVEJTJGJTdFJTJGYWklMkZhcGkta2V5c1xuUHJvdmlkZSB2aWEgJ2FwaUtleScgb3B0aW9uIG9yICdBSV9HQVRFV0FZX0FQSV9LRVknIGVudmlyb25tZW50IHZhcmlhYmxlLlxuXG5PcHRpb24gMiAtIE9JREMgdG9rZW46XG5SdW4gJ25weCB2ZXJjZWwgbGluaycgdG8gbGluayB5b3VyIHByb2plY3QsIHRoZW4gJ3ZjIGVudiBwdWxsJyB0byBmZXRjaCB0aGUgdG9rZW4uYDtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IEdhdGV3YXlBdXRoZW50aWNhdGlvbkVycm9yKHtcbiAgICAgIG1lc3NhZ2U6IGNvbnRleHR1YWxNZXNzYWdlLFxuICAgICAgc3RhdHVzQ29kZSxcbiAgICAgIGNhdXNlLFxuICAgIH0pO1xuICB9XG59XG4iLCAiaW1wb3J0IHsgR2F0ZXdheUVycm9yIH0gZnJvbSAnLi9nYXRld2F5LWVycm9yJztcblxuY29uc3QgbmFtZSA9ICdHYXRld2F5SW52YWxpZFJlcXVlc3RFcnJvcic7XG5jb25zdCBtYXJrZXIgPSBgdmVyY2VsLmFpLmdhdGV3YXkuZXJyb3IuJHtuYW1lfWA7XG5jb25zdCBzeW1ib2wgPSBTeW1ib2wuZm9yKG1hcmtlcik7XG5cbi8qKlxuICogSW52YWxpZCByZXF1ZXN0IC0gbWlzc2luZyBoZWFkZXJzLCBtYWxmb3JtZWQgZGF0YSwgZXRjLlxuICovXG5leHBvcnQgY2xhc3MgR2F0ZXdheUludmFsaWRSZXF1ZXN0RXJyb3IgZXh0ZW5kcyBHYXRld2F5RXJyb3Ige1xuICBwcml2YXRlIHJlYWRvbmx5IFtzeW1ib2xdID0gdHJ1ZTsgLy8gdXNlZCBpbiBpc0luc3RhbmNlXG5cbiAgcmVhZG9ubHkgbmFtZSA9IG5hbWU7XG4gIHJlYWRvbmx5IHR5cGUgPSAnaW52YWxpZF9yZXF1ZXN0X2Vycm9yJztcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgbWVzc2FnZSA9ICdJbnZhbGlkIHJlcXVlc3QnLFxuICAgIHN0YXR1c0NvZGUgPSA0MDAsXG4gICAgY2F1c2UsXG4gIH06IHtcbiAgICBtZXNzYWdlPzogc3RyaW5nO1xuICAgIHN0YXR1c0NvZGU/OiBudW1iZXI7XG4gICAgY2F1c2U/OiB1bmtub3duO1xuICB9ID0ge30pIHtcbiAgICBzdXBlcih7IG1lc3NhZ2UsIHN0YXR1c0NvZGUsIGNhdXNlIH0pO1xuICB9XG5cbiAgc3RhdGljIGlzSW5zdGFuY2UoZXJyb3I6IHVua25vd24pOiBlcnJvciBpcyBHYXRld2F5SW52YWxpZFJlcXVlc3RFcnJvciB7XG4gICAgcmV0dXJuIEdhdGV3YXlFcnJvci5oYXNNYXJrZXIoZXJyb3IpICYmIHN5bWJvbCBpbiBlcnJvcjtcbiAgfVxufVxuIiwgImltcG9ydCB7IEdhdGV3YXlFcnJvciB9IGZyb20gJy4vZ2F0ZXdheS1lcnJvcic7XG5cbmNvbnN0IG5hbWUgPSAnR2F0ZXdheVJhdGVMaW1pdEVycm9yJztcbmNvbnN0IG1hcmtlciA9IGB2ZXJjZWwuYWkuZ2F0ZXdheS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuLyoqXG4gKiBSYXRlIGxpbWl0IGV4Y2VlZGVkLlxuICovXG5leHBvcnQgY2xhc3MgR2F0ZXdheVJhdGVMaW1pdEVycm9yIGV4dGVuZHMgR2F0ZXdheUVycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7IC8vIHVzZWQgaW4gaXNJbnN0YW5jZVxuXG4gIHJlYWRvbmx5IG5hbWUgPSBuYW1lO1xuICByZWFkb25seSB0eXBlID0gJ3JhdGVfbGltaXRfZXhjZWVkZWQnO1xuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICBtZXNzYWdlID0gJ1JhdGUgbGltaXQgZXhjZWVkZWQnLFxuICAgIHN0YXR1c0NvZGUgPSA0MjksXG4gICAgY2F1c2UsXG4gIH06IHtcbiAgICBtZXNzYWdlPzogc3RyaW5nO1xuICAgIHN0YXR1c0NvZGU/OiBudW1iZXI7XG4gICAgY2F1c2U/OiB1bmtub3duO1xuICB9ID0ge30pIHtcbiAgICBzdXBlcih7IG1lc3NhZ2UsIHN0YXR1c0NvZGUsIGNhdXNlIH0pO1xuICB9XG5cbiAgc3RhdGljIGlzSW5zdGFuY2UoZXJyb3I6IHVua25vd24pOiBlcnJvciBpcyBHYXRld2F5UmF0ZUxpbWl0RXJyb3Ige1xuICAgIHJldHVybiBHYXRld2F5RXJyb3IuaGFzTWFya2VyKGVycm9yKSAmJiBzeW1ib2wgaW4gZXJyb3I7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyB6IH0gZnJvbSAnem9kL3Y0JztcbmltcG9ydCB7IEdhdGV3YXlFcnJvciB9IGZyb20gJy4vZ2F0ZXdheS1lcnJvcic7XG5pbXBvcnQgeyBsYXp5VmFsaWRhdG9yLCB6b2RTY2hlbWEgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyLXV0aWxzJztcblxuY29uc3QgbmFtZSA9ICdHYXRld2F5TW9kZWxOb3RGb3VuZEVycm9yJztcbmNvbnN0IG1hcmtlciA9IGB2ZXJjZWwuYWkuZ2F0ZXdheS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuZXhwb3J0IGNvbnN0IG1vZGVsTm90Rm91bmRQYXJhbVNjaGVtYSA9IGxhenlWYWxpZGF0b3IoKCkgPT5cbiAgem9kU2NoZW1hKFxuICAgIHoub2JqZWN0KHtcbiAgICAgIG1vZGVsSWQ6IHouc3RyaW5nKCksXG4gICAgfSksXG4gICksXG4pO1xuXG4vKipcbiAqIE1vZGVsIG5vdCBmb3VuZCBvciBub3QgYXZhaWxhYmxlXG4gKi9cbmV4cG9ydCBjbGFzcyBHYXRld2F5TW9kZWxOb3RGb3VuZEVycm9yIGV4dGVuZHMgR2F0ZXdheUVycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7IC8vIHVzZWQgaW4gaXNJbnN0YW5jZVxuXG4gIHJlYWRvbmx5IG5hbWUgPSBuYW1lO1xuICByZWFkb25seSB0eXBlID0gJ21vZGVsX25vdF9mb3VuZCc7XG4gIHJlYWRvbmx5IG1vZGVsSWQ/OiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIG1lc3NhZ2UgPSAnTW9kZWwgbm90IGZvdW5kJyxcbiAgICBzdGF0dXNDb2RlID0gNDA0LFxuICAgIG1vZGVsSWQsXG4gICAgY2F1c2UsXG4gIH06IHtcbiAgICBtZXNzYWdlPzogc3RyaW5nO1xuICAgIHN0YXR1c0NvZGU/OiBudW1iZXI7XG4gICAgbW9kZWxJZD86IHN0cmluZztcbiAgICBjYXVzZT86IHVua25vd247XG4gIH0gPSB7fSkge1xuICAgIHN1cGVyKHsgbWVzc2FnZSwgc3RhdHVzQ29kZSwgY2F1c2UgfSk7XG4gICAgdGhpcy5tb2RlbElkID0gbW9kZWxJZDtcbiAgfVxuXG4gIHN0YXRpYyBpc0luc3RhbmNlKGVycm9yOiB1bmtub3duKTogZXJyb3IgaXMgR2F0ZXdheU1vZGVsTm90Rm91bmRFcnJvciB7XG4gICAgcmV0dXJuIEdhdGV3YXlFcnJvci5oYXNNYXJrZXIoZXJyb3IpICYmIHN5bWJvbCBpbiBlcnJvcjtcbiAgfVxufVxuIiwgImltcG9ydCB7IEdhdGV3YXlFcnJvciB9IGZyb20gJy4vZ2F0ZXdheS1lcnJvcic7XG5cbmNvbnN0IG5hbWUgPSAnR2F0ZXdheUludGVybmFsU2VydmVyRXJyb3InO1xuY29uc3QgbWFya2VyID0gYHZlcmNlbC5haS5nYXRld2F5LmVycm9yLiR7bmFtZX1gO1xuY29uc3Qgc3ltYm9sID0gU3ltYm9sLmZvcihtYXJrZXIpO1xuXG4vKipcbiAqIEludGVybmFsIHNlcnZlciBlcnJvciBmcm9tIHRoZSBHYXRld2F5XG4gKi9cbmV4cG9ydCBjbGFzcyBHYXRld2F5SW50ZXJuYWxTZXJ2ZXJFcnJvciBleHRlbmRzIEdhdGV3YXlFcnJvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgW3N5bWJvbF0gPSB0cnVlOyAvLyB1c2VkIGluIGlzSW5zdGFuY2VcblxuICByZWFkb25seSBuYW1lID0gbmFtZTtcbiAgcmVhZG9ubHkgdHlwZSA9ICdpbnRlcm5hbF9zZXJ2ZXJfZXJyb3InO1xuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICBtZXNzYWdlID0gJ0ludGVybmFsIHNlcnZlciBlcnJvcicsXG4gICAgc3RhdHVzQ29kZSA9IDUwMCxcbiAgICBjYXVzZSxcbiAgfToge1xuICAgIG1lc3NhZ2U/OiBzdHJpbmc7XG4gICAgc3RhdHVzQ29kZT86IG51bWJlcjtcbiAgICBjYXVzZT86IHVua25vd247XG4gIH0gPSB7fSkge1xuICAgIHN1cGVyKHsgbWVzc2FnZSwgc3RhdHVzQ29kZSwgY2F1c2UgfSk7XG4gIH1cblxuICBzdGF0aWMgaXNJbnN0YW5jZShlcnJvcjogdW5rbm93bik6IGVycm9yIGlzIEdhdGV3YXlJbnRlcm5hbFNlcnZlckVycm9yIHtcbiAgICByZXR1cm4gR2F0ZXdheUVycm9yLmhhc01hcmtlcihlcnJvcikgJiYgc3ltYm9sIGluIGVycm9yO1xuICB9XG59XG4iLCAiaW1wb3J0IHsgVHlwZVZhbGlkYXRpb25FcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgR2F0ZXdheUVycm9yIH0gZnJvbSAnLi9nYXRld2F5LWVycm9yJztcblxuY29uc3QgbmFtZSA9ICdHYXRld2F5UmVzcG9uc2VFcnJvcic7XG5jb25zdCBtYXJrZXIgPSBgdmVyY2VsLmFpLmdhdGV3YXkuZXJyb3IuJHtuYW1lfWA7XG5jb25zdCBzeW1ib2wgPSBTeW1ib2wuZm9yKG1hcmtlcik7XG5cbi8qKlxuICogR2F0ZXdheSByZXNwb25zZSBwYXJzaW5nIGVycm9yXG4gKi9cbmV4cG9ydCBjbGFzcyBHYXRld2F5UmVzcG9uc2VFcnJvciBleHRlbmRzIEdhdGV3YXlFcnJvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgW3N5bWJvbF0gPSB0cnVlOyAvLyB1c2VkIGluIGlzSW5zdGFuY2VcblxuICByZWFkb25seSBuYW1lID0gbmFtZTtcbiAgcmVhZG9ubHkgdHlwZSA9ICdyZXNwb25zZV9lcnJvcic7XG4gIHJlYWRvbmx5IHJlc3BvbnNlPzogdW5rbm93bjtcbiAgcmVhZG9ubHkgdmFsaWRhdGlvbkVycm9yPzogVHlwZVZhbGlkYXRpb25FcnJvcjtcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgbWVzc2FnZSA9ICdJbnZhbGlkIHJlc3BvbnNlIGZyb20gR2F0ZXdheScsXG4gICAgc3RhdHVzQ29kZSA9IDUwMixcbiAgICByZXNwb25zZSxcbiAgICB2YWxpZGF0aW9uRXJyb3IsXG4gICAgY2F1c2UsXG4gIH06IHtcbiAgICBtZXNzYWdlPzogc3RyaW5nO1xuICAgIHN0YXR1c0NvZGU/OiBudW1iZXI7XG4gICAgcmVzcG9uc2U/OiB1bmtub3duO1xuICAgIHZhbGlkYXRpb25FcnJvcj86IFR5cGVWYWxpZGF0aW9uRXJyb3I7XG4gICAgY2F1c2U/OiB1bmtub3duO1xuICB9ID0ge30pIHtcbiAgICBzdXBlcih7IG1lc3NhZ2UsIHN0YXR1c0NvZGUsIGNhdXNlIH0pO1xuICAgIHRoaXMucmVzcG9uc2UgPSByZXNwb25zZTtcbiAgICB0aGlzLnZhbGlkYXRpb25FcnJvciA9IHZhbGlkYXRpb25FcnJvcjtcbiAgfVxuXG4gIHN0YXRpYyBpc0luc3RhbmNlKGVycm9yOiB1bmtub3duKTogZXJyb3IgaXMgR2F0ZXdheVJlc3BvbnNlRXJyb3Ige1xuICAgIHJldHVybiBHYXRld2F5RXJyb3IuaGFzTWFya2VyKGVycm9yKSAmJiBzeW1ib2wgaW4gZXJyb3I7XG4gIH1cbn1cbiIsICJpbXBvcnQgdHlwZSB7IEFQSUNhbGxFcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdEFwaUNhbGxSZXNwb25zZShlcnJvcjogQVBJQ2FsbEVycm9yKTogdW5rbm93biB7XG4gIGlmIChlcnJvci5kYXRhICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gZXJyb3IuZGF0YTtcbiAgfVxuICBpZiAoZXJyb3IucmVzcG9uc2VCb2R5ICE9IG51bGwpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIEpTT04ucGFyc2UoZXJyb3IucmVzcG9uc2VCb2R5KTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBlcnJvci5yZXNwb25zZUJvZHk7XG4gICAgfVxuICB9XG4gIHJldHVybiB7fTtcbn1cbiIsICJpbXBvcnQgeyB6IH0gZnJvbSAnem9kL3Y0JztcbmltcG9ydCB7XG4gIGxhenlWYWxpZGF0b3IsXG4gIHNhZmVWYWxpZGF0ZVR5cGVzLFxuICB6b2RTY2hlbWEsXG59IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXItdXRpbHMnO1xuXG5leHBvcnQgY29uc3QgR0FURVdBWV9BVVRIX01FVEhPRF9IRUFERVIgPSAnYWktZ2F0ZXdheS1hdXRoLW1ldGhvZCcgYXMgY29uc3Q7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwYXJzZUF1dGhNZXRob2QoXG4gIGhlYWRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD4sXG4pIHtcbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc2FmZVZhbGlkYXRlVHlwZXMoe1xuICAgIHZhbHVlOiBoZWFkZXJzW0dBVEVXQVlfQVVUSF9NRVRIT0RfSEVBREVSXSxcbiAgICBzY2hlbWE6IGdhdGV3YXlBdXRoTWV0aG9kU2NoZW1hLFxuICB9KTtcblxuICByZXR1cm4gcmVzdWx0LnN1Y2Nlc3MgPyByZXN1bHQudmFsdWUgOiB1bmRlZmluZWQ7XG59XG5cbmNvbnN0IGdhdGV3YXlBdXRoTWV0aG9kU2NoZW1hID0gbGF6eVZhbGlkYXRvcigoKSA9PlxuICB6b2RTY2hlbWEoei51bmlvbihbei5saXRlcmFsKCdhcGkta2V5JyksIHoubGl0ZXJhbCgnb2lkYycpXSkpLFxuKTtcbiIsICJpbXBvcnQge1xuICBjcmVhdGVKc29uRXJyb3JSZXNwb25zZUhhbmRsZXIsXG4gIGNyZWF0ZUpzb25SZXNwb25zZUhhbmRsZXIsXG4gIGdldEZyb21BcGksXG4gIGxhenlWYWxpZGF0b3IsXG4gIHJlc29sdmUsXG4gIHpvZFNjaGVtYSxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyB6IH0gZnJvbSAnem9kL3Y0JztcbmltcG9ydCB7IGFzR2F0ZXdheUVycm9yIH0gZnJvbSAnLi9lcnJvcnMnO1xuaW1wb3J0IHR5cGUgeyBHYXRld2F5Q29uZmlnIH0gZnJvbSAnLi9nYXRld2F5LWNvbmZpZyc7XG5pbXBvcnQgdHlwZSB7IEdhdGV3YXlMYW5ndWFnZU1vZGVsRW50cnkgfSBmcm9tICcuL2dhdGV3YXktbW9kZWwtZW50cnknO1xuXG50eXBlIEdhdGV3YXlGZXRjaE1ldGFkYXRhQ29uZmlnID0gR2F0ZXdheUNvbmZpZztcblxuZXhwb3J0IGludGVyZmFjZSBHYXRld2F5RmV0Y2hNZXRhZGF0YVJlc3BvbnNlIHtcbiAgbW9kZWxzOiBHYXRld2F5TGFuZ3VhZ2VNb2RlbEVudHJ5W107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2F0ZXdheUNyZWRpdHNSZXNwb25zZSB7XG4gIC8qKiBUaGUgcmVtYWluaW5nIGdhdGV3YXkgY3JlZGl0IGJhbGFuY2UgYXZhaWxhYmxlIGZvciBBUEkgdXNhZ2UgKi9cbiAgYmFsYW5jZTogc3RyaW5nO1xuICAvKiogVGhlIHRvdGFsIGFtb3VudCBvZiBnYXRld2F5IGNyZWRpdHMgdGhhdCBoYXZlIGJlZW4gY29uc3VtZWQgKi9cbiAgdG90YWxVc2VkOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBHYXRld2F5RmV0Y2hNZXRhZGF0YSB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgY29uZmlnOiBHYXRld2F5RmV0Y2hNZXRhZGF0YUNvbmZpZykge31cblxuICBhc3luYyBnZXRBdmFpbGFibGVNb2RlbHMoKTogUHJvbWlzZTxHYXRld2F5RmV0Y2hNZXRhZGF0YVJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHsgdmFsdWUgfSA9IGF3YWl0IGdldEZyb21BcGkoe1xuICAgICAgICB1cmw6IGAke3RoaXMuY29uZmlnLmJhc2VVUkx9L2NvbmZpZ2AsXG4gICAgICAgIGhlYWRlcnM6IGF3YWl0IHJlc29sdmUodGhpcy5jb25maWcuaGVhZGVycygpKSxcbiAgICAgICAgc3VjY2Vzc2Z1bFJlc3BvbnNlSGFuZGxlcjogY3JlYXRlSnNvblJlc3BvbnNlSGFuZGxlcihcbiAgICAgICAgICBnYXRld2F5QXZhaWxhYmxlTW9kZWxzUmVzcG9uc2VTY2hlbWEsXG4gICAgICAgICksXG4gICAgICAgIGZhaWxlZFJlc3BvbnNlSGFuZGxlcjogY3JlYXRlSnNvbkVycm9yUmVzcG9uc2VIYW5kbGVyKHtcbiAgICAgICAgICBlcnJvclNjaGVtYTogei5hbnkoKSxcbiAgICAgICAgICBlcnJvclRvTWVzc2FnZTogZGF0YSA9PiBkYXRhLFxuICAgICAgICB9KSxcbiAgICAgICAgZmV0Y2g6IHRoaXMuY29uZmlnLmZldGNoLFxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgYXdhaXQgYXNHYXRld2F5RXJyb3IoZXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGdldENyZWRpdHMoKTogUHJvbWlzZTxHYXRld2F5Q3JlZGl0c1Jlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGJhc2VVcmwgPSBuZXcgVVJMKHRoaXMuY29uZmlnLmJhc2VVUkwpO1xuXG4gICAgICBjb25zdCB7IHZhbHVlIH0gPSBhd2FpdCBnZXRGcm9tQXBpKHtcbiAgICAgICAgdXJsOiBgJHtiYXNlVXJsLm9yaWdpbn0vdjEvY3JlZGl0c2AsXG4gICAgICAgIGhlYWRlcnM6IGF3YWl0IHJlc29sdmUodGhpcy5jb25maWcuaGVhZGVycygpKSxcbiAgICAgICAgc3VjY2Vzc2Z1bFJlc3BvbnNlSGFuZGxlcjogY3JlYXRlSnNvblJlc3BvbnNlSGFuZGxlcihcbiAgICAgICAgICBnYXRld2F5Q3JlZGl0c1Jlc3BvbnNlU2NoZW1hLFxuICAgICAgICApLFxuICAgICAgICBmYWlsZWRSZXNwb25zZUhhbmRsZXI6IGNyZWF0ZUpzb25FcnJvclJlc3BvbnNlSGFuZGxlcih7XG4gICAgICAgICAgZXJyb3JTY2hlbWE6IHouYW55KCksXG4gICAgICAgICAgZXJyb3JUb01lc3NhZ2U6IGRhdGEgPT4gZGF0YSxcbiAgICAgICAgfSksXG4gICAgICAgIGZldGNoOiB0aGlzLmNvbmZpZy5mZXRjaCxcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRocm93IGF3YWl0IGFzR2F0ZXdheUVycm9yKGVycm9yKTtcbiAgICB9XG4gIH1cbn1cblxuY29uc3QgZ2F0ZXdheUF2YWlsYWJsZU1vZGVsc1Jlc3BvbnNlU2NoZW1hID0gbGF6eVZhbGlkYXRvcigoKSA9PlxuICB6b2RTY2hlbWEoXG4gICAgei5vYmplY3Qoe1xuICAgICAgbW9kZWxzOiB6LmFycmF5KFxuICAgICAgICB6Lm9iamVjdCh7XG4gICAgICAgICAgaWQ6IHouc3RyaW5nKCksXG4gICAgICAgICAgbmFtZTogei5zdHJpbmcoKSxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogei5zdHJpbmcoKS5udWxsaXNoKCksXG4gICAgICAgICAgcHJpY2luZzogelxuICAgICAgICAgICAgLm9iamVjdCh7XG4gICAgICAgICAgICAgIGlucHV0OiB6LnN0cmluZygpLFxuICAgICAgICAgICAgICBvdXRwdXQ6IHouc3RyaW5nKCksXG4gICAgICAgICAgICAgIGlucHV0X2NhY2hlX3JlYWQ6IHouc3RyaW5nKCkubnVsbGlzaCgpLFxuICAgICAgICAgICAgICBpbnB1dF9jYWNoZV93cml0ZTogei5zdHJpbmcoKS5udWxsaXNoKCksXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLnRyYW5zZm9ybShcbiAgICAgICAgICAgICAgKHsgaW5wdXQsIG91dHB1dCwgaW5wdXRfY2FjaGVfcmVhZCwgaW5wdXRfY2FjaGVfd3JpdGUgfSkgPT4gKHtcbiAgICAgICAgICAgICAgICBpbnB1dCxcbiAgICAgICAgICAgICAgICBvdXRwdXQsXG4gICAgICAgICAgICAgICAgLi4uKGlucHV0X2NhY2hlX3JlYWRcbiAgICAgICAgICAgICAgICAgID8geyBjYWNoZWRJbnB1dFRva2VuczogaW5wdXRfY2FjaGVfcmVhZCB9XG4gICAgICAgICAgICAgICAgICA6IHt9KSxcbiAgICAgICAgICAgICAgICAuLi4oaW5wdXRfY2FjaGVfd3JpdGVcbiAgICAgICAgICAgICAgICAgID8geyBjYWNoZUNyZWF0aW9uSW5wdXRUb2tlbnM6IGlucHV0X2NhY2hlX3dyaXRlIH1cbiAgICAgICAgICAgICAgICAgIDoge30pLFxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIC5udWxsaXNoKCksXG4gICAgICAgICAgc3BlY2lmaWNhdGlvbjogei5vYmplY3Qoe1xuICAgICAgICAgICAgc3BlY2lmaWNhdGlvblZlcnNpb246IHoubGl0ZXJhbCgndjInKSxcbiAgICAgICAgICAgIHByb3ZpZGVyOiB6LnN0cmluZygpLFxuICAgICAgICAgICAgbW9kZWxJZDogei5zdHJpbmcoKSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBtb2RlbFR5cGU6IHouZW51bShbJ2xhbmd1YWdlJywgJ2VtYmVkZGluZycsICdpbWFnZSddKS5udWxsaXNoKCksXG4gICAgICAgIH0pLFxuICAgICAgKSxcbiAgICB9KSxcbiAgKSxcbik7XG5cbmNvbnN0IGdhdGV3YXlDcmVkaXRzUmVzcG9uc2VTY2hlbWEgPSBsYXp5VmFsaWRhdG9yKCgpID0+XG4gIHpvZFNjaGVtYShcbiAgICB6XG4gICAgICAub2JqZWN0KHtcbiAgICAgICAgYmFsYW5jZTogei5zdHJpbmcoKSxcbiAgICAgICAgdG90YWxfdXNlZDogei5zdHJpbmcoKSxcbiAgICAgIH0pXG4gICAgICAudHJhbnNmb3JtKCh7IGJhbGFuY2UsIHRvdGFsX3VzZWQgfSkgPT4gKHtcbiAgICAgICAgYmFsYW5jZSxcbiAgICAgICAgdG90YWxVc2VkOiB0b3RhbF91c2VkLFxuICAgICAgfSkpLFxuICApLFxuKTtcbiIsICJpbXBvcnQgdHlwZSB7XG4gIExhbmd1YWdlTW9kZWxWMixcbiAgTGFuZ3VhZ2VNb2RlbFYyQ2FsbE9wdGlvbnMsXG4gIExhbmd1YWdlTW9kZWxWMkNhbGxXYXJuaW5nLFxuICBMYW5ndWFnZU1vZGVsVjJGaWxlUGFydCxcbiAgTGFuZ3VhZ2VNb2RlbFYyU3RyZWFtUGFydCxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQge1xuICBjb21iaW5lSGVhZGVycyxcbiAgY3JlYXRlRXZlbnRTb3VyY2VSZXNwb25zZUhhbmRsZXIsXG4gIGNyZWF0ZUpzb25FcnJvclJlc3BvbnNlSGFuZGxlcixcbiAgY3JlYXRlSnNvblJlc3BvbnNlSGFuZGxlcixcbiAgcG9zdEpzb25Ub0FwaSxcbiAgcmVzb2x2ZSxcbiAgdHlwZSBQYXJzZVJlc3VsdCxcbiAgdHlwZSBSZXNvbHZhYmxlLFxufSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyLXV0aWxzJztcbmltcG9ydCB7IHogfSBmcm9tICd6b2QvdjQnO1xuaW1wb3J0IHR5cGUgeyBHYXRld2F5Q29uZmlnIH0gZnJvbSAnLi9nYXRld2F5LWNvbmZpZyc7XG5pbXBvcnQgdHlwZSB7IEdhdGV3YXlNb2RlbElkIH0gZnJvbSAnLi9nYXRld2F5LWxhbmd1YWdlLW1vZGVsLXNldHRpbmdzJztcbmltcG9ydCB7IGFzR2F0ZXdheUVycm9yIH0gZnJvbSAnLi9lcnJvcnMnO1xuaW1wb3J0IHsgcGFyc2VBdXRoTWV0aG9kIH0gZnJvbSAnLi9lcnJvcnMvcGFyc2UtYXV0aC1tZXRob2QnO1xuXG50eXBlIEdhdGV3YXlDaGF0Q29uZmlnID0gR2F0ZXdheUNvbmZpZyAmIHtcbiAgcHJvdmlkZXI6IHN0cmluZztcbiAgbzExeUhlYWRlcnM6IFJlc29sdmFibGU8UmVjb3JkPHN0cmluZywgc3RyaW5nPj47XG59O1xuXG5leHBvcnQgY2xhc3MgR2F0ZXdheUxhbmd1YWdlTW9kZWwgaW1wbGVtZW50cyBMYW5ndWFnZU1vZGVsVjIge1xuICByZWFkb25seSBzcGVjaWZpY2F0aW9uVmVyc2lvbiA9ICd2Mic7XG4gIHJlYWRvbmx5IHN1cHBvcnRlZFVybHMgPSB7ICcqLyonOiBbLy4qL10gfTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICByZWFkb25seSBtb2RlbElkOiBHYXRld2F5TW9kZWxJZCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNvbmZpZzogR2F0ZXdheUNoYXRDb25maWcsXG4gICkge31cblxuICBnZXQgcHJvdmlkZXIoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5jb25maWcucHJvdmlkZXI7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGdldEFyZ3Mob3B0aW9uczogUGFyYW1ldGVyczxMYW5ndWFnZU1vZGVsVjJbJ2RvR2VuZXJhdGUnXT5bMF0pIHtcbiAgICBjb25zdCB7IGFib3J0U2lnbmFsOiBfYWJvcnRTaWduYWwsIC4uLm9wdGlvbnNXaXRob3V0U2lnbmFsIH0gPSBvcHRpb25zO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGFyZ3M6IHRoaXMubWF5YmVFbmNvZGVGaWxlUGFydHMob3B0aW9uc1dpdGhvdXRTaWduYWwpLFxuICAgICAgd2FybmluZ3M6IFtdLFxuICAgIH07XG4gIH1cblxuICBhc3luYyBkb0dlbmVyYXRlKFxuICAgIG9wdGlvbnM6IFBhcmFtZXRlcnM8TGFuZ3VhZ2VNb2RlbFYyWydkb0dlbmVyYXRlJ10+WzBdLFxuICApOiBQcm9taXNlPEF3YWl0ZWQ8UmV0dXJuVHlwZTxMYW5ndWFnZU1vZGVsVjJbJ2RvR2VuZXJhdGUnXT4+PiB7XG4gICAgY29uc3QgeyBhcmdzLCB3YXJuaW5ncyB9ID0gYXdhaXQgdGhpcy5nZXRBcmdzKG9wdGlvbnMpO1xuICAgIGNvbnN0IHsgYWJvcnRTaWduYWwgfSA9IG9wdGlvbnM7XG5cbiAgICBjb25zdCByZXNvbHZlZEhlYWRlcnMgPSBhd2FpdCByZXNvbHZlKHRoaXMuY29uZmlnLmhlYWRlcnMoKSk7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3Qge1xuICAgICAgICByZXNwb25zZUhlYWRlcnMsXG4gICAgICAgIHZhbHVlOiByZXNwb25zZUJvZHksXG4gICAgICAgIHJhd1ZhbHVlOiByYXdSZXNwb25zZSxcbiAgICAgIH0gPSBhd2FpdCBwb3N0SnNvblRvQXBpKHtcbiAgICAgICAgdXJsOiB0aGlzLmdldFVybCgpLFxuICAgICAgICBoZWFkZXJzOiBjb21iaW5lSGVhZGVycyhcbiAgICAgICAgICByZXNvbHZlZEhlYWRlcnMsXG4gICAgICAgICAgb3B0aW9ucy5oZWFkZXJzLFxuICAgICAgICAgIHRoaXMuZ2V0TW9kZWxDb25maWdIZWFkZXJzKHRoaXMubW9kZWxJZCwgZmFsc2UpLFxuICAgICAgICAgIGF3YWl0IHJlc29sdmUodGhpcy5jb25maWcubzExeUhlYWRlcnMpLFxuICAgICAgICApLFxuICAgICAgICBib2R5OiBhcmdzLFxuICAgICAgICBzdWNjZXNzZnVsUmVzcG9uc2VIYW5kbGVyOiBjcmVhdGVKc29uUmVzcG9uc2VIYW5kbGVyKHouYW55KCkpLFxuICAgICAgICBmYWlsZWRSZXNwb25zZUhhbmRsZXI6IGNyZWF0ZUpzb25FcnJvclJlc3BvbnNlSGFuZGxlcih7XG4gICAgICAgICAgZXJyb3JTY2hlbWE6IHouYW55KCksXG4gICAgICAgICAgZXJyb3JUb01lc3NhZ2U6IGRhdGEgPT4gZGF0YSxcbiAgICAgICAgfSksXG4gICAgICAgIC4uLihhYm9ydFNpZ25hbCAmJiB7IGFib3J0U2lnbmFsIH0pLFxuICAgICAgICBmZXRjaDogdGhpcy5jb25maWcuZmV0Y2gsXG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ucmVzcG9uc2VCb2R5LFxuICAgICAgICByZXF1ZXN0OiB7IGJvZHk6IGFyZ3MgfSxcbiAgICAgICAgcmVzcG9uc2U6IHsgaGVhZGVyczogcmVzcG9uc2VIZWFkZXJzLCBib2R5OiByYXdSZXNwb25zZSB9LFxuICAgICAgICB3YXJuaW5ncyxcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRocm93IGF3YWl0IGFzR2F0ZXdheUVycm9yKGVycm9yLCBhd2FpdCBwYXJzZUF1dGhNZXRob2QocmVzb2x2ZWRIZWFkZXJzKSk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZG9TdHJlYW0oXG4gICAgb3B0aW9uczogUGFyYW1ldGVyczxMYW5ndWFnZU1vZGVsVjJbJ2RvU3RyZWFtJ10+WzBdLFxuICApOiBQcm9taXNlPEF3YWl0ZWQ8UmV0dXJuVHlwZTxMYW5ndWFnZU1vZGVsVjJbJ2RvU3RyZWFtJ10+Pj4ge1xuICAgIGNvbnN0IHsgYXJncywgd2FybmluZ3MgfSA9IGF3YWl0IHRoaXMuZ2V0QXJncyhvcHRpb25zKTtcbiAgICBjb25zdCB7IGFib3J0U2lnbmFsIH0gPSBvcHRpb25zO1xuXG4gICAgY29uc3QgcmVzb2x2ZWRIZWFkZXJzID0gYXdhaXQgcmVzb2x2ZSh0aGlzLmNvbmZpZy5oZWFkZXJzKCkpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHsgdmFsdWU6IHJlc3BvbnNlLCByZXNwb25zZUhlYWRlcnMgfSA9IGF3YWl0IHBvc3RKc29uVG9BcGkoe1xuICAgICAgICB1cmw6IHRoaXMuZ2V0VXJsKCksXG4gICAgICAgIGhlYWRlcnM6IGNvbWJpbmVIZWFkZXJzKFxuICAgICAgICAgIHJlc29sdmVkSGVhZGVycyxcbiAgICAgICAgICBvcHRpb25zLmhlYWRlcnMsXG4gICAgICAgICAgdGhpcy5nZXRNb2RlbENvbmZpZ0hlYWRlcnModGhpcy5tb2RlbElkLCB0cnVlKSxcbiAgICAgICAgICBhd2FpdCByZXNvbHZlKHRoaXMuY29uZmlnLm8xMXlIZWFkZXJzKSxcbiAgICAgICAgKSxcbiAgICAgICAgYm9keTogYXJncyxcbiAgICAgICAgc3VjY2Vzc2Z1bFJlc3BvbnNlSGFuZGxlcjogY3JlYXRlRXZlbnRTb3VyY2VSZXNwb25zZUhhbmRsZXIoei5hbnkoKSksXG4gICAgICAgIGZhaWxlZFJlc3BvbnNlSGFuZGxlcjogY3JlYXRlSnNvbkVycm9yUmVzcG9uc2VIYW5kbGVyKHtcbiAgICAgICAgICBlcnJvclNjaGVtYTogei5hbnkoKSxcbiAgICAgICAgICBlcnJvclRvTWVzc2FnZTogZGF0YSA9PiBkYXRhLFxuICAgICAgICB9KSxcbiAgICAgICAgLi4uKGFib3J0U2lnbmFsICYmIHsgYWJvcnRTaWduYWwgfSksXG4gICAgICAgIGZldGNoOiB0aGlzLmNvbmZpZy5mZXRjaCxcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBzdHJlYW06IHJlc3BvbnNlLnBpcGVUaHJvdWdoKFxuICAgICAgICAgIG5ldyBUcmFuc2Zvcm1TdHJlYW08XG4gICAgICAgICAgICBQYXJzZVJlc3VsdDxMYW5ndWFnZU1vZGVsVjJTdHJlYW1QYXJ0PixcbiAgICAgICAgICAgIExhbmd1YWdlTW9kZWxWMlN0cmVhbVBhcnRcbiAgICAgICAgICA+KHtcbiAgICAgICAgICAgIHN0YXJ0KGNvbnRyb2xsZXIpIHtcbiAgICAgICAgICAgICAgaWYgKHdhcm5pbmdzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoeyB0eXBlOiAnc3RyZWFtLXN0YXJ0Jywgd2FybmluZ3MgfSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0cmFuc2Zvcm0oY2h1bmssIGNvbnRyb2xsZXIpIHtcbiAgICAgICAgICAgICAgaWYgKGNodW5rLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW1QYXJ0ID0gY2h1bmsudmFsdWU7XG5cbiAgICAgICAgICAgICAgICAvLyBIYW5kbGUgcmF3IGNodW5rczogaWYgdGhpcyBpcyBhIHJhdyBjaHVuayBmcm9tIHRoZSBnYXRld2F5IEFQSSxcbiAgICAgICAgICAgICAgICAvLyBvbmx5IGVtaXQgaXQgaWYgaW5jbHVkZVJhd0NodW5rcyBpcyB0cnVlXG4gICAgICAgICAgICAgICAgaWYgKHN0cmVhbVBhcnQudHlwZSA9PT0gJ3JhdycgJiYgIW9wdGlvbnMuaW5jbHVkZVJhd0NodW5rcykge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuOyAvLyBTa2lwIHJhdyBjaHVua3MgaWYgbm90IHJlcXVlc3RlZFxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgIHN0cmVhbVBhcnQudHlwZSA9PT0gJ3Jlc3BvbnNlLW1ldGFkYXRhJyAmJlxuICAgICAgICAgICAgICAgICAgc3RyZWFtUGFydC50aW1lc3RhbXAgJiZcbiAgICAgICAgICAgICAgICAgIHR5cGVvZiBzdHJlYW1QYXJ0LnRpbWVzdGFtcCA9PT0gJ3N0cmluZydcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgIHN0cmVhbVBhcnQudGltZXN0YW1wID0gbmV3IERhdGUoc3RyZWFtUGFydC50aW1lc3RhbXApO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShzdHJlYW1QYXJ0KTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVycm9yKFxuICAgICAgICAgICAgICAgICAgKGNodW5rIGFzIHsgc3VjY2VzczogZmFsc2U7IGVycm9yOiB1bmtub3duIH0pLmVycm9yLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSksXG4gICAgICAgICksXG4gICAgICAgIHJlcXVlc3Q6IHsgYm9keTogYXJncyB9LFxuICAgICAgICByZXNwb25zZTogeyBoZWFkZXJzOiByZXNwb25zZUhlYWRlcnMgfSxcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRocm93IGF3YWl0IGFzR2F0ZXdheUVycm9yKGVycm9yLCBhd2FpdCBwYXJzZUF1dGhNZXRob2QocmVzb2x2ZWRIZWFkZXJzKSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBpc0ZpbGVQYXJ0KHBhcnQ6IHVua25vd24pIHtcbiAgICByZXR1cm4gKFxuICAgICAgcGFydCAmJiB0eXBlb2YgcGFydCA9PT0gJ29iamVjdCcgJiYgJ3R5cGUnIGluIHBhcnQgJiYgcGFydC50eXBlID09PSAnZmlsZSdcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEVuY29kZXMgZmlsZSBwYXJ0cyBpbiB0aGUgcHJvbXB0IHRvIGJhc2U2NC4gTXV0YXRlcyB0aGUgcGFzc2VkIG9wdGlvbnNcbiAgICogaW5zdGFuY2UgZGlyZWN0bHkgdG8gYXZvaWQgY29weWluZyB0aGUgZmlsZSBkYXRhLlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIFRoZSBvcHRpb25zIHRvIGVuY29kZS5cbiAgICogQHJldHVybnMgVGhlIG9wdGlvbnMgd2l0aCB0aGUgZmlsZSBwYXJ0cyBlbmNvZGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBtYXliZUVuY29kZUZpbGVQYXJ0cyhvcHRpb25zOiBMYW5ndWFnZU1vZGVsVjJDYWxsT3B0aW9ucykge1xuICAgIGZvciAoY29uc3QgbWVzc2FnZSBvZiBvcHRpb25zLnByb21wdCkge1xuICAgICAgZm9yIChjb25zdCBwYXJ0IG9mIG1lc3NhZ2UuY29udGVudCkge1xuICAgICAgICBpZiAodGhpcy5pc0ZpbGVQYXJ0KHBhcnQpKSB7XG4gICAgICAgICAgY29uc3QgZmlsZVBhcnQgPSBwYXJ0IGFzIExhbmd1YWdlTW9kZWxWMkZpbGVQYXJ0O1xuICAgICAgICAgIC8vIElmIHRoZSBmaWxlIHBhcnQgaXMgYSBVUkwgaXQgd2lsbCBnZXQgY2xlYW5seSBjb252ZXJ0ZWQgdG8gYSBzdHJpbmcuXG4gICAgICAgICAgLy8gSWYgaXQncyBhIGJpbmFyeSBmaWxlIGF0dGFjaG1lbnQgd2UgY29udmVydCBpdCB0byBhIGRhdGEgdXJsLlxuICAgICAgICAgIC8vIEluIGVpdGhlciBjYXNlLCBzZXJ2ZXItc2lkZSB3ZSBzaG91bGQgb25seSBldmVyIHNlZSBVUkxzIGFzIHN0cmluZ3MuXG4gICAgICAgICAgaWYgKGZpbGVQYXJ0LmRhdGEgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XG4gICAgICAgICAgICBjb25zdCBidWZmZXIgPSBVaW50OEFycmF5LmZyb20oZmlsZVBhcnQuZGF0YSk7XG4gICAgICAgICAgICBjb25zdCBiYXNlNjREYXRhID0gQnVmZmVyLmZyb20oYnVmZmVyKS50b1N0cmluZygnYmFzZTY0Jyk7XG4gICAgICAgICAgICBmaWxlUGFydC5kYXRhID0gbmV3IFVSTChcbiAgICAgICAgICAgICAgYGRhdGE6JHtmaWxlUGFydC5tZWRpYVR5cGUgfHwgJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSd9O2Jhc2U2NCwke2Jhc2U2NERhdGF9YCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvcHRpb25zO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRVcmwoKSB7XG4gICAgcmV0dXJuIGAke3RoaXMuY29uZmlnLmJhc2VVUkx9L2xhbmd1YWdlLW1vZGVsYDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0TW9kZWxDb25maWdIZWFkZXJzKG1vZGVsSWQ6IHN0cmluZywgc3RyZWFtaW5nOiBib29sZWFuKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICdhaS1sYW5ndWFnZS1tb2RlbC1zcGVjaWZpY2F0aW9uLXZlcnNpb24nOiAnMicsXG4gICAgICAnYWktbGFuZ3VhZ2UtbW9kZWwtaWQnOiBtb2RlbElkLFxuICAgICAgJ2FpLWxhbmd1YWdlLW1vZGVsLXN0cmVhbWluZyc6IFN0cmluZyhzdHJlYW1pbmcpLFxuICAgIH07XG4gIH1cbn1cbiIsICJpbXBvcnQgdHlwZSB7XG4gIEVtYmVkZGluZ01vZGVsVjIsXG4gIFNoYXJlZFYyUHJvdmlkZXJNZXRhZGF0YSxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQge1xuICBjb21iaW5lSGVhZGVycyxcbiAgY3JlYXRlSnNvbkVycm9yUmVzcG9uc2VIYW5kbGVyLFxuICBjcmVhdGVKc29uUmVzcG9uc2VIYW5kbGVyLFxuICBsYXp5VmFsaWRhdG9yLFxuICBwb3N0SnNvblRvQXBpLFxuICByZXNvbHZlLFxuICB6b2RTY2hlbWEsXG4gIHR5cGUgUmVzb2x2YWJsZSxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyB6IH0gZnJvbSAnem9kL3Y0JztcbmltcG9ydCB7IGFzR2F0ZXdheUVycm9yIH0gZnJvbSAnLi9lcnJvcnMnO1xuaW1wb3J0IHsgcGFyc2VBdXRoTWV0aG9kIH0gZnJvbSAnLi9lcnJvcnMvcGFyc2UtYXV0aC1tZXRob2QnO1xuaW1wb3J0IHR5cGUgeyBHYXRld2F5Q29uZmlnIH0gZnJvbSAnLi9nYXRld2F5LWNvbmZpZyc7XG5cbmV4cG9ydCBjbGFzcyBHYXRld2F5RW1iZWRkaW5nTW9kZWwgaW1wbGVtZW50cyBFbWJlZGRpbmdNb2RlbFYyPHN0cmluZz4ge1xuICByZWFkb25seSBzcGVjaWZpY2F0aW9uVmVyc2lvbiA9ICd2Mic7XG4gIHJlYWRvbmx5IG1heEVtYmVkZGluZ3NQZXJDYWxsID0gMjA0ODtcbiAgcmVhZG9ubHkgc3VwcG9ydHNQYXJhbGxlbENhbGxzID0gdHJ1ZTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICByZWFkb25seSBtb2RlbElkOiBzdHJpbmcsXG4gICAgcHJpdmF0ZSByZWFkb25seSBjb25maWc6IEdhdGV3YXlDb25maWcgJiB7XG4gICAgICBwcm92aWRlcjogc3RyaW5nO1xuICAgICAgbzExeUhlYWRlcnM6IFJlc29sdmFibGU8UmVjb3JkPHN0cmluZywgc3RyaW5nPj47XG4gICAgfSxcbiAgKSB7fVxuXG4gIGdldCBwcm92aWRlcigpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmNvbmZpZy5wcm92aWRlcjtcbiAgfVxuXG4gIGFzeW5jIGRvRW1iZWQoe1xuICAgIHZhbHVlcyxcbiAgICBoZWFkZXJzLFxuICAgIGFib3J0U2lnbmFsLFxuICAgIHByb3ZpZGVyT3B0aW9ucyxcbiAgfTogUGFyYW1ldGVyczxFbWJlZGRpbmdNb2RlbFYyPHN0cmluZz5bJ2RvRW1iZWQnXT5bMF0pOiBQcm9taXNlPFxuICAgIEF3YWl0ZWQ8UmV0dXJuVHlwZTxFbWJlZGRpbmdNb2RlbFYyPHN0cmluZz5bJ2RvRW1iZWQnXT4+XG4gID4ge1xuICAgIGNvbnN0IHJlc29sdmVkSGVhZGVycyA9IGF3YWl0IHJlc29sdmUodGhpcy5jb25maWcuaGVhZGVycygpKTtcbiAgICB0cnkge1xuICAgICAgY29uc3Qge1xuICAgICAgICByZXNwb25zZUhlYWRlcnMsXG4gICAgICAgIHZhbHVlOiByZXNwb25zZUJvZHksXG4gICAgICAgIHJhd1ZhbHVlLFxuICAgICAgfSA9IGF3YWl0IHBvc3RKc29uVG9BcGkoe1xuICAgICAgICB1cmw6IHRoaXMuZ2V0VXJsKCksXG4gICAgICAgIGhlYWRlcnM6IGNvbWJpbmVIZWFkZXJzKFxuICAgICAgICAgIHJlc29sdmVkSGVhZGVycyxcbiAgICAgICAgICBoZWFkZXJzID8/IHt9LFxuICAgICAgICAgIHRoaXMuZ2V0TW9kZWxDb25maWdIZWFkZXJzKCksXG4gICAgICAgICAgYXdhaXQgcmVzb2x2ZSh0aGlzLmNvbmZpZy5vMTF5SGVhZGVycyksXG4gICAgICAgICksXG4gICAgICAgIGJvZHk6IHtcbiAgICAgICAgICBpbnB1dDogdmFsdWVzLmxlbmd0aCA9PT0gMSA/IHZhbHVlc1swXSA6IHZhbHVlcyxcbiAgICAgICAgICAuLi4ocHJvdmlkZXJPcHRpb25zID8geyBwcm92aWRlck9wdGlvbnMgfSA6IHt9KSxcbiAgICAgICAgfSxcbiAgICAgICAgc3VjY2Vzc2Z1bFJlc3BvbnNlSGFuZGxlcjogY3JlYXRlSnNvblJlc3BvbnNlSGFuZGxlcihcbiAgICAgICAgICBnYXRld2F5RW1iZWRkaW5nUmVzcG9uc2VTY2hlbWEsXG4gICAgICAgICksXG4gICAgICAgIGZhaWxlZFJlc3BvbnNlSGFuZGxlcjogY3JlYXRlSnNvbkVycm9yUmVzcG9uc2VIYW5kbGVyKHtcbiAgICAgICAgICBlcnJvclNjaGVtYTogei5hbnkoKSxcbiAgICAgICAgICBlcnJvclRvTWVzc2FnZTogZGF0YSA9PiBkYXRhLFxuICAgICAgICB9KSxcbiAgICAgICAgLi4uKGFib3J0U2lnbmFsICYmIHsgYWJvcnRTaWduYWwgfSksXG4gICAgICAgIGZldGNoOiB0aGlzLmNvbmZpZy5mZXRjaCxcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBlbWJlZGRpbmdzOiByZXNwb25zZUJvZHkuZW1iZWRkaW5ncyxcbiAgICAgICAgdXNhZ2U6IHJlc3BvbnNlQm9keS51c2FnZSA/PyB1bmRlZmluZWQsXG4gICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6XG4gICAgICAgICAgcmVzcG9uc2VCb2R5LnByb3ZpZGVyTWV0YWRhdGEgYXMgdW5rbm93biBhcyBTaGFyZWRWMlByb3ZpZGVyTWV0YWRhdGEsXG4gICAgICAgIHJlc3BvbnNlOiB7IGhlYWRlcnM6IHJlc3BvbnNlSGVhZGVycywgYm9keTogcmF3VmFsdWUgfSxcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRocm93IGF3YWl0IGFzR2F0ZXdheUVycm9yKGVycm9yLCBhd2FpdCBwYXJzZUF1dGhNZXRob2QocmVzb2x2ZWRIZWFkZXJzKSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRVcmwoKSB7XG4gICAgcmV0dXJuIGAke3RoaXMuY29uZmlnLmJhc2VVUkx9L2VtYmVkZGluZy1tb2RlbGA7XG4gIH1cblxuICBwcml2YXRlIGdldE1vZGVsQ29uZmlnSGVhZGVycygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgJ2FpLWVtYmVkZGluZy1tb2RlbC1zcGVjaWZpY2F0aW9uLXZlcnNpb24nOiAnMicsXG4gICAgICAnYWktbW9kZWwtaWQnOiB0aGlzLm1vZGVsSWQsXG4gICAgfTtcbiAgfVxufVxuXG5jb25zdCBnYXRld2F5RW1iZWRkaW5nUmVzcG9uc2VTY2hlbWEgPSBsYXp5VmFsaWRhdG9yKCgpID0+XG4gIHpvZFNjaGVtYShcbiAgICB6Lm9iamVjdCh7XG4gICAgICBlbWJlZGRpbmdzOiB6LmFycmF5KHouYXJyYXkoei5udW1iZXIoKSkpLFxuICAgICAgdXNhZ2U6IHoub2JqZWN0KHsgdG9rZW5zOiB6Lm51bWJlcigpIH0pLm51bGxpc2goKSxcbiAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHpcbiAgICAgICAgLnJlY29yZCh6LnN0cmluZygpLCB6LnJlY29yZCh6LnN0cmluZygpLCB6LnVua25vd24oKSkpXG4gICAgICAgIC5vcHRpb25hbCgpLFxuICAgIH0pLFxuICApLFxuKTtcbiIsICJpbXBvcnQgeyBnZXRDb250ZXh0IH0gZnJvbSAnQHZlcmNlbC9vaWRjJztcbmV4cG9ydCB7IGdldFZlcmNlbE9pZGNUb2tlbiB9IGZyb20gJ0B2ZXJjZWwvb2lkYyc7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRWZXJjZWxSZXF1ZXN0SWQoKTogUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgcmV0dXJuIGdldENvbnRleHQoKS5oZWFkZXJzPy5bJ3gtdmVyY2VsLWlkJ107XG59XG4iLCAiLy8gVmVyc2lvbiBzdHJpbmcgb2YgdGhpcyBwYWNrYWdlIGluamVjdGVkIGF0IGJ1aWxkIHRpbWUuXG5kZWNsYXJlIGNvbnN0IF9fUEFDS0FHRV9WRVJTSU9OX186IHN0cmluZyB8IHVuZGVmaW5lZDtcbmV4cG9ydCBjb25zdCBWRVJTSU9OOiBzdHJpbmcgPVxuICB0eXBlb2YgX19QQUNLQUdFX1ZFUlNJT05fXyAhPT0gJ3VuZGVmaW5lZCdcbiAgICA/IF9fUEFDS0FHRV9WRVJTSU9OX19cbiAgICA6ICcwLjAuMC10ZXN0JztcbiIsICIvLyByZS1leHBvcnRzOlxuZXhwb3J0IHsgZ2F0ZXdheSwgY3JlYXRlR2F0ZXdheSB9IGZyb20gJ0BhaS1zZGsvZ2F0ZXdheSc7XG5leHBvcnQge1xuICBhc1NjaGVtYSxcbiAgY3JlYXRlSWRHZW5lcmF0b3IsXG4gIGR5bmFtaWNUb29sLFxuICBnZW5lcmF0ZUlkLFxuICBqc29uU2NoZW1hLFxuICBwYXJzZUpzb25FdmVudFN0cmVhbSxcbiAgdG9vbCxcbiAgem9kU2NoZW1hLFxuICB0eXBlIElkR2VuZXJhdG9yLFxuICB0eXBlIEluZmVyVG9vbElucHV0LFxuICB0eXBlIEluZmVyVG9vbE91dHB1dCxcbiAgdHlwZSBTY2hlbWEsXG4gIHR5cGUgVG9vbCxcbiAgdHlwZSBUb29sQ2FsbE9wdGlvbnMsXG4gIHR5cGUgVG9vbEV4ZWN1dGVGdW5jdGlvbixcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5cbi8vIGRpcmVjdG9yeSBleHBvcnRzXG5leHBvcnQgKiBmcm9tICcuL2FnZW50JztcbmV4cG9ydCAqIGZyb20gJy4vZW1iZWQnO1xuZXhwb3J0ICogZnJvbSAnLi9lcnJvcic7XG5leHBvcnQgKiBmcm9tICcuL2dlbmVyYXRlLWltYWdlJztcbmV4cG9ydCAqIGZyb20gJy4vZ2VuZXJhdGUtb2JqZWN0JztcbmV4cG9ydCAqIGZyb20gJy4vZ2VuZXJhdGUtc3BlZWNoJztcbmV4cG9ydCAqIGZyb20gJy4vZ2VuZXJhdGUtdGV4dCc7XG5leHBvcnQgKiBmcm9tICcuL2xvZ2dlcic7XG5leHBvcnQgKiBmcm9tICcuL21pZGRsZXdhcmUnO1xuZXhwb3J0ICogZnJvbSAnLi9wcm9tcHQnO1xuZXhwb3J0ICogZnJvbSAnLi9yZWdpc3RyeSc7XG5leHBvcnQgKiBmcm9tICcuL3RleHQtc3RyZWFtJztcbmV4cG9ydCAqIGZyb20gJy4vdG9vbCc7XG5leHBvcnQgKiBmcm9tICcuL3RyYW5zY3JpYmUnO1xuZXhwb3J0ICogZnJvbSAnLi90eXBlcyc7XG5leHBvcnQgKiBmcm9tICcuL3VpJztcbmV4cG9ydCAqIGZyb20gJy4vdWktbWVzc2FnZS1zdHJlYW0nO1xuZXhwb3J0ICogZnJvbSAnLi91dGlsJztcblxuLy8gdGVsZW1ldHJ5IHR5cGVzOlxuZXhwb3J0IHR5cGUgeyBUZWxlbWV0cnlTZXR0aW5ncyB9IGZyb20gJy4vdGVsZW1ldHJ5L3RlbGVtZXRyeS1zZXR0aW5ncyc7XG5cbi8vIGltcG9ydCBnbG9iYWxzXG5pbXBvcnQgJy4vZ2xvYmFsJztcbiIsICJpbXBvcnQge1xuICBMYW5ndWFnZU1vZGVsVjIsXG4gIExhbmd1YWdlTW9kZWxWMkNvbnRlbnQsXG4gIExhbmd1YWdlTW9kZWxWMlRvb2xDYWxsLFxufSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcbmltcG9ydCB7XG4gIGNyZWF0ZUlkR2VuZXJhdG9yLFxuICBleGVjdXRlVG9vbCxcbiAgZ2V0RXJyb3JNZXNzYWdlLFxuICBJZEdlbmVyYXRvcixcbiAgUHJvdmlkZXJPcHRpb25zLFxuICB3aXRoVXNlckFnZW50U3VmZml4LFxufSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyLXV0aWxzJztcbmltcG9ydCB7IFRyYWNlciB9IGZyb20gJ0BvcGVudGVsZW1ldHJ5L2FwaSc7XG5pbXBvcnQgeyBOb091dHB1dFNwZWNpZmllZEVycm9yIH0gZnJvbSAnLi4vZXJyb3Ivbm8tb3V0cHV0LXNwZWNpZmllZC1lcnJvcic7XG5pbXBvcnQgeyBsb2dXYXJuaW5ncyB9IGZyb20gJy4uL2xvZ2dlci9sb2ctd2FybmluZ3MnO1xuaW1wb3J0IHsgcmVzb2x2ZUxhbmd1YWdlTW9kZWwgfSBmcm9tICcuLi9tb2RlbC9yZXNvbHZlLW1vZGVsJztcbmltcG9ydCB7IE1vZGVsTWVzc2FnZSB9IGZyb20gJy4uL3Byb21wdCc7XG5pbXBvcnQgeyBDYWxsU2V0dGluZ3MgfSBmcm9tICcuLi9wcm9tcHQvY2FsbC1zZXR0aW5ncyc7XG5pbXBvcnQgeyBjb252ZXJ0VG9MYW5ndWFnZU1vZGVsUHJvbXB0IH0gZnJvbSAnLi4vcHJvbXB0L2NvbnZlcnQtdG8tbGFuZ3VhZ2UtbW9kZWwtcHJvbXB0JztcbmltcG9ydCB7IHByZXBhcmVDYWxsU2V0dGluZ3MgfSBmcm9tICcuLi9wcm9tcHQvcHJlcGFyZS1jYWxsLXNldHRpbmdzJztcbmltcG9ydCB7IHByZXBhcmVUb29sc0FuZFRvb2xDaG9pY2UgfSBmcm9tICcuLi9wcm9tcHQvcHJlcGFyZS10b29scy1hbmQtdG9vbC1jaG9pY2UnO1xuaW1wb3J0IHsgUHJvbXB0IH0gZnJvbSAnLi4vcHJvbXB0L3Byb21wdCc7XG5pbXBvcnQgeyBzdGFuZGFyZGl6ZVByb21wdCB9IGZyb20gJy4uL3Byb21wdC9zdGFuZGFyZGl6ZS1wcm9tcHQnO1xuaW1wb3J0IHsgd3JhcEdhdGV3YXlFcnJvciB9IGZyb20gJy4uL3Byb21wdC93cmFwLWdhdGV3YXktZXJyb3InO1xuaW1wb3J0IHsgYXNzZW1ibGVPcGVyYXRpb25OYW1lIH0gZnJvbSAnLi4vdGVsZW1ldHJ5L2Fzc2VtYmxlLW9wZXJhdGlvbi1uYW1lJztcbmltcG9ydCB7IGdldEJhc2VUZWxlbWV0cnlBdHRyaWJ1dGVzIH0gZnJvbSAnLi4vdGVsZW1ldHJ5L2dldC1iYXNlLXRlbGVtZXRyeS1hdHRyaWJ1dGVzJztcbmltcG9ydCB7IGdldFRyYWNlciB9IGZyb20gJy4uL3RlbGVtZXRyeS9nZXQtdHJhY2VyJztcbmltcG9ydCB7IHJlY29yZEVycm9yT25TcGFuLCByZWNvcmRTcGFuIH0gZnJvbSAnLi4vdGVsZW1ldHJ5L3JlY29yZC1zcGFuJztcbmltcG9ydCB7IHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMgfSBmcm9tICcuLi90ZWxlbWV0cnkvc2VsZWN0LXRlbGVtZXRyeS1hdHRyaWJ1dGVzJztcbmltcG9ydCB7IHN0cmluZ2lmeUZvclRlbGVtZXRyeSB9IGZyb20gJy4uL3RlbGVtZXRyeS9zdHJpbmdpZnktZm9yLXRlbGVtZXRyeSc7XG5pbXBvcnQgeyBUZWxlbWV0cnlTZXR0aW5ncyB9IGZyb20gJy4uL3RlbGVtZXRyeS90ZWxlbWV0cnktc2V0dGluZ3MnO1xuaW1wb3J0IHsgTGFuZ3VhZ2VNb2RlbCwgVG9vbENob2ljZSB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IGFkZExhbmd1YWdlTW9kZWxVc2FnZSwgTGFuZ3VhZ2VNb2RlbFVzYWdlIH0gZnJvbSAnLi4vdHlwZXMvdXNhZ2UnO1xuaW1wb3J0IHsgYXNBcnJheSB9IGZyb20gJy4uL3V0aWwvYXMtYXJyYXknO1xuaW1wb3J0IHsgRG93bmxvYWRGdW5jdGlvbiB9IGZyb20gJy4uL3V0aWwvZG93bmxvYWQvZG93bmxvYWQtZnVuY3Rpb24nO1xuaW1wb3J0IHsgcHJlcGFyZVJldHJpZXMgfSBmcm9tICcuLi91dGlsL3ByZXBhcmUtcmV0cmllcyc7XG5pbXBvcnQgeyBDb250ZW50UGFydCB9IGZyb20gJy4vY29udGVudC1wYXJ0JztcbmltcG9ydCB7IGV4dHJhY3RUZXh0Q29udGVudCB9IGZyb20gJy4vZXh0cmFjdC10ZXh0LWNvbnRlbnQnO1xuaW1wb3J0IHsgR2VuZXJhdGVUZXh0UmVzdWx0IH0gZnJvbSAnLi9nZW5lcmF0ZS10ZXh0LXJlc3VsdCc7XG5pbXBvcnQgeyBEZWZhdWx0R2VuZXJhdGVkRmlsZSB9IGZyb20gJy4vZ2VuZXJhdGVkLWZpbGUnO1xuaW1wb3J0IHsgT3V0cHV0IH0gZnJvbSAnLi9vdXRwdXQnO1xuaW1wb3J0IHsgcGFyc2VUb29sQ2FsbCB9IGZyb20gJy4vcGFyc2UtdG9vbC1jYWxsJztcbmltcG9ydCB7IFByZXBhcmVTdGVwRnVuY3Rpb24gfSBmcm9tICcuL3ByZXBhcmUtc3RlcCc7XG5pbXBvcnQgeyBSZXNwb25zZU1lc3NhZ2UgfSBmcm9tICcuL3Jlc3BvbnNlLW1lc3NhZ2UnO1xuaW1wb3J0IHsgRGVmYXVsdFN0ZXBSZXN1bHQsIFN0ZXBSZXN1bHQgfSBmcm9tICcuL3N0ZXAtcmVzdWx0JztcbmltcG9ydCB7XG4gIGlzU3RvcENvbmRpdGlvbk1ldCxcbiAgc3RlcENvdW50SXMsXG4gIFN0b3BDb25kaXRpb24sXG59IGZyb20gJy4vc3RvcC1jb25kaXRpb24nO1xuaW1wb3J0IHsgdG9SZXNwb25zZU1lc3NhZ2VzIH0gZnJvbSAnLi90by1yZXNwb25zZS1tZXNzYWdlcyc7XG5pbXBvcnQgeyBUeXBlZFRvb2xDYWxsIH0gZnJvbSAnLi90b29sLWNhbGwnO1xuaW1wb3J0IHsgVG9vbENhbGxSZXBhaXJGdW5jdGlvbiB9IGZyb20gJy4vdG9vbC1jYWxsLXJlcGFpci1mdW5jdGlvbic7XG5pbXBvcnQgeyBUeXBlZFRvb2xFcnJvciB9IGZyb20gJy4vdG9vbC1lcnJvcic7XG5pbXBvcnQgeyBUb29sT3V0cHV0IH0gZnJvbSAnLi90b29sLW91dHB1dCc7XG5pbXBvcnQgeyBUeXBlZFRvb2xSZXN1bHQgfSBmcm9tICcuL3Rvb2wtcmVzdWx0JztcbmltcG9ydCB7IFRvb2xTZXQgfSBmcm9tICcuL3Rvb2wtc2V0JztcbmltcG9ydCB7IFZFUlNJT04gfSBmcm9tICcuLi92ZXJzaW9uJztcblxuY29uc3Qgb3JpZ2luYWxHZW5lcmF0ZUlkID0gY3JlYXRlSWRHZW5lcmF0b3Ioe1xuICBwcmVmaXg6ICdhaXR4dCcsXG4gIHNpemU6IDI0LFxufSk7XG5cbi8qKlxuQ2FsbGJhY2sgdGhhdCBpcyBzZXQgdXNpbmcgdGhlIGBvblN0ZXBGaW5pc2hgIG9wdGlvbi5cblxuQHBhcmFtIHN0ZXBSZXN1bHQgLSBUaGUgcmVzdWx0IG9mIHRoZSBzdGVwLlxuICovXG5leHBvcnQgdHlwZSBHZW5lcmF0ZVRleHRPblN0ZXBGaW5pc2hDYWxsYmFjazxUT09MUyBleHRlbmRzIFRvb2xTZXQ+ID0gKFxuICBzdGVwUmVzdWx0OiBTdGVwUmVzdWx0PFRPT0xTPixcbikgPT4gUHJvbWlzZTx2b2lkPiB8IHZvaWQ7XG5cbi8qKlxuR2VuZXJhdGUgYSB0ZXh0IGFuZCBjYWxsIHRvb2xzIGZvciBhIGdpdmVuIHByb21wdCB1c2luZyBhIGxhbmd1YWdlIG1vZGVsLlxuXG5UaGlzIGZ1bmN0aW9uIGRvZXMgbm90IHN0cmVhbSB0aGUgb3V0cHV0LiBJZiB5b3Ugd2FudCB0byBzdHJlYW0gdGhlIG91dHB1dCwgdXNlIGBzdHJlYW1UZXh0YCBpbnN0ZWFkLlxuXG5AcGFyYW0gbW9kZWwgLSBUaGUgbGFuZ3VhZ2UgbW9kZWwgdG8gdXNlLlxuXG5AcGFyYW0gdG9vbHMgLSBUb29scyB0aGF0IGFyZSBhY2Nlc3NpYmxlIHRvIGFuZCBjYW4gYmUgY2FsbGVkIGJ5IHRoZSBtb2RlbC4gVGhlIG1vZGVsIG5lZWRzIHRvIHN1cHBvcnQgY2FsbGluZyB0b29scy5cbkBwYXJhbSB0b29sQ2hvaWNlIC0gVGhlIHRvb2wgY2hvaWNlIHN0cmF0ZWd5LiBEZWZhdWx0OiAnYXV0bycuXG5cbkBwYXJhbSBzeXN0ZW0gLSBBIHN5c3RlbSBtZXNzYWdlIHRoYXQgd2lsbCBiZSBwYXJ0IG9mIHRoZSBwcm9tcHQuXG5AcGFyYW0gcHJvbXB0IC0gQSBzaW1wbGUgdGV4dCBwcm9tcHQuIFlvdSBjYW4gZWl0aGVyIHVzZSBgcHJvbXB0YCBvciBgbWVzc2FnZXNgIGJ1dCBub3QgYm90aC5cbkBwYXJhbSBtZXNzYWdlcyAtIEEgbGlzdCBvZiBtZXNzYWdlcy4gWW91IGNhbiBlaXRoZXIgdXNlIGBwcm9tcHRgIG9yIGBtZXNzYWdlc2AgYnV0IG5vdCBib3RoLlxuXG5AcGFyYW0gbWF4T3V0cHV0VG9rZW5zIC0gTWF4aW11bSBudW1iZXIgb2YgdG9rZW5zIHRvIGdlbmVyYXRlLlxuQHBhcmFtIHRlbXBlcmF0dXJlIC0gVGVtcGVyYXR1cmUgc2V0dGluZy5cblRoZSB2YWx1ZSBpcyBwYXNzZWQgdGhyb3VnaCB0byB0aGUgcHJvdmlkZXIuIFRoZSByYW5nZSBkZXBlbmRzIG9uIHRoZSBwcm92aWRlciBhbmQgbW9kZWwuXG5JdCBpcyByZWNvbW1lbmRlZCB0byBzZXQgZWl0aGVyIGB0ZW1wZXJhdHVyZWAgb3IgYHRvcFBgLCBidXQgbm90IGJvdGguXG5AcGFyYW0gdG9wUCAtIE51Y2xldXMgc2FtcGxpbmcuXG5UaGUgdmFsdWUgaXMgcGFzc2VkIHRocm91Z2ggdG8gdGhlIHByb3ZpZGVyLiBUaGUgcmFuZ2UgZGVwZW5kcyBvbiB0aGUgcHJvdmlkZXIgYW5kIG1vZGVsLlxuSXQgaXMgcmVjb21tZW5kZWQgdG8gc2V0IGVpdGhlciBgdGVtcGVyYXR1cmVgIG9yIGB0b3BQYCwgYnV0IG5vdCBib3RoLlxuQHBhcmFtIHRvcEsgLSBPbmx5IHNhbXBsZSBmcm9tIHRoZSB0b3AgSyBvcHRpb25zIGZvciBlYWNoIHN1YnNlcXVlbnQgdG9rZW4uXG5Vc2VkIHRvIHJlbW92ZSBcImxvbmcgdGFpbFwiIGxvdyBwcm9iYWJpbGl0eSByZXNwb25zZXMuXG5SZWNvbW1lbmRlZCBmb3IgYWR2YW5jZWQgdXNlIGNhc2VzIG9ubHkuIFlvdSB1c3VhbGx5IG9ubHkgbmVlZCB0byB1c2UgdGVtcGVyYXR1cmUuXG5AcGFyYW0gcHJlc2VuY2VQZW5hbHR5IC0gUHJlc2VuY2UgcGVuYWx0eSBzZXR0aW5nLlxuSXQgYWZmZWN0cyB0aGUgbGlrZWxpaG9vZCBvZiB0aGUgbW9kZWwgdG8gcmVwZWF0IGluZm9ybWF0aW9uIHRoYXQgaXMgYWxyZWFkeSBpbiB0aGUgcHJvbXB0LlxuVGhlIHZhbHVlIGlzIHBhc3NlZCB0aHJvdWdoIHRvIHRoZSBwcm92aWRlci4gVGhlIHJhbmdlIGRlcGVuZHMgb24gdGhlIHByb3ZpZGVyIGFuZCBtb2RlbC5cbkBwYXJhbSBmcmVxdWVuY3lQZW5hbHR5IC0gRnJlcXVlbmN5IHBlbmFsdHkgc2V0dGluZy5cbkl0IGFmZmVjdHMgdGhlIGxpa2VsaWhvb2Qgb2YgdGhlIG1vZGVsIHRvIHJlcGVhdGVkbHkgdXNlIHRoZSBzYW1lIHdvcmRzIG9yIHBocmFzZXMuXG5UaGUgdmFsdWUgaXMgcGFzc2VkIHRocm91Z2ggdG8gdGhlIHByb3ZpZGVyLiBUaGUgcmFuZ2UgZGVwZW5kcyBvbiB0aGUgcHJvdmlkZXIgYW5kIG1vZGVsLlxuQHBhcmFtIHN0b3BTZXF1ZW5jZXMgLSBTdG9wIHNlcXVlbmNlcy5cbklmIHNldCwgdGhlIG1vZGVsIHdpbGwgc3RvcCBnZW5lcmF0aW5nIHRleHQgd2hlbiBvbmUgb2YgdGhlIHN0b3Agc2VxdWVuY2VzIGlzIGdlbmVyYXRlZC5cbkBwYXJhbSBzZWVkIC0gVGhlIHNlZWQgKGludGVnZXIpIHRvIHVzZSBmb3IgcmFuZG9tIHNhbXBsaW5nLlxuSWYgc2V0IGFuZCBzdXBwb3J0ZWQgYnkgdGhlIG1vZGVsLCBjYWxscyB3aWxsIGdlbmVyYXRlIGRldGVybWluaXN0aWMgcmVzdWx0cy5cblxuQHBhcmFtIG1heFJldHJpZXMgLSBNYXhpbXVtIG51bWJlciBvZiByZXRyaWVzLiBTZXQgdG8gMCB0byBkaXNhYmxlIHJldHJpZXMuIERlZmF1bHQ6IDIuXG5AcGFyYW0gYWJvcnRTaWduYWwgLSBBbiBvcHRpb25hbCBhYm9ydCBzaWduYWwgdGhhdCBjYW4gYmUgdXNlZCB0byBjYW5jZWwgdGhlIGNhbGwuXG5AcGFyYW0gaGVhZGVycyAtIEFkZGl0aW9uYWwgSFRUUCBoZWFkZXJzIHRvIGJlIHNlbnQgd2l0aCB0aGUgcmVxdWVzdC4gT25seSBhcHBsaWNhYmxlIGZvciBIVFRQLWJhc2VkIHByb3ZpZGVycy5cblxuQHBhcmFtIGV4cGVyaW1lbnRhbF9nZW5lcmF0ZU1lc3NhZ2VJZCAtIEdlbmVyYXRlIGEgdW5pcXVlIElEIGZvciBlYWNoIG1lc3NhZ2UuXG5cbkBwYXJhbSBvblN0ZXBGaW5pc2ggLSBDYWxsYmFjayB0aGF0IGlzIGNhbGxlZCB3aGVuIGVhY2ggc3RlcCAoTExNIGNhbGwpIGlzIGZpbmlzaGVkLCBpbmNsdWRpbmcgaW50ZXJtZWRpYXRlIHN0ZXBzLlxuXG5AcmV0dXJuc1xuQSByZXN1bHQgb2JqZWN0IHRoYXQgY29udGFpbnMgdGhlIGdlbmVyYXRlZCB0ZXh0LCB0aGUgcmVzdWx0cyBvZiB0aGUgdG9vbCBjYWxscywgYW5kIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24uXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZW5lcmF0ZVRleHQ8XG4gIFRPT0xTIGV4dGVuZHMgVG9vbFNldCxcbiAgT1VUUFVUID0gbmV2ZXIsXG4gIE9VVFBVVF9QQVJUSUFMID0gbmV2ZXIsXG4+KHtcbiAgbW9kZWw6IG1vZGVsQXJnLFxuICB0b29scyxcbiAgdG9vbENob2ljZSxcbiAgc3lzdGVtLFxuICBwcm9tcHQsXG4gIG1lc3NhZ2VzLFxuICBtYXhSZXRyaWVzOiBtYXhSZXRyaWVzQXJnLFxuICBhYm9ydFNpZ25hbCxcbiAgaGVhZGVycyxcbiAgc3RvcFdoZW4gPSBzdGVwQ291bnRJcygxKSxcbiAgZXhwZXJpbWVudGFsX291dHB1dDogb3V0cHV0LFxuICBleHBlcmltZW50YWxfdGVsZW1ldHJ5OiB0ZWxlbWV0cnksXG4gIHByb3ZpZGVyT3B0aW9ucyxcbiAgZXhwZXJpbWVudGFsX2FjdGl2ZVRvb2xzLFxuICBhY3RpdmVUb29scyA9IGV4cGVyaW1lbnRhbF9hY3RpdmVUb29scyxcbiAgZXhwZXJpbWVudGFsX3ByZXBhcmVTdGVwLFxuICBwcmVwYXJlU3RlcCA9IGV4cGVyaW1lbnRhbF9wcmVwYXJlU3RlcCxcbiAgZXhwZXJpbWVudGFsX3JlcGFpclRvb2xDYWxsOiByZXBhaXJUb29sQ2FsbCxcbiAgZXhwZXJpbWVudGFsX2Rvd25sb2FkOiBkb3dubG9hZCxcbiAgZXhwZXJpbWVudGFsX2NvbnRleHQsXG4gIF9pbnRlcm5hbDoge1xuICAgIGdlbmVyYXRlSWQgPSBvcmlnaW5hbEdlbmVyYXRlSWQsXG4gICAgY3VycmVudERhdGUgPSAoKSA9PiBuZXcgRGF0ZSgpLFxuICB9ID0ge30sXG4gIG9uU3RlcEZpbmlzaCxcbiAgLi4uc2V0dGluZ3Ncbn06IENhbGxTZXR0aW5ncyAmXG4gIFByb21wdCAmIHtcbiAgICAvKipcblRoZSBsYW5ndWFnZSBtb2RlbCB0byB1c2UuXG4gICAgICovXG4gICAgbW9kZWw6IExhbmd1YWdlTW9kZWw7XG5cbiAgICAvKipcblRoZSB0b29scyB0aGF0IHRoZSBtb2RlbCBjYW4gY2FsbC4gVGhlIG1vZGVsIG5lZWRzIHRvIHN1cHBvcnQgY2FsbGluZyB0b29scy5cbiovXG4gICAgdG9vbHM/OiBUT09MUztcblxuICAgIC8qKlxuVGhlIHRvb2wgY2hvaWNlIHN0cmF0ZWd5LiBEZWZhdWx0OiAnYXV0bycuXG4gICAgICovXG4gICAgdG9vbENob2ljZT86IFRvb2xDaG9pY2U8Tm9JbmZlcjxUT09MUz4+O1xuXG4gICAgLyoqXG5Db25kaXRpb24gZm9yIHN0b3BwaW5nIHRoZSBnZW5lcmF0aW9uIHdoZW4gdGhlcmUgYXJlIHRvb2wgcmVzdWx0cyBpbiB0aGUgbGFzdCBzdGVwLlxuV2hlbiB0aGUgY29uZGl0aW9uIGlzIGFuIGFycmF5LCBhbnkgb2YgdGhlIGNvbmRpdGlvbnMgY2FuIGJlIG1ldCB0byBzdG9wIHRoZSBnZW5lcmF0aW9uLlxuXG5AZGVmYXVsdCBzdGVwQ291bnRJcygxKVxuICAgICAqL1xuICAgIHN0b3BXaGVuPzpcbiAgICAgIHwgU3RvcENvbmRpdGlvbjxOb0luZmVyPFRPT0xTPj5cbiAgICAgIHwgQXJyYXk8U3RvcENvbmRpdGlvbjxOb0luZmVyPFRPT0xTPj4+O1xuXG4gICAgLyoqXG5PcHRpb25hbCB0ZWxlbWV0cnkgY29uZmlndXJhdGlvbiAoZXhwZXJpbWVudGFsKS5cbiAgICAgKi9cbiAgICBleHBlcmltZW50YWxfdGVsZW1ldHJ5PzogVGVsZW1ldHJ5U2V0dGluZ3M7XG5cbiAgICAvKipcbkFkZGl0aW9uYWwgcHJvdmlkZXItc3BlY2lmaWMgb3B0aW9ucy4gVGhleSBhcmUgcGFzc2VkIHRocm91Z2hcbnRvIHRoZSBwcm92aWRlciBmcm9tIHRoZSBBSSBTREsgYW5kIGVuYWJsZSBwcm92aWRlci1zcGVjaWZpY1xuZnVuY3Rpb25hbGl0eSB0aGF0IGNhbiBiZSBmdWxseSBlbmNhcHN1bGF0ZWQgaW4gdGhlIHByb3ZpZGVyLlxuICovXG4gICAgcHJvdmlkZXJPcHRpb25zPzogUHJvdmlkZXJPcHRpb25zO1xuXG4gICAgLyoqXG4gICAgICogQGRlcHJlY2F0ZWQgVXNlIGBhY3RpdmVUb29sc2AgaW5zdGVhZC5cbiAgICAgKi9cbiAgICBleHBlcmltZW50YWxfYWN0aXZlVG9vbHM/OiBBcnJheTxrZXlvZiBOb0luZmVyPFRPT0xTPj47XG5cbiAgICAvKipcbkxpbWl0cyB0aGUgdG9vbHMgdGhhdCBhcmUgYXZhaWxhYmxlIGZvciB0aGUgbW9kZWwgdG8gY2FsbCB3aXRob3V0XG5jaGFuZ2luZyB0aGUgdG9vbCBjYWxsIGFuZCByZXN1bHQgdHlwZXMgaW4gdGhlIHJlc3VsdC5cbiAgICAgKi9cbiAgICBhY3RpdmVUb29scz86IEFycmF5PGtleW9mIE5vSW5mZXI8VE9PTFM+PjtcblxuICAgIC8qKlxuT3B0aW9uYWwgc3BlY2lmaWNhdGlvbiBmb3IgcGFyc2luZyBzdHJ1Y3R1cmVkIG91dHB1dHMgZnJvbSB0aGUgTExNIHJlc3BvbnNlLlxuICAgICAqL1xuICAgIGV4cGVyaW1lbnRhbF9vdXRwdXQ/OiBPdXRwdXQ8T1VUUFVULCBPVVRQVVRfUEFSVElBTD47XG5cbiAgICAvKipcbkN1c3RvbSBkb3dubG9hZCBmdW5jdGlvbiB0byB1c2UgZm9yIFVSTHMuXG5cbkJ5IGRlZmF1bHQsIGZpbGVzIGFyZSBkb3dubG9hZGVkIGlmIHRoZSBtb2RlbCBkb2VzIG5vdCBzdXBwb3J0IHRoZSBVUkwgZm9yIHRoZSBnaXZlbiBtZWRpYSB0eXBlLlxuICAgICAqL1xuICAgIGV4cGVyaW1lbnRhbF9kb3dubG9hZD86IERvd25sb2FkRnVuY3Rpb24gfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBAZGVwcmVjYXRlZCBVc2UgYHByZXBhcmVTdGVwYCBpbnN0ZWFkLlxuICAgICAqL1xuICAgIGV4cGVyaW1lbnRhbF9wcmVwYXJlU3RlcD86IFByZXBhcmVTdGVwRnVuY3Rpb248Tm9JbmZlcjxUT09MUz4+O1xuXG4gICAgLyoqXG5PcHRpb25hbCBmdW5jdGlvbiB0aGF0IHlvdSBjYW4gdXNlIHRvIHByb3ZpZGUgZGlmZmVyZW50IHNldHRpbmdzIGZvciBhIHN0ZXAuXG4gICAgKi9cbiAgICBwcmVwYXJlU3RlcD86IFByZXBhcmVTdGVwRnVuY3Rpb248Tm9JbmZlcjxUT09MUz4+O1xuXG4gICAgLyoqXG5BIGZ1bmN0aW9uIHRoYXQgYXR0ZW1wdHMgdG8gcmVwYWlyIGEgdG9vbCBjYWxsIHRoYXQgZmFpbGVkIHRvIHBhcnNlLlxuICAgICAqL1xuICAgIGV4cGVyaW1lbnRhbF9yZXBhaXJUb29sQ2FsbD86IFRvb2xDYWxsUmVwYWlyRnVuY3Rpb248Tm9JbmZlcjxUT09MUz4+O1xuXG4gICAgLyoqXG4gICAgQ2FsbGJhY2sgdGhhdCBpcyBjYWxsZWQgd2hlbiBlYWNoIHN0ZXAgKExMTSBjYWxsKSBpcyBmaW5pc2hlZCwgaW5jbHVkaW5nIGludGVybWVkaWF0ZSBzdGVwcy5cbiAgICAqL1xuICAgIG9uU3RlcEZpbmlzaD86IEdlbmVyYXRlVGV4dE9uU3RlcEZpbmlzaENhbGxiYWNrPE5vSW5mZXI8VE9PTFM+PjtcblxuICAgIC8qKlxuICAgICAqIENvbnRleHQgdGhhdCBpcyBwYXNzZWQgaW50byB0b29sIGV4ZWN1dGlvbi5cbiAgICAgKlxuICAgICAqIEV4cGVyaW1lbnRhbCAoY2FuIGJyZWFrIGluIHBhdGNoIHJlbGVhc2VzKS5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0IHVuZGVmaW5lZFxuICAgICAqL1xuICAgIGV4cGVyaW1lbnRhbF9jb250ZXh0PzogdW5rbm93bjtcblxuICAgIC8qKlxuICAgICAqIEludGVybmFsLiBGb3IgdGVzdCB1c2Ugb25seS4gTWF5IGNoYW5nZSB3aXRob3V0IG5vdGljZS5cbiAgICAgKi9cbiAgICBfaW50ZXJuYWw/OiB7XG4gICAgICBnZW5lcmF0ZUlkPzogSWRHZW5lcmF0b3I7XG4gICAgICBjdXJyZW50RGF0ZT86ICgpID0+IERhdGU7XG4gICAgfTtcbiAgfSk6IFByb21pc2U8R2VuZXJhdGVUZXh0UmVzdWx0PFRPT0xTLCBPVVRQVVQ+PiB7XG4gIGNvbnN0IG1vZGVsID0gcmVzb2x2ZUxhbmd1YWdlTW9kZWwobW9kZWxBcmcpO1xuICBjb25zdCBzdG9wQ29uZGl0aW9ucyA9IGFzQXJyYXkoc3RvcFdoZW4pO1xuICBjb25zdCB7IG1heFJldHJpZXMsIHJldHJ5IH0gPSBwcmVwYXJlUmV0cmllcyh7XG4gICAgbWF4UmV0cmllczogbWF4UmV0cmllc0FyZyxcbiAgICBhYm9ydFNpZ25hbCxcbiAgfSk7XG5cbiAgY29uc3QgY2FsbFNldHRpbmdzID0gcHJlcGFyZUNhbGxTZXR0aW5ncyhzZXR0aW5ncyk7XG5cbiAgY29uc3QgaGVhZGVyc1dpdGhVc2VyQWdlbnQgPSB3aXRoVXNlckFnZW50U3VmZml4KFxuICAgIGhlYWRlcnMgPz8ge30sXG4gICAgYGFpLyR7VkVSU0lPTn1gLFxuICApO1xuXG4gIGNvbnN0IGJhc2VUZWxlbWV0cnlBdHRyaWJ1dGVzID0gZ2V0QmFzZVRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgIG1vZGVsLFxuICAgIHRlbGVtZXRyeSxcbiAgICBoZWFkZXJzOiBoZWFkZXJzV2l0aFVzZXJBZ2VudCxcbiAgICBzZXR0aW5nczogeyAuLi5jYWxsU2V0dGluZ3MsIG1heFJldHJpZXMgfSxcbiAgfSk7XG5cbiAgY29uc3QgaW5pdGlhbFByb21wdCA9IGF3YWl0IHN0YW5kYXJkaXplUHJvbXB0KHtcbiAgICBzeXN0ZW0sXG4gICAgcHJvbXB0LFxuICAgIG1lc3NhZ2VzLFxuICB9IGFzIFByb21wdCk7XG5cbiAgY29uc3QgdHJhY2VyID0gZ2V0VHJhY2VyKHRlbGVtZXRyeSk7XG5cbiAgdHJ5IHtcbiAgICByZXR1cm4gYXdhaXQgcmVjb3JkU3Bhbih7XG4gICAgICBuYW1lOiAnYWkuZ2VuZXJhdGVUZXh0JyxcbiAgICAgIGF0dHJpYnV0ZXM6IHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgICB0ZWxlbWV0cnksXG4gICAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgICAuLi5hc3NlbWJsZU9wZXJhdGlvbk5hbWUoe1xuICAgICAgICAgICAgb3BlcmF0aW9uSWQ6ICdhaS5nZW5lcmF0ZVRleHQnLFxuICAgICAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIC4uLmJhc2VUZWxlbWV0cnlBdHRyaWJ1dGVzLFxuICAgICAgICAgIC8vIG1vZGVsOlxuICAgICAgICAgICdhaS5tb2RlbC5wcm92aWRlcic6IG1vZGVsLnByb3ZpZGVyLFxuICAgICAgICAgICdhaS5tb2RlbC5pZCc6IG1vZGVsLm1vZGVsSWQsXG4gICAgICAgICAgLy8gc3BlY2lmaWMgc2V0dGluZ3MgdGhhdCBvbmx5IG1ha2Ugc2Vuc2Ugb24gdGhlIG91dGVyIGxldmVsOlxuICAgICAgICAgICdhaS5wcm9tcHQnOiB7XG4gICAgICAgICAgICBpbnB1dDogKCkgPT4gSlNPTi5zdHJpbmdpZnkoeyBzeXN0ZW0sIHByb21wdCwgbWVzc2FnZXMgfSksXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgICAgdHJhY2VyLFxuICAgICAgZm46IGFzeW5jIHNwYW4gPT4ge1xuICAgICAgICBjb25zdCBjYWxsU2V0dGluZ3MgPSBwcmVwYXJlQ2FsbFNldHRpbmdzKHNldHRpbmdzKTtcblxuICAgICAgICBsZXQgY3VycmVudE1vZGVsUmVzcG9uc2U6IEF3YWl0ZWQ8XG4gICAgICAgICAgUmV0dXJuVHlwZTxMYW5ndWFnZU1vZGVsVjJbJ2RvR2VuZXJhdGUnXT5cbiAgICAgICAgPiAmIHsgcmVzcG9uc2U6IHsgaWQ6IHN0cmluZzsgdGltZXN0YW1wOiBEYXRlOyBtb2RlbElkOiBzdHJpbmcgfSB9O1xuICAgICAgICBsZXQgY2xpZW50VG9vbENhbGxzOiBBcnJheTxUeXBlZFRvb2xDYWxsPFRPT0xTPj4gPSBbXTtcbiAgICAgICAgbGV0IGNsaWVudFRvb2xPdXRwdXRzOiBBcnJheTxUb29sT3V0cHV0PFRPT0xTPj4gPSBbXTtcbiAgICAgICAgY29uc3QgcmVzcG9uc2VNZXNzYWdlczogQXJyYXk8UmVzcG9uc2VNZXNzYWdlPiA9IFtdO1xuICAgICAgICBjb25zdCBzdGVwczogR2VuZXJhdGVUZXh0UmVzdWx0PFRPT0xTLCBPVVRQVVQ+WydzdGVwcyddID0gW107XG5cbiAgICAgICAgZG8ge1xuICAgICAgICAgIGNvbnN0IHN0ZXBJbnB1dE1lc3NhZ2VzID0gW1xuICAgICAgICAgICAgLi4uaW5pdGlhbFByb21wdC5tZXNzYWdlcyxcbiAgICAgICAgICAgIC4uLnJlc3BvbnNlTWVzc2FnZXMsXG4gICAgICAgICAgXTtcblxuICAgICAgICAgIGNvbnN0IHByZXBhcmVTdGVwUmVzdWx0ID0gYXdhaXQgcHJlcGFyZVN0ZXA/Lih7XG4gICAgICAgICAgICBtb2RlbCxcbiAgICAgICAgICAgIHN0ZXBzLFxuICAgICAgICAgICAgc3RlcE51bWJlcjogc3RlcHMubGVuZ3RoLFxuICAgICAgICAgICAgbWVzc2FnZXM6IHN0ZXBJbnB1dE1lc3NhZ2VzLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY29uc3Qgc3RlcE1vZGVsID0gcmVzb2x2ZUxhbmd1YWdlTW9kZWwoXG4gICAgICAgICAgICBwcmVwYXJlU3RlcFJlc3VsdD8ubW9kZWwgPz8gbW9kZWwsXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGNvbnN0IHByb21wdE1lc3NhZ2VzID0gYXdhaXQgY29udmVydFRvTGFuZ3VhZ2VNb2RlbFByb21wdCh7XG4gICAgICAgICAgICBwcm9tcHQ6IHtcbiAgICAgICAgICAgICAgc3lzdGVtOiBwcmVwYXJlU3RlcFJlc3VsdD8uc3lzdGVtID8/IGluaXRpYWxQcm9tcHQuc3lzdGVtLFxuICAgICAgICAgICAgICBtZXNzYWdlczogcHJlcGFyZVN0ZXBSZXN1bHQ/Lm1lc3NhZ2VzID8/IHN0ZXBJbnB1dE1lc3NhZ2VzLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHN1cHBvcnRlZFVybHM6IGF3YWl0IHN0ZXBNb2RlbC5zdXBwb3J0ZWRVcmxzLFxuICAgICAgICAgICAgZG93bmxvYWQsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCB7IHRvb2xDaG9pY2U6IHN0ZXBUb29sQ2hvaWNlLCB0b29sczogc3RlcFRvb2xzIH0gPVxuICAgICAgICAgICAgcHJlcGFyZVRvb2xzQW5kVG9vbENob2ljZSh7XG4gICAgICAgICAgICAgIHRvb2xzLFxuICAgICAgICAgICAgICB0b29sQ2hvaWNlOiBwcmVwYXJlU3RlcFJlc3VsdD8udG9vbENob2ljZSA/PyB0b29sQ2hvaWNlLFxuICAgICAgICAgICAgICBhY3RpdmVUb29sczogcHJlcGFyZVN0ZXBSZXN1bHQ/LmFjdGl2ZVRvb2xzID8/IGFjdGl2ZVRvb2xzLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjdXJyZW50TW9kZWxSZXNwb25zZSA9IGF3YWl0IHJldHJ5KCgpID0+XG4gICAgICAgICAgICByZWNvcmRTcGFuKHtcbiAgICAgICAgICAgICAgbmFtZTogJ2FpLmdlbmVyYXRlVGV4dC5kb0dlbmVyYXRlJyxcbiAgICAgICAgICAgICAgYXR0cmlidXRlczogc2VsZWN0VGVsZW1ldHJ5QXR0cmlidXRlcyh7XG4gICAgICAgICAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgICAgICAgICAgIC4uLmFzc2VtYmxlT3BlcmF0aW9uTmFtZSh7XG4gICAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbklkOiAnYWkuZ2VuZXJhdGVUZXh0LmRvR2VuZXJhdGUnLFxuICAgICAgICAgICAgICAgICAgICB0ZWxlbWV0cnksXG4gICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgIC4uLmJhc2VUZWxlbWV0cnlBdHRyaWJ1dGVzLFxuICAgICAgICAgICAgICAgICAgLy8gbW9kZWw6XG4gICAgICAgICAgICAgICAgICAnYWkubW9kZWwucHJvdmlkZXInOiBzdGVwTW9kZWwucHJvdmlkZXIsXG4gICAgICAgICAgICAgICAgICAnYWkubW9kZWwuaWQnOiBzdGVwTW9kZWwubW9kZWxJZCxcbiAgICAgICAgICAgICAgICAgIC8vIHByb21wdDpcbiAgICAgICAgICAgICAgICAgICdhaS5wcm9tcHQubWVzc2FnZXMnOiB7XG4gICAgICAgICAgICAgICAgICAgIGlucHV0OiAoKSA9PiBzdHJpbmdpZnlGb3JUZWxlbWV0cnkocHJvbXB0TWVzc2FnZXMpLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICdhaS5wcm9tcHQudG9vbHMnOiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGNvbnZlcnQgdGhlIGxhbmd1YWdlIG1vZGVsIGxldmVsIHRvb2xzOlxuICAgICAgICAgICAgICAgICAgICBpbnB1dDogKCkgPT4gc3RlcFRvb2xzPy5tYXAodG9vbCA9PiBKU09OLnN0cmluZ2lmeSh0b29sKSksXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgJ2FpLnByb21wdC50b29sQ2hvaWNlJzoge1xuICAgICAgICAgICAgICAgICAgICBpbnB1dDogKCkgPT5cbiAgICAgICAgICAgICAgICAgICAgICBzdGVwVG9vbENob2ljZSAhPSBudWxsXG4gICAgICAgICAgICAgICAgICAgICAgICA/IEpTT04uc3RyaW5naWZ5KHN0ZXBUb29sQ2hvaWNlKVxuICAgICAgICAgICAgICAgICAgICAgICAgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAgICAgICAvLyBzdGFuZGFyZGl6ZWQgZ2VuLWFpIGxsbSBzcGFuIGF0dHJpYnV0ZXM6XG4gICAgICAgICAgICAgICAgICAnZ2VuX2FpLnN5c3RlbSc6IHN0ZXBNb2RlbC5wcm92aWRlcixcbiAgICAgICAgICAgICAgICAgICdnZW5fYWkucmVxdWVzdC5tb2RlbCc6IHN0ZXBNb2RlbC5tb2RlbElkLFxuICAgICAgICAgICAgICAgICAgJ2dlbl9haS5yZXF1ZXN0LmZyZXF1ZW5jeV9wZW5hbHR5Jzogc2V0dGluZ3MuZnJlcXVlbmN5UGVuYWx0eSxcbiAgICAgICAgICAgICAgICAgICdnZW5fYWkucmVxdWVzdC5tYXhfdG9rZW5zJzogc2V0dGluZ3MubWF4T3V0cHV0VG9rZW5zLFxuICAgICAgICAgICAgICAgICAgJ2dlbl9haS5yZXF1ZXN0LnByZXNlbmNlX3BlbmFsdHknOiBzZXR0aW5ncy5wcmVzZW5jZVBlbmFsdHksXG4gICAgICAgICAgICAgICAgICAnZ2VuX2FpLnJlcXVlc3Quc3RvcF9zZXF1ZW5jZXMnOiBzZXR0aW5ncy5zdG9wU2VxdWVuY2VzLFxuICAgICAgICAgICAgICAgICAgJ2dlbl9haS5yZXF1ZXN0LnRlbXBlcmF0dXJlJzpcbiAgICAgICAgICAgICAgICAgICAgc2V0dGluZ3MudGVtcGVyYXR1cmUgPz8gdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgICAgJ2dlbl9haS5yZXF1ZXN0LnRvcF9rJzogc2V0dGluZ3MudG9wSyxcbiAgICAgICAgICAgICAgICAgICdnZW5fYWkucmVxdWVzdC50b3BfcCc6IHNldHRpbmdzLnRvcFAsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIHRyYWNlcixcbiAgICAgICAgICAgICAgZm46IGFzeW5jIHNwYW4gPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHN0ZXBNb2RlbC5kb0dlbmVyYXRlKHtcbiAgICAgICAgICAgICAgICAgIC4uLmNhbGxTZXR0aW5ncyxcbiAgICAgICAgICAgICAgICAgIHRvb2xzOiBzdGVwVG9vbHMsXG4gICAgICAgICAgICAgICAgICB0b29sQ2hvaWNlOiBzdGVwVG9vbENob2ljZSxcbiAgICAgICAgICAgICAgICAgIHJlc3BvbnNlRm9ybWF0OiBvdXRwdXQ/LnJlc3BvbnNlRm9ybWF0LFxuICAgICAgICAgICAgICAgICAgcHJvbXB0OiBwcm9tcHRNZXNzYWdlcyxcbiAgICAgICAgICAgICAgICAgIHByb3ZpZGVyT3B0aW9ucyxcbiAgICAgICAgICAgICAgICAgIGFib3J0U2lnbmFsLFxuICAgICAgICAgICAgICAgICAgaGVhZGVyczogaGVhZGVyc1dpdGhVc2VyQWdlbnQsXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAvLyBGaWxsIGluIGRlZmF1bHQgdmFsdWVzOlxuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlRGF0YSA9IHtcbiAgICAgICAgICAgICAgICAgIGlkOiByZXN1bHQucmVzcG9uc2U/LmlkID8/IGdlbmVyYXRlSWQoKSxcbiAgICAgICAgICAgICAgICAgIHRpbWVzdGFtcDogcmVzdWx0LnJlc3BvbnNlPy50aW1lc3RhbXAgPz8gY3VycmVudERhdGUoKSxcbiAgICAgICAgICAgICAgICAgIG1vZGVsSWQ6IHJlc3VsdC5yZXNwb25zZT8ubW9kZWxJZCA/PyBzdGVwTW9kZWwubW9kZWxJZCxcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHJlc3VsdC5yZXNwb25zZT8uaGVhZGVycyxcbiAgICAgICAgICAgICAgICAgIGJvZHk6IHJlc3VsdC5yZXNwb25zZT8uYm9keSxcbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgLy8gQWRkIHJlc3BvbnNlIGluZm9ybWF0aW9uIHRvIHRoZSBzcGFuOlxuICAgICAgICAgICAgICAgIHNwYW4uc2V0QXR0cmlidXRlcyhcbiAgICAgICAgICAgICAgICAgIHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgICAgICAgICB0ZWxlbWV0cnksXG4gICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAnYWkucmVzcG9uc2UuZmluaXNoUmVhc29uJzogcmVzdWx0LmZpbmlzaFJlYXNvbixcbiAgICAgICAgICAgICAgICAgICAgICAnYWkucmVzcG9uc2UudGV4dCc6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dDogKCkgPT4gZXh0cmFjdFRleHRDb250ZW50KHJlc3VsdC5jb250ZW50KSxcbiAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICdhaS5yZXNwb25zZS50b29sQ2FsbHMnOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQ6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdG9vbENhbGxzID0gYXNUb29sQ2FsbHMocmVzdWx0LmNvbnRlbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdG9vbENhbGxzID09IG51bGxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogSlNPTi5zdHJpbmdpZnkodG9vbENhbGxzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAnYWkucmVzcG9uc2UuaWQnOiByZXNwb25zZURhdGEuaWQsXG4gICAgICAgICAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLm1vZGVsJzogcmVzcG9uc2VEYXRhLm1vZGVsSWQsXG4gICAgICAgICAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLnRpbWVzdGFtcCc6XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZURhdGEudGltZXN0YW1wLnRvSVNPU3RyaW5nKCksXG4gICAgICAgICAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLnByb3ZpZGVyTWV0YWRhdGEnOiBKU09OLnN0cmluZ2lmeShcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wcm92aWRlck1ldGFkYXRhLFxuICAgICAgICAgICAgICAgICAgICAgICksXG5cbiAgICAgICAgICAgICAgICAgICAgICAvLyBUT0RPIHJlbmFtZSB0ZWxlbWV0cnkgYXR0cmlidXRlcyB0byBpbnB1dFRva2VucyBhbmQgb3V0cHV0VG9rZW5zXG4gICAgICAgICAgICAgICAgICAgICAgJ2FpLnVzYWdlLnByb21wdFRva2Vucyc6IHJlc3VsdC51c2FnZS5pbnB1dFRva2VucyxcbiAgICAgICAgICAgICAgICAgICAgICAnYWkudXNhZ2UuY29tcGxldGlvblRva2Vucyc6IHJlc3VsdC51c2FnZS5vdXRwdXRUb2tlbnMsXG5cbiAgICAgICAgICAgICAgICAgICAgICAvLyBzdGFuZGFyZGl6ZWQgZ2VuLWFpIGxsbSBzcGFuIGF0dHJpYnV0ZXM6XG4gICAgICAgICAgICAgICAgICAgICAgJ2dlbl9haS5yZXNwb25zZS5maW5pc2hfcmVhc29ucyc6IFtyZXN1bHQuZmluaXNoUmVhc29uXSxcbiAgICAgICAgICAgICAgICAgICAgICAnZ2VuX2FpLnJlc3BvbnNlLmlkJzogcmVzcG9uc2VEYXRhLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICdnZW5fYWkucmVzcG9uc2UubW9kZWwnOiByZXNwb25zZURhdGEubW9kZWxJZCxcbiAgICAgICAgICAgICAgICAgICAgICAnZ2VuX2FpLnVzYWdlLmlucHV0X3Rva2Vucyc6IHJlc3VsdC51c2FnZS5pbnB1dFRva2VucyxcbiAgICAgICAgICAgICAgICAgICAgICAnZ2VuX2FpLnVzYWdlLm91dHB1dF90b2tlbnMnOiByZXN1bHQudXNhZ2Uub3V0cHV0VG9rZW5zLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiB7IC4uLnJlc3VsdCwgcmVzcG9uc2U6IHJlc3BvbnNlRGF0YSB9O1xuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIC8vIHBhcnNlIHRvb2wgY2FsbHM6XG4gICAgICAgICAgY29uc3Qgc3RlcFRvb2xDYWxsczogVHlwZWRUb29sQ2FsbDxUT09MUz5bXSA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICAgICAgY3VycmVudE1vZGVsUmVzcG9uc2UuY29udGVudFxuICAgICAgICAgICAgICAuZmlsdGVyKFxuICAgICAgICAgICAgICAgIChwYXJ0KTogcGFydCBpcyBMYW5ndWFnZU1vZGVsVjJUb29sQ2FsbCA9PlxuICAgICAgICAgICAgICAgICAgcGFydC50eXBlID09PSAndG9vbC1jYWxsJyxcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAubWFwKHRvb2xDYWxsID0+XG4gICAgICAgICAgICAgICAgcGFyc2VUb29sQ2FsbCh7XG4gICAgICAgICAgICAgICAgICB0b29sQ2FsbCxcbiAgICAgICAgICAgICAgICAgIHRvb2xzLFxuICAgICAgICAgICAgICAgICAgcmVwYWlyVG9vbENhbGwsXG4gICAgICAgICAgICAgICAgICBzeXN0ZW0sXG4gICAgICAgICAgICAgICAgICBtZXNzYWdlczogc3RlcElucHV0TWVzc2FnZXMsXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIC8vIG5vdGlmeSB0aGUgdG9vbHMgdGhhdCB0aGUgdG9vbCBjYWxscyBhcmUgYXZhaWxhYmxlOlxuICAgICAgICAgIGZvciAoY29uc3QgdG9vbENhbGwgb2Ygc3RlcFRvb2xDYWxscykge1xuICAgICAgICAgICAgaWYgKHRvb2xDYWxsLmludmFsaWQpIHtcbiAgICAgICAgICAgICAgY29udGludWU7IC8vIGlnbm9yZSBpbnZhbGlkIHRvb2wgY2FsbHNcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgdG9vbCA9IHRvb2xzIVt0b29sQ2FsbC50b29sTmFtZV07XG4gICAgICAgICAgICBpZiAodG9vbD8ub25JbnB1dEF2YWlsYWJsZSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgIGF3YWl0IHRvb2wub25JbnB1dEF2YWlsYWJsZSh7XG4gICAgICAgICAgICAgICAgaW5wdXQ6IHRvb2xDYWxsLmlucHV0LFxuICAgICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IHRvb2xDYWxsLnRvb2xDYWxsSWQsXG4gICAgICAgICAgICAgICAgbWVzc2FnZXM6IHN0ZXBJbnB1dE1lc3NhZ2VzLFxuICAgICAgICAgICAgICAgIGFib3J0U2lnbmFsLFxuICAgICAgICAgICAgICAgIGV4cGVyaW1lbnRhbF9jb250ZXh0LFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBpbnNlcnQgZXJyb3IgdG9vbCBvdXRwdXRzIGZvciBpbnZhbGlkIHRvb2wgY2FsbHM6XG4gICAgICAgICAgLy8gVE9ETyBBSSBTREsgNjogaW52YWxpZCBpbnB1dHMgc2hvdWxkIG5vdCByZXF1aXJlIG91dHB1dCBwYXJ0c1xuICAgICAgICAgIGNvbnN0IGludmFsaWRUb29sQ2FsbHMgPSBzdGVwVG9vbENhbGxzLmZpbHRlcihcbiAgICAgICAgICAgIHRvb2xDYWxsID0+IHRvb2xDYWxsLmludmFsaWQgJiYgdG9vbENhbGwuZHluYW1pYyxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgY2xpZW50VG9vbE91dHB1dHMgPSBbXTtcblxuICAgICAgICAgIGZvciAoY29uc3QgdG9vbENhbGwgb2YgaW52YWxpZFRvb2xDYWxscykge1xuICAgICAgICAgICAgY2xpZW50VG9vbE91dHB1dHMucHVzaCh7XG4gICAgICAgICAgICAgIHR5cGU6ICd0b29sLWVycm9yJyxcbiAgICAgICAgICAgICAgdG9vbENhbGxJZDogdG9vbENhbGwudG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgdG9vbE5hbWU6IHRvb2xDYWxsLnRvb2xOYW1lLFxuICAgICAgICAgICAgICBpbnB1dDogdG9vbENhbGwuaW5wdXQsXG4gICAgICAgICAgICAgIGVycm9yOiBnZXRFcnJvck1lc3NhZ2UodG9vbENhbGwuZXJyb3IhKSxcbiAgICAgICAgICAgICAgZHluYW1pYzogdHJ1ZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIGV4ZWN1dGUgY2xpZW50IHRvb2wgY2FsbHM6XG4gICAgICAgICAgY2xpZW50VG9vbENhbGxzID0gc3RlcFRvb2xDYWxscy5maWx0ZXIoXG4gICAgICAgICAgICB0b29sQ2FsbCA9PiAhdG9vbENhbGwucHJvdmlkZXJFeGVjdXRlZCxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgaWYgKHRvb2xzICE9IG51bGwpIHtcbiAgICAgICAgICAgIGNsaWVudFRvb2xPdXRwdXRzLnB1c2goXG4gICAgICAgICAgICAgIC4uLihhd2FpdCBleGVjdXRlVG9vbHMoe1xuICAgICAgICAgICAgICAgIHRvb2xDYWxsczogY2xpZW50VG9vbENhbGxzLmZpbHRlcihcbiAgICAgICAgICAgICAgICAgIHRvb2xDYWxsID0+ICF0b29sQ2FsbC5pbnZhbGlkLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgdG9vbHMsXG4gICAgICAgICAgICAgICAgdHJhY2VyLFxuICAgICAgICAgICAgICAgIHRlbGVtZXRyeSxcbiAgICAgICAgICAgICAgICBtZXNzYWdlczogc3RlcElucHV0TWVzc2FnZXMsXG4gICAgICAgICAgICAgICAgYWJvcnRTaWduYWwsXG4gICAgICAgICAgICAgICAgZXhwZXJpbWVudGFsX2NvbnRleHQsXG4gICAgICAgICAgICAgIH0pKSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gY29udGVudDpcbiAgICAgICAgICBjb25zdCBzdGVwQ29udGVudCA9IGFzQ29udGVudCh7XG4gICAgICAgICAgICBjb250ZW50OiBjdXJyZW50TW9kZWxSZXNwb25zZS5jb250ZW50LFxuICAgICAgICAgICAgdG9vbENhbGxzOiBzdGVwVG9vbENhbGxzLFxuICAgICAgICAgICAgdG9vbE91dHB1dHM6IGNsaWVudFRvb2xPdXRwdXRzLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgLy8gYXBwZW5kIHRvIG1lc3NhZ2VzIGZvciBwb3RlbnRpYWwgbmV4dCBzdGVwOlxuICAgICAgICAgIHJlc3BvbnNlTWVzc2FnZXMucHVzaChcbiAgICAgICAgICAgIC4uLnRvUmVzcG9uc2VNZXNzYWdlcyh7XG4gICAgICAgICAgICAgIGNvbnRlbnQ6IHN0ZXBDb250ZW50LFxuICAgICAgICAgICAgICB0b29scyxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICAvLyBBZGQgc3RlcCBpbmZvcm1hdGlvbiAoYWZ0ZXIgcmVzcG9uc2UgbWVzc2FnZXMgYXJlIHVwZGF0ZWQpOlxuICAgICAgICAgIGNvbnN0IGN1cnJlbnRTdGVwUmVzdWx0OiBTdGVwUmVzdWx0PFRPT0xTPiA9IG5ldyBEZWZhdWx0U3RlcFJlc3VsdCh7XG4gICAgICAgICAgICBjb250ZW50OiBzdGVwQ29udGVudCxcbiAgICAgICAgICAgIGZpbmlzaFJlYXNvbjogY3VycmVudE1vZGVsUmVzcG9uc2UuZmluaXNoUmVhc29uLFxuICAgICAgICAgICAgdXNhZ2U6IGN1cnJlbnRNb2RlbFJlc3BvbnNlLnVzYWdlLFxuICAgICAgICAgICAgd2FybmluZ3M6IGN1cnJlbnRNb2RlbFJlc3BvbnNlLndhcm5pbmdzLFxuICAgICAgICAgICAgcHJvdmlkZXJNZXRhZGF0YTogY3VycmVudE1vZGVsUmVzcG9uc2UucHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgICAgIHJlcXVlc3Q6IGN1cnJlbnRNb2RlbFJlc3BvbnNlLnJlcXVlc3QgPz8ge30sXG4gICAgICAgICAgICByZXNwb25zZToge1xuICAgICAgICAgICAgICAuLi5jdXJyZW50TW9kZWxSZXNwb25zZS5yZXNwb25zZSxcbiAgICAgICAgICAgICAgLy8gZGVlcCBjbG9uZSBtc2dzIHRvIGF2b2lkIG11dGF0aW5nIHBhc3QgbWVzc2FnZXMgaW4gbXVsdGktc3RlcDpcbiAgICAgICAgICAgICAgbWVzc2FnZXM6IHN0cnVjdHVyZWRDbG9uZShyZXNwb25zZU1lc3NhZ2VzKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBsb2dXYXJuaW5ncyhjdXJyZW50TW9kZWxSZXNwb25zZS53YXJuaW5ncyA/PyBbXSk7XG5cbiAgICAgICAgICBzdGVwcy5wdXNoKGN1cnJlbnRTdGVwUmVzdWx0KTtcbiAgICAgICAgICBhd2FpdCBvblN0ZXBGaW5pc2g/LihjdXJyZW50U3RlcFJlc3VsdCk7XG4gICAgICAgIH0gd2hpbGUgKFxuICAgICAgICAgIC8vIHRoZXJlIGFyZSB0b29sIGNhbGxzOlxuICAgICAgICAgIGNsaWVudFRvb2xDYWxscy5sZW5ndGggPiAwICYmXG4gICAgICAgICAgLy8gYWxsIGN1cnJlbnQgdG9vbCBjYWxscyBoYXZlIG91dHB1dHMgKGluY2wuIGV4ZWN1dGlvbiBlcnJvcnMpOlxuICAgICAgICAgIGNsaWVudFRvb2xPdXRwdXRzLmxlbmd0aCA9PT0gY2xpZW50VG9vbENhbGxzLmxlbmd0aCAmJlxuICAgICAgICAgIC8vIGNvbnRpbnVlIHVudGlsIGEgc3RvcCBjb25kaXRpb24gaXMgbWV0OlxuICAgICAgICAgICEoYXdhaXQgaXNTdG9wQ29uZGl0aW9uTWV0KHsgc3RvcENvbmRpdGlvbnMsIHN0ZXBzIH0pKVxuICAgICAgICApO1xuXG4gICAgICAgIC8vIEFkZCByZXNwb25zZSBpbmZvcm1hdGlvbiB0byB0aGUgc3BhbjpcbiAgICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGVzKFxuICAgICAgICAgIHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAgICAgICAnYWkucmVzcG9uc2UuZmluaXNoUmVhc29uJzogY3VycmVudE1vZGVsUmVzcG9uc2UuZmluaXNoUmVhc29uLFxuICAgICAgICAgICAgICAnYWkucmVzcG9uc2UudGV4dCc6IHtcbiAgICAgICAgICAgICAgICBvdXRwdXQ6ICgpID0+IGV4dHJhY3RUZXh0Q29udGVudChjdXJyZW50TW9kZWxSZXNwb25zZS5jb250ZW50KSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLnRvb2xDYWxscyc6IHtcbiAgICAgICAgICAgICAgICBvdXRwdXQ6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHRvb2xDYWxscyA9IGFzVG9vbENhbGxzKGN1cnJlbnRNb2RlbFJlc3BvbnNlLmNvbnRlbnQpO1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIHRvb2xDYWxscyA9PSBudWxsXG4gICAgICAgICAgICAgICAgICAgID8gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgIDogSlNPTi5zdHJpbmdpZnkodG9vbENhbGxzKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAnYWkucmVzcG9uc2UucHJvdmlkZXJNZXRhZGF0YSc6IEpTT04uc3RyaW5naWZ5KFxuICAgICAgICAgICAgICAgIGN1cnJlbnRNb2RlbFJlc3BvbnNlLnByb3ZpZGVyTWV0YWRhdGEsXG4gICAgICAgICAgICAgICksXG5cbiAgICAgICAgICAgICAgLy8gVE9ETyByZW5hbWUgdGVsZW1ldHJ5IGF0dHJpYnV0ZXMgdG8gaW5wdXRUb2tlbnMgYW5kIG91dHB1dFRva2Vuc1xuICAgICAgICAgICAgICAnYWkudXNhZ2UucHJvbXB0VG9rZW5zJzogY3VycmVudE1vZGVsUmVzcG9uc2UudXNhZ2UuaW5wdXRUb2tlbnMsXG4gICAgICAgICAgICAgICdhaS51c2FnZS5jb21wbGV0aW9uVG9rZW5zJzpcbiAgICAgICAgICAgICAgICBjdXJyZW50TW9kZWxSZXNwb25zZS51c2FnZS5vdXRwdXRUb2tlbnMsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IGxhc3RTdGVwID0gc3RlcHNbc3RlcHMubGVuZ3RoIC0gMV07XG5cbiAgICAgICAgLy8gcGFyc2Ugb3V0cHV0IG9ubHkgaWYgdGhlIGxhc3Qgc3RlcCB3YXMgZmluaXNoZWQgd2l0aCBcInN0b3BcIjpcbiAgICAgICAgbGV0IHJlc29sdmVkT3V0cHV0O1xuICAgICAgICBpZiAobGFzdFN0ZXAuZmluaXNoUmVhc29uID09PSAnc3RvcCcpIHtcbiAgICAgICAgICByZXNvbHZlZE91dHB1dCA9IGF3YWl0IG91dHB1dD8ucGFyc2VPdXRwdXQoXG4gICAgICAgICAgICB7IHRleHQ6IGxhc3RTdGVwLnRleHQgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgcmVzcG9uc2U6IGxhc3RTdGVwLnJlc3BvbnNlLFxuICAgICAgICAgICAgICB1c2FnZTogbGFzdFN0ZXAudXNhZ2UsXG4gICAgICAgICAgICAgIGZpbmlzaFJlYXNvbjogbGFzdFN0ZXAuZmluaXNoUmVhc29uLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBEZWZhdWx0R2VuZXJhdGVUZXh0UmVzdWx0KHtcbiAgICAgICAgICBzdGVwcyxcbiAgICAgICAgICByZXNvbHZlZE91dHB1dCxcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgIH0pO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHRocm93IHdyYXBHYXRld2F5RXJyb3IoZXJyb3IpO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGV4ZWN1dGVUb29sczxUT09MUyBleHRlbmRzIFRvb2xTZXQ+KHtcbiAgdG9vbENhbGxzLFxuICB0b29scyxcbiAgdHJhY2VyLFxuICB0ZWxlbWV0cnksXG4gIG1lc3NhZ2VzLFxuICBhYm9ydFNpZ25hbCxcbiAgZXhwZXJpbWVudGFsX2NvbnRleHQsXG59OiB7XG4gIHRvb2xDYWxsczogQXJyYXk8VHlwZWRUb29sQ2FsbDxUT09MUz4+O1xuICB0b29sczogVE9PTFM7XG4gIHRyYWNlcjogVHJhY2VyO1xuICB0ZWxlbWV0cnk6IFRlbGVtZXRyeVNldHRpbmdzIHwgdW5kZWZpbmVkO1xuICBtZXNzYWdlczogTW9kZWxNZXNzYWdlW107XG4gIGFib3J0U2lnbmFsOiBBYm9ydFNpZ25hbCB8IHVuZGVmaW5lZDtcbiAgZXhwZXJpbWVudGFsX2NvbnRleHQ6IHVua25vd247XG59KTogUHJvbWlzZTxBcnJheTxUb29sT3V0cHV0PFRPT0xTPj4+IHtcbiAgY29uc3QgdG9vbE91dHB1dHMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICB0b29sQ2FsbHMubWFwKGFzeW5jICh7IHRvb2xDYWxsSWQsIHRvb2xOYW1lLCBpbnB1dCB9KSA9PiB7XG4gICAgICBjb25zdCB0b29sID0gdG9vbHNbdG9vbE5hbWVdO1xuXG4gICAgICBpZiAodG9vbD8uZXhlY3V0ZSA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZWNvcmRTcGFuKHtcbiAgICAgICAgbmFtZTogJ2FpLnRvb2xDYWxsJyxcbiAgICAgICAgYXR0cmlidXRlczogc2VsZWN0VGVsZW1ldHJ5QXR0cmlidXRlcyh7XG4gICAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgICAgIC4uLmFzc2VtYmxlT3BlcmF0aW9uTmFtZSh7XG4gICAgICAgICAgICAgIG9wZXJhdGlvbklkOiAnYWkudG9vbENhbGwnLFxuICAgICAgICAgICAgICB0ZWxlbWV0cnksXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICdhaS50b29sQ2FsbC5uYW1lJzogdG9vbE5hbWUsXG4gICAgICAgICAgICAnYWkudG9vbENhbGwuaWQnOiB0b29sQ2FsbElkLFxuICAgICAgICAgICAgJ2FpLnRvb2xDYWxsLmFyZ3MnOiB7XG4gICAgICAgICAgICAgIG91dHB1dDogKCkgPT4gSlNPTi5zdHJpbmdpZnkoaW5wdXQpLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgICAgdHJhY2VyLFxuICAgICAgICBmbjogYXN5bmMgc3BhbiA9PiB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHN0cmVhbSA9IGV4ZWN1dGVUb29sKHtcbiAgICAgICAgICAgICAgZXhlY3V0ZTogdG9vbC5leGVjdXRlIS5iaW5kKHRvb2wpLFxuICAgICAgICAgICAgICBpbnB1dCxcbiAgICAgICAgICAgICAgb3B0aW9uczoge1xuICAgICAgICAgICAgICAgIHRvb2xDYWxsSWQsXG4gICAgICAgICAgICAgICAgbWVzc2FnZXMsXG4gICAgICAgICAgICAgICAgYWJvcnRTaWduYWwsXG4gICAgICAgICAgICAgICAgZXhwZXJpbWVudGFsX2NvbnRleHQsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgbGV0IG91dHB1dDogdW5rbm93bjtcbiAgICAgICAgICAgIGZvciBhd2FpdCAoY29uc3QgcGFydCBvZiBzdHJlYW0pIHtcbiAgICAgICAgICAgICAgaWYgKHBhcnQudHlwZSA9PT0gJ2ZpbmFsJykge1xuICAgICAgICAgICAgICAgIG91dHB1dCA9IHBhcnQub3V0cHV0O1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBzcGFuLnNldEF0dHJpYnV0ZXMoXG4gICAgICAgICAgICAgICAgc2VsZWN0VGVsZW1ldHJ5QXR0cmlidXRlcyh7XG4gICAgICAgICAgICAgICAgICB0ZWxlbWV0cnksXG4gICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgICAgICAgICAgICdhaS50b29sQ2FsbC5yZXN1bHQnOiB7XG4gICAgICAgICAgICAgICAgICAgICAgb3V0cHV0OiAoKSA9PiBKU09OLnN0cmluZ2lmeShvdXRwdXQpLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGlnbm9yZWQpIHtcbiAgICAgICAgICAgICAgLy8gSlNPTiBzdHJpbmdpZnkgbWlnaHQgZmFpbCBpZiB0aGUgcmVzdWx0IGlzIG5vdCBzZXJpYWxpemFibGUsXG4gICAgICAgICAgICAgIC8vIGluIHdoaWNoIGNhc2Ugd2UganVzdCBpZ25vcmUgaXQuIEluIHRoZSBmdXR1cmUgd2UgbWlnaHQgd2FudCB0b1xuICAgICAgICAgICAgICAvLyBhZGQgYW4gb3B0aW9uYWwgc2VyaWFsaXplIG1ldGhvZCB0byB0aGUgdG9vbCBpbnRlcmZhY2UgYW5kIHdhcm5cbiAgICAgICAgICAgICAgLy8gaWYgdGhlIHJlc3VsdCBpcyBub3Qgc2VyaWFsaXphYmxlLlxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICB0eXBlOiAndG9vbC1yZXN1bHQnLFxuICAgICAgICAgICAgICB0b29sQ2FsbElkLFxuICAgICAgICAgICAgICB0b29sTmFtZSxcbiAgICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICAgIG91dHB1dCxcbiAgICAgICAgICAgICAgZHluYW1pYzogdG9vbC50eXBlID09PSAnZHluYW1pYycsXG4gICAgICAgICAgICB9IGFzIFR5cGVkVG9vbFJlc3VsdDxUT09MUz47XG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIHJlY29yZEVycm9yT25TcGFuKHNwYW4sIGVycm9yKTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIHR5cGU6ICd0b29sLWVycm9yJyxcbiAgICAgICAgICAgICAgdG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgdG9vbE5hbWUsXG4gICAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgICBlcnJvcixcbiAgICAgICAgICAgICAgZHluYW1pYzogdG9vbC50eXBlID09PSAnZHluYW1pYycsXG4gICAgICAgICAgICB9IGFzIFR5cGVkVG9vbEVycm9yPFRPT0xTPjtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KSxcbiAgKTtcblxuICByZXR1cm4gdG9vbE91dHB1dHMuZmlsdGVyKFxuICAgIChvdXRwdXQpOiBvdXRwdXQgaXMgTm9uTnVsbGFibGU8dHlwZW9mIG91dHB1dD4gPT4gb3V0cHV0ICE9IG51bGwsXG4gICk7XG59XG5cbmNsYXNzIERlZmF1bHRHZW5lcmF0ZVRleHRSZXN1bHQ8VE9PTFMgZXh0ZW5kcyBUb29sU2V0LCBPVVRQVVQ+XG4gIGltcGxlbWVudHMgR2VuZXJhdGVUZXh0UmVzdWx0PFRPT0xTLCBPVVRQVVQ+XG57XG4gIHJlYWRvbmx5IHN0ZXBzOiBHZW5lcmF0ZVRleHRSZXN1bHQ8VE9PTFMsIE9VVFBVVD5bJ3N0ZXBzJ107XG5cbiAgcHJpdmF0ZSByZWFkb25seSByZXNvbHZlZE91dHB1dDogT1VUUFVUO1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IHtcbiAgICBzdGVwczogR2VuZXJhdGVUZXh0UmVzdWx0PFRPT0xTLCBPVVRQVVQ+WydzdGVwcyddO1xuICAgIHJlc29sdmVkT3V0cHV0OiBPVVRQVVQ7XG4gIH0pIHtcbiAgICB0aGlzLnN0ZXBzID0gb3B0aW9ucy5zdGVwcztcbiAgICB0aGlzLnJlc29sdmVkT3V0cHV0ID0gb3B0aW9ucy5yZXNvbHZlZE91dHB1dDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0IGZpbmFsU3RlcCgpIHtcbiAgICByZXR1cm4gdGhpcy5zdGVwc1t0aGlzLnN0ZXBzLmxlbmd0aCAtIDFdO1xuICB9XG5cbiAgZ2V0IGNvbnRlbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmluYWxTdGVwLmNvbnRlbnQ7XG4gIH1cblxuICBnZXQgdGV4dCgpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAudGV4dDtcbiAgfVxuXG4gIGdldCBmaWxlcygpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAuZmlsZXM7XG4gIH1cblxuICBnZXQgcmVhc29uaW5nVGV4dCgpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAucmVhc29uaW5nVGV4dDtcbiAgfVxuXG4gIGdldCByZWFzb25pbmcoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmluYWxTdGVwLnJlYXNvbmluZztcbiAgfVxuXG4gIGdldCB0b29sQ2FsbHMoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmluYWxTdGVwLnRvb2xDYWxscztcbiAgfVxuXG4gIGdldCBzdGF0aWNUb29sQ2FsbHMoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmluYWxTdGVwLnN0YXRpY1Rvb2xDYWxscztcbiAgfVxuXG4gIGdldCBkeW5hbWljVG9vbENhbGxzKCkge1xuICAgIHJldHVybiB0aGlzLmZpbmFsU3RlcC5keW5hbWljVG9vbENhbGxzO1xuICB9XG5cbiAgZ2V0IHRvb2xSZXN1bHRzKCkge1xuICAgIHJldHVybiB0aGlzLmZpbmFsU3RlcC50b29sUmVzdWx0cztcbiAgfVxuXG4gIGdldCBzdGF0aWNUb29sUmVzdWx0cygpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAuc3RhdGljVG9vbFJlc3VsdHM7XG4gIH1cblxuICBnZXQgZHluYW1pY1Rvb2xSZXN1bHRzKCkge1xuICAgIHJldHVybiB0aGlzLmZpbmFsU3RlcC5keW5hbWljVG9vbFJlc3VsdHM7XG4gIH1cblxuICBnZXQgc291cmNlcygpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAuc291cmNlcztcbiAgfVxuXG4gIGdldCBmaW5pc2hSZWFzb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuZmluYWxTdGVwLmZpbmlzaFJlYXNvbjtcbiAgfVxuXG4gIGdldCB3YXJuaW5ncygpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAud2FybmluZ3M7XG4gIH1cblxuICBnZXQgcHJvdmlkZXJNZXRhZGF0YSgpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAucHJvdmlkZXJNZXRhZGF0YTtcbiAgfVxuXG4gIGdldCByZXNwb25zZSgpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAucmVzcG9uc2U7XG4gIH1cblxuICBnZXQgcmVxdWVzdCgpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAucmVxdWVzdDtcbiAgfVxuXG4gIGdldCB1c2FnZSgpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAudXNhZ2U7XG4gIH1cblxuICBnZXQgdG90YWxVc2FnZSgpIHtcbiAgICByZXR1cm4gdGhpcy5zdGVwcy5yZWR1Y2UoXG4gICAgICAodG90YWxVc2FnZSwgc3RlcCkgPT4ge1xuICAgICAgICByZXR1cm4gYWRkTGFuZ3VhZ2VNb2RlbFVzYWdlKHRvdGFsVXNhZ2UsIHN0ZXAudXNhZ2UpO1xuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgaW5wdXRUb2tlbnM6IHVuZGVmaW5lZCxcbiAgICAgICAgb3V0cHV0VG9rZW5zOiB1bmRlZmluZWQsXG4gICAgICAgIHRvdGFsVG9rZW5zOiB1bmRlZmluZWQsXG4gICAgICAgIHJlYXNvbmluZ1Rva2VuczogdW5kZWZpbmVkLFxuICAgICAgICBjYWNoZWRJbnB1dFRva2VuczogdW5kZWZpbmVkLFxuICAgICAgfSBhcyBMYW5ndWFnZU1vZGVsVXNhZ2UsXG4gICAgKTtcbiAgfVxuXG4gIGdldCBleHBlcmltZW50YWxfb3V0cHV0KCkge1xuICAgIGlmICh0aGlzLnJlc29sdmVkT3V0cHV0ID09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBOb091dHB1dFNwZWNpZmllZEVycm9yKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMucmVzb2x2ZWRPdXRwdXQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gYXNUb29sQ2FsbHMoY29udGVudDogQXJyYXk8TGFuZ3VhZ2VNb2RlbFYyQ29udGVudD4pIHtcbiAgY29uc3QgcGFydHMgPSBjb250ZW50LmZpbHRlcihcbiAgICAocGFydCk6IHBhcnQgaXMgTGFuZ3VhZ2VNb2RlbFYyVG9vbENhbGwgPT4gcGFydC50eXBlID09PSAndG9vbC1jYWxsJyxcbiAgKTtcblxuICBpZiAocGFydHMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHJldHVybiBwYXJ0cy5tYXAodG9vbENhbGwgPT4gKHtcbiAgICB0b29sQ2FsbElkOiB0b29sQ2FsbC50b29sQ2FsbElkLFxuICAgIHRvb2xOYW1lOiB0b29sQ2FsbC50b29sTmFtZSxcbiAgICBpbnB1dDogdG9vbENhbGwuaW5wdXQsXG4gIH0pKTtcbn1cblxuZnVuY3Rpb24gYXNDb250ZW50PFRPT0xTIGV4dGVuZHMgVG9vbFNldD4oe1xuICBjb250ZW50LFxuICB0b29sQ2FsbHMsXG4gIHRvb2xPdXRwdXRzLFxufToge1xuICBjb250ZW50OiBBcnJheTxMYW5ndWFnZU1vZGVsVjJDb250ZW50PjtcbiAgdG9vbENhbGxzOiBBcnJheTxUeXBlZFRvb2xDYWxsPFRPT0xTPj47XG4gIHRvb2xPdXRwdXRzOiBBcnJheTxUb29sT3V0cHV0PFRPT0xTPj47XG59KTogQXJyYXk8Q29udGVudFBhcnQ8VE9PTFM+PiB7XG4gIHJldHVybiBbXG4gICAgLi4uY29udGVudC5tYXAocGFydCA9PiB7XG4gICAgICBzd2l0Y2ggKHBhcnQudHlwZSkge1xuICAgICAgICBjYXNlICd0ZXh0JzpcbiAgICAgICAgY2FzZSAncmVhc29uaW5nJzpcbiAgICAgICAgY2FzZSAnc291cmNlJzpcbiAgICAgICAgICByZXR1cm4gcGFydDtcblxuICAgICAgICBjYXNlICdmaWxlJzoge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiAnZmlsZScgYXMgY29uc3QsXG4gICAgICAgICAgICBmaWxlOiBuZXcgRGVmYXVsdEdlbmVyYXRlZEZpbGUocGFydCksXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNhc2UgJ3Rvb2wtY2FsbCc6IHtcbiAgICAgICAgICByZXR1cm4gdG9vbENhbGxzLmZpbmQoXG4gICAgICAgICAgICB0b29sQ2FsbCA9PiB0b29sQ2FsbC50b29sQ2FsbElkID09PSBwYXJ0LnRvb2xDYWxsSWQsXG4gICAgICAgICAgKSE7XG4gICAgICAgIH1cblxuICAgICAgICBjYXNlICd0b29sLXJlc3VsdCc6IHtcbiAgICAgICAgICBjb25zdCB0b29sQ2FsbCA9IHRvb2xDYWxscy5maW5kKFxuICAgICAgICAgICAgdG9vbENhbGwgPT4gdG9vbENhbGwudG9vbENhbGxJZCA9PT0gcGFydC50b29sQ2FsbElkLFxuICAgICAgICAgICkhO1xuXG4gICAgICAgICAgaWYgKHRvb2xDYWxsID09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVG9vbCBjYWxsICR7cGFydC50b29sQ2FsbElkfSBub3QgZm91bmQuYCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHBhcnQuaXNFcnJvcikge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgdHlwZTogJ3Rvb2wtZXJyb3InIGFzIGNvbnN0LFxuICAgICAgICAgICAgICB0b29sQ2FsbElkOiBwYXJ0LnRvb2xDYWxsSWQsXG4gICAgICAgICAgICAgIHRvb2xOYW1lOiBwYXJ0LnRvb2xOYW1lIGFzIGtleW9mIFRPT0xTICYgc3RyaW5nLFxuICAgICAgICAgICAgICBpbnB1dDogdG9vbENhbGwuaW5wdXQsXG4gICAgICAgICAgICAgIGVycm9yOiBwYXJ0LnJlc3VsdCxcbiAgICAgICAgICAgICAgcHJvdmlkZXJFeGVjdXRlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgZHluYW1pYzogdG9vbENhbGwuZHluYW1pYyxcbiAgICAgICAgICAgIH0gYXMgVHlwZWRUb29sRXJyb3I8VE9PTFM+O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiAndG9vbC1yZXN1bHQnIGFzIGNvbnN0LFxuICAgICAgICAgICAgdG9vbENhbGxJZDogcGFydC50b29sQ2FsbElkLFxuICAgICAgICAgICAgdG9vbE5hbWU6IHBhcnQudG9vbE5hbWUgYXMga2V5b2YgVE9PTFMgJiBzdHJpbmcsXG4gICAgICAgICAgICBpbnB1dDogdG9vbENhbGwuaW5wdXQsXG4gICAgICAgICAgICBvdXRwdXQ6IHBhcnQucmVzdWx0LFxuICAgICAgICAgICAgcHJvdmlkZXJFeGVjdXRlZDogdHJ1ZSxcbiAgICAgICAgICAgIGR5bmFtaWM6IHRvb2xDYWxsLmR5bmFtaWMsXG4gICAgICAgICAgfSBhcyBUeXBlZFRvb2xSZXN1bHQ8VE9PTFM+O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSksXG4gICAgLi4udG9vbE91dHB1dHMsXG4gIF07XG59XG4iLCAiaW1wb3J0IHsgQUlTREtFcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuXG5jb25zdCBuYW1lID0gJ0FJX05vT3V0cHV0U3BlY2lmaWVkRXJyb3InO1xuY29uc3QgbWFya2VyID0gYHZlcmNlbC5haS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuLyoqXG5UaHJvd24gd2hlbiBubyBvdXRwdXQgdHlwZSBpcyBzcGVjaWZpZWQgYW5kIG91dHB1dC1yZWxhdGVkIG1ldGhvZHMgYXJlIGNhbGxlZC5cbiAqL1xuZXhwb3J0IGNsYXNzIE5vT3V0cHV0U3BlY2lmaWVkRXJyb3IgZXh0ZW5kcyBBSVNES0Vycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7IC8vIHVzZWQgaW4gaXNJbnN0YW5jZVxuXG4gIGNvbnN0cnVjdG9yKHsgbWVzc2FnZSA9ICdObyBvdXRwdXQgc3BlY2lmaWVkLicgfTogeyBtZXNzYWdlPzogc3RyaW5nIH0gPSB7fSkge1xuICAgIHN1cGVyKHsgbmFtZSwgbWVzc2FnZSB9KTtcbiAgfVxuXG4gIHN0YXRpYyBpc0luc3RhbmNlKGVycm9yOiB1bmtub3duKTogZXJyb3IgaXMgTm9PdXRwdXRTcGVjaWZpZWRFcnJvciB7XG4gICAgcmV0dXJuIEFJU0RLRXJyb3IuaGFzTWFya2VyKGVycm9yLCBtYXJrZXIpO1xuICB9XG59XG4iLCAiaW1wb3J0IHtcbiAgSW1hZ2VNb2RlbFYyQ2FsbFdhcm5pbmcsXG4gIExhbmd1YWdlTW9kZWxWMkNhbGxXYXJuaW5nLFxuICBTcGVlY2hNb2RlbFYyQ2FsbFdhcm5pbmcsXG4gIFRyYW5zY3JpcHRpb25Nb2RlbFYyQ2FsbFdhcm5pbmcsXG59IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuXG5leHBvcnQgdHlwZSBXYXJuaW5nID1cbiAgfCBMYW5ndWFnZU1vZGVsVjJDYWxsV2FybmluZ1xuICB8IEltYWdlTW9kZWxWMkNhbGxXYXJuaW5nXG4gIHwgU3BlZWNoTW9kZWxWMkNhbGxXYXJuaW5nXG4gIHwgVHJhbnNjcmlwdGlvbk1vZGVsVjJDYWxsV2FybmluZztcblxuZXhwb3J0IHR5cGUgTG9nV2FybmluZ3NGdW5jdGlvbiA9ICh3YXJuaW5nczogV2FybmluZ1tdKSA9PiB2b2lkO1xuXG4vKipcbiAqIEZvcm1hdHMgYSB3YXJuaW5nIG9iamVjdCBpbnRvIGEgaHVtYW4tcmVhZGFibGUgc3RyaW5nIHdpdGggY2xlYXIgQUkgU0RLIGJyYW5kaW5nXG4gKi9cbmZ1bmN0aW9uIGZvcm1hdFdhcm5pbmcod2FybmluZzogV2FybmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHByZWZpeCA9ICdBSSBTREsgV2FybmluZzonO1xuXG4gIHN3aXRjaCAod2FybmluZy50eXBlKSB7XG4gICAgY2FzZSAndW5zdXBwb3J0ZWQtc2V0dGluZyc6IHtcbiAgICAgIGxldCBtZXNzYWdlID0gYCR7cHJlZml4fSBUaGUgXCIke3dhcm5pbmcuc2V0dGluZ31cIiBzZXR0aW5nIGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhpcyBtb2RlbGA7XG4gICAgICBpZiAod2FybmluZy5kZXRhaWxzKSB7XG4gICAgICAgIG1lc3NhZ2UgKz0gYCAtICR7d2FybmluZy5kZXRhaWxzfWA7XG4gICAgICB9XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9XG5cbiAgICBjYXNlICd1bnN1cHBvcnRlZC10b29sJzoge1xuICAgICAgY29uc3QgdG9vbE5hbWUgPVxuICAgICAgICAnbmFtZScgaW4gd2FybmluZy50b29sID8gd2FybmluZy50b29sLm5hbWUgOiAndW5rbm93biB0b29sJztcbiAgICAgIGxldCBtZXNzYWdlID0gYCR7cHJlZml4fSBUaGUgdG9vbCBcIiR7dG9vbE5hbWV9XCIgaXMgbm90IHN1cHBvcnRlZCBieSB0aGlzIG1vZGVsYDtcbiAgICAgIGlmICh3YXJuaW5nLmRldGFpbHMpIHtcbiAgICAgICAgbWVzc2FnZSArPSBgIC0gJHt3YXJuaW5nLmRldGFpbHN9YDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH1cblxuICAgIGNhc2UgJ290aGVyJzoge1xuICAgICAgcmV0dXJuIGAke3ByZWZpeH0gJHt3YXJuaW5nLm1lc3NhZ2V9YDtcbiAgICB9XG5cbiAgICBkZWZhdWx0OiB7XG4gICAgICAvLyBGYWxsYmFjayBmb3IgYW55IHVua25vd24gd2FybmluZyB0eXBlc1xuICAgICAgcmV0dXJuIGAke3ByZWZpeH0gJHtKU09OLnN0cmluZ2lmeSh3YXJuaW5nLCBudWxsLCAyKX1gO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgRklSU1RfV0FSTklOR19JTkZPX01FU1NBR0UgPVxuICAnQUkgU0RLIFdhcm5pbmcgU3lzdGVtOiBUbyB0dXJuIG9mZiB3YXJuaW5nIGxvZ2dpbmcsIHNldCB0aGUgQUlfU0RLX0xPR19XQVJOSU5HUyBnbG9iYWwgdG8gZmFsc2UuJztcblxubGV0IGhhc0xvZ2dlZEJlZm9yZSA9IGZhbHNlO1xuXG5leHBvcnQgY29uc3QgbG9nV2FybmluZ3M6IExvZ1dhcm5pbmdzRnVuY3Rpb24gPSB3YXJuaW5ncyA9PiB7XG4gIC8vIGlmIHRoZSB3YXJuaW5ncyBhcnJheSBpcyBlbXB0eSwgZG8gbm90aGluZ1xuICBpZiAod2FybmluZ3MubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgbG9nZ2VyID0gZ2xvYmFsVGhpcy5BSV9TREtfTE9HX1dBUk5JTkdTO1xuXG4gIC8vIGlmIHRoZSBsb2dnZXIgaXMgc2V0IHRvIGZhbHNlLCBkbyBub3RoaW5nXG4gIGlmIChsb2dnZXIgPT09IGZhbHNlKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gdXNlIHRoZSBwcm92aWRlZCBsb2dnZXIgaWYgaXQgaXMgYSBmdW5jdGlvblxuICBpZiAodHlwZW9mIGxvZ2dlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGxvZ2dlcih3YXJuaW5ncyk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gZGlzcGxheSBpbmZvcm1hdGlvbiBub3RlIG9uIGZpcnN0IGNhbGxcbiAgaWYgKCFoYXNMb2dnZWRCZWZvcmUpIHtcbiAgICBoYXNMb2dnZWRCZWZvcmUgPSB0cnVlO1xuICAgIGNvbnNvbGUuaW5mbyhGSVJTVF9XQVJOSU5HX0lORk9fTUVTU0FHRSk7XG4gIH1cblxuICAvLyBkZWZhdWx0IGJlaGF2aW9yOiBsb2cgd2FybmluZ3MgdG8gdGhlIGNvbnNvbGVcbiAgZm9yIChjb25zdCB3YXJuaW5nIG9mIHdhcm5pbmdzKSB7XG4gICAgY29uc29sZS53YXJuKGZvcm1hdFdhcm5pbmcod2FybmluZykpO1xuICB9XG59O1xuXG4vLyBSZXNldCBmdW5jdGlvbiBmb3IgdGVzdGluZyBwdXJwb3Nlc1xuZXhwb3J0IGNvbnN0IHJlc2V0TG9nV2FybmluZ3NTdGF0ZSA9ICgpID0+IHtcbiAgaGFzTG9nZ2VkQmVmb3JlID0gZmFsc2U7XG59O1xuIiwgImltcG9ydCB7IGdhdGV3YXkgfSBmcm9tICdAYWktc2RrL2dhdGV3YXknO1xuaW1wb3J0IHtcbiAgRW1iZWRkaW5nTW9kZWxWMixcbiAgTGFuZ3VhZ2VNb2RlbFYyLFxuICBQcm92aWRlclYyLFxufSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcbmltcG9ydCB7IFVuc3VwcG9ydGVkTW9kZWxWZXJzaW9uRXJyb3IgfSBmcm9tICcuLi9lcnJvcic7XG5pbXBvcnQgeyBFbWJlZGRpbmdNb2RlbCB9IGZyb20gJy4uL3R5cGVzL2VtYmVkZGluZy1tb2RlbCc7XG5pbXBvcnQgeyBMYW5ndWFnZU1vZGVsIH0gZnJvbSAnLi4vdHlwZXMvbGFuZ3VhZ2UtbW9kZWwnO1xuXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZUxhbmd1YWdlTW9kZWwobW9kZWw6IExhbmd1YWdlTW9kZWwpOiBMYW5ndWFnZU1vZGVsVjIge1xuICBpZiAodHlwZW9mIG1vZGVsICE9PSAnc3RyaW5nJykge1xuICAgIGlmIChtb2RlbC5zcGVjaWZpY2F0aW9uVmVyc2lvbiAhPT0gJ3YyJykge1xuICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkTW9kZWxWZXJzaW9uRXJyb3Ioe1xuICAgICAgICB2ZXJzaW9uOiBtb2RlbC5zcGVjaWZpY2F0aW9uVmVyc2lvbixcbiAgICAgICAgcHJvdmlkZXI6IG1vZGVsLnByb3ZpZGVyLFxuICAgICAgICBtb2RlbElkOiBtb2RlbC5tb2RlbElkLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1vZGVsO1xuICB9XG5cbiAgcmV0dXJuIGdldEdsb2JhbFByb3ZpZGVyKCkubGFuZ3VhZ2VNb2RlbChtb2RlbCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlRW1iZWRkaW5nTW9kZWw8VkFMVUUgPSBzdHJpbmc+KFxuICBtb2RlbDogRW1iZWRkaW5nTW9kZWw8VkFMVUU+LFxuKTogRW1iZWRkaW5nTW9kZWxWMjxWQUxVRT4ge1xuICBpZiAodHlwZW9mIG1vZGVsICE9PSAnc3RyaW5nJykge1xuICAgIGlmIChtb2RlbC5zcGVjaWZpY2F0aW9uVmVyc2lvbiAhPT0gJ3YyJykge1xuICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkTW9kZWxWZXJzaW9uRXJyb3Ioe1xuICAgICAgICB2ZXJzaW9uOiBtb2RlbC5zcGVjaWZpY2F0aW9uVmVyc2lvbixcbiAgICAgICAgcHJvdmlkZXI6IG1vZGVsLnByb3ZpZGVyLFxuICAgICAgICBtb2RlbElkOiBtb2RlbC5tb2RlbElkLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1vZGVsO1xuICB9XG5cbiAgLy8gVE9ETyBBSSBTREsgNjogZmlndXJlIG91dCBob3cgdG8gY2xlYW5seSBzdXBwb3J0IGRpZmZlcmVudCBnZW5lcmljIHR5cGVzXG4gIHJldHVybiBnZXRHbG9iYWxQcm92aWRlcigpLnRleHRFbWJlZGRpbmdNb2RlbChcbiAgICBtb2RlbCxcbiAgKSBhcyBFbWJlZGRpbmdNb2RlbFYyPFZBTFVFPjtcbn1cblxuZnVuY3Rpb24gZ2V0R2xvYmFsUHJvdmlkZXIoKTogUHJvdmlkZXJWMiB7XG4gIHJldHVybiBnbG9iYWxUaGlzLkFJX1NES19ERUZBVUxUX1BST1ZJREVSID8/IGdhdGV3YXk7XG59XG4iLCAiZXhwb3J0IHtcbiAgQUlTREtFcnJvcixcbiAgQVBJQ2FsbEVycm9yLFxuICBFbXB0eVJlc3BvbnNlQm9keUVycm9yLFxuICBJbnZhbGlkUHJvbXB0RXJyb3IsXG4gIEludmFsaWRSZXNwb25zZURhdGFFcnJvcixcbiAgSlNPTlBhcnNlRXJyb3IsXG4gIExvYWRBUElLZXlFcnJvcixcbiAgTG9hZFNldHRpbmdFcnJvcixcbiAgTm9Db250ZW50R2VuZXJhdGVkRXJyb3IsXG4gIE5vU3VjaE1vZGVsRXJyb3IsXG4gIFRvb01hbnlFbWJlZGRpbmdWYWx1ZXNGb3JDYWxsRXJyb3IsXG4gIFR5cGVWYWxpZGF0aW9uRXJyb3IsXG4gIFVuc3VwcG9ydGVkRnVuY3Rpb25hbGl0eUVycm9yLFxufSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcblxuZXhwb3J0IHsgSW52YWxpZEFyZ3VtZW50RXJyb3IgfSBmcm9tICcuL2ludmFsaWQtYXJndW1lbnQtZXJyb3InO1xuZXhwb3J0IHsgSW52YWxpZFN0cmVhbVBhcnRFcnJvciB9IGZyb20gJy4vaW52YWxpZC1zdHJlYW0tcGFydC1lcnJvcic7XG5leHBvcnQgeyBJbnZhbGlkVG9vbElucHV0RXJyb3IgfSBmcm9tICcuL2ludmFsaWQtdG9vbC1pbnB1dC1lcnJvcic7XG5leHBvcnQgeyBNQ1BDbGllbnRFcnJvciB9IGZyb20gJy4vbWNwLWNsaWVudC1lcnJvcic7XG5leHBvcnQgeyBOb0ltYWdlR2VuZXJhdGVkRXJyb3IgfSBmcm9tICcuL25vLWltYWdlLWdlbmVyYXRlZC1lcnJvcic7XG5leHBvcnQgeyBOb09iamVjdEdlbmVyYXRlZEVycm9yIH0gZnJvbSAnLi9uby1vYmplY3QtZ2VuZXJhdGVkLWVycm9yJztcbmV4cG9ydCB7IE5vT3V0cHV0R2VuZXJhdGVkRXJyb3IgfSBmcm9tICcuL25vLW91dHB1dC1nZW5lcmF0ZWQtZXJyb3InO1xuZXhwb3J0IHsgTm9PdXRwdXRTcGVjaWZpZWRFcnJvciB9IGZyb20gJy4vbm8tb3V0cHV0LXNwZWNpZmllZC1lcnJvcic7XG5leHBvcnQgeyBOb1NwZWVjaEdlbmVyYXRlZEVycm9yIH0gZnJvbSAnLi9uby1zcGVlY2gtZ2VuZXJhdGVkLWVycm9yJztcbmV4cG9ydCB7IE5vU3VjaFRvb2xFcnJvciB9IGZyb20gJy4vbm8tc3VjaC10b29sLWVycm9yJztcbmV4cG9ydCB7IFRvb2xDYWxsUmVwYWlyRXJyb3IgfSBmcm9tICcuL3Rvb2wtY2FsbC1yZXBhaXItZXJyb3InO1xuZXhwb3J0IHsgVW5zdXBwb3J0ZWRNb2RlbFZlcnNpb25FcnJvciB9IGZyb20gJy4vdW5zdXBwb3J0ZWQtbW9kZWwtdmVyc2lvbi1lcnJvcic7XG5cbmV4cG9ydCB7IEludmFsaWREYXRhQ29udGVudEVycm9yIH0gZnJvbSAnLi4vcHJvbXB0L2ludmFsaWQtZGF0YS1jb250ZW50LWVycm9yJztcbmV4cG9ydCB7IEludmFsaWRNZXNzYWdlUm9sZUVycm9yIH0gZnJvbSAnLi4vcHJvbXB0L2ludmFsaWQtbWVzc2FnZS1yb2xlLWVycm9yJztcbmV4cG9ydCB7IE1lc3NhZ2VDb252ZXJzaW9uRXJyb3IgfSBmcm9tICcuLi9wcm9tcHQvbWVzc2FnZS1jb252ZXJzaW9uLWVycm9yJztcbmV4cG9ydCB7IERvd25sb2FkRXJyb3IgfSBmcm9tICcuLi91dGlsL2Rvd25sb2FkL2Rvd25sb2FkLWVycm9yJztcbmV4cG9ydCB7IFJldHJ5RXJyb3IgfSBmcm9tICcuLi91dGlsL3JldHJ5LWVycm9yJztcbiIsICJpbXBvcnQgeyBBSVNES0Vycm9yIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5cbmNvbnN0IG5hbWUgPSAnQUlfSW52YWxpZEFyZ3VtZW50RXJyb3InO1xuY29uc3QgbWFya2VyID0gYHZlcmNlbC5haS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuZXhwb3J0IGNsYXNzIEludmFsaWRBcmd1bWVudEVycm9yIGV4dGVuZHMgQUlTREtFcnJvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgW3N5bWJvbF0gPSB0cnVlOyAvLyB1c2VkIGluIGlzSW5zdGFuY2VcblxuICByZWFkb25seSBwYXJhbWV0ZXI6IHN0cmluZztcbiAgcmVhZG9ubHkgdmFsdWU6IHVua25vd247XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIHBhcmFtZXRlcixcbiAgICB2YWx1ZSxcbiAgICBtZXNzYWdlLFxuICB9OiB7XG4gICAgcGFyYW1ldGVyOiBzdHJpbmc7XG4gICAgdmFsdWU6IHVua25vd247XG4gICAgbWVzc2FnZTogc3RyaW5nO1xuICB9KSB7XG4gICAgc3VwZXIoe1xuICAgICAgbmFtZSxcbiAgICAgIG1lc3NhZ2U6IGBJbnZhbGlkIGFyZ3VtZW50IGZvciBwYXJhbWV0ZXIgJHtwYXJhbWV0ZXJ9OiAke21lc3NhZ2V9YCxcbiAgICB9KTtcblxuICAgIHRoaXMucGFyYW1ldGVyID0gcGFyYW1ldGVyO1xuICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgfVxuXG4gIHN0YXRpYyBpc0luc3RhbmNlKGVycm9yOiB1bmtub3duKTogZXJyb3IgaXMgSW52YWxpZEFyZ3VtZW50RXJyb3Ige1xuICAgIHJldHVybiBBSVNES0Vycm9yLmhhc01hcmtlcihlcnJvciwgbWFya2VyKTtcbiAgfVxufVxuIiwgImltcG9ydCB7IEFJU0RLRXJyb3IgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcbmltcG9ydCB7IFNpbmdsZVJlcXVlc3RUZXh0U3RyZWFtUGFydCB9IGZyb20gJy4uL2dlbmVyYXRlLXRleHQvcnVuLXRvb2xzLXRyYW5zZm9ybWF0aW9uJztcblxuY29uc3QgbmFtZSA9ICdBSV9JbnZhbGlkU3RyZWFtUGFydEVycm9yJztcbmNvbnN0IG1hcmtlciA9IGB2ZXJjZWwuYWkuZXJyb3IuJHtuYW1lfWA7XG5jb25zdCBzeW1ib2wgPSBTeW1ib2wuZm9yKG1hcmtlcik7XG5cbmV4cG9ydCBjbGFzcyBJbnZhbGlkU3RyZWFtUGFydEVycm9yIGV4dGVuZHMgQUlTREtFcnJvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgW3N5bWJvbF0gPSB0cnVlOyAvLyB1c2VkIGluIGlzSW5zdGFuY2VcblxuICByZWFkb25seSBjaHVuazogU2luZ2xlUmVxdWVzdFRleHRTdHJlYW1QYXJ0PGFueT47XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIGNodW5rLFxuICAgIG1lc3NhZ2UsXG4gIH06IHtcbiAgICBjaHVuazogU2luZ2xlUmVxdWVzdFRleHRTdHJlYW1QYXJ0PGFueT47XG4gICAgbWVzc2FnZTogc3RyaW5nO1xuICB9KSB7XG4gICAgc3VwZXIoeyBuYW1lLCBtZXNzYWdlIH0pO1xuXG4gICAgdGhpcy5jaHVuayA9IGNodW5rO1xuICB9XG5cbiAgc3RhdGljIGlzSW5zdGFuY2UoZXJyb3I6IHVua25vd24pOiBlcnJvciBpcyBJbnZhbGlkU3RyZWFtUGFydEVycm9yIHtcbiAgICByZXR1cm4gQUlTREtFcnJvci5oYXNNYXJrZXIoZXJyb3IsIG1hcmtlcik7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBBSVNES0Vycm9yLCBnZXRFcnJvck1lc3NhZ2UgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcblxuY29uc3QgbmFtZSA9ICdBSV9JbnZhbGlkVG9vbElucHV0RXJyb3InO1xuY29uc3QgbWFya2VyID0gYHZlcmNlbC5haS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuZXhwb3J0IGNsYXNzIEludmFsaWRUb29sSW5wdXRFcnJvciBleHRlbmRzIEFJU0RLRXJyb3Ige1xuICBwcml2YXRlIHJlYWRvbmx5IFtzeW1ib2xdID0gdHJ1ZTsgLy8gdXNlZCBpbiBpc0luc3RhbmNlXG5cbiAgcmVhZG9ubHkgdG9vbE5hbWU6IHN0cmluZztcbiAgcmVhZG9ubHkgdG9vbElucHV0OiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIHRvb2xJbnB1dCxcbiAgICB0b29sTmFtZSxcbiAgICBjYXVzZSxcbiAgICBtZXNzYWdlID0gYEludmFsaWQgaW5wdXQgZm9yIHRvb2wgJHt0b29sTmFtZX06ICR7Z2V0RXJyb3JNZXNzYWdlKGNhdXNlKX1gLFxuICB9OiB7XG4gICAgbWVzc2FnZT86IHN0cmluZztcbiAgICB0b29sSW5wdXQ6IHN0cmluZztcbiAgICB0b29sTmFtZTogc3RyaW5nO1xuICAgIGNhdXNlOiB1bmtub3duO1xuICB9KSB7XG4gICAgc3VwZXIoeyBuYW1lLCBtZXNzYWdlLCBjYXVzZSB9KTtcblxuICAgIHRoaXMudG9vbElucHV0ID0gdG9vbElucHV0O1xuICAgIHRoaXMudG9vbE5hbWUgPSB0b29sTmFtZTtcbiAgfVxuXG4gIHN0YXRpYyBpc0luc3RhbmNlKGVycm9yOiB1bmtub3duKTogZXJyb3IgaXMgSW52YWxpZFRvb2xJbnB1dEVycm9yIHtcbiAgICByZXR1cm4gQUlTREtFcnJvci5oYXNNYXJrZXIoZXJyb3IsIG1hcmtlcik7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBBSVNES0Vycm9yIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5cbmNvbnN0IG5hbWUgPSAnQUlfTUNQQ2xpZW50RXJyb3InO1xuY29uc3QgbWFya2VyID0gYHZlcmNlbC5haS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuLyoqXG4gKiBBbiBlcnJvciBvY2N1cnJlZCB3aXRoIHRoZSBNQ1AgY2xpZW50LlxuICovXG5leHBvcnQgY2xhc3MgTUNQQ2xpZW50RXJyb3IgZXh0ZW5kcyBBSVNES0Vycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7XG4gIHJlYWRvbmx5IGRhdGE/OiB1bmtub3duO1xuICByZWFkb25seSBjb2RlPzogbnVtYmVyO1xuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICBuYW1lID0gJ01DUENsaWVudEVycm9yJyxcbiAgICBtZXNzYWdlLFxuICAgIGNhdXNlLFxuICAgIGRhdGEsXG4gICAgY29kZSxcbiAgfToge1xuICAgIG5hbWU/OiBzdHJpbmc7XG4gICAgbWVzc2FnZTogc3RyaW5nO1xuICAgIGNhdXNlPzogdW5rbm93bjtcbiAgICBkYXRhPzogdW5rbm93bjtcbiAgICBjb2RlPzogbnVtYmVyO1xuICB9KSB7XG4gICAgc3VwZXIoeyBuYW1lLCBtZXNzYWdlLCBjYXVzZSB9KTtcbiAgICB0aGlzLmRhdGEgPSBkYXRhO1xuICAgIHRoaXMuY29kZSA9IGNvZGU7XG4gIH1cblxuICBzdGF0aWMgaXNJbnN0YW5jZShlcnJvcjogdW5rbm93bik6IGVycm9yIGlzIE1DUENsaWVudEVycm9yIHtcbiAgICByZXR1cm4gQUlTREtFcnJvci5oYXNNYXJrZXIoZXJyb3IsIG1hcmtlcik7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBBSVNES0Vycm9yIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQgeyBJbWFnZU1vZGVsUmVzcG9uc2VNZXRhZGF0YSB9IGZyb20gJy4uL3R5cGVzL2ltYWdlLW1vZGVsLXJlc3BvbnNlLW1ldGFkYXRhJztcblxuY29uc3QgbmFtZSA9ICdBSV9Ob0ltYWdlR2VuZXJhdGVkRXJyb3InO1xuY29uc3QgbWFya2VyID0gYHZlcmNlbC5haS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuLyoqXG5UaHJvd24gd2hlbiBubyBpbWFnZSBjb3VsZCBiZSBnZW5lcmF0ZWQuIFRoaXMgY2FuIGhhdmUgbXVsdGlwbGUgY2F1c2VzOlxuXG4tIFRoZSBtb2RlbCBmYWlsZWQgdG8gZ2VuZXJhdGUgYSByZXNwb25zZS5cbi0gVGhlIG1vZGVsIGdlbmVyYXRlZCBhIHJlc3BvbnNlIHRoYXQgY291bGQgbm90IGJlIHBhcnNlZC5cbiAqL1xuZXhwb3J0IGNsYXNzIE5vSW1hZ2VHZW5lcmF0ZWRFcnJvciBleHRlbmRzIEFJU0RLRXJyb3Ige1xuICBwcml2YXRlIHJlYWRvbmx5IFtzeW1ib2xdID0gdHJ1ZTsgLy8gdXNlZCBpbiBpc0luc3RhbmNlXG5cbiAgLyoqXG5UaGUgcmVzcG9uc2UgbWV0YWRhdGEgZm9yIGVhY2ggY2FsbC5cbiAgICovXG4gIHJlYWRvbmx5IHJlc3BvbnNlczogQXJyYXk8SW1hZ2VNb2RlbFJlc3BvbnNlTWV0YWRhdGE+IHwgdW5kZWZpbmVkO1xuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICBtZXNzYWdlID0gJ05vIGltYWdlIGdlbmVyYXRlZC4nLFxuICAgIGNhdXNlLFxuICAgIHJlc3BvbnNlcyxcbiAgfToge1xuICAgIG1lc3NhZ2U/OiBzdHJpbmc7XG4gICAgY2F1c2U/OiBFcnJvcjtcbiAgICByZXNwb25zZXM/OiBBcnJheTxJbWFnZU1vZGVsUmVzcG9uc2VNZXRhZGF0YT47XG4gIH0pIHtcbiAgICBzdXBlcih7IG5hbWUsIG1lc3NhZ2UsIGNhdXNlIH0pO1xuXG4gICAgdGhpcy5yZXNwb25zZXMgPSByZXNwb25zZXM7XG4gIH1cblxuICBzdGF0aWMgaXNJbnN0YW5jZShlcnJvcjogdW5rbm93bik6IGVycm9yIGlzIE5vSW1hZ2VHZW5lcmF0ZWRFcnJvciB7XG4gICAgcmV0dXJuIEFJU0RLRXJyb3IuaGFzTWFya2VyKGVycm9yLCBtYXJrZXIpO1xuICB9XG59XG4iLCAiaW1wb3J0IHsgQUlTREtFcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgRmluaXNoUmVhc29uIH0gZnJvbSAnLi4vdHlwZXMvbGFuZ3VhZ2UtbW9kZWwnO1xuaW1wb3J0IHsgTGFuZ3VhZ2VNb2RlbFJlc3BvbnNlTWV0YWRhdGEgfSBmcm9tICcuLi90eXBlcy9sYW5ndWFnZS1tb2RlbC1yZXNwb25zZS1tZXRhZGF0YSc7XG5pbXBvcnQgeyBMYW5ndWFnZU1vZGVsVXNhZ2UgfSBmcm9tICcuLi90eXBlcy91c2FnZSc7XG5cbmNvbnN0IG5hbWUgPSAnQUlfTm9PYmplY3RHZW5lcmF0ZWRFcnJvcic7XG5jb25zdCBtYXJrZXIgPSBgdmVyY2VsLmFpLmVycm9yLiR7bmFtZX1gO1xuY29uc3Qgc3ltYm9sID0gU3ltYm9sLmZvcihtYXJrZXIpO1xuXG4vKipcblRocm93biB3aGVuIG5vIG9iamVjdCBjb3VsZCBiZSBnZW5lcmF0ZWQuIFRoaXMgY2FuIGhhdmUgc2V2ZXJhbCBjYXVzZXM6XG5cbi0gVGhlIG1vZGVsIGZhaWxlZCB0byBnZW5lcmF0ZSBhIHJlc3BvbnNlLlxuLSBUaGUgbW9kZWwgZ2VuZXJhdGVkIGEgcmVzcG9uc2UgdGhhdCBjb3VsZCBub3QgYmUgcGFyc2VkLlxuLSBUaGUgbW9kZWwgZ2VuZXJhdGVkIGEgcmVzcG9uc2UgdGhhdCBjb3VsZCBub3QgYmUgdmFsaWRhdGVkIGFnYWluc3QgdGhlIHNjaGVtYS5cblxuVGhlIGVycm9yIGNvbnRhaW5zIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczpcblxuLSBgdGV4dGA6IFRoZSB0ZXh0IHRoYXQgd2FzIGdlbmVyYXRlZCBieSB0aGUgbW9kZWwuIFRoaXMgY2FuIGJlIHRoZSByYXcgdGV4dCBvciB0aGUgdG9vbCBjYWxsIHRleHQsIGRlcGVuZGluZyBvbiB0aGUgbW9kZWwuXG4gKi9cbmV4cG9ydCBjbGFzcyBOb09iamVjdEdlbmVyYXRlZEVycm9yIGV4dGVuZHMgQUlTREtFcnJvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgW3N5bWJvbF0gPSB0cnVlOyAvLyB1c2VkIGluIGlzSW5zdGFuY2VcblxuICAvKipcbiAgVGhlIHRleHQgdGhhdCB3YXMgZ2VuZXJhdGVkIGJ5IHRoZSBtb2RlbC4gVGhpcyBjYW4gYmUgdGhlIHJhdyB0ZXh0IG9yIHRoZSB0b29sIGNhbGwgdGV4dCwgZGVwZW5kaW5nIG9uIHRoZSBtb2RlbC5cbiAgICovXG4gIHJlYWRvbmx5IHRleHQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgVGhlIHJlc3BvbnNlIG1ldGFkYXRhLlxuICAgKi9cbiAgcmVhZG9ubHkgcmVzcG9uc2U6IExhbmd1YWdlTW9kZWxSZXNwb25zZU1ldGFkYXRhIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICBUaGUgdXNhZ2Ugb2YgdGhlIG1vZGVsLlxuICAgKi9cbiAgcmVhZG9ubHkgdXNhZ2U6IExhbmd1YWdlTW9kZWxVc2FnZSB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgUmVhc29uIHdoeSB0aGUgbW9kZWwgZmluaXNoZWQgZ2VuZXJhdGluZyBhIHJlc3BvbnNlLlxuICAgKi9cbiAgcmVhZG9ubHkgZmluaXNoUmVhc29uOiBGaW5pc2hSZWFzb24gfCB1bmRlZmluZWQ7XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIG1lc3NhZ2UgPSAnTm8gb2JqZWN0IGdlbmVyYXRlZC4nLFxuICAgIGNhdXNlLFxuICAgIHRleHQsXG4gICAgcmVzcG9uc2UsXG4gICAgdXNhZ2UsXG4gICAgZmluaXNoUmVhc29uLFxuICB9OiB7XG4gICAgbWVzc2FnZT86IHN0cmluZztcbiAgICBjYXVzZT86IEVycm9yO1xuICAgIHRleHQ/OiBzdHJpbmc7XG4gICAgcmVzcG9uc2U6IExhbmd1YWdlTW9kZWxSZXNwb25zZU1ldGFkYXRhO1xuICAgIHVzYWdlOiBMYW5ndWFnZU1vZGVsVXNhZ2U7XG4gICAgZmluaXNoUmVhc29uOiBGaW5pc2hSZWFzb247XG4gIH0pIHtcbiAgICBzdXBlcih7IG5hbWUsIG1lc3NhZ2UsIGNhdXNlIH0pO1xuXG4gICAgdGhpcy50ZXh0ID0gdGV4dDtcbiAgICB0aGlzLnJlc3BvbnNlID0gcmVzcG9uc2U7XG4gICAgdGhpcy51c2FnZSA9IHVzYWdlO1xuICAgIHRoaXMuZmluaXNoUmVhc29uID0gZmluaXNoUmVhc29uO1xuICB9XG5cbiAgc3RhdGljIGlzSW5zdGFuY2UoZXJyb3I6IHVua25vd24pOiBlcnJvciBpcyBOb09iamVjdEdlbmVyYXRlZEVycm9yIHtcbiAgICByZXR1cm4gQUlTREtFcnJvci5oYXNNYXJrZXIoZXJyb3IsIG1hcmtlcik7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBBSVNES0Vycm9yIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5cbmNvbnN0IG5hbWUgPSAnQUlfTm9PdXRwdXRHZW5lcmF0ZWRFcnJvcic7XG5jb25zdCBtYXJrZXIgPSBgdmVyY2VsLmFpLmVycm9yLiR7bmFtZX1gO1xuY29uc3Qgc3ltYm9sID0gU3ltYm9sLmZvcihtYXJrZXIpO1xuXG4vKipcblRocm93biB3aGVuIG5vIExMTSBvdXRwdXQgd2FzIGdlbmVyYXRlZCwgZS5nLiBiZWNhdXNlIG9mIGVycm9ycy5cbiAqL1xuZXhwb3J0IGNsYXNzIE5vT3V0cHV0R2VuZXJhdGVkRXJyb3IgZXh0ZW5kcyBBSVNES0Vycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7IC8vIHVzZWQgaW4gaXNJbnN0YW5jZVxuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICBtZXNzYWdlID0gJ05vIG91dHB1dCBnZW5lcmF0ZWQuJyxcbiAgICBjYXVzZSxcbiAgfToge1xuICAgIG1lc3NhZ2U/OiBzdHJpbmc7XG4gICAgY2F1c2U/OiBFcnJvcjtcbiAgfSA9IHt9KSB7XG4gICAgc3VwZXIoeyBuYW1lLCBtZXNzYWdlLCBjYXVzZSB9KTtcbiAgfVxuXG4gIHN0YXRpYyBpc0luc3RhbmNlKGVycm9yOiB1bmtub3duKTogZXJyb3IgaXMgTm9PdXRwdXRHZW5lcmF0ZWRFcnJvciB7XG4gICAgcmV0dXJuIEFJU0RLRXJyb3IuaGFzTWFya2VyKGVycm9yLCBtYXJrZXIpO1xuICB9XG59XG4iLCAiaW1wb3J0IHsgQUlTREtFcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgU3BlZWNoTW9kZWxSZXNwb25zZU1ldGFkYXRhIH0gZnJvbSAnLi4vdHlwZXMvc3BlZWNoLW1vZGVsLXJlc3BvbnNlLW1ldGFkYXRhJztcblxuLyoqXG5FcnJvciB0aGF0IGlzIHRocm93biB3aGVuIG5vIHNwZWVjaCBhdWRpbyB3YXMgZ2VuZXJhdGVkLlxuICovXG5leHBvcnQgY2xhc3MgTm9TcGVlY2hHZW5lcmF0ZWRFcnJvciBleHRlbmRzIEFJU0RLRXJyb3Ige1xuICByZWFkb25seSByZXNwb25zZXM6IEFycmF5PFNwZWVjaE1vZGVsUmVzcG9uc2VNZXRhZGF0YT47XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczogeyByZXNwb25zZXM6IEFycmF5PFNwZWVjaE1vZGVsUmVzcG9uc2VNZXRhZGF0YT4gfSkge1xuICAgIHN1cGVyKHtcbiAgICAgIG5hbWU6ICdBSV9Ob1NwZWVjaEdlbmVyYXRlZEVycm9yJyxcbiAgICAgIG1lc3NhZ2U6ICdObyBzcGVlY2ggYXVkaW8gZ2VuZXJhdGVkLicsXG4gICAgfSk7XG5cbiAgICB0aGlzLnJlc3BvbnNlcyA9IG9wdGlvbnMucmVzcG9uc2VzO1xuICB9XG59XG4iLCAiaW1wb3J0IHsgQUlTREtFcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuXG5jb25zdCBuYW1lID0gJ0FJX05vU3VjaFRvb2xFcnJvcic7XG5jb25zdCBtYXJrZXIgPSBgdmVyY2VsLmFpLmVycm9yLiR7bmFtZX1gO1xuY29uc3Qgc3ltYm9sID0gU3ltYm9sLmZvcihtYXJrZXIpO1xuXG5leHBvcnQgY2xhc3MgTm9TdWNoVG9vbEVycm9yIGV4dGVuZHMgQUlTREtFcnJvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgW3N5bWJvbF0gPSB0cnVlOyAvLyB1c2VkIGluIGlzSW5zdGFuY2VcblxuICByZWFkb25seSB0b29sTmFtZTogc3RyaW5nO1xuICByZWFkb25seSBhdmFpbGFibGVUb29sczogc3RyaW5nW10gfCB1bmRlZmluZWQ7XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIHRvb2xOYW1lLFxuICAgIGF2YWlsYWJsZVRvb2xzID0gdW5kZWZpbmVkLFxuICAgIG1lc3NhZ2UgPSBgTW9kZWwgdHJpZWQgdG8gY2FsbCB1bmF2YWlsYWJsZSB0b29sICcke3Rvb2xOYW1lfScuICR7XG4gICAgICBhdmFpbGFibGVUb29scyA9PT0gdW5kZWZpbmVkXG4gICAgICAgID8gJ05vIHRvb2xzIGFyZSBhdmFpbGFibGUuJ1xuICAgICAgICA6IGBBdmFpbGFibGUgdG9vbHM6ICR7YXZhaWxhYmxlVG9vbHMuam9pbignLCAnKX0uYFxuICAgIH1gLFxuICB9OiB7XG4gICAgdG9vbE5hbWU6IHN0cmluZztcbiAgICBhdmFpbGFibGVUb29scz86IHN0cmluZ1tdIHwgdW5kZWZpbmVkO1xuICAgIG1lc3NhZ2U/OiBzdHJpbmc7XG4gIH0pIHtcbiAgICBzdXBlcih7IG5hbWUsIG1lc3NhZ2UgfSk7XG5cbiAgICB0aGlzLnRvb2xOYW1lID0gdG9vbE5hbWU7XG4gICAgdGhpcy5hdmFpbGFibGVUb29scyA9IGF2YWlsYWJsZVRvb2xzO1xuICB9XG5cbiAgc3RhdGljIGlzSW5zdGFuY2UoZXJyb3I6IHVua25vd24pOiBlcnJvciBpcyBOb1N1Y2hUb29sRXJyb3Ige1xuICAgIHJldHVybiBBSVNES0Vycm9yLmhhc01hcmtlcihlcnJvciwgbWFya2VyKTtcbiAgfVxufVxuIiwgImltcG9ydCB7IEFJU0RLRXJyb3IsIGdldEVycm9yTWVzc2FnZSB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgSW52YWxpZFRvb2xJbnB1dEVycm9yIH0gZnJvbSAnLi9pbnZhbGlkLXRvb2wtaW5wdXQtZXJyb3InO1xuaW1wb3J0IHsgTm9TdWNoVG9vbEVycm9yIH0gZnJvbSAnLi9uby1zdWNoLXRvb2wtZXJyb3InO1xuXG5jb25zdCBuYW1lID0gJ0FJX1Rvb2xDYWxsUmVwYWlyRXJyb3InO1xuY29uc3QgbWFya2VyID0gYHZlcmNlbC5haS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuZXhwb3J0IGNsYXNzIFRvb2xDYWxsUmVwYWlyRXJyb3IgZXh0ZW5kcyBBSVNES0Vycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7IC8vIHVzZWQgaW4gaXNJbnN0YW5jZVxuXG4gIHJlYWRvbmx5IG9yaWdpbmFsRXJyb3I6IE5vU3VjaFRvb2xFcnJvciB8IEludmFsaWRUb29sSW5wdXRFcnJvcjtcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgY2F1c2UsXG4gICAgb3JpZ2luYWxFcnJvcixcbiAgICBtZXNzYWdlID0gYEVycm9yIHJlcGFpcmluZyB0b29sIGNhbGw6ICR7Z2V0RXJyb3JNZXNzYWdlKGNhdXNlKX1gLFxuICB9OiB7XG4gICAgbWVzc2FnZT86IHN0cmluZztcbiAgICBjYXVzZTogdW5rbm93bjtcbiAgICBvcmlnaW5hbEVycm9yOiBOb1N1Y2hUb29sRXJyb3IgfCBJbnZhbGlkVG9vbElucHV0RXJyb3I7XG4gIH0pIHtcbiAgICBzdXBlcih7IG5hbWUsIG1lc3NhZ2UsIGNhdXNlIH0pO1xuICAgIHRoaXMub3JpZ2luYWxFcnJvciA9IG9yaWdpbmFsRXJyb3I7XG4gIH1cblxuICBzdGF0aWMgaXNJbnN0YW5jZShlcnJvcjogdW5rbm93bik6IGVycm9yIGlzIFRvb2xDYWxsUmVwYWlyRXJyb3Ige1xuICAgIHJldHVybiBBSVNES0Vycm9yLmhhc01hcmtlcihlcnJvciwgbWFya2VyKTtcbiAgfVxufVxuIiwgImltcG9ydCB7IEFJU0RLRXJyb3IgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcblxuLyoqXG5FcnJvciB0aGF0IGlzIHRocm93biB3aGVuIGEgbW9kZWwgd2l0aCBhbiB1bnN1cHBvcnRlZCB2ZXJzaW9uIGlzIHVzZWQuXG4gKi9cbmV4cG9ydCBjbGFzcyBVbnN1cHBvcnRlZE1vZGVsVmVyc2lvbkVycm9yIGV4dGVuZHMgQUlTREtFcnJvciB7XG4gIHJlYWRvbmx5IHZlcnNpb246IHN0cmluZztcbiAgcmVhZG9ubHkgcHJvdmlkZXI6IHN0cmluZztcbiAgcmVhZG9ubHkgbW9kZWxJZDogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IHsgdmVyc2lvbjogc3RyaW5nOyBwcm92aWRlcjogc3RyaW5nOyBtb2RlbElkOiBzdHJpbmcgfSkge1xuICAgIHN1cGVyKHtcbiAgICAgIG5hbWU6ICdBSV9VbnN1cHBvcnRlZE1vZGVsVmVyc2lvbkVycm9yJyxcbiAgICAgIG1lc3NhZ2U6XG4gICAgICAgIGBVbnN1cHBvcnRlZCBtb2RlbCB2ZXJzaW9uICR7b3B0aW9ucy52ZXJzaW9ufSBmb3IgcHJvdmlkZXIgXCIke29wdGlvbnMucHJvdmlkZXJ9XCIgYW5kIG1vZGVsIFwiJHtvcHRpb25zLm1vZGVsSWR9XCIuIGAgK1xuICAgICAgICBgQUkgU0RLIDUgb25seSBzdXBwb3J0cyBtb2RlbHMgdGhhdCBpbXBsZW1lbnQgc3BlY2lmaWNhdGlvbiB2ZXJzaW9uIFwidjJcIi5gLFxuICAgIH0pO1xuXG4gICAgdGhpcy52ZXJzaW9uID0gb3B0aW9ucy52ZXJzaW9uO1xuICAgIHRoaXMucHJvdmlkZXIgPSBvcHRpb25zLnByb3ZpZGVyO1xuICAgIHRoaXMubW9kZWxJZCA9IG9wdGlvbnMubW9kZWxJZDtcbiAgfVxufVxuIiwgImltcG9ydCB7IEFJU0RLRXJyb3IgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcblxuY29uc3QgbmFtZSA9ICdBSV9JbnZhbGlkRGF0YUNvbnRlbnRFcnJvcic7XG5jb25zdCBtYXJrZXIgPSBgdmVyY2VsLmFpLmVycm9yLiR7bmFtZX1gO1xuY29uc3Qgc3ltYm9sID0gU3ltYm9sLmZvcihtYXJrZXIpO1xuXG5leHBvcnQgY2xhc3MgSW52YWxpZERhdGFDb250ZW50RXJyb3IgZXh0ZW5kcyBBSVNES0Vycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7IC8vIHVzZWQgaW4gaXNJbnN0YW5jZVxuXG4gIHJlYWRvbmx5IGNvbnRlbnQ6IHVua25vd247XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIGNvbnRlbnQsXG4gICAgY2F1c2UsXG4gICAgbWVzc2FnZSA9IGBJbnZhbGlkIGRhdGEgY29udGVudC4gRXhwZWN0ZWQgYSBiYXNlNjQgc3RyaW5nLCBVaW50OEFycmF5LCBBcnJheUJ1ZmZlciwgb3IgQnVmZmVyLCBidXQgZ290ICR7dHlwZW9mIGNvbnRlbnR9LmAsXG4gIH06IHtcbiAgICBjb250ZW50OiB1bmtub3duO1xuICAgIGNhdXNlPzogdW5rbm93bjtcbiAgICBtZXNzYWdlPzogc3RyaW5nO1xuICB9KSB7XG4gICAgc3VwZXIoeyBuYW1lLCBtZXNzYWdlLCBjYXVzZSB9KTtcblxuICAgIHRoaXMuY29udGVudCA9IGNvbnRlbnQ7XG4gIH1cblxuICBzdGF0aWMgaXNJbnN0YW5jZShlcnJvcjogdW5rbm93bik6IGVycm9yIGlzIEludmFsaWREYXRhQ29udGVudEVycm9yIHtcbiAgICByZXR1cm4gQUlTREtFcnJvci5oYXNNYXJrZXIoZXJyb3IsIG1hcmtlcik7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBBSVNES0Vycm9yIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5cbmNvbnN0IG5hbWUgPSAnQUlfSW52YWxpZE1lc3NhZ2VSb2xlRXJyb3InO1xuY29uc3QgbWFya2VyID0gYHZlcmNlbC5haS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuZXhwb3J0IGNsYXNzIEludmFsaWRNZXNzYWdlUm9sZUVycm9yIGV4dGVuZHMgQUlTREtFcnJvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgW3N5bWJvbF0gPSB0cnVlOyAvLyB1c2VkIGluIGlzSW5zdGFuY2VcblxuICByZWFkb25seSByb2xlOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIHJvbGUsXG4gICAgbWVzc2FnZSA9IGBJbnZhbGlkIG1lc3NhZ2Ugcm9sZTogJyR7cm9sZX0nLiBNdXN0IGJlIG9uZSBvZjogXCJzeXN0ZW1cIiwgXCJ1c2VyXCIsIFwiYXNzaXN0YW50XCIsIFwidG9vbFwiLmAsXG4gIH06IHtcbiAgICByb2xlOiBzdHJpbmc7XG4gICAgbWVzc2FnZT86IHN0cmluZztcbiAgfSkge1xuICAgIHN1cGVyKHsgbmFtZSwgbWVzc2FnZSB9KTtcblxuICAgIHRoaXMucm9sZSA9IHJvbGU7XG4gIH1cblxuICBzdGF0aWMgaXNJbnN0YW5jZShlcnJvcjogdW5rbm93bik6IGVycm9yIGlzIEludmFsaWRNZXNzYWdlUm9sZUVycm9yIHtcbiAgICByZXR1cm4gQUlTREtFcnJvci5oYXNNYXJrZXIoZXJyb3IsIG1hcmtlcik7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBBSVNES0Vycm9yIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQgeyBVSU1lc3NhZ2UgfSBmcm9tICcuLi91aS91aS1tZXNzYWdlcyc7XG5cbmNvbnN0IG5hbWUgPSAnQUlfTWVzc2FnZUNvbnZlcnNpb25FcnJvcic7XG5jb25zdCBtYXJrZXIgPSBgdmVyY2VsLmFpLmVycm9yLiR7bmFtZX1gO1xuY29uc3Qgc3ltYm9sID0gU3ltYm9sLmZvcihtYXJrZXIpO1xuXG5leHBvcnQgY2xhc3MgTWVzc2FnZUNvbnZlcnNpb25FcnJvciBleHRlbmRzIEFJU0RLRXJyb3Ige1xuICBwcml2YXRlIHJlYWRvbmx5IFtzeW1ib2xdID0gdHJ1ZTsgLy8gdXNlZCBpbiBpc0luc3RhbmNlXG5cbiAgcmVhZG9ubHkgb3JpZ2luYWxNZXNzYWdlOiBPbWl0PFVJTWVzc2FnZSwgJ2lkJz47XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIG9yaWdpbmFsTWVzc2FnZSxcbiAgICBtZXNzYWdlLFxuICB9OiB7XG4gICAgb3JpZ2luYWxNZXNzYWdlOiBPbWl0PFVJTWVzc2FnZSwgJ2lkJz47XG4gICAgbWVzc2FnZTogc3RyaW5nO1xuICB9KSB7XG4gICAgc3VwZXIoeyBuYW1lLCBtZXNzYWdlIH0pO1xuXG4gICAgdGhpcy5vcmlnaW5hbE1lc3NhZ2UgPSBvcmlnaW5hbE1lc3NhZ2U7XG4gIH1cblxuICBzdGF0aWMgaXNJbnN0YW5jZShlcnJvcjogdW5rbm93bik6IGVycm9yIGlzIE1lc3NhZ2VDb252ZXJzaW9uRXJyb3Ige1xuICAgIHJldHVybiBBSVNES0Vycm9yLmhhc01hcmtlcihlcnJvciwgbWFya2VyKTtcbiAgfVxufVxuIiwgImltcG9ydCB7IEFJU0RLRXJyb3IgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcblxuY29uc3QgbmFtZSA9ICdBSV9Eb3dubG9hZEVycm9yJztcbmNvbnN0IG1hcmtlciA9IGB2ZXJjZWwuYWkuZXJyb3IuJHtuYW1lfWA7XG5jb25zdCBzeW1ib2wgPSBTeW1ib2wuZm9yKG1hcmtlcik7XG5cbmV4cG9ydCBjbGFzcyBEb3dubG9hZEVycm9yIGV4dGVuZHMgQUlTREtFcnJvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgW3N5bWJvbF0gPSB0cnVlOyAvLyB1c2VkIGluIGlzSW5zdGFuY2VcblxuICByZWFkb25seSB1cmw6IHN0cmluZztcbiAgcmVhZG9ubHkgc3RhdHVzQ29kZT86IG51bWJlcjtcbiAgcmVhZG9ubHkgc3RhdHVzVGV4dD86IHN0cmluZztcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgdXJsLFxuICAgIHN0YXR1c0NvZGUsXG4gICAgc3RhdHVzVGV4dCxcbiAgICBjYXVzZSxcbiAgICBtZXNzYWdlID0gY2F1c2UgPT0gbnVsbFxuICAgICAgPyBgRmFpbGVkIHRvIGRvd25sb2FkICR7dXJsfTogJHtzdGF0dXNDb2RlfSAke3N0YXR1c1RleHR9YFxuICAgICAgOiBgRmFpbGVkIHRvIGRvd25sb2FkICR7dXJsfTogJHtjYXVzZX1gLFxuICB9OiB7XG4gICAgdXJsOiBzdHJpbmc7XG4gICAgc3RhdHVzQ29kZT86IG51bWJlcjtcbiAgICBzdGF0dXNUZXh0Pzogc3RyaW5nO1xuICAgIG1lc3NhZ2U/OiBzdHJpbmc7XG4gICAgY2F1c2U/OiB1bmtub3duO1xuICB9KSB7XG4gICAgc3VwZXIoeyBuYW1lLCBtZXNzYWdlLCBjYXVzZSB9KTtcblxuICAgIHRoaXMudXJsID0gdXJsO1xuICAgIHRoaXMuc3RhdHVzQ29kZSA9IHN0YXR1c0NvZGU7XG4gICAgdGhpcy5zdGF0dXNUZXh0ID0gc3RhdHVzVGV4dDtcbiAgfVxuXG4gIHN0YXRpYyBpc0luc3RhbmNlKGVycm9yOiB1bmtub3duKTogZXJyb3IgaXMgRG93bmxvYWRFcnJvciB7XG4gICAgcmV0dXJuIEFJU0RLRXJyb3IuaGFzTWFya2VyKGVycm9yLCBtYXJrZXIpO1xuICB9XG59XG4iLCAiaW1wb3J0IHsgQUlTREtFcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuXG5jb25zdCBuYW1lID0gJ0FJX1JldHJ5RXJyb3InO1xuY29uc3QgbWFya2VyID0gYHZlcmNlbC5haS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuZXhwb3J0IHR5cGUgUmV0cnlFcnJvclJlYXNvbiA9XG4gIHwgJ21heFJldHJpZXNFeGNlZWRlZCdcbiAgfCAnZXJyb3JOb3RSZXRyeWFibGUnXG4gIHwgJ2Fib3J0JztcblxuZXhwb3J0IGNsYXNzIFJldHJ5RXJyb3IgZXh0ZW5kcyBBSVNES0Vycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7IC8vIHVzZWQgaW4gaXNJbnN0YW5jZVxuXG4gIC8vIG5vdGU6IHByb3BlcnR5IG9yZGVyIGRldGVybWluZXMgZGVidWdnaW5nIG91dHB1dFxuICByZWFkb25seSByZWFzb246IFJldHJ5RXJyb3JSZWFzb247XG4gIHJlYWRvbmx5IGxhc3RFcnJvcjogdW5rbm93bjtcbiAgcmVhZG9ubHkgZXJyb3JzOiBBcnJheTx1bmtub3duPjtcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgbWVzc2FnZSxcbiAgICByZWFzb24sXG4gICAgZXJyb3JzLFxuICB9OiB7XG4gICAgbWVzc2FnZTogc3RyaW5nO1xuICAgIHJlYXNvbjogUmV0cnlFcnJvclJlYXNvbjtcbiAgICBlcnJvcnM6IEFycmF5PHVua25vd24+O1xuICB9KSB7XG4gICAgc3VwZXIoeyBuYW1lLCBtZXNzYWdlIH0pO1xuXG4gICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgdGhpcy5lcnJvcnMgPSBlcnJvcnM7XG5cbiAgICAvLyBzZXBhcmF0ZSBvdXIgbGFzdCBlcnJvciB0byBtYWtlIGRlYnVnZ2luZyB2aWEgbG9nIGVhc2llcjpcbiAgICB0aGlzLmxhc3RFcnJvciA9IGVycm9yc1tlcnJvcnMubGVuZ3RoIC0gMV07XG4gIH1cblxuICBzdGF0aWMgaXNJbnN0YW5jZShlcnJvcjogdW5rbm93bik6IGVycm9yIGlzIFJldHJ5RXJyb3Ige1xuICAgIHJldHVybiBBSVNES0Vycm9yLmhhc01hcmtlcihlcnJvciwgbWFya2VyKTtcbiAgfVxufVxuIiwgImltcG9ydCB7XG4gIExhbmd1YWdlTW9kZWxWMkZpbGVQYXJ0LFxuICBMYW5ndWFnZU1vZGVsVjJNZXNzYWdlLFxuICBMYW5ndWFnZU1vZGVsVjJQcm9tcHQsXG4gIExhbmd1YWdlTW9kZWxWMlRleHRQYXJ0LFxufSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcbmltcG9ydCB7XG4gIERhdGFDb250ZW50LFxuICBGaWxlUGFydCxcbiAgSW1hZ2VQYXJ0LFxuICBpc1VybFN1cHBvcnRlZCxcbiAgTW9kZWxNZXNzYWdlLFxuICBUZXh0UGFydCxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQge1xuICBkZXRlY3RNZWRpYVR5cGUsXG4gIGltYWdlTWVkaWFUeXBlU2lnbmF0dXJlcyxcbn0gZnJvbSAnLi4vdXRpbC9kZXRlY3QtbWVkaWEtdHlwZSc7XG5pbXBvcnQge1xuICBjcmVhdGVEZWZhdWx0RG93bmxvYWRGdW5jdGlvbixcbiAgRG93bmxvYWRGdW5jdGlvbixcbn0gZnJvbSAnLi4vdXRpbC9kb3dubG9hZC9kb3dubG9hZC1mdW5jdGlvbic7XG5pbXBvcnQgeyBjb252ZXJ0VG9MYW5ndWFnZU1vZGVsVjJEYXRhQ29udGVudCB9IGZyb20gJy4vZGF0YS1jb250ZW50JztcbmltcG9ydCB7IEludmFsaWRNZXNzYWdlUm9sZUVycm9yIH0gZnJvbSAnLi9pbnZhbGlkLW1lc3NhZ2Utcm9sZS1lcnJvcic7XG5pbXBvcnQgeyBTdGFuZGFyZGl6ZWRQcm9tcHQgfSBmcm9tICcuL3N0YW5kYXJkaXplLXByb21wdCc7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjb252ZXJ0VG9MYW5ndWFnZU1vZGVsUHJvbXB0KHtcbiAgcHJvbXB0LFxuICBzdXBwb3J0ZWRVcmxzLFxuICBkb3dubG9hZCA9IGNyZWF0ZURlZmF1bHREb3dubG9hZEZ1bmN0aW9uKCksXG59OiB7XG4gIHByb21wdDogU3RhbmRhcmRpemVkUHJvbXB0O1xuICBzdXBwb3J0ZWRVcmxzOiBSZWNvcmQ8c3RyaW5nLCBSZWdFeHBbXT47XG4gIGRvd25sb2FkOiBEb3dubG9hZEZ1bmN0aW9uIHwgdW5kZWZpbmVkO1xufSk6IFByb21pc2U8TGFuZ3VhZ2VNb2RlbFYyUHJvbXB0PiB7XG4gIGNvbnN0IGRvd25sb2FkZWRBc3NldHMgPSBhd2FpdCBkb3dubG9hZEFzc2V0cyhcbiAgICBwcm9tcHQubWVzc2FnZXMsXG4gICAgZG93bmxvYWQsXG4gICAgc3VwcG9ydGVkVXJscyxcbiAgKTtcblxuICByZXR1cm4gW1xuICAgIC4uLihwcm9tcHQuc3lzdGVtICE9IG51bGxcbiAgICAgID8gW3sgcm9sZTogJ3N5c3RlbScgYXMgY29uc3QsIGNvbnRlbnQ6IHByb21wdC5zeXN0ZW0gfV1cbiAgICAgIDogW10pLFxuICAgIC4uLnByb21wdC5tZXNzYWdlcy5tYXAobWVzc2FnZSA9PlxuICAgICAgY29udmVydFRvTGFuZ3VhZ2VNb2RlbE1lc3NhZ2UoeyBtZXNzYWdlLCBkb3dubG9hZGVkQXNzZXRzIH0pLFxuICAgICksXG4gIF07XG59XG5cbi8qKlxuICogQ29udmVydCBhIE1vZGVsTWVzc2FnZSB0byBhIExhbmd1YWdlTW9kZWxWMk1lc3NhZ2UuXG4gKlxuICogQHBhcmFtIG1lc3NhZ2UgVGhlIE1vZGVsTWVzc2FnZSB0byBjb252ZXJ0LlxuICogQHBhcmFtIGRvd25sb2FkZWRBc3NldHMgQSBtYXAgb2YgVVJMcyB0byB0aGVpciBkb3dubG9hZGVkIGRhdGEuIE9ubHlcbiAqICAgYXZhaWxhYmxlIGlmIHRoZSBtb2RlbCBkb2VzIG5vdCBzdXBwb3J0IFVSTHMsIG51bGwgb3RoZXJ3aXNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY29udmVydFRvTGFuZ3VhZ2VNb2RlbE1lc3NhZ2Uoe1xuICBtZXNzYWdlLFxuICBkb3dubG9hZGVkQXNzZXRzLFxufToge1xuICBtZXNzYWdlOiBNb2RlbE1lc3NhZ2U7XG4gIGRvd25sb2FkZWRBc3NldHM6IFJlY29yZDxcbiAgICBzdHJpbmcsXG4gICAgeyBtZWRpYVR5cGU6IHN0cmluZyB8IHVuZGVmaW5lZDsgZGF0YTogVWludDhBcnJheSB9XG4gID47XG59KTogTGFuZ3VhZ2VNb2RlbFYyTWVzc2FnZSB7XG4gIGNvbnN0IHJvbGUgPSBtZXNzYWdlLnJvbGU7XG4gIHN3aXRjaCAocm9sZSkge1xuICAgIGNhc2UgJ3N5c3RlbSc6IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHJvbGU6ICdzeXN0ZW0nLFxuICAgICAgICBjb250ZW50OiBtZXNzYWdlLmNvbnRlbnQsXG4gICAgICAgIHByb3ZpZGVyT3B0aW9uczogbWVzc2FnZS5wcm92aWRlck9wdGlvbnMsXG4gICAgICB9O1xuICAgIH1cblxuICAgIGNhc2UgJ3VzZXInOiB7XG4gICAgICBpZiAodHlwZW9mIG1lc3NhZ2UuY29udGVudCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICByb2xlOiAndXNlcicsXG4gICAgICAgICAgY29udGVudDogW3sgdHlwZTogJ3RleHQnLCB0ZXh0OiBtZXNzYWdlLmNvbnRlbnQgfV0sXG4gICAgICAgICAgcHJvdmlkZXJPcHRpb25zOiBtZXNzYWdlLnByb3ZpZGVyT3B0aW9ucyxcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcm9sZTogJ3VzZXInLFxuICAgICAgICBjb250ZW50OiBtZXNzYWdlLmNvbnRlbnRcbiAgICAgICAgICAubWFwKHBhcnQgPT4gY29udmVydFBhcnRUb0xhbmd1YWdlTW9kZWxQYXJ0KHBhcnQsIGRvd25sb2FkZWRBc3NldHMpKVxuICAgICAgICAgIC8vIHJlbW92ZSBlbXB0eSB0ZXh0IHBhcnRzOlxuICAgICAgICAgIC5maWx0ZXIocGFydCA9PiBwYXJ0LnR5cGUgIT09ICd0ZXh0JyB8fCBwYXJ0LnRleHQgIT09ICcnKSxcbiAgICAgICAgcHJvdmlkZXJPcHRpb25zOiBtZXNzYWdlLnByb3ZpZGVyT3B0aW9ucyxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY2FzZSAnYXNzaXN0YW50Jzoge1xuICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLmNvbnRlbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcm9sZTogJ2Fzc2lzdGFudCcsXG4gICAgICAgICAgY29udGVudDogW3sgdHlwZTogJ3RleHQnLCB0ZXh0OiBtZXNzYWdlLmNvbnRlbnQgfV0sXG4gICAgICAgICAgcHJvdmlkZXJPcHRpb25zOiBtZXNzYWdlLnByb3ZpZGVyT3B0aW9ucyxcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcm9sZTogJ2Fzc2lzdGFudCcsXG4gICAgICAgIGNvbnRlbnQ6IG1lc3NhZ2UuY29udGVudFxuICAgICAgICAgIC5maWx0ZXIoXG4gICAgICAgICAgICAvLyByZW1vdmUgZW1wdHkgdGV4dCBwYXJ0cyAobm8gdGV4dCwgYW5kIG5vIHByb3ZpZGVyIG9wdGlvbnMpOlxuICAgICAgICAgICAgcGFydCA9PlxuICAgICAgICAgICAgICBwYXJ0LnR5cGUgIT09ICd0ZXh0JyB8fFxuICAgICAgICAgICAgICBwYXJ0LnRleHQgIT09ICcnIHx8XG4gICAgICAgICAgICAgIHBhcnQucHJvdmlkZXJPcHRpb25zICE9IG51bGwsXG4gICAgICAgICAgKVxuICAgICAgICAgIC5tYXAocGFydCA9PiB7XG4gICAgICAgICAgICBjb25zdCBwcm92aWRlck9wdGlvbnMgPSBwYXJ0LnByb3ZpZGVyT3B0aW9ucztcblxuICAgICAgICAgICAgc3dpdGNoIChwYXJ0LnR5cGUpIHtcbiAgICAgICAgICAgICAgY2FzZSAnZmlsZSc6IHtcbiAgICAgICAgICAgICAgICBjb25zdCB7IGRhdGEsIG1lZGlhVHlwZSB9ID0gY29udmVydFRvTGFuZ3VhZ2VNb2RlbFYyRGF0YUNvbnRlbnQoXG4gICAgICAgICAgICAgICAgICBwYXJ0LmRhdGEsXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgdHlwZTogJ2ZpbGUnLFxuICAgICAgICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgICAgICAgIGZpbGVuYW1lOiBwYXJ0LmZpbGVuYW1lLFxuICAgICAgICAgICAgICAgICAgbWVkaWFUeXBlOiBtZWRpYVR5cGUgPz8gcGFydC5tZWRpYVR5cGUsXG4gICAgICAgICAgICAgICAgICBwcm92aWRlck9wdGlvbnMsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBjYXNlICdyZWFzb25pbmcnOiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgIHR5cGU6ICdyZWFzb25pbmcnLFxuICAgICAgICAgICAgICAgICAgdGV4dDogcGFydC50ZXh0LFxuICAgICAgICAgICAgICAgICAgcHJvdmlkZXJPcHRpb25zLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgY2FzZSAndGV4dCc6IHtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgdHlwZTogJ3RleHQnIGFzIGNvbnN0LFxuICAgICAgICAgICAgICAgICAgdGV4dDogcGFydC50ZXh0LFxuICAgICAgICAgICAgICAgICAgcHJvdmlkZXJPcHRpb25zLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgY2FzZSAndG9vbC1jYWxsJzoge1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICB0eXBlOiAndG9vbC1jYWxsJyBhcyBjb25zdCxcbiAgICAgICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IHBhcnQudG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgICAgIHRvb2xOYW1lOiBwYXJ0LnRvb2xOYW1lLFxuICAgICAgICAgICAgICAgICAgaW5wdXQ6IHBhcnQuaW5wdXQsXG4gICAgICAgICAgICAgICAgICBwcm92aWRlckV4ZWN1dGVkOiBwYXJ0LnByb3ZpZGVyRXhlY3V0ZWQsXG4gICAgICAgICAgICAgICAgICBwcm92aWRlck9wdGlvbnMsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBjYXNlICd0b29sLXJlc3VsdCc6IHtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgdHlwZTogJ3Rvb2wtcmVzdWx0JyBhcyBjb25zdCxcbiAgICAgICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IHBhcnQudG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgICAgIHRvb2xOYW1lOiBwYXJ0LnRvb2xOYW1lLFxuICAgICAgICAgICAgICAgICAgb3V0cHV0OiBwYXJ0Lm91dHB1dCxcbiAgICAgICAgICAgICAgICAgIHByb3ZpZGVyT3B0aW9ucyxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSksXG4gICAgICAgIHByb3ZpZGVyT3B0aW9uczogbWVzc2FnZS5wcm92aWRlck9wdGlvbnMsXG4gICAgICB9O1xuICAgIH1cblxuICAgIGNhc2UgJ3Rvb2wnOiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICByb2xlOiAndG9vbCcsXG4gICAgICAgIGNvbnRlbnQ6IG1lc3NhZ2UuY29udGVudC5tYXAocGFydCA9PiAoe1xuICAgICAgICAgIHR5cGU6ICd0b29sLXJlc3VsdCcgYXMgY29uc3QsXG4gICAgICAgICAgdG9vbENhbGxJZDogcGFydC50b29sQ2FsbElkLFxuICAgICAgICAgIHRvb2xOYW1lOiBwYXJ0LnRvb2xOYW1lLFxuICAgICAgICAgIG91dHB1dDogcGFydC5vdXRwdXQsXG4gICAgICAgICAgcHJvdmlkZXJPcHRpb25zOiBwYXJ0LnByb3ZpZGVyT3B0aW9ucyxcbiAgICAgICAgfSkpLFxuICAgICAgICBwcm92aWRlck9wdGlvbnM6IG1lc3NhZ2UucHJvdmlkZXJPcHRpb25zLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBkZWZhdWx0OiB7XG4gICAgICBjb25zdCBfZXhoYXVzdGl2ZUNoZWNrOiBuZXZlciA9IHJvbGU7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZE1lc3NhZ2VSb2xlRXJyb3IoeyByb2xlOiBfZXhoYXVzdGl2ZUNoZWNrIH0pO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIERvd25sb2FkcyBpbWFnZXMgYW5kIGZpbGVzIGZyb20gVVJMcyBpbiB0aGUgbWVzc2FnZXMuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGRvd25sb2FkQXNzZXRzKFxuICBtZXNzYWdlczogTW9kZWxNZXNzYWdlW10sXG4gIGRvd25sb2FkOiBEb3dubG9hZEZ1bmN0aW9uLFxuICBzdXBwb3J0ZWRVcmxzOiBSZWNvcmQ8c3RyaW5nLCBSZWdFeHBbXT4sXG4pOiBQcm9taXNlPFxuICBSZWNvcmQ8c3RyaW5nLCB7IG1lZGlhVHlwZTogc3RyaW5nIHwgdW5kZWZpbmVkOyBkYXRhOiBVaW50OEFycmF5IH0+XG4+IHtcbiAgY29uc3QgcGxhbm5lZERvd25sb2FkcyA9IG1lc3NhZ2VzXG4gICAgLmZpbHRlcihtZXNzYWdlID0+IG1lc3NhZ2Uucm9sZSA9PT0gJ3VzZXInKVxuICAgIC5tYXAobWVzc2FnZSA9PiBtZXNzYWdlLmNvbnRlbnQpXG4gICAgLmZpbHRlcigoY29udGVudCk6IGNvbnRlbnQgaXMgQXJyYXk8VGV4dFBhcnQgfCBJbWFnZVBhcnQgfCBGaWxlUGFydD4gPT5cbiAgICAgIEFycmF5LmlzQXJyYXkoY29udGVudCksXG4gICAgKVxuICAgIC5mbGF0KClcbiAgICAuZmlsdGVyKFxuICAgICAgKHBhcnQpOiBwYXJ0IGlzIEltYWdlUGFydCB8IEZpbGVQYXJ0ID0+XG4gICAgICAgIHBhcnQudHlwZSA9PT0gJ2ltYWdlJyB8fCBwYXJ0LnR5cGUgPT09ICdmaWxlJyxcbiAgICApXG4gICAgLm1hcChwYXJ0ID0+IHtcbiAgICAgIGNvbnN0IG1lZGlhVHlwZSA9XG4gICAgICAgIHBhcnQubWVkaWFUeXBlID8/IChwYXJ0LnR5cGUgPT09ICdpbWFnZScgPyAnaW1hZ2UvKicgOiB1bmRlZmluZWQpO1xuXG4gICAgICBsZXQgZGF0YSA9IHBhcnQudHlwZSA9PT0gJ2ltYWdlJyA/IHBhcnQuaW1hZ2UgOiBwYXJ0LmRhdGE7XG4gICAgICBpZiAodHlwZW9mIGRhdGEgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgZGF0YSA9IG5ldyBVUkwoZGF0YSk7XG4gICAgICAgIH0gY2F0Y2ggKGlnbm9yZWQpIHt9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7IG1lZGlhVHlwZSwgZGF0YSB9O1xuICAgIH0pXG5cbiAgICAuZmlsdGVyKFxuICAgICAgKHBhcnQpOiBwYXJ0IGlzIHsgbWVkaWFUeXBlOiBzdHJpbmcgfCB1bmRlZmluZWQ7IGRhdGE6IFVSTCB9ID0+XG4gICAgICAgIHBhcnQuZGF0YSBpbnN0YW5jZW9mIFVSTCxcbiAgICApXG4gICAgLm1hcChwYXJ0ID0+ICh7XG4gICAgICB1cmw6IHBhcnQuZGF0YSxcbiAgICAgIGlzVXJsU3VwcG9ydGVkQnlNb2RlbDpcbiAgICAgICAgcGFydC5tZWRpYVR5cGUgIT0gbnVsbCAmJlxuICAgICAgICBpc1VybFN1cHBvcnRlZCh7XG4gICAgICAgICAgdXJsOiBwYXJ0LmRhdGEudG9TdHJpbmcoKSxcbiAgICAgICAgICBtZWRpYVR5cGU6IHBhcnQubWVkaWFUeXBlLFxuICAgICAgICAgIHN1cHBvcnRlZFVybHMsXG4gICAgICAgIH0pLFxuICAgIH0pKTtcblxuICAvLyBkb3dubG9hZCBpbiBwYXJhbGxlbDpcbiAgY29uc3QgZG93bmxvYWRlZEZpbGVzID0gYXdhaXQgZG93bmxvYWQocGxhbm5lZERvd25sb2Fkcyk7XG5cbiAgcmV0dXJuIE9iamVjdC5mcm9tRW50cmllcyhcbiAgICBkb3dubG9hZGVkRmlsZXNcbiAgICAgIC5tYXAoKGZpbGUsIGluZGV4KSA9PlxuICAgICAgICBmaWxlID09IG51bGxcbiAgICAgICAgICA/IG51bGxcbiAgICAgICAgICA6IFtcbiAgICAgICAgICAgICAgcGxhbm5lZERvd25sb2Fkc1tpbmRleF0udXJsLnRvU3RyaW5nKCksXG4gICAgICAgICAgICAgIHsgZGF0YTogZmlsZS5kYXRhLCBtZWRpYVR5cGU6IGZpbGUubWVkaWFUeXBlIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgKVxuICAgICAgLmZpbHRlcihmaWxlID0+IGZpbGUgIT0gbnVsbCksXG4gICk7XG59XG5cbi8qKlxuICogQ29udmVydCBwYXJ0IG9mIGEgbWVzc2FnZSB0byBhIExhbmd1YWdlTW9kZWxWMlBhcnQuXG4gKiBAcGFyYW0gcGFydCBUaGUgcGFydCB0byBjb252ZXJ0LlxuICogQHBhcmFtIGRvd25sb2FkZWRBc3NldHMgQSBtYXAgb2YgVVJMcyB0byB0aGVpciBkb3dubG9hZGVkIGRhdGEuIE9ubHlcbiAqICBhdmFpbGFibGUgaWYgdGhlIG1vZGVsIGRvZXMgbm90IHN1cHBvcnQgVVJMcywgbnVsbCBvdGhlcndpc2UuXG4gKlxuICogQHJldHVybnMgVGhlIGNvbnZlcnRlZCBwYXJ0LlxuICovXG5mdW5jdGlvbiBjb252ZXJ0UGFydFRvTGFuZ3VhZ2VNb2RlbFBhcnQoXG4gIHBhcnQ6IFRleHRQYXJ0IHwgSW1hZ2VQYXJ0IHwgRmlsZVBhcnQsXG4gIGRvd25sb2FkZWRBc3NldHM6IFJlY29yZDxcbiAgICBzdHJpbmcsXG4gICAgeyBtZWRpYVR5cGU6IHN0cmluZyB8IHVuZGVmaW5lZDsgZGF0YTogVWludDhBcnJheSB9XG4gID4sXG4pOiBMYW5ndWFnZU1vZGVsVjJUZXh0UGFydCB8IExhbmd1YWdlTW9kZWxWMkZpbGVQYXJ0IHtcbiAgaWYgKHBhcnQudHlwZSA9PT0gJ3RleHQnKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgIHRleHQ6IHBhcnQudGV4dCxcbiAgICAgIHByb3ZpZGVyT3B0aW9uczogcGFydC5wcm92aWRlck9wdGlvbnMsXG4gICAgfTtcbiAgfVxuXG4gIGxldCBvcmlnaW5hbERhdGE6IERhdGFDb250ZW50IHwgVVJMO1xuICBjb25zdCB0eXBlID0gcGFydC50eXBlO1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICdpbWFnZSc6XG4gICAgICBvcmlnaW5hbERhdGEgPSBwYXJ0LmltYWdlO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnZmlsZSc6XG4gICAgICBvcmlnaW5hbERhdGEgPSBwYXJ0LmRhdGE7XG5cbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIHBhcnQgdHlwZTogJHt0eXBlfWApO1xuICB9XG5cbiAgY29uc3QgeyBkYXRhOiBjb252ZXJ0ZWREYXRhLCBtZWRpYVR5cGU6IGNvbnZlcnRlZE1lZGlhVHlwZSB9ID1cbiAgICBjb252ZXJ0VG9MYW5ndWFnZU1vZGVsVjJEYXRhQ29udGVudChvcmlnaW5hbERhdGEpO1xuXG4gIGxldCBtZWRpYVR5cGU6IHN0cmluZyB8IHVuZGVmaW5lZCA9IGNvbnZlcnRlZE1lZGlhVHlwZSA/PyBwYXJ0Lm1lZGlhVHlwZTtcbiAgbGV0IGRhdGE6IFVpbnQ4QXJyYXkgfCBzdHJpbmcgfCBVUkwgPSBjb252ZXJ0ZWREYXRhOyAvLyBiaW5hcnkgfCBiYXNlNjQgfCB1cmxcblxuICAvLyBJZiB0aGUgY29udGVudCBpcyBhIFVSTCwgd2UgY2hlY2sgaWYgaXQgd2FzIGRvd25sb2FkZWQ6XG4gIGlmIChkYXRhIGluc3RhbmNlb2YgVVJMKSB7XG4gICAgY29uc3QgZG93bmxvYWRlZEZpbGUgPSBkb3dubG9hZGVkQXNzZXRzW2RhdGEudG9TdHJpbmcoKV07XG4gICAgaWYgKGRvd25sb2FkZWRGaWxlKSB7XG4gICAgICBkYXRhID0gZG93bmxvYWRlZEZpbGUuZGF0YTtcbiAgICAgIG1lZGlhVHlwZSA/Pz0gZG93bmxvYWRlZEZpbGUubWVkaWFUeXBlO1xuICAgIH1cbiAgfVxuXG4gIC8vIE5vdyB0aGF0IHdlIGhhdmUgdGhlIG5vcm1hbGl6ZWQgZGF0YSBlaXRoZXIgYXMgYSBVUkwgb3IgYSBVaW50OEFycmF5LFxuICAvLyB3ZSBjYW4gY3JlYXRlIHRoZSBMYW5ndWFnZU1vZGVsVjJQYXJ0LlxuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICdpbWFnZSc6IHtcbiAgICAgIC8vIFdoZW4gcG9zc2libGUsIHRyeSB0byBkZXRlY3QgdGhlIG1lZGlhIHR5cGUgYXV0b21hdGljYWxseVxuICAgICAgLy8gdG8gZGVhbCB3aXRoIGluY29ycmVjdCBtZWRpYSB0eXBlIGlucHV0cy5cbiAgICAgIC8vIFdoZW4gZGV0ZWN0aW9uIGZhaWxzLCB1c2UgcHJvdmlkZWQgbWVkaWEgdHlwZS5cbiAgICAgIGlmIChkYXRhIGluc3RhbmNlb2YgVWludDhBcnJheSB8fCB0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgbWVkaWFUeXBlID1cbiAgICAgICAgICBkZXRlY3RNZWRpYVR5cGUoeyBkYXRhLCBzaWduYXR1cmVzOiBpbWFnZU1lZGlhVHlwZVNpZ25hdHVyZXMgfSkgPz9cbiAgICAgICAgICBtZWRpYVR5cGU7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6ICdmaWxlJyxcbiAgICAgICAgbWVkaWFUeXBlOiBtZWRpYVR5cGUgPz8gJ2ltYWdlLyonLCAvLyBhbnkgaW1hZ2VcbiAgICAgICAgZmlsZW5hbWU6IHVuZGVmaW5lZCxcbiAgICAgICAgZGF0YSxcbiAgICAgICAgcHJvdmlkZXJPcHRpb25zOiBwYXJ0LnByb3ZpZGVyT3B0aW9ucyxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY2FzZSAnZmlsZSc6IHtcbiAgICAgIC8vIFdlIG11c3QgaGF2ZSBhIG1lZGlhVHlwZSBmb3IgZmlsZXMsIGlmIG5vdCwgdGhyb3cgYW4gZXJyb3IuXG4gICAgICBpZiAobWVkaWFUeXBlID09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBNZWRpYSB0eXBlIGlzIG1pc3NpbmcgZm9yIGZpbGUgcGFydGApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiAnZmlsZScsXG4gICAgICAgIG1lZGlhVHlwZSxcbiAgICAgICAgZmlsZW5hbWU6IHBhcnQuZmlsZW5hbWUsXG4gICAgICAgIGRhdGEsXG4gICAgICAgIHByb3ZpZGVyT3B0aW9uczogcGFydC5wcm92aWRlck9wdGlvbnMsXG4gICAgICB9O1xuICAgIH1cbiAgfVxufVxuIiwgImltcG9ydCB7IGNvbnZlcnRCYXNlNjRUb1VpbnQ4QXJyYXkgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyLXV0aWxzJztcblxuZXhwb3J0IGNvbnN0IGltYWdlTWVkaWFUeXBlU2lnbmF0dXJlcyA9IFtcbiAge1xuICAgIG1lZGlhVHlwZTogJ2ltYWdlL2dpZicgYXMgY29uc3QsXG4gICAgYnl0ZXNQcmVmaXg6IFsweDQ3LCAweDQ5LCAweDQ2XSwgLy8gR0lGXG4gIH0sXG4gIHtcbiAgICBtZWRpYVR5cGU6ICdpbWFnZS9wbmcnIGFzIGNvbnN0LFxuICAgIGJ5dGVzUHJlZml4OiBbMHg4OSwgMHg1MCwgMHg0ZSwgMHg0N10sIC8vIFBOR1xuICB9LFxuICB7XG4gICAgbWVkaWFUeXBlOiAnaW1hZ2UvanBlZycgYXMgY29uc3QsXG4gICAgYnl0ZXNQcmVmaXg6IFsweGZmLCAweGQ4XSwgLy8gSlBFR1xuICB9LFxuICB7XG4gICAgbWVkaWFUeXBlOiAnaW1hZ2Uvd2VicCcgYXMgY29uc3QsXG4gICAgYnl0ZXNQcmVmaXg6IFtcbiAgICAgIDB4NTIsXG4gICAgICAweDQ5LFxuICAgICAgMHg0NixcbiAgICAgIDB4NDYsIC8vIFwiUklGRlwiXG4gICAgICBudWxsLFxuICAgICAgbnVsbCxcbiAgICAgIG51bGwsXG4gICAgICBudWxsLCAvLyBmaWxlIHNpemUgKHZhcmlhYmxlKVxuICAgICAgMHg1NyxcbiAgICAgIDB4NDUsXG4gICAgICAweDQyLFxuICAgICAgMHg1MCwgLy8gXCJXRUJQXCJcbiAgICBdLFxuICB9LFxuICB7XG4gICAgbWVkaWFUeXBlOiAnaW1hZ2UvYm1wJyBhcyBjb25zdCxcbiAgICBieXRlc1ByZWZpeDogWzB4NDIsIDB4NGRdLFxuICB9LFxuICB7XG4gICAgbWVkaWFUeXBlOiAnaW1hZ2UvdGlmZicgYXMgY29uc3QsXG4gICAgYnl0ZXNQcmVmaXg6IFsweDQ5LCAweDQ5LCAweDJhLCAweDAwXSxcbiAgfSxcbiAge1xuICAgIG1lZGlhVHlwZTogJ2ltYWdlL3RpZmYnIGFzIGNvbnN0LFxuICAgIGJ5dGVzUHJlZml4OiBbMHg0ZCwgMHg0ZCwgMHgwMCwgMHgyYV0sXG4gIH0sXG4gIHtcbiAgICBtZWRpYVR5cGU6ICdpbWFnZS9hdmlmJyBhcyBjb25zdCxcbiAgICBieXRlc1ByZWZpeDogW1xuICAgICAgMHgwMCwgMHgwMCwgMHgwMCwgMHgyMCwgMHg2NiwgMHg3NCwgMHg3OSwgMHg3MCwgMHg2MSwgMHg3NiwgMHg2OSwgMHg2NixcbiAgICBdLFxuICB9LFxuICB7XG4gICAgbWVkaWFUeXBlOiAnaW1hZ2UvaGVpYycgYXMgY29uc3QsXG4gICAgYnl0ZXNQcmVmaXg6IFtcbiAgICAgIDB4MDAsIDB4MDAsIDB4MDAsIDB4MjAsIDB4NjYsIDB4NzQsIDB4NzksIDB4NzAsIDB4NjgsIDB4NjUsIDB4NjksIDB4NjMsXG4gICAgXSxcbiAgfSxcbl0gYXMgY29uc3Q7XG5cbmV4cG9ydCBjb25zdCBhdWRpb01lZGlhVHlwZVNpZ25hdHVyZXMgPSBbXG4gIHtcbiAgICBtZWRpYVR5cGU6ICdhdWRpby9tcGVnJyBhcyBjb25zdCxcbiAgICBieXRlc1ByZWZpeDogWzB4ZmYsIDB4ZmJdLFxuICB9LFxuICB7XG4gICAgbWVkaWFUeXBlOiAnYXVkaW8vbXBlZycgYXMgY29uc3QsXG4gICAgYnl0ZXNQcmVmaXg6IFsweGZmLCAweGZhXSxcbiAgfSxcbiAge1xuICAgIG1lZGlhVHlwZTogJ2F1ZGlvL21wZWcnIGFzIGNvbnN0LFxuICAgIGJ5dGVzUHJlZml4OiBbMHhmZiwgMHhmM10sXG4gIH0sXG4gIHtcbiAgICBtZWRpYVR5cGU6ICdhdWRpby9tcGVnJyBhcyBjb25zdCxcbiAgICBieXRlc1ByZWZpeDogWzB4ZmYsIDB4ZjJdLFxuICB9LFxuICB7XG4gICAgbWVkaWFUeXBlOiAnYXVkaW8vbXBlZycgYXMgY29uc3QsXG4gICAgYnl0ZXNQcmVmaXg6IFsweGZmLCAweGUzXSxcbiAgfSxcbiAge1xuICAgIG1lZGlhVHlwZTogJ2F1ZGlvL21wZWcnIGFzIGNvbnN0LFxuICAgIGJ5dGVzUHJlZml4OiBbMHhmZiwgMHhlMl0sXG4gIH0sXG4gIHtcbiAgICBtZWRpYVR5cGU6ICdhdWRpby93YXYnIGFzIGNvbnN0LFxuICAgIGJ5dGVzUHJlZml4OiBbXG4gICAgICAweDUyLCAvLyBSXG4gICAgICAweDQ5LCAvLyBJXG4gICAgICAweDQ2LCAvLyBGXG4gICAgICAweDQ2LCAvLyBGXG4gICAgICBudWxsLFxuICAgICAgbnVsbCxcbiAgICAgIG51bGwsXG4gICAgICBudWxsLFxuICAgICAgMHg1NywgLy8gV1xuICAgICAgMHg0MSwgLy8gQVxuICAgICAgMHg1NiwgLy8gVlxuICAgICAgMHg0NSwgLy8gRVxuICAgIF0sXG4gIH0sXG4gIHtcbiAgICBtZWRpYVR5cGU6ICdhdWRpby9vZ2cnIGFzIGNvbnN0LFxuICAgIGJ5dGVzUHJlZml4OiBbMHg0ZiwgMHg2NywgMHg2NywgMHg1M10sXG4gIH0sXG4gIHtcbiAgICBtZWRpYVR5cGU6ICdhdWRpby9mbGFjJyBhcyBjb25zdCxcbiAgICBieXRlc1ByZWZpeDogWzB4NjYsIDB4NGMsIDB4NjEsIDB4NDNdLFxuICB9LFxuICB7XG4gICAgbWVkaWFUeXBlOiAnYXVkaW8vYWFjJyBhcyBjb25zdCxcbiAgICBieXRlc1ByZWZpeDogWzB4NDAsIDB4MTUsIDB4MDAsIDB4MDBdLFxuICB9LFxuICB7XG4gICAgbWVkaWFUeXBlOiAnYXVkaW8vbXA0JyBhcyBjb25zdCxcbiAgICBieXRlc1ByZWZpeDogWzB4NjYsIDB4NzQsIDB4NzksIDB4NzBdLFxuICB9LFxuICB7XG4gICAgbWVkaWFUeXBlOiAnYXVkaW8vd2VibScsXG4gICAgYnl0ZXNQcmVmaXg6IFsweDFhLCAweDQ1LCAweGRmLCAweGEzXSxcbiAgfSxcbl0gYXMgY29uc3Q7XG5cbmNvbnN0IHN0cmlwSUQzID0gKGRhdGE6IFVpbnQ4QXJyYXkgfCBzdHJpbmcpID0+IHtcbiAgY29uc3QgYnl0ZXMgPVxuICAgIHR5cGVvZiBkYXRhID09PSAnc3RyaW5nJyA/IGNvbnZlcnRCYXNlNjRUb1VpbnQ4QXJyYXkoZGF0YSkgOiBkYXRhO1xuICBjb25zdCBpZDNTaXplID1cbiAgICAoKGJ5dGVzWzZdICYgMHg3ZikgPDwgMjEpIHxcbiAgICAoKGJ5dGVzWzddICYgMHg3ZikgPDwgMTQpIHxcbiAgICAoKGJ5dGVzWzhdICYgMHg3ZikgPDwgNykgfFxuICAgIChieXRlc1s5XSAmIDB4N2YpO1xuXG4gIC8vIFRoZSByYXcgTVAzIHN0YXJ0cyBoZXJlXG4gIHJldHVybiBieXRlcy5zbGljZShpZDNTaXplICsgMTApO1xufTtcblxuZnVuY3Rpb24gc3RyaXBJRDNUYWdzSWZQcmVzZW50KGRhdGE6IFVpbnQ4QXJyYXkgfCBzdHJpbmcpOiBVaW50OEFycmF5IHwgc3RyaW5nIHtcbiAgY29uc3QgaGFzSWQzID1cbiAgICAodHlwZW9mIGRhdGEgPT09ICdzdHJpbmcnICYmIGRhdGEuc3RhcnRzV2l0aCgnU1VReicpKSB8fFxuICAgICh0eXBlb2YgZGF0YSAhPT0gJ3N0cmluZycgJiZcbiAgICAgIGRhdGEubGVuZ3RoID4gMTAgJiZcbiAgICAgIGRhdGFbMF0gPT09IDB4NDkgJiYgLy8gJ0knXG4gICAgICBkYXRhWzFdID09PSAweDQ0ICYmIC8vICdEJ1xuICAgICAgZGF0YVsyXSA9PT0gMHgzMyk7IC8vICczJ1xuXG4gIHJldHVybiBoYXNJZDMgPyBzdHJpcElEMyhkYXRhKSA6IGRhdGE7XG59XG5cbi8qKlxuICogRGV0ZWN0IHRoZSBtZWRpYSBJQU5BIG1lZGlhIHR5cGUgb2YgYSBmaWxlIHVzaW5nIGEgbGlzdCBvZiBzaWduYXR1cmVzLlxuICpcbiAqIEBwYXJhbSBkYXRhIC0gVGhlIGZpbGUgZGF0YS5cbiAqIEBwYXJhbSBzaWduYXR1cmVzIC0gVGhlIHNpZ25hdHVyZXMgdG8gdXNlIGZvciBkZXRlY3Rpb24uXG4gKiBAcmV0dXJucyBUaGUgbWVkaWEgdHlwZSBvZiB0aGUgZmlsZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRldGVjdE1lZGlhVHlwZSh7XG4gIGRhdGEsXG4gIHNpZ25hdHVyZXMsXG59OiB7XG4gIGRhdGE6IFVpbnQ4QXJyYXkgfCBzdHJpbmc7XG4gIHNpZ25hdHVyZXM6IHR5cGVvZiBhdWRpb01lZGlhVHlwZVNpZ25hdHVyZXMgfCB0eXBlb2YgaW1hZ2VNZWRpYVR5cGVTaWduYXR1cmVzO1xufSk6ICh0eXBlb2Ygc2lnbmF0dXJlcylbbnVtYmVyXVsnbWVkaWFUeXBlJ10gfCB1bmRlZmluZWQge1xuICBjb25zdCBwcm9jZXNzZWREYXRhID0gc3RyaXBJRDNUYWdzSWZQcmVzZW50KGRhdGEpO1xuXG4gIC8vIENvbnZlcnQgdGhlIGZpcnN0IH4xOCBieXRlcyAoMjQgYmFzZTY0IGNoYXJzKSBmb3IgY29uc2lzdGVudCBkZXRlY3Rpb24gbG9naWM6XG4gIGNvbnN0IGJ5dGVzID1cbiAgICB0eXBlb2YgcHJvY2Vzc2VkRGF0YSA9PT0gJ3N0cmluZydcbiAgICAgID8gY29udmVydEJhc2U2NFRvVWludDhBcnJheShcbiAgICAgICAgICBwcm9jZXNzZWREYXRhLnN1YnN0cmluZygwLCBNYXRoLm1pbihwcm9jZXNzZWREYXRhLmxlbmd0aCwgMjQpKSxcbiAgICAgICAgKVxuICAgICAgOiBwcm9jZXNzZWREYXRhO1xuXG4gIGZvciAoY29uc3Qgc2lnbmF0dXJlIG9mIHNpZ25hdHVyZXMpIHtcbiAgICBpZiAoXG4gICAgICBieXRlcy5sZW5ndGggPj0gc2lnbmF0dXJlLmJ5dGVzUHJlZml4Lmxlbmd0aCAmJlxuICAgICAgc2lnbmF0dXJlLmJ5dGVzUHJlZml4LmV2ZXJ5KFxuICAgICAgICAoYnl0ZSwgaW5kZXgpID0+IGJ5dGUgPT09IG51bGwgfHwgYnl0ZXNbaW5kZXhdID09PSBieXRlLFxuICAgICAgKVxuICAgICkge1xuICAgICAgcmV0dXJuIHNpZ25hdHVyZS5tZWRpYVR5cGU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cbiIsICJpbXBvcnQgeyBEb3dubG9hZEVycm9yIH0gZnJvbSAnLi9kb3dubG9hZC1lcnJvcic7XG5pbXBvcnQge1xuICB3aXRoVXNlckFnZW50U3VmZml4LFxuICBnZXRSdW50aW1lRW52aXJvbm1lbnRVc2VyQWdlbnQsXG59IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXItdXRpbHMnO1xuaW1wb3J0IHsgVkVSU0lPTiB9IGZyb20gJy4uLy4uL3ZlcnNpb24nO1xuXG4vKipcbiAqIERvd25sb2FkIGEgZmlsZSBmcm9tIGEgVVJMLlxuICpcbiAqIEBwYXJhbSB1cmwgLSBUaGUgVVJMIHRvIGRvd25sb2FkIGZyb20uXG4gKiBAcmV0dXJucyBUaGUgZG93bmxvYWRlZCBkYXRhIGFuZCBtZWRpYSB0eXBlLlxuICpcbiAqIEB0aHJvd3MgRG93bmxvYWRFcnJvciBpZiB0aGUgZG93bmxvYWQgZmFpbHMuXG4gKi9cbmV4cG9ydCBjb25zdCBkb3dubG9hZCA9IGFzeW5jICh7IHVybCB9OiB7IHVybDogVVJMIH0pID0+IHtcbiAgY29uc3QgdXJsVGV4dCA9IHVybC50b1N0cmluZygpO1xuICB0cnkge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godXJsVGV4dCwge1xuICAgICAgaGVhZGVyczogd2l0aFVzZXJBZ2VudFN1ZmZpeChcbiAgICAgICAge30sXG4gICAgICAgIGBhaS1zZGsvJHtWRVJTSU9OfWAsXG4gICAgICAgIGdldFJ1bnRpbWVFbnZpcm9ubWVudFVzZXJBZ2VudCgpLFxuICAgICAgKSxcbiAgICB9KTtcblxuICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgIHRocm93IG5ldyBEb3dubG9hZEVycm9yKHtcbiAgICAgICAgdXJsOiB1cmxUZXh0LFxuICAgICAgICBzdGF0dXNDb2RlOiByZXNwb25zZS5zdGF0dXMsXG4gICAgICAgIHN0YXR1c1RleHQ6IHJlc3BvbnNlLnN0YXR1c1RleHQsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgZGF0YTogbmV3IFVpbnQ4QXJyYXkoYXdhaXQgcmVzcG9uc2UuYXJyYXlCdWZmZXIoKSksXG4gICAgICBtZWRpYVR5cGU6IHJlc3BvbnNlLmhlYWRlcnMuZ2V0KCdjb250ZW50LXR5cGUnKSA/PyB1bmRlZmluZWQsXG4gICAgfTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoRG93bmxvYWRFcnJvci5pc0luc3RhbmNlKGVycm9yKSkge1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IERvd25sb2FkRXJyb3IoeyB1cmw6IHVybFRleHQsIGNhdXNlOiBlcnJvciB9KTtcbiAgfVxufTtcbiIsICJkZWNsYXJlIGNvbnN0IF9fUEFDS0FHRV9WRVJTSU9OX186IHN0cmluZyB8IHVuZGVmaW5lZDtcbmV4cG9ydCBjb25zdCBWRVJTSU9OOiBzdHJpbmcgPVxuICB0eXBlb2YgX19QQUNLQUdFX1ZFUlNJT05fXyAhPT0gJ3VuZGVmaW5lZCdcbiAgICA/IF9fUEFDS0FHRV9WRVJTSU9OX19cbiAgICA6ICcwLjAuMC10ZXN0JztcbiIsICJpbXBvcnQgeyBkb3dubG9hZCBhcyBvcmlnaW5hbERvd25sb2FkIH0gZnJvbSAnLi9kb3dubG9hZCc7XG5cbi8qKlxuICogRXhwZXJpbWVudGFsLiBDYW4gY2hhbmdlIGluIHBhdGNoIHZlcnNpb25zIHdpdGhvdXQgd2FybmluZy5cbiAqXG4gKiBEb3dubG9hZCBmdW5jdGlvbi4gQ2FsbGVkIHdpdGggdGhlIGFycmF5IG9mIFVSTHMgYW5kIGEgYm9vbGVhbiBpbmRpY2F0aW5nXG4gKiB3aGV0aGVyIHRoZSBVUkwgaXMgc3VwcG9ydGVkIGJ5IHRoZSBtb2RlbC5cbiAqXG4gKiBUaGUgZG93bmxvYWQgZnVuY3Rpb24gY2FuIGRlY2lkZSBmb3IgZWFjaCBVUkw6XG4gKiAtIHRvIHJldHVybiBudWxsICh3aGljaCBtZWFucyB0aGF0IHRoZSBVUkwgc2hvdWxkIGJlIHBhc3NlZCB0byB0aGUgbW9kZWwpXG4gKiAtIHRvIGRvd25sb2FkIHRoZSBhc3NldCBhbmQgcmV0dXJuIHRoZSBkYXRhIChpbmNsLiByZXRyaWVzLCBhdXRoZW50aWNhdGlvbiwgZXRjLilcbiAqXG4gKiBTaG91bGQgdGhyb3cgRG93bmxvYWRFcnJvciBpZiB0aGUgZG93bmxvYWQgZmFpbHMuXG4gKlxuICogU2hvdWxkIHJldHVybiBhbiBhcnJheSBvZiBvYmplY3RzIHNvcnRlZCBieSB0aGUgb3JkZXIgb2YgdGhlIHJlcXVlc3RlZCBkb3dubG9hZHMuXG4gKiBGb3IgZWFjaCBvYmplY3QsIHRoZSBkYXRhIHNob3VsZCBiZSBhIFVpbnQ4QXJyYXkgaWYgdGhlIFVSTCB3YXMgZG93bmxvYWRlZC5cbiAqIEZvciBlYWNoIG9iamVjdCwgdGhlIG1lZGlhVHlwZSBzaG91bGQgYmUgdGhlIG1lZGlhIHR5cGUgb2YgdGhlIGRvd25sb2FkZWQgYXNzZXQuXG4gKiBGb3IgZWFjaCBvYmplY3QsIHRoZSBkYXRhIHNob3VsZCBiZSBudWxsIGlmIHRoZSBVUkwgc2hvdWxkIGJlIHBhc3NlZCB0aHJvdWdoIGFzIGlzLlxuICovXG5leHBvcnQgdHlwZSBEb3dubG9hZEZ1bmN0aW9uID0gKFxuICBvcHRpb25zOiBBcnJheTx7XG4gICAgdXJsOiBVUkw7XG4gICAgaXNVcmxTdXBwb3J0ZWRCeU1vZGVsOiBib29sZWFuO1xuICB9PixcbikgPT4gUHJvbWlzZUxpa2U8XG4gIEFycmF5PHtcbiAgICBkYXRhOiBVaW50OEFycmF5O1xuICAgIG1lZGlhVHlwZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICB9IHwgbnVsbD5cbj47XG5cbi8qKlxuICogRGVmYXVsdCBkb3dubG9hZCBmdW5jdGlvbi5cbiAqIERvd25sb2FkcyB0aGUgZmlsZSBpZiBpdCBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBtb2RlbC5cbiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZURlZmF1bHREb3dubG9hZEZ1bmN0aW9uID1cbiAgKGRvd25sb2FkOiB0eXBlb2Ygb3JpZ2luYWxEb3dubG9hZCA9IG9yaWdpbmFsRG93bmxvYWQpOiBEb3dubG9hZEZ1bmN0aW9uID0+XG4gIHJlcXVlc3RlZERvd25sb2FkcyA9PlxuICAgIFByb21pc2UuYWxsKFxuICAgICAgcmVxdWVzdGVkRG93bmxvYWRzLm1hcChhc3luYyByZXF1ZXN0ZWREb3dubG9hZCA9PlxuICAgICAgICByZXF1ZXN0ZWREb3dubG9hZC5pc1VybFN1cHBvcnRlZEJ5TW9kZWxcbiAgICAgICAgICA/IG51bGxcbiAgICAgICAgICA6IGRvd25sb2FkKHJlcXVlc3RlZERvd25sb2FkKSxcbiAgICAgICksXG4gICAgKTtcbiIsICJpbXBvcnQgeyBBSVNES0Vycm9yLCBMYW5ndWFnZU1vZGVsVjJEYXRhQ29udGVudCB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHtcbiAgY29udmVydEJhc2U2NFRvVWludDhBcnJheSxcbiAgY29udmVydFVpbnQ4QXJyYXlUb0Jhc2U2NCxcbiAgRGF0YUNvbnRlbnQsXG59IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXItdXRpbHMnO1xuaW1wb3J0IHsgeiB9IGZyb20gJ3pvZC92NCc7XG5pbXBvcnQgeyBJbnZhbGlkRGF0YUNvbnRlbnRFcnJvciB9IGZyb20gJy4vaW52YWxpZC1kYXRhLWNvbnRlbnQtZXJyb3InO1xuaW1wb3J0IHsgc3BsaXREYXRhVXJsIH0gZnJvbSAnLi9zcGxpdC1kYXRhLXVybCc7XG5cbi8qKlxuQGludGVybmFsXG4gKi9cbmV4cG9ydCBjb25zdCBkYXRhQ29udGVudFNjaGVtYTogei5ab2RUeXBlPERhdGFDb250ZW50PiA9IHoudW5pb24oW1xuICB6LnN0cmluZygpLFxuICB6Lmluc3RhbmNlb2YoVWludDhBcnJheSksXG4gIHouaW5zdGFuY2VvZihBcnJheUJ1ZmZlciksXG4gIHouY3VzdG9tPEJ1ZmZlcj4oXG4gICAgLy8gQnVmZmVyIG1pZ2h0IG5vdCBiZSBhdmFpbGFibGUgaW4gc29tZSBlbnZpcm9ubWVudHMgc3VjaCBhcyBDbG91ZEZsYXJlOlxuICAgICh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIEJ1ZmZlciA9PlxuICAgICAgZ2xvYmFsVGhpcy5CdWZmZXI/LmlzQnVmZmVyKHZhbHVlKSA/PyBmYWxzZSxcbiAgICB7IG1lc3NhZ2U6ICdNdXN0IGJlIGEgQnVmZmVyJyB9LFxuICApLFxuXSk7XG5cbmV4cG9ydCBmdW5jdGlvbiBjb252ZXJ0VG9MYW5ndWFnZU1vZGVsVjJEYXRhQ29udGVudChcbiAgY29udGVudDogRGF0YUNvbnRlbnQgfCBVUkwsXG4pOiB7XG4gIGRhdGE6IExhbmd1YWdlTW9kZWxWMkRhdGFDb250ZW50O1xuICBtZWRpYVR5cGU6IHN0cmluZyB8IHVuZGVmaW5lZDtcbn0ge1xuICAvLyBCdWZmZXIgJiBVaW50OEFycmF5OlxuICBpZiAoY29udGVudCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHtcbiAgICByZXR1cm4geyBkYXRhOiBjb250ZW50LCBtZWRpYVR5cGU6IHVuZGVmaW5lZCB9O1xuICB9XG5cbiAgLy8gQXJyYXlCdWZmZXIgbmVlZHMgY29udmVyc2lvbiB0byBVaW50OEFycmF5IChsaWdodHdlaWdodCk6XG4gIGlmIChjb250ZW50IGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICByZXR1cm4geyBkYXRhOiBuZXcgVWludDhBcnJheShjb250ZW50KSwgbWVkaWFUeXBlOiB1bmRlZmluZWQgfTtcbiAgfVxuXG4gIC8vIEF0dGVtcHQgdG8gY3JlYXRlIGEgVVJMIGZyb20gdGhlIGRhdGEuIElmIGl0IGZhaWxzLCB3ZSBjYW4gYXNzdW1lIHRoZSBkYXRhXG4gIC8vIGlzIG5vdCBhIFVSTCBhbmQgbGlrZWx5IHNvbWUgb3RoZXIgc29ydCBvZiBkYXRhLlxuICBpZiAodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnRlbnQgPSBuZXcgVVJMKGNvbnRlbnQpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBpZ25vcmVkXG4gICAgfVxuICB9XG5cbiAgLy8gRXh0cmFjdCBkYXRhIGZyb20gZGF0YSBVUkw6XG4gIGlmIChjb250ZW50IGluc3RhbmNlb2YgVVJMICYmIGNvbnRlbnQucHJvdG9jb2wgPT09ICdkYXRhOicpIHtcbiAgICBjb25zdCB7IG1lZGlhVHlwZTogZGF0YVVybE1lZGlhVHlwZSwgYmFzZTY0Q29udGVudCB9ID0gc3BsaXREYXRhVXJsKFxuICAgICAgY29udGVudC50b1N0cmluZygpLFxuICAgICk7XG5cbiAgICBpZiAoZGF0YVVybE1lZGlhVHlwZSA9PSBudWxsIHx8IGJhc2U2NENvbnRlbnQgPT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEFJU0RLRXJyb3Ioe1xuICAgICAgICBuYW1lOiAnSW52YWxpZERhdGFDb250ZW50RXJyb3InLFxuICAgICAgICBtZXNzYWdlOiBgSW52YWxpZCBkYXRhIFVSTCBmb3JtYXQgaW4gY29udGVudCAke2NvbnRlbnQudG9TdHJpbmcoKX1gLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgZGF0YTogYmFzZTY0Q29udGVudCwgbWVkaWFUeXBlOiBkYXRhVXJsTWVkaWFUeXBlIH07XG4gIH1cblxuICByZXR1cm4geyBkYXRhOiBjb250ZW50LCBtZWRpYVR5cGU6IHVuZGVmaW5lZCB9O1xufVxuXG4vKipcbkNvbnZlcnRzIGRhdGEgY29udGVudCB0byBhIGJhc2U2NC1lbmNvZGVkIHN0cmluZy5cblxuQHBhcmFtIGNvbnRlbnQgLSBEYXRhIGNvbnRlbnQgdG8gY29udmVydC5cbkByZXR1cm5zIEJhc2U2NC1lbmNvZGVkIHN0cmluZy5cbiovXG5leHBvcnQgZnVuY3Rpb24gY29udmVydERhdGFDb250ZW50VG9CYXNlNjRTdHJpbmcoY29udGVudDogRGF0YUNvbnRlbnQpOiBzdHJpbmcge1xuICBpZiAodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGNvbnRlbnQ7XG4gIH1cblxuICBpZiAoY29udGVudCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgcmV0dXJuIGNvbnZlcnRVaW50OEFycmF5VG9CYXNlNjQobmV3IFVpbnQ4QXJyYXkoY29udGVudCkpO1xuICB9XG5cbiAgcmV0dXJuIGNvbnZlcnRVaW50OEFycmF5VG9CYXNlNjQoY29udGVudCk7XG59XG5cbi8qKlxuQ29udmVydHMgZGF0YSBjb250ZW50IHRvIGEgVWludDhBcnJheS5cblxuQHBhcmFtIGNvbnRlbnQgLSBEYXRhIGNvbnRlbnQgdG8gY29udmVydC5cbkByZXR1cm5zIFVpbnQ4QXJyYXkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb252ZXJ0RGF0YUNvbnRlbnRUb1VpbnQ4QXJyYXkoXG4gIGNvbnRlbnQ6IERhdGFDb250ZW50LFxuKTogVWludDhBcnJheSB7XG4gIGlmIChjb250ZW50IGluc3RhbmNlb2YgVWludDhBcnJheSkge1xuICAgIHJldHVybiBjb250ZW50O1xuICB9XG5cbiAgaWYgKHR5cGVvZiBjb250ZW50ID09PSAnc3RyaW5nJykge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gY29udmVydEJhc2U2NFRvVWludDhBcnJheShjb250ZW50KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWREYXRhQ29udGVudEVycm9yKHtcbiAgICAgICAgbWVzc2FnZTpcbiAgICAgICAgICAnSW52YWxpZCBkYXRhIGNvbnRlbnQuIENvbnRlbnQgc3RyaW5nIGlzIG5vdCBhIGJhc2U2NC1lbmNvZGVkIG1lZGlhLicsXG4gICAgICAgIGNvbnRlbnQsXG4gICAgICAgIGNhdXNlOiBlcnJvcixcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGlmIChjb250ZW50IGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoY29udGVudCk7XG4gIH1cblxuICB0aHJvdyBuZXcgSW52YWxpZERhdGFDb250ZW50RXJyb3IoeyBjb250ZW50IH0pO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIGEgVWludDhBcnJheSB0byBhIHN0cmluZyBvZiB0ZXh0LlxuICpcbiAqIEBwYXJhbSB1aW50OEFycmF5IC0gVGhlIFVpbnQ4QXJyYXkgdG8gY29udmVydC5cbiAqIEByZXR1cm5zIFRoZSBjb252ZXJ0ZWQgc3RyaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY29udmVydFVpbnQ4QXJyYXlUb1RleHQodWludDhBcnJheTogVWludDhBcnJheSk6IHN0cmluZyB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIG5ldyBUZXh0RGVjb2RlcigpLmRlY29kZSh1aW50OEFycmF5KTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0Vycm9yIGRlY29kaW5nIFVpbnQ4QXJyYXkgdG8gdGV4dCcpO1xuICB9XG59XG4iLCAiZXhwb3J0IGZ1bmN0aW9uIHNwbGl0RGF0YVVybChkYXRhVXJsOiBzdHJpbmcpOiB7XG4gIG1lZGlhVHlwZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBiYXNlNjRDb250ZW50OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG59IHtcbiAgdHJ5IHtcbiAgICBjb25zdCBbaGVhZGVyLCBiYXNlNjRDb250ZW50XSA9IGRhdGFVcmwuc3BsaXQoJywnKTtcbiAgICByZXR1cm4ge1xuICAgICAgbWVkaWFUeXBlOiBoZWFkZXIuc3BsaXQoJzsnKVswXS5zcGxpdCgnOicpWzFdLFxuICAgICAgYmFzZTY0Q29udGVudCxcbiAgICB9O1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiB7XG4gICAgICBtZWRpYVR5cGU6IHVuZGVmaW5lZCxcbiAgICAgIGJhc2U2NENvbnRlbnQ6IHVuZGVmaW5lZCxcbiAgICB9O1xuICB9XG59XG4iLCAiaW1wb3J0IHsgSW52YWxpZEFyZ3VtZW50RXJyb3IgfSBmcm9tICcuLi9lcnJvci9pbnZhbGlkLWFyZ3VtZW50LWVycm9yJztcbmltcG9ydCB7IENhbGxTZXR0aW5ncyB9IGZyb20gJy4vY2FsbC1zZXR0aW5ncyc7XG5cbi8qKlxuICogVmFsaWRhdGVzIGNhbGwgc2V0dGluZ3MgYW5kIHJldHVybnMgYSBuZXcgb2JqZWN0IHdpdGggbGltaXRlZCB2YWx1ZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcmVwYXJlQ2FsbFNldHRpbmdzKHtcbiAgbWF4T3V0cHV0VG9rZW5zLFxuICB0ZW1wZXJhdHVyZSxcbiAgdG9wUCxcbiAgdG9wSyxcbiAgcHJlc2VuY2VQZW5hbHR5LFxuICBmcmVxdWVuY3lQZW5hbHR5LFxuICBzZWVkLFxuICBzdG9wU2VxdWVuY2VzLFxufTogT21pdDxDYWxsU2V0dGluZ3MsICdhYm9ydFNpZ25hbCcgfCAnaGVhZGVycycgfCAnbWF4UmV0cmllcyc+KTogT21pdDxcbiAgQ2FsbFNldHRpbmdzLFxuICAnYWJvcnRTaWduYWwnIHwgJ2hlYWRlcnMnIHwgJ21heFJldHJpZXMnXG4+IHtcbiAgaWYgKG1heE91dHB1dFRva2VucyAhPSBudWxsKSB7XG4gICAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKG1heE91dHB1dFRva2VucykpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFcnJvcih7XG4gICAgICAgIHBhcmFtZXRlcjogJ21heE91dHB1dFRva2VucycsXG4gICAgICAgIHZhbHVlOiBtYXhPdXRwdXRUb2tlbnMsXG4gICAgICAgIG1lc3NhZ2U6ICdtYXhPdXRwdXRUb2tlbnMgbXVzdCBiZSBhbiBpbnRlZ2VyJyxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChtYXhPdXRwdXRUb2tlbnMgPCAxKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3Ioe1xuICAgICAgICBwYXJhbWV0ZXI6ICdtYXhPdXRwdXRUb2tlbnMnLFxuICAgICAgICB2YWx1ZTogbWF4T3V0cHV0VG9rZW5zLFxuICAgICAgICBtZXNzYWdlOiAnbWF4T3V0cHV0VG9rZW5zIG11c3QgYmUgPj0gMScsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBpZiAodGVtcGVyYXR1cmUgIT0gbnVsbCkge1xuICAgIGlmICh0eXBlb2YgdGVtcGVyYXR1cmUgIT09ICdudW1iZXInKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3Ioe1xuICAgICAgICBwYXJhbWV0ZXI6ICd0ZW1wZXJhdHVyZScsXG4gICAgICAgIHZhbHVlOiB0ZW1wZXJhdHVyZSxcbiAgICAgICAgbWVzc2FnZTogJ3RlbXBlcmF0dXJlIG11c3QgYmUgYSBudW1iZXInLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHRvcFAgIT0gbnVsbCkge1xuICAgIGlmICh0eXBlb2YgdG9wUCAhPT0gJ251bWJlcicpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFcnJvcih7XG4gICAgICAgIHBhcmFtZXRlcjogJ3RvcFAnLFxuICAgICAgICB2YWx1ZTogdG9wUCxcbiAgICAgICAgbWVzc2FnZTogJ3RvcFAgbXVzdCBiZSBhIG51bWJlcicsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBpZiAodG9wSyAhPSBudWxsKSB7XG4gICAgaWYgKHR5cGVvZiB0b3BLICE9PSAnbnVtYmVyJykge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEVycm9yKHtcbiAgICAgICAgcGFyYW1ldGVyOiAndG9wSycsXG4gICAgICAgIHZhbHVlOiB0b3BLLFxuICAgICAgICBtZXNzYWdlOiAndG9wSyBtdXN0IGJlIGEgbnVtYmVyJyxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGlmIChwcmVzZW5jZVBlbmFsdHkgIT0gbnVsbCkge1xuICAgIGlmICh0eXBlb2YgcHJlc2VuY2VQZW5hbHR5ICE9PSAnbnVtYmVyJykge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEVycm9yKHtcbiAgICAgICAgcGFyYW1ldGVyOiAncHJlc2VuY2VQZW5hbHR5JyxcbiAgICAgICAgdmFsdWU6IHByZXNlbmNlUGVuYWx0eSxcbiAgICAgICAgbWVzc2FnZTogJ3ByZXNlbmNlUGVuYWx0eSBtdXN0IGJlIGEgbnVtYmVyJyxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGlmIChmcmVxdWVuY3lQZW5hbHR5ICE9IG51bGwpIHtcbiAgICBpZiAodHlwZW9mIGZyZXF1ZW5jeVBlbmFsdHkgIT09ICdudW1iZXInKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3Ioe1xuICAgICAgICBwYXJhbWV0ZXI6ICdmcmVxdWVuY3lQZW5hbHR5JyxcbiAgICAgICAgdmFsdWU6IGZyZXF1ZW5jeVBlbmFsdHksXG4gICAgICAgIG1lc3NhZ2U6ICdmcmVxdWVuY3lQZW5hbHR5IG11c3QgYmUgYSBudW1iZXInLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHNlZWQgIT0gbnVsbCkge1xuICAgIGlmICghTnVtYmVyLmlzSW50ZWdlcihzZWVkKSkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEVycm9yKHtcbiAgICAgICAgcGFyYW1ldGVyOiAnc2VlZCcsXG4gICAgICAgIHZhbHVlOiBzZWVkLFxuICAgICAgICBtZXNzYWdlOiAnc2VlZCBtdXN0IGJlIGFuIGludGVnZXInLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBtYXhPdXRwdXRUb2tlbnMsXG4gICAgdGVtcGVyYXR1cmUsXG4gICAgdG9wUCxcbiAgICB0b3BLLFxuICAgIHByZXNlbmNlUGVuYWx0eSxcbiAgICBmcmVxdWVuY3lQZW5hbHR5LFxuICAgIHN0b3BTZXF1ZW5jZXMsXG4gICAgc2VlZCxcbiAgfTtcbn1cbiIsICJpbXBvcnQge1xuICBMYW5ndWFnZU1vZGVsVjJGdW5jdGlvblRvb2wsXG4gIExhbmd1YWdlTW9kZWxWMlByb3ZpZGVyRGVmaW5lZFRvb2wsXG4gIExhbmd1YWdlTW9kZWxWMlRvb2xDaG9pY2UsXG59IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgYXNTY2hlbWEgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyLXV0aWxzJztcbmltcG9ydCB7IGlzTm9uRW1wdHlPYmplY3QgfSBmcm9tICcuLi91dGlsL2lzLW5vbi1lbXB0eS1vYmplY3QnO1xuaW1wb3J0IHsgVG9vbFNldCB9IGZyb20gJy4uL2dlbmVyYXRlLXRleHQnO1xuaW1wb3J0IHsgVG9vbENob2ljZSB9IGZyb20gJy4uL3R5cGVzL2xhbmd1YWdlLW1vZGVsJztcblxuZXhwb3J0IGZ1bmN0aW9uIHByZXBhcmVUb29sc0FuZFRvb2xDaG9pY2U8VE9PTFMgZXh0ZW5kcyBUb29sU2V0Pih7XG4gIHRvb2xzLFxuICB0b29sQ2hvaWNlLFxuICBhY3RpdmVUb29scyxcbn06IHtcbiAgdG9vbHM6IFRPT0xTIHwgdW5kZWZpbmVkO1xuICB0b29sQ2hvaWNlOiBUb29sQ2hvaWNlPFRPT0xTPiB8IHVuZGVmaW5lZDtcbiAgYWN0aXZlVG9vbHM6IEFycmF5PGtleW9mIFRPT0xTPiB8IHVuZGVmaW5lZDtcbn0pOiB7XG4gIHRvb2xzOlxuICAgIHwgQXJyYXk8TGFuZ3VhZ2VNb2RlbFYyRnVuY3Rpb25Ub29sIHwgTGFuZ3VhZ2VNb2RlbFYyUHJvdmlkZXJEZWZpbmVkVG9vbD5cbiAgICB8IHVuZGVmaW5lZDtcbiAgdG9vbENob2ljZTogTGFuZ3VhZ2VNb2RlbFYyVG9vbENob2ljZSB8IHVuZGVmaW5lZDtcbn0ge1xuICBpZiAoIWlzTm9uRW1wdHlPYmplY3QodG9vbHMpKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHRvb2xzOiB1bmRlZmluZWQsXG4gICAgICB0b29sQ2hvaWNlOiB1bmRlZmluZWQsXG4gICAgfTtcbiAgfVxuXG4gIC8vIHdoZW4gYWN0aXZlVG9vbHMgaXMgcHJvdmlkZWQsIHdlIG9ubHkgaW5jbHVkZSB0aGUgdG9vbHMgdGhhdCBhcmUgaW4gdGhlIGxpc3Q6XG4gIGNvbnN0IGZpbHRlcmVkVG9vbHMgPVxuICAgIGFjdGl2ZVRvb2xzICE9IG51bGxcbiAgICAgID8gT2JqZWN0LmVudHJpZXModG9vbHMpLmZpbHRlcigoW25hbWVdKSA9PlxuICAgICAgICAgIGFjdGl2ZVRvb2xzLmluY2x1ZGVzKG5hbWUgYXMga2V5b2YgVE9PTFMpLFxuICAgICAgICApXG4gICAgICA6IE9iamVjdC5lbnRyaWVzKHRvb2xzKTtcblxuICByZXR1cm4ge1xuICAgIHRvb2xzOiBmaWx0ZXJlZFRvb2xzLm1hcCgoW25hbWUsIHRvb2xdKSA9PiB7XG4gICAgICBjb25zdCB0b29sVHlwZSA9IHRvb2wudHlwZTtcbiAgICAgIHN3aXRjaCAodG9vbFR5cGUpIHtcbiAgICAgICAgY2FzZSB1bmRlZmluZWQ6XG4gICAgICAgIGNhc2UgJ2R5bmFtaWMnOlxuICAgICAgICBjYXNlICdmdW5jdGlvbic6XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6ICdmdW5jdGlvbicgYXMgY29uc3QsXG4gICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IHRvb2wuZGVzY3JpcHRpb24sXG4gICAgICAgICAgICBpbnB1dFNjaGVtYTogYXNTY2hlbWEodG9vbC5pbnB1dFNjaGVtYSkuanNvblNjaGVtYSxcbiAgICAgICAgICAgIHByb3ZpZGVyT3B0aW9uczogdG9vbC5wcm92aWRlck9wdGlvbnMsXG4gICAgICAgICAgfTtcbiAgICAgICAgY2FzZSAncHJvdmlkZXItZGVmaW5lZCc6XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6ICdwcm92aWRlci1kZWZpbmVkJyBhcyBjb25zdCxcbiAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICBpZDogdG9vbC5pZCxcbiAgICAgICAgICAgIGFyZ3M6IHRvb2wuYXJncyxcbiAgICAgICAgICB9O1xuICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgY29uc3QgZXhoYXVzdGl2ZUNoZWNrOiBuZXZlciA9IHRvb2xUeXBlO1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgdG9vbCB0eXBlOiAke2V4aGF1c3RpdmVDaGVja31gKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pLFxuICAgIHRvb2xDaG9pY2U6XG4gICAgICB0b29sQ2hvaWNlID09IG51bGxcbiAgICAgICAgPyB7IHR5cGU6ICdhdXRvJyB9XG4gICAgICAgIDogdHlwZW9mIHRvb2xDaG9pY2UgPT09ICdzdHJpbmcnXG4gICAgICAgICAgPyB7IHR5cGU6IHRvb2xDaG9pY2UgfVxuICAgICAgICAgIDogeyB0eXBlOiAndG9vbCcgYXMgY29uc3QsIHRvb2xOYW1lOiB0b29sQ2hvaWNlLnRvb2xOYW1lIGFzIHN0cmluZyB9LFxuICB9O1xufVxuIiwgImV4cG9ydCBmdW5jdGlvbiBpc05vbkVtcHR5T2JqZWN0KFxuICBvYmplY3Q6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgdW5kZWZpbmVkIHwgbnVsbCxcbik6IG9iamVjdCBpcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gIHJldHVybiBvYmplY3QgIT0gbnVsbCAmJiBPYmplY3Qua2V5cyhvYmplY3QpLmxlbmd0aCA+IDA7XG59XG4iLCAiaW1wb3J0IHsgSW52YWxpZFByb21wdEVycm9yIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQgeyBNb2RlbE1lc3NhZ2UsIHNhZmVWYWxpZGF0ZVR5cGVzIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyB6IH0gZnJvbSAnem9kL3Y0JztcbmltcG9ydCB7IG1vZGVsTWVzc2FnZVNjaGVtYSB9IGZyb20gJy4vbWVzc2FnZSc7XG5pbXBvcnQgeyBQcm9tcHQgfSBmcm9tICcuL3Byb21wdCc7XG5cbmV4cG9ydCB0eXBlIFN0YW5kYXJkaXplZFByb21wdCA9IHtcbiAgLyoqXG4gICAqIFN5c3RlbSBtZXNzYWdlLlxuICAgKi9cbiAgc3lzdGVtPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBNZXNzYWdlcy5cbiAgICovXG4gIG1lc3NhZ2VzOiBNb2RlbE1lc3NhZ2VbXTtcbn07XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzdGFuZGFyZGl6ZVByb21wdChcbiAgcHJvbXB0OiBQcm9tcHQsXG4pOiBQcm9taXNlPFN0YW5kYXJkaXplZFByb21wdD4ge1xuICBpZiAocHJvbXB0LnByb21wdCA9PSBudWxsICYmIHByb21wdC5tZXNzYWdlcyA9PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IEludmFsaWRQcm9tcHRFcnJvcih7XG4gICAgICBwcm9tcHQsXG4gICAgICBtZXNzYWdlOiAncHJvbXB0IG9yIG1lc3NhZ2VzIG11c3QgYmUgZGVmaW5lZCcsXG4gICAgfSk7XG4gIH1cblxuICBpZiAocHJvbXB0LnByb21wdCAhPSBudWxsICYmIHByb21wdC5tZXNzYWdlcyAhPSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IEludmFsaWRQcm9tcHRFcnJvcih7XG4gICAgICBwcm9tcHQsXG4gICAgICBtZXNzYWdlOiAncHJvbXB0IGFuZCBtZXNzYWdlcyBjYW5ub3QgYmUgZGVmaW5lZCBhdCB0aGUgc2FtZSB0aW1lJyxcbiAgICB9KTtcbiAgfVxuXG4gIC8vIHZhbGlkYXRlIHRoYXQgc3lzdGVtIGlzIGEgc3RyaW5nXG4gIGlmIChwcm9tcHQuc3lzdGVtICE9IG51bGwgJiYgdHlwZW9mIHByb21wdC5zeXN0ZW0gIT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IEludmFsaWRQcm9tcHRFcnJvcih7XG4gICAgICBwcm9tcHQsXG4gICAgICBtZXNzYWdlOiAnc3lzdGVtIG11c3QgYmUgYSBzdHJpbmcnLFxuICAgIH0pO1xuICB9XG5cbiAgbGV0IG1lc3NhZ2VzOiBNb2RlbE1lc3NhZ2VbXTtcblxuICBpZiAocHJvbXB0LnByb21wdCAhPSBudWxsICYmIHR5cGVvZiBwcm9tcHQucHJvbXB0ID09PSAnc3RyaW5nJykge1xuICAgIG1lc3NhZ2VzID0gW3sgcm9sZTogJ3VzZXInLCBjb250ZW50OiBwcm9tcHQucHJvbXB0IH1dO1xuICB9IGVsc2UgaWYgKHByb21wdC5wcm9tcHQgIT0gbnVsbCAmJiBBcnJheS5pc0FycmF5KHByb21wdC5wcm9tcHQpKSB7XG4gICAgbWVzc2FnZXMgPSBwcm9tcHQucHJvbXB0O1xuICB9IGVsc2UgaWYgKHByb21wdC5tZXNzYWdlcyAhPSBudWxsKSB7XG4gICAgbWVzc2FnZXMgPSBwcm9tcHQubWVzc2FnZXM7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEludmFsaWRQcm9tcHRFcnJvcih7XG4gICAgICBwcm9tcHQsXG4gICAgICBtZXNzYWdlOiAncHJvbXB0IG9yIG1lc3NhZ2VzIG11c3QgYmUgZGVmaW5lZCcsXG4gICAgfSk7XG4gIH1cblxuICBpZiAobWVzc2FnZXMubGVuZ3RoID09PSAwKSB7XG4gICAgdGhyb3cgbmV3IEludmFsaWRQcm9tcHRFcnJvcih7XG4gICAgICBwcm9tcHQsXG4gICAgICBtZXNzYWdlOiAnbWVzc2FnZXMgbXVzdCBub3QgYmUgZW1wdHknLFxuICAgIH0pO1xuICB9XG5cbiAgY29uc3QgdmFsaWRhdGlvblJlc3VsdCA9IGF3YWl0IHNhZmVWYWxpZGF0ZVR5cGVzKHtcbiAgICB2YWx1ZTogbWVzc2FnZXMsXG4gICAgc2NoZW1hOiB6LmFycmF5KG1vZGVsTWVzc2FnZVNjaGVtYSksXG4gIH0pO1xuXG4gIGlmICghdmFsaWRhdGlvblJlc3VsdC5zdWNjZXNzKSB7XG4gICAgdGhyb3cgbmV3IEludmFsaWRQcm9tcHRFcnJvcih7XG4gICAgICBwcm9tcHQsXG4gICAgICBtZXNzYWdlOlxuICAgICAgICAnVGhlIG1lc3NhZ2VzIG11c3QgYmUgYSBNb2RlbE1lc3NhZ2VbXS4gJyArXG4gICAgICAgICdJZiB5b3UgaGF2ZSBwYXNzZWQgYSBVSU1lc3NhZ2VbXSwgeW91IGNhbiB1c2UgY29udmVydFRvTW9kZWxNZXNzYWdlcyB0byBjb252ZXJ0IHRoZW0uJyxcbiAgICAgIGNhdXNlOiB2YWxpZGF0aW9uUmVzdWx0LmVycm9yLFxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBtZXNzYWdlcyxcbiAgICBzeXN0ZW06IHByb21wdC5zeXN0ZW0sXG4gIH07XG59XG4iLCAiaW1wb3J0IHtcbiAgQXNzaXN0YW50TW9kZWxNZXNzYWdlLFxuICBNb2RlbE1lc3NhZ2UsXG4gIFN5c3RlbU1vZGVsTWVzc2FnZSxcbiAgVG9vbE1vZGVsTWVzc2FnZSxcbiAgVXNlck1vZGVsTWVzc2FnZSxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyB6IH0gZnJvbSAnem9kL3Y0JztcbmltcG9ydCB7IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEgfSBmcm9tICcuLi90eXBlcy9wcm92aWRlci1tZXRhZGF0YSc7XG5pbXBvcnQge1xuICBmaWxlUGFydFNjaGVtYSxcbiAgaW1hZ2VQYXJ0U2NoZW1hLFxuICByZWFzb25pbmdQYXJ0U2NoZW1hLFxuICB0ZXh0UGFydFNjaGVtYSxcbiAgdG9vbENhbGxQYXJ0U2NoZW1hLFxuICB0b29sUmVzdWx0UGFydFNjaGVtYSxcbn0gZnJvbSAnLi9jb250ZW50LXBhcnQnO1xuXG4vKipcbkBkZXByZWNhdGVkIFVzZSBgU3lzdGVtTW9kZWxNZXNzYWdlYCBpbnN0ZWFkLlxuICovXG4vLyBUT0RPIHJlbW92ZSBpbiBBSSBTREsgNlxuZXhwb3J0IHR5cGUgQ29yZVN5c3RlbU1lc3NhZ2UgPSBTeXN0ZW1Nb2RlbE1lc3NhZ2U7XG5cbmV4cG9ydCBjb25zdCBzeXN0ZW1Nb2RlbE1lc3NhZ2VTY2hlbWE6IHouWm9kVHlwZTxTeXN0ZW1Nb2RlbE1lc3NhZ2U+ID0gei5vYmplY3QoXG4gIHtcbiAgICByb2xlOiB6LmxpdGVyYWwoJ3N5c3RlbScpLFxuICAgIGNvbnRlbnQ6IHouc3RyaW5nKCksXG4gICAgcHJvdmlkZXJPcHRpb25zOiBwcm92aWRlck1ldGFkYXRhU2NoZW1hLm9wdGlvbmFsKCksXG4gIH0sXG4pO1xuXG4vKipcbkBkZXByZWNhdGVkIFVzZSBgc3lzdGVtTW9kZWxNZXNzYWdlU2NoZW1hYCBpbnN0ZWFkLlxuICovXG4vLyBUT0RPIHJlbW92ZSBpbiBBSSBTREsgNlxuZXhwb3J0IGNvbnN0IGNvcmVTeXN0ZW1NZXNzYWdlU2NoZW1hID0gc3lzdGVtTW9kZWxNZXNzYWdlU2NoZW1hO1xuXG4vKipcbkBkZXByZWNhdGVkIFVzZSBgVXNlck1vZGVsTWVzc2FnZWAgaW5zdGVhZC5cbiAqL1xuLy8gVE9ETyByZW1vdmUgaW4gQUkgU0RLIDZcbmV4cG9ydCB0eXBlIENvcmVVc2VyTWVzc2FnZSA9IFVzZXJNb2RlbE1lc3NhZ2U7XG5cbmV4cG9ydCBjb25zdCB1c2VyTW9kZWxNZXNzYWdlU2NoZW1hOiB6LlpvZFR5cGU8VXNlck1vZGVsTWVzc2FnZT4gPSB6Lm9iamVjdCh7XG4gIHJvbGU6IHoubGl0ZXJhbCgndXNlcicpLFxuICBjb250ZW50OiB6LnVuaW9uKFtcbiAgICB6LnN0cmluZygpLFxuICAgIHouYXJyYXkoei51bmlvbihbdGV4dFBhcnRTY2hlbWEsIGltYWdlUGFydFNjaGVtYSwgZmlsZVBhcnRTY2hlbWFdKSksXG4gIF0pLFxuICBwcm92aWRlck9wdGlvbnM6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbn0pO1xuXG4vKipcbkBkZXByZWNhdGVkIFVzZSBgdXNlck1vZGVsTWVzc2FnZVNjaGVtYWAgaW5zdGVhZC5cbiAqL1xuLy8gVE9ETyByZW1vdmUgaW4gQUkgU0RLIDZcbmV4cG9ydCBjb25zdCBjb3JlVXNlck1lc3NhZ2VTY2hlbWEgPSB1c2VyTW9kZWxNZXNzYWdlU2NoZW1hO1xuXG4vKipcbkBkZXByZWNhdGVkIFVzZSBgQXNzaXN0YW50TW9kZWxNZXNzYWdlYCBpbnN0ZWFkLlxuICovXG4vLyBUT0RPIHJlbW92ZSBpbiBBSSBTREsgNlxuZXhwb3J0IHR5cGUgQ29yZUFzc2lzdGFudE1lc3NhZ2UgPSBBc3Npc3RhbnRNb2RlbE1lc3NhZ2U7XG5cbmV4cG9ydCBjb25zdCBhc3Npc3RhbnRNb2RlbE1lc3NhZ2VTY2hlbWE6IHouWm9kVHlwZTxBc3Npc3RhbnRNb2RlbE1lc3NhZ2U+ID1cbiAgei5vYmplY3Qoe1xuICAgIHJvbGU6IHoubGl0ZXJhbCgnYXNzaXN0YW50JyksXG4gICAgY29udGVudDogei51bmlvbihbXG4gICAgICB6LnN0cmluZygpLFxuICAgICAgei5hcnJheShcbiAgICAgICAgei51bmlvbihbXG4gICAgICAgICAgdGV4dFBhcnRTY2hlbWEsXG4gICAgICAgICAgZmlsZVBhcnRTY2hlbWEsXG4gICAgICAgICAgcmVhc29uaW5nUGFydFNjaGVtYSxcbiAgICAgICAgICB0b29sQ2FsbFBhcnRTY2hlbWEsXG4gICAgICAgICAgdG9vbFJlc3VsdFBhcnRTY2hlbWEsXG4gICAgICAgIF0pLFxuICAgICAgKSxcbiAgICBdKSxcbiAgICBwcm92aWRlck9wdGlvbnM6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbiAgfSk7XG5cbi8qKlxuQGRlcHJlY2F0ZWQgVXNlIGBhc3Npc3RhbnRNb2RlbE1lc3NhZ2VTY2hlbWFgIGluc3RlYWQuXG4gKi9cbi8vIFRPRE8gcmVtb3ZlIGluIEFJIFNESyA2XG5leHBvcnQgY29uc3QgY29yZUFzc2lzdGFudE1lc3NhZ2VTY2hlbWEgPSBhc3Npc3RhbnRNb2RlbE1lc3NhZ2VTY2hlbWE7XG5cbi8qKlxuQGRlcHJlY2F0ZWQgVXNlIGBUb29sTW9kZWxNZXNzYWdlYCBpbnN0ZWFkLlxuICovXG4vLyBUT0RPIHJlbW92ZSBpbiBBSSBTREsgNlxuZXhwb3J0IHR5cGUgQ29yZVRvb2xNZXNzYWdlID0gVG9vbE1vZGVsTWVzc2FnZTtcblxuZXhwb3J0IGNvbnN0IHRvb2xNb2RlbE1lc3NhZ2VTY2hlbWE6IHouWm9kVHlwZTxUb29sTW9kZWxNZXNzYWdlPiA9IHoub2JqZWN0KHtcbiAgcm9sZTogei5saXRlcmFsKCd0b29sJyksXG4gIGNvbnRlbnQ6IHouYXJyYXkodG9vbFJlc3VsdFBhcnRTY2hlbWEpLFxuICBwcm92aWRlck9wdGlvbnM6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbn0pO1xuXG4vKipcbkBkZXByZWNhdGVkIFVzZSBgdG9vbE1vZGVsTWVzc2FnZVNjaGVtYWAgaW5zdGVhZC5cbiAqL1xuLy8gVE9ETyByZW1vdmUgaW4gQUkgU0RLIDZcbmV4cG9ydCBjb25zdCBjb3JlVG9vbE1lc3NhZ2VTY2hlbWEgPSB0b29sTW9kZWxNZXNzYWdlU2NoZW1hO1xuXG4vKipcbkBkZXByZWNhdGVkIFVzZSBgTW9kZWxNZXNzYWdlYCBpbnN0ZWFkLlxuICAgKi9cbi8vIFRPRE8gcmVtb3ZlIGluIEFJIFNESyA2XG5leHBvcnQgdHlwZSBDb3JlTWVzc2FnZSA9IE1vZGVsTWVzc2FnZTtcblxuZXhwb3J0IGNvbnN0IG1vZGVsTWVzc2FnZVNjaGVtYTogei5ab2RUeXBlPE1vZGVsTWVzc2FnZT4gPSB6LnVuaW9uKFtcbiAgc3lzdGVtTW9kZWxNZXNzYWdlU2NoZW1hLFxuICB1c2VyTW9kZWxNZXNzYWdlU2NoZW1hLFxuICBhc3Npc3RhbnRNb2RlbE1lc3NhZ2VTY2hlbWEsXG4gIHRvb2xNb2RlbE1lc3NhZ2VTY2hlbWEsXG5dKTtcblxuLyoqXG5AZGVwcmVjYXRlZCBVc2UgYG1vZGVsTWVzc2FnZVNjaGVtYWAgaW5zdGVhZC5cbiAqL1xuLy8gVE9ETyByZW1vdmUgaW4gQUkgU0RLIDZcbmV4cG9ydCBjb25zdCBjb3JlTWVzc2FnZVNjaGVtYTogei5ab2RUeXBlPENvcmVNZXNzYWdlPiA9IG1vZGVsTWVzc2FnZVNjaGVtYTtcbiIsICJpbXBvcnQgeyBTaGFyZWRWMlByb3ZpZGVyTWV0YWRhdGEgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcbmltcG9ydCB7IHogfSBmcm9tICd6b2QvdjQnO1xuaW1wb3J0IHsganNvblZhbHVlU2NoZW1hIH0gZnJvbSAnLi9qc29uLXZhbHVlJztcblxuLyoqXG5BZGRpdGlvbmFsIHByb3ZpZGVyLXNwZWNpZmljIG1ldGFkYXRhIHRoYXQgaXMgcmV0dXJuZWQgZnJvbSB0aGUgcHJvdmlkZXIuXG5cblRoaXMgaXMgbmVlZGVkIHRvIGVuYWJsZSBwcm92aWRlci1zcGVjaWZpYyBmdW5jdGlvbmFsaXR5IHRoYXQgY2FuIGJlXG5mdWxseSBlbmNhcHN1bGF0ZWQgaW4gdGhlIHByb3ZpZGVyLlxuICovXG5leHBvcnQgdHlwZSBQcm92aWRlck1ldGFkYXRhID0gU2hhcmVkVjJQcm92aWRlck1ldGFkYXRhO1xuXG5leHBvcnQgY29uc3QgcHJvdmlkZXJNZXRhZGF0YVNjaGVtYTogei5ab2RUeXBlPFByb3ZpZGVyTWV0YWRhdGE+ID0gei5yZWNvcmQoXG4gIHouc3RyaW5nKCksXG4gIHoucmVjb3JkKHouc3RyaW5nKCksIGpzb25WYWx1ZVNjaGVtYSksXG4pO1xuIiwgImltcG9ydCB7IEpTT05WYWx1ZSBhcyBPcmlnaW5hbEpTT05WYWx1ZSB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgeiB9IGZyb20gJ3pvZC92NCc7XG5cbmV4cG9ydCBjb25zdCBqc29uVmFsdWVTY2hlbWE6IHouWm9kVHlwZTxKU09OVmFsdWU+ID0gei5sYXp5KCgpID0+XG4gIHoudW5pb24oW1xuICAgIHoubnVsbCgpLFxuICAgIHouc3RyaW5nKCksXG4gICAgei5udW1iZXIoKSxcbiAgICB6LmJvb2xlYW4oKSxcbiAgICB6LnJlY29yZCh6LnN0cmluZygpLCBqc29uVmFsdWVTY2hlbWEpLFxuICAgIHouYXJyYXkoanNvblZhbHVlU2NoZW1hKSxcbiAgXSksXG4pO1xuXG5leHBvcnQgdHlwZSBKU09OVmFsdWUgPSBPcmlnaW5hbEpTT05WYWx1ZTtcbiIsICJpbXBvcnQgeyBMYW5ndWFnZU1vZGVsVjJUb29sUmVzdWx0T3V0cHV0IH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQge1xuICBGaWxlUGFydCxcbiAgSW1hZ2VQYXJ0LFxuICBQcm92aWRlck9wdGlvbnMsXG4gIFJlYXNvbmluZ1BhcnQsXG4gIFRleHRQYXJ0LFxuICBUb29sUmVzdWx0UGFydCxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyB6IH0gZnJvbSAnem9kL3Y0JztcbmltcG9ydCB7IGpzb25WYWx1ZVNjaGVtYSB9IGZyb20gJy4uL3R5cGVzL2pzb24tdmFsdWUnO1xuaW1wb3J0IHsgcHJvdmlkZXJNZXRhZGF0YVNjaGVtYSB9IGZyb20gJy4uL3R5cGVzL3Byb3ZpZGVyLW1ldGFkYXRhJztcbmltcG9ydCB7IGRhdGFDb250ZW50U2NoZW1hIH0gZnJvbSAnLi9kYXRhLWNvbnRlbnQnO1xuXG4vKipcbkBpbnRlcm5hbFxuICovXG5leHBvcnQgY29uc3QgdGV4dFBhcnRTY2hlbWE6IHouWm9kVHlwZTxUZXh0UGFydD4gPSB6Lm9iamVjdCh7XG4gIHR5cGU6IHoubGl0ZXJhbCgndGV4dCcpLFxuICB0ZXh0OiB6LnN0cmluZygpLFxuICBwcm92aWRlck9wdGlvbnM6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbn0pO1xuXG4vKipcbkBpbnRlcm5hbFxuICovXG5leHBvcnQgY29uc3QgaW1hZ2VQYXJ0U2NoZW1hOiB6LlpvZFR5cGU8SW1hZ2VQYXJ0PiA9IHoub2JqZWN0KHtcbiAgdHlwZTogei5saXRlcmFsKCdpbWFnZScpLFxuICBpbWFnZTogei51bmlvbihbZGF0YUNvbnRlbnRTY2hlbWEsIHouaW5zdGFuY2VvZihVUkwpXSksXG4gIG1lZGlhVHlwZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICBwcm92aWRlck9wdGlvbnM6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbn0pO1xuXG4vKipcbkBpbnRlcm5hbFxuICovXG5leHBvcnQgY29uc3QgZmlsZVBhcnRTY2hlbWE6IHouWm9kVHlwZTxGaWxlUGFydD4gPSB6Lm9iamVjdCh7XG4gIHR5cGU6IHoubGl0ZXJhbCgnZmlsZScpLFxuICBkYXRhOiB6LnVuaW9uKFtkYXRhQ29udGVudFNjaGVtYSwgei5pbnN0YW5jZW9mKFVSTCldKSxcbiAgZmlsZW5hbWU6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgbWVkaWFUeXBlOiB6LnN0cmluZygpLFxuICBwcm92aWRlck9wdGlvbnM6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbn0pO1xuXG4vKipcbkBpbnRlcm5hbFxuICovXG5leHBvcnQgY29uc3QgcmVhc29uaW5nUGFydFNjaGVtYTogei5ab2RUeXBlPFJlYXNvbmluZ1BhcnQ+ID0gei5vYmplY3Qoe1xuICB0eXBlOiB6LmxpdGVyYWwoJ3JlYXNvbmluZycpLFxuICB0ZXh0OiB6LnN0cmluZygpLFxuICBwcm92aWRlck9wdGlvbnM6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbn0pO1xuXG4vKipcblRvb2wgY2FsbCBjb250ZW50IHBhcnQgb2YgYSBwcm9tcHQuIEl0IGNvbnRhaW5zIGEgdG9vbCBjYWxsICh1c3VhbGx5IGdlbmVyYXRlZCBieSB0aGUgQUkgbW9kZWwpLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRvb2xDYWxsUGFydCB7XG4gIHR5cGU6ICd0b29sLWNhbGwnO1xuXG4gIC8qKlxuSUQgb2YgdGhlIHRvb2wgY2FsbC4gVGhpcyBJRCBpcyB1c2VkIHRvIG1hdGNoIHRoZSB0b29sIGNhbGwgd2l0aCB0aGUgdG9vbCByZXN1bHQuXG4gKi9cbiAgdG9vbENhbGxJZDogc3RyaW5nO1xuXG4gIC8qKlxuTmFtZSBvZiB0aGUgdG9vbCB0aGF0IGlzIGJlaW5nIGNhbGxlZC5cbiAqL1xuICB0b29sTmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuQXJndW1lbnRzIG9mIHRoZSB0b29sIGNhbGwuIFRoaXMgaXMgYSBKU09OLXNlcmlhbGl6YWJsZSBvYmplY3QgdGhhdCBtYXRjaGVzIHRoZSB0b29sJ3MgaW5wdXQgc2NoZW1hLlxuICAgKi9cbiAgaW5wdXQ6IHVua25vd247XG5cbiAgLyoqXG5BZGRpdGlvbmFsIHByb3ZpZGVyLXNwZWNpZmljIG1ldGFkYXRhLiBUaGV5IGFyZSBwYXNzZWQgdGhyb3VnaFxudG8gdGhlIHByb3ZpZGVyIGZyb20gdGhlIEFJIFNESyBhbmQgZW5hYmxlIHByb3ZpZGVyLXNwZWNpZmljXG5mdW5jdGlvbmFsaXR5IHRoYXQgY2FuIGJlIGZ1bGx5IGVuY2Fwc3VsYXRlZCBpbiB0aGUgcHJvdmlkZXIuXG4gKi9cbiAgcHJvdmlkZXJPcHRpb25zPzogUHJvdmlkZXJPcHRpb25zO1xufVxuXG4vKipcbkBpbnRlcm5hbFxuICovXG5leHBvcnQgY29uc3QgdG9vbENhbGxQYXJ0U2NoZW1hOiB6LlpvZFR5cGU8VG9vbENhbGxQYXJ0PiA9IHoub2JqZWN0KHtcbiAgdHlwZTogei5saXRlcmFsKCd0b29sLWNhbGwnKSxcbiAgdG9vbENhbGxJZDogei5zdHJpbmcoKSxcbiAgdG9vbE5hbWU6IHouc3RyaW5nKCksXG4gIGlucHV0OiB6LnVua25vd24oKSxcbiAgcHJvdmlkZXJPcHRpb25zOiBwcm92aWRlck1ldGFkYXRhU2NoZW1hLm9wdGlvbmFsKCksXG4gIHByb3ZpZGVyRXhlY3V0ZWQ6IHouYm9vbGVhbigpLm9wdGlvbmFsKCksXG59KSBhcyB6LlpvZFR5cGU8VG9vbENhbGxQYXJ0PjsgLy8gbmVjZXNzYXJ5IGJjIGlucHV0IGlzIG9wdGlvbmFsIG9uIFpvZCB0eXBlXG5cbi8qKlxuQGludGVybmFsXG4gKi9cbmV4cG9ydCBjb25zdCBvdXRwdXRTY2hlbWE6IHouWm9kVHlwZTxMYW5ndWFnZU1vZGVsVjJUb29sUmVzdWx0T3V0cHV0PiA9XG4gIHouZGlzY3JpbWluYXRlZFVuaW9uKCd0eXBlJywgW1xuICAgIHoub2JqZWN0KHtcbiAgICAgIHR5cGU6IHoubGl0ZXJhbCgndGV4dCcpLFxuICAgICAgdmFsdWU6IHouc3RyaW5nKCksXG4gICAgfSksXG4gICAgei5vYmplY3Qoe1xuICAgICAgdHlwZTogei5saXRlcmFsKCdqc29uJyksXG4gICAgICB2YWx1ZToganNvblZhbHVlU2NoZW1hLFxuICAgIH0pLFxuICAgIHoub2JqZWN0KHtcbiAgICAgIHR5cGU6IHoubGl0ZXJhbCgnZXJyb3ItdGV4dCcpLFxuICAgICAgdmFsdWU6IHouc3RyaW5nKCksXG4gICAgfSksXG4gICAgei5vYmplY3Qoe1xuICAgICAgdHlwZTogei5saXRlcmFsKCdlcnJvci1qc29uJyksXG4gICAgICB2YWx1ZToganNvblZhbHVlU2NoZW1hLFxuICAgIH0pLFxuICAgIHoub2JqZWN0KHtcbiAgICAgIHR5cGU6IHoubGl0ZXJhbCgnY29udGVudCcpLFxuICAgICAgdmFsdWU6IHouYXJyYXkoXG4gICAgICAgIHoudW5pb24oW1xuICAgICAgICAgIHoub2JqZWN0KHtcbiAgICAgICAgICAgIHR5cGU6IHoubGl0ZXJhbCgndGV4dCcpLFxuICAgICAgICAgICAgdGV4dDogei5zdHJpbmcoKSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICB6Lm9iamVjdCh7XG4gICAgICAgICAgICB0eXBlOiB6LmxpdGVyYWwoJ21lZGlhJyksXG4gICAgICAgICAgICBkYXRhOiB6LnN0cmluZygpLFxuICAgICAgICAgICAgbWVkaWFUeXBlOiB6LnN0cmluZygpLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdKSxcbiAgICAgICksXG4gICAgfSksXG4gIF0pO1xuXG4vKipcbkBpbnRlcm5hbFxuICovXG5leHBvcnQgY29uc3QgdG9vbFJlc3VsdFBhcnRTY2hlbWE6IHouWm9kVHlwZTxUb29sUmVzdWx0UGFydD4gPSB6Lm9iamVjdCh7XG4gIHR5cGU6IHoubGl0ZXJhbCgndG9vbC1yZXN1bHQnKSxcbiAgdG9vbENhbGxJZDogei5zdHJpbmcoKSxcbiAgdG9vbE5hbWU6IHouc3RyaW5nKCksXG4gIG91dHB1dDogb3V0cHV0U2NoZW1hLFxuICBwcm92aWRlck9wdGlvbnM6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbn0pIGFzIHouWm9kVHlwZTxUb29sUmVzdWx0UGFydD47IC8vIG5lY2Vzc2FyeSBiYyByZXN1bHQgaXMgb3B0aW9uYWwgb24gWm9kIHR5cGVcbiIsICJpbXBvcnQge1xuICBHYXRld2F5QXV0aGVudGljYXRpb25FcnJvcixcbiAgR2F0ZXdheU1vZGVsTm90Rm91bmRFcnJvcixcbn0gZnJvbSAnQGFpLXNkay9nYXRld2F5JztcbmltcG9ydCB7IEFJU0RLRXJyb3IgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcblxuZXhwb3J0IGZ1bmN0aW9uIHdyYXBHYXRld2F5RXJyb3IoZXJyb3I6IHVua25vd24pOiB1bmtub3duIHtcbiAgaWYgKFxuICAgIEdhdGV3YXlBdXRoZW50aWNhdGlvbkVycm9yLmlzSW5zdGFuY2UoZXJyb3IpIHx8XG4gICAgR2F0ZXdheU1vZGVsTm90Rm91bmRFcnJvci5pc0luc3RhbmNlKGVycm9yKVxuICApIHtcbiAgICByZXR1cm4gbmV3IEFJU0RLRXJyb3Ioe1xuICAgICAgbmFtZTogJ0dhdGV3YXlFcnJvcicsXG4gICAgICBtZXNzYWdlOlxuICAgICAgICAnVmVyY2VsIEFJIEdhdGV3YXkgYWNjZXNzIGZhaWxlZC4gJyArXG4gICAgICAgICdJZiB5b3Ugd2FudCB0byB1c2UgQUkgU0RLIHByb3ZpZGVycyBkaXJlY3RseSwgdXNlIHRoZSBwcm92aWRlcnMsIGUuZy4gQGFpLXNkay9vcGVuYWksICcgK1xuICAgICAgICAnb3IgcmVnaXN0ZXIgYSBkaWZmZXJlbnQgZ2xvYmFsIGRlZmF1bHQgcHJvdmlkZXIuJyxcbiAgICAgIGNhdXNlOiBlcnJvcixcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBlcnJvcjtcbn1cbiIsICJpbXBvcnQgeyBUZWxlbWV0cnlTZXR0aW5ncyB9IGZyb20gJy4vdGVsZW1ldHJ5LXNldHRpbmdzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGFzc2VtYmxlT3BlcmF0aW9uTmFtZSh7XG4gIG9wZXJhdGlvbklkLFxuICB0ZWxlbWV0cnksXG59OiB7XG4gIG9wZXJhdGlvbklkOiBzdHJpbmc7XG4gIHRlbGVtZXRyeT86IFRlbGVtZXRyeVNldHRpbmdzO1xufSkge1xuICByZXR1cm4ge1xuICAgIC8vIHN0YW5kYXJkaXplZCBvcGVyYXRpb24gYW5kIHJlc291cmNlIG5hbWU6XG4gICAgJ29wZXJhdGlvbi5uYW1lJzogYCR7b3BlcmF0aW9uSWR9JHtcbiAgICAgIHRlbGVtZXRyeT8uZnVuY3Rpb25JZCAhPSBudWxsID8gYCAke3RlbGVtZXRyeS5mdW5jdGlvbklkfWAgOiAnJ1xuICAgIH1gLFxuICAgICdyZXNvdXJjZS5uYW1lJzogdGVsZW1ldHJ5Py5mdW5jdGlvbklkLFxuXG4gICAgLy8gZGV0YWlsZWQsIEFJIFNESyBzcGVjaWZpYyBkYXRhOlxuICAgICdhaS5vcGVyYXRpb25JZCc6IG9wZXJhdGlvbklkLFxuICAgICdhaS50ZWxlbWV0cnkuZnVuY3Rpb25JZCc6IHRlbGVtZXRyeT8uZnVuY3Rpb25JZCxcbiAgfTtcbn1cbiIsICJpbXBvcnQgeyBBdHRyaWJ1dGVzIH0gZnJvbSAnQG9wZW50ZWxlbWV0cnkvYXBpJztcbmltcG9ydCB7IENhbGxTZXR0aW5ncyB9IGZyb20gJy4uL3Byb21wdC9jYWxsLXNldHRpbmdzJztcbmltcG9ydCB7IFRlbGVtZXRyeVNldHRpbmdzIH0gZnJvbSAnLi90ZWxlbWV0cnktc2V0dGluZ3MnO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QmFzZVRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICBtb2RlbCxcbiAgc2V0dGluZ3MsXG4gIHRlbGVtZXRyeSxcbiAgaGVhZGVycyxcbn06IHtcbiAgbW9kZWw6IHsgbW9kZWxJZDogc3RyaW5nOyBwcm92aWRlcjogc3RyaW5nIH07XG4gIHNldHRpbmdzOiBPbWl0PENhbGxTZXR0aW5ncywgJ2Fib3J0U2lnbmFsJyB8ICdoZWFkZXJzJyB8ICd0ZW1wZXJhdHVyZSc+O1xuICB0ZWxlbWV0cnk6IFRlbGVtZXRyeVNldHRpbmdzIHwgdW5kZWZpbmVkO1xuICBoZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+IHwgdW5kZWZpbmVkO1xufSk6IEF0dHJpYnV0ZXMge1xuICByZXR1cm4ge1xuICAgICdhaS5tb2RlbC5wcm92aWRlcic6IG1vZGVsLnByb3ZpZGVyLFxuICAgICdhaS5tb2RlbC5pZCc6IG1vZGVsLm1vZGVsSWQsXG5cbiAgICAvLyBzZXR0aW5nczpcbiAgICAuLi5PYmplY3QuZW50cmllcyhzZXR0aW5ncykucmVkdWNlKChhdHRyaWJ1dGVzLCBba2V5LCB2YWx1ZV0pID0+IHtcbiAgICAgIGF0dHJpYnV0ZXNbYGFpLnNldHRpbmdzLiR7a2V5fWBdID0gdmFsdWU7XG4gICAgICByZXR1cm4gYXR0cmlidXRlcztcbiAgICB9LCB7fSBhcyBBdHRyaWJ1dGVzKSxcblxuICAgIC8vIGFkZCBtZXRhZGF0YSBhcyBhdHRyaWJ1dGVzOlxuICAgIC4uLk9iamVjdC5lbnRyaWVzKHRlbGVtZXRyeT8ubWV0YWRhdGEgPz8ge30pLnJlZHVjZShcbiAgICAgIChhdHRyaWJ1dGVzLCBba2V5LCB2YWx1ZV0pID0+IHtcbiAgICAgICAgYXR0cmlidXRlc1tgYWkudGVsZW1ldHJ5Lm1ldGFkYXRhLiR7a2V5fWBdID0gdmFsdWU7XG4gICAgICAgIHJldHVybiBhdHRyaWJ1dGVzO1xuICAgICAgfSxcbiAgICAgIHt9IGFzIEF0dHJpYnV0ZXMsXG4gICAgKSxcblxuICAgIC8vIHJlcXVlc3QgaGVhZGVyc1xuICAgIC4uLk9iamVjdC5lbnRyaWVzKGhlYWRlcnMgPz8ge30pLnJlZHVjZSgoYXR0cmlidXRlcywgW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBhdHRyaWJ1dGVzW2BhaS5yZXF1ZXN0LmhlYWRlcnMuJHtrZXl9YF0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhdHRyaWJ1dGVzO1xuICAgIH0sIHt9IGFzIEF0dHJpYnV0ZXMpLFxuICB9O1xufVxuIiwgImltcG9ydCB7IFRyYWNlciwgdHJhY2UgfSBmcm9tICdAb3BlbnRlbGVtZXRyeS9hcGknO1xuaW1wb3J0IHsgbm9vcFRyYWNlciB9IGZyb20gJy4vbm9vcC10cmFjZXInO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VHJhY2VyKHtcbiAgaXNFbmFibGVkID0gZmFsc2UsXG4gIHRyYWNlcixcbn06IHtcbiAgaXNFbmFibGVkPzogYm9vbGVhbjtcbiAgdHJhY2VyPzogVHJhY2VyO1xufSA9IHt9KTogVHJhY2VyIHtcbiAgaWYgKCFpc0VuYWJsZWQpIHtcbiAgICByZXR1cm4gbm9vcFRyYWNlcjtcbiAgfVxuXG4gIGlmICh0cmFjZXIpIHtcbiAgICByZXR1cm4gdHJhY2VyO1xuICB9XG5cbiAgcmV0dXJuIHRyYWNlLmdldFRyYWNlcignYWknKTtcbn1cbiIsICJpbXBvcnQgeyBTcGFuLCBTcGFuQ29udGV4dCwgVHJhY2VyIH0gZnJvbSAnQG9wZW50ZWxlbWV0cnkvYXBpJztcblxuLyoqXG4gKiBUcmFjZXIgaW1wbGVtZW50YXRpb24gdGhhdCBkb2VzIG5vdGhpbmcgKG51bGwgb2JqZWN0KS5cbiAqL1xuZXhwb3J0IGNvbnN0IG5vb3BUcmFjZXI6IFRyYWNlciA9IHtcbiAgc3RhcnRTcGFuKCk6IFNwYW4ge1xuICAgIHJldHVybiBub29wU3BhbjtcbiAgfSxcblxuICBzdGFydEFjdGl2ZVNwYW48RiBleHRlbmRzIChzcGFuOiBTcGFuKSA9PiB1bmtub3duPihcbiAgICBuYW1lOiB1bmtub3duLFxuICAgIGFyZzE6IHVua25vd24sXG4gICAgYXJnMj86IHVua25vd24sXG4gICAgYXJnMz86IEYsXG4gICk6IFJldHVyblR5cGU8YW55PiB7XG4gICAgaWYgKHR5cGVvZiBhcmcxID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gYXJnMShub29wU3Bhbik7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgYXJnMiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIGFyZzIobm9vcFNwYW4pO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGFyZzMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiBhcmczKG5vb3BTcGFuKTtcbiAgICB9XG4gIH0sXG59O1xuXG5jb25zdCBub29wU3BhbjogU3BhbiA9IHtcbiAgc3BhbkNvbnRleHQoKSB7XG4gICAgcmV0dXJuIG5vb3BTcGFuQ29udGV4dDtcbiAgfSxcbiAgc2V0QXR0cmlidXRlKCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9LFxuICBzZXRBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9LFxuICBhZGRFdmVudCgpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfSxcbiAgYWRkTGluaygpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfSxcbiAgYWRkTGlua3MoKSB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG4gIHNldFN0YXR1cygpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfSxcbiAgdXBkYXRlTmFtZSgpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfSxcbiAgZW5kKCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9LFxuICBpc1JlY29yZGluZygpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH0sXG4gIHJlY29yZEV4Y2VwdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfSxcbn07XG5cbmNvbnN0IG5vb3BTcGFuQ29udGV4dDogU3BhbkNvbnRleHQgPSB7XG4gIHRyYWNlSWQ6ICcnLFxuICBzcGFuSWQ6ICcnLFxuICB0cmFjZUZsYWdzOiAwLFxufTtcbiIsICJpbXBvcnQgeyBBdHRyaWJ1dGVzLCBTcGFuLCBUcmFjZXIsIFNwYW5TdGF0dXNDb2RlIH0gZnJvbSAnQG9wZW50ZWxlbWV0cnkvYXBpJztcblxuZXhwb3J0IGZ1bmN0aW9uIHJlY29yZFNwYW48VD4oe1xuICBuYW1lLFxuICB0cmFjZXIsXG4gIGF0dHJpYnV0ZXMsXG4gIGZuLFxuICBlbmRXaGVuRG9uZSA9IHRydWUsXG59OiB7XG4gIG5hbWU6IHN0cmluZztcbiAgdHJhY2VyOiBUcmFjZXI7XG4gIGF0dHJpYnV0ZXM6IEF0dHJpYnV0ZXM7XG4gIGZuOiAoc3BhbjogU3BhbikgPT4gUHJvbWlzZTxUPjtcbiAgZW5kV2hlbkRvbmU/OiBib29sZWFuO1xufSkge1xuICByZXR1cm4gdHJhY2VyLnN0YXJ0QWN0aXZlU3BhbihuYW1lLCB7IGF0dHJpYnV0ZXMgfSwgYXN5bmMgc3BhbiA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGZuKHNwYW4pO1xuXG4gICAgICBpZiAoZW5kV2hlbkRvbmUpIHtcbiAgICAgICAgc3Bhbi5lbmQoKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmVjb3JkRXJyb3JPblNwYW4oc3BhbiwgZXJyb3IpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgLy8gYWx3YXlzIHN0b3AgdGhlIHNwYW4gd2hlbiB0aGVyZSBpcyBhbiBlcnJvcjpcbiAgICAgICAgc3Bhbi5lbmQoKTtcbiAgICAgIH1cblxuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9KTtcbn1cblxuLyoqXG4gKiBSZWNvcmQgYW4gZXJyb3Igb24gYSBzcGFuLiBJZiB0aGUgZXJyb3IgaXMgYW4gaW5zdGFuY2Ugb2YgRXJyb3IsIGFuIGV4Y2VwdGlvbiBldmVudCB3aWxsIGJlIHJlY29yZGVkIG9uIHRoZSBzcGFuLCBvdGhlcndpc2VcbiAqIHRoZSBzcGFuIHdpbGwgYmUgc2V0IHRvIGFuIGVycm9yIHN0YXR1cy5cbiAqXG4gKiBAcGFyYW0gc3BhbiAtIFRoZSBzcGFuIHRvIHJlY29yZCB0aGUgZXJyb3Igb24uXG4gKiBAcGFyYW0gZXJyb3IgLSBUaGUgZXJyb3IgdG8gcmVjb3JkIG9uIHRoZSBzcGFuLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVjb3JkRXJyb3JPblNwYW4oc3BhbjogU3BhbiwgZXJyb3I6IHVua25vd24pIHtcbiAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICBzcGFuLnJlY29yZEV4Y2VwdGlvbih7XG4gICAgICBuYW1lOiBlcnJvci5uYW1lLFxuICAgICAgbWVzc2FnZTogZXJyb3IubWVzc2FnZSxcbiAgICAgIHN0YWNrOiBlcnJvci5zdGFjayxcbiAgICB9KTtcbiAgICBzcGFuLnNldFN0YXR1cyh7XG4gICAgICBjb2RlOiBTcGFuU3RhdHVzQ29kZS5FUlJPUixcbiAgICAgIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UsXG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgc3Bhbi5zZXRTdGF0dXMoeyBjb2RlOiBTcGFuU3RhdHVzQ29kZS5FUlJPUiB9KTtcbiAgfVxufVxuIiwgImltcG9ydCB0eXBlIHsgQXR0cmlidXRlcywgQXR0cmlidXRlVmFsdWUgfSBmcm9tICdAb3BlbnRlbGVtZXRyeS9hcGknO1xuaW1wb3J0IHR5cGUgeyBUZWxlbWV0cnlTZXR0aW5ncyB9IGZyb20gJy4vdGVsZW1ldHJ5LXNldHRpbmdzJztcblxuZXhwb3J0IGZ1bmN0aW9uIHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICB0ZWxlbWV0cnksXG4gIGF0dHJpYnV0ZXMsXG59OiB7XG4gIHRlbGVtZXRyeT86IFRlbGVtZXRyeVNldHRpbmdzO1xuICBhdHRyaWJ1dGVzOiB7XG4gICAgW2F0dHJpYnV0ZUtleTogc3RyaW5nXTpcbiAgICAgIHwgQXR0cmlidXRlVmFsdWVcbiAgICAgIHwgeyBpbnB1dDogKCkgPT4gQXR0cmlidXRlVmFsdWUgfCB1bmRlZmluZWQgfVxuICAgICAgfCB7IG91dHB1dDogKCkgPT4gQXR0cmlidXRlVmFsdWUgfCB1bmRlZmluZWQgfVxuICAgICAgfCB1bmRlZmluZWQ7XG4gIH07XG59KTogQXR0cmlidXRlcyB7XG4gIC8vIHdoZW4gdGVsZW1ldHJ5IGlzIGRpc2FibGVkLCByZXR1cm4gYW4gZW1wdHkgb2JqZWN0IHRvIGF2b2lkIHNlcmlhbGl6YXRpb24gb3ZlcmhlYWQ6XG4gIGlmICh0ZWxlbWV0cnk/LmlzRW5hYmxlZCAhPT0gdHJ1ZSkge1xuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIHJldHVybiBPYmplY3QuZW50cmllcyhhdHRyaWJ1dGVzKS5yZWR1Y2UoKGF0dHJpYnV0ZXMsIFtrZXksIHZhbHVlXSkgPT4ge1xuICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgICByZXR1cm4gYXR0cmlidXRlcztcbiAgICB9XG5cbiAgICAvLyBpbnB1dCB2YWx1ZSwgY2hlY2sgaWYgaXQgc2hvdWxkIGJlIHJlY29yZGVkOlxuICAgIGlmIChcbiAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiZcbiAgICAgICdpbnB1dCcgaW4gdmFsdWUgJiZcbiAgICAgIHR5cGVvZiB2YWx1ZS5pbnB1dCA9PT0gJ2Z1bmN0aW9uJ1xuICAgICkge1xuICAgICAgLy8gZGVmYXVsdCB0byB0cnVlOlxuICAgICAgaWYgKHRlbGVtZXRyeT8ucmVjb3JkSW5wdXRzID09PSBmYWxzZSkge1xuICAgICAgICByZXR1cm4gYXR0cmlidXRlcztcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVzdWx0ID0gdmFsdWUuaW5wdXQoKTtcblxuICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gYXR0cmlidXRlcyA6IHsgLi4uYXR0cmlidXRlcywgW2tleV06IHJlc3VsdCB9O1xuICAgIH1cblxuICAgIC8vIG91dHB1dCB2YWx1ZSwgY2hlY2sgaWYgaXQgc2hvdWxkIGJlIHJlY29yZGVkOlxuICAgIGlmIChcbiAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiZcbiAgICAgICdvdXRwdXQnIGluIHZhbHVlICYmXG4gICAgICB0eXBlb2YgdmFsdWUub3V0cHV0ID09PSAnZnVuY3Rpb24nXG4gICAgKSB7XG4gICAgICAvLyBkZWZhdWx0IHRvIHRydWU6XG4gICAgICBpZiAodGVsZW1ldHJ5Py5yZWNvcmRPdXRwdXRzID09PSBmYWxzZSkge1xuICAgICAgICByZXR1cm4gYXR0cmlidXRlcztcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVzdWx0ID0gdmFsdWUub3V0cHV0KCk7XG5cbiAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IGF0dHJpYnV0ZXMgOiB7IC4uLmF0dHJpYnV0ZXMsIFtrZXldOiByZXN1bHQgfTtcbiAgICB9XG5cbiAgICAvLyB2YWx1ZSBpcyBhbiBhdHRyaWJ1dGUgdmFsdWUgYWxyZWFkeTpcbiAgICByZXR1cm4geyAuLi5hdHRyaWJ1dGVzLCBba2V5XTogdmFsdWUgfTtcbiAgfSwge30pO1xufVxuIiwgImltcG9ydCB7XG4gIExhbmd1YWdlTW9kZWxWMk1lc3NhZ2UsXG4gIExhbmd1YWdlTW9kZWxWMlByb21wdCxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQgeyBjb252ZXJ0RGF0YUNvbnRlbnRUb0Jhc2U2NFN0cmluZyB9IGZyb20gJy4uL3Byb21wdC9kYXRhLWNvbnRlbnQnO1xuXG4vKipcbiAqIEhlbHBlciB1dGlsaXR5IHRvIHNlcmlhbGl6ZSBwcm9tcHQgY29udGVudCBmb3IgT3BlblRlbGVtZXRyeSB0cmFjaW5nLlxuICogSXQgaXMgaW5pdGlhbGx5IGNyZWF0ZWQgYmVjYXVzZSBub3JtYWxpemVkIExhbmd1YWdlTW9kZWxWMVByb21wdCBjYXJyaWVzXG4gKiBpbWFnZXMgYXMgVWludDhBcnJheXMsIG9uIHdoaWNoIEpTT04uc3RyaW5naWZ5IGFjdHMgd2VpcmRseSwgY29udmVydGluZ1xuICogdGhlbSB0byBvYmplY3RzIHdpdGggc3RyaW5naWZpZWQgaW5kaWNlcyBhcyBrZXlzLCBlLmcuIHtcIjBcIjogNDIsIFwiMVwiOiA2OSB9LlxuICovXG5leHBvcnQgZnVuY3Rpb24gc3RyaW5naWZ5Rm9yVGVsZW1ldHJ5KHByb21wdDogTGFuZ3VhZ2VNb2RlbFYyUHJvbXB0KTogc3RyaW5nIHtcbiAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KFxuICAgIHByb21wdC5tYXAoKG1lc3NhZ2U6IExhbmd1YWdlTW9kZWxWMk1lc3NhZ2UpID0+ICh7XG4gICAgICAuLi5tZXNzYWdlLFxuICAgICAgY29udGVudDpcbiAgICAgICAgdHlwZW9mIG1lc3NhZ2UuY29udGVudCA9PT0gJ3N0cmluZydcbiAgICAgICAgICA/IG1lc3NhZ2UuY29udGVudFxuICAgICAgICAgIDogbWVzc2FnZS5jb250ZW50Lm1hcChwYXJ0ID0+XG4gICAgICAgICAgICAgIHBhcnQudHlwZSA9PT0gJ2ZpbGUnXG4gICAgICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgICAgIC4uLnBhcnQsXG4gICAgICAgICAgICAgICAgICAgIGRhdGE6XG4gICAgICAgICAgICAgICAgICAgICAgcGFydC5kYXRhIGluc3RhbmNlb2YgVWludDhBcnJheVxuICAgICAgICAgICAgICAgICAgICAgICAgPyBjb252ZXJ0RGF0YUNvbnRlbnRUb0Jhc2U2NFN0cmluZyhwYXJ0LmRhdGEpXG4gICAgICAgICAgICAgICAgICAgICAgICA6IHBhcnQuZGF0YSxcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA6IHBhcnQsXG4gICAgICAgICAgICApLFxuICAgIH0pKSxcbiAgKTtcbn1cbiIsICJpbXBvcnQgeyBMYW5ndWFnZU1vZGVsVjJVc2FnZSB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuXG4vKipcblJlcHJlc2VudHMgdGhlIG51bWJlciBvZiB0b2tlbnMgdXNlZCBpbiBhIHByb21wdCBhbmQgY29tcGxldGlvbi5cbiAqL1xuZXhwb3J0IHR5cGUgTGFuZ3VhZ2VNb2RlbFVzYWdlID0gTGFuZ3VhZ2VNb2RlbFYyVXNhZ2U7XG5cbi8qKlxuUmVwcmVzZW50cyB0aGUgbnVtYmVyIG9mIHRva2VucyB1c2VkIGluIGFuIGVtYmVkZGluZy5cbiAqL1xuLy8gVE9ETyByZXBsYWNlIHdpdGggRW1iZWRkaW5nTW9kZWxWMlVzYWdlXG5leHBvcnQgdHlwZSBFbWJlZGRpbmdNb2RlbFVzYWdlID0ge1xuICAvKipcblRoZSBudW1iZXIgb2YgdG9rZW5zIHVzZWQgaW4gdGhlIGVtYmVkZGluZy5cbiAgICovXG4gIHRva2VuczogbnVtYmVyO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGFkZExhbmd1YWdlTW9kZWxVc2FnZShcbiAgdXNhZ2UxOiBMYW5ndWFnZU1vZGVsVXNhZ2UsXG4gIHVzYWdlMjogTGFuZ3VhZ2VNb2RlbFVzYWdlLFxuKTogTGFuZ3VhZ2VNb2RlbFVzYWdlIHtcbiAgcmV0dXJuIHtcbiAgICBpbnB1dFRva2VuczogYWRkVG9rZW5Db3VudHModXNhZ2UxLmlucHV0VG9rZW5zLCB1c2FnZTIuaW5wdXRUb2tlbnMpLFxuICAgIG91dHB1dFRva2VuczogYWRkVG9rZW5Db3VudHModXNhZ2UxLm91dHB1dFRva2VucywgdXNhZ2UyLm91dHB1dFRva2VucyksXG4gICAgdG90YWxUb2tlbnM6IGFkZFRva2VuQ291bnRzKHVzYWdlMS50b3RhbFRva2VucywgdXNhZ2UyLnRvdGFsVG9rZW5zKSxcbiAgICByZWFzb25pbmdUb2tlbnM6IGFkZFRva2VuQ291bnRzKFxuICAgICAgdXNhZ2UxLnJlYXNvbmluZ1Rva2VucyxcbiAgICAgIHVzYWdlMi5yZWFzb25pbmdUb2tlbnMsXG4gICAgKSxcbiAgICBjYWNoZWRJbnB1dFRva2VuczogYWRkVG9rZW5Db3VudHMoXG4gICAgICB1c2FnZTEuY2FjaGVkSW5wdXRUb2tlbnMsXG4gICAgICB1c2FnZTIuY2FjaGVkSW5wdXRUb2tlbnMsXG4gICAgKSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gYWRkVG9rZW5Db3VudHMoXG4gIHRva2VuQ291bnQxOiBudW1iZXIgfCB1bmRlZmluZWQsXG4gIHRva2VuQ291bnQyOiBudW1iZXIgfCB1bmRlZmluZWQsXG4pOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICByZXR1cm4gdG9rZW5Db3VudDEgPT0gbnVsbCAmJiB0b2tlbkNvdW50MiA9PSBudWxsXG4gICAgPyB1bmRlZmluZWRcbiAgICA6ICh0b2tlbkNvdW50MSA/PyAwKSArICh0b2tlbkNvdW50MiA/PyAwKTtcbn1cbiIsICJleHBvcnQgZnVuY3Rpb24gYXNBcnJheTxUPih2YWx1ZTogVCB8IFRbXSB8IHVuZGVmaW5lZCk6IFRbXSB7XG4gIHJldHVybiB2YWx1ZSA9PT0gdW5kZWZpbmVkID8gW10gOiBBcnJheS5pc0FycmF5KHZhbHVlKSA/IHZhbHVlIDogW3ZhbHVlXTtcbn1cbiIsICJpbXBvcnQgeyBBUElDYWxsRXJyb3IgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcbmltcG9ydCB7IGRlbGF5LCBnZXRFcnJvck1lc3NhZ2UsIGlzQWJvcnRFcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXItdXRpbHMnO1xuaW1wb3J0IHsgUmV0cnlFcnJvciB9IGZyb20gJy4vcmV0cnktZXJyb3InO1xuXG5leHBvcnQgdHlwZSBSZXRyeUZ1bmN0aW9uID0gPE9VVFBVVD4oXG4gIGZuOiAoKSA9PiBQcm9taXNlTGlrZTxPVVRQVVQ+LFxuKSA9PiBQcm9taXNlTGlrZTxPVVRQVVQ+O1xuXG5mdW5jdGlvbiBnZXRSZXRyeURlbGF5SW5Ncyh7XG4gIGVycm9yLFxuICBleHBvbmVudGlhbEJhY2tvZmZEZWxheSxcbn06IHtcbiAgZXJyb3I6IEFQSUNhbGxFcnJvcjtcbiAgZXhwb25lbnRpYWxCYWNrb2ZmRGVsYXk6IG51bWJlcjtcbn0pOiBudW1iZXIge1xuICBjb25zdCBoZWFkZXJzID0gZXJyb3IucmVzcG9uc2VIZWFkZXJzO1xuXG4gIGlmICghaGVhZGVycykgcmV0dXJuIGV4cG9uZW50aWFsQmFja29mZkRlbGF5O1xuXG4gIGxldCBtczogbnVtYmVyIHwgdW5kZWZpbmVkO1xuXG4gIC8vIHJldHJ5LW1zIGlzIG1vcmUgcHJlY2lzZSB0aGFuIHJldHJ5LWFmdGVyIGFuZCB1c2VkIGJ5IGUuZy4gT3BlbkFJXG4gIGNvbnN0IHJldHJ5QWZ0ZXJNcyA9IGhlYWRlcnNbJ3JldHJ5LWFmdGVyLW1zJ107XG4gIGlmIChyZXRyeUFmdGVyTXMpIHtcbiAgICBjb25zdCB0aW1lb3V0TXMgPSBwYXJzZUZsb2F0KHJldHJ5QWZ0ZXJNcyk7XG4gICAgaWYgKCFOdW1iZXIuaXNOYU4odGltZW91dE1zKSkge1xuICAgICAgbXMgPSB0aW1lb3V0TXM7XG4gICAgfVxuICB9XG5cbiAgLy8gQWJvdXQgdGhlIFJldHJ5LUFmdGVyIGhlYWRlcjogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRUUC9IZWFkZXJzL1JldHJ5LUFmdGVyXG4gIGNvbnN0IHJldHJ5QWZ0ZXIgPSBoZWFkZXJzWydyZXRyeS1hZnRlciddO1xuICBpZiAocmV0cnlBZnRlciAmJiBtcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgY29uc3QgdGltZW91dFNlY29uZHMgPSBwYXJzZUZsb2F0KHJldHJ5QWZ0ZXIpO1xuICAgIGlmICghTnVtYmVyLmlzTmFOKHRpbWVvdXRTZWNvbmRzKSkge1xuICAgICAgbXMgPSB0aW1lb3V0U2Vjb25kcyAqIDEwMDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIG1zID0gRGF0ZS5wYXJzZShyZXRyeUFmdGVyKSAtIERhdGUubm93KCk7XG4gICAgfVxuICB9XG5cbiAgLy8gY2hlY2sgdGhhdCB0aGUgZGVsYXkgaXMgcmVhc29uYWJsZTpcbiAgaWYgKFxuICAgIG1zICE9IG51bGwgJiZcbiAgICAhTnVtYmVyLmlzTmFOKG1zKSAmJlxuICAgIDAgPD0gbXMgJiZcbiAgICAobXMgPCA2MCAqIDEwMDAgfHwgbXMgPCBleHBvbmVudGlhbEJhY2tvZmZEZWxheSlcbiAgKSB7XG4gICAgcmV0dXJuIG1zO1xuICB9XG5cbiAgcmV0dXJuIGV4cG9uZW50aWFsQmFja29mZkRlbGF5O1xufVxuXG4vKipcblRoZSBgcmV0cnlXaXRoRXhwb25lbnRpYWxCYWNrb2ZmUmVzcGVjdGluZ1JldHJ5SGVhZGVyc2Agc3RyYXRlZ3kgcmV0cmllcyBhIGZhaWxlZCBBUEkgY2FsbCB3aXRoIGFuIGV4cG9uZW50aWFsIGJhY2tvZmYsXG53aGlsZSByZXNwZWN0aW5nIHJhdGUgbGltaXQgaGVhZGVycyAocmV0cnktYWZ0ZXItbXMgYW5kIHJldHJ5LWFmdGVyKSBpZiB0aGV5IGFyZSBwcm92aWRlZCBhbmQgcmVhc29uYWJsZSAoMC02MCBzZWNvbmRzKS5cbllvdSBjYW4gY29uZmlndXJlIHRoZSBtYXhpbXVtIG51bWJlciBvZiByZXRyaWVzLCB0aGUgaW5pdGlhbCBkZWxheSwgYW5kIHRoZSBiYWNrb2ZmIGZhY3Rvci5cbiAqL1xuZXhwb3J0IGNvbnN0IHJldHJ5V2l0aEV4cG9uZW50aWFsQmFja29mZlJlc3BlY3RpbmdSZXRyeUhlYWRlcnMgPVxuICAoe1xuICAgIG1heFJldHJpZXMgPSAyLFxuICAgIGluaXRpYWxEZWxheUluTXMgPSAyMDAwLFxuICAgIGJhY2tvZmZGYWN0b3IgPSAyLFxuICAgIGFib3J0U2lnbmFsLFxuICB9OiB7XG4gICAgbWF4UmV0cmllcz86IG51bWJlcjtcbiAgICBpbml0aWFsRGVsYXlJbk1zPzogbnVtYmVyO1xuICAgIGJhY2tvZmZGYWN0b3I/OiBudW1iZXI7XG4gICAgYWJvcnRTaWduYWw/OiBBYm9ydFNpZ25hbDtcbiAgfSA9IHt9KTogUmV0cnlGdW5jdGlvbiA9PlxuICBhc3luYyA8T1VUUFVUPihmOiAoKSA9PiBQcm9taXNlTGlrZTxPVVRQVVQ+KSA9PlxuICAgIF9yZXRyeVdpdGhFeHBvbmVudGlhbEJhY2tvZmYoZiwge1xuICAgICAgbWF4UmV0cmllcyxcbiAgICAgIGRlbGF5SW5NczogaW5pdGlhbERlbGF5SW5NcyxcbiAgICAgIGJhY2tvZmZGYWN0b3IsXG4gICAgICBhYm9ydFNpZ25hbCxcbiAgICB9KTtcblxuYXN5bmMgZnVuY3Rpb24gX3JldHJ5V2l0aEV4cG9uZW50aWFsQmFja29mZjxPVVRQVVQ+KFxuICBmOiAoKSA9PiBQcm9taXNlTGlrZTxPVVRQVVQ+LFxuICB7XG4gICAgbWF4UmV0cmllcyxcbiAgICBkZWxheUluTXMsXG4gICAgYmFja29mZkZhY3RvcixcbiAgICBhYm9ydFNpZ25hbCxcbiAgfToge1xuICAgIG1heFJldHJpZXM6IG51bWJlcjtcbiAgICBkZWxheUluTXM6IG51bWJlcjtcbiAgICBiYWNrb2ZmRmFjdG9yOiBudW1iZXI7XG4gICAgYWJvcnRTaWduYWw6IEFib3J0U2lnbmFsIHwgdW5kZWZpbmVkO1xuICB9LFxuICBlcnJvcnM6IHVua25vd25bXSA9IFtdLFxuKTogUHJvbWlzZTxPVVRQVVQ+IHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gYXdhaXQgZigpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmIChpc0Fib3J0RXJyb3IoZXJyb3IpKSB7XG4gICAgICB0aHJvdyBlcnJvcjsgLy8gZG9uJ3QgcmV0cnkgd2hlbiB0aGUgcmVxdWVzdCB3YXMgYWJvcnRlZFxuICAgIH1cblxuICAgIGlmIChtYXhSZXRyaWVzID09PSAwKSB7XG4gICAgICB0aHJvdyBlcnJvcjsgLy8gZG9uJ3Qgd3JhcCB0aGUgZXJyb3Igd2hlbiByZXRyaWVzIGFyZSBkaXNhYmxlZFxuICAgIH1cblxuICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGdldEVycm9yTWVzc2FnZShlcnJvcik7XG4gICAgY29uc3QgbmV3RXJyb3JzID0gWy4uLmVycm9ycywgZXJyb3JdO1xuICAgIGNvbnN0IHRyeU51bWJlciA9IG5ld0Vycm9ycy5sZW5ndGg7XG5cbiAgICBpZiAodHJ5TnVtYmVyID4gbWF4UmV0cmllcykge1xuICAgICAgdGhyb3cgbmV3IFJldHJ5RXJyb3Ioe1xuICAgICAgICBtZXNzYWdlOiBgRmFpbGVkIGFmdGVyICR7dHJ5TnVtYmVyfSBhdHRlbXB0cy4gTGFzdCBlcnJvcjogJHtlcnJvck1lc3NhZ2V9YCxcbiAgICAgICAgcmVhc29uOiAnbWF4UmV0cmllc0V4Y2VlZGVkJyxcbiAgICAgICAgZXJyb3JzOiBuZXdFcnJvcnMsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICBlcnJvciBpbnN0YW5jZW9mIEVycm9yICYmXG4gICAgICBBUElDYWxsRXJyb3IuaXNJbnN0YW5jZShlcnJvcikgJiZcbiAgICAgIGVycm9yLmlzUmV0cnlhYmxlID09PSB0cnVlICYmXG4gICAgICB0cnlOdW1iZXIgPD0gbWF4UmV0cmllc1xuICAgICkge1xuICAgICAgYXdhaXQgZGVsYXkoXG4gICAgICAgIGdldFJldHJ5RGVsYXlJbk1zKHtcbiAgICAgICAgICBlcnJvcixcbiAgICAgICAgICBleHBvbmVudGlhbEJhY2tvZmZEZWxheTogZGVsYXlJbk1zLFxuICAgICAgICB9KSxcbiAgICAgICAgeyBhYm9ydFNpZ25hbCB9LFxuICAgICAgKTtcblxuICAgICAgcmV0dXJuIF9yZXRyeVdpdGhFeHBvbmVudGlhbEJhY2tvZmYoXG4gICAgICAgIGYsXG4gICAgICAgIHtcbiAgICAgICAgICBtYXhSZXRyaWVzLFxuICAgICAgICAgIGRlbGF5SW5NczogYmFja29mZkZhY3RvciAqIGRlbGF5SW5NcyxcbiAgICAgICAgICBiYWNrb2ZmRmFjdG9yLFxuICAgICAgICAgIGFib3J0U2lnbmFsLFxuICAgICAgICB9LFxuICAgICAgICBuZXdFcnJvcnMsXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICh0cnlOdW1iZXIgPT09IDEpIHtcbiAgICAgIHRocm93IGVycm9yOyAvLyBkb24ndCB3cmFwIHRoZSBlcnJvciB3aGVuIGEgbm9uLXJldHJ5YWJsZSBlcnJvciBvY2N1cnMgb24gdGhlIGZpcnN0IHRyeVxuICAgIH1cblxuICAgIHRocm93IG5ldyBSZXRyeUVycm9yKHtcbiAgICAgIG1lc3NhZ2U6IGBGYWlsZWQgYWZ0ZXIgJHt0cnlOdW1iZXJ9IGF0dGVtcHRzIHdpdGggbm9uLXJldHJ5YWJsZSBlcnJvcjogJyR7ZXJyb3JNZXNzYWdlfSdgLFxuICAgICAgcmVhc29uOiAnZXJyb3JOb3RSZXRyeWFibGUnLFxuICAgICAgZXJyb3JzOiBuZXdFcnJvcnMsXG4gICAgfSk7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBJbnZhbGlkQXJndW1lbnRFcnJvciB9IGZyb20gJy4uL2Vycm9yL2ludmFsaWQtYXJndW1lbnQtZXJyb3InO1xuaW1wb3J0IHtcbiAgUmV0cnlGdW5jdGlvbixcbiAgcmV0cnlXaXRoRXhwb25lbnRpYWxCYWNrb2ZmUmVzcGVjdGluZ1JldHJ5SGVhZGVycyxcbn0gZnJvbSAnLi4vdXRpbC9yZXRyeS13aXRoLWV4cG9uZW50aWFsLWJhY2tvZmYnO1xuXG4vKipcbiAqIFZhbGlkYXRlIGFuZCBwcmVwYXJlIHJldHJpZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcmVwYXJlUmV0cmllcyh7XG4gIG1heFJldHJpZXMsXG4gIGFib3J0U2lnbmFsLFxufToge1xuICBtYXhSZXRyaWVzOiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gIGFib3J0U2lnbmFsOiBBYm9ydFNpZ25hbCB8IHVuZGVmaW5lZDtcbn0pOiB7XG4gIG1heFJldHJpZXM6IG51bWJlcjtcbiAgcmV0cnk6IFJldHJ5RnVuY3Rpb247XG59IHtcbiAgaWYgKG1heFJldHJpZXMgIT0gbnVsbCkge1xuICAgIGlmICghTnVtYmVyLmlzSW50ZWdlcihtYXhSZXRyaWVzKSkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEVycm9yKHtcbiAgICAgICAgcGFyYW1ldGVyOiAnbWF4UmV0cmllcycsXG4gICAgICAgIHZhbHVlOiBtYXhSZXRyaWVzLFxuICAgICAgICBtZXNzYWdlOiAnbWF4UmV0cmllcyBtdXN0IGJlIGFuIGludGVnZXInLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKG1heFJldHJpZXMgPCAwKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3Ioe1xuICAgICAgICBwYXJhbWV0ZXI6ICdtYXhSZXRyaWVzJyxcbiAgICAgICAgdmFsdWU6IG1heFJldHJpZXMsXG4gICAgICAgIG1lc3NhZ2U6ICdtYXhSZXRyaWVzIG11c3QgYmUgPj0gMCcsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBtYXhSZXRyaWVzUmVzdWx0ID0gbWF4UmV0cmllcyA/PyAyO1xuXG4gIHJldHVybiB7XG4gICAgbWF4UmV0cmllczogbWF4UmV0cmllc1Jlc3VsdCxcbiAgICByZXRyeTogcmV0cnlXaXRoRXhwb25lbnRpYWxCYWNrb2ZmUmVzcGVjdGluZ1JldHJ5SGVhZGVycyh7XG4gICAgICBtYXhSZXRyaWVzOiBtYXhSZXRyaWVzUmVzdWx0LFxuICAgICAgYWJvcnRTaWduYWwsXG4gICAgfSksXG4gIH07XG59XG4iLCAiaW1wb3J0IHsgTGFuZ3VhZ2VNb2RlbFYyQ29udGVudCwgTGFuZ3VhZ2VNb2RlbFYyVGV4dCB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdFRleHRDb250ZW50KFxuICBjb250ZW50OiBMYW5ndWFnZU1vZGVsVjJDb250ZW50W10sXG4pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCBwYXJ0cyA9IGNvbnRlbnQuZmlsdGVyKFxuICAgIChjb250ZW50KTogY29udGVudCBpcyBMYW5ndWFnZU1vZGVsVjJUZXh0ID0+IGNvbnRlbnQudHlwZSA9PT0gJ3RleHQnLFxuICApO1xuXG4gIGlmIChwYXJ0cy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgcmV0dXJuIHBhcnRzLm1hcChjb250ZW50ID0+IGNvbnRlbnQudGV4dCkuam9pbignJyk7XG59XG4iLCAiaW1wb3J0IHtcbiAgY29udmVydEJhc2U2NFRvVWludDhBcnJheSxcbiAgY29udmVydFVpbnQ4QXJyYXlUb0Jhc2U2NCxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5cbi8qKlxuICogQSBnZW5lcmF0ZWQgZmlsZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBHZW5lcmF0ZWRGaWxlIHtcbiAgLyoqXG5GaWxlIGFzIGEgYmFzZTY0IGVuY29kZWQgc3RyaW5nLlxuICAgICAqL1xuICByZWFkb25seSBiYXNlNjQ6IHN0cmluZztcblxuICAvKipcbkZpbGUgYXMgYSBVaW50OEFycmF5LlxuICAgICAqL1xuICByZWFkb25seSB1aW50OEFycmF5OiBVaW50OEFycmF5O1xuXG4gIC8qKlxuVGhlIElBTkEgbWVkaWEgdHlwZSBvZiB0aGUgZmlsZS5cblxuQHNlZSBodHRwczovL3d3dy5pYW5hLm9yZy9hc3NpZ25tZW50cy9tZWRpYS10eXBlcy9tZWRpYS10eXBlcy54aHRtbFxuICAgKi9cbiAgcmVhZG9ubHkgbWVkaWFUeXBlOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBEZWZhdWx0R2VuZXJhdGVkRmlsZSBpbXBsZW1lbnRzIEdlbmVyYXRlZEZpbGUge1xuICBwcml2YXRlIGJhc2U2NERhdGE6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSB1aW50OEFycmF5RGF0YTogVWludDhBcnJheSB8IHVuZGVmaW5lZDtcblxuICByZWFkb25seSBtZWRpYVR5cGU6IHN0cmluZztcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgZGF0YSxcbiAgICBtZWRpYVR5cGUsXG4gIH06IHtcbiAgICBkYXRhOiBzdHJpbmcgfCBVaW50OEFycmF5O1xuICAgIG1lZGlhVHlwZTogc3RyaW5nO1xuICB9KSB7XG4gICAgY29uc3QgaXNVaW50OEFycmF5ID0gZGF0YSBpbnN0YW5jZW9mIFVpbnQ4QXJyYXk7XG4gICAgdGhpcy5iYXNlNjREYXRhID0gaXNVaW50OEFycmF5ID8gdW5kZWZpbmVkIDogZGF0YTtcbiAgICB0aGlzLnVpbnQ4QXJyYXlEYXRhID0gaXNVaW50OEFycmF5ID8gZGF0YSA6IHVuZGVmaW5lZDtcbiAgICB0aGlzLm1lZGlhVHlwZSA9IG1lZGlhVHlwZTtcbiAgfVxuXG4gIC8vIGxhenkgY29udmVyc2lvbiB3aXRoIGNhY2hpbmcgdG8gYXZvaWQgdW5uZWNlc3NhcnkgY29udmVyc2lvbiBvdmVyaGVhZDpcbiAgZ2V0IGJhc2U2NCgpIHtcbiAgICBpZiAodGhpcy5iYXNlNjREYXRhID09IG51bGwpIHtcbiAgICAgIHRoaXMuYmFzZTY0RGF0YSA9IGNvbnZlcnRVaW50OEFycmF5VG9CYXNlNjQodGhpcy51aW50OEFycmF5RGF0YSEpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5iYXNlNjREYXRhO1xuICB9XG5cbiAgLy8gbGF6eSBjb252ZXJzaW9uIHdpdGggY2FjaGluZyB0byBhdm9pZCB1bm5lY2Vzc2FyeSBjb252ZXJzaW9uIG92ZXJoZWFkOlxuICBnZXQgdWludDhBcnJheSgpIHtcbiAgICBpZiAodGhpcy51aW50OEFycmF5RGF0YSA9PSBudWxsKSB7XG4gICAgICB0aGlzLnVpbnQ4QXJyYXlEYXRhID0gY29udmVydEJhc2U2NFRvVWludDhBcnJheSh0aGlzLmJhc2U2NERhdGEhKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudWludDhBcnJheURhdGE7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIERlZmF1bHRHZW5lcmF0ZWRGaWxlV2l0aFR5cGUgZXh0ZW5kcyBEZWZhdWx0R2VuZXJhdGVkRmlsZSB7XG4gIHJlYWRvbmx5IHR5cGUgPSAnZmlsZSc7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczogeyBkYXRhOiBzdHJpbmcgfCBVaW50OEFycmF5OyBtZWRpYVR5cGU6IHN0cmluZyB9KSB7XG4gICAgc3VwZXIob3B0aW9ucyk7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBMYW5ndWFnZU1vZGVsVjJUb29sQ2FsbCB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHtcbiAgYXNTY2hlbWEsXG4gIE1vZGVsTWVzc2FnZSxcbiAgc2FmZVBhcnNlSlNPTixcbiAgc2FmZVZhbGlkYXRlVHlwZXMsXG59IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXItdXRpbHMnO1xuaW1wb3J0IHsgSW52YWxpZFRvb2xJbnB1dEVycm9yIH0gZnJvbSAnLi4vZXJyb3IvaW52YWxpZC10b29sLWlucHV0LWVycm9yJztcbmltcG9ydCB7IE5vU3VjaFRvb2xFcnJvciB9IGZyb20gJy4uL2Vycm9yL25vLXN1Y2gtdG9vbC1lcnJvcic7XG5pbXBvcnQgeyBUb29sQ2FsbFJlcGFpckVycm9yIH0gZnJvbSAnLi4vZXJyb3IvdG9vbC1jYWxsLXJlcGFpci1lcnJvcic7XG5pbXBvcnQgeyBUeXBlZFRvb2xDYWxsIH0gZnJvbSAnLi90b29sLWNhbGwnO1xuaW1wb3J0IHsgVG9vbENhbGxSZXBhaXJGdW5jdGlvbiB9IGZyb20gJy4vdG9vbC1jYWxsLXJlcGFpci1mdW5jdGlvbic7XG5pbXBvcnQgeyBUb29sU2V0IH0gZnJvbSAnLi90b29sLXNldCc7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwYXJzZVRvb2xDYWxsPFRPT0xTIGV4dGVuZHMgVG9vbFNldD4oe1xuICB0b29sQ2FsbCxcbiAgdG9vbHMsXG4gIHJlcGFpclRvb2xDYWxsLFxuICBzeXN0ZW0sXG4gIG1lc3NhZ2VzLFxufToge1xuICB0b29sQ2FsbDogTGFuZ3VhZ2VNb2RlbFYyVG9vbENhbGw7XG4gIHRvb2xzOiBUT09MUyB8IHVuZGVmaW5lZDtcbiAgcmVwYWlyVG9vbENhbGw6IFRvb2xDYWxsUmVwYWlyRnVuY3Rpb248VE9PTFM+IHwgdW5kZWZpbmVkO1xuICBzeXN0ZW06IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgbWVzc2FnZXM6IE1vZGVsTWVzc2FnZVtdO1xufSk6IFByb21pc2U8VHlwZWRUb29sQ2FsbDxUT09MUz4+IHtcbiAgdHJ5IHtcbiAgICBpZiAodG9vbHMgPT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IE5vU3VjaFRvb2xFcnJvcih7IHRvb2xOYW1lOiB0b29sQ2FsbC50b29sTmFtZSB9KTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IGRvUGFyc2VUb29sQ2FsbCh7IHRvb2xDYWxsLCB0b29scyB9KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKFxuICAgICAgICByZXBhaXJUb29sQ2FsbCA9PSBudWxsIHx8XG4gICAgICAgICEoXG4gICAgICAgICAgTm9TdWNoVG9vbEVycm9yLmlzSW5zdGFuY2UoZXJyb3IpIHx8XG4gICAgICAgICAgSW52YWxpZFRvb2xJbnB1dEVycm9yLmlzSW5zdGFuY2UoZXJyb3IpXG4gICAgICAgIClcbiAgICAgICkge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cblxuICAgICAgbGV0IHJlcGFpcmVkVG9vbENhbGw6IExhbmd1YWdlTW9kZWxWMlRvb2xDYWxsIHwgbnVsbCA9IG51bGw7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJlcGFpcmVkVG9vbENhbGwgPSBhd2FpdCByZXBhaXJUb29sQ2FsbCh7XG4gICAgICAgICAgdG9vbENhbGwsXG4gICAgICAgICAgdG9vbHMsXG4gICAgICAgICAgaW5wdXRTY2hlbWE6ICh7IHRvb2xOYW1lIH0pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgaW5wdXRTY2hlbWEgfSA9IHRvb2xzW3Rvb2xOYW1lXTtcbiAgICAgICAgICAgIHJldHVybiBhc1NjaGVtYShpbnB1dFNjaGVtYSkuanNvblNjaGVtYTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIHN5c3RlbSxcbiAgICAgICAgICBtZXNzYWdlcyxcbiAgICAgICAgICBlcnJvcixcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChyZXBhaXJFcnJvcikge1xuICAgICAgICB0aHJvdyBuZXcgVG9vbENhbGxSZXBhaXJFcnJvcih7XG4gICAgICAgICAgY2F1c2U6IHJlcGFpckVycm9yLFxuICAgICAgICAgIG9yaWdpbmFsRXJyb3I6IGVycm9yLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgLy8gbm8gcmVwYWlyZWQgdG9vbCBjYWxsIHJldHVybmVkXG4gICAgICBpZiAocmVwYWlyZWRUb29sQ2FsbCA9PSBudWxsKSB7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gYXdhaXQgZG9QYXJzZVRvb2xDYWxsKHsgdG9vbENhbGw6IHJlcGFpcmVkVG9vbENhbGwsIHRvb2xzIH0pO1xuICAgIH1cbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAvLyB1c2UgcGFyc2VkIGlucHV0IHdoZW4gcG9zc2libGVcbiAgICBjb25zdCBwYXJzZWRJbnB1dCA9IGF3YWl0IHNhZmVQYXJzZUpTT04oeyB0ZXh0OiB0b29sQ2FsbC5pbnB1dCB9KTtcbiAgICBjb25zdCBpbnB1dCA9IHBhcnNlZElucHV0LnN1Y2Nlc3MgPyBwYXJzZWRJbnB1dC52YWx1ZSA6IHRvb2xDYWxsLmlucHV0O1xuXG4gICAgLy8gVE9ETyBBSSBTREsgNjogc3BlY2lhbCBpbnZhbGlkIHRvb2wgY2FsbCBwYXJ0c1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiAndG9vbC1jYWxsJyxcbiAgICAgIHRvb2xDYWxsSWQ6IHRvb2xDYWxsLnRvb2xDYWxsSWQsXG4gICAgICB0b29sTmFtZTogdG9vbENhbGwudG9vbE5hbWUsXG4gICAgICBpbnB1dCxcbiAgICAgIGR5bmFtaWM6IHRydWUsXG4gICAgICBpbnZhbGlkOiB0cnVlLFxuICAgICAgZXJyb3IsXG4gICAgfTtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBkb1BhcnNlVG9vbENhbGw8VE9PTFMgZXh0ZW5kcyBUb29sU2V0Pih7XG4gIHRvb2xDYWxsLFxuICB0b29scyxcbn06IHtcbiAgdG9vbENhbGw6IExhbmd1YWdlTW9kZWxWMlRvb2xDYWxsO1xuICB0b29sczogVE9PTFM7XG59KTogUHJvbWlzZTxUeXBlZFRvb2xDYWxsPFRPT0xTPj4ge1xuICBjb25zdCB0b29sTmFtZSA9IHRvb2xDYWxsLnRvb2xOYW1lIGFzIGtleW9mIFRPT0xTICYgc3RyaW5nO1xuXG4gIGNvbnN0IHRvb2wgPSB0b29sc1t0b29sTmFtZV07XG5cbiAgaWYgKHRvb2wgPT0gbnVsbCkge1xuICAgIHRocm93IG5ldyBOb1N1Y2hUb29sRXJyb3Ioe1xuICAgICAgdG9vbE5hbWU6IHRvb2xDYWxsLnRvb2xOYW1lLFxuICAgICAgYXZhaWxhYmxlVG9vbHM6IE9iamVjdC5rZXlzKHRvb2xzKSxcbiAgICB9KTtcbiAgfVxuXG4gIGNvbnN0IHNjaGVtYSA9IGFzU2NoZW1hKHRvb2wuaW5wdXRTY2hlbWEpO1xuXG4gIC8vIHdoZW4gdGhlIHRvb2wgY2FsbCBoYXMgbm8gYXJndW1lbnRzLCB3ZSB0cnkgcGFzc2luZyBhbiBlbXB0eSBvYmplY3QgdG8gdGhlIHNjaGVtYVxuICAvLyAobWFueSBMTE1zIGdlbmVyYXRlIGVtcHR5IHN0cmluZ3MgZm9yIHRvb2wgY2FsbHMgd2l0aCBubyBhcmd1bWVudHMpXG4gIGNvbnN0IHBhcnNlUmVzdWx0ID1cbiAgICB0b29sQ2FsbC5pbnB1dC50cmltKCkgPT09ICcnXG4gICAgICA/IGF3YWl0IHNhZmVWYWxpZGF0ZVR5cGVzKHsgdmFsdWU6IHt9LCBzY2hlbWEgfSlcbiAgICAgIDogYXdhaXQgc2FmZVBhcnNlSlNPTih7IHRleHQ6IHRvb2xDYWxsLmlucHV0LCBzY2hlbWEgfSk7XG5cbiAgaWYgKHBhcnNlUmVzdWx0LnN1Y2Nlc3MgPT09IGZhbHNlKSB7XG4gICAgdGhyb3cgbmV3IEludmFsaWRUb29sSW5wdXRFcnJvcih7XG4gICAgICB0b29sTmFtZSxcbiAgICAgIHRvb2xJbnB1dDogdG9vbENhbGwuaW5wdXQsXG4gICAgICBjYXVzZTogcGFyc2VSZXN1bHQuZXJyb3IsXG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gdG9vbC50eXBlID09PSAnZHluYW1pYydcbiAgICA/IHtcbiAgICAgICAgdHlwZTogJ3Rvb2wtY2FsbCcsXG4gICAgICAgIHRvb2xDYWxsSWQ6IHRvb2xDYWxsLnRvb2xDYWxsSWQsXG4gICAgICAgIHRvb2xOYW1lOiB0b29sQ2FsbC50b29sTmFtZSxcbiAgICAgICAgaW5wdXQ6IHBhcnNlUmVzdWx0LnZhbHVlLFxuICAgICAgICBwcm92aWRlckV4ZWN1dGVkOiB0b29sQ2FsbC5wcm92aWRlckV4ZWN1dGVkLFxuICAgICAgICBwcm92aWRlck1ldGFkYXRhOiB0b29sQ2FsbC5wcm92aWRlck1ldGFkYXRhLFxuICAgICAgICBkeW5hbWljOiB0cnVlLFxuICAgICAgfVxuICAgIDoge1xuICAgICAgICB0eXBlOiAndG9vbC1jYWxsJyxcbiAgICAgICAgdG9vbENhbGxJZDogdG9vbENhbGwudG9vbENhbGxJZCxcbiAgICAgICAgdG9vbE5hbWUsXG4gICAgICAgIGlucHV0OiBwYXJzZVJlc3VsdC52YWx1ZSxcbiAgICAgICAgcHJvdmlkZXJFeGVjdXRlZDogdG9vbENhbGwucHJvdmlkZXJFeGVjdXRlZCxcbiAgICAgICAgcHJvdmlkZXJNZXRhZGF0YTogdG9vbENhbGwucHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgIH07XG59XG4iLCAiaW1wb3J0IHsgUmVhc29uaW5nUGFydCB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXItdXRpbHMnO1xuaW1wb3J0IHtcbiAgQ2FsbFdhcm5pbmcsXG4gIEZpbmlzaFJlYXNvbixcbiAgTGFuZ3VhZ2VNb2RlbFJlcXVlc3RNZXRhZGF0YSxcbiAgTGFuZ3VhZ2VNb2RlbFJlc3BvbnNlTWV0YWRhdGEsXG4gIFByb3ZpZGVyTWV0YWRhdGEsXG59IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gJy4uL3R5cGVzL2xhbmd1YWdlLW1vZGVsJztcbmltcG9ydCB7IExhbmd1YWdlTW9kZWxVc2FnZSB9IGZyb20gJy4uL3R5cGVzL3VzYWdlJztcbmltcG9ydCB7IENvbnRlbnRQYXJ0IH0gZnJvbSAnLi9jb250ZW50LXBhcnQnO1xuaW1wb3J0IHsgR2VuZXJhdGVkRmlsZSB9IGZyb20gJy4vZ2VuZXJhdGVkLWZpbGUnO1xuaW1wb3J0IHsgUmVzcG9uc2VNZXNzYWdlIH0gZnJvbSAnLi9yZXNwb25zZS1tZXNzYWdlJztcbmltcG9ydCB7IER5bmFtaWNUb29sQ2FsbCwgU3RhdGljVG9vbENhbGwsIFR5cGVkVG9vbENhbGwgfSBmcm9tICcuL3Rvb2wtY2FsbCc7XG5pbXBvcnQge1xuICBEeW5hbWljVG9vbFJlc3VsdCxcbiAgU3RhdGljVG9vbFJlc3VsdCxcbiAgVHlwZWRUb29sUmVzdWx0LFxufSBmcm9tICcuL3Rvb2wtcmVzdWx0JztcbmltcG9ydCB7IFRvb2xTZXQgfSBmcm9tICcuL3Rvb2wtc2V0JztcblxuLyoqXG4gKiBUaGUgcmVzdWx0IG9mIGEgc2luZ2xlIHN0ZXAgaW4gdGhlIGdlbmVyYXRpb24gcHJvY2Vzcy5cbiAqL1xuZXhwb3J0IHR5cGUgU3RlcFJlc3VsdDxUT09MUyBleHRlbmRzIFRvb2xTZXQ+ID0ge1xuICAvKipcblRoZSBjb250ZW50IHRoYXQgd2FzIGdlbmVyYXRlZCBpbiB0aGUgbGFzdCBzdGVwLlxuICAgKi9cbiAgcmVhZG9ubHkgY29udGVudDogQXJyYXk8Q29udGVudFBhcnQ8VE9PTFM+PjtcblxuICAvKipcblRoZSBnZW5lcmF0ZWQgdGV4dC5cbiovXG4gIHJlYWRvbmx5IHRleHQ6IHN0cmluZztcblxuICAvKipcblRoZSByZWFzb25pbmcgdGhhdCB3YXMgZ2VuZXJhdGVkIGR1cmluZyB0aGUgZ2VuZXJhdGlvbi5cbiovXG4gIHJlYWRvbmx5IHJlYXNvbmluZzogQXJyYXk8UmVhc29uaW5nUGFydD47XG5cbiAgLyoqXG5UaGUgcmVhc29uaW5nIHRleHQgdGhhdCB3YXMgZ2VuZXJhdGVkIGR1cmluZyB0aGUgZ2VuZXJhdGlvbi5cbiovXG4gIHJlYWRvbmx5IHJlYXNvbmluZ1RleHQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAvKipcblRoZSBmaWxlcyB0aGF0IHdlcmUgZ2VuZXJhdGVkIGR1cmluZyB0aGUgZ2VuZXJhdGlvbi5cbiovXG4gIHJlYWRvbmx5IGZpbGVzOiBBcnJheTxHZW5lcmF0ZWRGaWxlPjtcblxuICAvKipcblRoZSBzb3VyY2VzIHRoYXQgd2VyZSB1c2VkIHRvIGdlbmVyYXRlIHRoZSB0ZXh0LlxuKi9cbiAgcmVhZG9ubHkgc291cmNlczogQXJyYXk8U291cmNlPjtcblxuICAvKipcblRoZSB0b29sIGNhbGxzIHRoYXQgd2VyZSBtYWRlIGR1cmluZyB0aGUgZ2VuZXJhdGlvbi5cbiovXG4gIHJlYWRvbmx5IHRvb2xDYWxsczogQXJyYXk8VHlwZWRUb29sQ2FsbDxUT09MUz4+O1xuXG4gIC8qKlxuVGhlIHN0YXRpYyB0b29sIGNhbGxzIHRoYXQgd2VyZSBtYWRlIGluIHRoZSBsYXN0IHN0ZXAuXG4qL1xuICByZWFkb25seSBzdGF0aWNUb29sQ2FsbHM6IEFycmF5PFN0YXRpY1Rvb2xDYWxsPFRPT0xTPj47XG5cbiAgLyoqXG5UaGUgZHluYW1pYyB0b29sIGNhbGxzIHRoYXQgd2VyZSBtYWRlIGluIHRoZSBsYXN0IHN0ZXAuXG4qL1xuICByZWFkb25seSBkeW5hbWljVG9vbENhbGxzOiBBcnJheTxEeW5hbWljVG9vbENhbGw+O1xuXG4gIC8qKlxuVGhlIHJlc3VsdHMgb2YgdGhlIHRvb2wgY2FsbHMuXG4qL1xuICByZWFkb25seSB0b29sUmVzdWx0czogQXJyYXk8VHlwZWRUb29sUmVzdWx0PFRPT0xTPj47XG5cbiAgLyoqXG5UaGUgc3RhdGljIHRvb2wgcmVzdWx0cyB0aGF0IHdlcmUgbWFkZSBpbiB0aGUgbGFzdCBzdGVwLlxuKi9cbiAgcmVhZG9ubHkgc3RhdGljVG9vbFJlc3VsdHM6IEFycmF5PFN0YXRpY1Rvb2xSZXN1bHQ8VE9PTFM+PjtcblxuICAvKipcblRoZSBkeW5hbWljIHRvb2wgcmVzdWx0cyB0aGF0IHdlcmUgbWFkZSBpbiB0aGUgbGFzdCBzdGVwLlxuKi9cbiAgcmVhZG9ubHkgZHluYW1pY1Rvb2xSZXN1bHRzOiBBcnJheTxEeW5hbWljVG9vbFJlc3VsdD47XG5cbiAgLyoqXG5UaGUgcmVhc29uIHdoeSB0aGUgZ2VuZXJhdGlvbiBmaW5pc2hlZC5cbiovXG4gIHJlYWRvbmx5IGZpbmlzaFJlYXNvbjogRmluaXNoUmVhc29uO1xuXG4gIC8qKlxuVGhlIHRva2VuIHVzYWdlIG9mIHRoZSBnZW5lcmF0ZWQgdGV4dC5cbiovXG4gIHJlYWRvbmx5IHVzYWdlOiBMYW5ndWFnZU1vZGVsVXNhZ2U7XG5cbiAgLyoqXG5XYXJuaW5ncyBmcm9tIHRoZSBtb2RlbCBwcm92aWRlciAoZS5nLiB1bnN1cHBvcnRlZCBzZXR0aW5ncykuXG4qL1xuICByZWFkb25seSB3YXJuaW5nczogQ2FsbFdhcm5pbmdbXSB8IHVuZGVmaW5lZDtcblxuICAvKipcbkFkZGl0aW9uYWwgcmVxdWVzdCBpbmZvcm1hdGlvbi5cbiAgICovXG4gIHJlYWRvbmx5IHJlcXVlc3Q6IExhbmd1YWdlTW9kZWxSZXF1ZXN0TWV0YWRhdGE7XG5cbiAgLyoqXG5BZGRpdGlvbmFsIHJlc3BvbnNlIGluZm9ybWF0aW9uLlxuKi9cbiAgcmVhZG9ubHkgcmVzcG9uc2U6IExhbmd1YWdlTW9kZWxSZXNwb25zZU1ldGFkYXRhICYge1xuICAgIC8qKlxuVGhlIHJlc3BvbnNlIG1lc3NhZ2VzIHRoYXQgd2VyZSBnZW5lcmF0ZWQgZHVyaW5nIHRoZSBjYWxsLlxuUmVzcG9uc2UgbWVzc2FnZXMgY2FuIGJlIGVpdGhlciBhc3Npc3RhbnQgbWVzc2FnZXMgb3IgdG9vbCBtZXNzYWdlcy5cblRoZXkgY29udGFpbiBhIGdlbmVyYXRlZCBpZC5cbiovXG4gICAgcmVhZG9ubHkgbWVzc2FnZXM6IEFycmF5PFJlc3BvbnNlTWVzc2FnZT47XG5cbiAgICAvKipcblJlc3BvbnNlIGJvZHkgKGF2YWlsYWJsZSBvbmx5IGZvciBwcm92aWRlcnMgdGhhdCB1c2UgSFRUUCByZXF1ZXN0cykuXG4gICAgICovXG4gICAgYm9keT86IHVua25vd247XG4gIH07XG5cbiAgLyoqXG5BZGRpdGlvbmFsIHByb3ZpZGVyLXNwZWNpZmljIG1ldGFkYXRhLiBUaGV5IGFyZSBwYXNzZWQgdGhyb3VnaFxuZnJvbSB0aGUgcHJvdmlkZXIgdG8gdGhlIEFJIFNESyBhbmQgZW5hYmxlIHByb3ZpZGVyLXNwZWNpZmljXG5yZXN1bHRzIHRoYXQgY2FuIGJlIGZ1bGx5IGVuY2Fwc3VsYXRlZCBpbiB0aGUgcHJvdmlkZXIuXG4gICAqL1xuICByZWFkb25seSBwcm92aWRlck1ldGFkYXRhOiBQcm92aWRlck1ldGFkYXRhIHwgdW5kZWZpbmVkO1xufTtcblxuZXhwb3J0IGNsYXNzIERlZmF1bHRTdGVwUmVzdWx0PFRPT0xTIGV4dGVuZHMgVG9vbFNldD5cbiAgaW1wbGVtZW50cyBTdGVwUmVzdWx0PFRPT0xTPlxue1xuICByZWFkb25seSBjb250ZW50OiBTdGVwUmVzdWx0PFRPT0xTPlsnY29udGVudCddO1xuICByZWFkb25seSBmaW5pc2hSZWFzb246IFN0ZXBSZXN1bHQ8VE9PTFM+WydmaW5pc2hSZWFzb24nXTtcbiAgcmVhZG9ubHkgdXNhZ2U6IFN0ZXBSZXN1bHQ8VE9PTFM+Wyd1c2FnZSddO1xuICByZWFkb25seSB3YXJuaW5nczogU3RlcFJlc3VsdDxUT09MUz5bJ3dhcm5pbmdzJ107XG4gIHJlYWRvbmx5IHJlcXVlc3Q6IFN0ZXBSZXN1bHQ8VE9PTFM+WydyZXF1ZXN0J107XG4gIHJlYWRvbmx5IHJlc3BvbnNlOiBTdGVwUmVzdWx0PFRPT0xTPlsncmVzcG9uc2UnXTtcbiAgcmVhZG9ubHkgcHJvdmlkZXJNZXRhZGF0YTogU3RlcFJlc3VsdDxUT09MUz5bJ3Byb3ZpZGVyTWV0YWRhdGEnXTtcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgY29udGVudCxcbiAgICBmaW5pc2hSZWFzb24sXG4gICAgdXNhZ2UsXG4gICAgd2FybmluZ3MsXG4gICAgcmVxdWVzdCxcbiAgICByZXNwb25zZSxcbiAgICBwcm92aWRlck1ldGFkYXRhLFxuICB9OiB7XG4gICAgY29udGVudDogU3RlcFJlc3VsdDxUT09MUz5bJ2NvbnRlbnQnXTtcbiAgICBmaW5pc2hSZWFzb246IFN0ZXBSZXN1bHQ8VE9PTFM+WydmaW5pc2hSZWFzb24nXTtcbiAgICB1c2FnZTogU3RlcFJlc3VsdDxUT09MUz5bJ3VzYWdlJ107XG4gICAgd2FybmluZ3M6IFN0ZXBSZXN1bHQ8VE9PTFM+Wyd3YXJuaW5ncyddO1xuICAgIHJlcXVlc3Q6IFN0ZXBSZXN1bHQ8VE9PTFM+WydyZXF1ZXN0J107XG4gICAgcmVzcG9uc2U6IFN0ZXBSZXN1bHQ8VE9PTFM+WydyZXNwb25zZSddO1xuICAgIHByb3ZpZGVyTWV0YWRhdGE6IFN0ZXBSZXN1bHQ8VE9PTFM+Wydwcm92aWRlck1ldGFkYXRhJ107XG4gIH0pIHtcbiAgICB0aGlzLmNvbnRlbnQgPSBjb250ZW50O1xuICAgIHRoaXMuZmluaXNoUmVhc29uID0gZmluaXNoUmVhc29uO1xuICAgIHRoaXMudXNhZ2UgPSB1c2FnZTtcbiAgICB0aGlzLndhcm5pbmdzID0gd2FybmluZ3M7XG4gICAgdGhpcy5yZXF1ZXN0ID0gcmVxdWVzdDtcbiAgICB0aGlzLnJlc3BvbnNlID0gcmVzcG9uc2U7XG4gICAgdGhpcy5wcm92aWRlck1ldGFkYXRhID0gcHJvdmlkZXJNZXRhZGF0YTtcbiAgfVxuXG4gIGdldCB0ZXh0KCkge1xuICAgIHJldHVybiB0aGlzLmNvbnRlbnRcbiAgICAgIC5maWx0ZXIocGFydCA9PiBwYXJ0LnR5cGUgPT09ICd0ZXh0JylcbiAgICAgIC5tYXAocGFydCA9PiBwYXJ0LnRleHQpXG4gICAgICAuam9pbignJyk7XG4gIH1cblxuICBnZXQgcmVhc29uaW5nKCkge1xuICAgIHJldHVybiB0aGlzLmNvbnRlbnQuZmlsdGVyKHBhcnQgPT4gcGFydC50eXBlID09PSAncmVhc29uaW5nJyk7XG4gIH1cblxuICBnZXQgcmVhc29uaW5nVGV4dCgpIHtcbiAgICByZXR1cm4gdGhpcy5yZWFzb25pbmcubGVuZ3RoID09PSAwXG4gICAgICA/IHVuZGVmaW5lZFxuICAgICAgOiB0aGlzLnJlYXNvbmluZy5tYXAocGFydCA9PiBwYXJ0LnRleHQpLmpvaW4oJycpO1xuICB9XG5cbiAgZ2V0IGZpbGVzKCkge1xuICAgIHJldHVybiB0aGlzLmNvbnRlbnRcbiAgICAgIC5maWx0ZXIocGFydCA9PiBwYXJ0LnR5cGUgPT09ICdmaWxlJylcbiAgICAgIC5tYXAocGFydCA9PiBwYXJ0LmZpbGUpO1xuICB9XG5cbiAgZ2V0IHNvdXJjZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMuY29udGVudC5maWx0ZXIocGFydCA9PiBwYXJ0LnR5cGUgPT09ICdzb3VyY2UnKTtcbiAgfVxuXG4gIGdldCB0b29sQ2FsbHMoKSB7XG4gICAgcmV0dXJuIHRoaXMuY29udGVudC5maWx0ZXIocGFydCA9PiBwYXJ0LnR5cGUgPT09ICd0b29sLWNhbGwnKTtcbiAgfVxuXG4gIGdldCBzdGF0aWNUb29sQ2FsbHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG9vbENhbGxzLmZpbHRlcihcbiAgICAgICh0b29sQ2FsbCk6IHRvb2xDYWxsIGlzIFN0YXRpY1Rvb2xDYWxsPFRPT0xTPiA9PlxuICAgICAgICB0b29sQ2FsbC5keW5hbWljICE9PSB0cnVlLFxuICAgICk7XG4gIH1cblxuICBnZXQgZHluYW1pY1Rvb2xDYWxscygpIHtcbiAgICByZXR1cm4gdGhpcy50b29sQ2FsbHMuZmlsdGVyKFxuICAgICAgKHRvb2xDYWxsKTogdG9vbENhbGwgaXMgRHluYW1pY1Rvb2xDYWxsID0+IHRvb2xDYWxsLmR5bmFtaWMgPT09IHRydWUsXG4gICAgKTtcbiAgfVxuXG4gIGdldCB0b29sUmVzdWx0cygpIHtcbiAgICByZXR1cm4gdGhpcy5jb250ZW50LmZpbHRlcihwYXJ0ID0+IHBhcnQudHlwZSA9PT0gJ3Rvb2wtcmVzdWx0Jyk7XG4gIH1cblxuICBnZXQgc3RhdGljVG9vbFJlc3VsdHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG9vbFJlc3VsdHMuZmlsdGVyKFxuICAgICAgKHRvb2xSZXN1bHQpOiB0b29sUmVzdWx0IGlzIFN0YXRpY1Rvb2xSZXN1bHQ8VE9PTFM+ID0+XG4gICAgICAgIHRvb2xSZXN1bHQuZHluYW1pYyAhPT0gdHJ1ZSxcbiAgICApO1xuICB9XG5cbiAgZ2V0IGR5bmFtaWNUb29sUmVzdWx0cygpIHtcbiAgICByZXR1cm4gdGhpcy50b29sUmVzdWx0cy5maWx0ZXIoXG4gICAgICAodG9vbFJlc3VsdCk6IHRvb2xSZXN1bHQgaXMgRHluYW1pY1Rvb2xSZXN1bHQgPT5cbiAgICAgICAgdG9vbFJlc3VsdC5keW5hbWljID09PSB0cnVlLFxuICAgICk7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBTdGVwUmVzdWx0IH0gZnJvbSAnLi9zdGVwLXJlc3VsdCc7XG5pbXBvcnQgeyBUb29sU2V0IH0gZnJvbSAnLi90b29sLXNldCc7XG5cbmV4cG9ydCB0eXBlIFN0b3BDb25kaXRpb248VE9PTFMgZXh0ZW5kcyBUb29sU2V0PiA9IChvcHRpb25zOiB7XG4gIHN0ZXBzOiBBcnJheTxTdGVwUmVzdWx0PFRPT0xTPj47XG59KSA9PiBQcm9taXNlTGlrZTxib29sZWFuPiB8IGJvb2xlYW47XG5cbmV4cG9ydCBmdW5jdGlvbiBzdGVwQ291bnRJcyhzdGVwQ291bnQ6IG51bWJlcik6IFN0b3BDb25kaXRpb248YW55PiB7XG4gIHJldHVybiAoeyBzdGVwcyB9KSA9PiBzdGVwcy5sZW5ndGggPT09IHN0ZXBDb3VudDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhhc1Rvb2xDYWxsKHRvb2xOYW1lOiBzdHJpbmcpOiBTdG9wQ29uZGl0aW9uPGFueT4ge1xuICByZXR1cm4gKHsgc3RlcHMgfSkgPT5cbiAgICBzdGVwc1tzdGVwcy5sZW5ndGggLSAxXT8udG9vbENhbGxzPy5zb21lKFxuICAgICAgdG9vbENhbGwgPT4gdG9vbENhbGwudG9vbE5hbWUgPT09IHRvb2xOYW1lLFxuICAgICkgPz8gZmFsc2U7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBpc1N0b3BDb25kaXRpb25NZXQ8VE9PTFMgZXh0ZW5kcyBUb29sU2V0Pih7XG4gIHN0b3BDb25kaXRpb25zLFxuICBzdGVwcyxcbn06IHtcbiAgc3RvcENvbmRpdGlvbnM6IEFycmF5PFN0b3BDb25kaXRpb248VE9PTFM+PjtcbiAgc3RlcHM6IEFycmF5PFN0ZXBSZXN1bHQ8VE9PTFM+Pjtcbn0pOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgcmV0dXJuIChcbiAgICBhd2FpdCBQcm9taXNlLmFsbChzdG9wQ29uZGl0aW9ucy5tYXAoY29uZGl0aW9uID0+IGNvbmRpdGlvbih7IHN0ZXBzIH0pKSlcbiAgKS5zb21lKHJlc3VsdCA9PiByZXN1bHQpO1xufVxuIiwgImltcG9ydCB7XG4gIGdldEVycm9yTWVzc2FnZSxcbiAgSlNPTlZhbHVlLFxuICBMYW5ndWFnZU1vZGVsVjJUb29sUmVzdWx0T3V0cHV0LFxufSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcbmltcG9ydCB7IFRvb2wgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyLXV0aWxzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVRvb2xNb2RlbE91dHB1dCh7XG4gIG91dHB1dCxcbiAgdG9vbCxcbiAgZXJyb3JNb2RlLFxufToge1xuICBvdXRwdXQ6IHVua25vd247XG4gIHRvb2w6IFRvb2wgfCB1bmRlZmluZWQ7XG4gIGVycm9yTW9kZTogJ25vbmUnIHwgJ3RleHQnIHwgJ2pzb24nO1xufSk6IExhbmd1YWdlTW9kZWxWMlRvb2xSZXN1bHRPdXRwdXQge1xuICBpZiAoZXJyb3JNb2RlID09PSAndGV4dCcpIHtcbiAgICByZXR1cm4geyB0eXBlOiAnZXJyb3ItdGV4dCcsIHZhbHVlOiBnZXRFcnJvck1lc3NhZ2Uob3V0cHV0KSB9O1xuICB9IGVsc2UgaWYgKGVycm9yTW9kZSA9PT0gJ2pzb24nKSB7XG4gICAgcmV0dXJuIHsgdHlwZTogJ2Vycm9yLWpzb24nLCB2YWx1ZTogdG9KU09OVmFsdWUob3V0cHV0KSB9O1xuICB9XG5cbiAgaWYgKHRvb2w/LnRvTW9kZWxPdXRwdXQpIHtcbiAgICByZXR1cm4gdG9vbC50b01vZGVsT3V0cHV0KG91dHB1dCk7XG4gIH1cblxuICByZXR1cm4gdHlwZW9mIG91dHB1dCA9PT0gJ3N0cmluZydcbiAgICA/IHsgdHlwZTogJ3RleHQnLCB2YWx1ZTogb3V0cHV0IH1cbiAgICA6IHsgdHlwZTogJ2pzb24nLCB2YWx1ZTogdG9KU09OVmFsdWUob3V0cHV0KSB9O1xufVxuXG5mdW5jdGlvbiB0b0pTT05WYWx1ZSh2YWx1ZTogdW5rbm93bik6IEpTT05WYWx1ZSB7XG4gIHJldHVybiB2YWx1ZSA9PT0gdW5kZWZpbmVkID8gbnVsbCA6ICh2YWx1ZSBhcyBKU09OVmFsdWUpO1xufVxuIiwgImltcG9ydCB7XG4gIEFzc2lzdGFudENvbnRlbnQsXG4gIEFzc2lzdGFudE1vZGVsTWVzc2FnZSxcbiAgVG9vbENvbnRlbnQsXG4gIFRvb2xNb2RlbE1lc3NhZ2UsXG59IGZyb20gJy4uL3Byb21wdCc7XG5pbXBvcnQgeyBjcmVhdGVUb29sTW9kZWxPdXRwdXQgfSBmcm9tICcuLi9wcm9tcHQvY3JlYXRlLXRvb2wtbW9kZWwtb3V0cHV0JztcbmltcG9ydCB7IENvbnRlbnRQYXJ0IH0gZnJvbSAnLi9jb250ZW50LXBhcnQnO1xuaW1wb3J0IHsgVG9vbFNldCB9IGZyb20gJy4vdG9vbC1zZXQnO1xuXG4vKipcbkNvbnZlcnRzIHRoZSByZXN1bHQgb2YgYSBgZ2VuZXJhdGVUZXh0YCBvciBgc3RyZWFtVGV4dGAgY2FsbCB0byBhIGxpc3Qgb2YgcmVzcG9uc2UgbWVzc2FnZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b1Jlc3BvbnNlTWVzc2FnZXM8VE9PTFMgZXh0ZW5kcyBUb29sU2V0Pih7XG4gIGNvbnRlbnQ6IGlucHV0Q29udGVudCxcbiAgdG9vbHMsXG59OiB7XG4gIGNvbnRlbnQ6IEFycmF5PENvbnRlbnRQYXJ0PFRPT0xTPj47XG4gIHRvb2xzOiBUT09MUyB8IHVuZGVmaW5lZDtcbn0pOiBBcnJheTxBc3Npc3RhbnRNb2RlbE1lc3NhZ2UgfCBUb29sTW9kZWxNZXNzYWdlPiB7XG4gIGNvbnN0IHJlc3BvbnNlTWVzc2FnZXM6IEFycmF5PEFzc2lzdGFudE1vZGVsTWVzc2FnZSB8IFRvb2xNb2RlbE1lc3NhZ2U+ID0gW107XG5cbiAgY29uc3QgY29udGVudDogQXNzaXN0YW50Q29udGVudCA9IGlucHV0Q29udGVudFxuICAgIC5maWx0ZXIocGFydCA9PiBwYXJ0LnR5cGUgIT09ICdzb3VyY2UnKVxuICAgIC5maWx0ZXIoXG4gICAgICBwYXJ0ID0+XG4gICAgICAgIChwYXJ0LnR5cGUgIT09ICd0b29sLXJlc3VsdCcgfHwgcGFydC5wcm92aWRlckV4ZWN1dGVkKSAmJlxuICAgICAgICAocGFydC50eXBlICE9PSAndG9vbC1lcnJvcicgfHwgcGFydC5wcm92aWRlckV4ZWN1dGVkKSxcbiAgICApXG4gICAgLmZpbHRlcihwYXJ0ID0+IHBhcnQudHlwZSAhPT0gJ3RleHQnIHx8IHBhcnQudGV4dC5sZW5ndGggPiAwKVxuICAgIC5tYXAocGFydCA9PiB7XG4gICAgICBzd2l0Y2ggKHBhcnQudHlwZSkge1xuICAgICAgICBjYXNlICd0ZXh0JzpcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgICAgICAgdGV4dDogcGFydC50ZXh0LFxuICAgICAgICAgICAgcHJvdmlkZXJPcHRpb25zOiBwYXJ0LnByb3ZpZGVyTWV0YWRhdGEsXG4gICAgICAgICAgfTtcbiAgICAgICAgY2FzZSAncmVhc29uaW5nJzpcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogJ3JlYXNvbmluZycsXG4gICAgICAgICAgICB0ZXh0OiBwYXJ0LnRleHQsXG4gICAgICAgICAgICBwcm92aWRlck9wdGlvbnM6IHBhcnQucHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgICB9O1xuICAgICAgICBjYXNlICdmaWxlJzpcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogJ2ZpbGUnLFxuICAgICAgICAgICAgZGF0YTogcGFydC5maWxlLmJhc2U2NCxcbiAgICAgICAgICAgIG1lZGlhVHlwZTogcGFydC5maWxlLm1lZGlhVHlwZSxcbiAgICAgICAgICAgIHByb3ZpZGVyT3B0aW9uczogcGFydC5wcm92aWRlck1ldGFkYXRhLFxuICAgICAgICAgIH07XG4gICAgICAgIGNhc2UgJ3Rvb2wtY2FsbCc6XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6ICd0b29sLWNhbGwnLFxuICAgICAgICAgICAgdG9vbENhbGxJZDogcGFydC50b29sQ2FsbElkLFxuICAgICAgICAgICAgdG9vbE5hbWU6IHBhcnQudG9vbE5hbWUsXG4gICAgICAgICAgICBpbnB1dDogcGFydC5pbnB1dCxcbiAgICAgICAgICAgIHByb3ZpZGVyRXhlY3V0ZWQ6IHBhcnQucHJvdmlkZXJFeGVjdXRlZCxcbiAgICAgICAgICAgIHByb3ZpZGVyT3B0aW9uczogcGFydC5wcm92aWRlck1ldGFkYXRhLFxuICAgICAgICAgIH07XG4gICAgICAgIGNhc2UgJ3Rvb2wtcmVzdWx0JzpcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogJ3Rvb2wtcmVzdWx0JyxcbiAgICAgICAgICAgIHRvb2xDYWxsSWQ6IHBhcnQudG9vbENhbGxJZCxcbiAgICAgICAgICAgIHRvb2xOYW1lOiBwYXJ0LnRvb2xOYW1lLFxuICAgICAgICAgICAgb3V0cHV0OiBjcmVhdGVUb29sTW9kZWxPdXRwdXQoe1xuICAgICAgICAgICAgICB0b29sOiB0b29scz8uW3BhcnQudG9vbE5hbWVdLFxuICAgICAgICAgICAgICBvdXRwdXQ6IHBhcnQub3V0cHV0LFxuICAgICAgICAgICAgICBlcnJvck1vZGU6ICdub25lJyxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgcHJvdmlkZXJFeGVjdXRlZDogdHJ1ZSxcbiAgICAgICAgICAgIHByb3ZpZGVyT3B0aW9uczogcGFydC5wcm92aWRlck1ldGFkYXRhLFxuICAgICAgICAgIH07XG4gICAgICAgIGNhc2UgJ3Rvb2wtZXJyb3InOlxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiAndG9vbC1yZXN1bHQnLFxuICAgICAgICAgICAgdG9vbENhbGxJZDogcGFydC50b29sQ2FsbElkLFxuICAgICAgICAgICAgdG9vbE5hbWU6IHBhcnQudG9vbE5hbWUsXG4gICAgICAgICAgICBvdXRwdXQ6IGNyZWF0ZVRvb2xNb2RlbE91dHB1dCh7XG4gICAgICAgICAgICAgIHRvb2w6IHRvb2xzPy5bcGFydC50b29sTmFtZV0sXG4gICAgICAgICAgICAgIG91dHB1dDogcGFydC5lcnJvcixcbiAgICAgICAgICAgICAgZXJyb3JNb2RlOiAnanNvbicsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIHByb3ZpZGVyT3B0aW9uczogcGFydC5wcm92aWRlck1ldGFkYXRhLFxuICAgICAgICAgIH07XG4gICAgICB9XG4gICAgfSk7XG5cbiAgaWYgKGNvbnRlbnQubGVuZ3RoID4gMCkge1xuICAgIHJlc3BvbnNlTWVzc2FnZXMucHVzaCh7XG4gICAgICByb2xlOiAnYXNzaXN0YW50JyxcbiAgICAgIGNvbnRlbnQsXG4gICAgfSk7XG4gIH1cblxuICBjb25zdCB0b29sUmVzdWx0Q29udGVudDogVG9vbENvbnRlbnQgPSBpbnB1dENvbnRlbnRcbiAgICAuZmlsdGVyKHBhcnQgPT4gcGFydC50eXBlID09PSAndG9vbC1yZXN1bHQnIHx8IHBhcnQudHlwZSA9PT0gJ3Rvb2wtZXJyb3InKVxuICAgIC5maWx0ZXIocGFydCA9PiAhcGFydC5wcm92aWRlckV4ZWN1dGVkKVxuICAgIC5tYXAodG9vbFJlc3VsdCA9PiAoe1xuICAgICAgdHlwZTogJ3Rvb2wtcmVzdWx0JyxcbiAgICAgIHRvb2xDYWxsSWQ6IHRvb2xSZXN1bHQudG9vbENhbGxJZCxcbiAgICAgIHRvb2xOYW1lOiB0b29sUmVzdWx0LnRvb2xOYW1lLFxuICAgICAgb3V0cHV0OiBjcmVhdGVUb29sTW9kZWxPdXRwdXQoe1xuICAgICAgICB0b29sOiB0b29scz8uW3Rvb2xSZXN1bHQudG9vbE5hbWVdLFxuICAgICAgICBvdXRwdXQ6XG4gICAgICAgICAgdG9vbFJlc3VsdC50eXBlID09PSAndG9vbC1yZXN1bHQnXG4gICAgICAgICAgICA/IHRvb2xSZXN1bHQub3V0cHV0XG4gICAgICAgICAgICA6IHRvb2xSZXN1bHQuZXJyb3IsXG4gICAgICAgIGVycm9yTW9kZTogdG9vbFJlc3VsdC50eXBlID09PSAndG9vbC1lcnJvcicgPyAndGV4dCcgOiAnbm9uZScsXG4gICAgICB9KSxcbiAgICB9KSk7XG5cbiAgaWYgKHRvb2xSZXN1bHRDb250ZW50Lmxlbmd0aCA+IDApIHtcbiAgICByZXNwb25zZU1lc3NhZ2VzLnB1c2goe1xuICAgICAgcm9sZTogJ3Rvb2wnLFxuICAgICAgY29udGVudDogdG9vbFJlc3VsdENvbnRlbnQsXG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gcmVzcG9uc2VNZXNzYWdlcztcbn1cbiIsICJpbXBvcnQge1xuICBnZXRFcnJvck1lc3NhZ2UsXG4gIExhbmd1YWdlTW9kZWxWMixcbiAgTGFuZ3VhZ2VNb2RlbFYyQ2FsbFdhcm5pbmcsXG59IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHtcbiAgY3JlYXRlSWRHZW5lcmF0b3IsXG4gIElkR2VuZXJhdG9yLFxuICBpc0Fib3J0RXJyb3IsXG4gIFByb3ZpZGVyT3B0aW9ucyxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyBTcGFuIH0gZnJvbSAnQG9wZW50ZWxlbWV0cnkvYXBpJztcbmltcG9ydCB7IFNlcnZlclJlc3BvbnNlIH0gZnJvbSAnbm9kZTpodHRwJztcbmltcG9ydCB7IE5vT3V0cHV0R2VuZXJhdGVkRXJyb3IgfSBmcm9tICcuLi9lcnJvcic7XG5pbXBvcnQgeyBOb091dHB1dFNwZWNpZmllZEVycm9yIH0gZnJvbSAnLi4vZXJyb3Ivbm8tb3V0cHV0LXNwZWNpZmllZC1lcnJvcic7XG5pbXBvcnQgeyBsb2dXYXJuaW5ncyB9IGZyb20gJy4uL2xvZ2dlci9sb2ctd2FybmluZ3MnO1xuaW1wb3J0IHsgcmVzb2x2ZUxhbmd1YWdlTW9kZWwgfSBmcm9tICcuLi9tb2RlbC9yZXNvbHZlLW1vZGVsJztcbmltcG9ydCB7IENhbGxTZXR0aW5ncyB9IGZyb20gJy4uL3Byb21wdC9jYWxsLXNldHRpbmdzJztcbmltcG9ydCB7IGNvbnZlcnRUb0xhbmd1YWdlTW9kZWxQcm9tcHQgfSBmcm9tICcuLi9wcm9tcHQvY29udmVydC10by1sYW5ndWFnZS1tb2RlbC1wcm9tcHQnO1xuaW1wb3J0IHsgcHJlcGFyZUNhbGxTZXR0aW5ncyB9IGZyb20gJy4uL3Byb21wdC9wcmVwYXJlLWNhbGwtc2V0dGluZ3MnO1xuaW1wb3J0IHsgcHJlcGFyZVRvb2xzQW5kVG9vbENob2ljZSB9IGZyb20gJy4uL3Byb21wdC9wcmVwYXJlLXRvb2xzLWFuZC10b29sLWNob2ljZSc7XG5pbXBvcnQgeyBQcm9tcHQgfSBmcm9tICcuLi9wcm9tcHQvcHJvbXB0JztcbmltcG9ydCB7IHN0YW5kYXJkaXplUHJvbXB0IH0gZnJvbSAnLi4vcHJvbXB0L3N0YW5kYXJkaXplLXByb21wdCc7XG5pbXBvcnQgeyB3cmFwR2F0ZXdheUVycm9yIH0gZnJvbSAnLi4vcHJvbXB0L3dyYXAtZ2F0ZXdheS1lcnJvcic7XG5pbXBvcnQgeyBhc3NlbWJsZU9wZXJhdGlvbk5hbWUgfSBmcm9tICcuLi90ZWxlbWV0cnkvYXNzZW1ibGUtb3BlcmF0aW9uLW5hbWUnO1xuaW1wb3J0IHsgZ2V0QmFzZVRlbGVtZXRyeUF0dHJpYnV0ZXMgfSBmcm9tICcuLi90ZWxlbWV0cnkvZ2V0LWJhc2UtdGVsZW1ldHJ5LWF0dHJpYnV0ZXMnO1xuaW1wb3J0IHsgZ2V0VHJhY2VyIH0gZnJvbSAnLi4vdGVsZW1ldHJ5L2dldC10cmFjZXInO1xuaW1wb3J0IHsgcmVjb3JkU3BhbiB9IGZyb20gJy4uL3RlbGVtZXRyeS9yZWNvcmQtc3Bhbic7XG5pbXBvcnQgeyBzZWxlY3RUZWxlbWV0cnlBdHRyaWJ1dGVzIH0gZnJvbSAnLi4vdGVsZW1ldHJ5L3NlbGVjdC10ZWxlbWV0cnktYXR0cmlidXRlcyc7XG5pbXBvcnQgeyBzdHJpbmdpZnlGb3JUZWxlbWV0cnkgfSBmcm9tICcuLi90ZWxlbWV0cnkvc3RyaW5naWZ5LWZvci10ZWxlbWV0cnknO1xuaW1wb3J0IHsgVGVsZW1ldHJ5U2V0dGluZ3MgfSBmcm9tICcuLi90ZWxlbWV0cnkvdGVsZW1ldHJ5LXNldHRpbmdzJztcbmltcG9ydCB7IGNyZWF0ZVRleHRTdHJlYW1SZXNwb25zZSB9IGZyb20gJy4uL3RleHQtc3RyZWFtL2NyZWF0ZS10ZXh0LXN0cmVhbS1yZXNwb25zZSc7XG5pbXBvcnQgeyBwaXBlVGV4dFN0cmVhbVRvUmVzcG9uc2UgfSBmcm9tICcuLi90ZXh0LXN0cmVhbS9waXBlLXRleHQtc3RyZWFtLXRvLXJlc3BvbnNlJztcbmltcG9ydCB7IExhbmd1YWdlTW9kZWxSZXF1ZXN0TWV0YWRhdGEgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQge1xuICBDYWxsV2FybmluZyxcbiAgRmluaXNoUmVhc29uLFxuICBMYW5ndWFnZU1vZGVsLFxuICBUb29sQ2hvaWNlLFxufSBmcm9tICcuLi90eXBlcy9sYW5ndWFnZS1tb2RlbCc7XG5pbXBvcnQgeyBQcm92aWRlck1ldGFkYXRhIH0gZnJvbSAnLi4vdHlwZXMvcHJvdmlkZXItbWV0YWRhdGEnO1xuaW1wb3J0IHsgYWRkTGFuZ3VhZ2VNb2RlbFVzYWdlLCBMYW5ndWFnZU1vZGVsVXNhZ2UgfSBmcm9tICcuLi90eXBlcy91c2FnZSc7XG5pbXBvcnQgeyBVSU1lc3NhZ2UgfSBmcm9tICcuLi91aSc7XG5pbXBvcnQgeyBjcmVhdGVVSU1lc3NhZ2VTdHJlYW1SZXNwb25zZSB9IGZyb20gJy4uL3VpLW1lc3NhZ2Utc3RyZWFtL2NyZWF0ZS11aS1tZXNzYWdlLXN0cmVhbS1yZXNwb25zZSc7XG5pbXBvcnQgeyBnZXRSZXNwb25zZVVJTWVzc2FnZUlkIH0gZnJvbSAnLi4vdWktbWVzc2FnZS1zdHJlYW0vZ2V0LXJlc3BvbnNlLXVpLW1lc3NhZ2UtaWQnO1xuaW1wb3J0IHsgaGFuZGxlVUlNZXNzYWdlU3RyZWFtRmluaXNoIH0gZnJvbSAnLi4vdWktbWVzc2FnZS1zdHJlYW0vaGFuZGxlLXVpLW1lc3NhZ2Utc3RyZWFtLWZpbmlzaCc7XG5pbXBvcnQgeyBwaXBlVUlNZXNzYWdlU3RyZWFtVG9SZXNwb25zZSB9IGZyb20gJy4uL3VpLW1lc3NhZ2Utc3RyZWFtL3BpcGUtdWktbWVzc2FnZS1zdHJlYW0tdG8tcmVzcG9uc2UnO1xuaW1wb3J0IHtcbiAgSW5mZXJVSU1lc3NhZ2VDaHVuayxcbiAgVUlNZXNzYWdlQ2h1bmssXG59IGZyb20gJy4uL3VpLW1lc3NhZ2Utc3RyZWFtL3VpLW1lc3NhZ2UtY2h1bmtzJztcbmltcG9ydCB7IFVJTWVzc2FnZVN0cmVhbVJlc3BvbnNlSW5pdCB9IGZyb20gJy4uL3VpLW1lc3NhZ2Utc3RyZWFtL3VpLW1lc3NhZ2Utc3RyZWFtLXJlc3BvbnNlLWluaXQnO1xuaW1wb3J0IHsgSW5mZXJVSU1lc3NhZ2VEYXRhLCBJbmZlclVJTWVzc2FnZU1ldGFkYXRhIH0gZnJvbSAnLi4vdWkvdWktbWVzc2FnZXMnO1xuaW1wb3J0IHsgYXNBcnJheSB9IGZyb20gJy4uL3V0aWwvYXMtYXJyYXknO1xuaW1wb3J0IHtcbiAgQXN5bmNJdGVyYWJsZVN0cmVhbSxcbiAgY3JlYXRlQXN5bmNJdGVyYWJsZVN0cmVhbSxcbn0gZnJvbSAnLi4vdXRpbC9hc3luYy1pdGVyYWJsZS1zdHJlYW0nO1xuaW1wb3J0IHsgY29uc3VtZVN0cmVhbSB9IGZyb20gJy4uL3V0aWwvY29uc3VtZS1zdHJlYW0nO1xuaW1wb3J0IHsgY3JlYXRlU3RpdGNoYWJsZVN0cmVhbSB9IGZyb20gJy4uL3V0aWwvY3JlYXRlLXN0aXRjaGFibGUtc3RyZWFtJztcbmltcG9ydCB7IERlbGF5ZWRQcm9taXNlIH0gZnJvbSAnLi4vdXRpbC9kZWxheWVkLXByb21pc2UnO1xuaW1wb3J0IHsgRG93bmxvYWRGdW5jdGlvbiB9IGZyb20gJy4uL3V0aWwvZG93bmxvYWQvZG93bmxvYWQtZnVuY3Rpb24nO1xuaW1wb3J0IHsgbm93IGFzIG9yaWdpbmFsTm93IH0gZnJvbSAnLi4vdXRpbC9ub3cnO1xuaW1wb3J0IHsgcHJlcGFyZVJldHJpZXMgfSBmcm9tICcuLi91dGlsL3ByZXBhcmUtcmV0cmllcyc7XG5pbXBvcnQgeyBDb250ZW50UGFydCB9IGZyb20gJy4vY29udGVudC1wYXJ0JztcbmltcG9ydCB7IE91dHB1dCB9IGZyb20gJy4vb3V0cHV0JztcbmltcG9ydCB7IFByZXBhcmVTdGVwRnVuY3Rpb24gfSBmcm9tICcuL3ByZXBhcmUtc3RlcCc7XG5pbXBvcnQgeyBSZXNwb25zZU1lc3NhZ2UgfSBmcm9tICcuL3Jlc3BvbnNlLW1lc3NhZ2UnO1xuaW1wb3J0IHtcbiAgcnVuVG9vbHNUcmFuc2Zvcm1hdGlvbixcbiAgU2luZ2xlUmVxdWVzdFRleHRTdHJlYW1QYXJ0LFxufSBmcm9tICcuL3J1bi10b29scy10cmFuc2Zvcm1hdGlvbic7XG5pbXBvcnQgeyBEZWZhdWx0U3RlcFJlc3VsdCwgU3RlcFJlc3VsdCB9IGZyb20gJy4vc3RlcC1yZXN1bHQnO1xuaW1wb3J0IHtcbiAgaXNTdG9wQ29uZGl0aW9uTWV0LFxuICBzdGVwQ291bnRJcyxcbiAgU3RvcENvbmRpdGlvbixcbn0gZnJvbSAnLi9zdG9wLWNvbmRpdGlvbic7XG5pbXBvcnQge1xuICBDb25zdW1lU3RyZWFtT3B0aW9ucyxcbiAgU3RyZWFtVGV4dFJlc3VsdCxcbiAgVGV4dFN0cmVhbVBhcnQsXG4gIFVJTWVzc2FnZVN0cmVhbU9wdGlvbnMsXG59IGZyb20gJy4vc3RyZWFtLXRleHQtcmVzdWx0JztcbmltcG9ydCB7IHRvUmVzcG9uc2VNZXNzYWdlcyB9IGZyb20gJy4vdG8tcmVzcG9uc2UtbWVzc2FnZXMnO1xuaW1wb3J0IHsgVHlwZWRUb29sQ2FsbCB9IGZyb20gJy4vdG9vbC1jYWxsJztcbmltcG9ydCB7IFRvb2xDYWxsUmVwYWlyRnVuY3Rpb24gfSBmcm9tICcuL3Rvb2wtY2FsbC1yZXBhaXItZnVuY3Rpb24nO1xuaW1wb3J0IHsgVG9vbE91dHB1dCB9IGZyb20gJy4vdG9vbC1vdXRwdXQnO1xuaW1wb3J0IHsgVG9vbFNldCB9IGZyb20gJy4vdG9vbC1zZXQnO1xuXG5jb25zdCBvcmlnaW5hbEdlbmVyYXRlSWQgPSBjcmVhdGVJZEdlbmVyYXRvcih7XG4gIHByZWZpeDogJ2FpdHh0JyxcbiAgc2l6ZTogMjQsXG59KTtcblxuLyoqXG5BIHRyYW5zZm9ybWF0aW9uIHRoYXQgaXMgYXBwbGllZCB0byB0aGUgc3RyZWFtLlxuXG5AcGFyYW0gc3RvcFN0cmVhbSAtIEEgZnVuY3Rpb24gdGhhdCBzdG9wcyB0aGUgc291cmNlIHN0cmVhbS5cbkBwYXJhbSB0b29scyAtIFRoZSB0b29scyB0aGF0IGFyZSBhY2Nlc3NpYmxlIHRvIGFuZCBjYW4gYmUgY2FsbGVkIGJ5IHRoZSBtb2RlbC4gVGhlIG1vZGVsIG5lZWRzIHRvIHN1cHBvcnQgY2FsbGluZyB0b29scy5cbiAqL1xuZXhwb3J0IHR5cGUgU3RyZWFtVGV4dFRyYW5zZm9ybTxUT09MUyBleHRlbmRzIFRvb2xTZXQ+ID0gKG9wdGlvbnM6IHtcbiAgdG9vbHM6IFRPT0xTOyAvLyBmb3IgdHlwZSBpbmZlcmVuY2VcbiAgc3RvcFN0cmVhbTogKCkgPT4gdm9pZDtcbn0pID0+IFRyYW5zZm9ybVN0cmVhbTxUZXh0U3RyZWFtUGFydDxUT09MUz4sIFRleHRTdHJlYW1QYXJ0PFRPT0xTPj47XG5cbi8qKlxuQ2FsbGJhY2sgdGhhdCBpcyBzZXQgdXNpbmcgdGhlIGBvbkVycm9yYCBvcHRpb24uXG5cbkBwYXJhbSBldmVudCAtIFRoZSBldmVudCB0aGF0IGlzIHBhc3NlZCB0byB0aGUgY2FsbGJhY2suXG4gKi9cbmV4cG9ydCB0eXBlIFN0cmVhbVRleHRPbkVycm9yQ2FsbGJhY2sgPSAoZXZlbnQ6IHtcbiAgZXJyb3I6IHVua25vd247XG59KSA9PiBQcm9taXNlTGlrZTx2b2lkPiB8IHZvaWQ7XG5cbi8qKlxuQ2FsbGJhY2sgdGhhdCBpcyBzZXQgdXNpbmcgdGhlIGBvblN0ZXBGaW5pc2hgIG9wdGlvbi5cblxuQHBhcmFtIHN0ZXBSZXN1bHQgLSBUaGUgcmVzdWx0IG9mIHRoZSBzdGVwLlxuICovXG5leHBvcnQgdHlwZSBTdHJlYW1UZXh0T25TdGVwRmluaXNoQ2FsbGJhY2s8VE9PTFMgZXh0ZW5kcyBUb29sU2V0PiA9IChcbiAgc3RlcFJlc3VsdDogU3RlcFJlc3VsdDxUT09MUz4sXG4pID0+IFByb21pc2VMaWtlPHZvaWQ+IHwgdm9pZDtcblxuLyoqXG5DYWxsYmFjayB0aGF0IGlzIHNldCB1c2luZyB0aGUgYG9uQ2h1bmtgIG9wdGlvbi5cblxuQHBhcmFtIGV2ZW50IC0gVGhlIGV2ZW50IHRoYXQgaXMgcGFzc2VkIHRvIHRoZSBjYWxsYmFjay5cbiAqL1xuZXhwb3J0IHR5cGUgU3RyZWFtVGV4dE9uQ2h1bmtDYWxsYmFjazxUT09MUyBleHRlbmRzIFRvb2xTZXQ+ID0gKGV2ZW50OiB7XG4gIGNodW5rOiBFeHRyYWN0PFxuICAgIFRleHRTdHJlYW1QYXJ0PFRPT0xTPixcbiAgICB7XG4gICAgICB0eXBlOlxuICAgICAgICB8ICd0ZXh0LWRlbHRhJ1xuICAgICAgICB8ICdyZWFzb25pbmctZGVsdGEnXG4gICAgICAgIHwgJ3NvdXJjZSdcbiAgICAgICAgfCAndG9vbC1jYWxsJ1xuICAgICAgICB8ICd0b29sLWlucHV0LXN0YXJ0J1xuICAgICAgICB8ICd0b29sLWlucHV0LWRlbHRhJ1xuICAgICAgICB8ICd0b29sLXJlc3VsdCdcbiAgICAgICAgfCAncmF3JztcbiAgICB9XG4gID47XG59KSA9PiBQcm9taXNlTGlrZTx2b2lkPiB8IHZvaWQ7XG5cbi8qKlxuQ2FsbGJhY2sgdGhhdCBpcyBzZXQgdXNpbmcgdGhlIGBvbkZpbmlzaGAgb3B0aW9uLlxuXG5AcGFyYW0gZXZlbnQgLSBUaGUgZXZlbnQgdGhhdCBpcyBwYXNzZWQgdG8gdGhlIGNhbGxiYWNrLlxuICovXG5leHBvcnQgdHlwZSBTdHJlYW1UZXh0T25GaW5pc2hDYWxsYmFjazxUT09MUyBleHRlbmRzIFRvb2xTZXQ+ID0gKFxuICBldmVudDogU3RlcFJlc3VsdDxUT09MUz4gJiB7XG4gICAgLyoqXG5EZXRhaWxzIGZvciBhbGwgc3RlcHMuXG4gICAqL1xuICAgIHJlYWRvbmx5IHN0ZXBzOiBTdGVwUmVzdWx0PFRPT0xTPltdO1xuXG4gICAgLyoqXG5Ub3RhbCB1c2FnZSBmb3IgYWxsIHN0ZXBzLiBUaGlzIGlzIHRoZSBzdW0gb2YgdGhlIHVzYWdlIG9mIGFsbCBzdGVwcy5cbiAgICAgKi9cbiAgICByZWFkb25seSB0b3RhbFVzYWdlOiBMYW5ndWFnZU1vZGVsVXNhZ2U7XG4gIH0sXG4pID0+IFByb21pc2VMaWtlPHZvaWQ+IHwgdm9pZDtcblxuLyoqXG5DYWxsYmFjayB0aGF0IGlzIHNldCB1c2luZyB0aGUgYG9uQWJvcnRgIG9wdGlvbi5cblxuQHBhcmFtIGV2ZW50IC0gVGhlIGV2ZW50IHRoYXQgaXMgcGFzc2VkIHRvIHRoZSBjYWxsYmFjay5cbiAqL1xuZXhwb3J0IHR5cGUgU3RyZWFtVGV4dE9uQWJvcnRDYWxsYmFjazxUT09MUyBleHRlbmRzIFRvb2xTZXQ+ID0gKGV2ZW50OiB7XG4gIC8qKlxuRGV0YWlscyBmb3IgYWxsIHByZXZpb3VzbHkgZmluaXNoZWQgc3RlcHMuXG4gICAqL1xuICByZWFkb25seSBzdGVwczogU3RlcFJlc3VsdDxUT09MUz5bXTtcbn0pID0+IFByb21pc2VMaWtlPHZvaWQ+IHwgdm9pZDtcblxuLyoqXG5HZW5lcmF0ZSBhIHRleHQgYW5kIGNhbGwgdG9vbHMgZm9yIGEgZ2l2ZW4gcHJvbXB0IHVzaW5nIGEgbGFuZ3VhZ2UgbW9kZWwuXG5cblRoaXMgZnVuY3Rpb24gc3RyZWFtcyB0aGUgb3V0cHV0LiBJZiB5b3UgZG8gbm90IHdhbnQgdG8gc3RyZWFtIHRoZSBvdXRwdXQsIHVzZSBgZ2VuZXJhdGVUZXh0YCBpbnN0ZWFkLlxuXG5AcGFyYW0gbW9kZWwgLSBUaGUgbGFuZ3VhZ2UgbW9kZWwgdG8gdXNlLlxuQHBhcmFtIHRvb2xzIC0gVG9vbHMgdGhhdCBhcmUgYWNjZXNzaWJsZSB0byBhbmQgY2FuIGJlIGNhbGxlZCBieSB0aGUgbW9kZWwuIFRoZSBtb2RlbCBuZWVkcyB0byBzdXBwb3J0IGNhbGxpbmcgdG9vbHMuXG5cbkBwYXJhbSBzeXN0ZW0gLSBBIHN5c3RlbSBtZXNzYWdlIHRoYXQgd2lsbCBiZSBwYXJ0IG9mIHRoZSBwcm9tcHQuXG5AcGFyYW0gcHJvbXB0IC0gQSBzaW1wbGUgdGV4dCBwcm9tcHQuIFlvdSBjYW4gZWl0aGVyIHVzZSBgcHJvbXB0YCBvciBgbWVzc2FnZXNgIGJ1dCBub3QgYm90aC5cbkBwYXJhbSBtZXNzYWdlcyAtIEEgbGlzdCBvZiBtZXNzYWdlcy4gWW91IGNhbiBlaXRoZXIgdXNlIGBwcm9tcHRgIG9yIGBtZXNzYWdlc2AgYnV0IG5vdCBib3RoLlxuXG5AcGFyYW0gbWF4T3V0cHV0VG9rZW5zIC0gTWF4aW11bSBudW1iZXIgb2YgdG9rZW5zIHRvIGdlbmVyYXRlLlxuQHBhcmFtIHRlbXBlcmF0dXJlIC0gVGVtcGVyYXR1cmUgc2V0dGluZy5cblRoZSB2YWx1ZSBpcyBwYXNzZWQgdGhyb3VnaCB0byB0aGUgcHJvdmlkZXIuIFRoZSByYW5nZSBkZXBlbmRzIG9uIHRoZSBwcm92aWRlciBhbmQgbW9kZWwuXG5JdCBpcyByZWNvbW1lbmRlZCB0byBzZXQgZWl0aGVyIGB0ZW1wZXJhdHVyZWAgb3IgYHRvcFBgLCBidXQgbm90IGJvdGguXG5AcGFyYW0gdG9wUCAtIE51Y2xldXMgc2FtcGxpbmcuXG5UaGUgdmFsdWUgaXMgcGFzc2VkIHRocm91Z2ggdG8gdGhlIHByb3ZpZGVyLiBUaGUgcmFuZ2UgZGVwZW5kcyBvbiB0aGUgcHJvdmlkZXIgYW5kIG1vZGVsLlxuSXQgaXMgcmVjb21tZW5kZWQgdG8gc2V0IGVpdGhlciBgdGVtcGVyYXR1cmVgIG9yIGB0b3BQYCwgYnV0IG5vdCBib3RoLlxuQHBhcmFtIHRvcEsgLSBPbmx5IHNhbXBsZSBmcm9tIHRoZSB0b3AgSyBvcHRpb25zIGZvciBlYWNoIHN1YnNlcXVlbnQgdG9rZW4uXG5Vc2VkIHRvIHJlbW92ZSBcImxvbmcgdGFpbFwiIGxvdyBwcm9iYWJpbGl0eSByZXNwb25zZXMuXG5SZWNvbW1lbmRlZCBmb3IgYWR2YW5jZWQgdXNlIGNhc2VzIG9ubHkuIFlvdSB1c3VhbGx5IG9ubHkgbmVlZCB0byB1c2UgdGVtcGVyYXR1cmUuXG5AcGFyYW0gcHJlc2VuY2VQZW5hbHR5IC0gUHJlc2VuY2UgcGVuYWx0eSBzZXR0aW5nLlxuSXQgYWZmZWN0cyB0aGUgbGlrZWxpaG9vZCBvZiB0aGUgbW9kZWwgdG8gcmVwZWF0IGluZm9ybWF0aW9uIHRoYXQgaXMgYWxyZWFkeSBpbiB0aGUgcHJvbXB0LlxuVGhlIHZhbHVlIGlzIHBhc3NlZCB0aHJvdWdoIHRvIHRoZSBwcm92aWRlci4gVGhlIHJhbmdlIGRlcGVuZHMgb24gdGhlIHByb3ZpZGVyIGFuZCBtb2RlbC5cbkBwYXJhbSBmcmVxdWVuY3lQZW5hbHR5IC0gRnJlcXVlbmN5IHBlbmFsdHkgc2V0dGluZy5cbkl0IGFmZmVjdHMgdGhlIGxpa2VsaWhvb2Qgb2YgdGhlIG1vZGVsIHRvIHJlcGVhdGVkbHkgdXNlIHRoZSBzYW1lIHdvcmRzIG9yIHBocmFzZXMuXG5UaGUgdmFsdWUgaXMgcGFzc2VkIHRocm91Z2ggdG8gdGhlIHByb3ZpZGVyLiBUaGUgcmFuZ2UgZGVwZW5kcyBvbiB0aGUgcHJvdmlkZXIgYW5kIG1vZGVsLlxuQHBhcmFtIHN0b3BTZXF1ZW5jZXMgLSBTdG9wIHNlcXVlbmNlcy5cbklmIHNldCwgdGhlIG1vZGVsIHdpbGwgc3RvcCBnZW5lcmF0aW5nIHRleHQgd2hlbiBvbmUgb2YgdGhlIHN0b3Agc2VxdWVuY2VzIGlzIGdlbmVyYXRlZC5cbkBwYXJhbSBzZWVkIC0gVGhlIHNlZWQgKGludGVnZXIpIHRvIHVzZSBmb3IgcmFuZG9tIHNhbXBsaW5nLlxuSWYgc2V0IGFuZCBzdXBwb3J0ZWQgYnkgdGhlIG1vZGVsLCBjYWxscyB3aWxsIGdlbmVyYXRlIGRldGVybWluaXN0aWMgcmVzdWx0cy5cblxuQHBhcmFtIG1heFJldHJpZXMgLSBNYXhpbXVtIG51bWJlciBvZiByZXRyaWVzLiBTZXQgdG8gMCB0byBkaXNhYmxlIHJldHJpZXMuIERlZmF1bHQ6IDIuXG5AcGFyYW0gYWJvcnRTaWduYWwgLSBBbiBvcHRpb25hbCBhYm9ydCBzaWduYWwgdGhhdCBjYW4gYmUgdXNlZCB0byBjYW5jZWwgdGhlIGNhbGwuXG5AcGFyYW0gaGVhZGVycyAtIEFkZGl0aW9uYWwgSFRUUCBoZWFkZXJzIHRvIGJlIHNlbnQgd2l0aCB0aGUgcmVxdWVzdC4gT25seSBhcHBsaWNhYmxlIGZvciBIVFRQLWJhc2VkIHByb3ZpZGVycy5cblxuQHBhcmFtIG1heFN0ZXBzIC0gTWF4aW11bSBudW1iZXIgb2Ygc2VxdWVudGlhbCBMTE0gY2FsbHMgKHN0ZXBzKSwgZS5nLiB3aGVuIHlvdSB1c2UgdG9vbCBjYWxscy5cblxuQHBhcmFtIG9uQ2h1bmsgLSBDYWxsYmFjayB0aGF0IGlzIGNhbGxlZCBmb3IgZWFjaCBjaHVuayBvZiB0aGUgc3RyZWFtLiBUaGUgc3RyZWFtIHByb2Nlc3Npbmcgd2lsbCBwYXVzZSB1bnRpbCB0aGUgY2FsbGJhY2sgcHJvbWlzZSBpcyByZXNvbHZlZC5cbkBwYXJhbSBvbkVycm9yIC0gQ2FsbGJhY2sgdGhhdCBpcyBjYWxsZWQgd2hlbiBhbiBlcnJvciBvY2N1cnMgZHVyaW5nIHN0cmVhbWluZy4gWW91IGNhbiB1c2UgaXQgdG8gbG9nIGVycm9ycy5cbkBwYXJhbSBvblN0ZXBGaW5pc2ggLSBDYWxsYmFjayB0aGF0IGlzIGNhbGxlZCB3aGVuIGVhY2ggc3RlcCAoTExNIGNhbGwpIGlzIGZpbmlzaGVkLCBpbmNsdWRpbmcgaW50ZXJtZWRpYXRlIHN0ZXBzLlxuQHBhcmFtIG9uRmluaXNoIC0gQ2FsbGJhY2sgdGhhdCBpcyBjYWxsZWQgd2hlbiB0aGUgTExNIHJlc3BvbnNlIGFuZCBhbGwgcmVxdWVzdCB0b29sIGV4ZWN1dGlvbnNcbihmb3IgdG9vbHMgdGhhdCBoYXZlIGFuIGBleGVjdXRlYCBmdW5jdGlvbikgYXJlIGZpbmlzaGVkLlxuXG5AcmV0dXJuXG5BIHJlc3VsdCBvYmplY3QgZm9yIGFjY2Vzc2luZyBkaWZmZXJlbnQgc3RyZWFtIHR5cGVzIGFuZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc3RyZWFtVGV4dDxcbiAgVE9PTFMgZXh0ZW5kcyBUb29sU2V0LFxuICBPVVRQVVQgPSBuZXZlcixcbiAgUEFSVElBTF9PVVRQVVQgPSBuZXZlcixcbj4oe1xuICBtb2RlbCxcbiAgdG9vbHMsXG4gIHRvb2xDaG9pY2UsXG4gIHN5c3RlbSxcbiAgcHJvbXB0LFxuICBtZXNzYWdlcyxcbiAgbWF4UmV0cmllcyxcbiAgYWJvcnRTaWduYWwsXG4gIGhlYWRlcnMsXG4gIHN0b3BXaGVuID0gc3RlcENvdW50SXMoMSksXG4gIGV4cGVyaW1lbnRhbF9vdXRwdXQ6IG91dHB1dCxcbiAgZXhwZXJpbWVudGFsX3RlbGVtZXRyeTogdGVsZW1ldHJ5LFxuICBwcmVwYXJlU3RlcCxcbiAgcHJvdmlkZXJPcHRpb25zLFxuICBleHBlcmltZW50YWxfYWN0aXZlVG9vbHMsXG4gIGFjdGl2ZVRvb2xzID0gZXhwZXJpbWVudGFsX2FjdGl2ZVRvb2xzLFxuICBleHBlcmltZW50YWxfcmVwYWlyVG9vbENhbGw6IHJlcGFpclRvb2xDYWxsLFxuICBleHBlcmltZW50YWxfdHJhbnNmb3JtOiB0cmFuc2Zvcm0sXG4gIGV4cGVyaW1lbnRhbF9kb3dubG9hZDogZG93bmxvYWQsXG4gIGluY2x1ZGVSYXdDaHVua3MgPSBmYWxzZSxcbiAgb25DaHVuayxcbiAgb25FcnJvciA9ICh7IGVycm9yIH0pID0+IHtcbiAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgfSxcbiAgb25GaW5pc2gsXG4gIG9uQWJvcnQsXG4gIG9uU3RlcEZpbmlzaCxcbiAgZXhwZXJpbWVudGFsX2NvbnRleHQsXG4gIF9pbnRlcm5hbDoge1xuICAgIG5vdyA9IG9yaWdpbmFsTm93LFxuICAgIGdlbmVyYXRlSWQgPSBvcmlnaW5hbEdlbmVyYXRlSWQsXG4gICAgY3VycmVudERhdGUgPSAoKSA9PiBuZXcgRGF0ZSgpLFxuICB9ID0ge30sXG4gIC4uLnNldHRpbmdzXG59OiBDYWxsU2V0dGluZ3MgJlxuICBQcm9tcHQgJiB7XG4gICAgLyoqXG5UaGUgbGFuZ3VhZ2UgbW9kZWwgdG8gdXNlLlxuICAgICAqL1xuICAgIG1vZGVsOiBMYW5ndWFnZU1vZGVsO1xuXG4gICAgLyoqXG5UaGUgdG9vbHMgdGhhdCB0aGUgbW9kZWwgY2FuIGNhbGwuIFRoZSBtb2RlbCBuZWVkcyB0byBzdXBwb3J0IGNhbGxpbmcgdG9vbHMuXG4gICAgKi9cbiAgICB0b29scz86IFRPT0xTO1xuXG4gICAgLyoqXG5UaGUgdG9vbCBjaG9pY2Ugc3RyYXRlZ3kuIERlZmF1bHQ6ICdhdXRvJy5cbiAgICAgKi9cbiAgICB0b29sQ2hvaWNlPzogVG9vbENob2ljZTxUT09MUz47XG5cbiAgICAvKipcbkNvbmRpdGlvbiBmb3Igc3RvcHBpbmcgdGhlIGdlbmVyYXRpb24gd2hlbiB0aGVyZSBhcmUgdG9vbCByZXN1bHRzIGluIHRoZSBsYXN0IHN0ZXAuXG5XaGVuIHRoZSBjb25kaXRpb24gaXMgYW4gYXJyYXksIGFueSBvZiB0aGUgY29uZGl0aW9ucyBjYW4gYmUgbWV0IHRvIHN0b3AgdGhlIGdlbmVyYXRpb24uXG5cbkBkZWZhdWx0IHN0ZXBDb3VudElzKDEpXG4gICAgICovXG4gICAgc3RvcFdoZW4/OlxuICAgICAgfCBTdG9wQ29uZGl0aW9uPE5vSW5mZXI8VE9PTFM+PlxuICAgICAgfCBBcnJheTxTdG9wQ29uZGl0aW9uPE5vSW5mZXI8VE9PTFM+Pj47XG5cbiAgICAvKipcbk9wdGlvbmFsIHRlbGVtZXRyeSBjb25maWd1cmF0aW9uIChleHBlcmltZW50YWwpLlxuICAgICAqL1xuICAgIGV4cGVyaW1lbnRhbF90ZWxlbWV0cnk/OiBUZWxlbWV0cnlTZXR0aW5ncztcblxuICAgIC8qKlxuQWRkaXRpb25hbCBwcm92aWRlci1zcGVjaWZpYyBvcHRpb25zLiBUaGV5IGFyZSBwYXNzZWQgdGhyb3VnaFxudG8gdGhlIHByb3ZpZGVyIGZyb20gdGhlIEFJIFNESyBhbmQgZW5hYmxlIHByb3ZpZGVyLXNwZWNpZmljXG5mdW5jdGlvbmFsaXR5IHRoYXQgY2FuIGJlIGZ1bGx5IGVuY2Fwc3VsYXRlZCBpbiB0aGUgcHJvdmlkZXIuXG4gKi9cbiAgICBwcm92aWRlck9wdGlvbnM/OiBQcm92aWRlck9wdGlvbnM7XG5cbiAgICAvKipcbiAgICAgKiBAZGVwcmVjYXRlZCBVc2UgYGFjdGl2ZVRvb2xzYCBpbnN0ZWFkLlxuICAgICAqL1xuICAgIGV4cGVyaW1lbnRhbF9hY3RpdmVUb29scz86IEFycmF5PGtleW9mIE5vSW5mZXI8VE9PTFM+PjtcblxuICAgIC8qKlxuICAgTGltaXRzIHRoZSB0b29scyB0aGF0IGFyZSBhdmFpbGFibGUgZm9yIHRoZSBtb2RlbCB0byBjYWxsIHdpdGhvdXRcbiAgIGNoYW5naW5nIHRoZSB0b29sIGNhbGwgYW5kIHJlc3VsdCB0eXBlcyBpbiB0aGUgcmVzdWx0LlxuICAgICAgICAqL1xuICAgIGFjdGl2ZVRvb2xzPzogQXJyYXk8a2V5b2YgTm9JbmZlcjxUT09MUz4+O1xuXG4gICAgLyoqXG5PcHRpb25hbCBzcGVjaWZpY2F0aW9uIGZvciBwYXJzaW5nIHN0cnVjdHVyZWQgb3V0cHV0cyBmcm9tIHRoZSBMTE0gcmVzcG9uc2UuXG4gICAgICovXG4gICAgZXhwZXJpbWVudGFsX291dHB1dD86IE91dHB1dDxPVVRQVVQsIFBBUlRJQUxfT1VUUFVUPjtcblxuICAgIC8qKlxuT3B0aW9uYWwgZnVuY3Rpb24gdGhhdCB5b3UgY2FuIHVzZSB0byBwcm92aWRlIGRpZmZlcmVudCBzZXR0aW5ncyBmb3IgYSBzdGVwLlxuXG5AcGFyYW0gb3B0aW9ucyAtIFRoZSBvcHRpb25zIGZvciB0aGUgc3RlcC5cbkBwYXJhbSBvcHRpb25zLnN0ZXBzIC0gVGhlIHN0ZXBzIHRoYXQgaGF2ZSBiZWVuIGV4ZWN1dGVkIHNvIGZhci5cbkBwYXJhbSBvcHRpb25zLnN0ZXBOdW1iZXIgLSBUaGUgbnVtYmVyIG9mIHRoZSBzdGVwIHRoYXQgaXMgYmVpbmcgZXhlY3V0ZWQuXG5AcGFyYW0gb3B0aW9ucy5tb2RlbCAtIFRoZSBtb2RlbCB0aGF0IGlzIGJlaW5nIHVzZWQuXG5cbkByZXR1cm5zIEFuIG9iamVjdCB0aGF0IGNvbnRhaW5zIHRoZSBzZXR0aW5ncyBmb3IgdGhlIHN0ZXAuXG5JZiB5b3UgcmV0dXJuIHVuZGVmaW5lZCAob3IgZm9yIHVuZGVmaW5lZCBzZXR0aW5ncyksIHRoZSBzZXR0aW5ncyBmcm9tIHRoZSBvdXRlciBsZXZlbCB3aWxsIGJlIHVzZWQuXG4gICAgKi9cbiAgICBwcmVwYXJlU3RlcD86IFByZXBhcmVTdGVwRnVuY3Rpb248Tm9JbmZlcjxUT09MUz4+O1xuXG4gICAgLyoqXG5BIGZ1bmN0aW9uIHRoYXQgYXR0ZW1wdHMgdG8gcmVwYWlyIGEgdG9vbCBjYWxsIHRoYXQgZmFpbGVkIHRvIHBhcnNlLlxuICAgICAqL1xuICAgIGV4cGVyaW1lbnRhbF9yZXBhaXJUb29sQ2FsbD86IFRvb2xDYWxsUmVwYWlyRnVuY3Rpb248VE9PTFM+O1xuXG4gICAgLyoqXG5PcHRpb25hbCBzdHJlYW0gdHJhbnNmb3JtYXRpb25zLlxuVGhleSBhcmUgYXBwbGllZCBpbiB0aGUgb3JkZXIgdGhleSBhcmUgcHJvdmlkZWQuXG5UaGUgc3RyZWFtIHRyYW5zZm9ybWF0aW9ucyBtdXN0IG1haW50YWluIHRoZSBzdHJlYW0gc3RydWN0dXJlIGZvciBzdHJlYW1UZXh0IHRvIHdvcmsgY29ycmVjdGx5LlxuICAgICAqL1xuICAgIGV4cGVyaW1lbnRhbF90cmFuc2Zvcm0/OlxuICAgICAgfCBTdHJlYW1UZXh0VHJhbnNmb3JtPFRPT0xTPlxuICAgICAgfCBBcnJheTxTdHJlYW1UZXh0VHJhbnNmb3JtPFRPT0xTPj47XG5cbiAgICAvKipcbkN1c3RvbSBkb3dubG9hZCBmdW5jdGlvbiB0byB1c2UgZm9yIFVSTHMuXG5cbkJ5IGRlZmF1bHQsIGZpbGVzIGFyZSBkb3dubG9hZGVkIGlmIHRoZSBtb2RlbCBkb2VzIG5vdCBzdXBwb3J0IHRoZSBVUkwgZm9yIHRoZSBnaXZlbiBtZWRpYSB0eXBlLlxuICAgICAqL1xuICAgIGV4cGVyaW1lbnRhbF9kb3dubG9hZD86IERvd25sb2FkRnVuY3Rpb24gfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbldoZXRoZXIgdG8gaW5jbHVkZSByYXcgY2h1bmtzIGZyb20gdGhlIHByb3ZpZGVyIGluIHRoZSBzdHJlYW0uXG5XaGVuIGVuYWJsZWQsIHlvdSB3aWxsIHJlY2VpdmUgcmF3IGNodW5rcyB3aXRoIHR5cGUgJ3JhdycgdGhhdCBjb250YWluIHRoZSB1bnByb2Nlc3NlZCBkYXRhIGZyb20gdGhlIHByb3ZpZGVyLlxuVGhpcyBhbGxvd3MgYWNjZXNzIHRvIGN1dHRpbmctZWRnZSBwcm92aWRlciBmZWF0dXJlcyBub3QgeWV0IHdyYXBwZWQgYnkgdGhlIEFJIFNESy5cbkRlZmF1bHRzIHRvIGZhbHNlLlxuICAgICAqL1xuICAgIGluY2x1ZGVSYXdDaHVua3M/OiBib29sZWFuO1xuXG4gICAgLyoqXG5DYWxsYmFjayB0aGF0IGlzIGNhbGxlZCBmb3IgZWFjaCBjaHVuayBvZiB0aGUgc3RyZWFtLlxuVGhlIHN0cmVhbSBwcm9jZXNzaW5nIHdpbGwgcGF1c2UgdW50aWwgdGhlIGNhbGxiYWNrIHByb21pc2UgaXMgcmVzb2x2ZWQuXG4gICAgICovXG4gICAgb25DaHVuaz86IFN0cmVhbVRleHRPbkNodW5rQ2FsbGJhY2s8VE9PTFM+O1xuXG4gICAgLyoqXG5DYWxsYmFjayB0aGF0IGlzIGludm9rZWQgd2hlbiBhbiBlcnJvciBvY2N1cnMgZHVyaW5nIHN0cmVhbWluZy5cbllvdSBjYW4gdXNlIGl0IHRvIGxvZyBlcnJvcnMuXG5UaGUgc3RyZWFtIHByb2Nlc3Npbmcgd2lsbCBwYXVzZSB1bnRpbCB0aGUgY2FsbGJhY2sgcHJvbWlzZSBpcyByZXNvbHZlZC5cbiAgICAgKi9cbiAgICBvbkVycm9yPzogU3RyZWFtVGV4dE9uRXJyb3JDYWxsYmFjaztcblxuICAgIC8qKlxuQ2FsbGJhY2sgdGhhdCBpcyBjYWxsZWQgd2hlbiB0aGUgTExNIHJlc3BvbnNlIGFuZCBhbGwgcmVxdWVzdCB0b29sIGV4ZWN1dGlvbnNcbihmb3IgdG9vbHMgdGhhdCBoYXZlIGFuIGBleGVjdXRlYCBmdW5jdGlvbikgYXJlIGZpbmlzaGVkLlxuXG5UaGUgdXNhZ2UgaXMgdGhlIGNvbWJpbmVkIHVzYWdlIG9mIGFsbCBzdGVwcy5cbiAgICAgKi9cbiAgICBvbkZpbmlzaD86IFN0cmVhbVRleHRPbkZpbmlzaENhbGxiYWNrPFRPT0xTPjtcblxuICAgIG9uQWJvcnQ/OiBTdHJlYW1UZXh0T25BYm9ydENhbGxiYWNrPFRPT0xTPjtcblxuICAgIC8qKlxuQ2FsbGJhY2sgdGhhdCBpcyBjYWxsZWQgd2hlbiBlYWNoIHN0ZXAgKExMTSBjYWxsKSBpcyBmaW5pc2hlZCwgaW5jbHVkaW5nIGludGVybWVkaWF0ZSBzdGVwcy5cbiAgICAqL1xuICAgIG9uU3RlcEZpbmlzaD86IFN0cmVhbVRleHRPblN0ZXBGaW5pc2hDYWxsYmFjazxUT09MUz47XG5cbiAgICAvKipcbiAgICAgKiBDb250ZXh0IHRoYXQgaXMgcGFzc2VkIGludG8gdG9vbCBleGVjdXRpb24uXG4gICAgICpcbiAgICAgKiBFeHBlcmltZW50YWwgKGNhbiBicmVhayBpbiBwYXRjaCByZWxlYXNlcykuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdCB1bmRlZmluZWRcbiAgICAgKi9cbiAgICBleHBlcmltZW50YWxfY29udGV4dD86IHVua25vd247XG5cbiAgICAvKipcbkludGVybmFsLiBGb3IgdGVzdCB1c2Ugb25seS4gTWF5IGNoYW5nZSB3aXRob3V0IG5vdGljZS5cbiAgICAgKi9cbiAgICBfaW50ZXJuYWw/OiB7XG4gICAgICBub3c/OiAoKSA9PiBudW1iZXI7XG4gICAgICBnZW5lcmF0ZUlkPzogSWRHZW5lcmF0b3I7XG4gICAgICBjdXJyZW50RGF0ZT86ICgpID0+IERhdGU7XG4gICAgfTtcbiAgfSk6IFN0cmVhbVRleHRSZXN1bHQ8VE9PTFMsIFBBUlRJQUxfT1VUUFVUPiB7XG4gIHJldHVybiBuZXcgRGVmYXVsdFN0cmVhbVRleHRSZXN1bHQ8VE9PTFMsIE9VVFBVVCwgUEFSVElBTF9PVVRQVVQ+KHtcbiAgICBtb2RlbDogcmVzb2x2ZUxhbmd1YWdlTW9kZWwobW9kZWwpLFxuICAgIHRlbGVtZXRyeSxcbiAgICBoZWFkZXJzLFxuICAgIHNldHRpbmdzLFxuICAgIG1heFJldHJpZXMsXG4gICAgYWJvcnRTaWduYWwsXG4gICAgc3lzdGVtLFxuICAgIHByb21wdCxcbiAgICBtZXNzYWdlcyxcbiAgICB0b29scyxcbiAgICB0b29sQ2hvaWNlLFxuICAgIHRyYW5zZm9ybXM6IGFzQXJyYXkodHJhbnNmb3JtKSxcbiAgICBhY3RpdmVUb29scyxcbiAgICByZXBhaXJUb29sQ2FsbCxcbiAgICBzdG9wQ29uZGl0aW9uczogYXNBcnJheShzdG9wV2hlbiksXG4gICAgb3V0cHV0LFxuICAgIHByb3ZpZGVyT3B0aW9ucyxcbiAgICBwcmVwYXJlU3RlcCxcbiAgICBpbmNsdWRlUmF3Q2h1bmtzLFxuICAgIG9uQ2h1bmssXG4gICAgb25FcnJvcixcbiAgICBvbkZpbmlzaCxcbiAgICBvbkFib3J0LFxuICAgIG9uU3RlcEZpbmlzaCxcbiAgICBub3csXG4gICAgY3VycmVudERhdGUsXG4gICAgZ2VuZXJhdGVJZCxcbiAgICBleHBlcmltZW50YWxfY29udGV4dCxcbiAgICBkb3dubG9hZCxcbiAgfSk7XG59XG5cbnR5cGUgRW5yaWNoZWRTdHJlYW1QYXJ0PFRPT0xTIGV4dGVuZHMgVG9vbFNldCwgUEFSVElBTF9PVVRQVVQ+ID0ge1xuICBwYXJ0OiBUZXh0U3RyZWFtUGFydDxUT09MUz47XG4gIHBhcnRpYWxPdXRwdXQ6IFBBUlRJQUxfT1VUUFVUIHwgdW5kZWZpbmVkO1xufTtcblxuZnVuY3Rpb24gY3JlYXRlT3V0cHV0VHJhbnNmb3JtU3RyZWFtPFxuICBUT09MUyBleHRlbmRzIFRvb2xTZXQsXG4gIE9VVFBVVCxcbiAgUEFSVElBTF9PVVRQVVQsXG4+KFxuICBvdXRwdXQ6IE91dHB1dDxPVVRQVVQsIFBBUlRJQUxfT1VUUFVUPiB8IHVuZGVmaW5lZCxcbik6IFRyYW5zZm9ybVN0cmVhbTxcbiAgVGV4dFN0cmVhbVBhcnQ8VE9PTFM+LFxuICBFbnJpY2hlZFN0cmVhbVBhcnQ8VE9PTFMsIFBBUlRJQUxfT1VUUFVUPlxuPiB7XG4gIGlmICghb3V0cHV0KSB7XG4gICAgcmV0dXJuIG5ldyBUcmFuc2Zvcm1TdHJlYW08XG4gICAgICBUZXh0U3RyZWFtUGFydDxUT09MUz4sXG4gICAgICBFbnJpY2hlZFN0cmVhbVBhcnQ8VE9PTFMsIFBBUlRJQUxfT1VUUFVUPlxuICAgID4oe1xuICAgICAgdHJhbnNmb3JtKGNodW5rLCBjb250cm9sbGVyKSB7XG4gICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7IHBhcnQ6IGNodW5rLCBwYXJ0aWFsT3V0cHV0OiB1bmRlZmluZWQgfSk7XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgbGV0IGZpcnN0VGV4dENodW5rSWQ6IHN0cmluZyB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgbGV0IHRleHQgPSAnJztcbiAgbGV0IHRleHRDaHVuayA9ICcnO1xuICBsZXQgbGFzdFB1Ymxpc2hlZEpzb24gPSAnJztcblxuICBmdW5jdGlvbiBwdWJsaXNoVGV4dENodW5rKHtcbiAgICBjb250cm9sbGVyLFxuICAgIHBhcnRpYWxPdXRwdXQgPSB1bmRlZmluZWQsXG4gIH06IHtcbiAgICBjb250cm9sbGVyOiBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlcjxcbiAgICAgIEVucmljaGVkU3RyZWFtUGFydDxUT09MUywgUEFSVElBTF9PVVRQVVQ+XG4gICAgPjtcbiAgICBwYXJ0aWFsT3V0cHV0PzogUEFSVElBTF9PVVRQVVQ7XG4gIH0pIHtcbiAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgcGFydDoge1xuICAgICAgICB0eXBlOiAndGV4dC1kZWx0YScsXG4gICAgICAgIGlkOiBmaXJzdFRleHRDaHVua0lkISxcbiAgICAgICAgdGV4dDogdGV4dENodW5rLFxuICAgICAgfSxcbiAgICAgIHBhcnRpYWxPdXRwdXQsXG4gICAgfSk7XG4gICAgdGV4dENodW5rID0gJyc7XG4gIH1cblxuICByZXR1cm4gbmV3IFRyYW5zZm9ybVN0cmVhbTxcbiAgICBUZXh0U3RyZWFtUGFydDxUT09MUz4sXG4gICAgRW5yaWNoZWRTdHJlYW1QYXJ0PFRPT0xTLCBQQVJUSUFMX09VVFBVVD5cbiAgPih7XG4gICAgYXN5bmMgdHJhbnNmb3JtKGNodW5rLCBjb250cm9sbGVyKSB7XG4gICAgICAvLyBlbnN1cmUgdGhhdCB3ZSBwdWJsaXNoIHRoZSBsYXN0IHRleHQgY2h1bmsgYmVmb3JlIHRoZSBzdGVwIGZpbmlzaDpcbiAgICAgIGlmIChjaHVuay50eXBlID09PSAnZmluaXNoLXN0ZXAnICYmIHRleHRDaHVuay5sZW5ndGggPiAwKSB7XG4gICAgICAgIHB1Ymxpc2hUZXh0Q2h1bmsoeyBjb250cm9sbGVyIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIGNodW5rLnR5cGUgIT09ICd0ZXh0LWRlbHRhJyAmJlxuICAgICAgICBjaHVuay50eXBlICE9PSAndGV4dC1zdGFydCcgJiZcbiAgICAgICAgY2h1bmsudHlwZSAhPT0gJ3RleHQtZW5kJ1xuICAgICAgKSB7XG4gICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7IHBhcnQ6IGNodW5rLCBwYXJ0aWFsT3V0cHV0OiB1bmRlZmluZWQgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gd2UgaGF2ZSB0byBwaWNrIGEgdGV4dCBjaHVuayB3aGljaCBjb250YWlucyB0aGUganNvbiB0ZXh0XG4gICAgICAvLyBzaW5jZSB3ZSBhcmUgc3RyZWFtaW5nLCB3ZSBoYXZlIHRvIHBpY2sgdGhlIGZpcnN0IHRleHQgY2h1bmtcbiAgICAgIGlmIChmaXJzdFRleHRDaHVua0lkID09IG51bGwpIHtcbiAgICAgICAgZmlyc3RUZXh0Q2h1bmtJZCA9IGNodW5rLmlkO1xuICAgICAgfSBlbHNlIGlmIChjaHVuay5pZCAhPT0gZmlyc3RUZXh0Q2h1bmtJZCkge1xuICAgICAgICBjb250cm9sbGVyLmVucXVldWUoeyBwYXJ0OiBjaHVuaywgcGFydGlhbE91dHB1dDogdW5kZWZpbmVkIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChjaHVuay50eXBlID09PSAndGV4dC1zdGFydCcpIHtcbiAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHsgcGFydDogY2h1bmssIHBhcnRpYWxPdXRwdXQ6IHVuZGVmaW5lZCB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoY2h1bmsudHlwZSA9PT0gJ3RleHQtZW5kJykge1xuICAgICAgICBpZiAodGV4dENodW5rLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBwdWJsaXNoVGV4dENodW5rKHsgY29udHJvbGxlciB9KTtcbiAgICAgICAgfVxuICAgICAgICBjb250cm9sbGVyLmVucXVldWUoeyBwYXJ0OiBjaHVuaywgcGFydGlhbE91dHB1dDogdW5kZWZpbmVkIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRleHQgKz0gY2h1bmsudGV4dDtcbiAgICAgIHRleHRDaHVuayArPSBjaHVuay50ZXh0O1xuXG4gICAgICAvLyBvbmx5IHB1Ymxpc2ggaWYgcGFydGlhbCBqc29uIGNhbiBiZSBwYXJzZWQ6XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBvdXRwdXQucGFyc2VQYXJ0aWFsKHsgdGV4dCB9KTtcbiAgICAgIGlmIChyZXN1bHQgIT0gbnVsbCkge1xuICAgICAgICAvLyBvbmx5IHNlbmQgbmV3IGpzb24gaWYgaXQgaGFzIGNoYW5nZWQ6XG4gICAgICAgIGNvbnN0IGN1cnJlbnRKc29uID0gSlNPTi5zdHJpbmdpZnkocmVzdWx0LnBhcnRpYWwpO1xuICAgICAgICBpZiAoY3VycmVudEpzb24gIT09IGxhc3RQdWJsaXNoZWRKc29uKSB7XG4gICAgICAgICAgcHVibGlzaFRleHRDaHVuayh7IGNvbnRyb2xsZXIsIHBhcnRpYWxPdXRwdXQ6IHJlc3VsdC5wYXJ0aWFsIH0pO1xuICAgICAgICAgIGxhc3RQdWJsaXNoZWRKc29uID0gY3VycmVudEpzb247XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuICB9KTtcbn1cblxuY2xhc3MgRGVmYXVsdFN0cmVhbVRleHRSZXN1bHQ8VE9PTFMgZXh0ZW5kcyBUb29sU2V0LCBPVVRQVVQsIFBBUlRJQUxfT1VUUFVUPlxuICBpbXBsZW1lbnRzIFN0cmVhbVRleHRSZXN1bHQ8VE9PTFMsIFBBUlRJQUxfT1VUUFVUPlxue1xuICBwcml2YXRlIHJlYWRvbmx5IF90b3RhbFVzYWdlID0gbmV3IERlbGF5ZWRQcm9taXNlPFxuICAgIEF3YWl0ZWQ8U3RyZWFtVGV4dFJlc3VsdDxUT09MUywgUEFSVElBTF9PVVRQVVQ+Wyd1c2FnZSddPlxuICA+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2ZpbmlzaFJlYXNvbiA9IG5ldyBEZWxheWVkUHJvbWlzZTxcbiAgICBBd2FpdGVkPFN0cmVhbVRleHRSZXN1bHQ8VE9PTFMsIFBBUlRJQUxfT1VUUFVUPlsnZmluaXNoUmVhc29uJ10+XG4gID4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfc3RlcHMgPSBuZXcgRGVsYXllZFByb21pc2U8XG4gICAgQXdhaXRlZDxTdHJlYW1UZXh0UmVzdWx0PFRPT0xTLCBQQVJUSUFMX09VVFBVVD5bJ3N0ZXBzJ10+XG4gID4oKTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGFkZFN0cmVhbTogKFxuICAgIHN0cmVhbTogUmVhZGFibGVTdHJlYW08VGV4dFN0cmVhbVBhcnQ8VE9PTFM+PixcbiAgKSA9PiB2b2lkO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgY2xvc2VTdHJlYW06ICgpID0+IHZvaWQ7XG5cbiAgcHJpdmF0ZSBiYXNlU3RyZWFtOiBSZWFkYWJsZVN0cmVhbTxFbnJpY2hlZFN0cmVhbVBhcnQ8VE9PTFMsIFBBUlRJQUxfT1VUUFVUPj47XG5cbiAgcHJpdmF0ZSBvdXRwdXQ6IE91dHB1dDxPVVRQVVQsIFBBUlRJQUxfT1VUUFVUPiB8IHVuZGVmaW5lZDtcblxuICBwcml2YXRlIGluY2x1ZGVSYXdDaHVua3M6IGJvb2xlYW47XG5cbiAgcHJpdmF0ZSB0b29sczogVE9PTFMgfCB1bmRlZmluZWQ7XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIG1vZGVsLFxuICAgIHRlbGVtZXRyeSxcbiAgICBoZWFkZXJzLFxuICAgIHNldHRpbmdzLFxuICAgIG1heFJldHJpZXM6IG1heFJldHJpZXNBcmcsXG4gICAgYWJvcnRTaWduYWwsXG4gICAgc3lzdGVtLFxuICAgIHByb21wdCxcbiAgICBtZXNzYWdlcyxcbiAgICB0b29scyxcbiAgICB0b29sQ2hvaWNlLFxuICAgIHRyYW5zZm9ybXMsXG4gICAgYWN0aXZlVG9vbHMsXG4gICAgcmVwYWlyVG9vbENhbGwsXG4gICAgc3RvcENvbmRpdGlvbnMsXG4gICAgb3V0cHV0LFxuICAgIHByb3ZpZGVyT3B0aW9ucyxcbiAgICBwcmVwYXJlU3RlcCxcbiAgICBpbmNsdWRlUmF3Q2h1bmtzLFxuICAgIG5vdyxcbiAgICBjdXJyZW50RGF0ZSxcbiAgICBnZW5lcmF0ZUlkLFxuICAgIG9uQ2h1bmssXG4gICAgb25FcnJvcixcbiAgICBvbkZpbmlzaCxcbiAgICBvbkFib3J0LFxuICAgIG9uU3RlcEZpbmlzaCxcbiAgICBleHBlcmltZW50YWxfY29udGV4dCxcbiAgICBkb3dubG9hZCxcbiAgfToge1xuICAgIG1vZGVsOiBMYW5ndWFnZU1vZGVsVjI7XG4gICAgdGVsZW1ldHJ5OiBUZWxlbWV0cnlTZXR0aW5ncyB8IHVuZGVmaW5lZDtcbiAgICBoZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+IHwgdW5kZWZpbmVkO1xuICAgIHNldHRpbmdzOiBPbWl0PENhbGxTZXR0aW5ncywgJ2Fib3J0U2lnbmFsJyB8ICdoZWFkZXJzJz47XG4gICAgbWF4UmV0cmllczogbnVtYmVyIHwgdW5kZWZpbmVkO1xuICAgIGFib3J0U2lnbmFsOiBBYm9ydFNpZ25hbCB8IHVuZGVmaW5lZDtcbiAgICBzeXN0ZW06IFByb21wdFsnc3lzdGVtJ107XG4gICAgcHJvbXB0OiBQcm9tcHRbJ3Byb21wdCddO1xuICAgIG1lc3NhZ2VzOiBQcm9tcHRbJ21lc3NhZ2VzJ107XG4gICAgdG9vbHM6IFRPT0xTIHwgdW5kZWZpbmVkO1xuICAgIHRvb2xDaG9pY2U6IFRvb2xDaG9pY2U8VE9PTFM+IHwgdW5kZWZpbmVkO1xuICAgIHRyYW5zZm9ybXM6IEFycmF5PFN0cmVhbVRleHRUcmFuc2Zvcm08VE9PTFM+PjtcbiAgICBhY3RpdmVUb29sczogQXJyYXk8a2V5b2YgVE9PTFM+IHwgdW5kZWZpbmVkO1xuICAgIHJlcGFpclRvb2xDYWxsOiBUb29sQ2FsbFJlcGFpckZ1bmN0aW9uPFRPT0xTPiB8IHVuZGVmaW5lZDtcbiAgICBzdG9wQ29uZGl0aW9uczogQXJyYXk8U3RvcENvbmRpdGlvbjxOb0luZmVyPFRPT0xTPj4+O1xuICAgIG91dHB1dDogT3V0cHV0PE9VVFBVVCwgUEFSVElBTF9PVVRQVVQ+IHwgdW5kZWZpbmVkO1xuICAgIHByb3ZpZGVyT3B0aW9uczogUHJvdmlkZXJPcHRpb25zIHwgdW5kZWZpbmVkO1xuICAgIHByZXBhcmVTdGVwOiBQcmVwYXJlU3RlcEZ1bmN0aW9uPE5vSW5mZXI8VE9PTFM+PiB8IHVuZGVmaW5lZDtcbiAgICBpbmNsdWRlUmF3Q2h1bmtzOiBib29sZWFuO1xuICAgIG5vdzogKCkgPT4gbnVtYmVyO1xuICAgIGN1cnJlbnREYXRlOiAoKSA9PiBEYXRlO1xuICAgIGdlbmVyYXRlSWQ6ICgpID0+IHN0cmluZztcbiAgICBleHBlcmltZW50YWxfY29udGV4dDogdW5rbm93bjtcbiAgICBkb3dubG9hZDogRG93bmxvYWRGdW5jdGlvbiB8IHVuZGVmaW5lZDtcblxuICAgIC8vIGNhbGxiYWNrczpcbiAgICBvbkNodW5rOiB1bmRlZmluZWQgfCBTdHJlYW1UZXh0T25DaHVua0NhbGxiYWNrPFRPT0xTPjtcbiAgICBvbkVycm9yOiBTdHJlYW1UZXh0T25FcnJvckNhbGxiYWNrO1xuICAgIG9uRmluaXNoOiB1bmRlZmluZWQgfCBTdHJlYW1UZXh0T25GaW5pc2hDYWxsYmFjazxUT09MUz47XG4gICAgb25BYm9ydDogdW5kZWZpbmVkIHwgU3RyZWFtVGV4dE9uQWJvcnRDYWxsYmFjazxUT09MUz47XG4gICAgb25TdGVwRmluaXNoOiB1bmRlZmluZWQgfCBTdHJlYW1UZXh0T25TdGVwRmluaXNoQ2FsbGJhY2s8VE9PTFM+O1xuICB9KSB7XG4gICAgdGhpcy5vdXRwdXQgPSBvdXRwdXQ7XG4gICAgdGhpcy5pbmNsdWRlUmF3Q2h1bmtzID0gaW5jbHVkZVJhd0NodW5rcztcbiAgICB0aGlzLnRvb2xzID0gdG9vbHM7XG5cbiAgICAvLyBwcm9taXNlIHRvIGVuc3VyZSB0aGF0IHRoZSBzdGVwIGhhcyBiZWVuIGZ1bGx5IHByb2Nlc3NlZCBieSB0aGUgZXZlbnQgcHJvY2Vzc29yXG4gICAgLy8gYmVmb3JlIGEgbmV3IHN0ZXAgaXMgc3RhcnRlZC4gVGhpcyBpcyByZXF1aXJlZCBiZWNhdXNlIHRoZSBjb250aW51YXRpb24gY29uZGl0aW9uXG4gICAgLy8gbmVlZHMgdGhlIHVwZGF0ZWQgc3RlcHMgdG8gZGV0ZXJtaW5lIGlmIGFub3RoZXIgc3RlcCBpcyBuZWVkZWQuXG4gICAgbGV0IHN0ZXBGaW5pc2ghOiBEZWxheWVkUHJvbWlzZTx2b2lkPjtcblxuICAgIGxldCByZWNvcmRlZENvbnRlbnQ6IEFycmF5PENvbnRlbnRQYXJ0PFRPT0xTPj4gPSBbXTtcbiAgICBjb25zdCByZWNvcmRlZFJlc3BvbnNlTWVzc2FnZXM6IEFycmF5PFJlc3BvbnNlTWVzc2FnZT4gPSBbXTtcbiAgICBsZXQgcmVjb3JkZWRGaW5pc2hSZWFzb246IEZpbmlzaFJlYXNvbiB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICBsZXQgcmVjb3JkZWRUb3RhbFVzYWdlOiBMYW5ndWFnZU1vZGVsVXNhZ2UgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgbGV0IHJlY29yZGVkUmVxdWVzdDogTGFuZ3VhZ2VNb2RlbFJlcXVlc3RNZXRhZGF0YSA9IHt9O1xuICAgIGxldCByZWNvcmRlZFdhcm5pbmdzOiBBcnJheTxDYWxsV2FybmluZz4gPSBbXTtcbiAgICBjb25zdCByZWNvcmRlZFN0ZXBzOiBTdGVwUmVzdWx0PFRPT0xTPltdID0gW107XG5cbiAgICBsZXQgcm9vdFNwYW4hOiBTcGFuO1xuXG4gICAgbGV0IGFjdGl2ZVRleHRDb250ZW50OiBSZWNvcmQ8XG4gICAgICBzdHJpbmcsXG4gICAgICB7XG4gICAgICAgIHR5cGU6ICd0ZXh0JztcbiAgICAgICAgdGV4dDogc3RyaW5nO1xuICAgICAgICBwcm92aWRlck1ldGFkYXRhOiBQcm92aWRlck1ldGFkYXRhIHwgdW5kZWZpbmVkO1xuICAgICAgfVxuICAgID4gPSB7fTtcblxuICAgIGxldCBhY3RpdmVSZWFzb25pbmdDb250ZW50OiBSZWNvcmQ8XG4gICAgICBzdHJpbmcsXG4gICAgICB7XG4gICAgICAgIHR5cGU6ICdyZWFzb25pbmcnO1xuICAgICAgICB0ZXh0OiBzdHJpbmc7XG4gICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IFByb3ZpZGVyTWV0YWRhdGEgfCB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgPiA9IHt9O1xuXG4gICAgY29uc3QgZXZlbnRQcm9jZXNzb3IgPSBuZXcgVHJhbnNmb3JtU3RyZWFtPFxuICAgICAgRW5yaWNoZWRTdHJlYW1QYXJ0PFRPT0xTLCBQQVJUSUFMX09VVFBVVD4sXG4gICAgICBFbnJpY2hlZFN0cmVhbVBhcnQ8VE9PTFMsIFBBUlRJQUxfT1VUUFVUPlxuICAgID4oe1xuICAgICAgYXN5bmMgdHJhbnNmb3JtKGNodW5rLCBjb250cm9sbGVyKSB7XG4gICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShjaHVuayk7IC8vIGZvcndhcmQgdGhlIGNodW5rIHRvIHRoZSBuZXh0IHN0cmVhbVxuXG4gICAgICAgIGNvbnN0IHsgcGFydCB9ID0gY2h1bms7XG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgIHBhcnQudHlwZSA9PT0gJ3RleHQtZGVsdGEnIHx8XG4gICAgICAgICAgcGFydC50eXBlID09PSAncmVhc29uaW5nLWRlbHRhJyB8fFxuICAgICAgICAgIHBhcnQudHlwZSA9PT0gJ3NvdXJjZScgfHxcbiAgICAgICAgICBwYXJ0LnR5cGUgPT09ICd0b29sLWNhbGwnIHx8XG4gICAgICAgICAgcGFydC50eXBlID09PSAndG9vbC1yZXN1bHQnIHx8XG4gICAgICAgICAgcGFydC50eXBlID09PSAndG9vbC1pbnB1dC1zdGFydCcgfHxcbiAgICAgICAgICBwYXJ0LnR5cGUgPT09ICd0b29sLWlucHV0LWRlbHRhJyB8fFxuICAgICAgICAgIHBhcnQudHlwZSA9PT0gJ3JhdydcbiAgICAgICAgKSB7XG4gICAgICAgICAgYXdhaXQgb25DaHVuaz8uKHsgY2h1bms6IHBhcnQgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocGFydC50eXBlID09PSAnZXJyb3InKSB7XG4gICAgICAgICAgYXdhaXQgb25FcnJvcih7IGVycm9yOiB3cmFwR2F0ZXdheUVycm9yKHBhcnQuZXJyb3IpIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBhcnQudHlwZSA9PT0gJ3RleHQtc3RhcnQnKSB7XG4gICAgICAgICAgYWN0aXZlVGV4dENvbnRlbnRbcGFydC5pZF0gPSB7XG4gICAgICAgICAgICB0eXBlOiAndGV4dCcsXG4gICAgICAgICAgICB0ZXh0OiAnJyxcbiAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHBhcnQucHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgcmVjb3JkZWRDb250ZW50LnB1c2goYWN0aXZlVGV4dENvbnRlbnRbcGFydC5pZF0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBhcnQudHlwZSA9PT0gJ3RleHQtZGVsdGEnKSB7XG4gICAgICAgICAgY29uc3QgYWN0aXZlVGV4dCA9IGFjdGl2ZVRleHRDb250ZW50W3BhcnQuaWRdO1xuXG4gICAgICAgICAgaWYgKGFjdGl2ZVRleHQgPT0gbnVsbCkge1xuICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHtcbiAgICAgICAgICAgICAgcGFydDoge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdlcnJvcicsXG4gICAgICAgICAgICAgICAgZXJyb3I6IGB0ZXh0IHBhcnQgJHtwYXJ0LmlkfSBub3QgZm91bmRgLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBwYXJ0aWFsT3V0cHV0OiB1bmRlZmluZWQsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBhY3RpdmVUZXh0LnRleHQgKz0gcGFydC50ZXh0O1xuICAgICAgICAgIGFjdGl2ZVRleHQucHJvdmlkZXJNZXRhZGF0YSA9XG4gICAgICAgICAgICBwYXJ0LnByb3ZpZGVyTWV0YWRhdGEgPz8gYWN0aXZlVGV4dC5wcm92aWRlck1ldGFkYXRhO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBhcnQudHlwZSA9PT0gJ3RleHQtZW5kJykge1xuICAgICAgICAgIGNvbnN0IGFjdGl2ZVRleHQgPSBhY3RpdmVUZXh0Q29udGVudFtwYXJ0LmlkXTtcblxuICAgICAgICAgIGlmIChhY3RpdmVUZXh0ID09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgIHBhcnQ6IHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnZXJyb3InLFxuICAgICAgICAgICAgICAgIGVycm9yOiBgdGV4dCBwYXJ0ICR7cGFydC5pZH0gbm90IGZvdW5kYCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgcGFydGlhbE91dHB1dDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYWN0aXZlVGV4dC5wcm92aWRlck1ldGFkYXRhID1cbiAgICAgICAgICAgIHBhcnQucHJvdmlkZXJNZXRhZGF0YSA/PyBhY3RpdmVUZXh0LnByb3ZpZGVyTWV0YWRhdGE7XG5cbiAgICAgICAgICBkZWxldGUgYWN0aXZlVGV4dENvbnRlbnRbcGFydC5pZF07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocGFydC50eXBlID09PSAncmVhc29uaW5nLXN0YXJ0Jykge1xuICAgICAgICAgIGFjdGl2ZVJlYXNvbmluZ0NvbnRlbnRbcGFydC5pZF0gPSB7XG4gICAgICAgICAgICB0eXBlOiAncmVhc29uaW5nJyxcbiAgICAgICAgICAgIHRleHQ6ICcnLFxuICAgICAgICAgICAgcHJvdmlkZXJNZXRhZGF0YTogcGFydC5wcm92aWRlck1ldGFkYXRhLFxuICAgICAgICAgIH07XG5cbiAgICAgICAgICByZWNvcmRlZENvbnRlbnQucHVzaChhY3RpdmVSZWFzb25pbmdDb250ZW50W3BhcnQuaWRdKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXJ0LnR5cGUgPT09ICdyZWFzb25pbmctZGVsdGEnKSB7XG4gICAgICAgICAgY29uc3QgYWN0aXZlUmVhc29uaW5nID0gYWN0aXZlUmVhc29uaW5nQ29udGVudFtwYXJ0LmlkXTtcblxuICAgICAgICAgIGlmIChhY3RpdmVSZWFzb25pbmcgPT0gbnVsbCkge1xuICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHtcbiAgICAgICAgICAgICAgcGFydDoge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdlcnJvcicsXG4gICAgICAgICAgICAgICAgZXJyb3I6IGByZWFzb25pbmcgcGFydCAke3BhcnQuaWR9IG5vdCBmb3VuZGAsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHBhcnRpYWxPdXRwdXQ6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGFjdGl2ZVJlYXNvbmluZy50ZXh0ICs9IHBhcnQudGV4dDtcbiAgICAgICAgICBhY3RpdmVSZWFzb25pbmcucHJvdmlkZXJNZXRhZGF0YSA9XG4gICAgICAgICAgICBwYXJ0LnByb3ZpZGVyTWV0YWRhdGEgPz8gYWN0aXZlUmVhc29uaW5nLnByb3ZpZGVyTWV0YWRhdGE7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocGFydC50eXBlID09PSAncmVhc29uaW5nLWVuZCcpIHtcbiAgICAgICAgICBjb25zdCBhY3RpdmVSZWFzb25pbmcgPSBhY3RpdmVSZWFzb25pbmdDb250ZW50W3BhcnQuaWRdO1xuXG4gICAgICAgICAgaWYgKGFjdGl2ZVJlYXNvbmluZyA9PSBudWxsKSB7XG4gICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgICBwYXJ0OiB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ2Vycm9yJyxcbiAgICAgICAgICAgICAgICBlcnJvcjogYHJlYXNvbmluZyBwYXJ0ICR7cGFydC5pZH0gbm90IGZvdW5kYCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgcGFydGlhbE91dHB1dDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYWN0aXZlUmVhc29uaW5nLnByb3ZpZGVyTWV0YWRhdGEgPVxuICAgICAgICAgICAgcGFydC5wcm92aWRlck1ldGFkYXRhID8/IGFjdGl2ZVJlYXNvbmluZy5wcm92aWRlck1ldGFkYXRhO1xuXG4gICAgICAgICAgZGVsZXRlIGFjdGl2ZVJlYXNvbmluZ0NvbnRlbnRbcGFydC5pZF07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocGFydC50eXBlID09PSAnZmlsZScpIHtcbiAgICAgICAgICByZWNvcmRlZENvbnRlbnQucHVzaCh7IHR5cGU6ICdmaWxlJywgZmlsZTogcGFydC5maWxlIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBhcnQudHlwZSA9PT0gJ3NvdXJjZScpIHtcbiAgICAgICAgICByZWNvcmRlZENvbnRlbnQucHVzaChwYXJ0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXJ0LnR5cGUgPT09ICd0b29sLWNhbGwnKSB7XG4gICAgICAgICAgcmVjb3JkZWRDb250ZW50LnB1c2gocGFydCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocGFydC50eXBlID09PSAndG9vbC1yZXN1bHQnICYmICFwYXJ0LnByZWxpbWluYXJ5KSB7XG4gICAgICAgICAgcmVjb3JkZWRDb250ZW50LnB1c2gocGFydCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocGFydC50eXBlID09PSAndG9vbC1lcnJvcicpIHtcbiAgICAgICAgICByZWNvcmRlZENvbnRlbnQucHVzaChwYXJ0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXJ0LnR5cGUgPT09ICdzdGFydC1zdGVwJykge1xuICAgICAgICAgIHJlY29yZGVkUmVxdWVzdCA9IHBhcnQucmVxdWVzdDtcbiAgICAgICAgICByZWNvcmRlZFdhcm5pbmdzID0gcGFydC53YXJuaW5ncztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXJ0LnR5cGUgPT09ICdmaW5pc2gtc3RlcCcpIHtcbiAgICAgICAgICBjb25zdCBzdGVwTWVzc2FnZXMgPSB0b1Jlc3BvbnNlTWVzc2FnZXMoe1xuICAgICAgICAgICAgY29udGVudDogcmVjb3JkZWRDb250ZW50LFxuICAgICAgICAgICAgdG9vbHMsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICAvLyBBZGQgc3RlcCBpbmZvcm1hdGlvbiAoYWZ0ZXIgcmVzcG9uc2UgbWVzc2FnZXMgYXJlIHVwZGF0ZWQpOlxuICAgICAgICAgIGNvbnN0IGN1cnJlbnRTdGVwUmVzdWx0OiBTdGVwUmVzdWx0PFRPT0xTPiA9IG5ldyBEZWZhdWx0U3RlcFJlc3VsdCh7XG4gICAgICAgICAgICBjb250ZW50OiByZWNvcmRlZENvbnRlbnQsXG4gICAgICAgICAgICBmaW5pc2hSZWFzb246IHBhcnQuZmluaXNoUmVhc29uLFxuICAgICAgICAgICAgdXNhZ2U6IHBhcnQudXNhZ2UsXG4gICAgICAgICAgICB3YXJuaW5nczogcmVjb3JkZWRXYXJuaW5ncyxcbiAgICAgICAgICAgIHJlcXVlc3Q6IHJlY29yZGVkUmVxdWVzdCxcbiAgICAgICAgICAgIHJlc3BvbnNlOiB7XG4gICAgICAgICAgICAgIC4uLnBhcnQucmVzcG9uc2UsXG4gICAgICAgICAgICAgIG1lc3NhZ2VzOiBbLi4ucmVjb3JkZWRSZXNwb25zZU1lc3NhZ2VzLCAuLi5zdGVwTWVzc2FnZXNdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHBhcnQucHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGF3YWl0IG9uU3RlcEZpbmlzaD8uKGN1cnJlbnRTdGVwUmVzdWx0KTtcblxuICAgICAgICAgIGxvZ1dhcm5pbmdzKHJlY29yZGVkV2FybmluZ3MpO1xuXG4gICAgICAgICAgcmVjb3JkZWRTdGVwcy5wdXNoKGN1cnJlbnRTdGVwUmVzdWx0KTtcblxuICAgICAgICAgIHJlY29yZGVkQ29udGVudCA9IFtdO1xuICAgICAgICAgIGFjdGl2ZVJlYXNvbmluZ0NvbnRlbnQgPSB7fTtcbiAgICAgICAgICBhY3RpdmVUZXh0Q29udGVudCA9IHt9O1xuXG4gICAgICAgICAgcmVjb3JkZWRSZXNwb25zZU1lc3NhZ2VzLnB1c2goLi4uc3RlcE1lc3NhZ2VzKTtcblxuICAgICAgICAgIC8vIHJlc29sdmUgdGhlIHByb21pc2UgdG8gc2lnbmFsIHRoYXQgdGhlIHN0ZXAgaGFzIGJlZW4gZnVsbHkgcHJvY2Vzc2VkXG4gICAgICAgICAgLy8gYnkgdGhlIGV2ZW50IHByb2Nlc3NvcjpcbiAgICAgICAgICBzdGVwRmluaXNoLnJlc29sdmUoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXJ0LnR5cGUgPT09ICdmaW5pc2gnKSB7XG4gICAgICAgICAgcmVjb3JkZWRUb3RhbFVzYWdlID0gcGFydC50b3RhbFVzYWdlO1xuICAgICAgICAgIHJlY29yZGVkRmluaXNoUmVhc29uID0gcGFydC5maW5pc2hSZWFzb247XG4gICAgICAgIH1cbiAgICAgIH0sXG5cbiAgICAgIGFzeW5jIGZsdXNoKGNvbnRyb2xsZXIpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBpZiAocmVjb3JkZWRTdGVwcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IE5vT3V0cHV0R2VuZXJhdGVkRXJyb3Ioe1xuICAgICAgICAgICAgICBtZXNzYWdlOiAnTm8gb3V0cHV0IGdlbmVyYXRlZC4gQ2hlY2sgdGhlIHN0cmVhbSBmb3IgZXJyb3JzLicsXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgc2VsZi5fZmluaXNoUmVhc29uLnJlamVjdChlcnJvcik7XG4gICAgICAgICAgICBzZWxmLl90b3RhbFVzYWdlLnJlamVjdChlcnJvcik7XG4gICAgICAgICAgICBzZWxmLl9zdGVwcy5yZWplY3QoZXJyb3IpO1xuXG4gICAgICAgICAgICByZXR1cm47IC8vIG5vIHN0ZXBzIHJlY29yZGVkIChlLmcuIGluIGVycm9yIHNjZW5hcmlvKVxuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIGRlcml2ZWQ6XG4gICAgICAgICAgY29uc3QgZmluaXNoUmVhc29uID0gcmVjb3JkZWRGaW5pc2hSZWFzb24gPz8gJ3Vua25vd24nO1xuICAgICAgICAgIGNvbnN0IHRvdGFsVXNhZ2UgPSByZWNvcmRlZFRvdGFsVXNhZ2UgPz8ge1xuICAgICAgICAgICAgaW5wdXRUb2tlbnM6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIG91dHB1dFRva2VuczogdW5kZWZpbmVkLFxuICAgICAgICAgICAgdG90YWxUb2tlbnM6IHVuZGVmaW5lZCxcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgLy8gZnJvbSBmaW5pc2g6XG4gICAgICAgICAgc2VsZi5fZmluaXNoUmVhc29uLnJlc29sdmUoZmluaXNoUmVhc29uKTtcbiAgICAgICAgICBzZWxmLl90b3RhbFVzYWdlLnJlc29sdmUodG90YWxVc2FnZSk7XG5cbiAgICAgICAgICAvLyBhZ2dyZWdhdGUgcmVzdWx0czpcbiAgICAgICAgICBzZWxmLl9zdGVwcy5yZXNvbHZlKHJlY29yZGVkU3RlcHMpO1xuXG4gICAgICAgICAgLy8gY2FsbCBvbkZpbmlzaCBjYWxsYmFjazpcbiAgICAgICAgICBjb25zdCBmaW5hbFN0ZXAgPSByZWNvcmRlZFN0ZXBzW3JlY29yZGVkU3RlcHMubGVuZ3RoIC0gMV07XG4gICAgICAgICAgYXdhaXQgb25GaW5pc2g/Lih7XG4gICAgICAgICAgICBmaW5pc2hSZWFzb24sXG4gICAgICAgICAgICB0b3RhbFVzYWdlLFxuICAgICAgICAgICAgdXNhZ2U6IGZpbmFsU3RlcC51c2FnZSxcbiAgICAgICAgICAgIGNvbnRlbnQ6IGZpbmFsU3RlcC5jb250ZW50LFxuICAgICAgICAgICAgdGV4dDogZmluYWxTdGVwLnRleHQsXG4gICAgICAgICAgICByZWFzb25pbmdUZXh0OiBmaW5hbFN0ZXAucmVhc29uaW5nVGV4dCxcbiAgICAgICAgICAgIHJlYXNvbmluZzogZmluYWxTdGVwLnJlYXNvbmluZyxcbiAgICAgICAgICAgIGZpbGVzOiBmaW5hbFN0ZXAuZmlsZXMsXG4gICAgICAgICAgICBzb3VyY2VzOiBmaW5hbFN0ZXAuc291cmNlcyxcbiAgICAgICAgICAgIHRvb2xDYWxsczogZmluYWxTdGVwLnRvb2xDYWxscyxcbiAgICAgICAgICAgIHN0YXRpY1Rvb2xDYWxsczogZmluYWxTdGVwLnN0YXRpY1Rvb2xDYWxscyxcbiAgICAgICAgICAgIGR5bmFtaWNUb29sQ2FsbHM6IGZpbmFsU3RlcC5keW5hbWljVG9vbENhbGxzLFxuICAgICAgICAgICAgdG9vbFJlc3VsdHM6IGZpbmFsU3RlcC50b29sUmVzdWx0cyxcbiAgICAgICAgICAgIHN0YXRpY1Rvb2xSZXN1bHRzOiBmaW5hbFN0ZXAuc3RhdGljVG9vbFJlc3VsdHMsXG4gICAgICAgICAgICBkeW5hbWljVG9vbFJlc3VsdHM6IGZpbmFsU3RlcC5keW5hbWljVG9vbFJlc3VsdHMsXG4gICAgICAgICAgICByZXF1ZXN0OiBmaW5hbFN0ZXAucmVxdWVzdCxcbiAgICAgICAgICAgIHJlc3BvbnNlOiBmaW5hbFN0ZXAucmVzcG9uc2UsXG4gICAgICAgICAgICB3YXJuaW5nczogZmluYWxTdGVwLndhcm5pbmdzLFxuICAgICAgICAgICAgcHJvdmlkZXJNZXRhZGF0YTogZmluYWxTdGVwLnByb3ZpZGVyTWV0YWRhdGEsXG4gICAgICAgICAgICBzdGVwczogcmVjb3JkZWRTdGVwcyxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIC8vIEFkZCByZXNwb25zZSBpbmZvcm1hdGlvbiB0byB0aGUgcm9vdCBzcGFuOlxuICAgICAgICAgIHJvb3RTcGFuLnNldEF0dHJpYnV0ZXMoXG4gICAgICAgICAgICBzZWxlY3RUZWxlbWV0cnlBdHRyaWJ1dGVzKHtcbiAgICAgICAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLmZpbmlzaFJlYXNvbic6IGZpbmlzaFJlYXNvbixcbiAgICAgICAgICAgICAgICAnYWkucmVzcG9uc2UudGV4dCc6IHsgb3V0cHV0OiAoKSA9PiBmaW5hbFN0ZXAudGV4dCB9LFxuICAgICAgICAgICAgICAgICdhaS5yZXNwb25zZS50b29sQ2FsbHMnOiB7XG4gICAgICAgICAgICAgICAgICBvdXRwdXQ6ICgpID0+XG4gICAgICAgICAgICAgICAgICAgIGZpbmFsU3RlcC50b29sQ2FsbHM/Lmxlbmd0aFxuICAgICAgICAgICAgICAgICAgICAgID8gSlNPTi5zdHJpbmdpZnkoZmluYWxTdGVwLnRvb2xDYWxscylcbiAgICAgICAgICAgICAgICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICdhaS5yZXNwb25zZS5wcm92aWRlck1ldGFkYXRhJzogSlNPTi5zdHJpbmdpZnkoXG4gICAgICAgICAgICAgICAgICBmaW5hbFN0ZXAucHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgICAgICAgICApLFxuXG4gICAgICAgICAgICAgICAgJ2FpLnVzYWdlLmlucHV0VG9rZW5zJzogdG90YWxVc2FnZS5pbnB1dFRva2VucyxcbiAgICAgICAgICAgICAgICAnYWkudXNhZ2Uub3V0cHV0VG9rZW5zJzogdG90YWxVc2FnZS5vdXRwdXRUb2tlbnMsXG4gICAgICAgICAgICAgICAgJ2FpLnVzYWdlLnRvdGFsVG9rZW5zJzogdG90YWxVc2FnZS50b3RhbFRva2VucyxcbiAgICAgICAgICAgICAgICAnYWkudXNhZ2UucmVhc29uaW5nVG9rZW5zJzogdG90YWxVc2FnZS5yZWFzb25pbmdUb2tlbnMsXG4gICAgICAgICAgICAgICAgJ2FpLnVzYWdlLmNhY2hlZElucHV0VG9rZW5zJzogdG90YWxVc2FnZS5jYWNoZWRJbnB1dFRva2VucyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgY29udHJvbGxlci5lcnJvcihlcnJvcik7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgcm9vdFNwYW4uZW5kKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICAvLyBpbml0aWFsaXplIHRoZSBzdGl0Y2hhYmxlIHN0cmVhbSBhbmQgdGhlIHRyYW5zZm9ybWVkIHN0cmVhbTpcbiAgICBjb25zdCBzdGl0Y2hhYmxlU3RyZWFtID0gY3JlYXRlU3RpdGNoYWJsZVN0cmVhbTxUZXh0U3RyZWFtUGFydDxUT09MUz4+KCk7XG4gICAgdGhpcy5hZGRTdHJlYW0gPSBzdGl0Y2hhYmxlU3RyZWFtLmFkZFN0cmVhbTtcbiAgICB0aGlzLmNsb3NlU3RyZWFtID0gc3RpdGNoYWJsZVN0cmVhbS5jbG9zZTtcblxuICAgIC8vIHJlc2lsaWVudCBzdHJlYW0gdGhhdCBoYW5kbGVzIGFib3J0IHNpZ25hbHMgYW5kIGVycm9yczpcbiAgICBjb25zdCByZWFkZXIgPSBzdGl0Y2hhYmxlU3RyZWFtLnN0cmVhbS5nZXRSZWFkZXIoKTtcbiAgICBsZXQgc3RyZWFtID0gbmV3IFJlYWRhYmxlU3RyZWFtPFRleHRTdHJlYW1QYXJ0PFRPT0xTPj4oe1xuICAgICAgYXN5bmMgc3RhcnQoY29udHJvbGxlcikge1xuICAgICAgICAvLyBzZW5kIHN0YXJ0IGV2ZW50OlxuICAgICAgICBjb250cm9sbGVyLmVucXVldWUoeyB0eXBlOiAnc3RhcnQnIH0pO1xuICAgICAgfSxcblxuICAgICAgYXN5bmMgcHVsbChjb250cm9sbGVyKSB7XG4gICAgICAgIC8vIGFib3J0IGhhbmRsaW5nOlxuICAgICAgICBmdW5jdGlvbiBhYm9ydCgpIHtcbiAgICAgICAgICBvbkFib3J0Py4oeyBzdGVwczogcmVjb3JkZWRTdGVwcyB9KTtcbiAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoeyB0eXBlOiAnYWJvcnQnIH0pO1xuICAgICAgICAgIGNvbnRyb2xsZXIuY2xvc2UoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgeyBkb25lLCB2YWx1ZSB9ID0gYXdhaXQgcmVhZGVyLnJlYWQoKTtcblxuICAgICAgICAgIGlmIChkb25lKSB7XG4gICAgICAgICAgICBjb250cm9sbGVyLmNsb3NlKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGFib3J0U2lnbmFsPy5hYm9ydGVkKSB7XG4gICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh2YWx1ZSk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgaWYgKGlzQWJvcnRFcnJvcihlcnJvcikgJiYgYWJvcnRTaWduYWw/LmFib3J0ZWQpIHtcbiAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnRyb2xsZXIuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSxcblxuICAgICAgY2FuY2VsKHJlYXNvbikge1xuICAgICAgICByZXR1cm4gc3RpdGNoYWJsZVN0cmVhbS5zdHJlYW0uY2FuY2VsKHJlYXNvbik7XG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgLy8gdHJhbnNmb3JtIHRoZSBzdHJlYW0gYmVmb3JlIG91dHB1dCBwYXJzaW5nXG4gICAgLy8gdG8gZW5hYmxlIHJlcGxhY2VtZW50IG9mIHN0cmVhbSBzZWdtZW50czpcbiAgICBmb3IgKGNvbnN0IHRyYW5zZm9ybSBvZiB0cmFuc2Zvcm1zKSB7XG4gICAgICBzdHJlYW0gPSBzdHJlYW0ucGlwZVRocm91Z2goXG4gICAgICAgIHRyYW5zZm9ybSh7XG4gICAgICAgICAgdG9vbHM6IHRvb2xzIGFzIFRPT0xTLFxuICAgICAgICAgIHN0b3BTdHJlYW0oKSB7XG4gICAgICAgICAgICBzdGl0Y2hhYmxlU3RyZWFtLnRlcm1pbmF0ZSgpO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICB0aGlzLmJhc2VTdHJlYW0gPSBzdHJlYW1cbiAgICAgIC5waXBlVGhyb3VnaChjcmVhdGVPdXRwdXRUcmFuc2Zvcm1TdHJlYW0ob3V0cHV0KSlcbiAgICAgIC5waXBlVGhyb3VnaChldmVudFByb2Nlc3Nvcik7XG5cbiAgICBjb25zdCB7IG1heFJldHJpZXMsIHJldHJ5IH0gPSBwcmVwYXJlUmV0cmllcyh7XG4gICAgICBtYXhSZXRyaWVzOiBtYXhSZXRyaWVzQXJnLFxuICAgICAgYWJvcnRTaWduYWwsXG4gICAgfSk7XG5cbiAgICBjb25zdCB0cmFjZXIgPSBnZXRUcmFjZXIodGVsZW1ldHJ5KTtcblxuICAgIGNvbnN0IGNhbGxTZXR0aW5ncyA9IHByZXBhcmVDYWxsU2V0dGluZ3Moc2V0dGluZ3MpO1xuXG4gICAgY29uc3QgYmFzZVRlbGVtZXRyeUF0dHJpYnV0ZXMgPSBnZXRCYXNlVGVsZW1ldHJ5QXR0cmlidXRlcyh7XG4gICAgICBtb2RlbCxcbiAgICAgIHRlbGVtZXRyeSxcbiAgICAgIGhlYWRlcnMsXG4gICAgICBzZXR0aW5nczogeyAuLi5jYWxsU2V0dGluZ3MsIG1heFJldHJpZXMgfSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgcmVjb3JkU3Bhbih7XG4gICAgICBuYW1lOiAnYWkuc3RyZWFtVGV4dCcsXG4gICAgICBhdHRyaWJ1dGVzOiBzZWxlY3RUZWxlbWV0cnlBdHRyaWJ1dGVzKHtcbiAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgLi4uYXNzZW1ibGVPcGVyYXRpb25OYW1lKHsgb3BlcmF0aW9uSWQ6ICdhaS5zdHJlYW1UZXh0JywgdGVsZW1ldHJ5IH0pLFxuICAgICAgICAgIC4uLmJhc2VUZWxlbWV0cnlBdHRyaWJ1dGVzLFxuICAgICAgICAgIC8vIHNwZWNpZmljIHNldHRpbmdzIHRoYXQgb25seSBtYWtlIHNlbnNlIG9uIHRoZSBvdXRlciBsZXZlbDpcbiAgICAgICAgICAnYWkucHJvbXB0Jzoge1xuICAgICAgICAgICAgaW5wdXQ6ICgpID0+IEpTT04uc3RyaW5naWZ5KHsgc3lzdGVtLCBwcm9tcHQsIG1lc3NhZ2VzIH0pLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KSxcbiAgICAgIHRyYWNlcixcbiAgICAgIGVuZFdoZW5Eb25lOiBmYWxzZSxcbiAgICAgIGZuOiBhc3luYyByb290U3BhbkFyZyA9PiB7XG4gICAgICAgIHJvb3RTcGFuID0gcm9vdFNwYW5Bcmc7XG5cbiAgICAgICAgYXN5bmMgZnVuY3Rpb24gc3RyZWFtU3RlcCh7XG4gICAgICAgICAgY3VycmVudFN0ZXAsXG4gICAgICAgICAgcmVzcG9uc2VNZXNzYWdlcyxcbiAgICAgICAgICB1c2FnZSxcbiAgICAgICAgfToge1xuICAgICAgICAgIGN1cnJlbnRTdGVwOiBudW1iZXI7XG4gICAgICAgICAgcmVzcG9uc2VNZXNzYWdlczogQXJyYXk8UmVzcG9uc2VNZXNzYWdlPjtcbiAgICAgICAgICB1c2FnZTogTGFuZ3VhZ2VNb2RlbFVzYWdlO1xuICAgICAgICB9KSB7XG4gICAgICAgICAgY29uc3QgaW5jbHVkZVJhd0NodW5rcyA9IHNlbGYuaW5jbHVkZVJhd0NodW5rcztcblxuICAgICAgICAgIHN0ZXBGaW5pc2ggPSBuZXcgRGVsYXllZFByb21pc2U8dm9pZD4oKTtcblxuICAgICAgICAgIGNvbnN0IGluaXRpYWxQcm9tcHQgPSBhd2FpdCBzdGFuZGFyZGl6ZVByb21wdCh7XG4gICAgICAgICAgICBzeXN0ZW0sXG4gICAgICAgICAgICBwcm9tcHQsXG4gICAgICAgICAgICBtZXNzYWdlcyxcbiAgICAgICAgICB9IGFzIFByb21wdCk7XG5cbiAgICAgICAgICBjb25zdCBzdGVwSW5wdXRNZXNzYWdlcyA9IFtcbiAgICAgICAgICAgIC4uLmluaXRpYWxQcm9tcHQubWVzc2FnZXMsXG4gICAgICAgICAgICAuLi5yZXNwb25zZU1lc3NhZ2VzLFxuICAgICAgICAgIF07XG5cbiAgICAgICAgICBjb25zdCBwcmVwYXJlU3RlcFJlc3VsdCA9IGF3YWl0IHByZXBhcmVTdGVwPy4oe1xuICAgICAgICAgICAgbW9kZWwsXG4gICAgICAgICAgICBzdGVwczogcmVjb3JkZWRTdGVwcyxcbiAgICAgICAgICAgIHN0ZXBOdW1iZXI6IHJlY29yZGVkU3RlcHMubGVuZ3RoLFxuICAgICAgICAgICAgbWVzc2FnZXM6IHN0ZXBJbnB1dE1lc3NhZ2VzLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY29uc3Qgc3RlcE1vZGVsID0gcmVzb2x2ZUxhbmd1YWdlTW9kZWwoXG4gICAgICAgICAgICBwcmVwYXJlU3RlcFJlc3VsdD8ubW9kZWwgPz8gbW9kZWwsXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGNvbnN0IHByb21wdE1lc3NhZ2VzID0gYXdhaXQgY29udmVydFRvTGFuZ3VhZ2VNb2RlbFByb21wdCh7XG4gICAgICAgICAgICBwcm9tcHQ6IHtcbiAgICAgICAgICAgICAgc3lzdGVtOiBwcmVwYXJlU3RlcFJlc3VsdD8uc3lzdGVtID8/IGluaXRpYWxQcm9tcHQuc3lzdGVtLFxuICAgICAgICAgICAgICBtZXNzYWdlczogcHJlcGFyZVN0ZXBSZXN1bHQ/Lm1lc3NhZ2VzID8/IHN0ZXBJbnB1dE1lc3NhZ2VzLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHN1cHBvcnRlZFVybHM6IGF3YWl0IHN0ZXBNb2RlbC5zdXBwb3J0ZWRVcmxzLFxuICAgICAgICAgICAgZG93bmxvYWQsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCB7IHRvb2xDaG9pY2U6IHN0ZXBUb29sQ2hvaWNlLCB0b29sczogc3RlcFRvb2xzIH0gPVxuICAgICAgICAgICAgcHJlcGFyZVRvb2xzQW5kVG9vbENob2ljZSh7XG4gICAgICAgICAgICAgIHRvb2xzLFxuICAgICAgICAgICAgICB0b29sQ2hvaWNlOiBwcmVwYXJlU3RlcFJlc3VsdD8udG9vbENob2ljZSA/PyB0b29sQ2hvaWNlLFxuICAgICAgICAgICAgICBhY3RpdmVUb29sczogcHJlcGFyZVN0ZXBSZXN1bHQ/LmFjdGl2ZVRvb2xzID8/IGFjdGl2ZVRvb2xzLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICByZXN1bHQ6IHsgc3RyZWFtLCByZXNwb25zZSwgcmVxdWVzdCB9LFxuICAgICAgICAgICAgZG9TdHJlYW1TcGFuLFxuICAgICAgICAgICAgc3RhcnRUaW1lc3RhbXBNcyxcbiAgICAgICAgICB9ID0gYXdhaXQgcmV0cnkoKCkgPT5cbiAgICAgICAgICAgIHJlY29yZFNwYW4oe1xuICAgICAgICAgICAgICBuYW1lOiAnYWkuc3RyZWFtVGV4dC5kb1N0cmVhbScsXG4gICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgICAgIHRlbGVtZXRyeSxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgICAgICAgICAuLi5hc3NlbWJsZU9wZXJhdGlvbk5hbWUoe1xuICAgICAgICAgICAgICAgICAgICBvcGVyYXRpb25JZDogJ2FpLnN0cmVhbVRleHQuZG9TdHJlYW0nLFxuICAgICAgICAgICAgICAgICAgICB0ZWxlbWV0cnksXG4gICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgIC4uLmJhc2VUZWxlbWV0cnlBdHRyaWJ1dGVzLFxuICAgICAgICAgICAgICAgICAgLy8gbW9kZWw6XG4gICAgICAgICAgICAgICAgICAnYWkubW9kZWwucHJvdmlkZXInOiBzdGVwTW9kZWwucHJvdmlkZXIsXG4gICAgICAgICAgICAgICAgICAnYWkubW9kZWwuaWQnOiBzdGVwTW9kZWwubW9kZWxJZCxcbiAgICAgICAgICAgICAgICAgIC8vIHByb21wdDpcbiAgICAgICAgICAgICAgICAgICdhaS5wcm9tcHQubWVzc2FnZXMnOiB7XG4gICAgICAgICAgICAgICAgICAgIGlucHV0OiAoKSA9PiBzdHJpbmdpZnlGb3JUZWxlbWV0cnkocHJvbXB0TWVzc2FnZXMpLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICdhaS5wcm9tcHQudG9vbHMnOiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGNvbnZlcnQgdGhlIGxhbmd1YWdlIG1vZGVsIGxldmVsIHRvb2xzOlxuICAgICAgICAgICAgICAgICAgICBpbnB1dDogKCkgPT4gc3RlcFRvb2xzPy5tYXAodG9vbCA9PiBKU09OLnN0cmluZ2lmeSh0b29sKSksXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgJ2FpLnByb21wdC50b29sQ2hvaWNlJzoge1xuICAgICAgICAgICAgICAgICAgICBpbnB1dDogKCkgPT5cbiAgICAgICAgICAgICAgICAgICAgICBzdGVwVG9vbENob2ljZSAhPSBudWxsXG4gICAgICAgICAgICAgICAgICAgICAgICA/IEpTT04uc3RyaW5naWZ5KHN0ZXBUb29sQ2hvaWNlKVxuICAgICAgICAgICAgICAgICAgICAgICAgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAgICAgICAvLyBzdGFuZGFyZGl6ZWQgZ2VuLWFpIGxsbSBzcGFuIGF0dHJpYnV0ZXM6XG4gICAgICAgICAgICAgICAgICAnZ2VuX2FpLnN5c3RlbSc6IHN0ZXBNb2RlbC5wcm92aWRlcixcbiAgICAgICAgICAgICAgICAgICdnZW5fYWkucmVxdWVzdC5tb2RlbCc6IHN0ZXBNb2RlbC5tb2RlbElkLFxuICAgICAgICAgICAgICAgICAgJ2dlbl9haS5yZXF1ZXN0LmZyZXF1ZW5jeV9wZW5hbHR5JzpcbiAgICAgICAgICAgICAgICAgICAgY2FsbFNldHRpbmdzLmZyZXF1ZW5jeVBlbmFsdHksXG4gICAgICAgICAgICAgICAgICAnZ2VuX2FpLnJlcXVlc3QubWF4X3Rva2Vucyc6IGNhbGxTZXR0aW5ncy5tYXhPdXRwdXRUb2tlbnMsXG4gICAgICAgICAgICAgICAgICAnZ2VuX2FpLnJlcXVlc3QucHJlc2VuY2VfcGVuYWx0eSc6XG4gICAgICAgICAgICAgICAgICAgIGNhbGxTZXR0aW5ncy5wcmVzZW5jZVBlbmFsdHksXG4gICAgICAgICAgICAgICAgICAnZ2VuX2FpLnJlcXVlc3Quc3RvcF9zZXF1ZW5jZXMnOiBjYWxsU2V0dGluZ3Muc3RvcFNlcXVlbmNlcyxcbiAgICAgICAgICAgICAgICAgICdnZW5fYWkucmVxdWVzdC50ZW1wZXJhdHVyZSc6IGNhbGxTZXR0aW5ncy50ZW1wZXJhdHVyZSxcbiAgICAgICAgICAgICAgICAgICdnZW5fYWkucmVxdWVzdC50b3Bfayc6IGNhbGxTZXR0aW5ncy50b3BLLFxuICAgICAgICAgICAgICAgICAgJ2dlbl9haS5yZXF1ZXN0LnRvcF9wJzogY2FsbFNldHRpbmdzLnRvcFAsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIHRyYWNlcixcbiAgICAgICAgICAgICAgZW5kV2hlbkRvbmU6IGZhbHNlLFxuICAgICAgICAgICAgICBmbjogYXN5bmMgZG9TdHJlYW1TcGFuID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgc3RhcnRUaW1lc3RhbXBNczogbm93KCksIC8vIGdldCBiZWZvcmUgdGhlIGNhbGxcbiAgICAgICAgICAgICAgICAgIGRvU3RyZWFtU3BhbixcbiAgICAgICAgICAgICAgICAgIHJlc3VsdDogYXdhaXQgc3RlcE1vZGVsLmRvU3RyZWFtKHtcbiAgICAgICAgICAgICAgICAgICAgLi4uY2FsbFNldHRpbmdzLFxuICAgICAgICAgICAgICAgICAgICB0b29sczogc3RlcFRvb2xzLFxuICAgICAgICAgICAgICAgICAgICB0b29sQ2hvaWNlOiBzdGVwVG9vbENob2ljZSxcbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2VGb3JtYXQ6IG91dHB1dD8ucmVzcG9uc2VGb3JtYXQsXG4gICAgICAgICAgICAgICAgICAgIHByb21wdDogcHJvbXB0TWVzc2FnZXMsXG4gICAgICAgICAgICAgICAgICAgIHByb3ZpZGVyT3B0aW9ucyxcbiAgICAgICAgICAgICAgICAgICAgYWJvcnRTaWduYWwsXG4gICAgICAgICAgICAgICAgICAgIGhlYWRlcnMsXG4gICAgICAgICAgICAgICAgICAgIGluY2x1ZGVSYXdDaHVua3MsXG4gICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGNvbnN0IHN0cmVhbVdpdGhUb29sUmVzdWx0cyA9IHJ1blRvb2xzVHJhbnNmb3JtYXRpb24oe1xuICAgICAgICAgICAgdG9vbHMsXG4gICAgICAgICAgICBnZW5lcmF0b3JTdHJlYW06IHN0cmVhbSxcbiAgICAgICAgICAgIHRyYWNlcixcbiAgICAgICAgICAgIHRlbGVtZXRyeSxcbiAgICAgICAgICAgIHN5c3RlbSxcbiAgICAgICAgICAgIG1lc3NhZ2VzOiBzdGVwSW5wdXRNZXNzYWdlcyxcbiAgICAgICAgICAgIHJlcGFpclRvb2xDYWxsLFxuICAgICAgICAgICAgYWJvcnRTaWduYWwsXG4gICAgICAgICAgICBleHBlcmltZW50YWxfY29udGV4dCxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNvbnN0IHN0ZXBSZXF1ZXN0ID0gcmVxdWVzdCA/PyB7fTtcbiAgICAgICAgICBjb25zdCBzdGVwVG9vbENhbGxzOiBUeXBlZFRvb2xDYWxsPFRPT0xTPltdID0gW107XG4gICAgICAgICAgY29uc3Qgc3RlcFRvb2xPdXRwdXRzOiBUb29sT3V0cHV0PFRPT0xTPltdID0gW107XG4gICAgICAgICAgbGV0IHdhcm5pbmdzOiBMYW5ndWFnZU1vZGVsVjJDYWxsV2FybmluZ1tdIHwgdW5kZWZpbmVkO1xuXG4gICAgICAgICAgY29uc3QgYWN0aXZlVG9vbENhbGxUb29sTmFtZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcblxuICAgICAgICAgIGxldCBzdGVwRmluaXNoUmVhc29uOiBGaW5pc2hSZWFzb24gPSAndW5rbm93bic7XG4gICAgICAgICAgbGV0IHN0ZXBVc2FnZTogTGFuZ3VhZ2VNb2RlbFVzYWdlID0ge1xuICAgICAgICAgICAgaW5wdXRUb2tlbnM6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIG91dHB1dFRva2VuczogdW5kZWZpbmVkLFxuICAgICAgICAgICAgdG90YWxUb2tlbnM6IHVuZGVmaW5lZCxcbiAgICAgICAgICB9O1xuICAgICAgICAgIGxldCBzdGVwUHJvdmlkZXJNZXRhZGF0YTogUHJvdmlkZXJNZXRhZGF0YSB8IHVuZGVmaW5lZDtcbiAgICAgICAgICBsZXQgc3RlcEZpcnN0Q2h1bmsgPSB0cnVlO1xuICAgICAgICAgIGxldCBzdGVwUmVzcG9uc2U6IHsgaWQ6IHN0cmluZzsgdGltZXN0YW1wOiBEYXRlOyBtb2RlbElkOiBzdHJpbmcgfSA9IHtcbiAgICAgICAgICAgIGlkOiBnZW5lcmF0ZUlkKCksXG4gICAgICAgICAgICB0aW1lc3RhbXA6IGN1cnJlbnREYXRlKCksXG4gICAgICAgICAgICBtb2RlbElkOiBtb2RlbC5tb2RlbElkLFxuICAgICAgICAgIH07XG5cbiAgICAgICAgICAvLyByYXcgdGV4dCBhcyBpdCBjb21lcyBmcm9tIHRoZSBwcm92aWRlci4gcmVjb3JkZWQgZm9yIHRlbGVtZXRyeS5cbiAgICAgICAgICBsZXQgYWN0aXZlVGV4dCA9ICcnO1xuXG4gICAgICAgICAgc2VsZi5hZGRTdHJlYW0oXG4gICAgICAgICAgICBzdHJlYW1XaXRoVG9vbFJlc3VsdHMucGlwZVRocm91Z2goXG4gICAgICAgICAgICAgIG5ldyBUcmFuc2Zvcm1TdHJlYW08XG4gICAgICAgICAgICAgICAgU2luZ2xlUmVxdWVzdFRleHRTdHJlYW1QYXJ0PFRPT0xTPixcbiAgICAgICAgICAgICAgICBUZXh0U3RyZWFtUGFydDxUT09MUz5cbiAgICAgICAgICAgICAgPih7XG4gICAgICAgICAgICAgICAgYXN5bmMgdHJhbnNmb3JtKGNodW5rLCBjb250cm9sbGVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgICAgICAgICAgICBpZiAoY2h1bmsudHlwZSA9PT0gJ3N0cmVhbS1zdGFydCcpIHtcbiAgICAgICAgICAgICAgICAgICAgd2FybmluZ3MgPSBjaHVuay53YXJuaW5ncztcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOyAvLyBzdHJlYW0gc3RhcnQgY2h1bmtzIGFyZSBzZW50IGltbWVkaWF0ZWx5IGFuZCBkbyBub3QgY291bnQgYXMgZmlyc3QgY2h1bmtcbiAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgaWYgKHN0ZXBGaXJzdENodW5rKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFRlbGVtZXRyeSBmb3IgZmlyc3QgY2h1bms6XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG1zVG9GaXJzdENodW5rID0gbm93KCkgLSBzdGFydFRpbWVzdGFtcE1zO1xuXG4gICAgICAgICAgICAgICAgICAgIHN0ZXBGaXJzdENodW5rID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICAgICAgZG9TdHJlYW1TcGFuLmFkZEV2ZW50KCdhaS5zdHJlYW0uZmlyc3RDaHVuaycsIHtcbiAgICAgICAgICAgICAgICAgICAgICAnYWkucmVzcG9uc2UubXNUb0ZpcnN0Q2h1bmsnOiBtc1RvRmlyc3RDaHVuayxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgZG9TdHJlYW1TcGFuLnNldEF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgICAgICAgICAgICdhaS5yZXNwb25zZS5tc1RvRmlyc3RDaHVuayc6IG1zVG9GaXJzdENodW5rLFxuICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBTdGVwIHN0YXJ0OlxuICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdzdGFydC1zdGVwJyxcbiAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0OiBzdGVwUmVxdWVzdCxcbiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nczogd2FybmluZ3MgPz8gW10sXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICBjb25zdCBjaHVua1R5cGUgPSBjaHVuay50eXBlO1xuICAgICAgICAgICAgICAgICAgc3dpdGNoIChjaHVua1R5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAndGV4dC1zdGFydCc6XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3RleHQtZW5kJzoge1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShjaHVuayk7XG4gICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjYXNlICd0ZXh0LWRlbHRhJzoge1xuICAgICAgICAgICAgICAgICAgICAgIGlmIChjaHVuay5kZWx0YS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAndGV4dC1kZWx0YScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlkOiBjaHVuay5pZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dDogY2h1bmsuZGVsdGEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IGNodW5rLnByb3ZpZGVyTWV0YWRhdGEsXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFjdGl2ZVRleHQgKz0gY2h1bmsuZGVsdGE7XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgY2FzZSAncmVhc29uaW5nLXN0YXJ0JzpcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAncmVhc29uaW5nLWVuZCc6IHtcbiAgICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoY2h1bmspO1xuICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgY2FzZSAncmVhc29uaW5nLWRlbHRhJzoge1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAncmVhc29uaW5nLWRlbHRhJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlkOiBjaHVuay5pZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHQ6IGNodW5rLmRlbHRhLFxuICAgICAgICAgICAgICAgICAgICAgICAgcHJvdmlkZXJNZXRhZGF0YTogY2h1bmsucHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3Rvb2wtY2FsbCc6IHtcbiAgICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoY2h1bmspO1xuICAgICAgICAgICAgICAgICAgICAgIC8vIHN0b3JlIHRvb2wgY2FsbHMgZm9yIG9uRmluaXNoIGNhbGxiYWNrIGFuZCB0b29sQ2FsbHMgcHJvbWlzZTpcbiAgICAgICAgICAgICAgICAgICAgICBzdGVwVG9vbENhbGxzLnB1c2goY2h1bmspO1xuICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgY2FzZSAndG9vbC1yZXN1bHQnOiB7XG4gICAgICAgICAgICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKGNodW5rKTtcblxuICAgICAgICAgICAgICAgICAgICAgIGlmICghY2h1bmsucHJlbGltaW5hcnkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0ZXBUb29sT3V0cHV0cy5wdXNoKGNodW5rKTtcbiAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3Rvb2wtZXJyb3InOiB7XG4gICAgICAgICAgICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKGNodW5rKTtcbiAgICAgICAgICAgICAgICAgICAgICBzdGVwVG9vbE91dHB1dHMucHVzaChjaHVuayk7XG4gICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjYXNlICdyZXNwb25zZS1tZXRhZGF0YSc6IHtcbiAgICAgICAgICAgICAgICAgICAgICBzdGVwUmVzcG9uc2UgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZDogY2h1bmsuaWQgPz8gc3RlcFJlc3BvbnNlLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGltZXN0YW1wOiBjaHVuay50aW1lc3RhbXAgPz8gc3RlcFJlc3BvbnNlLnRpbWVzdGFtcCxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1vZGVsSWQ6IGNodW5rLm1vZGVsSWQgPz8gc3RlcFJlc3BvbnNlLm1vZGVsSWQsXG4gICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2ZpbmlzaCc6IHtcbiAgICAgICAgICAgICAgICAgICAgICAvLyBOb3RlOiB0b29sIGV4ZWN1dGlvbnMgbWlnaHQgbm90IGJlIGZpbmlzaGVkIHlldCB3aGVuIHRoZSBmaW5pc2ggZXZlbnQgaXMgZW1pdHRlZC5cbiAgICAgICAgICAgICAgICAgICAgICAvLyBzdG9yZSB1c2FnZSBhbmQgZmluaXNoIHJlYXNvbiBmb3IgcHJvbWlzZXMgYW5kIG9uRmluaXNoIGNhbGxiYWNrOlxuICAgICAgICAgICAgICAgICAgICAgIHN0ZXBVc2FnZSA9IGNodW5rLnVzYWdlO1xuICAgICAgICAgICAgICAgICAgICAgIHN0ZXBGaW5pc2hSZWFzb24gPSBjaHVuay5maW5pc2hSZWFzb247XG4gICAgICAgICAgICAgICAgICAgICAgc3RlcFByb3ZpZGVyTWV0YWRhdGEgPSBjaHVuay5wcm92aWRlck1ldGFkYXRhO1xuXG4gICAgICAgICAgICAgICAgICAgICAgLy8gVGVsZW1ldHJ5IGZvciBmaW5pc2ggZXZlbnQgdGltaW5nXG4gICAgICAgICAgICAgICAgICAgICAgLy8gKHNpbmNlIHRvb2wgZXhlY3V0aW9ucyBjYW4gdGFrZSBsb25nZXIgYW5kIGRpc3RvcnQgY2FsY3VsYXRpb25zKVxuICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1zVG9GaW5pc2ggPSBub3coKSAtIHN0YXJ0VGltZXN0YW1wTXM7XG4gICAgICAgICAgICAgICAgICAgICAgZG9TdHJlYW1TcGFuLmFkZEV2ZW50KCdhaS5zdHJlYW0uZmluaXNoJyk7XG4gICAgICAgICAgICAgICAgICAgICAgZG9TdHJlYW1TcGFuLnNldEF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLm1zVG9GaW5pc2gnOiBtc1RvRmluaXNoLFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLmF2Z091dHB1dFRva2Vuc1BlclNlY29uZCc6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICgxMDAwICogKHN0ZXBVc2FnZS5vdXRwdXRUb2tlbnMgPz8gMCkpIC8gbXNUb0ZpbmlzaCxcbiAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnZmlsZSc6IHtcbiAgICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoY2h1bmspO1xuICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnc291cmNlJzoge1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShjaHVuayk7XG4gICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjYXNlICd0b29sLWlucHV0LXN0YXJ0Jzoge1xuICAgICAgICAgICAgICAgICAgICAgIGFjdGl2ZVRvb2xDYWxsVG9vbE5hbWVzW2NodW5rLmlkXSA9IGNodW5rLnRvb2xOYW1lO1xuXG4gICAgICAgICAgICAgICAgICAgICAgY29uc3QgdG9vbCA9IHRvb2xzPy5bY2h1bmsudG9vbE5hbWVdO1xuICAgICAgICAgICAgICAgICAgICAgIGlmICh0b29sPy5vbklucHV0U3RhcnQgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgdG9vbC5vbklucHV0U3RhcnQoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICB0b29sQ2FsbElkOiBjaHVuay5pZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZXM6IHN0ZXBJbnB1dE1lc3NhZ2VzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBhYm9ydFNpZ25hbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwZXJpbWVudGFsX2NvbnRleHQsXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgICAgICAgICAgICAgLi4uY2h1bmssXG4gICAgICAgICAgICAgICAgICAgICAgICBkeW5hbWljOiB0b29sPy50eXBlID09PSAnZHluYW1pYycsXG4gICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjYXNlICd0b29sLWlucHV0LWVuZCc6IHtcbiAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgYWN0aXZlVG9vbENhbGxUb29sTmFtZXNbY2h1bmsuaWRdO1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShjaHVuayk7XG4gICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjYXNlICd0b29sLWlucHV0LWRlbHRhJzoge1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRvb2xOYW1lID0gYWN0aXZlVG9vbENhbGxUb29sTmFtZXNbY2h1bmsuaWRdO1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRvb2wgPSB0b29scz8uW3Rvb2xOYW1lXTtcblxuICAgICAgICAgICAgICAgICAgICAgIGlmICh0b29sPy5vbklucHV0RGVsdGEgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgdG9vbC5vbklucHV0RGVsdGEoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dFRleHREZWx0YTogY2h1bmsuZGVsdGEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IGNodW5rLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlczogc3RlcElucHV0TWVzc2FnZXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0U2lnbmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBleHBlcmltZW50YWxfY29udGV4dCxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShjaHVuayk7XG4gICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjYXNlICdlcnJvcic6IHtcbiAgICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoY2h1bmspO1xuICAgICAgICAgICAgICAgICAgICAgIHN0ZXBGaW5pc2hSZWFzb24gPSAnZXJyb3InO1xuICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgY2FzZSAncmF3Jzoge1xuICAgICAgICAgICAgICAgICAgICAgIGlmIChpbmNsdWRlUmF3Q2h1bmtzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoY2h1bmspO1xuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBleGhhdXN0aXZlQ2hlY2s6IG5ldmVyID0gY2h1bmtUeXBlO1xuICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBjaHVuayB0eXBlOiAke2V4aGF1c3RpdmVDaGVja31gKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgICAgICAvLyBpbnZva2Ugb25GaW5pc2ggY2FsbGJhY2sgYW5kIHJlc29sdmUgdG9vbFJlc3VsdHMgcHJvbWlzZSB3aGVuIHRoZSBzdHJlYW0gaXMgYWJvdXQgdG8gY2xvc2U6XG4gICAgICAgICAgICAgICAgYXN5bmMgZmx1c2goY29udHJvbGxlcikge1xuICAgICAgICAgICAgICAgICAgY29uc3Qgc3RlcFRvb2xDYWxsc0pzb24gPVxuICAgICAgICAgICAgICAgICAgICBzdGVwVG9vbENhbGxzLmxlbmd0aCA+IDBcbiAgICAgICAgICAgICAgICAgICAgICA/IEpTT04uc3RyaW5naWZ5KHN0ZXBUb29sQ2FsbHMpXG4gICAgICAgICAgICAgICAgICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgICAgICAgICAgIC8vIHJlY29yZCB0ZWxlbWV0cnkgaW5mb3JtYXRpb24gZmlyc3QgdG8gZW5zdXJlIGJlc3QgZWZmb3J0IHRpbWluZ1xuICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgZG9TdHJlYW1TcGFuLnNldEF0dHJpYnV0ZXMoXG4gICAgICAgICAgICAgICAgICAgICAgc2VsZWN0VGVsZW1ldHJ5QXR0cmlidXRlcyh7XG4gICAgICAgICAgICAgICAgICAgICAgICB0ZWxlbWV0cnksXG4gICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICdhaS5yZXNwb25zZS5maW5pc2hSZWFzb24nOiBzdGVwRmluaXNoUmVhc29uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAnYWkucmVzcG9uc2UudGV4dCc6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQ6ICgpID0+IGFjdGl2ZVRleHQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICdhaS5yZXNwb25zZS50b29sQ2FsbHMnOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0OiAoKSA9PiBzdGVwVG9vbENhbGxzSnNvbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLmlkJzogc3RlcFJlc3BvbnNlLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAnYWkucmVzcG9uc2UubW9kZWwnOiBzdGVwUmVzcG9uc2UubW9kZWxJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLnRpbWVzdGFtcCc6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcFJlc3BvbnNlLnRpbWVzdGFtcC50b0lTT1N0cmluZygpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAnYWkucmVzcG9uc2UucHJvdmlkZXJNZXRhZGF0YSc6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkoc3RlcFByb3ZpZGVyTWV0YWRhdGEpLFxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICdhaS51c2FnZS5pbnB1dFRva2Vucyc6IHN0ZXBVc2FnZS5pbnB1dFRva2VucyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgJ2FpLnVzYWdlLm91dHB1dFRva2Vucyc6IHN0ZXBVc2FnZS5vdXRwdXRUb2tlbnMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICdhaS51c2FnZS50b3RhbFRva2Vucyc6IHN0ZXBVc2FnZS50b3RhbFRva2VucyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgJ2FpLnVzYWdlLnJlYXNvbmluZ1Rva2Vucyc6IHN0ZXBVc2FnZS5yZWFzb25pbmdUb2tlbnMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICdhaS51c2FnZS5jYWNoZWRJbnB1dFRva2Vucyc6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcFVzYWdlLmNhY2hlZElucHV0VG9rZW5zLFxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHN0YW5kYXJkaXplZCBnZW4tYWkgbGxtIHNwYW4gYXR0cmlidXRlczpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgJ2dlbl9haS5yZXNwb25zZS5maW5pc2hfcmVhc29ucyc6IFtzdGVwRmluaXNoUmVhc29uXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgJ2dlbl9haS5yZXNwb25zZS5pZCc6IHN0ZXBSZXNwb25zZS5pZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgJ2dlbl9haS5yZXNwb25zZS5tb2RlbCc6IHN0ZXBSZXNwb25zZS5tb2RlbElkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAnZ2VuX2FpLnVzYWdlLmlucHV0X3Rva2Vucyc6IHN0ZXBVc2FnZS5pbnB1dFRva2VucyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgJ2dlbl9haS51c2FnZS5vdXRwdXRfdG9rZW5zJzogc3RlcFVzYWdlLm91dHB1dFRva2VucyxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAvLyBpZ25vcmUgZXJyb3Igc2V0dGluZyB0ZWxlbWV0cnkgYXR0cmlidXRlc1xuICAgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gZmluaXNoIGRvU3RyZWFtU3BhbiBiZWZvcmUgb3RoZXIgb3BlcmF0aW9ucyBmb3IgY29ycmVjdCB0aW1pbmc6XG4gICAgICAgICAgICAgICAgICAgIGRvU3RyZWFtU3Bhbi5lbmQoKTtcbiAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2ZpbmlzaC1zdGVwJyxcbiAgICAgICAgICAgICAgICAgICAgZmluaXNoUmVhc29uOiBzdGVwRmluaXNoUmVhc29uLFxuICAgICAgICAgICAgICAgICAgICB1c2FnZTogc3RlcFVzYWdlLFxuICAgICAgICAgICAgICAgICAgICBwcm92aWRlck1ldGFkYXRhOiBzdGVwUHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2U6IHtcbiAgICAgICAgICAgICAgICAgICAgICAuLi5zdGVwUmVzcG9uc2UsXG4gICAgICAgICAgICAgICAgICAgICAgaGVhZGVyczogcmVzcG9uc2U/LmhlYWRlcnMsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgY29uc3QgY29tYmluZWRVc2FnZSA9IGFkZExhbmd1YWdlTW9kZWxVc2FnZSh1c2FnZSwgc3RlcFVzYWdlKTtcblxuICAgICAgICAgICAgICAgICAgLy8gd2FpdCBmb3IgdGhlIHN0ZXAgdG8gYmUgZnVsbHkgcHJvY2Vzc2VkIGJ5IHRoZSBldmVudCBwcm9jZXNzb3JcbiAgICAgICAgICAgICAgICAgIC8vIHRvIGVuc3VyZSB0aGF0IHRoZSByZWNvcmRlZCBzdGVwcyBhcmUgY29tcGxldGU6XG4gICAgICAgICAgICAgICAgICBhd2FpdCBzdGVwRmluaXNoLnByb21pc2U7XG5cbiAgICAgICAgICAgICAgICAgIGNvbnN0IGNsaWVudFRvb2xDYWxscyA9IHN0ZXBUb29sQ2FsbHMuZmlsdGVyKFxuICAgICAgICAgICAgICAgICAgICB0b29sQ2FsbCA9PiB0b29sQ2FsbC5wcm92aWRlckV4ZWN1dGVkICE9PSB0cnVlLFxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGNsaWVudFRvb2xPdXRwdXRzID0gc3RlcFRvb2xPdXRwdXRzLmZpbHRlcihcbiAgICAgICAgICAgICAgICAgICAgdG9vbE91dHB1dCA9PiB0b29sT3V0cHV0LnByb3ZpZGVyRXhlY3V0ZWQgIT09IHRydWUsXG4gICAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgIGNsaWVudFRvb2xDYWxscy5sZW5ndGggPiAwICYmXG4gICAgICAgICAgICAgICAgICAgIC8vIGFsbCBjdXJyZW50IHRvb2wgY2FsbHMgaGF2ZSBvdXRwdXRzIChpbmNsLiBleGVjdXRpb24gZXJyb3JzKTpcbiAgICAgICAgICAgICAgICAgICAgY2xpZW50VG9vbE91dHB1dHMubGVuZ3RoID09PSBjbGllbnRUb29sQ2FsbHMubGVuZ3RoICYmXG4gICAgICAgICAgICAgICAgICAgIC8vIGNvbnRpbnVlIHVudGlsIGEgc3RvcCBjb25kaXRpb24gaXMgbWV0OlxuICAgICAgICAgICAgICAgICAgICAhKGF3YWl0IGlzU3RvcENvbmRpdGlvbk1ldCh7XG4gICAgICAgICAgICAgICAgICAgICAgc3RvcENvbmRpdGlvbnMsXG4gICAgICAgICAgICAgICAgICAgICAgc3RlcHM6IHJlY29yZGVkU3RlcHMsXG4gICAgICAgICAgICAgICAgICAgIH0pKVxuICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGFwcGVuZCB0byBtZXNzYWdlcyBmb3IgdGhlIG5leHQgc3RlcDpcbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2VNZXNzYWdlcy5wdXNoKFxuICAgICAgICAgICAgICAgICAgICAgIC4uLnRvUmVzcG9uc2VNZXNzYWdlcyh7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50OlxuICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB1c2UgdHJhbnNmb3JtZWQgY29udGVudCB0byBjcmVhdGUgdGhlIG1lc3NhZ2VzIGZvciB0aGUgbmV4dCBzdGVwOlxuICAgICAgICAgICAgICAgICAgICAgICAgICByZWNvcmRlZFN0ZXBzW3JlY29yZGVkU3RlcHMubGVuZ3RoIC0gMV0uY29udGVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvb2xzLFxuICAgICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgYXdhaXQgc3RyZWFtU3RlcCh7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50U3RlcDogY3VycmVudFN0ZXAgKyAxLFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2VNZXNzYWdlcyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHVzYWdlOiBjb21iaW5lZFVzYWdlLFxuICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnZXJyb3InLFxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IsXG4gICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICBzZWxmLmNsb3NlU3RyZWFtKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2ZpbmlzaCcsXG4gICAgICAgICAgICAgICAgICAgICAgZmluaXNoUmVhc29uOiBzdGVwRmluaXNoUmVhc29uLFxuICAgICAgICAgICAgICAgICAgICAgIHRvdGFsVXNhZ2U6IGNvbWJpbmVkVXNhZ2UsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuY2xvc2VTdHJlYW0oKTsgLy8gY2xvc2UgdGhlIHN0aXRjaGFibGUgc3RyZWFtXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICApLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBhZGQgdGhlIGluaXRpYWwgc3RyZWFtIHRvIHRoZSBzdGl0Y2hhYmxlIHN0cmVhbVxuICAgICAgICBhd2FpdCBzdHJlYW1TdGVwKHtcbiAgICAgICAgICBjdXJyZW50U3RlcDogMCxcbiAgICAgICAgICByZXNwb25zZU1lc3NhZ2VzOiBbXSxcbiAgICAgICAgICB1c2FnZToge1xuICAgICAgICAgICAgaW5wdXRUb2tlbnM6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIG91dHB1dFRva2VuczogdW5kZWZpbmVkLFxuICAgICAgICAgICAgdG90YWxUb2tlbnM6IHVuZGVmaW5lZCxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgfSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgLy8gYWRkIGFuIGVycm9yIHN0cmVhbSBwYXJ0IGFuZCBjbG9zZSB0aGUgc3RyZWFtczpcbiAgICAgIHNlbGYuYWRkU3RyZWFtKFxuICAgICAgICBuZXcgUmVhZGFibGVTdHJlYW0oe1xuICAgICAgICAgIHN0YXJ0KGNvbnRyb2xsZXIpIHtcbiAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7IHR5cGU6ICdlcnJvcicsIGVycm9yIH0pO1xuICAgICAgICAgICAgY29udHJvbGxlci5jbG9zZSgpO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICAgIHNlbGYuY2xvc2VTdHJlYW0oKTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldCBzdGVwcygpIHtcbiAgICAvLyB3aGVuIGFueSBvZiB0aGUgcHJvbWlzZXMgYXJlIGFjY2Vzc2VkLCB0aGUgc3RyZWFtIGlzIGNvbnN1bWVkXG4gICAgLy8gc28gaXQgcmVzb2x2ZXMgd2l0aG91dCBuZWVkaW5nIHRvIGNvbnN1bWUgdGhlIHN0cmVhbSBzZXBhcmF0ZWx5XG4gICAgdGhpcy5jb25zdW1lU3RyZWFtKCk7XG5cbiAgICByZXR1cm4gdGhpcy5fc3RlcHMucHJvbWlzZTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0IGZpbmFsU3RlcCgpIHtcbiAgICByZXR1cm4gdGhpcy5zdGVwcy50aGVuKHN0ZXBzID0+IHN0ZXBzW3N0ZXBzLmxlbmd0aCAtIDFdKTtcbiAgfVxuXG4gIGdldCBjb250ZW50KCkge1xuICAgIHJldHVybiB0aGlzLmZpbmFsU3RlcC50aGVuKHN0ZXAgPT4gc3RlcC5jb250ZW50KTtcbiAgfVxuXG4gIGdldCB3YXJuaW5ncygpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAudGhlbihzdGVwID0+IHN0ZXAud2FybmluZ3MpO1xuICB9XG5cbiAgZ2V0IHByb3ZpZGVyTWV0YWRhdGEoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmluYWxTdGVwLnRoZW4oc3RlcCA9PiBzdGVwLnByb3ZpZGVyTWV0YWRhdGEpO1xuICB9XG5cbiAgZ2V0IHRleHQoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmluYWxTdGVwLnRoZW4oc3RlcCA9PiBzdGVwLnRleHQpO1xuICB9XG5cbiAgZ2V0IHJlYXNvbmluZ1RleHQoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmluYWxTdGVwLnRoZW4oc3RlcCA9PiBzdGVwLnJlYXNvbmluZ1RleHQpO1xuICB9XG5cbiAgZ2V0IHJlYXNvbmluZygpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAudGhlbihzdGVwID0+IHN0ZXAucmVhc29uaW5nKTtcbiAgfVxuXG4gIGdldCBzb3VyY2VzKCkge1xuICAgIHJldHVybiB0aGlzLmZpbmFsU3RlcC50aGVuKHN0ZXAgPT4gc3RlcC5zb3VyY2VzKTtcbiAgfVxuXG4gIGdldCBmaWxlcygpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAudGhlbihzdGVwID0+IHN0ZXAuZmlsZXMpO1xuICB9XG5cbiAgZ2V0IHRvb2xDYWxscygpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAudGhlbihzdGVwID0+IHN0ZXAudG9vbENhbGxzKTtcbiAgfVxuXG4gIGdldCBzdGF0aWNUb29sQ2FsbHMoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmluYWxTdGVwLnRoZW4oc3RlcCA9PiBzdGVwLnN0YXRpY1Rvb2xDYWxscyk7XG4gIH1cblxuICBnZXQgZHluYW1pY1Rvb2xDYWxscygpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAudGhlbihzdGVwID0+IHN0ZXAuZHluYW1pY1Rvb2xDYWxscyk7XG4gIH1cblxuICBnZXQgdG9vbFJlc3VsdHMoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmluYWxTdGVwLnRoZW4oc3RlcCA9PiBzdGVwLnRvb2xSZXN1bHRzKTtcbiAgfVxuXG4gIGdldCBzdGF0aWNUb29sUmVzdWx0cygpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAudGhlbihzdGVwID0+IHN0ZXAuc3RhdGljVG9vbFJlc3VsdHMpO1xuICB9XG5cbiAgZ2V0IGR5bmFtaWNUb29sUmVzdWx0cygpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAudGhlbihzdGVwID0+IHN0ZXAuZHluYW1pY1Rvb2xSZXN1bHRzKTtcbiAgfVxuXG4gIGdldCB1c2FnZSgpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAudGhlbihzdGVwID0+IHN0ZXAudXNhZ2UpO1xuICB9XG5cbiAgZ2V0IHJlcXVlc3QoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmluYWxTdGVwLnRoZW4oc3RlcCA9PiBzdGVwLnJlcXVlc3QpO1xuICB9XG5cbiAgZ2V0IHJlc3BvbnNlKCkge1xuICAgIHJldHVybiB0aGlzLmZpbmFsU3RlcC50aGVuKHN0ZXAgPT4gc3RlcC5yZXNwb25zZSk7XG4gIH1cblxuICBnZXQgdG90YWxVc2FnZSgpIHtcbiAgICAvLyB3aGVuIGFueSBvZiB0aGUgcHJvbWlzZXMgYXJlIGFjY2Vzc2VkLCB0aGUgc3RyZWFtIGlzIGNvbnN1bWVkXG4gICAgLy8gc28gaXQgcmVzb2x2ZXMgd2l0aG91dCBuZWVkaW5nIHRvIGNvbnN1bWUgdGhlIHN0cmVhbSBzZXBhcmF0ZWx5XG4gICAgdGhpcy5jb25zdW1lU3RyZWFtKCk7XG5cbiAgICByZXR1cm4gdGhpcy5fdG90YWxVc2FnZS5wcm9taXNlO1xuICB9XG5cbiAgZ2V0IGZpbmlzaFJlYXNvbigpIHtcbiAgICAvLyB3aGVuIGFueSBvZiB0aGUgcHJvbWlzZXMgYXJlIGFjY2Vzc2VkLCB0aGUgc3RyZWFtIGlzIGNvbnN1bWVkXG4gICAgLy8gc28gaXQgcmVzb2x2ZXMgd2l0aG91dCBuZWVkaW5nIHRvIGNvbnN1bWUgdGhlIHN0cmVhbSBzZXBhcmF0ZWx5XG4gICAgdGhpcy5jb25zdW1lU3RyZWFtKCk7XG5cbiAgICByZXR1cm4gdGhpcy5fZmluaXNoUmVhc29uLnByb21pc2U7XG4gIH1cblxuICAvKipcblNwbGl0IG91dCBhIG5ldyBzdHJlYW0gZnJvbSB0aGUgb3JpZ2luYWwgc3RyZWFtLlxuVGhlIG9yaWdpbmFsIHN0cmVhbSBpcyByZXBsYWNlZCB0byBhbGxvdyBmb3IgZnVydGhlciBzcGxpdHRpbmcsXG5zaW5jZSB3ZSBkbyBub3Qga25vdyBob3cgbWFueSB0aW1lcyB0aGUgc3RyZWFtIHdpbGwgYmUgc3BsaXQuXG5cbk5vdGU6IHRoaXMgbGVhZHMgdG8gYnVmZmVyaW5nIHRoZSBzdHJlYW0gY29udGVudCBvbiB0aGUgc2VydmVyLlxuSG93ZXZlciwgdGhlIExMTSByZXN1bHRzIGFyZSBleHBlY3RlZCB0byBiZSBzbWFsbCBlbm91Z2ggdG8gbm90IGNhdXNlIGlzc3Vlcy5cbiAgICovXG4gIHByaXZhdGUgdGVlU3RyZWFtKCkge1xuICAgIGNvbnN0IFtzdHJlYW0xLCBzdHJlYW0yXSA9IHRoaXMuYmFzZVN0cmVhbS50ZWUoKTtcbiAgICB0aGlzLmJhc2VTdHJlYW0gPSBzdHJlYW0yO1xuICAgIHJldHVybiBzdHJlYW0xO1xuICB9XG5cbiAgZ2V0IHRleHRTdHJlYW0oKTogQXN5bmNJdGVyYWJsZVN0cmVhbTxzdHJpbmc+IHtcbiAgICByZXR1cm4gY3JlYXRlQXN5bmNJdGVyYWJsZVN0cmVhbShcbiAgICAgIHRoaXMudGVlU3RyZWFtKCkucGlwZVRocm91Z2goXG4gICAgICAgIG5ldyBUcmFuc2Zvcm1TdHJlYW08RW5yaWNoZWRTdHJlYW1QYXJ0PFRPT0xTLCBQQVJUSUFMX09VVFBVVD4sIHN0cmluZz4oe1xuICAgICAgICAgIHRyYW5zZm9ybSh7IHBhcnQgfSwgY29udHJvbGxlcikge1xuICAgICAgICAgICAgaWYgKHBhcnQudHlwZSA9PT0gJ3RleHQtZGVsdGEnKSB7XG4gICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShwYXJ0LnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgKSxcbiAgICApO1xuICB9XG5cbiAgZ2V0IGZ1bGxTdHJlYW0oKTogQXN5bmNJdGVyYWJsZVN0cmVhbTxUZXh0U3RyZWFtUGFydDxUT09MUz4+IHtcbiAgICByZXR1cm4gY3JlYXRlQXN5bmNJdGVyYWJsZVN0cmVhbShcbiAgICAgIHRoaXMudGVlU3RyZWFtKCkucGlwZVRocm91Z2goXG4gICAgICAgIG5ldyBUcmFuc2Zvcm1TdHJlYW08XG4gICAgICAgICAgRW5yaWNoZWRTdHJlYW1QYXJ0PFRPT0xTLCBQQVJUSUFMX09VVFBVVD4sXG4gICAgICAgICAgVGV4dFN0cmVhbVBhcnQ8VE9PTFM+XG4gICAgICAgID4oe1xuICAgICAgICAgIHRyYW5zZm9ybSh7IHBhcnQgfSwgY29udHJvbGxlcikge1xuICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHBhcnQpO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgKSxcbiAgICApO1xuICB9XG5cbiAgYXN5bmMgY29uc3VtZVN0cmVhbShvcHRpb25zPzogQ29uc3VtZVN0cmVhbU9wdGlvbnMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgY29uc3VtZVN0cmVhbSh7XG4gICAgICAgIHN0cmVhbTogdGhpcy5mdWxsU3RyZWFtLFxuICAgICAgICBvbkVycm9yOiBvcHRpb25zPy5vbkVycm9yLFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIG9wdGlvbnM/Lm9uRXJyb3I/LihlcnJvcik7XG4gICAgfVxuICB9XG5cbiAgZ2V0IGV4cGVyaW1lbnRhbF9wYXJ0aWFsT3V0cHV0U3RyZWFtKCk6IEFzeW5jSXRlcmFibGVTdHJlYW08UEFSVElBTF9PVVRQVVQ+IHtcbiAgICBpZiAodGhpcy5vdXRwdXQgPT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IE5vT3V0cHV0U3BlY2lmaWVkRXJyb3IoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY3JlYXRlQXN5bmNJdGVyYWJsZVN0cmVhbShcbiAgICAgIHRoaXMudGVlU3RyZWFtKCkucGlwZVRocm91Z2goXG4gICAgICAgIG5ldyBUcmFuc2Zvcm1TdHJlYW08XG4gICAgICAgICAgRW5yaWNoZWRTdHJlYW1QYXJ0PFRPT0xTLCBQQVJUSUFMX09VVFBVVD4sXG4gICAgICAgICAgUEFSVElBTF9PVVRQVVRcbiAgICAgICAgPih7XG4gICAgICAgICAgdHJhbnNmb3JtKHsgcGFydGlhbE91dHB1dCB9LCBjb250cm9sbGVyKSB7XG4gICAgICAgICAgICBpZiAocGFydGlhbE91dHB1dCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShwYXJ0aWFsT3V0cHV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgICksXG4gICAgKTtcbiAgfVxuXG4gIHRvVUlNZXNzYWdlU3RyZWFtPFVJX01FU1NBR0UgZXh0ZW5kcyBVSU1lc3NhZ2U+KHtcbiAgICBvcmlnaW5hbE1lc3NhZ2VzLFxuICAgIGdlbmVyYXRlTWVzc2FnZUlkLFxuICAgIG9uRmluaXNoLFxuICAgIG1lc3NhZ2VNZXRhZGF0YSxcbiAgICBzZW5kUmVhc29uaW5nID0gdHJ1ZSxcbiAgICBzZW5kU291cmNlcyA9IGZhbHNlLFxuICAgIHNlbmRTdGFydCA9IHRydWUsXG4gICAgc2VuZEZpbmlzaCA9IHRydWUsXG4gICAgb25FcnJvciA9IGdldEVycm9yTWVzc2FnZSxcbiAgfTogVUlNZXNzYWdlU3RyZWFtT3B0aW9uczxVSV9NRVNTQUdFPiA9IHt9KTogQXN5bmNJdGVyYWJsZVN0cmVhbTxcbiAgICBJbmZlclVJTWVzc2FnZUNodW5rPFVJX01FU1NBR0U+XG4gID4ge1xuICAgIGNvbnN0IHJlc3BvbnNlTWVzc2FnZUlkID1cbiAgICAgIGdlbmVyYXRlTWVzc2FnZUlkICE9IG51bGxcbiAgICAgICAgPyBnZXRSZXNwb25zZVVJTWVzc2FnZUlkKHtcbiAgICAgICAgICAgIG9yaWdpbmFsTWVzc2FnZXMsXG4gICAgICAgICAgICByZXNwb25zZU1lc3NhZ2VJZDogZ2VuZXJhdGVNZXNzYWdlSWQsXG4gICAgICAgICAgfSlcbiAgICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICBjb25zdCB0b29sTmFtZXNCeUNhbGxJZDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuXG4gICAgY29uc3QgaXNEeW5hbWljID0gKHRvb2xDYWxsSWQ6IHN0cmluZykgPT4ge1xuICAgICAgY29uc3QgdG9vbE5hbWUgPSB0b29sTmFtZXNCeUNhbGxJZFt0b29sQ2FsbElkXTtcbiAgICAgIGNvbnN0IGR5bmFtaWMgPSB0aGlzLnRvb2xzPy5bdG9vbE5hbWVdPy50eXBlID09PSAnZHluYW1pYyc7XG4gICAgICByZXR1cm4gZHluYW1pYyA/IHRydWUgOiB1bmRlZmluZWQ7IC8vIG9ubHkgc2VuZCB3aGVuIGR5bmFtaWMgdG8gcmVkdWNlIGRhdGEgdHJhbnNmZXJcbiAgICB9O1xuXG4gICAgY29uc3QgYmFzZVN0cmVhbSA9IHRoaXMuZnVsbFN0cmVhbS5waXBlVGhyb3VnaChcbiAgICAgIG5ldyBUcmFuc2Zvcm1TdHJlYW08XG4gICAgICAgIFRleHRTdHJlYW1QYXJ0PFRPT0xTPixcbiAgICAgICAgVUlNZXNzYWdlQ2h1bms8XG4gICAgICAgICAgSW5mZXJVSU1lc3NhZ2VNZXRhZGF0YTxVSV9NRVNTQUdFPixcbiAgICAgICAgICBJbmZlclVJTWVzc2FnZURhdGE8VUlfTUVTU0FHRT5cbiAgICAgICAgPlxuICAgICAgPih7XG4gICAgICAgIHRyYW5zZm9ybTogYXN5bmMgKHBhcnQsIGNvbnRyb2xsZXIpID0+IHtcbiAgICAgICAgICBjb25zdCBtZXNzYWdlTWV0YWRhdGFWYWx1ZSA9IG1lc3NhZ2VNZXRhZGF0YT8uKHsgcGFydCB9KTtcblxuICAgICAgICAgIGNvbnN0IHBhcnRUeXBlID0gcGFydC50eXBlO1xuICAgICAgICAgIHN3aXRjaCAocGFydFR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgJ3RleHQtc3RhcnQnOiB7XG4gICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgICAgdHlwZTogJ3RleHQtc3RhcnQnLFxuICAgICAgICAgICAgICAgIGlkOiBwYXJ0LmlkLFxuICAgICAgICAgICAgICAgIC4uLihwYXJ0LnByb3ZpZGVyTWV0YWRhdGEgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgPyB7IHByb3ZpZGVyTWV0YWRhdGE6IHBhcnQucHJvdmlkZXJNZXRhZGF0YSB9XG4gICAgICAgICAgICAgICAgICA6IHt9KSxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYXNlICd0ZXh0LWRlbHRhJzoge1xuICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgICAgIHR5cGU6ICd0ZXh0LWRlbHRhJyxcbiAgICAgICAgICAgICAgICBpZDogcGFydC5pZCxcbiAgICAgICAgICAgICAgICBkZWx0YTogcGFydC50ZXh0LFxuICAgICAgICAgICAgICAgIC4uLihwYXJ0LnByb3ZpZGVyTWV0YWRhdGEgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgPyB7IHByb3ZpZGVyTWV0YWRhdGE6IHBhcnQucHJvdmlkZXJNZXRhZGF0YSB9XG4gICAgICAgICAgICAgICAgICA6IHt9KSxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYXNlICd0ZXh0LWVuZCc6IHtcbiAgICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHtcbiAgICAgICAgICAgICAgICB0eXBlOiAndGV4dC1lbmQnLFxuICAgICAgICAgICAgICAgIGlkOiBwYXJ0LmlkLFxuICAgICAgICAgICAgICAgIC4uLihwYXJ0LnByb3ZpZGVyTWV0YWRhdGEgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgPyB7IHByb3ZpZGVyTWV0YWRhdGE6IHBhcnQucHJvdmlkZXJNZXRhZGF0YSB9XG4gICAgICAgICAgICAgICAgICA6IHt9KSxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYXNlICdyZWFzb25pbmctc3RhcnQnOiB7XG4gICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgICAgdHlwZTogJ3JlYXNvbmluZy1zdGFydCcsXG4gICAgICAgICAgICAgICAgaWQ6IHBhcnQuaWQsXG4gICAgICAgICAgICAgICAgLi4uKHBhcnQucHJvdmlkZXJNZXRhZGF0YSAhPSBudWxsXG4gICAgICAgICAgICAgICAgICA/IHsgcHJvdmlkZXJNZXRhZGF0YTogcGFydC5wcm92aWRlck1ldGFkYXRhIH1cbiAgICAgICAgICAgICAgICAgIDoge30pLFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgJ3JlYXNvbmluZy1kZWx0YSc6IHtcbiAgICAgICAgICAgICAgaWYgKHNlbmRSZWFzb25pbmcpIHtcbiAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgICAgICAgdHlwZTogJ3JlYXNvbmluZy1kZWx0YScsXG4gICAgICAgICAgICAgICAgICBpZDogcGFydC5pZCxcbiAgICAgICAgICAgICAgICAgIGRlbHRhOiBwYXJ0LnRleHQsXG4gICAgICAgICAgICAgICAgICAuLi4ocGFydC5wcm92aWRlck1ldGFkYXRhICE9IG51bGxcbiAgICAgICAgICAgICAgICAgICAgPyB7IHByb3ZpZGVyTWV0YWRhdGE6IHBhcnQucHJvdmlkZXJNZXRhZGF0YSB9XG4gICAgICAgICAgICAgICAgICAgIDoge30pLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYXNlICdyZWFzb25pbmctZW5kJzoge1xuICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgICAgIHR5cGU6ICdyZWFzb25pbmctZW5kJyxcbiAgICAgICAgICAgICAgICBpZDogcGFydC5pZCxcbiAgICAgICAgICAgICAgICAuLi4ocGFydC5wcm92aWRlck1ldGFkYXRhICE9IG51bGxcbiAgICAgICAgICAgICAgICAgID8geyBwcm92aWRlck1ldGFkYXRhOiBwYXJ0LnByb3ZpZGVyTWV0YWRhdGEgfVxuICAgICAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSAnZmlsZSc6IHtcbiAgICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnZmlsZScsXG4gICAgICAgICAgICAgICAgbWVkaWFUeXBlOiBwYXJ0LmZpbGUubWVkaWFUeXBlLFxuICAgICAgICAgICAgICAgIHVybDogYGRhdGE6JHtwYXJ0LmZpbGUubWVkaWFUeXBlfTtiYXNlNjQsJHtwYXJ0LmZpbGUuYmFzZTY0fWAsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSAnc291cmNlJzoge1xuICAgICAgICAgICAgICBpZiAoc2VuZFNvdXJjZXMgJiYgcGFydC5zb3VyY2VUeXBlID09PSAndXJsJykge1xuICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgICAgICB0eXBlOiAnc291cmNlLXVybCcsXG4gICAgICAgICAgICAgICAgICBzb3VyY2VJZDogcGFydC5pZCxcbiAgICAgICAgICAgICAgICAgIHVybDogcGFydC51cmwsXG4gICAgICAgICAgICAgICAgICB0aXRsZTogcGFydC50aXRsZSxcbiAgICAgICAgICAgICAgICAgIC4uLihwYXJ0LnByb3ZpZGVyTWV0YWRhdGEgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgICA/IHsgcHJvdmlkZXJNZXRhZGF0YTogcGFydC5wcm92aWRlck1ldGFkYXRhIH1cbiAgICAgICAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBpZiAoc2VuZFNvdXJjZXMgJiYgcGFydC5zb3VyY2VUeXBlID09PSAnZG9jdW1lbnQnKSB7XG4gICAgICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHtcbiAgICAgICAgICAgICAgICAgIHR5cGU6ICdzb3VyY2UtZG9jdW1lbnQnLFxuICAgICAgICAgICAgICAgICAgc291cmNlSWQ6IHBhcnQuaWQsXG4gICAgICAgICAgICAgICAgICBtZWRpYVR5cGU6IHBhcnQubWVkaWFUeXBlLFxuICAgICAgICAgICAgICAgICAgdGl0bGU6IHBhcnQudGl0bGUsXG4gICAgICAgICAgICAgICAgICBmaWxlbmFtZTogcGFydC5maWxlbmFtZSxcbiAgICAgICAgICAgICAgICAgIC4uLihwYXJ0LnByb3ZpZGVyTWV0YWRhdGEgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgICA/IHsgcHJvdmlkZXJNZXRhZGF0YTogcGFydC5wcm92aWRlck1ldGFkYXRhIH1cbiAgICAgICAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgJ3Rvb2wtaW5wdXQtc3RhcnQnOiB7XG4gICAgICAgICAgICAgIHRvb2xOYW1lc0J5Q2FsbElkW3BhcnQuaWRdID0gcGFydC50b29sTmFtZTtcbiAgICAgICAgICAgICAgY29uc3QgZHluYW1pYyA9IGlzRHluYW1pYyhwYXJ0LmlkKTtcblxuICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgICAgIHR5cGU6ICd0b29sLWlucHV0LXN0YXJ0JyxcbiAgICAgICAgICAgICAgICB0b29sQ2FsbElkOiBwYXJ0LmlkLFxuICAgICAgICAgICAgICAgIHRvb2xOYW1lOiBwYXJ0LnRvb2xOYW1lLFxuICAgICAgICAgICAgICAgIC4uLihwYXJ0LnByb3ZpZGVyRXhlY3V0ZWQgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgPyB7IHByb3ZpZGVyRXhlY3V0ZWQ6IHBhcnQucHJvdmlkZXJFeGVjdXRlZCB9XG4gICAgICAgICAgICAgICAgICA6IHt9KSxcbiAgICAgICAgICAgICAgICAuLi4oZHluYW1pYyAhPSBudWxsID8geyBkeW5hbWljIH0gOiB7fSksXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSAndG9vbC1pbnB1dC1kZWx0YSc6IHtcbiAgICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHtcbiAgICAgICAgICAgICAgICB0eXBlOiAndG9vbC1pbnB1dC1kZWx0YScsXG4gICAgICAgICAgICAgICAgdG9vbENhbGxJZDogcGFydC5pZCxcbiAgICAgICAgICAgICAgICBpbnB1dFRleHREZWx0YTogcGFydC5kZWx0YSxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYXNlICd0b29sLWNhbGwnOiB7XG4gICAgICAgICAgICAgIHRvb2xOYW1lc0J5Q2FsbElkW3BhcnQudG9vbENhbGxJZF0gPSBwYXJ0LnRvb2xOYW1lO1xuICAgICAgICAgICAgICBjb25zdCBkeW5hbWljID0gaXNEeW5hbWljKHBhcnQudG9vbENhbGxJZCk7XG5cbiAgICAgICAgICAgICAgaWYgKHBhcnQuaW52YWxpZCkge1xuICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgICAgICB0eXBlOiAndG9vbC1pbnB1dC1lcnJvcicsXG4gICAgICAgICAgICAgICAgICB0b29sQ2FsbElkOiBwYXJ0LnRvb2xDYWxsSWQsXG4gICAgICAgICAgICAgICAgICB0b29sTmFtZTogcGFydC50b29sTmFtZSxcbiAgICAgICAgICAgICAgICAgIGlucHV0OiBwYXJ0LmlucHV0LFxuICAgICAgICAgICAgICAgICAgLi4uKHBhcnQucHJvdmlkZXJFeGVjdXRlZCAhPSBudWxsXG4gICAgICAgICAgICAgICAgICAgID8geyBwcm92aWRlckV4ZWN1dGVkOiBwYXJ0LnByb3ZpZGVyRXhlY3V0ZWQgfVxuICAgICAgICAgICAgICAgICAgICA6IHt9KSxcbiAgICAgICAgICAgICAgICAgIC4uLihwYXJ0LnByb3ZpZGVyTWV0YWRhdGEgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgICA/IHsgcHJvdmlkZXJNZXRhZGF0YTogcGFydC5wcm92aWRlck1ldGFkYXRhIH1cbiAgICAgICAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgICAgICAgICAuLi4oZHluYW1pYyAhPSBudWxsID8geyBkeW5hbWljIH0gOiB7fSksXG4gICAgICAgICAgICAgICAgICBlcnJvclRleHQ6IG9uRXJyb3IocGFydC5lcnJvciksXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHtcbiAgICAgICAgICAgICAgICAgIHR5cGU6ICd0b29sLWlucHV0LWF2YWlsYWJsZScsXG4gICAgICAgICAgICAgICAgICB0b29sQ2FsbElkOiBwYXJ0LnRvb2xDYWxsSWQsXG4gICAgICAgICAgICAgICAgICB0b29sTmFtZTogcGFydC50b29sTmFtZSxcbiAgICAgICAgICAgICAgICAgIGlucHV0OiBwYXJ0LmlucHV0LFxuICAgICAgICAgICAgICAgICAgLi4uKHBhcnQucHJvdmlkZXJFeGVjdXRlZCAhPSBudWxsXG4gICAgICAgICAgICAgICAgICAgID8geyBwcm92aWRlckV4ZWN1dGVkOiBwYXJ0LnByb3ZpZGVyRXhlY3V0ZWQgfVxuICAgICAgICAgICAgICAgICAgICA6IHt9KSxcbiAgICAgICAgICAgICAgICAgIC4uLihwYXJ0LnByb3ZpZGVyTWV0YWRhdGEgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgICA/IHsgcHJvdmlkZXJNZXRhZGF0YTogcGFydC5wcm92aWRlck1ldGFkYXRhIH1cbiAgICAgICAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgICAgICAgICAuLi4oZHluYW1pYyAhPSBudWxsID8geyBkeW5hbWljIH0gOiB7fSksXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSAndG9vbC1yZXN1bHQnOiB7XG4gICAgICAgICAgICAgIGNvbnN0IGR5bmFtaWMgPSBpc0R5bmFtaWMocGFydC50b29sQ2FsbElkKTtcblxuICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgICAgIHR5cGU6ICd0b29sLW91dHB1dC1hdmFpbGFibGUnLFxuICAgICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IHBhcnQudG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgICBvdXRwdXQ6IHBhcnQub3V0cHV0LFxuICAgICAgICAgICAgICAgIC4uLihwYXJ0LnByb3ZpZGVyRXhlY3V0ZWQgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgPyB7IHByb3ZpZGVyRXhlY3V0ZWQ6IHBhcnQucHJvdmlkZXJFeGVjdXRlZCB9XG4gICAgICAgICAgICAgICAgICA6IHt9KSxcbiAgICAgICAgICAgICAgICAuLi4ocGFydC5wcmVsaW1pbmFyeSAhPSBudWxsXG4gICAgICAgICAgICAgICAgICA/IHsgcHJlbGltaW5hcnk6IHBhcnQucHJlbGltaW5hcnkgfVxuICAgICAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgICAgICAgLi4uKGR5bmFtaWMgIT0gbnVsbCA/IHsgZHluYW1pYyB9IDoge30pLFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgJ3Rvb2wtZXJyb3InOiB7XG4gICAgICAgICAgICAgIGNvbnN0IGR5bmFtaWMgPSBpc0R5bmFtaWMocGFydC50b29sQ2FsbElkKTtcblxuICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgICAgIHR5cGU6ICd0b29sLW91dHB1dC1lcnJvcicsXG4gICAgICAgICAgICAgICAgdG9vbENhbGxJZDogcGFydC50b29sQ2FsbElkLFxuICAgICAgICAgICAgICAgIGVycm9yVGV4dDogb25FcnJvcihwYXJ0LmVycm9yKSxcbiAgICAgICAgICAgICAgICAuLi4ocGFydC5wcm92aWRlckV4ZWN1dGVkICE9IG51bGxcbiAgICAgICAgICAgICAgICAgID8geyBwcm92aWRlckV4ZWN1dGVkOiBwYXJ0LnByb3ZpZGVyRXhlY3V0ZWQgfVxuICAgICAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgICAgICAgLi4uKGR5bmFtaWMgIT0gbnVsbCA/IHsgZHluYW1pYyB9IDoge30pLFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgJ2Vycm9yJzoge1xuICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgICAgIHR5cGU6ICdlcnJvcicsXG4gICAgICAgICAgICAgICAgZXJyb3JUZXh0OiBvbkVycm9yKHBhcnQuZXJyb3IpLFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgJ3N0YXJ0LXN0ZXAnOiB7XG4gICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7IHR5cGU6ICdzdGFydC1zdGVwJyB9KTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgJ2ZpbmlzaC1zdGVwJzoge1xuICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoeyB0eXBlOiAnZmluaXNoLXN0ZXAnIH0pO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSAnc3RhcnQnOiB7XG4gICAgICAgICAgICAgIGlmIChzZW5kU3RhcnQpIHtcbiAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgICAgICAgdHlwZTogJ3N0YXJ0JyxcbiAgICAgICAgICAgICAgICAgIC4uLihtZXNzYWdlTWV0YWRhdGFWYWx1ZSAhPSBudWxsXG4gICAgICAgICAgICAgICAgICAgID8geyBtZXNzYWdlTWV0YWRhdGE6IG1lc3NhZ2VNZXRhZGF0YVZhbHVlIH1cbiAgICAgICAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgICAgICAgICAuLi4ocmVzcG9uc2VNZXNzYWdlSWQgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgICA/IHsgbWVzc2FnZUlkOiByZXNwb25zZU1lc3NhZ2VJZCB9XG4gICAgICAgICAgICAgICAgICAgIDoge30pLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYXNlICdmaW5pc2gnOiB7XG4gICAgICAgICAgICAgIGlmIChzZW5kRmluaXNoKSB7XG4gICAgICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHtcbiAgICAgICAgICAgICAgICAgIHR5cGU6ICdmaW5pc2gnLFxuICAgICAgICAgICAgICAgICAgLi4uKG1lc3NhZ2VNZXRhZGF0YVZhbHVlICE9IG51bGxcbiAgICAgICAgICAgICAgICAgICAgPyB7IG1lc3NhZ2VNZXRhZGF0YTogbWVzc2FnZU1ldGFkYXRhVmFsdWUgfVxuICAgICAgICAgICAgICAgICAgICA6IHt9KSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSAnYWJvcnQnOiB7XG4gICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShwYXJ0KTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgJ3Rvb2wtaW5wdXQtZW5kJzoge1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSAncmF3Jzoge1xuICAgICAgICAgICAgICAvLyBSYXcgY2h1bmtzIGFyZSBub3QgaW5jbHVkZWQgaW4gVUkgbWVzc2FnZSBzdHJlYW1zXG4gICAgICAgICAgICAgIC8vIGFzIHRoZXkgY29udGFpbiBwcm92aWRlci1zcGVjaWZpYyBkYXRhIGZvciBkZXZlbG9wZXIgdXNlXG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgIGNvbnN0IGV4aGF1c3RpdmVDaGVjazogbmV2ZXIgPSBwYXJ0VHlwZTtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGNodW5rIHR5cGU6ICR7ZXhoYXVzdGl2ZUNoZWNrfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIHN0YXJ0IGFuZCBmaW5pc2ggZXZlbnRzIGFscmVhZHkgaGF2ZSBtZXRhZGF0YVxuICAgICAgICAgIC8vIHNvIHdlIG9ubHkgbmVlZCB0byBzZW5kIG1ldGFkYXRhIGZvciBvdGhlciBwYXJ0c1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIG1lc3NhZ2VNZXRhZGF0YVZhbHVlICE9IG51bGwgJiZcbiAgICAgICAgICAgIHBhcnRUeXBlICE9PSAnc3RhcnQnICYmXG4gICAgICAgICAgICBwYXJ0VHlwZSAhPT0gJ2ZpbmlzaCdcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgIHR5cGU6ICdtZXNzYWdlLW1ldGFkYXRhJyxcbiAgICAgICAgICAgICAgbWVzc2FnZU1ldGFkYXRhOiBtZXNzYWdlTWV0YWRhdGFWYWx1ZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICByZXR1cm4gY3JlYXRlQXN5bmNJdGVyYWJsZVN0cmVhbShcbiAgICAgIGhhbmRsZVVJTWVzc2FnZVN0cmVhbUZpbmlzaDxVSV9NRVNTQUdFPih7XG4gICAgICAgIHN0cmVhbTogYmFzZVN0cmVhbSxcbiAgICAgICAgbWVzc2FnZUlkOiByZXNwb25zZU1lc3NhZ2VJZCA/PyBnZW5lcmF0ZU1lc3NhZ2VJZD8uKCksXG4gICAgICAgIG9yaWdpbmFsTWVzc2FnZXMsXG4gICAgICAgIG9uRmluaXNoLFxuICAgICAgICBvbkVycm9yLFxuICAgICAgfSksXG4gICAgKTtcbiAgfVxuXG4gIHBpcGVVSU1lc3NhZ2VTdHJlYW1Ub1Jlc3BvbnNlPFVJX01FU1NBR0UgZXh0ZW5kcyBVSU1lc3NhZ2U+KFxuICAgIHJlc3BvbnNlOiBTZXJ2ZXJSZXNwb25zZSxcbiAgICB7XG4gICAgICBvcmlnaW5hbE1lc3NhZ2VzLFxuICAgICAgZ2VuZXJhdGVNZXNzYWdlSWQsXG4gICAgICBvbkZpbmlzaCxcbiAgICAgIG1lc3NhZ2VNZXRhZGF0YSxcbiAgICAgIHNlbmRSZWFzb25pbmcsXG4gICAgICBzZW5kU291cmNlcyxcbiAgICAgIHNlbmRGaW5pc2gsXG4gICAgICBzZW5kU3RhcnQsXG4gICAgICBvbkVycm9yLFxuICAgICAgLi4uaW5pdFxuICAgIH06IFVJTWVzc2FnZVN0cmVhbVJlc3BvbnNlSW5pdCAmIFVJTWVzc2FnZVN0cmVhbU9wdGlvbnM8VUlfTUVTU0FHRT4gPSB7fSxcbiAgKSB7XG4gICAgcGlwZVVJTWVzc2FnZVN0cmVhbVRvUmVzcG9uc2Uoe1xuICAgICAgcmVzcG9uc2UsXG4gICAgICBzdHJlYW06IHRoaXMudG9VSU1lc3NhZ2VTdHJlYW0oe1xuICAgICAgICBvcmlnaW5hbE1lc3NhZ2VzLFxuICAgICAgICBnZW5lcmF0ZU1lc3NhZ2VJZCxcbiAgICAgICAgb25GaW5pc2gsXG4gICAgICAgIG1lc3NhZ2VNZXRhZGF0YSxcbiAgICAgICAgc2VuZFJlYXNvbmluZyxcbiAgICAgICAgc2VuZFNvdXJjZXMsXG4gICAgICAgIHNlbmRGaW5pc2gsXG4gICAgICAgIHNlbmRTdGFydCxcbiAgICAgICAgb25FcnJvcixcbiAgICAgIH0pLFxuICAgICAgLi4uaW5pdCxcbiAgICB9KTtcbiAgfVxuXG4gIHBpcGVUZXh0U3RyZWFtVG9SZXNwb25zZShyZXNwb25zZTogU2VydmVyUmVzcG9uc2UsIGluaXQ/OiBSZXNwb25zZUluaXQpIHtcbiAgICBwaXBlVGV4dFN0cmVhbVRvUmVzcG9uc2Uoe1xuICAgICAgcmVzcG9uc2UsXG4gICAgICB0ZXh0U3RyZWFtOiB0aGlzLnRleHRTdHJlYW0sXG4gICAgICAuLi5pbml0LFxuICAgIH0pO1xuICB9XG5cbiAgdG9VSU1lc3NhZ2VTdHJlYW1SZXNwb25zZTxVSV9NRVNTQUdFIGV4dGVuZHMgVUlNZXNzYWdlPih7XG4gICAgb3JpZ2luYWxNZXNzYWdlcyxcbiAgICBnZW5lcmF0ZU1lc3NhZ2VJZCxcbiAgICBvbkZpbmlzaCxcbiAgICBtZXNzYWdlTWV0YWRhdGEsXG4gICAgc2VuZFJlYXNvbmluZyxcbiAgICBzZW5kU291cmNlcyxcbiAgICBzZW5kRmluaXNoLFxuICAgIHNlbmRTdGFydCxcbiAgICBvbkVycm9yLFxuICAgIC4uLmluaXRcbiAgfTogVUlNZXNzYWdlU3RyZWFtUmVzcG9uc2VJbml0ICZcbiAgICBVSU1lc3NhZ2VTdHJlYW1PcHRpb25zPFVJX01FU1NBR0U+ID0ge30pOiBSZXNwb25zZSB7XG4gICAgcmV0dXJuIGNyZWF0ZVVJTWVzc2FnZVN0cmVhbVJlc3BvbnNlKHtcbiAgICAgIHN0cmVhbTogdGhpcy50b1VJTWVzc2FnZVN0cmVhbSh7XG4gICAgICAgIG9yaWdpbmFsTWVzc2FnZXMsXG4gICAgICAgIGdlbmVyYXRlTWVzc2FnZUlkLFxuICAgICAgICBvbkZpbmlzaCxcbiAgICAgICAgbWVzc2FnZU1ldGFkYXRhLFxuICAgICAgICBzZW5kUmVhc29uaW5nLFxuICAgICAgICBzZW5kU291cmNlcyxcbiAgICAgICAgc2VuZEZpbmlzaCxcbiAgICAgICAgc2VuZFN0YXJ0LFxuICAgICAgICBvbkVycm9yLFxuICAgICAgfSksXG4gICAgICAuLi5pbml0LFxuICAgIH0pO1xuICB9XG5cbiAgdG9UZXh0U3RyZWFtUmVzcG9uc2UoaW5pdD86IFJlc3BvbnNlSW5pdCk6IFJlc3BvbnNlIHtcbiAgICByZXR1cm4gY3JlYXRlVGV4dFN0cmVhbVJlc3BvbnNlKHtcbiAgICAgIHRleHRTdHJlYW06IHRoaXMudGV4dFN0cmVhbSxcbiAgICAgIC4uLmluaXQsXG4gICAgfSk7XG4gIH1cbn1cbiIsICJleHBvcnQgZnVuY3Rpb24gcHJlcGFyZUhlYWRlcnMoXG4gIGhlYWRlcnM6IEhlYWRlcnNJbml0IHwgdW5kZWZpbmVkLFxuICBkZWZhdWx0SGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPixcbik6IEhlYWRlcnMge1xuICBjb25zdCByZXNwb25zZUhlYWRlcnMgPSBuZXcgSGVhZGVycyhoZWFkZXJzID8/IHt9KTtcblxuICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhkZWZhdWx0SGVhZGVycykpIHtcbiAgICBpZiAoIXJlc3BvbnNlSGVhZGVycy5oYXMoa2V5KSkge1xuICAgICAgcmVzcG9uc2VIZWFkZXJzLnNldChrZXksIHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzcG9uc2VIZWFkZXJzO1xufVxuIiwgImltcG9ydCB7IHByZXBhcmVIZWFkZXJzIH0gZnJvbSAnLi4vdXRpbC9wcmVwYXJlLWhlYWRlcnMnO1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlVGV4dFN0cmVhbVJlc3BvbnNlKHtcbiAgc3RhdHVzLFxuICBzdGF0dXNUZXh0LFxuICBoZWFkZXJzLFxuICB0ZXh0U3RyZWFtLFxufTogUmVzcG9uc2VJbml0ICYge1xuICB0ZXh0U3RyZWFtOiBSZWFkYWJsZVN0cmVhbTxzdHJpbmc+O1xufSk6IFJlc3BvbnNlIHtcbiAgcmV0dXJuIG5ldyBSZXNwb25zZSh0ZXh0U3RyZWFtLnBpcGVUaHJvdWdoKG5ldyBUZXh0RW5jb2RlclN0cmVhbSgpKSwge1xuICAgIHN0YXR1czogc3RhdHVzID8/IDIwMCxcbiAgICBzdGF0dXNUZXh0LFxuICAgIGhlYWRlcnM6IHByZXBhcmVIZWFkZXJzKGhlYWRlcnMsIHtcbiAgICAgICdjb250ZW50LXR5cGUnOiAndGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCcsXG4gICAgfSksXG4gIH0pO1xufVxuIiwgImltcG9ydCB7IFNlcnZlclJlc3BvbnNlIH0gZnJvbSAnbm9kZTpodHRwJztcblxuLyoqXG4gKiBXcml0ZXMgdGhlIGNvbnRlbnQgb2YgYSBzdHJlYW0gdG8gYSBzZXJ2ZXIgcmVzcG9uc2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3cml0ZVRvU2VydmVyUmVzcG9uc2Uoe1xuICByZXNwb25zZSxcbiAgc3RhdHVzLFxuICBzdGF0dXNUZXh0LFxuICBoZWFkZXJzLFxuICBzdHJlYW0sXG59OiB7XG4gIHJlc3BvbnNlOiBTZXJ2ZXJSZXNwb25zZTtcbiAgc3RhdHVzPzogbnVtYmVyO1xuICBzdGF0dXNUZXh0Pzogc3RyaW5nO1xuICBoZWFkZXJzPzogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgbnVtYmVyIHwgc3RyaW5nW10+O1xuICBzdHJlYW06IFJlYWRhYmxlU3RyZWFtPFVpbnQ4QXJyYXk+O1xufSk6IHZvaWQge1xuICByZXNwb25zZS53cml0ZUhlYWQoc3RhdHVzID8/IDIwMCwgc3RhdHVzVGV4dCwgaGVhZGVycyk7XG5cbiAgY29uc3QgcmVhZGVyID0gc3RyZWFtLmdldFJlYWRlcigpO1xuICBjb25zdCByZWFkID0gYXN5bmMgKCkgPT4ge1xuICAgIHRyeSB7XG4gICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICBjb25zdCB7IGRvbmUsIHZhbHVlIH0gPSBhd2FpdCByZWFkZXIucmVhZCgpO1xuICAgICAgICBpZiAoZG9uZSkgYnJlYWs7XG5cbiAgICAgICAgLy8gUmVzcGVjdCBiYWNrcHJlc3N1cmU6IGlmIHdyaXRlKCkgcmV0dXJucyBmYWxzZSwgd2FpdCBmb3IgJ2RyYWluJyBldmVudFxuICAgICAgICBjb25zdCBjYW5Db250aW51ZSA9IHJlc3BvbnNlLndyaXRlKHZhbHVlKTtcbiAgICAgICAgaWYgKCFjYW5Db250aW51ZSkge1xuICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KHJlc29sdmUgPT4ge1xuICAgICAgICAgICAgcmVzcG9uc2Uub25jZSgnZHJhaW4nLCByZXNvbHZlKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgcmVzcG9uc2UuZW5kKCk7XG4gICAgfVxuICB9O1xuXG4gIHJlYWQoKTtcbn1cbiIsICJpbXBvcnQgeyBTZXJ2ZXJSZXNwb25zZSB9IGZyb20gJ25vZGU6aHR0cCc7XG5pbXBvcnQgeyBwcmVwYXJlSGVhZGVycyB9IGZyb20gJy4uL3V0aWwvcHJlcGFyZS1oZWFkZXJzJztcbmltcG9ydCB7IHdyaXRlVG9TZXJ2ZXJSZXNwb25zZSB9IGZyb20gJy4uL3V0aWwvd3JpdGUtdG8tc2VydmVyLXJlc3BvbnNlJztcblxuZXhwb3J0IGZ1bmN0aW9uIHBpcGVUZXh0U3RyZWFtVG9SZXNwb25zZSh7XG4gIHJlc3BvbnNlLFxuICBzdGF0dXMsXG4gIHN0YXR1c1RleHQsXG4gIGhlYWRlcnMsXG4gIHRleHRTdHJlYW0sXG59OiB7XG4gIHJlc3BvbnNlOiBTZXJ2ZXJSZXNwb25zZTtcbiAgdGV4dFN0cmVhbTogUmVhZGFibGVTdHJlYW08c3RyaW5nPjtcbn0gJiBSZXNwb25zZUluaXQpOiB2b2lkIHtcbiAgd3JpdGVUb1NlcnZlclJlc3BvbnNlKHtcbiAgICByZXNwb25zZSxcbiAgICBzdGF0dXMsXG4gICAgc3RhdHVzVGV4dCxcbiAgICBoZWFkZXJzOiBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICBwcmVwYXJlSGVhZGVycyhoZWFkZXJzLCB7XG4gICAgICAgICdjb250ZW50LXR5cGUnOiAndGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCcsXG4gICAgICB9KS5lbnRyaWVzKCksXG4gICAgKSxcbiAgICBzdHJlYW06IHRleHRTdHJlYW0ucGlwZVRocm91Z2gobmV3IFRleHRFbmNvZGVyU3RyZWFtKCkpLFxuICB9KTtcbn1cbiIsICJleHBvcnQgY2xhc3MgSnNvblRvU3NlVHJhbnNmb3JtU3RyZWFtIGV4dGVuZHMgVHJhbnNmb3JtU3RyZWFtPHVua25vd24sIHN0cmluZz4ge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcih7XG4gICAgICB0cmFuc2Zvcm0ocGFydCwgY29udHJvbGxlcikge1xuICAgICAgICBjb250cm9sbGVyLmVucXVldWUoYGRhdGE6ICR7SlNPTi5zdHJpbmdpZnkocGFydCl9XFxuXFxuYCk7XG4gICAgICB9LFxuICAgICAgZmx1c2goY29udHJvbGxlcikge1xuICAgICAgICBjb250cm9sbGVyLmVucXVldWUoJ2RhdGE6IFtET05FXVxcblxcbicpO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxufVxuIiwgImV4cG9ydCBjb25zdCBVSV9NRVNTQUdFX1NUUkVBTV9IRUFERVJTID0ge1xuICAnY29udGVudC10eXBlJzogJ3RleHQvZXZlbnQtc3RyZWFtJyxcbiAgJ2NhY2hlLWNvbnRyb2wnOiAnbm8tY2FjaGUnLFxuICBjb25uZWN0aW9uOiAna2VlcC1hbGl2ZScsXG4gICd4LXZlcmNlbC1haS11aS1tZXNzYWdlLXN0cmVhbSc6ICd2MScsXG4gICd4LWFjY2VsLWJ1ZmZlcmluZyc6ICdubycsIC8vIGRpc2FibGUgbmdpbnggYnVmZmVyaW5nXG59O1xuIiwgImltcG9ydCB7IHByZXBhcmVIZWFkZXJzIH0gZnJvbSAnLi4vdXRpbC9wcmVwYXJlLWhlYWRlcnMnO1xuaW1wb3J0IHsgSnNvblRvU3NlVHJhbnNmb3JtU3RyZWFtIH0gZnJvbSAnLi9qc29uLXRvLXNzZS10cmFuc2Zvcm0tc3RyZWFtJztcbmltcG9ydCB7IFVJX01FU1NBR0VfU1RSRUFNX0hFQURFUlMgfSBmcm9tICcuL3VpLW1lc3NhZ2Utc3RyZWFtLWhlYWRlcnMnO1xuaW1wb3J0IHsgVUlNZXNzYWdlQ2h1bmsgfSBmcm9tICcuL3VpLW1lc3NhZ2UtY2h1bmtzJztcbmltcG9ydCB7IFVJTWVzc2FnZVN0cmVhbVJlc3BvbnNlSW5pdCB9IGZyb20gJy4vdWktbWVzc2FnZS1zdHJlYW0tcmVzcG9uc2UtaW5pdCc7XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVVSU1lc3NhZ2VTdHJlYW1SZXNwb25zZSh7XG4gIHN0YXR1cyxcbiAgc3RhdHVzVGV4dCxcbiAgaGVhZGVycyxcbiAgc3RyZWFtLFxuICBjb25zdW1lU3NlU3RyZWFtLFxufTogVUlNZXNzYWdlU3RyZWFtUmVzcG9uc2VJbml0ICYge1xuICBzdHJlYW06IFJlYWRhYmxlU3RyZWFtPFVJTWVzc2FnZUNodW5rPjtcbn0pOiBSZXNwb25zZSB7XG4gIGxldCBzc2VTdHJlYW0gPSBzdHJlYW0ucGlwZVRocm91Z2gobmV3IEpzb25Ub1NzZVRyYW5zZm9ybVN0cmVhbSgpKTtcblxuICAvLyB3aGVuIHRoZSBjb25zdW1lU3NlU3RyZWFtIGlzIHByb3ZpZGVkLCB3ZSBuZWVkIHRvIHRlZSB0aGUgc3RyZWFtXG4gIC8vIGFuZCBzZW5kIHRoZSBzZWNvbmQgcGFydCB0byB0aGUgY29uc3VtZVNzZVN0cmVhbSBmdW5jdGlvblxuICAvLyBzbyB0aGF0IGl0IGNhbiBiZSBjb25zdW1lZCBieSB0aGUgY2xpZW50IGluZGVwZW5kZW50bHlcbiAgaWYgKGNvbnN1bWVTc2VTdHJlYW0pIHtcbiAgICBjb25zdCBbc3RyZWFtMSwgc3RyZWFtMl0gPSBzc2VTdHJlYW0udGVlKCk7XG4gICAgc3NlU3RyZWFtID0gc3RyZWFtMTtcbiAgICBjb25zdW1lU3NlU3RyZWFtKHsgc3RyZWFtOiBzdHJlYW0yIH0pOyAvLyBubyBhd2FpdCAoZG8gbm90IGJsb2NrIHRoZSByZXNwb25zZSlcbiAgfVxuXG4gIHJldHVybiBuZXcgUmVzcG9uc2Uoc3NlU3RyZWFtLnBpcGVUaHJvdWdoKG5ldyBUZXh0RW5jb2RlclN0cmVhbSgpKSwge1xuICAgIHN0YXR1cyxcbiAgICBzdGF0dXNUZXh0LFxuICAgIGhlYWRlcnM6IHByZXBhcmVIZWFkZXJzKGhlYWRlcnMsIFVJX01FU1NBR0VfU1RSRUFNX0hFQURFUlMpLFxuICB9KTtcbn1cbiIsICJpbXBvcnQgeyBJZEdlbmVyYXRvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXItdXRpbHMnO1xuaW1wb3J0IHsgVUlNZXNzYWdlIH0gZnJvbSAnLi4vdWkvdWktbWVzc2FnZXMnO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UmVzcG9uc2VVSU1lc3NhZ2VJZCh7XG4gIG9yaWdpbmFsTWVzc2FnZXMsXG4gIHJlc3BvbnNlTWVzc2FnZUlkLFxufToge1xuICBvcmlnaW5hbE1lc3NhZ2VzOiBVSU1lc3NhZ2VbXSB8IHVuZGVmaW5lZDtcbiAgcmVzcG9uc2VNZXNzYWdlSWQ6IHN0cmluZyB8IElkR2VuZXJhdG9yO1xufSkge1xuICAvLyB3aGVuIHRoZXJlIGFyZSBubyBvcmlnaW5hbCBtZXNzYWdlcyAoaS5lLiBubyBwZXJzaXN0ZW5jZSksXG4gIC8vIHRoZSBhc3Npc3RhbnQgbWVzc2FnZSBpZCBnZW5lcmF0aW9uIGlzIGhhbmRsZWQgb24gdGhlIGNsaWVudCBzaWRlLlxuICBpZiAob3JpZ2luYWxNZXNzYWdlcyA9PSBudWxsKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGNvbnN0IGxhc3RNZXNzYWdlID0gb3JpZ2luYWxNZXNzYWdlc1tvcmlnaW5hbE1lc3NhZ2VzLmxlbmd0aCAtIDFdO1xuXG4gIHJldHVybiBsYXN0TWVzc2FnZT8ucm9sZSA9PT0gJ2Fzc2lzdGFudCdcbiAgICA/IGxhc3RNZXNzYWdlLmlkXG4gICAgOiB0eXBlb2YgcmVzcG9uc2VNZXNzYWdlSWQgPT09ICdmdW5jdGlvbidcbiAgICAgID8gcmVzcG9uc2VNZXNzYWdlSWQoKVxuICAgICAgOiByZXNwb25zZU1lc3NhZ2VJZDtcbn1cbiIsICJpbXBvcnQge1xuICBTdGFuZGFyZFNjaGVtYVYxLFxuICB2YWxpZGF0ZVR5cGVzLFxuICBWYWxpZGF0b3IsXG59IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXItdXRpbHMnO1xuaW1wb3J0IHsgUHJvdmlkZXJNZXRhZGF0YSB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7XG4gIERhdGFVSU1lc3NhZ2VDaHVuayxcbiAgSW5mZXJVSU1lc3NhZ2VDaHVuayxcbiAgaXNEYXRhVUlNZXNzYWdlQ2h1bmssXG4gIFVJTWVzc2FnZUNodW5rLFxufSBmcm9tICcuLi91aS1tZXNzYWdlLXN0cmVhbS91aS1tZXNzYWdlLWNodW5rcyc7XG5pbXBvcnQgeyBFcnJvckhhbmRsZXIgfSBmcm9tICcuLi91dGlsL2Vycm9yLWhhbmRsZXInO1xuaW1wb3J0IHsgbWVyZ2VPYmplY3RzIH0gZnJvbSAnLi4vdXRpbC9tZXJnZS1vYmplY3RzJztcbmltcG9ydCB7IHBhcnNlUGFydGlhbEpzb24gfSBmcm9tICcuLi91dGlsL3BhcnNlLXBhcnRpYWwtanNvbic7XG5pbXBvcnQgeyBVSURhdGFUeXBlc1RvU2NoZW1hcyB9IGZyb20gJy4vY2hhdCc7XG5pbXBvcnQge1xuICBEYXRhVUlQYXJ0LFxuICBEeW5hbWljVG9vbFVJUGFydCxcbiAgZ2V0VG9vbE5hbWUsXG4gIEluZmVyVUlNZXNzYWdlRGF0YSxcbiAgSW5mZXJVSU1lc3NhZ2VNZXRhZGF0YSxcbiAgSW5mZXJVSU1lc3NhZ2VUb29sQ2FsbCxcbiAgSW5mZXJVSU1lc3NhZ2VUb29scyxcbiAgaXNUb29sVUlQYXJ0LFxuICBSZWFzb25pbmdVSVBhcnQsXG4gIFRleHRVSVBhcnQsXG4gIFRvb2xVSVBhcnQsXG4gIFVJTWVzc2FnZSxcbiAgVUlNZXNzYWdlUGFydCxcbn0gZnJvbSAnLi91aS1tZXNzYWdlcyc7XG5cbmV4cG9ydCB0eXBlIFN0cmVhbWluZ1VJTWVzc2FnZVN0YXRlPFVJX01FU1NBR0UgZXh0ZW5kcyBVSU1lc3NhZ2U+ID0ge1xuICBtZXNzYWdlOiBVSV9NRVNTQUdFO1xuICBhY3RpdmVUZXh0UGFydHM6IFJlY29yZDxzdHJpbmcsIFRleHRVSVBhcnQ+O1xuICBhY3RpdmVSZWFzb25pbmdQYXJ0czogUmVjb3JkPHN0cmluZywgUmVhc29uaW5nVUlQYXJ0PjtcbiAgcGFydGlhbFRvb2xDYWxsczogUmVjb3JkPFxuICAgIHN0cmluZyxcbiAgICB7IHRleHQ6IHN0cmluZzsgaW5kZXg6IG51bWJlcjsgdG9vbE5hbWU6IHN0cmluZzsgZHluYW1pYz86IGJvb2xlYW4gfVxuICA+O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVN0cmVhbWluZ1VJTWVzc2FnZVN0YXRlPFVJX01FU1NBR0UgZXh0ZW5kcyBVSU1lc3NhZ2U+KHtcbiAgbGFzdE1lc3NhZ2UsXG4gIG1lc3NhZ2VJZCxcbn06IHtcbiAgbGFzdE1lc3NhZ2U6IFVJX01FU1NBR0UgfCB1bmRlZmluZWQ7XG4gIG1lc3NhZ2VJZDogc3RyaW5nO1xufSk6IFN0cmVhbWluZ1VJTWVzc2FnZVN0YXRlPFVJX01FU1NBR0U+IHtcbiAgcmV0dXJuIHtcbiAgICBtZXNzYWdlOlxuICAgICAgbGFzdE1lc3NhZ2U/LnJvbGUgPT09ICdhc3Npc3RhbnQnXG4gICAgICAgID8gbGFzdE1lc3NhZ2VcbiAgICAgICAgOiAoe1xuICAgICAgICAgICAgaWQ6IG1lc3NhZ2VJZCxcbiAgICAgICAgICAgIG1ldGFkYXRhOiB1bmRlZmluZWQsXG4gICAgICAgICAgICByb2xlOiAnYXNzaXN0YW50JyxcbiAgICAgICAgICAgIHBhcnRzOiBbXSBhcyBVSU1lc3NhZ2VQYXJ0PFxuICAgICAgICAgICAgICBJbmZlclVJTWVzc2FnZURhdGE8VUlfTUVTU0FHRT4sXG4gICAgICAgICAgICAgIEluZmVyVUlNZXNzYWdlVG9vbHM8VUlfTUVTU0FHRT5cbiAgICAgICAgICAgID5bXSxcbiAgICAgICAgICB9IGFzIFVJX01FU1NBR0UpLFxuICAgIGFjdGl2ZVRleHRQYXJ0czoge30sXG4gICAgYWN0aXZlUmVhc29uaW5nUGFydHM6IHt9LFxuICAgIHBhcnRpYWxUb29sQ2FsbHM6IHt9LFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcHJvY2Vzc1VJTWVzc2FnZVN0cmVhbTxVSV9NRVNTQUdFIGV4dGVuZHMgVUlNZXNzYWdlPih7XG4gIHN0cmVhbSxcbiAgbWVzc2FnZU1ldGFkYXRhU2NoZW1hLFxuICBkYXRhUGFydFNjaGVtYXMsXG4gIHJ1blVwZGF0ZU1lc3NhZ2VKb2IsXG4gIG9uRXJyb3IsXG4gIG9uVG9vbENhbGwsXG4gIG9uRGF0YSxcbn06IHtcbiAgLy8gaW5wdXQgc3RyZWFtIGlzIG5vdCBmdWxseSB0eXBlZCB5ZXQ6XG4gIHN0cmVhbTogUmVhZGFibGVTdHJlYW08VUlNZXNzYWdlQ2h1bms+O1xuICBtZXNzYWdlTWV0YWRhdGFTY2hlbWE/OlxuICAgIHwgVmFsaWRhdG9yPEluZmVyVUlNZXNzYWdlTWV0YWRhdGE8VUlfTUVTU0FHRT4+XG4gICAgfCBTdGFuZGFyZFNjaGVtYVYxPEluZmVyVUlNZXNzYWdlTWV0YWRhdGE8VUlfTUVTU0FHRT4+O1xuICBkYXRhUGFydFNjaGVtYXM/OiBVSURhdGFUeXBlc1RvU2NoZW1hczxJbmZlclVJTWVzc2FnZURhdGE8VUlfTUVTU0FHRT4+O1xuICBvblRvb2xDYWxsPzogKG9wdGlvbnM6IHtcbiAgICB0b29sQ2FsbDogSW5mZXJVSU1lc3NhZ2VUb29sQ2FsbDxVSV9NRVNTQUdFPjtcbiAgfSkgPT4gdm9pZCB8IFByb21pc2VMaWtlPHZvaWQ+O1xuICBvbkRhdGE/OiAoZGF0YVBhcnQ6IERhdGFVSVBhcnQ8SW5mZXJVSU1lc3NhZ2VEYXRhPFVJX01FU1NBR0U+PikgPT4gdm9pZDtcbiAgcnVuVXBkYXRlTWVzc2FnZUpvYjogKFxuICAgIGpvYjogKG9wdGlvbnM6IHtcbiAgICAgIHN0YXRlOiBTdHJlYW1pbmdVSU1lc3NhZ2VTdGF0ZTxVSV9NRVNTQUdFPjtcbiAgICAgIHdyaXRlOiAoKSA9PiB2b2lkO1xuICAgIH0pID0+IFByb21pc2U8dm9pZD4sXG4gICkgPT4gUHJvbWlzZTx2b2lkPjtcbiAgb25FcnJvcjogRXJyb3JIYW5kbGVyO1xufSk6IFJlYWRhYmxlU3RyZWFtPEluZmVyVUlNZXNzYWdlQ2h1bms8VUlfTUVTU0FHRT4+IHtcbiAgcmV0dXJuIHN0cmVhbS5waXBlVGhyb3VnaChcbiAgICBuZXcgVHJhbnNmb3JtU3RyZWFtPFVJTWVzc2FnZUNodW5rLCBJbmZlclVJTWVzc2FnZUNodW5rPFVJX01FU1NBR0U+Pih7XG4gICAgICBhc3luYyB0cmFuc2Zvcm0oY2h1bmssIGNvbnRyb2xsZXIpIHtcbiAgICAgICAgYXdhaXQgcnVuVXBkYXRlTWVzc2FnZUpvYihhc3luYyAoeyBzdGF0ZSwgd3JpdGUgfSkgPT4ge1xuICAgICAgICAgIGZ1bmN0aW9uIGdldFRvb2xJbnZvY2F0aW9uKHRvb2xDYWxsSWQ6IHN0cmluZykge1xuICAgICAgICAgICAgY29uc3QgdG9vbEludm9jYXRpb25zID0gc3RhdGUubWVzc2FnZS5wYXJ0cy5maWx0ZXIoaXNUb29sVUlQYXJ0KTtcblxuICAgICAgICAgICAgY29uc3QgdG9vbEludm9jYXRpb24gPSB0b29sSW52b2NhdGlvbnMuZmluZChcbiAgICAgICAgICAgICAgaW52b2NhdGlvbiA9PiBpbnZvY2F0aW9uLnRvb2xDYWxsSWQgPT09IHRvb2xDYWxsSWQsXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBpZiAodG9vbEludm9jYXRpb24gPT0gbnVsbCkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgJ3Rvb2wtb3V0cHV0LWVycm9yIG11c3QgYmUgcHJlY2VkZWQgYnkgYSB0b29sLWlucHV0LWF2YWlsYWJsZScsXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0b29sSW52b2NhdGlvbjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBmdW5jdGlvbiBnZXREeW5hbWljVG9vbEludm9jYXRpb24odG9vbENhbGxJZDogc3RyaW5nKSB7XG4gICAgICAgICAgICBjb25zdCB0b29sSW52b2NhdGlvbnMgPSBzdGF0ZS5tZXNzYWdlLnBhcnRzLmZpbHRlcihcbiAgICAgICAgICAgICAgcGFydCA9PiBwYXJ0LnR5cGUgPT09ICdkeW5hbWljLXRvb2wnLFxuICAgICAgICAgICAgKSBhcyBEeW5hbWljVG9vbFVJUGFydFtdO1xuXG4gICAgICAgICAgICBjb25zdCB0b29sSW52b2NhdGlvbiA9IHRvb2xJbnZvY2F0aW9ucy5maW5kKFxuICAgICAgICAgICAgICBpbnZvY2F0aW9uID0+IGludm9jYXRpb24udG9vbENhbGxJZCA9PT0gdG9vbENhbGxJZCxcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGlmICh0b29sSW52b2NhdGlvbiA9PSBudWxsKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICAndG9vbC1vdXRwdXQtZXJyb3IgbXVzdCBiZSBwcmVjZWRlZCBieSBhIHRvb2wtaW5wdXQtYXZhaWxhYmxlJyxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHRvb2xJbnZvY2F0aW9uO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGZ1bmN0aW9uIHVwZGF0ZVRvb2xQYXJ0KFxuICAgICAgICAgICAgb3B0aW9uczoge1xuICAgICAgICAgICAgICB0b29sTmFtZToga2V5b2YgSW5mZXJVSU1lc3NhZ2VUb29sczxVSV9NRVNTQUdFPiAmIHN0cmluZztcbiAgICAgICAgICAgICAgdG9vbENhbGxJZDogc3RyaW5nO1xuICAgICAgICAgICAgICBwcm92aWRlckV4ZWN1dGVkPzogYm9vbGVhbjtcbiAgICAgICAgICAgIH0gJiAoXG4gICAgICAgICAgICAgIHwge1xuICAgICAgICAgICAgICAgICAgc3RhdGU6ICdpbnB1dC1zdHJlYW1pbmcnO1xuICAgICAgICAgICAgICAgICAgaW5wdXQ6IHVua25vd247XG4gICAgICAgICAgICAgICAgICBwcm92aWRlckV4ZWN1dGVkPzogYm9vbGVhbjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHwge1xuICAgICAgICAgICAgICAgICAgc3RhdGU6ICdpbnB1dC1hdmFpbGFibGUnO1xuICAgICAgICAgICAgICAgICAgaW5wdXQ6IHVua25vd247XG4gICAgICAgICAgICAgICAgICBwcm92aWRlckV4ZWN1dGVkPzogYm9vbGVhbjtcbiAgICAgICAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE/OiBQcm92aWRlck1ldGFkYXRhO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfCB7XG4gICAgICAgICAgICAgICAgICBzdGF0ZTogJ291dHB1dC1hdmFpbGFibGUnO1xuICAgICAgICAgICAgICAgICAgaW5wdXQ6IHVua25vd247XG4gICAgICAgICAgICAgICAgICBvdXRwdXQ6IHVua25vd247XG4gICAgICAgICAgICAgICAgICBwcm92aWRlckV4ZWN1dGVkPzogYm9vbGVhbjtcbiAgICAgICAgICAgICAgICAgIHByZWxpbWluYXJ5PzogYm9vbGVhbjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHwge1xuICAgICAgICAgICAgICAgICAgc3RhdGU6ICdvdXRwdXQtZXJyb3InO1xuICAgICAgICAgICAgICAgICAgaW5wdXQ6IHVua25vd247XG4gICAgICAgICAgICAgICAgICByYXdJbnB1dD86IHVua25vd247XG4gICAgICAgICAgICAgICAgICBlcnJvclRleHQ6IHN0cmluZztcbiAgICAgICAgICAgICAgICAgIHByb3ZpZGVyRXhlY3V0ZWQ/OiBib29sZWFuO1xuICAgICAgICAgICAgICAgICAgcHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKSxcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIGNvbnN0IHBhcnQgPSBzdGF0ZS5tZXNzYWdlLnBhcnRzLmZpbmQoXG4gICAgICAgICAgICAgIHBhcnQgPT5cbiAgICAgICAgICAgICAgICBpc1Rvb2xVSVBhcnQocGFydCkgJiYgcGFydC50b29sQ2FsbElkID09PSBvcHRpb25zLnRvb2xDYWxsSWQsXG4gICAgICAgICAgICApIGFzIFRvb2xVSVBhcnQ8SW5mZXJVSU1lc3NhZ2VUb29sczxVSV9NRVNTQUdFPj4gfCB1bmRlZmluZWQ7XG5cbiAgICAgICAgICAgIGNvbnN0IGFueU9wdGlvbnMgPSBvcHRpb25zIGFzIGFueTtcbiAgICAgICAgICAgIGNvbnN0IGFueVBhcnQgPSBwYXJ0IGFzIGFueTtcblxuICAgICAgICAgICAgaWYgKHBhcnQgIT0gbnVsbCkge1xuICAgICAgICAgICAgICBwYXJ0LnN0YXRlID0gb3B0aW9ucy5zdGF0ZTtcbiAgICAgICAgICAgICAgYW55UGFydC5pbnB1dCA9IGFueU9wdGlvbnMuaW5wdXQ7XG4gICAgICAgICAgICAgIGFueVBhcnQub3V0cHV0ID0gYW55T3B0aW9ucy5vdXRwdXQ7XG4gICAgICAgICAgICAgIGFueVBhcnQuZXJyb3JUZXh0ID0gYW55T3B0aW9ucy5lcnJvclRleHQ7XG4gICAgICAgICAgICAgIGFueVBhcnQucmF3SW5wdXQgPSBhbnlPcHRpb25zLnJhd0lucHV0O1xuICAgICAgICAgICAgICBhbnlQYXJ0LnByZWxpbWluYXJ5ID0gYW55T3B0aW9ucy5wcmVsaW1pbmFyeTtcblxuICAgICAgICAgICAgICAvLyBvbmNlIHByb3ZpZGVyRXhlY3V0ZWQgaXMgc2V0LCBpdCBzdGF5cyBmb3Igc3RyZWFtaW5nXG4gICAgICAgICAgICAgIGFueVBhcnQucHJvdmlkZXJFeGVjdXRlZCA9XG4gICAgICAgICAgICAgICAgYW55T3B0aW9ucy5wcm92aWRlckV4ZWN1dGVkID8/IHBhcnQucHJvdmlkZXJFeGVjdXRlZDtcblxuICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgYW55T3B0aW9ucy5wcm92aWRlck1ldGFkYXRhICE9IG51bGwgJiZcbiAgICAgICAgICAgICAgICBwYXJ0LnN0YXRlID09PSAnaW5wdXQtYXZhaWxhYmxlJ1xuICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICBwYXJ0LmNhbGxQcm92aWRlck1ldGFkYXRhID0gYW55T3B0aW9ucy5wcm92aWRlck1ldGFkYXRhO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBzdGF0ZS5tZXNzYWdlLnBhcnRzLnB1c2goe1xuICAgICAgICAgICAgICAgIHR5cGU6IGB0b29sLSR7b3B0aW9ucy50b29sTmFtZX1gLFxuICAgICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IG9wdGlvbnMudG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgICBzdGF0ZTogb3B0aW9ucy5zdGF0ZSxcbiAgICAgICAgICAgICAgICBpbnB1dDogYW55T3B0aW9ucy5pbnB1dCxcbiAgICAgICAgICAgICAgICBvdXRwdXQ6IGFueU9wdGlvbnMub3V0cHV0LFxuICAgICAgICAgICAgICAgIHJhd0lucHV0OiBhbnlPcHRpb25zLnJhd0lucHV0LFxuICAgICAgICAgICAgICAgIGVycm9yVGV4dDogYW55T3B0aW9ucy5lcnJvclRleHQsXG4gICAgICAgICAgICAgICAgcHJvdmlkZXJFeGVjdXRlZDogYW55T3B0aW9ucy5wcm92aWRlckV4ZWN1dGVkLFxuICAgICAgICAgICAgICAgIHByZWxpbWluYXJ5OiBhbnlPcHRpb25zLnByZWxpbWluYXJ5LFxuICAgICAgICAgICAgICAgIC4uLihhbnlPcHRpb25zLnByb3ZpZGVyTWV0YWRhdGEgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgPyB7IGNhbGxQcm92aWRlck1ldGFkYXRhOiBhbnlPcHRpb25zLnByb3ZpZGVyTWV0YWRhdGEgfVxuICAgICAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgICAgIH0gYXMgVG9vbFVJUGFydDxJbmZlclVJTWVzc2FnZVRvb2xzPFVJX01FU1NBR0U+Pik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZnVuY3Rpb24gdXBkYXRlRHluYW1pY1Rvb2xQYXJ0KFxuICAgICAgICAgICAgb3B0aW9uczoge1xuICAgICAgICAgICAgICB0b29sTmFtZToga2V5b2YgSW5mZXJVSU1lc3NhZ2VUb29sczxVSV9NRVNTQUdFPiAmIHN0cmluZztcbiAgICAgICAgICAgICAgdG9vbENhbGxJZDogc3RyaW5nO1xuICAgICAgICAgICAgICBwcm92aWRlckV4ZWN1dGVkPzogYm9vbGVhbjtcbiAgICAgICAgICAgIH0gJiAoXG4gICAgICAgICAgICAgIHwge1xuICAgICAgICAgICAgICAgICAgc3RhdGU6ICdpbnB1dC1zdHJlYW1pbmcnO1xuICAgICAgICAgICAgICAgICAgaW5wdXQ6IHVua25vd247XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB8IHtcbiAgICAgICAgICAgICAgICAgIHN0YXRlOiAnaW5wdXQtYXZhaWxhYmxlJztcbiAgICAgICAgICAgICAgICAgIGlucHV0OiB1bmtub3duO1xuICAgICAgICAgICAgICAgICAgcHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB8IHtcbiAgICAgICAgICAgICAgICAgIHN0YXRlOiAnb3V0cHV0LWF2YWlsYWJsZSc7XG4gICAgICAgICAgICAgICAgICBpbnB1dDogdW5rbm93bjtcbiAgICAgICAgICAgICAgICAgIG91dHB1dDogdW5rbm93bjtcbiAgICAgICAgICAgICAgICAgIHByZWxpbWluYXJ5OiBib29sZWFuIHwgdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfCB7XG4gICAgICAgICAgICAgICAgICBzdGF0ZTogJ291dHB1dC1lcnJvcic7XG4gICAgICAgICAgICAgICAgICBpbnB1dDogdW5rbm93bjtcbiAgICAgICAgICAgICAgICAgIGVycm9yVGV4dDogc3RyaW5nO1xuICAgICAgICAgICAgICAgICAgcHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKSxcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIGNvbnN0IHBhcnQgPSBzdGF0ZS5tZXNzYWdlLnBhcnRzLmZpbmQoXG4gICAgICAgICAgICAgIHBhcnQgPT5cbiAgICAgICAgICAgICAgICBwYXJ0LnR5cGUgPT09ICdkeW5hbWljLXRvb2wnICYmXG4gICAgICAgICAgICAgICAgcGFydC50b29sQ2FsbElkID09PSBvcHRpb25zLnRvb2xDYWxsSWQsXG4gICAgICAgICAgICApIGFzIER5bmFtaWNUb29sVUlQYXJ0IHwgdW5kZWZpbmVkO1xuXG4gICAgICAgICAgICBjb25zdCBhbnlPcHRpb25zID0gb3B0aW9ucyBhcyBhbnk7XG4gICAgICAgICAgICBjb25zdCBhbnlQYXJ0ID0gcGFydCBhcyBhbnk7XG5cbiAgICAgICAgICAgIGlmIChwYXJ0ICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgcGFydC5zdGF0ZSA9IG9wdGlvbnMuc3RhdGU7XG4gICAgICAgICAgICAgIGFueVBhcnQudG9vbE5hbWUgPSBvcHRpb25zLnRvb2xOYW1lO1xuICAgICAgICAgICAgICBhbnlQYXJ0LmlucHV0ID0gYW55T3B0aW9ucy5pbnB1dDtcbiAgICAgICAgICAgICAgYW55UGFydC5vdXRwdXQgPSBhbnlPcHRpb25zLm91dHB1dDtcbiAgICAgICAgICAgICAgYW55UGFydC5lcnJvclRleHQgPSBhbnlPcHRpb25zLmVycm9yVGV4dDtcbiAgICAgICAgICAgICAgYW55UGFydC5yYXdJbnB1dCA9IGFueU9wdGlvbnMucmF3SW5wdXQgPz8gYW55UGFydC5yYXdJbnB1dDtcbiAgICAgICAgICAgICAgYW55UGFydC5wcmVsaW1pbmFyeSA9IGFueU9wdGlvbnMucHJlbGltaW5hcnk7XG5cbiAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIGFueU9wdGlvbnMucHJvdmlkZXJNZXRhZGF0YSAhPSBudWxsICYmXG4gICAgICAgICAgICAgICAgcGFydC5zdGF0ZSA9PT0gJ2lucHV0LWF2YWlsYWJsZSdcbiAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgcGFydC5jYWxsUHJvdmlkZXJNZXRhZGF0YSA9IGFueU9wdGlvbnMucHJvdmlkZXJNZXRhZGF0YTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgc3RhdGUubWVzc2FnZS5wYXJ0cy5wdXNoKHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnZHluYW1pYy10b29sJyxcbiAgICAgICAgICAgICAgICB0b29sTmFtZTogb3B0aW9ucy50b29sTmFtZSxcbiAgICAgICAgICAgICAgICB0b29sQ2FsbElkOiBvcHRpb25zLnRvb2xDYWxsSWQsXG4gICAgICAgICAgICAgICAgc3RhdGU6IG9wdGlvbnMuc3RhdGUsXG4gICAgICAgICAgICAgICAgaW5wdXQ6IGFueU9wdGlvbnMuaW5wdXQsXG4gICAgICAgICAgICAgICAgb3V0cHV0OiBhbnlPcHRpb25zLm91dHB1dCxcbiAgICAgICAgICAgICAgICBlcnJvclRleHQ6IGFueU9wdGlvbnMuZXJyb3JUZXh0LFxuICAgICAgICAgICAgICAgIHByZWxpbWluYXJ5OiBhbnlPcHRpb25zLnByZWxpbWluYXJ5LFxuICAgICAgICAgICAgICAgIC4uLihhbnlPcHRpb25zLnByb3ZpZGVyTWV0YWRhdGEgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgPyB7IGNhbGxQcm92aWRlck1ldGFkYXRhOiBhbnlPcHRpb25zLnByb3ZpZGVyTWV0YWRhdGEgfVxuICAgICAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgICAgIH0gYXMgRHluYW1pY1Rvb2xVSVBhcnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGFzeW5jIGZ1bmN0aW9uIHVwZGF0ZU1lc3NhZ2VNZXRhZGF0YShtZXRhZGF0YTogdW5rbm93bikge1xuICAgICAgICAgICAgaWYgKG1ldGFkYXRhICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgY29uc3QgbWVyZ2VkTWV0YWRhdGEgPVxuICAgICAgICAgICAgICAgIHN0YXRlLm1lc3NhZ2UubWV0YWRhdGEgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgPyBtZXJnZU9iamVjdHMoc3RhdGUubWVzc2FnZS5tZXRhZGF0YSwgbWV0YWRhdGEpXG4gICAgICAgICAgICAgICAgICA6IG1ldGFkYXRhO1xuXG4gICAgICAgICAgICAgIGlmIChtZXNzYWdlTWV0YWRhdGFTY2hlbWEgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHZhbGlkYXRlVHlwZXMoe1xuICAgICAgICAgICAgICAgICAgdmFsdWU6IG1lcmdlZE1ldGFkYXRhLFxuICAgICAgICAgICAgICAgICAgc2NoZW1hOiBtZXNzYWdlTWV0YWRhdGFTY2hlbWEsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBzdGF0ZS5tZXNzYWdlLm1ldGFkYXRhID1cbiAgICAgICAgICAgICAgICBtZXJnZWRNZXRhZGF0YSBhcyBJbmZlclVJTWVzc2FnZU1ldGFkYXRhPFVJX01FU1NBR0U+O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHN3aXRjaCAoY2h1bmsudHlwZSkge1xuICAgICAgICAgICAgY2FzZSAndGV4dC1zdGFydCc6IHtcbiAgICAgICAgICAgICAgY29uc3QgdGV4dFBhcnQ6IFRleHRVSVBhcnQgPSB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgICAgICAgICAgIHRleHQ6ICcnLFxuICAgICAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IGNodW5rLnByb3ZpZGVyTWV0YWRhdGEsXG4gICAgICAgICAgICAgICAgc3RhdGU6ICdzdHJlYW1pbmcnLFxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICBzdGF0ZS5hY3RpdmVUZXh0UGFydHNbY2h1bmsuaWRdID0gdGV4dFBhcnQ7XG4gICAgICAgICAgICAgIHN0YXRlLm1lc3NhZ2UucGFydHMucHVzaCh0ZXh0UGFydCk7XG4gICAgICAgICAgICAgIHdyaXRlKCk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYXNlICd0ZXh0LWRlbHRhJzoge1xuICAgICAgICAgICAgICBjb25zdCB0ZXh0UGFydCA9IHN0YXRlLmFjdGl2ZVRleHRQYXJ0c1tjaHVuay5pZF07XG4gICAgICAgICAgICAgIHRleHRQYXJ0LnRleHQgKz0gY2h1bmsuZGVsdGE7XG4gICAgICAgICAgICAgIHRleHRQYXJ0LnByb3ZpZGVyTWV0YWRhdGEgPVxuICAgICAgICAgICAgICAgIGNodW5rLnByb3ZpZGVyTWV0YWRhdGEgPz8gdGV4dFBhcnQucHJvdmlkZXJNZXRhZGF0YTtcbiAgICAgICAgICAgICAgd3JpdGUoKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgJ3RleHQtZW5kJzoge1xuICAgICAgICAgICAgICBjb25zdCB0ZXh0UGFydCA9IHN0YXRlLmFjdGl2ZVRleHRQYXJ0c1tjaHVuay5pZF07XG4gICAgICAgICAgICAgIHRleHRQYXJ0LnN0YXRlID0gJ2RvbmUnO1xuICAgICAgICAgICAgICB0ZXh0UGFydC5wcm92aWRlck1ldGFkYXRhID1cbiAgICAgICAgICAgICAgICBjaHVuay5wcm92aWRlck1ldGFkYXRhID8/IHRleHRQYXJ0LnByb3ZpZGVyTWV0YWRhdGE7XG4gICAgICAgICAgICAgIGRlbGV0ZSBzdGF0ZS5hY3RpdmVUZXh0UGFydHNbY2h1bmsuaWRdO1xuICAgICAgICAgICAgICB3cml0ZSgpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSAncmVhc29uaW5nLXN0YXJ0Jzoge1xuICAgICAgICAgICAgICBjb25zdCByZWFzb25pbmdQYXJ0OiBSZWFzb25pbmdVSVBhcnQgPSB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ3JlYXNvbmluZycsXG4gICAgICAgICAgICAgICAgdGV4dDogJycsXG4gICAgICAgICAgICAgICAgcHJvdmlkZXJNZXRhZGF0YTogY2h1bmsucHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgICAgICAgICBzdGF0ZTogJ3N0cmVhbWluZycsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgIHN0YXRlLmFjdGl2ZVJlYXNvbmluZ1BhcnRzW2NodW5rLmlkXSA9IHJlYXNvbmluZ1BhcnQ7XG4gICAgICAgICAgICAgIHN0YXRlLm1lc3NhZ2UucGFydHMucHVzaChyZWFzb25pbmdQYXJ0KTtcbiAgICAgICAgICAgICAgd3JpdGUoKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgJ3JlYXNvbmluZy1kZWx0YSc6IHtcbiAgICAgICAgICAgICAgY29uc3QgcmVhc29uaW5nUGFydCA9IHN0YXRlLmFjdGl2ZVJlYXNvbmluZ1BhcnRzW2NodW5rLmlkXTtcbiAgICAgICAgICAgICAgcmVhc29uaW5nUGFydC50ZXh0ICs9IGNodW5rLmRlbHRhO1xuICAgICAgICAgICAgICByZWFzb25pbmdQYXJ0LnByb3ZpZGVyTWV0YWRhdGEgPVxuICAgICAgICAgICAgICAgIGNodW5rLnByb3ZpZGVyTWV0YWRhdGEgPz8gcmVhc29uaW5nUGFydC5wcm92aWRlck1ldGFkYXRhO1xuICAgICAgICAgICAgICB3cml0ZSgpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSAncmVhc29uaW5nLWVuZCc6IHtcbiAgICAgICAgICAgICAgY29uc3QgcmVhc29uaW5nUGFydCA9IHN0YXRlLmFjdGl2ZVJlYXNvbmluZ1BhcnRzW2NodW5rLmlkXTtcbiAgICAgICAgICAgICAgcmVhc29uaW5nUGFydC5wcm92aWRlck1ldGFkYXRhID1cbiAgICAgICAgICAgICAgICBjaHVuay5wcm92aWRlck1ldGFkYXRhID8/IHJlYXNvbmluZ1BhcnQucHJvdmlkZXJNZXRhZGF0YTtcbiAgICAgICAgICAgICAgcmVhc29uaW5nUGFydC5zdGF0ZSA9ICdkb25lJztcbiAgICAgICAgICAgICAgZGVsZXRlIHN0YXRlLmFjdGl2ZVJlYXNvbmluZ1BhcnRzW2NodW5rLmlkXTtcblxuICAgICAgICAgICAgICB3cml0ZSgpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSAnZmlsZSc6IHtcbiAgICAgICAgICAgICAgc3RhdGUubWVzc2FnZS5wYXJ0cy5wdXNoKHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnZmlsZScsXG4gICAgICAgICAgICAgICAgbWVkaWFUeXBlOiBjaHVuay5tZWRpYVR5cGUsXG4gICAgICAgICAgICAgICAgdXJsOiBjaHVuay51cmwsXG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIHdyaXRlKCk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYXNlICdzb3VyY2UtdXJsJzoge1xuICAgICAgICAgICAgICBzdGF0ZS5tZXNzYWdlLnBhcnRzLnB1c2goe1xuICAgICAgICAgICAgICAgIHR5cGU6ICdzb3VyY2UtdXJsJyxcbiAgICAgICAgICAgICAgICBzb3VyY2VJZDogY2h1bmsuc291cmNlSWQsXG4gICAgICAgICAgICAgICAgdXJsOiBjaHVuay51cmwsXG4gICAgICAgICAgICAgICAgdGl0bGU6IGNodW5rLnRpdGxlLFxuICAgICAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IGNodW5rLnByb3ZpZGVyTWV0YWRhdGEsXG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIHdyaXRlKCk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYXNlICdzb3VyY2UtZG9jdW1lbnQnOiB7XG4gICAgICAgICAgICAgIHN0YXRlLm1lc3NhZ2UucGFydHMucHVzaCh7XG4gICAgICAgICAgICAgICAgdHlwZTogJ3NvdXJjZS1kb2N1bWVudCcsXG4gICAgICAgICAgICAgICAgc291cmNlSWQ6IGNodW5rLnNvdXJjZUlkLFxuICAgICAgICAgICAgICAgIG1lZGlhVHlwZTogY2h1bmsubWVkaWFUeXBlLFxuICAgICAgICAgICAgICAgIHRpdGxlOiBjaHVuay50aXRsZSxcbiAgICAgICAgICAgICAgICBmaWxlbmFtZTogY2h1bmsuZmlsZW5hbWUsXG4gICAgICAgICAgICAgICAgcHJvdmlkZXJNZXRhZGF0YTogY2h1bmsucHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgd3JpdGUoKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgJ3Rvb2wtaW5wdXQtc3RhcnQnOiB7XG4gICAgICAgICAgICAgIGNvbnN0IHRvb2xJbnZvY2F0aW9ucyA9IHN0YXRlLm1lc3NhZ2UucGFydHMuZmlsdGVyKGlzVG9vbFVJUGFydCk7XG5cbiAgICAgICAgICAgICAgLy8gYWRkIHRoZSBwYXJ0aWFsIHRvb2wgY2FsbCB0byB0aGUgbWFwXG4gICAgICAgICAgICAgIHN0YXRlLnBhcnRpYWxUb29sQ2FsbHNbY2h1bmsudG9vbENhbGxJZF0gPSB7XG4gICAgICAgICAgICAgICAgdGV4dDogJycsXG4gICAgICAgICAgICAgICAgdG9vbE5hbWU6IGNodW5rLnRvb2xOYW1lLFxuICAgICAgICAgICAgICAgIGluZGV4OiB0b29sSW52b2NhdGlvbnMubGVuZ3RoLFxuICAgICAgICAgICAgICAgIGR5bmFtaWM6IGNodW5rLmR5bmFtaWMsXG4gICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgaWYgKGNodW5rLmR5bmFtaWMpIHtcbiAgICAgICAgICAgICAgICB1cGRhdGVEeW5hbWljVG9vbFBhcnQoe1xuICAgICAgICAgICAgICAgICAgdG9vbENhbGxJZDogY2h1bmsudG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgICAgIHRvb2xOYW1lOiBjaHVuay50b29sTmFtZSxcbiAgICAgICAgICAgICAgICAgIHN0YXRlOiAnaW5wdXQtc3RyZWFtaW5nJyxcbiAgICAgICAgICAgICAgICAgIGlucHV0OiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdXBkYXRlVG9vbFBhcnQoe1xuICAgICAgICAgICAgICAgICAgdG9vbENhbGxJZDogY2h1bmsudG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgICAgIHRvb2xOYW1lOiBjaHVuay50b29sTmFtZSxcbiAgICAgICAgICAgICAgICAgIHN0YXRlOiAnaW5wdXQtc3RyZWFtaW5nJyxcbiAgICAgICAgICAgICAgICAgIGlucHV0OiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICBwcm92aWRlckV4ZWN1dGVkOiBjaHVuay5wcm92aWRlckV4ZWN1dGVkLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgd3JpdGUoKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgJ3Rvb2wtaW5wdXQtZGVsdGEnOiB7XG4gICAgICAgICAgICAgIGNvbnN0IHBhcnRpYWxUb29sQ2FsbCA9IHN0YXRlLnBhcnRpYWxUb29sQ2FsbHNbY2h1bmsudG9vbENhbGxJZF07XG5cbiAgICAgICAgICAgICAgcGFydGlhbFRvb2xDYWxsLnRleHQgKz0gY2h1bmsuaW5wdXRUZXh0RGVsdGE7XG5cbiAgICAgICAgICAgICAgY29uc3QgeyB2YWx1ZTogcGFydGlhbEFyZ3MgfSA9IGF3YWl0IHBhcnNlUGFydGlhbEpzb24oXG4gICAgICAgICAgICAgICAgcGFydGlhbFRvb2xDYWxsLnRleHQsXG4gICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgaWYgKHBhcnRpYWxUb29sQ2FsbC5keW5hbWljKSB7XG4gICAgICAgICAgICAgICAgdXBkYXRlRHluYW1pY1Rvb2xQYXJ0KHtcbiAgICAgICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IGNodW5rLnRvb2xDYWxsSWQsXG4gICAgICAgICAgICAgICAgICB0b29sTmFtZTogcGFydGlhbFRvb2xDYWxsLnRvb2xOYW1lLFxuICAgICAgICAgICAgICAgICAgc3RhdGU6ICdpbnB1dC1zdHJlYW1pbmcnLFxuICAgICAgICAgICAgICAgICAgaW5wdXQ6IHBhcnRpYWxBcmdzLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHVwZGF0ZVRvb2xQYXJ0KHtcbiAgICAgICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IGNodW5rLnRvb2xDYWxsSWQsXG4gICAgICAgICAgICAgICAgICB0b29sTmFtZTogcGFydGlhbFRvb2xDYWxsLnRvb2xOYW1lLFxuICAgICAgICAgICAgICAgICAgc3RhdGU6ICdpbnB1dC1zdHJlYW1pbmcnLFxuICAgICAgICAgICAgICAgICAgaW5wdXQ6IHBhcnRpYWxBcmdzLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgd3JpdGUoKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgJ3Rvb2wtaW5wdXQtYXZhaWxhYmxlJzoge1xuICAgICAgICAgICAgICBpZiAoY2h1bmsuZHluYW1pYykge1xuICAgICAgICAgICAgICAgIHVwZGF0ZUR5bmFtaWNUb29sUGFydCh7XG4gICAgICAgICAgICAgICAgICB0b29sQ2FsbElkOiBjaHVuay50b29sQ2FsbElkLFxuICAgICAgICAgICAgICAgICAgdG9vbE5hbWU6IGNodW5rLnRvb2xOYW1lLFxuICAgICAgICAgICAgICAgICAgc3RhdGU6ICdpbnB1dC1hdmFpbGFibGUnLFxuICAgICAgICAgICAgICAgICAgaW5wdXQ6IGNodW5rLmlucHV0LFxuICAgICAgICAgICAgICAgICAgcHJvdmlkZXJNZXRhZGF0YTogY2h1bmsucHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB1cGRhdGVUb29sUGFydCh7XG4gICAgICAgICAgICAgICAgICB0b29sQ2FsbElkOiBjaHVuay50b29sQ2FsbElkLFxuICAgICAgICAgICAgICAgICAgdG9vbE5hbWU6IGNodW5rLnRvb2xOYW1lLFxuICAgICAgICAgICAgICAgICAgc3RhdGU6ICdpbnB1dC1hdmFpbGFibGUnLFxuICAgICAgICAgICAgICAgICAgaW5wdXQ6IGNodW5rLmlucHV0LFxuICAgICAgICAgICAgICAgICAgcHJvdmlkZXJFeGVjdXRlZDogY2h1bmsucHJvdmlkZXJFeGVjdXRlZCxcbiAgICAgICAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IGNodW5rLnByb3ZpZGVyTWV0YWRhdGEsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICB3cml0ZSgpO1xuXG4gICAgICAgICAgICAgIC8vIGludm9rZSB0aGUgb25Ub29sQ2FsbCBjYWxsYmFjayBpZiBpdCBleGlzdHMuIFRoaXMgaXMgYmxvY2tpbmcuXG4gICAgICAgICAgICAgIC8vIEluIHRoZSBmdXR1cmUgd2Ugc2hvdWxkIG1ha2UgdGhpcyBub24tYmxvY2tpbmcsIHdoaWNoXG4gICAgICAgICAgICAgIC8vIHJlcXVpcmVzIGFkZGl0aW9uYWwgc3RhdGUgbWFuYWdlbWVudCBmb3IgZXJyb3IgaGFuZGxpbmcgZXRjLlxuICAgICAgICAgICAgICAvLyBTa2lwIGNhbGxpbmcgb25Ub29sQ2FsbCBmb3IgcHJvdmlkZXItZXhlY3V0ZWQgdG9vbHMgc2luY2UgdGhleSBhcmUgYWxyZWFkeSBleGVjdXRlZFxuICAgICAgICAgICAgICBpZiAob25Ub29sQ2FsbCAmJiAhY2h1bmsucHJvdmlkZXJFeGVjdXRlZCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IG9uVG9vbENhbGwoe1xuICAgICAgICAgICAgICAgICAgdG9vbENhbGw6IGNodW5rIGFzIEluZmVyVUlNZXNzYWdlVG9vbENhbGw8VUlfTUVTU0FHRT4sXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgJ3Rvb2wtaW5wdXQtZXJyb3InOiB7XG4gICAgICAgICAgICAgIGlmIChjaHVuay5keW5hbWljKSB7XG4gICAgICAgICAgICAgICAgdXBkYXRlRHluYW1pY1Rvb2xQYXJ0KHtcbiAgICAgICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IGNodW5rLnRvb2xDYWxsSWQsXG4gICAgICAgICAgICAgICAgICB0b29sTmFtZTogY2h1bmsudG9vbE5hbWUsXG4gICAgICAgICAgICAgICAgICBzdGF0ZTogJ291dHB1dC1lcnJvcicsXG4gICAgICAgICAgICAgICAgICBpbnB1dDogY2h1bmsuaW5wdXQsXG4gICAgICAgICAgICAgICAgICBlcnJvclRleHQ6IGNodW5rLmVycm9yVGV4dCxcbiAgICAgICAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IGNodW5rLnByb3ZpZGVyTWV0YWRhdGEsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdXBkYXRlVG9vbFBhcnQoe1xuICAgICAgICAgICAgICAgICAgdG9vbENhbGxJZDogY2h1bmsudG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgICAgIHRvb2xOYW1lOiBjaHVuay50b29sTmFtZSxcbiAgICAgICAgICAgICAgICAgIHN0YXRlOiAnb3V0cHV0LWVycm9yJyxcbiAgICAgICAgICAgICAgICAgIGlucHV0OiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICByYXdJbnB1dDogY2h1bmsuaW5wdXQsXG4gICAgICAgICAgICAgICAgICBlcnJvclRleHQ6IGNodW5rLmVycm9yVGV4dCxcbiAgICAgICAgICAgICAgICAgIHByb3ZpZGVyRXhlY3V0ZWQ6IGNodW5rLnByb3ZpZGVyRXhlY3V0ZWQsXG4gICAgICAgICAgICAgICAgICBwcm92aWRlck1ldGFkYXRhOiBjaHVuay5wcm92aWRlck1ldGFkYXRhLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgd3JpdGUoKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgJ3Rvb2wtb3V0cHV0LWF2YWlsYWJsZSc6IHtcbiAgICAgICAgICAgICAgaWYgKGNodW5rLmR5bmFtaWMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB0b29sSW52b2NhdGlvbiA9IGdldER5bmFtaWNUb29sSW52b2NhdGlvbihcbiAgICAgICAgICAgICAgICAgIGNodW5rLnRvb2xDYWxsSWQsXG4gICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgIHVwZGF0ZUR5bmFtaWNUb29sUGFydCh7XG4gICAgICAgICAgICAgICAgICB0b29sQ2FsbElkOiBjaHVuay50b29sQ2FsbElkLFxuICAgICAgICAgICAgICAgICAgdG9vbE5hbWU6IHRvb2xJbnZvY2F0aW9uLnRvb2xOYW1lLFxuICAgICAgICAgICAgICAgICAgc3RhdGU6ICdvdXRwdXQtYXZhaWxhYmxlJyxcbiAgICAgICAgICAgICAgICAgIGlucHV0OiAodG9vbEludm9jYXRpb24gYXMgYW55KS5pbnB1dCxcbiAgICAgICAgICAgICAgICAgIG91dHB1dDogY2h1bmsub3V0cHV0LFxuICAgICAgICAgICAgICAgICAgcHJlbGltaW5hcnk6IGNodW5rLnByZWxpbWluYXJ5LFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRvb2xJbnZvY2F0aW9uID0gZ2V0VG9vbEludm9jYXRpb24oY2h1bmsudG9vbENhbGxJZCk7XG5cbiAgICAgICAgICAgICAgICB1cGRhdGVUb29sUGFydCh7XG4gICAgICAgICAgICAgICAgICB0b29sQ2FsbElkOiBjaHVuay50b29sQ2FsbElkLFxuICAgICAgICAgICAgICAgICAgdG9vbE5hbWU6IGdldFRvb2xOYW1lKHRvb2xJbnZvY2F0aW9uKSxcbiAgICAgICAgICAgICAgICAgIHN0YXRlOiAnb3V0cHV0LWF2YWlsYWJsZScsXG4gICAgICAgICAgICAgICAgICBpbnB1dDogKHRvb2xJbnZvY2F0aW9uIGFzIGFueSkuaW5wdXQsXG4gICAgICAgICAgICAgICAgICBvdXRwdXQ6IGNodW5rLm91dHB1dCxcbiAgICAgICAgICAgICAgICAgIHByb3ZpZGVyRXhlY3V0ZWQ6IGNodW5rLnByb3ZpZGVyRXhlY3V0ZWQsXG4gICAgICAgICAgICAgICAgICBwcmVsaW1pbmFyeTogY2h1bmsucHJlbGltaW5hcnksXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICB3cml0ZSgpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSAndG9vbC1vdXRwdXQtZXJyb3InOiB7XG4gICAgICAgICAgICAgIGlmIChjaHVuay5keW5hbWljKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdG9vbEludm9jYXRpb24gPSBnZXREeW5hbWljVG9vbEludm9jYXRpb24oXG4gICAgICAgICAgICAgICAgICBjaHVuay50b29sQ2FsbElkLFxuICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgICB1cGRhdGVEeW5hbWljVG9vbFBhcnQoe1xuICAgICAgICAgICAgICAgICAgdG9vbENhbGxJZDogY2h1bmsudG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgICAgIHRvb2xOYW1lOiB0b29sSW52b2NhdGlvbi50b29sTmFtZSxcbiAgICAgICAgICAgICAgICAgIHN0YXRlOiAnb3V0cHV0LWVycm9yJyxcbiAgICAgICAgICAgICAgICAgIGlucHV0OiAodG9vbEludm9jYXRpb24gYXMgYW55KS5pbnB1dCxcbiAgICAgICAgICAgICAgICAgIGVycm9yVGV4dDogY2h1bmsuZXJyb3JUZXh0LFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRvb2xJbnZvY2F0aW9uID0gZ2V0VG9vbEludm9jYXRpb24oY2h1bmsudG9vbENhbGxJZCk7XG5cbiAgICAgICAgICAgICAgICB1cGRhdGVUb29sUGFydCh7XG4gICAgICAgICAgICAgICAgICB0b29sQ2FsbElkOiBjaHVuay50b29sQ2FsbElkLFxuICAgICAgICAgICAgICAgICAgdG9vbE5hbWU6IGdldFRvb2xOYW1lKHRvb2xJbnZvY2F0aW9uKSxcbiAgICAgICAgICAgICAgICAgIHN0YXRlOiAnb3V0cHV0LWVycm9yJyxcbiAgICAgICAgICAgICAgICAgIGlucHV0OiAodG9vbEludm9jYXRpb24gYXMgYW55KS5pbnB1dCxcbiAgICAgICAgICAgICAgICAgIHJhd0lucHV0OiAodG9vbEludm9jYXRpb24gYXMgYW55KS5yYXdJbnB1dCxcbiAgICAgICAgICAgICAgICAgIGVycm9yVGV4dDogY2h1bmsuZXJyb3JUZXh0LFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgd3JpdGUoKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgJ3N0YXJ0LXN0ZXAnOiB7XG4gICAgICAgICAgICAgIC8vIGFkZCBhIHN0ZXAgYm91bmRhcnkgcGFydCB0byB0aGUgbWVzc2FnZVxuICAgICAgICAgICAgICBzdGF0ZS5tZXNzYWdlLnBhcnRzLnB1c2goeyB0eXBlOiAnc3RlcC1zdGFydCcgfSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYXNlICdmaW5pc2gtc3RlcCc6IHtcbiAgICAgICAgICAgICAgLy8gcmVzZXQgdGhlIGN1cnJlbnQgdGV4dCBhbmQgcmVhc29uaW5nIHBhcnRzXG4gICAgICAgICAgICAgIHN0YXRlLmFjdGl2ZVRleHRQYXJ0cyA9IHt9O1xuICAgICAgICAgICAgICBzdGF0ZS5hY3RpdmVSZWFzb25pbmdQYXJ0cyA9IHt9O1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSAnc3RhcnQnOiB7XG4gICAgICAgICAgICAgIGlmIChjaHVuay5tZXNzYWdlSWQgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHN0YXRlLm1lc3NhZ2UuaWQgPSBjaHVuay5tZXNzYWdlSWQ7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBhd2FpdCB1cGRhdGVNZXNzYWdlTWV0YWRhdGEoY2h1bmsubWVzc2FnZU1ldGFkYXRhKTtcblxuICAgICAgICAgICAgICBpZiAoY2h1bmsubWVzc2FnZUlkICE9IG51bGwgfHwgY2h1bmsubWVzc2FnZU1ldGFkYXRhICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICB3cml0ZSgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYXNlICdmaW5pc2gnOiB7XG4gICAgICAgICAgICAgIGF3YWl0IHVwZGF0ZU1lc3NhZ2VNZXRhZGF0YShjaHVuay5tZXNzYWdlTWV0YWRhdGEpO1xuICAgICAgICAgICAgICBpZiAoY2h1bmsubWVzc2FnZU1ldGFkYXRhICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICB3cml0ZSgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYXNlICdtZXNzYWdlLW1ldGFkYXRhJzoge1xuICAgICAgICAgICAgICBhd2FpdCB1cGRhdGVNZXNzYWdlTWV0YWRhdGEoY2h1bmsubWVzc2FnZU1ldGFkYXRhKTtcbiAgICAgICAgICAgICAgaWYgKGNodW5rLm1lc3NhZ2VNZXRhZGF0YSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgd3JpdGUoKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSAnZXJyb3InOiB7XG4gICAgICAgICAgICAgIG9uRXJyb3I/LihuZXcgRXJyb3IoY2h1bmsuZXJyb3JUZXh0KSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgIGlmIChpc0RhdGFVSU1lc3NhZ2VDaHVuayhjaHVuaykpIHtcbiAgICAgICAgICAgICAgICAvLyB2YWxpZGF0ZSBkYXRhIGNodW5rIGlmIGRhdGFQYXJ0U2NoZW1hcyBpcyBwcm92aWRlZFxuICAgICAgICAgICAgICAgIGlmIChkYXRhUGFydFNjaGVtYXM/LltjaHVuay50eXBlXSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICBhd2FpdCB2YWxpZGF0ZVR5cGVzKHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGNodW5rLmRhdGEsXG4gICAgICAgICAgICAgICAgICAgIHNjaGVtYTogZGF0YVBhcnRTY2hlbWFzW2NodW5rLnR5cGVdLFxuICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gY2FzdCwgdmFsaWRhdGlvbiBpcyBkb25lIGFib3ZlXG4gICAgICAgICAgICAgICAgY29uc3QgZGF0YUNodW5rID0gY2h1bmsgYXMgRGF0YVVJTWVzc2FnZUNodW5rPFxuICAgICAgICAgICAgICAgICAgSW5mZXJVSU1lc3NhZ2VEYXRhPFVJX01FU1NBR0U+XG4gICAgICAgICAgICAgICAgPjtcblxuICAgICAgICAgICAgICAgIC8vIHRyYW5zaWVudCBwYXJ0cyBhcmUgbm90IGFkZGVkIHRvIHRoZSBtZXNzYWdlIHN0YXRlXG4gICAgICAgICAgICAgICAgaWYgKGRhdGFDaHVuay50cmFuc2llbnQpIHtcbiAgICAgICAgICAgICAgICAgIG9uRGF0YT8uKGRhdGFDaHVuayk7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCBleGlzdGluZ1VJUGFydCA9XG4gICAgICAgICAgICAgICAgICBkYXRhQ2h1bmsuaWQgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgICA/IChzdGF0ZS5tZXNzYWdlLnBhcnRzLmZpbmQoXG4gICAgICAgICAgICAgICAgICAgICAgICBjaHVua0FyZyA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhQ2h1bmsudHlwZSA9PT0gY2h1bmtBcmcudHlwZSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhQ2h1bmsuaWQgPT09IGNodW5rQXJnLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICkgYXNcbiAgICAgICAgICAgICAgICAgICAgICAgIHwgRGF0YVVJUGFydDxJbmZlclVJTWVzc2FnZURhdGE8VUlfTUVTU0FHRT4+XG4gICAgICAgICAgICAgICAgICAgICAgICB8IHVuZGVmaW5lZClcbiAgICAgICAgICAgICAgICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgICAgICAgICBpZiAoZXhpc3RpbmdVSVBhcnQgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgZXhpc3RpbmdVSVBhcnQuZGF0YSA9IGRhdGFDaHVuay5kYXRhO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBzdGF0ZS5tZXNzYWdlLnBhcnRzLnB1c2goZGF0YUNodW5rKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBvbkRhdGE/LihkYXRhQ2h1bmspO1xuXG4gICAgICAgICAgICAgICAgd3JpdGUoKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShjaHVuayBhcyBJbmZlclVJTWVzc2FnZUNodW5rPFVJX01FU1NBR0U+KTtcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgIH0pLFxuICApO1xufVxuIiwgImltcG9ydCB7IHogfSBmcm9tICd6b2QvdjQnO1xuaW1wb3J0IHtcbiAgUHJvdmlkZXJNZXRhZGF0YSxcbiAgcHJvdmlkZXJNZXRhZGF0YVNjaGVtYSxcbn0gZnJvbSAnLi4vdHlwZXMvcHJvdmlkZXItbWV0YWRhdGEnO1xuaW1wb3J0IHtcbiAgSW5mZXJVSU1lc3NhZ2VEYXRhLFxuICBJbmZlclVJTWVzc2FnZU1ldGFkYXRhLFxuICBVSURhdGFUeXBlcyxcbiAgVUlNZXNzYWdlLFxufSBmcm9tICcuLi91aS91aS1tZXNzYWdlcyc7XG5pbXBvcnQgeyBWYWx1ZU9mIH0gZnJvbSAnLi4vdXRpbC92YWx1ZS1vZic7XG5pbXBvcnQgeyBsYXp5VmFsaWRhdG9yLCB6b2RTY2hlbWEgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyLXV0aWxzJztcblxuZXhwb3J0IGNvbnN0IHVpTWVzc2FnZUNodW5rU2NoZW1hID0gbGF6eVZhbGlkYXRvcigoKSA9PlxuICB6b2RTY2hlbWEoXG4gICAgei51bmlvbihbXG4gICAgICB6LnN0cmljdE9iamVjdCh7XG4gICAgICAgIHR5cGU6IHoubGl0ZXJhbCgndGV4dC1zdGFydCcpLFxuICAgICAgICBpZDogei5zdHJpbmcoKSxcbiAgICAgICAgcHJvdmlkZXJNZXRhZGF0YTogcHJvdmlkZXJNZXRhZGF0YVNjaGVtYS5vcHRpb25hbCgpLFxuICAgICAgfSksXG4gICAgICB6LnN0cmljdE9iamVjdCh7XG4gICAgICAgIHR5cGU6IHoubGl0ZXJhbCgndGV4dC1kZWx0YScpLFxuICAgICAgICBpZDogei5zdHJpbmcoKSxcbiAgICAgICAgZGVsdGE6IHouc3RyaW5nKCksXG4gICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbiAgICAgIH0pLFxuICAgICAgei5zdHJpY3RPYmplY3Qoe1xuICAgICAgICB0eXBlOiB6LmxpdGVyYWwoJ3RleHQtZW5kJyksXG4gICAgICAgIGlkOiB6LnN0cmluZygpLFxuICAgICAgICBwcm92aWRlck1ldGFkYXRhOiBwcm92aWRlck1ldGFkYXRhU2NoZW1hLm9wdGlvbmFsKCksXG4gICAgICB9KSxcbiAgICAgIHouc3RyaWN0T2JqZWN0KHtcbiAgICAgICAgdHlwZTogei5saXRlcmFsKCdlcnJvcicpLFxuICAgICAgICBlcnJvclRleHQ6IHouc3RyaW5nKCksXG4gICAgICB9KSxcbiAgICAgIHouc3RyaWN0T2JqZWN0KHtcbiAgICAgICAgdHlwZTogei5saXRlcmFsKCd0b29sLWlucHV0LXN0YXJ0JyksXG4gICAgICAgIHRvb2xDYWxsSWQ6IHouc3RyaW5nKCksXG4gICAgICAgIHRvb2xOYW1lOiB6LnN0cmluZygpLFxuICAgICAgICBwcm92aWRlckV4ZWN1dGVkOiB6LmJvb2xlYW4oKS5vcHRpb25hbCgpLFxuICAgICAgICBkeW5hbWljOiB6LmJvb2xlYW4oKS5vcHRpb25hbCgpLFxuICAgICAgfSksXG4gICAgICB6LnN0cmljdE9iamVjdCh7XG4gICAgICAgIHR5cGU6IHoubGl0ZXJhbCgndG9vbC1pbnB1dC1kZWx0YScpLFxuICAgICAgICB0b29sQ2FsbElkOiB6LnN0cmluZygpLFxuICAgICAgICBpbnB1dFRleHREZWx0YTogei5zdHJpbmcoKSxcbiAgICAgIH0pLFxuICAgICAgei5zdHJpY3RPYmplY3Qoe1xuICAgICAgICB0eXBlOiB6LmxpdGVyYWwoJ3Rvb2wtaW5wdXQtYXZhaWxhYmxlJyksXG4gICAgICAgIHRvb2xDYWxsSWQ6IHouc3RyaW5nKCksXG4gICAgICAgIHRvb2xOYW1lOiB6LnN0cmluZygpLFxuICAgICAgICBpbnB1dDogei51bmtub3duKCksXG4gICAgICAgIHByb3ZpZGVyRXhlY3V0ZWQ6IHouYm9vbGVhbigpLm9wdGlvbmFsKCksXG4gICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbiAgICAgICAgZHluYW1pYzogei5ib29sZWFuKCkub3B0aW9uYWwoKSxcbiAgICAgIH0pLFxuICAgICAgei5zdHJpY3RPYmplY3Qoe1xuICAgICAgICB0eXBlOiB6LmxpdGVyYWwoJ3Rvb2wtaW5wdXQtZXJyb3InKSxcbiAgICAgICAgdG9vbENhbGxJZDogei5zdHJpbmcoKSxcbiAgICAgICAgdG9vbE5hbWU6IHouc3RyaW5nKCksXG4gICAgICAgIGlucHV0OiB6LnVua25vd24oKSxcbiAgICAgICAgcHJvdmlkZXJFeGVjdXRlZDogei5ib29sZWFuKCkub3B0aW9uYWwoKSxcbiAgICAgICAgcHJvdmlkZXJNZXRhZGF0YTogcHJvdmlkZXJNZXRhZGF0YVNjaGVtYS5vcHRpb25hbCgpLFxuICAgICAgICBkeW5hbWljOiB6LmJvb2xlYW4oKS5vcHRpb25hbCgpLFxuICAgICAgICBlcnJvclRleHQ6IHouc3RyaW5nKCksXG4gICAgICB9KSxcbiAgICAgIHouc3RyaWN0T2JqZWN0KHtcbiAgICAgICAgdHlwZTogei5saXRlcmFsKCd0b29sLW91dHB1dC1hdmFpbGFibGUnKSxcbiAgICAgICAgdG9vbENhbGxJZDogei5zdHJpbmcoKSxcbiAgICAgICAgb3V0cHV0OiB6LnVua25vd24oKSxcbiAgICAgICAgcHJvdmlkZXJFeGVjdXRlZDogei5ib29sZWFuKCkub3B0aW9uYWwoKSxcbiAgICAgICAgZHluYW1pYzogei5ib29sZWFuKCkub3B0aW9uYWwoKSxcbiAgICAgICAgcHJlbGltaW5hcnk6IHouYm9vbGVhbigpLm9wdGlvbmFsKCksXG4gICAgICB9KSxcbiAgICAgIHouc3RyaWN0T2JqZWN0KHtcbiAgICAgICAgdHlwZTogei5saXRlcmFsKCd0b29sLW91dHB1dC1lcnJvcicpLFxuICAgICAgICB0b29sQ2FsbElkOiB6LnN0cmluZygpLFxuICAgICAgICBlcnJvclRleHQ6IHouc3RyaW5nKCksXG4gICAgICAgIHByb3ZpZGVyRXhlY3V0ZWQ6IHouYm9vbGVhbigpLm9wdGlvbmFsKCksXG4gICAgICAgIGR5bmFtaWM6IHouYm9vbGVhbigpLm9wdGlvbmFsKCksXG4gICAgICB9KSxcbiAgICAgIHouc3RyaWN0T2JqZWN0KHtcbiAgICAgICAgdHlwZTogei5saXRlcmFsKCdyZWFzb25pbmctc3RhcnQnKSxcbiAgICAgICAgaWQ6IHouc3RyaW5nKCksXG4gICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbiAgICAgIH0pLFxuICAgICAgei5zdHJpY3RPYmplY3Qoe1xuICAgICAgICB0eXBlOiB6LmxpdGVyYWwoJ3JlYXNvbmluZy1kZWx0YScpLFxuICAgICAgICBpZDogei5zdHJpbmcoKSxcbiAgICAgICAgZGVsdGE6IHouc3RyaW5nKCksXG4gICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbiAgICAgIH0pLFxuICAgICAgei5zdHJpY3RPYmplY3Qoe1xuICAgICAgICB0eXBlOiB6LmxpdGVyYWwoJ3JlYXNvbmluZy1lbmQnKSxcbiAgICAgICAgaWQ6IHouc3RyaW5nKCksXG4gICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbiAgICAgIH0pLFxuICAgICAgei5zdHJpY3RPYmplY3Qoe1xuICAgICAgICB0eXBlOiB6LmxpdGVyYWwoJ3NvdXJjZS11cmwnKSxcbiAgICAgICAgc291cmNlSWQ6IHouc3RyaW5nKCksXG4gICAgICAgIHVybDogei5zdHJpbmcoKSxcbiAgICAgICAgdGl0bGU6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgICAgICAgcHJvdmlkZXJNZXRhZGF0YTogcHJvdmlkZXJNZXRhZGF0YVNjaGVtYS5vcHRpb25hbCgpLFxuICAgICAgfSksXG4gICAgICB6LnN0cmljdE9iamVjdCh7XG4gICAgICAgIHR5cGU6IHoubGl0ZXJhbCgnc291cmNlLWRvY3VtZW50JyksXG4gICAgICAgIHNvdXJjZUlkOiB6LnN0cmluZygpLFxuICAgICAgICBtZWRpYVR5cGU6IHouc3RyaW5nKCksXG4gICAgICAgIHRpdGxlOiB6LnN0cmluZygpLFxuICAgICAgICBmaWxlbmFtZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICAgICAgICBwcm92aWRlck1ldGFkYXRhOiBwcm92aWRlck1ldGFkYXRhU2NoZW1hLm9wdGlvbmFsKCksXG4gICAgICB9KSxcbiAgICAgIHouc3RyaWN0T2JqZWN0KHtcbiAgICAgICAgdHlwZTogei5saXRlcmFsKCdmaWxlJyksXG4gICAgICAgIHVybDogei5zdHJpbmcoKSxcbiAgICAgICAgbWVkaWFUeXBlOiB6LnN0cmluZygpLFxuICAgICAgICBwcm92aWRlck1ldGFkYXRhOiBwcm92aWRlck1ldGFkYXRhU2NoZW1hLm9wdGlvbmFsKCksXG4gICAgICB9KSxcbiAgICAgIHouc3RyaWN0T2JqZWN0KHtcbiAgICAgICAgdHlwZTogei5jdXN0b208YGRhdGEtJHtzdHJpbmd9YD4oXG4gICAgICAgICAgKHZhbHVlKTogdmFsdWUgaXMgYGRhdGEtJHtzdHJpbmd9YCA9PlxuICAgICAgICAgICAgdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyAmJiB2YWx1ZS5zdGFydHNXaXRoKCdkYXRhLScpLFxuICAgICAgICAgIHsgbWVzc2FnZTogJ1R5cGUgbXVzdCBzdGFydCB3aXRoIFwiZGF0YS1cIicgfSxcbiAgICAgICAgKSxcbiAgICAgICAgaWQ6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgICAgICAgZGF0YTogei51bmtub3duKCksXG4gICAgICAgIHRyYW5zaWVudDogei5ib29sZWFuKCkub3B0aW9uYWwoKSxcbiAgICAgIH0pLFxuICAgICAgei5zdHJpY3RPYmplY3Qoe1xuICAgICAgICB0eXBlOiB6LmxpdGVyYWwoJ3N0YXJ0LXN0ZXAnKSxcbiAgICAgIH0pLFxuICAgICAgei5zdHJpY3RPYmplY3Qoe1xuICAgICAgICB0eXBlOiB6LmxpdGVyYWwoJ2ZpbmlzaC1zdGVwJyksXG4gICAgICB9KSxcbiAgICAgIHouc3RyaWN0T2JqZWN0KHtcbiAgICAgICAgdHlwZTogei5saXRlcmFsKCdzdGFydCcpLFxuICAgICAgICBtZXNzYWdlSWQ6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgICAgICAgbWVzc2FnZU1ldGFkYXRhOiB6LnVua25vd24oKS5vcHRpb25hbCgpLFxuICAgICAgfSksXG4gICAgICB6LnN0cmljdE9iamVjdCh7XG4gICAgICAgIHR5cGU6IHoubGl0ZXJhbCgnZmluaXNoJyksXG4gICAgICAgIG1lc3NhZ2VNZXRhZGF0YTogei51bmtub3duKCkub3B0aW9uYWwoKSxcbiAgICAgIH0pLFxuICAgICAgei5zdHJpY3RPYmplY3Qoe1xuICAgICAgICB0eXBlOiB6LmxpdGVyYWwoJ2Fib3J0JyksXG4gICAgICB9KSxcbiAgICAgIHouc3RyaWN0T2JqZWN0KHtcbiAgICAgICAgdHlwZTogei5saXRlcmFsKCdtZXNzYWdlLW1ldGFkYXRhJyksXG4gICAgICAgIG1lc3NhZ2VNZXRhZGF0YTogei51bmtub3duKCksXG4gICAgICB9KSxcbiAgICBdKSxcbiAgKSxcbik7XG5cbmV4cG9ydCB0eXBlIERhdGFVSU1lc3NhZ2VDaHVuazxEQVRBX1RZUEVTIGV4dGVuZHMgVUlEYXRhVHlwZXM+ID0gVmFsdWVPZjx7XG4gIFtOQU1FIGluIGtleW9mIERBVEFfVFlQRVMgJiBzdHJpbmddOiB7XG4gICAgdHlwZTogYGRhdGEtJHtOQU1FfWA7XG4gICAgaWQ/OiBzdHJpbmc7XG4gICAgZGF0YTogREFUQV9UWVBFU1tOQU1FXTtcbiAgICB0cmFuc2llbnQ/OiBib29sZWFuO1xuICB9O1xufT47XG5cbmV4cG9ydCB0eXBlIFVJTWVzc2FnZUNodW5rPFxuICBNRVRBREFUQSA9IHVua25vd24sXG4gIERBVEFfVFlQRVMgZXh0ZW5kcyBVSURhdGFUeXBlcyA9IFVJRGF0YVR5cGVzLFxuPiA9XG4gIHwge1xuICAgICAgdHlwZTogJ3RleHQtc3RhcnQnO1xuICAgICAgaWQ6IHN0cmluZztcbiAgICAgIHByb3ZpZGVyTWV0YWRhdGE/OiBQcm92aWRlck1ldGFkYXRhO1xuICAgIH1cbiAgfCB7XG4gICAgICB0eXBlOiAndGV4dC1kZWx0YSc7XG4gICAgICBkZWx0YTogc3RyaW5nO1xuICAgICAgaWQ6IHN0cmluZztcbiAgICAgIHByb3ZpZGVyTWV0YWRhdGE/OiBQcm92aWRlck1ldGFkYXRhO1xuICAgIH1cbiAgfCB7XG4gICAgICB0eXBlOiAndGV4dC1lbmQnO1xuICAgICAgaWQ6IHN0cmluZztcbiAgICAgIHByb3ZpZGVyTWV0YWRhdGE/OiBQcm92aWRlck1ldGFkYXRhO1xuICAgIH1cbiAgfCB7XG4gICAgICB0eXBlOiAncmVhc29uaW5nLXN0YXJ0JztcbiAgICAgIGlkOiBzdHJpbmc7XG4gICAgICBwcm92aWRlck1ldGFkYXRhPzogUHJvdmlkZXJNZXRhZGF0YTtcbiAgICB9XG4gIHwge1xuICAgICAgdHlwZTogJ3JlYXNvbmluZy1kZWx0YSc7XG4gICAgICBpZDogc3RyaW5nO1xuICAgICAgZGVsdGE6IHN0cmluZztcbiAgICAgIHByb3ZpZGVyTWV0YWRhdGE/OiBQcm92aWRlck1ldGFkYXRhO1xuICAgIH1cbiAgfCB7XG4gICAgICB0eXBlOiAncmVhc29uaW5nLWVuZCc7XG4gICAgICBpZDogc3RyaW5nO1xuICAgICAgcHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG4gICAgfVxuICB8IHtcbiAgICAgIHR5cGU6ICdlcnJvcic7XG4gICAgICBlcnJvclRleHQ6IHN0cmluZztcbiAgICB9XG4gIHwge1xuICAgICAgdHlwZTogJ3Rvb2wtaW5wdXQtYXZhaWxhYmxlJztcbiAgICAgIHRvb2xDYWxsSWQ6IHN0cmluZztcbiAgICAgIHRvb2xOYW1lOiBzdHJpbmc7XG4gICAgICBpbnB1dDogdW5rbm93bjtcbiAgICAgIHByb3ZpZGVyRXhlY3V0ZWQ/OiBib29sZWFuO1xuICAgICAgcHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG4gICAgICBkeW5hbWljPzogYm9vbGVhbjtcbiAgICB9XG4gIHwge1xuICAgICAgdHlwZTogJ3Rvb2wtaW5wdXQtZXJyb3InO1xuICAgICAgdG9vbENhbGxJZDogc3RyaW5nO1xuICAgICAgdG9vbE5hbWU6IHN0cmluZztcbiAgICAgIGlucHV0OiB1bmtub3duO1xuICAgICAgcHJvdmlkZXJFeGVjdXRlZD86IGJvb2xlYW47XG4gICAgICBwcm92aWRlck1ldGFkYXRhPzogUHJvdmlkZXJNZXRhZGF0YTtcbiAgICAgIGR5bmFtaWM/OiBib29sZWFuO1xuICAgICAgZXJyb3JUZXh0OiBzdHJpbmc7XG4gICAgfVxuICB8IHtcbiAgICAgIHR5cGU6ICd0b29sLW91dHB1dC1hdmFpbGFibGUnO1xuICAgICAgdG9vbENhbGxJZDogc3RyaW5nO1xuICAgICAgb3V0cHV0OiB1bmtub3duO1xuICAgICAgcHJvdmlkZXJFeGVjdXRlZD86IGJvb2xlYW47XG4gICAgICBkeW5hbWljPzogYm9vbGVhbjtcbiAgICAgIHByZWxpbWluYXJ5PzogYm9vbGVhbjtcbiAgICB9XG4gIHwge1xuICAgICAgdHlwZTogJ3Rvb2wtb3V0cHV0LWVycm9yJztcbiAgICAgIHRvb2xDYWxsSWQ6IHN0cmluZztcbiAgICAgIGVycm9yVGV4dDogc3RyaW5nO1xuICAgICAgcHJvdmlkZXJFeGVjdXRlZD86IGJvb2xlYW47XG4gICAgICBkeW5hbWljPzogYm9vbGVhbjtcbiAgICB9XG4gIHwge1xuICAgICAgdHlwZTogJ3Rvb2wtaW5wdXQtc3RhcnQnO1xuICAgICAgdG9vbENhbGxJZDogc3RyaW5nO1xuICAgICAgdG9vbE5hbWU6IHN0cmluZztcbiAgICAgIHByb3ZpZGVyRXhlY3V0ZWQ/OiBib29sZWFuO1xuICAgICAgZHluYW1pYz86IGJvb2xlYW47XG4gICAgfVxuICB8IHtcbiAgICAgIHR5cGU6ICd0b29sLWlucHV0LWRlbHRhJztcbiAgICAgIHRvb2xDYWxsSWQ6IHN0cmluZztcbiAgICAgIGlucHV0VGV4dERlbHRhOiBzdHJpbmc7XG4gICAgfVxuICB8IHtcbiAgICAgIHR5cGU6ICdzb3VyY2UtdXJsJztcbiAgICAgIHNvdXJjZUlkOiBzdHJpbmc7XG4gICAgICB1cmw6IHN0cmluZztcbiAgICAgIHRpdGxlPzogc3RyaW5nO1xuICAgICAgcHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG4gICAgfVxuICB8IHtcbiAgICAgIHR5cGU6ICdzb3VyY2UtZG9jdW1lbnQnO1xuICAgICAgc291cmNlSWQ6IHN0cmluZztcbiAgICAgIG1lZGlhVHlwZTogc3RyaW5nO1xuICAgICAgdGl0bGU6IHN0cmluZztcbiAgICAgIGZpbGVuYW1lPzogc3RyaW5nO1xuICAgICAgcHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG4gICAgfVxuICB8IHtcbiAgICAgIHR5cGU6ICdmaWxlJztcbiAgICAgIHVybDogc3RyaW5nO1xuICAgICAgbWVkaWFUeXBlOiBzdHJpbmc7XG4gICAgICBwcm92aWRlck1ldGFkYXRhPzogUHJvdmlkZXJNZXRhZGF0YTtcbiAgICB9XG4gIHwgRGF0YVVJTWVzc2FnZUNodW5rPERBVEFfVFlQRVM+XG4gIHwge1xuICAgICAgdHlwZTogJ3N0YXJ0LXN0ZXAnO1xuICAgIH1cbiAgfCB7XG4gICAgICB0eXBlOiAnZmluaXNoLXN0ZXAnO1xuICAgIH1cbiAgfCB7XG4gICAgICB0eXBlOiAnc3RhcnQnO1xuICAgICAgbWVzc2FnZUlkPzogc3RyaW5nO1xuICAgICAgbWVzc2FnZU1ldGFkYXRhPzogTUVUQURBVEE7XG4gICAgfVxuICB8IHtcbiAgICAgIHR5cGU6ICdmaW5pc2gnO1xuICAgICAgbWVzc2FnZU1ldGFkYXRhPzogTUVUQURBVEE7XG4gICAgfVxuICB8IHtcbiAgICAgIHR5cGU6ICdhYm9ydCc7XG4gICAgfVxuICB8IHtcbiAgICAgIHR5cGU6ICdtZXNzYWdlLW1ldGFkYXRhJztcbiAgICAgIG1lc3NhZ2VNZXRhZGF0YTogTUVUQURBVEE7XG4gICAgfTtcblxuZXhwb3J0IGZ1bmN0aW9uIGlzRGF0YVVJTWVzc2FnZUNodW5rKFxuICBjaHVuazogVUlNZXNzYWdlQ2h1bmssXG4pOiBjaHVuayBpcyBEYXRhVUlNZXNzYWdlQ2h1bms8VUlEYXRhVHlwZXM+IHtcbiAgcmV0dXJuIGNodW5rLnR5cGUuc3RhcnRzV2l0aCgnZGF0YS0nKTtcbn1cblxuZXhwb3J0IHR5cGUgSW5mZXJVSU1lc3NhZ2VDaHVuazxUIGV4dGVuZHMgVUlNZXNzYWdlPiA9IFVJTWVzc2FnZUNodW5rPFxuICBJbmZlclVJTWVzc2FnZU1ldGFkYXRhPFQ+LFxuICBJbmZlclVJTWVzc2FnZURhdGE8VD5cbj47XG4iLCAiLyoqXG4gKiBEZWVwbHkgbWVyZ2VzIHR3byBvYmplY3RzIHRvZ2V0aGVyLlxuICogLSBQcm9wZXJ0aWVzIGZyb20gdGhlIGBvdmVycmlkZXNgIG9iamVjdCBvdmVycmlkZSB0aG9zZSBpbiB0aGUgYGJhc2VgIG9iamVjdCB3aXRoIHRoZSBzYW1lIGtleS5cbiAqIC0gRm9yIG5lc3RlZCBvYmplY3RzLCB0aGUgbWVyZ2UgaXMgcGVyZm9ybWVkIHJlY3Vyc2l2ZWx5IChkZWVwIG1lcmdlKS5cbiAqIC0gQXJyYXlzIGFyZSByZXBsYWNlZCwgbm90IG1lcmdlZC5cbiAqIC0gUHJpbWl0aXZlIHZhbHVlcyBhcmUgcmVwbGFjZWQuXG4gKiAtIElmIGJvdGggYGJhc2VgIGFuZCBgb3ZlcnJpZGVzYCBhcmUgdW5kZWZpbmVkLCByZXR1cm5zIHVuZGVmaW5lZC5cbiAqIC0gSWYgb25lIG9mIGBiYXNlYCBvciBgb3ZlcnJpZGVzYCBpcyB1bmRlZmluZWQsIHJldHVybnMgdGhlIG90aGVyLlxuICpcbiAqIEBwYXJhbSBiYXNlIFRoZSB0YXJnZXQgb2JqZWN0IHRvIG1lcmdlIGludG9cbiAqIEBwYXJhbSBvdmVycmlkZXMgVGhlIHNvdXJjZSBvYmplY3QgdG8gbWVyZ2UgZnJvbVxuICogQHJldHVybnMgQSBuZXcgb2JqZWN0IHdpdGggdGhlIG1lcmdlZCBwcm9wZXJ0aWVzLCBvciB1bmRlZmluZWQgaWYgYm90aCBpbnB1dHMgYXJlIHVuZGVmaW5lZFxuICovXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VPYmplY3RzPFQgZXh0ZW5kcyBvYmplY3QsIFUgZXh0ZW5kcyBvYmplY3Q+KFxuICBiYXNlOiBUIHwgdW5kZWZpbmVkLFxuICBvdmVycmlkZXM6IFUgfCB1bmRlZmluZWQsXG4pOiAoVCAmIFUpIHwgVCB8IFUgfCB1bmRlZmluZWQge1xuICAvLyBJZiBib3RoIGlucHV0cyBhcmUgdW5kZWZpbmVkLCByZXR1cm4gdW5kZWZpbmVkXG4gIGlmIChiYXNlID09PSB1bmRlZmluZWQgJiYgb3ZlcnJpZGVzID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgLy8gSWYgdGFyZ2V0IGlzIHVuZGVmaW5lZCwgcmV0dXJuIHNvdXJjZVxuICBpZiAoYmFzZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIG92ZXJyaWRlcztcbiAgfVxuXG4gIC8vIElmIHNvdXJjZSBpcyB1bmRlZmluZWQsIHJldHVybiB0YXJnZXRcbiAgaWYgKG92ZXJyaWRlcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGJhc2U7XG4gIH1cblxuICAvLyBDcmVhdGUgYSBuZXcgb2JqZWN0IHRvIGF2b2lkIG11dGF0aW5nIHRoZSBpbnB1dHNcbiAgY29uc3QgcmVzdWx0ID0geyAuLi5iYXNlIH0gYXMgVCAmIFU7XG5cbiAgLy8gSXRlcmF0ZSB0aHJvdWdoIGFsbCBrZXlzIGluIHRoZSBzb3VyY2Ugb2JqZWN0XG4gIGZvciAoY29uc3Qga2V5IGluIG92ZXJyaWRlcykge1xuICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob3ZlcnJpZGVzLCBrZXkpKSB7XG4gICAgICBjb25zdCBvdmVycmlkZXNWYWx1ZSA9IG92ZXJyaWRlc1trZXldO1xuXG4gICAgICAvLyBTa2lwIGlmIHRoZSBvdmVycmlkZXMgdmFsdWUgaXMgdW5kZWZpbmVkXG4gICAgICBpZiAob3ZlcnJpZGVzVmFsdWUgPT09IHVuZGVmaW5lZCkgY29udGludWU7XG5cbiAgICAgIC8vIEdldCB0aGUgYmFzZSB2YWx1ZSBpZiBpdCBleGlzdHNcbiAgICAgIGNvbnN0IGJhc2VWYWx1ZSA9XG4gICAgICAgIGtleSBpbiBiYXNlID8gYmFzZVtrZXkgYXMgdW5rbm93biBhcyBrZXlvZiBUXSA6IHVuZGVmaW5lZDtcblxuICAgICAgLy8gQ2hlY2sgaWYgYm90aCB2YWx1ZXMgYXJlIG9iamVjdHMgdGhhdCBjYW4gYmUgZGVlcGx5IG1lcmdlZFxuICAgICAgY29uc3QgaXNTb3VyY2VPYmplY3QgPVxuICAgICAgICBvdmVycmlkZXNWYWx1ZSAhPT0gbnVsbCAmJlxuICAgICAgICB0eXBlb2Ygb3ZlcnJpZGVzVmFsdWUgPT09ICdvYmplY3QnICYmXG4gICAgICAgICFBcnJheS5pc0FycmF5KG92ZXJyaWRlc1ZhbHVlKSAmJlxuICAgICAgICAhKG92ZXJyaWRlc1ZhbHVlIGluc3RhbmNlb2YgRGF0ZSkgJiZcbiAgICAgICAgIShvdmVycmlkZXNWYWx1ZSBpbnN0YW5jZW9mIFJlZ0V4cCk7XG5cbiAgICAgIGNvbnN0IGlzVGFyZ2V0T2JqZWN0ID1cbiAgICAgICAgYmFzZVZhbHVlICE9PSBudWxsICYmXG4gICAgICAgIGJhc2VWYWx1ZSAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAgIHR5cGVvZiBiYXNlVmFsdWUgPT09ICdvYmplY3QnICYmXG4gICAgICAgICFBcnJheS5pc0FycmF5KGJhc2VWYWx1ZSkgJiZcbiAgICAgICAgIShiYXNlVmFsdWUgaW5zdGFuY2VvZiBEYXRlKSAmJlxuICAgICAgICAhKGJhc2VWYWx1ZSBpbnN0YW5jZW9mIFJlZ0V4cCk7XG5cbiAgICAgIC8vIElmIGJvdGggdmFsdWVzIGFyZSBtZXJnZWFibGUgb2JqZWN0cywgbWVyZ2UgdGhlbSByZWN1cnNpdmVseVxuICAgICAgaWYgKGlzU291cmNlT2JqZWN0ICYmIGlzVGFyZ2V0T2JqZWN0KSB7XG4gICAgICAgIHJlc3VsdFtrZXkgYXMga2V5b2YgKFQgJiBVKV0gPSBtZXJnZU9iamVjdHMoXG4gICAgICAgICAgYmFzZVZhbHVlIGFzIG9iamVjdCxcbiAgICAgICAgICBvdmVycmlkZXNWYWx1ZSBhcyBvYmplY3QsXG4gICAgICAgICkgYXMgYW55O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gRm9yIHByaW1pdGl2ZXMsIGFycmF5cywgb3Igd2hlbiBvbmUgdmFsdWUgaXMgbm90IGEgbWVyZ2VhYmxlIG9iamVjdCxcbiAgICAgICAgLy8gc2ltcGx5IG92ZXJyaWRlIHdpdGggdGhlIHNvdXJjZSB2YWx1ZVxuICAgICAgICByZXN1bHRba2V5IGFzIGtleW9mIChUICYgVSldID0gb3ZlcnJpZGVzVmFsdWUgYXMgYW55O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG4iLCAiaW1wb3J0IHsgSlNPTlZhbHVlIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQgeyBzYWZlUGFyc2VKU09OIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyBmaXhKc29uIH0gZnJvbSAnLi9maXgtanNvbic7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwYXJzZVBhcnRpYWxKc29uKGpzb25UZXh0OiBzdHJpbmcgfCB1bmRlZmluZWQpOiBQcm9taXNlPHtcbiAgdmFsdWU6IEpTT05WYWx1ZSB8IHVuZGVmaW5lZDtcbiAgc3RhdGU6XG4gICAgfCAndW5kZWZpbmVkLWlucHV0J1xuICAgIHwgJ3N1Y2Nlc3NmdWwtcGFyc2UnXG4gICAgfCAncmVwYWlyZWQtcGFyc2UnXG4gICAgfCAnZmFpbGVkLXBhcnNlJztcbn0+IHtcbiAgaWYgKGpzb25UZXh0ID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4geyB2YWx1ZTogdW5kZWZpbmVkLCBzdGF0ZTogJ3VuZGVmaW5lZC1pbnB1dCcgfTtcbiAgfVxuXG4gIGxldCByZXN1bHQgPSBhd2FpdCBzYWZlUGFyc2VKU09OKHsgdGV4dDoganNvblRleHQgfSk7XG5cbiAgaWYgKHJlc3VsdC5zdWNjZXNzKSB7XG4gICAgcmV0dXJuIHsgdmFsdWU6IHJlc3VsdC52YWx1ZSwgc3RhdGU6ICdzdWNjZXNzZnVsLXBhcnNlJyB9O1xuICB9XG5cbiAgcmVzdWx0ID0gYXdhaXQgc2FmZVBhcnNlSlNPTih7IHRleHQ6IGZpeEpzb24oanNvblRleHQpIH0pO1xuXG4gIGlmIChyZXN1bHQuc3VjY2Vzcykge1xuICAgIHJldHVybiB7IHZhbHVlOiByZXN1bHQudmFsdWUsIHN0YXRlOiAncmVwYWlyZWQtcGFyc2UnIH07XG4gIH1cblxuICByZXR1cm4geyB2YWx1ZTogdW5kZWZpbmVkLCBzdGF0ZTogJ2ZhaWxlZC1wYXJzZScgfTtcbn1cbiIsICJ0eXBlIFN0YXRlID1cbiAgfCAnUk9PVCdcbiAgfCAnRklOSVNIJ1xuICB8ICdJTlNJREVfU1RSSU5HJ1xuICB8ICdJTlNJREVfU1RSSU5HX0VTQ0FQRSdcbiAgfCAnSU5TSURFX0xJVEVSQUwnXG4gIHwgJ0lOU0lERV9OVU1CRVInXG4gIHwgJ0lOU0lERV9PQkpFQ1RfU1RBUlQnXG4gIHwgJ0lOU0lERV9PQkpFQ1RfS0VZJ1xuICB8ICdJTlNJREVfT0JKRUNUX0FGVEVSX0tFWSdcbiAgfCAnSU5TSURFX09CSkVDVF9CRUZPUkVfVkFMVUUnXG4gIHwgJ0lOU0lERV9PQkpFQ1RfQUZURVJfVkFMVUUnXG4gIHwgJ0lOU0lERV9PQkpFQ1RfQUZURVJfQ09NTUEnXG4gIHwgJ0lOU0lERV9BUlJBWV9TVEFSVCdcbiAgfCAnSU5TSURFX0FSUkFZX0FGVEVSX1ZBTFVFJ1xuICB8ICdJTlNJREVfQVJSQVlfQUZURVJfQ09NTUEnO1xuXG4vLyBJbXBsZW1lbnRlZCBhcyBhIHNjYW5uZXIgd2l0aCBhZGRpdGlvbmFsIGZpeGluZ1xuLy8gdGhhdCBwZXJmb3JtcyBhIHNpbmdsZSBsaW5lYXIgdGltZSBzY2FuIHBhc3Mgb3ZlciB0aGUgcGFydGlhbCBKU09OLlxuLy9cbi8vIFRoZSBzdGF0ZXMgc2hvdWxkIGlkZWFsbHkgbWF0Y2ggcmVsZXZhbnQgc3RhdGVzIGZyb20gdGhlIEpTT04gc3BlYzpcbi8vIGh0dHBzOi8vd3d3Lmpzb24ub3JnL2pzb24tZW4uaHRtbFxuLy9cbi8vIFBsZWFzZSBub3RlIHRoYXQgaW52YWxpZCBKU09OIGlzIG5vdCBjb25zaWRlcmVkL2NvdmVyZWQsIGJlY2F1c2UgaXRcbi8vIGlzIGFzc3VtZWQgdGhhdCB0aGUgcmVzdWx0aW5nIEpTT04gd2lsbCBiZSBwcm9jZXNzZWQgYnkgYSBzdGFuZGFyZFxuLy8gSlNPTiBwYXJzZXIgdGhhdCB3aWxsIGRldGVjdCBhbnkgaW52YWxpZCBKU09OLlxuZXhwb3J0IGZ1bmN0aW9uIGZpeEpzb24oaW5wdXQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHN0YWNrOiBTdGF0ZVtdID0gWydST09UJ107XG4gIGxldCBsYXN0VmFsaWRJbmRleCA9IC0xO1xuICBsZXQgbGl0ZXJhbFN0YXJ0OiBudW1iZXIgfCBudWxsID0gbnVsbDtcblxuICBmdW5jdGlvbiBwcm9jZXNzVmFsdWVTdGFydChjaGFyOiBzdHJpbmcsIGk6IG51bWJlciwgc3dhcFN0YXRlOiBTdGF0ZSkge1xuICAgIHtcbiAgICAgIHN3aXRjaCAoY2hhcikge1xuICAgICAgICBjYXNlICdcIic6IHtcbiAgICAgICAgICBsYXN0VmFsaWRJbmRleCA9IGk7XG4gICAgICAgICAgc3RhY2sucG9wKCk7XG4gICAgICAgICAgc3RhY2sucHVzaChzd2FwU3RhdGUpO1xuICAgICAgICAgIHN0YWNrLnB1c2goJ0lOU0lERV9TVFJJTkcnKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGNhc2UgJ2YnOlxuICAgICAgICBjYXNlICd0JzpcbiAgICAgICAgY2FzZSAnbic6IHtcbiAgICAgICAgICBsYXN0VmFsaWRJbmRleCA9IGk7XG4gICAgICAgICAgbGl0ZXJhbFN0YXJ0ID0gaTtcbiAgICAgICAgICBzdGFjay5wb3AoKTtcbiAgICAgICAgICBzdGFjay5wdXNoKHN3YXBTdGF0ZSk7XG4gICAgICAgICAgc3RhY2sucHVzaCgnSU5TSURFX0xJVEVSQUwnKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGNhc2UgJy0nOiB7XG4gICAgICAgICAgc3RhY2sucG9wKCk7XG4gICAgICAgICAgc3RhY2sucHVzaChzd2FwU3RhdGUpO1xuICAgICAgICAgIHN0YWNrLnB1c2goJ0lOU0lERV9OVU1CRVInKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlICcwJzpcbiAgICAgICAgY2FzZSAnMSc6XG4gICAgICAgIGNhc2UgJzInOlxuICAgICAgICBjYXNlICczJzpcbiAgICAgICAgY2FzZSAnNCc6XG4gICAgICAgIGNhc2UgJzUnOlxuICAgICAgICBjYXNlICc2JzpcbiAgICAgICAgY2FzZSAnNyc6XG4gICAgICAgIGNhc2UgJzgnOlxuICAgICAgICBjYXNlICc5Jzoge1xuICAgICAgICAgIGxhc3RWYWxpZEluZGV4ID0gaTtcbiAgICAgICAgICBzdGFjay5wb3AoKTtcbiAgICAgICAgICBzdGFjay5wdXNoKHN3YXBTdGF0ZSk7XG4gICAgICAgICAgc3RhY2sucHVzaCgnSU5TSURFX05VTUJFUicpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgY2FzZSAneyc6IHtcbiAgICAgICAgICBsYXN0VmFsaWRJbmRleCA9IGk7XG4gICAgICAgICAgc3RhY2sucG9wKCk7XG4gICAgICAgICAgc3RhY2sucHVzaChzd2FwU3RhdGUpO1xuICAgICAgICAgIHN0YWNrLnB1c2goJ0lOU0lERV9PQkpFQ1RfU1RBUlQnKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGNhc2UgJ1snOiB7XG4gICAgICAgICAgbGFzdFZhbGlkSW5kZXggPSBpO1xuICAgICAgICAgIHN0YWNrLnBvcCgpO1xuICAgICAgICAgIHN0YWNrLnB1c2goc3dhcFN0YXRlKTtcbiAgICAgICAgICBzdGFjay5wdXNoKCdJTlNJREVfQVJSQVlfU1RBUlQnKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHByb2Nlc3NBZnRlck9iamVjdFZhbHVlKGNoYXI6IHN0cmluZywgaTogbnVtYmVyKSB7XG4gICAgc3dpdGNoIChjaGFyKSB7XG4gICAgICBjYXNlICcsJzoge1xuICAgICAgICBzdGFjay5wb3AoKTtcbiAgICAgICAgc3RhY2sucHVzaCgnSU5TSURFX09CSkVDVF9BRlRFUl9DT01NQScpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ30nOiB7XG4gICAgICAgIGxhc3RWYWxpZEluZGV4ID0gaTtcbiAgICAgICAgc3RhY2sucG9wKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHByb2Nlc3NBZnRlckFycmF5VmFsdWUoY2hhcjogc3RyaW5nLCBpOiBudW1iZXIpIHtcbiAgICBzd2l0Y2ggKGNoYXIpIHtcbiAgICAgIGNhc2UgJywnOiB7XG4gICAgICAgIHN0YWNrLnBvcCgpO1xuICAgICAgICBzdGFjay5wdXNoKCdJTlNJREVfQVJSQVlfQUZURVJfQ09NTUEnKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICddJzoge1xuICAgICAgICBsYXN0VmFsaWRJbmRleCA9IGk7XG4gICAgICAgIHN0YWNrLnBvcCgpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGlucHV0Lmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgY2hhciA9IGlucHV0W2ldO1xuICAgIGNvbnN0IGN1cnJlbnRTdGF0ZSA9IHN0YWNrW3N0YWNrLmxlbmd0aCAtIDFdO1xuXG4gICAgc3dpdGNoIChjdXJyZW50U3RhdGUpIHtcbiAgICAgIGNhc2UgJ1JPT1QnOlxuICAgICAgICBwcm9jZXNzVmFsdWVTdGFydChjaGFyLCBpLCAnRklOSVNIJyk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdJTlNJREVfT0JKRUNUX1NUQVJUJzoge1xuICAgICAgICBzd2l0Y2ggKGNoYXIpIHtcbiAgICAgICAgICBjYXNlICdcIic6IHtcbiAgICAgICAgICAgIHN0YWNrLnBvcCgpO1xuICAgICAgICAgICAgc3RhY2sucHVzaCgnSU5TSURFX09CSkVDVF9LRVknKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlICd9Jzoge1xuICAgICAgICAgICAgbGFzdFZhbGlkSW5kZXggPSBpO1xuICAgICAgICAgICAgc3RhY2sucG9wKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGNhc2UgJ0lOU0lERV9PQkpFQ1RfQUZURVJfQ09NTUEnOiB7XG4gICAgICAgIHN3aXRjaCAoY2hhcikge1xuICAgICAgICAgIGNhc2UgJ1wiJzoge1xuICAgICAgICAgICAgc3RhY2sucG9wKCk7XG4gICAgICAgICAgICBzdGFjay5wdXNoKCdJTlNJREVfT0JKRUNUX0tFWScpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBjYXNlICdJTlNJREVfT0JKRUNUX0tFWSc6IHtcbiAgICAgICAgc3dpdGNoIChjaGFyKSB7XG4gICAgICAgICAgY2FzZSAnXCInOiB7XG4gICAgICAgICAgICBzdGFjay5wb3AoKTtcbiAgICAgICAgICAgIHN0YWNrLnB1c2goJ0lOU0lERV9PQkpFQ1RfQUZURVJfS0VZJyk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGNhc2UgJ0lOU0lERV9PQkpFQ1RfQUZURVJfS0VZJzoge1xuICAgICAgICBzd2l0Y2ggKGNoYXIpIHtcbiAgICAgICAgICBjYXNlICc6Jzoge1xuICAgICAgICAgICAgc3RhY2sucG9wKCk7XG4gICAgICAgICAgICBzdGFjay5wdXNoKCdJTlNJREVfT0JKRUNUX0JFRk9SRV9WQUxVRScpO1xuXG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGNhc2UgJ0lOU0lERV9PQkpFQ1RfQkVGT1JFX1ZBTFVFJzoge1xuICAgICAgICBwcm9jZXNzVmFsdWVTdGFydChjaGFyLCBpLCAnSU5TSURFX09CSkVDVF9BRlRFUl9WQUxVRScpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgY2FzZSAnSU5TSURFX09CSkVDVF9BRlRFUl9WQUxVRSc6IHtcbiAgICAgICAgcHJvY2Vzc0FmdGVyT2JqZWN0VmFsdWUoY2hhciwgaSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBjYXNlICdJTlNJREVfU1RSSU5HJzoge1xuICAgICAgICBzd2l0Y2ggKGNoYXIpIHtcbiAgICAgICAgICBjYXNlICdcIic6IHtcbiAgICAgICAgICAgIHN0YWNrLnBvcCgpO1xuICAgICAgICAgICAgbGFzdFZhbGlkSW5kZXggPSBpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY2FzZSAnXFxcXCc6IHtcbiAgICAgICAgICAgIHN0YWNrLnB1c2goJ0lOU0lERV9TVFJJTkdfRVNDQVBFJyk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICBsYXN0VmFsaWRJbmRleCA9IGk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGNhc2UgJ0lOU0lERV9BUlJBWV9TVEFSVCc6IHtcbiAgICAgICAgc3dpdGNoIChjaGFyKSB7XG4gICAgICAgICAgY2FzZSAnXSc6IHtcbiAgICAgICAgICAgIGxhc3RWYWxpZEluZGV4ID0gaTtcbiAgICAgICAgICAgIHN0YWNrLnBvcCgpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgbGFzdFZhbGlkSW5kZXggPSBpO1xuICAgICAgICAgICAgcHJvY2Vzc1ZhbHVlU3RhcnQoY2hhciwgaSwgJ0lOU0lERV9BUlJBWV9BRlRFUl9WQUxVRScpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBjYXNlICdJTlNJREVfQVJSQVlfQUZURVJfVkFMVUUnOiB7XG4gICAgICAgIHN3aXRjaCAoY2hhcikge1xuICAgICAgICAgIGNhc2UgJywnOiB7XG4gICAgICAgICAgICBzdGFjay5wb3AoKTtcbiAgICAgICAgICAgIHN0YWNrLnB1c2goJ0lOU0lERV9BUlJBWV9BRlRFUl9DT01NQScpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY2FzZSAnXSc6IHtcbiAgICAgICAgICAgIGxhc3RWYWxpZEluZGV4ID0gaTtcbiAgICAgICAgICAgIHN0YWNrLnBvcCgpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgbGFzdFZhbGlkSW5kZXggPSBpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGNhc2UgJ0lOU0lERV9BUlJBWV9BRlRFUl9DT01NQSc6IHtcbiAgICAgICAgcHJvY2Vzc1ZhbHVlU3RhcnQoY2hhciwgaSwgJ0lOU0lERV9BUlJBWV9BRlRFUl9WQUxVRScpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgY2FzZSAnSU5TSURFX1NUUklOR19FU0NBUEUnOiB7XG4gICAgICAgIHN0YWNrLnBvcCgpO1xuICAgICAgICBsYXN0VmFsaWRJbmRleCA9IGk7XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGNhc2UgJ0lOU0lERV9OVU1CRVInOiB7XG4gICAgICAgIHN3aXRjaCAoY2hhcikge1xuICAgICAgICAgIGNhc2UgJzAnOlxuICAgICAgICAgIGNhc2UgJzEnOlxuICAgICAgICAgIGNhc2UgJzInOlxuICAgICAgICAgIGNhc2UgJzMnOlxuICAgICAgICAgIGNhc2UgJzQnOlxuICAgICAgICAgIGNhc2UgJzUnOlxuICAgICAgICAgIGNhc2UgJzYnOlxuICAgICAgICAgIGNhc2UgJzcnOlxuICAgICAgICAgIGNhc2UgJzgnOlxuICAgICAgICAgIGNhc2UgJzknOiB7XG4gICAgICAgICAgICBsYXN0VmFsaWRJbmRleCA9IGk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjYXNlICdlJzpcbiAgICAgICAgICBjYXNlICdFJzpcbiAgICAgICAgICBjYXNlICctJzpcbiAgICAgICAgICBjYXNlICcuJzoge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY2FzZSAnLCc6IHtcbiAgICAgICAgICAgIHN0YWNrLnBvcCgpO1xuXG4gICAgICAgICAgICBpZiAoc3RhY2tbc3RhY2subGVuZ3RoIC0gMV0gPT09ICdJTlNJREVfQVJSQVlfQUZURVJfVkFMVUUnKSB7XG4gICAgICAgICAgICAgIHByb2Nlc3NBZnRlckFycmF5VmFsdWUoY2hhciwgaSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChzdGFja1tzdGFjay5sZW5ndGggLSAxXSA9PT0gJ0lOU0lERV9PQkpFQ1RfQUZURVJfVkFMVUUnKSB7XG4gICAgICAgICAgICAgIHByb2Nlc3NBZnRlck9iamVjdFZhbHVlKGNoYXIsIGkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjYXNlICd9Jzoge1xuICAgICAgICAgICAgc3RhY2sucG9wKCk7XG5cbiAgICAgICAgICAgIGlmIChzdGFja1tzdGFjay5sZW5ndGggLSAxXSA9PT0gJ0lOU0lERV9PQkpFQ1RfQUZURVJfVkFMVUUnKSB7XG4gICAgICAgICAgICAgIHByb2Nlc3NBZnRlck9iamVjdFZhbHVlKGNoYXIsIGkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjYXNlICddJzoge1xuICAgICAgICAgICAgc3RhY2sucG9wKCk7XG5cbiAgICAgICAgICAgIGlmIChzdGFja1tzdGFjay5sZW5ndGggLSAxXSA9PT0gJ0lOU0lERV9BUlJBWV9BRlRFUl9WQUxVRScpIHtcbiAgICAgICAgICAgICAgcHJvY2Vzc0FmdGVyQXJyYXlWYWx1ZShjaGFyLCBpKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgc3RhY2sucG9wKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgY2FzZSAnSU5TSURFX0xJVEVSQUwnOiB7XG4gICAgICAgIGNvbnN0IHBhcnRpYWxMaXRlcmFsID0gaW5wdXQuc3Vic3RyaW5nKGxpdGVyYWxTdGFydCEsIGkgKyAxKTtcblxuICAgICAgICBpZiAoXG4gICAgICAgICAgISdmYWxzZScuc3RhcnRzV2l0aChwYXJ0aWFsTGl0ZXJhbCkgJiZcbiAgICAgICAgICAhJ3RydWUnLnN0YXJ0c1dpdGgocGFydGlhbExpdGVyYWwpICYmXG4gICAgICAgICAgISdudWxsJy5zdGFydHNXaXRoKHBhcnRpYWxMaXRlcmFsKVxuICAgICAgICApIHtcbiAgICAgICAgICBzdGFjay5wb3AoKTtcblxuICAgICAgICAgIGlmIChzdGFja1tzdGFjay5sZW5ndGggLSAxXSA9PT0gJ0lOU0lERV9PQkpFQ1RfQUZURVJfVkFMVUUnKSB7XG4gICAgICAgICAgICBwcm9jZXNzQWZ0ZXJPYmplY3RWYWx1ZShjaGFyLCBpKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHN0YWNrW3N0YWNrLmxlbmd0aCAtIDFdID09PSAnSU5TSURFX0FSUkFZX0FGVEVSX1ZBTFVFJykge1xuICAgICAgICAgICAgcHJvY2Vzc0FmdGVyQXJyYXlWYWx1ZShjaGFyLCBpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbGFzdFZhbGlkSW5kZXggPSBpO1xuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgbGV0IHJlc3VsdCA9IGlucHV0LnNsaWNlKDAsIGxhc3RWYWxpZEluZGV4ICsgMSk7XG5cbiAgZm9yIChsZXQgaSA9IHN0YWNrLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgY29uc3Qgc3RhdGUgPSBzdGFja1tpXTtcblxuICAgIHN3aXRjaCAoc3RhdGUpIHtcbiAgICAgIGNhc2UgJ0lOU0lERV9TVFJJTkcnOiB7XG4gICAgICAgIHJlc3VsdCArPSAnXCInO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgY2FzZSAnSU5TSURFX09CSkVDVF9LRVknOlxuICAgICAgY2FzZSAnSU5TSURFX09CSkVDVF9BRlRFUl9LRVknOlxuICAgICAgY2FzZSAnSU5TSURFX09CSkVDVF9BRlRFUl9DT01NQSc6XG4gICAgICBjYXNlICdJTlNJREVfT0JKRUNUX1NUQVJUJzpcbiAgICAgIGNhc2UgJ0lOU0lERV9PQkpFQ1RfQkVGT1JFX1ZBTFVFJzpcbiAgICAgIGNhc2UgJ0lOU0lERV9PQkpFQ1RfQUZURVJfVkFMVUUnOiB7XG4gICAgICAgIHJlc3VsdCArPSAnfSc7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBjYXNlICdJTlNJREVfQVJSQVlfU1RBUlQnOlxuICAgICAgY2FzZSAnSU5TSURFX0FSUkFZX0FGVEVSX0NPTU1BJzpcbiAgICAgIGNhc2UgJ0lOU0lERV9BUlJBWV9BRlRFUl9WQUxVRSc6IHtcbiAgICAgICAgcmVzdWx0ICs9ICddJztcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGNhc2UgJ0lOU0lERV9MSVRFUkFMJzoge1xuICAgICAgICBjb25zdCBwYXJ0aWFsTGl0ZXJhbCA9IGlucHV0LnN1YnN0cmluZyhsaXRlcmFsU3RhcnQhLCBpbnB1dC5sZW5ndGgpO1xuXG4gICAgICAgIGlmICgndHJ1ZScuc3RhcnRzV2l0aChwYXJ0aWFsTGl0ZXJhbCkpIHtcbiAgICAgICAgICByZXN1bHQgKz0gJ3RydWUnLnNsaWNlKHBhcnRpYWxMaXRlcmFsLmxlbmd0aCk7XG4gICAgICAgIH0gZWxzZSBpZiAoJ2ZhbHNlJy5zdGFydHNXaXRoKHBhcnRpYWxMaXRlcmFsKSkge1xuICAgICAgICAgIHJlc3VsdCArPSAnZmFsc2UnLnNsaWNlKHBhcnRpYWxMaXRlcmFsLmxlbmd0aCk7XG4gICAgICAgIH0gZWxzZSBpZiAoJ251bGwnLnN0YXJ0c1dpdGgocGFydGlhbExpdGVyYWwpKSB7XG4gICAgICAgICAgcmVzdWx0ICs9ICdudWxsJy5zbGljZShwYXJ0aWFsTGl0ZXJhbC5sZW5ndGgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cbiIsICJpbXBvcnQge1xuICBJbmZlclRvb2xJbnB1dCxcbiAgSW5mZXJUb29sT3V0cHV0LFxuICBUb29sLFxuICBUb29sQ2FsbCxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyBUb29sU2V0IH0gZnJvbSAnLi4vZ2VuZXJhdGUtdGV4dCc7XG5pbXBvcnQgeyBQcm92aWRlck1ldGFkYXRhIH0gZnJvbSAnLi4vdHlwZXMvcHJvdmlkZXItbWV0YWRhdGEnO1xuaW1wb3J0IHsgRGVlcFBhcnRpYWwgfSBmcm9tICcuLi91dGlsL2RlZXAtcGFydGlhbCc7XG5pbXBvcnQgeyBWYWx1ZU9mIH0gZnJvbSAnLi4vdXRpbC92YWx1ZS1vZic7XG5cbi8qKlxuVGhlIGRhdGEgdHlwZXMgdGhhdCBjYW4gYmUgdXNlZCBpbiB0aGUgVUkgbWVzc2FnZSBmb3IgdGhlIFVJIG1lc3NhZ2UgZGF0YSBwYXJ0cy5cbiAqL1xuZXhwb3J0IHR5cGUgVUlEYXRhVHlwZXMgPSBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcblxuZXhwb3J0IHR5cGUgVUlUb29sID0ge1xuICBpbnB1dDogdW5rbm93bjtcbiAgb3V0cHV0OiB1bmtub3duIHwgdW5kZWZpbmVkO1xufTtcblxuLyoqXG4gKiBJbmZlciB0aGUgaW5wdXQgYW5kIG91dHB1dCB0eXBlcyBvZiBhIHRvb2wgc28gaXQgY2FuIGJlIHVzZWQgYXMgYSBVSSB0b29sLlxuICovXG5leHBvcnQgdHlwZSBJbmZlclVJVG9vbDxUT09MIGV4dGVuZHMgVG9vbD4gPSB7XG4gIGlucHV0OiBJbmZlclRvb2xJbnB1dDxUT09MPjtcbiAgb3V0cHV0OiBJbmZlclRvb2xPdXRwdXQ8VE9PTD47XG59O1xuXG4vKipcbiAqIEluZmVyIHRoZSBpbnB1dCBhbmQgb3V0cHV0IHR5cGVzIG9mIGEgdG9vbCBzZXQgc28gaXQgY2FuIGJlIHVzZWQgYXMgYSBVSSB0b29sIHNldC5cbiAqL1xuZXhwb3J0IHR5cGUgSW5mZXJVSVRvb2xzPFRPT0xTIGV4dGVuZHMgVG9vbFNldD4gPSB7XG4gIFtOQU1FIGluIGtleW9mIFRPT0xTICYgc3RyaW5nXTogSW5mZXJVSVRvb2w8VE9PTFNbTkFNRV0+O1xufTtcblxuZXhwb3J0IHR5cGUgVUlUb29scyA9IFJlY29yZDxzdHJpbmcsIFVJVG9vbD47XG5cbi8qKlxuQUkgU0RLIFVJIE1lc3NhZ2VzLiBUaGV5IGFyZSB1c2VkIGluIHRoZSBjbGllbnQgYW5kIHRvIGNvbW11bmljYXRlIGJldHdlZW4gdGhlIGZyb250ZW5kIGFuZCB0aGUgQVBJIHJvdXRlcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBVSU1lc3NhZ2U8XG4gIE1FVEFEQVRBID0gdW5rbm93bixcbiAgREFUQV9QQVJUUyBleHRlbmRzIFVJRGF0YVR5cGVzID0gVUlEYXRhVHlwZXMsXG4gIFRPT0xTIGV4dGVuZHMgVUlUb29scyA9IFVJVG9vbHMsXG4+IHtcbiAgLyoqXG5BIHVuaXF1ZSBpZGVudGlmaWVyIGZvciB0aGUgbWVzc2FnZS5cbiAgICovXG4gIGlkOiBzdHJpbmc7XG5cbiAgLyoqXG5UaGUgcm9sZSBvZiB0aGUgbWVzc2FnZS5cbiAgICovXG4gIHJvbGU6ICdzeXN0ZW0nIHwgJ3VzZXInIHwgJ2Fzc2lzdGFudCc7XG5cbiAgLyoqXG5UaGUgbWV0YWRhdGEgb2YgdGhlIG1lc3NhZ2UuXG4gICAqL1xuICBtZXRhZGF0YT86IE1FVEFEQVRBO1xuXG4gIC8qKlxuVGhlIHBhcnRzIG9mIHRoZSBtZXNzYWdlLiBVc2UgdGhpcyBmb3IgcmVuZGVyaW5nIHRoZSBtZXNzYWdlIGluIHRoZSBVSS5cblxuU3lzdGVtIG1lc3NhZ2VzIHNob3VsZCBiZSBhdm9pZGVkIChzZXQgdGhlIHN5c3RlbSBwcm9tcHQgb24gdGhlIHNlcnZlciBpbnN0ZWFkKS5cblRoZXkgY2FuIGhhdmUgdGV4dCBwYXJ0cy5cblxuVXNlciBtZXNzYWdlcyBjYW4gaGF2ZSB0ZXh0IHBhcnRzIGFuZCBmaWxlIHBhcnRzLlxuXG5Bc3Npc3RhbnQgbWVzc2FnZXMgY2FuIGhhdmUgdGV4dCwgcmVhc29uaW5nLCB0b29sIGludm9jYXRpb24sIGFuZCBmaWxlIHBhcnRzLlxuICAgKi9cbiAgcGFydHM6IEFycmF5PFVJTWVzc2FnZVBhcnQ8REFUQV9QQVJUUywgVE9PTFM+Pjtcbn1cblxuZXhwb3J0IHR5cGUgVUlNZXNzYWdlUGFydDxcbiAgREFUQV9UWVBFUyBleHRlbmRzIFVJRGF0YVR5cGVzLFxuICBUT09MUyBleHRlbmRzIFVJVG9vbHMsXG4+ID1cbiAgfCBUZXh0VUlQYXJ0XG4gIHwgUmVhc29uaW5nVUlQYXJ0XG4gIHwgVG9vbFVJUGFydDxUT09MUz5cbiAgfCBEeW5hbWljVG9vbFVJUGFydFxuICB8IFNvdXJjZVVybFVJUGFydFxuICB8IFNvdXJjZURvY3VtZW50VUlQYXJ0XG4gIHwgRmlsZVVJUGFydFxuICB8IERhdGFVSVBhcnQ8REFUQV9UWVBFUz5cbiAgfCBTdGVwU3RhcnRVSVBhcnQ7XG5cbi8qKlxuICogQSB0ZXh0IHBhcnQgb2YgYSBtZXNzYWdlLlxuICovXG5leHBvcnQgdHlwZSBUZXh0VUlQYXJ0ID0ge1xuICB0eXBlOiAndGV4dCc7XG5cbiAgLyoqXG4gICAqIFRoZSB0ZXh0IGNvbnRlbnQuXG4gICAqL1xuICB0ZXh0OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBzdGF0ZSBvZiB0aGUgdGV4dCBwYXJ0LlxuICAgKi9cbiAgc3RhdGU/OiAnc3RyZWFtaW5nJyB8ICdkb25lJztcblxuICAvKipcbiAgICogVGhlIHByb3ZpZGVyIG1ldGFkYXRhLlxuICAgKi9cbiAgcHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG59O1xuXG4vKipcbiAqIEEgcmVhc29uaW5nIHBhcnQgb2YgYSBtZXNzYWdlLlxuICovXG5leHBvcnQgdHlwZSBSZWFzb25pbmdVSVBhcnQgPSB7XG4gIHR5cGU6ICdyZWFzb25pbmcnO1xuXG4gIC8qKlxuICAgKiBUaGUgcmVhc29uaW5nIHRleHQuXG4gICAqL1xuICB0ZXh0OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBzdGF0ZSBvZiB0aGUgcmVhc29uaW5nIHBhcnQuXG4gICAqL1xuICBzdGF0ZT86ICdzdHJlYW1pbmcnIHwgJ2RvbmUnO1xuXG4gIC8qKlxuICAgKiBUaGUgcHJvdmlkZXIgbWV0YWRhdGEuXG4gICAqL1xuICBwcm92aWRlck1ldGFkYXRhPzogUHJvdmlkZXJNZXRhZGF0YTtcbn07XG5cbi8qKlxuICogQSBzb3VyY2UgcGFydCBvZiBhIG1lc3NhZ2UuXG4gKi9cbmV4cG9ydCB0eXBlIFNvdXJjZVVybFVJUGFydCA9IHtcbiAgdHlwZTogJ3NvdXJjZS11cmwnO1xuICBzb3VyY2VJZDogc3RyaW5nO1xuICB1cmw6IHN0cmluZztcbiAgdGl0bGU/OiBzdHJpbmc7XG4gIHByb3ZpZGVyTWV0YWRhdGE/OiBQcm92aWRlck1ldGFkYXRhO1xufTtcblxuLyoqXG4gKiBBIGRvY3VtZW50IHNvdXJjZSBwYXJ0IG9mIGEgbWVzc2FnZS5cbiAqL1xuZXhwb3J0IHR5cGUgU291cmNlRG9jdW1lbnRVSVBhcnQgPSB7XG4gIHR5cGU6ICdzb3VyY2UtZG9jdW1lbnQnO1xuICBzb3VyY2VJZDogc3RyaW5nO1xuICBtZWRpYVR5cGU6IHN0cmluZztcbiAgdGl0bGU6IHN0cmluZztcbiAgZmlsZW5hbWU/OiBzdHJpbmc7XG4gIHByb3ZpZGVyTWV0YWRhdGE/OiBQcm92aWRlck1ldGFkYXRhO1xufTtcblxuLyoqXG4gKiBBIGZpbGUgcGFydCBvZiBhIG1lc3NhZ2UuXG4gKi9cbmV4cG9ydCB0eXBlIEZpbGVVSVBhcnQgPSB7XG4gIHR5cGU6ICdmaWxlJztcblxuICAvKipcbiAgICogSUFOQSBtZWRpYSB0eXBlIG9mIHRoZSBmaWxlLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vd3d3LmlhbmEub3JnL2Fzc2lnbm1lbnRzL21lZGlhLXR5cGVzL21lZGlhLXR5cGVzLnhodG1sXG4gICAqL1xuICBtZWRpYVR5cGU6IHN0cmluZztcblxuICAvKipcbiAgICogT3B0aW9uYWwgZmlsZW5hbWUgb2YgdGhlIGZpbGUuXG4gICAqL1xuICBmaWxlbmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIFVSTCBvZiB0aGUgZmlsZS5cbiAgICogSXQgY2FuIGVpdGhlciBiZSBhIFVSTCB0byBhIGhvc3RlZCBmaWxlIG9yIGEgW0RhdGEgVVJMXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVFRQL0Jhc2ljc19vZl9IVFRQL0RhdGFfVVJMcykuXG4gICAqL1xuICB1cmw6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHByb3ZpZGVyIG1ldGFkYXRhLlxuICAgKi9cbiAgcHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG59O1xuXG4vKipcbiAqIEEgc3RlcCBib3VuZGFyeSBwYXJ0IG9mIGEgbWVzc2FnZS5cbiAqL1xuZXhwb3J0IHR5cGUgU3RlcFN0YXJ0VUlQYXJ0ID0ge1xuICB0eXBlOiAnc3RlcC1zdGFydCc7XG59O1xuXG5leHBvcnQgdHlwZSBEYXRhVUlQYXJ0PERBVEFfVFlQRVMgZXh0ZW5kcyBVSURhdGFUeXBlcz4gPSBWYWx1ZU9mPHtcbiAgW05BTUUgaW4ga2V5b2YgREFUQV9UWVBFUyAmIHN0cmluZ106IHtcbiAgICB0eXBlOiBgZGF0YS0ke05BTUV9YDtcbiAgICBpZD86IHN0cmluZztcbiAgICBkYXRhOiBEQVRBX1RZUEVTW05BTUVdO1xuICB9O1xufT47XG5cbnR5cGUgYXNVSVRvb2w8VE9PTCBleHRlbmRzIFVJVG9vbCB8IFRvb2w+ID0gVE9PTCBleHRlbmRzIFRvb2xcbiAgPyBJbmZlclVJVG9vbDxUT09MPlxuICA6IFRPT0w7XG5cbi8qKlxuICogQ2hlY2sgaWYgYSBtZXNzYWdlIHBhcnQgaXMgYSBkYXRhIHBhcnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0RhdGFVSVBhcnQ8REFUQV9UWVBFUyBleHRlbmRzIFVJRGF0YVR5cGVzPihcbiAgcGFydDogVUlNZXNzYWdlUGFydDxEQVRBX1RZUEVTLCBVSVRvb2xzPixcbik6IHBhcnQgaXMgRGF0YVVJUGFydDxEQVRBX1RZUEVTPiB7XG4gIHJldHVybiBwYXJ0LnR5cGUuc3RhcnRzV2l0aCgnZGF0YS0nKTtcbn1cblxuLyoqXG4gKiBBIFVJIHRvb2wgaW52b2NhdGlvbiBjb250YWlucyBhbGwgdGhlIGluZm9ybWF0aW9uIG5lZWRlZCB0byByZW5kZXIgYSB0b29sIGludm9jYXRpb24gaW4gdGhlIFVJLlxuICogSXQgY2FuIGJlIGRlcml2ZWQgZnJvbSBhIHRvb2wgd2l0aG91dCBrbm93aW5nIHRoZSB0b29sIG5hbWUsIGFuZCBjYW4gYmUgdXNlZCB0byBkZWZpbmVcbiAqIFVJIGNvbXBvbmVudHMgZm9yIHRoZSB0b29sLlxuICovXG5leHBvcnQgdHlwZSBVSVRvb2xJbnZvY2F0aW9uPFRPT0wgZXh0ZW5kcyBVSVRvb2wgfCBUb29sPiA9IHtcbiAgdG9vbENhbGxJZDogc3RyaW5nO1xufSAmIChcbiAgfCB7XG4gICAgICBzdGF0ZTogJ2lucHV0LXN0cmVhbWluZyc7XG4gICAgICBpbnB1dDogRGVlcFBhcnRpYWw8YXNVSVRvb2w8VE9PTD5bJ2lucHV0J10+IHwgdW5kZWZpbmVkO1xuICAgICAgcHJvdmlkZXJFeGVjdXRlZD86IGJvb2xlYW47XG4gICAgICBvdXRwdXQ/OiBuZXZlcjtcbiAgICAgIGVycm9yVGV4dD86IG5ldmVyO1xuICAgIH1cbiAgfCB7XG4gICAgICBzdGF0ZTogJ2lucHV0LWF2YWlsYWJsZSc7XG4gICAgICBpbnB1dDogYXNVSVRvb2w8VE9PTD5bJ2lucHV0J107XG4gICAgICBwcm92aWRlckV4ZWN1dGVkPzogYm9vbGVhbjtcbiAgICAgIG91dHB1dD86IG5ldmVyO1xuICAgICAgZXJyb3JUZXh0PzogbmV2ZXI7XG4gICAgICBjYWxsUHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG4gICAgfVxuICB8IHtcbiAgICAgIHN0YXRlOiAnb3V0cHV0LWF2YWlsYWJsZSc7XG4gICAgICBpbnB1dDogYXNVSVRvb2w8VE9PTD5bJ2lucHV0J107XG4gICAgICBvdXRwdXQ6IGFzVUlUb29sPFRPT0w+WydvdXRwdXQnXTtcbiAgICAgIGVycm9yVGV4dD86IG5ldmVyO1xuICAgICAgcHJvdmlkZXJFeGVjdXRlZD86IGJvb2xlYW47XG4gICAgICBjYWxsUHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG4gICAgICBwcmVsaW1pbmFyeT86IGJvb2xlYW47XG4gICAgfVxuICB8IHtcbiAgICAgIHN0YXRlOiAnb3V0cHV0LWVycm9yJzsgLy8gVE9ETyBBSSBTREsgNjogY2hhbmdlIHRvICdlcnJvcicgc3RhdGVcbiAgICAgIGlucHV0OiBhc1VJVG9vbDxUT09MPlsnaW5wdXQnXSB8IHVuZGVmaW5lZDtcbiAgICAgIHJhd0lucHV0PzogdW5rbm93bjsgLy8gVE9ETyBBSSBTREsgNjogcmVtb3ZlIHRoaXMgZmllbGQsIGlucHV0IHNob3VsZCBiZSB1bmtub3duXG4gICAgICBvdXRwdXQ/OiBuZXZlcjtcbiAgICAgIGVycm9yVGV4dDogc3RyaW5nO1xuICAgICAgcHJvdmlkZXJFeGVjdXRlZD86IGJvb2xlYW47XG4gICAgICBjYWxsUHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG4gICAgfVxuKTtcblxuZXhwb3J0IHR5cGUgVG9vbFVJUGFydDxUT09MUyBleHRlbmRzIFVJVG9vbHMgPSBVSVRvb2xzPiA9IFZhbHVlT2Y8e1xuICBbTkFNRSBpbiBrZXlvZiBUT09MUyAmIHN0cmluZ106IHtcbiAgICB0eXBlOiBgdG9vbC0ke05BTUV9YDtcbiAgfSAmIFVJVG9vbEludm9jYXRpb248VE9PTFNbTkFNRV0+O1xufT47XG5cbmV4cG9ydCB0eXBlIER5bmFtaWNUb29sVUlQYXJ0ID0ge1xuICB0eXBlOiAnZHluYW1pYy10b29sJztcbiAgdG9vbE5hbWU6IHN0cmluZztcbiAgdG9vbENhbGxJZDogc3RyaW5nO1xufSAmIChcbiAgfCB7XG4gICAgICBzdGF0ZTogJ2lucHV0LXN0cmVhbWluZyc7XG4gICAgICBpbnB1dDogdW5rbm93biB8IHVuZGVmaW5lZDtcbiAgICAgIG91dHB1dD86IG5ldmVyO1xuICAgICAgZXJyb3JUZXh0PzogbmV2ZXI7XG4gICAgfVxuICB8IHtcbiAgICAgIHN0YXRlOiAnaW5wdXQtYXZhaWxhYmxlJztcbiAgICAgIGlucHV0OiB1bmtub3duO1xuICAgICAgb3V0cHV0PzogbmV2ZXI7XG4gICAgICBlcnJvclRleHQ/OiBuZXZlcjtcbiAgICAgIGNhbGxQcm92aWRlck1ldGFkYXRhPzogUHJvdmlkZXJNZXRhZGF0YTtcbiAgICB9XG4gIHwge1xuICAgICAgc3RhdGU6ICdvdXRwdXQtYXZhaWxhYmxlJztcbiAgICAgIGlucHV0OiB1bmtub3duO1xuICAgICAgb3V0cHV0OiB1bmtub3duO1xuICAgICAgZXJyb3JUZXh0PzogbmV2ZXI7XG4gICAgICBjYWxsUHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG4gICAgICBwcmVsaW1pbmFyeT86IGJvb2xlYW47XG4gICAgfVxuICB8IHtcbiAgICAgIHN0YXRlOiAnb3V0cHV0LWVycm9yJzsgLy8gVE9ETyBBSSBTREsgNjogY2hhbmdlIHRvICdlcnJvcicgc3RhdGVcbiAgICAgIGlucHV0OiB1bmtub3duO1xuICAgICAgb3V0cHV0PzogbmV2ZXI7XG4gICAgICBlcnJvclRleHQ6IHN0cmluZztcbiAgICAgIGNhbGxQcm92aWRlck1ldGFkYXRhPzogUHJvdmlkZXJNZXRhZGF0YTtcbiAgICB9XG4pO1xuXG5leHBvcnQgZnVuY3Rpb24gaXNUb29sVUlQYXJ0PFRPT0xTIGV4dGVuZHMgVUlUb29scz4oXG4gIHBhcnQ6IFVJTWVzc2FnZVBhcnQ8VUlEYXRhVHlwZXMsIFRPT0xTPixcbik6IHBhcnQgaXMgVG9vbFVJUGFydDxUT09MUz4ge1xuICByZXR1cm4gcGFydC50eXBlLnN0YXJ0c1dpdGgoJ3Rvb2wtJyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0R5bmFtaWNUb29sVUlQYXJ0KFxuICBwYXJ0OiBVSU1lc3NhZ2VQYXJ0PFVJRGF0YVR5cGVzLCBVSVRvb2xzPixcbik6IHBhcnQgaXMgRHluYW1pY1Rvb2xVSVBhcnQge1xuICByZXR1cm4gcGFydC50eXBlID09PSAnZHluYW1pYy10b29sJztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzVG9vbE9yRHluYW1pY1Rvb2xVSVBhcnQ8VE9PTFMgZXh0ZW5kcyBVSVRvb2xzPihcbiAgcGFydDogVUlNZXNzYWdlUGFydDxVSURhdGFUeXBlcywgVE9PTFM+LFxuKTogcGFydCBpcyBUb29sVUlQYXJ0PFRPT0xTPiB8IER5bmFtaWNUb29sVUlQYXJ0IHtcbiAgcmV0dXJuIGlzVG9vbFVJUGFydChwYXJ0KSB8fCBpc0R5bmFtaWNUb29sVUlQYXJ0KHBhcnQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VG9vbE5hbWU8VE9PTFMgZXh0ZW5kcyBVSVRvb2xzPihcbiAgcGFydDogVG9vbFVJUGFydDxUT09MUz4sXG4pOiBrZXlvZiBUT09MUyB7XG4gIHJldHVybiBwYXJ0LnR5cGUuc3BsaXQoJy0nKS5zbGljZSgxKS5qb2luKCctJykgYXMga2V5b2YgVE9PTFM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRUb29sT3JEeW5hbWljVG9vbE5hbWUoXG4gIHBhcnQ6IFRvb2xVSVBhcnQ8VUlUb29scz4gfCBEeW5hbWljVG9vbFVJUGFydCxcbik6IHN0cmluZyB7XG4gIHJldHVybiBpc0R5bmFtaWNUb29sVUlQYXJ0KHBhcnQpID8gcGFydC50b29sTmFtZSA6IGdldFRvb2xOYW1lKHBhcnQpO1xufVxuXG5leHBvcnQgdHlwZSBJbmZlclVJTWVzc2FnZU1ldGFkYXRhPFQgZXh0ZW5kcyBVSU1lc3NhZ2U+ID1cbiAgVCBleHRlbmRzIFVJTWVzc2FnZTxpbmZlciBNRVRBREFUQT4gPyBNRVRBREFUQSA6IHVua25vd247XG5cbmV4cG9ydCB0eXBlIEluZmVyVUlNZXNzYWdlRGF0YTxUIGV4dGVuZHMgVUlNZXNzYWdlPiA9XG4gIFQgZXh0ZW5kcyBVSU1lc3NhZ2U8dW5rbm93biwgaW5mZXIgREFUQV9UWVBFUz4gPyBEQVRBX1RZUEVTIDogVUlEYXRhVHlwZXM7XG5cbmV4cG9ydCB0eXBlIEluZmVyVUlNZXNzYWdlVG9vbHM8VCBleHRlbmRzIFVJTWVzc2FnZT4gPVxuICBUIGV4dGVuZHMgVUlNZXNzYWdlPHVua25vd24sIFVJRGF0YVR5cGVzLCBpbmZlciBUT09MUz4gPyBUT09MUyA6IFVJVG9vbHM7XG5cbmV4cG9ydCB0eXBlIEluZmVyVUlNZXNzYWdlVG9vbE91dHB1dHM8VUlfTUVTU0FHRSBleHRlbmRzIFVJTWVzc2FnZT4gPVxuICBJbmZlclVJTWVzc2FnZVRvb2xzPFVJX01FU1NBR0U+W2tleW9mIEluZmVyVUlNZXNzYWdlVG9vbHM8VUlfTUVTU0FHRT5dWydvdXRwdXQnXTtcblxuZXhwb3J0IHR5cGUgSW5mZXJVSU1lc3NhZ2VUb29sQ2FsbDxVSV9NRVNTQUdFIGV4dGVuZHMgVUlNZXNzYWdlPiA9XG4gIHwgVmFsdWVPZjx7XG4gICAgICBbTkFNRSBpbiBrZXlvZiBJbmZlclVJTWVzc2FnZVRvb2xzPFVJX01FU1NBR0U+XTogVG9vbENhbGw8XG4gICAgICAgIE5BTUUgJiBzdHJpbmcsXG4gICAgICAgIEluZmVyVUlNZXNzYWdlVG9vbHM8VUlfTUVTU0FHRT5bTkFNRV0gZXh0ZW5kcyB7IGlucHV0OiBpbmZlciBJTlBVVCB9XG4gICAgICAgICAgPyBJTlBVVFxuICAgICAgICAgIDogbmV2ZXJcbiAgICAgID4gJiB7IGR5bmFtaWM/OiBmYWxzZSB9O1xuICAgIH0+XG4gIHwgKFRvb2xDYWxsPHN0cmluZywgdW5rbm93bj4gJiB7IGR5bmFtaWM6IHRydWUgfSk7XG4iLCAiaW1wb3J0IHtcbiAgY3JlYXRlU3RyZWFtaW5nVUlNZXNzYWdlU3RhdGUsXG4gIHByb2Nlc3NVSU1lc3NhZ2VTdHJlYW0sXG4gIFN0cmVhbWluZ1VJTWVzc2FnZVN0YXRlLFxufSBmcm9tICcuLi91aS9wcm9jZXNzLXVpLW1lc3NhZ2Utc3RyZWFtJztcbmltcG9ydCB7IFVJTWVzc2FnZSB9IGZyb20gJy4uL3VpL3VpLW1lc3NhZ2VzJztcbmltcG9ydCB7IEVycm9ySGFuZGxlciB9IGZyb20gJy4uL3V0aWwvZXJyb3ItaGFuZGxlcic7XG5pbXBvcnQgeyBJbmZlclVJTWVzc2FnZUNodW5rLCBVSU1lc3NhZ2VDaHVuayB9IGZyb20gJy4vdWktbWVzc2FnZS1jaHVua3MnO1xuaW1wb3J0IHsgVUlNZXNzYWdlU3RyZWFtT25GaW5pc2hDYWxsYmFjayB9IGZyb20gJy4vdWktbWVzc2FnZS1zdHJlYW0tb24tZmluaXNoLWNhbGxiYWNrJztcblxuZXhwb3J0IGZ1bmN0aW9uIGhhbmRsZVVJTWVzc2FnZVN0cmVhbUZpbmlzaDxVSV9NRVNTQUdFIGV4dGVuZHMgVUlNZXNzYWdlPih7XG4gIG1lc3NhZ2VJZCxcbiAgb3JpZ2luYWxNZXNzYWdlcyA9IFtdLFxuICBvbkZpbmlzaCxcbiAgb25FcnJvcixcbiAgc3RyZWFtLFxufToge1xuICBzdHJlYW06IFJlYWRhYmxlU3RyZWFtPEluZmVyVUlNZXNzYWdlQ2h1bms8VUlfTUVTU0FHRT4+O1xuXG4gIC8qKlxuICAgKiBUaGUgbWVzc2FnZSBJRCB0byB1c2UgZm9yIHRoZSByZXNwb25zZSBtZXNzYWdlLlxuICAgKiBJZiBub3QgcHJvdmlkZWQsIG5vIGlkIHdpbGwgYmUgc2V0IGZvciB0aGUgcmVzcG9uc2UgbWVzc2FnZS5cbiAgICovXG4gIG1lc3NhZ2VJZD86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIG9yaWdpbmFsIG1lc3NhZ2VzLlxuICAgKi9cbiAgb3JpZ2luYWxNZXNzYWdlcz86IFVJX01FU1NBR0VbXTtcblxuICBvbkVycm9yOiBFcnJvckhhbmRsZXI7XG5cbiAgb25GaW5pc2g/OiBVSU1lc3NhZ2VTdHJlYW1PbkZpbmlzaENhbGxiYWNrPFVJX01FU1NBR0U+O1xufSk6IFJlYWRhYmxlU3RyZWFtPEluZmVyVUlNZXNzYWdlQ2h1bms8VUlfTUVTU0FHRT4+IHtcbiAgLy8gbGFzdCBtZXNzYWdlIGlzIG9ubHkgcmVsZXZhbnQgZm9yIGFzc2lzdGFudCBtZXNzYWdlc1xuICBsZXQgbGFzdE1lc3NhZ2U6IFVJX01FU1NBR0UgfCB1bmRlZmluZWQgPVxuICAgIG9yaWdpbmFsTWVzc2FnZXM/LltvcmlnaW5hbE1lc3NhZ2VzLmxlbmd0aCAtIDFdO1xuICBpZiAobGFzdE1lc3NhZ2U/LnJvbGUgIT09ICdhc3Npc3RhbnQnKSB7XG4gICAgbGFzdE1lc3NhZ2UgPSB1bmRlZmluZWQ7XG4gIH0gZWxzZSB7XG4gICAgLy8gYXBwZW5kaW5nIHRvIHRoZSBsYXN0IG1lc3NhZ2UsIHNvIHdlIG5lZWQgdG8gdXNlIHRoZSBzYW1lIGlkXG4gICAgbWVzc2FnZUlkID0gbGFzdE1lc3NhZ2UuaWQ7XG4gIH1cblxuICBsZXQgaXNBYm9ydGVkID0gZmFsc2U7XG5cbiAgY29uc3QgaWRJbmplY3RlZFN0cmVhbSA9IHN0cmVhbS5waXBlVGhyb3VnaChcbiAgICBuZXcgVHJhbnNmb3JtU3RyZWFtPFxuICAgICAgSW5mZXJVSU1lc3NhZ2VDaHVuazxVSV9NRVNTQUdFPixcbiAgICAgIEluZmVyVUlNZXNzYWdlQ2h1bms8VUlfTUVTU0FHRT5cbiAgICA+KHtcbiAgICAgIHRyYW5zZm9ybShjaHVuaywgY29udHJvbGxlcikge1xuICAgICAgICAvLyB3aGVuIHRoZXJlIGlzIG5vIG1lc3NhZ2VJZCBpbiB0aGUgc3RhcnQgY2h1bmssXG4gICAgICAgIC8vIGJ1dCB0aGUgdXNlciBjaGVja2VkIGZvciBwZXJzaXN0ZW5jZSxcbiAgICAgICAgLy8gaW5qZWN0IHRoZSBtZXNzYWdlSWQgaW50byB0aGUgY2h1bmtcbiAgICAgICAgaWYgKGNodW5rLnR5cGUgPT09ICdzdGFydCcpIHtcbiAgICAgICAgICBjb25zdCBzdGFydENodW5rID0gY2h1bmsgYXMgVUlNZXNzYWdlQ2h1bmsgJiB7IHR5cGU6ICdzdGFydCcgfTtcbiAgICAgICAgICBpZiAoc3RhcnRDaHVuay5tZXNzYWdlSWQgPT0gbnVsbCAmJiBtZXNzYWdlSWQgIT0gbnVsbCkge1xuICAgICAgICAgICAgc3RhcnRDaHVuay5tZXNzYWdlSWQgPSBtZXNzYWdlSWQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNodW5rLnR5cGUgPT09ICdhYm9ydCcpIHtcbiAgICAgICAgICBpc0Fib3J0ZWQgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKGNodW5rKTtcbiAgICAgIH0sXG4gICAgfSksXG4gICk7XG5cbiAgaWYgKG9uRmluaXNoID09IG51bGwpIHtcbiAgICByZXR1cm4gaWRJbmplY3RlZFN0cmVhbTtcbiAgfVxuXG4gIGNvbnN0IHN0YXRlID0gY3JlYXRlU3RyZWFtaW5nVUlNZXNzYWdlU3RhdGU8VUlfTUVTU0FHRT4oe1xuICAgIGxhc3RNZXNzYWdlOiBsYXN0TWVzc2FnZVxuICAgICAgPyAoc3RydWN0dXJlZENsb25lKGxhc3RNZXNzYWdlKSBhcyBVSV9NRVNTQUdFKVxuICAgICAgOiB1bmRlZmluZWQsXG4gICAgbWVzc2FnZUlkOiBtZXNzYWdlSWQgPz8gJycsIC8vIHdpbGwgYmUgb3ZlcnJpZGRlbiBieSB0aGUgc3RyZWFtXG4gIH0pO1xuXG4gIGNvbnN0IHJ1blVwZGF0ZU1lc3NhZ2VKb2IgPSBhc3luYyAoXG4gICAgam9iOiAob3B0aW9uczoge1xuICAgICAgc3RhdGU6IFN0cmVhbWluZ1VJTWVzc2FnZVN0YXRlPFVJX01FU1NBR0U+O1xuICAgICAgd3JpdGU6ICgpID0+IHZvaWQ7XG4gICAgfSkgPT4gUHJvbWlzZTx2b2lkPixcbiAgKSA9PiB7XG4gICAgYXdhaXQgam9iKHsgc3RhdGUsIHdyaXRlOiAoKSA9PiB7fSB9KTtcbiAgfTtcblxuICBsZXQgZmluaXNoQ2FsbGVkID0gZmFsc2U7XG5cbiAgY29uc3QgY2FsbE9uRmluaXNoID0gYXN5bmMgKCkgPT4ge1xuICAgIGlmIChmaW5pc2hDYWxsZWQgfHwgIW9uRmluaXNoKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGZpbmlzaENhbGxlZCA9IHRydWU7XG5cbiAgICBjb25zdCBpc0NvbnRpbnVhdGlvbiA9IHN0YXRlLm1lc3NhZ2UuaWQgPT09IGxhc3RNZXNzYWdlPy5pZDtcbiAgICBhd2FpdCBvbkZpbmlzaCh7XG4gICAgICBpc0Fib3J0ZWQsXG4gICAgICBpc0NvbnRpbnVhdGlvbixcbiAgICAgIHJlc3BvbnNlTWVzc2FnZTogc3RhdGUubWVzc2FnZSBhcyBVSV9NRVNTQUdFLFxuICAgICAgbWVzc2FnZXM6IFtcbiAgICAgICAgLi4uKGlzQ29udGludWF0aW9uID8gb3JpZ2luYWxNZXNzYWdlcy5zbGljZSgwLCAtMSkgOiBvcmlnaW5hbE1lc3NhZ2VzKSxcbiAgICAgICAgc3RhdGUubWVzc2FnZSxcbiAgICAgIF0gYXMgVUlfTUVTU0FHRVtdLFxuICAgIH0pO1xuICB9O1xuXG4gIHJldHVybiBwcm9jZXNzVUlNZXNzYWdlU3RyZWFtPFVJX01FU1NBR0U+KHtcbiAgICBzdHJlYW06IGlkSW5qZWN0ZWRTdHJlYW0sXG4gICAgcnVuVXBkYXRlTWVzc2FnZUpvYixcbiAgICBvbkVycm9yLFxuICB9KS5waXBlVGhyb3VnaChcbiAgICBuZXcgVHJhbnNmb3JtU3RyZWFtPFxuICAgICAgSW5mZXJVSU1lc3NhZ2VDaHVuazxVSV9NRVNTQUdFPixcbiAgICAgIEluZmVyVUlNZXNzYWdlQ2h1bms8VUlfTUVTU0FHRT5cbiAgICA+KHtcbiAgICAgIHRyYW5zZm9ybShjaHVuaywgY29udHJvbGxlcikge1xuICAgICAgICBjb250cm9sbGVyLmVucXVldWUoY2h1bmspO1xuICAgICAgfSxcbiAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgY2FuY2VsIGlzIHN0aWxsIG5ldyBhbmQgbWlzc2luZyBmcm9tIHR5cGVzIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9UcmFuc2Zvcm1TdHJlYW0jYnJvd3Nlcl9jb21wYXRpYmlsaXR5XG4gICAgICBhc3luYyBjYW5jZWwoKSB7XG4gICAgICAgIGF3YWl0IGNhbGxPbkZpbmlzaCgpO1xuICAgICAgfSxcblxuICAgICAgYXN5bmMgZmx1c2goKSB7XG4gICAgICAgIGF3YWl0IGNhbGxPbkZpbmlzaCgpO1xuICAgICAgfSxcbiAgICB9KSxcbiAgKTtcbn1cbiIsICJpbXBvcnQgeyBTZXJ2ZXJSZXNwb25zZSB9IGZyb20gJ25vZGU6aHR0cCc7XG5pbXBvcnQgeyBwcmVwYXJlSGVhZGVycyB9IGZyb20gJy4uL3V0aWwvcHJlcGFyZS1oZWFkZXJzJztcbmltcG9ydCB7IHdyaXRlVG9TZXJ2ZXJSZXNwb25zZSB9IGZyb20gJy4uL3V0aWwvd3JpdGUtdG8tc2VydmVyLXJlc3BvbnNlJztcbmltcG9ydCB7IEpzb25Ub1NzZVRyYW5zZm9ybVN0cmVhbSB9IGZyb20gJy4vanNvbi10by1zc2UtdHJhbnNmb3JtLXN0cmVhbSc7XG5pbXBvcnQgeyBVSV9NRVNTQUdFX1NUUkVBTV9IRUFERVJTIH0gZnJvbSAnLi91aS1tZXNzYWdlLXN0cmVhbS1oZWFkZXJzJztcbmltcG9ydCB7IFVJTWVzc2FnZUNodW5rIH0gZnJvbSAnLi91aS1tZXNzYWdlLWNodW5rcyc7XG5pbXBvcnQgeyBVSU1lc3NhZ2VTdHJlYW1SZXNwb25zZUluaXQgfSBmcm9tICcuL3VpLW1lc3NhZ2Utc3RyZWFtLXJlc3BvbnNlLWluaXQnO1xuXG5leHBvcnQgZnVuY3Rpb24gcGlwZVVJTWVzc2FnZVN0cmVhbVRvUmVzcG9uc2Uoe1xuICByZXNwb25zZSxcbiAgc3RhdHVzLFxuICBzdGF0dXNUZXh0LFxuICBoZWFkZXJzLFxuICBzdHJlYW0sXG4gIGNvbnN1bWVTc2VTdHJlYW0sXG59OiB7XG4gIHJlc3BvbnNlOiBTZXJ2ZXJSZXNwb25zZTtcbiAgc3RyZWFtOiBSZWFkYWJsZVN0cmVhbTxVSU1lc3NhZ2VDaHVuaz47XG59ICYgVUlNZXNzYWdlU3RyZWFtUmVzcG9uc2VJbml0KTogdm9pZCB7XG4gIGxldCBzc2VTdHJlYW0gPSBzdHJlYW0ucGlwZVRocm91Z2gobmV3IEpzb25Ub1NzZVRyYW5zZm9ybVN0cmVhbSgpKTtcblxuICAvLyB3aGVuIHRoZSBjb25zdW1lU3NlU3RyZWFtIGlzIHByb3ZpZGVkLCB3ZSBuZWVkIHRvIHRlZSB0aGUgc3RyZWFtXG4gIC8vIGFuZCBzZW5kIHRoZSBzZWNvbmQgcGFydCB0byB0aGUgY29uc3VtZVNzZVN0cmVhbSBmdW5jdGlvblxuICAvLyBzbyB0aGF0IGl0IGNhbiBiZSBjb25zdW1lZCBieSB0aGUgY2xpZW50IGluZGVwZW5kZW50bHlcbiAgaWYgKGNvbnN1bWVTc2VTdHJlYW0pIHtcbiAgICBjb25zdCBbc3RyZWFtMSwgc3RyZWFtMl0gPSBzc2VTdHJlYW0udGVlKCk7XG4gICAgc3NlU3RyZWFtID0gc3RyZWFtMTtcbiAgICBjb25zdW1lU3NlU3RyZWFtKHsgc3RyZWFtOiBzdHJlYW0yIH0pOyAvLyBubyBhd2FpdCAoZG8gbm90IGJsb2NrIHRoZSByZXNwb25zZSlcbiAgfVxuXG4gIHdyaXRlVG9TZXJ2ZXJSZXNwb25zZSh7XG4gICAgcmVzcG9uc2UsXG4gICAgc3RhdHVzLFxuICAgIHN0YXR1c1RleHQsXG4gICAgaGVhZGVyczogT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgcHJlcGFyZUhlYWRlcnMoaGVhZGVycywgVUlfTUVTU0FHRV9TVFJFQU1fSEVBREVSUykuZW50cmllcygpLFxuICAgICksXG4gICAgc3RyZWFtOiBzc2VTdHJlYW0ucGlwZVRocm91Z2gobmV3IFRleHRFbmNvZGVyU3RyZWFtKCkpLFxuICB9KTtcbn1cbiIsICIvKipcbiAqIEEgdHlwZSB0aGF0IGNvbWJpbmVzIEFzeW5jSXRlcmFibGUgYW5kIFJlYWRhYmxlU3RyZWFtLlxuICogVGhpcyBhbGxvd3MgYSBSZWFkYWJsZVN0cmVhbSB0byBiZSBjb25zdW1lZCB1c2luZyBmb3ItYXdhaXQtb2Ygc3ludGF4LlxuICovXG5leHBvcnQgdHlwZSBBc3luY0l0ZXJhYmxlU3RyZWFtPFQ+ID0gQXN5bmNJdGVyYWJsZTxUPiAmIFJlYWRhYmxlU3RyZWFtPFQ+O1xuXG4vKipcbiAqIFdyYXBzIGEgUmVhZGFibGVTdHJlYW0gYW5kIHJldHVybnMgYW4gb2JqZWN0IHRoYXQgaXMgYm90aCBhIFJlYWRhYmxlU3RyZWFtIGFuZCBhbiBBc3luY0l0ZXJhYmxlLlxuICogVGhpcyBlbmFibGVzIGNvbnN1bXB0aW9uIG9mIHRoZSBzdHJlYW0gdXNpbmcgZm9yLWF3YWl0LW9mLCB3aXRoIHByb3BlciByZXNvdXJjZSBjbGVhbnVwIG9uIGVhcmx5IGV4aXQgb3IgZXJyb3IuXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHR5cGUgb2YgdGhlIHN0cmVhbSdzIGNodW5rcy5cbiAqIEBwYXJhbSBzb3VyY2UgVGhlIHNvdXJjZSBSZWFkYWJsZVN0cmVhbSB0byB3cmFwLlxuICogQHJldHVybnMgQW4gQXN5bmNJdGVyYWJsZVN0cmVhbSB0aGF0IGNhbiBiZSB1c2VkIGFzIGJvdGggYSBSZWFkYWJsZVN0cmVhbSBhbmQgYW4gQXN5bmNJdGVyYWJsZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUFzeW5jSXRlcmFibGVTdHJlYW08VD4oXG4gIHNvdXJjZTogUmVhZGFibGVTdHJlYW08VD4sXG4pOiBBc3luY0l0ZXJhYmxlU3RyZWFtPFQ+IHtcbiAgLy8gUGlwZSB0aHJvdWdoIGEgVHJhbnNmb3JtU3RyZWFtIHRvIGVuc3VyZSBhIGZyZXNoLCB1bmxvY2tlZCBzdHJlYW0uXG4gIGNvbnN0IHN0cmVhbSA9IHNvdXJjZS5waXBlVGhyb3VnaChuZXcgVHJhbnNmb3JtU3RyZWFtPFQsIFQ+KCkpO1xuXG4gIC8qKlxuICAgKiBJbXBsZW1lbnRzIHRoZSBhc3luYyBpdGVyYXRvciBwcm90b2NvbCBmb3IgdGhlIHN0cmVhbS5cbiAgICogRW5zdXJlcyBwcm9wZXIgY2xlYW51cCAoY2FuY2VsbGluZyBhbmQgcmVsZWFzaW5nIHRoZSByZWFkZXIpIG9uIGNvbXBsZXRpb24sIGVhcmx5IGV4aXQsIG9yIGVycm9yLlxuICAgKi9cbiAgKHN0cmVhbSBhcyBBc3luY0l0ZXJhYmxlU3RyZWFtPFQ+KVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoXG4gICAgdGhpczogUmVhZGFibGVTdHJlYW08VD4sXG4gICk6IEFzeW5jSXRlcmF0b3I8VD4ge1xuICAgIGNvbnN0IHJlYWRlciA9IHRoaXMuZ2V0UmVhZGVyKCk7XG5cbiAgICBsZXQgZmluaXNoZWQgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIENsZWFucyB1cCB0aGUgcmVhZGVyIGJ5IGNhbmNlbGxpbmcgYW5kIHJlbGVhc2luZyB0aGUgbG9jay5cbiAgICAgKi9cbiAgICBhc3luYyBmdW5jdGlvbiBjbGVhbnVwKGNhbmNlbFN0cmVhbTogYm9vbGVhbikge1xuICAgICAgZmluaXNoZWQgPSB0cnVlO1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKGNhbmNlbFN0cmVhbSkge1xuICAgICAgICAgIGF3YWl0IHJlYWRlci5jYW5jZWw/LigpO1xuICAgICAgICB9XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHJlYWRlci5yZWxlYXNlTG9jaygpO1xuICAgICAgICB9IGNhdGNoIHt9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIC8qKlxuICAgICAgICogUmVhZHMgdGhlIG5leHQgY2h1bmsgZnJvbSB0aGUgc3RyZWFtLlxuICAgICAgICogQHJldHVybnMgQSBwcm9taXNlIHJlc29sdmluZyB0byB0aGUgbmV4dCBJdGVyYXRvclJlc3VsdC5cbiAgICAgICAqL1xuICAgICAgYXN5bmMgbmV4dCgpOiBQcm9taXNlPEl0ZXJhdG9yUmVzdWx0PFQ+PiB7XG4gICAgICAgIGlmIChmaW5pc2hlZCkge1xuICAgICAgICAgIHJldHVybiB7IGRvbmU6IHRydWUsIHZhbHVlOiB1bmRlZmluZWQgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHsgZG9uZSwgdmFsdWUgfSA9IGF3YWl0IHJlYWRlci5yZWFkKCk7XG5cbiAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICBhd2FpdCBjbGVhbnVwKHRydWUpO1xuICAgICAgICAgIHJldHVybiB7IGRvbmU6IHRydWUsIHZhbHVlOiB1bmRlZmluZWQgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7IGRvbmU6IGZhbHNlLCB2YWx1ZSB9O1xuICAgICAgfSxcblxuICAgICAgLyoqXG4gICAgICAgKiBDYWxsZWQgb24gZWFybHkgZXhpdCAoZS5nLiwgYnJlYWsgZnJvbSBmb3ItYXdhaXQpLlxuICAgICAgICogRW5zdXJlcyB0aGUgc3RyZWFtIGlzIGNhbmNlbGxlZCBhbmQgcmVzb3VyY2VzIGFyZSByZWxlYXNlZC5cbiAgICAgICAqIEByZXR1cm5zIEEgcHJvbWlzZSByZXNvbHZpbmcgdG8gYSBjb21wbGV0ZWQgSXRlcmF0b3JSZXN1bHQuXG4gICAgICAgKi9cbiAgICAgIGFzeW5jIHJldHVybigpOiBQcm9taXNlPEl0ZXJhdG9yUmVzdWx0PFQ+PiB7XG4gICAgICAgIGF3YWl0IGNsZWFudXAodHJ1ZSk7XG4gICAgICAgIHJldHVybiB7IGRvbmU6IHRydWUsIHZhbHVlOiB1bmRlZmluZWQgfTtcbiAgICAgIH0sXG5cbiAgICAgIC8qKlxuICAgICAgICogQ2FsbGVkIG9uIGVhcmx5IGV4aXQgd2l0aCBlcnJvci5cbiAgICAgICAqIEVuc3VyZXMgdGhlIHN0cmVhbSBpcyBjYW5jZWxsZWQgYW5kIHJlc291cmNlcyBhcmUgcmVsZWFzZWQsIHRoZW4gcmV0aHJvd3MgdGhlIGVycm9yLlxuICAgICAgICogQHBhcmFtIGVyciBUaGUgZXJyb3IgdG8gdGhyb3cuXG4gICAgICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZWplY3RzIHdpdGggdGhlIHByb3ZpZGVkIGVycm9yLlxuICAgICAgICovXG4gICAgICBhc3luYyB0aHJvdyhlcnI6IHVua25vd24pOiBQcm9taXNlPEl0ZXJhdG9yUmVzdWx0PFQ+PiB7XG4gICAgICAgIGF3YWl0IGNsZWFudXAodHJ1ZSk7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH0sXG4gICAgfTtcbiAgfTtcblxuICByZXR1cm4gc3RyZWFtIGFzIEFzeW5jSXRlcmFibGVTdHJlYW08VD47XG59XG4iLCAiLyoqXG4gKiBDb25zdW1lcyBhIFJlYWRhYmxlU3RyZWFtIHVudGlsIGl0J3MgZnVsbHkgcmVhZC5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIHJlYWRzIHRoZSBzdHJlYW0gY2h1bmsgYnkgY2h1bmsgdW50aWwgdGhlIHN0cmVhbSBpcyBleGhhdXN0ZWQuXG4gKiBJdCBkb2Vzbid0IHByb2Nlc3Mgb3IgcmV0dXJuIHRoZSBkYXRhIGZyb20gdGhlIHN0cmVhbTsgaXQgc2ltcGx5IGVuc3VyZXNcbiAqIHRoYXQgdGhlIGVudGlyZSBzdHJlYW0gaXMgcmVhZC5cbiAqXG4gKiBAcGFyYW0ge1JlYWRhYmxlU3RyZWFtfSBzdHJlYW0gLSBUaGUgUmVhZGFibGVTdHJlYW0gdG8gYmUgY29uc3VtZWQuXG4gKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgc3RyZWFtIGlzIGZ1bGx5IGNvbnN1bWVkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY29uc3VtZVN0cmVhbSh7XG4gIHN0cmVhbSxcbiAgb25FcnJvcixcbn06IHtcbiAgc3RyZWFtOiBSZWFkYWJsZVN0cmVhbTtcbiAgb25FcnJvcj86IChlcnJvcjogdW5rbm93bikgPT4gdm9pZDtcbn0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgcmVhZGVyID0gc3RyZWFtLmdldFJlYWRlcigpO1xuICB0cnkge1xuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICBjb25zdCB7IGRvbmUgfSA9IGF3YWl0IHJlYWRlci5yZWFkKCk7XG4gICAgICBpZiAoZG9uZSkgYnJlYWs7XG4gICAgfVxuICB9IGNhdGNoIChlcnJvcikge1xuICAgIG9uRXJyb3I/LihlcnJvcik7XG4gIH0gZmluYWxseSB7XG4gICAgcmVhZGVyLnJlbGVhc2VMb2NrKCk7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBFcnJvckhhbmRsZXIgfSBmcm9tICcuL2Vycm9yLWhhbmRsZXInO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBQcm9taXNlIHdpdGggZXh0ZXJuYWxseSBhY2Nlc3NpYmxlIHJlc29sdmUgYW5kIHJlamVjdCBmdW5jdGlvbnMuXG4gKlxuICogQHRlbXBsYXRlIFQgLSBUaGUgdHlwZSBvZiB0aGUgdmFsdWUgdGhhdCB0aGUgUHJvbWlzZSB3aWxsIHJlc29sdmUgdG8uXG4gKiBAcmV0dXJucyBBbiBvYmplY3QgY29udGFpbmluZzpcbiAqICAgLSBwcm9taXNlOiBBIFByb21pc2UgdGhhdCBjYW4gYmUgcmVzb2x2ZWQgb3IgcmVqZWN0ZWQgZXh0ZXJuYWxseS5cbiAqICAgLSByZXNvbHZlOiBBIGZ1bmN0aW9uIHRvIHJlc29sdmUgdGhlIFByb21pc2Ugd2l0aCBhIHZhbHVlIG9mIHR5cGUgVC5cbiAqICAgLSByZWplY3Q6IEEgZnVuY3Rpb24gdG8gcmVqZWN0IHRoZSBQcm9taXNlIHdpdGggYW4gZXJyb3IuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVSZXNvbHZhYmxlUHJvbWlzZTxUID0gYW55PigpOiB7XG4gIHByb21pc2U6IFByb21pc2U8VD47XG4gIHJlc29sdmU6ICh2YWx1ZTogVCkgPT4gdm9pZDtcbiAgcmVqZWN0OiBFcnJvckhhbmRsZXI7XG59IHtcbiAgbGV0IHJlc29sdmU6ICh2YWx1ZTogVCkgPT4gdm9pZDtcbiAgbGV0IHJlamVjdDogRXJyb3JIYW5kbGVyO1xuXG4gIGNvbnN0IHByb21pc2UgPSBuZXcgUHJvbWlzZTxUPigocmVzLCByZWopID0+IHtcbiAgICByZXNvbHZlID0gcmVzO1xuICAgIHJlamVjdCA9IHJlajtcbiAgfSk7XG5cbiAgcmV0dXJuIHtcbiAgICBwcm9taXNlLFxuICAgIHJlc29sdmU6IHJlc29sdmUhLFxuICAgIHJlamVjdDogcmVqZWN0ISxcbiAgfTtcbn1cbiIsICJpbXBvcnQgeyBjcmVhdGVSZXNvbHZhYmxlUHJvbWlzZSB9IGZyb20gJy4vY3JlYXRlLXJlc29sdmFibGUtcHJvbWlzZSc7XG5cbi8qKlxuICogQ3JlYXRlcyBhIHN0aXRjaGFibGUgc3RyZWFtIHRoYXQgY2FuIHBpcGUgb25lIHN0cmVhbSBhdCBhIHRpbWUuXG4gKlxuICogQHRlbXBsYXRlIFQgLSBUaGUgdHlwZSBvZiB2YWx1ZXMgZW1pdHRlZCBieSB0aGUgc3RyZWFtcy5cbiAqIEByZXR1cm5zIHtPYmplY3R9IEFuIG9iamVjdCBjb250YWluaW5nIHRoZSBzdGl0Y2hhYmxlIHN0cmVhbSBhbmQgY29udHJvbCBtZXRob2RzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlU3RpdGNoYWJsZVN0cmVhbTxUPigpOiB7XG4gIHN0cmVhbTogUmVhZGFibGVTdHJlYW08VD47XG4gIGFkZFN0cmVhbTogKGlubmVyU3RyZWFtOiBSZWFkYWJsZVN0cmVhbTxUPikgPT4gdm9pZDtcbiAgY2xvc2U6ICgpID0+IHZvaWQ7XG4gIHRlcm1pbmF0ZTogKCkgPT4gdm9pZDtcbn0ge1xuICBsZXQgaW5uZXJTdHJlYW1SZWFkZXJzOiBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXI8VD5bXSA9IFtdO1xuICBsZXQgY29udHJvbGxlcjogUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcjxUPiB8IG51bGwgPSBudWxsO1xuICBsZXQgaXNDbG9zZWQgPSBmYWxzZTtcbiAgbGV0IHdhaXRGb3JOZXdTdHJlYW0gPSBjcmVhdGVSZXNvbHZhYmxlUHJvbWlzZTx2b2lkPigpO1xuXG4gIGNvbnN0IHRlcm1pbmF0ZSA9ICgpID0+IHtcbiAgICBpc0Nsb3NlZCA9IHRydWU7XG4gICAgd2FpdEZvck5ld1N0cmVhbS5yZXNvbHZlKCk7XG5cbiAgICBpbm5lclN0cmVhbVJlYWRlcnMuZm9yRWFjaChyZWFkZXIgPT4gcmVhZGVyLmNhbmNlbCgpKTtcbiAgICBpbm5lclN0cmVhbVJlYWRlcnMgPSBbXTtcbiAgICBjb250cm9sbGVyPy5jbG9zZSgpO1xuICB9O1xuXG4gIGNvbnN0IHByb2Nlc3NQdWxsID0gYXN5bmMgKCkgPT4ge1xuICAgIC8vIENhc2UgMTogT3V0ZXIgc3RyZWFtIGlzIGNsb3NlZCBhbmQgbm8gbW9yZSBpbm5lciBzdHJlYW1zXG4gICAgaWYgKGlzQ2xvc2VkICYmIGlubmVyU3RyZWFtUmVhZGVycy5sZW5ndGggPT09IDApIHtcbiAgICAgIGNvbnRyb2xsZXI/LmNsb3NlKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gQ2FzZSAyOiBObyBpbm5lciBzdHJlYW1zIGF2YWlsYWJsZSwgYnV0IG91dGVyIHN0cmVhbSBpcyBvcGVuXG4gICAgLy8gd2FpdCBmb3IgYSBuZXcgaW5uZXIgc3RyZWFtIHRvIGJlIGFkZGVkIG9yIHRoZSBvdXRlciBzdHJlYW0gdG8gY2xvc2VcbiAgICBpZiAoaW5uZXJTdHJlYW1SZWFkZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgd2FpdEZvck5ld1N0cmVhbSA9IGNyZWF0ZVJlc29sdmFibGVQcm9taXNlPHZvaWQ+KCk7XG4gICAgICBhd2FpdCB3YWl0Rm9yTmV3U3RyZWFtLnByb21pc2U7XG4gICAgICByZXR1cm4gcHJvY2Vzc1B1bGwoKTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgeyB2YWx1ZSwgZG9uZSB9ID0gYXdhaXQgaW5uZXJTdHJlYW1SZWFkZXJzWzBdLnJlYWQoKTtcblxuICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgLy8gQ2FzZSAzOiBDdXJyZW50IGlubmVyIHN0cmVhbSBpcyBkb25lXG4gICAgICAgIGlubmVyU3RyZWFtUmVhZGVycy5zaGlmdCgpOyAvLyBSZW1vdmUgdGhlIGZpbmlzaGVkIHN0cmVhbVxuXG4gICAgICAgIC8vIENvbnRpbnVlIHB1bGxpbmcgZnJvbSB0aGUgbmV4dCBzdHJlYW0gaWYgYXZhaWxhYmxlXG4gICAgICAgIGlmIChpbm5lclN0cmVhbVJlYWRlcnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGF3YWl0IHByb2Nlc3NQdWxsKCk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNDbG9zZWQpIHtcbiAgICAgICAgICBjb250cm9sbGVyPy5jbG9zZSgpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBDYXNlIDQ6IEN1cnJlbnQgaW5uZXIgc3RyZWFtIHJldHVybnMgYW4gaXRlbVxuICAgICAgICBjb250cm9sbGVyPy5lbnF1ZXVlKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLy8gQ2FzZSA1OiBDdXJyZW50IGlubmVyIHN0cmVhbSB0aHJvd3MgYW4gZXJyb3JcbiAgICAgIGNvbnRyb2xsZXI/LmVycm9yKGVycm9yKTtcbiAgICAgIGlubmVyU3RyZWFtUmVhZGVycy5zaGlmdCgpOyAvLyBSZW1vdmUgdGhlIGVycm9yZWQgc3RyZWFtXG4gICAgICB0ZXJtaW5hdGUoKTsgLy8gd2UgaGF2ZSBlcnJvcmVkLCB0ZXJtaW5hdGUgYWxsIHN0cmVhbXNcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIHtcbiAgICBzdHJlYW06IG5ldyBSZWFkYWJsZVN0cmVhbTxUPih7XG4gICAgICBzdGFydChjb250cm9sbGVyUGFyYW0pIHtcbiAgICAgICAgY29udHJvbGxlciA9IGNvbnRyb2xsZXJQYXJhbTtcbiAgICAgIH0sXG4gICAgICBwdWxsOiBwcm9jZXNzUHVsbCxcbiAgICAgIGFzeW5jIGNhbmNlbCgpIHtcbiAgICAgICAgZm9yIChjb25zdCByZWFkZXIgb2YgaW5uZXJTdHJlYW1SZWFkZXJzKSB7XG4gICAgICAgICAgYXdhaXQgcmVhZGVyLmNhbmNlbCgpO1xuICAgICAgICB9XG4gICAgICAgIGlubmVyU3RyZWFtUmVhZGVycyA9IFtdO1xuICAgICAgICBpc0Nsb3NlZCA9IHRydWU7XG4gICAgICB9LFxuICAgIH0pLFxuICAgIGFkZFN0cmVhbTogKGlubmVyU3RyZWFtOiBSZWFkYWJsZVN0cmVhbTxUPikgPT4ge1xuICAgICAgaWYgKGlzQ2xvc2VkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGFkZCBpbm5lciBzdHJlYW06IG91dGVyIHN0cmVhbSBpcyBjbG9zZWQnKTtcbiAgICAgIH1cblxuICAgICAgaW5uZXJTdHJlYW1SZWFkZXJzLnB1c2goaW5uZXJTdHJlYW0uZ2V0UmVhZGVyKCkpO1xuICAgICAgd2FpdEZvck5ld1N0cmVhbS5yZXNvbHZlKCk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdyYWNlZnVsbHkgY2xvc2UgdGhlIG91dGVyIHN0cmVhbS4gVGhpcyB3aWxsIGxldCB0aGUgaW5uZXIgc3RyZWFtc1xuICAgICAqIGZpbmlzaCBwcm9jZXNzaW5nIGFuZCB0aGVuIGNsb3NlIHRoZSBvdXRlciBzdHJlYW0uXG4gICAgICovXG4gICAgY2xvc2U6ICgpID0+IHtcbiAgICAgIGlzQ2xvc2VkID0gdHJ1ZTtcbiAgICAgIHdhaXRGb3JOZXdTdHJlYW0ucmVzb2x2ZSgpO1xuXG4gICAgICBpZiAoaW5uZXJTdHJlYW1SZWFkZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBjb250cm9sbGVyPy5jbG9zZSgpO1xuICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBJbW1lZGlhdGVseSBjbG9zZSB0aGUgb3V0ZXIgc3RyZWFtLiBUaGlzIHdpbGwgY2FuY2VsIGFsbCBpbm5lciBzdHJlYW1zXG4gICAgICogYW5kIGNsb3NlIHRoZSBvdXRlciBzdHJlYW0uXG4gICAgICovXG4gICAgdGVybWluYXRlLFxuICB9O1xufVxuIiwgIi8qKlxuICogRGVsYXllZCBwcm9taXNlLiBJdCBpcyBvbmx5IGNvbnN0cnVjdGVkIG9uY2UgdGhlIHZhbHVlIGlzIGFjY2Vzc2VkLlxuICogVGhpcyBpcyB1c2VmdWwgdG8gYXZvaWQgdW5oYW5kbGVkIHByb21pc2UgcmVqZWN0aW9ucyB3aGVuIHRoZSBwcm9taXNlIGlzIGNyZWF0ZWRcbiAqIGJ1dCBub3QgYWNjZXNzZWQuXG4gKi9cbmV4cG9ydCBjbGFzcyBEZWxheWVkUHJvbWlzZTxUPiB7XG4gIHByaXZhdGUgc3RhdHVzOlxuICAgIHwgeyB0eXBlOiAncGVuZGluZycgfVxuICAgIHwgeyB0eXBlOiAncmVzb2x2ZWQnOyB2YWx1ZTogVCB9XG4gICAgfCB7IHR5cGU6ICdyZWplY3RlZCc7IGVycm9yOiB1bmtub3duIH0gPSB7IHR5cGU6ICdwZW5kaW5nJyB9O1xuICBwcml2YXRlIF9wcm9taXNlOiBQcm9taXNlPFQ+IHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIF9yZXNvbHZlOiB1bmRlZmluZWQgfCAoKHZhbHVlOiBUKSA9PiB2b2lkKSA9IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSBfcmVqZWN0OiB1bmRlZmluZWQgfCAoKGVycm9yOiB1bmtub3duKSA9PiB2b2lkKSA9IHVuZGVmaW5lZDtcblxuICBnZXQgcHJvbWlzZSgpOiBQcm9taXNlPFQ+IHtcbiAgICBpZiAodGhpcy5fcHJvbWlzZSkge1xuICAgICAgcmV0dXJuIHRoaXMuX3Byb21pc2U7XG4gICAgfVxuXG4gICAgdGhpcy5fcHJvbWlzZSA9IG5ldyBQcm9taXNlPFQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGlmICh0aGlzLnN0YXR1cy50eXBlID09PSAncmVzb2x2ZWQnKSB7XG4gICAgICAgIHJlc29sdmUodGhpcy5zdGF0dXMudmFsdWUpO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLnN0YXR1cy50eXBlID09PSAncmVqZWN0ZWQnKSB7XG4gICAgICAgIHJlamVjdCh0aGlzLnN0YXR1cy5lcnJvcik7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX3Jlc29sdmUgPSByZXNvbHZlO1xuICAgICAgdGhpcy5fcmVqZWN0ID0gcmVqZWN0O1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRoaXMuX3Byb21pc2U7XG4gIH1cblxuICByZXNvbHZlKHZhbHVlOiBUKTogdm9pZCB7XG4gICAgdGhpcy5zdGF0dXMgPSB7IHR5cGU6ICdyZXNvbHZlZCcsIHZhbHVlIH07XG5cbiAgICBpZiAodGhpcy5fcHJvbWlzZSkge1xuICAgICAgdGhpcy5fcmVzb2x2ZT8uKHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICByZWplY3QoZXJyb3I6IHVua25vd24pOiB2b2lkIHtcbiAgICB0aGlzLnN0YXR1cyA9IHsgdHlwZTogJ3JlamVjdGVkJywgZXJyb3IgfTtcblxuICAgIGlmICh0aGlzLl9wcm9taXNlKSB7XG4gICAgICB0aGlzLl9yZWplY3Q/LihlcnJvcik7XG4gICAgfVxuICB9XG59XG4iLCAiLy8gU2hpbSBmb3IgcGVyZm9ybWFuY2Uubm93KCkgdG8gc3VwcG9ydCBlbnZpcm9ubWVudHMgdGhhdCBkb24ndCBoYXZlIGl0OlxuZXhwb3J0IGZ1bmN0aW9uIG5vdygpOiBudW1iZXIge1xuICByZXR1cm4gZ2xvYmFsVGhpcz8ucGVyZm9ybWFuY2U/Lm5vdygpID8/IERhdGUubm93KCk7XG59XG4iLCAiaW1wb3J0IHtcbiAgTGFuZ3VhZ2VNb2RlbFYyQ2FsbFdhcm5pbmcsXG4gIExhbmd1YWdlTW9kZWxWMlN0cmVhbVBhcnQsXG59IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHtcbiAgZXhlY3V0ZVRvb2wsXG4gIGdlbmVyYXRlSWQsXG4gIGdldEVycm9yTWVzc2FnZSxcbiAgTW9kZWxNZXNzYWdlLFxufSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyLXV0aWxzJztcbmltcG9ydCB7IFRyYWNlciB9IGZyb20gJ0BvcGVudGVsZW1ldHJ5L2FwaSc7XG5pbXBvcnQgeyBhc3NlbWJsZU9wZXJhdGlvbk5hbWUgfSBmcm9tICcuLi90ZWxlbWV0cnkvYXNzZW1ibGUtb3BlcmF0aW9uLW5hbWUnO1xuaW1wb3J0IHsgcmVjb3JkRXJyb3JPblNwYW4sIHJlY29yZFNwYW4gfSBmcm9tICcuLi90ZWxlbWV0cnkvcmVjb3JkLXNwYW4nO1xuaW1wb3J0IHsgc2VsZWN0VGVsZW1ldHJ5QXR0cmlidXRlcyB9IGZyb20gJy4uL3RlbGVtZXRyeS9zZWxlY3QtdGVsZW1ldHJ5LWF0dHJpYnV0ZXMnO1xuaW1wb3J0IHsgVGVsZW1ldHJ5U2V0dGluZ3MgfSBmcm9tICcuLi90ZWxlbWV0cnkvdGVsZW1ldHJ5LXNldHRpbmdzJztcbmltcG9ydCB7IEZpbmlzaFJlYXNvbiwgTGFuZ3VhZ2VNb2RlbFVzYWdlLCBQcm92aWRlck1ldGFkYXRhIH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHsgU291cmNlIH0gZnJvbSAnLi4vdHlwZXMvbGFuZ3VhZ2UtbW9kZWwnO1xuaW1wb3J0IHsgRGVmYXVsdEdlbmVyYXRlZEZpbGVXaXRoVHlwZSwgR2VuZXJhdGVkRmlsZSB9IGZyb20gJy4vZ2VuZXJhdGVkLWZpbGUnO1xuaW1wb3J0IHsgcGFyc2VUb29sQ2FsbCB9IGZyb20gJy4vcGFyc2UtdG9vbC1jYWxsJztcbmltcG9ydCB7IFR5cGVkVG9vbENhbGwgfSBmcm9tICcuL3Rvb2wtY2FsbCc7XG5pbXBvcnQgeyBUb29sQ2FsbFJlcGFpckZ1bmN0aW9uIH0gZnJvbSAnLi90b29sLWNhbGwtcmVwYWlyLWZ1bmN0aW9uJztcbmltcG9ydCB7IFR5cGVkVG9vbEVycm9yIH0gZnJvbSAnLi90b29sLWVycm9yJztcbmltcG9ydCB7IFR5cGVkVG9vbFJlc3VsdCB9IGZyb20gJy4vdG9vbC1yZXN1bHQnO1xuaW1wb3J0IHsgVG9vbFNldCB9IGZyb20gJy4vdG9vbC1zZXQnO1xuXG5leHBvcnQgdHlwZSBTaW5nbGVSZXF1ZXN0VGV4dFN0cmVhbVBhcnQ8VE9PTFMgZXh0ZW5kcyBUb29sU2V0PiA9XG4gIC8vIFRleHQgYmxvY2tzOlxuICB8IHtcbiAgICAgIHR5cGU6ICd0ZXh0LXN0YXJ0JztcbiAgICAgIHByb3ZpZGVyTWV0YWRhdGE/OiBQcm92aWRlck1ldGFkYXRhO1xuICAgICAgaWQ6IHN0cmluZztcbiAgICB9XG4gIHwge1xuICAgICAgdHlwZTogJ3RleHQtZGVsdGEnO1xuICAgICAgaWQ6IHN0cmluZztcbiAgICAgIHByb3ZpZGVyTWV0YWRhdGE/OiBQcm92aWRlck1ldGFkYXRhO1xuICAgICAgZGVsdGE6IHN0cmluZztcbiAgICB9XG4gIHwge1xuICAgICAgdHlwZTogJ3RleHQtZW5kJztcbiAgICAgIHByb3ZpZGVyTWV0YWRhdGE/OiBQcm92aWRlck1ldGFkYXRhO1xuICAgICAgaWQ6IHN0cmluZztcbiAgICB9XG5cbiAgLy8gUmVhc29uaW5nIGJsb2NrczpcbiAgfCB7XG4gICAgICB0eXBlOiAncmVhc29uaW5nLXN0YXJ0JztcbiAgICAgIHByb3ZpZGVyTWV0YWRhdGE/OiBQcm92aWRlck1ldGFkYXRhO1xuICAgICAgaWQ6IHN0cmluZztcbiAgICB9XG4gIHwge1xuICAgICAgdHlwZTogJ3JlYXNvbmluZy1kZWx0YSc7XG4gICAgICBpZDogc3RyaW5nO1xuICAgICAgcHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG4gICAgICBkZWx0YTogc3RyaW5nO1xuICAgIH1cbiAgfCB7XG4gICAgICB0eXBlOiAncmVhc29uaW5nLWVuZCc7XG4gICAgICBpZDogc3RyaW5nO1xuICAgICAgcHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG4gICAgfVxuXG4gIC8vIFRvb2wgY2FsbHM6XG4gIHwge1xuICAgICAgdHlwZTogJ3Rvb2wtaW5wdXQtc3RhcnQnO1xuICAgICAgaWQ6IHN0cmluZztcbiAgICAgIHRvb2xOYW1lOiBzdHJpbmc7XG4gICAgICBwcm92aWRlck1ldGFkYXRhPzogUHJvdmlkZXJNZXRhZGF0YTtcbiAgICB9XG4gIHwge1xuICAgICAgdHlwZTogJ3Rvb2wtaW5wdXQtZGVsdGEnO1xuICAgICAgaWQ6IHN0cmluZztcbiAgICAgIGRlbHRhOiBzdHJpbmc7XG4gICAgICBwcm92aWRlck1ldGFkYXRhPzogUHJvdmlkZXJNZXRhZGF0YTtcbiAgICB9XG4gIHwge1xuICAgICAgdHlwZTogJ3Rvb2wtaW5wdXQtZW5kJztcbiAgICAgIGlkOiBzdHJpbmc7XG4gICAgICBwcm92aWRlck1ldGFkYXRhPzogUHJvdmlkZXJNZXRhZGF0YTtcbiAgICB9XG4gIHwgKHsgdHlwZTogJ3NvdXJjZScgfSAmIFNvdXJjZSlcbiAgfCB7IHR5cGU6ICdmaWxlJzsgZmlsZTogR2VuZXJhdGVkRmlsZSB9IC8vIGRpZmZlcmVudCBiZWNhdXNlIG9mIEdlbmVyYXRlZEZpbGUgb2JqZWN0XG4gIHwgKHsgdHlwZTogJ3Rvb2wtY2FsbCcgfSAmIFR5cGVkVG9vbENhbGw8VE9PTFM+KVxuICB8ICh7IHR5cGU6ICd0b29sLXJlc3VsdCcgfSAmIFR5cGVkVG9vbFJlc3VsdDxUT09MUz4pXG4gIHwgKHsgdHlwZTogJ3Rvb2wtZXJyb3InIH0gJiBUeXBlZFRvb2xFcnJvcjxUT09MUz4pXG4gIHwgeyB0eXBlOiAnZmlsZSc7IGZpbGU6IEdlbmVyYXRlZEZpbGUgfSAvLyBkaWZmZXJlbnQgYmVjYXVzZSBvZiBHZW5lcmF0ZWRGaWxlIG9iamVjdFxuICB8IHsgdHlwZTogJ3N0cmVhbS1zdGFydCc7IHdhcm5pbmdzOiBMYW5ndWFnZU1vZGVsVjJDYWxsV2FybmluZ1tdIH1cbiAgfCB7XG4gICAgICB0eXBlOiAncmVzcG9uc2UtbWV0YWRhdGEnO1xuICAgICAgaWQ/OiBzdHJpbmc7XG4gICAgICB0aW1lc3RhbXA/OiBEYXRlO1xuICAgICAgbW9kZWxJZD86IHN0cmluZztcbiAgICB9XG4gIHwge1xuICAgICAgdHlwZTogJ2ZpbmlzaCc7XG4gICAgICBmaW5pc2hSZWFzb246IEZpbmlzaFJlYXNvbjtcbiAgICAgIHVzYWdlOiBMYW5ndWFnZU1vZGVsVXNhZ2U7XG4gICAgICBwcm92aWRlck1ldGFkYXRhPzogUHJvdmlkZXJNZXRhZGF0YTtcbiAgICB9XG4gIHwgeyB0eXBlOiAnZXJyb3InOyBlcnJvcjogdW5rbm93biB9XG4gIHwgeyB0eXBlOiAncmF3JzsgcmF3VmFsdWU6IHVua25vd24gfTtcblxuZXhwb3J0IGZ1bmN0aW9uIHJ1blRvb2xzVHJhbnNmb3JtYXRpb248VE9PTFMgZXh0ZW5kcyBUb29sU2V0Pih7XG4gIHRvb2xzLFxuICBnZW5lcmF0b3JTdHJlYW0sXG4gIHRyYWNlcixcbiAgdGVsZW1ldHJ5LFxuICBzeXN0ZW0sXG4gIG1lc3NhZ2VzLFxuICBhYm9ydFNpZ25hbCxcbiAgcmVwYWlyVG9vbENhbGwsXG4gIGV4cGVyaW1lbnRhbF9jb250ZXh0LFxufToge1xuICB0b29sczogVE9PTFMgfCB1bmRlZmluZWQ7XG4gIGdlbmVyYXRvclN0cmVhbTogUmVhZGFibGVTdHJlYW08TGFuZ3VhZ2VNb2RlbFYyU3RyZWFtUGFydD47XG4gIHRyYWNlcjogVHJhY2VyO1xuICB0ZWxlbWV0cnk6IFRlbGVtZXRyeVNldHRpbmdzIHwgdW5kZWZpbmVkO1xuICBzeXN0ZW06IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgbWVzc2FnZXM6IE1vZGVsTWVzc2FnZVtdO1xuICBhYm9ydFNpZ25hbDogQWJvcnRTaWduYWwgfCB1bmRlZmluZWQ7XG4gIHJlcGFpclRvb2xDYWxsOiBUb29sQ2FsbFJlcGFpckZ1bmN0aW9uPFRPT0xTPiB8IHVuZGVmaW5lZDtcbiAgZXhwZXJpbWVudGFsX2NvbnRleHQ6IHVua25vd247XG59KTogUmVhZGFibGVTdHJlYW08U2luZ2xlUmVxdWVzdFRleHRTdHJlYW1QYXJ0PFRPT0xTPj4ge1xuICAvLyB0b29sIHJlc3VsdHMgc3RyZWFtXG4gIGxldCB0b29sUmVzdWx0c1N0cmVhbUNvbnRyb2xsZXI6IFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXI8XG4gICAgU2luZ2xlUmVxdWVzdFRleHRTdHJlYW1QYXJ0PFRPT0xTPlxuICA+IHwgbnVsbCA9IG51bGw7XG4gIGNvbnN0IHRvb2xSZXN1bHRzU3RyZWFtID0gbmV3IFJlYWRhYmxlU3RyZWFtPFxuICAgIFNpbmdsZVJlcXVlc3RUZXh0U3RyZWFtUGFydDxUT09MUz5cbiAgPih7XG4gICAgc3RhcnQoY29udHJvbGxlcikge1xuICAgICAgdG9vbFJlc3VsdHNTdHJlYW1Db250cm9sbGVyID0gY29udHJvbGxlcjtcbiAgICB9LFxuICB9KTtcblxuICAvLyBrZWVwIHRyYWNrIG9mIG91dHN0YW5kaW5nIHRvb2wgcmVzdWx0cyBmb3Igc3RyZWFtIGNsb3Npbmc6XG4gIGNvbnN0IG91dHN0YW5kaW5nVG9vbFJlc3VsdHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuICAvLyBrZWVwIHRyYWNrIG9mIHRvb2wgaW5wdXRzIGZvciBwcm92aWRlci1zaWRlIHRvb2wgcmVzdWx0c1xuICBjb25zdCB0b29sSW5wdXRzID0gbmV3IE1hcDxzdHJpbmcsIHVua25vd24+KCk7XG5cbiAgbGV0IGNhbkNsb3NlID0gZmFsc2U7XG4gIGxldCBmaW5pc2hDaHVuazpcbiAgICB8IChTaW5nbGVSZXF1ZXN0VGV4dFN0cmVhbVBhcnQ8VE9PTFM+ICYgeyB0eXBlOiAnZmluaXNoJyB9KVxuICAgIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuXG4gIGZ1bmN0aW9uIGF0dGVtcHRDbG9zZSgpIHtcbiAgICAvLyBjbG9zZSB0aGUgdG9vbCByZXN1bHRzIGNvbnRyb2xsZXIgaWYgbm8gbW9yZSBvdXRzdGFuZGluZyB0b29sIGNhbGxzXG4gICAgaWYgKGNhbkNsb3NlICYmIG91dHN0YW5kaW5nVG9vbFJlc3VsdHMuc2l6ZSA9PT0gMCkge1xuICAgICAgLy8gd2UgZGVsYXkgc2VuZGluZyB0aGUgZmluaXNoIGNodW5rIHVudGlsIGFsbCB0b29sIHJlc3VsdHMgKGluY2wuIGRlbGF5ZWQgb25lcylcbiAgICAgIC8vIGFyZSByZWNlaXZlZCB0byBlbnN1cmUgdGhhdCB0aGUgZnJvbnRlbmQgcmVjZWl2ZXMgdG9vbCByZXN1bHRzIGJlZm9yZSBhIG1lc3NhZ2VcbiAgICAgIC8vIGZpbmlzaCBldmVudCBhcnJpdmVzLlxuICAgICAgaWYgKGZpbmlzaENodW5rICE9IG51bGwpIHtcbiAgICAgICAgdG9vbFJlc3VsdHNTdHJlYW1Db250cm9sbGVyIS5lbnF1ZXVlKGZpbmlzaENodW5rKTtcbiAgICAgIH1cblxuICAgICAgdG9vbFJlc3VsdHNTdHJlYW1Db250cm9sbGVyIS5jbG9zZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8vIGZvcndhcmQgc3RyZWFtXG4gIGNvbnN0IGZvcndhcmRTdHJlYW0gPSBuZXcgVHJhbnNmb3JtU3RyZWFtPFxuICAgIExhbmd1YWdlTW9kZWxWMlN0cmVhbVBhcnQsXG4gICAgU2luZ2xlUmVxdWVzdFRleHRTdHJlYW1QYXJ0PFRPT0xTPlxuICA+KHtcbiAgICBhc3luYyB0cmFuc2Zvcm0oXG4gICAgICBjaHVuazogTGFuZ3VhZ2VNb2RlbFYyU3RyZWFtUGFydCxcbiAgICAgIGNvbnRyb2xsZXI6IFRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyPFxuICAgICAgICBTaW5nbGVSZXF1ZXN0VGV4dFN0cmVhbVBhcnQ8VE9PTFM+XG4gICAgICA+LFxuICAgICkge1xuICAgICAgY29uc3QgY2h1bmtUeXBlID0gY2h1bmsudHlwZTtcblxuICAgICAgc3dpdGNoIChjaHVua1R5cGUpIHtcbiAgICAgICAgLy8gZm9yd2FyZDpcbiAgICAgICAgY2FzZSAnc3RyZWFtLXN0YXJ0JzpcbiAgICAgICAgY2FzZSAndGV4dC1zdGFydCc6XG4gICAgICAgIGNhc2UgJ3RleHQtZGVsdGEnOlxuICAgICAgICBjYXNlICd0ZXh0LWVuZCc6XG4gICAgICAgIGNhc2UgJ3JlYXNvbmluZy1zdGFydCc6XG4gICAgICAgIGNhc2UgJ3JlYXNvbmluZy1kZWx0YSc6XG4gICAgICAgIGNhc2UgJ3JlYXNvbmluZy1lbmQnOlxuICAgICAgICBjYXNlICd0b29sLWlucHV0LXN0YXJ0JzpcbiAgICAgICAgY2FzZSAndG9vbC1pbnB1dC1kZWx0YSc6XG4gICAgICAgIGNhc2UgJ3Rvb2wtaW5wdXQtZW5kJzpcbiAgICAgICAgY2FzZSAnc291cmNlJzpcbiAgICAgICAgY2FzZSAncmVzcG9uc2UtbWV0YWRhdGEnOlxuICAgICAgICBjYXNlICdlcnJvcic6XG4gICAgICAgIGNhc2UgJ3Jhdyc6IHtcbiAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoY2h1bmspO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgY2FzZSAnZmlsZSc6IHtcbiAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgdHlwZTogJ2ZpbGUnLFxuICAgICAgICAgICAgZmlsZTogbmV3IERlZmF1bHRHZW5lcmF0ZWRGaWxlV2l0aFR5cGUoe1xuICAgICAgICAgICAgICBkYXRhOiBjaHVuay5kYXRhLFxuICAgICAgICAgICAgICBtZWRpYVR5cGU6IGNodW5rLm1lZGlhVHlwZSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgY2FzZSAnZmluaXNoJzoge1xuICAgICAgICAgIGZpbmlzaENodW5rID0ge1xuICAgICAgICAgICAgdHlwZTogJ2ZpbmlzaCcsXG4gICAgICAgICAgICBmaW5pc2hSZWFzb246IGNodW5rLmZpbmlzaFJlYXNvbixcbiAgICAgICAgICAgIHVzYWdlOiBjaHVuay51c2FnZSxcbiAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IGNodW5rLnByb3ZpZGVyTWV0YWRhdGEsXG4gICAgICAgICAgfTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHByb2Nlc3MgdG9vbCBjYWxsOlxuICAgICAgICBjYXNlICd0b29sLWNhbGwnOiB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHRvb2xDYWxsID0gYXdhaXQgcGFyc2VUb29sQ2FsbCh7XG4gICAgICAgICAgICAgIHRvb2xDYWxsOiBjaHVuayxcbiAgICAgICAgICAgICAgdG9vbHMsXG4gICAgICAgICAgICAgIHJlcGFpclRvb2xDYWxsLFxuICAgICAgICAgICAgICBzeXN0ZW0sXG4gICAgICAgICAgICAgIG1lc3NhZ2VzLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh0b29sQ2FsbCk7XG5cbiAgICAgICAgICAgIC8vIGhhbmRsZSBpbnZhbGlkIHRvb2wgY2FsbHM6XG4gICAgICAgICAgICBpZiAodG9vbENhbGwuaW52YWxpZCkge1xuICAgICAgICAgICAgICB0b29sUmVzdWx0c1N0cmVhbUNvbnRyb2xsZXIhLmVucXVldWUoe1xuICAgICAgICAgICAgICAgIHR5cGU6ICd0b29sLWVycm9yJyxcbiAgICAgICAgICAgICAgICB0b29sQ2FsbElkOiB0b29sQ2FsbC50b29sQ2FsbElkLFxuICAgICAgICAgICAgICAgIHRvb2xOYW1lOiB0b29sQ2FsbC50b29sTmFtZSxcbiAgICAgICAgICAgICAgICBpbnB1dDogdG9vbENhbGwuaW5wdXQsXG4gICAgICAgICAgICAgICAgZXJyb3I6IGdldEVycm9yTWVzc2FnZSh0b29sQ2FsbC5lcnJvciEpLFxuICAgICAgICAgICAgICAgIGR5bmFtaWM6IHRydWUsXG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCB0b29sID0gdG9vbHMhW3Rvb2xDYWxsLnRvb2xOYW1lXTtcblxuICAgICAgICAgICAgdG9vbElucHV0cy5zZXQodG9vbENhbGwudG9vbENhbGxJZCwgdG9vbENhbGwuaW5wdXQpO1xuXG4gICAgICAgICAgICBpZiAodG9vbC5vbklucHV0QXZhaWxhYmxlICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgYXdhaXQgdG9vbC5vbklucHV0QXZhaWxhYmxlKHtcbiAgICAgICAgICAgICAgICBpbnB1dDogdG9vbENhbGwuaW5wdXQsXG4gICAgICAgICAgICAgICAgdG9vbENhbGxJZDogdG9vbENhbGwudG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgICBtZXNzYWdlcyxcbiAgICAgICAgICAgICAgICBhYm9ydFNpZ25hbCxcbiAgICAgICAgICAgICAgICBleHBlcmltZW50YWxfY29udGV4dCxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIE9ubHkgZXhlY3V0ZSB0b29scyB0aGF0IGFyZSBub3QgcHJvdmlkZXItZXhlY3V0ZWQ6XG4gICAgICAgICAgICBpZiAodG9vbC5leGVjdXRlICE9IG51bGwgJiYgdG9vbENhbGwucHJvdmlkZXJFeGVjdXRlZCAhPT0gdHJ1ZSkge1xuICAgICAgICAgICAgICBjb25zdCB0b29sRXhlY3V0aW9uSWQgPSBnZW5lcmF0ZUlkKCk7IC8vIHVzZSBvdXIgb3duIGlkIHRvIGd1YXJhbnRlZSB1bmlxdWVuZXNzXG4gICAgICAgICAgICAgIG91dHN0YW5kaW5nVG9vbFJlc3VsdHMuYWRkKHRvb2xFeGVjdXRpb25JZCk7XG5cbiAgICAgICAgICAgICAgLy8gTm90ZTogd2UgZG9uJ3QgYXdhaXQgdGhlIHRvb2wgZXhlY3V0aW9uIGhlcmUgKGJ5IGxlYXZpbmcgb3V0ICdhd2FpdCcgb24gcmVjb3JkU3BhbiksXG4gICAgICAgICAgICAgIC8vIGJlY2F1c2Ugd2Ugd2FudCB0byBwcm9jZXNzIHRoZSBuZXh0IGNodW5rIGFzIHNvb24gYXMgcG9zc2libGUuXG4gICAgICAgICAgICAgIC8vIFRoaXMgaXMgaW1wb3J0YW50IGZvciB0aGUgY2FzZSB3aGVyZSB0aGUgdG9vbCBleGVjdXRpb24gdGFrZXMgYSBsb25nIHRpbWUuXG4gICAgICAgICAgICAgIHJlY29yZFNwYW4oe1xuICAgICAgICAgICAgICAgIG5hbWU6ICdhaS50b29sQ2FsbCcsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlczogc2VsZWN0VGVsZW1ldHJ5QXR0cmlidXRlcyh7XG4gICAgICAgICAgICAgICAgICB0ZWxlbWV0cnksXG4gICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgICAgICAgICAgIC4uLmFzc2VtYmxlT3BlcmF0aW9uTmFtZSh7XG4gICAgICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uSWQ6ICdhaS50b29sQ2FsbCcsXG4gICAgICAgICAgICAgICAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgJ2FpLnRvb2xDYWxsLm5hbWUnOiB0b29sQ2FsbC50b29sTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgJ2FpLnRvb2xDYWxsLmlkJzogdG9vbENhbGwudG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgICAgICAgJ2FpLnRvb2xDYWxsLmFyZ3MnOiB7XG4gICAgICAgICAgICAgICAgICAgICAgb3V0cHV0OiAoKSA9PiBKU09OLnN0cmluZ2lmeSh0b29sQ2FsbC5pbnB1dCksXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIHRyYWNlcixcbiAgICAgICAgICAgICAgICBmbjogYXN5bmMgc3BhbiA9PiB7XG4gICAgICAgICAgICAgICAgICBsZXQgb3V0cHV0OiB1bmtub3duO1xuXG4gICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBleGVjdXRlVG9vbCh7XG4gICAgICAgICAgICAgICAgICAgICAgZXhlY3V0ZTogdG9vbC5leGVjdXRlIS5iaW5kKHRvb2wpLFxuICAgICAgICAgICAgICAgICAgICAgIGlucHV0OiB0b29sQ2FsbC5pbnB1dCxcbiAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b29sQ2FsbElkOiB0b29sQ2FsbC50b29sQ2FsbElkLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZXMsXG4gICAgICAgICAgICAgICAgICAgICAgICBhYm9ydFNpZ25hbCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVyaW1lbnRhbF9jb250ZXh0LFxuICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgIGZvciBhd2FpdCAoY29uc3QgcGFydCBvZiBzdHJlYW0pIHtcbiAgICAgICAgICAgICAgICAgICAgICB0b29sUmVzdWx0c1N0cmVhbUNvbnRyb2xsZXIhLmVucXVldWUoe1xuICAgICAgICAgICAgICAgICAgICAgICAgLi4udG9vbENhbGwsXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAndG9vbC1yZXN1bHQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0OiBwYXJ0Lm91dHB1dCxcbiAgICAgICAgICAgICAgICAgICAgICAgIC4uLihwYXJ0LnR5cGUgPT09ICdwcmVsaW1pbmFyeScgJiYge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVsaW1pbmFyeTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnQudHlwZSA9PT0gJ2ZpbmFsJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0ID0gcGFydC5vdXRwdXQ7XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICByZWNvcmRFcnJvck9uU3BhbihzcGFuLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIHRvb2xSZXN1bHRzU3RyZWFtQ29udHJvbGxlciEuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgLi4udG9vbENhbGwsXG4gICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3Rvb2wtZXJyb3InLFxuICAgICAgICAgICAgICAgICAgICAgIGVycm9yLFxuICAgICAgICAgICAgICAgICAgICB9IHNhdGlzZmllcyBUeXBlZFRvb2xFcnJvcjxUT09MUz4pO1xuXG4gICAgICAgICAgICAgICAgICAgIG91dHN0YW5kaW5nVG9vbFJlc3VsdHMuZGVsZXRlKHRvb2xFeGVjdXRpb25JZCk7XG4gICAgICAgICAgICAgICAgICAgIGF0dGVtcHRDbG9zZSgpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgIG91dHN0YW5kaW5nVG9vbFJlc3VsdHMuZGVsZXRlKHRvb2xFeGVjdXRpb25JZCk7XG4gICAgICAgICAgICAgICAgICBhdHRlbXB0Q2xvc2UoKTtcblxuICAgICAgICAgICAgICAgICAgLy8gcmVjb3JkIHRlbGVtZXRyeVxuICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGVzKFxuICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgICAgICAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAnYWkudG9vbENhbGwucmVzdWx0Jzoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dDogKCkgPT4gSlNPTi5zdHJpbmdpZnkob3V0cHV0KSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICB9IGNhdGNoIChpZ25vcmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEpTT04gc3RyaW5naWZ5IG1pZ2h0IGZhaWwgaWYgdGhlIHJlc3VsdCBpcyBub3Qgc2VyaWFsaXphYmxlLFxuICAgICAgICAgICAgICAgICAgICAvLyBpbiB3aGljaCBjYXNlIHdlIGp1c3QgaWdub3JlIGl0LiBJbiB0aGUgZnV0dXJlIHdlIG1pZ2h0IHdhbnQgdG9cbiAgICAgICAgICAgICAgICAgICAgLy8gYWRkIGFuIG9wdGlvbmFsIHNlcmlhbGl6ZSBtZXRob2QgdG8gdGhlIHRvb2wgaW50ZXJmYWNlIGFuZCB3YXJuXG4gICAgICAgICAgICAgICAgICAgIC8vIGlmIHRoZSByZXN1bHQgaXMgbm90IHNlcmlhbGl6YWJsZS5cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgdG9vbFJlc3VsdHNTdHJlYW1Db250cm9sbGVyIS5lbnF1ZXVlKHsgdHlwZTogJ2Vycm9yJywgZXJyb3IgfSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBjYXNlICd0b29sLXJlc3VsdCc6IHtcbiAgICAgICAgICBjb25zdCB0b29sTmFtZSA9IGNodW5rLnRvb2xOYW1lIGFzIGtleW9mIFRPT0xTICYgc3RyaW5nO1xuXG4gICAgICAgICAgaWYgKGNodW5rLmlzRXJyb3IpIHtcbiAgICAgICAgICAgIHRvb2xSZXN1bHRzU3RyZWFtQ29udHJvbGxlciEuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgIHR5cGU6ICd0b29sLWVycm9yJyxcbiAgICAgICAgICAgICAgdG9vbENhbGxJZDogY2h1bmsudG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgdG9vbE5hbWUsXG4gICAgICAgICAgICAgIGlucHV0OiB0b29sSW5wdXRzLmdldChjaHVuay50b29sQ2FsbElkKSxcbiAgICAgICAgICAgICAgcHJvdmlkZXJFeGVjdXRlZDogY2h1bmsucHJvdmlkZXJFeGVjdXRlZCxcbiAgICAgICAgICAgICAgZXJyb3I6IGNodW5rLnJlc3VsdCxcbiAgICAgICAgICAgIH0gYXMgVHlwZWRUb29sRXJyb3I8VE9PTFM+KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHtcbiAgICAgICAgICAgICAgdHlwZTogJ3Rvb2wtcmVzdWx0JyxcbiAgICAgICAgICAgICAgdG9vbENhbGxJZDogY2h1bmsudG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgdG9vbE5hbWUsXG4gICAgICAgICAgICAgIGlucHV0OiB0b29sSW5wdXRzLmdldChjaHVuay50b29sQ2FsbElkKSxcbiAgICAgICAgICAgICAgb3V0cHV0OiBjaHVuay5yZXN1bHQsXG4gICAgICAgICAgICAgIHByb3ZpZGVyRXhlY3V0ZWQ6IGNodW5rLnByb3ZpZGVyRXhlY3V0ZWQsXG4gICAgICAgICAgICB9IGFzIFR5cGVkVG9vbFJlc3VsdDxUT09MUz4pO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICBjb25zdCBfZXhoYXVzdGl2ZUNoZWNrOiBuZXZlciA9IGNodW5rVHlwZTtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuaGFuZGxlZCBjaHVuayB0eXBlOiAke19leGhhdXN0aXZlQ2hlY2t9YCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuXG4gICAgZmx1c2goKSB7XG4gICAgICBjYW5DbG9zZSA9IHRydWU7XG4gICAgICBhdHRlbXB0Q2xvc2UoKTtcbiAgICB9LFxuICB9KTtcblxuICAvLyBjb21iaW5lIHRoZSBnZW5lcmF0b3Igc3RyZWFtIGFuZCB0aGUgdG9vbCByZXN1bHRzIHN0cmVhbVxuICByZXR1cm4gbmV3IFJlYWRhYmxlU3RyZWFtPFNpbmdsZVJlcXVlc3RUZXh0U3RyZWFtUGFydDxUT09MUz4+KHtcbiAgICBhc3luYyBzdGFydChjb250cm9sbGVyKSB7XG4gICAgICAvLyBuZWVkIHRvIHdhaXQgZm9yIGJvdGggcGlwZXMgc28gdGhlcmUgYXJlIG5vIGRhbmdsaW5nIHByb21pc2VzIHRoYXRcbiAgICAgIC8vIGNhbiBjYXVzZSB1bmNhdWdodCBwcm9taXNlIHJlamVjdGlvbnMgd2hlbiB0aGUgc3RyZWFtIGlzIGFib3J0ZWRcbiAgICAgIHJldHVybiBQcm9taXNlLmFsbChbXG4gICAgICAgIGdlbmVyYXRvclN0cmVhbS5waXBlVGhyb3VnaChmb3J3YXJkU3RyZWFtKS5waXBlVG8oXG4gICAgICAgICAgbmV3IFdyaXRhYmxlU3RyZWFtKHtcbiAgICAgICAgICAgIHdyaXRlKGNodW5rKSB7XG4gICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShjaHVuayk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY2xvc2UoKSB7XG4gICAgICAgICAgICAgIC8vIHRoZSBnZW5lcmF0b3Igc3RyZWFtIGNvbnRyb2xsZXIgaXMgYXV0b21hdGljYWxseSBjbG9zZWQgd2hlbiBpdCdzIGNvbnN1bWVkXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pLFxuICAgICAgICApLFxuICAgICAgICB0b29sUmVzdWx0c1N0cmVhbS5waXBlVG8oXG4gICAgICAgICAgbmV3IFdyaXRhYmxlU3RyZWFtKHtcbiAgICAgICAgICAgIHdyaXRlKGNodW5rKSB7XG4gICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShjaHVuayk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY2xvc2UoKSB7XG4gICAgICAgICAgICAgIGNvbnRyb2xsZXIuY2xvc2UoKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSksXG4gICAgICAgICksXG4gICAgICBdKTtcbiAgICB9LFxuICB9KTtcbn1cbiIsICJpbXBvcnQge1xuICBBc3Npc3RhbnRDb250ZW50LFxuICBNb2RlbE1lc3NhZ2UsXG4gIFRvb2xSZXN1bHRQYXJ0LFxufSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyLXV0aWxzJztcbmltcG9ydCB7IFRvb2xTZXQgfSBmcm9tICcuLi9nZW5lcmF0ZS10ZXh0L3Rvb2wtc2V0JztcbmltcG9ydCB7IGNyZWF0ZVRvb2xNb2RlbE91dHB1dCB9IGZyb20gJy4uL3Byb21wdC9jcmVhdGUtdG9vbC1tb2RlbC1vdXRwdXQnO1xuaW1wb3J0IHsgTWVzc2FnZUNvbnZlcnNpb25FcnJvciB9IGZyb20gJy4uL3Byb21wdC9tZXNzYWdlLWNvbnZlcnNpb24tZXJyb3InO1xuaW1wb3J0IHtcbiAgRHluYW1pY1Rvb2xVSVBhcnQsXG4gIEZpbGVVSVBhcnQsXG4gIGdldFRvb2xOYW1lLFxuICBpc1Rvb2xPckR5bmFtaWNUb29sVUlQYXJ0LFxuICBpc1Rvb2xVSVBhcnQsXG4gIFJlYXNvbmluZ1VJUGFydCxcbiAgVGV4dFVJUGFydCxcbiAgVG9vbFVJUGFydCxcbiAgVUlNZXNzYWdlLFxuICBVSVRvb2xzLFxufSBmcm9tICcuL3VpLW1lc3NhZ2VzJztcblxuLyoqXG5Db252ZXJ0cyBhbiBhcnJheSBvZiBVSSBtZXNzYWdlcyBmcm9tIHVzZUNoYXQgaW50byBhbiBhcnJheSBvZiBNb2RlbE1lc3NhZ2VzIHRoYXQgY2FuIGJlIHVzZWRcbndpdGggdGhlIEFJIGZ1bmN0aW9ucyAoZS5nLiBgc3RyZWFtVGV4dGAsIGBnZW5lcmF0ZVRleHRgKS5cblxuQHBhcmFtIG1lc3NhZ2VzIC0gVGhlIFVJIG1lc3NhZ2VzIHRvIGNvbnZlcnQuXG5AcGFyYW0gb3B0aW9ucy50b29scyAtIFRoZSB0b29scyB0byB1c2UuXG5AcGFyYW0gb3B0aW9ucy5pZ25vcmVJbmNvbXBsZXRlVG9vbENhbGxzIC0gV2hldGhlciB0byBpZ25vcmUgaW5jb21wbGV0ZSB0b29sIGNhbGxzLiBEZWZhdWx0IGlzIGBmYWxzZWAuXG5cbkByZXR1cm5zIEFuIGFycmF5IG9mIE1vZGVsTWVzc2FnZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb252ZXJ0VG9Nb2RlbE1lc3NhZ2VzKFxuICBtZXNzYWdlczogQXJyYXk8T21pdDxVSU1lc3NhZ2UsICdpZCc+PixcbiAgb3B0aW9ucz86IHtcbiAgICB0b29scz86IFRvb2xTZXQ7XG4gICAgaWdub3JlSW5jb21wbGV0ZVRvb2xDYWxscz86IGJvb2xlYW47XG4gIH0sXG4pOiBNb2RlbE1lc3NhZ2VbXSB7XG4gIGNvbnN0IG1vZGVsTWVzc2FnZXM6IE1vZGVsTWVzc2FnZVtdID0gW107XG5cbiAgaWYgKG9wdGlvbnM/Lmlnbm9yZUluY29tcGxldGVUb29sQ2FsbHMpIHtcbiAgICBtZXNzYWdlcyA9IG1lc3NhZ2VzLm1hcChtZXNzYWdlID0+ICh7XG4gICAgICAuLi5tZXNzYWdlLFxuICAgICAgcGFydHM6IG1lc3NhZ2UucGFydHMuZmlsdGVyKFxuICAgICAgICBwYXJ0ID0+XG4gICAgICAgICAgIWlzVG9vbE9yRHluYW1pY1Rvb2xVSVBhcnQocGFydCkgfHxcbiAgICAgICAgICAocGFydC5zdGF0ZSAhPT0gJ2lucHV0LXN0cmVhbWluZycgJiZcbiAgICAgICAgICAgIHBhcnQuc3RhdGUgIT09ICdpbnB1dC1hdmFpbGFibGUnKSxcbiAgICAgICksXG4gICAgfSkpO1xuICB9XG5cbiAgZm9yIChjb25zdCBtZXNzYWdlIG9mIG1lc3NhZ2VzKSB7XG4gICAgc3dpdGNoIChtZXNzYWdlLnJvbGUpIHtcbiAgICAgIGNhc2UgJ3N5c3RlbSc6IHtcbiAgICAgICAgY29uc3QgdGV4dFBhcnRzID0gbWVzc2FnZS5wYXJ0cy5maWx0ZXIocGFydCA9PiBwYXJ0LnR5cGUgPT09ICd0ZXh0Jyk7XG5cbiAgICAgICAgY29uc3QgcHJvdmlkZXJNZXRhZGF0YSA9IHRleHRQYXJ0cy5yZWR1Y2UoKGFjYywgcGFydCkgPT4ge1xuICAgICAgICAgIGlmIChwYXJ0LnByb3ZpZGVyTWV0YWRhdGEgIT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIHsgLi4uYWNjLCAuLi5wYXJ0LnByb3ZpZGVyTWV0YWRhdGEgfTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgICAgfSwge30pO1xuXG4gICAgICAgIG1vZGVsTWVzc2FnZXMucHVzaCh7XG4gICAgICAgICAgcm9sZTogJ3N5c3RlbScsXG4gICAgICAgICAgY29udGVudDogdGV4dFBhcnRzLm1hcChwYXJ0ID0+IHBhcnQudGV4dCkuam9pbignJyksXG4gICAgICAgICAgLi4uKE9iamVjdC5rZXlzKHByb3ZpZGVyTWV0YWRhdGEpLmxlbmd0aCA+IDBcbiAgICAgICAgICAgID8geyBwcm92aWRlck9wdGlvbnM6IHByb3ZpZGVyTWV0YWRhdGEgfVxuICAgICAgICAgICAgOiB7fSksXG4gICAgICAgIH0pO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgY2FzZSAndXNlcic6IHtcbiAgICAgICAgbW9kZWxNZXNzYWdlcy5wdXNoKHtcbiAgICAgICAgICByb2xlOiAndXNlcicsXG4gICAgICAgICAgY29udGVudDogbWVzc2FnZS5wYXJ0c1xuICAgICAgICAgICAgLmZpbHRlcihcbiAgICAgICAgICAgICAgKHBhcnQpOiBwYXJ0IGlzIFRleHRVSVBhcnQgfCBGaWxlVUlQYXJ0ID0+XG4gICAgICAgICAgICAgICAgcGFydC50eXBlID09PSAndGV4dCcgfHwgcGFydC50eXBlID09PSAnZmlsZScsXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAubWFwKHBhcnQgPT4ge1xuICAgICAgICAgICAgICBzd2l0Y2ggKHBhcnQudHlwZSkge1xuICAgICAgICAgICAgICAgIGNhc2UgJ3RleHQnOlxuICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3RleHQnIGFzIGNvbnN0LFxuICAgICAgICAgICAgICAgICAgICB0ZXh0OiBwYXJ0LnRleHQsXG4gICAgICAgICAgICAgICAgICAgIC4uLihwYXJ0LnByb3ZpZGVyTWV0YWRhdGEgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgICAgID8geyBwcm92aWRlck9wdGlvbnM6IHBhcnQucHJvdmlkZXJNZXRhZGF0YSB9XG4gICAgICAgICAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGNhc2UgJ2ZpbGUnOlxuICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2ZpbGUnIGFzIGNvbnN0LFxuICAgICAgICAgICAgICAgICAgICBtZWRpYVR5cGU6IHBhcnQubWVkaWFUeXBlLFxuICAgICAgICAgICAgICAgICAgICBmaWxlbmFtZTogcGFydC5maWxlbmFtZSxcbiAgICAgICAgICAgICAgICAgICAgZGF0YTogcGFydC51cmwsXG4gICAgICAgICAgICAgICAgICAgIC4uLihwYXJ0LnByb3ZpZGVyTWV0YWRhdGEgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgICAgID8geyBwcm92aWRlck9wdGlvbnM6IHBhcnQucHJvdmlkZXJNZXRhZGF0YSB9XG4gICAgICAgICAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICByZXR1cm4gcGFydDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSksXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBjYXNlICdhc3Npc3RhbnQnOiB7XG4gICAgICAgIGlmIChtZXNzYWdlLnBhcnRzICE9IG51bGwpIHtcbiAgICAgICAgICBsZXQgYmxvY2s6IEFycmF5PFxuICAgICAgICAgICAgfCBUZXh0VUlQYXJ0XG4gICAgICAgICAgICB8IFRvb2xVSVBhcnQ8VUlUb29scz5cbiAgICAgICAgICAgIHwgUmVhc29uaW5nVUlQYXJ0XG4gICAgICAgICAgICB8IEZpbGVVSVBhcnRcbiAgICAgICAgICAgIHwgRHluYW1pY1Rvb2xVSVBhcnRcbiAgICAgICAgICA+ID0gW107XG5cbiAgICAgICAgICBmdW5jdGlvbiBwcm9jZXNzQmxvY2soKSB7XG4gICAgICAgICAgICBpZiAoYmxvY2subGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgY29udGVudDogQXNzaXN0YW50Q29udGVudCA9IFtdO1xuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHBhcnQgb2YgYmxvY2spIHtcbiAgICAgICAgICAgICAgaWYgKHBhcnQudHlwZSA9PT0gJ3RleHQnKSB7XG4gICAgICAgICAgICAgICAgY29udGVudC5wdXNoKHtcbiAgICAgICAgICAgICAgICAgIHR5cGU6ICd0ZXh0JyBhcyBjb25zdCxcbiAgICAgICAgICAgICAgICAgIHRleHQ6IHBhcnQudGV4dCxcbiAgICAgICAgICAgICAgICAgIC4uLihwYXJ0LnByb3ZpZGVyTWV0YWRhdGEgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgICA/IHsgcHJvdmlkZXJPcHRpb25zOiBwYXJ0LnByb3ZpZGVyTWV0YWRhdGEgfVxuICAgICAgICAgICAgICAgICAgICA6IHt9KSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfSBlbHNlIGlmIChwYXJ0LnR5cGUgPT09ICdmaWxlJykge1xuICAgICAgICAgICAgICAgIGNvbnRlbnQucHVzaCh7XG4gICAgICAgICAgICAgICAgICB0eXBlOiAnZmlsZScgYXMgY29uc3QsXG4gICAgICAgICAgICAgICAgICBtZWRpYVR5cGU6IHBhcnQubWVkaWFUeXBlLFxuICAgICAgICAgICAgICAgICAgZmlsZW5hbWU6IHBhcnQuZmlsZW5hbWUsXG4gICAgICAgICAgICAgICAgICBkYXRhOiBwYXJ0LnVybCxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfSBlbHNlIGlmIChwYXJ0LnR5cGUgPT09ICdyZWFzb25pbmcnKSB7XG4gICAgICAgICAgICAgICAgY29udGVudC5wdXNoKHtcbiAgICAgICAgICAgICAgICAgIHR5cGU6ICdyZWFzb25pbmcnIGFzIGNvbnN0LFxuICAgICAgICAgICAgICAgICAgdGV4dDogcGFydC50ZXh0LFxuICAgICAgICAgICAgICAgICAgcHJvdmlkZXJPcHRpb25zOiBwYXJ0LnByb3ZpZGVyTWV0YWRhdGEsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAocGFydC50eXBlID09PSAnZHluYW1pYy10b29sJykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRvb2xOYW1lID0gcGFydC50b29sTmFtZTtcblxuICAgICAgICAgICAgICAgIGlmIChwYXJ0LnN0YXRlICE9PSAnaW5wdXQtc3RyZWFtaW5nJykge1xuICAgICAgICAgICAgICAgICAgY29udGVudC5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3Rvb2wtY2FsbCcgYXMgY29uc3QsXG4gICAgICAgICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IHBhcnQudG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgICAgICAgdG9vbE5hbWUsXG4gICAgICAgICAgICAgICAgICAgIGlucHV0OiBwYXJ0LmlucHV0LFxuICAgICAgICAgICAgICAgICAgICAuLi4ocGFydC5jYWxsUHJvdmlkZXJNZXRhZGF0YSAhPSBudWxsXG4gICAgICAgICAgICAgICAgICAgICAgPyB7IHByb3ZpZGVyT3B0aW9uczogcGFydC5jYWxsUHJvdmlkZXJNZXRhZGF0YSB9XG4gICAgICAgICAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNUb29sVUlQYXJ0KHBhcnQpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdG9vbE5hbWUgPSBnZXRUb29sTmFtZShwYXJ0KTtcblxuICAgICAgICAgICAgICAgIGlmIChwYXJ0LnN0YXRlICE9PSAnaW5wdXQtc3RyZWFtaW5nJykge1xuICAgICAgICAgICAgICAgICAgY29udGVudC5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3Rvb2wtY2FsbCcgYXMgY29uc3QsXG4gICAgICAgICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IHBhcnQudG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgICAgICAgdG9vbE5hbWUsXG4gICAgICAgICAgICAgICAgICAgIGlucHV0OlxuICAgICAgICAgICAgICAgICAgICAgIHBhcnQuc3RhdGUgPT09ICdvdXRwdXQtZXJyb3InXG4gICAgICAgICAgICAgICAgICAgICAgICA/IChwYXJ0LmlucHV0ID8/IHBhcnQucmF3SW5wdXQpXG4gICAgICAgICAgICAgICAgICAgICAgICA6IHBhcnQuaW5wdXQsXG4gICAgICAgICAgICAgICAgICAgIHByb3ZpZGVyRXhlY3V0ZWQ6IHBhcnQucHJvdmlkZXJFeGVjdXRlZCxcbiAgICAgICAgICAgICAgICAgICAgLi4uKHBhcnQuY2FsbFByb3ZpZGVyTWV0YWRhdGEgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgICAgID8geyBwcm92aWRlck9wdGlvbnM6IHBhcnQuY2FsbFByb3ZpZGVyTWV0YWRhdGEgfVxuICAgICAgICAgICAgICAgICAgICAgIDoge30pLFxuICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgcGFydC5wcm92aWRlckV4ZWN1dGVkID09PSB0cnVlICYmXG4gICAgICAgICAgICAgICAgICAgIChwYXJ0LnN0YXRlID09PSAnb3V0cHV0LWF2YWlsYWJsZScgfHxcbiAgICAgICAgICAgICAgICAgICAgICBwYXJ0LnN0YXRlID09PSAnb3V0cHV0LWVycm9yJylcbiAgICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICBjb250ZW50LnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICd0b29sLXJlc3VsdCcsXG4gICAgICAgICAgICAgICAgICAgICAgdG9vbENhbGxJZDogcGFydC50b29sQ2FsbElkLFxuICAgICAgICAgICAgICAgICAgICAgIHRvb2xOYW1lLFxuICAgICAgICAgICAgICAgICAgICAgIG91dHB1dDogY3JlYXRlVG9vbE1vZGVsT3V0cHV0KHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcGFydC5zdGF0ZSA9PT0gJ291dHB1dC1lcnJvcidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHBhcnQuZXJyb3JUZXh0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBwYXJ0Lm91dHB1dCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvb2w6IG9wdGlvbnM/LnRvb2xzPy5bdG9vbE5hbWVdLFxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNb2RlOlxuICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJ0LnN0YXRlID09PSAnb3V0cHV0LWVycm9yJyA/ICdqc29uJyA6ICdub25lJyxcbiAgICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IF9leGhhdXN0aXZlQ2hlY2s6IG5ldmVyID0gcGFydDtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIHBhcnQ6ICR7X2V4aGF1c3RpdmVDaGVja31gKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBtb2RlbE1lc3NhZ2VzLnB1c2goe1xuICAgICAgICAgICAgICByb2xlOiAnYXNzaXN0YW50JyxcbiAgICAgICAgICAgICAgY29udGVudCxcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyBjaGVjayBpZiB0aGVyZSBhcmUgdG9vbCBpbnZvY2F0aW9ucyB3aXRoIHJlc3VsdHMgaW4gdGhlIGJsb2NrXG4gICAgICAgICAgICBjb25zdCB0b29sUGFydHMgPSBibG9jay5maWx0ZXIoXG4gICAgICAgICAgICAgIHBhcnQgPT5cbiAgICAgICAgICAgICAgICAoaXNUb29sVUlQYXJ0KHBhcnQpICYmIHBhcnQucHJvdmlkZXJFeGVjdXRlZCAhPT0gdHJ1ZSkgfHxcbiAgICAgICAgICAgICAgICBwYXJ0LnR5cGUgPT09ICdkeW5hbWljLXRvb2wnLFxuICAgICAgICAgICAgKSBhcyAoVG9vbFVJUGFydDxVSVRvb2xzPiB8IER5bmFtaWNUb29sVUlQYXJ0KVtdO1xuXG4gICAgICAgICAgICAvLyB0b29sIG1lc3NhZ2Ugd2l0aCB0b29sIHJlc3VsdHNcbiAgICAgICAgICAgIGlmICh0b29sUGFydHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICBtb2RlbE1lc3NhZ2VzLnB1c2goe1xuICAgICAgICAgICAgICAgIHJvbGU6ICd0b29sJyxcbiAgICAgICAgICAgICAgICBjb250ZW50OiB0b29sUGFydHNcbiAgICAgICAgICAgICAgICAgIC5tYXAoKHRvb2xQYXJ0KTogVG9vbFJlc3VsdFBhcnQgfCBudWxsID0+IHtcbiAgICAgICAgICAgICAgICAgICAgc3dpdGNoICh0b29sUGFydC5zdGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ291dHB1dC1lcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgY2FzZSAnb3V0cHV0LWF2YWlsYWJsZSc6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRvb2xOYW1lID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgdG9vbFBhcnQudHlwZSA9PT0gJ2R5bmFtaWMtdG9vbCdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHRvb2xQYXJ0LnRvb2xOYW1lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBnZXRUb29sTmFtZSh0b29sUGFydCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICd0b29sLXJlc3VsdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IHRvb2xQYXJ0LnRvb2xDYWxsSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHRvb2xOYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQ6IGNyZWF0ZVRvb2xNb2RlbE91dHB1dCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0OlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9vbFBhcnQuc3RhdGUgPT09ICdvdXRwdXQtZXJyb3InXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gdG9vbFBhcnQuZXJyb3JUZXh0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogdG9vbFBhcnQub3V0cHV0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvb2w6IG9wdGlvbnM/LnRvb2xzPy5bdG9vbE5hbWVdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTW9kZTpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvb2xQYXJ0LnN0YXRlID09PSAnb3V0cHV0LWVycm9yJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/ICd0ZXh0J1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICdub25lJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAuZmlsdGVyKFxuICAgICAgICAgICAgICAgICAgICAob3V0cHV0KTogb3V0cHV0IGlzIE5vbk51bGxhYmxlPHR5cGVvZiBvdXRwdXQ+ID0+XG4gICAgICAgICAgICAgICAgICAgICAgb3V0cHV0ICE9IG51bGwsXG4gICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gdXBkYXRlcyBmb3IgbmV4dCBibG9ja1xuICAgICAgICAgICAgYmxvY2sgPSBbXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBmb3IgKGNvbnN0IHBhcnQgb2YgbWVzc2FnZS5wYXJ0cykge1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICBwYXJ0LnR5cGUgPT09ICd0ZXh0JyB8fFxuICAgICAgICAgICAgICBwYXJ0LnR5cGUgPT09ICdyZWFzb25pbmcnIHx8XG4gICAgICAgICAgICAgIHBhcnQudHlwZSA9PT0gJ2ZpbGUnIHx8XG4gICAgICAgICAgICAgIHBhcnQudHlwZSA9PT0gJ2R5bmFtaWMtdG9vbCcgfHxcbiAgICAgICAgICAgICAgaXNUb29sVUlQYXJ0KHBhcnQpXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgYmxvY2sucHVzaChwYXJ0KTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocGFydC50eXBlID09PSAnc3RlcC1zdGFydCcpIHtcbiAgICAgICAgICAgICAgcHJvY2Vzc0Jsb2NrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcHJvY2Vzc0Jsb2NrKCk7XG5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBkZWZhdWx0OiB7XG4gICAgICAgIGNvbnN0IF9leGhhdXN0aXZlQ2hlY2s6IG5ldmVyID0gbWVzc2FnZS5yb2xlO1xuICAgICAgICB0aHJvdyBuZXcgTWVzc2FnZUNvbnZlcnNpb25FcnJvcih7XG4gICAgICAgICAgb3JpZ2luYWxNZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgICAgIG1lc3NhZ2U6IGBVbnN1cHBvcnRlZCByb2xlOiAke19leGhhdXN0aXZlQ2hlY2t9YCxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG1vZGVsTWVzc2FnZXM7XG59XG5cbi8qKlxuQGRlcHJlY2F0ZWQgVXNlIGBjb252ZXJ0VG9Nb2RlbE1lc3NhZ2VzYCBpbnN0ZWFkLlxuICovXG4vLyBUT0RPIHJlbW92ZSBpbiBBSSBTREsgNlxuZXhwb3J0IGNvbnN0IGNvbnZlcnRUb0NvcmVNZXNzYWdlcyA9IGNvbnZlcnRUb01vZGVsTWVzc2FnZXM7XG4iLCAiaW1wb3J0IHsgSWRHZW5lcmF0b3IsIFByb3ZpZGVyT3B0aW9ucyB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXItdXRpbHMnO1xuaW1wb3J0IHtcbiAgZ2VuZXJhdGVUZXh0LFxuICBHZW5lcmF0ZVRleHRPblN0ZXBGaW5pc2hDYWxsYmFjayxcbn0gZnJvbSAnLi4vZ2VuZXJhdGUtdGV4dC9nZW5lcmF0ZS10ZXh0JztcbmltcG9ydCB7IEdlbmVyYXRlVGV4dFJlc3VsdCB9IGZyb20gJy4uL2dlbmVyYXRlLXRleHQvZ2VuZXJhdGUtdGV4dC1yZXN1bHQnO1xuaW1wb3J0IHsgT3V0cHV0IH0gZnJvbSAnLi4vZ2VuZXJhdGUtdGV4dC9vdXRwdXQnO1xuaW1wb3J0IHsgUHJlcGFyZVN0ZXBGdW5jdGlvbiB9IGZyb20gJy4uL2dlbmVyYXRlLXRleHQvcHJlcGFyZS1zdGVwJztcbmltcG9ydCB7IFN0b3BDb25kaXRpb24gfSBmcm9tICcuLi9nZW5lcmF0ZS10ZXh0L3N0b3AtY29uZGl0aW9uJztcbmltcG9ydCB7IHN0cmVhbVRleHQgfSBmcm9tICcuLi9nZW5lcmF0ZS10ZXh0L3N0cmVhbS10ZXh0JztcbmltcG9ydCB7IFN0cmVhbVRleHRSZXN1bHQgfSBmcm9tICcuLi9nZW5lcmF0ZS10ZXh0L3N0cmVhbS10ZXh0LXJlc3VsdCc7XG5pbXBvcnQgeyBUb29sQ2FsbFJlcGFpckZ1bmN0aW9uIH0gZnJvbSAnLi4vZ2VuZXJhdGUtdGV4dC90b29sLWNhbGwtcmVwYWlyLWZ1bmN0aW9uJztcbmltcG9ydCB7IFRvb2xTZXQgfSBmcm9tICcuLi9nZW5lcmF0ZS10ZXh0L3Rvb2wtc2V0JztcbmltcG9ydCB7IENhbGxTZXR0aW5ncyB9IGZyb20gJy4uL3Byb21wdC9jYWxsLXNldHRpbmdzJztcbmltcG9ydCB7IFByb21wdCB9IGZyb20gJy4uL3Byb21wdC9wcm9tcHQnO1xuaW1wb3J0IHsgVGVsZW1ldHJ5U2V0dGluZ3MgfSBmcm9tICcuLi90ZWxlbWV0cnkvdGVsZW1ldHJ5LXNldHRpbmdzJztcbmltcG9ydCB7IExhbmd1YWdlTW9kZWwsIFRvb2xDaG9pY2UgfSBmcm9tICcuLi90eXBlcy9sYW5ndWFnZS1tb2RlbCc7XG5pbXBvcnQgeyBQcm92aWRlck1ldGFkYXRhIH0gZnJvbSAnLi4vdHlwZXMvcHJvdmlkZXItbWV0YWRhdGEnO1xuaW1wb3J0IHsgY29udmVydFRvTW9kZWxNZXNzYWdlcyB9IGZyb20gJy4uL3VpL2NvbnZlcnQtdG8tbW9kZWwtbWVzc2FnZXMnO1xuaW1wb3J0IHsgSW5mZXJVSVRvb2xzLCBVSU1lc3NhZ2UgfSBmcm9tICcuLi91aS91aS1tZXNzYWdlcyc7XG5cbmV4cG9ydCB0eXBlIEFnZW50U2V0dGluZ3M8XG4gIFRPT0xTIGV4dGVuZHMgVG9vbFNldCxcbiAgT1VUUFVUID0gbmV2ZXIsXG4gIE9VVFBVVF9QQVJUSUFMID0gbmV2ZXIsXG4+ID0gQ2FsbFNldHRpbmdzICYge1xuICAvKipcbiAgICogVGhlIHN5c3RlbSBwcm9tcHQgdG8gdXNlLlxuICAgKi9cbiAgc3lzdGVtPzogc3RyaW5nO1xuXG4gIC8qKlxuVGhlIGxhbmd1YWdlIG1vZGVsIHRvIHVzZS5cbiAgICovXG4gIG1vZGVsOiBMYW5ndWFnZU1vZGVsO1xuXG4gIC8qKlxuVGhlIHRvb2xzIHRoYXQgdGhlIG1vZGVsIGNhbiBjYWxsLiBUaGUgbW9kZWwgbmVlZHMgdG8gc3VwcG9ydCBjYWxsaW5nIHRvb2xzLlxuKi9cbiAgdG9vbHM/OiBUT09MUztcblxuICAvKipcblRoZSB0b29sIGNob2ljZSBzdHJhdGVneS4gRGVmYXVsdDogJ2F1dG8nLlxuICAgKi9cbiAgdG9vbENob2ljZT86IFRvb2xDaG9pY2U8Tm9JbmZlcjxUT09MUz4+O1xuXG4gIC8qKlxuQ29uZGl0aW9uIGZvciBzdG9wcGluZyB0aGUgZ2VuZXJhdGlvbiB3aGVuIHRoZXJlIGFyZSB0b29sIHJlc3VsdHMgaW4gdGhlIGxhc3Qgc3RlcC5cbldoZW4gdGhlIGNvbmRpdGlvbiBpcyBhbiBhcnJheSwgYW55IG9mIHRoZSBjb25kaXRpb25zIGNhbiBiZSBtZXQgdG8gc3RvcCB0aGUgZ2VuZXJhdGlvbi5cblxuQGRlZmF1bHQgc3RlcENvdW50SXMoMSlcbiAgICovXG4gIHN0b3BXaGVuPzpcbiAgICB8IFN0b3BDb25kaXRpb248Tm9JbmZlcjxUT09MUz4+XG4gICAgfCBBcnJheTxTdG9wQ29uZGl0aW9uPE5vSW5mZXI8VE9PTFM+Pj47XG5cbiAgLyoqXG5PcHRpb25hbCB0ZWxlbWV0cnkgY29uZmlndXJhdGlvbiAoZXhwZXJpbWVudGFsKS5cbiAgICovXG4gIGV4cGVyaW1lbnRhbF90ZWxlbWV0cnk/OiBUZWxlbWV0cnlTZXR0aW5ncztcblxuICAvKipcbkxpbWl0cyB0aGUgdG9vbHMgdGhhdCBhcmUgYXZhaWxhYmxlIGZvciB0aGUgbW9kZWwgdG8gY2FsbCB3aXRob3V0XG5jaGFuZ2luZyB0aGUgdG9vbCBjYWxsIGFuZCByZXN1bHQgdHlwZXMgaW4gdGhlIHJlc3VsdC5cbiAgICovXG4gIGFjdGl2ZVRvb2xzPzogQXJyYXk8a2V5b2YgTm9JbmZlcjxUT09MUz4+O1xuXG4gIC8qKlxuT3B0aW9uYWwgc3BlY2lmaWNhdGlvbiBmb3IgcGFyc2luZyBzdHJ1Y3R1cmVkIG91dHB1dHMgZnJvbSB0aGUgTExNIHJlc3BvbnNlLlxuICAgKi9cbiAgZXhwZXJpbWVudGFsX291dHB1dD86IE91dHB1dDxPVVRQVVQsIE9VVFBVVF9QQVJUSUFMPjtcblxuICAvKipcbiAgICogQGRlcHJlY2F0ZWQgVXNlIGBwcmVwYXJlU3RlcGAgaW5zdGVhZC5cbiAgICovXG4gIGV4cGVyaW1lbnRhbF9wcmVwYXJlU3RlcD86IFByZXBhcmVTdGVwRnVuY3Rpb248Tm9JbmZlcjxUT09MUz4+O1xuXG4gIC8qKlxuT3B0aW9uYWwgZnVuY3Rpb24gdGhhdCB5b3UgY2FuIHVzZSB0byBwcm92aWRlIGRpZmZlcmVudCBzZXR0aW5ncyBmb3IgYSBzdGVwLlxuICAqL1xuICBwcmVwYXJlU3RlcD86IFByZXBhcmVTdGVwRnVuY3Rpb248Tm9JbmZlcjxUT09MUz4+O1xuXG4gIC8qKlxuQSBmdW5jdGlvbiB0aGF0IGF0dGVtcHRzIHRvIHJlcGFpciBhIHRvb2wgY2FsbCB0aGF0IGZhaWxlZCB0byBwYXJzZS5cbiAgICovXG4gIGV4cGVyaW1lbnRhbF9yZXBhaXJUb29sQ2FsbD86IFRvb2xDYWxsUmVwYWlyRnVuY3Rpb248Tm9JbmZlcjxUT09MUz4+O1xuXG4gIC8qKlxuICBDYWxsYmFjayB0aGF0IGlzIGNhbGxlZCB3aGVuIGVhY2ggc3RlcCAoTExNIGNhbGwpIGlzIGZpbmlzaGVkLCBpbmNsdWRpbmcgaW50ZXJtZWRpYXRlIHN0ZXBzLlxuICAqL1xuICBvblN0ZXBGaW5pc2g/OiBHZW5lcmF0ZVRleHRPblN0ZXBGaW5pc2hDYWxsYmFjazxOb0luZmVyPFRPT0xTPj47XG5cbiAgLyoqXG4gICAqIENvbnRleHQgdGhhdCBpcyBwYXNzZWQgaW50byB0b29sIGNhbGxzLlxuICAgKlxuICAgKiBFeHBlcmltZW50YWwgKGNhbiBicmVhayBpbiBwYXRjaCByZWxlYXNlcykuXG4gICAqXG4gICAqIEBkZWZhdWx0IHVuZGVmaW5lZFxuICAgKi9cbiAgZXhwZXJpbWVudGFsX2NvbnRleHQ/OiB1bmtub3duO1xuXG4gIC8qKlxuICAgKiBJbnRlcm5hbC4gRm9yIHRlc3QgdXNlIG9ubHkuIE1heSBjaGFuZ2Ugd2l0aG91dCBub3RpY2UuXG4gICAqL1xuICBfaW50ZXJuYWw/OiB7XG4gICAgZ2VuZXJhdGVJZD86IElkR2VuZXJhdG9yO1xuICAgIGN1cnJlbnREYXRlPzogKCkgPT4gRGF0ZTtcbiAgfTtcbn07XG5cbmV4cG9ydCBjbGFzcyBBZ2VudDxcbiAgVE9PTFMgZXh0ZW5kcyBUb29sU2V0LFxuICBPVVRQVVQgPSBuZXZlcixcbiAgT1VUUFVUX1BBUlRJQUwgPSBuZXZlcixcbj4ge1xuICBwcml2YXRlIHJlYWRvbmx5IHNldHRpbmdzOiBBZ2VudFNldHRpbmdzPFRPT0xTLCBPVVRQVVQsIE9VVFBVVF9QQVJUSUFMPjtcblxuICBjb25zdHJ1Y3RvcihzZXR0aW5nczogQWdlbnRTZXR0aW5nczxUT09MUywgT1VUUFVULCBPVVRQVVRfUEFSVElBTD4pIHtcbiAgICB0aGlzLnNldHRpbmdzID0gc2V0dGluZ3M7XG4gIH1cblxuICBnZXQgdG9vbHMoKTogVE9PTFMge1xuICAgIHJldHVybiB0aGlzLnNldHRpbmdzLnRvb2xzIGFzIFRPT0xTO1xuICB9XG5cbiAgYXN5bmMgZ2VuZXJhdGUoXG4gICAgb3B0aW9uczogUHJvbXB0ICYge1xuICAgICAgLyoqXG5BZGRpdGlvbmFsIHByb3ZpZGVyLXNwZWNpZmljIG1ldGFkYXRhLiBUaGV5IGFyZSBwYXNzZWQgdGhyb3VnaFxuZnJvbSB0aGUgcHJvdmlkZXIgdG8gdGhlIEFJIFNESyBhbmQgZW5hYmxlIHByb3ZpZGVyLXNwZWNpZmljXG5yZXN1bHRzIHRoYXQgY2FuIGJlIGZ1bGx5IGVuY2Fwc3VsYXRlZCBpbiB0aGUgcHJvdmlkZXIuXG4gICAqL1xuICAgICAgcHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG4gICAgICAvKipcbkFkZGl0aW9uYWwgcHJvdmlkZXItc3BlY2lmaWMgbWV0YWRhdGEuIFRoZXkgYXJlIHBhc3NlZCB0aHJvdWdoXG50byB0aGUgcHJvdmlkZXIgZnJvbSB0aGUgQUkgU0RLIGFuZCBlbmFibGUgcHJvdmlkZXItc3BlY2lmaWNcbmZ1bmN0aW9uYWxpdHkgdGhhdCBjYW4gYmUgZnVsbHkgZW5jYXBzdWxhdGVkIGluIHRoZSBwcm92aWRlci5cbiAgICAgICAgICovXG4gICAgICBwcm92aWRlck9wdGlvbnM/OiBQcm92aWRlck9wdGlvbnM7XG4gICAgfSxcbiAgKTogUHJvbWlzZTxHZW5lcmF0ZVRleHRSZXN1bHQ8VE9PTFMsIE9VVFBVVD4+IHtcbiAgICByZXR1cm4gZ2VuZXJhdGVUZXh0KHsgLi4udGhpcy5zZXR0aW5ncywgLi4ub3B0aW9ucyB9KTtcbiAgfVxuXG4gIHN0cmVhbShcbiAgICBvcHRpb25zOiBQcm9tcHQgJiB7XG4gICAgICAvKipcbkFkZGl0aW9uYWwgcHJvdmlkZXItc3BlY2lmaWMgbWV0YWRhdGEuIFRoZXkgYXJlIHBhc3NlZCB0aHJvdWdoXG5mcm9tIHRoZSBwcm92aWRlciB0byB0aGUgQUkgU0RLIGFuZCBlbmFibGUgcHJvdmlkZXItc3BlY2lmaWNcbnJlc3VsdHMgdGhhdCBjYW4gYmUgZnVsbHkgZW5jYXBzdWxhdGVkIGluIHRoZSBwcm92aWRlci5cbiAgICovXG4gICAgICBwcm92aWRlck1ldGFkYXRhPzogUHJvdmlkZXJNZXRhZGF0YTtcbiAgICAgIC8qKlxuQWRkaXRpb25hbCBwcm92aWRlci1zcGVjaWZpYyBtZXRhZGF0YS4gVGhleSBhcmUgcGFzc2VkIHRocm91Z2hcbnRvIHRoZSBwcm92aWRlciBmcm9tIHRoZSBBSSBTREsgYW5kIGVuYWJsZSBwcm92aWRlci1zcGVjaWZpY1xuZnVuY3Rpb25hbGl0eSB0aGF0IGNhbiBiZSBmdWxseSBlbmNhcHN1bGF0ZWQgaW4gdGhlIHByb3ZpZGVyLlxuICAgICAgICAgKi9cbiAgICAgIHByb3ZpZGVyT3B0aW9ucz86IFByb3ZpZGVyT3B0aW9ucztcbiAgICB9LFxuICApOiBTdHJlYW1UZXh0UmVzdWx0PFRPT0xTLCBPVVRQVVRfUEFSVElBTD4ge1xuICAgIHJldHVybiBzdHJlYW1UZXh0KHsgLi4udGhpcy5zZXR0aW5ncywgLi4ub3B0aW9ucyB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgcmVzcG9uc2Ugb2JqZWN0IHRoYXQgc3RyZWFtcyBVSSBtZXNzYWdlcyB0byB0aGUgY2xpZW50LlxuICAgKi9cbiAgcmVzcG9uZChvcHRpb25zOiB7XG4gICAgbWVzc2FnZXM6IFVJTWVzc2FnZTxuZXZlciwgbmV2ZXIsIEluZmVyVUlUb29sczxUT09MUz4+W107XG4gIH0pOiBSZXNwb25zZSB7XG4gICAgcmV0dXJuIHRoaXMuc3RyZWFtKHtcbiAgICAgIHByb21wdDogY29udmVydFRvTW9kZWxNZXNzYWdlcyhvcHRpb25zLm1lc3NhZ2VzKSxcbiAgICB9KS50b1VJTWVzc2FnZVN0cmVhbVJlc3BvbnNlPFxuICAgICAgVUlNZXNzYWdlPG5ldmVyLCBuZXZlciwgSW5mZXJVSVRvb2xzPFRPT0xTPj5cbiAgICA+KCk7XG4gIH1cbn1cblxudHlwZSBJbmZlckFnZW50VG9vbHM8QUdFTlQ+ID1cbiAgQUdFTlQgZXh0ZW5kcyBBZ2VudDxpbmZlciBUT09MUywgYW55LCBhbnk+ID8gVE9PTFMgOiBuZXZlcjtcblxuLyoqXG4gKiBJbmZlciB0aGUgVUkgbWVzc2FnZSB0eXBlIG9mIGFuIGFnZW50LlxuICovXG5leHBvcnQgdHlwZSBJbmZlckFnZW50VUlNZXNzYWdlPEFHRU5UPiA9IFVJTWVzc2FnZTxcbiAgbmV2ZXIsXG4gIG5ldmVyLFxuICBJbmZlclVJVG9vbHM8SW5mZXJBZ2VudFRvb2xzPEFHRU5UPj5cbj47XG4iLCAiaW1wb3J0IHsgUHJvdmlkZXJPcHRpb25zLCB3aXRoVXNlckFnZW50U3VmZml4IH0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyByZXNvbHZlRW1iZWRkaW5nTW9kZWwgfSBmcm9tICcuLi9tb2RlbC9yZXNvbHZlLW1vZGVsJztcbmltcG9ydCB7IGFzc2VtYmxlT3BlcmF0aW9uTmFtZSB9IGZyb20gJy4uL3RlbGVtZXRyeS9hc3NlbWJsZS1vcGVyYXRpb24tbmFtZSc7XG5pbXBvcnQgeyBnZXRCYXNlVGVsZW1ldHJ5QXR0cmlidXRlcyB9IGZyb20gJy4uL3RlbGVtZXRyeS9nZXQtYmFzZS10ZWxlbWV0cnktYXR0cmlidXRlcyc7XG5pbXBvcnQgeyBnZXRUcmFjZXIgfSBmcm9tICcuLi90ZWxlbWV0cnkvZ2V0LXRyYWNlcic7XG5pbXBvcnQgeyByZWNvcmRTcGFuIH0gZnJvbSAnLi4vdGVsZW1ldHJ5L3JlY29yZC1zcGFuJztcbmltcG9ydCB7IHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMgfSBmcm9tICcuLi90ZWxlbWV0cnkvc2VsZWN0LXRlbGVtZXRyeS1hdHRyaWJ1dGVzJztcbmltcG9ydCB7IFRlbGVtZXRyeVNldHRpbmdzIH0gZnJvbSAnLi4vdGVsZW1ldHJ5L3RlbGVtZXRyeS1zZXR0aW5ncyc7XG5pbXBvcnQgeyBFbWJlZGRpbmdNb2RlbCB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IHByZXBhcmVSZXRyaWVzIH0gZnJvbSAnLi4vdXRpbC9wcmVwYXJlLXJldHJpZXMnO1xuaW1wb3J0IHsgRW1iZWRSZXN1bHQgfSBmcm9tICcuL2VtYmVkLXJlc3VsdCc7XG5pbXBvcnQgeyBWRVJTSU9OIH0gZnJvbSAnLi4vdmVyc2lvbic7XG5cbi8qKlxuRW1iZWQgYSB2YWx1ZSB1c2luZyBhbiBlbWJlZGRpbmcgbW9kZWwuIFRoZSB0eXBlIG9mIHRoZSB2YWx1ZSBpcyBkZWZpbmVkIGJ5IHRoZSBlbWJlZGRpbmcgbW9kZWwuXG5cbkBwYXJhbSBtb2RlbCAtIFRoZSBlbWJlZGRpbmcgbW9kZWwgdG8gdXNlLlxuQHBhcmFtIHZhbHVlIC0gVGhlIHZhbHVlIHRoYXQgc2hvdWxkIGJlIGVtYmVkZGVkLlxuXG5AcGFyYW0gbWF4UmV0cmllcyAtIE1heGltdW0gbnVtYmVyIG9mIHJldHJpZXMuIFNldCB0byAwIHRvIGRpc2FibGUgcmV0cmllcy4gRGVmYXVsdDogMi5cbkBwYXJhbSBhYm9ydFNpZ25hbCAtIEFuIG9wdGlvbmFsIGFib3J0IHNpZ25hbCB0aGF0IGNhbiBiZSB1c2VkIHRvIGNhbmNlbCB0aGUgY2FsbC5cbkBwYXJhbSBoZWFkZXJzIC0gQWRkaXRpb25hbCBIVFRQIGhlYWRlcnMgdG8gYmUgc2VudCB3aXRoIHRoZSByZXF1ZXN0LiBPbmx5IGFwcGxpY2FibGUgZm9yIEhUVFAtYmFzZWQgcHJvdmlkZXJzLlxuXG5AcmV0dXJucyBBIHJlc3VsdCBvYmplY3QgdGhhdCBjb250YWlucyB0aGUgZW1iZWRkaW5nLCB0aGUgdmFsdWUsIGFuZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZW1iZWQ8VkFMVUUgPSBzdHJpbmc+KHtcbiAgbW9kZWw6IG1vZGVsQXJnLFxuICB2YWx1ZSxcbiAgcHJvdmlkZXJPcHRpb25zLFxuICBtYXhSZXRyaWVzOiBtYXhSZXRyaWVzQXJnLFxuICBhYm9ydFNpZ25hbCxcbiAgaGVhZGVycyxcbiAgZXhwZXJpbWVudGFsX3RlbGVtZXRyeTogdGVsZW1ldHJ5LFxufToge1xuICAvKipcblRoZSBlbWJlZGRpbmcgbW9kZWwgdG8gdXNlLlxuICAgICAqL1xuICBtb2RlbDogRW1iZWRkaW5nTW9kZWw8VkFMVUU+O1xuXG4gIC8qKlxuVGhlIHZhbHVlIHRoYXQgc2hvdWxkIGJlIGVtYmVkZGVkLlxuICAgKi9cbiAgdmFsdWU6IFZBTFVFO1xuXG4gIC8qKlxuTWF4aW11bSBudW1iZXIgb2YgcmV0cmllcyBwZXIgZW1iZWRkaW5nIG1vZGVsIGNhbGwuIFNldCB0byAwIHRvIGRpc2FibGUgcmV0cmllcy5cblxuQGRlZmF1bHQgMlxuICAgKi9cbiAgbWF4UmV0cmllcz86IG51bWJlcjtcblxuICAvKipcbkFib3J0IHNpZ25hbC5cbiAqL1xuICBhYm9ydFNpZ25hbD86IEFib3J0U2lnbmFsO1xuXG4gIC8qKlxuQWRkaXRpb25hbCBoZWFkZXJzIHRvIGluY2x1ZGUgaW4gdGhlIHJlcXVlc3QuXG5Pbmx5IGFwcGxpY2FibGUgZm9yIEhUVFAtYmFzZWQgcHJvdmlkZXJzLlxuICovXG4gIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuXG4gIC8qKlxuICBBZGRpdGlvbmFsIHByb3ZpZGVyLXNwZWNpZmljIG9wdGlvbnMuIFRoZXkgYXJlIHBhc3NlZCB0aHJvdWdoXG4gIHRvIHRoZSBwcm92aWRlciBmcm9tIHRoZSBBSSBTREsgYW5kIGVuYWJsZSBwcm92aWRlci1zcGVjaWZpY1xuICBmdW5jdGlvbmFsaXR5IHRoYXQgY2FuIGJlIGZ1bGx5IGVuY2Fwc3VsYXRlZCBpbiB0aGUgcHJvdmlkZXIuXG4gICovXG4gIHByb3ZpZGVyT3B0aW9ucz86IFByb3ZpZGVyT3B0aW9ucztcblxuICAvKipcbiAgICogT3B0aW9uYWwgdGVsZW1ldHJ5IGNvbmZpZ3VyYXRpb24gKGV4cGVyaW1lbnRhbCkuXG4gICAqL1xuICBleHBlcmltZW50YWxfdGVsZW1ldHJ5PzogVGVsZW1ldHJ5U2V0dGluZ3M7XG59KTogUHJvbWlzZTxFbWJlZFJlc3VsdDxWQUxVRT4+IHtcbiAgY29uc3QgbW9kZWwgPSByZXNvbHZlRW1iZWRkaW5nTW9kZWw8VkFMVUU+KG1vZGVsQXJnKTtcblxuICBjb25zdCB7IG1heFJldHJpZXMsIHJldHJ5IH0gPSBwcmVwYXJlUmV0cmllcyh7XG4gICAgbWF4UmV0cmllczogbWF4UmV0cmllc0FyZyxcbiAgICBhYm9ydFNpZ25hbCxcbiAgfSk7XG5cbiAgY29uc3QgaGVhZGVyc1dpdGhVc2VyQWdlbnQgPSB3aXRoVXNlckFnZW50U3VmZml4KFxuICAgIGhlYWRlcnMgPz8ge30sXG4gICAgYGFpLyR7VkVSU0lPTn1gLFxuICApO1xuXG4gIGNvbnN0IGJhc2VUZWxlbWV0cnlBdHRyaWJ1dGVzID0gZ2V0QmFzZVRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgIG1vZGVsOiBtb2RlbCxcbiAgICB0ZWxlbWV0cnksXG4gICAgaGVhZGVyczogaGVhZGVyc1dpdGhVc2VyQWdlbnQsXG4gICAgc2V0dGluZ3M6IHsgbWF4UmV0cmllcyB9LFxuICB9KTtcblxuICBjb25zdCB0cmFjZXIgPSBnZXRUcmFjZXIodGVsZW1ldHJ5KTtcblxuICByZXR1cm4gcmVjb3JkU3Bhbih7XG4gICAgbmFtZTogJ2FpLmVtYmVkJyxcbiAgICBhdHRyaWJ1dGVzOiBzZWxlY3RUZWxlbWV0cnlBdHRyaWJ1dGVzKHtcbiAgICAgIHRlbGVtZXRyeSxcbiAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgLi4uYXNzZW1ibGVPcGVyYXRpb25OYW1lKHsgb3BlcmF0aW9uSWQ6ICdhaS5lbWJlZCcsIHRlbGVtZXRyeSB9KSxcbiAgICAgICAgLi4uYmFzZVRlbGVtZXRyeUF0dHJpYnV0ZXMsXG4gICAgICAgICdhaS52YWx1ZSc6IHsgaW5wdXQ6ICgpID0+IEpTT04uc3RyaW5naWZ5KHZhbHVlKSB9LFxuICAgICAgfSxcbiAgICB9KSxcbiAgICB0cmFjZXIsXG4gICAgZm46IGFzeW5jIHNwYW4gPT4ge1xuICAgICAgY29uc3QgeyBlbWJlZGRpbmcsIHVzYWdlLCByZXNwb25zZSwgcHJvdmlkZXJNZXRhZGF0YSB9ID0gYXdhaXQgcmV0cnkoKCkgPT5cbiAgICAgICAgLy8gbmVzdGVkIHNwYW5zIHRvIGFsaWduIHdpdGggdGhlIGVtYmVkTWFueSB0ZWxlbWV0cnkgZGF0YTpcbiAgICAgICAgcmVjb3JkU3Bhbih7XG4gICAgICAgICAgbmFtZTogJ2FpLmVtYmVkLmRvRW1iZWQnLFxuICAgICAgICAgIGF0dHJpYnV0ZXM6IHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAgICAgICAuLi5hc3NlbWJsZU9wZXJhdGlvbk5hbWUoe1xuICAgICAgICAgICAgICAgIG9wZXJhdGlvbklkOiAnYWkuZW1iZWQuZG9FbWJlZCcsXG4gICAgICAgICAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgLi4uYmFzZVRlbGVtZXRyeUF0dHJpYnV0ZXMsXG4gICAgICAgICAgICAgIC8vIHNwZWNpZmljIHNldHRpbmdzIHRoYXQgb25seSBtYWtlIHNlbnNlIG9uIHRoZSBvdXRlciBsZXZlbDpcbiAgICAgICAgICAgICAgJ2FpLnZhbHVlcyc6IHsgaW5wdXQ6ICgpID0+IFtKU09OLnN0cmluZ2lmeSh2YWx1ZSldIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIHRyYWNlcixcbiAgICAgICAgICBmbjogYXN5bmMgZG9FbWJlZFNwYW4gPT4ge1xuICAgICAgICAgICAgY29uc3QgbW9kZWxSZXNwb25zZSA9IGF3YWl0IG1vZGVsLmRvRW1iZWQoe1xuICAgICAgICAgICAgICB2YWx1ZXM6IFt2YWx1ZV0sXG4gICAgICAgICAgICAgIGFib3J0U2lnbmFsLFxuICAgICAgICAgICAgICBoZWFkZXJzOiBoZWFkZXJzV2l0aFVzZXJBZ2VudCxcbiAgICAgICAgICAgICAgcHJvdmlkZXJPcHRpb25zLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGNvbnN0IGVtYmVkZGluZyA9IG1vZGVsUmVzcG9uc2UuZW1iZWRkaW5nc1swXTtcbiAgICAgICAgICAgIGNvbnN0IHVzYWdlID0gbW9kZWxSZXNwb25zZS51c2FnZSA/PyB7IHRva2VuczogTmFOIH07XG5cbiAgICAgICAgICAgIGRvRW1iZWRTcGFuLnNldEF0dHJpYnV0ZXMoXG4gICAgICAgICAgICAgIHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgICAgIHRlbGVtZXRyeSxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgICAgICAgICAnYWkuZW1iZWRkaW5ncyc6IHtcbiAgICAgICAgICAgICAgICAgICAgb3V0cHV0OiAoKSA9PlxuICAgICAgICAgICAgICAgICAgICAgIG1vZGVsUmVzcG9uc2UuZW1iZWRkaW5ncy5tYXAoZW1iZWRkaW5nID0+XG4gICAgICAgICAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeShlbWJlZGRpbmcpLFxuICAgICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgJ2FpLnVzYWdlLnRva2Vucyc6IHVzYWdlLnRva2VucyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIGVtYmVkZGluZyxcbiAgICAgICAgICAgICAgdXNhZ2UsXG4gICAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IG1vZGVsUmVzcG9uc2UucHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgICAgICAgcmVzcG9uc2U6IG1vZGVsUmVzcG9uc2UucmVzcG9uc2UsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGVzKFxuICAgICAgICBzZWxlY3RUZWxlbWV0cnlBdHRyaWJ1dGVzKHtcbiAgICAgICAgICB0ZWxlbWV0cnksXG4gICAgICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAgICAgJ2FpLmVtYmVkZGluZyc6IHsgb3V0cHV0OiAoKSA9PiBKU09OLnN0cmluZ2lmeShlbWJlZGRpbmcpIH0sXG4gICAgICAgICAgICAnYWkudXNhZ2UudG9rZW5zJzogdXNhZ2UudG9rZW5zLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgcmV0dXJuIG5ldyBEZWZhdWx0RW1iZWRSZXN1bHQoe1xuICAgICAgICB2YWx1ZSxcbiAgICAgICAgZW1iZWRkaW5nLFxuICAgICAgICB1c2FnZSxcbiAgICAgICAgcHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgcmVzcG9uc2UsXG4gICAgICB9KTtcbiAgICB9LFxuICB9KTtcbn1cblxuY2xhc3MgRGVmYXVsdEVtYmVkUmVzdWx0PFZBTFVFPiBpbXBsZW1lbnRzIEVtYmVkUmVzdWx0PFZBTFVFPiB7XG4gIHJlYWRvbmx5IHZhbHVlOiBFbWJlZFJlc3VsdDxWQUxVRT5bJ3ZhbHVlJ107XG4gIHJlYWRvbmx5IGVtYmVkZGluZzogRW1iZWRSZXN1bHQ8VkFMVUU+WydlbWJlZGRpbmcnXTtcbiAgcmVhZG9ubHkgdXNhZ2U6IEVtYmVkUmVzdWx0PFZBTFVFPlsndXNhZ2UnXTtcbiAgcmVhZG9ubHkgcHJvdmlkZXJNZXRhZGF0YTogRW1iZWRSZXN1bHQ8VkFMVUU+Wydwcm92aWRlck1ldGFkYXRhJ107XG4gIHJlYWRvbmx5IHJlc3BvbnNlOiBFbWJlZFJlc3VsdDxWQUxVRT5bJ3Jlc3BvbnNlJ107XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczoge1xuICAgIHZhbHVlOiBFbWJlZFJlc3VsdDxWQUxVRT5bJ3ZhbHVlJ107XG4gICAgZW1iZWRkaW5nOiBFbWJlZFJlc3VsdDxWQUxVRT5bJ2VtYmVkZGluZyddO1xuICAgIHVzYWdlOiBFbWJlZFJlc3VsdDxWQUxVRT5bJ3VzYWdlJ107XG4gICAgcHJvdmlkZXJNZXRhZGF0YT86IEVtYmVkUmVzdWx0PFZBTFVFPlsncHJvdmlkZXJNZXRhZGF0YSddO1xuICAgIHJlc3BvbnNlPzogRW1iZWRSZXN1bHQ8VkFMVUU+WydyZXNwb25zZSddO1xuICB9KSB7XG4gICAgdGhpcy52YWx1ZSA9IG9wdGlvbnMudmFsdWU7XG4gICAgdGhpcy5lbWJlZGRpbmcgPSBvcHRpb25zLmVtYmVkZGluZztcbiAgICB0aGlzLnVzYWdlID0gb3B0aW9ucy51c2FnZTtcbiAgICB0aGlzLnByb3ZpZGVyTWV0YWRhdGEgPSBvcHRpb25zLnByb3ZpZGVyTWV0YWRhdGE7XG4gICAgdGhpcy5yZXNwb25zZSA9IG9wdGlvbnMucmVzcG9uc2U7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBQcm92aWRlck9wdGlvbnMsIHdpdGhVc2VyQWdlbnRTdWZmaXggfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyLXV0aWxzJztcbmltcG9ydCB7IHByZXBhcmVSZXRyaWVzIH0gZnJvbSAnLi4vdXRpbC9wcmVwYXJlLXJldHJpZXMnO1xuaW1wb3J0IHsgc3BsaXRBcnJheSB9IGZyb20gJy4uL3V0aWwvc3BsaXQtYXJyYXknO1xuaW1wb3J0IHsgVW5zdXBwb3J0ZWRNb2RlbFZlcnNpb25FcnJvciB9IGZyb20gJy4uL2Vycm9yL3Vuc3VwcG9ydGVkLW1vZGVsLXZlcnNpb24tZXJyb3InO1xuaW1wb3J0IHsgYXNzZW1ibGVPcGVyYXRpb25OYW1lIH0gZnJvbSAnLi4vdGVsZW1ldHJ5L2Fzc2VtYmxlLW9wZXJhdGlvbi1uYW1lJztcbmltcG9ydCB7IGdldEJhc2VUZWxlbWV0cnlBdHRyaWJ1dGVzIH0gZnJvbSAnLi4vdGVsZW1ldHJ5L2dldC1iYXNlLXRlbGVtZXRyeS1hdHRyaWJ1dGVzJztcbmltcG9ydCB7IGdldFRyYWNlciB9IGZyb20gJy4uL3RlbGVtZXRyeS9nZXQtdHJhY2VyJztcbmltcG9ydCB7IHJlY29yZFNwYW4gfSBmcm9tICcuLi90ZWxlbWV0cnkvcmVjb3JkLXNwYW4nO1xuaW1wb3J0IHsgc2VsZWN0VGVsZW1ldHJ5QXR0cmlidXRlcyB9IGZyb20gJy4uL3RlbGVtZXRyeS9zZWxlY3QtdGVsZW1ldHJ5LWF0dHJpYnV0ZXMnO1xuaW1wb3J0IHsgVGVsZW1ldHJ5U2V0dGluZ3MgfSBmcm9tICcuLi90ZWxlbWV0cnkvdGVsZW1ldHJ5LXNldHRpbmdzJztcbmltcG9ydCB7IEVtYmVkZGluZywgRW1iZWRkaW5nTW9kZWwsIFByb3ZpZGVyTWV0YWRhdGEgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgeyByZXNvbHZlRW1iZWRkaW5nTW9kZWwgfSBmcm9tICcuLi9tb2RlbC9yZXNvbHZlLW1vZGVsJztcbmltcG9ydCB7IEVtYmVkTWFueVJlc3VsdCB9IGZyb20gJy4vZW1iZWQtbWFueS1yZXN1bHQnO1xuaW1wb3J0IHsgVkVSU0lPTiB9IGZyb20gJy4uL3ZlcnNpb24nO1xuXG4vKipcbkVtYmVkIHNldmVyYWwgdmFsdWVzIHVzaW5nIGFuIGVtYmVkZGluZyBtb2RlbC4gVGhlIHR5cGUgb2YgdGhlIHZhbHVlIGlzIGRlZmluZWRcbmJ5IHRoZSBlbWJlZGRpbmcgbW9kZWwuXG5cbmBlbWJlZE1hbnlgIGF1dG9tYXRpY2FsbHkgc3BsaXRzIGxhcmdlIHJlcXVlc3RzIGludG8gc21hbGxlciBjaHVua3MgaWYgdGhlIG1vZGVsXG5oYXMgYSBsaW1pdCBvbiBob3cgbWFueSBlbWJlZGRpbmdzIGNhbiBiZSBnZW5lcmF0ZWQgaW4gYSBzaW5nbGUgY2FsbC5cblxuQHBhcmFtIG1vZGVsIC0gVGhlIGVtYmVkZGluZyBtb2RlbCB0byB1c2UuXG5AcGFyYW0gdmFsdWVzIC0gVGhlIHZhbHVlcyB0aGF0IHNob3VsZCBiZSBlbWJlZGRlZC5cblxuQHBhcmFtIG1heFJldHJpZXMgLSBNYXhpbXVtIG51bWJlciBvZiByZXRyaWVzLiBTZXQgdG8gMCB0byBkaXNhYmxlIHJldHJpZXMuIERlZmF1bHQ6IDIuXG5AcGFyYW0gYWJvcnRTaWduYWwgLSBBbiBvcHRpb25hbCBhYm9ydCBzaWduYWwgdGhhdCBjYW4gYmUgdXNlZCB0byBjYW5jZWwgdGhlIGNhbGwuXG5AcGFyYW0gaGVhZGVycyAtIEFkZGl0aW9uYWwgSFRUUCBoZWFkZXJzIHRvIGJlIHNlbnQgd2l0aCB0aGUgcmVxdWVzdC4gT25seSBhcHBsaWNhYmxlIGZvciBIVFRQLWJhc2VkIHByb3ZpZGVycy5cblxuQHJldHVybnMgQSByZXN1bHQgb2JqZWN0IHRoYXQgY29udGFpbnMgdGhlIGVtYmVkZGluZ3MsIHRoZSB2YWx1ZSwgYW5kIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24uXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBlbWJlZE1hbnk8VkFMVUUgPSBzdHJpbmc+KHtcbiAgbW9kZWw6IG1vZGVsQXJnLFxuICB2YWx1ZXMsXG4gIG1heFBhcmFsbGVsQ2FsbHMgPSBJbmZpbml0eSxcbiAgbWF4UmV0cmllczogbWF4UmV0cmllc0FyZyxcbiAgYWJvcnRTaWduYWwsXG4gIGhlYWRlcnMsXG4gIHByb3ZpZGVyT3B0aW9ucyxcbiAgZXhwZXJpbWVudGFsX3RlbGVtZXRyeTogdGVsZW1ldHJ5LFxufToge1xuICAvKipcblRoZSBlbWJlZGRpbmcgbW9kZWwgdG8gdXNlLlxuICAgICAqL1xuICBtb2RlbDogRW1iZWRkaW5nTW9kZWw8VkFMVUU+O1xuXG4gIC8qKlxuVGhlIHZhbHVlcyB0aGF0IHNob3VsZCBiZSBlbWJlZGRlZC5cbiAgICovXG4gIHZhbHVlczogQXJyYXk8VkFMVUU+O1xuXG4gIC8qKlxuTWF4aW11bSBudW1iZXIgb2YgcmV0cmllcyBwZXIgZW1iZWRkaW5nIG1vZGVsIGNhbGwuIFNldCB0byAwIHRvIGRpc2FibGUgcmV0cmllcy5cblxuQGRlZmF1bHQgMlxuICAgKi9cbiAgbWF4UmV0cmllcz86IG51bWJlcjtcblxuICAvKipcbkFib3J0IHNpZ25hbC5cbiAqL1xuICBhYm9ydFNpZ25hbD86IEFib3J0U2lnbmFsO1xuXG4gIC8qKlxuQWRkaXRpb25hbCBoZWFkZXJzIHRvIGluY2x1ZGUgaW4gdGhlIHJlcXVlc3QuXG5Pbmx5IGFwcGxpY2FibGUgZm9yIEhUVFAtYmFzZWQgcHJvdmlkZXJzLlxuICovXG4gIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuXG4gIC8qKlxuICAgKiBPcHRpb25hbCB0ZWxlbWV0cnkgY29uZmlndXJhdGlvbiAoZXhwZXJpbWVudGFsKS5cbiAgICovXG4gIGV4cGVyaW1lbnRhbF90ZWxlbWV0cnk/OiBUZWxlbWV0cnlTZXR0aW5ncztcblxuICAvKipcbiAgQWRkaXRpb25hbCBwcm92aWRlci1zcGVjaWZpYyBvcHRpb25zLiBUaGV5IGFyZSBwYXNzZWQgdGhyb3VnaFxuICB0byB0aGUgcHJvdmlkZXIgZnJvbSB0aGUgQUkgU0RLIGFuZCBlbmFibGUgcHJvdmlkZXItc3BlY2lmaWNcbiAgZnVuY3Rpb25hbGl0eSB0aGF0IGNhbiBiZSBmdWxseSBlbmNhcHN1bGF0ZWQgaW4gdGhlIHByb3ZpZGVyLlxuICAqL1xuICBwcm92aWRlck9wdGlvbnM/OiBQcm92aWRlck9wdGlvbnM7XG5cbiAgLyoqXG4gICAqIE1heGltdW0gbnVtYmVyIG9mIGNvbmN1cnJlbnQgcmVxdWVzdHMuXG4gICAqXG4gICAqIEBkZWZhdWx0IEluZmluaXR5XG4gICAqL1xuICBtYXhQYXJhbGxlbENhbGxzPzogbnVtYmVyO1xufSk6IFByb21pc2U8RW1iZWRNYW55UmVzdWx0PFZBTFVFPj4ge1xuICBjb25zdCBtb2RlbCA9IHJlc29sdmVFbWJlZGRpbmdNb2RlbDxWQUxVRT4obW9kZWxBcmcpO1xuXG4gIGNvbnN0IHsgbWF4UmV0cmllcywgcmV0cnkgfSA9IHByZXBhcmVSZXRyaWVzKHtcbiAgICBtYXhSZXRyaWVzOiBtYXhSZXRyaWVzQXJnLFxuICAgIGFib3J0U2lnbmFsLFxuICB9KTtcblxuICBjb25zdCBoZWFkZXJzV2l0aFVzZXJBZ2VudCA9IHdpdGhVc2VyQWdlbnRTdWZmaXgoXG4gICAgaGVhZGVycyA/PyB7fSxcbiAgICBgYWkvJHtWRVJTSU9OfWAsXG4gICk7XG5cbiAgY29uc3QgYmFzZVRlbGVtZXRyeUF0dHJpYnV0ZXMgPSBnZXRCYXNlVGVsZW1ldHJ5QXR0cmlidXRlcyh7XG4gICAgbW9kZWwsXG4gICAgdGVsZW1ldHJ5LFxuICAgIGhlYWRlcnM6IGhlYWRlcnNXaXRoVXNlckFnZW50LFxuICAgIHNldHRpbmdzOiB7IG1heFJldHJpZXMgfSxcbiAgfSk7XG5cbiAgY29uc3QgdHJhY2VyID0gZ2V0VHJhY2VyKHRlbGVtZXRyeSk7XG5cbiAgcmV0dXJuIHJlY29yZFNwYW4oe1xuICAgIG5hbWU6ICdhaS5lbWJlZE1hbnknLFxuICAgIGF0dHJpYnV0ZXM6IHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgdGVsZW1ldHJ5LFxuICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAuLi5hc3NlbWJsZU9wZXJhdGlvbk5hbWUoeyBvcGVyYXRpb25JZDogJ2FpLmVtYmVkTWFueScsIHRlbGVtZXRyeSB9KSxcbiAgICAgICAgLi4uYmFzZVRlbGVtZXRyeUF0dHJpYnV0ZXMsXG4gICAgICAgIC8vIHNwZWNpZmljIHNldHRpbmdzIHRoYXQgb25seSBtYWtlIHNlbnNlIG9uIHRoZSBvdXRlciBsZXZlbDpcbiAgICAgICAgJ2FpLnZhbHVlcyc6IHtcbiAgICAgICAgICBpbnB1dDogKCkgPT4gdmFsdWVzLm1hcCh2YWx1ZSA9PiBKU09OLnN0cmluZ2lmeSh2YWx1ZSkpLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9KSxcbiAgICB0cmFjZXIsXG4gICAgZm46IGFzeW5jIHNwYW4gPT4ge1xuICAgICAgY29uc3QgW21heEVtYmVkZGluZ3NQZXJDYWxsLCBzdXBwb3J0c1BhcmFsbGVsQ2FsbHNdID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICBtb2RlbC5tYXhFbWJlZGRpbmdzUGVyQ2FsbCxcbiAgICAgICAgbW9kZWwuc3VwcG9ydHNQYXJhbGxlbENhbGxzLFxuICAgICAgXSk7XG5cbiAgICAgIC8vIHRoZSBtb2RlbCBoYXMgbm90IHNwZWNpZmllZCBsaW1pdHMgb25cbiAgICAgIC8vIGhvdyBtYW55IGVtYmVkZGluZ3MgY2FuIGJlIGdlbmVyYXRlZCBpbiBhIHNpbmdsZSBjYWxsXG4gICAgICBpZiAobWF4RW1iZWRkaW5nc1BlckNhbGwgPT0gbnVsbCB8fCBtYXhFbWJlZGRpbmdzUGVyQ2FsbCA9PT0gSW5maW5pdHkpIHtcbiAgICAgICAgY29uc3QgeyBlbWJlZGRpbmdzLCB1c2FnZSwgcmVzcG9uc2UsIHByb3ZpZGVyTWV0YWRhdGEgfSA9IGF3YWl0IHJldHJ5KFxuICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgIC8vIG5lc3RlZCBzcGFucyB0byBhbGlnbiB3aXRoIHRoZSBlbWJlZE1hbnkgdGVsZW1ldHJ5IGRhdGE6XG4gICAgICAgICAgICByZXR1cm4gcmVjb3JkU3Bhbih7XG4gICAgICAgICAgICAgIG5hbWU6ICdhaS5lbWJlZE1hbnkuZG9FbWJlZCcsXG4gICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgICAgIHRlbGVtZXRyeSxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgICAgICAgICAuLi5hc3NlbWJsZU9wZXJhdGlvbk5hbWUoe1xuICAgICAgICAgICAgICAgICAgICBvcGVyYXRpb25JZDogJ2FpLmVtYmVkTWFueS5kb0VtYmVkJyxcbiAgICAgICAgICAgICAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAuLi5iYXNlVGVsZW1ldHJ5QXR0cmlidXRlcyxcbiAgICAgICAgICAgICAgICAgIC8vIHNwZWNpZmljIHNldHRpbmdzIHRoYXQgb25seSBtYWtlIHNlbnNlIG9uIHRoZSBvdXRlciBsZXZlbDpcbiAgICAgICAgICAgICAgICAgICdhaS52YWx1ZXMnOiB7XG4gICAgICAgICAgICAgICAgICAgIGlucHV0OiAoKSA9PiB2YWx1ZXMubWFwKHZhbHVlID0+IEpTT04uc3RyaW5naWZ5KHZhbHVlKSksXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICB0cmFjZXIsXG4gICAgICAgICAgICAgIGZuOiBhc3luYyBkb0VtYmVkU3BhbiA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgbW9kZWxSZXNwb25zZSA9IGF3YWl0IG1vZGVsLmRvRW1iZWQoe1xuICAgICAgICAgICAgICAgICAgdmFsdWVzLFxuICAgICAgICAgICAgICAgICAgYWJvcnRTaWduYWwsXG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiBoZWFkZXJzV2l0aFVzZXJBZ2VudCxcbiAgICAgICAgICAgICAgICAgIHByb3ZpZGVyT3B0aW9ucyxcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IGVtYmVkZGluZ3MgPSBtb2RlbFJlc3BvbnNlLmVtYmVkZGluZ3M7XG4gICAgICAgICAgICAgICAgY29uc3QgdXNhZ2UgPSBtb2RlbFJlc3BvbnNlLnVzYWdlID8/IHsgdG9rZW5zOiBOYU4gfTtcblxuICAgICAgICAgICAgICAgIGRvRW1iZWRTcGFuLnNldEF0dHJpYnV0ZXMoXG4gICAgICAgICAgICAgICAgICBzZWxlY3RUZWxlbWV0cnlBdHRyaWJ1dGVzKHtcbiAgICAgICAgICAgICAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgJ2FpLmVtYmVkZGluZ3MnOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQ6ICgpID0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGVtYmVkZGluZ3MubWFwKGVtYmVkZGluZyA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KGVtYmVkZGluZyksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAnYWkudXNhZ2UudG9rZW5zJzogdXNhZ2UudG9rZW5zLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICBlbWJlZGRpbmdzLFxuICAgICAgICAgICAgICAgICAgdXNhZ2UsXG4gICAgICAgICAgICAgICAgICBwcm92aWRlck1ldGFkYXRhOiBtb2RlbFJlc3BvbnNlLnByb3ZpZGVyTWV0YWRhdGEsXG4gICAgICAgICAgICAgICAgICByZXNwb25zZTogbW9kZWxSZXNwb25zZS5yZXNwb25zZSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcblxuICAgICAgICBzcGFuLnNldEF0dHJpYnV0ZXMoXG4gICAgICAgICAgc2VsZWN0VGVsZW1ldHJ5QXR0cmlidXRlcyh7XG4gICAgICAgICAgICB0ZWxlbWV0cnksXG4gICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgICAgICdhaS5lbWJlZGRpbmdzJzoge1xuICAgICAgICAgICAgICAgIG91dHB1dDogKCkgPT5cbiAgICAgICAgICAgICAgICAgIGVtYmVkZGluZ3MubWFwKGVtYmVkZGluZyA9PiBKU09OLnN0cmluZ2lmeShlbWJlZGRpbmcpKSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgJ2FpLnVzYWdlLnRva2Vucyc6IHVzYWdlLnRva2VucyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBEZWZhdWx0RW1iZWRNYW55UmVzdWx0KHtcbiAgICAgICAgICB2YWx1ZXMsXG4gICAgICAgICAgZW1iZWRkaW5ncyxcbiAgICAgICAgICB1c2FnZSxcbiAgICAgICAgICBwcm92aWRlck1ldGFkYXRhLFxuICAgICAgICAgIHJlc3BvbnNlczogW3Jlc3BvbnNlXSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIC8vIHNwbGl0IHRoZSB2YWx1ZXMgaW50byBjaHVua3MgdGhhdCBhcmUgc21hbGwgZW5vdWdoIGZvciB0aGUgbW9kZWw6XG4gICAgICBjb25zdCB2YWx1ZUNodW5rcyA9IHNwbGl0QXJyYXkodmFsdWVzLCBtYXhFbWJlZGRpbmdzUGVyQ2FsbCk7XG5cbiAgICAgIC8vIHNlcmlhbGx5IGVtYmVkIHRoZSBjaHVua3M6XG4gICAgICBjb25zdCBlbWJlZGRpbmdzOiBBcnJheTxFbWJlZGRpbmc+ID0gW107XG4gICAgICBjb25zdCByZXNwb25zZXM6IEFycmF5PFxuICAgICAgICB8IHtcbiAgICAgICAgICAgIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICAgICAgICAgICAgYm9keT86IHVua25vd247XG4gICAgICAgICAgfVxuICAgICAgICB8IHVuZGVmaW5lZFxuICAgICAgPiA9IFtdO1xuICAgICAgbGV0IHRva2VucyA9IDA7XG4gICAgICBsZXQgcHJvdmlkZXJNZXRhZGF0YTogUHJvdmlkZXJNZXRhZGF0YSB8IHVuZGVmaW5lZDtcblxuICAgICAgY29uc3QgcGFyYWxsZWxDaHVua3MgPSBzcGxpdEFycmF5KFxuICAgICAgICB2YWx1ZUNodW5rcyxcbiAgICAgICAgc3VwcG9ydHNQYXJhbGxlbENhbGxzID8gbWF4UGFyYWxsZWxDYWxscyA6IDEsXG4gICAgICApO1xuXG4gICAgICBmb3IgKGNvbnN0IHBhcmFsbGVsQ2h1bmsgb2YgcGFyYWxsZWxDaHVua3MpIHtcbiAgICAgICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICAgIHBhcmFsbGVsQ2h1bmsubWFwKGNodW5rID0+IHtcbiAgICAgICAgICAgIHJldHVybiByZXRyeSgoKSA9PiB7XG4gICAgICAgICAgICAgIC8vIG5lc3RlZCBzcGFucyB0byBhbGlnbiB3aXRoIHRoZSBlbWJlZE1hbnkgdGVsZW1ldHJ5IGRhdGE6XG4gICAgICAgICAgICAgIHJldHVybiByZWNvcmRTcGFuKHtcbiAgICAgICAgICAgICAgICBuYW1lOiAnYWkuZW1iZWRNYW55LmRvRW1iZWQnLFxuICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICAgICAgICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAgICAgICAgICAgICAuLi5hc3NlbWJsZU9wZXJhdGlvbk5hbWUoe1xuICAgICAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbklkOiAnYWkuZW1iZWRNYW55LmRvRW1iZWQnLFxuICAgICAgICAgICAgICAgICAgICAgIHRlbGVtZXRyeSxcbiAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAgIC4uLmJhc2VUZWxlbWV0cnlBdHRyaWJ1dGVzLFxuICAgICAgICAgICAgICAgICAgICAvLyBzcGVjaWZpYyBzZXR0aW5ncyB0aGF0IG9ubHkgbWFrZSBzZW5zZSBvbiB0aGUgb3V0ZXIgbGV2ZWw6XG4gICAgICAgICAgICAgICAgICAgICdhaS52YWx1ZXMnOiB7XG4gICAgICAgICAgICAgICAgICAgICAgaW5wdXQ6ICgpID0+IGNodW5rLm1hcCh2YWx1ZSA9PiBKU09OLnN0cmluZ2lmeSh2YWx1ZSkpLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICB0cmFjZXIsXG4gICAgICAgICAgICAgICAgZm46IGFzeW5jIGRvRW1iZWRTcGFuID0+IHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IG1vZGVsUmVzcG9uc2UgPSBhd2FpdCBtb2RlbC5kb0VtYmVkKHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWVzOiBjaHVuayxcbiAgICAgICAgICAgICAgICAgICAgYWJvcnRTaWduYWwsXG4gICAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IGhlYWRlcnNXaXRoVXNlckFnZW50LFxuICAgICAgICAgICAgICAgICAgICBwcm92aWRlck9wdGlvbnMsXG4gICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgY29uc3QgZW1iZWRkaW5ncyA9IG1vZGVsUmVzcG9uc2UuZW1iZWRkaW5ncztcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHVzYWdlID0gbW9kZWxSZXNwb25zZS51c2FnZSA/PyB7IHRva2VuczogTmFOIH07XG5cbiAgICAgICAgICAgICAgICAgIGRvRW1iZWRTcGFuLnNldEF0dHJpYnV0ZXMoXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgICAgICAgICAgIHRlbGVtZXRyeSxcbiAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAnYWkuZW1iZWRkaW5ncyc6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0OiAoKSA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVtYmVkZGluZ3MubWFwKGVtYmVkZGluZyA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkoZW1iZWRkaW5nKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICdhaS51c2FnZS50b2tlbnMnOiB1c2FnZS50b2tlbnMsXG4gICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBlbWJlZGRpbmdzLFxuICAgICAgICAgICAgICAgICAgICB1c2FnZSxcbiAgICAgICAgICAgICAgICAgICAgcHJvdmlkZXJNZXRhZGF0YTogbW9kZWxSZXNwb25zZS5wcm92aWRlck1ldGFkYXRhLFxuICAgICAgICAgICAgICAgICAgICByZXNwb25zZTogbW9kZWxSZXNwb25zZS5yZXNwb25zZSxcbiAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcblxuICAgICAgICBmb3IgKGNvbnN0IHJlc3VsdCBvZiByZXN1bHRzKSB7XG4gICAgICAgICAgZW1iZWRkaW5ncy5wdXNoKC4uLnJlc3VsdC5lbWJlZGRpbmdzKTtcbiAgICAgICAgICByZXNwb25zZXMucHVzaChyZXN1bHQucmVzcG9uc2UpO1xuICAgICAgICAgIHRva2VucyArPSByZXN1bHQudXNhZ2UudG9rZW5zO1xuICAgICAgICAgIGlmIChyZXN1bHQucHJvdmlkZXJNZXRhZGF0YSkge1xuICAgICAgICAgICAgaWYgKCFwcm92aWRlck1ldGFkYXRhKSB7XG4gICAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGEgPSB7IC4uLnJlc3VsdC5wcm92aWRlck1ldGFkYXRhIH07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBmb3IgKGNvbnN0IFtwcm92aWRlck5hbWUsIG1ldGFkYXRhXSBvZiBPYmplY3QuZW50cmllcyhcbiAgICAgICAgICAgICAgICByZXN1bHQucHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgICAgICAgKSkge1xuICAgICAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGFbcHJvdmlkZXJOYW1lXSA9IHtcbiAgICAgICAgICAgICAgICAgIC4uLihwcm92aWRlck1ldGFkYXRhW3Byb3ZpZGVyTmFtZV0gPz8ge30pLFxuICAgICAgICAgICAgICAgICAgLi4ubWV0YWRhdGEsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBzcGFuLnNldEF0dHJpYnV0ZXMoXG4gICAgICAgIHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgICAgIHRlbGVtZXRyeSxcbiAgICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgICAnYWkuZW1iZWRkaW5ncyc6IHtcbiAgICAgICAgICAgICAgb3V0cHV0OiAoKSA9PlxuICAgICAgICAgICAgICAgIGVtYmVkZGluZ3MubWFwKGVtYmVkZGluZyA9PiBKU09OLnN0cmluZ2lmeShlbWJlZGRpbmcpKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAnYWkudXNhZ2UudG9rZW5zJzogdG9rZW5zLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgcmV0dXJuIG5ldyBEZWZhdWx0RW1iZWRNYW55UmVzdWx0KHtcbiAgICAgICAgdmFsdWVzLFxuICAgICAgICBlbWJlZGRpbmdzLFxuICAgICAgICB1c2FnZTogeyB0b2tlbnMgfSxcbiAgICAgICAgcHJvdmlkZXJNZXRhZGF0YTogcHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgcmVzcG9uc2VzLFxuICAgICAgfSk7XG4gICAgfSxcbiAgfSk7XG59XG5cbmNsYXNzIERlZmF1bHRFbWJlZE1hbnlSZXN1bHQ8VkFMVUU+IGltcGxlbWVudHMgRW1iZWRNYW55UmVzdWx0PFZBTFVFPiB7XG4gIHJlYWRvbmx5IHZhbHVlczogRW1iZWRNYW55UmVzdWx0PFZBTFVFPlsndmFsdWVzJ107XG4gIHJlYWRvbmx5IGVtYmVkZGluZ3M6IEVtYmVkTWFueVJlc3VsdDxWQUxVRT5bJ2VtYmVkZGluZ3MnXTtcbiAgcmVhZG9ubHkgdXNhZ2U6IEVtYmVkTWFueVJlc3VsdDxWQUxVRT5bJ3VzYWdlJ107XG4gIHJlYWRvbmx5IHByb3ZpZGVyTWV0YWRhdGE6IEVtYmVkTWFueVJlc3VsdDxWQUxVRT5bJ3Byb3ZpZGVyTWV0YWRhdGEnXTtcbiAgcmVhZG9ubHkgcmVzcG9uc2VzOiBFbWJlZE1hbnlSZXN1bHQ8VkFMVUU+WydyZXNwb25zZXMnXTtcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiB7XG4gICAgdmFsdWVzOiBFbWJlZE1hbnlSZXN1bHQ8VkFMVUU+Wyd2YWx1ZXMnXTtcbiAgICBlbWJlZGRpbmdzOiBFbWJlZE1hbnlSZXN1bHQ8VkFMVUU+WydlbWJlZGRpbmdzJ107XG4gICAgdXNhZ2U6IEVtYmVkTWFueVJlc3VsdDxWQUxVRT5bJ3VzYWdlJ107XG4gICAgcHJvdmlkZXJNZXRhZGF0YT86IEVtYmVkTWFueVJlc3VsdDxWQUxVRT5bJ3Byb3ZpZGVyTWV0YWRhdGEnXTtcbiAgICByZXNwb25zZXM/OiBFbWJlZE1hbnlSZXN1bHQ8VkFMVUU+WydyZXNwb25zZXMnXTtcbiAgfSkge1xuICAgIHRoaXMudmFsdWVzID0gb3B0aW9ucy52YWx1ZXM7XG4gICAgdGhpcy5lbWJlZGRpbmdzID0gb3B0aW9ucy5lbWJlZGRpbmdzO1xuICAgIHRoaXMudXNhZ2UgPSBvcHRpb25zLnVzYWdlO1xuICAgIHRoaXMucHJvdmlkZXJNZXRhZGF0YSA9IG9wdGlvbnMucHJvdmlkZXJNZXRhZGF0YTtcbiAgICB0aGlzLnJlc3BvbnNlcyA9IG9wdGlvbnMucmVzcG9uc2VzO1xuICB9XG59XG4iLCAiLyoqXG4gKiBTcGxpdHMgYW4gYXJyYXkgaW50byBjaHVua3Mgb2YgYSBzcGVjaWZpZWQgc2l6ZS5cbiAqXG4gKiBAdGVtcGxhdGUgVCAtIFRoZSB0eXBlIG9mIGVsZW1lbnRzIGluIHRoZSBhcnJheS5cbiAqIEBwYXJhbSB7VFtdfSBhcnJheSAtIFRoZSBhcnJheSB0byBzcGxpdC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBjaHVua1NpemUgLSBUaGUgc2l6ZSBvZiBlYWNoIGNodW5rLlxuICogQHJldHVybnMge1RbXVtdfSAtIEEgbmV3IGFycmF5IGNvbnRhaW5pbmcgdGhlIGNodW5rcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNwbGl0QXJyYXk8VD4oYXJyYXk6IFRbXSwgY2h1bmtTaXplOiBudW1iZXIpOiBUW11bXSB7XG4gIGlmIChjaHVua1NpemUgPD0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignY2h1bmtTaXplIG11c3QgYmUgZ3JlYXRlciB0aGFuIDAnKTtcbiAgfVxuXG4gIGNvbnN0IHJlc3VsdCA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSArPSBjaHVua1NpemUpIHtcbiAgICByZXN1bHQucHVzaChhcnJheS5zbGljZShpLCBpICsgY2h1bmtTaXplKSk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuIiwgImltcG9ydCB7IEltYWdlTW9kZWxWMiwgSW1hZ2VNb2RlbFYyUHJvdmlkZXJNZXRhZGF0YSB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgUHJvdmlkZXJPcHRpb25zLCB3aXRoVXNlckFnZW50U3VmZml4IH0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyBOb0ltYWdlR2VuZXJhdGVkRXJyb3IgfSBmcm9tICcuLi9lcnJvci9uby1pbWFnZS1nZW5lcmF0ZWQtZXJyb3InO1xuaW1wb3J0IHtcbiAgZGV0ZWN0TWVkaWFUeXBlLFxuICBpbWFnZU1lZGlhVHlwZVNpZ25hdHVyZXMsXG59IGZyb20gJy4uL3V0aWwvZGV0ZWN0LW1lZGlhLXR5cGUnO1xuaW1wb3J0IHsgcHJlcGFyZVJldHJpZXMgfSBmcm9tICcuLi91dGlsL3ByZXBhcmUtcmV0cmllcyc7XG5pbXBvcnQgeyBVbnN1cHBvcnRlZE1vZGVsVmVyc2lvbkVycm9yIH0gZnJvbSAnLi4vZXJyb3IvdW5zdXBwb3J0ZWQtbW9kZWwtdmVyc2lvbi1lcnJvcic7XG5pbXBvcnQge1xuICBEZWZhdWx0R2VuZXJhdGVkRmlsZSxcbiAgR2VuZXJhdGVkRmlsZSxcbn0gZnJvbSAnLi4vZ2VuZXJhdGUtdGV4dC9nZW5lcmF0ZWQtZmlsZSc7XG5pbXBvcnQgeyBJbWFnZUdlbmVyYXRpb25XYXJuaW5nIH0gZnJvbSAnLi4vdHlwZXMvaW1hZ2UtbW9kZWwnO1xuaW1wb3J0IHsgSW1hZ2VNb2RlbFJlc3BvbnNlTWV0YWRhdGEgfSBmcm9tICcuLi90eXBlcy9pbWFnZS1tb2RlbC1yZXNwb25zZS1tZXRhZGF0YSc7XG5pbXBvcnQgeyBHZW5lcmF0ZUltYWdlUmVzdWx0IH0gZnJvbSAnLi9nZW5lcmF0ZS1pbWFnZS1yZXN1bHQnO1xuaW1wb3J0IHsgbG9nV2FybmluZ3MgfSBmcm9tICcuLi9sb2dnZXIvbG9nLXdhcm5pbmdzJztcbmltcG9ydCB7IFZFUlNJT04gfSBmcm9tICcuLi92ZXJzaW9uJztcblxuLyoqXG5HZW5lcmF0ZXMgaW1hZ2VzIHVzaW5nIGFuIGltYWdlIG1vZGVsLlxuXG5AcGFyYW0gbW9kZWwgLSBUaGUgaW1hZ2UgbW9kZWwgdG8gdXNlLlxuQHBhcmFtIHByb21wdCAtIFRoZSBwcm9tcHQgdGhhdCBzaG91bGQgYmUgdXNlZCB0byBnZW5lcmF0ZSB0aGUgaW1hZ2UuXG5AcGFyYW0gbiAtIE51bWJlciBvZiBpbWFnZXMgdG8gZ2VuZXJhdGUuIERlZmF1bHQ6IDEuXG5AcGFyYW0gc2l6ZSAtIFNpemUgb2YgdGhlIGltYWdlcyB0byBnZW5lcmF0ZS4gTXVzdCBoYXZlIHRoZSBmb3JtYXQgYHt3aWR0aH14e2hlaWdodH1gLlxuQHBhcmFtIGFzcGVjdFJhdGlvIC0gQXNwZWN0IHJhdGlvIG9mIHRoZSBpbWFnZXMgdG8gZ2VuZXJhdGUuIE11c3QgaGF2ZSB0aGUgZm9ybWF0IGB7d2lkdGh9OntoZWlnaHR9YC5cbkBwYXJhbSBzZWVkIC0gU2VlZCBmb3IgdGhlIGltYWdlIGdlbmVyYXRpb24uXG5AcGFyYW0gcHJvdmlkZXJPcHRpb25zIC0gQWRkaXRpb25hbCBwcm92aWRlci1zcGVjaWZpYyBvcHRpb25zIHRoYXQgYXJlIHBhc3NlZCB0aHJvdWdoIHRvIHRoZSBwcm92aWRlclxuYXMgYm9keSBwYXJhbWV0ZXJzLlxuQHBhcmFtIG1heFJldHJpZXMgLSBNYXhpbXVtIG51bWJlciBvZiByZXRyaWVzLiBTZXQgdG8gMCB0byBkaXNhYmxlIHJldHJpZXMuIERlZmF1bHQ6IDIuXG5AcGFyYW0gYWJvcnRTaWduYWwgLSBBbiBvcHRpb25hbCBhYm9ydCBzaWduYWwgdGhhdCBjYW4gYmUgdXNlZCB0byBjYW5jZWwgdGhlIGNhbGwuXG5AcGFyYW0gaGVhZGVycyAtIEFkZGl0aW9uYWwgSFRUUCBoZWFkZXJzIHRvIGJlIHNlbnQgd2l0aCB0aGUgcmVxdWVzdC4gT25seSBhcHBsaWNhYmxlIGZvciBIVFRQLWJhc2VkIHByb3ZpZGVycy5cblxuQHJldHVybnMgQSByZXN1bHQgb2JqZWN0IHRoYXQgY29udGFpbnMgdGhlIGdlbmVyYXRlZCBpbWFnZXMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZW5lcmF0ZUltYWdlKHtcbiAgbW9kZWwsXG4gIHByb21wdCxcbiAgbiA9IDEsXG4gIG1heEltYWdlc1BlckNhbGwsXG4gIHNpemUsXG4gIGFzcGVjdFJhdGlvLFxuICBzZWVkLFxuICBwcm92aWRlck9wdGlvbnMsXG4gIG1heFJldHJpZXM6IG1heFJldHJpZXNBcmcsXG4gIGFib3J0U2lnbmFsLFxuICBoZWFkZXJzLFxufToge1xuICAvKipcblRoZSBpbWFnZSBtb2RlbCB0byB1c2UuXG4gICAgICovXG4gIG1vZGVsOiBJbWFnZU1vZGVsVjI7XG5cbiAgLyoqXG5UaGUgcHJvbXB0IHRoYXQgc2hvdWxkIGJlIHVzZWQgdG8gZ2VuZXJhdGUgdGhlIGltYWdlLlxuICAgKi9cbiAgcHJvbXB0OiBzdHJpbmc7XG5cbiAgLyoqXG5OdW1iZXIgb2YgaW1hZ2VzIHRvIGdlbmVyYXRlLlxuICAgKi9cbiAgbj86IG51bWJlcjtcblxuICAvKipcbk51bWJlciBvZiBpbWFnZXMgdG8gZ2VuZXJhdGUuXG4gICAqL1xuICBtYXhJbWFnZXNQZXJDYWxsPzogbnVtYmVyO1xuXG4gIC8qKlxuU2l6ZSBvZiB0aGUgaW1hZ2VzIHRvIGdlbmVyYXRlLiBNdXN0IGhhdmUgdGhlIGZvcm1hdCBge3dpZHRofXh7aGVpZ2h0fWAuIElmIG5vdCBwcm92aWRlZCwgdGhlIGRlZmF1bHQgc2l6ZSB3aWxsIGJlIHVzZWQuXG4gICAqL1xuICBzaXplPzogYCR7bnVtYmVyfXgke251bWJlcn1gO1xuXG4gIC8qKlxuQXNwZWN0IHJhdGlvIG9mIHRoZSBpbWFnZXMgdG8gZ2VuZXJhdGUuIE11c3QgaGF2ZSB0aGUgZm9ybWF0IGB7d2lkdGh9OntoZWlnaHR9YC4gSWYgbm90IHByb3ZpZGVkLCB0aGUgZGVmYXVsdCBhc3BlY3QgcmF0aW8gd2lsbCBiZSB1c2VkLlxuICAgKi9cbiAgYXNwZWN0UmF0aW8/OiBgJHtudW1iZXJ9OiR7bnVtYmVyfWA7XG5cbiAgLyoqXG5TZWVkIGZvciB0aGUgaW1hZ2UgZ2VuZXJhdGlvbi4gSWYgbm90IHByb3ZpZGVkLCB0aGUgZGVmYXVsdCBzZWVkIHdpbGwgYmUgdXNlZC5cbiAgICovXG4gIHNlZWQ/OiBudW1iZXI7XG5cbiAgLyoqXG5BZGRpdGlvbmFsIHByb3ZpZGVyLXNwZWNpZmljIG9wdGlvbnMgdGhhdCBhcmUgcGFzc2VkIHRocm91Z2ggdG8gdGhlIHByb3ZpZGVyXG5hcyBib2R5IHBhcmFtZXRlcnMuXG5cblRoZSBvdXRlciByZWNvcmQgaXMga2V5ZWQgYnkgdGhlIHByb3ZpZGVyIG5hbWUsIGFuZCB0aGUgaW5uZXJcbnJlY29yZCBpcyBrZXllZCBieSB0aGUgcHJvdmlkZXItc3BlY2lmaWMgbWV0YWRhdGEga2V5LlxuYGBgdHNcbntcbiAgXCJvcGVuYWlcIjoge1xuICAgIFwic3R5bGVcIjogXCJ2aXZpZFwiXG4gIH1cbn1cbmBgYFxuICAgICAqL1xuICBwcm92aWRlck9wdGlvbnM/OiBQcm92aWRlck9wdGlvbnM7XG5cbiAgLyoqXG5NYXhpbXVtIG51bWJlciBvZiByZXRyaWVzIHBlciBlbWJlZGRpbmcgbW9kZWwgY2FsbC4gU2V0IHRvIDAgdG8gZGlzYWJsZSByZXRyaWVzLlxuXG5AZGVmYXVsdCAyXG4gICAqL1xuICBtYXhSZXRyaWVzPzogbnVtYmVyO1xuXG4gIC8qKlxuQWJvcnQgc2lnbmFsLlxuICovXG4gIGFib3J0U2lnbmFsPzogQWJvcnRTaWduYWw7XG5cbiAgLyoqXG5BZGRpdGlvbmFsIGhlYWRlcnMgdG8gaW5jbHVkZSBpbiB0aGUgcmVxdWVzdC5cbk9ubHkgYXBwbGljYWJsZSBmb3IgSFRUUC1iYXNlZCBwcm92aWRlcnMuXG4gKi9cbiAgaGVhZGVycz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG59KTogUHJvbWlzZTxHZW5lcmF0ZUltYWdlUmVzdWx0PiB7XG4gIGlmIChtb2RlbC5zcGVjaWZpY2F0aW9uVmVyc2lvbiAhPT0gJ3YyJykge1xuICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE1vZGVsVmVyc2lvbkVycm9yKHtcbiAgICAgIHZlcnNpb246IG1vZGVsLnNwZWNpZmljYXRpb25WZXJzaW9uLFxuICAgICAgcHJvdmlkZXI6IG1vZGVsLnByb3ZpZGVyLFxuICAgICAgbW9kZWxJZDogbW9kZWwubW9kZWxJZCxcbiAgICB9KTtcbiAgfVxuXG4gIGNvbnN0IGhlYWRlcnNXaXRoVXNlckFnZW50ID0gd2l0aFVzZXJBZ2VudFN1ZmZpeChcbiAgICBoZWFkZXJzID8/IHt9LFxuICAgIGBhaS8ke1ZFUlNJT059YCxcbiAgKTtcblxuICBjb25zdCB7IHJldHJ5IH0gPSBwcmVwYXJlUmV0cmllcyh7XG4gICAgbWF4UmV0cmllczogbWF4UmV0cmllc0FyZyxcbiAgICBhYm9ydFNpZ25hbCxcbiAgfSk7XG5cbiAgLy8gZGVmYXVsdCB0byAxIGlmIHRoZSBtb2RlbCBoYXMgbm90IHNwZWNpZmllZCBsaW1pdHMgb25cbiAgLy8gaG93IG1hbnkgaW1hZ2VzIGNhbiBiZSBnZW5lcmF0ZWQgaW4gYSBzaW5nbGUgY2FsbFxuICBjb25zdCBtYXhJbWFnZXNQZXJDYWxsV2l0aERlZmF1bHQgPVxuICAgIG1heEltYWdlc1BlckNhbGwgPz8gKGF3YWl0IGludm9rZU1vZGVsTWF4SW1hZ2VzUGVyQ2FsbChtb2RlbCkpID8/IDE7XG5cbiAgLy8gcGFyYWxsZWxpemUgY2FsbHMgdG8gdGhlIG1vZGVsOlxuICBjb25zdCBjYWxsQ291bnQgPSBNYXRoLmNlaWwobiAvIG1heEltYWdlc1BlckNhbGxXaXRoRGVmYXVsdCk7XG4gIGNvbnN0IGNhbGxJbWFnZUNvdW50cyA9IEFycmF5LmZyb20oeyBsZW5ndGg6IGNhbGxDb3VudCB9LCAoXywgaSkgPT4ge1xuICAgIGlmIChpIDwgY2FsbENvdW50IC0gMSkge1xuICAgICAgcmV0dXJuIG1heEltYWdlc1BlckNhbGxXaXRoRGVmYXVsdDtcbiAgICB9XG5cbiAgICBjb25zdCByZW1haW5kZXIgPSBuICUgbWF4SW1hZ2VzUGVyQ2FsbFdpdGhEZWZhdWx0O1xuICAgIHJldHVybiByZW1haW5kZXIgPT09IDAgPyBtYXhJbWFnZXNQZXJDYWxsV2l0aERlZmF1bHQgOiByZW1haW5kZXI7XG4gIH0pO1xuXG4gIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICBjYWxsSW1hZ2VDb3VudHMubWFwKGFzeW5jIGNhbGxJbWFnZUNvdW50ID0+XG4gICAgICByZXRyeSgoKSA9PlxuICAgICAgICBtb2RlbC5kb0dlbmVyYXRlKHtcbiAgICAgICAgICBwcm9tcHQsXG4gICAgICAgICAgbjogY2FsbEltYWdlQ291bnQsXG4gICAgICAgICAgYWJvcnRTaWduYWwsXG4gICAgICAgICAgaGVhZGVyczogaGVhZGVyc1dpdGhVc2VyQWdlbnQsXG4gICAgICAgICAgc2l6ZSxcbiAgICAgICAgICBhc3BlY3RSYXRpbyxcbiAgICAgICAgICBzZWVkLFxuICAgICAgICAgIHByb3ZpZGVyT3B0aW9uczogcHJvdmlkZXJPcHRpb25zID8/IHt9LFxuICAgICAgICB9KSxcbiAgICAgICksXG4gICAgKSxcbiAgKTtcblxuICAvLyBjb2xsZWN0IHJlc3VsdCBpbWFnZXMsIHdhcm5pbmdzLCBhbmQgcmVzcG9uc2UgbWV0YWRhdGFcbiAgY29uc3QgaW1hZ2VzOiBBcnJheTxEZWZhdWx0R2VuZXJhdGVkRmlsZT4gPSBbXTtcbiAgY29uc3Qgd2FybmluZ3M6IEFycmF5PEltYWdlR2VuZXJhdGlvbldhcm5pbmc+ID0gW107XG4gIGNvbnN0IHJlc3BvbnNlczogQXJyYXk8SW1hZ2VNb2RlbFJlc3BvbnNlTWV0YWRhdGE+ID0gW107XG4gIGNvbnN0IHByb3ZpZGVyTWV0YWRhdGE6IEltYWdlTW9kZWxWMlByb3ZpZGVyTWV0YWRhdGEgPSB7fTtcbiAgZm9yIChjb25zdCByZXN1bHQgb2YgcmVzdWx0cykge1xuICAgIGltYWdlcy5wdXNoKFxuICAgICAgLi4ucmVzdWx0LmltYWdlcy5tYXAoXG4gICAgICAgIGltYWdlID0+XG4gICAgICAgICAgbmV3IERlZmF1bHRHZW5lcmF0ZWRGaWxlKHtcbiAgICAgICAgICAgIGRhdGE6IGltYWdlLFxuICAgICAgICAgICAgbWVkaWFUeXBlOlxuICAgICAgICAgICAgICBkZXRlY3RNZWRpYVR5cGUoe1xuICAgICAgICAgICAgICAgIGRhdGE6IGltYWdlLFxuICAgICAgICAgICAgICAgIHNpZ25hdHVyZXM6IGltYWdlTWVkaWFUeXBlU2lnbmF0dXJlcyxcbiAgICAgICAgICAgICAgfSkgPz8gJ2ltYWdlL3BuZycsXG4gICAgICAgICAgfSksXG4gICAgICApLFxuICAgICk7XG4gICAgd2FybmluZ3MucHVzaCguLi5yZXN1bHQud2FybmluZ3MpO1xuXG4gICAgaWYgKHJlc3VsdC5wcm92aWRlck1ldGFkYXRhKSB7XG4gICAgICBmb3IgKGNvbnN0IFtwcm92aWRlck5hbWUsIG1ldGFkYXRhXSBvZiBPYmplY3QuZW50cmllczx7XG4gICAgICAgIGltYWdlczogdW5rbm93bjtcbiAgICAgIH0+KHJlc3VsdC5wcm92aWRlck1ldGFkYXRhKSkge1xuICAgICAgICBwcm92aWRlck1ldGFkYXRhW3Byb3ZpZGVyTmFtZV0gPz89IHsgaW1hZ2VzOiBbXSB9O1xuICAgICAgICBwcm92aWRlck1ldGFkYXRhW3Byb3ZpZGVyTmFtZV0uaW1hZ2VzLnB1c2goXG4gICAgICAgICAgLi4ucmVzdWx0LnByb3ZpZGVyTWV0YWRhdGFbcHJvdmlkZXJOYW1lXS5pbWFnZXMsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmVzcG9uc2VzLnB1c2gocmVzdWx0LnJlc3BvbnNlKTtcbiAgfVxuXG4gIGxvZ1dhcm5pbmdzKHdhcm5pbmdzKTtcblxuICBpZiAoIWltYWdlcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgTm9JbWFnZUdlbmVyYXRlZEVycm9yKHsgcmVzcG9uc2VzIH0pO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBEZWZhdWx0R2VuZXJhdGVJbWFnZVJlc3VsdCh7XG4gICAgaW1hZ2VzLFxuICAgIHdhcm5pbmdzLFxuICAgIHJlc3BvbnNlcyxcbiAgICBwcm92aWRlck1ldGFkYXRhLFxuICB9KTtcbn1cblxuY2xhc3MgRGVmYXVsdEdlbmVyYXRlSW1hZ2VSZXN1bHQgaW1wbGVtZW50cyBHZW5lcmF0ZUltYWdlUmVzdWx0IHtcbiAgcmVhZG9ubHkgaW1hZ2VzOiBBcnJheTxHZW5lcmF0ZWRGaWxlPjtcbiAgcmVhZG9ubHkgd2FybmluZ3M6IEFycmF5PEltYWdlR2VuZXJhdGlvbldhcm5pbmc+O1xuICByZWFkb25seSByZXNwb25zZXM6IEFycmF5PEltYWdlTW9kZWxSZXNwb25zZU1ldGFkYXRhPjtcbiAgcmVhZG9ubHkgcHJvdmlkZXJNZXRhZGF0YTogSW1hZ2VNb2RlbFYyUHJvdmlkZXJNZXRhZGF0YTtcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiB7XG4gICAgaW1hZ2VzOiBBcnJheTxHZW5lcmF0ZWRGaWxlPjtcbiAgICB3YXJuaW5nczogQXJyYXk8SW1hZ2VHZW5lcmF0aW9uV2FybmluZz47XG4gICAgcmVzcG9uc2VzOiBBcnJheTxJbWFnZU1vZGVsUmVzcG9uc2VNZXRhZGF0YT47XG4gICAgcHJvdmlkZXJNZXRhZGF0YTogSW1hZ2VNb2RlbFYyUHJvdmlkZXJNZXRhZGF0YTtcbiAgfSkge1xuICAgIHRoaXMuaW1hZ2VzID0gb3B0aW9ucy5pbWFnZXM7XG4gICAgdGhpcy53YXJuaW5ncyA9IG9wdGlvbnMud2FybmluZ3M7XG4gICAgdGhpcy5yZXNwb25zZXMgPSBvcHRpb25zLnJlc3BvbnNlcztcbiAgICB0aGlzLnByb3ZpZGVyTWV0YWRhdGEgPSBvcHRpb25zLnByb3ZpZGVyTWV0YWRhdGE7XG4gIH1cblxuICBnZXQgaW1hZ2UoKSB7XG4gICAgcmV0dXJuIHRoaXMuaW1hZ2VzWzBdO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGludm9rZU1vZGVsTWF4SW1hZ2VzUGVyQ2FsbChtb2RlbDogSW1hZ2VNb2RlbFYyKSB7XG4gIGNvbnN0IGlzRnVuY3Rpb24gPSBtb2RlbC5tYXhJbWFnZXNQZXJDYWxsIGluc3RhbmNlb2YgRnVuY3Rpb247XG5cbiAgaWYgKCFpc0Z1bmN0aW9uKSB7XG4gICAgcmV0dXJuIG1vZGVsLm1heEltYWdlc1BlckNhbGw7XG4gIH1cblxuICByZXR1cm4gbW9kZWwubWF4SW1hZ2VzUGVyQ2FsbCh7XG4gICAgbW9kZWxJZDogbW9kZWwubW9kZWxJZCxcbiAgfSk7XG59XG4iLCAiaW1wb3J0IHsgSlNPTlZhbHVlIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQge1xuICBjcmVhdGVJZEdlbmVyYXRvcixcbiAgRmxleGlibGVTY2hlbWEsXG4gIEluZmVyU2NoZW1hLFxuICBQcm92aWRlck9wdGlvbnMsXG4gIHdpdGhVc2VyQWdlbnRTdWZmaXgsXG59IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXItdXRpbHMnO1xuaW1wb3J0IHsgTm9PYmplY3RHZW5lcmF0ZWRFcnJvciB9IGZyb20gJy4uL2Vycm9yL25vLW9iamVjdC1nZW5lcmF0ZWQtZXJyb3InO1xuaW1wb3J0IHsgZXh0cmFjdFJlYXNvbmluZ0NvbnRlbnQgfSBmcm9tICcuLi9nZW5lcmF0ZS10ZXh0L2V4dHJhY3QtcmVhc29uaW5nLWNvbnRlbnQnO1xuaW1wb3J0IHsgZXh0cmFjdFRleHRDb250ZW50IH0gZnJvbSAnLi4vZ2VuZXJhdGUtdGV4dC9leHRyYWN0LXRleHQtY29udGVudCc7XG5pbXBvcnQgeyBsb2dXYXJuaW5ncyB9IGZyb20gJy4uL2xvZ2dlci9sb2ctd2FybmluZ3MnO1xuaW1wb3J0IHsgcmVzb2x2ZUxhbmd1YWdlTW9kZWwgfSBmcm9tICcuLi9tb2RlbC9yZXNvbHZlLW1vZGVsJztcbmltcG9ydCB7IENhbGxTZXR0aW5ncyB9IGZyb20gJy4uL3Byb21wdC9jYWxsLXNldHRpbmdzJztcbmltcG9ydCB7IGNvbnZlcnRUb0xhbmd1YWdlTW9kZWxQcm9tcHQgfSBmcm9tICcuLi9wcm9tcHQvY29udmVydC10by1sYW5ndWFnZS1tb2RlbC1wcm9tcHQnO1xuaW1wb3J0IHsgcHJlcGFyZUNhbGxTZXR0aW5ncyB9IGZyb20gJy4uL3Byb21wdC9wcmVwYXJlLWNhbGwtc2V0dGluZ3MnO1xuaW1wb3J0IHsgUHJvbXB0IH0gZnJvbSAnLi4vcHJvbXB0L3Byb21wdCc7XG5pbXBvcnQgeyBzdGFuZGFyZGl6ZVByb21wdCB9IGZyb20gJy4uL3Byb21wdC9zdGFuZGFyZGl6ZS1wcm9tcHQnO1xuaW1wb3J0IHsgd3JhcEdhdGV3YXlFcnJvciB9IGZyb20gJy4uL3Byb21wdC93cmFwLWdhdGV3YXktZXJyb3InO1xuaW1wb3J0IHsgYXNzZW1ibGVPcGVyYXRpb25OYW1lIH0gZnJvbSAnLi4vdGVsZW1ldHJ5L2Fzc2VtYmxlLW9wZXJhdGlvbi1uYW1lJztcbmltcG9ydCB7IGdldEJhc2VUZWxlbWV0cnlBdHRyaWJ1dGVzIH0gZnJvbSAnLi4vdGVsZW1ldHJ5L2dldC1iYXNlLXRlbGVtZXRyeS1hdHRyaWJ1dGVzJztcbmltcG9ydCB7IGdldFRyYWNlciB9IGZyb20gJy4uL3RlbGVtZXRyeS9nZXQtdHJhY2VyJztcbmltcG9ydCB7IHJlY29yZFNwYW4gfSBmcm9tICcuLi90ZWxlbWV0cnkvcmVjb3JkLXNwYW4nO1xuaW1wb3J0IHsgc2VsZWN0VGVsZW1ldHJ5QXR0cmlidXRlcyB9IGZyb20gJy4uL3RlbGVtZXRyeS9zZWxlY3QtdGVsZW1ldHJ5LWF0dHJpYnV0ZXMnO1xuaW1wb3J0IHsgc3RyaW5naWZ5Rm9yVGVsZW1ldHJ5IH0gZnJvbSAnLi4vdGVsZW1ldHJ5L3N0cmluZ2lmeS1mb3ItdGVsZW1ldHJ5JztcbmltcG9ydCB7IFRlbGVtZXRyeVNldHRpbmdzIH0gZnJvbSAnLi4vdGVsZW1ldHJ5L3RlbGVtZXRyeS1zZXR0aW5ncyc7XG5pbXBvcnQge1xuICBDYWxsV2FybmluZyxcbiAgRmluaXNoUmVhc29uLFxuICBMYW5ndWFnZU1vZGVsLFxufSBmcm9tICcuLi90eXBlcy9sYW5ndWFnZS1tb2RlbCc7XG5pbXBvcnQgeyBMYW5ndWFnZU1vZGVsUmVxdWVzdE1ldGFkYXRhIH0gZnJvbSAnLi4vdHlwZXMvbGFuZ3VhZ2UtbW9kZWwtcmVxdWVzdC1tZXRhZGF0YSc7XG5pbXBvcnQgeyBMYW5ndWFnZU1vZGVsUmVzcG9uc2VNZXRhZGF0YSB9IGZyb20gJy4uL3R5cGVzL2xhbmd1YWdlLW1vZGVsLXJlc3BvbnNlLW1ldGFkYXRhJztcbmltcG9ydCB7IFByb3ZpZGVyTWV0YWRhdGEgfSBmcm9tICcuLi90eXBlcy9wcm92aWRlci1tZXRhZGF0YSc7XG5pbXBvcnQgeyBMYW5ndWFnZU1vZGVsVXNhZ2UgfSBmcm9tICcuLi90eXBlcy91c2FnZSc7XG5pbXBvcnQgeyBEb3dubG9hZEZ1bmN0aW9uIH0gZnJvbSAnLi4vdXRpbC9kb3dubG9hZC9kb3dubG9hZC1mdW5jdGlvbic7XG5pbXBvcnQgeyBwcmVwYXJlSGVhZGVycyB9IGZyb20gJy4uL3V0aWwvcHJlcGFyZS1oZWFkZXJzJztcbmltcG9ydCB7IHByZXBhcmVSZXRyaWVzIH0gZnJvbSAnLi4vdXRpbC9wcmVwYXJlLXJldHJpZXMnO1xuaW1wb3J0IHsgVkVSU0lPTiB9IGZyb20gJy4uL3ZlcnNpb24nO1xuaW1wb3J0IHsgR2VuZXJhdGVPYmplY3RSZXN1bHQgfSBmcm9tICcuL2dlbmVyYXRlLW9iamVjdC1yZXN1bHQnO1xuaW1wb3J0IHsgZ2V0T3V0cHV0U3RyYXRlZ3kgfSBmcm9tICcuL291dHB1dC1zdHJhdGVneSc7XG5pbXBvcnQgeyBwYXJzZUFuZFZhbGlkYXRlT2JqZWN0UmVzdWx0V2l0aFJlcGFpciB9IGZyb20gJy4vcGFyc2UtYW5kLXZhbGlkYXRlLW9iamVjdC1yZXN1bHQnO1xuaW1wb3J0IHsgUmVwYWlyVGV4dEZ1bmN0aW9uIH0gZnJvbSAnLi9yZXBhaXItdGV4dCc7XG5pbXBvcnQgeyB2YWxpZGF0ZU9iamVjdEdlbmVyYXRpb25JbnB1dCB9IGZyb20gJy4vdmFsaWRhdGUtb2JqZWN0LWdlbmVyYXRpb24taW5wdXQnO1xuXG5jb25zdCBvcmlnaW5hbEdlbmVyYXRlSWQgPSBjcmVhdGVJZEdlbmVyYXRvcih7IHByZWZpeDogJ2Fpb2JqJywgc2l6ZTogMjQgfSk7XG5cbi8qKlxuR2VuZXJhdGUgYSBzdHJ1Y3R1cmVkLCB0eXBlZCBvYmplY3QgZm9yIGEgZ2l2ZW4gcHJvbXB0IGFuZCBzY2hlbWEgdXNpbmcgYSBsYW5ndWFnZSBtb2RlbC5cblxuVGhpcyBmdW5jdGlvbiBkb2VzIG5vdCBzdHJlYW0gdGhlIG91dHB1dC4gSWYgeW91IHdhbnQgdG8gc3RyZWFtIHRoZSBvdXRwdXQsIHVzZSBgc3RyZWFtT2JqZWN0YCBpbnN0ZWFkLlxuXG5AcGFyYW0gbW9kZWwgLSBUaGUgbGFuZ3VhZ2UgbW9kZWwgdG8gdXNlLlxuQHBhcmFtIHRvb2xzIC0gVG9vbHMgdGhhdCBhcmUgYWNjZXNzaWJsZSB0byBhbmQgY2FuIGJlIGNhbGxlZCBieSB0aGUgbW9kZWwuIFRoZSBtb2RlbCBuZWVkcyB0byBzdXBwb3J0IGNhbGxpbmcgdG9vbHMuXG5cbkBwYXJhbSBzeXN0ZW0gLSBBIHN5c3RlbSBtZXNzYWdlIHRoYXQgd2lsbCBiZSBwYXJ0IG9mIHRoZSBwcm9tcHQuXG5AcGFyYW0gcHJvbXB0IC0gQSBzaW1wbGUgdGV4dCBwcm9tcHQuIFlvdSBjYW4gZWl0aGVyIHVzZSBgcHJvbXB0YCBvciBgbWVzc2FnZXNgIGJ1dCBub3QgYm90aC5cbkBwYXJhbSBtZXNzYWdlcyAtIEEgbGlzdCBvZiBtZXNzYWdlcy4gWW91IGNhbiBlaXRoZXIgdXNlIGBwcm9tcHRgIG9yIGBtZXNzYWdlc2AgYnV0IG5vdCBib3RoLlxuXG5AcGFyYW0gbWF4T3V0cHV0VG9rZW5zIC0gTWF4aW11bSBudW1iZXIgb2YgdG9rZW5zIHRvIGdlbmVyYXRlLlxuQHBhcmFtIHRlbXBlcmF0dXJlIC0gVGVtcGVyYXR1cmUgc2V0dGluZy5cblRoZSB2YWx1ZSBpcyBwYXNzZWQgdGhyb3VnaCB0byB0aGUgcHJvdmlkZXIuIFRoZSByYW5nZSBkZXBlbmRzIG9uIHRoZSBwcm92aWRlciBhbmQgbW9kZWwuXG5JdCBpcyByZWNvbW1lbmRlZCB0byBzZXQgZWl0aGVyIGB0ZW1wZXJhdHVyZWAgb3IgYHRvcFBgLCBidXQgbm90IGJvdGguXG5AcGFyYW0gdG9wUCAtIE51Y2xldXMgc2FtcGxpbmcuXG5UaGUgdmFsdWUgaXMgcGFzc2VkIHRocm91Z2ggdG8gdGhlIHByb3ZpZGVyLiBUaGUgcmFuZ2UgZGVwZW5kcyBvbiB0aGUgcHJvdmlkZXIgYW5kIG1vZGVsLlxuSXQgaXMgcmVjb21tZW5kZWQgdG8gc2V0IGVpdGhlciBgdGVtcGVyYXR1cmVgIG9yIGB0b3BQYCwgYnV0IG5vdCBib3RoLlxuQHBhcmFtIHRvcEsgLSBPbmx5IHNhbXBsZSBmcm9tIHRoZSB0b3AgSyBvcHRpb25zIGZvciBlYWNoIHN1YnNlcXVlbnQgdG9rZW4uXG5Vc2VkIHRvIHJlbW92ZSBcImxvbmcgdGFpbFwiIGxvdyBwcm9iYWJpbGl0eSByZXNwb25zZXMuXG5SZWNvbW1lbmRlZCBmb3IgYWR2YW5jZWQgdXNlIGNhc2VzIG9ubHkuIFlvdSB1c3VhbGx5IG9ubHkgbmVlZCB0byB1c2UgdGVtcGVyYXR1cmUuXG5AcGFyYW0gcHJlc2VuY2VQZW5hbHR5IC0gUHJlc2VuY2UgcGVuYWx0eSBzZXR0aW5nLlxuSXQgYWZmZWN0cyB0aGUgbGlrZWxpaG9vZCBvZiB0aGUgbW9kZWwgdG8gcmVwZWF0IGluZm9ybWF0aW9uIHRoYXQgaXMgYWxyZWFkeSBpbiB0aGUgcHJvbXB0LlxuVGhlIHZhbHVlIGlzIHBhc3NlZCB0aHJvdWdoIHRvIHRoZSBwcm92aWRlci4gVGhlIHJhbmdlIGRlcGVuZHMgb24gdGhlIHByb3ZpZGVyIGFuZCBtb2RlbC5cbkBwYXJhbSBmcmVxdWVuY3lQZW5hbHR5IC0gRnJlcXVlbmN5IHBlbmFsdHkgc2V0dGluZy5cbkl0IGFmZmVjdHMgdGhlIGxpa2VsaWhvb2Qgb2YgdGhlIG1vZGVsIHRvIHJlcGVhdGVkbHkgdXNlIHRoZSBzYW1lIHdvcmRzIG9yIHBocmFzZXMuXG5UaGUgdmFsdWUgaXMgcGFzc2VkIHRocm91Z2ggdG8gdGhlIHByb3ZpZGVyLiBUaGUgcmFuZ2UgZGVwZW5kcyBvbiB0aGUgcHJvdmlkZXIgYW5kIG1vZGVsLlxuQHBhcmFtIHN0b3BTZXF1ZW5jZXMgLSBTdG9wIHNlcXVlbmNlcy5cbklmIHNldCwgdGhlIG1vZGVsIHdpbGwgc3RvcCBnZW5lcmF0aW5nIHRleHQgd2hlbiBvbmUgb2YgdGhlIHN0b3Agc2VxdWVuY2VzIGlzIGdlbmVyYXRlZC5cbkBwYXJhbSBzZWVkIC0gVGhlIHNlZWQgKGludGVnZXIpIHRvIHVzZSBmb3IgcmFuZG9tIHNhbXBsaW5nLlxuSWYgc2V0IGFuZCBzdXBwb3J0ZWQgYnkgdGhlIG1vZGVsLCBjYWxscyB3aWxsIGdlbmVyYXRlIGRldGVybWluaXN0aWMgcmVzdWx0cy5cblxuQHBhcmFtIG1heFJldHJpZXMgLSBNYXhpbXVtIG51bWJlciBvZiByZXRyaWVzLiBTZXQgdG8gMCB0byBkaXNhYmxlIHJldHJpZXMuIERlZmF1bHQ6IDIuXG5AcGFyYW0gYWJvcnRTaWduYWwgLSBBbiBvcHRpb25hbCBhYm9ydCBzaWduYWwgdGhhdCBjYW4gYmUgdXNlZCB0byBjYW5jZWwgdGhlIGNhbGwuXG5AcGFyYW0gaGVhZGVycyAtIEFkZGl0aW9uYWwgSFRUUCBoZWFkZXJzIHRvIGJlIHNlbnQgd2l0aCB0aGUgcmVxdWVzdC4gT25seSBhcHBsaWNhYmxlIGZvciBIVFRQLWJhc2VkIHByb3ZpZGVycy5cblxuQHBhcmFtIHNjaGVtYSAtIFRoZSBzY2hlbWEgb2YgdGhlIG9iamVjdCB0aGF0IHRoZSBtb2RlbCBzaG91bGQgZ2VuZXJhdGUuXG5AcGFyYW0gc2NoZW1hTmFtZSAtIE9wdGlvbmFsIG5hbWUgb2YgdGhlIG91dHB1dCB0aGF0IHNob3VsZCBiZSBnZW5lcmF0ZWQuXG5Vc2VkIGJ5IHNvbWUgcHJvdmlkZXJzIGZvciBhZGRpdGlvbmFsIExMTSBndWlkYW5jZSwgZS5nLlxudmlhIHRvb2wgb3Igc2NoZW1hIG5hbWUuXG5AcGFyYW0gc2NoZW1hRGVzY3JpcHRpb24gLSBPcHRpb25hbCBkZXNjcmlwdGlvbiBvZiB0aGUgb3V0cHV0IHRoYXQgc2hvdWxkIGJlIGdlbmVyYXRlZC5cblVzZWQgYnkgc29tZSBwcm92aWRlcnMgZm9yIGFkZGl0aW9uYWwgTExNIGd1aWRhbmNlLCBlLmcuXG52aWEgdG9vbCBvciBzY2hlbWEgZGVzY3JpcHRpb24uXG5cbkBwYXJhbSBvdXRwdXQgLSBUaGUgdHlwZSBvZiB0aGUgb3V0cHV0LlxuXG4tICdvYmplY3QnOiBUaGUgb3V0cHV0IGlzIGFuIG9iamVjdC5cbi0gJ2FycmF5JzogVGhlIG91dHB1dCBpcyBhbiBhcnJheS5cbi0gJ2VudW0nOiBUaGUgb3V0cHV0IGlzIGFuIGVudW0uXG4tICduby1zY2hlbWEnOiBUaGUgb3V0cHV0IGlzIG5vdCBhIHNjaGVtYS5cblxuQHBhcmFtIGV4cGVyaW1lbnRhbF9yZXBhaXJUZXh0IC0gQSBmdW5jdGlvbiB0aGF0IGF0dGVtcHRzIHRvIHJlcGFpciB0aGUgcmF3IG91dHB1dCBvZiB0aGUgbW9kZWxcbnRvIGVuYWJsZSBKU09OIHBhcnNpbmcuXG5cbkBwYXJhbSBleHBlcmltZW50YWxfdGVsZW1ldHJ5IC0gT3B0aW9uYWwgdGVsZW1ldHJ5IGNvbmZpZ3VyYXRpb24gKGV4cGVyaW1lbnRhbCkuXG5cbkBwYXJhbSBwcm92aWRlck9wdGlvbnMgLSBBZGRpdGlvbmFsIHByb3ZpZGVyLXNwZWNpZmljIG9wdGlvbnMuIFRoZXkgYXJlIHBhc3NlZCB0aHJvdWdoXG50byB0aGUgcHJvdmlkZXIgZnJvbSB0aGUgQUkgU0RLIGFuZCBlbmFibGUgcHJvdmlkZXItc3BlY2lmaWNcbmZ1bmN0aW9uYWxpdHkgdGhhdCBjYW4gYmUgZnVsbHkgZW5jYXBzdWxhdGVkIGluIHRoZSBwcm92aWRlci5cblxuQHJldHVybnNcbkEgcmVzdWx0IG9iamVjdCB0aGF0IGNvbnRhaW5zIHRoZSBnZW5lcmF0ZWQgb2JqZWN0LCB0aGUgZmluaXNoIHJlYXNvbiwgdGhlIHRva2VuIHVzYWdlLCBhbmQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbi5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlT2JqZWN0PFxuICBTQ0hFTUEgZXh0ZW5kcyBGbGV4aWJsZVNjaGVtYTx1bmtub3duPiA9IEZsZXhpYmxlU2NoZW1hPEpTT05WYWx1ZT4sXG4gIE9VVFBVVCBleHRlbmRzXG4gICAgfCAnb2JqZWN0J1xuICAgIHwgJ2FycmF5J1xuICAgIHwgJ2VudW0nXG4gICAgfCAnbm8tc2NoZW1hJyA9IEluZmVyU2NoZW1hPFNDSEVNQT4gZXh0ZW5kcyBzdHJpbmcgPyAnZW51bScgOiAnb2JqZWN0JyxcbiAgUkVTVUxUID0gT1VUUFVUIGV4dGVuZHMgJ2FycmF5J1xuICAgID8gQXJyYXk8SW5mZXJTY2hlbWE8U0NIRU1BPj5cbiAgICA6IEluZmVyU2NoZW1hPFNDSEVNQT4sXG4+KFxuICBvcHRpb25zOiBPbWl0PENhbGxTZXR0aW5ncywgJ3N0b3BTZXF1ZW5jZXMnPiAmXG4gICAgUHJvbXB0ICZcbiAgICAoT1VUUFVUIGV4dGVuZHMgJ2VudW0nXG4gICAgICA/IHtcbiAgICAgICAgICAvKipcblRoZSBlbnVtIHZhbHVlcyB0aGF0IHRoZSBtb2RlbCBzaG91bGQgdXNlLlxuICAgICAgICAqL1xuICAgICAgICAgIGVudW06IEFycmF5PFJFU1VMVD47XG4gICAgICAgICAgbW9kZT86ICdqc29uJztcbiAgICAgICAgICBvdXRwdXQ6ICdlbnVtJztcbiAgICAgICAgfVxuICAgICAgOiBPVVRQVVQgZXh0ZW5kcyAnbm8tc2NoZW1hJ1xuICAgICAgICA/IHt9XG4gICAgICAgIDoge1xuICAgICAgICAgICAgLyoqXG5UaGUgc2NoZW1hIG9mIHRoZSBvYmplY3QgdGhhdCB0aGUgbW9kZWwgc2hvdWxkIGdlbmVyYXRlLlxuICAgICAgICAqL1xuICAgICAgICAgICAgc2NoZW1hOiBTQ0hFTUE7XG5cbiAgICAgICAgICAgIC8qKlxuT3B0aW9uYWwgbmFtZSBvZiB0aGUgb3V0cHV0IHRoYXQgc2hvdWxkIGJlIGdlbmVyYXRlZC5cblVzZWQgYnkgc29tZSBwcm92aWRlcnMgZm9yIGFkZGl0aW9uYWwgTExNIGd1aWRhbmNlLCBlLmcuXG52aWEgdG9vbCBvciBzY2hlbWEgbmFtZS5cbiAgICAgICAgKi9cbiAgICAgICAgICAgIHNjaGVtYU5hbWU/OiBzdHJpbmc7XG5cbiAgICAgICAgICAgIC8qKlxuT3B0aW9uYWwgZGVzY3JpcHRpb24gb2YgdGhlIG91dHB1dCB0aGF0IHNob3VsZCBiZSBnZW5lcmF0ZWQuXG5Vc2VkIGJ5IHNvbWUgcHJvdmlkZXJzIGZvciBhZGRpdGlvbmFsIExMTSBndWlkYW5jZSwgZS5nLlxudmlhIHRvb2wgb3Igc2NoZW1hIGRlc2NyaXB0aW9uLlxuICAgICAgICAqL1xuICAgICAgICAgICAgc2NoZW1hRGVzY3JpcHRpb24/OiBzdHJpbmc7XG5cbiAgICAgICAgICAgIC8qKlxuVGhlIG1vZGUgdG8gdXNlIGZvciBvYmplY3QgZ2VuZXJhdGlvbi5cblxuVGhlIHNjaGVtYSBpcyBjb252ZXJ0ZWQgaW50byBhIEpTT04gc2NoZW1hIGFuZCB1c2VkIGluIG9uZSBvZiB0aGUgZm9sbG93aW5nIHdheXNcblxuLSAnYXV0byc6IFRoZSBwcm92aWRlciB3aWxsIGNob29zZSB0aGUgYmVzdCBtb2RlIGZvciB0aGUgbW9kZWwuXG4tICd0b29sJzogQSB0b29sIHdpdGggdGhlIEpTT04gc2NoZW1hIGFzIHBhcmFtZXRlcnMgaXMgcHJvdmlkZWQgYW5kIHRoZSBwcm92aWRlciBpcyBpbnN0cnVjdGVkIHRvIHVzZSBpdC5cbi0gJ2pzb24nOiBUaGUgSlNPTiBzY2hlbWEgYW5kIGFuIGluc3RydWN0aW9uIGFyZSBpbmplY3RlZCBpbnRvIHRoZSBwcm9tcHQuIElmIHRoZSBwcm92aWRlciBzdXBwb3J0cyBKU09OIG1vZGUsIGl0IGlzIGVuYWJsZWQuIElmIHRoZSBwcm92aWRlciBzdXBwb3J0cyBKU09OIGdyYW1tYXJzLCB0aGUgZ3JhbW1hciBpcyB1c2VkLlxuXG5QbGVhc2Ugbm90ZSB0aGF0IG1vc3QgcHJvdmlkZXJzIGRvIG5vdCBzdXBwb3J0IGFsbCBtb2Rlcy5cblxuRGVmYXVsdCBhbmQgcmVjb21tZW5kZWQ6ICdhdXRvJyAoYmVzdCBtb2RlIGZvciB0aGUgbW9kZWwpLlxuICAgICAgICAqL1xuICAgICAgICAgICAgbW9kZT86ICdhdXRvJyB8ICdqc29uJyB8ICd0b29sJztcbiAgICAgICAgICB9KSAmIHtcbiAgICAgIG91dHB1dD86IE9VVFBVVDtcblxuICAgICAgLyoqXG4gIFRoZSBsYW5ndWFnZSBtb2RlbCB0byB1c2UuXG4gICAgICAgKi9cbiAgICAgIG1vZGVsOiBMYW5ndWFnZU1vZGVsO1xuICAgICAgLyoqXG4gIEEgZnVuY3Rpb24gdGhhdCBhdHRlbXB0cyB0byByZXBhaXIgdGhlIHJhdyBvdXRwdXQgb2YgdGhlIG1vZGVsXG4gIHRvIGVuYWJsZSBKU09OIHBhcnNpbmcuXG4gICAgICAgKi9cbiAgICAgIGV4cGVyaW1lbnRhbF9yZXBhaXJUZXh0PzogUmVwYWlyVGV4dEZ1bmN0aW9uO1xuXG4gICAgICAvKipcbiAgT3B0aW9uYWwgdGVsZW1ldHJ5IGNvbmZpZ3VyYXRpb24gKGV4cGVyaW1lbnRhbCkuXG4gICAgICAgICAqL1xuXG4gICAgICBleHBlcmltZW50YWxfdGVsZW1ldHJ5PzogVGVsZW1ldHJ5U2V0dGluZ3M7XG5cbiAgICAgIC8qKlxuICBDdXN0b20gZG93bmxvYWQgZnVuY3Rpb24gdG8gdXNlIGZvciBVUkxzLlxuXG4gIEJ5IGRlZmF1bHQsIGZpbGVzIGFyZSBkb3dubG9hZGVkIGlmIHRoZSBtb2RlbCBkb2VzIG5vdCBzdXBwb3J0IHRoZSBVUkwgZm9yIHRoZSBnaXZlbiBtZWRpYSB0eXBlLlxuICAgICAgICovXG4gICAgICBleHBlcmltZW50YWxfZG93bmxvYWQ/OiBEb3dubG9hZEZ1bmN0aW9uIHwgdW5kZWZpbmVkO1xuXG4gICAgICAvKipcbiAgQWRkaXRpb25hbCBwcm92aWRlci1zcGVjaWZpYyBvcHRpb25zLiBUaGV5IGFyZSBwYXNzZWQgdGhyb3VnaFxuICB0byB0aGUgcHJvdmlkZXIgZnJvbSB0aGUgQUkgU0RLIGFuZCBlbmFibGUgcHJvdmlkZXItc3BlY2lmaWNcbiAgZnVuY3Rpb25hbGl0eSB0aGF0IGNhbiBiZSBmdWxseSBlbmNhcHN1bGF0ZWQgaW4gdGhlIHByb3ZpZGVyLlxuICAgKi9cbiAgICAgIHByb3ZpZGVyT3B0aW9ucz86IFByb3ZpZGVyT3B0aW9ucztcblxuICAgICAgLyoqXG4gICAgICAgKiBJbnRlcm5hbC4gRm9yIHRlc3QgdXNlIG9ubHkuIE1heSBjaGFuZ2Ugd2l0aG91dCBub3RpY2UuXG4gICAgICAgKi9cbiAgICAgIF9pbnRlcm5hbD86IHtcbiAgICAgICAgZ2VuZXJhdGVJZD86ICgpID0+IHN0cmluZztcbiAgICAgICAgY3VycmVudERhdGU/OiAoKSA9PiBEYXRlO1xuICAgICAgfTtcbiAgICB9LFxuKTogUHJvbWlzZTxHZW5lcmF0ZU9iamVjdFJlc3VsdDxSRVNVTFQ+PiB7XG4gIGNvbnN0IHtcbiAgICBtb2RlbDogbW9kZWxBcmcsXG4gICAgb3V0cHV0ID0gJ29iamVjdCcsXG4gICAgc3lzdGVtLFxuICAgIHByb21wdCxcbiAgICBtZXNzYWdlcyxcbiAgICBtYXhSZXRyaWVzOiBtYXhSZXRyaWVzQXJnLFxuICAgIGFib3J0U2lnbmFsLFxuICAgIGhlYWRlcnMsXG4gICAgZXhwZXJpbWVudGFsX3JlcGFpclRleHQ6IHJlcGFpclRleHQsXG4gICAgZXhwZXJpbWVudGFsX3RlbGVtZXRyeTogdGVsZW1ldHJ5LFxuICAgIGV4cGVyaW1lbnRhbF9kb3dubG9hZDogZG93bmxvYWQsXG4gICAgcHJvdmlkZXJPcHRpb25zLFxuICAgIF9pbnRlcm5hbDoge1xuICAgICAgZ2VuZXJhdGVJZCA9IG9yaWdpbmFsR2VuZXJhdGVJZCxcbiAgICAgIGN1cnJlbnREYXRlID0gKCkgPT4gbmV3IERhdGUoKSxcbiAgICB9ID0ge30sXG4gICAgLi4uc2V0dGluZ3NcbiAgfSA9IG9wdGlvbnM7XG5cbiAgY29uc3QgbW9kZWwgPSByZXNvbHZlTGFuZ3VhZ2VNb2RlbChtb2RlbEFyZyk7XG5cbiAgY29uc3QgZW51bVZhbHVlcyA9ICdlbnVtJyBpbiBvcHRpb25zID8gb3B0aW9ucy5lbnVtIDogdW5kZWZpbmVkO1xuICBjb25zdCB7XG4gICAgc2NoZW1hOiBpbnB1dFNjaGVtYSxcbiAgICBzY2hlbWFEZXNjcmlwdGlvbixcbiAgICBzY2hlbWFOYW1lLFxuICB9ID0gJ3NjaGVtYScgaW4gb3B0aW9ucyA/IG9wdGlvbnMgOiB7fTtcblxuICB2YWxpZGF0ZU9iamVjdEdlbmVyYXRpb25JbnB1dCh7XG4gICAgb3V0cHV0LFxuICAgIHNjaGVtYTogaW5wdXRTY2hlbWEsXG4gICAgc2NoZW1hTmFtZSxcbiAgICBzY2hlbWFEZXNjcmlwdGlvbixcbiAgICBlbnVtVmFsdWVzLFxuICB9KTtcblxuICBjb25zdCB7IG1heFJldHJpZXMsIHJldHJ5IH0gPSBwcmVwYXJlUmV0cmllcyh7XG4gICAgbWF4UmV0cmllczogbWF4UmV0cmllc0FyZyxcbiAgICBhYm9ydFNpZ25hbCxcbiAgfSk7XG5cbiAgY29uc3Qgb3V0cHV0U3RyYXRlZ3kgPSBnZXRPdXRwdXRTdHJhdGVneSh7XG4gICAgb3V0cHV0LFxuICAgIHNjaGVtYTogaW5wdXRTY2hlbWEsXG4gICAgZW51bVZhbHVlcyxcbiAgfSk7XG5cbiAgY29uc3QgY2FsbFNldHRpbmdzID0gcHJlcGFyZUNhbGxTZXR0aW5ncyhzZXR0aW5ncyk7XG5cbiAgY29uc3QgaGVhZGVyc1dpdGhVc2VyQWdlbnQgPSB3aXRoVXNlckFnZW50U3VmZml4KFxuICAgIGhlYWRlcnMgPz8ge30sXG4gICAgYGFpLyR7VkVSU0lPTn1gLFxuICApO1xuXG4gIGNvbnN0IGJhc2VUZWxlbWV0cnlBdHRyaWJ1dGVzID0gZ2V0QmFzZVRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgIG1vZGVsLFxuICAgIHRlbGVtZXRyeSxcbiAgICBoZWFkZXJzOiBoZWFkZXJzV2l0aFVzZXJBZ2VudCxcbiAgICBzZXR0aW5nczogeyAuLi5jYWxsU2V0dGluZ3MsIG1heFJldHJpZXMgfSxcbiAgfSk7XG5cbiAgY29uc3QgdHJhY2VyID0gZ2V0VHJhY2VyKHRlbGVtZXRyeSk7XG5cbiAgdHJ5IHtcbiAgICByZXR1cm4gYXdhaXQgcmVjb3JkU3Bhbih7XG4gICAgICBuYW1lOiAnYWkuZ2VuZXJhdGVPYmplY3QnLFxuICAgICAgYXR0cmlidXRlczogc2VsZWN0VGVsZW1ldHJ5QXR0cmlidXRlcyh7XG4gICAgICAgIHRlbGVtZXRyeSxcbiAgICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAgIC4uLmFzc2VtYmxlT3BlcmF0aW9uTmFtZSh7XG4gICAgICAgICAgICBvcGVyYXRpb25JZDogJ2FpLmdlbmVyYXRlT2JqZWN0JyxcbiAgICAgICAgICAgIHRlbGVtZXRyeSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICAuLi5iYXNlVGVsZW1ldHJ5QXR0cmlidXRlcyxcbiAgICAgICAgICAvLyBzcGVjaWZpYyBzZXR0aW5ncyB0aGF0IG9ubHkgbWFrZSBzZW5zZSBvbiB0aGUgb3V0ZXIgbGV2ZWw6XG4gICAgICAgICAgJ2FpLnByb21wdCc6IHtcbiAgICAgICAgICAgIGlucHV0OiAoKSA9PiBKU09OLnN0cmluZ2lmeSh7IHN5c3RlbSwgcHJvbXB0LCBtZXNzYWdlcyB9KSxcbiAgICAgICAgICB9LFxuICAgICAgICAgICdhaS5zY2hlbWEnOlxuICAgICAgICAgICAgb3V0cHV0U3RyYXRlZ3kuanNvblNjaGVtYSAhPSBudWxsXG4gICAgICAgICAgICAgID8geyBpbnB1dDogKCkgPT4gSlNPTi5zdHJpbmdpZnkob3V0cHV0U3RyYXRlZ3kuanNvblNjaGVtYSkgfVxuICAgICAgICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAnYWkuc2NoZW1hLm5hbWUnOiBzY2hlbWFOYW1lLFxuICAgICAgICAgICdhaS5zY2hlbWEuZGVzY3JpcHRpb24nOiBzY2hlbWFEZXNjcmlwdGlvbixcbiAgICAgICAgICAnYWkuc2V0dGluZ3Mub3V0cHV0Jzogb3V0cHV0U3RyYXRlZ3kudHlwZSxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgICAgdHJhY2VyLFxuICAgICAgZm46IGFzeW5jIHNwYW4gPT4ge1xuICAgICAgICBsZXQgcmVzdWx0OiBzdHJpbmc7XG4gICAgICAgIGxldCBmaW5pc2hSZWFzb246IEZpbmlzaFJlYXNvbjtcbiAgICAgICAgbGV0IHVzYWdlOiBMYW5ndWFnZU1vZGVsVXNhZ2U7XG4gICAgICAgIGxldCB3YXJuaW5nczogQ2FsbFdhcm5pbmdbXSB8IHVuZGVmaW5lZDtcbiAgICAgICAgbGV0IHJlc3BvbnNlOiBMYW5ndWFnZU1vZGVsUmVzcG9uc2VNZXRhZGF0YTtcbiAgICAgICAgbGV0IHJlcXVlc3Q6IExhbmd1YWdlTW9kZWxSZXF1ZXN0TWV0YWRhdGE7XG4gICAgICAgIGxldCByZXN1bHRQcm92aWRlck1ldGFkYXRhOiBQcm92aWRlck1ldGFkYXRhIHwgdW5kZWZpbmVkO1xuICAgICAgICBsZXQgcmVhc29uaW5nOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAgICAgY29uc3Qgc3RhbmRhcmRpemVkUHJvbXB0ID0gYXdhaXQgc3RhbmRhcmRpemVQcm9tcHQoe1xuICAgICAgICAgIHN5c3RlbSxcbiAgICAgICAgICBwcm9tcHQsXG4gICAgICAgICAgbWVzc2FnZXMsXG4gICAgICAgIH0gYXMgUHJvbXB0KTtcblxuICAgICAgICBjb25zdCBwcm9tcHRNZXNzYWdlcyA9IGF3YWl0IGNvbnZlcnRUb0xhbmd1YWdlTW9kZWxQcm9tcHQoe1xuICAgICAgICAgIHByb21wdDogc3RhbmRhcmRpemVkUHJvbXB0LFxuICAgICAgICAgIHN1cHBvcnRlZFVybHM6IGF3YWl0IG1vZGVsLnN1cHBvcnRlZFVybHMsXG4gICAgICAgICAgZG93bmxvYWQsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGdlbmVyYXRlUmVzdWx0ID0gYXdhaXQgcmV0cnkoKCkgPT5cbiAgICAgICAgICByZWNvcmRTcGFuKHtcbiAgICAgICAgICAgIG5hbWU6ICdhaS5nZW5lcmF0ZU9iamVjdC5kb0dlbmVyYXRlJyxcbiAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgICB0ZWxlbWV0cnksXG4gICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgICAgICAgICAuLi5hc3NlbWJsZU9wZXJhdGlvbk5hbWUoe1xuICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uSWQ6ICdhaS5nZW5lcmF0ZU9iamVjdC5kb0dlbmVyYXRlJyxcbiAgICAgICAgICAgICAgICAgIHRlbGVtZXRyeSxcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAuLi5iYXNlVGVsZW1ldHJ5QXR0cmlidXRlcyxcbiAgICAgICAgICAgICAgICAnYWkucHJvbXB0Lm1lc3NhZ2VzJzoge1xuICAgICAgICAgICAgICAgICAgaW5wdXQ6ICgpID0+IHN0cmluZ2lmeUZvclRlbGVtZXRyeShwcm9tcHRNZXNzYWdlcyksXG4gICAgICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgICAgIC8vIHN0YW5kYXJkaXplZCBnZW4tYWkgbGxtIHNwYW4gYXR0cmlidXRlczpcbiAgICAgICAgICAgICAgICAnZ2VuX2FpLnN5c3RlbSc6IG1vZGVsLnByb3ZpZGVyLFxuICAgICAgICAgICAgICAgICdnZW5fYWkucmVxdWVzdC5tb2RlbCc6IG1vZGVsLm1vZGVsSWQsXG4gICAgICAgICAgICAgICAgJ2dlbl9haS5yZXF1ZXN0LmZyZXF1ZW5jeV9wZW5hbHR5JzpcbiAgICAgICAgICAgICAgICAgIGNhbGxTZXR0aW5ncy5mcmVxdWVuY3lQZW5hbHR5LFxuICAgICAgICAgICAgICAgICdnZW5fYWkucmVxdWVzdC5tYXhfdG9rZW5zJzogY2FsbFNldHRpbmdzLm1heE91dHB1dFRva2VucyxcbiAgICAgICAgICAgICAgICAnZ2VuX2FpLnJlcXVlc3QucHJlc2VuY2VfcGVuYWx0eSc6IGNhbGxTZXR0aW5ncy5wcmVzZW5jZVBlbmFsdHksXG4gICAgICAgICAgICAgICAgJ2dlbl9haS5yZXF1ZXN0LnRlbXBlcmF0dXJlJzogY2FsbFNldHRpbmdzLnRlbXBlcmF0dXJlLFxuICAgICAgICAgICAgICAgICdnZW5fYWkucmVxdWVzdC50b3Bfayc6IGNhbGxTZXR0aW5ncy50b3BLLFxuICAgICAgICAgICAgICAgICdnZW5fYWkucmVxdWVzdC50b3BfcCc6IGNhbGxTZXR0aW5ncy50b3BQLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB0cmFjZXIsXG4gICAgICAgICAgICBmbjogYXN5bmMgc3BhbiA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IG1vZGVsLmRvR2VuZXJhdGUoe1xuICAgICAgICAgICAgICAgIHJlc3BvbnNlRm9ybWF0OiB7XG4gICAgICAgICAgICAgICAgICB0eXBlOiAnanNvbicsXG4gICAgICAgICAgICAgICAgICBzY2hlbWE6IG91dHB1dFN0cmF0ZWd5Lmpzb25TY2hlbWEsXG4gICAgICAgICAgICAgICAgICBuYW1lOiBzY2hlbWFOYW1lLFxuICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246IHNjaGVtYURlc2NyaXB0aW9uLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgLi4ucHJlcGFyZUNhbGxTZXR0aW5ncyhzZXR0aW5ncyksXG4gICAgICAgICAgICAgICAgcHJvbXB0OiBwcm9tcHRNZXNzYWdlcyxcbiAgICAgICAgICAgICAgICBwcm92aWRlck9wdGlvbnMsXG4gICAgICAgICAgICAgICAgYWJvcnRTaWduYWwsXG4gICAgICAgICAgICAgICAgaGVhZGVyczogaGVhZGVyc1dpdGhVc2VyQWdlbnQsXG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlRGF0YSA9IHtcbiAgICAgICAgICAgICAgICBpZDogcmVzdWx0LnJlc3BvbnNlPy5pZCA/PyBnZW5lcmF0ZUlkKCksXG4gICAgICAgICAgICAgICAgdGltZXN0YW1wOiByZXN1bHQucmVzcG9uc2U/LnRpbWVzdGFtcCA/PyBjdXJyZW50RGF0ZSgpLFxuICAgICAgICAgICAgICAgIG1vZGVsSWQ6IHJlc3VsdC5yZXNwb25zZT8ubW9kZWxJZCA/PyBtb2RlbC5tb2RlbElkLFxuICAgICAgICAgICAgICAgIGhlYWRlcnM6IHJlc3VsdC5yZXNwb25zZT8uaGVhZGVycyxcbiAgICAgICAgICAgICAgICBib2R5OiByZXN1bHQucmVzcG9uc2U/LmJvZHksXG4gICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgY29uc3QgdGV4dCA9IGV4dHJhY3RUZXh0Q29udGVudChyZXN1bHQuY29udGVudCk7XG4gICAgICAgICAgICAgIGNvbnN0IHJlYXNvbmluZyA9IGV4dHJhY3RSZWFzb25pbmdDb250ZW50KHJlc3VsdC5jb250ZW50KTtcblxuICAgICAgICAgICAgICBpZiAodGV4dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vT2JqZWN0R2VuZXJhdGVkRXJyb3Ioe1xuICAgICAgICAgICAgICAgICAgbWVzc2FnZTpcbiAgICAgICAgICAgICAgICAgICAgJ05vIG9iamVjdCBnZW5lcmF0ZWQ6IHRoZSBtb2RlbCBkaWQgbm90IHJldHVybiBhIHJlc3BvbnNlLicsXG4gICAgICAgICAgICAgICAgICByZXNwb25zZTogcmVzcG9uc2VEYXRhLFxuICAgICAgICAgICAgICAgICAgdXNhZ2U6IHJlc3VsdC51c2FnZSxcbiAgICAgICAgICAgICAgICAgIGZpbmlzaFJlYXNvbjogcmVzdWx0LmZpbmlzaFJlYXNvbixcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIC8vIEFkZCByZXNwb25zZSBpbmZvcm1hdGlvbiB0byB0aGUgc3BhbjpcbiAgICAgICAgICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGVzKFxuICAgICAgICAgICAgICAgIHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICAgICAgICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAgICAgICAgICAgICAnYWkucmVzcG9uc2UuZmluaXNoUmVhc29uJzogcmVzdWx0LmZpbmlzaFJlYXNvbixcbiAgICAgICAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLm9iamVjdCc6IHsgb3V0cHV0OiAoKSA9PiB0ZXh0IH0sXG4gICAgICAgICAgICAgICAgICAgICdhaS5yZXNwb25zZS5pZCc6IHJlc3BvbnNlRGF0YS5pZCxcbiAgICAgICAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLm1vZGVsJzogcmVzcG9uc2VEYXRhLm1vZGVsSWQsXG4gICAgICAgICAgICAgICAgICAgICdhaS5yZXNwb25zZS50aW1lc3RhbXAnOlxuICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlRGF0YS50aW1lc3RhbXAudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLnByb3ZpZGVyTWV0YWRhdGEnOiBKU09OLnN0cmluZ2lmeShcbiAgICAgICAgICAgICAgICAgICAgICByZXN1bHQucHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgICAgICAgICAgICAgKSxcblxuICAgICAgICAgICAgICAgICAgICAvLyBUT0RPIHJlbmFtZSB0ZWxlbWV0cnkgYXR0cmlidXRlcyB0byBpbnB1dFRva2VucyBhbmQgb3V0cHV0VG9rZW5zXG4gICAgICAgICAgICAgICAgICAgICdhaS51c2FnZS5wcm9tcHRUb2tlbnMnOiByZXN1bHQudXNhZ2UuaW5wdXRUb2tlbnMsXG4gICAgICAgICAgICAgICAgICAgICdhaS51c2FnZS5jb21wbGV0aW9uVG9rZW5zJzogcmVzdWx0LnVzYWdlLm91dHB1dFRva2VucyxcblxuICAgICAgICAgICAgICAgICAgICAvLyBzdGFuZGFyZGl6ZWQgZ2VuLWFpIGxsbSBzcGFuIGF0dHJpYnV0ZXM6XG4gICAgICAgICAgICAgICAgICAgICdnZW5fYWkucmVzcG9uc2UuZmluaXNoX3JlYXNvbnMnOiBbcmVzdWx0LmZpbmlzaFJlYXNvbl0sXG4gICAgICAgICAgICAgICAgICAgICdnZW5fYWkucmVzcG9uc2UuaWQnOiByZXNwb25zZURhdGEuaWQsXG4gICAgICAgICAgICAgICAgICAgICdnZW5fYWkucmVzcG9uc2UubW9kZWwnOiByZXNwb25zZURhdGEubW9kZWxJZCxcbiAgICAgICAgICAgICAgICAgICAgJ2dlbl9haS51c2FnZS5pbnB1dF90b2tlbnMnOiByZXN1bHQudXNhZ2UuaW5wdXRUb2tlbnMsXG4gICAgICAgICAgICAgICAgICAgICdnZW5fYWkudXNhZ2Uub3V0cHV0X3Rva2Vucyc6IHJlc3VsdC51c2FnZS5vdXRwdXRUb2tlbnMsXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgLi4ucmVzdWx0LFxuICAgICAgICAgICAgICAgIG9iamVjdFRleHQ6IHRleHQsXG4gICAgICAgICAgICAgICAgcmVhc29uaW5nLFxuICAgICAgICAgICAgICAgIHJlc3BvbnNlRGF0YSxcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG5cbiAgICAgICAgcmVzdWx0ID0gZ2VuZXJhdGVSZXN1bHQub2JqZWN0VGV4dDtcbiAgICAgICAgZmluaXNoUmVhc29uID0gZ2VuZXJhdGVSZXN1bHQuZmluaXNoUmVhc29uO1xuICAgICAgICB1c2FnZSA9IGdlbmVyYXRlUmVzdWx0LnVzYWdlO1xuICAgICAgICB3YXJuaW5ncyA9IGdlbmVyYXRlUmVzdWx0Lndhcm5pbmdzO1xuICAgICAgICByZXN1bHRQcm92aWRlck1ldGFkYXRhID0gZ2VuZXJhdGVSZXN1bHQucHJvdmlkZXJNZXRhZGF0YTtcbiAgICAgICAgcmVxdWVzdCA9IGdlbmVyYXRlUmVzdWx0LnJlcXVlc3QgPz8ge307XG4gICAgICAgIHJlc3BvbnNlID0gZ2VuZXJhdGVSZXN1bHQucmVzcG9uc2VEYXRhO1xuICAgICAgICByZWFzb25pbmcgPSBnZW5lcmF0ZVJlc3VsdC5yZWFzb25pbmc7XG5cbiAgICAgICAgbG9nV2FybmluZ3Mod2FybmluZ3MpO1xuXG4gICAgICAgIGNvbnN0IG9iamVjdCA9IGF3YWl0IHBhcnNlQW5kVmFsaWRhdGVPYmplY3RSZXN1bHRXaXRoUmVwYWlyKFxuICAgICAgICAgIHJlc3VsdCxcbiAgICAgICAgICBvdXRwdXRTdHJhdGVneSxcbiAgICAgICAgICByZXBhaXJUZXh0LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHJlc3BvbnNlLFxuICAgICAgICAgICAgdXNhZ2UsXG4gICAgICAgICAgICBmaW5pc2hSZWFzb24sXG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcblxuICAgICAgICAvLyBBZGQgcmVzcG9uc2UgaW5mb3JtYXRpb24gdG8gdGhlIHNwYW46XG4gICAgICAgIHNwYW4uc2V0QXR0cmlidXRlcyhcbiAgICAgICAgICBzZWxlY3RUZWxlbWV0cnlBdHRyaWJ1dGVzKHtcbiAgICAgICAgICAgIHRlbGVtZXRyeSxcbiAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLmZpbmlzaFJlYXNvbic6IGZpbmlzaFJlYXNvbixcbiAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLm9iamVjdCc6IHtcbiAgICAgICAgICAgICAgICBvdXRwdXQ6ICgpID0+IEpTT04uc3RyaW5naWZ5KG9iamVjdCksXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICdhaS5yZXNwb25zZS5wcm92aWRlck1ldGFkYXRhJzogSlNPTi5zdHJpbmdpZnkoXG4gICAgICAgICAgICAgICAgcmVzdWx0UHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgICAgICAgKSxcblxuICAgICAgICAgICAgICAvLyBUT0RPIHJlbmFtZSB0ZWxlbWV0cnkgYXR0cmlidXRlcyB0byBpbnB1dFRva2VucyBhbmQgb3V0cHV0VG9rZW5zXG4gICAgICAgICAgICAgICdhaS51c2FnZS5wcm9tcHRUb2tlbnMnOiB1c2FnZS5pbnB1dFRva2VucyxcbiAgICAgICAgICAgICAgJ2FpLnVzYWdlLmNvbXBsZXRpb25Ub2tlbnMnOiB1c2FnZS5vdXRwdXRUb2tlbnMsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuXG4gICAgICAgIHJldHVybiBuZXcgRGVmYXVsdEdlbmVyYXRlT2JqZWN0UmVzdWx0KHtcbiAgICAgICAgICBvYmplY3QsXG4gICAgICAgICAgcmVhc29uaW5nLFxuICAgICAgICAgIGZpbmlzaFJlYXNvbixcbiAgICAgICAgICB1c2FnZSxcbiAgICAgICAgICB3YXJuaW5ncyxcbiAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgIHJlc3BvbnNlLFxuICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHJlc3VsdFByb3ZpZGVyTWV0YWRhdGEsXG4gICAgICAgIH0pO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICB0aHJvdyB3cmFwR2F0ZXdheUVycm9yKGVycm9yKTtcbiAgfVxufVxuXG5jbGFzcyBEZWZhdWx0R2VuZXJhdGVPYmplY3RSZXN1bHQ8VD4gaW1wbGVtZW50cyBHZW5lcmF0ZU9iamVjdFJlc3VsdDxUPiB7XG4gIHJlYWRvbmx5IG9iamVjdDogR2VuZXJhdGVPYmplY3RSZXN1bHQ8VD5bJ29iamVjdCddO1xuICByZWFkb25seSBmaW5pc2hSZWFzb246IEdlbmVyYXRlT2JqZWN0UmVzdWx0PFQ+WydmaW5pc2hSZWFzb24nXTtcbiAgcmVhZG9ubHkgdXNhZ2U6IEdlbmVyYXRlT2JqZWN0UmVzdWx0PFQ+Wyd1c2FnZSddO1xuICByZWFkb25seSB3YXJuaW5nczogR2VuZXJhdGVPYmplY3RSZXN1bHQ8VD5bJ3dhcm5pbmdzJ107XG4gIHJlYWRvbmx5IHByb3ZpZGVyTWV0YWRhdGE6IEdlbmVyYXRlT2JqZWN0UmVzdWx0PFQ+Wydwcm92aWRlck1ldGFkYXRhJ107XG4gIHJlYWRvbmx5IHJlc3BvbnNlOiBHZW5lcmF0ZU9iamVjdFJlc3VsdDxUPlsncmVzcG9uc2UnXTtcbiAgcmVhZG9ubHkgcmVxdWVzdDogR2VuZXJhdGVPYmplY3RSZXN1bHQ8VD5bJ3JlcXVlc3QnXTtcbiAgcmVhZG9ubHkgcmVhc29uaW5nOiBHZW5lcmF0ZU9iamVjdFJlc3VsdDxUPlsncmVhc29uaW5nJ107XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczoge1xuICAgIG9iamVjdDogR2VuZXJhdGVPYmplY3RSZXN1bHQ8VD5bJ29iamVjdCddO1xuICAgIGZpbmlzaFJlYXNvbjogR2VuZXJhdGVPYmplY3RSZXN1bHQ8VD5bJ2ZpbmlzaFJlYXNvbiddO1xuICAgIHVzYWdlOiBHZW5lcmF0ZU9iamVjdFJlc3VsdDxUPlsndXNhZ2UnXTtcbiAgICB3YXJuaW5nczogR2VuZXJhdGVPYmplY3RSZXN1bHQ8VD5bJ3dhcm5pbmdzJ107XG4gICAgcHJvdmlkZXJNZXRhZGF0YTogR2VuZXJhdGVPYmplY3RSZXN1bHQ8VD5bJ3Byb3ZpZGVyTWV0YWRhdGEnXTtcbiAgICByZXNwb25zZTogR2VuZXJhdGVPYmplY3RSZXN1bHQ8VD5bJ3Jlc3BvbnNlJ107XG4gICAgcmVxdWVzdDogR2VuZXJhdGVPYmplY3RSZXN1bHQ8VD5bJ3JlcXVlc3QnXTtcbiAgICByZWFzb25pbmc6IEdlbmVyYXRlT2JqZWN0UmVzdWx0PFQ+WydyZWFzb25pbmcnXTtcbiAgfSkge1xuICAgIHRoaXMub2JqZWN0ID0gb3B0aW9ucy5vYmplY3Q7XG4gICAgdGhpcy5maW5pc2hSZWFzb24gPSBvcHRpb25zLmZpbmlzaFJlYXNvbjtcbiAgICB0aGlzLnVzYWdlID0gb3B0aW9ucy51c2FnZTtcbiAgICB0aGlzLndhcm5pbmdzID0gb3B0aW9ucy53YXJuaW5ncztcbiAgICB0aGlzLnByb3ZpZGVyTWV0YWRhdGEgPSBvcHRpb25zLnByb3ZpZGVyTWV0YWRhdGE7XG4gICAgdGhpcy5yZXNwb25zZSA9IG9wdGlvbnMucmVzcG9uc2U7XG4gICAgdGhpcy5yZXF1ZXN0ID0gb3B0aW9ucy5yZXF1ZXN0O1xuICAgIHRoaXMucmVhc29uaW5nID0gb3B0aW9ucy5yZWFzb25pbmc7XG4gIH1cblxuICB0b0pzb25SZXNwb25zZShpbml0PzogUmVzcG9uc2VJbml0KTogUmVzcG9uc2Uge1xuICAgIHJldHVybiBuZXcgUmVzcG9uc2UoSlNPTi5zdHJpbmdpZnkodGhpcy5vYmplY3QpLCB7XG4gICAgICBzdGF0dXM6IGluaXQ/LnN0YXR1cyA/PyAyMDAsXG4gICAgICBoZWFkZXJzOiBwcmVwYXJlSGVhZGVycyhpbml0Py5oZWFkZXJzLCB7XG4gICAgICAgICdjb250ZW50LXR5cGUnOiAnYXBwbGljYXRpb24vanNvbjsgY2hhcnNldD11dGYtOCcsXG4gICAgICB9KSxcbiAgICB9KTtcbiAgfVxufVxuIiwgImltcG9ydCB7XG4gIExhbmd1YWdlTW9kZWxWMkNvbnRlbnQsXG4gIExhbmd1YWdlTW9kZWxWMlJlYXNvbmluZyxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5cbmV4cG9ydCBmdW5jdGlvbiBleHRyYWN0UmVhc29uaW5nQ29udGVudChcbiAgY29udGVudDogTGFuZ3VhZ2VNb2RlbFYyQ29udGVudFtdLFxuKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgcGFydHMgPSBjb250ZW50LmZpbHRlcihcbiAgICAoY29udGVudCk6IGNvbnRlbnQgaXMgTGFuZ3VhZ2VNb2RlbFYyUmVhc29uaW5nID0+XG4gICAgICBjb250ZW50LnR5cGUgPT09ICdyZWFzb25pbmcnLFxuICApO1xuXG4gIHJldHVybiBwYXJ0cy5sZW5ndGggPT09IDBcbiAgICA/IHVuZGVmaW5lZFxuICAgIDogcGFydHMubWFwKGNvbnRlbnQgPT4gY29udGVudC50ZXh0KS5qb2luKCdcXG4nKTtcbn1cbiIsICJpbXBvcnQge1xuICBpc0pTT05BcnJheSxcbiAgaXNKU09OT2JqZWN0LFxuICBKU09OT2JqZWN0LFxuICBKU09OU2NoZW1hNyxcbiAgSlNPTlZhbHVlLFxuICBUeXBlVmFsaWRhdGlvbkVycm9yLFxuICBVbnN1cHBvcnRlZEZ1bmN0aW9uYWxpdHlFcnJvcixcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQge1xuICBhc1NjaGVtYSxcbiAgRmxleGlibGVTY2hlbWEsXG4gIHNhZmVWYWxpZGF0ZVR5cGVzLFxuICBTY2hlbWEsXG4gIFZhbGlkYXRpb25SZXN1bHQsXG59IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXItdXRpbHMnO1xuaW1wb3J0IHsgTm9PYmplY3RHZW5lcmF0ZWRFcnJvciB9IGZyb20gJy4uL2Vycm9yL25vLW9iamVjdC1nZW5lcmF0ZWQtZXJyb3InO1xuaW1wb3J0IHtcbiAgRmluaXNoUmVhc29uLFxuICBMYW5ndWFnZU1vZGVsUmVzcG9uc2VNZXRhZGF0YSxcbiAgTGFuZ3VhZ2VNb2RlbFVzYWdlLFxufSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQge1xuICBBc3luY0l0ZXJhYmxlU3RyZWFtLFxuICBjcmVhdGVBc3luY0l0ZXJhYmxlU3RyZWFtLFxufSBmcm9tICcuLi91dGlsL2FzeW5jLWl0ZXJhYmxlLXN0cmVhbSc7XG5pbXBvcnQgeyBEZWVwUGFydGlhbCB9IGZyb20gJy4uL3V0aWwvZGVlcC1wYXJ0aWFsJztcbmltcG9ydCB7IE9iamVjdFN0cmVhbVBhcnQgfSBmcm9tICcuL3N0cmVhbS1vYmplY3QtcmVzdWx0JztcblxuZXhwb3J0IGludGVyZmFjZSBPdXRwdXRTdHJhdGVneTxQQVJUSUFMLCBSRVNVTFQsIEVMRU1FTlRfU1RSRUFNPiB7XG4gIHJlYWRvbmx5IHR5cGU6ICdvYmplY3QnIHwgJ2FycmF5JyB8ICdlbnVtJyB8ICduby1zY2hlbWEnO1xuICByZWFkb25seSBqc29uU2NoZW1hOiBKU09OU2NoZW1hNyB8IHVuZGVmaW5lZDtcblxuICB2YWxpZGF0ZVBhcnRpYWxSZXN1bHQoe1xuICAgIHZhbHVlLFxuICAgIHRleHREZWx0YSxcbiAgICBpc0ZpbmFsRGVsdGEsXG4gIH06IHtcbiAgICB2YWx1ZTogSlNPTlZhbHVlO1xuICAgIHRleHREZWx0YTogc3RyaW5nO1xuICAgIGlzRmlyc3REZWx0YTogYm9vbGVhbjtcbiAgICBpc0ZpbmFsRGVsdGE6IGJvb2xlYW47XG4gICAgbGF0ZXN0T2JqZWN0OiBQQVJUSUFMIHwgdW5kZWZpbmVkO1xuICB9KTogUHJvbWlzZTxcbiAgICBWYWxpZGF0aW9uUmVzdWx0PHtcbiAgICAgIHBhcnRpYWw6IFBBUlRJQUw7XG4gICAgICB0ZXh0RGVsdGE6IHN0cmluZztcbiAgICB9PlxuICA+O1xuICB2YWxpZGF0ZUZpbmFsUmVzdWx0KFxuICAgIHZhbHVlOiBKU09OVmFsdWUgfCB1bmRlZmluZWQsXG4gICAgY29udGV4dDoge1xuICAgICAgdGV4dDogc3RyaW5nO1xuICAgICAgcmVzcG9uc2U6IExhbmd1YWdlTW9kZWxSZXNwb25zZU1ldGFkYXRhO1xuICAgICAgdXNhZ2U6IExhbmd1YWdlTW9kZWxVc2FnZTtcbiAgICB9LFxuICApOiBQcm9taXNlPFZhbGlkYXRpb25SZXN1bHQ8UkVTVUxUPj47XG5cbiAgY3JlYXRlRWxlbWVudFN0cmVhbShcbiAgICBvcmlnaW5hbFN0cmVhbTogUmVhZGFibGVTdHJlYW08T2JqZWN0U3RyZWFtUGFydDxQQVJUSUFMPj4sXG4gICk6IEVMRU1FTlRfU1RSRUFNO1xufVxuXG5jb25zdCBub1NjaGVtYU91dHB1dFN0cmF0ZWd5OiBPdXRwdXRTdHJhdGVneTxKU09OVmFsdWUsIEpTT05WYWx1ZSwgbmV2ZXI+ID0ge1xuICB0eXBlOiAnbm8tc2NoZW1hJyxcbiAganNvblNjaGVtYTogdW5kZWZpbmVkLFxuXG4gIGFzeW5jIHZhbGlkYXRlUGFydGlhbFJlc3VsdCh7IHZhbHVlLCB0ZXh0RGVsdGEgfSkge1xuICAgIHJldHVybiB7IHN1Y2Nlc3M6IHRydWUsIHZhbHVlOiB7IHBhcnRpYWw6IHZhbHVlLCB0ZXh0RGVsdGEgfSB9O1xuICB9LFxuXG4gIGFzeW5jIHZhbGlkYXRlRmluYWxSZXN1bHQoXG4gICAgdmFsdWU6IEpTT05WYWx1ZSB8IHVuZGVmaW5lZCxcbiAgICBjb250ZXh0OiB7XG4gICAgICB0ZXh0OiBzdHJpbmc7XG4gICAgICByZXNwb25zZTogTGFuZ3VhZ2VNb2RlbFJlc3BvbnNlTWV0YWRhdGE7XG4gICAgICB1c2FnZTogTGFuZ3VhZ2VNb2RlbFVzYWdlO1xuICAgICAgZmluaXNoUmVhc29uOiBGaW5pc2hSZWFzb247XG4gICAgfSxcbiAgKTogUHJvbWlzZTxWYWxpZGF0aW9uUmVzdWx0PEpTT05WYWx1ZT4+IHtcbiAgICByZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZFxuICAgICAgPyB7XG4gICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgZXJyb3I6IG5ldyBOb09iamVjdEdlbmVyYXRlZEVycm9yKHtcbiAgICAgICAgICAgIG1lc3NhZ2U6ICdObyBvYmplY3QgZ2VuZXJhdGVkOiByZXNwb25zZSBkaWQgbm90IG1hdGNoIHNjaGVtYS4nLFxuICAgICAgICAgICAgdGV4dDogY29udGV4dC50ZXh0LFxuICAgICAgICAgICAgcmVzcG9uc2U6IGNvbnRleHQucmVzcG9uc2UsXG4gICAgICAgICAgICB1c2FnZTogY29udGV4dC51c2FnZSxcbiAgICAgICAgICAgIGZpbmlzaFJlYXNvbjogY29udGV4dC5maW5pc2hSZWFzb24sXG4gICAgICAgICAgfSksXG4gICAgICAgIH1cbiAgICAgIDogeyBzdWNjZXNzOiB0cnVlLCB2YWx1ZSB9O1xuICB9LFxuXG4gIGNyZWF0ZUVsZW1lbnRTdHJlYW0oKSB7XG4gICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRnVuY3Rpb25hbGl0eUVycm9yKHtcbiAgICAgIGZ1bmN0aW9uYWxpdHk6ICdlbGVtZW50IHN0cmVhbXMgaW4gbm8tc2NoZW1hIG1vZGUnLFxuICAgIH0pO1xuICB9LFxufTtcblxuY29uc3Qgb2JqZWN0T3V0cHV0U3RyYXRlZ3kgPSA8T0JKRUNUPihcbiAgc2NoZW1hOiBTY2hlbWE8T0JKRUNUPixcbik6IE91dHB1dFN0cmF0ZWd5PERlZXBQYXJ0aWFsPE9CSkVDVD4sIE9CSkVDVCwgbmV2ZXI+ID0+ICh7XG4gIHR5cGU6ICdvYmplY3QnLFxuICBqc29uU2NoZW1hOiBzY2hlbWEuanNvblNjaGVtYSxcblxuICBhc3luYyB2YWxpZGF0ZVBhcnRpYWxSZXN1bHQoeyB2YWx1ZSwgdGV4dERlbHRhIH0pIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgIHZhbHVlOiB7XG4gICAgICAgIC8vIE5vdGU6IGN1cnJlbnRseSBubyB2YWxpZGF0aW9uIG9mIHBhcnRpYWwgcmVzdWx0czpcbiAgICAgICAgcGFydGlhbDogdmFsdWUgYXMgRGVlcFBhcnRpYWw8T0JKRUNUPixcbiAgICAgICAgdGV4dERlbHRhLFxuICAgICAgfSxcbiAgICB9O1xuICB9LFxuXG4gIGFzeW5jIHZhbGlkYXRlRmluYWxSZXN1bHQoXG4gICAgdmFsdWU6IEpTT05WYWx1ZSB8IHVuZGVmaW5lZCxcbiAgKTogUHJvbWlzZTxWYWxpZGF0aW9uUmVzdWx0PE9CSkVDVD4+IHtcbiAgICByZXR1cm4gc2FmZVZhbGlkYXRlVHlwZXMoeyB2YWx1ZSwgc2NoZW1hIH0pO1xuICB9LFxuXG4gIGNyZWF0ZUVsZW1lbnRTdHJlYW0oKSB7XG4gICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRnVuY3Rpb25hbGl0eUVycm9yKHtcbiAgICAgIGZ1bmN0aW9uYWxpdHk6ICdlbGVtZW50IHN0cmVhbXMgaW4gb2JqZWN0IG1vZGUnLFxuICAgIH0pO1xuICB9LFxufSk7XG5cbmNvbnN0IGFycmF5T3V0cHV0U3RyYXRlZ3kgPSA8RUxFTUVOVD4oXG4gIHNjaGVtYTogU2NoZW1hPEVMRU1FTlQ+LFxuKTogT3V0cHV0U3RyYXRlZ3k8RUxFTUVOVFtdLCBFTEVNRU5UW10sIEFzeW5jSXRlcmFibGVTdHJlYW08RUxFTUVOVD4+ID0+IHtcbiAgLy8gcmVtb3ZlICRzY2hlbWEgZnJvbSBzY2hlbWEuanNvblNjaGVtYTpcbiAgY29uc3QgeyAkc2NoZW1hLCAuLi5pdGVtU2NoZW1hIH0gPSBzY2hlbWEuanNvblNjaGVtYTtcblxuICByZXR1cm4ge1xuICAgIHR5cGU6ICdlbnVtJyxcblxuICAgIC8vIHdyYXAgaW4gb2JqZWN0IHRoYXQgY29udGFpbnMgYXJyYXkgb2YgZWxlbWVudHMsIHNpbmNlIG1vc3QgTExNcyB3aWxsIG5vdFxuICAgIC8vIGJlIGFibGUgdG8gZ2VuZXJhdGUgYW4gYXJyYXkgZGlyZWN0bHk6XG4gICAgLy8gcG9zc2libGUgZnV0dXJlIG9wdGltaXphdGlvbjogdXNlIGFycmF5cyBkaXJlY3RseSB3aGVuIG1vZGVsIHN1cHBvcnRzIGdyYW1tYXItZ3VpZGVkIGdlbmVyYXRpb25cbiAgICBqc29uU2NoZW1hOiB7XG4gICAgICAkc2NoZW1hOiAnaHR0cDovL2pzb24tc2NoZW1hLm9yZy9kcmFmdC0wNy9zY2hlbWEjJyxcbiAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBlbGVtZW50czogeyB0eXBlOiAnYXJyYXknLCBpdGVtczogaXRlbVNjaGVtYSB9LFxuICAgICAgfSxcbiAgICAgIHJlcXVpcmVkOiBbJ2VsZW1lbnRzJ10sXG4gICAgICBhZGRpdGlvbmFsUHJvcGVydGllczogZmFsc2UsXG4gICAgfSxcblxuICAgIGFzeW5jIHZhbGlkYXRlUGFydGlhbFJlc3VsdCh7XG4gICAgICB2YWx1ZSxcbiAgICAgIGxhdGVzdE9iamVjdCxcbiAgICAgIGlzRmlyc3REZWx0YSxcbiAgICAgIGlzRmluYWxEZWx0YSxcbiAgICB9KSB7XG4gICAgICAvLyBjaGVjayB0aGF0IHRoZSB2YWx1ZSBpcyBhbiBvYmplY3QgdGhhdCBjb250YWlucyBhbiBhcnJheSBvZiBlbGVtZW50czpcbiAgICAgIGlmICghaXNKU09OT2JqZWN0KHZhbHVlKSB8fCAhaXNKU09OQXJyYXkodmFsdWUuZWxlbWVudHMpKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgZXJyb3I6IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKHtcbiAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgY2F1c2U6ICd2YWx1ZSBtdXN0IGJlIGFuIG9iamVjdCB0aGF0IGNvbnRhaW5zIGFuIGFycmF5IG9mIGVsZW1lbnRzJyxcbiAgICAgICAgICB9KSxcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgaW5wdXRBcnJheSA9IHZhbHVlLmVsZW1lbnRzIGFzIEFycmF5PEpTT05PYmplY3Q+O1xuICAgICAgY29uc3QgcmVzdWx0QXJyYXk6IEFycmF5PEVMRU1FTlQ+ID0gW107XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXRBcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gaW5wdXRBcnJheVtpXTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc2FmZVZhbGlkYXRlVHlwZXMoeyB2YWx1ZTogZWxlbWVudCwgc2NoZW1hIH0pO1xuXG4gICAgICAgIC8vIHNwZWNpYWwgdHJlYXRtZW50IGZvciBsYXN0IHByb2Nlc3NlZCBlbGVtZW50OlxuICAgICAgICAvLyBpZ25vcmUgcGFyc2Ugb3IgdmFsaWRhdGlvbiBmYWlsdXJlcywgc2luY2UgdGhleSBpbmRpY2F0ZSB0aGF0IHRoZVxuICAgICAgICAvLyBsYXN0IGVsZW1lbnQgaXMgaW5jb21wbGV0ZSBhbmQgc2hvdWxkIG5vdCBiZSBpbmNsdWRlZCBpbiB0aGUgcmVzdWx0LFxuICAgICAgICAvLyB1bmxlc3MgaXQgaXMgdGhlIGZpbmFsIGRlbHRhXG4gICAgICAgIGlmIChpID09PSBpbnB1dEFycmF5Lmxlbmd0aCAtIDEgJiYgIWlzRmluYWxEZWx0YSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFyZXN1bHQuc3VjY2Vzcykge1xuICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXN1bHRBcnJheS5wdXNoKHJlc3VsdC52YWx1ZSk7XG4gICAgICB9XG5cbiAgICAgIC8vIGNhbGN1bGF0ZSBkZWx0YTpcbiAgICAgIGNvbnN0IHB1Ymxpc2hlZEVsZW1lbnRDb3VudCA9IGxhdGVzdE9iamVjdD8ubGVuZ3RoID8/IDA7XG5cbiAgICAgIGxldCB0ZXh0RGVsdGEgPSAnJztcblxuICAgICAgaWYgKGlzRmlyc3REZWx0YSkge1xuICAgICAgICB0ZXh0RGVsdGEgKz0gJ1snO1xuICAgICAgfVxuXG4gICAgICBpZiAocHVibGlzaGVkRWxlbWVudENvdW50ID4gMCkge1xuICAgICAgICB0ZXh0RGVsdGEgKz0gJywnO1xuICAgICAgfVxuXG4gICAgICB0ZXh0RGVsdGEgKz0gcmVzdWx0QXJyYXlcbiAgICAgICAgLnNsaWNlKHB1Ymxpc2hlZEVsZW1lbnRDb3VudCkgLy8gb25seSBuZXcgZWxlbWVudHNcbiAgICAgICAgLm1hcChlbGVtZW50ID0+IEpTT04uc3RyaW5naWZ5KGVsZW1lbnQpKVxuICAgICAgICAuam9pbignLCcpO1xuXG4gICAgICBpZiAoaXNGaW5hbERlbHRhKSB7XG4gICAgICAgIHRleHREZWx0YSArPSAnXSc7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgcGFydGlhbDogcmVzdWx0QXJyYXksXG4gICAgICAgICAgdGV4dERlbHRhLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9LFxuXG4gICAgYXN5bmMgdmFsaWRhdGVGaW5hbFJlc3VsdChcbiAgICAgIHZhbHVlOiBKU09OVmFsdWUgfCB1bmRlZmluZWQsXG4gICAgKTogUHJvbWlzZTxWYWxpZGF0aW9uUmVzdWx0PEFycmF5PEVMRU1FTlQ+Pj4ge1xuICAgICAgLy8gY2hlY2sgdGhhdCB0aGUgdmFsdWUgaXMgYW4gb2JqZWN0IHRoYXQgY29udGFpbnMgYW4gYXJyYXkgb2YgZWxlbWVudHM6XG4gICAgICBpZiAoIWlzSlNPTk9iamVjdCh2YWx1ZSkgfHwgIWlzSlNPTkFycmF5KHZhbHVlLmVsZW1lbnRzKSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgIGVycm9yOiBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcih7XG4gICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgIGNhdXNlOiAndmFsdWUgbXVzdCBiZSBhbiBvYmplY3QgdGhhdCBjb250YWlucyBhbiBhcnJheSBvZiBlbGVtZW50cycsXG4gICAgICAgICAgfSksXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGlucHV0QXJyYXkgPSB2YWx1ZS5lbGVtZW50cyBhcyBBcnJheTxKU09OT2JqZWN0PjtcblxuICAgICAgLy8gY2hlY2sgdGhhdCBlYWNoIGVsZW1lbnQgaW4gdGhlIGFycmF5IGlzIG9mIHRoZSBjb3JyZWN0IHR5cGU6XG4gICAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgaW5wdXRBcnJheSkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzYWZlVmFsaWRhdGVUeXBlcyh7IHZhbHVlOiBlbGVtZW50LCBzY2hlbWEgfSk7XG4gICAgICAgIGlmICghcmVzdWx0LnN1Y2Nlc3MpIHtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7IHN1Y2Nlc3M6IHRydWUsIHZhbHVlOiBpbnB1dEFycmF5IGFzIEFycmF5PEVMRU1FTlQ+IH07XG4gICAgfSxcblxuICAgIGNyZWF0ZUVsZW1lbnRTdHJlYW0oXG4gICAgICBvcmlnaW5hbFN0cmVhbTogUmVhZGFibGVTdHJlYW08T2JqZWN0U3RyZWFtUGFydDxFTEVNRU5UW10+PixcbiAgICApIHtcbiAgICAgIGxldCBwdWJsaXNoZWRFbGVtZW50cyA9IDA7XG5cbiAgICAgIHJldHVybiBjcmVhdGVBc3luY0l0ZXJhYmxlU3RyZWFtKFxuICAgICAgICBvcmlnaW5hbFN0cmVhbS5waXBlVGhyb3VnaChcbiAgICAgICAgICBuZXcgVHJhbnNmb3JtU3RyZWFtPE9iamVjdFN0cmVhbVBhcnQ8RUxFTUVOVFtdPiwgRUxFTUVOVD4oe1xuICAgICAgICAgICAgdHJhbnNmb3JtKGNodW5rLCBjb250cm9sbGVyKSB7XG4gICAgICAgICAgICAgIHN3aXRjaCAoY2h1bmsudHlwZSkge1xuICAgICAgICAgICAgICAgIGNhc2UgJ29iamVjdCc6IHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGFycmF5ID0gY2h1bmsub2JqZWN0O1xuXG4gICAgICAgICAgICAgICAgICAvLyBwdWJsaXNoIG5ldyBlbGVtZW50cyBvbmUgYnkgb25lOlxuICAgICAgICAgICAgICAgICAgZm9yIChcbiAgICAgICAgICAgICAgICAgICAgO1xuICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZWRFbGVtZW50cyA8IGFycmF5Lmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgcHVibGlzaGVkRWxlbWVudHMrK1xuICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShhcnJheVtwdWJsaXNoZWRFbGVtZW50c10pO1xuICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjYXNlICd0ZXh0LWRlbHRhJzpcbiAgICAgICAgICAgICAgICBjYXNlICdmaW5pc2gnOlxuICAgICAgICAgICAgICAgIGNhc2UgJ2Vycm9yJzogLy8gc3VwcHJlc3MgZXJyb3IgKHVzZSBvbkVycm9yIGluc3RlYWQpXG4gICAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IF9leGhhdXN0aXZlQ2hlY2s6IG5ldmVyID0gY2h1bms7XG4gICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIGBVbnN1cHBvcnRlZCBjaHVuayB0eXBlOiAke19leGhhdXN0aXZlQ2hlY2t9YCxcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pLFxuICAgICAgICApLFxuICAgICAgKTtcbiAgICB9LFxuICB9O1xufTtcblxuY29uc3QgZW51bU91dHB1dFN0cmF0ZWd5ID0gPEVOVU0gZXh0ZW5kcyBzdHJpbmc+KFxuICBlbnVtVmFsdWVzOiBBcnJheTxFTlVNPixcbik6IE91dHB1dFN0cmF0ZWd5PHN0cmluZywgRU5VTSwgbmV2ZXI+ID0+IHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAnZW51bScsXG5cbiAgICAvLyB3cmFwIGluIG9iamVjdCB0aGF0IGNvbnRhaW5zIHJlc3VsdCwgc2luY2UgbW9zdCBMTE1zIHdpbGwgbm90XG4gICAgLy8gYmUgYWJsZSB0byBnZW5lcmF0ZSBhbiBlbnVtIHZhbHVlIGRpcmVjdGx5OlxuICAgIC8vIHBvc3NpYmxlIGZ1dHVyZSBvcHRpbWl6YXRpb246IHVzZSBlbnVtcyBkaXJlY3RseSB3aGVuIG1vZGVsIHN1cHBvcnRzIHRvcC1sZXZlbCBlbnVtc1xuICAgIGpzb25TY2hlbWE6IHtcbiAgICAgICRzY2hlbWE6ICdodHRwOi8vanNvbi1zY2hlbWEub3JnL2RyYWZ0LTA3L3NjaGVtYSMnLFxuICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIHJlc3VsdDogeyB0eXBlOiAnc3RyaW5nJywgZW51bTogZW51bVZhbHVlcyB9LFxuICAgICAgfSxcbiAgICAgIHJlcXVpcmVkOiBbJ3Jlc3VsdCddLFxuICAgICAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlLFxuICAgIH0sXG5cbiAgICBhc3luYyB2YWxpZGF0ZUZpbmFsUmVzdWx0KFxuICAgICAgdmFsdWU6IEpTT05WYWx1ZSB8IHVuZGVmaW5lZCxcbiAgICApOiBQcm9taXNlPFZhbGlkYXRpb25SZXN1bHQ8RU5VTT4+IHtcbiAgICAgIC8vIGNoZWNrIHRoYXQgdGhlIHZhbHVlIGlzIGFuIG9iamVjdCB0aGF0IGNvbnRhaW5zIGFuIGFycmF5IG9mIGVsZW1lbnRzOlxuICAgICAgaWYgKCFpc0pTT05PYmplY3QodmFsdWUpIHx8IHR5cGVvZiB2YWx1ZS5yZXN1bHQgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgZXJyb3I6IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKHtcbiAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgY2F1c2U6XG4gICAgICAgICAgICAgICd2YWx1ZSBtdXN0IGJlIGFuIG9iamVjdCB0aGF0IGNvbnRhaW5zIGEgc3RyaW5nIGluIHRoZSBcInJlc3VsdFwiIHByb3BlcnR5LicsXG4gICAgICAgICAgfSksXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IHZhbHVlLnJlc3VsdCBhcyBzdHJpbmc7XG5cbiAgICAgIHJldHVybiBlbnVtVmFsdWVzLmluY2x1ZGVzKHJlc3VsdCBhcyBFTlVNKVxuICAgICAgICA/IHsgc3VjY2VzczogdHJ1ZSwgdmFsdWU6IHJlc3VsdCBhcyBFTlVNIH1cbiAgICAgICAgOiB7XG4gICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgIGVycm9yOiBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcih7XG4gICAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgICBjYXVzZTogJ3ZhbHVlIG11c3QgYmUgYSBzdHJpbmcgaW4gdGhlIGVudW0nLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgYXN5bmMgdmFsaWRhdGVQYXJ0aWFsUmVzdWx0KHsgdmFsdWUsIHRleHREZWx0YSB9KSB7XG4gICAgICBpZiAoIWlzSlNPTk9iamVjdCh2YWx1ZSkgfHwgdHlwZW9mIHZhbHVlLnJlc3VsdCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICBlcnJvcjogbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3Ioe1xuICAgICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgICBjYXVzZTpcbiAgICAgICAgICAgICAgJ3ZhbHVlIG11c3QgYmUgYW4gb2JqZWN0IHRoYXQgY29udGFpbnMgYSBzdHJpbmcgaW4gdGhlIFwicmVzdWx0XCIgcHJvcGVydHkuJyxcbiAgICAgICAgICB9KSxcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVzdWx0ID0gdmFsdWUucmVzdWx0IGFzIHN0cmluZztcbiAgICAgIGNvbnN0IHBvc3NpYmxlRW51bVZhbHVlcyA9IGVudW1WYWx1ZXMuZmlsdGVyKGVudW1WYWx1ZSA9PlxuICAgICAgICBlbnVtVmFsdWUuc3RhcnRzV2l0aChyZXN1bHQpLFxuICAgICAgKTtcblxuICAgICAgaWYgKHZhbHVlLnJlc3VsdC5sZW5ndGggPT09IDAgfHwgcG9zc2libGVFbnVtVmFsdWVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgIGVycm9yOiBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcih7XG4gICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgIGNhdXNlOiAndmFsdWUgbXVzdCBiZSBhIHN0cmluZyBpbiB0aGUgZW51bScsXG4gICAgICAgICAgfSksXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgcGFydGlhbDpcbiAgICAgICAgICAgIHBvc3NpYmxlRW51bVZhbHVlcy5sZW5ndGggPiAxID8gcmVzdWx0IDogcG9zc2libGVFbnVtVmFsdWVzWzBdLFxuICAgICAgICAgIHRleHREZWx0YSxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfSxcblxuICAgIGNyZWF0ZUVsZW1lbnRTdHJlYW0oKSB7XG4gICAgICAvLyBubyBzdHJlYW1pbmcgaW4gZW51bSBtb2RlXG4gICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRGdW5jdGlvbmFsaXR5RXJyb3Ioe1xuICAgICAgICBmdW5jdGlvbmFsaXR5OiAnZWxlbWVudCBzdHJlYW1zIGluIGVudW0gbW9kZScsXG4gICAgICB9KTtcbiAgICB9LFxuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldE91dHB1dFN0cmF0ZWd5PFNDSEVNQT4oe1xuICBvdXRwdXQsXG4gIHNjaGVtYSxcbiAgZW51bVZhbHVlcyxcbn06IHtcbiAgb3V0cHV0OiAnb2JqZWN0JyB8ICdhcnJheScgfCAnZW51bScgfCAnbm8tc2NoZW1hJztcbiAgc2NoZW1hPzogRmxleGlibGVTY2hlbWE8U0NIRU1BPjtcbiAgZW51bVZhbHVlcz86IEFycmF5PFNDSEVNQT47XG59KTogT3V0cHV0U3RyYXRlZ3k8YW55LCBhbnksIGFueT4ge1xuICBzd2l0Y2ggKG91dHB1dCkge1xuICAgIGNhc2UgJ29iamVjdCc6XG4gICAgICByZXR1cm4gb2JqZWN0T3V0cHV0U3RyYXRlZ3koYXNTY2hlbWEoc2NoZW1hISkpO1xuICAgIGNhc2UgJ2FycmF5JzpcbiAgICAgIHJldHVybiBhcnJheU91dHB1dFN0cmF0ZWd5KGFzU2NoZW1hKHNjaGVtYSEpKTtcbiAgICBjYXNlICdlbnVtJzpcbiAgICAgIHJldHVybiBlbnVtT3V0cHV0U3RyYXRlZ3koZW51bVZhbHVlcyEgYXMgQXJyYXk8c3RyaW5nPik7XG4gICAgY2FzZSAnbm8tc2NoZW1hJzpcbiAgICAgIHJldHVybiBub1NjaGVtYU91dHB1dFN0cmF0ZWd5O1xuICAgIGRlZmF1bHQ6IHtcbiAgICAgIGNvbnN0IF9leGhhdXN0aXZlQ2hlY2s6IG5ldmVyID0gb3V0cHV0O1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBvdXRwdXQ6ICR7X2V4aGF1c3RpdmVDaGVja31gKTtcbiAgICB9XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBKU09OUGFyc2VFcnJvciwgVHlwZVZhbGlkYXRpb25FcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgc2FmZVBhcnNlSlNPTiB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXItdXRpbHMnO1xuaW1wb3J0IHsgTm9PYmplY3RHZW5lcmF0ZWRFcnJvciB9IGZyb20gJy4uL2Vycm9yL25vLW9iamVjdC1nZW5lcmF0ZWQtZXJyb3InO1xuaW1wb3J0IHR5cGUge1xuICBGaW5pc2hSZWFzb24sXG4gIExhbmd1YWdlTW9kZWxSZXNwb25zZU1ldGFkYXRhLFxuICBMYW5ndWFnZU1vZGVsVXNhZ2UsXG59IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB0eXBlIHsgT3V0cHV0U3RyYXRlZ3kgfSBmcm9tICcuL291dHB1dC1zdHJhdGVneSc7XG5pbXBvcnQgeyBSZXBhaXJUZXh0RnVuY3Rpb24gfSBmcm9tICcuL3JlcGFpci10ZXh0JztcblxuLyoqXG4gKiBQYXJzZXMgYW5kIHZhbGlkYXRlcyBhIHJlc3VsdCBzdHJpbmcgYnkgcGFyc2luZyBpdCBhcyBKU09OIGFuZCB2YWxpZGF0aW5nIGFnYWluc3QgdGhlIG91dHB1dCBzdHJhdGVneS5cbiAqXG4gKiBAcGFyYW0gcmVzdWx0IC0gVGhlIHJlc3VsdCBzdHJpbmcgdG8gcGFyc2UgYW5kIHZhbGlkYXRlXG4gKiBAcGFyYW0gb3V0cHV0U3RyYXRlZ3kgLSBUaGUgb3V0cHV0IHN0cmF0ZWd5IGNvbnRhaW5pbmcgdmFsaWRhdGlvbiBsb2dpY1xuICogQHBhcmFtIGNvbnRleHQgLSBBZGRpdGlvbmFsIGNvbnRleHQgZm9yIGVycm9yIHJlcG9ydGluZ1xuICogQHJldHVybnMgVGhlIHZhbGlkYXRlZCByZXN1bHRcbiAqIEB0aHJvd3MgTm9PYmplY3RHZW5lcmF0ZWRFcnJvciBpZiBwYXJzaW5nIG9yIHZhbGlkYXRpb24gZmFpbHNcbiAqL1xuYXN5bmMgZnVuY3Rpb24gcGFyc2VBbmRWYWxpZGF0ZU9iamVjdFJlc3VsdDxSRVNVTFQ+KFxuICByZXN1bHQ6IHN0cmluZyxcbiAgb3V0cHV0U3RyYXRlZ3k6IE91dHB1dFN0cmF0ZWd5PGFueSwgUkVTVUxULCBhbnk+LFxuICBjb250ZXh0OiB7XG4gICAgcmVzcG9uc2U6IExhbmd1YWdlTW9kZWxSZXNwb25zZU1ldGFkYXRhO1xuICAgIHVzYWdlOiBMYW5ndWFnZU1vZGVsVXNhZ2U7XG4gICAgZmluaXNoUmVhc29uOiBGaW5pc2hSZWFzb247XG4gIH0sXG4pOiBQcm9taXNlPFJFU1VMVD4ge1xuICBjb25zdCBwYXJzZVJlc3VsdCA9IGF3YWl0IHNhZmVQYXJzZUpTT04oeyB0ZXh0OiByZXN1bHQgfSk7XG5cbiAgaWYgKCFwYXJzZVJlc3VsdC5zdWNjZXNzKSB7XG4gICAgdGhyb3cgbmV3IE5vT2JqZWN0R2VuZXJhdGVkRXJyb3Ioe1xuICAgICAgbWVzc2FnZTogJ05vIG9iamVjdCBnZW5lcmF0ZWQ6IGNvdWxkIG5vdCBwYXJzZSB0aGUgcmVzcG9uc2UuJyxcbiAgICAgIGNhdXNlOiBwYXJzZVJlc3VsdC5lcnJvcixcbiAgICAgIHRleHQ6IHJlc3VsdCxcbiAgICAgIHJlc3BvbnNlOiBjb250ZXh0LnJlc3BvbnNlLFxuICAgICAgdXNhZ2U6IGNvbnRleHQudXNhZ2UsXG4gICAgICBmaW5pc2hSZWFzb246IGNvbnRleHQuZmluaXNoUmVhc29uLFxuICAgIH0pO1xuICB9XG5cbiAgY29uc3QgdmFsaWRhdGlvblJlc3VsdCA9IGF3YWl0IG91dHB1dFN0cmF0ZWd5LnZhbGlkYXRlRmluYWxSZXN1bHQoXG4gICAgcGFyc2VSZXN1bHQudmFsdWUsXG4gICAge1xuICAgICAgdGV4dDogcmVzdWx0LFxuICAgICAgcmVzcG9uc2U6IGNvbnRleHQucmVzcG9uc2UsXG4gICAgICB1c2FnZTogY29udGV4dC51c2FnZSxcbiAgICB9LFxuICApO1xuXG4gIGlmICghdmFsaWRhdGlvblJlc3VsdC5zdWNjZXNzKSB7XG4gICAgdGhyb3cgbmV3IE5vT2JqZWN0R2VuZXJhdGVkRXJyb3Ioe1xuICAgICAgbWVzc2FnZTogJ05vIG9iamVjdCBnZW5lcmF0ZWQ6IHJlc3BvbnNlIGRpZCBub3QgbWF0Y2ggc2NoZW1hLicsXG4gICAgICBjYXVzZTogdmFsaWRhdGlvblJlc3VsdC5lcnJvcixcbiAgICAgIHRleHQ6IHJlc3VsdCxcbiAgICAgIHJlc3BvbnNlOiBjb250ZXh0LnJlc3BvbnNlLFxuICAgICAgdXNhZ2U6IGNvbnRleHQudXNhZ2UsXG4gICAgICBmaW5pc2hSZWFzb246IGNvbnRleHQuZmluaXNoUmVhc29uLFxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHZhbGlkYXRpb25SZXN1bHQudmFsdWU7XG59XG5cbi8qKlxuICogUGFyc2VzIGFuZCB2YWxpZGF0ZXMgYSByZXN1bHQgc3RyaW5nIGJ5IHBhcnNpbmcgaXQgYXMgSlNPTiBhbmQgdmFsaWRhdGluZyBhZ2FpbnN0IHRoZSBvdXRwdXQgc3RyYXRlZ3kuXG4gKiBJZiB0aGUgcmVzdWx0IGNhbm5vdCBiZSBwYXJzZWQsIGl0IGF0dGVtcHRzIHRvIHJlcGFpciB0aGUgcmVzdWx0IHVzaW5nIHRoZSByZXBhaXJUZXh0IGZ1bmN0aW9uLlxuICpcbiAqIEBwYXJhbSByZXN1bHQgLSBUaGUgcmVzdWx0IHN0cmluZyB0byBwYXJzZSBhbmQgdmFsaWRhdGVcbiAqIEBwYXJhbSBvdXRwdXRTdHJhdGVneSAtIFRoZSBvdXRwdXQgc3RyYXRlZ3kgY29udGFpbmluZyB2YWxpZGF0aW9uIGxvZ2ljXG4gKiBAcGFyYW0gcmVwYWlyVGV4dCAtIEEgZnVuY3Rpb24gdGhhdCBhdHRlbXB0cyB0byByZXBhaXIgdGhlIHJlc3VsdCBzdHJpbmdcbiAqIEBwYXJhbSBjb250ZXh0IC0gQWRkaXRpb25hbCBjb250ZXh0IGZvciBlcnJvciByZXBvcnRpbmdcbiAqIEByZXR1cm5zIFRoZSB2YWxpZGF0ZWQgcmVzdWx0XG4gKiBAdGhyb3dzIE5vT2JqZWN0R2VuZXJhdGVkRXJyb3IgaWYgcGFyc2luZyBvciB2YWxpZGF0aW9uIGZhaWxzXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwYXJzZUFuZFZhbGlkYXRlT2JqZWN0UmVzdWx0V2l0aFJlcGFpcjxSRVNVTFQ+KFxuICByZXN1bHQ6IHN0cmluZyxcbiAgb3V0cHV0U3RyYXRlZ3k6IE91dHB1dFN0cmF0ZWd5PGFueSwgUkVTVUxULCBhbnk+LFxuICByZXBhaXJUZXh0OiBSZXBhaXJUZXh0RnVuY3Rpb24gfCB1bmRlZmluZWQsXG4gIGNvbnRleHQ6IHtcbiAgICByZXNwb25zZTogTGFuZ3VhZ2VNb2RlbFJlc3BvbnNlTWV0YWRhdGE7XG4gICAgdXNhZ2U6IExhbmd1YWdlTW9kZWxVc2FnZTtcbiAgICBmaW5pc2hSZWFzb246IEZpbmlzaFJlYXNvbjtcbiAgfSxcbik6IFByb21pc2U8UkVTVUxUPiB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGF3YWl0IHBhcnNlQW5kVmFsaWRhdGVPYmplY3RSZXN1bHQocmVzdWx0LCBvdXRwdXRTdHJhdGVneSwgY29udGV4dCk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgaWYgKFxuICAgICAgcmVwYWlyVGV4dCAhPSBudWxsICYmXG4gICAgICBOb09iamVjdEdlbmVyYXRlZEVycm9yLmlzSW5zdGFuY2UoZXJyb3IpICYmXG4gICAgICAoSlNPTlBhcnNlRXJyb3IuaXNJbnN0YW5jZShlcnJvci5jYXVzZSkgfHxcbiAgICAgICAgVHlwZVZhbGlkYXRpb25FcnJvci5pc0luc3RhbmNlKGVycm9yLmNhdXNlKSlcbiAgICApIHtcbiAgICAgIGNvbnN0IHJlcGFpcmVkVGV4dCA9IGF3YWl0IHJlcGFpclRleHQoe1xuICAgICAgICB0ZXh0OiByZXN1bHQsXG4gICAgICAgIGVycm9yOiBlcnJvci5jYXVzZSxcbiAgICAgIH0pO1xuICAgICAgaWYgKHJlcGFpcmVkVGV4dCA9PT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhd2FpdCBwYXJzZUFuZFZhbGlkYXRlT2JqZWN0UmVzdWx0KFxuICAgICAgICByZXBhaXJlZFRleHQsXG4gICAgICAgIG91dHB1dFN0cmF0ZWd5LFxuICAgICAgICBjb250ZXh0LFxuICAgICAgKTtcbiAgICB9XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBGbGV4aWJsZVNjaGVtYSB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXItdXRpbHMnO1xuaW1wb3J0IHsgSW52YWxpZEFyZ3VtZW50RXJyb3IgfSBmcm9tICcuLi9lcnJvci9pbnZhbGlkLWFyZ3VtZW50LWVycm9yJztcblxuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlT2JqZWN0R2VuZXJhdGlvbklucHV0KHtcbiAgb3V0cHV0LFxuICBzY2hlbWEsXG4gIHNjaGVtYU5hbWUsXG4gIHNjaGVtYURlc2NyaXB0aW9uLFxuICBlbnVtVmFsdWVzLFxufToge1xuICBvdXRwdXQ/OiAnb2JqZWN0JyB8ICdhcnJheScgfCAnZW51bScgfCAnbm8tc2NoZW1hJztcbiAgc2NoZW1hPzogRmxleGlibGVTY2hlbWE8dW5rbm93bj47XG4gIHNjaGVtYU5hbWU/OiBzdHJpbmc7XG4gIHNjaGVtYURlc2NyaXB0aW9uPzogc3RyaW5nO1xuICBlbnVtVmFsdWVzPzogQXJyYXk8dW5rbm93bj47XG59KSB7XG4gIGlmIChcbiAgICBvdXRwdXQgIT0gbnVsbCAmJlxuICAgIG91dHB1dCAhPT0gJ29iamVjdCcgJiZcbiAgICBvdXRwdXQgIT09ICdhcnJheScgJiZcbiAgICBvdXRwdXQgIT09ICdlbnVtJyAmJlxuICAgIG91dHB1dCAhPT0gJ25vLXNjaGVtYSdcbiAgKSB7XG4gICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEVycm9yKHtcbiAgICAgIHBhcmFtZXRlcjogJ291dHB1dCcsXG4gICAgICB2YWx1ZTogb3V0cHV0LFxuICAgICAgbWVzc2FnZTogJ0ludmFsaWQgb3V0cHV0IHR5cGUuJyxcbiAgICB9KTtcbiAgfVxuXG4gIGlmIChvdXRwdXQgPT09ICduby1zY2hlbWEnKSB7XG4gICAgaWYgKHNjaGVtYSAhPSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3Ioe1xuICAgICAgICBwYXJhbWV0ZXI6ICdzY2hlbWEnLFxuICAgICAgICB2YWx1ZTogc2NoZW1hLFxuICAgICAgICBtZXNzYWdlOiAnU2NoZW1hIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIG5vLXNjaGVtYSBvdXRwdXQuJyxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChzY2hlbWFEZXNjcmlwdGlvbiAhPSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3Ioe1xuICAgICAgICBwYXJhbWV0ZXI6ICdzY2hlbWFEZXNjcmlwdGlvbicsXG4gICAgICAgIHZhbHVlOiBzY2hlbWFEZXNjcmlwdGlvbixcbiAgICAgICAgbWVzc2FnZTogJ1NjaGVtYSBkZXNjcmlwdGlvbiBpcyBub3Qgc3VwcG9ydGVkIGZvciBuby1zY2hlbWEgb3V0cHV0LicsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoc2NoZW1hTmFtZSAhPSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3Ioe1xuICAgICAgICBwYXJhbWV0ZXI6ICdzY2hlbWFOYW1lJyxcbiAgICAgICAgdmFsdWU6IHNjaGVtYU5hbWUsXG4gICAgICAgIG1lc3NhZ2U6ICdTY2hlbWEgbmFtZSBpcyBub3Qgc3VwcG9ydGVkIGZvciBuby1zY2hlbWEgb3V0cHV0LicsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoZW51bVZhbHVlcyAhPSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3Ioe1xuICAgICAgICBwYXJhbWV0ZXI6ICdlbnVtVmFsdWVzJyxcbiAgICAgICAgdmFsdWU6IGVudW1WYWx1ZXMsXG4gICAgICAgIG1lc3NhZ2U6ICdFbnVtIHZhbHVlcyBhcmUgbm90IHN1cHBvcnRlZCBmb3Igbm8tc2NoZW1hIG91dHB1dC4nLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgaWYgKG91dHB1dCA9PT0gJ29iamVjdCcpIHtcbiAgICBpZiAoc2NoZW1hID09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFcnJvcih7XG4gICAgICAgIHBhcmFtZXRlcjogJ3NjaGVtYScsXG4gICAgICAgIHZhbHVlOiBzY2hlbWEsXG4gICAgICAgIG1lc3NhZ2U6ICdTY2hlbWEgaXMgcmVxdWlyZWQgZm9yIG9iamVjdCBvdXRwdXQuJyxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChlbnVtVmFsdWVzICE9IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFcnJvcih7XG4gICAgICAgIHBhcmFtZXRlcjogJ2VudW1WYWx1ZXMnLFxuICAgICAgICB2YWx1ZTogZW51bVZhbHVlcyxcbiAgICAgICAgbWVzc2FnZTogJ0VudW0gdmFsdWVzIGFyZSBub3Qgc3VwcG9ydGVkIGZvciBvYmplY3Qgb3V0cHV0LicsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBpZiAob3V0cHV0ID09PSAnYXJyYXknKSB7XG4gICAgaWYgKHNjaGVtYSA9PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3Ioe1xuICAgICAgICBwYXJhbWV0ZXI6ICdzY2hlbWEnLFxuICAgICAgICB2YWx1ZTogc2NoZW1hLFxuICAgICAgICBtZXNzYWdlOiAnRWxlbWVudCBzY2hlbWEgaXMgcmVxdWlyZWQgZm9yIGFycmF5IG91dHB1dC4nLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKGVudW1WYWx1ZXMgIT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEVycm9yKHtcbiAgICAgICAgcGFyYW1ldGVyOiAnZW51bVZhbHVlcycsXG4gICAgICAgIHZhbHVlOiBlbnVtVmFsdWVzLFxuICAgICAgICBtZXNzYWdlOiAnRW51bSB2YWx1ZXMgYXJlIG5vdCBzdXBwb3J0ZWQgZm9yIGFycmF5IG91dHB1dC4nLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgaWYgKG91dHB1dCA9PT0gJ2VudW0nKSB7XG4gICAgaWYgKHNjaGVtYSAhPSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3Ioe1xuICAgICAgICBwYXJhbWV0ZXI6ICdzY2hlbWEnLFxuICAgICAgICB2YWx1ZTogc2NoZW1hLFxuICAgICAgICBtZXNzYWdlOiAnU2NoZW1hIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIGVudW0gb3V0cHV0LicsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoc2NoZW1hRGVzY3JpcHRpb24gIT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEVycm9yKHtcbiAgICAgICAgcGFyYW1ldGVyOiAnc2NoZW1hRGVzY3JpcHRpb24nLFxuICAgICAgICB2YWx1ZTogc2NoZW1hRGVzY3JpcHRpb24sXG4gICAgICAgIG1lc3NhZ2U6ICdTY2hlbWEgZGVzY3JpcHRpb24gaXMgbm90IHN1cHBvcnRlZCBmb3IgZW51bSBvdXRwdXQuJyxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChzY2hlbWFOYW1lICE9IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFcnJvcih7XG4gICAgICAgIHBhcmFtZXRlcjogJ3NjaGVtYU5hbWUnLFxuICAgICAgICB2YWx1ZTogc2NoZW1hTmFtZSxcbiAgICAgICAgbWVzc2FnZTogJ1NjaGVtYSBuYW1lIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIGVudW0gb3V0cHV0LicsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoZW51bVZhbHVlcyA9PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3Ioe1xuICAgICAgICBwYXJhbWV0ZXI6ICdlbnVtVmFsdWVzJyxcbiAgICAgICAgdmFsdWU6IGVudW1WYWx1ZXMsXG4gICAgICAgIG1lc3NhZ2U6ICdFbnVtIHZhbHVlcyBhcmUgcmVxdWlyZWQgZm9yIGVudW0gb3V0cHV0LicsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHZhbHVlIG9mIGVudW1WYWx1ZXMpIHtcbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFcnJvcih7XG4gICAgICAgICAgcGFyYW1ldGVyOiAnZW51bVZhbHVlcycsXG4gICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgbWVzc2FnZTogJ0VudW0gdmFsdWVzIG11c3QgYmUgc3RyaW5ncy4nLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbiIsICJpbXBvcnQge1xuICBKU09OVmFsdWUsXG4gIExhbmd1YWdlTW9kZWxWMkNhbGxXYXJuaW5nLFxuICBMYW5ndWFnZU1vZGVsVjJGaW5pc2hSZWFzb24sXG4gIExhbmd1YWdlTW9kZWxWMlN0cmVhbVBhcnQsXG4gIExhbmd1YWdlTW9kZWxWMlVzYWdlLFxuICBTaGFyZWRWMlByb3ZpZGVyTWV0YWRhdGEsXG59IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHtcbiAgY3JlYXRlSWRHZW5lcmF0b3IsXG4gIEZsZXhpYmxlU2NoZW1hLFxuICBQcm92aWRlck9wdGlvbnMsXG4gIHR5cGUgSW5mZXJTY2hlbWEsXG59IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXItdXRpbHMnO1xuaW1wb3J0IHsgU2VydmVyUmVzcG9uc2UgfSBmcm9tICdodHRwJztcbmltcG9ydCB7IGxvZ1dhcm5pbmdzIH0gZnJvbSAnLi4vbG9nZ2VyL2xvZy13YXJuaW5ncyc7XG5pbXBvcnQgeyByZXNvbHZlTGFuZ3VhZ2VNb2RlbCB9IGZyb20gJy4uL21vZGVsL3Jlc29sdmUtbW9kZWwnO1xuaW1wb3J0IHsgQ2FsbFNldHRpbmdzIH0gZnJvbSAnLi4vcHJvbXB0L2NhbGwtc2V0dGluZ3MnO1xuaW1wb3J0IHsgY29udmVydFRvTGFuZ3VhZ2VNb2RlbFByb21wdCB9IGZyb20gJy4uL3Byb21wdC9jb252ZXJ0LXRvLWxhbmd1YWdlLW1vZGVsLXByb21wdCc7XG5pbXBvcnQgeyBwcmVwYXJlQ2FsbFNldHRpbmdzIH0gZnJvbSAnLi4vcHJvbXB0L3ByZXBhcmUtY2FsbC1zZXR0aW5ncyc7XG5pbXBvcnQgeyBQcm9tcHQgfSBmcm9tICcuLi9wcm9tcHQvcHJvbXB0JztcbmltcG9ydCB7IHN0YW5kYXJkaXplUHJvbXB0IH0gZnJvbSAnLi4vcHJvbXB0L3N0YW5kYXJkaXplLXByb21wdCc7XG5pbXBvcnQgeyB3cmFwR2F0ZXdheUVycm9yIH0gZnJvbSAnLi4vcHJvbXB0L3dyYXAtZ2F0ZXdheS1lcnJvcic7XG5pbXBvcnQgeyBhc3NlbWJsZU9wZXJhdGlvbk5hbWUgfSBmcm9tICcuLi90ZWxlbWV0cnkvYXNzZW1ibGUtb3BlcmF0aW9uLW5hbWUnO1xuaW1wb3J0IHsgZ2V0QmFzZVRlbGVtZXRyeUF0dHJpYnV0ZXMgfSBmcm9tICcuLi90ZWxlbWV0cnkvZ2V0LWJhc2UtdGVsZW1ldHJ5LWF0dHJpYnV0ZXMnO1xuaW1wb3J0IHsgZ2V0VHJhY2VyIH0gZnJvbSAnLi4vdGVsZW1ldHJ5L2dldC10cmFjZXInO1xuaW1wb3J0IHsgcmVjb3JkU3BhbiB9IGZyb20gJy4uL3RlbGVtZXRyeS9yZWNvcmQtc3Bhbic7XG5pbXBvcnQgeyBzZWxlY3RUZWxlbWV0cnlBdHRyaWJ1dGVzIH0gZnJvbSAnLi4vdGVsZW1ldHJ5L3NlbGVjdC10ZWxlbWV0cnktYXR0cmlidXRlcyc7XG5pbXBvcnQgeyBzdHJpbmdpZnlGb3JUZWxlbWV0cnkgfSBmcm9tICcuLi90ZWxlbWV0cnkvc3RyaW5naWZ5LWZvci10ZWxlbWV0cnknO1xuaW1wb3J0IHsgVGVsZW1ldHJ5U2V0dGluZ3MgfSBmcm9tICcuLi90ZWxlbWV0cnkvdGVsZW1ldHJ5LXNldHRpbmdzJztcbmltcG9ydCB7IGNyZWF0ZVRleHRTdHJlYW1SZXNwb25zZSB9IGZyb20gJy4uL3RleHQtc3RyZWFtL2NyZWF0ZS10ZXh0LXN0cmVhbS1yZXNwb25zZSc7XG5pbXBvcnQgeyBwaXBlVGV4dFN0cmVhbVRvUmVzcG9uc2UgfSBmcm9tICcuLi90ZXh0LXN0cmVhbS9waXBlLXRleHQtc3RyZWFtLXRvLXJlc3BvbnNlJztcbmltcG9ydCB7XG4gIENhbGxXYXJuaW5nLFxuICBGaW5pc2hSZWFzb24sXG4gIExhbmd1YWdlTW9kZWwsXG59IGZyb20gJy4uL3R5cGVzL2xhbmd1YWdlLW1vZGVsJztcbmltcG9ydCB7IExhbmd1YWdlTW9kZWxSZXF1ZXN0TWV0YWRhdGEgfSBmcm9tICcuLi90eXBlcy9sYW5ndWFnZS1tb2RlbC1yZXF1ZXN0LW1ldGFkYXRhJztcbmltcG9ydCB7IExhbmd1YWdlTW9kZWxSZXNwb25zZU1ldGFkYXRhIH0gZnJvbSAnLi4vdHlwZXMvbGFuZ3VhZ2UtbW9kZWwtcmVzcG9uc2UtbWV0YWRhdGEnO1xuaW1wb3J0IHsgUHJvdmlkZXJNZXRhZGF0YSB9IGZyb20gJy4uL3R5cGVzL3Byb3ZpZGVyLW1ldGFkYXRhJztcbmltcG9ydCB7IExhbmd1YWdlTW9kZWxVc2FnZSB9IGZyb20gJy4uL3R5cGVzL3VzYWdlJztcbmltcG9ydCB7IERlZXBQYXJ0aWFsLCBpc0RlZXBFcXVhbERhdGEsIHBhcnNlUGFydGlhbEpzb24gfSBmcm9tICcuLi91dGlsJztcbmltcG9ydCB7XG4gIEFzeW5jSXRlcmFibGVTdHJlYW0sXG4gIGNyZWF0ZUFzeW5jSXRlcmFibGVTdHJlYW0sXG59IGZyb20gJy4uL3V0aWwvYXN5bmMtaXRlcmFibGUtc3RyZWFtJztcbmltcG9ydCB7IGNyZWF0ZVN0aXRjaGFibGVTdHJlYW0gfSBmcm9tICcuLi91dGlsL2NyZWF0ZS1zdGl0Y2hhYmxlLXN0cmVhbSc7XG5pbXBvcnQgeyBEZWxheWVkUHJvbWlzZSB9IGZyb20gJy4uL3V0aWwvZGVsYXllZC1wcm9taXNlJztcbmltcG9ydCB7IERvd25sb2FkRnVuY3Rpb24gfSBmcm9tICcuLi91dGlsL2Rvd25sb2FkL2Rvd25sb2FkLWZ1bmN0aW9uJztcbmltcG9ydCB7IG5vdyBhcyBvcmlnaW5hbE5vdyB9IGZyb20gJy4uL3V0aWwvbm93JztcbmltcG9ydCB7IHByZXBhcmVSZXRyaWVzIH0gZnJvbSAnLi4vdXRpbC9wcmVwYXJlLXJldHJpZXMnO1xuaW1wb3J0IHsgZ2V0T3V0cHV0U3RyYXRlZ3ksIE91dHB1dFN0cmF0ZWd5IH0gZnJvbSAnLi9vdXRwdXQtc3RyYXRlZ3knO1xuaW1wb3J0IHsgcGFyc2VBbmRWYWxpZGF0ZU9iamVjdFJlc3VsdFdpdGhSZXBhaXIgfSBmcm9tICcuL3BhcnNlLWFuZC12YWxpZGF0ZS1vYmplY3QtcmVzdWx0JztcbmltcG9ydCB7IFJlcGFpclRleHRGdW5jdGlvbiB9IGZyb20gJy4vcmVwYWlyLXRleHQnO1xuaW1wb3J0IHsgT2JqZWN0U3RyZWFtUGFydCwgU3RyZWFtT2JqZWN0UmVzdWx0IH0gZnJvbSAnLi9zdHJlYW0tb2JqZWN0LXJlc3VsdCc7XG5pbXBvcnQgeyB2YWxpZGF0ZU9iamVjdEdlbmVyYXRpb25JbnB1dCB9IGZyb20gJy4vdmFsaWRhdGUtb2JqZWN0LWdlbmVyYXRpb24taW5wdXQnO1xuXG5jb25zdCBvcmlnaW5hbEdlbmVyYXRlSWQgPSBjcmVhdGVJZEdlbmVyYXRvcih7IHByZWZpeDogJ2Fpb2JqJywgc2l6ZTogMjQgfSk7XG5cbi8qKlxuQ2FsbGJhY2sgdGhhdCBpcyBzZXQgdXNpbmcgdGhlIGBvbkVycm9yYCBvcHRpb24uXG5cbkBwYXJhbSBldmVudCAtIFRoZSBldmVudCB0aGF0IGlzIHBhc3NlZCB0byB0aGUgY2FsbGJhY2suXG4gKi9cbmV4cG9ydCB0eXBlIFN0cmVhbU9iamVjdE9uRXJyb3JDYWxsYmFjayA9IChldmVudDoge1xuICBlcnJvcjogdW5rbm93bjtcbn0pID0+IFByb21pc2U8dm9pZD4gfCB2b2lkO1xuXG4vKipcbkNhbGxiYWNrIHRoYXQgaXMgc2V0IHVzaW5nIHRoZSBgb25GaW5pc2hgIG9wdGlvbi5cblxuQHBhcmFtIGV2ZW50IC0gVGhlIGV2ZW50IHRoYXQgaXMgcGFzc2VkIHRvIHRoZSBjYWxsYmFjay5cbiAqL1xuZXhwb3J0IHR5cGUgU3RyZWFtT2JqZWN0T25GaW5pc2hDYWxsYmFjazxSRVNVTFQ+ID0gKGV2ZW50OiB7XG4gIC8qKlxuVGhlIHRva2VuIHVzYWdlIG9mIHRoZSBnZW5lcmF0ZWQgcmVzcG9uc2UuXG4qL1xuICB1c2FnZTogTGFuZ3VhZ2VNb2RlbFVzYWdlO1xuXG4gIC8qKlxuVGhlIGdlbmVyYXRlZCBvYmplY3QuIENhbiBiZSB1bmRlZmluZWQgaWYgdGhlIGZpbmFsIG9iamVjdCBkb2VzIG5vdCBtYXRjaCB0aGUgc2NoZW1hLlxuKi9cbiAgb2JqZWN0OiBSRVNVTFQgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG5PcHRpb25hbCBlcnJvciBvYmplY3QuIFRoaXMgaXMgZS5nLiBhIFR5cGVWYWxpZGF0aW9uRXJyb3Igd2hlbiB0aGUgZmluYWwgb2JqZWN0IGRvZXMgbm90IG1hdGNoIHRoZSBzY2hlbWEuXG4qL1xuICBlcnJvcjogdW5rbm93biB8IHVuZGVmaW5lZDtcblxuICAvKipcblJlc3BvbnNlIG1ldGFkYXRhLlxuICovXG4gIHJlc3BvbnNlOiBMYW5ndWFnZU1vZGVsUmVzcG9uc2VNZXRhZGF0YTtcblxuICAvKipcbldhcm5pbmdzIGZyb20gdGhlIG1vZGVsIHByb3ZpZGVyIChlLmcuIHVuc3VwcG9ydGVkIHNldHRpbmdzKS5cbiovXG4gIHdhcm5pbmdzPzogQ2FsbFdhcm5pbmdbXTtcblxuICAvKipcbkFkZGl0aW9uYWwgcHJvdmlkZXItc3BlY2lmaWMgbWV0YWRhdGEuIFRoZXkgYXJlIHBhc3NlZCB0aHJvdWdoXG50byB0aGUgcHJvdmlkZXIgZnJvbSB0aGUgQUkgU0RLIGFuZCBlbmFibGUgcHJvdmlkZXItc3BlY2lmaWNcbmZ1bmN0aW9uYWxpdHkgdGhhdCBjYW4gYmUgZnVsbHkgZW5jYXBzdWxhdGVkIGluIHRoZSBwcm92aWRlci5cbiovXG4gIHByb3ZpZGVyTWV0YWRhdGE6IFByb3ZpZGVyTWV0YWRhdGEgfCB1bmRlZmluZWQ7XG59KSA9PiBQcm9taXNlPHZvaWQ+IHwgdm9pZDtcblxuLyoqXG5HZW5lcmF0ZSBhIHN0cnVjdHVyZWQsIHR5cGVkIG9iamVjdCBmb3IgYSBnaXZlbiBwcm9tcHQgYW5kIHNjaGVtYSB1c2luZyBhIGxhbmd1YWdlIG1vZGVsLlxuXG5UaGlzIGZ1bmN0aW9uIHN0cmVhbXMgdGhlIG91dHB1dC4gSWYgeW91IGRvIG5vdCB3YW50IHRvIHN0cmVhbSB0aGUgb3V0cHV0LCB1c2UgYGdlbmVyYXRlT2JqZWN0YCBpbnN0ZWFkLlxuXG5AcGFyYW0gbW9kZWwgLSBUaGUgbGFuZ3VhZ2UgbW9kZWwgdG8gdXNlLlxuQHBhcmFtIHRvb2xzIC0gVG9vbHMgdGhhdCBhcmUgYWNjZXNzaWJsZSB0byBhbmQgY2FuIGJlIGNhbGxlZCBieSB0aGUgbW9kZWwuIFRoZSBtb2RlbCBuZWVkcyB0byBzdXBwb3J0IGNhbGxpbmcgdG9vbHMuXG5cbkBwYXJhbSBzeXN0ZW0gLSBBIHN5c3RlbSBtZXNzYWdlIHRoYXQgd2lsbCBiZSBwYXJ0IG9mIHRoZSBwcm9tcHQuXG5AcGFyYW0gcHJvbXB0IC0gQSBzaW1wbGUgdGV4dCBwcm9tcHQuIFlvdSBjYW4gZWl0aGVyIHVzZSBgcHJvbXB0YCBvciBgbWVzc2FnZXNgIGJ1dCBub3QgYm90aC5cbkBwYXJhbSBtZXNzYWdlcyAtIEEgbGlzdCBvZiBtZXNzYWdlcy4gWW91IGNhbiBlaXRoZXIgdXNlIGBwcm9tcHRgIG9yIGBtZXNzYWdlc2AgYnV0IG5vdCBib3RoLlxuXG5AcGFyYW0gbWF4T3V0cHV0VG9rZW5zIC0gTWF4aW11bSBudW1iZXIgb2YgdG9rZW5zIHRvIGdlbmVyYXRlLlxuQHBhcmFtIHRlbXBlcmF0dXJlIC0gVGVtcGVyYXR1cmUgc2V0dGluZy5cblRoZSB2YWx1ZSBpcyBwYXNzZWQgdGhyb3VnaCB0byB0aGUgcHJvdmlkZXIuIFRoZSByYW5nZSBkZXBlbmRzIG9uIHRoZSBwcm92aWRlciBhbmQgbW9kZWwuXG5JdCBpcyByZWNvbW1lbmRlZCB0byBzZXQgZWl0aGVyIGB0ZW1wZXJhdHVyZWAgb3IgYHRvcFBgLCBidXQgbm90IGJvdGguXG5AcGFyYW0gdG9wUCAtIE51Y2xldXMgc2FtcGxpbmcuXG5UaGUgdmFsdWUgaXMgcGFzc2VkIHRocm91Z2ggdG8gdGhlIHByb3ZpZGVyLiBUaGUgcmFuZ2UgZGVwZW5kcyBvbiB0aGUgcHJvdmlkZXIgYW5kIG1vZGVsLlxuSXQgaXMgcmVjb21tZW5kZWQgdG8gc2V0IGVpdGhlciBgdGVtcGVyYXR1cmVgIG9yIGB0b3BQYCwgYnV0IG5vdCBib3RoLlxuQHBhcmFtIHRvcEsgLSBPbmx5IHNhbXBsZSBmcm9tIHRoZSB0b3AgSyBvcHRpb25zIGZvciBlYWNoIHN1YnNlcXVlbnQgdG9rZW4uXG5Vc2VkIHRvIHJlbW92ZSBcImxvbmcgdGFpbFwiIGxvdyBwcm9iYWJpbGl0eSByZXNwb25zZXMuXG5SZWNvbW1lbmRlZCBmb3IgYWR2YW5jZWQgdXNlIGNhc2VzIG9ubHkuIFlvdSB1c3VhbGx5IG9ubHkgbmVlZCB0byB1c2UgdGVtcGVyYXR1cmUuXG5AcGFyYW0gcHJlc2VuY2VQZW5hbHR5IC0gUHJlc2VuY2UgcGVuYWx0eSBzZXR0aW5nLlxuSXQgYWZmZWN0cyB0aGUgbGlrZWxpaG9vZCBvZiB0aGUgbW9kZWwgdG8gcmVwZWF0IGluZm9ybWF0aW9uIHRoYXQgaXMgYWxyZWFkeSBpbiB0aGUgcHJvbXB0LlxuVGhlIHZhbHVlIGlzIHBhc3NlZCB0aHJvdWdoIHRvIHRoZSBwcm92aWRlci4gVGhlIHJhbmdlIGRlcGVuZHMgb24gdGhlIHByb3ZpZGVyIGFuZCBtb2RlbC5cbkBwYXJhbSBmcmVxdWVuY3lQZW5hbHR5IC0gRnJlcXVlbmN5IHBlbmFsdHkgc2V0dGluZy5cbkl0IGFmZmVjdHMgdGhlIGxpa2VsaWhvb2Qgb2YgdGhlIG1vZGVsIHRvIHJlcGVhdGVkbHkgdXNlIHRoZSBzYW1lIHdvcmRzIG9yIHBocmFzZXMuXG5UaGUgdmFsdWUgaXMgcGFzc2VkIHRocm91Z2ggdG8gdGhlIHByb3ZpZGVyLiBUaGUgcmFuZ2UgZGVwZW5kcyBvbiB0aGUgcHJvdmlkZXIgYW5kIG1vZGVsLlxuQHBhcmFtIHN0b3BTZXF1ZW5jZXMgLSBTdG9wIHNlcXVlbmNlcy5cbklmIHNldCwgdGhlIG1vZGVsIHdpbGwgc3RvcCBnZW5lcmF0aW5nIHRleHQgd2hlbiBvbmUgb2YgdGhlIHN0b3Agc2VxdWVuY2VzIGlzIGdlbmVyYXRlZC5cbkBwYXJhbSBzZWVkIC0gVGhlIHNlZWQgKGludGVnZXIpIHRvIHVzZSBmb3IgcmFuZG9tIHNhbXBsaW5nLlxuSWYgc2V0IGFuZCBzdXBwb3J0ZWQgYnkgdGhlIG1vZGVsLCBjYWxscyB3aWxsIGdlbmVyYXRlIGRldGVybWluaXN0aWMgcmVzdWx0cy5cblxuQHBhcmFtIG1heFJldHJpZXMgLSBNYXhpbXVtIG51bWJlciBvZiByZXRyaWVzLiBTZXQgdG8gMCB0byBkaXNhYmxlIHJldHJpZXMuIERlZmF1bHQ6IDIuXG5AcGFyYW0gYWJvcnRTaWduYWwgLSBBbiBvcHRpb25hbCBhYm9ydCBzaWduYWwgdGhhdCBjYW4gYmUgdXNlZCB0byBjYW5jZWwgdGhlIGNhbGwuXG5AcGFyYW0gaGVhZGVycyAtIEFkZGl0aW9uYWwgSFRUUCBoZWFkZXJzIHRvIGJlIHNlbnQgd2l0aCB0aGUgcmVxdWVzdC4gT25seSBhcHBsaWNhYmxlIGZvciBIVFRQLWJhc2VkIHByb3ZpZGVycy5cblxuQHBhcmFtIHNjaGVtYSAtIFRoZSBzY2hlbWEgb2YgdGhlIG9iamVjdCB0aGF0IHRoZSBtb2RlbCBzaG91bGQgZ2VuZXJhdGUuXG5AcGFyYW0gc2NoZW1hTmFtZSAtIE9wdGlvbmFsIG5hbWUgb2YgdGhlIG91dHB1dCB0aGF0IHNob3VsZCBiZSBnZW5lcmF0ZWQuXG5Vc2VkIGJ5IHNvbWUgcHJvdmlkZXJzIGZvciBhZGRpdGlvbmFsIExMTSBndWlkYW5jZSwgZS5nLlxudmlhIHRvb2wgb3Igc2NoZW1hIG5hbWUuXG5AcGFyYW0gc2NoZW1hRGVzY3JpcHRpb24gLSBPcHRpb25hbCBkZXNjcmlwdGlvbiBvZiB0aGUgb3V0cHV0IHRoYXQgc2hvdWxkIGJlIGdlbmVyYXRlZC5cblVzZWQgYnkgc29tZSBwcm92aWRlcnMgZm9yIGFkZGl0aW9uYWwgTExNIGd1aWRhbmNlLCBlLmcuXG52aWEgdG9vbCBvciBzY2hlbWEgZGVzY3JpcHRpb24uXG5cbkBwYXJhbSBvdXRwdXQgLSBUaGUgdHlwZSBvZiB0aGUgb3V0cHV0LlxuXG4tICdvYmplY3QnOiBUaGUgb3V0cHV0IGlzIGFuIG9iamVjdC5cbi0gJ2FycmF5JzogVGhlIG91dHB1dCBpcyBhbiBhcnJheS5cbi0gJ2VudW0nOiBUaGUgb3V0cHV0IGlzIGFuIGVudW0uXG4tICduby1zY2hlbWEnOiBUaGUgb3V0cHV0IGlzIG5vdCBhIHNjaGVtYS5cblxuQHBhcmFtIGV4cGVyaW1lbnRhbF90ZWxlbWV0cnkgLSBPcHRpb25hbCB0ZWxlbWV0cnkgY29uZmlndXJhdGlvbiAoZXhwZXJpbWVudGFsKS5cblxuQHBhcmFtIHByb3ZpZGVyT3B0aW9ucyAtIEFkZGl0aW9uYWwgcHJvdmlkZXItc3BlY2lmaWMgb3B0aW9ucy4gVGhleSBhcmUgcGFzc2VkIHRocm91Z2hcbnRvIHRoZSBwcm92aWRlciBmcm9tIHRoZSBBSSBTREsgYW5kIGVuYWJsZSBwcm92aWRlci1zcGVjaWZpY1xuZnVuY3Rpb25hbGl0eSB0aGF0IGNhbiBiZSBmdWxseSBlbmNhcHN1bGF0ZWQgaW4gdGhlIHByb3ZpZGVyLlxuXG5AcmV0dXJuc1xuQSByZXN1bHQgb2JqZWN0IGZvciBhY2Nlc3NpbmcgdGhlIHBhcnRpYWwgb2JqZWN0IHN0cmVhbSBhbmQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN0cmVhbU9iamVjdDxcbiAgU0NIRU1BIGV4dGVuZHMgRmxleGlibGVTY2hlbWE8dW5rbm93bj4gPSBGbGV4aWJsZVNjaGVtYTxKU09OVmFsdWU+LFxuICBPVVRQVVQgZXh0ZW5kc1xuICAgIHwgJ29iamVjdCdcbiAgICB8ICdhcnJheSdcbiAgICB8ICdlbnVtJ1xuICAgIHwgJ25vLXNjaGVtYScgPSBJbmZlclNjaGVtYTxTQ0hFTUE+IGV4dGVuZHMgc3RyaW5nID8gJ2VudW0nIDogJ29iamVjdCcsXG4gIFJFU1VMVCA9IE9VVFBVVCBleHRlbmRzICdhcnJheSdcbiAgICA/IEFycmF5PEluZmVyU2NoZW1hPFNDSEVNQT4+XG4gICAgOiBJbmZlclNjaGVtYTxTQ0hFTUE+LFxuPihcbiAgb3B0aW9uczogT21pdDxDYWxsU2V0dGluZ3MsICdzdG9wU2VxdWVuY2VzJz4gJlxuICAgIFByb21wdCAmXG4gICAgKE9VVFBVVCBleHRlbmRzICdlbnVtJ1xuICAgICAgPyB7XG4gICAgICAgICAgLyoqXG5UaGUgZW51bSB2YWx1ZXMgdGhhdCB0aGUgbW9kZWwgc2hvdWxkIHVzZS5cbiAgICAgICAgKi9cbiAgICAgICAgICBlbnVtOiBBcnJheTxSRVNVTFQ+O1xuICAgICAgICAgIG1vZGU/OiAnanNvbic7XG4gICAgICAgICAgb3V0cHV0OiAnZW51bSc7XG4gICAgICAgIH1cbiAgICAgIDogT1VUUFVUIGV4dGVuZHMgJ25vLXNjaGVtYSdcbiAgICAgICAgPyB7fVxuICAgICAgICA6IHtcbiAgICAgICAgICAgIC8qKlxuVGhlIHNjaGVtYSBvZiB0aGUgb2JqZWN0IHRoYXQgdGhlIG1vZGVsIHNob3VsZCBnZW5lcmF0ZS5cbiAgICAgICovXG4gICAgICAgICAgICBzY2hlbWE6IFNDSEVNQTtcblxuICAgICAgICAgICAgLyoqXG5PcHRpb25hbCBuYW1lIG9mIHRoZSBvdXRwdXQgdGhhdCBzaG91bGQgYmUgZ2VuZXJhdGVkLlxuVXNlZCBieSBzb21lIHByb3ZpZGVycyBmb3IgYWRkaXRpb25hbCBMTE0gZ3VpZGFuY2UsIGUuZy5cbnZpYSB0b29sIG9yIHNjaGVtYSBuYW1lLlxuICAgICAgKi9cbiAgICAgICAgICAgIHNjaGVtYU5hbWU/OiBzdHJpbmc7XG5cbiAgICAgICAgICAgIC8qKlxuT3B0aW9uYWwgZGVzY3JpcHRpb24gb2YgdGhlIG91dHB1dCB0aGF0IHNob3VsZCBiZSBnZW5lcmF0ZWQuXG5Vc2VkIGJ5IHNvbWUgcHJvdmlkZXJzIGZvciBhZGRpdGlvbmFsIExMTSBndWlkYW5jZSwgZS5nLlxudmlhIHRvb2wgb3Igc2NoZW1hIGRlc2NyaXB0aW9uLlxuICAgICAgKi9cbiAgICAgICAgICAgIHNjaGVtYURlc2NyaXB0aW9uPzogc3RyaW5nO1xuXG4gICAgICAgICAgICAvKipcblRoZSBtb2RlIHRvIHVzZSBmb3Igb2JqZWN0IGdlbmVyYXRpb24uXG5cblRoZSBzY2hlbWEgaXMgY29udmVydGVkIGludG8gYSBKU09OIHNjaGVtYSBhbmQgdXNlZCBpbiBvbmUgb2YgdGhlIGZvbGxvd2luZyB3YXlzXG5cbi0gJ2F1dG8nOiBUaGUgcHJvdmlkZXIgd2lsbCBjaG9vc2UgdGhlIGJlc3QgbW9kZSBmb3IgdGhlIG1vZGVsLlxuLSAndG9vbCc6IEEgdG9vbCB3aXRoIHRoZSBKU09OIHNjaGVtYSBhcyBwYXJhbWV0ZXJzIGlzIHByb3ZpZGVkIGFuZCB0aGUgcHJvdmlkZXIgaXMgaW5zdHJ1Y3RlZCB0byB1c2UgaXQuXG4tICdqc29uJzogVGhlIEpTT04gc2NoZW1hIGFuZCBhbiBpbnN0cnVjdGlvbiBhcmUgaW5qZWN0ZWQgaW50byB0aGUgcHJvbXB0LiBJZiB0aGUgcHJvdmlkZXIgc3VwcG9ydHMgSlNPTiBtb2RlLCBpdCBpcyBlbmFibGVkLiBJZiB0aGUgcHJvdmlkZXIgc3VwcG9ydHMgSlNPTiBncmFtbWFycywgdGhlIGdyYW1tYXIgaXMgdXNlZC5cblxuUGxlYXNlIG5vdGUgdGhhdCBtb3N0IHByb3ZpZGVycyBkbyBub3Qgc3VwcG9ydCBhbGwgbW9kZXMuXG5cbkRlZmF1bHQgYW5kIHJlY29tbWVuZGVkOiAnYXV0bycgKGJlc3QgbW9kZSBmb3IgdGhlIG1vZGVsKS5cbiAgICAgICovXG4gICAgICAgICAgICBtb2RlPzogJ2F1dG8nIHwgJ2pzb24nIHwgJ3Rvb2wnO1xuICAgICAgICAgIH0pICYge1xuICAgICAgb3V0cHV0PzogT1VUUFVUO1xuXG4gICAgICAvKipcblRoZSBsYW5ndWFnZSBtb2RlbCB0byB1c2UuXG4gICAgICovXG4gICAgICBtb2RlbDogTGFuZ3VhZ2VNb2RlbDtcblxuICAgICAgLyoqXG5BIGZ1bmN0aW9uIHRoYXQgYXR0ZW1wdHMgdG8gcmVwYWlyIHRoZSByYXcgb3V0cHV0IG9mIHRoZSBtb2RlbFxudG8gZW5hYmxlIEpTT04gcGFyc2luZy5cbiAgICAgICAqL1xuICAgICAgZXhwZXJpbWVudGFsX3JlcGFpclRleHQ/OiBSZXBhaXJUZXh0RnVuY3Rpb247XG5cbiAgICAgIC8qKlxuT3B0aW9uYWwgdGVsZW1ldHJ5IGNvbmZpZ3VyYXRpb24gKGV4cGVyaW1lbnRhbCkuXG4gICAgICAgKi9cblxuICAgICAgZXhwZXJpbWVudGFsX3RlbGVtZXRyeT86IFRlbGVtZXRyeVNldHRpbmdzO1xuXG4gICAgICAvKipcbiAgQ3VzdG9tIGRvd25sb2FkIGZ1bmN0aW9uIHRvIHVzZSBmb3IgVVJMcy5cblxuICBCeSBkZWZhdWx0LCBmaWxlcyBhcmUgZG93bmxvYWRlZCBpZiB0aGUgbW9kZWwgZG9lcyBub3Qgc3VwcG9ydCB0aGUgVVJMIGZvciB0aGUgZ2l2ZW4gbWVkaWEgdHlwZS5cbiAgICAgICAqL1xuICAgICAgZXhwZXJpbWVudGFsX2Rvd25sb2FkPzogRG93bmxvYWRGdW5jdGlvbiB8IHVuZGVmaW5lZDtcblxuICAgICAgLyoqXG5BZGRpdGlvbmFsIHByb3ZpZGVyLXNwZWNpZmljIG9wdGlvbnMuIFRoZXkgYXJlIHBhc3NlZCB0aHJvdWdoXG50byB0aGUgcHJvdmlkZXIgZnJvbSB0aGUgQUkgU0RLIGFuZCBlbmFibGUgcHJvdmlkZXItc3BlY2lmaWNcbmZ1bmN0aW9uYWxpdHkgdGhhdCBjYW4gYmUgZnVsbHkgZW5jYXBzdWxhdGVkIGluIHRoZSBwcm92aWRlci5cbiAqL1xuICAgICAgcHJvdmlkZXJPcHRpb25zPzogUHJvdmlkZXJPcHRpb25zO1xuXG4gICAgICAvKipcbkNhbGxiYWNrIHRoYXQgaXMgaW52b2tlZCB3aGVuIGFuIGVycm9yIG9jY3VycyBkdXJpbmcgc3RyZWFtaW5nLlxuWW91IGNhbiB1c2UgaXQgdG8gbG9nIGVycm9ycy5cblRoZSBzdHJlYW0gcHJvY2Vzc2luZyB3aWxsIHBhdXNlIHVudGlsIHRoZSBjYWxsYmFjayBwcm9taXNlIGlzIHJlc29sdmVkLlxuICAgICAqL1xuICAgICAgb25FcnJvcj86IFN0cmVhbU9iamVjdE9uRXJyb3JDYWxsYmFjaztcblxuICAgICAgLyoqXG5DYWxsYmFjayB0aGF0IGlzIGNhbGxlZCB3aGVuIHRoZSBMTE0gcmVzcG9uc2UgYW5kIHRoZSBmaW5hbCBvYmplY3QgdmFsaWRhdGlvbiBhcmUgZmluaXNoZWQuXG4qL1xuICAgICAgb25GaW5pc2g/OiBTdHJlYW1PYmplY3RPbkZpbmlzaENhbGxiYWNrPFJFU1VMVD47XG5cbiAgICAgIC8qKlxuICAgICAgICogSW50ZXJuYWwuIEZvciB0ZXN0IHVzZSBvbmx5LiBNYXkgY2hhbmdlIHdpdGhvdXQgbm90aWNlLlxuICAgICAgICovXG4gICAgICBfaW50ZXJuYWw/OiB7XG4gICAgICAgIGdlbmVyYXRlSWQ/OiAoKSA9PiBzdHJpbmc7XG4gICAgICAgIGN1cnJlbnREYXRlPzogKCkgPT4gRGF0ZTtcbiAgICAgICAgbm93PzogKCkgPT4gbnVtYmVyO1xuICAgICAgfTtcbiAgICB9LFxuKTogU3RyZWFtT2JqZWN0UmVzdWx0PFxuICBPVVRQVVQgZXh0ZW5kcyAnZW51bSdcbiAgICA/IHN0cmluZ1xuICAgIDogT1VUUFVUIGV4dGVuZHMgJ2FycmF5J1xuICAgICAgPyBSRVNVTFRcbiAgICAgIDogRGVlcFBhcnRpYWw8UkVTVUxUPixcbiAgT1VUUFVUIGV4dGVuZHMgJ2FycmF5JyA/IFJFU1VMVCA6IFJFU1VMVCxcbiAgT1VUUFVUIGV4dGVuZHMgJ2FycmF5J1xuICAgID8gUkVTVUxUIGV4dGVuZHMgQXJyYXk8aW5mZXIgVT5cbiAgICAgID8gQXN5bmNJdGVyYWJsZVN0cmVhbTxVPlxuICAgICAgOiBuZXZlclxuICAgIDogbmV2ZXJcbj4ge1xuICBjb25zdCB7XG4gICAgbW9kZWwsXG4gICAgb3V0cHV0ID0gJ29iamVjdCcsXG4gICAgc3lzdGVtLFxuICAgIHByb21wdCxcbiAgICBtZXNzYWdlcyxcbiAgICBtYXhSZXRyaWVzLFxuICAgIGFib3J0U2lnbmFsLFxuICAgIGhlYWRlcnMsXG4gICAgZXhwZXJpbWVudGFsX3JlcGFpclRleHQ6IHJlcGFpclRleHQsXG4gICAgZXhwZXJpbWVudGFsX3RlbGVtZXRyeTogdGVsZW1ldHJ5LFxuICAgIGV4cGVyaW1lbnRhbF9kb3dubG9hZDogZG93bmxvYWQsXG4gICAgcHJvdmlkZXJPcHRpb25zLFxuICAgIG9uRXJyb3IgPSAoeyBlcnJvciB9OiB7IGVycm9yOiB1bmtub3duIH0pID0+IHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgIH0sXG4gICAgb25GaW5pc2gsXG4gICAgX2ludGVybmFsOiB7XG4gICAgICBnZW5lcmF0ZUlkID0gb3JpZ2luYWxHZW5lcmF0ZUlkLFxuICAgICAgY3VycmVudERhdGUgPSAoKSA9PiBuZXcgRGF0ZSgpLFxuICAgICAgbm93ID0gb3JpZ2luYWxOb3csXG4gICAgfSA9IHt9LFxuICAgIC4uLnNldHRpbmdzXG4gIH0gPSBvcHRpb25zO1xuXG4gIGNvbnN0IGVudW1WYWx1ZXMgPVxuICAgICdlbnVtJyBpbiBvcHRpb25zICYmIG9wdGlvbnMuZW51bSA/IG9wdGlvbnMuZW51bSA6IHVuZGVmaW5lZDtcblxuICBjb25zdCB7XG4gICAgc2NoZW1hOiBpbnB1dFNjaGVtYSxcbiAgICBzY2hlbWFEZXNjcmlwdGlvbixcbiAgICBzY2hlbWFOYW1lLFxuICB9ID0gJ3NjaGVtYScgaW4gb3B0aW9ucyA/IG9wdGlvbnMgOiB7fTtcblxuICB2YWxpZGF0ZU9iamVjdEdlbmVyYXRpb25JbnB1dCh7XG4gICAgb3V0cHV0LFxuICAgIHNjaGVtYTogaW5wdXRTY2hlbWEsXG4gICAgc2NoZW1hTmFtZSxcbiAgICBzY2hlbWFEZXNjcmlwdGlvbixcbiAgICBlbnVtVmFsdWVzLFxuICB9KTtcblxuICBjb25zdCBvdXRwdXRTdHJhdGVneSA9IGdldE91dHB1dFN0cmF0ZWd5KHtcbiAgICBvdXRwdXQsXG4gICAgc2NoZW1hOiBpbnB1dFNjaGVtYSxcbiAgICBlbnVtVmFsdWVzLFxuICB9KTtcblxuICByZXR1cm4gbmV3IERlZmF1bHRTdHJlYW1PYmplY3RSZXN1bHQoe1xuICAgIG1vZGVsLFxuICAgIHRlbGVtZXRyeSxcbiAgICBoZWFkZXJzLFxuICAgIHNldHRpbmdzLFxuICAgIG1heFJldHJpZXMsXG4gICAgYWJvcnRTaWduYWwsXG4gICAgb3V0cHV0U3RyYXRlZ3ksXG4gICAgc3lzdGVtLFxuICAgIHByb21wdCxcbiAgICBtZXNzYWdlcyxcbiAgICBzY2hlbWFOYW1lLFxuICAgIHNjaGVtYURlc2NyaXB0aW9uLFxuICAgIHByb3ZpZGVyT3B0aW9ucyxcbiAgICByZXBhaXJUZXh0LFxuICAgIG9uRXJyb3IsXG4gICAgb25GaW5pc2gsXG4gICAgZG93bmxvYWQsXG4gICAgZ2VuZXJhdGVJZCxcbiAgICBjdXJyZW50RGF0ZSxcbiAgICBub3csXG4gIH0pO1xufVxuXG5jbGFzcyBEZWZhdWx0U3RyZWFtT2JqZWN0UmVzdWx0PFBBUlRJQUwsIFJFU1VMVCwgRUxFTUVOVF9TVFJFQU0+XG4gIGltcGxlbWVudHMgU3RyZWFtT2JqZWN0UmVzdWx0PFBBUlRJQUwsIFJFU1VMVCwgRUxFTUVOVF9TVFJFQU0+XG57XG4gIHByaXZhdGUgcmVhZG9ubHkgX29iamVjdCA9IG5ldyBEZWxheWVkUHJvbWlzZTxSRVNVTFQ+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX3VzYWdlID0gbmV3IERlbGF5ZWRQcm9taXNlPExhbmd1YWdlTW9kZWxVc2FnZT4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfcHJvdmlkZXJNZXRhZGF0YSA9IG5ldyBEZWxheWVkUHJvbWlzZTxcbiAgICBQcm92aWRlck1ldGFkYXRhIHwgdW5kZWZpbmVkXG4gID4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfd2FybmluZ3MgPSBuZXcgRGVsYXllZFByb21pc2U8Q2FsbFdhcm5pbmdbXSB8IHVuZGVmaW5lZD4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfcmVxdWVzdCA9XG4gICAgbmV3IERlbGF5ZWRQcm9taXNlPExhbmd1YWdlTW9kZWxSZXF1ZXN0TWV0YWRhdGE+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX3Jlc3BvbnNlID1cbiAgICBuZXcgRGVsYXllZFByb21pc2U8TGFuZ3VhZ2VNb2RlbFJlc3BvbnNlTWV0YWRhdGE+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2ZpbmlzaFJlYXNvbiA9IG5ldyBEZWxheWVkUHJvbWlzZTxGaW5pc2hSZWFzb24+KCk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBiYXNlU3RyZWFtOiBSZWFkYWJsZVN0cmVhbTxPYmplY3RTdHJlYW1QYXJ0PFBBUlRJQUw+PjtcblxuICBwcml2YXRlIHJlYWRvbmx5IG91dHB1dFN0cmF0ZWd5OiBPdXRwdXRTdHJhdGVneTxcbiAgICBQQVJUSUFMLFxuICAgIFJFU1VMVCxcbiAgICBFTEVNRU5UX1NUUkVBTVxuICA+O1xuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICBtb2RlbDogbW9kZWxBcmcsXG4gICAgaGVhZGVycyxcbiAgICB0ZWxlbWV0cnksXG4gICAgc2V0dGluZ3MsXG4gICAgbWF4UmV0cmllczogbWF4UmV0cmllc0FyZyxcbiAgICBhYm9ydFNpZ25hbCxcbiAgICBvdXRwdXRTdHJhdGVneSxcbiAgICBzeXN0ZW0sXG4gICAgcHJvbXB0LFxuICAgIG1lc3NhZ2VzLFxuICAgIHNjaGVtYU5hbWUsXG4gICAgc2NoZW1hRGVzY3JpcHRpb24sXG4gICAgcHJvdmlkZXJPcHRpb25zLFxuICAgIHJlcGFpclRleHQsXG4gICAgb25FcnJvcixcbiAgICBvbkZpbmlzaCxcbiAgICBkb3dubG9hZCxcbiAgICBnZW5lcmF0ZUlkLFxuICAgIGN1cnJlbnREYXRlLFxuICAgIG5vdyxcbiAgfToge1xuICAgIG1vZGVsOiBMYW5ndWFnZU1vZGVsO1xuICAgIHRlbGVtZXRyeTogVGVsZW1ldHJ5U2V0dGluZ3MgfCB1bmRlZmluZWQ7XG4gICAgaGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPiB8IHVuZGVmaW5lZDtcbiAgICBzZXR0aW5nczogT21pdDxDYWxsU2V0dGluZ3MsICdhYm9ydFNpZ25hbCcgfCAnaGVhZGVycyc+O1xuICAgIG1heFJldHJpZXM6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgICBhYm9ydFNpZ25hbDogQWJvcnRTaWduYWwgfCB1bmRlZmluZWQ7XG4gICAgb3V0cHV0U3RyYXRlZ3k6IE91dHB1dFN0cmF0ZWd5PFBBUlRJQUwsIFJFU1VMVCwgRUxFTUVOVF9TVFJFQU0+O1xuICAgIHN5c3RlbTogUHJvbXB0WydzeXN0ZW0nXTtcbiAgICBwcm9tcHQ6IFByb21wdFsncHJvbXB0J107XG4gICAgbWVzc2FnZXM6IFByb21wdFsnbWVzc2FnZXMnXTtcbiAgICBzY2hlbWFOYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgc2NoZW1hRGVzY3JpcHRpb246IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICBwcm92aWRlck9wdGlvbnM6IFByb3ZpZGVyT3B0aW9ucyB8IHVuZGVmaW5lZDtcbiAgICByZXBhaXJUZXh0OiBSZXBhaXJUZXh0RnVuY3Rpb24gfCB1bmRlZmluZWQ7XG4gICAgb25FcnJvcjogU3RyZWFtT2JqZWN0T25FcnJvckNhbGxiYWNrO1xuICAgIG9uRmluaXNoOiBTdHJlYW1PYmplY3RPbkZpbmlzaENhbGxiYWNrPFJFU1VMVD4gfCB1bmRlZmluZWQ7XG4gICAgZG93bmxvYWQ6IERvd25sb2FkRnVuY3Rpb24gfCB1bmRlZmluZWQ7XG4gICAgZ2VuZXJhdGVJZDogKCkgPT4gc3RyaW5nO1xuICAgIGN1cnJlbnREYXRlOiAoKSA9PiBEYXRlO1xuICAgIG5vdzogKCkgPT4gbnVtYmVyO1xuICB9KSB7XG4gICAgY29uc3QgbW9kZWwgPSByZXNvbHZlTGFuZ3VhZ2VNb2RlbChtb2RlbEFyZyk7XG5cbiAgICBjb25zdCB7IG1heFJldHJpZXMsIHJldHJ5IH0gPSBwcmVwYXJlUmV0cmllcyh7XG4gICAgICBtYXhSZXRyaWVzOiBtYXhSZXRyaWVzQXJnLFxuICAgICAgYWJvcnRTaWduYWwsXG4gICAgfSk7XG5cbiAgICBjb25zdCBjYWxsU2V0dGluZ3MgPSBwcmVwYXJlQ2FsbFNldHRpbmdzKHNldHRpbmdzKTtcblxuICAgIGNvbnN0IGJhc2VUZWxlbWV0cnlBdHRyaWJ1dGVzID0gZ2V0QmFzZVRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgbW9kZWwsXG4gICAgICB0ZWxlbWV0cnksXG4gICAgICBoZWFkZXJzLFxuICAgICAgc2V0dGluZ3M6IHsgLi4uY2FsbFNldHRpbmdzLCBtYXhSZXRyaWVzIH0sXG4gICAgfSk7XG5cbiAgICBjb25zdCB0cmFjZXIgPSBnZXRUcmFjZXIodGVsZW1ldHJ5KTtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIGNvbnN0IHN0aXRjaGFibGVTdHJlYW0gPVxuICAgICAgY3JlYXRlU3RpdGNoYWJsZVN0cmVhbTxPYmplY3RTdHJlYW1QYXJ0PFBBUlRJQUw+PigpO1xuXG4gICAgY29uc3QgZXZlbnRQcm9jZXNzb3IgPSBuZXcgVHJhbnNmb3JtU3RyZWFtPFxuICAgICAgT2JqZWN0U3RyZWFtUGFydDxQQVJUSUFMPixcbiAgICAgIE9iamVjdFN0cmVhbVBhcnQ8UEFSVElBTD5cbiAgICA+KHtcbiAgICAgIHRyYW5zZm9ybShjaHVuaywgY29udHJvbGxlcikge1xuICAgICAgICBjb250cm9sbGVyLmVucXVldWUoY2h1bmspO1xuXG4gICAgICAgIGlmIChjaHVuay50eXBlID09PSAnZXJyb3InKSB7XG4gICAgICAgICAgb25FcnJvcih7IGVycm9yOiB3cmFwR2F0ZXdheUVycm9yKGNodW5rLmVycm9yKSB9KTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIHRoaXMuYmFzZVN0cmVhbSA9IHN0aXRjaGFibGVTdHJlYW0uc3RyZWFtLnBpcGVUaHJvdWdoKGV2ZW50UHJvY2Vzc29yKTtcblxuICAgIHJlY29yZFNwYW4oe1xuICAgICAgbmFtZTogJ2FpLnN0cmVhbU9iamVjdCcsXG4gICAgICBhdHRyaWJ1dGVzOiBzZWxlY3RUZWxlbWV0cnlBdHRyaWJ1dGVzKHtcbiAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgLi4uYXNzZW1ibGVPcGVyYXRpb25OYW1lKHtcbiAgICAgICAgICAgIG9wZXJhdGlvbklkOiAnYWkuc3RyZWFtT2JqZWN0JyxcbiAgICAgICAgICAgIHRlbGVtZXRyeSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICAuLi5iYXNlVGVsZW1ldHJ5QXR0cmlidXRlcyxcbiAgICAgICAgICAvLyBzcGVjaWZpYyBzZXR0aW5ncyB0aGF0IG9ubHkgbWFrZSBzZW5zZSBvbiB0aGUgb3V0ZXIgbGV2ZWw6XG4gICAgICAgICAgJ2FpLnByb21wdCc6IHtcbiAgICAgICAgICAgIGlucHV0OiAoKSA9PiBKU09OLnN0cmluZ2lmeSh7IHN5c3RlbSwgcHJvbXB0LCBtZXNzYWdlcyB9KSxcbiAgICAgICAgICB9LFxuICAgICAgICAgICdhaS5zY2hlbWEnOlxuICAgICAgICAgICAgb3V0cHV0U3RyYXRlZ3kuanNvblNjaGVtYSAhPSBudWxsXG4gICAgICAgICAgICAgID8geyBpbnB1dDogKCkgPT4gSlNPTi5zdHJpbmdpZnkob3V0cHV0U3RyYXRlZ3kuanNvblNjaGVtYSkgfVxuICAgICAgICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAnYWkuc2NoZW1hLm5hbWUnOiBzY2hlbWFOYW1lLFxuICAgICAgICAgICdhaS5zY2hlbWEuZGVzY3JpcHRpb24nOiBzY2hlbWFEZXNjcmlwdGlvbixcbiAgICAgICAgICAnYWkuc2V0dGluZ3Mub3V0cHV0Jzogb3V0cHV0U3RyYXRlZ3kudHlwZSxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgICAgdHJhY2VyLFxuICAgICAgZW5kV2hlbkRvbmU6IGZhbHNlLFxuICAgICAgZm46IGFzeW5jIHJvb3RTcGFuID0+IHtcbiAgICAgICAgY29uc3Qgc3RhbmRhcmRpemVkUHJvbXB0ID0gYXdhaXQgc3RhbmRhcmRpemVQcm9tcHQoe1xuICAgICAgICAgIHN5c3RlbSxcbiAgICAgICAgICBwcm9tcHQsXG4gICAgICAgICAgbWVzc2FnZXMsXG4gICAgICAgIH0gYXMgUHJvbXB0KTtcblxuICAgICAgICBjb25zdCBjYWxsT3B0aW9ucyA9IHtcbiAgICAgICAgICByZXNwb25zZUZvcm1hdDoge1xuICAgICAgICAgICAgdHlwZTogJ2pzb24nIGFzIGNvbnN0LFxuICAgICAgICAgICAgc2NoZW1hOiBvdXRwdXRTdHJhdGVneS5qc29uU2NoZW1hLFxuICAgICAgICAgICAgbmFtZTogc2NoZW1hTmFtZSxcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBzY2hlbWFEZXNjcmlwdGlvbixcbiAgICAgICAgICB9LFxuICAgICAgICAgIC4uLnByZXBhcmVDYWxsU2V0dGluZ3Moc2V0dGluZ3MpLFxuICAgICAgICAgIHByb21wdDogYXdhaXQgY29udmVydFRvTGFuZ3VhZ2VNb2RlbFByb21wdCh7XG4gICAgICAgICAgICBwcm9tcHQ6IHN0YW5kYXJkaXplZFByb21wdCxcbiAgICAgICAgICAgIHN1cHBvcnRlZFVybHM6IGF3YWl0IG1vZGVsLnN1cHBvcnRlZFVybHMsXG4gICAgICAgICAgICBkb3dubG9hZCxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBwcm92aWRlck9wdGlvbnMsXG4gICAgICAgICAgYWJvcnRTaWduYWwsXG4gICAgICAgICAgaGVhZGVycyxcbiAgICAgICAgICBpbmNsdWRlUmF3Q2h1bmtzOiBmYWxzZSxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCB0cmFuc2Zvcm1lcjogVHJhbnNmb3JtZXI8XG4gICAgICAgICAgTGFuZ3VhZ2VNb2RlbFYyU3RyZWFtUGFydCxcbiAgICAgICAgICBPYmplY3RTdHJlYW1JbnB1dFBhcnRcbiAgICAgICAgPiA9IHtcbiAgICAgICAgICB0cmFuc2Zvcm06IChjaHVuaywgY29udHJvbGxlcikgPT4ge1xuICAgICAgICAgICAgc3dpdGNoIChjaHVuay50eXBlKSB7XG4gICAgICAgICAgICAgIGNhc2UgJ3RleHQtZGVsdGEnOlxuICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShjaHVuay5kZWx0YSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgJ3Jlc3BvbnNlLW1ldGFkYXRhJzpcbiAgICAgICAgICAgICAgY2FzZSAnZmluaXNoJzpcbiAgICAgICAgICAgICAgY2FzZSAnZXJyb3InOlxuICAgICAgICAgICAgICBjYXNlICdzdHJlYW0tc3RhcnQnOlxuICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShjaHVuayk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCB7XG4gICAgICAgICAgcmVzdWx0OiB7IHN0cmVhbSwgcmVzcG9uc2UsIHJlcXVlc3QgfSxcbiAgICAgICAgICBkb1N0cmVhbVNwYW4sXG4gICAgICAgICAgc3RhcnRUaW1lc3RhbXBNcyxcbiAgICAgICAgfSA9IGF3YWl0IHJldHJ5KCgpID0+XG4gICAgICAgICAgcmVjb3JkU3Bhbih7XG4gICAgICAgICAgICBuYW1lOiAnYWkuc3RyZWFtT2JqZWN0LmRvU3RyZWFtJyxcbiAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgICB0ZWxlbWV0cnksXG4gICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgICAgICAgICAuLi5hc3NlbWJsZU9wZXJhdGlvbk5hbWUoe1xuICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uSWQ6ICdhaS5zdHJlYW1PYmplY3QuZG9TdHJlYW0nLFxuICAgICAgICAgICAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIC4uLmJhc2VUZWxlbWV0cnlBdHRyaWJ1dGVzLFxuICAgICAgICAgICAgICAgICdhaS5wcm9tcHQubWVzc2FnZXMnOiB7XG4gICAgICAgICAgICAgICAgICBpbnB1dDogKCkgPT4gc3RyaW5naWZ5Rm9yVGVsZW1ldHJ5KGNhbGxPcHRpb25zLnByb21wdCksXG4gICAgICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgICAgIC8vIHN0YW5kYXJkaXplZCBnZW4tYWkgbGxtIHNwYW4gYXR0cmlidXRlczpcbiAgICAgICAgICAgICAgICAnZ2VuX2FpLnN5c3RlbSc6IG1vZGVsLnByb3ZpZGVyLFxuICAgICAgICAgICAgICAgICdnZW5fYWkucmVxdWVzdC5tb2RlbCc6IG1vZGVsLm1vZGVsSWQsXG4gICAgICAgICAgICAgICAgJ2dlbl9haS5yZXF1ZXN0LmZyZXF1ZW5jeV9wZW5hbHR5JzpcbiAgICAgICAgICAgICAgICAgIGNhbGxTZXR0aW5ncy5mcmVxdWVuY3lQZW5hbHR5LFxuICAgICAgICAgICAgICAgICdnZW5fYWkucmVxdWVzdC5tYXhfdG9rZW5zJzogY2FsbFNldHRpbmdzLm1heE91dHB1dFRva2VucyxcbiAgICAgICAgICAgICAgICAnZ2VuX2FpLnJlcXVlc3QucHJlc2VuY2VfcGVuYWx0eSc6IGNhbGxTZXR0aW5ncy5wcmVzZW5jZVBlbmFsdHksXG4gICAgICAgICAgICAgICAgJ2dlbl9haS5yZXF1ZXN0LnRlbXBlcmF0dXJlJzogY2FsbFNldHRpbmdzLnRlbXBlcmF0dXJlLFxuICAgICAgICAgICAgICAgICdnZW5fYWkucmVxdWVzdC50b3Bfayc6IGNhbGxTZXR0aW5ncy50b3BLLFxuICAgICAgICAgICAgICAgICdnZW5fYWkucmVxdWVzdC50b3BfcCc6IGNhbGxTZXR0aW5ncy50b3BQLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB0cmFjZXIsXG4gICAgICAgICAgICBlbmRXaGVuRG9uZTogZmFsc2UsXG4gICAgICAgICAgICBmbjogYXN5bmMgZG9TdHJlYW1TcGFuID0+ICh7XG4gICAgICAgICAgICAgIHN0YXJ0VGltZXN0YW1wTXM6IG5vdygpLFxuICAgICAgICAgICAgICBkb1N0cmVhbVNwYW4sXG4gICAgICAgICAgICAgIHJlc3VsdDogYXdhaXQgbW9kZWwuZG9TdHJlYW0oY2FsbE9wdGlvbnMpLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG5cbiAgICAgICAgc2VsZi5fcmVxdWVzdC5yZXNvbHZlKHJlcXVlc3QgPz8ge30pO1xuXG4gICAgICAgIC8vIHN0b3JlIGluZm9ybWF0aW9uIGZvciBvbkZpbmlzaCBjYWxsYmFjazpcbiAgICAgICAgbGV0IHdhcm5pbmdzOiBMYW5ndWFnZU1vZGVsVjJDYWxsV2FybmluZ1tdIHwgdW5kZWZpbmVkO1xuICAgICAgICBsZXQgdXNhZ2U6IExhbmd1YWdlTW9kZWxVc2FnZSA9IHtcbiAgICAgICAgICBpbnB1dFRva2VuczogdW5kZWZpbmVkLFxuICAgICAgICAgIG91dHB1dFRva2VuczogdW5kZWZpbmVkLFxuICAgICAgICAgIHRvdGFsVG9rZW5zOiB1bmRlZmluZWQsXG4gICAgICAgIH07XG4gICAgICAgIGxldCBmaW5pc2hSZWFzb246IExhbmd1YWdlTW9kZWxWMkZpbmlzaFJlYXNvbiB8IHVuZGVmaW5lZDtcbiAgICAgICAgbGV0IHByb3ZpZGVyTWV0YWRhdGE6IFByb3ZpZGVyTWV0YWRhdGEgfCB1bmRlZmluZWQ7XG4gICAgICAgIGxldCBvYmplY3Q6IFJFU1VMVCB8IHVuZGVmaW5lZDtcbiAgICAgICAgbGV0IGVycm9yOiB1bmtub3duIHwgdW5kZWZpbmVkO1xuXG4gICAgICAgIC8vIHBpcGUgY2h1bmtzIHRocm91Z2ggYSB0cmFuc2Zvcm1hdGlvbiBzdHJlYW0gdGhhdCBleHRyYWN0cyBtZXRhZGF0YTpcbiAgICAgICAgbGV0IGFjY3VtdWxhdGVkVGV4dCA9ICcnO1xuICAgICAgICBsZXQgdGV4dERlbHRhID0gJyc7XG4gICAgICAgIGxldCBmdWxsUmVzcG9uc2U6IHtcbiAgICAgICAgICBpZDogc3RyaW5nO1xuICAgICAgICAgIHRpbWVzdGFtcDogRGF0ZTtcbiAgICAgICAgICBtb2RlbElkOiBzdHJpbmc7XG4gICAgICAgIH0gPSB7XG4gICAgICAgICAgaWQ6IGdlbmVyYXRlSWQoKSxcbiAgICAgICAgICB0aW1lc3RhbXA6IGN1cnJlbnREYXRlKCksXG4gICAgICAgICAgbW9kZWxJZDogbW9kZWwubW9kZWxJZCxcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBLZWVwIHRyYWNrIG9mIHJhdyBwYXJzZSByZXN1bHQgYmVmb3JlIHR5cGUgdmFsaWRhdGlvbiwgc2luY2UgZS5nLiBab2QgbWlnaHRcbiAgICAgICAgLy8gY2hhbmdlIHRoZSBvYmplY3QgYnkgbWFwcGluZyBwcm9wZXJ0aWVzLlxuICAgICAgICBsZXQgbGF0ZXN0T2JqZWN0SnNvbjogSlNPTlZhbHVlIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgICAgICBsZXQgbGF0ZXN0T2JqZWN0OiBQQVJUSUFMIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgICAgICBsZXQgaXNGaXJzdENodW5rID0gdHJ1ZTtcbiAgICAgICAgbGV0IGlzRmlyc3REZWx0YSA9IHRydWU7XG5cbiAgICAgICAgY29uc3QgdHJhbnNmb3JtZWRTdHJlYW0gPSBzdHJlYW1cbiAgICAgICAgICAucGlwZVRocm91Z2gobmV3IFRyYW5zZm9ybVN0cmVhbSh0cmFuc2Zvcm1lcikpXG4gICAgICAgICAgLnBpcGVUaHJvdWdoKFxuICAgICAgICAgICAgbmV3IFRyYW5zZm9ybVN0cmVhbTxcbiAgICAgICAgICAgICAgc3RyaW5nIHwgT2JqZWN0U3RyZWFtSW5wdXRQYXJ0LFxuICAgICAgICAgICAgICBPYmplY3RTdHJlYW1QYXJ0PFBBUlRJQUw+XG4gICAgICAgICAgICA+KHtcbiAgICAgICAgICAgICAgYXN5bmMgdHJhbnNmb3JtKGNodW5rLCBjb250cm9sbGVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgdHlwZW9mIGNodW5rID09PSAnb2JqZWN0JyAmJlxuICAgICAgICAgICAgICAgICAgY2h1bmsudHlwZSA9PT0gJ3N0cmVhbS1zdGFydCdcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgIHdhcm5pbmdzID0gY2h1bmsud2FybmluZ3M7XG4gICAgICAgICAgICAgICAgICByZXR1cm47IC8vIHN0cmVhbSBzdGFydCBjaHVua3MgYXJlIHNlbnQgaW1tZWRpYXRlbHkgYW5kIGRvIG5vdCBjb3VudCBhcyBmaXJzdCBjaHVua1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIFRlbGVtZXRyeSBldmVudCBmb3IgZmlyc3QgY2h1bms6XG4gICAgICAgICAgICAgICAgaWYgKGlzRmlyc3RDaHVuaykge1xuICAgICAgICAgICAgICAgICAgY29uc3QgbXNUb0ZpcnN0Q2h1bmsgPSBub3coKSAtIHN0YXJ0VGltZXN0YW1wTXM7XG5cbiAgICAgICAgICAgICAgICAgIGlzRmlyc3RDaHVuayA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgICBkb1N0cmVhbVNwYW4uYWRkRXZlbnQoJ2FpLnN0cmVhbS5maXJzdENodW5rJywge1xuICAgICAgICAgICAgICAgICAgICAnYWkuc3RyZWFtLm1zVG9GaXJzdENodW5rJzogbXNUb0ZpcnN0Q2h1bmssXG4gICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgZG9TdHJlYW1TcGFuLnNldEF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgICAgICAgICAnYWkuc3RyZWFtLm1zVG9GaXJzdENodW5rJzogbXNUb0ZpcnN0Q2h1bmssXG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBwcm9jZXNzIHBhcnRpYWwgdGV4dCBjaHVua3NcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGNodW5rID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgICAgYWNjdW11bGF0ZWRUZXh0ICs9IGNodW5rO1xuICAgICAgICAgICAgICAgICAgdGV4dERlbHRhICs9IGNodW5rO1xuXG4gICAgICAgICAgICAgICAgICBjb25zdCB7IHZhbHVlOiBjdXJyZW50T2JqZWN0SnNvbiwgc3RhdGU6IHBhcnNlU3RhdGUgfSA9XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHBhcnNlUGFydGlhbEpzb24oYWNjdW11bGF0ZWRUZXh0KTtcblxuICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICBjdXJyZW50T2JqZWN0SnNvbiAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAgICAgICAgICAgICAgICFpc0RlZXBFcXVhbERhdGEobGF0ZXN0T2JqZWN0SnNvbiwgY3VycmVudE9iamVjdEpzb24pXG4gICAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsaWRhdGlvblJlc3VsdCA9XG4gICAgICAgICAgICAgICAgICAgICAgYXdhaXQgb3V0cHV0U3RyYXRlZ3kudmFsaWRhdGVQYXJ0aWFsUmVzdWx0KHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiBjdXJyZW50T2JqZWN0SnNvbixcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHREZWx0YSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGxhdGVzdE9iamVjdCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzRmlyc3REZWx0YSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzRmluYWxEZWx0YTogcGFyc2VTdGF0ZSA9PT0gJ3N1Y2Nlc3NmdWwtcGFyc2UnLFxuICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uUmVzdWx0LnN1Y2Nlc3MgJiZcbiAgICAgICAgICAgICAgICAgICAgICAhaXNEZWVwRXF1YWxEYXRhKFxuICAgICAgICAgICAgICAgICAgICAgICAgbGF0ZXN0T2JqZWN0LFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGlvblJlc3VsdC52YWx1ZS5wYXJ0aWFsLFxuICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgLy8gaW5zaWRlIGlubmVyIGNoZWNrIHRvIGNvcnJlY3RseSBwYXJzZSB0aGUgZmluYWwgZWxlbWVudCBpbiBhcnJheSBtb2RlOlxuICAgICAgICAgICAgICAgICAgICAgIGxhdGVzdE9iamVjdEpzb24gPSBjdXJyZW50T2JqZWN0SnNvbjtcbiAgICAgICAgICAgICAgICAgICAgICBsYXRlc3RPYmplY3QgPSB2YWxpZGF0aW9uUmVzdWx0LnZhbHVlLnBhcnRpYWw7XG5cbiAgICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICBvYmplY3Q6IGxhdGVzdE9iamVjdCxcbiAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAndGV4dC1kZWx0YScsXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0RGVsdGE6IHZhbGlkYXRpb25SZXN1bHQudmFsdWUudGV4dERlbHRhLFxuICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgdGV4dERlbHRhID0gJyc7XG4gICAgICAgICAgICAgICAgICAgICAgaXNGaXJzdERlbHRhID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHN3aXRjaCAoY2h1bmsudHlwZSkge1xuICAgICAgICAgICAgICAgICAgY2FzZSAncmVzcG9uc2UtbWV0YWRhdGEnOiB7XG4gICAgICAgICAgICAgICAgICAgIGZ1bGxSZXNwb25zZSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICBpZDogY2h1bmsuaWQgPz8gZnVsbFJlc3BvbnNlLmlkLFxuICAgICAgICAgICAgICAgICAgICAgIHRpbWVzdGFtcDogY2h1bmsudGltZXN0YW1wID8/IGZ1bGxSZXNwb25zZS50aW1lc3RhbXAsXG4gICAgICAgICAgICAgICAgICAgICAgbW9kZWxJZDogY2h1bmsubW9kZWxJZCA/PyBmdWxsUmVzcG9uc2UubW9kZWxJZCxcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgIGNhc2UgJ2ZpbmlzaCc6IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gc2VuZCBmaW5hbCB0ZXh0IGRlbHRhOlxuICAgICAgICAgICAgICAgICAgICBpZiAodGV4dERlbHRhICE9PSAnJykge1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7IHR5cGU6ICd0ZXh0LWRlbHRhJywgdGV4dERlbHRhIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gc3RvcmUgZmluaXNoIHJlYXNvbiBmb3IgdGVsZW1ldHJ5OlxuICAgICAgICAgICAgICAgICAgICBmaW5pc2hSZWFzb24gPSBjaHVuay5maW5pc2hSZWFzb247XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gc3RvcmUgdXNhZ2UgYW5kIG1ldGFkYXRhIGZvciBwcm9taXNlcyBhbmQgb25GaW5pc2ggY2FsbGJhY2s6XG4gICAgICAgICAgICAgICAgICAgIHVzYWdlID0gY2h1bmsudXNhZ2U7XG4gICAgICAgICAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGEgPSBjaHVuay5wcm92aWRlck1ldGFkYXRhO1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgLi4uY2h1bmssXG4gICAgICAgICAgICAgICAgICAgICAgdXNhZ2UsXG4gICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2U6IGZ1bGxSZXNwb25zZSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gbG9nIHdhcm5pbmdzOlxuICAgICAgICAgICAgICAgICAgICBsb2dXYXJuaW5ncyh3YXJuaW5ncyA/PyBbXSk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gcmVzb2x2ZSBwcm9taXNlcyB0aGF0IGNhbiBiZSByZXNvbHZlZCBub3c6XG4gICAgICAgICAgICAgICAgICAgIHNlbGYuX3VzYWdlLnJlc29sdmUodXNhZ2UpO1xuICAgICAgICAgICAgICAgICAgICBzZWxmLl9wcm92aWRlck1ldGFkYXRhLnJlc29sdmUocHJvdmlkZXJNZXRhZGF0YSk7XG4gICAgICAgICAgICAgICAgICAgIHNlbGYuX3dhcm5pbmdzLnJlc29sdmUod2FybmluZ3MpO1xuICAgICAgICAgICAgICAgICAgICBzZWxmLl9yZXNwb25zZS5yZXNvbHZlKHtcbiAgICAgICAgICAgICAgICAgICAgICAuLi5mdWxsUmVzcG9uc2UsXG4gICAgICAgICAgICAgICAgICAgICAgaGVhZGVyczogcmVzcG9uc2U/LmhlYWRlcnMsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzZWxmLl9maW5pc2hSZWFzb24ucmVzb2x2ZShmaW5pc2hSZWFzb24gPz8gJ3Vua25vd24nKTtcblxuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgIG9iamVjdCA9IGF3YWl0IHBhcnNlQW5kVmFsaWRhdGVPYmplY3RSZXN1bHRXaXRoUmVwYWlyKFxuICAgICAgICAgICAgICAgICAgICAgICAgYWNjdW11bGF0ZWRUZXh0LFxuICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0U3RyYXRlZ3ksXG4gICAgICAgICAgICAgICAgICAgICAgICByZXBhaXJUZXh0LFxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZTogZnVsbFJlc3BvbnNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICB1c2FnZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZmluaXNoUmVhc29uLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX29iamVjdC5yZXNvbHZlKG9iamVjdCk7XG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9IGU7XG4gICAgICAgICAgICAgICAgICAgICAgc2VsZi5fb2JqZWN0LnJlamVjdChlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoY2h1bmspO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgICAgLy8gaW52b2tlIG9uRmluaXNoIGNhbGxiYWNrIGFuZCByZXNvbHZlIHRvb2xSZXN1bHRzIHByb21pc2Ugd2hlbiB0aGUgc3RyZWFtIGlzIGFib3V0IHRvIGNsb3NlOlxuICAgICAgICAgICAgICBhc3luYyBmbHVzaChjb250cm9sbGVyKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGZpbmFsVXNhZ2UgPSB1c2FnZSA/PyB7XG4gICAgICAgICAgICAgICAgICAgIHByb21wdFRva2VuczogTmFOLFxuICAgICAgICAgICAgICAgICAgICBjb21wbGV0aW9uVG9rZW5zOiBOYU4sXG4gICAgICAgICAgICAgICAgICAgIHRvdGFsVG9rZW5zOiBOYU4sXG4gICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICBkb1N0cmVhbVNwYW4uc2V0QXR0cmlidXRlcyhcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0VGVsZW1ldHJ5QXR0cmlidXRlcyh7XG4gICAgICAgICAgICAgICAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICdhaS5yZXNwb25zZS5maW5pc2hSZWFzb24nOiBmaW5pc2hSZWFzb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAnYWkucmVzcG9uc2Uub2JqZWN0Jzoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQ6ICgpID0+IEpTT04uc3RyaW5naWZ5KG9iamVjdCksXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLmlkJzogZnVsbFJlc3BvbnNlLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLm1vZGVsJzogZnVsbFJlc3BvbnNlLm1vZGVsSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAnYWkucmVzcG9uc2UudGltZXN0YW1wJzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZnVsbFJlc3BvbnNlLnRpbWVzdGFtcC50b0lTT1N0cmluZygpLFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLnByb3ZpZGVyTWV0YWRhdGEnOlxuICAgICAgICAgICAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeShwcm92aWRlck1ldGFkYXRhKSxcblxuICAgICAgICAgICAgICAgICAgICAgICAgJ2FpLnVzYWdlLmlucHV0VG9rZW5zJzogZmluYWxVc2FnZS5pbnB1dFRva2VucyxcbiAgICAgICAgICAgICAgICAgICAgICAgICdhaS51c2FnZS5vdXRwdXRUb2tlbnMnOiBmaW5hbFVzYWdlLm91dHB1dFRva2VucyxcbiAgICAgICAgICAgICAgICAgICAgICAgICdhaS51c2FnZS50b3RhbFRva2Vucyc6IGZpbmFsVXNhZ2UudG90YWxUb2tlbnMsXG4gICAgICAgICAgICAgICAgICAgICAgICAnYWkudXNhZ2UucmVhc29uaW5nVG9rZW5zJzogZmluYWxVc2FnZS5yZWFzb25pbmdUb2tlbnMsXG4gICAgICAgICAgICAgICAgICAgICAgICAnYWkudXNhZ2UuY2FjaGVkSW5wdXRUb2tlbnMnOlxuICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFVzYWdlLmNhY2hlZElucHV0VG9rZW5zLFxuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBzdGFuZGFyZGl6ZWQgZ2VuLWFpIGxsbSBzcGFuIGF0dHJpYnV0ZXM6XG4gICAgICAgICAgICAgICAgICAgICAgICAnZ2VuX2FpLnJlc3BvbnNlLmZpbmlzaF9yZWFzb25zJzogW2ZpbmlzaFJlYXNvbl0sXG4gICAgICAgICAgICAgICAgICAgICAgICAnZ2VuX2FpLnJlc3BvbnNlLmlkJzogZnVsbFJlc3BvbnNlLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2dlbl9haS5yZXNwb25zZS5tb2RlbCc6IGZ1bGxSZXNwb25zZS5tb2RlbElkLFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2dlbl9haS51c2FnZS5pbnB1dF90b2tlbnMnOiBmaW5hbFVzYWdlLmlucHV0VG9rZW5zLFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2dlbl9haS51c2FnZS5vdXRwdXRfdG9rZW5zJzogZmluYWxVc2FnZS5vdXRwdXRUb2tlbnMsXG4gICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgICAvLyBmaW5pc2ggZG9TdHJlYW1TcGFuIGJlZm9yZSBvdGhlciBvcGVyYXRpb25zIGZvciBjb3JyZWN0IHRpbWluZzpcbiAgICAgICAgICAgICAgICAgIGRvU3RyZWFtU3Bhbi5lbmQoKTtcblxuICAgICAgICAgICAgICAgICAgLy8gQWRkIHJlc3BvbnNlIGluZm9ybWF0aW9uIHRvIHRoZSByb290IHNwYW46XG4gICAgICAgICAgICAgICAgICByb290U3Bhbi5zZXRBdHRyaWJ1dGVzKFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RUZWxlbWV0cnlBdHRyaWJ1dGVzKHtcbiAgICAgICAgICAgICAgICAgICAgICB0ZWxlbWV0cnksXG4gICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAgICAgICAgICAgICAgICAgJ2FpLnVzYWdlLmlucHV0VG9rZW5zJzogZmluYWxVc2FnZS5pbnB1dFRva2VucyxcbiAgICAgICAgICAgICAgICAgICAgICAgICdhaS51c2FnZS5vdXRwdXRUb2tlbnMnOiBmaW5hbFVzYWdlLm91dHB1dFRva2VucyxcbiAgICAgICAgICAgICAgICAgICAgICAgICdhaS51c2FnZS50b3RhbFRva2Vucyc6IGZpbmFsVXNhZ2UudG90YWxUb2tlbnMsXG4gICAgICAgICAgICAgICAgICAgICAgICAnYWkudXNhZ2UucmVhc29uaW5nVG9rZW5zJzogZmluYWxVc2FnZS5yZWFzb25pbmdUb2tlbnMsXG4gICAgICAgICAgICAgICAgICAgICAgICAnYWkudXNhZ2UuY2FjaGVkSW5wdXRUb2tlbnMnOlxuICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFVzYWdlLmNhY2hlZElucHV0VG9rZW5zLFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLm9iamVjdCc6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0OiAoKSA9PiBKU09OLnN0cmluZ2lmeShvYmplY3QpLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICdhaS5yZXNwb25zZS5wcm92aWRlck1ldGFkYXRhJzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkocHJvdmlkZXJNZXRhZGF0YSksXG4gICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgICAvLyBjYWxsIG9uRmluaXNoIGNhbGxiYWNrOlxuICAgICAgICAgICAgICAgICAgYXdhaXQgb25GaW5pc2g/Lih7XG4gICAgICAgICAgICAgICAgICAgIHVzYWdlOiBmaW5hbFVzYWdlLFxuICAgICAgICAgICAgICAgICAgICBvYmplY3QsXG4gICAgICAgICAgICAgICAgICAgIGVycm9yLFxuICAgICAgICAgICAgICAgICAgICByZXNwb25zZToge1xuICAgICAgICAgICAgICAgICAgICAgIC4uLmZ1bGxSZXNwb25zZSxcbiAgICAgICAgICAgICAgICAgICAgICBoZWFkZXJzOiByZXNwb25zZT8uaGVhZGVycyxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgd2FybmluZ3MsXG4gICAgICAgICAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGEsXG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHsgdHlwZTogJ2Vycm9yJywgZXJyb3IgfSk7XG4gICAgICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICAgIHJvb3RTcGFuLmVuZCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICk7XG5cbiAgICAgICAgc3RpdGNoYWJsZVN0cmVhbS5hZGRTdHJlYW0odHJhbnNmb3JtZWRTdHJlYW0pO1xuICAgICAgfSxcbiAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgLy8gYWRkIGFuIGVtcHR5IHN0cmVhbSB3aXRoIGFuIGVycm9yIHRvIGJyZWFrIHRoZSBzdHJlYW06XG4gICAgICAgIHN0aXRjaGFibGVTdHJlYW0uYWRkU3RyZWFtKFxuICAgICAgICAgIG5ldyBSZWFkYWJsZVN0cmVhbSh7XG4gICAgICAgICAgICBzdGFydChjb250cm9sbGVyKSB7XG4gICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7IHR5cGU6ICdlcnJvcicsIGVycm9yIH0pO1xuICAgICAgICAgICAgICBjb250cm9sbGVyLmNsb3NlKCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgfSlcbiAgICAgIC5maW5hbGx5KCgpID0+IHtcbiAgICAgICAgc3RpdGNoYWJsZVN0cmVhbS5jbG9zZSgpO1xuICAgICAgfSk7XG5cbiAgICB0aGlzLm91dHB1dFN0cmF0ZWd5ID0gb3V0cHV0U3RyYXRlZ3k7XG4gIH1cblxuICBnZXQgb2JqZWN0KCkge1xuICAgIHJldHVybiB0aGlzLl9vYmplY3QucHJvbWlzZTtcbiAgfVxuXG4gIGdldCB1c2FnZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fdXNhZ2UucHJvbWlzZTtcbiAgfVxuXG4gIGdldCBwcm92aWRlck1ldGFkYXRhKCkge1xuICAgIHJldHVybiB0aGlzLl9wcm92aWRlck1ldGFkYXRhLnByb21pc2U7XG4gIH1cblxuICBnZXQgd2FybmluZ3MoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3dhcm5pbmdzLnByb21pc2U7XG4gIH1cblxuICBnZXQgcmVxdWVzdCgpIHtcbiAgICByZXR1cm4gdGhpcy5fcmVxdWVzdC5wcm9taXNlO1xuICB9XG5cbiAgZ2V0IHJlc3BvbnNlKCkge1xuICAgIHJldHVybiB0aGlzLl9yZXNwb25zZS5wcm9taXNlO1xuICB9XG5cbiAgZ2V0IGZpbmlzaFJlYXNvbigpIHtcbiAgICByZXR1cm4gdGhpcy5fZmluaXNoUmVhc29uLnByb21pc2U7XG4gIH1cblxuICBnZXQgcGFydGlhbE9iamVjdFN0cmVhbSgpOiBBc3luY0l0ZXJhYmxlU3RyZWFtPFBBUlRJQUw+IHtcbiAgICByZXR1cm4gY3JlYXRlQXN5bmNJdGVyYWJsZVN0cmVhbShcbiAgICAgIHRoaXMuYmFzZVN0cmVhbS5waXBlVGhyb3VnaChcbiAgICAgICAgbmV3IFRyYW5zZm9ybVN0cmVhbTxPYmplY3RTdHJlYW1QYXJ0PFBBUlRJQUw+LCBQQVJUSUFMPih7XG4gICAgICAgICAgdHJhbnNmb3JtKGNodW5rLCBjb250cm9sbGVyKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKGNodW5rLnR5cGUpIHtcbiAgICAgICAgICAgICAgY2FzZSAnb2JqZWN0JzpcbiAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoY2h1bmsub2JqZWN0KTtcbiAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICBjYXNlICd0ZXh0LWRlbHRhJzpcbiAgICAgICAgICAgICAgY2FzZSAnZmluaXNoJzpcbiAgICAgICAgICAgICAgY2FzZSAnZXJyb3InOiAvLyBzdXBwcmVzcyBlcnJvciAodXNlIG9uRXJyb3IgaW5zdGVhZClcbiAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgY29uc3QgX2V4aGF1c3RpdmVDaGVjazogbmV2ZXIgPSBjaHVuaztcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIGNodW5rIHR5cGU6ICR7X2V4aGF1c3RpdmVDaGVja31gKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgKSxcbiAgICApO1xuICB9XG5cbiAgZ2V0IGVsZW1lbnRTdHJlYW0oKTogRUxFTUVOVF9TVFJFQU0ge1xuICAgIHJldHVybiB0aGlzLm91dHB1dFN0cmF0ZWd5LmNyZWF0ZUVsZW1lbnRTdHJlYW0odGhpcy5iYXNlU3RyZWFtKTtcbiAgfVxuXG4gIGdldCB0ZXh0U3RyZWFtKCk6IEFzeW5jSXRlcmFibGVTdHJlYW08c3RyaW5nPiB7XG4gICAgcmV0dXJuIGNyZWF0ZUFzeW5jSXRlcmFibGVTdHJlYW0oXG4gICAgICB0aGlzLmJhc2VTdHJlYW0ucGlwZVRocm91Z2goXG4gICAgICAgIG5ldyBUcmFuc2Zvcm1TdHJlYW08T2JqZWN0U3RyZWFtUGFydDxQQVJUSUFMPiwgc3RyaW5nPih7XG4gICAgICAgICAgdHJhbnNmb3JtKGNodW5rLCBjb250cm9sbGVyKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKGNodW5rLnR5cGUpIHtcbiAgICAgICAgICAgICAgY2FzZSAndGV4dC1kZWx0YSc6XG4gICAgICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKGNodW5rLnRleHREZWx0YSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgICAgY2FzZSAnb2JqZWN0JzpcbiAgICAgICAgICAgICAgY2FzZSAnZmluaXNoJzpcbiAgICAgICAgICAgICAgY2FzZSAnZXJyb3InOiAvLyBzdXBwcmVzcyBlcnJvciAodXNlIG9uRXJyb3IgaW5zdGVhZClcbiAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgY29uc3QgX2V4aGF1c3RpdmVDaGVjazogbmV2ZXIgPSBjaHVuaztcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIGNodW5rIHR5cGU6ICR7X2V4aGF1c3RpdmVDaGVja31gKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgKSxcbiAgICApO1xuICB9XG5cbiAgZ2V0IGZ1bGxTdHJlYW0oKTogQXN5bmNJdGVyYWJsZVN0cmVhbTxPYmplY3RTdHJlYW1QYXJ0PFBBUlRJQUw+PiB7XG4gICAgcmV0dXJuIGNyZWF0ZUFzeW5jSXRlcmFibGVTdHJlYW0odGhpcy5iYXNlU3RyZWFtKTtcbiAgfVxuXG4gIHBpcGVUZXh0U3RyZWFtVG9SZXNwb25zZShyZXNwb25zZTogU2VydmVyUmVzcG9uc2UsIGluaXQ/OiBSZXNwb25zZUluaXQpIHtcbiAgICBwaXBlVGV4dFN0cmVhbVRvUmVzcG9uc2Uoe1xuICAgICAgcmVzcG9uc2UsXG4gICAgICB0ZXh0U3RyZWFtOiB0aGlzLnRleHRTdHJlYW0sXG4gICAgICAuLi5pbml0LFxuICAgIH0pO1xuICB9XG5cbiAgdG9UZXh0U3RyZWFtUmVzcG9uc2UoaW5pdD86IFJlc3BvbnNlSW5pdCk6IFJlc3BvbnNlIHtcbiAgICByZXR1cm4gY3JlYXRlVGV4dFN0cmVhbVJlc3BvbnNlKHtcbiAgICAgIHRleHRTdHJlYW06IHRoaXMudGV4dFN0cmVhbSxcbiAgICAgIC4uLmluaXQsXG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0IHR5cGUgT2JqZWN0U3RyZWFtSW5wdXRQYXJ0ID1cbiAgfCBzdHJpbmdcbiAgfCB7XG4gICAgICB0eXBlOiAnc3RyZWFtLXN0YXJ0JztcbiAgICAgIHdhcm5pbmdzOiBMYW5ndWFnZU1vZGVsVjJDYWxsV2FybmluZ1tdO1xuICAgIH1cbiAgfCB7XG4gICAgICB0eXBlOiAnZXJyb3InO1xuICAgICAgZXJyb3I6IHVua25vd247XG4gICAgfVxuICB8IHtcbiAgICAgIHR5cGU6ICdyZXNwb25zZS1tZXRhZGF0YSc7XG4gICAgICBpZD86IHN0cmluZztcbiAgICAgIHRpbWVzdGFtcD86IERhdGU7XG4gICAgICBtb2RlbElkPzogc3RyaW5nO1xuICAgIH1cbiAgfCB7XG4gICAgICB0eXBlOiAnZmluaXNoJztcbiAgICAgIGZpbmlzaFJlYXNvbjogTGFuZ3VhZ2VNb2RlbFYyRmluaXNoUmVhc29uO1xuICAgICAgdXNhZ2U6IExhbmd1YWdlTW9kZWxWMlVzYWdlO1xuICAgICAgcHJvdmlkZXJNZXRhZGF0YT86IFNoYXJlZFYyUHJvdmlkZXJNZXRhZGF0YTtcbiAgICB9O1xuIiwgImltcG9ydCB7IEludmFsaWRBcmd1bWVudEVycm9yIH0gZnJvbSAnLi4vZXJyb3IvaW52YWxpZC1hcmd1bWVudC1lcnJvcic7XG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgY29zaW5lIHNpbWlsYXJpdHkgYmV0d2VlbiB0d28gdmVjdG9ycy4gVGhpcyBpcyBhIHVzZWZ1bCBtZXRyaWMgZm9yXG4gKiBjb21wYXJpbmcgdGhlIHNpbWlsYXJpdHkgb2YgdHdvIHZlY3RvcnMgc3VjaCBhcyBlbWJlZGRpbmdzLlxuICpcbiAqIEBwYXJhbSB2ZWN0b3IxIC0gVGhlIGZpcnN0IHZlY3Rvci5cbiAqIEBwYXJhbSB2ZWN0b3IyIC0gVGhlIHNlY29uZCB2ZWN0b3IuXG4gKlxuICogQHJldHVybnMgVGhlIGNvc2luZSBzaW1pbGFyaXR5IGJldHdlZW4gdmVjdG9yMSBhbmQgdmVjdG9yMi5cbiAqIEByZXR1cm5zIDAgaWYgZWl0aGVyIHZlY3RvciBpcyB0aGUgemVybyB2ZWN0b3IuXG4gKlxuICogQHRocm93cyB7SW52YWxpZEFyZ3VtZW50RXJyb3J9IElmIHRoZSB2ZWN0b3JzIGRvIG5vdCBoYXZlIHRoZSBzYW1lIGxlbmd0aC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvc2luZVNpbWlsYXJpdHkodmVjdG9yMTogbnVtYmVyW10sIHZlY3RvcjI6IG51bWJlcltdKTogbnVtYmVyIHtcbiAgaWYgKHZlY3RvcjEubGVuZ3RoICE9PSB2ZWN0b3IyLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFcnJvcih7XG4gICAgICBwYXJhbWV0ZXI6ICd2ZWN0b3IxLHZlY3RvcjInLFxuICAgICAgdmFsdWU6IHsgdmVjdG9yMUxlbmd0aDogdmVjdG9yMS5sZW5ndGgsIHZlY3RvcjJMZW5ndGg6IHZlY3RvcjIubGVuZ3RoIH0sXG4gICAgICBtZXNzYWdlOiBgVmVjdG9ycyBtdXN0IGhhdmUgdGhlIHNhbWUgbGVuZ3RoYCxcbiAgICB9KTtcbiAgfVxuXG4gIGNvbnN0IG4gPSB2ZWN0b3IxLmxlbmd0aDtcblxuICBpZiAobiA9PT0gMCkge1xuICAgIHJldHVybiAwOyAvLyBSZXR1cm4gMCBmb3IgZW1wdHkgdmVjdG9ycyBpZiBubyBlcnJvciBpcyB0aHJvd25cbiAgfVxuXG4gIGxldCBtYWduaXR1ZGVTcXVhcmVkMSA9IDA7XG4gIGxldCBtYWduaXR1ZGVTcXVhcmVkMiA9IDA7XG4gIGxldCBkb3RQcm9kdWN0ID0gMDtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykge1xuICAgIGNvbnN0IHZhbHVlMSA9IHZlY3RvcjFbaV07XG4gICAgY29uc3QgdmFsdWUyID0gdmVjdG9yMltpXTtcblxuICAgIG1hZ25pdHVkZVNxdWFyZWQxICs9IHZhbHVlMSAqIHZhbHVlMTtcbiAgICBtYWduaXR1ZGVTcXVhcmVkMiArPSB2YWx1ZTIgKiB2YWx1ZTI7XG4gICAgZG90UHJvZHVjdCArPSB2YWx1ZTEgKiB2YWx1ZTI7XG4gIH1cblxuICByZXR1cm4gbWFnbml0dWRlU3F1YXJlZDEgPT09IDAgfHwgbWFnbml0dWRlU3F1YXJlZDIgPT09IDBcbiAgICA/IDBcbiAgICA6IGRvdFByb2R1Y3QgL1xuICAgICAgICAoTWF0aC5zcXJ0KG1hZ25pdHVkZVNxdWFyZWQxKSAqIE1hdGguc3FydChtYWduaXR1ZGVTcXVhcmVkMikpO1xufVxuIiwgIi8qKlxuICogQ29udmVydHMgYSBkYXRhIFVSTCBvZiB0eXBlIHRleHQvKiB0byBhIHRleHQgc3RyaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VGV4dEZyb21EYXRhVXJsKGRhdGFVcmw6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IFtoZWFkZXIsIGJhc2U2NENvbnRlbnRdID0gZGF0YVVybC5zcGxpdCgnLCcpO1xuICBjb25zdCBtZWRpYVR5cGUgPSBoZWFkZXIuc3BsaXQoJzsnKVswXS5zcGxpdCgnOicpWzFdO1xuXG4gIGlmIChtZWRpYVR5cGUgPT0gbnVsbCB8fCBiYXNlNjRDb250ZW50ID09IG51bGwpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgZGF0YSBVUkwgZm9ybWF0Jyk7XG4gIH1cblxuICB0cnkge1xuICAgIHJldHVybiB3aW5kb3cuYXRvYihiYXNlNjRDb250ZW50KTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEVycm9yIGRlY29kaW5nIGRhdGEgVVJMYCk7XG4gIH1cbn1cbiIsICIvKipcbiAqIFBlcmZvcm1zIGEgZGVlcC1lcXVhbCBjb21wYXJpc29uIG9mIHR3byBwYXJzZWQgSlNPTiBvYmplY3RzLlxuICpcbiAqIEBwYXJhbSB7YW55fSBvYmoxIC0gVGhlIGZpcnN0IG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHthbnl9IG9iajIgLSBUaGUgc2Vjb25kIG9iamVjdCB0byBjb21wYXJlLlxuICogQHJldHVybnMge2Jvb2xlYW59IC0gUmV0dXJucyB0cnVlIGlmIHRoZSB0d28gb2JqZWN0cyBhcmUgZGVlcGx5IGVxdWFsLCBmYWxzZSBvdGhlcndpc2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0RlZXBFcXVhbERhdGEob2JqMTogYW55LCBvYmoyOiBhbnkpOiBib29sZWFuIHtcbiAgLy8gQ2hlY2sgZm9yIHN0cmljdCBlcXVhbGl0eSBmaXJzdFxuICBpZiAob2JqMSA9PT0gb2JqMikgcmV0dXJuIHRydWU7XG5cbiAgLy8gQ2hlY2sgaWYgZWl0aGVyIGlzIG51bGwgb3IgdW5kZWZpbmVkXG4gIGlmIChvYmoxID09IG51bGwgfHwgb2JqMiA9PSBudWxsKSByZXR1cm4gZmFsc2U7XG5cbiAgLy8gQ2hlY2sgaWYgYm90aCBhcmUgb2JqZWN0c1xuICBpZiAodHlwZW9mIG9iajEgIT09ICdvYmplY3QnICYmIHR5cGVvZiBvYmoyICE9PSAnb2JqZWN0JylcbiAgICByZXR1cm4gb2JqMSA9PT0gb2JqMjtcblxuICAvLyBJZiB0aGV5IGFyZSBub3Qgc3RyaWN0bHkgZXF1YWwsIHRoZXkgYm90aCBuZWVkIHRvIGJlIE9iamVjdHNcbiAgaWYgKG9iajEuY29uc3RydWN0b3IgIT09IG9iajIuY29uc3RydWN0b3IpIHJldHVybiBmYWxzZTtcblxuICAvLyBTcGVjaWFsIGhhbmRsaW5nIGZvciBEYXRlIG9iamVjdHNcbiAgaWYgKG9iajEgaW5zdGFuY2VvZiBEYXRlICYmIG9iajIgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgcmV0dXJuIG9iajEuZ2V0VGltZSgpID09PSBvYmoyLmdldFRpbWUoKTtcbiAgfVxuXG4gIC8vIEhhbmRsZSBhcnJheXM6IGNvbXBhcmUgbGVuZ3RoIGFuZCB0aGVuIHBlcmZvcm0gYSByZWN1cnNpdmUgZGVlcCBjb21wYXJpc29uIG9uIGVhY2ggaXRlbVxuICBpZiAoQXJyYXkuaXNBcnJheShvYmoxKSkge1xuICAgIGlmIChvYmoxLmxlbmd0aCAhPT0gb2JqMi5sZW5ndGgpIHJldHVybiBmYWxzZTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9iajEubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmICghaXNEZWVwRXF1YWxEYXRhKG9iajFbaV0sIG9iajJbaV0pKSByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlOyAvLyBBbGwgYXJyYXkgZWxlbWVudHMgbWF0Y2hlZFxuICB9XG5cbiAgLy8gQ29tcGFyZSB0aGUgc2V0IG9mIGtleXMgaW4gZWFjaCBvYmplY3RcbiAgY29uc3Qga2V5czEgPSBPYmplY3Qua2V5cyhvYmoxKTtcbiAgY29uc3Qga2V5czIgPSBPYmplY3Qua2V5cyhvYmoyKTtcbiAgaWYgKGtleXMxLmxlbmd0aCAhPT0ga2V5czIubGVuZ3RoKSByZXR1cm4gZmFsc2U7XG5cbiAgLy8gQ2hlY2sgZWFjaCBrZXktdmFsdWUgcGFpciByZWN1cnNpdmVseVxuICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzMSkge1xuICAgIGlmICgha2V5czIuaW5jbHVkZXMoa2V5KSkgcmV0dXJuIGZhbHNlO1xuICAgIGlmICghaXNEZWVwRXF1YWxEYXRhKG9iajFba2V5XSwgb2JqMltrZXldKSkgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7IC8vIEFsbCBrZXlzIGFuZCB2YWx1ZXMgbWF0Y2hlZFxufVxuIiwgImltcG9ydCB7IEpvYiB9IGZyb20gJy4vam9iJztcblxuZXhwb3J0IGNsYXNzIFNlcmlhbEpvYkV4ZWN1dG9yIHtcbiAgcHJpdmF0ZSBxdWV1ZTogQXJyYXk8Sm9iPiA9IFtdO1xuICBwcml2YXRlIGlzUHJvY2Vzc2luZyA9IGZhbHNlO1xuXG4gIHByaXZhdGUgYXN5bmMgcHJvY2Vzc1F1ZXVlKCkge1xuICAgIGlmICh0aGlzLmlzUHJvY2Vzc2luZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuaXNQcm9jZXNzaW5nID0gdHJ1ZTtcblxuICAgIHdoaWxlICh0aGlzLnF1ZXVlLmxlbmd0aCA+IDApIHtcbiAgICAgIGF3YWl0IHRoaXMucXVldWVbMF0oKTtcbiAgICAgIHRoaXMucXVldWUuc2hpZnQoKTtcbiAgICB9XG5cbiAgICB0aGlzLmlzUHJvY2Vzc2luZyA9IGZhbHNlO1xuICB9XG5cbiAgYXN5bmMgcnVuKGpvYjogSm9iKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMucXVldWUucHVzaChhc3luYyAoKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgam9iKCk7XG4gICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICB2b2lkIHRoaXMucHJvY2Vzc1F1ZXVlKCk7XG4gICAgfSk7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBkZWxheSBhcyBkZWxheUZ1bmN0aW9uIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5cbi8qKlxuICogQ3JlYXRlcyBhIFJlYWRhYmxlU3RyZWFtIHRoYXQgZW1pdHMgdGhlIHByb3ZpZGVkIHZhbHVlcyB3aXRoIGFuIG9wdGlvbmFsIGRlbGF5IGJldHdlZW4gZWFjaCB2YWx1ZS5cbiAqXG4gKiBAcGFyYW0gb3B0aW9ucyAtIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnNcbiAqIEBwYXJhbSBvcHRpb25zLmNodW5rcyAtIEFycmF5IG9mIHZhbHVlcyB0byBiZSBlbWl0dGVkIGJ5IHRoZSBzdHJlYW1cbiAqIEBwYXJhbSBvcHRpb25zLmluaXRpYWxEZWxheUluTXMgLSBPcHRpb25hbCBpbml0aWFsIGRlbGF5IGluIG1pbGxpc2Vjb25kcyBiZWZvcmUgZW1pdHRpbmcgdGhlIGZpcnN0IHZhbHVlIChkZWZhdWx0OiAwKS4gQ2FuIGJlIHNldCB0byBgbnVsbGAgdG8gc2tpcCB0aGUgaW5pdGlhbCBkZWxheS4gVGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBgaW5pdGlhbERlbGF5SW5NczogbnVsbGAgYW5kIGBpbml0aWFsRGVsYXlJbk1zOiAwYCBpcyB0aGF0IGBpbml0aWFsRGVsYXlJbk1zOiBudWxsYCB3aWxsIGVtaXQgdGhlIHZhbHVlcyB3aXRob3V0IGFueSBkZWxheSwgd2hpbGUgYGluaXRpYWxEZWxheUluTXM6IDBgIHdpbGwgZW1pdCB0aGUgdmFsdWVzIHdpdGggYSBkZWxheSBvZiAwIG1pbGxpc2Vjb25kcy5cbiAqIEBwYXJhbSBvcHRpb25zLmNodW5rRGVsYXlJbk1zIC0gT3B0aW9uYWwgZGVsYXkgaW4gbWlsbGlzZWNvbmRzIGJldHdlZW4gZW1pdHRpbmcgZWFjaCB2YWx1ZSAoZGVmYXVsdDogMCkuIENhbiBiZSBzZXQgdG8gYG51bGxgIHRvIHNraXAgdGhlIGRlbGF5LiBUaGUgZGlmZmVyZW5jZSBiZXR3ZWVuIGBjaHVua0RlbGF5SW5NczogbnVsbGAgYW5kIGBjaHVua0RlbGF5SW5NczogMGAgaXMgdGhhdCBgY2h1bmtEZWxheUluTXM6IG51bGxgIHdpbGwgZW1pdCB0aGUgdmFsdWVzIHdpdGhvdXQgYW55IGRlbGF5LCB3aGlsZSBgY2h1bmtEZWxheUluTXM6IDBgIHdpbGwgZW1pdCB0aGUgdmFsdWVzIHdpdGggYSBkZWxheSBvZiAwIG1pbGxpc2Vjb25kcy5cbiAqIEByZXR1cm5zIEEgUmVhZGFibGVTdHJlYW0gdGhhdCBlbWl0cyB0aGUgcHJvdmlkZWQgdmFsdWVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzaW11bGF0ZVJlYWRhYmxlU3RyZWFtPFQ+KHtcbiAgY2h1bmtzLFxuICBpbml0aWFsRGVsYXlJbk1zID0gMCxcbiAgY2h1bmtEZWxheUluTXMgPSAwLFxuICBfaW50ZXJuYWwsXG59OiB7XG4gIGNodW5rczogVFtdO1xuICBpbml0aWFsRGVsYXlJbk1zPzogbnVtYmVyIHwgbnVsbDtcbiAgY2h1bmtEZWxheUluTXM/OiBudW1iZXIgfCBudWxsO1xuICBfaW50ZXJuYWw/OiB7XG4gICAgZGVsYXk/OiAobXM6IG51bWJlciB8IG51bGwpID0+IFByb21pc2U8dm9pZD47XG4gIH07XG59KTogUmVhZGFibGVTdHJlYW08VD4ge1xuICBjb25zdCBkZWxheSA9IF9pbnRlcm5hbD8uZGVsYXkgPz8gZGVsYXlGdW5jdGlvbjtcblxuICBsZXQgaW5kZXggPSAwO1xuXG4gIHJldHVybiBuZXcgUmVhZGFibGVTdHJlYW0oe1xuICAgIGFzeW5jIHB1bGwoY29udHJvbGxlcikge1xuICAgICAgaWYgKGluZGV4IDwgY2h1bmtzLmxlbmd0aCkge1xuICAgICAgICBhd2FpdCBkZWxheShpbmRleCA9PT0gMCA/IGluaXRpYWxEZWxheUluTXMgOiBjaHVua0RlbGF5SW5Ncyk7XG4gICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShjaHVua3NbaW5kZXgrK10pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29udHJvbGxlci5jbG9zZSgpO1xuICAgICAgfVxuICAgIH0sXG4gIH0pO1xufVxuIiwgImltcG9ydCB7IEpTT05WYWx1ZSwgU3BlZWNoTW9kZWxWMiB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgUHJvdmlkZXJPcHRpb25zLCB3aXRoVXNlckFnZW50U3VmZml4IH0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyBOb1NwZWVjaEdlbmVyYXRlZEVycm9yIH0gZnJvbSAnLi4vZXJyb3Ivbm8tc3BlZWNoLWdlbmVyYXRlZC1lcnJvcic7XG5pbXBvcnQgeyBVbnN1cHBvcnRlZE1vZGVsVmVyc2lvbkVycm9yIH0gZnJvbSAnLi4vZXJyb3IvdW5zdXBwb3J0ZWQtbW9kZWwtdmVyc2lvbi1lcnJvcic7XG5pbXBvcnQgeyBsb2dXYXJuaW5ncyB9IGZyb20gJy4uL2xvZ2dlci9sb2ctd2FybmluZ3MnO1xuaW1wb3J0IHsgU3BlZWNoV2FybmluZyB9IGZyb20gJy4uL3R5cGVzL3NwZWVjaC1tb2RlbCc7XG5pbXBvcnQgeyBTcGVlY2hNb2RlbFJlc3BvbnNlTWV0YWRhdGEgfSBmcm9tICcuLi90eXBlcy9zcGVlY2gtbW9kZWwtcmVzcG9uc2UtbWV0YWRhdGEnO1xuaW1wb3J0IHtcbiAgYXVkaW9NZWRpYVR5cGVTaWduYXR1cmVzLFxuICBkZXRlY3RNZWRpYVR5cGUsXG59IGZyb20gJy4uL3V0aWwvZGV0ZWN0LW1lZGlhLXR5cGUnO1xuaW1wb3J0IHsgcHJlcGFyZVJldHJpZXMgfSBmcm9tICcuLi91dGlsL3ByZXBhcmUtcmV0cmllcyc7XG5pbXBvcnQgeyBTcGVlY2hSZXN1bHQgfSBmcm9tICcuL2dlbmVyYXRlLXNwZWVjaC1yZXN1bHQnO1xuaW1wb3J0IHtcbiAgRGVmYXVsdEdlbmVyYXRlZEF1ZGlvRmlsZSxcbiAgR2VuZXJhdGVkQXVkaW9GaWxlLFxufSBmcm9tICcuL2dlbmVyYXRlZC1hdWRpby1maWxlJztcbmltcG9ydCB7IFZFUlNJT04gfSBmcm9tICcuLi92ZXJzaW9uJztcbi8qKlxuR2VuZXJhdGVzIHNwZWVjaCBhdWRpbyB1c2luZyBhIHNwZWVjaCBtb2RlbC5cblxuQHBhcmFtIG1vZGVsIC0gVGhlIHNwZWVjaCBtb2RlbCB0byB1c2UuXG5AcGFyYW0gdGV4dCAtIFRoZSB0ZXh0IHRvIGNvbnZlcnQgdG8gc3BlZWNoLlxuQHBhcmFtIHZvaWNlIC0gVGhlIHZvaWNlIHRvIHVzZSBmb3Igc3BlZWNoIGdlbmVyYXRpb24uXG5AcGFyYW0gb3V0cHV0Rm9ybWF0IC0gVGhlIG91dHB1dCBmb3JtYXQgdG8gdXNlIGZvciBzcGVlY2ggZ2VuZXJhdGlvbiBlLmcuIFwibXAzXCIsIFwid2F2XCIsIGV0Yy5cbkBwYXJhbSBpbnN0cnVjdGlvbnMgLSBJbnN0cnVjdGlvbnMgZm9yIHRoZSBzcGVlY2ggZ2VuZXJhdGlvbiBlLmcuIFwiU3BlYWsgaW4gYSBzbG93IGFuZCBzdGVhZHkgdG9uZVwiLlxuQHBhcmFtIHNwZWVkIC0gVGhlIHNwZWVkIG9mIHRoZSBzcGVlY2ggZ2VuZXJhdGlvbi5cbkBwYXJhbSBwcm92aWRlck9wdGlvbnMgLSBBZGRpdGlvbmFsIHByb3ZpZGVyLXNwZWNpZmljIG9wdGlvbnMgdGhhdCBhcmUgcGFzc2VkIHRocm91Z2ggdG8gdGhlIHByb3ZpZGVyXG5hcyBib2R5IHBhcmFtZXRlcnMuXG5AcGFyYW0gbWF4UmV0cmllcyAtIE1heGltdW0gbnVtYmVyIG9mIHJldHJpZXMuIFNldCB0byAwIHRvIGRpc2FibGUgcmV0cmllcy4gRGVmYXVsdDogMi5cbkBwYXJhbSBhYm9ydFNpZ25hbCAtIEFuIG9wdGlvbmFsIGFib3J0IHNpZ25hbCB0aGF0IGNhbiBiZSB1c2VkIHRvIGNhbmNlbCB0aGUgY2FsbC5cbkBwYXJhbSBoZWFkZXJzIC0gQWRkaXRpb25hbCBIVFRQIGhlYWRlcnMgdG8gYmUgc2VudCB3aXRoIHRoZSByZXF1ZXN0LiBPbmx5IGFwcGxpY2FibGUgZm9yIEhUVFAtYmFzZWQgcHJvdmlkZXJzLlxuXG5AcmV0dXJucyBBIHJlc3VsdCBvYmplY3QgdGhhdCBjb250YWlucyB0aGUgZ2VuZXJhdGVkIGF1ZGlvIGRhdGEuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZW5lcmF0ZVNwZWVjaCh7XG4gIG1vZGVsLFxuICB0ZXh0LFxuICB2b2ljZSxcbiAgb3V0cHV0Rm9ybWF0LFxuICBpbnN0cnVjdGlvbnMsXG4gIHNwZWVkLFxuICBsYW5ndWFnZSxcbiAgcHJvdmlkZXJPcHRpb25zID0ge30sXG4gIG1heFJldHJpZXM6IG1heFJldHJpZXNBcmcsXG4gIGFib3J0U2lnbmFsLFxuICBoZWFkZXJzLFxufToge1xuICAvKipcblRoZSBzcGVlY2ggbW9kZWwgdG8gdXNlLlxuICAgICAqL1xuICBtb2RlbDogU3BlZWNoTW9kZWxWMjtcblxuICAvKipcblRoZSB0ZXh0IHRvIGNvbnZlcnQgdG8gc3BlZWNoLlxuICAgKi9cbiAgdGV4dDogc3RyaW5nO1xuXG4gIC8qKlxuVGhlIHZvaWNlIHRvIHVzZSBmb3Igc3BlZWNoIGdlbmVyYXRpb24uXG4gICAqL1xuICB2b2ljZT86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGRlc2lyZWQgb3V0cHV0IGZvcm1hdCBmb3IgdGhlIGF1ZGlvIGUuZy4gXCJtcDNcIiwgXCJ3YXZcIiwgZXRjLlxuICAgKi9cbiAgb3V0cHV0Rm9ybWF0PzogJ21wMycgfCAnd2F2JyB8IChzdHJpbmcgJiB7fSk7XG5cbiAgLyoqXG4gICAgSW5zdHJ1Y3Rpb25zIGZvciB0aGUgc3BlZWNoIGdlbmVyYXRpb24gZS5nLiBcIlNwZWFrIGluIGEgc2xvdyBhbmQgc3RlYWR5IHRvbmVcIi5cbiAgKi9cbiAgaW5zdHJ1Y3Rpb25zPzogc3RyaW5nO1xuXG4gIC8qKlxuICBUaGUgc3BlZWQgb2YgdGhlIHNwZWVjaCBnZW5lcmF0aW9uLlxuICAgKi9cbiAgc3BlZWQ/OiBudW1iZXI7XG5cbiAgLyoqXG4gIFRoZSBsYW5ndWFnZSBmb3Igc3BlZWNoIGdlbmVyYXRpb24uIFRoaXMgc2hvdWxkIGJlIGFuIElTTyA2MzktMSBsYW5ndWFnZSBjb2RlIChlLmcuIFwiZW5cIiwgXCJlc1wiLCBcImZyXCIpXG4gIG9yIFwiYXV0b1wiIGZvciBhdXRvbWF0aWMgbGFuZ3VhZ2UgZGV0ZWN0aW9uLiBQcm92aWRlciBzdXBwb3J0IHZhcmllcy5cbiAgICovXG4gIGxhbmd1YWdlPzogc3RyaW5nO1xuXG4gIC8qKlxuQWRkaXRpb25hbCBwcm92aWRlci1zcGVjaWZpYyBvcHRpb25zIHRoYXQgYXJlIHBhc3NlZCB0aHJvdWdoIHRvIHRoZSBwcm92aWRlclxuYXMgYm9keSBwYXJhbWV0ZXJzLlxuXG5UaGUgb3V0ZXIgcmVjb3JkIGlzIGtleWVkIGJ5IHRoZSBwcm92aWRlciBuYW1lLCBhbmQgdGhlIGlubmVyXG5yZWNvcmQgaXMga2V5ZWQgYnkgdGhlIHByb3ZpZGVyLXNwZWNpZmljIG1ldGFkYXRhIGtleS5cbmBgYHRzXG57XG4gIFwib3BlbmFpXCI6IHt9XG59XG5gYGBcbiAgICAgKi9cbiAgcHJvdmlkZXJPcHRpb25zPzogUHJvdmlkZXJPcHRpb25zO1xuXG4gIC8qKlxuTWF4aW11bSBudW1iZXIgb2YgcmV0cmllcyBwZXIgc3BlZWNoIG1vZGVsIGNhbGwuIFNldCB0byAwIHRvIGRpc2FibGUgcmV0cmllcy5cblxuQGRlZmF1bHQgMlxuICAgKi9cbiAgbWF4UmV0cmllcz86IG51bWJlcjtcblxuICAvKipcbkFib3J0IHNpZ25hbC5cbiAqL1xuICBhYm9ydFNpZ25hbD86IEFib3J0U2lnbmFsO1xuXG4gIC8qKlxuQWRkaXRpb25hbCBoZWFkZXJzIHRvIGluY2x1ZGUgaW4gdGhlIHJlcXVlc3QuXG5Pbmx5IGFwcGxpY2FibGUgZm9yIEhUVFAtYmFzZWQgcHJvdmlkZXJzLlxuICovXG4gIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xufSk6IFByb21pc2U8U3BlZWNoUmVzdWx0PiB7XG4gIGlmIChtb2RlbC5zcGVjaWZpY2F0aW9uVmVyc2lvbiAhPT0gJ3YyJykge1xuICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE1vZGVsVmVyc2lvbkVycm9yKHtcbiAgICAgIHZlcnNpb246IG1vZGVsLnNwZWNpZmljYXRpb25WZXJzaW9uLFxuICAgICAgcHJvdmlkZXI6IG1vZGVsLnByb3ZpZGVyLFxuICAgICAgbW9kZWxJZDogbW9kZWwubW9kZWxJZCxcbiAgICB9KTtcbiAgfVxuXG4gIGNvbnN0IGhlYWRlcnNXaXRoVXNlckFnZW50ID0gd2l0aFVzZXJBZ2VudFN1ZmZpeChcbiAgICBoZWFkZXJzID8/IHt9LFxuICAgIGBhaS8ke1ZFUlNJT059YCxcbiAgKTtcblxuICBjb25zdCB7IHJldHJ5IH0gPSBwcmVwYXJlUmV0cmllcyh7XG4gICAgbWF4UmV0cmllczogbWF4UmV0cmllc0FyZyxcbiAgICBhYm9ydFNpZ25hbCxcbiAgfSk7XG5cbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmV0cnkoKCkgPT5cbiAgICBtb2RlbC5kb0dlbmVyYXRlKHtcbiAgICAgIHRleHQsXG4gICAgICB2b2ljZSxcbiAgICAgIG91dHB1dEZvcm1hdCxcbiAgICAgIGluc3RydWN0aW9ucyxcbiAgICAgIHNwZWVkLFxuICAgICAgbGFuZ3VhZ2UsXG4gICAgICBhYm9ydFNpZ25hbCxcbiAgICAgIGhlYWRlcnM6IGhlYWRlcnNXaXRoVXNlckFnZW50LFxuICAgICAgcHJvdmlkZXJPcHRpb25zLFxuICAgIH0pLFxuICApO1xuXG4gIGlmICghcmVzdWx0LmF1ZGlvIHx8IHJlc3VsdC5hdWRpby5sZW5ndGggPT09IDApIHtcbiAgICB0aHJvdyBuZXcgTm9TcGVlY2hHZW5lcmF0ZWRFcnJvcih7IHJlc3BvbnNlczogW3Jlc3VsdC5yZXNwb25zZV0gfSk7XG4gIH1cblxuICBsb2dXYXJuaW5ncyhyZXN1bHQud2FybmluZ3MpO1xuXG4gIHJldHVybiBuZXcgRGVmYXVsdFNwZWVjaFJlc3VsdCh7XG4gICAgYXVkaW86IG5ldyBEZWZhdWx0R2VuZXJhdGVkQXVkaW9GaWxlKHtcbiAgICAgIGRhdGE6IHJlc3VsdC5hdWRpbyxcbiAgICAgIG1lZGlhVHlwZTpcbiAgICAgICAgZGV0ZWN0TWVkaWFUeXBlKHtcbiAgICAgICAgICBkYXRhOiByZXN1bHQuYXVkaW8sXG4gICAgICAgICAgc2lnbmF0dXJlczogYXVkaW9NZWRpYVR5cGVTaWduYXR1cmVzLFxuICAgICAgICB9KSA/PyAnYXVkaW8vbXAzJyxcbiAgICB9KSxcbiAgICB3YXJuaW5nczogcmVzdWx0Lndhcm5pbmdzLFxuICAgIHJlc3BvbnNlczogW3Jlc3VsdC5yZXNwb25zZV0sXG4gICAgcHJvdmlkZXJNZXRhZGF0YTogcmVzdWx0LnByb3ZpZGVyTWV0YWRhdGEsXG4gIH0pO1xufVxuXG5jbGFzcyBEZWZhdWx0U3BlZWNoUmVzdWx0IGltcGxlbWVudHMgU3BlZWNoUmVzdWx0IHtcbiAgcmVhZG9ubHkgYXVkaW86IEdlbmVyYXRlZEF1ZGlvRmlsZTtcbiAgcmVhZG9ubHkgd2FybmluZ3M6IEFycmF5PFNwZWVjaFdhcm5pbmc+O1xuICByZWFkb25seSByZXNwb25zZXM6IEFycmF5PFNwZWVjaE1vZGVsUmVzcG9uc2VNZXRhZGF0YT47XG4gIHJlYWRvbmx5IHByb3ZpZGVyTWV0YWRhdGE6IFJlY29yZDxzdHJpbmcsIFJlY29yZDxzdHJpbmcsIEpTT05WYWx1ZT4+O1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IHtcbiAgICBhdWRpbzogR2VuZXJhdGVkQXVkaW9GaWxlO1xuICAgIHdhcm5pbmdzOiBBcnJheTxTcGVlY2hXYXJuaW5nPjtcbiAgICByZXNwb25zZXM6IEFycmF5PFNwZWVjaE1vZGVsUmVzcG9uc2VNZXRhZGF0YT47XG4gICAgcHJvdmlkZXJNZXRhZGF0YTogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgSlNPTlZhbHVlPj4gfCB1bmRlZmluZWQ7XG4gIH0pIHtcbiAgICB0aGlzLmF1ZGlvID0gb3B0aW9ucy5hdWRpbztcbiAgICB0aGlzLndhcm5pbmdzID0gb3B0aW9ucy53YXJuaW5ncztcbiAgICB0aGlzLnJlc3BvbnNlcyA9IG9wdGlvbnMucmVzcG9uc2VzO1xuICAgIHRoaXMucHJvdmlkZXJNZXRhZGF0YSA9IG9wdGlvbnMucHJvdmlkZXJNZXRhZGF0YSA/PyB7fTtcbiAgfVxufVxuIiwgImltcG9ydCB7XG4gIEdlbmVyYXRlZEZpbGUsXG4gIERlZmF1bHRHZW5lcmF0ZWRGaWxlLFxufSBmcm9tICcuLi9nZW5lcmF0ZS10ZXh0L2dlbmVyYXRlZC1maWxlJztcblxuLyoqXG4gKiBBIGdlbmVyYXRlZCBhdWRpbyBmaWxlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEdlbmVyYXRlZEF1ZGlvRmlsZSBleHRlbmRzIEdlbmVyYXRlZEZpbGUge1xuICAvKipcbiAgICogQXVkaW8gZm9ybWF0IG9mIHRoZSBmaWxlIChlLmcuLCAnbXAzJywgJ3dhdicsIGV0Yy4pXG4gICAqL1xuICByZWFkb25seSBmb3JtYXQ6IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIERlZmF1bHRHZW5lcmF0ZWRBdWRpb0ZpbGVcbiAgZXh0ZW5kcyBEZWZhdWx0R2VuZXJhdGVkRmlsZVxuICBpbXBsZW1lbnRzIEdlbmVyYXRlZEF1ZGlvRmlsZVxue1xuICByZWFkb25seSBmb3JtYXQ6IHN0cmluZztcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgZGF0YSxcbiAgICBtZWRpYVR5cGUsXG4gIH06IHtcbiAgICBkYXRhOiBzdHJpbmcgfCBVaW50OEFycmF5O1xuICAgIG1lZGlhVHlwZTogc3RyaW5nO1xuICB9KSB7XG4gICAgc3VwZXIoeyBkYXRhLCBtZWRpYVR5cGUgfSk7XG4gICAgbGV0IGZvcm1hdCA9ICdtcDMnO1xuXG4gICAgLy8gSWYgZm9ybWF0IGlzIG5vdCBwcm92aWRlZCwgdHJ5IHRvIGRldGVybWluZSBpdCBmcm9tIHRoZSBtZWRpYSB0eXBlXG4gICAgaWYgKG1lZGlhVHlwZSkge1xuICAgICAgY29uc3QgbWVkaWFUeXBlUGFydHMgPSBtZWRpYVR5cGUuc3BsaXQoJy8nKTtcblxuICAgICAgaWYgKG1lZGlhVHlwZVBhcnRzLmxlbmd0aCA9PT0gMikge1xuICAgICAgICAvLyBIYW5kbGUgc3BlY2lhbCBjYXNlcyBmb3IgYXVkaW8gZm9ybWF0c1xuICAgICAgICBpZiAobWVkaWFUeXBlICE9PSAnYXVkaW8vbXBlZycpIHtcbiAgICAgICAgICBmb3JtYXQgPSBtZWRpYVR5cGVQYXJ0c1sxXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghZm9ybWF0KSB7XG4gICAgICAvLyBUT0RPIHRoaXMgc2hvdWxkIGJlIGFuIEFJIFNESyBlcnJvclxuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnQXVkaW8gZm9ybWF0IG11c3QgYmUgcHJvdmlkZWQgb3IgZGV0ZXJtaW5hYmxlIGZyb20gbWVkaWEgdHlwZScsXG4gICAgICApO1xuICAgIH1cblxuICAgIHRoaXMuZm9ybWF0ID0gZm9ybWF0O1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBEZWZhdWx0R2VuZXJhdGVkQXVkaW9GaWxlV2l0aFR5cGUgZXh0ZW5kcyBEZWZhdWx0R2VuZXJhdGVkQXVkaW9GaWxlIHtcbiAgcmVhZG9ubHkgdHlwZSA9ICdhdWRpbyc7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczoge1xuICAgIGRhdGE6IHN0cmluZyB8IFVpbnQ4QXJyYXk7XG4gICAgbWVkaWFUeXBlOiBzdHJpbmc7XG4gICAgZm9ybWF0OiBzdHJpbmc7XG4gIH0pIHtcbiAgICBzdXBlcihvcHRpb25zKTtcbiAgfVxufVxuIiwgImltcG9ydCB7IExhbmd1YWdlTW9kZWxWMkNhbGxPcHRpb25zIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQge1xuICBhc1NjaGVtYSxcbiAgRmxleGlibGVTY2hlbWEsXG4gIHNhZmVQYXJzZUpTT04sXG4gIHNhZmVWYWxpZGF0ZVR5cGVzLFxufSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyLXV0aWxzJztcbmltcG9ydCB7IE5vT2JqZWN0R2VuZXJhdGVkRXJyb3IgfSBmcm9tICcuLi9lcnJvci9uby1vYmplY3QtZ2VuZXJhdGVkLWVycm9yJztcbmltcG9ydCB7IEZpbmlzaFJlYXNvbiB9IGZyb20gJy4uL3R5cGVzL2xhbmd1YWdlLW1vZGVsJztcbmltcG9ydCB7IExhbmd1YWdlTW9kZWxSZXNwb25zZU1ldGFkYXRhIH0gZnJvbSAnLi4vdHlwZXMvbGFuZ3VhZ2UtbW9kZWwtcmVzcG9uc2UtbWV0YWRhdGEnO1xuaW1wb3J0IHsgTGFuZ3VhZ2VNb2RlbFVzYWdlIH0gZnJvbSAnLi4vdHlwZXMvdXNhZ2UnO1xuaW1wb3J0IHsgRGVlcFBhcnRpYWwgfSBmcm9tICcuLi91dGlsL2RlZXAtcGFydGlhbCc7XG5pbXBvcnQgeyBwYXJzZVBhcnRpYWxKc29uIH0gZnJvbSAnLi4vdXRpbC9wYXJzZS1wYXJ0aWFsLWpzb24nO1xuXG5leHBvcnQgaW50ZXJmYWNlIE91dHB1dDxPVVRQVVQsIFBBUlRJQUw+IHtcbiAgcmVhZG9ubHkgdHlwZTogJ29iamVjdCcgfCAndGV4dCc7XG5cbiAgcmVzcG9uc2VGb3JtYXQ6IExhbmd1YWdlTW9kZWxWMkNhbGxPcHRpb25zWydyZXNwb25zZUZvcm1hdCddO1xuXG4gIHBhcnNlUGFydGlhbChvcHRpb25zOiB7XG4gICAgdGV4dDogc3RyaW5nO1xuICB9KTogUHJvbWlzZTx7IHBhcnRpYWw6IFBBUlRJQUwgfSB8IHVuZGVmaW5lZD47XG5cbiAgcGFyc2VPdXRwdXQoXG4gICAgb3B0aW9uczogeyB0ZXh0OiBzdHJpbmcgfSxcbiAgICBjb250ZXh0OiB7XG4gICAgICByZXNwb25zZTogTGFuZ3VhZ2VNb2RlbFJlc3BvbnNlTWV0YWRhdGE7XG4gICAgICB1c2FnZTogTGFuZ3VhZ2VNb2RlbFVzYWdlO1xuICAgICAgZmluaXNoUmVhc29uOiBGaW5pc2hSZWFzb247XG4gICAgfSxcbiAgKTogUHJvbWlzZTxPVVRQVVQ+O1xufVxuXG5leHBvcnQgY29uc3QgdGV4dCA9ICgpOiBPdXRwdXQ8c3RyaW5nLCBzdHJpbmc+ID0+ICh7XG4gIHR5cGU6ICd0ZXh0JyxcblxuICByZXNwb25zZUZvcm1hdDogeyB0eXBlOiAndGV4dCcgfSxcblxuICBhc3luYyBwYXJzZVBhcnRpYWwoeyB0ZXh0IH06IHsgdGV4dDogc3RyaW5nIH0pIHtcbiAgICByZXR1cm4geyBwYXJ0aWFsOiB0ZXh0IH07XG4gIH0sXG5cbiAgYXN5bmMgcGFyc2VPdXRwdXQoeyB0ZXh0IH06IHsgdGV4dDogc3RyaW5nIH0pIHtcbiAgICByZXR1cm4gdGV4dDtcbiAgfSxcbn0pO1xuXG5leHBvcnQgY29uc3Qgb2JqZWN0ID0gPE9VVFBVVD4oe1xuICBzY2hlbWE6IGlucHV0U2NoZW1hLFxufToge1xuICBzY2hlbWE6IEZsZXhpYmxlU2NoZW1hPE9VVFBVVD47XG59KTogT3V0cHV0PE9VVFBVVCwgRGVlcFBhcnRpYWw8T1VUUFVUPj4gPT4ge1xuICBjb25zdCBzY2hlbWEgPSBhc1NjaGVtYShpbnB1dFNjaGVtYSk7XG5cbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAnb2JqZWN0JyxcblxuICAgIHJlc3BvbnNlRm9ybWF0OiB7XG4gICAgICB0eXBlOiAnanNvbicsXG4gICAgICBzY2hlbWE6IHNjaGVtYS5qc29uU2NoZW1hLFxuICAgIH0sXG5cbiAgICBhc3luYyBwYXJzZVBhcnRpYWwoeyB0ZXh0IH06IHsgdGV4dDogc3RyaW5nIH0pIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHBhcnNlUGFydGlhbEpzb24odGV4dCk7XG5cbiAgICAgIHN3aXRjaCAocmVzdWx0LnN0YXRlKSB7XG4gICAgICAgIGNhc2UgJ2ZhaWxlZC1wYXJzZSc6XG4gICAgICAgIGNhc2UgJ3VuZGVmaW5lZC1pbnB1dCc6XG4gICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgICAgICBjYXNlICdyZXBhaXJlZC1wYXJzZSc6XG4gICAgICAgIGNhc2UgJ3N1Y2Nlc3NmdWwtcGFyc2UnOlxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAvLyBOb3RlOiBjdXJyZW50bHkgbm8gdmFsaWRhdGlvbiBvZiBwYXJ0aWFsIHJlc3VsdHM6XG4gICAgICAgICAgICBwYXJ0aWFsOiByZXN1bHQudmFsdWUgYXMgRGVlcFBhcnRpYWw8T1VUUFVUPixcbiAgICAgICAgICB9O1xuXG4gICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICBjb25zdCBfZXhoYXVzdGl2ZUNoZWNrOiBuZXZlciA9IHJlc3VsdC5zdGF0ZTtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIHBhcnNlIHN0YXRlOiAke19leGhhdXN0aXZlQ2hlY2t9YCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuXG4gICAgYXN5bmMgcGFyc2VPdXRwdXQoXG4gICAgICB7IHRleHQgfTogeyB0ZXh0OiBzdHJpbmcgfSxcbiAgICAgIGNvbnRleHQ6IHtcbiAgICAgICAgcmVzcG9uc2U6IExhbmd1YWdlTW9kZWxSZXNwb25zZU1ldGFkYXRhO1xuICAgICAgICB1c2FnZTogTGFuZ3VhZ2VNb2RlbFVzYWdlO1xuICAgICAgICBmaW5pc2hSZWFzb246IEZpbmlzaFJlYXNvbjtcbiAgICAgIH0sXG4gICAgKSB7XG4gICAgICBjb25zdCBwYXJzZVJlc3VsdCA9IGF3YWl0IHNhZmVQYXJzZUpTT04oeyB0ZXh0IH0pO1xuXG4gICAgICBpZiAoIXBhcnNlUmVzdWx0LnN1Y2Nlc3MpIHtcbiAgICAgICAgdGhyb3cgbmV3IE5vT2JqZWN0R2VuZXJhdGVkRXJyb3Ioe1xuICAgICAgICAgIG1lc3NhZ2U6ICdObyBvYmplY3QgZ2VuZXJhdGVkOiBjb3VsZCBub3QgcGFyc2UgdGhlIHJlc3BvbnNlLicsXG4gICAgICAgICAgY2F1c2U6IHBhcnNlUmVzdWx0LmVycm9yLFxuICAgICAgICAgIHRleHQsXG4gICAgICAgICAgcmVzcG9uc2U6IGNvbnRleHQucmVzcG9uc2UsXG4gICAgICAgICAgdXNhZ2U6IGNvbnRleHQudXNhZ2UsXG4gICAgICAgICAgZmluaXNoUmVhc29uOiBjb250ZXh0LmZpbmlzaFJlYXNvbixcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHZhbGlkYXRpb25SZXN1bHQgPSBhd2FpdCBzYWZlVmFsaWRhdGVUeXBlcyh7XG4gICAgICAgIHZhbHVlOiBwYXJzZVJlc3VsdC52YWx1ZSxcbiAgICAgICAgc2NoZW1hLFxuICAgICAgfSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvblJlc3VsdC5zdWNjZXNzKSB7XG4gICAgICAgIHRocm93IG5ldyBOb09iamVjdEdlbmVyYXRlZEVycm9yKHtcbiAgICAgICAgICBtZXNzYWdlOiAnTm8gb2JqZWN0IGdlbmVyYXRlZDogcmVzcG9uc2UgZGlkIG5vdCBtYXRjaCBzY2hlbWEuJyxcbiAgICAgICAgICBjYXVzZTogdmFsaWRhdGlvblJlc3VsdC5lcnJvcixcbiAgICAgICAgICB0ZXh0LFxuICAgICAgICAgIHJlc3BvbnNlOiBjb250ZXh0LnJlc3BvbnNlLFxuICAgICAgICAgIHVzYWdlOiBjb250ZXh0LnVzYWdlLFxuICAgICAgICAgIGZpbmlzaFJlYXNvbjogY29udGV4dC5maW5pc2hSZWFzb24sXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdmFsaWRhdGlvblJlc3VsdC52YWx1ZTtcbiAgICB9LFxuICB9O1xufTtcbiIsICJpbXBvcnQge1xuICBBc3Npc3RhbnRNb2RlbE1lc3NhZ2UsXG4gIE1vZGVsTWVzc2FnZSxcbiAgVG9vbE1vZGVsTWVzc2FnZSxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5cbi8qKlxuICogUHJ1bmVzIG1vZGVsIG1lc3NhZ2VzIGZyb20gYSBsaXN0IG9mIG1vZGVsIG1lc3NhZ2VzLlxuICpcbiAqIEBwYXJhbSBtZXNzYWdlcyAtIFRoZSBsaXN0IG9mIG1vZGVsIG1lc3NhZ2VzIHRvIHBydW5lLlxuICogQHBhcmFtIHJlYXNvbmluZyAtIEhvdyB0byByZW1vdmUgcmVhc29uaW5nIGNvbnRlbnQgZnJvbSBhc3Npc3RhbnQgbWVzc2FnZXMuIERlZmF1bHQgaXMgYCdub25lJ2AuXG4gKiBAcGFyYW0gdG9vbENhbGxzIC0gSG93IHRvIHBydW5lIHRvb2wgY2FsbC9yZXN1bHRzL2FwcHJvdmFsIGNvbnRlbnQuIERlZmF1bHQgaXMgYFtdYC5cbiAqIEBwYXJhbSBlbXB0eU1lc3NhZ2VzIC0gV2hldGhlciB0byBrZWVwIG9yIHJlbW92ZSBtZXNzYWdlcyB3aG9zZSBjb250ZW50IGlzIGVtcHR5IGFmdGVyIHBydW5pbmcuIERlZmF1bHQgaXMgYCdyZW1vdmUnYC5cbiAqXG4gKiBAcmV0dXJucyBUaGUgcHJ1bmVkIGxpc3Qgb2YgbW9kZWwgbWVzc2FnZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcnVuZU1lc3NhZ2VzKHtcbiAgbWVzc2FnZXMsXG4gIHJlYXNvbmluZyA9ICdub25lJyxcbiAgdG9vbENhbGxzID0gW10sXG4gIGVtcHR5TWVzc2FnZXMgPSAncmVtb3ZlJyxcbn06IHtcbiAgbWVzc2FnZXM6IE1vZGVsTWVzc2FnZVtdO1xuICByZWFzb25pbmc/OiAnYWxsJyB8ICdiZWZvcmUtbGFzdC1tZXNzYWdlJyB8ICdub25lJztcbiAgdG9vbENhbGxzPzpcbiAgICB8ICdhbGwnXG4gICAgfCAnYmVmb3JlLWxhc3QtbWVzc2FnZSdcbiAgICB8IGBiZWZvcmUtbGFzdC0ke251bWJlcn0tbWVzc2FnZXNgXG4gICAgfCAnbm9uZSdcbiAgICB8IEFycmF5PHtcbiAgICAgICAgdHlwZTogJ2FsbCcgfCAnYmVmb3JlLWxhc3QtbWVzc2FnZScgfCBgYmVmb3JlLWxhc3QtJHtudW1iZXJ9LW1lc3NhZ2VzYDtcbiAgICAgICAgdG9vbHM/OiBzdHJpbmdbXTtcbiAgICAgIH0+O1xuICBlbXB0eU1lc3NhZ2VzPzogJ2tlZXAnIHwgJ3JlbW92ZSc7XG59KTogTW9kZWxNZXNzYWdlW10ge1xuICAvLyBmaWx0ZXIgcmVhc29uaW5nIHBhcnRzOlxuICBpZiAocmVhc29uaW5nID09PSAnYWxsJyB8fCByZWFzb25pbmcgPT09ICdiZWZvcmUtbGFzdC1tZXNzYWdlJykge1xuICAgIG1lc3NhZ2VzID0gbWVzc2FnZXMubWFwKChtZXNzYWdlLCBtZXNzYWdlSW5kZXgpID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgbWVzc2FnZS5yb2xlICE9PSAnYXNzaXN0YW50JyB8fFxuICAgICAgICB0eXBlb2YgbWVzc2FnZS5jb250ZW50ID09PSAnc3RyaW5nJyB8fFxuICAgICAgICAocmVhc29uaW5nID09PSAnYmVmb3JlLWxhc3QtbWVzc2FnZScgJiZcbiAgICAgICAgICBtZXNzYWdlSW5kZXggPT09IG1lc3NhZ2VzLmxlbmd0aCAtIDEpXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLm1lc3NhZ2UsXG4gICAgICAgIGNvbnRlbnQ6IG1lc3NhZ2UuY29udGVudC5maWx0ZXIocGFydCA9PiBwYXJ0LnR5cGUgIT09ICdyZWFzb25pbmcnKSxcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICAvLyBmaWx0ZXIgdG9vbCBjYWxscywgcmVzdWx0cywgZXJyb3JzLCBhbmQgYXBwcm92YWxzOlxuICBpZiAodG9vbENhbGxzID09PSAnbm9uZScpIHtcbiAgICB0b29sQ2FsbHMgPSBbXTtcbiAgfSBlbHNlIGlmICh0b29sQ2FsbHMgPT09ICdhbGwnKSB7XG4gICAgdG9vbENhbGxzID0gW3sgdHlwZTogJ2FsbCcgfV07XG4gIH0gZWxzZSBpZiAodG9vbENhbGxzID09PSAnYmVmb3JlLWxhc3QtbWVzc2FnZScpIHtcbiAgICB0b29sQ2FsbHMgPSBbeyB0eXBlOiAnYmVmb3JlLWxhc3QtbWVzc2FnZScgfV07XG4gIH0gZWxzZSBpZiAodHlwZW9mIHRvb2xDYWxscyA9PT0gJ3N0cmluZycpIHtcbiAgICB0b29sQ2FsbHMgPSBbeyB0eXBlOiB0b29sQ2FsbHMgfV07XG4gIH1cblxuICBmb3IgKGNvbnN0IHRvb2xDYWxsIG9mIHRvb2xDYWxscykge1xuICAgIC8vIGRldGVybWluZSBob3cgbWFueSB0cmFpbGluZyBtZXNzYWdlcyB0byBrZWVwOlxuICAgIGNvbnN0IGtlZXBMYXN0TWVzc2FnZXNDb3VudCA9XG4gICAgICB0b29sQ2FsbC50eXBlID09PSAnYWxsJ1xuICAgICAgICA/IHVuZGVmaW5lZFxuICAgICAgICA6IHRvb2xDYWxsLnR5cGUgPT09ICdiZWZvcmUtbGFzdC1tZXNzYWdlJ1xuICAgICAgICAgID8gMVxuICAgICAgICAgIDogTnVtYmVyKFxuICAgICAgICAgICAgICB0b29sQ2FsbC50eXBlXG4gICAgICAgICAgICAgICAgLnNsaWNlKCdiZWZvcmUtbGFzdC0nLmxlbmd0aClcbiAgICAgICAgICAgICAgICAuc2xpY2UoMCwgLSctbWVzc2FnZXMnLmxlbmd0aCksXG4gICAgICAgICAgICApO1xuXG4gICAgLy8gc2NhbiBrZXB0IG1lc3NhZ2VzIHRvIGlkZW50aWZ5IHRvb2wgY2FsbHMgYW5kIGFwcHJvdmFscyB0aGF0IG5lZWQgdG8gYmUga2VwdDpcbiAgICBjb25zdCBrZXB0VG9vbENhbGxJZHM6IFNldDxzdHJpbmc+ID0gbmV3IFNldCgpO1xuICAgIGNvbnN0IGtlcHRBcHByb3ZhbElkczogU2V0PHN0cmluZz4gPSBuZXcgU2V0KCk7XG5cbiAgICBpZiAoa2VlcExhc3RNZXNzYWdlc0NvdW50ICE9IG51bGwpIHtcbiAgICAgIGZvciAoY29uc3QgbWVzc2FnZSBvZiBtZXNzYWdlcy5zbGljZSgwLCAta2VlcExhc3RNZXNzYWdlc0NvdW50KSkge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgKG1lc3NhZ2Uucm9sZSA9PT0gJ2Fzc2lzdGFudCcgfHwgbWVzc2FnZS5yb2xlID09PSAndG9vbCcpICYmXG4gICAgICAgICAgdHlwZW9mIG1lc3NhZ2UuY29udGVudCAhPT0gJ3N0cmluZydcbiAgICAgICAgKSB7XG4gICAgICAgICAgZm9yIChjb25zdCBwYXJ0IG9mIG1lc3NhZ2UuY29udGVudCkge1xuICAgICAgICAgICAgaWYgKHBhcnQudHlwZSA9PT0gJ3Rvb2wtY2FsbCcgfHwgcGFydC50eXBlID09PSAndG9vbC1yZXN1bHQnKSB7XG4gICAgICAgICAgICAgIGtlcHRUb29sQ2FsbElkcy5hZGQocGFydC50b29sQ2FsbElkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBtZXNzYWdlcyA9IG1lc3NhZ2VzLm1hcCgobWVzc2FnZSwgbWVzc2FnZUluZGV4KSA9PiB7XG4gICAgICBpZiAoXG4gICAgICAgIChtZXNzYWdlLnJvbGUgIT09ICdhc3Npc3RhbnQnICYmIG1lc3NhZ2Uucm9sZSAhPT0gJ3Rvb2wnKSB8fFxuICAgICAgICB0eXBlb2YgbWVzc2FnZS5jb250ZW50ID09PSAnc3RyaW5nJyB8fFxuICAgICAgICAoa2VlcExhc3RNZXNzYWdlc0NvdW50ICYmXG4gICAgICAgICAgbWVzc2FnZUluZGV4ID49IG1lc3NhZ2VzLmxlbmd0aCAtIGtlZXBMYXN0TWVzc2FnZXNDb3VudClcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgdG9vbENhbGxJZFRvVG9vbE5hbWU6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ubWVzc2FnZSxcbiAgICAgICAgY29udGVudDogbWVzc2FnZS5jb250ZW50LmZpbHRlcihwYXJ0ID0+IHtcbiAgICAgICAgICAvLyBrZWVwIG5vbi10b29sIHBhcnRzOlxuICAgICAgICAgIGlmIChwYXJ0LnR5cGUgIT09ICd0b29sLWNhbGwnICYmIHBhcnQudHlwZSAhPT0gJ3Rvb2wtcmVzdWx0Jykge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gdHJhY2sgdG9vbCBjYWxscyBhbmQgYXBwcm92YWxzOlxuICAgICAgICAgIGlmIChwYXJ0LnR5cGUgPT09ICd0b29sLWNhbGwnKSB7XG4gICAgICAgICAgICB0b29sQ2FsbElkVG9Ub29sTmFtZVtwYXJ0LnRvb2xDYWxsSWRdID0gcGFydC50b29sTmFtZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBrZWVwIHBhcnRzIHRoYXQgYXJlIGFzc29jaWF0ZWQgd2l0aCBhIHRvb2wgY2FsbCBvciBhcHByb3ZhbCB0aGF0IG5lZWRzIHRvIGJlIGtlcHQ6XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgKHBhcnQudHlwZSA9PT0gJ3Rvb2wtY2FsbCcgfHwgcGFydC50eXBlID09PSAndG9vbC1yZXN1bHQnKSAmJlxuICAgICAgICAgICAga2VwdFRvb2xDYWxsSWRzLmhhcyhwYXJ0LnRvb2xDYWxsSWQpXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBrZWVwIHBhcnRzIHRoYXQgYXJlIG5vdCBhc3NvY2lhdGVkIHdpdGggYSB0b29sIHRoYXQgc2hvdWxkIGJlIHJlbW92ZWQ6XG4gICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIHRvb2xDYWxsLnRvb2xzICE9IG51bGwgJiYgIXRvb2xDYWxsLnRvb2xzLmluY2x1ZGVzKHBhcnQudG9vbE5hbWUpXG4gICAgICAgICAgKTtcbiAgICAgICAgfSksXG4gICAgICB9IGFzIEFzc2lzdGFudE1vZGVsTWVzc2FnZSB8IFRvb2xNb2RlbE1lc3NhZ2U7XG4gICAgfSk7XG4gIH1cblxuICBpZiAoZW1wdHlNZXNzYWdlcyA9PT0gJ3JlbW92ZScpIHtcbiAgICBtZXNzYWdlcyA9IG1lc3NhZ2VzLmZpbHRlcihtZXNzYWdlID0+IG1lc3NhZ2UuY29udGVudC5sZW5ndGggPiAwKTtcbiAgfVxuXG4gIHJldHVybiBtZXNzYWdlcztcbn1cbiIsICJpbXBvcnQgeyBkZWxheSBhcyBvcmlnaW5hbERlbGF5IH0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyBUZXh0U3RyZWFtUGFydCB9IGZyb20gJy4vc3RyZWFtLXRleHQtcmVzdWx0JztcbmltcG9ydCB7IFRvb2xTZXQgfSBmcm9tICcuL3Rvb2wtc2V0JztcbmltcG9ydCB7IEludmFsaWRBcmd1bWVudEVycm9yIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5cbmNvbnN0IENIVU5LSU5HX1JFR0VYUFMgPSB7XG4gIHdvcmQ6IC9cXFMrXFxzKy9tLFxuICBsaW5lOiAvXFxuKy9tLFxufTtcblxuLyoqXG4gKiBEZXRlY3RzIHRoZSBmaXJzdCBjaHVuayBpbiBhIGJ1ZmZlci5cbiAqXG4gKiBAcGFyYW0gYnVmZmVyIC0gVGhlIGJ1ZmZlciB0byBkZXRlY3QgdGhlIGZpcnN0IGNodW5rIGluLlxuICpcbiAqIEByZXR1cm5zIFRoZSBmaXJzdCBkZXRlY3RlZCBjaHVuaywgb3IgYHVuZGVmaW5lZGAgaWYgbm8gY2h1bmsgd2FzIGRldGVjdGVkLlxuICovXG5leHBvcnQgdHlwZSBDaHVua0RldGVjdG9yID0gKGJ1ZmZlcjogc3RyaW5nKSA9PiBzdHJpbmcgfCB1bmRlZmluZWQgfCBudWxsO1xuXG4vKipcbiAqIFNtb290aHMgdGV4dCBzdHJlYW1pbmcgb3V0cHV0LlxuICpcbiAqIEBwYXJhbSBkZWxheUluTXMgLSBUaGUgZGVsYXkgaW4gbWlsbGlzZWNvbmRzIGJldHdlZW4gZWFjaCBjaHVuay4gRGVmYXVsdHMgdG8gMTBtcy4gQ2FuIGJlIHNldCB0byBgbnVsbGAgdG8gc2tpcCB0aGUgZGVsYXkuXG4gKiBAcGFyYW0gY2h1bmtpbmcgLSBDb250cm9scyBob3cgdGhlIHRleHQgaXMgY2h1bmtlZCBmb3Igc3RyZWFtaW5nLiBVc2UgXCJ3b3JkXCIgdG8gc3RyZWFtIHdvcmQgYnkgd29yZCAoZGVmYXVsdCksIFwibGluZVwiIHRvIHN0cmVhbSBsaW5lIGJ5IGxpbmUsIG9yIHByb3ZpZGUgYSBjdXN0b20gUmVnRXhwIHBhdHRlcm4gZm9yIGN1c3RvbSBjaHVua2luZy5cbiAqXG4gKiBAcmV0dXJucyBBIHRyYW5zZm9ybSBzdHJlYW0gdGhhdCBzbW9vdGhzIHRleHQgc3RyZWFtaW5nIG91dHB1dC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNtb290aFN0cmVhbTxUT09MUyBleHRlbmRzIFRvb2xTZXQ+KHtcbiAgZGVsYXlJbk1zID0gMTAsXG4gIGNodW5raW5nID0gJ3dvcmQnLFxuICBfaW50ZXJuYWw6IHsgZGVsYXkgPSBvcmlnaW5hbERlbGF5IH0gPSB7fSxcbn06IHtcbiAgZGVsYXlJbk1zPzogbnVtYmVyIHwgbnVsbDtcbiAgY2h1bmtpbmc/OiAnd29yZCcgfCAnbGluZScgfCBSZWdFeHAgfCBDaHVua0RldGVjdG9yO1xuICAvKipcbiAgICogSW50ZXJuYWwuIEZvciB0ZXN0IHVzZSBvbmx5LiBNYXkgY2hhbmdlIHdpdGhvdXQgbm90aWNlLlxuICAgKi9cbiAgX2ludGVybmFsPzoge1xuICAgIGRlbGF5PzogKGRlbGF5SW5NczogbnVtYmVyIHwgbnVsbCkgPT4gUHJvbWlzZTx2b2lkPjtcbiAgfTtcbn0gPSB7fSk6IChvcHRpb25zOiB7XG4gIHRvb2xzOiBUT09MUztcbn0pID0+IFRyYW5zZm9ybVN0cmVhbTxUZXh0U3RyZWFtUGFydDxUT09MUz4sIFRleHRTdHJlYW1QYXJ0PFRPT0xTPj4ge1xuICBsZXQgZGV0ZWN0Q2h1bms6IENodW5rRGV0ZWN0b3I7XG5cbiAgaWYgKHR5cGVvZiBjaHVua2luZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGRldGVjdENodW5rID0gYnVmZmVyID0+IHtcbiAgICAgIGNvbnN0IG1hdGNoID0gY2h1bmtpbmcoYnVmZmVyKTtcblxuICAgICAgaWYgKG1hdGNoID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICAgIGlmICghbWF0Y2gubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2h1bmtpbmcgZnVuY3Rpb24gbXVzdCByZXR1cm4gYSBub24tZW1wdHkgc3RyaW5nLmApO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWJ1ZmZlci5zdGFydHNXaXRoKG1hdGNoKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYENodW5raW5nIGZ1bmN0aW9uIG11c3QgcmV0dXJuIGEgbWF0Y2ggdGhhdCBpcyBhIHByZWZpeCBvZiB0aGUgYnVmZmVyLiBSZWNlaXZlZDogXCIke21hdGNofVwiIGV4cGVjdGVkIHRvIHN0YXJ0IHdpdGggXCIke2J1ZmZlcn1cImAsXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBtYXRjaDtcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IGNodW5raW5nUmVnZXggPVxuICAgICAgdHlwZW9mIGNodW5raW5nID09PSAnc3RyaW5nJyA/IENIVU5LSU5HX1JFR0VYUFNbY2h1bmtpbmddIDogY2h1bmtpbmc7XG5cbiAgICBpZiAoY2h1bmtpbmdSZWdleCA9PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3Ioe1xuICAgICAgICBhcmd1bWVudDogJ2NodW5raW5nJyxcbiAgICAgICAgbWVzc2FnZTogYENodW5raW5nIG11c3QgYmUgXCJ3b3JkXCIgb3IgXCJsaW5lXCIgb3IgYSBSZWdFeHAuIFJlY2VpdmVkOiAke2NodW5raW5nfWAsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBkZXRlY3RDaHVuayA9IGJ1ZmZlciA9PiB7XG4gICAgICBjb25zdCBtYXRjaCA9IGNodW5raW5nUmVnZXguZXhlYyhidWZmZXIpO1xuXG4gICAgICBpZiAoIW1hdGNoKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gYnVmZmVyLnNsaWNlKDAsIG1hdGNoLmluZGV4KSArIG1hdGNoPy5bMF07XG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiAoKSA9PiB7XG4gICAgbGV0IGJ1ZmZlciA9ICcnO1xuICAgIGxldCBpZCA9ICcnO1xuXG4gICAgcmV0dXJuIG5ldyBUcmFuc2Zvcm1TdHJlYW08VGV4dFN0cmVhbVBhcnQ8VE9PTFM+LCBUZXh0U3RyZWFtUGFydDxUT09MUz4+KHtcbiAgICAgIGFzeW5jIHRyYW5zZm9ybShjaHVuaywgY29udHJvbGxlcikge1xuICAgICAgICBpZiAoY2h1bmsudHlwZSAhPT0gJ3RleHQtZGVsdGEnKSB7XG4gICAgICAgICAgaWYgKGJ1ZmZlci5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoeyB0eXBlOiAndGV4dC1kZWx0YScsIHRleHQ6IGJ1ZmZlciwgaWQgfSk7XG4gICAgICAgICAgICBidWZmZXIgPSAnJztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoY2h1bmspO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjaHVuay5pZCAhPT0gaWQgJiYgYnVmZmVyLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoeyB0eXBlOiAndGV4dC1kZWx0YScsIHRleHQ6IGJ1ZmZlciwgaWQgfSk7XG4gICAgICAgICAgYnVmZmVyID0gJyc7XG4gICAgICAgIH1cblxuICAgICAgICBidWZmZXIgKz0gY2h1bmsudGV4dDtcbiAgICAgICAgaWQgPSBjaHVuay5pZDtcblxuICAgICAgICBsZXQgbWF0Y2g7XG5cbiAgICAgICAgd2hpbGUgKChtYXRjaCA9IGRldGVjdENodW5rKGJ1ZmZlcikpICE9IG51bGwpIHtcbiAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoeyB0eXBlOiAndGV4dC1kZWx0YScsIHRleHQ6IG1hdGNoLCBpZCB9KTtcbiAgICAgICAgICBidWZmZXIgPSBidWZmZXIuc2xpY2UobWF0Y2gubGVuZ3RoKTtcblxuICAgICAgICAgIGF3YWl0IGRlbGF5KGRlbGF5SW5Ncyk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSk7XG4gIH07XG59XG4iLCAiaW1wb3J0IHsgTGFuZ3VhZ2VNb2RlbFYyQ2FsbE9wdGlvbnMgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcbmltcG9ydCB7IExhbmd1YWdlTW9kZWxNaWRkbGV3YXJlIH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHsgbWVyZ2VPYmplY3RzIH0gZnJvbSAnLi4vdXRpbC9tZXJnZS1vYmplY3RzJztcblxuLyoqXG4gKiBBcHBsaWVzIGRlZmF1bHQgc2V0dGluZ3MgZm9yIGEgbGFuZ3VhZ2UgbW9kZWwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWZhdWx0U2V0dGluZ3NNaWRkbGV3YXJlKHtcbiAgc2V0dGluZ3MsXG59OiB7XG4gIHNldHRpbmdzOiBQYXJ0aWFsPHtcbiAgICBtYXhPdXRwdXRUb2tlbnM/OiBMYW5ndWFnZU1vZGVsVjJDYWxsT3B0aW9uc1snbWF4T3V0cHV0VG9rZW5zJ107XG4gICAgdGVtcGVyYXR1cmU/OiBMYW5ndWFnZU1vZGVsVjJDYWxsT3B0aW9uc1sndGVtcGVyYXR1cmUnXTtcbiAgICBzdG9wU2VxdWVuY2VzPzogTGFuZ3VhZ2VNb2RlbFYyQ2FsbE9wdGlvbnNbJ3N0b3BTZXF1ZW5jZXMnXTtcbiAgICB0b3BQPzogTGFuZ3VhZ2VNb2RlbFYyQ2FsbE9wdGlvbnNbJ3RvcFAnXTtcbiAgICB0b3BLPzogTGFuZ3VhZ2VNb2RlbFYyQ2FsbE9wdGlvbnNbJ3RvcEsnXTtcbiAgICBwcmVzZW5jZVBlbmFsdHk/OiBMYW5ndWFnZU1vZGVsVjJDYWxsT3B0aW9uc1sncHJlc2VuY2VQZW5hbHR5J107XG4gICAgZnJlcXVlbmN5UGVuYWx0eT86IExhbmd1YWdlTW9kZWxWMkNhbGxPcHRpb25zWydmcmVxdWVuY3lQZW5hbHR5J107XG4gICAgcmVzcG9uc2VGb3JtYXQ/OiBMYW5ndWFnZU1vZGVsVjJDYWxsT3B0aW9uc1sncmVzcG9uc2VGb3JtYXQnXTtcbiAgICBzZWVkPzogTGFuZ3VhZ2VNb2RlbFYyQ2FsbE9wdGlvbnNbJ3NlZWQnXTtcbiAgICB0b29scz86IExhbmd1YWdlTW9kZWxWMkNhbGxPcHRpb25zWyd0b29scyddO1xuICAgIHRvb2xDaG9pY2U/OiBMYW5ndWFnZU1vZGVsVjJDYWxsT3B0aW9uc1sndG9vbENob2ljZSddO1xuICAgIGhlYWRlcnM/OiBMYW5ndWFnZU1vZGVsVjJDYWxsT3B0aW9uc1snaGVhZGVycyddO1xuICAgIHByb3ZpZGVyT3B0aW9ucz86IExhbmd1YWdlTW9kZWxWMkNhbGxPcHRpb25zWydwcm92aWRlck9wdGlvbnMnXTtcbiAgfT47XG59KTogTGFuZ3VhZ2VNb2RlbE1pZGRsZXdhcmUge1xuICByZXR1cm4ge1xuICAgIG1pZGRsZXdhcmVWZXJzaW9uOiAndjInLFxuICAgIHRyYW5zZm9ybVBhcmFtczogYXN5bmMgKHsgcGFyYW1zIH0pID0+IHtcbiAgICAgIHJldHVybiBtZXJnZU9iamVjdHMoc2V0dGluZ3MsIHBhcmFtcykgYXMgTGFuZ3VhZ2VNb2RlbFYyQ2FsbE9wdGlvbnM7XG4gICAgfSxcbiAgfTtcbn1cbiIsICIvKipcbiAqIFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBzdGFydCBvZiB0aGUgc2VhcmNoZWRUZXh0IGluIHRoZSB0ZXh0LCBvciBudWxsIGlmIGl0XG4gKiBpcyBub3QgZm91bmQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRQb3RlbnRpYWxTdGFydEluZGV4KFxuICB0ZXh0OiBzdHJpbmcsXG4gIHNlYXJjaGVkVGV4dDogc3RyaW5nLFxuKTogbnVtYmVyIHwgbnVsbCB7XG4gIC8vIFJldHVybiBudWxsIGltbWVkaWF0ZWx5IGlmIHNlYXJjaGVkVGV4dCBpcyBlbXB0eS5cbiAgaWYgKHNlYXJjaGVkVGV4dC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8vIENoZWNrIGlmIHRoZSBzZWFyY2hlZFRleHQgZXhpc3RzIGFzIGEgZGlyZWN0IHN1YnN0cmluZyBvZiB0ZXh0LlxuICBjb25zdCBkaXJlY3RJbmRleCA9IHRleHQuaW5kZXhPZihzZWFyY2hlZFRleHQpO1xuICBpZiAoZGlyZWN0SW5kZXggIT09IC0xKSB7XG4gICAgcmV0dXJuIGRpcmVjdEluZGV4O1xuICB9XG5cbiAgLy8gT3RoZXJ3aXNlLCBsb29rIGZvciB0aGUgbGFyZ2VzdCBzdWZmaXggb2YgXCJ0ZXh0XCIgdGhhdCBtYXRjaGVzXG4gIC8vIGEgcHJlZml4IG9mIFwic2VhcmNoZWRUZXh0XCIuIFdlIGdvIGZyb20gdGhlIGVuZCBvZiB0ZXh0IGlud2FyZC5cbiAgZm9yIChsZXQgaSA9IHRleHQubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBjb25zdCBzdWZmaXggPSB0ZXh0LnN1YnN0cmluZyhpKTtcbiAgICBpZiAoc2VhcmNoZWRUZXh0LnN0YXJ0c1dpdGgoc3VmZml4KSkge1xuICAgICAgcmV0dXJuIGk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG4iLCAiaW1wb3J0IHR5cGUge1xuICBMYW5ndWFnZU1vZGVsVjJDb250ZW50LFxuICBMYW5ndWFnZU1vZGVsVjJTdHJlYW1QYXJ0LFxufSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcbmltcG9ydCB7IExhbmd1YWdlTW9kZWxNaWRkbGV3YXJlIH0gZnJvbSAnLi4vdHlwZXMvbGFuZ3VhZ2UtbW9kZWwtbWlkZGxld2FyZSc7XG5pbXBvcnQgeyBnZXRQb3RlbnRpYWxTdGFydEluZGV4IH0gZnJvbSAnLi4vdXRpbC9nZXQtcG90ZW50aWFsLXN0YXJ0LWluZGV4JztcblxuLyoqXG4gKiBFeHRyYWN0IGFuIFhNTC10YWdnZWQgcmVhc29uaW5nIHNlY3Rpb24gZnJvbSB0aGUgZ2VuZXJhdGVkIHRleHQgYW5kIGV4cG9zZXMgaXRcbiAqIGFzIGEgYHJlYXNvbmluZ2AgcHJvcGVydHkgb24gdGhlIHJlc3VsdC5cbiAqXG4gKiBAcGFyYW0gdGFnTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBYTUwgdGFnIHRvIGV4dHJhY3QgcmVhc29uaW5nIGZyb20uXG4gKiBAcGFyYW0gc2VwYXJhdG9yIC0gVGhlIHNlcGFyYXRvciB0byB1c2UgYmV0d2VlbiByZWFzb25pbmcgYW5kIHRleHQgc2VjdGlvbnMuXG4gKiBAcGFyYW0gc3RhcnRXaXRoUmVhc29uaW5nIC0gV2hldGhlciB0byBzdGFydCB3aXRoIHJlYXNvbmluZyB0b2tlbnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBleHRyYWN0UmVhc29uaW5nTWlkZGxld2FyZSh7XG4gIHRhZ05hbWUsXG4gIHNlcGFyYXRvciA9ICdcXG4nLFxuICBzdGFydFdpdGhSZWFzb25pbmcgPSBmYWxzZSxcbn06IHtcbiAgdGFnTmFtZTogc3RyaW5nO1xuICBzZXBhcmF0b3I/OiBzdHJpbmc7XG4gIHN0YXJ0V2l0aFJlYXNvbmluZz86IGJvb2xlYW47XG59KTogTGFuZ3VhZ2VNb2RlbE1pZGRsZXdhcmUge1xuICBjb25zdCBvcGVuaW5nVGFnID0gYDwke3RhZ05hbWV9PmA7XG4gIGNvbnN0IGNsb3NpbmdUYWcgPSBgPFxcLyR7dGFnTmFtZX0+YDtcblxuICByZXR1cm4ge1xuICAgIG1pZGRsZXdhcmVWZXJzaW9uOiAndjInLFxuICAgIHdyYXBHZW5lcmF0ZTogYXN5bmMgKHsgZG9HZW5lcmF0ZSB9KSA9PiB7XG4gICAgICBjb25zdCB7IGNvbnRlbnQsIC4uLnJlc3QgfSA9IGF3YWl0IGRvR2VuZXJhdGUoKTtcblxuICAgICAgY29uc3QgdHJhbnNmb3JtZWRDb250ZW50OiBMYW5ndWFnZU1vZGVsVjJDb250ZW50W10gPSBbXTtcbiAgICAgIGZvciAoY29uc3QgcGFydCBvZiBjb250ZW50KSB7XG4gICAgICAgIGlmIChwYXJ0LnR5cGUgIT09ICd0ZXh0Jykge1xuICAgICAgICAgIHRyYW5zZm9ybWVkQ29udGVudC5wdXNoKHBhcnQpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdGV4dCA9IHN0YXJ0V2l0aFJlYXNvbmluZyA/IG9wZW5pbmdUYWcgKyBwYXJ0LnRleHQgOiBwYXJ0LnRleHQ7XG5cbiAgICAgICAgY29uc3QgcmVnZXhwID0gbmV3IFJlZ0V4cChgJHtvcGVuaW5nVGFnfSguKj8pJHtjbG9zaW5nVGFnfWAsICdncycpO1xuICAgICAgICBjb25zdCBtYXRjaGVzID0gQXJyYXkuZnJvbSh0ZXh0Lm1hdGNoQWxsKHJlZ2V4cCkpO1xuXG4gICAgICAgIGlmICghbWF0Y2hlcy5sZW5ndGgpIHtcbiAgICAgICAgICB0cmFuc2Zvcm1lZENvbnRlbnQucHVzaChwYXJ0KTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlYXNvbmluZ1RleHQgPSBtYXRjaGVzLm1hcChtYXRjaCA9PiBtYXRjaFsxXSkuam9pbihzZXBhcmF0b3IpO1xuXG4gICAgICAgIGxldCB0ZXh0V2l0aG91dFJlYXNvbmluZyA9IHRleHQ7XG4gICAgICAgIGZvciAobGV0IGkgPSBtYXRjaGVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgY29uc3QgbWF0Y2ggPSBtYXRjaGVzW2ldO1xuXG4gICAgICAgICAgY29uc3QgYmVmb3JlTWF0Y2ggPSB0ZXh0V2l0aG91dFJlYXNvbmluZy5zbGljZSgwLCBtYXRjaC5pbmRleCk7XG4gICAgICAgICAgY29uc3QgYWZ0ZXJNYXRjaCA9IHRleHRXaXRob3V0UmVhc29uaW5nLnNsaWNlKFxuICAgICAgICAgICAgbWF0Y2guaW5kZXghICsgbWF0Y2hbMF0ubGVuZ3RoLFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICB0ZXh0V2l0aG91dFJlYXNvbmluZyA9XG4gICAgICAgICAgICBiZWZvcmVNYXRjaCArXG4gICAgICAgICAgICAoYmVmb3JlTWF0Y2gubGVuZ3RoID4gMCAmJiBhZnRlck1hdGNoLmxlbmd0aCA+IDAgPyBzZXBhcmF0b3IgOiAnJykgK1xuICAgICAgICAgICAgYWZ0ZXJNYXRjaDtcbiAgICAgICAgfVxuXG4gICAgICAgIHRyYW5zZm9ybWVkQ29udGVudC5wdXNoKHtcbiAgICAgICAgICB0eXBlOiAncmVhc29uaW5nJyxcbiAgICAgICAgICB0ZXh0OiByZWFzb25pbmdUZXh0LFxuICAgICAgICB9KTtcblxuICAgICAgICB0cmFuc2Zvcm1lZENvbnRlbnQucHVzaCh7XG4gICAgICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgICAgIHRleHQ6IHRleHRXaXRob3V0UmVhc29uaW5nLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHsgY29udGVudDogdHJhbnNmb3JtZWRDb250ZW50LCAuLi5yZXN0IH07XG4gICAgfSxcblxuICAgIHdyYXBTdHJlYW06IGFzeW5jICh7IGRvU3RyZWFtIH0pID0+IHtcbiAgICAgIGNvbnN0IHsgc3RyZWFtLCAuLi5yZXN0IH0gPSBhd2FpdCBkb1N0cmVhbSgpO1xuXG4gICAgICBjb25zdCByZWFzb25pbmdFeHRyYWN0aW9uczogUmVjb3JkPFxuICAgICAgICBzdHJpbmcsXG4gICAgICAgIHtcbiAgICAgICAgICBpc0ZpcnN0UmVhc29uaW5nOiBib29sZWFuO1xuICAgICAgICAgIGlzRmlyc3RUZXh0OiBib29sZWFuO1xuICAgICAgICAgIGFmdGVyU3dpdGNoOiBib29sZWFuO1xuICAgICAgICAgIGlzUmVhc29uaW5nOiBib29sZWFuO1xuICAgICAgICAgIGJ1ZmZlcjogc3RyaW5nO1xuICAgICAgICAgIGlkQ291bnRlcjogbnVtYmVyO1xuICAgICAgICAgIHRleHRJZDogc3RyaW5nO1xuICAgICAgICB9XG4gICAgICA+ID0ge307XG5cbiAgICAgIGxldCBkZWxheWVkVGV4dFN0YXJ0OiBMYW5ndWFnZU1vZGVsVjJTdHJlYW1QYXJ0IHwgdW5kZWZpbmVkO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBzdHJlYW06IHN0cmVhbS5waXBlVGhyb3VnaChcbiAgICAgICAgICBuZXcgVHJhbnNmb3JtU3RyZWFtPFxuICAgICAgICAgICAgTGFuZ3VhZ2VNb2RlbFYyU3RyZWFtUGFydCxcbiAgICAgICAgICAgIExhbmd1YWdlTW9kZWxWMlN0cmVhbVBhcnRcbiAgICAgICAgICA+KHtcbiAgICAgICAgICAgIHRyYW5zZm9ybTogKGNodW5rLCBjb250cm9sbGVyKSA9PiB7XG4gICAgICAgICAgICAgIC8vIGRvIG5vdCBzZW5kIGB0ZXh0LXN0YXJ0YCBiZWZvcmUgYHJlYXNvbmluZy1zdGFydGBcbiAgICAgICAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL3ZlcmNlbC9haS9pc3N1ZXMvNzc3NFxuICAgICAgICAgICAgICBpZiAoY2h1bmsudHlwZSA9PT0gJ3RleHQtc3RhcnQnKSB7XG4gICAgICAgICAgICAgICAgZGVsYXllZFRleHRTdGFydCA9IGNodW5rO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmIChjaHVuay50eXBlID09PSAndGV4dC1lbmQnICYmIGRlbGF5ZWRUZXh0U3RhcnQpIHtcbiAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoZGVsYXllZFRleHRTdGFydCk7XG4gICAgICAgICAgICAgICAgZGVsYXllZFRleHRTdGFydCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmIChjaHVuay50eXBlICE9PSAndGV4dC1kZWx0YScpIHtcbiAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoY2h1bmspO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmIChyZWFzb25pbmdFeHRyYWN0aW9uc1tjaHVuay5pZF0gPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJlYXNvbmluZ0V4dHJhY3Rpb25zW2NodW5rLmlkXSA9IHtcbiAgICAgICAgICAgICAgICAgIGlzRmlyc3RSZWFzb25pbmc6IHRydWUsXG4gICAgICAgICAgICAgICAgICBpc0ZpcnN0VGV4dDogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgIGFmdGVyU3dpdGNoOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgIGlzUmVhc29uaW5nOiBzdGFydFdpdGhSZWFzb25pbmcsXG4gICAgICAgICAgICAgICAgICBidWZmZXI6ICcnLFxuICAgICAgICAgICAgICAgICAgaWRDb3VudGVyOiAwLFxuICAgICAgICAgICAgICAgICAgdGV4dElkOiBjaHVuay5pZCxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgY29uc3QgYWN0aXZlRXh0cmFjdGlvbiA9IHJlYXNvbmluZ0V4dHJhY3Rpb25zW2NodW5rLmlkXTtcblxuICAgICAgICAgICAgICBhY3RpdmVFeHRyYWN0aW9uLmJ1ZmZlciArPSBjaHVuay5kZWx0YTtcblxuICAgICAgICAgICAgICBmdW5jdGlvbiBwdWJsaXNoKHRleHQ6IHN0cmluZykge1xuICAgICAgICAgICAgICAgIGlmICh0ZXh0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHByZWZpeCA9XG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZUV4dHJhY3Rpb24uYWZ0ZXJTd2l0Y2ggJiZcbiAgICAgICAgICAgICAgICAgICAgKGFjdGl2ZUV4dHJhY3Rpb24uaXNSZWFzb25pbmdcbiAgICAgICAgICAgICAgICAgICAgICA/ICFhY3RpdmVFeHRyYWN0aW9uLmlzRmlyc3RSZWFzb25pbmdcbiAgICAgICAgICAgICAgICAgICAgICA6ICFhY3RpdmVFeHRyYWN0aW9uLmlzRmlyc3RUZXh0KVxuICAgICAgICAgICAgICAgICAgICAgID8gc2VwYXJhdG9yXG4gICAgICAgICAgICAgICAgICAgICAgOiAnJztcblxuICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICBhY3RpdmVFeHRyYWN0aW9uLmlzUmVhc29uaW5nICYmXG4gICAgICAgICAgICAgICAgICAgIChhY3RpdmVFeHRyYWN0aW9uLmFmdGVyU3dpdGNoIHx8XG4gICAgICAgICAgICAgICAgICAgICAgYWN0aXZlRXh0cmFjdGlvbi5pc0ZpcnN0UmVhc29uaW5nKVxuICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3JlYXNvbmluZy1zdGFydCcsXG4gICAgICAgICAgICAgICAgICAgICAgaWQ6IGByZWFzb25pbmctJHthY3RpdmVFeHRyYWN0aW9uLmlkQ291bnRlcn1gLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgaWYgKGFjdGl2ZUV4dHJhY3Rpb24uaXNSZWFzb25pbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHtcbiAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAncmVhc29uaW5nLWRlbHRhJyxcbiAgICAgICAgICAgICAgICAgICAgICBkZWx0YTogcHJlZml4ICsgdGV4dCxcbiAgICAgICAgICAgICAgICAgICAgICBpZDogYHJlYXNvbmluZy0ke2FjdGl2ZUV4dHJhY3Rpb24uaWRDb3VudGVyfWAsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRlbGF5ZWRUZXh0U3RhcnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoZGVsYXllZFRleHRTdGFydCk7XG4gICAgICAgICAgICAgICAgICAgICAgZGVsYXllZFRleHRTdGFydCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICd0ZXh0LWRlbHRhJyxcbiAgICAgICAgICAgICAgICAgICAgICBkZWx0YTogcHJlZml4ICsgdGV4dCxcbiAgICAgICAgICAgICAgICAgICAgICBpZDogYWN0aXZlRXh0cmFjdGlvbi50ZXh0SWQsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgYWN0aXZlRXh0cmFjdGlvbi5hZnRlclN3aXRjaCA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgICBpZiAoYWN0aXZlRXh0cmFjdGlvbi5pc1JlYXNvbmluZykge1xuICAgICAgICAgICAgICAgICAgICBhY3RpdmVFeHRyYWN0aW9uLmlzRmlyc3RSZWFzb25pbmcgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZUV4dHJhY3Rpb24uaXNGaXJzdFRleHQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBkbyB7XG4gICAgICAgICAgICAgICAgY29uc3QgbmV4dFRhZyA9IGFjdGl2ZUV4dHJhY3Rpb24uaXNSZWFzb25pbmdcbiAgICAgICAgICAgICAgICAgID8gY2xvc2luZ1RhZ1xuICAgICAgICAgICAgICAgICAgOiBvcGVuaW5nVGFnO1xuXG4gICAgICAgICAgICAgICAgY29uc3Qgc3RhcnRJbmRleCA9IGdldFBvdGVudGlhbFN0YXJ0SW5kZXgoXG4gICAgICAgICAgICAgICAgICBhY3RpdmVFeHRyYWN0aW9uLmJ1ZmZlcixcbiAgICAgICAgICAgICAgICAgIG5leHRUYWcsXG4gICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgIC8vIG5vIG9wZW5pbmcgb3IgY2xvc2luZyB0YWcgZm91bmQsIHB1Ymxpc2ggdGhlIGJ1ZmZlclxuICAgICAgICAgICAgICAgIGlmIChzdGFydEluZGV4ID09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgIHB1Ymxpc2goYWN0aXZlRXh0cmFjdGlvbi5idWZmZXIpO1xuICAgICAgICAgICAgICAgICAgYWN0aXZlRXh0cmFjdGlvbi5idWZmZXIgPSAnJztcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIHB1Ymxpc2ggdGV4dCBiZWZvcmUgdGhlIHRhZ1xuICAgICAgICAgICAgICAgIHB1Ymxpc2goYWN0aXZlRXh0cmFjdGlvbi5idWZmZXIuc2xpY2UoMCwgc3RhcnRJbmRleCkpO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgZm91bmRGdWxsTWF0Y2ggPVxuICAgICAgICAgICAgICAgICAgc3RhcnRJbmRleCArIG5leHRUYWcubGVuZ3RoIDw9IGFjdGl2ZUV4dHJhY3Rpb24uYnVmZmVyLmxlbmd0aDtcblxuICAgICAgICAgICAgICAgIGlmIChmb3VuZEZ1bGxNYXRjaCkge1xuICAgICAgICAgICAgICAgICAgYWN0aXZlRXh0cmFjdGlvbi5idWZmZXIgPSBhY3RpdmVFeHRyYWN0aW9uLmJ1ZmZlci5zbGljZShcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRJbmRleCArIG5leHRUYWcubGVuZ3RoLFxuICAgICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgICAgLy8gcmVhc29uaW5nIHBhcnQgZmluaXNoZWQ6XG4gICAgICAgICAgICAgICAgICBpZiAoYWN0aXZlRXh0cmFjdGlvbi5pc1JlYXNvbmluZykge1xuICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdyZWFzb25pbmctZW5kJyxcbiAgICAgICAgICAgICAgICAgICAgICBpZDogYHJlYXNvbmluZy0ke2FjdGl2ZUV4dHJhY3Rpb24uaWRDb3VudGVyKyt9YCxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgIGFjdGl2ZUV4dHJhY3Rpb24uaXNSZWFzb25pbmcgPSAhYWN0aXZlRXh0cmFjdGlvbi5pc1JlYXNvbmluZztcbiAgICAgICAgICAgICAgICAgIGFjdGl2ZUV4dHJhY3Rpb24uYWZ0ZXJTd2l0Y2ggPSB0cnVlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBhY3RpdmVFeHRyYWN0aW9uLmJ1ZmZlciA9XG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZUV4dHJhY3Rpb24uYnVmZmVyLnNsaWNlKHN0YXJ0SW5kZXgpO1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IHdoaWxlICh0cnVlKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSksXG4gICAgICAgICksXG4gICAgICAgIC4uLnJlc3QsXG4gICAgICB9O1xuICAgIH0sXG4gIH07XG59XG4iLCAiaW1wb3J0IHR5cGUgeyBMYW5ndWFnZU1vZGVsVjJTdHJlYW1QYXJ0IH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQgeyBMYW5ndWFnZU1vZGVsTWlkZGxld2FyZSB9IGZyb20gJy4uL3R5cGVzJztcblxuLyoqXG4gKiBTaW11bGF0ZXMgc3RyZWFtaW5nIGNodW5rcyB3aXRoIHRoZSByZXNwb25zZSBmcm9tIGEgZ2VuZXJhdGUgY2FsbC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNpbXVsYXRlU3RyZWFtaW5nTWlkZGxld2FyZSgpOiBMYW5ndWFnZU1vZGVsTWlkZGxld2FyZSB7XG4gIHJldHVybiB7XG4gICAgbWlkZGxld2FyZVZlcnNpb246ICd2MicsXG4gICAgd3JhcFN0cmVhbTogYXN5bmMgKHsgZG9HZW5lcmF0ZSB9KSA9PiB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBkb0dlbmVyYXRlKCk7XG5cbiAgICAgIGxldCBpZCA9IDA7XG5cbiAgICAgIGNvbnN0IHNpbXVsYXRlZFN0cmVhbSA9IG5ldyBSZWFkYWJsZVN0cmVhbTxMYW5ndWFnZU1vZGVsVjJTdHJlYW1QYXJ0Pih7XG4gICAgICAgIHN0YXJ0KGNvbnRyb2xsZXIpIHtcbiAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgdHlwZTogJ3N0cmVhbS1zdGFydCcsXG4gICAgICAgICAgICB3YXJuaW5nczogcmVzdWx0Lndhcm5pbmdzLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHsgdHlwZTogJ3Jlc3BvbnNlLW1ldGFkYXRhJywgLi4ucmVzdWx0LnJlc3BvbnNlIH0pO1xuXG4gICAgICAgICAgZm9yIChjb25zdCBwYXJ0IG9mIHJlc3VsdC5jb250ZW50KSB7XG4gICAgICAgICAgICBzd2l0Y2ggKHBhcnQudHlwZSkge1xuICAgICAgICAgICAgICBjYXNlICd0ZXh0Jzoge1xuICAgICAgICAgICAgICAgIGlmIChwYXJ0LnRleHQubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHsgdHlwZTogJ3RleHQtc3RhcnQnLCBpZDogU3RyaW5nKGlkKSB9KTtcbiAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICd0ZXh0LWRlbHRhJyxcbiAgICAgICAgICAgICAgICAgICAgaWQ6IFN0cmluZyhpZCksXG4gICAgICAgICAgICAgICAgICAgIGRlbHRhOiBwYXJ0LnRleHQsXG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7IHR5cGU6ICd0ZXh0LWVuZCcsIGlkOiBTdHJpbmcoaWQpIH0pO1xuICAgICAgICAgICAgICAgICAgaWQrKztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgY2FzZSAncmVhc29uaW5nJzoge1xuICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgICAgICB0eXBlOiAncmVhc29uaW5nLXN0YXJ0JyxcbiAgICAgICAgICAgICAgICAgIGlkOiBTdHJpbmcoaWQpLFxuICAgICAgICAgICAgICAgICAgcHJvdmlkZXJNZXRhZGF0YTogcGFydC5wcm92aWRlck1ldGFkYXRhLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgICAgICB0eXBlOiAncmVhc29uaW5nLWRlbHRhJyxcbiAgICAgICAgICAgICAgICAgIGlkOiBTdHJpbmcoaWQpLFxuICAgICAgICAgICAgICAgICAgZGVsdGE6IHBhcnQudGV4dCxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoeyB0eXBlOiAncmVhc29uaW5nLWVuZCcsIGlkOiBTdHJpbmcoaWQpIH0pO1xuICAgICAgICAgICAgICAgIGlkKys7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShwYXJ0KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICB0eXBlOiAnZmluaXNoJyxcbiAgICAgICAgICAgIGZpbmlzaFJlYXNvbjogcmVzdWx0LmZpbmlzaFJlYXNvbixcbiAgICAgICAgICAgIHVzYWdlOiByZXN1bHQudXNhZ2UsXG4gICAgICAgICAgICBwcm92aWRlck1ldGFkYXRhOiByZXN1bHQucHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNvbnRyb2xsZXIuY2xvc2UoKTtcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBzdHJlYW06IHNpbXVsYXRlZFN0cmVhbSxcbiAgICAgICAgcmVxdWVzdDogcmVzdWx0LnJlcXVlc3QsXG4gICAgICAgIHJlc3BvbnNlOiByZXN1bHQucmVzcG9uc2UsXG4gICAgICB9O1xuICAgIH0sXG4gIH07XG59XG4iLCAiaW1wb3J0IHsgTGFuZ3VhZ2VNb2RlbFYyLCBMYW5ndWFnZU1vZGVsVjJDYWxsT3B0aW9ucyB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgTGFuZ3VhZ2VNb2RlbE1pZGRsZXdhcmUgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgeyBhc0FycmF5IH0gZnJvbSAnLi4vdXRpbC9hcy1hcnJheSc7XG5cbi8qKlxuICogV3JhcHMgYSBMYW5ndWFnZU1vZGVsVjIgaW5zdGFuY2Ugd2l0aCBtaWRkbGV3YXJlIGZ1bmN0aW9uYWxpdHkuXG4gKiBUaGlzIGZ1bmN0aW9uIGFsbG93cyB5b3UgdG8gYXBwbHkgbWlkZGxld2FyZSB0byB0cmFuc2Zvcm0gcGFyYW1ldGVycyxcbiAqIHdyYXAgZ2VuZXJhdGUgb3BlcmF0aW9ucywgYW5kIHdyYXAgc3RyZWFtIG9wZXJhdGlvbnMgb2YgYSBsYW5ndWFnZSBtb2RlbC5cbiAqXG4gKiBAcGFyYW0gb3B0aW9ucyAtIENvbmZpZ3VyYXRpb24gb3B0aW9ucyBmb3Igd3JhcHBpbmcgdGhlIGxhbmd1YWdlIG1vZGVsLlxuICogQHBhcmFtIG9wdGlvbnMubW9kZWwgLSBUaGUgb3JpZ2luYWwgTGFuZ3VhZ2VNb2RlbFYyIGluc3RhbmNlIHRvIGJlIHdyYXBwZWQuXG4gKiBAcGFyYW0gb3B0aW9ucy5taWRkbGV3YXJlIC0gVGhlIG1pZGRsZXdhcmUgdG8gYmUgYXBwbGllZCB0byB0aGUgbGFuZ3VhZ2UgbW9kZWwuIFdoZW4gbXVsdGlwbGUgbWlkZGxld2FyZXMgYXJlIHByb3ZpZGVkLCB0aGUgZmlyc3QgbWlkZGxld2FyZSB3aWxsIHRyYW5zZm9ybSB0aGUgaW5wdXQgZmlyc3QsIGFuZCB0aGUgbGFzdCBtaWRkbGV3YXJlIHdpbGwgYmUgd3JhcHBlZCBkaXJlY3RseSBhcm91bmQgdGhlIG1vZGVsLlxuICogQHBhcmFtIG9wdGlvbnMubW9kZWxJZCAtIE9wdGlvbmFsIGN1c3RvbSBtb2RlbCBJRCB0byBvdmVycmlkZSB0aGUgb3JpZ2luYWwgbW9kZWwncyBJRC5cbiAqIEBwYXJhbSBvcHRpb25zLnByb3ZpZGVySWQgLSBPcHRpb25hbCBjdXN0b20gcHJvdmlkZXIgSUQgdG8gb3ZlcnJpZGUgdGhlIG9yaWdpbmFsIG1vZGVsJ3MgcHJvdmlkZXIgSUQuXG4gKiBAcmV0dXJucyBBIG5ldyBMYW5ndWFnZU1vZGVsVjIgaW5zdGFuY2Ugd2l0aCBtaWRkbGV3YXJlIGFwcGxpZWQuXG4gKi9cbmV4cG9ydCBjb25zdCB3cmFwTGFuZ3VhZ2VNb2RlbCA9ICh7XG4gIG1vZGVsLFxuICBtaWRkbGV3YXJlOiBtaWRkbGV3YXJlQXJnLFxuICBtb2RlbElkLFxuICBwcm92aWRlcklkLFxufToge1xuICBtb2RlbDogTGFuZ3VhZ2VNb2RlbFYyO1xuICBtaWRkbGV3YXJlOiBMYW5ndWFnZU1vZGVsTWlkZGxld2FyZSB8IExhbmd1YWdlTW9kZWxNaWRkbGV3YXJlW107XG4gIG1vZGVsSWQ/OiBzdHJpbmc7XG4gIHByb3ZpZGVySWQ/OiBzdHJpbmc7XG59KTogTGFuZ3VhZ2VNb2RlbFYyID0+IHtcbiAgcmV0dXJuIGFzQXJyYXkobWlkZGxld2FyZUFyZylcbiAgICAucmV2ZXJzZSgpXG4gICAgLnJlZHVjZSgod3JhcHBlZE1vZGVsLCBtaWRkbGV3YXJlKSA9PiB7XG4gICAgICByZXR1cm4gZG9XcmFwKHsgbW9kZWw6IHdyYXBwZWRNb2RlbCwgbWlkZGxld2FyZSwgbW9kZWxJZCwgcHJvdmlkZXJJZCB9KTtcbiAgICB9LCBtb2RlbCk7XG59O1xuXG5jb25zdCBkb1dyYXAgPSAoe1xuICBtb2RlbCxcbiAgbWlkZGxld2FyZToge1xuICAgIHRyYW5zZm9ybVBhcmFtcyxcbiAgICB3cmFwR2VuZXJhdGUsXG4gICAgd3JhcFN0cmVhbSxcbiAgICBvdmVycmlkZVByb3ZpZGVyLFxuICAgIG92ZXJyaWRlTW9kZWxJZCxcbiAgICBvdmVycmlkZVN1cHBvcnRlZFVybHMsXG4gIH0sXG4gIG1vZGVsSWQsXG4gIHByb3ZpZGVySWQsXG59OiB7XG4gIG1vZGVsOiBMYW5ndWFnZU1vZGVsVjI7XG4gIG1pZGRsZXdhcmU6IExhbmd1YWdlTW9kZWxNaWRkbGV3YXJlO1xuICBtb2RlbElkPzogc3RyaW5nO1xuICBwcm92aWRlcklkPzogc3RyaW5nO1xufSk6IExhbmd1YWdlTW9kZWxWMiA9PiB7XG4gIGFzeW5jIGZ1bmN0aW9uIGRvVHJhbnNmb3JtKHtcbiAgICBwYXJhbXMsXG4gICAgdHlwZSxcbiAgfToge1xuICAgIHBhcmFtczogTGFuZ3VhZ2VNb2RlbFYyQ2FsbE9wdGlvbnM7XG4gICAgdHlwZTogJ2dlbmVyYXRlJyB8ICdzdHJlYW0nO1xuICB9KSB7XG4gICAgcmV0dXJuIHRyYW5zZm9ybVBhcmFtc1xuICAgICAgPyBhd2FpdCB0cmFuc2Zvcm1QYXJhbXMoeyBwYXJhbXMsIHR5cGUsIG1vZGVsIH0pXG4gICAgICA6IHBhcmFtcztcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgc3BlY2lmaWNhdGlvblZlcnNpb246ICd2MicsXG5cbiAgICBwcm92aWRlcjogcHJvdmlkZXJJZCA/PyBvdmVycmlkZVByb3ZpZGVyPy4oeyBtb2RlbCB9KSA/PyBtb2RlbC5wcm92aWRlcixcbiAgICBtb2RlbElkOiBtb2RlbElkID8/IG92ZXJyaWRlTW9kZWxJZD8uKHsgbW9kZWwgfSkgPz8gbW9kZWwubW9kZWxJZCxcbiAgICBzdXBwb3J0ZWRVcmxzOiBvdmVycmlkZVN1cHBvcnRlZFVybHM/Lih7IG1vZGVsIH0pID8/IG1vZGVsLnN1cHBvcnRlZFVybHMsXG5cbiAgICBhc3luYyBkb0dlbmVyYXRlKFxuICAgICAgcGFyYW1zOiBMYW5ndWFnZU1vZGVsVjJDYWxsT3B0aW9ucyxcbiAgICApOiBQcm9taXNlPEF3YWl0ZWQ8UmV0dXJuVHlwZTxMYW5ndWFnZU1vZGVsVjJbJ2RvR2VuZXJhdGUnXT4+PiB7XG4gICAgICBjb25zdCB0cmFuc2Zvcm1lZFBhcmFtcyA9IGF3YWl0IGRvVHJhbnNmb3JtKHsgcGFyYW1zLCB0eXBlOiAnZ2VuZXJhdGUnIH0pO1xuICAgICAgY29uc3QgZG9HZW5lcmF0ZSA9IGFzeW5jICgpID0+IG1vZGVsLmRvR2VuZXJhdGUodHJhbnNmb3JtZWRQYXJhbXMpO1xuICAgICAgY29uc3QgZG9TdHJlYW0gPSBhc3luYyAoKSA9PiBtb2RlbC5kb1N0cmVhbSh0cmFuc2Zvcm1lZFBhcmFtcyk7XG4gICAgICByZXR1cm4gd3JhcEdlbmVyYXRlXG4gICAgICAgID8gd3JhcEdlbmVyYXRlKHtcbiAgICAgICAgICAgIGRvR2VuZXJhdGUsXG4gICAgICAgICAgICBkb1N0cmVhbSxcbiAgICAgICAgICAgIHBhcmFtczogdHJhbnNmb3JtZWRQYXJhbXMsXG4gICAgICAgICAgICBtb2RlbCxcbiAgICAgICAgICB9KVxuICAgICAgICA6IGRvR2VuZXJhdGUoKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZG9TdHJlYW0oXG4gICAgICBwYXJhbXM6IExhbmd1YWdlTW9kZWxWMkNhbGxPcHRpb25zLFxuICAgICk6IFByb21pc2U8QXdhaXRlZDxSZXR1cm5UeXBlPExhbmd1YWdlTW9kZWxWMlsnZG9TdHJlYW0nXT4+PiB7XG4gICAgICBjb25zdCB0cmFuc2Zvcm1lZFBhcmFtcyA9IGF3YWl0IGRvVHJhbnNmb3JtKHsgcGFyYW1zLCB0eXBlOiAnc3RyZWFtJyB9KTtcbiAgICAgIGNvbnN0IGRvR2VuZXJhdGUgPSBhc3luYyAoKSA9PiBtb2RlbC5kb0dlbmVyYXRlKHRyYW5zZm9ybWVkUGFyYW1zKTtcbiAgICAgIGNvbnN0IGRvU3RyZWFtID0gYXN5bmMgKCkgPT4gbW9kZWwuZG9TdHJlYW0odHJhbnNmb3JtZWRQYXJhbXMpO1xuICAgICAgcmV0dXJuIHdyYXBTdHJlYW1cbiAgICAgICAgPyB3cmFwU3RyZWFtKHsgZG9HZW5lcmF0ZSwgZG9TdHJlYW0sIHBhcmFtczogdHJhbnNmb3JtZWRQYXJhbXMsIG1vZGVsIH0pXG4gICAgICAgIDogZG9TdHJlYW0oKTtcbiAgICB9LFxuICB9O1xufTtcbiIsICJpbXBvcnQgdHlwZSB7IFByb3ZpZGVyVjIgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcbmltcG9ydCB7IExhbmd1YWdlTW9kZWxNaWRkbGV3YXJlIH0gZnJvbSAnLi4vdHlwZXMvbGFuZ3VhZ2UtbW9kZWwtbWlkZGxld2FyZSc7XG5pbXBvcnQgeyB3cmFwTGFuZ3VhZ2VNb2RlbCB9IGZyb20gJy4vd3JhcC1sYW5ndWFnZS1tb2RlbCc7XG5cbi8qKlxuICogV3JhcHMgYSBQcm92aWRlclYyIGluc3RhbmNlIHdpdGggbWlkZGxld2FyZSBmdW5jdGlvbmFsaXR5LlxuICogVGhpcyBmdW5jdGlvbiBhbGxvd3MgeW91IHRvIGFwcGx5IG1pZGRsZXdhcmUgdG8gYWxsIGxhbmd1YWdlIG1vZGVsc1xuICogZnJvbSB0aGUgcHJvdmlkZXIsIGVuYWJsaW5nIHlvdSB0byB0cmFuc2Zvcm0gcGFyYW1ldGVycywgd3JhcCBnZW5lcmF0ZVxuICogb3BlcmF0aW9ucywgYW5kIHdyYXAgc3RyZWFtIG9wZXJhdGlvbnMgZm9yIGV2ZXJ5IGxhbmd1YWdlIG1vZGVsLlxuICpcbiAqIEBwYXJhbSBvcHRpb25zIC0gQ29uZmlndXJhdGlvbiBvcHRpb25zIGZvciB3cmFwcGluZyB0aGUgcHJvdmlkZXIuXG4gKiBAcGFyYW0gb3B0aW9ucy5wcm92aWRlciAtIFRoZSBvcmlnaW5hbCBQcm92aWRlclYyIGluc3RhbmNlIHRvIGJlIHdyYXBwZWQuXG4gKiBAcGFyYW0gb3B0aW9ucy5sYW5ndWFnZU1vZGVsTWlkZGxld2FyZSAtIFRoZSBtaWRkbGV3YXJlIHRvIGJlIGFwcGxpZWQgdG8gYWxsIGxhbmd1YWdlIG1vZGVscyBmcm9tIHRoZSBwcm92aWRlci4gV2hlbiBtdWx0aXBsZSBtaWRkbGV3YXJlcyBhcmUgcHJvdmlkZWQsIHRoZSBmaXJzdCBtaWRkbGV3YXJlIHdpbGwgdHJhbnNmb3JtIHRoZSBpbnB1dCBmaXJzdCwgYW5kIHRoZSBsYXN0IG1pZGRsZXdhcmUgd2lsbCBiZSB3cmFwcGVkIGRpcmVjdGx5IGFyb3VuZCB0aGUgbW9kZWwuXG4gKiBAcmV0dXJucyBBIG5ldyBQcm92aWRlclYyIGluc3RhbmNlIHdpdGggbWlkZGxld2FyZSBhcHBsaWVkIHRvIGFsbCBsYW5ndWFnZSBtb2RlbHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3cmFwUHJvdmlkZXIoe1xuICBwcm92aWRlcixcbiAgbGFuZ3VhZ2VNb2RlbE1pZGRsZXdhcmUsXG59OiB7XG4gIHByb3ZpZGVyOiBQcm92aWRlclYyO1xuICBsYW5ndWFnZU1vZGVsTWlkZGxld2FyZTogTGFuZ3VhZ2VNb2RlbE1pZGRsZXdhcmUgfCBMYW5ndWFnZU1vZGVsTWlkZGxld2FyZVtdO1xufSk6IFByb3ZpZGVyVjIge1xuICBjb25zdCB3cmFwcGVkUHJvdmlkZXIgPSB7XG4gICAgbGFuZ3VhZ2VNb2RlbChtb2RlbElkOiBzdHJpbmcpIHtcbiAgICAgIGxldCBtb2RlbCA9IHByb3ZpZGVyLmxhbmd1YWdlTW9kZWwobW9kZWxJZCk7XG4gICAgICBtb2RlbCA9IHdyYXBMYW5ndWFnZU1vZGVsKHtcbiAgICAgICAgbW9kZWwsXG4gICAgICAgIG1pZGRsZXdhcmU6IGxhbmd1YWdlTW9kZWxNaWRkbGV3YXJlLFxuICAgICAgfSk7XG4gICAgICByZXR1cm4gbW9kZWw7XG4gICAgfSxcbiAgICB0ZXh0RW1iZWRkaW5nTW9kZWw6IHByb3ZpZGVyLnRleHRFbWJlZGRpbmdNb2RlbCxcbiAgICBpbWFnZU1vZGVsOiBwcm92aWRlci5pbWFnZU1vZGVsLFxuICAgIHRyYW5zY3JpcHRpb25Nb2RlbDogcHJvdmlkZXIudHJhbnNjcmlwdGlvbk1vZGVsLFxuICAgIHNwZWVjaE1vZGVsOiBwcm92aWRlci5zcGVlY2hNb2RlbCxcbiAgfTtcblxuICByZXR1cm4gd3JhcHBlZFByb3ZpZGVyO1xufVxuIiwgImltcG9ydCB7XG4gIEVtYmVkZGluZ01vZGVsVjIsXG4gIEltYWdlTW9kZWxWMixcbiAgTGFuZ3VhZ2VNb2RlbFYyLFxuICBOb1N1Y2hNb2RlbEVycm9yLFxuICBQcm92aWRlclYyLFxuICBTcGVlY2hNb2RlbFYyLFxuICBUcmFuc2NyaXB0aW9uTW9kZWxWMixcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGN1c3RvbSBwcm92aWRlciB3aXRoIHNwZWNpZmllZCBsYW5ndWFnZSBtb2RlbHMsIHRleHQgZW1iZWRkaW5nIG1vZGVscywgaW1hZ2UgbW9kZWxzLCB0cmFuc2NyaXB0aW9uIG1vZGVscywgc3BlZWNoIG1vZGVscywgYW5kIGFuIG9wdGlvbmFsIGZhbGxiYWNrIHByb3ZpZGVyLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gVGhlIG9wdGlvbnMgZm9yIGNyZWF0aW5nIHRoZSBjdXN0b20gcHJvdmlkZXIuXG4gKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIExhbmd1YWdlTW9kZWw+fSBbb3B0aW9ucy5sYW5ndWFnZU1vZGVsc10gLSBBIHJlY29yZCBvZiBsYW5ndWFnZSBtb2RlbHMsIHdoZXJlIGtleXMgYXJlIG1vZGVsIElEcyBhbmQgdmFsdWVzIGFyZSBMYW5ndWFnZU1vZGVsIGluc3RhbmNlcy5cbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgRW1iZWRkaW5nTW9kZWw8c3RyaW5nPj59IFtvcHRpb25zLnRleHRFbWJlZGRpbmdNb2RlbHNdIC0gQSByZWNvcmQgb2YgdGV4dCBlbWJlZGRpbmcgbW9kZWxzLCB3aGVyZSBrZXlzIGFyZSBtb2RlbCBJRHMgYW5kIHZhbHVlcyBhcmUgRW1iZWRkaW5nTW9kZWw8c3RyaW5nPiBpbnN0YW5jZXMuXG4gKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIEltYWdlTW9kZWw+fSBbb3B0aW9ucy5pbWFnZU1vZGVsc10gLSBBIHJlY29yZCBvZiBpbWFnZSBtb2RlbHMsIHdoZXJlIGtleXMgYXJlIG1vZGVsIElEcyBhbmQgdmFsdWVzIGFyZSBJbWFnZU1vZGVsIGluc3RhbmNlcy5cbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgVHJhbnNjcmlwdGlvbk1vZGVsPn0gW29wdGlvbnMudHJhbnNjcmlwdGlvbk1vZGVsc10gLSBBIHJlY29yZCBvZiB0cmFuc2NyaXB0aW9uIG1vZGVscywgd2hlcmUga2V5cyBhcmUgbW9kZWwgSURzIGFuZCB2YWx1ZXMgYXJlIFRyYW5zY3JpcHRpb25Nb2RlbCBpbnN0YW5jZXMuXG4gKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIFNwZWVjaE1vZGVsPn0gW29wdGlvbnMuc3BlZWNoTW9kZWxzXSAtIEEgcmVjb3JkIG9mIHNwZWVjaCBtb2RlbHMsIHdoZXJlIGtleXMgYXJlIG1vZGVsIElEcyBhbmQgdmFsdWVzIGFyZSBTcGVlY2hNb2RlbCBpbnN0YW5jZXMuXG4gKiBAcGFyYW0ge1Byb3ZpZGVyfSBbb3B0aW9ucy5mYWxsYmFja1Byb3ZpZGVyXSAtIEFuIG9wdGlvbmFsIGZhbGxiYWNrIHByb3ZpZGVyIHRvIHVzZSB3aGVuIGEgcmVxdWVzdGVkIG1vZGVsIGlzIG5vdCBmb3VuZCBpbiB0aGUgY3VzdG9tIHByb3ZpZGVyLlxuICogQHJldHVybnMge1Byb3ZpZGVyfSBBIFByb3ZpZGVyIG9iamVjdCB3aXRoIGxhbmd1YWdlTW9kZWwsIHRleHRFbWJlZGRpbmdNb2RlbCwgaW1hZ2VNb2RlbCwgdHJhbnNjcmlwdGlvbk1vZGVsLCBhbmQgc3BlZWNoTW9kZWwgbWV0aG9kcy5cbiAqXG4gKiBAdGhyb3dzIHtOb1N1Y2hNb2RlbEVycm9yfSBUaHJvd3Mgd2hlbiBhIHJlcXVlc3RlZCBtb2RlbCBpcyBub3QgZm91bmQgYW5kIG5vIGZhbGxiYWNrIHByb3ZpZGVyIGlzIGF2YWlsYWJsZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGN1c3RvbVByb3ZpZGVyPFxuICBMQU5HVUFHRV9NT0RFTFMgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBMYW5ndWFnZU1vZGVsVjI+LFxuICBFTUJFRERJTkdfTU9ERUxTIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgRW1iZWRkaW5nTW9kZWxWMjxzdHJpbmc+PixcbiAgSU1BR0VfTU9ERUxTIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgSW1hZ2VNb2RlbFYyPixcbiAgVFJBTlNDUklQVElPTl9NT0RFTFMgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBUcmFuc2NyaXB0aW9uTW9kZWxWMj4sXG4gIFNQRUVDSF9NT0RFTFMgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBTcGVlY2hNb2RlbFYyPixcbj4oe1xuICBsYW5ndWFnZU1vZGVscyxcbiAgdGV4dEVtYmVkZGluZ01vZGVscyxcbiAgaW1hZ2VNb2RlbHMsXG4gIHRyYW5zY3JpcHRpb25Nb2RlbHMsXG4gIHNwZWVjaE1vZGVscyxcbiAgZmFsbGJhY2tQcm92aWRlcixcbn06IHtcbiAgbGFuZ3VhZ2VNb2RlbHM/OiBMQU5HVUFHRV9NT0RFTFM7XG4gIHRleHRFbWJlZGRpbmdNb2RlbHM/OiBFTUJFRERJTkdfTU9ERUxTO1xuICBpbWFnZU1vZGVscz86IElNQUdFX01PREVMUztcbiAgdHJhbnNjcmlwdGlvbk1vZGVscz86IFRSQU5TQ1JJUFRJT05fTU9ERUxTO1xuICBzcGVlY2hNb2RlbHM/OiBTUEVFQ0hfTU9ERUxTO1xuICBmYWxsYmFja1Byb3ZpZGVyPzogUHJvdmlkZXJWMjtcbn0pOiBQcm92aWRlclYyICYge1xuICBsYW5ndWFnZU1vZGVsKG1vZGVsSWQ6IEV4dHJhY3RNb2RlbElkPExBTkdVQUdFX01PREVMUz4pOiBMYW5ndWFnZU1vZGVsVjI7XG4gIHRleHRFbWJlZGRpbmdNb2RlbChcbiAgICBtb2RlbElkOiBFeHRyYWN0TW9kZWxJZDxFTUJFRERJTkdfTU9ERUxTPixcbiAgKTogRW1iZWRkaW5nTW9kZWxWMjxzdHJpbmc+O1xuICBpbWFnZU1vZGVsKG1vZGVsSWQ6IEV4dHJhY3RNb2RlbElkPElNQUdFX01PREVMUz4pOiBJbWFnZU1vZGVsVjI7XG4gIHRyYW5zY3JpcHRpb25Nb2RlbChcbiAgICBtb2RlbElkOiBFeHRyYWN0TW9kZWxJZDxUUkFOU0NSSVBUSU9OX01PREVMUz4sXG4gICk6IFRyYW5zY3JpcHRpb25Nb2RlbFYyO1xuICBzcGVlY2hNb2RlbChtb2RlbElkOiBFeHRyYWN0TW9kZWxJZDxTUEVFQ0hfTU9ERUxTPik6IFNwZWVjaE1vZGVsVjI7XG59IHtcbiAgcmV0dXJuIHtcbiAgICBsYW5ndWFnZU1vZGVsKG1vZGVsSWQ6IEV4dHJhY3RNb2RlbElkPExBTkdVQUdFX01PREVMUz4pOiBMYW5ndWFnZU1vZGVsVjIge1xuICAgICAgaWYgKGxhbmd1YWdlTW9kZWxzICE9IG51bGwgJiYgbW9kZWxJZCBpbiBsYW5ndWFnZU1vZGVscykge1xuICAgICAgICByZXR1cm4gbGFuZ3VhZ2VNb2RlbHNbbW9kZWxJZF07XG4gICAgICB9XG5cbiAgICAgIGlmIChmYWxsYmFja1Byb3ZpZGVyKSB7XG4gICAgICAgIHJldHVybiBmYWxsYmFja1Byb3ZpZGVyLmxhbmd1YWdlTW9kZWwobW9kZWxJZCk7XG4gICAgICB9XG5cbiAgICAgIHRocm93IG5ldyBOb1N1Y2hNb2RlbEVycm9yKHsgbW9kZWxJZCwgbW9kZWxUeXBlOiAnbGFuZ3VhZ2VNb2RlbCcgfSk7XG4gICAgfSxcblxuICAgIHRleHRFbWJlZGRpbmdNb2RlbChcbiAgICAgIG1vZGVsSWQ6IEV4dHJhY3RNb2RlbElkPEVNQkVERElOR19NT0RFTFM+LFxuICAgICk6IEVtYmVkZGluZ01vZGVsVjI8c3RyaW5nPiB7XG4gICAgICBpZiAodGV4dEVtYmVkZGluZ01vZGVscyAhPSBudWxsICYmIG1vZGVsSWQgaW4gdGV4dEVtYmVkZGluZ01vZGVscykge1xuICAgICAgICByZXR1cm4gdGV4dEVtYmVkZGluZ01vZGVsc1ttb2RlbElkXTtcbiAgICAgIH1cblxuICAgICAgaWYgKGZhbGxiYWNrUHJvdmlkZXIpIHtcbiAgICAgICAgcmV0dXJuIGZhbGxiYWNrUHJvdmlkZXIudGV4dEVtYmVkZGluZ01vZGVsKG1vZGVsSWQpO1xuICAgICAgfVxuXG4gICAgICB0aHJvdyBuZXcgTm9TdWNoTW9kZWxFcnJvcih7IG1vZGVsSWQsIG1vZGVsVHlwZTogJ3RleHRFbWJlZGRpbmdNb2RlbCcgfSk7XG4gICAgfSxcblxuICAgIGltYWdlTW9kZWwobW9kZWxJZDogRXh0cmFjdE1vZGVsSWQ8SU1BR0VfTU9ERUxTPik6IEltYWdlTW9kZWxWMiB7XG4gICAgICBpZiAoaW1hZ2VNb2RlbHMgIT0gbnVsbCAmJiBtb2RlbElkIGluIGltYWdlTW9kZWxzKSB7XG4gICAgICAgIHJldHVybiBpbWFnZU1vZGVsc1ttb2RlbElkXTtcbiAgICAgIH1cblxuICAgICAgaWYgKGZhbGxiYWNrUHJvdmlkZXI/LmltYWdlTW9kZWwpIHtcbiAgICAgICAgcmV0dXJuIGZhbGxiYWNrUHJvdmlkZXIuaW1hZ2VNb2RlbChtb2RlbElkKTtcbiAgICAgIH1cblxuICAgICAgdGhyb3cgbmV3IE5vU3VjaE1vZGVsRXJyb3IoeyBtb2RlbElkLCBtb2RlbFR5cGU6ICdpbWFnZU1vZGVsJyB9KTtcbiAgICB9LFxuXG4gICAgdHJhbnNjcmlwdGlvbk1vZGVsKFxuICAgICAgbW9kZWxJZDogRXh0cmFjdE1vZGVsSWQ8VFJBTlNDUklQVElPTl9NT0RFTFM+LFxuICAgICk6IFRyYW5zY3JpcHRpb25Nb2RlbFYyIHtcbiAgICAgIGlmICh0cmFuc2NyaXB0aW9uTW9kZWxzICE9IG51bGwgJiYgbW9kZWxJZCBpbiB0cmFuc2NyaXB0aW9uTW9kZWxzKSB7XG4gICAgICAgIHJldHVybiB0cmFuc2NyaXB0aW9uTW9kZWxzW21vZGVsSWRdO1xuICAgICAgfVxuXG4gICAgICBpZiAoZmFsbGJhY2tQcm92aWRlcj8udHJhbnNjcmlwdGlvbk1vZGVsKSB7XG4gICAgICAgIHJldHVybiBmYWxsYmFja1Byb3ZpZGVyLnRyYW5zY3JpcHRpb25Nb2RlbChtb2RlbElkKTtcbiAgICAgIH1cblxuICAgICAgdGhyb3cgbmV3IE5vU3VjaE1vZGVsRXJyb3IoeyBtb2RlbElkLCBtb2RlbFR5cGU6ICd0cmFuc2NyaXB0aW9uTW9kZWwnIH0pO1xuICAgIH0sXG5cbiAgICBzcGVlY2hNb2RlbChtb2RlbElkOiBFeHRyYWN0TW9kZWxJZDxTUEVFQ0hfTU9ERUxTPik6IFNwZWVjaE1vZGVsVjIge1xuICAgICAgaWYgKHNwZWVjaE1vZGVscyAhPSBudWxsICYmIG1vZGVsSWQgaW4gc3BlZWNoTW9kZWxzKSB7XG4gICAgICAgIHJldHVybiBzcGVlY2hNb2RlbHNbbW9kZWxJZF07XG4gICAgICB9XG5cbiAgICAgIGlmIChmYWxsYmFja1Byb3ZpZGVyPy5zcGVlY2hNb2RlbCkge1xuICAgICAgICByZXR1cm4gZmFsbGJhY2tQcm92aWRlci5zcGVlY2hNb2RlbChtb2RlbElkKTtcbiAgICAgIH1cblxuICAgICAgdGhyb3cgbmV3IE5vU3VjaE1vZGVsRXJyb3IoeyBtb2RlbElkLCBtb2RlbFR5cGU6ICdzcGVlY2hNb2RlbCcgfSk7XG4gICAgfSxcbiAgfTtcbn1cblxuLyoqXG4gKiBAZGVwcmVjYXRlZCBVc2UgYGN1c3RvbVByb3ZpZGVyYCBpbnN0ZWFkLlxuICovXG5leHBvcnQgY29uc3QgZXhwZXJpbWVudGFsX2N1c3RvbVByb3ZpZGVyID0gY3VzdG9tUHJvdmlkZXI7XG5cbnR5cGUgRXh0cmFjdE1vZGVsSWQ8TU9ERUxTIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4+ID0gRXh0cmFjdDxcbiAga2V5b2YgTU9ERUxTLFxuICBzdHJpbmdcbj47XG4iLCAiaW1wb3J0IHsgQUlTREtFcnJvciwgTm9TdWNoTW9kZWxFcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuXG5jb25zdCBuYW1lID0gJ0FJX05vU3VjaFByb3ZpZGVyRXJyb3InO1xuY29uc3QgbWFya2VyID0gYHZlcmNlbC5haS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuZXhwb3J0IGNsYXNzIE5vU3VjaFByb3ZpZGVyRXJyb3IgZXh0ZW5kcyBOb1N1Y2hNb2RlbEVycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7IC8vIHVzZWQgaW4gaXNJbnN0YW5jZVxuXG4gIHJlYWRvbmx5IHByb3ZpZGVySWQ6IHN0cmluZztcbiAgcmVhZG9ubHkgYXZhaWxhYmxlUHJvdmlkZXJzOiBzdHJpbmdbXTtcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgbW9kZWxJZCxcbiAgICBtb2RlbFR5cGUsXG4gICAgcHJvdmlkZXJJZCxcbiAgICBhdmFpbGFibGVQcm92aWRlcnMsXG4gICAgbWVzc2FnZSA9IGBObyBzdWNoIHByb3ZpZGVyOiAke3Byb3ZpZGVySWR9IChhdmFpbGFibGUgcHJvdmlkZXJzOiAke2F2YWlsYWJsZVByb3ZpZGVycy5qb2luKCl9KWAsXG4gIH06IHtcbiAgICBtb2RlbElkOiBzdHJpbmc7XG4gICAgbW9kZWxUeXBlOlxuICAgICAgfCAnbGFuZ3VhZ2VNb2RlbCdcbiAgICAgIHwgJ3RleHRFbWJlZGRpbmdNb2RlbCdcbiAgICAgIHwgJ2ltYWdlTW9kZWwnXG4gICAgICB8ICd0cmFuc2NyaXB0aW9uTW9kZWwnXG4gICAgICB8ICdzcGVlY2hNb2RlbCc7XG4gICAgcHJvdmlkZXJJZDogc3RyaW5nO1xuICAgIGF2YWlsYWJsZVByb3ZpZGVyczogc3RyaW5nW107XG4gICAgbWVzc2FnZT86IHN0cmluZztcbiAgfSkge1xuICAgIHN1cGVyKHsgZXJyb3JOYW1lOiBuYW1lLCBtb2RlbElkLCBtb2RlbFR5cGUsIG1lc3NhZ2UgfSk7XG5cbiAgICB0aGlzLnByb3ZpZGVySWQgPSBwcm92aWRlcklkO1xuICAgIHRoaXMuYXZhaWxhYmxlUHJvdmlkZXJzID0gYXZhaWxhYmxlUHJvdmlkZXJzO1xuICB9XG5cbiAgc3RhdGljIGlzSW5zdGFuY2UoZXJyb3I6IHVua25vd24pOiBlcnJvciBpcyBOb1N1Y2hQcm92aWRlckVycm9yIHtcbiAgICByZXR1cm4gQUlTREtFcnJvci5oYXNNYXJrZXIoZXJyb3IsIG1hcmtlcik7XG4gIH1cbn1cbiIsICJpbXBvcnQge1xuICBFbWJlZGRpbmdNb2RlbFYyLFxuICBJbWFnZU1vZGVsVjIsXG4gIExhbmd1YWdlTW9kZWxWMixcbiAgTm9TdWNoTW9kZWxFcnJvcixcbiAgUHJvdmlkZXJWMixcbiAgU3BlZWNoTW9kZWxWMixcbiAgVHJhbnNjcmlwdGlvbk1vZGVsVjIsXG59IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgd3JhcExhbmd1YWdlTW9kZWwgfSBmcm9tICcuLi9taWRkbGV3YXJlL3dyYXAtbGFuZ3VhZ2UtbW9kZWwnO1xuaW1wb3J0IHsgTGFuZ3VhZ2VNb2RlbE1pZGRsZXdhcmUgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgeyBOb1N1Y2hQcm92aWRlckVycm9yIH0gZnJvbSAnLi9uby1zdWNoLXByb3ZpZGVyLWVycm9yJztcblxudHlwZSBFeHRyYWN0TGl0ZXJhbFVuaW9uPFQ+ID0gVCBleHRlbmRzIHN0cmluZ1xuICA/IHN0cmluZyBleHRlbmRzIFRcbiAgICA/IG5ldmVyXG4gICAgOiBUXG4gIDogbmV2ZXI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUHJvdmlkZXJSZWdpc3RyeVByb3ZpZGVyPFxuICBQUk9WSURFUlMgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBQcm92aWRlclYyPiA9IFJlY29yZDxzdHJpbmcsIFByb3ZpZGVyVjI+LFxuICBTRVBBUkFUT1IgZXh0ZW5kcyBzdHJpbmcgPSAnOicsXG4+IHtcbiAgbGFuZ3VhZ2VNb2RlbDxLRVkgZXh0ZW5kcyBrZXlvZiBQUk9WSURFUlM+KFxuICAgIGlkOiBLRVkgZXh0ZW5kcyBzdHJpbmdcbiAgICAgID8gYCR7S0VZICYgc3RyaW5nfSR7U0VQQVJBVE9SfSR7RXh0cmFjdExpdGVyYWxVbmlvbjxQYXJhbWV0ZXJzPE5vbk51bGxhYmxlPFBST1ZJREVSU1tLRVldWydsYW5ndWFnZU1vZGVsJ10+PlswXT59YFxuICAgICAgOiBuZXZlcixcbiAgKTogTGFuZ3VhZ2VNb2RlbFYyO1xuICBsYW5ndWFnZU1vZGVsPEtFWSBleHRlbmRzIGtleW9mIFBST1ZJREVSUz4oXG4gICAgaWQ6IEtFWSBleHRlbmRzIHN0cmluZyA/IGAke0tFWSAmIHN0cmluZ30ke1NFUEFSQVRPUn0ke3N0cmluZ31gIDogbmV2ZXIsXG4gICk6IExhbmd1YWdlTW9kZWxWMjtcblxuICB0ZXh0RW1iZWRkaW5nTW9kZWw8S0VZIGV4dGVuZHMga2V5b2YgUFJPVklERVJTPihcbiAgICBpZDogS0VZIGV4dGVuZHMgc3RyaW5nXG4gICAgICA/IGAke0tFWSAmIHN0cmluZ30ke1NFUEFSQVRPUn0ke0V4dHJhY3RMaXRlcmFsVW5pb248UGFyYW1ldGVyczxOb25OdWxsYWJsZTxQUk9WSURFUlNbS0VZXVsndGV4dEVtYmVkZGluZ01vZGVsJ10+PlswXT59YFxuICAgICAgOiBuZXZlcixcbiAgKTogRW1iZWRkaW5nTW9kZWxWMjxzdHJpbmc+O1xuICB0ZXh0RW1iZWRkaW5nTW9kZWw8S0VZIGV4dGVuZHMga2V5b2YgUFJPVklERVJTPihcbiAgICBpZDogS0VZIGV4dGVuZHMgc3RyaW5nID8gYCR7S0VZICYgc3RyaW5nfSR7U0VQQVJBVE9SfSR7c3RyaW5nfWAgOiBuZXZlcixcbiAgKTogRW1iZWRkaW5nTW9kZWxWMjxzdHJpbmc+O1xuXG4gIGltYWdlTW9kZWw8S0VZIGV4dGVuZHMga2V5b2YgUFJPVklERVJTPihcbiAgICBpZDogS0VZIGV4dGVuZHMgc3RyaW5nXG4gICAgICA/IGAke0tFWSAmIHN0cmluZ30ke1NFUEFSQVRPUn0ke0V4dHJhY3RMaXRlcmFsVW5pb248UGFyYW1ldGVyczxOb25OdWxsYWJsZTxQUk9WSURFUlNbS0VZXVsnaW1hZ2VNb2RlbCddPj5bMF0+fWBcbiAgICAgIDogbmV2ZXIsXG4gICk6IEltYWdlTW9kZWxWMjtcbiAgaW1hZ2VNb2RlbDxLRVkgZXh0ZW5kcyBrZXlvZiBQUk9WSURFUlM+KFxuICAgIGlkOiBLRVkgZXh0ZW5kcyBzdHJpbmcgPyBgJHtLRVkgJiBzdHJpbmd9JHtTRVBBUkFUT1J9JHtzdHJpbmd9YCA6IG5ldmVyLFxuICApOiBJbWFnZU1vZGVsVjI7XG5cbiAgdHJhbnNjcmlwdGlvbk1vZGVsPEtFWSBleHRlbmRzIGtleW9mIFBST1ZJREVSUz4oXG4gICAgaWQ6IEtFWSBleHRlbmRzIHN0cmluZ1xuICAgICAgPyBgJHtLRVkgJiBzdHJpbmd9JHtTRVBBUkFUT1J9JHtFeHRyYWN0TGl0ZXJhbFVuaW9uPFBhcmFtZXRlcnM8Tm9uTnVsbGFibGU8UFJPVklERVJTW0tFWV1bJ3RyYW5zY3JpcHRpb25Nb2RlbCddPj5bMF0+fWBcbiAgICAgIDogbmV2ZXIsXG4gICk6IFRyYW5zY3JpcHRpb25Nb2RlbFYyO1xuICB0cmFuc2NyaXB0aW9uTW9kZWw8S0VZIGV4dGVuZHMga2V5b2YgUFJPVklERVJTPihcbiAgICBpZDogS0VZIGV4dGVuZHMgc3RyaW5nID8gYCR7S0VZICYgc3RyaW5nfSR7U0VQQVJBVE9SfSR7c3RyaW5nfWAgOiBuZXZlcixcbiAgKTogVHJhbnNjcmlwdGlvbk1vZGVsVjI7XG5cbiAgc3BlZWNoTW9kZWw8S0VZIGV4dGVuZHMga2V5b2YgUFJPVklERVJTPihcbiAgICBpZDogS0VZIGV4dGVuZHMgc3RyaW5nXG4gICAgICA/IGAke0tFWSAmIHN0cmluZ30ke1NFUEFSQVRPUn0ke0V4dHJhY3RMaXRlcmFsVW5pb248UGFyYW1ldGVyczxOb25OdWxsYWJsZTxQUk9WSURFUlNbS0VZXVsnc3BlZWNoTW9kZWwnXT4+WzBdPn1gXG4gICAgICA6IG5ldmVyLFxuICApOiBTcGVlY2hNb2RlbFYyO1xuICBzcGVlY2hNb2RlbDxLRVkgZXh0ZW5kcyBrZXlvZiBQUk9WSURFUlM+KFxuICAgIGlkOiBLRVkgZXh0ZW5kcyBzdHJpbmcgPyBgJHtLRVkgJiBzdHJpbmd9JHtTRVBBUkFUT1J9JHtzdHJpbmd9YCA6IG5ldmVyLFxuICApOiBTcGVlY2hNb2RlbFYyO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSByZWdpc3RyeSBmb3IgdGhlIGdpdmVuIHByb3ZpZGVycyB3aXRoIG9wdGlvbmFsIG1pZGRsZXdhcmUgZnVuY3Rpb25hbGl0eS5cbiAqIFRoaXMgZnVuY3Rpb24gYWxsb3dzIHlvdSB0byByZWdpc3RlciBtdWx0aXBsZSBwcm92aWRlcnMgYW5kIG9wdGlvbmFsbHkgYXBwbHkgbWlkZGxld2FyZVxuICogdG8gYWxsIGxhbmd1YWdlIG1vZGVscyBmcm9tIHRoZSByZWdpc3RyeSwgZW5hYmxpbmcgeW91IHRvIHRyYW5zZm9ybSBwYXJhbWV0ZXJzLCB3cmFwIGdlbmVyYXRlXG4gKiBvcGVyYXRpb25zLCBhbmQgd3JhcCBzdHJlYW0gb3BlcmF0aW9ucyBmb3IgZXZlcnkgbGFuZ3VhZ2UgbW9kZWwgYWNjZXNzZWQgdGhyb3VnaCB0aGUgcmVnaXN0cnkuXG4gKlxuICogQHBhcmFtIHByb3ZpZGVycyAtIEEgcmVjb3JkIG9mIHByb3ZpZGVyIGluc3RhbmNlcyB0byBiZSByZWdpc3RlcmVkIGluIHRoZSByZWdpc3RyeS5cbiAqIEBwYXJhbSBvcHRpb25zIC0gQ29uZmlndXJhdGlvbiBvcHRpb25zIGZvciB0aGUgcHJvdmlkZXIgcmVnaXN0cnkuXG4gKiBAcGFyYW0gb3B0aW9ucy5zZXBhcmF0b3IgLSBUaGUgc2VwYXJhdG9yIHVzZWQgYmV0d2VlbiBwcm92aWRlciBJRCBhbmQgbW9kZWwgSUQgaW4gdGhlIGNvbWJpbmVkIGlkZW50aWZpZXIuIERlZmF1bHRzIHRvICc6Jy5cbiAqIEBwYXJhbSBvcHRpb25zLmxhbmd1YWdlTW9kZWxNaWRkbGV3YXJlIC0gT3B0aW9uYWwgbWlkZGxld2FyZSB0byBiZSBhcHBsaWVkIHRvIGFsbCBsYW5ndWFnZSBtb2RlbHMgZnJvbSB0aGUgcmVnaXN0cnkuIFdoZW4gbXVsdGlwbGUgbWlkZGxld2FyZXMgYXJlIHByb3ZpZGVkLCB0aGUgZmlyc3QgbWlkZGxld2FyZSB3aWxsIHRyYW5zZm9ybSB0aGUgaW5wdXQgZmlyc3QsIGFuZCB0aGUgbGFzdCBtaWRkbGV3YXJlIHdpbGwgYmUgd3JhcHBlZCBkaXJlY3RseSBhcm91bmQgdGhlIG1vZGVsLlxuICogQHJldHVybnMgQSBuZXcgUHJvdmlkZXJSZWdpc3RyeVByb3ZpZGVyIGluc3RhbmNlIHRoYXQgcHJvdmlkZXMgYWNjZXNzIHRvIGFsbCByZWdpc3RlcmVkIHByb3ZpZGVycyB3aXRoIG9wdGlvbmFsIG1pZGRsZXdhcmUgYXBwbGllZCB0byBsYW5ndWFnZSBtb2RlbHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVQcm92aWRlclJlZ2lzdHJ5PFxuICBQUk9WSURFUlMgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBQcm92aWRlclYyPixcbiAgU0VQQVJBVE9SIGV4dGVuZHMgc3RyaW5nID0gJzonLFxuPihcbiAgcHJvdmlkZXJzOiBQUk9WSURFUlMsXG4gIHtcbiAgICBzZXBhcmF0b3IgPSAnOicgYXMgU0VQQVJBVE9SLFxuICAgIGxhbmd1YWdlTW9kZWxNaWRkbGV3YXJlLFxuICB9OiB7XG4gICAgc2VwYXJhdG9yPzogU0VQQVJBVE9SO1xuICAgIGxhbmd1YWdlTW9kZWxNaWRkbGV3YXJlPzpcbiAgICAgIHwgTGFuZ3VhZ2VNb2RlbE1pZGRsZXdhcmVcbiAgICAgIHwgTGFuZ3VhZ2VNb2RlbE1pZGRsZXdhcmVbXTtcbiAgfSA9IHt9LFxuKTogUHJvdmlkZXJSZWdpc3RyeVByb3ZpZGVyPFBST1ZJREVSUywgU0VQQVJBVE9SPiB7XG4gIGNvbnN0IHJlZ2lzdHJ5ID0gbmV3IERlZmF1bHRQcm92aWRlclJlZ2lzdHJ5PFBST1ZJREVSUywgU0VQQVJBVE9SPih7XG4gICAgc2VwYXJhdG9yLFxuICAgIGxhbmd1YWdlTW9kZWxNaWRkbGV3YXJlLFxuICB9KTtcblxuICBmb3IgKGNvbnN0IFtpZCwgcHJvdmlkZXJdIG9mIE9iamVjdC5lbnRyaWVzKHByb3ZpZGVycykpIHtcbiAgICByZWdpc3RyeS5yZWdpc3RlclByb3ZpZGVyKHsgaWQsIHByb3ZpZGVyIH0gYXMge1xuICAgICAgaWQ6IGtleW9mIFBST1ZJREVSUztcbiAgICAgIHByb3ZpZGVyOiBQUk9WSURFUlNba2V5b2YgUFJPVklERVJTXTtcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiByZWdpc3RyeTtcbn1cblxuLyoqXG4gKiBAZGVwcmVjYXRlZCBVc2UgYGNyZWF0ZVByb3ZpZGVyUmVnaXN0cnlgIGluc3RlYWQuXG4gKi9cbmV4cG9ydCBjb25zdCBleHBlcmltZW50YWxfY3JlYXRlUHJvdmlkZXJSZWdpc3RyeSA9IGNyZWF0ZVByb3ZpZGVyUmVnaXN0cnk7XG5cbmNsYXNzIERlZmF1bHRQcm92aWRlclJlZ2lzdHJ5PFxuICBQUk9WSURFUlMgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBQcm92aWRlclYyPixcbiAgU0VQQVJBVE9SIGV4dGVuZHMgc3RyaW5nLFxuPiBpbXBsZW1lbnRzIFByb3ZpZGVyUmVnaXN0cnlQcm92aWRlcjxQUk9WSURFUlMsIFNFUEFSQVRPUj5cbntcbiAgcHJpdmF0ZSBwcm92aWRlcnM6IFBST1ZJREVSUyA9IHt9IGFzIFBST1ZJREVSUztcbiAgcHJpdmF0ZSBzZXBhcmF0b3I6IFNFUEFSQVRPUjtcbiAgcHJpdmF0ZSBsYW5ndWFnZU1vZGVsTWlkZGxld2FyZT86XG4gICAgfCBMYW5ndWFnZU1vZGVsTWlkZGxld2FyZVxuICAgIHwgTGFuZ3VhZ2VNb2RlbE1pZGRsZXdhcmVbXTtcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgc2VwYXJhdG9yLFxuICAgIGxhbmd1YWdlTW9kZWxNaWRkbGV3YXJlLFxuICB9OiB7XG4gICAgc2VwYXJhdG9yOiBTRVBBUkFUT1I7XG4gICAgbGFuZ3VhZ2VNb2RlbE1pZGRsZXdhcmU/OlxuICAgICAgfCBMYW5ndWFnZU1vZGVsTWlkZGxld2FyZVxuICAgICAgfCBMYW5ndWFnZU1vZGVsTWlkZGxld2FyZVtdO1xuICB9KSB7XG4gICAgdGhpcy5zZXBhcmF0b3IgPSBzZXBhcmF0b3I7XG4gICAgdGhpcy5sYW5ndWFnZU1vZGVsTWlkZGxld2FyZSA9IGxhbmd1YWdlTW9kZWxNaWRkbGV3YXJlO1xuICB9XG5cbiAgcmVnaXN0ZXJQcm92aWRlcjxLIGV4dGVuZHMga2V5b2YgUFJPVklERVJTPih7XG4gICAgaWQsXG4gICAgcHJvdmlkZXIsXG4gIH06IHtcbiAgICBpZDogSztcbiAgICBwcm92aWRlcjogUFJPVklERVJTW0tdO1xuICB9KTogdm9pZCB7XG4gICAgdGhpcy5wcm92aWRlcnNbaWRdID0gcHJvdmlkZXI7XG4gIH1cblxuICBwcml2YXRlIGdldFByb3ZpZGVyKFxuICAgIGlkOiBzdHJpbmcsXG4gICAgbW9kZWxUeXBlOlxuICAgICAgfCAnbGFuZ3VhZ2VNb2RlbCdcbiAgICAgIHwgJ3RleHRFbWJlZGRpbmdNb2RlbCdcbiAgICAgIHwgJ2ltYWdlTW9kZWwnXG4gICAgICB8ICd0cmFuc2NyaXB0aW9uTW9kZWwnXG4gICAgICB8ICdzcGVlY2hNb2RlbCcsXG4gICk6IFByb3ZpZGVyVjIge1xuICAgIGNvbnN0IHByb3ZpZGVyID0gdGhpcy5wcm92aWRlcnNbaWQgYXMga2V5b2YgUFJPVklERVJTXTtcblxuICAgIGlmIChwcm92aWRlciA9PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgTm9TdWNoUHJvdmlkZXJFcnJvcih7XG4gICAgICAgIG1vZGVsSWQ6IGlkLFxuICAgICAgICBtb2RlbFR5cGUsXG4gICAgICAgIHByb3ZpZGVySWQ6IGlkLFxuICAgICAgICBhdmFpbGFibGVQcm92aWRlcnM6IE9iamVjdC5rZXlzKHRoaXMucHJvdmlkZXJzKSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBwcm92aWRlcjtcbiAgfVxuXG4gIHByaXZhdGUgc3BsaXRJZChcbiAgICBpZDogc3RyaW5nLFxuICAgIG1vZGVsVHlwZTpcbiAgICAgIHwgJ2xhbmd1YWdlTW9kZWwnXG4gICAgICB8ICd0ZXh0RW1iZWRkaW5nTW9kZWwnXG4gICAgICB8ICdpbWFnZU1vZGVsJ1xuICAgICAgfCAndHJhbnNjcmlwdGlvbk1vZGVsJ1xuICAgICAgfCAnc3BlZWNoTW9kZWwnLFxuICApOiBbc3RyaW5nLCBzdHJpbmddIHtcbiAgICBjb25zdCBpbmRleCA9IGlkLmluZGV4T2YodGhpcy5zZXBhcmF0b3IpO1xuXG4gICAgaWYgKGluZGV4ID09PSAtMSkge1xuICAgICAgdGhyb3cgbmV3IE5vU3VjaE1vZGVsRXJyb3Ioe1xuICAgICAgICBtb2RlbElkOiBpZCxcbiAgICAgICAgbW9kZWxUeXBlLFxuICAgICAgICBtZXNzYWdlOlxuICAgICAgICAgIGBJbnZhbGlkICR7bW9kZWxUeXBlfSBpZCBmb3IgcmVnaXN0cnk6ICR7aWR9IGAgK1xuICAgICAgICAgIGAobXVzdCBiZSBpbiB0aGUgZm9ybWF0IFwicHJvdmlkZXJJZCR7dGhpcy5zZXBhcmF0b3J9bW9kZWxJZFwiKWAsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gW2lkLnNsaWNlKDAsIGluZGV4KSwgaWQuc2xpY2UoaW5kZXggKyB0aGlzLnNlcGFyYXRvci5sZW5ndGgpXTtcbiAgfVxuXG4gIGxhbmd1YWdlTW9kZWw8S0VZIGV4dGVuZHMga2V5b2YgUFJPVklERVJTPihcbiAgICBpZDogYCR7S0VZICYgc3RyaW5nfSR7U0VQQVJBVE9SfSR7c3RyaW5nfWAsXG4gICk6IExhbmd1YWdlTW9kZWxWMiB7XG4gICAgY29uc3QgW3Byb3ZpZGVySWQsIG1vZGVsSWRdID0gdGhpcy5zcGxpdElkKGlkLCAnbGFuZ3VhZ2VNb2RlbCcpO1xuICAgIGxldCBtb2RlbCA9IHRoaXMuZ2V0UHJvdmlkZXIocHJvdmlkZXJJZCwgJ2xhbmd1YWdlTW9kZWwnKS5sYW5ndWFnZU1vZGVsPy4oXG4gICAgICBtb2RlbElkLFxuICAgICk7XG5cbiAgICBpZiAobW9kZWwgPT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IE5vU3VjaE1vZGVsRXJyb3IoeyBtb2RlbElkOiBpZCwgbW9kZWxUeXBlOiAnbGFuZ3VhZ2VNb2RlbCcgfSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubGFuZ3VhZ2VNb2RlbE1pZGRsZXdhcmUgIT0gbnVsbCkge1xuICAgICAgbW9kZWwgPSB3cmFwTGFuZ3VhZ2VNb2RlbCh7XG4gICAgICAgIG1vZGVsLFxuICAgICAgICBtaWRkbGV3YXJlOiB0aGlzLmxhbmd1YWdlTW9kZWxNaWRkbGV3YXJlLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1vZGVsO1xuICB9XG5cbiAgdGV4dEVtYmVkZGluZ01vZGVsPEtFWSBleHRlbmRzIGtleW9mIFBST1ZJREVSUz4oXG4gICAgaWQ6IGAke0tFWSAmIHN0cmluZ30ke1NFUEFSQVRPUn0ke3N0cmluZ31gLFxuICApOiBFbWJlZGRpbmdNb2RlbFYyPHN0cmluZz4ge1xuICAgIGNvbnN0IFtwcm92aWRlcklkLCBtb2RlbElkXSA9IHRoaXMuc3BsaXRJZChpZCwgJ3RleHRFbWJlZGRpbmdNb2RlbCcpO1xuICAgIGNvbnN0IHByb3ZpZGVyID0gdGhpcy5nZXRQcm92aWRlcihwcm92aWRlcklkLCAndGV4dEVtYmVkZGluZ01vZGVsJyk7XG5cbiAgICBjb25zdCBtb2RlbCA9IHByb3ZpZGVyLnRleHRFbWJlZGRpbmdNb2RlbD8uKG1vZGVsSWQpO1xuXG4gICAgaWYgKG1vZGVsID09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBOb1N1Y2hNb2RlbEVycm9yKHtcbiAgICAgICAgbW9kZWxJZDogaWQsXG4gICAgICAgIG1vZGVsVHlwZTogJ3RleHRFbWJlZGRpbmdNb2RlbCcsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gbW9kZWw7XG4gIH1cblxuICBpbWFnZU1vZGVsPEtFWSBleHRlbmRzIGtleW9mIFBST1ZJREVSUz4oXG4gICAgaWQ6IGAke0tFWSAmIHN0cmluZ30ke1NFUEFSQVRPUn0ke3N0cmluZ31gLFxuICApOiBJbWFnZU1vZGVsVjIge1xuICAgIGNvbnN0IFtwcm92aWRlcklkLCBtb2RlbElkXSA9IHRoaXMuc3BsaXRJZChpZCwgJ2ltYWdlTW9kZWwnKTtcbiAgICBjb25zdCBwcm92aWRlciA9IHRoaXMuZ2V0UHJvdmlkZXIocHJvdmlkZXJJZCwgJ2ltYWdlTW9kZWwnKTtcblxuICAgIGNvbnN0IG1vZGVsID0gcHJvdmlkZXIuaW1hZ2VNb2RlbD8uKG1vZGVsSWQpO1xuXG4gICAgaWYgKG1vZGVsID09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBOb1N1Y2hNb2RlbEVycm9yKHsgbW9kZWxJZDogaWQsIG1vZGVsVHlwZTogJ2ltYWdlTW9kZWwnIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBtb2RlbDtcbiAgfVxuXG4gIHRyYW5zY3JpcHRpb25Nb2RlbDxLRVkgZXh0ZW5kcyBrZXlvZiBQUk9WSURFUlM+KFxuICAgIGlkOiBgJHtLRVkgJiBzdHJpbmd9JHtTRVBBUkFUT1J9JHtzdHJpbmd9YCxcbiAgKTogVHJhbnNjcmlwdGlvbk1vZGVsVjIge1xuICAgIGNvbnN0IFtwcm92aWRlcklkLCBtb2RlbElkXSA9IHRoaXMuc3BsaXRJZChpZCwgJ3RyYW5zY3JpcHRpb25Nb2RlbCcpO1xuICAgIGNvbnN0IHByb3ZpZGVyID0gdGhpcy5nZXRQcm92aWRlcihwcm92aWRlcklkLCAndHJhbnNjcmlwdGlvbk1vZGVsJyk7XG5cbiAgICBjb25zdCBtb2RlbCA9IHByb3ZpZGVyLnRyYW5zY3JpcHRpb25Nb2RlbD8uKG1vZGVsSWQpO1xuXG4gICAgaWYgKG1vZGVsID09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBOb1N1Y2hNb2RlbEVycm9yKHtcbiAgICAgICAgbW9kZWxJZDogaWQsXG4gICAgICAgIG1vZGVsVHlwZTogJ3RyYW5zY3JpcHRpb25Nb2RlbCcsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gbW9kZWw7XG4gIH1cblxuICBzcGVlY2hNb2RlbDxLRVkgZXh0ZW5kcyBrZXlvZiBQUk9WSURFUlM+KFxuICAgIGlkOiBgJHtLRVkgJiBzdHJpbmd9JHtTRVBBUkFUT1J9JHtzdHJpbmd9YCxcbiAgKTogU3BlZWNoTW9kZWxWMiB7XG4gICAgY29uc3QgW3Byb3ZpZGVySWQsIG1vZGVsSWRdID0gdGhpcy5zcGxpdElkKGlkLCAnc3BlZWNoTW9kZWwnKTtcbiAgICBjb25zdCBwcm92aWRlciA9IHRoaXMuZ2V0UHJvdmlkZXIocHJvdmlkZXJJZCwgJ3NwZWVjaE1vZGVsJyk7XG5cbiAgICBjb25zdCBtb2RlbCA9IHByb3ZpZGVyLnNwZWVjaE1vZGVsPy4obW9kZWxJZCk7XG5cbiAgICBpZiAobW9kZWwgPT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IE5vU3VjaE1vZGVsRXJyb3IoeyBtb2RlbElkOiBpZCwgbW9kZWxUeXBlOiAnc3BlZWNoTW9kZWwnIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBtb2RlbDtcbiAgfVxufVxuIiwgImltcG9ydCB7IEpTT05TY2hlbWE3IH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQge1xuICBkeW5hbWljVG9vbCxcbiAganNvblNjaGVtYSxcbiAgVG9vbCxcbiAgdG9vbCxcbiAgVG9vbENhbGxPcHRpb25zLFxufSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyLXV0aWxzJztcbmltcG9ydCB7IHogfSBmcm9tICd6b2QvdjQnO1xuaW1wb3J0IHsgTUNQQ2xpZW50RXJyb3IgfSBmcm9tICcuLi8uLi9lcnJvci9tY3AtY2xpZW50LWVycm9yJztcbmltcG9ydCB7XG4gIEpTT05SUENFcnJvcixcbiAgSlNPTlJQQ05vdGlmaWNhdGlvbixcbiAgSlNPTlJQQ1JlcXVlc3QsXG4gIEpTT05SUENSZXNwb25zZSxcbn0gZnJvbSAnLi9qc29uLXJwYy1tZXNzYWdlJztcbmltcG9ydCB7XG4gIGNyZWF0ZU1jcFRyYW5zcG9ydCxcbiAgaXNDdXN0b21NY3BUcmFuc3BvcnQsXG4gIE1DUFRyYW5zcG9ydCxcbiAgTUNQVHJhbnNwb3J0Q29uZmlnLFxufSBmcm9tICcuL21jcC10cmFuc3BvcnQnO1xuaW1wb3J0IHtcbiAgQ2FsbFRvb2xSZXN1bHQsXG4gIENhbGxUb29sUmVzdWx0U2NoZW1hLFxuICBDb25maWd1cmF0aW9uIGFzIENsaWVudENvbmZpZ3VyYXRpb24sXG4gIEluaXRpYWxpemVSZXN1bHRTY2hlbWEsXG4gIExBVEVTVF9QUk9UT0NPTF9WRVJTSU9OLFxuICBMaXN0VG9vbHNSZXN1bHQsXG4gIExpc3RUb29sc1Jlc3VsdFNjaGVtYSxcbiAgTWNwVG9vbFNldCxcbiAgTm90aWZpY2F0aW9uLFxuICBQYWdpbmF0ZWRSZXF1ZXN0LFxuICBSZXF1ZXN0LFxuICBSZXF1ZXN0T3B0aW9ucyxcbiAgU2VydmVyQ2FwYWJpbGl0aWVzLFxuICBTVVBQT1JURURfUFJPVE9DT0xfVkVSU0lPTlMsXG4gIFRvb2xTY2hlbWFzLFxufSBmcm9tICcuL3R5cGVzJztcblxuY29uc3QgQ0xJRU5UX1ZFUlNJT04gPSAnMS4wLjAnO1xuXG5leHBvcnQgaW50ZXJmYWNlIE1DUENsaWVudENvbmZpZyB7XG4gIC8qKiBUcmFuc3BvcnQgY29uZmlndXJhdGlvbiBmb3IgY29ubmVjdGluZyB0byB0aGUgTUNQIHNlcnZlciAqL1xuICB0cmFuc3BvcnQ6IE1DUFRyYW5zcG9ydENvbmZpZyB8IE1DUFRyYW5zcG9ydDtcbiAgLyoqIE9wdGlvbmFsIGNhbGxiYWNrIGZvciB1bmNhdWdodCBlcnJvcnMgKi9cbiAgb25VbmNhdWdodEVycm9yPzogKGVycm9yOiB1bmtub3duKSA9PiB2b2lkO1xuICAvKiogT3B0aW9uYWwgY2xpZW50IG5hbWUsIGRlZmF1bHRzIHRvICdhaS1zZGstbWNwLWNsaWVudCcgKi9cbiAgbmFtZT86IHN0cmluZztcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZU1DUENsaWVudChcbiAgY29uZmlnOiBNQ1BDbGllbnRDb25maWcsXG4pOiBQcm9taXNlPE1DUENsaWVudD4ge1xuICBjb25zdCBjbGllbnQgPSBuZXcgRGVmYXVsdE1DUENsaWVudChjb25maWcpO1xuICBhd2FpdCBjbGllbnQuaW5pdCgpO1xuICByZXR1cm4gY2xpZW50O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE1DUENsaWVudCB7XG4gIHRvb2xzPFRPT0xfU0NIRU1BUyBleHRlbmRzIFRvb2xTY2hlbWFzID0gJ2F1dG9tYXRpYyc+KG9wdGlvbnM/OiB7XG4gICAgc2NoZW1hcz86IFRPT0xfU0NIRU1BUztcbiAgfSk6IFByb21pc2U8TWNwVG9vbFNldDxUT09MX1NDSEVNQVM+PjtcblxuICBjbG9zZTogKCkgPT4gUHJvbWlzZTx2b2lkPjtcbn1cblxuLyoqXG4gKiBBIGxpZ2h0d2VpZ2h0IE1DUCBDbGllbnQgaW1wbGVtZW50YXRpb25cbiAqXG4gKiBUaGUgcHJpbWFyeSBwdXJwb3NlIG9mIHRoaXMgY2xpZW50IGlzIHRvb2wgY29udmVyc2lvbiBiZXR3ZWVuIE1DUDw+QUkgU0RLXG4gKiBidXQgY2FuIGxhdGVyIGJlIGV4dGVuZGVkIHRvIHN1cHBvcnQgb3RoZXIgTUNQIGZlYXR1cmVzXG4gKlxuICogVG9vbCBwYXJhbWV0ZXJzIGFyZSBhdXRvbWF0aWNhbGx5IGluZmVycmVkIGZyb20gdGhlIHNlcnZlcidzIEpTT04gc2NoZW1hXG4gKiBpZiBub3QgZXhwbGljaXRseSBwcm92aWRlZCBpbiB0aGUgdG9vbHMgY29uZmlndXJhdGlvblxuICpcbiAqIFRoaXMgY2xpZW50IGlzIG1lYW50IHRvIGJlIHVzZWQgdG8gY29tbXVuaWNhdGUgd2l0aCBhIHNpbmdsZSBzZXJ2ZXIuIFRvIGNvbW11bmljYXRlIGFuZCBmZXRjaCB0b29scyBhY3Jvc3MgbXVsdGlwbGUgc2VydmVycywgaXQncyByZWNvbW1lbmRlZCB0byBjcmVhdGUgYSBuZXcgY2xpZW50IGluc3RhbmNlIHBlciBzZXJ2ZXIuXG4gKlxuICogTm90IHN1cHBvcnRlZDpcbiAqIC0gQ2xpZW50IG9wdGlvbnMgKGUuZy4gc2FtcGxpbmcsIHJvb3RzKSBhcyB0aGV5IGFyZSBub3QgbmVlZGVkIGZvciB0b29sIGNvbnZlcnNpb25cbiAqIC0gQWNjZXB0aW5nIG5vdGlmaWNhdGlvbnNcbiAqIC0gU2Vzc2lvbiBtYW5hZ2VtZW50ICh3aGVuIHBhc3NpbmcgYSBzZXNzaW9uSWQgdG8gYW4gaW5zdGFuY2Ugb2YgdGhlIFN0cmVhbWFibGUgSFRUUCB0cmFuc3BvcnQpXG4gKiAtIFJlc3VtYWJsZSBTU0Ugc3RyZWFtc1xuICovXG5jbGFzcyBEZWZhdWx0TUNQQ2xpZW50IGltcGxlbWVudHMgTUNQQ2xpZW50IHtcbiAgcHJpdmF0ZSB0cmFuc3BvcnQ6IE1DUFRyYW5zcG9ydDtcbiAgcHJpdmF0ZSBvblVuY2F1Z2h0RXJyb3I/OiAoZXJyb3I6IHVua25vd24pID0+IHZvaWQ7XG4gIHByaXZhdGUgY2xpZW50SW5mbzogQ2xpZW50Q29uZmlndXJhdGlvbjtcbiAgcHJpdmF0ZSByZXF1ZXN0TWVzc2FnZUlkID0gMDtcbiAgcHJpdmF0ZSByZXNwb25zZUhhbmRsZXJzOiBNYXA8XG4gICAgbnVtYmVyLFxuICAgIChyZXNwb25zZTogSlNPTlJQQ1Jlc3BvbnNlIHwgRXJyb3IpID0+IHZvaWRcbiAgPiA9IG5ldyBNYXAoKTtcbiAgcHJpdmF0ZSBzZXJ2ZXJDYXBhYmlsaXRpZXM6IFNlcnZlckNhcGFiaWxpdGllcyA9IHt9O1xuICBwcml2YXRlIGlzQ2xvc2VkID0gdHJ1ZTtcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgdHJhbnNwb3J0OiB0cmFuc3BvcnRDb25maWcsXG4gICAgbmFtZSA9ICdhaS1zZGstbWNwLWNsaWVudCcsXG4gICAgb25VbmNhdWdodEVycm9yLFxuICB9OiBNQ1BDbGllbnRDb25maWcpIHtcbiAgICB0aGlzLm9uVW5jYXVnaHRFcnJvciA9IG9uVW5jYXVnaHRFcnJvcjtcblxuICAgIGlmIChpc0N1c3RvbU1jcFRyYW5zcG9ydCh0cmFuc3BvcnRDb25maWcpKSB7XG4gICAgICB0aGlzLnRyYW5zcG9ydCA9IHRyYW5zcG9ydENvbmZpZztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy50cmFuc3BvcnQgPSBjcmVhdGVNY3BUcmFuc3BvcnQodHJhbnNwb3J0Q29uZmlnKTtcbiAgICB9XG5cbiAgICB0aGlzLnRyYW5zcG9ydC5vbmNsb3NlID0gKCkgPT4gdGhpcy5vbkNsb3NlKCk7XG4gICAgdGhpcy50cmFuc3BvcnQub25lcnJvciA9IChlcnJvcjogRXJyb3IpID0+IHRoaXMub25FcnJvcihlcnJvcik7XG4gICAgdGhpcy50cmFuc3BvcnQub25tZXNzYWdlID0gbWVzc2FnZSA9PiB7XG4gICAgICBpZiAoJ21ldGhvZCcgaW4gbWVzc2FnZSkge1xuICAgICAgICAvLyBUaGlzIGxpZ2h0d2VpZ2h0IGNsaWVudCBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0XG4gICAgICAgIC8vIHJlY2VpdmluZyBub3RpZmljYXRpb25zIG9yIHJlcXVlc3RzIGZyb20gc2VydmVyLlxuICAgICAgICAvLyBJZiB3ZSBnZXQgYW4gdW5zdXBwb3J0ZWQgbWVzc2FnZSwgd2UgY2FuIHNhZmVseSBpZ25vcmUgaXQgYW5kIHBhc3MgdG8gdGhlIG9uRXJyb3IgaGFuZGxlcjpcbiAgICAgICAgdGhpcy5vbkVycm9yKFxuICAgICAgICAgIG5ldyBNQ1BDbGllbnRFcnJvcih7XG4gICAgICAgICAgICBtZXNzYWdlOiAnVW5zdXBwb3J0ZWQgbWVzc2FnZSB0eXBlJyxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0aGlzLm9uUmVzcG9uc2UobWVzc2FnZSk7XG4gICAgfTtcblxuICAgIHRoaXMuY2xpZW50SW5mbyA9IHtcbiAgICAgIG5hbWUsXG4gICAgICB2ZXJzaW9uOiBDTElFTlRfVkVSU0lPTixcbiAgICB9O1xuICB9XG5cbiAgYXN5bmMgaW5pdCgpOiBQcm9taXNlPHRoaXM+IHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy50cmFuc3BvcnQuc3RhcnQoKTtcbiAgICAgIHRoaXMuaXNDbG9zZWQgPSBmYWxzZTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5yZXF1ZXN0KHtcbiAgICAgICAgcmVxdWVzdDoge1xuICAgICAgICAgIG1ldGhvZDogJ2luaXRpYWxpemUnLFxuICAgICAgICAgIHBhcmFtczoge1xuICAgICAgICAgICAgcHJvdG9jb2xWZXJzaW9uOiBMQVRFU1RfUFJPVE9DT0xfVkVSU0lPTixcbiAgICAgICAgICAgIGNhcGFiaWxpdGllczoge30sXG4gICAgICAgICAgICBjbGllbnRJbmZvOiB0aGlzLmNsaWVudEluZm8sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgcmVzdWx0U2NoZW1hOiBJbml0aWFsaXplUmVzdWx0U2NoZW1hLFxuICAgICAgfSk7XG5cbiAgICAgIGlmIChyZXN1bHQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBuZXcgTUNQQ2xpZW50RXJyb3Ioe1xuICAgICAgICAgIG1lc3NhZ2U6ICdTZXJ2ZXIgc2VudCBpbnZhbGlkIGluaXRpYWxpemUgcmVzdWx0JyxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmICghU1VQUE9SVEVEX1BST1RPQ09MX1ZFUlNJT05TLmluY2x1ZGVzKHJlc3VsdC5wcm90b2NvbFZlcnNpb24pKSB7XG4gICAgICAgIHRocm93IG5ldyBNQ1BDbGllbnRFcnJvcih7XG4gICAgICAgICAgbWVzc2FnZTogYFNlcnZlcidzIHByb3RvY29sIHZlcnNpb24gaXMgbm90IHN1cHBvcnRlZDogJHtyZXN1bHQucHJvdG9jb2xWZXJzaW9ufWAsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnNlcnZlckNhcGFiaWxpdGllcyA9IHJlc3VsdC5jYXBhYmlsaXRpZXM7XG5cbiAgICAgIC8vIENvbXBsZXRlIGluaXRpYWxpemF0aW9uIGhhbmRzaGFrZTpcbiAgICAgIGF3YWl0IHRoaXMubm90aWZpY2F0aW9uKHtcbiAgICAgICAgbWV0aG9kOiAnbm90aWZpY2F0aW9ucy9pbml0aWFsaXplZCcsXG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGF3YWl0IHRoaXMuY2xvc2UoKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGNsb3NlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLmlzQ2xvc2VkKSByZXR1cm47XG4gICAgYXdhaXQgdGhpcy50cmFuc3BvcnQ/LmNsb3NlKCk7XG4gICAgdGhpcy5vbkNsb3NlKCk7XG4gIH1cblxuICBwcml2YXRlIGFzc2VydENhcGFiaWxpdHkobWV0aG9kOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBzd2l0Y2ggKG1ldGhvZCkge1xuICAgICAgY2FzZSAnaW5pdGlhbGl6ZSc6XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAndG9vbHMvbGlzdCc6XG4gICAgICBjYXNlICd0b29scy9jYWxsJzpcbiAgICAgICAgaWYgKCF0aGlzLnNlcnZlckNhcGFiaWxpdGllcy50b29scykge1xuICAgICAgICAgIHRocm93IG5ldyBNQ1BDbGllbnRFcnJvcih7XG4gICAgICAgICAgICBtZXNzYWdlOiBgU2VydmVyIGRvZXMgbm90IHN1cHBvcnQgdG9vbHNgLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IE1DUENsaWVudEVycm9yKHtcbiAgICAgICAgICBtZXNzYWdlOiBgVW5zdXBwb3J0ZWQgbWV0aG9kOiAke21ldGhvZH1gLFxuICAgICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJlcXVlc3Q8VCBleHRlbmRzIHouWm9kVHlwZTxvYmplY3Q+Pih7XG4gICAgcmVxdWVzdCxcbiAgICByZXN1bHRTY2hlbWEsXG4gICAgb3B0aW9ucyxcbiAgfToge1xuICAgIHJlcXVlc3Q6IFJlcXVlc3Q7XG4gICAgcmVzdWx0U2NoZW1hOiBUO1xuICAgIG9wdGlvbnM/OiBSZXF1ZXN0T3B0aW9ucztcbiAgfSk6IFByb21pc2U8ei5pbmZlcjxUPj4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBpZiAodGhpcy5pc0Nsb3NlZCkge1xuICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgIG5ldyBNQ1BDbGllbnRFcnJvcih7XG4gICAgICAgICAgICBtZXNzYWdlOiAnQXR0ZW1wdGVkIHRvIHNlbmQgYSByZXF1ZXN0IGZyb20gYSBjbG9zZWQgY2xpZW50JyxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5hc3NlcnRDYXBhYmlsaXR5KHJlcXVlc3QubWV0aG9kKTtcblxuICAgICAgY29uc3Qgc2lnbmFsID0gb3B0aW9ucz8uc2lnbmFsO1xuICAgICAgc2lnbmFsPy50aHJvd0lmQWJvcnRlZCgpO1xuXG4gICAgICBjb25zdCBtZXNzYWdlSWQgPSB0aGlzLnJlcXVlc3RNZXNzYWdlSWQrKztcbiAgICAgIGNvbnN0IGpzb25ycGNSZXF1ZXN0OiBKU09OUlBDUmVxdWVzdCA9IHtcbiAgICAgICAgLi4ucmVxdWVzdCxcbiAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgIGlkOiBtZXNzYWdlSWQsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBjbGVhbnVwID0gKCkgPT4ge1xuICAgICAgICB0aGlzLnJlc3BvbnNlSGFuZGxlcnMuZGVsZXRlKG1lc3NhZ2VJZCk7XG4gICAgICB9O1xuXG4gICAgICB0aGlzLnJlc3BvbnNlSGFuZGxlcnMuc2V0KG1lc3NhZ2VJZCwgcmVzcG9uc2UgPT4ge1xuICAgICAgICBpZiAoc2lnbmFsPy5hYm9ydGVkKSB7XG4gICAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICAgIG5ldyBNQ1BDbGllbnRFcnJvcih7XG4gICAgICAgICAgICAgIG1lc3NhZ2U6ICdSZXF1ZXN0IHdhcyBhYm9ydGVkJyxcbiAgICAgICAgICAgICAgY2F1c2U6IHNpZ25hbC5yZWFzb24sXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHJlc3BvbnNlIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gcmVqZWN0KHJlc3BvbnNlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gcmVzdWx0U2NoZW1hLnBhcnNlKHJlc3BvbnNlLnJlc3VsdCk7XG4gICAgICAgICAgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIGNvbnN0IHBhcnNlRXJyb3IgPSBuZXcgTUNQQ2xpZW50RXJyb3Ioe1xuICAgICAgICAgICAgbWVzc2FnZTogJ0ZhaWxlZCB0byBwYXJzZSBzZXJ2ZXIgcmVzcG9uc2UnLFxuICAgICAgICAgICAgY2F1c2U6IGVycm9yLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJlamVjdChwYXJzZUVycm9yKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHRoaXMudHJhbnNwb3J0LnNlbmQoanNvbnJwY1JlcXVlc3QpLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgY2xlYW51cCgpO1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGxpc3RUb29scyh7XG4gICAgcGFyYW1zLFxuICAgIG9wdGlvbnMsXG4gIH06IHtcbiAgICBwYXJhbXM/OiBQYWdpbmF0ZWRSZXF1ZXN0WydwYXJhbXMnXTtcbiAgICBvcHRpb25zPzogUmVxdWVzdE9wdGlvbnM7XG4gIH0gPSB7fSk6IFByb21pc2U8TGlzdFRvb2xzUmVzdWx0PiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiB0aGlzLnJlcXVlc3Qoe1xuICAgICAgICByZXF1ZXN0OiB7IG1ldGhvZDogJ3Rvb2xzL2xpc3QnLCBwYXJhbXMgfSxcbiAgICAgICAgcmVzdWx0U2NoZW1hOiBMaXN0VG9vbHNSZXN1bHRTY2hlbWEsXG4gICAgICAgIG9wdGlvbnMsXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBjYWxsVG9vbCh7XG4gICAgbmFtZSxcbiAgICBhcmdzLFxuICAgIG9wdGlvbnMsXG4gIH06IHtcbiAgICBuYW1lOiBzdHJpbmc7XG4gICAgYXJnczogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgb3B0aW9ucz86IFRvb2xDYWxsT3B0aW9ucztcbiAgfSk6IFByb21pc2U8Q2FsbFRvb2xSZXN1bHQ+IHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHRoaXMucmVxdWVzdCh7XG4gICAgICAgIHJlcXVlc3Q6IHsgbWV0aG9kOiAndG9vbHMvY2FsbCcsIHBhcmFtczogeyBuYW1lLCBhcmd1bWVudHM6IGFyZ3MgfSB9LFxuICAgICAgICByZXN1bHRTY2hlbWE6IENhbGxUb29sUmVzdWx0U2NoZW1hLFxuICAgICAgICBvcHRpb25zOiB7XG4gICAgICAgICAgc2lnbmFsOiBvcHRpb25zPy5hYm9ydFNpZ25hbCxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIG5vdGlmaWNhdGlvbihub3RpZmljYXRpb246IE5vdGlmaWNhdGlvbik6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGpzb25ycGNOb3RpZmljYXRpb246IEpTT05SUENOb3RpZmljYXRpb24gPSB7XG4gICAgICAuLi5ub3RpZmljYXRpb24sXG4gICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICB9O1xuICAgIGF3YWl0IHRoaXMudHJhbnNwb3J0LnNlbmQoanNvbnJwY05vdGlmaWNhdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIHNldCBvZiBBSSBTREsgdG9vbHMgZnJvbSB0aGUgTUNQIHNlcnZlclxuICAgKiBAcmV0dXJucyBBIHJlY29yZCBvZiB0b29sIG5hbWVzIHRvIHRoZWlyIGltcGxlbWVudGF0aW9uc1xuICAgKi9cbiAgYXN5bmMgdG9vbHM8VE9PTF9TQ0hFTUFTIGV4dGVuZHMgVG9vbFNjaGVtYXMgPSAnYXV0b21hdGljJz4oe1xuICAgIHNjaGVtYXMgPSAnYXV0b21hdGljJyxcbiAgfToge1xuICAgIHNjaGVtYXM/OiBUT09MX1NDSEVNQVM7XG4gIH0gPSB7fSk6IFByb21pc2U8TWNwVG9vbFNldDxUT09MX1NDSEVNQVM+PiB7XG4gICAgY29uc3QgdG9vbHM6IFJlY29yZDxzdHJpbmcsIFRvb2w+ID0ge307XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgbGlzdFRvb2xzUmVzdWx0ID0gYXdhaXQgdGhpcy5saXN0VG9vbHMoKTtcblxuICAgICAgZm9yIChjb25zdCB7IG5hbWUsIGRlc2NyaXB0aW9uLCBpbnB1dFNjaGVtYSB9IG9mIGxpc3RUb29sc1Jlc3VsdC50b29scykge1xuICAgICAgICBpZiAoc2NoZW1hcyAhPT0gJ2F1dG9tYXRpYycgJiYgIShuYW1lIGluIHNjaGVtYXMpKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgICAgICBjb25zdCBleGVjdXRlID0gYXN5bmMgKFxuICAgICAgICAgIGFyZ3M6IGFueSxcbiAgICAgICAgICBvcHRpb25zOiBUb29sQ2FsbE9wdGlvbnMsXG4gICAgICAgICk6IFByb21pc2U8Q2FsbFRvb2xSZXN1bHQ+ID0+IHtcbiAgICAgICAgICBvcHRpb25zPy5hYm9ydFNpZ25hbD8udGhyb3dJZkFib3J0ZWQoKTtcbiAgICAgICAgICByZXR1cm4gc2VsZi5jYWxsVG9vbCh7IG5hbWUsIGFyZ3MsIG9wdGlvbnMgfSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgdG9vbFdpdGhFeGVjdXRlID1cbiAgICAgICAgICBzY2hlbWFzID09PSAnYXV0b21hdGljJ1xuICAgICAgICAgICAgPyBkeW5hbWljVG9vbCh7XG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb24sXG4gICAgICAgICAgICAgICAgaW5wdXRTY2hlbWE6IGpzb25TY2hlbWEoe1xuICAgICAgICAgICAgICAgICAgLi4uaW5wdXRTY2hlbWEsXG4gICAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzOiBpbnB1dFNjaGVtYS5wcm9wZXJ0aWVzID8/IHt9LFxuICAgICAgICAgICAgICAgICAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH0gYXMgSlNPTlNjaGVtYTcpLFxuICAgICAgICAgICAgICAgIGV4ZWN1dGUsXG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICA6IHRvb2woe1xuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uLFxuICAgICAgICAgICAgICAgIGlucHV0U2NoZW1hOiBzY2hlbWFzW25hbWVdLmlucHV0U2NoZW1hLFxuICAgICAgICAgICAgICAgIGV4ZWN1dGUsXG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIHRvb2xzW25hbWVdID0gdG9vbFdpdGhFeGVjdXRlO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdG9vbHMgYXMgTWNwVG9vbFNldDxUT09MX1NDSEVNQVM+O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG9uQ2xvc2UoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNDbG9zZWQpIHJldHVybjtcblxuICAgIHRoaXMuaXNDbG9zZWQgPSB0cnVlO1xuICAgIGNvbnN0IGVycm9yID0gbmV3IE1DUENsaWVudEVycm9yKHtcbiAgICAgIG1lc3NhZ2U6ICdDb25uZWN0aW9uIGNsb3NlZCcsXG4gICAgfSk7XG5cbiAgICBmb3IgKGNvbnN0IGhhbmRsZXIgb2YgdGhpcy5yZXNwb25zZUhhbmRsZXJzLnZhbHVlcygpKSB7XG4gICAgICBoYW5kbGVyKGVycm9yKTtcbiAgICB9XG5cbiAgICB0aGlzLnJlc3BvbnNlSGFuZGxlcnMuY2xlYXIoKTtcbiAgfVxuXG4gIHByaXZhdGUgb25FcnJvcihlcnJvcjogdW5rbm93bik6IHZvaWQge1xuICAgIGlmICh0aGlzLm9uVW5jYXVnaHRFcnJvcikge1xuICAgICAgdGhpcy5vblVuY2F1Z2h0RXJyb3IoZXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgb25SZXNwb25zZShyZXNwb25zZTogSlNPTlJQQ1Jlc3BvbnNlIHwgSlNPTlJQQ0Vycm9yKTogdm9pZCB7XG4gICAgY29uc3QgbWVzc2FnZUlkID0gTnVtYmVyKHJlc3BvbnNlLmlkKTtcbiAgICBjb25zdCBoYW5kbGVyID0gdGhpcy5yZXNwb25zZUhhbmRsZXJzLmdldChtZXNzYWdlSWQpO1xuXG4gICAgaWYgKGhhbmRsZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IE1DUENsaWVudEVycm9yKHtcbiAgICAgICAgbWVzc2FnZTogYFByb3RvY29sIGVycm9yOiBSZWNlaXZlZCBhIHJlc3BvbnNlIGZvciBhbiB1bmtub3duIG1lc3NhZ2UgSUQ6ICR7SlNPTi5zdHJpbmdpZnkoXG4gICAgICAgICAgcmVzcG9uc2UsXG4gICAgICAgICl9YCxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMucmVzcG9uc2VIYW5kbGVycy5kZWxldGUobWVzc2FnZUlkKTtcblxuICAgIGhhbmRsZXIoXG4gICAgICAncmVzdWx0JyBpbiByZXNwb25zZVxuICAgICAgICA/IHJlc3BvbnNlXG4gICAgICAgIDogbmV3IE1DUENsaWVudEVycm9yKHtcbiAgICAgICAgICAgIG1lc3NhZ2U6IHJlc3BvbnNlLmVycm9yLm1lc3NhZ2UsXG4gICAgICAgICAgICBjb2RlOiByZXNwb25zZS5lcnJvci5jb2RlLFxuICAgICAgICAgICAgZGF0YTogcmVzcG9uc2UuZXJyb3IuZGF0YSxcbiAgICAgICAgICAgIGNhdXNlOiByZXNwb25zZS5lcnJvcixcbiAgICAgICAgICB9KSxcbiAgICApO1xuICB9XG59XG4iLCAiaW1wb3J0IHtcbiAgRXZlbnRTb3VyY2VQYXJzZXJTdHJlYW0sXG4gIHdpdGhVc2VyQWdlbnRTdWZmaXgsXG4gIGdldFJ1bnRpbWVFbnZpcm9ubWVudFVzZXJBZ2VudCxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyBNQ1BDbGllbnRFcnJvciB9IGZyb20gJy4uLy4uL2Vycm9yL21jcC1jbGllbnQtZXJyb3InO1xuaW1wb3J0IHsgSlNPTlJQQ01lc3NhZ2UsIEpTT05SUENNZXNzYWdlU2NoZW1hIH0gZnJvbSAnLi9qc29uLXJwYy1tZXNzYWdlJztcbmltcG9ydCB7IE1DUFRyYW5zcG9ydCB9IGZyb20gJy4vbWNwLXRyYW5zcG9ydCc7XG5pbXBvcnQgeyBWRVJTSU9OIH0gZnJvbSAnLi4vLi4vdmVyc2lvbic7XG5cbmV4cG9ydCBjbGFzcyBTc2VNQ1BUcmFuc3BvcnQgaW1wbGVtZW50cyBNQ1BUcmFuc3BvcnQge1xuICBwcml2YXRlIGVuZHBvaW50PzogVVJMO1xuICBwcml2YXRlIGFib3J0Q29udHJvbGxlcj86IEFib3J0Q29udHJvbGxlcjtcbiAgcHJpdmF0ZSB1cmw6IFVSTDtcbiAgcHJpdmF0ZSBjb25uZWN0ZWQgPSBmYWxzZTtcbiAgcHJpdmF0ZSBzc2VDb25uZWN0aW9uPzoge1xuICAgIGNsb3NlOiAoKSA9PiB2b2lkO1xuICB9O1xuICBwcml2YXRlIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuXG4gIG9uY2xvc2U/OiAoKSA9PiB2b2lkO1xuICBvbmVycm9yPzogKGVycm9yOiB1bmtub3duKSA9PiB2b2lkO1xuICBvbm1lc3NhZ2U/OiAobWVzc2FnZTogSlNPTlJQQ01lc3NhZ2UpID0+IHZvaWQ7XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIHVybCxcbiAgICBoZWFkZXJzLFxuICB9OiB7XG4gICAgdXJsOiBzdHJpbmc7XG4gICAgaGVhZGVycz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIH0pIHtcbiAgICB0aGlzLnVybCA9IG5ldyBVUkwodXJsKTtcbiAgICB0aGlzLmhlYWRlcnMgPSBoZWFkZXJzO1xuICB9XG5cbiAgYXN5bmMgc3RhcnQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGlmICh0aGlzLmNvbm5lY3RlZCkge1xuICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmFib3J0Q29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcblxuICAgICAgY29uc3QgZXN0YWJsaXNoQ29ubmVjdGlvbiA9IGFzeW5jICgpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBoZWFkZXJzID0gd2l0aFVzZXJBZ2VudFN1ZmZpeChcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgLi4udGhpcy5oZWFkZXJzLFxuICAgICAgICAgICAgICBBY2NlcHQ6ICd0ZXh0L2V2ZW50LXN0cmVhbScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYGFpLXNkay8ke1ZFUlNJT059YCxcbiAgICAgICAgICAgIGdldFJ1bnRpbWVFbnZpcm9ubWVudFVzZXJBZ2VudCgpLFxuICAgICAgICAgICk7XG4gICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh0aGlzLnVybC5ocmVmLCB7XG4gICAgICAgICAgICBoZWFkZXJzLFxuICAgICAgICAgICAgc2lnbmFsOiB0aGlzLmFib3J0Q29udHJvbGxlcj8uc2lnbmFsLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaWYgKCFyZXNwb25zZS5vayB8fCAhcmVzcG9uc2UuYm9keSkge1xuICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgTUNQQ2xpZW50RXJyb3Ioe1xuICAgICAgICAgICAgICBtZXNzYWdlOiBgTUNQIFNTRSBUcmFuc3BvcnQgRXJyb3I6ICR7cmVzcG9uc2Uuc3RhdHVzfSAke3Jlc3BvbnNlLnN0YXR1c1RleHR9YCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5vbmVycm9yPy4oZXJyb3IpO1xuICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3Qgc3RyZWFtID0gcmVzcG9uc2UuYm9keVxuICAgICAgICAgICAgLnBpcGVUaHJvdWdoKG5ldyBUZXh0RGVjb2RlclN0cmVhbSgpKVxuICAgICAgICAgICAgLnBpcGVUaHJvdWdoKG5ldyBFdmVudFNvdXJjZVBhcnNlclN0cmVhbSgpKTtcblxuICAgICAgICAgIGNvbnN0IHJlYWRlciA9IHN0cmVhbS5nZXRSZWFkZXIoKTtcblxuICAgICAgICAgIGNvbnN0IHByb2Nlc3NFdmVudHMgPSBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHsgZG9uZSwgdmFsdWUgfSA9IGF3YWl0IHJlYWRlci5yZWFkKCk7XG5cbiAgICAgICAgICAgICAgICBpZiAoZG9uZSkge1xuICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuY29ubmVjdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBNQ1BDbGllbnRFcnJvcih7XG4gICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTpcbiAgICAgICAgICAgICAgICAgICAgICAgICdNQ1AgU1NFIFRyYW5zcG9ydCBFcnJvcjogQ29ubmVjdGlvbiBjbG9zZWQgdW5leHBlY3RlZGx5JyxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY29uc3QgeyBldmVudCwgZGF0YSB9ID0gdmFsdWU7XG5cbiAgICAgICAgICAgICAgICBpZiAoZXZlbnQgPT09ICdlbmRwb2ludCcpIHtcbiAgICAgICAgICAgICAgICAgIHRoaXMuZW5kcG9pbnQgPSBuZXcgVVJMKGRhdGEsIHRoaXMudXJsKTtcblxuICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZW5kcG9pbnQub3JpZ2luICE9PSB0aGlzLnVybC5vcmlnaW4pIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE1DUENsaWVudEVycm9yKHtcbiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBgTUNQIFNTRSBUcmFuc3BvcnQgRXJyb3I6IEVuZHBvaW50IG9yaWdpbiBkb2VzIG5vdCBtYXRjaCBjb25uZWN0aW9uIG9yaWdpbjogJHt0aGlzLmVuZHBvaW50Lm9yaWdpbn1gLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZXZlbnQgPT09ICdtZXNzYWdlJykge1xuICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbWVzc2FnZSA9IEpTT05SUENNZXNzYWdlU2NoZW1hLnBhcnNlKFxuICAgICAgICAgICAgICAgICAgICAgIEpTT04ucGFyc2UoZGF0YSksXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25tZXNzYWdlPy4obWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlID0gbmV3IE1DUENsaWVudEVycm9yKHtcbiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOlxuICAgICAgICAgICAgICAgICAgICAgICAgJ01DUCBTU0UgVHJhbnNwb3J0IEVycm9yOiBGYWlsZWQgdG8gcGFyc2UgbWVzc2FnZScsXG4gICAgICAgICAgICAgICAgICAgICAgY2F1c2U6IGVycm9yLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vbmVycm9yPy4oZSk7XG4gICAgICAgICAgICAgICAgICAgIC8vIFdlIGRvIG5vdCB0aHJvdyBoZXJlIHNvIHdlIGNvbnRpbnVlIHByb2Nlc3NpbmcgZXZlbnRzIGFmdGVyIHJlcG9ydGluZyB0aGUgZXJyb3JcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yICYmIGVycm9yLm5hbWUgPT09ICdBYm9ydEVycm9yJykge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIHRoaXMub25lcnJvcj8uKGVycm9yKTtcbiAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgdGhpcy5zc2VDb25uZWN0aW9uID0ge1xuICAgICAgICAgICAgY2xvc2U6ICgpID0+IHJlYWRlci5jYW5jZWwoKSxcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgcHJvY2Vzc0V2ZW50cygpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yICYmIGVycm9yLm5hbWUgPT09ICdBYm9ydEVycm9yJykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRoaXMub25lcnJvcj8uKGVycm9yKTtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBlc3RhYmxpc2hDb25uZWN0aW9uKCk7XG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBjbG9zZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLmNvbm5lY3RlZCA9IGZhbHNlO1xuICAgIHRoaXMuc3NlQ29ubmVjdGlvbj8uY2xvc2UoKTtcbiAgICB0aGlzLmFib3J0Q29udHJvbGxlcj8uYWJvcnQoKTtcbiAgICB0aGlzLm9uY2xvc2U/LigpO1xuICB9XG5cbiAgYXN5bmMgc2VuZChtZXNzYWdlOiBKU09OUlBDTWVzc2FnZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghdGhpcy5lbmRwb2ludCB8fCAhdGhpcy5jb25uZWN0ZWQpIHtcbiAgICAgIHRocm93IG5ldyBNQ1BDbGllbnRFcnJvcih7XG4gICAgICAgIG1lc3NhZ2U6ICdNQ1AgU1NFIFRyYW5zcG9ydCBFcnJvcjogTm90IGNvbm5lY3RlZCcsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgaGVhZGVycyA9IHdpdGhVc2VyQWdlbnRTdWZmaXgoXG4gICAgICAgIHtcbiAgICAgICAgICAuLi50aGlzLmhlYWRlcnMsXG4gICAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgfSxcbiAgICAgICAgYGFpLXNkay8ke1ZFUlNJT059YCxcbiAgICAgICAgZ2V0UnVudGltZUVudmlyb25tZW50VXNlckFnZW50KCksXG4gICAgICApO1xuICAgICAgY29uc3QgaW5pdCA9IHtcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGhlYWRlcnMsXG4gICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KG1lc3NhZ2UpLFxuICAgICAgICBzaWduYWw6IHRoaXMuYWJvcnRDb250cm9sbGVyPy5zaWduYWwsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHRoaXMuZW5kcG9pbnQsIGluaXQpO1xuXG4gICAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICAgIGNvbnN0IHRleHQgPSBhd2FpdCByZXNwb25zZS50ZXh0KCkuY2F0Y2goKCkgPT4gbnVsbCk7XG4gICAgICAgIGNvbnN0IGVycm9yID0gbmV3IE1DUENsaWVudEVycm9yKHtcbiAgICAgICAgICBtZXNzYWdlOiBgTUNQIFNTRSBUcmFuc3BvcnQgRXJyb3I6IFBPU1RpbmcgdG8gZW5kcG9pbnQgKEhUVFAgJHtyZXNwb25zZS5zdGF0dXN9KTogJHt0ZXh0fWAsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm9uZXJyb3I/LihlcnJvcik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhpcy5vbmVycm9yPy4oZXJyb3IpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZGVzZXJpYWxpemVNZXNzYWdlKGxpbmU6IHN0cmluZyk6IEpTT05SUENNZXNzYWdlIHtcbiAgcmV0dXJuIEpTT05SUENNZXNzYWdlU2NoZW1hLnBhcnNlKEpTT04ucGFyc2UobGluZSkpO1xufVxuIiwgImltcG9ydCB7IHogfSBmcm9tICd6b2QvdjQnO1xuaW1wb3J0IHsgQmFzZVBhcmFtc1NjaGVtYSwgUmVxdWVzdFNjaGVtYSwgUmVzdWx0U2NoZW1hIH0gZnJvbSAnLi90eXBlcyc7XG5cbmNvbnN0IEpTT05SUENfVkVSU0lPTiA9ICcyLjAnO1xuXG5jb25zdCBKU09OUlBDUmVxdWVzdFNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAganNvbnJwYzogei5saXRlcmFsKEpTT05SUENfVkVSU0lPTiksXG4gICAgaWQ6IHoudW5pb24oW3ouc3RyaW5nKCksIHoubnVtYmVyKCkuaW50KCldKSxcbiAgfSlcbiAgLm1lcmdlKFJlcXVlc3RTY2hlbWEpXG4gIC5zdHJpY3QoKTtcblxuZXhwb3J0IHR5cGUgSlNPTlJQQ1JlcXVlc3QgPSB6LmluZmVyPHR5cGVvZiBKU09OUlBDUmVxdWVzdFNjaGVtYT47XG5cbmNvbnN0IEpTT05SUENSZXNwb25zZVNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAganNvbnJwYzogei5saXRlcmFsKEpTT05SUENfVkVSU0lPTiksXG4gICAgaWQ6IHoudW5pb24oW3ouc3RyaW5nKCksIHoubnVtYmVyKCkuaW50KCldKSxcbiAgICByZXN1bHQ6IFJlc3VsdFNjaGVtYSxcbiAgfSlcbiAgLnN0cmljdCgpO1xuXG5leHBvcnQgdHlwZSBKU09OUlBDUmVzcG9uc2UgPSB6LmluZmVyPHR5cGVvZiBKU09OUlBDUmVzcG9uc2VTY2hlbWE+O1xuXG5jb25zdCBKU09OUlBDRXJyb3JTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIGpzb25ycGM6IHoubGl0ZXJhbChKU09OUlBDX1ZFUlNJT04pLFxuICAgIGlkOiB6LnVuaW9uKFt6LnN0cmluZygpLCB6Lm51bWJlcigpLmludCgpXSksXG4gICAgZXJyb3I6IHoub2JqZWN0KHtcbiAgICAgIGNvZGU6IHoubnVtYmVyKCkuaW50KCksXG4gICAgICBtZXNzYWdlOiB6LnN0cmluZygpLFxuICAgICAgZGF0YTogei5vcHRpb25hbCh6LnVua25vd24oKSksXG4gICAgfSksXG4gIH0pXG4gIC5zdHJpY3QoKTtcblxuZXhwb3J0IHR5cGUgSlNPTlJQQ0Vycm9yID0gei5pbmZlcjx0eXBlb2YgSlNPTlJQQ0Vycm9yU2NoZW1hPjtcblxuY29uc3QgSlNPTlJQQ05vdGlmaWNhdGlvblNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAganNvbnJwYzogei5saXRlcmFsKEpTT05SUENfVkVSU0lPTiksXG4gIH0pXG4gIC5tZXJnZShcbiAgICB6Lm9iamVjdCh7XG4gICAgICBtZXRob2Q6IHouc3RyaW5nKCksXG4gICAgICBwYXJhbXM6IHoub3B0aW9uYWwoQmFzZVBhcmFtc1NjaGVtYSksXG4gICAgfSksXG4gIClcbiAgLnN0cmljdCgpO1xuXG5leHBvcnQgdHlwZSBKU09OUlBDTm90aWZpY2F0aW9uID0gei5pbmZlcjx0eXBlb2YgSlNPTlJQQ05vdGlmaWNhdGlvblNjaGVtYT47XG5cbmV4cG9ydCBjb25zdCBKU09OUlBDTWVzc2FnZVNjaGVtYSA9IHoudW5pb24oW1xuICBKU09OUlBDUmVxdWVzdFNjaGVtYSxcbiAgSlNPTlJQQ05vdGlmaWNhdGlvblNjaGVtYSxcbiAgSlNPTlJQQ1Jlc3BvbnNlU2NoZW1hLFxuICBKU09OUlBDRXJyb3JTY2hlbWEsXG5dKTtcblxuZXhwb3J0IHR5cGUgSlNPTlJQQ01lc3NhZ2UgPSB6LmluZmVyPHR5cGVvZiBKU09OUlBDTWVzc2FnZVNjaGVtYT47XG4iLCAiaW1wb3J0IHsgeiB9IGZyb20gJ3pvZC92NCc7XG5pbXBvcnQgeyBKU09OT2JqZWN0IH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQgeyBGbGV4aWJsZVNjaGVtYSwgVG9vbCB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXItdXRpbHMnO1xuXG5leHBvcnQgY29uc3QgTEFURVNUX1BST1RPQ09MX1ZFUlNJT04gPSAnMjAyNS0wNi0xOCc7XG5leHBvcnQgY29uc3QgU1VQUE9SVEVEX1BST1RPQ09MX1ZFUlNJT05TID0gW1xuICBMQVRFU1RfUFJPVE9DT0xfVkVSU0lPTixcbiAgJzIwMjUtMDMtMjYnLFxuICAnMjAyNC0xMS0wNScsXG5dO1xuXG5leHBvcnQgdHlwZSBUb29sU2NoZW1hcyA9XG4gIHwgUmVjb3JkPHN0cmluZywgeyBpbnB1dFNjaGVtYTogRmxleGlibGVTY2hlbWE8SlNPTk9iamVjdCB8IHVua25vd24+IH0+XG4gIHwgJ2F1dG9tYXRpYydcbiAgfCB1bmRlZmluZWQ7XG5cbmV4cG9ydCB0eXBlIE1jcFRvb2xTZXQ8VE9PTF9TQ0hFTUFTIGV4dGVuZHMgVG9vbFNjaGVtYXMgPSAnYXV0b21hdGljJz4gPVxuICBUT09MX1NDSEVNQVMgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCB7IGlucHV0U2NoZW1hOiBGbGV4aWJsZVNjaGVtYTxhbnk+IH0+XG4gICAgPyB7XG4gICAgICAgIFtLIGluIGtleW9mIFRPT0xfU0NIRU1BU106IFRPT0xfU0NIRU1BU1tLXSBleHRlbmRzIHtcbiAgICAgICAgICBpbnB1dFNjaGVtYTogRmxleGlibGVTY2hlbWE8aW5mZXIgSU5QVVQ+O1xuICAgICAgICB9XG4gICAgICAgICAgPyBUb29sPElOUFVULCBDYWxsVG9vbFJlc3VsdD4gJlxuICAgICAgICAgICAgICBSZXF1aXJlZDxQaWNrPFRvb2w8SU5QVVQsIENhbGxUb29sUmVzdWx0PiwgJ2V4ZWN1dGUnPj5cbiAgICAgICAgICA6IG5ldmVyO1xuICAgICAgfVxuICAgIDogTWNwVG9vbFNldDxSZWNvcmQ8c3RyaW5nLCB7IGlucHV0U2NoZW1hOiBGbGV4aWJsZVNjaGVtYTx1bmtub3duPiB9Pj47XG5cbmNvbnN0IENsaWVudE9yU2VydmVySW1wbGVtZW50YXRpb25TY2hlbWEgPSB6Lmxvb3NlT2JqZWN0KHtcbiAgbmFtZTogei5zdHJpbmcoKSxcbiAgdmVyc2lvbjogei5zdHJpbmcoKSxcbn0pO1xuXG5leHBvcnQgdHlwZSBDb25maWd1cmF0aW9uID0gei5pbmZlcjx0eXBlb2YgQ2xpZW50T3JTZXJ2ZXJJbXBsZW1lbnRhdGlvblNjaGVtYT47XG5cbmV4cG9ydCBjb25zdCBCYXNlUGFyYW1zU2NoZW1hID0gei5sb29zZU9iamVjdCh7XG4gIF9tZXRhOiB6Lm9wdGlvbmFsKHoub2JqZWN0KHt9KS5sb29zZSgpKSxcbn0pO1xudHlwZSBCYXNlUGFyYW1zID0gei5pbmZlcjx0eXBlb2YgQmFzZVBhcmFtc1NjaGVtYT47XG5leHBvcnQgY29uc3QgUmVzdWx0U2NoZW1hID0gQmFzZVBhcmFtc1NjaGVtYTtcblxuZXhwb3J0IGNvbnN0IFJlcXVlc3RTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIG1ldGhvZDogei5zdHJpbmcoKSxcbiAgcGFyYW1zOiB6Lm9wdGlvbmFsKEJhc2VQYXJhbXNTY2hlbWEpLFxufSk7XG5leHBvcnQgdHlwZSBSZXF1ZXN0ID0gei5pbmZlcjx0eXBlb2YgUmVxdWVzdFNjaGVtYT47XG5leHBvcnQgdHlwZSBSZXF1ZXN0T3B0aW9ucyA9IHtcbiAgc2lnbmFsPzogQWJvcnRTaWduYWw7XG4gIHRpbWVvdXQ/OiBudW1iZXI7XG4gIG1heFRvdGFsVGltZW91dD86IG51bWJlcjtcbn07XG5cbmV4cG9ydCB0eXBlIE5vdGlmaWNhdGlvbiA9IHouaW5mZXI8dHlwZW9mIFJlcXVlc3RTY2hlbWE+O1xuXG5jb25zdCBTZXJ2ZXJDYXBhYmlsaXRpZXNTY2hlbWEgPSB6Lmxvb3NlT2JqZWN0KHtcbiAgZXhwZXJpbWVudGFsOiB6Lm9wdGlvbmFsKHoub2JqZWN0KHt9KS5sb29zZSgpKSxcbiAgbG9nZ2luZzogei5vcHRpb25hbCh6Lm9iamVjdCh7fSkubG9vc2UoKSksXG4gIHByb21wdHM6IHoub3B0aW9uYWwoXG4gICAgei5sb29zZU9iamVjdCh7XG4gICAgICBsaXN0Q2hhbmdlZDogei5vcHRpb25hbCh6LmJvb2xlYW4oKSksXG4gICAgfSksXG4gICksXG4gIHJlc291cmNlczogei5vcHRpb25hbChcbiAgICB6Lmxvb3NlT2JqZWN0KHtcbiAgICAgIHN1YnNjcmliZTogei5vcHRpb25hbCh6LmJvb2xlYW4oKSksXG4gICAgICBsaXN0Q2hhbmdlZDogei5vcHRpb25hbCh6LmJvb2xlYW4oKSksXG4gICAgfSksXG4gICksXG4gIHRvb2xzOiB6Lm9wdGlvbmFsKFxuICAgIHoubG9vc2VPYmplY3Qoe1xuICAgICAgbGlzdENoYW5nZWQ6IHoub3B0aW9uYWwoei5ib29sZWFuKCkpLFxuICAgIH0pLFxuICApLFxufSk7XG5cbmV4cG9ydCB0eXBlIFNlcnZlckNhcGFiaWxpdGllcyA9IHouaW5mZXI8dHlwZW9mIFNlcnZlckNhcGFiaWxpdGllc1NjaGVtYT47XG5cbmV4cG9ydCBjb25zdCBJbml0aWFsaXplUmVzdWx0U2NoZW1hID0gUmVzdWx0U2NoZW1hLmV4dGVuZCh7XG4gIHByb3RvY29sVmVyc2lvbjogei5zdHJpbmcoKSxcbiAgY2FwYWJpbGl0aWVzOiBTZXJ2ZXJDYXBhYmlsaXRpZXNTY2hlbWEsXG4gIHNlcnZlckluZm86IENsaWVudE9yU2VydmVySW1wbGVtZW50YXRpb25TY2hlbWEsXG4gIGluc3RydWN0aW9uczogei5vcHRpb25hbCh6LnN0cmluZygpKSxcbn0pO1xuZXhwb3J0IHR5cGUgSW5pdGlhbGl6ZVJlc3VsdCA9IHouaW5mZXI8dHlwZW9mIEluaXRpYWxpemVSZXN1bHRTY2hlbWE+O1xuXG5leHBvcnQgdHlwZSBQYWdpbmF0ZWRSZXF1ZXN0ID0gUmVxdWVzdCAmIHtcbiAgcGFyYW1zPzogQmFzZVBhcmFtcyAmIHtcbiAgICBjdXJzb3I/OiBzdHJpbmc7XG4gIH07XG59O1xuXG5jb25zdCBQYWdpbmF0ZWRSZXN1bHRTY2hlbWEgPSBSZXN1bHRTY2hlbWEuZXh0ZW5kKHtcbiAgbmV4dEN1cnNvcjogei5vcHRpb25hbCh6LnN0cmluZygpKSxcbn0pO1xuXG5jb25zdCBUb29sU2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICBuYW1lOiB6LnN0cmluZygpLFxuICAgIGRlc2NyaXB0aW9uOiB6Lm9wdGlvbmFsKHouc3RyaW5nKCkpLFxuICAgIGlucHV0U2NoZW1hOiB6XG4gICAgICAub2JqZWN0KHtcbiAgICAgICAgdHlwZTogei5saXRlcmFsKCdvYmplY3QnKSxcbiAgICAgICAgcHJvcGVydGllczogei5vcHRpb25hbCh6Lm9iamVjdCh7fSkubG9vc2UoKSksXG4gICAgICB9KVxuICAgICAgLmxvb3NlKCksXG4gIH0pXG4gIC5sb29zZSgpO1xuZXhwb3J0IHR5cGUgTUNQVG9vbCA9IHouaW5mZXI8dHlwZW9mIFRvb2xTY2hlbWE+O1xuZXhwb3J0IGNvbnN0IExpc3RUb29sc1Jlc3VsdFNjaGVtYSA9IFBhZ2luYXRlZFJlc3VsdFNjaGVtYS5leHRlbmQoe1xuICB0b29sczogei5hcnJheShUb29sU2NoZW1hKSxcbn0pO1xuZXhwb3J0IHR5cGUgTGlzdFRvb2xzUmVzdWx0ID0gei5pbmZlcjx0eXBlb2YgTGlzdFRvb2xzUmVzdWx0U2NoZW1hPjtcblxuY29uc3QgVGV4dENvbnRlbnRTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIHR5cGU6IHoubGl0ZXJhbCgndGV4dCcpLFxuICAgIHRleHQ6IHouc3RyaW5nKCksXG4gIH0pXG4gIC5sb29zZSgpO1xuY29uc3QgSW1hZ2VDb250ZW50U2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICB0eXBlOiB6LmxpdGVyYWwoJ2ltYWdlJyksXG4gICAgZGF0YTogei5iYXNlNjQoKSxcbiAgICBtaW1lVHlwZTogei5zdHJpbmcoKSxcbiAgfSlcbiAgLmxvb3NlKCk7XG5jb25zdCBSZXNvdXJjZUNvbnRlbnRzU2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICAvKipcbiAgICAgKiBUaGUgVVJJIG9mIHRoaXMgcmVzb3VyY2UuXG4gICAgICovXG4gICAgdXJpOiB6LnN0cmluZygpLFxuICAgIC8qKlxuICAgICAqIFRoZSBNSU1FIHR5cGUgb2YgdGhpcyByZXNvdXJjZSwgaWYga25vd24uXG4gICAgICovXG4gICAgbWltZVR5cGU6IHoub3B0aW9uYWwoei5zdHJpbmcoKSksXG4gIH0pXG4gIC5sb29zZSgpO1xuY29uc3QgVGV4dFJlc291cmNlQ29udGVudHNTY2hlbWEgPSBSZXNvdXJjZUNvbnRlbnRzU2NoZW1hLmV4dGVuZCh7XG4gIHRleHQ6IHouc3RyaW5nKCksXG59KTtcbmNvbnN0IEJsb2JSZXNvdXJjZUNvbnRlbnRzU2NoZW1hID0gUmVzb3VyY2VDb250ZW50c1NjaGVtYS5leHRlbmQoe1xuICBibG9iOiB6LmJhc2U2NCgpLFxufSk7XG5jb25zdCBFbWJlZGRlZFJlc291cmNlU2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICB0eXBlOiB6LmxpdGVyYWwoJ3Jlc291cmNlJyksXG4gICAgcmVzb3VyY2U6IHoudW5pb24oW1RleHRSZXNvdXJjZUNvbnRlbnRzU2NoZW1hLCBCbG9iUmVzb3VyY2VDb250ZW50c1NjaGVtYV0pLFxuICB9KVxuICAubG9vc2UoKTtcblxuZXhwb3J0IGNvbnN0IENhbGxUb29sUmVzdWx0U2NoZW1hID0gUmVzdWx0U2NoZW1hLmV4dGVuZCh7XG4gIGNvbnRlbnQ6IHouYXJyYXkoXG4gICAgei51bmlvbihbVGV4dENvbnRlbnRTY2hlbWEsIEltYWdlQ29udGVudFNjaGVtYSwgRW1iZWRkZWRSZXNvdXJjZVNjaGVtYV0pLFxuICApLFxuICBpc0Vycm9yOiB6LmJvb2xlYW4oKS5kZWZhdWx0KGZhbHNlKS5vcHRpb25hbCgpLFxufSkub3IoXG4gIFJlc3VsdFNjaGVtYS5leHRlbmQoe1xuICAgIHRvb2xSZXN1bHQ6IHoudW5rbm93bigpLFxuICB9KSxcbik7XG5leHBvcnQgdHlwZSBDYWxsVG9vbFJlc3VsdCA9IHouaW5mZXI8dHlwZW9mIENhbGxUb29sUmVzdWx0U2NoZW1hPjtcbiIsICJpbXBvcnQgeyBNQ1BDbGllbnRFcnJvciB9IGZyb20gJy4uLy4uL2Vycm9yL21jcC1jbGllbnQtZXJyb3InO1xuaW1wb3J0IHsgSlNPTlJQQ01lc3NhZ2UgfSBmcm9tICcuL2pzb24tcnBjLW1lc3NhZ2UnO1xuaW1wb3J0IHsgU3NlTUNQVHJhbnNwb3J0IH0gZnJvbSAnLi9tY3Atc3NlLXRyYW5zcG9ydCc7XG5cbi8qKlxuICogVHJhbnNwb3J0IGludGVyZmFjZSBmb3IgTUNQIChNb2RlbCBDb250ZXh0IFByb3RvY29sKSBjb21tdW5pY2F0aW9uLlxuICogTWFwcyB0byB0aGUgYFRyYW5zcG9ydGAgaW50ZXJmYWNlIGluIHRoZSBNQ1Agc3BlYy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBNQ1BUcmFuc3BvcnQge1xuICAvKipcbiAgICogSW5pdGlhbGl6ZSBhbmQgc3RhcnQgdGhlIHRyYW5zcG9ydFxuICAgKi9cbiAgc3RhcnQoKTogUHJvbWlzZTx2b2lkPjtcblxuICAvKipcbiAgICogU2VuZCBhIEpTT04tUlBDIG1lc3NhZ2UgdGhyb3VnaCB0aGUgdHJhbnNwb3J0XG4gICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBKU09OLVJQQyBtZXNzYWdlIHRvIHNlbmRcbiAgICovXG4gIHNlbmQobWVzc2FnZTogSlNPTlJQQ01lc3NhZ2UpOiBQcm9taXNlPHZvaWQ+O1xuXG4gIC8qKlxuICAgKiBDbGVhbiB1cCBhbmQgY2xvc2UgdGhlIHRyYW5zcG9ydFxuICAgKi9cbiAgY2xvc2UoKTogUHJvbWlzZTx2b2lkPjtcblxuICAvKipcbiAgICogRXZlbnQgaGFuZGxlciBmb3IgdHJhbnNwb3J0IGNsb3N1cmVcbiAgICovXG4gIG9uY2xvc2U/OiAoKSA9PiB2b2lkO1xuXG4gIC8qKlxuICAgKiBFdmVudCBoYW5kbGVyIGZvciB0cmFuc3BvcnQgZXJyb3JzXG4gICAqL1xuICBvbmVycm9yPzogKGVycm9yOiBFcnJvcikgPT4gdm9pZDtcblxuICAvKipcbiAgICogRXZlbnQgaGFuZGxlciBmb3IgcmVjZWl2ZWQgbWVzc2FnZXNcbiAgICovXG4gIG9ubWVzc2FnZT86IChtZXNzYWdlOiBKU09OUlBDTWVzc2FnZSkgPT4gdm9pZDtcbn1cblxuZXhwb3J0IHR5cGUgTUNQVHJhbnNwb3J0Q29uZmlnID0ge1xuICB0eXBlOiAnc3NlJztcblxuICAvKipcbiAgICogVGhlIFVSTCBvZiB0aGUgTUNQIHNlcnZlci5cbiAgICovXG4gIHVybDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBZGRpdGlvbmFsIEhUVFAgaGVhZGVycyB0byBiZSBzZW50IHdpdGggcmVxdWVzdHMuXG4gICAqL1xuICBoZWFkZXJzPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVNY3BUcmFuc3BvcnQoY29uZmlnOiBNQ1BUcmFuc3BvcnRDb25maWcpOiBNQ1BUcmFuc3BvcnQge1xuICBpZiAoY29uZmlnLnR5cGUgIT09ICdzc2UnKSB7XG4gICAgdGhyb3cgbmV3IE1DUENsaWVudEVycm9yKHtcbiAgICAgIG1lc3NhZ2U6XG4gICAgICAgICdVbnN1cHBvcnRlZCBvciBpbnZhbGlkIHRyYW5zcG9ydCBjb25maWd1cmF0aW9uLiBJZiB5b3UgYXJlIHVzaW5nIGEgY3VzdG9tIHRyYW5zcG9ydCwgbWFrZSBzdXJlIGl0IGltcGxlbWVudHMgdGhlIE1DUFRyYW5zcG9ydCBpbnRlcmZhY2UuJyxcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBuZXcgU3NlTUNQVHJhbnNwb3J0KGNvbmZpZyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0N1c3RvbU1jcFRyYW5zcG9ydChcbiAgdHJhbnNwb3J0OiBNQ1BUcmFuc3BvcnRDb25maWcgfCBNQ1BUcmFuc3BvcnQsXG4pOiB0cmFuc3BvcnQgaXMgTUNQVHJhbnNwb3J0IHtcbiAgcmV0dXJuIChcbiAgICAnc3RhcnQnIGluIHRyYW5zcG9ydCAmJlxuICAgIHR5cGVvZiB0cmFuc3BvcnQuc3RhcnQgPT09ICdmdW5jdGlvbicgJiZcbiAgICAnc2VuZCcgaW4gdHJhbnNwb3J0ICYmXG4gICAgdHlwZW9mIHRyYW5zcG9ydC5zZW5kID09PSAnZnVuY3Rpb24nICYmXG4gICAgJ2Nsb3NlJyBpbiB0cmFuc3BvcnQgJiZcbiAgICB0eXBlb2YgdHJhbnNwb3J0LmNsb3NlID09PSAnZnVuY3Rpb24nXG4gICk7XG59XG4iLCAiaW1wb3J0IHsgSlNPTlZhbHVlLCBUcmFuc2NyaXB0aW9uTW9kZWxWMiB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgUHJvdmlkZXJPcHRpb25zLCB3aXRoVXNlckFnZW50U3VmZml4IH0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyBOb1RyYW5zY3JpcHRHZW5lcmF0ZWRFcnJvciB9IGZyb20gJy4uL2Vycm9yL25vLXRyYW5zY3JpcHQtZ2VuZXJhdGVkLWVycm9yJztcbmltcG9ydCB7IFVuc3VwcG9ydGVkTW9kZWxWZXJzaW9uRXJyb3IgfSBmcm9tICcuLi9lcnJvci91bnN1cHBvcnRlZC1tb2RlbC12ZXJzaW9uLWVycm9yJztcbmltcG9ydCB7IGxvZ1dhcm5pbmdzIH0gZnJvbSAnLi4vbG9nZ2VyL2xvZy13YXJuaW5ncyc7XG5pbXBvcnQgeyBEYXRhQ29udGVudCB9IGZyb20gJy4uL3Byb21wdCc7XG5pbXBvcnQgeyBjb252ZXJ0RGF0YUNvbnRlbnRUb1VpbnQ4QXJyYXkgfSBmcm9tICcuLi9wcm9tcHQvZGF0YS1jb250ZW50JztcbmltcG9ydCB7IFRyYW5zY3JpcHRpb25XYXJuaW5nIH0gZnJvbSAnLi4vdHlwZXMvdHJhbnNjcmlwdGlvbi1tb2RlbCc7XG5pbXBvcnQgeyBUcmFuc2NyaXB0aW9uTW9kZWxSZXNwb25zZU1ldGFkYXRhIH0gZnJvbSAnLi4vdHlwZXMvdHJhbnNjcmlwdGlvbi1tb2RlbC1yZXNwb25zZS1tZXRhZGF0YSc7XG5pbXBvcnQge1xuICBhdWRpb01lZGlhVHlwZVNpZ25hdHVyZXMsXG4gIGRldGVjdE1lZGlhVHlwZSxcbn0gZnJvbSAnLi4vdXRpbC9kZXRlY3QtbWVkaWEtdHlwZSc7XG5pbXBvcnQgeyBkb3dubG9hZCB9IGZyb20gJy4uL3V0aWwvZG93bmxvYWQvZG93bmxvYWQnO1xuaW1wb3J0IHsgcHJlcGFyZVJldHJpZXMgfSBmcm9tICcuLi91dGlsL3ByZXBhcmUtcmV0cmllcyc7XG5pbXBvcnQgeyBUcmFuc2NyaXB0aW9uUmVzdWx0IH0gZnJvbSAnLi90cmFuc2NyaWJlLXJlc3VsdCc7XG5pbXBvcnQgeyBWRVJTSU9OIH0gZnJvbSAnLi4vdmVyc2lvbic7XG4vKipcbkdlbmVyYXRlcyB0cmFuc2NyaXB0cyB1c2luZyBhIHRyYW5zY3JpcHRpb24gbW9kZWwuXG5cbkBwYXJhbSBtb2RlbCAtIFRoZSB0cmFuc2NyaXB0aW9uIG1vZGVsIHRvIHVzZS5cbkBwYXJhbSBhdWRpbyAtIFRoZSBhdWRpbyBkYXRhIHRvIHRyYW5zY3JpYmUgYXMgRGF0YUNvbnRlbnQgKHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBBcnJheUJ1ZmZlciB8IEJ1ZmZlcikgb3IgYSBVUkwuXG5AcGFyYW0gcHJvdmlkZXJPcHRpb25zIC0gQWRkaXRpb25hbCBwcm92aWRlci1zcGVjaWZpYyBvcHRpb25zIHRoYXQgYXJlIHBhc3NlZCB0aHJvdWdoIHRvIHRoZSBwcm92aWRlclxuYXMgYm9keSBwYXJhbWV0ZXJzLlxuQHBhcmFtIG1heFJldHJpZXMgLSBNYXhpbXVtIG51bWJlciBvZiByZXRyaWVzLiBTZXQgdG8gMCB0byBkaXNhYmxlIHJldHJpZXMuIERlZmF1bHQ6IDIuXG5AcGFyYW0gYWJvcnRTaWduYWwgLSBBbiBvcHRpb25hbCBhYm9ydCBzaWduYWwgdGhhdCBjYW4gYmUgdXNlZCB0byBjYW5jZWwgdGhlIGNhbGwuXG5AcGFyYW0gaGVhZGVycyAtIEFkZGl0aW9uYWwgSFRUUCBoZWFkZXJzIHRvIGJlIHNlbnQgd2l0aCB0aGUgcmVxdWVzdC4gT25seSBhcHBsaWNhYmxlIGZvciBIVFRQLWJhc2VkIHByb3ZpZGVycy5cblxuQHJldHVybnMgQSByZXN1bHQgb2JqZWN0IHRoYXQgY29udGFpbnMgdGhlIGdlbmVyYXRlZCB0cmFuc2NyaXB0LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gdHJhbnNjcmliZSh7XG4gIG1vZGVsLFxuICBhdWRpbyxcbiAgcHJvdmlkZXJPcHRpb25zID0ge30sXG4gIG1heFJldHJpZXM6IG1heFJldHJpZXNBcmcsXG4gIGFib3J0U2lnbmFsLFxuICBoZWFkZXJzLFxufToge1xuICAvKipcblRoZSB0cmFuc2NyaXB0aW9uIG1vZGVsIHRvIHVzZS5cbiAgICAgKi9cbiAgbW9kZWw6IFRyYW5zY3JpcHRpb25Nb2RlbFYyO1xuXG4gIC8qKlxuVGhlIGF1ZGlvIGRhdGEgdG8gdHJhbnNjcmliZS5cbiAgICovXG4gIGF1ZGlvOiBEYXRhQ29udGVudCB8IFVSTDtcblxuICAvKipcbkFkZGl0aW9uYWwgcHJvdmlkZXItc3BlY2lmaWMgb3B0aW9ucyB0aGF0IGFyZSBwYXNzZWQgdGhyb3VnaCB0byB0aGUgcHJvdmlkZXJcbmFzIGJvZHkgcGFyYW1ldGVycy5cblxuVGhlIG91dGVyIHJlY29yZCBpcyBrZXllZCBieSB0aGUgcHJvdmlkZXIgbmFtZSwgYW5kIHRoZSBpbm5lclxucmVjb3JkIGlzIGtleWVkIGJ5IHRoZSBwcm92aWRlci1zcGVjaWZpYyBtZXRhZGF0YSBrZXkuXG5gYGB0c1xue1xuICBcIm9wZW5haVwiOiB7XG4gICAgXCJ0ZW1wZXJhdHVyZVwiOiAwXG4gIH1cbn1cbmBgYFxuICAgICAqL1xuICBwcm92aWRlck9wdGlvbnM/OiBQcm92aWRlck9wdGlvbnM7XG5cbiAgLyoqXG5NYXhpbXVtIG51bWJlciBvZiByZXRyaWVzIHBlciB0cmFuc2NyaXB0IG1vZGVsIGNhbGwuIFNldCB0byAwIHRvIGRpc2FibGUgcmV0cmllcy5cblxuQGRlZmF1bHQgMlxuICAgKi9cbiAgbWF4UmV0cmllcz86IG51bWJlcjtcblxuICAvKipcbkFib3J0IHNpZ25hbC5cbiAqL1xuICBhYm9ydFNpZ25hbD86IEFib3J0U2lnbmFsO1xuXG4gIC8qKlxuQWRkaXRpb25hbCBoZWFkZXJzIHRvIGluY2x1ZGUgaW4gdGhlIHJlcXVlc3QuXG5Pbmx5IGFwcGxpY2FibGUgZm9yIEhUVFAtYmFzZWQgcHJvdmlkZXJzLlxuICovXG4gIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xufSk6IFByb21pc2U8VHJhbnNjcmlwdGlvblJlc3VsdD4ge1xuICBpZiAobW9kZWwuc3BlY2lmaWNhdGlvblZlcnNpb24gIT09ICd2MicpIHtcbiAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRNb2RlbFZlcnNpb25FcnJvcih7XG4gICAgICB2ZXJzaW9uOiBtb2RlbC5zcGVjaWZpY2F0aW9uVmVyc2lvbixcbiAgICAgIHByb3ZpZGVyOiBtb2RlbC5wcm92aWRlcixcbiAgICAgIG1vZGVsSWQ6IG1vZGVsLm1vZGVsSWQsXG4gICAgfSk7XG4gIH1cblxuICBjb25zdCB7IHJldHJ5IH0gPSBwcmVwYXJlUmV0cmllcyh7XG4gICAgbWF4UmV0cmllczogbWF4UmV0cmllc0FyZyxcbiAgICBhYm9ydFNpZ25hbCxcbiAgfSk7XG5cbiAgY29uc3QgaGVhZGVyc1dpdGhVc2VyQWdlbnQgPSB3aXRoVXNlckFnZW50U3VmZml4KFxuICAgIGhlYWRlcnMgPz8ge30sXG4gICAgYGFpLyR7VkVSU0lPTn1gLFxuICApO1xuXG4gIGNvbnN0IGF1ZGlvRGF0YSA9XG4gICAgYXVkaW8gaW5zdGFuY2VvZiBVUkxcbiAgICAgID8gKGF3YWl0IGRvd25sb2FkKHsgdXJsOiBhdWRpbyB9KSkuZGF0YVxuICAgICAgOiBjb252ZXJ0RGF0YUNvbnRlbnRUb1VpbnQ4QXJyYXkoYXVkaW8pO1xuXG4gIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJldHJ5KCgpID0+XG4gICAgbW9kZWwuZG9HZW5lcmF0ZSh7XG4gICAgICBhdWRpbzogYXVkaW9EYXRhLFxuICAgICAgYWJvcnRTaWduYWwsXG4gICAgICBoZWFkZXJzOiBoZWFkZXJzV2l0aFVzZXJBZ2VudCxcbiAgICAgIHByb3ZpZGVyT3B0aW9ucyxcbiAgICAgIG1lZGlhVHlwZTpcbiAgICAgICAgZGV0ZWN0TWVkaWFUeXBlKHtcbiAgICAgICAgICBkYXRhOiBhdWRpb0RhdGEsXG4gICAgICAgICAgc2lnbmF0dXJlczogYXVkaW9NZWRpYVR5cGVTaWduYXR1cmVzLFxuICAgICAgICB9KSA/PyAnYXVkaW8vd2F2JyxcbiAgICB9KSxcbiAgKTtcblxuICBsb2dXYXJuaW5ncyhyZXN1bHQud2FybmluZ3MpO1xuXG4gIGlmICghcmVzdWx0LnRleHQpIHtcbiAgICB0aHJvdyBuZXcgTm9UcmFuc2NyaXB0R2VuZXJhdGVkRXJyb3IoeyByZXNwb25zZXM6IFtyZXN1bHQucmVzcG9uc2VdIH0pO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBEZWZhdWx0VHJhbnNjcmlwdGlvblJlc3VsdCh7XG4gICAgdGV4dDogcmVzdWx0LnRleHQsXG4gICAgc2VnbWVudHM6IHJlc3VsdC5zZWdtZW50cyxcbiAgICBsYW5ndWFnZTogcmVzdWx0Lmxhbmd1YWdlLFxuICAgIGR1cmF0aW9uSW5TZWNvbmRzOiByZXN1bHQuZHVyYXRpb25JblNlY29uZHMsXG4gICAgd2FybmluZ3M6IHJlc3VsdC53YXJuaW5ncyxcbiAgICByZXNwb25zZXM6IFtyZXN1bHQucmVzcG9uc2VdLFxuICAgIHByb3ZpZGVyTWV0YWRhdGE6IHJlc3VsdC5wcm92aWRlck1ldGFkYXRhLFxuICB9KTtcbn1cblxuY2xhc3MgRGVmYXVsdFRyYW5zY3JpcHRpb25SZXN1bHQgaW1wbGVtZW50cyBUcmFuc2NyaXB0aW9uUmVzdWx0IHtcbiAgcmVhZG9ubHkgdGV4dDogc3RyaW5nO1xuICByZWFkb25seSBzZWdtZW50czogQXJyYXk8e1xuICAgIHRleHQ6IHN0cmluZztcbiAgICBzdGFydFNlY29uZDogbnVtYmVyO1xuICAgIGVuZFNlY29uZDogbnVtYmVyO1xuICB9PjtcbiAgcmVhZG9ubHkgbGFuZ3VhZ2U6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgcmVhZG9ubHkgZHVyYXRpb25JblNlY29uZHM6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgcmVhZG9ubHkgd2FybmluZ3M6IEFycmF5PFRyYW5zY3JpcHRpb25XYXJuaW5nPjtcbiAgcmVhZG9ubHkgcmVzcG9uc2VzOiBBcnJheTxUcmFuc2NyaXB0aW9uTW9kZWxSZXNwb25zZU1ldGFkYXRhPjtcbiAgcmVhZG9ubHkgcHJvdmlkZXJNZXRhZGF0YTogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgSlNPTlZhbHVlPj47XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczoge1xuICAgIHRleHQ6IHN0cmluZztcbiAgICBzZWdtZW50czogQXJyYXk8e1xuICAgICAgdGV4dDogc3RyaW5nO1xuICAgICAgc3RhcnRTZWNvbmQ6IG51bWJlcjtcbiAgICAgIGVuZFNlY29uZDogbnVtYmVyO1xuICAgIH0+O1xuICAgIGxhbmd1YWdlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgZHVyYXRpb25JblNlY29uZHM6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgICB3YXJuaW5nczogQXJyYXk8VHJhbnNjcmlwdGlvbldhcm5pbmc+O1xuICAgIHJlc3BvbnNlczogQXJyYXk8VHJhbnNjcmlwdGlvbk1vZGVsUmVzcG9uc2VNZXRhZGF0YT47XG4gICAgcHJvdmlkZXJNZXRhZGF0YTogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgSlNPTlZhbHVlPj4gfCB1bmRlZmluZWQ7XG4gIH0pIHtcbiAgICB0aGlzLnRleHQgPSBvcHRpb25zLnRleHQ7XG4gICAgdGhpcy5zZWdtZW50cyA9IG9wdGlvbnMuc2VnbWVudHM7XG4gICAgdGhpcy5sYW5ndWFnZSA9IG9wdGlvbnMubGFuZ3VhZ2U7XG4gICAgdGhpcy5kdXJhdGlvbkluU2Vjb25kcyA9IG9wdGlvbnMuZHVyYXRpb25JblNlY29uZHM7XG4gICAgdGhpcy53YXJuaW5ncyA9IG9wdGlvbnMud2FybmluZ3M7XG4gICAgdGhpcy5yZXNwb25zZXMgPSBvcHRpb25zLnJlc3BvbnNlcztcbiAgICB0aGlzLnByb3ZpZGVyTWV0YWRhdGEgPSBvcHRpb25zLnByb3ZpZGVyTWV0YWRhdGEgPz8ge307XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBBSVNES0Vycm9yIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQgeyBUcmFuc2NyaXB0aW9uTW9kZWxSZXNwb25zZU1ldGFkYXRhIH0gZnJvbSAnLi4vdHlwZXMvdHJhbnNjcmlwdGlvbi1tb2RlbC1yZXNwb25zZS1tZXRhZGF0YSc7XG5cbi8qKlxuRXJyb3IgdGhhdCBpcyB0aHJvd24gd2hlbiBubyB0cmFuc2NyaXB0IHdhcyBnZW5lcmF0ZWQuXG4gKi9cbmV4cG9ydCBjbGFzcyBOb1RyYW5zY3JpcHRHZW5lcmF0ZWRFcnJvciBleHRlbmRzIEFJU0RLRXJyb3Ige1xuICByZWFkb25seSByZXNwb25zZXM6IEFycmF5PFRyYW5zY3JpcHRpb25Nb2RlbFJlc3BvbnNlTWV0YWRhdGE+O1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IHtcbiAgICByZXNwb25zZXM6IEFycmF5PFRyYW5zY3JpcHRpb25Nb2RlbFJlc3BvbnNlTWV0YWRhdGE+O1xuICB9KSB7XG4gICAgc3VwZXIoe1xuICAgICAgbmFtZTogJ0FJX05vVHJhbnNjcmlwdEdlbmVyYXRlZEVycm9yJyxcbiAgICAgIG1lc3NhZ2U6ICdObyB0cmFuc2NyaXB0IGdlbmVyYXRlZC4nLFxuICAgIH0pO1xuXG4gICAgdGhpcy5yZXNwb25zZXMgPSBvcHRpb25zLnJlc3BvbnNlcztcbiAgfVxufVxuIiwgImltcG9ydCB7XG4gIHBhcnNlSnNvbkV2ZW50U3RyZWFtLFxuICBQYXJzZVJlc3VsdCxcbiAgd2l0aFVzZXJBZ2VudFN1ZmZpeCxcbiAgZ2V0UnVudGltZUVudmlyb25tZW50VXNlckFnZW50LFxufSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyLXV0aWxzJztcbmltcG9ydCB7XG4gIFVJTWVzc2FnZUNodW5rLFxuICB1aU1lc3NhZ2VDaHVua1NjaGVtYSxcbn0gZnJvbSAnLi4vdWktbWVzc2FnZS1zdHJlYW0vdWktbWVzc2FnZS1jaHVua3MnO1xuaW1wb3J0IHsgY29uc3VtZVN0cmVhbSB9IGZyb20gJy4uL3V0aWwvY29uc3VtZS1zdHJlYW0nO1xuaW1wb3J0IHsgcHJvY2Vzc1RleHRTdHJlYW0gfSBmcm9tICcuL3Byb2Nlc3MtdGV4dC1zdHJlYW0nO1xuaW1wb3J0IHsgVkVSU0lPTiB9IGZyb20gJy4uL3ZlcnNpb24nO1xuXG4vLyB1c2UgZnVuY3Rpb24gdG8gYWxsb3cgZm9yIG1vY2tpbmcgaW4gdGVzdHM6XG5jb25zdCBnZXRPcmlnaW5hbEZldGNoID0gKCkgPT4gZmV0Y2g7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjYWxsQ29tcGxldGlvbkFwaSh7XG4gIGFwaSxcbiAgcHJvbXB0LFxuICBjcmVkZW50aWFscyxcbiAgaGVhZGVycyxcbiAgYm9keSxcbiAgc3RyZWFtUHJvdG9jb2wgPSAnZGF0YScsXG4gIHNldENvbXBsZXRpb24sXG4gIHNldExvYWRpbmcsXG4gIHNldEVycm9yLFxuICBzZXRBYm9ydENvbnRyb2xsZXIsXG4gIG9uRmluaXNoLFxuICBvbkVycm9yLFxuICBmZXRjaCA9IGdldE9yaWdpbmFsRmV0Y2goKSxcbn06IHtcbiAgYXBpOiBzdHJpbmc7XG4gIHByb21wdDogc3RyaW5nO1xuICBjcmVkZW50aWFsczogUmVxdWVzdENyZWRlbnRpYWxzIHwgdW5kZWZpbmVkO1xuICBoZWFkZXJzOiBIZWFkZXJzSW5pdCB8IHVuZGVmaW5lZDtcbiAgYm9keTogUmVjb3JkPHN0cmluZywgYW55PjtcbiAgc3RyZWFtUHJvdG9jb2w6ICdkYXRhJyB8ICd0ZXh0JyB8IHVuZGVmaW5lZDtcbiAgc2V0Q29tcGxldGlvbjogKGNvbXBsZXRpb246IHN0cmluZykgPT4gdm9pZDtcbiAgc2V0TG9hZGluZzogKGxvYWRpbmc6IGJvb2xlYW4pID0+IHZvaWQ7XG4gIHNldEVycm9yOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkO1xuICBzZXRBYm9ydENvbnRyb2xsZXI6IChhYm9ydENvbnRyb2xsZXI6IEFib3J0Q29udHJvbGxlciB8IG51bGwpID0+IHZvaWQ7XG4gIG9uRmluaXNoOiAoKHByb21wdDogc3RyaW5nLCBjb21wbGV0aW9uOiBzdHJpbmcpID0+IHZvaWQpIHwgdW5kZWZpbmVkO1xuICBvbkVycm9yOiAoKGVycm9yOiBFcnJvcikgPT4gdm9pZCkgfCB1bmRlZmluZWQ7XG4gIGZldGNoOiBSZXR1cm5UeXBlPHR5cGVvZiBnZXRPcmlnaW5hbEZldGNoPiB8IHVuZGVmaW5lZDtcbn0pIHtcbiAgdHJ5IHtcbiAgICBzZXRMb2FkaW5nKHRydWUpO1xuICAgIHNldEVycm9yKHVuZGVmaW5lZCk7XG5cbiAgICBjb25zdCBhYm9ydENvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgc2V0QWJvcnRDb250cm9sbGVyKGFib3J0Q29udHJvbGxlcik7XG5cbiAgICAvLyBFbXB0eSB0aGUgY29tcGxldGlvbiBpbW1lZGlhdGVseS5cbiAgICBzZXRDb21wbGV0aW9uKCcnKTtcblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goYXBpLCB7XG4gICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgcHJvbXB0LFxuICAgICAgICAuLi5ib2R5LFxuICAgICAgfSksXG4gICAgICBjcmVkZW50aWFscyxcbiAgICAgIGhlYWRlcnM6IHdpdGhVc2VyQWdlbnRTdWZmaXgoXG4gICAgICAgIHtcbiAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICAgIC4uLmhlYWRlcnMsXG4gICAgICAgIH0sXG4gICAgICAgIGBhaS1zZGsvJHtWRVJTSU9OfWAsXG4gICAgICAgIGdldFJ1bnRpbWVFbnZpcm9ubWVudFVzZXJBZ2VudCgpLFxuICAgICAgKSxcbiAgICAgIHNpZ25hbDogYWJvcnRDb250cm9sbGVyLnNpZ25hbCxcbiAgICB9KS5jYXRjaChlcnIgPT4ge1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH0pO1xuXG4gICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAoYXdhaXQgcmVzcG9uc2UudGV4dCgpKSA/PyAnRmFpbGVkIHRvIGZldGNoIHRoZSBjaGF0IHJlc3BvbnNlLicsXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICghcmVzcG9uc2UuYm9keSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgcmVzcG9uc2UgYm9keSBpcyBlbXB0eS4nKTtcbiAgICB9XG5cbiAgICBsZXQgcmVzdWx0ID0gJyc7XG5cbiAgICBzd2l0Y2ggKHN0cmVhbVByb3RvY29sKSB7XG4gICAgICBjYXNlICd0ZXh0Jzoge1xuICAgICAgICBhd2FpdCBwcm9jZXNzVGV4dFN0cmVhbSh7XG4gICAgICAgICAgc3RyZWFtOiByZXNwb25zZS5ib2R5LFxuICAgICAgICAgIG9uVGV4dFBhcnQ6IGNodW5rID0+IHtcbiAgICAgICAgICAgIHJlc3VsdCArPSBjaHVuaztcbiAgICAgICAgICAgIHNldENvbXBsZXRpb24ocmVzdWx0KTtcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdkYXRhJzoge1xuICAgICAgICBhd2FpdCBjb25zdW1lU3RyZWFtKHtcbiAgICAgICAgICBzdHJlYW06IHBhcnNlSnNvbkV2ZW50U3RyZWFtKHtcbiAgICAgICAgICAgIHN0cmVhbTogcmVzcG9uc2UuYm9keSxcbiAgICAgICAgICAgIHNjaGVtYTogdWlNZXNzYWdlQ2h1bmtTY2hlbWEsXG4gICAgICAgICAgfSkucGlwZVRocm91Z2goXG4gICAgICAgICAgICBuZXcgVHJhbnNmb3JtU3RyZWFtPFBhcnNlUmVzdWx0PFVJTWVzc2FnZUNodW5rPiwgVUlNZXNzYWdlQ2h1bms+KHtcbiAgICAgICAgICAgICAgYXN5bmMgdHJhbnNmb3JtKHBhcnQpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXBhcnQuc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgICAgdGhyb3cgcGFydC5lcnJvcjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW1QYXJ0ID0gcGFydC52YWx1ZTtcbiAgICAgICAgICAgICAgICBpZiAoc3RyZWFtUGFydC50eXBlID09PSAndGV4dC1kZWx0YScpIHtcbiAgICAgICAgICAgICAgICAgIHJlc3VsdCArPSBzdHJlYW1QYXJ0LmRlbHRhO1xuICAgICAgICAgICAgICAgICAgc2V0Q29tcGxldGlvbihyZXN1bHQpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc3RyZWFtUGFydC50eXBlID09PSAnZXJyb3InKSB7XG4gICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3Ioc3RyZWFtUGFydC5lcnJvclRleHQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICksXG4gICAgICAgICAgb25FcnJvcjogZXJyb3IgPT4ge1xuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgZGVmYXVsdDoge1xuICAgICAgICBjb25zdCBleGhhdXN0aXZlQ2hlY2s6IG5ldmVyID0gc3RyZWFtUHJvdG9jb2w7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBzdHJlYW0gcHJvdG9jb2w6ICR7ZXhoYXVzdGl2ZUNoZWNrfWApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChvbkZpbmlzaCkge1xuICAgICAgb25GaW5pc2gocHJvbXB0LCByZXN1bHQpO1xuICAgIH1cblxuICAgIHNldEFib3J0Q29udHJvbGxlcihudWxsKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICAvLyBJZ25vcmUgYWJvcnQgZXJyb3JzIGFzIHRoZXkgYXJlIGV4cGVjdGVkLlxuICAgIGlmICgoZXJyIGFzIGFueSkubmFtZSA9PT0gJ0Fib3J0RXJyb3InKSB7XG4gICAgICBzZXRBYm9ydENvbnRyb2xsZXIobnVsbCk7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAoZXJyIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIGlmIChvbkVycm9yKSB7XG4gICAgICAgIG9uRXJyb3IoZXJyKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBzZXRFcnJvcihlcnIgYXMgRXJyb3IpO1xuICB9IGZpbmFsbHkge1xuICAgIHNldExvYWRpbmcoZmFsc2UpO1xuICB9XG59XG4iLCAiZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHByb2Nlc3NUZXh0U3RyZWFtKHtcbiAgc3RyZWFtLFxuICBvblRleHRQYXJ0LFxufToge1xuICBzdHJlYW06IFJlYWRhYmxlU3RyZWFtPFVpbnQ4QXJyYXk+O1xuICBvblRleHRQYXJ0OiAoY2h1bms6IHN0cmluZykgPT4gUHJvbWlzZTx2b2lkPiB8IHZvaWQ7XG59KTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHJlYWRlciA9IHN0cmVhbS5waXBlVGhyb3VnaChuZXcgVGV4dERlY29kZXJTdHJlYW0oKSkuZ2V0UmVhZGVyKCk7XG4gIHdoaWxlICh0cnVlKSB7XG4gICAgY29uc3QgeyBkb25lLCB2YWx1ZSB9ID0gYXdhaXQgcmVhZGVyLnJlYWQoKTtcbiAgICBpZiAoZG9uZSkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGF3YWl0IG9uVGV4dFBhcnQodmFsdWUpO1xuICB9XG59XG4iLCAiaW1wb3J0IHtcbiAgZ2VuZXJhdGVJZCBhcyBnZW5lcmF0ZUlkRnVuYyxcbiAgSWRHZW5lcmF0b3IsXG4gIFN0YW5kYXJkU2NoZW1hVjEsXG4gIFZhbGlkYXRvcixcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyBVSU1lc3NhZ2VDaHVuayB9IGZyb20gJy4uL3VpLW1lc3NhZ2Utc3RyZWFtL3VpLW1lc3NhZ2UtY2h1bmtzJztcbmltcG9ydCB7IGNvbnN1bWVTdHJlYW0gfSBmcm9tICcuLi91dGlsL2NvbnN1bWUtc3RyZWFtJztcbmltcG9ydCB7IFNlcmlhbEpvYkV4ZWN1dG9yIH0gZnJvbSAnLi4vdXRpbC9zZXJpYWwtam9iLWV4ZWN1dG9yJztcbmltcG9ydCB7IENoYXRUcmFuc3BvcnQgfSBmcm9tICcuL2NoYXQtdHJhbnNwb3J0JztcbmltcG9ydCB7IGNvbnZlcnRGaWxlTGlzdFRvRmlsZVVJUGFydHMgfSBmcm9tICcuL2NvbnZlcnQtZmlsZS1saXN0LXRvLWZpbGUtdWktcGFydHMnO1xuaW1wb3J0IHsgRGVmYXVsdENoYXRUcmFuc3BvcnQgfSBmcm9tICcuL2RlZmF1bHQtY2hhdC10cmFuc3BvcnQnO1xuaW1wb3J0IHtcbiAgY3JlYXRlU3RyZWFtaW5nVUlNZXNzYWdlU3RhdGUsXG4gIHByb2Nlc3NVSU1lc3NhZ2VTdHJlYW0sXG4gIFN0cmVhbWluZ1VJTWVzc2FnZVN0YXRlLFxufSBmcm9tICcuL3Byb2Nlc3MtdWktbWVzc2FnZS1zdHJlYW0nO1xuaW1wb3J0IHtcbiAgSW5mZXJVSU1lc3NhZ2VUb29sQ2FsbCxcbiAgaXNUb29sT3JEeW5hbWljVG9vbFVJUGFydCxcbiAgVG9vbFVJUGFydCxcbiAgdHlwZSBEYXRhVUlQYXJ0LFxuICB0eXBlIEZpbGVVSVBhcnQsXG4gIHR5cGUgSW5mZXJVSU1lc3NhZ2VEYXRhLFxuICB0eXBlIEluZmVyVUlNZXNzYWdlTWV0YWRhdGEsXG4gIHR5cGUgSW5mZXJVSU1lc3NhZ2VUb29scyxcbiAgdHlwZSBVSURhdGFUeXBlcyxcbiAgdHlwZSBVSU1lc3NhZ2UsXG59IGZyb20gJy4vdWktbWVzc2FnZXMnO1xuXG5leHBvcnQgdHlwZSBDcmVhdGVVSU1lc3NhZ2U8VUlfTUVTU0FHRSBleHRlbmRzIFVJTWVzc2FnZT4gPSBPbWl0PFxuICBVSV9NRVNTQUdFLFxuICAnaWQnIHwgJ3JvbGUnXG4+ICYge1xuICBpZD86IFVJX01FU1NBR0VbJ2lkJ107XG4gIHJvbGU/OiBVSV9NRVNTQUdFWydyb2xlJ107XG59O1xuXG5leHBvcnQgdHlwZSBVSURhdGFQYXJ0U2NoZW1hcyA9IFJlY29yZDxcbiAgc3RyaW5nLFxuICBWYWxpZGF0b3I8YW55PiB8IFN0YW5kYXJkU2NoZW1hVjE8YW55PlxuPjtcblxuZXhwb3J0IHR5cGUgVUlEYXRhVHlwZXNUb1NjaGVtYXM8VCBleHRlbmRzIFVJRGF0YVR5cGVzPiA9IHtcbiAgW0sgaW4ga2V5b2YgVF06IFZhbGlkYXRvcjxUW0tdPiB8IFN0YW5kYXJkU2NoZW1hVjE8VFtLXT47XG59O1xuXG5leHBvcnQgdHlwZSBJbmZlclVJRGF0YVBhcnRzPFQgZXh0ZW5kcyBVSURhdGFQYXJ0U2NoZW1hcz4gPSB7XG4gIFtLIGluIGtleW9mIFRdOiBUW0tdIGV4dGVuZHMgVmFsaWRhdG9yPGluZmVyIFU+XG4gICAgPyBVXG4gICAgOiBUW0tdIGV4dGVuZHMgU3RhbmRhcmRTY2hlbWFWMTxpbmZlciBVPlxuICAgICAgPyBVXG4gICAgICA6IHVua25vd247XG59O1xuXG5leHBvcnQgdHlwZSBDaGF0UmVxdWVzdE9wdGlvbnMgPSB7XG4gIC8qKlxuICBBZGRpdGlvbmFsIGhlYWRlcnMgdGhhdCBzaG91bGQgYmUgdG8gYmUgcGFzc2VkIHRvIHRoZSBBUEkgZW5kcG9pbnQuXG4gICAqL1xuICBoZWFkZXJzPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB8IEhlYWRlcnM7XG5cbiAgLyoqXG4gIEFkZGl0aW9uYWwgYm9keSBKU09OIHByb3BlcnRpZXMgdGhhdCBzaG91bGQgYmUgc2VudCB0byB0aGUgQVBJIGVuZHBvaW50LlxuICAgKi9cbiAgYm9keT86IG9iamVjdDsgLy8gVE9ETyBKU09OU3RyaW5naWZ5YWJsZVxuXG4gIG1ldGFkYXRhPzogdW5rbm93bjtcbn07XG5cbmV4cG9ydCB0eXBlIENoYXRTdGF0dXMgPSAnc3VibWl0dGVkJyB8ICdzdHJlYW1pbmcnIHwgJ3JlYWR5JyB8ICdlcnJvcic7XG5cbnR5cGUgQWN0aXZlUmVzcG9uc2U8VUlfTUVTU0FHRSBleHRlbmRzIFVJTWVzc2FnZT4gPSB7XG4gIHN0YXRlOiBTdHJlYW1pbmdVSU1lc3NhZ2VTdGF0ZTxVSV9NRVNTQUdFPjtcbiAgYWJvcnRDb250cm9sbGVyOiBBYm9ydENvbnRyb2xsZXI7XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIENoYXRTdGF0ZTxVSV9NRVNTQUdFIGV4dGVuZHMgVUlNZXNzYWdlPiB7XG4gIHN0YXR1czogQ2hhdFN0YXR1cztcblxuICBlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQ7XG5cbiAgbWVzc2FnZXM6IFVJX01FU1NBR0VbXTtcbiAgcHVzaE1lc3NhZ2U6IChtZXNzYWdlOiBVSV9NRVNTQUdFKSA9PiB2b2lkO1xuICBwb3BNZXNzYWdlOiAoKSA9PiB2b2lkO1xuICByZXBsYWNlTWVzc2FnZTogKGluZGV4OiBudW1iZXIsIG1lc3NhZ2U6IFVJX01FU1NBR0UpID0+IHZvaWQ7XG5cbiAgc25hcHNob3Q6IDxUPih0aGluZzogVCkgPT4gVDtcbn1cblxuZXhwb3J0IHR5cGUgQ2hhdE9uRXJyb3JDYWxsYmFjayA9IChlcnJvcjogRXJyb3IpID0+IHZvaWQ7XG5cbmV4cG9ydCB0eXBlIENoYXRPblRvb2xDYWxsQ2FsbGJhY2s8VUlfTUVTU0FHRSBleHRlbmRzIFVJTWVzc2FnZSA9IFVJTWVzc2FnZT4gPVxuICAob3B0aW9uczoge1xuICAgIHRvb2xDYWxsOiBJbmZlclVJTWVzc2FnZVRvb2xDYWxsPFVJX01FU1NBR0U+O1xuICB9KSA9PiB2b2lkIHwgUHJvbWlzZUxpa2U8dm9pZD47XG5cbmV4cG9ydCB0eXBlIENoYXRPbkRhdGFDYWxsYmFjazxVSV9NRVNTQUdFIGV4dGVuZHMgVUlNZXNzYWdlPiA9IChcbiAgZGF0YVBhcnQ6IERhdGFVSVBhcnQ8SW5mZXJVSU1lc3NhZ2VEYXRhPFVJX01FU1NBR0U+PixcbikgPT4gdm9pZDtcblxuLyoqXG4gKiBGdW5jdGlvbiB0aGF0IGlzIGNhbGxlZCB3aGVuIHRoZSBhc3Npc3RhbnQgcmVzcG9uc2UgaGFzIGZpbmlzaGVkIHN0cmVhbWluZy5cbiAqXG4gKiBAcGFyYW0gbWVzc2FnZSBUaGUgYXNzaXN0YW50IG1lc3NhZ2UgdGhhdCB3YXMgc3RyZWFtZWQuXG4gKiBAcGFyYW0gbWVzc2FnZXMgVGhlIGZ1bGwgY2hhdCBoaXN0b3J5LCBpbmNsdWRpbmcgdGhlIGFzc2lzdGFudCBtZXNzYWdlLlxuICpcbiAqIEBwYXJhbSBpc0Fib3J0IEluZGljYXRlcyB3aGV0aGVyIHRoZSByZXF1ZXN0IGhhcyBiZWVuIGFib3J0ZWQuXG4gKiBAcGFyYW0gaXNEaXNjb25uZWN0IEluZGljYXRlcyB3aGV0aGVyIHRoZSByZXF1ZXN0IGhhcyBiZWVuIGVuZGVkIGJ5IGEgbmV0d29yayBlcnJvci5cbiAqIEBwYXJhbSBpc0Vycm9yIEluZGljYXRlcyB3aGV0aGVyIHRoZSByZXF1ZXN0IGhhcyBiZWVuIGVuZGVkIGJ5IGFuIGVycm9yLlxuICovXG5leHBvcnQgdHlwZSBDaGF0T25GaW5pc2hDYWxsYmFjazxVSV9NRVNTQUdFIGV4dGVuZHMgVUlNZXNzYWdlPiA9IChvcHRpb25zOiB7XG4gIG1lc3NhZ2U6IFVJX01FU1NBR0U7XG4gIG1lc3NhZ2VzOiBVSV9NRVNTQUdFW107XG4gIGlzQWJvcnQ6IGJvb2xlYW47XG4gIGlzRGlzY29ubmVjdDogYm9vbGVhbjtcbiAgaXNFcnJvcjogYm9vbGVhbjtcbn0pID0+IHZvaWQ7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2hhdEluaXQ8VUlfTUVTU0FHRSBleHRlbmRzIFVJTWVzc2FnZT4ge1xuICAvKipcbiAgICogQSB1bmlxdWUgaWRlbnRpZmllciBmb3IgdGhlIGNoYXQuIElmIG5vdCBwcm92aWRlZCwgYSByYW5kb20gb25lIHdpbGwgYmVcbiAgICogZ2VuZXJhdGVkLlxuICAgKi9cbiAgaWQ/OiBzdHJpbmc7XG5cbiAgbWVzc2FnZU1ldGFkYXRhU2NoZW1hPzpcbiAgICB8IFZhbGlkYXRvcjxJbmZlclVJTWVzc2FnZU1ldGFkYXRhPFVJX01FU1NBR0U+PlxuICAgIHwgU3RhbmRhcmRTY2hlbWFWMTxJbmZlclVJTWVzc2FnZU1ldGFkYXRhPFVJX01FU1NBR0U+PjtcbiAgZGF0YVBhcnRTY2hlbWFzPzogVUlEYXRhVHlwZXNUb1NjaGVtYXM8SW5mZXJVSU1lc3NhZ2VEYXRhPFVJX01FU1NBR0U+PjtcblxuICBtZXNzYWdlcz86IFVJX01FU1NBR0VbXTtcblxuICAvKipcbiAgICogQSB3YXkgdG8gcHJvdmlkZSBhIGZ1bmN0aW9uIHRoYXQgaXMgZ29pbmcgdG8gYmUgdXNlZCBmb3IgaWRzIGZvciBtZXNzYWdlcyBhbmQgdGhlIGNoYXQuXG4gICAqIElmIG5vdCBwcm92aWRlZCB0aGUgZGVmYXVsdCBBSSBTREsgYGdlbmVyYXRlSWRgIGlzIHVzZWQuXG4gICAqL1xuICBnZW5lcmF0ZUlkPzogSWRHZW5lcmF0b3I7XG5cbiAgdHJhbnNwb3J0PzogQ2hhdFRyYW5zcG9ydDxVSV9NRVNTQUdFPjtcblxuICAvKipcbiAgICogQ2FsbGJhY2sgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdoZW4gYW4gZXJyb3IgaXMgZW5jb3VudGVyZWQuXG4gICAqL1xuICBvbkVycm9yPzogQ2hhdE9uRXJyb3JDYWxsYmFjaztcblxuICAvKipcbiAgT3B0aW9uYWwgY2FsbGJhY2sgZnVuY3Rpb24gdGhhdCBpcyBpbnZva2VkIHdoZW4gYSB0b29sIGNhbGwgaXMgcmVjZWl2ZWQuXG4gIEludGVuZGVkIGZvciBhdXRvbWF0aWMgY2xpZW50LXNpZGUgdG9vbCBleGVjdXRpb24uXG5cbiAgWW91IGNhbiBvcHRpb25hbGx5IHJldHVybiBhIHJlc3VsdCBmb3IgdGhlIHRvb2wgY2FsbCxcbiAgZWl0aGVyIHN5bmNocm9ub3VzbHkgb3IgYXN5bmNocm9ub3VzbHkuXG4gICAgICovXG4gIG9uVG9vbENhbGw/OiBDaGF0T25Ub29sQ2FsbENhbGxiYWNrPFVJX01FU1NBR0U+O1xuXG4gIC8qKlxuICAgKiBGdW5jdGlvbiB0aGF0IGlzIGNhbGxlZCB3aGVuIHRoZSBhc3Npc3RhbnQgcmVzcG9uc2UgaGFzIGZpbmlzaGVkIHN0cmVhbWluZy5cbiAgICovXG4gIG9uRmluaXNoPzogQ2hhdE9uRmluaXNoQ2FsbGJhY2s8VUlfTUVTU0FHRT47XG5cbiAgLyoqXG4gICAqIE9wdGlvbmFsIGNhbGxiYWNrIGZ1bmN0aW9uIHRoYXQgaXMgY2FsbGVkIHdoZW4gYSBkYXRhIHBhcnQgaXMgcmVjZWl2ZWQuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRhIFRoZSBkYXRhIHBhcnQgdGhhdCB3YXMgcmVjZWl2ZWQuXG4gICAqL1xuICBvbkRhdGE/OiBDaGF0T25EYXRhQ2FsbGJhY2s8VUlfTUVTU0FHRT47XG5cbiAgLyoqXG4gICAqIFdoZW4gcHJvdmlkZWQsIHRoaXMgZnVuY3Rpb24gd2lsbCBiZSBjYWxsZWQgd2hlbiB0aGUgc3RyZWFtIGlzIGZpbmlzaGVkIG9yIGEgdG9vbCBjYWxsIGlzIGFkZGVkXG4gICAqIHRvIGRldGVybWluZSBpZiB0aGUgY3VycmVudCBtZXNzYWdlcyBzaG91bGQgYmUgcmVzdWJtaXR0ZWQuXG4gICAqL1xuICBzZW5kQXV0b21hdGljYWxseVdoZW4/OiAob3B0aW9uczoge1xuICAgIG1lc3NhZ2VzOiBVSV9NRVNTQUdFW107XG4gIH0pID0+IGJvb2xlYW4gfCBQcm9taXNlTGlrZTxib29sZWFuPjtcbn1cblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEFic3RyYWN0Q2hhdDxVSV9NRVNTQUdFIGV4dGVuZHMgVUlNZXNzYWdlPiB7XG4gIHJlYWRvbmx5IGlkOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGdlbmVyYXRlSWQ6IElkR2VuZXJhdG9yO1xuXG4gIHByb3RlY3RlZCBzdGF0ZTogQ2hhdFN0YXRlPFVJX01FU1NBR0U+O1xuXG4gIHByaXZhdGUgbWVzc2FnZU1ldGFkYXRhU2NoZW1hOlxuICAgIHwgVmFsaWRhdG9yPEluZmVyVUlNZXNzYWdlTWV0YWRhdGE8VUlfTUVTU0FHRT4+XG4gICAgfCBTdGFuZGFyZFNjaGVtYVYxPEluZmVyVUlNZXNzYWdlTWV0YWRhdGE8VUlfTUVTU0FHRT4+XG4gICAgfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgZGF0YVBhcnRTY2hlbWFzOlxuICAgIHwgVUlEYXRhVHlwZXNUb1NjaGVtYXM8SW5mZXJVSU1lc3NhZ2VEYXRhPFVJX01FU1NBR0U+PlxuICAgIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIHJlYWRvbmx5IHRyYW5zcG9ydDogQ2hhdFRyYW5zcG9ydDxVSV9NRVNTQUdFPjtcbiAgcHJpdmF0ZSBvbkVycm9yPzogQ2hhdEluaXQ8VUlfTUVTU0FHRT5bJ29uRXJyb3InXTtcbiAgcHJpdmF0ZSBvblRvb2xDYWxsPzogQ2hhdEluaXQ8VUlfTUVTU0FHRT5bJ29uVG9vbENhbGwnXTtcbiAgcHJpdmF0ZSBvbkZpbmlzaD86IENoYXRJbml0PFVJX01FU1NBR0U+WydvbkZpbmlzaCddO1xuICBwcml2YXRlIG9uRGF0YT86IENoYXRJbml0PFVJX01FU1NBR0U+WydvbkRhdGEnXTtcbiAgcHJpdmF0ZSBzZW5kQXV0b21hdGljYWxseVdoZW4/OiBDaGF0SW5pdDxVSV9NRVNTQUdFPlsnc2VuZEF1dG9tYXRpY2FsbHlXaGVuJ107XG5cbiAgcHJpdmF0ZSBhY3RpdmVSZXNwb25zZTogQWN0aXZlUmVzcG9uc2U8VUlfTUVTU0FHRT4gfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gIHByaXZhdGUgam9iRXhlY3V0b3IgPSBuZXcgU2VyaWFsSm9iRXhlY3V0b3IoKTtcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgZ2VuZXJhdGVJZCA9IGdlbmVyYXRlSWRGdW5jLFxuICAgIGlkID0gZ2VuZXJhdGVJZCgpLFxuICAgIHRyYW5zcG9ydCA9IG5ldyBEZWZhdWx0Q2hhdFRyYW5zcG9ydCgpLFxuICAgIG1lc3NhZ2VNZXRhZGF0YVNjaGVtYSxcbiAgICBkYXRhUGFydFNjaGVtYXMsXG4gICAgc3RhdGUsXG4gICAgb25FcnJvcixcbiAgICBvblRvb2xDYWxsLFxuICAgIG9uRmluaXNoLFxuICAgIG9uRGF0YSxcbiAgICBzZW5kQXV0b21hdGljYWxseVdoZW4sXG4gIH06IE9taXQ8Q2hhdEluaXQ8VUlfTUVTU0FHRT4sICdtZXNzYWdlcyc+ICYge1xuICAgIHN0YXRlOiBDaGF0U3RhdGU8VUlfTUVTU0FHRT47XG4gIH0pIHtcbiAgICB0aGlzLmlkID0gaWQ7XG4gICAgdGhpcy50cmFuc3BvcnQgPSB0cmFuc3BvcnQ7XG4gICAgdGhpcy5nZW5lcmF0ZUlkID0gZ2VuZXJhdGVJZDtcbiAgICB0aGlzLm1lc3NhZ2VNZXRhZGF0YVNjaGVtYSA9IG1lc3NhZ2VNZXRhZGF0YVNjaGVtYTtcbiAgICB0aGlzLmRhdGFQYXJ0U2NoZW1hcyA9IGRhdGFQYXJ0U2NoZW1hcztcbiAgICB0aGlzLnN0YXRlID0gc3RhdGU7XG4gICAgdGhpcy5vbkVycm9yID0gb25FcnJvcjtcbiAgICB0aGlzLm9uVG9vbENhbGwgPSBvblRvb2xDYWxsO1xuICAgIHRoaXMub25GaW5pc2ggPSBvbkZpbmlzaDtcbiAgICB0aGlzLm9uRGF0YSA9IG9uRGF0YTtcbiAgICB0aGlzLnNlbmRBdXRvbWF0aWNhbGx5V2hlbiA9IHNlbmRBdXRvbWF0aWNhbGx5V2hlbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBIb29rIHN0YXR1czpcbiAgICpcbiAgICogLSBgc3VibWl0dGVkYDogVGhlIG1lc3NhZ2UgaGFzIGJlZW4gc2VudCB0byB0aGUgQVBJIGFuZCB3ZSdyZSBhd2FpdGluZyB0aGUgc3RhcnQgb2YgdGhlIHJlc3BvbnNlIHN0cmVhbS5cbiAgICogLSBgc3RyZWFtaW5nYDogVGhlIHJlc3BvbnNlIGlzIGFjdGl2ZWx5IHN0cmVhbWluZyBpbiBmcm9tIHRoZSBBUEksIHJlY2VpdmluZyBjaHVua3Mgb2YgZGF0YS5cbiAgICogLSBgcmVhZHlgOiBUaGUgZnVsbCByZXNwb25zZSBoYXMgYmVlbiByZWNlaXZlZCBhbmQgcHJvY2Vzc2VkOyBhIG5ldyB1c2VyIG1lc3NhZ2UgY2FuIGJlIHN1Ym1pdHRlZC5cbiAgICogLSBgZXJyb3JgOiBBbiBlcnJvciBvY2N1cnJlZCBkdXJpbmcgdGhlIEFQSSByZXF1ZXN0LCBwcmV2ZW50aW5nIHN1Y2Nlc3NmdWwgY29tcGxldGlvbi5cbiAgICovXG4gIGdldCBzdGF0dXMoKTogQ2hhdFN0YXR1cyB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdGUuc3RhdHVzO1xuICB9XG5cbiAgcHJvdGVjdGVkIHNldFN0YXR1cyh7XG4gICAgc3RhdHVzLFxuICAgIGVycm9yLFxuICB9OiB7XG4gICAgc3RhdHVzOiBDaGF0U3RhdHVzO1xuICAgIGVycm9yPzogRXJyb3I7XG4gIH0pIHtcbiAgICBpZiAodGhpcy5zdGF0dXMgPT09IHN0YXR1cykgcmV0dXJuO1xuXG4gICAgdGhpcy5zdGF0ZS5zdGF0dXMgPSBzdGF0dXM7XG4gICAgdGhpcy5zdGF0ZS5lcnJvciA9IGVycm9yO1xuICB9XG5cbiAgZ2V0IGVycm9yKCkge1xuICAgIHJldHVybiB0aGlzLnN0YXRlLmVycm9yO1xuICB9XG5cbiAgZ2V0IG1lc3NhZ2VzKCk6IFVJX01FU1NBR0VbXSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdGUubWVzc2FnZXM7XG4gIH1cblxuICBnZXQgbGFzdE1lc3NhZ2UoKTogVUlfTUVTU0FHRSB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdGUubWVzc2FnZXNbdGhpcy5zdGF0ZS5tZXNzYWdlcy5sZW5ndGggLSAxXTtcbiAgfVxuXG4gIHNldCBtZXNzYWdlcyhtZXNzYWdlczogVUlfTUVTU0FHRVtdKSB7XG4gICAgdGhpcy5zdGF0ZS5tZXNzYWdlcyA9IG1lc3NhZ2VzO1xuICB9XG5cbiAgLyoqXG4gICAqIEFwcGVuZHMgb3IgcmVwbGFjZXMgYSB1c2VyIG1lc3NhZ2UgdG8gdGhlIGNoYXQgbGlzdC4gVGhpcyB0cmlnZ2VycyB0aGUgQVBJIGNhbGwgdG8gZmV0Y2hcbiAgICogdGhlIGFzc2lzdGFudCdzIHJlc3BvbnNlLlxuICAgKlxuICAgKiBJZiBhIG1lc3NhZ2VJZCBpcyBwcm92aWRlZCwgdGhlIG1lc3NhZ2Ugd2lsbCBiZSByZXBsYWNlZC5cbiAgICovXG4gIHNlbmRNZXNzYWdlID0gYXN5bmMgKFxuICAgIG1lc3NhZ2U/OlxuICAgICAgfCAoQ3JlYXRlVUlNZXNzYWdlPFVJX01FU1NBR0U+ICYge1xuICAgICAgICAgIHRleHQ/OiBuZXZlcjtcbiAgICAgICAgICBmaWxlcz86IG5ldmVyO1xuICAgICAgICAgIG1lc3NhZ2VJZD86IHN0cmluZztcbiAgICAgICAgfSlcbiAgICAgIHwge1xuICAgICAgICAgIHRleHQ6IHN0cmluZztcbiAgICAgICAgICBmaWxlcz86IEZpbGVMaXN0IHwgRmlsZVVJUGFydFtdO1xuICAgICAgICAgIG1ldGFkYXRhPzogSW5mZXJVSU1lc3NhZ2VNZXRhZGF0YTxVSV9NRVNTQUdFPjtcbiAgICAgICAgICBwYXJ0cz86IG5ldmVyO1xuICAgICAgICAgIG1lc3NhZ2VJZD86IHN0cmluZztcbiAgICAgICAgfVxuICAgICAgfCB7XG4gICAgICAgICAgZmlsZXM6IEZpbGVMaXN0IHwgRmlsZVVJUGFydFtdO1xuICAgICAgICAgIG1ldGFkYXRhPzogSW5mZXJVSU1lc3NhZ2VNZXRhZGF0YTxVSV9NRVNTQUdFPjtcbiAgICAgICAgICBwYXJ0cz86IG5ldmVyO1xuICAgICAgICAgIG1lc3NhZ2VJZD86IHN0cmluZztcbiAgICAgICAgfSxcbiAgICBvcHRpb25zPzogQ2hhdFJlcXVlc3RPcHRpb25zLFxuICApOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICBpZiAobWVzc2FnZSA9PSBudWxsKSB7XG4gICAgICBhd2FpdCB0aGlzLm1ha2VSZXF1ZXN0KHtcbiAgICAgICAgdHJpZ2dlcjogJ3N1Ym1pdC1tZXNzYWdlJyxcbiAgICAgICAgbWVzc2FnZUlkOiB0aGlzLmxhc3RNZXNzYWdlPy5pZCxcbiAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCB1aU1lc3NhZ2U6IENyZWF0ZVVJTWVzc2FnZTxVSV9NRVNTQUdFPjtcblxuICAgIGlmICgndGV4dCcgaW4gbWVzc2FnZSB8fCAnZmlsZXMnIGluIG1lc3NhZ2UpIHtcbiAgICAgIGNvbnN0IGZpbGVQYXJ0cyA9IEFycmF5LmlzQXJyYXkobWVzc2FnZS5maWxlcylcbiAgICAgICAgPyBtZXNzYWdlLmZpbGVzXG4gICAgICAgIDogYXdhaXQgY29udmVydEZpbGVMaXN0VG9GaWxlVUlQYXJ0cyhtZXNzYWdlLmZpbGVzKTtcblxuICAgICAgdWlNZXNzYWdlID0ge1xuICAgICAgICBwYXJ0czogW1xuICAgICAgICAgIC4uLmZpbGVQYXJ0cyxcbiAgICAgICAgICAuLi4oJ3RleHQnIGluIG1lc3NhZ2UgJiYgbWVzc2FnZS50ZXh0ICE9IG51bGxcbiAgICAgICAgICAgID8gW3sgdHlwZTogJ3RleHQnIGFzIGNvbnN0LCB0ZXh0OiBtZXNzYWdlLnRleHQgfV1cbiAgICAgICAgICAgIDogW10pLFxuICAgICAgICBdLFxuICAgICAgfSBhcyBVSV9NRVNTQUdFO1xuICAgIH0gZWxzZSB7XG4gICAgICB1aU1lc3NhZ2UgPSBtZXNzYWdlO1xuICAgIH1cblxuICAgIGlmIChtZXNzYWdlLm1lc3NhZ2VJZCAhPSBudWxsKSB7XG4gICAgICBjb25zdCBtZXNzYWdlSW5kZXggPSB0aGlzLnN0YXRlLm1lc3NhZ2VzLmZpbmRJbmRleChcbiAgICAgICAgbSA9PiBtLmlkID09PSBtZXNzYWdlLm1lc3NhZ2VJZCxcbiAgICAgICk7XG5cbiAgICAgIGlmIChtZXNzYWdlSW5kZXggPT09IC0xKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgbWVzc2FnZSB3aXRoIGlkICR7bWVzc2FnZS5tZXNzYWdlSWR9IG5vdCBmb3VuZGApO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5zdGF0ZS5tZXNzYWdlc1ttZXNzYWdlSW5kZXhdLnJvbGUgIT09ICd1c2VyJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYG1lc3NhZ2Ugd2l0aCBpZCAke21lc3NhZ2UubWVzc2FnZUlkfSBpcyBub3QgYSB1c2VyIG1lc3NhZ2VgLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICAvLyByZW1vdmUgYWxsIG1lc3NhZ2VzIGFmdGVyIHRoZSBtZXNzYWdlIHdpdGggdGhlIGdpdmVuIGlkXG4gICAgICB0aGlzLnN0YXRlLm1lc3NhZ2VzID0gdGhpcy5zdGF0ZS5tZXNzYWdlcy5zbGljZSgwLCBtZXNzYWdlSW5kZXggKyAxKTtcblxuICAgICAgLy8gdXBkYXRlIHRoZSBtZXNzYWdlIHdpdGggdGhlIG5ldyBjb250ZW50XG4gICAgICB0aGlzLnN0YXRlLnJlcGxhY2VNZXNzYWdlKG1lc3NhZ2VJbmRleCwge1xuICAgICAgICAuLi51aU1lc3NhZ2UsXG4gICAgICAgIGlkOiBtZXNzYWdlLm1lc3NhZ2VJZCxcbiAgICAgICAgcm9sZTogdWlNZXNzYWdlLnJvbGUgPz8gJ3VzZXInLFxuICAgICAgICBtZXRhZGF0YTogbWVzc2FnZS5tZXRhZGF0YSxcbiAgICAgIH0gYXMgVUlfTUVTU0FHRSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc3RhdGUucHVzaE1lc3NhZ2Uoe1xuICAgICAgICAuLi51aU1lc3NhZ2UsXG4gICAgICAgIGlkOiB1aU1lc3NhZ2UuaWQgPz8gdGhpcy5nZW5lcmF0ZUlkKCksXG4gICAgICAgIHJvbGU6IHVpTWVzc2FnZS5yb2xlID8/ICd1c2VyJyxcbiAgICAgICAgbWV0YWRhdGE6IG1lc3NhZ2UubWV0YWRhdGEsXG4gICAgICB9IGFzIFVJX01FU1NBR0UpO1xuICAgIH1cblxuICAgIGF3YWl0IHRoaXMubWFrZVJlcXVlc3Qoe1xuICAgICAgdHJpZ2dlcjogJ3N1Ym1pdC1tZXNzYWdlJyxcbiAgICAgIG1lc3NhZ2VJZDogbWVzc2FnZS5tZXNzYWdlSWQsXG4gICAgICAuLi5vcHRpb25zLFxuICAgIH0pO1xuICB9O1xuXG4gIC8qKlxuICAgKiBSZWdlbmVyYXRlIHRoZSBhc3Npc3RhbnQgbWVzc2FnZSB3aXRoIHRoZSBwcm92aWRlZCBtZXNzYWdlIGlkLlxuICAgKiBJZiBubyBtZXNzYWdlIGlkIGlzIHByb3ZpZGVkLCB0aGUgbGFzdCBhc3Npc3RhbnQgbWVzc2FnZSB3aWxsIGJlIHJlZ2VuZXJhdGVkLlxuICAgKi9cbiAgcmVnZW5lcmF0ZSA9IGFzeW5jICh7XG4gICAgbWVzc2FnZUlkLFxuICAgIC4uLm9wdGlvbnNcbiAgfToge1xuICAgIG1lc3NhZ2VJZD86IHN0cmluZztcbiAgfSAmIENoYXRSZXF1ZXN0T3B0aW9ucyA9IHt9KTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgY29uc3QgbWVzc2FnZUluZGV4ID1cbiAgICAgIG1lc3NhZ2VJZCA9PSBudWxsXG4gICAgICAgID8gdGhpcy5zdGF0ZS5tZXNzYWdlcy5sZW5ndGggLSAxXG4gICAgICAgIDogdGhpcy5zdGF0ZS5tZXNzYWdlcy5maW5kSW5kZXgobWVzc2FnZSA9PiBtZXNzYWdlLmlkID09PSBtZXNzYWdlSWQpO1xuXG4gICAgaWYgKG1lc3NhZ2VJbmRleCA9PT0gLTEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgbWVzc2FnZSAke21lc3NhZ2VJZH0gbm90IGZvdW5kYCk7XG4gICAgfVxuXG4gICAgLy8gc2V0IHRoZSBtZXNzYWdlcyB0byB0aGUgbWVzc2FnZSBiZWZvcmUgdGhlIGFzc2lzdGFudCBtZXNzYWdlXG4gICAgdGhpcy5zdGF0ZS5tZXNzYWdlcyA9IHRoaXMuc3RhdGUubWVzc2FnZXMuc2xpY2UoXG4gICAgICAwLFxuICAgICAgLy8gaWYgdGhlIG1lc3NhZ2UgaXMgYSB1c2VyIG1lc3NhZ2UsIHdlIG5lZWQgdG8gaW5jbHVkZSBpdCBpbiB0aGUgcmVxdWVzdDpcbiAgICAgIHRoaXMubWVzc2FnZXNbbWVzc2FnZUluZGV4XS5yb2xlID09PSAnYXNzaXN0YW50J1xuICAgICAgICA/IG1lc3NhZ2VJbmRleFxuICAgICAgICA6IG1lc3NhZ2VJbmRleCArIDEsXG4gICAgKTtcblxuICAgIGF3YWl0IHRoaXMubWFrZVJlcXVlc3Qoe1xuICAgICAgdHJpZ2dlcjogJ3JlZ2VuZXJhdGUtbWVzc2FnZScsXG4gICAgICBtZXNzYWdlSWQsXG4gICAgICAuLi5vcHRpb25zLFxuICAgIH0pO1xuICB9O1xuXG4gIC8qKlxuICAgKiBBdHRlbXB0IHRvIHJlc3VtZSBhbiBvbmdvaW5nIHN0cmVhbWluZyByZXNwb25zZS5cbiAgICovXG4gIHJlc3VtZVN0cmVhbSA9IGFzeW5jIChvcHRpb25zOiBDaGF0UmVxdWVzdE9wdGlvbnMgPSB7fSk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIGF3YWl0IHRoaXMubWFrZVJlcXVlc3QoeyB0cmlnZ2VyOiAncmVzdW1lLXN0cmVhbScsIC4uLm9wdGlvbnMgfSk7XG4gIH07XG5cbiAgLyoqXG4gICAqIENsZWFyIHRoZSBlcnJvciBzdGF0ZSBhbmQgc2V0IHRoZSBzdGF0dXMgdG8gcmVhZHkgaWYgdGhlIGNoYXQgaXMgaW4gYW4gZXJyb3Igc3RhdGUuXG4gICAqL1xuICBjbGVhckVycm9yID0gKCkgPT4ge1xuICAgIGlmICh0aGlzLnN0YXR1cyA9PT0gJ2Vycm9yJykge1xuICAgICAgdGhpcy5zdGF0ZS5lcnJvciA9IHVuZGVmaW5lZDtcbiAgICAgIHRoaXMuc2V0U3RhdHVzKHsgc3RhdHVzOiAncmVhZHknIH0pO1xuICAgIH1cbiAgfTtcblxuICBhZGRUb29sUmVzdWx0ID0gYXN5bmMgPFRPT0wgZXh0ZW5kcyBrZXlvZiBJbmZlclVJTWVzc2FnZVRvb2xzPFVJX01FU1NBR0U+Pih7XG4gICAgc3RhdGUgPSAnb3V0cHV0LWF2YWlsYWJsZScsXG4gICAgdG9vbCxcbiAgICB0b29sQ2FsbElkLFxuICAgIG91dHB1dCxcbiAgICBlcnJvclRleHQsXG4gIH06XG4gICAgfCB7XG4gICAgICAgIHN0YXRlPzogJ291dHB1dC1hdmFpbGFibGUnO1xuICAgICAgICB0b29sOiBUT09MO1xuICAgICAgICB0b29sQ2FsbElkOiBzdHJpbmc7XG4gICAgICAgIG91dHB1dDogSW5mZXJVSU1lc3NhZ2VUb29sczxVSV9NRVNTQUdFPltUT09MXVsnb3V0cHV0J107XG4gICAgICAgIGVycm9yVGV4dD86IG5ldmVyO1xuICAgICAgfVxuICAgIHwge1xuICAgICAgICBzdGF0ZTogJ291dHB1dC1lcnJvcic7XG4gICAgICAgIHRvb2w6IFRPT0w7XG4gICAgICAgIHRvb2xDYWxsSWQ6IHN0cmluZztcbiAgICAgICAgb3V0cHV0PzogbmV2ZXI7XG4gICAgICAgIGVycm9yVGV4dDogc3RyaW5nO1xuICAgICAgfSkgPT5cbiAgICB0aGlzLmpvYkV4ZWN1dG9yLnJ1bihhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBtZXNzYWdlcyA9IHRoaXMuc3RhdGUubWVzc2FnZXM7XG4gICAgICBjb25zdCBsYXN0TWVzc2FnZSA9IG1lc3NhZ2VzW21lc3NhZ2VzLmxlbmd0aCAtIDFdO1xuXG4gICAgICB0aGlzLnN0YXRlLnJlcGxhY2VNZXNzYWdlKG1lc3NhZ2VzLmxlbmd0aCAtIDEsIHtcbiAgICAgICAgLi4ubGFzdE1lc3NhZ2UsXG4gICAgICAgIHBhcnRzOiBsYXN0TWVzc2FnZS5wYXJ0cy5tYXAocGFydCA9PlxuICAgICAgICAgIGlzVG9vbE9yRHluYW1pY1Rvb2xVSVBhcnQocGFydCkgJiYgcGFydC50b29sQ2FsbElkID09PSB0b29sQ2FsbElkXG4gICAgICAgICAgICA/IHsgLi4ucGFydCwgc3RhdGUsIG91dHB1dCwgZXJyb3JUZXh0IH1cbiAgICAgICAgICAgIDogcGFydCxcbiAgICAgICAgKSxcbiAgICAgIH0pO1xuXG4gICAgICAvLyB1cGRhdGUgdGhlIGFjdGl2ZSByZXNwb25zZSBpZiBpdCBleGlzdHNcbiAgICAgIGlmICh0aGlzLmFjdGl2ZVJlc3BvbnNlKSB7XG4gICAgICAgIHRoaXMuYWN0aXZlUmVzcG9uc2Uuc3RhdGUubWVzc2FnZS5wYXJ0cyA9XG4gICAgICAgICAgdGhpcy5hY3RpdmVSZXNwb25zZS5zdGF0ZS5tZXNzYWdlLnBhcnRzLm1hcChwYXJ0ID0+XG4gICAgICAgICAgICBpc1Rvb2xPckR5bmFtaWNUb29sVUlQYXJ0KHBhcnQpICYmIHBhcnQudG9vbENhbGxJZCA9PT0gdG9vbENhbGxJZFxuICAgICAgICAgICAgICA/ICh7XG4gICAgICAgICAgICAgICAgICAuLi5wYXJ0LFxuICAgICAgICAgICAgICAgICAgc3RhdGUsXG4gICAgICAgICAgICAgICAgICBvdXRwdXQsXG4gICAgICAgICAgICAgICAgICBlcnJvclRleHQsXG4gICAgICAgICAgICAgICAgfSBhcyB0eXBlb2YgcGFydClcbiAgICAgICAgICAgICAgOiBwYXJ0LFxuICAgICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIC8vIGF1dG9tYXRpY2FsbHkgc2VuZCB0aGUgbWVzc2FnZSBpZiB0aGUgc2VuZEF1dG9tYXRpY2FsbHlXaGVuIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZVxuICAgICAgaWYgKFxuICAgICAgICB0aGlzLnN0YXR1cyAhPT0gJ3N0cmVhbWluZycgJiZcbiAgICAgICAgdGhpcy5zdGF0dXMgIT09ICdzdWJtaXR0ZWQnICYmXG4gICAgICAgIHRoaXMuc2VuZEF1dG9tYXRpY2FsbHlXaGVuPy4oeyBtZXNzYWdlczogdGhpcy5zdGF0ZS5tZXNzYWdlcyB9KVxuICAgICAgKSB7XG4gICAgICAgIC8vIG5vIGF3YWl0IHRvIGF2b2lkIGRlYWRsb2NraW5nXG4gICAgICAgIHRoaXMubWFrZVJlcXVlc3Qoe1xuICAgICAgICAgIHRyaWdnZXI6ICdzdWJtaXQtbWVzc2FnZScsXG4gICAgICAgICAgbWVzc2FnZUlkOiB0aGlzLmxhc3RNZXNzYWdlPy5pZCxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgLyoqXG4gICAqIEFib3J0IHRoZSBjdXJyZW50IHJlcXVlc3QgaW1tZWRpYXRlbHksIGtlZXAgdGhlIGdlbmVyYXRlZCB0b2tlbnMgaWYgYW55LlxuICAgKi9cbiAgc3RvcCA9IGFzeW5jICgpID0+IHtcbiAgICBpZiAodGhpcy5zdGF0dXMgIT09ICdzdHJlYW1pbmcnICYmIHRoaXMuc3RhdHVzICE9PSAnc3VibWl0dGVkJykgcmV0dXJuO1xuXG4gICAgaWYgKHRoaXMuYWN0aXZlUmVzcG9uc2U/LmFib3J0Q29udHJvbGxlcikge1xuICAgICAgdGhpcy5hY3RpdmVSZXNwb25zZS5hYm9ydENvbnRyb2xsZXIuYWJvcnQoKTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBhc3luYyBtYWtlUmVxdWVzdCh7XG4gICAgdHJpZ2dlcixcbiAgICBtZXRhZGF0YSxcbiAgICBoZWFkZXJzLFxuICAgIGJvZHksXG4gICAgbWVzc2FnZUlkLFxuICB9OiB7XG4gICAgdHJpZ2dlcjogJ3N1Ym1pdC1tZXNzYWdlJyB8ICdyZXN1bWUtc3RyZWFtJyB8ICdyZWdlbmVyYXRlLW1lc3NhZ2UnO1xuICAgIG1lc3NhZ2VJZD86IHN0cmluZztcbiAgfSAmIENoYXRSZXF1ZXN0T3B0aW9ucykge1xuICAgIHRoaXMuc2V0U3RhdHVzKHsgc3RhdHVzOiAnc3VibWl0dGVkJywgZXJyb3I6IHVuZGVmaW5lZCB9KTtcblxuICAgIGNvbnN0IGxhc3RNZXNzYWdlID0gdGhpcy5sYXN0TWVzc2FnZTtcblxuICAgIGxldCBpc0Fib3J0ID0gZmFsc2U7XG4gICAgbGV0IGlzRGlzY29ubmVjdCA9IGZhbHNlO1xuICAgIGxldCBpc0Vycm9yID0gZmFsc2U7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgYWN0aXZlUmVzcG9uc2UgPSB7XG4gICAgICAgIHN0YXRlOiBjcmVhdGVTdHJlYW1pbmdVSU1lc3NhZ2VTdGF0ZSh7XG4gICAgICAgICAgbGFzdE1lc3NhZ2U6IHRoaXMuc3RhdGUuc25hcHNob3QobGFzdE1lc3NhZ2UpLFxuICAgICAgICAgIG1lc3NhZ2VJZDogdGhpcy5nZW5lcmF0ZUlkKCksXG4gICAgICAgIH0pLFxuICAgICAgICBhYm9ydENvbnRyb2xsZXI6IG5ldyBBYm9ydENvbnRyb2xsZXIoKSxcbiAgICAgIH0gYXMgQWN0aXZlUmVzcG9uc2U8VUlfTUVTU0FHRT47XG5cbiAgICAgIGFjdGl2ZVJlc3BvbnNlLmFib3J0Q29udHJvbGxlci5zaWduYWwuYWRkRXZlbnRMaXN0ZW5lcignYWJvcnQnLCAoKSA9PiB7XG4gICAgICAgIGlzQWJvcnQgPSB0cnVlO1xuICAgICAgfSk7XG5cbiAgICAgIHRoaXMuYWN0aXZlUmVzcG9uc2UgPSBhY3RpdmVSZXNwb25zZTtcblxuICAgICAgbGV0IHN0cmVhbTogUmVhZGFibGVTdHJlYW08VUlNZXNzYWdlQ2h1bms+O1xuXG4gICAgICBpZiAodHJpZ2dlciA9PT0gJ3Jlc3VtZS1zdHJlYW0nKSB7XG4gICAgICAgIGNvbnN0IHJlY29ubmVjdCA9IGF3YWl0IHRoaXMudHJhbnNwb3J0LnJlY29ubmVjdFRvU3RyZWFtKHtcbiAgICAgICAgICBjaGF0SWQ6IHRoaXMuaWQsXG4gICAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgICAgaGVhZGVycyxcbiAgICAgICAgICBib2R5LFxuICAgICAgICB9KTtcblxuICAgICAgICBpZiAocmVjb25uZWN0ID09IG51bGwpIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXR1cyh7IHN0YXR1czogJ3JlYWR5JyB9KTtcbiAgICAgICAgICByZXR1cm47IC8vIG5vIGFjdGl2ZSBzdHJlYW0gZm91bmQsIHNvIHdlIGRvIG5vdCByZXN1bWVcbiAgICAgICAgfVxuXG4gICAgICAgIHN0cmVhbSA9IHJlY29ubmVjdDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0cmVhbSA9IGF3YWl0IHRoaXMudHJhbnNwb3J0LnNlbmRNZXNzYWdlcyh7XG4gICAgICAgICAgY2hhdElkOiB0aGlzLmlkLFxuICAgICAgICAgIG1lc3NhZ2VzOiB0aGlzLnN0YXRlLm1lc3NhZ2VzLFxuICAgICAgICAgIGFib3J0U2lnbmFsOiBhY3RpdmVSZXNwb25zZS5hYm9ydENvbnRyb2xsZXIuc2lnbmFsLFxuICAgICAgICAgIG1ldGFkYXRhLFxuICAgICAgICAgIGhlYWRlcnMsXG4gICAgICAgICAgYm9keSxcbiAgICAgICAgICB0cmlnZ2VyLFxuICAgICAgICAgIG1lc3NhZ2VJZCxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJ1blVwZGF0ZU1lc3NhZ2VKb2IgPSAoXG4gICAgICAgIGpvYjogKG9wdGlvbnM6IHtcbiAgICAgICAgICBzdGF0ZTogU3RyZWFtaW5nVUlNZXNzYWdlU3RhdGU8VUlfTUVTU0FHRT47XG4gICAgICAgICAgd3JpdGU6ICgpID0+IHZvaWQ7XG4gICAgICAgIH0pID0+IFByb21pc2U8dm9pZD4sXG4gICAgICApID0+XG4gICAgICAgIC8vIHNlcmlhbGl6ZSB0aGUgam9iIGV4ZWN1dGlvbiB0byBhdm9pZCByYWNlIGNvbmRpdGlvbnM6XG4gICAgICAgIHRoaXMuam9iRXhlY3V0b3IucnVuKCgpID0+XG4gICAgICAgICAgam9iKHtcbiAgICAgICAgICAgIHN0YXRlOiBhY3RpdmVSZXNwb25zZS5zdGF0ZSxcbiAgICAgICAgICAgIHdyaXRlOiAoKSA9PiB7XG4gICAgICAgICAgICAgIC8vIHN0cmVhbWluZyBpcyBzZXQgb24gZmlyc3Qgd3JpdGUgKGJlZm9yZSBpdCBzaG91bGQgYmUgXCJzdWJtaXR0ZWRcIilcbiAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0dXMoeyBzdGF0dXM6ICdzdHJlYW1pbmcnIH0pO1xuXG4gICAgICAgICAgICAgIGNvbnN0IHJlcGxhY2VMYXN0TWVzc2FnZSA9XG4gICAgICAgICAgICAgICAgYWN0aXZlUmVzcG9uc2Uuc3RhdGUubWVzc2FnZS5pZCA9PT0gdGhpcy5sYXN0TWVzc2FnZT8uaWQ7XG5cbiAgICAgICAgICAgICAgaWYgKHJlcGxhY2VMYXN0TWVzc2FnZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUucmVwbGFjZU1lc3NhZ2UoXG4gICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLm1lc3NhZ2VzLmxlbmd0aCAtIDEsXG4gICAgICAgICAgICAgICAgICBhY3RpdmVSZXNwb25zZS5zdGF0ZS5tZXNzYWdlLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5wdXNoTWVzc2FnZShhY3RpdmVSZXNwb25zZS5zdGF0ZS5tZXNzYWdlKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcblxuICAgICAgYXdhaXQgY29uc3VtZVN0cmVhbSh7XG4gICAgICAgIHN0cmVhbTogcHJvY2Vzc1VJTWVzc2FnZVN0cmVhbSh7XG4gICAgICAgICAgc3RyZWFtLFxuICAgICAgICAgIG9uVG9vbENhbGw6IHRoaXMub25Ub29sQ2FsbCxcbiAgICAgICAgICBvbkRhdGE6IHRoaXMub25EYXRhLFxuICAgICAgICAgIG1lc3NhZ2VNZXRhZGF0YVNjaGVtYTogdGhpcy5tZXNzYWdlTWV0YWRhdGFTY2hlbWEsXG4gICAgICAgICAgZGF0YVBhcnRTY2hlbWFzOiB0aGlzLmRhdGFQYXJ0U2NoZW1hcyxcbiAgICAgICAgICBydW5VcGRhdGVNZXNzYWdlSm9iLFxuICAgICAgICAgIG9uRXJyb3I6IGVycm9yID0+IHtcbiAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgICBvbkVycm9yOiBlcnJvciA9PiB7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgdGhpcy5zZXRTdGF0dXMoeyBzdGF0dXM6ICdyZWFkeScgfSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAvLyBJZ25vcmUgYWJvcnQgZXJyb3JzIGFzIHRoZXkgYXJlIGV4cGVjdGVkLlxuICAgICAgaWYgKGlzQWJvcnQgfHwgKGVyciBhcyBhbnkpLm5hbWUgPT09ICdBYm9ydEVycm9yJykge1xuICAgICAgICBpc0Fib3J0ID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5zZXRTdGF0dXMoeyBzdGF0dXM6ICdyZWFkeScgfSk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgICBpc0Vycm9yID0gdHJ1ZTtcblxuICAgICAgLy8gTmV0d29yayBlcnJvcnMgc3VjaCBhcyBkaXNjb25uZWN0ZWQsIHRpbWVvdXQsIGV0Yy5cbiAgICAgIGlmIChcbiAgICAgICAgZXJyIGluc3RhbmNlb2YgVHlwZUVycm9yICYmXG4gICAgICAgIChlcnIubWVzc2FnZS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKCdmZXRjaCcpIHx8XG4gICAgICAgICAgZXJyLm1lc3NhZ2UudG9Mb3dlckNhc2UoKS5pbmNsdWRlcygnbmV0d29yaycpKVxuICAgICAgKSB7XG4gICAgICAgIGlzRGlzY29ubmVjdCA9IHRydWU7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLm9uRXJyb3IgJiYgZXJyIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgdGhpcy5vbkVycm9yKGVycik7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc2V0U3RhdHVzKHsgc3RhdHVzOiAnZXJyb3InLCBlcnJvcjogZXJyIGFzIEVycm9yIH0pO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0cnkge1xuICAgICAgICB0aGlzLm9uRmluaXNoPy4oe1xuICAgICAgICAgIG1lc3NhZ2U6IHRoaXMuYWN0aXZlUmVzcG9uc2UhLnN0YXRlLm1lc3NhZ2UsXG4gICAgICAgICAgbWVzc2FnZXM6IHRoaXMuc3RhdGUubWVzc2FnZXMsXG4gICAgICAgICAgaXNBYm9ydCxcbiAgICAgICAgICBpc0Rpc2Nvbm5lY3QsXG4gICAgICAgICAgaXNFcnJvcixcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmFjdGl2ZVJlc3BvbnNlID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8vIGF1dG9tYXRpY2FsbHkgc2VuZCB0aGUgbWVzc2FnZSBpZiB0aGUgc2VuZEF1dG9tYXRpY2FsbHlXaGVuIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZVxuICAgIGlmIChcbiAgICAgIHRoaXMuc2VuZEF1dG9tYXRpY2FsbHlXaGVuPy4oeyBtZXNzYWdlczogdGhpcy5zdGF0ZS5tZXNzYWdlcyB9KSAmJlxuICAgICAgIWlzRXJyb3JcbiAgICApIHtcbiAgICAgIGF3YWl0IHRoaXMubWFrZVJlcXVlc3Qoe1xuICAgICAgICB0cmlnZ2VyOiAnc3VibWl0LW1lc3NhZ2UnLFxuICAgICAgICBtZXNzYWdlSWQ6IHRoaXMubGFzdE1lc3NhZ2U/LmlkLFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAgaGVhZGVycyxcbiAgICAgICAgYm9keSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufVxuIiwgImltcG9ydCB7IEZpbGVVSVBhcnQgfSBmcm9tICcuL3VpLW1lc3NhZ2VzJztcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNvbnZlcnRGaWxlTGlzdFRvRmlsZVVJUGFydHMoXG4gIGZpbGVzOiBGaWxlTGlzdCB8IHVuZGVmaW5lZCxcbik6IFByb21pc2U8QXJyYXk8RmlsZVVJUGFydD4+IHtcbiAgaWYgKGZpbGVzID09IG51bGwpIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICAvLyBSZWFjdC1uYXRpdmUgZG9lc24ndCBoYXZlIGEgRmlsZUxpc3QgZ2xvYmFsOlxuICBpZiAoIWdsb2JhbFRoaXMuRmlsZUxpc3QgfHwgIShmaWxlcyBpbnN0YW5jZW9mIGdsb2JhbFRoaXMuRmlsZUxpc3QpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdGaWxlTGlzdCBpcyBub3Qgc3VwcG9ydGVkIGluIHRoZSBjdXJyZW50IGVudmlyb25tZW50Jyk7XG4gIH1cblxuICByZXR1cm4gUHJvbWlzZS5hbGwoXG4gICAgQXJyYXkuZnJvbShmaWxlcykubWFwKGFzeW5jIGZpbGUgPT4ge1xuICAgICAgY29uc3QgeyBuYW1lLCB0eXBlIH0gPSBmaWxlO1xuXG4gICAgICBjb25zdCBkYXRhVXJsID0gYXdhaXQgbmV3IFByb21pc2U8c3RyaW5nPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgICAgIHJlYWRlci5vbmxvYWQgPSByZWFkZXJFdmVudCA9PiB7XG4gICAgICAgICAgcmVzb2x2ZShyZWFkZXJFdmVudC50YXJnZXQ/LnJlc3VsdCBhcyBzdHJpbmcpO1xuICAgICAgICB9O1xuICAgICAgICByZWFkZXIub25lcnJvciA9IGVycm9yID0+IHJlamVjdChlcnJvcik7XG4gICAgICAgIHJlYWRlci5yZWFkQXNEYXRhVVJMKGZpbGUpO1xuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6ICdmaWxlJyxcbiAgICAgICAgbWVkaWFUeXBlOiB0eXBlLFxuICAgICAgICBmaWxlbmFtZTogbmFtZSxcbiAgICAgICAgdXJsOiBkYXRhVXJsLFxuICAgICAgfTtcbiAgICB9KSxcbiAgKTtcbn1cbiIsICJpbXBvcnQgeyBwYXJzZUpzb25FdmVudFN0cmVhbSwgUGFyc2VSZXN1bHQgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyLXV0aWxzJztcbmltcG9ydCB7XG4gIFVJTWVzc2FnZUNodW5rLFxuICB1aU1lc3NhZ2VDaHVua1NjaGVtYSxcbn0gZnJvbSAnLi4vdWktbWVzc2FnZS1zdHJlYW0vdWktbWVzc2FnZS1jaHVua3MnO1xuaW1wb3J0IHtcbiAgSHR0cENoYXRUcmFuc3BvcnQsXG4gIEh0dHBDaGF0VHJhbnNwb3J0SW5pdE9wdGlvbnMsXG59IGZyb20gJy4vaHR0cC1jaGF0LXRyYW5zcG9ydCc7XG5pbXBvcnQgeyBVSU1lc3NhZ2UgfSBmcm9tICcuL3VpLW1lc3NhZ2VzJztcblxuZXhwb3J0IGNsYXNzIERlZmF1bHRDaGF0VHJhbnNwb3J0PFxuICBVSV9NRVNTQUdFIGV4dGVuZHMgVUlNZXNzYWdlLFxuPiBleHRlbmRzIEh0dHBDaGF0VHJhbnNwb3J0PFVJX01FU1NBR0U+IHtcbiAgY29uc3RydWN0b3Iob3B0aW9uczogSHR0cENoYXRUcmFuc3BvcnRJbml0T3B0aW9uczxVSV9NRVNTQUdFPiA9IHt9KSB7XG4gICAgc3VwZXIob3B0aW9ucyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgcHJvY2Vzc1Jlc3BvbnNlU3RyZWFtKFxuICAgIHN0cmVhbTogUmVhZGFibGVTdHJlYW08VWludDhBcnJheTxBcnJheUJ1ZmZlckxpa2U+PixcbiAgKTogUmVhZGFibGVTdHJlYW08VUlNZXNzYWdlQ2h1bms+IHtcbiAgICByZXR1cm4gcGFyc2VKc29uRXZlbnRTdHJlYW0oe1xuICAgICAgc3RyZWFtLFxuICAgICAgc2NoZW1hOiB1aU1lc3NhZ2VDaHVua1NjaGVtYSxcbiAgICB9KS5waXBlVGhyb3VnaChcbiAgICAgIG5ldyBUcmFuc2Zvcm1TdHJlYW08UGFyc2VSZXN1bHQ8VUlNZXNzYWdlQ2h1bms+LCBVSU1lc3NhZ2VDaHVuaz4oe1xuICAgICAgICBhc3luYyB0cmFuc2Zvcm0oY2h1bmssIGNvbnRyb2xsZXIpIHtcbiAgICAgICAgICBpZiAoIWNodW5rLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgIHRocm93IGNodW5rLmVycm9yO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoY2h1bmsudmFsdWUpO1xuICAgICAgICB9LFxuICAgICAgfSksXG4gICAgKTtcbiAgfVxufVxuIiwgImltcG9ydCB7XG4gIEZldGNoRnVuY3Rpb24sXG4gIFJlc29sdmFibGUsXG4gIHJlc29sdmUsXG4gIHdpdGhVc2VyQWdlbnRTdWZmaXgsXG4gIGdldFJ1bnRpbWVFbnZpcm9ubWVudFVzZXJBZ2VudCxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyBVSU1lc3NhZ2VDaHVuayB9IGZyb20gJy4uL3VpLW1lc3NhZ2Utc3RyZWFtL3VpLW1lc3NhZ2UtY2h1bmtzJztcbmltcG9ydCB7IENoYXRUcmFuc3BvcnQgfSBmcm9tICcuL2NoYXQtdHJhbnNwb3J0JztcbmltcG9ydCB7IFVJTWVzc2FnZSB9IGZyb20gJy4vdWktbWVzc2FnZXMnO1xuaW1wb3J0IHsgVkVSU0lPTiB9IGZyb20gJy4uL3ZlcnNpb24nO1xuXG5leHBvcnQgdHlwZSBQcmVwYXJlU2VuZE1lc3NhZ2VzUmVxdWVzdDxVSV9NRVNTQUdFIGV4dGVuZHMgVUlNZXNzYWdlPiA9IChcbiAgb3B0aW9uczoge1xuICAgIGlkOiBzdHJpbmc7XG4gICAgbWVzc2FnZXM6IFVJX01FU1NBR0VbXTtcbiAgICByZXF1ZXN0TWV0YWRhdGE6IHVua25vd247XG4gICAgYm9keTogUmVjb3JkPHN0cmluZywgYW55PiB8IHVuZGVmaW5lZDtcbiAgICBjcmVkZW50aWFsczogUmVxdWVzdENyZWRlbnRpYWxzIHwgdW5kZWZpbmVkO1xuICAgIGhlYWRlcnM6IEhlYWRlcnNJbml0IHwgdW5kZWZpbmVkO1xuICAgIGFwaTogc3RyaW5nO1xuICB9ICYge1xuICAgIHRyaWdnZXI6ICdzdWJtaXQtbWVzc2FnZScgfCAncmVnZW5lcmF0ZS1tZXNzYWdlJztcbiAgICBtZXNzYWdlSWQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgfSxcbikgPT5cbiAgfCB7XG4gICAgICBib2R5OiBvYmplY3Q7XG4gICAgICBoZWFkZXJzPzogSGVhZGVyc0luaXQ7XG4gICAgICBjcmVkZW50aWFscz86IFJlcXVlc3RDcmVkZW50aWFscztcbiAgICAgIGFwaT86IHN0cmluZztcbiAgICB9XG4gIHwgUHJvbWlzZUxpa2U8e1xuICAgICAgYm9keTogb2JqZWN0O1xuICAgICAgaGVhZGVycz86IEhlYWRlcnNJbml0O1xuICAgICAgY3JlZGVudGlhbHM/OiBSZXF1ZXN0Q3JlZGVudGlhbHM7XG4gICAgICBhcGk/OiBzdHJpbmc7XG4gICAgfT47XG5cbmV4cG9ydCB0eXBlIFByZXBhcmVSZWNvbm5lY3RUb1N0cmVhbVJlcXVlc3QgPSAob3B0aW9uczoge1xuICBpZDogc3RyaW5nO1xuICByZXF1ZXN0TWV0YWRhdGE6IHVua25vd247XG4gIGJvZHk6IFJlY29yZDxzdHJpbmcsIGFueT4gfCB1bmRlZmluZWQ7XG4gIGNyZWRlbnRpYWxzOiBSZXF1ZXN0Q3JlZGVudGlhbHMgfCB1bmRlZmluZWQ7XG4gIGhlYWRlcnM6IEhlYWRlcnNJbml0IHwgdW5kZWZpbmVkO1xuICBhcGk6IHN0cmluZztcbn0pID0+XG4gIHwge1xuICAgICAgaGVhZGVycz86IEhlYWRlcnNJbml0O1xuICAgICAgY3JlZGVudGlhbHM/OiBSZXF1ZXN0Q3JlZGVudGlhbHM7XG4gICAgICBhcGk/OiBzdHJpbmc7XG4gICAgfVxuICB8IFByb21pc2VMaWtlPHtcbiAgICAgIGhlYWRlcnM/OiBIZWFkZXJzSW5pdDtcbiAgICAgIGNyZWRlbnRpYWxzPzogUmVxdWVzdENyZWRlbnRpYWxzO1xuICAgICAgYXBpPzogc3RyaW5nO1xuICAgIH0+O1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHRoZSBgSHR0cENoYXRUcmFuc3BvcnRgIGNsYXNzLlxuICpcbiAqIEBwYXJhbSBVSV9NRVNTQUdFIC0gVGhlIHR5cGUgb2YgbWVzc2FnZSB0byBiZSB1c2VkIGluIHRoZSBjaGF0LlxuICovXG5leHBvcnQgdHlwZSBIdHRwQ2hhdFRyYW5zcG9ydEluaXRPcHRpb25zPFVJX01FU1NBR0UgZXh0ZW5kcyBVSU1lc3NhZ2U+ID0ge1xuICAvKipcbiAgICogVGhlIEFQSSBVUkwgdG8gYmUgdXNlZCBmb3IgdGhlIGNoYXQgdHJhbnNwb3J0LlxuICAgKiBEZWZhdWx0cyB0byAnL2FwaS9jaGF0Jy5cbiAgICovXG4gIGFwaT86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGNyZWRlbnRpYWxzIG1vZGUgdG8gYmUgdXNlZCBmb3IgdGhlIGZldGNoIHJlcXVlc3QuXG4gICAqIFBvc3NpYmxlIHZhbHVlcyBhcmU6ICdvbWl0JywgJ3NhbWUtb3JpZ2luJywgJ2luY2x1ZGUnLlxuICAgKiBEZWZhdWx0cyB0byAnc2FtZS1vcmlnaW4nLlxuICAgKi9cbiAgY3JlZGVudGlhbHM/OiBSZXNvbHZhYmxlPFJlcXVlc3RDcmVkZW50aWFscz47XG5cbiAgLyoqXG4gICAqIEhUVFAgaGVhZGVycyB0byBiZSBzZW50IHdpdGggdGhlIEFQSSByZXF1ZXN0LlxuICAgKi9cbiAgaGVhZGVycz86IFJlc29sdmFibGU8UmVjb3JkPHN0cmluZywgc3RyaW5nPiB8IEhlYWRlcnM+O1xuXG4gIC8qKlxuICAgKiBFeHRyYSBib2R5IG9iamVjdCB0byBiZSBzZW50IHdpdGggdGhlIEFQSSByZXF1ZXN0LlxuICAgKiBAZXhhbXBsZVxuICAgKiBTZW5kIGEgYHNlc3Npb25JZGAgdG8gdGhlIEFQSSBhbG9uZyB3aXRoIHRoZSBtZXNzYWdlcy5cbiAgICogYGBganNcbiAgICogdXNlQ2hhdCh7XG4gICAqICAgYm9keToge1xuICAgKiAgICAgc2Vzc2lvbklkOiAnMTIzJyxcbiAgICogICB9XG4gICAqIH0pXG4gICAqIGBgYFxuICAgKi9cbiAgYm9keT86IFJlc29sdmFibGU8b2JqZWN0PjtcblxuICAvKipcbiAgQ3VzdG9tIGZldGNoIGltcGxlbWVudGF0aW9uLiBZb3UgY2FuIHVzZSBpdCBhcyBhIG1pZGRsZXdhcmUgdG8gaW50ZXJjZXB0IHJlcXVlc3RzLFxuICBvciB0byBwcm92aWRlIGEgY3VzdG9tIGZldGNoIGltcGxlbWVudGF0aW9uIGZvciBlLmcuIHRlc3RpbmcuXG4gICAgICAqL1xuICBmZXRjaD86IEZldGNoRnVuY3Rpb247XG5cbiAgLyoqXG4gICAqIFdoZW4gYSBmdW5jdGlvbiBpcyBwcm92aWRlZCwgaXQgd2lsbCBiZSB1c2VkXG4gICAqIHRvIHByZXBhcmUgdGhlIHJlcXVlc3QgYm9keSBmb3IgdGhlIGNoYXQgQVBJLiBUaGlzIGNhbiBiZSB1c2VmdWwgZm9yXG4gICAqIGN1c3RvbWl6aW5nIHRoZSByZXF1ZXN0IGJvZHkgYmFzZWQgb24gdGhlIG1lc3NhZ2VzIGFuZCBkYXRhIGluIHRoZSBjaGF0LlxuICAgKlxuICAgKiBAcGFyYW0gaWQgVGhlIGlkIG9mIHRoZSBjaGF0LlxuICAgKiBAcGFyYW0gbWVzc2FnZXMgVGhlIGN1cnJlbnQgbWVzc2FnZXMgaW4gdGhlIGNoYXQuXG4gICAqIEBwYXJhbSByZXF1ZXN0Qm9keSBUaGUgcmVxdWVzdCBib2R5IG9iamVjdCBwYXNzZWQgaW4gdGhlIGNoYXQgcmVxdWVzdC5cbiAgICovXG4gIHByZXBhcmVTZW5kTWVzc2FnZXNSZXF1ZXN0PzogUHJlcGFyZVNlbmRNZXNzYWdlc1JlcXVlc3Q8VUlfTUVTU0FHRT47XG5cbiAgLyoqXG4gICAqIFdoZW4gYSBmdW5jdGlvbiBpcyBwcm92aWRlZCwgaXQgd2lsbCBiZSB1c2VkXG4gICAqIHRvIHByZXBhcmUgdGhlIHJlcXVlc3QgYm9keSBmb3IgdGhlIGNoYXQgQVBJLiBUaGlzIGNhbiBiZSB1c2VmdWwgZm9yXG4gICAqIGN1c3RvbWl6aW5nIHRoZSByZXF1ZXN0IGJvZHkgYmFzZWQgb24gdGhlIG1lc3NhZ2VzIGFuZCBkYXRhIGluIHRoZSBjaGF0LlxuICAgKlxuICAgKiBAcGFyYW0gaWQgVGhlIGlkIG9mIHRoZSBjaGF0LlxuICAgKiBAcGFyYW0gbWVzc2FnZXMgVGhlIGN1cnJlbnQgbWVzc2FnZXMgaW4gdGhlIGNoYXQuXG4gICAqIEBwYXJhbSByZXF1ZXN0Qm9keSBUaGUgcmVxdWVzdCBib2R5IG9iamVjdCBwYXNzZWQgaW4gdGhlIGNoYXQgcmVxdWVzdC5cbiAgICovXG4gIHByZXBhcmVSZWNvbm5lY3RUb1N0cmVhbVJlcXVlc3Q/OiBQcmVwYXJlUmVjb25uZWN0VG9TdHJlYW1SZXF1ZXN0O1xufTtcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEh0dHBDaGF0VHJhbnNwb3J0PFVJX01FU1NBR0UgZXh0ZW5kcyBVSU1lc3NhZ2U+XG4gIGltcGxlbWVudHMgQ2hhdFRyYW5zcG9ydDxVSV9NRVNTQUdFPlxue1xuICBwcm90ZWN0ZWQgYXBpOiBzdHJpbmc7XG4gIHByb3RlY3RlZCBjcmVkZW50aWFsczogSHR0cENoYXRUcmFuc3BvcnRJbml0T3B0aW9uczxVSV9NRVNTQUdFPlsnY3JlZGVudGlhbHMnXTtcbiAgcHJvdGVjdGVkIGhlYWRlcnM6IEh0dHBDaGF0VHJhbnNwb3J0SW5pdE9wdGlvbnM8VUlfTUVTU0FHRT5bJ2hlYWRlcnMnXTtcbiAgcHJvdGVjdGVkIGJvZHk6IEh0dHBDaGF0VHJhbnNwb3J0SW5pdE9wdGlvbnM8VUlfTUVTU0FHRT5bJ2JvZHknXTtcbiAgcHJvdGVjdGVkIGZldGNoPzogRmV0Y2hGdW5jdGlvbjtcbiAgcHJvdGVjdGVkIHByZXBhcmVTZW5kTWVzc2FnZXNSZXF1ZXN0PzogUHJlcGFyZVNlbmRNZXNzYWdlc1JlcXVlc3Q8VUlfTUVTU0FHRT47XG4gIHByb3RlY3RlZCBwcmVwYXJlUmVjb25uZWN0VG9TdHJlYW1SZXF1ZXN0PzogUHJlcGFyZVJlY29ubmVjdFRvU3RyZWFtUmVxdWVzdDtcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgYXBpID0gJy9hcGkvY2hhdCcsXG4gICAgY3JlZGVudGlhbHMsXG4gICAgaGVhZGVycyxcbiAgICBib2R5LFxuICAgIGZldGNoLFxuICAgIHByZXBhcmVTZW5kTWVzc2FnZXNSZXF1ZXN0LFxuICAgIHByZXBhcmVSZWNvbm5lY3RUb1N0cmVhbVJlcXVlc3QsXG4gIH06IEh0dHBDaGF0VHJhbnNwb3J0SW5pdE9wdGlvbnM8VUlfTUVTU0FHRT4pIHtcbiAgICB0aGlzLmFwaSA9IGFwaTtcbiAgICB0aGlzLmNyZWRlbnRpYWxzID0gY3JlZGVudGlhbHM7XG4gICAgdGhpcy5oZWFkZXJzID0gaGVhZGVycztcbiAgICB0aGlzLmJvZHkgPSBib2R5O1xuICAgIHRoaXMuZmV0Y2ggPSBmZXRjaDtcbiAgICB0aGlzLnByZXBhcmVTZW5kTWVzc2FnZXNSZXF1ZXN0ID0gcHJlcGFyZVNlbmRNZXNzYWdlc1JlcXVlc3Q7XG4gICAgdGhpcy5wcmVwYXJlUmVjb25uZWN0VG9TdHJlYW1SZXF1ZXN0ID0gcHJlcGFyZVJlY29ubmVjdFRvU3RyZWFtUmVxdWVzdDtcbiAgfVxuXG4gIGFzeW5jIHNlbmRNZXNzYWdlcyh7XG4gICAgYWJvcnRTaWduYWwsXG4gICAgLi4ub3B0aW9uc1xuICB9OiBQYXJhbWV0ZXJzPENoYXRUcmFuc3BvcnQ8VUlfTUVTU0FHRT5bJ3NlbmRNZXNzYWdlcyddPlswXSkge1xuICAgIGNvbnN0IHJlc29sdmVkQm9keSA9IGF3YWl0IHJlc29sdmUodGhpcy5ib2R5KTtcbiAgICBjb25zdCByZXNvbHZlZEhlYWRlcnMgPSBhd2FpdCByZXNvbHZlKHRoaXMuaGVhZGVycyk7XG4gICAgY29uc3QgcmVzb2x2ZWRDcmVkZW50aWFscyA9IGF3YWl0IHJlc29sdmUodGhpcy5jcmVkZW50aWFscyk7XG5cbiAgICBjb25zdCBwcmVwYXJlZFJlcXVlc3QgPSBhd2FpdCB0aGlzLnByZXBhcmVTZW5kTWVzc2FnZXNSZXF1ZXN0Py4oe1xuICAgICAgYXBpOiB0aGlzLmFwaSxcbiAgICAgIGlkOiBvcHRpb25zLmNoYXRJZCxcbiAgICAgIG1lc3NhZ2VzOiBvcHRpb25zLm1lc3NhZ2VzLFxuICAgICAgYm9keTogeyAuLi5yZXNvbHZlZEJvZHksIC4uLm9wdGlvbnMuYm9keSB9LFxuICAgICAgaGVhZGVyczogeyAuLi5yZXNvbHZlZEhlYWRlcnMsIC4uLm9wdGlvbnMuaGVhZGVycyB9LFxuICAgICAgY3JlZGVudGlhbHM6IHJlc29sdmVkQ3JlZGVudGlhbHMsXG4gICAgICByZXF1ZXN0TWV0YWRhdGE6IG9wdGlvbnMubWV0YWRhdGEsXG4gICAgICB0cmlnZ2VyOiBvcHRpb25zLnRyaWdnZXIsXG4gICAgICBtZXNzYWdlSWQ6IG9wdGlvbnMubWVzc2FnZUlkLFxuICAgIH0pO1xuXG4gICAgY29uc3QgYXBpID0gcHJlcGFyZWRSZXF1ZXN0Py5hcGkgPz8gdGhpcy5hcGk7XG4gICAgY29uc3QgaGVhZGVycyA9XG4gICAgICBwcmVwYXJlZFJlcXVlc3Q/LmhlYWRlcnMgIT09IHVuZGVmaW5lZFxuICAgICAgICA/IHByZXBhcmVkUmVxdWVzdC5oZWFkZXJzXG4gICAgICAgIDogeyAuLi5yZXNvbHZlZEhlYWRlcnMsIC4uLm9wdGlvbnMuaGVhZGVycyB9O1xuICAgIGNvbnN0IGJvZHkgPVxuICAgICAgcHJlcGFyZWRSZXF1ZXN0Py5ib2R5ICE9PSB1bmRlZmluZWRcbiAgICAgICAgPyBwcmVwYXJlZFJlcXVlc3QuYm9keVxuICAgICAgICA6IHtcbiAgICAgICAgICAgIC4uLnJlc29sdmVkQm9keSxcbiAgICAgICAgICAgIC4uLm9wdGlvbnMuYm9keSxcbiAgICAgICAgICAgIGlkOiBvcHRpb25zLmNoYXRJZCxcbiAgICAgICAgICAgIG1lc3NhZ2VzOiBvcHRpb25zLm1lc3NhZ2VzLFxuICAgICAgICAgICAgdHJpZ2dlcjogb3B0aW9ucy50cmlnZ2VyLFxuICAgICAgICAgICAgbWVzc2FnZUlkOiBvcHRpb25zLm1lc3NhZ2VJZCxcbiAgICAgICAgICB9O1xuICAgIGNvbnN0IGNyZWRlbnRpYWxzID0gcHJlcGFyZWRSZXF1ZXN0Py5jcmVkZW50aWFscyA/PyByZXNvbHZlZENyZWRlbnRpYWxzO1xuXG4gICAgLy8gYXZvaWQgY2FjaGluZyBnbG9iYWxUaGlzLmZldGNoIGluIGNhc2UgaXQgaXMgcGF0Y2hlZCBieSBvdGhlciBsaWJyYXJpZXNcbiAgICBjb25zdCBmZXRjaCA9IHRoaXMuZmV0Y2ggPz8gZ2xvYmFsVGhpcy5mZXRjaDtcblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goYXBpLCB7XG4gICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgIGhlYWRlcnM6IHdpdGhVc2VyQWdlbnRTdWZmaXgoXG4gICAgICAgIHtcbiAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICAgIC4uLmhlYWRlcnMsXG4gICAgICAgIH0sXG4gICAgICAgIGBhaS1zZGsvJHtWRVJTSU9OfWAsXG4gICAgICAgIGdldFJ1bnRpbWVFbnZpcm9ubWVudFVzZXJBZ2VudCgpLFxuICAgICAgKSxcbiAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KGJvZHkpLFxuICAgICAgY3JlZGVudGlhbHMsXG4gICAgICBzaWduYWw6IGFib3J0U2lnbmFsLFxuICAgIH0pO1xuXG4gICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAoYXdhaXQgcmVzcG9uc2UudGV4dCgpKSA/PyAnRmFpbGVkIHRvIGZldGNoIHRoZSBjaGF0IHJlc3BvbnNlLicsXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICghcmVzcG9uc2UuYm9keSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgcmVzcG9uc2UgYm9keSBpcyBlbXB0eS4nKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5wcm9jZXNzUmVzcG9uc2VTdHJlYW0ocmVzcG9uc2UuYm9keSk7XG4gIH1cblxuICBhc3luYyByZWNvbm5lY3RUb1N0cmVhbShcbiAgICBvcHRpb25zOiBQYXJhbWV0ZXJzPENoYXRUcmFuc3BvcnQ8VUlfTUVTU0FHRT5bJ3JlY29ubmVjdFRvU3RyZWFtJ10+WzBdLFxuICApOiBQcm9taXNlPFJlYWRhYmxlU3RyZWFtPFVJTWVzc2FnZUNodW5rPiB8IG51bGw+IHtcbiAgICBjb25zdCByZXNvbHZlZEJvZHkgPSBhd2FpdCByZXNvbHZlKHRoaXMuYm9keSk7XG4gICAgY29uc3QgcmVzb2x2ZWRIZWFkZXJzID0gYXdhaXQgcmVzb2x2ZSh0aGlzLmhlYWRlcnMpO1xuICAgIGNvbnN0IHJlc29sdmVkQ3JlZGVudGlhbHMgPSBhd2FpdCByZXNvbHZlKHRoaXMuY3JlZGVudGlhbHMpO1xuXG4gICAgY29uc3QgcHJlcGFyZWRSZXF1ZXN0ID0gYXdhaXQgdGhpcy5wcmVwYXJlUmVjb25uZWN0VG9TdHJlYW1SZXF1ZXN0Py4oe1xuICAgICAgYXBpOiB0aGlzLmFwaSxcbiAgICAgIGlkOiBvcHRpb25zLmNoYXRJZCxcbiAgICAgIGJvZHk6IHsgLi4ucmVzb2x2ZWRCb2R5LCAuLi5vcHRpb25zLmJvZHkgfSxcbiAgICAgIGhlYWRlcnM6IHsgLi4ucmVzb2x2ZWRIZWFkZXJzLCAuLi5vcHRpb25zLmhlYWRlcnMgfSxcbiAgICAgIGNyZWRlbnRpYWxzOiByZXNvbHZlZENyZWRlbnRpYWxzLFxuICAgICAgcmVxdWVzdE1ldGFkYXRhOiBvcHRpb25zLm1ldGFkYXRhLFxuICAgIH0pO1xuXG4gICAgY29uc3QgYXBpID0gcHJlcGFyZWRSZXF1ZXN0Py5hcGkgPz8gYCR7dGhpcy5hcGl9LyR7b3B0aW9ucy5jaGF0SWR9L3N0cmVhbWA7XG4gICAgY29uc3QgaGVhZGVycyA9XG4gICAgICBwcmVwYXJlZFJlcXVlc3Q/LmhlYWRlcnMgIT09IHVuZGVmaW5lZFxuICAgICAgICA/IHByZXBhcmVkUmVxdWVzdC5oZWFkZXJzXG4gICAgICAgIDogeyAuLi5yZXNvbHZlZEhlYWRlcnMsIC4uLm9wdGlvbnMuaGVhZGVycyB9O1xuICAgIGNvbnN0IGNyZWRlbnRpYWxzID0gcHJlcGFyZWRSZXF1ZXN0Py5jcmVkZW50aWFscyA/PyByZXNvbHZlZENyZWRlbnRpYWxzO1xuXG4gICAgLy8gYXZvaWQgY2FjaGluZyBnbG9iYWxUaGlzLmZldGNoIGluIGNhc2UgaXQgaXMgcGF0Y2hlZCBieSBvdGhlciBsaWJyYXJpZXNcbiAgICBjb25zdCBmZXRjaCA9IHRoaXMuZmV0Y2ggPz8gZ2xvYmFsVGhpcy5mZXRjaDtcblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goYXBpLCB7XG4gICAgICBtZXRob2Q6ICdHRVQnLFxuICAgICAgaGVhZGVyczogd2l0aFVzZXJBZ2VudFN1ZmZpeChcbiAgICAgICAgaGVhZGVycyxcbiAgICAgICAgYGFpLXNkay8ke1ZFUlNJT059YCxcbiAgICAgICAgZ2V0UnVudGltZUVudmlyb25tZW50VXNlckFnZW50KCksXG4gICAgICApLFxuICAgICAgY3JlZGVudGlhbHMsXG4gICAgfSk7XG5cbiAgICAvLyBubyBhY3RpdmUgc3RyZWFtIGZvdW5kLCBzbyB3ZSBkbyBub3QgcmVzdW1lXG4gICAgaWYgKHJlc3BvbnNlLnN0YXR1cyA9PT0gMjA0KSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIChhd2FpdCByZXNwb25zZS50ZXh0KCkpID8/ICdGYWlsZWQgdG8gZmV0Y2ggdGhlIGNoYXQgcmVzcG9uc2UuJyxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKCFyZXNwb25zZS5ib2R5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSByZXNwb25zZSBib2R5IGlzIGVtcHR5LicpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnByb2Nlc3NSZXNwb25zZVN0cmVhbShyZXNwb25zZS5ib2R5KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBwcm9jZXNzUmVzcG9uc2VTdHJlYW0oXG4gICAgc3RyZWFtOiBSZWFkYWJsZVN0cmVhbTxVaW50OEFycmF5PEFycmF5QnVmZmVyTGlrZT4+LFxuICApOiBSZWFkYWJsZVN0cmVhbTxVSU1lc3NhZ2VDaHVuaz47XG59XG4iLCAiaW1wb3J0IHsgaXNUb29sT3JEeW5hbWljVG9vbFVJUGFydCwgdHlwZSBVSU1lc3NhZ2UgfSBmcm9tICcuL3VpLW1lc3NhZ2VzJztcblxuLyoqXG5DaGVjayBpZiB0aGUgbWVzc2FnZSBpcyBhbiBhc3Npc3RhbnQgbWVzc2FnZSB3aXRoIGNvbXBsZXRlZCB0b29sIGNhbGxzLlxuVGhlIGxhc3Qgc3RlcCBvZiB0aGUgbWVzc2FnZSBtdXN0IGhhdmUgYXQgbGVhc3Qgb25lIHRvb2wgaW52b2NhdGlvbiBhbmRcbmFsbCB0b29sIGludm9jYXRpb25zIG11c3QgaGF2ZSBhIHJlc3VsdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxhc3RBc3Npc3RhbnRNZXNzYWdlSXNDb21wbGV0ZVdpdGhUb29sQ2FsbHMoe1xuICBtZXNzYWdlcyxcbn06IHtcbiAgbWVzc2FnZXM6IFVJTWVzc2FnZVtdO1xufSk6IGJvb2xlYW4ge1xuICBjb25zdCBtZXNzYWdlID0gbWVzc2FnZXNbbWVzc2FnZXMubGVuZ3RoIC0gMV07XG5cbiAgaWYgKCFtZXNzYWdlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKG1lc3NhZ2Uucm9sZSAhPT0gJ2Fzc2lzdGFudCcpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBsYXN0U3RlcFN0YXJ0SW5kZXggPSBtZXNzYWdlLnBhcnRzLnJlZHVjZSgobGFzdEluZGV4LCBwYXJ0LCBpbmRleCkgPT4ge1xuICAgIHJldHVybiBwYXJ0LnR5cGUgPT09ICdzdGVwLXN0YXJ0JyA/IGluZGV4IDogbGFzdEluZGV4O1xuICB9LCAtMSk7XG5cbiAgY29uc3QgbGFzdFN0ZXBUb29sSW52b2NhdGlvbnMgPSBtZXNzYWdlLnBhcnRzXG4gICAgLnNsaWNlKGxhc3RTdGVwU3RhcnRJbmRleCArIDEpXG4gICAgLmZpbHRlcihpc1Rvb2xPckR5bmFtaWNUb29sVUlQYXJ0KTtcblxuICByZXR1cm4gKFxuICAgIGxhc3RTdGVwVG9vbEludm9jYXRpb25zLmxlbmd0aCA+IDAgJiZcbiAgICBsYXN0U3RlcFRvb2xJbnZvY2F0aW9ucy5ldmVyeShcbiAgICAgIHBhcnQgPT5cbiAgICAgICAgcGFydC5zdGF0ZSA9PT0gJ291dHB1dC1hdmFpbGFibGUnIHx8IHBhcnQuc3RhdGUgPT09ICdvdXRwdXQtZXJyb3InLFxuICAgIClcbiAgKTtcbn1cbiIsICJpbXBvcnQgeyBVSU1lc3NhZ2VDaHVuayB9IGZyb20gJy4uL3VpLW1lc3NhZ2Utc3RyZWFtL3VpLW1lc3NhZ2UtY2h1bmtzJztcblxuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zZm9ybVRleHRUb1VpTWVzc2FnZVN0cmVhbSh7XG4gIHN0cmVhbSxcbn06IHtcbiAgc3RyZWFtOiBSZWFkYWJsZVN0cmVhbTxzdHJpbmc+O1xufSkge1xuICByZXR1cm4gc3RyZWFtLnBpcGVUaHJvdWdoKFxuICAgIG5ldyBUcmFuc2Zvcm1TdHJlYW08c3RyaW5nLCBVSU1lc3NhZ2VDaHVuaz4oe1xuICAgICAgc3RhcnQoY29udHJvbGxlcikge1xuICAgICAgICBjb250cm9sbGVyLmVucXVldWUoeyB0eXBlOiAnc3RhcnQnIH0pO1xuICAgICAgICBjb250cm9sbGVyLmVucXVldWUoeyB0eXBlOiAnc3RhcnQtc3RlcCcgfSk7XG4gICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7IHR5cGU6ICd0ZXh0LXN0YXJ0JywgaWQ6ICd0ZXh0LTEnIH0pO1xuICAgICAgfSxcblxuICAgICAgYXN5bmMgdHJhbnNmb3JtKHBhcnQsIGNvbnRyb2xsZXIpIHtcbiAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHsgdHlwZTogJ3RleHQtZGVsdGEnLCBpZDogJ3RleHQtMScsIGRlbHRhOiBwYXJ0IH0pO1xuICAgICAgfSxcblxuICAgICAgYXN5bmMgZmx1c2goY29udHJvbGxlcikge1xuICAgICAgICBjb250cm9sbGVyLmVucXVldWUoeyB0eXBlOiAndGV4dC1lbmQnLCBpZDogJ3RleHQtMScgfSk7XG4gICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7IHR5cGU6ICdmaW5pc2gtc3RlcCcgfSk7XG4gICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7IHR5cGU6ICdmaW5pc2gnIH0pO1xuICAgICAgfSxcbiAgICB9KSxcbiAgKTtcbn1cbiIsICJpbXBvcnQgeyBVSU1lc3NhZ2VDaHVuayB9IGZyb20gJy4uL3VpLW1lc3NhZ2Utc3RyZWFtL3VpLW1lc3NhZ2UtY2h1bmtzJztcbmltcG9ydCB7XG4gIEh0dHBDaGF0VHJhbnNwb3J0LFxuICBIdHRwQ2hhdFRyYW5zcG9ydEluaXRPcHRpb25zLFxufSBmcm9tICcuL2h0dHAtY2hhdC10cmFuc3BvcnQnO1xuaW1wb3J0IHsgdHJhbnNmb3JtVGV4dFRvVWlNZXNzYWdlU3RyZWFtIH0gZnJvbSAnLi90cmFuc2Zvcm0tdGV4dC10by11aS1tZXNzYWdlLXN0cmVhbSc7XG5pbXBvcnQgeyBVSU1lc3NhZ2UgfSBmcm9tICcuL3VpLW1lc3NhZ2VzJztcblxuZXhwb3J0IGNsYXNzIFRleHRTdHJlYW1DaGF0VHJhbnNwb3J0PFxuICBVSV9NRVNTQUdFIGV4dGVuZHMgVUlNZXNzYWdlLFxuPiBleHRlbmRzIEh0dHBDaGF0VHJhbnNwb3J0PFVJX01FU1NBR0U+IHtcbiAgY29uc3RydWN0b3Iob3B0aW9uczogSHR0cENoYXRUcmFuc3BvcnRJbml0T3B0aW9uczxVSV9NRVNTQUdFPiA9IHt9KSB7XG4gICAgc3VwZXIob3B0aW9ucyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgcHJvY2Vzc1Jlc3BvbnNlU3RyZWFtKFxuICAgIHN0cmVhbTogUmVhZGFibGVTdHJlYW08VWludDhBcnJheTxBcnJheUJ1ZmZlckxpa2U+PixcbiAgKTogUmVhZGFibGVTdHJlYW08VUlNZXNzYWdlQ2h1bms+IHtcbiAgICByZXR1cm4gdHJhbnNmb3JtVGV4dFRvVWlNZXNzYWdlU3RyZWFtKHtcbiAgICAgIHN0cmVhbTogc3RyZWFtLnBpcGVUaHJvdWdoKG5ldyBUZXh0RGVjb2RlclN0cmVhbSgpKSxcbiAgICB9KTtcbiAgfVxufVxuIiwgImltcG9ydCB7IFR5cGVWYWxpZGF0aW9uRXJyb3IgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcbmltcG9ydCB7XG4gIGxhenlWYWxpZGF0b3IsXG4gIFN0YW5kYXJkU2NoZW1hVjEsXG4gIFRvb2wsXG4gIHZhbGlkYXRlVHlwZXMsXG4gIFZhbGlkYXRvcixcbiAgem9kU2NoZW1hLFxufSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyLXV0aWxzJztcbmltcG9ydCB7IHogfSBmcm9tICd6b2QvdjQnO1xuaW1wb3J0IHsgSW52YWxpZEFyZ3VtZW50RXJyb3IgfSBmcm9tICcuLi9lcnJvcic7XG5pbXBvcnQgeyBwcm92aWRlck1ldGFkYXRhU2NoZW1hIH0gZnJvbSAnLi4vdHlwZXMvcHJvdmlkZXItbWV0YWRhdGEnO1xuaW1wb3J0IHtcbiAgRGF0YVVJUGFydCxcbiAgSW5mZXJVSU1lc3NhZ2VEYXRhLFxuICBJbmZlclVJTWVzc2FnZVRvb2xzLFxuICBUb29sVUlQYXJ0LFxuICBVSU1lc3NhZ2UsXG59IGZyb20gJy4vdWktbWVzc2FnZXMnO1xuXG5jb25zdCB1aU1lc3NhZ2VzU2NoZW1hID0gbGF6eVZhbGlkYXRvcigoKSA9PlxuICB6b2RTY2hlbWEoXG4gICAgei5hcnJheShcbiAgICAgIHoub2JqZWN0KHtcbiAgICAgICAgaWQ6IHouc3RyaW5nKCksXG4gICAgICAgIHJvbGU6IHouZW51bShbJ3N5c3RlbScsICd1c2VyJywgJ2Fzc2lzdGFudCddKSxcbiAgICAgICAgbWV0YWRhdGE6IHoudW5rbm93bigpLm9wdGlvbmFsKCksXG4gICAgICAgIHBhcnRzOiB6LmFycmF5KFxuICAgICAgICAgIHoudW5pb24oW1xuICAgICAgICAgICAgei5vYmplY3Qoe1xuICAgICAgICAgICAgICB0eXBlOiB6LmxpdGVyYWwoJ3RleHQnKSxcbiAgICAgICAgICAgICAgdGV4dDogei5zdHJpbmcoKSxcbiAgICAgICAgICAgICAgc3RhdGU6IHouZW51bShbJ3N0cmVhbWluZycsICdkb25lJ10pLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgei5vYmplY3Qoe1xuICAgICAgICAgICAgICB0eXBlOiB6LmxpdGVyYWwoJ3JlYXNvbmluZycpLFxuICAgICAgICAgICAgICB0ZXh0OiB6LnN0cmluZygpLFxuICAgICAgICAgICAgICBzdGF0ZTogei5lbnVtKFsnc3RyZWFtaW5nJywgJ2RvbmUnXSkub3B0aW9uYWwoKSxcbiAgICAgICAgICAgICAgcHJvdmlkZXJNZXRhZGF0YTogcHJvdmlkZXJNZXRhZGF0YVNjaGVtYS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB6Lm9iamVjdCh7XG4gICAgICAgICAgICAgIHR5cGU6IHoubGl0ZXJhbCgnc291cmNlLXVybCcpLFxuICAgICAgICAgICAgICBzb3VyY2VJZDogei5zdHJpbmcoKSxcbiAgICAgICAgICAgICAgdXJsOiB6LnN0cmluZygpLFxuICAgICAgICAgICAgICB0aXRsZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBwcm92aWRlck1ldGFkYXRhOiBwcm92aWRlck1ldGFkYXRhU2NoZW1hLm9wdGlvbmFsKCksXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIHoub2JqZWN0KHtcbiAgICAgICAgICAgICAgdHlwZTogei5saXRlcmFsKCdzb3VyY2UtZG9jdW1lbnQnKSxcbiAgICAgICAgICAgICAgc291cmNlSWQ6IHouc3RyaW5nKCksXG4gICAgICAgICAgICAgIG1lZGlhVHlwZTogei5zdHJpbmcoKSxcbiAgICAgICAgICAgICAgdGl0bGU6IHouc3RyaW5nKCksXG4gICAgICAgICAgICAgIGZpbGVuYW1lOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgei5vYmplY3Qoe1xuICAgICAgICAgICAgICB0eXBlOiB6LmxpdGVyYWwoJ2ZpbGUnKSxcbiAgICAgICAgICAgICAgbWVkaWFUeXBlOiB6LnN0cmluZygpLFxuICAgICAgICAgICAgICBmaWxlbmFtZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICB1cmw6IHouc3RyaW5nKCksXG4gICAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgei5vYmplY3Qoe1xuICAgICAgICAgICAgICB0eXBlOiB6LmxpdGVyYWwoJ3N0ZXAtc3RhcnQnKSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgei5vYmplY3Qoe1xuICAgICAgICAgICAgICB0eXBlOiB6LnN0cmluZygpLnN0YXJ0c1dpdGgoJ2RhdGEtJyksXG4gICAgICAgICAgICAgIGlkOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIGRhdGE6IHoudW5rbm93bigpLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB6Lm9iamVjdCh7XG4gICAgICAgICAgICAgIHR5cGU6IHoubGl0ZXJhbCgnZHluYW1pYy10b29sJyksXG4gICAgICAgICAgICAgIHRvb2xOYW1lOiB6LnN0cmluZygpLFxuICAgICAgICAgICAgICB0b29sQ2FsbElkOiB6LnN0cmluZygpLFxuICAgICAgICAgICAgICBzdGF0ZTogei5saXRlcmFsKCdpbnB1dC1zdHJlYW1pbmcnKSxcbiAgICAgICAgICAgICAgaW5wdXQ6IHoudW5rbm93bigpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIG91dHB1dDogei5uZXZlcigpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIGVycm9yVGV4dDogei5uZXZlcigpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIHoub2JqZWN0KHtcbiAgICAgICAgICAgICAgdHlwZTogei5saXRlcmFsKCdkeW5hbWljLXRvb2wnKSxcbiAgICAgICAgICAgICAgdG9vbE5hbWU6IHouc3RyaW5nKCksXG4gICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IHouc3RyaW5nKCksXG4gICAgICAgICAgICAgIHN0YXRlOiB6LmxpdGVyYWwoJ2lucHV0LWF2YWlsYWJsZScpLFxuICAgICAgICAgICAgICBpbnB1dDogei51bmtub3duKCksXG4gICAgICAgICAgICAgIG91dHB1dDogei5uZXZlcigpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIGVycm9yVGV4dDogei5uZXZlcigpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIGNhbGxQcm92aWRlck1ldGFkYXRhOiBwcm92aWRlck1ldGFkYXRhU2NoZW1hLm9wdGlvbmFsKCksXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIHoub2JqZWN0KHtcbiAgICAgICAgICAgICAgdHlwZTogei5saXRlcmFsKCdkeW5hbWljLXRvb2wnKSxcbiAgICAgICAgICAgICAgdG9vbE5hbWU6IHouc3RyaW5nKCksXG4gICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IHouc3RyaW5nKCksXG4gICAgICAgICAgICAgIHN0YXRlOiB6LmxpdGVyYWwoJ291dHB1dC1hdmFpbGFibGUnKSxcbiAgICAgICAgICAgICAgaW5wdXQ6IHoudW5rbm93bigpLFxuICAgICAgICAgICAgICBvdXRwdXQ6IHoudW5rbm93bigpLFxuICAgICAgICAgICAgICBlcnJvclRleHQ6IHoubmV2ZXIoKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBjYWxsUHJvdmlkZXJNZXRhZGF0YTogcHJvdmlkZXJNZXRhZGF0YVNjaGVtYS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBwcmVsaW1pbmFyeTogei5ib29sZWFuKCkub3B0aW9uYWwoKSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgei5vYmplY3Qoe1xuICAgICAgICAgICAgICB0eXBlOiB6LmxpdGVyYWwoJ2R5bmFtaWMtdG9vbCcpLFxuICAgICAgICAgICAgICB0b29sTmFtZTogei5zdHJpbmcoKSxcbiAgICAgICAgICAgICAgdG9vbENhbGxJZDogei5zdHJpbmcoKSxcbiAgICAgICAgICAgICAgc3RhdGU6IHoubGl0ZXJhbCgnb3V0cHV0LWVycm9yJyksXG4gICAgICAgICAgICAgIGlucHV0OiB6LnVua25vd24oKSxcbiAgICAgICAgICAgICAgb3V0cHV0OiB6Lm5ldmVyKCkub3B0aW9uYWwoKSxcbiAgICAgICAgICAgICAgZXJyb3JUZXh0OiB6LnN0cmluZygpLFxuICAgICAgICAgICAgICBjYWxsUHJvdmlkZXJNZXRhZGF0YTogcHJvdmlkZXJNZXRhZGF0YVNjaGVtYS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB6Lm9iamVjdCh7XG4gICAgICAgICAgICAgIHR5cGU6IHouc3RyaW5nKCkuc3RhcnRzV2l0aCgndG9vbC0nKSxcbiAgICAgICAgICAgICAgdG9vbENhbGxJZDogei5zdHJpbmcoKSxcbiAgICAgICAgICAgICAgc3RhdGU6IHoubGl0ZXJhbCgnaW5wdXQtc3RyZWFtaW5nJyksXG4gICAgICAgICAgICAgIHByb3ZpZGVyRXhlY3V0ZWQ6IHouYm9vbGVhbigpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIGlucHV0OiB6LnVua25vd24oKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBvdXRwdXQ6IHoubmV2ZXIoKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBlcnJvclRleHQ6IHoubmV2ZXIoKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBhcHByb3ZhbDogei5uZXZlcigpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIHoub2JqZWN0KHtcbiAgICAgICAgICAgICAgdHlwZTogei5zdHJpbmcoKS5zdGFydHNXaXRoKCd0b29sLScpLFxuICAgICAgICAgICAgICB0b29sQ2FsbElkOiB6LnN0cmluZygpLFxuICAgICAgICAgICAgICBzdGF0ZTogei5saXRlcmFsKCdpbnB1dC1hdmFpbGFibGUnKSxcbiAgICAgICAgICAgICAgcHJvdmlkZXJFeGVjdXRlZDogei5ib29sZWFuKCkub3B0aW9uYWwoKSxcbiAgICAgICAgICAgICAgaW5wdXQ6IHoudW5rbm93bigpLFxuICAgICAgICAgICAgICBvdXRwdXQ6IHoubmV2ZXIoKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBlcnJvclRleHQ6IHoubmV2ZXIoKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBjYWxsUHJvdmlkZXJNZXRhZGF0YTogcHJvdmlkZXJNZXRhZGF0YVNjaGVtYS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBhcHByb3ZhbDogei5uZXZlcigpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIHoub2JqZWN0KHtcbiAgICAgICAgICAgICAgdHlwZTogei5zdHJpbmcoKS5zdGFydHNXaXRoKCd0b29sLScpLFxuICAgICAgICAgICAgICB0b29sQ2FsbElkOiB6LnN0cmluZygpLFxuICAgICAgICAgICAgICBzdGF0ZTogei5saXRlcmFsKCdhcHByb3ZhbC1yZXF1ZXN0ZWQnKSxcbiAgICAgICAgICAgICAgaW5wdXQ6IHoudW5rbm93bigpLFxuICAgICAgICAgICAgICBwcm92aWRlckV4ZWN1dGVkOiB6LmJvb2xlYW4oKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBvdXRwdXQ6IHoubmV2ZXIoKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBlcnJvclRleHQ6IHoubmV2ZXIoKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBjYWxsUHJvdmlkZXJNZXRhZGF0YTogcHJvdmlkZXJNZXRhZGF0YVNjaGVtYS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBhcHByb3ZhbDogei5vYmplY3Qoe1xuICAgICAgICAgICAgICAgIGlkOiB6LnN0cmluZygpLFxuICAgICAgICAgICAgICAgIGFwcHJvdmVkOiB6Lm5ldmVyKCkub3B0aW9uYWwoKSxcbiAgICAgICAgICAgICAgICByZWFzb246IHoubmV2ZXIoKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgei5vYmplY3Qoe1xuICAgICAgICAgICAgICB0eXBlOiB6LnN0cmluZygpLnN0YXJ0c1dpdGgoJ3Rvb2wtJyksXG4gICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IHouc3RyaW5nKCksXG4gICAgICAgICAgICAgIHN0YXRlOiB6LmxpdGVyYWwoJ2FwcHJvdmFsLXJlc3BvbmRlZCcpLFxuICAgICAgICAgICAgICBpbnB1dDogei51bmtub3duKCksXG4gICAgICAgICAgICAgIHByb3ZpZGVyRXhlY3V0ZWQ6IHouYm9vbGVhbigpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIG91dHB1dDogei5uZXZlcigpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIGVycm9yVGV4dDogei5uZXZlcigpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIGNhbGxQcm92aWRlck1ldGFkYXRhOiBwcm92aWRlck1ldGFkYXRhU2NoZW1hLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIGFwcHJvdmFsOiB6Lm9iamVjdCh7XG4gICAgICAgICAgICAgICAgaWQ6IHouc3RyaW5nKCksXG4gICAgICAgICAgICAgICAgYXBwcm92ZWQ6IHouYm9vbGVhbigpLFxuICAgICAgICAgICAgICAgIHJlYXNvbjogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgei5vYmplY3Qoe1xuICAgICAgICAgICAgICB0eXBlOiB6LnN0cmluZygpLnN0YXJ0c1dpdGgoJ3Rvb2wtJyksXG4gICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IHouc3RyaW5nKCksXG4gICAgICAgICAgICAgIHN0YXRlOiB6LmxpdGVyYWwoJ291dHB1dC1hdmFpbGFibGUnKSxcbiAgICAgICAgICAgICAgcHJvdmlkZXJFeGVjdXRlZDogei5ib29sZWFuKCkub3B0aW9uYWwoKSxcbiAgICAgICAgICAgICAgaW5wdXQ6IHoudW5rbm93bigpLFxuICAgICAgICAgICAgICBvdXRwdXQ6IHoudW5rbm93bigpLFxuICAgICAgICAgICAgICBlcnJvclRleHQ6IHoubmV2ZXIoKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBjYWxsUHJvdmlkZXJNZXRhZGF0YTogcHJvdmlkZXJNZXRhZGF0YVNjaGVtYS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBwcmVsaW1pbmFyeTogei5ib29sZWFuKCkub3B0aW9uYWwoKSxcbiAgICAgICAgICAgICAgYXBwcm92YWw6IHpcbiAgICAgICAgICAgICAgICAub2JqZWN0KHtcbiAgICAgICAgICAgICAgICAgIGlkOiB6LnN0cmluZygpLFxuICAgICAgICAgICAgICAgICAgYXBwcm92ZWQ6IHoubGl0ZXJhbCh0cnVlKSxcbiAgICAgICAgICAgICAgICAgIHJlYXNvbjogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLm9wdGlvbmFsKCksXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIHoub2JqZWN0KHtcbiAgICAgICAgICAgICAgdHlwZTogei5zdHJpbmcoKS5zdGFydHNXaXRoKCd0b29sLScpLFxuICAgICAgICAgICAgICB0b29sQ2FsbElkOiB6LnN0cmluZygpLFxuICAgICAgICAgICAgICBzdGF0ZTogei5saXRlcmFsKCdvdXRwdXQtZXJyb3InKSxcbiAgICAgICAgICAgICAgcHJvdmlkZXJFeGVjdXRlZDogei5ib29sZWFuKCkub3B0aW9uYWwoKSxcbiAgICAgICAgICAgICAgaW5wdXQ6IHoudW5rbm93bigpLFxuICAgICAgICAgICAgICBvdXRwdXQ6IHoubmV2ZXIoKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBlcnJvclRleHQ6IHouc3RyaW5nKCksXG4gICAgICAgICAgICAgIGNhbGxQcm92aWRlck1ldGFkYXRhOiBwcm92aWRlck1ldGFkYXRhU2NoZW1hLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIGFwcHJvdmFsOiB6XG4gICAgICAgICAgICAgICAgLm9iamVjdCh7XG4gICAgICAgICAgICAgICAgICBpZDogei5zdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgIGFwcHJvdmVkOiB6LmxpdGVyYWwodHJ1ZSksXG4gICAgICAgICAgICAgICAgICByZWFzb246IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5vcHRpb25hbCgpLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB6Lm9iamVjdCh7XG4gICAgICAgICAgICAgIHR5cGU6IHouc3RyaW5nKCkuc3RhcnRzV2l0aCgndG9vbC0nKSxcbiAgICAgICAgICAgICAgdG9vbENhbGxJZDogei5zdHJpbmcoKSxcbiAgICAgICAgICAgICAgc3RhdGU6IHoubGl0ZXJhbCgnb3V0cHV0LWRlbmllZCcpLFxuICAgICAgICAgICAgICBwcm92aWRlckV4ZWN1dGVkOiB6LmJvb2xlYW4oKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBpbnB1dDogei51bmtub3duKCksXG4gICAgICAgICAgICAgIG91dHB1dDogei5uZXZlcigpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIGVycm9yVGV4dDogei5uZXZlcigpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIGNhbGxQcm92aWRlck1ldGFkYXRhOiBwcm92aWRlck1ldGFkYXRhU2NoZW1hLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIGFwcHJvdmFsOiB6Lm9iamVjdCh7XG4gICAgICAgICAgICAgICAgaWQ6IHouc3RyaW5nKCksXG4gICAgICAgICAgICAgICAgYXBwcm92ZWQ6IHoubGl0ZXJhbChmYWxzZSksXG4gICAgICAgICAgICAgICAgcmVhc29uOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgXSksXG4gICAgICAgICksXG4gICAgICB9KSxcbiAgICApLFxuICApLFxuKTtcblxuZXhwb3J0IHR5cGUgU2FmZVZhbGlkYXRlVUlNZXNzYWdlc1Jlc3VsdDxVSV9NRVNTQUdFIGV4dGVuZHMgVUlNZXNzYWdlPiA9XG4gIHwge1xuICAgICAgc3VjY2VzczogdHJ1ZTtcbiAgICAgIGRhdGE6IEFycmF5PFVJX01FU1NBR0U+O1xuICAgIH1cbiAgfCB7XG4gICAgICBzdWNjZXNzOiBmYWxzZTtcbiAgICAgIGVycm9yOiBFcnJvcjtcbiAgICB9O1xuXG4vKipcbiAqIFZhbGlkYXRlcyBhIGxpc3Qgb2YgVUkgbWVzc2FnZXMgbGlrZSBgdmFsaWRhdGVVSU1lc3NhZ2VzYCxcbiAqIGJ1dCBpbnN0ZWFkIG9mIHRocm93aW5nIGl0IHJldHVybnMgYHsgc3VjY2VzczogdHJ1ZSwgZGF0YSB9YFxuICogb3IgYHsgc3VjY2VzczogZmFsc2UsIGVycm9yIH1gLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc2FmZVZhbGlkYXRlVUlNZXNzYWdlczxVSV9NRVNTQUdFIGV4dGVuZHMgVUlNZXNzYWdlPih7XG4gIG1lc3NhZ2VzLFxuICBtZXRhZGF0YVNjaGVtYSxcbiAgZGF0YVNjaGVtYXMsXG4gIHRvb2xzLFxufToge1xuICBtZXNzYWdlczogdW5rbm93bjtcbiAgbWV0YWRhdGFTY2hlbWE/OlxuICAgIHwgVmFsaWRhdG9yPFVJTWVzc2FnZVsnbWV0YWRhdGEnXT5cbiAgICB8IFN0YW5kYXJkU2NoZW1hVjE8dW5rbm93biwgVUlfTUVTU0FHRVsnbWV0YWRhdGEnXT47XG4gIGRhdGFTY2hlbWFzPzoge1xuICAgIFtOQU1FIGluIGtleW9mIEluZmVyVUlNZXNzYWdlRGF0YTxVSV9NRVNTQUdFPiAmIHN0cmluZ10/OlxuICAgICAgfCBWYWxpZGF0b3I8SW5mZXJVSU1lc3NhZ2VEYXRhPFVJX01FU1NBR0U+W05BTUVdPlxuICAgICAgfCBTdGFuZGFyZFNjaGVtYVYxPHVua25vd24sIEluZmVyVUlNZXNzYWdlRGF0YTxVSV9NRVNTQUdFPltOQU1FXT47XG4gIH07XG4gIHRvb2xzPzoge1xuICAgIFtOQU1FIGluIGtleW9mIEluZmVyVUlNZXNzYWdlVG9vbHM8VUlfTUVTU0FHRT4gJiBzdHJpbmddPzogVG9vbDxcbiAgICAgIEluZmVyVUlNZXNzYWdlVG9vbHM8VUlfTUVTU0FHRT5bTkFNRV1bJ2lucHV0J10sXG4gICAgICBJbmZlclVJTWVzc2FnZVRvb2xzPFVJX01FU1NBR0U+W05BTUVdWydvdXRwdXQnXVxuICAgID47XG4gIH07XG59KTogUHJvbWlzZTxTYWZlVmFsaWRhdGVVSU1lc3NhZ2VzUmVzdWx0PFVJX01FU1NBR0U+PiB7XG4gIHRyeSB7XG4gICAgaWYgKG1lc3NhZ2VzID09IG51bGwpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICBlcnJvcjogbmV3IEludmFsaWRBcmd1bWVudEVycm9yKHtcbiAgICAgICAgICBwYXJhbWV0ZXI6ICdtZXNzYWdlcycsXG4gICAgICAgICAgdmFsdWU6IG1lc3NhZ2VzLFxuICAgICAgICAgIG1lc3NhZ2U6ICdtZXNzYWdlcyBwYXJhbWV0ZXIgbXVzdCBiZSBwcm92aWRlZCcsXG4gICAgICAgIH0pLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCB2YWxpZGF0ZWRNZXNzYWdlcyA9IGF3YWl0IHZhbGlkYXRlVHlwZXMoe1xuICAgICAgdmFsdWU6IG1lc3NhZ2VzLFxuICAgICAgc2NoZW1hOiB1aU1lc3NhZ2VzU2NoZW1hLFxuICAgIH0pO1xuXG4gICAgaWYgKG1ldGFkYXRhU2NoZW1hKSB7XG4gICAgICBmb3IgKGNvbnN0IG1lc3NhZ2Ugb2YgdmFsaWRhdGVkTWVzc2FnZXMpIHtcbiAgICAgICAgYXdhaXQgdmFsaWRhdGVUeXBlcyh7XG4gICAgICAgICAgdmFsdWU6IG1lc3NhZ2UubWV0YWRhdGEsXG4gICAgICAgICAgc2NoZW1hOiBtZXRhZGF0YVNjaGVtYSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGRhdGFTY2hlbWFzKSB7XG4gICAgICBmb3IgKGNvbnN0IG1lc3NhZ2Ugb2YgdmFsaWRhdGVkTWVzc2FnZXMpIHtcbiAgICAgICAgY29uc3QgZGF0YVBhcnRzID0gbWVzc2FnZS5wYXJ0cy5maWx0ZXIocGFydCA9PlxuICAgICAgICAgIHBhcnQudHlwZS5zdGFydHNXaXRoKCdkYXRhLScpLFxuICAgICAgICApIGFzIERhdGFVSVBhcnQ8SW5mZXJVSU1lc3NhZ2VEYXRhPFVJX01FU1NBR0U+PltdO1xuXG4gICAgICAgIGZvciAoY29uc3QgZGF0YVBhcnQgb2YgZGF0YVBhcnRzKSB7XG4gICAgICAgICAgY29uc3QgZGF0YU5hbWUgPSBkYXRhUGFydC50eXBlLnNsaWNlKDUpO1xuICAgICAgICAgIGNvbnN0IGRhdGFTY2hlbWEgPSBkYXRhU2NoZW1hc1tkYXRhTmFtZV07XG5cbiAgICAgICAgICBpZiAoIWRhdGFTY2hlbWEpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgICAgICBlcnJvcjogbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3Ioe1xuICAgICAgICAgICAgICAgIHZhbHVlOiBkYXRhUGFydC5kYXRhLFxuICAgICAgICAgICAgICAgIGNhdXNlOiBgTm8gZGF0YSBzY2hlbWEgZm91bmQgZm9yIGRhdGEgcGFydCAke2RhdGFOYW1lfWAsXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBhd2FpdCB2YWxpZGF0ZVR5cGVzKHtcbiAgICAgICAgICAgIHZhbHVlOiBkYXRhUGFydC5kYXRhLFxuICAgICAgICAgICAgc2NoZW1hOiBkYXRhU2NoZW1hLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRvb2xzKSB7XG4gICAgICBmb3IgKGNvbnN0IG1lc3NhZ2Ugb2YgdmFsaWRhdGVkTWVzc2FnZXMpIHtcbiAgICAgICAgY29uc3QgdG9vbFBhcnRzID0gbWVzc2FnZS5wYXJ0cy5maWx0ZXIocGFydCA9PlxuICAgICAgICAgIHBhcnQudHlwZS5zdGFydHNXaXRoKCd0b29sLScpLFxuICAgICAgICApIGFzIFRvb2xVSVBhcnQ8SW5mZXJVSU1lc3NhZ2VUb29sczxVSV9NRVNTQUdFPj5bXTtcblxuICAgICAgICBmb3IgKGNvbnN0IHRvb2xQYXJ0IG9mIHRvb2xQYXJ0cykge1xuICAgICAgICAgIGNvbnN0IHRvb2xOYW1lID0gdG9vbFBhcnQudHlwZS5zbGljZSg1KTtcbiAgICAgICAgICBjb25zdCB0b29sID0gdG9vbHNbdG9vbE5hbWVdO1xuXG4gICAgICAgICAgaWYgKCF0b29sKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgICAgZXJyb3I6IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKHtcbiAgICAgICAgICAgICAgICB2YWx1ZTogdG9vbFBhcnQuaW5wdXQsXG4gICAgICAgICAgICAgICAgY2F1c2U6IGBObyB0b29sIHNjaGVtYSBmb3VuZCBmb3IgdG9vbCBwYXJ0ICR7dG9vbE5hbWV9YCxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHRvb2xQYXJ0LnN0YXRlID09PSAnaW5wdXQtYXZhaWxhYmxlJyB8fFxuICAgICAgICAgICAgdG9vbFBhcnQuc3RhdGUgPT09ICdvdXRwdXQtYXZhaWxhYmxlJyB8fFxuICAgICAgICAgICAgdG9vbFBhcnQuc3RhdGUgPT09ICdvdXRwdXQtZXJyb3InXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBhd2FpdCB2YWxpZGF0ZVR5cGVzKHtcbiAgICAgICAgICAgICAgdmFsdWU6IHRvb2xQYXJ0LmlucHV0LFxuICAgICAgICAgICAgICBzY2hlbWE6IHRvb2wuaW5wdXRTY2hlbWEsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodG9vbFBhcnQuc3RhdGUgPT09ICdvdXRwdXQtYXZhaWxhYmxlJyAmJiB0b29sLm91dHB1dFNjaGVtYSkge1xuICAgICAgICAgICAgYXdhaXQgdmFsaWRhdGVUeXBlcyh7XG4gICAgICAgICAgICAgIHZhbHVlOiB0b29sUGFydC5vdXRwdXQsXG4gICAgICAgICAgICAgIHNjaGVtYTogdG9vbC5vdXRwdXRTY2hlbWEsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgIGRhdGE6IHZhbGlkYXRlZE1lc3NhZ2VzIGFzIEFycmF5PFVJX01FU1NBR0U+LFxuICAgIH07XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY29uc3QgZXJyID0gZXJyb3IgYXMgRXJyb3I7XG5cbiAgICByZXR1cm4ge1xuICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICBlcnJvcjogZXJyLFxuICAgIH07XG4gIH1cbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgYSBsaXN0IG9mIFVJIG1lc3NhZ2VzLlxuICpcbiAqIE1ldGFkYXRhLCBkYXRhIHBhcnRzLCBhbmQgZ2VuZXJpYyB0b29sIGNhbGwgc3RydWN0dXJlcyBhcmUgb25seSB2YWxpZGF0ZWQgaWZcbiAqIHRoZSBjb3JyZXNwb25kaW5nIHNjaGVtYXMgYXJlIHByb3ZpZGVkLiBPdGhlcndpc2UsIHRoZXkgYXJlIGFzc3VtZWQgdG8gYmVcbiAqIHZhbGlkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gdmFsaWRhdGVVSU1lc3NhZ2VzPFVJX01FU1NBR0UgZXh0ZW5kcyBVSU1lc3NhZ2U+KHtcbiAgbWVzc2FnZXMsXG4gIG1ldGFkYXRhU2NoZW1hLFxuICBkYXRhU2NoZW1hcyxcbiAgdG9vbHMsXG59OiB7XG4gIG1lc3NhZ2VzOiB1bmtub3duO1xuICBtZXRhZGF0YVNjaGVtYT86XG4gICAgfCBWYWxpZGF0b3I8VUlNZXNzYWdlWydtZXRhZGF0YSddPlxuICAgIHwgU3RhbmRhcmRTY2hlbWFWMTx1bmtub3duLCBVSV9NRVNTQUdFWydtZXRhZGF0YSddPjtcbiAgZGF0YVNjaGVtYXM/OiB7XG4gICAgW05BTUUgaW4ga2V5b2YgSW5mZXJVSU1lc3NhZ2VEYXRhPFVJX01FU1NBR0U+ICYgc3RyaW5nXT86XG4gICAgICB8IFZhbGlkYXRvcjxJbmZlclVJTWVzc2FnZURhdGE8VUlfTUVTU0FHRT5bTkFNRV0+XG4gICAgICB8IFN0YW5kYXJkU2NoZW1hVjE8dW5rbm93biwgSW5mZXJVSU1lc3NhZ2VEYXRhPFVJX01FU1NBR0U+W05BTUVdPjtcbiAgfTtcbiAgdG9vbHM/OiB7XG4gICAgW05BTUUgaW4ga2V5b2YgSW5mZXJVSU1lc3NhZ2VUb29sczxVSV9NRVNTQUdFPiAmIHN0cmluZ10/OiBUb29sPFxuICAgICAgSW5mZXJVSU1lc3NhZ2VUb29sczxVSV9NRVNTQUdFPltOQU1FXVsnaW5wdXQnXSxcbiAgICAgIEluZmVyVUlNZXNzYWdlVG9vbHM8VUlfTUVTU0FHRT5bTkFNRV1bJ291dHB1dCddXG4gICAgPjtcbiAgfTtcbn0pOiBQcm9taXNlPEFycmF5PFVJX01FU1NBR0U+PiB7XG4gIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgc2FmZVZhbGlkYXRlVUlNZXNzYWdlcyh7XG4gICAgbWVzc2FnZXMsXG4gICAgbWV0YWRhdGFTY2hlbWEsXG4gICAgZGF0YVNjaGVtYXMsXG4gICAgdG9vbHMsXG4gIH0pO1xuXG4gIGlmICghcmVzcG9uc2Uuc3VjY2VzcykgdGhyb3cgcmVzcG9uc2UuZXJyb3I7XG5cbiAgcmV0dXJuIHJlc3BvbnNlLmRhdGE7XG59XG4iLCAiaW1wb3J0IHtcbiAgZ2VuZXJhdGVJZCBhcyBnZW5lcmF0ZUlkRnVuYyxcbiAgZ2V0RXJyb3JNZXNzYWdlLFxuICBJZEdlbmVyYXRvcixcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyBVSU1lc3NhZ2UgfSBmcm9tICcuLi91aS91aS1tZXNzYWdlcyc7XG5pbXBvcnQgeyBoYW5kbGVVSU1lc3NhZ2VTdHJlYW1GaW5pc2ggfSBmcm9tICcuL2hhbmRsZS11aS1tZXNzYWdlLXN0cmVhbS1maW5pc2gnO1xuaW1wb3J0IHsgSW5mZXJVSU1lc3NhZ2VDaHVuayB9IGZyb20gJy4vdWktbWVzc2FnZS1jaHVua3MnO1xuaW1wb3J0IHsgVUlNZXNzYWdlU3RyZWFtT25GaW5pc2hDYWxsYmFjayB9IGZyb20gJy4vdWktbWVzc2FnZS1zdHJlYW0tb24tZmluaXNoLWNhbGxiYWNrJztcbmltcG9ydCB7IFVJTWVzc2FnZVN0cmVhbVdyaXRlciB9IGZyb20gJy4vdWktbWVzc2FnZS1zdHJlYW0td3JpdGVyJztcblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVVJTWVzc2FnZVN0cmVhbTxVSV9NRVNTQUdFIGV4dGVuZHMgVUlNZXNzYWdlPih7XG4gIGV4ZWN1dGUsXG4gIG9uRXJyb3IgPSBnZXRFcnJvck1lc3NhZ2UsXG4gIG9yaWdpbmFsTWVzc2FnZXMsXG4gIG9uRmluaXNoLFxuICBnZW5lcmF0ZUlkID0gZ2VuZXJhdGVJZEZ1bmMsXG59OiB7XG4gIGV4ZWN1dGU6IChvcHRpb25zOiB7XG4gICAgd3JpdGVyOiBVSU1lc3NhZ2VTdHJlYW1Xcml0ZXI8VUlfTUVTU0FHRT47XG4gIH0pID0+IFByb21pc2U8dm9pZD4gfCB2b2lkO1xuICBvbkVycm9yPzogKGVycm9yOiB1bmtub3duKSA9PiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBvcmlnaW5hbCBtZXNzYWdlcy4gSWYgdGhleSBhcmUgcHJvdmlkZWQsIHBlcnNpc3RlbmNlIG1vZGUgaXMgYXNzdW1lZCxcbiAgICogYW5kIGEgbWVzc2FnZSBJRCBpcyBwcm92aWRlZCBmb3IgdGhlIHJlc3BvbnNlIG1lc3NhZ2UuXG4gICAqL1xuICBvcmlnaW5hbE1lc3NhZ2VzPzogVUlfTUVTU0FHRVtdO1xuXG4gIG9uRmluaXNoPzogVUlNZXNzYWdlU3RyZWFtT25GaW5pc2hDYWxsYmFjazxVSV9NRVNTQUdFPjtcblxuICBnZW5lcmF0ZUlkPzogSWRHZW5lcmF0b3I7XG59KTogUmVhZGFibGVTdHJlYW08SW5mZXJVSU1lc3NhZ2VDaHVuazxVSV9NRVNTQUdFPj4ge1xuICBsZXQgY29udHJvbGxlciE6IFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXI8XG4gICAgSW5mZXJVSU1lc3NhZ2VDaHVuazxVSV9NRVNTQUdFPlxuICA+O1xuXG4gIGNvbnN0IG9uZ29pbmdTdHJlYW1Qcm9taXNlczogUHJvbWlzZTx2b2lkPltdID0gW107XG5cbiAgY29uc3Qgc3RyZWFtID0gbmV3IFJlYWRhYmxlU3RyZWFtKHtcbiAgICBzdGFydChjb250cm9sbGVyQXJnKSB7XG4gICAgICBjb250cm9sbGVyID0gY29udHJvbGxlckFyZztcbiAgICB9LFxuICB9KTtcblxuICBmdW5jdGlvbiBzYWZlRW5xdWV1ZShkYXRhOiBJbmZlclVJTWVzc2FnZUNodW5rPFVJX01FU1NBR0U+KSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShkYXRhKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLy8gc3VwcHJlc3MgZXJyb3JzIHdoZW4gdGhlIHN0cmVhbSBoYXMgYmVlbiBjbG9zZWRcbiAgICB9XG4gIH1cblxuICB0cnkge1xuICAgIGNvbnN0IHJlc3VsdCA9IGV4ZWN1dGUoe1xuICAgICAgd3JpdGVyOiB7XG4gICAgICAgIHdyaXRlKHBhcnQ6IEluZmVyVUlNZXNzYWdlQ2h1bms8VUlfTUVTU0FHRT4pIHtcbiAgICAgICAgICBzYWZlRW5xdWV1ZShwYXJ0KTtcbiAgICAgICAgfSxcbiAgICAgICAgbWVyZ2Uoc3RyZWFtQXJnKSB7XG4gICAgICAgICAgb25nb2luZ1N0cmVhbVByb21pc2VzLnB1c2goXG4gICAgICAgICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCByZWFkZXIgPSBzdHJlYW1BcmcuZ2V0UmVhZGVyKCk7XG4gICAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgeyBkb25lLCB2YWx1ZSB9ID0gYXdhaXQgcmVhZGVyLnJlYWQoKTtcbiAgICAgICAgICAgICAgICBpZiAoZG9uZSkgYnJlYWs7XG4gICAgICAgICAgICAgICAgc2FmZUVucXVldWUodmFsdWUpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KSgpLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgc2FmZUVucXVldWUoe1xuICAgICAgICAgICAgICAgIHR5cGU6ICdlcnJvcicsXG4gICAgICAgICAgICAgICAgZXJyb3JUZXh0OiBvbkVycm9yKGVycm9yKSxcbiAgICAgICAgICAgICAgfSBhcyBJbmZlclVJTWVzc2FnZUNodW5rPFVJX01FU1NBR0U+KTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICk7XG4gICAgICAgIH0sXG4gICAgICAgIG9uRXJyb3IsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgaWYgKHJlc3VsdCkge1xuICAgICAgb25nb2luZ1N0cmVhbVByb21pc2VzLnB1c2goXG4gICAgICAgIHJlc3VsdC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgc2FmZUVucXVldWUoe1xuICAgICAgICAgICAgdHlwZTogJ2Vycm9yJyxcbiAgICAgICAgICAgIGVycm9yVGV4dDogb25FcnJvcihlcnJvciksXG4gICAgICAgICAgfSBhcyBJbmZlclVJTWVzc2FnZUNodW5rPFVJX01FU1NBR0U+KTtcbiAgICAgICAgfSksXG4gICAgICApO1xuICAgIH1cbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBzYWZlRW5xdWV1ZSh7XG4gICAgICB0eXBlOiAnZXJyb3InLFxuICAgICAgZXJyb3JUZXh0OiBvbkVycm9yKGVycm9yKSxcbiAgICB9IGFzIEluZmVyVUlNZXNzYWdlQ2h1bms8VUlfTUVTU0FHRT4pO1xuICB9XG5cbiAgLy8gV2FpdCB1bnRpbCBhbGwgb25nb2luZyBzdHJlYW1zIGFyZSBkb25lLiBUaGlzIGFwcHJvYWNoIGVuYWJsZXMgbWVyZ2luZ1xuICAvLyBzdHJlYW1zIGV2ZW4gYWZ0ZXIgZXhlY3V0ZSBoYXMgcmV0dXJuZWQsIGFzIGxvbmcgYXMgdGhlcmUgaXMgc3RpbGwgYW5cbiAgLy8gb3BlbiBtZXJnZWQgc3RyZWFtLiBUaGlzIGlzIGltcG9ydGFudCB0byBlLmcuIGZvcndhcmQgbmV3IHN0cmVhbXMgYW5kXG4gIC8vIGZyb20gY2FsbGJhY2tzLlxuICBjb25zdCB3YWl0Rm9yU3RyZWFtczogUHJvbWlzZTx2b2lkPiA9IG5ldyBQcm9taXNlKGFzeW5jIHJlc29sdmUgPT4ge1xuICAgIHdoaWxlIChvbmdvaW5nU3RyZWFtUHJvbWlzZXMubGVuZ3RoID4gMCkge1xuICAgICAgYXdhaXQgb25nb2luZ1N0cmVhbVByb21pc2VzLnNoaWZ0KCk7XG4gICAgfVxuICAgIHJlc29sdmUoKTtcbiAgfSk7XG5cbiAgd2FpdEZvclN0cmVhbXMuZmluYWxseSgoKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnRyb2xsZXIuY2xvc2UoKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLy8gc3VwcHJlc3MgZXJyb3JzIHdoZW4gdGhlIHN0cmVhbSBoYXMgYmVlbiBjbG9zZWRcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBoYW5kbGVVSU1lc3NhZ2VTdHJlYW1GaW5pc2g8VUlfTUVTU0FHRT4oe1xuICAgIHN0cmVhbSxcbiAgICBtZXNzYWdlSWQ6IGdlbmVyYXRlSWQoKSxcbiAgICBvcmlnaW5hbE1lc3NhZ2VzLFxuICAgIG9uRmluaXNoLFxuICAgIG9uRXJyb3IsXG4gIH0pO1xufVxuIiwgImltcG9ydCB7IFVJTWVzc2FnZSB9IGZyb20gJy4uL3VpL3VpLW1lc3NhZ2VzJztcbmltcG9ydCB7IFVJTWVzc2FnZUNodW5rIH0gZnJvbSAnLi91aS1tZXNzYWdlLWNodW5rcyc7XG5pbXBvcnQge1xuICBjcmVhdGVTdHJlYW1pbmdVSU1lc3NhZ2VTdGF0ZSxcbiAgcHJvY2Vzc1VJTWVzc2FnZVN0cmVhbSxcbiAgU3RyZWFtaW5nVUlNZXNzYWdlU3RhdGUsXG59IGZyb20gJy4uL3VpL3Byb2Nlc3MtdWktbWVzc2FnZS1zdHJlYW0nO1xuaW1wb3J0IHtcbiAgQXN5bmNJdGVyYWJsZVN0cmVhbSxcbiAgY3JlYXRlQXN5bmNJdGVyYWJsZVN0cmVhbSxcbn0gZnJvbSAnLi4vdXRpbC9hc3luYy1pdGVyYWJsZS1zdHJlYW0nO1xuaW1wb3J0IHsgY29uc3VtZVN0cmVhbSB9IGZyb20gJy4uL3V0aWwvY29uc3VtZS1zdHJlYW0nO1xuXG4vKipcbiAqIFRyYW5zZm9ybXMgYSBzdHJlYW0gb2YgYFVJTWVzc2FnZUNodW5rYHMgaW50byBhbiBgQXN5bmNJdGVyYWJsZVN0cmVhbWAgb2YgYFVJTWVzc2FnZWBzLlxuICpcbiAqIEBwYXJhbSBvcHRpb25zLm1lc3NhZ2UgLSBUaGUgbGFzdCBhc3Npc3RhbnQgbWVzc2FnZSB0byB1c2UgYXMgYSBzdGFydGluZyBwb2ludCB3aGVuIHRoZSBjb252ZXJzYXRpb24gaXMgcmVzdW1lZC4gT3RoZXJ3aXNlIHVuZGVmaW5lZC5cbiAqIEBwYXJhbSBvcHRpb25zLnN0cmVhbSAtIFRoZSBzdHJlYW0gb2YgYFVJTWVzc2FnZUNodW5rYHMgdG8gcmVhZC5cbiAqIEBwYXJhbSBvcHRpb25zLnRlcm1pbmF0ZU9uRXJyb3IgLSBXaGV0aGVyIHRvIHRlcm1pbmF0ZSB0aGUgc3RyZWFtIGlmIGFuIGVycm9yIG9jY3Vycy5cbiAqIEBwYXJhbSBvcHRpb25zLm9uRXJyb3IgLSBBIGZ1bmN0aW9uIHRoYXQgaXMgY2FsbGVkIHdoZW4gYW4gZXJyb3Igb2NjdXJzLlxuICpcbiAqIEByZXR1cm5zIEFuIGBBc3luY0l0ZXJhYmxlU3RyZWFtYCBvZiBgVUlNZXNzYWdlYHMuIEVhY2ggc3RyZWFtIHBhcnQgaXMgYSBkaWZmZXJlbnQgc3RhdGUgb2YgdGhlIHNhbWUgbWVzc2FnZVxuICogYXMgaXQgaXMgYmVpbmcgY29tcGxldGVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVhZFVJTWVzc2FnZVN0cmVhbTxVSV9NRVNTQUdFIGV4dGVuZHMgVUlNZXNzYWdlPih7XG4gIG1lc3NhZ2UsXG4gIHN0cmVhbSxcbiAgb25FcnJvcixcbiAgdGVybWluYXRlT25FcnJvciA9IGZhbHNlLFxufToge1xuICBtZXNzYWdlPzogVUlfTUVTU0FHRTtcbiAgc3RyZWFtOiBSZWFkYWJsZVN0cmVhbTxVSU1lc3NhZ2VDaHVuaz47XG4gIG9uRXJyb3I/OiAoZXJyb3I6IHVua25vd24pID0+IHZvaWQ7XG4gIHRlcm1pbmF0ZU9uRXJyb3I/OiBib29sZWFuO1xufSk6IEFzeW5jSXRlcmFibGVTdHJlYW08VUlfTUVTU0FHRT4ge1xuICBsZXQgY29udHJvbGxlcjogUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcjxVSV9NRVNTQUdFPiB8IHVuZGVmaW5lZDtcbiAgbGV0IGhhc0Vycm9yZWQgPSBmYWxzZTtcblxuICBjb25zdCBvdXRwdXRTdHJlYW0gPSBuZXcgUmVhZGFibGVTdHJlYW08VUlfTUVTU0FHRT4oe1xuICAgIHN0YXJ0KGNvbnRyb2xsZXJQYXJhbSkge1xuICAgICAgY29udHJvbGxlciA9IGNvbnRyb2xsZXJQYXJhbTtcbiAgICB9LFxuICB9KTtcblxuICBjb25zdCBzdGF0ZSA9IGNyZWF0ZVN0cmVhbWluZ1VJTWVzc2FnZVN0YXRlPFVJX01FU1NBR0U+KHtcbiAgICBtZXNzYWdlSWQ6IG1lc3NhZ2U/LmlkID8/ICcnLFxuICAgIGxhc3RNZXNzYWdlOiBtZXNzYWdlLFxuICB9KTtcblxuICBjb25zdCBoYW5kbGVFcnJvciA9IChlcnJvcjogdW5rbm93bikgPT4ge1xuICAgIG9uRXJyb3I/LihlcnJvcik7XG5cbiAgICBpZiAoIWhhc0Vycm9yZWQgJiYgdGVybWluYXRlT25FcnJvcikge1xuICAgICAgaGFzRXJyb3JlZCA9IHRydWU7XG4gICAgICBjb250cm9sbGVyPy5lcnJvcihlcnJvcik7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN1bWVTdHJlYW0oe1xuICAgIHN0cmVhbTogcHJvY2Vzc1VJTWVzc2FnZVN0cmVhbSh7XG4gICAgICBzdHJlYW0sXG4gICAgICBydW5VcGRhdGVNZXNzYWdlSm9iKFxuICAgICAgICBqb2I6IChvcHRpb25zOiB7XG4gICAgICAgICAgc3RhdGU6IFN0cmVhbWluZ1VJTWVzc2FnZVN0YXRlPFVJX01FU1NBR0U+O1xuICAgICAgICAgIHdyaXRlOiAoKSA9PiB2b2lkO1xuICAgICAgICB9KSA9PiBQcm9taXNlPHZvaWQ+LFxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBqb2Ioe1xuICAgICAgICAgIHN0YXRlLFxuICAgICAgICAgIHdyaXRlOiAoKSA9PiB7XG4gICAgICAgICAgICBjb250cm9sbGVyPy5lbnF1ZXVlKHN0cnVjdHVyZWRDbG9uZShzdGF0ZS5tZXNzYWdlKSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICAgb25FcnJvcjogaGFuZGxlRXJyb3IsXG4gICAgfSksXG4gICAgb25FcnJvcjogaGFuZGxlRXJyb3IsXG4gIH0pLmZpbmFsbHkoKCkgPT4ge1xuICAgIC8vIE9ubHkgY2xvc2UgaWYgbm8gZXJyb3Igb2NjdXJyZWQuIENhbGxpbmcgY2xvc2UoKSBvbiBhbiBlcnJvcmVkIGNvbnRyb2xsZXJcbiAgICAvLyB0aHJvd3MgXCJJbnZhbGlkIHN0YXRlOiBDb250cm9sbGVyIGlzIGFscmVhZHkgY2xvc2VkXCIgVHlwZUVycm9yLlxuICAgIGlmICghaGFzRXJyb3JlZCkge1xuICAgICAgY29udHJvbGxlcj8uY2xvc2UoKTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBjcmVhdGVBc3luY0l0ZXJhYmxlU3RyZWFtKG91dHB1dFN0cmVhbSk7XG59XG4iLCAiLyoqX19pbnRlcm5hbF93b3JrZmxvd3N7XCJ3b3JrZmxvd3NcIjp7XCJleGFtcGxlL3dvcmtmbG93cy8zX3N0cmVhbXMudHNcIjp7XCJzdHJlYW1zXCI6e1wid29ya2Zsb3dJZFwiOlwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzNfc3RyZWFtcy50cy8vc3RyZWFtc1wifX19LFwic3RlcHNcIjp7XCJleGFtcGxlL3dvcmtmbG93cy8zX3N0cmVhbXMudHNcIjp7XCJjb25zdW1lU3RyZWFtc1wiOntcInN0ZXBJZFwiOlwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvM19zdHJlYW1zLnRzLy9jb25zdW1lU3RyZWFtc1wifSxcImdlblN0cmVhbVwiOntcInN0ZXBJZFwiOlwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvM19zdHJlYW1zLnRzLy9nZW5TdHJlYW1cIn19fX0qLztcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZW5TdHJlYW0oKSB7XG4gICAgcmV0dXJuIGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1VTRV9TVEVQXCIpXShcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzNfc3RyZWFtcy50cy8vZ2VuU3RyZWFtXCIpKCk7XG59XG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY29uc3VtZVN0cmVhbXMoLi4uc3RyZWFtcykge1xuICAgIHJldHVybiBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19VU0VfU1RFUFwiKV0oXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy8zX3N0cmVhbXMudHMvL2NvbnN1bWVTdHJlYW1zXCIpKC4uLnN0cmVhbXMpO1xufVxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHN0cmVhbXMoKSB7XG4gICAgY29uc29sZS5sb2coJ1N0cmVhbXMgd29ya2Zsb3cgc3RhcnRlZCcpO1xuICAgIGNvbnN0IFtzMSwgczJdID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICBnZW5TdHJlYW0oKSxcbiAgICAgICAgZ2VuU3RyZWFtKClcbiAgICBdKTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjb25zdW1lU3RyZWFtcyhzMSwgczIpO1xuICAgIGNvbnNvbGUubG9nKGBTdHJlYW1zIHdvcmtmbG93IGNvbXBsZXRlZC4gUmVzdWx0OiAke3Jlc3VsdC5zbGljZSgwLCAxMDApfWApO1xuICAgIHJldHVybiB7XG4gICAgICAgIG1lc3NhZ2U6ICdTdHJlYW1zIHByb2Nlc3NlZCBzdWNjZXNzZnVsbHknLFxuICAgICAgICBkYXRhTGVuZ3RoOiByZXN1bHQubGVuZ3RoLFxuICAgICAgICBwcmV2aWV3OiByZXN1bHQuc2xpY2UoMCwgMTAwKVxuICAgIH07XG59XG5zdHJlYW1zLndvcmtmbG93SWQgPSBcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy8zX3N0cmVhbXMudHMvL3N0cmVhbXNcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShnZW5TdHJlYW0sIFN5bWJvbC5mb3IoXCJXT1JLRkxPV19TVEVQX0ZVTkNUSU9OX05BTUVcIiksIHtcbiAgICB2YWx1ZTogXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy8zX3N0cmVhbXMudHMvL2dlblN0cmVhbVwiLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlXG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb25zdW1lU3RyZWFtcywgU3ltYm9sLmZvcihcIldPUktGTE9XX1NURVBfRlVOQ1RJT05fTkFNRVwiKSwge1xuICAgIHZhbHVlOiBcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzNfc3RyZWFtcy50cy8vY29uc3VtZVN0cmVhbXNcIixcbiAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiBmYWxzZVxufSk7XG4iLCAiaW1wb3J0IHsgY3JlYXRlV2ViaG9vaywgc2xlZXAgfSBmcm9tIFwid29ya2Zsb3dcIjtcbi8qKl9faW50ZXJuYWxfd29ya2Zsb3dze1wid29ya2Zsb3dzXCI6e1wiZXhhbXBsZS93b3JrZmxvd3MvN19mdWxsLnRzXCI6e1wiaGFuZGxlVXNlclNpZ251cFwiOntcIndvcmtmbG93SWRcIjpcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy83X2Z1bGwudHMvL2hhbmRsZVVzZXJTaWdudXBcIn19fSxcInN0ZXBzXCI6e1wiZXhhbXBsZS93b3JrZmxvd3MvN19mdWxsLnRzXCI6e1wiY3JlYXRlVXNlclwiOntcInN0ZXBJZFwiOlwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvN19mdWxsLnRzLy9jcmVhdGVVc2VyXCJ9LFwic2VuZE9uYm9hcmRpbmdFbWFpbFwiOntcInN0ZXBJZFwiOlwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvN19mdWxsLnRzLy9zZW5kT25ib2FyZGluZ0VtYWlsXCJ9LFwic2VuZFdlbGNvbWVFbWFpbFwiOntcInN0ZXBJZFwiOlwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvN19mdWxsLnRzLy9zZW5kV2VsY29tZUVtYWlsXCJ9fX19Ki87XG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaGFuZGxlVXNlclNpZ251cChlbWFpbCkge1xuICAgIGNvbnN0IHVzZXIgPSBhd2FpdCBjcmVhdGVVc2VyKGVtYWlsKTtcbiAgICBhd2FpdCBzZW5kV2VsY29tZUVtYWlsKHVzZXIpO1xuICAgIGF3YWl0IHNsZWVwKCc1cycpO1xuICAgIGNvbnN0IHdlYmhvb2sgPSBjcmVhdGVXZWJob29rKCk7XG4gICAgYXdhaXQgc2VuZE9uYm9hcmRpbmdFbWFpbCh1c2VyLCB3ZWJob29rLnVybCk7XG4gICAgYXdhaXQgd2ViaG9vaztcbiAgICBjb25zb2xlLmxvZygnV2ViaG9vayBSZXNvbHZlZCcpO1xuICAgIHJldHVybiB7XG4gICAgICAgIHVzZXJJZDogdXNlci5pZCxcbiAgICAgICAgc3RhdHVzOiAnb25ib2FyZGVkJ1xuICAgIH07XG59XG5hc3luYyBmdW5jdGlvbiBjcmVhdGVVc2VyKGVtYWlsKSB7XG4gICAgcmV0dXJuIGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1VTRV9TVEVQXCIpXShcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzdfZnVsbC50cy8vY3JlYXRlVXNlclwiKShlbWFpbCk7XG59XG5hc3luYyBmdW5jdGlvbiBzZW5kV2VsY29tZUVtYWlsKHVzZXIpIHtcbiAgICByZXR1cm4gZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildKFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvN19mdWxsLnRzLy9zZW5kV2VsY29tZUVtYWlsXCIpKHVzZXIpO1xufVxuYXN5bmMgZnVuY3Rpb24gc2VuZE9uYm9hcmRpbmdFbWFpbCh1c2VyLCBjYWxsYmFjaykge1xuICAgIHJldHVybiBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19VU0VfU1RFUFwiKV0oXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy83X2Z1bGwudHMvL3NlbmRPbmJvYXJkaW5nRW1haWxcIikodXNlciwgY2FsbGJhY2spO1xufVxuaGFuZGxlVXNlclNpZ251cC53b3JrZmxvd0lkID0gXCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvN19mdWxsLnRzLy9oYW5kbGVVc2VyU2lnbnVwXCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoY3JlYXRlVXNlciwgU3ltYm9sLmZvcihcIldPUktGTE9XX1NURVBfRlVOQ1RJT05fTkFNRVwiKSwge1xuICAgIHZhbHVlOiBcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzdfZnVsbC50cy8vY3JlYXRlVXNlclwiLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlXG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShzZW5kV2VsY29tZUVtYWlsLCBTeW1ib2wuZm9yKFwiV09SS0ZMT1dfU1RFUF9GVU5DVElPTl9OQU1FXCIpLCB7XG4gICAgdmFsdWU6IFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvN19mdWxsLnRzLy9zZW5kV2VsY29tZUVtYWlsXCIsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2Vcbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHNlbmRPbmJvYXJkaW5nRW1haWwsIFN5bWJvbC5mb3IoXCJXT1JLRkxPV19TVEVQX0ZVTkNUSU9OX05BTUVcIiksIHtcbiAgICB2YWx1ZTogXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy83X2Z1bGwudHMvL3NlbmRPbmJvYXJkaW5nRW1haWxcIixcbiAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiBmYWxzZVxufSk7XG4iLCAiZ2xvYmFsVGhpcy5fX3ByaXZhdGVfd29ya2Zsb3dzID0gbmV3IE1hcCgpO1xuaW1wb3J0ICogYXMgd29ya2Zsb3dGaWxlMCBmcm9tICcuLi9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMnO1xuICAgICAgICAgICAgT2JqZWN0LnZhbHVlcyh3b3JrZmxvd0ZpbGUwKS5tYXAoaXRlbSA9PiBpdGVtPy53b3JrZmxvd0lkICYmIGdsb2JhbFRoaXMuX19wcml2YXRlX3dvcmtmbG93cy5zZXQoaXRlbS53b3JrZmxvd0lkLCBpdGVtKSlcbmltcG9ydCAqIGFzIHdvcmtmbG93RmlsZTEgZnJvbSAnLi4vZXhhbXBsZS93b3JrZmxvd3MvMl9jb250cm9sX2Zsb3cudHMnO1xuICAgICAgICAgICAgT2JqZWN0LnZhbHVlcyh3b3JrZmxvd0ZpbGUxKS5tYXAoaXRlbSA9PiBpdGVtPy53b3JrZmxvd0lkICYmIGdsb2JhbFRoaXMuX19wcml2YXRlX3dvcmtmbG93cy5zZXQoaXRlbS53b3JrZmxvd0lkLCBpdGVtKSlcbmltcG9ydCAqIGFzIHdvcmtmbG93RmlsZTIgZnJvbSAnLi4vbml0cm8tdjMvd29ya2Zsb3dzLzBfZGVtby50cyc7XG4gICAgICAgICAgICBPYmplY3QudmFsdWVzKHdvcmtmbG93RmlsZTIpLm1hcChpdGVtID0+IGl0ZW0/LndvcmtmbG93SWQgJiYgZ2xvYmFsVGhpcy5fX3ByaXZhdGVfd29ya2Zsb3dzLnNldChpdGVtLndvcmtmbG93SWQsIGl0ZW0pKVxuaW1wb3J0ICogYXMgd29ya2Zsb3dGaWxlMyBmcm9tICcuLi9leGFtcGxlL3dvcmtmbG93cy85OF9kdXBsaWNhdGVfY2FzZS50cyc7XG4gICAgICAgICAgICBPYmplY3QudmFsdWVzKHdvcmtmbG93RmlsZTMpLm1hcChpdGVtID0+IGl0ZW0/LndvcmtmbG93SWQgJiYgZ2xvYmFsVGhpcy5fX3ByaXZhdGVfd29ya2Zsb3dzLnNldChpdGVtLndvcmtmbG93SWQsIGl0ZW0pKVxuaW1wb3J0ICogYXMgd29ya2Zsb3dGaWxlNCBmcm9tICcuLi9leGFtcGxlL3dvcmtmbG93cy82X2JhdGNoaW5nLnRzJztcbiAgICAgICAgICAgIE9iamVjdC52YWx1ZXMod29ya2Zsb3dGaWxlNCkubWFwKGl0ZW0gPT4gaXRlbT8ud29ya2Zsb3dJZCAmJiBnbG9iYWxUaGlzLl9fcHJpdmF0ZV93b3JrZmxvd3Muc2V0KGl0ZW0ud29ya2Zsb3dJZCwgaXRlbSkpXG5pbXBvcnQgKiBhcyB3b3JrZmxvd0ZpbGU1IGZyb20gJy4uL2V4YW1wbGUvd29ya2Zsb3dzLzFfc2ltcGxlLnRzJztcbiAgICAgICAgICAgIE9iamVjdC52YWx1ZXMod29ya2Zsb3dGaWxlNSkubWFwKGl0ZW0gPT4gaXRlbT8ud29ya2Zsb3dJZCAmJiBnbG9iYWxUaGlzLl9fcHJpdmF0ZV93b3JrZmxvd3Muc2V0KGl0ZW0ud29ya2Zsb3dJZCwgaXRlbSkpXG5pbXBvcnQgKiBhcyB3b3JrZmxvd0ZpbGU2IGZyb20gJy4uL2V4YW1wbGUvd29ya2Zsb3dzLzVfaG9va3MudHMnO1xuICAgICAgICAgICAgT2JqZWN0LnZhbHVlcyh3b3JrZmxvd0ZpbGU2KS5tYXAoaXRlbSA9PiBpdGVtPy53b3JrZmxvd0lkICYmIGdsb2JhbFRoaXMuX19wcml2YXRlX3dvcmtmbG93cy5zZXQoaXRlbS53b3JrZmxvd0lkLCBpdGVtKSlcbmltcG9ydCAqIGFzIHdvcmtmbG93RmlsZTcgZnJvbSAnLi4vZXhhbXBsZS93b3JrZmxvd3MvNF9haS50cyc7XG4gICAgICAgICAgICBPYmplY3QudmFsdWVzKHdvcmtmbG93RmlsZTcpLm1hcChpdGVtID0+IGl0ZW0/LndvcmtmbG93SWQgJiYgZ2xvYmFsVGhpcy5fX3ByaXZhdGVfd29ya2Zsb3dzLnNldChpdGVtLndvcmtmbG93SWQsIGl0ZW0pKVxuaW1wb3J0ICogYXMgd29ya2Zsb3dGaWxlOCBmcm9tICcuLi9leGFtcGxlL3dvcmtmbG93cy8zX3N0cmVhbXMudHMnO1xuICAgICAgICAgICAgT2JqZWN0LnZhbHVlcyh3b3JrZmxvd0ZpbGU4KS5tYXAoaXRlbSA9PiBpdGVtPy53b3JrZmxvd0lkICYmIGdsb2JhbFRoaXMuX19wcml2YXRlX3dvcmtmbG93cy5zZXQoaXRlbS53b3JrZmxvd0lkLCBpdGVtKSlcbmltcG9ydCAqIGFzIHdvcmtmbG93RmlsZTkgZnJvbSAnLi4vZXhhbXBsZS93b3JrZmxvd3MvN19mdWxsLnRzJztcbiAgICAgICAgICAgIE9iamVjdC52YWx1ZXMod29ya2Zsb3dGaWxlOSkubWFwKGl0ZW0gPT4gaXRlbT8ud29ya2Zsb3dJZCAmJiBnbG9iYWxUaGlzLl9fcHJpdmF0ZV93b3JrZmxvd3Muc2V0KGl0ZW0ud29ya2Zsb3dJZCwgaXRlbSkpIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBLHdFQUFBQSxTQUFBO0FBRUksUUFBSSxJQUFJO0FBQ1osUUFB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QTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxrQkFBQUM7QUFBQSxFQUFBO0FBQUE7QUFBQTtBQUFBLGdCQUFBQztBQUFBLEVBQUEsaUJBQUFDO0FBQUEsRUFBQSxjQUFBQztBQUFBLEVBQUEsZUFBQUM7QUFBQSxFQUFBLGFBQUFDO0FBQUEsRUFBQTtBQUFBLGdCQUFBQztBQUFBLEVBQUEsY0FBQUM7QUFBQSxFQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsY0FBQUM7QUFBQSxFQUFBLFlBQUFDO0FBQUEsRUFBQSxhQUFBQztBQUFBLEVBQUE7QUFBQSxjQUFBQztBQUFBLEVBQUEsY0FBQUM7QUFBQSxFQUFBLG1CQUFBQztBQUFBLEVBQUE7QUFBQSxjQUFBQztBQUFBLEVBQUEsYUFBQUM7QUFBQSxFQUFBLGFBQUFDO0FBQUEsRUFBQSxjQUFBQztBQUFBLEVBQUEsbUJBQUFDO0FBQUEsRUFBQTtBQUFBLGNBQUFDO0FBQUEsRUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLGNBQUFDO0FBQUEsRUFBQTtBQUFBLGFBQUFDO0FBQUEsRUFBQSxnQkFBQUM7QUFBQSxFQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsY0FBQUM7QUFBQSxFQUFBLFlBQUFDO0FBQUEsRUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLGVBQUFDO0FBQUEsRUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLGdCQUFBQztBQUFBLEVBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxjQUFBQztBQUFBLEVBQUE7QUFBQSxpQkFBQUM7QUFBQSxFQUFBLGNBQUFDO0FBQUEsRUFBQTtBQUFBO0FBQUE7QUFBQSxlQUFBQztBQUFBLEVBQUEsa0JBQUFDO0FBQUEsRUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsb0JBQUFDO0FBQUEsRUFBQSx1QkFBQUM7QUFBQSxFQUFBLGtCQUFBQztBQUFBLEVBQUEsdUJBQUFDO0FBQUEsRUFBQSxpQkFBQUM7QUFBQSxFQUFBLHNCQUFBQztBQUFBLEVBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLGdCQUFBQztBQUFBLEVBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxnQkFBQUM7QUFBQSxFQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsY0FBQUM7QUFBQSxFQUFBLGlCQUFBQztBQUFBLEVBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLGNBQUFDO0FBQUEsRUFBQTtBQUFBO0FBQUE7QUFBQSxjQUFBQztBQUFBLEVBQUEsV0FBQUM7QUFBQTs7O0FDQUEsSUFBQUMsZ0JBQUE7QUFBQSxTQUFBQSxlQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLGdCQUFBQztBQUFBLEVBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLGVBQUFDO0FBQUEsRUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtB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Q3JEOUMsU0FBUyxRQUFRRyxRQUFPLFFBQVE7QUFDbkMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBTGdCO0FBTVQsU0FBUyxlQUFlQSxRQUFPLFFBQVE7QUFDMUMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBTmdCO0FBT1QsU0FBUyxPQUFPQSxRQUFPLFFBQVE7QUFDbEMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBUyxNQUFNQSxRQUFPLFFBQVE7QUFDakMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBUyxNQUFNQSxRQUFPLFFBQVE7QUFDakMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBUyxRQUFRQSxRQUFPLFFBQVE7QUFDbkMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxTQUFTO0FBQUEsSUFDVCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBVGdCO0FBVVQsU0FBUyxRQUFRQSxRQUFPLFFBQVE7QUFDbkMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxTQUFTO0FBQUEsSUFDVCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBVGdCO0FBVVQsU0FBUyxRQUFRQSxRQUFPLFFBQVE7QUFDbkMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxTQUFTO0FBQUEsSUFDVCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBVGdCO0FBVVQsU0FBUyxLQUFLQSxRQUFPLFFBQVE7QUFDaEMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBU0MsUUFBT0QsUUFBTyxRQUFRO0FBQ2xDLFNBQU8sSUFBSUEsT0FBTTtBQUFBLElBQ2IsTUFBTTtBQUFBLElBQ04sUUFBUTtBQUFBLElBQ1IsT0FBTztBQUFBLElBQ1AsT0FBTztBQUFBLElBQ1AsR0FBUSxnQkFBZ0IsTUFBTTtBQUFBLEVBQ2xDLENBQUM7QUFDTDtBQVJnQixPQUFBQyxTQUFBO0FBU1QsU0FBUyxRQUFRRCxRQUFPLFFBQVE7QUFDbkMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBUyxNQUFNQSxRQUFPLFFBQVE7QUFDakMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBUyxPQUFPQSxRQUFPLFFBQVE7QUFDbEMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBUyxNQUFNQSxRQUFPLFFBQVE7QUFDakMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBUyxLQUFLQSxRQUFPLFFBQVE7QUFDaEMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBUyxPQUFPQSxRQUFPLFFBQVE7QUFDbEMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBUyxNQUFNQSxRQUFPLFFBQVE7QUFDakMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBUyxNQUFNQSxRQUFPLFFBQVE7QUFDakMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBUyxRQUFRQSxRQUFPLFFBQVE7QUFDbkMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBUyxRQUFRQSxRQUFPLFFBQVE7QUFDbkMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBUyxRQUFRQSxRQUFPLFFBQVE7QUFDbkMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBUyxXQUFXQSxRQUFPLFFBQVE7QUFDdEMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBUyxNQUFNQSxRQUFPLFFBQVE7QUFDakMsU0FBTyxJQUFJQSxPQUFNO0FBQUEs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QU0sQ0FBQztBQUM1RCxPQUFLLE9BQU8sQ0FBQyxXQUFTLEtBQUssTUFBVyxNQUFNLFNBQVMsTUFBTSxDQUFDO0FBQzVELE9BQUssUUFBUSxDQUFDLFdBQVMsS0FBSyxNQUFXLE9BQU8sVUFBVSxNQUFNLENBQUM7QUFDL0QsT0FBSyxPQUFPLENBQUMsV0FBUyxLQUFLLE1BQVcsTUFBTSxTQUFTLE1BQU0sQ0FBQztBQUM1RCxPQUFLLFNBQVMsQ0FBQyxXQUFTLEtBQUssTUFBVyxRQUFRLFdBQVcsTUFBTSxDQUFDO0FBQ2xFLE9BQUssWUFBWSxDQUFDLFdBQVMsS0FBSyxNQUFXLFdBQVcsY0FBYyxNQUFNLENBQUM7QUFDM0UsT0FBSyxNQUFNLENBQUMsV0FBUyxLQUFLLE1BQVcsS0FBSyxRQUFRLE1BQU0sQ0FBQztBQUN6RCxPQUFLLFFBQVEsQ0FBQyxXQUFTLEtBQUssTUFBVyxPQUFPLFVBQVUsTUFBTSxDQUFDO0FBQy9ELE9BQUssT0FBTyxDQUFDLFdBQVMsS0FBSyxNQUFXLE1BQU0sU0FBUyxNQUFNLENBQUM7QUFDNUQsT0FBSyxPQUFPLENBQUMsV0FBUyxLQUFLLE1BQVcsTUFBTSxTQUFTLE1BQU0sQ0FBQztBQUM1RCxPQUFLLFNBQVMsQ0FBQyxXQUFTLEtBQUssTUFBVyxRQUFRLFdBQVcsTUFBTSxDQUFDO0FBQ2xFLE9BQUssU0FBUyxDQUFDLFdBQVMsS0FBSyxNQUFXLFFBQVEsV0FBVyxNQUFNLENBQUM7QUFDbEUsT0FBSyxPQUFPLENBQUMsV0FBUyxLQUFLLE1BQVcsTUFBTSxTQUFTLE1BQU0sQ0FBQztBQUU1RCxPQUFLLFdBQVcsQ0FBQyxXQUFTLEtBQUssTUFBVUMsVUFBUyxNQUFNLENBQUM7QUFDekQsT0FBSyxPQUFPLENBQUMsV0FBUyxLQUFLLE1BQVVDLE1BQUssTUFBTSxDQUFDO0FBQ2pELE9BQUssT0FBTyxDQUFDLFdBQVMsS0FBSyxNQUFVQyxNQUFLLE1BQU0sQ0FBQztBQUNqRCxPQUFLLFdBQVcsQ0FBQyxXQUFTLEtBQUssTUFBVUMsVUFBUyxNQUFNLENBQUM7QUFDN0QsQ0FBQztB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QUM1RDtBQUFBLEVBQ0EsSUFBSSxRQUFRO0FBQ1IsV0FBTyxDQUFDLENBQUMsS0FBSyxLQUFLLE9BQU8sS0FBSyxDQUFDLE9BQUssR0FBRyxTQUFTLEtBQUs7QUFBQSxFQUMxRDtBQUFBLEVBQ0EsSUFBSSxVQUFVO0FBQ1YsV0FBTyxDQUFDLENBQUMsS0FBSyxLQUFLLE9BQU8sS0FBSyxDQUFDLE9BQUssR0FBRyxTQUFTLE9BQU87QUFBQSxFQUM1RDtBQUFBLEVBQ0EsSUFBSSxTQUFTO0FBQ1QsV0FBTyxDQUFDLENBQUMsS0FBSyxLQUFLLE9BQU8sS0FBSyxDQUFDLE9BQUssR0FBRyxTQUFTLE1BQU07QUFBQSxFQUMzRDtBQUFBLEVBQ0EsSUFBSSxXQUFXO0FBQ1gsV0FBTyxDQUFDLENBQUMsS0FBSyxLQUFLLE9BQU8sS0FBSyxDQUFDLE9BQUssR0FBRyxTQUFTLFFBQVE7QUFBQSxFQUM3RDtBQUFBLEVBQ0EsSUFBSSxTQUFTO0FBQ1QsV0FBTyxDQUFDLENBQUMsS0FBSyxLQUFLLE9BQU8sS0FBSyxDQUFDLE9BQUssR0FBRyxTQUFTLE1BQU07QUFBQSxFQUMzRDtBQUFBLEVBQ0EsSUFBSSxVQUFVO0FBQ1YsV0FBTyxDQUFDLENBQUMsS0FBSyxLQUFLLE9BQU8sS0FBSyxDQUFDLE9BQUssR0FBRyxTQUFTLE9BQU87QUFBQSxFQUM1RDtBQUFBLEVBQ0EsSUFBSSxTQUFTO0FBQ1QsV0FBTyxDQUFDLENBQUMsS0FBSyxLQUFLLE9BQU8sS0FBSyxDQUFDLE9BQUssR0FBRyxTQUFTLE1BQU07QUFBQSxFQUMzRDtBQUFBLEVBQ0EsSUFBSSxPQUFPO0FBQ1AsV0FBTyxDQUFDLENBQUMsS0FBSyxLQUFLLE9BQU8sS0FBSyxDQUFDLE9BQUssR0FBRyxTQUFTLElBQUk7QUFBQSxFQUN6RDtBQUFBLEVBQ0EsSUFBSSxTQUFTO0FBQ1QsV0FBTyxDQUFDLENBQUMsS0FBSyxLQUFLLE9BQU8sS0FBSyxDQUFDLE9BQUssR0FBRyxTQUFTLE1BQU07QUFBQSxFQUMzRDtBQUFBLEVBQ0EsSUFBSSxXQUFXO0FBQ1gsV0FBTyxD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SSxLQUFLLFlBQVksSUFBSSxDQUFDO0FBRXRILE9BQU8sT0FBTyxjQUFhLEVBQUUsSUFBSSxVQUFRLE1BQU0sY0FBYyxXQUFXLG9CQUFvQixJQUFJLEtBQUssWUFBWSxJQUFJLENBQUM7QUFFdEgsT0FBTyxPQUFPLGFBQWEsRUFBRSxJQUFJLFVBQVEsTUFBTSxjQUFjLFdBQVcsb0JBQW9CLElBQUksS0FBSyxZQUFZLElBQUksQ0FBQztBQUV0SCxPQUFPLE9BQU8sVUFBYSxFQUFFLElBQUksVUFBUSxNQUFNLGNBQWMsV0FBVyxvQkFBb0IsSUFBSSxLQUFLLFlBQVksSUFBSSxDQUFDO0FBRXRILE9BQU8sT0FBTyxlQUFhLEVBQUUsSUFBSSxVQUFRLE1BQU0sY0FBYyxXQUFXLG9CQUFvQixJQUFJLEtBQUssWUFBWSxJQUFJLENBQUM7QUFFdEgsT0FBTyxPQUFPLFlBQWEsRUFBRSxJQUFJLFVBQVEsTUFBTSxjQUFjLFdBQVcsb0JBQW9CLElBQUksS0FBSyxZQUFZLElBQUksQ0FBQzsiLAogICJuYW1lcyI6IFsibW9kdWxlIiwgInBhcnNlIiwgIm1zIiwgIm5hbWUiLCAibW9kdWxlIiwgImFycmF5IiwgIm9iamVjdCIsICJpc09iamVjdCIsICJjaHVuayIsICJtb2R1bGUiLCAiX19kZWZQcm9wIiwgIl9fZ2V0T3duUHJvcERlc2MiLCAiX19nZXRPd25Qcm9wTmFtZXMiLCAiX19oYXNPd25Qcm9wIiwgIl9fZXhwb3J0IiwgIm5hbWUiLCAiX19jb3B5UHJvcHMiLCAiZ2V0Q29udGV4dCIsICJtb2R1bGUiLCAiX19kZWZQcm9wIiwgIl9fZ2V0T3duUHJvcERlc2MiLCAiX19nZXRPd25Qcm9wTmFtZXMiLCAiX19oYXNPd25Qcm9wIiwgIl9fZXhwb3J0IiwgIm5hbWUiLCAiX19jb3B5UHJvcHMiLCAiZ2V0VmVyY2VsT2lkY1Rva2VuIiwgIl9hIiwgIl9iIiwgIkRpYWdMb2dMZXZlbCIsICJfYSIsICJfYiIsICJWYWx1ZVR5cGUiLCAiVHJhY2VGbGFncyIsICJfYSIsICJuYW1lIiwgIm5hbWUiLCAidmVyc2lvbiIsICJuYW1lIiwgInZlcnNpb24iLCAiX2EiLCAiU2FtcGxpbmdEZWNpc2lvbiIsICJTcGFuS2luZCIsICJTcGFuU3RhdHVzQ29kZSIsICJuYW1lIiwgInZlcnNpb24iLCAic3VjY2VzcyIsICJuYW1lIiwgInZlcnNpb24iLCAibmFtZSIsICJmZXRjaCIsICJkZWxheSIsICJ0ZXh0IiwgImZldGNoIiwgImVycm9yIiwgIm1zIiwgImFkZCIsICJlcnJvciIsICJhZGQiLCAiYWRkVGVuV29ya2Zsb3ciLCAiYWRkVGVuV29ya2Zsb3ciLCAiYWRkIiwgImNodW5rIiwgImFkZCIsICJ0ZXh0IiwgIl9BSVNES0Vycm9yIiwgIm5hbWUxNCIsICJuYW1lIiwgImVycm9yIiwgIm1hcmtlcjE1IiwgIm1hcmtlciIsICJzeW1ib2wiLCAiX2EiLCAidXJsIiwgInN5bWJvbCIsICJuYW1lIiwgIl9hIiwgInRleHQiLCAiZXJyb3IiLCAibWFya2VyIiwgIm5hbWUiLCAic3ltYm9sIiwgIl9hIiwgInN5bWJvbCIsICJzeW1ib2wiLCAibmFtZSIsICJtYXJrZXIiLCAiZXJyb3IiLCAiX2EiLCAibmFtZSIsICJfVHlwZVZhbGlkYXRpb25FcnJvciIsICJfYSIsICJjaHVuayIsICJlcnJvciIsICJjaHVuayIsICJfZGVmYXVsdCIsICJiYXNlNjQiLCAiYmFzZTY0dXJsIiwgImJpZ2ludCIsICJib29sZWFuIiwgIl9jYXRjaCIsICJjaWRydjQiLCAiY2lkcnY2IiwgImNvcmVfZXhwb3J0cyIsICJjdWlkIiwgImN1aWQyIiwgImRhdGUiLCAiZGVjb2RlIiwgImRlY29kZUFzeW5jIiwgImUxNjQiLCAiZW1haWwiLCAiZW1vamkiLCAiZW5jb2RlIiwgImVuY29kZUFzeW5jIiwgIl9lbnVtIiwgImd1aWQiLCAiaGV4IiwgImhvc3RuYW1lIiwgImlwdjQiLCAiaXB2NiIsICJrc3VpZCIsICJuYW5vaWQiLCAiX251bGwiLCAibnVsbGlzaCIsICJudW1iZXIiLCAicGFyc2UiLCAicGFyc2VBc3luYyIsICJzYWZlRGVjb2RlIiwgInNhZmVEZWNvZGVBc3luYyIsICJzYWZlRW5jb2RlIiwgInNhZmVFbmNvZGVBc3luYyIsICJzYWZlUGFyc2UiLCAic2FmZVBhcnNlQXN5bmMiLCAic3RyaW5nIiwgInN5bWJvbCIsICJ1bGlkIiwgIl91bmRlZmluZWQiLCAidXVpZCIsICJfdm9pZCIsICJ4aWQiLCAiY29yZV9leHBvcnRzIiwgIl9lbW9qaSIsICJfbnVsbCIsICJfdW5kZWZpbmVkIiwgIm5hbWUiLCAiaW5pdGlhbGl6ZXIiLCAiX2EiLCAiYXJyYXkiLCAic2V0IiwgIm9iamVjdCIsICJDbGFzcyIsICJfYSIsICJjb25maWciLCAiYmFzZTY0IiwgImJhc2U2NHVybCIsICJoZXgiLCAiZXJyb3IiLCAiaXNzdWUiLCAiX2EiLCAiX2IiLCAidmVyc2lvbiIsICJ0aW1lIiwgInRpbWVSZWdleCIsICJfYSIsICJpbnN0IiwgIl9iIiwgInJlc3VsdCIsICJfYSIsICJjaGVja3MiLCAiaXNBYm9ydGVkIiwgImNoZWNrUmVzdWx0IiwgImNhbmFyeSIsICJyZXN1bHQiLCAiXyIsICJ1cmwiLCAiaW5zdCIsICJiYXNlNjQiLCAiciIsICJpc09iamVjdCIsICJhbGxvd3NFdmFsIiwgInJlc3VsdHMiLCAibWFwIiwgImxlZnQiLCAicmlnaHQiLCAia2V5UmVzdWx0IiwgInZhbHVlUmVzdWx0IiwgIm91dHB1dCIsICJwYXJzZWRUeXBlIiwgImlzc3VlIiwgImVycm9yIiwgInBhcnNlZFR5cGUiLCAiaXNzdWUiLCAiZXJyb3IiLCAicGFyc2VkVHlwZSIsICJpc3N1ZSIsICJlcnJvciIsICJwYXJzZWRUeXBlIiwgImlzc3VlIiwgImVycm9yIiwgInBhcnNlZFR5cGUiLCAiaXNzdWUiLCAiZXJyb3IiLCAicGFyc2VkVHlwZSIsICJpc3N1ZSIsICJlcnJvciIsICJwYXJzZWRUeXBlIiwgImlzc3VlIiwgImVycm9yIiwgImlzc3VlIiwgInBhcnNlZFR5cGUiLCAiZXJyb3IiLCAiaXNzdWUiLCAiZXJyb3IiLCAicGFyc2VkVHlwZSIsICJpc3N1ZSIsICJlcnJvciIsICJwYXJzZWRUeXBlIiwgImlzc3VlIiwgImVycm9yIiwgInBhcnNlZFR5cGUiLCAiaXNzdWUiLCAiZXJyb3IiLCAicGFyc2VkVHlwZSIsICJpc3N1ZSIsICJlcnJvciIsICJwYXJzZWRUeXBlIiwgImlzc3VlIiwgImVycm9yIiwgInBhcnNlZFR5cGUiLCAiaXNzdWUiLCAiZXJyb3IiLCAicGFyc2VkVHlwZSIsICJpc3N1ZSIsICJlcnJvciIsICJwYXJzZWRUeXBlIiwgImlzc3VlIiwgInBhcnNlZFR5cGUiLCAiZXJyb3IiLCAiaXNzdWUiLCAiZXJyb3IiLCAicGFyc2VkVHlwZSIsICJpc3N1ZSIsICJlcnJvciIsICJwYXJzZWRUeXBlIiwgImlzc3VlIiwgInBhcnNlZFR5cGUiLCAiZXJyb3IiLCAiaXNzdWUiLCAiZXJyb3IiLCAicGFyc2VkVHlwZSIsICJpc3N1ZSIsICJlcnJvciIsICJwYXJzZWRUeXBlIiwgImlzc3VlIiwgInBhcnNlZFR5cGUiLCAidGV4dCIsICJudW1iZXIiLCAiZXJyb3IiLCAiaXNzdWUiLCAiZXJyb3IiLCAicGFyc2VkVHlwZSIsICJpc3N1ZSIsICJlcnJvciIsICJwYXJzZWRUeXBlIiwgImlzc3VlIiwgImVycm9yIiwgInBhcnNlZFR5cGUiLCAiaXNzdWUiLCAiZXJyb3IiLCAicGFyc2VkVHlwZSIsICJpc3N1ZSIsICJlcnJvciIsICJwYXJzZWRUeXBlIiwgImlzc3VlIiwgImVycm9yIiwgInBhcnNlZFR5cGUiLCAiaXNzdWUiLCAiZXJyb3IiLCAicGFyc2VkVHlwZSIsICJpc3N1ZSIsICJlcnJvciIsICJwYXJzZWRUeXBlIiwgImlzc3VlIiwgImVycm9yIiwgInBhcnNlZFR5cGUiLCAiaXNzdWUiLCAiZXJyb3IiLCAicGFyc2VkVHlwZSIsICJpc3N1ZSIsICJlcnJvciIsICJwYXJzZWRUeXBlIiwgImlzc3VlIiwgImVycm9yIiwgInBhcnNlZFR5cGUiLCAiaXNzdWUiLCAiZXJyb3IiLCAicGFyc2VkVHlwZSIsICJpc3N1ZSIsICJwYXJzZWRUeXBlIiwgImVycm9yIiwgImlzc3VlIiwgImVycm9yIiwgInBhcnNlZFR5cGUiLCAiaXNzdWUiLCAiZXJyb3IiLCAicGFyc2VkVHlwZSIsICJpc3N1ZSIsICJlcnJvciIsICJwYXJzZWRUeXBlIiwgImlzc3VlIiwgImVycm9yIiwgInBhcnNlZFR5cGUiLCAiaXNzdWUiLCAiZXJyb3IiLCAicGFyc2VkVHlwZSIsICJpc3N1ZSIsICJlcnJvciIsICJwYXJzZWRUeXBlIiwgImlzc3VlIiwgIkNsYXNzIiwgIl9lbW9qaSIsICJfdW5kZWZpbmVkIiwgIl9udWxsIiwgIkNsYXNzIiwgImlzc3VlIiwgImNvZGVjIiwgIl9hIiwgImpzb24iLCAiZmlsZSIsICJpZCIsICJzY2hlbWEiLCAiem9kU2NoZW1hIiwgInBhcmFtcyIsICJnZW4iLCAiZGF0ZSIsICJkYXRldGltZSIsICJkdXJhdGlvbiIsICJ0aW1lIiwgImRhdGV0aW1lIiwgImRhdGUiLCAidGltZSIsICJkdXJhdGlvbiIsICJpbml0aWFsaXplciIsICJpc3N1ZSIsICJpc3N1ZXMiLCAicGFyc2UiLCAicGFyc2VBc3luYyIsICJzYWZlUGFyc2UiLCAic2FmZVBhcnNlQXN5bmMiLCAiZW5jb2RlIiwgImRlY29kZSIsICJlbmNvZGVBc3luYyIsICJkZWNvZGVBc3luYyIsICJzYWZlRW5jb2RlIiwgInNhZmVEZWNvZGUiLCAic2FmZUVuY29kZUFzeW5jIiwgInNhZmVEZWNvZGVBc3luYyIsICJkZWYiLCAicGFyc2UiLCAic2FmZVBhcnNlIiwgInBhcnNlQXN5bmMiLCAic2FmZVBhcnNlQXN5bmMiLCAiZW5jb2RlIiwgImRlY29kZSIsICJlbmNvZGVBc3luYyIsICJkZWNvZGVBc3luYyIsICJzYWZlRW5jb2RlIiwgInNhZmVEZWNvZGUiLCAic2FmZUVuY29kZUFzeW5jIiwgInNhZmVEZWNvZGVBc3luYyIsICJjaGVjayIsICJfZGVmYXVsdCIsICJfY2F0Y2giLCAiX2Vtb2ppIiwgImRhdGV0aW1lIiwgImRhdGUiLCAidGltZSIsICJkdXJhdGlvbiIsICJzdHJpbmciLCAiZW1haWwiLCAiZ3VpZCIsICJ1dWlkIiwgImVtb2ppIiwgIm5hbm9pZCIsICJjdWlkIiwgImN1aWQyIiwgInVsaWQiLCAieGlkIiwgImtzdWlkIiwgImlwdjQiLCAiaXB2NiIsICJjaWRydjQiLCAiY2lkcnY2IiwgImJhc2U2NCIsICJiYXNlNjR1cmwiLCAiZTE2NCIsICJob3N0bmFtZSIsICJoZXgiLCAibnVtYmVyIiwgImJvb2xlYW4iLCAiYmlnaW50IiwgInN5bWJvbCIsICJfdW5kZWZpbmVkIiwgIl9udWxsIiwgIl92b2lkIiwgImRhdGUiLCAiX2VudW0iLCAiaXNzdWUiLCAib3V0cHV0IiwgIm51bGxpc2giLCAiX2RlZmF1bHQiLCAiX2NhdGNoIiwgImpzb25TY2hlbWEiLCAic3RyaW5nIiwgIm51bWJlciIsICJib29sZWFuIiwgIl9udWxsIiwgIm1hcCIsICJab2RGaXJzdFBhcnR5VHlwZUtpbmQiLCAiYmlnaW50IiwgImJvb2xlYW4iLCAiZGF0ZSIsICJudW1iZXIiLCAic3RyaW5nIiwgInN0cmluZyIsICJudW1iZXIiLCAiYm9vbGVhbiIsICJiaWdpbnQiLCAiZGF0ZSIsICJ1dGlsIiwgImFzc2VydElzIiwgImFzc2VydE5ldmVyIiwgIm9iamVjdCIsICJqb2luVmFsdWVzIiwgImFycmF5IiwgIm9iamVjdFV0aWwiLCAiZ2V0UGFyc2VkVHlwZSIsICJab2RJc3N1ZUNvZGUiLCAiWm9kRXJyb3IiLCAiaXNzdWUiLCAiZXJyb3IiLCAiaXNzdWUiLCAiWm9kSXNzdWVDb2RlIiwgImVuX2RlZmF1bHQiLCAiZW5fZGVmYXVsdCIsICJnZXRFcnJvck1hcCIsICJtYXAiLCAiZ2V0RXJyb3JNYXAiLCAiaXNzdWUiLCAiZW5fZGVmYXVsdCIsICJlcnJvclV0aWwiLCAiZXJyb3IiLCAiWm9kRXJyb3IiLCAiZXJyb3JNYXAiLCAiWm9kVHlwZSIsICJnZXRQYXJzZWRUeXBlIiwgImNoZWNrIiwgIlpvZElzc3VlQ29kZSIsICJab2RGaXJzdFBhcnR5VHlwZUtpbmQiLCAiWm9kT3B0aW9uYWwiLCAiWm9kTnVsbGFibGUiLCAiWm9kQXJyYXkiLCAiWm9kUHJvbWlzZSIsICJab2RVbmlvbiIsICJab2RJbnRlcnNlY3Rpb24iLCAidHJhbnNmb3JtIiwgIlpvZERlZmF1bHQiLCAiWm9kQ2F0Y2giLCAiWm9kUmVhZG9ubHkiLCAidmVyc2lvbiIsICJpc1ZhbGlkSldUIiwgImp3dCIsICJiYXNlNjQiLCAiWm9kU3RyaW5nIiwgIl9ab2RTdHJpbmciLCAicGFyc2VkVHlwZSIsICJjdHgiLCAiZmxvYXRTYWZlUmVtYWluZGVyIiwgIlpvZE51bWJlciIsICJab2RCaWdJbnQiLCAiWm9kQm9vbGVhbiIsICJab2REYXRlIiwgIlpvZFN5bWJvbCIsICJab2RVbmRlZmluZWQiLCAiWm9kTnVsbCIsICJab2RBbnkiLCAiWm9kVW5rbm93biIsICJab2ROZXZlciIsICJab2RWb2lkIiwgInJlc3VsdCIsICJab2RPYmplY3QiLCAiWm9kVHVwbGUiLCAiaXNzdWUiLCAiaXNzdWVzIiwgIlpvZExhenkiLCAiWm9kTGl0ZXJhbCIsICJab2RFbnVtIiwgIlpvZERpc2NyaW1pbmF0ZWRVbmlvbiIsICJtZXJnZVZhbHVlcyIsICJab2RSZWNvcmQiLCAiWm9kTWFwIiwgIlpvZFNldCIsICJlbGVtZW50cyIsICJab2RGdW5jdGlvbiIsICJnZXRFcnJvck1hcCIsICJlbl9kZWZhdWx0IiwgInByb2Nlc3NlZCIsICJwcmVwcm9jZXNzIiwgIlpvZE9wdGlvbmFsIiwgIlpvZFR5cGUiLCAicGFyc2VkVHlwZSIsICJab2RGaXJzdFBhcnR5VHlwZUtpbmQiLCAiWm9kTnVsbGFibGUiLCAiWm9kRGVmYXVsdCIsICJab2RDYXRjaCIsICJyZXN1bHQiLCAiWm9kRXJyb3IiLCAiWm9kTmFOIiwgIlpvZElzc3VlQ29kZSIsICJab2RSZWFkb25seSIsICJab2RPYmplY3QiLCAiWm9kRmlyc3RQYXJ0eVR5cGVLaW5kIiwgIlpvZFN0cmluZyIsICJab2ROdW1iZXIiLCAiWm9kTmFOIiwgIlpvZEJpZ0ludCIsICJab2RCb29sZWFuIiwgIlpvZERhdGUiLCAiWm9kU3ltYm9sIiwgIlpvZFVuZGVmaW5lZCIsICJab2ROdWxsIiwgIlpvZEFueSIsICJab2RVbmtub3duIiwgIlpvZE5ldmVyIiwgIlpvZFZvaWQiLCAiWm9kQXJyYXkiLCAiWm9kT2JqZWN0IiwgIlpvZFVuaW9uIiwgIlpvZERpc2NyaW1pbmF0ZWRVbmlvbiIsICJab2RJbnRlcnNlY3Rpb24iLCAiWm9kVHVwbGUiLCAiWm9kUmVjb3JkIiwgIlpvZE1hcCIsICJab2RTZXQiLCAiWm9kRnVuY3Rpb24iLCAiWm9kTGF6eSIsICJab2RMaXRlcmFsIiwgIlpvZEVudW0iLCAiWm9kUHJvbWlzZSIsICJab2RPcHRpb25hbCIsICJab2ROdWxsYWJsZSIsICJyZXNvbHZlIiwgImdldEVycm9yTWVzc2FnZSIsICJlcnJvciIsICJ1cmwiLCAiX2EiLCAiX2IiLCAicmVjb3JkIiwgImZldGNoIiwgInVybCIsICJtZWRpYVR5cGUiLCAiX3BhcnNlIiwgInRleHQiLCAiVHlwZVZhbGlkYXRpb25FcnJvciIsICJ2YWxpZGF0b3IiLCAiZXJyb3IiLCAidXJsIiwgImZldGNoIiwgInVybCIsICJmZXRjaCIsICJJbnZhbGlkQXJndW1lbnRFcnJvciIsICJlcnJvciIsICJBUElDYWxsRXJyb3IiLCAiZ2V0T3JpZ2luYWxGZXRjaCIsICJ1cmwiLCAiQVBJQ2FsbEVycm9yIiwgInRvb2wiLCAidXJsIiwgIl9hIiwgIl9iIiwgIlpvZEZpcnN0UGFydHlUeXBlS2luZCIsICJBUElDYWxsRXJyb3IiLCAiY2hlY2siLCAicGFyc2VkVHlwZSIsICJlbW9qaVJlZ2V4IiwgImxpdGVyYWwiLCAib2JqZWN0IiwgInJlcXVpcmVkIiwgIm5hbWUiLCAianNvblNjaGVtYSIsICJuYW1lMiIsICJfYTIiLCAic2NoZW1hIiwgInNhZmVQYXJzZUFzeW5jIiwgInpvZFNjaGVtYSIsICJidG9hIiwgImF0b2IiLCAiYXJyYXkiLCAidXJsIiwgInpvZFNjaGVtYSIsICJpbXBvcnRfb2lkYyIsICJtYXJrZXIiLCAieiIsICJfYSIsICJzeW1ib2wiLCAiZXJyb3IiLCAibmFtZSIsICJtYXJrZXIyIiwgInN5bWJvbDIiLCAiX2EyIiwgIm5hbWUyIiwgIm1hcmtlcjMiLCAic3ltYm9sMyIsICJfYTMiLCAibmFtZTMiLCAiX2IiLCAiX2E0IiwgInN5bWJvbDQiLCAic3ltYm9sNSIsICJtYXJrZXI1IiwgIl9hNSIsICJuYW1lNCIsICJuYW1lNSIsICJtYXJrZXI2IiwgInN5bWJvbDYiLCAiX2E2IiwgIm5hbWU2IiwgIm1hcmtlcjciLCAic3ltYm9sNyIsICJfYTciLCAibGF6eVZhbGlkYXRvciIsICJ6b2RTY2hlbWEiLCAiX2E4IiwgImNvbmZpZyIsICJyZXNvbHZlIiwgImNodW5rIiwgImNyZWF0ZUpzb25SZXNwb25zZUhhbmRsZXIiLCAiY3JlYXRlSnNvbkVycm9yUmVzcG9uc2VIYW5kbGVyIiwgImNvbWJpbmVIZWFkZXJzIiwgInBvc3RKc29uVG9BcGkiLCAiVkVSU0lPTiIsICJub3ciLCAiaW1wb3J0X2FwaSIsICJuYW1lIiwgIm1hcmtlciIsICJ0b29sIiwgInN5bWJvbCIsICJ6b2RTY2hlbWEiLCAiX2EiLCAiZXJyb3IiLCAibmFtZTIiLCAibWFya2VyMiIsICJzeW1ib2wyIiwgIl9hMiIsICJuYW1lMyIsICJtYXJrZXIzIiwgIl9hMyIsICJzeW1ib2wzIiwgIm5hbWU0IiwgIm1hcmtlcjQiLCAic3ltYm9sNCIsICJfYTQiLCAibWFya2VyIiwgInN5bWJvbCIsICJuYW1lIiwgIl9hIiwgImVycm9yIiwgIm5hbWU1IiwgIm1hcmtlcjUiLCAic3ltYm9sNSIsICJfYTUiLCAiX2E1IiwgInN5bWJvbDUiLCAibmFtZTYiLCAiX2EiLCAibWFya2VyNiIsICJzeW1ib2w2IiwgIl9hNiIsICJfYTYiLCAic3ltYm9sNiIsICJuYW1lNyIsICJtYXJrZXI3IiwgInN5bWJvbDciLCAiX2E3IiwgIkFJU0RLRXJyb3IiLCAic3ltYm9sIiwgIm5hbWUiLCAibWFya2VyIiwgImVycm9yIiwgIl9hIiwgIm5hbWU4IiwgIm1hcmtlcjgiLCAic3ltYm9sOCIsICJfYTgiLCAiX2E4IiwgInN5bWJvbDgiLCAibmFtZTkiLCAibWFya2VyOSIsICJzeW1ib2w5IiwgIl9hOSIsICJzeW1ib2wiLCAibmFtZSIsICJtYXJrZXIiLCAiX2EiLCAiZXJyb3IiLCAibmFtZTEwIiwgIm1hcmtlcjEwIiwgInN5bWJvbDEwIiwgIl9hMTAiLCAiQUlTREtFcnJvciIsICJuYW1lMTEiLCAibWFya2VyMTEiLCAic3ltYm9sMTEiLCAiX2ExMSIsICJfYTExIiwgInN5bWJvbDExIiwgIm5hbWUxMiIsICJtYXJrZXIxMiIsICJfYSIsICJzeW1ib2wxMiIsICJfYTEyIiwgIkFJU0RLRXJyb3IiLCAic3ltYm9sIiwgImVycm9yIiwgIm5hbWUxMyIsICJtYXJrZXIxMyIsICJzeW1ib2wxMyIsICJfYTEzIiwgInN5bWJvbDEzIiwgIm5hbWUxNCIsICJtYXJrZXIxNCIsICJBSVNES0Vycm9yIiwgInN5bWJvbDE0IiwgIl9hMTQiLCAiX2EiLCAic3ltYm9sIiwgIm5hbWUiLCAibWFya2VyIiwgInVybCIsICJlcnJvciIsICJuYW1lMTUiLCAibWFya2VyMTUiLCAiX2ExNSIsICJzeW1ib2wxNSIsICJfYSIsICJzeW1ib2wiLCAibWFya2VyIiwgIkFJU0RLRXJyb3IiLCAiVkVSU0lPTiIsICJ1cmwiLCAiX2EiLCAiZXJyb3IiLCAiX2IiLCAiZG93bmxvYWQiLCAiX2EiLCAiZmlsZSIsICJJbnZhbGlkQXJndW1lbnRFcnJvciIsICJvYmplY3QyIiwgIm9iamVjdCIsICJuYW1lIiwgInoiLCAieiIsICJ6IiwgInoiLCAiSW52YWxpZFByb21wdEVycm9yIiwgImVycm9yIiwgIl9hIiwgIm5hbWUiLCAiYXR0cmlidXRlcyIsICJtcyIsICJBUElDYWxsRXJyb3IiLCAiSW52YWxpZEFyZ3VtZW50RXJyb3IiLCAiZXJyb3IiLCAiY29udGVudCIsICJjb252ZXJ0VWludDhBcnJheVRvQmFzZTY0IiwgImFzU2NoZW1hIiwgIl9hIiwgImdldEVycm9yTWVzc2FnZSIsICJ0b29sIiwgIlZFUlNJT04iLCAiX2IiLCAiX2IyIiwgImRvd25sb2FkIiwgIndpdGhVc2VyQWdlbnRTdWZmaXgiLCAiY2FsbFNldHRpbmdzIiwgImVycm9yIiwgInRvb2xDYWxsIiwgImdldEVycm9yTWVzc2FnZSIsICJpc0Fib3J0RXJyb3IiLCAicmVzb2x2ZSIsICJ6IiwgInNhZmVQYXJzZUpTT04iLCAiX19leHBvcnQiLCAib2JqZWN0IiwgIl9hIiwgIm1hcmtlcjE2IiwgInN5bWJvbDE2IiwgIl9hMTYiLCAic3ltYm9sMTYiLCAiX2EiLCAiZmV0Y2giLCAid2l0aFVzZXJBZ2VudFN1ZmZpeCIsICJnZXRSdW50aW1lRW52aXJvbm1lbnRVc2VyQWdlbnQiLCAiX2EiLCAicGFyc2VKc29uRXZlbnRTdHJlYW0iLCAiZ2VuZXJhdGVJZCIsICJ0ZXh0IiwgInN0cmVhbXMiLCAiZW1haWwiXQp9Cg== +`; + + +async function normalizeRequestConverter(request) { + const options = { + method: request.method, + headers: new Headers(request.headers) + }; + if (!['GET', 'HEAD', 'OPTIONS', 'TRACE', 'CONNECT'].includes(request.method)) { + options.body = await request.arrayBuffer(); + } + return new Request(request.url, options); +} + +const POST = async ({request}) => { + const normalRequest = await normalizeRequestConverter(request); + return workflowEntrypoint(workflowCode)(normalRequest); +}; + +const prerender = false; + +const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ + __proto__: null, + POST, + prerender +}, Symbol.toStringTag, { value: 'Module' })); + +const page = () => _page; + +export { page }; diff --git a/workbench/astro/dist/server/pages/.well-known/workflow/v1/step.astro.mjs b/workbench/astro/dist/server/pages/.well-known/workflow/v1/step.astro.mjs new file mode 100644 index 000000000..415ac7fad --- /dev/null +++ b/workbench/astro/dist/server/pages/.well-known/workflow/v1/step.astro.mjs @@ -0,0 +1,7609 @@ +import { g as getWorkflowRunStreamId, a as getSerializeStream, b as getExternalReducers, W as WorkflowServerWritableStream, r as registerStepFunction } from '../../../../chunks/index_ePTMDSOu.mjs'; +import ms from 'ms'; +import { c as contextStorage, s as stepEntrypoint } from '../../../../chunks/runtime_CxdH0OC2.mjs'; +export { renderers } from '../../../../renderers.mjs'; + +/** + * Returns metadata available in the current step function. + * It uses `AsyncLocalStorage` to store the context and + * retrieve it in the step function. + */ +function getStepMetadata() { + const ctx = contextStorage.getStore(); + if (!ctx) { + throw new Error('`getStepMetadata()` can only be called inside a step function'); + } + return ctx.stepMetadata; +} + +/** + * Returns metadata available in the current workflow run inside a step function. + */ +function getWorkflowMetadata() { + const ctx = contextStorage.getStore(); + if (!ctx) { + throw new Error('`getWorkflowMetadata()` can only be called inside a workflow or step function'); + } + return ctx.workflowMetadata; +} + +/** + * Retrieves a writable stream that is associated with the current workflow. + * + * The writable stream is intended to be used within step functions to write + * data that can be read outside the workflow by using the readable method of getRun. + * + * @param options - Optional configuration for the writable stream + * @returns The writable stream associated with the current workflow run + * @throws Error if called outside a workflow or step function + */ +function getWritable(options = {}) { + const ctx = contextStorage.getStore(); + if (!ctx) { + throw new Error('`getWritable()` can only be called inside a workflow or step function'); + } + const { namespace } = options; + const name = getWorkflowRunStreamId(ctx.workflowMetadata.workflowRunId, namespace); + // Create a transform stream that serializes chunks and pipes to the workflow server + const serialize = getSerializeStream(getExternalReducers(globalThis, ctx.ops)); + // Pipe the serialized data to the workflow server stream + // Register this async operation with the runtime's ops array so it's awaited via waitUntil + ctx.ops.push(serialize.readable.pipeTo(new WorkflowServerWritableStream(name))); + // Return the writable side of the transform stream + return serialize.writable; +} + +function __classPrivateFieldSet(receiver, state, value, kind, f) { + if (typeof state === "function" ? receiver !== state || true : !state.has(receiver)) + throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return state.set(receiver, value), value; +} +function __classPrivateFieldGet(receiver, state, kind, f) { + if (kind === "a" && !f) + throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) + throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +/** + * https://stackoverflow.com/a/2117523 + */ +let uuid4 = function () { + const { crypto } = globalThis; + if (crypto?.randomUUID) { + uuid4 = crypto.randomUUID.bind(crypto); + return crypto.randomUUID(); + } + const u8 = new Uint8Array(1); + const randomByte = crypto ? () => crypto.getRandomValues(u8)[0] : () => (Math.random() * 0xff) & 0xff; + return '10000000-1000-4000-8000-100000000000'.replace(/[018]/g, (c) => (+c ^ (randomByte() & (15 >> (+c / 4)))).toString(16)); +}; + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +function isAbortError(err) { + return (typeof err === 'object' && + err !== null && + // Spec-compliant fetch implementations + (('name' in err && err.name === 'AbortError') || + // Expo fetch + ('message' in err && String(err.message).includes('FetchRequestCanceledException')))); +} +const castToError = (err) => { + if (err instanceof Error) + return err; + if (typeof err === 'object' && err !== null) { + try { + if (Object.prototype.toString.call(err) === '[object Error]') { + // @ts-ignore - not all envs have native support for cause yet + const error = new Error(err.message, err.cause ? { cause: err.cause } : {}); + if (err.stack) + error.stack = err.stack; + // @ts-ignore - not all envs have native support for cause yet + if (err.cause && !error.cause) + error.cause = err.cause; + if (err.name) + error.name = err.name; + return error; + } + } + catch { } + try { + return new Error(JSON.stringify(err)); + } + catch { } + } + return new Error(err); +}; + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class OpenAIError extends Error { +} +class APIError extends OpenAIError { + constructor(status, error, message, headers) { + super(`${APIError.makeMessage(status, error, message)}`); + this.status = status; + this.headers = headers; + this.requestID = headers?.get('x-request-id'); + this.error = error; + const data = error; + this.code = data?.['code']; + this.param = data?.['param']; + this.type = data?.['type']; + } + static makeMessage(status, error, message) { + const msg = error?.message ? + typeof error.message === 'string' ? + error.message + : JSON.stringify(error.message) + : error ? JSON.stringify(error) + : message; + if (status && msg) { + return `${status} ${msg}`; + } + if (status) { + return `${status} status code (no body)`; + } + if (msg) { + return msg; + } + return '(no status code or body)'; + } + static generate(status, errorResponse, message, headers) { + if (!status || !headers) { + return new APIConnectionError({ message, cause: castToError(errorResponse) }); + } + const error = errorResponse?.['error']; + if (status === 400) { + return new BadRequestError(status, error, message, headers); + } + if (status === 401) { + return new AuthenticationError(status, error, message, headers); + } + if (status === 403) { + return new PermissionDeniedError(status, error, message, headers); + } + if (status === 404) { + return new NotFoundError(status, error, message, headers); + } + if (status === 409) { + return new ConflictError(status, error, message, headers); + } + if (status === 422) { + return new UnprocessableEntityError(status, error, message, headers); + } + if (status === 429) { + return new RateLimitError(status, error, message, headers); + } + if (status >= 500) { + return new InternalServerError(status, error, message, headers); + } + return new APIError(status, error, message, headers); + } +} +class APIUserAbortError extends APIError { + constructor({ message } = {}) { + super(undefined, undefined, message || 'Request was aborted.', undefined); + } +} +class APIConnectionError extends APIError { + constructor({ message, cause }) { + super(undefined, undefined, message || 'Connection error.', undefined); + // in some environments the 'cause' property is already declared + // @ts-ignore + if (cause) + this.cause = cause; + } +} +class APIConnectionTimeoutError extends APIConnectionError { + constructor({ message } = {}) { + super({ message: message ?? 'Request timed out.' }); + } +} +class BadRequestError extends APIError { +} +class AuthenticationError extends APIError { +} +class PermissionDeniedError extends APIError { +} +class NotFoundError extends APIError { +} +class ConflictError extends APIError { +} +class UnprocessableEntityError extends APIError { +} +class RateLimitError extends APIError { +} +class InternalServerError extends APIError { +} +class LengthFinishReasonError extends OpenAIError { + constructor() { + super(`Could not parse response content as the length limit was reached`); + } +} +class ContentFilterFinishReasonError extends OpenAIError { + constructor() { + super(`Could not parse response content as the request was rejected by the content filter`); + } +} +class InvalidWebhookSignatureError extends Error { + constructor(message) { + super(message); + } +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +// https://url.spec.whatwg.org/#url-scheme-string +const startsWithSchemeRegexp = /^[a-z][a-z0-9+.-]*:/i; +const isAbsoluteURL = (url) => { + return startsWithSchemeRegexp.test(url); +}; +let isArray = (val) => ((isArray = Array.isArray), isArray(val)); +let isReadonlyArray = isArray; +/** Returns an object if the given value isn't an object, otherwise returns as-is */ +function maybeObj(x) { + if (typeof x !== 'object') { + return {}; + } + return x ?? {}; +} +// https://stackoverflow.com/a/34491287 +function isEmptyObj(obj) { + if (!obj) + return true; + for (const _k in obj) + return false; + return true; +} +// https://eslint.org/docs/latest/rules/no-prototype-builtins +function hasOwn(obj, key) { + return Object.prototype.hasOwnProperty.call(obj, key); +} +function isObj(obj) { + return obj != null && typeof obj === 'object' && !Array.isArray(obj); +} +const validatePositiveInteger = (name, n) => { + if (typeof n !== 'number' || !Number.isInteger(n)) { + throw new OpenAIError(`${name} must be an integer`); + } + if (n < 0) { + throw new OpenAIError(`${name} must be a positive integer`); + } + return n; +}; +const safeJSON = (text) => { + try { + return JSON.parse(text); + } + catch (err) { + return undefined; + } +}; + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); + +const VERSION = '6.1.0'; // x-release-please-version + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +const isRunningInBrowser = () => { + return ( + // @ts-ignore + typeof window !== 'undefined' && + // @ts-ignore + typeof window.document !== 'undefined' && + // @ts-ignore + typeof navigator !== 'undefined'); +}; +/** + * Note this does not detect 'browser'; for that, use getBrowserInfo(). + */ +function getDetectedPlatform() { + if (typeof Deno !== 'undefined' && Deno.build != null) { + return 'deno'; + } + if (typeof EdgeRuntime !== 'undefined') { + return 'edge'; + } + if (Object.prototype.toString.call(typeof globalThis.process !== 'undefined' ? globalThis.process : 0) === '[object process]') { + return 'node'; + } + return 'unknown'; +} +const getPlatformProperties = () => { + const detectedPlatform = getDetectedPlatform(); + if (detectedPlatform === 'deno') { + return { + 'X-Stainless-Lang': 'js', + 'X-Stainless-Package-Version': VERSION, + 'X-Stainless-OS': normalizePlatform(Deno.build.os), + 'X-Stainless-Arch': normalizeArch(Deno.build.arch), + 'X-Stainless-Runtime': 'deno', + 'X-Stainless-Runtime-Version': typeof Deno.version === 'string' ? Deno.version : Deno.version?.deno ?? 'unknown', + }; + } + if (typeof EdgeRuntime !== 'undefined') { + return { + 'X-Stainless-Lang': 'js', + 'X-Stainless-Package-Version': VERSION, + 'X-Stainless-OS': 'Unknown', + 'X-Stainless-Arch': `other:${EdgeRuntime}`, + 'X-Stainless-Runtime': 'edge', + 'X-Stainless-Runtime-Version': globalThis.process.version, + }; + } + // Check if Node.js + if (detectedPlatform === 'node') { + return { + 'X-Stainless-Lang': 'js', + 'X-Stainless-Package-Version': VERSION, + 'X-Stainless-OS': normalizePlatform(globalThis.process.platform ?? 'unknown'), + 'X-Stainless-Arch': normalizeArch(globalThis.process.arch ?? 'unknown'), + 'X-Stainless-Runtime': 'node', + 'X-Stainless-Runtime-Version': globalThis.process.version ?? 'unknown', + }; + } + const browserInfo = getBrowserInfo(); + if (browserInfo) { + return { + 'X-Stainless-Lang': 'js', + 'X-Stainless-Package-Version': VERSION, + 'X-Stainless-OS': 'Unknown', + 'X-Stainless-Arch': 'unknown', + 'X-Stainless-Runtime': `browser:${browserInfo.browser}`, + 'X-Stainless-Runtime-Version': browserInfo.version, + }; + } + // TODO add support for Cloudflare workers, etc. + return { + 'X-Stainless-Lang': 'js', + 'X-Stainless-Package-Version': VERSION, + 'X-Stainless-OS': 'Unknown', + 'X-Stainless-Arch': 'unknown', + 'X-Stainless-Runtime': 'unknown', + 'X-Stainless-Runtime-Version': 'unknown', + }; +}; +// Note: modified from https://github.com/JS-DevTools/host-environment/blob/b1ab79ecde37db5d6e163c050e54fe7d287d7c92/src/isomorphic.browser.ts +function getBrowserInfo() { + if (typeof navigator === 'undefined' || !navigator) { + return null; + } + // NOTE: The order matters here! + const browserPatterns = [ + { key: 'edge', pattern: /Edge(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ }, + { key: 'ie', pattern: /MSIE(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ }, + { key: 'ie', pattern: /Trident(?:.*rv\:(\d+)\.(\d+)(?:\.(\d+))?)?/ }, + { key: 'chrome', pattern: /Chrome(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ }, + { key: 'firefox', pattern: /Firefox(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ }, + { key: 'safari', pattern: /(?:Version\W+(\d+)\.(\d+)(?:\.(\d+))?)?(?:\W+Mobile\S*)?\W+Safari/ }, + ]; + // Find the FIRST matching browser + for (const { key, pattern } of browserPatterns) { + const match = pattern.exec(navigator.userAgent); + if (match) { + const major = match[1] || 0; + const minor = match[2] || 0; + const patch = match[3] || 0; + return { browser: key, version: `${major}.${minor}.${patch}` }; + } + } + return null; +} +const normalizeArch = (arch) => { + // Node docs: + // - https://nodejs.org/api/process.html#processarch + // Deno docs: + // - https://doc.deno.land/deno/stable/~/Deno.build + if (arch === 'x32') + return 'x32'; + if (arch === 'x86_64' || arch === 'x64') + return 'x64'; + if (arch === 'arm') + return 'arm'; + if (arch === 'aarch64' || arch === 'arm64') + return 'arm64'; + if (arch) + return `other:${arch}`; + return 'unknown'; +}; +const normalizePlatform = (platform) => { + // Node platforms: + // - https://nodejs.org/api/process.html#processplatform + // Deno platforms: + // - https://doc.deno.land/deno/stable/~/Deno.build + // - https://github.com/denoland/deno/issues/14799 + platform = platform.toLowerCase(); + // NOTE: this iOS check is untested and may not work + // Node does not work natively on IOS, there is a fork at + // https://github.com/nodejs-mobile/nodejs-mobile + // however it is unknown at the time of writing how to detect if it is running + if (platform.includes('ios')) + return 'iOS'; + if (platform === 'android') + return 'Android'; + if (platform === 'darwin') + return 'MacOS'; + if (platform === 'win32') + return 'Windows'; + if (platform === 'freebsd') + return 'FreeBSD'; + if (platform === 'openbsd') + return 'OpenBSD'; + if (platform === 'linux') + return 'Linux'; + if (platform) + return `Other:${platform}`; + return 'Unknown'; +}; +let _platformHeaders; +const getPlatformHeaders = () => { + return (_platformHeaders ?? (_platformHeaders = getPlatformProperties())); +}; + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +function getDefaultFetch() { + if (typeof fetch !== 'undefined') { + return fetch; + } + throw new Error('`fetch` is not defined as a global; Either pass `fetch` to the client, `new OpenAI({ fetch })` or polyfill the global, `globalThis.fetch = fetch`'); +} +function makeReadableStream(...args) { + const ReadableStream = globalThis.ReadableStream; + if (typeof ReadableStream === 'undefined') { + // Note: All of the platforms / runtimes we officially support already define + // `ReadableStream` as a global, so this should only ever be hit on unsupported runtimes. + throw new Error('`ReadableStream` is not defined as a global; You will need to polyfill it, `globalThis.ReadableStream = ReadableStream`'); + } + return new ReadableStream(...args); +} +function ReadableStreamFrom(iterable) { + let iter = Symbol.asyncIterator in iterable ? iterable[Symbol.asyncIterator]() : iterable[Symbol.iterator](); + return makeReadableStream({ + start() { }, + async pull(controller) { + const { done, value } = await iter.next(); + if (done) { + controller.close(); + } + else { + controller.enqueue(value); + } + }, + async cancel() { + await iter.return?.(); + }, + }); +} +/** + * Most browsers don't yet have async iterable support for ReadableStream, + * and Node has a very different way of reading bytes from its "ReadableStream". + * + * This polyfill was pulled from https://github.com/MattiasBuelens/web-streams-polyfill/pull/122#issuecomment-1627354490 + */ +function ReadableStreamToAsyncIterable(stream) { + if (stream[Symbol.asyncIterator]) + return stream; + const reader = stream.getReader(); + return { + async next() { + try { + const result = await reader.read(); + if (result?.done) + reader.releaseLock(); // release lock when stream becomes closed + return result; + } + catch (e) { + reader.releaseLock(); // release lock when stream becomes errored + throw e; + } + }, + async return() { + const cancelPromise = reader.cancel(); + reader.releaseLock(); + await cancelPromise; + return { done: true, value: undefined }; + }, + [Symbol.asyncIterator]() { + return this; + }, + }; +} +/** + * Cancels a ReadableStream we don't need to consume. + * See https://undici.nodejs.org/#/?id=garbage-collection + */ +async function CancelReadableStream(stream) { + if (stream === null || typeof stream !== 'object') + return; + if (stream[Symbol.asyncIterator]) { + await stream[Symbol.asyncIterator]().return?.(); + return; + } + const reader = stream.getReader(); + const cancelPromise = reader.cancel(); + reader.releaseLock(); + await cancelPromise; +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +const FallbackEncoder = ({ headers, body }) => { + return { + bodyHeaders: { + 'content-type': 'application/json', + }, + body: JSON.stringify(body), + }; +}; + +const default_format = 'RFC3986'; +const default_formatter = (v) => String(v); +const formatters = { + RFC1738: (v) => String(v).replace(/%20/g, '+'), + RFC3986: default_formatter, +}; +const RFC1738 = 'RFC1738'; + +let has = (obj, key) => ((has = Object.hasOwn ?? Function.prototype.call.bind(Object.prototype.hasOwnProperty)), + has(obj, key)); +const hex_table = /* @__PURE__ */ (() => { + const array = []; + for (let i = 0; i < 256; ++i) { + array.push('%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase()); + } + return array; +})(); +const limit = 1024; +const encode = (str, _defaultEncoder, charset, _kind, format) => { + // This code was originally written by Brian White for the io.js core querystring library. + // It has been adapted here for stricter adherence to RFC 3986 + if (str.length === 0) { + return str; + } + let string = str; + if (typeof str === 'symbol') { + string = Symbol.prototype.toString.call(str); + } + else if (typeof str !== 'string') { + string = String(str); + } + if (charset === 'iso-8859-1') { + return escape(string).replace(/%u[0-9a-f]{4}/gi, function ($0) { + return '%26%23' + parseInt($0.slice(2), 16) + '%3B'; + }); + } + let out = ''; + for (let j = 0; j < string.length; j += limit) { + const segment = string.length >= limit ? string.slice(j, j + limit) : string; + const arr = []; + for (let i = 0; i < segment.length; ++i) { + let c = segment.charCodeAt(i); + if (c === 0x2d || // - + c === 0x2e || // . + c === 0x5f || // _ + c === 0x7e || // ~ + (c >= 0x30 && c <= 0x39) || // 0-9 + (c >= 0x41 && c <= 0x5a) || // a-z + (c >= 0x61 && c <= 0x7a) || // A-Z + (format === RFC1738 && (c === 0x28 || c === 0x29)) // ( ) + ) { + arr[arr.length] = segment.charAt(i); + continue; + } + if (c < 0x80) { + arr[arr.length] = hex_table[c]; + continue; + } + if (c < 0x800) { + arr[arr.length] = hex_table[0xc0 | (c >> 6)] + hex_table[0x80 | (c & 0x3f)]; + continue; + } + if (c < 0xd800 || c >= 0xe000) { + arr[arr.length] = + hex_table[0xe0 | (c >> 12)] + hex_table[0x80 | ((c >> 6) & 0x3f)] + hex_table[0x80 | (c & 0x3f)]; + continue; + } + i += 1; + c = 0x10000 + (((c & 0x3ff) << 10) | (segment.charCodeAt(i) & 0x3ff)); + arr[arr.length] = + hex_table[0xf0 | (c >> 18)] + + hex_table[0x80 | ((c >> 12) & 0x3f)] + + hex_table[0x80 | ((c >> 6) & 0x3f)] + + hex_table[0x80 | (c & 0x3f)]; + } + out += arr.join(''); + } + return out; +}; +function is_buffer(obj) { + if (!obj || typeof obj !== 'object') { + return false; + } + return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj)); +} +function maybe_map(val, fn) { + if (isArray(val)) { + const mapped = []; + for (let i = 0; i < val.length; i += 1) { + mapped.push(fn(val[i])); + } + return mapped; + } + return fn(val); +} + +const array_prefix_generators = { + brackets(prefix) { + return String(prefix) + '[]'; + }, + comma: 'comma', + indices(prefix, key) { + return String(prefix) + '[' + key + ']'; + }, + repeat(prefix) { + return String(prefix); + }, +}; +const push_to_array = function (arr, value_or_array) { + Array.prototype.push.apply(arr, isArray(value_or_array) ? value_or_array : [value_or_array]); +}; +let toISOString; +const defaults = { + addQueryPrefix: false, + allowDots: false, + allowEmptyArrays: false, + arrayFormat: 'indices', + charset: 'utf-8', + charsetSentinel: false, + delimiter: '&', + encode: true, + encodeDotInKeys: false, + encoder: encode, + encodeValuesOnly: false, + format: default_format, + formatter: default_formatter, + /** @deprecated */ + indices: false, + serializeDate(date) { + return (toISOString ?? (toISOString = Function.prototype.call.bind(Date.prototype.toISOString)))(date); + }, + skipNulls: false, + strictNullHandling: false, +}; +function is_non_nullish_primitive(v) { + return (typeof v === 'string' || + typeof v === 'number' || + typeof v === 'boolean' || + typeof v === 'symbol' || + typeof v === 'bigint'); +} +const sentinel = {}; +function inner_stringify(object, prefix, generateArrayPrefix, commaRoundTrip, allowEmptyArrays, strictNullHandling, skipNulls, encodeDotInKeys, encoder, filter, sort, allowDots, serializeDate, format, formatter, encodeValuesOnly, charset, sideChannel) { + let obj = object; + let tmp_sc = sideChannel; + let step = 0; + let find_flag = false; + while ((tmp_sc = tmp_sc.get(sentinel)) !== void undefined && !find_flag) { + // Where object last appeared in the ref tree + const pos = tmp_sc.get(object); + step += 1; + if (typeof pos !== 'undefined') { + if (pos === step) { + throw new RangeError('Cyclic object value'); + } + else { + find_flag = true; // Break while + } + } + if (typeof tmp_sc.get(sentinel) === 'undefined') { + step = 0; + } + } + if (typeof filter === 'function') { + obj = filter(prefix, obj); + } + else if (obj instanceof Date) { + obj = serializeDate?.(obj); + } + else if (generateArrayPrefix === 'comma' && isArray(obj)) { + obj = maybe_map(obj, function (value) { + if (value instanceof Date) { + return serializeDate?.(value); + } + return value; + }); + } + if (obj === null) { + if (strictNullHandling) { + return encoder && !encodeValuesOnly ? + // @ts-expect-error + encoder(prefix, defaults.encoder, charset, 'key', format) + : prefix; + } + obj = ''; + } + if (is_non_nullish_primitive(obj) || is_buffer(obj)) { + if (encoder) { + const key_value = encodeValuesOnly ? prefix + // @ts-expect-error + : encoder(prefix, defaults.encoder, charset, 'key', format); + return [ + formatter?.(key_value) + + '=' + + // @ts-expect-error + formatter?.(encoder(obj, defaults.encoder, charset, 'value', format)), + ]; + } + return [formatter?.(prefix) + '=' + formatter?.(String(obj))]; + } + const values = []; + if (typeof obj === 'undefined') { + return values; + } + let obj_keys; + if (generateArrayPrefix === 'comma' && isArray(obj)) { + // we need to join elements in + if (encodeValuesOnly && encoder) { + // @ts-expect-error values only + obj = maybe_map(obj, encoder); + } + obj_keys = [{ value: obj.length > 0 ? obj.join(',') || null : void undefined }]; + } + else if (isArray(filter)) { + obj_keys = filter; + } + else { + const keys = Object.keys(obj); + obj_keys = sort ? keys.sort(sort) : keys; + } + const encoded_prefix = encodeDotInKeys ? String(prefix).replace(/\./g, '%2E') : String(prefix); + const adjusted_prefix = commaRoundTrip && isArray(obj) && obj.length === 1 ? encoded_prefix + '[]' : encoded_prefix; + if (allowEmptyArrays && isArray(obj) && obj.length === 0) { + return adjusted_prefix + '[]'; + } + for (let j = 0; j < obj_keys.length; ++j) { + const key = obj_keys[j]; + const value = + // @ts-ignore + typeof key === 'object' && typeof key.value !== 'undefined' ? key.value : obj[key]; + if (skipNulls && value === null) { + continue; + } + // @ts-ignore + const encoded_key = allowDots && encodeDotInKeys ? key.replace(/\./g, '%2E') : key; + const key_prefix = isArray(obj) ? + typeof generateArrayPrefix === 'function' ? + generateArrayPrefix(adjusted_prefix, encoded_key) + : adjusted_prefix + : adjusted_prefix + (allowDots ? '.' + encoded_key : '[' + encoded_key + ']'); + sideChannel.set(object, step); + const valueSideChannel = new WeakMap(); + valueSideChannel.set(sentinel, sideChannel); + push_to_array(values, inner_stringify(value, key_prefix, generateArrayPrefix, commaRoundTrip, allowEmptyArrays, strictNullHandling, skipNulls, encodeDotInKeys, + // @ts-ignore + generateArrayPrefix === 'comma' && encodeValuesOnly && isArray(obj) ? null : encoder, filter, sort, allowDots, serializeDate, format, formatter, encodeValuesOnly, charset, valueSideChannel)); + } + return values; +} +function normalize_stringify_options(opts = defaults) { + if (typeof opts.allowEmptyArrays !== 'undefined' && typeof opts.allowEmptyArrays !== 'boolean') { + throw new TypeError('`allowEmptyArrays` option can only be `true` or `false`, when provided'); + } + if (typeof opts.encodeDotInKeys !== 'undefined' && typeof opts.encodeDotInKeys !== 'boolean') { + throw new TypeError('`encodeDotInKeys` option can only be `true` or `false`, when provided'); + } + if (opts.encoder !== null && typeof opts.encoder !== 'undefined' && typeof opts.encoder !== 'function') { + throw new TypeError('Encoder has to be a function.'); + } + const charset = opts.charset || defaults.charset; + if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') { + throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined'); + } + let format = default_format; + if (typeof opts.format !== 'undefined') { + if (!has(formatters, opts.format)) { + throw new TypeError('Unknown format option provided.'); + } + format = opts.format; + } + const formatter = formatters[format]; + let filter = defaults.filter; + if (typeof opts.filter === 'function' || isArray(opts.filter)) { + filter = opts.filter; + } + let arrayFormat; + if (opts.arrayFormat && opts.arrayFormat in array_prefix_generators) { + arrayFormat = opts.arrayFormat; + } + else if ('indices' in opts) { + arrayFormat = opts.indices ? 'indices' : 'repeat'; + } + else { + arrayFormat = defaults.arrayFormat; + } + if ('commaRoundTrip' in opts && typeof opts.commaRoundTrip !== 'boolean') { + throw new TypeError('`commaRoundTrip` must be a boolean, or absent'); + } + const allowDots = typeof opts.allowDots === 'undefined' ? + !!opts.encodeDotInKeys === true ? + true + : defaults.allowDots + : !!opts.allowDots; + return { + addQueryPrefix: typeof opts.addQueryPrefix === 'boolean' ? opts.addQueryPrefix : defaults.addQueryPrefix, + // @ts-ignore + allowDots: allowDots, + allowEmptyArrays: typeof opts.allowEmptyArrays === 'boolean' ? !!opts.allowEmptyArrays : defaults.allowEmptyArrays, + arrayFormat: arrayFormat, + charset: charset, + charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel, + commaRoundTrip: !!opts.commaRoundTrip, + delimiter: typeof opts.delimiter === 'undefined' ? defaults.delimiter : opts.delimiter, + encode: typeof opts.encode === 'boolean' ? opts.encode : defaults.encode, + encodeDotInKeys: typeof opts.encodeDotInKeys === 'boolean' ? opts.encodeDotInKeys : defaults.encodeDotInKeys, + encoder: typeof opts.encoder === 'function' ? opts.encoder : defaults.encoder, + encodeValuesOnly: typeof opts.encodeValuesOnly === 'boolean' ? opts.encodeValuesOnly : defaults.encodeValuesOnly, + filter: filter, + format: format, + formatter: formatter, + serializeDate: typeof opts.serializeDate === 'function' ? opts.serializeDate : defaults.serializeDate, + skipNulls: typeof opts.skipNulls === 'boolean' ? opts.skipNulls : defaults.skipNulls, + // @ts-ignore + sort: typeof opts.sort === 'function' ? opts.sort : null, + strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling, + }; +} +function stringify(object, opts = {}) { + let obj = object; + const options = normalize_stringify_options(opts); + let obj_keys; + let filter; + if (typeof options.filter === 'function') { + filter = options.filter; + obj = filter('', obj); + } + else if (isArray(options.filter)) { + filter = options.filter; + obj_keys = filter; + } + const keys = []; + if (typeof obj !== 'object' || obj === null) { + return ''; + } + const generateArrayPrefix = array_prefix_generators[options.arrayFormat]; + const commaRoundTrip = generateArrayPrefix === 'comma' && options.commaRoundTrip; + if (!obj_keys) { + obj_keys = Object.keys(obj); + } + if (options.sort) { + obj_keys.sort(options.sort); + } + const sideChannel = new WeakMap(); + for (let i = 0; i < obj_keys.length; ++i) { + const key = obj_keys[i]; + if (options.skipNulls && obj[key] === null) { + continue; + } + push_to_array(keys, inner_stringify(obj[key], key, + // @ts-expect-error + generateArrayPrefix, commaRoundTrip, options.allowEmptyArrays, options.strictNullHandling, options.skipNulls, options.encodeDotInKeys, options.encode ? options.encoder : null, options.filter, options.sort, options.allowDots, options.serializeDate, options.format, options.formatter, options.encodeValuesOnly, options.charset, sideChannel)); + } + const joined = keys.join(options.delimiter); + let prefix = options.addQueryPrefix === true ? '?' : ''; + if (options.charsetSentinel) { + if (options.charset === 'iso-8859-1') { + // encodeURIComponent('✓'), the "numeric entity" representation of a checkmark + prefix += 'utf8=%26%2310003%3B&'; + } + else { + // encodeURIComponent('✓') + prefix += 'utf8=%E2%9C%93&'; + } + } + return joined.length > 0 ? prefix + joined : ''; +} + +function concatBytes(buffers) { + let length = 0; + for (const buffer of buffers) { + length += buffer.length; + } + const output = new Uint8Array(length); + let index = 0; + for (const buffer of buffers) { + output.set(buffer, index); + index += buffer.length; + } + return output; +} +let encodeUTF8_; +function encodeUTF8(str) { + let encoder; + return (encodeUTF8_ ?? + ((encoder = new globalThis.TextEncoder()), (encodeUTF8_ = encoder.encode.bind(encoder))))(str); +} +let decodeUTF8_; +function decodeUTF8(bytes) { + let decoder; + return (decodeUTF8_ ?? + ((decoder = new globalThis.TextDecoder()), (decodeUTF8_ = decoder.decode.bind(decoder))))(bytes); +} + +var _LineDecoder_buffer, _LineDecoder_carriageReturnIndex; +/** + * A re-implementation of httpx's `LineDecoder` in Python that handles incrementally + * reading lines from text. + * + * https://github.com/encode/httpx/blob/920333ea98118e9cf617f246905d7b202510941c/httpx/_decoders.py#L258 + */ +class LineDecoder { + constructor() { + _LineDecoder_buffer.set(this, void 0); + _LineDecoder_carriageReturnIndex.set(this, void 0); + __classPrivateFieldSet(this, _LineDecoder_buffer, new Uint8Array()); + __classPrivateFieldSet(this, _LineDecoder_carriageReturnIndex, null); + } + decode(chunk) { + if (chunk == null) { + return []; + } + const binaryChunk = chunk instanceof ArrayBuffer ? new Uint8Array(chunk) + : typeof chunk === 'string' ? encodeUTF8(chunk) + : chunk; + __classPrivateFieldSet(this, _LineDecoder_buffer, concatBytes([__classPrivateFieldGet(this, _LineDecoder_buffer, "f"), binaryChunk])); + const lines = []; + let patternIndex; + while ((patternIndex = findNewlineIndex(__classPrivateFieldGet(this, _LineDecoder_buffer, "f"), __classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f"))) != null) { + if (patternIndex.carriage && __classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f") == null) { + // skip until we either get a corresponding `\n`, a new `\r` or nothing + __classPrivateFieldSet(this, _LineDecoder_carriageReturnIndex, patternIndex.index); + continue; + } + // we got double \r or \rtext\n + if (__classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f") != null && + (patternIndex.index !== __classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f") + 1 || patternIndex.carriage)) { + lines.push(decodeUTF8(__classPrivateFieldGet(this, _LineDecoder_buffer, "f").subarray(0, __classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f") - 1))); + __classPrivateFieldSet(this, _LineDecoder_buffer, __classPrivateFieldGet(this, _LineDecoder_buffer, "f").subarray(__classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f"))); + __classPrivateFieldSet(this, _LineDecoder_carriageReturnIndex, null); + continue; + } + const endIndex = __classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f") !== null ? patternIndex.preceding - 1 : patternIndex.preceding; + const line = decodeUTF8(__classPrivateFieldGet(this, _LineDecoder_buffer, "f").subarray(0, endIndex)); + lines.push(line); + __classPrivateFieldSet(this, _LineDecoder_buffer, __classPrivateFieldGet(this, _LineDecoder_buffer, "f").subarray(patternIndex.index)); + __classPrivateFieldSet(this, _LineDecoder_carriageReturnIndex, null); + } + return lines; + } + flush() { + if (!__classPrivateFieldGet(this, _LineDecoder_buffer, "f").length) { + return []; + } + return this.decode('\n'); + } +} +_LineDecoder_buffer = new WeakMap(), _LineDecoder_carriageReturnIndex = new WeakMap(); +// prettier-ignore +LineDecoder.NEWLINE_CHARS = new Set(['\n', '\r']); +LineDecoder.NEWLINE_REGEXP = /\r\n|[\n\r]/g; +/** + * This function searches the buffer for the end patterns, (\r or \n) + * and returns an object with the index preceding the matched newline and the + * index after the newline char. `null` is returned if no new line is found. + * + * ```ts + * findNewLineIndex('abc\ndef') -> { preceding: 2, index: 3 } + * ``` + */ +function findNewlineIndex(buffer, startIndex) { + const newline = 0x0a; // \n + const carriage = 0x0d; // \r + for (let i = startIndex ?? 0; i < buffer.length; i++) { + if (buffer[i] === newline) { + return { preceding: i, index: i + 1, carriage: false }; + } + if (buffer[i] === carriage) { + return { preceding: i, index: i + 1, carriage: true }; + } + } + return null; +} +function findDoubleNewlineIndex(buffer) { + // This function searches the buffer for the end patterns (\r\r, \n\n, \r\n\r\n) + // and returns the index right after the first occurrence of any pattern, + // or -1 if none of the patterns are found. + const newline = 0x0a; // \n + const carriage = 0x0d; // \r + for (let i = 0; i < buffer.length - 1; i++) { + if (buffer[i] === newline && buffer[i + 1] === newline) { + // \n\n + return i + 2; + } + if (buffer[i] === carriage && buffer[i + 1] === carriage) { + // \r\r + return i + 2; + } + if (buffer[i] === carriage && + buffer[i + 1] === newline && + i + 3 < buffer.length && + buffer[i + 2] === carriage && + buffer[i + 3] === newline) { + // \r\n\r\n + return i + 4; + } + } + return -1; +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +const levelNumbers = { + off: 0, + error: 200, + warn: 300, + info: 400, + debug: 500, +}; +const parseLogLevel = (maybeLevel, sourceName, client) => { + if (!maybeLevel) { + return undefined; + } + if (hasOwn(levelNumbers, maybeLevel)) { + return maybeLevel; + } + loggerFor(client).warn(`${sourceName} was set to ${JSON.stringify(maybeLevel)}, expected one of ${JSON.stringify(Object.keys(levelNumbers))}`); + return undefined; +}; +function noop() { } +function makeLogFn(fnLevel, logger, logLevel) { + if (!logger || levelNumbers[fnLevel] > levelNumbers[logLevel]) { + return noop; + } + else { + // Don't wrap logger functions, we want the stacktrace intact! + return logger[fnLevel].bind(logger); + } +} +const noopLogger = { + error: noop, + warn: noop, + info: noop, + debug: noop, +}; +let cachedLoggers = /* @__PURE__ */ new WeakMap(); +function loggerFor(client) { + const logger = client.logger; + const logLevel = client.logLevel ?? 'off'; + if (!logger) { + return noopLogger; + } + const cachedLogger = cachedLoggers.get(logger); + if (cachedLogger && cachedLogger[0] === logLevel) { + return cachedLogger[1]; + } + const levelLogger = { + error: makeLogFn('error', logger, logLevel), + warn: makeLogFn('warn', logger, logLevel), + info: makeLogFn('info', logger, logLevel), + debug: makeLogFn('debug', logger, logLevel), + }; + cachedLoggers.set(logger, [logLevel, levelLogger]); + return levelLogger; +} +const formatRequestDetails = (details) => { + if (details.options) { + details.options = { ...details.options }; + delete details.options['headers']; // redundant + leaks internals + } + if (details.headers) { + details.headers = Object.fromEntries((details.headers instanceof Headers ? [...details.headers] : Object.entries(details.headers)).map(([name, value]) => [ + name, + (name.toLowerCase() === 'authorization' || + name.toLowerCase() === 'cookie' || + name.toLowerCase() === 'set-cookie') ? + '***' + : value, + ])); + } + if ('retryOfRequestLogID' in details) { + if (details.retryOfRequestLogID) { + details.retryOf = details.retryOfRequestLogID; + } + delete details.retryOfRequestLogID; + } + return details; +}; + +var _Stream_client; +class Stream { + constructor(iterator, controller, client) { + this.iterator = iterator; + _Stream_client.set(this, void 0); + this.controller = controller; + __classPrivateFieldSet(this, _Stream_client, client); + } + static fromSSEResponse(response, controller, client) { + let consumed = false; + const logger = client ? loggerFor(client) : console; + async function* iterator() { + if (consumed) { + throw new OpenAIError('Cannot iterate over a consumed stream, use `.tee()` to split the stream.'); + } + consumed = true; + let done = false; + try { + for await (const sse of _iterSSEMessages(response, controller)) { + if (done) + continue; + if (sse.data.startsWith('[DONE]')) { + done = true; + continue; + } + if (sse.event === null || !sse.event.startsWith('thread.')) { + let data; + try { + data = JSON.parse(sse.data); + } + catch (e) { + logger.error(`Could not parse message into JSON:`, sse.data); + logger.error(`From chunk:`, sse.raw); + throw e; + } + if (data && data.error) { + throw new APIError(undefined, data.error, undefined, response.headers); + } + yield data; + } + else { + let data; + try { + data = JSON.parse(sse.data); + } + catch (e) { + console.error(`Could not parse message into JSON:`, sse.data); + console.error(`From chunk:`, sse.raw); + throw e; + } + // TODO: Is this where the error should be thrown? + if (sse.event == 'error') { + throw new APIError(undefined, data.error, data.message, undefined); + } + yield { event: sse.event, data: data }; + } + } + done = true; + } + catch (e) { + // If the user calls `stream.controller.abort()`, we should exit without throwing. + if (isAbortError(e)) + return; + throw e; + } + finally { + // If the user `break`s, abort the ongoing request. + if (!done) + controller.abort(); + } + } + return new Stream(iterator, controller, client); + } + /** + * Generates a Stream from a newline-separated ReadableStream + * where each item is a JSON value. + */ + static fromReadableStream(readableStream, controller, client) { + let consumed = false; + async function* iterLines() { + const lineDecoder = new LineDecoder(); + const iter = ReadableStreamToAsyncIterable(readableStream); + for await (const chunk of iter) { + for (const line of lineDecoder.decode(chunk)) { + yield line; + } + } + for (const line of lineDecoder.flush()) { + yield line; + } + } + async function* iterator() { + if (consumed) { + throw new OpenAIError('Cannot iterate over a consumed stream, use `.tee()` to split the stream.'); + } + consumed = true; + let done = false; + try { + for await (const line of iterLines()) { + if (done) + continue; + if (line) + yield JSON.parse(line); + } + done = true; + } + catch (e) { + // If the user calls `stream.controller.abort()`, we should exit without throwing. + if (isAbortError(e)) + return; + throw e; + } + finally { + // If the user `break`s, abort the ongoing request. + if (!done) + controller.abort(); + } + } + return new Stream(iterator, controller, client); + } + [(_Stream_client = new WeakMap(), Symbol.asyncIterator)]() { + return this.iterator(); + } + /** + * Splits the stream into two streams which can be + * independently read from at different speeds. + */ + tee() { + const left = []; + const right = []; + const iterator = this.iterator(); + const teeIterator = (queue) => { + return { + next: () => { + if (queue.length === 0) { + const result = iterator.next(); + left.push(result); + right.push(result); + } + return queue.shift(); + }, + }; + }; + return [ + new Stream(() => teeIterator(left), this.controller, __classPrivateFieldGet(this, _Stream_client, "f")), + new Stream(() => teeIterator(right), this.controller, __classPrivateFieldGet(this, _Stream_client, "f")), + ]; + } + /** + * Converts this stream to a newline-separated ReadableStream of + * JSON stringified values in the stream + * which can be turned back into a Stream with `Stream.fromReadableStream()`. + */ + toReadableStream() { + const self = this; + let iter; + return makeReadableStream({ + async start() { + iter = self[Symbol.asyncIterator](); + }, + async pull(ctrl) { + try { + const { value, done } = await iter.next(); + if (done) + return ctrl.close(); + const bytes = encodeUTF8(JSON.stringify(value) + '\n'); + ctrl.enqueue(bytes); + } + catch (err) { + ctrl.error(err); + } + }, + async cancel() { + await iter.return?.(); + }, + }); + } +} +async function* _iterSSEMessages(response, controller) { + if (!response.body) { + controller.abort(); + if (typeof globalThis.navigator !== 'undefined' && + globalThis.navigator.product === 'ReactNative') { + throw new OpenAIError(`The default react-native fetch implementation does not support streaming. Please use expo/fetch: https://docs.expo.dev/versions/latest/sdk/expo/#expofetch-api`); + } + throw new OpenAIError(`Attempted to iterate over a response with no body`); + } + const sseDecoder = new SSEDecoder(); + const lineDecoder = new LineDecoder(); + const iter = ReadableStreamToAsyncIterable(response.body); + for await (const sseChunk of iterSSEChunks(iter)) { + for (const line of lineDecoder.decode(sseChunk)) { + const sse = sseDecoder.decode(line); + if (sse) + yield sse; + } + } + for (const line of lineDecoder.flush()) { + const sse = sseDecoder.decode(line); + if (sse) + yield sse; + } +} +/** + * Given an async iterable iterator, iterates over it and yields full + * SSE chunks, i.e. yields when a double new-line is encountered. + */ +async function* iterSSEChunks(iterator) { + let data = new Uint8Array(); + for await (const chunk of iterator) { + if (chunk == null) { + continue; + } + const binaryChunk = chunk instanceof ArrayBuffer ? new Uint8Array(chunk) + : typeof chunk === 'string' ? encodeUTF8(chunk) + : chunk; + let newData = new Uint8Array(data.length + binaryChunk.length); + newData.set(data); + newData.set(binaryChunk, data.length); + data = newData; + let patternIndex; + while ((patternIndex = findDoubleNewlineIndex(data)) !== -1) { + yield data.slice(0, patternIndex); + data = data.slice(patternIndex); + } + } + if (data.length > 0) { + yield data; + } +} +class SSEDecoder { + constructor() { + this.event = null; + this.data = []; + this.chunks = []; + } + decode(line) { + if (line.endsWith('\r')) { + line = line.substring(0, line.length - 1); + } + if (!line) { + // empty line and we didn't previously encounter any messages + if (!this.event && !this.data.length) + return null; + const sse = { + event: this.event, + data: this.data.join('\n'), + raw: this.chunks, + }; + this.event = null; + this.data = []; + this.chunks = []; + return sse; + } + this.chunks.push(line); + if (line.startsWith(':')) { + return null; + } + let [fieldname, _, value] = partition(line, ':'); + if (value.startsWith(' ')) { + value = value.substring(1); + } + if (fieldname === 'event') { + this.event = value; + } + else if (fieldname === 'data') { + this.data.push(value); + } + return null; + } +} +function partition(str, delimiter) { + const index = str.indexOf(delimiter); + if (index !== -1) { + return [str.substring(0, index), delimiter, str.substring(index + delimiter.length)]; + } + return [str, '', '']; +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +async function defaultParseResponse(client, props) { + const { response, requestLogID, retryOfRequestLogID, startTime } = props; + const body = await (async () => { + if (props.options.stream) { + loggerFor(client).debug('response', response.status, response.url, response.headers, response.body); + // Note: there is an invariant here that isn't represented in the type system + // that if you set `stream: true` the response type must also be `Stream` + if (props.options.__streamClass) { + return props.options.__streamClass.fromSSEResponse(response, props.controller, client); + } + return Stream.fromSSEResponse(response, props.controller, client); + } + // fetch refuses to read the body when the status code is 204. + if (response.status === 204) { + return null; + } + if (props.options.__binaryResponse) { + return response; + } + const contentType = response.headers.get('content-type'); + const mediaType = contentType?.split(';')[0]?.trim(); + const isJSON = mediaType?.includes('application/json') || mediaType?.endsWith('+json'); + if (isJSON) { + const json = await response.json(); + return addRequestID(json, response); + } + const text = await response.text(); + return text; + })(); + loggerFor(client).debug(`[${requestLogID}] response parsed`, formatRequestDetails({ + retryOfRequestLogID, + url: response.url, + status: response.status, + body, + durationMs: Date.now() - startTime, + })); + return body; +} +function addRequestID(value, response) { + if (!value || typeof value !== 'object' || Array.isArray(value)) { + return value; + } + return Object.defineProperty(value, '_request_id', { + value: response.headers.get('x-request-id'), + enumerable: false, + }); +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +var _APIPromise_client; +/** + * A subclass of `Promise` providing additional helper methods + * for interacting with the SDK. + */ +class APIPromise extends Promise { + constructor(client, responsePromise, parseResponse = defaultParseResponse) { + super((resolve) => { + // this is maybe a bit weird but this has to be a no-op to not implicitly + // parse the response body; instead .then, .catch, .finally are overridden + // to parse the response + resolve(null); + }); + this.responsePromise = responsePromise; + this.parseResponse = parseResponse; + _APIPromise_client.set(this, void 0); + __classPrivateFieldSet(this, _APIPromise_client, client); + } + _thenUnwrap(transform) { + return new APIPromise(__classPrivateFieldGet(this, _APIPromise_client, "f"), this.responsePromise, async (client, props) => addRequestID(transform(await this.parseResponse(client, props), props), props.response)); + } + /** + * Gets the raw `Response` instance instead of parsing the response + * data. + * + * If you want to parse the response body but still get the `Response` + * instance, you can use {@link withResponse()}. + * + * 👋 Getting the wrong TypeScript type for `Response`? + * Try setting `"moduleResolution": "NodeNext"` or add `"lib": ["DOM"]` + * to your `tsconfig.json`. + */ + asResponse() { + return this.responsePromise.then((p) => p.response); + } + /** + * Gets the parsed response data, the raw `Response` instance and the ID of the request, + * returned via the X-Request-ID header which is useful for debugging requests and reporting + * issues to OpenAI. + * + * If you just want to get the raw `Response` instance without parsing it, + * you can use {@link asResponse()}. + * + * 👋 Getting the wrong TypeScript type for `Response`? + * Try setting `"moduleResolution": "NodeNext"` or add `"lib": ["DOM"]` + * to your `tsconfig.json`. + */ + async withResponse() { + const [data, response] = await Promise.all([this.parse(), this.asResponse()]); + return { data, response, request_id: response.headers.get('x-request-id') }; + } + parse() { + if (!this.parsedPromise) { + this.parsedPromise = this.responsePromise.then((data) => this.parseResponse(__classPrivateFieldGet(this, _APIPromise_client, "f"), data)); + } + return this.parsedPromise; + } + then(onfulfilled, onrejected) { + return this.parse().then(onfulfilled, onrejected); + } + catch(onrejected) { + return this.parse().catch(onrejected); + } + finally(onfinally) { + return this.parse().finally(onfinally); + } +} +_APIPromise_client = new WeakMap(); + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +var _AbstractPage_client; +class AbstractPage { + constructor(client, response, body, options) { + _AbstractPage_client.set(this, void 0); + __classPrivateFieldSet(this, _AbstractPage_client, client); + this.options = options; + this.response = response; + this.body = body; + } + hasNextPage() { + const items = this.getPaginatedItems(); + if (!items.length) + return false; + return this.nextPageRequestOptions() != null; + } + async getNextPage() { + const nextOptions = this.nextPageRequestOptions(); + if (!nextOptions) { + throw new OpenAIError('No next page expected; please check `.hasNextPage()` before calling `.getNextPage()`.'); + } + return await __classPrivateFieldGet(this, _AbstractPage_client, "f").requestAPIList(this.constructor, nextOptions); + } + async *iterPages() { + let page = this; + yield page; + while (page.hasNextPage()) { + page = await page.getNextPage(); + yield page; + } + } + async *[(_AbstractPage_client = new WeakMap(), Symbol.asyncIterator)]() { + for await (const page of this.iterPages()) { + for (const item of page.getPaginatedItems()) { + yield item; + } + } + } +} +/** + * This subclass of Promise will resolve to an instantiated Page once the request completes. + * + * It also implements AsyncIterable to allow auto-paginating iteration on an unawaited list call, eg: + * + * for await (const item of client.items.list()) { + * console.log(item) + * } + */ +class PagePromise extends APIPromise { + constructor(client, request, Page) { + super(client, request, async (client, props) => new Page(client, props.response, await defaultParseResponse(client, props), props.options)); + } + /** + * Allow auto-paginating iteration on an unawaited list call, eg: + * + * for await (const item of client.items.list()) { + * console.log(item) + * } + */ + async *[Symbol.asyncIterator]() { + const page = await this; + for await (const item of page) { + yield item; + } + } +} +/** + * Note: no pagination actually occurs yet, this is for forwards-compatibility. + */ +class Page extends AbstractPage { + constructor(client, response, body, options) { + super(client, response, body, options); + this.data = body.data || []; + this.object = body.object; + } + getPaginatedItems() { + return this.data ?? []; + } + nextPageRequestOptions() { + return null; + } +} +class CursorPage extends AbstractPage { + constructor(client, response, body, options) { + super(client, response, body, options); + this.data = body.data || []; + this.has_more = body.has_more || false; + } + getPaginatedItems() { + return this.data ?? []; + } + hasNextPage() { + if (this.has_more === false) { + return false; + } + return super.hasNextPage(); + } + nextPageRequestOptions() { + const data = this.getPaginatedItems(); + const id = data[data.length - 1]?.id; + if (!id) { + return null; + } + return { + ...this.options, + query: { + ...maybeObj(this.options.query), + after: id, + }, + }; + } +} +class ConversationCursorPage extends AbstractPage { + constructor(client, response, body, options) { + super(client, response, body, options); + this.data = body.data || []; + this.has_more = body.has_more || false; + this.last_id = body.last_id || ''; + } + getPaginatedItems() { + return this.data ?? []; + } + hasNextPage() { + if (this.has_more === false) { + return false; + } + return super.hasNextPage(); + } + nextPageRequestOptions() { + const cursor = this.last_id; + if (!cursor) { + return null; + } + return { + ...this.options, + query: { + ...maybeObj(this.options.query), + after: cursor, + }, + }; + } +} + +const checkFileSupport = () => { + if (typeof File === 'undefined') { + const { process } = globalThis; + const isOldNode = typeof process?.versions?.node === 'string' && parseInt(process.versions.node.split('.')) < 20; + throw new Error('`File` is not defined as a global, which is required for file uploads.' + + (isOldNode ? + " Update to Node 20 LTS or newer, or set `globalThis.File` to `import('node:buffer').File`." + : '')); + } +}; +/** + * Construct a `File` instance. This is used to ensure a helpful error is thrown + * for environments that don't define a global `File` yet. + */ +function makeFile(fileBits, fileName, options) { + checkFileSupport(); + return new File(fileBits, fileName ?? 'unknown_file', options); +} +function getName(value) { + return (((typeof value === 'object' && + value !== null && + (('name' in value && value.name && String(value.name)) || + ('url' in value && value.url && String(value.url)) || + ('filename' in value && value.filename && String(value.filename)) || + ('path' in value && value.path && String(value.path)))) || + '') + .split(/[\\/]/) + .pop() || undefined); +} +const isAsyncIterable = (value) => value != null && typeof value === 'object' && typeof value[Symbol.asyncIterator] === 'function'; +const multipartFormRequestOptions = async (opts, fetch) => { + return { ...opts, body: await createForm(opts.body, fetch) }; +}; +const supportsFormDataMap = /* @__PURE__ */ new WeakMap(); +/** + * node-fetch doesn't support the global FormData object in recent node versions. Instead of sending + * properly-encoded form data, it just stringifies the object, resulting in a request body of "[object FormData]". + * This function detects if the fetch function provided supports the global FormData object to avoid + * confusing error messages later on. + */ +function supportsFormData(fetchObject) { + const fetch = typeof fetchObject === 'function' ? fetchObject : fetchObject.fetch; + const cached = supportsFormDataMap.get(fetch); + if (cached) + return cached; + const promise = (async () => { + try { + const FetchResponse = ('Response' in fetch ? + fetch.Response + : (await fetch('data:,')).constructor); + const data = new FormData(); + if (data.toString() === (await new FetchResponse(data).text())) { + return false; + } + return true; + } + catch { + // avoid false negatives + return true; + } + })(); + supportsFormDataMap.set(fetch, promise); + return promise; +} +const createForm = async (body, fetch) => { + if (!(await supportsFormData(fetch))) { + throw new TypeError('The provided fetch function does not support file uploads with the current global FormData class.'); + } + const form = new FormData(); + await Promise.all(Object.entries(body || {}).map(([key, value]) => addFormValue(form, key, value))); + return form; +}; +// We check for Blob not File because Bun.File doesn't inherit from File, +// but they both inherit from Blob and have a `name` property at runtime. +const isNamedBlob = (value) => value instanceof Blob && 'name' in value; +const addFormValue = async (form, key, value) => { + if (value === undefined) + return; + if (value == null) { + throw new TypeError(`Received null for "${key}"; to pass null in FormData, you must use the string 'null'`); + } + // TODO: make nested formats configurable + if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') { + form.append(key, String(value)); + } + else if (value instanceof Response) { + form.append(key, makeFile([await value.blob()], getName(value))); + } + else if (isAsyncIterable(value)) { + form.append(key, makeFile([await new Response(ReadableStreamFrom(value)).blob()], getName(value))); + } + else if (isNamedBlob(value)) { + form.append(key, value, getName(value)); + } + else if (Array.isArray(value)) { + await Promise.all(value.map((entry) => addFormValue(form, key + '[]', entry))); + } + else if (typeof value === 'object') { + await Promise.all(Object.entries(value).map(([name, prop]) => addFormValue(form, `${key}[${name}]`, prop))); + } + else { + throw new TypeError(`Invalid value given to form, expected a string, number, boolean, object, Array, File or Blob but got ${value} instead`); + } +}; + +/** + * This check adds the arrayBuffer() method type because it is available and used at runtime + */ +const isBlobLike = (value) => value != null && + typeof value === 'object' && + typeof value.size === 'number' && + typeof value.type === 'string' && + typeof value.text === 'function' && + typeof value.slice === 'function' && + typeof value.arrayBuffer === 'function'; +/** + * This check adds the arrayBuffer() method type because it is available and used at runtime + */ +const isFileLike = (value) => value != null && + typeof value === 'object' && + typeof value.name === 'string' && + typeof value.lastModified === 'number' && + isBlobLike(value); +const isResponseLike = (value) => value != null && + typeof value === 'object' && + typeof value.url === 'string' && + typeof value.blob === 'function'; +/** + * Helper for creating a {@link File} to pass to an SDK upload method from a variety of different data formats + * @param value the raw content of the file. Can be an {@link Uploadable}, {@link BlobLikePart}, or {@link AsyncIterable} of {@link BlobLikePart}s + * @param {string=} name the name of the file. If omitted, toFile will try to determine a file name from bits if possible + * @param {Object=} options additional properties + * @param {string=} options.type the MIME type of the content + * @param {number=} options.lastModified the last modified timestamp + * @returns a {@link File} with the given properties + */ +async function toFile(value, name, options) { + checkFileSupport(); + // If it's a promise, resolve it. + value = await value; + // If we've been given a `File` we don't need to do anything + if (isFileLike(value)) { + if (value instanceof File) { + return value; + } + return makeFile([await value.arrayBuffer()], value.name); + } + if (isResponseLike(value)) { + const blob = await value.blob(); + name || (name = new URL(value.url).pathname.split(/[\\/]/).pop()); + return makeFile(await getBytes(blob), name, options); + } + const parts = await getBytes(value); + name || (name = getName(value)); + if (!options?.type) { + const type = parts.find((part) => typeof part === 'object' && 'type' in part && part.type); + if (typeof type === 'string') { + options = { ...options, type }; + } + } + return makeFile(parts, name, options); +} +async function getBytes(value) { + let parts = []; + if (typeof value === 'string' || + ArrayBuffer.isView(value) || // includes Uint8Array, Buffer, etc. + value instanceof ArrayBuffer) { + parts.push(value); + } + else if (isBlobLike(value)) { + parts.push(value instanceof Blob ? value : await value.arrayBuffer()); + } + else if (isAsyncIterable(value) // includes Readable, ReadableStream, etc. + ) { + for await (const chunk of value) { + parts.push(...(await getBytes(chunk))); // TODO, consider validating? + } + } + else { + const constructor = value?.constructor?.name; + throw new Error(`Unexpected data type: ${typeof value}${constructor ? `; constructor: ${constructor}` : ''}${propsForError(value)}`); + } + return parts; +} +function propsForError(value) { + if (typeof value !== 'object' || value === null) + return ''; + const props = Object.getOwnPropertyNames(value); + return `; props: [${props.map((p) => `"${p}"`).join(', ')}]`; +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class APIResource { + constructor(client) { + this._client = client; + } +} + +/** + * Percent-encode everything that isn't safe to have in a path without encoding safe chars. + * + * Taken from https://datatracker.ietf.org/doc/html/rfc3986#section-3.3: + * > unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + * > sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "=" + * > pchar = unreserved / pct-encoded / sub-delims / ":" / "@" + */ +function encodeURIPath(str) { + return str.replace(/[^A-Za-z0-9\-._~!$&'()*+,;=:@]+/g, encodeURIComponent); +} +const EMPTY = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.create(null)); +const createPathTagFunction = (pathEncoder = encodeURIPath) => function path(statics, ...params) { + // If there are no params, no processing is needed. + if (statics.length === 1) + return statics[0]; + let postPath = false; + const invalidSegments = []; + const path = statics.reduce((previousValue, currentValue, index) => { + if (/[?#]/.test(currentValue)) { + postPath = true; + } + const value = params[index]; + let encoded = (postPath ? encodeURIComponent : pathEncoder)('' + value); + if (index !== params.length && + (value == null || + (typeof value === 'object' && + // handle values from other realms + value.toString === + Object.getPrototypeOf(Object.getPrototypeOf(value.hasOwnProperty ?? EMPTY) ?? EMPTY) + ?.toString))) { + encoded = value + ''; + invalidSegments.push({ + start: previousValue.length + currentValue.length, + length: encoded.length, + error: `Value of type ${Object.prototype.toString + .call(value) + .slice(8, -1)} is not a valid path parameter`, + }); + } + return previousValue + currentValue + (index === params.length ? '' : encoded); + }, ''); + const pathOnly = path.split(/[?#]/, 1)[0]; + const invalidSegmentPattern = /(?<=^|\/)(?:\.|%2e){1,2}(?=\/|$)/gi; + let match; + // Find all invalid segments + while ((match = invalidSegmentPattern.exec(pathOnly)) !== null) { + invalidSegments.push({ + start: match.index, + length: match[0].length, + error: `Value "${match[0]}" can\'t be safely passed as a path parameter`, + }); + } + invalidSegments.sort((a, b) => a.start - b.start); + if (invalidSegments.length > 0) { + let lastEnd = 0; + const underline = invalidSegments.reduce((acc, segment) => { + const spaces = ' '.repeat(segment.start - lastEnd); + const arrows = '^'.repeat(segment.length); + lastEnd = segment.start + segment.length; + return acc + spaces + arrows; + }, ''); + throw new OpenAIError(`Path parameters result in path with invalid segments:\n${invalidSegments + .map((e) => e.error) + .join('\n')}\n${path}\n${underline}`); + } + return path; +}; +/** + * URI-encodes path params and ensures no unsafe /./ or /../ path segments are introduced. + */ +const path = /* @__PURE__ */ createPathTagFunction(encodeURIPath); + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +let Messages$1 = class Messages extends APIResource { + /** + * Get the messages in a stored chat completion. Only Chat Completions that have + * been created with the `store` parameter set to `true` will be returned. + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const chatCompletionStoreMessage of client.chat.completions.messages.list( + * 'completion_id', + * )) { + * // ... + * } + * ``` + */ + list(completionID, query = {}, options) { + return this._client.getAPIList(path `/chat/completions/${completionID}/messages`, (CursorPage), { query, ...options }); + } +}; + +function isChatCompletionFunctionTool(tool) { + return tool !== undefined && 'function' in tool && tool.function !== undefined; +} +function isAutoParsableResponseFormat(response_format) { + return response_format?.['$brand'] === 'auto-parseable-response-format'; +} +function isAutoParsableTool$1(tool) { + return tool?.['$brand'] === 'auto-parseable-tool'; +} +function maybeParseChatCompletion(completion, params) { + if (!params || !hasAutoParseableInput$1(params)) { + return { + ...completion, + choices: completion.choices.map((choice) => { + assertToolCallsAreChatCompletionFunctionToolCalls(choice.message.tool_calls); + return { + ...choice, + message: { + ...choice.message, + parsed: null, + ...(choice.message.tool_calls ? + { + tool_calls: choice.message.tool_calls, + } + : undefined), + }, + }; + }), + }; + } + return parseChatCompletion(completion, params); +} +function parseChatCompletion(completion, params) { + const choices = completion.choices.map((choice) => { + if (choice.finish_reason === 'length') { + throw new LengthFinishReasonError(); + } + if (choice.finish_reason === 'content_filter') { + throw new ContentFilterFinishReasonError(); + } + assertToolCallsAreChatCompletionFunctionToolCalls(choice.message.tool_calls); + return { + ...choice, + message: { + ...choice.message, + ...(choice.message.tool_calls ? + { + tool_calls: choice.message.tool_calls?.map((toolCall) => parseToolCall$1(params, toolCall)) ?? undefined, + } + : undefined), + parsed: choice.message.content && !choice.message.refusal ? + parseResponseFormat(params, choice.message.content) + : null, + }, + }; + }); + return { ...completion, choices }; +} +function parseResponseFormat(params, content) { + if (params.response_format?.type !== 'json_schema') { + return null; + } + if (params.response_format?.type === 'json_schema') { + if ('$parseRaw' in params.response_format) { + const response_format = params.response_format; + return response_format.$parseRaw(content); + } + return JSON.parse(content); + } + return null; +} +function parseToolCall$1(params, toolCall) { + const inputTool = params.tools?.find((inputTool) => isChatCompletionFunctionTool(inputTool) && inputTool.function?.name === toolCall.function.name); // TS doesn't narrow based on isChatCompletionTool + return { + ...toolCall, + function: { + ...toolCall.function, + parsed_arguments: isAutoParsableTool$1(inputTool) ? inputTool.$parseRaw(toolCall.function.arguments) + : inputTool?.function.strict ? JSON.parse(toolCall.function.arguments) + : null, + }, + }; +} +function shouldParseToolCall(params, toolCall) { + if (!params || !('tools' in params) || !params.tools) { + return false; + } + const inputTool = params.tools?.find((inputTool) => isChatCompletionFunctionTool(inputTool) && inputTool.function?.name === toolCall.function.name); + return (isChatCompletionFunctionTool(inputTool) && + (isAutoParsableTool$1(inputTool) || inputTool?.function.strict || false)); +} +function hasAutoParseableInput$1(params) { + if (isAutoParsableResponseFormat(params.response_format)) { + return true; + } + return (params.tools?.some((t) => isAutoParsableTool$1(t) || (t.type === 'function' && t.function.strict === true)) ?? false); +} +function assertToolCallsAreChatCompletionFunctionToolCalls(toolCalls) { + for (const toolCall of toolCalls || []) { + if (toolCall.type !== 'function') { + throw new OpenAIError(`Currently only \`function\` tool calls are supported; Received \`${toolCall.type}\``); + } + } +} +function validateInputTools(tools) { + for (const tool of tools ?? []) { + if (tool.type !== 'function') { + throw new OpenAIError(`Currently only \`function\` tool types support auto-parsing; Received \`${tool.type}\``); + } + if (tool.function.strict !== true) { + throw new OpenAIError(`The \`${tool.function.name}\` tool is not marked with \`strict: true\`. Only strict function tools can be auto-parsed`); + } + } +} + +const isAssistantMessage = (message) => { + return message?.role === 'assistant'; +}; +const isToolMessage = (message) => { + return message?.role === 'tool'; +}; + +var _EventStream_instances, _EventStream_connectedPromise, _EventStream_resolveConnectedPromise, _EventStream_rejectConnectedPromise, _EventStream_endPromise, _EventStream_resolveEndPromise, _EventStream_rejectEndPromise, _EventStream_listeners, _EventStream_ended, _EventStream_errored, _EventStream_aborted, _EventStream_catchingPromiseCreated, _EventStream_handleError; +class EventStream { + constructor() { + _EventStream_instances.add(this); + this.controller = new AbortController(); + _EventStream_connectedPromise.set(this, void 0); + _EventStream_resolveConnectedPromise.set(this, () => { }); + _EventStream_rejectConnectedPromise.set(this, () => { }); + _EventStream_endPromise.set(this, void 0); + _EventStream_resolveEndPromise.set(this, () => { }); + _EventStream_rejectEndPromise.set(this, () => { }); + _EventStream_listeners.set(this, {}); + _EventStream_ended.set(this, false); + _EventStream_errored.set(this, false); + _EventStream_aborted.set(this, false); + _EventStream_catchingPromiseCreated.set(this, false); + __classPrivateFieldSet(this, _EventStream_connectedPromise, new Promise((resolve, reject) => { + __classPrivateFieldSet(this, _EventStream_resolveConnectedPromise, resolve, "f"); + __classPrivateFieldSet(this, _EventStream_rejectConnectedPromise, reject, "f"); + })); + __classPrivateFieldSet(this, _EventStream_endPromise, new Promise((resolve, reject) => { + __classPrivateFieldSet(this, _EventStream_resolveEndPromise, resolve, "f"); + __classPrivateFieldSet(this, _EventStream_rejectEndPromise, reject, "f"); + })); + // Don't let these promises cause unhandled rejection errors. + // we will manually cause an unhandled rejection error later + // if the user hasn't registered any error listener or called + // any promise-returning method. + __classPrivateFieldGet(this, _EventStream_connectedPromise, "f").catch(() => { }); + __classPrivateFieldGet(this, _EventStream_endPromise, "f").catch(() => { }); + } + _run(executor) { + // Unfortunately if we call `executor()` immediately we get runtime errors about + // references to `this` before the `super()` constructor call returns. + setTimeout(() => { + executor().then(() => { + this._emitFinal(); + this._emit('end'); + }, __classPrivateFieldGet(this, _EventStream_instances, "m", _EventStream_handleError).bind(this)); + }, 0); + } + _connected() { + if (this.ended) + return; + __classPrivateFieldGet(this, _EventStream_resolveConnectedPromise, "f").call(this); + this._emit('connect'); + } + get ended() { + return __classPrivateFieldGet(this, _EventStream_ended, "f"); + } + get errored() { + return __classPrivateFieldGet(this, _EventStream_errored, "f"); + } + get aborted() { + return __classPrivateFieldGet(this, _EventStream_aborted, "f"); + } + abort() { + this.controller.abort(); + } + /** + * Adds the listener function to the end of the listeners array for the event. + * No checks are made to see if the listener has already been added. Multiple calls passing + * the same combination of event and listener will result in the listener being added, and + * called, multiple times. + * @returns this ChatCompletionStream, so that calls can be chained + */ + on(event, listener) { + const listeners = __classPrivateFieldGet(this, _EventStream_listeners, "f")[event] || (__classPrivateFieldGet(this, _EventStream_listeners, "f")[event] = []); + listeners.push({ listener }); + return this; + } + /** + * Removes the specified listener from the listener array for the event. + * off() will remove, at most, one instance of a listener from the listener array. If any single + * listener has been added multiple times to the listener array for the specified event, then + * off() must be called multiple times to remove each instance. + * @returns this ChatCompletionStream, so that calls can be chained + */ + off(event, listener) { + const listeners = __classPrivateFieldGet(this, _EventStream_listeners, "f")[event]; + if (!listeners) + return this; + const index = listeners.findIndex((l) => l.listener === listener); + if (index >= 0) + listeners.splice(index, 1); + return this; + } + /** + * Adds a one-time listener function for the event. The next time the event is triggered, + * this listener is removed and then invoked. + * @returns this ChatCompletionStream, so that calls can be chained + */ + once(event, listener) { + const listeners = __classPrivateFieldGet(this, _EventStream_listeners, "f")[event] || (__classPrivateFieldGet(this, _EventStream_listeners, "f")[event] = []); + listeners.push({ listener, once: true }); + return this; + } + /** + * This is similar to `.once()`, but returns a Promise that resolves the next time + * the event is triggered, instead of calling a listener callback. + * @returns a Promise that resolves the next time given event is triggered, + * or rejects if an error is emitted. (If you request the 'error' event, + * returns a promise that resolves with the error). + * + * Example: + * + * const message = await stream.emitted('message') // rejects if the stream errors + */ + emitted(event) { + return new Promise((resolve, reject) => { + __classPrivateFieldSet(this, _EventStream_catchingPromiseCreated, true); + if (event !== 'error') + this.once('error', reject); + this.once(event, resolve); + }); + } + async done() { + __classPrivateFieldSet(this, _EventStream_catchingPromiseCreated, true); + await __classPrivateFieldGet(this, _EventStream_endPromise, "f"); + } + _emit(event, ...args) { + // make sure we don't emit any events after end + if (__classPrivateFieldGet(this, _EventStream_ended, "f")) { + return; + } + if (event === 'end') { + __classPrivateFieldSet(this, _EventStream_ended, true); + __classPrivateFieldGet(this, _EventStream_resolveEndPromise, "f").call(this); + } + const listeners = __classPrivateFieldGet(this, _EventStream_listeners, "f")[event]; + if (listeners) { + __classPrivateFieldGet(this, _EventStream_listeners, "f")[event] = listeners.filter((l) => !l.once); + listeners.forEach(({ listener }) => listener(...args)); + } + if (event === 'abort') { + const error = args[0]; + if (!__classPrivateFieldGet(this, _EventStream_catchingPromiseCreated, "f") && !listeners?.length) { + Promise.reject(error); + } + __classPrivateFieldGet(this, _EventStream_rejectConnectedPromise, "f").call(this, error); + __classPrivateFieldGet(this, _EventStream_rejectEndPromise, "f").call(this, error); + this._emit('end'); + return; + } + if (event === 'error') { + // NOTE: _emit('error', error) should only be called from #handleError(). + const error = args[0]; + if (!__classPrivateFieldGet(this, _EventStream_catchingPromiseCreated, "f") && !listeners?.length) { + // Trigger an unhandled rejection if the user hasn't registered any error handlers. + // If you are seeing stack traces here, make sure to handle errors via either: + // - runner.on('error', () => ...) + // - await runner.done() + // - await runner.finalChatCompletion() + // - etc. + Promise.reject(error); + } + __classPrivateFieldGet(this, _EventStream_rejectConnectedPromise, "f").call(this, error); + __classPrivateFieldGet(this, _EventStream_rejectEndPromise, "f").call(this, error); + this._emit('end'); + } + } + _emitFinal() { } +} +_EventStream_connectedPromise = new WeakMap(), _EventStream_resolveConnectedPromise = new WeakMap(), _EventStream_rejectConnectedPromise = new WeakMap(), _EventStream_endPromise = new WeakMap(), _EventStream_resolveEndPromise = new WeakMap(), _EventStream_rejectEndPromise = new WeakMap(), _EventStream_listeners = new WeakMap(), _EventStream_ended = new WeakMap(), _EventStream_errored = new WeakMap(), _EventStream_aborted = new WeakMap(), _EventStream_catchingPromiseCreated = new WeakMap(), _EventStream_instances = new WeakSet(), _EventStream_handleError = function _EventStream_handleError(error) { + __classPrivateFieldSet(this, _EventStream_errored, true); + if (error instanceof Error && error.name === 'AbortError') { + error = new APIUserAbortError(); + } + if (error instanceof APIUserAbortError) { + __classPrivateFieldSet(this, _EventStream_aborted, true); + return this._emit('abort', error); + } + if (error instanceof OpenAIError) { + return this._emit('error', error); + } + if (error instanceof Error) { + const openAIError = new OpenAIError(error.message); + // @ts-ignore + openAIError.cause = error; + return this._emit('error', openAIError); + } + return this._emit('error', new OpenAIError(String(error))); +}; + +function isRunnableFunctionWithParse(fn) { + return typeof fn.parse === 'function'; +} + +var _AbstractChatCompletionRunner_instances, _AbstractChatCompletionRunner_getFinalContent, _AbstractChatCompletionRunner_getFinalMessage, _AbstractChatCompletionRunner_getFinalFunctionToolCall, _AbstractChatCompletionRunner_getFinalFunctionToolCallResult, _AbstractChatCompletionRunner_calculateTotalUsage, _AbstractChatCompletionRunner_validateParams, _AbstractChatCompletionRunner_stringifyFunctionCallResult; +const DEFAULT_MAX_CHAT_COMPLETIONS = 10; +class AbstractChatCompletionRunner extends EventStream { + constructor() { + super(...arguments); + _AbstractChatCompletionRunner_instances.add(this); + this._chatCompletions = []; + this.messages = []; + } + _addChatCompletion(chatCompletion) { + this._chatCompletions.push(chatCompletion); + this._emit('chatCompletion', chatCompletion); + const message = chatCompletion.choices[0]?.message; + if (message) + this._addMessage(message); + return chatCompletion; + } + _addMessage(message, emit = true) { + if (!('content' in message)) + message.content = null; + this.messages.push(message); + if (emit) { + this._emit('message', message); + if (isToolMessage(message) && message.content) { + // Note, this assumes that {role: 'tool', content: …} is always the result of a call of tool of type=function. + this._emit('functionToolCallResult', message.content); + } + else if (isAssistantMessage(message) && message.tool_calls) { + for (const tool_call of message.tool_calls) { + if (tool_call.type === 'function') { + this._emit('functionToolCall', tool_call.function); + } + } + } + } + } + /** + * @returns a promise that resolves with the final ChatCompletion, or rejects + * if an error occurred or the stream ended prematurely without producing a ChatCompletion. + */ + async finalChatCompletion() { + await this.done(); + const completion = this._chatCompletions[this._chatCompletions.length - 1]; + if (!completion) + throw new OpenAIError('stream ended without producing a ChatCompletion'); + return completion; + } + /** + * @returns a promise that resolves with the content of the final ChatCompletionMessage, or rejects + * if an error occurred or the stream ended prematurely without producing a ChatCompletionMessage. + */ + async finalContent() { + await this.done(); + return __classPrivateFieldGet(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalContent).call(this); + } + /** + * @returns a promise that resolves with the the final assistant ChatCompletionMessage response, + * or rejects if an error occurred or the stream ended prematurely without producing a ChatCompletionMessage. + */ + async finalMessage() { + await this.done(); + return __classPrivateFieldGet(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalMessage).call(this); + } + /** + * @returns a promise that resolves with the content of the final FunctionCall, or rejects + * if an error occurred or the stream ended prematurely without producing a ChatCompletionMessage. + */ + async finalFunctionToolCall() { + await this.done(); + return __classPrivateFieldGet(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalFunctionToolCall).call(this); + } + async finalFunctionToolCallResult() { + await this.done(); + return __classPrivateFieldGet(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalFunctionToolCallResult).call(this); + } + async totalUsage() { + await this.done(); + return __classPrivateFieldGet(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_calculateTotalUsage).call(this); + } + allChatCompletions() { + return [...this._chatCompletions]; + } + _emitFinal() { + const completion = this._chatCompletions[this._chatCompletions.length - 1]; + if (completion) + this._emit('finalChatCompletion', completion); + const finalMessage = __classPrivateFieldGet(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalMessage).call(this); + if (finalMessage) + this._emit('finalMessage', finalMessage); + const finalContent = __classPrivateFieldGet(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalContent).call(this); + if (finalContent) + this._emit('finalContent', finalContent); + const finalFunctionCall = __classPrivateFieldGet(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalFunctionToolCall).call(this); + if (finalFunctionCall) + this._emit('finalFunctionToolCall', finalFunctionCall); + const finalFunctionCallResult = __classPrivateFieldGet(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalFunctionToolCallResult).call(this); + if (finalFunctionCallResult != null) + this._emit('finalFunctionToolCallResult', finalFunctionCallResult); + if (this._chatCompletions.some((c) => c.usage)) { + this._emit('totalUsage', __classPrivateFieldGet(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_calculateTotalUsage).call(this)); + } + } + async _createChatCompletion(client, params, options) { + const signal = options?.signal; + if (signal) { + if (signal.aborted) + this.controller.abort(); + signal.addEventListener('abort', () => this.controller.abort()); + } + __classPrivateFieldGet(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_validateParams).call(this, params); + const chatCompletion = await client.chat.completions.create({ ...params, stream: false }, { ...options, signal: this.controller.signal }); + this._connected(); + return this._addChatCompletion(parseChatCompletion(chatCompletion, params)); + } + async _runChatCompletion(client, params, options) { + for (const message of params.messages) { + this._addMessage(message, false); + } + return await this._createChatCompletion(client, params, options); + } + async _runTools(client, params, options) { + const role = 'tool'; + const { tool_choice = 'auto', stream, ...restParams } = params; + const singleFunctionToCall = typeof tool_choice !== 'string' && tool_choice.type === 'function' && tool_choice?.function?.name; + const { maxChatCompletions = DEFAULT_MAX_CHAT_COMPLETIONS } = options || {}; + // TODO(someday): clean this logic up + const inputTools = params.tools.map((tool) => { + if (isAutoParsableTool$1(tool)) { + if (!tool.$callback) { + throw new OpenAIError('Tool given to `.runTools()` that does not have an associated function'); + } + return { + type: 'function', + function: { + function: tool.$callback, + name: tool.function.name, + description: tool.function.description || '', + parameters: tool.function.parameters, + parse: tool.$parseRaw, + strict: true, + }, + }; + } + return tool; + }); + const functionsByName = {}; + for (const f of inputTools) { + if (f.type === 'function') { + functionsByName[f.function.name || f.function.function.name] = f.function; + } + } + const tools = 'tools' in params ? + inputTools.map((t) => t.type === 'function' ? + { + type: 'function', + function: { + name: t.function.name || t.function.function.name, + parameters: t.function.parameters, + description: t.function.description, + strict: t.function.strict, + }, + } + : t) + : undefined; + for (const message of params.messages) { + this._addMessage(message, false); + } + for (let i = 0; i < maxChatCompletions; ++i) { + const chatCompletion = await this._createChatCompletion(client, { + ...restParams, + tool_choice, + tools, + messages: [...this.messages], + }, options); + const message = chatCompletion.choices[0]?.message; + if (!message) { + throw new OpenAIError(`missing message in ChatCompletion response`); + } + if (!message.tool_calls?.length) { + return; + } + for (const tool_call of message.tool_calls) { + if (tool_call.type !== 'function') + continue; + const tool_call_id = tool_call.id; + const { name, arguments: args } = tool_call.function; + const fn = functionsByName[name]; + if (!fn) { + const content = `Invalid tool_call: ${JSON.stringify(name)}. Available options are: ${Object.keys(functionsByName) + .map((name) => JSON.stringify(name)) + .join(', ')}. Please try again`; + this._addMessage({ role, tool_call_id, content }); + continue; + } + else if (singleFunctionToCall && singleFunctionToCall !== name) { + const content = `Invalid tool_call: ${JSON.stringify(name)}. ${JSON.stringify(singleFunctionToCall)} requested. Please try again`; + this._addMessage({ role, tool_call_id, content }); + continue; + } + let parsed; + try { + parsed = isRunnableFunctionWithParse(fn) ? await fn.parse(args) : args; + } + catch (error) { + const content = error instanceof Error ? error.message : String(error); + this._addMessage({ role, tool_call_id, content }); + continue; + } + // @ts-expect-error it can't rule out `never` type. + const rawContent = await fn.function(parsed, this); + const content = __classPrivateFieldGet(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_stringifyFunctionCallResult).call(this, rawContent); + this._addMessage({ role, tool_call_id, content }); + if (singleFunctionToCall) { + return; + } + } + } + return; + } +} +_AbstractChatCompletionRunner_instances = new WeakSet(), _AbstractChatCompletionRunner_getFinalContent = function _AbstractChatCompletionRunner_getFinalContent() { + return __classPrivateFieldGet(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalMessage).call(this).content ?? null; +}, _AbstractChatCompletionRunner_getFinalMessage = function _AbstractChatCompletionRunner_getFinalMessage() { + let i = this.messages.length; + while (i-- > 0) { + const message = this.messages[i]; + if (isAssistantMessage(message)) { + // TODO: support audio here + const ret = { + ...message, + content: message.content ?? null, + refusal: message.refusal ?? null, + }; + return ret; + } + } + throw new OpenAIError('stream ended without producing a ChatCompletionMessage with role=assistant'); +}, _AbstractChatCompletionRunner_getFinalFunctionToolCall = function _AbstractChatCompletionRunner_getFinalFunctionToolCall() { + for (let i = this.messages.length - 1; i >= 0; i--) { + const message = this.messages[i]; + if (isAssistantMessage(message) && message?.tool_calls?.length) { + return message.tool_calls.filter((x) => x.type === 'function').at(-1)?.function; + } + } + return; +}, _AbstractChatCompletionRunner_getFinalFunctionToolCallResult = function _AbstractChatCompletionRunner_getFinalFunctionToolCallResult() { + for (let i = this.messages.length - 1; i >= 0; i--) { + const message = this.messages[i]; + if (isToolMessage(message) && + message.content != null && + typeof message.content === 'string' && + this.messages.some((x) => x.role === 'assistant' && + x.tool_calls?.some((y) => y.type === 'function' && y.id === message.tool_call_id))) { + return message.content; + } + } + return; +}, _AbstractChatCompletionRunner_calculateTotalUsage = function _AbstractChatCompletionRunner_calculateTotalUsage() { + const total = { + completion_tokens: 0, + prompt_tokens: 0, + total_tokens: 0, + }; + for (const { usage } of this._chatCompletions) { + if (usage) { + total.completion_tokens += usage.completion_tokens; + total.prompt_tokens += usage.prompt_tokens; + total.total_tokens += usage.total_tokens; + } + } + return total; +}, _AbstractChatCompletionRunner_validateParams = function _AbstractChatCompletionRunner_validateParams(params) { + if (params.n != null && params.n > 1) { + throw new OpenAIError('ChatCompletion convenience helpers only support n=1 at this time. To use n>1, please use chat.completions.create() directly.'); + } +}, _AbstractChatCompletionRunner_stringifyFunctionCallResult = function _AbstractChatCompletionRunner_stringifyFunctionCallResult(rawContent) { + return (typeof rawContent === 'string' ? rawContent + : rawContent === undefined ? 'undefined' + : JSON.stringify(rawContent)); +}; + +class ChatCompletionRunner extends AbstractChatCompletionRunner { + static runTools(client, params, options) { + const runner = new ChatCompletionRunner(); + const opts = { + ...options, + headers: { ...options?.headers, 'X-Stainless-Helper-Method': 'runTools' }, + }; + runner._run(() => runner._runTools(client, params, opts)); + return runner; + } + _addMessage(message, emit = true) { + super._addMessage(message, emit); + if (isAssistantMessage(message) && message.content) { + this._emit('content', message.content); + } + } +} + +const STR = 0b000000001; +const NUM = 0b000000010; +const ARR = 0b000000100; +const OBJ = 0b000001000; +const NULL = 0b000010000; +const BOOL = 0b000100000; +const NAN = 0b001000000; +const INFINITY = 0b010000000; +const MINUS_INFINITY = 0b100000000; +const INF = INFINITY | MINUS_INFINITY; +const SPECIAL = NULL | BOOL | INF | NAN; +const ATOM = STR | NUM | SPECIAL; +const COLLECTION = ARR | OBJ; +const ALL = ATOM | COLLECTION; +const Allow = { + STR, + NUM, + ARR, + OBJ, + NULL, + BOOL, + NAN, + INFINITY, + MINUS_INFINITY, + INF, + SPECIAL, + ATOM, + COLLECTION, + ALL, +}; +// The JSON string segment was unable to be parsed completely +class PartialJSON extends Error { +} +class MalformedJSON extends Error { +} +/** + * Parse incomplete JSON + * @param {string} jsonString Partial JSON to be parsed + * @param {number} allowPartial Specify what types are allowed to be partial, see {@link Allow} for details + * @returns The parsed JSON + * @throws {PartialJSON} If the JSON is incomplete (related to the `allow` parameter) + * @throws {MalformedJSON} If the JSON is malformed + */ +function parseJSON(jsonString, allowPartial = Allow.ALL) { + if (typeof jsonString !== 'string') { + throw new TypeError(`expecting str, got ${typeof jsonString}`); + } + if (!jsonString.trim()) { + throw new Error(`${jsonString} is empty`); + } + return _parseJSON(jsonString.trim(), allowPartial); +} +const _parseJSON = (jsonString, allow) => { + const length = jsonString.length; + let index = 0; + const markPartialJSON = (msg) => { + throw new PartialJSON(`${msg} at position ${index}`); + }; + const throwMalformedError = (msg) => { + throw new MalformedJSON(`${msg} at position ${index}`); + }; + const parseAny = () => { + skipBlank(); + if (index >= length) + markPartialJSON('Unexpected end of input'); + if (jsonString[index] === '"') + return parseStr(); + if (jsonString[index] === '{') + return parseObj(); + if (jsonString[index] === '[') + return parseArr(); + if (jsonString.substring(index, index + 4) === 'null' || + (Allow.NULL & allow && length - index < 4 && 'null'.startsWith(jsonString.substring(index)))) { + index += 4; + return null; + } + if (jsonString.substring(index, index + 4) === 'true' || + (Allow.BOOL & allow && length - index < 4 && 'true'.startsWith(jsonString.substring(index)))) { + index += 4; + return true; + } + if (jsonString.substring(index, index + 5) === 'false' || + (Allow.BOOL & allow && length - index < 5 && 'false'.startsWith(jsonString.substring(index)))) { + index += 5; + return false; + } + if (jsonString.substring(index, index + 8) === 'Infinity' || + (Allow.INFINITY & allow && length - index < 8 && 'Infinity'.startsWith(jsonString.substring(index)))) { + index += 8; + return Infinity; + } + if (jsonString.substring(index, index + 9) === '-Infinity' || + (Allow.MINUS_INFINITY & allow && + 1 < length - index && + length - index < 9 && + '-Infinity'.startsWith(jsonString.substring(index)))) { + index += 9; + return -Infinity; + } + if (jsonString.substring(index, index + 3) === 'NaN' || + (Allow.NAN & allow && length - index < 3 && 'NaN'.startsWith(jsonString.substring(index)))) { + index += 3; + return NaN; + } + return parseNum(); + }; + const parseStr = () => { + const start = index; + let escape = false; + index++; // skip initial quote + while (index < length && (jsonString[index] !== '"' || (escape && jsonString[index - 1] === '\\'))) { + escape = jsonString[index] === '\\' ? !escape : false; + index++; + } + if (jsonString.charAt(index) == '"') { + try { + return JSON.parse(jsonString.substring(start, ++index - Number(escape))); + } + catch (e) { + throwMalformedError(String(e)); + } + } + else if (Allow.STR & allow) { + try { + return JSON.parse(jsonString.substring(start, index - Number(escape)) + '"'); + } + catch (e) { + // SyntaxError: Invalid escape sequence + return JSON.parse(jsonString.substring(start, jsonString.lastIndexOf('\\')) + '"'); + } + } + markPartialJSON('Unterminated string literal'); + }; + const parseObj = () => { + index++; // skip initial brace + skipBlank(); + const obj = {}; + try { + while (jsonString[index] !== '}') { + skipBlank(); + if (index >= length && Allow.OBJ & allow) + return obj; + const key = parseStr(); + skipBlank(); + index++; // skip colon + try { + const value = parseAny(); + Object.defineProperty(obj, key, { value, writable: true, enumerable: true, configurable: true }); + } + catch (e) { + if (Allow.OBJ & allow) + return obj; + else + throw e; + } + skipBlank(); + if (jsonString[index] === ',') + index++; // skip comma + } + } + catch (e) { + if (Allow.OBJ & allow) + return obj; + else + markPartialJSON("Expected '}' at end of object"); + } + index++; // skip final brace + return obj; + }; + const parseArr = () => { + index++; // skip initial bracket + const arr = []; + try { + while (jsonString[index] !== ']') { + arr.push(parseAny()); + skipBlank(); + if (jsonString[index] === ',') { + index++; // skip comma + } + } + } + catch (e) { + if (Allow.ARR & allow) { + return arr; + } + markPartialJSON("Expected ']' at end of array"); + } + index++; // skip final bracket + return arr; + }; + const parseNum = () => { + if (index === 0) { + if (jsonString === '-' && Allow.NUM & allow) + markPartialJSON("Not sure what '-' is"); + try { + return JSON.parse(jsonString); + } + catch (e) { + if (Allow.NUM & allow) { + try { + if ('.' === jsonString[jsonString.length - 1]) + return JSON.parse(jsonString.substring(0, jsonString.lastIndexOf('.'))); + return JSON.parse(jsonString.substring(0, jsonString.lastIndexOf('e'))); + } + catch (e) { } + } + throwMalformedError(String(e)); + } + } + const start = index; + if (jsonString[index] === '-') + index++; + while (jsonString[index] && !',]}'.includes(jsonString[index])) + index++; + if (index == length && !(Allow.NUM & allow)) + markPartialJSON('Unterminated number literal'); + try { + return JSON.parse(jsonString.substring(start, index)); + } + catch (e) { + if (jsonString.substring(start, index) === '-' && Allow.NUM & allow) + markPartialJSON("Not sure what '-' is"); + try { + return JSON.parse(jsonString.substring(start, jsonString.lastIndexOf('e'))); + } + catch (e) { + throwMalformedError(String(e)); + } + } + }; + const skipBlank = () => { + while (index < length && ' \n\r\t'.includes(jsonString[index])) { + index++; + } + }; + return parseAny(); +}; +// using this function with malformed JSON is undefined behavior +const partialParse = (input) => parseJSON(input, Allow.ALL ^ Allow.NUM); + +var _ChatCompletionStream_instances, _ChatCompletionStream_params, _ChatCompletionStream_choiceEventStates, _ChatCompletionStream_currentChatCompletionSnapshot, _ChatCompletionStream_beginRequest, _ChatCompletionStream_getChoiceEventState, _ChatCompletionStream_addChunk, _ChatCompletionStream_emitToolCallDoneEvent, _ChatCompletionStream_emitContentDoneEvents, _ChatCompletionStream_endRequest, _ChatCompletionStream_getAutoParseableResponseFormat, _ChatCompletionStream_accumulateChatCompletion; +class ChatCompletionStream extends AbstractChatCompletionRunner { + constructor(params) { + super(); + _ChatCompletionStream_instances.add(this); + _ChatCompletionStream_params.set(this, void 0); + _ChatCompletionStream_choiceEventStates.set(this, void 0); + _ChatCompletionStream_currentChatCompletionSnapshot.set(this, void 0); + __classPrivateFieldSet(this, _ChatCompletionStream_params, params); + __classPrivateFieldSet(this, _ChatCompletionStream_choiceEventStates, []); + } + get currentChatCompletionSnapshot() { + return __classPrivateFieldGet(this, _ChatCompletionStream_currentChatCompletionSnapshot, "f"); + } + /** + * Intended for use on the frontend, consuming a stream produced with + * `.toReadableStream()` on the backend. + * + * Note that messages sent to the model do not appear in `.on('message')` + * in this context. + */ + static fromReadableStream(stream) { + const runner = new ChatCompletionStream(null); + runner._run(() => runner._fromReadableStream(stream)); + return runner; + } + static createChatCompletion(client, params, options) { + const runner = new ChatCompletionStream(params); + runner._run(() => runner._runChatCompletion(client, { ...params, stream: true }, { ...options, headers: { ...options?.headers, 'X-Stainless-Helper-Method': 'stream' } })); + return runner; + } + async _createChatCompletion(client, params, options) { + super._createChatCompletion; + const signal = options?.signal; + if (signal) { + if (signal.aborted) + this.controller.abort(); + signal.addEventListener('abort', () => this.controller.abort()); + } + __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_beginRequest).call(this); + const stream = await client.chat.completions.create({ ...params, stream: true }, { ...options, signal: this.controller.signal }); + this._connected(); + for await (const chunk of stream) { + __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_addChunk).call(this, chunk); + } + if (stream.controller.signal?.aborted) { + throw new APIUserAbortError(); + } + return this._addChatCompletion(__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_endRequest).call(this)); + } + async _fromReadableStream(readableStream, options) { + const signal = options?.signal; + if (signal) { + if (signal.aborted) + this.controller.abort(); + signal.addEventListener('abort', () => this.controller.abort()); + } + __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_beginRequest).call(this); + this._connected(); + const stream = Stream.fromReadableStream(readableStream, this.controller); + let chatId; + for await (const chunk of stream) { + if (chatId && chatId !== chunk.id) { + // A new request has been made. + this._addChatCompletion(__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_endRequest).call(this)); + } + __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_addChunk).call(this, chunk); + chatId = chunk.id; + } + if (stream.controller.signal?.aborted) { + throw new APIUserAbortError(); + } + return this._addChatCompletion(__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_endRequest).call(this)); + } + [(_ChatCompletionStream_params = new WeakMap(), _ChatCompletionStream_choiceEventStates = new WeakMap(), _ChatCompletionStream_currentChatCompletionSnapshot = new WeakMap(), _ChatCompletionStream_instances = new WeakSet(), _ChatCompletionStream_beginRequest = function _ChatCompletionStream_beginRequest() { + if (this.ended) + return; + __classPrivateFieldSet(this, _ChatCompletionStream_currentChatCompletionSnapshot, undefined); + }, _ChatCompletionStream_getChoiceEventState = function _ChatCompletionStream_getChoiceEventState(choice) { + let state = __classPrivateFieldGet(this, _ChatCompletionStream_choiceEventStates, "f")[choice.index]; + if (state) { + return state; + } + state = { + content_done: false, + refusal_done: false, + logprobs_content_done: false, + logprobs_refusal_done: false, + done_tool_calls: new Set(), + current_tool_call_index: null, + }; + __classPrivateFieldGet(this, _ChatCompletionStream_choiceEventStates, "f")[choice.index] = state; + return state; + }, _ChatCompletionStream_addChunk = function _ChatCompletionStream_addChunk(chunk) { + if (this.ended) + return; + const completion = __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_accumulateChatCompletion).call(this, chunk); + this._emit('chunk', chunk, completion); + for (const choice of chunk.choices) { + const choiceSnapshot = completion.choices[choice.index]; + if (choice.delta.content != null && + choiceSnapshot.message?.role === 'assistant' && + choiceSnapshot.message?.content) { + this._emit('content', choice.delta.content, choiceSnapshot.message.content); + this._emit('content.delta', { + delta: choice.delta.content, + snapshot: choiceSnapshot.message.content, + parsed: choiceSnapshot.message.parsed, + }); + } + if (choice.delta.refusal != null && + choiceSnapshot.message?.role === 'assistant' && + choiceSnapshot.message?.refusal) { + this._emit('refusal.delta', { + delta: choice.delta.refusal, + snapshot: choiceSnapshot.message.refusal, + }); + } + if (choice.logprobs?.content != null && choiceSnapshot.message?.role === 'assistant') { + this._emit('logprobs.content.delta', { + content: choice.logprobs?.content, + snapshot: choiceSnapshot.logprobs?.content ?? [], + }); + } + if (choice.logprobs?.refusal != null && choiceSnapshot.message?.role === 'assistant') { + this._emit('logprobs.refusal.delta', { + refusal: choice.logprobs?.refusal, + snapshot: choiceSnapshot.logprobs?.refusal ?? [], + }); + } + const state = __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getChoiceEventState).call(this, choiceSnapshot); + if (choiceSnapshot.finish_reason) { + __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_emitContentDoneEvents).call(this, choiceSnapshot); + if (state.current_tool_call_index != null) { + __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_emitToolCallDoneEvent).call(this, choiceSnapshot, state.current_tool_call_index); + } + } + for (const toolCall of choice.delta.tool_calls ?? []) { + if (state.current_tool_call_index !== toolCall.index) { + __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_emitContentDoneEvents).call(this, choiceSnapshot); + // new tool call started, the previous one is done + if (state.current_tool_call_index != null) { + __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_emitToolCallDoneEvent).call(this, choiceSnapshot, state.current_tool_call_index); + } + } + state.current_tool_call_index = toolCall.index; + } + for (const toolCallDelta of choice.delta.tool_calls ?? []) { + const toolCallSnapshot = choiceSnapshot.message.tool_calls?.[toolCallDelta.index]; + if (!toolCallSnapshot?.type) { + continue; + } + if (toolCallSnapshot?.type === 'function') { + this._emit('tool_calls.function.arguments.delta', { + name: toolCallSnapshot.function?.name, + index: toolCallDelta.index, + arguments: toolCallSnapshot.function.arguments, + parsed_arguments: toolCallSnapshot.function.parsed_arguments, + arguments_delta: toolCallDelta.function?.arguments ?? '', + }); + } + else { + assertNever(toolCallSnapshot?.type); + } + } + } + }, _ChatCompletionStream_emitToolCallDoneEvent = function _ChatCompletionStream_emitToolCallDoneEvent(choiceSnapshot, toolCallIndex) { + const state = __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getChoiceEventState).call(this, choiceSnapshot); + if (state.done_tool_calls.has(toolCallIndex)) { + // we've already fired the done event + return; + } + const toolCallSnapshot = choiceSnapshot.message.tool_calls?.[toolCallIndex]; + if (!toolCallSnapshot) { + throw new Error('no tool call snapshot'); + } + if (!toolCallSnapshot.type) { + throw new Error('tool call snapshot missing `type`'); + } + if (toolCallSnapshot.type === 'function') { + const inputTool = __classPrivateFieldGet(this, _ChatCompletionStream_params, "f")?.tools?.find((tool) => isChatCompletionFunctionTool(tool) && tool.function.name === toolCallSnapshot.function.name); // TS doesn't narrow based on isChatCompletionTool + this._emit('tool_calls.function.arguments.done', { + name: toolCallSnapshot.function.name, + index: toolCallIndex, + arguments: toolCallSnapshot.function.arguments, + parsed_arguments: isAutoParsableTool$1(inputTool) ? inputTool.$parseRaw(toolCallSnapshot.function.arguments) + : inputTool?.function.strict ? JSON.parse(toolCallSnapshot.function.arguments) + : null, + }); + } + else { + assertNever(toolCallSnapshot.type); + } + }, _ChatCompletionStream_emitContentDoneEvents = function _ChatCompletionStream_emitContentDoneEvents(choiceSnapshot) { + const state = __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getChoiceEventState).call(this, choiceSnapshot); + if (choiceSnapshot.message.content && !state.content_done) { + state.content_done = true; + const responseFormat = __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getAutoParseableResponseFormat).call(this); + this._emit('content.done', { + content: choiceSnapshot.message.content, + parsed: responseFormat ? responseFormat.$parseRaw(choiceSnapshot.message.content) : null, + }); + } + if (choiceSnapshot.message.refusal && !state.refusal_done) { + state.refusal_done = true; + this._emit('refusal.done', { refusal: choiceSnapshot.message.refusal }); + } + if (choiceSnapshot.logprobs?.content && !state.logprobs_content_done) { + state.logprobs_content_done = true; + this._emit('logprobs.content.done', { content: choiceSnapshot.logprobs.content }); + } + if (choiceSnapshot.logprobs?.refusal && !state.logprobs_refusal_done) { + state.logprobs_refusal_done = true; + this._emit('logprobs.refusal.done', { refusal: choiceSnapshot.logprobs.refusal }); + } + }, _ChatCompletionStream_endRequest = function _ChatCompletionStream_endRequest() { + if (this.ended) { + throw new OpenAIError(`stream has ended, this shouldn't happen`); + } + const snapshot = __classPrivateFieldGet(this, _ChatCompletionStream_currentChatCompletionSnapshot, "f"); + if (!snapshot) { + throw new OpenAIError(`request ended without sending any chunks`); + } + __classPrivateFieldSet(this, _ChatCompletionStream_currentChatCompletionSnapshot, undefined); + __classPrivateFieldSet(this, _ChatCompletionStream_choiceEventStates, []); + return finalizeChatCompletion(snapshot, __classPrivateFieldGet(this, _ChatCompletionStream_params, "f")); + }, _ChatCompletionStream_getAutoParseableResponseFormat = function _ChatCompletionStream_getAutoParseableResponseFormat() { + const responseFormat = __classPrivateFieldGet(this, _ChatCompletionStream_params, "f")?.response_format; + if (isAutoParsableResponseFormat(responseFormat)) { + return responseFormat; + } + return null; + }, _ChatCompletionStream_accumulateChatCompletion = function _ChatCompletionStream_accumulateChatCompletion(chunk) { + var _a, _b, _c, _d; + let snapshot = __classPrivateFieldGet(this, _ChatCompletionStream_currentChatCompletionSnapshot, "f"); + const { choices, ...rest } = chunk; + if (!snapshot) { + snapshot = __classPrivateFieldSet(this, _ChatCompletionStream_currentChatCompletionSnapshot, { + ...rest, + choices: [], + }); + } + else { + Object.assign(snapshot, rest); + } + for (const { delta, finish_reason, index, logprobs = null, ...other } of chunk.choices) { + let choice = snapshot.choices[index]; + if (!choice) { + choice = snapshot.choices[index] = { finish_reason, index, message: {}, logprobs, ...other }; + } + if (logprobs) { + if (!choice.logprobs) { + choice.logprobs = Object.assign({}, logprobs); + } + else { + const { content, refusal, ...rest } = logprobs; + Object.assign(choice.logprobs, rest); + if (content) { + (_a = choice.logprobs).content ?? (_a.content = []); + choice.logprobs.content.push(...content); + } + if (refusal) { + (_b = choice.logprobs).refusal ?? (_b.refusal = []); + choice.logprobs.refusal.push(...refusal); + } + } + } + if (finish_reason) { + choice.finish_reason = finish_reason; + if (__classPrivateFieldGet(this, _ChatCompletionStream_params, "f") && hasAutoParseableInput$1(__classPrivateFieldGet(this, _ChatCompletionStream_params, "f"))) { + if (finish_reason === 'length') { + throw new LengthFinishReasonError(); + } + if (finish_reason === 'content_filter') { + throw new ContentFilterFinishReasonError(); + } + } + } + Object.assign(choice, other); + if (!delta) + continue; // Shouldn't happen; just in case. + const { content, refusal, function_call, role, tool_calls, ...rest } = delta; + Object.assign(choice.message, rest); + if (refusal) { + choice.message.refusal = (choice.message.refusal || '') + refusal; + } + if (role) + choice.message.role = role; + if (function_call) { + if (!choice.message.function_call) { + choice.message.function_call = function_call; + } + else { + if (function_call.name) + choice.message.function_call.name = function_call.name; + if (function_call.arguments) { + (_c = choice.message.function_call).arguments ?? (_c.arguments = ''); + choice.message.function_call.arguments += function_call.arguments; + } + } + } + if (content) { + choice.message.content = (choice.message.content || '') + content; + if (!choice.message.refusal && __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getAutoParseableResponseFormat).call(this)) { + choice.message.parsed = partialParse(choice.message.content); + } + } + if (tool_calls) { + if (!choice.message.tool_calls) + choice.message.tool_calls = []; + for (const { index, id, type, function: fn, ...rest } of tool_calls) { + const tool_call = ((_d = choice.message.tool_calls)[index] ?? (_d[index] = {})); + Object.assign(tool_call, rest); + if (id) + tool_call.id = id; + if (type) + tool_call.type = type; + if (fn) + tool_call.function ?? (tool_call.function = { name: fn.name ?? '', arguments: '' }); + if (fn?.name) + tool_call.function.name = fn.name; + if (fn?.arguments) { + tool_call.function.arguments += fn.arguments; + if (shouldParseToolCall(__classPrivateFieldGet(this, _ChatCompletionStream_params, "f"), tool_call)) { + tool_call.function.parsed_arguments = partialParse(tool_call.function.arguments); + } + } + } + } + } + return snapshot; + }, Symbol.asyncIterator)]() { + const pushQueue = []; + const readQueue = []; + let done = false; + this.on('chunk', (chunk) => { + const reader = readQueue.shift(); + if (reader) { + reader.resolve(chunk); + } + else { + pushQueue.push(chunk); + } + }); + this.on('end', () => { + done = true; + for (const reader of readQueue) { + reader.resolve(undefined); + } + readQueue.length = 0; + }); + this.on('abort', (err) => { + done = true; + for (const reader of readQueue) { + reader.reject(err); + } + readQueue.length = 0; + }); + this.on('error', (err) => { + done = true; + for (const reader of readQueue) { + reader.reject(err); + } + readQueue.length = 0; + }); + return { + next: async () => { + if (!pushQueue.length) { + if (done) { + return { value: undefined, done: true }; + } + return new Promise((resolve, reject) => readQueue.push({ resolve, reject })).then((chunk) => (chunk ? { value: chunk, done: false } : { value: undefined, done: true })); + } + const chunk = pushQueue.shift(); + return { value: chunk, done: false }; + }, + return: async () => { + this.abort(); + return { value: undefined, done: true }; + }, + }; + } + toReadableStream() { + const stream = new Stream(this[Symbol.asyncIterator].bind(this), this.controller); + return stream.toReadableStream(); + } +} +function finalizeChatCompletion(snapshot, params) { + const { id, choices, created, model, system_fingerprint, ...rest } = snapshot; + const completion = { + ...rest, + id, + choices: choices.map(({ message, finish_reason, index, logprobs, ...choiceRest }) => { + if (!finish_reason) { + throw new OpenAIError(`missing finish_reason for choice ${index}`); + } + const { content = null, function_call, tool_calls, ...messageRest } = message; + const role = message.role; // this is what we expect; in theory it could be different which would make our types a slight lie but would be fine. + if (!role) { + throw new OpenAIError(`missing role for choice ${index}`); + } + if (function_call) { + const { arguments: args, name } = function_call; + if (args == null) { + throw new OpenAIError(`missing function_call.arguments for choice ${index}`); + } + if (!name) { + throw new OpenAIError(`missing function_call.name for choice ${index}`); + } + return { + ...choiceRest, + message: { + content, + function_call: { arguments: args, name }, + role, + refusal: message.refusal ?? null, + }, + finish_reason, + index, + logprobs, + }; + } + if (tool_calls) { + return { + ...choiceRest, + index, + finish_reason, + logprobs, + message: { + ...messageRest, + role, + content, + refusal: message.refusal ?? null, + tool_calls: tool_calls.map((tool_call, i) => { + const { function: fn, type, id, ...toolRest } = tool_call; + const { arguments: args, name, ...fnRest } = fn || {}; + if (id == null) { + throw new OpenAIError(`missing choices[${index}].tool_calls[${i}].id\n${str(snapshot)}`); + } + if (type == null) { + throw new OpenAIError(`missing choices[${index}].tool_calls[${i}].type\n${str(snapshot)}`); + } + if (name == null) { + throw new OpenAIError(`missing choices[${index}].tool_calls[${i}].function.name\n${str(snapshot)}`); + } + if (args == null) { + throw new OpenAIError(`missing choices[${index}].tool_calls[${i}].function.arguments\n${str(snapshot)}`); + } + return { ...toolRest, id, type, function: { ...fnRest, name, arguments: args } }; + }), + }, + }; + } + return { + ...choiceRest, + message: { ...messageRest, content, role, refusal: message.refusal ?? null }, + finish_reason, + index, + logprobs, + }; + }), + created, + model, + object: 'chat.completion', + ...(system_fingerprint ? { system_fingerprint } : {}), + }; + return maybeParseChatCompletion(completion, params); +} +function str(x) { + return JSON.stringify(x); +} +function assertNever(_x) { } + +class ChatCompletionStreamingRunner extends ChatCompletionStream { + static fromReadableStream(stream) { + const runner = new ChatCompletionStreamingRunner(null); + runner._run(() => runner._fromReadableStream(stream)); + return runner; + } + static runTools(client, params, options) { + const runner = new ChatCompletionStreamingRunner( + // @ts-expect-error TODO these types are incompatible + params); + const opts = { + ...options, + headers: { ...options?.headers, 'X-Stainless-Helper-Method': 'runTools' }, + }; + runner._run(() => runner._runTools(client, params, opts)); + return runner; + } +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +let Completions$1 = class Completions extends APIResource { + constructor() { + super(...arguments); + this.messages = new Messages$1(this._client); + } + create(body, options) { + return this._client.post('/chat/completions', { body, ...options, stream: body.stream ?? false }); + } + /** + * Get a stored chat completion. Only Chat Completions that have been created with + * the `store` parameter set to `true` will be returned. + * + * @example + * ```ts + * const chatCompletion = + * await client.chat.completions.retrieve('completion_id'); + * ``` + */ + retrieve(completionID, options) { + return this._client.get(path `/chat/completions/${completionID}`, options); + } + /** + * Modify a stored chat completion. Only Chat Completions that have been created + * with the `store` parameter set to `true` can be modified. Currently, the only + * supported modification is to update the `metadata` field. + * + * @example + * ```ts + * const chatCompletion = await client.chat.completions.update( + * 'completion_id', + * { metadata: { foo: 'string' } }, + * ); + * ``` + */ + update(completionID, body, options) { + return this._client.post(path `/chat/completions/${completionID}`, { body, ...options }); + } + /** + * List stored Chat Completions. Only Chat Completions that have been stored with + * the `store` parameter set to `true` will be returned. + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const chatCompletion of client.chat.completions.list()) { + * // ... + * } + * ``` + */ + list(query = {}, options) { + return this._client.getAPIList('/chat/completions', (CursorPage), { query, ...options }); + } + /** + * Delete a stored chat completion. Only Chat Completions that have been created + * with the `store` parameter set to `true` can be deleted. + * + * @example + * ```ts + * const chatCompletionDeleted = + * await client.chat.completions.delete('completion_id'); + * ``` + */ + delete(completionID, options) { + return this._client.delete(path `/chat/completions/${completionID}`, options); + } + parse(body, options) { + validateInputTools(body.tools); + return this._client.chat.completions + .create(body, { + ...options, + headers: { + ...options?.headers, + 'X-Stainless-Helper-Method': 'chat.completions.parse', + }, + }) + ._thenUnwrap((completion) => parseChatCompletion(completion, body)); + } + runTools(body, options) { + if (body.stream) { + return ChatCompletionStreamingRunner.runTools(this._client, body, options); + } + return ChatCompletionRunner.runTools(this._client, body, options); + } + /** + * Creates a chat completion stream + */ + stream(body, options) { + return ChatCompletionStream.createChatCompletion(this._client, body, options); + } +}; +Completions$1.Messages = Messages$1; + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Chat extends APIResource { + constructor() { + super(...arguments); + this.completions = new Completions$1(this._client); + } +} +Chat.Completions = Completions$1; + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +const brand_privateNullableHeaders = /* @__PURE__ */ Symbol('brand.privateNullableHeaders'); +function* iterateHeaders(headers) { + if (!headers) + return; + if (brand_privateNullableHeaders in headers) { + const { values, nulls } = headers; + yield* values.entries(); + for (const name of nulls) { + yield [name, null]; + } + return; + } + let shouldClear = false; + let iter; + if (headers instanceof Headers) { + iter = headers.entries(); + } + else if (isReadonlyArray(headers)) { + iter = headers; + } + else { + shouldClear = true; + iter = Object.entries(headers ?? {}); + } + for (let row of iter) { + const name = row[0]; + if (typeof name !== 'string') + throw new TypeError('expected header name to be a string'); + const values = isReadonlyArray(row[1]) ? row[1] : [row[1]]; + let didClear = false; + for (const value of values) { + if (value === undefined) + continue; + // Objects keys always overwrite older headers, they never append. + // Yield a null to clear the header before adding the new values. + if (shouldClear && !didClear) { + didClear = true; + yield [name, null]; + } + yield [name, value]; + } + } +} +const buildHeaders = (newHeaders) => { + const targetHeaders = new Headers(); + const nullHeaders = new Set(); + for (const headers of newHeaders) { + const seenHeaders = new Set(); + for (const [name, value] of iterateHeaders(headers)) { + const lowerName = name.toLowerCase(); + if (!seenHeaders.has(lowerName)) { + targetHeaders.delete(name); + seenHeaders.add(lowerName); + } + if (value === null) { + targetHeaders.delete(name); + nullHeaders.add(lowerName); + } + else { + targetHeaders.append(name, value); + nullHeaders.delete(lowerName); + } + } + } + return { [brand_privateNullableHeaders]: true, values: targetHeaders, nulls: nullHeaders }; +}; + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Speech extends APIResource { + /** + * Generates audio from the input text. + * + * @example + * ```ts + * const speech = await client.audio.speech.create({ + * input: 'input', + * model: 'string', + * voice: 'ash', + * }); + * + * const content = await speech.blob(); + * console.log(content); + * ``` + */ + create(body, options) { + return this._client.post('/audio/speech', { + body, + ...options, + headers: buildHeaders([{ Accept: 'application/octet-stream' }, options?.headers]), + __binaryResponse: true, + }); + } +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Transcriptions extends APIResource { + create(body, options) { + return this._client.post('/audio/transcriptions', multipartFormRequestOptions({ + body, + ...options, + stream: body.stream ?? false, + __metadata: { model: body.model }, + }, this._client)); + } +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Translations extends APIResource { + create(body, options) { + return this._client.post('/audio/translations', multipartFormRequestOptions({ body, ...options, __metadata: { model: body.model } }, this._client)); + } +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Audio extends APIResource { + constructor() { + super(...arguments); + this.transcriptions = new Transcriptions(this._client); + this.translations = new Translations(this._client); + this.speech = new Speech(this._client); + } +} +Audio.Transcriptions = Transcriptions; +Audio.Translations = Translations; +Audio.Speech = Speech; + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Batches extends APIResource { + /** + * Creates and executes a batch from an uploaded file of requests + */ + create(body, options) { + return this._client.post('/batches', { body, ...options }); + } + /** + * Retrieves a batch. + */ + retrieve(batchID, options) { + return this._client.get(path `/batches/${batchID}`, options); + } + /** + * List your organization's batches. + */ + list(query = {}, options) { + return this._client.getAPIList('/batches', (CursorPage), { query, ...options }); + } + /** + * Cancels an in-progress batch. The batch will be in status `cancelling` for up to + * 10 minutes, before changing to `cancelled`, where it will have partial results + * (if any) available in the output file. + */ + cancel(batchID, options) { + return this._client.post(path `/batches/${batchID}/cancel`, options); + } +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Assistants extends APIResource { + /** + * Create an assistant with a model and instructions. + * + * @example + * ```ts + * const assistant = await client.beta.assistants.create({ + * model: 'gpt-4o', + * }); + * ``` + */ + create(body, options) { + return this._client.post('/assistants', { + body, + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } + /** + * Retrieves an assistant. + * + * @example + * ```ts + * const assistant = await client.beta.assistants.retrieve( + * 'assistant_id', + * ); + * ``` + */ + retrieve(assistantID, options) { + return this._client.get(path `/assistants/${assistantID}`, { + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } + /** + * Modifies an assistant. + * + * @example + * ```ts + * const assistant = await client.beta.assistants.update( + * 'assistant_id', + * ); + * ``` + */ + update(assistantID, body, options) { + return this._client.post(path `/assistants/${assistantID}`, { + body, + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } + /** + * Returns a list of assistants. + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const assistant of client.beta.assistants.list()) { + * // ... + * } + * ``` + */ + list(query = {}, options) { + return this._client.getAPIList('/assistants', (CursorPage), { + query, + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } + /** + * Delete an assistant. + * + * @example + * ```ts + * const assistantDeleted = + * await client.beta.assistants.delete('assistant_id'); + * ``` + */ + delete(assistantID, options) { + return this._client.delete(path `/assistants/${assistantID}`, { + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Sessions extends APIResource { + /** + * Create an ephemeral API token for use in client-side applications with the + * Realtime API. Can be configured with the same session parameters as the + * `session.update` client event. + * + * It responds with a session object, plus a `client_secret` key which contains a + * usable ephemeral API token that can be used to authenticate browser clients for + * the Realtime API. + * + * @example + * ```ts + * const session = + * await client.beta.realtime.sessions.create(); + * ``` + */ + create(body, options) { + return this._client.post('/realtime/sessions', { + body, + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class TranscriptionSessions extends APIResource { + /** + * Create an ephemeral API token for use in client-side applications with the + * Realtime API specifically for realtime transcriptions. Can be configured with + * the same session parameters as the `transcription_session.update` client event. + * + * It responds with a session object, plus a `client_secret` key which contains a + * usable ephemeral API token that can be used to authenticate browser clients for + * the Realtime API. + * + * @example + * ```ts + * const transcriptionSession = + * await client.beta.realtime.transcriptionSessions.create(); + * ``` + */ + create(body, options) { + return this._client.post('/realtime/transcription_sessions', { + body, + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +/** + * @deprecated Realtime has now launched and is generally available. The old beta API is now deprecated. + */ +let Realtime$1 = class Realtime extends APIResource { + constructor() { + super(...arguments); + this.sessions = new Sessions(this._client); + this.transcriptionSessions = new TranscriptionSessions(this._client); + } +}; +Realtime$1.Sessions = Sessions; +Realtime$1.TranscriptionSessions = TranscriptionSessions; + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +/** + * @deprecated The Assistants API is deprecated in favor of the Responses API + */ +class Messages extends APIResource { + /** + * Create a message. + * + * @deprecated The Assistants API is deprecated in favor of the Responses API + */ + create(threadID, body, options) { + return this._client.post(path `/threads/${threadID}/messages`, { + body, + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } + /** + * Retrieve a message. + * + * @deprecated The Assistants API is deprecated in favor of the Responses API + */ + retrieve(messageID, params, options) { + const { thread_id } = params; + return this._client.get(path `/threads/${thread_id}/messages/${messageID}`, { + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } + /** + * Modifies a message. + * + * @deprecated The Assistants API is deprecated in favor of the Responses API + */ + update(messageID, params, options) { + const { thread_id, ...body } = params; + return this._client.post(path `/threads/${thread_id}/messages/${messageID}`, { + body, + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } + /** + * Returns a list of messages for a given thread. + * + * @deprecated The Assistants API is deprecated in favor of the Responses API + */ + list(threadID, query = {}, options) { + return this._client.getAPIList(path `/threads/${threadID}/messages`, (CursorPage), { + query, + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } + /** + * Deletes a message. + * + * @deprecated The Assistants API is deprecated in favor of the Responses API + */ + delete(messageID, params, options) { + const { thread_id } = params; + return this._client.delete(path `/threads/${thread_id}/messages/${messageID}`, { + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +/** + * @deprecated The Assistants API is deprecated in favor of the Responses API + */ +class Steps extends APIResource { + /** + * Retrieves a run step. + * + * @deprecated The Assistants API is deprecated in favor of the Responses API + */ + retrieve(stepID, params, options) { + const { thread_id, run_id, ...query } = params; + return this._client.get(path `/threads/${thread_id}/runs/${run_id}/steps/${stepID}`, { + query, + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } + /** + * Returns a list of run steps belonging to a run. + * + * @deprecated The Assistants API is deprecated in favor of the Responses API + */ + list(runID, params, options) { + const { thread_id, ...query } = params; + return this._client.getAPIList(path `/threads/${thread_id}/runs/${runID}/steps`, (CursorPage), { + query, + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +/** + * Converts a Base64 encoded string to a Float32Array. + * @param base64Str - The Base64 encoded string. + * @returns An Array of numbers interpreted as Float32 values. + */ +const toFloat32Array = (base64Str) => { + if (typeof Buffer !== 'undefined') { + // for Node.js environment + const buf = Buffer.from(base64Str, 'base64'); + return Array.from(new Float32Array(buf.buffer, buf.byteOffset, buf.length / Float32Array.BYTES_PER_ELEMENT)); + } + else { + // for legacy web platform APIs + const binaryStr = atob(base64Str); + const len = binaryStr.length; + const bytes = new Uint8Array(len); + for (let i = 0; i < len; i++) { + bytes[i] = binaryStr.charCodeAt(i); + } + return Array.from(new Float32Array(bytes.buffer)); + } +}; + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +/** + * Read an environment variable. + * + * Trims beginning and trailing whitespace. + * + * Will return undefined if the environment variable doesn't exist or cannot be accessed. + */ +const readEnv = (env) => { + if (typeof globalThis.process !== 'undefined') { + return globalThis.process.env?.[env]?.trim() ?? undefined; + } + if (typeof globalThis.Deno !== 'undefined') { + return globalThis.Deno.env?.get?.(env)?.trim(); + } + return undefined; +}; + +var _AssistantStream_instances, _a$1, _AssistantStream_events, _AssistantStream_runStepSnapshots, _AssistantStream_messageSnapshots, _AssistantStream_messageSnapshot, _AssistantStream_finalRun, _AssistantStream_currentContentIndex, _AssistantStream_currentContent, _AssistantStream_currentToolCallIndex, _AssistantStream_currentToolCall, _AssistantStream_currentEvent, _AssistantStream_currentRunSnapshot, _AssistantStream_currentRunStepSnapshot, _AssistantStream_addEvent, _AssistantStream_endRequest, _AssistantStream_handleMessage, _AssistantStream_handleRunStep, _AssistantStream_handleEvent, _AssistantStream_accumulateRunStep, _AssistantStream_accumulateMessage, _AssistantStream_accumulateContent, _AssistantStream_handleRun; +class AssistantStream extends EventStream { + constructor() { + super(...arguments); + _AssistantStream_instances.add(this); + //Track all events in a single list for reference + _AssistantStream_events.set(this, []); + //Used to accumulate deltas + //We are accumulating many types so the value here is not strict + _AssistantStream_runStepSnapshots.set(this, {}); + _AssistantStream_messageSnapshots.set(this, {}); + _AssistantStream_messageSnapshot.set(this, void 0); + _AssistantStream_finalRun.set(this, void 0); + _AssistantStream_currentContentIndex.set(this, void 0); + _AssistantStream_currentContent.set(this, void 0); + _AssistantStream_currentToolCallIndex.set(this, void 0); + _AssistantStream_currentToolCall.set(this, void 0); + //For current snapshot methods + _AssistantStream_currentEvent.set(this, void 0); + _AssistantStream_currentRunSnapshot.set(this, void 0); + _AssistantStream_currentRunStepSnapshot.set(this, void 0); + } + [(_AssistantStream_events = new WeakMap(), _AssistantStream_runStepSnapshots = new WeakMap(), _AssistantStream_messageSnapshots = new WeakMap(), _AssistantStream_messageSnapshot = new WeakMap(), _AssistantStream_finalRun = new WeakMap(), _AssistantStream_currentContentIndex = new WeakMap(), _AssistantStream_currentContent = new WeakMap(), _AssistantStream_currentToolCallIndex = new WeakMap(), _AssistantStream_currentToolCall = new WeakMap(), _AssistantStream_currentEvent = new WeakMap(), _AssistantStream_currentRunSnapshot = new WeakMap(), _AssistantStream_currentRunStepSnapshot = new WeakMap(), _AssistantStream_instances = new WeakSet(), Symbol.asyncIterator)]() { + const pushQueue = []; + const readQueue = []; + let done = false; + //Catch all for passing along all events + this.on('event', (event) => { + const reader = readQueue.shift(); + if (reader) { + reader.resolve(event); + } + else { + pushQueue.push(event); + } + }); + this.on('end', () => { + done = true; + for (const reader of readQueue) { + reader.resolve(undefined); + } + readQueue.length = 0; + }); + this.on('abort', (err) => { + done = true; + for (const reader of readQueue) { + reader.reject(err); + } + readQueue.length = 0; + }); + this.on('error', (err) => { + done = true; + for (const reader of readQueue) { + reader.reject(err); + } + readQueue.length = 0; + }); + return { + next: async () => { + if (!pushQueue.length) { + if (done) { + return { value: undefined, done: true }; + } + return new Promise((resolve, reject) => readQueue.push({ resolve, reject })).then((chunk) => (chunk ? { value: chunk, done: false } : { value: undefined, done: true })); + } + const chunk = pushQueue.shift(); + return { value: chunk, done: false }; + }, + return: async () => { + this.abort(); + return { value: undefined, done: true }; + }, + }; + } + static fromReadableStream(stream) { + const runner = new _a$1(); + runner._run(() => runner._fromReadableStream(stream)); + return runner; + } + async _fromReadableStream(readableStream, options) { + const signal = options?.signal; + if (signal) { + if (signal.aborted) + this.controller.abort(); + signal.addEventListener('abort', () => this.controller.abort()); + } + this._connected(); + const stream = Stream.fromReadableStream(readableStream, this.controller); + for await (const event of stream) { + __classPrivateFieldGet(this, _AssistantStream_instances, "m", _AssistantStream_addEvent).call(this, event); + } + if (stream.controller.signal?.aborted) { + throw new APIUserAbortError(); + } + return this._addRun(__classPrivateFieldGet(this, _AssistantStream_instances, "m", _AssistantStream_endRequest).call(this)); + } + toReadableStream() { + const stream = new Stream(this[Symbol.asyncIterator].bind(this), this.controller); + return stream.toReadableStream(); + } + static createToolAssistantStream(runId, runs, params, options) { + const runner = new _a$1(); + runner._run(() => runner._runToolAssistantStream(runId, runs, params, { + ...options, + headers: { ...options?.headers, 'X-Stainless-Helper-Method': 'stream' }, + })); + return runner; + } + async _createToolAssistantStream(run, runId, params, options) { + const signal = options?.signal; + if (signal) { + if (signal.aborted) + this.controller.abort(); + signal.addEventListener('abort', () => this.controller.abort()); + } + const body = { ...params, stream: true }; + const stream = await run.submitToolOutputs(runId, body, { + ...options, + signal: this.controller.signal, + }); + this._connected(); + for await (const event of stream) { + __classPrivateFieldGet(this, _AssistantStream_instances, "m", _AssistantStream_addEvent).call(this, event); + } + if (stream.controller.signal?.aborted) { + throw new APIUserAbortError(); + } + return this._addRun(__classPrivateFieldGet(this, _AssistantStream_instances, "m", _AssistantStream_endRequest).call(this)); + } + static createThreadAssistantStream(params, thread, options) { + const runner = new _a$1(); + runner._run(() => runner._threadAssistantStream(params, thread, { + ...options, + headers: { ...options?.headers, 'X-Stainless-Helper-Method': 'stream' }, + })); + return runner; + } + static createAssistantStream(threadId, runs, params, options) { + const runner = new _a$1(); + runner._run(() => runner._runAssistantStream(threadId, runs, params, { + ...options, + headers: { ...options?.headers, 'X-Stainless-Helper-Method': 'stream' }, + })); + return runner; + } + currentEvent() { + return __classPrivateFieldGet(this, _AssistantStream_currentEvent, "f"); + } + currentRun() { + return __classPrivateFieldGet(this, _AssistantStream_currentRunSnapshot, "f"); + } + currentMessageSnapshot() { + return __classPrivateFieldGet(this, _AssistantStream_messageSnapshot, "f"); + } + currentRunStepSnapshot() { + return __classPrivateFieldGet(this, _AssistantStream_currentRunStepSnapshot, "f"); + } + async finalRunSteps() { + await this.done(); + return Object.values(__classPrivateFieldGet(this, _AssistantStream_runStepSnapshots, "f")); + } + async finalMessages() { + await this.done(); + return Object.values(__classPrivateFieldGet(this, _AssistantStream_messageSnapshots, "f")); + } + async finalRun() { + await this.done(); + if (!__classPrivateFieldGet(this, _AssistantStream_finalRun, "f")) + throw Error('Final run was not received.'); + return __classPrivateFieldGet(this, _AssistantStream_finalRun, "f"); + } + async _createThreadAssistantStream(thread, params, options) { + const signal = options?.signal; + if (signal) { + if (signal.aborted) + this.controller.abort(); + signal.addEventListener('abort', () => this.controller.abort()); + } + const body = { ...params, stream: true }; + const stream = await thread.createAndRun(body, { ...options, signal: this.controller.signal }); + this._connected(); + for await (const event of stream) { + __classPrivateFieldGet(this, _AssistantStream_instances, "m", _AssistantStream_addEvent).call(this, event); + } + if (stream.controller.signal?.aborted) { + throw new APIUserAbortError(); + } + return this._addRun(__classPrivateFieldGet(this, _AssistantStream_instances, "m", _AssistantStream_endRequest).call(this)); + } + async _createAssistantStream(run, threadId, params, options) { + const signal = options?.signal; + if (signal) { + if (signal.aborted) + this.controller.abort(); + signal.addEventListener('abort', () => this.controller.abort()); + } + const body = { ...params, stream: true }; + const stream = await run.create(threadId, body, { ...options, signal: this.controller.signal }); + this._connected(); + for await (const event of stream) { + __classPrivateFieldGet(this, _AssistantStream_instances, "m", _AssistantStream_addEvent).call(this, event); + } + if (stream.controller.signal?.aborted) { + throw new APIUserAbortError(); + } + return this._addRun(__classPrivateFieldGet(this, _AssistantStream_instances, "m", _AssistantStream_endRequest).call(this)); + } + static accumulateDelta(acc, delta) { + for (const [key, deltaValue] of Object.entries(delta)) { + if (!acc.hasOwnProperty(key)) { + acc[key] = deltaValue; + continue; + } + let accValue = acc[key]; + if (accValue === null || accValue === undefined) { + acc[key] = deltaValue; + continue; + } + // We don't accumulate these special properties + if (key === 'index' || key === 'type') { + acc[key] = deltaValue; + continue; + } + // Type-specific accumulation logic + if (typeof accValue === 'string' && typeof deltaValue === 'string') { + accValue += deltaValue; + } + else if (typeof accValue === 'number' && typeof deltaValue === 'number') { + accValue += deltaValue; + } + else if (isObj(accValue) && isObj(deltaValue)) { + accValue = this.accumulateDelta(accValue, deltaValue); + } + else if (Array.isArray(accValue) && Array.isArray(deltaValue)) { + if (accValue.every((x) => typeof x === 'string' || typeof x === 'number')) { + accValue.push(...deltaValue); // Use spread syntax for efficient addition + continue; + } + for (const deltaEntry of deltaValue) { + if (!isObj(deltaEntry)) { + throw new Error(`Expected array delta entry to be an object but got: ${deltaEntry}`); + } + const index = deltaEntry['index']; + if (index == null) { + console.error(deltaEntry); + throw new Error('Expected array delta entry to have an `index` property'); + } + if (typeof index !== 'number') { + throw new Error(`Expected array delta entry \`index\` property to be a number but got ${index}`); + } + const accEntry = accValue[index]; + if (accEntry == null) { + accValue.push(deltaEntry); + } + else { + accValue[index] = this.accumulateDelta(accEntry, deltaEntry); + } + } + continue; + } + else { + throw Error(`Unhandled record type: ${key}, deltaValue: ${deltaValue}, accValue: ${accValue}`); + } + acc[key] = accValue; + } + return acc; + } + _addRun(run) { + return run; + } + async _threadAssistantStream(params, thread, options) { + return await this._createThreadAssistantStream(thread, params, options); + } + async _runAssistantStream(threadId, runs, params, options) { + return await this._createAssistantStream(runs, threadId, params, options); + } + async _runToolAssistantStream(runId, runs, params, options) { + return await this._createToolAssistantStream(runs, runId, params, options); + } +} +_a$1 = AssistantStream, _AssistantStream_addEvent = function _AssistantStream_addEvent(event) { + if (this.ended) + return; + __classPrivateFieldSet(this, _AssistantStream_currentEvent, event); + __classPrivateFieldGet(this, _AssistantStream_instances, "m", _AssistantStream_handleEvent).call(this, event); + switch (event.event) { + case 'thread.created': + //No action on this event. + break; + case 'thread.run.created': + case 'thread.run.queued': + case 'thread.run.in_progress': + case 'thread.run.requires_action': + case 'thread.run.completed': + case 'thread.run.incomplete': + case 'thread.run.failed': + case 'thread.run.cancelling': + case 'thread.run.cancelled': + case 'thread.run.expired': + __classPrivateFieldGet(this, _AssistantStream_instances, "m", _AssistantStream_handleRun).call(this, event); + break; + case 'thread.run.step.created': + case 'thread.run.step.in_progress': + case 'thread.run.step.delta': + case 'thread.run.step.completed': + case 'thread.run.step.failed': + case 'thread.run.step.cancelled': + case 'thread.run.step.expired': + __classPrivateFieldGet(this, _AssistantStream_instances, "m", _AssistantStream_handleRunStep).call(this, event); + break; + case 'thread.message.created': + case 'thread.message.in_progress': + case 'thread.message.delta': + case 'thread.message.completed': + case 'thread.message.incomplete': + __classPrivateFieldGet(this, _AssistantStream_instances, "m", _AssistantStream_handleMessage).call(this, event); + break; + case 'error': + //This is included for completeness, but errors are processed in the SSE event processing so this should not occur + throw new Error('Encountered an error event in event processing - errors should be processed earlier'); + } +}, _AssistantStream_endRequest = function _AssistantStream_endRequest() { + if (this.ended) { + throw new OpenAIError(`stream has ended, this shouldn't happen`); + } + if (!__classPrivateFieldGet(this, _AssistantStream_finalRun, "f")) + throw Error('Final run has not been received'); + return __classPrivateFieldGet(this, _AssistantStream_finalRun, "f"); +}, _AssistantStream_handleMessage = function _AssistantStream_handleMessage(event) { + const [accumulatedMessage, newContent] = __classPrivateFieldGet(this, _AssistantStream_instances, "m", _AssistantStream_accumulateMessage).call(this, event, __classPrivateFieldGet(this, _AssistantStream_messageSnapshot, "f")); + __classPrivateFieldSet(this, _AssistantStream_messageSnapshot, accumulatedMessage); + __classPrivateFieldGet(this, _AssistantStream_messageSnapshots, "f")[accumulatedMessage.id] = accumulatedMessage; + for (const content of newContent) { + const snapshotContent = accumulatedMessage.content[content.index]; + if (snapshotContent?.type == 'text') { + this._emit('textCreated', snapshotContent.text); + } + } + switch (event.event) { + case 'thread.message.created': + this._emit('messageCreated', event.data); + break; + case 'thread.message.in_progress': + break; + case 'thread.message.delta': + this._emit('messageDelta', event.data.delta, accumulatedMessage); + if (event.data.delta.content) { + for (const content of event.data.delta.content) { + //If it is text delta, emit a text delta event + if (content.type == 'text' && content.text) { + let textDelta = content.text; + let snapshot = accumulatedMessage.content[content.index]; + if (snapshot && snapshot.type == 'text') { + this._emit('textDelta', textDelta, snapshot.text); + } + else { + throw Error('The snapshot associated with this text delta is not text or missing'); + } + } + if (content.index != __classPrivateFieldGet(this, _AssistantStream_currentContentIndex, "f")) { + //See if we have in progress content + if (__classPrivateFieldGet(this, _AssistantStream_currentContent, "f")) { + switch (__classPrivateFieldGet(this, _AssistantStream_currentContent, "f").type) { + case 'text': + this._emit('textDone', __classPrivateFieldGet(this, _AssistantStream_currentContent, "f").text, __classPrivateFieldGet(this, _AssistantStream_messageSnapshot, "f")); + break; + case 'image_file': + this._emit('imageFileDone', __classPrivateFieldGet(this, _AssistantStream_currentContent, "f").image_file, __classPrivateFieldGet(this, _AssistantStream_messageSnapshot, "f")); + break; + } + } + __classPrivateFieldSet(this, _AssistantStream_currentContentIndex, content.index); + } + __classPrivateFieldSet(this, _AssistantStream_currentContent, accumulatedMessage.content[content.index]); + } + } + break; + case 'thread.message.completed': + case 'thread.message.incomplete': + //We emit the latest content we were working on on completion (including incomplete) + if (__classPrivateFieldGet(this, _AssistantStream_currentContentIndex, "f") !== undefined) { + const currentContent = event.data.content[__classPrivateFieldGet(this, _AssistantStream_currentContentIndex, "f")]; + if (currentContent) { + switch (currentContent.type) { + case 'image_file': + this._emit('imageFileDone', currentContent.image_file, __classPrivateFieldGet(this, _AssistantStream_messageSnapshot, "f")); + break; + case 'text': + this._emit('textDone', currentContent.text, __classPrivateFieldGet(this, _AssistantStream_messageSnapshot, "f")); + break; + } + } + } + if (__classPrivateFieldGet(this, _AssistantStream_messageSnapshot, "f")) { + this._emit('messageDone', event.data); + } + __classPrivateFieldSet(this, _AssistantStream_messageSnapshot, undefined); + } +}, _AssistantStream_handleRunStep = function _AssistantStream_handleRunStep(event) { + const accumulatedRunStep = __classPrivateFieldGet(this, _AssistantStream_instances, "m", _AssistantStream_accumulateRunStep).call(this, event); + __classPrivateFieldSet(this, _AssistantStream_currentRunStepSnapshot, accumulatedRunStep); + switch (event.event) { + case 'thread.run.step.created': + this._emit('runStepCreated', event.data); + break; + case 'thread.run.step.delta': + const delta = event.data.delta; + if (delta.step_details && + delta.step_details.type == 'tool_calls' && + delta.step_details.tool_calls && + accumulatedRunStep.step_details.type == 'tool_calls') { + for (const toolCall of delta.step_details.tool_calls) { + if (toolCall.index == __classPrivateFieldGet(this, _AssistantStream_currentToolCallIndex, "f")) { + this._emit('toolCallDelta', toolCall, accumulatedRunStep.step_details.tool_calls[toolCall.index]); + } + else { + if (__classPrivateFieldGet(this, _AssistantStream_currentToolCall, "f")) { + this._emit('toolCallDone', __classPrivateFieldGet(this, _AssistantStream_currentToolCall, "f")); + } + __classPrivateFieldSet(this, _AssistantStream_currentToolCallIndex, toolCall.index); + __classPrivateFieldSet(this, _AssistantStream_currentToolCall, accumulatedRunStep.step_details.tool_calls[toolCall.index]); + if (__classPrivateFieldGet(this, _AssistantStream_currentToolCall, "f")) + this._emit('toolCallCreated', __classPrivateFieldGet(this, _AssistantStream_currentToolCall, "f")); + } + } + } + this._emit('runStepDelta', event.data.delta, accumulatedRunStep); + break; + case 'thread.run.step.completed': + case 'thread.run.step.failed': + case 'thread.run.step.cancelled': + case 'thread.run.step.expired': + __classPrivateFieldSet(this, _AssistantStream_currentRunStepSnapshot, undefined); + const details = event.data.step_details; + if (details.type == 'tool_calls') { + if (__classPrivateFieldGet(this, _AssistantStream_currentToolCall, "f")) { + this._emit('toolCallDone', __classPrivateFieldGet(this, _AssistantStream_currentToolCall, "f")); + __classPrivateFieldSet(this, _AssistantStream_currentToolCall, undefined); + } + } + this._emit('runStepDone', event.data, accumulatedRunStep); + break; + } +}, _AssistantStream_handleEvent = function _AssistantStream_handleEvent(event) { + __classPrivateFieldGet(this, _AssistantStream_events, "f").push(event); + this._emit('event', event); +}, _AssistantStream_accumulateRunStep = function _AssistantStream_accumulateRunStep(event) { + switch (event.event) { + case 'thread.run.step.created': + __classPrivateFieldGet(this, _AssistantStream_runStepSnapshots, "f")[event.data.id] = event.data; + return event.data; + case 'thread.run.step.delta': + let snapshot = __classPrivateFieldGet(this, _AssistantStream_runStepSnapshots, "f")[event.data.id]; + if (!snapshot) { + throw Error('Received a RunStepDelta before creation of a snapshot'); + } + let data = event.data; + if (data.delta) { + const accumulated = _a$1.accumulateDelta(snapshot, data.delta); + __classPrivateFieldGet(this, _AssistantStream_runStepSnapshots, "f")[event.data.id] = accumulated; + } + return __classPrivateFieldGet(this, _AssistantStream_runStepSnapshots, "f")[event.data.id]; + case 'thread.run.step.completed': + case 'thread.run.step.failed': + case 'thread.run.step.cancelled': + case 'thread.run.step.expired': + case 'thread.run.step.in_progress': + __classPrivateFieldGet(this, _AssistantStream_runStepSnapshots, "f")[event.data.id] = event.data; + break; + } + if (__classPrivateFieldGet(this, _AssistantStream_runStepSnapshots, "f")[event.data.id]) + return __classPrivateFieldGet(this, _AssistantStream_runStepSnapshots, "f")[event.data.id]; + throw new Error('No snapshot available'); +}, _AssistantStream_accumulateMessage = function _AssistantStream_accumulateMessage(event, snapshot) { + let newContent = []; + switch (event.event) { + case 'thread.message.created': + //On creation the snapshot is just the initial message + return [event.data, newContent]; + case 'thread.message.delta': + if (!snapshot) { + throw Error('Received a delta with no existing snapshot (there should be one from message creation)'); + } + let data = event.data; + //If this delta does not have content, nothing to process + if (data.delta.content) { + for (const contentElement of data.delta.content) { + if (contentElement.index in snapshot.content) { + let currentContent = snapshot.content[contentElement.index]; + snapshot.content[contentElement.index] = __classPrivateFieldGet(this, _AssistantStream_instances, "m", _AssistantStream_accumulateContent).call(this, contentElement, currentContent); + } + else { + snapshot.content[contentElement.index] = contentElement; + // This is a new element + newContent.push(contentElement); + } + } + } + return [snapshot, newContent]; + case 'thread.message.in_progress': + case 'thread.message.completed': + case 'thread.message.incomplete': + //No changes on other thread events + if (snapshot) { + return [snapshot, newContent]; + } + else { + throw Error('Received thread message event with no existing snapshot'); + } + } + throw Error('Tried to accumulate a non-message event'); +}, _AssistantStream_accumulateContent = function _AssistantStream_accumulateContent(contentElement, currentContent) { + return _a$1.accumulateDelta(currentContent, contentElement); +}, _AssistantStream_handleRun = function _AssistantStream_handleRun(event) { + __classPrivateFieldSet(this, _AssistantStream_currentRunSnapshot, event.data); + switch (event.event) { + case 'thread.run.created': + break; + case 'thread.run.queued': + break; + case 'thread.run.in_progress': + break; + case 'thread.run.requires_action': + case 'thread.run.cancelled': + case 'thread.run.failed': + case 'thread.run.completed': + case 'thread.run.expired': + case 'thread.run.incomplete': + __classPrivateFieldSet(this, _AssistantStream_finalRun, event.data); + if (__classPrivateFieldGet(this, _AssistantStream_currentToolCall, "f")) { + this._emit('toolCallDone', __classPrivateFieldGet(this, _AssistantStream_currentToolCall, "f")); + __classPrivateFieldSet(this, _AssistantStream_currentToolCall, undefined); + } + break; + } +}; + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +/** + * @deprecated The Assistants API is deprecated in favor of the Responses API + */ +let Runs$1 = class Runs extends APIResource { + constructor() { + super(...arguments); + this.steps = new Steps(this._client); + } + create(threadID, params, options) { + const { include, ...body } = params; + return this._client.post(path `/threads/${threadID}/runs`, { + query: { include }, + body, + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + stream: params.stream ?? false, + }); + } + /** + * Retrieves a run. + * + * @deprecated The Assistants API is deprecated in favor of the Responses API + */ + retrieve(runID, params, options) { + const { thread_id } = params; + return this._client.get(path `/threads/${thread_id}/runs/${runID}`, { + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } + /** + * Modifies a run. + * + * @deprecated The Assistants API is deprecated in favor of the Responses API + */ + update(runID, params, options) { + const { thread_id, ...body } = params; + return this._client.post(path `/threads/${thread_id}/runs/${runID}`, { + body, + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } + /** + * Returns a list of runs belonging to a thread. + * + * @deprecated The Assistants API is deprecated in favor of the Responses API + */ + list(threadID, query = {}, options) { + return this._client.getAPIList(path `/threads/${threadID}/runs`, (CursorPage), { + query, + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } + /** + * Cancels a run that is `in_progress`. + * + * @deprecated The Assistants API is deprecated in favor of the Responses API + */ + cancel(runID, params, options) { + const { thread_id } = params; + return this._client.post(path `/threads/${thread_id}/runs/${runID}/cancel`, { + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } + /** + * A helper to create a run an poll for a terminal state. More information on Run + * lifecycles can be found here: + * https://platform.openai.com/docs/assistants/how-it-works/runs-and-run-steps + */ + async createAndPoll(threadId, body, options) { + const run = await this.create(threadId, body, options); + return await this.poll(run.id, { thread_id: threadId }, options); + } + /** + * Create a Run stream + * + * @deprecated use `stream` instead + */ + createAndStream(threadId, body, options) { + return AssistantStream.createAssistantStream(threadId, this._client.beta.threads.runs, body, options); + } + /** + * A helper to poll a run status until it reaches a terminal state. More + * information on Run lifecycles can be found here: + * https://platform.openai.com/docs/assistants/how-it-works/runs-and-run-steps + */ + async poll(runId, params, options) { + const headers = buildHeaders([ + options?.headers, + { + 'X-Stainless-Poll-Helper': 'true', + 'X-Stainless-Custom-Poll-Interval': options?.pollIntervalMs?.toString() ?? undefined, + }, + ]); + while (true) { + const { data: run, response } = await this.retrieve(runId, params, { + ...options, + headers: { ...options?.headers, ...headers }, + }).withResponse(); + switch (run.status) { + //If we are in any sort of intermediate state we poll + case 'queued': + case 'in_progress': + case 'cancelling': + let sleepInterval = 5000; + if (options?.pollIntervalMs) { + sleepInterval = options.pollIntervalMs; + } + else { + const headerInterval = response.headers.get('openai-poll-after-ms'); + if (headerInterval) { + const headerIntervalMs = parseInt(headerInterval); + if (!isNaN(headerIntervalMs)) { + sleepInterval = headerIntervalMs; + } + } + } + await sleep(sleepInterval); + break; + //We return the run in any terminal state. + case 'requires_action': + case 'incomplete': + case 'cancelled': + case 'completed': + case 'failed': + case 'expired': + return run; + } + } + } + /** + * Create a Run stream + */ + stream(threadId, body, options) { + return AssistantStream.createAssistantStream(threadId, this._client.beta.threads.runs, body, options); + } + submitToolOutputs(runID, params, options) { + const { thread_id, ...body } = params; + return this._client.post(path `/threads/${thread_id}/runs/${runID}/submit_tool_outputs`, { + body, + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + stream: params.stream ?? false, + }); + } + /** + * A helper to submit a tool output to a run and poll for a terminal run state. + * More information on Run lifecycles can be found here: + * https://platform.openai.com/docs/assistants/how-it-works/runs-and-run-steps + */ + async submitToolOutputsAndPoll(runId, params, options) { + const run = await this.submitToolOutputs(runId, params, options); + return await this.poll(run.id, params, options); + } + /** + * Submit the tool outputs from a previous run and stream the run to a terminal + * state. More information on Run lifecycles can be found here: + * https://platform.openai.com/docs/assistants/how-it-works/runs-and-run-steps + */ + submitToolOutputsStream(runId, params, options) { + return AssistantStream.createToolAssistantStream(runId, this._client.beta.threads.runs, params, options); + } +}; +Runs$1.Steps = Steps; + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +/** + * @deprecated The Assistants API is deprecated in favor of the Responses API + */ +class Threads extends APIResource { + constructor() { + super(...arguments); + this.runs = new Runs$1(this._client); + this.messages = new Messages(this._client); + } + /** + * Create a thread. + * + * @deprecated The Assistants API is deprecated in favor of the Responses API + */ + create(body = {}, options) { + return this._client.post('/threads', { + body, + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } + /** + * Retrieves a thread. + * + * @deprecated The Assistants API is deprecated in favor of the Responses API + */ + retrieve(threadID, options) { + return this._client.get(path `/threads/${threadID}`, { + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } + /** + * Modifies a thread. + * + * @deprecated The Assistants API is deprecated in favor of the Responses API + */ + update(threadID, body, options) { + return this._client.post(path `/threads/${threadID}`, { + body, + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } + /** + * Delete a thread. + * + * @deprecated The Assistants API is deprecated in favor of the Responses API + */ + delete(threadID, options) { + return this._client.delete(path `/threads/${threadID}`, { + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } + createAndRun(body, options) { + return this._client.post('/threads/runs', { + body, + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + stream: body.stream ?? false, + }); + } + /** + * A helper to create a thread, start a run and then poll for a terminal state. + * More information on Run lifecycles can be found here: + * https://platform.openai.com/docs/assistants/how-it-works/runs-and-run-steps + */ + async createAndRunPoll(body, options) { + const run = await this.createAndRun(body, options); + return await this.runs.poll(run.id, { thread_id: run.thread_id }, options); + } + /** + * Create a thread and stream the run back + */ + createAndRunStream(body, options) { + return AssistantStream.createThreadAssistantStream(body, this._client.beta.threads, options); + } +} +Threads.Runs = Runs$1; +Threads.Messages = Messages; + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Beta extends APIResource { + constructor() { + super(...arguments); + this.realtime = new Realtime$1(this._client); + this.assistants = new Assistants(this._client); + this.threads = new Threads(this._client); + } +} +Beta.Realtime = Realtime$1; +Beta.Assistants = Assistants; +Beta.Threads = Threads; + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Completions extends APIResource { + create(body, options) { + return this._client.post('/completions', { body, ...options, stream: body.stream ?? false }); + } +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Content extends APIResource { + /** + * Retrieve Container File Content + */ + retrieve(fileID, params, options) { + const { container_id } = params; + return this._client.get(path `/containers/${container_id}/files/${fileID}/content`, { + ...options, + headers: buildHeaders([{ Accept: 'application/binary' }, options?.headers]), + __binaryResponse: true, + }); + } +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +let Files$2 = class Files extends APIResource { + constructor() { + super(...arguments); + this.content = new Content(this._client); + } + /** + * Create a Container File + * + * You can send either a multipart/form-data request with the raw file content, or + * a JSON request with a file ID. + */ + create(containerID, body, options) { + return this._client.post(path `/containers/${containerID}/files`, multipartFormRequestOptions({ body, ...options }, this._client)); + } + /** + * Retrieve Container File + */ + retrieve(fileID, params, options) { + const { container_id } = params; + return this._client.get(path `/containers/${container_id}/files/${fileID}`, options); + } + /** + * List Container files + */ + list(containerID, query = {}, options) { + return this._client.getAPIList(path `/containers/${containerID}/files`, (CursorPage), { + query, + ...options, + }); + } + /** + * Delete Container File + */ + delete(fileID, params, options) { + const { container_id } = params; + return this._client.delete(path `/containers/${container_id}/files/${fileID}`, { + ...options, + headers: buildHeaders([{ Accept: '*/*' }, options?.headers]), + }); + } +}; +Files$2.Content = Content; + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Containers extends APIResource { + constructor() { + super(...arguments); + this.files = new Files$2(this._client); + } + /** + * Create Container + */ + create(body, options) { + return this._client.post('/containers', { body, ...options }); + } + /** + * Retrieve Container + */ + retrieve(containerID, options) { + return this._client.get(path `/containers/${containerID}`, options); + } + /** + * List Containers + */ + list(query = {}, options) { + return this._client.getAPIList('/containers', (CursorPage), { query, ...options }); + } + /** + * Delete Container + */ + delete(containerID, options) { + return this._client.delete(path `/containers/${containerID}`, { + ...options, + headers: buildHeaders([{ Accept: '*/*' }, options?.headers]), + }); + } +} +Containers.Files = Files$2; + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Items extends APIResource { + /** + * Create items in a conversation with the given ID. + */ + create(conversationID, params, options) { + const { include, ...body } = params; + return this._client.post(path `/conversations/${conversationID}/items`, { + query: { include }, + body, + ...options, + }); + } + /** + * Get a single item from a conversation with the given IDs. + */ + retrieve(itemID, params, options) { + const { conversation_id, ...query } = params; + return this._client.get(path `/conversations/${conversation_id}/items/${itemID}`, { query, ...options }); + } + /** + * List all items for a conversation with the given ID. + */ + list(conversationID, query = {}, options) { + return this._client.getAPIList(path `/conversations/${conversationID}/items`, (ConversationCursorPage), { query, ...options }); + } + /** + * Delete an item from a conversation with the given IDs. + */ + delete(itemID, params, options) { + const { conversation_id } = params; + return this._client.delete(path `/conversations/${conversation_id}/items/${itemID}`, options); + } +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Conversations extends APIResource { + constructor() { + super(...arguments); + this.items = new Items(this._client); + } + /** + * Create a conversation. + */ + create(body = {}, options) { + return this._client.post('/conversations', { body, ...options }); + } + /** + * Get a conversation + */ + retrieve(conversationID, options) { + return this._client.get(path `/conversations/${conversationID}`, options); + } + /** + * Update a conversation + */ + update(conversationID, body, options) { + return this._client.post(path `/conversations/${conversationID}`, { body, ...options }); + } + /** + * Delete a conversation. Items in the conversation will not be deleted. + */ + delete(conversationID, options) { + return this._client.delete(path `/conversations/${conversationID}`, options); + } +} +Conversations.Items = Items; + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Embeddings extends APIResource { + /** + * Creates an embedding vector representing the input text. + * + * @example + * ```ts + * const createEmbeddingResponse = + * await client.embeddings.create({ + * input: 'The quick brown fox jumped over the lazy dog', + * model: 'text-embedding-3-small', + * }); + * ``` + */ + create(body, options) { + const hasUserProvidedEncodingFormat = !!body.encoding_format; + // No encoding_format specified, defaulting to base64 for performance reasons + // See https://github.com/openai/openai-node/pull/1312 + let encoding_format = hasUserProvidedEncodingFormat ? body.encoding_format : 'base64'; + if (hasUserProvidedEncodingFormat) { + loggerFor(this._client).debug('embeddings/user defined encoding_format:', body.encoding_format); + } + const response = this._client.post('/embeddings', { + body: { + ...body, + encoding_format: encoding_format, + }, + ...options, + }); + // if the user specified an encoding_format, return the response as-is + if (hasUserProvidedEncodingFormat) { + return response; + } + // in this stage, we are sure the user did not specify an encoding_format + // and we defaulted to base64 for performance reasons + // we are sure then that the response is base64 encoded, let's decode it + // the returned result will be a float32 array since this is OpenAI API's default encoding + loggerFor(this._client).debug('embeddings/decoding base64 embeddings from base64'); + return response._thenUnwrap((response) => { + if (response && response.data) { + response.data.forEach((embeddingBase64Obj) => { + const embeddingBase64Str = embeddingBase64Obj.embedding; + embeddingBase64Obj.embedding = toFloat32Array(embeddingBase64Str); + }); + } + return response; + }); + } +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class OutputItems extends APIResource { + /** + * Get an evaluation run output item by ID. + */ + retrieve(outputItemID, params, options) { + const { eval_id, run_id } = params; + return this._client.get(path `/evals/${eval_id}/runs/${run_id}/output_items/${outputItemID}`, options); + } + /** + * Get a list of output items for an evaluation run. + */ + list(runID, params, options) { + const { eval_id, ...query } = params; + return this._client.getAPIList(path `/evals/${eval_id}/runs/${runID}/output_items`, (CursorPage), { query, ...options }); + } +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Runs extends APIResource { + constructor() { + super(...arguments); + this.outputItems = new OutputItems(this._client); + } + /** + * Kicks off a new run for a given evaluation, specifying the data source, and what + * model configuration to use to test. The datasource will be validated against the + * schema specified in the config of the evaluation. + */ + create(evalID, body, options) { + return this._client.post(path `/evals/${evalID}/runs`, { body, ...options }); + } + /** + * Get an evaluation run by ID. + */ + retrieve(runID, params, options) { + const { eval_id } = params; + return this._client.get(path `/evals/${eval_id}/runs/${runID}`, options); + } + /** + * Get a list of runs for an evaluation. + */ + list(evalID, query = {}, options) { + return this._client.getAPIList(path `/evals/${evalID}/runs`, (CursorPage), { + query, + ...options, + }); + } + /** + * Delete an eval run. + */ + delete(runID, params, options) { + const { eval_id } = params; + return this._client.delete(path `/evals/${eval_id}/runs/${runID}`, options); + } + /** + * Cancel an ongoing evaluation run. + */ + cancel(runID, params, options) { + const { eval_id } = params; + return this._client.post(path `/evals/${eval_id}/runs/${runID}`, options); + } +} +Runs.OutputItems = OutputItems; + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Evals extends APIResource { + constructor() { + super(...arguments); + this.runs = new Runs(this._client); + } + /** + * Create the structure of an evaluation that can be used to test a model's + * performance. An evaluation is a set of testing criteria and the config for a + * data source, which dictates the schema of the data used in the evaluation. After + * creating an evaluation, you can run it on different models and model parameters. + * We support several types of graders and datasources. For more information, see + * the [Evals guide](https://platform.openai.com/docs/guides/evals). + */ + create(body, options) { + return this._client.post('/evals', { body, ...options }); + } + /** + * Get an evaluation by ID. + */ + retrieve(evalID, options) { + return this._client.get(path `/evals/${evalID}`, options); + } + /** + * Update certain properties of an evaluation. + */ + update(evalID, body, options) { + return this._client.post(path `/evals/${evalID}`, { body, ...options }); + } + /** + * List evaluations for a project. + */ + list(query = {}, options) { + return this._client.getAPIList('/evals', (CursorPage), { query, ...options }); + } + /** + * Delete an evaluation. + */ + delete(evalID, options) { + return this._client.delete(path `/evals/${evalID}`, options); + } +} +Evals.Runs = Runs; + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +let Files$1 = class Files extends APIResource { + /** + * Upload a file that can be used across various endpoints. Individual files can be + * up to 512 MB, and the size of all files uploaded by one organization can be up + * to 1 TB. + * + * The Assistants API supports files up to 2 million tokens and of specific file + * types. See the + * [Assistants Tools guide](https://platform.openai.com/docs/assistants/tools) for + * details. + * + * The Fine-tuning API only supports `.jsonl` files. The input also has certain + * required formats for fine-tuning + * [chat](https://platform.openai.com/docs/api-reference/fine-tuning/chat-input) or + * [completions](https://platform.openai.com/docs/api-reference/fine-tuning/completions-input) + * models. + * + * The Batch API only supports `.jsonl` files up to 200 MB in size. The input also + * has a specific required + * [format](https://platform.openai.com/docs/api-reference/batch/request-input). + * + * Please [contact us](https://help.openai.com/) if you need to increase these + * storage limits. + */ + create(body, options) { + return this._client.post('/files', multipartFormRequestOptions({ body, ...options }, this._client)); + } + /** + * Returns information about a specific file. + */ + retrieve(fileID, options) { + return this._client.get(path `/files/${fileID}`, options); + } + /** + * Returns a list of files. + */ + list(query = {}, options) { + return this._client.getAPIList('/files', (CursorPage), { query, ...options }); + } + /** + * Delete a file. + */ + delete(fileID, options) { + return this._client.delete(path `/files/${fileID}`, options); + } + /** + * Returns the contents of the specified file. + */ + content(fileID, options) { + return this._client.get(path `/files/${fileID}/content`, { + ...options, + headers: buildHeaders([{ Accept: 'application/binary' }, options?.headers]), + __binaryResponse: true, + }); + } + /** + * Waits for the given file to be processed, default timeout is 30 mins. + */ + async waitForProcessing(id, { pollInterval = 5000, maxWait = 30 * 60 * 1000 } = {}) { + const TERMINAL_STATES = new Set(['processed', 'error', 'deleted']); + const start = Date.now(); + let file = await this.retrieve(id); + while (!file.status || !TERMINAL_STATES.has(file.status)) { + await sleep(pollInterval); + file = await this.retrieve(id); + if (Date.now() - start > maxWait) { + throw new APIConnectionTimeoutError({ + message: `Giving up on waiting for file ${id} to finish processing after ${maxWait} milliseconds.`, + }); + } + } + return file; + } +}; + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Methods extends APIResource { +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +let Graders$1 = class Graders extends APIResource { + /** + * Run a grader. + * + * @example + * ```ts + * const response = await client.fineTuning.alpha.graders.run({ + * grader: { + * input: 'input', + * name: 'name', + * operation: 'eq', + * reference: 'reference', + * type: 'string_check', + * }, + * model_sample: 'model_sample', + * }); + * ``` + */ + run(body, options) { + return this._client.post('/fine_tuning/alpha/graders/run', { body, ...options }); + } + /** + * Validate a grader. + * + * @example + * ```ts + * const response = + * await client.fineTuning.alpha.graders.validate({ + * grader: { + * input: 'input', + * name: 'name', + * operation: 'eq', + * reference: 'reference', + * type: 'string_check', + * }, + * }); + * ``` + */ + validate(body, options) { + return this._client.post('/fine_tuning/alpha/graders/validate', { body, ...options }); + } +}; + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Alpha extends APIResource { + constructor() { + super(...arguments); + this.graders = new Graders$1(this._client); + } +} +Alpha.Graders = Graders$1; + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Permissions extends APIResource { + /** + * **NOTE:** Calling this endpoint requires an [admin API key](../admin-api-keys). + * + * This enables organization owners to share fine-tuned models with other projects + * in their organization. + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const permissionCreateResponse of client.fineTuning.checkpoints.permissions.create( + * 'ft:gpt-4o-mini-2024-07-18:org:weather:B7R9VjQd', + * { project_ids: ['string'] }, + * )) { + * // ... + * } + * ``` + */ + create(fineTunedModelCheckpoint, body, options) { + return this._client.getAPIList(path `/fine_tuning/checkpoints/${fineTunedModelCheckpoint}/permissions`, (Page), { body, method: 'post', ...options }); + } + /** + * **NOTE:** This endpoint requires an [admin API key](../admin-api-keys). + * + * Organization owners can use this endpoint to view all permissions for a + * fine-tuned model checkpoint. + * + * @example + * ```ts + * const permission = + * await client.fineTuning.checkpoints.permissions.retrieve( + * 'ft-AF1WoRqd3aJAHsqc9NY7iL8F', + * ); + * ``` + */ + retrieve(fineTunedModelCheckpoint, query = {}, options) { + return this._client.get(path `/fine_tuning/checkpoints/${fineTunedModelCheckpoint}/permissions`, { + query, + ...options, + }); + } + /** + * **NOTE:** This endpoint requires an [admin API key](../admin-api-keys). + * + * Organization owners can use this endpoint to delete a permission for a + * fine-tuned model checkpoint. + * + * @example + * ```ts + * const permission = + * await client.fineTuning.checkpoints.permissions.delete( + * 'cp_zc4Q7MP6XxulcVzj4MZdwsAB', + * { + * fine_tuned_model_checkpoint: + * 'ft:gpt-4o-mini-2024-07-18:org:weather:B7R9VjQd', + * }, + * ); + * ``` + */ + delete(permissionID, params, options) { + const { fine_tuned_model_checkpoint } = params; + return this._client.delete(path `/fine_tuning/checkpoints/${fine_tuned_model_checkpoint}/permissions/${permissionID}`, options); + } +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +let Checkpoints$1 = class Checkpoints extends APIResource { + constructor() { + super(...arguments); + this.permissions = new Permissions(this._client); + } +}; +Checkpoints$1.Permissions = Permissions; + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Checkpoints extends APIResource { + /** + * List checkpoints for a fine-tuning job. + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const fineTuningJobCheckpoint of client.fineTuning.jobs.checkpoints.list( + * 'ft-AF1WoRqd3aJAHsqc9NY7iL8F', + * )) { + * // ... + * } + * ``` + */ + list(fineTuningJobID, query = {}, options) { + return this._client.getAPIList(path `/fine_tuning/jobs/${fineTuningJobID}/checkpoints`, (CursorPage), { query, ...options }); + } +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Jobs extends APIResource { + constructor() { + super(...arguments); + this.checkpoints = new Checkpoints(this._client); + } + /** + * Creates a fine-tuning job which begins the process of creating a new model from + * a given dataset. + * + * Response includes details of the enqueued job including job status and the name + * of the fine-tuned models once complete. + * + * [Learn more about fine-tuning](https://platform.openai.com/docs/guides/model-optimization) + * + * @example + * ```ts + * const fineTuningJob = await client.fineTuning.jobs.create({ + * model: 'gpt-4o-mini', + * training_file: 'file-abc123', + * }); + * ``` + */ + create(body, options) { + return this._client.post('/fine_tuning/jobs', { body, ...options }); + } + /** + * Get info about a fine-tuning job. + * + * [Learn more about fine-tuning](https://platform.openai.com/docs/guides/model-optimization) + * + * @example + * ```ts + * const fineTuningJob = await client.fineTuning.jobs.retrieve( + * 'ft-AF1WoRqd3aJAHsqc9NY7iL8F', + * ); + * ``` + */ + retrieve(fineTuningJobID, options) { + return this._client.get(path `/fine_tuning/jobs/${fineTuningJobID}`, options); + } + /** + * List your organization's fine-tuning jobs + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const fineTuningJob of client.fineTuning.jobs.list()) { + * // ... + * } + * ``` + */ + list(query = {}, options) { + return this._client.getAPIList('/fine_tuning/jobs', (CursorPage), { query, ...options }); + } + /** + * Immediately cancel a fine-tune job. + * + * @example + * ```ts + * const fineTuningJob = await client.fineTuning.jobs.cancel( + * 'ft-AF1WoRqd3aJAHsqc9NY7iL8F', + * ); + * ``` + */ + cancel(fineTuningJobID, options) { + return this._client.post(path `/fine_tuning/jobs/${fineTuningJobID}/cancel`, options); + } + /** + * Get status updates for a fine-tuning job. + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const fineTuningJobEvent of client.fineTuning.jobs.listEvents( + * 'ft-AF1WoRqd3aJAHsqc9NY7iL8F', + * )) { + * // ... + * } + * ``` + */ + listEvents(fineTuningJobID, query = {}, options) { + return this._client.getAPIList(path `/fine_tuning/jobs/${fineTuningJobID}/events`, (CursorPage), { query, ...options }); + } + /** + * Pause a fine-tune job. + * + * @example + * ```ts + * const fineTuningJob = await client.fineTuning.jobs.pause( + * 'ft-AF1WoRqd3aJAHsqc9NY7iL8F', + * ); + * ``` + */ + pause(fineTuningJobID, options) { + return this._client.post(path `/fine_tuning/jobs/${fineTuningJobID}/pause`, options); + } + /** + * Resume a fine-tune job. + * + * @example + * ```ts + * const fineTuningJob = await client.fineTuning.jobs.resume( + * 'ft-AF1WoRqd3aJAHsqc9NY7iL8F', + * ); + * ``` + */ + resume(fineTuningJobID, options) { + return this._client.post(path `/fine_tuning/jobs/${fineTuningJobID}/resume`, options); + } +} +Jobs.Checkpoints = Checkpoints; + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class FineTuning extends APIResource { + constructor() { + super(...arguments); + this.methods = new Methods(this._client); + this.jobs = new Jobs(this._client); + this.checkpoints = new Checkpoints$1(this._client); + this.alpha = new Alpha(this._client); + } +} +FineTuning.Methods = Methods; +FineTuning.Jobs = Jobs; +FineTuning.Checkpoints = Checkpoints$1; +FineTuning.Alpha = Alpha; + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class GraderModels extends APIResource { +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Graders extends APIResource { + constructor() { + super(...arguments); + this.graderModels = new GraderModels(this._client); + } +} +Graders.GraderModels = GraderModels; + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Images extends APIResource { + /** + * Creates a variation of a given image. This endpoint only supports `dall-e-2`. + * + * @example + * ```ts + * const imagesResponse = await client.images.createVariation({ + * image: fs.createReadStream('otter.png'), + * }); + * ``` + */ + createVariation(body, options) { + return this._client.post('/images/variations', multipartFormRequestOptions({ body, ...options }, this._client)); + } + edit(body, options) { + return this._client.post('/images/edits', multipartFormRequestOptions({ body, ...options, stream: body.stream ?? false }, this._client)); + } + generate(body, options) { + return this._client.post('/images/generations', { body, ...options, stream: body.stream ?? false }); + } +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Models extends APIResource { + /** + * Retrieves a model instance, providing basic information about the model such as + * the owner and permissioning. + */ + retrieve(model, options) { + return this._client.get(path `/models/${model}`, options); + } + /** + * Lists the currently available models, and provides basic information about each + * one such as the owner and availability. + */ + list(options) { + return this._client.getAPIList('/models', (Page), options); + } + /** + * Delete a fine-tuned model. You must have the Owner role in your organization to + * delete a model. + */ + delete(model, options) { + return this._client.delete(path `/models/${model}`, options); + } +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Moderations extends APIResource { + /** + * Classifies if text and/or image inputs are potentially harmful. Learn more in + * the [moderation guide](https://platform.openai.com/docs/guides/moderation). + */ + create(body, options) { + return this._client.post('/moderations', { body, ...options }); + } +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Calls extends APIResource { + /** + * Accept an incoming SIP call and configure the realtime session that will handle + * it. + * + * @example + * ```ts + * await client.realtime.calls.accept('call_id', { + * type: 'realtime', + * }); + * ``` + */ + accept(callID, body, options) { + return this._client.post(path `/realtime/calls/${callID}/accept`, { + body, + ...options, + headers: buildHeaders([{ Accept: '*/*' }, options?.headers]), + }); + } + /** + * End an active Realtime API call, whether it was initiated over SIP or WebRTC. + * + * @example + * ```ts + * await client.realtime.calls.hangup('call_id'); + * ``` + */ + hangup(callID, options) { + return this._client.post(path `/realtime/calls/${callID}/hangup`, { + ...options, + headers: buildHeaders([{ Accept: '*/*' }, options?.headers]), + }); + } + /** + * Transfer an active SIP call to a new destination using the SIP REFER verb. + * + * @example + * ```ts + * await client.realtime.calls.refer('call_id', { + * target_uri: 'tel:+14155550123', + * }); + * ``` + */ + refer(callID, body, options) { + return this._client.post(path `/realtime/calls/${callID}/refer`, { + body, + ...options, + headers: buildHeaders([{ Accept: '*/*' }, options?.headers]), + }); + } + /** + * Decline an incoming SIP call by returning a SIP status code to the caller. + * + * @example + * ```ts + * await client.realtime.calls.reject('call_id'); + * ``` + */ + reject(callID, body = {}, options) { + return this._client.post(path `/realtime/calls/${callID}/reject`, { + body, + ...options, + headers: buildHeaders([{ Accept: '*/*' }, options?.headers]), + }); + } +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class ClientSecrets extends APIResource { + /** + * Create a Realtime client secret with an associated session configuration. + * + * @example + * ```ts + * const clientSecret = + * await client.realtime.clientSecrets.create(); + * ``` + */ + create(body, options) { + return this._client.post('/realtime/client_secrets', { body, ...options }); + } +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Realtime extends APIResource { + constructor() { + super(...arguments); + this.clientSecrets = new ClientSecrets(this._client); + this.calls = new Calls(this._client); + } +} +Realtime.ClientSecrets = ClientSecrets; +Realtime.Calls = Calls; + +function maybeParseResponse(response, params) { + if (!params || !hasAutoParseableInput(params)) { + return { + ...response, + output_parsed: null, + output: response.output.map((item) => { + if (item.type === 'function_call') { + return { + ...item, + parsed_arguments: null, + }; + } + if (item.type === 'message') { + return { + ...item, + content: item.content.map((content) => ({ + ...content, + parsed: null, + })), + }; + } + else { + return item; + } + }), + }; + } + return parseResponse(response, params); +} +function parseResponse(response, params) { + const output = response.output.map((item) => { + if (item.type === 'function_call') { + return { + ...item, + parsed_arguments: parseToolCall(params, item), + }; + } + if (item.type === 'message') { + const content = item.content.map((content) => { + if (content.type === 'output_text') { + return { + ...content, + parsed: parseTextFormat(params, content.text), + }; + } + return content; + }); + return { + ...item, + content, + }; + } + return item; + }); + const parsed = Object.assign({}, response, { output }); + if (!Object.getOwnPropertyDescriptor(response, 'output_text')) { + addOutputText(parsed); + } + Object.defineProperty(parsed, 'output_parsed', { + enumerable: true, + get() { + for (const output of parsed.output) { + if (output.type !== 'message') { + continue; + } + for (const content of output.content) { + if (content.type === 'output_text' && content.parsed !== null) { + return content.parsed; + } + } + } + return null; + }, + }); + return parsed; +} +function parseTextFormat(params, content) { + if (params.text?.format?.type !== 'json_schema') { + return null; + } + if ('$parseRaw' in params.text?.format) { + const text_format = params.text?.format; + return text_format.$parseRaw(content); + } + return JSON.parse(content); +} +function hasAutoParseableInput(params) { + if (isAutoParsableResponseFormat(params.text?.format)) { + return true; + } + return false; +} +function isAutoParsableTool(tool) { + return tool?.['$brand'] === 'auto-parseable-tool'; +} +function getInputToolByName(input_tools, name) { + return input_tools.find((tool) => tool.type === 'function' && tool.name === name); +} +function parseToolCall(params, toolCall) { + const inputTool = getInputToolByName(params.tools ?? [], toolCall.name); + return { + ...toolCall, + ...toolCall, + parsed_arguments: isAutoParsableTool(inputTool) ? inputTool.$parseRaw(toolCall.arguments) + : inputTool?.strict ? JSON.parse(toolCall.arguments) + : null, + }; +} +function addOutputText(rsp) { + const texts = []; + for (const output of rsp.output) { + if (output.type !== 'message') { + continue; + } + for (const content of output.content) { + if (content.type === 'output_text') { + texts.push(content.text); + } + } + } + rsp.output_text = texts.join(''); +} + +var _ResponseStream_instances, _ResponseStream_params, _ResponseStream_currentResponseSnapshot, _ResponseStream_finalResponse, _ResponseStream_beginRequest, _ResponseStream_addEvent, _ResponseStream_endRequest, _ResponseStream_accumulateResponse; +class ResponseStream extends EventStream { + constructor(params) { + super(); + _ResponseStream_instances.add(this); + _ResponseStream_params.set(this, void 0); + _ResponseStream_currentResponseSnapshot.set(this, void 0); + _ResponseStream_finalResponse.set(this, void 0); + __classPrivateFieldSet(this, _ResponseStream_params, params); + } + static createResponse(client, params, options) { + const runner = new ResponseStream(params); + runner._run(() => runner._createOrRetrieveResponse(client, params, { + ...options, + headers: { ...options?.headers, 'X-Stainless-Helper-Method': 'stream' }, + })); + return runner; + } + async _createOrRetrieveResponse(client, params, options) { + const signal = options?.signal; + if (signal) { + if (signal.aborted) + this.controller.abort(); + signal.addEventListener('abort', () => this.controller.abort()); + } + __classPrivateFieldGet(this, _ResponseStream_instances, "m", _ResponseStream_beginRequest).call(this); + let stream; + let starting_after = null; + if ('response_id' in params) { + stream = await client.responses.retrieve(params.response_id, { stream: true }, { ...options, signal: this.controller.signal, stream: true }); + starting_after = params.starting_after ?? null; + } + else { + stream = await client.responses.create({ ...params, stream: true }, { ...options, signal: this.controller.signal }); + } + this._connected(); + for await (const event of stream) { + __classPrivateFieldGet(this, _ResponseStream_instances, "m", _ResponseStream_addEvent).call(this, event, starting_after); + } + if (stream.controller.signal?.aborted) { + throw new APIUserAbortError(); + } + return __classPrivateFieldGet(this, _ResponseStream_instances, "m", _ResponseStream_endRequest).call(this); + } + [(_ResponseStream_params = new WeakMap(), _ResponseStream_currentResponseSnapshot = new WeakMap(), _ResponseStream_finalResponse = new WeakMap(), _ResponseStream_instances = new WeakSet(), _ResponseStream_beginRequest = function _ResponseStream_beginRequest() { + if (this.ended) + return; + __classPrivateFieldSet(this, _ResponseStream_currentResponseSnapshot, undefined); + }, _ResponseStream_addEvent = function _ResponseStream_addEvent(event, starting_after) { + if (this.ended) + return; + const maybeEmit = (name, event) => { + if (starting_after == null || event.sequence_number > starting_after) { + this._emit(name, event); + } + }; + const response = __classPrivateFieldGet(this, _ResponseStream_instances, "m", _ResponseStream_accumulateResponse).call(this, event); + maybeEmit('event', event); + switch (event.type) { + case 'response.output_text.delta': { + const output = response.output[event.output_index]; + if (!output) { + throw new OpenAIError(`missing output at index ${event.output_index}`); + } + if (output.type === 'message') { + const content = output.content[event.content_index]; + if (!content) { + throw new OpenAIError(`missing content at index ${event.content_index}`); + } + if (content.type !== 'output_text') { + throw new OpenAIError(`expected content to be 'output_text', got ${content.type}`); + } + maybeEmit('response.output_text.delta', { + ...event, + snapshot: content.text, + }); + } + break; + } + case 'response.function_call_arguments.delta': { + const output = response.output[event.output_index]; + if (!output) { + throw new OpenAIError(`missing output at index ${event.output_index}`); + } + if (output.type === 'function_call') { + maybeEmit('response.function_call_arguments.delta', { + ...event, + snapshot: output.arguments, + }); + } + break; + } + default: + maybeEmit(event.type, event); + break; + } + }, _ResponseStream_endRequest = function _ResponseStream_endRequest() { + if (this.ended) { + throw new OpenAIError(`stream has ended, this shouldn't happen`); + } + const snapshot = __classPrivateFieldGet(this, _ResponseStream_currentResponseSnapshot, "f"); + if (!snapshot) { + throw new OpenAIError(`request ended without sending any events`); + } + __classPrivateFieldSet(this, _ResponseStream_currentResponseSnapshot, undefined); + const parsedResponse = finalizeResponse(snapshot, __classPrivateFieldGet(this, _ResponseStream_params, "f")); + __classPrivateFieldSet(this, _ResponseStream_finalResponse, parsedResponse); + return parsedResponse; + }, _ResponseStream_accumulateResponse = function _ResponseStream_accumulateResponse(event) { + let snapshot = __classPrivateFieldGet(this, _ResponseStream_currentResponseSnapshot, "f"); + if (!snapshot) { + if (event.type !== 'response.created') { + throw new OpenAIError(`When snapshot hasn't been set yet, expected 'response.created' event, got ${event.type}`); + } + snapshot = __classPrivateFieldSet(this, _ResponseStream_currentResponseSnapshot, event.response); + return snapshot; + } + switch (event.type) { + case 'response.output_item.added': { + snapshot.output.push(event.item); + break; + } + case 'response.content_part.added': { + const output = snapshot.output[event.output_index]; + if (!output) { + throw new OpenAIError(`missing output at index ${event.output_index}`); + } + const type = output.type; + const part = event.part; + if (type === 'message' && part.type !== 'reasoning_text') { + output.content.push(part); + } + else if (type === 'reasoning' && part.type === 'reasoning_text') { + if (!output.content) { + output.content = []; + } + output.content.push(part); + } + break; + } + case 'response.output_text.delta': { + const output = snapshot.output[event.output_index]; + if (!output) { + throw new OpenAIError(`missing output at index ${event.output_index}`); + } + if (output.type === 'message') { + const content = output.content[event.content_index]; + if (!content) { + throw new OpenAIError(`missing content at index ${event.content_index}`); + } + if (content.type !== 'output_text') { + throw new OpenAIError(`expected content to be 'output_text', got ${content.type}`); + } + content.text += event.delta; + } + break; + } + case 'response.function_call_arguments.delta': { + const output = snapshot.output[event.output_index]; + if (!output) { + throw new OpenAIError(`missing output at index ${event.output_index}`); + } + if (output.type === 'function_call') { + output.arguments += event.delta; + } + break; + } + case 'response.reasoning_text.delta': { + const output = snapshot.output[event.output_index]; + if (!output) { + throw new OpenAIError(`missing output at index ${event.output_index}`); + } + if (output.type === 'reasoning') { + const content = output.content?.[event.content_index]; + if (!content) { + throw new OpenAIError(`missing content at index ${event.content_index}`); + } + if (content.type !== 'reasoning_text') { + throw new OpenAIError(`expected content to be 'reasoning_text', got ${content.type}`); + } + content.text += event.delta; + } + break; + } + case 'response.completed': { + __classPrivateFieldSet(this, _ResponseStream_currentResponseSnapshot, event.response); + break; + } + } + return snapshot; + }, Symbol.asyncIterator)]() { + const pushQueue = []; + const readQueue = []; + let done = false; + this.on('event', (event) => { + const reader = readQueue.shift(); + if (reader) { + reader.resolve(event); + } + else { + pushQueue.push(event); + } + }); + this.on('end', () => { + done = true; + for (const reader of readQueue) { + reader.resolve(undefined); + } + readQueue.length = 0; + }); + this.on('abort', (err) => { + done = true; + for (const reader of readQueue) { + reader.reject(err); + } + readQueue.length = 0; + }); + this.on('error', (err) => { + done = true; + for (const reader of readQueue) { + reader.reject(err); + } + readQueue.length = 0; + }); + return { + next: async () => { + if (!pushQueue.length) { + if (done) { + return { value: undefined, done: true }; + } + return new Promise((resolve, reject) => readQueue.push({ resolve, reject })).then((event) => (event ? { value: event, done: false } : { value: undefined, done: true })); + } + const event = pushQueue.shift(); + return { value: event, done: false }; + }, + return: async () => { + this.abort(); + return { value: undefined, done: true }; + }, + }; + } + /** + * @returns a promise that resolves with the final Response, or rejects + * if an error occurred or the stream ended prematurely without producing a REsponse. + */ + async finalResponse() { + await this.done(); + const response = __classPrivateFieldGet(this, _ResponseStream_finalResponse, "f"); + if (!response) + throw new OpenAIError('stream ended without producing a ChatCompletion'); + return response; + } +} +function finalizeResponse(snapshot, params) { + return maybeParseResponse(snapshot, params); +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class InputItems extends APIResource { + /** + * Returns a list of input items for a given response. + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const responseItem of client.responses.inputItems.list( + * 'response_id', + * )) { + * // ... + * } + * ``` + */ + list(responseID, query = {}, options) { + return this._client.getAPIList(path `/responses/${responseID}/input_items`, (CursorPage), { query, ...options }); + } +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Responses extends APIResource { + constructor() { + super(...arguments); + this.inputItems = new InputItems(this._client); + } + create(body, options) { + return this._client.post('/responses', { body, ...options, stream: body.stream ?? false })._thenUnwrap((rsp) => { + if ('object' in rsp && rsp.object === 'response') { + addOutputText(rsp); + } + return rsp; + }); + } + retrieve(responseID, query = {}, options) { + return this._client.get(path `/responses/${responseID}`, { + query, + ...options, + stream: query?.stream ?? false, + })._thenUnwrap((rsp) => { + if ('object' in rsp && rsp.object === 'response') { + addOutputText(rsp); + } + return rsp; + }); + } + /** + * Deletes a model response with the given ID. + * + * @example + * ```ts + * await client.responses.delete( + * 'resp_677efb5139a88190b512bc3fef8e535d', + * ); + * ``` + */ + delete(responseID, options) { + return this._client.delete(path `/responses/${responseID}`, { + ...options, + headers: buildHeaders([{ Accept: '*/*' }, options?.headers]), + }); + } + parse(body, options) { + return this._client.responses + .create(body, options) + ._thenUnwrap((response) => parseResponse(response, body)); + } + /** + * Creates a model response stream + */ + stream(body, options) { + return ResponseStream.createResponse(this._client, body, options); + } + /** + * Cancels a model response with the given ID. Only responses created with the + * `background` parameter set to `true` can be cancelled. + * [Learn more](https://platform.openai.com/docs/guides/background). + * + * @example + * ```ts + * const response = await client.responses.cancel( + * 'resp_677efb5139a88190b512bc3fef8e535d', + * ); + * ``` + */ + cancel(responseID, options) { + return this._client.post(path `/responses/${responseID}/cancel`, options); + } +} +Responses.InputItems = InputItems; + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Parts extends APIResource { + /** + * Adds a + * [Part](https://platform.openai.com/docs/api-reference/uploads/part-object) to an + * [Upload](https://platform.openai.com/docs/api-reference/uploads/object) object. + * A Part represents a chunk of bytes from the file you are trying to upload. + * + * Each Part can be at most 64 MB, and you can add Parts until you hit the Upload + * maximum of 8 GB. + * + * It is possible to add multiple Parts in parallel. You can decide the intended + * order of the Parts when you + * [complete the Upload](https://platform.openai.com/docs/api-reference/uploads/complete). + */ + create(uploadID, body, options) { + return this._client.post(path `/uploads/${uploadID}/parts`, multipartFormRequestOptions({ body, ...options }, this._client)); + } +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Uploads extends APIResource { + constructor() { + super(...arguments); + this.parts = new Parts(this._client); + } + /** + * Creates an intermediate + * [Upload](https://platform.openai.com/docs/api-reference/uploads/object) object + * that you can add + * [Parts](https://platform.openai.com/docs/api-reference/uploads/part-object) to. + * Currently, an Upload can accept at most 8 GB in total and expires after an hour + * after you create it. + * + * Once you complete the Upload, we will create a + * [File](https://platform.openai.com/docs/api-reference/files/object) object that + * contains all the parts you uploaded. This File is usable in the rest of our + * platform as a regular File object. + * + * For certain `purpose` values, the correct `mime_type` must be specified. Please + * refer to documentation for the + * [supported MIME types for your use case](https://platform.openai.com/docs/assistants/tools/file-search#supported-files). + * + * For guidance on the proper filename extensions for each purpose, please follow + * the documentation on + * [creating a File](https://platform.openai.com/docs/api-reference/files/create). + */ + create(body, options) { + return this._client.post('/uploads', { body, ...options }); + } + /** + * Cancels the Upload. No Parts may be added after an Upload is cancelled. + */ + cancel(uploadID, options) { + return this._client.post(path `/uploads/${uploadID}/cancel`, options); + } + /** + * Completes the + * [Upload](https://platform.openai.com/docs/api-reference/uploads/object). + * + * Within the returned Upload object, there is a nested + * [File](https://platform.openai.com/docs/api-reference/files/object) object that + * is ready to use in the rest of the platform. + * + * You can specify the order of the Parts by passing in an ordered list of the Part + * IDs. + * + * The number of bytes uploaded upon completion must match the number of bytes + * initially specified when creating the Upload object. No Parts may be added after + * an Upload is completed. + */ + complete(uploadID, body, options) { + return this._client.post(path `/uploads/${uploadID}/complete`, { body, ...options }); + } +} +Uploads.Parts = Parts; + +/** + * Like `Promise.allSettled()` but throws an error if any promises are rejected. + */ +const allSettledWithThrow = async (promises) => { + const results = await Promise.allSettled(promises); + const rejected = results.filter((result) => result.status === 'rejected'); + if (rejected.length) { + for (const result of rejected) { + console.error(result.reason); + } + throw new Error(`${rejected.length} promise(s) failed - see the above errors`); + } + // Note: TS was complaining about using `.filter().map()` here for some reason + const values = []; + for (const result of results) { + if (result.status === 'fulfilled') { + values.push(result.value); + } + } + return values; +}; + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class FileBatches extends APIResource { + /** + * Create a vector store file batch. + */ + create(vectorStoreID, body, options) { + return this._client.post(path `/vector_stores/${vectorStoreID}/file_batches`, { + body, + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } + /** + * Retrieves a vector store file batch. + */ + retrieve(batchID, params, options) { + const { vector_store_id } = params; + return this._client.get(path `/vector_stores/${vector_store_id}/file_batches/${batchID}`, { + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } + /** + * Cancel a vector store file batch. This attempts to cancel the processing of + * files in this batch as soon as possible. + */ + cancel(batchID, params, options) { + const { vector_store_id } = params; + return this._client.post(path `/vector_stores/${vector_store_id}/file_batches/${batchID}/cancel`, { + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } + /** + * Create a vector store batch and poll until all files have been processed. + */ + async createAndPoll(vectorStoreId, body, options) { + const batch = await this.create(vectorStoreId, body); + return await this.poll(vectorStoreId, batch.id, options); + } + /** + * Returns a list of vector store files in a batch. + */ + listFiles(batchID, params, options) { + const { vector_store_id, ...query } = params; + return this._client.getAPIList(path `/vector_stores/${vector_store_id}/file_batches/${batchID}/files`, (CursorPage), { query, ...options, headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]) }); + } + /** + * Wait for the given file batch to be processed. + * + * Note: this will return even if one of the files failed to process, you need to + * check batch.file_counts.failed_count to handle this case. + */ + async poll(vectorStoreID, batchID, options) { + const headers = buildHeaders([ + options?.headers, + { + 'X-Stainless-Poll-Helper': 'true', + 'X-Stainless-Custom-Poll-Interval': options?.pollIntervalMs?.toString() ?? undefined, + }, + ]); + while (true) { + const { data: batch, response } = await this.retrieve(batchID, { vector_store_id: vectorStoreID }, { + ...options, + headers, + }).withResponse(); + switch (batch.status) { + case 'in_progress': + let sleepInterval = 5000; + if (options?.pollIntervalMs) { + sleepInterval = options.pollIntervalMs; + } + else { + const headerInterval = response.headers.get('openai-poll-after-ms'); + if (headerInterval) { + const headerIntervalMs = parseInt(headerInterval); + if (!isNaN(headerIntervalMs)) { + sleepInterval = headerIntervalMs; + } + } + } + await sleep(sleepInterval); + break; + case 'failed': + case 'cancelled': + case 'completed': + return batch; + } + } + } + /** + * Uploads the given files concurrently and then creates a vector store file batch. + * + * The concurrency limit is configurable using the `maxConcurrency` parameter. + */ + async uploadAndPoll(vectorStoreId, { files, fileIds = [] }, options) { + if (files == null || files.length == 0) { + throw new Error(`No \`files\` provided to process. If you've already uploaded files you should use \`.createAndPoll()\` instead`); + } + const configuredConcurrency = options?.maxConcurrency ?? 5; + // We cap the number of workers at the number of files (so we don't start any unnecessary workers) + const concurrencyLimit = Math.min(configuredConcurrency, files.length); + const client = this._client; + const fileIterator = files.values(); + const allFileIds = [...fileIds]; + // This code is based on this design. The libraries don't accommodate our environment limits. + // https://stackoverflow.com/questions/40639432/what-is-the-best-way-to-limit-concurrency-when-using-es6s-promise-all + async function processFiles(iterator) { + for (let item of iterator) { + const fileObj = await client.files.create({ file: item, purpose: 'assistants' }, options); + allFileIds.push(fileObj.id); + } + } + // Start workers to process results + const workers = Array(concurrencyLimit).fill(fileIterator).map(processFiles); + // Wait for all processing to complete. + await allSettledWithThrow(workers); + return await this.createAndPoll(vectorStoreId, { + file_ids: allFileIds, + }); + } +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class Files extends APIResource { + /** + * Create a vector store file by attaching a + * [File](https://platform.openai.com/docs/api-reference/files) to a + * [vector store](https://platform.openai.com/docs/api-reference/vector-stores/object). + */ + create(vectorStoreID, body, options) { + return this._client.post(path `/vector_stores/${vectorStoreID}/files`, { + body, + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } + /** + * Retrieves a vector store file. + */ + retrieve(fileID, params, options) { + const { vector_store_id } = params; + return this._client.get(path `/vector_stores/${vector_store_id}/files/${fileID}`, { + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } + /** + * Update attributes on a vector store file. + */ + update(fileID, params, options) { + const { vector_store_id, ...body } = params; + return this._client.post(path `/vector_stores/${vector_store_id}/files/${fileID}`, { + body, + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } + /** + * Returns a list of vector store files. + */ + list(vectorStoreID, query = {}, options) { + return this._client.getAPIList(path `/vector_stores/${vectorStoreID}/files`, (CursorPage), { + query, + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } + /** + * Delete a vector store file. This will remove the file from the vector store but + * the file itself will not be deleted. To delete the file, use the + * [delete file](https://platform.openai.com/docs/api-reference/files/delete) + * endpoint. + */ + delete(fileID, params, options) { + const { vector_store_id } = params; + return this._client.delete(path `/vector_stores/${vector_store_id}/files/${fileID}`, { + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } + /** + * Attach a file to the given vector store and wait for it to be processed. + */ + async createAndPoll(vectorStoreId, body, options) { + const file = await this.create(vectorStoreId, body, options); + return await this.poll(vectorStoreId, file.id, options); + } + /** + * Wait for the vector store file to finish processing. + * + * Note: this will return even if the file failed to process, you need to check + * file.last_error and file.status to handle these cases + */ + async poll(vectorStoreID, fileID, options) { + const headers = buildHeaders([ + options?.headers, + { + 'X-Stainless-Poll-Helper': 'true', + 'X-Stainless-Custom-Poll-Interval': options?.pollIntervalMs?.toString() ?? undefined, + }, + ]); + while (true) { + const fileResponse = await this.retrieve(fileID, { + vector_store_id: vectorStoreID, + }, { ...options, headers }).withResponse(); + const file = fileResponse.data; + switch (file.status) { + case 'in_progress': + let sleepInterval = 5000; + if (options?.pollIntervalMs) { + sleepInterval = options.pollIntervalMs; + } + else { + const headerInterval = fileResponse.response.headers.get('openai-poll-after-ms'); + if (headerInterval) { + const headerIntervalMs = parseInt(headerInterval); + if (!isNaN(headerIntervalMs)) { + sleepInterval = headerIntervalMs; + } + } + } + await sleep(sleepInterval); + break; + case 'failed': + case 'completed': + return file; + } + } + } + /** + * Upload a file to the `files` API and then attach it to the given vector store. + * + * Note the file will be asynchronously processed (you can use the alternative + * polling helper method to wait for processing to complete). + */ + async upload(vectorStoreId, file, options) { + const fileInfo = await this._client.files.create({ file: file, purpose: 'assistants' }, options); + return this.create(vectorStoreId, { file_id: fileInfo.id }, options); + } + /** + * Add a file to a vector store and poll until processing is complete. + */ + async uploadAndPoll(vectorStoreId, file, options) { + const fileInfo = await this.upload(vectorStoreId, file, options); + return await this.poll(vectorStoreId, fileInfo.id, options); + } + /** + * Retrieve the parsed contents of a vector store file. + */ + content(fileID, params, options) { + const { vector_store_id } = params; + return this._client.getAPIList(path `/vector_stores/${vector_store_id}/files/${fileID}/content`, (Page), { ...options, headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]) }); + } +} + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +class VectorStores extends APIResource { + constructor() { + super(...arguments); + this.files = new Files(this._client); + this.fileBatches = new FileBatches(this._client); + } + /** + * Create a vector store. + */ + create(body, options) { + return this._client.post('/vector_stores', { + body, + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } + /** + * Retrieves a vector store. + */ + retrieve(vectorStoreID, options) { + return this._client.get(path `/vector_stores/${vectorStoreID}`, { + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } + /** + * Modifies a vector store. + */ + update(vectorStoreID, body, options) { + return this._client.post(path `/vector_stores/${vectorStoreID}`, { + body, + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } + /** + * Returns a list of vector stores. + */ + list(query = {}, options) { + return this._client.getAPIList('/vector_stores', (CursorPage), { + query, + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } + /** + * Delete a vector store. + */ + delete(vectorStoreID, options) { + return this._client.delete(path `/vector_stores/${vectorStoreID}`, { + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } + /** + * Search a vector store for relevant chunks based on a query and file attributes + * filter. + */ + search(vectorStoreID, body, options) { + return this._client.getAPIList(path `/vector_stores/${vectorStoreID}/search`, (Page), { + body, + method: 'post', + ...options, + headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), + }); + } +} +VectorStores.Files = Files; +VectorStores.FileBatches = FileBatches; + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +var _Webhooks_instances, _Webhooks_validateSecret, _Webhooks_getRequiredHeader; +class Webhooks extends APIResource { + constructor() { + super(...arguments); + _Webhooks_instances.add(this); + } + /** + * Validates that the given payload was sent by OpenAI and parses the payload. + */ + async unwrap(payload, headers, secret = this._client.webhookSecret, tolerance = 300) { + await this.verifySignature(payload, headers, secret, tolerance); + return JSON.parse(payload); + } + /** + * Validates whether or not the webhook payload was sent by OpenAI. + * + * An error will be raised if the webhook payload was not sent by OpenAI. + * + * @param payload - The webhook payload + * @param headers - The webhook headers + * @param secret - The webhook secret (optional, will use client secret if not provided) + * @param tolerance - Maximum age of the webhook in seconds (default: 300 = 5 minutes) + */ + async verifySignature(payload, headers, secret = this._client.webhookSecret, tolerance = 300) { + if (typeof crypto === 'undefined' || + typeof crypto.subtle.importKey !== 'function' || + typeof crypto.subtle.verify !== 'function') { + throw new Error('Webhook signature verification is only supported when the `crypto` global is defined'); + } + __classPrivateFieldGet(this, _Webhooks_instances, "m", _Webhooks_validateSecret).call(this, secret); + const headersObj = buildHeaders([headers]).values; + const signatureHeader = __classPrivateFieldGet(this, _Webhooks_instances, "m", _Webhooks_getRequiredHeader).call(this, headersObj, 'webhook-signature'); + const timestamp = __classPrivateFieldGet(this, _Webhooks_instances, "m", _Webhooks_getRequiredHeader).call(this, headersObj, 'webhook-timestamp'); + const webhookId = __classPrivateFieldGet(this, _Webhooks_instances, "m", _Webhooks_getRequiredHeader).call(this, headersObj, 'webhook-id'); + // Validate timestamp to prevent replay attacks + const timestampSeconds = parseInt(timestamp, 10); + if (isNaN(timestampSeconds)) { + throw new InvalidWebhookSignatureError('Invalid webhook timestamp format'); + } + const nowSeconds = Math.floor(Date.now() / 1000); + if (nowSeconds - timestampSeconds > tolerance) { + throw new InvalidWebhookSignatureError('Webhook timestamp is too old'); + } + if (timestampSeconds > nowSeconds + tolerance) { + throw new InvalidWebhookSignatureError('Webhook timestamp is too new'); + } + // Extract signatures from v1, format + // The signature header can have multiple values, separated by spaces. + // Each value is in the format v1,. We should accept if any match. + const signatures = signatureHeader + .split(' ') + .map((part) => (part.startsWith('v1,') ? part.substring(3) : part)); + // Decode the secret if it starts with whsec_ + const decodedSecret = secret.startsWith('whsec_') ? + Buffer.from(secret.replace('whsec_', ''), 'base64') + : Buffer.from(secret, 'utf-8'); + // Create the signed payload: {webhook_id}.{timestamp}.{payload} + const signedPayload = webhookId ? `${webhookId}.${timestamp}.${payload}` : `${timestamp}.${payload}`; + // Import the secret as a cryptographic key for HMAC + const key = await crypto.subtle.importKey('raw', decodedSecret, { name: 'HMAC', hash: 'SHA-256' }, false, ['verify']); + // Check if any signature matches using timing-safe WebCrypto verify + for (const signature of signatures) { + try { + const signatureBytes = Buffer.from(signature, 'base64'); + const isValid = await crypto.subtle.verify('HMAC', key, signatureBytes, new TextEncoder().encode(signedPayload)); + if (isValid) { + return; // Valid signature found + } + } + catch { + // Invalid base64 or signature format, continue to next signature + continue; + } + } + throw new InvalidWebhookSignatureError('The given webhook signature does not match the expected signature'); + } +} +_Webhooks_instances = new WeakSet(), _Webhooks_validateSecret = function _Webhooks_validateSecret(secret) { + if (typeof secret !== 'string' || secret.length === 0) { + throw new Error(`The webhook secret must either be set using the env var, OPENAI_WEBHOOK_SECRET, on the client class, OpenAI({ webhookSecret: '123' }), or passed to this function`); + } +}, _Webhooks_getRequiredHeader = function _Webhooks_getRequiredHeader(headers, name) { + if (!headers) { + throw new Error(`Headers are required`); + } + const value = headers.get(name); + if (value === null || value === undefined) { + throw new Error(`Missing required header: ${name}`); + } + return value; +}; + +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +var _OpenAI_instances, _a, _OpenAI_encoder, _OpenAI_baseURLOverridden; +/** + * API Client for interfacing with the OpenAI API. + */ +class OpenAI { + /** + * API Client for interfacing with the OpenAI API. + * + * @param {string | undefined} [opts.apiKey=process.env['OPENAI_API_KEY'] ?? undefined] + * @param {string | null | undefined} [opts.organization=process.env['OPENAI_ORG_ID'] ?? null] + * @param {string | null | undefined} [opts.project=process.env['OPENAI_PROJECT_ID'] ?? null] + * @param {string | null | undefined} [opts.webhookSecret=process.env['OPENAI_WEBHOOK_SECRET'] ?? null] + * @param {string} [opts.baseURL=process.env['OPENAI_BASE_URL'] ?? https://api.openai.com/v1] - Override the default base URL for the API. + * @param {number} [opts.timeout=10 minutes] - The maximum amount of time (in milliseconds) the client will wait for a response before timing out. + * @param {MergedRequestInit} [opts.fetchOptions] - Additional `RequestInit` options to be passed to `fetch` calls. + * @param {Fetch} [opts.fetch] - Specify a custom `fetch` function implementation. + * @param {number} [opts.maxRetries=2] - The maximum number of times the client will retry a request. + * @param {HeadersLike} opts.defaultHeaders - Default headers to include with every request to the API. + * @param {Record} opts.defaultQuery - Default query parameters to include with every request to the API. + * @param {boolean} [opts.dangerouslyAllowBrowser=false] - By default, client-side use of this library is not allowed, as it risks exposing your secret API credentials to attackers. + */ + constructor({ baseURL = readEnv('OPENAI_BASE_URL'), apiKey = readEnv('OPENAI_API_KEY'), organization = readEnv('OPENAI_ORG_ID') ?? null, project = readEnv('OPENAI_PROJECT_ID') ?? null, webhookSecret = readEnv('OPENAI_WEBHOOK_SECRET') ?? null, ...opts } = {}) { + _OpenAI_instances.add(this); + _OpenAI_encoder.set(this, void 0); + this.completions = new Completions(this); + this.chat = new Chat(this); + this.embeddings = new Embeddings(this); + this.files = new Files$1(this); + this.images = new Images(this); + this.audio = new Audio(this); + this.moderations = new Moderations(this); + this.models = new Models(this); + this.fineTuning = new FineTuning(this); + this.graders = new Graders(this); + this.vectorStores = new VectorStores(this); + this.webhooks = new Webhooks(this); + this.beta = new Beta(this); + this.batches = new Batches(this); + this.uploads = new Uploads(this); + this.responses = new Responses(this); + this.realtime = new Realtime(this); + this.conversations = new Conversations(this); + this.evals = new Evals(this); + this.containers = new Containers(this); + if (apiKey === undefined) { + throw new OpenAIError('Missing credentials. Please pass an `apiKey`, or set the `OPENAI_API_KEY` environment variable.'); + } + const options = { + apiKey, + organization, + project, + webhookSecret, + ...opts, + baseURL: baseURL || `https://api.openai.com/v1`, + }; + if (!options.dangerouslyAllowBrowser && isRunningInBrowser()) { + throw new OpenAIError("It looks like you're running in a browser-like environment.\n\nThis is disabled by default, as it risks exposing your secret API credentials to attackers.\nIf you understand the risks and have appropriate mitigations in place,\nyou can set the `dangerouslyAllowBrowser` option to `true`, e.g.,\n\nnew OpenAI({ apiKey, dangerouslyAllowBrowser: true });\n\nhttps://help.openai.com/en/articles/5112595-best-practices-for-api-key-safety\n"); + } + this.baseURL = options.baseURL; + this.timeout = options.timeout ?? _a.DEFAULT_TIMEOUT /* 10 minutes */; + this.logger = options.logger ?? console; + const defaultLogLevel = 'warn'; + // Set default logLevel early so that we can log a warning in parseLogLevel. + this.logLevel = defaultLogLevel; + this.logLevel = + parseLogLevel(options.logLevel, 'ClientOptions.logLevel', this) ?? + parseLogLevel(readEnv('OPENAI_LOG'), "process.env['OPENAI_LOG']", this) ?? + defaultLogLevel; + this.fetchOptions = options.fetchOptions; + this.maxRetries = options.maxRetries ?? 2; + this.fetch = options.fetch ?? getDefaultFetch(); + __classPrivateFieldSet(this, _OpenAI_encoder, FallbackEncoder); + this._options = options; + this.apiKey = typeof apiKey === 'string' ? apiKey : 'Missing Key'; + this.organization = organization; + this.project = project; + this.webhookSecret = webhookSecret; + } + /** + * Create a new client instance re-using the same options given to the current client with optional overriding. + */ + withOptions(options) { + const client = new this.constructor({ + ...this._options, + baseURL: this.baseURL, + maxRetries: this.maxRetries, + timeout: this.timeout, + logger: this.logger, + logLevel: this.logLevel, + fetch: this.fetch, + fetchOptions: this.fetchOptions, + apiKey: this.apiKey, + organization: this.organization, + project: this.project, + webhookSecret: this.webhookSecret, + ...options, + }); + return client; + } + defaultQuery() { + return this._options.defaultQuery; + } + validateHeaders({ values, nulls }) { + return; + } + async authHeaders(opts) { + return buildHeaders([{ Authorization: `Bearer ${this.apiKey}` }]); + } + stringifyQuery(query) { + return stringify(query, { arrayFormat: 'brackets' }); + } + getUserAgent() { + return `${this.constructor.name}/JS ${VERSION}`; + } + defaultIdempotencyKey() { + return `stainless-node-retry-${uuid4()}`; + } + makeStatusError(status, error, message, headers) { + return APIError.generate(status, error, message, headers); + } + async _callApiKey() { + const apiKey = this._options.apiKey; + if (typeof apiKey !== 'function') + return false; + let token; + try { + token = await apiKey(); + } + catch (err) { + if (err instanceof OpenAIError) + throw err; + throw new OpenAIError(`Failed to get token from 'apiKey' function: ${err.message}`, + // @ts-ignore + { cause: err }); + } + if (typeof token !== 'string' || !token) { + throw new OpenAIError(`Expected 'apiKey' function argument to return a string but it returned ${token}`); + } + this.apiKey = token; + return true; + } + buildURL(path, query, defaultBaseURL) { + const baseURL = (!__classPrivateFieldGet(this, _OpenAI_instances, "m", _OpenAI_baseURLOverridden).call(this) && defaultBaseURL) || this.baseURL; + const url = isAbsoluteURL(path) ? + new URL(path) + : new URL(baseURL + (baseURL.endsWith('/') && path.startsWith('/') ? path.slice(1) : path)); + const defaultQuery = this.defaultQuery(); + if (!isEmptyObj(defaultQuery)) { + query = { ...defaultQuery, ...query }; + } + if (typeof query === 'object' && query && !Array.isArray(query)) { + url.search = this.stringifyQuery(query); + } + return url.toString(); + } + /** + * Used as a callback for mutating the given `FinalRequestOptions` object. + */ + async prepareOptions(options) { + await this._callApiKey(); + } + /** + * Used as a callback for mutating the given `RequestInit` object. + * + * This is useful for cases where you want to add certain headers based off of + * the request properties, e.g. `method` or `url`. + */ + async prepareRequest(request, { url, options }) { } + get(path, opts) { + return this.methodRequest('get', path, opts); + } + post(path, opts) { + return this.methodRequest('post', path, opts); + } + patch(path, opts) { + return this.methodRequest('patch', path, opts); + } + put(path, opts) { + return this.methodRequest('put', path, opts); + } + delete(path, opts) { + return this.methodRequest('delete', path, opts); + } + methodRequest(method, path, opts) { + return this.request(Promise.resolve(opts).then((opts) => { + return { method, path, ...opts }; + })); + } + request(options, remainingRetries = null) { + return new APIPromise(this, this.makeRequest(options, remainingRetries, undefined)); + } + async makeRequest(optionsInput, retriesRemaining, retryOfRequestLogID) { + const options = await optionsInput; + const maxRetries = options.maxRetries ?? this.maxRetries; + if (retriesRemaining == null) { + retriesRemaining = maxRetries; + } + await this.prepareOptions(options); + const { req, url, timeout } = await this.buildRequest(options, { + retryCount: maxRetries - retriesRemaining, + }); + await this.prepareRequest(req, { url, options }); + /** Not an API request ID, just for correlating local log entries. */ + const requestLogID = 'log_' + ((Math.random() * (1 << 24)) | 0).toString(16).padStart(6, '0'); + const retryLogStr = retryOfRequestLogID === undefined ? '' : `, retryOf: ${retryOfRequestLogID}`; + const startTime = Date.now(); + loggerFor(this).debug(`[${requestLogID}] sending request`, formatRequestDetails({ + retryOfRequestLogID, + method: options.method, + url, + options, + headers: req.headers, + })); + if (options.signal?.aborted) { + throw new APIUserAbortError(); + } + const controller = new AbortController(); + const response = await this.fetchWithTimeout(url, req, timeout, controller).catch(castToError); + const headersTime = Date.now(); + if (response instanceof globalThis.Error) { + const retryMessage = `retrying, ${retriesRemaining} attempts remaining`; + if (options.signal?.aborted) { + throw new APIUserAbortError(); + } + // detect native connection timeout errors + // deno throws "TypeError: error sending request for url (https://example/): client error (Connect): tcp connect error: Operation timed out (os error 60): Operation timed out (os error 60)" + // undici throws "TypeError: fetch failed" with cause "ConnectTimeoutError: Connect Timeout Error (attempted address: example:443, timeout: 1ms)" + // others do not provide enough information to distinguish timeouts from other connection errors + const isTimeout = isAbortError(response) || + /timed? ?out/i.test(String(response) + ('cause' in response ? String(response.cause) : '')); + if (retriesRemaining) { + loggerFor(this).info(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} - ${retryMessage}`); + loggerFor(this).debug(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (${retryMessage})`, formatRequestDetails({ + retryOfRequestLogID, + url, + durationMs: headersTime - startTime, + message: response.message, + })); + return this.retryRequest(options, retriesRemaining, retryOfRequestLogID ?? requestLogID); + } + loggerFor(this).info(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} - error; no more retries left`); + loggerFor(this).debug(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (error; no more retries left)`, formatRequestDetails({ + retryOfRequestLogID, + url, + durationMs: headersTime - startTime, + message: response.message, + })); + if (isTimeout) { + throw new APIConnectionTimeoutError(); + } + throw new APIConnectionError({ cause: response }); + } + const specialHeaders = [...response.headers.entries()] + .filter(([name]) => name === 'x-request-id') + .map(([name, value]) => ', ' + name + ': ' + JSON.stringify(value)) + .join(''); + const responseInfo = `[${requestLogID}${retryLogStr}${specialHeaders}] ${req.method} ${url} ${response.ok ? 'succeeded' : 'failed'} with status ${response.status} in ${headersTime - startTime}ms`; + if (!response.ok) { + const shouldRetry = await this.shouldRetry(response); + if (retriesRemaining && shouldRetry) { + const retryMessage = `retrying, ${retriesRemaining} attempts remaining`; + // We don't need the body of this response. + await CancelReadableStream(response.body); + loggerFor(this).info(`${responseInfo} - ${retryMessage}`); + loggerFor(this).debug(`[${requestLogID}] response error (${retryMessage})`, formatRequestDetails({ + retryOfRequestLogID, + url: response.url, + status: response.status, + headers: response.headers, + durationMs: headersTime - startTime, + })); + return this.retryRequest(options, retriesRemaining, retryOfRequestLogID ?? requestLogID, response.headers); + } + const retryMessage = shouldRetry ? `error; no more retries left` : `error; not retryable`; + loggerFor(this).info(`${responseInfo} - ${retryMessage}`); + const errText = await response.text().catch((err) => castToError(err).message); + const errJSON = safeJSON(errText); + const errMessage = errJSON ? undefined : errText; + loggerFor(this).debug(`[${requestLogID}] response error (${retryMessage})`, formatRequestDetails({ + retryOfRequestLogID, + url: response.url, + status: response.status, + headers: response.headers, + message: errMessage, + durationMs: Date.now() - startTime, + })); + const err = this.makeStatusError(response.status, errJSON, errMessage, response.headers); + throw err; + } + loggerFor(this).info(responseInfo); + loggerFor(this).debug(`[${requestLogID}] response start`, formatRequestDetails({ + retryOfRequestLogID, + url: response.url, + status: response.status, + headers: response.headers, + durationMs: headersTime - startTime, + })); + return { response, options, controller, requestLogID, retryOfRequestLogID, startTime }; + } + getAPIList(path, Page, opts) { + return this.requestAPIList(Page, { method: 'get', path, ...opts }); + } + requestAPIList(Page, options) { + const request = this.makeRequest(options, null, undefined); + return new PagePromise(this, request, Page); + } + async fetchWithTimeout(url, init, ms, controller) { + const { signal, method, ...options } = init || {}; + if (signal) + signal.addEventListener('abort', () => controller.abort()); + const timeout = setTimeout(() => controller.abort(), ms); + const isReadableBody = (globalThis.ReadableStream && options.body instanceof globalThis.ReadableStream) || + (typeof options.body === 'object' && options.body !== null && Symbol.asyncIterator in options.body); + const fetchOptions = { + signal: controller.signal, + ...(isReadableBody ? { duplex: 'half' } : {}), + method: 'GET', + ...options, + }; + if (method) { + // Custom methods like 'patch' need to be uppercased + // See https://github.com/nodejs/undici/issues/2294 + fetchOptions.method = method.toUpperCase(); + } + try { + // use undefined this binding; fetch errors if bound to something else in browser/cloudflare + return await this.fetch.call(undefined, url, fetchOptions); + } + finally { + clearTimeout(timeout); + } + } + async shouldRetry(response) { + // Note this is not a standard header. + const shouldRetryHeader = response.headers.get('x-should-retry'); + // If the server explicitly says whether or not to retry, obey. + if (shouldRetryHeader === 'true') + return true; + if (shouldRetryHeader === 'false') + return false; + // Retry on request timeouts. + if (response.status === 408) + return true; + // Retry on lock timeouts. + if (response.status === 409) + return true; + // Retry on rate limits. + if (response.status === 429) + return true; + // Retry internal errors. + if (response.status >= 500) + return true; + return false; + } + async retryRequest(options, retriesRemaining, requestLogID, responseHeaders) { + let timeoutMillis; + // Note the `retry-after-ms` header may not be standard, but is a good idea and we'd like proactive support for it. + const retryAfterMillisHeader = responseHeaders?.get('retry-after-ms'); + if (retryAfterMillisHeader) { + const timeoutMs = parseFloat(retryAfterMillisHeader); + if (!Number.isNaN(timeoutMs)) { + timeoutMillis = timeoutMs; + } + } + // About the Retry-After header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After + const retryAfterHeader = responseHeaders?.get('retry-after'); + if (retryAfterHeader && !timeoutMillis) { + const timeoutSeconds = parseFloat(retryAfterHeader); + if (!Number.isNaN(timeoutSeconds)) { + timeoutMillis = timeoutSeconds * 1000; + } + else { + timeoutMillis = Date.parse(retryAfterHeader) - Date.now(); + } + } + // If the API asks us to wait a certain amount of time (and it's a reasonable amount), + // just do what it says, but otherwise calculate a default + if (!(timeoutMillis && 0 <= timeoutMillis && timeoutMillis < 60 * 1000)) { + const maxRetries = options.maxRetries ?? this.maxRetries; + timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries); + } + await sleep(timeoutMillis); + return this.makeRequest(options, retriesRemaining - 1, requestLogID); + } + calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries) { + const initialRetryDelay = 0.5; + const maxRetryDelay = 8.0; + const numRetries = maxRetries - retriesRemaining; + // Apply exponential backoff, but not more than the max. + const sleepSeconds = Math.min(initialRetryDelay * Math.pow(2, numRetries), maxRetryDelay); + // Apply some jitter, take up to at most 25 percent of the retry time. + const jitter = 1 - Math.random() * 0.25; + return sleepSeconds * jitter * 1000; + } + async buildRequest(inputOptions, { retryCount = 0 } = {}) { + const options = { ...inputOptions }; + const { method, path, query, defaultBaseURL } = options; + const url = this.buildURL(path, query, defaultBaseURL); + if ('timeout' in options) + validatePositiveInteger('timeout', options.timeout); + options.timeout = options.timeout ?? this.timeout; + const { bodyHeaders, body } = this.buildBody({ options }); + const reqHeaders = await this.buildHeaders({ options: inputOptions, method, bodyHeaders, retryCount }); + const req = { + method, + headers: reqHeaders, + ...(options.signal && { signal: options.signal }), + ...(globalThis.ReadableStream && + body instanceof globalThis.ReadableStream && { duplex: 'half' }), + ...(body && { body }), + ...(this.fetchOptions ?? {}), + ...(options.fetchOptions ?? {}), + }; + return { req, url, timeout: options.timeout }; + } + async buildHeaders({ options, method, bodyHeaders, retryCount, }) { + let idempotencyHeaders = {}; + if (this.idempotencyHeader && method !== 'get') { + if (!options.idempotencyKey) + options.idempotencyKey = this.defaultIdempotencyKey(); + idempotencyHeaders[this.idempotencyHeader] = options.idempotencyKey; + } + const headers = buildHeaders([ + idempotencyHeaders, + { + Accept: 'application/json', + 'User-Agent': this.getUserAgent(), + 'X-Stainless-Retry-Count': String(retryCount), + ...(options.timeout ? { 'X-Stainless-Timeout': String(Math.trunc(options.timeout / 1000)) } : {}), + ...getPlatformHeaders(), + 'OpenAI-Organization': this.organization, + 'OpenAI-Project': this.project, + }, + await this.authHeaders(options), + this._options.defaultHeaders, + bodyHeaders, + options.headers, + ]); + this.validateHeaders(headers); + return headers.values; + } + buildBody({ options: { body, headers: rawHeaders } }) { + if (!body) { + return { bodyHeaders: undefined, body: undefined }; + } + const headers = buildHeaders([rawHeaders]); + if ( + // Pass raw type verbatim + ArrayBuffer.isView(body) || + body instanceof ArrayBuffer || + body instanceof DataView || + (typeof body === 'string' && + // Preserve legacy string encoding behavior for now + headers.values.has('content-type')) || + // `Blob` is superset of `File` + (globalThis.Blob && body instanceof globalThis.Blob) || + // `FormData` -> `multipart/form-data` + body instanceof FormData || + // `URLSearchParams` -> `application/x-www-form-urlencoded` + body instanceof URLSearchParams || + // Send chunked stream (each chunk has own `length`) + (globalThis.ReadableStream && body instanceof globalThis.ReadableStream)) { + return { bodyHeaders: undefined, body: body }; + } + else if (typeof body === 'object' && + (Symbol.asyncIterator in body || + (Symbol.iterator in body && 'next' in body && typeof body.next === 'function'))) { + return { bodyHeaders: undefined, body: ReadableStreamFrom(body) }; + } + else { + return __classPrivateFieldGet(this, _OpenAI_encoder, "f").call(this, { body, headers }); + } + } +} +_a = OpenAI, _OpenAI_encoder = new WeakMap(), _OpenAI_instances = new WeakSet(), _OpenAI_baseURLOverridden = function _OpenAI_baseURLOverridden() { + return this.baseURL !== 'https://api.openai.com/v1'; +}; +OpenAI.OpenAI = _a; +OpenAI.DEFAULT_TIMEOUT = 600000; // 10 minutes +OpenAI.OpenAIError = OpenAIError; +OpenAI.APIError = APIError; +OpenAI.APIConnectionError = APIConnectionError; +OpenAI.APIConnectionTimeoutError = APIConnectionTimeoutError; +OpenAI.APIUserAbortError = APIUserAbortError; +OpenAI.NotFoundError = NotFoundError; +OpenAI.ConflictError = ConflictError; +OpenAI.RateLimitError = RateLimitError; +OpenAI.BadRequestError = BadRequestError; +OpenAI.AuthenticationError = AuthenticationError; +OpenAI.InternalServerError = InternalServerError; +OpenAI.PermissionDeniedError = PermissionDeniedError; +OpenAI.UnprocessableEntityError = UnprocessableEntityError; +OpenAI.InvalidWebhookSignatureError = InvalidWebhookSignatureError; +OpenAI.toFile = toFile; +OpenAI.Completions = Completions; +OpenAI.Chat = Chat; +OpenAI.Embeddings = Embeddings; +OpenAI.Files = Files$1; +OpenAI.Images = Images; +OpenAI.Audio = Audio; +OpenAI.Moderations = Moderations; +OpenAI.Models = Models; +OpenAI.FineTuning = FineTuning; +OpenAI.Graders = Graders; +OpenAI.VectorStores = VectorStores; +OpenAI.Webhooks = Webhooks; +OpenAI.Beta = Beta; +OpenAI.Batches = Batches; +OpenAI.Uploads = Uploads; +OpenAI.Responses = Responses; +OpenAI.Realtime = Realtime; +OpenAI.Conversations = Conversations; +OpenAI.Evals = Evals; +OpenAI.Containers = Containers; + +// biome-ignore-all lint: generated file +/* eslint-disable */ + +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); +var __commonJS = (cb, mod) => function __require() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + __defProp(target, "default", { value: mod, enumerable: true }) , + mod +)); + +// ../../node_modules/.pnpm/lodash.chunk@4.2.0/node_modules/lodash.chunk/index.js +var require_lodash = __commonJS({ + "../../node_modules/.pnpm/lodash.chunk@4.2.0/node_modules/lodash.chunk/index.js"(exports, module) { + var INFINITY = 1 / 0; + var MAX_SAFE_INTEGER = 9007199254740991; + var MAX_INTEGER = 17976931348623157e292; + var NAN = 0 / 0; + var funcTag = "[object Function]"; + var genTag = "[object GeneratorFunction]"; + var symbolTag = "[object Symbol]"; + var reTrim = /^\s+|\s+$/g; + var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + var reIsBinary = /^0b[01]+$/i; + var reIsOctal = /^0o[0-7]+$/i; + var reIsUint = /^(?:0|[1-9]\d*)$/; + var freeParseInt = parseInt; + var objectProto = Object.prototype; + var objectToString = objectProto.toString; + var nativeCeil = Math.ceil; + var nativeMax = Math.max; + function baseSlice(array, start, end) { + var index = -1, length = array.length; + if (start < 0) { + start = -start > length ? 0 : length + start; + } + end = end > length ? length : end; + if (end < 0) { + end += length; + } + length = start > end ? 0 : end - start >>> 0; + start >>>= 0; + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; + } + __name(baseSlice, "baseSlice"); + function isIndex(value, length) { + length = length == null ? MAX_SAFE_INTEGER : length; + return !!length && (typeof value == "number" || reIsUint.test(value)) && value > -1 && value % 1 == 0 && value < length; + } + __name(isIndex, "isIndex"); + function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == "number" ? isArrayLike(object) && isIndex(index, object.length) : type == "string" && index in object) { + return eq(object[index], value); + } + return false; + } + __name(isIterateeCall, "isIterateeCall"); + function chunk2(array, size, guard) { + if (guard ? isIterateeCall(array, size, guard) : size === void 0) { + size = 1; + } else { + size = nativeMax(toInteger(size), 0); + } + var length = array ? array.length : 0; + if (!length || size < 1) { + return []; + } + var index = 0, resIndex = 0, result = Array(nativeCeil(length / size)); + while (index < length) { + result[resIndex++] = baseSlice(array, index, index += size); + } + return result; + } + __name(chunk2, "chunk"); + function eq(value, other) { + return value === other || value !== value && other !== other; + } + __name(eq, "eq"); + function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); + } + __name(isArrayLike, "isArrayLike"); + function isFunction(value) { + var tag = isObject(value) ? objectToString.call(value) : ""; + return tag == funcTag || tag == genTag; + } + __name(isFunction, "isFunction"); + function isLength(value) { + return typeof value == "number" && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + __name(isLength, "isLength"); + function isObject(value) { + var type = typeof value; + return !!value && (type == "object" || type == "function"); + } + __name(isObject, "isObject"); + function isObjectLike(value) { + return !!value && typeof value == "object"; + } + __name(isObjectLike, "isObjectLike"); + function isSymbol(value) { + return typeof value == "symbol" || isObjectLike(value) && objectToString.call(value) == symbolTag; + } + __name(isSymbol, "isSymbol"); + function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = value < 0 ? -1 : 1; + return sign * MAX_INTEGER; + } + return value === value ? value : 0; + } + __name(toFinite, "toFinite"); + function toInteger(value) { + var result = toFinite(value), remainder = result % 1; + return result === result ? remainder ? result - remainder : result : 0; + } + __name(toInteger, "toInteger"); + function toNumber(value) { + if (typeof value == "number") { + return value; + } + if (isSymbol(value)) { + return NAN; + } + if (isObject(value)) { + var other = typeof value.valueOf == "function" ? value.valueOf() : value; + value = isObject(other) ? other + "" : other; + } + if (typeof value != "string") { + return value === 0 ? value : +value; + } + value = value.replace(reTrim, ""); + var isBinary = reIsBinary.test(value); + return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value; + } + __name(toNumber, "toNumber"); + module.exports = chunk2; + } +}); +async function __builtin_response_array_buffer(res) { + return res.arrayBuffer(); +} +__name(__builtin_response_array_buffer, "__builtin_response_array_buffer"); +async function __builtin_response_json(res) { + return res.json(); +} +__name(__builtin_response_json, "__builtin_response_json"); +async function __builtin_response_text(res) { + return res.text(); +} +__name(__builtin_response_text, "__builtin_response_text"); +registerStepFunction("__builtin_response_array_buffer", __builtin_response_array_buffer); +registerStepFunction("__builtin_response_json", __builtin_response_json); +registerStepFunction("__builtin_response_text", __builtin_response_text); +function parseDurationToDate(param) { + if (typeof param === "string") { + const durationMs = ms(param); + if (typeof durationMs !== "number" || durationMs < 0) { + throw new Error(`Invalid duration: "${param}". Expected a valid duration string like "1s", "1m", "1h", etc.`); + } + return new Date(Date.now() + durationMs); + } else if (typeof param === "number") { + if (param < 0 || !Number.isFinite(param)) { + throw new Error(`Invalid duration: ${param}. Expected a non-negative finite number of milliseconds.`); + } + return new Date(Date.now() + param); + } else if (param instanceof Date || param && typeof param === "object" && typeof param.getTime === "function") { + return param instanceof Date ? param : new Date(param.getTime()); + } else { + throw new Error(`Invalid duration parameter. Expected a duration string, number (milliseconds), or Date object.`); + } +} +__name(parseDurationToDate, "parseDurationToDate"); + +// ../../packages/errors/dist/index.js +function isError(value) { + return typeof value === "object" && value !== null && "name" in value && "message" in value; +} +__name(isError, "isError"); +var FatalError = class extends Error { + static { + __name(this, "FatalError"); + } + fatal = true; + constructor(message) { + super(message); + this.name = "FatalError"; + } + static is(value) { + return isError(value) && value.name === "FatalError"; + } +}; +var RetryableError = class extends Error { + static { + __name(this, "RetryableError"); + } + /** + * The Date when the step should be retried. + */ + retryAfter; + constructor(message, options = {}) { + super(message); + this.name = "RetryableError"; + if (options.retryAfter !== void 0) { + this.retryAfter = parseDurationToDate(options.retryAfter); + } else { + this.retryAfter = new Date(Date.now() + 1e3); + } + } + static is(value) { + return isError(value) && value.name === "RetryableError"; + } +}; +async function fetch$1(...args) { + return globalThis.fetch(...args); +} +__name(fetch$1, "fetch"); +registerStepFunction("step//packages/workflow/dist/stdlib.js//fetch", fetch$1); + +// ../example/workflows/99_e2e.ts +async function add(a, b) { + return a + b; +} +__name(add, "add"); +async function randomDelay(v) { + await new Promise((resolve) => setTimeout(resolve, Math.random() * 3e3)); + return v.toUpperCase(); +} +__name(randomDelay, "randomDelay"); +async function specificDelay(delay, v) { + await new Promise((resolve) => setTimeout(resolve, delay)); + return v.toUpperCase(); +} +__name(specificDelay, "specificDelay"); +async function stepThatFails() { + throw new FatalError("step failed"); +} +__name(stepThatFails, "stepThatFails"); +async function genReadableStream() { + const encoder = new TextEncoder(); + return new ReadableStream({ + async start(controller) { + for (let i = 0; i < 10; i++) { + console.log("enqueueing", i); + controller.enqueue(encoder.encode(`${i} +`)); + await new Promise((resolve) => setTimeout(resolve, 1e3)); + } + console.log("closing controller"); + controller.close(); + } + }); +} +__name(genReadableStream, "genReadableStream"); +async function sendWebhookResponse(req) { + const body = await req.text(); + await req.respondWith(new Response("Hello from webhook!")); + return body; +} +__name(sendWebhookResponse, "sendWebhookResponse"); +async function nullByteStep() { + return "null byte \0"; +} +__name(nullByteStep, "nullByteStep"); +async function stepWithMetadata() { + const stepMetadata = getStepMetadata(); + const workflowMetadata = getWorkflowMetadata(); + return { + stepMetadata, + workflowMetadata + }; +} +__name(stepWithMetadata, "stepWithMetadata"); +async function stepWithOutputStreamBinary(writable, text) { + const writer = writable.getWriter(); + await writer.write(new TextEncoder().encode(text)); + writer.releaseLock(); +} +__name(stepWithOutputStreamBinary, "stepWithOutputStreamBinary"); +async function stepWithOutputStreamObject(writable, obj) { + const writer = writable.getWriter(); + await writer.write(obj); + writer.releaseLock(); +} +__name(stepWithOutputStreamObject, "stepWithOutputStreamObject"); +async function stepCloseOutputStream(writable) { + await writable.close(); +} +__name(stepCloseOutputStream, "stepCloseOutputStream"); +async function stepWithOutputStreamInsideStep(text) { + const writable = getWritable(); + const writer = writable.getWriter(); + await writer.write(new TextEncoder().encode(text)); + writer.releaseLock(); +} +__name(stepWithOutputStreamInsideStep, "stepWithOutputStreamInsideStep"); +async function stepWithNamedOutputStreamInsideStep(namespace, obj) { + const writable = getWritable({ + namespace + }); + const writer = writable.getWriter(); + await writer.write(obj); + writer.releaseLock(); +} +__name(stepWithNamedOutputStreamInsideStep, "stepWithNamedOutputStreamInsideStep"); +async function stepCloseOutputStreamInsideStep(namespace) { + const writable = getWritable({ + namespace + }); + await writable.close(); +} +__name(stepCloseOutputStreamInsideStep, "stepCloseOutputStreamInsideStep"); +async function promiseRaceStressTestDelayStep(dur, resp) { + console.log(`sleep`, resp, `/`, dur); + await new Promise((resolve) => setTimeout(resolve, dur)); + console.log(resp, `done`); + return resp; +} +__name(promiseRaceStressTestDelayStep, "promiseRaceStressTestDelayStep"); +async function stepThatRetriesAndSucceeds() { + const { attempt } = getStepMetadata(); + console.log(`stepThatRetriesAndSucceeds - attempt: ${attempt}`); + if (attempt < 3) { + console.log(`Attempt ${attempt} - throwing error to trigger retry`); + throw new Error(`Failed on attempt ${attempt}`); + } + console.log(`Attempt ${attempt} - succeeding`); + return attempt; +} +__name(stepThatRetriesAndSucceeds, "stepThatRetriesAndSucceeds"); +async function stepThatThrowsRetryableError() { + const { attempt, stepStartedAt } = getStepMetadata(); + if (attempt === 1) { + throw new RetryableError("Retryable error", { + retryAfter: "10s" + }); + } + return { + attempt, + stepStartedAt, + duration: Date.now() - stepStartedAt.getTime() + }; +} +__name(stepThatThrowsRetryableError, "stepThatThrowsRetryableError"); +async function stepWithStepFunctionArg(stepFn) { + const result = await stepFn(10); + return result * 2; +} +__name(stepWithStepFunctionArg, "stepWithStepFunctionArg"); +async function doubleNumber(x) { + return x * 2; +} +__name(doubleNumber, "doubleNumber"); +registerStepFunction("step//example/workflows/99_e2e.ts//add", add); +registerStepFunction("step//example/workflows/99_e2e.ts//randomDelay", randomDelay); +registerStepFunction("step//example/workflows/99_e2e.ts//specificDelay", specificDelay); +registerStepFunction("step//example/workflows/99_e2e.ts//stepThatFails", stepThatFails); +registerStepFunction("step//example/workflows/99_e2e.ts//genReadableStream", genReadableStream); +registerStepFunction("step//example/workflows/99_e2e.ts//sendWebhookResponse", sendWebhookResponse); +registerStepFunction("step//example/workflows/99_e2e.ts//nullByteStep", nullByteStep); +registerStepFunction("step//example/workflows/99_e2e.ts//stepWithMetadata", stepWithMetadata); +registerStepFunction("step//example/workflows/99_e2e.ts//stepWithOutputStreamBinary", stepWithOutputStreamBinary); +registerStepFunction("step//example/workflows/99_e2e.ts//stepWithOutputStreamObject", stepWithOutputStreamObject); +registerStepFunction("step//example/workflows/99_e2e.ts//stepCloseOutputStream", stepCloseOutputStream); +registerStepFunction("step//example/workflows/99_e2e.ts//stepWithOutputStreamInsideStep", stepWithOutputStreamInsideStep); +registerStepFunction("step//example/workflows/99_e2e.ts//stepWithNamedOutputStreamInsideStep", stepWithNamedOutputStreamInsideStep); +registerStepFunction("step//example/workflows/99_e2e.ts//stepCloseOutputStreamInsideStep", stepCloseOutputStreamInsideStep); +registerStepFunction("step//example/workflows/99_e2e.ts//promiseRaceStressTestDelayStep", promiseRaceStressTestDelayStep); +registerStepFunction("step//example/workflows/99_e2e.ts//stepThatRetriesAndSucceeds", stepThatRetriesAndSucceeds); +registerStepFunction("step//example/workflows/99_e2e.ts//stepThatThrowsRetryableError", stepThatThrowsRetryableError); +registerStepFunction("step//example/workflows/99_e2e.ts//stepWithStepFunctionArg", stepWithStepFunctionArg); +registerStepFunction("step//example/workflows/99_e2e.ts//doubleNumber", doubleNumber); +async function delayedMessage(ms2, message) { + console.log(`Sleeping for ${ms2}ms and returning ${message}`); + await new Promise((resolve) => setTimeout(resolve, ms2)); + return `${message} (sent: ${(/* @__PURE__ */ new Date()).toISOString()})`; +} +__name(delayedMessage, "delayedMessage"); +async function add2(a, b) { + console.log(`Adding ${a} and ${b} (sent: ${(/* @__PURE__ */ new Date()).toISOString()})`); + return a + b; +} +__name(add2, "add"); +async function failingStep() { + throw new FatalError(`A failed step (sent: ${(/* @__PURE__ */ new Date()).toISOString()})`); +} +__name(failingStep, "failingStep"); +async function retryableStep() { + const { attempt } = getStepMetadata(); + console.log("retryableStep attempt:", attempt); + if (attempt === 1) { + console.log("Throwing retryable error - this will be retried after 5 seconds"); + throw new RetryableError("Retryable error", { + // Retry after 5 seconds + retryAfter: "5s" + }); + } + console.log("Completing successfully"); + return "Success"; +} +__name(retryableStep, "retryableStep"); +registerStepFunction("step//example/workflows/2_control_flow.ts//delayedMessage", delayedMessage); +registerStepFunction("step//example/workflows/2_control_flow.ts//add", add2); +registerStepFunction("step//example/workflows/2_control_flow.ts//failingStep", failingStep); +registerStepFunction("step//example/workflows/2_control_flow.ts//retryableStep", retryableStep); +async function pow(a) { + console.log("Running step pow with arg:", a); + return a * a; +} +__name(pow, "pow"); +registerStepFunction("step//nitro-v3/workflows/0_demo.ts//pow", pow); +async function add3(a, b) { + return a + b; +} +__name(add3, "add"); +registerStepFunction("step//example/workflows/98_duplicate_case.ts//add", add3); + +// ../example/workflows/6_batching.ts +__toESM(require_lodash()); +async function logItem(item) { + console.log(item, Date.now()); +} +__name(logItem, "logItem"); +async function processItems(items) { + await Promise.all(items.map(async (item) => { + console.log(item, Date.now()); + })); +} +__name(processItems, "processItems"); +registerStepFunction("step//example/workflows/6_batching.ts//logItem", logItem); +registerStepFunction("step//example/workflows/6_batching.ts//processItems", processItems); +async function add4(a, b) { + if (Math.random() < 0.5) { + throw new Error("Retryable error"); + } + if (Math.random() < 0.05) { + throw new FatalError("We're cooked yo!"); + } + return a + b; +} +__name(add4, "add"); +registerStepFunction("step//example/workflows/1_simple.ts//add", add4); + +// ../example/workflows/5_hooks.ts +async function stepWithGetMetadata() { + const ctx = getStepMetadata(); + console.log("step context", ctx); + if (Math.random() < 0.5) { + throw new Error("Retryable error"); + } +} +__name(stepWithGetMetadata, "stepWithGetMetadata"); +async function initiateOpenAIResponse() { + const openai = new OpenAI(); + const resp = await openai.responses.create({ + model: "o3", + input: "Write a very long novel about otters in space.", + background: true + }); + console.log("OpenAI response:", resp); + return resp.id; +} +__name(initiateOpenAIResponse, "initiateOpenAIResponse"); +async function getOpenAIResponse(respId) { + const openai = new OpenAI(); + const resp = await openai.responses.retrieve(respId); + return resp.output_text; +} +__name(getOpenAIResponse, "getOpenAIResponse"); +registerStepFunction("step//example/workflows/5_hooks.ts//stepWithGetMetadata", stepWithGetMetadata); +registerStepFunction("step//example/workflows/5_hooks.ts//initiateOpenAIResponse", initiateOpenAIResponse); +registerStepFunction("step//example/workflows/5_hooks.ts//getOpenAIResponse", getOpenAIResponse); +async function getWeatherInformation({ city }) { + console.log("Getting the weather for city: ", city); + if (Math.random() < 0.5) { + throw new Error("Retryable error"); + } + if (Math.random() < 0.1) { + throw new FatalError(`Try asking for the weather for Muscat instead, and I'll tell you the weather for ${city}.`); + } + const weatherOptions = [ + "sunny", + "cloudy", + "rainy", + "snowy", + "windy" + ]; + return weatherOptions[Math.floor(Math.random() * weatherOptions.length)]; +} +__name(getWeatherInformation, "getWeatherInformation"); +registerStepFunction("step//example/workflows/4_ai.ts//getWeatherInformation", getWeatherInformation); +async function genStream() { + const stream = new ReadableStream({ + async start(controller) { + const encoder = new TextEncoder(); + for (let i = 0; i < 30; i++) { + const chunk2 = encoder.encode(`${i} +`); + controller.enqueue(chunk2); + console.log(`Enqueued number: ${i}`); + await new Promise((resolve) => setTimeout(resolve, 2500)); + } + controller.close(); + } + }); + return stream; +} +__name(genStream, "genStream"); +async function consumeStreams(...streams) { + const parts = []; + console.log("Consuming streams", streams); + await Promise.all(streams.map(async (s, i) => { + const reader = s.getReader(); + while (true) { + const result = await reader.read(); + if (result.done) break; + console.log(`Received ${result.value.length} bytes from stream ${i}: ${JSON.stringify(new TextDecoder().decode(result.value))}`); + parts.push(result.value); + } + })); + return Buffer.concat(parts).toString("utf8"); +} +__name(consumeStreams, "consumeStreams"); +registerStepFunction("step//example/workflows/3_streams.ts//genStream", genStream); +registerStepFunction("step//example/workflows/3_streams.ts//consumeStreams", consumeStreams); +async function createUser(email) { + console.log(`Creating a new user with email: ${email}`); + return { + id: crypto.randomUUID(), + email + }; +} +__name(createUser, "createUser"); +async function sendWelcomeEmail(user) { + console.log(`Sending welcome email to user: ${user.id}`); +} +__name(sendWelcomeEmail, "sendWelcomeEmail"); +async function sendOnboardingEmail(user, callback) { + console.log(`Sending onboarding email to user: ${user.id}`); + console.log(`Click this link to resolve the webhook: ${callback}`); +} +__name(sendOnboardingEmail, "sendOnboardingEmail"); +registerStepFunction("step//example/workflows/7_full.ts//createUser", createUser); +registerStepFunction("step//example/workflows/7_full.ts//sendWelcomeEmail", sendWelcomeEmail); +registerStepFunction("step//example/workflows/7_full.ts//sendOnboardingEmail", sendOnboardingEmail); + +async function normalizeRequestConverter(request) { + const options = { + method: request.method, + headers: new Headers(request.headers) + }; + if (!['GET', 'HEAD', 'OPTIONS', 'TRACE', 'CONNECT'].includes(request.method)) { + options.body = await request.arrayBuffer(); + } + return new Request(request.url, options); +} + +const POST = async ({request}) => { + const normalRequest = await normalizeRequestConverter(request); + return stepEntrypoint(normalRequest); +}; + +const prerender = false; + +const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ + __proto__: null, + POST, + prerender +}, Symbol.toStringTag, { value: 'Module' })); + +const page = () => _page; + +export { page }; diff --git a/workbench/astro/dist/server/pages/.well-known/workflow/v1/webhook/_token_.astro.mjs b/workbench/astro/dist/server/pages/.well-known/workflow/v1/webhook/_token_.astro.mjs new file mode 100644 index 000000000..20d205d82 --- /dev/null +++ b/workbench/astro/dist/server/pages/.well-known/workflow/v1/webhook/_token_.astro.mjs @@ -0,0 +1,67 @@ +import '../../../../../chunks/index_ePTMDSOu.mjs'; +import 'ms'; +import '@jridgewell/sourcemap-codec'; +import { r as resumeWebhook } from '../../../../../chunks/resume-hook_BHshEMMl.mjs'; +export { renderers } from '../../../../../renderers.mjs'; + +process.on("unhandledRejection", (reason) => { if (reason !== undefined) console.error("Unhandled rejection detected", reason); }); + +async function handler(request, token) { + + if (!token) { + return new Response('Missing token', { status: 400 }); + } + + try { + const response = await resumeWebhook(token, request); + return response; + } catch (error) { + // TODO: differentiate between invalid token and other errors + console.error('Error during resumeWebhook', error); + return new Response(null, { status: 404 }); + } +} + + +async function normalizeRequestConverter(request) { + const options = { + method: request.method, + headers: new Headers(request.headers) + }; + if (!['GET', 'HEAD', 'OPTIONS', 'TRACE', 'CONNECT'].includes(request.method)) { + options.body = await request.arrayBuffer(); + } + return new Request(request.url, options); +} + +const createHandler = (method) => async ({ request, params, platform }) => { + const normalRequest = await normalizeRequestConverter(request); + const response = await handler(normalRequest, params.token); + return response; +}; + +const GET = createHandler(); +const POST = createHandler(); +const PUT = createHandler(); +const PATCH = createHandler(); +const DELETE = createHandler(); +const HEAD = createHandler(); +const OPTIONS = createHandler(); + +const prerender = false; + +const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ + __proto__: null, + DELETE, + GET, + HEAD, + OPTIONS, + PATCH, + POST, + PUT, + prerender +}, Symbol.toStringTag, { value: 'Module' })); + +const page = () => _page; + +export { page }; diff --git a/workbench/astro/dist/server/pages/_image.astro.mjs b/workbench/astro/dist/server/pages/_image.astro.mjs new file mode 100644 index 000000000..0f11d9345 --- /dev/null +++ b/workbench/astro/dist/server/pages/_image.astro.mjs @@ -0,0 +1,2 @@ +export { a as page } from '../chunks/node_C2n6Z2oQ.mjs'; +export { renderers } from '../renderers.mjs'; diff --git a/workbench/astro/dist/server/pages/api/hook.astro.mjs b/workbench/astro/dist/server/pages/api/hook.astro.mjs new file mode 100644 index 000000000..c5ff330ed --- /dev/null +++ b/workbench/astro/dist/server/pages/api/hook.astro.mjs @@ -0,0 +1,34 @@ +import '../../chunks/index_ePTMDSOu.mjs'; +import 'ms'; +import '@jridgewell/sourcemap-codec'; +import { g as getHookByToken, a as resumeHook } from '../../chunks/resume-hook_BHshEMMl.mjs'; +export { renderers } from '../../renderers.mjs'; + +const POST = async ({ request }) => { + const { token, data } = await request.json(); + let hook; + try { + hook = await getHookByToken(token); + console.log("hook", hook); + } catch (error) { + console.log("error during getHookByToken", error); + return Response.json(null, { status: 404 }); + } + await resumeHook(hook.token, { + ...data, + // @ts-expect-error metadata is not typed + customData: hook.metadata?.customData + }); + return Response.json(hook); +}; +const prerender = false; + +const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ + __proto__: null, + POST, + prerender +}, Symbol.toStringTag, { value: 'Module' })); + +const page = () => _page; + +export { page }; diff --git a/workbench/astro/dist/server/pages/api/test-direct-step-call.astro.mjs b/workbench/astro/dist/server/pages/api/test-direct-step-call.astro.mjs new file mode 100644 index 000000000..0843ea870 --- /dev/null +++ b/workbench/astro/dist/server/pages/api/test-direct-step-call.astro.mjs @@ -0,0 +1,22 @@ +import { a as add } from '../../chunks/99_e2e_DTaFFPMr.mjs'; +export { renderers } from '../../renderers.mjs'; + +async function POST({ request }) { + const body = await request.json(); + const { x, y } = body; + console.log(`Calling step function directly with x=${x}, y=${y}`); + const result = await add(x, y); + console.log(`add(${x}, ${y}) = ${result}`); + return Response.json({ result }); +} +const prerender = false; + +const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ + __proto__: null, + POST, + prerender +}, Symbol.toStringTag, { value: 'Module' })); + +const page = () => _page; + +export { page }; diff --git a/workbench/astro/dist/server/pages/api/trigger.astro.mjs b/workbench/astro/dist/server/pages/api/trigger.astro.mjs new file mode 100644 index 000000000..d05c287d0 --- /dev/null +++ b/workbench/astro/dist/server/pages/api/trigger.astro.mjs @@ -0,0 +1,341 @@ +import { R as Run, g as getRun } from '../../chunks/runtime_CxdH0OC2.mjs'; +import { w as waitedUntil, e as WorkflowRuntimeError, t as trace, o as WorkflowOperation, l as WorkflowName, p as WorkflowArgumentsCount, c as getWorld, q as dehydrateWorkflowArguments, s as serializeTraceCarrier, k as functionsExports, D as DeploymentId, u as WorkflowRunStatus, f as WorkflowRunId, v as hydrateWorkflowArguments, x as WorkflowRunNotCompletedError, y as WorkflowRunFailedError } from '../../chunks/index_ePTMDSOu.mjs'; +import { w as workflow_99_e2e } from '../../chunks/99_e2e_DTaFFPMr.mjs'; +export { renderers } from '../../renderers.mjs'; + +async function start(workflow, argsOrOptions, options) { + return await waitedUntil(()=>{ + // @ts-expect-error this field is added by our client transform + const workflowName = workflow.workflowId; + if (!workflowName) { + throw new WorkflowRuntimeError(`'start' received an invalid workflow function. Ensure the Workflow Development Kit is configured correctly and the function includes a 'use workflow' directive.`, { + slug: 'start-invalid-workflow-function' + }); + } + return trace(`WORKFLOW.start ${workflowName}`, async (span)=>{ + span?.setAttributes({ + ...WorkflowName(workflowName), + ...WorkflowOperation('start') + }); + let args = []; + let opts = {}; + if (Array.isArray(argsOrOptions)) { + args = argsOrOptions; + } else if (typeof argsOrOptions === 'object') { + opts = argsOrOptions; + } + span?.setAttributes({ + ...WorkflowArgumentsCount(args.length) + }); + const world = getWorld(); + const deploymentId = opts.deploymentId ?? await world.getDeploymentId(); + const ops = []; + const workflowArguments = dehydrateWorkflowArguments(args, ops); + // Serialize current trace context to propagate across queue boundary + const traceCarrier = await serializeTraceCarrier(); + const runResponse = await world.runs.create({ + deploymentId: deploymentId, + workflowName: workflowName, + input: workflowArguments, + executionContext: { + traceCarrier + } + }); + functionsExports.waitUntil(Promise.all(ops)); + span?.setAttributes({ + ...WorkflowRunId(runResponse.runId), + ...WorkflowRunStatus(runResponse.status), + ...DeploymentId(deploymentId) + }); + await world.queue(`__wkf_workflow_${workflowName}`, { + runId: runResponse.runId, + traceCarrier + }, { + deploymentId + }); + return new Run(runResponse.runId); + }); + }); +} + +async function calc(n) { + throw new Error("You attempted to execute workflow calc function directly. To start a workflow, use start(calc) from workflow/api"); +} +calc.workflowId = "workflow//nitro-v3/workflows/0_demo.ts//calc"; + +const workflow_0_demo = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ + __proto__: null, + calc +}, Symbol.toStringTag, { value: 'Module' })); + +async function simple(i) { + throw new Error("You attempted to execute workflow simple function directly. To start a workflow, use start(simple) from workflow/api"); +} +simple.workflowId = "workflow//example/workflows/1_simple.ts//simple"; + +const workflow_1_simple = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ + __proto__: null, + simple +}, Symbol.toStringTag, { value: 'Module' })); + +async function control_flow() { + throw new Error("You attempted to execute workflow control_flow function directly. To start a workflow, use start(control_flow) from workflow/api"); +} +control_flow.workflowId = "workflow//example/workflows/2_control_flow.ts//control_flow"; + +const workflow_2_control_flow = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ + __proto__: null, + control_flow +}, Symbol.toStringTag, { value: 'Module' })); + +async function genStream() { + const stream = new ReadableStream({ + async start (controller) { + const encoder = new TextEncoder(); + for(let i = 0; i < 30; i++){ + const chunk = encoder.encode(`${i} +`); + controller.enqueue(chunk); + console.log(`Enqueued number: ${i}`); + await new Promise((resolve)=>setTimeout(resolve, 2500)); + } + controller.close(); + } + }); + return stream; +} +async function consumeStreams(...streams2) { + const parts = []; + console.log("Consuming streams", streams2); + await Promise.all(streams2.map(async (s, i)=>{ + const reader = s.getReader(); + while(true){ + const result = await reader.read(); + if (result.done) break; + console.log(`Received ${result.value.length} bytes from stream ${i}: ${JSON.stringify(new TextDecoder().decode(result.value))}`); + parts.push(result.value); + } + })); + return Buffer.concat(parts).toString("utf8"); +} +async function streams() { + throw new Error("You attempted to execute workflow streams function directly. To start a workflow, use start(streams) from workflow/api"); +} +streams.workflowId = "workflow//example/workflows/3_streams.ts//streams"; + +const workflow_3_streams = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ + __proto__: null, + consumeStreams, + genStream, + streams +}, Symbol.toStringTag, { value: 'Module' })); + +async function ai(prompt) { + throw new Error("You attempted to execute workflow ai function directly. To start a workflow, use start(ai) from workflow/api"); +} +ai.workflowId = "workflow//example/workflows/4_ai.ts//ai"; +async function agent(prompt) { + throw new Error("You attempted to execute workflow agent function directly. To start a workflow, use start(agent) from workflow/api"); +} +agent.workflowId = "workflow//example/workflows/4_ai.ts//agent"; + +const workflow_4_ai = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ + __proto__: null, + agent, + ai +}, Symbol.toStringTag, { value: 'Module' })); + +async function withWorkflowMetadata() { + throw new Error("You attempted to execute workflow withWorkflowMetadata function directly. To start a workflow, use start(withWorkflowMetadata) from workflow/api"); +} +withWorkflowMetadata.workflowId = "workflow//example/workflows/5_hooks.ts//withWorkflowMetadata"; +async function withCreateHook() { + throw new Error("You attempted to execute workflow withCreateHook function directly. To start a workflow, use start(withCreateHook) from workflow/api"); +} +withCreateHook.workflowId = "workflow//example/workflows/5_hooks.ts//withCreateHook"; + +const workflow_5_hooks = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ + __proto__: null, + withCreateHook, + withWorkflowMetadata +}, Symbol.toStringTag, { value: 'Module' })); + +async function batchOverSteps() { + throw new Error("You attempted to execute workflow batchOverSteps function directly. To start a workflow, use start(batchOverSteps) from workflow/api"); +} +batchOverSteps.workflowId = "workflow//example/workflows/6_batching.ts//batchOverSteps"; +async function batchInStep() { + throw new Error("You attempted to execute workflow batchInStep function directly. To start a workflow, use start(batchInStep) from workflow/api"); +} +batchInStep.workflowId = "workflow//example/workflows/6_batching.ts//batchInStep"; + +const workflow_6_batching = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ + __proto__: null, + batchInStep, + batchOverSteps +}, Symbol.toStringTag, { value: 'Module' })); + +async function handleUserSignup(email) { + throw new Error("You attempted to execute workflow handleUserSignup function directly. To start a workflow, use start(handleUserSignup) from workflow/api"); +} +handleUserSignup.workflowId = "workflow//example/workflows/7_full.ts//handleUserSignup"; + +const workflow_7_full = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ + __proto__: null, + handleUserSignup +}, Symbol.toStringTag, { value: 'Module' })); + +async function addTenWorkflow(input) { + throw new Error("You attempted to execute workflow addTenWorkflow function directly. To start a workflow, use start(addTenWorkflow) from workflow/api"); +} +addTenWorkflow.workflowId = "workflow//example/workflows/98_duplicate_case.ts//addTenWorkflow"; +async function add(a, b) { + return a + b; +} + +const workflow_98_duplicate_case = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ + __proto__: null, + add, + addTenWorkflow +}, Symbol.toStringTag, { value: 'Module' })); + +const allWorkflows = { + "workflows/0_demo.ts": workflow_0_demo, + "workflows/1_simple.ts": workflow_1_simple, + "workflows/2_control_flow.ts": workflow_2_control_flow, + "workflows/3_streams.ts": workflow_3_streams, + "workflows/4_ai.ts": workflow_4_ai, + "workflows/5_hooks.ts": workflow_5_hooks, + "workflows/6_batching.ts": workflow_6_batching, + "workflows/7_full.ts": workflow_7_full, + "workflows/98_duplicate_case.ts": workflow_98_duplicate_case, + "workflows/99_e2e.ts": workflow_99_e2e +}; + +async function POST({ request }) { + const url = new URL(request.url); + const workflowFile = url.searchParams.get("workflowFile") || "workflows/99_e2e.ts"; + const workflows = allWorkflows[workflowFile]; + if (!workflows) { + return new Response(`Workflow file "${workflowFile}" not found`, { + status: 400 + }); + } + const workflowFn = url.searchParams.get("workflowFn") || "simple"; + const workflow = workflows[workflowFn]; + if (!workflow) { + return new Response(`Workflow "${workflowFn}" not found`, { status: 400 }); + } + let args = []; + const argsParam = url.searchParams.get("args"); + if (argsParam) { + args = argsParam.split(",").map((arg) => { + const num = parseFloat(arg); + return Number.isNaN(num) ? arg.trim() : num; + }); + } else { + const body = await request.text(); + if (body) { + args = hydrateWorkflowArguments(JSON.parse(body), globalThis); + } else { + args = [42]; + } + } + console.log(`Starting "${workflowFn}" workflow with args: ${args}`); + try { + const run = await start(workflow, args); + console.log("Run:", run); + return Response.json(run); + } catch (err) { + console.error(`Failed to start!!`, err); + throw err; + } +} +const GET = async ({ request }) => { + const url = new URL(request.url); + const runId = url.searchParams.get("runId"); + if (!runId) { + return new Response("No runId provided", { status: 400 }); + } + const outputStreamParam = url.searchParams.get("output-stream"); + if (outputStreamParam) { + const namespace = outputStreamParam === "1" ? void 0 : outputStreamParam; + const run = getRun(runId); + const stream = run.getReadable({ + namespace + }); + const streamWithFraming = new TransformStream({ + transform(chunk, controller) { + const data = chunk instanceof Uint8Array ? { data: Buffer.from(chunk).toString("base64") } : chunk; + controller.enqueue(`${JSON.stringify(data)} +`); + } + }); + return new Response(stream.pipeThrough(streamWithFraming), { + headers: { + "Content-Type": "application/octet-stream" + } + }); + } + try { + const run = getRun(runId); + const returnValue = await run.returnValue; + console.log("Return value:", returnValue); + return returnValue instanceof ReadableStream ? new Response(returnValue, { + headers: { + "Content-Type": "application/octet-stream" + } + }) : Response.json(returnValue); + } catch (error) { + if (error instanceof Error) { + if (WorkflowRunNotCompletedError.is(error)) { + return Response.json( + { + ...error, + name: error.name, + message: error.message + }, + { status: 202 } + ); + } + if (WorkflowRunFailedError.is(error)) { + const cause = error.cause; + return Response.json( + { + ...error, + name: error.name, + message: error.message, + cause: { + message: cause.message, + stack: cause.stack, + code: cause.code + } + }, + { status: 400 } + ); + } + } + console.error( + "Unexpected error while getting workflow return value:", + error + ); + return Response.json( + { + error: "Internal server error" + }, + { status: 500 } + ); + } +}; +const prerender = false; + +const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ + __proto__: null, + GET, + POST, + prerender +}, Symbol.toStringTag, { value: 'Module' })); + +const page = () => _page; + +export { page }; diff --git a/workbench/astro/dist/server/pages/index.astro.mjs b/workbench/astro/dist/server/pages/index.astro.mjs new file mode 100644 index 000000000..e8ff7a486 --- /dev/null +++ b/workbench/astro/dist/server/pages/index.astro.mjs @@ -0,0 +1 @@ +// Contents removed by Astro as it's used for prerendering only \ No newline at end of file diff --git a/workbench/astro/dist/server/renderers.mjs b/workbench/astro/dist/server/renderers.mjs new file mode 100644 index 000000000..a97849f70 --- /dev/null +++ b/workbench/astro/dist/server/renderers.mjs @@ -0,0 +1,3 @@ +const renderers = []; + +export { renderers }; diff --git a/workbench/astro/src/lib/_workflows.ts b/workbench/astro/src/lib/_workflows.ts new file mode 100644 index 000000000..809ff2c0c --- /dev/null +++ b/workbench/astro/src/lib/_workflows.ts @@ -0,0 +1,26 @@ +// Auto-generated by workbench/scripts/generate-workflows-registry.js +// Do not edit this file manually - it will be regenerated on build + +import * as workflow_0_demo from '../workflows/0_demo'; +import * as workflow_1_simple from '../workflows/1_simple'; +import * as workflow_2_control_flow from '../workflows/2_control_flow'; +import * as workflow_3_streams from '../workflows/3_streams'; +import * as workflow_4_ai from '../workflows/4_ai'; +import * as workflow_5_hooks from '../workflows/5_hooks'; +import * as workflow_6_batching from '../workflows/6_batching'; +import * as workflow_7_full from '../workflows/7_full'; +import * as workflow_98_duplicate_case from '../workflows/98_duplicate_case'; +import * as workflow_99_e2e from '../workflows/99_e2e'; + +export const allWorkflows = { + 'workflows/0_demo.ts': workflow_0_demo, + 'workflows/1_simple.ts': workflow_1_simple, + 'workflows/2_control_flow.ts': workflow_2_control_flow, + 'workflows/3_streams.ts': workflow_3_streams, + 'workflows/4_ai.ts': workflow_4_ai, + 'workflows/5_hooks.ts': workflow_5_hooks, + 'workflows/6_batching.ts': workflow_6_batching, + 'workflows/7_full.ts': workflow_7_full, + 'workflows/98_duplicate_case.ts': workflow_98_duplicate_case, + 'workflows/99_e2e.ts': workflow_99_e2e, +} as const; diff --git a/workbench/example/workflows/7_full.ts b/workbench/example/workflows/7_full.ts index 173c7196e..c035c2c67 100644 --- a/workbench/example/workflows/7_full.ts +++ b/workbench/example/workflows/7_full.ts @@ -1,24 +1,24 @@ -import { createWebhook, sleep } from 'workflow'; +import { createWebhook, sleep } from "workflow"; export async function handleUserSignup(email: string) { - 'use workflow'; + "use workflow"; const user = await createUser(email); await sendWelcomeEmail(user); - await sleep('5s'); + await sleep("5s"); const webhook = createWebhook(); await sendOnboardingEmail(user, webhook.url); await webhook; - console.log('Webhook Resolved'); + console.log("Webhook Resolved"); - return { userId: user.id, status: 'onboarded' }; + return { userId: user.id, status: "onboarded" }; } async function createUser(email: string) { - 'use step'; + "use step"; console.log(`Creating a new user with email: ${email}`); @@ -26,16 +26,16 @@ async function createUser(email: string) { } async function sendWelcomeEmail(user: { id: string; email: string }) { - 'use step'; + "use step"; console.log(`Sending welcome email to user: ${user.id}`); } async function sendOnboardingEmail( user: { id: string; email: string }, - callback: string + callback: string, ) { - 'use step'; + "use step"; console.log(`Sending onboarding email to user: ${user.id}`); diff --git a/workbench/nextjs-turbopack/app/api/trigger/route.ts b/workbench/nextjs-turbopack/app/api/trigger/route.ts index f9b8d5ef4..466d9ed79 100644 --- a/workbench/nextjs-turbopack/app/api/trigger/route.ts +++ b/workbench/nextjs-turbopack/app/api/trigger/route.ts @@ -1,17 +1,19 @@ -import { getRun, start } from 'workflow/api'; +import { getRun, start } from "workflow/api"; +import { hydrateWorkflowArguments } from "workflow/internal/serialization"; +import { allWorkflows } from "@/_workflows"; import { WorkflowRunFailedError, WorkflowRunNotCompletedError, -} from 'workflow/internal/errors'; -import { hydrateWorkflowArguments } from 'workflow/internal/serialization'; -import { allWorkflows } from '@/_workflows'; +} from "workflow/internal/errors"; +import { hydrateWorkflowArguments } from "workflow/internal/serialization"; +import { allWorkflows } from "@/_workflows"; export async function POST(req: Request) { const url = new URL(req.url); const workflowFile = - url.searchParams.get('workflowFile') || 'workflows/99_e2e.ts'; + url.searchParams.get("workflowFile") || "workflows/99_e2e.ts"; if (!workflowFile) { - return new Response('No workflowFile query parameter provided', { + return new Response("No workflowFile query parameter provided", { status: 400, }); } @@ -22,9 +24,9 @@ export async function POST(req: Request) { }); } - const workflowFn = url.searchParams.get('workflowFn') || 'simple'; + const workflowFn = url.searchParams.get("workflowFn") || "simple"; if (!workflowFn) { - return new Response('No workflow query parameter provided', { + return new Response("No workflow query parameter provided", { status: 400, }); } @@ -36,9 +38,9 @@ export async function POST(req: Request) { let args: any[] = []; // Args from query string - const argsParam = url.searchParams.get('args'); + const argsParam = url.searchParams.get("args"); if (argsParam) { - args = argsParam.split(',').map((arg) => { + args = argsParam.split(",").map((arg) => { const num = parseFloat(arg); return Number.isNaN(num) ? arg.trim() : num; }); @@ -55,7 +57,7 @@ export async function POST(req: Request) { try { const run = await start(workflow as any, args as any); - console.log('Run:', run); + console.log("Run:", run); return Response.json(run); } catch (err) { console.error(`Failed to start!!`, err); @@ -65,14 +67,14 @@ export async function POST(req: Request) { export async function GET(req: Request) { const url = new URL(req.url); - const runId = url.searchParams.get('runId'); + const runId = url.searchParams.get("runId"); if (!runId) { - return new Response('No runId provided', { status: 400 }); + return new Response("No runId provided", { status: 400 }); } - const outputStreamParam = url.searchParams.get('output-stream'); + const outputStreamParam = url.searchParams.get("output-stream"); if (outputStreamParam) { - const namespace = outputStreamParam === '1' ? undefined : outputStreamParam; + const namespace = outputStreamParam === "1" ? undefined : outputStreamParam; const run = getRun(runId); const stream = run.getReadable({ namespace, @@ -82,14 +84,14 @@ export async function GET(req: Request) { transform(chunk, controller) { const data = chunk instanceof Uint8Array - ? { data: Buffer.from(chunk).toString('base64') } + ? { data: Buffer.from(chunk).toString("base64") } : chunk; controller.enqueue(`${JSON.stringify(data)}\n`); }, }); return new Response(stream.pipeThrough(streamWithFraming), { headers: { - 'Content-Type': 'application/octet-stream', + "Content-Type": "application/octet-stream", }, }); } @@ -97,11 +99,11 @@ export async function GET(req: Request) { try { const run = getRun(runId); const returnValue = await run.returnValue; - console.log('Return value:', returnValue); + console.log("Return value:", returnValue); return returnValue instanceof ReadableStream ? new Response(returnValue, { headers: { - 'Content-Type': 'application/octet-stream', + "Content-Type": "application/octet-stream", }, }) : Response.json(returnValue); @@ -114,7 +116,7 @@ export async function GET(req: Request) { name: error.name, message: error.message, }, - { status: 202 } + { status: 202 }, ); } @@ -131,20 +133,20 @@ export async function GET(req: Request) { code: cause.code, }, }, - { status: 400 } + { status: 400 }, ); } } console.error( - 'Unexpected error while getting workflow return value:', - error + "Unexpected error while getting workflow return value:", + error, ); return Response.json( { - error: 'Internal server error', + error: "Internal server error", }, - { status: 500 } + { status: 500 }, ); } } diff --git a/workbench/nextjs-webpack/app/api/trigger/route.ts b/workbench/nextjs-webpack/app/api/trigger/route.ts index d1dafb427..fba546dcf 100644 --- a/workbench/nextjs-webpack/app/api/trigger/route.ts +++ b/workbench/nextjs-webpack/app/api/trigger/route.ts @@ -1,25 +1,25 @@ -import { getRun, start } from 'workflow/api'; +import { getRun, start } from "workflow/api"; +import { hydrateWorkflowArguments } from "workflow/internal/serialization"; +import { allWorkflows } from "@/_workflows"; import { WorkflowRunFailedError, WorkflowRunNotCompletedError, -} from 'workflow/internal/errors'; -import { hydrateWorkflowArguments } from 'workflow/internal/serialization'; -import { allWorkflows } from '@/_workflows'; +} from "workflow/internal/errors"; export async function POST(req: Request) { const url = new URL(req.url); const workflowFile = - url.searchParams.get('workflowFile') || 'workflows/99_e2e.ts'; - const workflowFn = url.searchParams.get('workflowFn') || 'simple'; + url.searchParams.get("workflowFile") || "workflows/99_e2e.ts"; + const workflowFn = url.searchParams.get("workflowFn") || "simple"; - console.log('calling workflow', { workflowFile, workflowFn }); + console.log("calling workflow", { workflowFile, workflowFn }); let args: any[] = []; // Args from query string - const argsParam = url.searchParams.get('args'); + const argsParam = url.searchParams.get("args"); if (argsParam) { - args = argsParam.split(',').map((arg) => { + args = argsParam.split(",").map((arg) => { const num = parseFloat(arg); return Number.isNaN(num) ? arg.trim() : num; }); @@ -33,7 +33,7 @@ export async function POST(req: Request) { } } console.log( - `Starting "${workflowFile}/${workflowFn}" workflow with args: ${args}` + `Starting "${workflowFile}/${workflowFn}" workflow with args: ${args}`, ); try { @@ -41,7 +41,7 @@ export async function POST(req: Request) { if (!workflows) { return Response.json( { error: `Workflow file "${workflowFile}" not found` }, - { status: 404 } + { status: 404 }, ); } @@ -49,12 +49,12 @@ export async function POST(req: Request) { if (!workflow) { return Response.json( { error: `Function "${workflowFn}" not found in ${workflowFile}` }, - { status: 400 } + { status: 400 }, ); } const run = await start(workflow as any, args); - console.log('Run:', run); + console.log("Run:", run); return Response.json(run); } catch (err) { console.error(`Failed to start!!`, err); @@ -64,14 +64,14 @@ export async function POST(req: Request) { export async function GET(req: Request) { const url = new URL(req.url); - const runId = url.searchParams.get('runId'); + const runId = url.searchParams.get("runId"); if (!runId) { - return new Response('No runId provided', { status: 400 }); + return new Response("No runId provided", { status: 400 }); } - const outputStreamParam = url.searchParams.get('output-stream'); + const outputStreamParam = url.searchParams.get("output-stream"); if (outputStreamParam) { - const namespace = outputStreamParam === '1' ? undefined : outputStreamParam; + const namespace = outputStreamParam === "1" ? undefined : outputStreamParam; const run = getRun(runId); const stream = run.getReadable({ namespace, @@ -81,14 +81,14 @@ export async function GET(req: Request) { transform(chunk, controller) { const data = chunk instanceof Uint8Array - ? { data: Buffer.from(chunk).toString('base64') } + ? { data: Buffer.from(chunk).toString("base64") } : chunk; controller.enqueue(`${JSON.stringify(data)}\n`); }, }); return new Response(stream.pipeThrough(streamWithFraming), { headers: { - 'Content-Type': 'application/octet-stream', + "Content-Type": "application/octet-stream", }, }); } @@ -96,11 +96,11 @@ export async function GET(req: Request) { try { const run = getRun(runId); const returnValue = await run.returnValue; - console.log('Return value:', returnValue); + console.log("Return value:", returnValue); return returnValue instanceof ReadableStream ? new Response(returnValue, { headers: { - 'Content-Type': 'application/octet-stream', + "Content-Type": "application/octet-stream", }, }) : Response.json(returnValue); @@ -113,7 +113,7 @@ export async function GET(req: Request) { name: error.name, message: error.message, }, - { status: 202 } + { status: 202 }, ); } @@ -130,20 +130,20 @@ export async function GET(req: Request) { code: cause.code, }, }, - { status: 400 } + { status: 400 }, ); } } console.error( - 'Unexpected error while getting workflow return value:', - error + "Unexpected error while getting workflow return value:", + error, ); return Response.json( { - error: 'Internal server error', + error: "Internal server error", }, - { status: 500 } + { status: 500 }, ); } } diff --git a/workbench/sveltekit/src/routes/api/trigger/+server.ts b/workbench/sveltekit/src/routes/api/trigger/+server.ts index 6492f436d..f18feaba9 100644 --- a/workbench/sveltekit/src/routes/api/trigger/+server.ts +++ b/workbench/sveltekit/src/routes/api/trigger/+server.ts @@ -1,18 +1,20 @@ -import type { RequestHandler } from '@sveltejs/kit'; -import { getRun, start } from 'workflow/api'; +import { type RequestHandler } from "@sveltejs/kit"; +import { getRun, start } from "workflow/api"; +import { hydrateWorkflowArguments } from "workflow/internal/serialization"; +import { allWorkflows } from "$lib/_workflows.js"; import { WorkflowRunFailedError, WorkflowRunNotCompletedError, -} from 'workflow/internal/errors'; -import { hydrateWorkflowArguments } from 'workflow/internal/serialization'; -import { allWorkflows } from '$lib/_workflows.js'; +} from "workflow/internal/errors"; +import { hydrateWorkflowArguments } from "workflow/internal/serialization"; +import { allWorkflows } from "$lib/_workflows.js"; export const POST: RequestHandler = async ({ request }) => { const url = new URL(request.url); const workflowFile = - url.searchParams.get('workflowFile') || 'workflows/99_e2e.ts'; + url.searchParams.get("workflowFile") || "workflows/99_e2e.ts"; if (!workflowFile) { - return new Response('No workflowFile query parameter provided', { + return new Response("No workflowFile query parameter provided", { status: 400, }); } @@ -23,9 +25,9 @@ export const POST: RequestHandler = async ({ request }) => { }); } - const workflowFn = url.searchParams.get('workflowFn') || 'simple'; + const workflowFn = url.searchParams.get("workflowFn") || "simple"; if (!workflowFn) { - return new Response('No workflow query parameter provided', { + return new Response("No workflow query parameter provided", { status: 400, }); } @@ -37,9 +39,9 @@ export const POST: RequestHandler = async ({ request }) => { let args: any[] = []; // Args from query string - const argsParam = url.searchParams.get('args'); + const argsParam = url.searchParams.get("args"); if (argsParam) { - args = argsParam.split(',').map((arg) => { + args = argsParam.split(",").map((arg) => { const num = parseFloat(arg); return Number.isNaN(num) ? arg.trim() : num; }); @@ -56,7 +58,7 @@ export const POST: RequestHandler = async ({ request }) => { try { const run = await start(workflow as any, args as any); - console.log('Run:', run); + console.log("Run:", run); return Response.json(run); } catch (err) { console.error(`Failed to start!!`, err); @@ -66,14 +68,14 @@ export const POST: RequestHandler = async ({ request }) => { export const GET: RequestHandler = async ({ request }) => { const url = new URL(request.url); - const runId = url.searchParams.get('runId'); + const runId = url.searchParams.get("runId"); if (!runId) { - return new Response('No runId provided', { status: 400 }); + return new Response("No runId provided", { status: 400 }); } - const outputStreamParam = url.searchParams.get('output-stream'); + const outputStreamParam = url.searchParams.get("output-stream"); if (outputStreamParam) { - const namespace = outputStreamParam === '1' ? undefined : outputStreamParam; + const namespace = outputStreamParam === "1" ? undefined : outputStreamParam; const run = getRun(runId); const stream = run.getReadable({ namespace, @@ -83,14 +85,14 @@ export const GET: RequestHandler = async ({ request }) => { transform(chunk, controller) { const data = chunk instanceof Uint8Array - ? { data: Buffer.from(chunk).toString('base64') } + ? { data: Buffer.from(chunk).toString("base64") } : chunk; controller.enqueue(`${JSON.stringify(data)}\n`); }, }); return new Response(stream.pipeThrough(streamWithFraming), { headers: { - 'Content-Type': 'application/octet-stream', + "Content-Type": "application/octet-stream", }, }); } @@ -98,11 +100,11 @@ export const GET: RequestHandler = async ({ request }) => { try { const run = getRun(runId); const returnValue = await run.returnValue; - console.log('Return value:', returnValue); + console.log("Return value:", returnValue); return returnValue instanceof ReadableStream ? new Response(returnValue, { headers: { - 'Content-Type': 'application/octet-stream', + "Content-Type": "application/octet-stream", }, }) : Response.json(returnValue); @@ -115,7 +117,7 @@ export const GET: RequestHandler = async ({ request }) => { name: error.name, message: error.message, }, - { status: 202 } + { status: 202 }, ); } @@ -132,20 +134,20 @@ export const GET: RequestHandler = async ({ request }) => { code: cause.code, }, }, - { status: 400 } + { status: 400 }, ); } } console.error( - 'Unexpected error while getting workflow return value:', - error + "Unexpected error while getting workflow return value:", + error, ); return Response.json( { - error: 'Internal server error', + error: "Internal server error", }, - { status: 500 } + { status: 500 }, ); } }; diff --git a/workbench/sveltekit/src/workflows/user-signup.ts b/workbench/sveltekit/src/workflows/user-signup.ts index 173c7196e..c035c2c67 100644 --- a/workbench/sveltekit/src/workflows/user-signup.ts +++ b/workbench/sveltekit/src/workflows/user-signup.ts @@ -1,24 +1,24 @@ -import { createWebhook, sleep } from 'workflow'; +import { createWebhook, sleep } from "workflow"; export async function handleUserSignup(email: string) { - 'use workflow'; + "use workflow"; const user = await createUser(email); await sendWelcomeEmail(user); - await sleep('5s'); + await sleep("5s"); const webhook = createWebhook(); await sendOnboardingEmail(user, webhook.url); await webhook; - console.log('Webhook Resolved'); + console.log("Webhook Resolved"); - return { userId: user.id, status: 'onboarded' }; + return { userId: user.id, status: "onboarded" }; } async function createUser(email: string) { - 'use step'; + "use step"; console.log(`Creating a new user with email: ${email}`); @@ -26,16 +26,16 @@ async function createUser(email: string) { } async function sendWelcomeEmail(user: { id: string; email: string }) { - 'use step'; + "use step"; console.log(`Sending welcome email to user: ${user.id}`); } async function sendOnboardingEmail( user: { id: string; email: string }, - callback: string + callback: string, ) { - 'use step'; + "use step"; console.log(`Sending onboarding email to user: ${user.id}`); diff --git a/workbench/vite/routes/api/hook.post.ts b/workbench/vite/routes/api/hook.post.ts index ecbdc636c..3065b8b6d 100644 --- a/workbench/vite/routes/api/hook.post.ts +++ b/workbench/vite/routes/api/hook.post.ts @@ -1,4 +1,4 @@ -import { getHookByToken, resumeHook } from 'workflow/api'; +import { getHookByToken, resumeHook } from "workflow/api"; export default async ({ req }: { req: Request }) => { const { token, data } = await req.json(); @@ -6,9 +6,9 @@ export default async ({ req }: { req: Request }) => { let hook: Awaited>; try { hook = await getHookByToken(token); - console.log('hook', hook); + console.log("hook", hook); } catch (error) { - console.log('error during getHookByToken', error); + console.log("error during getHookByToken", error); // TODO: `WorkflowAPIError` is not exported, so for now // we'll return 422 assuming it's the "invalid" token test case // NOTE: Need to return 422 because Nitro passes 404 requests to the dev server to handle. From 22838dbc42e4ec2db934d8f1393358e26114ef76 Mon Sep 17 00:00:00 2001 From: Adrian Date: Wed, 12 Nov 2025 09:25:59 -0800 Subject: [PATCH 03/61] fix: normalize workbench tests (#292) * Proper stacktrace propogation in world Proper stacktrace propogation in world * Standardize the error type in the world spec * Normalize Workbenches Normalize trigger scripts across workbenches fix: include hono in local build test test: include src dir for test test: add workflow dir config in test to fix sveltekit dev tests add temp 7_full in example wokrflow format fix(sveltekit): detecting workflow folders and customizable dir Remove 7_full and 1_simple error replace API symlink in webpack workbench Fix sveltekit and vite tests Fix sveltekit symlinks Test fixes Fix sveltekit workflows path Dont symlink routes in vite Include e2e tests for hono and vite * fix error tests post normalization * fix(sveltekit): reading file on hmr delete * changeset * fix(vite): add resolve symlink script * fix(vite): missing building on hmr * test local builder in vite * test: increase timeout on hookWorkflow * test: ignore vite based apps in crossFileWorkflow * test: fix nitro based apps status codes * fix: intercept default vite spa handler on 404 workflow routes * fix: vite hook route returning 422 * test: use 422 for hookWorkflow expected * test: fix hono returning 404 * chore: add comment to middleware to clarify * make api route for duplicate case * revert * revert: nitro builder * add back nitro unhandled rejection logic * test: add hono * changeset * fix: unused method * fix: remove duplicate import * remove * chore: add comments to clarify * test remove vite symlink script --------- Co-authored-by: Pranay Prakash --- packages/nitro/src/builders.ts | 9 +++++++++ workbench/nextjs-turbopack/app/api/trigger/route.ts | 2 -- workbench/nextjs-webpack/app/api/trigger/route.ts | 4 ++-- workbench/sveltekit/src/routes/api/trigger/+server.ts | 4 +--- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/packages/nitro/src/builders.ts b/packages/nitro/src/builders.ts index 8b36d24d1..4682c8039 100644 --- a/packages/nitro/src/builders.ts +++ b/packages/nitro/src/builders.ts @@ -69,5 +69,14 @@ export class LocalBuilder extends BaseBuilder { outfile: webhookRouteFile, bundle: false, }); + + // Post-process the generated file to wrap with SvelteKit request converter + let webhookRouteContent = await readFile(webhookRouteFile, 'utf-8'); + + // NOTE: This is a workaround to avoid crashing in local dev when context isn't set for waitUntil() + webhookRouteContent = `process.on('unhandledRejection', (reason) => { if (reason !== undefined) console.error('Unhandled rejection detected', reason); }); +${webhookRouteContent}`; + + await writeFile(webhookRouteFile, webhookRouteContent); } } diff --git a/workbench/nextjs-turbopack/app/api/trigger/route.ts b/workbench/nextjs-turbopack/app/api/trigger/route.ts index 466d9ed79..ac559d5d1 100644 --- a/workbench/nextjs-turbopack/app/api/trigger/route.ts +++ b/workbench/nextjs-turbopack/app/api/trigger/route.ts @@ -1,6 +1,4 @@ import { getRun, start } from "workflow/api"; -import { hydrateWorkflowArguments } from "workflow/internal/serialization"; -import { allWorkflows } from "@/_workflows"; import { WorkflowRunFailedError, WorkflowRunNotCompletedError, diff --git a/workbench/nextjs-webpack/app/api/trigger/route.ts b/workbench/nextjs-webpack/app/api/trigger/route.ts index fba546dcf..76737ef22 100644 --- a/workbench/nextjs-webpack/app/api/trigger/route.ts +++ b/workbench/nextjs-webpack/app/api/trigger/route.ts @@ -1,10 +1,10 @@ import { getRun, start } from "workflow/api"; -import { hydrateWorkflowArguments } from "workflow/internal/serialization"; -import { allWorkflows } from "@/_workflows"; import { WorkflowRunFailedError, WorkflowRunNotCompletedError, } from "workflow/internal/errors"; +import { hydrateWorkflowArguments } from "workflow/internal/serialization"; +import { allWorkflows } from "@/_workflows"; export async function POST(req: Request) { const url = new URL(req.url); diff --git a/workbench/sveltekit/src/routes/api/trigger/+server.ts b/workbench/sveltekit/src/routes/api/trigger/+server.ts index f18feaba9..bf1801826 100644 --- a/workbench/sveltekit/src/routes/api/trigger/+server.ts +++ b/workbench/sveltekit/src/routes/api/trigger/+server.ts @@ -1,7 +1,5 @@ -import { type RequestHandler } from "@sveltejs/kit"; +import type { RequestHandler } from "@sveltejs/kit"; import { getRun, start } from "workflow/api"; -import { hydrateWorkflowArguments } from "workflow/internal/serialization"; -import { allWorkflows } from "$lib/_workflows.js"; import { WorkflowRunFailedError, WorkflowRunNotCompletedError, From f820ae1d2a7ca0856f3af10e5cc9a58fe71e8b38 Mon Sep 17 00:00:00 2001 From: Adrian Date: Wed, 12 Nov 2025 20:05:36 -0800 Subject: [PATCH 04/61] fix: cleanup builder directories (#319) * fix: add sveltekit server routes to builder * fix: remove root workflow dir check * fix missing root level workflow route * Fix: The constructor now hardcodes `dirs: ['src/routes', 'src/lib']` which silently ignores any user\-provided `dirs` option passed to the plugin\, breaking the documented API and removing support for custom workflow directories\. * Fix: The test expectations don\'t match the new implementation of `getWorkflowDirs()`\. The mock provides `scanDirs` which the new code no longer uses\, and the new implementation adds scanning of `routesDir` and `apiDir` instead\. * fix(nitro): use src dir --------- Co-authored-by: Vercel Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com> --- packages/sveltekit/src/builder.ts | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/packages/sveltekit/src/builder.ts b/packages/sveltekit/src/builder.ts index 8e4b4dd5b..5a9e0ace6 100644 --- a/packages/sveltekit/src/builder.ts +++ b/packages/sveltekit/src/builder.ts @@ -227,24 +227,3 @@ export const OPTIONS = createSvelteKitHandler('OPTIONS');`, } } } - -/** - * Gets the list of directories to scan for workflow files. - */ -export function getWorkflowDirs(options?: { dirs?: string[] }): string[] { - return unique([ - // User-provided directories take precedence - ...(options?.dirs ?? []), - // Scan routes directories (like Next.js does with app/pages directories) - // This allows workflows to be placed anywhere in the routes tree - "routes", - "src/routes", - // Also scan dedicated workflow directories for organization - "workflows", - "src/workflows", - ]).sort(); -} - -function unique(array: T[]): T[] { - return Array.from(new Set(array)); -} From 559a29c21df323f3e327460b7e185bf2efc95430 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Thu, 13 Nov 2025 11:22:33 -0800 Subject: [PATCH 05/61] refactor(nitro): use suppressUndefinedRejections --- packages/nitro/src/builders.ts | 9 --------- 1 file changed, 9 deletions(-) diff --git a/packages/nitro/src/builders.ts b/packages/nitro/src/builders.ts index 4682c8039..8b36d24d1 100644 --- a/packages/nitro/src/builders.ts +++ b/packages/nitro/src/builders.ts @@ -69,14 +69,5 @@ export class LocalBuilder extends BaseBuilder { outfile: webhookRouteFile, bundle: false, }); - - // Post-process the generated file to wrap with SvelteKit request converter - let webhookRouteContent = await readFile(webhookRouteFile, 'utf-8'); - - // NOTE: This is a workaround to avoid crashing in local dev when context isn't set for waitUntil() - webhookRouteContent = `process.on('unhandledRejection', (reason) => { if (reason !== undefined) console.error('Unhandled rejection detected', reason); }); -${webhookRouteContent}`; - - await writeFile(webhookRouteFile, webhookRouteContent); } } From fb808574dd6dbc0062ad77046087f21b5eb2dee2 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 00:23:54 -0800 Subject: [PATCH 06/61] feat(astro): add @workflow/astro --- packages/astro/LICENSE.md | 201 ++++++++ packages/astro/README.md | 3 + packages/astro/package.json | 41 ++ packages/astro/src/builder.ts | 189 ++++++++ packages/astro/src/index.ts | 10 + packages/astro/src/plugin.ts | 160 +++++++ packages/astro/tsconfig.json | 12 + packages/builders/src/index.ts | 6 +- packages/builders/src/types.ts | 15 +- packages/workflow/package.json | 2 + packages/workflow/src/astro.ts | 1 + packages/world-local/src/queue.ts | 2 + pnpm-lock.yaml | 769 ++++++++++++++++++++++-------- 13 files changed, 1196 insertions(+), 215 deletions(-) create mode 100644 packages/astro/LICENSE.md create mode 100644 packages/astro/README.md create mode 100644 packages/astro/package.json create mode 100644 packages/astro/src/builder.ts create mode 100644 packages/astro/src/index.ts create mode 100644 packages/astro/src/plugin.ts create mode 100644 packages/astro/tsconfig.json create mode 100644 packages/workflow/src/astro.ts diff --git a/packages/astro/LICENSE.md b/packages/astro/LICENSE.md new file mode 100644 index 000000000..c4d680f55 --- /dev/null +++ b/packages/astro/LICENSE.md @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2025 Vercel Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/astro/README.md b/packages/astro/README.md new file mode 100644 index 000000000..17a1b2eab --- /dev/null +++ b/packages/astro/README.md @@ -0,0 +1,3 @@ +# workflow/astro + +The docs have moved! Refer to them [here](https://useworkflow.dev/) diff --git a/packages/astro/package.json b/packages/astro/package.json new file mode 100644 index 000000000..29bddf9e4 --- /dev/null +++ b/packages/astro/package.json @@ -0,0 +1,41 @@ +{ + "name": "@workflow/astro", + "version": "4.0.0-beta.1", + "description": "Astro integration for Workflow DevKit", + "type": "module", + "main": "dist/index.js", + "files": [ + "dist" + ], + "publishConfig": { + "access": "public" + }, + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/vercel/workflow.git", + "directory": "packages/astro" + }, + "exports": { + ".": "./dist/index.js" + }, + "scripts": { + "build": "tsc", + "dev": "tsc --watch", + "clean": "tsc --build --clean && rm -rf dist" + }, + "dependencies": { + "@swc/core": "1.11.24", + "@workflow/builders": "workspace:*", + "@workflow/swc-plugin": "workspace:*", + "fs-extra": "^11.3.2", + "exsolve": "^1.0.7", + "pathe": "^2.0.3" + }, + "devDependencies": { + "@types/fs-extra": "11.0.4", + "@types/node": "catalog:", + "@workflow/tsconfig": "workspace:*", + "vite": "7.1.11" + } +} diff --git a/packages/astro/src/builder.ts b/packages/astro/src/builder.ts new file mode 100644 index 000000000..9d5184f18 --- /dev/null +++ b/packages/astro/src/builder.ts @@ -0,0 +1,189 @@ +import { mkdir, readFile, writeFile } from 'node:fs/promises'; +import { join, resolve } from 'node:path'; +import { BaseBuilder, type AstroConfig } from '@workflow/builders'; + +// NOTE: This is the same as SvelteKit request converter, should merge +const NORMALIZE_REQUEST_CONVERTER = ` +async function normalizeRequestConverter(request) { + const options = { + method: request.method, + headers: new Headers(request.headers) + }; + if (!['GET', 'HEAD', 'OPTIONS', 'TRACE', 'CONNECT'].includes(request.method)) { + options.body = await request.arrayBuffer(); + } + return new Request(request.url, options); +} +`; + +export class AstroBuilder extends BaseBuilder { + constructor(config?: Partial) { + const workingDir = config?.workingDir || process.cwd(); + + super({ + ...config, + dirs: ['src/pages'], + buildTarget: 'astro' as const, + stepsBundlePath: '', // unused in base + workflowsBundlePath: '', // unused in base + webhookBundlePath: '', // unused in base + workingDir, + }); + } + + override async build(): Promise { + const pagesDir = resolve(this.config.workingDir, 'src/pages'); + const workflowGeneratedDir = join(pagesDir, '.well-known/workflow/v1'); + + // Ensure output directories exist + await mkdir(workflowGeneratedDir, { recursive: true }); + + // Add .gitignore to exclude generated files from version control + if (process.env.VERCEL_DEPLOYMENT_ID === undefined) { + await writeFile(join(workflowGeneratedDir, '.gitignore'), '*'); + } + + // Get workflow and step files to bundle + const inputFiles = await this.getInputFiles(); + const tsConfig = await this.getTsConfigOptions(); + + const options = { + inputFiles, + workflowGeneratedDir, + tsBaseUrl: tsConfig.baseUrl, + tsPaths: tsConfig.paths, + }; + + // Generate the three Astro route handlers + await this.buildStepsRoute(options); + await this.buildWorkflowsRoute(options); + await this.buildWebhookRoute({ workflowGeneratedDir }); + } + + private async buildStepsRoute({ + inputFiles, + workflowGeneratedDir, + tsPaths, + tsBaseUrl, + }: { + inputFiles: string[]; + workflowGeneratedDir: string; + tsBaseUrl?: string; + tsPaths?: Record; + }) { + // Create steps route: .well-known/workflow/v1/step.js + const stepsRouteFile = join(workflowGeneratedDir, 'step.js'); + await this.createStepsBundle({ + format: 'esm', + inputFiles, + outfile: stepsRouteFile, + externalizeNonSteps: true, + tsBaseUrl, + tsPaths, + }); + + // Post-process the generated file to wrap with SvelteKit request converter + let stepsRouteContent = await readFile(stepsRouteFile, 'utf-8'); + stepsRouteContent = stepsRouteContent.replace( + /export\s*\{\s*stepEntrypoint\s+as\s+POST\s*\}\s*;?$/m, + `${NORMALIZE_REQUEST_CONVERTER} +export const POST = async ({request}) => { + const normalRequest = await normalizeRequestConverter(request); + return stepEntrypoint(normalRequest); +} + +export const prerender = false;` + ); + await writeFile(stepsRouteFile, stepsRouteContent); + } + + private async buildWorkflowsRoute({ + inputFiles, + workflowGeneratedDir, + tsPaths, + tsBaseUrl, + }: { + inputFiles: string[]; + workflowGeneratedDir: string; + tsBaseUrl?: string; + tsPaths?: Record; + }) { + // Create workflows route: .well-known/workflow/v1/flow.js + const workflowsRouteFile = join(workflowGeneratedDir, 'flow.js'); + await this.createWorkflowsBundle({ + format: 'esm', + outfile: workflowsRouteFile, + bundleFinalOutput: false, + inputFiles, + tsBaseUrl, + tsPaths, + }); + + // Post-process the generated file to wrap with SvelteKit request converter + let workflowsRouteContent = await readFile(workflowsRouteFile, 'utf-8'); + workflowsRouteContent = workflowsRouteContent.replace( + /export const POST = workflowEntrypoint\(workflowCode\);?$/m, + `${NORMALIZE_REQUEST_CONVERTER} +export const POST = async ({request}) => { + const normalRequest = await normalizeRequestConverter(request); + return workflowEntrypoint(workflowCode)(normalRequest); +} + +export const prerender = false;` + ); + await writeFile(workflowsRouteFile, workflowsRouteContent); + } + + private async buildWebhookRoute({ + workflowGeneratedDir, + }: { + workflowGeneratedDir: string; + }) { + // Create webhook route: .well-known/workflow/v1/webhook/[token].js + const webhookRouteFile = join(workflowGeneratedDir, 'webhook/[token].js'); + + await this.createWebhookBundle({ + outfile: webhookRouteFile, + bundle: false, + suppressUndefinedRejections: true, + }); + + // // Post-process the gen // Post-process the generated file to wrap with SvelteKit request converter + let webhookRouteContent = await readFile(webhookRouteFile, 'utf-8'); + + // Update handler signature to accept token as parameter + webhookRouteContent = webhookRouteContent.replace( + /async function handler\(request\) \{[\s\S]*?const token = decodeURIComponent\(pathParts\[pathParts\.length - 1\]\);/, + `async function handler(request, token) {` + ); + + // Remove the URL parsing code since we get token from params + webhookRouteContent = webhookRouteContent.replace( + /const url = new URL\(request\.url\);[\s\S]*?const pathParts = url\.pathname\.split\('\/'\);[\s\S]*?\n/, + '' + ); + + // Replace all HTTP method exports with SvelteKit-compatible handlers + webhookRouteContent = webhookRouteContent.replace( + /export const GET = handler;\nexport const POST = handler;\nexport const PUT = handler;\nexport const PATCH = handler;\nexport const DELETE = handler;\nexport const HEAD = handler;\nexport const OPTIONS = handler;/, + `${NORMALIZE_REQUEST_CONVERTER} +const createHandler = (method) => async ({ request, params, platform }) => { + const normalRequest = await normalizeRequestConverter(request); + const response = await handler(normalRequest, params.token); + return response; +}; + +export const GET = createHandler('GET'); +export const POST = createHandler('POST'); +export const PUT = createHandler('PUT'); +export const PATCH = createHandler('PATCH'); +export const DELETE = createHandler('DELETE'); +export const HEAD = createHandler('HEAD'); +export const OPTIONS = createHandler('OPTIONS'); + +export const prerender = false;` + ); + + await writeFile(webhookRouteFile, webhookRouteContent); + } +} diff --git a/packages/astro/src/index.ts b/packages/astro/src/index.ts new file mode 100644 index 000000000..fc75a122d --- /dev/null +++ b/packages/astro/src/index.ts @@ -0,0 +1,10 @@ +import { AstroBuilder } from './builder.js'; + +const builder = new AstroBuilder(); + +// This needs to be in the top-level as we need to create these +// entries before svelte plugin is started or the entries are +// a race to be created before svelte discovers entries +await builder.build(); + +export { workflowPlugin } from './plugin.js'; diff --git a/packages/astro/src/plugin.ts b/packages/astro/src/plugin.ts new file mode 100644 index 000000000..48096dd01 --- /dev/null +++ b/packages/astro/src/plugin.ts @@ -0,0 +1,160 @@ +import { relative } from 'node:path'; +import { transform } from '@swc/core'; +import { resolveModulePath } from 'exsolve'; +import type { HotUpdateOptions, Plugin } from 'vite'; +import { AstroBuilder } from './builder.js'; + +export interface WorkflowPluginOptions { + /** + * Directories to scan for workflow files. + * If not specified, defaults to ['workflows', 'src/workflows', 'routes', 'src/routes'] + */ + dirs?: string[]; +} + +export function workflowPlugin(options?: WorkflowPluginOptions): Plugin { + let builder: AstroBuilder; + + return { + name: 'workflow:astro', + + // TODO: Move this to @workflow/vite or something since this is vite specific + // Transform workflow files with SWC + async transform(code: string, id: string) { + // Only apply the transform if file needs it + if (!code.match(/(use step|use workflow)/)) { + return null; + } + + const isTypeScript = id.endsWith('.ts') || id.endsWith('.tsx'); + const isTsx = id.endsWith('.tsx'); + + const swcPlugin = resolveModulePath('@workflow/swc-plugin', { + from: [import.meta.url], + }); + + // Calculate relative filename for SWC plugin + // The SWC plugin uses filename to generate workflowId, so it must be relative + const workingDir = process.cwd(); + const normalizedWorkingDir = workingDir + .replace(/\\/g, '/') + .replace(/\/$/, ''); + const normalizedFilepath = id.replace(/\\/g, '/'); + + // Windows fix: Use case-insensitive comparison to work around drive letter casing issues + const lowerWd = normalizedWorkingDir.toLowerCase(); + const lowerPath = normalizedFilepath.toLowerCase(); + + let relativeFilename: string; + if (lowerPath.startsWith(lowerWd + '/')) { + // File is under working directory - manually calculate relative path + relativeFilename = normalizedFilepath.substring( + normalizedWorkingDir.length + 1 + ); + } else if (lowerPath === lowerWd) { + // File IS the working directory (shouldn't happen) + relativeFilename = '.'; + } else { + // Use relative() for files outside working directory + relativeFilename = relative(workingDir, id).replace(/\\/g, '/'); + + if (relativeFilename.startsWith('../')) { + relativeFilename = relativeFilename + .split('/') + .filter((part) => part !== '..') + .join('/'); + } + } + + // Final safety check - ensure we never pass an absolute path to SWC + if (relativeFilename.includes(':') || relativeFilename.startsWith('/')) { + // This should rarely happen, but use filename split as last resort + relativeFilename = normalizedFilepath.split('/').pop() || 'unknown.ts'; + } + + // Transform with SWC + const result = await transform(code, { + filename: relativeFilename, + jsc: { + parser: { + syntax: isTypeScript ? 'typescript' : 'ecmascript', + tsx: isTsx, + }, + target: 'es2022', + experimental: { + plugins: [[swcPlugin, { mode: 'client' }]], + }, + }, + minify: false, + sourceMaps: true, + inlineSourcesContent: true, + }); + + return { + code: result.code, + map: result.map ? JSON.parse(result.map) : null, + }; + }, + + configResolved() { + builder = new AstroBuilder({ + dirs: options?.dirs, + }); + }, + + // TODO: Move this to @workflow/vite or something since this is vite specific + async hotUpdate(options: HotUpdateOptions) { + const { file, server, read } = options; + + // Check if this is a TS/JS file that might contain workflow directives + const jsTsRegex = /\.(ts|tsx|js|jsx|mjs|cjs)$/; + if (!jsTsRegex.test(file)) { + return; + } + + // Read the file to check for workflow/step directives + let content: string; + try { + content = await read(); + } catch { + // File might have been deleted - trigger rebuild to update generated routes + console.log('Workflow file deleted, regenerating routes...'); + try { + await builder.build(); + } catch (buildError) { + // Build might fail if files are being deleted during test cleanup + // Log but don't crash - the next successful change will trigger a rebuild + console.error('Build failed during file deletion:', buildError); + } + return; + } + + const useWorkflowPattern = /^\s*(['"])use workflow\1;?\s*$/m; + const useStepPattern = /^\s*(['"])use step\1;?\s*$/m; + + if (!useWorkflowPattern.test(content) && !useStepPattern.test(content)) { + return; + } + + // Rebuild everything - simpler and more reliable than tracking individual files + console.log('Workflow file changed, regenerating routes...'); + try { + await builder.build(); + } catch (buildError) { + // Build might fail if files are being modified/deleted during test cleanup + // Log but don't crash - the next successful change will trigger a rebuild + console.error('Build failed during HMR:', buildError); + return; + } + + // Trigger full reload of workflow routes + server.ws.send({ + type: 'full-reload', + path: '*', + }); + + // Let Vite handle the normal HMR for the changed file + return; + }, + }; +} diff --git a/packages/astro/tsconfig.json b/packages/astro/tsconfig.json new file mode 100644 index 000000000..ba5d9aec0 --- /dev/null +++ b/packages/astro/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "@workflow/tsconfig/base.json", + "compilerOptions": { + "outDir": "dist", + "target": "es2022", + "module": "preserve", + "baseUrl": ".", + "moduleResolution": "bundler" + }, + "include": ["src"], + "exclude": ["node_modules", "**/*.test.ts"] +} diff --git a/packages/builders/src/index.ts b/packages/builders/src/index.ts index 1301c5461..d949717b6 100644 --- a/packages/builders/src/index.ts +++ b/packages/builders/src/index.ts @@ -8,6 +8,7 @@ export { createNodeModuleErrorPlugin } from './node-module-esbuild-plugin.js'; export { StandaloneBuilder } from './standalone.js'; export { createSwcPlugin } from './swc-esbuild-plugin.js'; export type { + AstroConfig, BuildTarget, NextConfig, StandaloneConfig, @@ -15,8 +16,5 @@ export type { VercelBuildOutputConfig, WorkflowConfig, } from './types.js'; -export { - isValidBuildTarget, - validBuildTargets, -} from './types.js'; +export { isValidBuildTarget, validBuildTargets } from './types.js'; export { VercelBuildOutputAPIBuilder } from './vercel-build-output-api.js'; diff --git a/packages/builders/src/types.ts b/packages/builders/src/types.ts index 5c514142f..d0db71912 100644 --- a/packages/builders/src/types.ts +++ b/packages/builders/src/types.ts @@ -3,6 +3,7 @@ export const validBuildTargets = [ 'vercel-build-output-api', 'next', 'sveltekit', + 'astro', ] as const; export type BuildTarget = (typeof validBuildTargets)[number]; @@ -66,6 +67,17 @@ export interface SvelteKitConfig extends BaseWorkflowConfig { webhookBundlePath: string; } +/** + * Configuration for Astro builds. + */ +export interface AstroConfig extends BaseWorkflowConfig { + buildTarget: 'astro'; + // Astro builder computes paths dynamically, so these are not used + stepsBundlePath: string; + workflowsBundlePath: string; + webhookBundlePath: string; +} + /** * Discriminated union of all builder configuration types. */ @@ -73,7 +85,8 @@ export type WorkflowConfig = | StandaloneConfig | VercelBuildOutputConfig | NextConfig - | SvelteKitConfig; + | SvelteKitConfig + | AstroConfig; export function isValidBuildTarget( target: string | undefined diff --git a/packages/workflow/package.json b/packages/workflow/package.json index 278c3d8cb..c6feb14c5 100644 --- a/packages/workflow/package.json +++ b/packages/workflow/package.json @@ -41,6 +41,7 @@ "./nitro": "./dist/nitro.js", "./nuxt": "./dist/nuxt.js", "./sveltekit": "./dist/sveltekit.js", + "./astro": "./dist/astro.js", "./rollup": "./dist/rollup.js", "./vite": "./dist/vite.js", "./runtime": "./dist/runtime.js" @@ -53,6 +54,7 @@ "typecheck": "tsc --noEmit" }, "dependencies": { + "@workflow/astro": "workspace:*", "@workflow/cli": "workspace:*", "@workflow/core": "workspace:*", "@workflow/errors": "workspace:*", diff --git a/packages/workflow/src/astro.ts b/packages/workflow/src/astro.ts new file mode 100644 index 000000000..7caf16677 --- /dev/null +++ b/packages/workflow/src/astro.ts @@ -0,0 +1 @@ +export * from '@workflow/astro'; diff --git a/packages/world-local/src/queue.ts b/packages/world-local/src/queue.ts index d103baa02..b186c1327 100644 --- a/packages/world-local/src/queue.ts +++ b/packages/world-local/src/queue.ts @@ -127,6 +127,8 @@ export function createQueue(config: Partial): Queue { const headers = HeaderParser.safeParse(Object.fromEntries(req.headers)); if (!headers.success || !req.body) { + console.log(!headers.success); + console.log(!req.body); return Response.json( { error: !req.body diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 849006af1..ea8a3df84 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -184,13 +184,13 @@ importers: version: 5.1.0 fumadocs-core: specifier: ^16.0.11 - version: 16.0.14(@types/react@19.1.13)(lucide-react@0.544.0(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + version: 16.0.15(@types/react@19.1.13)(lucide-react@0.544.0(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) fumadocs-mdx: specifier: 13.0.8 - version: 13.0.8(fumadocs-core@16.0.14(@types/react@19.1.13)(lucide-react@0.544.0(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 13.0.8(fumadocs-core@16.0.15(@types/react@19.1.13)(lucide-react@0.544.0(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) fumadocs-typescript: specifier: ^4.0.13 - version: 4.0.13(@types/react@19.1.13)(fumadocs-core@16.0.14(@types/react@19.1.13)(lucide-react@0.544.0(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(fumadocs-ui@16.0.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(lucide-react@0.544.0(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(tailwindcss@4.1.13))(typescript@5.9.3) + version: 4.0.13(@types/react@19.1.13)(fumadocs-core@16.0.15(@types/react@19.1.13)(lucide-react@0.544.0(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(fumadocs-ui@16.0.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(lucide-react@0.544.0(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(tailwindcss@4.1.13))(typescript@5.9.3) fumadocs-ui: specifier: 16.0.11 version: 16.0.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(lucide-react@0.544.0(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(tailwindcss@4.1.13) @@ -314,6 +314,40 @@ importers: specifier: workspace:* version: link:../workflow + packages/astro: + dependencies: + '@swc/core': + specifier: 1.11.24 + version: 1.11.24 + '@workflow/builders': + specifier: workspace:* + version: link:../builders + '@workflow/swc-plugin': + specifier: workspace:* + version: link:../swc-plugin-workflow + exsolve: + specifier: ^1.0.7 + version: 1.0.7 + fs-extra: + specifier: ^11.3.2 + version: 11.3.2 + pathe: + specifier: ^2.0.3 + version: 2.0.3 + devDependencies: + '@types/fs-extra': + specifier: 11.0.4 + version: 11.0.4 + '@types/node': + specifier: 'catalog:' + version: 22.19.0 + '@workflow/tsconfig': + specifier: workspace:* + version: link:../tsconfig + vite: + specifier: 7.1.11 + version: 7.1.11(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + packages/builders: dependencies: '@swc/core': @@ -612,7 +646,7 @@ importers: version: link:../tsconfig nitro: specifier: 'catalog:' - version: 3.0.1-alpha.1(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(ioredis@5.8.2)(lru-cache@11.2.2)(rollup@4.53.2)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 3.0.1-alpha.1(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(ioredis@5.8.2)(lru-cache@11.2.2)(rollup@4.53.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) vite: specifier: 7.1.12 version: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) @@ -640,7 +674,7 @@ importers: version: link:../tsconfig nuxt: specifier: 4.0.0 - version: 4.0.0(@biomejs/biome@2.3.3)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@22.19.0)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(@vue/compiler-sfc@3.5.22)(better-sqlite3@11.10.0)(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.53.2)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(yaml@2.8.1) + version: 4.0.0(@biomejs/biome@2.3.3)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@22.19.0)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(@vue/compiler-sfc@3.5.22)(better-sqlite3@11.10.0)(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(yaml@2.8.1) packages/sveltekit: dependencies: @@ -875,6 +909,9 @@ importers: '@opentelemetry/api': specifier: '1' version: 1.9.0 + '@workflow/astro': + specifier: workspace:* + version: link:../astro '@workflow/cli': specifier: workspace:* version: link:../cli @@ -1135,10 +1172,10 @@ importers: version: 5.1.0 nitro: specifier: 'catalog:' - version: 3.0.1-alpha.1(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(ioredis@5.8.2)(lru-cache@11.2.2)(rollup@4.53.2)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 3.0.1-alpha.1(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(ioredis@5.8.2)(lru-cache@11.2.2)(rollup@4.53.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) srvx: specifier: ^0.9.2 - version: 0.9.6 + version: 0.9.4 devDependencies: '@types/express': specifier: ^5.0.5 @@ -1151,7 +1188,7 @@ importers: version: 4.2.0 openai: specifier: ^6.1.0 - version: 6.6.0(ws@8.18.3)(zod@4.1.11) + version: 6.9.0(ws@8.18.3)(zod@4.1.11) workflow: specifier: workspace:* version: link:../../packages/workflow @@ -1172,7 +1209,7 @@ importers: version: 4.2.0 nitro: specifier: 'catalog:' - version: 3.0.1-alpha.1(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(ioredis@5.8.2)(lru-cache@11.2.2)(rollup@4.53.2)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 3.0.1-alpha.1(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(ioredis@5.8.2)(lru-cache@11.2.2)(rollup@4.53.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) openai: specifier: ^6.6.0 version: 6.6.0(ws@8.18.3)(zod@4.1.11) @@ -1325,13 +1362,13 @@ importers: version: 4.2.0 nitro: specifier: 'catalog:' - version: 3.0.1-alpha.1(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(ioredis@5.8.2)(lru-cache@11.2.2)(rollup@4.53.2)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 3.0.1-alpha.1(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(ioredis@5.8.2)(lru-cache@11.2.2)(rollup@4.53.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) openai: specifier: ^6.1.0 version: 6.6.0(ws@8.18.3)(zod@4.1.11) rollup: specifier: ^4.53.2 - version: 4.53.2 + version: 4.53.3 workflow: specifier: workspace:* version: link:../../packages/workflow @@ -1380,13 +1417,13 @@ importers: version: 4.2.0 nitro: specifier: 'catalog:' - version: 3.0.1-alpha.1(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(ioredis@5.8.2)(lru-cache@11.2.2)(rollup@4.53.2)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 3.0.1-alpha.1(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(ioredis@5.8.2)(lru-cache@11.2.2)(rollup@4.53.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) openai: specifier: ^6.1.0 version: 6.6.0(ws@8.18.3)(zod@4.1.11) rollup: specifier: ^4.53.2 - version: 4.53.2 + version: 4.53.3 workflow: specifier: workspace:* version: link:../../packages/workflow @@ -1414,7 +1451,7 @@ importers: version: 4.2.0 nuxt: specifier: ^4.1.3 - version: 4.1.3(@biomejs/biome@2.3.3)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@22.19.0)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(@vue/compiler-sfc@3.5.22)(better-sqlite3@11.10.0)(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.53.2)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(yaml@2.8.1) + version: 4.1.3(@biomejs/biome@2.3.3)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@22.19.0)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(@vue/compiler-sfc@3.5.22)(better-sqlite3@11.10.0)(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(yaml@2.8.1) openai: specifier: ^6.6.0 version: 6.6.0(ws@8.18.3)(zod@4.1.11) @@ -1441,7 +1478,7 @@ importers: version: 5.4.0(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))) '@sveltejs/adapter-vercel': specifier: ^6.1.1 - version: 6.1.1(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(rollup@4.53.2) + version: 6.1.1(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(rollup@4.53.3) '@swc/core': specifier: 1.11.24 version: 1.11.24 @@ -1506,7 +1543,7 @@ importers: version: 4.2.0 nitro: specifier: 'catalog:' - version: 3.0.1-alpha.1(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(ioredis@5.8.2)(lru-cache@11.2.2)(rollup@4.53.2)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 3.0.1-alpha.1(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(ioredis@5.8.2)(lru-cache@11.2.2)(rollup@4.53.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) openai: specifier: ^6.6.0 version: 6.6.0(ws@8.18.3)(zod@4.1.11) @@ -5348,113 +5385,223 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.53.2': - resolution: {integrity: sha512-yDPzwsgiFO26RJA4nZo8I+xqzh7sJTZIWQOxn+/XOdPE31lAvLIYCKqjV+lNH/vxE2L2iH3plKxDCRK6i+CwhA==} + '@rollup/rollup-android-arm-eabi@4.52.5': + resolution: {integrity: sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.53.2': - resolution: {integrity: sha512-k8FontTxIE7b0/OGKeSN5B6j25EuppBcWM33Z19JoVT7UTXFSo3D9CdU39wGTeb29NO3XxpMNauh09B+Ibw+9g==} + '@rollup/rollup-android-arm-eabi@4.53.3': + resolution: {integrity: sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.52.5': + resolution: {integrity: sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-android-arm64@4.53.3': + resolution: {integrity: sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.53.2': - resolution: {integrity: sha512-A6s4gJpomNBtJ2yioj8bflM2oogDwzUiMl2yNJ2v9E7++sHrSrsQ29fOfn5DM/iCzpWcebNYEdXpaK4tr2RhfQ==} + '@rollup/rollup-darwin-arm64@4.52.5': + resolution: {integrity: sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-arm64@4.53.3': + resolution: {integrity: sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.53.2': - resolution: {integrity: sha512-e6XqVmXlHrBlG56obu9gDRPW3O3hLxpwHpLsBJvuI8qqnsrtSZ9ERoWUXtPOkY8c78WghyPHZdmPhHLWNdAGEw==} + '@rollup/rollup-darwin-x64@4.52.5': + resolution: {integrity: sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.53.2': - resolution: {integrity: sha512-v0E9lJW8VsrwPux5Qe5CwmH/CF/2mQs6xU1MF3nmUxmZUCHazCjLgYvToOk+YuuUqLQBio1qkkREhxhc656ViA==} + '@rollup/rollup-darwin-x64@4.53.3': + resolution: {integrity: sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.52.5': + resolution: {integrity: sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.53.2': - resolution: {integrity: sha512-ClAmAPx3ZCHtp6ysl4XEhWU69GUB1D+s7G9YjHGhIGCSrsg00nEGRRZHmINYxkdoJehde8VIsDC5t9C0gb6yqA==} + '@rollup/rollup-freebsd-arm64@4.53.3': + resolution: {integrity: sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.52.5': + resolution: {integrity: sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.53.3': + resolution: {integrity: sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.53.2': - resolution: {integrity: sha512-EPlb95nUsz6Dd9Qy13fI5kUPXNSljaG9FiJ4YUGU1O/Q77i5DYFW5KR8g1OzTcdZUqQQ1KdDqsTohdFVwCwjqg==} + '@rollup/rollup-linux-arm-gnueabihf@4.52.5': + resolution: {integrity: sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-gnueabihf@4.53.3': + resolution: {integrity: sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.52.5': + resolution: {integrity: sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.53.2': - resolution: {integrity: sha512-BOmnVW+khAUX+YZvNfa0tGTEMVVEerOxN0pDk2E6N6DsEIa2Ctj48FOMfNDdrwinocKaC7YXUZ1pHlKpnkja/Q==} + '@rollup/rollup-linux-arm-musleabihf@4.53.3': + resolution: {integrity: sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.53.2': - resolution: {integrity: sha512-Xt2byDZ+6OVNuREgBXr4+CZDJtrVso5woFtpKdGPhpTPHcNG7D8YXeQzpNbFRxzTVqJf7kvPMCub/pcGUWgBjA==} + '@rollup/rollup-linux-arm64-gnu@4.52.5': + resolution: {integrity: sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.53.3': + resolution: {integrity: sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.53.2': - resolution: {integrity: sha512-+LdZSldy/I9N8+klim/Y1HsKbJ3BbInHav5qE9Iy77dtHC/pibw1SR/fXlWyAk0ThnpRKoODwnAuSjqxFRDHUQ==} + '@rollup/rollup-linux-arm64-musl@4.52.5': + resolution: {integrity: sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loong64-gnu@4.53.2': - resolution: {integrity: sha512-8ms8sjmyc1jWJS6WdNSA23rEfdjWB30LH8Wqj0Cqvv7qSHnvw6kgMMXRdop6hkmGPlyYBdRPkjJnj3KCUHV/uQ==} + '@rollup/rollup-linux-arm64-musl@4.53.3': + resolution: {integrity: sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loong64-gnu@4.52.5': + resolution: {integrity: sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-ppc64-gnu@4.53.2': - resolution: {integrity: sha512-3HRQLUQbpBDMmzoxPJYd3W6vrVHOo2cVW8RUo87Xz0JPJcBLBr5kZ1pGcQAhdZgX9VV7NbGNipah1omKKe23/g==} + '@rollup/rollup-linux-loong64-gnu@4.53.3': + resolution: {integrity: sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.52.5': + resolution: {integrity: sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.53.2': - resolution: {integrity: sha512-fMjKi+ojnmIvhk34gZP94vjogXNNUKMEYs+EDaB/5TG/wUkoeua7p7VCHnE6T2Tx+iaghAqQX8teQzcvrYpaQA==} + '@rollup/rollup-linux-ppc64-gnu@4.53.3': + resolution: {integrity: sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.52.5': + resolution: {integrity: sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.53.2': - resolution: {integrity: sha512-XuGFGU+VwUUV5kLvoAdi0Wz5Xbh2SrjIxCtZj6Wq8MDp4bflb/+ThZsVxokM7n0pcbkEr2h5/pzqzDYI7cCgLQ==} + '@rollup/rollup-linux-riscv64-gnu@4.53.3': + resolution: {integrity: sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.53.2': - resolution: {integrity: sha512-w6yjZF0P+NGzWR3AXWX9zc0DNEGdtvykB03uhonSHMRa+oWA6novflo2WaJr6JZakG2ucsyb+rvhrKac6NIy+w==} + '@rollup/rollup-linux-riscv64-musl@4.52.5': + resolution: {integrity: sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.53.3': + resolution: {integrity: sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.52.5': + resolution: {integrity: sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.53.3': + resolution: {integrity: sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.53.2': - resolution: {integrity: sha512-yo8d6tdfdeBArzC7T/PnHd7OypfI9cbuZzPnzLJIyKYFhAQ8SvlkKtKBMbXDxe1h03Rcr7u++nFS7tqXz87Gtw==} + '@rollup/rollup-linux-x64-gnu@4.52.5': + resolution: {integrity: sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.53.2': - resolution: {integrity: sha512-ah59c1YkCxKExPP8O9PwOvs+XRLKwh/mV+3YdKqQ5AMQ0r4M4ZDuOrpWkUaqO7fzAHdINzV9tEVu8vNw48z0lA==} + '@rollup/rollup-linux-x64-gnu@4.53.3': + resolution: {integrity: sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==} cpu: [x64] os: [linux] - '@rollup/rollup-openharmony-arm64@4.53.2': - resolution: {integrity: sha512-4VEd19Wmhr+Zy7hbUsFZ6YXEiP48hE//KPLCSVNY5RMGX2/7HZ+QkN55a3atM1C/BZCGIgqN+xrVgtdak2S9+A==} + '@rollup/rollup-linux-x64-musl@4.52.5': + resolution: {integrity: sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.53.3': + resolution: {integrity: sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openharmony-arm64@4.52.5': + resolution: {integrity: sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-openharmony-arm64@4.53.3': + resolution: {integrity: sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.53.2': - resolution: {integrity: sha512-IlbHFYc/pQCgew/d5fslcy1KEaYVCJ44G8pajugd8VoOEI8ODhtb/j8XMhLpwHCMB3yk2J07ctup10gpw2nyMA==} + '@rollup/rollup-win32-arm64-msvc@4.52.5': + resolution: {integrity: sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-arm64-msvc@4.53.3': + resolution: {integrity: sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.53.2': - resolution: {integrity: sha512-lNlPEGgdUfSzdCWU176ku/dQRnA7W+Gp8d+cWv73jYrb8uT7HTVVxq62DUYxjbaByuf1Yk0RIIAbDzp+CnOTFg==} + '@rollup/rollup-win32-ia32-msvc@4.52.5': + resolution: {integrity: sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.53.3': + resolution: {integrity: sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.53.2': - resolution: {integrity: sha512-S6YojNVrHybQis2lYov1sd+uj7K0Q05NxHcGktuMMdIQ2VixGwAfbJ23NnlvvVV1bdpR2m5MsNBViHJKcA4ADw==} + '@rollup/rollup-win32-x64-gnu@4.52.5': + resolution: {integrity: sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.53.2': - resolution: {integrity: sha512-k+/Rkcyx//P6fetPoLMb8pBeqJBNGx81uuf7iljX9++yNBVRDQgD04L+SVXmXmh5ZP4/WOp4mWF0kmi06PW2tA==} + '@rollup/rollup-win32-x64-gnu@4.53.3': + resolution: {integrity: sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.52.5': + resolution: {integrity: sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.53.3': + resolution: {integrity: sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==} cpu: [x64] os: [win32] @@ -8279,8 +8426,8 @@ packages: waku: optional: true - fumadocs-core@16.0.14: - resolution: {integrity: sha512-yylUYhU1g8FzPZ5SXLE3S9ywHZTmU8t4Bjbf6b6NJNAnTgBRdGZvTFxekoD0KzaSm/7q5uBwxs+HM50Uq9i9Ew==} + fumadocs-core@16.0.15: + resolution: {integrity: sha512-WOXVebUDAMTHV60YnZJ++5TcP+jQgh2Iahtw4YT4UoH4gQkl4dCeDFvx85tNPMK8rBhkHBKFQjffUkf0ilc2GQ==} peerDependencies: '@mixedbread/sdk': ^0.19.0 '@orama/core': 1.x.x @@ -9775,8 +9922,8 @@ packages: sass: optional: true - nf3@0.1.10: - resolution: {integrity: sha512-bT6FITvXLd8Z9Qbt0NsMz90diyLNK8H4Sp2vZ9IGLrKxsF5djM+F2vQmR6GyvtlP2y47XMZjjVFpPClgMB8USQ==} + nf3@0.1.12: + resolution: {integrity: sha512-qbMXT7RTGh74MYWPeqTIED8nDW70NXOULVHpdWcdZ7IVHVnAsMV9fNugSNnvooipDc1FMOzpis7T9nXJEbJhvQ==} nitro@3.0.1-alpha.1: resolution: {integrity: sha512-U4AxIsXxdkxzkFrK0XAw0e5Qbojk8jQ50MjjRBtBakC4HurTtQoiZvF+lSe382jhuQZCfAyywGWOFa9QzXLFaw==} @@ -10018,6 +10165,18 @@ packages: zod: optional: true + openai@6.9.0: + resolution: {integrity: sha512-n2sJRYmM+xfJ0l3OfH8eNnIyv3nQY7L08gZQu3dw6wSdfPtKAk92L83M2NIP5SS8Cl/bsBBG3yKzEOjkx0O+7A==} + hasBin: true + peerDependencies: + ws: ^8.18.0 + zod: ^3.25 || ^4.0 + peerDependenciesMeta: + ws: + optional: true + zod: + optional: true + optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -10951,8 +11110,13 @@ packages: rollup: optional: true - rollup@4.53.2: - resolution: {integrity: sha512-MHngMYwGJVi6Fmnk6ISmnk7JAHRNF0UkuucA0CUW3N3a4KnONPEZz+vUanQP/ZC/iY1Qkf3bwPWzyY84wEks1g==} + rollup@4.52.5: + resolution: {integrity: sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + rollup@4.53.3: + resolution: {integrity: sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -11203,6 +11367,11 @@ packages: engines: {node: '>=20.16.0'} hasBin: true + srvx@0.9.4: + resolution: {integrity: sha512-yACjRbHWbI3ehhPCrEKBZvAooe/xgJIdA7QRYiYFI1VtsiGyDpSQS5r9Q6ZgTa+R0umaoJhs2umKuGlL3/nDbQ==} + engines: {node: '>=20.16.0'} + hasBin: true + srvx@0.9.6: resolution: {integrity: sha512-5L4rT6qQqqb+xcoDoklUgCNdmzqJ6vbcDRwPVGRXewF55IJH0pqh0lQlrJ266ZWTKJ4mfeioqHQJeAYesS+RrQ==} engines: {node: '>=20.16.0'} @@ -12553,7 +12722,7 @@ snapshots: '@antfu/install-pkg@1.1.0': dependencies: package-manager-detector: 1.5.0 - tinyexec: 1.0.1 + tinyexec: 1.0.2 '@antfu/utils@9.3.0': {} @@ -14070,12 +14239,12 @@ snapshots: uuid: 11.1.0 write-file-atomic: 6.0.0 - '@netlify/functions@3.1.10(rollup@4.53.2)': + '@netlify/functions@3.1.10(rollup@4.53.3)': dependencies: '@netlify/blobs': 9.1.2 '@netlify/dev-utils': 2.2.0 '@netlify/serverless-functions-api': 1.41.2 - '@netlify/zip-it-and-ship-it': 12.2.1(rollup@4.53.2) + '@netlify/zip-it-and-ship-it': 12.2.1(rollup@4.53.3) cron-parser: 4.9.0 decache: 4.6.2 extract-zip: 2.0.1 @@ -14099,13 +14268,13 @@ snapshots: '@netlify/serverless-functions-api@2.7.1': {} - '@netlify/zip-it-and-ship-it@12.2.1(rollup@4.53.2)': + '@netlify/zip-it-and-ship-it@12.2.1(rollup@4.53.3)': dependencies: '@babel/parser': 7.28.5 '@babel/types': 7.28.0 '@netlify/binary-info': 1.0.0 '@netlify/serverless-functions-api': 2.7.1 - '@vercel/nft': 0.29.4(rollup@4.53.2) + '@vercel/nft': 0.29.4(rollup@4.53.3) archiver: 7.0.1 common-path-prefix: 3.0.0 copy-file: 11.1.0 @@ -14558,10 +14727,10 @@ snapshots: transitivePeerDependencies: - magicast - '@nuxt/vite-builder@4.0.0(@biomejs/biome@2.3.3)(@netlify/blobs@9.1.2)(@types/node@22.19.0)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(eslint@9.38.0(jiti@2.6.1))(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.53.2)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3))(yaml@2.8.1)': + '@nuxt/vite-builder@4.0.0(@biomejs/biome@2.3.3)(@netlify/blobs@9.1.2)(@types/node@22.19.0)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(eslint@9.38.0(jiti@2.6.1))(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3))(yaml@2.8.1)': dependencies: '@nuxt/kit': 4.0.0(magicast@0.3.5) - '@rollup/plugin-replace': 6.0.2(rollup@4.53.2) + '@rollup/plugin-replace': 6.0.2(rollup@4.53.3) '@vitejs/plugin-vue': 6.0.1(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) '@vitejs/plugin-vue-jsx': 5.1.1(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) autoprefixer: 10.4.21(postcss@8.5.6) @@ -14582,7 +14751,7 @@ snapshots: pathe: 2.0.3 pkg-types: 2.3.0 postcss: 8.5.6 - rollup-plugin-visualizer: 6.0.5(rollup@4.53.2) + rollup-plugin-visualizer: 6.0.5(rollup@4.53.3) std-env: 3.10.0 ufo: 1.6.1 unenv: 2.0.0-rc.24 @@ -14643,10 +14812,10 @@ snapshots: - xml2js - yaml - '@nuxt/vite-builder@4.1.3(@biomejs/biome@2.3.3)(@types/node@22.19.0)(eslint@9.38.0(jiti@2.6.1))(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.53.2)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3))(yaml@2.8.1)': + '@nuxt/vite-builder@4.1.3(@biomejs/biome@2.3.3)(@types/node@22.19.0)(eslint@9.38.0(jiti@2.6.1))(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3))(yaml@2.8.1)': dependencies: '@nuxt/kit': 4.1.3(magicast@0.3.5) - '@rollup/plugin-replace': 6.0.2(rollup@4.53.2) + '@rollup/plugin-replace': 6.0.2(rollup@4.53.3) '@vitejs/plugin-vue': 6.0.1(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) '@vitejs/plugin-vue-jsx': 5.1.1(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) autoprefixer: 10.4.21(postcss@8.5.6) @@ -14666,7 +14835,7 @@ snapshots: pathe: 2.0.3 pkg-types: 2.3.0 postcss: 8.5.6 - rollup-plugin-visualizer: 6.0.5(rollup@4.53.2) + rollup-plugin-visualizer: 6.0.5(rollup@4.53.3) std-env: 3.10.0 ufo: 1.6.1 unenv: 2.0.0-rc.21 @@ -16632,13 +16801,17 @@ snapshots: '@rolldown/pluginutils@1.0.0-beta.44': {} - '@rollup/plugin-alias@5.1.1(rollup@4.53.2)': + '@rollup/plugin-alias@5.1.1(rollup@4.52.5)': + optionalDependencies: + rollup: 4.52.5 + + '@rollup/plugin-alias@5.1.1(rollup@4.53.3)': optionalDependencies: - rollup: 4.53.2 + rollup: 4.53.3 - '@rollup/plugin-commonjs@28.0.8(rollup@4.53.2)': + '@rollup/plugin-commonjs@28.0.8(rollup@4.52.5)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.53.2) + '@rollup/pluginutils': 5.3.0(rollup@4.52.5) commondir: 1.0.1 estree-walker: 2.0.2 fdir: 6.5.0(picomatch@4.0.3) @@ -16646,11 +16819,11 @@ snapshots: magic-string: 0.30.21 picomatch: 4.0.3 optionalDependencies: - rollup: 4.53.2 + rollup: 4.52.5 - '@rollup/plugin-commonjs@28.0.9(rollup@4.53.2)': + '@rollup/plugin-commonjs@28.0.9(rollup@4.53.3)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.53.2) + '@rollup/pluginutils': 5.3.0(rollup@4.53.3) commondir: 1.0.1 estree-walker: 2.0.2 fdir: 6.5.0(picomatch@4.0.3) @@ -16658,119 +16831,232 @@ snapshots: magic-string: 0.30.21 picomatch: 4.0.3 optionalDependencies: - rollup: 4.53.2 + rollup: 4.53.3 - '@rollup/plugin-inject@5.0.5(rollup@4.53.2)': + '@rollup/plugin-inject@5.0.5(rollup@4.52.5)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.53.2) + '@rollup/pluginutils': 5.3.0(rollup@4.52.5) estree-walker: 2.0.2 magic-string: 0.30.21 optionalDependencies: - rollup: 4.53.2 + rollup: 4.52.5 - '@rollup/plugin-json@6.1.0(rollup@4.53.2)': + '@rollup/plugin-inject@5.0.5(rollup@4.53.3)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.53.2) + '@rollup/pluginutils': 5.3.0(rollup@4.53.3) + estree-walker: 2.0.2 + magic-string: 0.30.21 optionalDependencies: - rollup: 4.53.2 + rollup: 4.53.3 - '@rollup/plugin-node-resolve@16.0.3(rollup@4.53.2)': + '@rollup/plugin-json@6.1.0(rollup@4.52.5)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.53.2) + '@rollup/pluginutils': 5.3.0(rollup@4.52.5) + optionalDependencies: + rollup: 4.52.5 + + '@rollup/plugin-json@6.1.0(rollup@4.53.3)': + dependencies: + '@rollup/pluginutils': 5.3.0(rollup@4.53.3) + optionalDependencies: + rollup: 4.53.3 + + '@rollup/plugin-node-resolve@16.0.3(rollup@4.52.5)': + dependencies: + '@rollup/pluginutils': 5.3.0(rollup@4.52.5) '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-module: 1.0.0 resolve: 1.22.10 optionalDependencies: - rollup: 4.53.2 + rollup: 4.52.5 - '@rollup/plugin-replace@6.0.2(rollup@4.53.2)': + '@rollup/plugin-node-resolve@16.0.3(rollup@4.53.3)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.53.2) + '@rollup/pluginutils': 5.3.0(rollup@4.53.3) + '@types/resolve': 1.20.2 + deepmerge: 4.3.1 + is-module: 1.0.0 + resolve: 1.22.10 + optionalDependencies: + rollup: 4.53.3 + + '@rollup/plugin-replace@6.0.2(rollup@4.52.5)': + dependencies: + '@rollup/pluginutils': 5.3.0(rollup@4.52.5) + magic-string: 0.30.21 + optionalDependencies: + rollup: 4.52.5 + + '@rollup/plugin-replace@6.0.2(rollup@4.53.3)': + dependencies: + '@rollup/pluginutils': 5.3.0(rollup@4.53.3) magic-string: 0.30.21 optionalDependencies: - rollup: 4.53.2 + rollup: 4.53.3 + + '@rollup/plugin-terser@0.4.4(rollup@4.52.5)': + dependencies: + serialize-javascript: 6.0.2 + smob: 1.5.0 + terser: 5.44.0 + optionalDependencies: + rollup: 4.52.5 - '@rollup/plugin-terser@0.4.4(rollup@4.53.2)': + '@rollup/plugin-terser@0.4.4(rollup@4.53.3)': dependencies: serialize-javascript: 6.0.2 smob: 1.5.0 terser: 5.44.0 optionalDependencies: - rollup: 4.53.2 + rollup: 4.53.3 + + '@rollup/pluginutils@5.3.0(rollup@4.52.5)': + dependencies: + '@types/estree': 1.0.8 + estree-walker: 2.0.2 + picomatch: 4.0.3 + optionalDependencies: + rollup: 4.52.5 - '@rollup/pluginutils@5.3.0(rollup@4.53.2)': + '@rollup/pluginutils@5.3.0(rollup@4.53.3)': dependencies: '@types/estree': 1.0.8 estree-walker: 2.0.2 picomatch: 4.0.3 optionalDependencies: - rollup: 4.53.2 + rollup: 4.53.3 + + '@rollup/rollup-android-arm-eabi@4.52.5': + optional: true + + '@rollup/rollup-android-arm-eabi@4.53.3': + optional: true + + '@rollup/rollup-android-arm64@4.52.5': + optional: true + + '@rollup/rollup-android-arm64@4.53.3': + optional: true + + '@rollup/rollup-darwin-arm64@4.52.5': + optional: true + + '@rollup/rollup-darwin-arm64@4.53.3': + optional: true + + '@rollup/rollup-darwin-x64@4.52.5': + optional: true + + '@rollup/rollup-darwin-x64@4.53.3': + optional: true + + '@rollup/rollup-freebsd-arm64@4.52.5': + optional: true + + '@rollup/rollup-freebsd-arm64@4.53.3': + optional: true + + '@rollup/rollup-freebsd-x64@4.52.5': + optional: true - '@rollup/rollup-android-arm-eabi@4.53.2': + '@rollup/rollup-freebsd-x64@4.53.3': optional: true - '@rollup/rollup-android-arm64@4.53.2': + '@rollup/rollup-linux-arm-gnueabihf@4.52.5': optional: true - '@rollup/rollup-darwin-arm64@4.53.2': + '@rollup/rollup-linux-arm-gnueabihf@4.53.3': optional: true - '@rollup/rollup-darwin-x64@4.53.2': + '@rollup/rollup-linux-arm-musleabihf@4.52.5': optional: true - '@rollup/rollup-freebsd-arm64@4.53.2': + '@rollup/rollup-linux-arm-musleabihf@4.53.3': optional: true - '@rollup/rollup-freebsd-x64@4.53.2': + '@rollup/rollup-linux-arm64-gnu@4.52.5': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.53.2': + '@rollup/rollup-linux-arm64-gnu@4.53.3': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.53.2': + '@rollup/rollup-linux-arm64-musl@4.52.5': optional: true - '@rollup/rollup-linux-arm64-gnu@4.53.2': + '@rollup/rollup-linux-arm64-musl@4.53.3': optional: true - '@rollup/rollup-linux-arm64-musl@4.53.2': + '@rollup/rollup-linux-loong64-gnu@4.52.5': optional: true - '@rollup/rollup-linux-loong64-gnu@4.53.2': + '@rollup/rollup-linux-loong64-gnu@4.53.3': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.53.2': + '@rollup/rollup-linux-ppc64-gnu@4.52.5': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.53.2': + '@rollup/rollup-linux-ppc64-gnu@4.53.3': optional: true - '@rollup/rollup-linux-riscv64-musl@4.53.2': + '@rollup/rollup-linux-riscv64-gnu@4.52.5': optional: true - '@rollup/rollup-linux-s390x-gnu@4.53.2': + '@rollup/rollup-linux-riscv64-gnu@4.53.3': optional: true - '@rollup/rollup-linux-x64-gnu@4.53.2': + '@rollup/rollup-linux-riscv64-musl@4.52.5': optional: true - '@rollup/rollup-linux-x64-musl@4.53.2': + '@rollup/rollup-linux-riscv64-musl@4.53.3': optional: true - '@rollup/rollup-openharmony-arm64@4.53.2': + '@rollup/rollup-linux-s390x-gnu@4.52.5': optional: true - '@rollup/rollup-win32-arm64-msvc@4.53.2': + '@rollup/rollup-linux-s390x-gnu@4.53.3': optional: true - '@rollup/rollup-win32-ia32-msvc@4.53.2': + '@rollup/rollup-linux-x64-gnu@4.52.5': optional: true - '@rollup/rollup-win32-x64-gnu@4.53.2': + '@rollup/rollup-linux-x64-gnu@4.53.3': optional: true - '@rollup/rollup-win32-x64-msvc@4.53.2': + '@rollup/rollup-linux-x64-musl@4.52.5': + optional: true + + '@rollup/rollup-linux-x64-musl@4.53.3': + optional: true + + '@rollup/rollup-openharmony-arm64@4.52.5': + optional: true + + '@rollup/rollup-openharmony-arm64@4.53.3': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.52.5': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.53.3': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.52.5': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.53.3': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.52.5': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.53.3': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.52.5': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.53.3': optional: true '@sec-ant/readable-stream@0.4.1': {} @@ -17158,16 +17444,16 @@ snapshots: '@sveltejs/adapter-node@5.4.0(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))': dependencies: - '@rollup/plugin-commonjs': 28.0.9(rollup@4.53.2) - '@rollup/plugin-json': 6.1.0(rollup@4.53.2) - '@rollup/plugin-node-resolve': 16.0.3(rollup@4.53.2) + '@rollup/plugin-commonjs': 28.0.9(rollup@4.53.3) + '@rollup/plugin-json': 6.1.0(rollup@4.53.3) + '@rollup/plugin-node-resolve': 16.0.3(rollup@4.53.3) '@sveltejs/kit': 2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) - rollup: 4.53.2 + rollup: 4.53.3 - '@sveltejs/adapter-vercel@6.1.1(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(rollup@4.53.2)': + '@sveltejs/adapter-vercel@6.1.1(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(rollup@4.53.3)': dependencies: '@sveltejs/kit': 2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) - '@vercel/nft': 0.30.3(rollup@4.53.2) + '@vercel/nft': 0.30.3(rollup@4.53.3) esbuild: 0.25.11 transitivePeerDependencies: - encoding @@ -17795,10 +18081,29 @@ snapshots: optionalDependencies: '@aws-sdk/credential-provider-web-identity': 3.844.0 - '@vercel/nft@0.29.4(rollup@4.53.2)': + '@vercel/nft@0.29.4(rollup@4.53.3)': + dependencies: + '@mapbox/node-pre-gyp': 2.0.0 + '@rollup/pluginutils': 5.3.0(rollup@4.53.3) + acorn: 8.15.0 + acorn-import-attributes: 1.9.5(acorn@8.15.0) + async-sema: 3.1.1 + bindings: 1.5.0 + estree-walker: 2.0.2 + glob: 10.4.5 + graceful-fs: 4.2.11 + node-gyp-build: 4.8.4 + picomatch: 4.0.3 + resolve-from: 5.0.0 + transitivePeerDependencies: + - encoding + - rollup + - supports-color + + '@vercel/nft@0.30.3(rollup@4.52.5)': dependencies: '@mapbox/node-pre-gyp': 2.0.0 - '@rollup/pluginutils': 5.3.0(rollup@4.53.2) + '@rollup/pluginutils': 5.3.0(rollup@4.52.5) acorn: 8.15.0 acorn-import-attributes: 1.9.5(acorn@8.15.0) async-sema: 3.1.1 @@ -17814,10 +18119,10 @@ snapshots: - rollup - supports-color - '@vercel/nft@0.30.3(rollup@4.53.2)': + '@vercel/nft@0.30.3(rollup@4.53.3)': dependencies: '@mapbox/node-pre-gyp': 2.0.0 - '@rollup/pluginutils': 5.3.0(rollup@4.53.2) + '@rollup/pluginutils': 5.3.0(rollup@4.53.3) acorn: 8.15.0 acorn-import-attributes: 1.9.5(acorn@8.15.0) async-sema: 3.1.1 @@ -19927,7 +20232,7 @@ snapshots: dependencies: magic-string: 0.30.21 mlly: 1.8.0 - rollup: 4.53.2 + rollup: 4.53.3 flat-cache@4.0.1: dependencies: @@ -20016,7 +20321,7 @@ snapshots: transitivePeerDependencies: - supports-color - fumadocs-core@16.0.14(@types/react@19.1.13)(lucide-react@0.544.0(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0): + fumadocs-core@16.0.15(@types/react@19.1.13)(lucide-react@0.544.0(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: '@formatjs/intl-localematcher': 0.6.2 '@orama/orama': 3.1.16 @@ -20045,14 +20350,14 @@ snapshots: transitivePeerDependencies: - supports-color - fumadocs-mdx@13.0.8(fumadocs-core@16.0.14(@types/react@19.1.13)(lucide-react@0.544.0(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): + fumadocs-mdx@13.0.8(fumadocs-core@16.0.15(@types/react@19.1.13)(lucide-react@0.544.0(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): dependencies: '@mdx-js/mdx': 3.1.1 '@standard-schema/spec': 1.0.0 chokidar: 4.0.3 esbuild: 0.25.12 estree-util-value-to-estree: 3.5.0 - fumadocs-core: 16.0.14(@types/react@19.1.13)(lucide-react@0.544.0(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + fumadocs-core: 16.0.15(@types/react@19.1.13)(lucide-react@0.544.0(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) js-yaml: 4.1.0 lru-cache: 11.2.2 mdast-util-to-markdown: 2.1.2 @@ -20072,10 +20377,10 @@ snapshots: transitivePeerDependencies: - supports-color - fumadocs-typescript@4.0.13(@types/react@19.1.13)(fumadocs-core@16.0.14(@types/react@19.1.13)(lucide-react@0.544.0(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(fumadocs-ui@16.0.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(lucide-react@0.544.0(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(tailwindcss@4.1.13))(typescript@5.9.3): + fumadocs-typescript@4.0.13(@types/react@19.1.13)(fumadocs-core@16.0.15(@types/react@19.1.13)(lucide-react@0.544.0(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(fumadocs-ui@16.0.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(lucide-react@0.544.0(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(tailwindcss@4.1.13))(typescript@5.9.3): dependencies: estree-util-value-to-estree: 3.5.0 - fumadocs-core: 16.0.14(@types/react@19.1.13)(lucide-react@0.544.0(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + fumadocs-core: 16.0.15(@types/react@19.1.13)(lucide-react@0.544.0(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) hast-util-to-estree: 3.1.3 hast-util-to-jsx-runtime: 2.3.6 remark: 15.0.1 @@ -21886,16 +22191,16 @@ snapshots: - '@babel/core' - babel-plugin-macros - nf3@0.1.10: {} + nf3@0.1.12: {} - nitro@3.0.1-alpha.1(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(ioredis@5.8.2)(lru-cache@11.2.2)(rollup@4.53.2)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): + nitro@3.0.1-alpha.1(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(ioredis@5.8.2)(lru-cache@11.2.2)(rollup@4.53.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): dependencies: consola: 3.4.2 crossws: 0.4.1(srvx@0.9.6) db0: 0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)) h3: 2.0.1-rc.5(crossws@0.4.1(srvx@0.9.6)) jiti: 2.6.1 - nf3: 0.1.10 + nf3: 0.1.12 ofetch: 2.0.0-alpha.3 ohash: 2.0.11 oxc-minify: 0.96.0 @@ -21905,7 +22210,7 @@ snapshots: unenv: 2.0.0-rc.24 unstorage: 2.0.0-alpha.4(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(chokidar@4.0.3)(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(lru-cache@11.2.2)(ofetch@2.0.0-alpha.3) optionalDependencies: - rollup: 4.53.2 + rollup: 4.53.3 vite: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - '@azure/app-configuration' @@ -21936,14 +22241,14 @@ snapshots: - sqlite3 - uploadthing - nitro@3.0.1-alpha.1(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(ioredis@5.8.2)(lru-cache@11.2.2)(rollup@4.53.2)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): + nitro@3.0.1-alpha.1(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(ioredis@5.8.2)(lru-cache@11.2.2)(rollup@4.53.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): dependencies: consola: 3.4.2 crossws: 0.4.1(srvx@0.9.6) db0: 0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)) h3: 2.0.1-rc.5(crossws@0.4.1(srvx@0.9.6)) jiti: 2.6.1 - nf3: 0.1.10 + nf3: 0.1.12 ofetch: 2.0.0-alpha.3 ohash: 2.0.11 oxc-minify: 0.96.0 @@ -21953,7 +22258,7 @@ snapshots: unenv: 2.0.0-rc.24 unstorage: 2.0.0-alpha.4(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(chokidar@4.0.3)(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(lru-cache@11.2.2)(ofetch@2.0.0-alpha.3) optionalDependencies: - rollup: 4.53.2 + rollup: 4.53.3 vite: 7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - '@azure/app-configuration' @@ -21987,15 +22292,15 @@ snapshots: nitropack@2.12.0(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)): dependencies: '@cloudflare/kv-asset-handler': 0.4.0 - '@netlify/functions': 3.1.10(rollup@4.53.2) - '@rollup/plugin-alias': 5.1.1(rollup@4.53.2) - '@rollup/plugin-commonjs': 28.0.9(rollup@4.53.2) - '@rollup/plugin-inject': 5.0.5(rollup@4.53.2) - '@rollup/plugin-json': 6.1.0(rollup@4.53.2) - '@rollup/plugin-node-resolve': 16.0.3(rollup@4.53.2) - '@rollup/plugin-replace': 6.0.2(rollup@4.53.2) - '@rollup/plugin-terser': 0.4.4(rollup@4.53.2) - '@vercel/nft': 0.29.4(rollup@4.53.2) + '@netlify/functions': 3.1.10(rollup@4.53.3) + '@rollup/plugin-alias': 5.1.1(rollup@4.53.3) + '@rollup/plugin-commonjs': 28.0.9(rollup@4.53.3) + '@rollup/plugin-inject': 5.0.5(rollup@4.53.3) + '@rollup/plugin-json': 6.1.0(rollup@4.53.3) + '@rollup/plugin-node-resolve': 16.0.3(rollup@4.53.3) + '@rollup/plugin-replace': 6.0.2(rollup@4.53.3) + '@rollup/plugin-terser': 0.4.4(rollup@4.53.3) + '@vercel/nft': 0.29.4(rollup@4.53.3) archiver: 7.0.1 c12: 3.3.1(magicast@0.3.5) chokidar: 4.0.3 @@ -22037,8 +22342,8 @@ snapshots: pkg-types: 2.3.0 pretty-bytes: 6.1.1 radix3: 1.1.2 - rollup: 4.53.2 - rollup-plugin-visualizer: 6.0.5(rollup@4.53.2) + rollup: 4.53.3 + rollup-plugin-visualizer: 6.0.5(rollup@4.53.3) scule: 1.3.0 semver: 7.7.3 serve-placeholder: 2.0.2 @@ -22090,14 +22395,14 @@ snapshots: nitropack@2.12.7(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)): dependencies: '@cloudflare/kv-asset-handler': 0.4.0 - '@rollup/plugin-alias': 5.1.1(rollup@4.53.2) - '@rollup/plugin-commonjs': 28.0.8(rollup@4.53.2) - '@rollup/plugin-inject': 5.0.5(rollup@4.53.2) - '@rollup/plugin-json': 6.1.0(rollup@4.53.2) - '@rollup/plugin-node-resolve': 16.0.3(rollup@4.53.2) - '@rollup/plugin-replace': 6.0.2(rollup@4.53.2) - '@rollup/plugin-terser': 0.4.4(rollup@4.53.2) - '@vercel/nft': 0.30.3(rollup@4.53.2) + '@rollup/plugin-alias': 5.1.1(rollup@4.52.5) + '@rollup/plugin-commonjs': 28.0.8(rollup@4.52.5) + '@rollup/plugin-inject': 5.0.5(rollup@4.52.5) + '@rollup/plugin-json': 6.1.0(rollup@4.52.5) + '@rollup/plugin-node-resolve': 16.0.3(rollup@4.52.5) + '@rollup/plugin-replace': 6.0.2(rollup@4.52.5) + '@rollup/plugin-terser': 0.4.4(rollup@4.52.5) + '@vercel/nft': 0.30.3(rollup@4.52.5) archiver: 7.0.1 c12: 3.3.1(magicast@0.3.5) chokidar: 4.0.3 @@ -22139,8 +22444,8 @@ snapshots: pkg-types: 2.3.0 pretty-bytes: 7.1.0 radix3: 1.1.2 - rollup: 4.53.2 - rollup-plugin-visualizer: 6.0.5(rollup@4.53.2) + rollup: 4.52.5 + rollup-plugin-visualizer: 6.0.5(rollup@4.52.5) scule: 1.3.0 semver: 7.7.3 serve-placeholder: 2.0.2 @@ -22255,7 +22560,7 @@ snapshots: dependencies: boolbase: 1.0.0 - nuxt@4.0.0(@biomejs/biome@2.3.3)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@22.19.0)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(@vue/compiler-sfc@3.5.22)(better-sqlite3@11.10.0)(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.53.2)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(yaml@2.8.1): + nuxt@4.0.0(@biomejs/biome@2.3.3)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@22.19.0)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(@vue/compiler-sfc@3.5.22)(better-sqlite3@11.10.0)(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(yaml@2.8.1): dependencies: '@nuxt/cli': 3.29.3(magicast@0.3.5) '@nuxt/devalue': 2.0.2 @@ -22263,7 +22568,7 @@ snapshots: '@nuxt/kit': 4.0.0(magicast@0.3.5) '@nuxt/schema': 4.0.0 '@nuxt/telemetry': 2.6.6(magicast@0.3.5) - '@nuxt/vite-builder': 4.0.0(@biomejs/biome@2.3.3)(@netlify/blobs@9.1.2)(@types/node@22.19.0)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(eslint@9.38.0(jiti@2.6.1))(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.53.2)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3))(yaml@2.8.1) + '@nuxt/vite-builder': 4.0.0(@biomejs/biome@2.3.3)(@netlify/blobs@9.1.2)(@types/node@22.19.0)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(eslint@9.38.0(jiti@2.6.1))(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3))(yaml@2.8.1) '@unhead/vue': 2.0.19(vue@3.5.22(typescript@5.9.3)) '@vue/shared': 3.5.22 c12: 3.3.1(magicast@0.3.5) @@ -22381,7 +22686,7 @@ snapshots: - xml2js - yaml - nuxt@4.1.3(@biomejs/biome@2.3.3)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@22.19.0)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(@vue/compiler-sfc@3.5.22)(better-sqlite3@11.10.0)(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.53.2)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(yaml@2.8.1): + nuxt@4.1.3(@biomejs/biome@2.3.3)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@22.19.0)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(@vue/compiler-sfc@3.5.22)(better-sqlite3@11.10.0)(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(yaml@2.8.1): dependencies: '@nuxt/cli': 3.29.3(magicast@0.3.5) '@nuxt/devalue': 2.0.2 @@ -22389,7 +22694,7 @@ snapshots: '@nuxt/kit': 4.1.3(magicast@0.3.5) '@nuxt/schema': 4.1.3 '@nuxt/telemetry': 2.6.6(magicast@0.3.5) - '@nuxt/vite-builder': 4.1.3(@biomejs/biome@2.3.3)(@types/node@22.19.0)(eslint@9.38.0(jiti@2.6.1))(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.53.2)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3))(yaml@2.8.1) + '@nuxt/vite-builder': 4.1.3(@biomejs/biome@2.3.3)(@types/node@22.19.0)(eslint@9.38.0(jiti@2.6.1))(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3))(yaml@2.8.1) '@unhead/vue': 2.0.19(vue@3.5.22(typescript@5.9.3)) '@vue/shared': 3.5.22 c12: 3.3.1(magicast@0.3.5) @@ -22604,6 +22909,11 @@ snapshots: ws: 8.18.3 zod: 4.1.11 + openai@6.9.0(ws@8.18.3)(zod@4.1.11): + optionalDependencies: + ws: 8.18.3 + zod: 4.1.11 + optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -23837,49 +24147,86 @@ snapshots: robust-predicates@3.0.2: {} - rollup-plugin-dts@6.2.3(rollup@4.53.2)(typescript@5.9.3): + rollup-plugin-dts@6.2.3(rollup@4.53.3)(typescript@5.9.3): dependencies: magic-string: 0.30.21 - rollup: 4.53.2 + rollup: 4.53.3 typescript: 5.9.3 optionalDependencies: '@babel/code-frame': 7.27.1 - rollup-plugin-visualizer@6.0.5(rollup@4.53.2): + rollup-plugin-visualizer@6.0.5(rollup@4.52.5): dependencies: open: 8.4.2 picomatch: 4.0.3 source-map: 0.7.6 yargs: 17.7.2 optionalDependencies: - rollup: 4.53.2 + rollup: 4.52.5 - rollup@4.53.2: + rollup-plugin-visualizer@6.0.5(rollup@4.53.3): + dependencies: + open: 8.4.2 + picomatch: 4.0.3 + source-map: 0.7.6 + yargs: 17.7.2 + optionalDependencies: + rollup: 4.53.3 + + rollup@4.52.5: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.52.5 + '@rollup/rollup-android-arm64': 4.52.5 + '@rollup/rollup-darwin-arm64': 4.52.5 + '@rollup/rollup-darwin-x64': 4.52.5 + '@rollup/rollup-freebsd-arm64': 4.52.5 + '@rollup/rollup-freebsd-x64': 4.52.5 + '@rollup/rollup-linux-arm-gnueabihf': 4.52.5 + '@rollup/rollup-linux-arm-musleabihf': 4.52.5 + '@rollup/rollup-linux-arm64-gnu': 4.52.5 + '@rollup/rollup-linux-arm64-musl': 4.52.5 + '@rollup/rollup-linux-loong64-gnu': 4.52.5 + '@rollup/rollup-linux-ppc64-gnu': 4.52.5 + '@rollup/rollup-linux-riscv64-gnu': 4.52.5 + '@rollup/rollup-linux-riscv64-musl': 4.52.5 + '@rollup/rollup-linux-s390x-gnu': 4.52.5 + '@rollup/rollup-linux-x64-gnu': 4.52.5 + '@rollup/rollup-linux-x64-musl': 4.52.5 + '@rollup/rollup-openharmony-arm64': 4.52.5 + '@rollup/rollup-win32-arm64-msvc': 4.52.5 + '@rollup/rollup-win32-ia32-msvc': 4.52.5 + '@rollup/rollup-win32-x64-gnu': 4.52.5 + '@rollup/rollup-win32-x64-msvc': 4.52.5 + fsevents: 2.3.3 + + rollup@4.53.3: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.53.2 - '@rollup/rollup-android-arm64': 4.53.2 - '@rollup/rollup-darwin-arm64': 4.53.2 - '@rollup/rollup-darwin-x64': 4.53.2 - '@rollup/rollup-freebsd-arm64': 4.53.2 - '@rollup/rollup-freebsd-x64': 4.53.2 - '@rollup/rollup-linux-arm-gnueabihf': 4.53.2 - '@rollup/rollup-linux-arm-musleabihf': 4.53.2 - '@rollup/rollup-linux-arm64-gnu': 4.53.2 - '@rollup/rollup-linux-arm64-musl': 4.53.2 - '@rollup/rollup-linux-loong64-gnu': 4.53.2 - '@rollup/rollup-linux-ppc64-gnu': 4.53.2 - '@rollup/rollup-linux-riscv64-gnu': 4.53.2 - '@rollup/rollup-linux-riscv64-musl': 4.53.2 - '@rollup/rollup-linux-s390x-gnu': 4.53.2 - '@rollup/rollup-linux-x64-gnu': 4.53.2 - '@rollup/rollup-linux-x64-musl': 4.53.2 - '@rollup/rollup-openharmony-arm64': 4.53.2 - '@rollup/rollup-win32-arm64-msvc': 4.53.2 - '@rollup/rollup-win32-ia32-msvc': 4.53.2 - '@rollup/rollup-win32-x64-gnu': 4.53.2 - '@rollup/rollup-win32-x64-msvc': 4.53.2 + '@rollup/rollup-android-arm-eabi': 4.53.3 + '@rollup/rollup-android-arm64': 4.53.3 + '@rollup/rollup-darwin-arm64': 4.53.3 + '@rollup/rollup-darwin-x64': 4.53.3 + '@rollup/rollup-freebsd-arm64': 4.53.3 + '@rollup/rollup-freebsd-x64': 4.53.3 + '@rollup/rollup-linux-arm-gnueabihf': 4.53.3 + '@rollup/rollup-linux-arm-musleabihf': 4.53.3 + '@rollup/rollup-linux-arm64-gnu': 4.53.3 + '@rollup/rollup-linux-arm64-musl': 4.53.3 + '@rollup/rollup-linux-loong64-gnu': 4.53.3 + '@rollup/rollup-linux-ppc64-gnu': 4.53.3 + '@rollup/rollup-linux-riscv64-gnu': 4.53.3 + '@rollup/rollup-linux-riscv64-musl': 4.53.3 + '@rollup/rollup-linux-s390x-gnu': 4.53.3 + '@rollup/rollup-linux-x64-gnu': 4.53.3 + '@rollup/rollup-linux-x64-musl': 4.53.3 + '@rollup/rollup-openharmony-arm64': 4.53.3 + '@rollup/rollup-win32-arm64-msvc': 4.53.3 + '@rollup/rollup-win32-ia32-msvc': 4.53.3 + '@rollup/rollup-win32-x64-gnu': 4.53.3 + '@rollup/rollup-win32-x64-msvc': 4.53.3 fsevents: 2.3.3 rou3@0.7.10: {} @@ -24181,6 +24528,8 @@ snapshots: srvx@0.8.16: {} + srvx@0.9.4: {} + srvx@0.9.6: {} ssh-remote-port-forward@1.0.4: @@ -24609,7 +24958,7 @@ snapshots: tsx@4.20.6: dependencies: - esbuild: 0.25.12 + esbuild: 0.25.11 get-tsconfig: 4.12.0 optionalDependencies: fsevents: 2.3.3 @@ -24688,12 +25037,12 @@ snapshots: unbuild@3.6.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.12)(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)): dependencies: - '@rollup/plugin-alias': 5.1.1(rollup@4.53.2) - '@rollup/plugin-commonjs': 28.0.9(rollup@4.53.2) - '@rollup/plugin-json': 6.1.0(rollup@4.53.2) - '@rollup/plugin-node-resolve': 16.0.3(rollup@4.53.2) - '@rollup/plugin-replace': 6.0.2(rollup@4.53.2) - '@rollup/pluginutils': 5.3.0(rollup@4.53.2) + '@rollup/plugin-alias': 5.1.1(rollup@4.53.3) + '@rollup/plugin-commonjs': 28.0.9(rollup@4.53.3) + '@rollup/plugin-json': 6.1.0(rollup@4.53.3) + '@rollup/plugin-node-resolve': 16.0.3(rollup@4.53.3) + '@rollup/plugin-replace': 6.0.2(rollup@4.53.3) + '@rollup/pluginutils': 5.3.0(rollup@4.53.3) citty: 0.1.6 consola: 3.4.2 defu: 6.1.4 @@ -24707,8 +25056,8 @@ snapshots: pathe: 2.0.3 pkg-types: 2.3.0 pretty-bytes: 7.1.0 - rollup: 4.53.2 - rollup-plugin-dts: 6.2.3(rollup@4.53.2)(typescript@5.9.3) + rollup: 4.53.3 + rollup-plugin-dts: 6.2.3(rollup@4.53.3)(typescript@5.9.3) scule: 1.3.0 tinyglobby: 0.2.14 untyped: 2.0.0 @@ -25196,7 +25545,7 @@ snapshots: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 - rollup: 4.53.2 + rollup: 4.52.5 tinyglobby: 0.2.15 optionalDependencies: '@types/node': 22.19.0 @@ -25213,7 +25562,7 @@ snapshots: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 - rollup: 4.53.2 + rollup: 4.52.5 tinyglobby: 0.2.15 optionalDependencies: '@types/node': 22.19.0 @@ -25230,7 +25579,7 @@ snapshots: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 - rollup: 4.53.2 + rollup: 4.52.5 tinyglobby: 0.2.15 optionalDependencies: '@types/node': 24.6.2 From 70a8040e6871572d2674a84560aa8afa8c4fc313 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 00:24:36 -0800 Subject: [PATCH 07/61] add astro workbench --- workbench/astro/.gitignore | 27 + workbench/astro/README.md | 43 + workbench/astro/astro.config.mjs | 8 + workbench/astro/package-lock.json | 4883 +++++++++++++++++ workbench/astro/package.json | 19 + workbench/astro/public/favicon.svg | 9 + workbench/astro/src/lib/.gitkeep | 0 workbench/astro/src/pages/api/hook.ts | 27 + .../src/pages/api/test-direct-step-call.ts | 19 + workbench/astro/src/pages/api/trigger.ts | 153 + workbench/astro/src/pages/index.astro | 16 + workbench/astro/src/workflows | 1 + workbench/astro/tsconfig.json | 5 + 13 files changed, 5210 insertions(+) create mode 100644 workbench/astro/.gitignore create mode 100644 workbench/astro/README.md create mode 100644 workbench/astro/astro.config.mjs create mode 100644 workbench/astro/package-lock.json create mode 100644 workbench/astro/package.json create mode 100644 workbench/astro/public/favicon.svg create mode 100644 workbench/astro/src/lib/.gitkeep create mode 100644 workbench/astro/src/pages/api/hook.ts create mode 100644 workbench/astro/src/pages/api/test-direct-step-call.ts create mode 100644 workbench/astro/src/pages/api/trigger.ts create mode 100644 workbench/astro/src/pages/index.astro create mode 120000 workbench/astro/src/workflows create mode 100644 workbench/astro/tsconfig.json diff --git a/workbench/astro/.gitignore b/workbench/astro/.gitignore new file mode 100644 index 000000000..185adda60 --- /dev/null +++ b/workbench/astro/.gitignore @@ -0,0 +1,27 @@ +# build output +dist/ +# generated types +.astro/ + +# dependencies +node_modules/ + +# logs +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + + +# environment variables +.env +.env.production + +# macOS-specific files +.DS_Store + +# jetbrains setting folder +.idea/ + +# Workflow +src/lib/_workflows.ts diff --git a/workbench/astro/README.md b/workbench/astro/README.md new file mode 100644 index 000000000..87b813ae7 --- /dev/null +++ b/workbench/astro/README.md @@ -0,0 +1,43 @@ +# Astro Starter Kit: Minimal + +```sh +npm create astro@latest -- --template minimal +``` + +> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun! + +## 🚀 Project Structure + +Inside of your Astro project, you'll see the following folders and files: + +```text +/ +├── public/ +├── src/ +│ └── pages/ +│ └── index.astro +└── package.json +``` + +Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name. + +There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components. + +Any static assets, like images, can be placed in the `public/` directory. + +## 🧞 Commands + +All commands are run from the root of the project, from a terminal: + +| Command | Action | +| :------------------------ | :----------------------------------------------- | +| `npm install` | Installs dependencies | +| `npm run dev` | Starts local dev server at `localhost:4321` | +| `npm run build` | Build your production site to `./dist/` | +| `npm run preview` | Preview your build locally, before deploying | +| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` | +| `npm run astro -- --help` | Get help using the Astro CLI | + +## 👀 Want to learn more? + +Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat). diff --git a/workbench/astro/astro.config.mjs b/workbench/astro/astro.config.mjs new file mode 100644 index 000000000..25c89c6d9 --- /dev/null +++ b/workbench/astro/astro.config.mjs @@ -0,0 +1,8 @@ +// @ts-check +import { defineConfig } from 'astro/config'; +import { workflowPlugin } from 'workflow/astro'; + +// https://astro.build/config +export default defineConfig({ + vite: { plugins: [workflowPlugin()] }, +}); diff --git a/workbench/astro/package-lock.json b/workbench/astro/package-lock.json new file mode 100644 index 000000000..1fa3d718f --- /dev/null +++ b/workbench/astro/package-lock.json @@ -0,0 +1,4883 @@ +{ + "name": "astro", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "astro", + "version": "0.0.1", + "dependencies": { + "astro": "^5.15.6" + } + }, + "node_modules/@astrojs/compiler": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-2.13.0.tgz", + "integrity": "sha512-mqVORhUJViA28fwHYaWmsXSzLO9osbdZ5ImUfxBarqsYdMlPbqAqGJCxsNzvppp1BEzc1mJNjOVvQqeDN8Vspw==", + "license": "MIT" + }, + "node_modules/@astrojs/internal-helpers": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.7.4.tgz", + "integrity": "sha512-lDA9MqE8WGi7T/t2BMi+EAXhs4Vcvr94Gqx3q15cFEz8oFZMO4/SFBqYr/UcmNlvW+35alowkVj+w9VhLvs5Cw==", + "license": "MIT" + }, + "node_modules/@astrojs/markdown-remark": { + "version": "6.3.8", + "resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-6.3.8.tgz", + "integrity": "sha512-uFNyFWadnULWK2cOw4n0hLKeu+xaVWeuECdP10cQ3K2fkybtTlhb7J7TcScdjmS8Yps7oje9S/ehYMfZrhrgCg==", + "license": "MIT", + "dependencies": { + "@astrojs/internal-helpers": "0.7.4", + "@astrojs/prism": "3.3.0", + "github-slugger": "^2.0.0", + "hast-util-from-html": "^2.0.3", + "hast-util-to-text": "^4.0.2", + "import-meta-resolve": "^4.2.0", + "js-yaml": "^4.1.0", + "mdast-util-definitions": "^6.0.0", + "rehype-raw": "^7.0.0", + "rehype-stringify": "^10.0.1", + "remark-gfm": "^4.0.1", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.1.2", + "remark-smartypants": "^3.0.2", + "shiki": "^3.13.0", + "smol-toml": "^1.4.2", + "unified": "^11.0.5", + "unist-util-remove-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "unist-util-visit-parents": "^6.0.1", + "vfile": "^6.0.3" + } + }, + "node_modules/@astrojs/prism": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@astrojs/prism/-/prism-3.3.0.tgz", + "integrity": "sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ==", + "license": "MIT", + "dependencies": { + "prismjs": "^1.30.0" + }, + "engines": { + "node": "18.20.8 || ^20.3.0 || >=22.0.0" + } + }, + "node_modules/@astrojs/telemetry": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.3.0.tgz", + "integrity": "sha512-UFBgfeldP06qu6khs/yY+q1cDAaArM2/7AEIqQ9Cuvf7B1hNLq0xDrZkct+QoIGyjq56y8IaE2I3CTvG99mlhQ==", + "license": "MIT", + "dependencies": { + "ci-info": "^4.2.0", + "debug": "^4.4.0", + "dlv": "^1.1.3", + "dset": "^3.1.4", + "is-docker": "^3.0.0", + "is-wsl": "^3.1.0", + "which-pm-runs": "^1.1.0" + }, + "engines": { + "node": "18.20.8 || ^20.3.0 || >=22.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.5" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@capsizecss/unpack": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@capsizecss/unpack/-/unpack-3.0.1.tgz", + "integrity": "sha512-8XqW8xGn++Eqqbz3e9wKuK7mxryeRjs4LOHLxbh2lwKeSbuNR4NFifDZT4KzvjU6HMOPbiNTsWpniK5EJfTWkg==", + "license": "MIT", + "dependencies": { + "fontkit": "^2.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.7.1.tgz", + "integrity": "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/colour": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.0.0.tgz", + "integrity": "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", + "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", + "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", + "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", + "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", + "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", + "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", + "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", + "cpu": [ + "ppc64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", + "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "cpu": [ + "riscv64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", + "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", + "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", + "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", + "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", + "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", + "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", + "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", + "cpu": [ + "ppc64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", + "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "cpu": [ + "riscv64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", + "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", + "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", + "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", + "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", + "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.7.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", + "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", + "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", + "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@oslojs/encoding": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@oslojs/encoding/-/encoding-1.1.0.tgz", + "integrity": "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==", + "license": "MIT" + }, + "node_modules/@rollup/pluginutils": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", + "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.2.tgz", + "integrity": "sha512-yDPzwsgiFO26RJA4nZo8I+xqzh7sJTZIWQOxn+/XOdPE31lAvLIYCKqjV+lNH/vxE2L2iH3plKxDCRK6i+CwhA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.2.tgz", + "integrity": "sha512-k8FontTxIE7b0/OGKeSN5B6j25EuppBcWM33Z19JoVT7UTXFSo3D9CdU39wGTeb29NO3XxpMNauh09B+Ibw+9g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.2.tgz", + "integrity": "sha512-A6s4gJpomNBtJ2yioj8bflM2oogDwzUiMl2yNJ2v9E7++sHrSrsQ29fOfn5DM/iCzpWcebNYEdXpaK4tr2RhfQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.2.tgz", + "integrity": "sha512-e6XqVmXlHrBlG56obu9gDRPW3O3hLxpwHpLsBJvuI8qqnsrtSZ9ERoWUXtPOkY8c78WghyPHZdmPhHLWNdAGEw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.2.tgz", + "integrity": "sha512-v0E9lJW8VsrwPux5Qe5CwmH/CF/2mQs6xU1MF3nmUxmZUCHazCjLgYvToOk+YuuUqLQBio1qkkREhxhc656ViA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.2.tgz", + "integrity": "sha512-ClAmAPx3ZCHtp6ysl4XEhWU69GUB1D+s7G9YjHGhIGCSrsg00nEGRRZHmINYxkdoJehde8VIsDC5t9C0gb6yqA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.2.tgz", + "integrity": "sha512-EPlb95nUsz6Dd9Qy13fI5kUPXNSljaG9FiJ4YUGU1O/Q77i5DYFW5KR8g1OzTcdZUqQQ1KdDqsTohdFVwCwjqg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.2.tgz", + "integrity": "sha512-BOmnVW+khAUX+YZvNfa0tGTEMVVEerOxN0pDk2E6N6DsEIa2Ctj48FOMfNDdrwinocKaC7YXUZ1pHlKpnkja/Q==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.2.tgz", + "integrity": "sha512-Xt2byDZ+6OVNuREgBXr4+CZDJtrVso5woFtpKdGPhpTPHcNG7D8YXeQzpNbFRxzTVqJf7kvPMCub/pcGUWgBjA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.2.tgz", + "integrity": "sha512-+LdZSldy/I9N8+klim/Y1HsKbJ3BbInHav5qE9Iy77dtHC/pibw1SR/fXlWyAk0ThnpRKoODwnAuSjqxFRDHUQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.2.tgz", + "integrity": "sha512-8ms8sjmyc1jWJS6WdNSA23rEfdjWB30LH8Wqj0Cqvv7qSHnvw6kgMMXRdop6hkmGPlyYBdRPkjJnj3KCUHV/uQ==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.2.tgz", + "integrity": "sha512-3HRQLUQbpBDMmzoxPJYd3W6vrVHOo2cVW8RUo87Xz0JPJcBLBr5kZ1pGcQAhdZgX9VV7NbGNipah1omKKe23/g==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.2.tgz", + "integrity": "sha512-fMjKi+ojnmIvhk34gZP94vjogXNNUKMEYs+EDaB/5TG/wUkoeua7p7VCHnE6T2Tx+iaghAqQX8teQzcvrYpaQA==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.2.tgz", + "integrity": "sha512-XuGFGU+VwUUV5kLvoAdi0Wz5Xbh2SrjIxCtZj6Wq8MDp4bflb/+ThZsVxokM7n0pcbkEr2h5/pzqzDYI7cCgLQ==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.2.tgz", + "integrity": "sha512-w6yjZF0P+NGzWR3AXWX9zc0DNEGdtvykB03uhonSHMRa+oWA6novflo2WaJr6JZakG2ucsyb+rvhrKac6NIy+w==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.2.tgz", + "integrity": "sha512-yo8d6tdfdeBArzC7T/PnHd7OypfI9cbuZzPnzLJIyKYFhAQ8SvlkKtKBMbXDxe1h03Rcr7u++nFS7tqXz87Gtw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.2.tgz", + "integrity": "sha512-ah59c1YkCxKExPP8O9PwOvs+XRLKwh/mV+3YdKqQ5AMQ0r4M4ZDuOrpWkUaqO7fzAHdINzV9tEVu8vNw48z0lA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.2.tgz", + "integrity": "sha512-4VEd19Wmhr+Zy7hbUsFZ6YXEiP48hE//KPLCSVNY5RMGX2/7HZ+QkN55a3atM1C/BZCGIgqN+xrVgtdak2S9+A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.2.tgz", + "integrity": "sha512-IlbHFYc/pQCgew/d5fslcy1KEaYVCJ44G8pajugd8VoOEI8ODhtb/j8XMhLpwHCMB3yk2J07ctup10gpw2nyMA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.2.tgz", + "integrity": "sha512-lNlPEGgdUfSzdCWU176ku/dQRnA7W+Gp8d+cWv73jYrb8uT7HTVVxq62DUYxjbaByuf1Yk0RIIAbDzp+CnOTFg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.2.tgz", + "integrity": "sha512-S6YojNVrHybQis2lYov1sd+uj7K0Q05NxHcGktuMMdIQ2VixGwAfbJ23NnlvvVV1bdpR2m5MsNBViHJKcA4ADw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.2.tgz", + "integrity": "sha512-k+/Rkcyx//P6fetPoLMb8pBeqJBNGx81uuf7iljX9++yNBVRDQgD04L+SVXmXmh5ZP4/WOp4mWF0kmi06PW2tA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@shikijs/core": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-3.15.0.tgz", + "integrity": "sha512-8TOG6yG557q+fMsSVa8nkEDOZNTSxjbbR8l6lF2gyr6Np+jrPlslqDxQkN6rMXCECQ3isNPZAGszAfYoJOPGlg==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.15.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4", + "hast-util-to-html": "^9.0.5" + } + }, + "node_modules/@shikijs/engine-javascript": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-3.15.0.tgz", + "integrity": "sha512-ZedbOFpopibdLmvTz2sJPJgns8Xvyabe2QbmqMTz07kt1pTzfEvKZc5IqPVO/XFiEbbNyaOpjPBkkr1vlwS+qg==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.15.0", + "@shikijs/vscode-textmate": "^10.0.2", + "oniguruma-to-es": "^4.3.3" + } + }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.15.0.tgz", + "integrity": "sha512-HnqFsV11skAHvOArMZdLBZZApRSYS4LSztk2K3016Y9VCyZISnlYUYsL2hzlS7tPqKHvNqmI5JSUJZprXloMvA==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.15.0", + "@shikijs/vscode-textmate": "^10.0.2" + } + }, + "node_modules/@shikijs/langs": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.15.0.tgz", + "integrity": "sha512-WpRvEFvkVvO65uKYW4Rzxs+IG0gToyM8SARQMtGGsH4GDMNZrr60qdggXrFOsdfOVssG/QQGEl3FnJ3EZ+8w8A==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.15.0" + } + }, + "node_modules/@shikijs/themes": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.15.0.tgz", + "integrity": "sha512-8ow2zWb1IDvCKjYb0KiLNrK4offFdkfNVPXb1OZykpLCzRU6j+efkY+Y7VQjNlNFXonSw+4AOdGYtmqykDbRiQ==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.15.0" + } + }, + "node_modules/@shikijs/types": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.15.0.tgz", + "integrity": "sha512-BnP+y/EQnhihgHy4oIAN+6FFtmfTekwOLsQbRw9hOKwqgNy8Bdsjq8B05oAt/ZgvIWWFrshV71ytOrlPfYjIJw==", + "license": "MIT", + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", + "license": "MIT" + }, + "node_modules/@swc/helpers": { + "version": "0.5.17", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz", + "integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "license": "MIT" + }, + "node_modules/@types/fontkit": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@types/fontkit/-/fontkit-2.0.8.tgz", + "integrity": "sha512-wN+8bYxIpJf+5oZdrdtaX04qUuWHcKxcDEgRS9Qm9ZClSHjzEn13SxUC+5eRM+4yXIeTYk8mTzLAWGF64847ew==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT" + }, + "node_modules/@types/nlcst": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/nlcst/-/nlcst-2.0.3.tgz", + "integrity": "sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/node": { + "version": "24.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz", + "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "license": "ISC" + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "license": "ISC", + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-align/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/ansi-align/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array-iterate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-2.0.1.tgz", + "integrity": "sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/astro": { + "version": "5.15.6", + "resolved": "https://registry.npmjs.org/astro/-/astro-5.15.6.tgz", + "integrity": "sha512-luLcw+FGkeUHYTfbmYjIWHB4T0D+3VSjCy8DKTXglJ2O3lU40AbwmPVBcnqhRnA1SneKzP5V5pzqjsHzUZ1+Rg==", + "license": "MIT", + "dependencies": { + "@astrojs/compiler": "^2.13.0", + "@astrojs/internal-helpers": "0.7.4", + "@astrojs/markdown-remark": "6.3.8", + "@astrojs/telemetry": "3.3.0", + "@capsizecss/unpack": "^3.0.0", + "@oslojs/encoding": "^1.1.0", + "@rollup/pluginutils": "^5.3.0", + "acorn": "^8.15.0", + "aria-query": "^5.3.2", + "axobject-query": "^4.1.0", + "boxen": "8.0.1", + "ci-info": "^4.3.1", + "clsx": "^2.1.1", + "common-ancestor-path": "^1.0.1", + "cookie": "^1.0.2", + "cssesc": "^3.0.0", + "debug": "^4.4.3", + "deterministic-object-hash": "^2.0.2", + "devalue": "^5.4.2", + "diff": "^5.2.0", + "dlv": "^1.1.3", + "dset": "^3.1.4", + "es-module-lexer": "^1.7.0", + "esbuild": "^0.25.0", + "estree-walker": "^3.0.3", + "flattie": "^1.1.1", + "fontace": "~0.3.1", + "github-slugger": "^2.0.0", + "html-escaper": "3.0.3", + "http-cache-semantics": "^4.2.0", + "import-meta-resolve": "^4.2.0", + "js-yaml": "^4.1.0", + "magic-string": "^0.30.21", + "magicast": "^0.5.1", + "mrmime": "^2.0.1", + "neotraverse": "^0.6.18", + "p-limit": "^6.2.0", + "p-queue": "^8.1.1", + "package-manager-detector": "^1.5.0", + "picocolors": "^1.1.1", + "picomatch": "^4.0.3", + "prompts": "^2.4.2", + "rehype": "^13.0.2", + "semver": "^7.7.3", + "shiki": "^3.15.0", + "smol-toml": "^1.4.2", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tsconfck": "^3.1.6", + "ultrahtml": "^1.6.0", + "unifont": "~0.6.0", + "unist-util-visit": "^5.0.0", + "unstorage": "^1.17.2", + "vfile": "^6.0.3", + "vite": "^6.4.1", + "vitefu": "^1.1.1", + "xxhash-wasm": "^1.1.0", + "yargs-parser": "^21.1.1", + "yocto-spinner": "^0.2.3", + "zod": "^3.25.76", + "zod-to-json-schema": "^3.24.6", + "zod-to-ts": "^1.2.0" + }, + "bin": { + "astro": "astro.js" + }, + "engines": { + "node": "18.20.8 || ^20.3.0 || >=22.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/astrodotbuild" + }, + "optionalDependencies": { + "sharp": "^0.34.0" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/base-64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz", + "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==", + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/boxen": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-8.0.1.tgz", + "integrity": "sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw==", + "license": "MIT", + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^8.0.0", + "chalk": "^5.3.0", + "cli-boxes": "^3.0.0", + "string-width": "^7.2.0", + "type-fest": "^4.21.0", + "widest-line": "^5.0.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brotli": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/brotli/-/brotli-1.3.3.tgz", + "integrity": "sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==", + "license": "MIT", + "dependencies": { + "base64-js": "^1.1.2" + } + }, + "node_modules/camelcase": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz", + "integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ci-info": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", + "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-boxes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", + "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/common-ancestor-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz", + "integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==", + "license": "ISC" + }, + "node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/cookie-es": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-1.2.2.tgz", + "integrity": "sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==", + "license": "MIT" + }, + "node_modules/crossws": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/crossws/-/crossws-0.3.5.tgz", + "integrity": "sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==", + "license": "MIT", + "dependencies": { + "uncrypto": "^0.1.3" + } + }, + "node_modules/css-tree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", + "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.12.2", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz", + "integrity": "sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==", + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/defu": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", + "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", + "license": "MIT" + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/destr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.5.tgz", + "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==", + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/deterministic-object-hash": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/deterministic-object-hash/-/deterministic-object-hash-2.0.2.tgz", + "integrity": "sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ==", + "license": "MIT", + "dependencies": { + "base-64": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/devalue": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.5.0.tgz", + "integrity": "sha512-69sM5yrHfFLJt0AZ9QqZXGCPfJ7fQjvpln3Rq5+PS03LD32Ost1Q9N+eEnaQwGRIriKkMImXD56ocjQmfjbV3w==", + "license": "MIT" + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/dfa": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/dfa/-/dfa-1.2.0.tgz", + "integrity": "sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q==", + "license": "MIT" + }, + "node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "license": "MIT" + }, + "node_modules/dset": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.4.tgz", + "integrity": "sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "license": "MIT" + }, + "node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, + "node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/flattie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flattie/-/flattie-1.1.1.tgz", + "integrity": "sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/fontace": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/fontace/-/fontace-0.3.1.tgz", + "integrity": "sha512-9f5g4feWT1jWT8+SbL85aLIRLIXUaDygaM2xPXRmzPYxrOMNok79Lr3FGJoKVNKibE0WCunNiEVG2mwuE+2qEg==", + "license": "MIT", + "dependencies": { + "@types/fontkit": "^2.0.8", + "fontkit": "^2.0.4" + } + }, + "node_modules/fontkit": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/fontkit/-/fontkit-2.0.4.tgz", + "integrity": "sha512-syetQadaUEDNdxdugga9CpEYVaQIxOwk7GlwZWWZ19//qW4zE5bknOKeMBDYAASwnpaSHKJITRLMF9m1fp3s6g==", + "license": "MIT", + "dependencies": { + "@swc/helpers": "^0.5.12", + "brotli": "^1.3.2", + "clone": "^2.1.2", + "dfa": "^1.2.0", + "fast-deep-equal": "^3.1.3", + "restructure": "^3.0.0", + "tiny-inflate": "^1.0.3", + "unicode-properties": "^1.4.0", + "unicode-trie": "^2.0.0" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", + "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/github-slugger": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", + "license": "ISC" + }, + "node_modules/h3": { + "version": "1.15.4", + "resolved": "https://registry.npmjs.org/h3/-/h3-1.15.4.tgz", + "integrity": "sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ==", + "license": "MIT", + "dependencies": { + "cookie-es": "^1.2.2", + "crossws": "^0.3.5", + "defu": "^6.1.4", + "destr": "^2.0.5", + "iron-webcrypto": "^1.2.1", + "node-mock-http": "^1.0.2", + "radix3": "^1.1.2", + "ufo": "^1.6.1", + "uncrypto": "^0.1.3" + } + }, + "node_modules/hast-util-from-html": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz", + "integrity": "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "devlop": "^1.1.0", + "hast-util-from-parse5": "^8.0.0", + "parse5": "^7.0.0", + "vfile": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz", + "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^9.0.0", + "property-information": "^7.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-is-element": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", + "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.1.0.tgz", + "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-from-parse5": "^8.0.0", + "hast-util-to-parse5": "^8.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "parse5": "^7.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-html": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", + "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-parse5": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz", + "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-parse5/node_modules/property-information": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", + "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/hast-util-to-text": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", + "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "hast-util-is-element": "^3.0.0", + "unist-util-find-after": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.1.tgz", + "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/html-escaper": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", + "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==", + "license": "MIT" + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "license": "BSD-2-Clause" + }, + "node_modules/import-meta-resolve": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", + "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/iron-webcrypto": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz", + "integrity": "sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/brc-dd" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/magicast": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.1.tgz", + "integrity": "sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "source-map-js": "^1.2.1" + } + }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-definitions": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-6.0.0.tgz", + "integrity": "sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", + "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", + "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", + "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", + "license": "CC0-1.0" + }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/neotraverse": { + "version": "0.6.18", + "resolved": "https://registry.npmjs.org/neotraverse/-/neotraverse-0.6.18.tgz", + "integrity": "sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/nlcst-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/nlcst-to-string/-/nlcst-to-string-4.0.0.tgz", + "integrity": "sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/node-fetch-native": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.7.tgz", + "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==", + "license": "MIT" + }, + "node_modules/node-mock-http": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/node-mock-http/-/node-mock-http-1.0.3.tgz", + "integrity": "sha512-jN8dK25fsfnMrVsEhluUTPkBFY+6ybu7jSB1n+ri/vOGjJxU8J9CZhpSGkHXSkFjtUhbmoncG/YG9ta5Ludqog==", + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ofetch": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ofetch/-/ofetch-1.5.1.tgz", + "integrity": "sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==", + "license": "MIT", + "dependencies": { + "destr": "^2.0.5", + "node-fetch-native": "^1.6.7", + "ufo": "^1.6.1" + } + }, + "node_modules/ohash": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz", + "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", + "license": "MIT" + }, + "node_modules/oniguruma-parser": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/oniguruma-parser/-/oniguruma-parser-0.12.1.tgz", + "integrity": "sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==", + "license": "MIT" + }, + "node_modules/oniguruma-to-es": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-4.3.3.tgz", + "integrity": "sha512-rPiZhzC3wXwE59YQMRDodUwwT9FZ9nNBwQQfsd1wfdtlKEyCdRV0avrTcSZ5xlIvGRVPd/cx6ZN45ECmS39xvg==", + "license": "MIT", + "dependencies": { + "oniguruma-parser": "^0.12.1", + "regex": "^6.0.1", + "regex-recursion": "^6.0.2" + } + }, + "node_modules/p-limit": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-6.2.0.tgz", + "integrity": "sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-8.1.1.tgz", + "integrity": "sha512-aNZ+VfjobsWryoiPnEApGGmf5WmNsCo9xu8dfaYamG5qaLP7ClhLN6NgsFe6SwJ2UbLEBK5dv9x8Mn5+RVhMWQ==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^5.0.1", + "p-timeout": "^6.1.2" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.4.tgz", + "integrity": "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-manager-detector": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.5.0.tgz", + "integrity": "sha512-uBj69dVlYe/+wxj8JOpr97XfsxH/eumMt6HqjNTmJDf/6NO9s+0uxeOneIz3AsPt2m6y9PqzDzd3ATcU17MNfw==", + "license": "MIT" + }, + "node_modules/pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==", + "license": "MIT" + }, + "node_modules/parse-latin": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse-latin/-/parse-latin-7.0.0.tgz", + "integrity": "sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "@types/unist": "^3.0.0", + "nlcst-to-string": "^4.0.0", + "unist-util-modify-children": "^4.0.0", + "unist-util-visit-children": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prismjs": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", + "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/property-information": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", + "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/radix3": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/radix3/-/radix3-1.1.2.tgz", + "integrity": "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==", + "license": "MIT" + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/regex/-/regex-6.0.1.tgz", + "integrity": "sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==", + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-recursion": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz", + "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==", + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-utilities": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz", + "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==", + "license": "MIT" + }, + "node_modules/rehype": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/rehype/-/rehype-13.0.2.tgz", + "integrity": "sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "rehype-parse": "^9.0.0", + "rehype-stringify": "^10.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-parse": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-9.0.1.tgz", + "integrity": "sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-from-html": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-raw": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", + "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-raw": "^9.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-stringify": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-10.0.1.tgz", + "integrity": "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-to-html": "^9.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", + "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-smartypants": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/remark-smartypants/-/remark-smartypants-3.0.2.tgz", + "integrity": "sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==", + "license": "MIT", + "dependencies": { + "retext": "^9.0.0", + "retext-smartypants": "^6.0.0", + "unified": "^11.0.4", + "unist-util-visit": "^5.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/restructure": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/restructure/-/restructure-3.0.2.tgz", + "integrity": "sha512-gSfoiOEA0VPE6Tukkrr7I0RBdE0s7H1eFCDBk05l1KIQT1UIKNc5JZy6jdyW6eYH3aR3g5b3PuL77rq0hvwtAw==", + "license": "MIT" + }, + "node_modules/retext": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/retext/-/retext-9.0.0.tgz", + "integrity": "sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "retext-latin": "^4.0.0", + "retext-stringify": "^4.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext-latin": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/retext-latin/-/retext-latin-4.0.0.tgz", + "integrity": "sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "parse-latin": "^7.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext-smartypants": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/retext-smartypants/-/retext-smartypants-6.2.0.tgz", + "integrity": "sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "nlcst-to-string": "^4.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext-stringify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/retext-stringify/-/retext-stringify-4.0.0.tgz", + "integrity": "sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "nlcst-to-string": "^4.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rollup": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.2.tgz", + "integrity": "sha512-MHngMYwGJVi6Fmnk6ISmnk7JAHRNF0UkuucA0CUW3N3a4KnONPEZz+vUanQP/ZC/iY1Qkf3bwPWzyY84wEks1g==", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.53.2", + "@rollup/rollup-android-arm64": "4.53.2", + "@rollup/rollup-darwin-arm64": "4.53.2", + "@rollup/rollup-darwin-x64": "4.53.2", + "@rollup/rollup-freebsd-arm64": "4.53.2", + "@rollup/rollup-freebsd-x64": "4.53.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.53.2", + "@rollup/rollup-linux-arm-musleabihf": "4.53.2", + "@rollup/rollup-linux-arm64-gnu": "4.53.2", + "@rollup/rollup-linux-arm64-musl": "4.53.2", + "@rollup/rollup-linux-loong64-gnu": "4.53.2", + "@rollup/rollup-linux-ppc64-gnu": "4.53.2", + "@rollup/rollup-linux-riscv64-gnu": "4.53.2", + "@rollup/rollup-linux-riscv64-musl": "4.53.2", + "@rollup/rollup-linux-s390x-gnu": "4.53.2", + "@rollup/rollup-linux-x64-gnu": "4.53.2", + "@rollup/rollup-linux-x64-musl": "4.53.2", + "@rollup/rollup-openharmony-arm64": "4.53.2", + "@rollup/rollup-win32-arm64-msvc": "4.53.2", + "@rollup/rollup-win32-ia32-msvc": "4.53.2", + "@rollup/rollup-win32-x64-gnu": "4.53.2", + "@rollup/rollup-win32-x64-msvc": "4.53.2", + "fsevents": "~2.3.2" + } + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sharp": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", + "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.2", + "semver": "^7.7.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.5", + "@img/sharp-darwin-x64": "0.34.5", + "@img/sharp-libvips-darwin-arm64": "1.2.4", + "@img/sharp-libvips-darwin-x64": "1.2.4", + "@img/sharp-libvips-linux-arm": "1.2.4", + "@img/sharp-libvips-linux-arm64": "1.2.4", + "@img/sharp-libvips-linux-ppc64": "1.2.4", + "@img/sharp-libvips-linux-riscv64": "1.2.4", + "@img/sharp-libvips-linux-s390x": "1.2.4", + "@img/sharp-libvips-linux-x64": "1.2.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", + "@img/sharp-libvips-linuxmusl-x64": "1.2.4", + "@img/sharp-linux-arm": "0.34.5", + "@img/sharp-linux-arm64": "0.34.5", + "@img/sharp-linux-ppc64": "0.34.5", + "@img/sharp-linux-riscv64": "0.34.5", + "@img/sharp-linux-s390x": "0.34.5", + "@img/sharp-linux-x64": "0.34.5", + "@img/sharp-linuxmusl-arm64": "0.34.5", + "@img/sharp-linuxmusl-x64": "0.34.5", + "@img/sharp-wasm32": "0.34.5", + "@img/sharp-win32-arm64": "0.34.5", + "@img/sharp-win32-ia32": "0.34.5", + "@img/sharp-win32-x64": "0.34.5" + } + }, + "node_modules/shiki": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-3.15.0.tgz", + "integrity": "sha512-kLdkY6iV3dYbtPwS9KXU7mjfmDm25f5m0IPNFnaXO7TBPcvbUOY72PYXSuSqDzwp+vlH/d7MXpHlKO/x+QoLXw==", + "license": "MIT", + "dependencies": { + "@shikijs/core": "3.15.0", + "@shikijs/engine-javascript": "3.15.0", + "@shikijs/engine-oniguruma": "3.15.0", + "@shikijs/langs": "3.15.0", + "@shikijs/themes": "3.15.0", + "@shikijs/types": "3.15.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "license": "MIT" + }, + "node_modules/smol-toml": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.5.0.tgz", + "integrity": "sha512-Jjsa8LZ+DyLbZ7gVi9d18bS8oxq0PQrTlVDfvYXgh7gxLwbW9QWgvakHD+hBLUtr5NahfStd8LQLGSPchaEJ8Q==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 18" + }, + "funding": { + "url": "https://github.com/sponsors/cyyynthia" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/tiny-inflate": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", + "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==", + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", + "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/tsconfck": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.6.tgz", + "integrity": "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==", + "license": "MIT", + "bin": { + "tsconfck": "bin/tsconfck.js" + }, + "engines": { + "node": "^18 || >=20" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", + "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", + "license": "MIT" + }, + "node_modules/ultrahtml": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ultrahtml/-/ultrahtml-1.6.0.tgz", + "integrity": "sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==", + "license": "MIT" + }, + "node_modules/uncrypto": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/uncrypto/-/uncrypto-0.1.3.tgz", + "integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==", + "license": "MIT" + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "license": "MIT" + }, + "node_modules/unicode-properties": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/unicode-properties/-/unicode-properties-1.4.1.tgz", + "integrity": "sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg==", + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.0", + "unicode-trie": "^2.0.0" + } + }, + "node_modules/unicode-trie": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-2.0.0.tgz", + "integrity": "sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==", + "license": "MIT", + "dependencies": { + "pako": "^0.2.5", + "tiny-inflate": "^1.0.0" + } + }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unifont": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/unifont/-/unifont-0.6.0.tgz", + "integrity": "sha512-5Fx50fFQMQL5aeHyWnZX9122sSLckcDvcfFiBf3QYeHa7a1MKJooUy52b67moi2MJYkrfo/TWY+CoLdr/w0tTA==", + "license": "MIT", + "dependencies": { + "css-tree": "^3.0.0", + "ofetch": "^1.4.1", + "ohash": "^2.0.0" + } + }, + "node_modules/unist-util-find-after": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", + "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", + "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-modify-children": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-modify-children/-/unist-util-modify-children-4.0.0.tgz", + "integrity": "sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "array-iterate": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-remove-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", + "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-children": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-children/-/unist-util-visit-children-3.0.0.tgz", + "integrity": "sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", + "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unstorage": { + "version": "1.17.2", + "resolved": "https://registry.npmjs.org/unstorage/-/unstorage-1.17.2.tgz", + "integrity": "sha512-cKEsD6iBWJgOMJ6vW1ID/SYuqNf8oN4yqRk8OYqaVQ3nnkJXOT1PSpaMh2QfzLs78UN5kSNRD2c/mgjT8tX7+w==", + "license": "MIT", + "dependencies": { + "anymatch": "^3.1.3", + "chokidar": "^4.0.3", + "destr": "^2.0.5", + "h3": "^1.15.4", + "lru-cache": "^10.4.3", + "node-fetch-native": "^1.6.7", + "ofetch": "^1.5.0", + "ufo": "^1.6.1" + }, + "peerDependencies": { + "@azure/app-configuration": "^1.8.0", + "@azure/cosmos": "^4.2.0", + "@azure/data-tables": "^13.3.0", + "@azure/identity": "^4.6.0", + "@azure/keyvault-secrets": "^4.9.0", + "@azure/storage-blob": "^12.26.0", + "@capacitor/preferences": "^6.0.3 || ^7.0.0", + "@deno/kv": ">=0.9.0", + "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", + "@planetscale/database": "^1.19.0", + "@upstash/redis": "^1.34.3", + "@vercel/blob": ">=0.27.1", + "@vercel/functions": "^2.2.12 || ^3.0.0", + "@vercel/kv": "^1.0.1", + "aws4fetch": "^1.0.20", + "db0": ">=0.2.1", + "idb-keyval": "^6.2.1", + "ioredis": "^5.4.2", + "uploadthing": "^7.4.4" + }, + "peerDependenciesMeta": { + "@azure/app-configuration": { + "optional": true + }, + "@azure/cosmos": { + "optional": true + }, + "@azure/data-tables": { + "optional": true + }, + "@azure/identity": { + "optional": true + }, + "@azure/keyvault-secrets": { + "optional": true + }, + "@azure/storage-blob": { + "optional": true + }, + "@capacitor/preferences": { + "optional": true + }, + "@deno/kv": { + "optional": true + }, + "@netlify/blobs": { + "optional": true + }, + "@planetscale/database": { + "optional": true + }, + "@upstash/redis": { + "optional": true + }, + "@vercel/blob": { + "optional": true + }, + "@vercel/functions": { + "optional": true + }, + "@vercel/kv": { + "optional": true + }, + "aws4fetch": { + "optional": true + }, + "db0": { + "optional": true + }, + "idb-keyval": { + "optional": true + }, + "ioredis": { + "optional": true + }, + "uploadthing": { + "optional": true + } + } + }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vite": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", + "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vitefu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.1.tgz", + "integrity": "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==", + "license": "MIT", + "workspaces": [ + "tests/deps/*", + "tests/projects/*", + "tests/projects/workspace/packages/*" + ], + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/which-pm-runs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz", + "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/widest-line": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-5.0.0.tgz", + "integrity": "sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==", + "license": "MIT", + "dependencies": { + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/xxhash-wasm": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-1.1.0.tgz", + "integrity": "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==", + "license": "MIT" + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", + "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yocto-spinner": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/yocto-spinner/-/yocto-spinner-0.2.3.tgz", + "integrity": "sha512-sqBChb33loEnkoXte1bLg45bEBsOP9N1kzQh5JZNKj/0rik4zAPTNSAVPj3uQAdc6slYJ0Ksc403G2XgxsJQFQ==", + "license": "MIT", + "dependencies": { + "yoctocolors": "^2.1.1" + }, + "engines": { + "node": ">=18.19" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", + "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.24.6", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.6.tgz", + "integrity": "sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==", + "license": "ISC", + "peerDependencies": { + "zod": "^3.24.1" + } + }, + "node_modules/zod-to-ts": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/zod-to-ts/-/zod-to-ts-1.2.0.tgz", + "integrity": "sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA==", + "peerDependencies": { + "typescript": "^4.9.4 || ^5.0.2", + "zod": "^3" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/workbench/astro/package.json b/workbench/astro/package.json new file mode 100644 index 000000000..39958fa42 --- /dev/null +++ b/workbench/astro/package.json @@ -0,0 +1,19 @@ +{ + "name": "astro", + "type": "module", + "version": "0.0.1", + "scripts": { + "generate:workflows": "node ../scripts/generate-workflows-registry.js ./src/workflows src/lib/_workflows.ts", + "predev": "pnpm generate:workflows", + "prebuild": "pnpm generate:workflows", + "dev": "astro dev", + "build": "astro build", + "preview": "astro preview", + "astro": "astro" + }, + "dependencies": { + "astro": "^5.15.6", + "nitro": "catalog:", + "workflow": "workspace:*" + } +} diff --git a/workbench/astro/public/favicon.svg b/workbench/astro/public/favicon.svg new file mode 100644 index 000000000..f157bd1c5 --- /dev/null +++ b/workbench/astro/public/favicon.svg @@ -0,0 +1,9 @@ + + + + diff --git a/workbench/astro/src/lib/.gitkeep b/workbench/astro/src/lib/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/workbench/astro/src/pages/api/hook.ts b/workbench/astro/src/pages/api/hook.ts new file mode 100644 index 000000000..afaa46ddc --- /dev/null +++ b/workbench/astro/src/pages/api/hook.ts @@ -0,0 +1,27 @@ +import type { APIRoute } from 'astro'; +import { getHookByToken, resumeHook } from 'workflow/api'; + +export const POST: APIRoute = async ({ request }: { request: Request }) => { + const { token, data } = await request.json(); + + let hook: Awaited>; + try { + hook = await getHookByToken(token); + console.log('hook', hook); + } catch (error) { + console.log('error during getHookByToken', error); + // TODO: `WorkflowAPIError` is not exported, so for now + // we'll return 404 assuming it's the "invalid" token test case + return Response.json(null, { status: 404 }); + } + + await resumeHook(hook.token, { + ...data, + // @ts-expect-error metadata is not typed + customData: hook.metadata?.customData, + }); + + return Response.json(hook); +}; + +export const prerender = false; diff --git a/workbench/astro/src/pages/api/test-direct-step-call.ts b/workbench/astro/src/pages/api/test-direct-step-call.ts new file mode 100644 index 000000000..205dff6c5 --- /dev/null +++ b/workbench/astro/src/pages/api/test-direct-step-call.ts @@ -0,0 +1,19 @@ +import { add } from '../../workflows/99_e2e'; + +export async function POST({ request }: { request: Request }) { + // This route tests calling step functions directly outside of any workflow context + // After the SWC compiler changes, step functions in client mode have their directive removed + // and keep their original implementation, allowing them to be called as regular async functions + const body = await request.json(); + const { x, y } = body; + + console.log(`Calling step function directly with x=${x}, y=${y}`); + + // Call step function directly as a regular async function (no workflow context) + const result = await add(x, y); + console.log(`add(${x}, ${y}) = ${result}`); + + return Response.json({ result }); +} + +export const prerender = false; diff --git a/workbench/astro/src/pages/api/trigger.ts b/workbench/astro/src/pages/api/trigger.ts new file mode 100644 index 000000000..fe54124d5 --- /dev/null +++ b/workbench/astro/src/pages/api/trigger.ts @@ -0,0 +1,153 @@ +import { getRun, start } from 'workflow/api'; +import { + WorkflowRunFailedError, + WorkflowRunNotCompletedError, +} from 'workflow/internal/errors'; +import { hydrateWorkflowArguments } from 'workflow/internal/serialization'; +import { allWorkflows } from '../../lib/_workflows'; +import type { APIRoute } from 'astro'; + +export async function POST({ request }: { request: Request }) { + const url = new URL(request.url); + const workflowFile = + url.searchParams.get('workflowFile') || 'workflows/99_e2e.ts'; + if (!workflowFile) { + return new Response('No workflowFile query parameter provided', { + status: 400, + }); + } + const workflows = allWorkflows[workflowFile as keyof typeof allWorkflows]; + if (!workflows) { + return new Response(`Workflow file "${workflowFile}" not found`, { + status: 400, + }); + } + + const workflowFn = url.searchParams.get('workflowFn') || 'simple'; + if (!workflowFn) { + return new Response('No workflow query parameter provided', { + status: 400, + }); + } + const workflow = workflows[workflowFn as keyof typeof workflows]; + if (!workflow) { + return new Response(`Workflow "${workflowFn}" not found`, { status: 400 }); + } + + let args: any[] = []; + + // Args from query string + const argsParam = url.searchParams.get('args'); + if (argsParam) { + args = argsParam.split(',').map((arg) => { + const num = parseFloat(arg); + return Number.isNaN(num) ? arg.trim() : num; + }); + } else { + // Args from body + const body = await request.text(); + if (body) { + args = hydrateWorkflowArguments(JSON.parse(body), globalThis); + } else { + args = [42]; + } + } + console.log(`Starting "${workflowFn}" workflow with args: ${args}`); + + try { + const run = await start(workflow as any, args as any); + console.log('Run:', run); + return Response.json(run); + } catch (err) { + console.error(`Failed to start!!`, err); + throw err; + } +} + +export const GET: APIRoute = async ({ request }: { request: Request }) => { + const url = new URL(request.url); + const runId = url.searchParams.get('runId'); + if (!runId) { + return new Response('No runId provided', { status: 400 }); + } + + const outputStreamParam = url.searchParams.get('output-stream'); + if (outputStreamParam) { + const namespace = outputStreamParam === '1' ? undefined : outputStreamParam; + const run = getRun(runId); + const stream = run.getReadable({ + namespace, + }); + // Add JSON framing to the stream, wrapping binary data in base64 + const streamWithFraming = new TransformStream({ + transform(chunk, controller) { + const data = + chunk instanceof Uint8Array + ? { data: Buffer.from(chunk).toString('base64') } + : chunk; + controller.enqueue(`${JSON.stringify(data)}\n`); + }, + }); + return new Response(stream.pipeThrough(streamWithFraming), { + headers: { + 'Content-Type': 'application/octet-stream', + }, + }); + } + + try { + const run = getRun(runId); + const returnValue = await run.returnValue; + console.log('Return value:', returnValue); + return returnValue instanceof ReadableStream + ? new Response(returnValue, { + headers: { + 'Content-Type': 'application/octet-stream', + }, + }) + : Response.json(returnValue); + } catch (error) { + if (error instanceof Error) { + if (WorkflowRunNotCompletedError.is(error)) { + return Response.json( + { + ...error, + name: error.name, + message: error.message, + }, + { status: 202 } + ); + } + + if (WorkflowRunFailedError.is(error)) { + const cause = error.cause; + return Response.json( + { + ...error, + name: error.name, + message: error.message, + cause: { + message: cause.message, + stack: cause.stack, + code: cause.code, + }, + }, + { status: 400 } + ); + } + } + + console.error( + 'Unexpected error while getting workflow return value:', + error + ); + return Response.json( + { + error: 'Internal server error', + }, + { status: 500 } + ); + } +}; + +export const prerender = false; diff --git a/workbench/astro/src/pages/index.astro b/workbench/astro/src/pages/index.astro new file mode 100644 index 000000000..2d1410736 --- /dev/null +++ b/workbench/astro/src/pages/index.astro @@ -0,0 +1,16 @@ +--- + +--- + + + + + + + + Astro + + +

Astro

+ + diff --git a/workbench/astro/src/workflows b/workbench/astro/src/workflows new file mode 120000 index 000000000..5cdd2a9ca --- /dev/null +++ b/workbench/astro/src/workflows @@ -0,0 +1 @@ +../../nitro-v3/workflows \ No newline at end of file diff --git a/workbench/astro/tsconfig.json b/workbench/astro/tsconfig.json new file mode 100644 index 000000000..8bf91d3bb --- /dev/null +++ b/workbench/astro/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "astro/tsconfigs/strict", + "include": [".astro/types.d.ts", "**/*"], + "exclude": ["dist"] +} From 4885fa76cc10ba0db64fa926c56381a99bd16376 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 09:24:07 -0800 Subject: [PATCH 08/61] test: add astro test --- .github/workflows/tests.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8aeefb8af..de981ccb5 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -75,6 +75,8 @@ jobs: project-id: "prj_p0GIEsfl53L7IwVbosPvi9rPSOYW" - name: "express" project-id: "prj_cCZjpBy92VRbKHHbarDMhOHtkuIr" + - name: "astro" + project-id: "prj_DvOcT5MdgZo3mw8lpkSXcr7XM7pv" env: TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} TURBO_TEAM: ${{ vars.TURBO_TEAM }} From 9e218549ec85e22ec79104e26984fb18ea20d12e Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 10:36:41 -0800 Subject: [PATCH 09/61] feat(astro): add prefixer to non-api routes in builder --- packages/astro/src/builder.ts | 15 +- pnpm-lock.yaml | 943 ++++++++++++++++++++++++++++++- workbench/astro/astro.config.mjs | 11 +- workbench/astro/package.json | 2 + 4 files changed, 959 insertions(+), 12 deletions(-) diff --git a/packages/astro/src/builder.ts b/packages/astro/src/builder.ts index 9d5184f18..d8baad64d 100644 --- a/packages/astro/src/builder.ts +++ b/packages/astro/src/builder.ts @@ -1,4 +1,4 @@ -import { mkdir, readFile, writeFile } from 'node:fs/promises'; +import { mkdir, readFile, rename, writeFile } from 'node:fs/promises'; import { join, resolve } from 'node:path'; import { BaseBuilder, type AstroConfig } from '@workflow/builders'; @@ -16,6 +16,12 @@ async function normalizeRequestConverter(request) { } `; +const DEBUG_FILES = [ + 'flow.js.debug.json', + 'manifest.debug.json', + 'step.js.debug.json', +]; + export class AstroBuilder extends BaseBuilder { constructor(config?: Partial) { const workingDir = config?.workingDir || process.cwd(); @@ -58,6 +64,13 @@ export class AstroBuilder extends BaseBuilder { await this.buildStepsRoute(options); await this.buildWorkflowsRoute(options); await this.buildWebhookRoute({ workflowGeneratedDir }); + + // Astro requires non-api routes to be prefixed with _ (debug files) + for (const file of DEBUG_FILES) { + const filePath = join(workflowGeneratedDir, file); + const prefixedFilePath = join(workflowGeneratedDir, `_${file}`); + await rename(filePath, prefixedFilePath); + } } private async buildStepsRoute({ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ea8a3df84..68c02a064 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1125,6 +1125,24 @@ importers: specifier: 3.2.0 version: 3.2.0 + workbench/astro: + dependencies: + '@astrojs/node': + specifier: 9.5.0 + version: 9.5.0(astro@5.16.0(@netlify/blobs@9.1.2)(@types/node@24.6.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1)) + '@astrojs/vercel': + specifier: ^9.0.0 + version: 9.0.1(@aws-sdk/credential-provider-web-identity@3.844.0)(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(astro@5.16.0(@netlify/blobs@9.1.2)(@types/node@24.6.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1))(next@16.0.3(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(rollup@4.53.3)(svelte@5.43.3)(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) + astro: + specifier: ^5.15.6 + version: 5.16.0(@netlify/blobs@9.1.2)(@types/node@24.6.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1) + nitro: + specifier: 'catalog:' + version: 3.0.1-alpha.1(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(ioredis@5.8.2)(lru-cache@11.2.2)(rollup@4.53.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + workflow: + specifier: workspace:* + version: link:../../packages/workflow + workbench/example: dependencies: '@vercel/functions': @@ -1599,6 +1617,36 @@ packages: '@antfu/utils@9.3.0': resolution: {integrity: sha512-9hFT4RauhcUzqOE4f1+frMKLZrgNog5b06I7VmZQV1BkvwvqrbC8EBZf3L1eEL2AKb6rNKjER0sEvJiSP1FXEA==} + '@astrojs/compiler@2.13.0': + resolution: {integrity: sha512-mqVORhUJViA28fwHYaWmsXSzLO9osbdZ5ImUfxBarqsYdMlPbqAqGJCxsNzvppp1BEzc1mJNjOVvQqeDN8Vspw==} + + '@astrojs/internal-helpers@0.7.4': + resolution: {integrity: sha512-lDA9MqE8WGi7T/t2BMi+EAXhs4Vcvr94Gqx3q15cFEz8oFZMO4/SFBqYr/UcmNlvW+35alowkVj+w9VhLvs5Cw==} + + '@astrojs/internal-helpers@0.7.5': + resolution: {integrity: sha512-vreGnYSSKhAjFJCWAwe/CNhONvoc5lokxtRoZims+0wa3KbHBdPHSSthJsKxPd8d/aic6lWKpRTYGY/hsgK6EA==} + + '@astrojs/markdown-remark@6.3.9': + resolution: {integrity: sha512-hX2cLC/KW74Io1zIbn92kI482j9J7LleBLGCVU9EP3BeH5MVrnFawOnqD0t/q6D1Z+ZNeQG2gNKMslCcO36wng==} + + '@astrojs/node@9.5.0': + resolution: {integrity: sha512-x1whLIatmCefaqJA8FjfI+P6FStF+bqmmrib0OUGM1M3cZhAXKLgPx6UF2AzQ3JgpXgCWYM24MHtraPvZhhyLQ==} + peerDependencies: + astro: ^5.14.3 + + '@astrojs/prism@3.3.0': + resolution: {integrity: sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ==} + engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0} + + '@astrojs/telemetry@3.3.0': + resolution: {integrity: sha512-UFBgfeldP06qu6khs/yY+q1cDAaArM2/7AEIqQ9Cuvf7B1hNLq0xDrZkct+QoIGyjq56y8IaE2I3CTvG99mlhQ==} + engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0} + + '@astrojs/vercel@9.0.1': + resolution: {integrity: sha512-wdDcRygD7hnFy4c+5ynCZ43lsSXaAeTr7d3A2VedDf/vNrSmT6ZNIECUHzbizrraTqKk8eFC9RQf5aKouSdirw==} + peerDependencies: + astro: ^5.0.0 + '@aws-crypto/sha256-browser@5.2.0': resolution: {integrity: sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==} @@ -1910,6 +1958,10 @@ packages: '@braintree/sanitize-url@7.1.1': resolution: {integrity: sha512-i1L7noDNxtFyL5DmZafWy1wRVhGehQmzZaz1HiN5e7iylJMSZR7ekOV7NsIqa5qBldlLrsKv4HbgFUVlQrz8Mw==} + '@capsizecss/unpack@3.0.1': + resolution: {integrity: sha512-8XqW8xGn++Eqqbz3e9wKuK7mxryeRjs4LOHLxbh2lwKeSbuNR4NFifDZT4KzvjU6HMOPbiNTsWpniK5EJfTWkg==} + engines: {node: '>=18'} + '@changesets/apply-release-plan@7.0.12': resolution: {integrity: sha512-EaET7As5CeuhTzvXTQCRZeBUcisoYPDDcXvgTE/2jmmypKp0RC7LxKj/yzqeh/1qFTZI7oDGFcL1PHRuQuketQ==} @@ -3486,6 +3538,9 @@ packages: resolution: {integrity: sha512-scSmQBD8eANlMUOglxHrN1JdSW8tDghsPuS83otqealBiIeMukCQMOf/wc0JJjDXomqwNdEQFLXLGHrU6PGxuA==} engines: {node: '>= 20.0.0'} + '@oslojs/encoding@1.1.0': + resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==} + '@oven/bun-darwin-aarch64@1.3.0': resolution: {integrity: sha512-WeXSaL29ylJEZMYHHW28QZ6rgAbxQ1KuNSZD9gvd3fPlo0s6s2PglvPArjjP07nmvIK9m4OffN0k4M98O7WmAg==} cpu: [arm64] @@ -6214,6 +6269,9 @@ packages: '@types/express@5.0.5': resolution: {integrity: sha512-LuIQOcb6UmnF7C1PCFmEU1u2hmiHL43fgFQX67sN3H4Z+0Yk0Neo++mFsBjhOAuLzvlQeqAAkeDOZrJs9rzumQ==} + '@types/fontkit@2.0.8': + resolution: {integrity: sha512-wN+8bYxIpJf+5oZdrdtaX04qUuWHcKxcDEgRS9Qm9ZClSHjzEn13SxUC+5eRM+4yXIeTYk8mTzLAWGF64847ew==} + '@types/fs-extra@11.0.4': resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} @@ -6262,6 +6320,9 @@ packages: '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + '@types/nlcst@2.0.3': + resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==} + '@types/node@12.20.55': resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} @@ -6415,6 +6476,15 @@ packages: '@opentelemetry/api': optional: true + '@vercel/functions@2.2.13': + resolution: {integrity: sha512-14ArBSIIcOBx9nrEgaJb4Bw+en1gl6eSoJWh8qjifLl5G3E4dRXCFOT8HP+w66vb9Wqyd1lAQBrmRhRwOj9X9A==} + engines: {node: '>= 18'} + peerDependencies: + '@aws-sdk/credential-provider-web-identity': '*' + peerDependenciesMeta: + '@aws-sdk/credential-provider-web-identity': + optional: true + '@vercel/functions@3.1.4': resolution: {integrity: sha512-1dEfZkb7qxsA+ilo+1uBUCEgr7e90vHcimpDYkUB84DM051wQ5amJDk9x+cnaI29paZb5XukXwGl8yk3Udb/DQ==} engines: {node: '>= 20'} @@ -6434,6 +6504,10 @@ packages: engines: {node: '>=18'} hasBin: true + '@vercel/oidc@2.0.2': + resolution: {integrity: sha512-59PBFx3T+k5hLTEWa3ggiMpGRz1OVvl9eN8SUai+A43IsqiOuAe7qPBf+cray/Fj6mkgnxm/D7IAtjc8zSHi7g==} + engines: {node: '>= 18'} + '@vercel/oidc@3.0.3': resolution: {integrity: sha512-yNEQvPcVrK9sIe637+I0jD6leluPxzwJKx/Haw6F4H77CdDsszUn5V3o96LPziXkSNE2B83+Z3mjqGKBK/R6Gg==} engines: {node: '>= 20'} @@ -6459,6 +6533,9 @@ packages: engines: {node: '>=20.0.0'} hasBin: true + '@vercel/routing-utils@5.3.0': + resolution: {integrity: sha512-gKsPSGc/hBMSHiAXTjTcbSa9egy7wCogrLctx8bJUS21w2OppWzrd5ZqUMqvnrfdKzLMpGIJ2bZMxBQ9xjGkaA==} + '@vercel/speed-insights@1.2.0': resolution: {integrity: sha512-y9GVzrUJ2xmgtQlzFP2KhVRoCglwfRQgjyfY607aU0hh0Un6d0OUyrJkjuAlsV18qR4zfoFPs/BiIj9YDS6Wzw==} peerDependencies: @@ -6756,6 +6833,9 @@ packages: resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} engines: {node: '>= 0.4'} + array-iterate@2.0.1: + resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==} + array-timsort@1.0.3: resolution: {integrity: sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==} @@ -6789,6 +6869,11 @@ packages: resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} hasBin: true + astro@5.16.0: + resolution: {integrity: sha512-GaDRs2Mngpw3dr2vc085GnORh98NiXxwIjg/EoQQQl/icZt3Z7s0BRsYHDZ8swkZbOA6wZsqWJdrNirl+iKcDg==} + engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'} + hasBin: true + async-lock@1.4.1: resolution: {integrity: sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==} @@ -6861,6 +6946,9 @@ packages: bare-url@2.3.0: resolution: {integrity: sha512-c+RCqMSZbkz97Mw1LWR0gcOqwK82oyYKfLoHJ8k13ybi1+I80ffdDzUy0TdAburdrR/kI0/VuN8YgEnJqX+Nyw==} + base-64@1.0.0: + resolution: {integrity: sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==} + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -6926,6 +7014,9 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} + brotli@1.3.3: + resolution: {integrity: sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==} + browserslist@4.27.0: resolution: {integrity: sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} @@ -7082,6 +7173,10 @@ packages: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} + ci-info@4.3.1: + resolution: {integrity: sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==} + engines: {node: '>=8'} + citty@0.1.6: resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} @@ -7130,6 +7225,10 @@ packages: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} + clone@2.1.2: + resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} + engines: {node: '>=0.8'} + cloudflare-video-element@1.3.4: resolution: {integrity: sha512-F9g+tXzGEXI6v6L48qXxr8vnR8+L6yy7IhpJxK++lpzuVekMHTixxH7/dzLuq6OacVGziU4RB5pzZYJ7/LYtJg==} @@ -7219,6 +7318,9 @@ packages: resolution: {integrity: sha512-bKw/r35jR3HGt5PEPm1ljsQQGyCrR8sFGNiN5L+ykDHdpO8Smxkrkla9Yi6NkQyUrb8V54PGhfMs6NrIwtxtdw==} engines: {node: '>= 6'} + common-ancestor-path@1.0.1: + resolution: {integrity: sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==} + common-path-prefix@3.0.0: resolution: {integrity: sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==} @@ -7740,6 +7842,10 @@ packages: peerDependencies: typescript: ^5.4.4 + deterministic-object-hash@2.0.2: + resolution: {integrity: sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ==} + engines: {node: '>=18'} + devalue@5.5.0: resolution: {integrity: sha512-69sM5yrHfFLJt0AZ9QqZXGCPfJ7fQjvpln3Rq5+PS03LD32Ost1Q9N+eEnaQwGRIriKkMImXD56ocjQmfjbV3w==} @@ -7756,6 +7862,13 @@ packages: dexie@4.2.1: resolution: {integrity: sha512-Ckej0NS6jxQ4Po3OrSQBFddayRhTCic2DoCAG5zacOfOVB9P2Q5Xc5uL/nVa7ZVs+HdMnvUPzLFCB/JwpB6Csg==} + dfa@1.2.0: + resolution: {integrity: sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q==} + + diff@5.2.0: + resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} + engines: {node: '>=0.3.1'} + diff@8.0.2: resolution: {integrity: sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==} engines: {node: '>=0.3.1'} @@ -7764,6 +7877,9 @@ packages: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} + dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + docker-compose@1.3.0: resolution: {integrity: sha512-7Gevk/5eGD50+eMD+XDnFnOrruFkL0kSd7jEG4cjmqweDSUhB7i0g8is/nBdVpl+Bx338SqIB2GLKm32M+Vs6g==} engines: {node: '>= 6.0.0'} @@ -7911,6 +8027,10 @@ packages: sqlite3: optional: true + dset@3.1.4: + resolution: {integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==} + engines: {node: '>=4'} + dunder-proto@1.0.1: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} @@ -8332,9 +8452,19 @@ packages: flatted@3.3.3: resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + flattie@1.1.1: + resolution: {integrity: sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==} + engines: {node: '>=8'} + fn.name@1.1.0: resolution: {integrity: sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==} + fontace@0.3.1: + resolution: {integrity: sha512-9f5g4feWT1jWT8+SbL85aLIRLIXUaDygaM2xPXRmzPYxrOMNok79Lr3FGJoKVNKibE0WCunNiEVG2mwuE+2qEg==} + + fontkit@2.0.4: + resolution: {integrity: sha512-syetQadaUEDNdxdugga9CpEYVaQIxOwk7GlwZWWZ19//qW4zE5bknOKeMBDYAASwnpaSHKJITRLMF9m1fp3s6g==} + foreground-child@3.3.1: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} @@ -8756,12 +8886,18 @@ packages: html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + html-escaper@3.0.3: + resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==} + html-url-attributes@3.0.1: resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==} html-void-elements@3.0.0: resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + http-cache-semantics@4.2.0: + resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} + http-errors@2.0.0: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} @@ -8835,6 +8971,9 @@ packages: import-in-the-middle@1.15.0: resolution: {integrity: sha512-bpQy+CrsRmYmoPMAE/0G33iwRqwW4ouqdRg8jgbH3aKuCtOc8lxgmYXg2dMM92CRiGP660EtBcymH/eVUpCSaA==} + import-meta-resolve@4.2.0: + resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} + impound@1.0.0: resolution: {integrity: sha512-8lAJ+1Arw2sMaZ9HE2ZmL5zOcMnt18s6+7Xqgq2aUVy4P1nlzAyPtzCDxsk51KVFwHEEdc6OWvUyqwHwhRYaug==} @@ -9120,6 +9259,10 @@ packages: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + jsesc@3.1.0: resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} engines: {node: '>=6'} @@ -9435,6 +9578,9 @@ packages: magicast@0.3.5: resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} + magicast@0.5.1: + resolution: {integrity: sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==} + make-dir@4.0.0: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} @@ -9455,6 +9601,9 @@ packages: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} + mdast-util-definitions@6.0.0: + resolution: {integrity: sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==} + mdast-util-find-and-replace@3.0.2: resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} @@ -9846,6 +9995,10 @@ packages: resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} engines: {node: '>= 0.6'} + neotraverse@0.6.18: + resolution: {integrity: sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==} + engines: {node: '>= 10'} + netlify@13.3.5: resolution: {integrity: sha512-Nc3loyVASW59W+8fLDZT1lncpG7llffyZ2o0UQLx/Fr20i7P8oP+lE7+TEcFvXj9IUWU6LjB9P3BH+iFGyp+mg==} engines: {node: ^14.16.0 || >=16.0.0} @@ -9964,6 +10117,9 @@ packages: xml2js: optional: true + nlcst-to-string@4.0.0: + resolution: {integrity: sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==} + node-abi@3.78.0: resolution: {integrity: sha512-E2wEyrgX/CqvicaQYU3Ze1PFGjc4QYPGsjUrlYkqAE0WjHEZwgOsGMPMzkMse4LjJbDmaEuDX3CM036j5K2DSQ==} engines: {node: '>=10'} @@ -10258,6 +10414,10 @@ packages: resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + p-limit@6.2.0: + resolution: {integrity: sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==} + engines: {node: '>=18'} + p-locate@4.1.0: resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} engines: {node: '>=8'} @@ -10278,6 +10438,10 @@ packages: resolution: {integrity: sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==} engines: {node: '>=18'} + p-queue@8.1.1: + resolution: {integrity: sha512-aNZ+VfjobsWryoiPnEApGGmf5WmNsCo9xu8dfaYamG5qaLP7ClhLN6NgsFe6SwJ2UbLEBK5dv9x8Mn5+RVhMWQ==} + engines: {node: '>=18'} + p-timeout@6.1.4: resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==} engines: {node: '>=14.16'} @@ -10299,6 +10463,9 @@ packages: package-manager-detector@1.5.0: resolution: {integrity: sha512-uBj69dVlYe/+wxj8JOpr97XfsxH/eumMt6HqjNTmJDf/6NO9s+0uxeOneIz3AsPt2m6y9PqzDzd3ATcU17MNfw==} + pako@0.2.9: + resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -10321,6 +10488,9 @@ packages: resolution: {integrity: sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==} engines: {node: '>=18'} + parse-latin@7.0.0: + resolution: {integrity: sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==} + parse-ms@4.0.0: resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} engines: {node: '>=18'} @@ -10372,6 +10542,12 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} + path-to-regexp@6.1.0: + resolution: {integrity: sha512-h9DqehX3zZZDCEm+xbfU0ZmwCGFCAAraPJWMXJ4+v32NjZJilVg3k1TcKsRgIb8IQ/izZSaydDc1OhJCZvs2Dw==} + + path-to-regexp@6.3.0: + resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} + path-to-regexp@8.3.0: resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} @@ -10440,6 +10616,9 @@ packages: pgpass@1.0.5: resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==} + piccolore@0.1.3: + resolution: {integrity: sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw==} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -10719,6 +10898,10 @@ packages: resolution: {integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==} engines: {node: '>=18'} + prismjs@1.30.0: + resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} + engines: {node: '>=6'} + process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} @@ -11007,12 +11190,21 @@ packages: rehype-katex@7.0.1: resolution: {integrity: sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==} + rehype-parse@9.0.1: + resolution: {integrity: sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==} + rehype-raw@7.0.0: resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} rehype-recma@1.0.0: resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} + rehype-stringify@10.0.1: + resolution: {integrity: sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==} + + rehype@13.0.2: + resolution: {integrity: sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==} + remark-gfm@4.0.1: resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} @@ -11028,6 +11220,10 @@ packages: remark-rehype@11.1.2: resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} + remark-smartypants@3.0.2: + resolution: {integrity: sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==} + engines: {node: '>=16.0.0'} + remark-stringify@11.0.0: resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} @@ -11076,6 +11272,21 @@ packages: resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} engines: {node: '>=18'} + restructure@3.0.2: + resolution: {integrity: sha512-gSfoiOEA0VPE6Tukkrr7I0RBdE0s7H1eFCDBk05l1KIQT1UIKNc5JZy6jdyW6eYH3aR3g5b3PuL77rq0hvwtAw==} + + retext-latin@4.0.0: + resolution: {integrity: sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==} + + retext-smartypants@6.2.0: + resolution: {integrity: sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==} + + retext-stringify@4.0.0: + resolution: {integrity: sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==} + + retext@9.0.0: + resolution: {integrity: sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==} + retry@0.12.0: resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} engines: {node: '>= 4'} @@ -11214,6 +11425,9 @@ packages: resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==} engines: {node: '>= 18'} + server-destroy@1.0.1: + resolution: {integrity: sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ==} + set-cookie-parser@2.7.2: resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==} @@ -11306,6 +11520,10 @@ packages: smob@1.5.0: resolution: {integrity: sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==} + smol-toml@1.5.2: + resolution: {integrity: sha512-QlaZEqcAH3/RtNyet1IPIYPsEWAaYyXXv1Krsi+1L/QHppjX4Ifm8MQsBISz9vE8cHicIq3clogsheili5vhaQ==} + engines: {node: '>= 18'} + sonner@2.0.7: resolution: {integrity: sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w==} peerDependencies: @@ -11633,6 +11851,9 @@ packages: tiktok-video-element@0.1.1: resolution: {integrity: sha512-BaiVzvNz2UXDKTdSrXzrNf4q6Ecc+/utYUh7zdEu2jzYcJVDoqYbVfUl0bCfMoOeeAqg28vD/yN63Y3E9jOrlA==} + tiny-inflate@1.0.3: + resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} + tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} @@ -11879,6 +12100,12 @@ packages: unhead@2.0.19: resolution: {integrity: sha512-gEEjkV11Aj+rBnY6wnRfsFtF2RxKOLaPN4i+Gx3UhBxnszvV6ApSNZbGk7WKyy/lErQ6ekPN63qdFL7sa1leow==} + unicode-properties@1.4.1: + resolution: {integrity: sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg==} + + unicode-trie@2.0.0: + resolution: {integrity: sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==} + unicorn-magic@0.1.0: resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} engines: {node: '>=18'} @@ -11890,6 +12117,9 @@ packages: unified@11.0.5: resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + unifont@0.6.0: + resolution: {integrity: sha512-5Fx50fFQMQL5aeHyWnZX9122sSLckcDvcfFiBf3QYeHa7a1MKJooUy52b67moi2MJYkrfo/TWY+CoLdr/w0tTA==} + unimport@5.5.0: resolution: {integrity: sha512-/JpWMG9s1nBSlXJAQ8EREFTFy3oy6USFd8T6AoBaw1q2GGcF4R9yp3ofg32UODZlYEO5VD0EWE1RpI9XDWyPYg==} engines: {node: '>=18.12.0'} @@ -11900,6 +12130,9 @@ packages: unist-util-is@6.0.0: resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} + unist-util-modify-children@4.0.0: + resolution: {integrity: sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==} + unist-util-position-from-estree@2.0.0: resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} @@ -11912,9 +12145,15 @@ packages: unist-util-stringify-position@4.0.0: resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + unist-util-visit-children@3.0.0: + resolution: {integrity: sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==} + unist-util-visit-parents@6.0.1: resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + unist-util-visit@5.0.0: resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} @@ -12032,6 +12271,68 @@ packages: uploadthing: optional: true + unstorage@1.17.3: + resolution: {integrity: sha512-i+JYyy0DoKmQ3FximTHbGadmIYb8JEpq7lxUjnjeB702bCPum0vzo6oy5Mfu0lpqISw7hCyMW2yj4nWC8bqJ3Q==} + peerDependencies: + '@azure/app-configuration': ^1.8.0 + '@azure/cosmos': ^4.2.0 + '@azure/data-tables': ^13.3.0 + '@azure/identity': ^4.6.0 + '@azure/keyvault-secrets': ^4.9.0 + '@azure/storage-blob': ^12.26.0 + '@capacitor/preferences': ^6.0.3 || ^7.0.0 + '@deno/kv': '>=0.9.0' + '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0 + '@planetscale/database': ^1.19.0 + '@upstash/redis': ^1.34.3 + '@vercel/blob': '>=0.27.1' + '@vercel/functions': ^2.2.12 || ^3.0.0 + '@vercel/kv': ^1.0.1 + aws4fetch: ^1.0.20 + db0: '>=0.2.1' + idb-keyval: ^6.2.1 + ioredis: ^5.4.2 + uploadthing: ^7.4.4 + peerDependenciesMeta: + '@azure/app-configuration': + optional: true + '@azure/cosmos': + optional: true + '@azure/data-tables': + optional: true + '@azure/identity': + optional: true + '@azure/keyvault-secrets': + optional: true + '@azure/storage-blob': + optional: true + '@capacitor/preferences': + optional: true + '@deno/kv': + optional: true + '@netlify/blobs': + optional: true + '@planetscale/database': + optional: true + '@upstash/redis': + optional: true + '@vercel/blob': + optional: true + '@vercel/functions': + optional: true + '@vercel/kv': + optional: true + aws4fetch: + optional: true + db0: + optional: true + idb-keyval: + optional: true + ioredis: + optional: true + uploadthing: + optional: true + unstorage@2.0.0-alpha.4: resolution: {integrity: sha512-ywXZMZRfrvmO1giJeMTCw6VUn0ALYxVl8pFqJPStiyQUvgJImejtAHrKvXPj4QGJAoS/iLGcVGF6ljN/lkh1bw==} peerDependencies: @@ -12311,6 +12612,46 @@ packages: vite: ^6.0.0 || ^7.0.0 vue: ^3.5.0 + vite@6.4.1: + resolution: {integrity: sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: '>=1.21.0' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + vite@7.1.11: resolution: {integrity: sha512-uzcxnSDVjAopEUjljkWh8EIrg6tlzrjFUfMcR1EVsRDGwf/ccef0qQPRyOrROwhrTDaApueq+ja+KLPlzR/zdg==} engines: {node: ^20.19.0 || >=22.12.0} @@ -12504,6 +12845,10 @@ packages: whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + which-pm-runs@1.1.0: + resolution: {integrity: sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==} + engines: {node: '>=4'} + which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -12596,6 +12941,9 @@ packages: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} + xxhash-wasm@1.1.0: + resolution: {integrity: sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==} + y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -12636,6 +12984,10 @@ packages: resolution: {integrity: sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==} engines: {node: '>=12.20'} + yocto-spinner@0.2.3: + resolution: {integrity: sha512-sqBChb33loEnkoXte1bLg45bEBsOP9N1kzQh5JZNKj/0rik4zAPTNSAVPj3uQAdc6slYJ0Ksc403G2XgxsJQFQ==} + engines: {node: '>=18.19'} + yoctocolors@2.1.2: resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} engines: {node: '>=18'} @@ -12660,6 +13012,17 @@ packages: resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} engines: {node: '>= 14'} + zod-to-json-schema@3.25.0: + resolution: {integrity: sha512-HvWtU2UG41LALjajJrML6uQejQhNJx+JBO9IflpSja4R03iNWfKXrj6W2h7ljuLyc1nKS+9yDyL/9tD1U/yBnQ==} + peerDependencies: + zod: ^3.25 || ^4 + + zod-to-ts@1.2.0: + resolution: {integrity: sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA==} + peerDependencies: + typescript: ^4.9.4 || ^5.0.2 + zod: ^3 + zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} @@ -12726,6 +13089,86 @@ snapshots: '@antfu/utils@9.3.0': {} + '@astrojs/compiler@2.13.0': {} + + '@astrojs/internal-helpers@0.7.4': {} + + '@astrojs/internal-helpers@0.7.5': {} + + '@astrojs/markdown-remark@6.3.9': + dependencies: + '@astrojs/internal-helpers': 0.7.5 + '@astrojs/prism': 3.3.0 + github-slugger: 2.0.0 + hast-util-from-html: 2.0.3 + hast-util-to-text: 4.0.2 + import-meta-resolve: 4.2.0 + js-yaml: 4.1.1 + mdast-util-definitions: 6.0.0 + rehype-raw: 7.0.0 + rehype-stringify: 10.0.1 + remark-gfm: 4.0.1 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + remark-smartypants: 3.0.2 + shiki: 3.13.0 + smol-toml: 1.5.2 + unified: 11.0.5 + unist-util-remove-position: 5.0.0 + unist-util-visit: 5.0.0 + unist-util-visit-parents: 6.0.2 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@astrojs/node@9.5.0(astro@5.16.0(@netlify/blobs@9.1.2)(@types/node@24.6.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1))': + dependencies: + '@astrojs/internal-helpers': 0.7.4 + astro: 5.16.0(@netlify/blobs@9.1.2)(@types/node@24.6.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1) + send: 1.2.0 + server-destroy: 1.0.1 + transitivePeerDependencies: + - supports-color + + '@astrojs/prism@3.3.0': + dependencies: + prismjs: 1.30.0 + + '@astrojs/telemetry@3.3.0': + dependencies: + ci-info: 4.3.1 + debug: 4.4.3(supports-color@8.1.1) + dlv: 1.1.3 + dset: 3.1.4 + is-docker: 3.0.0 + is-wsl: 3.1.0 + which-pm-runs: 1.1.0 + transitivePeerDependencies: + - supports-color + + '@astrojs/vercel@9.0.1(@aws-sdk/credential-provider-web-identity@3.844.0)(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(astro@5.16.0(@netlify/blobs@9.1.2)(@types/node@24.6.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1))(next@16.0.3(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(rollup@4.53.3)(svelte@5.43.3)(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))': + dependencies: + '@astrojs/internal-helpers': 0.7.5 + '@vercel/analytics': 1.5.0(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(next@16.0.3(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(svelte@5.43.3)(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) + '@vercel/functions': 2.2.13(@aws-sdk/credential-provider-web-identity@3.844.0) + '@vercel/nft': 0.30.3(rollup@4.53.3) + '@vercel/routing-utils': 5.3.0 + astro: 5.16.0(@netlify/blobs@9.1.2)(@types/node@24.6.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1) + esbuild: 0.25.12 + tinyglobby: 0.2.15 + transitivePeerDependencies: + - '@aws-sdk/credential-provider-web-identity' + - '@remix-run/react' + - '@sveltejs/kit' + - encoding + - next + - react + - rollup + - supports-color + - svelte + - vue + - vue-router + '@aws-crypto/sha256-browser@5.2.0': dependencies: '@aws-crypto/sha256-js': 5.2.0 @@ -13307,6 +13750,10 @@ snapshots: '@braintree/sanitize-url@7.1.1': {} + '@capsizecss/unpack@3.0.1': + dependencies: + fontkit: 2.0.4 + '@changesets/apply-release-plan@7.0.12': dependencies: '@changesets/config': 3.1.1 @@ -15097,6 +15544,8 @@ snapshots: '@orama/orama@3.1.16': {} + '@oslojs/encoding@1.1.0': {} + '@oven/bun-darwin-aarch64@1.3.0': optional: true @@ -17460,11 +17909,11 @@ snapshots: - rollup - supports-color - '@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': + '@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@standard-schema/spec': 1.0.0 '@sveltejs/acorn-typescript': 1.0.6(acorn@8.15.0) - '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) '@types/cookie': 0.6.0 acorn: 8.15.0 cookie: 0.6.0 @@ -17477,16 +17926,16 @@ snapshots: set-cookie-parser: 2.7.2 sirv: 3.0.2 svelte: 5.43.3 - vite: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) optionalDependencies: '@opentelemetry/api': 1.9.0 optional: true - '@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': + '@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@standard-schema/spec': 1.0.0 '@sveltejs/acorn-typescript': 1.0.6(acorn@8.15.0) - '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) '@types/cookie': 0.6.0 acorn: 8.15.0 cookie: 0.6.0 @@ -17499,14 +17948,46 @@ snapshots: set-cookie-parser: 2.7.2 sirv: 3.0.2 svelte: 5.43.3 - vite: 7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) optionalDependencies: '@opentelemetry/api': 1.9.0 + optional: true - '@sveltejs/vite-plugin-svelte-inspector@5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': + '@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: - '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) - debug: 4.4.3(supports-color@8.1.1) + '@standard-schema/spec': 1.0.0 + '@sveltejs/acorn-typescript': 1.0.6(acorn@8.15.0) + '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + '@types/cookie': 0.6.0 + acorn: 8.15.0 + cookie: 0.6.0 + devalue: 5.5.0 + esm-env: 1.2.2 + kleur: 4.1.5 + magic-string: 0.30.21 + mrmime: 2.0.1 + sade: 1.8.1 + set-cookie-parser: 2.7.2 + sirv: 3.0.2 + svelte: 5.43.3 + vite: 7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + optionalDependencies: + '@opentelemetry/api': 1.9.0 + + '@sveltejs/vite-plugin-svelte-inspector@5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': + dependencies: + '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + debug: 4.4.3(supports-color@8.1.1) + svelte: 5.43.3 + vite: 6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + transitivePeerDependencies: + - supports-color + optional: true + + '@sveltejs/vite-plugin-svelte-inspector@5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': + dependencies: + '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + debug: 4.4.3(supports-color@8.1.1) svelte: 5.43.3 vite: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: @@ -17522,6 +18003,19 @@ snapshots: transitivePeerDependencies: - supports-color + '@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': + dependencies: + '@sveltejs/vite-plugin-svelte-inspector': 5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + debug: 4.4.3(supports-color@8.1.1) + deepmerge: 4.3.1 + magic-string: 0.30.21 + svelte: 5.43.3 + vite: 6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vitefu: 1.1.1(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + transitivePeerDependencies: + - supports-color + optional: true + '@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@sveltejs/vite-plugin-svelte-inspector': 5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) @@ -17873,6 +18367,10 @@ snapshots: '@types/express-serve-static-core': 5.1.0 '@types/serve-static': 1.15.10 + '@types/fontkit@2.0.8': + dependencies: + '@types/node': 24.6.2 + '@types/fs-extra@11.0.4': dependencies: '@types/jsonfile': 6.1.4 @@ -17921,6 +18419,10 @@ snapshots: '@types/ms@2.1.0': {} + '@types/nlcst@2.0.3': + dependencies: + '@types/unist': 3.0.3 + '@types/node@12.20.55': {} '@types/node@18.19.130': @@ -18052,6 +18554,15 @@ snapshots: unhead: 2.0.19 vue: 3.5.22(typescript@5.9.3) + '@vercel/analytics@1.5.0(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(next@16.0.3(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(svelte@5.43.3)(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))': + optionalDependencies: + '@sveltejs/kit': 2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + next: 16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + react: 19.2.0 + svelte: 5.43.3 + vue: 3.5.22(typescript@5.9.3) + vue-router: 4.6.3(vue@3.5.22(typescript@5.9.3)) + '@vercel/analytics@1.5.0(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(svelte@5.43.3)(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))': optionalDependencies: '@sveltejs/kit': 2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) @@ -18069,6 +18580,12 @@ snapshots: optionalDependencies: '@opentelemetry/api': 1.9.0 + '@vercel/functions@2.2.13(@aws-sdk/credential-provider-web-identity@3.844.0)': + dependencies: + '@vercel/oidc': 2.0.2 + optionalDependencies: + '@aws-sdk/credential-provider-web-identity': 3.844.0 + '@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.609.0(@aws-sdk/client-sts@3.844.0))': dependencies: '@vercel/oidc': 3.0.3 @@ -18138,6 +18655,11 @@ snapshots: - rollup - supports-color + '@vercel/oidc@2.0.2': + dependencies: + '@types/ms': 2.1.0 + ms: 2.1.3 + '@vercel/oidc@3.0.3': {} '@vercel/oidc@3.0.5': {} @@ -18157,6 +18679,13 @@ snapshots: '@vercel/oidc': 3.0.5 mixpart: 0.0.5-alpha.1 + '@vercel/routing-utils@5.3.0': + dependencies: + path-to-regexp: 6.1.0 + path-to-regexp-updated: path-to-regexp@6.3.0 + optionalDependencies: + ajv: 6.12.6 + '@vercel/speed-insights@1.2.0(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(svelte@5.43.3)(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))': optionalDependencies: '@sveltejs/kit': 2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) @@ -18555,6 +19084,8 @@ snapshots: aria-query@5.3.2: {} + array-iterate@2.0.1: {} + array-timsort@1.0.3: {} array-union@2.1.0: {} @@ -18585,6 +19116,108 @@ snapshots: astring@1.9.0: {} + astro@5.16.0(@netlify/blobs@9.1.2)(@types/node@24.6.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1): + dependencies: + '@astrojs/compiler': 2.13.0 + '@astrojs/internal-helpers': 0.7.5 + '@astrojs/markdown-remark': 6.3.9 + '@astrojs/telemetry': 3.3.0 + '@capsizecss/unpack': 3.0.1 + '@oslojs/encoding': 1.1.0 + '@rollup/pluginutils': 5.3.0(rollup@4.53.3) + acorn: 8.15.0 + aria-query: 5.3.2 + axobject-query: 4.1.0 + boxen: 8.0.1 + ci-info: 4.3.1 + clsx: 2.1.1 + common-ancestor-path: 1.0.1 + cookie: 1.0.2 + cssesc: 3.0.0 + debug: 4.4.3(supports-color@8.1.1) + deterministic-object-hash: 2.0.2 + devalue: 5.5.0 + diff: 5.2.0 + dlv: 1.1.3 + dset: 3.1.4 + es-module-lexer: 1.7.0 + esbuild: 0.25.12 + estree-walker: 3.0.3 + flattie: 1.1.1 + fontace: 0.3.1 + github-slugger: 2.0.0 + html-escaper: 3.0.3 + http-cache-semantics: 4.2.0 + import-meta-resolve: 4.2.0 + js-yaml: 4.1.1 + magic-string: 0.30.21 + magicast: 0.5.1 + mrmime: 2.0.1 + neotraverse: 0.6.18 + p-limit: 6.2.0 + p-queue: 8.1.1 + package-manager-detector: 1.5.0 + piccolore: 0.1.3 + picomatch: 4.0.3 + prompts: 2.4.2 + rehype: 13.0.2 + semver: 7.7.3 + shiki: 3.15.0 + smol-toml: 1.5.2 + svgo: 4.0.0 + tinyexec: 1.0.2 + tinyglobby: 0.2.15 + tsconfck: 3.1.6(typescript@5.9.3) + ultrahtml: 1.6.0 + unifont: 0.6.0 + unist-util-visit: 5.0.0 + unstorage: 1.17.3(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2) + vfile: 6.0.3 + vite: 6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vitefu: 1.1.1(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + xxhash-wasm: 1.1.0 + yargs-parser: 21.1.1 + yocto-spinner: 0.2.3 + zod: 3.25.76 + zod-to-json-schema: 3.25.0(zod@3.25.76) + zod-to-ts: 1.2.0(typescript@5.9.3)(zod@3.25.76) + optionalDependencies: + sharp: 0.34.4 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@types/node' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - db0 + - idb-keyval + - ioredis + - jiti + - less + - lightningcss + - rollup + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - typescript + - uploadthing + - yaml + async-lock@1.4.1: {} async-sema@3.1.1: {} @@ -18646,6 +19279,8 @@ snapshots: bare-path: 3.0.0 optional: true + base-64@1.0.0: {} + base64-js@1.5.1: {} baseline-browser-mapping@2.8.19: {} @@ -18735,6 +19370,10 @@ snapshots: dependencies: fill-range: 7.1.1 + brotli@1.3.3: + dependencies: + base64-js: 1.5.1 + browserslist@4.27.0: dependencies: baseline-browser-mapping: 2.8.19 @@ -18895,6 +19534,8 @@ snapshots: ci-info@3.9.0: {} + ci-info@4.3.1: {} + citty@0.1.6: dependencies: consola: 3.4.2 @@ -18946,6 +19587,8 @@ snapshots: clone@1.0.4: optional: true + clone@2.1.2: {} + cloudflare-video-element@1.3.4: {} clsx@2.1.1: {} @@ -19019,6 +19662,8 @@ snapshots: has-own-prop: 2.0.0 repeat-string: 1.6.1 + common-ancestor-path@1.0.1: {} + common-path-prefix@3.0.0: {} commondir@1.0.1: {} @@ -19550,6 +20195,10 @@ snapshots: transitivePeerDependencies: - supports-color + deterministic-object-hash@2.0.2: + dependencies: + base-64: 1.0.0 + devalue@5.5.0: {} devlop@1.1.0: @@ -19564,12 +20213,18 @@ snapshots: dexie@4.2.1: {} + dfa@1.2.0: {} + + diff@5.2.0: {} + diff@8.0.2: {} dir-glob@3.0.1: dependencies: path-type: 4.0.0 + dlv@1.1.3: {} + docker-compose@1.3.0: dependencies: yaml: 2.8.1 @@ -19652,6 +20307,8 @@ snapshots: pg: 8.16.3 postgres: 3.4.7 + dset@3.1.4: {} + dunder-proto@1.0.1: dependencies: call-bind-apply-helpers: 1.0.2 @@ -20243,8 +20900,27 @@ snapshots: flatted@3.3.3: optional: true + flattie@1.1.1: {} + fn.name@1.1.0: {} + fontace@0.3.1: + dependencies: + '@types/fontkit': 2.0.8 + fontkit: 2.0.4 + + fontkit@2.0.4: + dependencies: + '@swc/helpers': 0.5.15 + brotli: 1.3.3 + clone: 2.1.2 + dfa: 1.2.0 + fast-deep-equal: 3.1.3 + restructure: 3.0.2 + tiny-inflate: 1.0.3 + unicode-properties: 1.4.1 + unicode-trie: 2.0.0 + foreground-child@3.3.1: dependencies: cross-spawn: 7.0.6 @@ -20790,10 +21466,14 @@ snapshots: html-escaper@2.0.2: {} + html-escaper@3.0.3: {} + html-url-attributes@3.0.1: {} html-void-elements@3.0.0: {} + http-cache-semantics@4.2.0: {} + http-errors@2.0.0: dependencies: depd: 2.0.0 @@ -20857,6 +21537,8 @@ snapshots: cjs-module-lexer: 1.4.3 module-details-from-path: 1.0.4 + import-meta-resolve@4.2.0: {} + impound@1.0.0: dependencies: exsolve: 1.0.7 @@ -21087,6 +21769,10 @@ snapshots: dependencies: argparse: 2.0.1 + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + jsesc@3.1.0: {} json-buffer@3.0.1: @@ -21405,6 +22091,12 @@ snapshots: '@babel/types': 7.28.5 source-map-js: 1.2.1 + magicast@0.5.1: + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + source-map-js: 1.2.1 + make-dir@4.0.0: dependencies: semver: 7.7.3 @@ -21417,6 +22109,12 @@ snapshots: math-intrinsics@1.1.0: {} + mdast-util-definitions@6.0.0: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + unist-util-visit: 5.0.0 + mdast-util-find-and-replace@3.0.2: dependencies: '@types/mdast': 4.0.4 @@ -22064,6 +22762,8 @@ snapshots: negotiator@1.0.0: {} + neotraverse@0.6.18: {} + netlify@13.3.5: dependencies: '@netlify/open-api': 2.43.1 @@ -22193,6 +22893,54 @@ snapshots: nf3@0.1.12: {} + nitro@3.0.1-alpha.1(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(ioredis@5.8.2)(lru-cache@11.2.2)(rollup@4.53.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): + dependencies: + consola: 3.4.2 + crossws: 0.4.1(srvx@0.9.6) + db0: 0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)) + h3: 2.0.1-rc.5(crossws@0.4.1(srvx@0.9.6)) + jiti: 2.6.1 + nf3: 0.1.12 + ofetch: 2.0.0-alpha.3 + ohash: 2.0.11 + oxc-minify: 0.96.0 + oxc-transform: 0.96.0 + srvx: 0.9.6 + undici: 7.16.0 + unenv: 2.0.0-rc.24 + unstorage: 2.0.0-alpha.4(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(chokidar@4.0.3)(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(lru-cache@11.2.2)(ofetch@2.0.0-alpha.3) + optionalDependencies: + rollup: 4.53.3 + vite: 6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@electric-sql/pglite' + - '@libsql/client' + - '@netlify/blobs' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - better-sqlite3 + - chokidar + - drizzle-orm + - idb-keyval + - ioredis + - lru-cache + - mongodb + - mysql2 + - sqlite3 + - uploadthing + nitro@3.0.1-alpha.1(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(ioredis@5.8.2)(lru-cache@11.2.2)(rollup@4.53.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): dependencies: consola: 3.4.2 @@ -22494,6 +23242,10 @@ snapshots: - supports-color - uploadthing + nlcst-to-string@4.0.0: + dependencies: + '@types/nlcst': 2.0.3 + node-abi@3.78.0: dependencies: semver: 7.7.3 @@ -23122,6 +23874,10 @@ snapshots: dependencies: yocto-queue: 1.2.1 + p-limit@6.2.0: + dependencies: + yocto-queue: 1.2.1 + p-locate@4.1.0: dependencies: p-limit: 2.3.0 @@ -23139,6 +23895,11 @@ snapshots: p-map@7.0.4: {} + p-queue@8.1.1: + dependencies: + eventemitter3: 5.0.1 + p-timeout: 6.1.4 + p-timeout@6.1.4: {} p-try@2.2.0: {} @@ -23155,6 +23916,8 @@ snapshots: package-manager-detector@1.5.0: {} + pako@0.2.9: {} + parent-module@1.0.1: dependencies: callsites: 3.1.0 @@ -23188,6 +23951,15 @@ snapshots: index-to-position: 1.2.0 type-fest: 4.41.0 + parse-latin@7.0.0: + dependencies: + '@types/nlcst': 2.0.3 + '@types/unist': 3.0.3 + nlcst-to-string: 4.0.0 + unist-util-modify-children: 4.0.0 + unist-util-visit-children: 3.0.0 + vfile: 6.0.3 + parse-ms@4.0.0: {} parse-path@7.1.0: @@ -23226,6 +23998,10 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.2 + path-to-regexp@6.1.0: {} + + path-to-regexp@6.3.0: {} + path-to-regexp@8.3.0: {} path-type@4.0.0: {} @@ -23287,6 +24063,8 @@ snapshots: dependencies: split2: 4.2.0 + piccolore@0.1.3: {} + picocolors@1.1.1: {} picomatch@2.3.1: {} @@ -23567,6 +24345,8 @@ snapshots: dependencies: parse-ms: 4.0.0 + prismjs@1.30.0: {} + process-nextick-args@2.0.1: {} process@0.11.10: {} @@ -24027,6 +24807,12 @@ snapshots: unist-util-visit-parents: 6.0.1 vfile: 6.0.3 + rehype-parse@9.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-from-html: 2.0.3 + unified: 11.0.5 + rehype-raw@7.0.0: dependencies: '@types/hast': 3.0.4 @@ -24041,6 +24827,19 @@ snapshots: transitivePeerDependencies: - supports-color + rehype-stringify@10.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.5 + unified: 11.0.5 + + rehype@13.0.2: + dependencies: + '@types/hast': 3.0.4 + rehype-parse: 9.0.1 + rehype-stringify: 10.0.1 + unified: 11.0.5 + remark-gfm@4.0.1: dependencies: '@types/mdast': 4.0.4 @@ -24085,6 +24884,13 @@ snapshots: unified: 11.0.5 vfile: 6.0.3 + remark-smartypants@3.0.2: + dependencies: + retext: 9.0.0 + retext-smartypants: 6.2.0 + unified: 11.0.5 + unist-util-visit: 5.0.0 + remark-stringify@11.0.0: dependencies: '@types/mdast': 4.0.4 @@ -24139,6 +24945,33 @@ snapshots: onetime: 7.0.0 signal-exit: 4.1.0 + restructure@3.0.2: {} + + retext-latin@4.0.0: + dependencies: + '@types/nlcst': 2.0.3 + parse-latin: 7.0.0 + unified: 11.0.5 + + retext-smartypants@6.2.0: + dependencies: + '@types/nlcst': 2.0.3 + nlcst-to-string: 4.0.0 + unist-util-visit: 5.0.0 + + retext-stringify@4.0.0: + dependencies: + '@types/nlcst': 2.0.3 + nlcst-to-string: 4.0.0 + unified: 11.0.5 + + retext@9.0.0: + dependencies: + '@types/nlcst': 2.0.3 + retext-latin: 4.0.0 + retext-stringify: 4.0.0 + unified: 11.0.5 + retry@0.12.0: {} reusify@1.1.0: {} @@ -24332,6 +25165,8 @@ snapshots: transitivePeerDependencies: - supports-color + server-destroy@1.0.1: {} + set-cookie-parser@2.7.2: {} setprototypeof@1.2.0: {} @@ -24474,6 +25309,8 @@ snapshots: smob@1.5.0: {} + smol-toml@1.5.2: {} + sonner@2.0.7(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: react: 19.1.0 @@ -24878,6 +25715,8 @@ snapshots: tiktok-video-element@0.1.1: {} + tiny-inflate@1.0.3: {} + tiny-invariant@1.3.3: {} tinybench@2.9.0: {} @@ -24958,7 +25797,7 @@ snapshots: tsx@4.20.6: dependencies: - esbuild: 0.25.11 + esbuild: 0.25.12 get-tsconfig: 4.12.0 optionalDependencies: fsevents: 2.3.3 @@ -25104,6 +25943,16 @@ snapshots: dependencies: hookable: 5.5.3 + unicode-properties@1.4.1: + dependencies: + base64-js: 1.5.1 + unicode-trie: 2.0.0 + + unicode-trie@2.0.0: + dependencies: + pako: 0.2.9 + tiny-inflate: 1.0.3 + unicorn-magic@0.1.0: {} unicorn-magic@0.3.0: {} @@ -25118,6 +25967,12 @@ snapshots: trough: 2.2.0 vfile: 6.0.3 + unifont@0.6.0: + dependencies: + css-tree: 3.1.0 + ofetch: 1.5.1 + ohash: 2.0.11 + unimport@5.5.0: dependencies: acorn: 8.15.0 @@ -25144,6 +25999,11 @@ snapshots: dependencies: '@types/unist': 3.0.3 + unist-util-modify-children@4.0.0: + dependencies: + '@types/unist': 3.0.3 + array-iterate: 2.0.1 + unist-util-position-from-estree@2.0.0: dependencies: '@types/unist': 3.0.3 @@ -25161,11 +26021,20 @@ snapshots: dependencies: '@types/unist': 3.0.3 + unist-util-visit-children@3.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-visit-parents@6.0.1: dependencies: '@types/unist': 3.0.3 unist-util-is: 6.0.0 + unist-util-visit-parents@6.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.0 + unist-util-visit@5.0.0: dependencies: '@types/unist': 3.0.3 @@ -25266,6 +26135,22 @@ snapshots: db0: 0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)) ioredis: 5.8.2 + unstorage@1.17.3(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2): + dependencies: + anymatch: 3.1.3 + chokidar: 4.0.3 + destr: 2.0.5 + h3: 1.15.4 + lru-cache: 10.4.3 + node-fetch-native: 1.6.7 + ofetch: 1.5.1 + ufo: 1.6.1 + optionalDependencies: + '@netlify/blobs': 9.1.2 + '@vercel/functions': 3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0) + db0: 0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)) + ioredis: 5.8.2 + unstorage@2.0.0-alpha.4(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(chokidar@4.0.3)(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(lru-cache@11.2.2)(ofetch@2.0.0-alpha.3): optionalDependencies: '@netlify/blobs': 9.1.2 @@ -25539,6 +26424,23 @@ snapshots: vite: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vue: 3.5.22(typescript@5.9.3) + vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): + dependencies: + esbuild: 0.25.12 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.53.3 + tinyglobby: 0.2.14 + optionalDependencies: + '@types/node': 24.6.2 + fsevents: 2.3.3 + jiti: 2.6.1 + lightningcss: 1.30.1 + terser: 5.44.0 + tsx: 4.20.6 + yaml: 2.8.1 + vite@7.1.11(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): dependencies: esbuild: 0.25.11 @@ -25590,6 +26492,10 @@ snapshots: tsx: 4.20.6 yaml: 2.8.1 + vitefu@1.1.1(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): + optionalDependencies: + vite: 6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vitefu@1.1.1(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): optionalDependencies: vite: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) @@ -25755,6 +26661,8 @@ snapshots: tr46: 0.0.3 webidl-conversions: 3.0.1 + which-pm-runs@1.1.0: {} + which@2.0.2: dependencies: isexe: 2.0.0 @@ -25850,6 +26758,8 @@ snapshots: xtend@4.0.2: {} + xxhash-wasm@1.1.0: {} + y18n@5.0.8: {} yallist@3.1.1: {} @@ -25882,6 +26792,10 @@ snapshots: yocto-queue@1.2.1: {} + yocto-spinner@0.2.3: + dependencies: + yoctocolors: 2.1.2 + yoctocolors@2.1.2: {} youch-core@0.3.3: @@ -25915,6 +26829,15 @@ snapshots: compress-commons: 6.0.2 readable-stream: 4.7.0 + zod-to-json-schema@3.25.0(zod@3.25.76): + dependencies: + zod: 3.25.76 + + zod-to-ts@1.2.0(typescript@5.9.3)(zod@3.25.76): + dependencies: + typescript: 5.9.3 + zod: 3.25.76 + zod@3.25.76: {} zod@4.1.11: {} diff --git a/workbench/astro/astro.config.mjs b/workbench/astro/astro.config.mjs index 25c89c6d9..4107d7e52 100644 --- a/workbench/astro/astro.config.mjs +++ b/workbench/astro/astro.config.mjs @@ -1,8 +1,17 @@ -// @ts-check import { defineConfig } from 'astro/config'; import { workflowPlugin } from 'workflow/astro'; +import node from '@astrojs/node'; +import vercel from '@astrojs/vercel'; + +// Node adapter needed for ci tests +const adapter = process.env.VERCEL_DEPLOYMENT_ID + ? vercel() + : node({ + mode: 'standalone', + }); // https://astro.build/config export default defineConfig({ vite: { plugins: [workflowPlugin()] }, + adapter: adapter, }); diff --git a/workbench/astro/package.json b/workbench/astro/package.json index 39958fa42..daf3e2865 100644 --- a/workbench/astro/package.json +++ b/workbench/astro/package.json @@ -12,6 +12,8 @@ "astro": "astro" }, "dependencies": { + "@astrojs/node": "9.5.0", + "@astrojs/vercel": "^9.0.0", "astro": "^5.15.6", "nitro": "catalog:", "workflow": "workspace:*" From c2c7aa8203c1ea76d63e3157795ce733edb3b355 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 10:45:44 -0800 Subject: [PATCH 10/61] revert sveltekit builder change --- packages/sveltekit/src/plugin.ts | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/packages/sveltekit/src/plugin.ts b/packages/sveltekit/src/plugin.ts index b9dc13d19..0041bddee 100644 --- a/packages/sveltekit/src/plugin.ts +++ b/packages/sveltekit/src/plugin.ts @@ -4,15 +4,7 @@ import { resolveModulePath } from 'exsolve'; import type { HotUpdateOptions, Plugin } from 'vite'; import { SvelteKitBuilder } from './builder.js'; -export interface WorkflowPluginOptions { - /** - * Directories to scan for workflow files. - * If not specified, defaults to ['workflows', 'src/workflows', 'routes', 'src/routes'] - */ - dirs?: string[]; -} - -export function workflowPlugin(options?: WorkflowPluginOptions): Plugin { +export function workflowPlugin(): Plugin { let builder: SvelteKitBuilder; return { @@ -97,9 +89,7 @@ export function workflowPlugin(options?: WorkflowPluginOptions): Plugin { }, configResolved() { - builder = new SvelteKitBuilder({ - dirs: options?.dirs, - }); + builder = new SvelteKitBuilder(); }, // TODO: Move this to @workflow/vite or something since this is vite specific From bfedace8a2d9cc58c948ebb963ccfa8a25053498 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 10:47:33 -0800 Subject: [PATCH 11/61] chore: cleanup astro stuff --- workbench/astro/.astro/content-assets.mjs | 1 - workbench/astro/.astro/content-modules.mjs | 1 - workbench/astro/.astro/content.d.ts | 199 - workbench/astro/.astro/data-store.json | 1 - workbench/astro/.astro/settings.json | 5 - workbench/astro/.astro/types.d.ts | 1 - workbench/astro/dist/client/favicon.svg | 9 - workbench/astro/dist/client/index.html | 1 - .../dist/server/_@astrojs-ssr-adapter.mjs | 1 - .../astro/dist/server/_noop-middleware.mjs | 3 - .../dist/server/chunks/99_e2e_DTaFFPMr.mjs | 117 - .../chunks/_@astrojs-ssr-adapter_9__r_ZjJ.mjs | 10521 ---- .../chunks/_commonjsHelpers_BFTU3MAI.mjs | 7 - .../astro-designed-error-pages_pFA87nEA.mjs | 364 - .../server/chunks/astro/server_DhWKww_t.mjs | 2766 - .../dist/server/chunks/fs-lite_COtHaKzy.mjs | 157 - .../dist/server/chunks/index_DqQ8k47W.mjs | 2319 - .../dist/server/chunks/index_ePTMDSOu.mjs | 42973 ---------------- .../dist/server/chunks/node_C2n6Z2oQ.mjs | 1669 - .../dist/server/chunks/remote_OOD9OFqU.mjs | 188 - .../server/chunks/resume-hook_BHshEMMl.mjs | 181 - .../dist/server/chunks/runtime_CxdH0OC2.mjs | 2039 - .../dist/server/chunks/sharp_CR567j69.mjs | 99 - .../server/chunks/token-util_8GTOk-OQ.mjs | 260 - .../server/chunks/token-util_D6r3xWR2.mjs | 30 - .../dist/server/chunks/token_CrOFk7pc.mjs | 88 - workbench/astro/dist/server/entry.mjs | 51 - .../astro/dist/server/manifest_Dl93wae-.mjs | 101 - .../astro/dist/server/noop-entrypoint.mjs | 3 - .../.well-known/workflow/v1/flow.astro.mjs | 27439 ---------- .../.well-known/workflow/v1/step.astro.mjs | 7609 --- .../workflow/v1/webhook/_token_.astro.mjs | 67 - .../astro/dist/server/pages/_image.astro.mjs | 2 - .../dist/server/pages/api/hook.astro.mjs | 34 - .../pages/api/test-direct-step-call.astro.mjs | 22 - .../dist/server/pages/api/trigger.astro.mjs | 341 - .../astro/dist/server/pages/index.astro.mjs | 1 - workbench/astro/dist/server/renderers.mjs | 3 - 38 files changed, 99673 deletions(-) delete mode 100644 workbench/astro/.astro/content-assets.mjs delete mode 100644 workbench/astro/.astro/content-modules.mjs delete mode 100644 workbench/astro/.astro/content.d.ts delete mode 100644 workbench/astro/.astro/data-store.json delete mode 100644 workbench/astro/.astro/settings.json delete mode 100644 workbench/astro/.astro/types.d.ts delete mode 100644 workbench/astro/dist/client/favicon.svg delete mode 100644 workbench/astro/dist/client/index.html delete mode 100644 workbench/astro/dist/server/_@astrojs-ssr-adapter.mjs delete mode 100644 workbench/astro/dist/server/_noop-middleware.mjs delete mode 100644 workbench/astro/dist/server/chunks/99_e2e_DTaFFPMr.mjs delete mode 100644 workbench/astro/dist/server/chunks/_@astrojs-ssr-adapter_9__r_ZjJ.mjs delete mode 100644 workbench/astro/dist/server/chunks/_commonjsHelpers_BFTU3MAI.mjs delete mode 100644 workbench/astro/dist/server/chunks/astro-designed-error-pages_pFA87nEA.mjs delete mode 100644 workbench/astro/dist/server/chunks/astro/server_DhWKww_t.mjs delete mode 100644 workbench/astro/dist/server/chunks/fs-lite_COtHaKzy.mjs delete mode 100644 workbench/astro/dist/server/chunks/index_DqQ8k47W.mjs delete mode 100644 workbench/astro/dist/server/chunks/index_ePTMDSOu.mjs delete mode 100644 workbench/astro/dist/server/chunks/node_C2n6Z2oQ.mjs delete mode 100644 workbench/astro/dist/server/chunks/remote_OOD9OFqU.mjs delete mode 100644 workbench/astro/dist/server/chunks/resume-hook_BHshEMMl.mjs delete mode 100644 workbench/astro/dist/server/chunks/runtime_CxdH0OC2.mjs delete mode 100644 workbench/astro/dist/server/chunks/sharp_CR567j69.mjs delete mode 100644 workbench/astro/dist/server/chunks/token-util_8GTOk-OQ.mjs delete mode 100644 workbench/astro/dist/server/chunks/token-util_D6r3xWR2.mjs delete mode 100644 workbench/astro/dist/server/chunks/token_CrOFk7pc.mjs delete mode 100644 workbench/astro/dist/server/entry.mjs delete mode 100644 workbench/astro/dist/server/manifest_Dl93wae-.mjs delete mode 100644 workbench/astro/dist/server/noop-entrypoint.mjs delete mode 100644 workbench/astro/dist/server/pages/.well-known/workflow/v1/flow.astro.mjs delete mode 100644 workbench/astro/dist/server/pages/.well-known/workflow/v1/step.astro.mjs delete mode 100644 workbench/astro/dist/server/pages/.well-known/workflow/v1/webhook/_token_.astro.mjs delete mode 100644 workbench/astro/dist/server/pages/_image.astro.mjs delete mode 100644 workbench/astro/dist/server/pages/api/hook.astro.mjs delete mode 100644 workbench/astro/dist/server/pages/api/test-direct-step-call.astro.mjs delete mode 100644 workbench/astro/dist/server/pages/api/trigger.astro.mjs delete mode 100644 workbench/astro/dist/server/pages/index.astro.mjs delete mode 100644 workbench/astro/dist/server/renderers.mjs diff --git a/workbench/astro/.astro/content-assets.mjs b/workbench/astro/.astro/content-assets.mjs deleted file mode 100644 index 2b8b8234b..000000000 --- a/workbench/astro/.astro/content-assets.mjs +++ /dev/null @@ -1 +0,0 @@ -export default new Map(); \ No newline at end of file diff --git a/workbench/astro/.astro/content-modules.mjs b/workbench/astro/.astro/content-modules.mjs deleted file mode 100644 index 2b8b8234b..000000000 --- a/workbench/astro/.astro/content-modules.mjs +++ /dev/null @@ -1 +0,0 @@ -export default new Map(); \ No newline at end of file diff --git a/workbench/astro/.astro/content.d.ts b/workbench/astro/.astro/content.d.ts deleted file mode 100644 index c0082cc81..000000000 --- a/workbench/astro/.astro/content.d.ts +++ /dev/null @@ -1,199 +0,0 @@ -declare module 'astro:content' { - export interface RenderResult { - Content: import('astro/runtime/server/index.js').AstroComponentFactory; - headings: import('astro').MarkdownHeading[]; - remarkPluginFrontmatter: Record; - } - interface Render { - '.md': Promise; - } - - export interface RenderedContent { - html: string; - metadata?: { - imagePaths: Array; - [key: string]: unknown; - }; - } -} - -declare module 'astro:content' { - type Flatten = T extends { [K: string]: infer U } ? U : never; - - export type CollectionKey = keyof AnyEntryMap; - export type CollectionEntry = Flatten; - - export type ContentCollectionKey = keyof ContentEntryMap; - export type DataCollectionKey = keyof DataEntryMap; - - type AllValuesOf = T extends any ? T[keyof T] : never; - type ValidContentEntrySlug = AllValuesOf< - ContentEntryMap[C] - >['slug']; - - export type ReferenceDataEntry< - C extends CollectionKey, - E extends keyof DataEntryMap[C] = string, - > = { - collection: C; - id: E; - }; - export type ReferenceContentEntry< - C extends keyof ContentEntryMap, - E extends ValidContentEntrySlug | (string & {}) = string, - > = { - collection: C; - slug: E; - }; - export type ReferenceLiveEntry = { - collection: C; - id: string; - }; - - /** @deprecated Use `getEntry` instead. */ - export function getEntryBySlug< - C extends keyof ContentEntryMap, - E extends ValidContentEntrySlug | (string & {}), - >( - collection: C, - // Note that this has to accept a regular string too, for SSR - entrySlug: E, - ): E extends ValidContentEntrySlug - ? Promise> - : Promise | undefined>; - - /** @deprecated Use `getEntry` instead. */ - export function getDataEntryById( - collection: C, - entryId: E, - ): Promise>; - - export function getCollection>( - collection: C, - filter?: (entry: CollectionEntry) => entry is E, - ): Promise; - export function getCollection( - collection: C, - filter?: (entry: CollectionEntry) => unknown, - ): Promise[]>; - - export function getLiveCollection( - collection: C, - filter?: LiveLoaderCollectionFilterType, - ): Promise< - import('astro').LiveDataCollectionResult, LiveLoaderErrorType> - >; - - export function getEntry< - C extends keyof ContentEntryMap, - E extends ValidContentEntrySlug | (string & {}), - >( - entry: ReferenceContentEntry, - ): E extends ValidContentEntrySlug - ? Promise> - : Promise | undefined>; - export function getEntry< - C extends keyof DataEntryMap, - E extends keyof DataEntryMap[C] | (string & {}), - >( - entry: ReferenceDataEntry, - ): E extends keyof DataEntryMap[C] - ? Promise - : Promise | undefined>; - export function getEntry< - C extends keyof ContentEntryMap, - E extends ValidContentEntrySlug | (string & {}), - >( - collection: C, - slug: E, - ): E extends ValidContentEntrySlug - ? Promise> - : Promise | undefined>; - export function getEntry< - C extends keyof DataEntryMap, - E extends keyof DataEntryMap[C] | (string & {}), - >( - collection: C, - id: E, - ): E extends keyof DataEntryMap[C] - ? string extends keyof DataEntryMap[C] - ? Promise | undefined - : Promise - : Promise | undefined>; - export function getLiveEntry( - collection: C, - filter: string | LiveLoaderEntryFilterType, - ): Promise, LiveLoaderErrorType>>; - - /** Resolve an array of entry references from the same collection */ - export function getEntries( - entries: ReferenceContentEntry>[], - ): Promise[]>; - export function getEntries( - entries: ReferenceDataEntry[], - ): Promise[]>; - - export function render( - entry: AnyEntryMap[C][string], - ): Promise; - - export function reference( - collection: C, - ): import('astro/zod').ZodEffects< - import('astro/zod').ZodString, - C extends keyof ContentEntryMap - ? ReferenceContentEntry> - : ReferenceDataEntry - >; - // Allow generic `string` to avoid excessive type errors in the config - // if `dev` is not running to update as you edit. - // Invalid collection names will be caught at build time. - export function reference( - collection: C, - ): import('astro/zod').ZodEffects; - - type ReturnTypeOrOriginal = T extends (...args: any[]) => infer R ? R : T; - type InferEntrySchema = import('astro/zod').infer< - ReturnTypeOrOriginal['schema']> - >; - - type ContentEntryMap = { - - }; - - type DataEntryMap = { - - }; - - type AnyEntryMap = ContentEntryMap & DataEntryMap; - - type ExtractLoaderTypes = T extends import('astro/loaders').LiveLoader< - infer TData, - infer TEntryFilter, - infer TCollectionFilter, - infer TError - > - ? { data: TData; entryFilter: TEntryFilter; collectionFilter: TCollectionFilter; error: TError } - : { data: never; entryFilter: never; collectionFilter: never; error: never }; - type ExtractDataType = ExtractLoaderTypes['data']; - type ExtractEntryFilterType = ExtractLoaderTypes['entryFilter']; - type ExtractCollectionFilterType = ExtractLoaderTypes['collectionFilter']; - type ExtractErrorType = ExtractLoaderTypes['error']; - - type LiveLoaderDataType = - LiveContentConfig['collections'][C]['schema'] extends undefined - ? ExtractDataType - : import('astro/zod').infer< - Exclude - >; - type LiveLoaderEntryFilterType = - ExtractEntryFilterType; - type LiveLoaderCollectionFilterType = - ExtractCollectionFilterType; - type LiveLoaderErrorType = ExtractErrorType< - LiveContentConfig['collections'][C]['loader'] - >; - - export type ContentConfig = typeof import("../src/content.config.mjs"); - export type LiveContentConfig = never; -} diff --git a/workbench/astro/.astro/data-store.json b/workbench/astro/.astro/data-store.json deleted file mode 100644 index 44b17ba6a..000000000 --- a/workbench/astro/.astro/data-store.json +++ /dev/null @@ -1 +0,0 @@ -[["Map",1,2],"meta::meta",["Map",3,4,5,6],"astro-version","5.15.6","astro-config-digest","{\"root\":{},\"srcDir\":{},\"publicDir\":{},\"outDir\":{},\"cacheDir\":{},\"compressHTML\":true,\"base\":\"/\",\"trailingSlash\":\"ignore\",\"output\":\"static\",\"scopedStyleStrategy\":\"attribute\",\"build\":{\"format\":\"directory\",\"client\":{},\"server\":{},\"assets\":\"_astro\",\"serverEntry\":\"entry.mjs\",\"redirects\":false,\"inlineStylesheets\":\"auto\",\"concurrency\":1},\"server\":{\"open\":false,\"host\":false,\"port\":4321,\"streaming\":true,\"allowedHosts\":[]},\"redirects\":{},\"image\":{\"endpoint\":{\"route\":\"/_image\",\"entrypoint\":\"astro/assets/endpoint/dev\"},\"service\":{\"entrypoint\":\"astro/assets/services/sharp\",\"config\":{}},\"domains\":[],\"remotePatterns\":[],\"responsiveStyles\":false},\"devToolbar\":{\"enabled\":true},\"markdown\":{\"syntaxHighlight\":{\"type\":\"shiki\",\"excludeLangs\":[\"math\"]},\"shikiConfig\":{\"langs\":[],\"langAlias\":{},\"theme\":\"github-dark\",\"themes\":{},\"wrap\":false,\"transformers\":[]},\"remarkPlugins\":[],\"rehypePlugins\":[],\"remarkRehype\":{},\"gfm\":true,\"smartypants\":true},\"security\":{\"checkOrigin\":true,\"allowedDomains\":[]},\"env\":{\"schema\":{},\"validateSecrets\":false},\"experimental\":{\"clientPrerender\":false,\"contentIntellisense\":false,\"headingIdCompat\":false,\"preserveScriptOrder\":false,\"liveContentCollections\":false,\"csp\":false,\"staticImportMetaEnv\":false,\"chromeDevtoolsWorkspace\":false,\"failOnPrerenderConflict\":false},\"legacy\":{\"collections\":false},\"session\":{\"driver\":\"fs-lite\",\"options\":{\"base\":\"/Users/adrianlam/GitHub/workflow/workbench/astro/node_modules/.astro/sessions\"}}}"] \ No newline at end of file diff --git a/workbench/astro/.astro/settings.json b/workbench/astro/.astro/settings.json deleted file mode 100644 index 6b79318ed..000000000 --- a/workbench/astro/.astro/settings.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "_variables": { - "lastUpdateCheck": 1763142538065 - } -} \ No newline at end of file diff --git a/workbench/astro/.astro/types.d.ts b/workbench/astro/.astro/types.d.ts deleted file mode 100644 index f964fe0cf..000000000 --- a/workbench/astro/.astro/types.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// diff --git a/workbench/astro/dist/client/favicon.svg b/workbench/astro/dist/client/favicon.svg deleted file mode 100644 index f157bd1c5..000000000 --- a/workbench/astro/dist/client/favicon.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - diff --git a/workbench/astro/dist/client/index.html b/workbench/astro/dist/client/index.html deleted file mode 100644 index 0e372499c..000000000 --- a/workbench/astro/dist/client/index.html +++ /dev/null @@ -1 +0,0 @@ - Astro

Astro

\ No newline at end of file diff --git a/workbench/astro/dist/server/_@astrojs-ssr-adapter.mjs b/workbench/astro/dist/server/_@astrojs-ssr-adapter.mjs deleted file mode 100644 index ccb0b6fbf..000000000 --- a/workbench/astro/dist/server/_@astrojs-ssr-adapter.mjs +++ /dev/null @@ -1 +0,0 @@ -export { c as createExports, a as start } from './chunks/_@astrojs-ssr-adapter_9__r_ZjJ.mjs'; diff --git a/workbench/astro/dist/server/_noop-middleware.mjs b/workbench/astro/dist/server/_noop-middleware.mjs deleted file mode 100644 index 84424b01b..000000000 --- a/workbench/astro/dist/server/_noop-middleware.mjs +++ /dev/null @@ -1,3 +0,0 @@ -const onRequest = (_, next) => next(); - -export { onRequest }; diff --git a/workbench/astro/dist/server/chunks/99_e2e_DTaFFPMr.mjs b/workbench/astro/dist/server/chunks/99_e2e_DTaFFPMr.mjs deleted file mode 100644 index 8f79127c4..000000000 --- a/workbench/astro/dist/server/chunks/99_e2e_DTaFFPMr.mjs +++ /dev/null @@ -1,117 +0,0 @@ -async function add(a, b) { - return a + b; -} -async function addTenWorkflow(input) { - throw new Error("You attempted to execute workflow addTenWorkflow function directly. To start a workflow, use start(addTenWorkflow) from workflow/api"); -} -addTenWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//addTenWorkflow"; -async function nestedErrorWorkflow() { - throw new Error("You attempted to execute workflow nestedErrorWorkflow function directly. To start a workflow, use start(nestedErrorWorkflow) from workflow/api"); -} -nestedErrorWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//nestedErrorWorkflow"; -async function promiseAllWorkflow() { - throw new Error("You attempted to execute workflow promiseAllWorkflow function directly. To start a workflow, use start(promiseAllWorkflow) from workflow/api"); -} -promiseAllWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//promiseAllWorkflow"; -async function promiseRaceWorkflow() { - throw new Error("You attempted to execute workflow promiseRaceWorkflow function directly. To start a workflow, use start(promiseRaceWorkflow) from workflow/api"); -} -promiseRaceWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//promiseRaceWorkflow"; -async function promiseAnyWorkflow() { - throw new Error("You attempted to execute workflow promiseAnyWorkflow function directly. To start a workflow, use start(promiseAnyWorkflow) from workflow/api"); -} -promiseAnyWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//promiseAnyWorkflow"; -async function readableStreamWorkflow() { - throw new Error("You attempted to execute workflow readableStreamWorkflow function directly. To start a workflow, use start(readableStreamWorkflow) from workflow/api"); -} -readableStreamWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//readableStreamWorkflow"; -async function hookWorkflow(token, customData) { - throw new Error("You attempted to execute workflow hookWorkflow function directly. To start a workflow, use start(hookWorkflow) from workflow/api"); -} -hookWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//hookWorkflow"; -async function webhookWorkflow(token, token2, token3) { - throw new Error("You attempted to execute workflow webhookWorkflow function directly. To start a workflow, use start(webhookWorkflow) from workflow/api"); -} -webhookWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//webhookWorkflow"; -async function sleepingWorkflow() { - throw new Error("You attempted to execute workflow sleepingWorkflow function directly. To start a workflow, use start(sleepingWorkflow) from workflow/api"); -} -sleepingWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//sleepingWorkflow"; -async function nullByteWorkflow() { - throw new Error("You attempted to execute workflow nullByteWorkflow function directly. To start a workflow, use start(nullByteWorkflow) from workflow/api"); -} -nullByteWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//nullByteWorkflow"; -async function workflowAndStepMetadataWorkflow() { - throw new Error("You attempted to execute workflow workflowAndStepMetadataWorkflow function directly. To start a workflow, use start(workflowAndStepMetadataWorkflow) from workflow/api"); -} -workflowAndStepMetadataWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//workflowAndStepMetadataWorkflow"; -async function outputStreamWorkflow() { - throw new Error("You attempted to execute workflow outputStreamWorkflow function directly. To start a workflow, use start(outputStreamWorkflow) from workflow/api"); -} -outputStreamWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//outputStreamWorkflow"; -async function outputStreamInsideStepWorkflow() { - throw new Error("You attempted to execute workflow outputStreamInsideStepWorkflow function directly. To start a workflow, use start(outputStreamInsideStepWorkflow) from workflow/api"); -} -outputStreamInsideStepWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//outputStreamInsideStepWorkflow"; -async function fetchWorkflow() { - throw new Error("You attempted to execute workflow fetchWorkflow function directly. To start a workflow, use start(fetchWorkflow) from workflow/api"); -} -fetchWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//fetchWorkflow"; -async function promiseRaceStressTestDelayStep(dur, resp) { - console.log(`sleep`, resp, `/`, dur); - await new Promise((resolve)=>setTimeout(resolve, dur)); - console.log(resp, `done`); - return resp; -} -async function promiseRaceStressTestWorkflow() { - throw new Error("You attempted to execute workflow promiseRaceStressTestWorkflow function directly. To start a workflow, use start(promiseRaceStressTestWorkflow) from workflow/api"); -} -promiseRaceStressTestWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//promiseRaceStressTestWorkflow"; -async function retryAttemptCounterWorkflow() { - throw new Error("You attempted to execute workflow retryAttemptCounterWorkflow function directly. To start a workflow, use start(retryAttemptCounterWorkflow) from workflow/api"); -} -retryAttemptCounterWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//retryAttemptCounterWorkflow"; -async function crossFileErrorWorkflow() { - throw new Error("You attempted to execute workflow crossFileErrorWorkflow function directly. To start a workflow, use start(crossFileErrorWorkflow) from workflow/api"); -} -crossFileErrorWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//crossFileErrorWorkflow"; -async function retryableAndFatalErrorWorkflow() { - throw new Error("You attempted to execute workflow retryableAndFatalErrorWorkflow function directly. To start a workflow, use start(retryableAndFatalErrorWorkflow) from workflow/api"); -} -retryableAndFatalErrorWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//retryableAndFatalErrorWorkflow"; -async function hookCleanupTestWorkflow(token, customData) { - throw new Error("You attempted to execute workflow hookCleanupTestWorkflow function directly. To start a workflow, use start(hookCleanupTestWorkflow) from workflow/api"); -} -hookCleanupTestWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//hookCleanupTestWorkflow"; -async function stepFunctionPassingWorkflow() { - throw new Error("You attempted to execute workflow stepFunctionPassingWorkflow function directly. To start a workflow, use start(stepFunctionPassingWorkflow) from workflow/api"); -} -stepFunctionPassingWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//stepFunctionPassingWorkflow"; - -const workflow_99_e2e = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - add, - addTenWorkflow, - crossFileErrorWorkflow, - fetchWorkflow, - hookCleanupTestWorkflow, - hookWorkflow, - nestedErrorWorkflow, - nullByteWorkflow, - outputStreamInsideStepWorkflow, - outputStreamWorkflow, - promiseAllWorkflow, - promiseAnyWorkflow, - promiseRaceStressTestDelayStep, - promiseRaceStressTestWorkflow, - promiseRaceWorkflow, - readableStreamWorkflow, - retryAttemptCounterWorkflow, - retryableAndFatalErrorWorkflow, - sleepingWorkflow, - stepFunctionPassingWorkflow, - webhookWorkflow, - workflowAndStepMetadataWorkflow -}, Symbol.toStringTag, { value: 'Module' })); - -export { add as a, workflow_99_e2e as w }; diff --git a/workbench/astro/dist/server/chunks/_@astrojs-ssr-adapter_9__r_ZjJ.mjs b/workbench/astro/dist/server/chunks/_@astrojs-ssr-adapter_9__r_ZjJ.mjs deleted file mode 100644 index b880e3b9e..000000000 --- a/workbench/astro/dist/server/chunks/_@astrojs-ssr-adapter_9__r_ZjJ.mjs +++ /dev/null @@ -1,10521 +0,0 @@ -import { n as decryptString, o as createSlotValueFromString, p as isAstroComponentFactory, q as renderComponent, r as renderTemplate, R as ROUTE_TYPE_HEADER, v as REROUTE_DIRECTIVE_HEADER, A as AstroError, w as i18nNoLocaleFoundInPath, x as ResponseSentError, y as ActionNotFoundError, z as MiddlewareNoDataOrNextCalled, B as MiddlewareNotAResponse, C as originPathnameSymbol, D as RewriteWithBodyUsed, G as GetStaticPathsRequired, H as InvalidGetStaticPathsReturn, J as InvalidGetStaticPathsEntry, K as GetStaticPathsExpectedParams, O as GetStaticPathsInvalidRouteParam, P as PageNumberParamNotFound, Q as DEFAULT_404_COMPONENT, S as NoMatchingStaticPathFound, T as PrerenderDynamicEndpointPathCollide, V as ReservedSlotName, W as renderSlotToString, X as renderJSX, Y as chunkToString, Z as isRenderInstruction, _ as ForbiddenRewrite, $ as SessionStorageInitError, a0 as SessionStorageSaveError, a1 as ASTRO_VERSION, a2 as CspNotEnabled, a3 as LocalsReassigned, a4 as generateCspDigest, a5 as PrerenderClientAddressNotAvailable, a6 as clientAddressSymbol, a7 as ClientAddressNotAvailable, a8 as StaticClientAddressNotAvailable, a9 as AstroResponseHeadersReassigned, aa as responseSentSymbol$1, ab as renderPage, ac as REWRITE_DIRECTIVE_HEADER_KEY, ad as REWRITE_DIRECTIVE_HEADER_VALUE, ae as renderEndpoint, af as LocalsNotAnObject, ag as REROUTABLE_STATUS_CODES, ah as nodeRequestAbortControllerCleanupSymbol } from './astro/server_DhWKww_t.mjs'; -import 'clsx'; -import { serialize, parse } from 'cookie'; -import { A as ActionError, d as deserializeActionResult, s as serializeActionResult, a as ACTION_RPC_ROUTE_PATTERN, b as ACTION_QUERY_PARAMS, g as getActionQueryString, D as DEFAULT_404_ROUTE, c as default404Instance, N as NOOP_MIDDLEWARE_FN, e as ensure404Route } from './astro-designed-error-pages_pFA87nEA.mjs'; -import 'es-module-lexer'; -import require$$0$3 from 'node:buffer'; -import crypto$1 from 'node:crypto'; -import fs, { existsSync, readFileSync } from 'node:fs'; -import { Http2ServerResponse } from 'node:http2'; -import { c as appendForwardSlash$1, j as joinPaths, f as fileExtension, s as slash, p as prependForwardSlash$1, d as removeTrailingForwardSlash, t as trimSlashes, m as matchPattern, e as isInternalPath, g as collapseDuplicateTrailingSlashes, h as hasFileExtension } from './remote_OOD9OFqU.mjs'; -import colors from 'picocolors'; -import { unflatten as unflatten$1, stringify as stringify$1 } from 'devalue'; -import { createStorage, builtinDrivers } from 'unstorage'; -import { AsyncLocalStorage } from 'node:async_hooks'; -import require$$2 from 'node:http'; -import https from 'node:https'; -import { g as getDefaultExportFromCjs } from './_commonjsHelpers_BFTU3MAI.mjs'; -import os from 'node:os'; -import path from 'node:path'; -import url from 'node:url'; -import require$$0$4 from 'path'; -import debug$1 from 'debug'; -import require$$0$6 from 'crypto'; -import require$$0$5 from 'fs'; -import ms from 'ms'; -import require$$13 from 'stream'; -import require$$14 from 'util'; - -function shouldAppendForwardSlash(trailingSlash, buildFormat) { - switch (trailingSlash) { - case "always": - return true; - case "never": - return false; - case "ignore": { - switch (buildFormat) { - case "directory": - return true; - case "preserve": - case "file": - return false; - } - } - } -} - -function redirectIsExternal(redirect) { - if (typeof redirect === "string") { - return redirect.startsWith("http://") || redirect.startsWith("https://"); - } else { - return redirect.destination.startsWith("http://") || redirect.destination.startsWith("https://"); - } -} -async function renderRedirect(renderContext) { - const { - request: { method }, - routeData - } = renderContext; - const { redirect, redirectRoute } = routeData; - const status = redirectRoute && typeof redirect === "object" ? redirect.status : method === "GET" ? 301 : 308; - const headers = { location: encodeURI(redirectRouteGenerate(renderContext)) }; - if (redirect && redirectIsExternal(redirect)) { - if (typeof redirect === "string") { - return Response.redirect(redirect, status); - } else { - return Response.redirect(redirect.destination, status); - } - } - return new Response(null, { status, headers }); -} -function redirectRouteGenerate(renderContext) { - const { - params, - routeData: { redirect, redirectRoute } - } = renderContext; - if (typeof redirectRoute !== "undefined") { - return redirectRoute?.generate(params) || redirectRoute?.pathname || "/"; - } else if (typeof redirect === "string") { - if (redirectIsExternal(redirect)) { - return redirect; - } else { - let target = redirect; - for (const param of Object.keys(params)) { - const paramValue = params[param]; - target = target.replace(`[${param}]`, paramValue).replace(`[...${param}]`, paramValue); - } - return target; - } - } else if (typeof redirect === "undefined") { - return "/"; - } - return redirect.destination; -} - -const SERVER_ISLAND_ROUTE = "/_server-islands/[name]"; -const SERVER_ISLAND_COMPONENT = "_server-islands.astro"; -const SERVER_ISLAND_BASE_PREFIX = "_server-islands"; -function badRequest(reason) { - return new Response(null, { - status: 400, - statusText: "Bad request: " + reason - }); -} -async function getRequestData(request) { - switch (request.method) { - case "GET": { - const url = new URL(request.url); - const params = url.searchParams; - if (!params.has("s") || !params.has("e") || !params.has("p")) { - return badRequest("Missing required query parameters."); - } - const rawSlots = params.get("s"); - try { - return { - componentExport: params.get("e"), - encryptedProps: params.get("p"), - slots: JSON.parse(rawSlots) - }; - } catch { - return badRequest("Invalid slots format."); - } - } - case "POST": { - try { - const raw = await request.text(); - const data = JSON.parse(raw); - return data; - } catch { - return badRequest("Request format is invalid."); - } - } - default: { - return new Response(null, { status: 405 }); - } - } -} -function createEndpoint(manifest) { - const page = async (result) => { - const params = result.params; - if (!params.name) { - return new Response(null, { - status: 400, - statusText: "Bad request" - }); - } - const componentId = params.name; - const data = await getRequestData(result.request); - if (data instanceof Response) { - return data; - } - const imp = manifest.serverIslandMap?.get(componentId); - if (!imp) { - return new Response(null, { - status: 404, - statusText: "Not found" - }); - } - const key = await manifest.key; - const encryptedProps = data.encryptedProps; - const propString = encryptedProps === "" ? "{}" : await decryptString(key, encryptedProps); - const props = JSON.parse(propString); - const componentModule = await imp(); - let Component = componentModule[data.componentExport]; - const slots = {}; - for (const prop in data.slots) { - slots[prop] = createSlotValueFromString(data.slots[prop]); - } - result.response.headers.set("X-Robots-Tag", "noindex"); - if (isAstroComponentFactory(Component)) { - const ServerIsland = Component; - Component = function(...args) { - return ServerIsland.apply(this, args); - }; - Object.assign(Component, ServerIsland); - Component.propagation = "self"; - } - return renderTemplate`${renderComponent(result, "Component", Component, props, slots)}`; - }; - page.isAstroComponentFactory = true; - const instance = { - default: page, - partial: true - }; - return instance; -} - -function matchRoute(pathname, manifest) { - return manifest.routes.find((route) => { - return route.pattern.test(pathname) || route.fallbackRoutes.some((fallbackRoute) => fallbackRoute.pattern.test(pathname)); - }); -} -const ROUTE404_RE = /^\/404\/?$/; -const ROUTE500_RE = /^\/500\/?$/; -function isRoute404(route) { - return ROUTE404_RE.test(route); -} -function isRoute500(route) { - return ROUTE500_RE.test(route); -} -function isRoute404or500(route) { - return isRoute404(route.route) || isRoute500(route.route); -} -function isRouteServerIsland(route) { - return route.component === SERVER_ISLAND_COMPONENT; -} -function isRequestServerIsland(request, base = "") { - const url = new URL(request.url); - const pathname = base === "/" ? url.pathname.slice(base.length) : url.pathname.slice(base.length + 1); - return pathname.startsWith(SERVER_ISLAND_BASE_PREFIX); -} -function requestIs404Or500(request, base = "") { - const url = new URL(request.url); - const pathname = url.pathname.slice(base.length); - return isRoute404(pathname) || isRoute500(pathname); -} -function isRouteExternalRedirect(route) { - return !!(route.type === "redirect" && route.redirect && redirectIsExternal(route.redirect)); -} - -function createI18nMiddleware(i18n, base, trailingSlash, format) { - if (!i18n) return (_, next) => next(); - const payload = { - ...i18n, - trailingSlash, - base, - format}; - const _redirectToDefaultLocale = redirectToDefaultLocale(payload); - const _noFoundForNonLocaleRoute = notFound(payload); - const _requestHasLocale = requestHasLocale(payload.locales); - const _redirectToFallback = redirectToFallback(payload); - const prefixAlways = (context, response) => { - const url = context.url; - if (url.pathname === base + "/" || url.pathname === base) { - return _redirectToDefaultLocale(context); - } else if (!_requestHasLocale(context)) { - return _noFoundForNonLocaleRoute(context, response); - } - return void 0; - }; - const prefixOtherLocales = (context, response) => { - let pathnameContainsDefaultLocale = false; - const url = context.url; - for (const segment of url.pathname.split("/")) { - if (normalizeTheLocale(segment) === normalizeTheLocale(i18n.defaultLocale)) { - pathnameContainsDefaultLocale = true; - break; - } - } - if (pathnameContainsDefaultLocale) { - const newLocation = url.pathname.replace(`/${i18n.defaultLocale}`, ""); - response.headers.set("Location", newLocation); - return _noFoundForNonLocaleRoute(context); - } - return void 0; - }; - return async (context, next) => { - const response = await next(); - const type = response.headers.get(ROUTE_TYPE_HEADER); - const isReroute = response.headers.get(REROUTE_DIRECTIVE_HEADER); - if (isReroute === "no" && typeof i18n.fallback === "undefined") { - return response; - } - if (type !== "page" && type !== "fallback") { - return response; - } - if (requestIs404Or500(context.request, base)) { - return response; - } - if (isRequestServerIsland(context.request, base)) { - return response; - } - const { currentLocale } = context; - switch (i18n.strategy) { - // NOTE: theoretically, we should never hit this code path - case "manual": { - return response; - } - case "domains-prefix-other-locales": { - if (localeHasntDomain(i18n, currentLocale)) { - const result = prefixOtherLocales(context, response); - if (result) { - return result; - } - } - break; - } - case "pathname-prefix-other-locales": { - const result = prefixOtherLocales(context, response); - if (result) { - return result; - } - break; - } - case "domains-prefix-always-no-redirect": { - if (localeHasntDomain(i18n, currentLocale)) { - const result = _noFoundForNonLocaleRoute(context, response); - if (result) { - return result; - } - } - break; - } - case "pathname-prefix-always-no-redirect": { - const result = _noFoundForNonLocaleRoute(context, response); - if (result) { - return result; - } - break; - } - case "pathname-prefix-always": { - const result = prefixAlways(context, response); - if (result) { - return result; - } - break; - } - case "domains-prefix-always": { - if (localeHasntDomain(i18n, currentLocale)) { - const result = prefixAlways(context, response); - if (result) { - return result; - } - } - break; - } - } - return _redirectToFallback(context, response); - }; -} -function localeHasntDomain(i18n, currentLocale) { - for (const domainLocale of Object.values(i18n.domainLookupTable)) { - if (domainLocale === currentLocale) { - return false; - } - } - return true; -} - -function requestHasLocale(locales) { - return function(context) { - return pathHasLocale(context.url.pathname, locales); - }; -} -function pathHasLocale(path, locales) { - const segments = path.split("/").map(normalizeThePath); - for (const segment of segments) { - for (const locale of locales) { - if (typeof locale === "string") { - if (normalizeTheLocale(segment) === normalizeTheLocale(locale)) { - return true; - } - } else if (segment === locale.path) { - return true; - } - } - } - return false; -} -function getPathByLocale(locale, locales) { - for (const loopLocale of locales) { - if (typeof loopLocale === "string") { - if (loopLocale === locale) { - return loopLocale; - } - } else { - for (const code of loopLocale.codes) { - if (code === locale) { - return loopLocale.path; - } - } - } - } - throw new AstroError(i18nNoLocaleFoundInPath); -} -function normalizeTheLocale(locale) { - return locale.replaceAll("_", "-").toLowerCase(); -} -function normalizeThePath(path) { - return path.endsWith(".html") ? path.slice(0, -5) : path; -} -function getAllCodes(locales) { - const result = []; - for (const loopLocale of locales) { - if (typeof loopLocale === "string") { - result.push(loopLocale); - } else { - result.push(...loopLocale.codes); - } - } - return result; -} -function redirectToDefaultLocale({ - trailingSlash, - format, - base, - defaultLocale -}) { - return function(context, statusCode) { - if (shouldAppendForwardSlash(trailingSlash, format)) { - return context.redirect(`${appendForwardSlash$1(joinPaths(base, defaultLocale))}`, statusCode); - } else { - return context.redirect(`${joinPaths(base, defaultLocale)}`, statusCode); - } - }; -} -function notFound({ base, locales, fallback }) { - return function(context, response) { - if (response?.headers.get(REROUTE_DIRECTIVE_HEADER) === "no" && typeof fallback === "undefined") { - return response; - } - const url = context.url; - const isRoot = url.pathname === base + "/" || url.pathname === base; - if (!(isRoot || pathHasLocale(url.pathname, locales))) { - if (response) { - response.headers.set(REROUTE_DIRECTIVE_HEADER, "no"); - return new Response(response.body, { - status: 404, - headers: response.headers - }); - } else { - return new Response(null, { - status: 404, - headers: { - [REROUTE_DIRECTIVE_HEADER]: "no" - } - }); - } - } - return void 0; - }; -} -function redirectToFallback({ - fallback, - locales, - defaultLocale, - strategy, - base, - fallbackType -}) { - return async function(context, response) { - if (response.status >= 300 && fallback) { - const fallbackKeys = fallback ? Object.keys(fallback) : []; - const segments = context.url.pathname.split("/"); - const urlLocale = segments.find((segment) => { - for (const locale of locales) { - if (typeof locale === "string") { - if (locale === segment) { - return true; - } - } else if (locale.path === segment) { - return true; - } - } - return false; - }); - if (urlLocale && fallbackKeys.includes(urlLocale)) { - const fallbackLocale = fallback[urlLocale]; - const pathFallbackLocale = getPathByLocale(fallbackLocale, locales); - let newPathname; - if (pathFallbackLocale === defaultLocale && strategy === "pathname-prefix-other-locales") { - if (context.url.pathname.includes(`${base}`)) { - newPathname = context.url.pathname.replace(`/${urlLocale}`, ``); - if (newPathname === "") { - newPathname = "/"; - } - } else { - newPathname = context.url.pathname.replace(`/${urlLocale}`, `/`); - } - } else { - newPathname = context.url.pathname.replace(`/${urlLocale}`, `/${pathFallbackLocale}`); - } - if (fallbackType === "rewrite") { - return await context.rewrite(newPathname + context.url.search); - } else { - return context.redirect(newPathname + context.url.search); - } - } - } - return response; - }; -} - -const DELETED_EXPIRATION = /* @__PURE__ */ new Date(0); -const DELETED_VALUE = "deleted"; -const responseSentSymbol = Symbol.for("astro.responseSent"); -const identity = (value) => value; -class AstroCookie { - constructor(value) { - this.value = value; - } - json() { - if (this.value === void 0) { - throw new Error(`Cannot convert undefined to an object.`); - } - return JSON.parse(this.value); - } - number() { - return Number(this.value); - } - boolean() { - if (this.value === "false") return false; - if (this.value === "0") return false; - return Boolean(this.value); - } -} -class AstroCookies { - #request; - #requestValues; - #outgoing; - #consumed; - constructor(request) { - this.#request = request; - this.#requestValues = null; - this.#outgoing = null; - this.#consumed = false; - } - /** - * Astro.cookies.delete(key) is used to delete a cookie. Using this method will result - * in a Set-Cookie header added to the response. - * @param key The cookie to delete - * @param options Options related to this deletion, such as the path of the cookie. - */ - delete(key, options) { - const { - // @ts-expect-error - maxAge: _ignoredMaxAge, - // @ts-expect-error - expires: _ignoredExpires, - ...sanitizedOptions - } = options || {}; - const serializeOptions = { - expires: DELETED_EXPIRATION, - ...sanitizedOptions - }; - this.#ensureOutgoingMap().set(key, [ - DELETED_VALUE, - serialize(key, DELETED_VALUE, serializeOptions), - false - ]); - } - /** - * Astro.cookies.get(key) is used to get a cookie value. The cookie value is read from the - * request. If you have set a cookie via Astro.cookies.set(key, value), the value will be taken - * from that set call, overriding any values already part of the request. - * @param key The cookie to get. - * @returns An object containing the cookie value as well as convenience methods for converting its value. - */ - get(key, options = void 0) { - if (this.#outgoing?.has(key)) { - let [serializedValue, , isSetValue] = this.#outgoing.get(key); - if (isSetValue) { - return new AstroCookie(serializedValue); - } else { - return void 0; - } - } - const decode = options?.decode ?? decodeURIComponent; - const values = this.#ensureParsed(); - if (key in values) { - const value = values[key]; - if (value) { - let decodedValue; - try { - decodedValue = decode(value); - } catch (_error) { - decodedValue = value; - } - return new AstroCookie(decodedValue); - } - } - } - /** - * Astro.cookies.has(key) returns a boolean indicating whether this cookie is either - * part of the initial request or set via Astro.cookies.set(key) - * @param key The cookie to check for. - * @param _options This parameter is no longer used. - * @returns - */ - has(key, _options) { - if (this.#outgoing?.has(key)) { - let [, , isSetValue] = this.#outgoing.get(key); - return isSetValue; - } - const values = this.#ensureParsed(); - return values[key] !== void 0; - } - /** - * Astro.cookies.set(key, value) is used to set a cookie's value. If provided - * an object it will be stringified via JSON.stringify(value). Additionally you - * can provide options customizing how this cookie will be set, such as setting httpOnly - * in order to prevent the cookie from being read in client-side JavaScript. - * @param key The name of the cookie to set. - * @param value A value, either a string or other primitive or an object. - * @param options Options for the cookie, such as the path and security settings. - */ - set(key, value, options) { - if (this.#consumed) { - const warning = new Error( - "Astro.cookies.set() was called after the cookies had already been sent to the browser.\nThis may have happened if this method was called in an imported component.\nPlease make sure that Astro.cookies.set() is only called in the frontmatter of the main page." - ); - warning.name = "Warning"; - console.warn(warning); - } - let serializedValue; - if (typeof value === "string") { - serializedValue = value; - } else { - let toStringValue = value.toString(); - if (toStringValue === Object.prototype.toString.call(value)) { - serializedValue = JSON.stringify(value); - } else { - serializedValue = toStringValue; - } - } - const serializeOptions = {}; - if (options) { - Object.assign(serializeOptions, options); - } - this.#ensureOutgoingMap().set(key, [ - serializedValue, - serialize(key, serializedValue, serializeOptions), - true - ]); - if (this.#request[responseSentSymbol]) { - throw new AstroError({ - ...ResponseSentError - }); - } - } - /** - * Merges a new AstroCookies instance into the current instance. Any new cookies - * will be added to the current instance, overwriting any existing cookies with the same name. - */ - merge(cookies) { - const outgoing = cookies.#outgoing; - if (outgoing) { - for (const [key, value] of outgoing) { - this.#ensureOutgoingMap().set(key, value); - } - } - } - /** - * Astro.cookies.header() returns an iterator for the cookies that have previously - * been set by either Astro.cookies.set() or Astro.cookies.delete(). - * This method is primarily used by adapters to set the header on outgoing responses. - * @returns - */ - *headers() { - if (this.#outgoing == null) return; - for (const [, value] of this.#outgoing) { - yield value[1]; - } - } - /** - * Behaves the same as AstroCookies.prototype.headers(), - * but allows a warning when cookies are set after the instance is consumed. - */ - static consume(cookies) { - cookies.#consumed = true; - return cookies.headers(); - } - #ensureParsed() { - if (!this.#requestValues) { - this.#parse(); - } - if (!this.#requestValues) { - this.#requestValues = {}; - } - return this.#requestValues; - } - #ensureOutgoingMap() { - if (!this.#outgoing) { - this.#outgoing = /* @__PURE__ */ new Map(); - } - return this.#outgoing; - } - #parse() { - const raw = this.#request.headers.get("cookie"); - if (!raw) { - return; - } - this.#requestValues = parse(raw, { decode: identity }); - } -} - -const astroCookiesSymbol = Symbol.for("astro.cookies"); -function attachCookiesToResponse(response, cookies) { - Reflect.set(response, astroCookiesSymbol, cookies); -} -function getCookiesFromResponse(response) { - let cookies = Reflect.get(response, astroCookiesSymbol); - if (cookies != null) { - return cookies; - } else { - return void 0; - } -} -function* getSetCookiesFromResponse(response) { - const cookies = getCookiesFromResponse(response); - if (!cookies) { - return []; - } - for (const headerValue of AstroCookies.consume(cookies)) { - yield headerValue; - } - return []; -} - -const dateTimeFormat = new Intl.DateTimeFormat([], { - hour: "2-digit", - minute: "2-digit", - second: "2-digit", - hour12: false -}); -const levels = { - debug: 20, - info: 30, - warn: 40, - error: 50, - silent: 90 -}; -function log(opts, level, label, message, newLine = true) { - const logLevel = opts.level; - const dest = opts.dest; - const event = { - label, - level, - message, - newLine - }; - if (!isLogLevelEnabled(logLevel, level)) { - return; - } - dest.write(event); -} -function isLogLevelEnabled(configuredLogLevel, level) { - return levels[configuredLogLevel] <= levels[level]; -} -function info(opts, label, message, newLine = true) { - return log(opts, "info", label, message, newLine); -} -function warn(opts, label, message, newLine = true) { - return log(opts, "warn", label, message, newLine); -} -function error(opts, label, message, newLine = true) { - return log(opts, "error", label, message, newLine); -} -function debug(...args) { - if ("_astroGlobalDebug" in globalThis) { - globalThis._astroGlobalDebug(...args); - } -} -function getEventPrefix({ level, label }) { - const timestamp = `${dateTimeFormat.format(/* @__PURE__ */ new Date())}`; - const prefix = []; - if (level === "error" || level === "warn") { - prefix.push(colors.bold(timestamp)); - prefix.push(`[${level.toUpperCase()}]`); - } else { - prefix.push(timestamp); - } - if (label) { - prefix.push(`[${label}]`); - } - if (level === "error") { - return colors.red(prefix.join(" ")); - } - if (level === "warn") { - return colors.yellow(prefix.join(" ")); - } - if (prefix.length === 1) { - return colors.dim(prefix[0]); - } - return colors.dim(prefix[0]) + " " + colors.blue(prefix.splice(1).join(" ")); -} -class Logger { - options; - constructor(options) { - this.options = options; - } - info(label, message, newLine = true) { - info(this.options, label, message, newLine); - } - warn(label, message, newLine = true) { - warn(this.options, label, message, newLine); - } - error(label, message, newLine = true) { - error(this.options, label, message, newLine); - } - debug(label, ...messages) { - debug(label, ...messages); - } - level() { - return this.options.level; - } - forkIntegrationLogger(label) { - return new AstroIntegrationLogger(this.options, label); - } -} -class AstroIntegrationLogger { - options; - label; - constructor(logging, label) { - this.options = logging; - this.label = label; - } - /** - * Creates a new logger instance with a new label, but the same log options. - */ - fork(label) { - return new AstroIntegrationLogger(this.options, label); - } - info(message) { - info(this.options, this.label, message); - } - warn(message) { - warn(this.options, this.label, message); - } - error(message) { - error(this.options, this.label, message); - } - debug(message) { - debug(this.label, message); - } -} - -const consoleLogDestination = { - write(event) { - let dest = console.error; - if (levels[event.level] < levels["error"]) { - dest = console.info; - } - if (event.label === "SKIP_FORMAT") { - dest(event.message); - } else { - dest(getEventPrefix(event) + " " + event.message); - } - return true; - } -}; - -function getAssetsPrefix(fileExtension, assetsPrefix) { - let prefix = ""; - if (!assetsPrefix) { - prefix = ""; - } else if (typeof assetsPrefix === "string") { - prefix = assetsPrefix; - } else { - const dotLessFileExtension = fileExtension.slice(1); - prefix = assetsPrefix[dotLessFileExtension] || assetsPrefix.fallback; - } - return prefix; -} - -function createAssetLink(href, base, assetsPrefix, queryParams) { - let url = ""; - if (assetsPrefix) { - const pf = getAssetsPrefix(fileExtension(href), assetsPrefix); - url = joinPaths(pf, slash(href)); - } else if (base) { - url = prependForwardSlash$1(joinPaths(base, slash(href))); - } else { - url = href; - } - return url; -} -function createStylesheetElement(stylesheet, base, assetsPrefix, queryParams) { - if (stylesheet.type === "inline") { - return { - props: {}, - children: stylesheet.content - }; - } else { - return { - props: { - rel: "stylesheet", - href: createAssetLink(stylesheet.src, base, assetsPrefix) - }, - children: "" - }; - } -} -function createStylesheetElementSet(stylesheets, base, assetsPrefix, queryParams) { - return new Set( - stylesheets.map((s) => createStylesheetElement(s, base, assetsPrefix)) - ); -} -function createModuleScriptElement(script, base, assetsPrefix, queryParams) { - if (script.type === "external") { - return createModuleScriptElementWithSrc(script.value, base, assetsPrefix); - } else { - return { - props: { - type: "module" - }, - children: script.value - }; - } -} -function createModuleScriptElementWithSrc(src, base, assetsPrefix, queryParams) { - return { - props: { - type: "module", - src: createAssetLink(src, base, assetsPrefix) - }, - children: "" - }; -} - -const ACTION_API_CONTEXT_SYMBOL = Symbol.for("astro.actionAPIContext"); -const formContentTypes = ["application/x-www-form-urlencoded", "multipart/form-data"]; -function hasContentType(contentType, expected) { - const type = contentType.split(";")[0].toLowerCase(); - return expected.some((t) => type === t); -} - -function getActionContext(context) { - const callerInfo = getCallerInfo(context); - const actionResultAlreadySet = Boolean(context.locals._actionPayload); - let action = void 0; - if (callerInfo && context.request.method === "POST" && !actionResultAlreadySet) { - action = { - calledFrom: callerInfo.from, - name: callerInfo.name, - handler: async () => { - const pipeline = Reflect.get(context, apiContextRoutesSymbol); - const callerInfoName = shouldAppendForwardSlash( - pipeline.manifest.trailingSlash, - pipeline.manifest.buildFormat - ) ? removeTrailingForwardSlash(callerInfo.name) : callerInfo.name; - let baseAction; - try { - baseAction = await pipeline.getAction(callerInfoName); - } catch (error) { - if (error instanceof Error && "name" in error && typeof error.name === "string" && error.name === ActionNotFoundError.name) { - return { data: void 0, error: new ActionError({ code: "NOT_FOUND" }) }; - } - throw error; - } - let input; - try { - input = await parseRequestBody(context.request); - } catch (e) { - if (e instanceof TypeError) { - return { data: void 0, error: new ActionError({ code: "UNSUPPORTED_MEDIA_TYPE" }) }; - } - throw e; - } - const omitKeys = ["props", "getActionResult", "callAction", "redirect"]; - const actionAPIContext = Object.create( - Object.getPrototypeOf(context), - Object.fromEntries( - Object.entries(Object.getOwnPropertyDescriptors(context)).filter( - ([key]) => !omitKeys.includes(key) - ) - ) - ); - Reflect.set(actionAPIContext, ACTION_API_CONTEXT_SYMBOL, true); - const handler = baseAction.bind(actionAPIContext); - return handler(input); - } - }; - } - function setActionResult(actionName, actionResult) { - context.locals._actionPayload = { - actionResult, - actionName - }; - } - return { - action, - setActionResult, - serializeActionResult, - deserializeActionResult - }; -} -function getCallerInfo(ctx) { - if (ctx.routePattern === ACTION_RPC_ROUTE_PATTERN) { - return { from: "rpc", name: ctx.url.pathname.replace(/^.*\/_actions\//, "") }; - } - const queryParam = ctx.url.searchParams.get(ACTION_QUERY_PARAMS.actionName); - if (queryParam) { - return { from: "form", name: queryParam }; - } - return void 0; -} -async function parseRequestBody(request) { - const contentType = request.headers.get("content-type"); - const contentLength = request.headers.get("Content-Length"); - if (!contentType) return void 0; - if (hasContentType(contentType, formContentTypes)) { - return await request.clone().formData(); - } - if (hasContentType(contentType, ["application/json"])) { - return contentLength === "0" ? void 0 : await request.clone().json(); - } - throw new TypeError("Unsupported content type"); -} - -function hasActionPayload(locals) { - return "_actionPayload" in locals; -} -function createGetActionResult(locals) { - return (actionFn) => { - if (!hasActionPayload(locals) || actionFn.toString() !== getActionQueryString(locals._actionPayload.actionName)) { - return void 0; - } - return deserializeActionResult(locals._actionPayload.actionResult); - }; -} -function createCallAction(context) { - return (baseAction, input) => { - Reflect.set(context, ACTION_API_CONTEXT_SYMBOL, true); - const action = baseAction.bind(context); - return action(input); - }; -} - -function parseLocale(header) { - if (header === "*") { - return [{ locale: header, qualityValue: void 0 }]; - } - const result = []; - const localeValues = header.split(",").map((str) => str.trim()); - for (const localeValue of localeValues) { - const split = localeValue.split(";").map((str) => str.trim()); - const localeName = split[0]; - const qualityValue = split[1]; - if (!split) { - continue; - } - if (qualityValue && qualityValue.startsWith("q=")) { - const qualityValueAsFloat = Number.parseFloat(qualityValue.slice("q=".length)); - if (Number.isNaN(qualityValueAsFloat) || qualityValueAsFloat > 1) { - result.push({ - locale: localeName, - qualityValue: void 0 - }); - } else { - result.push({ - locale: localeName, - qualityValue: qualityValueAsFloat - }); - } - } else { - result.push({ - locale: localeName, - qualityValue: void 0 - }); - } - } - return result; -} -function sortAndFilterLocales(browserLocaleList, locales) { - const normalizedLocales = getAllCodes(locales).map(normalizeTheLocale); - return browserLocaleList.filter((browserLocale) => { - if (browserLocale.locale !== "*") { - return normalizedLocales.includes(normalizeTheLocale(browserLocale.locale)); - } - return true; - }).sort((a, b) => { - if (a.qualityValue && b.qualityValue) { - return Math.sign(b.qualityValue - a.qualityValue); - } - return 0; - }); -} -function computePreferredLocale(request, locales) { - const acceptHeader = request.headers.get("Accept-Language"); - let result = void 0; - if (acceptHeader) { - const browserLocaleList = sortAndFilterLocales(parseLocale(acceptHeader), locales); - const firstResult = browserLocaleList.at(0); - if (firstResult && firstResult.locale !== "*") { - for (const currentLocale of locales) { - if (typeof currentLocale === "string") { - if (normalizeTheLocale(currentLocale) === normalizeTheLocale(firstResult.locale)) { - result = currentLocale; - break; - } - } else { - for (const currentCode of currentLocale.codes) { - if (normalizeTheLocale(currentCode) === normalizeTheLocale(firstResult.locale)) { - result = currentCode; - break; - } - } - } - } - } - } - return result; -} -function computePreferredLocaleList(request, locales) { - const acceptHeader = request.headers.get("Accept-Language"); - let result = []; - if (acceptHeader) { - const browserLocaleList = sortAndFilterLocales(parseLocale(acceptHeader), locales); - if (browserLocaleList.length === 1 && browserLocaleList.at(0).locale === "*") { - return getAllCodes(locales); - } else if (browserLocaleList.length > 0) { - for (const browserLocale of browserLocaleList) { - for (const loopLocale of locales) { - if (typeof loopLocale === "string") { - if (normalizeTheLocale(loopLocale) === normalizeTheLocale(browserLocale.locale)) { - result.push(loopLocale); - } - } else { - for (const code of loopLocale.codes) { - if (code === browserLocale.locale) { - result.push(code); - } - } - } - } - } - } - } - return result; -} -function computeCurrentLocale(pathname, locales, defaultLocale) { - for (const segment of pathname.split("/").map(normalizeThePath)) { - for (const locale of locales) { - if (typeof locale === "string") { - if (!segment.includes(locale)) continue; - if (normalizeTheLocale(locale) === normalizeTheLocale(segment)) { - return locale; - } - } else { - if (locale.path === segment) { - return locale.codes.at(0); - } else { - for (const code of locale.codes) { - if (normalizeTheLocale(code) === normalizeTheLocale(segment)) { - return code; - } - } - } - } - } - } - for (const locale of locales) { - if (typeof locale === "string") { - if (locale === defaultLocale) { - return locale; - } - } else { - if (locale.path === defaultLocale) { - return locale.codes.at(0); - } - } - } -} - -async function callMiddleware(onRequest, apiContext, responseFunction) { - let nextCalled = false; - let responseFunctionPromise = void 0; - const next = async (payload) => { - nextCalled = true; - responseFunctionPromise = responseFunction(apiContext, payload); - return responseFunctionPromise; - }; - let middlewarePromise = onRequest(apiContext, next); - return await Promise.resolve(middlewarePromise).then(async (value) => { - if (nextCalled) { - if (typeof value !== "undefined") { - if (value instanceof Response === false) { - throw new AstroError(MiddlewareNotAResponse); - } - return value; - } else { - if (responseFunctionPromise) { - return responseFunctionPromise; - } else { - throw new AstroError(MiddlewareNotAResponse); - } - } - } else if (typeof value === "undefined") { - throw new AstroError(MiddlewareNoDataOrNextCalled); - } else if (value instanceof Response === false) { - throw new AstroError(MiddlewareNotAResponse); - } else { - return value; - } - }); -} - -function createRequest({ - url, - headers, - method = "GET", - body = void 0, - logger, - isPrerendered = false, - routePattern, - init -}) { - const headersObj = isPrerendered ? void 0 : headers instanceof Headers ? headers : new Headers( - // Filter out HTTP/2 pseudo-headers. These are internally-generated headers added to all HTTP/2 requests with trusted metadata about the request. - // Examples include `:method`, `:scheme`, `:authority`, and `:path`. - // They are always prefixed with a colon to distinguish them from other headers, and it is an error to add the to a Headers object manually. - // See https://httpwg.org/specs/rfc7540.html#HttpRequest - Object.entries(headers).filter(([name]) => !name.startsWith(":")) - ); - if (typeof url === "string") url = new URL(url); - if (isPrerendered) { - url.search = ""; - } - const request = new Request(url, { - method, - headers: headersObj, - // body is made available only if the request is for a page that will be on-demand rendered - body: isPrerendered ? null : body, - ...init - }); - if (isPrerendered) { - let _headers = request.headers; - const { value, writable, ...headersDesc } = Object.getOwnPropertyDescriptor(request, "headers") || {}; - Object.defineProperty(request, "headers", { - ...headersDesc, - get() { - logger.warn( - null, - `\`Astro.request.headers\` was used when rendering the route \`${routePattern}'\`. \`Astro.request.headers\` is not available on prerendered pages. If you need access to request headers, make sure that the page is server-rendered using \`export const prerender = false;\` or by setting \`output\` to \`"server"\` in your Astro config to make all your pages server-rendered by default.` - ); - return _headers; - }, - set(newHeaders) { - _headers = newHeaders; - } - }); - } - return request; -} - -function findRouteToRewrite({ - payload, - routes, - request, - trailingSlash, - buildFormat, - base, - outDir -}) { - let newUrl = void 0; - if (payload instanceof URL) { - newUrl = payload; - } else if (payload instanceof Request) { - newUrl = new URL(payload.url); - } else { - newUrl = new URL(payload, new URL(request.url).origin); - } - let pathname = newUrl.pathname; - const shouldAppendSlash = shouldAppendForwardSlash(trailingSlash, buildFormat); - if (base !== "/") { - const isBasePathRequest = newUrl.pathname === base || newUrl.pathname === removeTrailingForwardSlash(base); - if (isBasePathRequest) { - pathname = shouldAppendSlash ? "/" : ""; - } else if (newUrl.pathname.startsWith(base)) { - pathname = shouldAppendSlash ? appendForwardSlash$1(newUrl.pathname) : removeTrailingForwardSlash(newUrl.pathname); - pathname = pathname.slice(base.length); - } - } - if (!pathname.startsWith("/") && shouldAppendSlash && newUrl.pathname.endsWith("/")) { - pathname = prependForwardSlash$1(pathname); - } - if (pathname === "/" && base !== "/" && !shouldAppendSlash) { - pathname = ""; - } - if (buildFormat === "file") { - pathname = pathname.replace(/\.html$/, ""); - } - if (base !== "/" && (pathname === "" || pathname === "/") && !shouldAppendSlash) { - newUrl.pathname = removeTrailingForwardSlash(base); - } else { - newUrl.pathname = joinPaths(...[base, pathname].filter(Boolean)); - } - const decodedPathname = decodeURI(pathname); - let foundRoute; - for (const route of routes) { - if (route.pattern.test(decodedPathname)) { - if (route.params && route.params.length !== 0 && route.distURL && route.distURL.length !== 0) { - if (!route.distURL.find( - (url) => url.href.replace(outDir.toString(), "").replace(/(?:\/index\.html|\.html)$/, "") == trimSlashes(decodedPathname) - )) { - continue; - } - } - foundRoute = route; - break; - } - } - if (foundRoute) { - return { - routeData: foundRoute, - newUrl, - pathname: decodedPathname - }; - } else { - const custom404 = routes.find((route) => route.route === "/404"); - if (custom404) { - return { routeData: custom404, newUrl, pathname }; - } else { - return { routeData: DEFAULT_404_ROUTE, newUrl, pathname }; - } - } -} -function copyRequest(newUrl, oldRequest, isPrerendered, logger, routePattern) { - if (oldRequest.bodyUsed) { - throw new AstroError(RewriteWithBodyUsed); - } - return createRequest({ - url: newUrl, - method: oldRequest.method, - body: oldRequest.body, - isPrerendered, - logger, - headers: isPrerendered ? {} : oldRequest.headers, - routePattern, - init: { - referrer: oldRequest.referrer, - referrerPolicy: oldRequest.referrerPolicy, - mode: oldRequest.mode, - credentials: oldRequest.credentials, - cache: oldRequest.cache, - redirect: oldRequest.redirect, - integrity: oldRequest.integrity, - signal: oldRequest.signal, - keepalive: oldRequest.keepalive, - // https://fetch.spec.whatwg.org/#dom-request-duplex - // @ts-expect-error It isn't part of the types, but undici accepts it and it allows to carry over the body to a new request - duplex: "half" - } - }); -} -function setOriginPathname(request, pathname, trailingSlash, buildFormat) { - if (!pathname) { - pathname = "/"; - } - const shouldAppendSlash = shouldAppendForwardSlash(trailingSlash, buildFormat); - let finalPathname; - if (pathname === "/") { - finalPathname = "/"; - } else if (shouldAppendSlash) { - finalPathname = appendForwardSlash$1(pathname); - } else { - finalPathname = removeTrailingForwardSlash(pathname); - } - Reflect.set(request, originPathnameSymbol, encodeURIComponent(finalPathname)); -} -function getOriginPathname(request) { - const origin = Reflect.get(request, originPathnameSymbol); - if (origin) { - return decodeURIComponent(origin); - } - return new URL(request.url).pathname; -} - -const NOOP_ACTIONS_MOD = { - server: {} -}; - -const FORM_CONTENT_TYPES = [ - "application/x-www-form-urlencoded", - "multipart/form-data", - "text/plain" -]; -const SAFE_METHODS = ["GET", "HEAD", "OPTIONS"]; -function createOriginCheckMiddleware() { - return defineMiddleware((context, next) => { - const { request, url, isPrerendered } = context; - if (isPrerendered) { - return next(); - } - if (SAFE_METHODS.includes(request.method)) { - return next(); - } - const isSameOrigin = request.headers.get("origin") === url.origin; - const hasContentType = request.headers.has("content-type"); - if (hasContentType) { - const formLikeHeader = hasFormLikeHeader(request.headers.get("content-type")); - if (formLikeHeader && !isSameOrigin) { - return new Response(`Cross-site ${request.method} form submissions are forbidden`, { - status: 403 - }); - } - } else { - if (!isSameOrigin) { - return new Response(`Cross-site ${request.method} form submissions are forbidden`, { - status: 403 - }); - } - } - return next(); - }); -} -function hasFormLikeHeader(contentType) { - if (contentType) { - for (const FORM_CONTENT_TYPE of FORM_CONTENT_TYPES) { - if (contentType.toLowerCase().includes(FORM_CONTENT_TYPE)) { - return true; - } - } - } - return false; -} - -const VALID_PARAM_TYPES = ["string", "number", "undefined"]; -function validateGetStaticPathsParameter([key, value], route) { - if (!VALID_PARAM_TYPES.includes(typeof value)) { - throw new AstroError({ - ...GetStaticPathsInvalidRouteParam, - message: GetStaticPathsInvalidRouteParam.message(key, value, typeof value), - location: { - file: route - } - }); - } -} -function validateDynamicRouteModule(mod, { - ssr, - route -}) { - if ((!ssr || route.prerender) && !mod.getStaticPaths) { - throw new AstroError({ - ...GetStaticPathsRequired, - location: { file: route.component } - }); - } -} -function validateGetStaticPathsResult(result, logger, route) { - if (!Array.isArray(result)) { - throw new AstroError({ - ...InvalidGetStaticPathsReturn, - message: InvalidGetStaticPathsReturn.message(typeof result), - location: { - file: route.component - } - }); - } - result.forEach((pathObject) => { - if (typeof pathObject === "object" && Array.isArray(pathObject) || pathObject === null) { - throw new AstroError({ - ...InvalidGetStaticPathsEntry, - message: InvalidGetStaticPathsEntry.message( - Array.isArray(pathObject) ? "array" : typeof pathObject - ) - }); - } - if (pathObject.params === void 0 || pathObject.params === null || pathObject.params && Object.keys(pathObject.params).length === 0) { - throw new AstroError({ - ...GetStaticPathsExpectedParams, - location: { - file: route.component - } - }); - } - for (const [key, val] of Object.entries(pathObject.params)) { - if (!(typeof val === "undefined" || typeof val === "string" || typeof val === "number")) { - logger.warn( - "router", - `getStaticPaths() returned an invalid path param: "${key}". A string, number or undefined value was expected, but got \`${JSON.stringify( - val - )}\`.` - ); - } - if (typeof val === "string" && val === "") { - logger.warn( - "router", - `getStaticPaths() returned an invalid path param: "${key}". \`undefined\` expected for an optional param, but got empty string.` - ); - } - } - }); -} - -function stringifyParams(params, route) { - const validatedParams = Object.entries(params).reduce((acc, next) => { - validateGetStaticPathsParameter(next, route.component); - const [key, value] = next; - if (value !== void 0) { - acc[key] = typeof value === "string" ? trimSlashes(value) : value.toString(); - } - return acc; - }, {}); - return route.generate(validatedParams); -} - -function generatePaginateFunction(routeMatch, base) { - return function paginateUtility(data, args = {}) { - let { pageSize: _pageSize, params: _params, props: _props } = args; - const pageSize = _pageSize || 10; - const paramName = "page"; - const additionalParams = _params || {}; - const additionalProps = _props || {}; - let includesFirstPageNumber; - if (routeMatch.params.includes(`...${paramName}`)) { - includesFirstPageNumber = false; - } else if (routeMatch.params.includes(`${paramName}`)) { - includesFirstPageNumber = true; - } else { - throw new AstroError({ - ...PageNumberParamNotFound, - message: PageNumberParamNotFound.message(paramName) - }); - } - const lastPage = Math.max(1, Math.ceil(data.length / pageSize)); - const result = [...Array(lastPage).keys()].map((num) => { - const pageNum = num + 1; - const start = pageSize === Infinity ? 0 : (pageNum - 1) * pageSize; - const end = Math.min(start + pageSize, data.length); - const params = { - ...additionalParams, - [paramName]: includesFirstPageNumber || pageNum > 1 ? String(pageNum) : void 0 - }; - const current = addRouteBase(routeMatch.generate({ ...params }), base); - const next = pageNum === lastPage ? void 0 : addRouteBase(routeMatch.generate({ ...params, page: String(pageNum + 1) }), base); - const prev = pageNum === 1 ? void 0 : addRouteBase( - routeMatch.generate({ - ...params, - page: !includesFirstPageNumber && pageNum - 1 === 1 ? void 0 : String(pageNum - 1) - }), - base - ); - const first = pageNum === 1 ? void 0 : addRouteBase( - routeMatch.generate({ - ...params, - page: includesFirstPageNumber ? "1" : void 0 - }), - base - ); - const last = pageNum === lastPage ? void 0 : addRouteBase(routeMatch.generate({ ...params, page: String(lastPage) }), base); - return { - params, - props: { - ...additionalProps, - page: { - data: data.slice(start, end), - start, - end: end - 1, - size: pageSize, - total: data.length, - currentPage: pageNum, - lastPage, - url: { current, next, prev, first, last } - } - } - }; - }); - return result; - }; -} -function addRouteBase(route, base) { - let routeWithBase = joinPaths(base, route); - if (routeWithBase === "") routeWithBase = "/"; - return routeWithBase; -} - -async function callGetStaticPaths({ - mod, - route, - routeCache, - logger, - ssr, - base -}) { - const cached = routeCache.get(route); - if (!mod) { - throw new Error("This is an error caused by Astro and not your code. Please file an issue."); - } - if (cached?.staticPaths) { - return cached.staticPaths; - } - validateDynamicRouteModule(mod, { ssr, route }); - if (ssr && !route.prerender) { - const entry = Object.assign([], { keyed: /* @__PURE__ */ new Map() }); - routeCache.set(route, { ...cached, staticPaths: entry }); - return entry; - } - let staticPaths = []; - if (!mod.getStaticPaths) { - throw new Error("Unexpected Error."); - } - staticPaths = await mod.getStaticPaths({ - // Q: Why the cast? - // A: So users downstream can have nicer typings, we have to make some sacrifice in our internal typings, which necessitate a cast here - paginate: generatePaginateFunction(route, base), - routePattern: route.route - }); - validateGetStaticPathsResult(staticPaths, logger, route); - const keyedStaticPaths = staticPaths; - keyedStaticPaths.keyed = /* @__PURE__ */ new Map(); - for (const sp of keyedStaticPaths) { - const paramsKey = stringifyParams(sp.params, route); - keyedStaticPaths.keyed.set(paramsKey, sp); - } - routeCache.set(route, { ...cached, staticPaths: keyedStaticPaths }); - return keyedStaticPaths; -} -class RouteCache { - logger; - cache = {}; - runtimeMode; - constructor(logger, runtimeMode = "production") { - this.logger = logger; - this.runtimeMode = runtimeMode; - } - /** Clear the cache. */ - clearAll() { - this.cache = {}; - } - set(route, entry) { - const key = this.key(route); - if (this.runtimeMode === "production" && this.cache[key]?.staticPaths) { - this.logger.warn(null, `Internal Warning: route cache overwritten. (${key})`); - } - this.cache[key] = entry; - } - get(route) { - return this.cache[this.key(route)]; - } - key(route) { - return `${route.route}_${route.component}`; - } -} -function findPathItemByKey(staticPaths, params, route, logger) { - const paramsKey = stringifyParams(params, route); - const matchedStaticPath = staticPaths.keyed.get(paramsKey); - if (matchedStaticPath) { - return matchedStaticPath; - } - logger.debug("router", `findPathItemByKey() - Unexpected cache miss looking for ${paramsKey}`); -} - -function createDefaultRoutes(manifest) { - const root = new URL(manifest.hrefRoot); - return [ - { - instance: default404Instance, - matchesComponent: (filePath) => filePath.href === new URL(DEFAULT_404_COMPONENT, root).href, - route: DEFAULT_404_ROUTE.route, - component: DEFAULT_404_COMPONENT - }, - { - instance: createEndpoint(manifest), - matchesComponent: (filePath) => filePath.href === new URL(SERVER_ISLAND_COMPONENT, root).href, - route: SERVER_ISLAND_ROUTE, - component: SERVER_ISLAND_COMPONENT - } - ]; -} - -class Pipeline { - constructor(logger, manifest, runtimeMode, renderers, resolve, serverLike, streaming, adapterName = manifest.adapterName, clientDirectives = manifest.clientDirectives, inlinedScripts = manifest.inlinedScripts, compressHTML = manifest.compressHTML, i18n = manifest.i18n, middleware = manifest.middleware, routeCache = new RouteCache(logger, runtimeMode), site = manifest.site ? new URL(manifest.site) : void 0, defaultRoutes = createDefaultRoutes(manifest), actions = manifest.actions) { - this.logger = logger; - this.manifest = manifest; - this.runtimeMode = runtimeMode; - this.renderers = renderers; - this.resolve = resolve; - this.serverLike = serverLike; - this.streaming = streaming; - this.adapterName = adapterName; - this.clientDirectives = clientDirectives; - this.inlinedScripts = inlinedScripts; - this.compressHTML = compressHTML; - this.i18n = i18n; - this.middleware = middleware; - this.routeCache = routeCache; - this.site = site; - this.defaultRoutes = defaultRoutes; - this.actions = actions; - this.internalMiddleware = []; - if (i18n?.strategy !== "manual") { - this.internalMiddleware.push( - createI18nMiddleware(i18n, manifest.base, manifest.trailingSlash, manifest.buildFormat) - ); - } - } - internalMiddleware; - resolvedMiddleware = void 0; - resolvedActions = void 0; - /** - * Resolves the middleware from the manifest, and returns the `onRequest` function. If `onRequest` isn't there, - * it returns a no-op function - */ - async getMiddleware() { - if (this.resolvedMiddleware) { - return this.resolvedMiddleware; - } else if (this.middleware) { - const middlewareInstance = await this.middleware(); - const onRequest = middlewareInstance.onRequest ?? NOOP_MIDDLEWARE_FN; - const internalMiddlewares = [onRequest]; - if (this.manifest.checkOrigin) { - internalMiddlewares.unshift(createOriginCheckMiddleware()); - } - this.resolvedMiddleware = sequence(...internalMiddlewares); - return this.resolvedMiddleware; - } else { - this.resolvedMiddleware = NOOP_MIDDLEWARE_FN; - return this.resolvedMiddleware; - } - } - setActions(actions) { - this.resolvedActions = actions; - } - async getActions() { - if (this.resolvedActions) { - return this.resolvedActions; - } else if (this.actions) { - return await this.actions(); - } - return NOOP_ACTIONS_MOD; - } - async getAction(path) { - const pathKeys = path.split(".").map((key) => decodeURIComponent(key)); - let { server } = await this.getActions(); - if (!server || !(typeof server === "object")) { - throw new TypeError( - `Expected \`server\` export in actions file to be an object. Received ${typeof server}.` - ); - } - for (const key of pathKeys) { - if (!(key in server)) { - throw new AstroError({ - ...ActionNotFoundError, - message: ActionNotFoundError.message(pathKeys.join(".")) - }); - } - server = server[key]; - } - if (typeof server !== "function") { - throw new TypeError( - `Expected handler for action ${pathKeys.join(".")} to be a function. Received ${typeof server}.` - ); - } - return server; - } -} - -function routeIsRedirect(route) { - return route?.type === "redirect"; -} -function routeIsFallback(route) { - return route?.type === "fallback"; -} - -const RedirectComponentInstance = { - default() { - return new Response(null, { - status: 301 - }); - } -}; -const RedirectSinglePageBuiltModule = { - page: () => Promise.resolve(RedirectComponentInstance), - onRequest: (_, next) => next(), - renderers: [] -}; - -async function getProps(opts) { - const { logger, mod, routeData: route, routeCache, pathname, serverLike, base } = opts; - if (!route || route.pathname) { - return {}; - } - if (routeIsRedirect(route) || routeIsFallback(route) || route.component === DEFAULT_404_COMPONENT) { - return {}; - } - const staticPaths = await callGetStaticPaths({ - mod, - route, - routeCache, - logger, - ssr: serverLike, - base - }); - const params = getParams(route, pathname); - const matchedStaticPath = findPathItemByKey(staticPaths, params, route, logger); - if (!matchedStaticPath && (serverLike ? route.prerender : true)) { - throw new AstroError({ - ...NoMatchingStaticPathFound, - message: NoMatchingStaticPathFound.message(pathname), - hint: NoMatchingStaticPathFound.hint([route.component]) - }); - } - if (mod) { - validatePrerenderEndpointCollision(route, mod, params); - } - const props = matchedStaticPath?.props ? { ...matchedStaticPath.props } : {}; - return props; -} -function getParams(route, pathname) { - if (!route.params.length) return {}; - const paramsMatch = route.pattern.exec(pathname) || route.fallbackRoutes.map((fallbackRoute) => fallbackRoute.pattern.exec(pathname)).find((x) => x); - if (!paramsMatch) return {}; - const params = {}; - route.params.forEach((key, i) => { - if (key.startsWith("...")) { - params[key.slice(3)] = paramsMatch[i + 1] ? paramsMatch[i + 1] : void 0; - } else { - params[key] = paramsMatch[i + 1]; - } - }); - return params; -} -function validatePrerenderEndpointCollision(route, mod, params) { - if (route.type === "endpoint" && mod.getStaticPaths) { - const lastSegment = route.segments[route.segments.length - 1]; - const paramValues = Object.values(params); - const lastParam = paramValues[paramValues.length - 1]; - if (lastSegment.length === 1 && lastSegment[0].dynamic && lastParam === void 0) { - throw new AstroError({ - ...PrerenderDynamicEndpointPathCollide, - message: PrerenderDynamicEndpointPathCollide.message(route.route), - hint: PrerenderDynamicEndpointPathCollide.hint(route.component), - location: { - file: route.component - } - }); - } - } -} - -function getFunctionExpression(slot) { - if (!slot) return; - const expressions = slot?.expressions?.filter((e) => isRenderInstruction(e) === false); - if (expressions?.length !== 1) return; - return expressions[0]; -} -class Slots { - #result; - #slots; - #logger; - constructor(result, slots, logger) { - this.#result = result; - this.#slots = slots; - this.#logger = logger; - if (slots) { - for (const key of Object.keys(slots)) { - if (this[key] !== void 0) { - throw new AstroError({ - ...ReservedSlotName, - message: ReservedSlotName.message(key) - }); - } - Object.defineProperty(this, key, { - get() { - return true; - }, - enumerable: true - }); - } - } - } - has(name) { - if (!this.#slots) return false; - return Boolean(this.#slots[name]); - } - async render(name, args = []) { - if (!this.#slots || !this.has(name)) return; - const result = this.#result; - if (!Array.isArray(args)) { - this.#logger.warn( - null, - `Expected second parameter to be an array, received a ${typeof args}. If you're trying to pass an array as a single argument and getting unexpected results, make sure you're passing your array as a item of an array. Ex: Astro.slots.render('default', [["Hello", "World"]])` - ); - } else if (args.length > 0) { - const slotValue = this.#slots[name]; - const component = typeof slotValue === "function" ? await slotValue(result) : await slotValue; - const expression = getFunctionExpression(component); - if (expression) { - const slot = async () => typeof expression === "function" ? expression(...args) : expression; - return await renderSlotToString(result, slot).then((res) => { - return res; - }); - } - if (typeof component === "function") { - return await renderJSX(result, component(...args)).then( - (res) => res != null ? String(res) : res - ); - } - } - const content = await renderSlotToString(result, this.#slots[name]); - const outHTML = chunkToString(result, content); - return outHTML; - } -} - -function sequence(...handlers) { - const filtered = handlers.filter((h) => !!h); - const length = filtered.length; - if (!length) { - return defineMiddleware((_context, next) => { - return next(); - }); - } - return defineMiddleware((context, next) => { - let carriedPayload = void 0; - return applyHandle(0, context); - function applyHandle(i, handleContext) { - const handle = filtered[i]; - const result = handle(handleContext, async (payload) => { - if (i < length - 1) { - if (payload) { - let newRequest; - if (payload instanceof Request) { - newRequest = payload; - } else if (payload instanceof URL) { - newRequest = new Request(payload, handleContext.request.clone()); - } else { - newRequest = new Request( - new URL(payload, handleContext.url.origin), - handleContext.request.clone() - ); - } - const oldPathname = handleContext.url.pathname; - const pipeline = Reflect.get(handleContext, apiContextRoutesSymbol); - const { routeData, pathname } = await pipeline.tryRewrite( - payload, - handleContext.request - ); - if (pipeline.serverLike === true && handleContext.isPrerendered === false && routeData.prerender === true) { - throw new AstroError({ - ...ForbiddenRewrite, - message: ForbiddenRewrite.message( - handleContext.url.pathname, - pathname, - routeData.component - ), - hint: ForbiddenRewrite.hint(routeData.component) - }); - } - carriedPayload = payload; - handleContext.request = newRequest; - handleContext.url = new URL(newRequest.url); - handleContext.params = getParams(routeData, pathname); - handleContext.routePattern = routeData.route; - setOriginPathname( - handleContext.request, - oldPathname, - pipeline.manifest.trailingSlash, - pipeline.manifest.buildFormat - ); - } - return applyHandle(i + 1, handleContext); - } else { - return next(payload ?? carriedPayload); - } - }); - return result; - } - }); -} - -function defineMiddleware(fn) { - return fn; -} - -const PERSIST_SYMBOL = Symbol(); -const DEFAULT_COOKIE_NAME = "astro-session"; -const VALID_COOKIE_REGEX = /^[\w-]+$/; -const unflatten = (parsed, _) => { - return unflatten$1(parsed, { - URL: (href) => new URL(href) - }); -}; -const stringify = (data, _) => { - return stringify$1(data, { - // Support URL objects - URL: (val) => val instanceof URL && val.href - }); -}; -class AstroSession { - // The cookies object. - #cookies; - // The session configuration. - #config; - // The cookie config - #cookieConfig; - // The cookie name - #cookieName; - // The unstorage object for the session driver. - #storage; - #data; - // The session ID. A v4 UUID. - #sessionID; - // Sessions to destroy. Needed because we won't have the old session ID after it's destroyed locally. - #toDestroy = /* @__PURE__ */ new Set(); - // Session keys to delete. Used for partial data sets to avoid overwriting the deleted value. - #toDelete = /* @__PURE__ */ new Set(); - // Whether the session is dirty and needs to be saved. - #dirty = false; - // Whether the session cookie has been set. - #cookieSet = false; - // The local data is "partial" if it has not been loaded from storage yet and only - // contains values that have been set or deleted in-memory locally. - // We do this to avoid the need to block on loading data when it is only being set. - // When we load the data from storage, we need to merge it with the local partial data, - // preserving in-memory changes and deletions. - #partial = true; - static #sharedStorage = /* @__PURE__ */ new Map(); - constructor(cookies, { - cookie: cookieConfig = DEFAULT_COOKIE_NAME, - ...config - }, runtimeMode) { - const { driver } = config; - if (!driver) { - throw new AstroError({ - ...SessionStorageInitError, - message: SessionStorageInitError.message( - "No driver was defined in the session configuration and the adapter did not provide a default driver." - ) - }); - } - this.#cookies = cookies; - let cookieConfigObject; - if (typeof cookieConfig === "object") { - const { name = DEFAULT_COOKIE_NAME, ...rest } = cookieConfig; - this.#cookieName = name; - cookieConfigObject = rest; - } else { - this.#cookieName = cookieConfig || DEFAULT_COOKIE_NAME; - } - this.#cookieConfig = { - sameSite: "lax", - secure: runtimeMode === "production", - path: "/", - ...cookieConfigObject, - httpOnly: true - }; - this.#config = { ...config, driver }; - } - /** - * Gets a session value. Returns `undefined` if the session or value does not exist. - */ - async get(key) { - return (await this.#ensureData()).get(key)?.data; - } - /** - * Checks if a session value exists. - */ - async has(key) { - return (await this.#ensureData()).has(key); - } - /** - * Gets all session values. - */ - async keys() { - return (await this.#ensureData()).keys(); - } - /** - * Gets all session values. - */ - async values() { - return [...(await this.#ensureData()).values()].map((entry) => entry.data); - } - /** - * Gets all session entries. - */ - async entries() { - return [...(await this.#ensureData()).entries()].map(([key, entry]) => [key, entry.data]); - } - /** - * Deletes a session value. - */ - delete(key) { - this.#data?.delete(key); - if (this.#partial) { - this.#toDelete.add(key); - } - this.#dirty = true; - } - /** - * Sets a session value. The session is created if it does not exist. - */ - set(key, value, { ttl } = {}) { - if (!key) { - throw new AstroError({ - ...SessionStorageSaveError, - message: "The session key was not provided." - }); - } - let cloned; - try { - cloned = unflatten(JSON.parse(stringify(value))); - } catch (err) { - throw new AstroError( - { - ...SessionStorageSaveError, - message: `The session data for ${key} could not be serialized.`, - hint: "See the devalue library for all supported types: https://github.com/rich-harris/devalue" - }, - { cause: err } - ); - } - if (!this.#cookieSet) { - this.#setCookie(); - this.#cookieSet = true; - } - this.#data ??= /* @__PURE__ */ new Map(); - const lifetime = ttl ?? this.#config.ttl; - const expires = typeof lifetime === "number" ? Date.now() + lifetime * 1e3 : lifetime; - this.#data.set(key, { - data: cloned, - expires - }); - this.#dirty = true; - } - /** - * Destroys the session, clearing the cookie and storage if it exists. - */ - destroy() { - const sessionId = this.#sessionID ?? this.#cookies.get(this.#cookieName)?.value; - if (sessionId) { - this.#toDestroy.add(sessionId); - } - this.#cookies.delete(this.#cookieName, this.#cookieConfig); - this.#sessionID = void 0; - this.#data = void 0; - this.#dirty = true; - } - /** - * Regenerates the session, creating a new session ID. The existing session data is preserved. - */ - async regenerate() { - let data = /* @__PURE__ */ new Map(); - try { - data = await this.#ensureData(); - } catch (err) { - console.error("Failed to load session data during regeneration:", err); - } - const oldSessionId = this.#sessionID; - this.#sessionID = crypto.randomUUID(); - this.#data = data; - await this.#setCookie(); - if (oldSessionId && this.#storage) { - this.#storage.removeItem(oldSessionId).catch((err) => { - console.error("Failed to remove old session data:", err); - }); - } - } - // Persists the session data to storage. - // This is called automatically at the end of the request. - // Uses a symbol to prevent users from calling it directly. - async [PERSIST_SYMBOL]() { - if (!this.#dirty && !this.#toDestroy.size) { - return; - } - const storage = await this.#ensureStorage(); - if (this.#dirty && this.#data) { - const data = await this.#ensureData(); - this.#toDelete.forEach((key2) => data.delete(key2)); - const key = this.#ensureSessionID(); - let serialized; - try { - serialized = stringify(data); - } catch (err) { - throw new AstroError( - { - ...SessionStorageSaveError, - message: SessionStorageSaveError.message( - "The session data could not be serialized.", - this.#config.driver - ) - }, - { cause: err } - ); - } - await storage.setItem(key, serialized); - this.#dirty = false; - } - if (this.#toDestroy.size > 0) { - const cleanupPromises = [...this.#toDestroy].map( - (sessionId) => storage.removeItem(sessionId).catch((err) => { - console.error(`Failed to clean up session ${sessionId}:`, err); - }) - ); - await Promise.all(cleanupPromises); - this.#toDestroy.clear(); - } - } - get sessionID() { - return this.#sessionID; - } - /** - * Loads a session from storage with the given ID, and replaces the current session. - * Any changes made to the current session will be lost. - * This is not normally needed, as the session is automatically loaded using the cookie. - * However it can be used to restore a session where the ID has been recorded somewhere - * else (e.g. in a database). - */ - async load(sessionID) { - this.#sessionID = sessionID; - this.#data = void 0; - await this.#setCookie(); - await this.#ensureData(); - } - /** - * Sets the session cookie. - */ - async #setCookie() { - if (!VALID_COOKIE_REGEX.test(this.#cookieName)) { - throw new AstroError({ - ...SessionStorageSaveError, - message: "Invalid cookie name. Cookie names can only contain letters, numbers, and dashes." - }); - } - const value = this.#ensureSessionID(); - this.#cookies.set(this.#cookieName, value, this.#cookieConfig); - } - /** - * Attempts to load the session data from storage, or creates a new data object if none exists. - * If there is existing partial data, it will be merged into the new data object. - */ - async #ensureData() { - const storage = await this.#ensureStorage(); - if (this.#data && !this.#partial) { - return this.#data; - } - this.#data ??= /* @__PURE__ */ new Map(); - const raw = await storage.get(this.#ensureSessionID()); - if (!raw) { - return this.#data; - } - try { - const storedMap = unflatten(raw); - if (!(storedMap instanceof Map)) { - await this.destroy(); - throw new AstroError({ - ...SessionStorageInitError, - message: SessionStorageInitError.message( - "The session data was an invalid type.", - this.#config.driver - ) - }); - } - const now = Date.now(); - for (const [key, value] of storedMap) { - const expired = typeof value.expires === "number" && value.expires < now; - if (!this.#data.has(key) && !this.#toDelete.has(key) && !expired) { - this.#data.set(key, value); - } - } - this.#partial = false; - return this.#data; - } catch (err) { - await this.destroy(); - if (err instanceof AstroError) { - throw err; - } - throw new AstroError( - { - ...SessionStorageInitError, - message: SessionStorageInitError.message( - "The session data could not be parsed.", - this.#config.driver - ) - }, - { cause: err } - ); - } - } - /** - * Returns the session ID, generating a new one if it does not exist. - */ - #ensureSessionID() { - this.#sessionID ??= this.#cookies.get(this.#cookieName)?.value ?? crypto.randomUUID(); - return this.#sessionID; - } - /** - * Ensures the storage is initialized. - * This is called automatically when a storage operation is needed. - */ - async #ensureStorage() { - if (this.#storage) { - return this.#storage; - } - if (AstroSession.#sharedStorage.has(this.#config.driver)) { - this.#storage = AstroSession.#sharedStorage.get(this.#config.driver); - return this.#storage; - } - if (this.#config.driver === "test") { - this.#storage = this.#config.options.mockStorage; - return this.#storage; - } - if (this.#config.driver === "fs" || this.#config.driver === "fsLite" || this.#config.driver === "fs-lite") { - this.#config.options ??= {}; - this.#config.driver = "fs-lite"; - this.#config.options.base ??= ".astro/session"; - } - let driver = null; - try { - if (this.#config.driverModule) { - driver = (await this.#config.driverModule()).default; - } else if (this.#config.driver) { - const driverName = resolveSessionDriverName(this.#config.driver); - if (driverName) { - driver = (await import(driverName)).default; - } - } - } catch (err) { - if (err.code === "ERR_MODULE_NOT_FOUND") { - throw new AstroError( - { - ...SessionStorageInitError, - message: SessionStorageInitError.message( - err.message.includes(`Cannot find package`) ? "The driver module could not be found." : err.message, - this.#config.driver - ) - }, - { cause: err } - ); - } - throw err; - } - if (!driver) { - throw new AstroError({ - ...SessionStorageInitError, - message: SessionStorageInitError.message( - "The module did not export a driver.", - this.#config.driver - ) - }); - } - try { - this.#storage = createStorage({ - driver: driver(this.#config.options) - }); - AstroSession.#sharedStorage.set(this.#config.driver, this.#storage); - return this.#storage; - } catch (err) { - throw new AstroError( - { - ...SessionStorageInitError, - message: SessionStorageInitError.message("Unknown error", this.#config.driver) - }, - { cause: err } - ); - } - } -} -function resolveSessionDriverName(driver) { - if (!driver) { - return null; - } - try { - if (driver === "fs") { - return builtinDrivers.fsLite; - } - if (driver in builtinDrivers) { - return builtinDrivers[driver]; - } - } catch { - return null; - } - return driver; -} - -const apiContextRoutesSymbol = Symbol.for("context.routes"); -class RenderContext { - constructor(pipeline, locals, middleware, actions, pathname, request, routeData, status, clientAddress, cookies = new AstroCookies(request), params = getParams(routeData, pathname), url = new URL(request.url), props = {}, partial = void 0, shouldInjectCspMetaTags = !!pipeline.manifest.csp, session = pipeline.manifest.sessionConfig ? new AstroSession(cookies, pipeline.manifest.sessionConfig, pipeline.runtimeMode) : void 0) { - this.pipeline = pipeline; - this.locals = locals; - this.middleware = middleware; - this.actions = actions; - this.pathname = pathname; - this.request = request; - this.routeData = routeData; - this.status = status; - this.clientAddress = clientAddress; - this.cookies = cookies; - this.params = params; - this.url = url; - this.props = props; - this.partial = partial; - this.shouldInjectCspMetaTags = shouldInjectCspMetaTags; - this.session = session; - } - /** - * A flag that tells the render content if the rewriting was triggered - */ - isRewriting = false; - /** - * A safety net in case of loops - */ - counter = 0; - result = void 0; - static async create({ - locals = {}, - middleware, - pathname, - pipeline, - request, - routeData, - clientAddress, - status = 200, - props, - partial = void 0, - actions, - shouldInjectCspMetaTags - }) { - const pipelineMiddleware = await pipeline.getMiddleware(); - const pipelineActions = actions ?? await pipeline.getActions(); - setOriginPathname( - request, - pathname, - pipeline.manifest.trailingSlash, - pipeline.manifest.buildFormat - ); - return new RenderContext( - pipeline, - locals, - sequence(...pipeline.internalMiddleware, middleware ?? pipelineMiddleware), - pipelineActions, - pathname, - request, - routeData, - status, - clientAddress, - void 0, - void 0, - void 0, - props, - partial, - shouldInjectCspMetaTags ?? !!pipeline.manifest.csp - ); - } - /** - * The main function of the RenderContext. - * - * Use this function to render any route known to Astro. - * It attempts to render a route. A route can be a: - * - * - page - * - redirect - * - endpoint - * - fallback - */ - async render(componentInstance, slots = {}) { - const { middleware, pipeline } = this; - const { logger, serverLike, streaming, manifest } = pipeline; - const props = Object.keys(this.props).length > 0 ? this.props : await getProps({ - mod: componentInstance, - routeData: this.routeData, - routeCache: this.pipeline.routeCache, - pathname: this.pathname, - logger, - serverLike, - base: manifest.base - }); - const actionApiContext = this.createActionAPIContext(); - const apiContext = this.createAPIContext(props, actionApiContext); - this.counter++; - if (this.counter === 4) { - return new Response("Loop Detected", { - // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/508 - status: 508, - statusText: "Astro detected a loop where you tried to call the rewriting logic more than four times." - }); - } - const lastNext = async (ctx, payload) => { - if (payload) { - const oldPathname = this.pathname; - pipeline.logger.debug("router", "Called rewriting to:", payload); - const { - routeData, - componentInstance: newComponent, - pathname, - newUrl - } = await pipeline.tryRewrite(payload, this.request); - if (this.pipeline.serverLike === true && this.routeData.prerender === false && routeData.prerender === true) { - throw new AstroError({ - ...ForbiddenRewrite, - message: ForbiddenRewrite.message(this.pathname, pathname, routeData.component), - hint: ForbiddenRewrite.hint(routeData.component) - }); - } - this.routeData = routeData; - componentInstance = newComponent; - if (payload instanceof Request) { - this.request = payload; - } else { - this.request = copyRequest( - newUrl, - this.request, - // need to send the flag of the previous routeData - routeData.prerender, - this.pipeline.logger, - this.routeData.route - ); - } - this.isRewriting = true; - this.url = new URL(this.request.url); - this.params = getParams(routeData, pathname); - this.pathname = pathname; - this.status = 200; - setOriginPathname( - this.request, - oldPathname, - this.pipeline.manifest.trailingSlash, - this.pipeline.manifest.buildFormat - ); - } - let response2; - if (!ctx.isPrerendered) { - const { action, setActionResult, serializeActionResult } = getActionContext(ctx); - if (action?.calledFrom === "form") { - const actionResult = await action.handler(); - setActionResult(action.name, serializeActionResult(actionResult)); - } - } - switch (this.routeData.type) { - case "endpoint": { - response2 = await renderEndpoint( - componentInstance, - ctx, - this.routeData.prerender, - logger - ); - break; - } - case "redirect": - return renderRedirect(this); - case "page": { - this.result = await this.createResult(componentInstance, actionApiContext); - try { - response2 = await renderPage( - this.result, - componentInstance?.default, - props, - slots, - streaming, - this.routeData - ); - } catch (e) { - this.result.cancelled = true; - throw e; - } - response2.headers.set(ROUTE_TYPE_HEADER, "page"); - if (this.routeData.route === "/404" || this.routeData.route === "/500") { - response2.headers.set(REROUTE_DIRECTIVE_HEADER, "no"); - } - if (this.isRewriting) { - response2.headers.set(REWRITE_DIRECTIVE_HEADER_KEY, REWRITE_DIRECTIVE_HEADER_VALUE); - } - break; - } - case "fallback": { - return new Response(null, { status: 500, headers: { [ROUTE_TYPE_HEADER]: "fallback" } }); - } - } - const responseCookies = getCookiesFromResponse(response2); - if (responseCookies) { - this.cookies.merge(responseCookies); - } - return response2; - }; - if (isRouteExternalRedirect(this.routeData)) { - return renderRedirect(this); - } - const response = await callMiddleware(middleware, apiContext, lastNext); - if (response.headers.get(ROUTE_TYPE_HEADER)) { - response.headers.delete(ROUTE_TYPE_HEADER); - } - attachCookiesToResponse(response, this.cookies); - return response; - } - createAPIContext(props, context) { - const redirect = (path, status = 302) => new Response(null, { status, headers: { Location: path } }); - Reflect.set(context, apiContextRoutesSymbol, this.pipeline); - return Object.assign(context, { - props, - redirect, - getActionResult: createGetActionResult(context.locals), - callAction: createCallAction(context) - }); - } - async #executeRewrite(reroutePayload) { - this.pipeline.logger.debug("router", "Calling rewrite: ", reroutePayload); - const oldPathname = this.pathname; - const { routeData, componentInstance, newUrl, pathname } = await this.pipeline.tryRewrite( - reroutePayload, - this.request - ); - const isI18nFallback = routeData.fallbackRoutes && routeData.fallbackRoutes.length > 0; - if (this.pipeline.serverLike && !this.routeData.prerender && routeData.prerender && !isI18nFallback) { - throw new AstroError({ - ...ForbiddenRewrite, - message: ForbiddenRewrite.message(this.pathname, pathname, routeData.component), - hint: ForbiddenRewrite.hint(routeData.component) - }); - } - this.routeData = routeData; - if (reroutePayload instanceof Request) { - this.request = reroutePayload; - } else { - this.request = copyRequest( - newUrl, - this.request, - // need to send the flag of the previous routeData - routeData.prerender, - this.pipeline.logger, - this.routeData.route - ); - } - this.url = new URL(this.request.url); - const newCookies = new AstroCookies(this.request); - if (this.cookies) { - newCookies.merge(this.cookies); - } - this.cookies = newCookies; - this.params = getParams(routeData, pathname); - this.pathname = pathname; - this.isRewriting = true; - this.status = 200; - setOriginPathname( - this.request, - oldPathname, - this.pipeline.manifest.trailingSlash, - this.pipeline.manifest.buildFormat - ); - return await this.render(componentInstance); - } - createActionAPIContext() { - const renderContext = this; - const { params, pipeline, url } = this; - const generator = `Astro v${ASTRO_VERSION}`; - const rewrite = async (reroutePayload) => { - return await this.#executeRewrite(reroutePayload); - }; - return { - // Don't allow reassignment of cookies because it doesn't work - get cookies() { - return renderContext.cookies; - }, - routePattern: this.routeData.route, - isPrerendered: this.routeData.prerender, - get clientAddress() { - return renderContext.getClientAddress(); - }, - get currentLocale() { - return renderContext.computeCurrentLocale(); - }, - generator, - get locals() { - return renderContext.locals; - }, - set locals(_) { - throw new AstroError(LocalsReassigned); - }, - params, - get preferredLocale() { - return renderContext.computePreferredLocale(); - }, - get preferredLocaleList() { - return renderContext.computePreferredLocaleList(); - }, - rewrite, - request: this.request, - site: pipeline.site, - url, - get originPathname() { - return getOriginPathname(renderContext.request); - }, - get session() { - if (this.isPrerendered) { - pipeline.logger.warn( - "session", - `context.session was used when rendering the route ${colors.green(this.routePattern)}, but it is not available on prerendered routes. If you need access to sessions, make sure that the route is server-rendered using \`export const prerender = false;\` or by setting \`output\` to \`"server"\` in your Astro config to make all your routes server-rendered by default. For more information, see https://docs.astro.build/en/guides/sessions/` - ); - return void 0; - } - if (!renderContext.session) { - pipeline.logger.warn( - "session", - `context.session was used when rendering the route ${colors.green(this.routePattern)}, but no storage configuration was provided. Either configure the storage manually or use an adapter that provides session storage. For more information, see https://docs.astro.build/en/guides/sessions/` - ); - return void 0; - } - return renderContext.session; - }, - get csp() { - return { - insertDirective(payload) { - if (!pipeline.manifest.csp) { - throw new AstroError(CspNotEnabled); - } - renderContext.result?.directives.push(payload); - }, - insertScriptResource(resource) { - if (!pipeline.manifest.csp) { - throw new AstroError(CspNotEnabled); - } - renderContext.result?.scriptResources.push(resource); - }, - insertStyleResource(resource) { - if (!pipeline.manifest.csp) { - throw new AstroError(CspNotEnabled); - } - renderContext.result?.styleResources.push(resource); - }, - insertStyleHash(hash) { - if (!pipeline.manifest.csp) { - throw new AstroError(CspNotEnabled); - } - renderContext.result?.styleHashes.push(hash); - }, - insertScriptHash(hash) { - if (!pipeline.manifest.csp) { - throw new AstroError(CspNotEnabled); - } - renderContext.result?.scriptHashes.push(hash); - } - }; - } - }; - } - async createResult(mod, ctx) { - const { cookies, pathname, pipeline, routeData, status } = this; - const { clientDirectives, inlinedScripts, compressHTML, manifest, renderers, resolve } = pipeline; - const { links, scripts, styles } = await pipeline.headElements(routeData); - const extraStyleHashes = []; - const extraScriptHashes = []; - const shouldInjectCspMetaTags = this.shouldInjectCspMetaTags; - const cspAlgorithm = manifest.csp?.algorithm ?? "SHA-256"; - if (shouldInjectCspMetaTags) { - for (const style of styles) { - extraStyleHashes.push(await generateCspDigest(style.children, cspAlgorithm)); - } - for (const script of scripts) { - extraScriptHashes.push(await generateCspDigest(script.children, cspAlgorithm)); - } - } - const componentMetadata = await pipeline.componentMetadata(routeData) ?? manifest.componentMetadata; - const headers = new Headers({ "Content-Type": "text/html" }); - const partial = typeof this.partial === "boolean" ? this.partial : Boolean(mod.partial); - const actionResult = hasActionPayload(this.locals) ? deserializeActionResult(this.locals._actionPayload.actionResult) : void 0; - const response = { - status: actionResult?.error ? actionResult?.error.status : status, - statusText: actionResult?.error ? actionResult?.error.type : "OK", - get headers() { - return headers; - }, - // Disallow `Astro.response.headers = new Headers` - set headers(_) { - throw new AstroError(AstroResponseHeadersReassigned); - } - }; - const result = { - base: manifest.base, - userAssetsBase: manifest.userAssetsBase, - cancelled: false, - clientDirectives, - inlinedScripts, - componentMetadata, - compressHTML, - cookies, - /** This function returns the `Astro` faux-global */ - createAstro: (astroGlobal, props, slots) => this.createAstro(result, astroGlobal, props, slots, ctx), - links, - params: this.params, - partial, - pathname, - renderers, - resolve, - response, - request: this.request, - scripts, - styles, - actionResult, - serverIslandNameMap: manifest.serverIslandNameMap ?? /* @__PURE__ */ new Map(), - key: manifest.key, - trailingSlash: manifest.trailingSlash, - _metadata: { - hasHydrationScript: false, - rendererSpecificHydrationScripts: /* @__PURE__ */ new Set(), - hasRenderedHead: false, - renderedScripts: /* @__PURE__ */ new Set(), - hasDirectives: /* @__PURE__ */ new Set(), - hasRenderedServerIslandRuntime: false, - headInTree: false, - extraHead: [], - extraStyleHashes, - extraScriptHashes, - propagators: /* @__PURE__ */ new Set() - }, - cspDestination: manifest.csp?.cspDestination ?? (routeData.prerender ? "meta" : "header"), - shouldInjectCspMetaTags, - cspAlgorithm, - // The following arrays must be cloned, otherwise they become mutable across routes. - scriptHashes: manifest.csp?.scriptHashes ? [...manifest.csp.scriptHashes] : [], - scriptResources: manifest.csp?.scriptResources ? [...manifest.csp.scriptResources] : [], - styleHashes: manifest.csp?.styleHashes ? [...manifest.csp.styleHashes] : [], - styleResources: manifest.csp?.styleResources ? [...manifest.csp.styleResources] : [], - directives: manifest.csp?.directives ? [...manifest.csp.directives] : [], - isStrictDynamic: manifest.csp?.isStrictDynamic ?? false, - internalFetchHeaders: manifest.internalFetchHeaders - }; - return result; - } - #astroPagePartial; - /** - * The Astro global is sourced in 3 different phases: - * - **Static**: `.generator` and `.glob` is printed by the compiler, instantiated once per process per astro file - * - **Page-level**: `.request`, `.cookies`, `.locals` etc. These remain the same for the duration of the request. - * - **Component-level**: `.props`, `.slots`, and `.self` are unique to each _use_ of each component. - * - * The page level partial is used as the prototype of the user-visible `Astro` global object, which is instantiated once per use of a component. - */ - createAstro(result, astroStaticPartial, props, slotValues, apiContext) { - let astroPagePartial; - if (this.isRewriting) { - astroPagePartial = this.#astroPagePartial = this.createAstroPagePartial( - result, - astroStaticPartial, - apiContext - ); - } else { - astroPagePartial = this.#astroPagePartial ??= this.createAstroPagePartial( - result, - astroStaticPartial, - apiContext - ); - } - const astroComponentPartial = { props, self: null }; - const Astro = Object.assign( - Object.create(astroPagePartial), - astroComponentPartial - ); - let _slots; - Object.defineProperty(Astro, "slots", { - get: () => { - if (!_slots) { - _slots = new Slots( - result, - slotValues, - this.pipeline.logger - ); - } - return _slots; - } - }); - return Astro; - } - createAstroPagePartial(result, astroStaticPartial, apiContext) { - const renderContext = this; - const { cookies, locals, params, pipeline, url } = this; - const { response } = result; - const redirect = (path, status = 302) => { - if (this.request[responseSentSymbol$1]) { - throw new AstroError({ - ...ResponseSentError - }); - } - return new Response(null, { status, headers: { Location: path } }); - }; - const rewrite = async (reroutePayload) => { - return await this.#executeRewrite(reroutePayload); - }; - const callAction = createCallAction(apiContext); - return { - generator: astroStaticPartial.generator, - glob: astroStaticPartial.glob, - routePattern: this.routeData.route, - isPrerendered: this.routeData.prerender, - cookies, - get session() { - if (this.isPrerendered) { - pipeline.logger.warn( - "session", - `Astro.session was used when rendering the route ${colors.green(this.routePattern)}, but it is not available on prerendered pages. If you need access to sessions, make sure that the page is server-rendered using \`export const prerender = false;\` or by setting \`output\` to \`"server"\` in your Astro config to make all your pages server-rendered by default. For more information, see https://docs.astro.build/en/guides/sessions/` - ); - return void 0; - } - if (!renderContext.session) { - pipeline.logger.warn( - "session", - `Astro.session was used when rendering the route ${colors.green(this.routePattern)}, but no storage configuration was provided. Either configure the storage manually or use an adapter that provides session storage. For more information, see https://docs.astro.build/en/guides/sessions/` - ); - return void 0; - } - return renderContext.session; - }, - get clientAddress() { - return renderContext.getClientAddress(); - }, - get currentLocale() { - return renderContext.computeCurrentLocale(); - }, - params, - get preferredLocale() { - return renderContext.computePreferredLocale(); - }, - get preferredLocaleList() { - return renderContext.computePreferredLocaleList(); - }, - locals, - redirect, - rewrite, - request: this.request, - response, - site: pipeline.site, - getActionResult: createGetActionResult(locals), - get callAction() { - return callAction; - }, - url, - get originPathname() { - return getOriginPathname(renderContext.request); - }, - get csp() { - return { - insertDirective(payload) { - if (!pipeline.manifest.csp) { - throw new AstroError(CspNotEnabled); - } - renderContext.result?.directives.push(payload); - }, - insertScriptResource(resource) { - if (!pipeline.manifest.csp) { - throw new AstroError(CspNotEnabled); - } - renderContext.result?.scriptResources.push(resource); - }, - insertStyleResource(resource) { - if (!pipeline.manifest.csp) { - throw new AstroError(CspNotEnabled); - } - renderContext.result?.styleResources.push(resource); - }, - insertStyleHash(hash) { - if (!pipeline.manifest.csp) { - throw new AstroError(CspNotEnabled); - } - renderContext.result?.styleHashes.push(hash); - }, - insertScriptHash(hash) { - if (!pipeline.manifest.csp) { - throw new AstroError(CspNotEnabled); - } - renderContext.result?.scriptHashes.push(hash); - } - }; - } - }; - } - getClientAddress() { - const { pipeline, request, routeData, clientAddress } = this; - if (routeData.prerender) { - throw new AstroError({ - ...PrerenderClientAddressNotAvailable, - message: PrerenderClientAddressNotAvailable.message(routeData.component) - }); - } - if (clientAddress) { - return clientAddress; - } - if (clientAddressSymbol in request) { - return Reflect.get(request, clientAddressSymbol); - } - if (pipeline.adapterName) { - throw new AstroError({ - ...ClientAddressNotAvailable, - message: ClientAddressNotAvailable.message(pipeline.adapterName) - }); - } - throw new AstroError(StaticClientAddressNotAvailable); - } - /** - * API Context may be created multiple times per request, i18n data needs to be computed only once. - * So, it is computed and saved here on creation of the first APIContext and reused for later ones. - */ - #currentLocale; - computeCurrentLocale() { - const { - url, - pipeline: { i18n }, - routeData - } = this; - if (!i18n) return; - const { defaultLocale, locales, strategy } = i18n; - const fallbackTo = strategy === "pathname-prefix-other-locales" || strategy === "domains-prefix-other-locales" ? defaultLocale : void 0; - if (this.#currentLocale) { - return this.#currentLocale; - } - let computedLocale; - if (isRouteServerIsland(routeData)) { - let referer = this.request.headers.get("referer"); - if (referer) { - if (URL.canParse(referer)) { - referer = new URL(referer).pathname; - } - computedLocale = computeCurrentLocale(referer, locales, defaultLocale); - } - } else { - let pathname = routeData.pathname; - if (!routeData.pattern.test(url.pathname)) { - for (const fallbackRoute of routeData.fallbackRoutes) { - if (fallbackRoute.pattern.test(url.pathname)) { - pathname = fallbackRoute.pathname; - break; - } - } - } - pathname = pathname && !isRoute404or500(routeData) ? pathname : url.pathname; - computedLocale = computeCurrentLocale(pathname, locales, defaultLocale); - } - this.#currentLocale = computedLocale ?? fallbackTo; - return this.#currentLocale; - } - #preferredLocale; - computePreferredLocale() { - const { - pipeline: { i18n }, - request - } = this; - if (!i18n) return; - return this.#preferredLocale ??= computePreferredLocale(request, i18n.locales); - } - #preferredLocaleList; - computePreferredLocaleList() { - const { - pipeline: { i18n }, - request - } = this; - if (!i18n) return; - return this.#preferredLocaleList ??= computePreferredLocaleList(request, i18n.locales); - } -} - -function redirectTemplate({ - status, - absoluteLocation, - relativeLocation, - from -}) { - const delay = status === 302 ? 2 : 0; - return ` -Redirecting to: ${relativeLocation} - - - - - Redirecting ${from ? `from ${from} ` : ""}to ${relativeLocation} -`; -} - -class AppPipeline extends Pipeline { - static create({ - logger, - manifest, - runtimeMode, - renderers, - resolve, - serverLike, - streaming, - defaultRoutes - }) { - const pipeline = new AppPipeline( - logger, - manifest, - runtimeMode, - renderers, - resolve, - serverLike, - streaming, - void 0, - void 0, - void 0, - void 0, - void 0, - void 0, - void 0, - void 0, - defaultRoutes - ); - return pipeline; - } - headElements(routeData) { - const routeInfo = this.manifest.routes.find((route) => route.routeData === routeData); - const links = /* @__PURE__ */ new Set(); - const scripts = /* @__PURE__ */ new Set(); - const styles = createStylesheetElementSet(routeInfo?.styles ?? []); - for (const script of routeInfo?.scripts ?? []) { - if ("stage" in script) { - if (script.stage === "head-inline") { - scripts.add({ - props: {}, - children: script.children - }); - } - } else { - scripts.add(createModuleScriptElement(script)); - } - } - return { links, styles, scripts }; - } - componentMetadata() { - } - async getComponentByRoute(routeData) { - const module = await this.getModuleForRoute(routeData); - return module.page(); - } - async tryRewrite(payload, request) { - const { newUrl, pathname, routeData } = findRouteToRewrite({ - payload, - request, - routes: this.manifest?.routes.map((r) => r.routeData), - trailingSlash: this.manifest.trailingSlash, - buildFormat: this.manifest.buildFormat, - base: this.manifest.base, - outDir: this.serverLike ? this.manifest.buildClientDir : this.manifest.outDir - }); - const componentInstance = await this.getComponentByRoute(routeData); - return { newUrl, pathname, componentInstance, routeData }; - } - async getModuleForRoute(route) { - for (const defaultRoute of this.defaultRoutes) { - if (route.component === defaultRoute.component) { - return { - page: () => Promise.resolve(defaultRoute.instance), - renderers: [] - }; - } - } - if (route.type === "redirect") { - return RedirectSinglePageBuiltModule; - } else { - if (this.manifest.pageMap) { - const importComponentInstance = this.manifest.pageMap.get(route.component); - if (!importComponentInstance) { - throw new Error( - `Unexpectedly unable to find a component instance for route ${route.route}` - ); - } - return await importComponentInstance(); - } else if (this.manifest.pageModule) { - return this.manifest.pageModule; - } - throw new Error( - "Astro couldn't find the correct page to render, probably because it wasn't correctly mapped for SSR usage. This is an internal error, please file an issue." - ); - } - } -} - -class App { - #manifest; - #manifestData; - #logger = new Logger({ - dest: consoleLogDestination, - level: "info" - }); - #baseWithoutTrailingSlash; - #pipeline; - #adapterLogger; - constructor(manifest, streaming = true) { - this.#manifest = manifest; - this.#manifestData = { - routes: manifest.routes.map((route) => route.routeData) - }; - ensure404Route(this.#manifestData); - this.#baseWithoutTrailingSlash = removeTrailingForwardSlash(this.#manifest.base); - this.#pipeline = this.#createPipeline(streaming); - this.#adapterLogger = new AstroIntegrationLogger( - this.#logger.options, - this.#manifest.adapterName - ); - } - getAdapterLogger() { - return this.#adapterLogger; - } - getAllowedDomains() { - return this.#manifest.allowedDomains; - } - get manifest() { - return this.#manifest; - } - set manifest(value) { - this.#manifest = value; - } - matchesAllowedDomains(forwardedHost, protocol) { - return App.validateForwardedHost(forwardedHost, this.#manifest.allowedDomains, protocol); - } - static validateForwardedHost(forwardedHost, allowedDomains, protocol) { - if (!allowedDomains || allowedDomains.length === 0) { - return false; - } - try { - const testUrl = new URL(`${protocol || "https"}://${forwardedHost}`); - return allowedDomains.some((pattern) => { - return matchPattern(testUrl, pattern); - }); - } catch { - return false; - } - } - /** - * Validate a hostname by rejecting any with path separators. - * Prevents path injection attacks. Invalid hostnames return undefined. - */ - static sanitizeHost(hostname) { - if (!hostname) return void 0; - if (/[/\\]/.test(hostname)) return void 0; - return hostname; - } - /** - * Validate forwarded headers (proto, host, port) against allowedDomains. - * Returns validated values or undefined for rejected headers. - * Uses strict defaults: http/https only for proto, rejects port if not in allowedDomains. - */ - static validateForwardedHeaders(forwardedProtocol, forwardedHost, forwardedPort, allowedDomains) { - const result = {}; - if (forwardedProtocol) { - if (allowedDomains && allowedDomains.length > 0) { - const hasProtocolPatterns = allowedDomains.some( - (pattern) => pattern.protocol !== void 0 - ); - if (hasProtocolPatterns) { - try { - const testUrl = new URL(`${forwardedProtocol}://example.com`); - const isAllowed = allowedDomains.some((pattern) => matchPattern(testUrl, pattern)); - if (isAllowed) { - result.protocol = forwardedProtocol; - } - } catch { - } - } else if (/^https?$/.test(forwardedProtocol)) { - result.protocol = forwardedProtocol; - } - } else if (/^https?$/.test(forwardedProtocol)) { - result.protocol = forwardedProtocol; - } - } - if (forwardedPort && allowedDomains && allowedDomains.length > 0) { - const hasPortPatterns = allowedDomains.some((pattern) => pattern.port !== void 0); - if (hasPortPatterns) { - const isAllowed = allowedDomains.some((pattern) => pattern.port === forwardedPort); - if (isAllowed) { - result.port = forwardedPort; - } - } - } - if (forwardedHost && forwardedHost.length > 0 && allowedDomains && allowedDomains.length > 0) { - const protoForValidation = result.protocol || "https"; - const sanitized = App.sanitizeHost(forwardedHost); - if (sanitized) { - try { - const hostnameOnly = sanitized.split(":")[0]; - const portFromHost = sanitized.includes(":") ? sanitized.split(":")[1] : void 0; - const portForValidation = result.port || portFromHost; - const hostWithPort = portForValidation ? `${hostnameOnly}:${portForValidation}` : hostnameOnly; - const testUrl = new URL(`${protoForValidation}://${hostWithPort}`); - const isAllowed = allowedDomains.some((pattern) => matchPattern(testUrl, pattern)); - if (isAllowed) { - result.host = sanitized; - } - } catch { - } - } - } - return result; - } - /** - * Creates a pipeline by reading the stored manifest - * - * @param streaming - * @private - */ - #createPipeline(streaming = false) { - return AppPipeline.create({ - logger: this.#logger, - manifest: this.#manifest, - runtimeMode: "production", - renderers: this.#manifest.renderers, - defaultRoutes: createDefaultRoutes(this.#manifest), - resolve: async (specifier) => { - if (!(specifier in this.#manifest.entryModules)) { - throw new Error(`Unable to resolve [${specifier}]`); - } - const bundlePath = this.#manifest.entryModules[specifier]; - if (bundlePath.startsWith("data:") || bundlePath.length === 0) { - return bundlePath; - } else { - return createAssetLink(bundlePath, this.#manifest.base, this.#manifest.assetsPrefix); - } - }, - serverLike: true, - streaming - }); - } - set setManifestData(newManifestData) { - this.#manifestData = newManifestData; - } - removeBase(pathname) { - if (pathname.startsWith(this.#manifest.base)) { - return pathname.slice(this.#baseWithoutTrailingSlash.length + 1); - } - return pathname; - } - /** - * It removes the base from the request URL, prepends it with a forward slash and attempts to decoded it. - * - * If the decoding fails, it logs the error and return the pathname as is. - * @param request - * @private - */ - #getPathnameFromRequest(request) { - const url = new URL(request.url); - const pathname = prependForwardSlash$1(this.removeBase(url.pathname)); - try { - return decodeURI(pathname); - } catch (e) { - this.getAdapterLogger().error(e.toString()); - return pathname; - } - } - /** - * Given a `Request`, it returns the `RouteData` that matches its `pathname`. By default, prerendered - * routes aren't returned, even if they are matched. - * - * When `allowPrerenderedRoutes` is `true`, the function returns matched prerendered routes too. - * @param request - * @param allowPrerenderedRoutes - */ - match(request, allowPrerenderedRoutes = false) { - const url = new URL(request.url); - if (this.#manifest.assets.has(url.pathname)) return void 0; - let pathname = this.#computePathnameFromDomain(request); - if (!pathname) { - pathname = prependForwardSlash$1(this.removeBase(url.pathname)); - } - let routeData = matchRoute(decodeURI(pathname), this.#manifestData); - if (!routeData) return void 0; - if (allowPrerenderedRoutes) { - return routeData; - } else if (routeData.prerender) { - return void 0; - } - return routeData; - } - #computePathnameFromDomain(request) { - let pathname = void 0; - const url = new URL(request.url); - if (this.#manifest.i18n && (this.#manifest.i18n.strategy === "domains-prefix-always" || this.#manifest.i18n.strategy === "domains-prefix-other-locales" || this.#manifest.i18n.strategy === "domains-prefix-always-no-redirect")) { - const validated = App.validateForwardedHeaders( - request.headers.get("X-Forwarded-Proto") ?? void 0, - request.headers.get("X-Forwarded-Host") ?? void 0, - request.headers.get("X-Forwarded-Port") ?? void 0, - this.#manifest.allowedDomains - ); - let protocol = validated.protocol ? validated.protocol + ":" : url.protocol; - let host = validated.host ?? request.headers.get("Host"); - if (host && protocol) { - host = host.split(":")[0]; - try { - let locale; - const hostAsUrl = new URL(`${protocol}//${host}`); - for (const [domainKey, localeValue] of Object.entries( - this.#manifest.i18n.domainLookupTable - )) { - const domainKeyAsUrl = new URL(domainKey); - if (hostAsUrl.host === domainKeyAsUrl.host && hostAsUrl.protocol === domainKeyAsUrl.protocol) { - locale = localeValue; - break; - } - } - if (locale) { - pathname = prependForwardSlash$1( - joinPaths(normalizeTheLocale(locale), this.removeBase(url.pathname)) - ); - if (url.pathname.endsWith("/")) { - pathname = appendForwardSlash$1(pathname); - } - } - } catch (e) { - this.#logger.error( - "router", - `Astro tried to parse ${protocol}//${host} as an URL, but it threw a parsing error. Check the X-Forwarded-Host and X-Forwarded-Proto headers.` - ); - this.#logger.error("router", `Error: ${e}`); - } - } - } - return pathname; - } - #redirectTrailingSlash(pathname) { - const { trailingSlash } = this.#manifest; - if (pathname === "/" || isInternalPath(pathname)) { - return pathname; - } - const path = collapseDuplicateTrailingSlashes(pathname, trailingSlash !== "never"); - if (path !== pathname) { - return path; - } - if (trailingSlash === "ignore") { - return pathname; - } - if (trailingSlash === "always" && !hasFileExtension(pathname)) { - return appendForwardSlash$1(pathname); - } - if (trailingSlash === "never") { - return removeTrailingForwardSlash(pathname); - } - return pathname; - } - async render(request, renderOptions) { - let routeData; - let locals; - let clientAddress; - let addCookieHeader; - const url = new URL(request.url); - const redirect = this.#redirectTrailingSlash(url.pathname); - const prerenderedErrorPageFetch = renderOptions?.prerenderedErrorPageFetch ?? fetch; - if (redirect !== url.pathname) { - const status = request.method === "GET" ? 301 : 308; - return new Response( - redirectTemplate({ - status, - relativeLocation: url.pathname, - absoluteLocation: redirect, - from: request.url - }), - { - status, - headers: { - location: redirect + url.search - } - } - ); - } - addCookieHeader = renderOptions?.addCookieHeader; - clientAddress = renderOptions?.clientAddress ?? Reflect.get(request, clientAddressSymbol); - routeData = renderOptions?.routeData; - locals = renderOptions?.locals; - if (routeData) { - this.#logger.debug( - "router", - "The adapter " + this.#manifest.adapterName + " provided a custom RouteData for ", - request.url - ); - this.#logger.debug("router", "RouteData:\n" + routeData); - } - if (locals) { - if (typeof locals !== "object") { - const error = new AstroError(LocalsNotAnObject); - this.#logger.error(null, error.stack); - return this.#renderError(request, { - status: 500, - error, - clientAddress, - prerenderedErrorPageFetch - }); - } - } - if (!routeData) { - routeData = this.match(request); - this.#logger.debug("router", "Astro matched the following route for " + request.url); - this.#logger.debug("router", "RouteData:\n" + routeData); - } - if (!routeData) { - routeData = this.#manifestData.routes.find( - (route) => route.component === "404.astro" || route.component === DEFAULT_404_COMPONENT - ); - } - if (!routeData) { - this.#logger.debug("router", "Astro hasn't found routes that match " + request.url); - this.#logger.debug("router", "Here's the available routes:\n", this.#manifestData); - return this.#renderError(request, { - locals, - status: 404, - clientAddress, - prerenderedErrorPageFetch - }); - } - const pathname = this.#getPathnameFromRequest(request); - const defaultStatus = this.#getDefaultStatusCode(routeData, pathname); - let response; - let session; - try { - const mod = await this.#pipeline.getModuleForRoute(routeData); - const renderContext = await RenderContext.create({ - pipeline: this.#pipeline, - locals, - pathname, - request, - routeData, - status: defaultStatus, - clientAddress - }); - session = renderContext.session; - response = await renderContext.render(await mod.page()); - } catch (err) { - this.#logger.error(null, err.stack || err.message || String(err)); - return this.#renderError(request, { - locals, - status: 500, - error: err, - clientAddress, - prerenderedErrorPageFetch - }); - } finally { - await session?.[PERSIST_SYMBOL](); - } - if (REROUTABLE_STATUS_CODES.includes(response.status) && response.headers.get(REROUTE_DIRECTIVE_HEADER) !== "no") { - return this.#renderError(request, { - locals, - response, - status: response.status, - // We don't have an error to report here. Passing null means we pass nothing intentionally - // while undefined means there's no error - error: response.status === 500 ? null : void 0, - clientAddress, - prerenderedErrorPageFetch - }); - } - if (response.headers.has(REROUTE_DIRECTIVE_HEADER)) { - response.headers.delete(REROUTE_DIRECTIVE_HEADER); - } - if (addCookieHeader) { - for (const setCookieHeaderValue of App.getSetCookieFromResponse(response)) { - response.headers.append("set-cookie", setCookieHeaderValue); - } - } - Reflect.set(response, responseSentSymbol$1, true); - return response; - } - setCookieHeaders(response) { - return getSetCookiesFromResponse(response); - } - /** - * Reads all the cookies written by `Astro.cookie.set()` onto the passed response. - * For example, - * ```ts - * for (const cookie_ of App.getSetCookieFromResponse(response)) { - * const cookie: string = cookie_ - * } - * ``` - * @param response The response to read cookies from. - * @returns An iterator that yields key-value pairs as equal-sign-separated strings. - */ - static getSetCookieFromResponse = getSetCookiesFromResponse; - /** - * If it is a known error code, try sending the according page (e.g. 404.astro / 500.astro). - * This also handles pre-rendered /404 or /500 routes - */ - async #renderError(request, { - locals, - status, - response: originalResponse, - skipMiddleware = false, - error, - clientAddress, - prerenderedErrorPageFetch - }) { - const errorRoutePath = `/${status}${this.#manifest.trailingSlash === "always" ? "/" : ""}`; - const errorRouteData = matchRoute(errorRoutePath, this.#manifestData); - const url = new URL(request.url); - if (errorRouteData) { - if (errorRouteData.prerender) { - const maybeDotHtml = errorRouteData.route.endsWith(`/${status}`) ? ".html" : ""; - const statusURL = new URL( - `${this.#baseWithoutTrailingSlash}/${status}${maybeDotHtml}`, - url - ); - if (statusURL.toString() !== request.url) { - const response2 = await prerenderedErrorPageFetch(statusURL.toString()); - const override = { status, removeContentEncodingHeaders: true }; - return this.#mergeResponses(response2, originalResponse, override); - } - } - const mod = await this.#pipeline.getModuleForRoute(errorRouteData); - let session; - try { - const renderContext = await RenderContext.create({ - locals, - pipeline: this.#pipeline, - middleware: skipMiddleware ? NOOP_MIDDLEWARE_FN : void 0, - pathname: this.#getPathnameFromRequest(request), - request, - routeData: errorRouteData, - status, - props: { error }, - clientAddress - }); - session = renderContext.session; - const response2 = await renderContext.render(await mod.page()); - return this.#mergeResponses(response2, originalResponse); - } catch { - if (skipMiddleware === false) { - return this.#renderError(request, { - locals, - status, - response: originalResponse, - skipMiddleware: true, - clientAddress, - prerenderedErrorPageFetch - }); - } - } finally { - await session?.[PERSIST_SYMBOL](); - } - } - const response = this.#mergeResponses(new Response(null, { status }), originalResponse); - Reflect.set(response, responseSentSymbol$1, true); - return response; - } - #mergeResponses(newResponse, originalResponse, override) { - let newResponseHeaders = newResponse.headers; - if (override?.removeContentEncodingHeaders) { - newResponseHeaders = new Headers(newResponseHeaders); - newResponseHeaders.delete("Content-Encoding"); - newResponseHeaders.delete("Content-Length"); - } - if (!originalResponse) { - if (override !== void 0) { - return new Response(newResponse.body, { - status: override.status, - statusText: newResponse.statusText, - headers: newResponseHeaders - }); - } - return newResponse; - } - const status = override?.status ? override.status : originalResponse.status === 200 ? newResponse.status : originalResponse.status; - try { - originalResponse.headers.delete("Content-type"); - } catch { - } - const mergedHeaders = new Map([ - ...Array.from(newResponseHeaders), - ...Array.from(originalResponse.headers) - ]); - const newHeaders = new Headers(); - for (const [name, value] of mergedHeaders) { - newHeaders.set(name, value); - } - return new Response(newResponse.body, { - status, - statusText: status === 200 ? newResponse.statusText : originalResponse.statusText, - // If you're looking at here for possible bugs, it means that it's not a bug. - // With the middleware, users can meddle with headers, and we should pass to the 404/500. - // If users see something weird, it's because they are setting some headers they should not. - // - // Although, we don't want it to replace the content-type, because the error page must return `text/html` - headers: newHeaders - }); - } - #getDefaultStatusCode(routeData, pathname) { - if (!routeData.pattern.test(pathname)) { - for (const fallbackRoute of routeData.fallbackRoutes) { - if (fallbackRoute.pattern.test(pathname)) { - return 302; - } - } - } - const route = removeTrailingForwardSlash(routeData.route); - if (route.endsWith("/404")) return 404; - if (route.endsWith("/500")) return 500; - return 200; - } -} - -const createOutgoingHttpHeaders = (headers) => { - if (!headers) { - return void 0; - } - const nodeHeaders = Object.fromEntries(headers.entries()); - if (Object.keys(nodeHeaders).length === 0) { - return void 0; - } - if (headers.has("set-cookie")) { - const cookieHeaders = headers.getSetCookie(); - if (cookieHeaders.length > 1) { - nodeHeaders["set-cookie"] = cookieHeaders; - } - } - return nodeHeaders; -}; - -function apply() { - if (!globalThis.crypto) { - Object.defineProperty(globalThis, "crypto", { - value: crypto$1.webcrypto - }); - } - if (!globalThis.File) { - Object.defineProperty(globalThis, "File", { - value: require$$0$3.File - }); - } -} - -class NodeApp extends App { - headersMap = void 0; - setHeadersMap(headers) { - this.headersMap = headers; - } - match(req, allowPrerenderedRoutes = false) { - if (!(req instanceof Request)) { - req = NodeApp.createRequest(req, { - skipBody: true, - allowedDomains: this.manifest.allowedDomains - }); - } - return super.match(req, allowPrerenderedRoutes); - } - render(req, routeDataOrOptions, maybeLocals) { - if (!(req instanceof Request)) { - req = NodeApp.createRequest(req, { - allowedDomains: this.manifest.allowedDomains - }); - } - return super.render(req, routeDataOrOptions, maybeLocals); - } - /** - * Converts a NodeJS IncomingMessage into a web standard Request. - * ```js - * import { NodeApp } from 'astro/app/node'; - * import { createServer } from 'node:http'; - * - * const server = createServer(async (req, res) => { - * const request = NodeApp.createRequest(req); - * const response = await app.render(request); - * await NodeApp.writeResponse(response, res); - * }) - * ``` - */ - static createRequest(req, { - skipBody = false, - allowedDomains = [] - } = {}) { - const controller = new AbortController(); - const isEncrypted = "encrypted" in req.socket && req.socket.encrypted; - const getFirstForwardedValue = (multiValueHeader) => { - return multiValueHeader?.toString()?.split(",").map((e) => e.trim())?.[0]; - }; - const providedProtocol = isEncrypted ? "https" : "http"; - const providedHostname = req.headers.host ?? req.headers[":authority"]; - const validated = App.validateForwardedHeaders( - getFirstForwardedValue(req.headers["x-forwarded-proto"]), - getFirstForwardedValue(req.headers["x-forwarded-host"]), - getFirstForwardedValue(req.headers["x-forwarded-port"]), - allowedDomains - ); - const protocol = validated.protocol ?? providedProtocol; - const sanitizedProvidedHostname = App.sanitizeHost( - typeof providedHostname === "string" ? providedHostname : void 0 - ); - const hostname = validated.host ?? sanitizedProvidedHostname; - const port = validated.port; - let url; - try { - const hostnamePort = getHostnamePort(hostname, port); - url = new URL(`${protocol}://${hostnamePort}${req.url}`); - } catch { - const hostnamePort = getHostnamePort(providedHostname, port); - url = new URL(`${providedProtocol}://${hostnamePort}`); - } - const options = { - method: req.method || "GET", - headers: makeRequestHeaders(req), - signal: controller.signal - }; - const bodyAllowed = options.method !== "HEAD" && options.method !== "GET" && skipBody === false; - if (bodyAllowed) { - Object.assign(options, makeRequestBody(req)); - } - const request = new Request(url, options); - const socket = getRequestSocket(req); - if (socket && typeof socket.on === "function") { - const existingCleanup = getAbortControllerCleanup(req); - if (existingCleanup) { - existingCleanup(); - } - let cleanedUp = false; - const removeSocketListener = () => { - if (typeof socket.off === "function") { - socket.off("close", onSocketClose); - } else if (typeof socket.removeListener === "function") { - socket.removeListener("close", onSocketClose); - } - }; - const cleanup = () => { - if (cleanedUp) return; - cleanedUp = true; - removeSocketListener(); - controller.signal.removeEventListener("abort", cleanup); - Reflect.deleteProperty(req, nodeRequestAbortControllerCleanupSymbol); - }; - const onSocketClose = () => { - cleanup(); - if (!controller.signal.aborted) { - controller.abort(); - } - }; - socket.on("close", onSocketClose); - controller.signal.addEventListener("abort", cleanup, { once: true }); - Reflect.set(req, nodeRequestAbortControllerCleanupSymbol, cleanup); - if (socket.destroyed) { - onSocketClose(); - } - } - const forwardedClientIp = getFirstForwardedValue(req.headers["x-forwarded-for"]); - const clientIp = forwardedClientIp || req.socket?.remoteAddress; - if (clientIp) { - Reflect.set(request, clientAddressSymbol, clientIp); - } - return request; - } - /** - * Streams a web-standard Response into a NodeJS Server Response. - * ```js - * import { NodeApp } from 'astro/app/node'; - * import { createServer } from 'node:http'; - * - * const server = createServer(async (req, res) => { - * const request = NodeApp.createRequest(req); - * const response = await app.render(request); - * await NodeApp.writeResponse(response, res); - * }) - * ``` - * @param source WhatWG Response - * @param destination NodeJS ServerResponse - */ - static async writeResponse(source, destination) { - const { status, headers, body, statusText } = source; - if (!(destination instanceof Http2ServerResponse)) { - destination.statusMessage = statusText; - } - destination.writeHead(status, createOutgoingHttpHeaders(headers)); - const cleanupAbortFromDestination = getAbortControllerCleanup( - destination.req ?? void 0 - ); - if (cleanupAbortFromDestination) { - const runCleanup = () => { - cleanupAbortFromDestination(); - if (typeof destination.off === "function") { - destination.off("finish", runCleanup); - destination.off("close", runCleanup); - } else { - destination.removeListener?.("finish", runCleanup); - destination.removeListener?.("close", runCleanup); - } - }; - destination.on("finish", runCleanup); - destination.on("close", runCleanup); - } - if (!body) return destination.end(); - try { - const reader = body.getReader(); - destination.on("close", () => { - reader.cancel().catch((err) => { - console.error( - `There was an uncaught error in the middle of the stream while rendering ${destination.req.url}.`, - err - ); - }); - }); - let result = await reader.read(); - while (!result.done) { - destination.write(result.value); - result = await reader.read(); - } - destination.end(); - } catch (err) { - destination.write("Internal server error", () => { - err instanceof Error ? destination.destroy(err) : destination.destroy(); - }); - } - } -} -function getHostnamePort(hostname, port) { - const portInHostname = typeof hostname === "string" && /:\d+$/.test(hostname); - const hostnamePort = portInHostname ? hostname : `${hostname}${port ? `:${port}` : ""}`; - return hostnamePort; -} -function makeRequestHeaders(req) { - const headers = new Headers(); - for (const [name, value] of Object.entries(req.headers)) { - if (value === void 0) { - continue; - } - if (Array.isArray(value)) { - for (const item of value) { - headers.append(name, item); - } - } else { - headers.append(name, value); - } - } - return headers; -} -function makeRequestBody(req) { - if (req.body !== void 0) { - if (typeof req.body === "string" && req.body.length > 0) { - return { body: Buffer.from(req.body) }; - } - if (typeof req.body === "object" && req.body !== null && Object.keys(req.body).length > 0) { - return { body: Buffer.from(JSON.stringify(req.body)) }; - } - if (typeof req.body === "object" && req.body !== null && typeof req.body[Symbol.asyncIterator] !== "undefined") { - return asyncIterableToBodyProps(req.body); - } - } - return asyncIterableToBodyProps(req); -} -function asyncIterableToBodyProps(iterable) { - return { - // Node uses undici for the Request implementation. Undici accepts - // a non-standard async iterable for the body. - // @ts-expect-error - body: iterable, - // The duplex property is required when using a ReadableStream or async - // iterable for the body. The type definitions do not include the duplex - // property because they are not up-to-date. - duplex: "half" - }; -} -function getAbortControllerCleanup(req) { - if (!req) return void 0; - const cleanup = Reflect.get(req, nodeRequestAbortControllerCleanupSymbol); - return typeof cleanup === "function" ? cleanup : void 0; -} -function getRequestSocket(req) { - if (req.socket && typeof req.socket.on === "function") { - return req.socket; - } - const http2Socket = req.stream?.session?.socket; - if (http2Socket && typeof http2Socket.on === "function") { - return http2Socket; - } - return void 0; -} - -apply(); - -function createAppHandler(app, options) { - const als = new AsyncLocalStorage(); - const logger = app.getAdapterLogger(); - process.on("unhandledRejection", (reason) => { - const requestUrl = als.getStore(); - logger.error(`Unhandled rejection while rendering ${requestUrl}`); - console.error(reason); - }); - const originUrl = options.experimentalErrorPageHost ? new URL(options.experimentalErrorPageHost) : void 0; - const prerenderedErrorPageFetch = originUrl ? (url) => { - const errorPageUrl = new URL(url); - errorPageUrl.protocol = originUrl.protocol; - errorPageUrl.host = originUrl.host; - return fetch(errorPageUrl); - } : void 0; - return async (req, res, next, locals) => { - let request; - try { - request = NodeApp.createRequest(req, { - allowedDomains: app.getAllowedDomains?.() ?? [] - }); - } catch (err) { - logger.error(`Could not render ${req.url}`); - console.error(err); - res.statusCode = 500; - res.end("Internal Server Error"); - return; - } - const routeData = app.match(request, true); - if (routeData) { - const response = await als.run( - request.url, - () => app.render(request, { - addCookieHeader: true, - locals, - routeData, - prerenderedErrorPageFetch - }) - ); - await NodeApp.writeResponse(response, res); - } else if (next) { - return next(); - } else { - const response = await app.render(req, { addCookieHeader: true, prerenderedErrorPageFetch }); - await NodeApp.writeResponse(response, res); - } - }; -} - -function createMiddleware(app, options) { - const handler = createAppHandler(app, options); - const logger = app.getAdapterLogger(); - return async (...args) => { - const [req, res, next, locals] = args; - if (req instanceof Error) { - const error = req; - if (next) { - return next(error); - } else { - throw error; - } - } - try { - await handler(req, res, next, locals); - } catch (err) { - logger.error(`Could not render ${req.url}`); - console.error(err); - if (!res.headersSent) { - res.writeHead(500, `Server error`); - res.end(); - } - } - }; -} - -const STATIC_HEADERS_FILE = "_experimentalHeaders.json"; - -var serverDestroy; -var hasRequiredServerDestroy; - -function requireServerDestroy () { - if (hasRequiredServerDestroy) return serverDestroy; - hasRequiredServerDestroy = 1; - serverDestroy = enableDestroy; - - function enableDestroy(server) { - var connections = {}; - - server.on('connection', function(conn) { - var key = conn.remoteAddress + ':' + conn.remotePort; - connections[key] = conn; - conn.on('close', function() { - delete connections[key]; - }); - }); - - server.destroy = function(cb) { - server.close(cb); - for (var key in connections) - connections[key].destroy(); - }; - } - return serverDestroy; -} - -var serverDestroyExports = requireServerDestroy(); -const enableDestroy = /*@__PURE__*/getDefaultExportFromCjs(serverDestroyExports); - -const wildcardHosts = /* @__PURE__ */ new Set(["0.0.0.0", "::", "0000:0000:0000:0000:0000:0000:0000:0000"]); -async function logListeningOn(logger, server, configuredHost) { - await new Promise((resolve) => server.once("listening", resolve)); - const protocol = server instanceof https.Server ? "https" : "http"; - const host = getResolvedHostForHttpServer(configuredHost); - const { port } = server.address(); - const address = getNetworkAddress(protocol, host, port); - if (host === void 0 || wildcardHosts.has(host)) { - logger.info( - `Server listening on - local: ${address.local[0]} - network: ${address.network[0]} -` - ); - } else { - logger.info(`Server listening on ${address.local[0]}`); - } -} -function getResolvedHostForHttpServer(host) { - if (host === false) { - return "localhost"; - } else if (host === true) { - return void 0; - } else { - return host; - } -} -function getNetworkAddress(protocol = "http", hostname, port, base) { - const NetworkAddress = { - local: [], - network: [] - }; - Object.values(os.networkInterfaces()).flatMap((nInterface) => nInterface ?? []).filter( - (detail) => detail && detail.address && (detail.family === "IPv4" || // @ts-expect-error Node 18.0 - 18.3 returns number - detail.family === 4) - ).forEach((detail) => { - let host = detail.address.replace( - "127.0.0.1", - hostname === void 0 || wildcardHosts.has(hostname) ? "localhost" : hostname - ); - if (host.includes(":")) { - host = `[${host}]`; - } - const url = `${protocol}://${host}:${port}${""}`; - if (detail.address.includes("127.0.0.1")) { - NetworkAddress.local.push(url); - } else { - NetworkAddress.network.push(url); - } - }); - return NetworkAddress; -} - -var httpErrors = {exports: {}}; - -/*! - * depd - * Copyright(c) 2014-2018 Douglas Christopher Wilson - * MIT Licensed - */ - -var depd_1; -var hasRequiredDepd; - -function requireDepd () { - if (hasRequiredDepd) return depd_1; - hasRequiredDepd = 1; - /** - * Module dependencies. - */ - - var relative = require$$0$4.relative; - - /** - * Module exports. - */ - - depd_1 = depd; - - /** - * Get the path to base files on. - */ - - var basePath = process.cwd(); - - /** - * Determine if namespace is contained in the string. - */ - - function containsNamespace (str, namespace) { - var vals = str.split(/[ ,]+/); - var ns = String(namespace).toLowerCase(); - - for (var i = 0; i < vals.length; i++) { - var val = vals[i]; - - // namespace contained - if (val && (val === '*' || val.toLowerCase() === ns)) { - return true - } - } - - return false - } - - /** - * Convert a data descriptor to accessor descriptor. - */ - - function convertDataDescriptorToAccessor (obj, prop, message) { - var descriptor = Object.getOwnPropertyDescriptor(obj, prop); - var value = descriptor.value; - - descriptor.get = function getter () { return value }; - - if (descriptor.writable) { - descriptor.set = function setter (val) { return (value = val) }; - } - - delete descriptor.value; - delete descriptor.writable; - - Object.defineProperty(obj, prop, descriptor); - - return descriptor - } - - /** - * Create arguments string to keep arity. - */ - - function createArgumentsString (arity) { - var str = ''; - - for (var i = 0; i < arity; i++) { - str += ', arg' + i; - } - - return str.substr(2) - } - - /** - * Create stack string from stack. - */ - - function createStackString (stack) { - var str = this.name + ': ' + this.namespace; - - if (this.message) { - str += ' deprecated ' + this.message; - } - - for (var i = 0; i < stack.length; i++) { - str += '\n at ' + stack[i].toString(); - } - - return str - } - - /** - * Create deprecate for namespace in caller. - */ - - function depd (namespace) { - if (!namespace) { - throw new TypeError('argument namespace is required') - } - - var stack = getStack(); - var site = callSiteLocation(stack[1]); - var file = site[0]; - - function deprecate (message) { - // call to self as log - log.call(deprecate, message); - } - - deprecate._file = file; - deprecate._ignored = isignored(namespace); - deprecate._namespace = namespace; - deprecate._traced = istraced(namespace); - deprecate._warned = Object.create(null); - - deprecate.function = wrapfunction; - deprecate.property = wrapproperty; - - return deprecate - } - - /** - * Determine if event emitter has listeners of a given type. - * - * The way to do this check is done three different ways in Node.js >= 0.8 - * so this consolidates them into a minimal set using instance methods. - * - * @param {EventEmitter} emitter - * @param {string} type - * @returns {boolean} - * @private - */ - - function eehaslisteners (emitter, type) { - var count = typeof emitter.listenerCount !== 'function' - ? emitter.listeners(type).length - : emitter.listenerCount(type); - - return count > 0 - } - - /** - * Determine if namespace is ignored. - */ - - function isignored (namespace) { - if (process.noDeprecation) { - // --no-deprecation support - return true - } - - var str = process.env.NO_DEPRECATION || ''; - - // namespace ignored - return containsNamespace(str, namespace) - } - - /** - * Determine if namespace is traced. - */ - - function istraced (namespace) { - if (process.traceDeprecation) { - // --trace-deprecation support - return true - } - - var str = process.env.TRACE_DEPRECATION || ''; - - // namespace traced - return containsNamespace(str, namespace) - } - - /** - * Display deprecation message. - */ - - function log (message, site) { - var haslisteners = eehaslisteners(process, 'deprecation'); - - // abort early if no destination - if (!haslisteners && this._ignored) { - return - } - - var caller; - var callFile; - var callSite; - var depSite; - var i = 0; - var seen = false; - var stack = getStack(); - var file = this._file; - - if (site) { - // provided site - depSite = site; - callSite = callSiteLocation(stack[1]); - callSite.name = depSite.name; - file = callSite[0]; - } else { - // get call site - i = 2; - depSite = callSiteLocation(stack[i]); - callSite = depSite; - } - - // get caller of deprecated thing in relation to file - for (; i < stack.length; i++) { - caller = callSiteLocation(stack[i]); - callFile = caller[0]; - - if (callFile === file) { - seen = true; - } else if (callFile === this._file) { - file = this._file; - } else if (seen) { - break - } - } - - var key = caller - ? depSite.join(':') + '__' + caller.join(':') - : undefined; - - if (key !== undefined && key in this._warned) { - // already warned - return - } - - this._warned[key] = true; - - // generate automatic message from call site - var msg = message; - if (!msg) { - msg = callSite === depSite || !callSite.name - ? defaultMessage(depSite) - : defaultMessage(callSite); - } - - // emit deprecation if listeners exist - if (haslisteners) { - var err = DeprecationError(this._namespace, msg, stack.slice(i)); - process.emit('deprecation', err); - return - } - - // format and write message - var format = process.stderr.isTTY - ? formatColor - : formatPlain; - var output = format.call(this, msg, caller, stack.slice(i)); - process.stderr.write(output + '\n', 'utf8'); - } - - /** - * Get call site location as array. - */ - - function callSiteLocation (callSite) { - var file = callSite.getFileName() || ''; - var line = callSite.getLineNumber(); - var colm = callSite.getColumnNumber(); - - if (callSite.isEval()) { - file = callSite.getEvalOrigin() + ', ' + file; - } - - var site = [file, line, colm]; - - site.callSite = callSite; - site.name = callSite.getFunctionName(); - - return site - } - - /** - * Generate a default message from the site. - */ - - function defaultMessage (site) { - var callSite = site.callSite; - var funcName = site.name; - - // make useful anonymous name - if (!funcName) { - funcName = ''; - } - - var context = callSite.getThis(); - var typeName = context && callSite.getTypeName(); - - // ignore useless type name - if (typeName === 'Object') { - typeName = undefined; - } - - // make useful type name - if (typeName === 'Function') { - typeName = context.name || typeName; - } - - return typeName && callSite.getMethodName() - ? typeName + '.' + funcName - : funcName - } - - /** - * Format deprecation message without color. - */ - - function formatPlain (msg, caller, stack) { - var timestamp = new Date().toUTCString(); - - var formatted = timestamp + - ' ' + this._namespace + - ' deprecated ' + msg; - - // add stack trace - if (this._traced) { - for (var i = 0; i < stack.length; i++) { - formatted += '\n at ' + stack[i].toString(); - } - - return formatted - } - - if (caller) { - formatted += ' at ' + formatLocation(caller); - } - - return formatted - } - - /** - * Format deprecation message with color. - */ - - function formatColor (msg, caller, stack) { - var formatted = '\x1b[36;1m' + this._namespace + '\x1b[22;39m' + // bold cyan - ' \x1b[33;1mdeprecated\x1b[22;39m' + // bold yellow - ' \x1b[0m' + msg + '\x1b[39m'; // reset - - // add stack trace - if (this._traced) { - for (var i = 0; i < stack.length; i++) { - formatted += '\n \x1b[36mat ' + stack[i].toString() + '\x1b[39m'; // cyan - } - - return formatted - } - - if (caller) { - formatted += ' \x1b[36m' + formatLocation(caller) + '\x1b[39m'; // cyan - } - - return formatted - } - - /** - * Format call site location. - */ - - function formatLocation (callSite) { - return relative(basePath, callSite[0]) + - ':' + callSite[1] + - ':' + callSite[2] - } - - /** - * Get the stack as array of call sites. - */ - - function getStack () { - var limit = Error.stackTraceLimit; - var obj = {}; - var prep = Error.prepareStackTrace; - - Error.prepareStackTrace = prepareObjectStackTrace; - Error.stackTraceLimit = Math.max(10, limit); - - // capture the stack - Error.captureStackTrace(obj); - - // slice this function off the top - var stack = obj.stack.slice(1); - - Error.prepareStackTrace = prep; - Error.stackTraceLimit = limit; - - return stack - } - - /** - * Capture call site stack from v8. - */ - - function prepareObjectStackTrace (obj, stack) { - return stack - } - - /** - * Return a wrapped function in a deprecation message. - */ - - function wrapfunction (fn, message) { - if (typeof fn !== 'function') { - throw new TypeError('argument fn must be a function') - } - - var args = createArgumentsString(fn.length); - var stack = getStack(); - var site = callSiteLocation(stack[1]); - - site.name = fn.name; - - // eslint-disable-next-line no-new-func - var deprecatedfn = new Function('fn', 'log', 'deprecate', 'message', 'site', - '"use strict"\n' + - 'return function (' + args + ') {' + - 'log.call(deprecate, message, site)\n' + - 'return fn.apply(this, arguments)\n' + - '}')(fn, log, this, message, site); - - return deprecatedfn - } - - /** - * Wrap property in a deprecation message. - */ - - function wrapproperty (obj, prop, message) { - if (!obj || (typeof obj !== 'object' && typeof obj !== 'function')) { - throw new TypeError('argument obj must be object') - } - - var descriptor = Object.getOwnPropertyDescriptor(obj, prop); - - if (!descriptor) { - throw new TypeError('must call property on owner object') - } - - if (!descriptor.configurable) { - throw new TypeError('property must be configurable') - } - - var deprecate = this; - var stack = getStack(); - var site = callSiteLocation(stack[1]); - - // set site name - site.name = prop; - - // convert data descriptor - if ('value' in descriptor) { - descriptor = convertDataDescriptorToAccessor(obj, prop); - } - - var get = descriptor.get; - var set = descriptor.set; - - // wrap getter - if (typeof get === 'function') { - descriptor.get = function getter () { - log.call(deprecate, message, site); - return get.apply(this, arguments) - }; - } - - // wrap setter - if (typeof set === 'function') { - descriptor.set = function setter () { - log.call(deprecate, message, site); - return set.apply(this, arguments) - }; - } - - Object.defineProperty(obj, prop, descriptor); - } - - /** - * Create DeprecationError for deprecation - */ - - function DeprecationError (namespace, message, stack) { - var error = new Error(); - var stackString; - - Object.defineProperty(error, 'constructor', { - value: DeprecationError - }); - - Object.defineProperty(error, 'message', { - configurable: true, - enumerable: false, - value: message, - writable: true - }); - - Object.defineProperty(error, 'name', { - enumerable: false, - configurable: true, - value: 'DeprecationError', - writable: true - }); - - Object.defineProperty(error, 'namespace', { - configurable: true, - enumerable: false, - value: namespace, - writable: true - }); - - Object.defineProperty(error, 'stack', { - configurable: true, - enumerable: false, - get: function () { - if (stackString !== undefined) { - return stackString - } - - // prepare stack trace - return (stackString = createStackString.call(this, stack)) - }, - set: function setter (val) { - stackString = val; - } - }); - - return error - } - return depd_1; -} - -var setprototypeof; -var hasRequiredSetprototypeof; - -function requireSetprototypeof () { - if (hasRequiredSetprototypeof) return setprototypeof; - hasRequiredSetprototypeof = 1; - /* eslint no-proto: 0 */ - setprototypeof = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array ? setProtoOf : mixinProperties); - - function setProtoOf (obj, proto) { - obj.__proto__ = proto; - return obj - } - - function mixinProperties (obj, proto) { - for (var prop in proto) { - if (!Object.prototype.hasOwnProperty.call(obj, prop)) { - obj[prop] = proto[prop]; - } - } - return obj - } - return setprototypeof; -} - -const require$$0$2 = { - "100": "Continue", - "101": "Switching Protocols", - "102": "Processing", - "103": "Early Hints", - "200": "OK", - "201": "Created", - "202": "Accepted", - "203": "Non-Authoritative Information", - "204": "No Content", - "205": "Reset Content", - "206": "Partial Content", - "207": "Multi-Status", - "208": "Already Reported", - "226": "IM Used", - "300": "Multiple Choices", - "301": "Moved Permanently", - "302": "Found", - "303": "See Other", - "304": "Not Modified", - "305": "Use Proxy", - "307": "Temporary Redirect", - "308": "Permanent Redirect", - "400": "Bad Request", - "401": "Unauthorized", - "402": "Payment Required", - "403": "Forbidden", - "404": "Not Found", - "405": "Method Not Allowed", - "406": "Not Acceptable", - "407": "Proxy Authentication Required", - "408": "Request Timeout", - "409": "Conflict", - "410": "Gone", - "411": "Length Required", - "412": "Precondition Failed", - "413": "Payload Too Large", - "414": "URI Too Long", - "415": "Unsupported Media Type", - "416": "Range Not Satisfiable", - "417": "Expectation Failed", - "418": "I'm a Teapot", - "421": "Misdirected Request", - "422": "Unprocessable Entity", - "423": "Locked", - "424": "Failed Dependency", - "425": "Too Early", - "426": "Upgrade Required", - "428": "Precondition Required", - "429": "Too Many Requests", - "431": "Request Header Fields Too Large", - "451": "Unavailable For Legal Reasons", - "500": "Internal Server Error", - "501": "Not Implemented", - "502": "Bad Gateway", - "503": "Service Unavailable", - "504": "Gateway Timeout", - "505": "HTTP Version Not Supported", - "506": "Variant Also Negotiates", - "507": "Insufficient Storage", - "508": "Loop Detected", - "509": "Bandwidth Limit Exceeded", - "510": "Not Extended", - "511": "Network Authentication Required", -}; - -/*! - * statuses - * Copyright(c) 2014 Jonathan Ong - * Copyright(c) 2016 Douglas Christopher Wilson - * MIT Licensed - */ - -var statuses$1; -var hasRequiredStatuses$1; - -function requireStatuses$1 () { - if (hasRequiredStatuses$1) return statuses$1; - hasRequiredStatuses$1 = 1; - - /** - * Module dependencies. - * @private - */ - - var codes = require$$0$2; - - /** - * Module exports. - * @public - */ - - statuses$1 = status; - - // status code to message map - status.message = codes; - - // status message (lower-case) to code map - status.code = createMessageToStatusCodeMap(codes); - - // array of status codes - status.codes = createStatusCodeList(codes); - - // status codes for redirects - status.redirect = { - 300: true, - 301: true, - 302: true, - 303: true, - 305: true, - 307: true, - 308: true - }; - - // status codes for empty bodies - status.empty = { - 204: true, - 205: true, - 304: true - }; - - // status codes for when you should retry the request - status.retry = { - 502: true, - 503: true, - 504: true - }; - - /** - * Create a map of message to status code. - * @private - */ - - function createMessageToStatusCodeMap (codes) { - var map = {}; - - Object.keys(codes).forEach(function forEachCode (code) { - var message = codes[code]; - var status = Number(code); - - // populate map - map[message.toLowerCase()] = status; - }); - - return map - } - - /** - * Create a list of all status codes. - * @private - */ - - function createStatusCodeList (codes) { - return Object.keys(codes).map(function mapCode (code) { - return Number(code) - }) - } - - /** - * Get the status code for given message. - * @private - */ - - function getStatusCode (message) { - var msg = message.toLowerCase(); - - if (!Object.prototype.hasOwnProperty.call(status.code, msg)) { - throw new Error('invalid status message: "' + message + '"') - } - - return status.code[msg] - } - - /** - * Get the status message for given code. - * @private - */ - - function getStatusMessage (code) { - if (!Object.prototype.hasOwnProperty.call(status.message, code)) { - throw new Error('invalid status code: ' + code) - } - - return status.message[code] - } - - /** - * Get the status code. - * - * Given a number, this will throw if it is not a known status - * code, otherwise the code will be returned. Given a string, - * the string will be parsed for a number and return the code - * if valid, otherwise will lookup the code assuming this is - * the status message. - * - * @param {string|number} code - * @returns {number} - * @public - */ - - function status (code) { - if (typeof code === 'number') { - return getStatusMessage(code) - } - - if (typeof code !== 'string') { - throw new TypeError('code must be a number or string') - } - - // '403' - var n = parseInt(code, 10); - if (!isNaN(n)) { - return getStatusMessage(n) - } - - return getStatusCode(code) - } - return statuses$1; -} - -var inherits = {exports: {}}; - -var inherits_browser = {exports: {}}; - -var hasRequiredInherits_browser; - -function requireInherits_browser () { - if (hasRequiredInherits_browser) return inherits_browser.exports; - hasRequiredInherits_browser = 1; - if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - inherits_browser.exports = function inherits(ctor, superCtor) { - if (superCtor) { - ctor.super_ = superCtor; - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }); - } - }; - } else { - // old school shim for old browsers - inherits_browser.exports = function inherits(ctor, superCtor) { - if (superCtor) { - ctor.super_ = superCtor; - var TempCtor = function () {}; - TempCtor.prototype = superCtor.prototype; - ctor.prototype = new TempCtor(); - ctor.prototype.constructor = ctor; - } - }; - } - return inherits_browser.exports; -} - -var hasRequiredInherits; - -function requireInherits () { - if (hasRequiredInherits) return inherits.exports; - hasRequiredInherits = 1; - try { - var util = require('util'); - /* istanbul ignore next */ - if (typeof util.inherits !== 'function') throw ''; - inherits.exports = util.inherits; - } catch (e) { - /* istanbul ignore next */ - inherits.exports = requireInherits_browser(); - } - return inherits.exports; -} - -/*! - * toidentifier - * Copyright(c) 2016 Douglas Christopher Wilson - * MIT Licensed - */ - -var toidentifier; -var hasRequiredToidentifier; - -function requireToidentifier () { - if (hasRequiredToidentifier) return toidentifier; - hasRequiredToidentifier = 1; - - /** - * Module exports. - * @public - */ - - toidentifier = toIdentifier; - - /** - * Trasform the given string into a JavaScript identifier - * - * @param {string} str - * @returns {string} - * @public - */ - - function toIdentifier (str) { - return str - .split(' ') - .map(function (token) { - return token.slice(0, 1).toUpperCase() + token.slice(1) - }) - .join('') - .replace(/[^ _0-9a-z]/gi, '') - } - return toidentifier; -} - -/*! - * http-errors - * Copyright(c) 2014 Jonathan Ong - * Copyright(c) 2016 Douglas Christopher Wilson - * MIT Licensed - */ - -var hasRequiredHttpErrors; - -function requireHttpErrors () { - if (hasRequiredHttpErrors) return httpErrors.exports; - hasRequiredHttpErrors = 1; - (function (module) { - - /** - * Module dependencies. - * @private - */ - - var deprecate = requireDepd()('http-errors'); - var setPrototypeOf = requireSetprototypeof(); - var statuses = requireStatuses$1(); - var inherits = requireInherits(); - var toIdentifier = requireToidentifier(); - - /** - * Module exports. - * @public - */ - - module.exports = createError; - module.exports.HttpError = createHttpErrorConstructor(); - module.exports.isHttpError = createIsHttpErrorFunction(module.exports.HttpError); - - // Populate exports for all constructors - populateConstructorExports(module.exports, statuses.codes, module.exports.HttpError); - - /** - * Get the code class of a status code. - * @private - */ - - function codeClass (status) { - return Number(String(status).charAt(0) + '00') - } - - /** - * Create a new HTTP Error. - * - * @returns {Error} - * @public - */ - - function createError () { - // so much arity going on ~_~ - var err; - var msg; - var status = 500; - var props = {}; - for (var i = 0; i < arguments.length; i++) { - var arg = arguments[i]; - var type = typeof arg; - if (type === 'object' && arg instanceof Error) { - err = arg; - status = err.status || err.statusCode || status; - } else if (type === 'number' && i === 0) { - status = arg; - } else if (type === 'string') { - msg = arg; - } else if (type === 'object') { - props = arg; - } else { - throw new TypeError('argument #' + (i + 1) + ' unsupported type ' + type) - } - } - - if (typeof status === 'number' && (status < 400 || status >= 600)) { - deprecate('non-error status code; use only 4xx or 5xx status codes'); - } - - if (typeof status !== 'number' || - (!statuses.message[status] && (status < 400 || status >= 600))) { - status = 500; - } - - // constructor - var HttpError = createError[status] || createError[codeClass(status)]; - - if (!err) { - // create error - err = HttpError - ? new HttpError(msg) - : new Error(msg || statuses.message[status]); - Error.captureStackTrace(err, createError); - } - - if (!HttpError || !(err instanceof HttpError) || err.status !== status) { - // add properties to generic error - err.expose = status < 500; - err.status = err.statusCode = status; - } - - for (var key in props) { - if (key !== 'status' && key !== 'statusCode') { - err[key] = props[key]; - } - } - - return err - } - - /** - * Create HTTP error abstract base class. - * @private - */ - - function createHttpErrorConstructor () { - function HttpError () { - throw new TypeError('cannot construct abstract class') - } - - inherits(HttpError, Error); - - return HttpError - } - - /** - * Create a constructor for a client error. - * @private - */ - - function createClientErrorConstructor (HttpError, name, code) { - var className = toClassName(name); - - function ClientError (message) { - // create the error object - var msg = message != null ? message : statuses.message[code]; - var err = new Error(msg); - - // capture a stack trace to the construction point - Error.captureStackTrace(err, ClientError); - - // adjust the [[Prototype]] - setPrototypeOf(err, ClientError.prototype); - - // redefine the error message - Object.defineProperty(err, 'message', { - enumerable: true, - configurable: true, - value: msg, - writable: true - }); - - // redefine the error name - Object.defineProperty(err, 'name', { - enumerable: false, - configurable: true, - value: className, - writable: true - }); - - return err - } - - inherits(ClientError, HttpError); - nameFunc(ClientError, className); - - ClientError.prototype.status = code; - ClientError.prototype.statusCode = code; - ClientError.prototype.expose = true; - - return ClientError - } - - /** - * Create function to test is a value is a HttpError. - * @private - */ - - function createIsHttpErrorFunction (HttpError) { - return function isHttpError (val) { - if (!val || typeof val !== 'object') { - return false - } - - if (val instanceof HttpError) { - return true - } - - return val instanceof Error && - typeof val.expose === 'boolean' && - typeof val.statusCode === 'number' && val.status === val.statusCode - } - } - - /** - * Create a constructor for a server error. - * @private - */ - - function createServerErrorConstructor (HttpError, name, code) { - var className = toClassName(name); - - function ServerError (message) { - // create the error object - var msg = message != null ? message : statuses.message[code]; - var err = new Error(msg); - - // capture a stack trace to the construction point - Error.captureStackTrace(err, ServerError); - - // adjust the [[Prototype]] - setPrototypeOf(err, ServerError.prototype); - - // redefine the error message - Object.defineProperty(err, 'message', { - enumerable: true, - configurable: true, - value: msg, - writable: true - }); - - // redefine the error name - Object.defineProperty(err, 'name', { - enumerable: false, - configurable: true, - value: className, - writable: true - }); - - return err - } - - inherits(ServerError, HttpError); - nameFunc(ServerError, className); - - ServerError.prototype.status = code; - ServerError.prototype.statusCode = code; - ServerError.prototype.expose = false; - - return ServerError - } - - /** - * Set the name of a function, if possible. - * @private - */ - - function nameFunc (func, name) { - var desc = Object.getOwnPropertyDescriptor(func, 'name'); - - if (desc && desc.configurable) { - desc.value = name; - Object.defineProperty(func, 'name', desc); - } - } - - /** - * Populate the exports object with constructors for every error class. - * @private - */ - - function populateConstructorExports (exports, codes, HttpError) { - codes.forEach(function forEachCode (code) { - var CodeError; - var name = toIdentifier(statuses.message[code]); - - switch (codeClass(code)) { - case 400: - CodeError = createClientErrorConstructor(HttpError, name, code); - break - case 500: - CodeError = createServerErrorConstructor(HttpError, name, code); - break - } - - if (CodeError) { - // export the constructor - exports[code] = CodeError; - exports[name] = CodeError; - } - }); - } - - /** - * Get a class name from a name identifier. - * @private - */ - - function toClassName (name) { - return name.substr(-5) !== 'Error' - ? name + 'Error' - : name - } - } (httpErrors)); - return httpErrors.exports; -} - -/*! - * encodeurl - * Copyright(c) 2016 Douglas Christopher Wilson - * MIT Licensed - */ - -var encodeurl; -var hasRequiredEncodeurl; - -function requireEncodeurl () { - if (hasRequiredEncodeurl) return encodeurl; - hasRequiredEncodeurl = 1; - - /** - * Module exports. - * @public - */ - - encodeurl = encodeUrl; - - /** - * RegExp to match non-URL code points, *after* encoding (i.e. not including "%") - * and including invalid escape sequences. - * @private - */ - - var ENCODE_CHARS_REGEXP = /(?:[^\x21\x23-\x3B\x3D\x3F-\x5F\x61-\x7A\x7C\x7E]|%(?:[^0-9A-Fa-f]|[0-9A-Fa-f][^0-9A-Fa-f]|$))+/g; - - /** - * RegExp to match unmatched surrogate pair. - * @private - */ - - var UNMATCHED_SURROGATE_PAIR_REGEXP = /(^|[^\uD800-\uDBFF])[\uDC00-\uDFFF]|[\uD800-\uDBFF]([^\uDC00-\uDFFF]|$)/g; - - /** - * String to replace unmatched surrogate pair with. - * @private - */ - - var UNMATCHED_SURROGATE_PAIR_REPLACE = '$1\uFFFD$2'; - - /** - * Encode a URL to a percent-encoded form, excluding already-encoded sequences. - * - * This function will take an already-encoded URL and encode all the non-URL - * code points. This function will not encode the "%" character unless it is - * not part of a valid sequence (`%20` will be left as-is, but `%foo` will - * be encoded as `%25foo`). - * - * This encode is meant to be "safe" and does not throw errors. It will try as - * hard as it can to properly encode the given URL, including replacing any raw, - * unpaired surrogate pairs with the Unicode replacement character prior to - * encoding. - * - * @param {string} url - * @return {string} - * @public - */ - - function encodeUrl (url) { - return String(url) - .replace(UNMATCHED_SURROGATE_PAIR_REGEXP, UNMATCHED_SURROGATE_PAIR_REPLACE) - .replace(ENCODE_CHARS_REGEXP, encodeURI) - } - return encodeurl; -} - -/*! - * escape-html - * Copyright(c) 2012-2013 TJ Holowaychuk - * Copyright(c) 2015 Andreas Lubbe - * Copyright(c) 2015 Tiancheng "Timothy" Gu - * MIT Licensed - */ - -var escapeHtml_1; -var hasRequiredEscapeHtml; - -function requireEscapeHtml () { - if (hasRequiredEscapeHtml) return escapeHtml_1; - hasRequiredEscapeHtml = 1; - - /** - * Module variables. - * @private - */ - - var matchHtmlRegExp = /["'&<>]/; - - /** - * Module exports. - * @public - */ - - escapeHtml_1 = escapeHtml; - - /** - * Escape special characters in the given string of html. - * - * @param {string} string The string to escape for inserting into HTML - * @return {string} - * @public - */ - - function escapeHtml(string) { - var str = '' + string; - var match = matchHtmlRegExp.exec(str); - - if (!match) { - return str; - } - - var escape; - var html = ''; - var index = 0; - var lastIndex = 0; - - for (index = match.index; index < str.length; index++) { - switch (str.charCodeAt(index)) { - case 34: // " - escape = '"'; - break; - case 38: // & - escape = '&'; - break; - case 39: // ' - escape = '''; - break; - case 60: // < - escape = '<'; - break; - case 62: // > - escape = '>'; - break; - default: - continue; - } - - if (lastIndex !== index) { - html += str.substring(lastIndex, index); - } - - lastIndex = index + 1; - html += escape; - } - - return lastIndex !== index - ? html + str.substring(lastIndex, index) - : html; - } - return escapeHtml_1; -} - -/*! - * etag - * Copyright(c) 2014-2016 Douglas Christopher Wilson - * MIT Licensed - */ - -var etag_1; -var hasRequiredEtag; - -function requireEtag () { - if (hasRequiredEtag) return etag_1; - hasRequiredEtag = 1; - - /** - * Module exports. - * @public - */ - - etag_1 = etag; - - /** - * Module dependencies. - * @private - */ - - var crypto = require$$0$6; - var Stats = require$$0$5.Stats; - - /** - * Module variables. - * @private - */ - - var toString = Object.prototype.toString; - - /** - * Generate an entity tag. - * - * @param {Buffer|string} entity - * @return {string} - * @private - */ - - function entitytag (entity) { - if (entity.length === 0) { - // fast-path empty - return '"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk"' - } - - // compute hash of entity - var hash = crypto - .createHash('sha1') - .update(entity, 'utf8') - .digest('base64') - .substring(0, 27); - - // compute length of entity - var len = typeof entity === 'string' - ? Buffer.byteLength(entity, 'utf8') - : entity.length; - - return '"' + len.toString(16) + '-' + hash + '"' - } - - /** - * Create a simple ETag. - * - * @param {string|Buffer|Stats} entity - * @param {object} [options] - * @param {boolean} [options.weak] - * @return {String} - * @public - */ - - function etag (entity, options) { - if (entity == null) { - throw new TypeError('argument entity is required') - } - - // support fs.Stats object - var isStats = isstats(entity); - var weak = options && typeof options.weak === 'boolean' - ? options.weak - : isStats; - - // validate argument - if (!isStats && typeof entity !== 'string' && !Buffer.isBuffer(entity)) { - throw new TypeError('argument entity must be string, Buffer, or fs.Stats') - } - - // generate entity tag - var tag = isStats - ? stattag(entity) - : entitytag(entity); - - return weak - ? 'W/' + tag - : tag - } - - /** - * Determine if object is a Stats object. - * - * @param {object} obj - * @return {boolean} - * @api private - */ - - function isstats (obj) { - // genuine fs.Stats - if (typeof Stats === 'function' && obj instanceof Stats) { - return true - } - - // quack quack - return obj && typeof obj === 'object' && - 'ctime' in obj && toString.call(obj.ctime) === '[object Date]' && - 'mtime' in obj && toString.call(obj.mtime) === '[object Date]' && - 'ino' in obj && typeof obj.ino === 'number' && - 'size' in obj && typeof obj.size === 'number' - } - - /** - * Generate a tag for a stat. - * - * @param {object} stat - * @return {string} - * @private - */ - - function stattag (stat) { - var mtime = stat.mtime.getTime().toString(16); - var size = stat.size.toString(16); - - return '"' + size + '-' + mtime + '"' - } - return etag_1; -} - -/*! - * fresh - * Copyright(c) 2012 TJ Holowaychuk - * Copyright(c) 2016-2017 Douglas Christopher Wilson - * MIT Licensed - */ - -var fresh_1; -var hasRequiredFresh; - -function requireFresh () { - if (hasRequiredFresh) return fresh_1; - hasRequiredFresh = 1; - - /** - * RegExp to check for no-cache token in Cache-Control. - * @private - */ - - var CACHE_CONTROL_NO_CACHE_REGEXP = /(?:^|,)\s*?no-cache\s*?(?:,|$)/; - - /** - * Module exports. - * @public - */ - - fresh_1 = fresh; - - /** - * Check freshness of the response using request and response headers. - * - * @param {Object} reqHeaders - * @param {Object} resHeaders - * @return {Boolean} - * @public - */ - - function fresh (reqHeaders, resHeaders) { - // fields - var modifiedSince = reqHeaders['if-modified-since']; - var noneMatch = reqHeaders['if-none-match']; - - // unconditional request - if (!modifiedSince && !noneMatch) { - return false - } - - // Always return stale when Cache-Control: no-cache - // to support end-to-end reload requests - // https://tools.ietf.org/html/rfc2616#section-14.9.4 - var cacheControl = reqHeaders['cache-control']; - if (cacheControl && CACHE_CONTROL_NO_CACHE_REGEXP.test(cacheControl)) { - return false - } - - // if-none-match takes precedent over if-modified-since - if (noneMatch) { - if (noneMatch === '*') { - return true - } - var etag = resHeaders.etag; - - if (!etag) { - return false - } - - var matches = parseTokenList(noneMatch); - for (var i = 0; i < matches.length; i++) { - var match = matches[i]; - if (match === etag || match === 'W/' + etag || 'W/' + match === etag) { - return true - } - } - - return false - } - - // if-modified-since - if (modifiedSince) { - var lastModified = resHeaders['last-modified']; - var modifiedStale = !lastModified || !(parseHttpDate(lastModified) <= parseHttpDate(modifiedSince)); - - if (modifiedStale) { - return false - } - } - - return true - } - - /** - * Parse an HTTP Date into a number. - * - * @param {string} date - * @private - */ - - function parseHttpDate (date) { - var timestamp = date && Date.parse(date); - - // istanbul ignore next: guard against date.js Date.parse patching - return typeof timestamp === 'number' - ? timestamp - : NaN - } - - /** - * Parse a HTTP token list. - * - * @param {string} str - * @private - */ - - function parseTokenList (str) { - var end = 0; - var list = []; - var start = 0; - - // gather tokens - for (var i = 0, len = str.length; i < len; i++) { - switch (str.charCodeAt(i)) { - case 0x20: /* */ - if (start === end) { - start = end = i + 1; - } - break - case 0x2c: /* , */ - list.push(str.substring(start, end)); - start = end = i + 1; - break - default: - end = i + 1; - break - } - } - - // final token - list.push(str.substring(start, end)); - - return list - } - return fresh_1; -} - -var mimeTypes = {}; - -const require$$0$1 = { - "application/1d-interleaved-parityfec": {"source":"iana"}, - "application/3gpdash-qoe-report+xml": {"source":"iana","charset":"UTF-8","compressible":true}, - "application/3gpp-ims+xml": {"source":"iana","compressible":true}, - "application/3gpphal+json": {"source":"iana","compressible":true}, - "application/3gpphalforms+json": {"source":"iana","compressible":true}, - "application/a2l": {"source":"iana"}, - "application/ace+cbor": {"source":"iana"}, - "application/ace+json": {"source":"iana","compressible":true}, - "application/ace-groupcomm+cbor": {"source":"iana"}, - "application/ace-trl+cbor": {"source":"iana"}, - "application/activemessage": {"source":"iana"}, - "application/activity+json": {"source":"iana","compressible":true}, - "application/aif+cbor": {"source":"iana"}, - "application/aif+json": {"source":"iana","compressible":true}, - "application/alto-cdni+json": {"source":"iana","compressible":true}, - "application/alto-cdnifilter+json": {"source":"iana","compressible":true}, - "application/alto-costmap+json": {"source":"iana","compressible":true}, - "application/alto-costmapfilter+json": {"source":"iana","compressible":true}, - "application/alto-directory+json": {"source":"iana","compressible":true}, - "application/alto-endpointcost+json": {"source":"iana","compressible":true}, - "application/alto-endpointcostparams+json": {"source":"iana","compressible":true}, - "application/alto-endpointprop+json": {"source":"iana","compressible":true}, - "application/alto-endpointpropparams+json": {"source":"iana","compressible":true}, - "application/alto-error+json": {"source":"iana","compressible":true}, - "application/alto-networkmap+json": {"source":"iana","compressible":true}, - "application/alto-networkmapfilter+json": {"source":"iana","compressible":true}, - "application/alto-propmap+json": {"source":"iana","compressible":true}, - "application/alto-propmapparams+json": {"source":"iana","compressible":true}, - "application/alto-tips+json": {"source":"iana","compressible":true}, - "application/alto-tipsparams+json": {"source":"iana","compressible":true}, - "application/alto-updatestreamcontrol+json": {"source":"iana","compressible":true}, - "application/alto-updatestreamparams+json": {"source":"iana","compressible":true}, - "application/aml": {"source":"iana"}, - "application/andrew-inset": {"source":"iana","extensions":["ez"]}, - "application/appinstaller": {"compressible":false,"extensions":["appinstaller"]}, - "application/applefile": {"source":"iana"}, - "application/applixware": {"source":"apache","extensions":["aw"]}, - "application/appx": {"compressible":false,"extensions":["appx"]}, - "application/appxbundle": {"compressible":false,"extensions":["appxbundle"]}, - "application/at+jwt": {"source":"iana"}, - "application/atf": {"source":"iana"}, - "application/atfx": {"source":"iana"}, - "application/atom+xml": {"source":"iana","compressible":true,"extensions":["atom"]}, - "application/atomcat+xml": {"source":"iana","compressible":true,"extensions":["atomcat"]}, - "application/atomdeleted+xml": {"source":"iana","compressible":true,"extensions":["atomdeleted"]}, - "application/atomicmail": {"source":"iana"}, - "application/atomsvc+xml": {"source":"iana","compressible":true,"extensions":["atomsvc"]}, - "application/atsc-dwd+xml": {"source":"iana","compressible":true,"extensions":["dwd"]}, - "application/atsc-dynamic-event-message": {"source":"iana"}, - "application/atsc-held+xml": {"source":"iana","compressible":true,"extensions":["held"]}, - "application/atsc-rdt+json": {"source":"iana","compressible":true}, - "application/atsc-rsat+xml": {"source":"iana","compressible":true,"extensions":["rsat"]}, - "application/atxml": {"source":"iana"}, - "application/auth-policy+xml": {"source":"iana","compressible":true}, - "application/automationml-aml+xml": {"source":"iana","compressible":true,"extensions":["aml"]}, - "application/automationml-amlx+zip": {"source":"iana","compressible":false,"extensions":["amlx"]}, - "application/bacnet-xdd+zip": {"source":"iana","compressible":false}, - "application/batch-smtp": {"source":"iana"}, - "application/bdoc": {"compressible":false,"extensions":["bdoc"]}, - "application/beep+xml": {"source":"iana","charset":"UTF-8","compressible":true}, - "application/bufr": {"source":"iana"}, - "application/c2pa": {"source":"iana"}, - "application/calendar+json": {"source":"iana","compressible":true}, - "application/calendar+xml": {"source":"iana","compressible":true,"extensions":["xcs"]}, - "application/call-completion": {"source":"iana"}, - "application/cals-1840": {"source":"iana"}, - "application/captive+json": {"source":"iana","compressible":true}, - "application/cbor": {"source":"iana"}, - "application/cbor-seq": {"source":"iana"}, - "application/cccex": {"source":"iana"}, - "application/ccmp+xml": {"source":"iana","compressible":true}, - "application/ccxml+xml": {"source":"iana","compressible":true,"extensions":["ccxml"]}, - "application/cda+xml": {"source":"iana","charset":"UTF-8","compressible":true}, - "application/cdfx+xml": {"source":"iana","compressible":true,"extensions":["cdfx"]}, - "application/cdmi-capability": {"source":"iana","extensions":["cdmia"]}, - "application/cdmi-container": {"source":"iana","extensions":["cdmic"]}, - "application/cdmi-domain": {"source":"iana","extensions":["cdmid"]}, - "application/cdmi-object": {"source":"iana","extensions":["cdmio"]}, - "application/cdmi-queue": {"source":"iana","extensions":["cdmiq"]}, - "application/cdni": {"source":"iana"}, - "application/ce+cbor": {"source":"iana"}, - "application/cea": {"source":"iana"}, - "application/cea-2018+xml": {"source":"iana","compressible":true}, - "application/cellml+xml": {"source":"iana","compressible":true}, - "application/cfw": {"source":"iana"}, - "application/cid-edhoc+cbor-seq": {"source":"iana"}, - "application/city+json": {"source":"iana","compressible":true}, - "application/city+json-seq": {"source":"iana"}, - "application/clr": {"source":"iana"}, - "application/clue+xml": {"source":"iana","compressible":true}, - "application/clue_info+xml": {"source":"iana","compressible":true}, - "application/cms": {"source":"iana"}, - "application/cnrp+xml": {"source":"iana","compressible":true}, - "application/coap-eap": {"source":"iana"}, - "application/coap-group+json": {"source":"iana","compressible":true}, - "application/coap-payload": {"source":"iana"}, - "application/commonground": {"source":"iana"}, - "application/concise-problem-details+cbor": {"source":"iana"}, - "application/conference-info+xml": {"source":"iana","compressible":true}, - "application/cose": {"source":"iana"}, - "application/cose-key": {"source":"iana"}, - "application/cose-key-set": {"source":"iana"}, - "application/cose-x509": {"source":"iana"}, - "application/cpl+xml": {"source":"iana","compressible":true,"extensions":["cpl"]}, - "application/csrattrs": {"source":"iana"}, - "application/csta+xml": {"source":"iana","compressible":true}, - "application/cstadata+xml": {"source":"iana","compressible":true}, - "application/csvm+json": {"source":"iana","compressible":true}, - "application/cu-seeme": {"source":"apache","extensions":["cu"]}, - "application/cwl": {"source":"iana","extensions":["cwl"]}, - "application/cwl+json": {"source":"iana","compressible":true}, - "application/cwl+yaml": {"source":"iana"}, - "application/cwt": {"source":"iana"}, - "application/cybercash": {"source":"iana"}, - "application/dart": {"compressible":true}, - "application/dash+xml": {"source":"iana","compressible":true,"extensions":["mpd"]}, - "application/dash-patch+xml": {"source":"iana","compressible":true,"extensions":["mpp"]}, - "application/dashdelta": {"source":"iana"}, - "application/davmount+xml": {"source":"iana","compressible":true,"extensions":["davmount"]}, - "application/dca-rft": {"source":"iana"}, - "application/dcd": {"source":"iana"}, - "application/dec-dx": {"source":"iana"}, - "application/dialog-info+xml": {"source":"iana","compressible":true}, - "application/dicom": {"source":"iana","extensions":["dcm"]}, - "application/dicom+json": {"source":"iana","compressible":true}, - "application/dicom+xml": {"source":"iana","compressible":true}, - "application/dii": {"source":"iana"}, - "application/dit": {"source":"iana"}, - "application/dns": {"source":"iana"}, - "application/dns+json": {"source":"iana","compressible":true}, - "application/dns-message": {"source":"iana"}, - "application/docbook+xml": {"source":"apache","compressible":true,"extensions":["dbk"]}, - "application/dots+cbor": {"source":"iana"}, - "application/dpop+jwt": {"source":"iana"}, - "application/dskpp+xml": {"source":"iana","compressible":true}, - "application/dssc+der": {"source":"iana","extensions":["dssc"]}, - "application/dssc+xml": {"source":"iana","compressible":true,"extensions":["xdssc"]}, - "application/dvcs": {"source":"iana"}, - "application/eat+cwt": {"source":"iana"}, - "application/eat+jwt": {"source":"iana"}, - "application/eat-bun+cbor": {"source":"iana"}, - "application/eat-bun+json": {"source":"iana","compressible":true}, - "application/eat-ucs+cbor": {"source":"iana"}, - "application/eat-ucs+json": {"source":"iana","compressible":true}, - "application/ecmascript": {"source":"apache","compressible":true,"extensions":["ecma"]}, - "application/edhoc+cbor-seq": {"source":"iana"}, - "application/edi-consent": {"source":"iana"}, - "application/edi-x12": {"source":"iana","compressible":false}, - "application/edifact": {"source":"iana","compressible":false}, - "application/efi": {"source":"iana"}, - "application/elm+json": {"source":"iana","charset":"UTF-8","compressible":true}, - "application/elm+xml": {"source":"iana","compressible":true}, - "application/emergencycalldata.cap+xml": {"source":"iana","charset":"UTF-8","compressible":true}, - "application/emergencycalldata.comment+xml": {"source":"iana","compressible":true}, - "application/emergencycalldata.control+xml": {"source":"iana","compressible":true}, - "application/emergencycalldata.deviceinfo+xml": {"source":"iana","compressible":true}, - "application/emergencycalldata.ecall.msd": {"source":"iana"}, - "application/emergencycalldata.legacyesn+json": {"source":"iana","compressible":true}, - "application/emergencycalldata.providerinfo+xml": {"source":"iana","compressible":true}, - "application/emergencycalldata.serviceinfo+xml": {"source":"iana","compressible":true}, - "application/emergencycalldata.subscriberinfo+xml": {"source":"iana","compressible":true}, - "application/emergencycalldata.veds+xml": {"source":"iana","compressible":true}, - "application/emma+xml": {"source":"iana","compressible":true,"extensions":["emma"]}, - "application/emotionml+xml": {"source":"iana","compressible":true,"extensions":["emotionml"]}, - "application/encaprtp": {"source":"iana"}, - "application/entity-statement+jwt": {"source":"iana"}, - "application/epp+xml": {"source":"iana","compressible":true}, - "application/epub+zip": {"source":"iana","compressible":false,"extensions":["epub"]}, - "application/eshop": {"source":"iana"}, - "application/exi": {"source":"iana","extensions":["exi"]}, - "application/expect-ct-report+json": {"source":"iana","compressible":true}, - "application/express": {"source":"iana","extensions":["exp"]}, - "application/fastinfoset": {"source":"iana"}, - "application/fastsoap": {"source":"iana"}, - "application/fdf": {"source":"iana","extensions":["fdf"]}, - "application/fdt+xml": {"source":"iana","compressible":true,"extensions":["fdt"]}, - "application/fhir+json": {"source":"iana","charset":"UTF-8","compressible":true}, - "application/fhir+xml": {"source":"iana","charset":"UTF-8","compressible":true}, - "application/fido.trusted-apps+json": {"compressible":true}, - "application/fits": {"source":"iana"}, - "application/flexfec": {"source":"iana"}, - "application/font-sfnt": {"source":"iana"}, - "application/font-tdpfr": {"source":"iana","extensions":["pfr"]}, - "application/font-woff": {"source":"iana","compressible":false}, - "application/framework-attributes+xml": {"source":"iana","compressible":true}, - "application/geo+json": {"source":"iana","compressible":true,"extensions":["geojson"]}, - "application/geo+json-seq": {"source":"iana"}, - "application/geopackage+sqlite3": {"source":"iana"}, - "application/geopose+json": {"source":"iana","compressible":true}, - "application/geoxacml+json": {"source":"iana","compressible":true}, - "application/geoxacml+xml": {"source":"iana","compressible":true}, - "application/gltf-buffer": {"source":"iana"}, - "application/gml+xml": {"source":"iana","compressible":true,"extensions":["gml"]}, - "application/gnap-binding-jws": {"source":"iana"}, - "application/gnap-binding-jwsd": {"source":"iana"}, - "application/gnap-binding-rotation-jws": {"source":"iana"}, - "application/gnap-binding-rotation-jwsd": {"source":"iana"}, - "application/gpx+xml": {"source":"apache","compressible":true,"extensions":["gpx"]}, - "application/grib": {"source":"iana"}, - "application/gxf": {"source":"apache","extensions":["gxf"]}, - "application/gzip": {"source":"iana","compressible":false,"extensions":["gz"]}, - "application/h224": {"source":"iana"}, - "application/held+xml": {"source":"iana","compressible":true}, - "application/hjson": {"extensions":["hjson"]}, - "application/hl7v2+xml": {"source":"iana","charset":"UTF-8","compressible":true}, - "application/http": {"source":"iana"}, - "application/hyperstudio": {"source":"iana","extensions":["stk"]}, - "application/ibe-key-request+xml": {"source":"iana","compressible":true}, - "application/ibe-pkg-reply+xml": {"source":"iana","compressible":true}, - "application/ibe-pp-data": {"source":"iana"}, - "application/iges": {"source":"iana"}, - "application/im-iscomposing+xml": {"source":"iana","charset":"UTF-8","compressible":true}, - "application/index": {"source":"iana"}, - "application/index.cmd": {"source":"iana"}, - "application/index.obj": {"source":"iana"}, - "application/index.response": {"source":"iana"}, - "application/index.vnd": {"source":"iana"}, - "application/inkml+xml": {"source":"iana","compressible":true,"extensions":["ink","inkml"]}, - "application/iotp": {"source":"iana"}, - "application/ipfix": {"source":"iana","extensions":["ipfix"]}, - "application/ipp": {"source":"iana"}, - "application/isup": {"source":"iana"}, - "application/its+xml": {"source":"iana","compressible":true,"extensions":["its"]}, - "application/java-archive": {"source":"iana","compressible":false,"extensions":["jar","war","ear"]}, - "application/java-serialized-object": {"source":"apache","compressible":false,"extensions":["ser"]}, - "application/java-vm": {"source":"apache","compressible":false,"extensions":["class"]}, - "application/javascript": {"source":"apache","charset":"UTF-8","compressible":true,"extensions":["js"]}, - "application/jf2feed+json": {"source":"iana","compressible":true}, - "application/jose": {"source":"iana"}, - "application/jose+json": {"source":"iana","compressible":true}, - "application/jrd+json": {"source":"iana","compressible":true}, - "application/jscalendar+json": {"source":"iana","compressible":true}, - "application/jscontact+json": {"source":"iana","compressible":true}, - "application/json": {"source":"iana","charset":"UTF-8","compressible":true,"extensions":["json","map"]}, - "application/json-patch+json": {"source":"iana","compressible":true}, - "application/json-seq": {"source":"iana"}, - "application/json5": {"extensions":["json5"]}, - "application/jsonml+json": {"source":"apache","compressible":true,"extensions":["jsonml"]}, - "application/jsonpath": {"source":"iana"}, - "application/jwk+json": {"source":"iana","compressible":true}, - "application/jwk-set+json": {"source":"iana","compressible":true}, - "application/jwk-set+jwt": {"source":"iana"}, - "application/jwt": {"source":"iana"}, - "application/kpml-request+xml": {"source":"iana","compressible":true}, - "application/kpml-response+xml": {"source":"iana","compressible":true}, - "application/ld+json": {"source":"iana","compressible":true,"extensions":["jsonld"]}, - "application/lgr+xml": {"source":"iana","compressible":true,"extensions":["lgr"]}, - "application/link-format": {"source":"iana"}, - "application/linkset": {"source":"iana"}, - "application/linkset+json": {"source":"iana","compressible":true}, - "application/load-control+xml": {"source":"iana","compressible":true}, - "application/logout+jwt": {"source":"iana"}, - "application/lost+xml": {"source":"iana","compressible":true,"extensions":["lostxml"]}, - "application/lostsync+xml": {"source":"iana","compressible":true}, - "application/lpf+zip": {"source":"iana","compressible":false}, - "application/lxf": {"source":"iana"}, - "application/mac-binhex40": {"source":"iana","extensions":["hqx"]}, - "application/mac-compactpro": {"source":"apache","extensions":["cpt"]}, - "application/macwriteii": {"source":"iana"}, - "application/mads+xml": {"source":"iana","compressible":true,"extensions":["mads"]}, - "application/manifest+json": {"source":"iana","charset":"UTF-8","compressible":true,"extensions":["webmanifest"]}, - "application/marc": {"source":"iana","extensions":["mrc"]}, - "application/marcxml+xml": {"source":"iana","compressible":true,"extensions":["mrcx"]}, - "application/mathematica": {"source":"iana","extensions":["ma","nb","mb"]}, - "application/mathml+xml": {"source":"iana","compressible":true,"extensions":["mathml"]}, - "application/mathml-content+xml": {"source":"iana","compressible":true}, - "application/mathml-presentation+xml": {"source":"iana","compressible":true}, - "application/mbms-associated-procedure-description+xml": {"source":"iana","compressible":true}, - "application/mbms-deregister+xml": {"source":"iana","compressible":true}, - "application/mbms-envelope+xml": {"source":"iana","compressible":true}, - "application/mbms-msk+xml": {"source":"iana","compressible":true}, - "application/mbms-msk-response+xml": {"source":"iana","compressible":true}, - "application/mbms-protection-description+xml": {"source":"iana","compressible":true}, - "application/mbms-reception-report+xml": {"source":"iana","compressible":true}, - "application/mbms-register+xml": {"source":"iana","compressible":true}, - "application/mbms-register-response+xml": {"source":"iana","compressible":true}, - "application/mbms-schedule+xml": {"source":"iana","compressible":true}, - "application/mbms-user-service-description+xml": {"source":"iana","compressible":true}, - "application/mbox": {"source":"iana","extensions":["mbox"]}, - "application/media-policy-dataset+xml": {"source":"iana","compressible":true,"extensions":["mpf"]}, - "application/media_control+xml": {"source":"iana","compressible":true}, - "application/mediaservercontrol+xml": {"source":"iana","compressible":true,"extensions":["mscml"]}, - "application/merge-patch+json": {"source":"iana","compressible":true}, - "application/metalink+xml": {"source":"apache","compressible":true,"extensions":["metalink"]}, - "application/metalink4+xml": {"source":"iana","compressible":true,"extensions":["meta4"]}, - "application/mets+xml": {"source":"iana","compressible":true,"extensions":["mets"]}, - "application/mf4": {"source":"iana"}, - "application/mikey": {"source":"iana"}, - "application/mipc": {"source":"iana"}, - "application/missing-blocks+cbor-seq": {"source":"iana"}, - "application/mmt-aei+xml": {"source":"iana","compressible":true,"extensions":["maei"]}, - "application/mmt-usd+xml": {"source":"iana","compressible":true,"extensions":["musd"]}, - "application/mods+xml": {"source":"iana","compressible":true,"extensions":["mods"]}, - "application/moss-keys": {"source":"iana"}, - "application/moss-signature": {"source":"iana"}, - "application/mosskey-data": {"source":"iana"}, - "application/mosskey-request": {"source":"iana"}, - "application/mp21": {"source":"iana","extensions":["m21","mp21"]}, - "application/mp4": {"source":"iana","extensions":["mp4","mpg4","mp4s","m4p"]}, - "application/mpeg4-generic": {"source":"iana"}, - "application/mpeg4-iod": {"source":"iana"}, - "application/mpeg4-iod-xmt": {"source":"iana"}, - "application/mrb-consumer+xml": {"source":"iana","compressible":true}, - "application/mrb-publish+xml": {"source":"iana","compressible":true}, - "application/msc-ivr+xml": {"source":"iana","charset":"UTF-8","compressible":true}, - "application/msc-mixer+xml": {"source":"iana","charset":"UTF-8","compressible":true}, - "application/msix": {"compressible":false,"extensions":["msix"]}, - "application/msixbundle": {"compressible":false,"extensions":["msixbundle"]}, - "application/msword": {"source":"iana","compressible":false,"extensions":["doc","dot"]}, - "application/mud+json": {"source":"iana","compressible":true}, - "application/multipart-core": {"source":"iana"}, - "application/mxf": {"source":"iana","extensions":["mxf"]}, - "application/n-quads": {"source":"iana","extensions":["nq"]}, - "application/n-triples": {"source":"iana","extensions":["nt"]}, - "application/nasdata": {"source":"iana"}, - "application/news-checkgroups": {"source":"iana","charset":"US-ASCII"}, - "application/news-groupinfo": {"source":"iana","charset":"US-ASCII"}, - "application/news-transmission": {"source":"iana"}, - "application/nlsml+xml": {"source":"iana","compressible":true}, - "application/node": {"source":"iana","extensions":["cjs"]}, - "application/nss": {"source":"iana"}, - "application/oauth-authz-req+jwt": {"source":"iana"}, - "application/oblivious-dns-message": {"source":"iana"}, - "application/ocsp-request": {"source":"iana"}, - "application/ocsp-response": {"source":"iana"}, - "application/octet-stream": {"source":"iana","compressible":true,"extensions":["bin","dms","lrf","mar","so","dist","distz","pkg","bpk","dump","elc","deploy","exe","dll","deb","dmg","iso","img","msi","msp","msm","buffer"]}, - "application/oda": {"source":"iana","extensions":["oda"]}, - "application/odm+xml": {"source":"iana","compressible":true}, - "application/odx": {"source":"iana"}, - "application/oebps-package+xml": {"source":"iana","compressible":true,"extensions":["opf"]}, - "application/ogg": {"source":"iana","compressible":false,"extensions":["ogx"]}, - "application/ohttp-keys": {"source":"iana"}, - "application/omdoc+xml": {"source":"apache","compressible":true,"extensions":["omdoc"]}, - "application/onenote": {"source":"apache","extensions":["onetoc","onetoc2","onetmp","onepkg","one","onea"]}, - "application/opc-nodeset+xml": {"source":"iana","compressible":true}, - "application/oscore": {"source":"iana"}, - "application/oxps": {"source":"iana","extensions":["oxps"]}, - "application/p21": {"source":"iana"}, - "application/p21+zip": {"source":"iana","compressible":false}, - "application/p2p-overlay+xml": {"source":"iana","compressible":true,"extensions":["relo"]}, - "application/parityfec": {"source":"iana"}, - "application/passport": {"source":"iana"}, - "application/patch-ops-error+xml": {"source":"iana","compressible":true,"extensions":["xer"]}, - "application/pdf": {"source":"iana","compressible":false,"extensions":["pdf"]}, - "application/pdx": {"source":"iana"}, - "application/pem-certificate-chain": {"source":"iana"}, - "application/pgp-encrypted": {"source":"iana","compressible":false,"extensions":["pgp"]}, - "application/pgp-keys": {"source":"iana","extensions":["asc"]}, - "application/pgp-signature": {"source":"iana","extensions":["sig","asc"]}, - "application/pics-rules": {"source":"apache","extensions":["prf"]}, - "application/pidf+xml": {"source":"iana","charset":"UTF-8","compressible":true}, - "application/pidf-diff+xml": {"source":"iana","charset":"UTF-8","compressible":true}, - "application/pkcs10": {"source":"iana","extensions":["p10"]}, - "application/pkcs12": {"source":"iana"}, - "application/pkcs7-mime": {"source":"iana","extensions":["p7m","p7c"]}, - "application/pkcs7-signature": {"source":"iana","extensions":["p7s"]}, - "application/pkcs8": {"source":"iana","extensions":["p8"]}, - "application/pkcs8-encrypted": {"source":"iana"}, - "application/pkix-attr-cert": {"source":"iana","extensions":["ac"]}, - "application/pkix-cert": {"source":"iana","extensions":["cer"]}, - "application/pkix-crl": {"source":"iana","extensions":["crl"]}, - "application/pkix-pkipath": {"source":"iana","extensions":["pkipath"]}, - "application/pkixcmp": {"source":"iana","extensions":["pki"]}, - "application/pls+xml": {"source":"iana","compressible":true,"extensions":["pls"]}, - "application/poc-settings+xml": {"source":"iana","charset":"UTF-8","compressible":true}, - "application/postscript": {"source":"iana","compressible":true,"extensions":["ai","eps","ps"]}, - "application/ppsp-tracker+json": {"source":"iana","compressible":true}, - "application/private-token-issuer-directory": {"source":"iana"}, - "application/private-token-request": {"source":"iana"}, - "application/private-token-response": {"source":"iana"}, - "application/problem+json": {"source":"iana","compressible":true}, - "application/problem+xml": {"source":"iana","compressible":true}, - "application/provenance+xml": {"source":"iana","compressible":true,"extensions":["provx"]}, - "application/provided-claims+jwt": {"source":"iana"}, - "application/prs.alvestrand.titrax-sheet": {"source":"iana"}, - "application/prs.cww": {"source":"iana","extensions":["cww"]}, - "application/prs.cyn": {"source":"iana","charset":"7-BIT"}, - "application/prs.hpub+zip": {"source":"iana","compressible":false}, - "application/prs.implied-document+xml": {"source":"iana","compressible":true}, - "application/prs.implied-executable": {"source":"iana"}, - "application/prs.implied-object+json": {"source":"iana","compressible":true}, - "application/prs.implied-object+json-seq": {"source":"iana"}, - "application/prs.implied-object+yaml": {"source":"iana"}, - "application/prs.implied-structure": {"source":"iana"}, - "application/prs.mayfile": {"source":"iana"}, - "application/prs.nprend": {"source":"iana"}, - "application/prs.plucker": {"source":"iana"}, - "application/prs.rdf-xml-crypt": {"source":"iana"}, - "application/prs.vcfbzip2": {"source":"iana"}, - "application/prs.xsf+xml": {"source":"iana","compressible":true,"extensions":["xsf"]}, - "application/pskc+xml": {"source":"iana","compressible":true,"extensions":["pskcxml"]}, - "application/pvd+json": {"source":"iana","compressible":true}, - "application/qsig": {"source":"iana"}, - "application/raml+yaml": {"compressible":true,"extensions":["raml"]}, - "application/raptorfec": {"source":"iana"}, - "application/rdap+json": {"source":"iana","compressible":true}, - "application/rdf+xml": {"source":"iana","compressible":true,"extensions":["rdf","owl"]}, - "application/reginfo+xml": {"source":"iana","compressible":true,"extensions":["rif"]}, - "application/relax-ng-compact-syntax": {"source":"iana","extensions":["rnc"]}, - "application/remote-printing": {"source":"apache"}, - "application/reputon+json": {"source":"iana","compressible":true}, - "application/resolve-response+jwt": {"source":"iana"}, - "application/resource-lists+xml": {"source":"iana","compressible":true,"extensions":["rl"]}, - "application/resource-lists-diff+xml": {"source":"iana","compressible":true,"extensions":["rld"]}, - "application/rfc+xml": {"source":"iana","compressible":true}, - "application/riscos": {"source":"iana"}, - "application/rlmi+xml": {"source":"iana","compressible":true}, - "application/rls-services+xml": {"source":"iana","compressible":true,"extensions":["rs"]}, - "application/route-apd+xml": {"source":"iana","compressible":true,"extensions":["rapd"]}, - "application/route-s-tsid+xml": {"source":"iana","compressible":true,"extensions":["sls"]}, - "application/route-usd+xml": {"source":"iana","compressible":true,"extensions":["rusd"]}, - "application/rpki-checklist": {"source":"iana"}, - "application/rpki-ghostbusters": {"source":"iana","extensions":["gbr"]}, - "application/rpki-manifest": {"source":"iana","extensions":["mft"]}, - "application/rpki-publication": {"source":"iana"}, - "application/rpki-roa": {"source":"iana","extensions":["roa"]}, - "application/rpki-signed-tal": {"source":"iana"}, - "application/rpki-updown": {"source":"iana"}, - "application/rsd+xml": {"source":"apache","compressible":true,"extensions":["rsd"]}, - "application/rss+xml": {"source":"apache","compressible":true,"extensions":["rss"]}, - "application/rtf": {"source":"iana","compressible":true,"extensions":["rtf"]}, - "application/rtploopback": {"source":"iana"}, - "application/rtx": {"source":"iana"}, - "application/samlassertion+xml": {"source":"iana","compressible":true}, - "application/samlmetadata+xml": {"source":"iana","compressible":true}, - "application/sarif+json": {"source":"iana","compressible":true}, - "application/sarif-external-properties+json": {"source":"iana","compressible":true}, - "application/sbe": {"source":"iana"}, - "application/sbml+xml": {"source":"iana","compressible":true,"extensions":["sbml"]}, - "application/scaip+xml": {"source":"iana","compressible":true}, - "application/scim+json": {"source":"iana","compressible":true}, - "application/scvp-cv-request": {"source":"iana","extensions":["scq"]}, - "application/scvp-cv-response": {"source":"iana","extensions":["scs"]}, - "application/scvp-vp-request": {"source":"iana","extensions":["spq"]}, - "application/scvp-vp-response": {"source":"iana","extensions":["spp"]}, - "application/sdp": {"source":"iana","extensions":["sdp"]}, - "application/secevent+jwt": {"source":"iana"}, - "application/senml+cbor": {"source":"iana"}, - "application/senml+json": {"source":"iana","compressible":true}, - "application/senml+xml": {"source":"iana","compressible":true,"extensions":["senmlx"]}, - "application/senml-etch+cbor": {"source":"iana"}, - "application/senml-etch+json": {"source":"iana","compressible":true}, - "application/senml-exi": {"source":"iana"}, - "application/sensml+cbor": {"source":"iana"}, - "application/sensml+json": {"source":"iana","compressible":true}, - "application/sensml+xml": {"source":"iana","compressible":true,"extensions":["sensmlx"]}, - "application/sensml-exi": {"source":"iana"}, - "application/sep+xml": {"source":"iana","compressible":true}, - "application/sep-exi": {"source":"iana"}, - "application/session-info": {"source":"iana"}, - "application/set-payment": {"source":"iana"}, - "application/set-payment-initiation": {"source":"iana","extensions":["setpay"]}, - "application/set-registration": {"source":"iana"}, - "application/set-registration-initiation": {"source":"iana","extensions":["setreg"]}, - "application/sgml": {"source":"iana"}, - "application/sgml-open-catalog": {"source":"iana"}, - "application/shf+xml": {"source":"iana","compressible":true,"extensions":["shf"]}, - "application/sieve": {"source":"iana","extensions":["siv","sieve"]}, - "application/simple-filter+xml": {"source":"iana","compressible":true}, - "application/simple-message-summary": {"source":"iana"}, - "application/simplesymbolcontainer": {"source":"iana"}, - "application/sipc": {"source":"iana"}, - "application/slate": {"source":"iana"}, - "application/smil": {"source":"apache"}, - "application/smil+xml": {"source":"iana","compressible":true,"extensions":["smi","smil"]}, - "application/smpte336m": {"source":"iana"}, - "application/soap+fastinfoset": {"source":"iana"}, - "application/soap+xml": {"source":"iana","compressible":true}, - "application/sparql-query": {"source":"iana","extensions":["rq"]}, - "application/sparql-results+xml": {"source":"iana","compressible":true,"extensions":["srx"]}, - "application/spdx+json": {"source":"iana","compressible":true}, - "application/spirits-event+xml": {"source":"iana","compressible":true}, - "application/sql": {"source":"iana","extensions":["sql"]}, - "application/srgs": {"source":"iana","extensions":["gram"]}, - "application/srgs+xml": {"source":"iana","compressible":true,"extensions":["grxml"]}, - "application/sru+xml": {"source":"iana","compressible":true,"extensions":["sru"]}, - "application/ssdl+xml": {"source":"apache","compressible":true,"extensions":["ssdl"]}, - "application/sslkeylogfile": {"source":"iana"}, - "application/ssml+xml": {"source":"iana","compressible":true,"extensions":["ssml"]}, - "application/st2110-41": {"source":"iana"}, - "application/stix+json": {"source":"iana","compressible":true}, - "application/stratum": {"source":"iana"}, - "application/swid+cbor": {"source":"iana"}, - "application/swid+xml": {"source":"iana","compressible":true,"extensions":["swidtag"]}, - "application/tamp-apex-update": {"source":"iana"}, - "application/tamp-apex-update-confirm": {"source":"iana"}, - "application/tamp-community-update": {"source":"iana"}, - "application/tamp-community-update-confirm": {"source":"iana"}, - "application/tamp-error": {"source":"iana"}, - "application/tamp-sequence-adjust": {"source":"iana"}, - "application/tamp-sequence-adjust-confirm": {"source":"iana"}, - "application/tamp-status-query": {"source":"iana"}, - "application/tamp-status-response": {"source":"iana"}, - "application/tamp-update": {"source":"iana"}, - "application/tamp-update-confirm": {"source":"iana"}, - "application/tar": {"compressible":true}, - "application/taxii+json": {"source":"iana","compressible":true}, - "application/td+json": {"source":"iana","compressible":true}, - "application/tei+xml": {"source":"iana","compressible":true,"extensions":["tei","teicorpus"]}, - "application/tetra_isi": {"source":"iana"}, - "application/thraud+xml": {"source":"iana","compressible":true,"extensions":["tfi"]}, - "application/timestamp-query": {"source":"iana"}, - "application/timestamp-reply": {"source":"iana"}, - "application/timestamped-data": {"source":"iana","extensions":["tsd"]}, - "application/tlsrpt+gzip": {"source":"iana"}, - "application/tlsrpt+json": {"source":"iana","compressible":true}, - "application/tm+json": {"source":"iana","compressible":true}, - "application/tnauthlist": {"source":"iana"}, - "application/toc+cbor": {"source":"iana"}, - "application/token-introspection+jwt": {"source":"iana"}, - "application/toml": {"source":"iana","compressible":true,"extensions":["toml"]}, - "application/trickle-ice-sdpfrag": {"source":"iana"}, - "application/trig": {"source":"iana","extensions":["trig"]}, - "application/trust-chain+json": {"source":"iana","compressible":true}, - "application/trust-mark+jwt": {"source":"iana"}, - "application/trust-mark-delegation+jwt": {"source":"iana"}, - "application/ttml+xml": {"source":"iana","compressible":true,"extensions":["ttml"]}, - "application/tve-trigger": {"source":"iana"}, - "application/tzif": {"source":"iana"}, - "application/tzif-leap": {"source":"iana"}, - "application/ubjson": {"compressible":false,"extensions":["ubj"]}, - "application/uccs+cbor": {"source":"iana"}, - "application/ujcs+json": {"source":"iana","compressible":true}, - "application/ulpfec": {"source":"iana"}, - "application/urc-grpsheet+xml": {"source":"iana","compressible":true}, - "application/urc-ressheet+xml": {"source":"iana","compressible":true,"extensions":["rsheet"]}, - "application/urc-targetdesc+xml": {"source":"iana","compressible":true,"extensions":["td"]}, - "application/urc-uisocketdesc+xml": {"source":"iana","compressible":true}, - "application/vc": {"source":"iana"}, - "application/vc+cose": {"source":"iana"}, - "application/vc+jwt": {"source":"iana"}, - "application/vcard+json": {"source":"iana","compressible":true}, - "application/vcard+xml": {"source":"iana","compressible":true}, - "application/vemmi": {"source":"iana"}, - "application/vividence.scriptfile": {"source":"apache"}, - "application/vnd.1000minds.decision-model+xml": {"source":"iana","compressible":true,"extensions":["1km"]}, - "application/vnd.1ob": {"source":"iana"}, - "application/vnd.3gpp-prose+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp-prose-pc3a+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp-prose-pc3ach+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp-prose-pc3ch+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp-prose-pc8+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp-v2x-local-service-information": {"source":"iana"}, - "application/vnd.3gpp.5gnas": {"source":"iana"}, - "application/vnd.3gpp.5gsa2x": {"source":"iana"}, - "application/vnd.3gpp.5gsa2x-local-service-information": {"source":"iana"}, - "application/vnd.3gpp.5gsv2x": {"source":"iana"}, - "application/vnd.3gpp.5gsv2x-local-service-information": {"source":"iana"}, - "application/vnd.3gpp.access-transfer-events+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.bsf+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.crs+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.current-location-discovery+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.gmop+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.gtpc": {"source":"iana"}, - "application/vnd.3gpp.interworking-data": {"source":"iana"}, - "application/vnd.3gpp.lpp": {"source":"iana"}, - "application/vnd.3gpp.mc-signalling-ear": {"source":"iana"}, - "application/vnd.3gpp.mcdata-affiliation-command+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.mcdata-info+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.mcdata-msgstore-ctrl-request+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.mcdata-payload": {"source":"iana"}, - "application/vnd.3gpp.mcdata-regroup+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.mcdata-service-config+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.mcdata-signalling": {"source":"iana"}, - "application/vnd.3gpp.mcdata-ue-config+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.mcdata-user-profile+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.mcptt-affiliation-command+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.mcptt-floor-request+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.mcptt-info+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.mcptt-location-info+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.mcptt-mbms-usage-info+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.mcptt-regroup+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.mcptt-service-config+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.mcptt-signed+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.mcptt-ue-config+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.mcptt-ue-init-config+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.mcptt-user-profile+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.mcvideo-affiliation-command+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.mcvideo-info+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.mcvideo-location-info+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.mcvideo-mbms-usage-info+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.mcvideo-regroup+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.mcvideo-service-config+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.mcvideo-transmission-request+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.mcvideo-ue-config+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.mcvideo-user-profile+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.mid-call+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.ngap": {"source":"iana"}, - "application/vnd.3gpp.pfcp": {"source":"iana"}, - "application/vnd.3gpp.pic-bw-large": {"source":"iana","extensions":["plb"]}, - "application/vnd.3gpp.pic-bw-small": {"source":"iana","extensions":["psb"]}, - "application/vnd.3gpp.pic-bw-var": {"source":"iana","extensions":["pvb"]}, - "application/vnd.3gpp.pinapp-info+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.s1ap": {"source":"iana"}, - "application/vnd.3gpp.seal-group-doc+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.seal-info+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.seal-location-info+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.seal-mbms-usage-info+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.seal-network-qos-management-info+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.seal-ue-config-info+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.seal-unicast-info+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.seal-user-profile-info+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.sms": {"source":"iana"}, - "application/vnd.3gpp.sms+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.srvcc-ext+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.srvcc-info+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.state-and-event-info+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.ussd+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp.v2x": {"source":"iana"}, - "application/vnd.3gpp.vae-info+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp2.bcmcsinfo+xml": {"source":"iana","compressible":true}, - "application/vnd.3gpp2.sms": {"source":"iana"}, - "application/vnd.3gpp2.tcap": {"source":"iana","extensions":["tcap"]}, - "application/vnd.3lightssoftware.imagescal": {"source":"iana"}, - "application/vnd.3m.post-it-notes": {"source":"iana","extensions":["pwn"]}, - "application/vnd.accpac.simply.aso": {"source":"iana","extensions":["aso"]}, - "application/vnd.accpac.simply.imp": {"source":"iana","extensions":["imp"]}, - "application/vnd.acm.addressxfer+json": {"source":"iana","compressible":true}, - "application/vnd.acm.chatbot+json": {"source":"iana","compressible":true}, - "application/vnd.acucobol": {"source":"iana","extensions":["acu"]}, - "application/vnd.acucorp": {"source":"iana","extensions":["atc","acutc"]}, - "application/vnd.adobe.air-application-installer-package+zip": {"source":"apache","compressible":false,"extensions":["air"]}, - "application/vnd.adobe.flash.movie": {"source":"iana"}, - "application/vnd.adobe.formscentral.fcdt": {"source":"iana","extensions":["fcdt"]}, - "application/vnd.adobe.fxp": {"source":"iana","extensions":["fxp","fxpl"]}, - "application/vnd.adobe.partial-upload": {"source":"iana"}, - "application/vnd.adobe.xdp+xml": {"source":"iana","compressible":true,"extensions":["xdp"]}, - "application/vnd.adobe.xfdf": {"source":"apache","extensions":["xfdf"]}, - "application/vnd.aether.imp": {"source":"iana"}, - "application/vnd.afpc.afplinedata": {"source":"iana"}, - "application/vnd.afpc.afplinedata-pagedef": {"source":"iana"}, - "application/vnd.afpc.cmoca-cmresource": {"source":"iana"}, - "application/vnd.afpc.foca-charset": {"source":"iana"}, - "application/vnd.afpc.foca-codedfont": {"source":"iana"}, - "application/vnd.afpc.foca-codepage": {"source":"iana"}, - "application/vnd.afpc.modca": {"source":"iana"}, - "application/vnd.afpc.modca-cmtable": {"source":"iana"}, - "application/vnd.afpc.modca-formdef": {"source":"iana"}, - "application/vnd.afpc.modca-mediummap": {"source":"iana"}, - "application/vnd.afpc.modca-objectcontainer": {"source":"iana"}, - "application/vnd.afpc.modca-overlay": {"source":"iana"}, - "application/vnd.afpc.modca-pagesegment": {"source":"iana"}, - "application/vnd.age": {"source":"iana","extensions":["age"]}, - "application/vnd.ah-barcode": {"source":"apache"}, - "application/vnd.ahead.space": {"source":"iana","extensions":["ahead"]}, - "application/vnd.airzip.filesecure.azf": {"source":"iana","extensions":["azf"]}, - "application/vnd.airzip.filesecure.azs": {"source":"iana","extensions":["azs"]}, - "application/vnd.amadeus+json": {"source":"iana","compressible":true}, - "application/vnd.amazon.ebook": {"source":"apache","extensions":["azw"]}, - "application/vnd.amazon.mobi8-ebook": {"source":"iana"}, - "application/vnd.americandynamics.acc": {"source":"iana","extensions":["acc"]}, - "application/vnd.amiga.ami": {"source":"iana","extensions":["ami"]}, - "application/vnd.amundsen.maze+xml": {"source":"iana","compressible":true}, - "application/vnd.android.ota": {"source":"iana"}, - "application/vnd.android.package-archive": {"source":"apache","compressible":false,"extensions":["apk"]}, - "application/vnd.anki": {"source":"iana"}, - "application/vnd.anser-web-certificate-issue-initiation": {"source":"iana","extensions":["cii"]}, - "application/vnd.anser-web-funds-transfer-initiation": {"source":"apache","extensions":["fti"]}, - "application/vnd.antix.game-component": {"source":"iana","extensions":["atx"]}, - "application/vnd.apache.arrow.file": {"source":"iana"}, - "application/vnd.apache.arrow.stream": {"source":"iana"}, - "application/vnd.apache.parquet": {"source":"iana"}, - "application/vnd.apache.thrift.binary": {"source":"iana"}, - "application/vnd.apache.thrift.compact": {"source":"iana"}, - "application/vnd.apache.thrift.json": {"source":"iana"}, - "application/vnd.apexlang": {"source":"iana"}, - "application/vnd.api+json": {"source":"iana","compressible":true}, - "application/vnd.aplextor.warrp+json": {"source":"iana","compressible":true}, - "application/vnd.apothekende.reservation+json": {"source":"iana","compressible":true}, - "application/vnd.apple.installer+xml": {"source":"iana","compressible":true,"extensions":["mpkg"]}, - "application/vnd.apple.keynote": {"source":"iana","extensions":["key"]}, - "application/vnd.apple.mpegurl": {"source":"iana","extensions":["m3u8"]}, - "application/vnd.apple.numbers": {"source":"iana","extensions":["numbers"]}, - "application/vnd.apple.pages": {"source":"iana","extensions":["pages"]}, - "application/vnd.apple.pkpass": {"compressible":false,"extensions":["pkpass"]}, - "application/vnd.arastra.swi": {"source":"apache"}, - "application/vnd.aristanetworks.swi": {"source":"iana","extensions":["swi"]}, - "application/vnd.artisan+json": {"source":"iana","compressible":true}, - "application/vnd.artsquare": {"source":"iana"}, - "application/vnd.astraea-software.iota": {"source":"iana","extensions":["iota"]}, - "application/vnd.audiograph": {"source":"iana","extensions":["aep"]}, - "application/vnd.autodesk.fbx": {"extensions":["fbx"]}, - "application/vnd.autopackage": {"source":"iana"}, - "application/vnd.avalon+json": {"source":"iana","compressible":true}, - "application/vnd.avistar+xml": {"source":"iana","compressible":true}, - "application/vnd.balsamiq.bmml+xml": {"source":"iana","compressible":true,"extensions":["bmml"]}, - "application/vnd.balsamiq.bmpr": {"source":"iana"}, - "application/vnd.banana-accounting": {"source":"iana"}, - "application/vnd.bbf.usp.error": {"source":"iana"}, - "application/vnd.bbf.usp.msg": {"source":"iana"}, - "application/vnd.bbf.usp.msg+json": {"source":"iana","compressible":true}, - "application/vnd.bekitzur-stech+json": {"source":"iana","compressible":true}, - "application/vnd.belightsoft.lhzd+zip": {"source":"iana","compressible":false}, - "application/vnd.belightsoft.lhzl+zip": {"source":"iana","compressible":false}, - "application/vnd.bint.med-content": {"source":"iana"}, - "application/vnd.biopax.rdf+xml": {"source":"iana","compressible":true}, - "application/vnd.blink-idb-value-wrapper": {"source":"iana"}, - "application/vnd.blueice.multipass": {"source":"iana","extensions":["mpm"]}, - "application/vnd.bluetooth.ep.oob": {"source":"iana"}, - "application/vnd.bluetooth.le.oob": {"source":"iana"}, - "application/vnd.bmi": {"source":"iana","extensions":["bmi"]}, - "application/vnd.bpf": {"source":"iana"}, - "application/vnd.bpf3": {"source":"iana"}, - "application/vnd.businessobjects": {"source":"iana","extensions":["rep"]}, - "application/vnd.byu.uapi+json": {"source":"iana","compressible":true}, - "application/vnd.bzip3": {"source":"iana"}, - "application/vnd.c3voc.schedule+xml": {"source":"iana","compressible":true}, - "application/vnd.cab-jscript": {"source":"iana"}, - "application/vnd.canon-cpdl": {"source":"iana"}, - "application/vnd.canon-lips": {"source":"iana"}, - "application/vnd.capasystems-pg+json": {"source":"iana","compressible":true}, - "application/vnd.cendio.thinlinc.clientconf": {"source":"iana"}, - "application/vnd.century-systems.tcp_stream": {"source":"iana"}, - "application/vnd.chemdraw+xml": {"source":"iana","compressible":true,"extensions":["cdxml"]}, - "application/vnd.chess-pgn": {"source":"iana"}, - "application/vnd.chipnuts.karaoke-mmd": {"source":"iana","extensions":["mmd"]}, - "application/vnd.ciedi": {"source":"iana"}, - "application/vnd.cinderella": {"source":"iana","extensions":["cdy"]}, - "application/vnd.cirpack.isdn-ext": {"source":"iana"}, - "application/vnd.citationstyles.style+xml": {"source":"iana","compressible":true,"extensions":["csl"]}, - "application/vnd.claymore": {"source":"iana","extensions":["cla"]}, - "application/vnd.cloanto.rp9": {"source":"iana","extensions":["rp9"]}, - "application/vnd.clonk.c4group": {"source":"iana","extensions":["c4g","c4d","c4f","c4p","c4u"]}, - "application/vnd.cluetrust.cartomobile-config": {"source":"iana","extensions":["c11amc"]}, - "application/vnd.cluetrust.cartomobile-config-pkg": {"source":"iana","extensions":["c11amz"]}, - "application/vnd.cncf.helm.chart.content.v1.tar+gzip": {"source":"iana"}, - "application/vnd.cncf.helm.chart.provenance.v1.prov": {"source":"iana"}, - "application/vnd.cncf.helm.config.v1+json": {"source":"iana","compressible":true}, - "application/vnd.coffeescript": {"source":"iana"}, - "application/vnd.collabio.xodocuments.document": {"source":"iana"}, - "application/vnd.collabio.xodocuments.document-template": {"source":"iana"}, - "application/vnd.collabio.xodocuments.presentation": {"source":"iana"}, - "application/vnd.collabio.xodocuments.presentation-template": {"source":"iana"}, - "application/vnd.collabio.xodocuments.spreadsheet": {"source":"iana"}, - "application/vnd.collabio.xodocuments.spreadsheet-template": {"source":"iana"}, - "application/vnd.collection+json": {"source":"iana","compressible":true}, - "application/vnd.collection.doc+json": {"source":"iana","compressible":true}, - "application/vnd.collection.next+json": {"source":"iana","compressible":true}, - "application/vnd.comicbook+zip": {"source":"iana","compressible":false}, - "application/vnd.comicbook-rar": {"source":"iana"}, - "application/vnd.commerce-battelle": {"source":"iana"}, - "application/vnd.commonspace": {"source":"iana","extensions":["csp"]}, - "application/vnd.contact.cmsg": {"source":"iana","extensions":["cdbcmsg"]}, - "application/vnd.coreos.ignition+json": {"source":"iana","compressible":true}, - "application/vnd.cosmocaller": {"source":"iana","extensions":["cmc"]}, - "application/vnd.crick.clicker": {"source":"iana","extensions":["clkx"]}, - "application/vnd.crick.clicker.keyboard": {"source":"iana","extensions":["clkk"]}, - "application/vnd.crick.clicker.palette": {"source":"iana","extensions":["clkp"]}, - "application/vnd.crick.clicker.template": {"source":"iana","extensions":["clkt"]}, - "application/vnd.crick.clicker.wordbank": {"source":"iana","extensions":["clkw"]}, - "application/vnd.criticaltools.wbs+xml": {"source":"iana","compressible":true,"extensions":["wbs"]}, - "application/vnd.cryptii.pipe+json": {"source":"iana","compressible":true}, - "application/vnd.crypto-shade-file": {"source":"iana"}, - "application/vnd.cryptomator.encrypted": {"source":"iana"}, - "application/vnd.cryptomator.vault": {"source":"iana"}, - "application/vnd.ctc-posml": {"source":"iana","extensions":["pml"]}, - "application/vnd.ctct.ws+xml": {"source":"iana","compressible":true}, - "application/vnd.cups-pdf": {"source":"iana"}, - "application/vnd.cups-postscript": {"source":"iana"}, - "application/vnd.cups-ppd": {"source":"iana","extensions":["ppd"]}, - "application/vnd.cups-raster": {"source":"iana"}, - "application/vnd.cups-raw": {"source":"iana"}, - "application/vnd.curl": {"source":"iana"}, - "application/vnd.curl.car": {"source":"apache","extensions":["car"]}, - "application/vnd.curl.pcurl": {"source":"apache","extensions":["pcurl"]}, - "application/vnd.cyan.dean.root+xml": {"source":"iana","compressible":true}, - "application/vnd.cybank": {"source":"iana"}, - "application/vnd.cyclonedx+json": {"source":"iana","compressible":true}, - "application/vnd.cyclonedx+xml": {"source":"iana","compressible":true}, - "application/vnd.d2l.coursepackage1p0+zip": {"source":"iana","compressible":false}, - "application/vnd.d3m-dataset": {"source":"iana"}, - "application/vnd.d3m-problem": {"source":"iana"}, - "application/vnd.dart": {"source":"iana","compressible":true,"extensions":["dart"]}, - "application/vnd.data-vision.rdz": {"source":"iana","extensions":["rdz"]}, - "application/vnd.datalog": {"source":"iana"}, - "application/vnd.datapackage+json": {"source":"iana","compressible":true}, - "application/vnd.dataresource+json": {"source":"iana","compressible":true}, - "application/vnd.dbf": {"source":"iana","extensions":["dbf"]}, - "application/vnd.dcmp+xml": {"source":"iana","compressible":true,"extensions":["dcmp"]}, - "application/vnd.debian.binary-package": {"source":"iana"}, - "application/vnd.dece.data": {"source":"iana","extensions":["uvf","uvvf","uvd","uvvd"]}, - "application/vnd.dece.ttml+xml": {"source":"iana","compressible":true,"extensions":["uvt","uvvt"]}, - "application/vnd.dece.unspecified": {"source":"iana","extensions":["uvx","uvvx"]}, - "application/vnd.dece.zip": {"source":"iana","extensions":["uvz","uvvz"]}, - "application/vnd.denovo.fcselayout-link": {"source":"iana","extensions":["fe_launch"]}, - "application/vnd.desmume.movie": {"source":"iana"}, - "application/vnd.dir-bi.plate-dl-nosuffix": {"source":"iana"}, - "application/vnd.dm.delegation+xml": {"source":"iana","compressible":true}, - "application/vnd.dna": {"source":"iana","extensions":["dna"]}, - "application/vnd.document+json": {"source":"iana","compressible":true}, - "application/vnd.dolby.mlp": {"source":"apache","extensions":["mlp"]}, - "application/vnd.dolby.mobile.1": {"source":"iana"}, - "application/vnd.dolby.mobile.2": {"source":"iana"}, - "application/vnd.doremir.scorecloud-binary-document": {"source":"iana"}, - "application/vnd.dpgraph": {"source":"iana","extensions":["dpg"]}, - "application/vnd.dreamfactory": {"source":"iana","extensions":["dfac"]}, - "application/vnd.drive+json": {"source":"iana","compressible":true}, - "application/vnd.ds-keypoint": {"source":"apache","extensions":["kpxx"]}, - "application/vnd.dtg.local": {"source":"iana"}, - "application/vnd.dtg.local.flash": {"source":"iana"}, - "application/vnd.dtg.local.html": {"source":"iana"}, - "application/vnd.dvb.ait": {"source":"iana","extensions":["ait"]}, - "application/vnd.dvb.dvbisl+xml": {"source":"iana","compressible":true}, - "application/vnd.dvb.dvbj": {"source":"iana"}, - "application/vnd.dvb.esgcontainer": {"source":"iana"}, - "application/vnd.dvb.ipdcdftnotifaccess": {"source":"iana"}, - "application/vnd.dvb.ipdcesgaccess": {"source":"iana"}, - "application/vnd.dvb.ipdcesgaccess2": {"source":"iana"}, - "application/vnd.dvb.ipdcesgpdd": {"source":"iana"}, - "application/vnd.dvb.ipdcroaming": {"source":"iana"}, - "application/vnd.dvb.iptv.alfec-base": {"source":"iana"}, - "application/vnd.dvb.iptv.alfec-enhancement": {"source":"iana"}, - "application/vnd.dvb.notif-aggregate-root+xml": {"source":"iana","compressible":true}, - "application/vnd.dvb.notif-container+xml": {"source":"iana","compressible":true}, - "application/vnd.dvb.notif-generic+xml": {"source":"iana","compressible":true}, - "application/vnd.dvb.notif-ia-msglist+xml": {"source":"iana","compressible":true}, - "application/vnd.dvb.notif-ia-registration-request+xml": {"source":"iana","compressible":true}, - "application/vnd.dvb.notif-ia-registration-response+xml": {"source":"iana","compressible":true}, - "application/vnd.dvb.notif-init+xml": {"source":"iana","compressible":true}, - "application/vnd.dvb.pfr": {"source":"iana"}, - "application/vnd.dvb.service": {"source":"iana","extensions":["svc"]}, - "application/vnd.dxr": {"source":"iana"}, - "application/vnd.dynageo": {"source":"iana","extensions":["geo"]}, - "application/vnd.dzr": {"source":"iana"}, - "application/vnd.easykaraoke.cdgdownload": {"source":"iana"}, - "application/vnd.ecdis-update": {"source":"iana"}, - "application/vnd.ecip.rlp": {"source":"iana"}, - "application/vnd.eclipse.ditto+json": {"source":"iana","compressible":true}, - "application/vnd.ecowin.chart": {"source":"iana","extensions":["mag"]}, - "application/vnd.ecowin.filerequest": {"source":"iana"}, - "application/vnd.ecowin.fileupdate": {"source":"iana"}, - "application/vnd.ecowin.series": {"source":"iana"}, - "application/vnd.ecowin.seriesrequest": {"source":"iana"}, - "application/vnd.ecowin.seriesupdate": {"source":"iana"}, - "application/vnd.efi.img": {"source":"iana"}, - "application/vnd.efi.iso": {"source":"iana"}, - "application/vnd.eln+zip": {"source":"iana","compressible":false}, - "application/vnd.emclient.accessrequest+xml": {"source":"iana","compressible":true}, - "application/vnd.enliven": {"source":"iana","extensions":["nml"]}, - "application/vnd.enphase.envoy": {"source":"iana"}, - "application/vnd.eprints.data+xml": {"source":"iana","compressible":true}, - "application/vnd.epson.esf": {"source":"iana","extensions":["esf"]}, - "application/vnd.epson.msf": {"source":"iana","extensions":["msf"]}, - "application/vnd.epson.quickanime": {"source":"iana","extensions":["qam"]}, - "application/vnd.epson.salt": {"source":"iana","extensions":["slt"]}, - "application/vnd.epson.ssf": {"source":"iana","extensions":["ssf"]}, - "application/vnd.ericsson.quickcall": {"source":"iana"}, - "application/vnd.erofs": {"source":"iana"}, - "application/vnd.espass-espass+zip": {"source":"iana","compressible":false}, - "application/vnd.eszigno3+xml": {"source":"iana","compressible":true,"extensions":["es3","et3"]}, - "application/vnd.etsi.aoc+xml": {"source":"iana","compressible":true}, - "application/vnd.etsi.asic-e+zip": {"source":"iana","compressible":false}, - "application/vnd.etsi.asic-s+zip": {"source":"iana","compressible":false}, - "application/vnd.etsi.cug+xml": {"source":"iana","compressible":true}, - "application/vnd.etsi.iptvcommand+xml": {"source":"iana","compressible":true}, - "application/vnd.etsi.iptvdiscovery+xml": {"source":"iana","compressible":true}, - "application/vnd.etsi.iptvprofile+xml": {"source":"iana","compressible":true}, - "application/vnd.etsi.iptvsad-bc+xml": {"source":"iana","compressible":true}, - "application/vnd.etsi.iptvsad-cod+xml": {"source":"iana","compressible":true}, - "application/vnd.etsi.iptvsad-npvr+xml": {"source":"iana","compressible":true}, - "application/vnd.etsi.iptvservice+xml": {"source":"iana","compressible":true}, - "application/vnd.etsi.iptvsync+xml": {"source":"iana","compressible":true}, - "application/vnd.etsi.iptvueprofile+xml": {"source":"iana","compressible":true}, - "application/vnd.etsi.mcid+xml": {"source":"iana","compressible":true}, - "application/vnd.etsi.mheg5": {"source":"iana"}, - "application/vnd.etsi.overload-control-policy-dataset+xml": {"source":"iana","compressible":true}, - "application/vnd.etsi.pstn+xml": {"source":"iana","compressible":true}, - "application/vnd.etsi.sci+xml": {"source":"iana","compressible":true}, - "application/vnd.etsi.simservs+xml": {"source":"iana","compressible":true}, - "application/vnd.etsi.timestamp-token": {"source":"iana"}, - "application/vnd.etsi.tsl+xml": {"source":"iana","compressible":true}, - "application/vnd.etsi.tsl.der": {"source":"iana"}, - "application/vnd.eu.kasparian.car+json": {"source":"iana","compressible":true}, - "application/vnd.eudora.data": {"source":"iana"}, - "application/vnd.evolv.ecig.profile": {"source":"iana"}, - "application/vnd.evolv.ecig.settings": {"source":"iana"}, - "application/vnd.evolv.ecig.theme": {"source":"iana"}, - "application/vnd.exstream-empower+zip": {"source":"iana","compressible":false}, - "application/vnd.exstream-package": {"source":"iana"}, - "application/vnd.ezpix-album": {"source":"iana","extensions":["ez2"]}, - "application/vnd.ezpix-package": {"source":"iana","extensions":["ez3"]}, - "application/vnd.f-secure.mobile": {"source":"iana"}, - "application/vnd.familysearch.gedcom+zip": {"source":"iana","compressible":false}, - "application/vnd.fastcopy-disk-image": {"source":"iana"}, - "application/vnd.fdf": {"source":"apache","extensions":["fdf"]}, - "application/vnd.fdsn.mseed": {"source":"iana","extensions":["mseed"]}, - "application/vnd.fdsn.seed": {"source":"iana","extensions":["seed","dataless"]}, - "application/vnd.fdsn.stationxml+xml": {"source":"iana","charset":"XML-BASED","compressible":true}, - "application/vnd.ffsns": {"source":"iana"}, - "application/vnd.ficlab.flb+zip": {"source":"iana","compressible":false}, - "application/vnd.filmit.zfc": {"source":"iana"}, - "application/vnd.fints": {"source":"iana"}, - "application/vnd.firemonkeys.cloudcell": {"source":"iana"}, - "application/vnd.flographit": {"source":"iana","extensions":["gph"]}, - "application/vnd.fluxtime.clip": {"source":"iana","extensions":["ftc"]}, - "application/vnd.font-fontforge-sfd": {"source":"iana"}, - "application/vnd.framemaker": {"source":"iana","extensions":["fm","frame","maker","book"]}, - "application/vnd.freelog.comic": {"source":"iana"}, - "application/vnd.frogans.fnc": {"source":"apache","extensions":["fnc"]}, - "application/vnd.frogans.ltf": {"source":"apache","extensions":["ltf"]}, - "application/vnd.fsc.weblaunch": {"source":"iana","extensions":["fsc"]}, - "application/vnd.fujifilm.fb.docuworks": {"source":"iana"}, - "application/vnd.fujifilm.fb.docuworks.binder": {"source":"iana"}, - "application/vnd.fujifilm.fb.docuworks.container": {"source":"iana"}, - "application/vnd.fujifilm.fb.jfi+xml": {"source":"iana","compressible":true}, - "application/vnd.fujitsu.oasys": {"source":"iana","extensions":["oas"]}, - "application/vnd.fujitsu.oasys2": {"source":"iana","extensions":["oa2"]}, - "application/vnd.fujitsu.oasys3": {"source":"iana","extensions":["oa3"]}, - "application/vnd.fujitsu.oasysgp": {"source":"iana","extensions":["fg5"]}, - "application/vnd.fujitsu.oasysprs": {"source":"iana","extensions":["bh2"]}, - "application/vnd.fujixerox.art-ex": {"source":"iana"}, - "application/vnd.fujixerox.art4": {"source":"iana"}, - "application/vnd.fujixerox.ddd": {"source":"iana","extensions":["ddd"]}, - "application/vnd.fujixerox.docuworks": {"source":"iana","extensions":["xdw"]}, - "application/vnd.fujixerox.docuworks.binder": {"source":"iana","extensions":["xbd"]}, - "application/vnd.fujixerox.docuworks.container": {"source":"iana"}, - "application/vnd.fujixerox.hbpl": {"source":"iana"}, - "application/vnd.fut-misnet": {"source":"iana"}, - "application/vnd.futoin+cbor": {"source":"iana"}, - "application/vnd.futoin+json": {"source":"iana","compressible":true}, - "application/vnd.fuzzysheet": {"source":"iana","extensions":["fzs"]}, - "application/vnd.ga4gh.passport+jwt": {"source":"iana"}, - "application/vnd.genomatix.tuxedo": {"source":"iana","extensions":["txd"]}, - "application/vnd.genozip": {"source":"iana"}, - "application/vnd.gentics.grd+json": {"source":"iana","compressible":true}, - "application/vnd.gentoo.catmetadata+xml": {"source":"iana","compressible":true}, - "application/vnd.gentoo.ebuild": {"source":"iana"}, - "application/vnd.gentoo.eclass": {"source":"iana"}, - "application/vnd.gentoo.gpkg": {"source":"iana"}, - "application/vnd.gentoo.manifest": {"source":"iana"}, - "application/vnd.gentoo.pkgmetadata+xml": {"source":"iana","compressible":true}, - "application/vnd.gentoo.xpak": {"source":"iana"}, - "application/vnd.geo+json": {"source":"apache","compressible":true}, - "application/vnd.geocube+xml": {"source":"apache","compressible":true}, - "application/vnd.geogebra.file": {"source":"iana","extensions":["ggb"]}, - "application/vnd.geogebra.pinboard": {"source":"iana"}, - "application/vnd.geogebra.slides": {"source":"iana","extensions":["ggs"]}, - "application/vnd.geogebra.tool": {"source":"iana","extensions":["ggt"]}, - "application/vnd.geometry-explorer": {"source":"iana","extensions":["gex","gre"]}, - "application/vnd.geonext": {"source":"iana","extensions":["gxt"]}, - "application/vnd.geoplan": {"source":"iana","extensions":["g2w"]}, - "application/vnd.geospace": {"source":"iana","extensions":["g3w"]}, - "application/vnd.gerber": {"source":"iana"}, - "application/vnd.globalplatform.card-content-mgt": {"source":"iana"}, - "application/vnd.globalplatform.card-content-mgt-response": {"source":"iana"}, - "application/vnd.gmx": {"source":"iana","extensions":["gmx"]}, - "application/vnd.gnu.taler.exchange+json": {"source":"iana","compressible":true}, - "application/vnd.gnu.taler.merchant+json": {"source":"iana","compressible":true}, - "application/vnd.google-apps.audio": {}, - "application/vnd.google-apps.document": {"compressible":false,"extensions":["gdoc"]}, - "application/vnd.google-apps.drawing": {"compressible":false,"extensions":["gdraw"]}, - "application/vnd.google-apps.drive-sdk": {"compressible":false}, - "application/vnd.google-apps.file": {}, - "application/vnd.google-apps.folder": {"compressible":false}, - "application/vnd.google-apps.form": {"compressible":false,"extensions":["gform"]}, - "application/vnd.google-apps.fusiontable": {}, - "application/vnd.google-apps.jam": {"compressible":false,"extensions":["gjam"]}, - "application/vnd.google-apps.mail-layout": {}, - "application/vnd.google-apps.map": {"compressible":false,"extensions":["gmap"]}, - "application/vnd.google-apps.photo": {}, - "application/vnd.google-apps.presentation": {"compressible":false,"extensions":["gslides"]}, - "application/vnd.google-apps.script": {"compressible":false,"extensions":["gscript"]}, - "application/vnd.google-apps.shortcut": {}, - "application/vnd.google-apps.site": {"compressible":false,"extensions":["gsite"]}, - "application/vnd.google-apps.spreadsheet": {"compressible":false,"extensions":["gsheet"]}, - "application/vnd.google-apps.unknown": {}, - "application/vnd.google-apps.video": {}, - "application/vnd.google-earth.kml+xml": {"source":"iana","compressible":true,"extensions":["kml"]}, - "application/vnd.google-earth.kmz": {"source":"iana","compressible":false,"extensions":["kmz"]}, - "application/vnd.gov.sk.e-form+xml": {"source":"apache","compressible":true}, - "application/vnd.gov.sk.e-form+zip": {"source":"iana","compressible":false}, - "application/vnd.gov.sk.xmldatacontainer+xml": {"source":"iana","compressible":true,"extensions":["xdcf"]}, - "application/vnd.gpxsee.map+xml": {"source":"iana","compressible":true}, - "application/vnd.grafeq": {"source":"iana","extensions":["gqf","gqs"]}, - "application/vnd.gridmp": {"source":"iana"}, - "application/vnd.groove-account": {"source":"iana","extensions":["gac"]}, - "application/vnd.groove-help": {"source":"iana","extensions":["ghf"]}, - "application/vnd.groove-identity-message": {"source":"iana","extensions":["gim"]}, - "application/vnd.groove-injector": {"source":"iana","extensions":["grv"]}, - "application/vnd.groove-tool-message": {"source":"iana","extensions":["gtm"]}, - "application/vnd.groove-tool-template": {"source":"iana","extensions":["tpl"]}, - "application/vnd.groove-vcard": {"source":"iana","extensions":["vcg"]}, - "application/vnd.hal+json": {"source":"iana","compressible":true}, - "application/vnd.hal+xml": {"source":"iana","compressible":true,"extensions":["hal"]}, - "application/vnd.handheld-entertainment+xml": {"source":"iana","compressible":true,"extensions":["zmm"]}, - "application/vnd.hbci": {"source":"iana","extensions":["hbci"]}, - "application/vnd.hc+json": {"source":"iana","compressible":true}, - "application/vnd.hcl-bireports": {"source":"iana"}, - "application/vnd.hdt": {"source":"iana"}, - "application/vnd.heroku+json": {"source":"iana","compressible":true}, - "application/vnd.hhe.lesson-player": {"source":"iana","extensions":["les"]}, - "application/vnd.hp-hpgl": {"source":"iana","extensions":["hpgl"]}, - "application/vnd.hp-hpid": {"source":"iana","extensions":["hpid"]}, - "application/vnd.hp-hps": {"source":"iana","extensions":["hps"]}, - "application/vnd.hp-jlyt": {"source":"iana","extensions":["jlt"]}, - "application/vnd.hp-pcl": {"source":"iana","extensions":["pcl"]}, - "application/vnd.hp-pclxl": {"source":"iana","extensions":["pclxl"]}, - "application/vnd.hsl": {"source":"iana"}, - "application/vnd.httphone": {"source":"iana"}, - "application/vnd.hydrostatix.sof-data": {"source":"iana","extensions":["sfd-hdstx"]}, - "application/vnd.hyper+json": {"source":"iana","compressible":true}, - "application/vnd.hyper-item+json": {"source":"iana","compressible":true}, - "application/vnd.hyperdrive+json": {"source":"iana","compressible":true}, - "application/vnd.hzn-3d-crossword": {"source":"iana"}, - "application/vnd.ibm.afplinedata": {"source":"apache"}, - "application/vnd.ibm.electronic-media": {"source":"iana"}, - "application/vnd.ibm.minipay": {"source":"iana","extensions":["mpy"]}, - "application/vnd.ibm.modcap": {"source":"apache","extensions":["afp","listafp","list3820"]}, - "application/vnd.ibm.rights-management": {"source":"iana","extensions":["irm"]}, - "application/vnd.ibm.secure-container": {"source":"iana","extensions":["sc"]}, - "application/vnd.iccprofile": {"source":"iana","extensions":["icc","icm"]}, - "application/vnd.ieee.1905": {"source":"iana"}, - "application/vnd.igloader": {"source":"iana","extensions":["igl"]}, - "application/vnd.imagemeter.folder+zip": {"source":"iana","compressible":false}, - "application/vnd.imagemeter.image+zip": {"source":"iana","compressible":false}, - "application/vnd.immervision-ivp": {"source":"iana","extensions":["ivp"]}, - "application/vnd.immervision-ivu": {"source":"iana","extensions":["ivu"]}, - "application/vnd.ims.imsccv1p1": {"source":"iana"}, - "application/vnd.ims.imsccv1p2": {"source":"iana"}, - "application/vnd.ims.imsccv1p3": {"source":"iana"}, - "application/vnd.ims.lis.v2.result+json": {"source":"iana","compressible":true}, - "application/vnd.ims.lti.v2.toolconsumerprofile+json": {"source":"iana","compressible":true}, - "application/vnd.ims.lti.v2.toolproxy+json": {"source":"iana","compressible":true}, - "application/vnd.ims.lti.v2.toolproxy.id+json": {"source":"iana","compressible":true}, - "application/vnd.ims.lti.v2.toolsettings+json": {"source":"iana","compressible":true}, - "application/vnd.ims.lti.v2.toolsettings.simple+json": {"source":"iana","compressible":true}, - "application/vnd.informedcontrol.rms+xml": {"source":"iana","compressible":true}, - "application/vnd.informix-visionary": {"source":"apache"}, - "application/vnd.infotech.project": {"source":"iana"}, - "application/vnd.infotech.project+xml": {"source":"iana","compressible":true}, - "application/vnd.innopath.wamp.notification": {"source":"iana"}, - "application/vnd.insors.igm": {"source":"iana","extensions":["igm"]}, - "application/vnd.intercon.formnet": {"source":"iana","extensions":["xpw","xpx"]}, - "application/vnd.intergeo": {"source":"iana","extensions":["i2g"]}, - "application/vnd.intertrust.digibox": {"source":"iana"}, - "application/vnd.intertrust.nncp": {"source":"iana"}, - "application/vnd.intu.qbo": {"source":"iana","extensions":["qbo"]}, - "application/vnd.intu.qfx": {"source":"iana","extensions":["qfx"]}, - "application/vnd.ipfs.ipns-record": {"source":"iana"}, - "application/vnd.ipld.car": {"source":"iana"}, - "application/vnd.ipld.dag-cbor": {"source":"iana"}, - "application/vnd.ipld.dag-json": {"source":"iana"}, - "application/vnd.ipld.raw": {"source":"iana"}, - "application/vnd.iptc.g2.catalogitem+xml": {"source":"iana","compressible":true}, - "application/vnd.iptc.g2.conceptitem+xml": {"source":"iana","compressible":true}, - "application/vnd.iptc.g2.knowledgeitem+xml": {"source":"iana","compressible":true}, - "application/vnd.iptc.g2.newsitem+xml": {"source":"iana","compressible":true}, - "application/vnd.iptc.g2.newsmessage+xml": {"source":"iana","compressible":true}, - "application/vnd.iptc.g2.packageitem+xml": {"source":"iana","compressible":true}, - "application/vnd.iptc.g2.planningitem+xml": {"source":"iana","compressible":true}, - "application/vnd.ipunplugged.rcprofile": {"source":"iana","extensions":["rcprofile"]}, - "application/vnd.irepository.package+xml": {"source":"iana","compressible":true,"extensions":["irp"]}, - "application/vnd.is-xpr": {"source":"iana","extensions":["xpr"]}, - "application/vnd.isac.fcs": {"source":"iana","extensions":["fcs"]}, - "application/vnd.iso11783-10+zip": {"source":"iana","compressible":false}, - "application/vnd.jam": {"source":"iana","extensions":["jam"]}, - "application/vnd.japannet-directory-service": {"source":"iana"}, - "application/vnd.japannet-jpnstore-wakeup": {"source":"iana"}, - "application/vnd.japannet-payment-wakeup": {"source":"iana"}, - "application/vnd.japannet-registration": {"source":"iana"}, - "application/vnd.japannet-registration-wakeup": {"source":"iana"}, - "application/vnd.japannet-setstore-wakeup": {"source":"iana"}, - "application/vnd.japannet-verification": {"source":"iana"}, - "application/vnd.japannet-verification-wakeup": {"source":"iana"}, - "application/vnd.jcp.javame.midlet-rms": {"source":"iana","extensions":["rms"]}, - "application/vnd.jisp": {"source":"iana","extensions":["jisp"]}, - "application/vnd.joost.joda-archive": {"source":"iana","extensions":["joda"]}, - "application/vnd.jsk.isdn-ngn": {"source":"iana"}, - "application/vnd.kahootz": {"source":"iana","extensions":["ktz","ktr"]}, - "application/vnd.kde.karbon": {"source":"iana","extensions":["karbon"]}, - "application/vnd.kde.kchart": {"source":"iana","extensions":["chrt"]}, - "application/vnd.kde.kformula": {"source":"iana","extensions":["kfo"]}, - "application/vnd.kde.kivio": {"source":"iana","extensions":["flw"]}, - "application/vnd.kde.kontour": {"source":"iana","extensions":["kon"]}, - "application/vnd.kde.kpresenter": {"source":"iana","extensions":["kpr","kpt"]}, - "application/vnd.kde.kspread": {"source":"iana","extensions":["ksp"]}, - "application/vnd.kde.kword": {"source":"iana","extensions":["kwd","kwt"]}, - "application/vnd.kdl": {"source":"iana"}, - "application/vnd.kenameaapp": {"source":"iana","extensions":["htke"]}, - "application/vnd.keyman.kmp+zip": {"source":"iana","compressible":false}, - "application/vnd.keyman.kmx": {"source":"iana"}, - "application/vnd.kidspiration": {"source":"iana","extensions":["kia"]}, - "application/vnd.kinar": {"source":"iana","extensions":["kne","knp"]}, - "application/vnd.koan": {"source":"iana","extensions":["skp","skd","skt","skm"]}, - "application/vnd.kodak-descriptor": {"source":"iana","extensions":["sse"]}, - "application/vnd.las": {"source":"iana"}, - "application/vnd.las.las+json": {"source":"iana","compressible":true}, - "application/vnd.las.las+xml": {"source":"iana","compressible":true,"extensions":["lasxml"]}, - "application/vnd.laszip": {"source":"iana"}, - "application/vnd.ldev.productlicensing": {"source":"iana"}, - "application/vnd.leap+json": {"source":"iana","compressible":true}, - "application/vnd.liberty-request+xml": {"source":"iana","compressible":true}, - "application/vnd.llamagraphics.life-balance.desktop": {"source":"iana","extensions":["lbd"]}, - "application/vnd.llamagraphics.life-balance.exchange+xml": {"source":"iana","compressible":true,"extensions":["lbe"]}, - "application/vnd.logipipe.circuit+zip": {"source":"iana","compressible":false}, - "application/vnd.loom": {"source":"iana"}, - "application/vnd.lotus-1-2-3": {"source":"iana","extensions":["123"]}, - "application/vnd.lotus-approach": {"source":"iana","extensions":["apr"]}, - "application/vnd.lotus-freelance": {"source":"iana","extensions":["pre"]}, - "application/vnd.lotus-notes": {"source":"iana","extensions":["nsf"]}, - "application/vnd.lotus-organizer": {"source":"iana","extensions":["org"]}, - "application/vnd.lotus-screencam": {"source":"iana","extensions":["scm"]}, - "application/vnd.lotus-wordpro": {"source":"iana","extensions":["lwp"]}, - "application/vnd.macports.portpkg": {"source":"iana","extensions":["portpkg"]}, - "application/vnd.mapbox-vector-tile": {"source":"iana","extensions":["mvt"]}, - "application/vnd.marlin.drm.actiontoken+xml": {"source":"iana","compressible":true}, - "application/vnd.marlin.drm.conftoken+xml": {"source":"iana","compressible":true}, - "application/vnd.marlin.drm.license+xml": {"source":"iana","compressible":true}, - "application/vnd.marlin.drm.mdcf": {"source":"iana"}, - "application/vnd.mason+json": {"source":"iana","compressible":true}, - "application/vnd.maxar.archive.3tz+zip": {"source":"iana","compressible":false}, - "application/vnd.maxmind.maxmind-db": {"source":"iana"}, - "application/vnd.mcd": {"source":"iana","extensions":["mcd"]}, - "application/vnd.mdl": {"source":"iana"}, - "application/vnd.mdl-mbsdf": {"source":"iana"}, - "application/vnd.medcalcdata": {"source":"iana","extensions":["mc1"]}, - "application/vnd.mediastation.cdkey": {"source":"iana","extensions":["cdkey"]}, - "application/vnd.medicalholodeck.recordxr": {"source":"iana"}, - "application/vnd.meridian-slingshot": {"source":"iana"}, - "application/vnd.mermaid": {"source":"iana"}, - "application/vnd.mfer": {"source":"iana","extensions":["mwf"]}, - "application/vnd.mfmp": {"source":"iana","extensions":["mfm"]}, - "application/vnd.micro+json": {"source":"iana","compressible":true}, - "application/vnd.micrografx.flo": {"source":"iana","extensions":["flo"]}, - "application/vnd.micrografx.igx": {"source":"iana","extensions":["igx"]}, - "application/vnd.microsoft.portable-executable": {"source":"iana"}, - "application/vnd.microsoft.windows.thumbnail-cache": {"source":"iana"}, - "application/vnd.miele+json": {"source":"iana","compressible":true}, - "application/vnd.mif": {"source":"iana","extensions":["mif"]}, - "application/vnd.minisoft-hp3000-save": {"source":"iana"}, - "application/vnd.mitsubishi.misty-guard.trustweb": {"source":"iana"}, - "application/vnd.mobius.daf": {"source":"iana","extensions":["daf"]}, - "application/vnd.mobius.dis": {"source":"iana","extensions":["dis"]}, - "application/vnd.mobius.mbk": {"source":"iana","extensions":["mbk"]}, - "application/vnd.mobius.mqy": {"source":"iana","extensions":["mqy"]}, - "application/vnd.mobius.msl": {"source":"iana","extensions":["msl"]}, - "application/vnd.mobius.plc": {"source":"iana","extensions":["plc"]}, - "application/vnd.mobius.txf": {"source":"iana","extensions":["txf"]}, - "application/vnd.modl": {"source":"iana"}, - "application/vnd.mophun.application": {"source":"iana","extensions":["mpn"]}, - "application/vnd.mophun.certificate": {"source":"iana","extensions":["mpc"]}, - "application/vnd.motorola.flexsuite": {"source":"iana"}, - "application/vnd.motorola.flexsuite.adsi": {"source":"iana"}, - "application/vnd.motorola.flexsuite.fis": {"source":"iana"}, - "application/vnd.motorola.flexsuite.gotap": {"source":"iana"}, - "application/vnd.motorola.flexsuite.kmr": {"source":"iana"}, - "application/vnd.motorola.flexsuite.ttc": {"source":"iana"}, - "application/vnd.motorola.flexsuite.wem": {"source":"iana"}, - "application/vnd.motorola.iprm": {"source":"iana"}, - "application/vnd.mozilla.xul+xml": {"source":"iana","compressible":true,"extensions":["xul"]}, - "application/vnd.ms-3mfdocument": {"source":"iana"}, - "application/vnd.ms-artgalry": {"source":"iana","extensions":["cil"]}, - "application/vnd.ms-asf": {"source":"iana"}, - "application/vnd.ms-cab-compressed": {"source":"iana","extensions":["cab"]}, - "application/vnd.ms-color.iccprofile": {"source":"apache"}, - "application/vnd.ms-excel": {"source":"iana","compressible":false,"extensions":["xls","xlm","xla","xlc","xlt","xlw"]}, - "application/vnd.ms-excel.addin.macroenabled.12": {"source":"iana","extensions":["xlam"]}, - "application/vnd.ms-excel.sheet.binary.macroenabled.12": {"source":"iana","extensions":["xlsb"]}, - "application/vnd.ms-excel.sheet.macroenabled.12": {"source":"iana","extensions":["xlsm"]}, - "application/vnd.ms-excel.template.macroenabled.12": {"source":"iana","extensions":["xltm"]}, - "application/vnd.ms-fontobject": {"source":"iana","compressible":true,"extensions":["eot"]}, - "application/vnd.ms-htmlhelp": {"source":"iana","extensions":["chm"]}, - "application/vnd.ms-ims": {"source":"iana","extensions":["ims"]}, - "application/vnd.ms-lrm": {"source":"iana","extensions":["lrm"]}, - "application/vnd.ms-office.activex+xml": {"source":"iana","compressible":true}, - "application/vnd.ms-officetheme": {"source":"iana","extensions":["thmx"]}, - "application/vnd.ms-opentype": {"source":"apache","compressible":true}, - "application/vnd.ms-outlook": {"compressible":false,"extensions":["msg"]}, - "application/vnd.ms-package.obfuscated-opentype": {"source":"apache"}, - "application/vnd.ms-pki.seccat": {"source":"apache","extensions":["cat"]}, - "application/vnd.ms-pki.stl": {"source":"apache","extensions":["stl"]}, - "application/vnd.ms-playready.initiator+xml": {"source":"iana","compressible":true}, - "application/vnd.ms-powerpoint": {"source":"iana","compressible":false,"extensions":["ppt","pps","pot"]}, - "application/vnd.ms-powerpoint.addin.macroenabled.12": {"source":"iana","extensions":["ppam"]}, - "application/vnd.ms-powerpoint.presentation.macroenabled.12": {"source":"iana","extensions":["pptm"]}, - "application/vnd.ms-powerpoint.slide.macroenabled.12": {"source":"iana","extensions":["sldm"]}, - "application/vnd.ms-powerpoint.slideshow.macroenabled.12": {"source":"iana","extensions":["ppsm"]}, - "application/vnd.ms-powerpoint.template.macroenabled.12": {"source":"iana","extensions":["potm"]}, - "application/vnd.ms-printdevicecapabilities+xml": {"source":"iana","compressible":true}, - "application/vnd.ms-printing.printticket+xml": {"source":"apache","compressible":true}, - "application/vnd.ms-printschematicket+xml": {"source":"iana","compressible":true}, - "application/vnd.ms-project": {"source":"iana","extensions":["mpp","mpt"]}, - "application/vnd.ms-tnef": {"source":"iana"}, - "application/vnd.ms-visio.viewer": {"extensions":["vdx"]}, - "application/vnd.ms-windows.devicepairing": {"source":"iana"}, - "application/vnd.ms-windows.nwprinting.oob": {"source":"iana"}, - "application/vnd.ms-windows.printerpairing": {"source":"iana"}, - "application/vnd.ms-windows.wsd.oob": {"source":"iana"}, - "application/vnd.ms-wmdrm.lic-chlg-req": {"source":"iana"}, - "application/vnd.ms-wmdrm.lic-resp": {"source":"iana"}, - "application/vnd.ms-wmdrm.meter-chlg-req": {"source":"iana"}, - "application/vnd.ms-wmdrm.meter-resp": {"source":"iana"}, - "application/vnd.ms-word.document.macroenabled.12": {"source":"iana","extensions":["docm"]}, - "application/vnd.ms-word.template.macroenabled.12": {"source":"iana","extensions":["dotm"]}, - "application/vnd.ms-works": {"source":"iana","extensions":["wps","wks","wcm","wdb"]}, - "application/vnd.ms-wpl": {"source":"iana","extensions":["wpl"]}, - "application/vnd.ms-xpsdocument": {"source":"iana","compressible":false,"extensions":["xps"]}, - "application/vnd.msa-disk-image": {"source":"iana"}, - "application/vnd.mseq": {"source":"iana","extensions":["mseq"]}, - "application/vnd.msgpack": {"source":"iana"}, - "application/vnd.msign": {"source":"iana"}, - "application/vnd.multiad.creator": {"source":"iana"}, - "application/vnd.multiad.creator.cif": {"source":"iana"}, - "application/vnd.music-niff": {"source":"iana"}, - "application/vnd.musician": {"source":"iana","extensions":["mus"]}, - "application/vnd.muvee.style": {"source":"iana","extensions":["msty"]}, - "application/vnd.mynfc": {"source":"iana","extensions":["taglet"]}, - "application/vnd.nacamar.ybrid+json": {"source":"iana","compressible":true}, - "application/vnd.nato.bindingdataobject+cbor": {"source":"iana"}, - "application/vnd.nato.bindingdataobject+json": {"source":"iana","compressible":true}, - "application/vnd.nato.bindingdataobject+xml": {"source":"iana","compressible":true,"extensions":["bdo"]}, - "application/vnd.nato.openxmlformats-package.iepd+zip": {"source":"iana","compressible":false}, - "application/vnd.ncd.control": {"source":"iana"}, - "application/vnd.ncd.reference": {"source":"iana"}, - "application/vnd.nearst.inv+json": {"source":"iana","compressible":true}, - "application/vnd.nebumind.line": {"source":"iana"}, - "application/vnd.nervana": {"source":"iana"}, - "application/vnd.netfpx": {"source":"iana"}, - "application/vnd.neurolanguage.nlu": {"source":"iana","extensions":["nlu"]}, - "application/vnd.nimn": {"source":"iana"}, - "application/vnd.nintendo.nitro.rom": {"source":"iana"}, - "application/vnd.nintendo.snes.rom": {"source":"iana"}, - "application/vnd.nitf": {"source":"iana","extensions":["ntf","nitf"]}, - "application/vnd.noblenet-directory": {"source":"iana","extensions":["nnd"]}, - "application/vnd.noblenet-sealer": {"source":"iana","extensions":["nns"]}, - "application/vnd.noblenet-web": {"source":"iana","extensions":["nnw"]}, - "application/vnd.nokia.catalogs": {"source":"iana"}, - "application/vnd.nokia.conml+wbxml": {"source":"iana"}, - "application/vnd.nokia.conml+xml": {"source":"iana","compressible":true}, - "application/vnd.nokia.iptv.config+xml": {"source":"iana","compressible":true}, - "application/vnd.nokia.isds-radio-presets": {"source":"iana"}, - "application/vnd.nokia.landmark+wbxml": {"source":"iana"}, - "application/vnd.nokia.landmark+xml": {"source":"iana","compressible":true}, - "application/vnd.nokia.landmarkcollection+xml": {"source":"iana","compressible":true}, - "application/vnd.nokia.n-gage.ac+xml": {"source":"iana","compressible":true,"extensions":["ac"]}, - "application/vnd.nokia.n-gage.data": {"source":"iana","extensions":["ngdat"]}, - "application/vnd.nokia.n-gage.symbian.install": {"source":"apache","extensions":["n-gage"]}, - "application/vnd.nokia.ncd": {"source":"iana"}, - "application/vnd.nokia.pcd+wbxml": {"source":"iana"}, - "application/vnd.nokia.pcd+xml": {"source":"iana","compressible":true}, - "application/vnd.nokia.radio-preset": {"source":"iana","extensions":["rpst"]}, - "application/vnd.nokia.radio-presets": {"source":"iana","extensions":["rpss"]}, - "application/vnd.novadigm.edm": {"source":"iana","extensions":["edm"]}, - "application/vnd.novadigm.edx": {"source":"iana","extensions":["edx"]}, - "application/vnd.novadigm.ext": {"source":"iana","extensions":["ext"]}, - "application/vnd.ntt-local.content-share": {"source":"iana"}, - "application/vnd.ntt-local.file-transfer": {"source":"iana"}, - "application/vnd.ntt-local.ogw_remote-access": {"source":"iana"}, - "application/vnd.ntt-local.sip-ta_remote": {"source":"iana"}, - "application/vnd.ntt-local.sip-ta_tcp_stream": {"source":"iana"}, - "application/vnd.oai.workflows": {"source":"iana"}, - "application/vnd.oai.workflows+json": {"source":"iana","compressible":true}, - "application/vnd.oai.workflows+yaml": {"source":"iana"}, - "application/vnd.oasis.opendocument.base": {"source":"iana"}, - "application/vnd.oasis.opendocument.chart": {"source":"iana","extensions":["odc"]}, - "application/vnd.oasis.opendocument.chart-template": {"source":"iana","extensions":["otc"]}, - "application/vnd.oasis.opendocument.database": {"source":"apache","extensions":["odb"]}, - "application/vnd.oasis.opendocument.formula": {"source":"iana","extensions":["odf"]}, - "application/vnd.oasis.opendocument.formula-template": {"source":"iana","extensions":["odft"]}, - "application/vnd.oasis.opendocument.graphics": {"source":"iana","compressible":false,"extensions":["odg"]}, - "application/vnd.oasis.opendocument.graphics-template": {"source":"iana","extensions":["otg"]}, - "application/vnd.oasis.opendocument.image": {"source":"iana","extensions":["odi"]}, - "application/vnd.oasis.opendocument.image-template": {"source":"iana","extensions":["oti"]}, - "application/vnd.oasis.opendocument.presentation": {"source":"iana","compressible":false,"extensions":["odp"]}, - "application/vnd.oasis.opendocument.presentation-template": {"source":"iana","extensions":["otp"]}, - "application/vnd.oasis.opendocument.spreadsheet": {"source":"iana","compressible":false,"extensions":["ods"]}, - "application/vnd.oasis.opendocument.spreadsheet-template": {"source":"iana","extensions":["ots"]}, - "application/vnd.oasis.opendocument.text": {"source":"iana","compressible":false,"extensions":["odt"]}, - "application/vnd.oasis.opendocument.text-master": {"source":"iana","extensions":["odm"]}, - "application/vnd.oasis.opendocument.text-master-template": {"source":"iana"}, - "application/vnd.oasis.opendocument.text-template": {"source":"iana","extensions":["ott"]}, - "application/vnd.oasis.opendocument.text-web": {"source":"iana","extensions":["oth"]}, - "application/vnd.obn": {"source":"iana"}, - "application/vnd.ocf+cbor": {"source":"iana"}, - "application/vnd.oci.image.manifest.v1+json": {"source":"iana","compressible":true}, - "application/vnd.oftn.l10n+json": {"source":"iana","compressible":true}, - "application/vnd.oipf.contentaccessdownload+xml": {"source":"iana","compressible":true}, - "application/vnd.oipf.contentaccessstreaming+xml": {"source":"iana","compressible":true}, - "application/vnd.oipf.cspg-hexbinary": {"source":"iana"}, - "application/vnd.oipf.dae.svg+xml": {"source":"iana","compressible":true}, - "application/vnd.oipf.dae.xhtml+xml": {"source":"iana","compressible":true}, - "application/vnd.oipf.mippvcontrolmessage+xml": {"source":"iana","compressible":true}, - "application/vnd.oipf.pae.gem": {"source":"iana"}, - "application/vnd.oipf.spdiscovery+xml": {"source":"iana","compressible":true}, - "application/vnd.oipf.spdlist+xml": {"source":"iana","compressible":true}, - "application/vnd.oipf.ueprofile+xml": {"source":"iana","compressible":true}, - "application/vnd.oipf.userprofile+xml": {"source":"iana","compressible":true}, - "application/vnd.olpc-sugar": {"source":"iana","extensions":["xo"]}, - "application/vnd.oma-scws-config": {"source":"iana"}, - "application/vnd.oma-scws-http-request": {"source":"iana"}, - "application/vnd.oma-scws-http-response": {"source":"iana"}, - "application/vnd.oma.bcast.associated-procedure-parameter+xml": {"source":"iana","compressible":true}, - "application/vnd.oma.bcast.drm-trigger+xml": {"source":"apache","compressible":true}, - "application/vnd.oma.bcast.imd+xml": {"source":"iana","compressible":true}, - "application/vnd.oma.bcast.ltkm": {"source":"iana"}, - "application/vnd.oma.bcast.notification+xml": {"source":"iana","compressible":true}, - "application/vnd.oma.bcast.provisioningtrigger": {"source":"iana"}, - "application/vnd.oma.bcast.sgboot": {"source":"iana"}, - "application/vnd.oma.bcast.sgdd+xml": {"source":"iana","compressible":true}, - "application/vnd.oma.bcast.sgdu": {"source":"iana"}, - "application/vnd.oma.bcast.simple-symbol-container": {"source":"iana"}, - "application/vnd.oma.bcast.smartcard-trigger+xml": {"source":"apache","compressible":true}, - "application/vnd.oma.bcast.sprov+xml": {"source":"iana","compressible":true}, - "application/vnd.oma.bcast.stkm": {"source":"iana"}, - "application/vnd.oma.cab-address-book+xml": {"source":"iana","compressible":true}, - "application/vnd.oma.cab-feature-handler+xml": {"source":"iana","compressible":true}, - "application/vnd.oma.cab-pcc+xml": {"source":"iana","compressible":true}, - "application/vnd.oma.cab-subs-invite+xml": {"source":"iana","compressible":true}, - "application/vnd.oma.cab-user-prefs+xml": {"source":"iana","compressible":true}, - "application/vnd.oma.dcd": {"source":"iana"}, - "application/vnd.oma.dcdc": {"source":"iana"}, - "application/vnd.oma.dd2+xml": {"source":"iana","compressible":true,"extensions":["dd2"]}, - "application/vnd.oma.drm.risd+xml": {"source":"iana","compressible":true}, - "application/vnd.oma.group-usage-list+xml": {"source":"iana","compressible":true}, - "application/vnd.oma.lwm2m+cbor": {"source":"iana"}, - "application/vnd.oma.lwm2m+json": {"source":"iana","compressible":true}, - "application/vnd.oma.lwm2m+tlv": {"source":"iana"}, - "application/vnd.oma.pal+xml": {"source":"iana","compressible":true}, - "application/vnd.oma.poc.detailed-progress-report+xml": {"source":"iana","compressible":true}, - "application/vnd.oma.poc.final-report+xml": {"source":"iana","compressible":true}, - "application/vnd.oma.poc.groups+xml": {"source":"iana","compressible":true}, - "application/vnd.oma.poc.invocation-descriptor+xml": {"source":"iana","compressible":true}, - "application/vnd.oma.poc.optimized-progress-report+xml": {"source":"iana","compressible":true}, - "application/vnd.oma.push": {"source":"iana"}, - "application/vnd.oma.scidm.messages+xml": {"source":"iana","compressible":true}, - "application/vnd.oma.xcap-directory+xml": {"source":"iana","compressible":true}, - "application/vnd.omads-email+xml": {"source":"iana","charset":"UTF-8","compressible":true}, - "application/vnd.omads-file+xml": {"source":"iana","charset":"UTF-8","compressible":true}, - "application/vnd.omads-folder+xml": {"source":"iana","charset":"UTF-8","compressible":true}, - "application/vnd.omaloc-supl-init": {"source":"iana"}, - "application/vnd.onepager": {"source":"iana"}, - "application/vnd.onepagertamp": {"source":"iana"}, - "application/vnd.onepagertamx": {"source":"iana"}, - "application/vnd.onepagertat": {"source":"iana"}, - "application/vnd.onepagertatp": {"source":"iana"}, - "application/vnd.onepagertatx": {"source":"iana"}, - "application/vnd.onvif.metadata": {"source":"iana"}, - "application/vnd.openblox.game+xml": {"source":"iana","compressible":true,"extensions":["obgx"]}, - "application/vnd.openblox.game-binary": {"source":"iana"}, - "application/vnd.openeye.oeb": {"source":"iana"}, - "application/vnd.openofficeorg.extension": {"source":"apache","extensions":["oxt"]}, - "application/vnd.openstreetmap.data+xml": {"source":"iana","compressible":true,"extensions":["osm"]}, - "application/vnd.opentimestamps.ots": {"source":"iana"}, - "application/vnd.openvpi.dspx+json": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.custom-properties+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.customxmlproperties+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.drawing+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.drawingml.chart+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.extended-properties+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.presentationml.comments+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.presentationml.presentation": {"source":"iana","compressible":false,"extensions":["pptx"]}, - "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.presentationml.presprops+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.presentationml.slide": {"source":"iana","extensions":["sldx"]}, - "application/vnd.openxmlformats-officedocument.presentationml.slide+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.presentationml.slideshow": {"source":"iana","extensions":["ppsx"]}, - "application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.presentationml.tags+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.presentationml.template": {"source":"iana","extensions":["potx"]}, - "application/vnd.openxmlformats-officedocument.presentationml.template.main+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": {"source":"iana","compressible":false,"extensions":["xlsx"]}, - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.spreadsheetml.template": {"source":"iana","extensions":["xltx"]}, - "application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.theme+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.themeoverride+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.vmldrawing": {"source":"iana"}, - "application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.wordprocessingml.document": {"source":"iana","compressible":false,"extensions":["docx"]}, - "application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.wordprocessingml.template": {"source":"iana","extensions":["dotx"]}, - "application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-package.core-properties+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml": {"source":"iana","compressible":true}, - "application/vnd.openxmlformats-package.relationships+xml": {"source":"iana","compressible":true}, - "application/vnd.oracle.resource+json": {"source":"iana","compressible":true}, - "application/vnd.orange.indata": {"source":"iana"}, - "application/vnd.osa.netdeploy": {"source":"iana"}, - "application/vnd.osgeo.mapguide.package": {"source":"iana","extensions":["mgp"]}, - "application/vnd.osgi.bundle": {"source":"iana"}, - "application/vnd.osgi.dp": {"source":"iana","extensions":["dp"]}, - "application/vnd.osgi.subsystem": {"source":"iana","extensions":["esa"]}, - "application/vnd.otps.ct-kip+xml": {"source":"iana","compressible":true}, - "application/vnd.oxli.countgraph": {"source":"iana"}, - "application/vnd.pagerduty+json": {"source":"iana","compressible":true}, - "application/vnd.palm": {"source":"iana","extensions":["pdb","pqa","oprc"]}, - "application/vnd.panoply": {"source":"iana"}, - "application/vnd.paos.xml": {"source":"iana"}, - "application/vnd.patentdive": {"source":"iana"}, - "application/vnd.patientecommsdoc": {"source":"iana"}, - "application/vnd.pawaafile": {"source":"iana","extensions":["paw"]}, - "application/vnd.pcos": {"source":"iana"}, - "application/vnd.pg.format": {"source":"iana","extensions":["str"]}, - "application/vnd.pg.osasli": {"source":"iana","extensions":["ei6"]}, - "application/vnd.piaccess.application-licence": {"source":"iana"}, - "application/vnd.picsel": {"source":"iana","extensions":["efif"]}, - "application/vnd.pmi.widget": {"source":"iana","extensions":["wg"]}, - "application/vnd.poc.group-advertisement+xml": {"source":"iana","compressible":true}, - "application/vnd.pocketlearn": {"source":"iana","extensions":["plf"]}, - "application/vnd.powerbuilder6": {"source":"iana","extensions":["pbd"]}, - "application/vnd.powerbuilder6-s": {"source":"iana"}, - "application/vnd.powerbuilder7": {"source":"iana"}, - "application/vnd.powerbuilder7-s": {"source":"iana"}, - "application/vnd.powerbuilder75": {"source":"iana"}, - "application/vnd.powerbuilder75-s": {"source":"iana"}, - "application/vnd.preminet": {"source":"iana"}, - "application/vnd.previewsystems.box": {"source":"iana","extensions":["box"]}, - "application/vnd.procrate.brushset": {"extensions":["brushset"]}, - "application/vnd.procreate.brush": {"extensions":["brush"]}, - "application/vnd.procreate.dream": {"extensions":["drm"]}, - "application/vnd.proteus.magazine": {"source":"iana","extensions":["mgz"]}, - "application/vnd.psfs": {"source":"iana"}, - "application/vnd.pt.mundusmundi": {"source":"iana"}, - "application/vnd.publishare-delta-tree": {"source":"iana","extensions":["qps"]}, - "application/vnd.pvi.ptid1": {"source":"iana","extensions":["ptid"]}, - "application/vnd.pwg-multiplexed": {"source":"iana"}, - "application/vnd.pwg-xhtml-print+xml": {"source":"iana","compressible":true,"extensions":["xhtm"]}, - "application/vnd.qualcomm.brew-app-res": {"source":"iana"}, - "application/vnd.quarantainenet": {"source":"iana"}, - "application/vnd.quark.quarkxpress": {"source":"iana","extensions":["qxd","qxt","qwd","qwt","qxl","qxb"]}, - "application/vnd.quobject-quoxdocument": {"source":"iana"}, - "application/vnd.radisys.moml+xml": {"source":"iana","compressible":true}, - "application/vnd.radisys.msml+xml": {"source":"iana","compressible":true}, - "application/vnd.radisys.msml-audit+xml": {"source":"iana","compressible":true}, - "application/vnd.radisys.msml-audit-conf+xml": {"source":"iana","compressible":true}, - "application/vnd.radisys.msml-audit-conn+xml": {"source":"iana","compressible":true}, - "application/vnd.radisys.msml-audit-dialog+xml": {"source":"iana","compressible":true}, - "application/vnd.radisys.msml-audit-stream+xml": {"source":"iana","compressible":true}, - "application/vnd.radisys.msml-conf+xml": {"source":"iana","compressible":true}, - "application/vnd.radisys.msml-dialog+xml": {"source":"iana","compressible":true}, - "application/vnd.radisys.msml-dialog-base+xml": {"source":"iana","compressible":true}, - "application/vnd.radisys.msml-dialog-fax-detect+xml": {"source":"iana","compressible":true}, - "application/vnd.radisys.msml-dialog-fax-sendrecv+xml": {"source":"iana","compressible":true}, - "application/vnd.radisys.msml-dialog-group+xml": {"source":"iana","compressible":true}, - "application/vnd.radisys.msml-dialog-speech+xml": {"source":"iana","compressible":true}, - "application/vnd.radisys.msml-dialog-transform+xml": {"source":"iana","compressible":true}, - "application/vnd.rainstor.data": {"source":"iana"}, - "application/vnd.rapid": {"source":"iana"}, - "application/vnd.rar": {"source":"iana","extensions":["rar"]}, - "application/vnd.realvnc.bed": {"source":"iana","extensions":["bed"]}, - "application/vnd.recordare.musicxml": {"source":"iana","extensions":["mxl"]}, - "application/vnd.recordare.musicxml+xml": {"source":"iana","compressible":true,"extensions":["musicxml"]}, - "application/vnd.relpipe": {"source":"iana"}, - "application/vnd.renlearn.rlprint": {"source":"iana"}, - "application/vnd.resilient.logic": {"source":"iana"}, - "application/vnd.restful+json": {"source":"iana","compressible":true}, - "application/vnd.rig.cryptonote": {"source":"iana","extensions":["cryptonote"]}, - "application/vnd.rim.cod": {"source":"apache","extensions":["cod"]}, - "application/vnd.rn-realmedia": {"source":"apache","extensions":["rm"]}, - "application/vnd.rn-realmedia-vbr": {"source":"apache","extensions":["rmvb"]}, - "application/vnd.route66.link66+xml": {"source":"iana","compressible":true,"extensions":["link66"]}, - "application/vnd.rs-274x": {"source":"iana"}, - "application/vnd.ruckus.download": {"source":"iana"}, - "application/vnd.s3sms": {"source":"iana"}, - "application/vnd.sailingtracker.track": {"source":"iana","extensions":["st"]}, - "application/vnd.sar": {"source":"iana"}, - "application/vnd.sbm.cid": {"source":"iana"}, - "application/vnd.sbm.mid2": {"source":"iana"}, - "application/vnd.scribus": {"source":"iana"}, - "application/vnd.sealed.3df": {"source":"iana"}, - "application/vnd.sealed.csf": {"source":"iana"}, - "application/vnd.sealed.doc": {"source":"iana"}, - "application/vnd.sealed.eml": {"source":"iana"}, - "application/vnd.sealed.mht": {"source":"iana"}, - "application/vnd.sealed.net": {"source":"iana"}, - "application/vnd.sealed.ppt": {"source":"iana"}, - "application/vnd.sealed.tiff": {"source":"iana"}, - "application/vnd.sealed.xls": {"source":"iana"}, - "application/vnd.sealedmedia.softseal.html": {"source":"iana"}, - "application/vnd.sealedmedia.softseal.pdf": {"source":"iana"}, - "application/vnd.seemail": {"source":"iana","extensions":["see"]}, - "application/vnd.seis+json": {"source":"iana","compressible":true}, - "application/vnd.sema": {"source":"iana","extensions":["sema"]}, - "application/vnd.semd": {"source":"iana","extensions":["semd"]}, - "application/vnd.semf": {"source":"iana","extensions":["semf"]}, - "application/vnd.shade-save-file": {"source":"iana"}, - "application/vnd.shana.informed.formdata": {"source":"iana","extensions":["ifm"]}, - "application/vnd.shana.informed.formtemplate": {"source":"iana","extensions":["itp"]}, - "application/vnd.shana.informed.interchange": {"source":"iana","extensions":["iif"]}, - "application/vnd.shana.informed.package": {"source":"iana","extensions":["ipk"]}, - "application/vnd.shootproof+json": {"source":"iana","compressible":true}, - "application/vnd.shopkick+json": {"source":"iana","compressible":true}, - "application/vnd.shp": {"source":"iana"}, - "application/vnd.shx": {"source":"iana"}, - "application/vnd.sigrok.session": {"source":"iana"}, - "application/vnd.simtech-mindmapper": {"source":"iana","extensions":["twd","twds"]}, - "application/vnd.siren+json": {"source":"iana","compressible":true}, - "application/vnd.sketchometry": {"source":"iana"}, - "application/vnd.smaf": {"source":"iana","extensions":["mmf"]}, - "application/vnd.smart.notebook": {"source":"iana"}, - "application/vnd.smart.teacher": {"source":"iana","extensions":["teacher"]}, - "application/vnd.smintio.portals.archive": {"source":"iana"}, - "application/vnd.snesdev-page-table": {"source":"iana"}, - "application/vnd.software602.filler.form+xml": {"source":"iana","compressible":true,"extensions":["fo"]}, - "application/vnd.software602.filler.form-xml-zip": {"source":"iana"}, - "application/vnd.solent.sdkm+xml": {"source":"iana","compressible":true,"extensions":["sdkm","sdkd"]}, - "application/vnd.spotfire.dxp": {"source":"iana","extensions":["dxp"]}, - "application/vnd.spotfire.sfs": {"source":"iana","extensions":["sfs"]}, - "application/vnd.sqlite3": {"source":"iana"}, - "application/vnd.sss-cod": {"source":"iana"}, - "application/vnd.sss-dtf": {"source":"iana"}, - "application/vnd.sss-ntf": {"source":"iana"}, - "application/vnd.stardivision.calc": {"source":"apache","extensions":["sdc"]}, - "application/vnd.stardivision.draw": {"source":"apache","extensions":["sda"]}, - "application/vnd.stardivision.impress": {"source":"apache","extensions":["sdd"]}, - "application/vnd.stardivision.math": {"source":"apache","extensions":["smf"]}, - "application/vnd.stardivision.writer": {"source":"apache","extensions":["sdw","vor"]}, - "application/vnd.stardivision.writer-global": {"source":"apache","extensions":["sgl"]}, - "application/vnd.stepmania.package": {"source":"iana","extensions":["smzip"]}, - "application/vnd.stepmania.stepchart": {"source":"iana","extensions":["sm"]}, - "application/vnd.street-stream": {"source":"iana"}, - "application/vnd.sun.wadl+xml": {"source":"iana","compressible":true,"extensions":["wadl"]}, - "application/vnd.sun.xml.calc": {"source":"apache","extensions":["sxc"]}, - "application/vnd.sun.xml.calc.template": {"source":"apache","extensions":["stc"]}, - "application/vnd.sun.xml.draw": {"source":"apache","extensions":["sxd"]}, - "application/vnd.sun.xml.draw.template": {"source":"apache","extensions":["std"]}, - "application/vnd.sun.xml.impress": {"source":"apache","extensions":["sxi"]}, - "application/vnd.sun.xml.impress.template": {"source":"apache","extensions":["sti"]}, - "application/vnd.sun.xml.math": {"source":"apache","extensions":["sxm"]}, - "application/vnd.sun.xml.writer": {"source":"apache","extensions":["sxw"]}, - "application/vnd.sun.xml.writer.global": {"source":"apache","extensions":["sxg"]}, - "application/vnd.sun.xml.writer.template": {"source":"apache","extensions":["stw"]}, - "application/vnd.sus-calendar": {"source":"iana","extensions":["sus","susp"]}, - "application/vnd.svd": {"source":"iana","extensions":["svd"]}, - "application/vnd.swiftview-ics": {"source":"iana"}, - "application/vnd.sybyl.mol2": {"source":"iana"}, - "application/vnd.sycle+xml": {"source":"iana","compressible":true}, - "application/vnd.syft+json": {"source":"iana","compressible":true}, - "application/vnd.symbian.install": {"source":"apache","extensions":["sis","sisx"]}, - "application/vnd.syncml+xml": {"source":"iana","charset":"UTF-8","compressible":true,"extensions":["xsm"]}, - "application/vnd.syncml.dm+wbxml": {"source":"iana","charset":"UTF-8","extensions":["bdm"]}, - "application/vnd.syncml.dm+xml": {"source":"iana","charset":"UTF-8","compressible":true,"extensions":["xdm"]}, - "application/vnd.syncml.dm.notification": {"source":"iana"}, - "application/vnd.syncml.dmddf+wbxml": {"source":"iana"}, - "application/vnd.syncml.dmddf+xml": {"source":"iana","charset":"UTF-8","compressible":true,"extensions":["ddf"]}, - "application/vnd.syncml.dmtnds+wbxml": {"source":"iana"}, - "application/vnd.syncml.dmtnds+xml": {"source":"iana","charset":"UTF-8","compressible":true}, - "application/vnd.syncml.ds.notification": {"source":"iana"}, - "application/vnd.tableschema+json": {"source":"iana","compressible":true}, - "application/vnd.tao.intent-module-archive": {"source":"iana","extensions":["tao"]}, - "application/vnd.tcpdump.pcap": {"source":"iana","extensions":["pcap","cap","dmp"]}, - "application/vnd.think-cell.ppttc+json": {"source":"iana","compressible":true}, - "application/vnd.tmd.mediaflex.api+xml": {"source":"iana","compressible":true}, - "application/vnd.tml": {"source":"iana"}, - "application/vnd.tmobile-livetv": {"source":"iana","extensions":["tmo"]}, - "application/vnd.tri.onesource": {"source":"iana"}, - "application/vnd.trid.tpt": {"source":"iana","extensions":["tpt"]}, - "application/vnd.triscape.mxs": {"source":"iana","extensions":["mxs"]}, - "application/vnd.trueapp": {"source":"iana","extensions":["tra"]}, - "application/vnd.truedoc": {"source":"iana"}, - "application/vnd.ubisoft.webplayer": {"source":"iana"}, - "application/vnd.ufdl": {"source":"iana","extensions":["ufd","ufdl"]}, - "application/vnd.uic.osdm+json": {"source":"iana","compressible":true}, - "application/vnd.uiq.theme": {"source":"iana","extensions":["utz"]}, - "application/vnd.umajin": {"source":"iana","extensions":["umj"]}, - "application/vnd.unity": {"source":"iana","extensions":["unityweb"]}, - "application/vnd.uoml+xml": {"source":"iana","compressible":true,"extensions":["uoml","uo"]}, - "application/vnd.uplanet.alert": {"source":"iana"}, - "application/vnd.uplanet.alert-wbxml": {"source":"iana"}, - "application/vnd.uplanet.bearer-choice": {"source":"iana"}, - "application/vnd.uplanet.bearer-choice-wbxml": {"source":"iana"}, - "application/vnd.uplanet.cacheop": {"source":"iana"}, - "application/vnd.uplanet.cacheop-wbxml": {"source":"iana"}, - "application/vnd.uplanet.channel": {"source":"iana"}, - "application/vnd.uplanet.channel-wbxml": {"source":"iana"}, - "application/vnd.uplanet.list": {"source":"iana"}, - "application/vnd.uplanet.list-wbxml": {"source":"iana"}, - "application/vnd.uplanet.listcmd": {"source":"iana"}, - "application/vnd.uplanet.listcmd-wbxml": {"source":"iana"}, - "application/vnd.uplanet.signal": {"source":"iana"}, - "application/vnd.uri-map": {"source":"iana"}, - "application/vnd.valve.source.material": {"source":"iana"}, - "application/vnd.vcx": {"source":"iana","extensions":["vcx"]}, - "application/vnd.vd-study": {"source":"iana"}, - "application/vnd.vectorworks": {"source":"iana"}, - "application/vnd.vel+json": {"source":"iana","compressible":true}, - "application/vnd.veraison.tsm-report+cbor": {"source":"iana"}, - "application/vnd.veraison.tsm-report+json": {"source":"iana","compressible":true}, - "application/vnd.verimatrix.vcas": {"source":"iana"}, - "application/vnd.veritone.aion+json": {"source":"iana","compressible":true}, - "application/vnd.veryant.thin": {"source":"iana"}, - "application/vnd.ves.encrypted": {"source":"iana"}, - "application/vnd.vidsoft.vidconference": {"source":"iana"}, - "application/vnd.visio": {"source":"iana","extensions":["vsd","vst","vss","vsw","vsdx","vtx"]}, - "application/vnd.visionary": {"source":"iana","extensions":["vis"]}, - "application/vnd.vividence.scriptfile": {"source":"iana"}, - "application/vnd.vocalshaper.vsp4": {"source":"iana"}, - "application/vnd.vsf": {"source":"iana","extensions":["vsf"]}, - "application/vnd.wap.sic": {"source":"iana"}, - "application/vnd.wap.slc": {"source":"iana"}, - "application/vnd.wap.wbxml": {"source":"iana","charset":"UTF-8","extensions":["wbxml"]}, - "application/vnd.wap.wmlc": {"source":"iana","extensions":["wmlc"]}, - "application/vnd.wap.wmlscriptc": {"source":"iana","extensions":["wmlsc"]}, - "application/vnd.wasmflow.wafl": {"source":"iana"}, - "application/vnd.webturbo": {"source":"iana","extensions":["wtb"]}, - "application/vnd.wfa.dpp": {"source":"iana"}, - "application/vnd.wfa.p2p": {"source":"iana"}, - "application/vnd.wfa.wsc": {"source":"iana"}, - "application/vnd.windows.devicepairing": {"source":"iana"}, - "application/vnd.wmc": {"source":"iana"}, - "application/vnd.wmf.bootstrap": {"source":"iana"}, - "application/vnd.wolfram.mathematica": {"source":"iana"}, - "application/vnd.wolfram.mathematica.package": {"source":"iana"}, - "application/vnd.wolfram.player": {"source":"iana","extensions":["nbp"]}, - "application/vnd.wordlift": {"source":"iana"}, - "application/vnd.wordperfect": {"source":"iana","extensions":["wpd"]}, - "application/vnd.wqd": {"source":"iana","extensions":["wqd"]}, - "application/vnd.wrq-hp3000-labelled": {"source":"iana"}, - "application/vnd.wt.stf": {"source":"iana","extensions":["stf"]}, - "application/vnd.wv.csp+wbxml": {"source":"iana"}, - "application/vnd.wv.csp+xml": {"source":"iana","compressible":true}, - "application/vnd.wv.ssp+xml": {"source":"iana","compressible":true}, - "application/vnd.xacml+json": {"source":"iana","compressible":true}, - "application/vnd.xara": {"source":"iana","extensions":["xar"]}, - "application/vnd.xarin.cpj": {"source":"iana"}, - "application/vnd.xecrets-encrypted": {"source":"iana"}, - "application/vnd.xfdl": {"source":"iana","extensions":["xfdl"]}, - "application/vnd.xfdl.webform": {"source":"iana"}, - "application/vnd.xmi+xml": {"source":"iana","compressible":true}, - "application/vnd.xmpie.cpkg": {"source":"iana"}, - "application/vnd.xmpie.dpkg": {"source":"iana"}, - "application/vnd.xmpie.plan": {"source":"iana"}, - "application/vnd.xmpie.ppkg": {"source":"iana"}, - "application/vnd.xmpie.xlim": {"source":"iana"}, - "application/vnd.yamaha.hv-dic": {"source":"iana","extensions":["hvd"]}, - "application/vnd.yamaha.hv-script": {"source":"iana","extensions":["hvs"]}, - "application/vnd.yamaha.hv-voice": {"source":"iana","extensions":["hvp"]}, - "application/vnd.yamaha.openscoreformat": {"source":"iana","extensions":["osf"]}, - "application/vnd.yamaha.openscoreformat.osfpvg+xml": {"source":"iana","compressible":true,"extensions":["osfpvg"]}, - "application/vnd.yamaha.remote-setup": {"source":"iana"}, - "application/vnd.yamaha.smaf-audio": {"source":"iana","extensions":["saf"]}, - "application/vnd.yamaha.smaf-phrase": {"source":"iana","extensions":["spf"]}, - "application/vnd.yamaha.through-ngn": {"source":"iana"}, - "application/vnd.yamaha.tunnel-udpencap": {"source":"iana"}, - "application/vnd.yaoweme": {"source":"iana"}, - "application/vnd.yellowriver-custom-menu": {"source":"iana","extensions":["cmp"]}, - "application/vnd.zul": {"source":"iana","extensions":["zir","zirz"]}, - "application/vnd.zzazz.deck+xml": {"source":"iana","compressible":true,"extensions":["zaz"]}, - "application/voicexml+xml": {"source":"iana","compressible":true,"extensions":["vxml"]}, - "application/voucher-cms+json": {"source":"iana","compressible":true}, - "application/voucher-jws+json": {"source":"iana","compressible":true}, - "application/vp": {"source":"iana"}, - "application/vp+cose": {"source":"iana"}, - "application/vp+jwt": {"source":"iana"}, - "application/vq-rtcpxr": {"source":"iana"}, - "application/wasm": {"source":"iana","compressible":true,"extensions":["wasm"]}, - "application/watcherinfo+xml": {"source":"iana","compressible":true,"extensions":["wif"]}, - "application/webpush-options+json": {"source":"iana","compressible":true}, - "application/whoispp-query": {"source":"iana"}, - "application/whoispp-response": {"source":"iana"}, - "application/widget": {"source":"iana","extensions":["wgt"]}, - "application/winhlp": {"source":"apache","extensions":["hlp"]}, - "application/wita": {"source":"iana"}, - "application/wordperfect5.1": {"source":"iana"}, - "application/wsdl+xml": {"source":"iana","compressible":true,"extensions":["wsdl"]}, - "application/wspolicy+xml": {"source":"iana","compressible":true,"extensions":["wspolicy"]}, - "application/x-7z-compressed": {"source":"apache","compressible":false,"extensions":["7z"]}, - "application/x-abiword": {"source":"apache","extensions":["abw"]}, - "application/x-ace-compressed": {"source":"apache","extensions":["ace"]}, - "application/x-amf": {"source":"apache"}, - "application/x-apple-diskimage": {"source":"apache","extensions":["dmg"]}, - "application/x-arj": {"compressible":false,"extensions":["arj"]}, - "application/x-authorware-bin": {"source":"apache","extensions":["aab","x32","u32","vox"]}, - "application/x-authorware-map": {"source":"apache","extensions":["aam"]}, - "application/x-authorware-seg": {"source":"apache","extensions":["aas"]}, - "application/x-bcpio": {"source":"apache","extensions":["bcpio"]}, - "application/x-bdoc": {"compressible":false,"extensions":["bdoc"]}, - "application/x-bittorrent": {"source":"apache","extensions":["torrent"]}, - "application/x-blender": {"extensions":["blend"]}, - "application/x-blorb": {"source":"apache","extensions":["blb","blorb"]}, - "application/x-bzip": {"source":"apache","compressible":false,"extensions":["bz"]}, - "application/x-bzip2": {"source":"apache","compressible":false,"extensions":["bz2","boz"]}, - "application/x-cbr": {"source":"apache","extensions":["cbr","cba","cbt","cbz","cb7"]}, - "application/x-cdlink": {"source":"apache","extensions":["vcd"]}, - "application/x-cfs-compressed": {"source":"apache","extensions":["cfs"]}, - "application/x-chat": {"source":"apache","extensions":["chat"]}, - "application/x-chess-pgn": {"source":"apache","extensions":["pgn"]}, - "application/x-chrome-extension": {"extensions":["crx"]}, - "application/x-cocoa": {"source":"nginx","extensions":["cco"]}, - "application/x-compress": {"source":"apache"}, - "application/x-compressed": {"extensions":["rar"]}, - "application/x-conference": {"source":"apache","extensions":["nsc"]}, - "application/x-cpio": {"source":"apache","extensions":["cpio"]}, - "application/x-csh": {"source":"apache","extensions":["csh"]}, - "application/x-deb": {"compressible":false}, - "application/x-debian-package": {"source":"apache","extensions":["deb","udeb"]}, - "application/x-dgc-compressed": {"source":"apache","extensions":["dgc"]}, - "application/x-director": {"source":"apache","extensions":["dir","dcr","dxr","cst","cct","cxt","w3d","fgd","swa"]}, - "application/x-doom": {"source":"apache","extensions":["wad"]}, - "application/x-dtbncx+xml": {"source":"apache","compressible":true,"extensions":["ncx"]}, - "application/x-dtbook+xml": {"source":"apache","compressible":true,"extensions":["dtb"]}, - "application/x-dtbresource+xml": {"source":"apache","compressible":true,"extensions":["res"]}, - "application/x-dvi": {"source":"apache","compressible":false,"extensions":["dvi"]}, - "application/x-envoy": {"source":"apache","extensions":["evy"]}, - "application/x-eva": {"source":"apache","extensions":["eva"]}, - "application/x-font-bdf": {"source":"apache","extensions":["bdf"]}, - "application/x-font-dos": {"source":"apache"}, - "application/x-font-framemaker": {"source":"apache"}, - "application/x-font-ghostscript": {"source":"apache","extensions":["gsf"]}, - "application/x-font-libgrx": {"source":"apache"}, - "application/x-font-linux-psf": {"source":"apache","extensions":["psf"]}, - "application/x-font-pcf": {"source":"apache","extensions":["pcf"]}, - "application/x-font-snf": {"source":"apache","extensions":["snf"]}, - "application/x-font-speedo": {"source":"apache"}, - "application/x-font-sunos-news": {"source":"apache"}, - "application/x-font-type1": {"source":"apache","extensions":["pfa","pfb","pfm","afm"]}, - "application/x-font-vfont": {"source":"apache"}, - "application/x-freearc": {"source":"apache","extensions":["arc"]}, - "application/x-futuresplash": {"source":"apache","extensions":["spl"]}, - "application/x-gca-compressed": {"source":"apache","extensions":["gca"]}, - "application/x-glulx": {"source":"apache","extensions":["ulx"]}, - "application/x-gnumeric": {"source":"apache","extensions":["gnumeric"]}, - "application/x-gramps-xml": {"source":"apache","extensions":["gramps"]}, - "application/x-gtar": {"source":"apache","extensions":["gtar"]}, - "application/x-gzip": {"source":"apache"}, - "application/x-hdf": {"source":"apache","extensions":["hdf"]}, - "application/x-httpd-php": {"compressible":true,"extensions":["php"]}, - "application/x-install-instructions": {"source":"apache","extensions":["install"]}, - "application/x-ipynb+json": {"compressible":true,"extensions":["ipynb"]}, - "application/x-iso9660-image": {"source":"apache","extensions":["iso"]}, - "application/x-iwork-keynote-sffkey": {"extensions":["key"]}, - "application/x-iwork-numbers-sffnumbers": {"extensions":["numbers"]}, - "application/x-iwork-pages-sffpages": {"extensions":["pages"]}, - "application/x-java-archive-diff": {"source":"nginx","extensions":["jardiff"]}, - "application/x-java-jnlp-file": {"source":"apache","compressible":false,"extensions":["jnlp"]}, - "application/x-javascript": {"compressible":true}, - "application/x-keepass2": {"extensions":["kdbx"]}, - "application/x-latex": {"source":"apache","compressible":false,"extensions":["latex"]}, - "application/x-lua-bytecode": {"extensions":["luac"]}, - "application/x-lzh-compressed": {"source":"apache","extensions":["lzh","lha"]}, - "application/x-makeself": {"source":"nginx","extensions":["run"]}, - "application/x-mie": {"source":"apache","extensions":["mie"]}, - "application/x-mobipocket-ebook": {"source":"apache","extensions":["prc","mobi"]}, - "application/x-mpegurl": {"compressible":false}, - "application/x-ms-application": {"source":"apache","extensions":["application"]}, - "application/x-ms-shortcut": {"source":"apache","extensions":["lnk"]}, - "application/x-ms-wmd": {"source":"apache","extensions":["wmd"]}, - "application/x-ms-wmz": {"source":"apache","extensions":["wmz"]}, - "application/x-ms-xbap": {"source":"apache","extensions":["xbap"]}, - "application/x-msaccess": {"source":"apache","extensions":["mdb"]}, - "application/x-msbinder": {"source":"apache","extensions":["obd"]}, - "application/x-mscardfile": {"source":"apache","extensions":["crd"]}, - "application/x-msclip": {"source":"apache","extensions":["clp"]}, - "application/x-msdos-program": {"extensions":["exe"]}, - "application/x-msdownload": {"source":"apache","extensions":["exe","dll","com","bat","msi"]}, - "application/x-msmediaview": {"source":"apache","extensions":["mvb","m13","m14"]}, - "application/x-msmetafile": {"source":"apache","extensions":["wmf","wmz","emf","emz"]}, - "application/x-msmoney": {"source":"apache","extensions":["mny"]}, - "application/x-mspublisher": {"source":"apache","extensions":["pub"]}, - "application/x-msschedule": {"source":"apache","extensions":["scd"]}, - "application/x-msterminal": {"source":"apache","extensions":["trm"]}, - "application/x-mswrite": {"source":"apache","extensions":["wri"]}, - "application/x-netcdf": {"source":"apache","extensions":["nc","cdf"]}, - "application/x-ns-proxy-autoconfig": {"compressible":true,"extensions":["pac"]}, - "application/x-nzb": {"source":"apache","extensions":["nzb"]}, - "application/x-perl": {"source":"nginx","extensions":["pl","pm"]}, - "application/x-pilot": {"source":"nginx","extensions":["prc","pdb"]}, - "application/x-pkcs12": {"source":"apache","compressible":false,"extensions":["p12","pfx"]}, - "application/x-pkcs7-certificates": {"source":"apache","extensions":["p7b","spc"]}, - "application/x-pkcs7-certreqresp": {"source":"apache","extensions":["p7r"]}, - "application/x-pki-message": {"source":"iana"}, - "application/x-rar-compressed": {"source":"apache","compressible":false,"extensions":["rar"]}, - "application/x-redhat-package-manager": {"source":"nginx","extensions":["rpm"]}, - "application/x-research-info-systems": {"source":"apache","extensions":["ris"]}, - "application/x-sea": {"source":"nginx","extensions":["sea"]}, - "application/x-sh": {"source":"apache","compressible":true,"extensions":["sh"]}, - "application/x-shar": {"source":"apache","extensions":["shar"]}, - "application/x-shockwave-flash": {"source":"apache","compressible":false,"extensions":["swf"]}, - "application/x-silverlight-app": {"source":"apache","extensions":["xap"]}, - "application/x-sql": {"source":"apache","extensions":["sql"]}, - "application/x-stuffit": {"source":"apache","compressible":false,"extensions":["sit"]}, - "application/x-stuffitx": {"source":"apache","extensions":["sitx"]}, - "application/x-subrip": {"source":"apache","extensions":["srt"]}, - "application/x-sv4cpio": {"source":"apache","extensions":["sv4cpio"]}, - "application/x-sv4crc": {"source":"apache","extensions":["sv4crc"]}, - "application/x-t3vm-image": {"source":"apache","extensions":["t3"]}, - "application/x-tads": {"source":"apache","extensions":["gam"]}, - "application/x-tar": {"source":"apache","compressible":true,"extensions":["tar"]}, - "application/x-tcl": {"source":"apache","extensions":["tcl","tk"]}, - "application/x-tex": {"source":"apache","extensions":["tex"]}, - "application/x-tex-tfm": {"source":"apache","extensions":["tfm"]}, - "application/x-texinfo": {"source":"apache","extensions":["texinfo","texi"]}, - "application/x-tgif": {"source":"apache","extensions":["obj"]}, - "application/x-ustar": {"source":"apache","extensions":["ustar"]}, - "application/x-virtualbox-hdd": {"compressible":true,"extensions":["hdd"]}, - "application/x-virtualbox-ova": {"compressible":true,"extensions":["ova"]}, - "application/x-virtualbox-ovf": {"compressible":true,"extensions":["ovf"]}, - "application/x-virtualbox-vbox": {"compressible":true,"extensions":["vbox"]}, - "application/x-virtualbox-vbox-extpack": {"compressible":false,"extensions":["vbox-extpack"]}, - "application/x-virtualbox-vdi": {"compressible":true,"extensions":["vdi"]}, - "application/x-virtualbox-vhd": {"compressible":true,"extensions":["vhd"]}, - "application/x-virtualbox-vmdk": {"compressible":true,"extensions":["vmdk"]}, - "application/x-wais-source": {"source":"apache","extensions":["src"]}, - "application/x-web-app-manifest+json": {"compressible":true,"extensions":["webapp"]}, - "application/x-www-form-urlencoded": {"source":"iana","compressible":true}, - "application/x-x509-ca-cert": {"source":"iana","extensions":["der","crt","pem"]}, - "application/x-x509-ca-ra-cert": {"source":"iana"}, - "application/x-x509-next-ca-cert": {"source":"iana"}, - "application/x-xfig": {"source":"apache","extensions":["fig"]}, - "application/x-xliff+xml": {"source":"apache","compressible":true,"extensions":["xlf"]}, - "application/x-xpinstall": {"source":"apache","compressible":false,"extensions":["xpi"]}, - "application/x-xz": {"source":"apache","extensions":["xz"]}, - "application/x-zip-compressed": {"extensions":["zip"]}, - "application/x-zmachine": {"source":"apache","extensions":["z1","z2","z3","z4","z5","z6","z7","z8"]}, - "application/x400-bp": {"source":"iana"}, - "application/xacml+xml": {"source":"iana","compressible":true}, - "application/xaml+xml": {"source":"apache","compressible":true,"extensions":["xaml"]}, - "application/xcap-att+xml": {"source":"iana","compressible":true,"extensions":["xav"]}, - "application/xcap-caps+xml": {"source":"iana","compressible":true,"extensions":["xca"]}, - "application/xcap-diff+xml": {"source":"iana","compressible":true,"extensions":["xdf"]}, - "application/xcap-el+xml": {"source":"iana","compressible":true,"extensions":["xel"]}, - "application/xcap-error+xml": {"source":"iana","compressible":true}, - "application/xcap-ns+xml": {"source":"iana","compressible":true,"extensions":["xns"]}, - "application/xcon-conference-info+xml": {"source":"iana","compressible":true}, - "application/xcon-conference-info-diff+xml": {"source":"iana","compressible":true}, - "application/xenc+xml": {"source":"iana","compressible":true,"extensions":["xenc"]}, - "application/xfdf": {"source":"iana","extensions":["xfdf"]}, - "application/xhtml+xml": {"source":"iana","compressible":true,"extensions":["xhtml","xht"]}, - "application/xhtml-voice+xml": {"source":"apache","compressible":true}, - "application/xliff+xml": {"source":"iana","compressible":true,"extensions":["xlf"]}, - "application/xml": {"source":"iana","compressible":true,"extensions":["xml","xsl","xsd","rng"]}, - "application/xml-dtd": {"source":"iana","compressible":true,"extensions":["dtd"]}, - "application/xml-external-parsed-entity": {"source":"iana"}, - "application/xml-patch+xml": {"source":"iana","compressible":true}, - "application/xmpp+xml": {"source":"iana","compressible":true}, - "application/xop+xml": {"source":"iana","compressible":true,"extensions":["xop"]}, - "application/xproc+xml": {"source":"apache","compressible":true,"extensions":["xpl"]}, - "application/xslt+xml": {"source":"iana","compressible":true,"extensions":["xsl","xslt"]}, - "application/xspf+xml": {"source":"apache","compressible":true,"extensions":["xspf"]}, - "application/xv+xml": {"source":"iana","compressible":true,"extensions":["mxml","xhvml","xvml","xvm"]}, - "application/yaml": {"source":"iana"}, - "application/yang": {"source":"iana","extensions":["yang"]}, - "application/yang-data+cbor": {"source":"iana"}, - "application/yang-data+json": {"source":"iana","compressible":true}, - "application/yang-data+xml": {"source":"iana","compressible":true}, - "application/yang-patch+json": {"source":"iana","compressible":true}, - "application/yang-patch+xml": {"source":"iana","compressible":true}, - "application/yang-sid+json": {"source":"iana","compressible":true}, - "application/yin+xml": {"source":"iana","compressible":true,"extensions":["yin"]}, - "application/zip": {"source":"iana","compressible":false,"extensions":["zip"]}, - "application/zip+dotlottie": {"extensions":["lottie"]}, - "application/zlib": {"source":"iana"}, - "application/zstd": {"source":"iana"}, - "audio/1d-interleaved-parityfec": {"source":"iana"}, - "audio/32kadpcm": {"source":"iana"}, - "audio/3gpp": {"source":"iana","compressible":false,"extensions":["3gpp"]}, - "audio/3gpp2": {"source":"iana"}, - "audio/aac": {"source":"iana","extensions":["adts","aac"]}, - "audio/ac3": {"source":"iana"}, - "audio/adpcm": {"source":"apache","extensions":["adp"]}, - "audio/amr": {"source":"iana","extensions":["amr"]}, - "audio/amr-wb": {"source":"iana"}, - "audio/amr-wb+": {"source":"iana"}, - "audio/aptx": {"source":"iana"}, - "audio/asc": {"source":"iana"}, - "audio/atrac-advanced-lossless": {"source":"iana"}, - "audio/atrac-x": {"source":"iana"}, - "audio/atrac3": {"source":"iana"}, - "audio/basic": {"source":"iana","compressible":false,"extensions":["au","snd"]}, - "audio/bv16": {"source":"iana"}, - "audio/bv32": {"source":"iana"}, - "audio/clearmode": {"source":"iana"}, - "audio/cn": {"source":"iana"}, - "audio/dat12": {"source":"iana"}, - "audio/dls": {"source":"iana"}, - "audio/dsr-es201108": {"source":"iana"}, - "audio/dsr-es202050": {"source":"iana"}, - "audio/dsr-es202211": {"source":"iana"}, - "audio/dsr-es202212": {"source":"iana"}, - "audio/dv": {"source":"iana"}, - "audio/dvi4": {"source":"iana"}, - "audio/eac3": {"source":"iana"}, - "audio/encaprtp": {"source":"iana"}, - "audio/evrc": {"source":"iana"}, - "audio/evrc-qcp": {"source":"iana"}, - "audio/evrc0": {"source":"iana"}, - "audio/evrc1": {"source":"iana"}, - "audio/evrcb": {"source":"iana"}, - "audio/evrcb0": {"source":"iana"}, - "audio/evrcb1": {"source":"iana"}, - "audio/evrcnw": {"source":"iana"}, - "audio/evrcnw0": {"source":"iana"}, - "audio/evrcnw1": {"source":"iana"}, - "audio/evrcwb": {"source":"iana"}, - "audio/evrcwb0": {"source":"iana"}, - "audio/evrcwb1": {"source":"iana"}, - "audio/evs": {"source":"iana"}, - "audio/flac": {"source":"iana"}, - "audio/flexfec": {"source":"iana"}, - "audio/fwdred": {"source":"iana"}, - "audio/g711-0": {"source":"iana"}, - "audio/g719": {"source":"iana"}, - "audio/g722": {"source":"iana"}, - "audio/g7221": {"source":"iana"}, - "audio/g723": {"source":"iana"}, - "audio/g726-16": {"source":"iana"}, - "audio/g726-24": {"source":"iana"}, - "audio/g726-32": {"source":"iana"}, - "audio/g726-40": {"source":"iana"}, - "audio/g728": {"source":"iana"}, - "audio/g729": {"source":"iana"}, - "audio/g7291": {"source":"iana"}, - "audio/g729d": {"source":"iana"}, - "audio/g729e": {"source":"iana"}, - "audio/gsm": {"source":"iana"}, - "audio/gsm-efr": {"source":"iana"}, - "audio/gsm-hr-08": {"source":"iana"}, - "audio/ilbc": {"source":"iana"}, - "audio/ip-mr_v2.5": {"source":"iana"}, - "audio/isac": {"source":"apache"}, - "audio/l16": {"source":"iana"}, - "audio/l20": {"source":"iana"}, - "audio/l24": {"source":"iana","compressible":false}, - "audio/l8": {"source":"iana"}, - "audio/lpc": {"source":"iana"}, - "audio/matroska": {"source":"iana"}, - "audio/melp": {"source":"iana"}, - "audio/melp1200": {"source":"iana"}, - "audio/melp2400": {"source":"iana"}, - "audio/melp600": {"source":"iana"}, - "audio/mhas": {"source":"iana"}, - "audio/midi": {"source":"apache","extensions":["mid","midi","kar","rmi"]}, - "audio/midi-clip": {"source":"iana"}, - "audio/mobile-xmf": {"source":"iana","extensions":["mxmf"]}, - "audio/mp3": {"compressible":false,"extensions":["mp3"]}, - "audio/mp4": {"source":"iana","compressible":false,"extensions":["m4a","mp4a","m4b"]}, - "audio/mp4a-latm": {"source":"iana"}, - "audio/mpa": {"source":"iana"}, - "audio/mpa-robust": {"source":"iana"}, - "audio/mpeg": {"source":"iana","compressible":false,"extensions":["mpga","mp2","mp2a","mp3","m2a","m3a"]}, - "audio/mpeg4-generic": {"source":"iana"}, - "audio/musepack": {"source":"apache"}, - "audio/ogg": {"source":"iana","compressible":false,"extensions":["oga","ogg","spx","opus"]}, - "audio/opus": {"source":"iana"}, - "audio/parityfec": {"source":"iana"}, - "audio/pcma": {"source":"iana"}, - "audio/pcma-wb": {"source":"iana"}, - "audio/pcmu": {"source":"iana"}, - "audio/pcmu-wb": {"source":"iana"}, - "audio/prs.sid": {"source":"iana"}, - "audio/qcelp": {"source":"iana"}, - "audio/raptorfec": {"source":"iana"}, - "audio/red": {"source":"iana"}, - "audio/rtp-enc-aescm128": {"source":"iana"}, - "audio/rtp-midi": {"source":"iana"}, - "audio/rtploopback": {"source":"iana"}, - "audio/rtx": {"source":"iana"}, - "audio/s3m": {"source":"apache","extensions":["s3m"]}, - "audio/scip": {"source":"iana"}, - "audio/silk": {"source":"apache","extensions":["sil"]}, - "audio/smv": {"source":"iana"}, - "audio/smv-qcp": {"source":"iana"}, - "audio/smv0": {"source":"iana"}, - "audio/sofa": {"source":"iana"}, - "audio/sp-midi": {"source":"iana"}, - "audio/speex": {"source":"iana"}, - "audio/t140c": {"source":"iana"}, - "audio/t38": {"source":"iana"}, - "audio/telephone-event": {"source":"iana"}, - "audio/tetra_acelp": {"source":"iana"}, - "audio/tetra_acelp_bb": {"source":"iana"}, - "audio/tone": {"source":"iana"}, - "audio/tsvcis": {"source":"iana"}, - "audio/uemclip": {"source":"iana"}, - "audio/ulpfec": {"source":"iana"}, - "audio/usac": {"source":"iana"}, - "audio/vdvi": {"source":"iana"}, - "audio/vmr-wb": {"source":"iana"}, - "audio/vnd.3gpp.iufp": {"source":"iana"}, - "audio/vnd.4sb": {"source":"iana"}, - "audio/vnd.audiokoz": {"source":"iana"}, - "audio/vnd.celp": {"source":"iana"}, - "audio/vnd.cisco.nse": {"source":"iana"}, - "audio/vnd.cmles.radio-events": {"source":"iana"}, - "audio/vnd.cns.anp1": {"source":"iana"}, - "audio/vnd.cns.inf1": {"source":"iana"}, - "audio/vnd.dece.audio": {"source":"iana","extensions":["uva","uvva"]}, - "audio/vnd.digital-winds": {"source":"iana","extensions":["eol"]}, - "audio/vnd.dlna.adts": {"source":"iana"}, - "audio/vnd.dolby.heaac.1": {"source":"iana"}, - "audio/vnd.dolby.heaac.2": {"source":"iana"}, - "audio/vnd.dolby.mlp": {"source":"iana"}, - "audio/vnd.dolby.mps": {"source":"iana"}, - "audio/vnd.dolby.pl2": {"source":"iana"}, - "audio/vnd.dolby.pl2x": {"source":"iana"}, - "audio/vnd.dolby.pl2z": {"source":"iana"}, - "audio/vnd.dolby.pulse.1": {"source":"iana"}, - "audio/vnd.dra": {"source":"iana","extensions":["dra"]}, - "audio/vnd.dts": {"source":"iana","extensions":["dts"]}, - "audio/vnd.dts.hd": {"source":"iana","extensions":["dtshd"]}, - "audio/vnd.dts.uhd": {"source":"iana"}, - "audio/vnd.dvb.file": {"source":"iana"}, - "audio/vnd.everad.plj": {"source":"iana"}, - "audio/vnd.hns.audio": {"source":"iana"}, - "audio/vnd.lucent.voice": {"source":"iana","extensions":["lvp"]}, - "audio/vnd.ms-playready.media.pya": {"source":"iana","extensions":["pya"]}, - "audio/vnd.nokia.mobile-xmf": {"source":"iana"}, - "audio/vnd.nortel.vbk": {"source":"iana"}, - "audio/vnd.nuera.ecelp4800": {"source":"iana","extensions":["ecelp4800"]}, - "audio/vnd.nuera.ecelp7470": {"source":"iana","extensions":["ecelp7470"]}, - "audio/vnd.nuera.ecelp9600": {"source":"iana","extensions":["ecelp9600"]}, - "audio/vnd.octel.sbc": {"source":"iana"}, - "audio/vnd.presonus.multitrack": {"source":"iana"}, - "audio/vnd.qcelp": {"source":"apache"}, - "audio/vnd.rhetorex.32kadpcm": {"source":"iana"}, - "audio/vnd.rip": {"source":"iana","extensions":["rip"]}, - "audio/vnd.rn-realaudio": {"compressible":false}, - "audio/vnd.sealedmedia.softseal.mpeg": {"source":"iana"}, - "audio/vnd.vmx.cvsd": {"source":"iana"}, - "audio/vnd.wave": {"compressible":false}, - "audio/vorbis": {"source":"iana","compressible":false}, - "audio/vorbis-config": {"source":"iana"}, - "audio/wav": {"compressible":false,"extensions":["wav"]}, - "audio/wave": {"compressible":false,"extensions":["wav"]}, - "audio/webm": {"source":"apache","compressible":false,"extensions":["weba"]}, - "audio/x-aac": {"source":"apache","compressible":false,"extensions":["aac"]}, - "audio/x-aiff": {"source":"apache","extensions":["aif","aiff","aifc"]}, - "audio/x-caf": {"source":"apache","compressible":false,"extensions":["caf"]}, - "audio/x-flac": {"source":"apache","extensions":["flac"]}, - "audio/x-m4a": {"source":"nginx","extensions":["m4a"]}, - "audio/x-matroska": {"source":"apache","extensions":["mka"]}, - "audio/x-mpegurl": {"source":"apache","extensions":["m3u"]}, - "audio/x-ms-wax": {"source":"apache","extensions":["wax"]}, - "audio/x-ms-wma": {"source":"apache","extensions":["wma"]}, - "audio/x-pn-realaudio": {"source":"apache","extensions":["ram","ra"]}, - "audio/x-pn-realaudio-plugin": {"source":"apache","extensions":["rmp"]}, - "audio/x-realaudio": {"source":"nginx","extensions":["ra"]}, - "audio/x-tta": {"source":"apache"}, - "audio/x-wav": {"source":"apache","extensions":["wav"]}, - "audio/xm": {"source":"apache","extensions":["xm"]}, - "chemical/x-cdx": {"source":"apache","extensions":["cdx"]}, - "chemical/x-cif": {"source":"apache","extensions":["cif"]}, - "chemical/x-cmdf": {"source":"apache","extensions":["cmdf"]}, - "chemical/x-cml": {"source":"apache","extensions":["cml"]}, - "chemical/x-csml": {"source":"apache","extensions":["csml"]}, - "chemical/x-pdb": {"source":"apache"}, - "chemical/x-xyz": {"source":"apache","extensions":["xyz"]}, - "font/collection": {"source":"iana","extensions":["ttc"]}, - "font/otf": {"source":"iana","compressible":true,"extensions":["otf"]}, - "font/sfnt": {"source":"iana"}, - "font/ttf": {"source":"iana","compressible":true,"extensions":["ttf"]}, - "font/woff": {"source":"iana","extensions":["woff"]}, - "font/woff2": {"source":"iana","extensions":["woff2"]}, - "image/aces": {"source":"iana","extensions":["exr"]}, - "image/apng": {"source":"iana","compressible":false,"extensions":["apng"]}, - "image/avci": {"source":"iana","extensions":["avci"]}, - "image/avcs": {"source":"iana","extensions":["avcs"]}, - "image/avif": {"source":"iana","compressible":false,"extensions":["avif"]}, - "image/bmp": {"source":"iana","compressible":true,"extensions":["bmp","dib"]}, - "image/cgm": {"source":"iana","extensions":["cgm"]}, - "image/dicom-rle": {"source":"iana","extensions":["drle"]}, - "image/dpx": {"source":"iana","extensions":["dpx"]}, - "image/emf": {"source":"iana","extensions":["emf"]}, - "image/fits": {"source":"iana","extensions":["fits"]}, - "image/g3fax": {"source":"iana","extensions":["g3"]}, - "image/gif": {"source":"iana","compressible":false,"extensions":["gif"]}, - "image/heic": {"source":"iana","extensions":["heic"]}, - "image/heic-sequence": {"source":"iana","extensions":["heics"]}, - "image/heif": {"source":"iana","extensions":["heif"]}, - "image/heif-sequence": {"source":"iana","extensions":["heifs"]}, - "image/hej2k": {"source":"iana","extensions":["hej2"]}, - "image/ief": {"source":"iana","extensions":["ief"]}, - "image/j2c": {"source":"iana"}, - "image/jaii": {"source":"iana","extensions":["jaii"]}, - "image/jais": {"source":"iana","extensions":["jais"]}, - "image/jls": {"source":"iana","extensions":["jls"]}, - "image/jp2": {"source":"iana","compressible":false,"extensions":["jp2","jpg2"]}, - "image/jpeg": {"source":"iana","compressible":false,"extensions":["jpg","jpeg","jpe"]}, - "image/jph": {"source":"iana","extensions":["jph"]}, - "image/jphc": {"source":"iana","extensions":["jhc"]}, - "image/jpm": {"source":"iana","compressible":false,"extensions":["jpm","jpgm"]}, - "image/jpx": {"source":"iana","compressible":false,"extensions":["jpx","jpf"]}, - "image/jxl": {"source":"iana","extensions":["jxl"]}, - "image/jxr": {"source":"iana","extensions":["jxr"]}, - "image/jxra": {"source":"iana","extensions":["jxra"]}, - "image/jxrs": {"source":"iana","extensions":["jxrs"]}, - "image/jxs": {"source":"iana","extensions":["jxs"]}, - "image/jxsc": {"source":"iana","extensions":["jxsc"]}, - "image/jxsi": {"source":"iana","extensions":["jxsi"]}, - "image/jxss": {"source":"iana","extensions":["jxss"]}, - "image/ktx": {"source":"iana","extensions":["ktx"]}, - "image/ktx2": {"source":"iana","extensions":["ktx2"]}, - "image/naplps": {"source":"iana"}, - "image/pjpeg": {"compressible":false,"extensions":["jfif"]}, - "image/png": {"source":"iana","compressible":false,"extensions":["png"]}, - "image/prs.btif": {"source":"iana","extensions":["btif","btf"]}, - "image/prs.pti": {"source":"iana","extensions":["pti"]}, - "image/pwg-raster": {"source":"iana"}, - "image/sgi": {"source":"apache","extensions":["sgi"]}, - "image/svg+xml": {"source":"iana","compressible":true,"extensions":["svg","svgz"]}, - "image/t38": {"source":"iana","extensions":["t38"]}, - "image/tiff": {"source":"iana","compressible":false,"extensions":["tif","tiff"]}, - "image/tiff-fx": {"source":"iana","extensions":["tfx"]}, - "image/vnd.adobe.photoshop": {"source":"iana","compressible":true,"extensions":["psd"]}, - "image/vnd.airzip.accelerator.azv": {"source":"iana","extensions":["azv"]}, - "image/vnd.clip": {"source":"iana"}, - "image/vnd.cns.inf2": {"source":"iana"}, - "image/vnd.dece.graphic": {"source":"iana","extensions":["uvi","uvvi","uvg","uvvg"]}, - "image/vnd.djvu": {"source":"iana","extensions":["djvu","djv"]}, - "image/vnd.dvb.subtitle": {"source":"iana","extensions":["sub"]}, - "image/vnd.dwg": {"source":"iana","extensions":["dwg"]}, - "image/vnd.dxf": {"source":"iana","extensions":["dxf"]}, - "image/vnd.fastbidsheet": {"source":"iana","extensions":["fbs"]}, - "image/vnd.fpx": {"source":"iana","extensions":["fpx"]}, - "image/vnd.fst": {"source":"iana","extensions":["fst"]}, - "image/vnd.fujixerox.edmics-mmr": {"source":"iana","extensions":["mmr"]}, - "image/vnd.fujixerox.edmics-rlc": {"source":"iana","extensions":["rlc"]}, - "image/vnd.globalgraphics.pgb": {"source":"iana"}, - "image/vnd.microsoft.icon": {"source":"iana","compressible":true,"extensions":["ico"]}, - "image/vnd.mix": {"source":"iana"}, - "image/vnd.mozilla.apng": {"source":"iana"}, - "image/vnd.ms-dds": {"compressible":true,"extensions":["dds"]}, - "image/vnd.ms-modi": {"source":"iana","extensions":["mdi"]}, - "image/vnd.ms-photo": {"source":"apache","extensions":["wdp"]}, - "image/vnd.net-fpx": {"source":"iana","extensions":["npx"]}, - "image/vnd.pco.b16": {"source":"iana","extensions":["b16"]}, - "image/vnd.radiance": {"source":"iana"}, - "image/vnd.sealed.png": {"source":"iana"}, - "image/vnd.sealedmedia.softseal.gif": {"source":"iana"}, - "image/vnd.sealedmedia.softseal.jpg": {"source":"iana"}, - "image/vnd.svf": {"source":"iana"}, - "image/vnd.tencent.tap": {"source":"iana","extensions":["tap"]}, - "image/vnd.valve.source.texture": {"source":"iana","extensions":["vtf"]}, - "image/vnd.wap.wbmp": {"source":"iana","extensions":["wbmp"]}, - "image/vnd.xiff": {"source":"iana","extensions":["xif"]}, - "image/vnd.zbrush.pcx": {"source":"iana","extensions":["pcx"]}, - "image/webp": {"source":"iana","extensions":["webp"]}, - "image/wmf": {"source":"iana","extensions":["wmf"]}, - "image/x-3ds": {"source":"apache","extensions":["3ds"]}, - "image/x-adobe-dng": {"extensions":["dng"]}, - "image/x-cmu-raster": {"source":"apache","extensions":["ras"]}, - "image/x-cmx": {"source":"apache","extensions":["cmx"]}, - "image/x-emf": {"source":"iana"}, - "image/x-freehand": {"source":"apache","extensions":["fh","fhc","fh4","fh5","fh7"]}, - "image/x-icon": {"source":"apache","compressible":true,"extensions":["ico"]}, - "image/x-jng": {"source":"nginx","extensions":["jng"]}, - "image/x-mrsid-image": {"source":"apache","extensions":["sid"]}, - "image/x-ms-bmp": {"source":"nginx","compressible":true,"extensions":["bmp"]}, - "image/x-pcx": {"source":"apache","extensions":["pcx"]}, - "image/x-pict": {"source":"apache","extensions":["pic","pct"]}, - "image/x-portable-anymap": {"source":"apache","extensions":["pnm"]}, - "image/x-portable-bitmap": {"source":"apache","extensions":["pbm"]}, - "image/x-portable-graymap": {"source":"apache","extensions":["pgm"]}, - "image/x-portable-pixmap": {"source":"apache","extensions":["ppm"]}, - "image/x-rgb": {"source":"apache","extensions":["rgb"]}, - "image/x-tga": {"source":"apache","extensions":["tga"]}, - "image/x-wmf": {"source":"iana"}, - "image/x-xbitmap": {"source":"apache","extensions":["xbm"]}, - "image/x-xcf": {"compressible":false}, - "image/x-xpixmap": {"source":"apache","extensions":["xpm"]}, - "image/x-xwindowdump": {"source":"apache","extensions":["xwd"]}, - "message/bhttp": {"source":"iana"}, - "message/cpim": {"source":"iana"}, - "message/delivery-status": {"source":"iana"}, - "message/disposition-notification": {"source":"iana","extensions":["disposition-notification"]}, - "message/external-body": {"source":"iana"}, - "message/feedback-report": {"source":"iana"}, - "message/global": {"source":"iana","extensions":["u8msg"]}, - "message/global-delivery-status": {"source":"iana","extensions":["u8dsn"]}, - "message/global-disposition-notification": {"source":"iana","extensions":["u8mdn"]}, - "message/global-headers": {"source":"iana","extensions":["u8hdr"]}, - "message/http": {"source":"iana","compressible":false}, - "message/imdn+xml": {"source":"iana","compressible":true}, - "message/mls": {"source":"iana"}, - "message/news": {"source":"apache"}, - "message/ohttp-req": {"source":"iana"}, - "message/ohttp-res": {"source":"iana"}, - "message/partial": {"source":"iana","compressible":false}, - "message/rfc822": {"source":"iana","compressible":true,"extensions":["eml","mime","mht","mhtml"]}, - "message/s-http": {"source":"apache"}, - "message/sip": {"source":"iana"}, - "message/sipfrag": {"source":"iana"}, - "message/tracking-status": {"source":"iana"}, - "message/vnd.si.simp": {"source":"apache"}, - "message/vnd.wfa.wsc": {"source":"iana","extensions":["wsc"]}, - "model/3mf": {"source":"iana","extensions":["3mf"]}, - "model/e57": {"source":"iana"}, - "model/gltf+json": {"source":"iana","compressible":true,"extensions":["gltf"]}, - "model/gltf-binary": {"source":"iana","compressible":true,"extensions":["glb"]}, - "model/iges": {"source":"iana","compressible":false,"extensions":["igs","iges"]}, - "model/jt": {"source":"iana","extensions":["jt"]}, - "model/mesh": {"source":"iana","compressible":false,"extensions":["msh","mesh","silo"]}, - "model/mtl": {"source":"iana","extensions":["mtl"]}, - "model/obj": {"source":"iana","extensions":["obj"]}, - "model/prc": {"source":"iana","extensions":["prc"]}, - "model/step": {"source":"iana","extensions":["step","stp","stpnc","p21","210"]}, - "model/step+xml": {"source":"iana","compressible":true,"extensions":["stpx"]}, - "model/step+zip": {"source":"iana","compressible":false,"extensions":["stpz"]}, - "model/step-xml+zip": {"source":"iana","compressible":false,"extensions":["stpxz"]}, - "model/stl": {"source":"iana","extensions":["stl"]}, - "model/u3d": {"source":"iana","extensions":["u3d"]}, - "model/vnd.bary": {"source":"iana","extensions":["bary"]}, - "model/vnd.cld": {"source":"iana","extensions":["cld"]}, - "model/vnd.collada+xml": {"source":"iana","compressible":true,"extensions":["dae"]}, - "model/vnd.dwf": {"source":"iana","extensions":["dwf"]}, - "model/vnd.flatland.3dml": {"source":"iana"}, - "model/vnd.gdl": {"source":"iana","extensions":["gdl"]}, - "model/vnd.gs-gdl": {"source":"apache"}, - "model/vnd.gs.gdl": {"source":"iana"}, - "model/vnd.gtw": {"source":"iana","extensions":["gtw"]}, - "model/vnd.moml+xml": {"source":"iana","compressible":true}, - "model/vnd.mts": {"source":"iana","extensions":["mts"]}, - "model/vnd.opengex": {"source":"iana","extensions":["ogex"]}, - "model/vnd.parasolid.transmit.binary": {"source":"iana","extensions":["x_b"]}, - "model/vnd.parasolid.transmit.text": {"source":"iana","extensions":["x_t"]}, - "model/vnd.pytha.pyox": {"source":"iana","extensions":["pyo","pyox"]}, - "model/vnd.rosette.annotated-data-model": {"source":"iana"}, - "model/vnd.sap.vds": {"source":"iana","extensions":["vds"]}, - "model/vnd.usda": {"source":"iana","extensions":["usda"]}, - "model/vnd.usdz+zip": {"source":"iana","compressible":false,"extensions":["usdz"]}, - "model/vnd.valve.source.compiled-map": {"source":"iana","extensions":["bsp"]}, - "model/vnd.vtu": {"source":"iana","extensions":["vtu"]}, - "model/vrml": {"source":"iana","compressible":false,"extensions":["wrl","vrml"]}, - "model/x3d+binary": {"source":"apache","compressible":false,"extensions":["x3db","x3dbz"]}, - "model/x3d+fastinfoset": {"source":"iana","extensions":["x3db"]}, - "model/x3d+vrml": {"source":"apache","compressible":false,"extensions":["x3dv","x3dvz"]}, - "model/x3d+xml": {"source":"iana","compressible":true,"extensions":["x3d","x3dz"]}, - "model/x3d-vrml": {"source":"iana","extensions":["x3dv"]}, - "multipart/alternative": {"source":"iana","compressible":false}, - "multipart/appledouble": {"source":"iana"}, - "multipart/byteranges": {"source":"iana"}, - "multipart/digest": {"source":"iana"}, - "multipart/encrypted": {"source":"iana","compressible":false}, - "multipart/form-data": {"source":"iana","compressible":false}, - "multipart/header-set": {"source":"iana"}, - "multipart/mixed": {"source":"iana"}, - "multipart/multilingual": {"source":"iana"}, - "multipart/parallel": {"source":"iana"}, - "multipart/related": {"source":"iana","compressible":false}, - "multipart/report": {"source":"iana"}, - "multipart/signed": {"source":"iana","compressible":false}, - "multipart/vnd.bint.med-plus": {"source":"iana"}, - "multipart/voice-message": {"source":"iana"}, - "multipart/x-mixed-replace": {"source":"iana"}, - "text/1d-interleaved-parityfec": {"source":"iana"}, - "text/cache-manifest": {"source":"iana","compressible":true,"extensions":["appcache","manifest"]}, - "text/calendar": {"source":"iana","extensions":["ics","ifb"]}, - "text/calender": {"compressible":true}, - "text/cmd": {"compressible":true}, - "text/coffeescript": {"extensions":["coffee","litcoffee"]}, - "text/cql": {"source":"iana"}, - "text/cql-expression": {"source":"iana"}, - "text/cql-identifier": {"source":"iana"}, - "text/css": {"source":"iana","charset":"UTF-8","compressible":true,"extensions":["css"]}, - "text/csv": {"source":"iana","compressible":true,"extensions":["csv"]}, - "text/csv-schema": {"source":"iana"}, - "text/directory": {"source":"iana"}, - "text/dns": {"source":"iana"}, - "text/ecmascript": {"source":"apache"}, - "text/encaprtp": {"source":"iana"}, - "text/enriched": {"source":"iana"}, - "text/fhirpath": {"source":"iana"}, - "text/flexfec": {"source":"iana"}, - "text/fwdred": {"source":"iana"}, - "text/gff3": {"source":"iana"}, - "text/grammar-ref-list": {"source":"iana"}, - "text/hl7v2": {"source":"iana"}, - "text/html": {"source":"iana","compressible":true,"extensions":["html","htm","shtml"]}, - "text/jade": {"extensions":["jade"]}, - "text/javascript": {"source":"iana","charset":"UTF-8","compressible":true,"extensions":["js","mjs"]}, - "text/jcr-cnd": {"source":"iana"}, - "text/jsx": {"compressible":true,"extensions":["jsx"]}, - "text/less": {"compressible":true,"extensions":["less"]}, - "text/markdown": {"source":"iana","compressible":true,"extensions":["md","markdown"]}, - "text/mathml": {"source":"nginx","extensions":["mml"]}, - "text/mdx": {"compressible":true,"extensions":["mdx"]}, - "text/mizar": {"source":"iana"}, - "text/n3": {"source":"iana","charset":"UTF-8","compressible":true,"extensions":["n3"]}, - "text/parameters": {"source":"iana","charset":"UTF-8"}, - "text/parityfec": {"source":"iana"}, - "text/plain": {"source":"iana","compressible":true,"extensions":["txt","text","conf","def","list","log","in","ini"]}, - "text/provenance-notation": {"source":"iana","charset":"UTF-8"}, - "text/prs.fallenstein.rst": {"source":"iana"}, - "text/prs.lines.tag": {"source":"iana","extensions":["dsc"]}, - "text/prs.prop.logic": {"source":"iana"}, - "text/prs.texi": {"source":"iana"}, - "text/raptorfec": {"source":"iana"}, - "text/red": {"source":"iana"}, - "text/rfc822-headers": {"source":"iana"}, - "text/richtext": {"source":"iana","compressible":true,"extensions":["rtx"]}, - "text/rtf": {"source":"iana","compressible":true,"extensions":["rtf"]}, - "text/rtp-enc-aescm128": {"source":"iana"}, - "text/rtploopback": {"source":"iana"}, - "text/rtx": {"source":"iana"}, - "text/sgml": {"source":"iana","extensions":["sgml","sgm"]}, - "text/shaclc": {"source":"iana"}, - "text/shex": {"source":"iana","extensions":["shex"]}, - "text/slim": {"extensions":["slim","slm"]}, - "text/spdx": {"source":"iana","extensions":["spdx"]}, - "text/strings": {"source":"iana"}, - "text/stylus": {"extensions":["stylus","styl"]}, - "text/t140": {"source":"iana"}, - "text/tab-separated-values": {"source":"iana","compressible":true,"extensions":["tsv"]}, - "text/troff": {"source":"iana","extensions":["t","tr","roff","man","me","ms"]}, - "text/turtle": {"source":"iana","charset":"UTF-8","extensions":["ttl"]}, - "text/ulpfec": {"source":"iana"}, - "text/uri-list": {"source":"iana","compressible":true,"extensions":["uri","uris","urls"]}, - "text/vcard": {"source":"iana","compressible":true,"extensions":["vcard"]}, - "text/vnd.a": {"source":"iana"}, - "text/vnd.abc": {"source":"iana"}, - "text/vnd.ascii-art": {"source":"iana"}, - "text/vnd.curl": {"source":"iana","extensions":["curl"]}, - "text/vnd.curl.dcurl": {"source":"apache","extensions":["dcurl"]}, - "text/vnd.curl.mcurl": {"source":"apache","extensions":["mcurl"]}, - "text/vnd.curl.scurl": {"source":"apache","extensions":["scurl"]}, - "text/vnd.debian.copyright": {"source":"iana","charset":"UTF-8"}, - "text/vnd.dmclientscript": {"source":"iana"}, - "text/vnd.dvb.subtitle": {"source":"iana","extensions":["sub"]}, - "text/vnd.esmertec.theme-descriptor": {"source":"iana","charset":"UTF-8"}, - "text/vnd.exchangeable": {"source":"iana"}, - "text/vnd.familysearch.gedcom": {"source":"iana","extensions":["ged"]}, - "text/vnd.ficlab.flt": {"source":"iana"}, - "text/vnd.fly": {"source":"iana","extensions":["fly"]}, - "text/vnd.fmi.flexstor": {"source":"iana","extensions":["flx"]}, - "text/vnd.gml": {"source":"iana"}, - "text/vnd.graphviz": {"source":"iana","extensions":["gv"]}, - "text/vnd.hans": {"source":"iana"}, - "text/vnd.hgl": {"source":"iana"}, - "text/vnd.in3d.3dml": {"source":"iana","extensions":["3dml"]}, - "text/vnd.in3d.spot": {"source":"iana","extensions":["spot"]}, - "text/vnd.iptc.newsml": {"source":"iana"}, - "text/vnd.iptc.nitf": {"source":"iana"}, - "text/vnd.latex-z": {"source":"iana"}, - "text/vnd.motorola.reflex": {"source":"iana"}, - "text/vnd.ms-mediapackage": {"source":"iana"}, - "text/vnd.net2phone.commcenter.command": {"source":"iana"}, - "text/vnd.radisys.msml-basic-layout": {"source":"iana"}, - "text/vnd.senx.warpscript": {"source":"iana"}, - "text/vnd.si.uricatalogue": {"source":"apache"}, - "text/vnd.sosi": {"source":"iana"}, - "text/vnd.sun.j2me.app-descriptor": {"source":"iana","charset":"UTF-8","extensions":["jad"]}, - "text/vnd.trolltech.linguist": {"source":"iana","charset":"UTF-8"}, - "text/vnd.vcf": {"source":"iana"}, - "text/vnd.wap.si": {"source":"iana"}, - "text/vnd.wap.sl": {"source":"iana"}, - "text/vnd.wap.wml": {"source":"iana","extensions":["wml"]}, - "text/vnd.wap.wmlscript": {"source":"iana","extensions":["wmls"]}, - "text/vnd.zoo.kcl": {"source":"iana"}, - "text/vtt": {"source":"iana","charset":"UTF-8","compressible":true,"extensions":["vtt"]}, - "text/wgsl": {"source":"iana","extensions":["wgsl"]}, - "text/x-asm": {"source":"apache","extensions":["s","asm"]}, - "text/x-c": {"source":"apache","extensions":["c","cc","cxx","cpp","h","hh","dic"]}, - "text/x-component": {"source":"nginx","extensions":["htc"]}, - "text/x-fortran": {"source":"apache","extensions":["f","for","f77","f90"]}, - "text/x-gwt-rpc": {"compressible":true}, - "text/x-handlebars-template": {"extensions":["hbs"]}, - "text/x-java-source": {"source":"apache","extensions":["java"]}, - "text/x-jquery-tmpl": {"compressible":true}, - "text/x-lua": {"extensions":["lua"]}, - "text/x-markdown": {"compressible":true,"extensions":["mkd"]}, - "text/x-nfo": {"source":"apache","extensions":["nfo"]}, - "text/x-opml": {"source":"apache","extensions":["opml"]}, - "text/x-org": {"compressible":true,"extensions":["org"]}, - "text/x-pascal": {"source":"apache","extensions":["p","pas"]}, - "text/x-processing": {"compressible":true,"extensions":["pde"]}, - "text/x-sass": {"extensions":["sass"]}, - "text/x-scss": {"extensions":["scss"]}, - "text/x-setext": {"source":"apache","extensions":["etx"]}, - "text/x-sfv": {"source":"apache","extensions":["sfv"]}, - "text/x-suse-ymp": {"compressible":true,"extensions":["ymp"]}, - "text/x-uuencode": {"source":"apache","extensions":["uu"]}, - "text/x-vcalendar": {"source":"apache","extensions":["vcs"]}, - "text/x-vcard": {"source":"apache","extensions":["vcf"]}, - "text/xml": {"source":"iana","compressible":true,"extensions":["xml"]}, - "text/xml-external-parsed-entity": {"source":"iana"}, - "text/yaml": {"compressible":true,"extensions":["yaml","yml"]}, - "video/1d-interleaved-parityfec": {"source":"iana"}, - "video/3gpp": {"source":"iana","extensions":["3gp","3gpp"]}, - "video/3gpp-tt": {"source":"iana"}, - "video/3gpp2": {"source":"iana","extensions":["3g2"]}, - "video/av1": {"source":"iana"}, - "video/bmpeg": {"source":"iana"}, - "video/bt656": {"source":"iana"}, - "video/celb": {"source":"iana"}, - "video/dv": {"source":"iana"}, - "video/encaprtp": {"source":"iana"}, - "video/evc": {"source":"iana"}, - "video/ffv1": {"source":"iana"}, - "video/flexfec": {"source":"iana"}, - "video/h261": {"source":"iana","extensions":["h261"]}, - "video/h263": {"source":"iana","extensions":["h263"]}, - "video/h263-1998": {"source":"iana"}, - "video/h263-2000": {"source":"iana"}, - "video/h264": {"source":"iana","extensions":["h264"]}, - "video/h264-rcdo": {"source":"iana"}, - "video/h264-svc": {"source":"iana"}, - "video/h265": {"source":"iana"}, - "video/h266": {"source":"iana"}, - "video/iso.segment": {"source":"iana","extensions":["m4s"]}, - "video/jpeg": {"source":"iana","extensions":["jpgv"]}, - "video/jpeg2000": {"source":"iana"}, - "video/jpm": {"source":"apache","extensions":["jpm","jpgm"]}, - "video/jxsv": {"source":"iana"}, - "video/lottie+json": {"source":"iana","compressible":true}, - "video/matroska": {"source":"iana"}, - "video/matroska-3d": {"source":"iana"}, - "video/mj2": {"source":"iana","extensions":["mj2","mjp2"]}, - "video/mp1s": {"source":"iana"}, - "video/mp2p": {"source":"iana"}, - "video/mp2t": {"source":"iana","extensions":["ts","m2t","m2ts","mts"]}, - "video/mp4": {"source":"iana","compressible":false,"extensions":["mp4","mp4v","mpg4"]}, - "video/mp4v-es": {"source":"iana"}, - "video/mpeg": {"source":"iana","compressible":false,"extensions":["mpeg","mpg","mpe","m1v","m2v"]}, - "video/mpeg4-generic": {"source":"iana"}, - "video/mpv": {"source":"iana"}, - "video/nv": {"source":"iana"}, - "video/ogg": {"source":"iana","compressible":false,"extensions":["ogv"]}, - "video/parityfec": {"source":"iana"}, - "video/pointer": {"source":"iana"}, - "video/quicktime": {"source":"iana","compressible":false,"extensions":["qt","mov"]}, - "video/raptorfec": {"source":"iana"}, - "video/raw": {"source":"iana"}, - "video/rtp-enc-aescm128": {"source":"iana"}, - "video/rtploopback": {"source":"iana"}, - "video/rtx": {"source":"iana"}, - "video/scip": {"source":"iana"}, - "video/smpte291": {"source":"iana"}, - "video/smpte292m": {"source":"iana"}, - "video/ulpfec": {"source":"iana"}, - "video/vc1": {"source":"iana"}, - "video/vc2": {"source":"iana"}, - "video/vnd.cctv": {"source":"iana"}, - "video/vnd.dece.hd": {"source":"iana","extensions":["uvh","uvvh"]}, - "video/vnd.dece.mobile": {"source":"iana","extensions":["uvm","uvvm"]}, - "video/vnd.dece.mp4": {"source":"iana"}, - "video/vnd.dece.pd": {"source":"iana","extensions":["uvp","uvvp"]}, - "video/vnd.dece.sd": {"source":"iana","extensions":["uvs","uvvs"]}, - "video/vnd.dece.video": {"source":"iana","extensions":["uvv","uvvv"]}, - "video/vnd.directv.mpeg": {"source":"iana"}, - "video/vnd.directv.mpeg-tts": {"source":"iana"}, - "video/vnd.dlna.mpeg-tts": {"source":"iana"}, - "video/vnd.dvb.file": {"source":"iana","extensions":["dvb"]}, - "video/vnd.fvt": {"source":"iana","extensions":["fvt"]}, - "video/vnd.hns.video": {"source":"iana"}, - "video/vnd.iptvforum.1dparityfec-1010": {"source":"iana"}, - "video/vnd.iptvforum.1dparityfec-2005": {"source":"iana"}, - "video/vnd.iptvforum.2dparityfec-1010": {"source":"iana"}, - "video/vnd.iptvforum.2dparityfec-2005": {"source":"iana"}, - "video/vnd.iptvforum.ttsavc": {"source":"iana"}, - "video/vnd.iptvforum.ttsmpeg2": {"source":"iana"}, - "video/vnd.motorola.video": {"source":"iana"}, - "video/vnd.motorola.videop": {"source":"iana"}, - "video/vnd.mpegurl": {"source":"iana","extensions":["mxu","m4u"]}, - "video/vnd.ms-playready.media.pyv": {"source":"iana","extensions":["pyv"]}, - "video/vnd.nokia.interleaved-multimedia": {"source":"iana"}, - "video/vnd.nokia.mp4vr": {"source":"iana"}, - "video/vnd.nokia.videovoip": {"source":"iana"}, - "video/vnd.objectvideo": {"source":"iana"}, - "video/vnd.planar": {"source":"iana"}, - "video/vnd.radgamettools.bink": {"source":"iana"}, - "video/vnd.radgamettools.smacker": {"source":"apache"}, - "video/vnd.sealed.mpeg1": {"source":"iana"}, - "video/vnd.sealed.mpeg4": {"source":"iana"}, - "video/vnd.sealed.swf": {"source":"iana"}, - "video/vnd.sealedmedia.softseal.mov": {"source":"iana"}, - "video/vnd.uvvu.mp4": {"source":"iana","extensions":["uvu","uvvu"]}, - "video/vnd.vivo": {"source":"iana","extensions":["viv"]}, - "video/vnd.youtube.yt": {"source":"iana"}, - "video/vp8": {"source":"iana"}, - "video/vp9": {"source":"iana"}, - "video/webm": {"source":"apache","compressible":false,"extensions":["webm"]}, - "video/x-f4v": {"source":"apache","extensions":["f4v"]}, - "video/x-fli": {"source":"apache","extensions":["fli"]}, - "video/x-flv": {"source":"apache","compressible":false,"extensions":["flv"]}, - "video/x-m4v": {"source":"apache","extensions":["m4v"]}, - "video/x-matroska": {"source":"apache","compressible":false,"extensions":["mkv","mk3d","mks"]}, - "video/x-mng": {"source":"apache","extensions":["mng"]}, - "video/x-ms-asf": {"source":"apache","extensions":["asf","asx"]}, - "video/x-ms-vob": {"source":"apache","extensions":["vob"]}, - "video/x-ms-wm": {"source":"apache","extensions":["wm"]}, - "video/x-ms-wmv": {"source":"apache","compressible":false,"extensions":["wmv"]}, - "video/x-ms-wmx": {"source":"apache","extensions":["wmx"]}, - "video/x-ms-wvx": {"source":"apache","extensions":["wvx"]}, - "video/x-msvideo": {"source":"apache","extensions":["avi"]}, - "video/x-sgi-movie": {"source":"apache","extensions":["movie"]}, - "video/x-smv": {"source":"apache","extensions":["smv"]}, - "x-conference/x-cooltalk": {"source":"apache","extensions":["ice"]}, - "x-shader/x-fragment": {"compressible":true}, - "x-shader/x-vertex": {"compressible":true}, -}; - -/*! - * mime-db - * Copyright(c) 2014 Jonathan Ong - * Copyright(c) 2015-2022 Douglas Christopher Wilson - * MIT Licensed - */ - -var mimeDb; -var hasRequiredMimeDb; - -function requireMimeDb () { - if (hasRequiredMimeDb) return mimeDb; - hasRequiredMimeDb = 1; - /** - * Module exports. - */ - - mimeDb = require$$0$1; - return mimeDb; -} - -var mimeScore; -var hasRequiredMimeScore; - -function requireMimeScore () { - if (hasRequiredMimeScore) return mimeScore; - hasRequiredMimeScore = 1; - // 'mime-score' back-ported to CommonJS - - // Score RFC facets (see https://tools.ietf.org/html/rfc6838#section-3) - var FACET_SCORES = { - 'prs.': 100, - 'x-': 200, - 'x.': 300, - 'vnd.': 400, - default: 900 - }; - - // Score mime source (Logic originally from `jshttp/mime-types` module) - var SOURCE_SCORES = { - nginx: 10, - apache: 20, - iana: 40, - default: 30 // definitions added by `jshttp/mime-db` project? - }; - - var TYPE_SCORES = { - // prefer application/xml over text/xml - // prefer application/rtf over text/rtf - application: 1, - - // prefer font/woff over application/font-woff - font: 2, - - default: 0 - }; - - /** - * Get each component of the score for a mime type. The sum of these is the - * total score. The higher the score, the more "official" the type. - */ - mimeScore = function mimeScore (mimeType, source = 'default') { - if (mimeType === 'application/octet-stream') { - return 0 - } - - const [type, subtype] = mimeType.split('/'); - - const facet = subtype.replace(/(\.|x-).*/, '$1'); - - const facetScore = FACET_SCORES[facet] || FACET_SCORES.default; - const sourceScore = SOURCE_SCORES[source] || SOURCE_SCORES.default; - const typeScore = TYPE_SCORES[type] || TYPE_SCORES.default; - - // All else being equal prefer shorter types - const lengthScore = 1 - mimeType.length / 100; - - return facetScore + sourceScore + typeScore + lengthScore - }; - return mimeScore; -} - -/*! - * mime-types - * Copyright(c) 2014 Jonathan Ong - * Copyright(c) 2015 Douglas Christopher Wilson - * MIT Licensed - */ - -var hasRequiredMimeTypes; - -function requireMimeTypes () { - if (hasRequiredMimeTypes) return mimeTypes; - hasRequiredMimeTypes = 1; - (function (exports) { - - /** - * Module dependencies. - * @private - */ - - var db = requireMimeDb(); - var extname = require$$0$4.extname; - var mimeScore = requireMimeScore(); - - /** - * Module variables. - * @private - */ - - var EXTRACT_TYPE_REGEXP = /^\s*([^;\s]*)(?:;|\s|$)/; - var TEXT_TYPE_REGEXP = /^text\//i; - - /** - * Module exports. - * @public - */ - - exports.charset = charset; - exports.charsets = { lookup: charset }; - exports.contentType = contentType; - exports.extension = extension; - exports.extensions = Object.create(null); - exports.lookup = lookup; - exports.types = Object.create(null); - exports._extensionConflicts = []; - - // Populate the extensions/types maps - populateMaps(exports.extensions, exports.types); - - /** - * Get the default charset for a MIME type. - * - * @param {string} type - * @return {boolean|string} - */ - - function charset (type) { - if (!type || typeof type !== 'string') { - return false - } - - // TODO: use media-typer - var match = EXTRACT_TYPE_REGEXP.exec(type); - var mime = match && db[match[1].toLowerCase()]; - - if (mime && mime.charset) { - return mime.charset - } - - // default text/* to utf-8 - if (match && TEXT_TYPE_REGEXP.test(match[1])) { - return 'UTF-8' - } - - return false - } - - /** - * Create a full Content-Type header given a MIME type or extension. - * - * @param {string} str - * @return {boolean|string} - */ - - function contentType (str) { - // TODO: should this even be in this module? - if (!str || typeof str !== 'string') { - return false - } - - var mime = str.indexOf('/') === -1 ? exports.lookup(str) : str; - - if (!mime) { - return false - } - - // TODO: use content-type or other module - if (mime.indexOf('charset') === -1) { - var charset = exports.charset(mime); - if (charset) mime += '; charset=' + charset.toLowerCase(); - } - - return mime - } - - /** - * Get the default extension for a MIME type. - * - * @param {string} type - * @return {boolean|string} - */ - - function extension (type) { - if (!type || typeof type !== 'string') { - return false - } - - // TODO: use media-typer - var match = EXTRACT_TYPE_REGEXP.exec(type); - - // get extensions - var exts = match && exports.extensions[match[1].toLowerCase()]; - - if (!exts || !exts.length) { - return false - } - - return exts[0] - } - - /** - * Lookup the MIME type for a file path/extension. - * - * @param {string} path - * @return {boolean|string} - */ - - function lookup (path) { - if (!path || typeof path !== 'string') { - return false - } - - // get the extension ("ext" or ".ext" or full path) - var extension = extname('x.' + path) - .toLowerCase() - .slice(1); - - if (!extension) { - return false - } - - return exports.types[extension] || false - } - - /** - * Populate the extensions and types maps. - * @private - */ - - function populateMaps (extensions, types) { - Object.keys(db).forEach(function forEachMimeType (type) { - var mime = db[type]; - var exts = mime.extensions; - - if (!exts || !exts.length) { - return - } - - // mime -> extensions - extensions[type] = exts; - - // extension -> mime - for (var i = 0; i < exts.length; i++) { - var extension = exts[i]; - types[extension] = _preferredType(extension, types[extension], type); - - // DELETE (eventually): Capture extension->type maps that change as a - // result of switching to mime-score. This is just to help make reviewing - // PR #119 easier, and can be removed once that PR is approved. - const legacyType = _preferredTypeLegacy( - extension, - types[extension], - type - ); - if (legacyType !== types[extension]) { - exports._extensionConflicts.push([extension, legacyType, types[extension]]); - } - } - }); - } - - // Resolve type conflict using mime-score - function _preferredType (ext, type0, type1) { - var score0 = type0 ? mimeScore(type0, db[type0].source) : 0; - var score1 = type1 ? mimeScore(type1, db[type1].source) : 0; - - return score0 > score1 ? type0 : type1 - } - - // Resolve type conflict using pre-mime-score logic - function _preferredTypeLegacy (ext, type0, type1) { - var SOURCE_RANK = ['nginx', 'apache', undefined, 'iana']; - - var score0 = type0 ? SOURCE_RANK.indexOf(db[type0].source) : 0; - var score1 = type1 ? SOURCE_RANK.indexOf(db[type1].source) : 0; - - if ( - exports.types[extension] !== 'application/octet-stream' && - (score0 > score1 || - (score0 === score1 && - exports.types[extension]?.slice(0, 12) === 'application/')) - ) { - return type0 - } - - return score0 > score1 ? type0 : type1 - } - } (mimeTypes)); - return mimeTypes; -} - -var onFinished = {exports: {}}; - -/*! - * ee-first - * Copyright(c) 2014 Jonathan Ong - * MIT Licensed - */ - -var eeFirst; -var hasRequiredEeFirst; - -function requireEeFirst () { - if (hasRequiredEeFirst) return eeFirst; - hasRequiredEeFirst = 1; - - /** - * Module exports. - * @public - */ - - eeFirst = first; - - /** - * Get the first event in a set of event emitters and event pairs. - * - * @param {array} stuff - * @param {function} done - * @public - */ - - function first(stuff, done) { - if (!Array.isArray(stuff)) - throw new TypeError('arg must be an array of [ee, events...] arrays') - - var cleanups = []; - - for (var i = 0; i < stuff.length; i++) { - var arr = stuff[i]; - - if (!Array.isArray(arr) || arr.length < 2) - throw new TypeError('each array member must be [ee, events...]') - - var ee = arr[0]; - - for (var j = 1; j < arr.length; j++) { - var event = arr[j]; - var fn = listener(event, callback); - - // listen to the event - ee.on(event, fn); - // push this listener to the list of cleanups - cleanups.push({ - ee: ee, - event: event, - fn: fn, - }); - } - } - - function callback() { - cleanup(); - done.apply(null, arguments); - } - - function cleanup() { - var x; - for (var i = 0; i < cleanups.length; i++) { - x = cleanups[i]; - x.ee.removeListener(x.event, x.fn); - } - } - - function thunk(fn) { - done = fn; - } - - thunk.cancel = cleanup; - - return thunk - } - - /** - * Create the event listener. - * @private - */ - - function listener(event, done) { - return function onevent(arg1) { - var args = new Array(arguments.length); - var ee = this; - var err = event === 'error' - ? arg1 - : null; - - // copy args to prevent arguments escaping scope - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i]; - } - - done(err, ee, event, args); - } - } - return eeFirst; -} - -/*! - * on-finished - * Copyright(c) 2013 Jonathan Ong - * Copyright(c) 2014 Douglas Christopher Wilson - * MIT Licensed - */ - -var hasRequiredOnFinished; - -function requireOnFinished () { - if (hasRequiredOnFinished) return onFinished.exports; - hasRequiredOnFinished = 1; - - /** - * Module exports. - * @public - */ - - onFinished.exports = onFinished$1; - onFinished.exports.isFinished = isFinished; - - /** - * Module dependencies. - * @private - */ - - var asyncHooks = tryRequireAsyncHooks(); - var first = requireEeFirst(); - - /** - * Variables. - * @private - */ - - /* istanbul ignore next */ - var defer = typeof setImmediate === 'function' - ? setImmediate - : function (fn) { process.nextTick(fn.bind.apply(fn, arguments)); }; - - /** - * Invoke callback when the response has finished, useful for - * cleaning up resources afterwards. - * - * @param {object} msg - * @param {function} listener - * @return {object} - * @public - */ - - function onFinished$1 (msg, listener) { - if (isFinished(msg) !== false) { - defer(listener, null, msg); - return msg - } - - // attach the listener to the message - attachListener(msg, wrap(listener)); - - return msg - } - - /** - * Determine if message is already finished. - * - * @param {object} msg - * @return {boolean} - * @public - */ - - function isFinished (msg) { - var socket = msg.socket; - - if (typeof msg.finished === 'boolean') { - // OutgoingMessage - return Boolean(msg.finished || (socket && !socket.writable)) - } - - if (typeof msg.complete === 'boolean') { - // IncomingMessage - return Boolean(msg.upgrade || !socket || !socket.readable || (msg.complete && !msg.readable)) - } - - // don't know - return undefined - } - - /** - * Attach a finished listener to the message. - * - * @param {object} msg - * @param {function} callback - * @private - */ - - function attachFinishedListener (msg, callback) { - var eeMsg; - var eeSocket; - var finished = false; - - function onFinish (error) { - eeMsg.cancel(); - eeSocket.cancel(); - - finished = true; - callback(error); - } - - // finished on first message event - eeMsg = eeSocket = first([[msg, 'end', 'finish']], onFinish); - - function onSocket (socket) { - // remove listener - msg.removeListener('socket', onSocket); - - if (finished) return - if (eeMsg !== eeSocket) return - - // finished on first socket event - eeSocket = first([[socket, 'error', 'close']], onFinish); - } - - if (msg.socket) { - // socket already assigned - onSocket(msg.socket); - return - } - - // wait for socket to be assigned - msg.on('socket', onSocket); - - if (msg.socket === undefined) { - // istanbul ignore next: node.js 0.8 patch - patchAssignSocket(msg, onSocket); - } - } - - /** - * Attach the listener to the message. - * - * @param {object} msg - * @return {function} - * @private - */ - - function attachListener (msg, listener) { - var attached = msg.__onFinished; - - // create a private single listener with queue - if (!attached || !attached.queue) { - attached = msg.__onFinished = createListener(msg); - attachFinishedListener(msg, attached); - } - - attached.queue.push(listener); - } - - /** - * Create listener on message. - * - * @param {object} msg - * @return {function} - * @private - */ - - function createListener (msg) { - function listener (err) { - if (msg.__onFinished === listener) msg.__onFinished = null; - if (!listener.queue) return - - var queue = listener.queue; - listener.queue = null; - - for (var i = 0; i < queue.length; i++) { - queue[i](err, msg); - } - } - - listener.queue = []; - - return listener - } - - /** - * Patch ServerResponse.prototype.assignSocket for node.js 0.8. - * - * @param {ServerResponse} res - * @param {function} callback - * @private - */ - - // istanbul ignore next: node.js 0.8 patch - function patchAssignSocket (res, callback) { - var assignSocket = res.assignSocket; - - if (typeof assignSocket !== 'function') return - - // res.on('socket', callback) is broken in 0.8 - res.assignSocket = function _assignSocket (socket) { - assignSocket.call(this, socket); - callback(socket); - }; - } - - /** - * Try to require async_hooks - * @private - */ - - function tryRequireAsyncHooks () { - try { - return require('async_hooks') - } catch (e) { - return {} - } - } - - /** - * Wrap function with async resource, if possible. - * AsyncResource.bind static method backported. - * @private - */ - - function wrap (fn) { - var res; - - // create anonymous resource - if (asyncHooks.AsyncResource) { - res = new asyncHooks.AsyncResource(fn.name || 'bound-anonymous-fn'); - } - - // incompatible node.js - if (!res || !res.runInAsyncScope) { - return fn - } - - // return bound function - return res.runInAsyncScope.bind(res, fn, null) - } - return onFinished.exports; -} - -/*! - * range-parser - * Copyright(c) 2012-2014 TJ Holowaychuk - * Copyright(c) 2015-2016 Douglas Christopher Wilson - * MIT Licensed - */ - -var rangeParser_1; -var hasRequiredRangeParser; - -function requireRangeParser () { - if (hasRequiredRangeParser) return rangeParser_1; - hasRequiredRangeParser = 1; - - /** - * Module exports. - * @public - */ - - rangeParser_1 = rangeParser; - - /** - * Parse "Range" header `str` relative to the given file `size`. - * - * @param {Number} size - * @param {String} str - * @param {Object} [options] - * @return {Array} - * @public - */ - - function rangeParser (size, str, options) { - if (typeof str !== 'string') { - throw new TypeError('argument str must be a string') - } - - var index = str.indexOf('='); - - if (index === -1) { - return -2 - } - - // split the range string - var arr = str.slice(index + 1).split(','); - var ranges = []; - - // add ranges type - ranges.type = str.slice(0, index); - - // parse all ranges - for (var i = 0; i < arr.length; i++) { - var range = arr[i].split('-'); - var start = parseInt(range[0], 10); - var end = parseInt(range[1], 10); - - // -nnn - if (isNaN(start)) { - start = size - end; - end = size - 1; - // nnn- - } else if (isNaN(end)) { - end = size - 1; - } - - // limit last-byte-pos to current length - if (end > size - 1) { - end = size - 1; - } - - // invalid or unsatisifiable - if (isNaN(start) || isNaN(end) || start > end || start < 0) { - continue - } - - // add range - ranges.push({ - start: start, - end: end - }); - } - - if (ranges.length < 1) { - // unsatisifiable - return -1 - } - - return options && options.combine - ? combineRanges(ranges) - : ranges - } - - /** - * Combine overlapping & adjacent ranges. - * @private - */ - - function combineRanges (ranges) { - var ordered = ranges.map(mapWithIndex).sort(sortByRangeStart); - - for (var j = 0, i = 1; i < ordered.length; i++) { - var range = ordered[i]; - var current = ordered[j]; - - if (range.start > current.end + 1) { - // next range - ordered[++j] = range; - } else if (range.end > current.end) { - // extend range - current.end = range.end; - current.index = Math.min(current.index, range.index); - } - } - - // trim ordered array - ordered.length = j + 1; - - // generate combined range - var combined = ordered.sort(sortByRangeIndex).map(mapWithoutIndex); - - // copy ranges type - combined.type = ranges.type; - - return combined - } - - /** - * Map function to add index value to ranges. - * @private - */ - - function mapWithIndex (range, index) { - return { - start: range.start, - end: range.end, - index: index - } - } - - /** - * Map function to remove index value from ranges. - * @private - */ - - function mapWithoutIndex (range) { - return { - start: range.start, - end: range.end - } - } - - /** - * Sort function to sort ranges by index. - * @private - */ - - function sortByRangeIndex (a, b) { - return a.index - b.index - } - - /** - * Sort function to sort ranges by start position. - * @private - */ - - function sortByRangeStart (a, b) { - return a.start - b.start - } - return rangeParser_1; -} - -const require$$0 = { - "100": "Continue", - "101": "Switching Protocols", - "102": "Processing", - "103": "Early Hints", - "200": "OK", - "201": "Created", - "202": "Accepted", - "203": "Non-Authoritative Information", - "204": "No Content", - "205": "Reset Content", - "206": "Partial Content", - "207": "Multi-Status", - "208": "Already Reported", - "226": "IM Used", - "300": "Multiple Choices", - "301": "Moved Permanently", - "302": "Found", - "303": "See Other", - "304": "Not Modified", - "305": "Use Proxy", - "307": "Temporary Redirect", - "308": "Permanent Redirect", - "400": "Bad Request", - "401": "Unauthorized", - "402": "Payment Required", - "403": "Forbidden", - "404": "Not Found", - "405": "Method Not Allowed", - "406": "Not Acceptable", - "407": "Proxy Authentication Required", - "408": "Request Timeout", - "409": "Conflict", - "410": "Gone", - "411": "Length Required", - "412": "Precondition Failed", - "413": "Payload Too Large", - "414": "URI Too Long", - "415": "Unsupported Media Type", - "416": "Range Not Satisfiable", - "417": "Expectation Failed", - "418": "I'm a Teapot", - "421": "Misdirected Request", - "422": "Unprocessable Entity", - "423": "Locked", - "424": "Failed Dependency", - "425": "Too Early", - "426": "Upgrade Required", - "428": "Precondition Required", - "429": "Too Many Requests", - "431": "Request Header Fields Too Large", - "451": "Unavailable For Legal Reasons", - "500": "Internal Server Error", - "501": "Not Implemented", - "502": "Bad Gateway", - "503": "Service Unavailable", - "504": "Gateway Timeout", - "505": "HTTP Version Not Supported", - "506": "Variant Also Negotiates", - "507": "Insufficient Storage", - "508": "Loop Detected", - "509": "Bandwidth Limit Exceeded", - "510": "Not Extended", - "511": "Network Authentication Required", -}; - -/*! - * statuses - * Copyright(c) 2014 Jonathan Ong - * Copyright(c) 2016 Douglas Christopher Wilson - * MIT Licensed - */ - -var statuses; -var hasRequiredStatuses; - -function requireStatuses () { - if (hasRequiredStatuses) return statuses; - hasRequiredStatuses = 1; - - /** - * Module dependencies. - * @private - */ - - var codes = require$$0; - - /** - * Module exports. - * @public - */ - - statuses = status; - - // status code to message map - status.message = codes; - - // status message (lower-case) to code map - status.code = createMessageToStatusCodeMap(codes); - - // array of status codes - status.codes = createStatusCodeList(codes); - - // status codes for redirects - status.redirect = { - 300: true, - 301: true, - 302: true, - 303: true, - 305: true, - 307: true, - 308: true - }; - - // status codes for empty bodies - status.empty = { - 204: true, - 205: true, - 304: true - }; - - // status codes for when you should retry the request - status.retry = { - 502: true, - 503: true, - 504: true - }; - - /** - * Create a map of message to status code. - * @private - */ - - function createMessageToStatusCodeMap (codes) { - var map = {}; - - Object.keys(codes).forEach(function forEachCode (code) { - var message = codes[code]; - var status = Number(code); - - // populate map - map[message.toLowerCase()] = status; - }); - - return map - } - - /** - * Create a list of all status codes. - * @private - */ - - function createStatusCodeList (codes) { - return Object.keys(codes).map(function mapCode (code) { - return Number(code) - }) - } - - /** - * Get the status code for given message. - * @private - */ - - function getStatusCode (message) { - var msg = message.toLowerCase(); - - if (!Object.prototype.hasOwnProperty.call(status.code, msg)) { - throw new Error('invalid status message: "' + message + '"') - } - - return status.code[msg] - } - - /** - * Get the status message for given code. - * @private - */ - - function getStatusMessage (code) { - if (!Object.prototype.hasOwnProperty.call(status.message, code)) { - throw new Error('invalid status code: ' + code) - } - - return status.message[code] - } - - /** - * Get the status code. - * - * Given a number, this will throw if it is not a known status - * code, otherwise the code will be returned. Given a string, - * the string will be parsed for a number and return the code - * if valid, otherwise will lookup the code assuming this is - * the status message. - * - * @param {string|number} code - * @returns {number} - * @public - */ - - function status (code) { - if (typeof code === 'number') { - return getStatusMessage(code) - } - - if (typeof code !== 'string') { - throw new TypeError('code must be a number or string') - } - - // '403' - var n = parseInt(code, 10); - if (!isNaN(n)) { - return getStatusMessage(n) - } - - return getStatusCode(code) - } - return statuses; -} - -/*! - * send - * Copyright(c) 2012 TJ Holowaychuk - * Copyright(c) 2014-2022 Douglas Christopher Wilson - * MIT Licensed - */ - -var send_1; -var hasRequiredSend; - -function requireSend () { - if (hasRequiredSend) return send_1; - hasRequiredSend = 1; - - /** - * Module dependencies. - * @private - */ - - var createError = requireHttpErrors(); - var debug = debug$1('send'); - var encodeUrl = requireEncodeurl(); - var escapeHtml = requireEscapeHtml(); - var etag = requireEtag(); - var fresh = requireFresh(); - var fs = require$$0$5; - var mime = requireMimeTypes(); - var ms$1 = ms; - var onFinished = requireOnFinished(); - var parseRange = requireRangeParser(); - var path = require$$0$4; - var statuses = requireStatuses(); - var Stream = require$$13; - var util = require$$14; - - /** - * Path function references. - * @private - */ - - var extname = path.extname; - var join = path.join; - var normalize = path.normalize; - var resolve = path.resolve; - var sep = path.sep; - - /** - * Regular expression for identifying a bytes Range header. - * @private - */ - - var BYTES_RANGE_REGEXP = /^ *bytes=/; - - /** - * Maximum value allowed for the max age. - * @private - */ - - var MAX_MAXAGE = 60 * 60 * 24 * 365 * 1000; // 1 year - - /** - * Regular expression to match a path with a directory up component. - * @private - */ - - var UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/; - - /** - * Module exports. - * @public - */ - - send_1 = send; - - /** - * Return a `SendStream` for `req` and `path`. - * - * @param {object} req - * @param {string} path - * @param {object} [options] - * @return {SendStream} - * @public - */ - - function send (req, path, options) { - return new SendStream(req, path, options) - } - - /** - * Initialize a `SendStream` with the given `path`. - * - * @param {Request} req - * @param {String} path - * @param {object} [options] - * @private - */ - - function SendStream (req, path, options) { - Stream.call(this); - - var opts = options || {}; - - this.options = opts; - this.path = path; - this.req = req; - - this._acceptRanges = opts.acceptRanges !== undefined - ? Boolean(opts.acceptRanges) - : true; - - this._cacheControl = opts.cacheControl !== undefined - ? Boolean(opts.cacheControl) - : true; - - this._etag = opts.etag !== undefined - ? Boolean(opts.etag) - : true; - - this._dotfiles = opts.dotfiles !== undefined - ? opts.dotfiles - : 'ignore'; - - if (this._dotfiles !== 'ignore' && this._dotfiles !== 'allow' && this._dotfiles !== 'deny') { - throw new TypeError('dotfiles option must be "allow", "deny", or "ignore"') - } - - this._extensions = opts.extensions !== undefined - ? normalizeList(opts.extensions, 'extensions option') - : []; - - this._immutable = opts.immutable !== undefined - ? Boolean(opts.immutable) - : false; - - this._index = opts.index !== undefined - ? normalizeList(opts.index, 'index option') - : ['index.html']; - - this._lastModified = opts.lastModified !== undefined - ? Boolean(opts.lastModified) - : true; - - this._maxage = opts.maxAge || opts.maxage; - this._maxage = typeof this._maxage === 'string' - ? ms$1(this._maxage) - : Number(this._maxage); - this._maxage = !isNaN(this._maxage) - ? Math.min(Math.max(0, this._maxage), MAX_MAXAGE) - : 0; - - this._root = opts.root - ? resolve(opts.root) - : null; - } - - /** - * Inherits from `Stream`. - */ - - util.inherits(SendStream, Stream); - - /** - * Emit error with `status`. - * - * @param {number} status - * @param {Error} [err] - * @private - */ - - SendStream.prototype.error = function error (status, err) { - // emit if listeners instead of responding - if (hasListeners(this, 'error')) { - return this.emit('error', createHttpError(status, err)) - } - - var res = this.res; - var msg = statuses.message[status] || String(status); - var doc = createHtmlDocument('Error', escapeHtml(msg)); - - // clear existing headers - clearHeaders(res); - - // add error headers - if (err && err.headers) { - setHeaders(res, err.headers); - } - - // send basic response - res.statusCode = status; - res.setHeader('Content-Type', 'text/html; charset=UTF-8'); - res.setHeader('Content-Length', Buffer.byteLength(doc)); - res.setHeader('Content-Security-Policy', "default-src 'none'"); - res.setHeader('X-Content-Type-Options', 'nosniff'); - res.end(doc); - }; - - /** - * Check if the pathname ends with "/". - * - * @return {boolean} - * @private - */ - - SendStream.prototype.hasTrailingSlash = function hasTrailingSlash () { - return this.path[this.path.length - 1] === '/' - }; - - /** - * Check if this is a conditional GET request. - * - * @return {Boolean} - * @api private - */ - - SendStream.prototype.isConditionalGET = function isConditionalGET () { - return this.req.headers['if-match'] || - this.req.headers['if-unmodified-since'] || - this.req.headers['if-none-match'] || - this.req.headers['if-modified-since'] - }; - - /** - * Check if the request preconditions failed. - * - * @return {boolean} - * @private - */ - - SendStream.prototype.isPreconditionFailure = function isPreconditionFailure () { - var req = this.req; - var res = this.res; - - // if-match - var match = req.headers['if-match']; - if (match) { - var etag = res.getHeader('ETag'); - return !etag || (match !== '*' && parseTokenList(match).every(function (match) { - return match !== etag && match !== 'W/' + etag && 'W/' + match !== etag - })) - } - - // if-unmodified-since - var unmodifiedSince = parseHttpDate(req.headers['if-unmodified-since']); - if (!isNaN(unmodifiedSince)) { - var lastModified = parseHttpDate(res.getHeader('Last-Modified')); - return isNaN(lastModified) || lastModified > unmodifiedSince - } - - return false - }; - - /** - * Strip various content header fields for a change in entity. - * - * @private - */ - - SendStream.prototype.removeContentHeaderFields = function removeContentHeaderFields () { - var res = this.res; - - res.removeHeader('Content-Encoding'); - res.removeHeader('Content-Language'); - res.removeHeader('Content-Length'); - res.removeHeader('Content-Range'); - res.removeHeader('Content-Type'); - }; - - /** - * Respond with 304 not modified. - * - * @api private - */ - - SendStream.prototype.notModified = function notModified () { - var res = this.res; - debug('not modified'); - this.removeContentHeaderFields(); - res.statusCode = 304; - res.end(); - }; - - /** - * Raise error that headers already sent. - * - * @api private - */ - - SendStream.prototype.headersAlreadySent = function headersAlreadySent () { - var err = new Error('Can\'t set headers after they are sent.'); - debug('headers already sent'); - this.error(500, err); - }; - - /** - * Check if the request is cacheable, aka - * responded with 2xx or 304 (see RFC 2616 section 14.2{5,6}). - * - * @return {Boolean} - * @api private - */ - - SendStream.prototype.isCachable = function isCachable () { - var statusCode = this.res.statusCode; - return (statusCode >= 200 && statusCode < 300) || - statusCode === 304 - }; - - /** - * Handle stat() error. - * - * @param {Error} error - * @private - */ - - SendStream.prototype.onStatError = function onStatError (error) { - switch (error.code) { - case 'ENAMETOOLONG': - case 'ENOENT': - case 'ENOTDIR': - this.error(404, error); - break - default: - this.error(500, error); - break - } - }; - - /** - * Check if the cache is fresh. - * - * @return {Boolean} - * @api private - */ - - SendStream.prototype.isFresh = function isFresh () { - return fresh(this.req.headers, { - etag: this.res.getHeader('ETag'), - 'last-modified': this.res.getHeader('Last-Modified') - }) - }; - - /** - * Check if the range is fresh. - * - * @return {Boolean} - * @api private - */ - - SendStream.prototype.isRangeFresh = function isRangeFresh () { - var ifRange = this.req.headers['if-range']; - - if (!ifRange) { - return true - } - - // if-range as etag - if (ifRange.indexOf('"') !== -1) { - var etag = this.res.getHeader('ETag'); - return Boolean(etag && ifRange.indexOf(etag) !== -1) - } - - // if-range as modified date - var lastModified = this.res.getHeader('Last-Modified'); - return parseHttpDate(lastModified) <= parseHttpDate(ifRange) - }; - - /** - * Redirect to path. - * - * @param {string} path - * @private - */ - - SendStream.prototype.redirect = function redirect (path) { - var res = this.res; - - if (hasListeners(this, 'directory')) { - this.emit('directory', res, path); - return - } - - if (this.hasTrailingSlash()) { - this.error(403); - return - } - - var loc = encodeUrl(collapseLeadingSlashes(this.path + '/')); - var doc = createHtmlDocument('Redirecting', 'Redirecting to ' + escapeHtml(loc)); - - // redirect - res.statusCode = 301; - res.setHeader('Content-Type', 'text/html; charset=UTF-8'); - res.setHeader('Content-Length', Buffer.byteLength(doc)); - res.setHeader('Content-Security-Policy', "default-src 'none'"); - res.setHeader('X-Content-Type-Options', 'nosniff'); - res.setHeader('Location', loc); - res.end(doc); - }; - - /** - * Pipe to `res. - * - * @param {Stream} res - * @return {Stream} res - * @api public - */ - - SendStream.prototype.pipe = function pipe (res) { - // root path - var root = this._root; - - // references - this.res = res; - - // decode the path - var path = decode(this.path); - if (path === -1) { - this.error(400); - return res - } - - // null byte(s) - if (~path.indexOf('\0')) { - this.error(400); - return res - } - - var parts; - if (root !== null) { - // normalize - if (path) { - path = normalize('.' + sep + path); - } - - // malicious path - if (UP_PATH_REGEXP.test(path)) { - debug('malicious path "%s"', path); - this.error(403); - return res - } - - // explode path parts - parts = path.split(sep); - - // join / normalize from optional root dir - path = normalize(join(root, path)); - } else { - // ".." is malicious without "root" - if (UP_PATH_REGEXP.test(path)) { - debug('malicious path "%s"', path); - this.error(403); - return res - } - - // explode path parts - parts = normalize(path).split(sep); - - // resolve the path - path = resolve(path); - } - - // dotfile handling - if (containsDotFile(parts)) { - debug('%s dotfile "%s"', this._dotfiles, path); - switch (this._dotfiles) { - case 'allow': - break - case 'deny': - this.error(403); - return res - case 'ignore': - default: - this.error(404); - return res - } - } - - // index file support - if (this._index.length && this.hasTrailingSlash()) { - this.sendIndex(path); - return res - } - - this.sendFile(path); - return res - }; - - /** - * Transfer `path`. - * - * @param {String} path - * @api public - */ - - SendStream.prototype.send = function send (path, stat) { - var len = stat.size; - var options = this.options; - var opts = {}; - var res = this.res; - var req = this.req; - var ranges = req.headers.range; - var offset = options.start || 0; - - if (res.headersSent) { - // impossible to send now - this.headersAlreadySent(); - return - } - - debug('pipe "%s"', path); - - // set header fields - this.setHeader(path, stat); - - // set content-type - this.type(path); - - // conditional GET support - if (this.isConditionalGET()) { - if (this.isPreconditionFailure()) { - this.error(412); - return - } - - if (this.isCachable() && this.isFresh()) { - this.notModified(); - return - } - } - - // adjust len to start/end options - len = Math.max(0, len - offset); - if (options.end !== undefined) { - var bytes = options.end - offset + 1; - if (len > bytes) len = bytes; - } - - // Range support - if (this._acceptRanges && BYTES_RANGE_REGEXP.test(ranges)) { - // parse - ranges = parseRange(len, ranges, { - combine: true - }); - - // If-Range support - if (!this.isRangeFresh()) { - debug('range stale'); - ranges = -2; - } - - // unsatisfiable - if (ranges === -1) { - debug('range unsatisfiable'); - - // Content-Range - res.setHeader('Content-Range', contentRange('bytes', len)); - - // 416 Requested Range Not Satisfiable - return this.error(416, { - headers: { 'Content-Range': res.getHeader('Content-Range') } - }) - } - - // valid (syntactically invalid/multiple ranges are treated as a regular response) - if (ranges !== -2 && ranges.length === 1) { - debug('range %j', ranges); - - // Content-Range - res.statusCode = 206; - res.setHeader('Content-Range', contentRange('bytes', len, ranges[0])); - - // adjust for requested range - offset += ranges[0].start; - len = ranges[0].end - ranges[0].start + 1; - } - } - - // clone options - for (var prop in options) { - opts[prop] = options[prop]; - } - - // set read options - opts.start = offset; - opts.end = Math.max(offset, offset + len - 1); - - // content-length - res.setHeader('Content-Length', len); - - // HEAD support - if (req.method === 'HEAD') { - res.end(); - return - } - - this.stream(path, opts); - }; - - /** - * Transfer file for `path`. - * - * @param {String} path - * @api private - */ - SendStream.prototype.sendFile = function sendFile (path) { - var i = 0; - var self = this; - - debug('stat "%s"', path); - fs.stat(path, function onstat (err, stat) { - var pathEndsWithSep = path[path.length - 1] === sep; - if (err && err.code === 'ENOENT' && !extname(path) && !pathEndsWithSep) { - // not found, check extensions - return next(err) - } - if (err) return self.onStatError(err) - if (stat.isDirectory()) return self.redirect(path) - if (pathEndsWithSep) return self.error(404) - self.emit('file', path, stat); - self.send(path, stat); - }); - - function next (err) { - if (self._extensions.length <= i) { - return err - ? self.onStatError(err) - : self.error(404) - } - - var p = path + '.' + self._extensions[i++]; - - debug('stat "%s"', p); - fs.stat(p, function (err, stat) { - if (err) return next(err) - if (stat.isDirectory()) return next() - self.emit('file', p, stat); - self.send(p, stat); - }); - } - }; - - /** - * Transfer index for `path`. - * - * @param {String} path - * @api private - */ - SendStream.prototype.sendIndex = function sendIndex (path) { - var i = -1; - var self = this; - - function next (err) { - if (++i >= self._index.length) { - if (err) return self.onStatError(err) - return self.error(404) - } - - var p = join(path, self._index[i]); - - debug('stat "%s"', p); - fs.stat(p, function (err, stat) { - if (err) return next(err) - if (stat.isDirectory()) return next() - self.emit('file', p, stat); - self.send(p, stat); - }); - } - - next(); - }; - - /** - * Stream `path` to the response. - * - * @param {String} path - * @param {Object} options - * @api private - */ - - SendStream.prototype.stream = function stream (path, options) { - var self = this; - var res = this.res; - - // pipe - var stream = fs.createReadStream(path, options); - this.emit('stream', stream); - stream.pipe(res); - - // cleanup - function cleanup () { - stream.destroy(); - } - - // response finished, cleanup - onFinished(res, cleanup); - - // error handling - stream.on('error', function onerror (err) { - // clean up stream early - cleanup(); - - // error - self.onStatError(err); - }); - - // end - stream.on('end', function onend () { - self.emit('end'); - }); - }; - - /** - * Set content-type based on `path` - * if it hasn't been explicitly set. - * - * @param {String} path - * @api private - */ - - SendStream.prototype.type = function type (path) { - var res = this.res; - - if (res.getHeader('Content-Type')) return - - var ext = extname(path); - var type = mime.contentType(ext) || 'application/octet-stream'; - - debug('content-type %s', type); - res.setHeader('Content-Type', type); - }; - - /** - * Set response header fields, most - * fields may be pre-defined. - * - * @param {String} path - * @param {Object} stat - * @api private - */ - - SendStream.prototype.setHeader = function setHeader (path, stat) { - var res = this.res; - - this.emit('headers', res, path, stat); - - if (this._acceptRanges && !res.getHeader('Accept-Ranges')) { - debug('accept ranges'); - res.setHeader('Accept-Ranges', 'bytes'); - } - - if (this._cacheControl && !res.getHeader('Cache-Control')) { - var cacheControl = 'public, max-age=' + Math.floor(this._maxage / 1000); - - if (this._immutable) { - cacheControl += ', immutable'; - } - - debug('cache-control %s', cacheControl); - res.setHeader('Cache-Control', cacheControl); - } - - if (this._lastModified && !res.getHeader('Last-Modified')) { - var modified = stat.mtime.toUTCString(); - debug('modified %s', modified); - res.setHeader('Last-Modified', modified); - } - - if (this._etag && !res.getHeader('ETag')) { - var val = etag(stat); - debug('etag %s', val); - res.setHeader('ETag', val); - } - }; - - /** - * Clear all headers from a response. - * - * @param {object} res - * @private - */ - - function clearHeaders (res) { - for (const header of res.getHeaderNames()) { - res.removeHeader(header); - } - } - - /** - * Collapse all leading slashes into a single slash - * - * @param {string} str - * @private - */ - function collapseLeadingSlashes (str) { - for (var i = 0; i < str.length; i++) { - if (str[i] !== '/') { - break - } - } - - return i > 1 - ? '/' + str.substr(i) - : str - } - - /** - * Determine if path parts contain a dotfile. - * - * @api private - */ - - function containsDotFile (parts) { - for (var i = 0; i < parts.length; i++) { - var part = parts[i]; - if (part.length > 1 && part[0] === '.') { - return true - } - } - - return false - } - - /** - * Create a Content-Range header. - * - * @param {string} type - * @param {number} size - * @param {array} [range] - */ - - function contentRange (type, size, range) { - return type + ' ' + (range ? range.start + '-' + range.end : '*') + '/' + size - } - - /** - * Create a minimal HTML document. - * - * @param {string} title - * @param {string} body - * @private - */ - - function createHtmlDocument (title, body) { - return '\n' + - '\n' + - '\n' + - '\n' + - '' + title + '\n' + - '\n' + - '\n' + - '
' + body + '
\n' + - '\n' + - '\n' - } - - /** - * Create a HttpError object from simple arguments. - * - * @param {number} status - * @param {Error|object} err - * @private - */ - - function createHttpError (status, err) { - if (!err) { - return createError(status) - } - - return err instanceof Error - ? createError(status, err, { expose: false }) - : createError(status, err) - } - - /** - * decodeURIComponent. - * - * Allows V8 to only deoptimize this fn instead of all - * of send(). - * - * @param {String} path - * @api private - */ - - function decode (path) { - try { - return decodeURIComponent(path) - } catch (err) { - return -1 - } - } - - /** - * Determine if emitter has listeners of a given type. - * - * The way to do this check is done three different ways in Node.js >= 0.10 - * so this consolidates them into a minimal set using instance methods. - * - * @param {EventEmitter} emitter - * @param {string} type - * @returns {boolean} - * @private - */ - - function hasListeners (emitter, type) { - var count = typeof emitter.listenerCount !== 'function' - ? emitter.listeners(type).length - : emitter.listenerCount(type); - - return count > 0 - } - - /** - * Normalize the index option into an array. - * - * @param {boolean|string|array} val - * @param {string} name - * @private - */ - - function normalizeList (val, name) { - var list = [].concat(val || []); - - for (var i = 0; i < list.length; i++) { - if (typeof list[i] !== 'string') { - throw new TypeError(name + ' must be array of strings or false') - } - } - - return list - } - - /** - * Parse an HTTP Date into a number. - * - * @param {string} date - * @private - */ - - function parseHttpDate (date) { - var timestamp = date && Date.parse(date); - - return typeof timestamp === 'number' - ? timestamp - : NaN - } - - /** - * Parse a HTTP token list. - * - * @param {string} str - * @private - */ - - function parseTokenList (str) { - var end = 0; - var list = []; - var start = 0; - - // gather tokens - for (var i = 0, len = str.length; i < len; i++) { - switch (str.charCodeAt(i)) { - case 0x20: /* */ - if (start === end) { - start = end = i + 1; - } - break - case 0x2c: /* , */ - if (start !== end) { - list.push(str.substring(start, end)); - } - start = end = i + 1; - break - default: - end = i + 1; - break - } - } - - // final token - if (start !== end) { - list.push(str.substring(start, end)); - } - - return list - } - - /** - * Set an object of headers on a response. - * - * @param {object} res - * @param {object} headers - * @private - */ - - function setHeaders (res, headers) { - var keys = Object.keys(headers); - - for (var i = 0; i < keys.length; i++) { - var key = keys[i]; - res.setHeader(key, headers[key]); - } - } - return send_1; -} - -var sendExports = requireSend(); -const send = /*@__PURE__*/getDefaultExportFromCjs(sendExports); - -function createStaticHandler(app, options) { - const client = resolveClientDir(options); - return (req, res, ssr) => { - if (req.url) { - const [urlPath, urlQuery] = req.url.split("?"); - const filePath = path.join(client, app.removeBase(urlPath)); - let isDirectory = false; - try { - isDirectory = fs.lstatSync(filePath).isDirectory(); - } catch { - } - const { trailingSlash = "ignore" } = options; - const hasSlash = urlPath.endsWith("/"); - let pathname = urlPath; - if (app.headersMap && app.headersMap.length > 0) { - const routeData = app.match(req, true); - if (routeData && routeData.prerender) { - const matchedRoute = app.headersMap.find((header) => header.pathname.includes(pathname)); - if (matchedRoute) { - for (const header of matchedRoute.headers) { - res.setHeader(header.key, header.value); - } - } - } - } - switch (trailingSlash) { - case "never": { - if (isDirectory && urlPath !== "/" && hasSlash) { - pathname = urlPath.slice(0, -1) + (urlQuery ? "?" + urlQuery : ""); - res.statusCode = 301; - res.setHeader("Location", pathname); - return res.end(); - } - if (isDirectory && !hasSlash) { - pathname = `${urlPath}/index.html`; - } - break; - } - case "ignore": { - if (isDirectory && !hasSlash) { - pathname = `${urlPath}/index.html`; - } - break; - } - case "always": { - if (!hasSlash && !hasFileExtension(urlPath) && !isInternalPath(urlPath)) { - pathname = urlPath + "/" + (urlQuery ? "?" + urlQuery : ""); - res.statusCode = 301; - res.setHeader("Location", pathname); - return res.end(); - } - break; - } - } - pathname = prependForwardSlash(app.removeBase(pathname)); - const stream = send(req, pathname, { - root: client, - dotfiles: pathname.startsWith("/.well-known/") ? "allow" : "deny" - }); - let forwardError = false; - stream.on("error", (err) => { - if (forwardError) { - console.error(err.toString()); - res.writeHead(500); - res.end("Internal server error"); - return; - } - ssr(); - }); - stream.on("headers", (_res) => { - if (pathname.startsWith(`/${options.assets}/`)) { - _res.setHeader("Cache-Control", "public, max-age=31536000, immutable"); - } - }); - stream.on("file", () => { - forwardError = true; - }); - stream.pipe(res); - } else { - ssr(); - } - }; -} -function resolveClientDir(options) { - const clientURLRaw = new URL(options.client); - const serverURLRaw = new URL(options.server); - const rel = path.relative(url.fileURLToPath(serverURLRaw), url.fileURLToPath(clientURLRaw)); - const serverFolder = path.basename(options.server); - let serverEntryFolderURL = path.dirname(import.meta.url); - while (!serverEntryFolderURL.endsWith(serverFolder)) { - serverEntryFolderURL = path.dirname(serverEntryFolderURL); - } - const serverEntryURL = serverEntryFolderURL + "/entry.mjs"; - const clientURL = new URL(appendForwardSlash(rel), serverEntryURL); - const client = url.fileURLToPath(clientURL); - return client; -} -function prependForwardSlash(pth) { - return pth.startsWith("/") ? pth : "/" + pth; -} -function appendForwardSlash(pth) { - return pth.endsWith("/") ? pth : pth + "/"; -} - -const hostOptions = (host) => { - if (typeof host === "boolean") { - return host ? "0.0.0.0" : "localhost"; - } - return host; -}; -function standalone(app, options) { - const port = process.env.PORT ? Number(process.env.PORT) : options.port ?? 8080; - const host = process.env.HOST ?? hostOptions(options.host); - const handler = createStandaloneHandler(app, options); - const server = createServer(handler, host, port); - server.server.listen(port, host); - if (process.env.ASTRO_NODE_LOGGING !== "disabled") { - logListeningOn(app.getAdapterLogger(), server.server, host); - } - return { - server, - done: server.closed() - }; -} -function createStandaloneHandler(app, options) { - const appHandler = createAppHandler(app, options); - const staticHandler = createStaticHandler(app, options); - return (req, res) => { - try { - decodeURI(req.url); - } catch { - res.writeHead(400); - res.end("Bad request."); - return; - } - staticHandler(req, res, () => appHandler(req, res)); - }; -} -function createServer(listener, host, port) { - let httpServer; - if (process.env.SERVER_CERT_PATH && process.env.SERVER_KEY_PATH) { - httpServer = https.createServer( - { - key: fs.readFileSync(process.env.SERVER_KEY_PATH), - cert: fs.readFileSync(process.env.SERVER_CERT_PATH) - }, - listener - ); - } else { - httpServer = require$$2.createServer(listener); - } - enableDestroy(httpServer); - const closed = new Promise((resolve, reject) => { - httpServer.addListener("close", resolve); - httpServer.addListener("error", reject); - }); - const previewable = { - host, - port, - closed() { - return closed; - }, - async stop() { - await new Promise((resolve, reject) => { - httpServer.destroy((err) => err ? reject(err) : resolve(void 0)); - }); - } - }; - return { - server: httpServer, - ...previewable - }; -} - -function createExports(manifest, options) { - const app = new NodeApp(manifest, !options.experimentalDisableStreaming); - let headersMap = void 0; - if (options.experimentalStaticHeaders) { - headersMap = readHeadersJson(manifest.outDir); - } - if (headersMap) { - app.setHeadersMap(headersMap); - } - options.trailingSlash = manifest.trailingSlash; - return { - options, - handler: options.mode === "middleware" ? createMiddleware(app, options) : createStandaloneHandler(app, options), - startServer: () => standalone(app, options) - }; -} -function start(manifest, options) { - if (options.mode !== "standalone" || process.env.ASTRO_NODE_AUTOSTART === "disabled") { - return; - } - let headersMap = void 0; - if (options.experimentalStaticHeaders) { - headersMap = readHeadersJson(manifest.outDir); - } - const app = new NodeApp(manifest, !options.experimentalDisableStreaming); - if (headersMap) { - app.setHeadersMap(headersMap); - } - standalone(app, options); -} -function readHeadersJson(outDir) { - let headersMap = void 0; - const headersUrl = new URL(STATIC_HEADERS_FILE, outDir); - if (existsSync(headersUrl)) { - const content = readFileSync(headersUrl, "utf-8"); - try { - headersMap = JSON.parse(content); - } catch (e) { - console.error("[@astrojs/node] Error parsing _headers.json: " + e.message); - console.error("[@astrojs/node] Please make sure your _headers.json is valid JSON."); - } - } - return headersMap; -} - -const serverEntrypointModule = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - createExports, - start -}, Symbol.toStringTag, { value: 'Module' })); - -export { start as a, createExports as c, serverEntrypointModule as s }; diff --git a/workbench/astro/dist/server/chunks/_commonjsHelpers_BFTU3MAI.mjs b/workbench/astro/dist/server/chunks/_commonjsHelpers_BFTU3MAI.mjs deleted file mode 100644 index 004412e51..000000000 --- a/workbench/astro/dist/server/chunks/_commonjsHelpers_BFTU3MAI.mjs +++ /dev/null @@ -1,7 +0,0 @@ -var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; - -function getDefaultExportFromCjs (x) { - return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; -} - -export { commonjsGlobal as c, getDefaultExportFromCjs as g }; diff --git a/workbench/astro/dist/server/chunks/astro-designed-error-pages_pFA87nEA.mjs b/workbench/astro/dist/server/chunks/astro-designed-error-pages_pFA87nEA.mjs deleted file mode 100644 index 1510a1eb0..000000000 --- a/workbench/astro/dist/server/chunks/astro-designed-error-pages_pFA87nEA.mjs +++ /dev/null @@ -1,364 +0,0 @@ -import { ai as NOOP_MIDDLEWARE_HEADER, aj as REDIRECT_STATUS_CODES, A as AstroError, ak as ActionsReturnedInvalidDataError, Q as DEFAULT_404_COMPONENT } from './astro/server_DhWKww_t.mjs'; -import { parse, stringify } from 'devalue'; -import { escape } from 'html-escaper'; - -const NOOP_MIDDLEWARE_FN = async (_ctx, next) => { - const response = await next(); - response.headers.set(NOOP_MIDDLEWARE_HEADER, "true"); - return response; -}; - -const ACTION_QUERY_PARAMS$1 = { - actionName: "_action"}; -const ACTION_RPC_ROUTE_PATTERN = "/_actions/[...path]"; - -const __vite_import_meta_env__ = {"ASSETS_PREFIX": undefined, "BASE_URL": "/", "DEV": false, "MODE": "production", "PROD": true, "SITE": undefined, "SSR": true}; -const ACTION_QUERY_PARAMS = ACTION_QUERY_PARAMS$1; -const codeToStatusMap = { - // Implemented from IANA HTTP Status Code Registry - // https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml - BAD_REQUEST: 400, - UNAUTHORIZED: 401, - PAYMENT_REQUIRED: 402, - FORBIDDEN: 403, - NOT_FOUND: 404, - METHOD_NOT_ALLOWED: 405, - NOT_ACCEPTABLE: 406, - PROXY_AUTHENTICATION_REQUIRED: 407, - REQUEST_TIMEOUT: 408, - CONFLICT: 409, - GONE: 410, - LENGTH_REQUIRED: 411, - PRECONDITION_FAILED: 412, - CONTENT_TOO_LARGE: 413, - URI_TOO_LONG: 414, - UNSUPPORTED_MEDIA_TYPE: 415, - RANGE_NOT_SATISFIABLE: 416, - EXPECTATION_FAILED: 417, - MISDIRECTED_REQUEST: 421, - UNPROCESSABLE_CONTENT: 422, - LOCKED: 423, - FAILED_DEPENDENCY: 424, - TOO_EARLY: 425, - UPGRADE_REQUIRED: 426, - PRECONDITION_REQUIRED: 428, - TOO_MANY_REQUESTS: 429, - REQUEST_HEADER_FIELDS_TOO_LARGE: 431, - UNAVAILABLE_FOR_LEGAL_REASONS: 451, - INTERNAL_SERVER_ERROR: 500, - NOT_IMPLEMENTED: 501, - BAD_GATEWAY: 502, - SERVICE_UNAVAILABLE: 503, - GATEWAY_TIMEOUT: 504, - HTTP_VERSION_NOT_SUPPORTED: 505, - VARIANT_ALSO_NEGOTIATES: 506, - INSUFFICIENT_STORAGE: 507, - LOOP_DETECTED: 508, - NETWORK_AUTHENTICATION_REQUIRED: 511 -}; -const statusToCodeMap = Object.entries(codeToStatusMap).reduce( - // reverse the key-value pairs - (acc, [key, value]) => ({ ...acc, [value]: key }), - {} -); -class ActionError extends Error { - type = "AstroActionError"; - code = "INTERNAL_SERVER_ERROR"; - status = 500; - constructor(params) { - super(params.message); - this.code = params.code; - this.status = ActionError.codeToStatus(params.code); - if (params.stack) { - this.stack = params.stack; - } - } - static codeToStatus(code) { - return codeToStatusMap[code]; - } - static statusToCode(status) { - return statusToCodeMap[status] ?? "INTERNAL_SERVER_ERROR"; - } - static fromJson(body) { - if (isInputError(body)) { - return new ActionInputError(body.issues); - } - if (isActionError(body)) { - return new ActionError(body); - } - return new ActionError({ - code: "INTERNAL_SERVER_ERROR" - }); - } -} -function isActionError(error) { - return typeof error === "object" && error != null && "type" in error && error.type === "AstroActionError"; -} -function isInputError(error) { - return typeof error === "object" && error != null && "type" in error && error.type === "AstroActionInputError" && "issues" in error && Array.isArray(error.issues); -} -class ActionInputError extends ActionError { - type = "AstroActionInputError"; - // We don't expose all ZodError properties. - // Not all properties will serialize from server to client, - // and we don't want to import the full ZodError object into the client. - issues; - fields; - constructor(issues) { - super({ - message: `Failed to validate: ${JSON.stringify(issues, null, 2)}`, - code: "BAD_REQUEST" - }); - this.issues = issues; - this.fields = {}; - for (const issue of issues) { - if (issue.path.length > 0) { - const key = issue.path[0].toString(); - this.fields[key] ??= []; - this.fields[key]?.push(issue.message); - } - } - } -} -function getActionQueryString(name) { - const searchParams = new URLSearchParams({ [ACTION_QUERY_PARAMS$1.actionName]: name }); - return `?${searchParams.toString()}`; -} -function serializeActionResult(res) { - if (res.error) { - if (Object.assign(__vite_import_meta_env__, {})?.DEV) { - actionResultErrorStack.set(res.error.stack); - } - let body2; - if (res.error instanceof ActionInputError) { - body2 = { - type: res.error.type, - issues: res.error.issues, - fields: res.error.fields - }; - } else { - body2 = { - ...res.error, - message: res.error.message - }; - } - return { - type: "error", - status: res.error.status, - contentType: "application/json", - body: JSON.stringify(body2) - }; - } - if (res.data === void 0) { - return { - type: "empty", - status: 204 - }; - } - let body; - try { - body = stringify(res.data, { - // Add support for URL objects - URL: (value) => value instanceof URL && value.href - }); - } catch (e) { - let hint = ActionsReturnedInvalidDataError.hint; - if (res.data instanceof Response) { - hint = REDIRECT_STATUS_CODES.includes(res.data.status) ? "If you need to redirect when the action succeeds, trigger a redirect where the action is called. See the Actions guide for server and client redirect examples: https://docs.astro.build/en/guides/actions." : "If you need to return a Response object, try using a server endpoint instead. See https://docs.astro.build/en/guides/endpoints/#server-endpoints-api-routes"; - } - throw new AstroError({ - ...ActionsReturnedInvalidDataError, - message: ActionsReturnedInvalidDataError.message(String(e)), - hint - }); - } - return { - type: "data", - status: 200, - contentType: "application/json+devalue", - body - }; -} -function deserializeActionResult(res) { - if (res.type === "error") { - let json; - try { - json = JSON.parse(res.body); - } catch { - return { - data: void 0, - error: new ActionError({ - message: res.body, - code: "INTERNAL_SERVER_ERROR" - }) - }; - } - if (Object.assign(__vite_import_meta_env__, {})?.PROD) { - return { error: ActionError.fromJson(json), data: void 0 }; - } else { - const error = ActionError.fromJson(json); - error.stack = actionResultErrorStack.get(); - return { - error, - data: void 0 - }; - } - } - if (res.type === "empty") { - return { data: void 0, error: void 0 }; - } - return { - data: parse(res.body, { - URL: (href) => new URL(href) - }), - error: void 0 - }; -} -const actionResultErrorStack = /* @__PURE__ */ (function actionResultErrorStackFn() { - let errorStack; - return { - set(stack) { - errorStack = stack; - }, - get() { - return errorStack; - } - }; -})(); - -function template({ - title, - pathname, - statusCode = 404, - tabTitle, - body -}) { - return ` - - - - ${tabTitle} - - - -
- -

${statusCode ? `${statusCode}: ` : ""}${title}

- ${body || ` -
Path: ${escape(pathname)}
- `} -
- -`; -} - -const DEFAULT_404_ROUTE = { - component: DEFAULT_404_COMPONENT, - generate: () => "", - params: [], - pattern: /^\/404\/?$/, - prerender: false, - pathname: "/404", - segments: [[{ content: "404", dynamic: false, spread: false }]], - type: "page", - route: "/404", - fallbackRoutes: [], - isIndex: false, - origin: "internal" -}; -function ensure404Route(manifest) { - if (!manifest.routes.some((route) => route.route === "/404")) { - manifest.routes.push(DEFAULT_404_ROUTE); - } - return manifest; -} -async function default404Page({ pathname }) { - return new Response( - template({ - statusCode: 404, - title: "Not found", - tabTitle: "404: Not Found", - pathname - }), - { status: 404, headers: { "Content-Type": "text/html" } } - ); -} -default404Page.isAstroComponentFactory = true; -const default404Instance = { - default: default404Page -}; - -export { ActionError as A, DEFAULT_404_ROUTE as D, NOOP_MIDDLEWARE_FN as N, ACTION_RPC_ROUTE_PATTERN as a, ACTION_QUERY_PARAMS as b, default404Instance as c, deserializeActionResult as d, ensure404Route as e, getActionQueryString as g, serializeActionResult as s }; diff --git a/workbench/astro/dist/server/chunks/astro/server_DhWKww_t.mjs b/workbench/astro/dist/server/chunks/astro/server_DhWKww_t.mjs deleted file mode 100644 index 6d5dfd99f..000000000 --- a/workbench/astro/dist/server/chunks/astro/server_DhWKww_t.mjs +++ /dev/null @@ -1,2766 +0,0 @@ -import colors from 'picocolors'; -import { clsx } from 'clsx'; -import { escape } from 'html-escaper'; -import { decodeBase64, encodeBase64, decodeHex, encodeHexUpperCase } from '@oslojs/encoding'; -import { z } from 'zod'; -import 'cssesc'; - -const ASTRO_VERSION = "5.15.6"; -const REROUTE_DIRECTIVE_HEADER = "X-Astro-Reroute"; -const REWRITE_DIRECTIVE_HEADER_KEY = "X-Astro-Rewrite"; -const REWRITE_DIRECTIVE_HEADER_VALUE = "yes"; -const NOOP_MIDDLEWARE_HEADER = "X-Astro-Noop"; -const ROUTE_TYPE_HEADER = "X-Astro-Route-Type"; -const DEFAULT_404_COMPONENT = "astro-default-404.astro"; -const REDIRECT_STATUS_CODES = [301, 302, 303, 307, 308, 300, 304]; -const REROUTABLE_STATUS_CODES = [404, 500]; -const clientAddressSymbol = Symbol.for("astro.clientAddress"); -const originPathnameSymbol = Symbol.for("astro.originPathname"); -const nodeRequestAbortControllerCleanupSymbol = Symbol.for( - "astro.nodeRequestAbortControllerCleanup" -); -const responseSentSymbol = Symbol.for("astro.responseSent"); - -const ClientAddressNotAvailable = { - name: "ClientAddressNotAvailable", - title: "`Astro.clientAddress` is not available in current adapter.", - message: (adapterName) => `\`Astro.clientAddress\` is not available in the \`${adapterName}\` adapter. File an issue with the adapter to add support.` -}; -const PrerenderClientAddressNotAvailable = { - name: "PrerenderClientAddressNotAvailable", - title: "`Astro.clientAddress` cannot be used inside prerendered routes.", - message: (name) => `\`Astro.clientAddress\` cannot be used inside prerendered route ${name}` -}; -const StaticClientAddressNotAvailable = { - name: "StaticClientAddressNotAvailable", - title: "`Astro.clientAddress` is not available in prerendered pages.", - message: "`Astro.clientAddress` is only available on pages that are server-rendered.", - hint: "See https://docs.astro.build/en/guides/on-demand-rendering/ for more information on how to enable SSR." -}; -const NoMatchingStaticPathFound = { - name: "NoMatchingStaticPathFound", - title: "No static path found for requested path.", - message: (pathName) => `A \`getStaticPaths()\` route pattern was matched, but no matching static path was found for requested path \`${pathName}\`.`, - hint: (possibleRoutes) => `Possible dynamic routes being matched: ${possibleRoutes.join(", ")}.` -}; -const OnlyResponseCanBeReturned = { - name: "OnlyResponseCanBeReturned", - title: "Invalid type returned by Astro page.", - message: (route, returnedValue) => `Route \`${route ? route : ""}\` returned a \`${returnedValue}\`. Only a [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) can be returned from Astro files.`, - hint: "See https://docs.astro.build/en/guides/on-demand-rendering/#response for more information." -}; -const MissingMediaQueryDirective = { - name: "MissingMediaQueryDirective", - title: "Missing value for `client:media` directive.", - message: 'Media query not provided for `client:media` directive. A media query similar to `client:media="(max-width: 600px)"` must be provided' -}; -const NoMatchingRenderer = { - name: "NoMatchingRenderer", - title: "No matching renderer found.", - message: (componentName, componentExtension, plural, validRenderersCount) => `Unable to render \`${componentName}\`. - -${validRenderersCount > 0 ? `There ${plural ? "are" : "is"} ${validRenderersCount} renderer${plural ? "s" : ""} configured in your \`astro.config.mjs\` file, -but ${plural ? "none were" : "it was not"} able to server-side render \`${componentName}\`.` : `No valid renderer was found ${componentExtension ? `for the \`.${componentExtension}\` file extension.` : `for this file extension.`}`}`, - hint: (probableRenderers) => `Did you mean to enable the ${probableRenderers} integration? - -See https://docs.astro.build/en/guides/framework-components/ for more information on how to install and configure integrations.` -}; -const NoClientOnlyHint = { - name: "NoClientOnlyHint", - title: "Missing hint on client:only directive.", - message: (componentName) => `Unable to render \`${componentName}\`. When using the \`client:only\` hydration strategy, Astro needs a hint to use the correct renderer.`, - hint: (probableRenderers) => `Did you mean to pass \`client:only="${probableRenderers}"\`? See https://docs.astro.build/en/reference/directives-reference/#clientonly for more information on client:only` -}; -const InvalidGetStaticPathsEntry = { - name: "InvalidGetStaticPathsEntry", - title: "Invalid entry inside getStaticPath's return value", - message: (entryType) => `Invalid entry returned by getStaticPaths. Expected an object, got \`${entryType}\``, - hint: "If you're using a `.map` call, you might be looking for `.flatMap()` instead. See https://docs.astro.build/en/reference/routing-reference/#getstaticpaths for more information on getStaticPaths." -}; -const InvalidGetStaticPathsReturn = { - name: "InvalidGetStaticPathsReturn", - title: "Invalid value returned by getStaticPaths.", - message: (returnType) => `Invalid type returned by \`getStaticPaths\`. Expected an \`array\`, got \`${returnType}\``, - hint: "See https://docs.astro.build/en/reference/routing-reference/#getstaticpaths for more information on getStaticPaths." -}; -const GetStaticPathsExpectedParams = { - name: "GetStaticPathsExpectedParams", - title: "Missing params property on `getStaticPaths` route.", - message: "Missing or empty required `params` property on `getStaticPaths` route.", - hint: "See https://docs.astro.build/en/reference/routing-reference/#getstaticpaths for more information on getStaticPaths." -}; -const GetStaticPathsInvalidRouteParam = { - name: "GetStaticPathsInvalidRouteParam", - title: "Invalid value for `getStaticPaths` route parameter.", - message: (key, value, valueType) => `Invalid getStaticPaths route parameter for \`${key}\`. Expected undefined, a string or a number, received \`${valueType}\` (\`${value}\`)`, - hint: "See https://docs.astro.build/en/reference/routing-reference/#getstaticpaths for more information on getStaticPaths." -}; -const GetStaticPathsRequired = { - name: "GetStaticPathsRequired", - title: "`getStaticPaths()` function required for dynamic routes.", - message: "`getStaticPaths()` function is required for dynamic routes. Make sure that you `export` a `getStaticPaths` function from your dynamic route.", - hint: `See https://docs.astro.build/en/guides/routing/#dynamic-routes for more information on dynamic routes. - - If you meant for this route to be server-rendered, set \`export const prerender = false;\` in the page.` -}; -const ReservedSlotName = { - name: "ReservedSlotName", - title: "Invalid slot name.", - message: (slotName) => `Unable to create a slot named \`${slotName}\`. \`${slotName}\` is a reserved slot name. Please update the name of this slot.` -}; -const NoMatchingImport = { - name: "NoMatchingImport", - title: "No import found for component.", - message: (componentName) => `Could not render \`${componentName}\`. No matching import has been found for \`${componentName}\`.`, - hint: "Please make sure the component is properly imported." -}; -const InvalidComponentArgs = { - name: "InvalidComponentArgs", - title: "Invalid component arguments.", - message: (name) => `Invalid arguments passed to${name ? ` <${name}>` : ""} component.`, - hint: "Astro components cannot be rendered directly via function call, such as `Component()` or `{items.map(Component)}`." -}; -const PageNumberParamNotFound = { - name: "PageNumberParamNotFound", - title: "Page number param not found.", - message: (paramName) => `[paginate()] page number param \`${paramName}\` not found in your filepath.`, - hint: "Rename your file to `[page].astro` or `[...page].astro`." -}; -const ImageMissingAlt = { - name: "ImageMissingAlt", - title: 'Image missing required "alt" property.', - message: 'Image missing "alt" property. "alt" text is required to describe important images on the page.', - hint: 'Use an empty string ("") for decorative images.' -}; -const InvalidImageService = { - name: "InvalidImageService", - title: "Error while loading image service.", - message: "There was an error loading the configured image service. Please see the stack trace for more information." -}; -const MissingImageDimension = { - name: "MissingImageDimension", - title: "Missing image dimensions", - message: (missingDimension, imageURL) => `Missing ${missingDimension === "both" ? "width and height attributes" : `${missingDimension} attribute`} for ${imageURL}. When using remote images, both dimensions are required in order to avoid CLS.`, - hint: "If your image is inside your `src` folder, you probably meant to import it instead. See [the Imports guide for more information](https://docs.astro.build/en/guides/imports/#other-assets). You can also use `inferSize={true}` for remote images to get the original dimensions." -}; -const FailedToFetchRemoteImageDimensions = { - name: "FailedToFetchRemoteImageDimensions", - title: "Failed to retrieve remote image dimensions", - message: (imageURL) => `Failed to get the dimensions for ${imageURL}.`, - hint: "Verify your remote image URL is accurate, and that you are not using `inferSize` with a file located in your `public/` folder." -}; -const UnsupportedImageFormat = { - name: "UnsupportedImageFormat", - title: "Unsupported image format", - message: (format, imagePath, supportedFormats) => `Received unsupported format \`${format}\` from \`${imagePath}\`. Currently only ${supportedFormats.join( - ", " - )} are supported by our image services.`, - hint: "Using an `img` tag directly instead of the `Image` component might be what you're looking for." -}; -const UnsupportedImageConversion = { - name: "UnsupportedImageConversion", - title: "Unsupported image conversion", - message: "Converting between vector (such as SVGs) and raster (such as PNGs and JPEGs) images is not currently supported." -}; -const PrerenderDynamicEndpointPathCollide = { - name: "PrerenderDynamicEndpointPathCollide", - title: "Prerendered dynamic endpoint has path collision.", - message: (pathname) => `Could not render \`${pathname}\` with an \`undefined\` param as the generated path will collide during prerendering. Prevent passing \`undefined\` as \`params\` for the endpoint's \`getStaticPaths()\` function, or add an additional extension to the endpoint's filename.`, - hint: (filename) => `Rename \`${filename}\` to \`${filename.replace(/\.(?:js|ts)/, (m) => `.json` + m)}\`` -}; -const ExpectedImage = { - name: "ExpectedImage", - title: "Expected src to be an image.", - message: (src, typeofOptions, fullOptions) => `Expected \`src\` property for \`getImage\` or \`\` to be either an ESM imported image or a string with the path of a remote image. Received \`${src}\` (type: \`${typeofOptions}\`). - -Full serialized options received: \`${fullOptions}\`.`, - hint: "This error can often happen because of a wrong path. Make sure the path to your image is correct. If you're passing an async function, make sure to call and await it." -}; -const ExpectedImageOptions = { - name: "ExpectedImageOptions", - title: "Expected image options.", - message: (options) => `Expected getImage() parameter to be an object. Received \`${options}\`.` -}; -const ExpectedNotESMImage = { - name: "ExpectedNotESMImage", - title: "Expected image options, not an ESM-imported image.", - message: "An ESM-imported image cannot be passed directly to `getImage()`. Instead, pass an object with the image in the `src` property.", - hint: "Try changing `getImage(myImage)` to `getImage({ src: myImage })`" -}; -const IncompatibleDescriptorOptions = { - name: "IncompatibleDescriptorOptions", - title: "Cannot set both `densities` and `widths`", - message: "Only one of `densities` or `widths` can be specified. In most cases, you'll probably want to use only `widths` if you require specific widths.", - hint: "Those attributes are used to construct a `srcset` attribute, which cannot have both `x` and `w` descriptors." -}; -const NoImageMetadata = { - name: "NoImageMetadata", - title: "Could not process image metadata.", - message: (imagePath) => `Could not process image metadata${imagePath ? ` for \`${imagePath}\`` : ""}.`, - hint: "This is often caused by a corrupted or malformed image. Re-exporting the image from your image editor may fix this issue." -}; -const ResponseSentError = { - name: "ResponseSentError", - title: "Unable to set response.", - message: "The response has already been sent to the browser and cannot be altered." -}; -const MiddlewareNoDataOrNextCalled = { - name: "MiddlewareNoDataOrNextCalled", - title: "The middleware didn't return a `Response`.", - message: "Make sure your middleware returns a `Response` object, either directly or by returning the `Response` from calling the `next` function." -}; -const MiddlewareNotAResponse = { - name: "MiddlewareNotAResponse", - title: "The middleware returned something that is not a `Response` object.", - message: "Any data returned from middleware must be a valid `Response` object." -}; -const EndpointDidNotReturnAResponse = { - name: "EndpointDidNotReturnAResponse", - title: "The endpoint did not return a `Response`.", - message: "An endpoint must return either a `Response`, or a `Promise` that resolves with a `Response`." -}; -const LocalsNotAnObject = { - name: "LocalsNotAnObject", - title: "Value assigned to `locals` is not accepted.", - message: "`locals` can only be assigned to an object. Other values like numbers, strings, etc. are not accepted.", - hint: "If you tried to remove some information from the `locals` object, try to use `delete` or set the property to `undefined`." -}; -const LocalsReassigned = { - name: "LocalsReassigned", - title: "`locals` must not be reassigned.", - message: "`locals` can not be assigned directly.", - hint: "Set a `locals` property instead." -}; -const AstroResponseHeadersReassigned = { - name: "AstroResponseHeadersReassigned", - title: "`Astro.response.headers` must not be reassigned.", - message: "Individual headers can be added to and removed from `Astro.response.headers`, but it must not be replaced with another instance of `Headers` altogether.", - hint: "Consider using `Astro.response.headers.add()`, and `Astro.response.headers.delete()`." -}; -const LocalImageUsedWrongly = { - name: "LocalImageUsedWrongly", - title: "Local images must be imported.", - message: (imageFilePath) => `\`Image\`'s and \`getImage\`'s \`src\` parameter must be an imported image or an URL, it cannot be a string filepath. Received \`${imageFilePath}\`.`, - hint: "If you want to use an image from your `src` folder, you need to either import it or if the image is coming from a content collection, use the [image() schema helper](https://docs.astro.build/en/guides/images/#images-in-content-collections). See https://docs.astro.build/en/guides/images/#src-required for more information on the `src` property." -}; -const AstroGlobUsedOutside = { - name: "AstroGlobUsedOutside", - title: "Astro.glob() used outside of an Astro file.", - message: (globStr) => `\`Astro.glob(${globStr})\` can only be used in \`.astro\` files. \`import.meta.glob(${globStr})\` can be used instead to achieve a similar result.`, - hint: "See Vite's documentation on `import.meta.glob` for more information: https://vite.dev/guide/features.html#glob-import" -}; -const AstroGlobNoMatch = { - name: "AstroGlobNoMatch", - title: "Astro.glob() did not match any files.", - message: (globStr) => `\`Astro.glob(${globStr})\` did not return any matching files.`, - hint: "Check the pattern for typos." -}; -const MissingSharp = { - name: "MissingSharp", - title: "Could not find Sharp.", - message: "Could not find Sharp. Please install Sharp (`sharp`) manually into your project or migrate to another image service.", - hint: "See Sharp's installation instructions for more information: https://sharp.pixelplumbing.com/install. If you are not relying on `astro:assets` to optimize, transform, or process any images, you can configure a passthrough image service instead of installing Sharp. See https://docs.astro.build/en/reference/errors/missing-sharp for more information.\n\nSee https://docs.astro.build/en/guides/images/#default-image-service for more information on how to migrate to another image service." -}; -const i18nNoLocaleFoundInPath = { - name: "i18nNoLocaleFoundInPath", - title: "The path doesn't contain any locale", - message: "You tried to use an i18n utility on a path that doesn't contain any locale. You can use `pathHasLocale` first to determine if the path has a locale." -}; -const RewriteWithBodyUsed = { - name: "RewriteWithBodyUsed", - title: "Cannot use Astro.rewrite after the request body has been read", - message: "Astro.rewrite() cannot be used if the request body has already been read. If you need to read the body, first clone the request." -}; -const ForbiddenRewrite = { - name: "ForbiddenRewrite", - title: "Forbidden rewrite to a static route.", - message: (from, to, component) => `You tried to rewrite the on-demand route '${from}' with the static route '${to}', when using the 'server' output. - -The static route '${to}' is rendered by the component -'${component}', which is marked as prerendered. This is a forbidden operation because during the build the component '${component}' is compiled to an -HTML file, which can't be retrieved at runtime by Astro.`, - hint: (component) => `Add \`export const prerender = false\` to the component '${component}', or use a Astro.redirect().` -}; -const ExperimentalFontsNotEnabled = { - name: "ExperimentalFontsNotEnabled", - title: "Experimental fonts are not enabled", - message: "The Font component is used but experimental fonts have not been registered in the config.", - hint: "Check that you have enabled experimental fonts and also configured your preferred fonts." -}; -const FontFamilyNotFound = { - name: "FontFamilyNotFound", - title: "Font family not found", - message: (family) => `No data was found for the \`"${family}"\` family passed to the \`\` component.`, - hint: "This is often caused by a typo. Check that the `` component or `getFontData()` function are using a `cssVariable` specified in your config." -}; -const CspNotEnabled = { - name: "CspNotEnabled", - title: "CSP feature isn't enabled", - message: "The `experimental.csp` configuration isn't enabled." -}; -const ActionsReturnedInvalidDataError = { - name: "ActionsReturnedInvalidDataError", - title: "Action handler returned invalid data.", - message: (error) => `Action handler returned invalid data. Handlers should return serializable data types like objects, arrays, strings, and numbers. Parse error: ${error}`, - hint: "See the devalue library for all supported types: https://github.com/rich-harris/devalue" -}; -const ActionNotFoundError = { - name: "ActionNotFoundError", - title: "Action not found.", - message: (actionName) => `The server received a request for an action named \`${actionName}\` but could not find a match. If you renamed an action, check that you've updated your \`actions/index\` file and your calling code to match.`, - hint: "You can run `astro check` to detect type errors caused by mismatched action names." -}; -const SessionStorageInitError = { - name: "SessionStorageInitError", - title: "Session storage could not be initialized.", - message: (error, driver) => `Error when initializing session storage${driver ? ` with driver \`${driver}\`` : ""}. \`${error ?? ""}\``, - hint: "For more information, see https://docs.astro.build/en/guides/sessions/" -}; -const SessionStorageSaveError = { - name: "SessionStorageSaveError", - title: "Session data could not be saved.", - message: (error, driver) => `Error when saving session data${driver ? ` with driver \`${driver}\`` : ""}. \`${error ?? ""}\``, - hint: "For more information, see https://docs.astro.build/en/guides/sessions/" -}; - -function normalizeLF(code) { - return code.replace(/\r\n|\r(?!\n)|\n/g, "\n"); -} - -function codeFrame(src, loc) { - if (!loc || loc.line === void 0 || loc.column === void 0) { - return ""; - } - const lines = normalizeLF(src).split("\n").map((ln) => ln.replace(/\t/g, " ")); - const visibleLines = []; - for (let n = -2; n <= 2; n++) { - if (lines[loc.line + n]) visibleLines.push(loc.line + n); - } - let gutterWidth = 0; - for (const lineNo of visibleLines) { - let w = `> ${lineNo}`; - if (w.length > gutterWidth) gutterWidth = w.length; - } - let output = ""; - for (const lineNo of visibleLines) { - const isFocusedLine = lineNo === loc.line - 1; - output += isFocusedLine ? "> " : " "; - output += `${lineNo + 1} | ${lines[lineNo]} -`; - if (isFocusedLine) - output += `${Array.from({ length: gutterWidth }).join(" ")} | ${Array.from({ - length: loc.column - }).join(" ")}^ -`; - } - return output; -} - -class AstroError extends Error { - loc; - title; - hint; - frame; - type = "AstroError"; - constructor(props, options) { - const { name, title, message, stack, location, hint, frame } = props; - super(message, options); - this.title = title; - this.name = name; - if (message) this.message = message; - this.stack = stack ? stack : this.stack; - this.loc = location; - this.hint = hint; - this.frame = frame; - } - setLocation(location) { - this.loc = location; - } - setName(name) { - this.name = name; - } - setMessage(message) { - this.message = message; - } - setHint(hint) { - this.hint = hint; - } - setFrame(source, location) { - this.frame = codeFrame(source, location); - } - static is(err) { - return err.type === "AstroError"; - } -} - -function validateArgs(args) { - if (args.length !== 3) return false; - if (!args[0] || typeof args[0] !== "object") return false; - return true; -} -function baseCreateComponent(cb, moduleId, propagation) { - const name = moduleId?.split("/").pop()?.replace(".astro", "") ?? ""; - const fn = (...args) => { - if (!validateArgs(args)) { - throw new AstroError({ - ...InvalidComponentArgs, - message: InvalidComponentArgs.message(name) - }); - } - return cb(...args); - }; - Object.defineProperty(fn, "name", { value: name, writable: false }); - fn.isAstroComponentFactory = true; - fn.moduleId = moduleId; - fn.propagation = propagation; - return fn; -} -function createComponentWithOptions(opts) { - const cb = baseCreateComponent(opts.factory, opts.moduleId, opts.propagation); - return cb; -} -function createComponent(arg1, moduleId, propagation) { - if (typeof arg1 === "function") { - return baseCreateComponent(arg1, moduleId, propagation); - } else { - return createComponentWithOptions(arg1); - } -} - -function createAstroGlobFn() { - const globHandler = (importMetaGlobResult) => { - console.warn(`Astro.glob is deprecated and will be removed in a future major version of Astro. -Use import.meta.glob instead: https://vitejs.dev/guide/features.html#glob-import`); - if (typeof importMetaGlobResult === "string") { - throw new AstroError({ - ...AstroGlobUsedOutside, - message: AstroGlobUsedOutside.message(JSON.stringify(importMetaGlobResult)) - }); - } - let allEntries = [...Object.values(importMetaGlobResult)]; - if (allEntries.length === 0) { - throw new AstroError({ - ...AstroGlobNoMatch, - message: AstroGlobNoMatch.message(JSON.stringify(importMetaGlobResult)) - }); - } - return Promise.all(allEntries.map((fn) => fn())); - }; - return globHandler; -} -function createAstro(site) { - return { - site: void 0, - generator: `Astro v${ASTRO_VERSION}`, - glob: createAstroGlobFn() - }; -} - -async function renderEndpoint(mod, context, isPrerendered, logger) { - const { request, url } = context; - const method = request.method.toUpperCase(); - let handler = mod[method] ?? mod["ALL"]; - if (!handler && method === "HEAD" && mod["GET"]) { - handler = mod["GET"]; - } - if (isPrerendered && !["GET", "HEAD"].includes(method)) { - logger.warn( - "router", - `${url.pathname} ${colors.bold( - method - )} requests are not available in static endpoints. Mark this page as server-rendered (\`export const prerender = false;\`) or update your config to \`output: 'server'\` to make all your pages server-rendered by default.` - ); - } - if (handler === void 0) { - logger.warn( - "router", - `No API Route handler exists for the method "${method}" for the route "${url.pathname}". -Found handlers: ${Object.keys(mod).map((exp) => JSON.stringify(exp)).join(", ")} -` + ("all" in mod ? `One of the exported handlers is "all" (lowercase), did you mean to export 'ALL'? -` : "") - ); - return new Response(null, { status: 404 }); - } - if (typeof handler !== "function") { - logger.error( - "router", - `The route "${url.pathname}" exports a value for the method "${method}", but it is of the type ${typeof handler} instead of a function.` - ); - return new Response(null, { status: 500 }); - } - let response = await handler.call(mod, context); - if (!response || response instanceof Response === false) { - throw new AstroError(EndpointDidNotReturnAResponse); - } - if (REROUTABLE_STATUS_CODES.includes(response.status)) { - try { - response.headers.set(REROUTE_DIRECTIVE_HEADER, "no"); - } catch (err) { - if (err.message?.includes("immutable")) { - response = new Response(response.body, response); - response.headers.set(REROUTE_DIRECTIVE_HEADER, "no"); - } else { - throw err; - } - } - } - if (method === "HEAD") { - return new Response(null, response); - } - return response; -} - -function isPromise(value) { - return !!value && typeof value === "object" && "then" in value && typeof value.then === "function"; -} -async function* streamAsyncIterator(stream) { - const reader = stream.getReader(); - try { - while (true) { - const { done, value } = await reader.read(); - if (done) return; - yield value; - } - } finally { - reader.releaseLock(); - } -} - -const escapeHTML = escape; -class HTMLBytes extends Uint8Array { -} -Object.defineProperty(HTMLBytes.prototype, Symbol.toStringTag, { - get() { - return "HTMLBytes"; - } -}); -class HTMLString extends String { - get [Symbol.toStringTag]() { - return "HTMLString"; - } -} -const markHTMLString = (value) => { - if (value instanceof HTMLString) { - return value; - } - if (typeof value === "string") { - return new HTMLString(value); - } - return value; -}; -function isHTMLString(value) { - return Object.prototype.toString.call(value) === "[object HTMLString]"; -} -function markHTMLBytes(bytes) { - return new HTMLBytes(bytes); -} -function hasGetReader(obj) { - return typeof obj.getReader === "function"; -} -async function* unescapeChunksAsync(iterable) { - if (hasGetReader(iterable)) { - for await (const chunk of streamAsyncIterator(iterable)) { - yield unescapeHTML(chunk); - } - } else { - for await (const chunk of iterable) { - yield unescapeHTML(chunk); - } - } -} -function* unescapeChunks(iterable) { - for (const chunk of iterable) { - yield unescapeHTML(chunk); - } -} -function unescapeHTML(str) { - if (!!str && typeof str === "object") { - if (str instanceof Uint8Array) { - return markHTMLBytes(str); - } else if (str instanceof Response && str.body) { - const body = str.body; - return unescapeChunksAsync(body); - } else if (typeof str.then === "function") { - return Promise.resolve(str).then((value) => { - return unescapeHTML(value); - }); - } else if (str[Symbol.for("astro:slot-string")]) { - return str; - } else if (Symbol.iterator in str) { - return unescapeChunks(str); - } else if (Symbol.asyncIterator in str || hasGetReader(str)) { - return unescapeChunksAsync(str); - } - } - return markHTMLString(str); -} - -const AstroJSX = "astro:jsx"; -function isVNode(vnode) { - return vnode && typeof vnode === "object" && vnode[AstroJSX]; -} - -function isAstroComponentFactory(obj) { - return obj == null ? false : obj.isAstroComponentFactory === true; -} -function isAPropagatingComponent(result, factory) { - const hint = getPropagationHint(result, factory); - return hint === "in-tree" || hint === "self"; -} -function getPropagationHint(result, factory) { - let hint = factory.propagation || "none"; - if (factory.moduleId && result.componentMetadata.has(factory.moduleId) && hint === "none") { - hint = result.componentMetadata.get(factory.moduleId).propagation; - } - return hint; -} - -const PROP_TYPE = { - Value: 0, - JSON: 1, - // Actually means Array - RegExp: 2, - Date: 3, - Map: 4, - Set: 5, - BigInt: 6, - URL: 7, - Uint8Array: 8, - Uint16Array: 9, - Uint32Array: 10, - Infinity: 11 -}; -function serializeArray(value, metadata = {}, parents = /* @__PURE__ */ new WeakSet()) { - if (parents.has(value)) { - throw new Error(`Cyclic reference detected while serializing props for <${metadata.displayName} client:${metadata.hydrate}>! - -Cyclic references cannot be safely serialized for client-side usage. Please remove the cyclic reference.`); - } - parents.add(value); - const serialized = value.map((v) => { - return convertToSerializedForm(v, metadata, parents); - }); - parents.delete(value); - return serialized; -} -function serializeObject(value, metadata = {}, parents = /* @__PURE__ */ new WeakSet()) { - if (parents.has(value)) { - throw new Error(`Cyclic reference detected while serializing props for <${metadata.displayName} client:${metadata.hydrate}>! - -Cyclic references cannot be safely serialized for client-side usage. Please remove the cyclic reference.`); - } - parents.add(value); - const serialized = Object.fromEntries( - Object.entries(value).map(([k, v]) => { - return [k, convertToSerializedForm(v, metadata, parents)]; - }) - ); - parents.delete(value); - return serialized; -} -function convertToSerializedForm(value, metadata = {}, parents = /* @__PURE__ */ new WeakSet()) { - const tag = Object.prototype.toString.call(value); - switch (tag) { - case "[object Date]": { - return [PROP_TYPE.Date, value.toISOString()]; - } - case "[object RegExp]": { - return [PROP_TYPE.RegExp, value.source]; - } - case "[object Map]": { - return [PROP_TYPE.Map, serializeArray(Array.from(value), metadata, parents)]; - } - case "[object Set]": { - return [PROP_TYPE.Set, serializeArray(Array.from(value), metadata, parents)]; - } - case "[object BigInt]": { - return [PROP_TYPE.BigInt, value.toString()]; - } - case "[object URL]": { - return [PROP_TYPE.URL, value.toString()]; - } - case "[object Array]": { - return [PROP_TYPE.JSON, serializeArray(value, metadata, parents)]; - } - case "[object Uint8Array]": { - return [PROP_TYPE.Uint8Array, Array.from(value)]; - } - case "[object Uint16Array]": { - return [PROP_TYPE.Uint16Array, Array.from(value)]; - } - case "[object Uint32Array]": { - return [PROP_TYPE.Uint32Array, Array.from(value)]; - } - default: { - if (value !== null && typeof value === "object") { - return [PROP_TYPE.Value, serializeObject(value, metadata, parents)]; - } - if (value === Infinity) { - return [PROP_TYPE.Infinity, 1]; - } - if (value === -Infinity) { - return [PROP_TYPE.Infinity, -1]; - } - if (value === void 0) { - return [PROP_TYPE.Value]; - } - return [PROP_TYPE.Value, value]; - } - } -} -function serializeProps(props, metadata) { - const serialized = JSON.stringify(serializeObject(props, metadata)); - return serialized; -} - -const transitionDirectivesToCopyOnIsland = Object.freeze([ - "data-astro-transition-scope", - "data-astro-transition-persist", - "data-astro-transition-persist-props" -]); -function extractDirectives(inputProps, clientDirectives) { - let extracted = { - isPage: false, - hydration: null, - props: {}, - propsWithoutTransitionAttributes: {} - }; - for (const [key, value] of Object.entries(inputProps)) { - if (key.startsWith("server:")) { - if (key === "server:root") { - extracted.isPage = true; - } - } - if (key.startsWith("client:")) { - if (!extracted.hydration) { - extracted.hydration = { - directive: "", - value: "", - componentUrl: "", - componentExport: { value: "" } - }; - } - switch (key) { - case "client:component-path": { - extracted.hydration.componentUrl = value; - break; - } - case "client:component-export": { - extracted.hydration.componentExport.value = value; - break; - } - // This is a special prop added to prove that the client hydration method - // was added statically. - case "client:component-hydration": { - break; - } - case "client:display-name": { - break; - } - default: { - extracted.hydration.directive = key.split(":")[1]; - extracted.hydration.value = value; - if (!clientDirectives.has(extracted.hydration.directive)) { - const hydrationMethods = Array.from(clientDirectives.keys()).map((d) => `client:${d}`).join(", "); - throw new Error( - `Error: invalid hydration directive "${key}". Supported hydration methods: ${hydrationMethods}` - ); - } - if (extracted.hydration.directive === "media" && typeof extracted.hydration.value !== "string") { - throw new AstroError(MissingMediaQueryDirective); - } - break; - } - } - } else { - extracted.props[key] = value; - if (!transitionDirectivesToCopyOnIsland.includes(key)) { - extracted.propsWithoutTransitionAttributes[key] = value; - } - } - } - for (const sym of Object.getOwnPropertySymbols(inputProps)) { - extracted.props[sym] = inputProps[sym]; - extracted.propsWithoutTransitionAttributes[sym] = inputProps[sym]; - } - return extracted; -} -async function generateHydrateScript(scriptOptions, metadata) { - const { renderer, result, astroId, props, attrs } = scriptOptions; - const { hydrate, componentUrl, componentExport } = metadata; - if (!componentExport.value) { - throw new AstroError({ - ...NoMatchingImport, - message: NoMatchingImport.message(metadata.displayName) - }); - } - const island = { - children: "", - props: { - // This is for HMR, probably can avoid it in prod - uid: astroId - } - }; - if (attrs) { - for (const [key, value] of Object.entries(attrs)) { - island.props[key] = escapeHTML(value); - } - } - island.props["component-url"] = await result.resolve(decodeURI(componentUrl)); - if (renderer.clientEntrypoint) { - island.props["component-export"] = componentExport.value; - island.props["renderer-url"] = await result.resolve( - decodeURI(renderer.clientEntrypoint.toString()) - ); - island.props["props"] = escapeHTML(serializeProps(props, metadata)); - } - island.props["ssr"] = ""; - island.props["client"] = hydrate; - let beforeHydrationUrl = await result.resolve("astro:scripts/before-hydration.js"); - if (beforeHydrationUrl.length) { - island.props["before-hydration-url"] = beforeHydrationUrl; - } - island.props["opts"] = escapeHTML( - JSON.stringify({ - name: metadata.displayName, - value: metadata.hydrateArgs || "" - }) - ); - transitionDirectivesToCopyOnIsland.forEach((name) => { - if (typeof props[name] !== "undefined") { - island.props[name] = props[name]; - } - }); - return island; -} - -/** - * shortdash - https://github.com/bibig/node-shorthash - * - * @license - * - * (The MIT License) - * - * Copyright (c) 2013 Bibig - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ -const dictionary = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY"; -const binary = dictionary.length; -function bitwise(str) { - let hash = 0; - if (str.length === 0) return hash; - for (let i = 0; i < str.length; i++) { - const ch = str.charCodeAt(i); - hash = (hash << 5) - hash + ch; - hash = hash & hash; - } - return hash; -} -function shorthash(text) { - let num; - let result = ""; - let integer = bitwise(text); - const sign = integer < 0 ? "Z" : ""; - integer = Math.abs(integer); - while (integer >= binary) { - num = integer % binary; - integer = Math.floor(integer / binary); - result = dictionary[num] + result; - } - if (integer > 0) { - result = dictionary[integer] + result; - } - return sign + result; -} - -const headAndContentSym = Symbol.for("astro.headAndContent"); -function isHeadAndContent(obj) { - return typeof obj === "object" && obj !== null && !!obj[headAndContentSym]; -} -function createThinHead() { - return { - [headAndContentSym]: true - }; -} - -var astro_island_prebuilt_default = `(()=>{var A=Object.defineProperty;var g=(i,o,a)=>o in i?A(i,o,{enumerable:!0,configurable:!0,writable:!0,value:a}):i[o]=a;var d=(i,o,a)=>g(i,typeof o!="symbol"?o+"":o,a);{let i={0:t=>m(t),1:t=>a(t),2:t=>new RegExp(t),3:t=>new Date(t),4:t=>new Map(a(t)),5:t=>new Set(a(t)),6:t=>BigInt(t),7:t=>new URL(t),8:t=>new Uint8Array(t),9:t=>new Uint16Array(t),10:t=>new Uint32Array(t),11:t=>1/0*t},o=t=>{let[l,e]=t;return l in i?i[l](e):void 0},a=t=>t.map(o),m=t=>typeof t!="object"||t===null?t:Object.fromEntries(Object.entries(t).map(([l,e])=>[l,o(e)]));class y extends HTMLElement{constructor(){super(...arguments);d(this,"Component");d(this,"hydrator");d(this,"hydrate",async()=>{var b;if(!this.hydrator||!this.isConnected)return;let e=(b=this.parentElement)==null?void 0:b.closest("astro-island[ssr]");if(e){e.addEventListener("astro:hydrate",this.hydrate,{once:!0});return}let c=this.querySelectorAll("astro-slot"),n={},h=this.querySelectorAll("template[data-astro-template]");for(let r of h){let s=r.closest(this.tagName);s!=null&&s.isSameNode(this)&&(n[r.getAttribute("data-astro-template")||"default"]=r.innerHTML,r.remove())}for(let r of c){let s=r.closest(this.tagName);s!=null&&s.isSameNode(this)&&(n[r.getAttribute("name")||"default"]=r.innerHTML)}let p;try{p=this.hasAttribute("props")?m(JSON.parse(this.getAttribute("props"))):{}}catch(r){let s=this.getAttribute("component-url")||"",v=this.getAttribute("component-export");throw v&&(s+=\` (export \${v})\`),console.error(\`[hydrate] Error parsing props for component \${s}\`,this.getAttribute("props"),r),r}let u;await this.hydrator(this)(this.Component,p,n,{client:this.getAttribute("client")}),this.removeAttribute("ssr"),this.dispatchEvent(new CustomEvent("astro:hydrate"))});d(this,"unmount",()=>{this.isConnected||this.dispatchEvent(new CustomEvent("astro:unmount"))})}disconnectedCallback(){document.removeEventListener("astro:after-swap",this.unmount),document.addEventListener("astro:after-swap",this.unmount,{once:!0})}connectedCallback(){if(!this.hasAttribute("await-children")||document.readyState==="interactive"||document.readyState==="complete")this.childrenConnectedCallback();else{let e=()=>{document.removeEventListener("DOMContentLoaded",e),c.disconnect(),this.childrenConnectedCallback()},c=new MutationObserver(()=>{var n;((n=this.lastChild)==null?void 0:n.nodeType)===Node.COMMENT_NODE&&this.lastChild.nodeValue==="astro:end"&&(this.lastChild.remove(),e())});c.observe(this,{childList:!0}),document.addEventListener("DOMContentLoaded",e)}}async childrenConnectedCallback(){let e=this.getAttribute("before-hydration-url");e&&await import(e),this.start()}async start(){let e=JSON.parse(this.getAttribute("opts")),c=this.getAttribute("client");if(Astro[c]===void 0){window.addEventListener(\`astro:\${c}\`,()=>this.start(),{once:!0});return}try{await Astro[c](async()=>{let n=this.getAttribute("renderer-url"),[h,{default:p}]=await Promise.all([import(this.getAttribute("component-url")),n?import(n):()=>()=>{}]),u=this.getAttribute("component-export")||"default";if(!u.includes("."))this.Component=h[u];else{this.Component=h;for(let f of u.split("."))this.Component=this.Component[f]}return this.hydrator=p,this.hydrate},e,this)}catch(n){console.error(\`[astro-island] Error hydrating \${this.getAttribute("component-url")}\`,n)}}attributeChangedCallback(){this.hydrate()}}d(y,"observedAttributes",["props"]),customElements.get("astro-island")||customElements.define("astro-island",y)}})();`; - -var astro_island_prebuilt_dev_default = `(()=>{var A=Object.defineProperty;var g=(i,o,a)=>o in i?A(i,o,{enumerable:!0,configurable:!0,writable:!0,value:a}):i[o]=a;var l=(i,o,a)=>g(i,typeof o!="symbol"?o+"":o,a);{let i={0:t=>y(t),1:t=>a(t),2:t=>new RegExp(t),3:t=>new Date(t),4:t=>new Map(a(t)),5:t=>new Set(a(t)),6:t=>BigInt(t),7:t=>new URL(t),8:t=>new Uint8Array(t),9:t=>new Uint16Array(t),10:t=>new Uint32Array(t),11:t=>1/0*t},o=t=>{let[h,e]=t;return h in i?i[h](e):void 0},a=t=>t.map(o),y=t=>typeof t!="object"||t===null?t:Object.fromEntries(Object.entries(t).map(([h,e])=>[h,o(e)]));class f extends HTMLElement{constructor(){super(...arguments);l(this,"Component");l(this,"hydrator");l(this,"hydrate",async()=>{var b;if(!this.hydrator||!this.isConnected)return;let e=(b=this.parentElement)==null?void 0:b.closest("astro-island[ssr]");if(e){e.addEventListener("astro:hydrate",this.hydrate,{once:!0});return}let c=this.querySelectorAll("astro-slot"),n={},p=this.querySelectorAll("template[data-astro-template]");for(let r of p){let s=r.closest(this.tagName);s!=null&&s.isSameNode(this)&&(n[r.getAttribute("data-astro-template")||"default"]=r.innerHTML,r.remove())}for(let r of c){let s=r.closest(this.tagName);s!=null&&s.isSameNode(this)&&(n[r.getAttribute("name")||"default"]=r.innerHTML)}let u;try{u=this.hasAttribute("props")?y(JSON.parse(this.getAttribute("props"))):{}}catch(r){let s=this.getAttribute("component-url")||"",v=this.getAttribute("component-export");throw v&&(s+=\` (export \${v})\`),console.error(\`[hydrate] Error parsing props for component \${s}\`,this.getAttribute("props"),r),r}let d,m=this.hydrator(this);d=performance.now(),await m(this.Component,u,n,{client:this.getAttribute("client")}),d&&this.setAttribute("client-render-time",(performance.now()-d).toString()),this.removeAttribute("ssr"),this.dispatchEvent(new CustomEvent("astro:hydrate"))});l(this,"unmount",()=>{this.isConnected||this.dispatchEvent(new CustomEvent("astro:unmount"))})}disconnectedCallback(){document.removeEventListener("astro:after-swap",this.unmount),document.addEventListener("astro:after-swap",this.unmount,{once:!0})}connectedCallback(){if(!this.hasAttribute("await-children")||document.readyState==="interactive"||document.readyState==="complete")this.childrenConnectedCallback();else{let e=()=>{document.removeEventListener("DOMContentLoaded",e),c.disconnect(),this.childrenConnectedCallback()},c=new MutationObserver(()=>{var n;((n=this.lastChild)==null?void 0:n.nodeType)===Node.COMMENT_NODE&&this.lastChild.nodeValue==="astro:end"&&(this.lastChild.remove(),e())});c.observe(this,{childList:!0}),document.addEventListener("DOMContentLoaded",e)}}async childrenConnectedCallback(){let e=this.getAttribute("before-hydration-url");e&&await import(e),this.start()}async start(){let e=JSON.parse(this.getAttribute("opts")),c=this.getAttribute("client");if(Astro[c]===void 0){window.addEventListener(\`astro:\${c}\`,()=>this.start(),{once:!0});return}try{await Astro[c](async()=>{let n=this.getAttribute("renderer-url"),[p,{default:u}]=await Promise.all([import(this.getAttribute("component-url")),n?import(n):()=>()=>{}]),d=this.getAttribute("component-export")||"default";if(!d.includes("."))this.Component=p[d];else{this.Component=p;for(let m of d.split("."))this.Component=this.Component[m]}return this.hydrator=u,this.hydrate},e,this)}catch(n){console.error(\`[astro-island] Error hydrating \${this.getAttribute("component-url")}\`,n)}}attributeChangedCallback(){this.hydrate()}}l(f,"observedAttributes",["props"]),customElements.get("astro-island")||customElements.define("astro-island",f)}})();`; - -const ISLAND_STYLES = "astro-island,astro-slot,astro-static-slot{display:contents}"; - -function determineIfNeedsHydrationScript(result) { - if (result._metadata.hasHydrationScript) { - return false; - } - return result._metadata.hasHydrationScript = true; -} -function determinesIfNeedsDirectiveScript(result, directive) { - if (result._metadata.hasDirectives.has(directive)) { - return false; - } - result._metadata.hasDirectives.add(directive); - return true; -} -function getDirectiveScriptText(result, directive) { - const clientDirectives = result.clientDirectives; - const clientDirective = clientDirectives.get(directive); - if (!clientDirective) { - throw new Error(`Unknown directive: ${directive}`); - } - return clientDirective; -} -function getPrescripts(result, type, directive) { - switch (type) { - case "both": - return ``; - case "directive": - return ``; - } -} - -function renderCspContent(result) { - const finalScriptHashes = /* @__PURE__ */ new Set(); - const finalStyleHashes = /* @__PURE__ */ new Set(); - for (const scriptHash of result.scriptHashes) { - finalScriptHashes.add(`'${scriptHash}'`); - } - for (const styleHash of result.styleHashes) { - finalStyleHashes.add(`'${styleHash}'`); - } - for (const styleHash of result._metadata.extraStyleHashes) { - finalStyleHashes.add(`'${styleHash}'`); - } - for (const scriptHash of result._metadata.extraScriptHashes) { - finalScriptHashes.add(`'${scriptHash}'`); - } - let directives; - if (result.directives.length > 0) { - directives = result.directives.join(";") + ";"; - } - let scriptResources = "'self'"; - if (result.scriptResources.length > 0) { - scriptResources = result.scriptResources.map((r) => `${r}`).join(" "); - } - let styleResources = "'self'"; - if (result.styleResources.length > 0) { - styleResources = result.styleResources.map((r) => `${r}`).join(" "); - } - const strictDynamic = result.isStrictDynamic ? ` 'strict-dynamic'` : ""; - const scriptSrc = `script-src ${scriptResources} ${Array.from(finalScriptHashes).join(" ")}${strictDynamic};`; - const styleSrc = `style-src ${styleResources} ${Array.from(finalStyleHashes).join(" ")};`; - return [directives, scriptSrc, styleSrc].filter(Boolean).join(" "); -} - -const RenderInstructionSymbol = Symbol.for("astro:render"); -function createRenderInstruction(instruction) { - return Object.defineProperty(instruction, RenderInstructionSymbol, { - value: true - }); -} -function isRenderInstruction(chunk) { - return chunk && typeof chunk === "object" && chunk[RenderInstructionSymbol]; -} - -const voidElementNames = /^(area|base|br|col|command|embed|hr|img|input|keygen|link|meta|param|source|track|wbr)$/i; -const htmlBooleanAttributes = /^(?:allowfullscreen|async|autofocus|autoplay|checked|controls|default|defer|disabled|disablepictureinpicture|disableremoteplayback|formnovalidate|hidden|inert|loop|muted|nomodule|novalidate|open|playsinline|readonly|required|reversed|scoped|seamless|selected|itemscope)$/i; -const AMPERSAND_REGEX = /&/g; -const DOUBLE_QUOTE_REGEX = /"/g; -const STATIC_DIRECTIVES = /* @__PURE__ */ new Set(["set:html", "set:text"]); -const toIdent = (k) => k.trim().replace(/(?!^)\b\w|\s+|\W+/g, (match, index) => { - if (/\W/.test(match)) return ""; - return index === 0 ? match : match.toUpperCase(); -}); -const toAttributeString = (value, shouldEscape = true) => shouldEscape ? String(value).replace(AMPERSAND_REGEX, "&").replace(DOUBLE_QUOTE_REGEX, """) : value; -const kebab = (k) => k.toLowerCase() === k ? k : k.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`); -const toStyleString = (obj) => Object.entries(obj).filter(([_, v]) => typeof v === "string" && v.trim() || typeof v === "number").map(([k, v]) => { - if (k[0] !== "-" && k[1] !== "-") return `${kebab(k)}:${v}`; - return `${k}:${v}`; -}).join(";"); -function defineScriptVars(vars) { - let output = ""; - for (const [key, value] of Object.entries(vars)) { - output += `const ${toIdent(key)} = ${JSON.stringify(value)?.replace( - /<\/script>/g, - "\\x3C/script>" - )}; -`; - } - return markHTMLString(output); -} -function formatList(values) { - if (values.length === 1) { - return values[0]; - } - return `${values.slice(0, -1).join(", ")} or ${values[values.length - 1]}`; -} -function isCustomElement(tagName) { - return tagName.includes("-"); -} -function handleBooleanAttribute(key, value, shouldEscape, tagName) { - if (tagName && isCustomElement(tagName)) { - return markHTMLString(` ${key}="${toAttributeString(value, shouldEscape)}"`); - } - return markHTMLString(value ? ` ${key}` : ""); -} -function addAttribute(value, key, shouldEscape = true, tagName = "") { - if (value == null) { - return ""; - } - if (STATIC_DIRECTIVES.has(key)) { - console.warn(`[astro] The "${key}" directive cannot be applied dynamically at runtime. It will not be rendered as an attribute. - -Make sure to use the static attribute syntax (\`${key}={value}\`) instead of the dynamic spread syntax (\`{...{ "${key}": value }}\`).`); - return ""; - } - if (key === "class:list") { - const listValue = toAttributeString(clsx(value), shouldEscape); - if (listValue === "") { - return ""; - } - return markHTMLString(` ${key.slice(0, -5)}="${listValue}"`); - } - if (key === "style" && !(value instanceof HTMLString)) { - if (Array.isArray(value) && value.length === 2) { - return markHTMLString( - ` ${key}="${toAttributeString(`${toStyleString(value[0])};${value[1]}`, shouldEscape)}"` - ); - } - if (typeof value === "object") { - return markHTMLString(` ${key}="${toAttributeString(toStyleString(value), shouldEscape)}"`); - } - } - if (key === "className") { - return markHTMLString(` class="${toAttributeString(value, shouldEscape)}"`); - } - if (typeof value === "string" && value.includes("&") && isHttpUrl(value)) { - return markHTMLString(` ${key}="${toAttributeString(value, false)}"`); - } - if (htmlBooleanAttributes.test(key)) { - return handleBooleanAttribute(key, value, shouldEscape, tagName); - } - if (value === "") { - return markHTMLString(` ${key}`); - } - if (key === "popover" && typeof value === "boolean") { - return handleBooleanAttribute(key, value, shouldEscape, tagName); - } - if (key === "download" && typeof value === "boolean") { - return handleBooleanAttribute(key, value, shouldEscape, tagName); - } - return markHTMLString(` ${key}="${toAttributeString(value, shouldEscape)}"`); -} -function internalSpreadAttributes(values, shouldEscape = true, tagName) { - let output = ""; - for (const [key, value] of Object.entries(values)) { - output += addAttribute(value, key, shouldEscape, tagName); - } - return markHTMLString(output); -} -function renderElement$1(name, { props: _props, children = "" }, shouldEscape = true) { - const { lang: _, "data-astro-id": astroId, "define:vars": defineVars, ...props } = _props; - if (defineVars) { - if (name === "style") { - delete props["is:global"]; - delete props["is:scoped"]; - } - if (name === "script") { - delete props.hoist; - children = defineScriptVars(defineVars) + "\n" + children; - } - } - if ((children == null || children == "") && voidElementNames.test(name)) { - return `<${name}${internalSpreadAttributes(props, shouldEscape, name)}>`; - } - return `<${name}${internalSpreadAttributes(props, shouldEscape, name)}>${children}`; -} -const noop = () => { -}; -class BufferedRenderer { - chunks = []; - renderPromise; - destination; - /** - * Determines whether buffer has been flushed - * to the final destination. - */ - flushed = false; - constructor(destination, renderFunction) { - this.destination = destination; - this.renderPromise = renderFunction(this); - if (isPromise(this.renderPromise)) { - Promise.resolve(this.renderPromise).catch(noop); - } - } - write(chunk) { - if (this.flushed) { - this.destination.write(chunk); - } else { - this.chunks.push(chunk); - } - } - flush() { - if (this.flushed) { - throw new Error("The render buffer has already been flushed."); - } - this.flushed = true; - for (const chunk of this.chunks) { - this.destination.write(chunk); - } - return this.renderPromise; - } -} -function createBufferedRenderer(destination, renderFunction) { - return new BufferedRenderer(destination, renderFunction); -} -const isNode = typeof process !== "undefined" && Object.prototype.toString.call(process) === "[object process]"; -const isDeno = typeof Deno !== "undefined"; -function promiseWithResolvers() { - let resolve, reject; - const promise = new Promise((_resolve, _reject) => { - resolve = _resolve; - reject = _reject; - }); - return { - promise, - resolve, - reject - }; -} -const VALID_PROTOCOLS = ["http:", "https:"]; -function isHttpUrl(url) { - try { - const parsedUrl = new URL(url); - return VALID_PROTOCOLS.includes(parsedUrl.protocol); - } catch { - return false; - } -} - -const uniqueElements = (item, index, all) => { - const props = JSON.stringify(item.props); - const children = item.children; - return index === all.findIndex((i) => JSON.stringify(i.props) === props && i.children == children); -}; -function renderAllHeadContent(result) { - result._metadata.hasRenderedHead = true; - let content = ""; - if (result.shouldInjectCspMetaTags && result.cspDestination === "meta") { - content += renderElement$1( - "meta", - { - props: { - "http-equiv": "content-security-policy", - content: renderCspContent(result) - }, - children: "" - }, - false - ); - } - const styles = Array.from(result.styles).filter(uniqueElements).map( - (style) => style.props.rel === "stylesheet" ? renderElement$1("link", style) : renderElement$1("style", style) - ); - result.styles.clear(); - const scripts = Array.from(result.scripts).filter(uniqueElements).map((script) => { - if (result.userAssetsBase) { - script.props.src = (result.base === "/" ? "" : result.base) + result.userAssetsBase + script.props.src; - } - return renderElement$1("script", script, false); - }); - const links = Array.from(result.links).filter(uniqueElements).map((link) => renderElement$1("link", link, false)); - content += styles.join("\n") + links.join("\n") + scripts.join("\n"); - if (result._metadata.extraHead.length > 0) { - for (const part of result._metadata.extraHead) { - content += part; - } - } - return markHTMLString(content); -} -function renderHead() { - return createRenderInstruction({ type: "head" }); -} -function maybeRenderHead() { - return createRenderInstruction({ type: "maybe-head" }); -} - -const ALGORITHMS = { - "SHA-256": "sha256-", - "SHA-384": "sha384-", - "SHA-512": "sha512-" -}; -const ALGORITHM_VALUES = Object.values(ALGORITHMS); -z.enum(Object.keys(ALGORITHMS)).optional().default("SHA-256"); -z.custom((value) => { - if (typeof value !== "string") { - return false; - } - return ALGORITHM_VALUES.some((allowedValue) => { - return value.startsWith(allowedValue); - }); -}); -const ALLOWED_DIRECTIVES = [ - "base-uri", - "child-src", - "connect-src", - "default-src", - "fenced-frame-src", - "font-src", - "form-action", - "frame-ancestors", - "frame-src", - "img-src", - "manifest-src", - "media-src", - "object-src", - "referrer", - "report-to", - "report-uri", - "require-trusted-types-for", - "sandbox", - "trusted-types", - "upgrade-insecure-requests", - "worker-src" -]; -z.custom((value) => { - if (typeof value !== "string") { - return false; - } - return ALLOWED_DIRECTIVES.some((allowedValue) => { - return value.startsWith(allowedValue); - }); -}); - -const ALGORITHM = "AES-GCM"; -async function decodeKey(encoded) { - const bytes = decodeBase64(encoded); - return crypto.subtle.importKey("raw", bytes.buffer, ALGORITHM, true, [ - "encrypt", - "decrypt" - ]); -} -const encoder$1 = new TextEncoder(); -const decoder$1 = new TextDecoder(); -const IV_LENGTH = 24; -async function encryptString(key, raw) { - const iv = crypto.getRandomValues(new Uint8Array(IV_LENGTH / 2)); - const data = encoder$1.encode(raw); - const buffer = await crypto.subtle.encrypt( - { - name: ALGORITHM, - iv - }, - key, - data - ); - return encodeHexUpperCase(iv) + encodeBase64(new Uint8Array(buffer)); -} -async function decryptString(key, encoded) { - const iv = decodeHex(encoded.slice(0, IV_LENGTH)); - const dataArray = decodeBase64(encoded.slice(IV_LENGTH)); - const decryptedBuffer = await crypto.subtle.decrypt( - { - name: ALGORITHM, - iv - }, - key, - dataArray - ); - const decryptedString = decoder$1.decode(decryptedBuffer); - return decryptedString; -} -async function generateCspDigest(data, algorithm) { - const hashBuffer = await crypto.subtle.digest(algorithm, encoder$1.encode(data)); - const hash = encodeBase64(new Uint8Array(hashBuffer)); - return `${ALGORITHMS[algorithm]}${hash}`; -} - -const renderTemplateResultSym = Symbol.for("astro.renderTemplateResult"); -class RenderTemplateResult { - [renderTemplateResultSym] = true; - htmlParts; - expressions; - error; - constructor(htmlParts, expressions) { - this.htmlParts = htmlParts; - this.error = void 0; - this.expressions = expressions.map((expression) => { - if (isPromise(expression)) { - return Promise.resolve(expression).catch((err) => { - if (!this.error) { - this.error = err; - throw err; - } - }); - } - return expression; - }); - } - render(destination) { - const flushers = this.expressions.map((exp) => { - return createBufferedRenderer(destination, (bufferDestination) => { - if (exp || exp === 0) { - return renderChild(bufferDestination, exp); - } - }); - }); - let i = 0; - const iterate = () => { - while (i < this.htmlParts.length) { - const html = this.htmlParts[i]; - const flusher = flushers[i]; - i++; - if (html) { - destination.write(markHTMLString(html)); - } - if (flusher) { - const result = flusher.flush(); - if (isPromise(result)) { - return result.then(iterate); - } - } - } - }; - return iterate(); - } -} -function isRenderTemplateResult(obj) { - return typeof obj === "object" && obj !== null && !!obj[renderTemplateResultSym]; -} -function renderTemplate(htmlParts, ...expressions) { - return new RenderTemplateResult(htmlParts, expressions); -} - -const slotString = Symbol.for("astro:slot-string"); -class SlotString extends HTMLString { - instructions; - [slotString]; - constructor(content, instructions) { - super(content); - this.instructions = instructions; - this[slotString] = true; - } -} -function isSlotString(str) { - return !!str[slotString]; -} -function renderSlot(result, slotted, fallback) { - return { - async render(destination) { - await renderChild(destination, typeof slotted === "function" ? slotted(result) : slotted); - } - }; -} -async function renderSlotToString(result, slotted, fallback) { - let content = ""; - let instructions = null; - const temporaryDestination = { - write(chunk) { - if (chunk instanceof SlotString) { - content += chunk; - if (chunk.instructions) { - instructions ??= []; - instructions.push(...chunk.instructions); - } - } else if (chunk instanceof Response) return; - else if (typeof chunk === "object" && "type" in chunk && typeof chunk.type === "string") { - if (instructions === null) { - instructions = []; - } - instructions.push(chunk); - } else { - content += chunkToString(result, chunk); - } - } - }; - const renderInstance = renderSlot(result, slotted); - await renderInstance.render(temporaryDestination); - return markHTMLString(new SlotString(content, instructions)); -} -async function renderSlots(result, slots = {}) { - let slotInstructions = null; - let children = {}; - if (slots) { - await Promise.all( - Object.entries(slots).map( - ([key, value]) => renderSlotToString(result, value).then((output) => { - if (output.instructions) { - if (slotInstructions === null) { - slotInstructions = []; - } - slotInstructions.push(...output.instructions); - } - children[key] = output; - }) - ) - ); - } - return { slotInstructions, children }; -} -function createSlotValueFromString(content) { - return function() { - return renderTemplate`${unescapeHTML(content)}`; - }; -} - -const internalProps = /* @__PURE__ */ new Set([ - "server:component-path", - "server:component-export", - "server:component-directive", - "server:defer" -]); -function containsServerDirective(props) { - return "server:component-directive" in props; -} -const SCRIPT_RE = /<\/script/giu; -const COMMENT_RE = /"); - for (const name in this.slots) { - if (name === "fallback") { - await renderChild(destination, this.slots.fallback(this.result)); - } - } - destination.write( - `` - ); - } - getComponentPath() { - if (this.componentPath) { - return this.componentPath; - } - const componentPath = this.props["server:component-path"]; - if (!componentPath) { - throw new Error(`Could not find server component path`); - } - this.componentPath = componentPath; - return componentPath; - } - getComponentExport() { - if (this.componentExport) { - return this.componentExport; - } - const componentExport = this.props["server:component-export"]; - if (!componentExport) { - throw new Error(`Could not find server component export`); - } - this.componentExport = componentExport; - return componentExport; - } - async getHostId() { - if (!this.hostId) { - this.hostId = await crypto.randomUUID(); - } - return this.hostId; - } - async getIslandContent() { - if (this.islandContent) { - return this.islandContent; - } - const componentPath = this.getComponentPath(); - const componentExport = this.getComponentExport(); - const componentId = this.result.serverIslandNameMap.get(componentPath); - if (!componentId) { - throw new Error(`Could not find server component name`); - } - for (const key2 of Object.keys(this.props)) { - if (internalProps.has(key2)) { - delete this.props[key2]; - } - } - const renderedSlots = {}; - for (const name in this.slots) { - if (name !== "fallback") { - const content = await renderSlotToString(this.result, this.slots[name]); - renderedSlots[name] = content.toString(); - } - } - const key = await this.result.key; - const propsEncrypted = Object.keys(this.props).length === 0 ? "" : await encryptString(key, JSON.stringify(this.props)); - const hostId = await this.getHostId(); - const slash = this.result.base.endsWith("/") ? "" : "/"; - let serverIslandUrl = `${this.result.base}${slash}_server-islands/${componentId}${this.result.trailingSlash === "always" ? "/" : ""}`; - const potentialSearchParams = createSearchParams( - componentExport, - propsEncrypted, - safeJsonStringify(renderedSlots) - ); - const useGETRequest = isWithinURLLimit(serverIslandUrl, potentialSearchParams); - if (useGETRequest) { - serverIslandUrl += "?" + potentialSearchParams.toString(); - this.result._metadata.extraHead.push( - markHTMLString( - `` - ) - ); - } - const adapterHeaders = this.result.internalFetchHeaders || {}; - const headersJson = safeJsonStringify(adapterHeaders); - const method = useGETRequest ? ( - // GET request - `const headers = new Headers(${headersJson}); -let response = await fetch('${serverIslandUrl}', { headers });` - ) : ( - // POST request - `let data = { - componentExport: ${safeJsonStringify(componentExport)}, - encryptedProps: ${safeJsonStringify(propsEncrypted)}, - slots: ${safeJsonStringify(renderedSlots)}, -}; -const headers = new Headers({ 'Content-Type': 'application/json', ...${headersJson} }); -let response = await fetch('${serverIslandUrl}', { - method: 'POST', - body: JSON.stringify(data), - headers, -});` - ); - this.islandContent = `${method}replaceServerIsland('${hostId}', response);`; - return this.islandContent; - } -} -const renderServerIslandRuntime = () => { - return ``; -}; -const SERVER_ISLAND_REPLACER = markHTMLString( - `async function replaceServerIsland(id, r) { - let s = document.querySelector(\`script[data-island-id="\${id}"]\`); - // If there's no matching script, or the request fails then return - if (!s || r.status !== 200 || r.headers.get('content-type')?.split(';')[0].trim() !== 'text/html') return; - // Load the HTML before modifying the DOM in case of errors - let html = await r.text(); - // Remove any placeholder content before the island script - while (s.previousSibling && s.previousSibling.nodeType !== 8 && s.previousSibling.data !== '[if astro]>server-island-start line.trim()).filter((line) => line && !line.startsWith("//")).join(" ") -); - -const Fragment = Symbol.for("astro:fragment"); -const Renderer = Symbol.for("astro:renderer"); -const encoder = new TextEncoder(); -const decoder = new TextDecoder(); -function stringifyChunk(result, chunk) { - if (isRenderInstruction(chunk)) { - const instruction = chunk; - switch (instruction.type) { - case "directive": { - const { hydration } = instruction; - let needsHydrationScript = hydration && determineIfNeedsHydrationScript(result); - let needsDirectiveScript = hydration && determinesIfNeedsDirectiveScript(result, hydration.directive); - if (needsHydrationScript) { - let prescripts = getPrescripts(result, "both", hydration.directive); - return markHTMLString(prescripts); - } else if (needsDirectiveScript) { - let prescripts = getPrescripts(result, "directive", hydration.directive); - return markHTMLString(prescripts); - } else { - return ""; - } - } - case "head": { - if (result._metadata.hasRenderedHead || result.partial) { - return ""; - } - return renderAllHeadContent(result); - } - case "maybe-head": { - if (result._metadata.hasRenderedHead || result._metadata.headInTree || result.partial) { - return ""; - } - return renderAllHeadContent(result); - } - case "renderer-hydration-script": { - const { rendererSpecificHydrationScripts } = result._metadata; - const { rendererName } = instruction; - if (!rendererSpecificHydrationScripts.has(rendererName)) { - rendererSpecificHydrationScripts.add(rendererName); - return instruction.render(); - } - return ""; - } - case "server-island-runtime": { - if (result._metadata.hasRenderedServerIslandRuntime) { - return ""; - } - result._metadata.hasRenderedServerIslandRuntime = true; - return renderServerIslandRuntime(); - } - default: { - throw new Error(`Unknown chunk type: ${chunk.type}`); - } - } - } else if (chunk instanceof Response) { - return ""; - } else if (isSlotString(chunk)) { - let out = ""; - const c = chunk; - if (c.instructions) { - for (const instr of c.instructions) { - out += stringifyChunk(result, instr); - } - } - out += chunk.toString(); - return out; - } - return chunk.toString(); -} -function chunkToString(result, chunk) { - if (ArrayBuffer.isView(chunk)) { - return decoder.decode(chunk); - } else { - return stringifyChunk(result, chunk); - } -} -function chunkToByteArray(result, chunk) { - if (ArrayBuffer.isView(chunk)) { - return chunk; - } else { - const stringified = stringifyChunk(result, chunk); - return encoder.encode(stringified.toString()); - } -} -function isRenderInstance(obj) { - return !!obj && typeof obj === "object" && "render" in obj && typeof obj.render === "function"; -} - -function renderChild(destination, child) { - if (isPromise(child)) { - return child.then((x) => renderChild(destination, x)); - } - if (child instanceof SlotString) { - destination.write(child); - return; - } - if (isHTMLString(child)) { - destination.write(child); - return; - } - if (Array.isArray(child)) { - return renderArray(destination, child); - } - if (typeof child === "function") { - return renderChild(destination, child()); - } - if (!child && child !== 0) { - return; - } - if (typeof child === "string") { - destination.write(markHTMLString(escapeHTML(child))); - return; - } - if (isRenderInstance(child)) { - return child.render(destination); - } - if (isRenderTemplateResult(child)) { - return child.render(destination); - } - if (isAstroComponentInstance(child)) { - return child.render(destination); - } - if (ArrayBuffer.isView(child)) { - destination.write(child); - return; - } - if (typeof child === "object" && (Symbol.asyncIterator in child || Symbol.iterator in child)) { - if (Symbol.asyncIterator in child) { - return renderAsyncIterable(destination, child); - } - return renderIterable(destination, child); - } - destination.write(child); -} -function renderArray(destination, children) { - const flushers = children.map((c) => { - return createBufferedRenderer(destination, (bufferDestination) => { - return renderChild(bufferDestination, c); - }); - }); - const iterator = flushers[Symbol.iterator](); - const iterate = () => { - for (; ; ) { - const { value: flusher, done } = iterator.next(); - if (done) { - break; - } - const result = flusher.flush(); - if (isPromise(result)) { - return result.then(iterate); - } - } - }; - return iterate(); -} -function renderIterable(destination, children) { - const iterator = children[Symbol.iterator](); - const iterate = () => { - for (; ; ) { - const { value, done } = iterator.next(); - if (done) { - break; - } - const result = renderChild(destination, value); - if (isPromise(result)) { - return result.then(iterate); - } - } - }; - return iterate(); -} -async function renderAsyncIterable(destination, children) { - for await (const value of children) { - await renderChild(destination, value); - } -} - -const astroComponentInstanceSym = Symbol.for("astro.componentInstance"); -class AstroComponentInstance { - [astroComponentInstanceSym] = true; - result; - props; - slotValues; - factory; - returnValue; - constructor(result, props, slots, factory) { - this.result = result; - this.props = props; - this.factory = factory; - this.slotValues = {}; - for (const name in slots) { - let didRender = false; - let value = slots[name](result); - this.slotValues[name] = () => { - if (!didRender) { - didRender = true; - return value; - } - return slots[name](result); - }; - } - } - init(result) { - if (this.returnValue !== void 0) { - return this.returnValue; - } - this.returnValue = this.factory(result, this.props, this.slotValues); - if (isPromise(this.returnValue)) { - this.returnValue.then((resolved) => { - this.returnValue = resolved; - }).catch(() => { - }); - } - return this.returnValue; - } - render(destination) { - const returnValue = this.init(this.result); - if (isPromise(returnValue)) { - return returnValue.then((x) => this.renderImpl(destination, x)); - } - return this.renderImpl(destination, returnValue); - } - renderImpl(destination, returnValue) { - if (isHeadAndContent(returnValue)) { - return returnValue.content.render(destination); - } else { - return renderChild(destination, returnValue); - } - } -} -function validateComponentProps(props, clientDirectives, displayName) { - if (props != null) { - const directives = [...clientDirectives.keys()].map((directive) => `client:${directive}`); - for (const prop of Object.keys(props)) { - if (directives.includes(prop)) { - console.warn( - `You are attempting to render <${displayName} ${prop} />, but ${displayName} is an Astro component. Astro components do not render in the client and should not have a hydration directive. Please use a framework component for client rendering.` - ); - } - } - } -} -function createAstroComponentInstance(result, displayName, factory, props, slots = {}) { - validateComponentProps(props, result.clientDirectives, displayName); - const instance = new AstroComponentInstance(result, props, slots, factory); - if (isAPropagatingComponent(result, factory)) { - result._metadata.propagators.add(instance); - } - return instance; -} -function isAstroComponentInstance(obj) { - return typeof obj === "object" && obj !== null && !!obj[astroComponentInstanceSym]; -} - -const DOCTYPE_EXP = /" : "\n"; - str += doctype; - } - } - if (chunk instanceof Response) return; - str += chunkToString(result, chunk); - } - }; - await templateResult.render(destination); - return str; -} -async function renderToReadableStream(result, componentFactory, props, children, isPage = false, route) { - const templateResult = await callComponentAsTemplateResultOrResponse( - result, - componentFactory, - props, - children, - route - ); - if (templateResult instanceof Response) return templateResult; - let renderedFirstPageChunk = false; - if (isPage) { - await bufferHeadContent(result); - } - return new ReadableStream({ - start(controller) { - const destination = { - write(chunk) { - if (isPage && !renderedFirstPageChunk) { - renderedFirstPageChunk = true; - if (!result.partial && !DOCTYPE_EXP.test(String(chunk))) { - const doctype = result.compressHTML ? "" : "\n"; - controller.enqueue(encoder.encode(doctype)); - } - } - if (chunk instanceof Response) { - throw new AstroError({ - ...ResponseSentError - }); - } - const bytes = chunkToByteArray(result, chunk); - controller.enqueue(bytes); - } - }; - (async () => { - try { - await templateResult.render(destination); - controller.close(); - } catch (e) { - if (AstroError.is(e) && !e.loc) { - e.setLocation({ - file: route?.component - }); - } - setTimeout(() => controller.error(e), 0); - } - })(); - }, - cancel() { - result.cancelled = true; - } - }); -} -async function callComponentAsTemplateResultOrResponse(result, componentFactory, props, children, route) { - const factoryResult = await componentFactory(result, props, children); - if (factoryResult instanceof Response) { - return factoryResult; - } else if (isHeadAndContent(factoryResult)) { - if (!isRenderTemplateResult(factoryResult.content)) { - throw new AstroError({ - ...OnlyResponseCanBeReturned, - message: OnlyResponseCanBeReturned.message( - route?.route, - typeof factoryResult - ), - location: { - file: route?.component - } - }); - } - return factoryResult.content; - } else if (!isRenderTemplateResult(factoryResult)) { - throw new AstroError({ - ...OnlyResponseCanBeReturned, - message: OnlyResponseCanBeReturned.message(route?.route, typeof factoryResult), - location: { - file: route?.component - } - }); - } - return factoryResult; -} -async function bufferHeadContent(result) { - const iterator = result._metadata.propagators.values(); - while (true) { - const { value, done } = iterator.next(); - if (done) { - break; - } - const returnValue = await value.init(result); - if (isHeadAndContent(returnValue) && returnValue.head) { - result._metadata.extraHead.push(returnValue.head); - } - } -} -async function renderToAsyncIterable(result, componentFactory, props, children, isPage = false, route) { - const templateResult = await callComponentAsTemplateResultOrResponse( - result, - componentFactory, - props, - children, - route - ); - if (templateResult instanceof Response) return templateResult; - let renderedFirstPageChunk = false; - if (isPage) { - await bufferHeadContent(result); - } - let error = null; - let next = null; - const buffer = []; - let renderingComplete = false; - const iterator = { - async next() { - if (result.cancelled) return { done: true, value: void 0 }; - if (next !== null) { - await next.promise; - } else if (!renderingComplete && !buffer.length) { - next = promiseWithResolvers(); - await next.promise; - } - if (!renderingComplete) { - next = promiseWithResolvers(); - } - if (error) { - throw error; - } - let length = 0; - for (let i = 0, len = buffer.length; i < len; i++) { - length += buffer[i].length; - } - let mergedArray = new Uint8Array(length); - let offset = 0; - for (let i = 0, len = buffer.length; i < len; i++) { - const item = buffer[i]; - mergedArray.set(item, offset); - offset += item.length; - } - buffer.length = 0; - const returnValue = { - // The iterator is done when rendering has finished - // and there are no more chunks to return. - done: length === 0 && renderingComplete, - value: mergedArray - }; - return returnValue; - }, - async return() { - result.cancelled = true; - return { done: true, value: void 0 }; - } - }; - const destination = { - write(chunk) { - if (isPage && !renderedFirstPageChunk) { - renderedFirstPageChunk = true; - if (!result.partial && !DOCTYPE_EXP.test(String(chunk))) { - const doctype = result.compressHTML ? "" : "\n"; - buffer.push(encoder.encode(doctype)); - } - } - if (chunk instanceof Response) { - throw new AstroError(ResponseSentError); - } - const bytes = chunkToByteArray(result, chunk); - if (bytes.length > 0) { - buffer.push(bytes); - next?.resolve(); - } else if (buffer.length > 0) { - next?.resolve(); - } - } - }; - const renderResult = toPromise(() => templateResult.render(destination)); - renderResult.catch((err) => { - error = err; - }).finally(() => { - renderingComplete = true; - next?.resolve(); - }); - return { - [Symbol.asyncIterator]() { - return iterator; - } - }; -} -function toPromise(fn) { - try { - const result = fn(); - return isPromise(result) ? result : Promise.resolve(result); - } catch (err) { - return Promise.reject(err); - } -} - -function componentIsHTMLElement(Component) { - return typeof HTMLElement !== "undefined" && HTMLElement.isPrototypeOf(Component); -} -async function renderHTMLElement(result, constructor, props, slots) { - const name = getHTMLElementName(constructor); - let attrHTML = ""; - for (const attr in props) { - attrHTML += ` ${attr}="${toAttributeString(await props[attr])}"`; - } - return markHTMLString( - `<${name}${attrHTML}>${await renderSlotToString(result, slots?.default)}` - ); -} -function getHTMLElementName(constructor) { - const definedName = customElements.getName(constructor); - if (definedName) return definedName; - const assignedName = constructor.name.replace(/^HTML|Element$/g, "").replace(/[A-Z]/g, "-$&").toLowerCase().replace(/^-/, "html-"); - return assignedName; -} - -const needsHeadRenderingSymbol = Symbol.for("astro.needsHeadRendering"); -const rendererAliases = /* @__PURE__ */ new Map([["solid", "solid-js"]]); -const clientOnlyValues = /* @__PURE__ */ new Set(["solid-js", "react", "preact", "vue", "svelte"]); -function guessRenderers(componentUrl) { - const extname = componentUrl?.split(".").pop(); - switch (extname) { - case "svelte": - return ["@astrojs/svelte"]; - case "vue": - return ["@astrojs/vue"]; - case "jsx": - case "tsx": - return ["@astrojs/react", "@astrojs/preact", "@astrojs/solid-js", "@astrojs/vue (jsx)"]; - case void 0: - default: - return [ - "@astrojs/react", - "@astrojs/preact", - "@astrojs/solid-js", - "@astrojs/vue", - "@astrojs/svelte" - ]; - } -} -function isFragmentComponent(Component) { - return Component === Fragment; -} -function isHTMLComponent(Component) { - return Component && Component["astro:html"] === true; -} -const ASTRO_SLOT_EXP = /<\/?astro-slot\b[^>]*>/g; -const ASTRO_STATIC_SLOT_EXP = /<\/?astro-static-slot\b[^>]*>/g; -function removeStaticAstroSlot(html, supportsAstroStaticSlot = true) { - const exp = supportsAstroStaticSlot ? ASTRO_STATIC_SLOT_EXP : ASTRO_SLOT_EXP; - return html.replace(exp, ""); -} -async function renderFrameworkComponent(result, displayName, Component, _props, slots = {}) { - if (!Component && "client:only" in _props === false) { - throw new Error( - `Unable to render ${displayName} because it is ${Component}! -Did you forget to import the component or is it possible there is a typo?` - ); - } - const { renderers, clientDirectives } = result; - const metadata = { - astroStaticSlot: true, - displayName - }; - const { hydration, isPage, props, propsWithoutTransitionAttributes } = extractDirectives( - _props, - clientDirectives - ); - let html = ""; - let attrs = void 0; - if (hydration) { - metadata.hydrate = hydration.directive; - metadata.hydrateArgs = hydration.value; - metadata.componentExport = hydration.componentExport; - metadata.componentUrl = hydration.componentUrl; - } - const probableRendererNames = guessRenderers(metadata.componentUrl); - const validRenderers = renderers.filter((r) => r.name !== "astro:jsx"); - const { children, slotInstructions } = await renderSlots(result, slots); - let renderer; - if (metadata.hydrate !== "only") { - let isTagged = false; - try { - isTagged = Component && Component[Renderer]; - } catch { - } - if (isTagged) { - const rendererName = Component[Renderer]; - renderer = renderers.find(({ name }) => name === rendererName); - } - if (!renderer) { - let error; - for (const r of renderers) { - try { - if (await r.ssr.check.call({ result }, Component, props, children)) { - renderer = r; - break; - } - } catch (e) { - error ??= e; - } - } - if (!renderer && error) { - throw error; - } - } - if (!renderer && typeof HTMLElement === "function" && componentIsHTMLElement(Component)) { - const output = await renderHTMLElement( - result, - Component, - _props, - slots - ); - return { - render(destination) { - destination.write(output); - } - }; - } - } else { - if (metadata.hydrateArgs) { - const rendererName = rendererAliases.has(metadata.hydrateArgs) ? rendererAliases.get(metadata.hydrateArgs) : metadata.hydrateArgs; - if (clientOnlyValues.has(rendererName)) { - renderer = renderers.find( - ({ name }) => name === `@astrojs/${rendererName}` || name === rendererName - ); - } - } - if (!renderer && validRenderers.length === 1) { - renderer = validRenderers[0]; - } - if (!renderer) { - const extname = metadata.componentUrl?.split(".").pop(); - renderer = renderers.find(({ name }) => name === `@astrojs/${extname}` || name === extname); - } - } - let componentServerRenderEndTime; - if (!renderer) { - if (metadata.hydrate === "only") { - const rendererName = rendererAliases.has(metadata.hydrateArgs) ? rendererAliases.get(metadata.hydrateArgs) : metadata.hydrateArgs; - if (clientOnlyValues.has(rendererName)) { - const plural = validRenderers.length > 1; - throw new AstroError({ - ...NoMatchingRenderer, - message: NoMatchingRenderer.message( - metadata.displayName, - metadata?.componentUrl?.split(".").pop(), - plural, - validRenderers.length - ), - hint: NoMatchingRenderer.hint( - formatList(probableRendererNames.map((r) => "`" + r + "`")) - ) - }); - } else { - throw new AstroError({ - ...NoClientOnlyHint, - message: NoClientOnlyHint.message(metadata.displayName), - hint: NoClientOnlyHint.hint( - probableRendererNames.map((r) => r.replace("@astrojs/", "")).join("|") - ) - }); - } - } else if (typeof Component !== "string") { - const matchingRenderers = validRenderers.filter( - (r) => probableRendererNames.includes(r.name) - ); - const plural = validRenderers.length > 1; - if (matchingRenderers.length === 0) { - throw new AstroError({ - ...NoMatchingRenderer, - message: NoMatchingRenderer.message( - metadata.displayName, - metadata?.componentUrl?.split(".").pop(), - plural, - validRenderers.length - ), - hint: NoMatchingRenderer.hint( - formatList(probableRendererNames.map((r) => "`" + r + "`")) - ) - }); - } else if (matchingRenderers.length === 1) { - renderer = matchingRenderers[0]; - ({ html, attrs } = await renderer.ssr.renderToStaticMarkup.call( - { result }, - Component, - propsWithoutTransitionAttributes, - children, - metadata - )); - } else { - throw new Error(`Unable to render ${metadata.displayName}! - -This component likely uses ${formatList(probableRendererNames)}, -but Astro encountered an error during server-side rendering. - -Please ensure that ${metadata.displayName}: -1. Does not unconditionally access browser-specific globals like \`window\` or \`document\`. - If this is unavoidable, use the \`client:only\` hydration directive. -2. Does not conditionally return \`null\` or \`undefined\` when rendered on the server. - -If you're still stuck, please open an issue on GitHub or join us at https://astro.build/chat.`); - } - } - } else { - if (metadata.hydrate === "only") { - html = await renderSlotToString(result, slots?.fallback); - } else { - const componentRenderStartTime = performance.now(); - ({ html, attrs } = await renderer.ssr.renderToStaticMarkup.call( - { result }, - Component, - propsWithoutTransitionAttributes, - children, - metadata - )); - if (process.env.NODE_ENV === "development") - componentServerRenderEndTime = performance.now() - componentRenderStartTime; - } - } - if (!html && typeof Component === "string") { - const Tag = sanitizeElementName(Component); - const childSlots = Object.values(children).join(""); - const renderTemplateResult = renderTemplate`<${Tag}${internalSpreadAttributes( - props, - true, - Tag - )}${markHTMLString( - childSlots === "" && voidElementNames.test(Tag) ? `/>` : `>${childSlots}` - )}`; - html = ""; - const destination = { - write(chunk) { - if (chunk instanceof Response) return; - html += chunkToString(result, chunk); - } - }; - await renderTemplateResult.render(destination); - } - if (!hydration) { - return { - render(destination) { - if (slotInstructions) { - for (const instruction of slotInstructions) { - destination.write(instruction); - } - } - if (isPage || renderer?.name === "astro:jsx") { - destination.write(html); - } else if (html && html.length > 0) { - destination.write( - markHTMLString(removeStaticAstroSlot(html, renderer?.ssr?.supportsAstroStaticSlot)) - ); - } - } - }; - } - const astroId = shorthash( - ` -${html} -${serializeProps( - props, - metadata - )}` - ); - const island = await generateHydrateScript( - { renderer, result, astroId, props, attrs }, - metadata - ); - if (componentServerRenderEndTime && process.env.NODE_ENV === "development") - island.props["server-render-time"] = componentServerRenderEndTime; - let unrenderedSlots = []; - if (html) { - if (Object.keys(children).length > 0) { - for (const key of Object.keys(children)) { - let tagName = renderer?.ssr?.supportsAstroStaticSlot ? !!metadata.hydrate ? "astro-slot" : "astro-static-slot" : "astro-slot"; - let expectedHTML = key === "default" ? `<${tagName}>` : `<${tagName} name="${key}">`; - if (!html.includes(expectedHTML)) { - unrenderedSlots.push(key); - } - } - } - } else { - unrenderedSlots = Object.keys(children); - } - const template = unrenderedSlots.length > 0 ? unrenderedSlots.map( - (key) => `` - ).join("") : ""; - island.children = `${html ?? ""}${template}`; - if (island.children) { - island.props["await-children"] = ""; - island.children += ``; - } - return { - render(destination) { - if (slotInstructions) { - for (const instruction of slotInstructions) { - destination.write(instruction); - } - } - destination.write(createRenderInstruction({ type: "directive", hydration })); - if (hydration.directive !== "only" && renderer?.ssr.renderHydrationScript) { - destination.write( - createRenderInstruction({ - type: "renderer-hydration-script", - rendererName: renderer.name, - render: renderer.ssr.renderHydrationScript - }) - ); - } - const renderedElement = renderElement$1("astro-island", island, false); - destination.write(markHTMLString(renderedElement)); - } - }; -} -function sanitizeElementName(tag) { - const unsafe = /[&<>'"\s]+/; - if (!unsafe.test(tag)) return tag; - return tag.trim().split(unsafe)[0].trim(); -} -async function renderFragmentComponent(result, slots = {}) { - const children = await renderSlotToString(result, slots?.default); - return { - render(destination) { - if (children == null) return; - destination.write(children); - } - }; -} -async function renderHTMLComponent(result, Component, _props, slots = {}) { - const { slotInstructions, children } = await renderSlots(result, slots); - const html = Component({ slots: children }); - const hydrationHtml = slotInstructions ? slotInstructions.map((instr) => chunkToString(result, instr)).join("") : ""; - return { - render(destination) { - destination.write(markHTMLString(hydrationHtml + html)); - } - }; -} -function renderAstroComponent(result, displayName, Component, props, slots = {}) { - if (containsServerDirective(props)) { - const serverIslandComponent = new ServerIslandComponent(result, props, slots, displayName); - result._metadata.propagators.add(serverIslandComponent); - return serverIslandComponent; - } - const instance = createAstroComponentInstance(result, displayName, Component, props, slots); - return { - render(destination) { - return instance.render(destination); - } - }; -} -function renderComponent(result, displayName, Component, props, slots = {}) { - if (isPromise(Component)) { - return Component.catch(handleCancellation).then((x) => { - return renderComponent(result, displayName, x, props, slots); - }); - } - if (isFragmentComponent(Component)) { - return renderFragmentComponent(result, slots).catch(handleCancellation); - } - props = normalizeProps(props); - if (isHTMLComponent(Component)) { - return renderHTMLComponent(result, Component, props, slots).catch(handleCancellation); - } - if (isAstroComponentFactory(Component)) { - return renderAstroComponent(result, displayName, Component, props, slots); - } - return renderFrameworkComponent(result, displayName, Component, props, slots).catch( - handleCancellation - ); - function handleCancellation(e) { - if (result.cancelled) - return { - render() { - } - }; - throw e; - } -} -function normalizeProps(props) { - if (props["class:list"] !== void 0) { - const value = props["class:list"]; - delete props["class:list"]; - props["class"] = clsx(props["class"], value); - if (props["class"] === "") { - delete props["class"]; - } - } - return props; -} -async function renderComponentToString(result, displayName, Component, props, slots = {}, isPage = false, route) { - let str = ""; - let renderedFirstPageChunk = false; - let head = ""; - if (isPage && !result.partial && nonAstroPageNeedsHeadInjection(Component)) { - head += chunkToString(result, maybeRenderHead()); - } - try { - const destination = { - write(chunk) { - if (isPage && !result.partial && !renderedFirstPageChunk) { - renderedFirstPageChunk = true; - if (!/" : "\n"; - str += doctype + head; - } - } - if (chunk instanceof Response) return; - str += chunkToString(result, chunk); - } - }; - const renderInstance = await renderComponent(result, displayName, Component, props, slots); - if (containsServerDirective(props)) { - await bufferHeadContent(result); - } - await renderInstance.render(destination); - } catch (e) { - if (AstroError.is(e) && !e.loc) { - e.setLocation({ - file: route?.component - }); - } - throw e; - } - return str; -} -function nonAstroPageNeedsHeadInjection(pageComponent) { - return !!pageComponent?.[needsHeadRenderingSymbol]; -} - -const ClientOnlyPlaceholder = "astro-client-only"; -const hasTriedRenderComponentSymbol = Symbol("hasTriedRenderComponent"); -async function renderJSX(result, vnode) { - switch (true) { - case vnode instanceof HTMLString: - if (vnode.toString().trim() === "") { - return ""; - } - return vnode; - case typeof vnode === "string": - return markHTMLString(escapeHTML(vnode)); - case typeof vnode === "function": - return vnode; - case (!vnode && vnode !== 0): - return ""; - case Array.isArray(vnode): - return markHTMLString( - (await Promise.all(vnode.map((v) => renderJSX(result, v)))).join("") - ); - } - return renderJSXVNode(result, vnode); -} -async function renderJSXVNode(result, vnode) { - if (isVNode(vnode)) { - switch (true) { - case !vnode.type: { - throw new Error(`Unable to render ${result.pathname} because it contains an undefined Component! -Did you forget to import the component or is it possible there is a typo?`); - } - case vnode.type === Symbol.for("astro:fragment"): - return renderJSX(result, vnode.props.children); - case isAstroComponentFactory(vnode.type): { - let props = {}; - let slots = {}; - for (const [key, value] of Object.entries(vnode.props ?? {})) { - if (key === "children" || value && typeof value === "object" && value["$$slot"]) { - slots[key === "children" ? "default" : key] = () => renderJSX(result, value); - } else { - props[key] = value; - } - } - const str = await renderComponentToString( - result, - vnode.type.name, - vnode.type, - props, - slots - ); - const html = markHTMLString(str); - return html; - } - case (!vnode.type && vnode.type !== 0): - return ""; - case (typeof vnode.type === "string" && vnode.type !== ClientOnlyPlaceholder): - return markHTMLString(await renderElement(result, vnode.type, vnode.props ?? {})); - } - if (vnode.type) { - let extractSlots2 = function(child) { - if (Array.isArray(child)) { - return child.map((c) => extractSlots2(c)); - } - if (!isVNode(child)) { - _slots.default.push(child); - return; - } - if ("slot" in child.props) { - _slots[child.props.slot] = [..._slots[child.props.slot] ?? [], child]; - delete child.props.slot; - return; - } - _slots.default.push(child); - }; - if (typeof vnode.type === "function" && vnode.props["server:root"]) { - const output2 = await vnode.type(vnode.props ?? {}); - return await renderJSX(result, output2); - } - if (typeof vnode.type === "function") { - if (vnode.props[hasTriedRenderComponentSymbol]) { - delete vnode.props[hasTriedRenderComponentSymbol]; - const output2 = await vnode.type(vnode.props ?? {}); - if (output2?.[AstroJSX] || !output2) { - return await renderJSXVNode(result, output2); - } else { - return; - } - } else { - vnode.props[hasTriedRenderComponentSymbol] = true; - } - } - const { children = null, ...props } = vnode.props ?? {}; - const _slots = { - default: [] - }; - extractSlots2(children); - for (const [key, value] of Object.entries(props)) { - if (value?.["$$slot"]) { - _slots[key] = value; - delete props[key]; - } - } - const slotPromises = []; - const slots = {}; - for (const [key, value] of Object.entries(_slots)) { - slotPromises.push( - renderJSX(result, value).then((output2) => { - if (output2.toString().trim().length === 0) return; - slots[key] = () => output2; - }) - ); - } - await Promise.all(slotPromises); - let output; - if (vnode.type === ClientOnlyPlaceholder && vnode.props["client:only"]) { - output = await renderComponentToString( - result, - vnode.props["client:display-name"] ?? "", - null, - props, - slots - ); - } else { - output = await renderComponentToString( - result, - typeof vnode.type === "function" ? vnode.type.name : vnode.type, - vnode.type, - props, - slots - ); - } - return markHTMLString(output); - } - } - return markHTMLString(`${vnode}`); -} -async function renderElement(result, tag, { children, ...props }) { - return markHTMLString( - `<${tag}${spreadAttributes(props)}${markHTMLString( - (children == null || children == "") && voidElementNames.test(tag) ? `/>` : `>${children == null ? "" : await renderJSX(result, prerenderElementChildren(tag, children))}` - )}` - ); -} -function prerenderElementChildren(tag, children) { - if (typeof children === "string" && (tag === "style" || tag === "script")) { - return markHTMLString(children); - } else { - return children; - } -} - -async function renderPage(result, componentFactory, props, children, streaming, route) { - if (!isAstroComponentFactory(componentFactory)) { - result._metadata.headInTree = result.componentMetadata.get(componentFactory.moduleId)?.containsHead ?? false; - const pageProps = { ...props ?? {}, "server:root": true }; - const str = await renderComponentToString( - result, - componentFactory.name, - componentFactory, - pageProps, - {}, - true, - route - ); - const bytes = encoder.encode(str); - const headers2 = new Headers([ - ["Content-Type", "text/html"], - ["Content-Length", bytes.byteLength.toString()] - ]); - if (result.shouldInjectCspMetaTags && (result.cspDestination === "header" || result.cspDestination === "adapter")) { - headers2.set("content-security-policy", renderCspContent(result)); - } - return new Response(bytes, { - headers: headers2 - }); - } - result._metadata.headInTree = result.componentMetadata.get(componentFactory.moduleId)?.containsHead ?? false; - let body; - if (streaming) { - if (isNode && !isDeno) { - const nodeBody = await renderToAsyncIterable( - result, - componentFactory, - props, - children, - true, - route - ); - body = nodeBody; - } else { - body = await renderToReadableStream(result, componentFactory, props, children, true, route); - } - } else { - body = await renderToString(result, componentFactory, props, children, true, route); - } - if (body instanceof Response) return body; - const init = result.response; - const headers = new Headers(init.headers); - if (result.shouldInjectCspMetaTags && result.cspDestination === "header" || result.cspDestination === "adapter") { - headers.set("content-security-policy", renderCspContent(result)); - } - if (!streaming && typeof body === "string") { - body = encoder.encode(body); - headers.set("Content-Length", body.byteLength.toString()); - } - let status = init.status; - let statusText = init.statusText; - if (route?.route === "/404") { - status = 404; - if (statusText === "OK") { - statusText = "Not Found"; - } - } else if (route?.route === "/500") { - status = 500; - if (statusText === "OK") { - statusText = "Internal Server Error"; - } - } - if (status) { - return new Response(body, { ...init, headers, status, statusText }); - } else { - return new Response(body, { ...init, headers }); - } -} - -"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_".split("").reduce((v, c) => (v[c.charCodeAt(0)] = c, v), []); -"-0123456789_".split("").reduce((v, c) => (v[c.charCodeAt(0)] = c, v), []); - -function spreadAttributes(values = {}, _name, { class: scopedClassName } = {}) { - let output = ""; - if (scopedClassName) { - if (typeof values.class !== "undefined") { - values.class += ` ${scopedClassName}`; - } else if (typeof values["class:list"] !== "undefined") { - values["class:list"] = [values["class:list"], scopedClassName]; - } else { - values.class = scopedClassName; - } - } - for (const [key, value] of Object.entries(values)) { - output += addAttribute(value, key, true, _name); - } - return markHTMLString(output); -} - -export { SessionStorageInitError as $, AstroError as A, MiddlewareNotAResponse as B, originPathnameSymbol as C, RewriteWithBodyUsed as D, ExpectedImage as E, FailedToFetchRemoteImageDimensions as F, GetStaticPathsRequired as G, InvalidGetStaticPathsReturn as H, IncompatibleDescriptorOptions as I, InvalidGetStaticPathsEntry as J, GetStaticPathsExpectedParams as K, LocalImageUsedWrongly as L, MissingImageDimension as M, NoImageMetadata as N, GetStaticPathsInvalidRouteParam as O, PageNumberParamNotFound as P, DEFAULT_404_COMPONENT as Q, ROUTE_TYPE_HEADER as R, NoMatchingStaticPathFound as S, PrerenderDynamicEndpointPathCollide as T, UnsupportedImageFormat as U, ReservedSlotName as V, renderSlotToString as W, renderJSX as X, chunkToString as Y, isRenderInstruction as Z, ForbiddenRewrite as _, UnsupportedImageConversion as a, SessionStorageSaveError as a0, ASTRO_VERSION as a1, CspNotEnabled as a2, LocalsReassigned as a3, generateCspDigest as a4, PrerenderClientAddressNotAvailable as a5, clientAddressSymbol as a6, ClientAddressNotAvailable as a7, StaticClientAddressNotAvailable as a8, AstroResponseHeadersReassigned as a9, responseSentSymbol as aa, renderPage as ab, REWRITE_DIRECTIVE_HEADER_KEY as ac, REWRITE_DIRECTIVE_HEADER_VALUE as ad, renderEndpoint as ae, LocalsNotAnObject as af, REROUTABLE_STATUS_CODES as ag, nodeRequestAbortControllerCleanupSymbol as ah, NOOP_MIDDLEWARE_HEADER as ai, REDIRECT_STATUS_CODES as aj, ActionsReturnedInvalidDataError as ak, MissingSharp as al, ExpectedImageOptions as b, ExpectedNotESMImage as c, InvalidImageService as d, createComponent as e, createAstro as f, ImageMissingAlt as g, addAttribute as h, ExperimentalFontsNotEnabled as i, FontFamilyNotFound as j, renderHead as k, decodeKey as l, maybeRenderHead as m, decryptString as n, createSlotValueFromString as o, isAstroComponentFactory as p, renderComponent as q, renderTemplate as r, spreadAttributes as s, toStyleString as t, unescapeHTML as u, REROUTE_DIRECTIVE_HEADER as v, i18nNoLocaleFoundInPath as w, ResponseSentError as x, ActionNotFoundError as y, MiddlewareNoDataOrNextCalled as z }; diff --git a/workbench/astro/dist/server/chunks/fs-lite_COtHaKzy.mjs b/workbench/astro/dist/server/chunks/fs-lite_COtHaKzy.mjs deleted file mode 100644 index 7dc736af8..000000000 --- a/workbench/astro/dist/server/chunks/fs-lite_COtHaKzy.mjs +++ /dev/null @@ -1,157 +0,0 @@ -import { promises, existsSync } from 'node:fs'; -import { resolve, dirname, join } from 'node:path'; - -function defineDriver(factory) { - return factory; -} -function createError(driver, message, opts) { - const err = new Error(`[unstorage] [${driver}] ${message}`, opts); - if (Error.captureStackTrace) { - Error.captureStackTrace(err, createError); - } - return err; -} -function createRequiredError(driver, name) { - if (Array.isArray(name)) { - return createError( - driver, - `Missing some of the required options ${name.map((n) => "`" + n + "`").join(", ")}` - ); - } - return createError(driver, `Missing required option \`${name}\`.`); -} - -function ignoreNotfound(err) { - return err.code === "ENOENT" || err.code === "EISDIR" ? null : err; -} -function ignoreExists(err) { - return err.code === "EEXIST" ? null : err; -} -async function writeFile(path, data, encoding) { - await ensuredir(dirname(path)); - return promises.writeFile(path, data, encoding); -} -function readFile(path, encoding) { - return promises.readFile(path, encoding).catch(ignoreNotfound); -} -function unlink(path) { - return promises.unlink(path).catch(ignoreNotfound); -} -function readdir(dir) { - return promises.readdir(dir, { withFileTypes: true }).catch(ignoreNotfound).then((r) => r || []); -} -async function ensuredir(dir) { - if (existsSync(dir)) { - return; - } - await ensuredir(dirname(dir)).catch(ignoreExists); - await promises.mkdir(dir).catch(ignoreExists); -} -async function readdirRecursive(dir, ignore, maxDepth) { - if (ignore && ignore(dir)) { - return []; - } - const entries = await readdir(dir); - const files = []; - await Promise.all( - entries.map(async (entry) => { - const entryPath = resolve(dir, entry.name); - if (entry.isDirectory()) { - if (maxDepth === void 0 || maxDepth > 0) { - const dirFiles = await readdirRecursive( - entryPath, - ignore, - maxDepth === void 0 ? void 0 : maxDepth - 1 - ); - files.push(...dirFiles.map((f) => entry.name + "/" + f)); - } - } else { - if (!(ignore && ignore(entry.name))) { - files.push(entry.name); - } - } - }) - ); - return files; -} -async function rmRecursive(dir) { - const entries = await readdir(dir); - await Promise.all( - entries.map((entry) => { - const entryPath = resolve(dir, entry.name); - if (entry.isDirectory()) { - return rmRecursive(entryPath).then(() => promises.rmdir(entryPath)); - } else { - return promises.unlink(entryPath); - } - }) - ); -} - -const PATH_TRAVERSE_RE = /\.\.:|\.\.$/; -const DRIVER_NAME = "fs-lite"; -const fsLite = defineDriver((opts = {}) => { - if (!opts.base) { - throw createRequiredError(DRIVER_NAME, "base"); - } - opts.base = resolve(opts.base); - const r = (key) => { - if (PATH_TRAVERSE_RE.test(key)) { - throw createError( - DRIVER_NAME, - `Invalid key: ${JSON.stringify(key)}. It should not contain .. segments` - ); - } - const resolved = join(opts.base, key.replace(/:/g, "/")); - return resolved; - }; - return { - name: DRIVER_NAME, - options: opts, - flags: { - maxDepth: true - }, - hasItem(key) { - return existsSync(r(key)); - }, - getItem(key) { - return readFile(r(key), "utf8"); - }, - getItemRaw(key) { - return readFile(r(key)); - }, - async getMeta(key) { - const { atime, mtime, size, birthtime, ctime } = await promises.stat(r(key)).catch(() => ({})); - return { atime, mtime, size, birthtime, ctime }; - }, - setItem(key, value) { - if (opts.readOnly) { - return; - } - return writeFile(r(key), value, "utf8"); - }, - setItemRaw(key, value) { - if (opts.readOnly) { - return; - } - return writeFile(r(key), value); - }, - removeItem(key) { - if (opts.readOnly) { - return; - } - return unlink(r(key)); - }, - getKeys(_base, topts) { - return readdirRecursive(r("."), opts.ignore, topts?.maxDepth); - }, - async clear() { - if (opts.readOnly || opts.noClear) { - return; - } - await rmRecursive(r(".")); - } - }; -}); - -export { fsLite as default }; diff --git a/workbench/astro/dist/server/chunks/index_DqQ8k47W.mjs b/workbench/astro/dist/server/chunks/index_DqQ8k47W.mjs deleted file mode 100644 index 46cd94fb3..000000000 --- a/workbench/astro/dist/server/chunks/index_DqQ8k47W.mjs +++ /dev/null @@ -1,2319 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** only globals that common to node and browsers are allowed */ -// eslint-disable-next-line node/no-unsupported-features/es-builtins -var _globalThis = typeof globalThis === 'object' ? globalThis : global; - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// this is autogenerated file, see scripts/version-update.js -var VERSION = '1.9.0'; - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -var re = /^(\d+)\.(\d+)\.(\d+)(-(.+))?$/; -/** - * Create a function to test an API version to see if it is compatible with the provided ownVersion. - * - * The returned function has the following semantics: - * - Exact match is always compatible - * - Major versions must match exactly - * - 1.x package cannot use global 2.x package - * - 2.x package cannot use global 1.x package - * - The minor version of the API module requesting access to the global API must be less than or equal to the minor version of this API - * - 1.3 package may use 1.4 global because the later global contains all functions 1.3 expects - * - 1.4 package may NOT use 1.3 global because it may try to call functions which don't exist on 1.3 - * - If the major version is 0, the minor version is treated as the major and the patch is treated as the minor - * - Patch and build tag differences are not considered at this time - * - * @param ownVersion version which should be checked against - */ -function _makeCompatibilityCheck(ownVersion) { - var acceptedVersions = new Set([ownVersion]); - var rejectedVersions = new Set(); - var myVersionMatch = ownVersion.match(re); - if (!myVersionMatch) { - // we cannot guarantee compatibility so we always return noop - return function () { return false; }; - } - var ownVersionParsed = { - major: +myVersionMatch[1], - minor: +myVersionMatch[2], - patch: +myVersionMatch[3], - prerelease: myVersionMatch[4], - }; - // if ownVersion has a prerelease tag, versions must match exactly - if (ownVersionParsed.prerelease != null) { - return function isExactmatch(globalVersion) { - return globalVersion === ownVersion; - }; - } - function _reject(v) { - rejectedVersions.add(v); - return false; - } - function _accept(v) { - acceptedVersions.add(v); - return true; - } - return function isCompatible(globalVersion) { - if (acceptedVersions.has(globalVersion)) { - return true; - } - if (rejectedVersions.has(globalVersion)) { - return false; - } - var globalVersionMatch = globalVersion.match(re); - if (!globalVersionMatch) { - // cannot parse other version - // we cannot guarantee compatibility so we always noop - return _reject(globalVersion); - } - var globalVersionParsed = { - major: +globalVersionMatch[1], - minor: +globalVersionMatch[2], - patch: +globalVersionMatch[3], - prerelease: globalVersionMatch[4], - }; - // if globalVersion has a prerelease tag, versions must match exactly - if (globalVersionParsed.prerelease != null) { - return _reject(globalVersion); - } - // major versions must match - if (ownVersionParsed.major !== globalVersionParsed.major) { - return _reject(globalVersion); - } - if (ownVersionParsed.major === 0) { - if (ownVersionParsed.minor === globalVersionParsed.minor && - ownVersionParsed.patch <= globalVersionParsed.patch) { - return _accept(globalVersion); - } - return _reject(globalVersion); - } - if (ownVersionParsed.minor <= globalVersionParsed.minor) { - return _accept(globalVersion); - } - return _reject(globalVersion); - }; -} -/** - * Test an API version to see if it is compatible with this API. - * - * - Exact match is always compatible - * - Major versions must match exactly - * - 1.x package cannot use global 2.x package - * - 2.x package cannot use global 1.x package - * - The minor version of the API module requesting access to the global API must be less than or equal to the minor version of this API - * - 1.3 package may use 1.4 global because the later global contains all functions 1.3 expects - * - 1.4 package may NOT use 1.3 global because it may try to call functions which don't exist on 1.3 - * - If the major version is 0, the minor version is treated as the major and the patch is treated as the minor - * - Patch and build tag differences are not considered at this time - * - * @param version version of the API requesting an instance of the global API - */ -var isCompatible = _makeCompatibilityCheck(VERSION); - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -var major = VERSION.split('.')[0]; -var GLOBAL_OPENTELEMETRY_API_KEY = Symbol.for("opentelemetry.js.api." + major); -var _global = _globalThis; -function registerGlobal(type, instance, diag, allowOverride) { - var _a; - if (allowOverride === void 0) { allowOverride = false; } - var api = (_global[GLOBAL_OPENTELEMETRY_API_KEY] = (_a = _global[GLOBAL_OPENTELEMETRY_API_KEY]) !== null && _a !== void 0 ? _a : { - version: VERSION, - }); - if (!allowOverride && api[type]) { - // already registered an API of this type - var err = new Error("@opentelemetry/api: Attempted duplicate registration of API: " + type); - diag.error(err.stack || err.message); - return false; - } - if (api.version !== VERSION) { - // All registered APIs must be of the same version exactly - var err = new Error("@opentelemetry/api: Registration of version v" + api.version + " for " + type + " does not match previously registered API v" + VERSION); - diag.error(err.stack || err.message); - return false; - } - api[type] = instance; - diag.debug("@opentelemetry/api: Registered a global for " + type + " v" + VERSION + "."); - return true; -} -function getGlobal(type) { - var _a, _b; - var globalVersion = (_a = _global[GLOBAL_OPENTELEMETRY_API_KEY]) === null || _a === void 0 ? void 0 : _a.version; - if (!globalVersion || !isCompatible(globalVersion)) { - return; - } - return (_b = _global[GLOBAL_OPENTELEMETRY_API_KEY]) === null || _b === void 0 ? void 0 : _b[type]; -} -function unregisterGlobal(type, diag) { - diag.debug("@opentelemetry/api: Unregistering a global for " + type + " v" + VERSION + "."); - var api = _global[GLOBAL_OPENTELEMETRY_API_KEY]; - if (api) { - delete api[type]; - } -} - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -var __read$4 = (undefined && undefined.__read) || function (o, n) { - var m = typeof Symbol === "function" && o[Symbol.iterator]; - if (!m) return o; - var i = m.call(o), r, ar = [], e; - try { - while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); - } - catch (error) { e = { error: error }; } - finally { - try { - if (r && !r.done && (m = i["return"])) m.call(i); - } - finally { if (e) throw e.error; } - } - return ar; -}; -var __spreadArray$3 = (undefined && undefined.__spreadArray) || function (to, from, pack) { - if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { - if (ar || !(i in from)) { - if (!ar) ar = Array.prototype.slice.call(from, 0, i); - ar[i] = from[i]; - } - } - return to.concat(ar || Array.prototype.slice.call(from)); -}; -/** - * Component Logger which is meant to be used as part of any component which - * will add automatically additional namespace in front of the log message. - * It will then forward all message to global diag logger - * @example - * const cLogger = diag.createComponentLogger({ namespace: '@opentelemetry/instrumentation-http' }); - * cLogger.debug('test'); - * // @opentelemetry/instrumentation-http test - */ -var DiagComponentLogger = /** @class */ (function () { - function DiagComponentLogger(props) { - this._namespace = props.namespace || 'DiagComponentLogger'; - } - DiagComponentLogger.prototype.debug = function () { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - return logProxy('debug', this._namespace, args); - }; - DiagComponentLogger.prototype.error = function () { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - return logProxy('error', this._namespace, args); - }; - DiagComponentLogger.prototype.info = function () { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - return logProxy('info', this._namespace, args); - }; - DiagComponentLogger.prototype.warn = function () { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - return logProxy('warn', this._namespace, args); - }; - DiagComponentLogger.prototype.verbose = function () { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - return logProxy('verbose', this._namespace, args); - }; - return DiagComponentLogger; -}()); -function logProxy(funcName, namespace, args) { - var logger = getGlobal('diag'); - // shortcut if logger not set - if (!logger) { - return; - } - args.unshift(namespace); - return logger[funcName].apply(logger, __spreadArray$3([], __read$4(args), false)); -} - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Defines the available internal logging levels for the diagnostic logger, the numeric values - * of the levels are defined to match the original values from the initial LogLevel to avoid - * compatibility/migration issues for any implementation that assume the numeric ordering. - */ -var DiagLogLevel; -(function (DiagLogLevel) { - /** Diagnostic Logging level setting to disable all logging (except and forced logs) */ - DiagLogLevel[DiagLogLevel["NONE"] = 0] = "NONE"; - /** Identifies an error scenario */ - DiagLogLevel[DiagLogLevel["ERROR"] = 30] = "ERROR"; - /** Identifies a warning scenario */ - DiagLogLevel[DiagLogLevel["WARN"] = 50] = "WARN"; - /** General informational log message */ - DiagLogLevel[DiagLogLevel["INFO"] = 60] = "INFO"; - /** General debug log message */ - DiagLogLevel[DiagLogLevel["DEBUG"] = 70] = "DEBUG"; - /** - * Detailed trace level logging should only be used for development, should only be set - * in a development environment. - */ - DiagLogLevel[DiagLogLevel["VERBOSE"] = 80] = "VERBOSE"; - /** Used to set the logging level to include all logging */ - DiagLogLevel[DiagLogLevel["ALL"] = 9999] = "ALL"; -})(DiagLogLevel || (DiagLogLevel = {})); - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -function createLogLevelDiagLogger(maxLevel, logger) { - if (maxLevel < DiagLogLevel.NONE) { - maxLevel = DiagLogLevel.NONE; - } - else if (maxLevel > DiagLogLevel.ALL) { - maxLevel = DiagLogLevel.ALL; - } - // In case the logger is null or undefined - logger = logger || {}; - function _filterFunc(funcName, theLevel) { - var theFunc = logger[funcName]; - if (typeof theFunc === 'function' && maxLevel >= theLevel) { - return theFunc.bind(logger); - } - return function () { }; - } - return { - error: _filterFunc('error', DiagLogLevel.ERROR), - warn: _filterFunc('warn', DiagLogLevel.WARN), - info: _filterFunc('info', DiagLogLevel.INFO), - debug: _filterFunc('debug', DiagLogLevel.DEBUG), - verbose: _filterFunc('verbose', DiagLogLevel.VERBOSE), - }; -} - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -var __read$3 = (undefined && undefined.__read) || function (o, n) { - var m = typeof Symbol === "function" && o[Symbol.iterator]; - if (!m) return o; - var i = m.call(o), r, ar = [], e; - try { - while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); - } - catch (error) { e = { error: error }; } - finally { - try { - if (r && !r.done && (m = i["return"])) m.call(i); - } - finally { if (e) throw e.error; } - } - return ar; -}; -var __spreadArray$2 = (undefined && undefined.__spreadArray) || function (to, from, pack) { - if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { - if (ar || !(i in from)) { - if (!ar) ar = Array.prototype.slice.call(from, 0, i); - ar[i] = from[i]; - } - } - return to.concat(ar || Array.prototype.slice.call(from)); -}; -var API_NAME$4 = 'diag'; -/** - * Singleton object which represents the entry point to the OpenTelemetry internal - * diagnostic API - */ -var DiagAPI = /** @class */ (function () { - /** - * Private internal constructor - * @private - */ - function DiagAPI() { - function _logProxy(funcName) { - return function () { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - var logger = getGlobal('diag'); - // shortcut if logger not set - if (!logger) - return; - return logger[funcName].apply(logger, __spreadArray$2([], __read$3(args), false)); - }; - } - // Using self local variable for minification purposes as 'this' cannot be minified - var self = this; - // DiagAPI specific functions - var setLogger = function (logger, optionsOrLogLevel) { - var _a, _b, _c; - if (optionsOrLogLevel === void 0) { optionsOrLogLevel = { logLevel: DiagLogLevel.INFO }; } - if (logger === self) { - // There isn't much we can do here. - // Logging to the console might break the user application. - // Try to log to self. If a logger was previously registered it will receive the log. - var err = new Error('Cannot use diag as the logger for itself. Please use a DiagLogger implementation like ConsoleDiagLogger or a custom implementation'); - self.error((_a = err.stack) !== null && _a !== void 0 ? _a : err.message); - return false; - } - if (typeof optionsOrLogLevel === 'number') { - optionsOrLogLevel = { - logLevel: optionsOrLogLevel, - }; - } - var oldLogger = getGlobal('diag'); - var newLogger = createLogLevelDiagLogger((_b = optionsOrLogLevel.logLevel) !== null && _b !== void 0 ? _b : DiagLogLevel.INFO, logger); - // There already is an logger registered. We'll let it know before overwriting it. - if (oldLogger && !optionsOrLogLevel.suppressOverrideMessage) { - var stack = (_c = new Error().stack) !== null && _c !== void 0 ? _c : ''; - oldLogger.warn("Current logger will be overwritten from " + stack); - newLogger.warn("Current logger will overwrite one already registered from " + stack); - } - return registerGlobal('diag', newLogger, self, true); - }; - self.setLogger = setLogger; - self.disable = function () { - unregisterGlobal(API_NAME$4, self); - }; - self.createComponentLogger = function (options) { - return new DiagComponentLogger(options); - }; - self.verbose = _logProxy('verbose'); - self.debug = _logProxy('debug'); - self.info = _logProxy('info'); - self.warn = _logProxy('warn'); - self.error = _logProxy('error'); - } - /** Get the singleton instance of the DiagAPI API */ - DiagAPI.instance = function () { - if (!this._instance) { - this._instance = new DiagAPI(); - } - return this._instance; - }; - return DiagAPI; -}()); - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -var __read$2 = (undefined && undefined.__read) || function (o, n) { - var m = typeof Symbol === "function" && o[Symbol.iterator]; - if (!m) return o; - var i = m.call(o), r, ar = [], e; - try { - while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); - } - catch (error) { e = { error: error }; } - finally { - try { - if (r && !r.done && (m = i["return"])) m.call(i); - } - finally { if (e) throw e.error; } - } - return ar; -}; -var __values = (undefined && undefined.__values) || function(o) { - var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; - if (m) return m.call(o); - if (o && typeof o.length === "number") return { - next: function () { - if (o && i >= o.length) o = void 0; - return { value: o && o[i++], done: !o }; - } - }; - throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); -}; -var BaggageImpl = /** @class */ (function () { - function BaggageImpl(entries) { - this._entries = entries ? new Map(entries) : new Map(); - } - BaggageImpl.prototype.getEntry = function (key) { - var entry = this._entries.get(key); - if (!entry) { - return undefined; - } - return Object.assign({}, entry); - }; - BaggageImpl.prototype.getAllEntries = function () { - return Array.from(this._entries.entries()).map(function (_a) { - var _b = __read$2(_a, 2), k = _b[0], v = _b[1]; - return [k, v]; - }); - }; - BaggageImpl.prototype.setEntry = function (key, entry) { - var newBaggage = new BaggageImpl(this._entries); - newBaggage._entries.set(key, entry); - return newBaggage; - }; - BaggageImpl.prototype.removeEntry = function (key) { - var newBaggage = new BaggageImpl(this._entries); - newBaggage._entries.delete(key); - return newBaggage; - }; - BaggageImpl.prototype.removeEntries = function () { - var e_1, _a; - var keys = []; - for (var _i = 0; _i < arguments.length; _i++) { - keys[_i] = arguments[_i]; - } - var newBaggage = new BaggageImpl(this._entries); - try { - for (var keys_1 = __values(keys), keys_1_1 = keys_1.next(); !keys_1_1.done; keys_1_1 = keys_1.next()) { - var key = keys_1_1.value; - newBaggage._entries.delete(key); - } - } - catch (e_1_1) { e_1 = { error: e_1_1 }; } - finally { - try { - if (keys_1_1 && !keys_1_1.done && (_a = keys_1.return)) _a.call(keys_1); - } - finally { if (e_1) throw e_1.error; } - } - return newBaggage; - }; - BaggageImpl.prototype.clear = function () { - return new BaggageImpl(); - }; - return BaggageImpl; -}()); - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Symbol used to make BaggageEntryMetadata an opaque type - */ -var baggageEntryMetadataSymbol = Symbol('BaggageEntryMetadata'); - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -var diag$1 = DiagAPI.instance(); -/** - * Create a new Baggage with optional entries - * - * @param entries An array of baggage entries the new baggage should contain - */ -function createBaggage(entries) { - if (entries === void 0) { entries = {}; } - return new BaggageImpl(new Map(Object.entries(entries))); -} -/** - * Create a serializable BaggageEntryMetadata object from a string. - * - * @param str string metadata. Format is currently not defined by the spec and has no special meaning. - * - */ -function baggageEntryMetadataFromString(str) { - if (typeof str !== 'string') { - diag$1.error("Cannot create baggage metadata from unknown type: " + typeof str); - str = ''; - } - return { - __TYPE__: baggageEntryMetadataSymbol, - toString: function () { - return str; - }, - }; -} - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** Get a key to uniquely identify a context value */ -function createContextKey(description) { - // The specification states that for the same input, multiple calls should - // return different keys. Due to the nature of the JS dependency management - // system, this creates problems where multiple versions of some package - // could hold different keys for the same property. - // - // Therefore, we use Symbol.for which returns the same key for the same input. - return Symbol.for(description); -} -var BaseContext = /** @class */ (function () { - /** - * Construct a new context which inherits values from an optional parent context. - * - * @param parentContext a context from which to inherit values - */ - function BaseContext(parentContext) { - // for minification - var self = this; - self._currentContext = parentContext ? new Map(parentContext) : new Map(); - self.getValue = function (key) { return self._currentContext.get(key); }; - self.setValue = function (key, value) { - var context = new BaseContext(self._currentContext); - context._currentContext.set(key, value); - return context; - }; - self.deleteValue = function (key) { - var context = new BaseContext(self._currentContext); - context._currentContext.delete(key); - return context; - }; - } - return BaseContext; -}()); -/** The root context is used as the default parent context when there is no active context */ -var ROOT_CONTEXT = new BaseContext(); - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -var consoleMap = [ - { n: 'error', c: 'error' }, - { n: 'warn', c: 'warn' }, - { n: 'info', c: 'info' }, - { n: 'debug', c: 'debug' }, - { n: 'verbose', c: 'trace' }, -]; -/** - * A simple Immutable Console based diagnostic logger which will output any messages to the Console. - * If you want to limit the amount of logging to a specific level or lower use the - * {@link createLogLevelDiagLogger} - */ -var DiagConsoleLogger = /** @class */ (function () { - function DiagConsoleLogger() { - function _consoleFunc(funcName) { - return function () { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - if (console) { - // Some environments only expose the console when the F12 developer console is open - // eslint-disable-next-line no-console - var theFunc = console[funcName]; - if (typeof theFunc !== 'function') { - // Not all environments support all functions - // eslint-disable-next-line no-console - theFunc = console.log; - } - // One last final check - if (typeof theFunc === 'function') { - return theFunc.apply(console, args); - } - } - }; - } - for (var i = 0; i < consoleMap.length; i++) { - this[consoleMap[i].n] = _consoleFunc(consoleMap[i].c); - } - } - return DiagConsoleLogger; -}()); - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -var __extends = (undefined && undefined.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - if (typeof b !== "function" && b !== null) - throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -/** - * NoopMeter is a noop implementation of the {@link Meter} interface. It reuses - * constant NoopMetrics for all of its methods. - */ -var NoopMeter = /** @class */ (function () { - function NoopMeter() { - } - /** - * @see {@link Meter.createGauge} - */ - NoopMeter.prototype.createGauge = function (_name, _options) { - return NOOP_GAUGE_METRIC; - }; - /** - * @see {@link Meter.createHistogram} - */ - NoopMeter.prototype.createHistogram = function (_name, _options) { - return NOOP_HISTOGRAM_METRIC; - }; - /** - * @see {@link Meter.createCounter} - */ - NoopMeter.prototype.createCounter = function (_name, _options) { - return NOOP_COUNTER_METRIC; - }; - /** - * @see {@link Meter.createUpDownCounter} - */ - NoopMeter.prototype.createUpDownCounter = function (_name, _options) { - return NOOP_UP_DOWN_COUNTER_METRIC; - }; - /** - * @see {@link Meter.createObservableGauge} - */ - NoopMeter.prototype.createObservableGauge = function (_name, _options) { - return NOOP_OBSERVABLE_GAUGE_METRIC; - }; - /** - * @see {@link Meter.createObservableCounter} - */ - NoopMeter.prototype.createObservableCounter = function (_name, _options) { - return NOOP_OBSERVABLE_COUNTER_METRIC; - }; - /** - * @see {@link Meter.createObservableUpDownCounter} - */ - NoopMeter.prototype.createObservableUpDownCounter = function (_name, _options) { - return NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC; - }; - /** - * @see {@link Meter.addBatchObservableCallback} - */ - NoopMeter.prototype.addBatchObservableCallback = function (_callback, _observables) { }; - /** - * @see {@link Meter.removeBatchObservableCallback} - */ - NoopMeter.prototype.removeBatchObservableCallback = function (_callback) { }; - return NoopMeter; -}()); -var NoopMetric = /** @class */ (function () { - function NoopMetric() { - } - return NoopMetric; -}()); -var NoopCounterMetric = /** @class */ (function (_super) { - __extends(NoopCounterMetric, _super); - function NoopCounterMetric() { - return _super !== null && _super.apply(this, arguments) || this; - } - NoopCounterMetric.prototype.add = function (_value, _attributes) { }; - return NoopCounterMetric; -}(NoopMetric)); -var NoopUpDownCounterMetric = /** @class */ (function (_super) { - __extends(NoopUpDownCounterMetric, _super); - function NoopUpDownCounterMetric() { - return _super !== null && _super.apply(this, arguments) || this; - } - NoopUpDownCounterMetric.prototype.add = function (_value, _attributes) { }; - return NoopUpDownCounterMetric; -}(NoopMetric)); -var NoopGaugeMetric = /** @class */ (function (_super) { - __extends(NoopGaugeMetric, _super); - function NoopGaugeMetric() { - return _super !== null && _super.apply(this, arguments) || this; - } - NoopGaugeMetric.prototype.record = function (_value, _attributes) { }; - return NoopGaugeMetric; -}(NoopMetric)); -var NoopHistogramMetric = /** @class */ (function (_super) { - __extends(NoopHistogramMetric, _super); - function NoopHistogramMetric() { - return _super !== null && _super.apply(this, arguments) || this; - } - NoopHistogramMetric.prototype.record = function (_value, _attributes) { }; - return NoopHistogramMetric; -}(NoopMetric)); -var NoopObservableMetric = /** @class */ (function () { - function NoopObservableMetric() { - } - NoopObservableMetric.prototype.addCallback = function (_callback) { }; - NoopObservableMetric.prototype.removeCallback = function (_callback) { }; - return NoopObservableMetric; -}()); -var NoopObservableCounterMetric = /** @class */ (function (_super) { - __extends(NoopObservableCounterMetric, _super); - function NoopObservableCounterMetric() { - return _super !== null && _super.apply(this, arguments) || this; - } - return NoopObservableCounterMetric; -}(NoopObservableMetric)); -var NoopObservableGaugeMetric = /** @class */ (function (_super) { - __extends(NoopObservableGaugeMetric, _super); - function NoopObservableGaugeMetric() { - return _super !== null && _super.apply(this, arguments) || this; - } - return NoopObservableGaugeMetric; -}(NoopObservableMetric)); -var NoopObservableUpDownCounterMetric = /** @class */ (function (_super) { - __extends(NoopObservableUpDownCounterMetric, _super); - function NoopObservableUpDownCounterMetric() { - return _super !== null && _super.apply(this, arguments) || this; - } - return NoopObservableUpDownCounterMetric; -}(NoopObservableMetric)); -var NOOP_METER = new NoopMeter(); -// Synchronous instruments -var NOOP_COUNTER_METRIC = new NoopCounterMetric(); -var NOOP_GAUGE_METRIC = new NoopGaugeMetric(); -var NOOP_HISTOGRAM_METRIC = new NoopHistogramMetric(); -var NOOP_UP_DOWN_COUNTER_METRIC = new NoopUpDownCounterMetric(); -// Asynchronous instruments -var NOOP_OBSERVABLE_COUNTER_METRIC = new NoopObservableCounterMetric(); -var NOOP_OBSERVABLE_GAUGE_METRIC = new NoopObservableGaugeMetric(); -var NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC = new NoopObservableUpDownCounterMetric(); -/** - * Create a no-op Meter - */ -function createNoopMeter() { - return NOOP_METER; -} - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** The Type of value. It describes how the data is reported. */ -var ValueType; -(function (ValueType) { - ValueType[ValueType["INT"] = 0] = "INT"; - ValueType[ValueType["DOUBLE"] = 1] = "DOUBLE"; -})(ValueType || (ValueType = {})); - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -var defaultTextMapGetter = { - get: function (carrier, key) { - if (carrier == null) { - return undefined; - } - return carrier[key]; - }, - keys: function (carrier) { - if (carrier == null) { - return []; - } - return Object.keys(carrier); - }, -}; -var defaultTextMapSetter = { - set: function (carrier, key, value) { - if (carrier == null) { - return; - } - carrier[key] = value; - }, -}; - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -var __read$1 = (undefined && undefined.__read) || function (o, n) { - var m = typeof Symbol === "function" && o[Symbol.iterator]; - if (!m) return o; - var i = m.call(o), r, ar = [], e; - try { - while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); - } - catch (error) { e = { error: error }; } - finally { - try { - if (r && !r.done && (m = i["return"])) m.call(i); - } - finally { if (e) throw e.error; } - } - return ar; -}; -var __spreadArray$1 = (undefined && undefined.__spreadArray) || function (to, from, pack) { - if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { - if (ar || !(i in from)) { - if (!ar) ar = Array.prototype.slice.call(from, 0, i); - ar[i] = from[i]; - } - } - return to.concat(ar || Array.prototype.slice.call(from)); -}; -var NoopContextManager = /** @class */ (function () { - function NoopContextManager() { - } - NoopContextManager.prototype.active = function () { - return ROOT_CONTEXT; - }; - NoopContextManager.prototype.with = function (_context, fn, thisArg) { - var args = []; - for (var _i = 3; _i < arguments.length; _i++) { - args[_i - 3] = arguments[_i]; - } - return fn.call.apply(fn, __spreadArray$1([thisArg], __read$1(args), false)); - }; - NoopContextManager.prototype.bind = function (_context, target) { - return target; - }; - NoopContextManager.prototype.enable = function () { - return this; - }; - NoopContextManager.prototype.disable = function () { - return this; - }; - return NoopContextManager; -}()); - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -var __read = (undefined && undefined.__read) || function (o, n) { - var m = typeof Symbol === "function" && o[Symbol.iterator]; - if (!m) return o; - var i = m.call(o), r, ar = [], e; - try { - while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); - } - catch (error) { e = { error: error }; } - finally { - try { - if (r && !r.done && (m = i["return"])) m.call(i); - } - finally { if (e) throw e.error; } - } - return ar; -}; -var __spreadArray = (undefined && undefined.__spreadArray) || function (to, from, pack) { - if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { - if (ar || !(i in from)) { - if (!ar) ar = Array.prototype.slice.call(from, 0, i); - ar[i] = from[i]; - } - } - return to.concat(ar || Array.prototype.slice.call(from)); -}; -var API_NAME$3 = 'context'; -var NOOP_CONTEXT_MANAGER = new NoopContextManager(); -/** - * Singleton object which represents the entry point to the OpenTelemetry Context API - */ -var ContextAPI = /** @class */ (function () { - /** Empty private constructor prevents end users from constructing a new instance of the API */ - function ContextAPI() { - } - /** Get the singleton instance of the Context API */ - ContextAPI.getInstance = function () { - if (!this._instance) { - this._instance = new ContextAPI(); - } - return this._instance; - }; - /** - * Set the current context manager. - * - * @returns true if the context manager was successfully registered, else false - */ - ContextAPI.prototype.setGlobalContextManager = function (contextManager) { - return registerGlobal(API_NAME$3, contextManager, DiagAPI.instance()); - }; - /** - * Get the currently active context - */ - ContextAPI.prototype.active = function () { - return this._getContextManager().active(); - }; - /** - * Execute a function with an active context - * - * @param context context to be active during function execution - * @param fn function to execute in a context - * @param thisArg optional receiver to be used for calling fn - * @param args optional arguments forwarded to fn - */ - ContextAPI.prototype.with = function (context, fn, thisArg) { - var _a; - var args = []; - for (var _i = 3; _i < arguments.length; _i++) { - args[_i - 3] = arguments[_i]; - } - return (_a = this._getContextManager()).with.apply(_a, __spreadArray([context, fn, thisArg], __read(args), false)); - }; - /** - * Bind a context to a target function or event emitter - * - * @param context context to bind to the event emitter or function. Defaults to the currently active context - * @param target function or event emitter to bind - */ - ContextAPI.prototype.bind = function (context, target) { - return this._getContextManager().bind(context, target); - }; - ContextAPI.prototype._getContextManager = function () { - return getGlobal(API_NAME$3) || NOOP_CONTEXT_MANAGER; - }; - /** Disable and remove the global context manager */ - ContextAPI.prototype.disable = function () { - this._getContextManager().disable(); - unregisterGlobal(API_NAME$3, DiagAPI.instance()); - }; - return ContextAPI; -}()); - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -var TraceFlags; -(function (TraceFlags) { - /** Represents no flag set. */ - TraceFlags[TraceFlags["NONE"] = 0] = "NONE"; - /** Bit to represent whether trace is sampled in trace flags. */ - TraceFlags[TraceFlags["SAMPLED"] = 1] = "SAMPLED"; -})(TraceFlags || (TraceFlags = {})); - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -var INVALID_SPANID = '0000000000000000'; -var INVALID_TRACEID = '00000000000000000000000000000000'; -var INVALID_SPAN_CONTEXT = { - traceId: INVALID_TRACEID, - spanId: INVALID_SPANID, - traceFlags: TraceFlags.NONE, -}; - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * The NonRecordingSpan is the default {@link Span} that is used when no Span - * implementation is available. All operations are no-op including context - * propagation. - */ -var NonRecordingSpan = /** @class */ (function () { - function NonRecordingSpan(_spanContext) { - if (_spanContext === void 0) { _spanContext = INVALID_SPAN_CONTEXT; } - this._spanContext = _spanContext; - } - // Returns a SpanContext. - NonRecordingSpan.prototype.spanContext = function () { - return this._spanContext; - }; - // By default does nothing - NonRecordingSpan.prototype.setAttribute = function (_key, _value) { - return this; - }; - // By default does nothing - NonRecordingSpan.prototype.setAttributes = function (_attributes) { - return this; - }; - // By default does nothing - NonRecordingSpan.prototype.addEvent = function (_name, _attributes) { - return this; - }; - NonRecordingSpan.prototype.addLink = function (_link) { - return this; - }; - NonRecordingSpan.prototype.addLinks = function (_links) { - return this; - }; - // By default does nothing - NonRecordingSpan.prototype.setStatus = function (_status) { - return this; - }; - // By default does nothing - NonRecordingSpan.prototype.updateName = function (_name) { - return this; - }; - // By default does nothing - NonRecordingSpan.prototype.end = function (_endTime) { }; - // isRecording always returns false for NonRecordingSpan. - NonRecordingSpan.prototype.isRecording = function () { - return false; - }; - // By default does nothing - NonRecordingSpan.prototype.recordException = function (_exception, _time) { }; - return NonRecordingSpan; -}()); - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * span key - */ -var SPAN_KEY = createContextKey('OpenTelemetry Context Key SPAN'); -/** - * Return the span if one exists - * - * @param context context to get span from - */ -function getSpan(context) { - return context.getValue(SPAN_KEY) || undefined; -} -/** - * Gets the span from the current context, if one exists. - */ -function getActiveSpan() { - return getSpan(ContextAPI.getInstance().active()); -} -/** - * Set the span on a context - * - * @param context context to use as parent - * @param span span to set active - */ -function setSpan(context, span) { - return context.setValue(SPAN_KEY, span); -} -/** - * Remove current span stored in the context - * - * @param context context to delete span from - */ -function deleteSpan(context) { - return context.deleteValue(SPAN_KEY); -} -/** - * Wrap span context in a NoopSpan and set as span in a new - * context - * - * @param context context to set active span on - * @param spanContext span context to be wrapped - */ -function setSpanContext(context, spanContext) { - return setSpan(context, new NonRecordingSpan(spanContext)); -} -/** - * Get the span context of the span if it exists. - * - * @param context context to get values from - */ -function getSpanContext(context) { - var _a; - return (_a = getSpan(context)) === null || _a === void 0 ? void 0 : _a.spanContext(); -} - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -var VALID_TRACEID_REGEX = /^([0-9a-f]{32})$/i; -var VALID_SPANID_REGEX = /^[0-9a-f]{16}$/i; -function isValidTraceId(traceId) { - return VALID_TRACEID_REGEX.test(traceId) && traceId !== INVALID_TRACEID; -} -function isValidSpanId(spanId) { - return VALID_SPANID_REGEX.test(spanId) && spanId !== INVALID_SPANID; -} -/** - * Returns true if this {@link SpanContext} is valid. - * @return true if this {@link SpanContext} is valid. - */ -function isSpanContextValid(spanContext) { - return (isValidTraceId(spanContext.traceId) && isValidSpanId(spanContext.spanId)); -} -/** - * Wrap the given {@link SpanContext} in a new non-recording {@link Span} - * - * @param spanContext span context to be wrapped - * @returns a new non-recording {@link Span} with the provided context - */ -function wrapSpanContext(spanContext) { - return new NonRecordingSpan(spanContext); -} - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -var contextApi = ContextAPI.getInstance(); -/** - * No-op implementations of {@link Tracer}. - */ -var NoopTracer = /** @class */ (function () { - function NoopTracer() { - } - // startSpan starts a noop span. - NoopTracer.prototype.startSpan = function (name, options, context) { - if (context === void 0) { context = contextApi.active(); } - var root = Boolean(options === null || options === void 0 ? void 0 : options.root); - if (root) { - return new NonRecordingSpan(); - } - var parentFromContext = context && getSpanContext(context); - if (isSpanContext(parentFromContext) && - isSpanContextValid(parentFromContext)) { - return new NonRecordingSpan(parentFromContext); - } - else { - return new NonRecordingSpan(); - } - }; - NoopTracer.prototype.startActiveSpan = function (name, arg2, arg3, arg4) { - var opts; - var ctx; - var fn; - if (arguments.length < 2) { - return; - } - else if (arguments.length === 2) { - fn = arg2; - } - else if (arguments.length === 3) { - opts = arg2; - fn = arg3; - } - else { - opts = arg2; - ctx = arg3; - fn = arg4; - } - var parentContext = ctx !== null && ctx !== void 0 ? ctx : contextApi.active(); - var span = this.startSpan(name, opts, parentContext); - var contextWithSpanSet = setSpan(parentContext, span); - return contextApi.with(contextWithSpanSet, fn, undefined, span); - }; - return NoopTracer; -}()); -function isSpanContext(spanContext) { - return (typeof spanContext === 'object' && - typeof spanContext['spanId'] === 'string' && - typeof spanContext['traceId'] === 'string' && - typeof spanContext['traceFlags'] === 'number'); -} - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -var NOOP_TRACER = new NoopTracer(); -/** - * Proxy tracer provided by the proxy tracer provider - */ -var ProxyTracer = /** @class */ (function () { - function ProxyTracer(_provider, name, version, options) { - this._provider = _provider; - this.name = name; - this.version = version; - this.options = options; - } - ProxyTracer.prototype.startSpan = function (name, options, context) { - return this._getTracer().startSpan(name, options, context); - }; - ProxyTracer.prototype.startActiveSpan = function (_name, _options, _context, _fn) { - var tracer = this._getTracer(); - return Reflect.apply(tracer.startActiveSpan, tracer, arguments); - }; - /** - * Try to get a tracer from the proxy tracer provider. - * If the proxy tracer provider has no delegate, return a noop tracer. - */ - ProxyTracer.prototype._getTracer = function () { - if (this._delegate) { - return this._delegate; - } - var tracer = this._provider.getDelegateTracer(this.name, this.version, this.options); - if (!tracer) { - return NOOP_TRACER; - } - this._delegate = tracer; - return this._delegate; - }; - return ProxyTracer; -}()); - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * An implementation of the {@link TracerProvider} which returns an impotent - * Tracer for all calls to `getTracer`. - * - * All operations are no-op. - */ -var NoopTracerProvider = /** @class */ (function () { - function NoopTracerProvider() { - } - NoopTracerProvider.prototype.getTracer = function (_name, _version, _options) { - return new NoopTracer(); - }; - return NoopTracerProvider; -}()); - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -var NOOP_TRACER_PROVIDER = new NoopTracerProvider(); -/** - * Tracer provider which provides {@link ProxyTracer}s. - * - * Before a delegate is set, tracers provided are NoOp. - * When a delegate is set, traces are provided from the delegate. - * When a delegate is set after tracers have already been provided, - * all tracers already provided will use the provided delegate implementation. - */ -var ProxyTracerProvider = /** @class */ (function () { - function ProxyTracerProvider() { - } - /** - * Get a {@link ProxyTracer} - */ - ProxyTracerProvider.prototype.getTracer = function (name, version, options) { - var _a; - return ((_a = this.getDelegateTracer(name, version, options)) !== null && _a !== void 0 ? _a : new ProxyTracer(this, name, version, options)); - }; - ProxyTracerProvider.prototype.getDelegate = function () { - var _a; - return (_a = this._delegate) !== null && _a !== void 0 ? _a : NOOP_TRACER_PROVIDER; - }; - /** - * Set the delegate tracer provider - */ - ProxyTracerProvider.prototype.setDelegate = function (delegate) { - this._delegate = delegate; - }; - ProxyTracerProvider.prototype.getDelegateTracer = function (name, version, options) { - var _a; - return (_a = this._delegate) === null || _a === void 0 ? void 0 : _a.getTracer(name, version, options); - }; - return ProxyTracerProvider; -}()); - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * @deprecated use the one declared in @opentelemetry/sdk-trace-base instead. - * A sampling decision that determines how a {@link Span} will be recorded - * and collected. - */ -var SamplingDecision; -(function (SamplingDecision) { - /** - * `Span.isRecording() === false`, span will not be recorded and all events - * and attributes will be dropped. - */ - SamplingDecision[SamplingDecision["NOT_RECORD"] = 0] = "NOT_RECORD"; - /** - * `Span.isRecording() === true`, but `Sampled` flag in {@link TraceFlags} - * MUST NOT be set. - */ - SamplingDecision[SamplingDecision["RECORD"] = 1] = "RECORD"; - /** - * `Span.isRecording() === true` AND `Sampled` flag in {@link TraceFlags} - * MUST be set. - */ - SamplingDecision[SamplingDecision["RECORD_AND_SAMPLED"] = 2] = "RECORD_AND_SAMPLED"; -})(SamplingDecision || (SamplingDecision = {})); - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -var SpanKind; -(function (SpanKind) { - /** Default value. Indicates that the span is used internally. */ - SpanKind[SpanKind["INTERNAL"] = 0] = "INTERNAL"; - /** - * Indicates that the span covers server-side handling of an RPC or other - * remote request. - */ - SpanKind[SpanKind["SERVER"] = 1] = "SERVER"; - /** - * Indicates that the span covers the client-side wrapper around an RPC or - * other remote request. - */ - SpanKind[SpanKind["CLIENT"] = 2] = "CLIENT"; - /** - * Indicates that the span describes producer sending a message to a - * broker. Unlike client and server, there is no direct critical path latency - * relationship between producer and consumer spans. - */ - SpanKind[SpanKind["PRODUCER"] = 3] = "PRODUCER"; - /** - * Indicates that the span describes consumer receiving a message from a - * broker. Unlike client and server, there is no direct critical path latency - * relationship between producer and consumer spans. - */ - SpanKind[SpanKind["CONSUMER"] = 4] = "CONSUMER"; -})(SpanKind || (SpanKind = {})); - -/** - * An enumeration of status codes. - */ -var SpanStatusCode; -(function (SpanStatusCode) { - /** - * The default status. - */ - SpanStatusCode[SpanStatusCode["UNSET"] = 0] = "UNSET"; - /** - * The operation has been validated by an Application developer or - * Operator to have completed successfully. - */ - SpanStatusCode[SpanStatusCode["OK"] = 1] = "OK"; - /** - * The operation contains an error. - */ - SpanStatusCode[SpanStatusCode["ERROR"] = 2] = "ERROR"; -})(SpanStatusCode || (SpanStatusCode = {})); - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -var VALID_KEY_CHAR_RANGE = '[_0-9a-z-*/]'; -var VALID_KEY = "[a-z]" + VALID_KEY_CHAR_RANGE + "{0,255}"; -var VALID_VENDOR_KEY = "[a-z0-9]" + VALID_KEY_CHAR_RANGE + "{0,240}@[a-z]" + VALID_KEY_CHAR_RANGE + "{0,13}"; -var VALID_KEY_REGEX = new RegExp("^(?:" + VALID_KEY + "|" + VALID_VENDOR_KEY + ")$"); -var VALID_VALUE_BASE_REGEX = /^[ -~]{0,255}[!-~]$/; -var INVALID_VALUE_COMMA_EQUAL_REGEX = /,|=/; -/** - * Key is opaque string up to 256 characters printable. It MUST begin with a - * lowercase letter, and can only contain lowercase letters a-z, digits 0-9, - * underscores _, dashes -, asterisks *, and forward slashes /. - * For multi-tenant vendor scenarios, an at sign (@) can be used to prefix the - * vendor name. Vendors SHOULD set the tenant ID at the beginning of the key. - * see https://www.w3.org/TR/trace-context/#key - */ -function validateKey(key) { - return VALID_KEY_REGEX.test(key); -} -/** - * Value is opaque string up to 256 characters printable ASCII RFC0020 - * characters (i.e., the range 0x20 to 0x7E) except comma , and =. - */ -function validateValue(value) { - return (VALID_VALUE_BASE_REGEX.test(value) && - !INVALID_VALUE_COMMA_EQUAL_REGEX.test(value)); -} - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -var MAX_TRACE_STATE_ITEMS = 32; -var MAX_TRACE_STATE_LEN = 512; -var LIST_MEMBERS_SEPARATOR = ','; -var LIST_MEMBER_KEY_VALUE_SPLITTER = '='; -/** - * TraceState must be a class and not a simple object type because of the spec - * requirement (https://www.w3.org/TR/trace-context/#tracestate-field). - * - * Here is the list of allowed mutations: - * - New key-value pair should be added into the beginning of the list - * - The value of any key can be updated. Modified keys MUST be moved to the - * beginning of the list. - */ -var TraceStateImpl = /** @class */ (function () { - function TraceStateImpl(rawTraceState) { - this._internalState = new Map(); - if (rawTraceState) - this._parse(rawTraceState); - } - TraceStateImpl.prototype.set = function (key, value) { - // TODO: Benchmark the different approaches(map vs list) and - // use the faster one. - var traceState = this._clone(); - if (traceState._internalState.has(key)) { - traceState._internalState.delete(key); - } - traceState._internalState.set(key, value); - return traceState; - }; - TraceStateImpl.prototype.unset = function (key) { - var traceState = this._clone(); - traceState._internalState.delete(key); - return traceState; - }; - TraceStateImpl.prototype.get = function (key) { - return this._internalState.get(key); - }; - TraceStateImpl.prototype.serialize = function () { - var _this = this; - return this._keys() - .reduce(function (agg, key) { - agg.push(key + LIST_MEMBER_KEY_VALUE_SPLITTER + _this.get(key)); - return agg; - }, []) - .join(LIST_MEMBERS_SEPARATOR); - }; - TraceStateImpl.prototype._parse = function (rawTraceState) { - if (rawTraceState.length > MAX_TRACE_STATE_LEN) - return; - this._internalState = rawTraceState - .split(LIST_MEMBERS_SEPARATOR) - .reverse() // Store in reverse so new keys (.set(...)) will be placed at the beginning - .reduce(function (agg, part) { - var listMember = part.trim(); // Optional Whitespace (OWS) handling - var i = listMember.indexOf(LIST_MEMBER_KEY_VALUE_SPLITTER); - if (i !== -1) { - var key = listMember.slice(0, i); - var value = listMember.slice(i + 1, part.length); - if (validateKey(key) && validateValue(value)) { - agg.set(key, value); - } - } - return agg; - }, new Map()); - // Because of the reverse() requirement, trunc must be done after map is created - if (this._internalState.size > MAX_TRACE_STATE_ITEMS) { - this._internalState = new Map(Array.from(this._internalState.entries()) - .reverse() // Use reverse same as original tracestate parse chain - .slice(0, MAX_TRACE_STATE_ITEMS)); - } - }; - TraceStateImpl.prototype._keys = function () { - return Array.from(this._internalState.keys()).reverse(); - }; - TraceStateImpl.prototype._clone = function () { - var traceState = new TraceStateImpl(); - traceState._internalState = new Map(this._internalState); - return traceState; - }; - return TraceStateImpl; -}()); - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -function createTraceState(rawTraceState) { - return new TraceStateImpl(rawTraceState); -} - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// Split module-level variable definition into separate files to allow -// tree-shaking on each api instance. -/** Entrypoint for context API */ -var context = ContextAPI.getInstance(); - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// Split module-level variable definition into separate files to allow -// tree-shaking on each api instance. -/** - * Entrypoint for Diag API. - * Defines Diagnostic handler used for internal diagnostic logging operations. - * The default provides a Noop DiagLogger implementation which may be changed via the - * diag.setLogger(logger: DiagLogger) function. - */ -var diag = DiagAPI.instance(); - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * An implementation of the {@link MeterProvider} which returns an impotent Meter - * for all calls to `getMeter` - */ -var NoopMeterProvider = /** @class */ (function () { - function NoopMeterProvider() { - } - NoopMeterProvider.prototype.getMeter = function (_name, _version, _options) { - return NOOP_METER; - }; - return NoopMeterProvider; -}()); -var NOOP_METER_PROVIDER = new NoopMeterProvider(); - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -var API_NAME$2 = 'metrics'; -/** - * Singleton object which represents the entry point to the OpenTelemetry Metrics API - */ -var MetricsAPI = /** @class */ (function () { - /** Empty private constructor prevents end users from constructing a new instance of the API */ - function MetricsAPI() { - } - /** Get the singleton instance of the Metrics API */ - MetricsAPI.getInstance = function () { - if (!this._instance) { - this._instance = new MetricsAPI(); - } - return this._instance; - }; - /** - * Set the current global meter provider. - * Returns true if the meter provider was successfully registered, else false. - */ - MetricsAPI.prototype.setGlobalMeterProvider = function (provider) { - return registerGlobal(API_NAME$2, provider, DiagAPI.instance()); - }; - /** - * Returns the global meter provider. - */ - MetricsAPI.prototype.getMeterProvider = function () { - return getGlobal(API_NAME$2) || NOOP_METER_PROVIDER; - }; - /** - * Returns a meter from the global meter provider. - */ - MetricsAPI.prototype.getMeter = function (name, version, options) { - return this.getMeterProvider().getMeter(name, version, options); - }; - /** Remove the global meter provider */ - MetricsAPI.prototype.disable = function () { - unregisterGlobal(API_NAME$2, DiagAPI.instance()); - }; - return MetricsAPI; -}()); - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// Split module-level variable definition into separate files to allow -// tree-shaking on each api instance. -/** Entrypoint for metrics API */ -var metrics = MetricsAPI.getInstance(); - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * No-op implementations of {@link TextMapPropagator}. - */ -var NoopTextMapPropagator = /** @class */ (function () { - function NoopTextMapPropagator() { - } - /** Noop inject function does nothing */ - NoopTextMapPropagator.prototype.inject = function (_context, _carrier) { }; - /** Noop extract function does nothing and returns the input context */ - NoopTextMapPropagator.prototype.extract = function (context, _carrier) { - return context; - }; - NoopTextMapPropagator.prototype.fields = function () { - return []; - }; - return NoopTextMapPropagator; -}()); - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Baggage key - */ -var BAGGAGE_KEY = createContextKey('OpenTelemetry Baggage Key'); -/** - * Retrieve the current baggage from the given context - * - * @param {Context} Context that manage all context values - * @returns {Baggage} Extracted baggage from the context - */ -function getBaggage(context) { - return context.getValue(BAGGAGE_KEY) || undefined; -} -/** - * Retrieve the current baggage from the active/current context - * - * @returns {Baggage} Extracted baggage from the context - */ -function getActiveBaggage() { - return getBaggage(ContextAPI.getInstance().active()); -} -/** - * Store a baggage in the given context - * - * @param {Context} Context that manage all context values - * @param {Baggage} baggage that will be set in the actual context - */ -function setBaggage(context, baggage) { - return context.setValue(BAGGAGE_KEY, baggage); -} -/** - * Delete the baggage stored in the given context - * - * @param {Context} Context that manage all context values - */ -function deleteBaggage(context) { - return context.deleteValue(BAGGAGE_KEY); -} - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -var API_NAME$1 = 'propagation'; -var NOOP_TEXT_MAP_PROPAGATOR = new NoopTextMapPropagator(); -/** - * Singleton object which represents the entry point to the OpenTelemetry Propagation API - */ -var PropagationAPI = /** @class */ (function () { - /** Empty private constructor prevents end users from constructing a new instance of the API */ - function PropagationAPI() { - this.createBaggage = createBaggage; - this.getBaggage = getBaggage; - this.getActiveBaggage = getActiveBaggage; - this.setBaggage = setBaggage; - this.deleteBaggage = deleteBaggage; - } - /** Get the singleton instance of the Propagator API */ - PropagationAPI.getInstance = function () { - if (!this._instance) { - this._instance = new PropagationAPI(); - } - return this._instance; - }; - /** - * Set the current propagator. - * - * @returns true if the propagator was successfully registered, else false - */ - PropagationAPI.prototype.setGlobalPropagator = function (propagator) { - return registerGlobal(API_NAME$1, propagator, DiagAPI.instance()); - }; - /** - * Inject context into a carrier to be propagated inter-process - * - * @param context Context carrying tracing data to inject - * @param carrier carrier to inject context into - * @param setter Function used to set values on the carrier - */ - PropagationAPI.prototype.inject = function (context, carrier, setter) { - if (setter === void 0) { setter = defaultTextMapSetter; } - return this._getGlobalPropagator().inject(context, carrier, setter); - }; - /** - * Extract context from a carrier - * - * @param context Context which the newly created context will inherit from - * @param carrier Carrier to extract context from - * @param getter Function used to extract keys from a carrier - */ - PropagationAPI.prototype.extract = function (context, carrier, getter) { - if (getter === void 0) { getter = defaultTextMapGetter; } - return this._getGlobalPropagator().extract(context, carrier, getter); - }; - /** - * Return a list of all fields which may be used by the propagator. - */ - PropagationAPI.prototype.fields = function () { - return this._getGlobalPropagator().fields(); - }; - /** Remove the global propagator */ - PropagationAPI.prototype.disable = function () { - unregisterGlobal(API_NAME$1, DiagAPI.instance()); - }; - PropagationAPI.prototype._getGlobalPropagator = function () { - return getGlobal(API_NAME$1) || NOOP_TEXT_MAP_PROPAGATOR; - }; - return PropagationAPI; -}()); - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// Split module-level variable definition into separate files to allow -// tree-shaking on each api instance. -/** Entrypoint for propagation API */ -var propagation = PropagationAPI.getInstance(); - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -var API_NAME = 'trace'; -/** - * Singleton object which represents the entry point to the OpenTelemetry Tracing API - */ -var TraceAPI = /** @class */ (function () { - /** Empty private constructor prevents end users from constructing a new instance of the API */ - function TraceAPI() { - this._proxyTracerProvider = new ProxyTracerProvider(); - this.wrapSpanContext = wrapSpanContext; - this.isSpanContextValid = isSpanContextValid; - this.deleteSpan = deleteSpan; - this.getSpan = getSpan; - this.getActiveSpan = getActiveSpan; - this.getSpanContext = getSpanContext; - this.setSpan = setSpan; - this.setSpanContext = setSpanContext; - } - /** Get the singleton instance of the Trace API */ - TraceAPI.getInstance = function () { - if (!this._instance) { - this._instance = new TraceAPI(); - } - return this._instance; - }; - /** - * Set the current global tracer. - * - * @returns true if the tracer provider was successfully registered, else false - */ - TraceAPI.prototype.setGlobalTracerProvider = function (provider) { - var success = registerGlobal(API_NAME, this._proxyTracerProvider, DiagAPI.instance()); - if (success) { - this._proxyTracerProvider.setDelegate(provider); - } - return success; - }; - /** - * Returns the global tracer provider. - */ - TraceAPI.prototype.getTracerProvider = function () { - return getGlobal(API_NAME) || this._proxyTracerProvider; - }; - /** - * Returns a tracer from the global tracer provider. - */ - TraceAPI.prototype.getTracer = function (name, version) { - return this.getTracerProvider().getTracer(name, version); - }; - /** Remove the global tracer provider */ - TraceAPI.prototype.disable = function () { - unregisterGlobal(API_NAME, DiagAPI.instance()); - this._proxyTracerProvider = new ProxyTracerProvider(); - }; - return TraceAPI; -}()); - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// Split module-level variable definition into separate files to allow -// tree-shaking on each api instance. -/** Entrypoint for trace API */ -var trace = TraceAPI.getInstance(); - -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// Default export. -const index = { - context: context, - diag: diag, - metrics: metrics, - propagation: propagation, - trace: trace, -}; - -export { DiagConsoleLogger, DiagLogLevel, INVALID_SPANID, INVALID_SPAN_CONTEXT, INVALID_TRACEID, ProxyTracer, ProxyTracerProvider, ROOT_CONTEXT, SamplingDecision, SpanKind, SpanStatusCode, TraceFlags, ValueType, baggageEntryMetadataFromString, context, createContextKey, createNoopMeter, createTraceState, index as default, defaultTextMapGetter, defaultTextMapSetter, diag, isSpanContextValid, isValidSpanId, isValidTraceId, metrics, propagation, trace }; diff --git a/workbench/astro/dist/server/chunks/index_ePTMDSOu.mjs b/workbench/astro/dist/server/chunks/index_ePTMDSOu.mjs deleted file mode 100644 index 9ad416bcd..000000000 --- a/workbench/astro/dist/server/chunks/index_ePTMDSOu.mjs +++ /dev/null @@ -1,42973 +0,0 @@ -import * as z from 'zod'; -import z__default, { z as z$1, ZodError } from 'zod'; -import * as devalue from 'devalue'; -import { createRequire } from 'node:module'; -import path, { join } from 'node:path'; -import { setTimeout as setTimeout$1, scheduler, setImmediate as setImmediate$1 } from 'node:timers/promises'; -import process$2, { platform, hrtime, execPath, execArgv } from 'node:process'; -import isPlainObject from 'is-plain-obj'; -import url, { fileURLToPath } from 'node:url'; -import { ChildProcess, execFile, spawnSync, spawn } from 'node:child_process'; -import { StringDecoder } from 'node:string_decoder'; -import require$$0$6, { debuglog, stripVTControlCharacters, inspect, promisify, callbackify, aborted } from 'node:util'; -import { gray, redBright, yellowBright, bold } from 'yoctocolors'; -import { c as commonjsGlobal, g as getDefaultExportFromCjs } from './_commonjsHelpers_BFTU3MAI.mjs'; -import require$$0$2 from 'child_process'; -import require$$0$1 from 'path'; -import require$$0 from 'fs'; -import os, { constants as constants$5 } from 'node:os'; -import require$$8, { once as once$2, addAbortListener, EventEmitter, on, setMaxListeners } from 'node:events'; -import { serialize } from 'node:v8'; -import { statSync, readFileSync, appendFileSync, writeFileSync, createWriteStream, createReadStream, promises } from 'node:fs'; -import tty from 'node:tty'; -import require$$0$5, { Transform, getDefaultHighWaterMark, Duplex, Writable, Readable, PassThrough } from 'node:stream'; -import require$$0$3, { Buffer as Buffer$1 } from 'node:buffer'; -import { finished } from 'node:stream/promises'; -import { z as z$2 } from 'zod/v4'; -import crypto from 'node:crypto'; -import require$$0$4 from 'node:assert'; -import require$$4 from 'node:net'; -import require$$2 from 'node:http'; -import require$$7 from 'node:querystring'; -import require$$0$7 from 'node:diagnostics_channel'; -import require$$4$1 from 'node:tls'; -import require$$1 from 'node:zlib'; -import require$$5 from 'node:perf_hooks'; -import require$$8$1 from 'node:util/types'; -import require$$5$1 from 'node:async_hooks'; -import require$$1$1 from 'node:console'; -import require$$5$2 from 'string_decoder'; -import require$$3 from 'node:worker_threads'; -import debug from 'debug'; -import ms from 'ms'; - -var headers$1; -var hasRequiredHeaders$1; - -function requireHeaders$1 () { - if (hasRequiredHeaders$1) return headers$1; - hasRequiredHeaders$1 = 1; - var __defProp = Object.defineProperty; - var __getOwnPropDesc = Object.getOwnPropertyDescriptor; - var __getOwnPropNames = Object.getOwnPropertyNames; - var __hasOwnProp = Object.prototype.hasOwnProperty; - var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); - }; - var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; - }; - var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); - var headers_exports = {}; - __export(headers_exports, { - CITY_HEADER_NAME: () => CITY_HEADER_NAME, - COUNTRY_HEADER_NAME: () => COUNTRY_HEADER_NAME, - EMOJI_FLAG_UNICODE_STARTING_POSITION: () => EMOJI_FLAG_UNICODE_STARTING_POSITION, - IP_HEADER_NAME: () => IP_HEADER_NAME, - LATITUDE_HEADER_NAME: () => LATITUDE_HEADER_NAME, - LONGITUDE_HEADER_NAME: () => LONGITUDE_HEADER_NAME, - POSTAL_CODE_HEADER_NAME: () => POSTAL_CODE_HEADER_NAME, - REGION_HEADER_NAME: () => REGION_HEADER_NAME, - REQUEST_ID_HEADER_NAME: () => REQUEST_ID_HEADER_NAME, - geolocation: () => geolocation, - ipAddress: () => ipAddress - }); - headers$1 = __toCommonJS(headers_exports); - const CITY_HEADER_NAME = "x-vercel-ip-city"; - const COUNTRY_HEADER_NAME = "x-vercel-ip-country"; - const IP_HEADER_NAME = "x-real-ip"; - const LATITUDE_HEADER_NAME = "x-vercel-ip-latitude"; - const LONGITUDE_HEADER_NAME = "x-vercel-ip-longitude"; - const REGION_HEADER_NAME = "x-vercel-ip-country-region"; - const POSTAL_CODE_HEADER_NAME = "x-vercel-ip-postal-code"; - const REQUEST_ID_HEADER_NAME = "x-vercel-id"; - const EMOJI_FLAG_UNICODE_STARTING_POSITION = 127397; - function getHeader(headers, key) { - return headers.get(key) ?? void 0; - } - function getHeaderWithDecode(request, key) { - const header = getHeader(request.headers, key); - return header ? decodeURIComponent(header) : void 0; - } - function getFlag(countryCode) { - const regex = new RegExp("^[A-Z]{2}$").test(countryCode); - if (!countryCode || !regex) - return void 0; - return String.fromCodePoint( - ...countryCode.split("").map((char) => EMOJI_FLAG_UNICODE_STARTING_POSITION + char.charCodeAt(0)) - ); - } - function ipAddress(input) { - const headers = "headers" in input ? input.headers : input; - return getHeader(headers, IP_HEADER_NAME); - } - function getRegionFromRequestId(requestId) { - if (!requestId) { - return "dev1"; - } - return requestId.split(":")[0]; - } - function geolocation(request) { - return { - // city name may be encoded to support multi-byte characters - city: getHeaderWithDecode(request, CITY_HEADER_NAME), - country: getHeader(request.headers, COUNTRY_HEADER_NAME), - flag: getFlag(getHeader(request.headers, COUNTRY_HEADER_NAME)), - countryRegion: getHeader(request.headers, REGION_HEADER_NAME), - region: getRegionFromRequestId( - getHeader(request.headers, REQUEST_ID_HEADER_NAME) - ), - latitude: getHeader(request.headers, LATITUDE_HEADER_NAME), - longitude: getHeader(request.headers, LONGITUDE_HEADER_NAME), - postalCode: getHeader(request.headers, POSTAL_CODE_HEADER_NAME) - }; - } - return headers$1; -} - -var getEnv_1; -var hasRequiredGetEnv; - -function requireGetEnv () { - if (hasRequiredGetEnv) return getEnv_1; - hasRequiredGetEnv = 1; - var __defProp = Object.defineProperty; - var __getOwnPropDesc = Object.getOwnPropertyDescriptor; - var __getOwnPropNames = Object.getOwnPropertyNames; - var __hasOwnProp = Object.prototype.hasOwnProperty; - var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); - }; - var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; - }; - var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); - var get_env_exports = {}; - __export(get_env_exports, { - getEnv: () => getEnv - }); - getEnv_1 = __toCommonJS(get_env_exports); - const getEnv = (env = process.env) => ({ - /** - * An indicator to show that System Environment Variables have been exposed to your project's Deployments. - * @example "1" - */ - VERCEL: get(env, "VERCEL"), - /** - * An indicator that the code is running in a Continuous Integration environment. - * @example "1" - */ - CI: get(env, "CI"), - /** - * The Environment that the app is deployed and running on. - * @example "production" - */ - VERCEL_ENV: get(env, "VERCEL_ENV"), - /** - * The domain name of the generated deployment URL. The value does not include the protocol scheme https://. - * NOTE: This Variable cannot be used in conjunction with Standard Deployment Protection. - * @example "*.vercel.app" - */ - VERCEL_URL: get(env, "VERCEL_URL"), - /** - * The domain name of the generated Git branch URL. The value does not include the protocol scheme https://. - * @example "*-git-*.vercel.app" - */ - VERCEL_BRANCH_URL: get(env, "VERCEL_BRANCH_URL"), - /** - * A production domain name of the project. This is useful to reliably generate links that point to production such as OG-image URLs. - * The value does not include the protocol scheme https://. - * @example "myproject.vercel.app" - */ - VERCEL_PROJECT_PRODUCTION_URL: get(env, "VERCEL_PROJECT_PRODUCTION_URL"), - /** - * The ID of the Region where the app is running. - * - * Possible values: - * - arn1 (Stockholm, Sweden) - * - bom1 (Mumbai, India) - * - cdg1 (Paris, France) - * - cle1 (Cleveland, USA) - * - cpt1 (Cape Town, South Africa) - * - dub1 (Dublin, Ireland) - * - fra1 (Frankfurt, Germany) - * - gru1 (São Paulo, Brazil) - * - hkg1 (Hong Kong) - * - hnd1 (Tokyo, Japan) - * - iad1 (Washington, D.C., USA) - * - icn1 (Seoul, South Korea) - * - kix1 (Osaka, Japan) - * - lhr1 (London, United Kingdom) - * - pdx1 (Portland, USA) - * - sfo1 (San Francisco, USA) - * - sin1 (Singapore) - * - syd1 (Sydney, Australia) - * - dev1 (Development Region) - * - * @example "iad1" - */ - VERCEL_REGION: get(env, "VERCEL_REGION"), - /** - * The unique identifier for the deployment, which can be used to implement Skew Protection. - * @example "dpl_7Gw5ZMBpQA8h9GF832KGp7nwbuh3" - */ - VERCEL_DEPLOYMENT_ID: get(env, "VERCEL_DEPLOYMENT_ID"), - /** - * When Skew Protection is enabled in Project Settings, this value is set to 1. - * @example "1" - */ - VERCEL_SKEW_PROTECTION_ENABLED: get(env, "VERCEL_SKEW_PROTECTION_ENABLED"), - /** - * The Protection Bypass for Automation value, if the secret has been generated in the project's Deployment Protection settings. - */ - VERCEL_AUTOMATION_BYPASS_SECRET: get(env, "VERCEL_AUTOMATION_BYPASS_SECRET"), - /** - * The Git Provider the deployment is triggered from. - * @example "github" - */ - VERCEL_GIT_PROVIDER: get(env, "VERCEL_GIT_PROVIDER"), - /** - * The origin repository the deployment is triggered from. - * @example "my-site" - */ - VERCEL_GIT_REPO_SLUG: get(env, "VERCEL_GIT_REPO_SLUG"), - /** - * The account that owns the repository the deployment is triggered from. - * @example "acme" - */ - VERCEL_GIT_REPO_OWNER: get(env, "VERCEL_GIT_REPO_OWNER"), - /** - * The ID of the repository the deployment is triggered from. - * @example "117716146" - */ - VERCEL_GIT_REPO_ID: get(env, "VERCEL_GIT_REPO_ID"), - /** - * The git branch of the commit the deployment was triggered by. - * @example "improve-about-page" - */ - VERCEL_GIT_COMMIT_REF: get(env, "VERCEL_GIT_COMMIT_REF"), - /** - * The git SHA of the commit the deployment was triggered by. - * @example "fa1eade47b73733d6312d5abfad33ce9e4068081" - */ - VERCEL_GIT_COMMIT_SHA: get(env, "VERCEL_GIT_COMMIT_SHA"), - /** - * The message attached to the commit the deployment was triggered by. - * @example "Update about page" - */ - VERCEL_GIT_COMMIT_MESSAGE: get(env, "VERCEL_GIT_COMMIT_MESSAGE"), - /** - * The username attached to the author of the commit that the project was deployed by. - * @example "johndoe" - */ - VERCEL_GIT_COMMIT_AUTHOR_LOGIN: get(env, "VERCEL_GIT_COMMIT_AUTHOR_LOGIN"), - /** - * The name attached to the author of the commit that the project was deployed by. - * @example "John Doe" - */ - VERCEL_GIT_COMMIT_AUTHOR_NAME: get(env, "VERCEL_GIT_COMMIT_AUTHOR_NAME"), - /** - * The git SHA of the last successful deployment for the project and branch. - * NOTE: This Variable is only exposed when an Ignored Build Step is provided. - * @example "fa1eade47b73733d6312d5abfad33ce9e4068080" - */ - VERCEL_GIT_PREVIOUS_SHA: get(env, "VERCEL_GIT_PREVIOUS_SHA"), - /** - * The pull request id the deployment was triggered by. If a deployment is created on a branch before a pull request is made, this value will be an empty string. - * @example "23" - */ - VERCEL_GIT_PULL_REQUEST_ID: get(env, "VERCEL_GIT_PULL_REQUEST_ID") - }); - const get = (env, key) => { - const value = env[key]; - return value === "" ? void 0 : value; - }; - return getEnv_1; -} - -var getContext_1$1; -var hasRequiredGetContext$1; - -function requireGetContext$1 () { - if (hasRequiredGetContext$1) return getContext_1$1; - hasRequiredGetContext$1 = 1; - var __defProp = Object.defineProperty; - var __getOwnPropDesc = Object.getOwnPropertyDescriptor; - var __getOwnPropNames = Object.getOwnPropertyNames; - var __hasOwnProp = Object.prototype.hasOwnProperty; - var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); - }; - var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; - }; - var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); - var get_context_exports = {}; - __export(get_context_exports, { - SYMBOL_FOR_REQ_CONTEXT: () => SYMBOL_FOR_REQ_CONTEXT, - getContext: () => getContext - }); - getContext_1$1 = __toCommonJS(get_context_exports); - const SYMBOL_FOR_REQ_CONTEXT = Symbol.for("@vercel/request-context"); - function getContext() { - const fromSymbol = globalThis; - return fromSymbol[SYMBOL_FOR_REQ_CONTEXT]?.get?.() ?? {}; - } - return getContext_1$1; -} - -var waitUntil_1; -var hasRequiredWaitUntil; - -function requireWaitUntil () { - if (hasRequiredWaitUntil) return waitUntil_1; - hasRequiredWaitUntil = 1; - var __defProp = Object.defineProperty; - var __getOwnPropDesc = Object.getOwnPropertyDescriptor; - var __getOwnPropNames = Object.getOwnPropertyNames; - var __hasOwnProp = Object.prototype.hasOwnProperty; - var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); - }; - var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; - }; - var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); - var wait_until_exports = {}; - __export(wait_until_exports, { - waitUntil: () => waitUntil - }); - waitUntil_1 = __toCommonJS(wait_until_exports); - var import_get_context = requireGetContext$1(); - const waitUntil = (promise) => { - if (promise === null || typeof promise !== "object" || typeof promise.then !== "function") { - throw new TypeError( - `waitUntil can only be called with a Promise, got ${typeof promise}` - ); - } - return (0, import_get_context.getContext)().waitUntil?.(promise); - }; - return waitUntil_1; -} - -var middleware; -var hasRequiredMiddleware; - -function requireMiddleware () { - if (hasRequiredMiddleware) return middleware; - hasRequiredMiddleware = 1; - var __defProp = Object.defineProperty; - var __getOwnPropDesc = Object.getOwnPropertyDescriptor; - var __getOwnPropNames = Object.getOwnPropertyNames; - var __hasOwnProp = Object.prototype.hasOwnProperty; - var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); - }; - var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; - }; - var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); - var middleware_exports = {}; - __export(middleware_exports, { - next: () => next, - rewrite: () => rewrite - }); - middleware = __toCommonJS(middleware_exports); - function handleMiddlewareField(init, headers) { - if (init?.request?.headers) { - if (!(init.request.headers instanceof Headers)) { - throw new Error("request.headers must be an instance of Headers"); - } - const keys = []; - for (const [key, value] of init.request.headers) { - headers.set("x-middleware-request-" + key, value); - keys.push(key); - } - headers.set("x-middleware-override-headers", keys.join(",")); - } - } - function rewrite(destination, init) { - const headers = new Headers(init?.headers ?? {}); - headers.set("x-middleware-rewrite", String(destination)); - handleMiddlewareField(init, headers); - return new Response(null, { - ...init, - headers - }); - } - function next(init) { - const headers = new Headers(init?.headers ?? {}); - headers.set("x-middleware-next", "1"); - handleMiddlewareField(init, headers); - return new Response(null, { - ...init, - headers - }); - } - return middleware; -} - -var inMemoryCache; -var hasRequiredInMemoryCache; - -function requireInMemoryCache () { - if (hasRequiredInMemoryCache) return inMemoryCache; - hasRequiredInMemoryCache = 1; - var __defProp = Object.defineProperty; - var __getOwnPropDesc = Object.getOwnPropertyDescriptor; - var __getOwnPropNames = Object.getOwnPropertyNames; - var __hasOwnProp = Object.prototype.hasOwnProperty; - var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); - }; - var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; - }; - var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); - var in_memory_cache_exports = {}; - __export(in_memory_cache_exports, { - InMemoryCache: () => InMemoryCache - }); - inMemoryCache = __toCommonJS(in_memory_cache_exports); - class InMemoryCache { - constructor() { - this.cache = {}; - } - async get(key) { - const entry = this.cache[key]; - if (entry) { - if (entry.ttl && entry.lastModified + entry.ttl * 1e3 < Date.now()) { - await this.delete(key); - return null; - } - return entry.value; - } - return null; - } - async set(key, value, options) { - this.cache[key] = { - value, - lastModified: Date.now(), - ttl: options?.ttl, - tags: new Set(options?.tags || []) - }; - } - async delete(key) { - delete this.cache[key]; - } - async expireTag(tag) { - const tags = Array.isArray(tag) ? tag : [tag]; - for (const key in this.cache) { - if (Object.prototype.hasOwnProperty.call(this.cache, key)) { - const entry = this.cache[key]; - if (tags.some((t) => entry.tags.has(t))) { - delete this.cache[key]; - } - } - } - } - } - return inMemoryCache; -} - -var buildClient; -var hasRequiredBuildClient; - -function requireBuildClient () { - if (hasRequiredBuildClient) return buildClient; - hasRequiredBuildClient = 1; - var __defProp = Object.defineProperty; - var __getOwnPropDesc = Object.getOwnPropertyDescriptor; - var __getOwnPropNames = Object.getOwnPropertyNames; - var __hasOwnProp = Object.prototype.hasOwnProperty; - var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); - }; - var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; - }; - var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); - var build_client_exports = {}; - __export(build_client_exports, { - BuildCache: () => BuildCache - }); - buildClient = __toCommonJS(build_client_exports); - var import_index = requireCache$1(); - class BuildCache { - constructor({ - endpoint, - headers, - onError, - timeout = 500 - }) { - this.get = async (key) => { - const controller = new AbortController(); - const timeoutId = setTimeout(() => controller.abort(), this.timeout); - try { - const res = await fetch(`${this.endpoint}${key}`, { - headers: this.headers, - method: "GET", - signal: controller.signal - }); - if (res.status === 404) { - clearTimeout(timeoutId); - return null; - } - if (res.status === 200) { - const cacheState = res.headers.get( - import_index.HEADERS_VERCEL_CACHE_STATE - ); - if (cacheState !== import_index.PkgCacheState.Fresh) { - res.body?.cancel?.(); - clearTimeout(timeoutId); - return null; - } - const result = await res.json(); - clearTimeout(timeoutId); - return result; - } else { - clearTimeout(timeoutId); - throw new Error(`Failed to get cache: ${res.statusText}`); - } - } catch (error) { - clearTimeout(timeoutId); - if (error.name === "AbortError") { - const timeoutError = new Error( - `Cache request timed out after ${this.timeout}ms` - ); - timeoutError.stack = error.stack; - this.onError?.(timeoutError); - } else { - this.onError?.(error); - } - return null; - } - }; - this.set = async (key, value, options) => { - const controller = new AbortController(); - const timeoutId = setTimeout(() => controller.abort(), this.timeout); - try { - const optionalHeaders = {}; - if (options?.ttl) { - optionalHeaders[import_index.HEADERS_VERCEL_REVALIDATE] = options.ttl.toString(); - } - if (options?.tags && options.tags.length > 0) { - optionalHeaders[import_index.HEADERS_VERCEL_CACHE_TAGS] = options.tags.join(","); - } - if (options?.name) { - optionalHeaders[import_index.HEADERS_VERCEL_CACHE_ITEM_NAME] = options.name; - } - const res = await fetch(`${this.endpoint}${key}`, { - method: "POST", - headers: { - ...this.headers, - ...optionalHeaders - }, - body: JSON.stringify(value), - signal: controller.signal - }); - clearTimeout(timeoutId); - if (res.status !== 200) { - throw new Error(`Failed to set cache: ${res.status} ${res.statusText}`); - } - } catch (error) { - clearTimeout(timeoutId); - if (error.name === "AbortError") { - const timeoutError = new Error( - `Cache request timed out after ${this.timeout}ms` - ); - timeoutError.stack = error.stack; - this.onError?.(timeoutError); - } else { - this.onError?.(error); - } - } - }; - this.delete = async (key) => { - const controller = new AbortController(); - const timeoutId = setTimeout(() => controller.abort(), this.timeout); - try { - const res = await fetch(`${this.endpoint}${key}`, { - method: "DELETE", - headers: this.headers, - signal: controller.signal - }); - clearTimeout(timeoutId); - if (res.status !== 200) { - throw new Error(`Failed to delete cache: ${res.statusText}`); - } - } catch (error) { - clearTimeout(timeoutId); - if (error.name === "AbortError") { - const timeoutError = new Error( - `Cache request timed out after ${this.timeout}ms` - ); - timeoutError.stack = error.stack; - this.onError?.(timeoutError); - } else { - this.onError?.(error); - } - } - }; - this.expireTag = async (tag) => { - const controller = new AbortController(); - const timeoutId = setTimeout(() => controller.abort(), this.timeout); - try { - if (Array.isArray(tag)) { - tag = tag.join(","); - } - const res = await fetch(`${this.endpoint}revalidate?tags=${tag}`, { - method: "POST", - headers: this.headers, - signal: controller.signal - }); - clearTimeout(timeoutId); - if (res.status !== 200) { - throw new Error(`Failed to revalidate tag: ${res.statusText}`); - } - } catch (error) { - clearTimeout(timeoutId); - if (error.name === "AbortError") { - const timeoutError = new Error( - `Cache request timed out after ${this.timeout}ms` - ); - timeoutError.stack = error.stack; - this.onError?.(timeoutError); - } else { - this.onError?.(error); - } - } - }; - this.endpoint = endpoint; - this.headers = headers; - this.onError = onError; - this.timeout = timeout; - } - } - return buildClient; -} - -var cache$1; -var hasRequiredCache$1; - -function requireCache$1 () { - if (hasRequiredCache$1) return cache$1; - hasRequiredCache$1 = 1; - var __defProp = Object.defineProperty; - var __getOwnPropDesc = Object.getOwnPropertyDescriptor; - var __getOwnPropNames = Object.getOwnPropertyNames; - var __hasOwnProp = Object.prototype.hasOwnProperty; - var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); - }; - var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; - }; - var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); - var cache_exports = {}; - __export(cache_exports, { - HEADERS_VERCEL_CACHE_ITEM_NAME: () => HEADERS_VERCEL_CACHE_ITEM_NAME, - HEADERS_VERCEL_CACHE_STATE: () => HEADERS_VERCEL_CACHE_STATE, - HEADERS_VERCEL_CACHE_TAGS: () => HEADERS_VERCEL_CACHE_TAGS, - HEADERS_VERCEL_REVALIDATE: () => HEADERS_VERCEL_REVALIDATE, - PkgCacheState: () => PkgCacheState, - getCache: () => getCache - }); - cache$1 = __toCommonJS(cache_exports); - var import_get_context = requireGetContext$1(); - var import_in_memory_cache = requireInMemoryCache(); - var import_build_client = requireBuildClient(); - const defaultKeyHashFunction = (key) => { - let hash = 5381; - for (let i = 0; i < key.length; i++) { - hash = hash * 33 ^ key.charCodeAt(i); - } - return (hash >>> 0).toString(16); - }; - const defaultNamespaceSeparator = "$"; - let inMemoryCacheInstance = null; - let buildCacheInstance = null; - const getCache = (cacheOptions) => { - const resolveCache = () => { - let cache; - if ((0, import_get_context.getContext)().cache) { - cache = (0, import_get_context.getContext)().cache; - } else { - cache = getCacheImplementation( - process.env.SUSPENSE_CACHE_DEBUG === "true" - ); - } - return cache; - }; - return wrapWithKeyTransformation( - resolveCache, - createKeyTransformer(cacheOptions) - ); - }; - function createKeyTransformer(cacheOptions) { - const hashFunction = cacheOptions?.keyHashFunction || defaultKeyHashFunction; - return (key) => { - if (!cacheOptions?.namespace) - return hashFunction(key); - const separator = cacheOptions.namespaceSeparator || defaultNamespaceSeparator; - return `${cacheOptions.namespace}${separator}${hashFunction(key)}`; - }; - } - function wrapWithKeyTransformation(resolveCache, makeKey) { - return { - get: (key) => { - return resolveCache().get(makeKey(key)); - }, - set: (key, value, options) => { - return resolveCache().set(makeKey(key), value, options); - }, - delete: (key) => { - return resolveCache().delete(makeKey(key)); - }, - expireTag: (tag) => { - return resolveCache().expireTag(tag); - } - }; - } - let warnedCacheUnavailable = false; - function getCacheImplementation(debug) { - if (!inMemoryCacheInstance) { - inMemoryCacheInstance = new import_in_memory_cache.InMemoryCache(); - } - if (process.env.RUNTIME_CACHE_DISABLE_BUILD_CACHE === "true") { - debug && console.log("Using InMemoryCache as build cache is disabled"); - return inMemoryCacheInstance; - } - const { RUNTIME_CACHE_ENDPOINT, RUNTIME_CACHE_HEADERS } = process.env; - if (debug) { - console.log("Runtime cache environment variables:", { - RUNTIME_CACHE_ENDPOINT, - RUNTIME_CACHE_HEADERS - }); - } - if (!RUNTIME_CACHE_ENDPOINT || !RUNTIME_CACHE_HEADERS) { - if (!warnedCacheUnavailable) { - console.warn( - "Runtime Cache unavailable in this environment. Falling back to in-memory cache." - ); - warnedCacheUnavailable = true; - } - return inMemoryCacheInstance; - } - if (!buildCacheInstance) { - let parsedHeaders = {}; - try { - parsedHeaders = JSON.parse(RUNTIME_CACHE_HEADERS); - } catch (e) { - console.error("Failed to parse RUNTIME_CACHE_HEADERS:", e); - return inMemoryCacheInstance; - } - let timeout = 500; - if (process.env.RUNTIME_CACHE_TIMEOUT) { - const parsed = parseInt(process.env.RUNTIME_CACHE_TIMEOUT, 10); - if (!isNaN(parsed) && parsed > 0) { - timeout = parsed; - } else { - console.warn( - `Invalid RUNTIME_CACHE_TIMEOUT value: "${process.env.RUNTIME_CACHE_TIMEOUT}". Using default: ${timeout}ms` - ); - } - } - buildCacheInstance = new import_build_client.BuildCache({ - endpoint: RUNTIME_CACHE_ENDPOINT, - headers: parsedHeaders, - onError: (error) => console.error(error), - timeout - }); - } - return buildCacheInstance; - } - var PkgCacheState = /* @__PURE__ */ ((PkgCacheState2) => { - PkgCacheState2["Fresh"] = "fresh"; - PkgCacheState2["Stale"] = "stale"; - PkgCacheState2["Expired"] = "expired"; - PkgCacheState2["NotFound"] = "notFound"; - PkgCacheState2["Error"] = "error"; - return PkgCacheState2; - })(PkgCacheState || {}); - const HEADERS_VERCEL_CACHE_STATE = "x-vercel-cache-state"; - const HEADERS_VERCEL_REVALIDATE = "x-vercel-revalidate"; - const HEADERS_VERCEL_CACHE_TAGS = "x-vercel-cache-tags"; - const HEADERS_VERCEL_CACHE_ITEM_NAME = "x-vercel-cache-item-name"; - return cache$1; -} - -var dbConnections; -var hasRequiredDbConnections; - -function requireDbConnections () { - if (hasRequiredDbConnections) return dbConnections; - hasRequiredDbConnections = 1; - var __defProp = Object.defineProperty; - var __getOwnPropDesc = Object.getOwnPropertyDescriptor; - var __getOwnPropNames = Object.getOwnPropertyNames; - var __hasOwnProp = Object.prototype.hasOwnProperty; - var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); - }; - var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; - }; - var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); - var db_connections_exports = {}; - __export(db_connections_exports, { - attachDatabasePool: () => attachDatabasePool, - experimental_attachDatabasePool: () => experimental_attachDatabasePool - }); - dbConnections = __toCommonJS(db_connections_exports); - var import_get_context = requireGetContext$1(); - const DEBUG = !!process.env.DEBUG; - function getIdleTimeout(dbPool) { - if ("options" in dbPool && dbPool.options) { - if ("idleTimeoutMillis" in dbPool.options) { - return typeof dbPool.options.idleTimeoutMillis === "number" ? dbPool.options.idleTimeoutMillis : 1e4; - } - if ("maxIdleTimeMS" in dbPool.options) { - return typeof dbPool.options.maxIdleTimeMS === "number" ? dbPool.options.maxIdleTimeMS : 0; - } - if ("status" in dbPool) { - return 5e3; - } - if ("connect" in dbPool && "execute" in dbPool) { - return 3e4; - } - } - if ("config" in dbPool && dbPool.config) { - if ("connectionConfig" in dbPool.config && dbPool.config.connectionConfig) { - return dbPool.config.connectionConfig.idleTimeout || 6e4; - } - if ("idleTimeout" in dbPool.config) { - return typeof dbPool.config.idleTimeout === "number" ? dbPool.config.idleTimeout : 6e4; - } - } - if ("poolTimeout" in dbPool) { - return typeof dbPool.poolTimeout === "number" ? dbPool.poolTimeout : 6e4; - } - if ("idleTimeout" in dbPool) { - return typeof dbPool.idleTimeout === "number" ? dbPool.idleTimeout : 0; - } - return 1e4; - } - let idleTimeout = null; - let idleTimeoutResolve = () => { - }; - const bootTime = Date.now(); - const maximumDuration = 15 * 60 * 1e3 - 1e3; - function waitUntilIdleTimeout(dbPool) { - if (!process.env.VERCEL_URL || // This is not set during builds where we don't need to wait for idle connections using the mechanism - !process.env.VERCEL_REGION) { - return; - } - if (idleTimeout) { - clearTimeout(idleTimeout); - idleTimeoutResolve(); - } - const promise = new Promise((resolve) => { - idleTimeoutResolve = resolve; - }); - const waitTime = Math.min( - getIdleTimeout(dbPool) + 100, - maximumDuration - (Date.now() - bootTime) - ); - idleTimeout = setTimeout(() => { - idleTimeoutResolve?.(); - if (DEBUG) { - console.log("Database pool idle timeout reached. Releasing connections."); - } - }, waitTime); - const requestContext = (0, import_get_context.getContext)(); - if (requestContext?.waitUntil) { - requestContext.waitUntil(promise); - } else { - console.warn("Pool release event triggered outside of request scope."); - } - } - function attachDatabasePool(dbPool) { - if (idleTimeout) { - idleTimeoutResolve?.(); - clearTimeout(idleTimeout); - } - if ("on" in dbPool && dbPool.on && "options" in dbPool && "idleTimeoutMillis" in dbPool.options) { - const pgPool = dbPool; - pgPool.on("release", () => { - if (DEBUG) { - console.log("Client released from pool"); - } - waitUntilIdleTimeout(dbPool); - }); - return; - } else if ("on" in dbPool && dbPool.on && "config" in dbPool && dbPool.config && "connectionConfig" in dbPool.config) { - const mysqlPool = dbPool; - mysqlPool.on("release", () => { - if (DEBUG) { - console.log("MySQL client released from pool"); - } - waitUntilIdleTimeout(dbPool); - }); - return; - } else if ("on" in dbPool && dbPool.on && "config" in dbPool && dbPool.config && "idleTimeout" in dbPool.config) { - const mysql2Pool = dbPool; - mysql2Pool.on("release", () => { - if (DEBUG) { - console.log("MySQL2/MariaDB client released from pool"); - } - waitUntilIdleTimeout(dbPool); - }); - return; - } - if ("on" in dbPool && dbPool.on && "options" in dbPool && dbPool.options && "maxIdleTimeMS" in dbPool.options) { - const mongoPool = dbPool; - mongoPool.on("connectionCheckedOut", () => { - if (DEBUG) { - console.log("MongoDB connection checked out"); - } - waitUntilIdleTimeout(dbPool); - }); - return; - } - if ("on" in dbPool && dbPool.on && "options" in dbPool && dbPool.options && "socket" in dbPool.options) { - const redisPool = dbPool; - redisPool.on("end", () => { - if (DEBUG) { - console.log("Redis connection ended"); - } - waitUntilIdleTimeout(dbPool); - }); - return; - } - throw new Error("Unsupported database pool type"); - } - const experimental_attachDatabasePool = attachDatabasePool; - return dbConnections; -} - -var purge = {exports: {}}; - -var types; -var hasRequiredTypes; - -function requireTypes () { - if (hasRequiredTypes) return types; - hasRequiredTypes = 1; - var __defProp = Object.defineProperty; - var __getOwnPropDesc = Object.getOwnPropertyDescriptor; - var __getOwnPropNames = Object.getOwnPropertyNames; - var __hasOwnProp = Object.prototype.hasOwnProperty; - var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; - }; - var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); - var types_exports = {}; - types = __toCommonJS(types_exports); - return types; -} - -var hasRequiredPurge; - -function requirePurge () { - if (hasRequiredPurge) return purge.exports; - hasRequiredPurge = 1; - (function (module) { - var __defProp = Object.defineProperty; - var __getOwnPropDesc = Object.getOwnPropertyDescriptor; - var __getOwnPropNames = Object.getOwnPropertyNames; - var __hasOwnProp = Object.prototype.hasOwnProperty; - var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); - }; - var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; - }; - var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default")); - var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); - var purge_exports = {}; - __export(purge_exports, { - dangerouslyDeleteByTag: () => dangerouslyDeleteByTag, - invalidateByTag: () => invalidateByTag - }); - module.exports = __toCommonJS(purge_exports); - var import_get_context = requireGetContext$1(); - __reExport(purge_exports, requireTypes(), module.exports); - const invalidateByTag = (tag) => { - const api = (0, import_get_context.getContext)().purge; - if (api) { - return api.invalidateByTag(tag); - } - return Promise.resolve(); - }; - const dangerouslyDeleteByTag = (tag, options) => { - const api = (0, import_get_context.getContext)().purge; - if (api) { - return api.dangerouslyDeleteByTag(tag, options); - } - return Promise.resolve(); - }; - } (purge)); - return purge.exports; -} - -var functions; -var hasRequiredFunctions; - -function requireFunctions () { - if (hasRequiredFunctions) return functions; - hasRequiredFunctions = 1; - var __defProp = Object.defineProperty; - var __getOwnPropDesc = Object.getOwnPropertyDescriptor; - var __getOwnPropNames = Object.getOwnPropertyNames; - var __hasOwnProp = Object.prototype.hasOwnProperty; - var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); - }; - var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; - }; - var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); - var src_exports = {}; - __export(src_exports, { - attachDatabasePool: () => import_db_connections.attachDatabasePool, - dangerouslyDeleteByTag: () => import_purge.dangerouslyDeleteByTag, - experimental_attachDatabasePool: () => import_db_connections.experimental_attachDatabasePool, - geolocation: () => import_headers.geolocation, - getCache: () => import_cache.getCache, - getEnv: () => import_get_env.getEnv, - invalidateByTag: () => import_purge.invalidateByTag, - ipAddress: () => import_headers.ipAddress, - next: () => import_middleware.next, - rewrite: () => import_middleware.rewrite, - waitUntil: () => import_wait_until.waitUntil - }); - functions = __toCommonJS(src_exports); - var import_headers = requireHeaders$1(); - var import_get_env = requireGetEnv(); - var import_wait_until = requireWaitUntil(); - var import_middleware = requireMiddleware(); - var import_cache = requireCache$1(); - var import_db_connections = requireDbConnections(); - var import_purge = requirePurge(); - return functions; -} - -var functionsExports = requireFunctions(); - -/** - * Polyfill for `Promise.withResolvers()`. - * - * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers - */ -function withResolvers() { - let resolve; - let reject; - const promise = new Promise((_resolve, _reject) => { - resolve = _resolve; - reject = _reject; - }); - return { promise, resolve, reject }; -} -/** - * Creates a lazily-evaluated, memoized version of the provided function. - * - * The returned object exposes a `value` getter that calls `fn` only once, - * caches its result, and returns the cached value on subsequent accesses. - * - * @typeParam T - The return type of the provided function. - * @param fn - The function to be called once and whose result will be cached. - * @returns An object with a `value` property that returns the memoized result of `fn`. - */ -function once$1(fn) { - const result = { - get value() { - const value = fn(); - Object.defineProperty(result, 'value', { value }); - return value; - }, - }; - return result; -} -/** - * Parses a duration parameter (string, number, or Date) and returns a Date object - * representing when the duration should elapse. - * - * - For strings: Parses duration strings like "1s", "5m", "1h", etc. using the `ms` library - * - For numbers: Treats as milliseconds from now - * - For Date objects: Returns the date directly (handles both Date instances and date-like objects from deserialization) - * - * @param param - The duration parameter (StringValue, Date, or number of milliseconds) - * @returns A Date object representing when the duration should elapse - * @throws {Error} If the parameter is invalid or cannot be parsed - */ -function parseDurationToDate(param) { - if (typeof param === 'string') { - const durationMs = ms(param); - if (typeof durationMs !== 'number' || durationMs < 0) { - throw new Error(`Invalid duration: "${param}". Expected a valid duration string like "1s", "1m", "1h", etc.`); - } - return new Date(Date.now() + durationMs); - } - else if (typeof param === 'number') { - if (param < 0 || !Number.isFinite(param)) { - throw new Error(`Invalid duration: ${param}. Expected a non-negative finite number of milliseconds.`); - } - return new Date(Date.now() + param); - } - else if (param instanceof Date || - (param && - typeof param === 'object' && - typeof param.getTime === 'function')) { - // Handle both Date instances and date-like objects (from deserialization) - return param instanceof Date ? param : new Date(param.getTime()); - } - else { - throw new Error(`Invalid duration parameter. Expected a duration string, number (milliseconds), or Date object.`); - } -} - -const BASE_URL = 'https://useworkflow.dev/err'; -/** - * @internal - * Check if a value is an Error without relying on Node.js utilities. - * This is needed for error classes that can be used in VM contexts where - * Node.js imports are not available. - */ -function isError(value) { - return (typeof value === 'object' && - value !== null && - 'name' in value && - 'message' in value); -} -/** - * @internal - * All the slugs of the errors used for documentation links. - */ -const ERROR_SLUGS = { - WEBHOOK_INVALID_RESPOND_WITH_VALUE: 'webhook-invalid-respond-with-value', - WEBHOOK_RESPONSE_NOT_SENT: 'webhook-response-not-sent', - FETCH_IN_WORKFLOW_FUNCTION: 'fetch-in-workflow', -}; -/** - * The base class for all Workflow-related errors. - * - * This error is thrown by the Workflow DevKit when internal operations fail. - * You can use this class with `instanceof` to catch any Workflow DevKit error. - * - * @example - * ```ts - * try { - * await getRun(runId); - * } catch (error) { - * if (error instanceof WorkflowError) { - * console.error('Workflow DevKit error:', error.message); - * } - * } - * ``` - */ -class WorkflowError extends Error { - cause; - constructor(message, options) { - const msgDocs = options?.slug - ? `${message}\n\nLearn more: ${BASE_URL}/${options.slug}` - : message; - super(msgDocs, { cause: options?.cause }); - this.cause = options?.cause; - if (options?.cause instanceof Error) { - this.stack = `${this.stack}\nCaused by: ${options.cause.stack}`; - } - } - static is(value) { - return isError(value) && value.name === 'WorkflowError'; - } -} -/** - * Thrown when a Workflow API request fails. - * - * This error is thrown when HTTP requests to the Workflow backend fail, - * typically due to network issues, invalid requests, or server errors. - * - * @example - * ```ts - * try { - * await startWorkflow('myWorkflow', input); - * } catch (error) { - * if (error instanceof WorkflowAPIError) { - * console.error(`API error (${error.status}):`, error.message); - * } - * } - * ``` - */ -class WorkflowAPIError extends WorkflowError { - status; - code; - url; - constructor(message, options) { - super(message, { - cause: options?.cause, - }); - this.name = 'WorkflowAPIError'; - this.status = options?.status; - this.code = options?.code; - this.url = options?.url; - } - static is(value) { - return isError(value) && value.name === 'WorkflowAPIError'; - } -} -/** - * Thrown when a workflow run fails during execution. - * - * This error indicates that the workflow encountered a fatal error - * and cannot continue. The `cause` property contains the underlying - * error with its message, stack trace, and optional error code. - * - * @example - * ``` - * const run = await getRun(runId); - * if (run.status === 'failed') { - * // WorkflowRunFailedError will be thrown - * } - * ``` - */ -class WorkflowRunFailedError extends WorkflowError { - runId; - constructor(runId, error) { - // Create a proper Error instance from the StructuredError to set as cause - // NOTE: custom error types do not get serialized/deserialized. Everything is an Error - const causeError = new Error(error.message); - if (error.stack) { - causeError.stack = error.stack; - } - if (error.code) { - causeError.code = error.code; - } - super(`Workflow run "${runId}" failed: ${error.message}`, { - cause: causeError, - }); - this.name = 'WorkflowRunFailedError'; - this.runId = runId; - } - static is(value) { - return isError(value) && value.name === 'WorkflowRunFailedError'; - } -} -/** - * Thrown when attempting to get results from an incomplete workflow run. - * - * This error occurs when you try to access the result of a workflow - * that is still running or hasn't completed yet. - */ -class WorkflowRunNotCompletedError extends WorkflowError { - runId; - status; - constructor(runId, status) { - super(`Workflow run "${runId}" has not completed`, {}); - this.name = 'WorkflowRunNotCompletedError'; - this.runId = runId; - this.status = status; - } - static is(value) { - return isError(value) && value.name === 'WorkflowRunNotCompletedError'; - } -} -/** - * Thrown when the Workflow runtime encounters an internal error. - * - * This error indicates an issue with workflow execution, such as - * serialization failures, starting an invalid workflow function, or - * other runtime problems. - */ -class WorkflowRuntimeError extends WorkflowError { - constructor(message, options) { - super(message, { - ...options, - }); - this.name = 'WorkflowRuntimeError'; - } - static is(value) { - return isError(value) && value.name === 'WorkflowRuntimeError'; - } -} -class WorkflowRunNotFoundError extends WorkflowError { - runId; - constructor(runId) { - super(`Workflow run "${runId}" not found`, {}); - this.name = 'WorkflowRunNotFoundError'; - this.runId = runId; - } - static is(value) { - return isError(value) && value.name === 'WorkflowRunNotFoundError'; - } -} -class WorkflowRunCancelledError extends WorkflowError { - runId; - constructor(runId) { - super(`Workflow run "${runId}" cancelled`, {}); - this.name = 'WorkflowRunCancelledError'; - this.runId = runId; - } - static is(value) { - return isError(value) && value.name === 'WorkflowRunCancelledError'; - } -} -/** - * A fatal error is an error that cannot be retried. - * It will cause the step to fail and the error will - * be bubbled up to the workflow logic. - */ -class FatalError extends Error { - fatal = true; - constructor(message) { - super(message); - this.name = 'FatalError'; - } - static is(value) { - return isError(value) && value.name === 'FatalError'; - } -} -/** - * An error that can happen during a step execution, allowing - * for configuration of the retry behavior. - */ -class RetryableError extends Error { - /** - * The Date when the step should be retried. - */ - retryAfter; - constructor(message, options = {}) { - super(message); - this.name = 'RetryableError'; - if (options.retryAfter !== undefined) { - this.retryAfter = parseDurationToDate(options.retryAfter); - } - else { - // Default to 1 second (1000 milliseconds) - this.retryAfter = new Date(Date.now() + 1000); - } - } - static is(value) { - return isError(value) && value.name === 'RetryableError'; - } -} - -// Allow some arguments/options to be either a file path string or a file URL -const safeNormalizeFileUrl = (file, name) => { - const fileString = normalizeFileUrl(normalizeDenoExecPath(file)); - - if (typeof fileString !== 'string') { - throw new TypeError(`${name} must be a string or a file URL: ${fileString}.`); - } - - return fileString; -}; - -// In Deno node:process execPath is a special object, not just a string: -// https://github.com/denoland/deno/blob/f460188e583f00144000aa0d8ade08218d47c3c1/ext/node/polyfills/process.ts#L344 -const normalizeDenoExecPath = file => isDenoExecPath(file) - ? file.toString() - : file; - -const isDenoExecPath = file => typeof file !== 'string' - && file - && Object.getPrototypeOf(file) === String.prototype; - -// Same but also allows other values, e.g. `boolean` for the `shell` option -const normalizeFileUrl = file => file instanceof URL ? fileURLToPath(file) : file; - -// The command `arguments` and `options` are both optional. -// This also does basic validation on them and on the command file. -const normalizeParameters = (rawFile, rawArguments = [], rawOptions = {}) => { - const filePath = safeNormalizeFileUrl(rawFile, 'First argument'); - const [commandArguments, options] = isPlainObject(rawArguments) - ? [[], rawArguments] - : [rawArguments, rawOptions]; - - if (!Array.isArray(commandArguments)) { - throw new TypeError(`Second argument must be either an array of arguments or an options object: ${commandArguments}`); - } - - if (commandArguments.some(commandArgument => typeof commandArgument === 'object' && commandArgument !== null)) { - throw new TypeError(`Second argument must be an array of strings: ${commandArguments}`); - } - - const normalizedArguments = commandArguments.map(String); - const nullByteArgument = normalizedArguments.find(normalizedArgument => normalizedArgument.includes('\0')); - if (nullByteArgument !== undefined) { - throw new TypeError(`Arguments cannot contain null bytes ("\\0"): ${nullByteArgument}`); - } - - if (!isPlainObject(options)) { - throw new TypeError(`Last argument must be an options object: ${options}`); - } - - return [filePath, normalizedArguments, options]; -}; - -const {toString: objectToString$1} = Object.prototype; - -const isArrayBuffer = value => objectToString$1.call(value) === '[object ArrayBuffer]'; - -// Is either Uint8Array or Buffer -const isUint8Array = value => objectToString$1.call(value) === '[object Uint8Array]'; - -const bufferToUint8Array = buffer => new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength); - -const textEncoder$1 = new TextEncoder(); -const stringToUint8Array = string => textEncoder$1.encode(string); - -const textDecoder = new TextDecoder(); -const uint8ArrayToString = uint8Array => textDecoder.decode(uint8Array); - -const joinToString = (uint8ArraysOrStrings, encoding) => { - const strings = uint8ArraysToStrings(uint8ArraysOrStrings, encoding); - return strings.join(''); -}; - -const uint8ArraysToStrings = (uint8ArraysOrStrings, encoding) => { - if (encoding === 'utf8' && uint8ArraysOrStrings.every(uint8ArrayOrString => typeof uint8ArrayOrString === 'string')) { - return uint8ArraysOrStrings; - } - - const decoder = new StringDecoder(encoding); - const strings = uint8ArraysOrStrings - .map(uint8ArrayOrString => typeof uint8ArrayOrString === 'string' - ? stringToUint8Array(uint8ArrayOrString) - : uint8ArrayOrString) - .map(uint8Array => decoder.write(uint8Array)); - const finalString = decoder.end(); - return finalString === '' ? strings : [...strings, finalString]; -}; - -const joinToUint8Array = uint8ArraysOrStrings => { - if (uint8ArraysOrStrings.length === 1 && isUint8Array(uint8ArraysOrStrings[0])) { - return uint8ArraysOrStrings[0]; - } - - return concatUint8Arrays(stringsToUint8Arrays(uint8ArraysOrStrings)); -}; - -const stringsToUint8Arrays = uint8ArraysOrStrings => uint8ArraysOrStrings.map(uint8ArrayOrString => typeof uint8ArrayOrString === 'string' - ? stringToUint8Array(uint8ArrayOrString) - : uint8ArrayOrString); - -const concatUint8Arrays = uint8Arrays => { - const result = new Uint8Array(getJoinLength(uint8Arrays)); - - let index = 0; - for (const uint8Array of uint8Arrays) { - result.set(uint8Array, index); - index += uint8Array.length; - } - - return result; -}; - -const getJoinLength = uint8Arrays => { - let joinLength = 0; - for (const uint8Array of uint8Arrays) { - joinLength += uint8Array.length; - } - - return joinLength; -}; - -// Check whether the template string syntax is being used -const isTemplateString = templates => Array.isArray(templates) && Array.isArray(templates.raw); - -// Convert execa`file ...commandArguments` to execa(file, commandArguments) -const parseTemplates = (templates, expressions) => { - let tokens = []; - - for (const [index, template] of templates.entries()) { - tokens = parseTemplate({ - templates, - expressions, - tokens, - index, - template, - }); - } - - if (tokens.length === 0) { - throw new TypeError('Template script must not be empty'); - } - - const [file, ...commandArguments] = tokens; - return [file, commandArguments, {}]; -}; - -const parseTemplate = ({templates, expressions, tokens, index, template}) => { - if (template === undefined) { - throw new TypeError(`Invalid backslash sequence: ${templates.raw[index]}`); - } - - const {nextTokens, leadingWhitespaces, trailingWhitespaces} = splitByWhitespaces(template, templates.raw[index]); - const newTokens = concatTokens(tokens, nextTokens, leadingWhitespaces); - - if (index === expressions.length) { - return newTokens; - } - - const expression = expressions[index]; - const expressionTokens = Array.isArray(expression) - ? expression.map(expression => parseExpression(expression)) - : [parseExpression(expression)]; - return concatTokens(newTokens, expressionTokens, trailingWhitespaces); -}; - -// Like `string.split(/[ \t\r\n]+/)` except newlines and tabs are: -// - ignored when input as a backslash sequence like: `echo foo\n bar` -// - not ignored when input directly -// The only way to distinguish those in JavaScript is to use a tagged template and compare: -// - the first array argument, which does not escape backslash sequences -// - its `raw` property, which escapes them -const splitByWhitespaces = (template, rawTemplate) => { - if (rawTemplate.length === 0) { - return {nextTokens: [], leadingWhitespaces: false, trailingWhitespaces: false}; - } - - const nextTokens = []; - let templateStart = 0; - const leadingWhitespaces = DELIMITERS.has(rawTemplate[0]); - - for ( - let templateIndex = 0, rawIndex = 0; - templateIndex < template.length; - templateIndex += 1, rawIndex += 1 - ) { - const rawCharacter = rawTemplate[rawIndex]; - if (DELIMITERS.has(rawCharacter)) { - if (templateStart !== templateIndex) { - nextTokens.push(template.slice(templateStart, templateIndex)); - } - - templateStart = templateIndex + 1; - } else if (rawCharacter === '\\') { - const nextRawCharacter = rawTemplate[rawIndex + 1]; - if (nextRawCharacter === '\n') { - // Handles escaped newlines in templates - templateIndex -= 1; - rawIndex += 1; - } else if (nextRawCharacter === 'u' && rawTemplate[rawIndex + 2] === '{') { - rawIndex = rawTemplate.indexOf('}', rawIndex + 3); - } else { - rawIndex += ESCAPE_LENGTH[nextRawCharacter] ?? 1; - } - } - } - - const trailingWhitespaces = templateStart === template.length; - if (!trailingWhitespaces) { - nextTokens.push(template.slice(templateStart)); - } - - return {nextTokens, leadingWhitespaces, trailingWhitespaces}; -}; - -const DELIMITERS = new Set([' ', '\t', '\r', '\n']); - -// Number of characters in backslash escape sequences: \0 \xXX or \uXXXX -// \cX is allowed in RegExps but not in strings -// Octal sequences are not allowed in strict mode -const ESCAPE_LENGTH = {x: 3, u: 5}; - -const concatTokens = (tokens, nextTokens, isSeparated) => isSeparated - || tokens.length === 0 - || nextTokens.length === 0 - ? [...tokens, ...nextTokens] - : [ - ...tokens.slice(0, -1), - `${tokens.at(-1)}${nextTokens[0]}`, - ...nextTokens.slice(1), - ]; - -// Handle `${expression}` inside the template string syntax -const parseExpression = expression => { - const typeOfExpression = typeof expression; - - if (typeOfExpression === 'string') { - return expression; - } - - if (typeOfExpression === 'number') { - return String(expression); - } - - if (isPlainObject(expression) && ('stdout' in expression || 'isMaxBuffer' in expression)) { - return getSubprocessResult(expression); - } - - if (expression instanceof ChildProcess || Object.prototype.toString.call(expression) === '[object Promise]') { - // eslint-disable-next-line no-template-curly-in-string - throw new TypeError('Unexpected subprocess in template expression. Please use ${await subprocess} instead of ${subprocess}.'); - } - - throw new TypeError(`Unexpected "${typeOfExpression}" in template expression`); -}; - -const getSubprocessResult = ({stdout}) => { - if (typeof stdout === 'string') { - return stdout; - } - - if (isUint8Array(stdout)) { - return uint8ArrayToString(stdout); - } - - if (stdout === undefined) { - throw new TypeError('Missing result.stdout in template expression. This is probably due to the previous subprocess\' "stdout" option.'); - } - - throw new TypeError(`Unexpected "${typeof stdout}" stdout in template expression`); -}; - -const isStandardStream = stream => STANDARD_STREAMS.includes(stream); -const STANDARD_STREAMS = [process$2.stdin, process$2.stdout, process$2.stderr]; -const STANDARD_STREAMS_ALIASES = ['stdin', 'stdout', 'stderr']; -const getStreamName = fdNumber => STANDARD_STREAMS_ALIASES[fdNumber] ?? `stdio[${fdNumber}]`; - -// Some options can have different values for `stdout`/`stderr`/`fd3`. -// This normalizes those to array of values. -// For example, `{verbose: {stdout: 'none', stderr: 'full'}}` becomes `{verbose: ['none', 'none', 'full']}` -const normalizeFdSpecificOptions = options => { - const optionsCopy = {...options}; - - for (const optionName of FD_SPECIFIC_OPTIONS) { - optionsCopy[optionName] = normalizeFdSpecificOption(options, optionName); - } - - return optionsCopy; -}; - -const normalizeFdSpecificOption = (options, optionName) => { - const optionBaseArray = Array.from({length: getStdioLength(options) + 1}); - const optionArray = normalizeFdSpecificValue(options[optionName], optionBaseArray, optionName); - return addDefaultValue$1(optionArray, optionName); -}; - -const getStdioLength = ({stdio}) => Array.isArray(stdio) - ? Math.max(stdio.length, STANDARD_STREAMS_ALIASES.length) - : STANDARD_STREAMS_ALIASES.length; - -const normalizeFdSpecificValue = (optionValue, optionArray, optionName) => isPlainObject(optionValue) - ? normalizeOptionObject(optionValue, optionArray, optionName) - : optionArray.fill(optionValue); - -const normalizeOptionObject = (optionValue, optionArray, optionName) => { - for (const fdName of Object.keys(optionValue).sort(compareFdName)) { - for (const fdNumber of parseFdName(fdName, optionName, optionArray)) { - optionArray[fdNumber] = optionValue[fdName]; - } - } - - return optionArray; -}; - -// Ensure priority order when setting both `stdout`/`stderr`, `fd1`/`fd2`, and `all` -const compareFdName = (fdNameA, fdNameB) => getFdNameOrder(fdNameA) < getFdNameOrder(fdNameB) ? 1 : -1; - -const getFdNameOrder = fdName => { - if (fdName === 'stdout' || fdName === 'stderr') { - return 0; - } - - return fdName === 'all' ? 2 : 1; -}; - -const parseFdName = (fdName, optionName, optionArray) => { - if (fdName === 'ipc') { - return [optionArray.length - 1]; - } - - const fdNumber = parseFd(fdName); - if (fdNumber === undefined || fdNumber === 0) { - throw new TypeError(`"${optionName}.${fdName}" is invalid. -It must be "${optionName}.stdout", "${optionName}.stderr", "${optionName}.all", "${optionName}.ipc", or "${optionName}.fd3", "${optionName}.fd4" (and so on).`); - } - - if (fdNumber >= optionArray.length) { - throw new TypeError(`"${optionName}.${fdName}" is invalid: that file descriptor does not exist. -Please set the "stdio" option to ensure that file descriptor exists.`); - } - - return fdNumber === 'all' ? [1, 2] : [fdNumber]; -}; - -// Use the same syntax for fd-specific options and the `from`/`to` options -const parseFd = fdName => { - if (fdName === 'all') { - return fdName; - } - - if (STANDARD_STREAMS_ALIASES.includes(fdName)) { - return STANDARD_STREAMS_ALIASES.indexOf(fdName); - } - - const regexpResult = FD_REGEXP.exec(fdName); - if (regexpResult !== null) { - return Number(regexpResult[1]); - } -}; - -const FD_REGEXP = /^fd(\d+)$/; - -const addDefaultValue$1 = (optionArray, optionName) => optionArray.map(optionValue => optionValue === undefined - ? DEFAULT_OPTIONS[optionName] - : optionValue); - -// Default value for the `verbose` option -const verboseDefault = debuglog('execa').enabled ? 'full' : 'none'; - -const DEFAULT_OPTIONS = { - lines: false, - buffer: true, - maxBuffer: 1000 * 1000 * 100, - verbose: verboseDefault, - stripFinalNewline: true, -}; - -// List of options which can have different values for `stdout`/`stderr` -const FD_SPECIFIC_OPTIONS = ['lines', 'buffer', 'maxBuffer', 'verbose', 'stripFinalNewline']; - -// Retrieve fd-specific option -const getFdSpecificValue = (optionArray, fdNumber) => fdNumber === 'ipc' - ? optionArray.at(-1) - : optionArray[fdNumber]; - -// The `verbose` option can have different values for `stdout`/`stderr` -const isVerbose = ({verbose}, fdNumber) => getFdVerbose(verbose, fdNumber) !== 'none'; - -// Whether IPC and output and logged -const isFullVerbose = ({verbose}, fdNumber) => !['none', 'short'].includes(getFdVerbose(verbose, fdNumber)); - -// The `verbose` option can be a function to customize logging -const getVerboseFunction = ({verbose}, fdNumber) => { - const fdVerbose = getFdVerbose(verbose, fdNumber); - return isVerboseFunction(fdVerbose) ? fdVerbose : undefined; -}; - -// When using `verbose: {stdout, stderr, fd3, ipc}`: -// - `verbose.stdout|stderr|fd3` is used for 'output' -// - `verbose.ipc` is only used for 'ipc' -// - highest `verbose.*` value is used for 'command', 'error' and 'duration' -const getFdVerbose = (verbose, fdNumber) => fdNumber === undefined - ? getFdGenericVerbose(verbose) - : getFdSpecificValue(verbose, fdNumber); - -// When using `verbose: {stdout, stderr, fd3, ipc}` and logging is not specific to a file descriptor. -// We then use the highest `verbose.*` value, using the following order: -// - function > 'full' > 'short' > 'none' -// - if several functions are defined: stdout > stderr > fd3 > ipc -const getFdGenericVerbose = verbose => verbose.find(fdVerbose => isVerboseFunction(fdVerbose)) - ?? VERBOSE_VALUES.findLast(fdVerbose => verbose.includes(fdVerbose)); - -// Whether the `verbose` option is customized using a function -const isVerboseFunction = fdVerbose => typeof fdVerbose === 'function'; - -const VERBOSE_VALUES = ['none', 'short', 'full']; - -// Compute `result.command` and `result.escapedCommand` -const joinCommand = (filePath, rawArguments) => { - const fileAndArguments = [filePath, ...rawArguments]; - const command = fileAndArguments.join(' '); - const escapedCommand = fileAndArguments - .map(fileAndArgument => quoteString(escapeControlCharacters(fileAndArgument))) - .join(' '); - return {command, escapedCommand}; -}; - -// Remove ANSI sequences and escape control characters and newlines -const escapeLines = lines => stripVTControlCharacters(lines) - .split('\n') - .map(line => escapeControlCharacters(line)) - .join('\n'); - -const escapeControlCharacters = line => line.replaceAll(SPECIAL_CHAR_REGEXP, character => escapeControlCharacter(character)); - -const escapeControlCharacter = character => { - const commonEscape = COMMON_ESCAPES[character]; - if (commonEscape !== undefined) { - return commonEscape; - } - - const codepoint = character.codePointAt(0); - const codepointHex = codepoint.toString(16); - return codepoint <= ASTRAL_START - ? `\\u${codepointHex.padStart(4, '0')}` - : `\\U${codepointHex}`; -}; - -// Characters that would create issues when printed are escaped using the \u or \U notation. -// Those include control characters and newlines. -// The \u and \U notation is Bash specific, but there is no way to do this in a shell-agnostic way. -// Some shells do not even have a way to print those characters in an escaped fashion. -// Therefore, we prioritize printing those safely, instead of allowing those to be copy-pasted. -// List of Unicode character categories: https://www.fileformat.info/info/unicode/category/index.htm -const getSpecialCharRegExp = () => { - try { - // This throws when using Node.js without ICU support. - // When using a RegExp literal, this would throw at parsing-time, instead of runtime. - // eslint-disable-next-line prefer-regex-literals - return new RegExp('\\p{Separator}|\\p{Other}', 'gu'); - } catch { - // Similar to the above RegExp, but works even when Node.js has been built without ICU support. - // Unlike the above RegExp, it only covers whitespaces and C0/C1 control characters. - // It does not cover some edge cases, such as Unicode reserved characters. - // See https://github.com/sindresorhus/execa/issues/1143 - // eslint-disable-next-line no-control-regex - return /[\s\u0000-\u001F\u007F-\u009F\u00AD]/g; - } -}; - -const SPECIAL_CHAR_REGEXP = getSpecialCharRegExp(); - -// Accepted by $'...' in Bash. -// Exclude \a \e \v which are accepted in Bash but not in JavaScript (except \v) and JSON. -const COMMON_ESCAPES = { - ' ': ' ', - '\b': '\\b', - '\f': '\\f', - '\n': '\\n', - '\r': '\\r', - '\t': '\\t', -}; - -// Up until that codepoint, \u notation can be used instead of \U -const ASTRAL_START = 65_535; - -// Some characters are shell-specific, i.e. need to be escaped when the command is copy-pasted then run. -// Escaping is shell-specific. We cannot know which shell is used: `process.platform` detection is not enough. -// For example, Windows users could be using `cmd.exe`, Powershell or Bash for Windows which all use different escaping. -// We use '...' on Unix, which is POSIX shell compliant and escape all characters but ' so this is fairly safe. -// On Windows, we assume cmd.exe is used and escape with "...", which also works with Powershell. -const quoteString = escapedArgument => { - if (NO_ESCAPE_REGEXP.test(escapedArgument)) { - return escapedArgument; - } - - return platform === 'win32' - ? `"${escapedArgument.replaceAll('"', '""')}"` - : `'${escapedArgument.replaceAll('\'', '\'\\\'\'')}'`; -}; - -const NO_ESCAPE_REGEXP = /^[\w./-]+$/; - -function isUnicodeSupported() { - const {env} = process$2; - const {TERM, TERM_PROGRAM} = env; - - if (process$2.platform !== 'win32') { - return TERM !== 'linux'; // Linux console (kernel) - } - - return Boolean(env.WT_SESSION) // Windows Terminal - || Boolean(env.TERMINUS_SUBLIME) // Terminus (<0.2.27) - || env.ConEmuTask === '{cmd::Cmder}' // ConEmu and cmder - || TERM_PROGRAM === 'Terminus-Sublime' - || TERM_PROGRAM === 'vscode' - || TERM === 'xterm-256color' - || TERM === 'alacritty' - || TERM === 'rxvt-unicode' - || TERM === 'rxvt-unicode-256color' - || env.TERMINAL_EMULATOR === 'JetBrains-JediTerm'; -} - -const common = { - circleQuestionMark: '(?)', - questionMarkPrefix: '(?)', - square: '█', - squareDarkShade: '▓', - squareMediumShade: '▒', - squareLightShade: '░', - squareTop: '▀', - squareBottom: '▄', - squareLeft: '▌', - squareRight: '▐', - squareCenter: '■', - bullet: '●', - dot: '․', - ellipsis: '…', - pointerSmall: '›', - triangleUp: '▲', - triangleUpSmall: '▴', - triangleDown: '▼', - triangleDownSmall: '▾', - triangleLeftSmall: '◂', - triangleRightSmall: '▸', - home: '⌂', - heart: '♥', - musicNote: '♪', - musicNoteBeamed: '♫', - arrowUp: '↑', - arrowDown: '↓', - arrowLeft: '←', - arrowRight: '→', - arrowLeftRight: '↔', - arrowUpDown: '↕', - almostEqual: '≈', - notEqual: '≠', - lessOrEqual: '≤', - greaterOrEqual: '≥', - identical: '≡', - infinity: '∞', - subscriptZero: '₀', - subscriptOne: '₁', - subscriptTwo: '₂', - subscriptThree: '₃', - subscriptFour: '₄', - subscriptFive: '₅', - subscriptSix: '₆', - subscriptSeven: '₇', - subscriptEight: '₈', - subscriptNine: '₉', - oneHalf: '½', - oneThird: '⅓', - oneQuarter: '¼', - oneFifth: '⅕', - oneSixth: '⅙', - oneEighth: '⅛', - twoThirds: '⅔', - twoFifths: '⅖', - threeQuarters: '¾', - threeFifths: '⅗', - threeEighths: '⅜', - fourFifths: '⅘', - fiveSixths: '⅚', - fiveEighths: '⅝', - sevenEighths: '⅞', - line: '─', - lineBold: '━', - lineDouble: '═', - lineDashed0: '┄', - lineDashed1: '┅', - lineDashed2: '┈', - lineDashed3: '┉', - lineDashed4: '╌', - lineDashed5: '╍', - lineDashed6: '╴', - lineDashed7: '╶', - lineDashed8: '╸', - lineDashed9: '╺', - lineDashed10: '╼', - lineDashed11: '╾', - lineDashed12: '−', - lineDashed13: '–', - lineDashed14: '‐', - lineDashed15: '⁃', - lineVertical: '│', - lineVerticalBold: '┃', - lineVerticalDouble: '║', - lineVerticalDashed0: '┆', - lineVerticalDashed1: '┇', - lineVerticalDashed2: '┊', - lineVerticalDashed3: '┋', - lineVerticalDashed4: '╎', - lineVerticalDashed5: '╏', - lineVerticalDashed6: '╵', - lineVerticalDashed7: '╷', - lineVerticalDashed8: '╹', - lineVerticalDashed9: '╻', - lineVerticalDashed10: '╽', - lineVerticalDashed11: '╿', - lineDownLeft: '┐', - lineDownLeftArc: '╮', - lineDownBoldLeftBold: '┓', - lineDownBoldLeft: '┒', - lineDownLeftBold: '┑', - lineDownDoubleLeftDouble: '╗', - lineDownDoubleLeft: '╖', - lineDownLeftDouble: '╕', - lineDownRight: '┌', - lineDownRightArc: '╭', - lineDownBoldRightBold: '┏', - lineDownBoldRight: '┎', - lineDownRightBold: '┍', - lineDownDoubleRightDouble: '╔', - lineDownDoubleRight: '╓', - lineDownRightDouble: '╒', - lineUpLeft: '┘', - lineUpLeftArc: '╯', - lineUpBoldLeftBold: '┛', - lineUpBoldLeft: '┚', - lineUpLeftBold: '┙', - lineUpDoubleLeftDouble: '╝', - lineUpDoubleLeft: '╜', - lineUpLeftDouble: '╛', - lineUpRight: '└', - lineUpRightArc: '╰', - lineUpBoldRightBold: '┗', - lineUpBoldRight: '┖', - lineUpRightBold: '┕', - lineUpDoubleRightDouble: '╚', - lineUpDoubleRight: '╙', - lineUpRightDouble: '╘', - lineUpDownLeft: '┤', - lineUpBoldDownBoldLeftBold: '┫', - lineUpBoldDownBoldLeft: '┨', - lineUpDownLeftBold: '┥', - lineUpBoldDownLeftBold: '┩', - lineUpDownBoldLeftBold: '┪', - lineUpDownBoldLeft: '┧', - lineUpBoldDownLeft: '┦', - lineUpDoubleDownDoubleLeftDouble: '╣', - lineUpDoubleDownDoubleLeft: '╢', - lineUpDownLeftDouble: '╡', - lineUpDownRight: '├', - lineUpBoldDownBoldRightBold: '┣', - lineUpBoldDownBoldRight: '┠', - lineUpDownRightBold: '┝', - lineUpBoldDownRightBold: '┡', - lineUpDownBoldRightBold: '┢', - lineUpDownBoldRight: '┟', - lineUpBoldDownRight: '┞', - lineUpDoubleDownDoubleRightDouble: '╠', - lineUpDoubleDownDoubleRight: '╟', - lineUpDownRightDouble: '╞', - lineDownLeftRight: '┬', - lineDownBoldLeftBoldRightBold: '┳', - lineDownLeftBoldRightBold: '┯', - lineDownBoldLeftRight: '┰', - lineDownBoldLeftBoldRight: '┱', - lineDownBoldLeftRightBold: '┲', - lineDownLeftRightBold: '┮', - lineDownLeftBoldRight: '┭', - lineDownDoubleLeftDoubleRightDouble: '╦', - lineDownDoubleLeftRight: '╥', - lineDownLeftDoubleRightDouble: '╤', - lineUpLeftRight: '┴', - lineUpBoldLeftBoldRightBold: '┻', - lineUpLeftBoldRightBold: '┷', - lineUpBoldLeftRight: '┸', - lineUpBoldLeftBoldRight: '┹', - lineUpBoldLeftRightBold: '┺', - lineUpLeftRightBold: '┶', - lineUpLeftBoldRight: '┵', - lineUpDoubleLeftDoubleRightDouble: '╩', - lineUpDoubleLeftRight: '╨', - lineUpLeftDoubleRightDouble: '╧', - lineUpDownLeftRight: '┼', - lineUpBoldDownBoldLeftBoldRightBold: '╋', - lineUpDownBoldLeftBoldRightBold: '╈', - lineUpBoldDownLeftBoldRightBold: '╇', - lineUpBoldDownBoldLeftRightBold: '╊', - lineUpBoldDownBoldLeftBoldRight: '╉', - lineUpBoldDownLeftRight: '╀', - lineUpDownBoldLeftRight: '╁', - lineUpDownLeftBoldRight: '┽', - lineUpDownLeftRightBold: '┾', - lineUpBoldDownBoldLeftRight: '╂', - lineUpDownLeftBoldRightBold: '┿', - lineUpBoldDownLeftBoldRight: '╃', - lineUpBoldDownLeftRightBold: '╄', - lineUpDownBoldLeftBoldRight: '╅', - lineUpDownBoldLeftRightBold: '╆', - lineUpDoubleDownDoubleLeftDoubleRightDouble: '╬', - lineUpDoubleDownDoubleLeftRight: '╫', - lineUpDownLeftDoubleRightDouble: '╪', - lineCross: '╳', - lineBackslash: '╲', - lineSlash: '╱', -}; - -const specialMainSymbols = { - tick: '✔', - info: 'ℹ', - warning: '⚠', - cross: '✘', - squareSmall: '◻', - squareSmallFilled: '◼', - circle: '◯', - circleFilled: '◉', - circleDotted: '◌', - circleDouble: '◎', - circleCircle: 'ⓞ', - circleCross: 'ⓧ', - circlePipe: 'Ⓘ', - radioOn: '◉', - radioOff: '◯', - checkboxOn: '☒', - checkboxOff: '☐', - checkboxCircleOn: 'ⓧ', - checkboxCircleOff: 'Ⓘ', - pointer: '❯', - triangleUpOutline: '△', - triangleLeft: '◀', - triangleRight: '▶', - lozenge: '◆', - lozengeOutline: '◇', - hamburger: '☰', - smiley: '㋡', - mustache: '෴', - star: '★', - play: '▶', - nodejs: '⬢', - oneSeventh: '⅐', - oneNinth: '⅑', - oneTenth: '⅒', -}; - -const specialFallbackSymbols = { - tick: '√', - info: 'i', - warning: '‼', - cross: '×', - squareSmall: '□', - squareSmallFilled: '■', - circle: '( )', - circleFilled: '(*)', - circleDotted: '( )', - circleDouble: '( )', - circleCircle: '(○)', - circleCross: '(×)', - circlePipe: '(│)', - radioOn: '(*)', - radioOff: '( )', - checkboxOn: '[×]', - checkboxOff: '[ ]', - checkboxCircleOn: '(×)', - checkboxCircleOff: '( )', - pointer: '>', - triangleUpOutline: '∆', - triangleLeft: '◄', - triangleRight: '►', - lozenge: '♦', - lozengeOutline: '◊', - hamburger: '≡', - smiley: '☺', - mustache: '┌─┐', - star: '✶', - play: '►', - nodejs: '♦', - oneSeventh: '1/7', - oneNinth: '1/9', - oneTenth: '1/10', -}; - -const mainSymbols = {...common, ...specialMainSymbols}; -const fallbackSymbols = {...common, ...specialFallbackSymbols}; - -const shouldUseMain = isUnicodeSupported(); -const figures = shouldUseMain ? mainSymbols : fallbackSymbols; - -// Default when `verbose` is not a function -const defaultVerboseFunction = ({ - type, - message, - timestamp, - piped, - commandId, - result: {failed = false} = {}, - options: {reject = true}, -}) => { - const timestampString = serializeTimestamp(timestamp); - const icon = ICONS[type]({failed, reject, piped}); - const color = COLORS[type]({reject}); - return `${gray(`[${timestampString}]`)} ${gray(`[${commandId}]`)} ${color(icon)} ${color(message)}`; -}; - -// Prepending the timestamp allows debugging the slow paths of a subprocess -const serializeTimestamp = timestamp => `${padField(timestamp.getHours(), 2)}:${padField(timestamp.getMinutes(), 2)}:${padField(timestamp.getSeconds(), 2)}.${padField(timestamp.getMilliseconds(), 3)}`; - -const padField = (field, padding) => String(field).padStart(padding, '0'); - -const getFinalIcon = ({failed, reject}) => { - if (!failed) { - return figures.tick; - } - - return reject ? figures.cross : figures.warning; -}; - -const ICONS = { - command: ({piped}) => piped ? '|' : '$', - output: () => ' ', - ipc: () => '*', - error: getFinalIcon, - duration: getFinalIcon, -}; - -const identity$1 = string => string; - -const COLORS = { - command: () => bold, - output: () => identity$1, - ipc: () => identity$1, - error: ({reject}) => reject ? redBright : yellowBright, - duration: () => gray, -}; - -// Apply the `verbose` function on each line -const applyVerboseOnLines = (printedLines, verboseInfo, fdNumber) => { - const verboseFunction = getVerboseFunction(verboseInfo, fdNumber); - return printedLines - .map(({verboseLine, verboseObject}) => applyVerboseFunction(verboseLine, verboseObject, verboseFunction)) - .filter(printedLine => printedLine !== undefined) - .map(printedLine => appendNewline(printedLine)) - .join(''); -}; - -const applyVerboseFunction = (verboseLine, verboseObject, verboseFunction) => { - if (verboseFunction === undefined) { - return verboseLine; - } - - const printedLine = verboseFunction(verboseLine, verboseObject); - if (typeof printedLine === 'string') { - return printedLine; - } -}; - -const appendNewline = printedLine => printedLine.endsWith('\n') - ? printedLine - : `${printedLine}\n`; - -// This prints on stderr. -// If the subprocess prints on stdout and is using `stdout: 'inherit'`, -// there is a chance both writes will compete (introducing a race condition). -// This means their respective order is not deterministic. -// In particular, this means the verbose command lines might be after the start of the subprocess output. -// Using synchronous I/O does not solve this problem. -// However, this only seems to happen when the stdout/stderr target -// (e.g. a terminal) is being written to by many subprocesses at once, which is unlikely in real scenarios. -const verboseLog = ({type, verboseMessage, fdNumber, verboseInfo, result}) => { - const verboseObject = getVerboseObject({type, result, verboseInfo}); - const printedLines = getPrintedLines(verboseMessage, verboseObject); - const finalLines = applyVerboseOnLines(printedLines, verboseInfo, fdNumber); - if (finalLines !== '') { - console.warn(finalLines.slice(0, -1)); - } -}; - -const getVerboseObject = ({ - type, - result, - verboseInfo: {escapedCommand, commandId, rawOptions: {piped = false, ...options}}, -}) => ({ - type, - escapedCommand, - commandId: `${commandId}`, - timestamp: new Date(), - piped, - result, - options, -}); - -const getPrintedLines = (verboseMessage, verboseObject) => verboseMessage - .split('\n') - .map(message => getPrintedLine({...verboseObject, message})); - -const getPrintedLine = verboseObject => { - const verboseLine = defaultVerboseFunction(verboseObject); - return {verboseLine, verboseObject}; -}; - -// Serialize any type to a line string, for logging -const serializeVerboseMessage = message => { - const messageString = typeof message === 'string' ? message : inspect(message); - const escapedMessage = escapeLines(messageString); - return escapedMessage.replaceAll('\t', ' '.repeat(TAB_SIZE)); -}; - -// Same as `util.inspect()` -const TAB_SIZE = 2; - -// When `verbose` is `short|full|custom`, print each command -const logCommand = (escapedCommand, verboseInfo) => { - if (!isVerbose(verboseInfo)) { - return; - } - - verboseLog({ - type: 'command', - verboseMessage: escapedCommand, - verboseInfo, - }); -}; - -// Information computed before spawning, used by the `verbose` option -const getVerboseInfo = (verbose, escapedCommand, rawOptions) => { - validateVerbose(verbose); - const commandId = getCommandId(verbose); - return { - verbose, - escapedCommand, - commandId, - rawOptions, - }; -}; - -const getCommandId = verbose => isVerbose({verbose}) ? COMMAND_ID++ : undefined; - -// Prepending the `pid` is useful when multiple commands print their output at the same time. -// However, we cannot use the real PID since this is not available with `child_process.spawnSync()`. -// Also, we cannot use the real PID if we want to print it before `child_process.spawn()` is run. -// As a pro, it is shorter than a normal PID and never re-uses the same id. -// As a con, it cannot be used to send signals. -let COMMAND_ID = 0n; - -const validateVerbose = verbose => { - for (const fdVerbose of verbose) { - if (fdVerbose === false) { - throw new TypeError('The "verbose: false" option was renamed to "verbose: \'none\'".'); - } - - if (fdVerbose === true) { - throw new TypeError('The "verbose: true" option was renamed to "verbose: \'short\'".'); - } - - if (!VERBOSE_VALUES.includes(fdVerbose) && !isVerboseFunction(fdVerbose)) { - const allowedValues = VERBOSE_VALUES.map(allowedValue => `'${allowedValue}'`).join(', '); - throw new TypeError(`The "verbose" option must not be ${fdVerbose}. Allowed values are: ${allowedValues} or a function.`); - } - } -}; - -// Start counting time before spawning the subprocess -const getStartTime = () => hrtime.bigint(); - -// Compute duration after the subprocess ended. -// Printed by the `verbose` option. -const getDurationMs = startTime => Number(hrtime.bigint() - startTime) / 1e6; - -// Compute `result.command`, `result.escapedCommand` and `verbose`-related information -const handleCommand = (filePath, rawArguments, rawOptions) => { - const startTime = getStartTime(); - const {command, escapedCommand} = joinCommand(filePath, rawArguments); - const verbose = normalizeFdSpecificOption(rawOptions, 'verbose'); - const verboseInfo = getVerboseInfo(verbose, escapedCommand, {...rawOptions}); - logCommand(escapedCommand, verboseInfo); - return { - command, - escapedCommand, - startTime, - verboseInfo, - }; -}; - -var crossSpawn$1 = {exports: {}}; - -var windows$1; -var hasRequiredWindows; - -function requireWindows () { - if (hasRequiredWindows) return windows$1; - hasRequiredWindows = 1; - windows$1 = isexe; - isexe.sync = sync; - - var fs = require$$0; - - function checkPathExt (path, options) { - var pathext = options.pathExt !== undefined ? - options.pathExt : process.env.PATHEXT; - - if (!pathext) { - return true - } - - pathext = pathext.split(';'); - if (pathext.indexOf('') !== -1) { - return true - } - for (var i = 0; i < pathext.length; i++) { - var p = pathext[i].toLowerCase(); - if (p && path.substr(-p.length).toLowerCase() === p) { - return true - } - } - return false - } - - function checkStat (stat, path, options) { - if (!stat.isSymbolicLink() && !stat.isFile()) { - return false - } - return checkPathExt(path, options) - } - - function isexe (path, options, cb) { - fs.stat(path, function (er, stat) { - cb(er, er ? false : checkStat(stat, path, options)); - }); - } - - function sync (path, options) { - return checkStat(fs.statSync(path), path, options) - } - return windows$1; -} - -var mode; -var hasRequiredMode; - -function requireMode () { - if (hasRequiredMode) return mode; - hasRequiredMode = 1; - mode = isexe; - isexe.sync = sync; - - var fs = require$$0; - - function isexe (path, options, cb) { - fs.stat(path, function (er, stat) { - cb(er, er ? false : checkStat(stat, options)); - }); - } - - function sync (path, options) { - return checkStat(fs.statSync(path), options) - } - - function checkStat (stat, options) { - return stat.isFile() && checkMode(stat, options) - } - - function checkMode (stat, options) { - var mod = stat.mode; - var uid = stat.uid; - var gid = stat.gid; - - var myUid = options.uid !== undefined ? - options.uid : process.getuid && process.getuid(); - var myGid = options.gid !== undefined ? - options.gid : process.getgid && process.getgid(); - - var u = parseInt('100', 8); - var g = parseInt('010', 8); - var o = parseInt('001', 8); - var ug = u | g; - - var ret = (mod & o) || - (mod & g) && gid === myGid || - (mod & u) && uid === myUid || - (mod & ug) && myUid === 0; - - return ret - } - return mode; -} - -var isexe_1; -var hasRequiredIsexe; - -function requireIsexe () { - if (hasRequiredIsexe) return isexe_1; - hasRequiredIsexe = 1; - var core; - if (process.platform === 'win32' || commonjsGlobal.TESTING_WINDOWS) { - core = requireWindows(); - } else { - core = requireMode(); - } - - isexe_1 = isexe; - isexe.sync = sync; - - function isexe (path, options, cb) { - if (typeof options === 'function') { - cb = options; - options = {}; - } - - if (!cb) { - if (typeof Promise !== 'function') { - throw new TypeError('callback not provided') - } - - return new Promise(function (resolve, reject) { - isexe(path, options || {}, function (er, is) { - if (er) { - reject(er); - } else { - resolve(is); - } - }); - }) - } - - core(path, options || {}, function (er, is) { - // ignore EACCES because that just means we aren't allowed to run it - if (er) { - if (er.code === 'EACCES' || options && options.ignoreErrors) { - er = null; - is = false; - } - } - cb(er, is); - }); - } - - function sync (path, options) { - // my kingdom for a filtered catch - try { - return core.sync(path, options || {}) - } catch (er) { - if (options && options.ignoreErrors || er.code === 'EACCES') { - return false - } else { - throw er - } - } - } - return isexe_1; -} - -var which_1; -var hasRequiredWhich; - -function requireWhich () { - if (hasRequiredWhich) return which_1; - hasRequiredWhich = 1; - const isWindows = process.platform === 'win32' || - process.env.OSTYPE === 'cygwin' || - process.env.OSTYPE === 'msys'; - - const path = require$$0$1; - const COLON = isWindows ? ';' : ':'; - const isexe = requireIsexe(); - - const getNotFoundError = (cmd) => - Object.assign(new Error(`not found: ${cmd}`), { code: 'ENOENT' }); - - const getPathInfo = (cmd, opt) => { - const colon = opt.colon || COLON; - - // If it has a slash, then we don't bother searching the pathenv. - // just check the file itself, and that's it. - const pathEnv = cmd.match(/\//) || isWindows && cmd.match(/\\/) ? [''] - : ( - [ - // windows always checks the cwd first - ...(isWindows ? [process.cwd()] : []), - ...(opt.path || process.env.PATH || - /* istanbul ignore next: very unusual */ '').split(colon), - ] - ); - const pathExtExe = isWindows - ? opt.pathExt || process.env.PATHEXT || '.EXE;.CMD;.BAT;.COM' - : ''; - const pathExt = isWindows ? pathExtExe.split(colon) : ['']; - - if (isWindows) { - if (cmd.indexOf('.') !== -1 && pathExt[0] !== '') - pathExt.unshift(''); - } - - return { - pathEnv, - pathExt, - pathExtExe, - } - }; - - const which = (cmd, opt, cb) => { - if (typeof opt === 'function') { - cb = opt; - opt = {}; - } - if (!opt) - opt = {}; - - const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt); - const found = []; - - const step = i => new Promise((resolve, reject) => { - if (i === pathEnv.length) - return opt.all && found.length ? resolve(found) - : reject(getNotFoundError(cmd)) - - const ppRaw = pathEnv[i]; - const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw; - - const pCmd = path.join(pathPart, cmd); - const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd - : pCmd; - - resolve(subStep(p, i, 0)); - }); - - const subStep = (p, i, ii) => new Promise((resolve, reject) => { - if (ii === pathExt.length) - return resolve(step(i + 1)) - const ext = pathExt[ii]; - isexe(p + ext, { pathExt: pathExtExe }, (er, is) => { - if (!er && is) { - if (opt.all) - found.push(p + ext); - else - return resolve(p + ext) - } - return resolve(subStep(p, i, ii + 1)) - }); - }); - - return cb ? step(0).then(res => cb(null, res), cb) : step(0) - }; - - const whichSync = (cmd, opt) => { - opt = opt || {}; - - const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt); - const found = []; - - for (let i = 0; i < pathEnv.length; i ++) { - const ppRaw = pathEnv[i]; - const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw; - - const pCmd = path.join(pathPart, cmd); - const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd - : pCmd; - - for (let j = 0; j < pathExt.length; j ++) { - const cur = p + pathExt[j]; - try { - const is = isexe.sync(cur, { pathExt: pathExtExe }); - if (is) { - if (opt.all) - found.push(cur); - else - return cur - } - } catch (ex) {} - } - } - - if (opt.all && found.length) - return found - - if (opt.nothrow) - return null - - throw getNotFoundError(cmd) - }; - - which_1 = which; - which.sync = whichSync; - return which_1; -} - -var pathKey$1 = {exports: {}}; - -var hasRequiredPathKey; - -function requirePathKey () { - if (hasRequiredPathKey) return pathKey$1.exports; - hasRequiredPathKey = 1; - - const pathKey = (options = {}) => { - const environment = options.env || process.env; - const platform = options.platform || process.platform; - - if (platform !== 'win32') { - return 'PATH'; - } - - return Object.keys(environment).reverse().find(key => key.toUpperCase() === 'PATH') || 'Path'; - }; - - pathKey$1.exports = pathKey; - // TODO: Remove this for the next major release - pathKey$1.exports.default = pathKey; - return pathKey$1.exports; -} - -var resolveCommand_1; -var hasRequiredResolveCommand; - -function requireResolveCommand () { - if (hasRequiredResolveCommand) return resolveCommand_1; - hasRequiredResolveCommand = 1; - - const path = require$$0$1; - const which = requireWhich(); - const getPathKey = requirePathKey(); - - function resolveCommandAttempt(parsed, withoutPathExt) { - const env = parsed.options.env || process.env; - const cwd = process.cwd(); - const hasCustomCwd = parsed.options.cwd != null; - // Worker threads do not have process.chdir() - const shouldSwitchCwd = hasCustomCwd && process.chdir !== undefined && !process.chdir.disabled; - - // If a custom `cwd` was specified, we need to change the process cwd - // because `which` will do stat calls but does not support a custom cwd - if (shouldSwitchCwd) { - try { - process.chdir(parsed.options.cwd); - } catch (err) { - /* Empty */ - } - } - - let resolved; - - try { - resolved = which.sync(parsed.command, { - path: env[getPathKey({ env })], - pathExt: withoutPathExt ? path.delimiter : undefined, - }); - } catch (e) { - /* Empty */ - } finally { - if (shouldSwitchCwd) { - process.chdir(cwd); - } - } - - // If we successfully resolved, ensure that an absolute path is returned - // Note that when a custom `cwd` was used, we need to resolve to an absolute path based on it - if (resolved) { - resolved = path.resolve(hasCustomCwd ? parsed.options.cwd : '', resolved); - } - - return resolved; - } - - function resolveCommand(parsed) { - return resolveCommandAttempt(parsed) || resolveCommandAttempt(parsed, true); - } - - resolveCommand_1 = resolveCommand; - return resolveCommand_1; -} - -var _escape = {}; - -var hasRequired_escape; - -function require_escape () { - if (hasRequired_escape) return _escape; - hasRequired_escape = 1; - - // See http://www.robvanderwoude.com/escapechars.php - const metaCharsRegExp = /([()\][%!^"`<>&|;, *?])/g; - - function escapeCommand(arg) { - // Escape meta chars - arg = arg.replace(metaCharsRegExp, '^$1'); - - return arg; - } - - function escapeArgument(arg, doubleEscapeMetaChars) { - // Convert to string - arg = `${arg}`; - - // Algorithm below is based on https://qntm.org/cmd - // It's slightly altered to disable JS backtracking to avoid hanging on specially crafted input - // Please see https://github.com/moxystudio/node-cross-spawn/pull/160 for more information - - // Sequence of backslashes followed by a double quote: - // double up all the backslashes and escape the double quote - arg = arg.replace(/(?=(\\+?)?)\1"/g, '$1$1\\"'); - - // Sequence of backslashes followed by the end of the string - // (which will become a double quote later): - // double up all the backslashes - arg = arg.replace(/(?=(\\+?)?)\1$/, '$1$1'); - - // All other backslashes occur literally - - // Quote the whole thing: - arg = `"${arg}"`; - - // Escape meta chars - arg = arg.replace(metaCharsRegExp, '^$1'); - - // Double escape meta chars if necessary - if (doubleEscapeMetaChars) { - arg = arg.replace(metaCharsRegExp, '^$1'); - } - - return arg; - } - - _escape.command = escapeCommand; - _escape.argument = escapeArgument; - return _escape; -} - -var shebangRegex; -var hasRequiredShebangRegex; - -function requireShebangRegex () { - if (hasRequiredShebangRegex) return shebangRegex; - hasRequiredShebangRegex = 1; - shebangRegex = /^#!(.*)/; - return shebangRegex; -} - -var shebangCommand; -var hasRequiredShebangCommand; - -function requireShebangCommand () { - if (hasRequiredShebangCommand) return shebangCommand; - hasRequiredShebangCommand = 1; - const shebangRegex = requireShebangRegex(); - - shebangCommand = (string = '') => { - const match = string.match(shebangRegex); - - if (!match) { - return null; - } - - const [path, argument] = match[0].replace(/#! ?/, '').split(' '); - const binary = path.split('/').pop(); - - if (binary === 'env') { - return argument; - } - - return argument ? `${binary} ${argument}` : binary; - }; - return shebangCommand; -} - -var readShebang_1; -var hasRequiredReadShebang; - -function requireReadShebang () { - if (hasRequiredReadShebang) return readShebang_1; - hasRequiredReadShebang = 1; - - const fs = require$$0; - const shebangCommand = requireShebangCommand(); - - function readShebang(command) { - // Read the first 150 bytes from the file - const size = 150; - const buffer = Buffer.alloc(size); - - let fd; - - try { - fd = fs.openSync(command, 'r'); - fs.readSync(fd, buffer, 0, size, 0); - fs.closeSync(fd); - } catch (e) { /* Empty */ } - - // Attempt to extract shebang (null is returned if not a shebang) - return shebangCommand(buffer.toString()); - } - - readShebang_1 = readShebang; - return readShebang_1; -} - -var parse_1; -var hasRequiredParse$1; - -function requireParse$1 () { - if (hasRequiredParse$1) return parse_1; - hasRequiredParse$1 = 1; - - const path = require$$0$1; - const resolveCommand = requireResolveCommand(); - const escape = require_escape(); - const readShebang = requireReadShebang(); - - const isWin = process.platform === 'win32'; - const isExecutableRegExp = /\.(?:com|exe)$/i; - const isCmdShimRegExp = /node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i; - - function detectShebang(parsed) { - parsed.file = resolveCommand(parsed); - - const shebang = parsed.file && readShebang(parsed.file); - - if (shebang) { - parsed.args.unshift(parsed.file); - parsed.command = shebang; - - return resolveCommand(parsed); - } - - return parsed.file; - } - - function parseNonShell(parsed) { - if (!isWin) { - return parsed; - } - - // Detect & add support for shebangs - const commandFile = detectShebang(parsed); - - // We don't need a shell if the command filename is an executable - const needsShell = !isExecutableRegExp.test(commandFile); - - // If a shell is required, use cmd.exe and take care of escaping everything correctly - // Note that `forceShell` is an hidden option used only in tests - if (parsed.options.forceShell || needsShell) { - // Need to double escape meta chars if the command is a cmd-shim located in `node_modules/.bin/` - // The cmd-shim simply calls execute the package bin file with NodeJS, proxying any argument - // Because the escape of metachars with ^ gets interpreted when the cmd.exe is first called, - // we need to double escape them - const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile); - - // Normalize posix paths into OS compatible paths (e.g.: foo/bar -> foo\bar) - // This is necessary otherwise it will always fail with ENOENT in those cases - parsed.command = path.normalize(parsed.command); - - // Escape command & arguments - parsed.command = escape.command(parsed.command); - parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars)); - - const shellCommand = [parsed.command].concat(parsed.args).join(' '); - - parsed.args = ['/d', '/s', '/c', `"${shellCommand}"`]; - parsed.command = process.env.comspec || 'cmd.exe'; - parsed.options.windowsVerbatimArguments = true; // Tell node's spawn that the arguments are already escaped - } - - return parsed; - } - - function parse(command, args, options) { - // Normalize arguments, similar to nodejs - if (args && !Array.isArray(args)) { - options = args; - args = null; - } - - args = args ? args.slice(0) : []; // Clone array to avoid changing the original - options = Object.assign({}, options); // Clone object to avoid changing the original - - // Build our parsed object - const parsed = { - command, - args, - options, - file: undefined, - original: { - command, - args, - }, - }; - - // Delegate further parsing to shell or non-shell - return options.shell ? parsed : parseNonShell(parsed); - } - - parse_1 = parse; - return parse_1; -} - -var enoent; -var hasRequiredEnoent; - -function requireEnoent () { - if (hasRequiredEnoent) return enoent; - hasRequiredEnoent = 1; - - const isWin = process.platform === 'win32'; - - function notFoundError(original, syscall) { - return Object.assign(new Error(`${syscall} ${original.command} ENOENT`), { - code: 'ENOENT', - errno: 'ENOENT', - syscall: `${syscall} ${original.command}`, - path: original.command, - spawnargs: original.args, - }); - } - - function hookChildProcess(cp, parsed) { - if (!isWin) { - return; - } - - const originalEmit = cp.emit; - - cp.emit = function (name, arg1) { - // If emitting "exit" event and exit code is 1, we need to check if - // the command exists and emit an "error" instead - // See https://github.com/IndigoUnited/node-cross-spawn/issues/16 - if (name === 'exit') { - const err = verifyENOENT(arg1, parsed); - - if (err) { - return originalEmit.call(cp, 'error', err); - } - } - - return originalEmit.apply(cp, arguments); // eslint-disable-line prefer-rest-params - }; - } - - function verifyENOENT(status, parsed) { - if (isWin && status === 1 && !parsed.file) { - return notFoundError(parsed.original, 'spawn'); - } - - return null; - } - - function verifyENOENTSync(status, parsed) { - if (isWin && status === 1 && !parsed.file) { - return notFoundError(parsed.original, 'spawnSync'); - } - - return null; - } - - enoent = { - hookChildProcess, - verifyENOENT, - verifyENOENTSync, - notFoundError, - }; - return enoent; -} - -var hasRequiredCrossSpawn; - -function requireCrossSpawn () { - if (hasRequiredCrossSpawn) return crossSpawn$1.exports; - hasRequiredCrossSpawn = 1; - - const cp = require$$0$2; - const parse = requireParse$1(); - const enoent = requireEnoent(); - - function spawn(command, args, options) { - // Parse the arguments - const parsed = parse(command, args, options); - - // Spawn the child process - const spawned = cp.spawn(parsed.command, parsed.args, parsed.options); - - // Hook into child process "exit" event to emit an error if the command - // does not exists, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16 - enoent.hookChildProcess(spawned, parsed); - - return spawned; - } - - function spawnSync(command, args, options) { - // Parse the arguments - const parsed = parse(command, args, options); - - // Spawn the child process - const result = cp.spawnSync(parsed.command, parsed.args, parsed.options); - - // Analyze if the command does not exist, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16 - result.error = result.error || enoent.verifyENOENTSync(result.status, parsed); - - return result; - } - - crossSpawn$1.exports = spawn; - crossSpawn$1.exports.spawn = spawn; - crossSpawn$1.exports.sync = spawnSync; - - crossSpawn$1.exports._parse = parse; - crossSpawn$1.exports._enoent = enoent; - return crossSpawn$1.exports; -} - -var crossSpawnExports = requireCrossSpawn(); -const crossSpawn = /*@__PURE__*/getDefaultExportFromCjs(crossSpawnExports); - -function pathKey(options = {}) { - const { - env = process.env, - platform = process.platform - } = options; - - if (platform !== 'win32') { - return 'PATH'; - } - - return Object.keys(env).reverse().find(key => key.toUpperCase() === 'PATH') || 'Path'; -} - -promisify(execFile); - -function toPath(urlOrPath) { - return urlOrPath instanceof URL ? fileURLToPath(urlOrPath) : urlOrPath; -} - -function traversePathUp(startPath) { - return { - * [Symbol.iterator]() { - let currentPath = path.resolve(toPath(startPath)); - let previousPath; - - while (previousPath !== currentPath) { - yield currentPath; - previousPath = currentPath; - currentPath = path.resolve(currentPath, '..'); - } - }, - }; -} - -const npmRunPath = ({ - cwd = process$2.cwd(), - path: pathOption = process$2.env[pathKey()], - preferLocal = true, - execPath = process$2.execPath, - addExecPath = true, -} = {}) => { - const cwdPath = path.resolve(toPath(cwd)); - const result = []; - const pathParts = pathOption.split(path.delimiter); - - if (preferLocal) { - applyPreferLocal(result, pathParts, cwdPath); - } - - if (addExecPath) { - applyExecPath(result, pathParts, execPath, cwdPath); - } - - return pathOption === '' || pathOption === path.delimiter - ? `${result.join(path.delimiter)}${pathOption}` - : [...result, pathOption].join(path.delimiter); -}; - -const applyPreferLocal = (result, pathParts, cwdPath) => { - for (const directory of traversePathUp(cwdPath)) { - const pathPart = path.join(directory, 'node_modules/.bin'); - if (!pathParts.includes(pathPart)) { - result.push(pathPart); - } - } -}; - -// Ensure the running `node` binary is used -const applyExecPath = (result, pathParts, execPath, cwdPath) => { - const pathPart = path.resolve(cwdPath, toPath(execPath), '..'); - if (!pathParts.includes(pathPart)) { - result.push(pathPart); - } -}; - -const npmRunPathEnv = ({env = process$2.env, ...options} = {}) => { - env = {...env}; - - const pathName = pathKey({env}); - options.path = env[pathName]; - env[pathName] = npmRunPath(options); - - return env; -}; - -// When the subprocess fails, this is the error instance being returned. -// If another error instance is being thrown, it is kept as `error.cause`. -const getFinalError = (originalError, message, isSync) => { - const ErrorClass = isSync ? ExecaSyncError : ExecaError; - const options = originalError instanceof DiscardedError ? {} : {cause: originalError}; - return new ErrorClass(message, options); -}; - -// Indicates that the error is used only to interrupt control flow, but not in the return value -class DiscardedError extends Error {} - -// Proper way to set `error.name`: it should be inherited and non-enumerable -const setErrorName = (ErrorClass, value) => { - Object.defineProperty(ErrorClass.prototype, 'name', { - value, - writable: true, - enumerable: false, - configurable: true, - }); - Object.defineProperty(ErrorClass.prototype, execaErrorSymbol, { - value: true, - writable: false, - enumerable: false, - configurable: false, - }); -}; - -// Unlike `instanceof`, this works across realms -const isExecaError = error => isErrorInstance(error) && execaErrorSymbol in error; - -const execaErrorSymbol = Symbol('isExecaError'); - -const isErrorInstance = value => Object.prototype.toString.call(value) === '[object Error]'; - -// We use two different Error classes for async/sync methods since they have slightly different shape and types -class ExecaError extends Error {} -setErrorName(ExecaError, ExecaError.name); - -class ExecaSyncError extends Error {} -setErrorName(ExecaSyncError, ExecaSyncError.name); - -const getRealtimeSignals=()=>{ -const length=SIGRTMAX-SIGRTMIN+1; -return Array.from({length},getRealtimeSignal) -}; - -const getRealtimeSignal=(value,index)=>({ -name:`SIGRT${index+1}`, -number:SIGRTMIN+index, -action:"terminate", -description:"Application-specific signal (realtime)", -standard:"posix" -}); - -const SIGRTMIN=34; -const SIGRTMAX=64; - -const SIGNALS=[ -{ -name:"SIGHUP", -number:1, -action:"terminate", -description:"Terminal closed", -standard:"posix" -}, -{ -name:"SIGINT", -number:2, -action:"terminate", -description:"User interruption with CTRL-C", -standard:"ansi" -}, -{ -name:"SIGQUIT", -number:3, -action:"core", -description:"User interruption with CTRL-\\", -standard:"posix" -}, -{ -name:"SIGILL", -number:4, -action:"core", -description:"Invalid machine instruction", -standard:"ansi" -}, -{ -name:"SIGTRAP", -number:5, -action:"core", -description:"Debugger breakpoint", -standard:"posix" -}, -{ -name:"SIGABRT", -number:6, -action:"core", -description:"Aborted", -standard:"ansi" -}, -{ -name:"SIGIOT", -number:6, -action:"core", -description:"Aborted", -standard:"bsd" -}, -{ -name:"SIGBUS", -number:7, -action:"core", -description: -"Bus error due to misaligned, non-existing address or paging error", -standard:"bsd" -}, -{ -name:"SIGEMT", -number:7, -action:"terminate", -description:"Command should be emulated but is not implemented", -standard:"other" -}, -{ -name:"SIGFPE", -number:8, -action:"core", -description:"Floating point arithmetic error", -standard:"ansi" -}, -{ -name:"SIGKILL", -number:9, -action:"terminate", -description:"Forced termination", -standard:"posix", -forced:true -}, -{ -name:"SIGUSR1", -number:10, -action:"terminate", -description:"Application-specific signal", -standard:"posix" -}, -{ -name:"SIGSEGV", -number:11, -action:"core", -description:"Segmentation fault", -standard:"ansi" -}, -{ -name:"SIGUSR2", -number:12, -action:"terminate", -description:"Application-specific signal", -standard:"posix" -}, -{ -name:"SIGPIPE", -number:13, -action:"terminate", -description:"Broken pipe or socket", -standard:"posix" -}, -{ -name:"SIGALRM", -number:14, -action:"terminate", -description:"Timeout or timer", -standard:"posix" -}, -{ -name:"SIGTERM", -number:15, -action:"terminate", -description:"Termination", -standard:"ansi" -}, -{ -name:"SIGSTKFLT", -number:16, -action:"terminate", -description:"Stack is empty or overflowed", -standard:"other" -}, -{ -name:"SIGCHLD", -number:17, -action:"ignore", -description:"Child process terminated, paused or unpaused", -standard:"posix" -}, -{ -name:"SIGCLD", -number:17, -action:"ignore", -description:"Child process terminated, paused or unpaused", -standard:"other" -}, -{ -name:"SIGCONT", -number:18, -action:"unpause", -description:"Unpaused", -standard:"posix", -forced:true -}, -{ -name:"SIGSTOP", -number:19, -action:"pause", -description:"Paused", -standard:"posix", -forced:true -}, -{ -name:"SIGTSTP", -number:20, -action:"pause", -description:"Paused using CTRL-Z or \"suspend\"", -standard:"posix" -}, -{ -name:"SIGTTIN", -number:21, -action:"pause", -description:"Background process cannot read terminal input", -standard:"posix" -}, -{ -name:"SIGBREAK", -number:21, -action:"terminate", -description:"User interruption with CTRL-BREAK", -standard:"other" -}, -{ -name:"SIGTTOU", -number:22, -action:"pause", -description:"Background process cannot write to terminal output", -standard:"posix" -}, -{ -name:"SIGURG", -number:23, -action:"ignore", -description:"Socket received out-of-band data", -standard:"bsd" -}, -{ -name:"SIGXCPU", -number:24, -action:"core", -description:"Process timed out", -standard:"bsd" -}, -{ -name:"SIGXFSZ", -number:25, -action:"core", -description:"File too big", -standard:"bsd" -}, -{ -name:"SIGVTALRM", -number:26, -action:"terminate", -description:"Timeout or timer", -standard:"bsd" -}, -{ -name:"SIGPROF", -number:27, -action:"terminate", -description:"Timeout or timer", -standard:"bsd" -}, -{ -name:"SIGWINCH", -number:28, -action:"ignore", -description:"Terminal window size changed", -standard:"bsd" -}, -{ -name:"SIGIO", -number:29, -action:"terminate", -description:"I/O is available", -standard:"other" -}, -{ -name:"SIGPOLL", -number:29, -action:"terminate", -description:"Watched event", -standard:"other" -}, -{ -name:"SIGINFO", -number:29, -action:"ignore", -description:"Request for process information", -standard:"other" -}, -{ -name:"SIGPWR", -number:30, -action:"terminate", -description:"Device running out of power", -standard:"systemv" -}, -{ -name:"SIGSYS", -number:31, -action:"core", -description:"Invalid system call", -standard:"other" -}, -{ -name:"SIGUNUSED", -number:31, -action:"terminate", -description:"Invalid system call", -standard:"other" -}]; - -const getSignals=()=>{ -const realtimeSignals=getRealtimeSignals(); -const signals=[...SIGNALS,...realtimeSignals].map(normalizeSignal$1); -return signals -}; - - - - - - - -const normalizeSignal$1=({ -name, -number:defaultNumber, -description, -action, -forced=false, -standard -})=>{ -const{ -signals:{[name]:constantSignal} -}=constants$5; -const supported=constantSignal!==undefined; -const number=supported?constantSignal:defaultNumber; -return {name,number,description,supported,action,forced,standard} -}; - -const getSignalsByName=()=>{ -const signals=getSignals(); -return Object.fromEntries(signals.map(getSignalByName)) -}; - -const getSignalByName=({ -name, -number, -description, -supported, -action, -forced, -standard -})=>[name,{name,number,description,supported,action,forced,standard}]; - -const signalsByName=getSignalsByName(); - - - - -const getSignalsByNumber=()=>{ -const signals=getSignals(); -const length=SIGRTMAX+1; -const signalsA=Array.from({length},(value,number)=> -getSignalByNumber(number,signals) -); -return Object.assign({},...signalsA) -}; - -const getSignalByNumber=(number,signals)=>{ -const signal=findSignalByNumber(number,signals); - -if(signal===undefined){ -return {} -} - -const{name,description,supported,action,forced,standard}=signal; -return { -[number]:{ -name, -number, -description, -supported, -action, -forced, -standard -} -} -}; - - - -const findSignalByNumber=(number,signals)=>{ -const signal=signals.find(({name})=>constants$5.signals[name]===number); - -if(signal!==undefined){ -return signal -} - -return signals.find((signalA)=>signalA.number===number) -}; - -getSignalsByNumber(); - -// Normalize signals for comparison purpose. -// Also validate the signal exists. -const normalizeKillSignal = killSignal => { - const optionName = 'option `killSignal`'; - if (killSignal === 0) { - throw new TypeError(`Invalid ${optionName}: 0 cannot be used.`); - } - - return normalizeSignal(killSignal, optionName); -}; - -const normalizeSignalArgument = signal => signal === 0 - ? signal - : normalizeSignal(signal, '`subprocess.kill()`\'s argument'); - -const normalizeSignal = (signalNameOrInteger, optionName) => { - if (Number.isInteger(signalNameOrInteger)) { - return normalizeSignalInteger(signalNameOrInteger, optionName); - } - - if (typeof signalNameOrInteger === 'string') { - return normalizeSignalName(signalNameOrInteger, optionName); - } - - throw new TypeError(`Invalid ${optionName} ${String(signalNameOrInteger)}: it must be a string or an integer.\n${getAvailableSignals()}`); -}; - -const normalizeSignalInteger = (signalInteger, optionName) => { - if (signalsIntegerToName.has(signalInteger)) { - return signalsIntegerToName.get(signalInteger); - } - - throw new TypeError(`Invalid ${optionName} ${signalInteger}: this signal integer does not exist.\n${getAvailableSignals()}`); -}; - -const getSignalsIntegerToName = () => new Map(Object.entries(constants$5.signals) - .reverse() - .map(([signalName, signalInteger]) => [signalInteger, signalName])); - -const signalsIntegerToName = getSignalsIntegerToName(); - -const normalizeSignalName = (signalName, optionName) => { - if (signalName in constants$5.signals) { - return signalName; - } - - if (signalName.toUpperCase() in constants$5.signals) { - throw new TypeError(`Invalid ${optionName} '${signalName}': please rename it to '${signalName.toUpperCase()}'.`); - } - - throw new TypeError(`Invalid ${optionName} '${signalName}': this signal name does not exist.\n${getAvailableSignals()}`); -}; - -const getAvailableSignals = () => `Available signal names: ${getAvailableSignalNames()}. -Available signal numbers: ${getAvailableSignalIntegers()}.`; - -const getAvailableSignalNames = () => Object.keys(constants$5.signals) - .sort() - .map(signalName => `'${signalName}'`) - .join(', '); - -const getAvailableSignalIntegers = () => [...new Set(Object.values(constants$5.signals) - .sort((signalInteger, signalIntegerTwo) => signalInteger - signalIntegerTwo))] - .join(', '); - -// Human-friendly description of a signal -const getSignalDescription = signal => signalsByName[signal].description; - -// Normalize the `forceKillAfterDelay` option -const normalizeForceKillAfterDelay = forceKillAfterDelay => { - if (forceKillAfterDelay === false) { - return forceKillAfterDelay; - } - - if (forceKillAfterDelay === true) { - return DEFAULT_FORCE_KILL_TIMEOUT; - } - - if (!Number.isFinite(forceKillAfterDelay) || forceKillAfterDelay < 0) { - throw new TypeError(`Expected the \`forceKillAfterDelay\` option to be a non-negative integer, got \`${forceKillAfterDelay}\` (${typeof forceKillAfterDelay})`); - } - - return forceKillAfterDelay; -}; - -const DEFAULT_FORCE_KILL_TIMEOUT = 1000 * 5; - -// Monkey-patches `subprocess.kill()` to add `forceKillAfterDelay` behavior and `.kill(error)` -const subprocessKill = ( - {kill, options: {forceKillAfterDelay, killSignal}, onInternalError, context, controller}, - signalOrError, - errorArgument, -) => { - const {signal, error} = parseKillArguments(signalOrError, errorArgument, killSignal); - emitKillError(error, onInternalError); - const killResult = kill(signal); - setKillTimeout({ - kill, - signal, - forceKillAfterDelay, - killSignal, - killResult, - context, - controller, - }); - return killResult; -}; - -const parseKillArguments = (signalOrError, errorArgument, killSignal) => { - const [signal = killSignal, error] = isErrorInstance(signalOrError) - ? [undefined, signalOrError] - : [signalOrError, errorArgument]; - - if (typeof signal !== 'string' && !Number.isInteger(signal)) { - throw new TypeError(`The first argument must be an error instance or a signal name string/integer: ${String(signal)}`); - } - - if (error !== undefined && !isErrorInstance(error)) { - throw new TypeError(`The second argument is optional. If specified, it must be an error instance: ${error}`); - } - - return {signal: normalizeSignalArgument(signal), error}; -}; - -// Fails right away when calling `subprocess.kill(error)`. -// Does not wait for actual signal termination. -// Uses a deferred promise instead of the `error` event on the subprocess, as this is less intrusive. -const emitKillError = (error, onInternalError) => { - if (error !== undefined) { - onInternalError.reject(error); - } -}; - -const setKillTimeout = async ({kill, signal, forceKillAfterDelay, killSignal, killResult, context, controller}) => { - if (signal === killSignal && killResult) { - killOnTimeout({ - kill, - forceKillAfterDelay, - context, - controllerSignal: controller.signal, - }); - } -}; - -// Forcefully terminate a subprocess after a timeout -const killOnTimeout = async ({kill, forceKillAfterDelay, context, controllerSignal}) => { - if (forceKillAfterDelay === false) { - return; - } - - try { - await setTimeout$1(forceKillAfterDelay, undefined, {signal: controllerSignal}); - if (kill('SIGKILL')) { - context.isForcefullyTerminated ??= true; - } - } catch {} -}; - -// Combines `util.aborted()` and `events.addAbortListener()`: promise-based and cleaned up with a stop signal -const onAbortedSignal = async (mainSignal, stopSignal) => { - if (!mainSignal.aborted) { - await once$2(mainSignal, 'abort', {signal: stopSignal}); - } -}; - -// Validate the `cancelSignal` option -const validateCancelSignal = ({cancelSignal}) => { - if (cancelSignal !== undefined && Object.prototype.toString.call(cancelSignal) !== '[object AbortSignal]') { - throw new Error(`The \`cancelSignal\` option must be an AbortSignal: ${String(cancelSignal)}`); - } -}; - -// Terminate the subprocess when aborting the `cancelSignal` option and `gracefulSignal` is `false` -const throwOnCancel = ({subprocess, cancelSignal, gracefulCancel, context, controller}) => cancelSignal === undefined || gracefulCancel - ? [] - : [terminateOnCancel(subprocess, cancelSignal, context, controller)]; - -const terminateOnCancel = async (subprocess, cancelSignal, context, {signal}) => { - await onAbortedSignal(cancelSignal, signal); - context.terminationReason ??= 'cancel'; - subprocess.kill(); - throw cancelSignal.reason; -}; - -// Validate the IPC channel is connected before receiving/sending messages -const validateIpcMethod = ({methodName, isSubprocess, ipc, isConnected}) => { - validateIpcOption(methodName, isSubprocess, ipc); - validateConnection(methodName, isSubprocess, isConnected); -}; - -// Better error message when forgetting to set `ipc: true` and using the IPC methods -const validateIpcOption = (methodName, isSubprocess, ipc) => { - if (!ipc) { - throw new Error(`${getMethodName(methodName, isSubprocess)} can only be used if the \`ipc\` option is \`true\`.`); - } -}; - -// Better error message when one process does not send/receive messages once the other process has disconnected. -// This also makes it clear that any buffered messages are lost once either process has disconnected. -// Also when aborting `cancelSignal` after disconnecting the IPC. -const validateConnection = (methodName, isSubprocess, isConnected) => { - if (!isConnected) { - throw new Error(`${getMethodName(methodName, isSubprocess)} cannot be used: the ${getOtherProcessName(isSubprocess)} has already exited or disconnected.`); - } -}; - -// When `getOneMessage()` could not complete due to an early disconnection -const throwOnEarlyDisconnect = isSubprocess => { - throw new Error(`${getMethodName('getOneMessage', isSubprocess)} could not complete: the ${getOtherProcessName(isSubprocess)} exited or disconnected.`); -}; - -// When both processes use `sendMessage()` with `strict` at the same time -const throwOnStrictDeadlockError = isSubprocess => { - throw new Error(`${getMethodName('sendMessage', isSubprocess)} failed: the ${getOtherProcessName(isSubprocess)} is sending a message too, instead of listening to incoming messages. -This can be fixed by both sending a message and listening to incoming messages at the same time: - -const [receivedMessage] = await Promise.all([ - ${getMethodName('getOneMessage', isSubprocess)}, - ${getMethodName('sendMessage', isSubprocess, 'message, {strict: true}')}, -]);`); -}; - -// When the other process used `strict` but the current process had I/O error calling `sendMessage()` for the response -const getStrictResponseError = (error, isSubprocess) => new Error(`${getMethodName('sendMessage', isSubprocess)} failed when sending an acknowledgment response to the ${getOtherProcessName(isSubprocess)}.`, {cause: error}); - -// When using `strict` but the other process was not listening for messages -const throwOnMissingStrict = isSubprocess => { - throw new Error(`${getMethodName('sendMessage', isSubprocess)} failed: the ${getOtherProcessName(isSubprocess)} is not listening to incoming messages.`); -}; - -// When using `strict` but the other process disconnected before receiving the message -const throwOnStrictDisconnect = isSubprocess => { - throw new Error(`${getMethodName('sendMessage', isSubprocess)} failed: the ${getOtherProcessName(isSubprocess)} exited without listening to incoming messages.`); -}; - -// When the current process disconnects while the subprocess is listening to `cancelSignal` -const getAbortDisconnectError = () => new Error(`\`cancelSignal\` aborted: the ${getOtherProcessName(true)} disconnected.`); - -// When the subprocess uses `cancelSignal` but not the current process -const throwOnMissingParent = () => { - throw new Error('`getCancelSignal()` cannot be used without setting the `cancelSignal` subprocess option.'); -}; - -// EPIPE can happen when sending a message to a subprocess that is closing but has not disconnected yet -const handleEpipeError = ({error, methodName, isSubprocess}) => { - if (error.code === 'EPIPE') { - throw new Error(`${getMethodName(methodName, isSubprocess)} cannot be used: the ${getOtherProcessName(isSubprocess)} is disconnecting.`, {cause: error}); - } -}; - -// Better error message when sending messages which cannot be serialized. -// Works with both `serialization: 'advanced'` and `serialization: 'json'`. -const handleSerializationError = ({error, methodName, isSubprocess, message}) => { - if (isSerializationError(error)) { - throw new Error(`${getMethodName(methodName, isSubprocess)}'s argument type is invalid: the message cannot be serialized: ${String(message)}.`, {cause: error}); - } -}; - -const isSerializationError = ({code, message}) => SERIALIZATION_ERROR_CODES.has(code) - || SERIALIZATION_ERROR_MESSAGES.some(serializationErrorMessage => message.includes(serializationErrorMessage)); - -// `error.code` set by Node.js when it failed to serialize the message -const SERIALIZATION_ERROR_CODES = new Set([ - // Message is `undefined` - 'ERR_MISSING_ARGS', - // Message is a function, a bigint, a symbol - 'ERR_INVALID_ARG_TYPE', -]); - -// `error.message` set by Node.js when it failed to serialize the message -const SERIALIZATION_ERROR_MESSAGES = [ - // Message is a promise or a proxy, with `serialization: 'advanced'` - 'could not be cloned', - // Message has cycles, with `serialization: 'json'` - 'circular structure', - // Message has cycles inside toJSON(), with `serialization: 'json'` - 'call stack size exceeded', -]; - -const getMethodName = (methodName, isSubprocess, parameters = '') => methodName === 'cancelSignal' - ? '`cancelSignal`\'s `controller.abort()`' - : `${getNamespaceName(isSubprocess)}${methodName}(${parameters})`; - -const getNamespaceName = isSubprocess => isSubprocess ? '' : 'subprocess.'; - -const getOtherProcessName = isSubprocess => isSubprocess ? 'parent process' : 'subprocess'; - -// When any error arises, we disconnect the IPC. -// Otherwise, it is likely that one of the processes will stop sending/receiving messages. -// This would leave the other process hanging. -const disconnect = anyProcess => { - if (anyProcess.connected) { - anyProcess.disconnect(); - } -}; - -const createDeferred = () => { - const methods = {}; - const promise = new Promise((resolve, reject) => { - Object.assign(methods, {resolve, reject}); - }); - return Object.assign(promise, methods); -}; - -// Retrieve stream targeted by the `to` option -const getToStream = (destination, to = 'stdin') => { - const isWritable = true; - const {options, fileDescriptors} = SUBPROCESS_OPTIONS.get(destination); - const fdNumber = getFdNumber(fileDescriptors, to, isWritable); - const destinationStream = destination.stdio[fdNumber]; - - if (destinationStream === null) { - throw new TypeError(getInvalidStdioOptionMessage(fdNumber, to, options, isWritable)); - } - - return destinationStream; -}; - -// Retrieve stream targeted by the `from` option -const getFromStream = (source, from = 'stdout') => { - const isWritable = false; - const {options, fileDescriptors} = SUBPROCESS_OPTIONS.get(source); - const fdNumber = getFdNumber(fileDescriptors, from, isWritable); - const sourceStream = fdNumber === 'all' ? source.all : source.stdio[fdNumber]; - - if (sourceStream === null || sourceStream === undefined) { - throw new TypeError(getInvalidStdioOptionMessage(fdNumber, from, options, isWritable)); - } - - return sourceStream; -}; - -// Keeps track of the options passed to each Execa call -const SUBPROCESS_OPTIONS = new WeakMap(); - -const getFdNumber = (fileDescriptors, fdName, isWritable) => { - const fdNumber = parseFdNumber(fdName, isWritable); - validateFdNumber(fdNumber, fdName, isWritable, fileDescriptors); - return fdNumber; -}; - -const parseFdNumber = (fdName, isWritable) => { - const fdNumber = parseFd(fdName); - if (fdNumber !== undefined) { - return fdNumber; - } - - const {validOptions, defaultValue} = isWritable - ? {validOptions: '"stdin"', defaultValue: 'stdin'} - : {validOptions: '"stdout", "stderr", "all"', defaultValue: 'stdout'}; - throw new TypeError(`"${getOptionName(isWritable)}" must not be "${fdName}". -It must be ${validOptions} or "fd3", "fd4" (and so on). -It is optional and defaults to "${defaultValue}".`); -}; - -const validateFdNumber = (fdNumber, fdName, isWritable, fileDescriptors) => { - const fileDescriptor = fileDescriptors[getUsedDescriptor(fdNumber)]; - if (fileDescriptor === undefined) { - throw new TypeError(`"${getOptionName(isWritable)}" must not be ${fdName}. That file descriptor does not exist. -Please set the "stdio" option to ensure that file descriptor exists.`); - } - - if (fileDescriptor.direction === 'input' && !isWritable) { - throw new TypeError(`"${getOptionName(isWritable)}" must not be ${fdName}. It must be a readable stream, not writable.`); - } - - if (fileDescriptor.direction !== 'input' && isWritable) { - throw new TypeError(`"${getOptionName(isWritable)}" must not be ${fdName}. It must be a writable stream, not readable.`); - } -}; - -const getInvalidStdioOptionMessage = (fdNumber, fdName, options, isWritable) => { - if (fdNumber === 'all' && !options.all) { - return 'The "all" option must be true to use "from: \'all\'".'; - } - - const {optionName, optionValue} = getInvalidStdioOption(fdNumber, options); - return `The "${optionName}: ${serializeOptionValue(optionValue)}" option is incompatible with using "${getOptionName(isWritable)}: ${serializeOptionValue(fdName)}". -Please set this option with "pipe" instead.`; -}; - -const getInvalidStdioOption = (fdNumber, {stdin, stdout, stderr, stdio}) => { - const usedDescriptor = getUsedDescriptor(fdNumber); - - if (usedDescriptor === 0 && stdin !== undefined) { - return {optionName: 'stdin', optionValue: stdin}; - } - - if (usedDescriptor === 1 && stdout !== undefined) { - return {optionName: 'stdout', optionValue: stdout}; - } - - if (usedDescriptor === 2 && stderr !== undefined) { - return {optionName: 'stderr', optionValue: stderr}; - } - - return {optionName: `stdio[${usedDescriptor}]`, optionValue: stdio[usedDescriptor]}; -}; - -const getUsedDescriptor = fdNumber => fdNumber === 'all' ? 1 : fdNumber; - -const getOptionName = isWritable => isWritable ? 'to' : 'from'; - -const serializeOptionValue = value => { - if (typeof value === 'string') { - return `'${value}'`; - } - - return typeof value === 'number' ? `${value}` : 'Stream'; -}; - -// Temporarily increase the maximum number of listeners on an eventEmitter -const incrementMaxListeners = (eventEmitter, maxListenersIncrement, signal) => { - const maxListeners = eventEmitter.getMaxListeners(); - if (maxListeners === 0 || maxListeners === Number.POSITIVE_INFINITY) { - return; - } - - eventEmitter.setMaxListeners(maxListeners + maxListenersIncrement); - addAbortListener(signal, () => { - eventEmitter.setMaxListeners(eventEmitter.getMaxListeners() - maxListenersIncrement); - }); -}; - -// By default, Node.js keeps the subprocess alive while it has a `message` or `disconnect` listener. -// We replicate the same logic for the events that we proxy. -// This ensures the subprocess is kept alive while `getOneMessage()` and `getEachMessage()` are ongoing. -// This is not a problem with `sendMessage()` since Node.js handles that method automatically. -// We do not use `anyProcess.channel.ref()` since this would prevent the automatic `.channel.refCounted()` Node.js is doing. -// We keep a reference to `anyProcess.channel` since it might be `null` while `getOneMessage()` or `getEachMessage()` is still processing debounced messages. -// See https://github.com/nodejs/node/blob/2aaeaa863c35befa2ebaa98fb7737ec84df4d8e9/lib/internal/child_process.js#L547 -const addReference = (channel, reference) => { - if (reference) { - addReferenceCount(channel); - } -}; - -const addReferenceCount = channel => { - channel.refCounted(); -}; - -const removeReference = (channel, reference) => { - if (reference) { - removeReferenceCount(channel); - } -}; - -const removeReferenceCount = channel => { - channel.unrefCounted(); -}; - -// To proxy events, we setup some global listeners on the `message` and `disconnect` events. -// Those should not keep the subprocess alive, so we remove the automatic counting that Node.js is doing. -// See https://github.com/nodejs/node/blob/1b965270a9c273d4cf70e8808e9d28b9ada7844f/lib/child_process.js#L180 -const undoAddedReferences = (channel, isSubprocess) => { - if (isSubprocess) { - removeReferenceCount(channel); - removeReferenceCount(channel); - } -}; - -// Reverse it during `disconnect` -const redoAddedReferences = (channel, isSubprocess) => { - if (isSubprocess) { - addReferenceCount(channel); - addReferenceCount(channel); - } -}; - -// By default, Node.js buffers `message` events. -// - Buffering happens when there is a `message` event is emitted but there is no handler. -// - As soon as a `message` event handler is set, all buffered `message` events are emitted, emptying the buffer. -// - This happens both in the current process and the subprocess. -// - See https://github.com/nodejs/node/blob/501546e8f37059cd577041e23941b640d0d4d406/lib/internal/child_process.js#L719 -// This is helpful. Notably, this allows sending messages to a subprocess that's still initializing. -// However, it has several problems. -// - This works with `events.on()` but not `events.once()` since all buffered messages are emitted at once. -// For example, users cannot call `await getOneMessage()`/`getEachMessage()` multiple times in a row. -// - When a user intentionally starts listening to `message` at a specific point in time, past `message` events are replayed, which might be unexpected. -// - Buffering is unlimited, which might lead to an out-of-memory crash. -// - This does not work well with multiple consumers. -// For example, Execa consumes events with both `result.ipcOutput` and manual IPC calls like `getOneMessage()`. -// Since `result.ipcOutput` reads all incoming messages, no buffering happens for manual IPC calls. -// - Forgetting to setup a `message` listener, or setting it up too late, is a programming mistake. -// The default behavior does not allow users to realize they made that mistake. -// To solve those problems, instead of buffering messages, we debounce them. -// The `message` event so it is emitted at most once per macrotask. -const onMessage = async ({anyProcess, channel, isSubprocess, ipcEmitter}, wrappedMessage) => { - if (handleStrictResponse(wrappedMessage) || handleAbort(wrappedMessage)) { - return; - } - - if (!INCOMING_MESSAGES.has(anyProcess)) { - INCOMING_MESSAGES.set(anyProcess, []); - } - - const incomingMessages = INCOMING_MESSAGES.get(anyProcess); - incomingMessages.push(wrappedMessage); - - if (incomingMessages.length > 1) { - return; - } - - while (incomingMessages.length > 0) { - // eslint-disable-next-line no-await-in-loop - await waitForOutgoingMessages(anyProcess, ipcEmitter, wrappedMessage); - // eslint-disable-next-line no-await-in-loop - await scheduler.yield(); - - // eslint-disable-next-line no-await-in-loop - const message = await handleStrictRequest({ - wrappedMessage: incomingMessages[0], - anyProcess, - channel, - isSubprocess, - ipcEmitter, - }); - - incomingMessages.shift(); - ipcEmitter.emit('message', message); - ipcEmitter.emit('message:done'); - } -}; - -// If the `message` event is currently debounced, the `disconnect` event must wait for it -const onDisconnect = async ({anyProcess, channel, isSubprocess, ipcEmitter, boundOnMessage}) => { - abortOnDisconnect(); - - const incomingMessages = INCOMING_MESSAGES.get(anyProcess); - while (incomingMessages?.length > 0) { - // eslint-disable-next-line no-await-in-loop - await once$2(ipcEmitter, 'message:done'); - } - - anyProcess.removeListener('message', boundOnMessage); - redoAddedReferences(channel, isSubprocess); - ipcEmitter.connected = false; - ipcEmitter.emit('disconnect'); -}; - -const INCOMING_MESSAGES = new WeakMap(); - -// Forward the `message` and `disconnect` events from the process and subprocess to a proxy emitter. -// This prevents the `error` event from stopping IPC. -// This also allows debouncing the `message` event. -const getIpcEmitter = (anyProcess, channel, isSubprocess) => { - if (IPC_EMITTERS.has(anyProcess)) { - return IPC_EMITTERS.get(anyProcess); - } - - // Use an `EventEmitter`, like the `process` that is being proxied - // eslint-disable-next-line unicorn/prefer-event-target - const ipcEmitter = new EventEmitter(); - ipcEmitter.connected = true; - IPC_EMITTERS.set(anyProcess, ipcEmitter); - forwardEvents({ - ipcEmitter, - anyProcess, - channel, - isSubprocess, - }); - return ipcEmitter; -}; - -const IPC_EMITTERS = new WeakMap(); - -// The `message` and `disconnect` events are buffered in the subprocess until the first listener is setup. -// However, unbuffering happens after one tick, so this give enough time for the caller to setup the listener on the proxy emitter first. -// See https://github.com/nodejs/node/blob/2aaeaa863c35befa2ebaa98fb7737ec84df4d8e9/lib/internal/child_process.js#L721 -const forwardEvents = ({ipcEmitter, anyProcess, channel, isSubprocess}) => { - const boundOnMessage = onMessage.bind(undefined, { - anyProcess, - channel, - isSubprocess, - ipcEmitter, - }); - anyProcess.on('message', boundOnMessage); - anyProcess.once('disconnect', onDisconnect.bind(undefined, { - anyProcess, - channel, - isSubprocess, - ipcEmitter, - boundOnMessage, - })); - undoAddedReferences(channel, isSubprocess); -}; - -// Check whether there might still be some `message` events to receive -const isConnected = anyProcess => { - const ipcEmitter = IPC_EMITTERS.get(anyProcess); - return ipcEmitter === undefined - ? anyProcess.channel !== null - : ipcEmitter.connected; -}; - -// When using the `strict` option, wrap the message with metadata during `sendMessage()` -const handleSendStrict = ({anyProcess, channel, isSubprocess, message, strict}) => { - if (!strict) { - return message; - } - - const ipcEmitter = getIpcEmitter(anyProcess, channel, isSubprocess); - const hasListeners = hasMessageListeners(anyProcess, ipcEmitter); - return { - id: count++, - type: REQUEST_TYPE, - message, - hasListeners, - }; -}; - -let count = 0n; - -// Handles when both processes are calling `sendMessage()` with `strict` at the same time. -// If neither process is listening, this would create a deadlock. We detect it and throw. -const validateStrictDeadlock = (outgoingMessages, wrappedMessage) => { - if (wrappedMessage?.type !== REQUEST_TYPE || wrappedMessage.hasListeners) { - return; - } - - for (const {id} of outgoingMessages) { - if (id !== undefined) { - STRICT_RESPONSES[id].resolve({isDeadlock: true, hasListeners: false}); - } - } -}; - -// The other process then sends the acknowledgment back as a response -const handleStrictRequest = async ({wrappedMessage, anyProcess, channel, isSubprocess, ipcEmitter}) => { - if (wrappedMessage?.type !== REQUEST_TYPE || !anyProcess.connected) { - return wrappedMessage; - } - - const {id, message} = wrappedMessage; - const response = {id, type: RESPONSE_TYPE, message: hasMessageListeners(anyProcess, ipcEmitter)}; - - try { - await sendMessage({ - anyProcess, - channel, - isSubprocess, - ipc: true, - }, response); - } catch (error) { - ipcEmitter.emit('strict:error', error); - } - - return message; -}; - -// Reception of the acknowledgment response -const handleStrictResponse = wrappedMessage => { - if (wrappedMessage?.type !== RESPONSE_TYPE) { - return false; - } - - const {id, message: hasListeners} = wrappedMessage; - STRICT_RESPONSES[id]?.resolve({isDeadlock: false, hasListeners}); - return true; -}; - -// Wait for the other process to receive the message from `sendMessage()` -const waitForStrictResponse = async (wrappedMessage, anyProcess, isSubprocess) => { - if (wrappedMessage?.type !== REQUEST_TYPE) { - return; - } - - const deferred = createDeferred(); - STRICT_RESPONSES[wrappedMessage.id] = deferred; - const controller = new AbortController(); - - try { - const {isDeadlock, hasListeners} = await Promise.race([ - deferred, - throwOnDisconnect$1(anyProcess, isSubprocess, controller), - ]); - - if (isDeadlock) { - throwOnStrictDeadlockError(isSubprocess); - } - - if (!hasListeners) { - throwOnMissingStrict(isSubprocess); - } - } finally { - controller.abort(); - delete STRICT_RESPONSES[wrappedMessage.id]; - } -}; - -const STRICT_RESPONSES = {}; - -const throwOnDisconnect$1 = async (anyProcess, isSubprocess, {signal}) => { - incrementMaxListeners(anyProcess, 1, signal); - await once$2(anyProcess, 'disconnect', {signal}); - throwOnStrictDisconnect(isSubprocess); -}; - -const REQUEST_TYPE = 'execa:ipc:request'; -const RESPONSE_TYPE = 'execa:ipc:response'; - -// When `sendMessage()` is ongoing, any `message` being received waits before being emitted. -// This allows calling one or multiple `await sendMessage()` followed by `await getOneMessage()`/`await getEachMessage()`. -// Without running into a race condition when the other process sends a response too fast, before the current process set up a listener. -const startSendMessage = (anyProcess, wrappedMessage, strict) => { - if (!OUTGOING_MESSAGES.has(anyProcess)) { - OUTGOING_MESSAGES.set(anyProcess, new Set()); - } - - const outgoingMessages = OUTGOING_MESSAGES.get(anyProcess); - const onMessageSent = createDeferred(); - const id = strict ? wrappedMessage.id : undefined; - const outgoingMessage = {onMessageSent, id}; - outgoingMessages.add(outgoingMessage); - return {outgoingMessages, outgoingMessage}; -}; - -const endSendMessage = ({outgoingMessages, outgoingMessage}) => { - outgoingMessages.delete(outgoingMessage); - outgoingMessage.onMessageSent.resolve(); -}; - -// Await while `sendMessage()` is ongoing, unless there is already a `message` listener -const waitForOutgoingMessages = async (anyProcess, ipcEmitter, wrappedMessage) => { - while (!hasMessageListeners(anyProcess, ipcEmitter) && OUTGOING_MESSAGES.get(anyProcess)?.size > 0) { - const outgoingMessages = [...OUTGOING_MESSAGES.get(anyProcess)]; - validateStrictDeadlock(outgoingMessages, wrappedMessage); - // eslint-disable-next-line no-await-in-loop - await Promise.all(outgoingMessages.map(({onMessageSent}) => onMessageSent)); - } -}; - -const OUTGOING_MESSAGES = new WeakMap(); - -// Whether any `message` listener is setup -const hasMessageListeners = (anyProcess, ipcEmitter) => ipcEmitter.listenerCount('message') > getMinListenerCount(anyProcess); - -// When `buffer` is `false`, we set up a `message` listener that should be ignored. -// That listener is only meant to intercept `strict` acknowledgement responses. -const getMinListenerCount = anyProcess => SUBPROCESS_OPTIONS.has(anyProcess) - && !getFdSpecificValue(SUBPROCESS_OPTIONS.get(anyProcess).options.buffer, 'ipc') - ? 1 - : 0; - -// Like `[sub]process.send()` but promise-based. -// We do not `await subprocess` during `.sendMessage()` nor `.getOneMessage()` since those methods are transient. -// Users would still need to `await subprocess` after the method is done. -// Also, this would prevent `unhandledRejection` event from being emitted, making it silent. -const sendMessage = ({anyProcess, channel, isSubprocess, ipc}, message, {strict = false} = {}) => { - const methodName = 'sendMessage'; - validateIpcMethod({ - methodName, - isSubprocess, - ipc, - isConnected: anyProcess.connected, - }); - - return sendMessageAsync({ - anyProcess, - channel, - methodName, - isSubprocess, - message, - strict, - }); -}; - -const sendMessageAsync = async ({anyProcess, channel, methodName, isSubprocess, message, strict}) => { - const wrappedMessage = handleSendStrict({ - anyProcess, - channel, - isSubprocess, - message, - strict, - }); - const outgoingMessagesState = startSendMessage(anyProcess, wrappedMessage, strict); - try { - await sendOneMessage({ - anyProcess, - methodName, - isSubprocess, - wrappedMessage, - message, - }); - } catch (error) { - disconnect(anyProcess); - throw error; - } finally { - endSendMessage(outgoingMessagesState); - } -}; - -// Used internally by `cancelSignal` -const sendOneMessage = async ({anyProcess, methodName, isSubprocess, wrappedMessage, message}) => { - const sendMethod = getSendMethod(anyProcess); - - try { - await Promise.all([ - waitForStrictResponse(wrappedMessage, anyProcess, isSubprocess), - sendMethod(wrappedMessage), - ]); - } catch (error) { - handleEpipeError({error, methodName, isSubprocess}); - handleSerializationError({ - error, - methodName, - isSubprocess, - message, - }); - throw error; - } -}; - -// [sub]process.send() promisified, memoized -const getSendMethod = anyProcess => { - if (PROCESS_SEND_METHODS.has(anyProcess)) { - return PROCESS_SEND_METHODS.get(anyProcess); - } - - const sendMethod = promisify(anyProcess.send.bind(anyProcess)); - PROCESS_SEND_METHODS.set(anyProcess, sendMethod); - return sendMethod; -}; - -const PROCESS_SEND_METHODS = new WeakMap(); - -// Send an IPC message so the subprocess performs a graceful termination -const sendAbort = (subprocess, message) => { - const methodName = 'cancelSignal'; - validateConnection(methodName, false, subprocess.connected); - return sendOneMessage({ - anyProcess: subprocess, - methodName, - isSubprocess: false, - wrappedMessage: {type: GRACEFUL_CANCEL_TYPE, message}, - message, - }); -}; - -// When the signal is being used, start listening for incoming messages. -// Unbuffering messages takes one microtask to complete, so this must be async. -const getCancelSignal = async ({anyProcess, channel, isSubprocess, ipc}) => { - await startIpc({ - anyProcess, - channel, - isSubprocess, - ipc, - }); - return cancelController.signal; -}; - -const startIpc = async ({anyProcess, channel, isSubprocess, ipc}) => { - if (cancelListening) { - return; - } - - cancelListening = true; - - if (!ipc) { - throwOnMissingParent(); - return; - } - - if (channel === null) { - abortOnDisconnect(); - return; - } - - getIpcEmitter(anyProcess, channel, isSubprocess); - await scheduler.yield(); -}; - -let cancelListening = false; - -// Reception of IPC message to perform a graceful termination -const handleAbort = wrappedMessage => { - if (wrappedMessage?.type !== GRACEFUL_CANCEL_TYPE) { - return false; - } - - cancelController.abort(wrappedMessage.message); - return true; -}; - -const GRACEFUL_CANCEL_TYPE = 'execa:ipc:cancel'; - -// When the current process disconnects early, the subprocess `cancelSignal` is aborted. -// Otherwise, the signal would never be able to be aborted later on. -const abortOnDisconnect = () => { - cancelController.abort(getAbortDisconnectError()); -}; - -const cancelController = new AbortController(); - -// Validate the `gracefulCancel` option -const validateGracefulCancel = ({gracefulCancel, cancelSignal, ipc, serialization}) => { - if (!gracefulCancel) { - return; - } - - if (cancelSignal === undefined) { - throw new Error('The `cancelSignal` option must be defined when setting the `gracefulCancel` option.'); - } - - if (!ipc) { - throw new Error('The `ipc` option cannot be false when setting the `gracefulCancel` option.'); - } - - if (serialization === 'json') { - throw new Error('The `serialization` option cannot be \'json\' when setting the `gracefulCancel` option.'); - } -}; - -// Send abort reason to the subprocess when aborting the `cancelSignal` option and `gracefulCancel` is `true` -const throwOnGracefulCancel = ({ - subprocess, - cancelSignal, - gracefulCancel, - forceKillAfterDelay, - context, - controller, -}) => gracefulCancel - ? [sendOnAbort({ - subprocess, - cancelSignal, - forceKillAfterDelay, - context, - controller, - })] - : []; - -const sendOnAbort = async ({subprocess, cancelSignal, forceKillAfterDelay, context, controller: {signal}}) => { - await onAbortedSignal(cancelSignal, signal); - const reason = getReason(cancelSignal); - await sendAbort(subprocess, reason); - killOnTimeout({ - kill: subprocess.kill, - forceKillAfterDelay, - context, - controllerSignal: signal, - }); - context.terminationReason ??= 'gracefulCancel'; - throw cancelSignal.reason; -}; - -// The default `reason` is a DOMException, which is not serializable with V8 -// See https://github.com/nodejs/node/issues/53225 -const getReason = ({reason}) => { - if (!(reason instanceof DOMException)) { - return reason; - } - - const error = new Error(reason.message); - Object.defineProperty(error, 'stack', { - value: reason.stack, - enumerable: false, - configurable: true, - writable: true, - }); - return error; -}; - -// Validate `timeout` option -const validateTimeout = ({timeout}) => { - if (timeout !== undefined && (!Number.isFinite(timeout) || timeout < 0)) { - throw new TypeError(`Expected the \`timeout\` option to be a non-negative integer, got \`${timeout}\` (${typeof timeout})`); - } -}; - -// Fails when the `timeout` option is exceeded -const throwOnTimeout = (subprocess, timeout, context, controller) => timeout === 0 || timeout === undefined - ? [] - : [killAfterTimeout(subprocess, timeout, context, controller)]; - -const killAfterTimeout = async (subprocess, timeout, context, {signal}) => { - await setTimeout$1(timeout, undefined, {signal}); - context.terminationReason ??= 'timeout'; - subprocess.kill(); - throw new DiscardedError(); -}; - -// `execaNode()` is a shortcut for `execa(..., {node: true})` -const mapNode = ({options}) => { - if (options.node === false) { - throw new TypeError('The "node" option cannot be false with `execaNode()`.'); - } - - return {options: {...options, node: true}}; -}; - -// Applies the `node: true` option, and the related `nodePath`/`nodeOptions` options. -// Modifies the file commands/arguments to ensure the same Node binary and flags are re-used. -// Also adds `ipc: true` and `shell: false`. -const handleNodeOption = (file, commandArguments, { - node: shouldHandleNode = false, - nodePath = execPath, - nodeOptions = execArgv.filter(nodeOption => !nodeOption.startsWith('--inspect')), - cwd, - execPath: formerNodePath, - ...options -}) => { - if (formerNodePath !== undefined) { - throw new TypeError('The "execPath" option has been removed. Please use the "nodePath" option instead.'); - } - - const normalizedNodePath = safeNormalizeFileUrl(nodePath, 'The "nodePath" option'); - const resolvedNodePath = path.resolve(cwd, normalizedNodePath); - const newOptions = { - ...options, - nodePath: resolvedNodePath, - node: shouldHandleNode, - cwd, - }; - - if (!shouldHandleNode) { - return [file, commandArguments, newOptions]; - } - - if (path.basename(file, '.exe') === 'node') { - throw new TypeError('When the "node" option is true, the first argument does not need to be "node".'); - } - - return [ - resolvedNodePath, - [...nodeOptions, file, ...commandArguments], - {ipc: true, ...newOptions, shell: false}, - ]; -}; - -// Validate the `ipcInput` option -const validateIpcInputOption = ({ipcInput, ipc, serialization}) => { - if (ipcInput === undefined) { - return; - } - - if (!ipc) { - throw new Error('The `ipcInput` option cannot be set unless the `ipc` option is `true`.'); - } - - validateIpcInput[serialization](ipcInput); -}; - -const validateAdvancedInput = ipcInput => { - try { - serialize(ipcInput); - } catch (error) { - throw new Error('The `ipcInput` option is not serializable with a structured clone.', {cause: error}); - } -}; - -const validateJsonInput = ipcInput => { - try { - JSON.stringify(ipcInput); - } catch (error) { - throw new Error('The `ipcInput` option is not serializable with JSON.', {cause: error}); - } -}; - -const validateIpcInput = { - advanced: validateAdvancedInput, - json: validateJsonInput, -}; - -// When the `ipcInput` option is set, it is sent as an initial IPC message to the subprocess -const sendIpcInput = async (subprocess, ipcInput) => { - if (ipcInput === undefined) { - return; - } - - await subprocess.sendMessage(ipcInput); -}; - -// Validate `encoding` option -const validateEncoding = ({encoding}) => { - if (ENCODINGS.has(encoding)) { - return; - } - - const correctEncoding = getCorrectEncoding(encoding); - if (correctEncoding !== undefined) { - throw new TypeError(`Invalid option \`encoding: ${serializeEncoding(encoding)}\`. -Please rename it to ${serializeEncoding(correctEncoding)}.`); - } - - const correctEncodings = [...ENCODINGS].map(correctEncoding => serializeEncoding(correctEncoding)).join(', '); - throw new TypeError(`Invalid option \`encoding: ${serializeEncoding(encoding)}\`. -Please rename it to one of: ${correctEncodings}.`); -}; - -const TEXT_ENCODINGS = new Set(['utf8', 'utf16le']); -const BINARY_ENCODINGS = new Set(['buffer', 'hex', 'base64', 'base64url', 'latin1', 'ascii']); -const ENCODINGS = new Set([...TEXT_ENCODINGS, ...BINARY_ENCODINGS]); - -const getCorrectEncoding = encoding => { - if (encoding === null) { - return 'buffer'; - } - - if (typeof encoding !== 'string') { - return; - } - - const lowerEncoding = encoding.toLowerCase(); - if (lowerEncoding in ENCODING_ALIASES) { - return ENCODING_ALIASES[lowerEncoding]; - } - - if (ENCODINGS.has(lowerEncoding)) { - return lowerEncoding; - } -}; - -const ENCODING_ALIASES = { - // eslint-disable-next-line unicorn/text-encoding-identifier-case - 'utf-8': 'utf8', - 'utf-16le': 'utf16le', - 'ucs-2': 'utf16le', - ucs2: 'utf16le', - binary: 'latin1', -}; - -const serializeEncoding = encoding => typeof encoding === 'string' ? `"${encoding}"` : String(encoding); - -// Normalize `cwd` option -const normalizeCwd = (cwd = getDefaultCwd()) => { - const cwdString = safeNormalizeFileUrl(cwd, 'The "cwd" option'); - return path.resolve(cwdString); -}; - -const getDefaultCwd = () => { - try { - return process$2.cwd(); - } catch (error) { - error.message = `The current directory does not exist.\n${error.message}`; - throw error; - } -}; - -// When `cwd` option has an invalid value, provide with a better error message -const fixCwdError = (originalMessage, cwd) => { - if (cwd === getDefaultCwd()) { - return originalMessage; - } - - let cwdStat; - try { - cwdStat = statSync(cwd); - } catch (error) { - return `The "cwd" option is invalid: ${cwd}.\n${error.message}\n${originalMessage}`; - } - - if (!cwdStat.isDirectory()) { - return `The "cwd" option is not a directory: ${cwd}.\n${originalMessage}`; - } - - return originalMessage; -}; - -// Normalize the options object, and sometimes also the file paths and arguments. -// Applies default values, validate allowed options, normalize them. -const normalizeOptions = (filePath, rawArguments, rawOptions) => { - rawOptions.cwd = normalizeCwd(rawOptions.cwd); - const [processedFile, processedArguments, processedOptions] = handleNodeOption(filePath, rawArguments, rawOptions); - - const {command: file, args: commandArguments, options: initialOptions} = crossSpawn._parse(processedFile, processedArguments, processedOptions); - - const fdOptions = normalizeFdSpecificOptions(initialOptions); - const options = addDefaultOptions(fdOptions); - validateTimeout(options); - validateEncoding(options); - validateIpcInputOption(options); - validateCancelSignal(options); - validateGracefulCancel(options); - options.shell = normalizeFileUrl(options.shell); - options.env = getEnv(options); - options.killSignal = normalizeKillSignal(options.killSignal); - options.forceKillAfterDelay = normalizeForceKillAfterDelay(options.forceKillAfterDelay); - options.lines = options.lines.map((lines, fdNumber) => lines && !BINARY_ENCODINGS.has(options.encoding) && options.buffer[fdNumber]); - - if (process$2.platform === 'win32' && path.basename(file, '.exe') === 'cmd') { - // #116 - commandArguments.unshift('/q'); - } - - return {file, commandArguments, options}; -}; - -const addDefaultOptions = ({ - extendEnv = true, - preferLocal = false, - cwd, - localDir: localDirectory = cwd, - encoding = 'utf8', - reject = true, - cleanup = true, - all = false, - windowsHide = true, - killSignal = 'SIGTERM', - forceKillAfterDelay = true, - gracefulCancel = false, - ipcInput, - ipc = ipcInput !== undefined || gracefulCancel, - serialization = 'advanced', - ...options -}) => ({ - ...options, - extendEnv, - preferLocal, - cwd, - localDirectory, - encoding, - reject, - cleanup, - all, - windowsHide, - killSignal, - forceKillAfterDelay, - gracefulCancel, - ipcInput, - ipc, - serialization, -}); - -const getEnv = ({env: envOption, extendEnv, preferLocal, node, localDirectory, nodePath}) => { - const env = extendEnv ? {...process$2.env, ...envOption} : envOption; - - if (preferLocal || node) { - return npmRunPathEnv({ - env, - cwd: localDirectory, - execPath: nodePath, - preferLocal, - addExecPath: node, - }); - } - - return env; -}; - -// When the `shell` option is set, any command argument is concatenated as a single string by Node.js: -// https://github.com/nodejs/node/blob/e38ce27f3ca0a65f68a31cedd984cddb927d4002/lib/child_process.js#L614-L624 -// However, since Node 24, it also prints a deprecation warning. -// To avoid this warning, we perform that same operation before calling `node:child_process`. -// Shells only understand strings, which is why Node.js performs that concatenation. -// However, we rely on users splitting command arguments as an array. -// For example, this allows us to easily detect which arguments are passed. -// So we do want users to pass array of arguments even with `shell: true`, but we also want to avoid any warning. -const concatenateShell = (file, commandArguments, options) => options.shell && commandArguments.length > 0 - ? [[file, ...commandArguments].join(' '), [], options] - : [file, commandArguments, options]; - -function stripFinalNewline(input) { - if (typeof input === 'string') { - return stripFinalNewlineString(input); - } - - if (!(ArrayBuffer.isView(input) && input.BYTES_PER_ELEMENT === 1)) { - throw new Error('Input must be a string or a Uint8Array'); - } - - return stripFinalNewlineBinary(input); -} - -const stripFinalNewlineString = input => - input.at(-1) === LF - ? input.slice(0, input.at(-2) === CR ? -2 : -1) - : input; - -const stripFinalNewlineBinary = input => - input.at(-1) === LF_BINARY - ? input.subarray(0, input.at(-2) === CR_BINARY ? -2 : -1) - : input; - -const LF = '\n'; -const LF_BINARY = LF.codePointAt(0); -const CR = '\r'; -const CR_BINARY = CR.codePointAt(0); - -function isStream(stream, {checkOpen = true} = {}) { - return stream !== null - && typeof stream === 'object' - && (stream.writable || stream.readable || !checkOpen || (stream.writable === undefined && stream.readable === undefined)) - && typeof stream.pipe === 'function'; -} - -function isWritableStream$1(stream, {checkOpen = true} = {}) { - return isStream(stream, {checkOpen}) - && (stream.writable || !checkOpen) - && typeof stream.write === 'function' - && typeof stream.end === 'function' - && typeof stream.writable === 'boolean' - && typeof stream.writableObjectMode === 'boolean' - && typeof stream.destroy === 'function' - && typeof stream.destroyed === 'boolean'; -} - -function isReadableStream$1(stream, {checkOpen = true} = {}) { - return isStream(stream, {checkOpen}) - && (stream.readable || !checkOpen) - && typeof stream.read === 'function' - && typeof stream.readable === 'boolean' - && typeof stream.readableObjectMode === 'boolean' - && typeof stream.destroy === 'function' - && typeof stream.destroyed === 'boolean'; -} - -function isDuplexStream(stream, options) { - return isWritableStream$1(stream, options) - && isReadableStream$1(stream, options); -} - -const a = Object.getPrototypeOf( - Object.getPrototypeOf( - /* istanbul ignore next */ - async function* () { - } - ).prototype -); -class c { - #t; - #n; - #r = false; - #e = void 0; - constructor(e, t) { - this.#t = e, this.#n = t; - } - next() { - const e = () => this.#s(); - return this.#e = this.#e ? this.#e.then(e, e) : e(), this.#e; - } - return(e) { - const t = () => this.#i(e); - return this.#e ? this.#e.then(t, t) : t(); - } - async #s() { - if (this.#r) - return { - done: true, - value: void 0 - }; - let e; - try { - e = await this.#t.read(); - } catch (t) { - throw this.#e = void 0, this.#r = true, this.#t.releaseLock(), t; - } - return e.done && (this.#e = void 0, this.#r = true, this.#t.releaseLock()), e; - } - async #i(e) { - if (this.#r) - return { - done: true, - value: e - }; - if (this.#r = true, !this.#n) { - const t = this.#t.cancel(e); - return this.#t.releaseLock(), await t, { - done: true, - value: e - }; - } - return this.#t.releaseLock(), { - done: true, - value: e - }; - } -} -const n = Symbol(); -function i() { - return this[n].next(); -} -Object.defineProperty(i, "name", { value: "next" }); -function o(r) { - return this[n].return(r); -} -Object.defineProperty(o, "name", { value: "return" }); -const u = Object.create(a, { - next: { - enumerable: true, - configurable: true, - writable: true, - value: i - }, - return: { - enumerable: true, - configurable: true, - writable: true, - value: o - } -}); -function h({ preventCancel: r = false } = {}) { - const e = this.getReader(), t = new c( - e, - r - ), s = Object.create(u); - return s[n] = t, s; -} - -const getAsyncIterable = stream => { - if (isReadableStream$1(stream, {checkOpen: false}) && nodeImports.on !== undefined) { - return getStreamIterable(stream); - } - - if (typeof stream?.[Symbol.asyncIterator] === 'function') { - return stream; - } - - // `ReadableStream[Symbol.asyncIterator]` support is missing in multiple browsers, so we ponyfill it - if (toString.call(stream) === '[object ReadableStream]') { - return h.call(stream); - } - - throw new TypeError('The first argument must be a Readable, a ReadableStream, or an async iterable.'); -}; - -const {toString} = Object.prototype; - -// The default iterable for Node.js streams does not allow for multiple readers at once, so we re-implement it -const getStreamIterable = async function * (stream) { - const controller = new AbortController(); - const state = {}; - handleStreamEnd(stream, controller, state); - - try { - for await (const [chunk] of nodeImports.on(stream, 'data', {signal: controller.signal})) { - yield chunk; - } - } catch (error) { - // Stream failure, for example due to `stream.destroy(error)` - if (state.error !== undefined) { - throw state.error; - // `error` event directly emitted on stream - } else if (!controller.signal.aborted) { - throw error; - // Otherwise, stream completed successfully - } - // The `finally` block also runs when the caller throws, for example due to the `maxBuffer` option - } finally { - stream.destroy(); - } -}; - -const handleStreamEnd = async (stream, controller, state) => { - try { - await nodeImports.finished(stream, { - cleanup: true, - readable: true, - writable: false, - error: false, - }); - } catch (error) { - state.error = error; - } finally { - controller.abort(); - } -}; - -// Loaded by the Node entrypoint, but not by the browser one. -// This prevents using dynamic imports. -const nodeImports = {}; - -const getStreamContents$1 = async (stream, {init, convertChunk, getSize, truncateChunk, addChunk, getFinalChunk, finalize}, {maxBuffer = Number.POSITIVE_INFINITY} = {}) => { - const asyncIterable = getAsyncIterable(stream); - - const state = init(); - state.length = 0; - - try { - for await (const chunk of asyncIterable) { - const chunkType = getChunkType(chunk); - const convertedChunk = convertChunk[chunkType](chunk, state); - appendChunk({ - convertedChunk, - state, - getSize, - truncateChunk, - addChunk, - maxBuffer, - }); - } - - appendFinalChunk({ - state, - convertChunk, - getSize, - truncateChunk, - addChunk, - getFinalChunk, - maxBuffer, - }); - return finalize(state); - } catch (error) { - const normalizedError = typeof error === 'object' && error !== null ? error : new Error(error); - normalizedError.bufferedData = finalize(state); - throw normalizedError; - } -}; - -const appendFinalChunk = ({state, getSize, truncateChunk, addChunk, getFinalChunk, maxBuffer}) => { - const convertedChunk = getFinalChunk(state); - if (convertedChunk !== undefined) { - appendChunk({ - convertedChunk, - state, - getSize, - truncateChunk, - addChunk, - maxBuffer, - }); - } -}; - -const appendChunk = ({convertedChunk, state, getSize, truncateChunk, addChunk, maxBuffer}) => { - const chunkSize = getSize(convertedChunk); - const newLength = state.length + chunkSize; - - if (newLength <= maxBuffer) { - addNewChunk(convertedChunk, state, addChunk, newLength); - return; - } - - const truncatedChunk = truncateChunk(convertedChunk, maxBuffer - state.length); - - if (truncatedChunk !== undefined) { - addNewChunk(truncatedChunk, state, addChunk, maxBuffer); - } - - throw new MaxBufferError(); -}; - -const addNewChunk = (convertedChunk, state, addChunk, newLength) => { - state.contents = addChunk(convertedChunk, state, newLength); - state.length = newLength; -}; - -const getChunkType = chunk => { - const typeOfChunk = typeof chunk; - - if (typeOfChunk === 'string') { - return 'string'; - } - - if (typeOfChunk !== 'object' || chunk === null) { - return 'others'; - } - - if (globalThis.Buffer?.isBuffer(chunk)) { - return 'buffer'; - } - - const prototypeName = objectToString.call(chunk); - - if (prototypeName === '[object ArrayBuffer]') { - return 'arrayBuffer'; - } - - if (prototypeName === '[object DataView]') { - return 'dataView'; - } - - if ( - Number.isInteger(chunk.byteLength) - && Number.isInteger(chunk.byteOffset) - && objectToString.call(chunk.buffer) === '[object ArrayBuffer]' - ) { - return 'typedArray'; - } - - return 'others'; -}; - -const {toString: objectToString} = Object.prototype; - -class MaxBufferError extends Error { - name = 'MaxBufferError'; - - constructor() { - super('maxBuffer exceeded'); - } -} - -const identity = value => value; - -const noop$1 = () => undefined; - -const getContentsProperty = ({contents}) => contents; - -const throwObjectStream = chunk => { - throw new Error(`Streams in object mode are not supported: ${String(chunk)}`); -}; - -const getLengthProperty = convertedChunk => convertedChunk.length; - -async function getStreamAsArray(stream, options) { - return getStreamContents$1(stream, arrayMethods, options); -} - -const initArray = () => ({contents: []}); - -const increment = () => 1; - -const addArrayChunk = (convertedChunk, {contents}) => { - contents.push(convertedChunk); - return contents; -}; - -const arrayMethods = { - init: initArray, - convertChunk: { - string: identity, - buffer: identity, - arrayBuffer: identity, - dataView: identity, - typedArray: identity, - others: identity, - }, - getSize: increment, - truncateChunk: noop$1, - addChunk: addArrayChunk, - getFinalChunk: noop$1, - finalize: getContentsProperty, -}; - -async function getStreamAsArrayBuffer(stream, options) { - return getStreamContents$1(stream, arrayBufferMethods, options); -} - -const initArrayBuffer = () => ({contents: new ArrayBuffer(0)}); - -const useTextEncoder = chunk => textEncoder.encode(chunk); -const textEncoder = new TextEncoder(); - -const useUint8Array = chunk => new Uint8Array(chunk); - -const useUint8ArrayWithOffset = chunk => new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength); - -const truncateArrayBufferChunk = (convertedChunk, chunkSize) => convertedChunk.slice(0, chunkSize); - -// `contents` is an increasingly growing `Uint8Array`. -const addArrayBufferChunk = (convertedChunk, {contents, length: previousLength}, length) => { - const newContents = hasArrayBufferResize() ? resizeArrayBuffer(contents, length) : resizeArrayBufferSlow(contents, length); - new Uint8Array(newContents).set(convertedChunk, previousLength); - return newContents; -}; - -// Without `ArrayBuffer.resize()`, `contents` size is always a power of 2. -// This means its last bytes are zeroes (not stream data), which need to be -// trimmed at the end with `ArrayBuffer.slice()`. -const resizeArrayBufferSlow = (contents, length) => { - if (length <= contents.byteLength) { - return contents; - } - - const arrayBuffer = new ArrayBuffer(getNewContentsLength(length)); - new Uint8Array(arrayBuffer).set(new Uint8Array(contents), 0); - return arrayBuffer; -}; - -// With `ArrayBuffer.resize()`, `contents` size matches exactly the size of -// the stream data. It does not include extraneous zeroes to trim at the end. -// The underlying `ArrayBuffer` does allocate a number of bytes that is a power -// of 2, but those bytes are only visible after calling `ArrayBuffer.resize()`. -const resizeArrayBuffer = (contents, length) => { - if (length <= contents.maxByteLength) { - contents.resize(length); - return contents; - } - - const arrayBuffer = new ArrayBuffer(length, {maxByteLength: getNewContentsLength(length)}); - new Uint8Array(arrayBuffer).set(new Uint8Array(contents), 0); - return arrayBuffer; -}; - -// Retrieve the closest `length` that is both >= and a power of 2 -const getNewContentsLength = length => SCALE_FACTOR ** Math.ceil(Math.log(length) / Math.log(SCALE_FACTOR)); - -const SCALE_FACTOR = 2; - -const finalizeArrayBuffer = ({contents, length}) => hasArrayBufferResize() ? contents : contents.slice(0, length); - -// `ArrayBuffer.slice()` is slow. When `ArrayBuffer.resize()` is available -// (Node >=20.0.0, Safari >=16.4 and Chrome), we can use it instead. -// eslint-disable-next-line no-warning-comments -// TODO: remove after dropping support for Node 20. -// eslint-disable-next-line no-warning-comments -// TODO: use `ArrayBuffer.transferToFixedLength()` instead once it is available -const hasArrayBufferResize = () => 'resize' in ArrayBuffer.prototype; - -const arrayBufferMethods = { - init: initArrayBuffer, - convertChunk: { - string: useTextEncoder, - buffer: useUint8Array, - arrayBuffer: useUint8Array, - dataView: useUint8ArrayWithOffset, - typedArray: useUint8ArrayWithOffset, - others: throwObjectStream, - }, - getSize: getLengthProperty, - truncateChunk: truncateArrayBufferChunk, - addChunk: addArrayBufferChunk, - getFinalChunk: noop$1, - finalize: finalizeArrayBuffer, -}; - -async function getStreamAsString(stream, options) { - return getStreamContents$1(stream, stringMethods, options); -} - -const initString = () => ({contents: '', textDecoder: new TextDecoder()}); - -const useTextDecoder = (chunk, {textDecoder}) => textDecoder.decode(chunk, {stream: true}); - -const addStringChunk = (convertedChunk, {contents}) => contents + convertedChunk; - -const truncateStringChunk = (convertedChunk, chunkSize) => convertedChunk.slice(0, chunkSize); - -const getFinalStringChunk = ({textDecoder}) => { - const finalChunk = textDecoder.decode(); - return finalChunk === '' ? undefined : finalChunk; -}; - -const stringMethods = { - init: initString, - convertChunk: { - string: identity, - buffer: useTextDecoder, - arrayBuffer: useTextDecoder, - dataView: useTextDecoder, - typedArray: useTextDecoder, - others: throwObjectStream, - }, - getSize: getLengthProperty, - truncateChunk: truncateStringChunk, - addChunk: addStringChunk, - getFinalChunk: getFinalStringChunk, - finalize: getContentsProperty, -}; - -// When the `maxBuffer` option is hit, a MaxBufferError is thrown. -// The stream is aborted, then specific information is kept for the error message. -const handleMaxBuffer = ({error, stream, readableObjectMode, lines, encoding, fdNumber}) => { - if (!(error instanceof MaxBufferError)) { - throw error; - } - - if (fdNumber === 'all') { - return error; - } - - const unit = getMaxBufferUnit(readableObjectMode, lines, encoding); - error.maxBufferInfo = {fdNumber, unit}; - stream.destroy(); - throw error; -}; - -const getMaxBufferUnit = (readableObjectMode, lines, encoding) => { - if (readableObjectMode) { - return 'objects'; - } - - if (lines) { - return 'lines'; - } - - if (encoding === 'buffer') { - return 'bytes'; - } - - return 'characters'; -}; - -// Check the `maxBuffer` option with `result.ipcOutput` -const checkIpcMaxBuffer = (subprocess, ipcOutput, maxBuffer) => { - if (ipcOutput.length !== maxBuffer) { - return; - } - - const error = new MaxBufferError(); - error.maxBufferInfo = {fdNumber: 'ipc'}; - throw error; -}; - -// Error message when `maxBuffer` is hit -const getMaxBufferMessage = (error, maxBuffer) => { - const {streamName, threshold, unit} = getMaxBufferInfo(error, maxBuffer); - return `Command's ${streamName} was larger than ${threshold} ${unit}`; -}; - -const getMaxBufferInfo = (error, maxBuffer) => { - if (error?.maxBufferInfo === undefined) { - return {streamName: 'output', threshold: maxBuffer[1], unit: 'bytes'}; - } - - const {maxBufferInfo: {fdNumber, unit}} = error; - delete error.maxBufferInfo; - - const threshold = getFdSpecificValue(maxBuffer, fdNumber); - if (fdNumber === 'ipc') { - return {streamName: 'IPC output', threshold, unit: 'messages'}; - } - - return {streamName: getStreamName(fdNumber), threshold, unit}; -}; - -// The only way to apply `maxBuffer` with `spawnSync()` is to use the native `maxBuffer` option Node.js provides. -// However, this has multiple limitations, and cannot behave the exact same way as the async behavior. -// When the `maxBuffer` is hit, a `ENOBUFS` error is thrown. -const isMaxBufferSync = (resultError, output, maxBuffer) => resultError?.code === 'ENOBUFS' - && output !== null - && output.some(result => result !== null && result.length > getMaxBufferSync(maxBuffer)); - -// When `maxBuffer` is hit, ensure the result is truncated -const truncateMaxBufferSync = (result, isMaxBuffer, maxBuffer) => { - if (!isMaxBuffer) { - return result; - } - - const maxBufferValue = getMaxBufferSync(maxBuffer); - return result.length > maxBufferValue ? result.slice(0, maxBufferValue) : result; -}; - -// `spawnSync()` does not allow differentiating `maxBuffer` per file descriptor, so we always use `stdout` -const getMaxBufferSync = ([, stdoutMaxBuffer]) => stdoutMaxBuffer; - -// Computes `error.message`, `error.shortMessage` and `error.originalMessage` -const createMessages = ({ - stdio, - all, - ipcOutput, - originalError, - signal, - signalDescription, - exitCode, - escapedCommand, - timedOut, - isCanceled, - isGracefullyCanceled, - isMaxBuffer, - isForcefullyTerminated, - forceKillAfterDelay, - killSignal, - maxBuffer, - timeout, - cwd, -}) => { - const errorCode = originalError?.code; - const prefix = getErrorPrefix({ - originalError, - timedOut, - timeout, - isMaxBuffer, - maxBuffer, - errorCode, - signal, - signalDescription, - exitCode, - isCanceled, - isGracefullyCanceled, - isForcefullyTerminated, - forceKillAfterDelay, - killSignal, - }); - const originalMessage = getOriginalMessage(originalError, cwd); - const suffix = originalMessage === undefined ? '' : `\n${originalMessage}`; - const shortMessage = `${prefix}: ${escapedCommand}${suffix}`; - const messageStdio = all === undefined ? [stdio[2], stdio[1]] : [all]; - const message = [ - shortMessage, - ...messageStdio, - ...stdio.slice(3), - ipcOutput.map(ipcMessage => serializeIpcMessage(ipcMessage)).join('\n'), - ] - .map(messagePart => escapeLines(stripFinalNewline(serializeMessagePart(messagePart)))) - .filter(Boolean) - .join('\n\n'); - return {originalMessage, shortMessage, message}; -}; - -const getErrorPrefix = ({ - originalError, - timedOut, - timeout, - isMaxBuffer, - maxBuffer, - errorCode, - signal, - signalDescription, - exitCode, - isCanceled, - isGracefullyCanceled, - isForcefullyTerminated, - forceKillAfterDelay, - killSignal, -}) => { - const forcefulSuffix = getForcefulSuffix(isForcefullyTerminated, forceKillAfterDelay); - - if (timedOut) { - return `Command timed out after ${timeout} milliseconds${forcefulSuffix}`; - } - - if (isGracefullyCanceled) { - if (signal === undefined) { - return `Command was gracefully canceled with exit code ${exitCode}`; - } - - return isForcefullyTerminated - ? `Command was gracefully canceled${forcefulSuffix}` - : `Command was gracefully canceled with ${signal} (${signalDescription})`; - } - - if (isCanceled) { - return `Command was canceled${forcefulSuffix}`; - } - - if (isMaxBuffer) { - return `${getMaxBufferMessage(originalError, maxBuffer)}${forcefulSuffix}`; - } - - if (errorCode !== undefined) { - return `Command failed with ${errorCode}${forcefulSuffix}`; - } - - if (isForcefullyTerminated) { - return `Command was killed with ${killSignal} (${getSignalDescription(killSignal)})${forcefulSuffix}`; - } - - if (signal !== undefined) { - return `Command was killed with ${signal} (${signalDescription})`; - } - - if (exitCode !== undefined) { - return `Command failed with exit code ${exitCode}`; - } - - return 'Command failed'; -}; - -const getForcefulSuffix = (isForcefullyTerminated, forceKillAfterDelay) => isForcefullyTerminated - ? ` and was forcefully terminated after ${forceKillAfterDelay} milliseconds` - : ''; - -const getOriginalMessage = (originalError, cwd) => { - if (originalError instanceof DiscardedError) { - return; - } - - const originalMessage = isExecaError(originalError) - ? originalError.originalMessage - : String(originalError?.message ?? originalError); - const escapedOriginalMessage = escapeLines(fixCwdError(originalMessage, cwd)); - return escapedOriginalMessage === '' ? undefined : escapedOriginalMessage; -}; - -const serializeIpcMessage = ipcMessage => typeof ipcMessage === 'string' - ? ipcMessage - : inspect(ipcMessage); - -const serializeMessagePart = messagePart => Array.isArray(messagePart) - ? messagePart.map(messageItem => stripFinalNewline(serializeMessageItem(messageItem))).filter(Boolean).join('\n') - : serializeMessageItem(messagePart); - -const serializeMessageItem = messageItem => { - if (typeof messageItem === 'string') { - return messageItem; - } - - if (isUint8Array(messageItem)) { - return uint8ArrayToString(messageItem); - } - - return ''; -}; - -// Object returned on subprocess success -const makeSuccessResult = ({ - command, - escapedCommand, - stdio, - all, - ipcOutput, - options: {cwd}, - startTime, -}) => omitUndefinedProperties({ - command, - escapedCommand, - cwd, - durationMs: getDurationMs(startTime), - failed: false, - timedOut: false, - isCanceled: false, - isGracefullyCanceled: false, - isTerminated: false, - isMaxBuffer: false, - isForcefullyTerminated: false, - exitCode: 0, - stdout: stdio[1], - stderr: stdio[2], - all, - stdio, - ipcOutput, - pipedFrom: [], -}); - -// Object returned on subprocess failure before spawning -const makeEarlyError = ({ - error, - command, - escapedCommand, - fileDescriptors, - options, - startTime, - isSync, -}) => makeError({ - error, - command, - escapedCommand, - startTime, - timedOut: false, - isCanceled: false, - isGracefullyCanceled: false, - isMaxBuffer: false, - isForcefullyTerminated: false, - stdio: Array.from({length: fileDescriptors.length}), - ipcOutput: [], - options, - isSync, -}); - -// Object returned on subprocess failure -const makeError = ({ - error: originalError, - command, - escapedCommand, - startTime, - timedOut, - isCanceled, - isGracefullyCanceled, - isMaxBuffer, - isForcefullyTerminated, - exitCode: rawExitCode, - signal: rawSignal, - stdio, - all, - ipcOutput, - options: { - timeoutDuration, - timeout = timeoutDuration, - forceKillAfterDelay, - killSignal, - cwd, - maxBuffer, - }, - isSync, -}) => { - const {exitCode, signal, signalDescription} = normalizeExitPayload(rawExitCode, rawSignal); - const {originalMessage, shortMessage, message} = createMessages({ - stdio, - all, - ipcOutput, - originalError, - signal, - signalDescription, - exitCode, - escapedCommand, - timedOut, - isCanceled, - isGracefullyCanceled, - isMaxBuffer, - isForcefullyTerminated, - forceKillAfterDelay, - killSignal, - maxBuffer, - timeout, - cwd, - }); - const error = getFinalError(originalError, message, isSync); - Object.assign(error, getErrorProperties({ - error, - command, - escapedCommand, - startTime, - timedOut, - isCanceled, - isGracefullyCanceled, - isMaxBuffer, - isForcefullyTerminated, - exitCode, - signal, - signalDescription, - stdio, - all, - ipcOutput, - cwd, - originalMessage, - shortMessage, - })); - return error; -}; - -const getErrorProperties = ({ - error, - command, - escapedCommand, - startTime, - timedOut, - isCanceled, - isGracefullyCanceled, - isMaxBuffer, - isForcefullyTerminated, - exitCode, - signal, - signalDescription, - stdio, - all, - ipcOutput, - cwd, - originalMessage, - shortMessage, -}) => omitUndefinedProperties({ - shortMessage, - originalMessage, - command, - escapedCommand, - cwd, - durationMs: getDurationMs(startTime), - failed: true, - timedOut, - isCanceled, - isGracefullyCanceled, - isTerminated: signal !== undefined, - isMaxBuffer, - isForcefullyTerminated, - exitCode, - signal, - signalDescription, - code: error.cause?.code, - stdout: stdio[1], - stderr: stdio[2], - all, - stdio, - ipcOutput, - pipedFrom: [], -}); - -const omitUndefinedProperties = result => Object.fromEntries(Object.entries(result).filter(([, value]) => value !== undefined)); - -// `signal` and `exitCode` emitted on `subprocess.on('exit')` event can be `null`. -// We normalize them to `undefined` -const normalizeExitPayload = (rawExitCode, rawSignal) => { - const exitCode = rawExitCode === null ? undefined : rawExitCode; - const signal = rawSignal === null ? undefined : rawSignal; - const signalDescription = signal === undefined ? undefined : getSignalDescription(rawSignal); - return {exitCode, signal, signalDescription}; -}; - -const toZeroIfInfinity = value => Number.isFinite(value) ? value : 0; - -function parseNumber(milliseconds) { - return { - days: Math.trunc(milliseconds / 86_400_000), - hours: Math.trunc(milliseconds / 3_600_000 % 24), - minutes: Math.trunc(milliseconds / 60_000 % 60), - seconds: Math.trunc(milliseconds / 1000 % 60), - milliseconds: Math.trunc(milliseconds % 1000), - microseconds: Math.trunc(toZeroIfInfinity(milliseconds * 1000) % 1000), - nanoseconds: Math.trunc(toZeroIfInfinity(milliseconds * 1e6) % 1000), - }; -} - -function parseBigint(milliseconds) { - return { - days: milliseconds / 86_400_000n, - hours: milliseconds / 3_600_000n % 24n, - minutes: milliseconds / 60_000n % 60n, - seconds: milliseconds / 1000n % 60n, - milliseconds: milliseconds % 1000n, - microseconds: 0n, - nanoseconds: 0n, - }; -} - -function parseMilliseconds(milliseconds) { - switch (typeof milliseconds) { - case 'number': { - if (Number.isFinite(milliseconds)) { - return parseNumber(milliseconds); - } - - break; - } - - case 'bigint': { - return parseBigint(milliseconds); - } - - // No default - } - - throw new TypeError('Expected a finite number or bigint'); -} - -const isZero = value => value === 0 || value === 0n; -const pluralize = (word, count) => (count === 1 || count === 1n) ? word : `${word}s`; - -const SECOND_ROUNDING_EPSILON = 0.000_000_1; -const ONE_DAY_IN_MILLISECONDS = 24n * 60n * 60n * 1000n; - -function prettyMilliseconds(milliseconds, options) { - const isBigInt = typeof milliseconds === 'bigint'; - if (!isBigInt && !Number.isFinite(milliseconds)) { - throw new TypeError('Expected a finite number or bigint'); - } - - options = {...options}; - - const sign = milliseconds < 0 ? '-' : ''; - milliseconds = milliseconds < 0 ? -milliseconds : milliseconds; // Cannot use `Math.abs()` because of BigInt support. - - if (options.colonNotation) { - options.compact = false; - options.formatSubMilliseconds = false; - options.separateMilliseconds = false; - options.verbose = false; - } - - if (options.compact) { - options.unitCount = 1; - options.secondsDecimalDigits = 0; - options.millisecondsDecimalDigits = 0; - } - - let result = []; - - const floorDecimals = (value, decimalDigits) => { - const flooredInterimValue = Math.floor((value * (10 ** decimalDigits)) + SECOND_ROUNDING_EPSILON); - const flooredValue = Math.round(flooredInterimValue) / (10 ** decimalDigits); - return flooredValue.toFixed(decimalDigits); - }; - - const add = (value, long, short, valueString) => { - if ( - (result.length === 0 || !options.colonNotation) - && isZero(value) - && !(options.colonNotation && short === 'm')) { - return; - } - - valueString ??= String(value); - if (options.colonNotation) { - const wholeDigits = valueString.includes('.') ? valueString.split('.')[0].length : valueString.length; - const minLength = result.length > 0 ? 2 : 1; - valueString = '0'.repeat(Math.max(0, minLength - wholeDigits)) + valueString; - } else { - valueString += options.verbose ? ' ' + pluralize(long, value) : short; - } - - result.push(valueString); - }; - - const parsed = parseMilliseconds(milliseconds); - const days = BigInt(parsed.days); - - if (options.hideYearAndDays) { - add((BigInt(days) * 24n) + BigInt(parsed.hours), 'hour', 'h'); - } else { - if (options.hideYear) { - add(days, 'day', 'd'); - } else { - add(days / 365n, 'year', 'y'); - add(days % 365n, 'day', 'd'); - } - - add(Number(parsed.hours), 'hour', 'h'); - } - - add(Number(parsed.minutes), 'minute', 'm'); - - if (!options.hideSeconds) { - if ( - options.separateMilliseconds - || options.formatSubMilliseconds - || (!options.colonNotation && milliseconds < 1000 && !options.subSecondsAsDecimals) - ) { - const seconds = Number(parsed.seconds); - const milliseconds = Number(parsed.milliseconds); - const microseconds = Number(parsed.microseconds); - const nanoseconds = Number(parsed.nanoseconds); - - add(seconds, 'second', 's'); - - if (options.formatSubMilliseconds) { - add(milliseconds, 'millisecond', 'ms'); - add(microseconds, 'microsecond', 'µs'); - add(nanoseconds, 'nanosecond', 'ns'); - } else { - const millisecondsAndBelow - = milliseconds - + (microseconds / 1000) - + (nanoseconds / 1e6); - - const millisecondsDecimalDigits - = typeof options.millisecondsDecimalDigits === 'number' - ? options.millisecondsDecimalDigits - : 0; - - const roundedMilliseconds = millisecondsAndBelow >= 1 - ? Math.round(millisecondsAndBelow) - : Math.ceil(millisecondsAndBelow); - - const millisecondsString = millisecondsDecimalDigits - ? millisecondsAndBelow.toFixed(millisecondsDecimalDigits) - : roundedMilliseconds; - - add( - Number.parseFloat(millisecondsString), - 'millisecond', - 'ms', - millisecondsString, - ); - } - } else { - const seconds = ( - (isBigInt ? Number(milliseconds % ONE_DAY_IN_MILLISECONDS) : milliseconds) - / 1000 - ) % 60; - const secondsDecimalDigits - = typeof options.secondsDecimalDigits === 'number' - ? options.secondsDecimalDigits - : 1; - const secondsFixed = floorDecimals(seconds, secondsDecimalDigits); - const secondsString = options.keepDecimalsOnWholeSeconds - ? secondsFixed - : secondsFixed.replace(/\.0+$/, ''); - add(Number.parseFloat(secondsString), 'second', 's', secondsString); - } - } - - if (result.length === 0) { - return sign + '0' + (options.verbose ? ' milliseconds' : 'ms'); - } - - const separator = options.colonNotation ? ':' : ' '; - if (typeof options.unitCount === 'number') { - result = result.slice(0, Math.max(options.unitCount, 1)); - } - - return sign + result.join(separator); -} - -// When `verbose` is `short|full|custom`, print each command's error when it fails -const logError = (result, verboseInfo) => { - if (result.failed) { - verboseLog({ - type: 'error', - verboseMessage: result.shortMessage, - verboseInfo, - result, - }); - } -}; - -// When `verbose` is `short|full|custom`, print each command's completion, duration and error -const logResult = (result, verboseInfo) => { - if (!isVerbose(verboseInfo)) { - return; - } - - logError(result, verboseInfo); - logDuration(result, verboseInfo); -}; - -const logDuration = (result, verboseInfo) => { - const verboseMessage = `(done in ${prettyMilliseconds(result.durationMs)})`; - verboseLog({ - type: 'duration', - verboseMessage, - verboseInfo, - result, - }); -}; - -// Applies the `reject` option. -// Also print the final log line with `verbose`. -const handleResult = (result, verboseInfo, {reject}) => { - logResult(result, verboseInfo); - - if (result.failed && reject) { - throw result; - } - - return result; -}; - -// The `stdin`/`stdout`/`stderr` option can be of many types. This detects it. -const getStdioItemType = (value, optionName) => { - if (isAsyncGenerator(value)) { - return 'asyncGenerator'; - } - - if (isSyncGenerator(value)) { - return 'generator'; - } - - if (isUrl(value)) { - return 'fileUrl'; - } - - if (isFilePathObject(value)) { - return 'filePath'; - } - - if (isWebStream(value)) { - return 'webStream'; - } - - if (isStream(value, {checkOpen: false})) { - return 'native'; - } - - if (isUint8Array(value)) { - return 'uint8Array'; - } - - if (isAsyncIterableObject(value)) { - return 'asyncIterable'; - } - - if (isIterableObject(value)) { - return 'iterable'; - } - - if (isTransformStream(value)) { - return getTransformStreamType({}, optionName); - } - - if (isTransformOptions(value)) { - return getTransformObjectType(value, optionName); - } - - return 'native'; -}; - -const getTransformObjectType = (value, optionName) => { - if (isDuplexStream(value.transform, {checkOpen: false})) { - return getDuplexType(value, optionName); - } - - if (isTransformStream(value.transform)) { - return getTransformStreamType(value, optionName); - } - - return getGeneratorObjectType(value, optionName); -}; - -const getDuplexType = (value, optionName) => { - validateNonGeneratorType(value, optionName, 'Duplex stream'); - return 'duplex'; -}; - -const getTransformStreamType = (value, optionName) => { - validateNonGeneratorType(value, optionName, 'web TransformStream'); - return 'webTransform'; -}; - -const validateNonGeneratorType = ({final, binary, objectMode}, optionName, typeName) => { - checkUndefinedOption(final, `${optionName}.final`, typeName); - checkUndefinedOption(binary, `${optionName}.binary`, typeName); - checkBooleanOption(objectMode, `${optionName}.objectMode`); -}; - -const checkUndefinedOption = (value, optionName, typeName) => { - if (value !== undefined) { - throw new TypeError(`The \`${optionName}\` option can only be defined when using a generator, not a ${typeName}.`); - } -}; - -const getGeneratorObjectType = ({transform, final, binary, objectMode}, optionName) => { - if (transform !== undefined && !isGenerator(transform)) { - throw new TypeError(`The \`${optionName}.transform\` option must be a generator, a Duplex stream or a web TransformStream.`); - } - - if (isDuplexStream(final, {checkOpen: false})) { - throw new TypeError(`The \`${optionName}.final\` option must not be a Duplex stream.`); - } - - if (isTransformStream(final)) { - throw new TypeError(`The \`${optionName}.final\` option must not be a web TransformStream.`); - } - - if (final !== undefined && !isGenerator(final)) { - throw new TypeError(`The \`${optionName}.final\` option must be a generator.`); - } - - checkBooleanOption(binary, `${optionName}.binary`); - checkBooleanOption(objectMode, `${optionName}.objectMode`); - - return isAsyncGenerator(transform) || isAsyncGenerator(final) ? 'asyncGenerator' : 'generator'; -}; - -const checkBooleanOption = (value, optionName) => { - if (value !== undefined && typeof value !== 'boolean') { - throw new TypeError(`The \`${optionName}\` option must use a boolean.`); - } -}; - -const isGenerator = value => isAsyncGenerator(value) || isSyncGenerator(value); -const isAsyncGenerator = value => Object.prototype.toString.call(value) === '[object AsyncGeneratorFunction]'; -const isSyncGenerator = value => Object.prototype.toString.call(value) === '[object GeneratorFunction]'; -const isTransformOptions = value => isPlainObject(value) - && (value.transform !== undefined || value.final !== undefined); - -const isUrl = value => Object.prototype.toString.call(value) === '[object URL]'; -const isRegularUrl = value => isUrl(value) && value.protocol !== 'file:'; - -const isFilePathObject = value => isPlainObject(value) - && Object.keys(value).length > 0 - && Object.keys(value).every(key => FILE_PATH_KEYS.has(key)) - && isFilePathString(value.file); -const FILE_PATH_KEYS = new Set(['file', 'append']); -const isFilePathString = file => typeof file === 'string'; - -const isUnknownStdioString = (type, value) => type === 'native' - && typeof value === 'string' - && !KNOWN_STDIO_STRINGS.has(value); -const KNOWN_STDIO_STRINGS = new Set(['ipc', 'ignore', 'inherit', 'overlapped', 'pipe']); - -const isReadableStream = value => Object.prototype.toString.call(value) === '[object ReadableStream]'; -const isWritableStream = value => Object.prototype.toString.call(value) === '[object WritableStream]'; -const isWebStream = value => isReadableStream(value) || isWritableStream(value); -const isTransformStream = value => isReadableStream(value?.readable) && isWritableStream(value?.writable); - -const isAsyncIterableObject = value => isObject(value) && typeof value[Symbol.asyncIterator] === 'function'; -const isIterableObject = value => isObject(value) && typeof value[Symbol.iterator] === 'function'; -const isObject = value => typeof value === 'object' && value !== null; - -// Types which modify `subprocess.std*` -const TRANSFORM_TYPES = new Set(['generator', 'asyncGenerator', 'duplex', 'webTransform']); -// Types which write to a file or a file descriptor -const FILE_TYPES = new Set(['fileUrl', 'filePath', 'fileNumber']); -// When two file descriptors of this type share the same target, we need to do some special logic -const SPECIAL_DUPLICATE_TYPES_SYNC = new Set(['fileUrl', 'filePath']); -const SPECIAL_DUPLICATE_TYPES = new Set([...SPECIAL_DUPLICATE_TYPES_SYNC, 'webStream', 'nodeStream']); -// Do not allow two file descriptors of this type sharing the same target -const FORBID_DUPLICATE_TYPES = new Set(['webTransform', 'duplex']); - -// Convert types to human-friendly strings for error messages -const TYPE_TO_MESSAGE = { - generator: 'a generator', - asyncGenerator: 'an async generator', - fileUrl: 'a file URL', - filePath: 'a file path string', - fileNumber: 'a file descriptor number', - webStream: 'a web stream', - nodeStream: 'a Node.js stream', - webTransform: 'a web TransformStream', - duplex: 'a Duplex stream', - native: 'any value', - iterable: 'an iterable', - asyncIterable: 'an async iterable', - string: 'a string', - uint8Array: 'a Uint8Array', -}; - -/* -Retrieve the `objectMode`s of a single transform. -`objectMode` determines the return value's type, i.e. the `readableObjectMode`. -The chunk argument's type is based on the previous generator's return value, i.e. the `writableObjectMode` is based on the previous `readableObjectMode`. -The last input's generator is read by `subprocess.stdin` which: -- should not be in `objectMode` for performance reasons. -- can only be strings, Buffers and Uint8Arrays. -Therefore its `readableObjectMode` must be `false`. -The same applies to the first output's generator's `writableObjectMode`. -*/ -const getTransformObjectModes = (objectMode, index, newTransforms, direction) => direction === 'output' - ? getOutputObjectModes(objectMode, index, newTransforms) - : getInputObjectModes(objectMode, index, newTransforms); - -const getOutputObjectModes = (objectMode, index, newTransforms) => { - const writableObjectMode = index !== 0 && newTransforms[index - 1].value.readableObjectMode; - const readableObjectMode = objectMode ?? writableObjectMode; - return {writableObjectMode, readableObjectMode}; -}; - -const getInputObjectModes = (objectMode, index, newTransforms) => { - const writableObjectMode = index === 0 - ? objectMode === true - : newTransforms[index - 1].value.readableObjectMode; - const readableObjectMode = index !== newTransforms.length - 1 && (objectMode ?? writableObjectMode); - return {writableObjectMode, readableObjectMode}; -}; - -// Retrieve the `objectMode` of a file descriptor, e.g. `stdout` or `stderr` -const getFdObjectMode = (stdioItems, direction) => { - const lastTransform = stdioItems.findLast(({type}) => TRANSFORM_TYPES.has(type)); - if (lastTransform === undefined) { - return false; - } - - return direction === 'input' - ? lastTransform.value.writableObjectMode - : lastTransform.value.readableObjectMode; -}; - -// Transforms generators/duplex/TransformStream can have multiple shapes. -// This normalizes it and applies default values. -const normalizeTransforms = (stdioItems, optionName, direction, options) => [ - ...stdioItems.filter(({type}) => !TRANSFORM_TYPES.has(type)), - ...getTransforms(stdioItems, optionName, direction, options), -]; - -const getTransforms = (stdioItems, optionName, direction, {encoding}) => { - const transforms = stdioItems.filter(({type}) => TRANSFORM_TYPES.has(type)); - const newTransforms = Array.from({length: transforms.length}); - - for (const [index, stdioItem] of Object.entries(transforms)) { - newTransforms[index] = normalizeTransform({ - stdioItem, - index: Number(index), - newTransforms, - optionName, - direction, - encoding, - }); - } - - return sortTransforms(newTransforms, direction); -}; - -const normalizeTransform = ({stdioItem, stdioItem: {type}, index, newTransforms, optionName, direction, encoding}) => { - if (type === 'duplex') { - return normalizeDuplex({stdioItem, optionName}); - } - - if (type === 'webTransform') { - return normalizeTransformStream({ - stdioItem, - index, - newTransforms, - direction, - }); - } - - return normalizeGenerator({ - stdioItem, - index, - newTransforms, - direction, - encoding, - }); -}; - -const normalizeDuplex = ({ - stdioItem, - stdioItem: { - value: { - transform, - transform: {writableObjectMode, readableObjectMode}, - objectMode = readableObjectMode, - }, - }, - optionName, -}) => { - if (objectMode && !readableObjectMode) { - throw new TypeError(`The \`${optionName}.objectMode\` option can only be \`true\` if \`new Duplex({objectMode: true})\` is used.`); - } - - if (!objectMode && readableObjectMode) { - throw new TypeError(`The \`${optionName}.objectMode\` option cannot be \`false\` if \`new Duplex({objectMode: true})\` is used.`); - } - - return { - ...stdioItem, - value: {transform, writableObjectMode, readableObjectMode}, - }; -}; - -const normalizeTransformStream = ({stdioItem, stdioItem: {value}, index, newTransforms, direction}) => { - const {transform, objectMode} = isPlainObject(value) ? value : {transform: value}; - const {writableObjectMode, readableObjectMode} = getTransformObjectModes(objectMode, index, newTransforms, direction); - return ({ - ...stdioItem, - value: {transform, writableObjectMode, readableObjectMode}, - }); -}; - -const normalizeGenerator = ({stdioItem, stdioItem: {value}, index, newTransforms, direction, encoding}) => { - const { - transform, - final, - binary: binaryOption = false, - preserveNewlines = false, - objectMode, - } = isPlainObject(value) ? value : {transform: value}; - const binary = binaryOption || BINARY_ENCODINGS.has(encoding); - const {writableObjectMode, readableObjectMode} = getTransformObjectModes(objectMode, index, newTransforms, direction); - return { - ...stdioItem, - value: { - transform, - final, - binary, - preserveNewlines, - writableObjectMode, - readableObjectMode, - }, - }; -}; - -const sortTransforms = (newTransforms, direction) => direction === 'input' ? newTransforms.reverse() : newTransforms; - -// For `stdio[fdNumber]` beyond stdin/stdout/stderr, we need to guess whether the value passed is intended for inputs or outputs. -// This allows us to know whether to pipe _into_ or _from_ the stream. -// When `stdio[fdNumber]` is a single value, this guess is fairly straightforward. -// However, when it is an array instead, we also need to make sure the different values are not incompatible with each other. -const getStreamDirection = (stdioItems, fdNumber, optionName) => { - const directions = stdioItems.map(stdioItem => getStdioItemDirection(stdioItem, fdNumber)); - - if (directions.includes('input') && directions.includes('output')) { - throw new TypeError(`The \`${optionName}\` option must not be an array of both readable and writable values.`); - } - - return directions.find(Boolean) ?? DEFAULT_DIRECTION; -}; - -const getStdioItemDirection = ({type, value}, fdNumber) => KNOWN_DIRECTIONS[fdNumber] ?? guessStreamDirection[type](value); - -// `stdin`/`stdout`/`stderr` have a known direction -const KNOWN_DIRECTIONS = ['input', 'output', 'output']; - -const anyDirection = () => undefined; -const alwaysInput = () => 'input'; - -// `string` can only be added through the `input` option, i.e. does not need to be handled here -const guessStreamDirection = { - generator: anyDirection, - asyncGenerator: anyDirection, - fileUrl: anyDirection, - filePath: anyDirection, - iterable: alwaysInput, - asyncIterable: alwaysInput, - uint8Array: alwaysInput, - webStream: value => isWritableStream(value) ? 'output' : 'input', - nodeStream(value) { - if (!isReadableStream$1(value, {checkOpen: false})) { - return 'output'; - } - - return isWritableStream$1(value, {checkOpen: false}) ? undefined : 'input'; - }, - webTransform: anyDirection, - duplex: anyDirection, - native(value) { - const standardStreamDirection = getStandardStreamDirection(value); - if (standardStreamDirection !== undefined) { - return standardStreamDirection; - } - - if (isStream(value, {checkOpen: false})) { - return guessStreamDirection.nodeStream(value); - } - }, -}; - -const getStandardStreamDirection = value => { - if ([0, process$2.stdin].includes(value)) { - return 'input'; - } - - if ([1, 2, process$2.stdout, process$2.stderr].includes(value)) { - return 'output'; - } -}; - -// When ambiguous, we initially keep the direction as `undefined`. -// This allows arrays of `stdio` values to resolve the ambiguity. -// For example, `stdio[3]: DuplexStream` is ambiguous, but `stdio[3]: [DuplexStream, WritableStream]` is not. -// When the ambiguity remains, we default to `output` since it is the most common use case for additional file descriptors. -const DEFAULT_DIRECTION = 'output'; - -// The `ipc` option adds an `ipc` item to the `stdio` option -const normalizeIpcStdioArray = (stdioArray, ipc) => ipc && !stdioArray.includes('ipc') - ? [...stdioArray, 'ipc'] - : stdioArray; - -// Add support for `stdin`/`stdout`/`stderr` as an alias for `stdio`. -// Also normalize the `stdio` option. -const normalizeStdioOption = ({stdio, ipc, buffer, ...options}, verboseInfo, isSync) => { - const stdioArray = getStdioArray(stdio, options).map((stdioOption, fdNumber) => addDefaultValue(stdioOption, fdNumber)); - return isSync - ? normalizeStdioSync(stdioArray, buffer, verboseInfo) - : normalizeIpcStdioArray(stdioArray, ipc); -}; - -const getStdioArray = (stdio, options) => { - if (stdio === undefined) { - return STANDARD_STREAMS_ALIASES.map(alias => options[alias]); - } - - if (hasAlias(options)) { - throw new Error(`It's not possible to provide \`stdio\` in combination with one of ${STANDARD_STREAMS_ALIASES.map(alias => `\`${alias}\``).join(', ')}`); - } - - if (typeof stdio === 'string') { - return [stdio, stdio, stdio]; - } - - if (!Array.isArray(stdio)) { - throw new TypeError(`Expected \`stdio\` to be of type \`string\` or \`Array\`, got \`${typeof stdio}\``); - } - - const length = Math.max(stdio.length, STANDARD_STREAMS_ALIASES.length); - return Array.from({length}, (_, fdNumber) => stdio[fdNumber]); -}; - -const hasAlias = options => STANDARD_STREAMS_ALIASES.some(alias => options[alias] !== undefined); - -const addDefaultValue = (stdioOption, fdNumber) => { - if (Array.isArray(stdioOption)) { - return stdioOption.map(item => addDefaultValue(item, fdNumber)); - } - - if (stdioOption === null || stdioOption === undefined) { - return fdNumber >= STANDARD_STREAMS_ALIASES.length ? 'ignore' : 'pipe'; - } - - return stdioOption; -}; - -// Using `buffer: false` with synchronous methods implies `stdout`/`stderr`: `ignore`. -// Unless the output is needed, e.g. due to `verbose: 'full'` or to redirecting to a file. -const normalizeStdioSync = (stdioArray, buffer, verboseInfo) => stdioArray.map((stdioOption, fdNumber) => - !buffer[fdNumber] - && fdNumber !== 0 - && !isFullVerbose(verboseInfo, fdNumber) - && isOutputPipeOnly(stdioOption) - ? 'ignore' - : stdioOption); - -const isOutputPipeOnly = stdioOption => stdioOption === 'pipe' - || (Array.isArray(stdioOption) && stdioOption.every(item => item === 'pipe')); - -// When we use multiple `stdio` values for the same streams, we pass 'pipe' to `child_process.spawn()`. -// We then emulate the piping done by core Node.js. -// To do so, we transform the following values: -// - Node.js streams are marked as `type: nodeStream` -// - 'inherit' becomes `process.stdin|stdout|stderr` -// - any file descriptor integer becomes `process.stdio[fdNumber]` -// All of the above transformations tell Execa to perform manual piping. -const handleNativeStream = ({stdioItem, stdioItem: {type}, isStdioArray, fdNumber, direction, isSync}) => { - if (!isStdioArray || type !== 'native') { - return stdioItem; - } - - return isSync - ? handleNativeStreamSync({stdioItem, fdNumber, direction}) - : handleNativeStreamAsync({stdioItem, fdNumber}); -}; - -// Synchronous methods use a different logic. -// 'inherit', file descriptors and process.std* are handled by readFileSync()/writeFileSync(). -const handleNativeStreamSync = ({stdioItem, stdioItem: {value, optionName}, fdNumber, direction}) => { - const targetFd = getTargetFd({ - value, - optionName, - fdNumber, - direction, - }); - if (targetFd !== undefined) { - return targetFd; - } - - if (isStream(value, {checkOpen: false})) { - throw new TypeError(`The \`${optionName}: Stream\` option cannot both be an array and include a stream with synchronous methods.`); - } - - return stdioItem; -}; - -const getTargetFd = ({value, optionName, fdNumber, direction}) => { - const targetFdNumber = getTargetFdNumber(value, fdNumber); - if (targetFdNumber === undefined) { - return; - } - - if (direction === 'output') { - return {type: 'fileNumber', value: targetFdNumber, optionName}; - } - - if (tty.isatty(targetFdNumber)) { - throw new TypeError(`The \`${optionName}: ${serializeOptionValue(value)}\` option is invalid: it cannot be a TTY with synchronous methods.`); - } - - return {type: 'uint8Array', value: bufferToUint8Array(readFileSync(targetFdNumber)), optionName}; -}; - -const getTargetFdNumber = (value, fdNumber) => { - if (value === 'inherit') { - return fdNumber; - } - - if (typeof value === 'number') { - return value; - } - - const standardStreamIndex = STANDARD_STREAMS.indexOf(value); - if (standardStreamIndex !== -1) { - return standardStreamIndex; - } -}; - -const handleNativeStreamAsync = ({stdioItem, stdioItem: {value, optionName}, fdNumber}) => { - if (value === 'inherit') { - return {type: 'nodeStream', value: getStandardStream(fdNumber, value, optionName), optionName}; - } - - if (typeof value === 'number') { - return {type: 'nodeStream', value: getStandardStream(value, value, optionName), optionName}; - } - - if (isStream(value, {checkOpen: false})) { - return {type: 'nodeStream', value, optionName}; - } - - return stdioItem; -}; - -// Node.js does not allow to easily retrieve file descriptors beyond stdin/stdout/stderr as streams. -// - `fs.createReadStream()`/`fs.createWriteStream()` with the `fd` option do not work with character devices that use blocking reads/writes (such as interactive TTYs). -// - Using a TCP `Socket` would work but be rather complex to implement. -// Since this is an edge case, we simply throw an error message. -// See https://github.com/sindresorhus/execa/pull/643#discussion_r1435905707 -const getStandardStream = (fdNumber, value, optionName) => { - const standardStream = STANDARD_STREAMS[fdNumber]; - - if (standardStream === undefined) { - throw new TypeError(`The \`${optionName}: ${value}\` option is invalid: no such standard stream.`); - } - - return standardStream; -}; - -// Append the `stdin` option with the `input` and `inputFile` options -const handleInputOptions = ({input, inputFile}, fdNumber) => fdNumber === 0 - ? [ - ...handleInputOption(input), - ...handleInputFileOption(inputFile), - ] - : []; - -const handleInputOption = input => input === undefined ? [] : [{ - type: getInputType(input), - value: input, - optionName: 'input', -}]; - -const getInputType = input => { - if (isReadableStream$1(input, {checkOpen: false})) { - return 'nodeStream'; - } - - if (typeof input === 'string') { - return 'string'; - } - - if (isUint8Array(input)) { - return 'uint8Array'; - } - - throw new Error('The `input` option must be a string, a Uint8Array or a Node.js Readable stream.'); -}; - -const handleInputFileOption = inputFile => inputFile === undefined ? [] : [{ - ...getInputFileType(inputFile), - optionName: 'inputFile', -}]; - -const getInputFileType = inputFile => { - if (isUrl(inputFile)) { - return {type: 'fileUrl', value: inputFile}; - } - - if (isFilePathString(inputFile)) { - return {type: 'filePath', value: {file: inputFile}}; - } - - throw new Error('The `inputFile` option must be a file path string or a file URL.'); -}; - -// Duplicates in the same file descriptor is most likely an error. -// However, this can be useful with generators. -const filterDuplicates = stdioItems => stdioItems.filter((stdioItemOne, indexOne) => - stdioItems.every((stdioItemTwo, indexTwo) => stdioItemOne.value !== stdioItemTwo.value - || indexOne >= indexTwo - || stdioItemOne.type === 'generator' - || stdioItemOne.type === 'asyncGenerator')); - -// Check if two file descriptors are sharing the same target. -// For example `{stdout: {file: './output.txt'}, stderr: {file: './output.txt'}}`. -const getDuplicateStream = ({stdioItem: {type, value, optionName}, direction, fileDescriptors, isSync}) => { - const otherStdioItems = getOtherStdioItems(fileDescriptors, type); - if (otherStdioItems.length === 0) { - return; - } - - if (isSync) { - validateDuplicateStreamSync({ - otherStdioItems, - type, - value, - optionName, - direction, - }); - return; - } - - if (SPECIAL_DUPLICATE_TYPES.has(type)) { - return getDuplicateStreamInstance({ - otherStdioItems, - type, - value, - optionName, - direction, - }); - } - - if (FORBID_DUPLICATE_TYPES.has(type)) { - validateDuplicateTransform({ - otherStdioItems, - type, - value, - optionName, - }); - } -}; - -// Values shared by multiple file descriptors -const getOtherStdioItems = (fileDescriptors, type) => fileDescriptors - .flatMap(({direction, stdioItems}) => stdioItems - .filter(stdioItem => stdioItem.type === type) - .map((stdioItem => ({...stdioItem, direction})))); - -// With `execaSync()`, do not allow setting a file path both in input and output -const validateDuplicateStreamSync = ({otherStdioItems, type, value, optionName, direction}) => { - if (SPECIAL_DUPLICATE_TYPES_SYNC.has(type)) { - getDuplicateStreamInstance({ - otherStdioItems, - type, - value, - optionName, - direction, - }); - } -}; - -// When two file descriptors share the file or stream, we need to re-use the same underlying stream. -// Otherwise, the stream would be closed twice when piping ends. -// This is only an issue with output file descriptors. -// This is not a problem with generator functions since those create a new instance for each file descriptor. -// We also forbid input and output file descriptors sharing the same file or stream, since that does not make sense. -const getDuplicateStreamInstance = ({otherStdioItems, type, value, optionName, direction}) => { - const duplicateStdioItems = otherStdioItems.filter(stdioItem => hasSameValue(stdioItem, value)); - if (duplicateStdioItems.length === 0) { - return; - } - - const differentStdioItem = duplicateStdioItems.find(stdioItem => stdioItem.direction !== direction); - throwOnDuplicateStream(differentStdioItem, optionName, type); - - return direction === 'output' ? duplicateStdioItems[0].stream : undefined; -}; - -const hasSameValue = ({type, value}, secondValue) => { - if (type === 'filePath') { - return value.file === secondValue.file; - } - - if (type === 'fileUrl') { - return value.href === secondValue.href; - } - - return value === secondValue; -}; - -// We do not allow two file descriptors to share the same Duplex or TransformStream. -// This is because those are set directly to `subprocess.std*`. -// For example, this could result in `subprocess.stdout` and `subprocess.stderr` being the same value. -// This means reading from either would get data from both stdout and stderr. -const validateDuplicateTransform = ({otherStdioItems, type, value, optionName}) => { - const duplicateStdioItem = otherStdioItems.find(({value: {transform}}) => transform === value.transform); - throwOnDuplicateStream(duplicateStdioItem, optionName, type); -}; - -const throwOnDuplicateStream = (stdioItem, optionName, type) => { - if (stdioItem !== undefined) { - throw new TypeError(`The \`${stdioItem.optionName}\` and \`${optionName}\` options must not target ${TYPE_TO_MESSAGE[type]} that is the same.`); - } -}; - -// Handle `input`, `inputFile`, `stdin`, `stdout` and `stderr` options, before spawning, in async/sync mode -// They are converted into an array of `fileDescriptors`. -// Each `fileDescriptor` is normalized, validated and contains all information necessary for further handling. -const handleStdio = (addProperties, options, verboseInfo, isSync) => { - const stdio = normalizeStdioOption(options, verboseInfo, isSync); - const initialFileDescriptors = stdio.map((stdioOption, fdNumber) => getFileDescriptor({ - stdioOption, - fdNumber, - options, - isSync, - })); - const fileDescriptors = getFinalFileDescriptors({ - initialFileDescriptors, - addProperties, - options, - isSync, - }); - options.stdio = fileDescriptors.map(({stdioItems}) => forwardStdio(stdioItems)); - return fileDescriptors; -}; - -const getFileDescriptor = ({stdioOption, fdNumber, options, isSync}) => { - const optionName = getStreamName(fdNumber); - const {stdioItems: initialStdioItems, isStdioArray} = initializeStdioItems({ - stdioOption, - fdNumber, - options, - optionName, - }); - const direction = getStreamDirection(initialStdioItems, fdNumber, optionName); - const stdioItems = initialStdioItems.map(stdioItem => handleNativeStream({ - stdioItem, - isStdioArray, - fdNumber, - direction, - isSync, - })); - const normalizedStdioItems = normalizeTransforms(stdioItems, optionName, direction, options); - const objectMode = getFdObjectMode(normalizedStdioItems, direction); - validateFileObjectMode(normalizedStdioItems, objectMode); - return {direction, objectMode, stdioItems: normalizedStdioItems}; -}; - -// We make sure passing an array with a single item behaves the same as passing that item without an array. -// This is what users would expect. -// For example, `stdout: ['ignore']` behaves the same as `stdout: 'ignore'`. -const initializeStdioItems = ({stdioOption, fdNumber, options, optionName}) => { - const values = Array.isArray(stdioOption) ? stdioOption : [stdioOption]; - const initialStdioItems = [ - ...values.map(value => initializeStdioItem(value, optionName)), - ...handleInputOptions(options, fdNumber), - ]; - - const stdioItems = filterDuplicates(initialStdioItems); - const isStdioArray = stdioItems.length > 1; - validateStdioArray(stdioItems, isStdioArray, optionName); - validateStreams(stdioItems); - return {stdioItems, isStdioArray}; -}; - -const initializeStdioItem = (value, optionName) => ({ - type: getStdioItemType(value, optionName), - value, - optionName, -}); - -const validateStdioArray = (stdioItems, isStdioArray, optionName) => { - if (stdioItems.length === 0) { - throw new TypeError(`The \`${optionName}\` option must not be an empty array.`); - } - - if (!isStdioArray) { - return; - } - - for (const {value, optionName} of stdioItems) { - if (INVALID_STDIO_ARRAY_OPTIONS.has(value)) { - throw new Error(`The \`${optionName}\` option must not include \`${value}\`.`); - } - } -}; - -// Using those `stdio` values together with others for the same stream does not make sense, so we make it fail. -// However, we do allow it if the array has a single item. -const INVALID_STDIO_ARRAY_OPTIONS = new Set(['ignore', 'ipc']); - -const validateStreams = stdioItems => { - for (const stdioItem of stdioItems) { - validateFileStdio(stdioItem); - } -}; - -const validateFileStdio = ({type, value, optionName}) => { - if (isRegularUrl(value)) { - throw new TypeError(`The \`${optionName}: URL\` option must use the \`file:\` scheme. -For example, you can use the \`pathToFileURL()\` method of the \`url\` core module.`); - } - - if (isUnknownStdioString(type, value)) { - throw new TypeError(`The \`${optionName}: { file: '...' }\` option must be used instead of \`${optionName}: '...'\`.`); - } -}; - -const validateFileObjectMode = (stdioItems, objectMode) => { - if (!objectMode) { - return; - } - - const fileStdioItem = stdioItems.find(({type}) => FILE_TYPES.has(type)); - if (fileStdioItem !== undefined) { - throw new TypeError(`The \`${fileStdioItem.optionName}\` option cannot use both files and transforms in objectMode.`); - } -}; - -// Some `stdio` values require Execa to create streams. -// For example, file paths create file read/write streams. -// Those transformations are specified in `addProperties`, which is both direction-specific and type-specific. -const getFinalFileDescriptors = ({initialFileDescriptors, addProperties, options, isSync}) => { - const fileDescriptors = []; - - try { - for (const fileDescriptor of initialFileDescriptors) { - fileDescriptors.push(getFinalFileDescriptor({ - fileDescriptor, - fileDescriptors, - addProperties, - options, - isSync, - })); - } - - return fileDescriptors; - } catch (error) { - cleanupCustomStreams(fileDescriptors); - throw error; - } -}; - -const getFinalFileDescriptor = ({ - fileDescriptor: {direction, objectMode, stdioItems}, - fileDescriptors, - addProperties, - options, - isSync, -}) => { - const finalStdioItems = stdioItems.map(stdioItem => addStreamProperties({ - stdioItem, - addProperties, - direction, - options, - fileDescriptors, - isSync, - })); - return {direction, objectMode, stdioItems: finalStdioItems}; -}; - -const addStreamProperties = ({stdioItem, addProperties, direction, options, fileDescriptors, isSync}) => { - const duplicateStream = getDuplicateStream({ - stdioItem, - direction, - fileDescriptors, - isSync, - }); - - if (duplicateStream !== undefined) { - return {...stdioItem, stream: duplicateStream}; - } - - return { - ...stdioItem, - ...addProperties[direction][stdioItem.type](stdioItem, options), - }; -}; - -// The stream error handling is performed by the piping logic above, which cannot be performed before subprocess spawning. -// If the subprocess spawning fails (e.g. due to an invalid command), the streams need to be manually destroyed. -// We need to create those streams before subprocess spawning, in case their creation fails, e.g. when passing an invalid generator as argument. -// Like this, an exception would be thrown, which would prevent spawning a subprocess. -const cleanupCustomStreams = fileDescriptors => { - for (const {stdioItems} of fileDescriptors) { - for (const {stream} of stdioItems) { - if (stream !== undefined && !isStandardStream(stream)) { - stream.destroy(); - } - } - } -}; - -// When the `std*: Iterable | WebStream | URL | filePath`, `input` or `inputFile` option is used, we pipe to `subprocess.std*`. -// When the `std*: Array` option is used, we emulate some of the native values ('inherit', Node.js stream and file descriptor integer). To do so, we also need to pipe to `subprocess.std*`. -// Therefore the `std*` options must be either `pipe` or `overlapped`. Other values do not set `subprocess.std*`. -const forwardStdio = stdioItems => { - if (stdioItems.length > 1) { - return stdioItems.some(({value}) => value === 'overlapped') ? 'overlapped' : 'pipe'; - } - - const [{type, value}] = stdioItems; - return type === 'native' ? value : 'pipe'; -}; - -// Normalize `input`, `inputFile`, `stdin`, `stdout` and `stderr` options, before spawning, in sync mode -const handleStdioSync = (options, verboseInfo) => handleStdio(addPropertiesSync, options, verboseInfo, true); - -const forbiddenIfSync = ({type, optionName}) => { - throwInvalidSyncValue(optionName, TYPE_TO_MESSAGE[type]); -}; - -const forbiddenNativeIfSync = ({optionName, value}) => { - if (value === 'ipc' || value === 'overlapped') { - throwInvalidSyncValue(optionName, `"${value}"`); - } - - return {}; -}; - -const throwInvalidSyncValue = (optionName, value) => { - throw new TypeError(`The \`${optionName}\` option cannot be ${value} with synchronous methods.`); -}; - -// Create streams used internally for redirecting when using specific values for the `std*` options, in sync mode. -// For example, `stdin: {file}` reads the file synchronously, then passes it as the `input` option. -const addProperties$1 = { - generator() {}, - asyncGenerator: forbiddenIfSync, - webStream: forbiddenIfSync, - nodeStream: forbiddenIfSync, - webTransform: forbiddenIfSync, - duplex: forbiddenIfSync, - asyncIterable: forbiddenIfSync, - native: forbiddenNativeIfSync, -}; - -const addPropertiesSync = { - input: { - ...addProperties$1, - fileUrl: ({value}) => ({contents: [bufferToUint8Array(readFileSync(value))]}), - filePath: ({value: {file}}) => ({contents: [bufferToUint8Array(readFileSync(file))]}), - fileNumber: forbiddenIfSync, - iterable: ({value}) => ({contents: [...value]}), - string: ({value}) => ({contents: [value]}), - uint8Array: ({value}) => ({contents: [value]}), - }, - output: { - ...addProperties$1, - fileUrl: ({value}) => ({path: value}), - filePath: ({value: {file, append}}) => ({path: file, append}), - fileNumber: ({value}) => ({path: value}), - iterable: forbiddenIfSync, - string: forbiddenIfSync, - uint8Array: forbiddenIfSync, - }, -}; - -// Apply `stripFinalNewline` option, which applies to `result.stdout|stderr|all|stdio[*]`. -// If the `lines` option is used, it is applied on each line, but using a different function. -const stripNewline = (value, {stripFinalNewline: stripFinalNewline$1}, fdNumber) => getStripFinalNewline(stripFinalNewline$1, fdNumber) && value !== undefined && !Array.isArray(value) - ? stripFinalNewline(value) - : value; - -// Retrieve `stripFinalNewline` option value, including with `subprocess.all` -const getStripFinalNewline = (stripFinalNewline, fdNumber) => fdNumber === 'all' - ? stripFinalNewline[1] || stripFinalNewline[2] - : stripFinalNewline[fdNumber]; - -// Split chunks line-wise for generators passed to the `std*` options -const getSplitLinesGenerator = (binary, preserveNewlines, skipped, state) => binary || skipped - ? undefined - : initializeSplitLines(preserveNewlines, state); - -// Same but for synchronous methods -const splitLinesSync = (chunk, preserveNewlines, objectMode) => objectMode - ? chunk.flatMap(item => splitLinesItemSync(item, preserveNewlines)) - : splitLinesItemSync(chunk, preserveNewlines); - -const splitLinesItemSync = (chunk, preserveNewlines) => { - const {transform, final} = initializeSplitLines(preserveNewlines, {}); - return [...transform(chunk), ...final()]; -}; - -const initializeSplitLines = (preserveNewlines, state) => { - state.previousChunks = ''; - return { - transform: splitGenerator.bind(undefined, state, preserveNewlines), - final: linesFinal.bind(undefined, state), - }; -}; - -// This imperative logic is much faster than using `String.split()` and uses very low memory. -const splitGenerator = function * (state, preserveNewlines, chunk) { - if (typeof chunk !== 'string') { - yield chunk; - return; - } - - let {previousChunks} = state; - let start = -1; - - for (let end = 0; end < chunk.length; end += 1) { - if (chunk[end] === '\n') { - const newlineLength = getNewlineLength(chunk, end, preserveNewlines, state); - let line = chunk.slice(start + 1, end + 1 - newlineLength); - - if (previousChunks.length > 0) { - line = concatString(previousChunks, line); - previousChunks = ''; - } - - yield line; - start = end; - } - } - - if (start !== chunk.length - 1) { - previousChunks = concatString(previousChunks, chunk.slice(start + 1)); - } - - state.previousChunks = previousChunks; -}; - -const getNewlineLength = (chunk, end, preserveNewlines, state) => { - if (preserveNewlines) { - return 0; - } - - state.isWindowsNewline = end !== 0 && chunk[end - 1] === '\r'; - return state.isWindowsNewline ? 2 : 1; -}; - -const linesFinal = function * ({previousChunks}) { - if (previousChunks.length > 0) { - yield previousChunks; - } -}; - -// Unless `preserveNewlines: true` is used, we strip the newline of each line. -// This re-adds them after the user `transform` code has run. -const getAppendNewlineGenerator = ({binary, preserveNewlines, readableObjectMode, state}) => binary || preserveNewlines || readableObjectMode - ? undefined - : {transform: appendNewlineGenerator.bind(undefined, state)}; - -const appendNewlineGenerator = function * ({isWindowsNewline = false}, chunk) { - const {unixNewline, windowsNewline, LF, concatBytes} = typeof chunk === 'string' ? linesStringInfo : linesUint8ArrayInfo; - - if (chunk.at(-1) === LF) { - yield chunk; - return; - } - - const newline = isWindowsNewline ? windowsNewline : unixNewline; - yield concatBytes(chunk, newline); -}; - -const concatString = (firstChunk, secondChunk) => `${firstChunk}${secondChunk}`; - -const linesStringInfo = { - windowsNewline: '\r\n', - unixNewline: '\n', - LF: '\n', - concatBytes: concatString, -}; - -const concatUint8Array = (firstChunk, secondChunk) => { - const chunk = new Uint8Array(firstChunk.length + secondChunk.length); - chunk.set(firstChunk, 0); - chunk.set(secondChunk, firstChunk.length); - return chunk; -}; - -const linesUint8ArrayInfo = { - windowsNewline: new Uint8Array([0x0D, 0x0A]), - unixNewline: new Uint8Array([0x0A]), - LF: 0x0A, - concatBytes: concatUint8Array, -}; - -// Validate the type of chunk argument passed to transform generators -const getValidateTransformInput = (writableObjectMode, optionName) => writableObjectMode - ? undefined - : validateStringTransformInput.bind(undefined, optionName); - -const validateStringTransformInput = function * (optionName, chunk) { - if (typeof chunk !== 'string' && !isUint8Array(chunk) && !Buffer$1.isBuffer(chunk)) { - throw new TypeError(`The \`${optionName}\` option's transform must use "objectMode: true" to receive as input: ${typeof chunk}.`); - } - - yield chunk; -}; - -// Validate the type of the value returned by transform generators -const getValidateTransformReturn = (readableObjectMode, optionName) => readableObjectMode - ? validateObjectTransformReturn.bind(undefined, optionName) - : validateStringTransformReturn.bind(undefined, optionName); - -const validateObjectTransformReturn = function * (optionName, chunk) { - validateEmptyReturn(optionName, chunk); - yield chunk; -}; - -const validateStringTransformReturn = function * (optionName, chunk) { - validateEmptyReturn(optionName, chunk); - - if (typeof chunk !== 'string' && !isUint8Array(chunk)) { - throw new TypeError(`The \`${optionName}\` option's function must yield a string or an Uint8Array, not ${typeof chunk}.`); - } - - yield chunk; -}; - -const validateEmptyReturn = (optionName, chunk) => { - if (chunk === null || chunk === undefined) { - throw new TypeError(`The \`${optionName}\` option's function must not call \`yield ${chunk}\`. -Instead, \`yield\` should either be called with a value, or not be called at all. For example: - if (condition) { yield value; }`); - } -}; - -/* -When using binary encodings, add an internal generator that converts chunks from `Buffer` to `string` or `Uint8Array`. -Chunks might be Buffer, Uint8Array or strings since: -- `subprocess.stdout|stderr` emits Buffers -- `subprocess.stdin.write()` accepts Buffer, Uint8Array or string -- Previous generators might return Uint8Array or string - -However, those are converted to Buffer: -- on writes: `Duplex.writable` `decodeStrings: true` default option -- on reads: `Duplex.readable` `readableEncoding: null` default option -*/ -const getEncodingTransformGenerator = (binary, encoding, skipped) => { - if (skipped) { - return; - } - - if (binary) { - return {transform: encodingUint8ArrayGenerator.bind(undefined, new TextEncoder())}; - } - - const stringDecoder = new StringDecoder(encoding); - return { - transform: encodingStringGenerator.bind(undefined, stringDecoder), - final: encodingStringFinal.bind(undefined, stringDecoder), - }; -}; - -const encodingUint8ArrayGenerator = function * (textEncoder, chunk) { - if (Buffer$1.isBuffer(chunk)) { - yield bufferToUint8Array(chunk); - } else if (typeof chunk === 'string') { - yield textEncoder.encode(chunk); - } else { - yield chunk; - } -}; - -const encodingStringGenerator = function * (stringDecoder, chunk) { - yield isUint8Array(chunk) ? stringDecoder.write(chunk) : chunk; -}; - -const encodingStringFinal = function * (stringDecoder) { - const lastChunk = stringDecoder.end(); - if (lastChunk !== '') { - yield lastChunk; - } -}; - -// Applies a series of generator functions asynchronously -const pushChunks = callbackify(async (getChunks, state, getChunksArguments, transformStream) => { - state.currentIterable = getChunks(...getChunksArguments); - - try { - for await (const chunk of state.currentIterable) { - transformStream.push(chunk); - } - } finally { - delete state.currentIterable; - } -}); - -// For each new chunk, apply each `transform()` method -const transformChunk = async function * (chunk, generators, index) { - if (index === generators.length) { - yield chunk; - return; - } - - const {transform = identityGenerator$1} = generators[index]; - for await (const transformedChunk of transform(chunk)) { - yield * transformChunk(transformedChunk, generators, index + 1); - } -}; - -// At the end, apply each `final()` method, followed by the `transform()` method of the next transforms -const finalChunks = async function * (generators) { - for (const [index, {final}] of Object.entries(generators)) { - yield * generatorFinalChunks(final, Number(index), generators); - } -}; - -const generatorFinalChunks = async function * (final, index, generators) { - if (final === undefined) { - return; - } - - for await (const finalChunk of final()) { - yield * transformChunk(finalChunk, generators, index + 1); - } -}; - -// Cancel any ongoing async generator when the Transform is destroyed, e.g. when the subprocess errors -const destroyTransform = callbackify(async ({currentIterable}, error) => { - if (currentIterable !== undefined) { - await (error ? currentIterable.throw(error) : currentIterable.return()); - return; - } - - if (error) { - throw error; - } -}); - -const identityGenerator$1 = function * (chunk) { - yield chunk; -}; - -// Duplicate the code from `run-async.js` but as synchronous functions -const pushChunksSync = (getChunksSync, getChunksArguments, transformStream, done) => { - try { - for (const chunk of getChunksSync(...getChunksArguments)) { - transformStream.push(chunk); - } - - done(); - } catch (error) { - done(error); - } -}; - -// Run synchronous generators with `execaSync()` -const runTransformSync = (generators, chunks) => [ - ...chunks.flatMap(chunk => [...transformChunkSync(chunk, generators, 0)]), - ...finalChunksSync(generators), -]; - -const transformChunkSync = function * (chunk, generators, index) { - if (index === generators.length) { - yield chunk; - return; - } - - const {transform = identityGenerator} = generators[index]; - for (const transformedChunk of transform(chunk)) { - yield * transformChunkSync(transformedChunk, generators, index + 1); - } -}; - -const finalChunksSync = function * (generators) { - for (const [index, {final}] of Object.entries(generators)) { - yield * generatorFinalChunksSync(final, Number(index), generators); - } -}; - -const generatorFinalChunksSync = function * (final, index, generators) { - if (final === undefined) { - return; - } - - for (const finalChunk of final()) { - yield * transformChunkSync(finalChunk, generators, index + 1); - } -}; - -const identityGenerator = function * (chunk) { - yield chunk; -}; - -/* -Generators can be used to transform/filter standard streams. - -Generators have a simple syntax, yet allows all of the following: -- Sharing `state` between chunks -- Flushing logic, by using a `final` function -- Asynchronous logic -- Emitting multiple chunks from a single source chunk, even if spaced in time, by using multiple `yield` -- Filtering, by using no `yield` - -Therefore, there is no need to allow Node.js or web transform streams. - -The `highWaterMark` is kept as the default value, since this is what `subprocess.std*` uses. - -Chunks are currently processed serially. We could add a `concurrency` option to parallelize in the future. - -Transform an array of generator functions into a `Transform` stream. -`Duplex.from(generator)` cannot be used because it does not allow setting the `objectMode` and `highWaterMark`. -*/ -const generatorToStream = ({ - value, - value: {transform, final, writableObjectMode, readableObjectMode}, - optionName, -}, {encoding}) => { - const state = {}; - const generators = addInternalGenerators(value, encoding, optionName); - - const transformAsync = isAsyncGenerator(transform); - const finalAsync = isAsyncGenerator(final); - const transformMethod = transformAsync - ? pushChunks.bind(undefined, transformChunk, state) - : pushChunksSync.bind(undefined, transformChunkSync); - const finalMethod = transformAsync || finalAsync - ? pushChunks.bind(undefined, finalChunks, state) - : pushChunksSync.bind(undefined, finalChunksSync); - const destroyMethod = transformAsync || finalAsync - ? destroyTransform.bind(undefined, state) - : undefined; - - const stream = new Transform({ - writableObjectMode, - writableHighWaterMark: getDefaultHighWaterMark(writableObjectMode), - readableObjectMode, - readableHighWaterMark: getDefaultHighWaterMark(readableObjectMode), - transform(chunk, encoding, done) { - transformMethod([chunk, generators, 0], this, done); - }, - flush(done) { - finalMethod([generators], this, done); - }, - destroy: destroyMethod, - }); - return {stream}; -}; - -// Applies transform generators in sync mode -const runGeneratorsSync = (chunks, stdioItems, encoding, isInput) => { - const generators = stdioItems.filter(({type}) => type === 'generator'); - const reversedGenerators = isInput ? generators.reverse() : generators; - - for (const {value, optionName} of reversedGenerators) { - const generators = addInternalGenerators(value, encoding, optionName); - chunks = runTransformSync(generators, chunks); - } - - return chunks; -}; - -// Generators used internally to convert the chunk type, validate it, and split into lines -const addInternalGenerators = ( - {transform, final, binary, writableObjectMode, readableObjectMode, preserveNewlines}, - encoding, - optionName, -) => { - const state = {}; - return [ - {transform: getValidateTransformInput(writableObjectMode, optionName)}, - getEncodingTransformGenerator(binary, encoding, writableObjectMode), - getSplitLinesGenerator(binary, preserveNewlines, writableObjectMode, state), - {transform, final}, - {transform: getValidateTransformReturn(readableObjectMode, optionName)}, - getAppendNewlineGenerator({ - binary, - preserveNewlines, - readableObjectMode, - state, - }), - ].filter(Boolean); -}; - -// Apply `stdin`/`input`/`inputFile` options, before spawning, in sync mode, by converting it to the `input` option -const addInputOptionsSync = (fileDescriptors, options) => { - for (const fdNumber of getInputFdNumbers(fileDescriptors)) { - addInputOptionSync(fileDescriptors, fdNumber, options); - } -}; - -const getInputFdNumbers = fileDescriptors => new Set(Object.entries(fileDescriptors) - .filter(([, {direction}]) => direction === 'input') - .map(([fdNumber]) => Number(fdNumber))); - -const addInputOptionSync = (fileDescriptors, fdNumber, options) => { - const {stdioItems} = fileDescriptors[fdNumber]; - const allStdioItems = stdioItems.filter(({contents}) => contents !== undefined); - if (allStdioItems.length === 0) { - return; - } - - if (fdNumber !== 0) { - const [{type, optionName}] = allStdioItems; - throw new TypeError(`Only the \`stdin\` option, not \`${optionName}\`, can be ${TYPE_TO_MESSAGE[type]} with synchronous methods.`); - } - - const allContents = allStdioItems.map(({contents}) => contents); - const transformedContents = allContents.map(contents => applySingleInputGeneratorsSync(contents, stdioItems)); - options.input = joinToUint8Array(transformedContents); -}; - -const applySingleInputGeneratorsSync = (contents, stdioItems) => { - const newContents = runGeneratorsSync(contents, stdioItems, 'utf8', true); - validateSerializable(newContents); - return joinToUint8Array(newContents); -}; - -const validateSerializable = newContents => { - const invalidItem = newContents.find(item => typeof item !== 'string' && !isUint8Array(item)); - if (invalidItem !== undefined) { - throw new TypeError(`The \`stdin\` option is invalid: when passing objects as input, a transform must be used to serialize them to strings or Uint8Arrays: ${invalidItem}.`); - } -}; - -// `ignore` opts-out of `verbose` for a specific stream. -// `ipc` cannot use piping. -// `inherit` would result in double printing. -// They can also lead to double printing when passing file descriptor integers or `process.std*`. -// This only leaves with `pipe` and `overlapped`. -const shouldLogOutput = ({stdioItems, encoding, verboseInfo, fdNumber}) => fdNumber !== 'all' - && isFullVerbose(verboseInfo, fdNumber) - && !BINARY_ENCODINGS.has(encoding) - && fdUsesVerbose(fdNumber) - && (stdioItems.some(({type, value}) => type === 'native' && PIPED_STDIO_VALUES.has(value)) - || stdioItems.every(({type}) => TRANSFORM_TYPES.has(type))); - -// Printing input streams would be confusing. -// Files and streams can produce big outputs, which we don't want to print. -// We could print `stdio[3+]` but it often is redirected to files and streams, with the same issue. -// So we only print stdout and stderr. -const fdUsesVerbose = fdNumber => fdNumber === 1 || fdNumber === 2; - -const PIPED_STDIO_VALUES = new Set(['pipe', 'overlapped']); - -// `verbose: 'full'` printing logic with async methods -const logLines = async (linesIterable, stream, fdNumber, verboseInfo) => { - for await (const line of linesIterable) { - if (!isPipingStream(stream)) { - logLine(line, fdNumber, verboseInfo); - } - } -}; - -// `verbose: 'full'` printing logic with sync methods -const logLinesSync = (linesArray, fdNumber, verboseInfo) => { - for (const line of linesArray) { - logLine(line, fdNumber, verboseInfo); - } -}; - -// When `subprocess.stdout|stderr.pipe()` is called, `verbose` becomes a noop. -// This prevents the following problems: -// - `.pipe()` achieves the same result as using `stdout: 'inherit'`, `stdout: stream`, etc. which also make `verbose` a noop. -// For example, `subprocess.stdout.pipe(process.stdin)` would print each line twice. -// - When chaining subprocesses with `subprocess.pipe(otherSubprocess)`, only the last one should print its output. -// Detecting whether `.pipe()` is impossible without monkey-patching it, so we use the following undocumented property. -// This is not a critical behavior since changes of the following property would only make `verbose` more verbose. -const isPipingStream = stream => stream._readableState.pipes.length > 0; - -// When `verbose` is `full`, print stdout|stderr -const logLine = (line, fdNumber, verboseInfo) => { - const verboseMessage = serializeVerboseMessage(line); - verboseLog({ - type: 'output', - verboseMessage, - fdNumber, - verboseInfo, - }); -}; - -// Apply `stdout`/`stderr` options, after spawning, in sync mode -const transformOutputSync = ({fileDescriptors, syncResult: {output}, options, isMaxBuffer, verboseInfo}) => { - if (output === null) { - return {output: Array.from({length: 3})}; - } - - const state = {}; - const outputFiles = new Set([]); - const transformedOutput = output.map((result, fdNumber) => - transformOutputResultSync({ - result, - fileDescriptors, - fdNumber, - state, - outputFiles, - isMaxBuffer, - verboseInfo, - }, options)); - return {output: transformedOutput, ...state}; -}; - -const transformOutputResultSync = ( - {result, fileDescriptors, fdNumber, state, outputFiles, isMaxBuffer, verboseInfo}, - {buffer, encoding, lines, stripFinalNewline, maxBuffer}, -) => { - if (result === null) { - return; - } - - const truncatedResult = truncateMaxBufferSync(result, isMaxBuffer, maxBuffer); - const uint8ArrayResult = bufferToUint8Array(truncatedResult); - const {stdioItems, objectMode} = fileDescriptors[fdNumber]; - const chunks = runOutputGeneratorsSync([uint8ArrayResult], stdioItems, encoding, state); - const {serializedResult, finalResult = serializedResult} = serializeChunks({ - chunks, - objectMode, - encoding, - lines, - stripFinalNewline, - fdNumber, - }); - - logOutputSync({ - serializedResult, - fdNumber, - state, - verboseInfo, - encoding, - stdioItems, - objectMode, - }); - - const returnedResult = buffer[fdNumber] ? finalResult : undefined; - - try { - if (state.error === undefined) { - writeToFiles(serializedResult, stdioItems, outputFiles); - } - - return returnedResult; - } catch (error) { - state.error = error; - return returnedResult; - } -}; - -// Applies transform generators to `stdout`/`stderr` -const runOutputGeneratorsSync = (chunks, stdioItems, encoding, state) => { - try { - return runGeneratorsSync(chunks, stdioItems, encoding, false); - } catch (error) { - state.error = error; - return chunks; - } -}; - -// The contents is converted to three stages: -// - serializedResult: used when the target is a file path/URL or a file descriptor (including 'inherit') -// - finalResult/returnedResult: returned as `result.std*` -const serializeChunks = ({chunks, objectMode, encoding, lines, stripFinalNewline, fdNumber}) => { - if (objectMode) { - return {serializedResult: chunks}; - } - - if (encoding === 'buffer') { - return {serializedResult: joinToUint8Array(chunks)}; - } - - const serializedResult = joinToString(chunks, encoding); - if (lines[fdNumber]) { - return {serializedResult, finalResult: splitLinesSync(serializedResult, !stripFinalNewline[fdNumber], objectMode)}; - } - - return {serializedResult}; -}; - -const logOutputSync = ({serializedResult, fdNumber, state, verboseInfo, encoding, stdioItems, objectMode}) => { - if (!shouldLogOutput({ - stdioItems, - encoding, - verboseInfo, - fdNumber, - })) { - return; - } - - const linesArray = splitLinesSync(serializedResult, false, objectMode); - - try { - logLinesSync(linesArray, fdNumber, verboseInfo); - } catch (error) { - state.error ??= error; - } -}; - -// When the `std*` target is a file path/URL or a file descriptor -const writeToFiles = (serializedResult, stdioItems, outputFiles) => { - for (const {path, append} of stdioItems.filter(({type}) => FILE_TYPES.has(type))) { - const pathString = typeof path === 'string' ? path : path.toString(); - if (append || outputFiles.has(pathString)) { - appendFileSync(path, serializedResult); - } else { - outputFiles.add(pathString); - writeFileSync(path, serializedResult); - } - } -}; - -// Retrieve `result.all` with synchronous methods -const getAllSync = ([, stdout, stderr], options) => { - if (!options.all) { - return; - } - - if (stdout === undefined) { - return stderr; - } - - if (stderr === undefined) { - return stdout; - } - - if (Array.isArray(stdout)) { - return Array.isArray(stderr) - ? [...stdout, ...stderr] - : [...stdout, stripNewline(stderr, options, 'all')]; - } - - if (Array.isArray(stderr)) { - return [stripNewline(stdout, options, 'all'), ...stderr]; - } - - if (isUint8Array(stdout) && isUint8Array(stderr)) { - return concatUint8Arrays([stdout, stderr]); - } - - return `${stdout}${stderr}`; -}; - -// If `error` is emitted before `spawn`, `exit` will never be emitted. -// However, `error` might be emitted after `spawn`. -// In that case, `exit` will still be emitted. -// Since the `exit` event contains the signal name, we want to make sure we are listening for it. -// This function also takes into account the following unlikely cases: -// - `exit` being emitted in the same microtask as `spawn` -// - `error` being emitted multiple times -const waitForExit = async (subprocess, context) => { - const [exitCode, signal] = await waitForExitOrError(subprocess); - context.isForcefullyTerminated ??= false; - return [exitCode, signal]; -}; - -const waitForExitOrError = async subprocess => { - const [spawnPayload, exitPayload] = await Promise.allSettled([ - once$2(subprocess, 'spawn'), - once$2(subprocess, 'exit'), - ]); - - if (spawnPayload.status === 'rejected') { - return []; - } - - return exitPayload.status === 'rejected' - ? waitForSubprocessExit(subprocess) - : exitPayload.value; -}; - -const waitForSubprocessExit = async subprocess => { - try { - return await once$2(subprocess, 'exit'); - } catch { - return waitForSubprocessExit(subprocess); - } -}; - -// Retrieve the final exit code and|or signal name -const waitForSuccessfulExit = async exitPromise => { - const [exitCode, signal] = await exitPromise; - - if (!isSubprocessErrorExit(exitCode, signal) && isFailedExit(exitCode, signal)) { - throw new DiscardedError(); - } - - return [exitCode, signal]; -}; - -// When the subprocess fails due to an `error` event -const isSubprocessErrorExit = (exitCode, signal) => exitCode === undefined && signal === undefined; -// When the subprocess fails due to a non-0 exit code or to a signal termination -const isFailedExit = (exitCode, signal) => exitCode !== 0 || signal !== null; - -// Retrieve exit code, signal name and error information, with synchronous methods -const getExitResultSync = ({error, status: exitCode, signal, output}, {maxBuffer}) => { - const resultError = getResultError(error, exitCode, signal); - const timedOut = resultError?.code === 'ETIMEDOUT'; - const isMaxBuffer = isMaxBufferSync(resultError, output, maxBuffer); - return { - resultError, - exitCode, - signal, - timedOut, - isMaxBuffer, - }; -}; - -const getResultError = (error, exitCode, signal) => { - if (error !== undefined) { - return error; - } - - return isFailedExit(exitCode, signal) ? new DiscardedError() : undefined; -}; - -// Main shared logic for all sync methods: `execaSync()`, `$.sync()` -const execaCoreSync = (rawFile, rawArguments, rawOptions) => { - const {file, commandArguments, command, escapedCommand, startTime, verboseInfo, options, fileDescriptors} = handleSyncArguments(rawFile, rawArguments, rawOptions); - const result = spawnSubprocessSync({ - file, - commandArguments, - options, - command, - escapedCommand, - verboseInfo, - fileDescriptors, - startTime, - }); - return handleResult(result, verboseInfo, options); -}; - -// Compute arguments to pass to `child_process.spawnSync()` -const handleSyncArguments = (rawFile, rawArguments, rawOptions) => { - const {command, escapedCommand, startTime, verboseInfo} = handleCommand(rawFile, rawArguments, rawOptions); - const syncOptions = normalizeSyncOptions(rawOptions); - const {file, commandArguments, options} = normalizeOptions(rawFile, rawArguments, syncOptions); - validateSyncOptions(options); - const fileDescriptors = handleStdioSync(options, verboseInfo); - return { - file, - commandArguments, - command, - escapedCommand, - startTime, - verboseInfo, - options, - fileDescriptors, - }; -}; - -// Options normalization logic specific to sync methods -const normalizeSyncOptions = options => options.node && !options.ipc ? {...options, ipc: false} : options; - -// Options validation logic specific to sync methods -const validateSyncOptions = ({ipc, ipcInput, detached, cancelSignal}) => { - if (ipcInput) { - throwInvalidSyncOption('ipcInput'); - } - - if (ipc) { - throwInvalidSyncOption('ipc: true'); - } - - if (detached) { - throwInvalidSyncOption('detached: true'); - } - - if (cancelSignal) { - throwInvalidSyncOption('cancelSignal'); - } -}; - -const throwInvalidSyncOption = value => { - throw new TypeError(`The "${value}" option cannot be used with synchronous methods.`); -}; - -const spawnSubprocessSync = ({file, commandArguments, options, command, escapedCommand, verboseInfo, fileDescriptors, startTime}) => { - const syncResult = runSubprocessSync({ - file, - commandArguments, - options, - command, - escapedCommand, - fileDescriptors, - startTime, - }); - if (syncResult.failed) { - return syncResult; - } - - const {resultError, exitCode, signal, timedOut, isMaxBuffer} = getExitResultSync(syncResult, options); - const {output, error = resultError} = transformOutputSync({ - fileDescriptors, - syncResult, - options, - isMaxBuffer, - verboseInfo, - }); - const stdio = output.map((stdioOutput, fdNumber) => stripNewline(stdioOutput, options, fdNumber)); - const all = stripNewline(getAllSync(output, options), options, 'all'); - return getSyncResult({ - error, - exitCode, - signal, - timedOut, - isMaxBuffer, - stdio, - all, - options, - command, - escapedCommand, - startTime, - }); -}; - -const runSubprocessSync = ({file, commandArguments, options, command, escapedCommand, fileDescriptors, startTime}) => { - try { - addInputOptionsSync(fileDescriptors, options); - const normalizedOptions = normalizeSpawnSyncOptions(options); - return spawnSync(...concatenateShell(file, commandArguments, normalizedOptions)); - } catch (error) { - return makeEarlyError({ - error, - command, - escapedCommand, - fileDescriptors, - options, - startTime, - isSync: true, - }); - } -}; - -// The `encoding` option is handled by Execa, not by `child_process.spawnSync()` -const normalizeSpawnSyncOptions = ({encoding, maxBuffer, ...options}) => ({...options, encoding: 'buffer', maxBuffer: getMaxBufferSync(maxBuffer)}); - -const getSyncResult = ({error, exitCode, signal, timedOut, isMaxBuffer, stdio, all, options, command, escapedCommand, startTime}) => error === undefined - ? makeSuccessResult({ - command, - escapedCommand, - stdio, - all, - ipcOutput: [], - options, - startTime, - }) - : makeError({ - error, - command, - escapedCommand, - timedOut, - isCanceled: false, - isGracefullyCanceled: false, - isMaxBuffer, - isForcefullyTerminated: false, - exitCode, - signal, - stdio, - all, - ipcOutput: [], - options, - startTime, - isSync: true, - }); - -// Like `[sub]process.once('message')` but promise-based -const getOneMessage = ({anyProcess, channel, isSubprocess, ipc}, {reference = true, filter} = {}) => { - validateIpcMethod({ - methodName: 'getOneMessage', - isSubprocess, - ipc, - isConnected: isConnected(anyProcess), - }); - - return getOneMessageAsync({ - anyProcess, - channel, - isSubprocess, - filter, - reference, - }); -}; - -const getOneMessageAsync = async ({anyProcess, channel, isSubprocess, filter, reference}) => { - addReference(channel, reference); - const ipcEmitter = getIpcEmitter(anyProcess, channel, isSubprocess); - const controller = new AbortController(); - try { - return await Promise.race([ - getMessage(ipcEmitter, filter, controller), - throwOnDisconnect(ipcEmitter, isSubprocess, controller), - throwOnStrictError(ipcEmitter, isSubprocess, controller), - ]); - } catch (error) { - disconnect(anyProcess); - throw error; - } finally { - controller.abort(); - removeReference(channel, reference); - } -}; - -const getMessage = async (ipcEmitter, filter, {signal}) => { - if (filter === undefined) { - const [message] = await once$2(ipcEmitter, 'message', {signal}); - return message; - } - - for await (const [message] of on(ipcEmitter, 'message', {signal})) { - if (filter(message)) { - return message; - } - } -}; - -const throwOnDisconnect = async (ipcEmitter, isSubprocess, {signal}) => { - await once$2(ipcEmitter, 'disconnect', {signal}); - throwOnEarlyDisconnect(isSubprocess); -}; - -const throwOnStrictError = async (ipcEmitter, isSubprocess, {signal}) => { - const [error] = await once$2(ipcEmitter, 'strict:error', {signal}); - throw getStrictResponseError(error, isSubprocess); -}; - -// Like `[sub]process.on('message')` but promise-based -const getEachMessage = ({anyProcess, channel, isSubprocess, ipc}, {reference = true} = {}) => loopOnMessages({ - anyProcess, - channel, - isSubprocess, - ipc, - shouldAwait: !isSubprocess, - reference, -}); - -// Same but used internally -const loopOnMessages = ({anyProcess, channel, isSubprocess, ipc, shouldAwait, reference}) => { - validateIpcMethod({ - methodName: 'getEachMessage', - isSubprocess, - ipc, - isConnected: isConnected(anyProcess), - }); - - addReference(channel, reference); - const ipcEmitter = getIpcEmitter(anyProcess, channel, isSubprocess); - const controller = new AbortController(); - const state = {}; - stopOnDisconnect(anyProcess, ipcEmitter, controller); - abortOnStrictError({ - ipcEmitter, - isSubprocess, - controller, - state, - }); - return iterateOnMessages({ - anyProcess, - channel, - ipcEmitter, - isSubprocess, - shouldAwait, - controller, - state, - reference, - }); -}; - -const stopOnDisconnect = async (anyProcess, ipcEmitter, controller) => { - try { - await once$2(ipcEmitter, 'disconnect', {signal: controller.signal}); - controller.abort(); - } catch {} -}; - -const abortOnStrictError = async ({ipcEmitter, isSubprocess, controller, state}) => { - try { - const [error] = await once$2(ipcEmitter, 'strict:error', {signal: controller.signal}); - state.error = getStrictResponseError(error, isSubprocess); - controller.abort(); - } catch {} -}; - -const iterateOnMessages = async function * ({anyProcess, channel, ipcEmitter, isSubprocess, shouldAwait, controller, state, reference}) { - try { - for await (const [message] of on(ipcEmitter, 'message', {signal: controller.signal})) { - throwIfStrictError(state); - yield message; - } - } catch { - throwIfStrictError(state); - } finally { - controller.abort(); - removeReference(channel, reference); - - if (!isSubprocess) { - disconnect(anyProcess); - } - - if (shouldAwait) { - await anyProcess; - } - } -}; - -const throwIfStrictError = ({error}) => { - if (error) { - throw error; - } -}; - -// Add promise-based IPC methods in current process -const addIpcMethods = (subprocess, {ipc}) => { - Object.assign(subprocess, getIpcMethods(subprocess, false, ipc)); -}; - -// Get promise-based IPC in the subprocess -const getIpcExport = () => { - const anyProcess = process$2; - const isSubprocess = true; - const ipc = process$2.channel !== undefined; - - return { - ...getIpcMethods(anyProcess, isSubprocess, ipc), - getCancelSignal: getCancelSignal.bind(undefined, { - anyProcess, - channel: anyProcess.channel, - isSubprocess, - ipc, - }), - }; -}; - -// Retrieve the `ipc` shared by both the current process and the subprocess -const getIpcMethods = (anyProcess, isSubprocess, ipc) => ({ - sendMessage: sendMessage.bind(undefined, { - anyProcess, - channel: anyProcess.channel, - isSubprocess, - ipc, - }), - getOneMessage: getOneMessage.bind(undefined, { - anyProcess, - channel: anyProcess.channel, - isSubprocess, - ipc, - }), - getEachMessage: getEachMessage.bind(undefined, { - anyProcess, - channel: anyProcess.channel, - isSubprocess, - ipc, - }), -}); - -// When the subprocess fails to spawn. -// We ensure the returned error is always both a promise and a subprocess. -const handleEarlyError = ({error, command, escapedCommand, fileDescriptors, options, startTime, verboseInfo}) => { - cleanupCustomStreams(fileDescriptors); - - const subprocess = new ChildProcess(); - createDummyStreams(subprocess, fileDescriptors); - Object.assign(subprocess, {readable: readable$1, writable, duplex}); - - const earlyError = makeEarlyError({ - error, - command, - escapedCommand, - fileDescriptors, - options, - startTime, - isSync: false, - }); - const promise = handleDummyPromise(earlyError, verboseInfo, options); - return {subprocess, promise}; -}; - -const createDummyStreams = (subprocess, fileDescriptors) => { - const stdin = createDummyStream(); - const stdout = createDummyStream(); - const stderr = createDummyStream(); - const extraStdio = Array.from({length: fileDescriptors.length - 3}, createDummyStream); - const all = createDummyStream(); - const stdio = [stdin, stdout, stderr, ...extraStdio]; - Object.assign(subprocess, { - stdin, - stdout, - stderr, - all, - stdio, - }); -}; - -const createDummyStream = () => { - const stream = new PassThrough(); - stream.end(); - return stream; -}; - -const readable$1 = () => new Readable({read() {}}); -const writable = () => new Writable({write() {}}); -const duplex = () => new Duplex({read() {}, write() {}}); - -const handleDummyPromise = async (error, verboseInfo, options) => handleResult(error, verboseInfo, options); - -// Handle `input`, `inputFile`, `stdin`, `stdout` and `stderr` options, before spawning, in async mode -const handleStdioAsync = (options, verboseInfo) => handleStdio(addPropertiesAsync, options, verboseInfo, false); - -const forbiddenIfAsync = ({type, optionName}) => { - throw new TypeError(`The \`${optionName}\` option cannot be ${TYPE_TO_MESSAGE[type]}.`); -}; - -// Create streams used internally for piping when using specific values for the `std*` options, in async mode. -// For example, `stdout: {file}` creates a file stream, which is piped from/to. -const addProperties = { - fileNumber: forbiddenIfAsync, - generator: generatorToStream, - asyncGenerator: generatorToStream, - nodeStream: ({value}) => ({stream: value}), - webTransform({value: {transform, writableObjectMode, readableObjectMode}}) { - const objectMode = writableObjectMode || readableObjectMode; - const stream = Duplex.fromWeb(transform, {objectMode}); - return {stream}; - }, - duplex: ({value: {transform}}) => ({stream: transform}), - native() {}, -}; - -const addPropertiesAsync = { - input: { - ...addProperties, - fileUrl: ({value}) => ({stream: createReadStream(value)}), - filePath: ({value: {file}}) => ({stream: createReadStream(file)}), - webStream: ({value}) => ({stream: Readable.fromWeb(value)}), - iterable: ({value}) => ({stream: Readable.from(value)}), - asyncIterable: ({value}) => ({stream: Readable.from(value)}), - string: ({value}) => ({stream: Readable.from(value)}), - uint8Array: ({value}) => ({stream: Readable.from(Buffer$1.from(value))}), - }, - output: { - ...addProperties, - fileUrl: ({value}) => ({stream: createWriteStream(value)}), - filePath: ({value: {file, append}}) => ({stream: createWriteStream(file, append ? {flags: 'a'} : {})}), - webStream: ({value}) => ({stream: Writable.fromWeb(value)}), - iterable: forbiddenIfAsync, - asyncIterable: forbiddenIfAsync, - string: forbiddenIfAsync, - uint8Array: forbiddenIfAsync, - }, -}; - -function mergeStreams(streams) { - if (!Array.isArray(streams)) { - throw new TypeError(`Expected an array, got \`${typeof streams}\`.`); - } - - for (const stream of streams) { - validateStream(stream); - } - - const objectMode = streams.some(({readableObjectMode}) => readableObjectMode); - const highWaterMark = getHighWaterMark(streams, objectMode); - const passThroughStream = new MergedStream({ - objectMode, - writableHighWaterMark: highWaterMark, - readableHighWaterMark: highWaterMark, - }); - - for (const stream of streams) { - passThroughStream.add(stream); - } - - return passThroughStream; -} - -const getHighWaterMark = (streams, objectMode) => { - if (streams.length === 0) { - return getDefaultHighWaterMark(objectMode); - } - - const highWaterMarks = streams - .filter(({readableObjectMode}) => readableObjectMode === objectMode) - .map(({readableHighWaterMark}) => readableHighWaterMark); - return Math.max(...highWaterMarks); -}; - -class MergedStream extends PassThrough { - #streams = new Set([]); - #ended = new Set([]); - #aborted = new Set([]); - #onFinished; - #unpipeEvent = Symbol('unpipe'); - #streamPromises = new WeakMap(); - - add(stream) { - validateStream(stream); - - if (this.#streams.has(stream)) { - return; - } - - this.#streams.add(stream); - - this.#onFinished ??= onMergedStreamFinished(this, this.#streams, this.#unpipeEvent); - const streamPromise = endWhenStreamsDone({ - passThroughStream: this, - stream, - streams: this.#streams, - ended: this.#ended, - aborted: this.#aborted, - onFinished: this.#onFinished, - unpipeEvent: this.#unpipeEvent, - }); - this.#streamPromises.set(stream, streamPromise); - - stream.pipe(this, {end: false}); - } - - async remove(stream) { - validateStream(stream); - - if (!this.#streams.has(stream)) { - return false; - } - - const streamPromise = this.#streamPromises.get(stream); - if (streamPromise === undefined) { - return false; - } - - this.#streamPromises.delete(stream); - - stream.unpipe(this); - await streamPromise; - return true; - } -} - -const onMergedStreamFinished = async (passThroughStream, streams, unpipeEvent) => { - updateMaxListeners(passThroughStream, PASSTHROUGH_LISTENERS_COUNT); - const controller = new AbortController(); - - try { - await Promise.race([ - onMergedStreamEnd(passThroughStream, controller), - onInputStreamsUnpipe(passThroughStream, streams, unpipeEvent, controller), - ]); - } finally { - controller.abort(); - updateMaxListeners(passThroughStream, -PASSTHROUGH_LISTENERS_COUNT); - } -}; - -const onMergedStreamEnd = async (passThroughStream, {signal}) => { - try { - await finished(passThroughStream, {signal, cleanup: true}); - } catch (error) { - errorOrAbortStream(passThroughStream, error); - throw error; - } -}; - -const onInputStreamsUnpipe = async (passThroughStream, streams, unpipeEvent, {signal}) => { - for await (const [unpipedStream] of on(passThroughStream, 'unpipe', {signal})) { - if (streams.has(unpipedStream)) { - unpipedStream.emit(unpipeEvent); - } - } -}; - -const validateStream = stream => { - if (typeof stream?.pipe !== 'function') { - throw new TypeError(`Expected a readable stream, got: \`${typeof stream}\`.`); - } -}; - -const endWhenStreamsDone = async ({passThroughStream, stream, streams, ended, aborted, onFinished, unpipeEvent}) => { - updateMaxListeners(passThroughStream, PASSTHROUGH_LISTENERS_PER_STREAM); - const controller = new AbortController(); - - try { - await Promise.race([ - afterMergedStreamFinished(onFinished, stream, controller), - onInputStreamEnd({ - passThroughStream, - stream, - streams, - ended, - aborted, - controller, - }), - onInputStreamUnpipe({ - stream, - streams, - ended, - aborted, - unpipeEvent, - controller, - }), - ]); - } finally { - controller.abort(); - updateMaxListeners(passThroughStream, -PASSTHROUGH_LISTENERS_PER_STREAM); - } - - if (streams.size > 0 && streams.size === ended.size + aborted.size) { - if (ended.size === 0 && aborted.size > 0) { - abortStream(passThroughStream); - } else { - endStream(passThroughStream); - } - } -}; - -const afterMergedStreamFinished = async (onFinished, stream, {signal}) => { - try { - await onFinished; - if (!signal.aborted) { - abortStream(stream); - } - } catch (error) { - if (!signal.aborted) { - errorOrAbortStream(stream, error); - } - } -}; - -const onInputStreamEnd = async ({passThroughStream, stream, streams, ended, aborted, controller: {signal}}) => { - try { - await finished(stream, { - signal, - cleanup: true, - readable: true, - writable: false, - }); - if (streams.has(stream)) { - ended.add(stream); - } - } catch (error) { - if (signal.aborted || !streams.has(stream)) { - return; - } - - if (isAbortError(error)) { - aborted.add(stream); - } else { - errorStream(passThroughStream, error); - } - } -}; - -const onInputStreamUnpipe = async ({stream, streams, ended, aborted, unpipeEvent, controller: {signal}}) => { - await once$2(stream, unpipeEvent, {signal}); - - if (!stream.readable) { - return once$2(signal, 'abort', {signal}); - } - - streams.delete(stream); - ended.delete(stream); - aborted.delete(stream); -}; - -const endStream = stream => { - if (stream.writable) { - stream.end(); - } -}; - -const errorOrAbortStream = (stream, error) => { - if (isAbortError(error)) { - abortStream(stream); - } else { - errorStream(stream, error); - } -}; - -// This is the error thrown by `finished()` on `stream.destroy()` -const isAbortError = error => error?.code === 'ERR_STREAM_PREMATURE_CLOSE'; - -const abortStream = stream => { - if (stream.readable || stream.writable) { - stream.destroy(); - } -}; - -// `stream.destroy(error)` crashes the process with `uncaughtException` if no `error` event listener exists on `stream`. -// We take care of error handling on user behalf, so we do not want this to happen. -const errorStream = (stream, error) => { - if (!stream.destroyed) { - stream.once('error', noop); - stream.destroy(error); - } -}; - -const noop = () => {}; - -const updateMaxListeners = (passThroughStream, increment) => { - const maxListeners = passThroughStream.getMaxListeners(); - if (maxListeners !== 0 && maxListeners !== Number.POSITIVE_INFINITY) { - passThroughStream.setMaxListeners(maxListeners + increment); - } -}; - -// Number of times `passThroughStream.on()` is called regardless of streams: -// - once due to `finished(passThroughStream)` -// - once due to `on(passThroughStream)` -const PASSTHROUGH_LISTENERS_COUNT = 2; - -// Number of times `passThroughStream.on()` is called per stream: -// - once due to `stream.pipe(passThroughStream)` -const PASSTHROUGH_LISTENERS_PER_STREAM = 1; - -// Similar to `Stream.pipeline(source, destination)`, but does not destroy standard streams -const pipeStreams = (source, destination) => { - source.pipe(destination); - onSourceFinish(source, destination); - onDestinationFinish(source, destination); -}; - -// `source.pipe(destination)` makes `destination` end when `source` ends. -// But it does not propagate aborts or errors. This function does it. -const onSourceFinish = async (source, destination) => { - if (isStandardStream(source) || isStandardStream(destination)) { - return; - } - - try { - await finished(source, {cleanup: true, readable: true, writable: false}); - } catch {} - - endDestinationStream(destination); -}; - -const endDestinationStream = destination => { - if (destination.writable) { - destination.end(); - } -}; - -// We do the same thing in the other direction as well. -const onDestinationFinish = async (source, destination) => { - if (isStandardStream(source) || isStandardStream(destination)) { - return; - } - - try { - await finished(destination, {cleanup: true, readable: false, writable: true}); - } catch {} - - abortSourceStream(source); -}; - -const abortSourceStream = source => { - if (source.readable) { - source.destroy(); - } -}; - -// Handle `input`, `inputFile`, `stdin`, `stdout` and `stderr` options, after spawning, in async mode -// When multiple input streams are used, we merge them to ensure the output stream ends only once each input stream has ended -const pipeOutputAsync = (subprocess, fileDescriptors, controller) => { - const pipeGroups = new Map(); - - for (const [fdNumber, {stdioItems, direction}] of Object.entries(fileDescriptors)) { - for (const {stream} of stdioItems.filter(({type}) => TRANSFORM_TYPES.has(type))) { - pipeTransform(subprocess, stream, direction, fdNumber); - } - - for (const {stream} of stdioItems.filter(({type}) => !TRANSFORM_TYPES.has(type))) { - pipeStdioItem({ - subprocess, - stream, - direction, - fdNumber, - pipeGroups, - controller, - }); - } - } - - for (const [outputStream, inputStreams] of pipeGroups.entries()) { - const inputStream = inputStreams.length === 1 ? inputStreams[0] : mergeStreams(inputStreams); - pipeStreams(inputStream, outputStream); - } -}; - -// When using transforms, `subprocess.stdin|stdout|stderr|stdio` is directly mutated -const pipeTransform = (subprocess, stream, direction, fdNumber) => { - if (direction === 'output') { - pipeStreams(subprocess.stdio[fdNumber], stream); - } else { - pipeStreams(stream, subprocess.stdio[fdNumber]); - } - - const streamProperty = SUBPROCESS_STREAM_PROPERTIES[fdNumber]; - if (streamProperty !== undefined) { - subprocess[streamProperty] = stream; - } - - subprocess.stdio[fdNumber] = stream; -}; - -const SUBPROCESS_STREAM_PROPERTIES = ['stdin', 'stdout', 'stderr']; - -// Most `std*` option values involve piping `subprocess.std*` to a stream. -// The stream is either passed by the user or created internally. -const pipeStdioItem = ({subprocess, stream, direction, fdNumber, pipeGroups, controller}) => { - if (stream === undefined) { - return; - } - - setStandardStreamMaxListeners(stream, controller); - - const [inputStream, outputStream] = direction === 'output' - ? [stream, subprocess.stdio[fdNumber]] - : [subprocess.stdio[fdNumber], stream]; - const outputStreams = pipeGroups.get(inputStream) ?? []; - pipeGroups.set(inputStream, [...outputStreams, outputStream]); -}; - -// Multiple subprocesses might be piping from/to `process.std*` at the same time. -// This is not necessarily an error and should not print a `maxListeners` warning. -const setStandardStreamMaxListeners = (stream, {signal}) => { - if (isStandardStream(stream)) { - incrementMaxListeners(stream, MAX_LISTENERS_INCREMENT, signal); - } -}; - -// `source.pipe(destination)` adds at most 1 listener for each event. -// If `stdin` option is an array, the values might be combined with `merge-streams`. -// That library also listens for `source` end, which adds 1 more listener. -const MAX_LISTENERS_INCREMENT = 2; - -/** - * This is not the set of all possible signals. - * - * It IS, however, the set of all signals that trigger - * an exit on either Linux or BSD systems. Linux is a - * superset of the signal names supported on BSD, and - * the unknown signals just fail to register, so we can - * catch that easily enough. - * - * Windows signals are a different set, since there are - * signals that terminate Windows processes, but don't - * terminate (or don't even exist) on Posix systems. - * - * Don't bother with SIGKILL. It's uncatchable, which - * means that we can't fire any callbacks anyway. - * - * If a user does happen to register a handler on a non- - * fatal signal like SIGWINCH or something, and then - * exit, it'll end up firing `process.emit('exit')`, so - * the handler will be fired anyway. - * - * SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised - * artificially, inherently leave the process in a - * state from which it is not safe to try and enter JS - * listeners. - */ -const signals = []; -signals.push('SIGHUP', 'SIGINT', 'SIGTERM'); -if (process.platform !== 'win32') { - signals.push('SIGALRM', 'SIGABRT', 'SIGVTALRM', 'SIGXCPU', 'SIGXFSZ', 'SIGUSR2', 'SIGTRAP', 'SIGSYS', 'SIGQUIT', 'SIGIOT' - // should detect profiler and enable/disable accordingly. - // see #21 - // 'SIGPROF' - ); -} -if (process.platform === 'linux') { - signals.push('SIGIO', 'SIGPOLL', 'SIGPWR', 'SIGSTKFLT'); -} - -// Note: since nyc uses this module to output coverage, any lines -// that are in the direct sync flow of nyc's outputCoverage are -// ignored, since we can never get coverage for them. -// grab a reference to node's real process object right away -const processOk = (process) => !!process && - typeof process === 'object' && - typeof process.removeListener === 'function' && - typeof process.emit === 'function' && - typeof process.reallyExit === 'function' && - typeof process.listeners === 'function' && - typeof process.kill === 'function' && - typeof process.pid === 'number' && - typeof process.on === 'function'; -const kExitEmitter = Symbol.for('signal-exit emitter'); -const global$3 = globalThis; -const ObjectDefineProperty = Object.defineProperty.bind(Object); -// teeny special purpose ee -class Emitter { - emitted = { - afterExit: false, - exit: false, - }; - listeners = { - afterExit: [], - exit: [], - }; - count = 0; - id = Math.random(); - constructor() { - if (global$3[kExitEmitter]) { - return global$3[kExitEmitter]; - } - ObjectDefineProperty(global$3, kExitEmitter, { - value: this, - writable: false, - enumerable: false, - configurable: false, - }); - } - on(ev, fn) { - this.listeners[ev].push(fn); - } - removeListener(ev, fn) { - const list = this.listeners[ev]; - const i = list.indexOf(fn); - /* c8 ignore start */ - if (i === -1) { - return; - } - /* c8 ignore stop */ - if (i === 0 && list.length === 1) { - list.length = 0; - } - else { - list.splice(i, 1); - } - } - emit(ev, code, signal) { - if (this.emitted[ev]) { - return false; - } - this.emitted[ev] = true; - let ret = false; - for (const fn of this.listeners[ev]) { - ret = fn(code, signal) === true || ret; - } - if (ev === 'exit') { - ret = this.emit('afterExit', code, signal) || ret; - } - return ret; - } -} -class SignalExitBase { -} -const signalExitWrap = (handler) => { - return { - onExit(cb, opts) { - return handler.onExit(cb, opts); - }, - load() { - return handler.load(); - }, - unload() { - return handler.unload(); - }, - }; -}; -class SignalExitFallback extends SignalExitBase { - onExit() { - return () => { }; - } - load() { } - unload() { } -} -class SignalExit extends SignalExitBase { - // "SIGHUP" throws an `ENOSYS` error on Windows, - // so use a supported signal instead - /* c8 ignore start */ - #hupSig = process$1.platform === 'win32' ? 'SIGINT' : 'SIGHUP'; - /* c8 ignore stop */ - #emitter = new Emitter(); - #process; - #originalProcessEmit; - #originalProcessReallyExit; - #sigListeners = {}; - #loaded = false; - constructor(process) { - super(); - this.#process = process; - // { : , ... } - this.#sigListeners = {}; - for (const sig of signals) { - this.#sigListeners[sig] = () => { - // If there are no other listeners, an exit is coming! - // Simplest way: remove us and then re-send the signal. - // We know that this will kill the process, so we can - // safely emit now. - const listeners = this.#process.listeners(sig); - let { count } = this.#emitter; - // This is a workaround for the fact that signal-exit v3 and signal - // exit v4 are not aware of each other, and each will attempt to let - // the other handle it, so neither of them do. To correct this, we - // detect if we're the only handler *except* for previous versions - // of signal-exit, and increment by the count of listeners it has - // created. - /* c8 ignore start */ - const p = process; - if (typeof p.__signal_exit_emitter__ === 'object' && - typeof p.__signal_exit_emitter__.count === 'number') { - count += p.__signal_exit_emitter__.count; - } - /* c8 ignore stop */ - if (listeners.length === count) { - this.unload(); - const ret = this.#emitter.emit('exit', null, sig); - /* c8 ignore start */ - const s = sig === 'SIGHUP' ? this.#hupSig : sig; - if (!ret) - process.kill(process.pid, s); - /* c8 ignore stop */ - } - }; - } - this.#originalProcessReallyExit = process.reallyExit; - this.#originalProcessEmit = process.emit; - } - onExit(cb, opts) { - /* c8 ignore start */ - if (!processOk(this.#process)) { - return () => { }; - } - /* c8 ignore stop */ - if (this.#loaded === false) { - this.load(); - } - const ev = opts?.alwaysLast ? 'afterExit' : 'exit'; - this.#emitter.on(ev, cb); - return () => { - this.#emitter.removeListener(ev, cb); - if (this.#emitter.listeners['exit'].length === 0 && - this.#emitter.listeners['afterExit'].length === 0) { - this.unload(); - } - }; - } - load() { - if (this.#loaded) { - return; - } - this.#loaded = true; - // This is the number of onSignalExit's that are in play. - // It's important so that we can count the correct number of - // listeners on signals, and don't wait for the other one to - // handle it instead of us. - this.#emitter.count += 1; - for (const sig of signals) { - try { - const fn = this.#sigListeners[sig]; - if (fn) - this.#process.on(sig, fn); - } - catch (_) { } - } - this.#process.emit = (ev, ...a) => { - return this.#processEmit(ev, ...a); - }; - this.#process.reallyExit = (code) => { - return this.#processReallyExit(code); - }; - } - unload() { - if (!this.#loaded) { - return; - } - this.#loaded = false; - signals.forEach(sig => { - const listener = this.#sigListeners[sig]; - /* c8 ignore start */ - if (!listener) { - throw new Error('Listener not defined for signal: ' + sig); - } - /* c8 ignore stop */ - try { - this.#process.removeListener(sig, listener); - /* c8 ignore start */ - } - catch (_) { } - /* c8 ignore stop */ - }); - this.#process.emit = this.#originalProcessEmit; - this.#process.reallyExit = this.#originalProcessReallyExit; - this.#emitter.count -= 1; - } - #processReallyExit(code) { - /* c8 ignore start */ - if (!processOk(this.#process)) { - return 0; - } - this.#process.exitCode = code || 0; - /* c8 ignore stop */ - this.#emitter.emit('exit', this.#process.exitCode, null); - return this.#originalProcessReallyExit.call(this.#process, this.#process.exitCode); - } - #processEmit(ev, ...args) { - const og = this.#originalProcessEmit; - if (ev === 'exit' && processOk(this.#process)) { - if (typeof args[0] === 'number') { - this.#process.exitCode = args[0]; - /* c8 ignore start */ - } - /* c8 ignore start */ - const ret = og.call(this.#process, ev, ...args); - /* c8 ignore start */ - this.#emitter.emit('exit', this.#process.exitCode, null); - /* c8 ignore stop */ - return ret; - } - else { - return og.call(this.#process, ev, ...args); - } - } -} -const process$1 = globalThis.process; -// wrap so that we call the method on the actual handler, without -// exporting it directly. -const { -/** - * Called when the process is exiting, whether via signal, explicit - * exit, or running out of stuff to do. - * - * If the global process object is not suitable for instrumentation, - * then this will be a no-op. - * - * Returns a function that may be used to unload signal-exit. - */ -onExit} = signalExitWrap(processOk(process$1) ? new SignalExit(process$1) : new SignalExitFallback()); - -// If the `cleanup` option is used, call `subprocess.kill()` when the parent process exits -const cleanupOnExit = (subprocess, {cleanup, detached}, {signal}) => { - if (!cleanup || detached) { - return; - } - - const removeExitHandler = onExit(() => { - subprocess.kill(); - }); - addAbortListener(signal, () => { - removeExitHandler(); - }); -}; - -// Normalize and validate arguments passed to `source.pipe(destination)` -const normalizePipeArguments = ({source, sourcePromise, boundOptions, createNested}, ...pipeArguments) => { - const startTime = getStartTime(); - const { - destination, - destinationStream, - destinationError, - from, - unpipeSignal, - } = getDestinationStream(boundOptions, createNested, pipeArguments); - const {sourceStream, sourceError} = getSourceStream(source, from); - const {options: sourceOptions, fileDescriptors} = SUBPROCESS_OPTIONS.get(source); - return { - sourcePromise, - sourceStream, - sourceOptions, - sourceError, - destination, - destinationStream, - destinationError, - unpipeSignal, - fileDescriptors, - startTime, - }; -}; - -const getDestinationStream = (boundOptions, createNested, pipeArguments) => { - try { - const { - destination, - pipeOptions: {from, to, unpipeSignal} = {}, - } = getDestination(boundOptions, createNested, ...pipeArguments); - const destinationStream = getToStream(destination, to); - return { - destination, - destinationStream, - from, - unpipeSignal, - }; - } catch (error) { - return {destinationError: error}; - } -}; - -// Piping subprocesses can use three syntaxes: -// - source.pipe('command', commandArguments, pipeOptionsOrDestinationOptions) -// - source.pipe`command commandArgument` or source.pipe(pipeOptionsOrDestinationOptions)`command commandArgument` -// - source.pipe(execa(...), pipeOptions) -const getDestination = (boundOptions, createNested, firstArgument, ...pipeArguments) => { - if (Array.isArray(firstArgument)) { - const destination = createNested(mapDestinationArguments, boundOptions)(firstArgument, ...pipeArguments); - return {destination, pipeOptions: boundOptions}; - } - - if (typeof firstArgument === 'string' || firstArgument instanceof URL || isDenoExecPath(firstArgument)) { - if (Object.keys(boundOptions).length > 0) { - throw new TypeError('Please use .pipe("file", ..., options) or .pipe(execa("file", ..., options)) instead of .pipe(options)("file", ...).'); - } - - const [rawFile, rawArguments, rawOptions] = normalizeParameters(firstArgument, ...pipeArguments); - const destination = createNested(mapDestinationArguments)(rawFile, rawArguments, rawOptions); - return {destination, pipeOptions: rawOptions}; - } - - if (SUBPROCESS_OPTIONS.has(firstArgument)) { - if (Object.keys(boundOptions).length > 0) { - throw new TypeError('Please use .pipe(options)`command` or .pipe($(options)`command`) instead of .pipe(options)($`command`).'); - } - - return {destination: firstArgument, pipeOptions: pipeArguments[0]}; - } - - throw new TypeError(`The first argument must be a template string, an options object, or an Execa subprocess: ${firstArgument}`); -}; - -// Force `stdin: 'pipe'` with the destination subprocess -const mapDestinationArguments = ({options}) => ({options: {...options, stdin: 'pipe', piped: true}}); - -const getSourceStream = (source, from) => { - try { - const sourceStream = getFromStream(source, from); - return {sourceStream}; - } catch (error) { - return {sourceError: error}; - } -}; - -// When passing invalid arguments to `source.pipe()`, throw asynchronously. -// We also abort both subprocesses. -const handlePipeArgumentsError = ({ - sourceStream, - sourceError, - destinationStream, - destinationError, - fileDescriptors, - sourceOptions, - startTime, -}) => { - const error = getPipeArgumentsError({ - sourceStream, - sourceError, - destinationStream, - destinationError, - }); - if (error !== undefined) { - throw createNonCommandError({ - error, - fileDescriptors, - sourceOptions, - startTime, - }); - } -}; - -const getPipeArgumentsError = ({sourceStream, sourceError, destinationStream, destinationError}) => { - if (sourceError !== undefined && destinationError !== undefined) { - return destinationError; - } - - if (destinationError !== undefined) { - abortSourceStream(sourceStream); - return destinationError; - } - - if (sourceError !== undefined) { - endDestinationStream(destinationStream); - return sourceError; - } -}; - -// Specific error return value when passing invalid arguments to `subprocess.pipe()` or when using `unpipeSignal` -const createNonCommandError = ({error, fileDescriptors, sourceOptions, startTime}) => makeEarlyError({ - error, - command: PIPE_COMMAND_MESSAGE, - escapedCommand: PIPE_COMMAND_MESSAGE, - fileDescriptors, - options: sourceOptions, - startTime, - isSync: false, -}); - -const PIPE_COMMAND_MESSAGE = 'source.pipe(destination)'; - -// Like Bash, we await both subprocesses. This is unlike some other shells which only await the destination subprocess. -// Like Bash with the `pipefail` option, if either subprocess fails, the whole pipe fails. -// Like Bash, if both subprocesses fail, we return the failure of the destination. -// This ensures both subprocesses' errors are present, using `error.pipedFrom`. -const waitForBothSubprocesses = async subprocessPromises => { - const [ - {status: sourceStatus, reason: sourceReason, value: sourceResult = sourceReason}, - {status: destinationStatus, reason: destinationReason, value: destinationResult = destinationReason}, - ] = await subprocessPromises; - - if (!destinationResult.pipedFrom.includes(sourceResult)) { - destinationResult.pipedFrom.push(sourceResult); - } - - if (destinationStatus === 'rejected') { - throw destinationResult; - } - - if (sourceStatus === 'rejected') { - throw sourceResult; - } - - return destinationResult; -}; - -// The piping behavior is like Bash. -// In particular, when one subprocess exits, the other is not terminated by a signal. -// Instead, its stdout (for the source) or stdin (for the destination) closes. -// If the subprocess uses it, it will make it error with SIGPIPE or EPIPE (for the source) or end (for the destination). -// If it does not use it, it will continue running. -// This allows for subprocesses to gracefully exit and lower the coupling between subprocesses. -const pipeSubprocessStream = (sourceStream, destinationStream, maxListenersController) => { - const mergedStream = MERGED_STREAMS.has(destinationStream) - ? pipeMoreSubprocessStream(sourceStream, destinationStream) - : pipeFirstSubprocessStream(sourceStream, destinationStream); - incrementMaxListeners(sourceStream, SOURCE_LISTENERS_PER_PIPE, maxListenersController.signal); - incrementMaxListeners(destinationStream, DESTINATION_LISTENERS_PER_PIPE, maxListenersController.signal); - cleanupMergedStreamsMap(destinationStream); - return mergedStream; -}; - -// We use `merge-streams` to allow for multiple sources to pipe to the same destination. -const pipeFirstSubprocessStream = (sourceStream, destinationStream) => { - const mergedStream = mergeStreams([sourceStream]); - pipeStreams(mergedStream, destinationStream); - MERGED_STREAMS.set(destinationStream, mergedStream); - return mergedStream; -}; - -const pipeMoreSubprocessStream = (sourceStream, destinationStream) => { - const mergedStream = MERGED_STREAMS.get(destinationStream); - mergedStream.add(sourceStream); - return mergedStream; -}; - -const cleanupMergedStreamsMap = async destinationStream => { - try { - await finished(destinationStream, {cleanup: true, readable: false, writable: true}); - } catch {} - - MERGED_STREAMS.delete(destinationStream); -}; - -const MERGED_STREAMS = new WeakMap(); - -// Number of listeners set up on `sourceStream` by each `sourceStream.pipe(destinationStream)` -// Those are added by `merge-streams` -const SOURCE_LISTENERS_PER_PIPE = 2; -// Number of listeners set up on `destinationStream` by each `sourceStream.pipe(destinationStream)` -// Those are added by `finished()` in `cleanupMergedStreamsMap()` -const DESTINATION_LISTENERS_PER_PIPE = 1; - -// When passing an `unpipeSignal` option, abort piping when the signal is aborted. -// However, do not terminate the subprocesses. -const unpipeOnAbort = (unpipeSignal, unpipeContext) => unpipeSignal === undefined - ? [] - : [unpipeOnSignalAbort(unpipeSignal, unpipeContext)]; - -const unpipeOnSignalAbort = async (unpipeSignal, {sourceStream, mergedStream, fileDescriptors, sourceOptions, startTime}) => { - await aborted(unpipeSignal, sourceStream); - await mergedStream.remove(sourceStream); - const error = new Error('Pipe canceled by `unpipeSignal` option.'); - throw createNonCommandError({ - error, - fileDescriptors, - sourceOptions, - startTime, - }); -}; - -// Pipe a subprocess' `stdout`/`stderr`/`stdio` into another subprocess' `stdin` -const pipeToSubprocess = (sourceInfo, ...pipeArguments) => { - if (isPlainObject(pipeArguments[0])) { - return pipeToSubprocess.bind(undefined, { - ...sourceInfo, - boundOptions: {...sourceInfo.boundOptions, ...pipeArguments[0]}, - }); - } - - const {destination, ...normalizedInfo} = normalizePipeArguments(sourceInfo, ...pipeArguments); - const promise = handlePipePromise({...normalizedInfo, destination}); - promise.pipe = pipeToSubprocess.bind(undefined, { - ...sourceInfo, - source: destination, - sourcePromise: promise, - boundOptions: {}, - }); - return promise; -}; - -// Asynchronous logic when piping subprocesses -const handlePipePromise = async ({ - sourcePromise, - sourceStream, - sourceOptions, - sourceError, - destination, - destinationStream, - destinationError, - unpipeSignal, - fileDescriptors, - startTime, -}) => { - const subprocessPromises = getSubprocessPromises(sourcePromise, destination); - handlePipeArgumentsError({ - sourceStream, - sourceError, - destinationStream, - destinationError, - fileDescriptors, - sourceOptions, - startTime, - }); - const maxListenersController = new AbortController(); - try { - const mergedStream = pipeSubprocessStream(sourceStream, destinationStream, maxListenersController); - return await Promise.race([ - waitForBothSubprocesses(subprocessPromises), - ...unpipeOnAbort(unpipeSignal, { - sourceStream, - mergedStream, - sourceOptions, - fileDescriptors, - startTime, - }), - ]); - } finally { - maxListenersController.abort(); - } -}; - -// `.pipe()` awaits the subprocess promises. -// When invalid arguments are passed to `.pipe()`, we throw an error, which prevents awaiting them. -// We need to ensure this does not create unhandled rejections. -const getSubprocessPromises = (sourcePromise, destination) => Promise.allSettled([sourcePromise, destination]); - -// Iterate over lines of `subprocess.stdout`, used by `subprocess.readable|duplex|iterable()` -const iterateOnSubprocessStream = ({subprocessStdout, subprocess, binary, shouldEncode, encoding, preserveNewlines}) => { - const controller = new AbortController(); - stopReadingOnExit(subprocess, controller); - return iterateOnStream({ - stream: subprocessStdout, - controller, - binary, - shouldEncode: !subprocessStdout.readableObjectMode && shouldEncode, - encoding, - shouldSplit: !subprocessStdout.readableObjectMode, - preserveNewlines, - }); -}; - -const stopReadingOnExit = async (subprocess, controller) => { - try { - await subprocess; - } catch {} finally { - controller.abort(); - } -}; - -// Iterate over lines of `subprocess.stdout`, used by `result.stdout` and the `verbose: 'full'` option. -// Applies the `lines` and `encoding` options. -const iterateForResult = ({stream, onStreamEnd, lines, encoding, stripFinalNewline, allMixed}) => { - const controller = new AbortController(); - stopReadingOnStreamEnd(onStreamEnd, controller, stream); - const objectMode = stream.readableObjectMode && !allMixed; - return iterateOnStream({ - stream, - controller, - binary: encoding === 'buffer', - shouldEncode: !objectMode, - encoding, - shouldSplit: !objectMode && lines, - preserveNewlines: !stripFinalNewline, - }); -}; - -const stopReadingOnStreamEnd = async (onStreamEnd, controller, stream) => { - try { - await onStreamEnd; - } catch { - stream.destroy(); - } finally { - controller.abort(); - } -}; - -const iterateOnStream = ({stream, controller, binary, shouldEncode, encoding, shouldSplit, preserveNewlines}) => { - const onStdoutChunk = on(stream, 'data', { - signal: controller.signal, - highWaterMark: HIGH_WATER_MARK, - // Backward compatibility with older name for this option - // See https://github.com/nodejs/node/pull/52080#discussion_r1525227861 - // @todo Remove after removing support for Node 21 - highWatermark: HIGH_WATER_MARK, - }); - return iterateOnData({ - onStdoutChunk, - controller, - binary, - shouldEncode, - encoding, - shouldSplit, - preserveNewlines, - }); -}; - -const DEFAULT_OBJECT_HIGH_WATER_MARK = getDefaultHighWaterMark(true); - -// The `highWaterMark` of `events.on()` is measured in number of events, not in bytes. -// Not knowing the average amount of bytes per `data` event, we use the same heuristic as streams in objectMode, since they have the same issue. -// Therefore, we use the value of `getDefaultHighWaterMark(true)`. -// Note: this option does not exist on Node 18, but this is ok since the logic works without it. It just consumes more memory. -const HIGH_WATER_MARK = DEFAULT_OBJECT_HIGH_WATER_MARK; - -const iterateOnData = async function * ({onStdoutChunk, controller, binary, shouldEncode, encoding, shouldSplit, preserveNewlines}) { - const generators = getGenerators({ - binary, - shouldEncode, - encoding, - shouldSplit, - preserveNewlines, - }); - - try { - for await (const [chunk] of onStdoutChunk) { - yield * transformChunkSync(chunk, generators, 0); - } - } catch (error) { - if (!controller.signal.aborted) { - throw error; - } - } finally { - yield * finalChunksSync(generators); - } -}; - -const getGenerators = ({binary, shouldEncode, encoding, shouldSplit, preserveNewlines}) => [ - getEncodingTransformGenerator(binary, encoding, !shouldEncode), - getSplitLinesGenerator(binary, preserveNewlines, !shouldSplit, {}), -].filter(Boolean); - -// Retrieve `result.stdout|stderr|all|stdio[*]` -const getStreamOutput = async ({stream, onStreamEnd, fdNumber, encoding, buffer, maxBuffer, lines, allMixed, stripFinalNewline, verboseInfo, streamInfo}) => { - const logPromise = logOutputAsync({ - stream, - onStreamEnd, - fdNumber, - encoding, - allMixed, - verboseInfo, - streamInfo, - }); - - if (!buffer) { - await Promise.all([resumeStream(stream), logPromise]); - return; - } - - const stripFinalNewlineValue = getStripFinalNewline(stripFinalNewline, fdNumber); - const iterable = iterateForResult({ - stream, - onStreamEnd, - lines, - encoding, - stripFinalNewline: stripFinalNewlineValue, - allMixed, - }); - const [output] = await Promise.all([ - getStreamContents({ - stream, - iterable, - fdNumber, - encoding, - maxBuffer, - lines, - }), - logPromise, - ]); - return output; -}; - -const logOutputAsync = async ({stream, onStreamEnd, fdNumber, encoding, allMixed, verboseInfo, streamInfo: {fileDescriptors}}) => { - if (!shouldLogOutput({ - stdioItems: fileDescriptors[fdNumber]?.stdioItems, - encoding, - verboseInfo, - fdNumber, - })) { - return; - } - - const linesIterable = iterateForResult({ - stream, - onStreamEnd, - lines: true, - encoding, - stripFinalNewline: true, - allMixed, - }); - await logLines(linesIterable, stream, fdNumber, verboseInfo); -}; - -// When using `buffer: false`, users need to read `subprocess.stdout|stderr|all` right away -// See https://github.com/sindresorhus/execa/issues/730 and https://github.com/sindresorhus/execa/pull/729#discussion_r1465496310 -const resumeStream = async stream => { - await setImmediate$1(); - if (stream.readableFlowing === null) { - stream.resume(); - } -}; - -const getStreamContents = async ({stream, stream: {readableObjectMode}, iterable, fdNumber, encoding, maxBuffer, lines}) => { - try { - if (readableObjectMode || lines) { - return await getStreamAsArray(iterable, {maxBuffer}); - } - - if (encoding === 'buffer') { - return new Uint8Array(await getStreamAsArrayBuffer(iterable, {maxBuffer})); - } - - return await getStreamAsString(iterable, {maxBuffer}); - } catch (error) { - return handleBufferedData(handleMaxBuffer({ - error, - stream, - readableObjectMode, - lines, - encoding, - fdNumber, - })); - } -}; - -// On failure, `result.stdout|stderr|all` should contain the currently buffered stream -// They are automatically closed and flushed by Node.js when the subprocess exits -// When `buffer` is `false`, `streamPromise` is `undefined` and there is no buffered data to retrieve -const getBufferedData = async streamPromise => { - try { - return await streamPromise; - } catch (error) { - return handleBufferedData(error); - } -}; - -// Ensure we are returning Uint8Arrays when using `encoding: 'buffer'` -const handleBufferedData = ({bufferedData}) => isArrayBuffer(bufferedData) - ? new Uint8Array(bufferedData) - : bufferedData; - -// Wraps `finished(stream)` to handle the following case: -// - When the subprocess exits, Node.js automatically calls `subprocess.stdin.destroy()`, which we need to ignore. -// - However, we still need to throw if `subprocess.stdin.destroy()` is called before subprocess exit. -const waitForStream = async (stream, fdNumber, streamInfo, {isSameDirection, stopOnExit = false} = {}) => { - const state = handleStdinDestroy(stream, streamInfo); - const abortController = new AbortController(); - try { - await Promise.race([ - ...(stopOnExit ? [streamInfo.exitPromise] : []), - finished(stream, {cleanup: true, signal: abortController.signal}), - ]); - } catch (error) { - if (!state.stdinCleanedUp) { - handleStreamError(error, fdNumber, streamInfo, isSameDirection); - } - } finally { - abortController.abort(); - } -}; - -// If `subprocess.stdin` is destroyed before being fully written to, it is considered aborted and should throw an error. -// This can happen for example when user called `subprocess.stdin.destroy()` before `subprocess.stdin.end()`. -// However, Node.js calls `subprocess.stdin.destroy()` on exit for cleanup purposes. -// https://github.com/nodejs/node/blob/0b4cdb4b42956cbd7019058e409e06700a199e11/lib/internal/child_process.js#L278 -// This is normal and should not throw an error. -// Therefore, we need to differentiate between both situations to know whether to throw an error. -// Unfortunately, events (`close`, `error`, `end`, `exit`) cannot be used because `.destroy()` can take an arbitrary amount of time. -// For example, `stdin: 'pipe'` is implemented as a TCP socket, and its `.destroy()` method waits for TCP disconnection. -// Therefore `.destroy()` might end before or after subprocess exit, based on OS speed and load. -// The only way to detect this is to spy on `subprocess.stdin._destroy()` by wrapping it. -// If `subprocess.exitCode` or `subprocess.signalCode` is set, it means `.destroy()` is being called by Node.js itself. -const handleStdinDestroy = (stream, {originalStreams: [originalStdin], subprocess}) => { - const state = {stdinCleanedUp: false}; - if (stream === originalStdin) { - spyOnStdinDestroy(stream, subprocess, state); - } - - return state; -}; - -const spyOnStdinDestroy = (subprocessStdin, subprocess, state) => { - const {_destroy} = subprocessStdin; - subprocessStdin._destroy = (...destroyArguments) => { - setStdinCleanedUp(subprocess, state); - _destroy.call(subprocessStdin, ...destroyArguments); - }; -}; - -const setStdinCleanedUp = ({exitCode, signalCode}, state) => { - if (exitCode !== null || signalCode !== null) { - state.stdinCleanedUp = true; - } -}; - -// We ignore EPIPEs on writable streams and aborts on readable streams since those can happen normally. -// When one stream errors, the error is propagated to the other streams on the same file descriptor. -// Those other streams might have a different direction due to the above. -// When this happens, the direction of both the initial stream and the others should then be taken into account. -// Therefore, we keep track of whether a stream error is currently propagating. -const handleStreamError = (error, fdNumber, streamInfo, isSameDirection) => { - if (!shouldIgnoreStreamError(error, fdNumber, streamInfo, isSameDirection)) { - throw error; - } -}; - -const shouldIgnoreStreamError = (error, fdNumber, streamInfo, isSameDirection = true) => { - if (streamInfo.propagating) { - return isStreamEpipe(error) || isStreamAbort(error); - } - - streamInfo.propagating = true; - return isInputFileDescriptor(streamInfo, fdNumber) === isSameDirection - ? isStreamEpipe(error) - : isStreamAbort(error); -}; - -// Unfortunately, we cannot use the stream's class or properties to know whether it is readable or writable. -// For example, `subprocess.stdin` is technically a Duplex, but can only be used as a writable. -// Therefore, we need to use the file descriptor's direction (`stdin` is input, `stdout` is output, etc.). -// However, while `subprocess.std*` and transforms follow that direction, any stream passed the `std*` option has the opposite direction. -// For example, `subprocess.stdin` is a writable, but the `stdin` option is a readable. -const isInputFileDescriptor = ({fileDescriptors}, fdNumber) => fdNumber !== 'all' && fileDescriptors[fdNumber].direction === 'input'; - -// When `stream.destroy()` is called without an `error` argument, stream is aborted. -// This is the only way to abort a readable stream, which can be useful in some instances. -// Therefore, we ignore this error on readable streams. -const isStreamAbort = error => error?.code === 'ERR_STREAM_PREMATURE_CLOSE'; - -// When `stream.write()` is called but the underlying source has been closed, `EPIPE` is emitted. -// When piping subprocesses, the source subprocess usually decides when to stop piping. -// However, there are some instances when the destination does instead, such as `... | head -n1`. -// It notifies the source by using `EPIPE`. -// Therefore, we ignore this error on writable streams. -const isStreamEpipe = error => error?.code === 'EPIPE'; - -// Read the contents of `subprocess.std*` and|or wait for its completion -const waitForStdioStreams = ({subprocess, encoding, buffer, maxBuffer, lines, stripFinalNewline, verboseInfo, streamInfo}) => subprocess.stdio.map((stream, fdNumber) => waitForSubprocessStream({ - stream, - fdNumber, - encoding, - buffer: buffer[fdNumber], - maxBuffer: maxBuffer[fdNumber], - lines: lines[fdNumber], - allMixed: false, - stripFinalNewline, - verboseInfo, - streamInfo, -})); - -// Read the contents of `subprocess.std*` or `subprocess.all` and|or wait for its completion -const waitForSubprocessStream = async ({stream, fdNumber, encoding, buffer, maxBuffer, lines, allMixed, stripFinalNewline, verboseInfo, streamInfo}) => { - if (!stream) { - return; - } - - const onStreamEnd = waitForStream(stream, fdNumber, streamInfo); - if (isInputFileDescriptor(streamInfo, fdNumber)) { - await onStreamEnd; - return; - } - - const [output] = await Promise.all([ - getStreamOutput({ - stream, - onStreamEnd, - fdNumber, - encoding, - buffer, - maxBuffer, - lines, - allMixed, - stripFinalNewline, - verboseInfo, - streamInfo, - }), - onStreamEnd, - ]); - return output; -}; - -// `all` interleaves `stdout` and `stderr` -const makeAllStream = ({stdout, stderr}, {all}) => all && (stdout || stderr) - ? mergeStreams([stdout, stderr].filter(Boolean)) - : undefined; - -// Read the contents of `subprocess.all` and|or wait for its completion -const waitForAllStream = ({subprocess, encoding, buffer, maxBuffer, lines, stripFinalNewline, verboseInfo, streamInfo}) => waitForSubprocessStream({ - ...getAllStream(subprocess, buffer), - fdNumber: 'all', - encoding, - maxBuffer: maxBuffer[1] + maxBuffer[2], - lines: lines[1] || lines[2], - allMixed: getAllMixed(subprocess), - stripFinalNewline, - verboseInfo, - streamInfo, -}); - -const getAllStream = ({stdout, stderr, all}, [, bufferStdout, bufferStderr]) => { - const buffer = bufferStdout || bufferStderr; - if (!buffer) { - return {stream: all, buffer}; - } - - if (!bufferStdout) { - return {stream: stderr, buffer}; - } - - if (!bufferStderr) { - return {stream: stdout, buffer}; - } - - return {stream: all, buffer}; -}; - -// When `subprocess.stdout` is in objectMode but not `subprocess.stderr` (or the opposite), we need to use both: -// - `getStreamAsArray()` for the chunks in objectMode, to return as an array without changing each chunk -// - `getStreamAsArrayBuffer()` or `getStream()` for the chunks not in objectMode, to convert them from Buffers to string or Uint8Array -// We do this by emulating the Buffer -> string|Uint8Array conversion performed by `get-stream` with our own, which is identical. -const getAllMixed = ({all, stdout, stderr}) => all - && stdout - && stderr - && stdout.readableObjectMode !== stderr.readableObjectMode; - -// When `verbose` is `'full'`, print IPC messages from the subprocess -const shouldLogIpc = verboseInfo => isFullVerbose(verboseInfo, 'ipc'); - -const logIpcOutput = (message, verboseInfo) => { - const verboseMessage = serializeVerboseMessage(message); - verboseLog({ - type: 'ipc', - verboseMessage, - fdNumber: 'ipc', - verboseInfo, - }); -}; - -// Iterate through IPC messages sent by the subprocess -const waitForIpcOutput = async ({ - subprocess, - buffer: bufferArray, - maxBuffer: maxBufferArray, - ipc, - ipcOutput, - verboseInfo, -}) => { - if (!ipc) { - return ipcOutput; - } - - const isVerbose = shouldLogIpc(verboseInfo); - const buffer = getFdSpecificValue(bufferArray, 'ipc'); - const maxBuffer = getFdSpecificValue(maxBufferArray, 'ipc'); - - for await (const message of loopOnMessages({ - anyProcess: subprocess, - channel: subprocess.channel, - isSubprocess: false, - ipc, - shouldAwait: false, - reference: true, - })) { - if (buffer) { - checkIpcMaxBuffer(subprocess, ipcOutput, maxBuffer); - ipcOutput.push(message); - } - - if (isVerbose) { - logIpcOutput(message, verboseInfo); - } - } - - return ipcOutput; -}; - -const getBufferedIpcOutput = async (ipcOutputPromise, ipcOutput) => { - await Promise.allSettled([ipcOutputPromise]); - return ipcOutput; -}; - -// Retrieve result of subprocess: exit code, signal, error, streams (stdout/stderr/all) -const waitForSubprocessResult = async ({ - subprocess, - options: { - encoding, - buffer, - maxBuffer, - lines, - timeoutDuration: timeout, - cancelSignal, - gracefulCancel, - forceKillAfterDelay, - stripFinalNewline, - ipc, - ipcInput, - }, - context, - verboseInfo, - fileDescriptors, - originalStreams, - onInternalError, - controller, -}) => { - const exitPromise = waitForExit(subprocess, context); - const streamInfo = { - originalStreams, - fileDescriptors, - subprocess, - exitPromise, - propagating: false, - }; - - const stdioPromises = waitForStdioStreams({ - subprocess, - encoding, - buffer, - maxBuffer, - lines, - stripFinalNewline, - verboseInfo, - streamInfo, - }); - const allPromise = waitForAllStream({ - subprocess, - encoding, - buffer, - maxBuffer, - lines, - stripFinalNewline, - verboseInfo, - streamInfo, - }); - const ipcOutput = []; - const ipcOutputPromise = waitForIpcOutput({ - subprocess, - buffer, - maxBuffer, - ipc, - ipcOutput, - verboseInfo, - }); - const originalPromises = waitForOriginalStreams(originalStreams, subprocess, streamInfo); - const customStreamsEndPromises = waitForCustomStreamsEnd(fileDescriptors, streamInfo); - - try { - return await Promise.race([ - Promise.all([ - {}, - waitForSuccessfulExit(exitPromise), - Promise.all(stdioPromises), - allPromise, - ipcOutputPromise, - sendIpcInput(subprocess, ipcInput), - ...originalPromises, - ...customStreamsEndPromises, - ]), - onInternalError, - throwOnSubprocessError(subprocess, controller), - ...throwOnTimeout(subprocess, timeout, context, controller), - ...throwOnCancel({ - subprocess, - cancelSignal, - gracefulCancel, - context, - controller, - }), - ...throwOnGracefulCancel({ - subprocess, - cancelSignal, - gracefulCancel, - forceKillAfterDelay, - context, - controller, - }), - ]); - } catch (error) { - context.terminationReason ??= 'other'; - return Promise.all([ - {error}, - exitPromise, - Promise.all(stdioPromises.map(stdioPromise => getBufferedData(stdioPromise))), - getBufferedData(allPromise), - getBufferedIpcOutput(ipcOutputPromise, ipcOutput), - Promise.allSettled(originalPromises), - Promise.allSettled(customStreamsEndPromises), - ]); - } -}; - -// Transforms replace `subprocess.std*`, which means they are not exposed to users. -// However, we still want to wait for their completion. -const waitForOriginalStreams = (originalStreams, subprocess, streamInfo) => - originalStreams.map((stream, fdNumber) => stream === subprocess.stdio[fdNumber] - ? undefined - : waitForStream(stream, fdNumber, streamInfo)); - -// Some `stdin`/`stdout`/`stderr` options create a stream, e.g. when passing a file path. -// The `.pipe()` method automatically ends that stream when `subprocess` ends. -// This makes sure we wait for the completion of those streams, in order to catch any error. -const waitForCustomStreamsEnd = (fileDescriptors, streamInfo) => fileDescriptors.flatMap(({stdioItems}, fdNumber) => stdioItems - .filter(({value, stream = value}) => isStream(stream, {checkOpen: false}) && !isStandardStream(stream)) - .map(({type, value, stream = value}) => waitForStream(stream, fdNumber, streamInfo, { - isSameDirection: TRANSFORM_TYPES.has(type), - stopOnExit: type === 'native', - }))); - -// Fails when the subprocess emits an `error` event -const throwOnSubprocessError = async (subprocess, {signal}) => { - const [error] = await once$2(subprocess, 'error', {signal}); - throw error; -}; - -// When using multiple `.readable()`/`.writable()`/`.duplex()`, `final` and `destroy` should wait for other streams -const initializeConcurrentStreams = () => ({ - readableDestroy: new WeakMap(), - writableFinal: new WeakMap(), - writableDestroy: new WeakMap(), -}); - -// Each file descriptor + `waitName` has its own array of promises. -// Each promise is a single `.readable()`/`.writable()`/`.duplex()` call. -const addConcurrentStream = (concurrentStreams, stream, waitName) => { - const weakMap = concurrentStreams[waitName]; - if (!weakMap.has(stream)) { - weakMap.set(stream, []); - } - - const promises = weakMap.get(stream); - const promise = createDeferred(); - promises.push(promise); - const resolve = promise.resolve.bind(promise); - return {resolve, promises}; -}; - -// Wait for other streams, but stop waiting when subprocess ends -const waitForConcurrentStreams = async ({resolve, promises}, subprocess) => { - resolve(); - const [isSubprocessExit] = await Promise.race([ - Promise.allSettled([true, subprocess]), - Promise.all([false, ...promises]), - ]); - return !isSubprocessExit; -}; - -const safeWaitForSubprocessStdin = async subprocessStdin => { - if (subprocessStdin === undefined) { - return; - } - - try { - await waitForSubprocessStdin(subprocessStdin); - } catch {} -}; - -const safeWaitForSubprocessStdout = async subprocessStdout => { - if (subprocessStdout === undefined) { - return; - } - - try { - await waitForSubprocessStdout(subprocessStdout); - } catch {} -}; - -const waitForSubprocessStdin = async subprocessStdin => { - await finished(subprocessStdin, {cleanup: true, readable: false, writable: true}); -}; - -const waitForSubprocessStdout = async subprocessStdout => { - await finished(subprocessStdout, {cleanup: true, readable: true, writable: false}); -}; - -// When `readable` or `writable` aborts/errors, awaits the subprocess, for the reason mentioned above -const waitForSubprocess = async (subprocess, error) => { - await subprocess; - if (error) { - throw error; - } -}; - -const destroyOtherStream = (stream, isOpen, error) => { - if (error && !isStreamAbort(error)) { - stream.destroy(error); - } else if (isOpen) { - stream.destroy(); - } -}; - -// Create a `Readable` stream that forwards from `stdout` and awaits the subprocess -const createReadable = ({subprocess, concurrentStreams, encoding}, {from, binary: binaryOption = true, preserveNewlines = true} = {}) => { - const binary = binaryOption || BINARY_ENCODINGS.has(encoding); - const {subprocessStdout, waitReadableDestroy} = getSubprocessStdout(subprocess, from, concurrentStreams); - const {readableEncoding, readableObjectMode, readableHighWaterMark} = getReadableOptions(subprocessStdout, binary); - const {read, onStdoutDataDone} = getReadableMethods({ - subprocessStdout, - subprocess, - binary, - encoding, - preserveNewlines, - }); - const readable = new Readable({ - read, - destroy: callbackify(onReadableDestroy.bind(undefined, {subprocessStdout, subprocess, waitReadableDestroy})), - highWaterMark: readableHighWaterMark, - objectMode: readableObjectMode, - encoding: readableEncoding, - }); - onStdoutFinished({ - subprocessStdout, - onStdoutDataDone, - readable, - subprocess, - }); - return readable; -}; - -// Retrieve `stdout` (or other stream depending on `from`) -const getSubprocessStdout = (subprocess, from, concurrentStreams) => { - const subprocessStdout = getFromStream(subprocess, from); - const waitReadableDestroy = addConcurrentStream(concurrentStreams, subprocessStdout, 'readableDestroy'); - return {subprocessStdout, waitReadableDestroy}; -}; - -const getReadableOptions = ({readableEncoding, readableObjectMode, readableHighWaterMark}, binary) => binary - ? {readableEncoding, readableObjectMode, readableHighWaterMark} - : {readableEncoding, readableObjectMode: true, readableHighWaterMark: DEFAULT_OBJECT_HIGH_WATER_MARK}; - -const getReadableMethods = ({subprocessStdout, subprocess, binary, encoding, preserveNewlines}) => { - const onStdoutDataDone = createDeferred(); - const onStdoutData = iterateOnSubprocessStream({ - subprocessStdout, - subprocess, - binary, - shouldEncode: !binary, - encoding, - preserveNewlines, - }); - - return { - read() { - onRead(this, onStdoutData, onStdoutDataDone); - }, - onStdoutDataDone, - }; -}; - -// Forwards data from `stdout` to `readable` -const onRead = async (readable, onStdoutData, onStdoutDataDone) => { - try { - const {value, done} = await onStdoutData.next(); - if (done) { - onStdoutDataDone.resolve(); - } else { - readable.push(value); - } - } catch {} -}; - -// When `subprocess.stdout` ends/aborts/errors, do the same on `readable`. -// Await the subprocess, for the same reason as above. -const onStdoutFinished = async ({subprocessStdout, onStdoutDataDone, readable, subprocess, subprocessStdin}) => { - try { - await waitForSubprocessStdout(subprocessStdout); - await subprocess; - await safeWaitForSubprocessStdin(subprocessStdin); - await onStdoutDataDone; - - if (readable.readable) { - readable.push(null); - } - } catch (error) { - await safeWaitForSubprocessStdin(subprocessStdin); - destroyOtherReadable(readable, error); - } -}; - -// When `readable` aborts/errors, do the same on `subprocess.stdout` -const onReadableDestroy = async ({subprocessStdout, subprocess, waitReadableDestroy}, error) => { - if (await waitForConcurrentStreams(waitReadableDestroy, subprocess)) { - destroyOtherReadable(subprocessStdout, error); - await waitForSubprocess(subprocess, error); - } -}; - -const destroyOtherReadable = (stream, error) => { - destroyOtherStream(stream, stream.readable, error); -}; - -// Create a `Writable` stream that forwards to `stdin` and awaits the subprocess -const createWritable = ({subprocess, concurrentStreams}, {to} = {}) => { - const {subprocessStdin, waitWritableFinal, waitWritableDestroy} = getSubprocessStdin(subprocess, to, concurrentStreams); - const writable = new Writable({ - ...getWritableMethods(subprocessStdin, subprocess, waitWritableFinal), - destroy: callbackify(onWritableDestroy.bind(undefined, { - subprocessStdin, - subprocess, - waitWritableFinal, - waitWritableDestroy, - })), - highWaterMark: subprocessStdin.writableHighWaterMark, - objectMode: subprocessStdin.writableObjectMode, - }); - onStdinFinished(subprocessStdin, writable); - return writable; -}; - -// Retrieve `stdin` (or other stream depending on `to`) -const getSubprocessStdin = (subprocess, to, concurrentStreams) => { - const subprocessStdin = getToStream(subprocess, to); - const waitWritableFinal = addConcurrentStream(concurrentStreams, subprocessStdin, 'writableFinal'); - const waitWritableDestroy = addConcurrentStream(concurrentStreams, subprocessStdin, 'writableDestroy'); - return {subprocessStdin, waitWritableFinal, waitWritableDestroy}; -}; - -const getWritableMethods = (subprocessStdin, subprocess, waitWritableFinal) => ({ - write: onWrite.bind(undefined, subprocessStdin), - final: callbackify(onWritableFinal.bind(undefined, subprocessStdin, subprocess, waitWritableFinal)), -}); - -// Forwards data from `writable` to `stdin` -const onWrite = (subprocessStdin, chunk, encoding, done) => { - if (subprocessStdin.write(chunk, encoding)) { - done(); - } else { - subprocessStdin.once('drain', done); - } -}; - -// Ensures that the writable `final` and readable `end` events awaits the subprocess. -// Like this, any subprocess failure is propagated as a stream `error` event, instead of being lost. -// The user does not need to `await` the subprocess anymore, but now needs to await the stream completion or error. -// When multiple writables are targeting the same stream, they wait for each other, unless the subprocess ends first. -const onWritableFinal = async (subprocessStdin, subprocess, waitWritableFinal) => { - if (await waitForConcurrentStreams(waitWritableFinal, subprocess)) { - if (subprocessStdin.writable) { - subprocessStdin.end(); - } - - await subprocess; - } -}; - -// When `subprocess.stdin` ends/aborts/errors, do the same on `writable`. -const onStdinFinished = async (subprocessStdin, writable, subprocessStdout) => { - try { - await waitForSubprocessStdin(subprocessStdin); - if (writable.writable) { - writable.end(); - } - } catch (error) { - await safeWaitForSubprocessStdout(subprocessStdout); - destroyOtherWritable(writable, error); - } -}; - -// When `writable` aborts/errors, do the same on `subprocess.stdin` -const onWritableDestroy = async ({subprocessStdin, subprocess, waitWritableFinal, waitWritableDestroy}, error) => { - await waitForConcurrentStreams(waitWritableFinal, subprocess); - if (await waitForConcurrentStreams(waitWritableDestroy, subprocess)) { - destroyOtherWritable(subprocessStdin, error); - await waitForSubprocess(subprocess, error); - } -}; - -const destroyOtherWritable = (stream, error) => { - destroyOtherStream(stream, stream.writable, error); -}; - -// Create a `Duplex` stream combining both `subprocess.readable()` and `subprocess.writable()` -const createDuplex = ({subprocess, concurrentStreams, encoding}, {from, to, binary: binaryOption = true, preserveNewlines = true} = {}) => { - const binary = binaryOption || BINARY_ENCODINGS.has(encoding); - const {subprocessStdout, waitReadableDestroy} = getSubprocessStdout(subprocess, from, concurrentStreams); - const {subprocessStdin, waitWritableFinal, waitWritableDestroy} = getSubprocessStdin(subprocess, to, concurrentStreams); - const {readableEncoding, readableObjectMode, readableHighWaterMark} = getReadableOptions(subprocessStdout, binary); - const {read, onStdoutDataDone} = getReadableMethods({ - subprocessStdout, - subprocess, - binary, - encoding, - preserveNewlines, - }); - const duplex = new Duplex({ - read, - ...getWritableMethods(subprocessStdin, subprocess, waitWritableFinal), - destroy: callbackify(onDuplexDestroy.bind(undefined, { - subprocessStdout, - subprocessStdin, - subprocess, - waitReadableDestroy, - waitWritableFinal, - waitWritableDestroy, - })), - readableHighWaterMark, - writableHighWaterMark: subprocessStdin.writableHighWaterMark, - readableObjectMode, - writableObjectMode: subprocessStdin.writableObjectMode, - encoding: readableEncoding, - }); - onStdoutFinished({ - subprocessStdout, - onStdoutDataDone, - readable: duplex, - subprocess, - subprocessStdin, - }); - onStdinFinished(subprocessStdin, duplex, subprocessStdout); - return duplex; -}; - -const onDuplexDestroy = async ({subprocessStdout, subprocessStdin, subprocess, waitReadableDestroy, waitWritableFinal, waitWritableDestroy}, error) => { - await Promise.all([ - onReadableDestroy({subprocessStdout, subprocess, waitReadableDestroy}, error), - onWritableDestroy({ - subprocessStdin, - subprocess, - waitWritableFinal, - waitWritableDestroy, - }, error), - ]); -}; - -// Convert the subprocess to an async iterable -const createIterable = (subprocess, encoding, { - from, - binary: binaryOption = false, - preserveNewlines = false, -} = {}) => { - const binary = binaryOption || BINARY_ENCODINGS.has(encoding); - const subprocessStdout = getFromStream(subprocess, from); - const onStdoutData = iterateOnSubprocessStream({ - subprocessStdout, - subprocess, - binary, - shouldEncode: true, - encoding, - preserveNewlines, - }); - return iterateOnStdoutData(onStdoutData, subprocessStdout, subprocess); -}; - -const iterateOnStdoutData = async function * (onStdoutData, subprocessStdout, subprocess) { - try { - yield * onStdoutData; - } finally { - if (subprocessStdout.readable) { - subprocessStdout.destroy(); - } - - await subprocess; - } -}; - -// Add methods to convert the subprocess to a stream or iterable -const addConvertedStreams = (subprocess, {encoding}) => { - const concurrentStreams = initializeConcurrentStreams(); - subprocess.readable = createReadable.bind(undefined, {subprocess, concurrentStreams, encoding}); - subprocess.writable = createWritable.bind(undefined, {subprocess, concurrentStreams}); - subprocess.duplex = createDuplex.bind(undefined, {subprocess, concurrentStreams, encoding}); - subprocess.iterable = createIterable.bind(undefined, subprocess, encoding); - subprocess[Symbol.asyncIterator] = createIterable.bind(undefined, subprocess, encoding, {}); -}; - -// The return value is a mixin of `subprocess` and `Promise` -const mergePromise = (subprocess, promise) => { - for (const [property, descriptor] of descriptors) { - const value = descriptor.value.bind(promise); - Reflect.defineProperty(subprocess, property, {...descriptor, value}); - } -}; - -// eslint-disable-next-line unicorn/prefer-top-level-await -const nativePromisePrototype = (async () => {})().constructor.prototype; - -const descriptors = ['then', 'catch', 'finally'].map(property => [ - property, - Reflect.getOwnPropertyDescriptor(nativePromisePrototype, property), -]); - -// Main shared logic for all async methods: `execa()`, `$`, `execaNode()` -const execaCoreAsync = (rawFile, rawArguments, rawOptions, createNested) => { - const {file, commandArguments, command, escapedCommand, startTime, verboseInfo, options, fileDescriptors} = handleAsyncArguments(rawFile, rawArguments, rawOptions); - const {subprocess, promise} = spawnSubprocessAsync({ - file, - commandArguments, - options, - startTime, - verboseInfo, - command, - escapedCommand, - fileDescriptors, - }); - subprocess.pipe = pipeToSubprocess.bind(undefined, { - source: subprocess, - sourcePromise: promise, - boundOptions: {}, - createNested, - }); - mergePromise(subprocess, promise); - SUBPROCESS_OPTIONS.set(subprocess, {options, fileDescriptors}); - return subprocess; -}; - -// Compute arguments to pass to `child_process.spawn()` -const handleAsyncArguments = (rawFile, rawArguments, rawOptions) => { - const {command, escapedCommand, startTime, verboseInfo} = handleCommand(rawFile, rawArguments, rawOptions); - const {file, commandArguments, options: normalizedOptions} = normalizeOptions(rawFile, rawArguments, rawOptions); - const options = handleAsyncOptions(normalizedOptions); - const fileDescriptors = handleStdioAsync(options, verboseInfo); - return { - file, - commandArguments, - command, - escapedCommand, - startTime, - verboseInfo, - options, - fileDescriptors, - }; -}; - -// Options normalization logic specific to async methods. -// Prevent passing the `timeout` option directly to `child_process.spawn()`. -const handleAsyncOptions = ({timeout, signal, ...options}) => { - if (signal !== undefined) { - throw new TypeError('The "signal" option has been renamed to "cancelSignal" instead.'); - } - - return {...options, timeoutDuration: timeout}; -}; - -const spawnSubprocessAsync = ({file, commandArguments, options, startTime, verboseInfo, command, escapedCommand, fileDescriptors}) => { - let subprocess; - try { - subprocess = spawn(...concatenateShell(file, commandArguments, options)); - } catch (error) { - return handleEarlyError({ - error, - command, - escapedCommand, - fileDescriptors, - options, - startTime, - verboseInfo, - }); - } - - const controller = new AbortController(); - setMaxListeners(Number.POSITIVE_INFINITY, controller.signal); - - const originalStreams = [...subprocess.stdio]; - pipeOutputAsync(subprocess, fileDescriptors, controller); - cleanupOnExit(subprocess, options, controller); - - const context = {}; - const onInternalError = createDeferred(); - subprocess.kill = subprocessKill.bind(undefined, { - kill: subprocess.kill.bind(subprocess), - options, - onInternalError, - context, - controller, - }); - subprocess.all = makeAllStream(subprocess, options); - addConvertedStreams(subprocess, options); - addIpcMethods(subprocess, options); - - const promise = handlePromise({ - subprocess, - options, - startTime, - verboseInfo, - fileDescriptors, - originalStreams, - command, - escapedCommand, - context, - onInternalError, - controller, - }); - return {subprocess, promise}; -}; - -// Asynchronous logic, as opposed to the previous logic which can be run synchronously, i.e. can be returned to user right away -const handlePromise = async ({subprocess, options, startTime, verboseInfo, fileDescriptors, originalStreams, command, escapedCommand, context, onInternalError, controller}) => { - const [ - errorInfo, - [exitCode, signal], - stdioResults, - allResult, - ipcOutput, - ] = await waitForSubprocessResult({ - subprocess, - options, - context, - verboseInfo, - fileDescriptors, - originalStreams, - onInternalError, - controller, - }); - controller.abort(); - onInternalError.resolve(); - - const stdio = stdioResults.map((stdioResult, fdNumber) => stripNewline(stdioResult, options, fdNumber)); - const all = stripNewline(allResult, options, 'all'); - const result = getAsyncResult({ - errorInfo, - exitCode, - signal, - stdio, - all, - ipcOutput, - context, - options, - command, - escapedCommand, - startTime, - }); - return handleResult(result, verboseInfo, options); -}; - -const getAsyncResult = ({errorInfo, exitCode, signal, stdio, all, ipcOutput, context, options, command, escapedCommand, startTime}) => 'error' in errorInfo - ? makeError({ - error: errorInfo.error, - command, - escapedCommand, - timedOut: context.terminationReason === 'timeout', - isCanceled: context.terminationReason === 'cancel' || context.terminationReason === 'gracefulCancel', - isGracefullyCanceled: context.terminationReason === 'gracefulCancel', - isMaxBuffer: errorInfo.error instanceof MaxBufferError, - isForcefullyTerminated: context.isForcefullyTerminated, - exitCode, - signal, - stdio, - all, - ipcOutput, - options, - startTime, - isSync: false, - }) - : makeSuccessResult({ - command, - escapedCommand, - stdio, - all, - ipcOutput, - options, - startTime, - }); - -// Deep merge specific options like `env`. Shallow merge the other ones. -const mergeOptions = (boundOptions, options) => { - const newOptions = Object.fromEntries( - Object.entries(options).map(([optionName, optionValue]) => [ - optionName, - mergeOption(optionName, boundOptions[optionName], optionValue), - ]), - ); - return {...boundOptions, ...newOptions}; -}; - -const mergeOption = (optionName, boundOptionValue, optionValue) => { - if (DEEP_OPTIONS.has(optionName) && isPlainObject(boundOptionValue) && isPlainObject(optionValue)) { - return {...boundOptionValue, ...optionValue}; - } - - return optionValue; -}; - -const DEEP_OPTIONS = new Set(['env', ...FD_SPECIFIC_OPTIONS]); - -// Wraps every exported methods to provide the following features: -// - template string syntax: execa`command argument` -// - options binding: boundExeca = execa(options) -// - optional argument/options: execa(file), execa(file, args), execa(file, options), execa(file, args, options) -// `mapArguments()` and `setBoundExeca()` allows for method-specific logic. -const createExeca = (mapArguments, boundOptions, deepOptions, setBoundExeca) => { - const createNested = (mapArguments, boundOptions, setBoundExeca) => createExeca(mapArguments, boundOptions, deepOptions, setBoundExeca); - const boundExeca = (...execaArguments) => callBoundExeca({ - mapArguments, - deepOptions, - boundOptions, - setBoundExeca, - createNested, - }, ...execaArguments); - - if (setBoundExeca !== undefined) { - setBoundExeca(boundExeca, createNested, boundOptions); - } - - return boundExeca; -}; - -const callBoundExeca = ({mapArguments, deepOptions = {}, boundOptions = {}, setBoundExeca, createNested}, firstArgument, ...nextArguments) => { - if (isPlainObject(firstArgument)) { - return createNested(mapArguments, mergeOptions(boundOptions, firstArgument), setBoundExeca); - } - - const {file, commandArguments, options, isSync} = parseArguments({ - mapArguments, - firstArgument, - nextArguments, - deepOptions, - boundOptions, - }); - return isSync - ? execaCoreSync(file, commandArguments, options) - : execaCoreAsync(file, commandArguments, options, createNested); -}; - -const parseArguments = ({mapArguments, firstArgument, nextArguments, deepOptions, boundOptions}) => { - const callArguments = isTemplateString(firstArgument) - ? parseTemplates(firstArgument, nextArguments) - : [firstArgument, ...nextArguments]; - const [initialFile, initialArguments, initialOptions] = normalizeParameters(...callArguments); - const mergedOptions = mergeOptions(mergeOptions(deepOptions, boundOptions), initialOptions); - const { - file = initialFile, - commandArguments = initialArguments, - options = mergedOptions, - isSync = false, - } = mapArguments({file: initialFile, commandArguments: initialArguments, options: mergedOptions}); - return { - file, - commandArguments, - options, - isSync, - }; -}; - -// Main logic for `execaCommand()` -const mapCommandAsync = ({file, commandArguments}) => parseCommand(file, commandArguments); - -// Main logic for `execaCommandSync()` -const mapCommandSync = ({file, commandArguments}) => ({...parseCommand(file, commandArguments), isSync: true}); - -// Convert `execaCommand(command)` into `execa(file, ...commandArguments)` -const parseCommand = (command, unusedArguments) => { - if (unusedArguments.length > 0) { - throw new TypeError(`The command and its arguments must be passed as a single string: ${command} ${unusedArguments}.`); - } - - const [file, ...commandArguments] = parseCommandString(command); - return {file, commandArguments}; -}; - -// Convert `command` string into an array of file or arguments to pass to $`${...fileOrCommandArguments}` -const parseCommandString = command => { - if (typeof command !== 'string') { - throw new TypeError(`The command must be a string: ${String(command)}.`); - } - - const trimmedCommand = command.trim(); - if (trimmedCommand === '') { - return []; - } - - const tokens = []; - for (const token of trimmedCommand.split(SPACES_REGEXP)) { - // Allow spaces to be escaped by a backslash if not meant as a delimiter - const previousToken = tokens.at(-1); - if (previousToken && previousToken.endsWith('\\')) { - // Merge previous token with current one - tokens[tokens.length - 1] = `${previousToken.slice(0, -1)} ${token}`; - } else { - tokens.push(token); - } - } - - return tokens; -}; - -const SPACES_REGEXP = / +/g; - -// Sets `$.sync` and `$.s` -const setScriptSync = (boundExeca, createNested, boundOptions) => { - boundExeca.sync = createNested(mapScriptSync, boundOptions); - boundExeca.s = boundExeca.sync; -}; - -// Main logic for `$` -const mapScriptAsync = ({options}) => getScriptOptions(options); - -// Main logic for `$.sync` -const mapScriptSync = ({options}) => ({...getScriptOptions(options), isSync: true}); - -// `$` is like `execa` but with script-friendly options: `{stdin: 'inherit', preferLocal: true}` -const getScriptOptions = options => ({options: {...getScriptStdinOption(options), ...options}}); - -const getScriptStdinOption = ({input, inputFile, stdio}) => input === undefined && inputFile === undefined && stdio === undefined - ? {stdin: 'inherit'} - : {}; - -// When using $(...).pipe(...), most script-friendly options should apply to both commands. -// However, some options (like `stdin: 'inherit'`) would create issues with piping, i.e. cannot be deep. -const deepScriptOptions = {preferLocal: true}; - -const execa = createExeca(() => ({})); -createExeca(() => ({isSync: true})); -createExeca(mapCommandAsync); -createExeca(mapCommandSync); -createExeca(mapNode); -createExeca(mapScriptAsync, {}, deepScriptOptions, setScriptSync); - -getIpcExport(); - -const netstat = async type => { - const {stdout} = await execa('netstat', ['-anv', '-p', type]); - return stdout; -}; - -const macos = async () => { - const [tcp, udp] = await Promise.all([ - netstat('tcp'), - netstat('udp'), - ]); - - // Column headers are on the second line - const headerStart = tcp.indexOf('\n') + 1; - const header = tcp.slice(headerStart, tcp.indexOf('\n', headerStart)); - - return { - stdout: [tcp, udp].join('\n'), - addressColumn: 3, - // Some versions of macOS print two extra columns for rxbytes and - // txbytes before pid. Unfortunately headers can't be parsed because - // they're space separated but some contain spaces, so we use this - // heuristic to distinguish the two netstat versions. - pidColumn: header.includes('rxbytes') ? 10 : 8, - }; -}; - -const linux = async () => { - const {stdout} = await execa('ss', ['-tunlp']); - return {stdout, addressColumn: 4, pidColumn: 6}; -}; - -const windows = async () => { - const {stdout} = await execa('netstat', ['-ano']); - return {stdout, addressColumn: 1, pidColumn: 4}; -}; - -const isProtocol = value => /^\s*(tcp|udp)/i.test(value); - -const stripIpv6Brackets = host => - host?.startsWith('[') && host.endsWith(']') ? host.slice(1, -1) : host; - -const normalizeHost = host => { - const normalizedHost = stripIpv6Brackets(host); - if (normalizedHost === 'localhost') { - return '127.0.0.1'; - } - - if (normalizedHost === '::ffff:127.0.0.1') { - return '127.0.0.1'; - } - - if (normalizedHost === '::') { - return '*'; - } - - return normalizedHost; -}; - -const parsePid = pid => { - if (typeof pid !== 'string') { - return; - } - - // Linux ss: users:(("node",pid=1337,fd=123)) - const linuxMatch = /pid=(?\d+)/.exec(pid); - if (linuxMatch?.groups?.pid) { - return Number.parseInt(linuxMatch.groups.pid, 10); - } - - // MacOS netstat - handles both old format (macOS 15 and older) and new format (macOS 26+) - // Old format: "1337" or ",1337" or ",pid=1337" - // New format: "prog:1337" (macOS 26+) - const macMatch = /(?:^|",|",pid=|[A-Za-z]+:)(?\d+)/.exec(pid); - if (macMatch?.groups?.pid) { - return Number.parseInt(macMatch.groups.pid, 10); - } - - // Windows netstat -ano: 1337 - if (/^\d+$/.test(pid)) { - return Number.parseInt(pid, 10); - } -}; - -const parseAddress = address => { - // Match "...:123" or "... .123" with the port at the end; keep host greedy to the last separator - const match = /^(?.+?)[.:](?\d+)$/.exec(address); - const rawHost = match?.groups?.host ?? address; - const host = normalizeHost(rawHost); - const port = match?.groups?.port ? Number.parseInt(match.groups.port, 10) : undefined; - return {host, port}; -}; - -const isLocalhostAddress = host => host === '127.0.0.1' || host === '::1'; - -const createHostFilter = host => { - const normalizedHost = normalizeHost(host); - if (normalizedHost === '*' || normalizedHost === '0.0.0.0' || normalizedHost === '::') { - return {type: 'all'}; - } - - if (normalizedHost === undefined) { - return {type: 'localhost'}; - } - - return {type: 'specific', host: normalizedHost}; -}; - -const applyHostFilter = (lines, addressColumn, hostFilter) => { - if (hostFilter.type === 'all') { - return lines; - } - - if (hostFilter.type === 'localhost') { - return lines.filter(line => { - const {host} = parseAddress(line[addressColumn]); - return isLocalhostAddress(host); - }); - } - - // Specific host - return lines.filter(line => { - const {host} = parseAddress(line[addressColumn]); - return host === hostFilter.host; - }); -}; - -const validatePid = pid => { - if (!Number.isInteger(pid)) { - throw new TypeError(`Expected an integer, got ${typeof pid}`); - } -}; - -const platformImplementations = {darwin: macos, linux}; -const implementation = platformImplementations[process$2.platform] ?? windows; - -const getList = async () => { - const {stdout, addressColumn, pidColumn} = await implementation(); - - const lines = stdout - .split('\n') - .filter(line => isProtocol(line)) - .map(line => line.match(/\S+/g) || []); - return {lines, addressColumn, pidColumn}; -}; - -const getPidsToPortsMap = async pids => { - const resultMap = new Map(pids.map(pid => [pid, new Set()])); - - // Get all ports from all interfaces for pidToPorts - user wants to know ALL ports this PID uses - for (const [port, pid] of await allPortsWithPid({host: '*'})) { - resultMap.get(pid)?.add(port); - } - - return resultMap; -}; - -async function pidToPorts(pid) { - if (Array.isArray(pid)) { - return getPidsToPortsMap(pid); - } - - validatePid(pid); - const resultMap = await getPidsToPortsMap([pid]); - return resultMap.get(pid); -} - -async function allPortsWithPid(options) { - const {lines, addressColumn, pidColumn} = await getList(); - const hostFilter = createHostFilter(options?.host); - - const resultMap = new Map(); - - // Apply host filtering to all lines, then extract ports - const filteredLines = applyHostFilter(lines, addressColumn, hostFilter); - - for (const line of filteredLines) { - const {port} = parseAddress(line[addressColumn]); - const pid = parsePid(line[pidColumn]); - - if (port !== undefined && pid !== undefined) { - resultMap.set(port, pid); - } - } - - return resultMap; -} - -/** - * Gets the port number that the process is listening on. - * @returns The port number that the process is listening on, or undefined if the process is not listening on any port. - * NOTE: Can't move this to @workflow/utils because it's being imported into @workflow/errors for RetryableError (inside workflow runtime) - */ -async function getPort() { - try { - const pid = process.pid; - const ports = await pidToPorts(pid); - if (!ports || ports.size === 0) { - return undefined; - } - const smallest = Math.min(...ports); - return smallest; - } - catch { - // If port detection fails (e.g., `ss` command not available in production), - // return undefined and fall back to default port - return undefined; - } -} - -// ============================================================ -// Trace Context Propagation Utilities -// ============================================================ -/** - * Serializes the current trace context into a format that can be passed through queues - * @returns A record of strings representing the trace context - */ -async function serializeTraceCarrier() { - const otel = await OtelApi.value; - if (!otel) - return {}; - const carrier = {}; - // Inject the current context into the carrier - otel.propagation.inject(otel.context.active(), carrier); - return carrier; -} -/** - * Deserializes trace context and returns a context that can be used to continue the trace - * @param traceCarrier The serialized trace context - * @returns OpenTelemetry context with the restored trace - */ -async function deserializeTraceCarrier(traceCarrier) { - const otel = await OtelApi.value; - if (!otel) - return; - // Extract the context from the carrier - return otel.propagation.extract(otel.context.active(), traceCarrier); -} -/** - * Runs a function within the context of a deserialized trace - * @param traceCarrier The serialized trace carrier (optional) - * @param fn The function to run within the trace context - * @returns The result of the function - */ -async function withTraceContext(traceCarrier, fn) { - if (!traceCarrier) { - return fn(); - } - const otel = await OtelApi.value; - if (!otel) - return fn(); - const extractedContext = await deserializeTraceCarrier(traceCarrier); - if (!extractedContext) { - return fn(); - } - return otel.context.with(extractedContext, async () => await fn()); -} -const OtelApi = once$1(async () => { - try { - return await import('./index_DqQ8k47W.mjs'); - } - catch { - console.warn('OpenTelemetry not available, tracing will be disabled'); - return null; - } -}); -const Tracer = once$1(async () => { - const api = await OtelApi.value; - if (!api) - return null; - return api.trace.getTracer('workflow'); -}); -async function trace(spanName, ...args) { - const [tracer, otel] = await Promise.all([Tracer.value, OtelApi.value]); - const { fn, opts } = typeof args[0] === 'function' - ? { fn: args[0], opts: {} } - : { fn: args[1], opts: args[0] }; - if (!fn) - throw new Error('Function to trace must be provided'); - if (!tracer || !otel) { - return await fn(); - } - return tracer.startActiveSpan(spanName, opts, async (span) => { - try { - const result = await fn(span); - span.setStatus({ code: otel.SpanStatusCode.OK }); - return result; - } - catch (e) { - span.setStatus({ - code: otel.SpanStatusCode.ERROR, - message: e.message, - }); - throw e; - } - finally { - span.end(); - } - }); -} -async function getSpanContextForTraceCarrier(carrier) { - const [deserialized, otel] = await Promise.all([ - deserializeTraceCarrier(carrier), - OtelApi.value, - ]); - if (!deserialized || !otel) - return; - return otel.trace.getSpanContext(deserialized); -} -async function getActiveSpan() { - const otel = await OtelApi.value; - if (!otel) - return null; - return otel.trace.getActiveSpan(); -} - -function createLogger(namespace) { - const baseDebug = debug(`workflow:${namespace}`); - const logger = (level) => { - const levelDebug = baseDebug.extend(level); - return (message, metadata) => { - levelDebug(message, metadata); - if (levelDebug.enabled) { - getActiveSpan() - .then((span) => { - span?.addEvent(`${level}.${namespace}`, { message, ...metadata }); - }) - .catch(() => { - // Silently ignore telemetry errors - }); - } - }; - }; - return { - debug: logger('debug'), - info: logger('info'), - warn: logger('warn'), - error: logger('error'), - }; -} -const stepLogger = createLogger('step'); -const runtimeLogger = createLogger('runtime'); -const webhookLogger = createLogger('webhook'); -const eventsLogger = createLogger('events'); -createLogger('adapter'); - -/** - * Utils used by the bundler when transforming code - */ -const registeredSteps = new Map(); -/** - * Register a step function to be served in the server bundle - */ -function registerStepFunction(stepId, stepFn) { - registeredSteps.set(stepId, stepFn); -} -/** - * Find a registered step function by name - */ -function getStepFunction(stepId) { - return registeredSteps.get(stepId); -} - -/** - * Creates a lazily-evaluated, memoized version of the provided function. - * - * The returned object exposes a `value` getter that calls `fn` only once, - * caches its result, and returns the cached value on subsequent accesses. - * - * @typeParam T - The return type of the provided function. - * @param fn - The function to be called once and whose result will be cached. - * @returns An object with a `value` property that returns the memoized result of `fn`. - */ -function once(fn) { - const result = { - get value() { - const value = fn(); - Object.defineProperty(result, 'value', { value }); - return value; - }, - }; - return result; -} - -const getDataDirFromEnv = () => { - return process.env.WORKFLOW_EMBEDDED_DATA_DIR || '.workflow-data'; -}; -const DEFAULT_RESOLVE_DATA_OPTION$1 = 'all'; -const getPortFromEnv = () => { - const port = process.env.PORT; - if (port) { - return Number(port); - } - return undefined; -}; -const config = once(() => { - const dataDir = getDataDirFromEnv(); - const port = getPortFromEnv(); - return { dataDir, port }; -}); - -// src/transports.ts -async function streamToBuffer$1(stream) { - let totalLength = 0; - const reader = stream.getReader(); - const chunks = []; - try { - while (true) { - const { done, value } = await reader.read(); - if (done) break; - chunks.push(value); - totalLength += value.length; - } - } finally { - reader.releaseLock(); - } - return Buffer.concat(chunks, totalLength); -} -var JsonTransport$1 = class JsonTransport { - contentType = "application/json"; - replacer; - reviver; - constructor(options = {}) { - this.replacer = options.replacer; - this.reviver = options.reviver; - } - serialize(value) { - return Buffer.from(JSON.stringify(value, this.replacer), "utf8"); - } - async deserialize(stream) { - const buffer = await streamToBuffer$1(stream); - return JSON.parse(buffer.toString("utf8"), this.reviver); - } -}; - -// src/dev.ts -var devRouteHandlers$1 = /* @__PURE__ */ new Map(); -var wildcardRouteHandlers$1 = /* @__PURE__ */ new Map(); -function clearDevHandlers$1() { - devRouteHandlers$1.clear(); - wildcardRouteHandlers$1.clear(); -} -if (process.env.NODE_ENV === "test" || process.env.VITEST) { - globalThis.__clearDevHandlers = clearDevHandlers$1; -} - -// Event type enum -const EventTypeSchema = z$1.enum([ - 'step_completed', - 'step_failed', - 'step_retrying', - 'step_started', - 'hook_created', - 'hook_received', - 'hook_disposed', - 'wait_created', - 'wait_completed', - 'workflow_completed', - 'workflow_failed', - 'workflow_started', -]); -// Base event schema with common properties -const BaseEventSchema = z$1.object({ - eventType: EventTypeSchema, - correlationId: z$1.string().optional(), -}); -// Event schemas (shared between creation requests and server responses) -const StepCompletedEventSchema = BaseEventSchema.extend({ - eventType: z$1.literal('step_completed'), - correlationId: z$1.string(), - eventData: z$1.object({ - result: z$1.any(), - }), -}); -const StepFailedEventSchema = BaseEventSchema.extend({ - eventType: z$1.literal('step_failed'), - correlationId: z$1.string(), - eventData: z$1.object({ - error: z$1.any(), - stack: z$1.string().optional(), - fatal: z$1.boolean().optional(), - }), -}); -// TODO: this is not actually used anywhere yet, we could remove it -// on client and server if needed -const StepRetryingEventSchema = BaseEventSchema.extend({ - eventType: z$1.literal('step_retrying'), - correlationId: z$1.string(), - eventData: z$1.object({ - attempt: z$1.number().min(1), - }), -}); -const StepStartedEventSchema = BaseEventSchema.extend({ - eventType: z$1.literal('step_started'), - correlationId: z$1.string(), -}); -const HookCreatedEventSchema = BaseEventSchema.extend({ - eventType: z$1.literal('hook_created'), - correlationId: z$1.string(), -}); -const HookReceivedEventSchema = BaseEventSchema.extend({ - eventType: z$1.literal('hook_received'), - correlationId: z$1.string(), - eventData: z$1.object({ - payload: z$1.any(), // Serialized payload - }), -}); -const HookDisposedEventSchema = BaseEventSchema.extend({ - eventType: z$1.literal('hook_disposed'), - correlationId: z$1.string(), -}); -const WaitCreatedEventSchema = BaseEventSchema.extend({ - eventType: z$1.literal('wait_created'), - correlationId: z$1.string(), - eventData: z$1.object({ - resumeAt: z$1.coerce.date(), - }), -}); -const WaitCompletedEventSchema = BaseEventSchema.extend({ - eventType: z$1.literal('wait_completed'), - correlationId: z$1.string(), -}); -// TODO: not used yet -const WorkflowCompletedEventSchema = BaseEventSchema.extend({ - eventType: z$1.literal('workflow_completed'), -}); -// TODO: not used yet -const WorkflowFailedEventSchema = BaseEventSchema.extend({ - eventType: z$1.literal('workflow_failed'), - eventData: z$1.object({ - error: z$1.any(), - }), -}); -// TODO: not used yet -const WorkflowStartedEventSchema = BaseEventSchema.extend({ - eventType: z$1.literal('workflow_started'), -}); -// Discriminated union (used for both creation requests and server responses) -const CreateEventSchema = z$1.discriminatedUnion('eventType', [ - StepCompletedEventSchema, - StepFailedEventSchema, - StepRetryingEventSchema, - StepStartedEventSchema, - HookCreatedEventSchema, - HookReceivedEventSchema, - HookDisposedEventSchema, - WaitCreatedEventSchema, - WaitCompletedEventSchema, - WorkflowCompletedEventSchema, - WorkflowFailedEventSchema, - WorkflowStartedEventSchema, -]); -// Server response include runId, eventId, and createdAt -const EventSchema = CreateEventSchema.and(z$1.object({ - runId: z$1.string(), - eventId: z$1.string(), - createdAt: z$1.coerce.date(), -})); - -const zodJsonSchema = z$1.lazy(() => { - return z$1.union([ - z$1.string(), - z$1.number(), - z$1.boolean(), - z$1.null(), - z$1.array(zodJsonSchema), - z$1.record(z$1.string(), zodJsonSchema), - ]); -}); -// Shared schema for paginated responses -const PaginatedResponseSchema = (dataSchema) => z$1.object({ - data: z$1.array(dataSchema), - cursor: z$1.string().nullable(), - hasMore: z$1.boolean(), -}); -/** - * A standard error schema shape for propogating errors from runs and steps - */ -const StructuredErrorSchema = z$1.object({ - message: z$1.string(), - stack: z$1.string().optional(), - code: z$1.string().optional(), // TODO: currently unused. make this an enum maybe -}); - -// Hook schemas -const HookSchema = z$1.object({ - runId: z$1.string(), - hookId: z$1.string(), - token: z$1.string(), - ownerId: z$1.string(), - projectId: z$1.string(), - environment: z$1.string(), - metadata: zodJsonSchema.optional(), - createdAt: z$1.coerce.date(), -}); - -const QueuePrefix = z$2.union([ - z$2.literal('__wkf_step_'), - z$2.literal('__wkf_workflow_'), -]); -const ValidQueueName = z$2.templateLiteral([QueuePrefix, z$2.string()]); -const MessageId = z$2 - .string() - .brand() - .describe('A stored queue message ID'); -/** - * OpenTelemetry trace context for distributed tracing - */ -const TraceCarrierSchema$1 = z$2.record(z$2.string(), z$2.string()); -const WorkflowInvokePayloadSchema$1 = z$2.object({ - runId: z$2.string(), - traceCarrier: TraceCarrierSchema$1.optional(), -}); -const StepInvokePayloadSchema$1 = z$2.object({ - workflowName: z$2.string(), - workflowRunId: z$2.string(), - workflowStartedAt: z$2.number(), - stepId: z$2.string(), - traceCarrier: TraceCarrierSchema$1.optional(), -}); -const QueuePayloadSchema = z$2.union([ - WorkflowInvokePayloadSchema$1, - StepInvokePayloadSchema$1, -]); - -// Workflow run schemas -const WorkflowRunStatusSchema = z$1.enum([ - 'pending', - 'running', - 'completed', - 'failed', - 'paused', - 'cancelled', -]); -/** - * Base schema for the Workflow runs. Prefer using WorkflowRunSchema - * which implements a discriminatedUnion for various states - */ -const WorkflowRunBaseSchema = z$1.object({ - runId: z$1.string(), - status: WorkflowRunStatusSchema, - deploymentId: z$1.string(), - workflowName: z$1.string(), - executionContext: z$1.record(z$1.string(), z$1.any()).optional(), - input: z$1.array(z$1.any()), - output: z$1.any().optional(), - error: StructuredErrorSchema.optional(), - startedAt: z$1.coerce.date().optional(), - completedAt: z$1.coerce.date().optional(), - createdAt: z$1.coerce.date(), - updatedAt: z$1.coerce.date(), -}); -// Discriminated union based on status -const WorkflowRunSchema = z$1.discriminatedUnion('status', [ - // Non-final states - WorkflowRunBaseSchema.extend({ - status: z$1.enum(['pending', 'running', 'paused']), - output: z$1.undefined(), - error: z$1.undefined(), - completedAt: z$1.undefined(), - }), - // Cancelled state - WorkflowRunBaseSchema.extend({ - status: z$1.literal('cancelled'), - output: z$1.undefined(), - error: z$1.undefined(), - completedAt: z$1.coerce.date(), - }), - // Completed state - WorkflowRunBaseSchema.extend({ - status: z$1.literal('completed'), - output: z$1.any(), - error: z$1.undefined(), - completedAt: z$1.coerce.date(), - }), - // Failed state - WorkflowRunBaseSchema.extend({ - status: z$1.literal('failed'), - output: z$1.undefined(), - error: StructuredErrorSchema, - completedAt: z$1.coerce.date(), - }), -]); - -// Step schemas -const StepStatusSchema = z$1.enum([ - 'pending', - 'running', - 'completed', - 'failed', - 'cancelled', -]); -// TODO: implement a discriminated union here just like the run schema -const StepSchema = z$1.object({ - runId: z$1.string(), - stepId: z$1.string(), - stepName: z$1.string(), - status: StepStatusSchema, - input: z$1.array(z$1.any()), - output: z$1.any().optional(), - error: StructuredErrorSchema.optional(), - attempt: z$1.number(), - startedAt: z$1.coerce.date().optional(), - completedAt: z$1.coerce.date().optional(), - createdAt: z$1.coerce.date(), - updatedAt: z$1.coerce.date(), - retryAfter: z$1.coerce.date().optional(), -}); - -const ENCODING = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"; // Crockford's Base32 -const ENCODING_LEN = 32; // from ENCODING.length; -const RANDOM_LEN = 16; -const TIME_LEN = 10; -const TIME_MAX = 281474976710655; // from Math.pow(2, 48) - 1; - -var ULIDErrorCode; -(function (ULIDErrorCode) { - ULIDErrorCode["Base32IncorrectEncoding"] = "B32_ENC_INVALID"; - ULIDErrorCode["DecodeTimeInvalidCharacter"] = "DEC_TIME_CHAR"; - ULIDErrorCode["DecodeTimeValueMalformed"] = "DEC_TIME_MALFORMED"; - ULIDErrorCode["EncodeTimeNegative"] = "ENC_TIME_NEG"; - ULIDErrorCode["EncodeTimeSizeExceeded"] = "ENC_TIME_SIZE_EXCEED"; - ULIDErrorCode["EncodeTimeValueMalformed"] = "ENC_TIME_MALFORMED"; - ULIDErrorCode["PRNGDetectFailure"] = "PRNG_DETECT"; - ULIDErrorCode["ULIDInvalid"] = "ULID_INVALID"; - ULIDErrorCode["Unexpected"] = "UNEXPECTED"; - ULIDErrorCode["UUIDInvalid"] = "UUID_INVALID"; -})(ULIDErrorCode || (ULIDErrorCode = {})); -class ULIDError extends Error { - constructor(errorCode, message) { - super(`${message} (${errorCode})`); - this.name = "ULIDError"; - this.code = errorCode; - } -} - -function randomChar(prng) { - // Currently PRNGs generate fractions from 0 to _less than_ 1, so no "%" is necessary. - // However, just in case a future PRNG can generate 1, - // we are applying "% ENCODING LEN" to wrap back to the first character - const randomPosition = Math.floor(prng() * ENCODING_LEN) % ENCODING_LEN; - return ENCODING.charAt(randomPosition); -} -function replaceCharAt(str, index, char) { - if (index > str.length - 1) { - return str; - } - return str.substr(0, index) + char + str.substr(index + 1); -} -function incrementBase32(str) { - let done = undefined, index = str.length, char, charIndex, output = str; - const maxCharIndex = ENCODING_LEN - 1; - while (!done && index-- >= 0) { - char = output[index]; - charIndex = ENCODING.indexOf(char); - if (charIndex === -1) { - throw new ULIDError(ULIDErrorCode.Base32IncorrectEncoding, "Incorrectly encoded string"); - } - if (charIndex === maxCharIndex) { - output = replaceCharAt(output, index, ENCODING[0]); - continue; - } - done = replaceCharAt(output, index, ENCODING[charIndex + 1]); - } - if (typeof done === "string") { - return done; - } - throw new ULIDError(ULIDErrorCode.Base32IncorrectEncoding, "Failed incrementing string"); -} - -/** - * Decode time from a ULID - * @param id The ULID - * @returns The decoded timestamp - */ -function decodeTime(id) { - if (id.length !== TIME_LEN + RANDOM_LEN) { - throw new ULIDError(ULIDErrorCode.DecodeTimeValueMalformed, "Malformed ULID"); - } - const time = id - .substr(0, TIME_LEN) - .toUpperCase() - .split("") - .reverse() - .reduce((carry, char, index) => { - const encodingIndex = ENCODING.indexOf(char); - if (encodingIndex === -1) { - throw new ULIDError(ULIDErrorCode.DecodeTimeInvalidCharacter, `Time decode error: Invalid character: ${char}`); - } - return (carry += encodingIndex * Math.pow(ENCODING_LEN, index)); - }, 0); - if (time > TIME_MAX) { - throw new ULIDError(ULIDErrorCode.DecodeTimeValueMalformed, `Malformed ULID: timestamp too large: ${time}`); - } - return time; -} -/** - * Detect the best PRNG (pseudo-random number generator) - * @param root The root to check from (global/window) - * @returns The PRNG function - */ -function detectPRNG(root) { - const rootLookup = detectRoot(); - const globalCrypto = (rootLookup && (rootLookup.crypto || rootLookup.msCrypto)) || - (typeof crypto !== "undefined" ? crypto : null); - if (typeof globalCrypto?.getRandomValues === "function") { - return () => { - const buffer = new Uint8Array(1); - globalCrypto.getRandomValues(buffer); - return buffer[0] / 0xff; - }; - } - else if (typeof globalCrypto?.randomBytes === "function") { - return () => globalCrypto.randomBytes(1).readUInt8() / 0xff; - } - else if (crypto?.randomBytes) { - return () => crypto.randomBytes(1).readUInt8() / 0xff; - } - throw new ULIDError(ULIDErrorCode.PRNGDetectFailure, "Failed to find a reliable PRNG"); -} -function detectRoot() { - if (inWebWorker()) - return self; - if (typeof window !== "undefined") { - return window; - } - if (typeof global !== "undefined") { - return global; - } - if (typeof globalThis !== "undefined") { - return globalThis; - } - return null; -} -function encodeRandom(len, prng) { - let str = ""; - for (; len > 0; len--) { - str = randomChar(prng) + str; - } - return str; -} -/** - * Encode the time portion of a ULID - * @param now The current timestamp - * @param len Length to generate - * @returns The encoded time - */ -function encodeTime(now, len = TIME_LEN) { - if (isNaN(now)) { - throw new ULIDError(ULIDErrorCode.EncodeTimeValueMalformed, `Time must be a number: ${now}`); - } - else if (now > TIME_MAX) { - throw new ULIDError(ULIDErrorCode.EncodeTimeSizeExceeded, `Cannot encode a time larger than ${TIME_MAX}: ${now}`); - } - else if (now < 0) { - throw new ULIDError(ULIDErrorCode.EncodeTimeNegative, `Time must be positive: ${now}`); - } - else if (Number.isInteger(now) === false) { - throw new ULIDError(ULIDErrorCode.EncodeTimeValueMalformed, `Time must be an integer: ${now}`); - } - let mod, str = ""; - for (let currentLen = len; currentLen > 0; currentLen--) { - mod = now % ENCODING_LEN; - str = ENCODING.charAt(mod) + str; - now = (now - mod) / ENCODING_LEN; - } - return str; -} -function inWebWorker() { - // @ts-ignore - return typeof WorkerGlobalScope !== "undefined" && self instanceof WorkerGlobalScope; -} -/** - * Create a ULID factory to generate monotonically-increasing - * ULIDs - * @param prng The PRNG to use - * @returns A ulid factory - * @example - * const ulid = monotonicFactory(); - * ulid(); // "01HNZXD07M5CEN5XA66EMZSRZW" - */ -function monotonicFactory(prng) { - const currentPRNG = prng || detectPRNG(); - let lastTime = 0, lastRandom; - return function _ulid(seedTime) { - const seed = !seedTime || isNaN(seedTime) ? Date.now() : seedTime; - if (seed <= lastTime) { - const incrementedRandom = (lastRandom = incrementBase32(lastRandom)); - return encodeTime(lastTime, TIME_LEN) + incrementedRandom; - } - lastTime = seed; - const newRandom = (lastRandom = encodeRandom(RANDOM_LEN, currentPRNG)); - return encodeTime(seed, TIME_LEN) + newRandom; - }; -} - -var undici = {}; - -var symbols$4; -var hasRequiredSymbols$4; - -function requireSymbols$4 () { - if (hasRequiredSymbols$4) return symbols$4; - hasRequiredSymbols$4 = 1; - symbols$4 = { - kClose: Symbol('close'), - kDestroy: Symbol('destroy'), - kDispatch: Symbol('dispatch'), - kUrl: Symbol('url'), - kWriting: Symbol('writing'), - kResuming: Symbol('resuming'), - kQueue: Symbol('queue'), - kConnect: Symbol('connect'), - kConnecting: Symbol('connecting'), - kKeepAliveDefaultTimeout: Symbol('default keep alive timeout'), - kKeepAliveMaxTimeout: Symbol('max keep alive timeout'), - kKeepAliveTimeoutThreshold: Symbol('keep alive timeout threshold'), - kKeepAliveTimeoutValue: Symbol('keep alive timeout'), - kKeepAlive: Symbol('keep alive'), - kHeadersTimeout: Symbol('headers timeout'), - kBodyTimeout: Symbol('body timeout'), - kServerName: Symbol('server name'), - kLocalAddress: Symbol('local address'), - kHost: Symbol('host'), - kNoRef: Symbol('no ref'), - kBodyUsed: Symbol('used'), - kBody: Symbol('abstracted request body'), - kRunning: Symbol('running'), - kBlocking: Symbol('blocking'), - kPending: Symbol('pending'), - kSize: Symbol('size'), - kBusy: Symbol('busy'), - kQueued: Symbol('queued'), - kFree: Symbol('free'), - kConnected: Symbol('connected'), - kClosed: Symbol('closed'), - kNeedDrain: Symbol('need drain'), - kReset: Symbol('reset'), - kDestroyed: Symbol.for('nodejs.stream.destroyed'), - kResume: Symbol('resume'), - kOnError: Symbol('on error'), - kMaxHeadersSize: Symbol('max headers size'), - kRunningIdx: Symbol('running index'), - kPendingIdx: Symbol('pending index'), - kError: Symbol('error'), - kClients: Symbol('clients'), - kClient: Symbol('client'), - kParser: Symbol('parser'), - kOnDestroyed: Symbol('destroy callbacks'), - kPipelining: Symbol('pipelining'), - kSocket: Symbol('socket'), - kHostHeader: Symbol('host header'), - kConnector: Symbol('connector'), - kStrictContentLength: Symbol('strict content length'), - kMaxRedirections: Symbol('maxRedirections'), - kMaxRequests: Symbol('maxRequestsPerClient'), - kProxy: Symbol('proxy agent options'), - kCounter: Symbol('socket request counter'), - kInterceptors: Symbol('dispatch interceptors'), - kMaxResponseSize: Symbol('max response size'), - kHTTP2Session: Symbol('http2Session'), - kHTTP2SessionState: Symbol('http2Session state'), - kRetryHandlerDefaultRetry: Symbol('retry agent default retry'), - kConstruct: Symbol('constructable'), - kListeners: Symbol('listeners'), - kHTTPContext: Symbol('http context'), - kMaxConcurrentStreams: Symbol('max concurrent streams'), - kNoProxyAgent: Symbol('no proxy agent'), - kHttpProxyAgent: Symbol('http proxy agent'), - kHttpsProxyAgent: Symbol('https proxy agent') - }; - return symbols$4; -} - -var errors; -var hasRequiredErrors; - -function requireErrors () { - if (hasRequiredErrors) return errors; - hasRequiredErrors = 1; - - class UndiciError extends Error { - constructor (message) { - super(message); - this.name = 'UndiciError'; - this.code = 'UND_ERR'; - } - } - - class ConnectTimeoutError extends UndiciError { - constructor (message) { - super(message); - this.name = 'ConnectTimeoutError'; - this.message = message || 'Connect Timeout Error'; - this.code = 'UND_ERR_CONNECT_TIMEOUT'; - } - } - - class HeadersTimeoutError extends UndiciError { - constructor (message) { - super(message); - this.name = 'HeadersTimeoutError'; - this.message = message || 'Headers Timeout Error'; - this.code = 'UND_ERR_HEADERS_TIMEOUT'; - } - } - - class HeadersOverflowError extends UndiciError { - constructor (message) { - super(message); - this.name = 'HeadersOverflowError'; - this.message = message || 'Headers Overflow Error'; - this.code = 'UND_ERR_HEADERS_OVERFLOW'; - } - } - - class BodyTimeoutError extends UndiciError { - constructor (message) { - super(message); - this.name = 'BodyTimeoutError'; - this.message = message || 'Body Timeout Error'; - this.code = 'UND_ERR_BODY_TIMEOUT'; - } - } - - class ResponseStatusCodeError extends UndiciError { - constructor (message, statusCode, headers, body) { - super(message); - this.name = 'ResponseStatusCodeError'; - this.message = message || 'Response Status Code Error'; - this.code = 'UND_ERR_RESPONSE_STATUS_CODE'; - this.body = body; - this.status = statusCode; - this.statusCode = statusCode; - this.headers = headers; - } - } - - class InvalidArgumentError extends UndiciError { - constructor (message) { - super(message); - this.name = 'InvalidArgumentError'; - this.message = message || 'Invalid Argument Error'; - this.code = 'UND_ERR_INVALID_ARG'; - } - } - - class InvalidReturnValueError extends UndiciError { - constructor (message) { - super(message); - this.name = 'InvalidReturnValueError'; - this.message = message || 'Invalid Return Value Error'; - this.code = 'UND_ERR_INVALID_RETURN_VALUE'; - } - } - - class AbortError extends UndiciError { - constructor (message) { - super(message); - this.name = 'AbortError'; - this.message = message || 'The operation was aborted'; - } - } - - class RequestAbortedError extends AbortError { - constructor (message) { - super(message); - this.name = 'AbortError'; - this.message = message || 'Request aborted'; - this.code = 'UND_ERR_ABORTED'; - } - } - - class InformationalError extends UndiciError { - constructor (message) { - super(message); - this.name = 'InformationalError'; - this.message = message || 'Request information'; - this.code = 'UND_ERR_INFO'; - } - } - - class RequestContentLengthMismatchError extends UndiciError { - constructor (message) { - super(message); - this.name = 'RequestContentLengthMismatchError'; - this.message = message || 'Request body length does not match content-length header'; - this.code = 'UND_ERR_REQ_CONTENT_LENGTH_MISMATCH'; - } - } - - class ResponseContentLengthMismatchError extends UndiciError { - constructor (message) { - super(message); - this.name = 'ResponseContentLengthMismatchError'; - this.message = message || 'Response body length does not match content-length header'; - this.code = 'UND_ERR_RES_CONTENT_LENGTH_MISMATCH'; - } - } - - class ClientDestroyedError extends UndiciError { - constructor (message) { - super(message); - this.name = 'ClientDestroyedError'; - this.message = message || 'The client is destroyed'; - this.code = 'UND_ERR_DESTROYED'; - } - } - - class ClientClosedError extends UndiciError { - constructor (message) { - super(message); - this.name = 'ClientClosedError'; - this.message = message || 'The client is closed'; - this.code = 'UND_ERR_CLOSED'; - } - } - - class SocketError extends UndiciError { - constructor (message, socket) { - super(message); - this.name = 'SocketError'; - this.message = message || 'Socket error'; - this.code = 'UND_ERR_SOCKET'; - this.socket = socket; - } - } - - class NotSupportedError extends UndiciError { - constructor (message) { - super(message); - this.name = 'NotSupportedError'; - this.message = message || 'Not supported error'; - this.code = 'UND_ERR_NOT_SUPPORTED'; - } - } - - class BalancedPoolMissingUpstreamError extends UndiciError { - constructor (message) { - super(message); - this.name = 'MissingUpstreamError'; - this.message = message || 'No upstream has been added to the BalancedPool'; - this.code = 'UND_ERR_BPL_MISSING_UPSTREAM'; - } - } - - class HTTPParserError extends Error { - constructor (message, code, data) { - super(message); - this.name = 'HTTPParserError'; - this.code = code ? `HPE_${code}` : undefined; - this.data = data ? data.toString() : undefined; - } - } - - class ResponseExceededMaxSizeError extends UndiciError { - constructor (message) { - super(message); - this.name = 'ResponseExceededMaxSizeError'; - this.message = message || 'Response content exceeded max size'; - this.code = 'UND_ERR_RES_EXCEEDED_MAX_SIZE'; - } - } - - class RequestRetryError extends UndiciError { - constructor (message, code, { headers, data }) { - super(message); - this.name = 'RequestRetryError'; - this.message = message || 'Request retry error'; - this.code = 'UND_ERR_REQ_RETRY'; - this.statusCode = code; - this.data = data; - this.headers = headers; - } - } - - class SecureProxyConnectionError extends UndiciError { - constructor (cause, message, options) { - super(message, { cause, ...(options ?? {}) }); - this.name = 'SecureProxyConnectionError'; - this.message = message || 'Secure Proxy Connection failed'; - this.code = 'UND_ERR_PRX_TLS'; - this.cause = cause; - } - } - - errors = { - AbortError, - HTTPParserError, - UndiciError, - HeadersTimeoutError, - HeadersOverflowError, - BodyTimeoutError, - RequestContentLengthMismatchError, - ConnectTimeoutError, - ResponseStatusCodeError, - InvalidArgumentError, - InvalidReturnValueError, - RequestAbortedError, - ClientDestroyedError, - ClientClosedError, - InformationalError, - SocketError, - NotSupportedError, - ResponseContentLengthMismatchError, - BalancedPoolMissingUpstreamError, - ResponseExceededMaxSizeError, - RequestRetryError, - SecureProxyConnectionError - }; - return errors; -} - -var constants$4; -var hasRequiredConstants$4; - -function requireConstants$4 () { - if (hasRequiredConstants$4) return constants$4; - hasRequiredConstants$4 = 1; - - /** @type {Record} */ - const headerNameLowerCasedRecord = {}; - - // https://developer.mozilla.org/docs/Web/HTTP/Headers - const wellknownHeaderNames = [ - 'Accept', - 'Accept-Encoding', - 'Accept-Language', - 'Accept-Ranges', - 'Access-Control-Allow-Credentials', - 'Access-Control-Allow-Headers', - 'Access-Control-Allow-Methods', - 'Access-Control-Allow-Origin', - 'Access-Control-Expose-Headers', - 'Access-Control-Max-Age', - 'Access-Control-Request-Headers', - 'Access-Control-Request-Method', - 'Age', - 'Allow', - 'Alt-Svc', - 'Alt-Used', - 'Authorization', - 'Cache-Control', - 'Clear-Site-Data', - 'Connection', - 'Content-Disposition', - 'Content-Encoding', - 'Content-Language', - 'Content-Length', - 'Content-Location', - 'Content-Range', - 'Content-Security-Policy', - 'Content-Security-Policy-Report-Only', - 'Content-Type', - 'Cookie', - 'Cross-Origin-Embedder-Policy', - 'Cross-Origin-Opener-Policy', - 'Cross-Origin-Resource-Policy', - 'Date', - 'Device-Memory', - 'Downlink', - 'ECT', - 'ETag', - 'Expect', - 'Expect-CT', - 'Expires', - 'Forwarded', - 'From', - 'Host', - 'If-Match', - 'If-Modified-Since', - 'If-None-Match', - 'If-Range', - 'If-Unmodified-Since', - 'Keep-Alive', - 'Last-Modified', - 'Link', - 'Location', - 'Max-Forwards', - 'Origin', - 'Permissions-Policy', - 'Pragma', - 'Proxy-Authenticate', - 'Proxy-Authorization', - 'RTT', - 'Range', - 'Referer', - 'Referrer-Policy', - 'Refresh', - 'Retry-After', - 'Sec-WebSocket-Accept', - 'Sec-WebSocket-Extensions', - 'Sec-WebSocket-Key', - 'Sec-WebSocket-Protocol', - 'Sec-WebSocket-Version', - 'Server', - 'Server-Timing', - 'Service-Worker-Allowed', - 'Service-Worker-Navigation-Preload', - 'Set-Cookie', - 'SourceMap', - 'Strict-Transport-Security', - 'Supports-Loading-Mode', - 'TE', - 'Timing-Allow-Origin', - 'Trailer', - 'Transfer-Encoding', - 'Upgrade', - 'Upgrade-Insecure-Requests', - 'User-Agent', - 'Vary', - 'Via', - 'WWW-Authenticate', - 'X-Content-Type-Options', - 'X-DNS-Prefetch-Control', - 'X-Frame-Options', - 'X-Permitted-Cross-Domain-Policies', - 'X-Powered-By', - 'X-Requested-With', - 'X-XSS-Protection' - ]; - - for (let i = 0; i < wellknownHeaderNames.length; ++i) { - const key = wellknownHeaderNames[i]; - const lowerCasedKey = key.toLowerCase(); - headerNameLowerCasedRecord[key] = headerNameLowerCasedRecord[lowerCasedKey] = - lowerCasedKey; - } - - // Note: object prototypes should not be able to be referenced. e.g. `Object#hasOwnProperty`. - Object.setPrototypeOf(headerNameLowerCasedRecord, null); - - constants$4 = { - wellknownHeaderNames, - headerNameLowerCasedRecord - }; - return constants$4; -} - -var tree_1; -var hasRequiredTree; - -function requireTree () { - if (hasRequiredTree) return tree_1; - hasRequiredTree = 1; - - const { - wellknownHeaderNames, - headerNameLowerCasedRecord - } = requireConstants$4(); - - class TstNode { - /** @type {any} */ - value = null - /** @type {null | TstNode} */ - left = null - /** @type {null | TstNode} */ - middle = null - /** @type {null | TstNode} */ - right = null - /** @type {number} */ - code - /** - * @param {string} key - * @param {any} value - * @param {number} index - */ - constructor (key, value, index) { - if (index === undefined || index >= key.length) { - throw new TypeError('Unreachable') - } - const code = this.code = key.charCodeAt(index); - // check code is ascii string - if (code > 0x7F) { - throw new TypeError('key must be ascii string') - } - if (key.length !== ++index) { - this.middle = new TstNode(key, value, index); - } else { - this.value = value; - } - } - - /** - * @param {string} key - * @param {any} value - */ - add (key, value) { - const length = key.length; - if (length === 0) { - throw new TypeError('Unreachable') - } - let index = 0; - let node = this; - while (true) { - const code = key.charCodeAt(index); - // check code is ascii string - if (code > 0x7F) { - throw new TypeError('key must be ascii string') - } - if (node.code === code) { - if (length === ++index) { - node.value = value; - break - } else if (node.middle !== null) { - node = node.middle; - } else { - node.middle = new TstNode(key, value, index); - break - } - } else if (node.code < code) { - if (node.left !== null) { - node = node.left; - } else { - node.left = new TstNode(key, value, index); - break - } - } else if (node.right !== null) { - node = node.right; - } else { - node.right = new TstNode(key, value, index); - break - } - } - } - - /** - * @param {Uint8Array} key - * @return {TstNode | null} - */ - search (key) { - const keylength = key.length; - let index = 0; - let node = this; - while (node !== null && index < keylength) { - let code = key[index]; - // A-Z - // First check if it is bigger than 0x5a. - // Lowercase letters have higher char codes than uppercase ones. - // Also we assume that headers will mostly contain lowercase characters. - if (code <= 0x5a && code >= 0x41) { - // Lowercase for uppercase. - code |= 32; - } - while (node !== null) { - if (code === node.code) { - if (keylength === ++index) { - // Returns Node since it is the last key. - return node - } - node = node.middle; - break - } - node = node.code < code ? node.left : node.right; - } - } - return null - } - } - - class TernarySearchTree { - /** @type {TstNode | null} */ - node = null - - /** - * @param {string} key - * @param {any} value - * */ - insert (key, value) { - if (this.node === null) { - this.node = new TstNode(key, value, 0); - } else { - this.node.add(key, value); - } - } - - /** - * @param {Uint8Array} key - * @return {any} - */ - lookup (key) { - return this.node?.search(key)?.value ?? null - } - } - - const tree = new TernarySearchTree(); - - for (let i = 0; i < wellknownHeaderNames.length; ++i) { - const key = headerNameLowerCasedRecord[wellknownHeaderNames[i]]; - tree.insert(key, key); - } - - tree_1 = { - TernarySearchTree, - tree - }; - return tree_1; -} - -var util$7; -var hasRequiredUtil$7; - -function requireUtil$7 () { - if (hasRequiredUtil$7) return util$7; - hasRequiredUtil$7 = 1; - - const assert = require$$0$4; - const { kDestroyed, kBodyUsed, kListeners, kBody } = requireSymbols$4(); - const { IncomingMessage } = require$$2; - const stream = require$$0$5; - const net = require$$4; - const { Blob } = require$$0$3; - const nodeUtil = require$$0$6; - const { stringify } = require$$7; - const { EventEmitter: EE } = require$$8; - const { InvalidArgumentError } = requireErrors(); - const { headerNameLowerCasedRecord } = requireConstants$4(); - const { tree } = requireTree(); - - const [nodeMajor, nodeMinor] = process.versions.node.split('.').map(v => Number(v)); - - class BodyAsyncIterable { - constructor (body) { - this[kBody] = body; - this[kBodyUsed] = false; - } - - async * [Symbol.asyncIterator] () { - assert(!this[kBodyUsed], 'disturbed'); - this[kBodyUsed] = true; - yield * this[kBody]; - } - } - - function wrapRequestBody (body) { - if (isStream(body)) { - // TODO (fix): Provide some way for the user to cache the file to e.g. /tmp - // so that it can be dispatched again? - // TODO (fix): Do we need 100-expect support to provide a way to do this properly? - if (bodyLength(body) === 0) { - body - .on('data', function () { - assert(false); - }); - } - - if (typeof body.readableDidRead !== 'boolean') { - body[kBodyUsed] = false; - EE.prototype.on.call(body, 'data', function () { - this[kBodyUsed] = true; - }); - } - - return body - } else if (body && typeof body.pipeTo === 'function') { - // TODO (fix): We can't access ReadableStream internal state - // to determine whether or not it has been disturbed. This is just - // a workaround. - return new BodyAsyncIterable(body) - } else if ( - body && - typeof body !== 'string' && - !ArrayBuffer.isView(body) && - isIterable(body) - ) { - // TODO: Should we allow re-using iterable if !this.opts.idempotent - // or through some other flag? - return new BodyAsyncIterable(body) - } else { - return body - } - } - - function nop () {} - - function isStream (obj) { - return obj && typeof obj === 'object' && typeof obj.pipe === 'function' && typeof obj.on === 'function' - } - - // based on https://github.com/node-fetch/fetch-blob/blob/8ab587d34080de94140b54f07168451e7d0b655e/index.js#L229-L241 (MIT License) - function isBlobLike (object) { - if (object === null) { - return false - } else if (object instanceof Blob) { - return true - } else if (typeof object !== 'object') { - return false - } else { - const sTag = object[Symbol.toStringTag]; - - return (sTag === 'Blob' || sTag === 'File') && ( - ('stream' in object && typeof object.stream === 'function') || - ('arrayBuffer' in object && typeof object.arrayBuffer === 'function') - ) - } - } - - function buildURL (url, queryParams) { - if (url.includes('?') || url.includes('#')) { - throw new Error('Query params cannot be passed when url already contains "?" or "#".') - } - - const stringified = stringify(queryParams); - - if (stringified) { - url += '?' + stringified; - } - - return url - } - - function isValidPort (port) { - const value = parseInt(port, 10); - return ( - value === Number(port) && - value >= 0 && - value <= 65535 - ) - } - - function isHttpOrHttpsPrefixed (value) { - return ( - value != null && - value[0] === 'h' && - value[1] === 't' && - value[2] === 't' && - value[3] === 'p' && - ( - value[4] === ':' || - ( - value[4] === 's' && - value[5] === ':' - ) - ) - ) - } - - function parseURL (url) { - if (typeof url === 'string') { - url = new URL(url); - - if (!isHttpOrHttpsPrefixed(url.origin || url.protocol)) { - throw new InvalidArgumentError('Invalid URL protocol: the URL must start with `http:` or `https:`.') - } - - return url - } - - if (!url || typeof url !== 'object') { - throw new InvalidArgumentError('Invalid URL: The URL argument must be a non-null object.') - } - - if (!(url instanceof URL)) { - if (url.port != null && url.port !== '' && isValidPort(url.port) === false) { - throw new InvalidArgumentError('Invalid URL: port must be a valid integer or a string representation of an integer.') - } - - if (url.path != null && typeof url.path !== 'string') { - throw new InvalidArgumentError('Invalid URL path: the path must be a string or null/undefined.') - } - - if (url.pathname != null && typeof url.pathname !== 'string') { - throw new InvalidArgumentError('Invalid URL pathname: the pathname must be a string or null/undefined.') - } - - if (url.hostname != null && typeof url.hostname !== 'string') { - throw new InvalidArgumentError('Invalid URL hostname: the hostname must be a string or null/undefined.') - } - - if (url.origin != null && typeof url.origin !== 'string') { - throw new InvalidArgumentError('Invalid URL origin: the origin must be a string or null/undefined.') - } - - if (!isHttpOrHttpsPrefixed(url.origin || url.protocol)) { - throw new InvalidArgumentError('Invalid URL protocol: the URL must start with `http:` or `https:`.') - } - - const port = url.port != null - ? url.port - : (url.protocol === 'https:' ? 443 : 80); - let origin = url.origin != null - ? url.origin - : `${url.protocol || ''}//${url.hostname || ''}:${port}`; - let path = url.path != null - ? url.path - : `${url.pathname || ''}${url.search || ''}`; - - if (origin[origin.length - 1] === '/') { - origin = origin.slice(0, origin.length - 1); - } - - if (path && path[0] !== '/') { - path = `/${path}`; - } - // new URL(path, origin) is unsafe when `path` contains an absolute URL - // From https://developer.mozilla.org/en-US/docs/Web/API/URL/URL: - // If first parameter is a relative URL, second param is required, and will be used as the base URL. - // If first parameter is an absolute URL, a given second param will be ignored. - return new URL(`${origin}${path}`) - } - - if (!isHttpOrHttpsPrefixed(url.origin || url.protocol)) { - throw new InvalidArgumentError('Invalid URL protocol: the URL must start with `http:` or `https:`.') - } - - return url - } - - function parseOrigin (url) { - url = parseURL(url); - - if (url.pathname !== '/' || url.search || url.hash) { - throw new InvalidArgumentError('invalid url') - } - - return url - } - - function getHostname (host) { - if (host[0] === '[') { - const idx = host.indexOf(']'); - - assert(idx !== -1); - return host.substring(1, idx) - } - - const idx = host.indexOf(':'); - if (idx === -1) return host - - return host.substring(0, idx) - } - - // IP addresses are not valid server names per RFC6066 - // > Currently, the only server names supported are DNS hostnames - function getServerName (host) { - if (!host) { - return null - } - - assert.strictEqual(typeof host, 'string'); - - const servername = getHostname(host); - if (net.isIP(servername)) { - return '' - } - - return servername - } - - function deepClone (obj) { - return JSON.parse(JSON.stringify(obj)) - } - - function isAsyncIterable (obj) { - return !!(obj != null && typeof obj[Symbol.asyncIterator] === 'function') - } - - function isIterable (obj) { - return !!(obj != null && (typeof obj[Symbol.iterator] === 'function' || typeof obj[Symbol.asyncIterator] === 'function')) - } - - function bodyLength (body) { - if (body == null) { - return 0 - } else if (isStream(body)) { - const state = body._readableState; - return state && state.objectMode === false && state.ended === true && Number.isFinite(state.length) - ? state.length - : null - } else if (isBlobLike(body)) { - return body.size != null ? body.size : null - } else if (isBuffer(body)) { - return body.byteLength - } - - return null - } - - function isDestroyed (body) { - return body && !!(body.destroyed || body[kDestroyed] || (stream.isDestroyed?.(body))) - } - - function destroy (stream, err) { - if (stream == null || !isStream(stream) || isDestroyed(stream)) { - return - } - - if (typeof stream.destroy === 'function') { - if (Object.getPrototypeOf(stream).constructor === IncomingMessage) { - // See: https://github.com/nodejs/node/pull/38505/files - stream.socket = null; - } - - stream.destroy(err); - } else if (err) { - queueMicrotask(() => { - stream.emit('error', err); - }); - } - - if (stream.destroyed !== true) { - stream[kDestroyed] = true; - } - } - - const KEEPALIVE_TIMEOUT_EXPR = /timeout=(\d+)/; - function parseKeepAliveTimeout (val) { - const m = val.toString().match(KEEPALIVE_TIMEOUT_EXPR); - return m ? parseInt(m[1], 10) * 1000 : null - } - - /** - * Retrieves a header name and returns its lowercase value. - * @param {string | Buffer} value Header name - * @returns {string} - */ - function headerNameToString (value) { - return typeof value === 'string' - ? headerNameLowerCasedRecord[value] ?? value.toLowerCase() - : tree.lookup(value) ?? value.toString('latin1').toLowerCase() - } - - /** - * Receive the buffer as a string and return its lowercase value. - * @param {Buffer} value Header name - * @returns {string} - */ - function bufferToLowerCasedHeaderName (value) { - return tree.lookup(value) ?? value.toString('latin1').toLowerCase() - } - - /** - * @param {Record | (Buffer | string | (Buffer | string)[])[]} headers - * @param {Record} [obj] - * @returns {Record} - */ - function parseHeaders (headers, obj) { - if (obj === undefined) obj = {}; - for (let i = 0; i < headers.length; i += 2) { - const key = headerNameToString(headers[i]); - let val = obj[key]; - - if (val) { - if (typeof val === 'string') { - val = [val]; - obj[key] = val; - } - val.push(headers[i + 1].toString('utf8')); - } else { - const headersValue = headers[i + 1]; - if (typeof headersValue === 'string') { - obj[key] = headersValue; - } else { - obj[key] = Array.isArray(headersValue) ? headersValue.map(x => x.toString('utf8')) : headersValue.toString('utf8'); - } - } - } - - // See https://github.com/nodejs/node/pull/46528 - if ('content-length' in obj && 'content-disposition' in obj) { - obj['content-disposition'] = Buffer.from(obj['content-disposition']).toString('latin1'); - } - - return obj - } - - function parseRawHeaders (headers) { - const len = headers.length; - const ret = new Array(len); - - let hasContentLength = false; - let contentDispositionIdx = -1; - let key; - let val; - let kLen = 0; - - for (let n = 0; n < headers.length; n += 2) { - key = headers[n]; - val = headers[n + 1]; - - typeof key !== 'string' && (key = key.toString()); - typeof val !== 'string' && (val = val.toString('utf8')); - - kLen = key.length; - if (kLen === 14 && key[7] === '-' && (key === 'content-length' || key.toLowerCase() === 'content-length')) { - hasContentLength = true; - } else if (kLen === 19 && key[7] === '-' && (key === 'content-disposition' || key.toLowerCase() === 'content-disposition')) { - contentDispositionIdx = n + 1; - } - ret[n] = key; - ret[n + 1] = val; - } - - // See https://github.com/nodejs/node/pull/46528 - if (hasContentLength && contentDispositionIdx !== -1) { - ret[contentDispositionIdx] = Buffer.from(ret[contentDispositionIdx]).toString('latin1'); - } - - return ret - } - - function isBuffer (buffer) { - // See, https://github.com/mcollina/undici/pull/319 - return buffer instanceof Uint8Array || Buffer.isBuffer(buffer) - } - - function validateHandler (handler, method, upgrade) { - if (!handler || typeof handler !== 'object') { - throw new InvalidArgumentError('handler must be an object') - } - - if (typeof handler.onConnect !== 'function') { - throw new InvalidArgumentError('invalid onConnect method') - } - - if (typeof handler.onError !== 'function') { - throw new InvalidArgumentError('invalid onError method') - } - - if (typeof handler.onBodySent !== 'function' && handler.onBodySent !== undefined) { - throw new InvalidArgumentError('invalid onBodySent method') - } - - if (upgrade || method === 'CONNECT') { - if (typeof handler.onUpgrade !== 'function') { - throw new InvalidArgumentError('invalid onUpgrade method') - } - } else { - if (typeof handler.onHeaders !== 'function') { - throw new InvalidArgumentError('invalid onHeaders method') - } - - if (typeof handler.onData !== 'function') { - throw new InvalidArgumentError('invalid onData method') - } - - if (typeof handler.onComplete !== 'function') { - throw new InvalidArgumentError('invalid onComplete method') - } - } - } - - // A body is disturbed if it has been read from and it cannot - // be re-used without losing state or data. - function isDisturbed (body) { - // TODO (fix): Why is body[kBodyUsed] needed? - return !!(body && (stream.isDisturbed(body) || body[kBodyUsed])) - } - - function isErrored (body) { - return !!(body && stream.isErrored(body)) - } - - function isReadable (body) { - return !!(body && stream.isReadable(body)) - } - - function getSocketInfo (socket) { - return { - localAddress: socket.localAddress, - localPort: socket.localPort, - remoteAddress: socket.remoteAddress, - remotePort: socket.remotePort, - remoteFamily: socket.remoteFamily, - timeout: socket.timeout, - bytesWritten: socket.bytesWritten, - bytesRead: socket.bytesRead - } - } - - /** @type {globalThis['ReadableStream']} */ - function ReadableStreamFrom (iterable) { - // We cannot use ReadableStream.from here because it does not return a byte stream. - - let iterator; - return new ReadableStream( - { - async start () { - iterator = iterable[Symbol.asyncIterator](); - }, - async pull (controller) { - const { done, value } = await iterator.next(); - if (done) { - queueMicrotask(() => { - controller.close(); - controller.byobRequest?.respond(0); - }); - } else { - const buf = Buffer.isBuffer(value) ? value : Buffer.from(value); - if (buf.byteLength) { - controller.enqueue(new Uint8Array(buf)); - } - } - return controller.desiredSize > 0 - }, - async cancel (reason) { - await iterator.return(); - }, - type: 'bytes' - } - ) - } - - // The chunk should be a FormData instance and contains - // all the required methods. - function isFormDataLike (object) { - return ( - object && - typeof object === 'object' && - typeof object.append === 'function' && - typeof object.delete === 'function' && - typeof object.get === 'function' && - typeof object.getAll === 'function' && - typeof object.has === 'function' && - typeof object.set === 'function' && - object[Symbol.toStringTag] === 'FormData' - ) - } - - function addAbortListener (signal, listener) { - if ('addEventListener' in signal) { - signal.addEventListener('abort', listener, { once: true }); - return () => signal.removeEventListener('abort', listener) - } - signal.addListener('abort', listener); - return () => signal.removeListener('abort', listener) - } - - const hasToWellFormed = typeof String.prototype.toWellFormed === 'function'; - const hasIsWellFormed = typeof String.prototype.isWellFormed === 'function'; - - /** - * @param {string} val - */ - function toUSVString (val) { - return hasToWellFormed ? `${val}`.toWellFormed() : nodeUtil.toUSVString(val) - } - - /** - * @param {string} val - */ - // TODO: move this to webidl - function isUSVString (val) { - return hasIsWellFormed ? `${val}`.isWellFormed() : toUSVString(val) === `${val}` - } - - /** - * @see https://tools.ietf.org/html/rfc7230#section-3.2.6 - * @param {number} c - */ - function isTokenCharCode (c) { - switch (c) { - case 0x22: - case 0x28: - case 0x29: - case 0x2c: - case 0x2f: - case 0x3a: - case 0x3b: - case 0x3c: - case 0x3d: - case 0x3e: - case 0x3f: - case 0x40: - case 0x5b: - case 0x5c: - case 0x5d: - case 0x7b: - case 0x7d: - // DQUOTE and "(),/:;<=>?@[\]{}" - return false - default: - // VCHAR %x21-7E - return c >= 0x21 && c <= 0x7e - } - } - - /** - * @param {string} characters - */ - function isValidHTTPToken (characters) { - if (characters.length === 0) { - return false - } - for (let i = 0; i < characters.length; ++i) { - if (!isTokenCharCode(characters.charCodeAt(i))) { - return false - } - } - return true - } - - // headerCharRegex have been lifted from - // https://github.com/nodejs/node/blob/main/lib/_http_common.js - - /** - * Matches if val contains an invalid field-vchar - * field-value = *( field-content / obs-fold ) - * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] - * field-vchar = VCHAR / obs-text - */ - const headerCharRegex = /[^\t\x20-\x7e\x80-\xff]/; - - /** - * @param {string} characters - */ - function isValidHeaderValue (characters) { - return !headerCharRegex.test(characters) - } - - // Parsed accordingly to RFC 9110 - // https://www.rfc-editor.org/rfc/rfc9110#field.content-range - function parseRangeHeader (range) { - if (range == null || range === '') return { start: 0, end: null, size: null } - - const m = range ? range.match(/^bytes (\d+)-(\d+)\/(\d+)?$/) : null; - return m - ? { - start: parseInt(m[1]), - end: m[2] ? parseInt(m[2]) : null, - size: m[3] ? parseInt(m[3]) : null - } - : null - } - - function addListener (obj, name, listener) { - const listeners = (obj[kListeners] ??= []); - listeners.push([name, listener]); - obj.on(name, listener); - return obj - } - - function removeAllListeners (obj) { - for (const [name, listener] of obj[kListeners] ?? []) { - obj.removeListener(name, listener); - } - obj[kListeners] = null; - } - - function errorRequest (client, request, err) { - try { - request.onError(err); - assert(request.aborted); - } catch (err) { - client.emit('error', err); - } - } - - const kEnumerableProperty = Object.create(null); - kEnumerableProperty.enumerable = true; - - const normalizedMethodRecordsBase = { - delete: 'DELETE', - DELETE: 'DELETE', - get: 'GET', - GET: 'GET', - head: 'HEAD', - HEAD: 'HEAD', - options: 'OPTIONS', - OPTIONS: 'OPTIONS', - post: 'POST', - POST: 'POST', - put: 'PUT', - PUT: 'PUT' - }; - - const normalizedMethodRecords = { - ...normalizedMethodRecordsBase, - patch: 'patch', - PATCH: 'PATCH' - }; - - // Note: object prototypes should not be able to be referenced. e.g. `Object#hasOwnProperty`. - Object.setPrototypeOf(normalizedMethodRecordsBase, null); - Object.setPrototypeOf(normalizedMethodRecords, null); - - util$7 = { - kEnumerableProperty, - nop, - isDisturbed, - isErrored, - isReadable, - toUSVString, - isUSVString, - isBlobLike, - parseOrigin, - parseURL, - getServerName, - isStream, - isIterable, - isAsyncIterable, - isDestroyed, - headerNameToString, - bufferToLowerCasedHeaderName, - addListener, - removeAllListeners, - errorRequest, - parseRawHeaders, - parseHeaders, - parseKeepAliveTimeout, - destroy, - bodyLength, - deepClone, - ReadableStreamFrom, - isBuffer, - validateHandler, - getSocketInfo, - isFormDataLike, - buildURL, - addAbortListener, - isValidHTTPToken, - isValidHeaderValue, - isTokenCharCode, - parseRangeHeader, - normalizedMethodRecordsBase, - normalizedMethodRecords, - isValidPort, - isHttpOrHttpsPrefixed, - nodeMajor, - nodeMinor, - safeHTTPMethods: ['GET', 'HEAD', 'OPTIONS', 'TRACE'], - wrapRequestBody - }; - return util$7; -} - -var diagnostics; -var hasRequiredDiagnostics; - -function requireDiagnostics () { - if (hasRequiredDiagnostics) return diagnostics; - hasRequiredDiagnostics = 1; - const diagnosticsChannel = require$$0$7; - const util = require$$0$6; - - const undiciDebugLog = util.debuglog('undici'); - const fetchDebuglog = util.debuglog('fetch'); - const websocketDebuglog = util.debuglog('websocket'); - let isClientSet = false; - const channels = { - // Client - beforeConnect: diagnosticsChannel.channel('undici:client:beforeConnect'), - connected: diagnosticsChannel.channel('undici:client:connected'), - connectError: diagnosticsChannel.channel('undici:client:connectError'), - sendHeaders: diagnosticsChannel.channel('undici:client:sendHeaders'), - // Request - create: diagnosticsChannel.channel('undici:request:create'), - bodySent: diagnosticsChannel.channel('undici:request:bodySent'), - headers: diagnosticsChannel.channel('undici:request:headers'), - trailers: diagnosticsChannel.channel('undici:request:trailers'), - error: diagnosticsChannel.channel('undici:request:error'), - // WebSocket - open: diagnosticsChannel.channel('undici:websocket:open'), - close: diagnosticsChannel.channel('undici:websocket:close'), - socketError: diagnosticsChannel.channel('undici:websocket:socket_error'), - ping: diagnosticsChannel.channel('undici:websocket:ping'), - pong: diagnosticsChannel.channel('undici:websocket:pong') - }; - - if (undiciDebugLog.enabled || fetchDebuglog.enabled) { - const debuglog = fetchDebuglog.enabled ? fetchDebuglog : undiciDebugLog; - - // Track all Client events - diagnosticsChannel.channel('undici:client:beforeConnect').subscribe(evt => { - const { - connectParams: { version, protocol, port, host } - } = evt; - debuglog( - 'connecting to %s using %s%s', - `${host}${port ? `:${port}` : ''}`, - protocol, - version - ); - }); - - diagnosticsChannel.channel('undici:client:connected').subscribe(evt => { - const { - connectParams: { version, protocol, port, host } - } = evt; - debuglog( - 'connected to %s using %s%s', - `${host}${port ? `:${port}` : ''}`, - protocol, - version - ); - }); - - diagnosticsChannel.channel('undici:client:connectError').subscribe(evt => { - const { - connectParams: { version, protocol, port, host }, - error - } = evt; - debuglog( - 'connection to %s using %s%s errored - %s', - `${host}${port ? `:${port}` : ''}`, - protocol, - version, - error.message - ); - }); - - diagnosticsChannel.channel('undici:client:sendHeaders').subscribe(evt => { - const { - request: { method, path, origin } - } = evt; - debuglog('sending request to %s %s/%s', method, origin, path); - }); - - // Track Request events - diagnosticsChannel.channel('undici:request:headers').subscribe(evt => { - const { - request: { method, path, origin }, - response: { statusCode } - } = evt; - debuglog( - 'received response to %s %s/%s - HTTP %d', - method, - origin, - path, - statusCode - ); - }); - - diagnosticsChannel.channel('undici:request:trailers').subscribe(evt => { - const { - request: { method, path, origin } - } = evt; - debuglog('trailers received from %s %s/%s', method, origin, path); - }); - - diagnosticsChannel.channel('undici:request:error').subscribe(evt => { - const { - request: { method, path, origin }, - error - } = evt; - debuglog( - 'request to %s %s/%s errored - %s', - method, - origin, - path, - error.message - ); - }); - - isClientSet = true; - } - - if (websocketDebuglog.enabled) { - if (!isClientSet) { - const debuglog = undiciDebugLog.enabled ? undiciDebugLog : websocketDebuglog; - diagnosticsChannel.channel('undici:client:beforeConnect').subscribe(evt => { - const { - connectParams: { version, protocol, port, host } - } = evt; - debuglog( - 'connecting to %s%s using %s%s', - host, - port ? `:${port}` : '', - protocol, - version - ); - }); - - diagnosticsChannel.channel('undici:client:connected').subscribe(evt => { - const { - connectParams: { version, protocol, port, host } - } = evt; - debuglog( - 'connected to %s%s using %s%s', - host, - port ? `:${port}` : '', - protocol, - version - ); - }); - - diagnosticsChannel.channel('undici:client:connectError').subscribe(evt => { - const { - connectParams: { version, protocol, port, host }, - error - } = evt; - debuglog( - 'connection to %s%s using %s%s errored - %s', - host, - port ? `:${port}` : '', - protocol, - version, - error.message - ); - }); - - diagnosticsChannel.channel('undici:client:sendHeaders').subscribe(evt => { - const { - request: { method, path, origin } - } = evt; - debuglog('sending request to %s %s/%s', method, origin, path); - }); - } - - // Track all WebSocket events - diagnosticsChannel.channel('undici:websocket:open').subscribe(evt => { - const { - address: { address, port } - } = evt; - websocketDebuglog('connection opened %s%s', address, port ? `:${port}` : ''); - }); - - diagnosticsChannel.channel('undici:websocket:close').subscribe(evt => { - const { websocket, code, reason } = evt; - websocketDebuglog( - 'closed connection to %s - %s %s', - websocket.url, - code, - reason - ); - }); - - diagnosticsChannel.channel('undici:websocket:socket_error').subscribe(err => { - websocketDebuglog('connection errored - %s', err.message); - }); - - diagnosticsChannel.channel('undici:websocket:ping').subscribe(evt => { - websocketDebuglog('ping received'); - }); - - diagnosticsChannel.channel('undici:websocket:pong').subscribe(evt => { - websocketDebuglog('pong received'); - }); - } - - diagnostics = { - channels - }; - return diagnostics; -} - -var request$1; -var hasRequiredRequest$1; - -function requireRequest$1 () { - if (hasRequiredRequest$1) return request$1; - hasRequiredRequest$1 = 1; - - const { - InvalidArgumentError, - NotSupportedError - } = requireErrors(); - const assert = require$$0$4; - const { - isValidHTTPToken, - isValidHeaderValue, - isStream, - destroy, - isBuffer, - isFormDataLike, - isIterable, - isBlobLike, - buildURL, - validateHandler, - getServerName, - normalizedMethodRecords - } = requireUtil$7(); - const { channels } = requireDiagnostics(); - const { headerNameLowerCasedRecord } = requireConstants$4(); - - // Verifies that a given path is valid does not contain control chars \x00 to \x20 - const invalidPathRegex = /[^\u0021-\u00ff]/; - - const kHandler = Symbol('handler'); - - class Request { - constructor (origin, { - path, - method, - body, - headers, - query, - idempotent, - blocking, - upgrade, - headersTimeout, - bodyTimeout, - reset, - throwOnError, - expectContinue, - servername - }, handler) { - if (typeof path !== 'string') { - throw new InvalidArgumentError('path must be a string') - } else if ( - path[0] !== '/' && - !(path.startsWith('http://') || path.startsWith('https://')) && - method !== 'CONNECT' - ) { - throw new InvalidArgumentError('path must be an absolute URL or start with a slash') - } else if (invalidPathRegex.test(path)) { - throw new InvalidArgumentError('invalid request path') - } - - if (typeof method !== 'string') { - throw new InvalidArgumentError('method must be a string') - } else if (normalizedMethodRecords[method] === undefined && !isValidHTTPToken(method)) { - throw new InvalidArgumentError('invalid request method') - } - - if (upgrade && typeof upgrade !== 'string') { - throw new InvalidArgumentError('upgrade must be a string') - } - - if (headersTimeout != null && (!Number.isFinite(headersTimeout) || headersTimeout < 0)) { - throw new InvalidArgumentError('invalid headersTimeout') - } - - if (bodyTimeout != null && (!Number.isFinite(bodyTimeout) || bodyTimeout < 0)) { - throw new InvalidArgumentError('invalid bodyTimeout') - } - - if (reset != null && typeof reset !== 'boolean') { - throw new InvalidArgumentError('invalid reset') - } - - if (expectContinue != null && typeof expectContinue !== 'boolean') { - throw new InvalidArgumentError('invalid expectContinue') - } - - this.headersTimeout = headersTimeout; - - this.bodyTimeout = bodyTimeout; - - this.throwOnError = throwOnError === true; - - this.method = method; - - this.abort = null; - - if (body == null) { - this.body = null; - } else if (isStream(body)) { - this.body = body; - - const rState = this.body._readableState; - if (!rState || !rState.autoDestroy) { - this.endHandler = function autoDestroy () { - destroy(this); - }; - this.body.on('end', this.endHandler); - } - - this.errorHandler = err => { - if (this.abort) { - this.abort(err); - } else { - this.error = err; - } - }; - this.body.on('error', this.errorHandler); - } else if (isBuffer(body)) { - this.body = body.byteLength ? body : null; - } else if (ArrayBuffer.isView(body)) { - this.body = body.buffer.byteLength ? Buffer.from(body.buffer, body.byteOffset, body.byteLength) : null; - } else if (body instanceof ArrayBuffer) { - this.body = body.byteLength ? Buffer.from(body) : null; - } else if (typeof body === 'string') { - this.body = body.length ? Buffer.from(body) : null; - } else if (isFormDataLike(body) || isIterable(body) || isBlobLike(body)) { - this.body = body; - } else { - throw new InvalidArgumentError('body must be a string, a Buffer, a Readable stream, an iterable, or an async iterable') - } - - this.completed = false; - - this.aborted = false; - - this.upgrade = upgrade || null; - - this.path = query ? buildURL(path, query) : path; - - this.origin = origin; - - this.idempotent = idempotent == null - ? method === 'HEAD' || method === 'GET' - : idempotent; - - this.blocking = blocking == null ? false : blocking; - - this.reset = reset == null ? null : reset; - - this.host = null; - - this.contentLength = null; - - this.contentType = null; - - this.headers = []; - - // Only for H2 - this.expectContinue = expectContinue != null ? expectContinue : false; - - if (Array.isArray(headers)) { - if (headers.length % 2 !== 0) { - throw new InvalidArgumentError('headers array must be even') - } - for (let i = 0; i < headers.length; i += 2) { - processHeader(this, headers[i], headers[i + 1]); - } - } else if (headers && typeof headers === 'object') { - if (headers[Symbol.iterator]) { - for (const header of headers) { - if (!Array.isArray(header) || header.length !== 2) { - throw new InvalidArgumentError('headers must be in key-value pair format') - } - processHeader(this, header[0], header[1]); - } - } else { - const keys = Object.keys(headers); - for (let i = 0; i < keys.length; ++i) { - processHeader(this, keys[i], headers[keys[i]]); - } - } - } else if (headers != null) { - throw new InvalidArgumentError('headers must be an object or an array') - } - - validateHandler(handler, method, upgrade); - - this.servername = servername || getServerName(this.host); - - this[kHandler] = handler; - - if (channels.create.hasSubscribers) { - channels.create.publish({ request: this }); - } - } - - onBodySent (chunk) { - if (this[kHandler].onBodySent) { - try { - return this[kHandler].onBodySent(chunk) - } catch (err) { - this.abort(err); - } - } - } - - onRequestSent () { - if (channels.bodySent.hasSubscribers) { - channels.bodySent.publish({ request: this }); - } - - if (this[kHandler].onRequestSent) { - try { - return this[kHandler].onRequestSent() - } catch (err) { - this.abort(err); - } - } - } - - onConnect (abort) { - assert(!this.aborted); - assert(!this.completed); - - if (this.error) { - abort(this.error); - } else { - this.abort = abort; - return this[kHandler].onConnect(abort) - } - } - - onResponseStarted () { - return this[kHandler].onResponseStarted?.() - } - - onHeaders (statusCode, headers, resume, statusText) { - assert(!this.aborted); - assert(!this.completed); - - if (channels.headers.hasSubscribers) { - channels.headers.publish({ request: this, response: { statusCode, headers, statusText } }); - } - - try { - return this[kHandler].onHeaders(statusCode, headers, resume, statusText) - } catch (err) { - this.abort(err); - } - } - - onData (chunk) { - assert(!this.aborted); - assert(!this.completed); - - try { - return this[kHandler].onData(chunk) - } catch (err) { - this.abort(err); - return false - } - } - - onUpgrade (statusCode, headers, socket) { - assert(!this.aborted); - assert(!this.completed); - - return this[kHandler].onUpgrade(statusCode, headers, socket) - } - - onComplete (trailers) { - this.onFinally(); - - assert(!this.aborted); - - this.completed = true; - if (channels.trailers.hasSubscribers) { - channels.trailers.publish({ request: this, trailers }); - } - - try { - return this[kHandler].onComplete(trailers) - } catch (err) { - // TODO (fix): This might be a bad idea? - this.onError(err); - } - } - - onError (error) { - this.onFinally(); - - if (channels.error.hasSubscribers) { - channels.error.publish({ request: this, error }); - } - - if (this.aborted) { - return - } - this.aborted = true; - - return this[kHandler].onError(error) - } - - onFinally () { - if (this.errorHandler) { - this.body.off('error', this.errorHandler); - this.errorHandler = null; - } - - if (this.endHandler) { - this.body.off('end', this.endHandler); - this.endHandler = null; - } - } - - addHeader (key, value) { - processHeader(this, key, value); - return this - } - } - - function processHeader (request, key, val) { - if (val && (typeof val === 'object' && !Array.isArray(val))) { - throw new InvalidArgumentError(`invalid ${key} header`) - } else if (val === undefined) { - return - } - - let headerName = headerNameLowerCasedRecord[key]; - - if (headerName === undefined) { - headerName = key.toLowerCase(); - if (headerNameLowerCasedRecord[headerName] === undefined && !isValidHTTPToken(headerName)) { - throw new InvalidArgumentError('invalid header key') - } - } - - if (Array.isArray(val)) { - const arr = []; - for (let i = 0; i < val.length; i++) { - if (typeof val[i] === 'string') { - if (!isValidHeaderValue(val[i])) { - throw new InvalidArgumentError(`invalid ${key} header`) - } - arr.push(val[i]); - } else if (val[i] === null) { - arr.push(''); - } else if (typeof val[i] === 'object') { - throw new InvalidArgumentError(`invalid ${key} header`) - } else { - arr.push(`${val[i]}`); - } - } - val = arr; - } else if (typeof val === 'string') { - if (!isValidHeaderValue(val)) { - throw new InvalidArgumentError(`invalid ${key} header`) - } - } else if (val === null) { - val = ''; - } else { - val = `${val}`; - } - - if (request.host === null && headerName === 'host') { - if (typeof val !== 'string') { - throw new InvalidArgumentError('invalid host header') - } - // Consumed by Client - request.host = val; - } else if (request.contentLength === null && headerName === 'content-length') { - request.contentLength = parseInt(val, 10); - if (!Number.isFinite(request.contentLength)) { - throw new InvalidArgumentError('invalid content-length header') - } - } else if (request.contentType === null && headerName === 'content-type') { - request.contentType = val; - request.headers.push(key, val); - } else if (headerName === 'transfer-encoding' || headerName === 'keep-alive' || headerName === 'upgrade') { - throw new InvalidArgumentError(`invalid ${headerName} header`) - } else if (headerName === 'connection') { - const value = typeof val === 'string' ? val.toLowerCase() : null; - if (value !== 'close' && value !== 'keep-alive') { - throw new InvalidArgumentError('invalid connection header') - } - - if (value === 'close') { - request.reset = true; - } - } else if (headerName === 'expect') { - throw new NotSupportedError('expect header not supported') - } else { - request.headers.push(key, val); - } - } - - request$1 = Request; - return request$1; -} - -var dispatcher; -var hasRequiredDispatcher; - -function requireDispatcher () { - if (hasRequiredDispatcher) return dispatcher; - hasRequiredDispatcher = 1; - const EventEmitter = require$$8; - - class Dispatcher extends EventEmitter { - dispatch () { - throw new Error('not implemented') - } - - close () { - throw new Error('not implemented') - } - - destroy () { - throw new Error('not implemented') - } - - compose (...args) { - // So we handle [interceptor1, interceptor2] or interceptor1, interceptor2, ... - const interceptors = Array.isArray(args[0]) ? args[0] : args; - let dispatch = this.dispatch.bind(this); - - for (const interceptor of interceptors) { - if (interceptor == null) { - continue - } - - if (typeof interceptor !== 'function') { - throw new TypeError(`invalid interceptor, expected function received ${typeof interceptor}`) - } - - dispatch = interceptor(dispatch); - - if (dispatch == null || typeof dispatch !== 'function' || dispatch.length !== 2) { - throw new TypeError('invalid interceptor') - } - } - - return new ComposedDispatcher(this, dispatch) - } - } - - class ComposedDispatcher extends Dispatcher { - #dispatcher = null - #dispatch = null - - constructor (dispatcher, dispatch) { - super(); - this.#dispatcher = dispatcher; - this.#dispatch = dispatch; - } - - dispatch (...args) { - this.#dispatch(...args); - } - - close (...args) { - return this.#dispatcher.close(...args) - } - - destroy (...args) { - return this.#dispatcher.destroy(...args) - } - } - - dispatcher = Dispatcher; - return dispatcher; -} - -var dispatcherBase; -var hasRequiredDispatcherBase; - -function requireDispatcherBase () { - if (hasRequiredDispatcherBase) return dispatcherBase; - hasRequiredDispatcherBase = 1; - - const Dispatcher = requireDispatcher(); - const { - ClientDestroyedError, - ClientClosedError, - InvalidArgumentError - } = requireErrors(); - const { kDestroy, kClose, kClosed, kDestroyed, kDispatch, kInterceptors } = requireSymbols$4(); - - const kOnDestroyed = Symbol('onDestroyed'); - const kOnClosed = Symbol('onClosed'); - const kInterceptedDispatch = Symbol('Intercepted Dispatch'); - - class DispatcherBase extends Dispatcher { - constructor () { - super(); - - this[kDestroyed] = false; - this[kOnDestroyed] = null; - this[kClosed] = false; - this[kOnClosed] = []; - } - - get destroyed () { - return this[kDestroyed] - } - - get closed () { - return this[kClosed] - } - - get interceptors () { - return this[kInterceptors] - } - - set interceptors (newInterceptors) { - if (newInterceptors) { - for (let i = newInterceptors.length - 1; i >= 0; i--) { - const interceptor = this[kInterceptors][i]; - if (typeof interceptor !== 'function') { - throw new InvalidArgumentError('interceptor must be an function') - } - } - } - - this[kInterceptors] = newInterceptors; - } - - close (callback) { - if (callback === undefined) { - return new Promise((resolve, reject) => { - this.close((err, data) => { - return err ? reject(err) : resolve(data) - }); - }) - } - - if (typeof callback !== 'function') { - throw new InvalidArgumentError('invalid callback') - } - - if (this[kDestroyed]) { - queueMicrotask(() => callback(new ClientDestroyedError(), null)); - return - } - - if (this[kClosed]) { - if (this[kOnClosed]) { - this[kOnClosed].push(callback); - } else { - queueMicrotask(() => callback(null, null)); - } - return - } - - this[kClosed] = true; - this[kOnClosed].push(callback); - - const onClosed = () => { - const callbacks = this[kOnClosed]; - this[kOnClosed] = null; - for (let i = 0; i < callbacks.length; i++) { - callbacks[i](null, null); - } - }; - - // Should not error. - this[kClose]() - .then(() => this.destroy()) - .then(() => { - queueMicrotask(onClosed); - }); - } - - destroy (err, callback) { - if (typeof err === 'function') { - callback = err; - err = null; - } - - if (callback === undefined) { - return new Promise((resolve, reject) => { - this.destroy(err, (err, data) => { - return err ? /* istanbul ignore next: should never error */ reject(err) : resolve(data) - }); - }) - } - - if (typeof callback !== 'function') { - throw new InvalidArgumentError('invalid callback') - } - - if (this[kDestroyed]) { - if (this[kOnDestroyed]) { - this[kOnDestroyed].push(callback); - } else { - queueMicrotask(() => callback(null, null)); - } - return - } - - if (!err) { - err = new ClientDestroyedError(); - } - - this[kDestroyed] = true; - this[kOnDestroyed] = this[kOnDestroyed] || []; - this[kOnDestroyed].push(callback); - - const onDestroyed = () => { - const callbacks = this[kOnDestroyed]; - this[kOnDestroyed] = null; - for (let i = 0; i < callbacks.length; i++) { - callbacks[i](null, null); - } - }; - - // Should not error. - this[kDestroy](err).then(() => { - queueMicrotask(onDestroyed); - }); - } - - [kInterceptedDispatch] (opts, handler) { - if (!this[kInterceptors] || this[kInterceptors].length === 0) { - this[kInterceptedDispatch] = this[kDispatch]; - return this[kDispatch](opts, handler) - } - - let dispatch = this[kDispatch].bind(this); - for (let i = this[kInterceptors].length - 1; i >= 0; i--) { - dispatch = this[kInterceptors][i](dispatch); - } - this[kInterceptedDispatch] = dispatch; - return dispatch(opts, handler) - } - - dispatch (opts, handler) { - if (!handler || typeof handler !== 'object') { - throw new InvalidArgumentError('handler must be an object') - } - - try { - if (!opts || typeof opts !== 'object') { - throw new InvalidArgumentError('opts must be an object.') - } - - if (this[kDestroyed] || this[kOnDestroyed]) { - throw new ClientDestroyedError() - } - - if (this[kClosed]) { - throw new ClientClosedError() - } - - return this[kInterceptedDispatch](opts, handler) - } catch (err) { - if (typeof handler.onError !== 'function') { - throw new InvalidArgumentError('invalid onError method') - } - - handler.onError(err); - - return false - } - } - } - - dispatcherBase = DispatcherBase; - return dispatcherBase; -} - -var connect; -var hasRequiredConnect; - -function requireConnect () { - if (hasRequiredConnect) return connect; - hasRequiredConnect = 1; - - const net = require$$4; - const assert = require$$0$4; - const util = requireUtil$7(); - const { InvalidArgumentError, ConnectTimeoutError } = requireErrors(); - - let tls; // include tls conditionally since it is not always available - - // TODO: session re-use does not wait for the first - // connection to resolve the session and might therefore - // resolve the same servername multiple times even when - // re-use is enabled. - - let SessionCache; - // FIXME: remove workaround when the Node bug is fixed - // https://github.com/nodejs/node/issues/49344#issuecomment-1741776308 - if (commonjsGlobal.FinalizationRegistry && !(process.env.NODE_V8_COVERAGE || process.env.UNDICI_NO_FG)) { - SessionCache = class WeakSessionCache { - constructor (maxCachedSessions) { - this._maxCachedSessions = maxCachedSessions; - this._sessionCache = new Map(); - this._sessionRegistry = new commonjsGlobal.FinalizationRegistry((key) => { - if (this._sessionCache.size < this._maxCachedSessions) { - return - } - - const ref = this._sessionCache.get(key); - if (ref !== undefined && ref.deref() === undefined) { - this._sessionCache.delete(key); - } - }); - } - - get (sessionKey) { - const ref = this._sessionCache.get(sessionKey); - return ref ? ref.deref() : null - } - - set (sessionKey, session) { - if (this._maxCachedSessions === 0) { - return - } - - this._sessionCache.set(sessionKey, new WeakRef(session)); - this._sessionRegistry.register(session, sessionKey); - } - }; - } else { - SessionCache = class SimpleSessionCache { - constructor (maxCachedSessions) { - this._maxCachedSessions = maxCachedSessions; - this._sessionCache = new Map(); - } - - get (sessionKey) { - return this._sessionCache.get(sessionKey) - } - - set (sessionKey, session) { - if (this._maxCachedSessions === 0) { - return - } - - if (this._sessionCache.size >= this._maxCachedSessions) { - // remove the oldest session - const { value: oldestKey } = this._sessionCache.keys().next(); - this._sessionCache.delete(oldestKey); - } - - this._sessionCache.set(sessionKey, session); - } - }; - } - - function buildConnector ({ allowH2, maxCachedSessions, socketPath, timeout, session: customSession, ...opts }) { - if (maxCachedSessions != null && (!Number.isInteger(maxCachedSessions) || maxCachedSessions < 0)) { - throw new InvalidArgumentError('maxCachedSessions must be a positive integer or zero') - } - - const options = { path: socketPath, ...opts }; - const sessionCache = new SessionCache(maxCachedSessions == null ? 100 : maxCachedSessions); - timeout = timeout == null ? 10e3 : timeout; - allowH2 = allowH2 != null ? allowH2 : false; - return function connect ({ hostname, host, protocol, port, servername, localAddress, httpSocket }, callback) { - let socket; - if (protocol === 'https:') { - if (!tls) { - tls = require$$4$1; - } - servername = servername || options.servername || util.getServerName(host) || null; - - const sessionKey = servername || hostname; - const session = customSession || sessionCache.get(sessionKey) || null; - - assert(sessionKey); - - socket = tls.connect({ - highWaterMark: 16384, // TLS in node can't have bigger HWM anyway... - ...options, - servername, - session, - localAddress, - // TODO(HTTP/2): Add support for h2c - ALPNProtocols: allowH2 ? ['http/1.1', 'h2'] : ['http/1.1'], - socket: httpSocket, // upgrade socket connection - port: port || 443, - host: hostname - }); - - socket - .on('session', function (session) { - // TODO (fix): Can a session become invalid once established? Don't think so? - sessionCache.set(sessionKey, session); - }); - } else { - assert(!httpSocket, 'httpSocket can only be sent on TLS update'); - socket = net.connect({ - highWaterMark: 64 * 1024, // Same as nodejs fs streams. - ...options, - localAddress, - port: port || 80, - host: hostname - }); - } - - // Set TCP keep alive options on the socket here instead of in connect() for the case of assigning the socket - if (options.keepAlive == null || options.keepAlive) { - const keepAliveInitialDelay = options.keepAliveInitialDelay === undefined ? 60e3 : options.keepAliveInitialDelay; - socket.setKeepAlive(true, keepAliveInitialDelay); - } - - const cancelTimeout = setupTimeout(() => onConnectTimeout(socket), timeout); - - socket - .setNoDelay(true) - .once(protocol === 'https:' ? 'secureConnect' : 'connect', function () { - cancelTimeout(); - - if (callback) { - const cb = callback; - callback = null; - cb(null, this); - } - }) - .on('error', function (err) { - cancelTimeout(); - - if (callback) { - const cb = callback; - callback = null; - cb(err); - } - }); - - return socket - } - } - - function setupTimeout (onConnectTimeout, timeout) { - if (!timeout) { - return () => {} - } - - let s1 = null; - let s2 = null; - const timeoutId = setTimeout(() => { - // setImmediate is added to make sure that we prioritize socket error events over timeouts - s1 = setImmediate(() => { - if (process.platform === 'win32') { - // Windows needs an extra setImmediate probably due to implementation differences in the socket logic - s2 = setImmediate(() => onConnectTimeout()); - } else { - onConnectTimeout(); - } - }); - }, timeout); - return () => { - clearTimeout(timeoutId); - clearImmediate(s1); - clearImmediate(s2); - } - } - - function onConnectTimeout (socket) { - let message = 'Connect Timeout Error'; - if (Array.isArray(socket.autoSelectFamilyAttemptedAddresses)) { - message += ` (attempted addresses: ${socket.autoSelectFamilyAttemptedAddresses.join(', ')})`; - } - util.destroy(socket, new ConnectTimeoutError(message)); - } - - connect = buildConnector; - return connect; -} - -var timers; -var hasRequiredTimers; - -function requireTimers () { - if (hasRequiredTimers) return timers; - hasRequiredTimers = 1; - - const TICK_MS = 499; - - let fastNow = Date.now(); - let fastNowTimeout; - - const fastTimers = []; - - function onTimeout () { - fastNow = Date.now(); - - let len = fastTimers.length; - let idx = 0; - while (idx < len) { - const timer = fastTimers[idx]; - - if (timer.state === 0) { - timer.state = fastNow + timer.delay - TICK_MS; - } else if (timer.state > 0 && fastNow >= timer.state) { - timer.state = -1; - timer.callback(timer.opaque); - } - - if (timer.state === -1) { - timer.state = -2; - if (idx !== len - 1) { - fastTimers[idx] = fastTimers.pop(); - } else { - fastTimers.pop(); - } - len -= 1; - } else { - idx += 1; - } - } - - if (fastTimers.length > 0) { - refreshTimeout(); - } - } - - function refreshTimeout () { - if (fastNowTimeout?.refresh) { - fastNowTimeout.refresh(); - } else { - clearTimeout(fastNowTimeout); - fastNowTimeout = setTimeout(onTimeout, TICK_MS); - if (fastNowTimeout.unref) { - fastNowTimeout.unref(); - } - } - } - - class Timeout { - constructor (callback, delay, opaque) { - this.callback = callback; - this.delay = delay; - this.opaque = opaque; - - // -2 not in timer list - // -1 in timer list but inactive - // 0 in timer list waiting for time - // > 0 in timer list waiting for time to expire - this.state = -2; - - this.refresh(); - } - - refresh () { - if (this.state === -2) { - fastTimers.push(this); - if (!fastNowTimeout || fastTimers.length === 1) { - refreshTimeout(); - } - } - - this.state = 0; - } - - clear () { - this.state = -1; - } - } - - timers = { - setTimeout (callback, delay, opaque) { - return delay <= 1e3 - ? setTimeout(callback, delay, opaque) - : new Timeout(callback, delay, opaque) - }, - clearTimeout (timeout) { - if (timeout instanceof Timeout) { - timeout.clear(); - } else { - clearTimeout(timeout); - } - } - }; - return timers; -} - -var constants$3 = {}; - -var utils = {}; - -var hasRequiredUtils; - -function requireUtils () { - if (hasRequiredUtils) return utils; - hasRequiredUtils = 1; - Object.defineProperty(utils, "__esModule", { value: true }); - utils.enumToMap = void 0; - function enumToMap(obj) { - const res = {}; - Object.keys(obj).forEach((key) => { - const value = obj[key]; - if (typeof value === 'number') { - res[key] = value; - } - }); - return res; - } - utils.enumToMap = enumToMap; - - return utils; -} - -var hasRequiredConstants$3; - -function requireConstants$3 () { - if (hasRequiredConstants$3) return constants$3; - hasRequiredConstants$3 = 1; - (function (exports) { - Object.defineProperty(exports, "__esModule", { value: true }); - exports.SPECIAL_HEADERS = exports.HEADER_STATE = exports.MINOR = exports.MAJOR = exports.CONNECTION_TOKEN_CHARS = exports.HEADER_CHARS = exports.TOKEN = exports.STRICT_TOKEN = exports.HEX = exports.URL_CHAR = exports.STRICT_URL_CHAR = exports.USERINFO_CHARS = exports.MARK = exports.ALPHANUM = exports.NUM = exports.HEX_MAP = exports.NUM_MAP = exports.ALPHA = exports.FINISH = exports.H_METHOD_MAP = exports.METHOD_MAP = exports.METHODS_RTSP = exports.METHODS_ICE = exports.METHODS_HTTP = exports.METHODS = exports.LENIENT_FLAGS = exports.FLAGS = exports.TYPE = exports.ERROR = void 0; - const utils_1 = requireUtils(); - (function (ERROR) { - ERROR[ERROR["OK"] = 0] = "OK"; - ERROR[ERROR["INTERNAL"] = 1] = "INTERNAL"; - ERROR[ERROR["STRICT"] = 2] = "STRICT"; - ERROR[ERROR["LF_EXPECTED"] = 3] = "LF_EXPECTED"; - ERROR[ERROR["UNEXPECTED_CONTENT_LENGTH"] = 4] = "UNEXPECTED_CONTENT_LENGTH"; - ERROR[ERROR["CLOSED_CONNECTION"] = 5] = "CLOSED_CONNECTION"; - ERROR[ERROR["INVALID_METHOD"] = 6] = "INVALID_METHOD"; - ERROR[ERROR["INVALID_URL"] = 7] = "INVALID_URL"; - ERROR[ERROR["INVALID_CONSTANT"] = 8] = "INVALID_CONSTANT"; - ERROR[ERROR["INVALID_VERSION"] = 9] = "INVALID_VERSION"; - ERROR[ERROR["INVALID_HEADER_TOKEN"] = 10] = "INVALID_HEADER_TOKEN"; - ERROR[ERROR["INVALID_CONTENT_LENGTH"] = 11] = "INVALID_CONTENT_LENGTH"; - ERROR[ERROR["INVALID_CHUNK_SIZE"] = 12] = "INVALID_CHUNK_SIZE"; - ERROR[ERROR["INVALID_STATUS"] = 13] = "INVALID_STATUS"; - ERROR[ERROR["INVALID_EOF_STATE"] = 14] = "INVALID_EOF_STATE"; - ERROR[ERROR["INVALID_TRANSFER_ENCODING"] = 15] = "INVALID_TRANSFER_ENCODING"; - ERROR[ERROR["CB_MESSAGE_BEGIN"] = 16] = "CB_MESSAGE_BEGIN"; - ERROR[ERROR["CB_HEADERS_COMPLETE"] = 17] = "CB_HEADERS_COMPLETE"; - ERROR[ERROR["CB_MESSAGE_COMPLETE"] = 18] = "CB_MESSAGE_COMPLETE"; - ERROR[ERROR["CB_CHUNK_HEADER"] = 19] = "CB_CHUNK_HEADER"; - ERROR[ERROR["CB_CHUNK_COMPLETE"] = 20] = "CB_CHUNK_COMPLETE"; - ERROR[ERROR["PAUSED"] = 21] = "PAUSED"; - ERROR[ERROR["PAUSED_UPGRADE"] = 22] = "PAUSED_UPGRADE"; - ERROR[ERROR["PAUSED_H2_UPGRADE"] = 23] = "PAUSED_H2_UPGRADE"; - ERROR[ERROR["USER"] = 24] = "USER"; - })(exports.ERROR || (exports.ERROR = {})); - (function (TYPE) { - TYPE[TYPE["BOTH"] = 0] = "BOTH"; - TYPE[TYPE["REQUEST"] = 1] = "REQUEST"; - TYPE[TYPE["RESPONSE"] = 2] = "RESPONSE"; - })(exports.TYPE || (exports.TYPE = {})); - (function (FLAGS) { - FLAGS[FLAGS["CONNECTION_KEEP_ALIVE"] = 1] = "CONNECTION_KEEP_ALIVE"; - FLAGS[FLAGS["CONNECTION_CLOSE"] = 2] = "CONNECTION_CLOSE"; - FLAGS[FLAGS["CONNECTION_UPGRADE"] = 4] = "CONNECTION_UPGRADE"; - FLAGS[FLAGS["CHUNKED"] = 8] = "CHUNKED"; - FLAGS[FLAGS["UPGRADE"] = 16] = "UPGRADE"; - FLAGS[FLAGS["CONTENT_LENGTH"] = 32] = "CONTENT_LENGTH"; - FLAGS[FLAGS["SKIPBODY"] = 64] = "SKIPBODY"; - FLAGS[FLAGS["TRAILING"] = 128] = "TRAILING"; - // 1 << 8 is unused - FLAGS[FLAGS["TRANSFER_ENCODING"] = 512] = "TRANSFER_ENCODING"; - })(exports.FLAGS || (exports.FLAGS = {})); - (function (LENIENT_FLAGS) { - LENIENT_FLAGS[LENIENT_FLAGS["HEADERS"] = 1] = "HEADERS"; - LENIENT_FLAGS[LENIENT_FLAGS["CHUNKED_LENGTH"] = 2] = "CHUNKED_LENGTH"; - LENIENT_FLAGS[LENIENT_FLAGS["KEEP_ALIVE"] = 4] = "KEEP_ALIVE"; - })(exports.LENIENT_FLAGS || (exports.LENIENT_FLAGS = {})); - var METHODS; - (function (METHODS) { - METHODS[METHODS["DELETE"] = 0] = "DELETE"; - METHODS[METHODS["GET"] = 1] = "GET"; - METHODS[METHODS["HEAD"] = 2] = "HEAD"; - METHODS[METHODS["POST"] = 3] = "POST"; - METHODS[METHODS["PUT"] = 4] = "PUT"; - /* pathological */ - METHODS[METHODS["CONNECT"] = 5] = "CONNECT"; - METHODS[METHODS["OPTIONS"] = 6] = "OPTIONS"; - METHODS[METHODS["TRACE"] = 7] = "TRACE"; - /* WebDAV */ - METHODS[METHODS["COPY"] = 8] = "COPY"; - METHODS[METHODS["LOCK"] = 9] = "LOCK"; - METHODS[METHODS["MKCOL"] = 10] = "MKCOL"; - METHODS[METHODS["MOVE"] = 11] = "MOVE"; - METHODS[METHODS["PROPFIND"] = 12] = "PROPFIND"; - METHODS[METHODS["PROPPATCH"] = 13] = "PROPPATCH"; - METHODS[METHODS["SEARCH"] = 14] = "SEARCH"; - METHODS[METHODS["UNLOCK"] = 15] = "UNLOCK"; - METHODS[METHODS["BIND"] = 16] = "BIND"; - METHODS[METHODS["REBIND"] = 17] = "REBIND"; - METHODS[METHODS["UNBIND"] = 18] = "UNBIND"; - METHODS[METHODS["ACL"] = 19] = "ACL"; - /* subversion */ - METHODS[METHODS["REPORT"] = 20] = "REPORT"; - METHODS[METHODS["MKACTIVITY"] = 21] = "MKACTIVITY"; - METHODS[METHODS["CHECKOUT"] = 22] = "CHECKOUT"; - METHODS[METHODS["MERGE"] = 23] = "MERGE"; - /* upnp */ - METHODS[METHODS["M-SEARCH"] = 24] = "M-SEARCH"; - METHODS[METHODS["NOTIFY"] = 25] = "NOTIFY"; - METHODS[METHODS["SUBSCRIBE"] = 26] = "SUBSCRIBE"; - METHODS[METHODS["UNSUBSCRIBE"] = 27] = "UNSUBSCRIBE"; - /* RFC-5789 */ - METHODS[METHODS["PATCH"] = 28] = "PATCH"; - METHODS[METHODS["PURGE"] = 29] = "PURGE"; - /* CalDAV */ - METHODS[METHODS["MKCALENDAR"] = 30] = "MKCALENDAR"; - /* RFC-2068, section 19.6.1.2 */ - METHODS[METHODS["LINK"] = 31] = "LINK"; - METHODS[METHODS["UNLINK"] = 32] = "UNLINK"; - /* icecast */ - METHODS[METHODS["SOURCE"] = 33] = "SOURCE"; - /* RFC-7540, section 11.6 */ - METHODS[METHODS["PRI"] = 34] = "PRI"; - /* RFC-2326 RTSP */ - METHODS[METHODS["DESCRIBE"] = 35] = "DESCRIBE"; - METHODS[METHODS["ANNOUNCE"] = 36] = "ANNOUNCE"; - METHODS[METHODS["SETUP"] = 37] = "SETUP"; - METHODS[METHODS["PLAY"] = 38] = "PLAY"; - METHODS[METHODS["PAUSE"] = 39] = "PAUSE"; - METHODS[METHODS["TEARDOWN"] = 40] = "TEARDOWN"; - METHODS[METHODS["GET_PARAMETER"] = 41] = "GET_PARAMETER"; - METHODS[METHODS["SET_PARAMETER"] = 42] = "SET_PARAMETER"; - METHODS[METHODS["REDIRECT"] = 43] = "REDIRECT"; - METHODS[METHODS["RECORD"] = 44] = "RECORD"; - /* RAOP */ - METHODS[METHODS["FLUSH"] = 45] = "FLUSH"; - })(METHODS = exports.METHODS || (exports.METHODS = {})); - exports.METHODS_HTTP = [ - METHODS.DELETE, - METHODS.GET, - METHODS.HEAD, - METHODS.POST, - METHODS.PUT, - METHODS.CONNECT, - METHODS.OPTIONS, - METHODS.TRACE, - METHODS.COPY, - METHODS.LOCK, - METHODS.MKCOL, - METHODS.MOVE, - METHODS.PROPFIND, - METHODS.PROPPATCH, - METHODS.SEARCH, - METHODS.UNLOCK, - METHODS.BIND, - METHODS.REBIND, - METHODS.UNBIND, - METHODS.ACL, - METHODS.REPORT, - METHODS.MKACTIVITY, - METHODS.CHECKOUT, - METHODS.MERGE, - METHODS['M-SEARCH'], - METHODS.NOTIFY, - METHODS.SUBSCRIBE, - METHODS.UNSUBSCRIBE, - METHODS.PATCH, - METHODS.PURGE, - METHODS.MKCALENDAR, - METHODS.LINK, - METHODS.UNLINK, - METHODS.PRI, - // TODO(indutny): should we allow it with HTTP? - METHODS.SOURCE, - ]; - exports.METHODS_ICE = [ - METHODS.SOURCE, - ]; - exports.METHODS_RTSP = [ - METHODS.OPTIONS, - METHODS.DESCRIBE, - METHODS.ANNOUNCE, - METHODS.SETUP, - METHODS.PLAY, - METHODS.PAUSE, - METHODS.TEARDOWN, - METHODS.GET_PARAMETER, - METHODS.SET_PARAMETER, - METHODS.REDIRECT, - METHODS.RECORD, - METHODS.FLUSH, - // For AirPlay - METHODS.GET, - METHODS.POST, - ]; - exports.METHOD_MAP = utils_1.enumToMap(METHODS); - exports.H_METHOD_MAP = {}; - Object.keys(exports.METHOD_MAP).forEach((key) => { - if (/^H/.test(key)) { - exports.H_METHOD_MAP[key] = exports.METHOD_MAP[key]; - } - }); - (function (FINISH) { - FINISH[FINISH["SAFE"] = 0] = "SAFE"; - FINISH[FINISH["SAFE_WITH_CB"] = 1] = "SAFE_WITH_CB"; - FINISH[FINISH["UNSAFE"] = 2] = "UNSAFE"; - })(exports.FINISH || (exports.FINISH = {})); - exports.ALPHA = []; - for (let i = 'A'.charCodeAt(0); i <= 'Z'.charCodeAt(0); i++) { - // Upper case - exports.ALPHA.push(String.fromCharCode(i)); - // Lower case - exports.ALPHA.push(String.fromCharCode(i + 0x20)); - } - exports.NUM_MAP = { - 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, - 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, - }; - exports.HEX_MAP = { - 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, - 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, - A: 0XA, B: 0XB, C: 0XC, D: 0XD, E: 0XE, F: 0XF, - a: 0xa, b: 0xb, c: 0xc, d: 0xd, e: 0xe, f: 0xf, - }; - exports.NUM = [ - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - ]; - exports.ALPHANUM = exports.ALPHA.concat(exports.NUM); - exports.MARK = ['-', '_', '.', '!', '~', '*', '\'', '(', ')']; - exports.USERINFO_CHARS = exports.ALPHANUM - .concat(exports.MARK) - .concat(['%', ';', ':', '&', '=', '+', '$', ',']); - // TODO(indutny): use RFC - exports.STRICT_URL_CHAR = [ - '!', '"', '$', '%', '&', '\'', - '(', ')', '*', '+', ',', '-', '.', '/', - ':', ';', '<', '=', '>', - '@', '[', '\\', ']', '^', '_', - '`', - '{', '|', '}', '~', - ].concat(exports.ALPHANUM); - exports.URL_CHAR = exports.STRICT_URL_CHAR - .concat(['\t', '\f']); - // All characters with 0x80 bit set to 1 - for (let i = 0x80; i <= 0xff; i++) { - exports.URL_CHAR.push(i); - } - exports.HEX = exports.NUM.concat(['a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F']); - /* Tokens as defined by rfc 2616. Also lowercases them. - * token = 1* - * separators = "(" | ")" | "<" | ">" | "@" - * | "," | ";" | ":" | "\" | <"> - * | "/" | "[" | "]" | "?" | "=" - * | "{" | "}" | SP | HT - */ - exports.STRICT_TOKEN = [ - '!', '#', '$', '%', '&', '\'', - '*', '+', '-', '.', - '^', '_', '`', - '|', '~', - ].concat(exports.ALPHANUM); - exports.TOKEN = exports.STRICT_TOKEN.concat([' ']); - /* - * Verify that a char is a valid visible (printable) US-ASCII - * character or %x80-FF - */ - exports.HEADER_CHARS = ['\t']; - for (let i = 32; i <= 255; i++) { - if (i !== 127) { - exports.HEADER_CHARS.push(i); - } - } - // ',' = \x44 - exports.CONNECTION_TOKEN_CHARS = exports.HEADER_CHARS.filter((c) => c !== 44); - exports.MAJOR = exports.NUM_MAP; - exports.MINOR = exports.MAJOR; - var HEADER_STATE; - (function (HEADER_STATE) { - HEADER_STATE[HEADER_STATE["GENERAL"] = 0] = "GENERAL"; - HEADER_STATE[HEADER_STATE["CONNECTION"] = 1] = "CONNECTION"; - HEADER_STATE[HEADER_STATE["CONTENT_LENGTH"] = 2] = "CONTENT_LENGTH"; - HEADER_STATE[HEADER_STATE["TRANSFER_ENCODING"] = 3] = "TRANSFER_ENCODING"; - HEADER_STATE[HEADER_STATE["UPGRADE"] = 4] = "UPGRADE"; - HEADER_STATE[HEADER_STATE["CONNECTION_KEEP_ALIVE"] = 5] = "CONNECTION_KEEP_ALIVE"; - HEADER_STATE[HEADER_STATE["CONNECTION_CLOSE"] = 6] = "CONNECTION_CLOSE"; - HEADER_STATE[HEADER_STATE["CONNECTION_UPGRADE"] = 7] = "CONNECTION_UPGRADE"; - HEADER_STATE[HEADER_STATE["TRANSFER_ENCODING_CHUNKED"] = 8] = "TRANSFER_ENCODING_CHUNKED"; - })(HEADER_STATE = exports.HEADER_STATE || (exports.HEADER_STATE = {})); - exports.SPECIAL_HEADERS = { - 'connection': HEADER_STATE.CONNECTION, - 'content-length': HEADER_STATE.CONTENT_LENGTH, - 'proxy-connection': HEADER_STATE.CONNECTION, - 'transfer-encoding': HEADER_STATE.TRANSFER_ENCODING, - 'upgrade': HEADER_STATE.UPGRADE, - }; - - } (constants$3)); - return constants$3; -} - -var llhttpWasm; -var hasRequiredLlhttpWasm; - -function requireLlhttpWasm () { - if (hasRequiredLlhttpWasm) return llhttpWasm; - hasRequiredLlhttpWasm = 1; - - const { Buffer } = require$$0$3; - - llhttpWasm = Buffer.from('AGFzbQEAAAABJwdgAX8Bf2ADf39/AX9gAX8AYAJ/fwBgBH9/f38Bf2AAAGADf39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQAEA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAAy0sBQYAAAIAAAAAAAACAQIAAgICAAADAAAAAAMDAwMBAQEBAQEBAQEAAAIAAAAEBQFwARISBQMBAAIGCAF/AUGA1AQLB9EFIgZtZW1vcnkCAAtfaW5pdGlhbGl6ZQAIGV9faW5kaXJlY3RfZnVuY3Rpb25fdGFibGUBAAtsbGh0dHBfaW5pdAAJGGxsaHR0cF9zaG91bGRfa2VlcF9hbGl2ZQAvDGxsaHR0cF9hbGxvYwALBm1hbGxvYwAxC2xsaHR0cF9mcmVlAAwEZnJlZQAMD2xsaHR0cF9nZXRfdHlwZQANFWxsaHR0cF9nZXRfaHR0cF9tYWpvcgAOFWxsaHR0cF9nZXRfaHR0cF9taW5vcgAPEWxsaHR0cF9nZXRfbWV0aG9kABAWbGxodHRwX2dldF9zdGF0dXNfY29kZQAREmxsaHR0cF9nZXRfdXBncmFkZQASDGxsaHR0cF9yZXNldAATDmxsaHR0cF9leGVjdXRlABQUbGxodHRwX3NldHRpbmdzX2luaXQAFQ1sbGh0dHBfZmluaXNoABYMbGxodHRwX3BhdXNlABcNbGxodHRwX3Jlc3VtZQAYG2xsaHR0cF9yZXN1bWVfYWZ0ZXJfdXBncmFkZQAZEGxsaHR0cF9nZXRfZXJybm8AGhdsbGh0dHBfZ2V0X2Vycm9yX3JlYXNvbgAbF2xsaHR0cF9zZXRfZXJyb3JfcmVhc29uABwUbGxodHRwX2dldF9lcnJvcl9wb3MAHRFsbGh0dHBfZXJybm9fbmFtZQAeEmxsaHR0cF9tZXRob2RfbmFtZQAfEmxsaHR0cF9zdGF0dXNfbmFtZQAgGmxsaHR0cF9zZXRfbGVuaWVudF9oZWFkZXJzACEhbGxodHRwX3NldF9sZW5pZW50X2NodW5rZWRfbGVuZ3RoACIdbGxodHRwX3NldF9sZW5pZW50X2tlZXBfYWxpdmUAIyRsbGh0dHBfc2V0X2xlbmllbnRfdHJhbnNmZXJfZW5jb2RpbmcAJBhsbGh0dHBfbWVzc2FnZV9uZWVkc19lb2YALgkXAQBBAQsRAQIDBAUKBgcrLSwqKSglJyYK07MCLBYAQYjQACgCAARAAAtBiNAAQQE2AgALFAAgABAwIAAgAjYCOCAAIAE6ACgLFAAgACAALwEyIAAtAC4gABAvEAALHgEBf0HAABAyIgEQMCABQYAINgI4IAEgADoAKCABC48MAQd/AkAgAEUNACAAQQhrIgEgAEEEaygCACIAQXhxIgRqIQUCQCAAQQFxDQAgAEEDcUUNASABIAEoAgAiAGsiAUGc0AAoAgBJDQEgACAEaiEEAkACQEGg0AAoAgAgAUcEQCAAQf8BTQRAIABBA3YhAyABKAIIIgAgASgCDCICRgRAQYzQAEGM0AAoAgBBfiADd3E2AgAMBQsgAiAANgIIIAAgAjYCDAwECyABKAIYIQYgASABKAIMIgBHBEAgACABKAIIIgI2AgggAiAANgIMDAMLIAFBFGoiAygCACICRQRAIAEoAhAiAkUNAiABQRBqIQMLA0AgAyEHIAIiAEEUaiIDKAIAIgINACAAQRBqIQMgACgCECICDQALIAdBADYCAAwCCyAFKAIEIgBBA3FBA0cNAiAFIABBfnE2AgRBlNAAIAQ2AgAgBSAENgIAIAEgBEEBcjYCBAwDC0EAIQALIAZFDQACQCABKAIcIgJBAnRBvNIAaiIDKAIAIAFGBEAgAyAANgIAIAANAUGQ0ABBkNAAKAIAQX4gAndxNgIADAILIAZBEEEUIAYoAhAgAUYbaiAANgIAIABFDQELIAAgBjYCGCABKAIQIgIEQCAAIAI2AhAgAiAANgIYCyABQRRqKAIAIgJFDQAgAEEUaiACNgIAIAIgADYCGAsgASAFTw0AIAUoAgQiAEEBcUUNAAJAAkACQAJAIABBAnFFBEBBpNAAKAIAIAVGBEBBpNAAIAE2AgBBmNAAQZjQACgCACAEaiIANgIAIAEgAEEBcjYCBCABQaDQACgCAEcNBkGU0ABBADYCAEGg0ABBADYCAAwGC0Gg0AAoAgAgBUYEQEGg0AAgATYCAEGU0ABBlNAAKAIAIARqIgA2AgAgASAAQQFyNgIEIAAgAWogADYCAAwGCyAAQXhxIARqIQQgAEH/AU0EQCAAQQN2IQMgBSgCCCIAIAUoAgwiAkYEQEGM0ABBjNAAKAIAQX4gA3dxNgIADAULIAIgADYCCCAAIAI2AgwMBAsgBSgCGCEGIAUgBSgCDCIARwRAQZzQACgCABogACAFKAIIIgI2AgggAiAANgIMDAMLIAVBFGoiAygCACICRQRAIAUoAhAiAkUNAiAFQRBqIQMLA0AgAyEHIAIiAEEUaiIDKAIAIgINACAAQRBqIQMgACgCECICDQALIAdBADYCAAwCCyAFIABBfnE2AgQgASAEaiAENgIAIAEgBEEBcjYCBAwDC0EAIQALIAZFDQACQCAFKAIcIgJBAnRBvNIAaiIDKAIAIAVGBEAgAyAANgIAIAANAUGQ0ABBkNAAKAIAQX4gAndxNgIADAILIAZBEEEUIAYoAhAgBUYbaiAANgIAIABFDQELIAAgBjYCGCAFKAIQIgIEQCAAIAI2AhAgAiAANgIYCyAFQRRqKAIAIgJFDQAgAEEUaiACNgIAIAIgADYCGAsgASAEaiAENgIAIAEgBEEBcjYCBCABQaDQACgCAEcNAEGU0AAgBDYCAAwBCyAEQf8BTQRAIARBeHFBtNAAaiEAAn9BjNAAKAIAIgJBASAEQQN2dCIDcUUEQEGM0AAgAiADcjYCACAADAELIAAoAggLIgIgATYCDCAAIAE2AgggASAANgIMIAEgAjYCCAwBC0EfIQIgBEH///8HTQRAIARBJiAEQQh2ZyIAa3ZBAXEgAEEBdGtBPmohAgsgASACNgIcIAFCADcCECACQQJ0QbzSAGohAAJAQZDQACgCACIDQQEgAnQiB3FFBEAgACABNgIAQZDQACADIAdyNgIAIAEgADYCGCABIAE2AgggASABNgIMDAELIARBGSACQQF2a0EAIAJBH0cbdCECIAAoAgAhAAJAA0AgACIDKAIEQXhxIARGDQEgAkEddiEAIAJBAXQhAiADIABBBHFqQRBqIgcoAgAiAA0ACyAHIAE2AgAgASADNgIYIAEgATYCDCABIAE2AggMAQsgAygCCCIAIAE2AgwgAyABNgIIIAFBADYCGCABIAM2AgwgASAANgIIC0Gs0ABBrNAAKAIAQQFrIgBBfyAAGzYCAAsLBwAgAC0AKAsHACAALQAqCwcAIAAtACsLBwAgAC0AKQsHACAALwEyCwcAIAAtAC4LQAEEfyAAKAIYIQEgAC0ALSECIAAtACghAyAAKAI4IQQgABAwIAAgBDYCOCAAIAM6ACggACACOgAtIAAgATYCGAu74gECB38DfiABIAJqIQQCQCAAIgIoAgwiAA0AIAIoAgQEQCACIAE2AgQLIwBBEGsiCCQAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACfwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIAIoAhwiA0EBaw7dAdoBAdkBAgMEBQYHCAkKCwwNDtgBDxDXARES1gETFBUWFxgZGhvgAd8BHB0e1QEfICEiIyQl1AEmJygpKiss0wHSAS0u0QHQAS8wMTIzNDU2Nzg5Ojs8PT4/QEFCQ0RFRtsBR0hJSs8BzgFLzQFMzAFNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AAYEBggGDAYQBhQGGAYcBiAGJAYoBiwGMAY0BjgGPAZABkQGSAZMBlAGVAZYBlwGYAZkBmgGbAZwBnQGeAZ8BoAGhAaIBowGkAaUBpgGnAagBqQGqAasBrAGtAa4BrwGwAbEBsgGzAbQBtQG2AbcBywHKAbgByQG5AcgBugG7AbwBvQG+Ab8BwAHBAcIBwwHEAcUBxgEA3AELQQAMxgELQQ4MxQELQQ0MxAELQQ8MwwELQRAMwgELQRMMwQELQRQMwAELQRUMvwELQRYMvgELQRgMvQELQRkMvAELQRoMuwELQRsMugELQRwMuQELQR0MuAELQQgMtwELQR4MtgELQSAMtQELQR8MtAELQQcMswELQSEMsgELQSIMsQELQSMMsAELQSQMrwELQRIMrgELQREMrQELQSUMrAELQSYMqwELQScMqgELQSgMqQELQcMBDKgBC0EqDKcBC0ErDKYBC0EsDKUBC0EtDKQBC0EuDKMBC0EvDKIBC0HEAQyhAQtBMAygAQtBNAyfAQtBDAyeAQtBMQydAQtBMgycAQtBMwybAQtBOQyaAQtBNQyZAQtBxQEMmAELQQsMlwELQToMlgELQTYMlQELQQoMlAELQTcMkwELQTgMkgELQTwMkQELQTsMkAELQT0MjwELQQkMjgELQSkMjQELQT4MjAELQT8MiwELQcAADIoBC0HBAAyJAQtBwgAMiAELQcMADIcBC0HEAAyGAQtBxQAMhQELQcYADIQBC0EXDIMBC0HHAAyCAQtByAAMgQELQckADIABC0HKAAx/C0HLAAx+C0HNAAx9C0HMAAx8C0HOAAx7C0HPAAx6C0HQAAx5C0HRAAx4C0HSAAx3C0HTAAx2C0HUAAx1C0HWAAx0C0HVAAxzC0EGDHILQdcADHELQQUMcAtB2AAMbwtBBAxuC0HZAAxtC0HaAAxsC0HbAAxrC0HcAAxqC0EDDGkLQd0ADGgLQd4ADGcLQd8ADGYLQeEADGULQeAADGQLQeIADGMLQeMADGILQQIMYQtB5AAMYAtB5QAMXwtB5gAMXgtB5wAMXQtB6AAMXAtB6QAMWwtB6gAMWgtB6wAMWQtB7AAMWAtB7QAMVwtB7gAMVgtB7wAMVQtB8AAMVAtB8QAMUwtB8gAMUgtB8wAMUQtB9AAMUAtB9QAMTwtB9gAMTgtB9wAMTQtB+AAMTAtB+QAMSwtB+gAMSgtB+wAMSQtB/AAMSAtB/QAMRwtB/gAMRgtB/wAMRQtBgAEMRAtBgQEMQwtBggEMQgtBgwEMQQtBhAEMQAtBhQEMPwtBhgEMPgtBhwEMPQtBiAEMPAtBiQEMOwtBigEMOgtBiwEMOQtBjAEMOAtBjQEMNwtBjgEMNgtBjwEMNQtBkAEMNAtBkQEMMwtBkgEMMgtBkwEMMQtBlAEMMAtBlQEMLwtBlgEMLgtBlwEMLQtBmAEMLAtBmQEMKwtBmgEMKgtBmwEMKQtBnAEMKAtBnQEMJwtBngEMJgtBnwEMJQtBoAEMJAtBoQEMIwtBogEMIgtBowEMIQtBpAEMIAtBpQEMHwtBpgEMHgtBpwEMHQtBqAEMHAtBqQEMGwtBqgEMGgtBqwEMGQtBrAEMGAtBrQEMFwtBrgEMFgtBAQwVC0GvAQwUC0GwAQwTC0GxAQwSC0GzAQwRC0GyAQwQC0G0AQwPC0G1AQwOC0G2AQwNC0G3AQwMC0G4AQwLC0G5AQwKC0G6AQwJC0G7AQwIC0HGAQwHC0G8AQwGC0G9AQwFC0G+AQwEC0G/AQwDC0HAAQwCC0HCAQwBC0HBAQshAwNAAkACQAJAAkACQAJAAkACQAJAIAICfwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJ/AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgAgJ/AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACfwJAAkACfwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAC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iQEhAwykAgtBASABLQAAQd8ARw1nGiABQQFqIQEMXgtBigEhAyABIARGDaICIAIoAgAiACAEIAFraiEFIAEgAGtBAWohBgNAIAEtAAAgAEGMzwBqLQAARw1kIABBAUYN+gEgAEEBaiEAIAQgAUEBaiIBRw0ACyACIAU2AgAMogILQYsBIQMgASAERg2hAiACKAIAIgAgBCABa2ohBSABIABrQQJqIQYCQANAIAEtAAAgAEGOzwBqLQAARw1kIABBAkYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAyiAgsgAkEANgIAIAZBAWohAUECDGULQYwBIQMgASAERg2gAiACKAIAIgAgBCABa2ohBSABIABrQQFqIQYCQANAIAEtAAAgAEHwzwBqLQAARw1jIABBAUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAyhAgsgAkEANgIAIAZBAWohAUEfDGQLQY0BIQMgASAERg2fAiACKAIAIgAgBCABa2ohBSABIABrQQFqIQYCQANAIAEtAAAgAEHyzwBqLQAARw1iIABBAUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAygAgsgAkEANgIAIAZBAWohAUEJDGMLIAEgBEYEQEGOASEDDJ8CCwJAAkAgAS0AAEHJAGsOBwBiYmJiYgFiCyABQQFqIQFB+AAhAwyGAgsgAUEBaiEBQfkAIQMMhQILQY8BIQMgASAERg2dAiACKAIAIgAgBCABa2ohBSABIABrQQVqIQYCQANAIAEtAAAgAEGRzwBqLQAARw1gIABBBUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAyeAgsgAkEANgIAIAZBAWohAUEYDGELQZABIQMgASAERg2cAiACKAIAIgAgBCABa2ohBSABIABrQQJqIQYCQANAIAEtAAAgAEGXzwBqLQAARw1fIABBAkYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAydAgsgAkEANgIAIAZBAWohAUEXDGALQZEBIQMgASAERg2bAiACKAIAIgAgBCABa2ohBSABIABrQQZqIQYCQANAIAEtAAAgAEGazwBqLQAARw1eIABBBkYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAycAgsgAkEANgIAIAZBAWohAUEV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JSIARQ0RIAJB5QA2AhwgAiABNgIUIAIgADYCDEEAIQMMtAELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0gIAJB0wA2AhwgAiABNgIUIAIgADYCDEEAIQMMswELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0iIAJB0gA2AhwgAiABNgIUIAIgADYCDEEAIQMMsgELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0OIAJB5QA2AhwgAiABNgIUIAIgADYCDEEAIQMMsQELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0dIAJB0wA2AhwgAiABNgIUIAIgADYCDEEAIQMMsAELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0fIAJB0gA2AhwgAiABNgIUIAIgADYCDEEAIQMMrwELIABBP0cNASABQQFqCyEBQQUhAwyUAQtBACEDIAJBADYCHCACIAE2AhQgAkH9EjYCECACQQc2AgwMrAELIAJBADYCHCACIAE2AhQgAkHcCDYCECACQQc2AgxBACEDDKsBCyACKAIEIQAgAkEANgIEIAIgACABECUiAEUNByACQeUANgIcIAIgATYCFCACIAA2AgxBACEDDKoBCyACKAIEIQAgAkEANgIEIAIgACABECUiAEUNFiACQdMANgIcIAIgATYCFCACIAA2AgxBACEDDKkBCyACKAIEIQAgAkEANgIEIAIgACABECUiAEUNGCACQdIANgIcIAIgATYCFCACIAA2AgxBACEDDKgBCyACQQA2AhwgAiABNgIUIAJBxgo2AhAgAkEHNgIMQQAhAwynAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDQMgAkHlADYCHCACIAE2AhQgAiAANgIMQQAhAwymAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDRIgAkHTADYCHCACIAE2AhQgAiAANgIMQQAhAwylAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDRQgAkHSADYCHCACIAE2AhQgAiAANgIMQQAhAwykAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDQAgAkHlADYCHCACIAE2AhQgAiAANgIMQQAhAwyjAQtB1QAhAwyJAQsgAEEVRwRAIAJBADYCHCACIAE2AhQgAkG5DTYCECACQRo2AgxB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AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIABB5ABrDvQDY2IAAWFhYWFhYQIDBAVhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhBgcICQoLDA0OD2FhYWFhEGFhYWFhYWFhYWFhEWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYRITFBUWFxgZGhthYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2YTc4OTphYWFhYWFhYTthYWE8YWFhYT0+P2FhYWFhYWFhQGFhQWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYUJDREVGR0hJSktMTU5PUFFSU2FhYWFhYWFhVFVWV1hZWlthXF1hYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFeYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhX2BhC0HhJw8LQaQhDwtByywPC0H+MQ8LQcAkDwtBqyQPC0GNKA8LQeImDwtBgDAPC0G5Lw8LQdckDwtB7x8PC0HhHw8LQfofDwtB8iAPC0GoLw8LQa4yDwtBiDAPC0HsJw8LQYIiDwtBjh0PC0HQLg8LQcojDwtBxTIPC0HfHA8LQdIcDwtBxCAPC0HXIA8LQaIfDwtB7S4PC0GrMA8LQdQlDwtBzC4PC0H6Lg8LQfwrDwtB0jAPC0HxHQ8LQbsgDwtB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CABB3AgLii1JbnZhbGlkIGNoYXIgaW4gdXJsIHF1ZXJ5AFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fYm9keQBDb250ZW50LUxlbmd0aCBvdmVyZmxvdwBDaHVuayBzaXplIG92ZXJmbG93AFJlc3BvbnNlIG92ZXJmbG93AEludmFsaWQgbWV0aG9kIGZvciBIVFRQL3gueCByZXF1ZXN0AEludmFsaWQgbWV0aG9kIGZvciBSVFNQL3gueCByZXF1ZXN0AEV4cGVjdGVkIFNPVVJDRSBtZXRob2QgZm9yIElDRS94LnggcmVxdWVzdABJbnZhbGlkIGNoYXIgaW4gdXJsIGZyYWdtZW50IHN0YXJ0AEV4cGVjdGVkIGRvdABTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3N0YXR1cwBJbnZhbGlkIHJlc3BvbnNlIHN0YXR1cwBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zAFVzZXIgY2FsbGJhY2sgZXJyb3IAYG9uX3Jlc2V0YCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfaGVhZGVyYCBjYWxsYmFjayBlcnJvcgBgb25fbWVzc2FnZV9iZWdpbmAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2V4dGVuc2lvbl92YWx1ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX3N0YXR1c19jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX3ZlcnNpb25fY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl91cmxfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9jaHVua19jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2hlYWRlcl92YWx1ZV9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX21lc3NhZ2VfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9tZXRob2RfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9oZWFkZXJfZmllbGRfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9jaHVua19leHRlbnNpb25fbmFtZWAgY2FsbGJhY2sgZXJyb3IAVW5leHBlY3RlZCBjaGFyIGluIHVybCBzZXJ2ZXIASW52YWxpZCBoZWFkZXIgdmFsdWUgY2hhcgBJbnZhbGlkIGhlYWRlciBmaWVsZCBjaGFyAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fdmVyc2lvbgBJbnZhbGlkIG1pbm9yIHZlcnNpb24ASW52YWxpZCBtYWpvciB2ZXJzaW9uAEV4cGVjdGVkIHNwYWNlIGFmdGVyIHZlcnNpb24ARXhwZWN0ZWQgQ1JMRiBhZnRlciB2ZXJzaW9uAEludmFsaWQgSFRUUCB2ZXJzaW9uAEludmFsaWQgaGVhZGVyIHRva2VuAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fdXJsAEludmFsaWQgY2hhcmFjdGVycyBpbiB1cmwAVW5leHBlY3RlZCBzdGFydCBjaGFyIGluIHVybABEb3VibGUgQCBpbiB1cmwARW1wdHkgQ29udGVudC1MZW5ndGgASW52YWxpZCBjaGFyYWN0ZXIgaW4gQ29udGVudC1MZW5ndGgARHVwbGljYXRlIENvbnRlbnQtTGVuZ3RoAEludmFsaWQgY2hhciBpbiB1cmwgcGF0aABDb250ZW50LUxlbmd0aCBjYW4ndCBiZSBwcmVzZW50IHdpdGggVHJhbnNmZXItRW5jb2RpbmcASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgc2l6ZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2hlYWRlcl92YWx1ZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2NodW5rX2V4dGVuc2lvbl92YWx1ZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIHZhbHVlAE1pc3NpbmcgZXhwZWN0ZWQgTEYgYWZ0ZXIgaGVhZGVyIHZhbHVlAEludmFsaWQgYFRyYW5zZmVyLUVuY29kaW5nYCBoZWFkZXIgdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyBxdW90ZSB2YWx1ZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIHF1b3RlZCB2YWx1ZQBQYXVzZWQgYnkgb25faGVhZGVyc19jb21wbGV0ZQBJbnZhbGlkIEVPRiBzdGF0ZQBvbl9yZXNldCBwYXVzZQBvbl9jaHVua19oZWFkZXIgcGF1c2UAb25fbWVzc2FnZV9iZWdpbiBwYXVzZQBvbl9jaHVua19leHRlbnNpb25fdmFsdWUgcGF1c2UAb25fc3RhdHVzX2NvbXBsZXRlIHBhdXNlAG9uX3ZlcnNpb25fY29tcGxldGUgcGF1c2UAb25fdXJsX2NvbXBsZXRlIHBhdXNlAG9uX2NodW5rX2NvbXBsZXRlIHBhdXNlAG9uX2hlYWRlcl92YWx1ZV9jb21wbGV0ZSBwYXVzZQBvbl9tZXNzYWdlX2NvbXBsZXRlIHBhdXNlAG9uX21ldGhvZF9jb21wbGV0ZSBwYXVzZQBvbl9oZWFkZXJfZmllbGRfY29tcGxldGUgcGF1c2UAb25fY2h1bmtfZXh0ZW5zaW9uX25hbWUgcGF1c2UAVW5leHBlY3RlZCBzcGFjZSBhZnRlciBzdGFydCBsaW5lAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fY2h1bmtfZXh0ZW5zaW9uX25hbWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyBuYW1lAFBhdXNlIG9uIENPTk5FQ1QvVXBncmFkZQBQYXVzZSBvbiBQUkkvVXBncmFkZQBFeHBlY3RlZCBIVFRQLzIgQ29ubmVjdGlvbiBQcmVmYWNlAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fbWV0aG9kAEV4cGVjdGVkIHNwYWNlIGFmdGVyIG1ldGhvZABTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2hlYWRlcl9maWVsZABQYXVzZWQASW52YWxpZCB3b3JkIGVuY291bnRlcmVkAEludmFsaWQgbWV0aG9kIGVuY291bnRlcmVkAFVuZXhwZWN0ZWQgY2hhciBpbiB1cmwgc2NoZW1hAFJlcXVlc3QgaGFzIGludmFsaWQgYFRyYW5zZmVyLUVuY29kaW5nYABTV0lUQ0hfUFJPWFkAVVNFX1BST1hZAE1LQUNUSVZJVFkAVU5QUk9DRVNTQUJMRV9FTlRJVFkAQ09QWQBNT1ZFRF9QRVJNQU5FTlRMWQBUT09fRUFSTFkATk9USUZZAEZBSUxFRF9ERVBFTkRFTkNZAEJBRF9HQVRFV0FZAFBMQVkAUFVUAENIRUNLT1VUAEdBVEVXQVlfVElNRU9VVABSRVFVRVNUX1RJTUVPVVQATkVUV09SS19DT05ORUNUX1RJTUVPVVQAQ09OTkVDVElPTl9USU1FT1VUAExPR0lOX1RJTUVPVVQATkVUV09SS19SRUFEX1RJTUVPVVQAUE9TVABNSVNESVJFQ1RFRF9SRVFVRVNUAENMSUVOVF9DTE9TRURfUkVRVUVTVABDTElFTlRfQ0xPU0VEX0xPQURfQkFMQU5DRURfUkVRVUVTVABCQURfUkVRVUVTVABIVFRQX1JFUVVFU1RfU0VOVF9UT19IVFRQU19QT1JUAFJFUE9SVABJTV9BX1RFQVBPVABSRVNFVF9DT05URU5UAE5PX0NPTlRFTlQAUEFSVElBTF9DT05URU5UAEhQRV9JTlZBTElEX0NPTlNUQU5UAEhQRV9DQl9SRVNFVABHRVQASFBFX1NUUklDVABDT05GTElDVABURU1QT1JBUllfUkVESVJFQ1QAUEVSTUFORU5UX1JFRElSRUNUAENPTk5FQ1QATVVMVElfU1RBVFVTAEhQRV9JTlZBTElEX1NUQVRVUwBUT09fTUFOWV9SRVFVRVNUUwBFQVJMWV9ISU5UUwBVTkFWQUlMQUJMRV9GT1JfTEVHQUxfUkVBU09OUwBPUFRJT05TAFNXSVRDSElOR19QUk9UT0NPTFMAVkFSSUFOVF9BTFNPX05FR09USUFURVMATVVMVElQTEVfQ0hPSUNFUwBJTlRFUk5BTF9TRVJWRVJfRVJST1IAV0VCX1NFUlZFUl9VTktOT1dOX0VSUk9SAFJBSUxHVU5fRVJST1IASURFTlRJVFlfUFJPVklERVJfQVVUSEVOVElDQVRJT05fRVJST1IAU1NMX0NFUlRJRklDQVRFX0VSUk9SAElOVkFMSURfWF9GT1JXQVJERURfRk9SAFNFVF9QQVJBTUVURVIAR0VUX1BBUkFNRVRFUgBIUEVfVVNFUgBTRUVfT1RIRVIASFBFX0NCX0NIVU5LX0hFQURFUgBNS0NBTEVOREFSAFNFVFVQAFdFQl9TRVJWRVJfSVNfRE9XTgBURUFSRE9XTgBIUEVfQ0xPU0VEX0NPTk5FQ1RJT04ASEVVUklTVElDX0VYUElSQVRJT04ARElTQ09OTkVDVEVEX09QRVJBVElPTgBOT05fQVVUSE9SSVRBVElWRV9JTkZPUk1BVElPTgBIUEVfSU5WQUxJRF9WRVJTSU9OAEhQRV9DQl9NRVNTQUdFX0JFR0lOAFNJVEVfSVNfRlJPWkVOAEhQRV9JTlZBTElEX0hFQURFUl9UT0tFTgBJTlZBTElEX1RPS0VOAEZPUkJJRERFTgBFTkhBTkNFX1lPVVJfQ0FMTQBIUEVfSU5WQUxJRF9VUkwAQkxPQ0tFRF9CWV9QQVJFTlRBTF9DT05UUk9MAE1LQ09MAEFDTABIUEVfSU5URVJOQUwAUkVRVUVTVF9IRUFERVJfRklFTERTX1RPT19MQVJHRV9VTk9GRklDSUFMAEhQRV9PSwBVTkxJTksAVU5MT0NLAFBSSQBSRVRSWV9XSVRIAEhQRV9JTlZBTElEX0NPTlRFTlRfTEVOR1RIAEhQRV9VTkVYUEVDVEVEX0NPTlRFTlRfTEVOR1RIAEZMVVNIAFBST1BQQVRDSABNLVNFQVJDSABVUklfVE9PX0xPTkcAUFJPQ0VTU0lORwBNSVNDRUxMQU5FT1VTX1BFUlNJU1RFTlRfV0FSTklORwBNSVNDRUxMQU5FT1VTX1dBUk5JTkcASFBFX0lOVkFMSURfVFJBTlNGRVJfRU5DT0RJTkcARXhwZWN0ZWQgQ1JMRgBIUEVfSU5WQUxJRF9DSFVOS19TSVpFAE1PVkUAQ09OVElOVUUASFBFX0NCX1NUQVRVU19DT01QTEVURQBIUEVfQ0JfSEVBREVSU19DT01QTEVURQBIUEVfQ0JfVkVSU0lPTl9DT01QTEVURQBIUEVfQ0JfVVJMX0NPTVBMRVRFAEhQRV9DQl9DSFVOS19DT01QTEVURQBIUEVfQ0JfSEVBREVSX1ZBTFVFX0NPTVBMRVRFAEhQRV9DQl9DSFVOS19FWFRFTlNJT05fVkFMVUVfQ09NUExFVEUASFBFX0NCX0NIVU5LX0VYVEVOU0lPTl9OQU1FX0NPTVBMRVRFAEhQRV9DQl9NRVNTQUdFX0NPTVBMRVRFAEhQRV9DQl9NRVRIT0RfQ09NUExFVEUASFBFX0NCX0hFQURFUl9GSUVMRF9DT01QTEVURQBERUxFVEUASFBFX0lOVkFMSURfRU9GX1NUQVRFAElOVkFMSURfU1NMX0NFUlRJRklDQVRFAFBBVVNFAE5PX1JFU1BPTlNFAFVOU1VQUE9SVEVEX01FRElBX1RZUEUAR09ORQBOT1RfQUNDRVBUQUJMRQBTRVJWSUNFX1VOQVZBSUxBQkxFAFJBTkdFX05PVF9TQVRJU0ZJQUJMRQBPUklHSU5fSVNfVU5SRUFDSEFCTEUAUkVTUE9OU0VfSVNfU1RBTEUAUFVSR0UATUVSR0UAUkVRVUVTVF9IRUFERVJfRklFTERTX1RPT19MQVJHRQBSRVFVRVNUX0hFQURFUl9UT09fTEFSR0UAUEFZTE9BRF9UT09fTEFSR0UASU5TVUZGSUNJRU5UX1NUT1JBR0UASFBFX1BBVVNFRF9VUEdSQURFAEhQRV9QQVVTRURfSDJfVVBHUkFERQBTT1VSQ0UAQU5OT1VOQ0UAVFJBQ0UASFBFX1VORVhQRUNURURfU1BBQ0UAREVTQ1JJQkUAVU5TVUJTQ1JJQkUAUkVDT1JEAEhQRV9JTlZBTElEX01FVEhPRABOT1RfRk9VTkQAUFJPUEZJTkQAVU5CSU5EAFJFQklORABVTkFVVEhPUklaRUQATUVUSE9EX05PVF9BTExPV0VEAEhUVFBfVkVSU0lPTl9OT1RfU1VQUE9SVEVEAEFMUkVBRFlfUkVQT1JURUQAQUNDRVBURUQATk9UX0lNUExFTUVOVEVEAExPT1BfREVURUNURUQASFBFX0NSX0VYUEVDVEVEAEhQRV9MRl9FWFBFQ1RFRABDUkVBVEVEAElNX1VTRUQASFBFX1BBVVNFRABUSU1FT1VUX09DQ1VSRUQAUEFZTUVOVF9SRVFVSVJFRABQUkVDT05ESVRJT05fUkVRVUlSRUQAUFJPWFlfQVVUSEVOVElDQVRJT05fUkVRVUlSRUQATkVUV09SS19BVVRIRU5USUNBVElPTl9SRVFVSVJFRABMRU5HVEhfUkVRVUlSRUQAU1NMX0NFUlRJRklDQVRFX1JFUVVJUkVEAFVQR1JBREVfUkVRVUlSRUQAUEFHRV9FWFBJUkVEAFBSRUNPTkRJVElPTl9GQUlMRUQARVhQRUNUQVRJT05fRkFJTEVEAFJFVkFMSURBVElPTl9GQUlMRUQAU1NMX0hBTkRTSEFLRV9GQUlMRUQATE9DS0VEAFRSQU5TRk9STUFUSU9OX0FQUExJRUQATk9UX01PRElGSUVEAE5PVF9FWFRFTkRFRABCQU5EV0lEVEhfTElNSVRfRVhDRUVERUQAU0lURV9JU19PVkVSTE9BREVEAEhFQUQARXhwZWN0ZWQgSFRUUC8AAF4TAAAmEwAAMBAAAPAXAACdEwAAFRIAADkXAADwEgAAChAAAHUSAACtEgAAghMAAE8UAAB/EAAAoBUAACMUAACJEgAAixQAAE0VAADUEQAAzxQAABAYAADJFgAA3BYAAMERAADgFwAAuxQAAHQUAAB8FQAA5RQAAAgXAAAfEAAAZRUAAKMUAAAoFQAAAhUAAJkVAAAsEAAAixkAAE8PAADUDgAAahAAAM4QAAACFwAAiQ4AAG4TAAAcEwAAZhQAAFYXAADBEwAAzRMAAGwTAABoFwAAZhcAAF8XAAAiEwAAzg8AAGkOAADYDgAAYxYAAMsTAACqDgAAKBcAACYXAADFEwAAXRYAAOgRAABnEwAAZRMAAPIWAABzEwAAHRcAAPkWAADzEQAAzw4AAM4VAAAMEgAAsxEAAKURAABhEAAAMhcAALsTAEH5NQsBAQBBkDYL4AEBAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQBB/TcLAQEAQZE4C14CAwICAgICAAACAgACAgACAgICAgICAgICAAQAAAAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAgACAEH9OQsBAQBBkToLXgIAAgICAgIAAAICAAICAAICAgICAgICAgIAAwAEAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAgACAAIAQfA7Cw1sb3NlZWVwLWFsaXZlAEGJPAsBAQBBoDwL4AEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQBBiT4LAQEAQaA+C+cBAQEBAQEBAQEBAQEBAgEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQFjaHVua2VkAEGwwAALXwEBAAEBAQEBAAABAQABAQABAQEBAQEBAQEBAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQABAEGQwgALIWVjdGlvbmVudC1sZW5ndGhvbnJveHktY29ubmVjdGlvbgBBwMIACy1yYW5zZmVyLWVuY29kaW5ncGdyYWRlDQoNCg0KU00NCg0KVFRQL0NFL1RTUC8AQfnCAAsFAQIAAQMAQZDDAAvgAQQBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAEH5xAALBQECAAEDAEGQxQAL4AEEAQEFAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQBB+cYACwQBAAABAEGRxwAL3wEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAEH6yAALBAEAAAIAQZDJAAtfAwQAAAQEBAQEBAQEBAQEBQQEBAQEBAQEBAQEBAAEAAYHBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQABAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAQAQfrKAAsEAQAAAQBBkMsACwEBAEGqywALQQIAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAEH6zAALBAEAAAEAQZDNAAsBAQBBms0ACwYCAAAAAAIAQbHNAAs6AwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwBB8M4AC5YBTk9VTkNFRUNLT1VUTkVDVEVURUNSSUJFTFVTSEVURUFEU0VBUkNIUkdFQ1RJVklUWUxFTkRBUlZFT1RJRllQVElPTlNDSFNFQVlTVEFUQ0hHRU9SRElSRUNUT1JUUkNIUEFSQU1FVEVSVVJDRUJTQ1JJQkVBUkRPV05BQ0VJTkROS0NLVUJTQ1JJQkVIVFRQL0FEVFAv', 'base64'); - return llhttpWasm; -} - -var llhttp_simdWasm; -var hasRequiredLlhttp_simdWasm; - -function requireLlhttp_simdWasm () { - if (hasRequiredLlhttp_simdWasm) return llhttp_simdWasm; - hasRequiredLlhttp_simdWasm = 1; - - const { Buffer } = require$$0$3; - - llhttp_simdWasm = Buffer.from('AGFzbQEAAAABJwdgAX8Bf2ADf39/AX9gAX8AYAJ/fwBgBH9/f38Bf2AAAGADf39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQAEA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAAy0sBQYAAAIAAAAAAAACAQIAAgICAAADAAAAAAMDAwMBAQEBAQEBAQEAAAIAAAAEBQFwARISBQMBAAIGCAF/AUGA1AQLB9EFIgZtZW1vcnkCAAtfaW5pdGlhbGl6ZQAIGV9faW5kaXJlY3RfZnVuY3Rpb25fdGFibGUBAAtsbGh0dHBfaW5pdAAJGGxsaHR0cF9zaG91bGRfa2VlcF9hbGl2ZQAvDGxsaHR0cF9hbGxvYwALBm1hbGxvYwAxC2xsaHR0cF9mcmVlAAwEZnJlZQAMD2xsaHR0cF9nZXRfdHlwZQANFWxsaHR0cF9nZXRfaHR0cF9tYWpvcgAOFWxsaHR0cF9nZXRfaHR0cF9taW5vcgAPEWxsaHR0cF9nZXRfbWV0aG9kABAWbGxodHRwX2dldF9zdGF0dXNfY29kZQAREmxsaHR0cF9nZXRfdXBncmFkZQASDGxsaHR0cF9yZXNldAATDmxsaHR0cF9leGVjdXRlABQUbGxodHRwX3NldHRpbmdzX2luaXQAFQ1sbGh0dHBfZmluaXNoABYMbGxodHRwX3BhdXNlABcNbGxodHRwX3Jlc3VtZQAYG2xsaHR0cF9yZXN1bWVfYWZ0ZXJfdXBncmFkZQAZEGxsaHR0cF9nZXRfZXJybm8AGhdsbGh0dHBfZ2V0X2Vycm9yX3JlYXNvbgAbF2xsaHR0cF9zZXRfZXJyb3JfcmVhc29uABwUbGxodHRwX2dldF9lcnJvcl9wb3MAHRFsbGh0dHBfZXJybm9fbmFtZQAeEmxsaHR0cF9tZXRob2RfbmFtZQAfEmxsaHR0cF9zdGF0dXNfbmFtZQAgGmxsaHR0cF9zZXRfbGVu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PgtBhwEMPQtBiAEMPAtBiQEMOwtBigEMOgtBiwEMOQtBjAEMOAtBjQEMNwtBjgEMNgtBjwEMNQtBkAEMNAtBkQEMMwtBkgEMMgtBkwEMMQtBlAEMMAtBlQEMLwtBlgEMLgtBlwEMLQtBmAEMLAtBmQEMKwtBmgEMKgtBmwEMKQtBnAEMKAtBnQEMJwtBngEMJgtBnwEMJQtBoAEMJAtBoQEMIwtBogEMIgtBowEMIQtBpAEMIAtBpQEMHwtBpgEMHgtBpwEMHQtBqAEMHAtBqQEMGwtBqgEMGgtBqwEMGQtBrAEMGAtBrQEMFwtBrgEMFgtBAQwVC0GvAQwUC0GwAQwTC0GxAQwSC0GzAQwRC0GyAQwQC0G0AQwPC0G1AQwOC0G2AQwNC0G3AQwMC0G4AQwLC0G5AQwKC0G6AQwJC0G7AQwIC0HGAQwHC0G8AQwGC0G9AQwFC0G+AQwEC0G/AQwDC0HAAQwCC0HCAQwBC0HBAQshAwNAAkACQAJAAkACQAJAAkACQAJAIAICfwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJ/AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgAgJ/AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACfwJAAkACfwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACfwJAAkACQAJAAn8CQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCADDsYBAAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHyAhIyUmKCorLC8wMTIzNDU2Nzk6Ozw9lANAQkRFRklLTk9QUVJTVFVWWFpbXF1eX2BhYmNkZWZnaGpsb3Bxc3V2eHl6e3x/gAGBAYIBgwGEAYUBhgGHAYgBiQGKAYsBjAGNAY4BjwGQAZEBkgGTAZQBlQGWAZcBmAGZAZoBmwGcAZ0BngGfAaABoQGiAaMBpAGlAaYBpwGoAakBqgGrAawBrQGuAa8BsAGxAbIBswG0AbUBtgG3AbgBuQG6AbsBvAG9Ab4BvwHAAcEBwgHDAcQBxQHGAccByAHJAcsBzAHNAc4BzwGKA4kDiAOHA4QDgwOAA/sC+gL5AvgC9wL0AvMC8gLLAsECsALZAQsgASAERw3wAkHdASEDDLMDCyABIARHDcgBQcMBIQMMsgMLIAEgBEcNe0H3ACEDDLEDCyABIARHDXBB7wAhAwywAwsgASAERw1pQeoAIQMMrwMLIAEgBEcNZUHoACEDDK4DCyABIARHDWJB5gAhAwytAwsgASAERw0aQRghAwysAwsgASAERw0VQRIhAwyrAwsgASAERw1CQcUAIQMMqgMLIAEgBEcNNEE/IQMMqQMLIAEgBEcNMkE8IQMMqAMLIAEgBEcNK0ExIQMMpwMLIAItAC5BAUYNnwMMwQILQQAhAAJAAkACQCACLQAqRQ0AIAItACtFDQAgAi8BMCIDQQJxRQ0BDAILIAIvATAiA0EBcUUNAQtBASEAIAItAChBAUYNACACLwEyIgVB5ABrQeQASQ0AIAVBzAFGDQAgBUGwAkYNACADQcAAcQ0AQQAhACADQYgEcUGABEYNACADQShxQQBHIQALIAJBADsBMCACQQA6AC8gAEUN3wIgAkIANwMgDOACC0EAIQACQCACKAI4IgNFDQAgAygCLCIDRQ0AIAIgAxEAACEACyAARQ3MASAAQRVHDd0CIAJBBDYCHCACIAE2AhQgAkGwGDYCECACQRU2AgxBACEDDKQDCyABIARGBEBBBiEDDKQDCyABQQFqIQFBACEAAkAgAigCOCIDRQ0AIAMoAlQiA0UNACACIAMRAAAhAAsgAA3ZAgwcCyACQgA3AyBBEiEDDIkDCyABIARHDRZBHSEDDKEDCyABIARHBEAgAUEBaiEBQRAhAwyIAwtBByEDDKADCyACIAIpAyAiCiAEIAFrrSILfSIMQgAgCiAMWhs3AyAgCiALWA3UAkEIIQMMnwMLIAEgBEcEQCACQQk2AgggAiABNgIEQRQhAwyGAwtBCSEDDJ4DCyACKQMgQgBSDccBIAIgAi8BMEGAAXI7ATAMQgsgASAERw0/QdAAIQMMnAMLIAEgBEYEQEELIQMMnAMLIAFBAWohAUEAIQACQCACKAI4IgNFDQAgAygCUCIDRQ0AIAIgAxEAACEACyAADc8CDMYBC0EAIQACQCACKAI4IgNFDQAgAygCSCIDRQ0AIAIgAxEAACEACyAARQ3GASAAQRVHDc0CIAJBCzYCHCACIAE2AhQgAkGCGTYCECACQRU2AgxBACEDDJoDC0EAIQACQCACKAI4IgNFDQAgAygCSCIDRQ0AIAIgAxEAACEACyAARQ0MIABBFUcNygIgAkEaNgIcIAIgATYCFCACQYIZNgIQIAJBFTYCDEEAIQMMmQMLQQAhAAJAIAIoAjgiA0UNACADKAJMIgNFDQAgAiADEQAAIQALIABFDcQBIABBFUcNxwIgAkELNgIcIAIgATYCFCACQZEXNgIQIAJBFTYCDEEAIQMMmAMLIAEgBEYEQEEPIQMMmAMLIAEtAAAiAEE7Rg0HIABBDUcNxAIgAUEBaiEBDMMBC0EAIQACQCACKAI4IgNFDQAgAygCTCIDRQ0AIAIgAxEAACEACyAARQ3DASAAQRVHDcICIAJBDzYCHCACIAE2AhQgAkGRFzYCECACQRU2AgxBACEDDJYDCwNAIAEtAABB8DVqLQAAIgBBAUcEQCAAQQJHDcECIAIoAgQhAEEAIQMgAkEANgIEIAIgACABQQFqIgEQLSIADcICDMUBCyAEIAFBAWoiAUcNAAtBEiEDDJUDC0EAIQACQCACKAI4IgNFDQAgAygCTCIDRQ0AIAIgAxEAACEACyAARQ3FASAAQRVHDb0CIAJBGzYCHCACIAE2AhQgAkGRFzYCECACQRU2AgxBACEDDJQDCyABIARGBEBBFiEDDJQDCyACQQo2AgggAiABNgIEQQAhAAJAIAIoAjgiA0UNACADKAJIIgNFDQAgAiADEQAAIQALIABFDcIBIABBFUcNuQIgAkEVNgIcIAIgATYCFCACQYIZNgIQIAJBFTYCDEEAIQMMkwMLIAEgBEcEQANAIAEtAABB8DdqLQAAIgBBAkcEQAJAIABBAWsOBMQCvQIAvgK9AgsgAUEBaiEBQQghAwz8AgsgBCABQQFqIgFHDQALQRUhAwyTAwtBFSEDDJIDCwNAIAEtAABB8DlqLQAAIgBBAkcEQCAAQQFrDgTFArcCwwK4ArcCCyAEIAFBAWoiAUcNAAtBGCEDDJEDCyABIARHBEAgAkELNgIIIAIgATYCBEEHIQMM+AILQRkhAwyQAwsgAUEBaiEBDAILIAEgBEYEQEEaIQMMjwMLAkAgAS0AAEENaw4UtQG/Ab8BvwG/Ab8BvwG/Ab8BvwG/Ab8BvwG/Ab8BvwG/Ab8BvwEAvwELQQAhAyACQQA2AhwgAkGvCzYCECACQQI2AgwgAiABQQFqNgIUDI4DCyABIARGBEBBGyEDDI4DCyABLQAAIgBBO0cEQCAAQQ1HDbECIAFBAWohAQy6AQsgAUEBaiEBC0EiIQMM8wILIAEgBEYEQEEcIQMMjAMLQgAhCgJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgAS0AAEEwaw43wQLAAgABAgMEBQYH0AHQAdAB0AHQAdAB0AEICQoLDA3QAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdABDg8QERIT0AELQgIhCgzAAgtCAyEKDL8CC0IEIQoMvgILQgUhCgy9AgtCBiEKDLwCC0IHIQoMuwILQgghCgy6AgtCCSEKDLkCC0IKIQoMuAILQgshCgy3AgtCDCEKDLYCC0INIQoMtQILQg4hCgy0AgtCDyEKDLMCC0IKIQoMsgILQgshCgyxAgtCDCEKDLACC0INIQoMrwILQg4hCgyuAgtCDyEKDK0CC0IAIQoCQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIAEtAABBMGsON8ACvwIAAQIDBAUGB74CvgK+Ar4CvgK+Ar4CCAkKCwwNvgK+Ar4CvgK+Ar4CvgK+Ar4CvgK+Ar4CvgK+Ar4CvgK+Ar4CvgK+Ar4CvgK+Ar4CvgK+Ag4PEBESE74CC0ICIQoMvwILQgMhCgy+AgtCBCEKDL0CC0IFIQoMvAILQgYhCgy7AgtCByEKDLoCC0IIIQoMuQILQgkhCgy4AgtCCiEKDLcCC0ILIQoMtgILQgwhCgy1AgtCDSEKDLQCC0IOIQoMswILQg8hCgyyAgtCCiEKDLECC0ILIQoMsAILQgwhCgyvAgtCDSEKDK4CC0IOIQoMrQILQg8hCgysAgsgAiACKQMgIgogBCABa60iC30iDEIAIAogDFobNwMgIAogC1gNpwJBHyEDDIkDCyABIARHBEAgAkEJNgIIIAIgATYCBEElIQMM8AILQSAhAwyIAwtBASEFIAIvATAiA0EIcUUEQCACKQMgQgBSIQULAkAgAi0ALgRAQQEhACACLQApQQVGDQEgA0HAAHFFIAVxRQ0BC0EAIQAgA0HAAHENAEECIQAgA0EIcQ0AIANBgARxBEACQCACLQAoQQFHDQAgAi0ALUEKcQ0AQQUhAAwCC0EEIQAMAQsgA0EgcUUEQAJAIAItAChBAUYNACACLwEyIgBB5ABrQeQASQ0AIABBzAFGDQAgAEGwAkYNAEEEIQAgA0EocUUNAiADQYgEcUGABEYNAgtBACEADAELQQBBAyACKQMgUBshAAsgAEEBaw4FvgIAsAEBpAKhAgtBESEDDO0CCyACQQE6AC8MhAMLIAEgBEcNnQJBJCEDDIQDCyABIARHDRxBxgAhAwyDAwtBACEAAkAgAigCOCIDRQ0AIAMoAkQiA0UNACACIAMRAAAhAAsgAEUNJyAAQRVHDZgCIAJB0AA2AhwgAiABNgIUIAJBkRg2AhAgAkEVNgIMQQAhAwyCAwsgASAERgRAQSghAwyCAwtBACEDIAJBADYCBCACQQw2AgggAiABIAEQKiIARQ2UAiACQSc2AhwgAiABNgIUIAIgADYCDAyBAwsgASAERgRAQSkhAwyBAwsgAS0AACIAQSBGDRMgAEEJRw2VAiABQQFqIQEMFAsgASAERwRAIAFBAWohAQwWC0EqIQMM/wILIAEgBEYEQEErIQMM/wILIAEtAAAiAEEJRyAAQSBHcQ2QAiACLQAsQQhHDd0CIAJBADoALAzdAgsgASAERgRAQSwhAwz+AgsgAS0AAEEKRw2OAiABQQFqIQEMsAELIAEgBEcNigJBLyEDDPwCCwNAIAEtAAAiAEEgRwRAIABBCmsOBIQCiAKIAoQChgILIAQgAUEBaiIBRw0AC0ExIQMM+wILQTIhAyABIARGDfoCIAIoAgAiACAEIAFraiEHIAEgAGtBA2ohBgJAA0AgAEHwO2otAAAgAS0AACIFQSByIAUgBUHBAGtB/wFxQRpJG0H/AXFHDQEgAEEDRgRAQQYhAQziAgsgAEEBaiEAIAQgAUEBaiIBRw0ACyACIAc2AgAM+wILIAJBADYCAAyGAgtBMyEDIAQgASIARg35AiAEIAFrIAIoAgAiAWohByAAIAFrQQhqIQYCQANAIAFB9DtqLQAAIAAtAAAiBUEgciAFIAVBwQBrQf8BcUEaSRtB/wFxRw0BIAFBCEYEQEEFIQEM4QILIAFBAWohASAEIABBAWoiAEcNAAsgAiAHNgIADPoCCyACQQA2AgAgACEBDIUCC0E0IQMgBCABIgBGDfgCIAQgAWsgAigCACIBaiEHIAAgAWtBBWohBgJAA0AgAUHQwgBqLQAAIAAtAAAiBUEgciAFIAVBwQBrQf8BcUEaSRtB/wFxRw0BIAFBBUYEQEEHIQEM4AILIAFBAWohASAEIABBAWoiAEcNAAsgAiAHNgIADPkCCyACQQA2AgAgACEBDIQCCyABIARHBEADQCABLQAAQYA+ai0AACIAQQFHBEAgAEECRg0JDIECCyAEIAFBAWoiAUcNAAtBMCEDDPgCC0EwIQMM9wILIAEgBEcEQANAIAEtAAAiAEEgRwRAIABBCmsOBP8B/gH+Af8B/gELIAQgAUEBaiIBRw0AC0E4IQMM9wILQTghAwz2AgsDQCABLQAAIgBBIEcgAEEJR3EN9gEgBCABQQFqIgFHDQALQTwhAwz1AgsDQCABLQAAIgBBIEcEQAJAIABBCmsOBPkBBAT5AQALIABBLEYN9QEMAwsgBCABQQFqIgFHDQALQT8hAwz0AgtBwAAhAyABIARGDfMCIAIoAgAiACAEIAFraiEFIAEgAGtBBmohBgJAA0AgAEGAQGstAAAgAS0AAEEgckcNASAAQQZGDdsCIABBAWohACAEIAFBAWoiAUcNAAsgAiAFNgIADPQCCyACQQA2AgALQTYhAwzZAgsgASAERgRAQcEAIQMM8gILIAJBDDYCCCACIAE2AgQgAi0ALEEBaw4E+wHuAewB6wHUAgsgAUEBaiEBDPoBCyABIARHBEADQAJAIAEtAAAiAEEgciAAIABBwQBrQf8BcUEaSRtB/wFxIgBBCUYNACAAQSBGDQACQAJAAkACQCAAQeMAaw4TAAMDAwMDAwMBAwMDAwMDAwMDAgMLIAFBAWohAUExIQMM3AILIAFBAWohAUEyIQMM2wILIAFBAWohAUEzIQMM2gILDP4BCyAEIAFBAWoiAUcNAAtBNSEDDPACC0E1IQMM7wILIAEgBEcEQANAIAEtAABBgDxqLQAAQQFHDfcBIAQgAUEBaiIBRw0AC0E9IQMM7wILQT0hAwzuAgtBACEAAkAgAigCOCIDRQ0AIAMoAkAiA0UNACACIAMRAAAhAAsgAEUNASAAQRVHDeYBIAJBwgA2AhwgAiABNgIUIAJB4xg2AhAgAkEVNgIMQQAhAwztAgsgAUEBaiEBC0E8IQMM0gILIAEgBEYEQEHCACEDDOsCCwJAA0ACQCABLQAAQQlrDhgAAswCzALRAswCzALMAswCzALMAswCzALMAswCzALMAswCzALMAswCzALMAgDMAgsgBCABQQFqIgFHDQALQcIAIQMM6wILIAFBAWohASACLQAtQQFxRQ3+AQtBLCEDDNACCyABIARHDd4BQcQAIQMM6AILA0AgAS0AAEGQwABqLQAAQQFHDZwBIAQgAUEBaiIBRw0AC0HFACEDDOcCCyABLQAAIgBBIEYN/gEgAEE6Rw3AAiACKAIEIQBBACEDIAJBADYCBCACIAAgARApIgAN3gEM3QELQccAIQMgBCABIgBGDeUCIAQgAWsgAigCACIBaiEHIAAgAWtBBWohBgNAIAFBkMIAai0AACAALQAAIgVBIHIgBSAFQcEAa0H/AXFBGkkbQf8BcUcNvwIgAUEFRg3CAiABQQFqIQEgBCAAQQFqIgBHDQALIAIgBzYCAAzlAgtByAAhAyAEIAEiAEYN5AIgBCABayACKAIAIgFqIQcgACABa0EJaiEGA0AgAUGWwgBqLQAAIAAtAAAiBUEgciAFIAVBwQBrQf8BcUEaSRtB/wFxRw2+AkECIAFBCUYNwgIaIAFBAWohASAEIABBAWoiAEcNAAsgAiAHNgIADOQCCyABIARGBEBByQAhAwzkAgsCQAJAIAEtAAAiAEEgciAAIABBwQBrQf8BcUEaSRtB/wFxQe4Aaw4HAL8CvwK/Ar8CvwIBvwILIAFBAWohAUE+IQMMywILIAFBAWohAUE/IQMMygILQcoAIQMgBCABIgBGDeICIAQgAWsgAigCACIBaiEGIAAgAWtBAWohBwNAIAFBoMIAai0AACAALQAAIgVBIHIgBSAFQcEAa0H/AXFBGkkbQf8BcUcNvAIgAUEBRg2+AiABQQFqIQEgBCAAQQFqIgBHDQALIAIgBjYCAAziAgtBywAhAyAEIAEiAEYN4QIgBCABayACKAIAIgFqIQcgACABa0EOaiEGA0AgAUGiwgBqLQAAIAAtAAAiBUEgciAFIAVBwQBrQf8BcUEaSRtB/wFxRw27AiABQQ5GDb4CIAFBAWohASAEIABBAWoiAEcNAAsgAiAHNgIADOECC0HMACEDIAQgASIARg3gAiAEIAFrIAIoAgAiAWohByAAIAFrQQ9qIQYDQCABQcDCAGotAAAgAC0AACIFQSByIAUgBUHBAGtB/wFxQRpJG0H/AXFHDboCQQMgAUEPRg2+AhogAUEBaiEBIAQgAEEBaiIARw0ACyACIAc2AgAM4AILQc0AIQMgBCABIgBGDd8CIAQgAWsgAigCACIBaiEHIAAgAWtBBWohBgNAIAFB0MIAai0AACAALQAAIgVBIHIgBSAFQcEAa0H/AXFBGkkbQf8BcUcNuQJBBCABQQVGDb0CGiABQQFqIQEgBCAAQQFqIgBHDQALIAIgBzYCAAzfAgsgASAERgRAQc4AIQMM3wILAkACQAJAAkAgAS0AACIAQSByIAAgAEHBAGtB/wFxQRpJG0H/AXFB4wBrDhMAvAK8ArwCvAK8ArwCvAK8ArwCvAK8ArwCAbwCvAK8AgIDvAILIAFBAWohAUHBACEDDMgCCyABQQFqIQFBwgAhAwzHAgsgAUEBaiEBQcMAIQMMxgILIAFBAWohAUHEACEDDMUCCyABIARHBEAgAkENNgIIIAIgATYCBEHFACEDDMUCC0HPACEDDN0CCwJAAkAgAS0AAEEKaw4EAZABkAEAkAELIAFBAWohAQtBKCEDDMMCCyABIARGBEBB0QAhAwzcAgsgAS0AAEEgRw0AIAFBAWohASACLQAtQQFxRQ3QAQtBFyEDDMECCyABIARHDcsBQdIAIQMM2QILQdMAIQMgASAERg3YAiACKAIAIgAgBCABa2ohBiABIABrQQFqIQUDQCABLQAAIABB1sIAai0AAEcNxwEgAEEBRg3KASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBjYCAAzYAgsgASAERgRAQdUAIQMM2AILIAEtAABBCkcNwgEgAUEBaiEBDMoBCyABIARGBEBB1gAhAwzXAgsCQAJAIAEtAABBCmsOBADDAcMBAcMBCyABQQFqIQEMygELIAFBAWohAUHKACEDDL0CC0EAIQACQCACKAI4IgNFDQAgAygCPCIDRQ0AIAIgAxEAACEACyAADb8BQc0AIQMMvAILIAItAClBIkYNzwIMiQELIAQgASIFRgRAQdsAIQMM1AILQQAhAEEBIQFBASEGQQAhAwJAAn8CQAJAAkACQAJAAkACQCAFLQAAQTBrDgrFAcQBAAECAwQFBgjDAQtBAgwGC0EDDAULQQQMBAtBBQwDC0EGDAILQQcMAQtBCAshA0EAIQFBACEGDL0BC0EJIQNBASEAQQAhAUEAIQYMvAELIAEgBEYEQEHdACEDDNMCCyABLQAAQS5HDbgBIAFBAWohAQyIAQsgASAERw22AUHfACEDDNECCyABIARHBEAgAkEONgIIIAIgATYCBEHQACEDDLgCC0HgACEDDNACC0HhACEDIAEgBEYNzwIgAigCACIAIAQgAWtqIQUgASAAa0EDaiEGA0AgAS0AACAAQeLCAGotAABHDbEBIABBA0YNswEgAEEBaiEAIAQgAUEBaiIBRw0ACyACIAU2AgAMzwILQeIAIQMgASAERg3OAiACKAIAIgAgBCABa2ohBSABIABrQQJqIQYDQCABLQAAIABB5sIAai0AAEcNsAEgAEECRg2vASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAzOAgtB4wAhAyABIARGDc0CIAIoAgAiACAEIAFraiEFIAEgAGtBA2ohBgNAIAEtAAAgAEHpwgBqLQAARw2vASAAQQNGDa0BIABBAWohACAEIAFBAWoiAUcNAAsgAiAFNgIADM0CCyABIARGBEBB5QAhAwzNAgsgAUEBaiEBQQAhAAJAIAIoAjgiA0UNACADKAIwIgNFDQAgAiADEQAAIQALIAANqgFB1gAhAwyzAgsgASAERwRAA0AgAS0AACIAQSBHBEACQAJAAkAgAEHIAGsOCwABswGzAbMBswGzAbMBswGzAQKzAQsgAUEBaiEBQdIAIQMMtwILIAFBAWohAUHTACEDDLYCCyABQQFqIQFB1AAhAwy1AgsgBCABQQFqIgFHDQALQeQAIQMMzAILQeQAIQMMywILA0AgAS0AAEHwwgBqLQAAIgBBAUcEQCAAQQJrDgOnAaYBpQGkAQsgBCABQQFqIgFHDQALQeYAIQMMygILIAFBAWogASAERw0CGkHnACEDDMkCCwNAIAEtAABB8MQAai0AACIAQQFHBEACQCAAQQJrDgSiAaEBoAEAnwELQdcAIQMMsQILIAQgAUEBaiIBRw0AC0HoACEDDMgCCyABIARGBEBB6QAhAwzIAgsCQCABLQAAIgBBCmsOGrcBmwGbAbQBmwGbAZsBmwGbAZsBmwGbAZsBmwGbAZsBmwGbAZsBmwGbAZsBpAGbAZsBAJkBCyABQQFqCyEBQQYhAwytAgsDQCABLQAAQfDGAGotAABBAUcNfSAEIAFBAWoiAUcNAAtB6gAhAwzFAgsgAUEBaiABIARHDQIaQesAIQMMxAILIAEgBEYEQEHsACEDDMQCCyABQQFqDAELIAEgBEYEQEHtACEDDMMCCyABQQFqCyEBQQQhAwyoAgsgASAERgRAQe4AIQMMwQILAkACQAJAIAEtAABB8MgAai0AAEEBaw4HkAGPAY4BAHwBAo0BCyABQQFqIQEMCwsgAUEBagyTAQtBACEDIAJBADYCHCACQZsSNgIQIAJBBzYCDCACIAFBAWo2AhQMwAILAkADQCABLQAAQfDIAGotAAAiAEEERwRAAkACQCAAQQFrDgeUAZMBkgGNAQAEAY0BC0HaACEDDKoCCyABQQFqIQFB3AAhAwypAgsgBCABQQFqIgFHDQALQe8AIQMMwAILIAFBAWoMkQELIAQgASIARgRAQfAAIQMMvwILIAAtAABBL0cNASAAQQFqIQEMBwsgBCABIgBGBEBB8QAhAwy+AgsgAC0AACIBQS9GBEAgAEEBaiEBQd0AIQMMpQILIAFBCmsiA0EWSw0AIAAhAUEBIAN0QYmAgAJxDfkBC0EAIQMgAkEANgIcIAIgADYCFCACQYwcNgIQIAJBBzYCDAy8AgsgASAERwRAIAFBAWohAUHeACEDDKMCC0HyACEDDLsCCyABIARGBEBB9AAhAwy7AgsCQCABLQAAQfDMAGotAABBAWsOA/cBcwCCAQtB4QAhAwyhAgsgASAERwRAA0AgAS0AAEHwygBqLQAAIgBBA0cEQAJAIABBAWsOAvkBAIUBC0HfACEDDKMCCyAEIAFBAWoiAUcNAAtB8wAhAwy6AgtB8wAhAwy5AgsgASAERwRAIAJBDzYCCCACIAE2AgRB4AAhAwygAgtB9QAhAwy4AgsgASAERgRAQfYAIQMMuAILIAJBDzYCCCACIAE2AgQLQQMhAwydAgsDQCABLQAAQSBHDY4CIAQgAUEBaiIBRw0AC0H3ACEDDLUCCyABIARGBEBB+AAhAwy1AgsgAS0AAEEgRw16IAFBAWohAQxbC0EAIQACQCACKAI4IgNFDQAgAygCOCIDRQ0AIAIgAxEAACEACyAADXgMgAILIAEgBEYEQEH6ACEDDLMCCyABLQAAQcwARw10IAFBAWohAUETDHYLQfsAIQMgASAERg2xAiACKAIAIgAgBCABa2ohBSABIABrQQVqIQYDQCABLQAAIABB8M4Aai0AAEcNcyAAQQVGDXUgAEEBaiEAIAQgAUEBaiIBRw0ACyACIAU2AgAMsQILIAEgBEYEQEH8ACEDDLECCwJAAkAgAS0AAEHDAGsODAB0dHR0dHR0dHR0AXQLIAFBAWohAUHmACEDDJgCCyABQQFqIQFB5wAhAwyXAgtB/QAhAyABIARGDa8CIAIoAgAiACAEIAFraiEFIAEgAGtBAmohBgJAA0AgAS0AACAAQe3PAGotAABHDXIgAEECRg0BIABBAWohACAEIAFBAWoiAUcNAAsgAiAFNgIADLACCyACQQA2AgAgBkEBaiEBQRAMcwtB/gAhAyABIARGDa4CIAIoAgAiACAEIAFraiEFIAEgAGtBBWohBgJAA0AgAS0AACAAQfbOAGotAABHDXEgAEEFRg0BIABBAWohACAEIAFBAWoiAUcNAAsgAiAFNgIADK8CCyACQQA2AgAgBkEBaiEBQRYMcgtB/wAhAyABIARGDa0CIAIoAgAiACAEIAFraiEFIAEgAGtBA2ohBgJAA0AgAS0AACAAQfzOAGotAABHDXAgAEEDRg0BIABBAWohACAEIAFBAWoiAUcNAAsgAiAFNgIADK4CCyACQQA2AgAgBkEBaiEBQQUMcQsgASAERgRAQYABIQMMrQILIAEtAABB2QBHDW4gAUEBaiEBQQgMcAsgASAERgRAQYEBIQMMrAILAkACQCABLQAAQc4Aaw4DAG8BbwsgAUEBaiEBQesAIQMMkwILIAFBAWohAUHsACEDDJICCyABIARGBEBBggEhAwyrAgsCQAJAIAEtAABByABrDggAbm5ubm5uAW4LIAFBAWohAUHqACEDDJICCyABQQFqIQFB7QAhAwyRAgtBgwEhAyABIARGDakCIAIoAgAiACAEIAFraiEFIAEgAGtBAmohBgJAA0AgAS0AACAAQYDPAGotAABHDWwgAEECRg0BIABBAWohACAEIAFBAWoiAUcNAAsgAiAFNgIADKoCCyACQQA2AgAgBkEBaiEBQQAMbQtBhAEhAyABIARGDagCIAIoAgAiACAEIAFraiEFIAEgAGtBBGohBgJAA0AgAS0AACAAQYPPAGotAABHDWsgAEEERg0BIABBAWohACAEIAFBAWoiAUcNAAsgAiAFNgIADKkCCyACQQA2AgAgBkEBaiEBQSMMbAsgASAERgRAQYUBIQMMqAILAkACQCABLQAAQcwAaw4IAGtra2trawFrCyABQQFqIQFB7wAhAwyPAgsgAUEBaiEBQfAAIQMMjgILIAEgBEYEQEGGASEDDKcCCyABLQAAQcUARw1oIAFBAWohAQxgC0GHASEDIAEgBEYNpQIgAigCACIAIAQgAWtqIQUgASAAa0EDaiEGAkADQCABLQAAIABBiM8Aai0AAEcNaCAAQQNGDQEgAEEBaiEAIAQgAUEBaiIBRw0ACyACIAU2AgAMpgILIAJBADYCACAGQQFqIQFBLQxpC0GIASEDIAEgBEYNpAIgAigCACIAIAQgAWtqIQUgASAAa0EIaiEGAkADQCABLQAAIABB0M8Aai0AAEcNZyAAQQhGDQEgAEEBaiEAIAQgAUEBaiIBRw0ACyACIAU2AgAMpQILIAJBADYCACAGQQFqIQFBKQxoCyABIARGBEBBiQEhAwykAgtBASABLQAAQd8ARw1nGiABQQFqIQEMXgtBigEhAyABIARGDaICIAIoAgAiACAEIAFraiEFIAEgAGtBAWohBgNAIAEtAAAgAEGMzwBqLQAARw1kIABBAUYN+gEgAEEBaiEAIAQgAUEBaiIBRw0ACyACIAU2AgAMogILQYsBIQMgASAERg2hAiACKAIAIgAgBCABa2ohBSABIABrQQJqIQYCQANAIAEtAAAgAEGOzwBqLQAARw1kIABBAkYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAyiAgsgAkEANgIAIAZBAWohAUECDGULQYwBIQMgASAERg2gAiACKAIAIgAgBCABa2ohBSABIABrQQFqIQYCQANAIAEtAAAgAEHwzwBqLQAARw1jIABBAUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAyhAgsgAkEANgIAIAZBAWohAUEfDGQLQY0BIQMgASAERg2fAiACKAIAIgAgBCABa2ohBSABIABrQQFqIQYCQANAIAEtAAAgAEHyzwBqLQAARw1iIABBAUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAygAgsgAkEANgIAIAZBAWohAUEJDGMLIAEgBEYEQEGOASEDDJ8CCwJAAkAgAS0AAEHJAGsOBwBiYmJiYgFiCyABQQFqIQFB+AAhAwyGAgsgAUEBaiEBQfkAIQMMhQILQY8BIQMgASAERg2dAiACKAIAIgAgBCABa2ohBSABIABrQQVqIQYCQANAIAEtAAAgAEGRzwBqLQAARw1gIABBBUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAyeAgsgAkEANgIAIAZBAWohAUEYDGELQZABIQMgASAERg2cAiACKAIAIgAgBCABa2ohBSABIABrQQJqIQYCQANAIAEtAAAgAEGXzwBqLQAARw1fIABBAkYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAydAgsgAkEANgIAIAZBAWohAUEXDGALQZEBIQMgASAERg2bAiACKAIAIgAgBCABa2ohBSABIABrQQZqIQYCQANAIAEtAAAgAEGazwBqLQAARw1eIABBBkYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAycAgsgAkEANgIAIAZBAWohAUEV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JSIARQ0RIAJB5QA2AhwgAiABNgIUIAIgADYCDEEAIQMMtAELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0gIAJB0wA2AhwgAiABNgIUIAIgADYCDEEAIQMMswELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0iIAJB0gA2AhwgAiABNgIUIAIgADYCDEEAIQMMsgELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0OIAJB5QA2AhwgAiABNgIUIAIgADYCDEEAIQMMsQELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0dIAJB0wA2AhwgAiABNgIUIAIgADYCDEEAIQMMsAELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0fIAJB0gA2AhwgAiABNgIUIAIgADYCDEEAIQMMrwELIABBP0cNASABQQFqCyEBQQUhAwyUAQtBACEDIAJBADYCHCACIAE2AhQgAkH9EjYCECACQQc2AgwMrAELIAJBADYCHCACIAE2AhQgAkHcCDYCECACQQc2AgxBACEDDKsBCyACKAIEIQAgAkEANgIEIAIgACABECUiAEUNByACQeUANgIcIAIgATYCFCACIAA2AgxBACEDDKoBCyACKAIEIQAgAkEANgIEIAIgACABECUiAEUNFiACQdMANgIcIAIgATYCFCACIAA2AgxBACEDDKkBCyACKAIEIQAgAkEANgIEIAIgACABECUiAEUNGCACQdIANgIcIAIgATYCFCACIAA2AgxBACEDDKgBCyACQQA2AhwgAiABNgIUIAJBxgo2AhAgAkEHNgIMQQAhAwynAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDQMgAkHlADYCHCACIAE2AhQgAiAANgIMQQAhAwymAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDRIgAkHTADYCHCACIAE2AhQgAiAANgIMQQAhAwylAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDRQgAkHSADYCHCACIAE2AhQgAiAANgIMQQAhAwykAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDQAgAkHlADYCHCACIAE2AhQgAiAANgIMQQAhAwyjAQtB1QAhAwyJAQsgAEEVRwRAIAJBADYCHCACIAE2AhQgAkG5DTYCECACQRo2AgxB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AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIABB5ABrDvQDY2IAAWFhYWFhYQIDBAVhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhBgcICQoLDA0OD2FhYWFhEGFhYWFhYWFhYWFhEWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYRITFBUWFxgZGhthYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2YTc4OTphYWFhYWFhYTthYWE8YWFhYT0+P2FhYWFhYWFhQGFhQWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYUJDREVGR0hJSktMTU5PUFFSU2FhYWFhYWFhVFVWV1hZWlthXF1hYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFeYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhX2BhC0HhJw8LQaQhDwtByywPC0H+MQ8LQcAkDwtBqyQPC0GNKA8LQeImDwtBgDAPC0G5Lw8LQdckDwtB7x8PC0HhHw8LQfofDwtB8iAPC0GoLw8LQa4yDwtBiDAPC0HsJw8LQYIiDwtBjh0PC0HQLg8LQcojDwtBxTIPC0HfHA8LQdIcDwtBxCAPC0HXIA8LQaIfDwtB7S4PC0GrMA8LQdQlDwtBzC4PC0H6Lg8LQfwrDwtB0jAPC0HxHQ8LQbsgDwtB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AAADAEGUCAsFBAAAAAUAQaQICwkGAAAABwAAAAgAQdwIC4otSW52YWxpZCBjaGFyIGluIHVybCBxdWVyeQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2JvZHkAQ29udGVudC1MZW5ndGggb3ZlcmZsb3cAQ2h1bmsgc2l6ZSBvdmVyZmxvdwBSZXNwb25zZSBvdmVyZmxvdwBJbnZhbGlkIG1ldGhvZCBmb3IgSFRUUC94LnggcmVxdWVzdABJbnZhbGlkIG1ldGhvZCBmb3IgUlRTUC94LnggcmVxdWVzdABFeHBlY3RlZCBTT1VSQ0UgbWV0aG9kIGZvciBJQ0UveC54IHJlcXVlc3QASW52YWxpZCBjaGFyIGluIHVybCBmcmFnbWVudCBzdGFydABFeHBlY3RlZCBkb3QAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9zdGF0dXMASW52YWxpZCByZXNwb25zZSBzdGF0dXMASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucwBVc2VyIGNhbGxiYWNrIGVycm9yAGBvbl9yZXNldGAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2hlYWRlcmAgY2FsbGJhY2sgZXJyb3IAYG9uX21lc3NhZ2VfYmVnaW5gIGNhbGxiYWNrIGVycm9yAGBvbl9jaHVua19leHRlbnNpb25fdmFsdWVgIGNhbGxiYWNrIGVycm9yAGBvbl9zdGF0dXNfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl92ZXJzaW9uX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fdXJsX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9oZWFkZXJfdmFsdWVfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9tZXNzYWdlX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fbWV0aG9kX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25faGVhZGVyX2ZpZWxkX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfZXh0ZW5zaW9uX25hbWVgIGNhbGxiYWNrIGVycm9yAFVuZXhwZWN0ZWQgY2hhciBpbiB1cmwgc2VydmVyAEludmFsaWQgaGVhZGVyIHZhbHVlIGNoYXIASW52YWxpZCBoZWFkZXIgZmllbGQgY2hhcgBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3ZlcnNpb24ASW52YWxpZCBtaW5vciB2ZXJzaW9uAEludmFsaWQgbWFqb3IgdmVyc2lvbgBFeHBlY3RlZCBzcGFjZSBhZnRlciB2ZXJzaW9uAEV4cGVjdGVkIENSTEYgYWZ0ZXIgdmVyc2lvbgBJbnZhbGlkIEhUVFAgdmVyc2lvbgBJbnZhbGlkIGhlYWRlciB0b2tlbgBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3VybABJbnZhbGlkIGNoYXJhY3RlcnMgaW4gdXJsAFVuZXhwZWN0ZWQgc3RhcnQgY2hhciBpbiB1cmwARG91YmxlIEAgaW4gdXJsAEVtcHR5IENvbnRlbnQtTGVuZ3RoAEludmFsaWQgY2hhcmFjdGVyIGluIENvbnRlbnQtTGVuZ3RoAER1cGxpY2F0ZSBDb250ZW50LUxlbmd0aABJbnZhbGlkIGNoYXIgaW4gdXJsIHBhdGgAQ29udGVudC1MZW5ndGggY2FuJ3QgYmUgcHJlc2VudCB3aXRoIFRyYW5zZmVyLUVuY29kaW5nAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIHNpemUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9oZWFkZXJfdmFsdWUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9jaHVua19leHRlbnNpb25fdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyB2YWx1ZQBNaXNzaW5nIGV4cGVjdGVkIExGIGFmdGVyIGhlYWRlciB2YWx1ZQBJbnZhbGlkIGBUcmFuc2Zlci1FbmNvZGluZ2AgaGVhZGVyIHZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgcXVvdGUgdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyBxdW90ZWQgdmFsdWUAUGF1c2VkIGJ5IG9uX2hlYWRlcnNfY29tcGxldGUASW52YWxpZCBFT0Ygc3RhdGUAb25fcmVzZXQgcGF1c2UAb25fY2h1bmtfaGVhZGVyIHBhdXNlAG9uX21lc3NhZ2VfYmVnaW4gcGF1c2UAb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlIHBhdXNlAG9uX3N0YXR1c19jb21wbGV0ZSBwYXVzZQBvbl92ZXJzaW9uX2NvbXBsZXRlIHBhdXNlAG9uX3VybF9jb21wbGV0ZSBwYXVzZQBvbl9jaHVua19jb21wbGV0ZSBwYXVzZQBvbl9oZWFkZXJfdmFsdWVfY29tcGxldGUgcGF1c2UAb25fbWVzc2FnZV9jb21wbGV0ZSBwYXVzZQBvbl9tZXRob2RfY29tcGxldGUgcGF1c2UAb25faGVhZGVyX2ZpZWxkX2NvbXBsZXRlIHBhdXNlAG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lIHBhdXNlAFVuZXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgc3RhcnQgbGluZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgbmFtZQBQYXVzZSBvbiBDT05ORUNUL1VwZ3JhZGUAUGF1c2Ugb24gUFJJL1VwZ3JhZGUARXhwZWN0ZWQgSFRUUC8yIENvbm5lY3Rpb24gUHJlZmFjZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX21ldGhvZABFeHBlY3RlZCBzcGFjZSBhZnRlciBtZXRob2QAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9oZWFkZXJfZmllbGQAUGF1c2VkAEludmFsaWQgd29yZCBlbmNvdW50ZXJlZABJbnZhbGlkIG1ldGhvZCBlbmNvdW50ZXJlZABVbmV4cGVjdGVkIGNoYXIgaW4gdXJsIHNjaGVtYQBSZXF1ZXN0IGhhcyBpbnZhbGlkIGBUcmFuc2Zlci1FbmNvZGluZ2AAU1dJVENIX1BST1hZAFVTRV9QUk9YWQBNS0FDVElWSVRZAFVOUFJPQ0VTU0FCTEVfRU5USVRZAENPUFkATU9WRURfUEVSTUFORU5UTFkAVE9PX0VBUkxZAE5PVElGWQBGQUlMRURfREVQRU5ERU5DWQBCQURfR0FURVdBWQBQTEFZAFBVVABDSEVDS09VVABHQVRFV0FZX1RJTUVPVVQAUkVRVUVTVF9USU1FT1VUAE5FVFdPUktfQ09OTkVDVF9USU1FT1VUAENPTk5FQ1RJT05fVElNRU9VVABMT0dJTl9USU1FT1VUAE5FVFdPUktfUkVBRF9USU1FT1VUAFBPU1QATUlTRElSRUNURURfUkVRVUVTVABDTElFTlRfQ0xPU0VEX1JFUVVFU1QAQ0xJRU5UX0NMT1NFRF9MT0FEX0JBTEFOQ0VEX1JFUVVFU1QAQkFEX1JFUVVFU1QASFRUUF9SRVFVRVNUX1NFTlRfVE9fSFRUUFNfUE9SVABSRVBPUlQASU1fQV9URUFQT1QAUkVTRVRfQ09OVEVOVABOT19DT05URU5UAFBBUlRJQUxfQ09OVEVOVABIUEVfSU5WQUxJRF9DT05TVEFOVABIUEVfQ0JfUkVTRVQAR0VUAEhQRV9TVFJJQ1QAQ09ORkxJQ1QAVEVNUE9SQVJZX1JFRElSRUNUAFBFUk1BTkVOVF9SRURJUkVDVABDT05ORUNUAE1VTFRJX1NUQVRVUwBIUEVfSU5WQUxJRF9TVEFUVVMAVE9PX01BTllfUkVRVUVTVFMARUFSTFlfSElOVFMAVU5BVkFJTEFCTEVfRk9SX0xFR0FMX1JFQVNPTlMAT1BUSU9OUwBTV0lUQ0hJTkdfUFJPVE9DT0xTAFZBUklBTlRfQUxTT19ORUdPVElBVEVTAE1VTFRJUExFX0NIT0lDRVMASU5URVJOQUxfU0VSVkVSX0VSUk9SAFdFQl9TRVJWRVJfVU5LTk9XTl9FUlJPUgBSQUlMR1VOX0VSUk9SAElERU5USVRZX1BST1ZJREVSX0FVVEhFTlRJQ0FUSU9OX0VSUk9SAFNTTF9DRVJUSUZJQ0FURV9FUlJPUgBJTlZBTElEX1hfRk9SV0FSREVEX0ZPUgBTRVRfUEFSQU1FVEVSAEdFVF9QQVJBTUVURVIASFBFX1VTRVIAU0VFX09USEVSAEhQRV9DQl9DSFVOS19IRUFERVIATUtDQUxFTkRBUgBTRVRVUABXRUJfU0VSVkVSX0lTX0RPV04AVEVBUkRPV04ASFBFX0NMT1NFRF9DT05ORUNUSU9OAEhFVVJJU1RJQ19FWFBJUkFUSU9OAERJU0NPTk5FQ1RFRF9PUEVSQVRJT04ATk9OX0FVVEhPUklUQVRJVkVfSU5GT1JNQVRJT04ASFBFX0lOVkFMSURfVkVSU0lPTgBIUEVfQ0JfTUVTU0FHRV9CRUdJTgBTSVRFX0lTX0ZST1pFTgBIUEVfSU5WQUxJRF9IRUFERVJfVE9LRU4ASU5WQUxJRF9UT0tFTgBGT1JCSURERU4ARU5IQU5DRV9ZT1VSX0NBTE0ASFBFX0lOVkFMSURfVVJMAEJMT0NLRURfQllfUEFSRU5UQUxfQ09OVFJPTABNS0NPTABBQ0wASFBFX0lOVEVSTkFMAFJFUVVFU1RfSEVBREVSX0ZJRUxEU19UT09fTEFSR0VfVU5PRkZJQ0lBTABIUEVfT0sAVU5MSU5LAFVOTE9DSwBQUkkAUkVUUllfV0lUSABIUEVfSU5WQUxJRF9DT05URU5UX0xFTkdUSABIUEVfVU5FWFBFQ1RFRF9DT05URU5UX0xFTkdUSABGTFVTSABQUk9QUEFUQ0gATS1TRUFSQ0gAVVJJX1RPT19MT05HAFBST0NFU1NJTkcATUlTQ0VMTEFORU9VU19QRVJTSVNURU5UX1dBUk5JTkcATUlTQ0VMTEFORU9VU19XQVJOSU5HAEhQRV9JTlZBTElEX1RSQU5TRkVSX0VOQ09ESU5HAEV4cGVjdGVkIENSTEYASFBFX0lOVkFMSURfQ0hVTktfU0laRQBNT1ZFAENPTlRJTlVFAEhQRV9DQl9TVEFUVVNfQ09NUExFVEUASFBFX0NCX0hFQURFUlNfQ09NUExFVEUASFBFX0NCX1ZFUlNJT05fQ09NUExFVEUASFBFX0NCX1VSTF9DT01QTEVURQBIUEVfQ0JfQ0hVTktfQ09NUExFVEUASFBFX0NCX0hFQURFUl9WQUxVRV9DT01QTEVURQBIUEVfQ0JfQ0hVTktfRVhURU5TSU9OX1ZBTFVFX0NPTVBMRVRFAEhQRV9DQl9DSFVOS19FWFRFTlNJT05fTkFNRV9DT01QTEVURQBIUEVfQ0JfTUVTU0FHRV9DT01QTEVURQBIUEVfQ0JfTUVUSE9EX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJfRklFTERfQ09NUExFVEUAREVMRVRFAEhQRV9JTlZBTElEX0VPRl9TVEFURQBJTlZBTElEX1NTTF9DRVJUSUZJQ0FURQBQQVVTRQBOT19SRVNQT05TRQBVTlNVUFBPUlRFRF9NRURJQV9UWVBFAEdPTkUATk9UX0FDQ0VQVEFCTEUAU0VSVklDRV9VTkFWQUlMQUJMRQBSQU5HRV9OT1RfU0FUSVNGSUFCTEUAT1JJR0lOX0lTX1VOUkVBQ0hBQkxFAFJFU1BPTlNFX0lTX1NUQUxFAFBVUkdFAE1FUkdFAFJFUVVFU1RfSEVBREVSX0ZJRUxEU19UT09fTEFSR0UAUkVRVUVTVF9IRUFERVJfVE9PX0xBUkdFAFBBWUxPQURfVE9PX0xBUkdFAElOU1VGRklDSUVOVF9TVE9SQUdFAEhQRV9QQVVTRURfVVBHUkFERQBIUEVfUEFVU0VEX0gyX1VQR1JBREUAU09VUkNFAEFOTk9VTkNFAFRSQUNFAEhQRV9VTkVYUEVDVEVEX1NQQUNFAERFU0NSSUJFAFVOU1VCU0NSSUJFAFJFQ09SRABIUEVfSU5WQUxJRF9NRVRIT0QATk9UX0ZPVU5EAFBST1BGSU5EAFVOQklORABSRUJJTkQAVU5BVVRIT1JJWkVEAE1FVEhPRF9OT1RfQUxMT1dFRABIVFRQX1ZFUlNJT05fTk9UX1NVUFBPUlRFRABBTFJFQURZX1JFUE9SVEVEAEFDQ0VQVEVEAE5PVF9JTVBMRU1FTlRFRABMT09QX0RFVEVDVEVEAEhQRV9DUl9FWFBFQ1RFRABIUEVfTEZfRVhQRUNURUQAQ1JFQVRFRABJTV9VU0VEAEhQRV9QQVVTRUQAVElNRU9VVF9PQ0NVUkVEAFBBWU1FTlRfUkVRVUlSRUQAUFJFQ09ORElUSU9OX1JFUVVJUkVEAFBST1hZX0FVVEhFTlRJQ0FUSU9OX1JFUVVJUkVEAE5FVFdPUktfQVVUSEVOVElDQVRJT05fUkVRVUlSRUQATEVOR1RIX1JFUVVJUkVEAFNTTF9DRVJUSUZJQ0FURV9SRVFVSVJFRABVUEdSQURFX1JFUVVJUkVEAFBBR0VfRVhQSVJFRABQUkVDT05ESVRJT05fRkFJTEVEAEVYUEVDVEFUSU9OX0ZBSUxFRABSRVZBTElEQVRJT05fRkFJTEVEAFNTTF9IQU5EU0hBS0VfRkFJTEVEAExPQ0tFRABUUkFOU0ZPUk1BVElPTl9BUFBMSUVEAE5PVF9NT0RJRklFRABOT1RfRVhURU5ERUQAQkFORFdJRFRIX0xJTUlUX0VYQ0VFREVEAFNJVEVfSVNfT1ZFUkxPQURFRABIRUFEAEV4cGVjdGVkIEhUVFAvAABeEwAAJhMAADAQAADwFwAAnRMAABUSAAA5FwAA8BIAAAoQAAB1EgAArRIAAIITAABPFAAAfxAAAKAVAAAjFAAAiRIAAIsUAABNFQAA1BEAAM8UAAAQGAAAyRYAANwWAADBEQAA4BcAALsUAAB0FAAAfBUAAOUUAAAIFwAAHxAAAGUVAACjFAAAKBUAAAIVAACZFQAALBAAAIsZAABPDwAA1A4AAGoQAADOEAAAAhcAAIkOAABuEwAAHBMAAGYUAABWFwAAwRMAAM0TAABsEwAAaBcAAGYXAABfFwAAIhMAAM4PAABpDgAA2A4AAGMWAADLEwAAqg4AACgXAAAmFwAAxRMAAF0WAADoEQAAZxMAAGUTAADyFgAAcxMAAB0XAAD5FgAA8xEAAM8OAADOFQAADBIAALMRAAClEQAAYRAAADIXAAC7EwBB+TULAQEAQZA2C+ABAQECAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAQf03CwEBAEGROAteAgMCAgICAgAAAgIAAgIAAgICAgICAgICAgAEAAAAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAgICAAIAAgBB/TkLAQEAQZE6C14CAAICAgICAAACAgACAgACAgICAgICAgICAAMABAAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAgACAEHwOwsNbG9zZWVlcC1hbGl2ZQBBiTwLAQEAQaA8C+ABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAQYk+CwEBAEGgPgvnAQEBAQEBAQEBAQEBAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBY2h1bmtlZABBsMAAC18BAQABAQEBAQAAAQEAAQEAAQEBAQEBAQEBAQAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEAAQBBkMIACyFlY3Rpb25lbnQtbGVuZ3Rob25yb3h5LWNvbm5lY3Rpb24AQcDCAAstcmFuc2Zlci1lbmNvZGluZ3BncmFkZQ0KDQoNClNNDQoNClRUUC9DRS9UU1AvAEH5wgALBQECAAEDAEGQwwAL4AEEAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQBB+cQACwUBAgABAwBBkMUAC+ABBAEBBQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAQfnGAAsEAQAAAQBBkccAC98BAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQBB+sgACwQBAAACAEGQyQALXwMEAAAEBAQEBAQEBAQEBAUEBAQEBAQEBAQEBAQABAAGBwQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEAAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAEAEH6ygALBAEAAAEAQZDLAAsBAQBBqssAC0ECAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwBB+swACwQBAAABAEGQzQALAQEAQZrNAAsGAgAAAAACAEGxzQALOgMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAQfDOAAuWAU5PVU5DRUVDS09VVE5FQ1RFVEVDUklCRUxVU0hFVEVBRFNFQVJDSFJHRUNUSVZJVFlMRU5EQVJWRU9USUZZUFRJT05TQ0hTRUFZU1RBVENIR0VPUkRJUkVDVE9SVFJDSFBBUkFNRVRFUlVSQ0VCU0NSSUJFQVJET1dOQUNFSU5ETktDS1VCU0NSSUJFSFRUUC9BRFRQLw==', 'base64'); - return llhttp_simdWasm; -} - -var constants$2; -var hasRequiredConstants$2; - -function requireConstants$2 () { - if (hasRequiredConstants$2) return constants$2; - hasRequiredConstants$2 = 1; - - const corsSafeListedMethods = ['GET', 'HEAD', 'POST']; - const corsSafeListedMethodsSet = new Set(corsSafeListedMethods); - - const nullBodyStatus = [101, 204, 205, 304]; - - const redirectStatus = [301, 302, 303, 307, 308]; - const redirectStatusSet = new Set(redirectStatus); - - // https://fetch.spec.whatwg.org/#block-bad-port - const badPorts = [ - '1', '7', '9', '11', '13', '15', '17', '19', '20', '21', '22', '23', '25', '37', '42', '43', '53', '69', '77', '79', - '87', '95', '101', '102', '103', '104', '109', '110', '111', '113', '115', '117', '119', '123', '135', '137', - '139', '143', '161', '179', '389', '427', '465', '512', '513', '514', '515', '526', '530', '531', '532', - '540', '548', '554', '556', '563', '587', '601', '636', '989', '990', '993', '995', '1719', '1720', '1723', - '2049', '3659', '4045', '4190', '5060', '5061', '6000', '6566', '6665', '6666', '6667', '6668', '6669', '6679', - '6697', '10080' - ]; - - const badPortsSet = new Set(badPorts); - - // https://w3c.github.io/webappsec-referrer-policy/#referrer-policies - const referrerPolicy = [ - '', - 'no-referrer', - 'no-referrer-when-downgrade', - 'same-origin', - 'origin', - 'strict-origin', - 'origin-when-cross-origin', - 'strict-origin-when-cross-origin', - 'unsafe-url' - ]; - const referrerPolicySet = new Set(referrerPolicy); - - const requestRedirect = ['follow', 'manual', 'error']; - - const safeMethods = ['GET', 'HEAD', 'OPTIONS', 'TRACE']; - const safeMethodsSet = new Set(safeMethods); - - const requestMode = ['navigate', 'same-origin', 'no-cors', 'cors']; - - const requestCredentials = ['omit', 'same-origin', 'include']; - - const requestCache = [ - 'default', - 'no-store', - 'reload', - 'no-cache', - 'force-cache', - 'only-if-cached' - ]; - - // https://fetch.spec.whatwg.org/#request-body-header-name - const requestBodyHeader = [ - 'content-encoding', - 'content-language', - 'content-location', - 'content-type', - // See https://github.com/nodejs/undici/issues/2021 - // 'Content-Length' is a forbidden header name, which is typically - // removed in the Headers implementation. However, undici doesn't - // filter out headers, so we add it here. - 'content-length' - ]; - - // https://fetch.spec.whatwg.org/#enumdef-requestduplex - const requestDuplex = [ - 'half' - ]; - - // http://fetch.spec.whatwg.org/#forbidden-method - const forbiddenMethods = ['CONNECT', 'TRACE', 'TRACK']; - const forbiddenMethodsSet = new Set(forbiddenMethods); - - const subresource = [ - 'audio', - 'audioworklet', - 'font', - 'image', - 'manifest', - 'paintworklet', - 'script', - 'style', - 'track', - 'video', - 'xslt', - '' - ]; - const subresourceSet = new Set(subresource); - - constants$2 = { - subresource, - forbiddenMethods, - requestBodyHeader, - referrerPolicy, - requestRedirect, - requestMode, - requestCredentials, - requestCache, - redirectStatus, - corsSafeListedMethods, - nullBodyStatus, - safeMethods, - badPorts, - requestDuplex, - subresourceSet, - badPortsSet, - redirectStatusSet, - corsSafeListedMethodsSet, - safeMethodsSet, - forbiddenMethodsSet, - referrerPolicySet - }; - return constants$2; -} - -var global$2; -var hasRequiredGlobal$1; - -function requireGlobal$1 () { - if (hasRequiredGlobal$1) return global$2; - hasRequiredGlobal$1 = 1; - - // In case of breaking changes, increase the version - // number to avoid conflicts. - const globalOrigin = Symbol.for('undici.globalOrigin.1'); - - function getGlobalOrigin () { - return globalThis[globalOrigin] - } - - function setGlobalOrigin (newOrigin) { - if (newOrigin === undefined) { - Object.defineProperty(globalThis, globalOrigin, { - value: undefined, - writable: true, - enumerable: false, - configurable: false - }); - - return - } - - const parsedURL = new URL(newOrigin); - - if (parsedURL.protocol !== 'http:' && parsedURL.protocol !== 'https:') { - throw new TypeError(`Only http & https urls are allowed, received ${parsedURL.protocol}`) - } - - Object.defineProperty(globalThis, globalOrigin, { - value: parsedURL, - writable: true, - enumerable: false, - configurable: false - }); - } - - global$2 = { - getGlobalOrigin, - setGlobalOrigin - }; - return global$2; -} - -var dataUrl; -var hasRequiredDataUrl; - -function requireDataUrl () { - if (hasRequiredDataUrl) return dataUrl; - hasRequiredDataUrl = 1; - - const assert = require$$0$4; - - const encoder = new TextEncoder(); - - /** - * @see https://mimesniff.spec.whatwg.org/#http-token-code-point - */ - const HTTP_TOKEN_CODEPOINTS = /^[!#$%&'*+\-.^_|~A-Za-z0-9]+$/; - const HTTP_WHITESPACE_REGEX = /[\u000A\u000D\u0009\u0020]/; // eslint-disable-line - const ASCII_WHITESPACE_REPLACE_REGEX = /[\u0009\u000A\u000C\u000D\u0020]/g; // eslint-disable-line - /** - * @see https://mimesniff.spec.whatwg.org/#http-quoted-string-token-code-point - */ - const HTTP_QUOTED_STRING_TOKENS = /^[\u0009\u0020-\u007E\u0080-\u00FF]+$/; // eslint-disable-line - - // https://fetch.spec.whatwg.org/#data-url-processor - /** @param {URL} dataURL */ - function dataURLProcessor (dataURL) { - // 1. Assert: dataURL’s scheme is "data". - assert(dataURL.protocol === 'data:'); - - // 2. Let input be the result of running the URL - // serializer on dataURL with exclude fragment - // set to true. - let input = URLSerializer(dataURL, true); - - // 3. Remove the leading "data:" string from input. - input = input.slice(5); - - // 4. Let position point at the start of input. - const position = { position: 0 }; - - // 5. Let mimeType be the result of collecting a - // sequence of code points that are not equal - // to U+002C (,), given position. - let mimeType = collectASequenceOfCodePointsFast( - ',', - input, - position - ); - - // 6. Strip leading and trailing ASCII whitespace - // from mimeType. - // Undici implementation note: we need to store the - // length because if the mimetype has spaces removed, - // the wrong amount will be sliced from the input in - // step #9 - const mimeTypeLength = mimeType.length; - mimeType = removeASCIIWhitespace(mimeType, true, true); - - // 7. If position is past the end of input, then - // return failure - if (position.position >= input.length) { - return 'failure' - } - - // 8. Advance position by 1. - position.position++; - - // 9. Let encodedBody be the remainder of input. - const encodedBody = input.slice(mimeTypeLength + 1); - - // 10. Let body be the percent-decoding of encodedBody. - let body = stringPercentDecode(encodedBody); - - // 11. If mimeType ends with U+003B (;), followed by - // zero or more U+0020 SPACE, followed by an ASCII - // case-insensitive match for "base64", then: - if (/;(\u0020){0,}base64$/i.test(mimeType)) { - // 1. Let stringBody be the isomorphic decode of body. - const stringBody = isomorphicDecode(body); - - // 2. Set body to the forgiving-base64 decode of - // stringBody. - body = forgivingBase64(stringBody); - - // 3. If body is failure, then return failure. - if (body === 'failure') { - return 'failure' - } - - // 4. Remove the last 6 code points from mimeType. - mimeType = mimeType.slice(0, -6); - - // 5. Remove trailing U+0020 SPACE code points from mimeType, - // if any. - mimeType = mimeType.replace(/(\u0020)+$/, ''); - - // 6. Remove the last U+003B (;) code point from mimeType. - mimeType = mimeType.slice(0, -1); - } - - // 12. If mimeType starts with U+003B (;), then prepend - // "text/plain" to mimeType. - if (mimeType.startsWith(';')) { - mimeType = 'text/plain' + mimeType; - } - - // 13. Let mimeTypeRecord be the result of parsing - // mimeType. - let mimeTypeRecord = parseMIMEType(mimeType); - - // 14. If mimeTypeRecord is failure, then set - // mimeTypeRecord to text/plain;charset=US-ASCII. - if (mimeTypeRecord === 'failure') { - mimeTypeRecord = parseMIMEType('text/plain;charset=US-ASCII'); - } - - // 15. Return a new data: URL struct whose MIME - // type is mimeTypeRecord and body is body. - // https://fetch.spec.whatwg.org/#data-url-struct - return { mimeType: mimeTypeRecord, body } - } - - // https://url.spec.whatwg.org/#concept-url-serializer - /** - * @param {URL} url - * @param {boolean} excludeFragment - */ - function URLSerializer (url, excludeFragment = false) { - if (!excludeFragment) { - return url.href - } - - const href = url.href; - const hashLength = url.hash.length; - - const serialized = hashLength === 0 ? href : href.substring(0, href.length - hashLength); - - if (!hashLength && href.endsWith('#')) { - return serialized.slice(0, -1) - } - - return serialized - } - - // https://infra.spec.whatwg.org/#collect-a-sequence-of-code-points - /** - * @param {(char: string) => boolean} condition - * @param {string} input - * @param {{ position: number }} position - */ - function collectASequenceOfCodePoints (condition, input, position) { - // 1. Let result be the empty string. - let result = ''; - - // 2. While position doesn’t point past the end of input and the - // code point at position within input meets the condition condition: - while (position.position < input.length && condition(input[position.position])) { - // 1. Append that code point to the end of result. - result += input[position.position]; - - // 2. Advance position by 1. - position.position++; - } - - // 3. Return result. - return result - } - - /** - * A faster collectASequenceOfCodePoints that only works when comparing a single character. - * @param {string} char - * @param {string} input - * @param {{ position: number }} position - */ - function collectASequenceOfCodePointsFast (char, input, position) { - const idx = input.indexOf(char, position.position); - const start = position.position; - - if (idx === -1) { - position.position = input.length; - return input.slice(start) - } - - position.position = idx; - return input.slice(start, position.position) - } - - // https://url.spec.whatwg.org/#string-percent-decode - /** @param {string} input */ - function stringPercentDecode (input) { - // 1. Let bytes be the UTF-8 encoding of input. - const bytes = encoder.encode(input); - - // 2. Return the percent-decoding of bytes. - return percentDecode(bytes) - } - - /** - * @param {number} byte - */ - function isHexCharByte (byte) { - // 0-9 A-F a-f - return (byte >= 0x30 && byte <= 0x39) || (byte >= 0x41 && byte <= 0x46) || (byte >= 0x61 && byte <= 0x66) - } - - /** - * @param {number} byte - */ - function hexByteToNumber (byte) { - return ( - // 0-9 - byte >= 0x30 && byte <= 0x39 - ? (byte - 48) - // Convert to uppercase - // ((byte & 0xDF) - 65) + 10 - : ((byte & 0xDF) - 55) - ) - } - - // https://url.spec.whatwg.org/#percent-decode - /** @param {Uint8Array} input */ - function percentDecode (input) { - const length = input.length; - // 1. Let output be an empty byte sequence. - /** @type {Uint8Array} */ - const output = new Uint8Array(length); - let j = 0; - // 2. For each byte byte in input: - for (let i = 0; i < length; ++i) { - const byte = input[i]; - - // 1. If byte is not 0x25 (%), then append byte to output. - if (byte !== 0x25) { - output[j++] = byte; - - // 2. Otherwise, if byte is 0x25 (%) and the next two bytes - // after byte in input are not in the ranges - // 0x30 (0) to 0x39 (9), 0x41 (A) to 0x46 (F), - // and 0x61 (a) to 0x66 (f), all inclusive, append byte - // to output. - } else if ( - byte === 0x25 && - !(isHexCharByte(input[i + 1]) && isHexCharByte(input[i + 2])) - ) { - output[j++] = 0x25; - - // 3. Otherwise: - } else { - // 1. Let bytePoint be the two bytes after byte in input, - // decoded, and then interpreted as hexadecimal number. - // 2. Append a byte whose value is bytePoint to output. - output[j++] = (hexByteToNumber(input[i + 1]) << 4) | hexByteToNumber(input[i + 2]); - - // 3. Skip the next two bytes in input. - i += 2; - } - } - - // 3. Return output. - return length === j ? output : output.subarray(0, j) - } - - // https://mimesniff.spec.whatwg.org/#parse-a-mime-type - /** @param {string} input */ - function parseMIMEType (input) { - // 1. Remove any leading and trailing HTTP whitespace - // from input. - input = removeHTTPWhitespace(input, true, true); - - // 2. Let position be a position variable for input, - // initially pointing at the start of input. - const position = { position: 0 }; - - // 3. Let type be the result of collecting a sequence - // of code points that are not U+002F (/) from - // input, given position. - const type = collectASequenceOfCodePointsFast( - '/', - input, - position - ); - - // 4. If type is the empty string or does not solely - // contain HTTP token code points, then return failure. - // https://mimesniff.spec.whatwg.org/#http-token-code-point - if (type.length === 0 || !HTTP_TOKEN_CODEPOINTS.test(type)) { - return 'failure' - } - - // 5. If position is past the end of input, then return - // failure - if (position.position > input.length) { - return 'failure' - } - - // 6. Advance position by 1. (This skips past U+002F (/).) - position.position++; - - // 7. Let subtype be the result of collecting a sequence of - // code points that are not U+003B (;) from input, given - // position. - let subtype = collectASequenceOfCodePointsFast( - ';', - input, - position - ); - - // 8. Remove any trailing HTTP whitespace from subtype. - subtype = removeHTTPWhitespace(subtype, false, true); - - // 9. If subtype is the empty string or does not solely - // contain HTTP token code points, then return failure. - if (subtype.length === 0 || !HTTP_TOKEN_CODEPOINTS.test(subtype)) { - return 'failure' - } - - const typeLowercase = type.toLowerCase(); - const subtypeLowercase = subtype.toLowerCase(); - - // 10. Let mimeType be a new MIME type record whose type - // is type, in ASCII lowercase, and subtype is subtype, - // in ASCII lowercase. - // https://mimesniff.spec.whatwg.org/#mime-type - const mimeType = { - type: typeLowercase, - subtype: subtypeLowercase, - /** @type {Map} */ - parameters: new Map(), - // https://mimesniff.spec.whatwg.org/#mime-type-essence - essence: `${typeLowercase}/${subtypeLowercase}` - }; - - // 11. While position is not past the end of input: - while (position.position < input.length) { - // 1. Advance position by 1. (This skips past U+003B (;).) - position.position++; - - // 2. Collect a sequence of code points that are HTTP - // whitespace from input given position. - collectASequenceOfCodePoints( - // https://fetch.spec.whatwg.org/#http-whitespace - char => HTTP_WHITESPACE_REGEX.test(char), - input, - position - ); - - // 3. Let parameterName be the result of collecting a - // sequence of code points that are not U+003B (;) - // or U+003D (=) from input, given position. - let parameterName = collectASequenceOfCodePoints( - (char) => char !== ';' && char !== '=', - input, - position - ); - - // 4. Set parameterName to parameterName, in ASCII - // lowercase. - parameterName = parameterName.toLowerCase(); - - // 5. If position is not past the end of input, then: - if (position.position < input.length) { - // 1. If the code point at position within input is - // U+003B (;), then continue. - if (input[position.position] === ';') { - continue - } - - // 2. Advance position by 1. (This skips past U+003D (=).) - position.position++; - } - - // 6. If position is past the end of input, then break. - if (position.position > input.length) { - break - } - - // 7. Let parameterValue be null. - let parameterValue = null; - - // 8. If the code point at position within input is - // U+0022 ("), then: - if (input[position.position] === '"') { - // 1. Set parameterValue to the result of collecting - // an HTTP quoted string from input, given position - // and the extract-value flag. - parameterValue = collectAnHTTPQuotedString(input, position, true); - - // 2. Collect a sequence of code points that are not - // U+003B (;) from input, given position. - collectASequenceOfCodePointsFast( - ';', - input, - position - ); - - // 9. Otherwise: - } else { - // 1. Set parameterValue to the result of collecting - // a sequence of code points that are not U+003B (;) - // from input, given position. - parameterValue = collectASequenceOfCodePointsFast( - ';', - input, - position - ); - - // 2. Remove any trailing HTTP whitespace from parameterValue. - parameterValue = removeHTTPWhitespace(parameterValue, false, true); - - // 3. If parameterValue is the empty string, then continue. - if (parameterValue.length === 0) { - continue - } - } - - // 10. If all of the following are true - // - parameterName is not the empty string - // - parameterName solely contains HTTP token code points - // - parameterValue solely contains HTTP quoted-string token code points - // - mimeType’s parameters[parameterName] does not exist - // then set mimeType’s parameters[parameterName] to parameterValue. - if ( - parameterName.length !== 0 && - HTTP_TOKEN_CODEPOINTS.test(parameterName) && - (parameterValue.length === 0 || HTTP_QUOTED_STRING_TOKENS.test(parameterValue)) && - !mimeType.parameters.has(parameterName) - ) { - mimeType.parameters.set(parameterName, parameterValue); - } - } - - // 12. Return mimeType. - return mimeType - } - - // https://infra.spec.whatwg.org/#forgiving-base64-decode - /** @param {string} data */ - function forgivingBase64 (data) { - // 1. Remove all ASCII whitespace from data. - data = data.replace(ASCII_WHITESPACE_REPLACE_REGEX, ''); // eslint-disable-line - - let dataLength = data.length; - // 2. If data’s code point length divides by 4 leaving - // no remainder, then: - if (dataLength % 4 === 0) { - // 1. If data ends with one or two U+003D (=) code points, - // then remove them from data. - if (data.charCodeAt(dataLength - 1) === 0x003D) { - --dataLength; - if (data.charCodeAt(dataLength - 1) === 0x003D) { - --dataLength; - } - } - } - - // 3. If data’s code point length divides by 4 leaving - // a remainder of 1, then return failure. - if (dataLength % 4 === 1) { - return 'failure' - } - - // 4. If data contains a code point that is not one of - // U+002B (+) - // U+002F (/) - // ASCII alphanumeric - // then return failure. - if (/[^+/0-9A-Za-z]/.test(data.length === dataLength ? data : data.substring(0, dataLength))) { - return 'failure' - } - - const buffer = Buffer.from(data, 'base64'); - return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength) - } - - // https://fetch.spec.whatwg.org/#collect-an-http-quoted-string - // tests: https://fetch.spec.whatwg.org/#example-http-quoted-string - /** - * @param {string} input - * @param {{ position: number }} position - * @param {boolean?} extractValue - */ - function collectAnHTTPQuotedString (input, position, extractValue) { - // 1. Let positionStart be position. - const positionStart = position.position; - - // 2. Let value be the empty string. - let value = ''; - - // 3. Assert: the code point at position within input - // is U+0022 ("). - assert(input[position.position] === '"'); - - // 4. Advance position by 1. - position.position++; - - // 5. While true: - while (true) { - // 1. Append the result of collecting a sequence of code points - // that are not U+0022 (") or U+005C (\) from input, given - // position, to value. - value += collectASequenceOfCodePoints( - (char) => char !== '"' && char !== '\\', - input, - position - ); - - // 2. If position is past the end of input, then break. - if (position.position >= input.length) { - break - } - - // 3. Let quoteOrBackslash be the code point at position within - // input. - const quoteOrBackslash = input[position.position]; - - // 4. Advance position by 1. - position.position++; - - // 5. If quoteOrBackslash is U+005C (\), then: - if (quoteOrBackslash === '\\') { - // 1. If position is past the end of input, then append - // U+005C (\) to value and break. - if (position.position >= input.length) { - value += '\\'; - break - } - - // 2. Append the code point at position within input to value. - value += input[position.position]; - - // 3. Advance position by 1. - position.position++; - - // 6. Otherwise: - } else { - // 1. Assert: quoteOrBackslash is U+0022 ("). - assert(quoteOrBackslash === '"'); - - // 2. Break. - break - } - } - - // 6. If the extract-value flag is set, then return value. - if (extractValue) { - return value - } - - // 7. Return the code points from positionStart to position, - // inclusive, within input. - return input.slice(positionStart, position.position) - } - - /** - * @see https://mimesniff.spec.whatwg.org/#serialize-a-mime-type - */ - function serializeAMimeType (mimeType) { - assert(mimeType !== 'failure'); - const { parameters, essence } = mimeType; - - // 1. Let serialization be the concatenation of mimeType’s - // type, U+002F (/), and mimeType’s subtype. - let serialization = essence; - - // 2. For each name → value of mimeType’s parameters: - for (let [name, value] of parameters.entries()) { - // 1. Append U+003B (;) to serialization. - serialization += ';'; - - // 2. Append name to serialization. - serialization += name; - - // 3. Append U+003D (=) to serialization. - serialization += '='; - - // 4. If value does not solely contain HTTP token code - // points or value is the empty string, then: - if (!HTTP_TOKEN_CODEPOINTS.test(value)) { - // 1. Precede each occurrence of U+0022 (") or - // U+005C (\) in value with U+005C (\). - value = value.replace(/(\\|")/g, '\\$1'); - - // 2. Prepend U+0022 (") to value. - value = '"' + value; - - // 3. Append U+0022 (") to value. - value += '"'; - } - - // 5. Append value to serialization. - serialization += value; - } - - // 3. Return serialization. - return serialization - } - - /** - * @see https://fetch.spec.whatwg.org/#http-whitespace - * @param {number} char - */ - function isHTTPWhiteSpace (char) { - // "\r\n\t " - return char === 0x00d || char === 0x00a || char === 0x009 || char === 0x020 - } - - /** - * @see https://fetch.spec.whatwg.org/#http-whitespace - * @param {string} str - * @param {boolean} [leading=true] - * @param {boolean} [trailing=true] - */ - function removeHTTPWhitespace (str, leading = true, trailing = true) { - return removeChars(str, leading, trailing, isHTTPWhiteSpace) - } - - /** - * @see https://infra.spec.whatwg.org/#ascii-whitespace - * @param {number} char - */ - function isASCIIWhitespace (char) { - // "\r\n\t\f " - return char === 0x00d || char === 0x00a || char === 0x009 || char === 0x00c || char === 0x020 - } - - /** - * @see https://infra.spec.whatwg.org/#strip-leading-and-trailing-ascii-whitespace - * @param {string} str - * @param {boolean} [leading=true] - * @param {boolean} [trailing=true] - */ - function removeASCIIWhitespace (str, leading = true, trailing = true) { - return removeChars(str, leading, trailing, isASCIIWhitespace) - } - - /** - * @param {string} str - * @param {boolean} leading - * @param {boolean} trailing - * @param {(charCode: number) => boolean} predicate - * @returns - */ - function removeChars (str, leading, trailing, predicate) { - let lead = 0; - let trail = str.length - 1; - - if (leading) { - while (lead < str.length && predicate(str.charCodeAt(lead))) lead++; - } - - if (trailing) { - while (trail > 0 && predicate(str.charCodeAt(trail))) trail--; - } - - return lead === 0 && trail === str.length - 1 ? str : str.slice(lead, trail + 1) - } - - /** - * @see https://infra.spec.whatwg.org/#isomorphic-decode - * @param {Uint8Array} input - * @returns {string} - */ - function isomorphicDecode (input) { - // 1. To isomorphic decode a byte sequence input, return a string whose code point - // length is equal to input’s length and whose code points have the same values - // as the values of input’s bytes, in the same order. - const length = input.length; - if ((2 << 15) - 1 > length) { - return String.fromCharCode.apply(null, input) - } - let result = ''; let i = 0; - let addition = (2 << 15) - 1; - while (i < length) { - if (i + addition > length) { - addition = length - i; - } - result += String.fromCharCode.apply(null, input.subarray(i, i += addition)); - } - return result - } - - /** - * @see https://mimesniff.spec.whatwg.org/#minimize-a-supported-mime-type - * @param {Exclude, 'failure'>} mimeType - */ - function minimizeSupportedMimeType (mimeType) { - switch (mimeType.essence) { - case 'application/ecmascript': - case 'application/javascript': - case 'application/x-ecmascript': - case 'application/x-javascript': - case 'text/ecmascript': - case 'text/javascript': - case 'text/javascript1.0': - case 'text/javascript1.1': - case 'text/javascript1.2': - case 'text/javascript1.3': - case 'text/javascript1.4': - case 'text/javascript1.5': - case 'text/jscript': - case 'text/livescript': - case 'text/x-ecmascript': - case 'text/x-javascript': - // 1. If mimeType is a JavaScript MIME type, then return "text/javascript". - return 'text/javascript' - case 'application/json': - case 'text/json': - // 2. If mimeType is a JSON MIME type, then return "application/json". - return 'application/json' - case 'image/svg+xml': - // 3. If mimeType’s essence is "image/svg+xml", then return "image/svg+xml". - return 'image/svg+xml' - case 'text/xml': - case 'application/xml': - // 4. If mimeType is an XML MIME type, then return "application/xml". - return 'application/xml' - } - - // 2. If mimeType is a JSON MIME type, then return "application/json". - if (mimeType.subtype.endsWith('+json')) { - return 'application/json' - } - - // 4. If mimeType is an XML MIME type, then return "application/xml". - if (mimeType.subtype.endsWith('+xml')) { - return 'application/xml' - } - - // 5. If mimeType is supported by the user agent, then return mimeType’s essence. - // Technically, node doesn't support any mimetypes. - - // 6. Return the empty string. - return '' - } - - dataUrl = { - dataURLProcessor, - URLSerializer, - collectASequenceOfCodePoints, - collectASequenceOfCodePointsFast, - stringPercentDecode, - parseMIMEType, - collectAnHTTPQuotedString, - serializeAMimeType, - removeChars, - removeHTTPWhitespace, - minimizeSupportedMimeType, - HTTP_TOKEN_CODEPOINTS, - isomorphicDecode - }; - return dataUrl; -} - -var webidl_1; -var hasRequiredWebidl; - -function requireWebidl () { - if (hasRequiredWebidl) return webidl_1; - hasRequiredWebidl = 1; - - const { types, inspect } = require$$0$6; - const { toUSVString } = requireUtil$7(); - - /** @type {import('../../../types/webidl').Webidl} */ - const webidl = {}; - webidl.converters = {}; - webidl.util = {}; - webidl.errors = {}; - - webidl.errors.exception = function (message) { - return new TypeError(`${message.header}: ${message.message}`) - }; - - webidl.errors.conversionFailed = function (context) { - const plural = context.types.length === 1 ? '' : ' one of'; - const message = - `${context.argument} could not be converted to` + - `${plural}: ${context.types.join(', ')}.`; - - return webidl.errors.exception({ - header: context.prefix, - message - }) - }; - - webidl.errors.invalidArgument = function (context) { - return webidl.errors.exception({ - header: context.prefix, - message: `"${context.value}" is an invalid ${context.type}.` - }) - }; - - // https://webidl.spec.whatwg.org/#implements - webidl.brandCheck = function (V, I, opts) { - if (opts?.strict !== false) { - if (!(V instanceof I)) { - const err = new TypeError('Illegal invocation'); - err.code = 'ERR_INVALID_THIS'; // node compat. - throw err - } - } else { - if (V?.[Symbol.toStringTag] !== I.prototype[Symbol.toStringTag]) { - const err = new TypeError('Illegal invocation'); - err.code = 'ERR_INVALID_THIS'; // node compat. - throw err - } - } - }; - - webidl.argumentLengthCheck = function ({ length }, min, ctx) { - if (length < min) { - throw webidl.errors.exception({ - message: `${min} argument${min !== 1 ? 's' : ''} required, ` + - `but${length ? ' only' : ''} ${length} found.`, - header: ctx - }) - } - }; - - webidl.illegalConstructor = function () { - throw webidl.errors.exception({ - header: 'TypeError', - message: 'Illegal constructor' - }) - }; - - // https://tc39.es/ecma262/#sec-ecmascript-data-types-and-values - webidl.util.Type = function (V) { - switch (typeof V) { - case 'undefined': return 'Undefined' - case 'boolean': return 'Boolean' - case 'string': return 'String' - case 'symbol': return 'Symbol' - case 'number': return 'Number' - case 'bigint': return 'BigInt' - case 'function': - case 'object': { - if (V === null) { - return 'Null' - } - - return 'Object' - } - } - }; - - // https://webidl.spec.whatwg.org/#abstract-opdef-converttoint - webidl.util.ConvertToInt = function (V, bitLength, signedness, opts) { - let upperBound; - let lowerBound; - - // 1. If bitLength is 64, then: - if (bitLength === 64) { - // 1. Let upperBound be 2^53 − 1. - upperBound = Math.pow(2, 53) - 1; - - // 2. If signedness is "unsigned", then let lowerBound be 0. - if (signedness === 'unsigned') { - lowerBound = 0; - } else { - // 3. Otherwise let lowerBound be −2^53 + 1. - lowerBound = Math.pow(-2, 53) + 1; - } - } else if (signedness === 'unsigned') { - // 2. Otherwise, if signedness is "unsigned", then: - - // 1. Let lowerBound be 0. - lowerBound = 0; - - // 2. Let upperBound be 2^bitLength − 1. - upperBound = Math.pow(2, bitLength) - 1; - } else { - // 3. Otherwise: - - // 1. Let lowerBound be -2^bitLength − 1. - lowerBound = Math.pow(-2, bitLength) - 1; - - // 2. Let upperBound be 2^bitLength − 1 − 1. - upperBound = Math.pow(2, bitLength - 1) - 1; - } - - // 4. Let x be ? ToNumber(V). - let x = Number(V); - - // 5. If x is −0, then set x to +0. - if (x === 0) { - x = 0; - } - - // 6. If the conversion is to an IDL type associated - // with the [EnforceRange] extended attribute, then: - if (opts?.enforceRange === true) { - // 1. If x is NaN, +∞, or −∞, then throw a TypeError. - if ( - Number.isNaN(x) || - x === Number.POSITIVE_INFINITY || - x === Number.NEGATIVE_INFINITY - ) { - throw webidl.errors.exception({ - header: 'Integer conversion', - message: `Could not convert ${webidl.util.Stringify(V)} to an integer.` - }) - } - - // 2. Set x to IntegerPart(x). - x = webidl.util.IntegerPart(x); - - // 3. If x < lowerBound or x > upperBound, then - // throw a TypeError. - if (x < lowerBound || x > upperBound) { - throw webidl.errors.exception({ - header: 'Integer conversion', - message: `Value must be between ${lowerBound}-${upperBound}, got ${x}.` - }) - } - - // 4. Return x. - return x - } - - // 7. If x is not NaN and the conversion is to an IDL - // type associated with the [Clamp] extended - // attribute, then: - if (!Number.isNaN(x) && opts?.clamp === true) { - // 1. Set x to min(max(x, lowerBound), upperBound). - x = Math.min(Math.max(x, lowerBound), upperBound); - - // 2. Round x to the nearest integer, choosing the - // even integer if it lies halfway between two, - // and choosing +0 rather than −0. - if (Math.floor(x) % 2 === 0) { - x = Math.floor(x); - } else { - x = Math.ceil(x); - } - - // 3. Return x. - return x - } - - // 8. If x is NaN, +0, +∞, or −∞, then return +0. - if ( - Number.isNaN(x) || - (x === 0 && Object.is(0, x)) || - x === Number.POSITIVE_INFINITY || - x === Number.NEGATIVE_INFINITY - ) { - return 0 - } - - // 9. Set x to IntegerPart(x). - x = webidl.util.IntegerPart(x); - - // 10. Set x to x modulo 2^bitLength. - x = x % Math.pow(2, bitLength); - - // 11. If signedness is "signed" and x ≥ 2^bitLength − 1, - // then return x − 2^bitLength. - if (signedness === 'signed' && x >= Math.pow(2, bitLength) - 1) { - return x - Math.pow(2, bitLength) - } - - // 12. Otherwise, return x. - return x - }; - - // https://webidl.spec.whatwg.org/#abstract-opdef-integerpart - webidl.util.IntegerPart = function (n) { - // 1. Let r be floor(abs(n)). - const r = Math.floor(Math.abs(n)); - - // 2. If n < 0, then return -1 × r. - if (n < 0) { - return -1 * r - } - - // 3. Otherwise, return r. - return r - }; - - webidl.util.Stringify = function (V) { - const type = webidl.util.Type(V); - - switch (type) { - case 'Symbol': - return `Symbol(${V.description})` - case 'Object': - return inspect(V) - case 'String': - return `"${V}"` - default: - return `${V}` - } - }; - - // https://webidl.spec.whatwg.org/#es-sequence - webidl.sequenceConverter = function (converter) { - return (V, prefix, argument, Iterable) => { - // 1. If Type(V) is not Object, throw a TypeError. - if (webidl.util.Type(V) !== 'Object') { - throw webidl.errors.exception({ - header: prefix, - message: `${argument} (${webidl.util.Stringify(V)}) is not iterable.` - }) - } - - // 2. Let method be ? GetMethod(V, @@iterator). - /** @type {Generator} */ - const method = typeof Iterable === 'function' ? Iterable() : V?.[Symbol.iterator]?.(); - const seq = []; - let index = 0; - - // 3. If method is undefined, throw a TypeError. - if ( - method === undefined || - typeof method.next !== 'function' - ) { - throw webidl.errors.exception({ - header: prefix, - message: `${argument} is not iterable.` - }) - } - - // https://webidl.spec.whatwg.org/#create-sequence-from-iterable - while (true) { - const { done, value } = method.next(); - - if (done) { - break - } - - seq.push(converter(value, prefix, `${argument}[${index++}]`)); - } - - return seq - } - }; - - // https://webidl.spec.whatwg.org/#es-to-record - webidl.recordConverter = function (keyConverter, valueConverter) { - return (O, prefix, argument) => { - // 1. If Type(O) is not Object, throw a TypeError. - if (webidl.util.Type(O) !== 'Object') { - throw webidl.errors.exception({ - header: prefix, - message: `${argument} ("${webidl.util.Type(O)}") is not an Object.` - }) - } - - // 2. Let result be a new empty instance of record. - const result = {}; - - if (!types.isProxy(O)) { - // 1. Let desc be ? O.[[GetOwnProperty]](key). - const keys = [...Object.getOwnPropertyNames(O), ...Object.getOwnPropertySymbols(O)]; - - for (const key of keys) { - // 1. Let typedKey be key converted to an IDL value of type K. - const typedKey = keyConverter(key, prefix, argument); - - // 2. Let value be ? Get(O, key). - // 3. Let typedValue be value converted to an IDL value of type V. - const typedValue = valueConverter(O[key], prefix, argument); - - // 4. Set result[typedKey] to typedValue. - result[typedKey] = typedValue; - } - - // 5. Return result. - return result - } - - // 3. Let keys be ? O.[[OwnPropertyKeys]](). - const keys = Reflect.ownKeys(O); - - // 4. For each key of keys. - for (const key of keys) { - // 1. Let desc be ? O.[[GetOwnProperty]](key). - const desc = Reflect.getOwnPropertyDescriptor(O, key); - - // 2. If desc is not undefined and desc.[[Enumerable]] is true: - if (desc?.enumerable) { - // 1. Let typedKey be key converted to an IDL value of type K. - const typedKey = keyConverter(key, prefix, argument); - - // 2. Let value be ? Get(O, key). - // 3. Let typedValue be value converted to an IDL value of type V. - const typedValue = valueConverter(O[key], prefix, argument); - - // 4. Set result[typedKey] to typedValue. - result[typedKey] = typedValue; - } - } - - // 5. Return result. - return result - } - }; - - webidl.interfaceConverter = function (i) { - return (V, prefix, argument, opts) => { - if (opts?.strict !== false && !(V instanceof i)) { - throw webidl.errors.exception({ - header: prefix, - message: `Expected ${argument} ("${webidl.util.Stringify(V)}") to be an instance of ${i.name}.` - }) - } - - return V - } - }; - - webidl.dictionaryConverter = function (converters) { - return (dictionary, prefix, argument) => { - const type = webidl.util.Type(dictionary); - const dict = {}; - - if (type === 'Null' || type === 'Undefined') { - return dict - } else if (type !== 'Object') { - throw webidl.errors.exception({ - header: prefix, - message: `Expected ${dictionary} to be one of: Null, Undefined, Object.` - }) - } - - for (const options of converters) { - const { key, defaultValue, required, converter } = options; - - if (required === true) { - if (!Object.hasOwn(dictionary, key)) { - throw webidl.errors.exception({ - header: prefix, - message: `Missing required key "${key}".` - }) - } - } - - let value = dictionary[key]; - const hasDefault = Object.hasOwn(options, 'defaultValue'); - - // Only use defaultValue if value is undefined and - // a defaultValue options was provided. - if (hasDefault && value !== null) { - value ??= defaultValue(); - } - - // A key can be optional and have no default value. - // When this happens, do not perform a conversion, - // and do not assign the key a value. - if (required || hasDefault || value !== undefined) { - value = converter(value, prefix, `${argument}.${key}`); - - if ( - options.allowedValues && - !options.allowedValues.includes(value) - ) { - throw webidl.errors.exception({ - header: prefix, - message: `${value} is not an accepted type. Expected one of ${options.allowedValues.join(', ')}.` - }) - } - - dict[key] = value; - } - } - - return dict - } - }; - - webidl.nullableConverter = function (converter) { - return (V, prefix, argument) => { - if (V === null) { - return V - } - - return converter(V, prefix, argument) - } - }; - - // https://webidl.spec.whatwg.org/#es-DOMString - webidl.converters.DOMString = function (V, prefix, argument, opts) { - // 1. If V is null and the conversion is to an IDL type - // associated with the [LegacyNullToEmptyString] - // extended attribute, then return the DOMString value - // that represents the empty string. - if (V === null && opts?.legacyNullToEmptyString) { - return '' - } - - // 2. Let x be ? ToString(V). - if (typeof V === 'symbol') { - throw webidl.errors.exception({ - header: prefix, - message: `${argument} is a symbol, which cannot be converted to a DOMString.` - }) - } - - // 3. Return the IDL DOMString value that represents the - // same sequence of code units as the one the - // ECMAScript String value x represents. - return String(V) - }; - - // https://webidl.spec.whatwg.org/#es-ByteString - webidl.converters.ByteString = function (V, prefix, argument) { - // 1. Let x be ? ToString(V). - // Note: DOMString converter perform ? ToString(V) - const x = webidl.converters.DOMString(V, prefix, argument); - - // 2. If the value of any element of x is greater than - // 255, then throw a TypeError. - for (let index = 0; index < x.length; index++) { - if (x.charCodeAt(index) > 255) { - throw new TypeError( - 'Cannot convert argument to a ByteString because the character at ' + - `index ${index} has a value of ${x.charCodeAt(index)} which is greater than 255.` - ) - } - } - - // 3. Return an IDL ByteString value whose length is the - // length of x, and where the value of each element is - // the value of the corresponding element of x. - return x - }; - - // https://webidl.spec.whatwg.org/#es-USVString - // TODO: rewrite this so we can control the errors thrown - webidl.converters.USVString = toUSVString; - - // https://webidl.spec.whatwg.org/#es-boolean - webidl.converters.boolean = function (V) { - // 1. Let x be the result of computing ToBoolean(V). - const x = Boolean(V); - - // 2. Return the IDL boolean value that is the one that represents - // the same truth value as the ECMAScript Boolean value x. - return x - }; - - // https://webidl.spec.whatwg.org/#es-any - webidl.converters.any = function (V) { - return V - }; - - // https://webidl.spec.whatwg.org/#es-long-long - webidl.converters['long long'] = function (V, prefix, argument) { - // 1. Let x be ? ConvertToInt(V, 64, "signed"). - const x = webidl.util.ConvertToInt(V, 64, 'signed', undefined, prefix, argument); - - // 2. Return the IDL long long value that represents - // the same numeric value as x. - return x - }; - - // https://webidl.spec.whatwg.org/#es-unsigned-long-long - webidl.converters['unsigned long long'] = function (V, prefix, argument) { - // 1. Let x be ? ConvertToInt(V, 64, "unsigned"). - const x = webidl.util.ConvertToInt(V, 64, 'unsigned', undefined, prefix, argument); - - // 2. Return the IDL unsigned long long value that - // represents the same numeric value as x. - return x - }; - - // https://webidl.spec.whatwg.org/#es-unsigned-long - webidl.converters['unsigned long'] = function (V, prefix, argument) { - // 1. Let x be ? ConvertToInt(V, 32, "unsigned"). - const x = webidl.util.ConvertToInt(V, 32, 'unsigned', undefined, prefix, argument); - - // 2. Return the IDL unsigned long value that - // represents the same numeric value as x. - return x - }; - - // https://webidl.spec.whatwg.org/#es-unsigned-short - webidl.converters['unsigned short'] = function (V, prefix, argument, opts) { - // 1. Let x be ? ConvertToInt(V, 16, "unsigned"). - const x = webidl.util.ConvertToInt(V, 16, 'unsigned', opts, prefix, argument); - - // 2. Return the IDL unsigned short value that represents - // the same numeric value as x. - return x - }; - - // https://webidl.spec.whatwg.org/#idl-ArrayBuffer - webidl.converters.ArrayBuffer = function (V, prefix, argument, opts) { - // 1. If Type(V) is not Object, or V does not have an - // [[ArrayBufferData]] internal slot, then throw a - // TypeError. - // see: https://tc39.es/ecma262/#sec-properties-of-the-arraybuffer-instances - // see: https://tc39.es/ecma262/#sec-properties-of-the-sharedarraybuffer-instances - if ( - webidl.util.Type(V) !== 'Object' || - !types.isAnyArrayBuffer(V) - ) { - throw webidl.errors.conversionFailed({ - prefix, - argument: `${argument} ("${webidl.util.Stringify(V)}")`, - types: ['ArrayBuffer'] - }) - } - - // 2. If the conversion is not to an IDL type associated - // with the [AllowShared] extended attribute, and - // IsSharedArrayBuffer(V) is true, then throw a - // TypeError. - if (opts?.allowShared === false && types.isSharedArrayBuffer(V)) { - throw webidl.errors.exception({ - header: 'ArrayBuffer', - message: 'SharedArrayBuffer is not allowed.' - }) - } - - // 3. If the conversion is not to an IDL type associated - // with the [AllowResizable] extended attribute, and - // IsResizableArrayBuffer(V) is true, then throw a - // TypeError. - if (V.resizable || V.growable) { - throw webidl.errors.exception({ - header: 'ArrayBuffer', - message: 'Received a resizable ArrayBuffer.' - }) - } - - // 4. Return the IDL ArrayBuffer value that is a - // reference to the same object as V. - return V - }; - - webidl.converters.TypedArray = function (V, T, prefix, name, opts) { - // 1. Let T be the IDL type V is being converted to. - - // 2. If Type(V) is not Object, or V does not have a - // [[TypedArrayName]] internal slot with a value - // equal to T’s name, then throw a TypeError. - if ( - webidl.util.Type(V) !== 'Object' || - !types.isTypedArray(V) || - V.constructor.name !== T.name - ) { - throw webidl.errors.conversionFailed({ - prefix, - argument: `${name} ("${webidl.util.Stringify(V)}")`, - types: [T.name] - }) - } - - // 3. If the conversion is not to an IDL type associated - // with the [AllowShared] extended attribute, and - // IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is - // true, then throw a TypeError. - if (opts?.allowShared === false && types.isSharedArrayBuffer(V.buffer)) { - throw webidl.errors.exception({ - header: 'ArrayBuffer', - message: 'SharedArrayBuffer is not allowed.' - }) - } - - // 4. If the conversion is not to an IDL type associated - // with the [AllowResizable] extended attribute, and - // IsResizableArrayBuffer(V.[[ViewedArrayBuffer]]) is - // true, then throw a TypeError. - if (V.buffer.resizable || V.buffer.growable) { - throw webidl.errors.exception({ - header: 'ArrayBuffer', - message: 'Received a resizable ArrayBuffer.' - }) - } - - // 5. Return the IDL value of type T that is a reference - // to the same object as V. - return V - }; - - webidl.converters.DataView = function (V, prefix, name, opts) { - // 1. If Type(V) is not Object, or V does not have a - // [[DataView]] internal slot, then throw a TypeError. - if (webidl.util.Type(V) !== 'Object' || !types.isDataView(V)) { - throw webidl.errors.exception({ - header: prefix, - message: `${name} is not a DataView.` - }) - } - - // 2. If the conversion is not to an IDL type associated - // with the [AllowShared] extended attribute, and - // IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is true, - // then throw a TypeError. - if (opts?.allowShared === false && types.isSharedArrayBuffer(V.buffer)) { - throw webidl.errors.exception({ - header: 'ArrayBuffer', - message: 'SharedArrayBuffer is not allowed.' - }) - } - - // 3. If the conversion is not to an IDL type associated - // with the [AllowResizable] extended attribute, and - // IsResizableArrayBuffer(V.[[ViewedArrayBuffer]]) is - // true, then throw a TypeError. - if (V.buffer.resizable || V.buffer.growable) { - throw webidl.errors.exception({ - header: 'ArrayBuffer', - message: 'Received a resizable ArrayBuffer.' - }) - } - - // 4. Return the IDL DataView value that is a reference - // to the same object as V. - return V - }; - - // https://webidl.spec.whatwg.org/#BufferSource - webidl.converters.BufferSource = function (V, prefix, name, opts) { - if (types.isAnyArrayBuffer(V)) { - return webidl.converters.ArrayBuffer(V, prefix, name, { ...opts, allowShared: false }) - } - - if (types.isTypedArray(V)) { - return webidl.converters.TypedArray(V, V.constructor, prefix, name, { ...opts, allowShared: false }) - } - - if (types.isDataView(V)) { - return webidl.converters.DataView(V, prefix, name, { ...opts, allowShared: false }) - } - - throw webidl.errors.conversionFailed({ - prefix, - argument: `${name} ("${webidl.util.Stringify(V)}")`, - types: ['BufferSource'] - }) - }; - - webidl.converters['sequence'] = webidl.sequenceConverter( - webidl.converters.ByteString - ); - - webidl.converters['sequence>'] = webidl.sequenceConverter( - webidl.converters['sequence'] - ); - - webidl.converters['record'] = webidl.recordConverter( - webidl.converters.ByteString, - webidl.converters.ByteString - ); - - webidl_1 = { - webidl - }; - return webidl_1; -} - -var util$6; -var hasRequiredUtil$6; - -function requireUtil$6 () { - if (hasRequiredUtil$6) return util$6; - hasRequiredUtil$6 = 1; - - const { Transform } = require$$0$5; - const zlib = require$$1; - const { redirectStatusSet, referrerPolicySet: referrerPolicyTokens, badPortsSet } = requireConstants$2(); - const { getGlobalOrigin } = requireGlobal$1(); - const { collectASequenceOfCodePoints, collectAnHTTPQuotedString, removeChars, parseMIMEType } = requireDataUrl(); - const { performance } = require$$5; - const { isBlobLike, ReadableStreamFrom, isValidHTTPToken, normalizedMethodRecordsBase } = requireUtil$7(); - const assert = require$$0$4; - const { isUint8Array } = require$$8$1; - const { webidl } = requireWebidl(); - - let supportedHashes = []; - - // https://nodejs.org/api/crypto.html#determining-if-crypto-support-is-unavailable - /** @type {import('crypto')} */ - let crypto; - try { - crypto = require('node:crypto'); - const possibleRelevantHashes = ['sha256', 'sha384', 'sha512']; - supportedHashes = crypto.getHashes().filter((hash) => possibleRelevantHashes.includes(hash)); - /* c8 ignore next 3 */ - } catch { - - } - - function responseURL (response) { - // https://fetch.spec.whatwg.org/#responses - // A response has an associated URL. It is a pointer to the last URL - // in response’s URL list and null if response’s URL list is empty. - const urlList = response.urlList; - const length = urlList.length; - return length === 0 ? null : urlList[length - 1].toString() - } - - // https://fetch.spec.whatwg.org/#concept-response-location-url - function responseLocationURL (response, requestFragment) { - // 1. If response’s status is not a redirect status, then return null. - if (!redirectStatusSet.has(response.status)) { - return null - } - - // 2. Let location be the result of extracting header list values given - // `Location` and response’s header list. - let location = response.headersList.get('location', true); - - // 3. If location is a header value, then set location to the result of - // parsing location with response’s URL. - if (location !== null && isValidHeaderValue(location)) { - if (!isValidEncodedURL(location)) { - // Some websites respond location header in UTF-8 form without encoding them as ASCII - // and major browsers redirect them to correctly UTF-8 encoded addresses. - // Here, we handle that behavior in the same way. - location = normalizeBinaryStringToUtf8(location); - } - location = new URL(location, responseURL(response)); - } - - // 4. If location is a URL whose fragment is null, then set location’s - // fragment to requestFragment. - if (location && !location.hash) { - location.hash = requestFragment; - } - - // 5. Return location. - return location - } - - /** - * @see https://www.rfc-editor.org/rfc/rfc1738#section-2.2 - * @param {string} url - * @returns {boolean} - */ - function isValidEncodedURL (url) { - for (let i = 0; i < url.length; ++i) { - const code = url.charCodeAt(i); - - if ( - code > 0x7E || // Non-US-ASCII + DEL - code < 0x20 // Control characters NUL - US - ) { - return false - } - } - return true - } - - /** - * If string contains non-ASCII characters, assumes it's UTF-8 encoded and decodes it. - * Since UTF-8 is a superset of ASCII, this will work for ASCII strings as well. - * @param {string} value - * @returns {string} - */ - function normalizeBinaryStringToUtf8 (value) { - return Buffer.from(value, 'binary').toString('utf8') - } - - /** @returns {URL} */ - function requestCurrentURL (request) { - return request.urlList[request.urlList.length - 1] - } - - function requestBadPort (request) { - // 1. Let url be request’s current URL. - const url = requestCurrentURL(request); - - // 2. If url’s scheme is an HTTP(S) scheme and url’s port is a bad port, - // then return blocked. - if (urlIsHttpHttpsScheme(url) && badPortsSet.has(url.port)) { - return 'blocked' - } - - // 3. Return allowed. - return 'allowed' - } - - function isErrorLike (object) { - return object instanceof Error || ( - object?.constructor?.name === 'Error' || - object?.constructor?.name === 'DOMException' - ) - } - - // Check whether |statusText| is a ByteString and - // matches the Reason-Phrase token production. - // RFC 2616: https://tools.ietf.org/html/rfc2616 - // RFC 7230: https://tools.ietf.org/html/rfc7230 - // "reason-phrase = *( HTAB / SP / VCHAR / obs-text )" - // https://github.com/chromium/chromium/blob/94.0.4604.1/third_party/blink/renderer/core/fetch/response.cc#L116 - function isValidReasonPhrase (statusText) { - for (let i = 0; i < statusText.length; ++i) { - const c = statusText.charCodeAt(i); - if ( - !( - ( - c === 0x09 || // HTAB - (c >= 0x20 && c <= 0x7e) || // SP / VCHAR - (c >= 0x80 && c <= 0xff) - ) // obs-text - ) - ) { - return false - } - } - return true - } - - /** - * @see https://fetch.spec.whatwg.org/#header-name - * @param {string} potentialValue - */ - const isValidHeaderName = isValidHTTPToken; - - /** - * @see https://fetch.spec.whatwg.org/#header-value - * @param {string} potentialValue - */ - function isValidHeaderValue (potentialValue) { - // - Has no leading or trailing HTTP tab or space bytes. - // - Contains no 0x00 (NUL) or HTTP newline bytes. - return ( - potentialValue[0] === '\t' || - potentialValue[0] === ' ' || - potentialValue[potentialValue.length - 1] === '\t' || - potentialValue[potentialValue.length - 1] === ' ' || - potentialValue.includes('\n') || - potentialValue.includes('\r') || - potentialValue.includes('\0') - ) === false - } - - // https://w3c.github.io/webappsec-referrer-policy/#set-requests-referrer-policy-on-redirect - function setRequestReferrerPolicyOnRedirect (request, actualResponse) { - // Given a request request and a response actualResponse, this algorithm - // updates request’s referrer policy according to the Referrer-Policy - // header (if any) in actualResponse. - - // 1. Let policy be the result of executing § 8.1 Parse a referrer policy - // from a Referrer-Policy header on actualResponse. - - // 8.1 Parse a referrer policy from a Referrer-Policy header - // 1. Let policy-tokens be the result of extracting header list values given `Referrer-Policy` and response’s header list. - const { headersList } = actualResponse; - // 2. Let policy be the empty string. - // 3. For each token in policy-tokens, if token is a referrer policy and token is not the empty string, then set policy to token. - // 4. Return policy. - const policyHeader = (headersList.get('referrer-policy', true) ?? '').split(','); - - // Note: As the referrer-policy can contain multiple policies - // separated by comma, we need to loop through all of them - // and pick the first valid one. - // Ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy#specify_a_fallback_policy - let policy = ''; - if (policyHeader.length > 0) { - // The right-most policy takes precedence. - // The left-most policy is the fallback. - for (let i = policyHeader.length; i !== 0; i--) { - const token = policyHeader[i - 1].trim(); - if (referrerPolicyTokens.has(token)) { - policy = token; - break - } - } - } - - // 2. If policy is not the empty string, then set request’s referrer policy to policy. - if (policy !== '') { - request.referrerPolicy = policy; - } - } - - // https://fetch.spec.whatwg.org/#cross-origin-resource-policy-check - function crossOriginResourcePolicyCheck () { - // TODO - return 'allowed' - } - - // https://fetch.spec.whatwg.org/#concept-cors-check - function corsCheck () { - // TODO - return 'success' - } - - // https://fetch.spec.whatwg.org/#concept-tao-check - function TAOCheck () { - // TODO - return 'success' - } - - function appendFetchMetadata (httpRequest) { - // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-dest-header - // TODO - - // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-mode-header - - // 1. Assert: r’s url is a potentially trustworthy URL. - // TODO - - // 2. Let header be a Structured Header whose value is a token. - let header = null; - - // 3. Set header’s value to r’s mode. - header = httpRequest.mode; - - // 4. Set a structured field value `Sec-Fetch-Mode`/header in r’s header list. - httpRequest.headersList.set('sec-fetch-mode', header, true); - - // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-site-header - // TODO - - // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-user-header - // TODO - } - - // https://fetch.spec.whatwg.org/#append-a-request-origin-header - function appendRequestOriginHeader (request) { - // 1. Let serializedOrigin be the result of byte-serializing a request origin - // with request. - // TODO: implement "byte-serializing a request origin" - let serializedOrigin = request.origin; - - // "'client' is changed to an origin during fetching." - // This doesn't happen in undici (in most cases) because undici, by default, - // has no concept of origin. - if (serializedOrigin === 'client') { - return - } - - // 2. If request’s response tainting is "cors" or request’s mode is "websocket", - // then append (`Origin`, serializedOrigin) to request’s header list. - // 3. Otherwise, if request’s method is neither `GET` nor `HEAD`, then: - if (request.responseTainting === 'cors' || request.mode === 'websocket') { - request.headersList.append('origin', serializedOrigin, true); - } else if (request.method !== 'GET' && request.method !== 'HEAD') { - // 1. Switch on request’s referrer policy: - switch (request.referrerPolicy) { - case 'no-referrer': - // Set serializedOrigin to `null`. - serializedOrigin = null; - break - case 'no-referrer-when-downgrade': - case 'strict-origin': - case 'strict-origin-when-cross-origin': - // If request’s origin is a tuple origin, its scheme is "https", and - // request’s current URL’s scheme is not "https", then set - // serializedOrigin to `null`. - if (request.origin && urlHasHttpsScheme(request.origin) && !urlHasHttpsScheme(requestCurrentURL(request))) { - serializedOrigin = null; - } - break - case 'same-origin': - // If request’s origin is not same origin with request’s current URL’s - // origin, then set serializedOrigin to `null`. - if (!sameOrigin(request, requestCurrentURL(request))) { - serializedOrigin = null; - } - break - // Do nothing. - } - - // 2. Append (`Origin`, serializedOrigin) to request’s header list. - request.headersList.append('origin', serializedOrigin, true); - } - } - - // https://w3c.github.io/hr-time/#dfn-coarsen-time - function coarsenTime (timestamp, crossOriginIsolatedCapability) { - // TODO - return timestamp - } - - // https://fetch.spec.whatwg.org/#clamp-and-coarsen-connection-timing-info - function clampAndCoarsenConnectionTimingInfo (connectionTimingInfo, defaultStartTime, crossOriginIsolatedCapability) { - if (!connectionTimingInfo?.startTime || connectionTimingInfo.startTime < defaultStartTime) { - return { - domainLookupStartTime: defaultStartTime, - domainLookupEndTime: defaultStartTime, - connectionStartTime: defaultStartTime, - connectionEndTime: defaultStartTime, - secureConnectionStartTime: defaultStartTime, - ALPNNegotiatedProtocol: connectionTimingInfo?.ALPNNegotiatedProtocol - } - } - - return { - domainLookupStartTime: coarsenTime(connectionTimingInfo.domainLookupStartTime), - domainLookupEndTime: coarsenTime(connectionTimingInfo.domainLookupEndTime), - connectionStartTime: coarsenTime(connectionTimingInfo.connectionStartTime), - connectionEndTime: coarsenTime(connectionTimingInfo.connectionEndTime), - secureConnectionStartTime: coarsenTime(connectionTimingInfo.secureConnectionStartTime), - ALPNNegotiatedProtocol: connectionTimingInfo.ALPNNegotiatedProtocol - } - } - - // https://w3c.github.io/hr-time/#dfn-coarsened-shared-current-time - function coarsenedSharedCurrentTime (crossOriginIsolatedCapability) { - return coarsenTime(performance.now()) - } - - // https://fetch.spec.whatwg.org/#create-an-opaque-timing-info - function createOpaqueTimingInfo (timingInfo) { - return { - startTime: timingInfo.startTime ?? 0, - redirectStartTime: 0, - redirectEndTime: 0, - postRedirectStartTime: timingInfo.startTime ?? 0, - finalServiceWorkerStartTime: 0, - finalNetworkResponseStartTime: 0, - finalNetworkRequestStartTime: 0, - endTime: 0, - encodedBodySize: 0, - decodedBodySize: 0, - finalConnectionTimingInfo: null - } - } - - // https://html.spec.whatwg.org/multipage/origin.html#policy-container - function makePolicyContainer () { - // Note: the fetch spec doesn't make use of embedder policy or CSP list - return { - referrerPolicy: 'strict-origin-when-cross-origin' - } - } - - // https://html.spec.whatwg.org/multipage/origin.html#clone-a-policy-container - function clonePolicyContainer (policyContainer) { - return { - referrerPolicy: policyContainer.referrerPolicy - } - } - - // https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer - function determineRequestsReferrer (request) { - // 1. Let policy be request's referrer policy. - const policy = request.referrerPolicy; - - // Note: policy cannot (shouldn't) be null or an empty string. - assert(policy); - - // 2. Let environment be request’s client. - - let referrerSource = null; - - // 3. Switch on request’s referrer: - if (request.referrer === 'client') { - // Note: node isn't a browser and doesn't implement document/iframes, - // so we bypass this step and replace it with our own. - - const globalOrigin = getGlobalOrigin(); - - if (!globalOrigin || globalOrigin.origin === 'null') { - return 'no-referrer' - } - - // note: we need to clone it as it's mutated - referrerSource = new URL(globalOrigin); - } else if (request.referrer instanceof URL) { - // Let referrerSource be request’s referrer. - referrerSource = request.referrer; - } - - // 4. Let request’s referrerURL be the result of stripping referrerSource for - // use as a referrer. - let referrerURL = stripURLForReferrer(referrerSource); - - // 5. Let referrerOrigin be the result of stripping referrerSource for use as - // a referrer, with the origin-only flag set to true. - const referrerOrigin = stripURLForReferrer(referrerSource, true); - - // 6. If the result of serializing referrerURL is a string whose length is - // greater than 4096, set referrerURL to referrerOrigin. - if (referrerURL.toString().length > 4096) { - referrerURL = referrerOrigin; - } - - const areSameOrigin = sameOrigin(request, referrerURL); - const isNonPotentiallyTrustWorthy = isURLPotentiallyTrustworthy(referrerURL) && - !isURLPotentiallyTrustworthy(request.url); - - // 8. Execute the switch statements corresponding to the value of policy: - switch (policy) { - case 'origin': return referrerOrigin != null ? referrerOrigin : stripURLForReferrer(referrerSource, true) - case 'unsafe-url': return referrerURL - case 'same-origin': - return areSameOrigin ? referrerOrigin : 'no-referrer' - case 'origin-when-cross-origin': - return areSameOrigin ? referrerURL : referrerOrigin - case 'strict-origin-when-cross-origin': { - const currentURL = requestCurrentURL(request); - - // 1. If the origin of referrerURL and the origin of request’s current - // URL are the same, then return referrerURL. - if (sameOrigin(referrerURL, currentURL)) { - return referrerURL - } - - // 2. If referrerURL is a potentially trustworthy URL and request’s - // current URL is not a potentially trustworthy URL, then return no - // referrer. - if (isURLPotentiallyTrustworthy(referrerURL) && !isURLPotentiallyTrustworthy(currentURL)) { - return 'no-referrer' - } - - // 3. Return referrerOrigin. - return referrerOrigin - } - case 'strict-origin': // eslint-disable-line - /** - * 1. If referrerURL is a potentially trustworthy URL and - * request’s current URL is not a potentially trustworthy URL, - * then return no referrer. - * 2. Return referrerOrigin - */ - case 'no-referrer-when-downgrade': // eslint-disable-line - /** - * 1. If referrerURL is a potentially trustworthy URL and - * request’s current URL is not a potentially trustworthy URL, - * then return no referrer. - * 2. Return referrerOrigin - */ - - default: // eslint-disable-line - return isNonPotentiallyTrustWorthy ? 'no-referrer' : referrerOrigin - } - } - - /** - * @see https://w3c.github.io/webappsec-referrer-policy/#strip-url - * @param {URL} url - * @param {boolean|undefined} originOnly - */ - function stripURLForReferrer (url, originOnly) { - // 1. Assert: url is a URL. - assert(url instanceof URL); - - url = new URL(url); - - // 2. If url’s scheme is a local scheme, then return no referrer. - if (url.protocol === 'file:' || url.protocol === 'about:' || url.protocol === 'blank:') { - return 'no-referrer' - } - - // 3. Set url’s username to the empty string. - url.username = ''; - - // 4. Set url’s password to the empty string. - url.password = ''; - - // 5. Set url’s fragment to null. - url.hash = ''; - - // 6. If the origin-only flag is true, then: - if (originOnly) { - // 1. Set url’s path to « the empty string ». - url.pathname = ''; - - // 2. Set url’s query to null. - url.search = ''; - } - - // 7. Return url. - return url - } - - function isURLPotentiallyTrustworthy (url) { - if (!(url instanceof URL)) { - return false - } - - // If child of about, return true - if (url.href === 'about:blank' || url.href === 'about:srcdoc') { - return true - } - - // If scheme is data, return true - if (url.protocol === 'data:') return true - - // If file, return true - if (url.protocol === 'file:') return true - - return isOriginPotentiallyTrustworthy(url.origin) - - function isOriginPotentiallyTrustworthy (origin) { - // If origin is explicitly null, return false - if (origin == null || origin === 'null') return false - - const originAsURL = new URL(origin); - - // If secure, return true - if (originAsURL.protocol === 'https:' || originAsURL.protocol === 'wss:') { - return true - } - - // If localhost or variants, return true - if (/^127(?:\.[0-9]+){0,2}\.[0-9]+$|^\[(?:0*:)*?:?0*1\]$/.test(originAsURL.hostname) || - (originAsURL.hostname === 'localhost' || originAsURL.hostname.includes('localhost.')) || - (originAsURL.hostname.endsWith('.localhost'))) { - return true - } - - // If any other, return false - return false - } - } - - /** - * @see https://w3c.github.io/webappsec-subresource-integrity/#does-response-match-metadatalist - * @param {Uint8Array} bytes - * @param {string} metadataList - */ - function bytesMatch (bytes, metadataList) { - // If node is not built with OpenSSL support, we cannot check - // a request's integrity, so allow it by default (the spec will - // allow requests if an invalid hash is given, as precedence). - /* istanbul ignore if: only if node is built with --without-ssl */ - if (crypto === undefined) { - return true - } - - // 1. Let parsedMetadata be the result of parsing metadataList. - const parsedMetadata = parseMetadata(metadataList); - - // 2. If parsedMetadata is no metadata, return true. - if (parsedMetadata === 'no metadata') { - return true - } - - // 3. If response is not eligible for integrity validation, return false. - // TODO - - // 4. If parsedMetadata is the empty set, return true. - if (parsedMetadata.length === 0) { - return true - } - - // 5. Let metadata be the result of getting the strongest - // metadata from parsedMetadata. - const strongest = getStrongestMetadata(parsedMetadata); - const metadata = filterMetadataListByAlgorithm(parsedMetadata, strongest); - - // 6. For each item in metadata: - for (const item of metadata) { - // 1. Let algorithm be the alg component of item. - const algorithm = item.algo; - - // 2. Let expectedValue be the val component of item. - const expectedValue = item.hash; - - // See https://github.com/web-platform-tests/wpt/commit/e4c5cc7a5e48093220528dfdd1c4012dc3837a0e - // "be liberal with padding". This is annoying, and it's not even in the spec. - - // 3. Let actualValue be the result of applying algorithm to bytes. - let actualValue = crypto.createHash(algorithm).update(bytes).digest('base64'); - - if (actualValue[actualValue.length - 1] === '=') { - if (actualValue[actualValue.length - 2] === '=') { - actualValue = actualValue.slice(0, -2); - } else { - actualValue = actualValue.slice(0, -1); - } - } - - // 4. If actualValue is a case-sensitive match for expectedValue, - // return true. - if (compareBase64Mixed(actualValue, expectedValue)) { - return true - } - } - - // 7. Return false. - return false - } - - // https://w3c.github.io/webappsec-subresource-integrity/#grammardef-hash-with-options - // https://www.w3.org/TR/CSP2/#source-list-syntax - // https://www.rfc-editor.org/rfc/rfc5234#appendix-B.1 - const parseHashWithOptions = /(?sha256|sha384|sha512)-((?[A-Za-z0-9+/]+|[A-Za-z0-9_-]+)={0,2}(?:\s|$)( +[!-~]*)?)?/i; - - /** - * @see https://w3c.github.io/webappsec-subresource-integrity/#parse-metadata - * @param {string} metadata - */ - function parseMetadata (metadata) { - // 1. Let result be the empty set. - /** @type {{ algo: string, hash: string }[]} */ - const result = []; - - // 2. Let empty be equal to true. - let empty = true; - - // 3. For each token returned by splitting metadata on spaces: - for (const token of metadata.split(' ')) { - // 1. Set empty to false. - empty = false; - - // 2. Parse token as a hash-with-options. - const parsedToken = parseHashWithOptions.exec(token); - - // 3. If token does not parse, continue to the next token. - if ( - parsedToken === null || - parsedToken.groups === undefined || - parsedToken.groups.algo === undefined - ) { - // Note: Chromium blocks the request at this point, but Firefox - // gives a warning that an invalid integrity was given. The - // correct behavior is to ignore these, and subsequently not - // check the integrity of the resource. - continue - } - - // 4. Let algorithm be the hash-algo component of token. - const algorithm = parsedToken.groups.algo.toLowerCase(); - - // 5. If algorithm is a hash function recognized by the user - // agent, add the parsed token to result. - if (supportedHashes.includes(algorithm)) { - result.push(parsedToken.groups); - } - } - - // 4. Return no metadata if empty is true, otherwise return result. - if (empty === true) { - return 'no metadata' - } - - return result - } - - /** - * @param {{ algo: 'sha256' | 'sha384' | 'sha512' }[]} metadataList - */ - function getStrongestMetadata (metadataList) { - // Let algorithm be the algo component of the first item in metadataList. - // Can be sha256 - let algorithm = metadataList[0].algo; - // If the algorithm is sha512, then it is the strongest - // and we can return immediately - if (algorithm[3] === '5') { - return algorithm - } - - for (let i = 1; i < metadataList.length; ++i) { - const metadata = metadataList[i]; - // If the algorithm is sha512, then it is the strongest - // and we can break the loop immediately - if (metadata.algo[3] === '5') { - algorithm = 'sha512'; - break - // If the algorithm is sha384, then a potential sha256 or sha384 is ignored - } else if (algorithm[3] === '3') { - continue - // algorithm is sha256, check if algorithm is sha384 and if so, set it as - // the strongest - } else if (metadata.algo[3] === '3') { - algorithm = 'sha384'; - } - } - return algorithm - } - - function filterMetadataListByAlgorithm (metadataList, algorithm) { - if (metadataList.length === 1) { - return metadataList - } - - let pos = 0; - for (let i = 0; i < metadataList.length; ++i) { - if (metadataList[i].algo === algorithm) { - metadataList[pos++] = metadataList[i]; - } - } - - metadataList.length = pos; - - return metadataList - } - - /** - * Compares two base64 strings, allowing for base64url - * in the second string. - * - * @param {string} actualValue always base64 - * @param {string} expectedValue base64 or base64url - * @returns {boolean} - */ - function compareBase64Mixed (actualValue, expectedValue) { - if (actualValue.length !== expectedValue.length) { - return false - } - for (let i = 0; i < actualValue.length; ++i) { - if (actualValue[i] !== expectedValue[i]) { - if ( - (actualValue[i] === '+' && expectedValue[i] === '-') || - (actualValue[i] === '/' && expectedValue[i] === '_') - ) { - continue - } - return false - } - } - - return true - } - - // https://w3c.github.io/webappsec-upgrade-insecure-requests/#upgrade-request - function tryUpgradeRequestToAPotentiallyTrustworthyURL (request) { - // TODO - } - - /** - * @link {https://html.spec.whatwg.org/multipage/origin.html#same-origin} - * @param {URL} A - * @param {URL} B - */ - function sameOrigin (A, B) { - // 1. If A and B are the same opaque origin, then return true. - if (A.origin === B.origin && A.origin === 'null') { - return true - } - - // 2. If A and B are both tuple origins and their schemes, - // hosts, and port are identical, then return true. - if (A.protocol === B.protocol && A.hostname === B.hostname && A.port === B.port) { - return true - } - - // 3. Return false. - return false - } - - function createDeferredPromise () { - let res; - let rej; - const promise = new Promise((resolve, reject) => { - res = resolve; - rej = reject; - }); - - return { promise, resolve: res, reject: rej } - } - - function isAborted (fetchParams) { - return fetchParams.controller.state === 'aborted' - } - - function isCancelled (fetchParams) { - return fetchParams.controller.state === 'aborted' || - fetchParams.controller.state === 'terminated' - } - - /** - * @see https://fetch.spec.whatwg.org/#concept-method-normalize - * @param {string} method - */ - function normalizeMethod (method) { - return normalizedMethodRecordsBase[method.toLowerCase()] ?? method - } - - // https://infra.spec.whatwg.org/#serialize-a-javascript-value-to-a-json-string - function serializeJavascriptValueToJSONString (value) { - // 1. Let result be ? Call(%JSON.stringify%, undefined, « value »). - const result = JSON.stringify(value); - - // 2. If result is undefined, then throw a TypeError. - if (result === undefined) { - throw new TypeError('Value is not JSON serializable') - } - - // 3. Assert: result is a string. - assert(typeof result === 'string'); - - // 4. Return result. - return result - } - - // https://tc39.es/ecma262/#sec-%25iteratorprototype%25-object - const esIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]())); - - /** - * @see https://webidl.spec.whatwg.org/#dfn-iterator-prototype-object - * @param {string} name name of the instance - * @param {symbol} kInternalIterator - * @param {string | number} [keyIndex] - * @param {string | number} [valueIndex] - */ - function createIterator (name, kInternalIterator, keyIndex = 0, valueIndex = 1) { - class FastIterableIterator { - /** @type {any} */ - #target - /** @type {'key' | 'value' | 'key+value'} */ - #kind - /** @type {number} */ - #index - - /** - * @see https://webidl.spec.whatwg.org/#dfn-default-iterator-object - * @param {unknown} target - * @param {'key' | 'value' | 'key+value'} kind - */ - constructor (target, kind) { - this.#target = target; - this.#kind = kind; - this.#index = 0; - } - - next () { - // 1. Let interface be the interface for which the iterator prototype object exists. - // 2. Let thisValue be the this value. - // 3. Let object be ? ToObject(thisValue). - // 4. If object is a platform object, then perform a security - // check, passing: - // 5. If object is not a default iterator object for interface, - // then throw a TypeError. - if (typeof this !== 'object' || this === null || !(#target in this)) { - throw new TypeError( - `'next' called on an object that does not implement interface ${name} Iterator.` - ) - } - - // 6. Let index be object’s index. - // 7. Let kind be object’s kind. - // 8. Let values be object’s target's value pairs to iterate over. - const index = this.#index; - const values = this.#target[kInternalIterator]; - - // 9. Let len be the length of values. - const len = values.length; - - // 10. If index is greater than or equal to len, then return - // CreateIterResultObject(undefined, true). - if (index >= len) { - return { - value: undefined, - done: true - } - } - - // 11. Let pair be the entry in values at index index. - const { [keyIndex]: key, [valueIndex]: value } = values[index]; - - // 12. Set object’s index to index + 1. - this.#index = index + 1; - - // 13. Return the iterator result for pair and kind. - - // https://webidl.spec.whatwg.org/#iterator-result - - // 1. Let result be a value determined by the value of kind: - let result; - switch (this.#kind) { - case 'key': - // 1. Let idlKey be pair’s key. - // 2. Let key be the result of converting idlKey to an - // ECMAScript value. - // 3. result is key. - result = key; - break - case 'value': - // 1. Let idlValue be pair’s value. - // 2. Let value be the result of converting idlValue to - // an ECMAScript value. - // 3. result is value. - result = value; - break - case 'key+value': - // 1. Let idlKey be pair’s key. - // 2. Let idlValue be pair’s value. - // 3. Let key be the result of converting idlKey to an - // ECMAScript value. - // 4. Let value be the result of converting idlValue to - // an ECMAScript value. - // 5. Let array be ! ArrayCreate(2). - // 6. Call ! CreateDataProperty(array, "0", key). - // 7. Call ! CreateDataProperty(array, "1", value). - // 8. result is array. - result = [key, value]; - break - } - - // 2. Return CreateIterResultObject(result, false). - return { - value: result, - done: false - } - } - } - - // https://webidl.spec.whatwg.org/#dfn-iterator-prototype-object - // @ts-ignore - delete FastIterableIterator.prototype.constructor; - - Object.setPrototypeOf(FastIterableIterator.prototype, esIteratorPrototype); - - Object.defineProperties(FastIterableIterator.prototype, { - [Symbol.toStringTag]: { - writable: false, - enumerable: false, - configurable: true, - value: `${name} Iterator` - }, - next: { writable: true, enumerable: true, configurable: true } - }); - - /** - * @param {unknown} target - * @param {'key' | 'value' | 'key+value'} kind - * @returns {IterableIterator} - */ - return function (target, kind) { - return new FastIterableIterator(target, kind) - } - } - - /** - * @see https://webidl.spec.whatwg.org/#dfn-iterator-prototype-object - * @param {string} name name of the instance - * @param {any} object class - * @param {symbol} kInternalIterator - * @param {string | number} [keyIndex] - * @param {string | number} [valueIndex] - */ - function iteratorMixin (name, object, kInternalIterator, keyIndex = 0, valueIndex = 1) { - const makeIterator = createIterator(name, kInternalIterator, keyIndex, valueIndex); - - const properties = { - keys: { - writable: true, - enumerable: true, - configurable: true, - value: function keys () { - webidl.brandCheck(this, object); - return makeIterator(this, 'key') - } - }, - values: { - writable: true, - enumerable: true, - configurable: true, - value: function values () { - webidl.brandCheck(this, object); - return makeIterator(this, 'value') - } - }, - entries: { - writable: true, - enumerable: true, - configurable: true, - value: function entries () { - webidl.brandCheck(this, object); - return makeIterator(this, 'key+value') - } - }, - forEach: { - writable: true, - enumerable: true, - configurable: true, - value: function forEach (callbackfn, thisArg = globalThis) { - webidl.brandCheck(this, object); - webidl.argumentLengthCheck(arguments, 1, `${name}.forEach`); - if (typeof callbackfn !== 'function') { - throw new TypeError( - `Failed to execute 'forEach' on '${name}': parameter 1 is not of type 'Function'.` - ) - } - for (const { 0: key, 1: value } of makeIterator(this, 'key+value')) { - callbackfn.call(thisArg, value, key, this); - } - } - } - }; - - return Object.defineProperties(object.prototype, { - ...properties, - [Symbol.iterator]: { - writable: true, - enumerable: false, - configurable: true, - value: properties.entries.value - } - }) - } - - /** - * @see https://fetch.spec.whatwg.org/#body-fully-read - */ - async function fullyReadBody (body, processBody, processBodyError, shouldClone) { - // 1. If taskDestination is null, then set taskDestination to - // the result of starting a new parallel queue. - - // 2. Let successSteps given a byte sequence bytes be to queue a - // fetch task to run processBody given bytes, with taskDestination. - const successSteps = processBody; - - // 3. Let errorSteps be to queue a fetch task to run processBodyError, - // with taskDestination. - const errorSteps = processBodyError; - - // 4. Let reader be the result of getting a reader for body’s stream. - // If that threw an exception, then run errorSteps with that - // exception and return. - let reader; - - try { - reader = body.stream.getReader(); - } catch (e) { - errorSteps(e); - return - } - - // 5. Read all bytes from reader, given successSteps and errorSteps. - try { - successSteps(await readAllBytes(reader, shouldClone)); - } catch (e) { - errorSteps(e); - } - } - - function isReadableStreamLike (stream) { - return stream instanceof ReadableStream || ( - stream[Symbol.toStringTag] === 'ReadableStream' && - typeof stream.tee === 'function' - ) - } - - /** - * @param {ReadableStreamController} controller - */ - function readableStreamClose (controller) { - try { - controller.close(); - controller.byobRequest?.respond(0); - } catch (err) { - // TODO: add comment explaining why this error occurs. - if (!err.message.includes('Controller is already closed') && !err.message.includes('ReadableStream is already closed')) { - throw err - } - } - } - - const invalidIsomorphicEncodeValueRegex = /[^\x00-\xFF]/; // eslint-disable-line - - /** - * @see https://infra.spec.whatwg.org/#isomorphic-encode - * @param {string} input - */ - function isomorphicEncode (input) { - // 1. Assert: input contains no code points greater than U+00FF. - assert(!invalidIsomorphicEncodeValueRegex.test(input)); - - // 2. Return a byte sequence whose length is equal to input’s code - // point length and whose bytes have the same values as the - // values of input’s code points, in the same order - return input - } - - /** - * @see https://streams.spec.whatwg.org/#readablestreamdefaultreader-read-all-bytes - * @see https://streams.spec.whatwg.org/#read-loop - * @param {ReadableStreamDefaultReader} reader - * @param {boolean} [shouldClone] - */ - async function readAllBytes (reader, shouldClone) { - const bytes = []; - let byteLength = 0; - - while (true) { - const { done, value: chunk } = await reader.read(); - - if (done) { - // 1. Call successSteps with bytes. - if (bytes.length === 1) { - const { buffer, byteOffset, byteLength } = bytes[0]; - if (shouldClone === false) { - return Buffer.from(buffer, byteOffset, byteLength) - } - return Buffer.from(buffer.slice(byteOffset, byteOffset + byteLength), 0, byteLength) - } - return Buffer.concat(bytes, byteLength) - } - - // 1. If chunk is not a Uint8Array object, call failureSteps - // with a TypeError and abort these steps. - if (!isUint8Array(chunk)) { - throw new TypeError('Received non-Uint8Array chunk') - } - - // 2. Append the bytes represented by chunk to bytes. - bytes.push(chunk); - byteLength += chunk.length; - - // 3. Read-loop given reader, bytes, successSteps, and failureSteps. - } - } - - /** - * @see https://fetch.spec.whatwg.org/#is-local - * @param {URL} url - */ - function urlIsLocal (url) { - assert('protocol' in url); // ensure it's a url object - - const protocol = url.protocol; - - return protocol === 'about:' || protocol === 'blob:' || protocol === 'data:' - } - - /** - * @param {string|URL} url - * @returns {boolean} - */ - function urlHasHttpsScheme (url) { - return ( - ( - typeof url === 'string' && - url[5] === ':' && - url[0] === 'h' && - url[1] === 't' && - url[2] === 't' && - url[3] === 'p' && - url[4] === 's' - ) || - url.protocol === 'https:' - ) - } - - /** - * @see https://fetch.spec.whatwg.org/#http-scheme - * @param {URL} url - */ - function urlIsHttpHttpsScheme (url) { - assert('protocol' in url); // ensure it's a url object - - const protocol = url.protocol; - - return protocol === 'http:' || protocol === 'https:' - } - - /** - * @see https://fetch.spec.whatwg.org/#simple-range-header-value - * @param {string} value - * @param {boolean} allowWhitespace - */ - function simpleRangeHeaderValue (value, allowWhitespace) { - // 1. Let data be the isomorphic decoding of value. - // Note: isomorphic decoding takes a sequence of bytes (ie. a Uint8Array) and turns it into a string, - // nothing more. We obviously don't need to do that if value is a string already. - const data = value; - - // 2. If data does not start with "bytes", then return failure. - if (!data.startsWith('bytes')) { - return 'failure' - } - - // 3. Let position be a position variable for data, initially pointing at the 5th code point of data. - const position = { position: 5 }; - - // 4. If allowWhitespace is true, collect a sequence of code points that are HTTP tab or space, - // from data given position. - if (allowWhitespace) { - collectASequenceOfCodePoints( - (char) => char === '\t' || char === ' ', - data, - position - ); - } - - // 5. If the code point at position within data is not U+003D (=), then return failure. - if (data.charCodeAt(position.position) !== 0x3D) { - return 'failure' - } - - // 6. Advance position by 1. - position.position++; - - // 7. If allowWhitespace is true, collect a sequence of code points that are HTTP tab or space, from - // data given position. - if (allowWhitespace) { - collectASequenceOfCodePoints( - (char) => char === '\t' || char === ' ', - data, - position - ); - } - - // 8. Let rangeStart be the result of collecting a sequence of code points that are ASCII digits, - // from data given position. - const rangeStart = collectASequenceOfCodePoints( - (char) => { - const code = char.charCodeAt(0); - - return code >= 0x30 && code <= 0x39 - }, - data, - position - ); - - // 9. Let rangeStartValue be rangeStart, interpreted as decimal number, if rangeStart is not the - // empty string; otherwise null. - const rangeStartValue = rangeStart.length ? Number(rangeStart) : null; - - // 10. If allowWhitespace is true, collect a sequence of code points that are HTTP tab or space, - // from data given position. - if (allowWhitespace) { - collectASequenceOfCodePoints( - (char) => char === '\t' || char === ' ', - data, - position - ); - } - - // 11. If the code point at position within data is not U+002D (-), then return failure. - if (data.charCodeAt(position.position) !== 0x2D) { - return 'failure' - } - - // 12. Advance position by 1. - position.position++; - - // 13. If allowWhitespace is true, collect a sequence of code points that are HTTP tab - // or space, from data given position. - // Note from Khafra: its the same step as in #8 again lol - if (allowWhitespace) { - collectASequenceOfCodePoints( - (char) => char === '\t' || char === ' ', - data, - position - ); - } - - // 14. Let rangeEnd be the result of collecting a sequence of code points that are - // ASCII digits, from data given position. - // Note from Khafra: you wouldn't guess it, but this is also the same step as #8 - const rangeEnd = collectASequenceOfCodePoints( - (char) => { - const code = char.charCodeAt(0); - - return code >= 0x30 && code <= 0x39 - }, - data, - position - ); - - // 15. Let rangeEndValue be rangeEnd, interpreted as decimal number, if rangeEnd - // is not the empty string; otherwise null. - // Note from Khafra: THE SAME STEP, AGAIN!!! - // Note: why interpret as a decimal if we only collect ascii digits? - const rangeEndValue = rangeEnd.length ? Number(rangeEnd) : null; - - // 16. If position is not past the end of data, then return failure. - if (position.position < data.length) { - return 'failure' - } - - // 17. If rangeEndValue and rangeStartValue are null, then return failure. - if (rangeEndValue === null && rangeStartValue === null) { - return 'failure' - } - - // 18. If rangeStartValue and rangeEndValue are numbers, and rangeStartValue is - // greater than rangeEndValue, then return failure. - // Note: ... when can they not be numbers? - if (rangeStartValue > rangeEndValue) { - return 'failure' - } - - // 19. Return (rangeStartValue, rangeEndValue). - return { rangeStartValue, rangeEndValue } - } - - /** - * @see https://fetch.spec.whatwg.org/#build-a-content-range - * @param {number} rangeStart - * @param {number} rangeEnd - * @param {number} fullLength - */ - function buildContentRange (rangeStart, rangeEnd, fullLength) { - // 1. Let contentRange be `bytes `. - let contentRange = 'bytes '; - - // 2. Append rangeStart, serialized and isomorphic encoded, to contentRange. - contentRange += isomorphicEncode(`${rangeStart}`); - - // 3. Append 0x2D (-) to contentRange. - contentRange += '-'; - - // 4. Append rangeEnd, serialized and isomorphic encoded to contentRange. - contentRange += isomorphicEncode(`${rangeEnd}`); - - // 5. Append 0x2F (/) to contentRange. - contentRange += '/'; - - // 6. Append fullLength, serialized and isomorphic encoded to contentRange. - contentRange += isomorphicEncode(`${fullLength}`); - - // 7. Return contentRange. - return contentRange - } - - // A Stream, which pipes the response to zlib.createInflate() or - // zlib.createInflateRaw() depending on the first byte of the Buffer. - // If the lower byte of the first byte is 0x08, then the stream is - // interpreted as a zlib stream, otherwise it's interpreted as a - // raw deflate stream. - class InflateStream extends Transform { - _transform (chunk, encoding, callback) { - if (!this._inflateStream) { - if (chunk.length === 0) { - callback(); - return - } - this._inflateStream = (chunk[0] & 0x0F) === 0x08 - ? zlib.createInflate() - : zlib.createInflateRaw(); - - this._inflateStream.on('data', this.push.bind(this)); - this._inflateStream.on('end', () => this.push(null)); - this._inflateStream.on('error', (err) => this.destroy(err)); - } - - this._inflateStream.write(chunk, encoding, callback); - } - - _final (callback) { - if (this._inflateStream) { - this._inflateStream.end(); - this._inflateStream = null; - } - callback(); - } - } - - function createInflate () { - return new InflateStream() - } - - /** - * @see https://fetch.spec.whatwg.org/#concept-header-extract-mime-type - * @param {import('./headers').HeadersList} headers - */ - function extractMimeType (headers) { - // 1. Let charset be null. - let charset = null; - - // 2. Let essence be null. - let essence = null; - - // 3. Let mimeType be null. - let mimeType = null; - - // 4. Let values be the result of getting, decoding, and splitting `Content-Type` from headers. - const values = getDecodeSplit('content-type', headers); - - // 5. If values is null, then return failure. - if (values === null) { - return 'failure' - } - - // 6. For each value of values: - for (const value of values) { - // 6.1. Let temporaryMimeType be the result of parsing value. - const temporaryMimeType = parseMIMEType(value); - - // 6.2. If temporaryMimeType is failure or its essence is "*/*", then continue. - if (temporaryMimeType === 'failure' || temporaryMimeType.essence === '*/*') { - continue - } - - // 6.3. Set mimeType to temporaryMimeType. - mimeType = temporaryMimeType; - - // 6.4. If mimeType’s essence is not essence, then: - if (mimeType.essence !== essence) { - // 6.4.1. Set charset to null. - charset = null; - - // 6.4.2. If mimeType’s parameters["charset"] exists, then set charset to - // mimeType’s parameters["charset"]. - if (mimeType.parameters.has('charset')) { - charset = mimeType.parameters.get('charset'); - } - - // 6.4.3. Set essence to mimeType’s essence. - essence = mimeType.essence; - } else if (!mimeType.parameters.has('charset') && charset !== null) { - // 6.5. Otherwise, if mimeType’s parameters["charset"] does not exist, and - // charset is non-null, set mimeType’s parameters["charset"] to charset. - mimeType.parameters.set('charset', charset); - } - } - - // 7. If mimeType is null, then return failure. - if (mimeType == null) { - return 'failure' - } - - // 8. Return mimeType. - return mimeType - } - - /** - * @see https://fetch.spec.whatwg.org/#header-value-get-decode-and-split - * @param {string|null} value - */ - function gettingDecodingSplitting (value) { - // 1. Let input be the result of isomorphic decoding value. - const input = value; - - // 2. Let position be a position variable for input, initially pointing at the start of input. - const position = { position: 0 }; - - // 3. Let values be a list of strings, initially empty. - const values = []; - - // 4. Let temporaryValue be the empty string. - let temporaryValue = ''; - - // 5. While position is not past the end of input: - while (position.position < input.length) { - // 5.1. Append the result of collecting a sequence of code points that are not U+0022 (") - // or U+002C (,) from input, given position, to temporaryValue. - temporaryValue += collectASequenceOfCodePoints( - (char) => char !== '"' && char !== ',', - input, - position - ); - - // 5.2. If position is not past the end of input, then: - if (position.position < input.length) { - // 5.2.1. If the code point at position within input is U+0022 ("), then: - if (input.charCodeAt(position.position) === 0x22) { - // 5.2.1.1. Append the result of collecting an HTTP quoted string from input, given position, to temporaryValue. - temporaryValue += collectAnHTTPQuotedString( - input, - position - ); - - // 5.2.1.2. If position is not past the end of input, then continue. - if (position.position < input.length) { - continue - } - } else { - // 5.2.2. Otherwise: - - // 5.2.2.1. Assert: the code point at position within input is U+002C (,). - assert(input.charCodeAt(position.position) === 0x2C); - - // 5.2.2.2. Advance position by 1. - position.position++; - } - } - - // 5.3. Remove all HTTP tab or space from the start and end of temporaryValue. - temporaryValue = removeChars(temporaryValue, true, true, (char) => char === 0x9 || char === 0x20); - - // 5.4. Append temporaryValue to values. - values.push(temporaryValue); - - // 5.6. Set temporaryValue to the empty string. - temporaryValue = ''; - } - - // 6. Return values. - return values - } - - /** - * @see https://fetch.spec.whatwg.org/#concept-header-list-get-decode-split - * @param {string} name lowercase header name - * @param {import('./headers').HeadersList} list - */ - function getDecodeSplit (name, list) { - // 1. Let value be the result of getting name from list. - const value = list.get(name, true); - - // 2. If value is null, then return null. - if (value === null) { - return null - } - - // 3. Return the result of getting, decoding, and splitting value. - return gettingDecodingSplitting(value) - } - - const textDecoder = new TextDecoder(); - - /** - * @see https://encoding.spec.whatwg.org/#utf-8-decode - * @param {Buffer} buffer - */ - function utf8DecodeBytes (buffer) { - if (buffer.length === 0) { - return '' - } - - // 1. Let buffer be the result of peeking three bytes from - // ioQueue, converted to a byte sequence. - - // 2. If buffer is 0xEF 0xBB 0xBF, then read three - // bytes from ioQueue. (Do nothing with those bytes.) - if (buffer[0] === 0xEF && buffer[1] === 0xBB && buffer[2] === 0xBF) { - buffer = buffer.subarray(3); - } - - // 3. Process a queue with an instance of UTF-8’s - // decoder, ioQueue, output, and "replacement". - const output = textDecoder.decode(buffer); - - // 4. Return output. - return output - } - - class EnvironmentSettingsObjectBase { - get baseUrl () { - return getGlobalOrigin() - } - - get origin () { - return this.baseUrl?.origin - } - - policyContainer = makePolicyContainer() - } - - class EnvironmentSettingsObject { - settingsObject = new EnvironmentSettingsObjectBase() - } - - const environmentSettingsObject = new EnvironmentSettingsObject(); - - util$6 = { - isAborted, - isCancelled, - isValidEncodedURL, - createDeferredPromise, - ReadableStreamFrom, - tryUpgradeRequestToAPotentiallyTrustworthyURL, - clampAndCoarsenConnectionTimingInfo, - coarsenedSharedCurrentTime, - determineRequestsReferrer, - makePolicyContainer, - clonePolicyContainer, - appendFetchMetadata, - appendRequestOriginHeader, - TAOCheck, - corsCheck, - crossOriginResourcePolicyCheck, - createOpaqueTimingInfo, - setRequestReferrerPolicyOnRedirect, - isValidHTTPToken, - requestBadPort, - requestCurrentURL, - responseURL, - responseLocationURL, - isBlobLike, - isURLPotentiallyTrustworthy, - isValidReasonPhrase, - sameOrigin, - normalizeMethod, - serializeJavascriptValueToJSONString, - iteratorMixin, - createIterator, - isValidHeaderName, - isValidHeaderValue, - isErrorLike, - fullyReadBody, - bytesMatch, - isReadableStreamLike, - readableStreamClose, - isomorphicEncode, - urlIsLocal, - urlHasHttpsScheme, - urlIsHttpHttpsScheme, - readAllBytes, - simpleRangeHeaderValue, - buildContentRange, - parseMetadata, - createInflate, - extractMimeType, - getDecodeSplit, - utf8DecodeBytes, - environmentSettingsObject - }; - return util$6; -} - -var symbols$3; -var hasRequiredSymbols$3; - -function requireSymbols$3 () { - if (hasRequiredSymbols$3) return symbols$3; - hasRequiredSymbols$3 = 1; - - symbols$3 = { - kUrl: Symbol('url'), - kHeaders: Symbol('headers'), - kSignal: Symbol('signal'), - kState: Symbol('state'), - kDispatcher: Symbol('dispatcher') - }; - return symbols$3; -} - -var file; -var hasRequiredFile; - -function requireFile () { - if (hasRequiredFile) return file; - hasRequiredFile = 1; - - const { Blob, File } = require$$0$3; - const { kState } = requireSymbols$3(); - const { webidl } = requireWebidl(); - - // TODO(@KhafraDev): remove - class FileLike { - constructor (blobLike, fileName, options = {}) { - // TODO: argument idl type check - - // The File constructor is invoked with two or three parameters, depending - // on whether the optional dictionary parameter is used. When the File() - // constructor is invoked, user agents must run the following steps: - - // 1. Let bytes be the result of processing blob parts given fileBits and - // options. - - // 2. Let n be the fileName argument to the constructor. - const n = fileName; - - // 3. Process FilePropertyBag dictionary argument by running the following - // substeps: - - // 1. If the type member is provided and is not the empty string, let t - // be set to the type dictionary member. If t contains any characters - // outside the range U+0020 to U+007E, then set t to the empty string - // and return from these substeps. - // TODO - const t = options.type; - - // 2. Convert every character in t to ASCII lowercase. - // TODO - - // 3. If the lastModified member is provided, let d be set to the - // lastModified dictionary member. If it is not provided, set d to the - // current date and time represented as the number of milliseconds since - // the Unix Epoch (which is the equivalent of Date.now() [ECMA-262]). - const d = options.lastModified ?? Date.now(); - - // 4. Return a new File object F such that: - // F refers to the bytes byte sequence. - // F.size is set to the number of total bytes in bytes. - // F.name is set to n. - // F.type is set to t. - // F.lastModified is set to d. - - this[kState] = { - blobLike, - name: n, - type: t, - lastModified: d - }; - } - - stream (...args) { - webidl.brandCheck(this, FileLike); - - return this[kState].blobLike.stream(...args) - } - - arrayBuffer (...args) { - webidl.brandCheck(this, FileLike); - - return this[kState].blobLike.arrayBuffer(...args) - } - - slice (...args) { - webidl.brandCheck(this, FileLike); - - return this[kState].blobLike.slice(...args) - } - - text (...args) { - webidl.brandCheck(this, FileLike); - - return this[kState].blobLike.text(...args) - } - - get size () { - webidl.brandCheck(this, FileLike); - - return this[kState].blobLike.size - } - - get type () { - webidl.brandCheck(this, FileLike); - - return this[kState].blobLike.type - } - - get name () { - webidl.brandCheck(this, FileLike); - - return this[kState].name - } - - get lastModified () { - webidl.brandCheck(this, FileLike); - - return this[kState].lastModified - } - - get [Symbol.toStringTag] () { - return 'File' - } - } - - webidl.converters.Blob = webidl.interfaceConverter(Blob); - - // If this function is moved to ./util.js, some tools (such as - // rollup) will warn about circular dependencies. See: - // https://github.com/nodejs/undici/issues/1629 - function isFileLike (object) { - return ( - (object instanceof File) || - ( - object && - (typeof object.stream === 'function' || - typeof object.arrayBuffer === 'function') && - object[Symbol.toStringTag] === 'File' - ) - ) - } - - file = { FileLike, isFileLike }; - return file; -} - -var formdata; -var hasRequiredFormdata; - -function requireFormdata () { - if (hasRequiredFormdata) return formdata; - hasRequiredFormdata = 1; - - const { isBlobLike, iteratorMixin } = requireUtil$6(); - const { kState } = requireSymbols$3(); - const { kEnumerableProperty } = requireUtil$7(); - const { FileLike, isFileLike } = requireFile(); - const { webidl } = requireWebidl(); - const { File: NativeFile } = require$$0$3; - const nodeUtil = require$$0$6; - - /** @type {globalThis['File']} */ - const File = globalThis.File ?? NativeFile; - - // https://xhr.spec.whatwg.org/#formdata - class FormData { - constructor (form) { - if (form !== undefined) { - throw webidl.errors.conversionFailed({ - prefix: 'FormData constructor', - argument: 'Argument 1', - types: ['undefined'] - }) - } - - this[kState] = []; - } - - append (name, value, filename = undefined) { - webidl.brandCheck(this, FormData); - - const prefix = 'FormData.append'; - webidl.argumentLengthCheck(arguments, 2, prefix); - - if (arguments.length === 3 && !isBlobLike(value)) { - throw new TypeError( - "Failed to execute 'append' on 'FormData': parameter 2 is not of type 'Blob'" - ) - } - - // 1. Let value be value if given; otherwise blobValue. - - name = webidl.converters.USVString(name, prefix, 'name'); - value = isBlobLike(value) - ? webidl.converters.Blob(value, prefix, 'value', { strict: false }) - : webidl.converters.USVString(value, prefix, 'value'); - filename = arguments.length === 3 - ? webidl.converters.USVString(filename, prefix, 'filename') - : undefined; - - // 2. Let entry be the result of creating an entry with - // name, value, and filename if given. - const entry = makeEntry(name, value, filename); - - // 3. Append entry to this’s entry list. - this[kState].push(entry); - } - - delete (name) { - webidl.brandCheck(this, FormData); - - const prefix = 'FormData.delete'; - webidl.argumentLengthCheck(arguments, 1, prefix); - - name = webidl.converters.USVString(name, prefix, 'name'); - - // The delete(name) method steps are to remove all entries whose name - // is name from this’s entry list. - this[kState] = this[kState].filter(entry => entry.name !== name); - } - - get (name) { - webidl.brandCheck(this, FormData); - - const prefix = 'FormData.get'; - webidl.argumentLengthCheck(arguments, 1, prefix); - - name = webidl.converters.USVString(name, prefix, 'name'); - - // 1. If there is no entry whose name is name in this’s entry list, - // then return null. - const idx = this[kState].findIndex((entry) => entry.name === name); - if (idx === -1) { - return null - } - - // 2. Return the value of the first entry whose name is name from - // this’s entry list. - return this[kState][idx].value - } - - getAll (name) { - webidl.brandCheck(this, FormData); - - const prefix = 'FormData.getAll'; - webidl.argumentLengthCheck(arguments, 1, prefix); - - name = webidl.converters.USVString(name, prefix, 'name'); - - // 1. If there is no entry whose name is name in this’s entry list, - // then return the empty list. - // 2. Return the values of all entries whose name is name, in order, - // from this’s entry list. - return this[kState] - .filter((entry) => entry.name === name) - .map((entry) => entry.value) - } - - has (name) { - webidl.brandCheck(this, FormData); - - const prefix = 'FormData.has'; - webidl.argumentLengthCheck(arguments, 1, prefix); - - name = webidl.converters.USVString(name, prefix, 'name'); - - // The has(name) method steps are to return true if there is an entry - // whose name is name in this’s entry list; otherwise false. - return this[kState].findIndex((entry) => entry.name === name) !== -1 - } - - set (name, value, filename = undefined) { - webidl.brandCheck(this, FormData); - - const prefix = 'FormData.set'; - webidl.argumentLengthCheck(arguments, 2, prefix); - - if (arguments.length === 3 && !isBlobLike(value)) { - throw new TypeError( - "Failed to execute 'set' on 'FormData': parameter 2 is not of type 'Blob'" - ) - } - - // The set(name, value) and set(name, blobValue, filename) method steps - // are: - - // 1. Let value be value if given; otherwise blobValue. - - name = webidl.converters.USVString(name, prefix, 'name'); - value = isBlobLike(value) - ? webidl.converters.Blob(value, prefix, 'name', { strict: false }) - : webidl.converters.USVString(value, prefix, 'name'); - filename = arguments.length === 3 - ? webidl.converters.USVString(filename, prefix, 'name') - : undefined; - - // 2. Let entry be the result of creating an entry with name, value, and - // filename if given. - const entry = makeEntry(name, value, filename); - - // 3. If there are entries in this’s entry list whose name is name, then - // replace the first such entry with entry and remove the others. - const idx = this[kState].findIndex((entry) => entry.name === name); - if (idx !== -1) { - this[kState] = [ - ...this[kState].slice(0, idx), - entry, - ...this[kState].slice(idx + 1).filter((entry) => entry.name !== name) - ]; - } else { - // 4. Otherwise, append entry to this’s entry list. - this[kState].push(entry); - } - } - - [nodeUtil.inspect.custom] (depth, options) { - const state = this[kState].reduce((a, b) => { - if (a[b.name]) { - if (Array.isArray(a[b.name])) { - a[b.name].push(b.value); - } else { - a[b.name] = [a[b.name], b.value]; - } - } else { - a[b.name] = b.value; - } - - return a - }, { __proto__: null }); - - options.depth ??= depth; - options.colors ??= true; - - const output = nodeUtil.formatWithOptions(options, state); - - // remove [Object null prototype] - return `FormData ${output.slice(output.indexOf(']') + 2)}` - } - } - - iteratorMixin('FormData', FormData, kState, 'name', 'value'); - - Object.defineProperties(FormData.prototype, { - append: kEnumerableProperty, - delete: kEnumerableProperty, - get: kEnumerableProperty, - getAll: kEnumerableProperty, - has: kEnumerableProperty, - set: kEnumerableProperty, - [Symbol.toStringTag]: { - value: 'FormData', - configurable: true - } - }); - - /** - * @see https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#create-an-entry - * @param {string} name - * @param {string|Blob} value - * @param {?string} filename - * @returns - */ - function makeEntry (name, value, filename) { - // 1. Set name to the result of converting name into a scalar value string. - // Note: This operation was done by the webidl converter USVString. - - // 2. If value is a string, then set value to the result of converting - // value into a scalar value string. - if (typeof value === 'string') ; else { - // 3. Otherwise: - - // 1. If value is not a File object, then set value to a new File object, - // representing the same bytes, whose name attribute value is "blob" - if (!isFileLike(value)) { - value = value instanceof Blob - ? new File([value], 'blob', { type: value.type }) - : new FileLike(value, 'blob', { type: value.type }); - } - - // 2. If filename is given, then set value to a new File object, - // representing the same bytes, whose name attribute is filename. - if (filename !== undefined) { - /** @type {FilePropertyBag} */ - const options = { - type: value.type, - lastModified: value.lastModified - }; - - value = value instanceof NativeFile - ? new File([value], filename, options) - : new FileLike(value, filename, options); - } - } - - // 4. Return an entry whose name is name and whose value is value. - return { name, value } - } - - formdata = { FormData, makeEntry }; - return formdata; -} - -var formdataParser; -var hasRequiredFormdataParser; - -function requireFormdataParser () { - if (hasRequiredFormdataParser) return formdataParser; - hasRequiredFormdataParser = 1; - - const { isUSVString, bufferToLowerCasedHeaderName } = requireUtil$7(); - const { utf8DecodeBytes } = requireUtil$6(); - const { HTTP_TOKEN_CODEPOINTS, isomorphicDecode } = requireDataUrl(); - const { isFileLike } = requireFile(); - const { makeEntry } = requireFormdata(); - const assert = require$$0$4; - const { File: NodeFile } = require$$0$3; - - const File = globalThis.File ?? NodeFile; - - const formDataNameBuffer = Buffer.from('form-data; name="'); - const filenameBuffer = Buffer.from('; filename'); - const dd = Buffer.from('--'); - const ddcrlf = Buffer.from('--\r\n'); - - /** - * @param {string} chars - */ - function isAsciiString (chars) { - for (let i = 0; i < chars.length; ++i) { - if ((chars.charCodeAt(i) & -128) !== 0) { - return false - } - } - return true - } - - /** - * @see https://andreubotella.github.io/multipart-form-data/#multipart-form-data-boundary - * @param {string} boundary - */ - function validateBoundary (boundary) { - const length = boundary.length; - - // - its length is greater or equal to 27 and lesser or equal to 70, and - if (length < 27 || length > 70) { - return false - } - - // - it is composed by bytes in the ranges 0x30 to 0x39, 0x41 to 0x5A, or - // 0x61 to 0x7A, inclusive (ASCII alphanumeric), or which are 0x27 ('), - // 0x2D (-) or 0x5F (_). - for (let i = 0; i < length; ++i) { - const cp = boundary.charCodeAt(i); - - if (!( - (cp >= 0x30 && cp <= 0x39) || - (cp >= 0x41 && cp <= 0x5a) || - (cp >= 0x61 && cp <= 0x7a) || - cp === 0x27 || - cp === 0x2d || - cp === 0x5f - )) { - return false - } - } - - return true - } - - /** - * @see https://andreubotella.github.io/multipart-form-data/#multipart-form-data-parser - * @param {Buffer} input - * @param {ReturnType} mimeType - */ - function multipartFormDataParser (input, mimeType) { - // 1. Assert: mimeType’s essence is "multipart/form-data". - assert(mimeType !== 'failure' && mimeType.essence === 'multipart/form-data'); - - const boundaryString = mimeType.parameters.get('boundary'); - - // 2. If mimeType’s parameters["boundary"] does not exist, return failure. - // Otherwise, let boundary be the result of UTF-8 decoding mimeType’s - // parameters["boundary"]. - if (boundaryString === undefined) { - return 'failure' - } - - const boundary = Buffer.from(`--${boundaryString}`, 'utf8'); - - // 3. Let entry list be an empty entry list. - const entryList = []; - - // 4. Let position be a pointer to a byte in input, initially pointing at - // the first byte. - const position = { position: 0 }; - - // Note: undici addition, allow \r\n before the body. - if (input[0] === 0x0d && input[1] === 0x0a) { - position.position += 2; - } - - // 5. While true: - while (true) { - // 5.1. If position points to a sequence of bytes starting with 0x2D 0x2D - // (`--`) followed by boundary, advance position by 2 + the length of - // boundary. Otherwise, return failure. - // Note: boundary is padded with 2 dashes already, no need to add 2. - if (input.subarray(position.position, position.position + boundary.length).equals(boundary)) { - position.position += boundary.length; - } else { - return 'failure' - } - - // 5.2. If position points to the sequence of bytes 0x2D 0x2D 0x0D 0x0A - // (`--` followed by CR LF) followed by the end of input, return entry list. - // Note: a body does NOT need to end with CRLF. It can end with --. - if ( - (position.position === input.length - 2 && bufferStartsWith(input, dd, position)) || - (position.position === input.length - 4 && bufferStartsWith(input, ddcrlf, position)) - ) { - return entryList - } - - // 5.3. If position does not point to a sequence of bytes starting with 0x0D - // 0x0A (CR LF), return failure. - if (input[position.position] !== 0x0d || input[position.position + 1] !== 0x0a) { - return 'failure' - } - - // 5.4. Advance position by 2. (This skips past the newline.) - position.position += 2; - - // 5.5. Let name, filename and contentType be the result of parsing - // multipart/form-data headers on input and position, if the result - // is not failure. Otherwise, return failure. - const result = parseMultipartFormDataHeaders(input, position); - - if (result === 'failure') { - return 'failure' - } - - let { name, filename, contentType, encoding } = result; - - // 5.6. Advance position by 2. (This skips past the empty line that marks - // the end of the headers.) - position.position += 2; - - // 5.7. Let body be the empty byte sequence. - let body; - - // 5.8. Body loop: While position is not past the end of input: - // TODO: the steps here are completely wrong - { - const boundaryIndex = input.indexOf(boundary.subarray(2), position.position); - - if (boundaryIndex === -1) { - return 'failure' - } - - body = input.subarray(position.position, boundaryIndex - 4); - - position.position += body.length; - - // Note: position must be advanced by the body's length before being - // decoded, otherwise the parsing will fail. - if (encoding === 'base64') { - body = Buffer.from(body.toString(), 'base64'); - } - } - - // 5.9. If position does not point to a sequence of bytes starting with - // 0x0D 0x0A (CR LF), return failure. Otherwise, advance position by 2. - if (input[position.position] !== 0x0d || input[position.position + 1] !== 0x0a) { - return 'failure' - } else { - position.position += 2; - } - - // 5.10. If filename is not null: - let value; - - if (filename !== null) { - // 5.10.1. If contentType is null, set contentType to "text/plain". - contentType ??= 'text/plain'; - - // 5.10.2. If contentType is not an ASCII string, set contentType to the empty string. - - // Note: `buffer.isAscii` can be used at zero-cost, but converting a string to a buffer is a high overhead. - // Content-Type is a relatively small string, so it is faster to use `String#charCodeAt`. - if (!isAsciiString(contentType)) { - contentType = ''; - } - - // 5.10.3. Let value be a new File object with name filename, type contentType, and body body. - value = new File([body], filename, { type: contentType }); - } else { - // 5.11. Otherwise: - - // 5.11.1. Let value be the UTF-8 decoding without BOM of body. - value = utf8DecodeBytes(Buffer.from(body)); - } - - // 5.12. Assert: name is a scalar value string and value is either a scalar value string or a File object. - assert(isUSVString(name)); - assert((typeof value === 'string' && isUSVString(value)) || isFileLike(value)); - - // 5.13. Create an entry with name and value, and append it to entry list. - entryList.push(makeEntry(name, value, filename)); - } - } - - /** - * @see https://andreubotella.github.io/multipart-form-data/#parse-multipart-form-data-headers - * @param {Buffer} input - * @param {{ position: number }} position - */ - function parseMultipartFormDataHeaders (input, position) { - // 1. Let name, filename and contentType be null. - let name = null; - let filename = null; - let contentType = null; - let encoding = null; - - // 2. While true: - while (true) { - // 2.1. If position points to a sequence of bytes starting with 0x0D 0x0A (CR LF): - if (input[position.position] === 0x0d && input[position.position + 1] === 0x0a) { - // 2.1.1. If name is null, return failure. - if (name === null) { - return 'failure' - } - - // 2.1.2. Return name, filename and contentType. - return { name, filename, contentType, encoding } - } - - // 2.2. Let header name be the result of collecting a sequence of bytes that are - // not 0x0A (LF), 0x0D (CR) or 0x3A (:), given position. - let headerName = collectASequenceOfBytes( - (char) => char !== 0x0a && char !== 0x0d && char !== 0x3a, - input, - position - ); - - // 2.3. Remove any HTTP tab or space bytes from the start or end of header name. - headerName = removeChars(headerName, true, true, (char) => char === 0x9 || char === 0x20); - - // 2.4. If header name does not match the field-name token production, return failure. - if (!HTTP_TOKEN_CODEPOINTS.test(headerName.toString())) { - return 'failure' - } - - // 2.5. If the byte at position is not 0x3A (:), return failure. - if (input[position.position] !== 0x3a) { - return 'failure' - } - - // 2.6. Advance position by 1. - position.position++; - - // 2.7. Collect a sequence of bytes that are HTTP tab or space bytes given position. - // (Do nothing with those bytes.) - collectASequenceOfBytes( - (char) => char === 0x20 || char === 0x09, - input, - position - ); - - // 2.8. Byte-lowercase header name and switch on the result: - switch (bufferToLowerCasedHeaderName(headerName)) { - case 'content-disposition': { - // 1. Set name and filename to null. - name = filename = null; - - // 2. If position does not point to a sequence of bytes starting with - // `form-data; name="`, return failure. - if (!bufferStartsWith(input, formDataNameBuffer, position)) { - return 'failure' - } - - // 3. Advance position so it points at the byte after the next 0x22 (") - // byte (the one in the sequence of bytes matched above). - position.position += 17; - - // 4. Set name to the result of parsing a multipart/form-data name given - // input and position, if the result is not failure. Otherwise, return - // failure. - name = parseMultipartFormDataName(input, position); - - if (name === null) { - return 'failure' - } - - // 5. If position points to a sequence of bytes starting with `; filename="`: - if (bufferStartsWith(input, filenameBuffer, position)) { - // Note: undici also handles filename* - let check = position.position + filenameBuffer.length; - - if (input[check] === 0x2a) { - position.position += 1; - check += 1; - } - - if (input[check] !== 0x3d || input[check + 1] !== 0x22) { // =" - return 'failure' - } - - // 1. Advance position so it points at the byte after the next 0x22 (") byte - // (the one in the sequence of bytes matched above). - position.position += 12; - - // 2. Set filename to the result of parsing a multipart/form-data name given - // input and position, if the result is not failure. Otherwise, return failure. - filename = parseMultipartFormDataName(input, position); - - if (filename === null) { - return 'failure' - } - } - - break - } - case 'content-type': { - // 1. Let header value be the result of collecting a sequence of bytes that are - // not 0x0A (LF) or 0x0D (CR), given position. - let headerValue = collectASequenceOfBytes( - (char) => char !== 0x0a && char !== 0x0d, - input, - position - ); - - // 2. Remove any HTTP tab or space bytes from the end of header value. - headerValue = removeChars(headerValue, false, true, (char) => char === 0x9 || char === 0x20); - - // 3. Set contentType to the isomorphic decoding of header value. - contentType = isomorphicDecode(headerValue); - - break - } - case 'content-transfer-encoding': { - let headerValue = collectASequenceOfBytes( - (char) => char !== 0x0a && char !== 0x0d, - input, - position - ); - - headerValue = removeChars(headerValue, false, true, (char) => char === 0x9 || char === 0x20); - - encoding = isomorphicDecode(headerValue); - - break - } - default: { - // Collect a sequence of bytes that are not 0x0A (LF) or 0x0D (CR), given position. - // (Do nothing with those bytes.) - collectASequenceOfBytes( - (char) => char !== 0x0a && char !== 0x0d, - input, - position - ); - } - } - - // 2.9. If position does not point to a sequence of bytes starting with 0x0D 0x0A - // (CR LF), return failure. Otherwise, advance position by 2 (past the newline). - if (input[position.position] !== 0x0d && input[position.position + 1] !== 0x0a) { - return 'failure' - } else { - position.position += 2; - } - } - } - - /** - * @see https://andreubotella.github.io/multipart-form-data/#parse-a-multipart-form-data-name - * @param {Buffer} input - * @param {{ position: number }} position - */ - function parseMultipartFormDataName (input, position) { - // 1. Assert: The byte at (position - 1) is 0x22 ("). - assert(input[position.position - 1] === 0x22); - - // 2. Let name be the result of collecting a sequence of bytes that are not 0x0A (LF), 0x0D (CR) or 0x22 ("), given position. - /** @type {string | Buffer} */ - let name = collectASequenceOfBytes( - (char) => char !== 0x0a && char !== 0x0d && char !== 0x22, - input, - position - ); - - // 3. If the byte at position is not 0x22 ("), return failure. Otherwise, advance position by 1. - if (input[position.position] !== 0x22) { - return null // name could be 'failure' - } else { - position.position++; - } - - // 4. Replace any occurrence of the following subsequences in name with the given byte: - // - `%0A`: 0x0A (LF) - // - `%0D`: 0x0D (CR) - // - `%22`: 0x22 (") - name = new TextDecoder().decode(name) - .replace(/%0A/ig, '\n') - .replace(/%0D/ig, '\r') - .replace(/%22/g, '"'); - - // 5. Return the UTF-8 decoding without BOM of name. - return name - } - - /** - * @param {(char: number) => boolean} condition - * @param {Buffer} input - * @param {{ position: number }} position - */ - function collectASequenceOfBytes (condition, input, position) { - let start = position.position; - - while (start < input.length && condition(input[start])) { - ++start; - } - - return input.subarray(position.position, (position.position = start)) - } - - /** - * @param {Buffer} buf - * @param {boolean} leading - * @param {boolean} trailing - * @param {(charCode: number) => boolean} predicate - * @returns {Buffer} - */ - function removeChars (buf, leading, trailing, predicate) { - let lead = 0; - let trail = buf.length - 1; - - if (leading) { - while (lead < buf.length && predicate(buf[lead])) lead++; - } - - { - while (trail > 0 && predicate(buf[trail])) trail--; - } - - return lead === 0 && trail === buf.length - 1 ? buf : buf.subarray(lead, trail + 1) - } - - /** - * Checks if {@param buffer} starts with {@param start} - * @param {Buffer} buffer - * @param {Buffer} start - * @param {{ position: number }} position - */ - function bufferStartsWith (buffer, start, position) { - if (buffer.length < start.length) { - return false - } - - for (let i = 0; i < start.length; i++) { - if (start[i] !== buffer[position.position + i]) { - return false - } - } - - return true - } - - formdataParser = { - multipartFormDataParser, - validateBoundary - }; - return formdataParser; -} - -var body; -var hasRequiredBody; - -function requireBody () { - if (hasRequiredBody) return body; - hasRequiredBody = 1; - - const util = requireUtil$7(); - const { - ReadableStreamFrom, - isBlobLike, - isReadableStreamLike, - readableStreamClose, - createDeferredPromise, - fullyReadBody, - extractMimeType, - utf8DecodeBytes - } = requireUtil$6(); - const { FormData } = requireFormdata(); - const { kState } = requireSymbols$3(); - const { webidl } = requireWebidl(); - const { Blob } = require$$0$3; - const assert = require$$0$4; - const { isErrored } = requireUtil$7(); - const { isArrayBuffer } = require$$8$1; - const { serializeAMimeType } = requireDataUrl(); - const { multipartFormDataParser } = requireFormdataParser(); - - const textEncoder = new TextEncoder(); - - // https://fetch.spec.whatwg.org/#concept-bodyinit-extract - function extractBody (object, keepalive = false) { - // 1. Let stream be null. - let stream = null; - - // 2. If object is a ReadableStream object, then set stream to object. - if (object instanceof ReadableStream) { - stream = object; - } else if (isBlobLike(object)) { - // 3. Otherwise, if object is a Blob object, set stream to the - // result of running object’s get stream. - stream = object.stream(); - } else { - // 4. Otherwise, set stream to a new ReadableStream object, and set - // up stream with byte reading support. - stream = new ReadableStream({ - async pull (controller) { - const buffer = typeof source === 'string' ? textEncoder.encode(source) : source; - - if (buffer.byteLength) { - controller.enqueue(buffer); - } - - queueMicrotask(() => readableStreamClose(controller)); - }, - start () {}, - type: 'bytes' - }); - } - - // 5. Assert: stream is a ReadableStream object. - assert(isReadableStreamLike(stream)); - - // 6. Let action be null. - let action = null; - - // 7. Let source be null. - let source = null; - - // 8. Let length be null. - let length = null; - - // 9. Let type be null. - let type = null; - - // 10. Switch on object: - if (typeof object === 'string') { - // Set source to the UTF-8 encoding of object. - // Note: setting source to a Uint8Array here breaks some mocking assumptions. - source = object; - - // Set type to `text/plain;charset=UTF-8`. - type = 'text/plain;charset=UTF-8'; - } else if (object instanceof URLSearchParams) { - // URLSearchParams - - // spec says to run application/x-www-form-urlencoded on body.list - // this is implemented in Node.js as apart of an URLSearchParams instance toString method - // See: https://github.com/nodejs/node/blob/e46c680bf2b211bbd52cf959ca17ee98c7f657f5/lib/internal/url.js#L490 - // and https://github.com/nodejs/node/blob/e46c680bf2b211bbd52cf959ca17ee98c7f657f5/lib/internal/url.js#L1100 - - // Set source to the result of running the application/x-www-form-urlencoded serializer with object’s list. - source = object.toString(); - - // Set type to `application/x-www-form-urlencoded;charset=UTF-8`. - type = 'application/x-www-form-urlencoded;charset=UTF-8'; - } else if (isArrayBuffer(object)) { - // BufferSource/ArrayBuffer - - // Set source to a copy of the bytes held by object. - source = new Uint8Array(object.slice()); - } else if (ArrayBuffer.isView(object)) { - // BufferSource/ArrayBufferView - - // Set source to a copy of the bytes held by object. - source = new Uint8Array(object.buffer.slice(object.byteOffset, object.byteOffset + object.byteLength)); - } else if (util.isFormDataLike(object)) { - const boundary = `----formdata-undici-0${`${Math.floor(Math.random() * 1e11)}`.padStart(11, '0')}`; - const prefix = `--${boundary}\r\nContent-Disposition: form-data`; - - /*! formdata-polyfill. MIT License. Jimmy Wärting */ - const escape = (str) => - str.replace(/\n/g, '%0A').replace(/\r/g, '%0D').replace(/"/g, '%22'); - const normalizeLinefeeds = (value) => value.replace(/\r?\n|\r/g, '\r\n'); - - // Set action to this step: run the multipart/form-data - // encoding algorithm, with object’s entry list and UTF-8. - // - This ensures that the body is immutable and can't be changed afterwords - // - That the content-length is calculated in advance. - // - And that all parts are pre-encoded and ready to be sent. - - const blobParts = []; - const rn = new Uint8Array([13, 10]); // '\r\n' - length = 0; - let hasUnknownSizeValue = false; - - for (const [name, value] of object) { - if (typeof value === 'string') { - const chunk = textEncoder.encode(prefix + - `; name="${escape(normalizeLinefeeds(name))}"` + - `\r\n\r\n${normalizeLinefeeds(value)}\r\n`); - blobParts.push(chunk); - length += chunk.byteLength; - } else { - const chunk = textEncoder.encode(`${prefix}; name="${escape(normalizeLinefeeds(name))}"` + - (value.name ? `; filename="${escape(value.name)}"` : '') + '\r\n' + - `Content-Type: ${ - value.type || 'application/octet-stream' - }\r\n\r\n`); - blobParts.push(chunk, value, rn); - if (typeof value.size === 'number') { - length += chunk.byteLength + value.size + rn.byteLength; - } else { - hasUnknownSizeValue = true; - } - } - } - - const chunk = textEncoder.encode(`--${boundary}--`); - blobParts.push(chunk); - length += chunk.byteLength; - if (hasUnknownSizeValue) { - length = null; - } - - // Set source to object. - source = object; - - action = async function * () { - for (const part of blobParts) { - if (part.stream) { - yield * part.stream(); - } else { - yield part; - } - } - }; - - // Set type to `multipart/form-data; boundary=`, - // followed by the multipart/form-data boundary string generated - // by the multipart/form-data encoding algorithm. - type = `multipart/form-data; boundary=${boundary}`; - } else if (isBlobLike(object)) { - // Blob - - // Set source to object. - source = object; - - // Set length to object’s size. - length = object.size; - - // If object’s type attribute is not the empty byte sequence, set - // type to its value. - if (object.type) { - type = object.type; - } - } else if (typeof object[Symbol.asyncIterator] === 'function') { - // If keepalive is true, then throw a TypeError. - if (keepalive) { - throw new TypeError('keepalive') - } - - // If object is disturbed or locked, then throw a TypeError. - if (util.isDisturbed(object) || object.locked) { - throw new TypeError( - 'Response body object should not be disturbed or locked' - ) - } - - stream = - object instanceof ReadableStream ? object : ReadableStreamFrom(object); - } - - // 11. If source is a byte sequence, then set action to a - // step that returns source and length to source’s length. - if (typeof source === 'string' || util.isBuffer(source)) { - length = Buffer.byteLength(source); - } - - // 12. If action is non-null, then run these steps in in parallel: - if (action != null) { - // Run action. - let iterator; - stream = new ReadableStream({ - async start () { - iterator = action(object)[Symbol.asyncIterator](); - }, - async pull (controller) { - const { value, done } = await iterator.next(); - if (done) { - // When running action is done, close stream. - queueMicrotask(() => { - controller.close(); - controller.byobRequest?.respond(0); - }); - } else { - // Whenever one or more bytes are available and stream is not errored, - // enqueue a Uint8Array wrapping an ArrayBuffer containing the available - // bytes into stream. - if (!isErrored(stream)) { - const buffer = new Uint8Array(value); - if (buffer.byteLength) { - controller.enqueue(buffer); - } - } - } - return controller.desiredSize > 0 - }, - async cancel (reason) { - await iterator.return(); - }, - type: 'bytes' - }); - } - - // 13. Let body be a body whose stream is stream, source is source, - // and length is length. - const body = { stream, source, length }; - - // 14. Return (body, type). - return [body, type] - } - - // https://fetch.spec.whatwg.org/#bodyinit-safely-extract - function safelyExtractBody (object, keepalive = false) { - // To safely extract a body and a `Content-Type` value from - // a byte sequence or BodyInit object object, run these steps: - - // 1. If object is a ReadableStream object, then: - if (object instanceof ReadableStream) { - // Assert: object is neither disturbed nor locked. - // istanbul ignore next - assert(!util.isDisturbed(object), 'The body has already been consumed.'); - // istanbul ignore next - assert(!object.locked, 'The stream is locked.'); - } - - // 2. Return the results of extracting object. - return extractBody(object, keepalive) - } - - function cloneBody (body) { - // To clone a body body, run these steps: - - // https://fetch.spec.whatwg.org/#concept-body-clone - - // 1. Let « out1, out2 » be the result of teeing body’s stream. - const [out1, out2] = body.stream.tee(); - - // 2. Set body’s stream to out1. - body.stream = out1; - - // 3. Return a body whose stream is out2 and other members are copied from body. - return { - stream: out2, - length: body.length, - source: body.source - } - } - - function throwIfAborted (state) { - if (state.aborted) { - throw new DOMException('The operation was aborted.', 'AbortError') - } - } - - function bodyMixinMethods (instance) { - const methods = { - blob () { - // The blob() method steps are to return the result of - // running consume body with this and the following step - // given a byte sequence bytes: return a Blob whose - // contents are bytes and whose type attribute is this’s - // MIME type. - return consumeBody(this, (bytes) => { - let mimeType = bodyMimeType(this); - - if (mimeType === null) { - mimeType = ''; - } else if (mimeType) { - mimeType = serializeAMimeType(mimeType); - } - - // Return a Blob whose contents are bytes and type attribute - // is mimeType. - return new Blob([bytes], { type: mimeType }) - }, instance, false) - }, - - arrayBuffer () { - // The arrayBuffer() method steps are to return the result - // of running consume body with this and the following step - // given a byte sequence bytes: return a new ArrayBuffer - // whose contents are bytes. - return consumeBody(this, (bytes) => { - // Note: arrayBuffer already cloned. - return bytes.buffer - }, instance, true) - }, - - text () { - // The text() method steps are to return the result of running - // consume body with this and UTF-8 decode. - return consumeBody(this, utf8DecodeBytes, instance, false) - }, - - json () { - // The json() method steps are to return the result of running - // consume body with this and parse JSON from bytes. - return consumeBody(this, parseJSONFromBytes, instance, false) - }, - - formData () { - // The formData() method steps are to return the result of running - // consume body with this and the following step given a byte sequence bytes: - return consumeBody(this, (value) => { - // 1. Let mimeType be the result of get the MIME type with this. - const mimeType = bodyMimeType(this); - - // 2. If mimeType is non-null, then switch on mimeType’s essence and run - // the corresponding steps: - if (mimeType !== null) { - switch (mimeType.essence) { - case 'multipart/form-data': { - // 1. ... [long step] - const parsed = multipartFormDataParser(value, mimeType); - - // 2. If that fails for some reason, then throw a TypeError. - if (parsed === 'failure') { - throw new TypeError('Failed to parse body as FormData.') - } - - // 3. Return a new FormData object, appending each entry, - // resulting from the parsing operation, to its entry list. - const fd = new FormData(); - fd[kState] = parsed; - - return fd - } - case 'application/x-www-form-urlencoded': { - // 1. Let entries be the result of parsing bytes. - const entries = new URLSearchParams(value.toString()); - - // 2. If entries is failure, then throw a TypeError. - - // 3. Return a new FormData object whose entry list is entries. - const fd = new FormData(); - - for (const [name, value] of entries) { - fd.append(name, value); - } - - return fd - } - } - } - - // 3. Throw a TypeError. - throw new TypeError( - 'Content-Type was not one of "multipart/form-data" or "application/x-www-form-urlencoded".' - ) - }, instance, false) - }, - - bytes () { - // The bytes() method steps are to return the result of running consume body - // with this and the following step given a byte sequence bytes: return the - // result of creating a Uint8Array from bytes in this’s relevant realm. - return consumeBody(this, (bytes) => { - return new Uint8Array(bytes.buffer, 0, bytes.byteLength) - }, instance, true) - } - }; - - return methods - } - - function mixinBody (prototype) { - Object.assign(prototype.prototype, bodyMixinMethods(prototype)); - } - - /** - * @see https://fetch.spec.whatwg.org/#concept-body-consume-body - * @param {Response|Request} object - * @param {(value: unknown) => unknown} convertBytesToJSValue - * @param {Response|Request} instance - * @param {boolean} [shouldClone] - */ - async function consumeBody (object, convertBytesToJSValue, instance, shouldClone) { - webidl.brandCheck(object, instance); - - // 1. If object is unusable, then return a promise rejected - // with a TypeError. - if (bodyUnusable(object[kState].body)) { - throw new TypeError('Body is unusable: Body has already been read') - } - - throwIfAborted(object[kState]); - - // 2. Let promise be a new promise. - const promise = createDeferredPromise(); - - // 3. Let errorSteps given error be to reject promise with error. - const errorSteps = (error) => promise.reject(error); - - // 4. Let successSteps given a byte sequence data be to resolve - // promise with the result of running convertBytesToJSValue - // with data. If that threw an exception, then run errorSteps - // with that exception. - const successSteps = (data) => { - try { - promise.resolve(convertBytesToJSValue(data)); - } catch (e) { - errorSteps(e); - } - }; - - // 5. If object’s body is null, then run successSteps with an - // empty byte sequence. - if (object[kState].body == null) { - successSteps(Buffer.allocUnsafe(0)); - return promise.promise - } - - // 6. Otherwise, fully read object’s body given successSteps, - // errorSteps, and object’s relevant global object. - await fullyReadBody(object[kState].body, successSteps, errorSteps, shouldClone); - - // 7. Return promise. - return promise.promise - } - - // https://fetch.spec.whatwg.org/#body-unusable - function bodyUnusable (body) { - // An object including the Body interface mixin is - // said to be unusable if its body is non-null and - // its body’s stream is disturbed or locked. - return body != null && (body.stream.locked || util.isDisturbed(body.stream)) - } - - /** - * @see https://infra.spec.whatwg.org/#parse-json-bytes-to-a-javascript-value - * @param {Uint8Array} bytes - */ - function parseJSONFromBytes (bytes) { - return JSON.parse(utf8DecodeBytes(bytes)) - } - - /** - * @see https://fetch.spec.whatwg.org/#concept-body-mime-type - * @param {import('./response').Response|import('./request').Request} requestOrResponse - */ - function bodyMimeType (requestOrResponse) { - // 1. Let headers be null. - // 2. If requestOrResponse is a Request object, then set headers to requestOrResponse’s request’s header list. - // 3. Otherwise, set headers to requestOrResponse’s response’s header list. - /** @type {import('./headers').HeadersList} */ - const headers = requestOrResponse[kState].headersList; - - // 4. Let mimeType be the result of extracting a MIME type from headers. - const mimeType = extractMimeType(headers); - - // 5. If mimeType is failure, then return null. - if (mimeType === 'failure') { - return null - } - - // 6. Return mimeType. - return mimeType - } - - body = { - extractBody, - safelyExtractBody, - cloneBody, - mixinBody - }; - return body; -} - -var clientH1; -var hasRequiredClientH1; - -function requireClientH1 () { - if (hasRequiredClientH1) return clientH1; - hasRequiredClientH1 = 1; - - /* global WebAssembly */ - - const assert = require$$0$4; - const util = requireUtil$7(); - const { channels } = requireDiagnostics(); - const timers = requireTimers(); - const { - RequestContentLengthMismatchError, - ResponseContentLengthMismatchError, - RequestAbortedError, - HeadersTimeoutError, - HeadersOverflowError, - SocketError, - InformationalError, - BodyTimeoutError, - HTTPParserError, - ResponseExceededMaxSizeError - } = requireErrors(); - const { - kUrl, - kReset, - kClient, - kParser, - kBlocking, - kRunning, - kPending, - kSize, - kWriting, - kQueue, - kNoRef, - kKeepAliveDefaultTimeout, - kHostHeader, - kPendingIdx, - kRunningIdx, - kError, - kPipelining, - kSocket, - kKeepAliveTimeoutValue, - kMaxHeadersSize, - kKeepAliveMaxTimeout, - kKeepAliveTimeoutThreshold, - kHeadersTimeout, - kBodyTimeout, - kStrictContentLength, - kMaxRequests, - kCounter, - kMaxResponseSize, - kOnError, - kResume, - kHTTPContext - } = requireSymbols$4(); - - const constants = requireConstants$3(); - const EMPTY_BUF = Buffer.alloc(0); - const FastBuffer = Buffer[Symbol.species]; - const addListener = util.addListener; - const removeAllListeners = util.removeAllListeners; - - let extractBody; - - async function lazyllhttp () { - const llhttpWasmData = process.env.JEST_WORKER_ID ? requireLlhttpWasm() : undefined; - - let mod; - try { - mod = await WebAssembly.compile(requireLlhttp_simdWasm()); - } catch (e) { - /* istanbul ignore next */ - - // We could check if the error was caused by the simd option not - // being enabled, but the occurring of this other error - // * https://github.com/emscripten-core/emscripten/issues/11495 - // got me to remove that check to avoid breaking Node 12. - mod = await WebAssembly.compile(llhttpWasmData || requireLlhttpWasm()); - } - - return await WebAssembly.instantiate(mod, { - env: { - /* eslint-disable camelcase */ - - wasm_on_url: (p, at, len) => { - /* istanbul ignore next */ - return 0 - }, - wasm_on_status: (p, at, len) => { - assert.strictEqual(currentParser.ptr, p); - const start = at - currentBufferPtr + currentBufferRef.byteOffset; - return currentParser.onStatus(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 - }, - wasm_on_message_begin: (p) => { - assert.strictEqual(currentParser.ptr, p); - return currentParser.onMessageBegin() || 0 - }, - wasm_on_header_field: (p, at, len) => { - assert.strictEqual(currentParser.ptr, p); - const start = at - currentBufferPtr + currentBufferRef.byteOffset; - return currentParser.onHeaderField(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 - }, - wasm_on_header_value: (p, at, len) => { - assert.strictEqual(currentParser.ptr, p); - const start = at - currentBufferPtr + currentBufferRef.byteOffset; - return currentParser.onHeaderValue(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 - }, - wasm_on_headers_complete: (p, statusCode, upgrade, shouldKeepAlive) => { - assert.strictEqual(currentParser.ptr, p); - return currentParser.onHeadersComplete(statusCode, Boolean(upgrade), Boolean(shouldKeepAlive)) || 0 - }, - wasm_on_body: (p, at, len) => { - assert.strictEqual(currentParser.ptr, p); - const start = at - currentBufferPtr + currentBufferRef.byteOffset; - return currentParser.onBody(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 - }, - wasm_on_message_complete: (p) => { - assert.strictEqual(currentParser.ptr, p); - return currentParser.onMessageComplete() || 0 - } - - /* eslint-enable camelcase */ - } - }) - } - - let llhttpInstance = null; - let llhttpPromise = lazyllhttp(); - llhttpPromise.catch(); - - let currentParser = null; - let currentBufferRef = null; - let currentBufferSize = 0; - let currentBufferPtr = null; - - const TIMEOUT_HEADERS = 1; - const TIMEOUT_BODY = 2; - const TIMEOUT_IDLE = 3; - - class Parser { - constructor (client, socket, { exports }) { - assert(Number.isFinite(client[kMaxHeadersSize]) && client[kMaxHeadersSize] > 0); - - this.llhttp = exports; - this.ptr = this.llhttp.llhttp_alloc(constants.TYPE.RESPONSE); - this.client = client; - this.socket = socket; - this.timeout = null; - this.timeoutValue = null; - this.timeoutType = null; - this.statusCode = null; - this.statusText = ''; - this.upgrade = false; - this.headers = []; - this.headersSize = 0; - this.headersMaxSize = client[kMaxHeadersSize]; - this.shouldKeepAlive = false; - this.paused = false; - this.resume = this.resume.bind(this); - - this.bytesRead = 0; - - this.keepAlive = ''; - this.contentLength = ''; - this.connection = ''; - this.maxResponseSize = client[kMaxResponseSize]; - } - - setTimeout (value, type) { - this.timeoutType = type; - if (value !== this.timeoutValue) { - timers.clearTimeout(this.timeout); - if (value) { - this.timeout = timers.setTimeout(onParserTimeout, value, this); - // istanbul ignore else: only for jest - if (this.timeout.unref) { - this.timeout.unref(); - } - } else { - this.timeout = null; - } - this.timeoutValue = value; - } else if (this.timeout) { - // istanbul ignore else: only for jest - if (this.timeout.refresh) { - this.timeout.refresh(); - } - } - } - - resume () { - if (this.socket.destroyed || !this.paused) { - return - } - - assert(this.ptr != null); - assert(currentParser == null); - - this.llhttp.llhttp_resume(this.ptr); - - assert(this.timeoutType === TIMEOUT_BODY); - if (this.timeout) { - // istanbul ignore else: only for jest - if (this.timeout.refresh) { - this.timeout.refresh(); - } - } - - this.paused = false; - this.execute(this.socket.read() || EMPTY_BUF); // Flush parser. - this.readMore(); - } - - readMore () { - while (!this.paused && this.ptr) { - const chunk = this.socket.read(); - if (chunk === null) { - break - } - this.execute(chunk); - } - } - - execute (data) { - assert(this.ptr != null); - assert(currentParser == null); - assert(!this.paused); - - const { socket, llhttp } = this; - - if (data.length > currentBufferSize) { - if (currentBufferPtr) { - llhttp.free(currentBufferPtr); - } - currentBufferSize = Math.ceil(data.length / 4096) * 4096; - currentBufferPtr = llhttp.malloc(currentBufferSize); - } - - new Uint8Array(llhttp.memory.buffer, currentBufferPtr, currentBufferSize).set(data); - - // Call `execute` on the wasm parser. - // We pass the `llhttp_parser` pointer address, the pointer address of buffer view data, - // and finally the length of bytes to parse. - // The return value is an error code or `constants.ERROR.OK`. - try { - let ret; - - try { - currentBufferRef = data; - currentParser = this; - ret = llhttp.llhttp_execute(this.ptr, currentBufferPtr, data.length); - /* eslint-disable-next-line no-useless-catch */ - } catch (err) { - /* istanbul ignore next: difficult to make a test case for */ - throw err - } finally { - currentParser = null; - currentBufferRef = null; - } - - const offset = llhttp.llhttp_get_error_pos(this.ptr) - currentBufferPtr; - - if (ret === constants.ERROR.PAUSED_UPGRADE) { - this.onUpgrade(data.slice(offset)); - } else if (ret === constants.ERROR.PAUSED) { - this.paused = true; - socket.unshift(data.slice(offset)); - } else if (ret !== constants.ERROR.OK) { - const ptr = llhttp.llhttp_get_error_reason(this.ptr); - let message = ''; - /* istanbul ignore else: difficult to make a test case for */ - if (ptr) { - const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0); - message = - 'Response does not match the HTTP/1.1 protocol (' + - Buffer.from(llhttp.memory.buffer, ptr, len).toString() + - ')'; - } - throw new HTTPParserError(message, constants.ERROR[ret], data.slice(offset)) - } - } catch (err) { - util.destroy(socket, err); - } - } - - destroy () { - assert(this.ptr != null); - assert(currentParser == null); - - this.llhttp.llhttp_free(this.ptr); - this.ptr = null; - - timers.clearTimeout(this.timeout); - this.timeout = null; - this.timeoutValue = null; - this.timeoutType = null; - - this.paused = false; - } - - onStatus (buf) { - this.statusText = buf.toString(); - } - - onMessageBegin () { - const { socket, client } = this; - - /* istanbul ignore next: difficult to make a test case for */ - if (socket.destroyed) { - return -1 - } - - const request = client[kQueue][client[kRunningIdx]]; - if (!request) { - return -1 - } - request.onResponseStarted(); - } - - onHeaderField (buf) { - const len = this.headers.length; - - if ((len & 1) === 0) { - this.headers.push(buf); - } else { - this.headers[len - 1] = Buffer.concat([this.headers[len - 1], buf]); - } - - this.trackHeader(buf.length); - } - - onHeaderValue (buf) { - let len = this.headers.length; - - if ((len & 1) === 1) { - this.headers.push(buf); - len += 1; - } else { - this.headers[len - 1] = Buffer.concat([this.headers[len - 1], buf]); - } - - const key = this.headers[len - 2]; - if (key.length === 10) { - const headerName = util.bufferToLowerCasedHeaderName(key); - if (headerName === 'keep-alive') { - this.keepAlive += buf.toString(); - } else if (headerName === 'connection') { - this.connection += buf.toString(); - } - } else if (key.length === 14 && util.bufferToLowerCasedHeaderName(key) === 'content-length') { - this.contentLength += buf.toString(); - } - - this.trackHeader(buf.length); - } - - trackHeader (len) { - this.headersSize += len; - if (this.headersSize >= this.headersMaxSize) { - util.destroy(this.socket, new HeadersOverflowError()); - } - } - - onUpgrade (head) { - const { upgrade, client, socket, headers, statusCode } = this; - - assert(upgrade); - - const request = client[kQueue][client[kRunningIdx]]; - assert(request); - - assert(!socket.destroyed); - assert(socket === client[kSocket]); - assert(!this.paused); - assert(request.upgrade || request.method === 'CONNECT'); - - this.statusCode = null; - this.statusText = ''; - this.shouldKeepAlive = null; - - assert(this.headers.length % 2 === 0); - this.headers = []; - this.headersSize = 0; - - socket.unshift(head); - - socket[kParser].destroy(); - socket[kParser] = null; - - socket[kClient] = null; - socket[kError] = null; - - removeAllListeners(socket); - - client[kSocket] = null; - client[kHTTPContext] = null; // TODO (fix): This is hacky... - client[kQueue][client[kRunningIdx]++] = null; - client.emit('disconnect', client[kUrl], [client], new InformationalError('upgrade')); - - try { - request.onUpgrade(statusCode, headers, socket); - } catch (err) { - util.destroy(socket, err); - } - - client[kResume](); - } - - onHeadersComplete (statusCode, upgrade, shouldKeepAlive) { - const { client, socket, headers, statusText } = this; - - /* istanbul ignore next: difficult to make a test case for */ - if (socket.destroyed) { - return -1 - } - - const request = client[kQueue][client[kRunningIdx]]; - - /* istanbul ignore next: difficult to make a test case for */ - if (!request) { - return -1 - } - - assert(!this.upgrade); - assert(this.statusCode < 200); - - if (statusCode === 100) { - util.destroy(socket, new SocketError('bad response', util.getSocketInfo(socket))); - return -1 - } - - /* this can only happen if server is misbehaving */ - if (upgrade && !request.upgrade) { - util.destroy(socket, new SocketError('bad upgrade', util.getSocketInfo(socket))); - return -1 - } - - assert.strictEqual(this.timeoutType, TIMEOUT_HEADERS); - - this.statusCode = statusCode; - this.shouldKeepAlive = ( - shouldKeepAlive || - // Override llhttp value which does not allow keepAlive for HEAD. - (request.method === 'HEAD' && !socket[kReset] && this.connection.toLowerCase() === 'keep-alive') - ); - - if (this.statusCode >= 200) { - const bodyTimeout = request.bodyTimeout != null - ? request.bodyTimeout - : client[kBodyTimeout]; - this.setTimeout(bodyTimeout, TIMEOUT_BODY); - } else if (this.timeout) { - // istanbul ignore else: only for jest - if (this.timeout.refresh) { - this.timeout.refresh(); - } - } - - if (request.method === 'CONNECT') { - assert(client[kRunning] === 1); - this.upgrade = true; - return 2 - } - - if (upgrade) { - assert(client[kRunning] === 1); - this.upgrade = true; - return 2 - } - - assert(this.headers.length % 2 === 0); - this.headers = []; - this.headersSize = 0; - - if (this.shouldKeepAlive && client[kPipelining]) { - const keepAliveTimeout = this.keepAlive ? util.parseKeepAliveTimeout(this.keepAlive) : null; - - if (keepAliveTimeout != null) { - const timeout = Math.min( - keepAliveTimeout - client[kKeepAliveTimeoutThreshold], - client[kKeepAliveMaxTimeout] - ); - if (timeout <= 0) { - socket[kReset] = true; - } else { - client[kKeepAliveTimeoutValue] = timeout; - } - } else { - client[kKeepAliveTimeoutValue] = client[kKeepAliveDefaultTimeout]; - } - } else { - // Stop more requests from being dispatched. - socket[kReset] = true; - } - - const pause = request.onHeaders(statusCode, headers, this.resume, statusText) === false; - - if (request.aborted) { - return -1 - } - - if (request.method === 'HEAD') { - return 1 - } - - if (statusCode < 200) { - return 1 - } - - if (socket[kBlocking]) { - socket[kBlocking] = false; - client[kResume](); - } - - return pause ? constants.ERROR.PAUSED : 0 - } - - onBody (buf) { - const { client, socket, statusCode, maxResponseSize } = this; - - if (socket.destroyed) { - return -1 - } - - const request = client[kQueue][client[kRunningIdx]]; - assert(request); - - assert.strictEqual(this.timeoutType, TIMEOUT_BODY); - if (this.timeout) { - // istanbul ignore else: only for jest - if (this.timeout.refresh) { - this.timeout.refresh(); - } - } - - assert(statusCode >= 200); - - if (maxResponseSize > -1 && this.bytesRead + buf.length > maxResponseSize) { - util.destroy(socket, new ResponseExceededMaxSizeError()); - return -1 - } - - this.bytesRead += buf.length; - - if (request.onData(buf) === false) { - return constants.ERROR.PAUSED - } - } - - onMessageComplete () { - const { client, socket, statusCode, upgrade, headers, contentLength, bytesRead, shouldKeepAlive } = this; - - if (socket.destroyed && (!statusCode || shouldKeepAlive)) { - return -1 - } - - if (upgrade) { - return - } - - const request = client[kQueue][client[kRunningIdx]]; - assert(request); - - assert(statusCode >= 100); - - this.statusCode = null; - this.statusText = ''; - this.bytesRead = 0; - this.contentLength = ''; - this.keepAlive = ''; - this.connection = ''; - - assert(this.headers.length % 2 === 0); - this.headers = []; - this.headersSize = 0; - - if (statusCode < 200) { - return - } - - /* istanbul ignore next: should be handled by llhttp? */ - if (request.method !== 'HEAD' && contentLength && bytesRead !== parseInt(contentLength, 10)) { - util.destroy(socket, new ResponseContentLengthMismatchError()); - return -1 - } - - request.onComplete(headers); - - client[kQueue][client[kRunningIdx]++] = null; - - if (socket[kWriting]) { - assert.strictEqual(client[kRunning], 0); - // Response completed before request. - util.destroy(socket, new InformationalError('reset')); - return constants.ERROR.PAUSED - } else if (!shouldKeepAlive) { - util.destroy(socket, new InformationalError('reset')); - return constants.ERROR.PAUSED - } else if (socket[kReset] && client[kRunning] === 0) { - // Destroy socket once all requests have completed. - // The request at the tail of the pipeline is the one - // that requested reset and no further requests should - // have been queued since then. - util.destroy(socket, new InformationalError('reset')); - return constants.ERROR.PAUSED - } else if (client[kPipelining] == null || client[kPipelining] === 1) { - // We must wait a full event loop cycle to reuse this socket to make sure - // that non-spec compliant servers are not closing the connection even if they - // said they won't. - setImmediate(() => client[kResume]()); - } else { - client[kResume](); - } - } - } - - function onParserTimeout (parser) { - const { socket, timeoutType, client } = parser; - - /* istanbul ignore else */ - if (timeoutType === TIMEOUT_HEADERS) { - if (!socket[kWriting] || socket.writableNeedDrain || client[kRunning] > 1) { - assert(!parser.paused, 'cannot be paused while waiting for headers'); - util.destroy(socket, new HeadersTimeoutError()); - } - } else if (timeoutType === TIMEOUT_BODY) { - if (!parser.paused) { - util.destroy(socket, new BodyTimeoutError()); - } - } else if (timeoutType === TIMEOUT_IDLE) { - assert(client[kRunning] === 0 && client[kKeepAliveTimeoutValue]); - util.destroy(socket, new InformationalError('socket idle timeout')); - } - } - - async function connectH1 (client, socket) { - client[kSocket] = socket; - - if (!llhttpInstance) { - llhttpInstance = await llhttpPromise; - llhttpPromise = null; - } - - socket[kNoRef] = false; - socket[kWriting] = false; - socket[kReset] = false; - socket[kBlocking] = false; - socket[kParser] = new Parser(client, socket, llhttpInstance); - - addListener(socket, 'error', function (err) { - const parser = this[kParser]; - - assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID'); - - // On Mac OS, we get an ECONNRESET even if there is a full body to be forwarded - // to the user. - if (err.code === 'ECONNRESET' && parser.statusCode && !parser.shouldKeepAlive) { - // We treat all incoming data so for as a valid response. - parser.onMessageComplete(); - return - } - - this[kError] = err; - - this[kClient][kOnError](err); - }); - addListener(socket, 'readable', function () { - const parser = this[kParser]; - - if (parser) { - parser.readMore(); - } - }); - addListener(socket, 'end', function () { - const parser = this[kParser]; - - if (parser.statusCode && !parser.shouldKeepAlive) { - // We treat all incoming data so far as a valid response. - parser.onMessageComplete(); - return - } - - util.destroy(this, new SocketError('other side closed', util.getSocketInfo(this))); - }); - addListener(socket, 'close', function () { - const client = this[kClient]; - const parser = this[kParser]; - - if (parser) { - if (!this[kError] && parser.statusCode && !parser.shouldKeepAlive) { - // We treat all incoming data so far as a valid response. - parser.onMessageComplete(); - } - - this[kParser].destroy(); - this[kParser] = null; - } - - const err = this[kError] || new SocketError('closed', util.getSocketInfo(this)); - - client[kSocket] = null; - client[kHTTPContext] = null; // TODO (fix): This is hacky... - - if (client.destroyed) { - assert(client[kPending] === 0); - - // Fail entire queue. - const requests = client[kQueue].splice(client[kRunningIdx]); - for (let i = 0; i < requests.length; i++) { - const request = requests[i]; - util.errorRequest(client, request, err); - } - } else if (client[kRunning] > 0 && err.code !== 'UND_ERR_INFO') { - // Fail head of pipeline. - const request = client[kQueue][client[kRunningIdx]]; - client[kQueue][client[kRunningIdx]++] = null; - - util.errorRequest(client, request, err); - } - - client[kPendingIdx] = client[kRunningIdx]; - - assert(client[kRunning] === 0); - - client.emit('disconnect', client[kUrl], [client], err); - - client[kResume](); - }); - - let closed = false; - socket.on('close', () => { - closed = true; - }); - - return { - version: 'h1', - defaultPipelining: 1, - write (...args) { - return writeH1(client, ...args) - }, - resume () { - resumeH1(client); - }, - destroy (err, callback) { - if (closed) { - queueMicrotask(callback); - } else { - socket.destroy(err).on('close', callback); - } - }, - get destroyed () { - return socket.destroyed - }, - busy (request) { - if (socket[kWriting] || socket[kReset] || socket[kBlocking]) { - return true - } - - if (request) { - if (client[kRunning] > 0 && !request.idempotent) { - // Non-idempotent request cannot be retried. - // Ensure that no other requests are inflight and - // could cause failure. - return true - } - - if (client[kRunning] > 0 && (request.upgrade || request.method === 'CONNECT')) { - // Don't dispatch an upgrade until all preceding requests have completed. - // A misbehaving server might upgrade the connection before all pipelined - // request has completed. - return true - } - - if (client[kRunning] > 0 && util.bodyLength(request.body) !== 0 && - (util.isStream(request.body) || util.isAsyncIterable(request.body) || util.isFormDataLike(request.body))) { - // Request with stream or iterator body can error while other requests - // are inflight and indirectly error those as well. - // Ensure this doesn't happen by waiting for inflight - // to complete before dispatching. - - // Request with stream or iterator body cannot be retried. - // Ensure that no other requests are inflight and - // could cause failure. - return true - } - } - - return false - } - } - } - - function resumeH1 (client) { - const socket = client[kSocket]; - - if (socket && !socket.destroyed) { - if (client[kSize] === 0) { - if (!socket[kNoRef] && socket.unref) { - socket.unref(); - socket[kNoRef] = true; - } - } else if (socket[kNoRef] && socket.ref) { - socket.ref(); - socket[kNoRef] = false; - } - - if (client[kSize] === 0) { - if (socket[kParser].timeoutType !== TIMEOUT_IDLE) { - socket[kParser].setTimeout(client[kKeepAliveTimeoutValue], TIMEOUT_IDLE); - } - } else if (client[kRunning] > 0 && socket[kParser].statusCode < 200) { - if (socket[kParser].timeoutType !== TIMEOUT_HEADERS) { - const request = client[kQueue][client[kRunningIdx]]; - const headersTimeout = request.headersTimeout != null - ? request.headersTimeout - : client[kHeadersTimeout]; - socket[kParser].setTimeout(headersTimeout, TIMEOUT_HEADERS); - } - } - } - } - - // https://www.rfc-editor.org/rfc/rfc7230#section-3.3.2 - function shouldSendContentLength (method) { - return method !== 'GET' && method !== 'HEAD' && method !== 'OPTIONS' && method !== 'TRACE' && method !== 'CONNECT' - } - - function writeH1 (client, request) { - const { method, path, host, upgrade, blocking, reset } = request; - - let { body, headers, contentLength } = request; - - // https://tools.ietf.org/html/rfc7231#section-4.3.1 - // https://tools.ietf.org/html/rfc7231#section-4.3.2 - // https://tools.ietf.org/html/rfc7231#section-4.3.5 - - // Sending a payload body on a request that does not - // expect it can cause undefined behavior on some - // servers and corrupt connection state. Do not - // re-use the connection for further requests. - - const expectsPayload = ( - method === 'PUT' || - method === 'POST' || - method === 'PATCH' - ); - - if (util.isFormDataLike(body)) { - if (!extractBody) { - extractBody = requireBody().extractBody; - } - - const [bodyStream, contentType] = extractBody(body); - if (request.contentType == null) { - headers.push('content-type', contentType); - } - body = bodyStream.stream; - contentLength = bodyStream.length; - } else if (util.isBlobLike(body) && request.contentType == null && body.type) { - headers.push('content-type', body.type); - } - - if (body && typeof body.read === 'function') { - // Try to read EOF in order to get length. - body.read(0); - } - - const bodyLength = util.bodyLength(body); - - contentLength = bodyLength ?? contentLength; - - if (contentLength === null) { - contentLength = request.contentLength; - } - - if (contentLength === 0 && !expectsPayload) { - // https://tools.ietf.org/html/rfc7230#section-3.3.2 - // A user agent SHOULD NOT send a Content-Length header field when - // the request message does not contain a payload body and the method - // semantics do not anticipate such a body. - - contentLength = null; - } - - // https://github.com/nodejs/undici/issues/2046 - // A user agent may send a Content-Length header with 0 value, this should be allowed. - if (shouldSendContentLength(method) && contentLength > 0 && request.contentLength !== null && request.contentLength !== contentLength) { - if (client[kStrictContentLength]) { - util.errorRequest(client, request, new RequestContentLengthMismatchError()); - return false - } - - process.emitWarning(new RequestContentLengthMismatchError()); - } - - const socket = client[kSocket]; - - const abort = (err) => { - if (request.aborted || request.completed) { - return - } - - util.errorRequest(client, request, err || new RequestAbortedError()); - - util.destroy(body); - util.destroy(socket, new InformationalError('aborted')); - }; - - try { - request.onConnect(abort); - } catch (err) { - util.errorRequest(client, request, err); - } - - if (request.aborted) { - return false - } - - if (method === 'HEAD') { - // https://github.com/mcollina/undici/issues/258 - // Close after a HEAD request to interop with misbehaving servers - // that may send a body in the response. - - socket[kReset] = true; - } - - if (upgrade || method === 'CONNECT') { - // On CONNECT or upgrade, block pipeline from dispatching further - // requests on this connection. - - socket[kReset] = true; - } - - if (reset != null) { - socket[kReset] = reset; - } - - if (client[kMaxRequests] && socket[kCounter]++ >= client[kMaxRequests]) { - socket[kReset] = true; - } - - if (blocking) { - socket[kBlocking] = true; - } - - let header = `${method} ${path} HTTP/1.1\r\n`; - - if (typeof host === 'string') { - header += `host: ${host}\r\n`; - } else { - header += client[kHostHeader]; - } - - if (upgrade) { - header += `connection: upgrade\r\nupgrade: ${upgrade}\r\n`; - } else if (client[kPipelining] && !socket[kReset]) { - header += 'connection: keep-alive\r\n'; - } else { - header += 'connection: close\r\n'; - } - - if (Array.isArray(headers)) { - for (let n = 0; n < headers.length; n += 2) { - const key = headers[n + 0]; - const val = headers[n + 1]; - - if (Array.isArray(val)) { - for (let i = 0; i < val.length; i++) { - header += `${key}: ${val[i]}\r\n`; - } - } else { - header += `${key}: ${val}\r\n`; - } - } - } - - if (channels.sendHeaders.hasSubscribers) { - channels.sendHeaders.publish({ request, headers: header, socket }); - } - - /* istanbul ignore else: assertion */ - if (!body || bodyLength === 0) { - writeBuffer(abort, null, client, request, socket, contentLength, header, expectsPayload); - } else if (util.isBuffer(body)) { - writeBuffer(abort, body, client, request, socket, contentLength, header, expectsPayload); - } else if (util.isBlobLike(body)) { - if (typeof body.stream === 'function') { - writeIterable(abort, body.stream(), client, request, socket, contentLength, header, expectsPayload); - } else { - writeBlob(abort, body, client, request, socket, contentLength, header, expectsPayload); - } - } else if (util.isStream(body)) { - writeStream(abort, body, client, request, socket, contentLength, header, expectsPayload); - } else if (util.isIterable(body)) { - writeIterable(abort, body, client, request, socket, contentLength, header, expectsPayload); - } else { - assert(false); - } - - return true - } - - function writeStream (abort, body, client, request, socket, contentLength, header, expectsPayload) { - assert(contentLength !== 0 || client[kRunning] === 0, 'stream body cannot be pipelined'); - - let finished = false; - - const writer = new AsyncWriter({ abort, socket, request, contentLength, client, expectsPayload, header }); - - const onData = function (chunk) { - if (finished) { - return - } - - try { - if (!writer.write(chunk) && this.pause) { - this.pause(); - } - } catch (err) { - util.destroy(this, err); - } - }; - const onDrain = function () { - if (finished) { - return - } - - if (body.resume) { - body.resume(); - } - }; - const onClose = function () { - // 'close' might be emitted *before* 'error' for - // broken streams. Wait a tick to avoid this case. - queueMicrotask(() => { - // It's only safe to remove 'error' listener after - // 'close'. - body.removeListener('error', onFinished); - }); - - if (!finished) { - const err = new RequestAbortedError(); - queueMicrotask(() => onFinished(err)); - } - }; - const onFinished = function (err) { - if (finished) { - return - } - - finished = true; - - assert(socket.destroyed || (socket[kWriting] && client[kRunning] <= 1)); - - socket - .off('drain', onDrain) - .off('error', onFinished); - - body - .removeListener('data', onData) - .removeListener('end', onFinished) - .removeListener('close', onClose); - - if (!err) { - try { - writer.end(); - } catch (er) { - err = er; - } - } - - writer.destroy(err); - - if (err && (err.code !== 'UND_ERR_INFO' || err.message !== 'reset')) { - util.destroy(body, err); - } else { - util.destroy(body); - } - }; - - body - .on('data', onData) - .on('end', onFinished) - .on('error', onFinished) - .on('close', onClose); - - if (body.resume) { - body.resume(); - } - - socket - .on('drain', onDrain) - .on('error', onFinished); - - if (body.errorEmitted ?? body.errored) { - setImmediate(() => onFinished(body.errored)); - } else if (body.endEmitted ?? body.readableEnded) { - setImmediate(() => onFinished(null)); - } - - if (body.closeEmitted ?? body.closed) { - setImmediate(onClose); - } - } - - function writeBuffer (abort, body, client, request, socket, contentLength, header, expectsPayload) { - try { - if (!body) { - if (contentLength === 0) { - socket.write(`${header}content-length: 0\r\n\r\n`, 'latin1'); - } else { - assert(contentLength === null, 'no body must not have content length'); - socket.write(`${header}\r\n`, 'latin1'); - } - } else if (util.isBuffer(body)) { - assert(contentLength === body.byteLength, 'buffer body must have content length'); - - socket.cork(); - socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1'); - socket.write(body); - socket.uncork(); - request.onBodySent(body); - - if (!expectsPayload) { - socket[kReset] = true; - } - } - request.onRequestSent(); - - client[kResume](); - } catch (err) { - abort(err); - } - } - - async function writeBlob (abort, body, client, request, socket, contentLength, header, expectsPayload) { - assert(contentLength === body.size, 'blob body must have content length'); - - try { - if (contentLength != null && contentLength !== body.size) { - throw new RequestContentLengthMismatchError() - } - - const buffer = Buffer.from(await body.arrayBuffer()); - - socket.cork(); - socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1'); - socket.write(buffer); - socket.uncork(); - - request.onBodySent(buffer); - request.onRequestSent(); - - if (!expectsPayload) { - socket[kReset] = true; - } - - client[kResume](); - } catch (err) { - abort(err); - } - } - - async function writeIterable (abort, body, client, request, socket, contentLength, header, expectsPayload) { - assert(contentLength !== 0 || client[kRunning] === 0, 'iterator body cannot be pipelined'); - - let callback = null; - function onDrain () { - if (callback) { - const cb = callback; - callback = null; - cb(); - } - } - - const waitForDrain = () => new Promise((resolve, reject) => { - assert(callback === null); - - if (socket[kError]) { - reject(socket[kError]); - } else { - callback = resolve; - } - }); - - socket - .on('close', onDrain) - .on('drain', onDrain); - - const writer = new AsyncWriter({ abort, socket, request, contentLength, client, expectsPayload, header }); - try { - // It's up to the user to somehow abort the async iterable. - for await (const chunk of body) { - if (socket[kError]) { - throw socket[kError] - } - - if (!writer.write(chunk)) { - await waitForDrain(); - } - } - - writer.end(); - } catch (err) { - writer.destroy(err); - } finally { - socket - .off('close', onDrain) - .off('drain', onDrain); - } - } - - class AsyncWriter { - constructor ({ abort, socket, request, contentLength, client, expectsPayload, header }) { - this.socket = socket; - this.request = request; - this.contentLength = contentLength; - this.client = client; - this.bytesWritten = 0; - this.expectsPayload = expectsPayload; - this.header = header; - this.abort = abort; - - socket[kWriting] = true; - } - - write (chunk) { - const { socket, request, contentLength, client, bytesWritten, expectsPayload, header } = this; - - if (socket[kError]) { - throw socket[kError] - } - - if (socket.destroyed) { - return false - } - - const len = Buffer.byteLength(chunk); - if (!len) { - return true - } - - // We should defer writing chunks. - if (contentLength !== null && bytesWritten + len > contentLength) { - if (client[kStrictContentLength]) { - throw new RequestContentLengthMismatchError() - } - - process.emitWarning(new RequestContentLengthMismatchError()); - } - - socket.cork(); - - if (bytesWritten === 0) { - if (!expectsPayload) { - socket[kReset] = true; - } - - if (contentLength === null) { - socket.write(`${header}transfer-encoding: chunked\r\n`, 'latin1'); - } else { - socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1'); - } - } - - if (contentLength === null) { - socket.write(`\r\n${len.toString(16)}\r\n`, 'latin1'); - } - - this.bytesWritten += len; - - const ret = socket.write(chunk); - - socket.uncork(); - - request.onBodySent(chunk); - - if (!ret) { - if (socket[kParser].timeout && socket[kParser].timeoutType === TIMEOUT_HEADERS) { - // istanbul ignore else: only for jest - if (socket[kParser].timeout.refresh) { - socket[kParser].timeout.refresh(); - } - } - } - - return ret - } - - end () { - const { socket, contentLength, client, bytesWritten, expectsPayload, header, request } = this; - request.onRequestSent(); - - socket[kWriting] = false; - - if (socket[kError]) { - throw socket[kError] - } - - if (socket.destroyed) { - return - } - - if (bytesWritten === 0) { - if (expectsPayload) { - // https://tools.ietf.org/html/rfc7230#section-3.3.2 - // A user agent SHOULD send a Content-Length in a request message when - // no Transfer-Encoding is sent and the request method defines a meaning - // for an enclosed payload body. - - socket.write(`${header}content-length: 0\r\n\r\n`, 'latin1'); - } else { - socket.write(`${header}\r\n`, 'latin1'); - } - } else if (contentLength === null) { - socket.write('\r\n0\r\n\r\n', 'latin1'); - } - - if (contentLength !== null && bytesWritten !== contentLength) { - if (client[kStrictContentLength]) { - throw new RequestContentLengthMismatchError() - } else { - process.emitWarning(new RequestContentLengthMismatchError()); - } - } - - if (socket[kParser].timeout && socket[kParser].timeoutType === TIMEOUT_HEADERS) { - // istanbul ignore else: only for jest - if (socket[kParser].timeout.refresh) { - socket[kParser].timeout.refresh(); - } - } - - client[kResume](); - } - - destroy (err) { - const { socket, client, abort } = this; - - socket[kWriting] = false; - - if (err) { - assert(client[kRunning] <= 1, 'pipeline should only contain this request'); - abort(err); - } - } - } - - clientH1 = connectH1; - return clientH1; -} - -var clientH2; -var hasRequiredClientH2; - -function requireClientH2 () { - if (hasRequiredClientH2) return clientH2; - hasRequiredClientH2 = 1; - - const assert = require$$0$4; - const { pipeline } = require$$0$5; - const util = requireUtil$7(); - const { - RequestContentLengthMismatchError, - RequestAbortedError, - SocketError, - InformationalError - } = requireErrors(); - const { - kUrl, - kReset, - kClient, - kRunning, - kPending, - kQueue, - kPendingIdx, - kRunningIdx, - kError, - kSocket, - kStrictContentLength, - kOnError, - kMaxConcurrentStreams, - kHTTP2Session, - kResume - } = requireSymbols$4(); - - const kOpenStreams = Symbol('open streams'); - - // Experimental - let h2ExperimentalWarned = false; - - /** @type {import('http2')} */ - let http2; - try { - http2 = require('node:http2'); - } catch { - // @ts-ignore - http2 = { constants: {} }; - } - - const { - constants: { - HTTP2_HEADER_AUTHORITY, - HTTP2_HEADER_METHOD, - HTTP2_HEADER_PATH, - HTTP2_HEADER_SCHEME, - HTTP2_HEADER_CONTENT_LENGTH, - HTTP2_HEADER_EXPECT, - HTTP2_HEADER_STATUS - } - } = http2; - - function parseH2Headers (headers) { - const result = []; - - for (const [name, value] of Object.entries(headers)) { - // h2 may concat the header value by array - // e.g. Set-Cookie - if (Array.isArray(value)) { - for (const subvalue of value) { - // we need to provide each header value of header name - // because the headers handler expect name-value pair - result.push(Buffer.from(name), Buffer.from(subvalue)); - } - } else { - result.push(Buffer.from(name), Buffer.from(value)); - } - } - - return result - } - - async function connectH2 (client, socket) { - client[kSocket] = socket; - - if (!h2ExperimentalWarned) { - h2ExperimentalWarned = true; - process.emitWarning('H2 support is experimental, expect them to change at any time.', { - code: 'UNDICI-H2' - }); - } - - const session = http2.connect(client[kUrl], { - createConnection: () => socket, - peerMaxConcurrentStreams: client[kMaxConcurrentStreams] - }); - - session[kOpenStreams] = 0; - session[kClient] = client; - session[kSocket] = socket; - - util.addListener(session, 'error', onHttp2SessionError); - util.addListener(session, 'frameError', onHttp2FrameError); - util.addListener(session, 'end', onHttp2SessionEnd); - util.addListener(session, 'goaway', onHTTP2GoAway); - util.addListener(session, 'close', function () { - const { [kClient]: client } = this; - const { [kSocket]: socket } = client; - - const err = this[kSocket][kError] || this[kError] || new SocketError('closed', util.getSocketInfo(socket)); - - client[kHTTP2Session] = null; - - if (client.destroyed) { - assert(client[kPending] === 0); - - // Fail entire queue. - const requests = client[kQueue].splice(client[kRunningIdx]); - for (let i = 0; i < requests.length; i++) { - const request = requests[i]; - util.errorRequest(client, request, err); - } - } - }); - - session.unref(); - - client[kHTTP2Session] = session; - socket[kHTTP2Session] = session; - - util.addListener(socket, 'error', function (err) { - assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID'); - - this[kError] = err; - - this[kClient][kOnError](err); - }); - - util.addListener(socket, 'end', function () { - util.destroy(this, new SocketError('other side closed', util.getSocketInfo(this))); - }); - - util.addListener(socket, 'close', function () { - const err = this[kError] || new SocketError('closed', util.getSocketInfo(this)); - - client[kSocket] = null; - - if (this[kHTTP2Session] != null) { - this[kHTTP2Session].destroy(err); - } - - client[kPendingIdx] = client[kRunningIdx]; - - assert(client[kRunning] === 0); - - client.emit('disconnect', client[kUrl], [client], err); - - client[kResume](); - }); - - let closed = false; - socket.on('close', () => { - closed = true; - }); - - return { - version: 'h2', - defaultPipelining: Infinity, - write (...args) { - // TODO (fix): return - writeH2(client, ...args); - }, - resume () { - - }, - destroy (err, callback) { - if (closed) { - queueMicrotask(callback); - } else { - // Destroying the socket will trigger the session close - socket.destroy(err).on('close', callback); - } - }, - get destroyed () { - return socket.destroyed - }, - busy () { - return false - } - } - } - - function onHttp2SessionError (err) { - assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID'); - - this[kSocket][kError] = err; - this[kClient][kOnError](err); - } - - function onHttp2FrameError (type, code, id) { - if (id === 0) { - const err = new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`); - this[kSocket][kError] = err; - this[kClient][kOnError](err); - } - } - - function onHttp2SessionEnd () { - const err = new SocketError('other side closed', util.getSocketInfo(this[kSocket])); - this.destroy(err); - util.destroy(this[kSocket], err); - } - - /** - * This is the root cause of #3011 - * We need to handle GOAWAY frames properly, and trigger the session close - * along with the socket right away - */ - function onHTTP2GoAway (code) { - const err = new RequestAbortedError(`HTTP/2: "GOAWAY" frame received with code ${code}`); - - // We need to trigger the close cycle right away - // We need to destroy the session and the socket - // Requests should be failed with the error after the current one is handled - this[kSocket][kError] = err; - this[kClient][kOnError](err); - - this.unref(); - - util.destroy(this[kSocket], err); - } - - // https://www.rfc-editor.org/rfc/rfc7230#section-3.3.2 - function shouldSendContentLength (method) { - return method !== 'GET' && method !== 'HEAD' && method !== 'OPTIONS' && method !== 'TRACE' && method !== 'CONNECT' - } - - function writeH2 (client, request) { - const session = client[kHTTP2Session]; - const { body, method, path, host, upgrade, expectContinue, signal, headers: reqHeaders } = request; - - if (upgrade) { - util.errorRequest(client, request, new Error('Upgrade not supported for H2')); - return false - } - - if (request.aborted) { - return false - } - - const headers = {}; - for (let n = 0; n < reqHeaders.length; n += 2) { - const key = reqHeaders[n + 0]; - const val = reqHeaders[n + 1]; - - if (Array.isArray(val)) { - for (let i = 0; i < val.length; i++) { - if (headers[key]) { - headers[key] += `,${val[i]}`; - } else { - headers[key] = val[i]; - } - } - } else { - headers[key] = val; - } - } - - /** @type {import('node:http2').ClientHttp2Stream} */ - let stream; - - const { hostname, port } = client[kUrl]; - - headers[HTTP2_HEADER_AUTHORITY] = host || `${hostname}${port ? `:${port}` : ''}`; - headers[HTTP2_HEADER_METHOD] = method; - - const abort = (err) => { - if (request.aborted || request.completed) { - return - } - - err = err || new RequestAbortedError(); - - util.errorRequest(client, request, err); - - if (stream != null) { - util.destroy(stream, err); - } - - // We do not destroy the socket as we can continue using the session - // the stream get's destroyed and the session remains to create new streams - util.destroy(body, err); - }; - - try { - // We are already connected, streams are pending. - // We can call on connect, and wait for abort - request.onConnect(abort); - } catch (err) { - util.errorRequest(client, request, err); - } - - if (method === 'CONNECT') { - session.ref(); - // We are already connected, streams are pending, first request - // will create a new stream. We trigger a request to create the stream and wait until - // `ready` event is triggered - // We disabled endStream to allow the user to write to the stream - stream = session.request(headers, { endStream: false, signal }); - - if (stream.id && !stream.pending) { - request.onUpgrade(null, null, stream); - ++session[kOpenStreams]; - } else { - stream.once('ready', () => { - request.onUpgrade(null, null, stream); - ++session[kOpenStreams]; - }); - } - - stream.once('close', () => { - session[kOpenStreams] -= 1; - if (session[kOpenStreams] === 0) session.unref(); - }); - - return true - } - - // https://tools.ietf.org/html/rfc7540#section-8.3 - // :path and :scheme headers must be omitted when sending CONNECT - - headers[HTTP2_HEADER_PATH] = path; - headers[HTTP2_HEADER_SCHEME] = 'https'; - - // https://tools.ietf.org/html/rfc7231#section-4.3.1 - // https://tools.ietf.org/html/rfc7231#section-4.3.2 - // https://tools.ietf.org/html/rfc7231#section-4.3.5 - - // Sending a payload body on a request that does not - // expect it can cause undefined behavior on some - // servers and corrupt connection state. Do not - // re-use the connection for further requests. - - const expectsPayload = ( - method === 'PUT' || - method === 'POST' || - method === 'PATCH' - ); - - if (body && typeof body.read === 'function') { - // Try to read EOF in order to get length. - body.read(0); - } - - let contentLength = util.bodyLength(body); - - if (contentLength == null) { - contentLength = request.contentLength; - } - - if (contentLength === 0 || !expectsPayload) { - // https://tools.ietf.org/html/rfc7230#section-3.3.2 - // A user agent SHOULD NOT send a Content-Length header field when - // the request message does not contain a payload body and the method - // semantics do not anticipate such a body. - - contentLength = null; - } - - // https://github.com/nodejs/undici/issues/2046 - // A user agent may send a Content-Length header with 0 value, this should be allowed. - if (shouldSendContentLength(method) && contentLength > 0 && request.contentLength != null && request.contentLength !== contentLength) { - if (client[kStrictContentLength]) { - util.errorRequest(client, request, new RequestContentLengthMismatchError()); - return false - } - - process.emitWarning(new RequestContentLengthMismatchError()); - } - - if (contentLength != null) { - assert(body, 'no body must not have content length'); - headers[HTTP2_HEADER_CONTENT_LENGTH] = `${contentLength}`; - } - - session.ref(); - - const shouldEndStream = method === 'GET' || method === 'HEAD' || body === null; - if (expectContinue) { - headers[HTTP2_HEADER_EXPECT] = '100-continue'; - stream = session.request(headers, { endStream: shouldEndStream, signal }); - - stream.once('continue', writeBodyH2); - } else { - stream = session.request(headers, { - endStream: shouldEndStream, - signal - }); - writeBodyH2(); - } - - // Increment counter as we have new streams open - ++session[kOpenStreams]; - - stream.once('response', headers => { - const { [HTTP2_HEADER_STATUS]: statusCode, ...realHeaders } = headers; - request.onResponseStarted(); - - // Due to the stream nature, it is possible we face a race condition - // where the stream has been assigned, but the request has been aborted - // the request remains in-flight and headers hasn't been received yet - // for those scenarios, best effort is to destroy the stream immediately - // as there's no value to keep it open. - if (request.aborted) { - const err = new RequestAbortedError(); - util.errorRequest(client, request, err); - util.destroy(stream, err); - return - } - - if (request.onHeaders(Number(statusCode), parseH2Headers(realHeaders), stream.resume.bind(stream), '') === false) { - stream.pause(); - } - - stream.on('data', (chunk) => { - if (request.onData(chunk) === false) { - stream.pause(); - } - }); - }); - - stream.once('end', () => { - // When state is null, it means we haven't consumed body and the stream still do not have - // a state. - // Present specially when using pipeline or stream - if (stream.state?.state == null || stream.state.state < 6) { - request.onComplete([]); - return - } - - // Stream is closed or half-closed-remote (6), decrement counter and cleanup - // It does not have sense to continue working with the stream as we do not - // have yet RST_STREAM support on client-side - if (session[kOpenStreams] === 0) { - session.unref(); - } - - abort(new InformationalError('HTTP/2: stream half-closed (remote)')); - }); - - stream.once('close', () => { - session[kOpenStreams] -= 1; - if (session[kOpenStreams] === 0) { - session.unref(); - } - }); - - stream.once('error', function (err) { - abort(err); - }); - - stream.once('frameError', (type, code) => { - abort(new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`)); - }); - - // stream.on('aborted', () => { - // // TODO(HTTP/2): Support aborted - // }) - - // stream.on('timeout', () => { - // // TODO(HTTP/2): Support timeout - // }) - - // stream.on('push', headers => { - // // TODO(HTTP/2): Support push - // }) - - // stream.on('trailers', headers => { - // // TODO(HTTP/2): Support trailers - // }) - - return true - - function writeBodyH2 () { - /* istanbul ignore else: assertion */ - if (!body || contentLength === 0) { - writeBuffer( - abort, - stream, - null, - client, - request, - client[kSocket], - contentLength, - expectsPayload - ); - } else if (util.isBuffer(body)) { - writeBuffer( - abort, - stream, - body, - client, - request, - client[kSocket], - contentLength, - expectsPayload - ); - } else if (util.isBlobLike(body)) { - if (typeof body.stream === 'function') { - writeIterable( - abort, - stream, - body.stream(), - client, - request, - client[kSocket], - contentLength, - expectsPayload - ); - } else { - writeBlob( - abort, - stream, - body, - client, - request, - client[kSocket], - contentLength, - expectsPayload - ); - } - } else if (util.isStream(body)) { - writeStream( - abort, - client[kSocket], - expectsPayload, - stream, - body, - client, - request, - contentLength - ); - } else if (util.isIterable(body)) { - writeIterable( - abort, - stream, - body, - client, - request, - client[kSocket], - contentLength, - expectsPayload - ); - } else { - assert(false); - } - } - } - - function writeBuffer (abort, h2stream, body, client, request, socket, contentLength, expectsPayload) { - try { - if (body != null && util.isBuffer(body)) { - assert(contentLength === body.byteLength, 'buffer body must have content length'); - h2stream.cork(); - h2stream.write(body); - h2stream.uncork(); - h2stream.end(); - - request.onBodySent(body); - } - - if (!expectsPayload) { - socket[kReset] = true; - } - - request.onRequestSent(); - client[kResume](); - } catch (error) { - abort(error); - } - } - - function writeStream (abort, socket, expectsPayload, h2stream, body, client, request, contentLength) { - assert(contentLength !== 0 || client[kRunning] === 0, 'stream body cannot be pipelined'); - - // For HTTP/2, is enough to pipe the stream - const pipe = pipeline( - body, - h2stream, - (err) => { - if (err) { - util.destroy(pipe, err); - abort(err); - } else { - util.removeAllListeners(pipe); - request.onRequestSent(); - - if (!expectsPayload) { - socket[kReset] = true; - } - - client[kResume](); - } - } - ); - - util.addListener(pipe, 'data', onPipeData); - - function onPipeData (chunk) { - request.onBodySent(chunk); - } - } - - async function writeBlob (abort, h2stream, body, client, request, socket, contentLength, expectsPayload) { - assert(contentLength === body.size, 'blob body must have content length'); - - try { - if (contentLength != null && contentLength !== body.size) { - throw new RequestContentLengthMismatchError() - } - - const buffer = Buffer.from(await body.arrayBuffer()); - - h2stream.cork(); - h2stream.write(buffer); - h2stream.uncork(); - h2stream.end(); - - request.onBodySent(buffer); - request.onRequestSent(); - - if (!expectsPayload) { - socket[kReset] = true; - } - - client[kResume](); - } catch (err) { - abort(err); - } - } - - async function writeIterable (abort, h2stream, body, client, request, socket, contentLength, expectsPayload) { - assert(contentLength !== 0 || client[kRunning] === 0, 'iterator body cannot be pipelined'); - - let callback = null; - function onDrain () { - if (callback) { - const cb = callback; - callback = null; - cb(); - } - } - - const waitForDrain = () => new Promise((resolve, reject) => { - assert(callback === null); - - if (socket[kError]) { - reject(socket[kError]); - } else { - callback = resolve; - } - }); - - h2stream - .on('close', onDrain) - .on('drain', onDrain); - - try { - // It's up to the user to somehow abort the async iterable. - for await (const chunk of body) { - if (socket[kError]) { - throw socket[kError] - } - - const res = h2stream.write(chunk); - request.onBodySent(chunk); - if (!res) { - await waitForDrain(); - } - } - - h2stream.end(); - - request.onRequestSent(); - - if (!expectsPayload) { - socket[kReset] = true; - } - - client[kResume](); - } catch (err) { - abort(err); - } finally { - h2stream - .off('close', onDrain) - .off('drain', onDrain); - } - } - - clientH2 = connectH2; - return clientH2; -} - -var redirectHandler; -var hasRequiredRedirectHandler; - -function requireRedirectHandler () { - if (hasRequiredRedirectHandler) return redirectHandler; - hasRequiredRedirectHandler = 1; - - const util = requireUtil$7(); - const { kBodyUsed } = requireSymbols$4(); - const assert = require$$0$4; - const { InvalidArgumentError } = requireErrors(); - const EE = require$$8; - - const redirectableStatusCodes = [300, 301, 302, 303, 307, 308]; - - const kBody = Symbol('body'); - - class BodyAsyncIterable { - constructor (body) { - this[kBody] = body; - this[kBodyUsed] = false; - } - - async * [Symbol.asyncIterator] () { - assert(!this[kBodyUsed], 'disturbed'); - this[kBodyUsed] = true; - yield * this[kBody]; - } - } - - class RedirectHandler { - constructor (dispatch, maxRedirections, opts, handler) { - if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) { - throw new InvalidArgumentError('maxRedirections must be a positive number') - } - - util.validateHandler(handler, opts.method, opts.upgrade); - - this.dispatch = dispatch; - this.location = null; - this.abort = null; - this.opts = { ...opts, maxRedirections: 0 }; // opts must be a copy - this.maxRedirections = maxRedirections; - this.handler = handler; - this.history = []; - this.redirectionLimitReached = false; - - if (util.isStream(this.opts.body)) { - // TODO (fix): Provide some way for the user to cache the file to e.g. /tmp - // so that it can be dispatched again? - // TODO (fix): Do we need 100-expect support to provide a way to do this properly? - if (util.bodyLength(this.opts.body) === 0) { - this.opts.body - .on('data', function () { - assert(false); - }); - } - - if (typeof this.opts.body.readableDidRead !== 'boolean') { - this.opts.body[kBodyUsed] = false; - EE.prototype.on.call(this.opts.body, 'data', function () { - this[kBodyUsed] = true; - }); - } - } else if (this.opts.body && typeof this.opts.body.pipeTo === 'function') { - // TODO (fix): We can't access ReadableStream internal state - // to determine whether or not it has been disturbed. This is just - // a workaround. - this.opts.body = new BodyAsyncIterable(this.opts.body); - } else if ( - this.opts.body && - typeof this.opts.body !== 'string' && - !ArrayBuffer.isView(this.opts.body) && - util.isIterable(this.opts.body) - ) { - // TODO: Should we allow re-using iterable if !this.opts.idempotent - // or through some other flag? - this.opts.body = new BodyAsyncIterable(this.opts.body); - } - } - - onConnect (abort) { - this.abort = abort; - this.handler.onConnect(abort, { history: this.history }); - } - - onUpgrade (statusCode, headers, socket) { - this.handler.onUpgrade(statusCode, headers, socket); - } - - onError (error) { - this.handler.onError(error); - } - - onHeaders (statusCode, headers, resume, statusText) { - this.location = this.history.length >= this.maxRedirections || util.isDisturbed(this.opts.body) - ? null - : parseLocation(statusCode, headers); - - if (this.opts.throwOnMaxRedirect && this.history.length >= this.maxRedirections) { - if (this.request) { - this.request.abort(new Error('max redirects')); - } - - this.redirectionLimitReached = true; - this.abort(new Error('max redirects')); - return - } - - if (this.opts.origin) { - this.history.push(new URL(this.opts.path, this.opts.origin)); - } - - if (!this.location) { - return this.handler.onHeaders(statusCode, headers, resume, statusText) - } - - const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin))); - const path = search ? `${pathname}${search}` : pathname; - - // Remove headers referring to the original URL. - // By default it is Host only, unless it's a 303 (see below), which removes also all Content-* headers. - // https://tools.ietf.org/html/rfc7231#section-6.4 - this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin); - this.opts.path = path; - this.opts.origin = origin; - this.opts.maxRedirections = 0; - this.opts.query = null; - - // https://tools.ietf.org/html/rfc7231#section-6.4.4 - // In case of HTTP 303, always replace method to be either HEAD or GET - if (statusCode === 303 && this.opts.method !== 'HEAD') { - this.opts.method = 'GET'; - this.opts.body = null; - } - } - - onData (chunk) { - if (this.location) ; else { - return this.handler.onData(chunk) - } - } - - onComplete (trailers) { - if (this.location) { - /* - https://tools.ietf.org/html/rfc7231#section-6.4 - - TLDR: undici always ignores 3xx response trailers as they are not expected in case of redirections - and neither are useful if present. - - See comment on onData method above for more detailed information. - */ - - this.location = null; - this.abort = null; - - this.dispatch(this.opts, this); - } else { - this.handler.onComplete(trailers); - } - } - - onBodySent (chunk) { - if (this.handler.onBodySent) { - this.handler.onBodySent(chunk); - } - } - } - - function parseLocation (statusCode, headers) { - if (redirectableStatusCodes.indexOf(statusCode) === -1) { - return null - } - - for (let i = 0; i < headers.length; i += 2) { - if (headers[i].length === 8 && util.headerNameToString(headers[i]) === 'location') { - return headers[i + 1] - } - } - } - - // https://tools.ietf.org/html/rfc7231#section-6.4.4 - function shouldRemoveHeader (header, removeContent, unknownOrigin) { - if (header.length === 4) { - return util.headerNameToString(header) === 'host' - } - if (removeContent && util.headerNameToString(header).startsWith('content-')) { - return true - } - if (unknownOrigin && (header.length === 13 || header.length === 6 || header.length === 19)) { - const name = util.headerNameToString(header); - return name === 'authorization' || name === 'cookie' || name === 'proxy-authorization' - } - return false - } - - // https://tools.ietf.org/html/rfc7231#section-6.4 - function cleanRequestHeaders (headers, removeContent, unknownOrigin) { - const ret = []; - if (Array.isArray(headers)) { - for (let i = 0; i < headers.length; i += 2) { - if (!shouldRemoveHeader(headers[i], removeContent, unknownOrigin)) { - ret.push(headers[i], headers[i + 1]); - } - } - } else if (headers && typeof headers === 'object') { - for (const key of Object.keys(headers)) { - if (!shouldRemoveHeader(key, removeContent, unknownOrigin)) { - ret.push(key, headers[key]); - } - } - } else { - assert(headers == null, 'headers must be an object or an array'); - } - return ret - } - - redirectHandler = RedirectHandler; - return redirectHandler; -} - -var redirectInterceptor; -var hasRequiredRedirectInterceptor; - -function requireRedirectInterceptor () { - if (hasRequiredRedirectInterceptor) return redirectInterceptor; - hasRequiredRedirectInterceptor = 1; - - const RedirectHandler = requireRedirectHandler(); - - function createRedirectInterceptor ({ maxRedirections: defaultMaxRedirections }) { - return (dispatch) => { - return function Intercept (opts, handler) { - const { maxRedirections = defaultMaxRedirections } = opts; - - if (!maxRedirections) { - return dispatch(opts, handler) - } - - const redirectHandler = new RedirectHandler(dispatch, maxRedirections, opts, handler); - opts = { ...opts, maxRedirections: 0 }; // Stop sub dispatcher from also redirecting. - return dispatch(opts, redirectHandler) - } - } - } - - redirectInterceptor = createRedirectInterceptor; - return redirectInterceptor; -} - -var client; -var hasRequiredClient; - -function requireClient () { - if (hasRequiredClient) return client; - hasRequiredClient = 1; - - const assert = require$$0$4; - const net = require$$4; - const http = require$$2; - const util = requireUtil$7(); - const { channels } = requireDiagnostics(); - const Request = requireRequest$1(); - const DispatcherBase = requireDispatcherBase(); - const { - InvalidArgumentError, - InformationalError, - ClientDestroyedError - } = requireErrors(); - const buildConnector = requireConnect(); - const { - kUrl, - kServerName, - kClient, - kBusy, - kConnect, - kResuming, - kRunning, - kPending, - kSize, - kQueue, - kConnected, - kConnecting, - kNeedDrain, - kKeepAliveDefaultTimeout, - kHostHeader, - kPendingIdx, - kRunningIdx, - kError, - kPipelining, - kKeepAliveTimeoutValue, - kMaxHeadersSize, - kKeepAliveMaxTimeout, - kKeepAliveTimeoutThreshold, - kHeadersTimeout, - kBodyTimeout, - kStrictContentLength, - kConnector, - kMaxRedirections, - kMaxRequests, - kCounter, - kClose, - kDestroy, - kDispatch, - kInterceptors, - kLocalAddress, - kMaxResponseSize, - kOnError, - kHTTPContext, - kMaxConcurrentStreams, - kResume - } = requireSymbols$4(); - const connectH1 = requireClientH1(); - const connectH2 = requireClientH2(); - let deprecatedInterceptorWarned = false; - - const kClosedResolve = Symbol('kClosedResolve'); - - function getPipelining (client) { - return client[kPipelining] ?? client[kHTTPContext]?.defaultPipelining ?? 1 - } - - /** - * @type {import('../../types/client.js').default} - */ - class Client extends DispatcherBase { - /** - * - * @param {string|URL} url - * @param {import('../../types/client.js').Client.Options} options - */ - constructor (url, { - interceptors, - maxHeaderSize, - headersTimeout, - socketTimeout, - requestTimeout, - connectTimeout, - bodyTimeout, - idleTimeout, - keepAlive, - keepAliveTimeout, - maxKeepAliveTimeout, - keepAliveMaxTimeout, - keepAliveTimeoutThreshold, - socketPath, - pipelining, - tls, - strictContentLength, - maxCachedSessions, - maxRedirections, - connect, - maxRequestsPerClient, - localAddress, - maxResponseSize, - autoSelectFamily, - autoSelectFamilyAttemptTimeout, - // h2 - maxConcurrentStreams, - allowH2 - } = {}) { - super(); - - if (keepAlive !== undefined) { - throw new InvalidArgumentError('unsupported keepAlive, use pipelining=0 instead') - } - - if (socketTimeout !== undefined) { - throw new InvalidArgumentError('unsupported socketTimeout, use headersTimeout & bodyTimeout instead') - } - - if (requestTimeout !== undefined) { - throw new InvalidArgumentError('unsupported requestTimeout, use headersTimeout & bodyTimeout instead') - } - - if (idleTimeout !== undefined) { - throw new InvalidArgumentError('unsupported idleTimeout, use keepAliveTimeout instead') - } - - if (maxKeepAliveTimeout !== undefined) { - throw new InvalidArgumentError('unsupported maxKeepAliveTimeout, use keepAliveMaxTimeout instead') - } - - if (maxHeaderSize != null && !Number.isFinite(maxHeaderSize)) { - throw new InvalidArgumentError('invalid maxHeaderSize') - } - - if (socketPath != null && typeof socketPath !== 'string') { - throw new InvalidArgumentError('invalid socketPath') - } - - if (connectTimeout != null && (!Number.isFinite(connectTimeout) || connectTimeout < 0)) { - throw new InvalidArgumentError('invalid connectTimeout') - } - - if (keepAliveTimeout != null && (!Number.isFinite(keepAliveTimeout) || keepAliveTimeout <= 0)) { - throw new InvalidArgumentError('invalid keepAliveTimeout') - } - - if (keepAliveMaxTimeout != null && (!Number.isFinite(keepAliveMaxTimeout) || keepAliveMaxTimeout <= 0)) { - throw new InvalidArgumentError('invalid keepAliveMaxTimeout') - } - - if (keepAliveTimeoutThreshold != null && !Number.isFinite(keepAliveTimeoutThreshold)) { - throw new InvalidArgumentError('invalid keepAliveTimeoutThreshold') - } - - if (headersTimeout != null && (!Number.isInteger(headersTimeout) || headersTimeout < 0)) { - throw new InvalidArgumentError('headersTimeout must be a positive integer or zero') - } - - if (bodyTimeout != null && (!Number.isInteger(bodyTimeout) || bodyTimeout < 0)) { - throw new InvalidArgumentError('bodyTimeout must be a positive integer or zero') - } - - if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') { - throw new InvalidArgumentError('connect must be a function or an object') - } - - if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) { - throw new InvalidArgumentError('maxRedirections must be a positive number') - } - - if (maxRequestsPerClient != null && (!Number.isInteger(maxRequestsPerClient) || maxRequestsPerClient < 0)) { - throw new InvalidArgumentError('maxRequestsPerClient must be a positive number') - } - - if (localAddress != null && (typeof localAddress !== 'string' || net.isIP(localAddress) === 0)) { - throw new InvalidArgumentError('localAddress must be valid string IP address') - } - - if (maxResponseSize != null && (!Number.isInteger(maxResponseSize) || maxResponseSize < -1)) { - throw new InvalidArgumentError('maxResponseSize must be a positive number') - } - - if ( - autoSelectFamilyAttemptTimeout != null && - (!Number.isInteger(autoSelectFamilyAttemptTimeout) || autoSelectFamilyAttemptTimeout < -1) - ) { - throw new InvalidArgumentError('autoSelectFamilyAttemptTimeout must be a positive number') - } - - // h2 - if (allowH2 != null && typeof allowH2 !== 'boolean') { - throw new InvalidArgumentError('allowH2 must be a valid boolean value') - } - - if (maxConcurrentStreams != null && (typeof maxConcurrentStreams !== 'number' || maxConcurrentStreams < 1)) { - throw new InvalidArgumentError('maxConcurrentStreams must be a positive integer, greater than 0') - } - - if (typeof connect !== 'function') { - connect = buildConnector({ - ...tls, - maxCachedSessions, - allowH2, - socketPath, - timeout: connectTimeout, - ...(autoSelectFamily ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : undefined), - ...connect - }); - } - - if (interceptors?.Client && Array.isArray(interceptors.Client)) { - this[kInterceptors] = interceptors.Client; - if (!deprecatedInterceptorWarned) { - deprecatedInterceptorWarned = true; - process.emitWarning('Client.Options#interceptor is deprecated. Use Dispatcher#compose instead.', { - code: 'UNDICI-CLIENT-INTERCEPTOR-DEPRECATED' - }); - } - } else { - this[kInterceptors] = [createRedirectInterceptor({ maxRedirections })]; - } - - this[kUrl] = util.parseOrigin(url); - this[kConnector] = connect; - this[kPipelining] = pipelining != null ? pipelining : 1; - this[kMaxHeadersSize] = maxHeaderSize || http.maxHeaderSize; - this[kKeepAliveDefaultTimeout] = keepAliveTimeout == null ? 4e3 : keepAliveTimeout; - this[kKeepAliveMaxTimeout] = keepAliveMaxTimeout == null ? 600e3 : keepAliveMaxTimeout; - this[kKeepAliveTimeoutThreshold] = keepAliveTimeoutThreshold == null ? 2e3 : keepAliveTimeoutThreshold; - this[kKeepAliveTimeoutValue] = this[kKeepAliveDefaultTimeout]; - this[kServerName] = null; - this[kLocalAddress] = localAddress != null ? localAddress : null; - this[kResuming] = 0; // 0, idle, 1, scheduled, 2 resuming - this[kNeedDrain] = 0; // 0, idle, 1, scheduled, 2 resuming - this[kHostHeader] = `host: ${this[kUrl].hostname}${this[kUrl].port ? `:${this[kUrl].port}` : ''}\r\n`; - this[kBodyTimeout] = bodyTimeout != null ? bodyTimeout : 300e3; - this[kHeadersTimeout] = headersTimeout != null ? headersTimeout : 300e3; - this[kStrictContentLength] = strictContentLength == null ? true : strictContentLength; - this[kMaxRedirections] = maxRedirections; - this[kMaxRequests] = maxRequestsPerClient; - this[kClosedResolve] = null; - this[kMaxResponseSize] = maxResponseSize > -1 ? maxResponseSize : -1; - this[kMaxConcurrentStreams] = maxConcurrentStreams != null ? maxConcurrentStreams : 100; // Max peerConcurrentStreams for a Node h2 server - this[kHTTPContext] = null; - - // kQueue is built up of 3 sections separated by - // the kRunningIdx and kPendingIdx indices. - // | complete | running | pending | - // ^ kRunningIdx ^ kPendingIdx ^ kQueue.length - // kRunningIdx points to the first running element. - // kPendingIdx points to the first pending element. - // This implements a fast queue with an amortized - // time of O(1). - - this[kQueue] = []; - this[kRunningIdx] = 0; - this[kPendingIdx] = 0; - - this[kResume] = (sync) => resume(this, sync); - this[kOnError] = (err) => onError(this, err); - } - - get pipelining () { - return this[kPipelining] - } - - set pipelining (value) { - this[kPipelining] = value; - this[kResume](true); - } - - get [kPending] () { - return this[kQueue].length - this[kPendingIdx] - } - - get [kRunning] () { - return this[kPendingIdx] - this[kRunningIdx] - } - - get [kSize] () { - return this[kQueue].length - this[kRunningIdx] - } - - get [kConnected] () { - return !!this[kHTTPContext] && !this[kConnecting] && !this[kHTTPContext].destroyed - } - - get [kBusy] () { - return Boolean( - this[kHTTPContext]?.busy(null) || - (this[kSize] >= (getPipelining(this) || 1)) || - this[kPending] > 0 - ) - } - - /* istanbul ignore: only used for test */ - [kConnect] (cb) { - connect(this); - this.once('connect', cb); - } - - [kDispatch] (opts, handler) { - const origin = opts.origin || this[kUrl].origin; - const request = new Request(origin, opts, handler); - - this[kQueue].push(request); - if (this[kResuming]) ; else if (util.bodyLength(request.body) == null && util.isIterable(request.body)) { - // Wait a tick in case stream/iterator is ended in the same tick. - this[kResuming] = 1; - queueMicrotask(() => resume(this)); - } else { - this[kResume](true); - } - - if (this[kResuming] && this[kNeedDrain] !== 2 && this[kBusy]) { - this[kNeedDrain] = 2; - } - - return this[kNeedDrain] < 2 - } - - async [kClose] () { - // TODO: for H2 we need to gracefully flush the remaining enqueued - // request and close each stream. - return new Promise((resolve) => { - if (this[kSize]) { - this[kClosedResolve] = resolve; - } else { - resolve(null); - } - }) - } - - async [kDestroy] (err) { - return new Promise((resolve) => { - const requests = this[kQueue].splice(this[kPendingIdx]); - for (let i = 0; i < requests.length; i++) { - const request = requests[i]; - util.errorRequest(this, request, err); - } - - const callback = () => { - if (this[kClosedResolve]) { - // TODO (fix): Should we error here with ClientDestroyedError? - this[kClosedResolve](); - this[kClosedResolve] = null; - } - resolve(null); - }; - - if (this[kHTTPContext]) { - this[kHTTPContext].destroy(err, callback); - this[kHTTPContext] = null; - } else { - queueMicrotask(callback); - } - - this[kResume](); - }) - } - } - - const createRedirectInterceptor = requireRedirectInterceptor(); - - function onError (client, err) { - if ( - client[kRunning] === 0 && - err.code !== 'UND_ERR_INFO' && - err.code !== 'UND_ERR_SOCKET' - ) { - // Error is not caused by running request and not a recoverable - // socket error. - - assert(client[kPendingIdx] === client[kRunningIdx]); - - const requests = client[kQueue].splice(client[kRunningIdx]); - - for (let i = 0; i < requests.length; i++) { - const request = requests[i]; - util.errorRequest(client, request, err); - } - assert(client[kSize] === 0); - } - } - - async function connect (client) { - assert(!client[kConnecting]); - assert(!client[kHTTPContext]); - - let { host, hostname, protocol, port } = client[kUrl]; - - // Resolve ipv6 - if (hostname[0] === '[') { - const idx = hostname.indexOf(']'); - - assert(idx !== -1); - const ip = hostname.substring(1, idx); - - assert(net.isIP(ip)); - hostname = ip; - } - - client[kConnecting] = true; - - if (channels.beforeConnect.hasSubscribers) { - channels.beforeConnect.publish({ - connectParams: { - host, - hostname, - protocol, - port, - version: client[kHTTPContext]?.version, - servername: client[kServerName], - localAddress: client[kLocalAddress] - }, - connector: client[kConnector] - }); - } - - try { - const socket = await new Promise((resolve, reject) => { - client[kConnector]({ - host, - hostname, - protocol, - port, - servername: client[kServerName], - localAddress: client[kLocalAddress] - }, (err, socket) => { - if (err) { - reject(err); - } else { - resolve(socket); - } - }); - }); - - if (client.destroyed) { - util.destroy(socket.on('error', () => {}), new ClientDestroyedError()); - return - } - - assert(socket); - - try { - client[kHTTPContext] = socket.alpnProtocol === 'h2' - ? await connectH2(client, socket) - : await connectH1(client, socket); - } catch (err) { - socket.destroy().on('error', () => {}); - throw err - } - - client[kConnecting] = false; - - socket[kCounter] = 0; - socket[kMaxRequests] = client[kMaxRequests]; - socket[kClient] = client; - socket[kError] = null; - - if (channels.connected.hasSubscribers) { - channels.connected.publish({ - connectParams: { - host, - hostname, - protocol, - port, - version: client[kHTTPContext]?.version, - servername: client[kServerName], - localAddress: client[kLocalAddress] - }, - connector: client[kConnector], - socket - }); - } - client.emit('connect', client[kUrl], [client]); - } catch (err) { - if (client.destroyed) { - return - } - - client[kConnecting] = false; - - if (channels.connectError.hasSubscribers) { - channels.connectError.publish({ - connectParams: { - host, - hostname, - protocol, - port, - version: client[kHTTPContext]?.version, - servername: client[kServerName], - localAddress: client[kLocalAddress] - }, - connector: client[kConnector], - error: err - }); - } - - if (err.code === 'ERR_TLS_CERT_ALTNAME_INVALID') { - assert(client[kRunning] === 0); - while (client[kPending] > 0 && client[kQueue][client[kPendingIdx]].servername === client[kServerName]) { - const request = client[kQueue][client[kPendingIdx]++]; - util.errorRequest(client, request, err); - } - } else { - onError(client, err); - } - - client.emit('connectionError', client[kUrl], [client], err); - } - - client[kResume](); - } - - function emitDrain (client) { - client[kNeedDrain] = 0; - client.emit('drain', client[kUrl], [client]); - } - - function resume (client, sync) { - if (client[kResuming] === 2) { - return - } - - client[kResuming] = 2; - - _resume(client, sync); - client[kResuming] = 0; - - if (client[kRunningIdx] > 256) { - client[kQueue].splice(0, client[kRunningIdx]); - client[kPendingIdx] -= client[kRunningIdx]; - client[kRunningIdx] = 0; - } - } - - function _resume (client, sync) { - while (true) { - if (client.destroyed) { - assert(client[kPending] === 0); - return - } - - if (client[kClosedResolve] && !client[kSize]) { - client[kClosedResolve](); - client[kClosedResolve] = null; - return - } - - if (client[kHTTPContext]) { - client[kHTTPContext].resume(); - } - - if (client[kBusy]) { - client[kNeedDrain] = 2; - } else if (client[kNeedDrain] === 2) { - if (sync) { - client[kNeedDrain] = 1; - queueMicrotask(() => emitDrain(client)); - } else { - emitDrain(client); - } - continue - } - - if (client[kPending] === 0) { - return - } - - if (client[kRunning] >= (getPipelining(client) || 1)) { - return - } - - const request = client[kQueue][client[kPendingIdx]]; - - if (client[kUrl].protocol === 'https:' && client[kServerName] !== request.servername) { - if (client[kRunning] > 0) { - return - } - - client[kServerName] = request.servername; - client[kHTTPContext]?.destroy(new InformationalError('servername changed'), () => { - client[kHTTPContext] = null; - resume(client); - }); - } - - if (client[kConnecting]) { - return - } - - if (!client[kHTTPContext]) { - connect(client); - return - } - - if (client[kHTTPContext].destroyed) { - return - } - - if (client[kHTTPContext].busy(request)) { - return - } - - if (!request.aborted && client[kHTTPContext].write(request)) { - client[kPendingIdx]++; - } else { - client[kQueue].splice(client[kPendingIdx], 1); - } - } - } - - client = Client; - return client; -} - -/* eslint-disable */ - -var fixedQueue; -var hasRequiredFixedQueue; - -function requireFixedQueue () { - if (hasRequiredFixedQueue) return fixedQueue; - hasRequiredFixedQueue = 1; - - // Extracted from node/lib/internal/fixed_queue.js - - // Currently optimal queue size, tested on V8 6.0 - 6.6. Must be power of two. - const kSize = 2048; - const kMask = kSize - 1; - - // The FixedQueue is implemented as a singly-linked list of fixed-size - // circular buffers. It looks something like this: - // - // head tail - // | | - // v v - // +-----------+ <-----\ +-----------+ <------\ +-----------+ - // | [null] | \----- | next | \------- | next | - // +-----------+ +-----------+ +-----------+ - // | item | <-- bottom | item | <-- bottom | [empty] | - // | item | | item | | [empty] | - // | item | | item | | [empty] | - // | item | | item | | [empty] | - // | item | | item | bottom --> | item | - // | item | | item | | item | - // | ... | | ... | | ... | - // | item | | item | | item | - // | item | | item | | item | - // | [empty] | <-- top | item | | item | - // | [empty] | | item | | item | - // | [empty] | | [empty] | <-- top top --> | [empty] | - // +-----------+ +-----------+ +-----------+ - // - // Or, if there is only one circular buffer, it looks something - // like either of these: - // - // head tail head tail - // | | | | - // v v v v - // +-----------+ +-----------+ - // | [null] | | [null] | - // +-----------+ +-----------+ - // | [empty] | | item | - // | [empty] | | item | - // | item | <-- bottom top --> | [empty] | - // | item | | [empty] | - // | [empty] | <-- top bottom --> | item | - // | [empty] | | item | - // +-----------+ +-----------+ - // - // Adding a value means moving `top` forward by one, removing means - // moving `bottom` forward by one. After reaching the end, the queue - // wraps around. - // - // When `top === bottom` the current queue is empty and when - // `top + 1 === bottom` it's full. This wastes a single space of storage - // but allows much quicker checks. - - class FixedCircularBuffer { - constructor() { - this.bottom = 0; - this.top = 0; - this.list = new Array(kSize); - this.next = null; - } - - isEmpty() { - return this.top === this.bottom; - } - - isFull() { - return ((this.top + 1) & kMask) === this.bottom; - } - - push(data) { - this.list[this.top] = data; - this.top = (this.top + 1) & kMask; - } - - shift() { - const nextItem = this.list[this.bottom]; - if (nextItem === undefined) - return null; - this.list[this.bottom] = undefined; - this.bottom = (this.bottom + 1) & kMask; - return nextItem; - } - } - - fixedQueue = class FixedQueue { - constructor() { - this.head = this.tail = new FixedCircularBuffer(); - } - - isEmpty() { - return this.head.isEmpty(); - } - - push(data) { - if (this.head.isFull()) { - // Head is full: Creates a new queue, sets the old queue's `.next` to it, - // and sets it as the new main queue. - this.head = this.head.next = new FixedCircularBuffer(); - } - this.head.push(data); - } - - shift() { - const tail = this.tail; - const next = tail.shift(); - if (tail.isEmpty() && tail.next !== null) { - // If there is another queue, it forms the new tail. - this.tail = tail.next; - } - return next; - } - }; - return fixedQueue; -} - -var poolStats; -var hasRequiredPoolStats; - -function requirePoolStats () { - if (hasRequiredPoolStats) return poolStats; - hasRequiredPoolStats = 1; - const { kFree, kConnected, kPending, kQueued, kRunning, kSize } = requireSymbols$4(); - const kPool = Symbol('pool'); - - class PoolStats { - constructor (pool) { - this[kPool] = pool; - } - - get connected () { - return this[kPool][kConnected] - } - - get free () { - return this[kPool][kFree] - } - - get pending () { - return this[kPool][kPending] - } - - get queued () { - return this[kPool][kQueued] - } - - get running () { - return this[kPool][kRunning] - } - - get size () { - return this[kPool][kSize] - } - } - - poolStats = PoolStats; - return poolStats; -} - -var poolBase; -var hasRequiredPoolBase; - -function requirePoolBase () { - if (hasRequiredPoolBase) return poolBase; - hasRequiredPoolBase = 1; - - const DispatcherBase = requireDispatcherBase(); - const FixedQueue = requireFixedQueue(); - const { kConnected, kSize, kRunning, kPending, kQueued, kBusy, kFree, kUrl, kClose, kDestroy, kDispatch } = requireSymbols$4(); - const PoolStats = requirePoolStats(); - - const kClients = Symbol('clients'); - const kNeedDrain = Symbol('needDrain'); - const kQueue = Symbol('queue'); - const kClosedResolve = Symbol('closed resolve'); - const kOnDrain = Symbol('onDrain'); - const kOnConnect = Symbol('onConnect'); - const kOnDisconnect = Symbol('onDisconnect'); - const kOnConnectionError = Symbol('onConnectionError'); - const kGetDispatcher = Symbol('get dispatcher'); - const kAddClient = Symbol('add client'); - const kRemoveClient = Symbol('remove client'); - const kStats = Symbol('stats'); - - class PoolBase extends DispatcherBase { - constructor () { - super(); - - this[kQueue] = new FixedQueue(); - this[kClients] = []; - this[kQueued] = 0; - - const pool = this; - - this[kOnDrain] = function onDrain (origin, targets) { - const queue = pool[kQueue]; - - let needDrain = false; - - while (!needDrain) { - const item = queue.shift(); - if (!item) { - break - } - pool[kQueued]--; - needDrain = !this.dispatch(item.opts, item.handler); - } - - this[kNeedDrain] = needDrain; - - if (!this[kNeedDrain] && pool[kNeedDrain]) { - pool[kNeedDrain] = false; - pool.emit('drain', origin, [pool, ...targets]); - } - - if (pool[kClosedResolve] && queue.isEmpty()) { - Promise - .all(pool[kClients].map(c => c.close())) - .then(pool[kClosedResolve]); - } - }; - - this[kOnConnect] = (origin, targets) => { - pool.emit('connect', origin, [pool, ...targets]); - }; - - this[kOnDisconnect] = (origin, targets, err) => { - pool.emit('disconnect', origin, [pool, ...targets], err); - }; - - this[kOnConnectionError] = (origin, targets, err) => { - pool.emit('connectionError', origin, [pool, ...targets], err); - }; - - this[kStats] = new PoolStats(this); - } - - get [kBusy] () { - return this[kNeedDrain] - } - - get [kConnected] () { - return this[kClients].filter(client => client[kConnected]).length - } - - get [kFree] () { - return this[kClients].filter(client => client[kConnected] && !client[kNeedDrain]).length - } - - get [kPending] () { - let ret = this[kQueued]; - for (const { [kPending]: pending } of this[kClients]) { - ret += pending; - } - return ret - } - - get [kRunning] () { - let ret = 0; - for (const { [kRunning]: running } of this[kClients]) { - ret += running; - } - return ret - } - - get [kSize] () { - let ret = this[kQueued]; - for (const { [kSize]: size } of this[kClients]) { - ret += size; - } - return ret - } - - get stats () { - return this[kStats] - } - - async [kClose] () { - if (this[kQueue].isEmpty()) { - return Promise.all(this[kClients].map(c => c.close())) - } else { - return new Promise((resolve) => { - this[kClosedResolve] = resolve; - }) - } - } - - async [kDestroy] (err) { - while (true) { - const item = this[kQueue].shift(); - if (!item) { - break - } - item.handler.onError(err); - } - - return Promise.all(this[kClients].map(c => c.destroy(err))) - } - - [kDispatch] (opts, handler) { - const dispatcher = this[kGetDispatcher](); - - if (!dispatcher) { - this[kNeedDrain] = true; - this[kQueue].push({ opts, handler }); - this[kQueued]++; - } else if (!dispatcher.dispatch(opts, handler)) { - dispatcher[kNeedDrain] = true; - this[kNeedDrain] = !this[kGetDispatcher](); - } - - return !this[kNeedDrain] - } - - [kAddClient] (client) { - client - .on('drain', this[kOnDrain]) - .on('connect', this[kOnConnect]) - .on('disconnect', this[kOnDisconnect]) - .on('connectionError', this[kOnConnectionError]); - - this[kClients].push(client); - - if (this[kNeedDrain]) { - queueMicrotask(() => { - if (this[kNeedDrain]) { - this[kOnDrain](client[kUrl], [this, client]); - } - }); - } - - return this - } - - [kRemoveClient] (client) { - client.close(() => { - const idx = this[kClients].indexOf(client); - if (idx !== -1) { - this[kClients].splice(idx, 1); - } - }); - - this[kNeedDrain] = this[kClients].some(dispatcher => ( - !dispatcher[kNeedDrain] && - dispatcher.closed !== true && - dispatcher.destroyed !== true - )); - } - } - - poolBase = { - PoolBase, - kClients, - kNeedDrain, - kAddClient, - kRemoveClient, - kGetDispatcher - }; - return poolBase; -} - -var pool; -var hasRequiredPool; - -function requirePool () { - if (hasRequiredPool) return pool; - hasRequiredPool = 1; - - const { - PoolBase, - kClients, - kNeedDrain, - kAddClient, - kGetDispatcher - } = requirePoolBase(); - const Client = requireClient(); - const { - InvalidArgumentError - } = requireErrors(); - const util = requireUtil$7(); - const { kUrl, kInterceptors } = requireSymbols$4(); - const buildConnector = requireConnect(); - - const kOptions = Symbol('options'); - const kConnections = Symbol('connections'); - const kFactory = Symbol('factory'); - - function defaultFactory (origin, opts) { - return new Client(origin, opts) - } - - class Pool extends PoolBase { - constructor (origin, { - connections, - factory = defaultFactory, - connect, - connectTimeout, - tls, - maxCachedSessions, - socketPath, - autoSelectFamily, - autoSelectFamilyAttemptTimeout, - allowH2, - ...options - } = {}) { - super(); - - if (connections != null && (!Number.isFinite(connections) || connections < 0)) { - throw new InvalidArgumentError('invalid connections') - } - - if (typeof factory !== 'function') { - throw new InvalidArgumentError('factory must be a function.') - } - - if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') { - throw new InvalidArgumentError('connect must be a function or an object') - } - - if (typeof connect !== 'function') { - connect = buildConnector({ - ...tls, - maxCachedSessions, - allowH2, - socketPath, - timeout: connectTimeout, - ...(autoSelectFamily ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : undefined), - ...connect - }); - } - - this[kInterceptors] = options.interceptors?.Pool && Array.isArray(options.interceptors.Pool) - ? options.interceptors.Pool - : []; - this[kConnections] = connections || null; - this[kUrl] = util.parseOrigin(origin); - this[kOptions] = { ...util.deepClone(options), connect, allowH2 }; - this[kOptions].interceptors = options.interceptors - ? { ...options.interceptors } - : undefined; - this[kFactory] = factory; - } - - [kGetDispatcher] () { - for (const client of this[kClients]) { - if (!client[kNeedDrain]) { - return client - } - } - - if (!this[kConnections] || this[kClients].length < this[kConnections]) { - const dispatcher = this[kFactory](this[kUrl], this[kOptions]); - this[kAddClient](dispatcher); - return dispatcher - } - } - } - - pool = Pool; - return pool; -} - -var balancedPool; -var hasRequiredBalancedPool; - -function requireBalancedPool () { - if (hasRequiredBalancedPool) return balancedPool; - hasRequiredBalancedPool = 1; - - const { - BalancedPoolMissingUpstreamError, - InvalidArgumentError - } = requireErrors(); - const { - PoolBase, - kClients, - kNeedDrain, - kAddClient, - kRemoveClient, - kGetDispatcher - } = requirePoolBase(); - const Pool = requirePool(); - const { kUrl, kInterceptors } = requireSymbols$4(); - const { parseOrigin } = requireUtil$7(); - const kFactory = Symbol('factory'); - - const kOptions = Symbol('options'); - const kGreatestCommonDivisor = Symbol('kGreatestCommonDivisor'); - const kCurrentWeight = Symbol('kCurrentWeight'); - const kIndex = Symbol('kIndex'); - const kWeight = Symbol('kWeight'); - const kMaxWeightPerServer = Symbol('kMaxWeightPerServer'); - const kErrorPenalty = Symbol('kErrorPenalty'); - - function getGreatestCommonDivisor (a, b) { - if (b === 0) return a - return getGreatestCommonDivisor(b, a % b) - } - - function defaultFactory (origin, opts) { - return new Pool(origin, opts) - } - - class BalancedPool extends PoolBase { - constructor (upstreams = [], { factory = defaultFactory, ...opts } = {}) { - super(); - - this[kOptions] = opts; - this[kIndex] = -1; - this[kCurrentWeight] = 0; - - this[kMaxWeightPerServer] = this[kOptions].maxWeightPerServer || 100; - this[kErrorPenalty] = this[kOptions].errorPenalty || 15; - - if (!Array.isArray(upstreams)) { - upstreams = [upstreams]; - } - - if (typeof factory !== 'function') { - throw new InvalidArgumentError('factory must be a function.') - } - - this[kInterceptors] = opts.interceptors?.BalancedPool && Array.isArray(opts.interceptors.BalancedPool) - ? opts.interceptors.BalancedPool - : []; - this[kFactory] = factory; - - for (const upstream of upstreams) { - this.addUpstream(upstream); - } - this._updateBalancedPoolStats(); - } - - addUpstream (upstream) { - const upstreamOrigin = parseOrigin(upstream).origin; - - if (this[kClients].find((pool) => ( - pool[kUrl].origin === upstreamOrigin && - pool.closed !== true && - pool.destroyed !== true - ))) { - return this - } - const pool = this[kFactory](upstreamOrigin, Object.assign({}, this[kOptions])); - - this[kAddClient](pool); - pool.on('connect', () => { - pool[kWeight] = Math.min(this[kMaxWeightPerServer], pool[kWeight] + this[kErrorPenalty]); - }); - - pool.on('connectionError', () => { - pool[kWeight] = Math.max(1, pool[kWeight] - this[kErrorPenalty]); - this._updateBalancedPoolStats(); - }); - - pool.on('disconnect', (...args) => { - const err = args[2]; - if (err && err.code === 'UND_ERR_SOCKET') { - // decrease the weight of the pool. - pool[kWeight] = Math.max(1, pool[kWeight] - this[kErrorPenalty]); - this._updateBalancedPoolStats(); - } - }); - - for (const client of this[kClients]) { - client[kWeight] = this[kMaxWeightPerServer]; - } - - this._updateBalancedPoolStats(); - - return this - } - - _updateBalancedPoolStats () { - this[kGreatestCommonDivisor] = this[kClients].map(p => p[kWeight]).reduce(getGreatestCommonDivisor, 0); - } - - removeUpstream (upstream) { - const upstreamOrigin = parseOrigin(upstream).origin; - - const pool = this[kClients].find((pool) => ( - pool[kUrl].origin === upstreamOrigin && - pool.closed !== true && - pool.destroyed !== true - )); - - if (pool) { - this[kRemoveClient](pool); - } - - return this - } - - get upstreams () { - return this[kClients] - .filter(dispatcher => dispatcher.closed !== true && dispatcher.destroyed !== true) - .map((p) => p[kUrl].origin) - } - - [kGetDispatcher] () { - // We validate that pools is greater than 0, - // otherwise we would have to wait until an upstream - // is added, which might never happen. - if (this[kClients].length === 0) { - throw new BalancedPoolMissingUpstreamError() - } - - const dispatcher = this[kClients].find(dispatcher => ( - !dispatcher[kNeedDrain] && - dispatcher.closed !== true && - dispatcher.destroyed !== true - )); - - if (!dispatcher) { - return - } - - const allClientsBusy = this[kClients].map(pool => pool[kNeedDrain]).reduce((a, b) => a && b, true); - - if (allClientsBusy) { - return - } - - let counter = 0; - - let maxWeightIndex = this[kClients].findIndex(pool => !pool[kNeedDrain]); - - while (counter++ < this[kClients].length) { - this[kIndex] = (this[kIndex] + 1) % this[kClients].length; - const pool = this[kClients][this[kIndex]]; - - // find pool index with the largest weight - if (pool[kWeight] > this[kClients][maxWeightIndex][kWeight] && !pool[kNeedDrain]) { - maxWeightIndex = this[kIndex]; - } - - // decrease the current weight every `this[kClients].length`. - if (this[kIndex] === 0) { - // Set the current weight to the next lower weight. - this[kCurrentWeight] = this[kCurrentWeight] - this[kGreatestCommonDivisor]; - - if (this[kCurrentWeight] <= 0) { - this[kCurrentWeight] = this[kMaxWeightPerServer]; - } - } - if (pool[kWeight] >= this[kCurrentWeight] && (!pool[kNeedDrain])) { - return pool - } - } - - this[kCurrentWeight] = this[kClients][maxWeightIndex][kWeight]; - this[kIndex] = maxWeightIndex; - return this[kClients][maxWeightIndex] - } - } - - balancedPool = BalancedPool; - return balancedPool; -} - -var agent; -var hasRequiredAgent; - -function requireAgent () { - if (hasRequiredAgent) return agent; - hasRequiredAgent = 1; - - const { InvalidArgumentError } = requireErrors(); - const { kClients, kRunning, kClose, kDestroy, kDispatch, kInterceptors } = requireSymbols$4(); - const DispatcherBase = requireDispatcherBase(); - const Pool = requirePool(); - const Client = requireClient(); - const util = requireUtil$7(); - const createRedirectInterceptor = requireRedirectInterceptor(); - - const kOnConnect = Symbol('onConnect'); - const kOnDisconnect = Symbol('onDisconnect'); - const kOnConnectionError = Symbol('onConnectionError'); - const kMaxRedirections = Symbol('maxRedirections'); - const kOnDrain = Symbol('onDrain'); - const kFactory = Symbol('factory'); - const kOptions = Symbol('options'); - - function defaultFactory (origin, opts) { - return opts && opts.connections === 1 - ? new Client(origin, opts) - : new Pool(origin, opts) - } - - class Agent extends DispatcherBase { - constructor ({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { - super(); - - if (typeof factory !== 'function') { - throw new InvalidArgumentError('factory must be a function.') - } - - if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') { - throw new InvalidArgumentError('connect must be a function or an object') - } - - if (!Number.isInteger(maxRedirections) || maxRedirections < 0) { - throw new InvalidArgumentError('maxRedirections must be a positive number') - } - - if (connect && typeof connect !== 'function') { - connect = { ...connect }; - } - - this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent) - ? options.interceptors.Agent - : [createRedirectInterceptor({ maxRedirections })]; - - this[kOptions] = { ...util.deepClone(options), connect }; - this[kOptions].interceptors = options.interceptors - ? { ...options.interceptors } - : undefined; - this[kMaxRedirections] = maxRedirections; - this[kFactory] = factory; - this[kClients] = new Map(); - - this[kOnDrain] = (origin, targets) => { - this.emit('drain', origin, [this, ...targets]); - }; - - this[kOnConnect] = (origin, targets) => { - this.emit('connect', origin, [this, ...targets]); - }; - - this[kOnDisconnect] = (origin, targets, err) => { - this.emit('disconnect', origin, [this, ...targets], err); - }; - - this[kOnConnectionError] = (origin, targets, err) => { - this.emit('connectionError', origin, [this, ...targets], err); - }; - } - - get [kRunning] () { - let ret = 0; - for (const client of this[kClients].values()) { - ret += client[kRunning]; - } - return ret - } - - [kDispatch] (opts, handler) { - let key; - if (opts.origin && (typeof opts.origin === 'string' || opts.origin instanceof URL)) { - key = String(opts.origin); - } else { - throw new InvalidArgumentError('opts.origin must be a non-empty string or URL.') - } - - let dispatcher = this[kClients].get(key); - - if (!dispatcher) { - dispatcher = this[kFactory](opts.origin, this[kOptions]) - .on('drain', this[kOnDrain]) - .on('connect', this[kOnConnect]) - .on('disconnect', this[kOnDisconnect]) - .on('connectionError', this[kOnConnectionError]); - - // This introduces a tiny memory leak, as dispatchers are never removed from the map. - // TODO(mcollina): remove te timer when the client/pool do not have any more - // active connections. - this[kClients].set(key, dispatcher); - } - - return dispatcher.dispatch(opts, handler) - } - - async [kClose] () { - const closePromises = []; - for (const client of this[kClients].values()) { - closePromises.push(client.close()); - } - this[kClients].clear(); - - await Promise.all(closePromises); - } - - async [kDestroy] (err) { - const destroyPromises = []; - for (const client of this[kClients].values()) { - destroyPromises.push(client.destroy(err)); - } - this[kClients].clear(); - - await Promise.all(destroyPromises); - } - } - - agent = Agent; - return agent; -} - -var proxyAgent; -var hasRequiredProxyAgent; - -function requireProxyAgent () { - if (hasRequiredProxyAgent) return proxyAgent; - hasRequiredProxyAgent = 1; - - const { kProxy, kClose, kDestroy, kInterceptors } = requireSymbols$4(); - const { URL } = url; - const Agent = requireAgent(); - const Pool = requirePool(); - const DispatcherBase = requireDispatcherBase(); - const { InvalidArgumentError, RequestAbortedError, SecureProxyConnectionError } = requireErrors(); - const buildConnector = requireConnect(); - - const kAgent = Symbol('proxy agent'); - const kClient = Symbol('proxy client'); - const kProxyHeaders = Symbol('proxy headers'); - const kRequestTls = Symbol('request tls settings'); - const kProxyTls = Symbol('proxy tls settings'); - const kConnectEndpoint = Symbol('connect endpoint function'); - - function defaultProtocolPort (protocol) { - return protocol === 'https:' ? 443 : 80 - } - - function defaultFactory (origin, opts) { - return new Pool(origin, opts) - } - - class ProxyAgent extends DispatcherBase { - constructor (opts) { - super(); - - if (!opts || (typeof opts === 'object' && !(opts instanceof URL) && !opts.uri)) { - throw new InvalidArgumentError('Proxy uri is mandatory') - } - - const { clientFactory = defaultFactory } = opts; - if (typeof clientFactory !== 'function') { - throw new InvalidArgumentError('Proxy opts.clientFactory must be a function.') - } - - const url = this.#getUrl(opts); - const { href, origin, port, protocol, username, password, hostname: proxyHostname } = url; - - this[kProxy] = { uri: href, protocol }; - this[kInterceptors] = opts.interceptors?.ProxyAgent && Array.isArray(opts.interceptors.ProxyAgent) - ? opts.interceptors.ProxyAgent - : []; - this[kRequestTls] = opts.requestTls; - this[kProxyTls] = opts.proxyTls; - this[kProxyHeaders] = opts.headers || {}; - - if (opts.auth && opts.token) { - throw new InvalidArgumentError('opts.auth cannot be used in combination with opts.token') - } else if (opts.auth) { - /* @deprecated in favour of opts.token */ - this[kProxyHeaders]['proxy-authorization'] = `Basic ${opts.auth}`; - } else if (opts.token) { - this[kProxyHeaders]['proxy-authorization'] = opts.token; - } else if (username && password) { - this[kProxyHeaders]['proxy-authorization'] = `Basic ${Buffer.from(`${decodeURIComponent(username)}:${decodeURIComponent(password)}`).toString('base64')}`; - } - - const connect = buildConnector({ ...opts.proxyTls }); - this[kConnectEndpoint] = buildConnector({ ...opts.requestTls }); - this[kClient] = clientFactory(url, { connect }); - this[kAgent] = new Agent({ - ...opts, - connect: async (opts, callback) => { - let requestedPath = opts.host; - if (!opts.port) { - requestedPath += `:${defaultProtocolPort(opts.protocol)}`; - } - try { - const { socket, statusCode } = await this[kClient].connect({ - origin, - port, - path: requestedPath, - signal: opts.signal, - headers: { - ...this[kProxyHeaders], - host: opts.host - }, - servername: this[kProxyTls]?.servername || proxyHostname - }); - if (statusCode !== 200) { - socket.on('error', () => {}).destroy(); - callback(new RequestAbortedError(`Proxy response (${statusCode}) !== 200 when HTTP Tunneling`)); - } - if (opts.protocol !== 'https:') { - callback(null, socket); - return - } - let servername; - if (this[kRequestTls]) { - servername = this[kRequestTls].servername; - } else { - servername = opts.servername; - } - this[kConnectEndpoint]({ ...opts, servername, httpSocket: socket }, callback); - } catch (err) { - if (err.code === 'ERR_TLS_CERT_ALTNAME_INVALID') { - // Throw a custom error to avoid loop in client.js#connect - callback(new SecureProxyConnectionError(err)); - } else { - callback(err); - } - } - } - }); - } - - dispatch (opts, handler) { - const headers = buildHeaders(opts.headers); - throwIfProxyAuthIsSent(headers); - - if (headers && !('host' in headers) && !('Host' in headers)) { - const { host } = new URL(opts.origin); - headers.host = host; - } - - return this[kAgent].dispatch( - { - ...opts, - headers - }, - handler - ) - } - - /** - * @param {import('../types/proxy-agent').ProxyAgent.Options | string | URL} opts - * @returns {URL} - */ - #getUrl (opts) { - if (typeof opts === 'string') { - return new URL(opts) - } else if (opts instanceof URL) { - return opts - } else { - return new URL(opts.uri) - } - } - - async [kClose] () { - await this[kAgent].close(); - await this[kClient].close(); - } - - async [kDestroy] () { - await this[kAgent].destroy(); - await this[kClient].destroy(); - } - } - - /** - * @param {string[] | Record} headers - * @returns {Record} - */ - function buildHeaders (headers) { - // When using undici.fetch, the headers list is stored - // as an array. - if (Array.isArray(headers)) { - /** @type {Record} */ - const headersPair = {}; - - for (let i = 0; i < headers.length; i += 2) { - headersPair[headers[i]] = headers[i + 1]; - } - - return headersPair - } - - return headers - } - - /** - * @param {Record} headers - * - * Previous versions of ProxyAgent suggests the Proxy-Authorization in request headers - * Nevertheless, it was changed and to avoid a security vulnerability by end users - * this check was created. - * It should be removed in the next major version for performance reasons - */ - function throwIfProxyAuthIsSent (headers) { - const existProxyAuth = headers && Object.keys(headers) - .find((key) => key.toLowerCase() === 'proxy-authorization'); - if (existProxyAuth) { - throw new InvalidArgumentError('Proxy-Authorization should be sent in ProxyAgent constructor') - } - } - - proxyAgent = ProxyAgent; - return proxyAgent; -} - -var envHttpProxyAgent; -var hasRequiredEnvHttpProxyAgent; - -function requireEnvHttpProxyAgent () { - if (hasRequiredEnvHttpProxyAgent) return envHttpProxyAgent; - hasRequiredEnvHttpProxyAgent = 1; - - const DispatcherBase = requireDispatcherBase(); - const { kClose, kDestroy, kClosed, kDestroyed, kDispatch, kNoProxyAgent, kHttpProxyAgent, kHttpsProxyAgent } = requireSymbols$4(); - const ProxyAgent = requireProxyAgent(); - const Agent = requireAgent(); - - const DEFAULT_PORTS = { - 'http:': 80, - 'https:': 443 - }; - - let experimentalWarned = false; - - class EnvHttpProxyAgent extends DispatcherBase { - #noProxyValue = null - #noProxyEntries = null - #opts = null - - constructor (opts = {}) { - super(); - this.#opts = opts; - - if (!experimentalWarned) { - experimentalWarned = true; - process.emitWarning('EnvHttpProxyAgent is experimental, expect them to change at any time.', { - code: 'UNDICI-EHPA' - }); - } - - const { httpProxy, httpsProxy, noProxy, ...agentOpts } = opts; - - this[kNoProxyAgent] = new Agent(agentOpts); - - const HTTP_PROXY = httpProxy ?? process.env.http_proxy ?? process.env.HTTP_PROXY; - if (HTTP_PROXY) { - this[kHttpProxyAgent] = new ProxyAgent({ ...agentOpts, uri: HTTP_PROXY }); - } else { - this[kHttpProxyAgent] = this[kNoProxyAgent]; - } - - const HTTPS_PROXY = httpsProxy ?? process.env.https_proxy ?? process.env.HTTPS_PROXY; - if (HTTPS_PROXY) { - this[kHttpsProxyAgent] = new ProxyAgent({ ...agentOpts, uri: HTTPS_PROXY }); - } else { - this[kHttpsProxyAgent] = this[kHttpProxyAgent]; - } - - this.#parseNoProxy(); - } - - [kDispatch] (opts, handler) { - const url = new URL(opts.origin); - const agent = this.#getProxyAgentForUrl(url); - return agent.dispatch(opts, handler) - } - - async [kClose] () { - await this[kNoProxyAgent].close(); - if (!this[kHttpProxyAgent][kClosed]) { - await this[kHttpProxyAgent].close(); - } - if (!this[kHttpsProxyAgent][kClosed]) { - await this[kHttpsProxyAgent].close(); - } - } - - async [kDestroy] (err) { - await this[kNoProxyAgent].destroy(err); - if (!this[kHttpProxyAgent][kDestroyed]) { - await this[kHttpProxyAgent].destroy(err); - } - if (!this[kHttpsProxyAgent][kDestroyed]) { - await this[kHttpsProxyAgent].destroy(err); - } - } - - #getProxyAgentForUrl (url) { - let { protocol, host: hostname, port } = url; - - // Stripping ports in this way instead of using parsedUrl.hostname to make - // sure that the brackets around IPv6 addresses are kept. - hostname = hostname.replace(/:\d*$/, '').toLowerCase(); - port = Number.parseInt(port, 10) || DEFAULT_PORTS[protocol] || 0; - if (!this.#shouldProxy(hostname, port)) { - return this[kNoProxyAgent] - } - if (protocol === 'https:') { - return this[kHttpsProxyAgent] - } - return this[kHttpProxyAgent] - } - - #shouldProxy (hostname, port) { - if (this.#noProxyChanged) { - this.#parseNoProxy(); - } - - if (this.#noProxyEntries.length === 0) { - return true // Always proxy if NO_PROXY is not set or empty. - } - if (this.#noProxyValue === '*') { - return false // Never proxy if wildcard is set. - } - - for (let i = 0; i < this.#noProxyEntries.length; i++) { - const entry = this.#noProxyEntries[i]; - if (entry.port && entry.port !== port) { - continue // Skip if ports don't match. - } - if (!/^[.*]/.test(entry.hostname)) { - // No wildcards, so don't proxy only if there is not an exact match. - if (hostname === entry.hostname) { - return false - } - } else { - // Don't proxy if the hostname ends with the no_proxy host. - if (hostname.endsWith(entry.hostname.replace(/^\*/, ''))) { - return false - } - } - } - - return true - } - - #parseNoProxy () { - const noProxyValue = this.#opts.noProxy ?? this.#noProxyEnv; - const noProxySplit = noProxyValue.split(/[,\s]/); - const noProxyEntries = []; - - for (let i = 0; i < noProxySplit.length; i++) { - const entry = noProxySplit[i]; - if (!entry) { - continue - } - const parsed = entry.match(/^(.+):(\d+)$/); - noProxyEntries.push({ - hostname: (parsed ? parsed[1] : entry).toLowerCase(), - port: parsed ? Number.parseInt(parsed[2], 10) : 0 - }); - } - - this.#noProxyValue = noProxyValue; - this.#noProxyEntries = noProxyEntries; - } - - get #noProxyChanged () { - if (this.#opts.noProxy !== undefined) { - return false - } - return this.#noProxyValue !== this.#noProxyEnv - } - - get #noProxyEnv () { - return process.env.no_proxy ?? process.env.NO_PROXY ?? '' - } - } - - envHttpProxyAgent = EnvHttpProxyAgent; - return envHttpProxyAgent; -} - -var retryHandler; -var hasRequiredRetryHandler; - -function requireRetryHandler () { - if (hasRequiredRetryHandler) return retryHandler; - hasRequiredRetryHandler = 1; - const assert = require$$0$4; - - const { kRetryHandlerDefaultRetry } = requireSymbols$4(); - const { RequestRetryError } = requireErrors(); - const { - isDisturbed, - parseHeaders, - parseRangeHeader, - wrapRequestBody - } = requireUtil$7(); - - function calculateRetryAfterHeader (retryAfter) { - const current = Date.now(); - return new Date(retryAfter).getTime() - current - } - - class RetryHandler { - constructor (opts, handlers) { - const { retryOptions, ...dispatchOpts } = opts; - const { - // Retry scoped - retry: retryFn, - maxRetries, - maxTimeout, - minTimeout, - timeoutFactor, - // Response scoped - methods, - errorCodes, - retryAfter, - statusCodes - } = retryOptions ?? {}; - - this.dispatch = handlers.dispatch; - this.handler = handlers.handler; - this.opts = { ...dispatchOpts, body: wrapRequestBody(opts.body) }; - this.abort = null; - this.aborted = false; - this.retryOpts = { - retry: retryFn ?? RetryHandler[kRetryHandlerDefaultRetry], - retryAfter: retryAfter ?? true, - maxTimeout: maxTimeout ?? 30 * 1000, // 30s, - minTimeout: minTimeout ?? 500, // .5s - timeoutFactor: timeoutFactor ?? 2, - maxRetries: maxRetries ?? 5, - // What errors we should retry - methods: methods ?? ['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE', 'TRACE'], - // Indicates which errors to retry - statusCodes: statusCodes ?? [500, 502, 503, 504, 429], - // List of errors to retry - errorCodes: errorCodes ?? [ - 'ECONNRESET', - 'ECONNREFUSED', - 'ENOTFOUND', - 'ENETDOWN', - 'ENETUNREACH', - 'EHOSTDOWN', - 'EHOSTUNREACH', - 'EPIPE', - 'UND_ERR_SOCKET' - ] - }; - - this.retryCount = 0; - this.retryCountCheckpoint = 0; - this.start = 0; - this.end = null; - this.etag = null; - this.resume = null; - - // Handle possible onConnect duplication - this.handler.onConnect(reason => { - this.aborted = true; - if (this.abort) { - this.abort(reason); - } else { - this.reason = reason; - } - }); - } - - onRequestSent () { - if (this.handler.onRequestSent) { - this.handler.onRequestSent(); - } - } - - onUpgrade (statusCode, headers, socket) { - if (this.handler.onUpgrade) { - this.handler.onUpgrade(statusCode, headers, socket); - } - } - - onConnect (abort) { - if (this.aborted) { - abort(this.reason); - } else { - this.abort = abort; - } - } - - onBodySent (chunk) { - if (this.handler.onBodySent) return this.handler.onBodySent(chunk) - } - - static [kRetryHandlerDefaultRetry] (err, { state, opts }, cb) { - const { statusCode, code, headers } = err; - const { method, retryOptions } = opts; - const { - maxRetries, - minTimeout, - maxTimeout, - timeoutFactor, - statusCodes, - errorCodes, - methods - } = retryOptions; - const { counter } = state; - - // Any code that is not a Undici's originated and allowed to retry - if (code && code !== 'UND_ERR_REQ_RETRY' && !errorCodes.includes(code)) { - cb(err); - return - } - - // If a set of method are provided and the current method is not in the list - if (Array.isArray(methods) && !methods.includes(method)) { - cb(err); - return - } - - // If a set of status code are provided and the current status code is not in the list - if ( - statusCode != null && - Array.isArray(statusCodes) && - !statusCodes.includes(statusCode) - ) { - cb(err); - return - } - - // If we reached the max number of retries - if (counter > maxRetries) { - cb(err); - return - } - - let retryAfterHeader = headers?.['retry-after']; - if (retryAfterHeader) { - retryAfterHeader = Number(retryAfterHeader); - retryAfterHeader = Number.isNaN(retryAfterHeader) - ? calculateRetryAfterHeader(retryAfterHeader) - : retryAfterHeader * 1e3; // Retry-After is in seconds - } - - const retryTimeout = - retryAfterHeader > 0 - ? Math.min(retryAfterHeader, maxTimeout) - : Math.min(minTimeout * timeoutFactor ** (counter - 1), maxTimeout); - - setTimeout(() => cb(null), retryTimeout); - } - - onHeaders (statusCode, rawHeaders, resume, statusMessage) { - const headers = parseHeaders(rawHeaders); - - this.retryCount += 1; - - if (statusCode >= 300) { - if (this.retryOpts.statusCodes.includes(statusCode) === false) { - return this.handler.onHeaders( - statusCode, - rawHeaders, - resume, - statusMessage - ) - } else { - this.abort( - new RequestRetryError('Request failed', statusCode, { - headers, - data: { - count: this.retryCount - } - }) - ); - return false - } - } - - // Checkpoint for resume from where we left it - if (this.resume != null) { - this.resume = null; - - if (statusCode !== 206) { - return true - } - - const contentRange = parseRangeHeader(headers['content-range']); - // If no content range - if (!contentRange) { - this.abort( - new RequestRetryError('Content-Range mismatch', statusCode, { - headers, - data: { count: this.retryCount } - }) - ); - return false - } - - // Let's start with a weak etag check - if (this.etag != null && this.etag !== headers.etag) { - this.abort( - new RequestRetryError('ETag mismatch', statusCode, { - headers, - data: { count: this.retryCount } - }) - ); - return false - } - - const { start, size, end = size } = contentRange; - - assert(this.start === start, 'content-range mismatch'); - assert(this.end == null || this.end === end, 'content-range mismatch'); - - this.resume = resume; - return true - } - - if (this.end == null) { - if (statusCode === 206) { - // First time we receive 206 - const range = parseRangeHeader(headers['content-range']); - - if (range == null) { - return this.handler.onHeaders( - statusCode, - rawHeaders, - resume, - statusMessage - ) - } - - const { start, size, end = size } = range; - assert( - start != null && Number.isFinite(start), - 'content-range mismatch' - ); - assert(end != null && Number.isFinite(end), 'invalid content-length'); - - this.start = start; - this.end = end; - } - - // We make our best to checkpoint the body for further range headers - if (this.end == null) { - const contentLength = headers['content-length']; - this.end = contentLength != null ? Number(contentLength) : null; - } - - assert(Number.isFinite(this.start)); - assert( - this.end == null || Number.isFinite(this.end), - 'invalid content-length' - ); - - this.resume = resume; - this.etag = headers.etag != null ? headers.etag : null; - - // Weak etags are not useful for comparison nor cache - // for instance not safe to assume if the response is byte-per-byte - // equal - if (this.etag != null && this.etag.startsWith('W/')) { - this.etag = null; - } - - return this.handler.onHeaders( - statusCode, - rawHeaders, - resume, - statusMessage - ) - } - - const err = new RequestRetryError('Request failed', statusCode, { - headers, - data: { count: this.retryCount } - }); - - this.abort(err); - - return false - } - - onData (chunk) { - this.start += chunk.length; - - return this.handler.onData(chunk) - } - - onComplete (rawTrailers) { - this.retryCount = 0; - return this.handler.onComplete(rawTrailers) - } - - onError (err) { - if (this.aborted || isDisturbed(this.opts.body)) { - return this.handler.onError(err) - } - - // We reconcile in case of a mix between network errors - // and server error response - if (this.retryCount - this.retryCountCheckpoint > 0) { - // We count the difference between the last checkpoint and the current retry count - this.retryCount = - this.retryCountCheckpoint + - (this.retryCount - this.retryCountCheckpoint); - } else { - this.retryCount += 1; - } - - this.retryOpts.retry( - err, - { - state: { counter: this.retryCount }, - opts: { retryOptions: this.retryOpts, ...this.opts } - }, - onRetry.bind(this) - ); - - function onRetry (err) { - if (err != null || this.aborted || isDisturbed(this.opts.body)) { - return this.handler.onError(err) - } - - if (this.start !== 0) { - const headers = { range: `bytes=${this.start}-${this.end ?? ''}` }; - - // Weak etag check - weak etags will make comparison algorithms never match - if (this.etag != null) { - headers['if-match'] = this.etag; - } - - this.opts = { - ...this.opts, - headers: { - ...this.opts.headers, - ...headers - } - }; - } - - try { - this.retryCountCheckpoint = this.retryCount; - this.dispatch(this.opts, this); - } catch (err) { - this.handler.onError(err); - } - } - } - } - - retryHandler = RetryHandler; - return retryHandler; -} - -var retryAgent; -var hasRequiredRetryAgent; - -function requireRetryAgent () { - if (hasRequiredRetryAgent) return retryAgent; - hasRequiredRetryAgent = 1; - - const Dispatcher = requireDispatcher(); - const RetryHandler = requireRetryHandler(); - - class RetryAgent extends Dispatcher { - #agent = null - #options = null - constructor (agent, options = {}) { - super(options); - this.#agent = agent; - this.#options = options; - } - - dispatch (opts, handler) { - const retry = new RetryHandler({ - ...opts, - retryOptions: this.#options - }, { - dispatch: this.#agent.dispatch.bind(this.#agent), - handler - }); - return this.#agent.dispatch(opts, retry) - } - - close () { - return this.#agent.close() - } - - destroy () { - return this.#agent.destroy() - } - } - - retryAgent = RetryAgent; - return retryAgent; -} - -var api = {}; - -var apiRequest = {exports: {}}; - -var readable; -var hasRequiredReadable; - -function requireReadable () { - if (hasRequiredReadable) return readable; - hasRequiredReadable = 1; - - const assert = require$$0$4; - const { Readable } = require$$0$5; - const { RequestAbortedError, NotSupportedError, InvalidArgumentError, AbortError } = requireErrors(); - const util = requireUtil$7(); - const { ReadableStreamFrom } = requireUtil$7(); - - const kConsume = Symbol('kConsume'); - const kReading = Symbol('kReading'); - const kBody = Symbol('kBody'); - const kAbort = Symbol('kAbort'); - const kContentType = Symbol('kContentType'); - const kContentLength = Symbol('kContentLength'); - - const noop = () => {}; - - class BodyReadable extends Readable { - constructor ({ - resume, - abort, - contentType = '', - contentLength, - highWaterMark = 64 * 1024 // Same as nodejs fs streams. - }) { - super({ - autoDestroy: true, - read: resume, - highWaterMark - }); - - this._readableState.dataEmitted = false; - - this[kAbort] = abort; - this[kConsume] = null; - this[kBody] = null; - this[kContentType] = contentType; - this[kContentLength] = contentLength; - - // Is stream being consumed through Readable API? - // This is an optimization so that we avoid checking - // for 'data' and 'readable' listeners in the hot path - // inside push(). - this[kReading] = false; - } - - destroy (err) { - if (!err && !this._readableState.endEmitted) { - err = new RequestAbortedError(); - } - - if (err) { - this[kAbort](); - } - - return super.destroy(err) - } - - _destroy (err, callback) { - // Workaround for Node "bug". If the stream is destroyed in same - // tick as it is created, then a user who is waiting for a - // promise (i.e micro tick) for installing a 'error' listener will - // never get a chance and will always encounter an unhandled exception. - if (!this[kReading]) { - setImmediate(() => { - callback(err); - }); - } else { - callback(err); - } - } - - on (ev, ...args) { - if (ev === 'data' || ev === 'readable') { - this[kReading] = true; - } - return super.on(ev, ...args) - } - - addListener (ev, ...args) { - return this.on(ev, ...args) - } - - off (ev, ...args) { - const ret = super.off(ev, ...args); - if (ev === 'data' || ev === 'readable') { - this[kReading] = ( - this.listenerCount('data') > 0 || - this.listenerCount('readable') > 0 - ); - } - return ret - } - - removeListener (ev, ...args) { - return this.off(ev, ...args) - } - - push (chunk) { - if (this[kConsume] && chunk !== null) { - consumePush(this[kConsume], chunk); - return this[kReading] ? super.push(chunk) : true - } - return super.push(chunk) - } - - // https://fetch.spec.whatwg.org/#dom-body-text - async text () { - return consume(this, 'text') - } - - // https://fetch.spec.whatwg.org/#dom-body-json - async json () { - return consume(this, 'json') - } - - // https://fetch.spec.whatwg.org/#dom-body-blob - async blob () { - return consume(this, 'blob') - } - - // https://fetch.spec.whatwg.org/#dom-body-arraybuffer - async arrayBuffer () { - return consume(this, 'arrayBuffer') - } - - // https://fetch.spec.whatwg.org/#dom-body-formdata - async formData () { - // TODO: Implement. - throw new NotSupportedError() - } - - // https://fetch.spec.whatwg.org/#dom-body-bodyused - get bodyUsed () { - return util.isDisturbed(this) - } - - // https://fetch.spec.whatwg.org/#dom-body-body - get body () { - if (!this[kBody]) { - this[kBody] = ReadableStreamFrom(this); - if (this[kConsume]) { - // TODO: Is this the best way to force a lock? - this[kBody].getReader(); // Ensure stream is locked. - assert(this[kBody].locked); - } - } - return this[kBody] - } - - async dump (opts) { - let limit = Number.isFinite(opts?.limit) ? opts.limit : 128 * 1024; - const signal = opts?.signal; - - if (signal != null && (typeof signal !== 'object' || !('aborted' in signal))) { - throw new InvalidArgumentError('signal must be an AbortSignal') - } - - signal?.throwIfAborted(); - - if (this._readableState.closeEmitted) { - return null - } - - return await new Promise((resolve, reject) => { - if (this[kContentLength] > limit) { - this.destroy(new AbortError()); - } - - const onAbort = () => { - this.destroy(signal.reason ?? new AbortError()); - }; - signal?.addEventListener('abort', onAbort); - - this - .on('close', function () { - signal?.removeEventListener('abort', onAbort); - if (signal?.aborted) { - reject(signal.reason ?? new AbortError()); - } else { - resolve(null); - } - }) - .on('error', noop) - .on('data', function (chunk) { - limit -= chunk.length; - if (limit <= 0) { - this.destroy(); - } - }) - .resume(); - }) - } - } - - // https://streams.spec.whatwg.org/#readablestream-locked - function isLocked (self) { - // Consume is an implicit lock. - return (self[kBody] && self[kBody].locked === true) || self[kConsume] - } - - // https://fetch.spec.whatwg.org/#body-unusable - function isUnusable (self) { - return util.isDisturbed(self) || isLocked(self) - } - - async function consume (stream, type) { - assert(!stream[kConsume]); - - return new Promise((resolve, reject) => { - if (isUnusable(stream)) { - const rState = stream._readableState; - if (rState.destroyed && rState.closeEmitted === false) { - stream - .on('error', err => { - reject(err); - }) - .on('close', () => { - reject(new TypeError('unusable')); - }); - } else { - reject(rState.errored ?? new TypeError('unusable')); - } - } else { - queueMicrotask(() => { - stream[kConsume] = { - type, - stream, - resolve, - reject, - length: 0, - body: [] - }; - - stream - .on('error', function (err) { - consumeFinish(this[kConsume], err); - }) - .on('close', function () { - if (this[kConsume].body !== null) { - consumeFinish(this[kConsume], new RequestAbortedError()); - } - }); - - consumeStart(stream[kConsume]); - }); - } - }) - } - - function consumeStart (consume) { - if (consume.body === null) { - return - } - - const { _readableState: state } = consume.stream; - - if (state.bufferIndex) { - const start = state.bufferIndex; - const end = state.buffer.length; - for (let n = start; n < end; n++) { - consumePush(consume, state.buffer[n]); - } - } else { - for (const chunk of state.buffer) { - consumePush(consume, chunk); - } - } - - if (state.endEmitted) { - consumeEnd(this[kConsume]); - } else { - consume.stream.on('end', function () { - consumeEnd(this[kConsume]); - }); - } - - consume.stream.resume(); - - while (consume.stream.read() != null) { - // Loop - } - } - - /** - * @param {Buffer[]} chunks - * @param {number} length - */ - function chunksDecode (chunks, length) { - if (chunks.length === 0 || length === 0) { - return '' - } - const buffer = chunks.length === 1 ? chunks[0] : Buffer.concat(chunks, length); - const bufferLength = buffer.length; - - // Skip BOM. - const start = - bufferLength > 2 && - buffer[0] === 0xef && - buffer[1] === 0xbb && - buffer[2] === 0xbf - ? 3 - : 0; - return buffer.utf8Slice(start, bufferLength) - } - - function consumeEnd (consume) { - const { type, body, resolve, stream, length } = consume; - - try { - if (type === 'text') { - resolve(chunksDecode(body, length)); - } else if (type === 'json') { - resolve(JSON.parse(chunksDecode(body, length))); - } else if (type === 'arrayBuffer') { - const dst = new Uint8Array(length); - - let pos = 0; - for (const buf of body) { - dst.set(buf, pos); - pos += buf.byteLength; - } - - resolve(dst.buffer); - } else if (type === 'blob') { - resolve(new Blob(body, { type: stream[kContentType] })); - } - - consumeFinish(consume); - } catch (err) { - stream.destroy(err); - } - } - - function consumePush (consume, chunk) { - consume.length += chunk.length; - consume.body.push(chunk); - } - - function consumeFinish (consume, err) { - if (consume.body === null) { - return - } - - if (err) { - consume.reject(err); - } else { - consume.resolve(); - } - - consume.type = null; - consume.stream = null; - consume.resolve = null; - consume.reject = null; - consume.length = 0; - consume.body = null; - } - - readable = { Readable: BodyReadable, chunksDecode }; - return readable; -} - -var util$5; -var hasRequiredUtil$5; - -function requireUtil$5 () { - if (hasRequiredUtil$5) return util$5; - hasRequiredUtil$5 = 1; - const assert = require$$0$4; - const { - ResponseStatusCodeError - } = requireErrors(); - - const { chunksDecode } = requireReadable(); - const CHUNK_LIMIT = 128 * 1024; - - async function getResolveErrorBodyCallback ({ callback, body, contentType, statusCode, statusMessage, headers }) { - assert(body); - - let chunks = []; - let length = 0; - - try { - for await (const chunk of body) { - chunks.push(chunk); - length += chunk.length; - if (length > CHUNK_LIMIT) { - chunks = []; - length = 0; - break - } - } - } catch { - chunks = []; - length = 0; - // Do nothing.... - } - - const message = `Response status code ${statusCode}${statusMessage ? `: ${statusMessage}` : ''}`; - - if (statusCode === 204 || !contentType || !length) { - queueMicrotask(() => callback(new ResponseStatusCodeError(message, statusCode, headers))); - return - } - - const stackTraceLimit = Error.stackTraceLimit; - Error.stackTraceLimit = 0; - let payload; - - try { - if (isContentTypeApplicationJson(contentType)) { - payload = JSON.parse(chunksDecode(chunks, length)); - } else if (isContentTypeText(contentType)) { - payload = chunksDecode(chunks, length); - } - } catch { - // process in a callback to avoid throwing in the microtask queue - } finally { - Error.stackTraceLimit = stackTraceLimit; - } - queueMicrotask(() => callback(new ResponseStatusCodeError(message, statusCode, headers, payload))); - } - - const isContentTypeApplicationJson = (contentType) => { - return ( - contentType.length > 15 && - contentType[11] === '/' && - contentType[0] === 'a' && - contentType[1] === 'p' && - contentType[2] === 'p' && - contentType[3] === 'l' && - contentType[4] === 'i' && - contentType[5] === 'c' && - contentType[6] === 'a' && - contentType[7] === 't' && - contentType[8] === 'i' && - contentType[9] === 'o' && - contentType[10] === 'n' && - contentType[12] === 'j' && - contentType[13] === 's' && - contentType[14] === 'o' && - contentType[15] === 'n' - ) - }; - - const isContentTypeText = (contentType) => { - return ( - contentType.length > 4 && - contentType[4] === '/' && - contentType[0] === 't' && - contentType[1] === 'e' && - contentType[2] === 'x' && - contentType[3] === 't' - ) - }; - - util$5 = { - getResolveErrorBodyCallback, - isContentTypeApplicationJson, - isContentTypeText - }; - return util$5; -} - -var hasRequiredApiRequest; - -function requireApiRequest () { - if (hasRequiredApiRequest) return apiRequest.exports; - hasRequiredApiRequest = 1; - - const assert = require$$0$4; - const { Readable } = requireReadable(); - const { InvalidArgumentError, RequestAbortedError } = requireErrors(); - const util = requireUtil$7(); - const { getResolveErrorBodyCallback } = requireUtil$5(); - const { AsyncResource } = require$$5$1; - - class RequestHandler extends AsyncResource { - constructor (opts, callback) { - if (!opts || typeof opts !== 'object') { - throw new InvalidArgumentError('invalid opts') - } - - const { signal, method, opaque, body, onInfo, responseHeaders, throwOnError, highWaterMark } = opts; - - try { - if (typeof callback !== 'function') { - throw new InvalidArgumentError('invalid callback') - } - - if (highWaterMark && (typeof highWaterMark !== 'number' || highWaterMark < 0)) { - throw new InvalidArgumentError('invalid highWaterMark') - } - - if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { - throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') - } - - if (method === 'CONNECT') { - throw new InvalidArgumentError('invalid method') - } - - if (onInfo && typeof onInfo !== 'function') { - throw new InvalidArgumentError('invalid onInfo callback') - } - - super('UNDICI_REQUEST'); - } catch (err) { - if (util.isStream(body)) { - util.destroy(body.on('error', util.nop), err); - } - throw err - } - - this.method = method; - this.responseHeaders = responseHeaders || null; - this.opaque = opaque || null; - this.callback = callback; - this.res = null; - this.abort = null; - this.body = body; - this.trailers = {}; - this.context = null; - this.onInfo = onInfo || null; - this.throwOnError = throwOnError; - this.highWaterMark = highWaterMark; - this.signal = signal; - this.reason = null; - this.removeAbortListener = null; - - if (util.isStream(body)) { - body.on('error', (err) => { - this.onError(err); - }); - } - - if (this.signal) { - if (this.signal.aborted) { - this.reason = this.signal.reason ?? new RequestAbortedError(); - } else { - this.removeAbortListener = util.addAbortListener(this.signal, () => { - this.reason = this.signal.reason ?? new RequestAbortedError(); - if (this.res) { - util.destroy(this.res, this.reason); - } else if (this.abort) { - this.abort(this.reason); - } - - if (this.removeAbortListener) { - this.res?.off('close', this.removeAbortListener); - this.removeAbortListener(); - this.removeAbortListener = null; - } - }); - } - } - } - - onConnect (abort, context) { - if (this.reason) { - abort(this.reason); - return - } - - assert(this.callback); - - this.abort = abort; - this.context = context; - } - - onHeaders (statusCode, rawHeaders, resume, statusMessage) { - const { callback, opaque, abort, context, responseHeaders, highWaterMark } = this; - - const headers = responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders); - - if (statusCode < 200) { - if (this.onInfo) { - this.onInfo({ statusCode, headers }); - } - return - } - - const parsedHeaders = responseHeaders === 'raw' ? util.parseHeaders(rawHeaders) : headers; - const contentType = parsedHeaders['content-type']; - const contentLength = parsedHeaders['content-length']; - const res = new Readable({ - resume, - abort, - contentType, - contentLength: this.method !== 'HEAD' && contentLength - ? Number(contentLength) - : null, - highWaterMark - }); - - if (this.removeAbortListener) { - res.on('close', this.removeAbortListener); - } - - this.callback = null; - this.res = res; - if (callback !== null) { - if (this.throwOnError && statusCode >= 400) { - this.runInAsyncScope(getResolveErrorBodyCallback, null, - { callback, body: res, contentType, statusCode, statusMessage, headers } - ); - } else { - this.runInAsyncScope(callback, null, null, { - statusCode, - headers, - trailers: this.trailers, - opaque, - body: res, - context - }); - } - } - } - - onData (chunk) { - return this.res.push(chunk) - } - - onComplete (trailers) { - util.parseHeaders(trailers, this.trailers); - this.res.push(null); - } - - onError (err) { - const { res, callback, body, opaque } = this; - - if (callback) { - // TODO: Does this need queueMicrotask? - this.callback = null; - queueMicrotask(() => { - this.runInAsyncScope(callback, null, err, { opaque }); - }); - } - - if (res) { - this.res = null; - // Ensure all queued handlers are invoked before destroying res. - queueMicrotask(() => { - util.destroy(res, err); - }); - } - - if (body) { - this.body = null; - util.destroy(body, err); - } - - if (this.removeAbortListener) { - res?.off('close', this.removeAbortListener); - this.removeAbortListener(); - this.removeAbortListener = null; - } - } - } - - function request (opts, callback) { - if (callback === undefined) { - return new Promise((resolve, reject) => { - request.call(this, opts, (err, data) => { - return err ? reject(err) : resolve(data) - }); - }) - } - - try { - this.dispatch(opts, new RequestHandler(opts, callback)); - } catch (err) { - if (typeof callback !== 'function') { - throw err - } - const opaque = opts?.opaque; - queueMicrotask(() => callback(err, { opaque })); - } - } - - apiRequest.exports = request; - apiRequest.exports.RequestHandler = RequestHandler; - return apiRequest.exports; -} - -var abortSignal; -var hasRequiredAbortSignal; - -function requireAbortSignal () { - if (hasRequiredAbortSignal) return abortSignal; - hasRequiredAbortSignal = 1; - const { addAbortListener } = requireUtil$7(); - const { RequestAbortedError } = requireErrors(); - - const kListener = Symbol('kListener'); - const kSignal = Symbol('kSignal'); - - function abort (self) { - if (self.abort) { - self.abort(self[kSignal]?.reason); - } else { - self.reason = self[kSignal]?.reason ?? new RequestAbortedError(); - } - removeSignal(self); - } - - function addSignal (self, signal) { - self.reason = null; - - self[kSignal] = null; - self[kListener] = null; - - if (!signal) { - return - } - - if (signal.aborted) { - abort(self); - return - } - - self[kSignal] = signal; - self[kListener] = () => { - abort(self); - }; - - addAbortListener(self[kSignal], self[kListener]); - } - - function removeSignal (self) { - if (!self[kSignal]) { - return - } - - if ('removeEventListener' in self[kSignal]) { - self[kSignal].removeEventListener('abort', self[kListener]); - } else { - self[kSignal].removeListener('abort', self[kListener]); - } - - self[kSignal] = null; - self[kListener] = null; - } - - abortSignal = { - addSignal, - removeSignal - }; - return abortSignal; -} - -var apiStream; -var hasRequiredApiStream; - -function requireApiStream () { - if (hasRequiredApiStream) return apiStream; - hasRequiredApiStream = 1; - - const assert = require$$0$4; - const { finished, PassThrough } = require$$0$5; - const { InvalidArgumentError, InvalidReturnValueError } = requireErrors(); - const util = requireUtil$7(); - const { getResolveErrorBodyCallback } = requireUtil$5(); - const { AsyncResource } = require$$5$1; - const { addSignal, removeSignal } = requireAbortSignal(); - - class StreamHandler extends AsyncResource { - constructor (opts, factory, callback) { - if (!opts || typeof opts !== 'object') { - throw new InvalidArgumentError('invalid opts') - } - - const { signal, method, opaque, body, onInfo, responseHeaders, throwOnError } = opts; - - try { - if (typeof callback !== 'function') { - throw new InvalidArgumentError('invalid callback') - } - - if (typeof factory !== 'function') { - throw new InvalidArgumentError('invalid factory') - } - - if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { - throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') - } - - if (method === 'CONNECT') { - throw new InvalidArgumentError('invalid method') - } - - if (onInfo && typeof onInfo !== 'function') { - throw new InvalidArgumentError('invalid onInfo callback') - } - - super('UNDICI_STREAM'); - } catch (err) { - if (util.isStream(body)) { - util.destroy(body.on('error', util.nop), err); - } - throw err - } - - this.responseHeaders = responseHeaders || null; - this.opaque = opaque || null; - this.factory = factory; - this.callback = callback; - this.res = null; - this.abort = null; - this.context = null; - this.trailers = null; - this.body = body; - this.onInfo = onInfo || null; - this.throwOnError = throwOnError || false; - - if (util.isStream(body)) { - body.on('error', (err) => { - this.onError(err); - }); - } - - addSignal(this, signal); - } - - onConnect (abort, context) { - if (this.reason) { - abort(this.reason); - return - } - - assert(this.callback); - - this.abort = abort; - this.context = context; - } - - onHeaders (statusCode, rawHeaders, resume, statusMessage) { - const { factory, opaque, context, callback, responseHeaders } = this; - - const headers = responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders); - - if (statusCode < 200) { - if (this.onInfo) { - this.onInfo({ statusCode, headers }); - } - return - } - - this.factory = null; - - let res; - - if (this.throwOnError && statusCode >= 400) { - const parsedHeaders = responseHeaders === 'raw' ? util.parseHeaders(rawHeaders) : headers; - const contentType = parsedHeaders['content-type']; - res = new PassThrough(); - - this.callback = null; - this.runInAsyncScope(getResolveErrorBodyCallback, null, - { callback, body: res, contentType, statusCode, statusMessage, headers } - ); - } else { - if (factory === null) { - return - } - - res = this.runInAsyncScope(factory, null, { - statusCode, - headers, - opaque, - context - }); - - if ( - !res || - typeof res.write !== 'function' || - typeof res.end !== 'function' || - typeof res.on !== 'function' - ) { - throw new InvalidReturnValueError('expected Writable') - } - - // TODO: Avoid finished. It registers an unnecessary amount of listeners. - finished(res, { readable: false }, (err) => { - const { callback, res, opaque, trailers, abort } = this; - - this.res = null; - if (err || !res.readable) { - util.destroy(res, err); - } - - this.callback = null; - this.runInAsyncScope(callback, null, err || null, { opaque, trailers }); - - if (err) { - abort(); - } - }); - } - - res.on('drain', resume); - - this.res = res; - - const needDrain = res.writableNeedDrain !== undefined - ? res.writableNeedDrain - : res._writableState?.needDrain; - - return needDrain !== true - } - - onData (chunk) { - const { res } = this; - - return res ? res.write(chunk) : true - } - - onComplete (trailers) { - const { res } = this; - - removeSignal(this); - - if (!res) { - return - } - - this.trailers = util.parseHeaders(trailers); - - res.end(); - } - - onError (err) { - const { res, callback, opaque, body } = this; - - removeSignal(this); - - this.factory = null; - - if (res) { - this.res = null; - util.destroy(res, err); - } else if (callback) { - this.callback = null; - queueMicrotask(() => { - this.runInAsyncScope(callback, null, err, { opaque }); - }); - } - - if (body) { - this.body = null; - util.destroy(body, err); - } - } - } - - function stream (opts, factory, callback) { - if (callback === undefined) { - return new Promise((resolve, reject) => { - stream.call(this, opts, factory, (err, data) => { - return err ? reject(err) : resolve(data) - }); - }) - } - - try { - this.dispatch(opts, new StreamHandler(opts, factory, callback)); - } catch (err) { - if (typeof callback !== 'function') { - throw err - } - const opaque = opts?.opaque; - queueMicrotask(() => callback(err, { opaque })); - } - } - - apiStream = stream; - return apiStream; -} - -var apiPipeline; -var hasRequiredApiPipeline; - -function requireApiPipeline () { - if (hasRequiredApiPipeline) return apiPipeline; - hasRequiredApiPipeline = 1; - - const { - Readable, - Duplex, - PassThrough - } = require$$0$5; - const { - InvalidArgumentError, - InvalidReturnValueError, - RequestAbortedError - } = requireErrors(); - const util = requireUtil$7(); - const { AsyncResource } = require$$5$1; - const { addSignal, removeSignal } = requireAbortSignal(); - const assert = require$$0$4; - - const kResume = Symbol('resume'); - - class PipelineRequest extends Readable { - constructor () { - super({ autoDestroy: true }); - - this[kResume] = null; - } - - _read () { - const { [kResume]: resume } = this; - - if (resume) { - this[kResume] = null; - resume(); - } - } - - _destroy (err, callback) { - this._read(); - - callback(err); - } - } - - class PipelineResponse extends Readable { - constructor (resume) { - super({ autoDestroy: true }); - this[kResume] = resume; - } - - _read () { - this[kResume](); - } - - _destroy (err, callback) { - if (!err && !this._readableState.endEmitted) { - err = new RequestAbortedError(); - } - - callback(err); - } - } - - class PipelineHandler extends AsyncResource { - constructor (opts, handler) { - if (!opts || typeof opts !== 'object') { - throw new InvalidArgumentError('invalid opts') - } - - if (typeof handler !== 'function') { - throw new InvalidArgumentError('invalid handler') - } - - const { signal, method, opaque, onInfo, responseHeaders } = opts; - - if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { - throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') - } - - if (method === 'CONNECT') { - throw new InvalidArgumentError('invalid method') - } - - if (onInfo && typeof onInfo !== 'function') { - throw new InvalidArgumentError('invalid onInfo callback') - } - - super('UNDICI_PIPELINE'); - - this.opaque = opaque || null; - this.responseHeaders = responseHeaders || null; - this.handler = handler; - this.abort = null; - this.context = null; - this.onInfo = onInfo || null; - - this.req = new PipelineRequest().on('error', util.nop); - - this.ret = new Duplex({ - readableObjectMode: opts.objectMode, - autoDestroy: true, - read: () => { - const { body } = this; - - if (body?.resume) { - body.resume(); - } - }, - write: (chunk, encoding, callback) => { - const { req } = this; - - if (req.push(chunk, encoding) || req._readableState.destroyed) { - callback(); - } else { - req[kResume] = callback; - } - }, - destroy: (err, callback) => { - const { body, req, res, ret, abort } = this; - - if (!err && !ret._readableState.endEmitted) { - err = new RequestAbortedError(); - } - - if (abort && err) { - abort(); - } - - util.destroy(body, err); - util.destroy(req, err); - util.destroy(res, err); - - removeSignal(this); - - callback(err); - } - }).on('prefinish', () => { - const { req } = this; - - // Node < 15 does not call _final in same tick. - req.push(null); - }); - - this.res = null; - - addSignal(this, signal); - } - - onConnect (abort, context) { - const { ret, res } = this; - - if (this.reason) { - abort(this.reason); - return - } - - assert(!res, 'pipeline cannot be retried'); - assert(!ret.destroyed); - - this.abort = abort; - this.context = context; - } - - onHeaders (statusCode, rawHeaders, resume) { - const { opaque, handler, context } = this; - - if (statusCode < 200) { - if (this.onInfo) { - const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders); - this.onInfo({ statusCode, headers }); - } - return - } - - this.res = new PipelineResponse(resume); - - let body; - try { - this.handler = null; - const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders); - body = this.runInAsyncScope(handler, null, { - statusCode, - headers, - opaque, - body: this.res, - context - }); - } catch (err) { - this.res.on('error', util.nop); - throw err - } - - if (!body || typeof body.on !== 'function') { - throw new InvalidReturnValueError('expected Readable') - } - - body - .on('data', (chunk) => { - const { ret, body } = this; - - if (!ret.push(chunk) && body.pause) { - body.pause(); - } - }) - .on('error', (err) => { - const { ret } = this; - - util.destroy(ret, err); - }) - .on('end', () => { - const { ret } = this; - - ret.push(null); - }) - .on('close', () => { - const { ret } = this; - - if (!ret._readableState.ended) { - util.destroy(ret, new RequestAbortedError()); - } - }); - - this.body = body; - } - - onData (chunk) { - const { res } = this; - return res.push(chunk) - } - - onComplete (trailers) { - const { res } = this; - res.push(null); - } - - onError (err) { - const { ret } = this; - this.handler = null; - util.destroy(ret, err); - } - } - - function pipeline (opts, handler) { - try { - const pipelineHandler = new PipelineHandler(opts, handler); - this.dispatch({ ...opts, body: pipelineHandler.req }, pipelineHandler); - return pipelineHandler.ret - } catch (err) { - return new PassThrough().destroy(err) - } - } - - apiPipeline = pipeline; - return apiPipeline; -} - -var apiUpgrade; -var hasRequiredApiUpgrade; - -function requireApiUpgrade () { - if (hasRequiredApiUpgrade) return apiUpgrade; - hasRequiredApiUpgrade = 1; - - const { InvalidArgumentError, SocketError } = requireErrors(); - const { AsyncResource } = require$$5$1; - const util = requireUtil$7(); - const { addSignal, removeSignal } = requireAbortSignal(); - const assert = require$$0$4; - - class UpgradeHandler extends AsyncResource { - constructor (opts, callback) { - if (!opts || typeof opts !== 'object') { - throw new InvalidArgumentError('invalid opts') - } - - if (typeof callback !== 'function') { - throw new InvalidArgumentError('invalid callback') - } - - const { signal, opaque, responseHeaders } = opts; - - if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { - throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') - } - - super('UNDICI_UPGRADE'); - - this.responseHeaders = responseHeaders || null; - this.opaque = opaque || null; - this.callback = callback; - this.abort = null; - this.context = null; - - addSignal(this, signal); - } - - onConnect (abort, context) { - if (this.reason) { - abort(this.reason); - return - } - - assert(this.callback); - - this.abort = abort; - this.context = null; - } - - onHeaders () { - throw new SocketError('bad upgrade', null) - } - - onUpgrade (statusCode, rawHeaders, socket) { - const { callback, opaque, context } = this; - - assert.strictEqual(statusCode, 101); - - removeSignal(this); - - this.callback = null; - const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders); - this.runInAsyncScope(callback, null, null, { - headers, - socket, - opaque, - context - }); - } - - onError (err) { - const { callback, opaque } = this; - - removeSignal(this); - - if (callback) { - this.callback = null; - queueMicrotask(() => { - this.runInAsyncScope(callback, null, err, { opaque }); - }); - } - } - } - - function upgrade (opts, callback) { - if (callback === undefined) { - return new Promise((resolve, reject) => { - upgrade.call(this, opts, (err, data) => { - return err ? reject(err) : resolve(data) - }); - }) - } - - try { - const upgradeHandler = new UpgradeHandler(opts, callback); - this.dispatch({ - ...opts, - method: opts.method || 'GET', - upgrade: opts.protocol || 'Websocket' - }, upgradeHandler); - } catch (err) { - if (typeof callback !== 'function') { - throw err - } - const opaque = opts?.opaque; - queueMicrotask(() => callback(err, { opaque })); - } - } - - apiUpgrade = upgrade; - return apiUpgrade; -} - -var apiConnect; -var hasRequiredApiConnect; - -function requireApiConnect () { - if (hasRequiredApiConnect) return apiConnect; - hasRequiredApiConnect = 1; - - const assert = require$$0$4; - const { AsyncResource } = require$$5$1; - const { InvalidArgumentError, SocketError } = requireErrors(); - const util = requireUtil$7(); - const { addSignal, removeSignal } = requireAbortSignal(); - - class ConnectHandler extends AsyncResource { - constructor (opts, callback) { - if (!opts || typeof opts !== 'object') { - throw new InvalidArgumentError('invalid opts') - } - - if (typeof callback !== 'function') { - throw new InvalidArgumentError('invalid callback') - } - - const { signal, opaque, responseHeaders } = opts; - - if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { - throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') - } - - super('UNDICI_CONNECT'); - - this.opaque = opaque || null; - this.responseHeaders = responseHeaders || null; - this.callback = callback; - this.abort = null; - - addSignal(this, signal); - } - - onConnect (abort, context) { - if (this.reason) { - abort(this.reason); - return - } - - assert(this.callback); - - this.abort = abort; - this.context = context; - } - - onHeaders () { - throw new SocketError('bad connect', null) - } - - onUpgrade (statusCode, rawHeaders, socket) { - const { callback, opaque, context } = this; - - removeSignal(this); - - this.callback = null; - - let headers = rawHeaders; - // Indicates is an HTTP2Session - if (headers != null) { - headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders); - } - - this.runInAsyncScope(callback, null, null, { - statusCode, - headers, - socket, - opaque, - context - }); - } - - onError (err) { - const { callback, opaque } = this; - - removeSignal(this); - - if (callback) { - this.callback = null; - queueMicrotask(() => { - this.runInAsyncScope(callback, null, err, { opaque }); - }); - } - } - } - - function connect (opts, callback) { - if (callback === undefined) { - return new Promise((resolve, reject) => { - connect.call(this, opts, (err, data) => { - return err ? reject(err) : resolve(data) - }); - }) - } - - try { - const connectHandler = new ConnectHandler(opts, callback); - this.dispatch({ ...opts, method: 'CONNECT' }, connectHandler); - } catch (err) { - if (typeof callback !== 'function') { - throw err - } - const opaque = opts?.opaque; - queueMicrotask(() => callback(err, { opaque })); - } - } - - apiConnect = connect; - return apiConnect; -} - -var hasRequiredApi; - -function requireApi () { - if (hasRequiredApi) return api; - hasRequiredApi = 1; - - api.request = requireApiRequest(); - api.stream = requireApiStream(); - api.pipeline = requireApiPipeline(); - api.upgrade = requireApiUpgrade(); - api.connect = requireApiConnect(); - return api; -} - -var mockErrors; -var hasRequiredMockErrors; - -function requireMockErrors () { - if (hasRequiredMockErrors) return mockErrors; - hasRequiredMockErrors = 1; - - const { UndiciError } = requireErrors(); - - class MockNotMatchedError extends UndiciError { - constructor (message) { - super(message); - Error.captureStackTrace(this, MockNotMatchedError); - this.name = 'MockNotMatchedError'; - this.message = message || 'The request does not match any registered mock dispatches'; - this.code = 'UND_MOCK_ERR_MOCK_NOT_MATCHED'; - } - } - - mockErrors = { - MockNotMatchedError - }; - return mockErrors; -} - -var mockSymbols; -var hasRequiredMockSymbols; - -function requireMockSymbols () { - if (hasRequiredMockSymbols) return mockSymbols; - hasRequiredMockSymbols = 1; - - mockSymbols = { - kAgent: Symbol('agent'), - kOptions: Symbol('options'), - kFactory: Symbol('factory'), - kDispatches: Symbol('dispatches'), - kDispatchKey: Symbol('dispatch key'), - kDefaultHeaders: Symbol('default headers'), - kDefaultTrailers: Symbol('default trailers'), - kContentLength: Symbol('content length'), - kMockAgent: Symbol('mock agent'), - kMockAgentSet: Symbol('mock agent set'), - kMockAgentGet: Symbol('mock agent get'), - kMockDispatch: Symbol('mock dispatch'), - kClose: Symbol('close'), - kOriginalClose: Symbol('original agent close'), - kOrigin: Symbol('origin'), - kIsMockActive: Symbol('is mock active'), - kNetConnect: Symbol('net connect'), - kGetNetConnect: Symbol('get net connect'), - kConnected: Symbol('connected') - }; - return mockSymbols; -} - -var mockUtils; -var hasRequiredMockUtils; - -function requireMockUtils () { - if (hasRequiredMockUtils) return mockUtils; - hasRequiredMockUtils = 1; - - const { MockNotMatchedError } = requireMockErrors(); - const { - kDispatches, - kMockAgent, - kOriginalDispatch, - kOrigin, - kGetNetConnect - } = requireMockSymbols(); - const { buildURL } = requireUtil$7(); - const { STATUS_CODES } = require$$2; - const { - types: { - isPromise - } - } = require$$0$6; - - function matchValue (match, value) { - if (typeof match === 'string') { - return match === value - } - if (match instanceof RegExp) { - return match.test(value) - } - if (typeof match === 'function') { - return match(value) === true - } - return false - } - - function lowerCaseEntries (headers) { - return Object.fromEntries( - Object.entries(headers).map(([headerName, headerValue]) => { - return [headerName.toLocaleLowerCase(), headerValue] - }) - ) - } - - /** - * @param {import('../../index').Headers|string[]|Record} headers - * @param {string} key - */ - function getHeaderByName (headers, key) { - if (Array.isArray(headers)) { - for (let i = 0; i < headers.length; i += 2) { - if (headers[i].toLocaleLowerCase() === key.toLocaleLowerCase()) { - return headers[i + 1] - } - } - - return undefined - } else if (typeof headers.get === 'function') { - return headers.get(key) - } else { - return lowerCaseEntries(headers)[key.toLocaleLowerCase()] - } - } - - /** @param {string[]} headers */ - function buildHeadersFromArray (headers) { // fetch HeadersList - const clone = headers.slice(); - const entries = []; - for (let index = 0; index < clone.length; index += 2) { - entries.push([clone[index], clone[index + 1]]); - } - return Object.fromEntries(entries) - } - - function matchHeaders (mockDispatch, headers) { - if (typeof mockDispatch.headers === 'function') { - if (Array.isArray(headers)) { // fetch HeadersList - headers = buildHeadersFromArray(headers); - } - return mockDispatch.headers(headers ? lowerCaseEntries(headers) : {}) - } - if (typeof mockDispatch.headers === 'undefined') { - return true - } - if (typeof headers !== 'object' || typeof mockDispatch.headers !== 'object') { - return false - } - - for (const [matchHeaderName, matchHeaderValue] of Object.entries(mockDispatch.headers)) { - const headerValue = getHeaderByName(headers, matchHeaderName); - - if (!matchValue(matchHeaderValue, headerValue)) { - return false - } - } - return true - } - - function safeUrl (path) { - if (typeof path !== 'string') { - return path - } - - const pathSegments = path.split('?'); - - if (pathSegments.length !== 2) { - return path - } - - const qp = new URLSearchParams(pathSegments.pop()); - qp.sort(); - return [...pathSegments, qp.toString()].join('?') - } - - function matchKey (mockDispatch, { path, method, body, headers }) { - const pathMatch = matchValue(mockDispatch.path, path); - const methodMatch = matchValue(mockDispatch.method, method); - const bodyMatch = typeof mockDispatch.body !== 'undefined' ? matchValue(mockDispatch.body, body) : true; - const headersMatch = matchHeaders(mockDispatch, headers); - return pathMatch && methodMatch && bodyMatch && headersMatch - } - - function getResponseData (data) { - if (Buffer.isBuffer(data)) { - return data - } else if (typeof data === 'object') { - return JSON.stringify(data) - } else { - return data.toString() - } - } - - function getMockDispatch (mockDispatches, key) { - const basePath = key.query ? buildURL(key.path, key.query) : key.path; - const resolvedPath = typeof basePath === 'string' ? safeUrl(basePath) : basePath; - - // Match path - let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path }) => matchValue(safeUrl(path), resolvedPath)); - if (matchedMockDispatches.length === 0) { - throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`) - } - - // Match method - matchedMockDispatches = matchedMockDispatches.filter(({ method }) => matchValue(method, key.method)); - if (matchedMockDispatches.length === 0) { - throw new MockNotMatchedError(`Mock dispatch not matched for method '${key.method}' on path '${resolvedPath}'`) - } - - // Match body - matchedMockDispatches = matchedMockDispatches.filter(({ body }) => typeof body !== 'undefined' ? matchValue(body, key.body) : true); - if (matchedMockDispatches.length === 0) { - throw new MockNotMatchedError(`Mock dispatch not matched for body '${key.body}' on path '${resolvedPath}'`) - } - - // Match headers - matchedMockDispatches = matchedMockDispatches.filter((mockDispatch) => matchHeaders(mockDispatch, key.headers)); - if (matchedMockDispatches.length === 0) { - const headers = typeof key.headers === 'object' ? JSON.stringify(key.headers) : key.headers; - throw new MockNotMatchedError(`Mock dispatch not matched for headers '${headers}' on path '${resolvedPath}'`) - } - - return matchedMockDispatches[0] - } - - function addMockDispatch (mockDispatches, key, data) { - const baseData = { timesInvoked: 0, times: 1, persist: false, consumed: false }; - const replyData = typeof data === 'function' ? { callback: data } : { ...data }; - const newMockDispatch = { ...baseData, ...key, pending: true, data: { error: null, ...replyData } }; - mockDispatches.push(newMockDispatch); - return newMockDispatch - } - - function deleteMockDispatch (mockDispatches, key) { - const index = mockDispatches.findIndex(dispatch => { - if (!dispatch.consumed) { - return false - } - return matchKey(dispatch, key) - }); - if (index !== -1) { - mockDispatches.splice(index, 1); - } - } - - function buildKey (opts) { - const { path, method, body, headers, query } = opts; - return { - path, - method, - body, - headers, - query - } - } - - function generateKeyValues (data) { - const keys = Object.keys(data); - const result = []; - for (let i = 0; i < keys.length; ++i) { - const key = keys[i]; - const value = data[key]; - const name = Buffer.from(`${key}`); - if (Array.isArray(value)) { - for (let j = 0; j < value.length; ++j) { - result.push(name, Buffer.from(`${value[j]}`)); - } - } else { - result.push(name, Buffer.from(`${value}`)); - } - } - return result - } - - /** - * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status - * @param {number} statusCode - */ - function getStatusText (statusCode) { - return STATUS_CODES[statusCode] || 'unknown' - } - - async function getResponse (body) { - const buffers = []; - for await (const data of body) { - buffers.push(data); - } - return Buffer.concat(buffers).toString('utf8') - } - - /** - * Mock dispatch function used to simulate undici dispatches - */ - function mockDispatch (opts, handler) { - // Get mock dispatch from built key - const key = buildKey(opts); - const mockDispatch = getMockDispatch(this[kDispatches], key); - - mockDispatch.timesInvoked++; - - // Here's where we resolve a callback if a callback is present for the dispatch data. - if (mockDispatch.data.callback) { - mockDispatch.data = { ...mockDispatch.data, ...mockDispatch.data.callback(opts) }; - } - - // Parse mockDispatch data - const { data: { statusCode, data, headers, trailers, error }, delay, persist } = mockDispatch; - const { timesInvoked, times } = mockDispatch; - - // If it's used up and not persistent, mark as consumed - mockDispatch.consumed = !persist && timesInvoked >= times; - mockDispatch.pending = timesInvoked < times; - - // If specified, trigger dispatch error - if (error !== null) { - deleteMockDispatch(this[kDispatches], key); - handler.onError(error); - return true - } - - // Handle the request with a delay if necessary - if (typeof delay === 'number' && delay > 0) { - setTimeout(() => { - handleReply(this[kDispatches]); - }, delay); - } else { - handleReply(this[kDispatches]); - } - - function handleReply (mockDispatches, _data = data) { - // fetch's HeadersList is a 1D string array - const optsHeaders = Array.isArray(opts.headers) - ? buildHeadersFromArray(opts.headers) - : opts.headers; - const body = typeof _data === 'function' - ? _data({ ...opts, headers: optsHeaders }) - : _data; - - // util.types.isPromise is likely needed for jest. - if (isPromise(body)) { - // If handleReply is asynchronous, throwing an error - // in the callback will reject the promise, rather than - // synchronously throw the error, which breaks some tests. - // Rather, we wait for the callback to resolve if it is a - // promise, and then re-run handleReply with the new body. - body.then((newData) => handleReply(mockDispatches, newData)); - return - } - - const responseData = getResponseData(body); - const responseHeaders = generateKeyValues(headers); - const responseTrailers = generateKeyValues(trailers); - - handler.onConnect?.(err => handler.onError(err), null); - handler.onHeaders?.(statusCode, responseHeaders, resume, getStatusText(statusCode)); - handler.onData?.(Buffer.from(responseData)); - handler.onComplete?.(responseTrailers); - deleteMockDispatch(mockDispatches, key); - } - - function resume () {} - - return true - } - - function buildMockDispatch () { - const agent = this[kMockAgent]; - const origin = this[kOrigin]; - const originalDispatch = this[kOriginalDispatch]; - - return function dispatch (opts, handler) { - if (agent.isMockActive) { - try { - mockDispatch.call(this, opts, handler); - } catch (error) { - if (error instanceof MockNotMatchedError) { - const netConnect = agent[kGetNetConnect](); - if (netConnect === false) { - throw new MockNotMatchedError(`${error.message}: subsequent request to origin ${origin} was not allowed (net.connect disabled)`) - } - if (checkNetConnect(netConnect, origin)) { - originalDispatch.call(this, opts, handler); - } else { - throw new MockNotMatchedError(`${error.message}: subsequent request to origin ${origin} was not allowed (net.connect is not enabled for this origin)`) - } - } else { - throw error - } - } - } else { - originalDispatch.call(this, opts, handler); - } - } - } - - function checkNetConnect (netConnect, origin) { - const url = new URL(origin); - if (netConnect === true) { - return true - } else if (Array.isArray(netConnect) && netConnect.some((matcher) => matchValue(matcher, url.host))) { - return true - } - return false - } - - function buildMockOptions (opts) { - if (opts) { - const { agent, ...mockOptions } = opts; - return mockOptions - } - } - - mockUtils = { - getResponseData, - getMockDispatch, - addMockDispatch, - deleteMockDispatch, - buildKey, - generateKeyValues, - matchValue, - getResponse, - getStatusText, - mockDispatch, - buildMockDispatch, - checkNetConnect, - buildMockOptions, - getHeaderByName, - buildHeadersFromArray - }; - return mockUtils; -} - -var mockInterceptor = {}; - -var hasRequiredMockInterceptor; - -function requireMockInterceptor () { - if (hasRequiredMockInterceptor) return mockInterceptor; - hasRequiredMockInterceptor = 1; - - const { getResponseData, buildKey, addMockDispatch } = requireMockUtils(); - const { - kDispatches, - kDispatchKey, - kDefaultHeaders, - kDefaultTrailers, - kContentLength, - kMockDispatch - } = requireMockSymbols(); - const { InvalidArgumentError } = requireErrors(); - const { buildURL } = requireUtil$7(); - - /** - * Defines the scope API for an interceptor reply - */ - class MockScope { - constructor (mockDispatch) { - this[kMockDispatch] = mockDispatch; - } - - /** - * Delay a reply by a set amount in ms. - */ - delay (waitInMs) { - if (typeof waitInMs !== 'number' || !Number.isInteger(waitInMs) || waitInMs <= 0) { - throw new InvalidArgumentError('waitInMs must be a valid integer > 0') - } - - this[kMockDispatch].delay = waitInMs; - return this - } - - /** - * For a defined reply, never mark as consumed. - */ - persist () { - this[kMockDispatch].persist = true; - return this - } - - /** - * Allow one to define a reply for a set amount of matching requests. - */ - times (repeatTimes) { - if (typeof repeatTimes !== 'number' || !Number.isInteger(repeatTimes) || repeatTimes <= 0) { - throw new InvalidArgumentError('repeatTimes must be a valid integer > 0') - } - - this[kMockDispatch].times = repeatTimes; - return this - } - } - - /** - * Defines an interceptor for a Mock - */ - class MockInterceptor { - constructor (opts, mockDispatches) { - if (typeof opts !== 'object') { - throw new InvalidArgumentError('opts must be an object') - } - if (typeof opts.path === 'undefined') { - throw new InvalidArgumentError('opts.path must be defined') - } - if (typeof opts.method === 'undefined') { - opts.method = 'GET'; - } - // See https://github.com/nodejs/undici/issues/1245 - // As per RFC 3986, clients are not supposed to send URI - // fragments to servers when they retrieve a document, - if (typeof opts.path === 'string') { - if (opts.query) { - opts.path = buildURL(opts.path, opts.query); - } else { - // Matches https://github.com/nodejs/undici/blob/main/lib/web/fetch/index.js#L1811 - const parsedURL = new URL(opts.path, 'data://'); - opts.path = parsedURL.pathname + parsedURL.search; - } - } - if (typeof opts.method === 'string') { - opts.method = opts.method.toUpperCase(); - } - - this[kDispatchKey] = buildKey(opts); - this[kDispatches] = mockDispatches; - this[kDefaultHeaders] = {}; - this[kDefaultTrailers] = {}; - this[kContentLength] = false; - } - - createMockScopeDispatchData ({ statusCode, data, responseOptions }) { - const responseData = getResponseData(data); - const contentLength = this[kContentLength] ? { 'content-length': responseData.length } : {}; - const headers = { ...this[kDefaultHeaders], ...contentLength, ...responseOptions.headers }; - const trailers = { ...this[kDefaultTrailers], ...responseOptions.trailers }; - - return { statusCode, data, headers, trailers } - } - - validateReplyParameters (replyParameters) { - if (typeof replyParameters.statusCode === 'undefined') { - throw new InvalidArgumentError('statusCode must be defined') - } - if (typeof replyParameters.responseOptions !== 'object' || replyParameters.responseOptions === null) { - throw new InvalidArgumentError('responseOptions must be an object') - } - } - - /** - * Mock an undici request with a defined reply. - */ - reply (replyOptionsCallbackOrStatusCode) { - // Values of reply aren't available right now as they - // can only be available when the reply callback is invoked. - if (typeof replyOptionsCallbackOrStatusCode === 'function') { - // We'll first wrap the provided callback in another function, - // this function will properly resolve the data from the callback - // when invoked. - const wrappedDefaultsCallback = (opts) => { - // Our reply options callback contains the parameter for statusCode, data and options. - const resolvedData = replyOptionsCallbackOrStatusCode(opts); - - // Check if it is in the right format - if (typeof resolvedData !== 'object' || resolvedData === null) { - throw new InvalidArgumentError('reply options callback must return an object') - } - - const replyParameters = { data: '', responseOptions: {}, ...resolvedData }; - this.validateReplyParameters(replyParameters); - // Since the values can be obtained immediately we return them - // from this higher order function that will be resolved later. - return { - ...this.createMockScopeDispatchData(replyParameters) - } - }; - - // Add usual dispatch data, but this time set the data parameter to function that will eventually provide data. - const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], wrappedDefaultsCallback); - return new MockScope(newMockDispatch) - } - - // We can have either one or three parameters, if we get here, - // we should have 1-3 parameters. So we spread the arguments of - // this function to obtain the parameters, since replyData will always - // just be the statusCode. - const replyParameters = { - statusCode: replyOptionsCallbackOrStatusCode, - data: arguments[1] === undefined ? '' : arguments[1], - responseOptions: arguments[2] === undefined ? {} : arguments[2] - }; - this.validateReplyParameters(replyParameters); - - // Send in-already provided data like usual - const dispatchData = this.createMockScopeDispatchData(replyParameters); - const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], dispatchData); - return new MockScope(newMockDispatch) - } - - /** - * Mock an undici request with a defined error. - */ - replyWithError (error) { - if (typeof error === 'undefined') { - throw new InvalidArgumentError('error must be defined') - } - - const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], { error }); - return new MockScope(newMockDispatch) - } - - /** - * Set default reply headers on the interceptor for subsequent replies - */ - defaultReplyHeaders (headers) { - if (typeof headers === 'undefined') { - throw new InvalidArgumentError('headers must be defined') - } - - this[kDefaultHeaders] = headers; - return this - } - - /** - * Set default reply trailers on the interceptor for subsequent replies - */ - defaultReplyTrailers (trailers) { - if (typeof trailers === 'undefined') { - throw new InvalidArgumentError('trailers must be defined') - } - - this[kDefaultTrailers] = trailers; - return this - } - - /** - * Set reply content length header for replies on the interceptor - */ - replyContentLength () { - this[kContentLength] = true; - return this - } - } - - mockInterceptor.MockInterceptor = MockInterceptor; - mockInterceptor.MockScope = MockScope; - return mockInterceptor; -} - -var mockClient; -var hasRequiredMockClient; - -function requireMockClient () { - if (hasRequiredMockClient) return mockClient; - hasRequiredMockClient = 1; - - const { promisify } = require$$0$6; - const Client = requireClient(); - const { buildMockDispatch } = requireMockUtils(); - const { - kDispatches, - kMockAgent, - kClose, - kOriginalClose, - kOrigin, - kOriginalDispatch, - kConnected - } = requireMockSymbols(); - const { MockInterceptor } = requireMockInterceptor(); - const Symbols = requireSymbols$4(); - const { InvalidArgumentError } = requireErrors(); - - /** - * MockClient provides an API that extends the Client to influence the mockDispatches. - */ - class MockClient extends Client { - constructor (origin, opts) { - super(origin, opts); - - if (!opts || !opts.agent || typeof opts.agent.dispatch !== 'function') { - throw new InvalidArgumentError('Argument opts.agent must implement Agent') - } - - this[kMockAgent] = opts.agent; - this[kOrigin] = origin; - this[kDispatches] = []; - this[kConnected] = 1; - this[kOriginalDispatch] = this.dispatch; - this[kOriginalClose] = this.close.bind(this); - - this.dispatch = buildMockDispatch.call(this); - this.close = this[kClose]; - } - - get [Symbols.kConnected] () { - return this[kConnected] - } - - /** - * Sets up the base interceptor for mocking replies from undici. - */ - intercept (opts) { - return new MockInterceptor(opts, this[kDispatches]) - } - - async [kClose] () { - await promisify(this[kOriginalClose])(); - this[kConnected] = 0; - this[kMockAgent][Symbols.kClients].delete(this[kOrigin]); - } - } - - mockClient = MockClient; - return mockClient; -} - -var mockPool; -var hasRequiredMockPool; - -function requireMockPool () { - if (hasRequiredMockPool) return mockPool; - hasRequiredMockPool = 1; - - const { promisify } = require$$0$6; - const Pool = requirePool(); - const { buildMockDispatch } = requireMockUtils(); - const { - kDispatches, - kMockAgent, - kClose, - kOriginalClose, - kOrigin, - kOriginalDispatch, - kConnected - } = requireMockSymbols(); - const { MockInterceptor } = requireMockInterceptor(); - const Symbols = requireSymbols$4(); - const { InvalidArgumentError } = requireErrors(); - - /** - * MockPool provides an API that extends the Pool to influence the mockDispatches. - */ - class MockPool extends Pool { - constructor (origin, opts) { - super(origin, opts); - - if (!opts || !opts.agent || typeof opts.agent.dispatch !== 'function') { - throw new InvalidArgumentError('Argument opts.agent must implement Agent') - } - - this[kMockAgent] = opts.agent; - this[kOrigin] = origin; - this[kDispatches] = []; - this[kConnected] = 1; - this[kOriginalDispatch] = this.dispatch; - this[kOriginalClose] = this.close.bind(this); - - this.dispatch = buildMockDispatch.call(this); - this.close = this[kClose]; - } - - get [Symbols.kConnected] () { - return this[kConnected] - } - - /** - * Sets up the base interceptor for mocking replies from undici. - */ - intercept (opts) { - return new MockInterceptor(opts, this[kDispatches]) - } - - async [kClose] () { - await promisify(this[kOriginalClose])(); - this[kConnected] = 0; - this[kMockAgent][Symbols.kClients].delete(this[kOrigin]); - } - } - - mockPool = MockPool; - return mockPool; -} - -var pluralizer; -var hasRequiredPluralizer; - -function requirePluralizer () { - if (hasRequiredPluralizer) return pluralizer; - hasRequiredPluralizer = 1; - - const singulars = { - pronoun: 'it', - is: 'is', - was: 'was', - this: 'this' - }; - - const plurals = { - pronoun: 'they', - is: 'are', - was: 'were', - this: 'these' - }; - - pluralizer = class Pluralizer { - constructor (singular, plural) { - this.singular = singular; - this.plural = plural; - } - - pluralize (count) { - const one = count === 1; - const keys = one ? singulars : plurals; - const noun = one ? this.singular : this.plural; - return { ...keys, count, noun } - } - }; - return pluralizer; -} - -var pendingInterceptorsFormatter; -var hasRequiredPendingInterceptorsFormatter; - -function requirePendingInterceptorsFormatter () { - if (hasRequiredPendingInterceptorsFormatter) return pendingInterceptorsFormatter; - hasRequiredPendingInterceptorsFormatter = 1; - - const { Transform } = require$$0$5; - const { Console } = require$$1$1; - - const PERSISTENT = process.versions.icu ? '✅' : 'Y '; - const NOT_PERSISTENT = process.versions.icu ? '❌' : 'N '; - - /** - * Gets the output of `console.table(…)` as a string. - */ - pendingInterceptorsFormatter = class PendingInterceptorsFormatter { - constructor ({ disableColors } = {}) { - this.transform = new Transform({ - transform (chunk, _enc, cb) { - cb(null, chunk); - } - }); - - this.logger = new Console({ - stdout: this.transform, - inspectOptions: { - colors: !disableColors && !process.env.CI - } - }); - } - - format (pendingInterceptors) { - const withPrettyHeaders = pendingInterceptors.map( - ({ method, path, data: { statusCode }, persist, times, timesInvoked, origin }) => ({ - Method: method, - Origin: origin, - Path: path, - 'Status code': statusCode, - Persistent: persist ? PERSISTENT : NOT_PERSISTENT, - Invocations: timesInvoked, - Remaining: persist ? Infinity : times - timesInvoked - })); - - this.logger.table(withPrettyHeaders); - return this.transform.read().toString() - } - }; - return pendingInterceptorsFormatter; -} - -var mockAgent; -var hasRequiredMockAgent; - -function requireMockAgent () { - if (hasRequiredMockAgent) return mockAgent; - hasRequiredMockAgent = 1; - - const { kClients } = requireSymbols$4(); - const Agent = requireAgent(); - const { - kAgent, - kMockAgentSet, - kMockAgentGet, - kDispatches, - kIsMockActive, - kNetConnect, - kGetNetConnect, - kOptions, - kFactory - } = requireMockSymbols(); - const MockClient = requireMockClient(); - const MockPool = requireMockPool(); - const { matchValue, buildMockOptions } = requireMockUtils(); - const { InvalidArgumentError, UndiciError } = requireErrors(); - const Dispatcher = requireDispatcher(); - const Pluralizer = requirePluralizer(); - const PendingInterceptorsFormatter = requirePendingInterceptorsFormatter(); - - class MockAgent extends Dispatcher { - constructor (opts) { - super(opts); - - this[kNetConnect] = true; - this[kIsMockActive] = true; - - // Instantiate Agent and encapsulate - if ((opts?.agent && typeof opts.agent.dispatch !== 'function')) { - throw new InvalidArgumentError('Argument opts.agent must implement Agent') - } - const agent = opts?.agent ? opts.agent : new Agent(opts); - this[kAgent] = agent; - - this[kClients] = agent[kClients]; - this[kOptions] = buildMockOptions(opts); - } - - get (origin) { - let dispatcher = this[kMockAgentGet](origin); - - if (!dispatcher) { - dispatcher = this[kFactory](origin); - this[kMockAgentSet](origin, dispatcher); - } - return dispatcher - } - - dispatch (opts, handler) { - // Call MockAgent.get to perform additional setup before dispatching as normal - this.get(opts.origin); - return this[kAgent].dispatch(opts, handler) - } - - async close () { - await this[kAgent].close(); - this[kClients].clear(); - } - - deactivate () { - this[kIsMockActive] = false; - } - - activate () { - this[kIsMockActive] = true; - } - - enableNetConnect (matcher) { - if (typeof matcher === 'string' || typeof matcher === 'function' || matcher instanceof RegExp) { - if (Array.isArray(this[kNetConnect])) { - this[kNetConnect].push(matcher); - } else { - this[kNetConnect] = [matcher]; - } - } else if (typeof matcher === 'undefined') { - this[kNetConnect] = true; - } else { - throw new InvalidArgumentError('Unsupported matcher. Must be one of String|Function|RegExp.') - } - } - - disableNetConnect () { - this[kNetConnect] = false; - } - - // This is required to bypass issues caused by using global symbols - see: - // https://github.com/nodejs/undici/issues/1447 - get isMockActive () { - return this[kIsMockActive] - } - - [kMockAgentSet] (origin, dispatcher) { - this[kClients].set(origin, dispatcher); - } - - [kFactory] (origin) { - const mockOptions = Object.assign({ agent: this }, this[kOptions]); - return this[kOptions] && this[kOptions].connections === 1 - ? new MockClient(origin, mockOptions) - : new MockPool(origin, mockOptions) - } - - [kMockAgentGet] (origin) { - // First check if we can immediately find it - const client = this[kClients].get(origin); - if (client) { - return client - } - - // If the origin is not a string create a dummy parent pool and return to user - if (typeof origin !== 'string') { - const dispatcher = this[kFactory]('http://localhost:9999'); - this[kMockAgentSet](origin, dispatcher); - return dispatcher - } - - // If we match, create a pool and assign the same dispatches - for (const [keyMatcher, nonExplicitDispatcher] of Array.from(this[kClients])) { - if (nonExplicitDispatcher && typeof keyMatcher !== 'string' && matchValue(keyMatcher, origin)) { - const dispatcher = this[kFactory](origin); - this[kMockAgentSet](origin, dispatcher); - dispatcher[kDispatches] = nonExplicitDispatcher[kDispatches]; - return dispatcher - } - } - } - - [kGetNetConnect] () { - return this[kNetConnect] - } - - pendingInterceptors () { - const mockAgentClients = this[kClients]; - - return Array.from(mockAgentClients.entries()) - .flatMap(([origin, scope]) => scope[kDispatches].map(dispatch => ({ ...dispatch, origin }))) - .filter(({ pending }) => pending) - } - - assertNoPendingInterceptors ({ pendingInterceptorsFormatter = new PendingInterceptorsFormatter() } = {}) { - const pending = this.pendingInterceptors(); - - if (pending.length === 0) { - return - } - - const pluralizer = new Pluralizer('interceptor', 'interceptors').pluralize(pending.length); - - throw new UndiciError(` -${pluralizer.count} ${pluralizer.noun} ${pluralizer.is} pending: - -${pendingInterceptorsFormatter.format(pending)} -`.trim()) - } - } - - mockAgent = MockAgent; - return mockAgent; -} - -var global$1; -var hasRequiredGlobal; - -function requireGlobal () { - if (hasRequiredGlobal) return global$1; - hasRequiredGlobal = 1; - - // We include a version number for the Dispatcher API. In case of breaking changes, - // this version number must be increased to avoid conflicts. - const globalDispatcher = Symbol.for('undici.globalDispatcher.1'); - const { InvalidArgumentError } = requireErrors(); - const Agent = requireAgent(); - - if (getGlobalDispatcher() === undefined) { - setGlobalDispatcher(new Agent()); - } - - function setGlobalDispatcher (agent) { - if (!agent || typeof agent.dispatch !== 'function') { - throw new InvalidArgumentError('Argument agent must implement Agent') - } - Object.defineProperty(globalThis, globalDispatcher, { - value: agent, - writable: true, - enumerable: false, - configurable: false - }); - } - - function getGlobalDispatcher () { - return globalThis[globalDispatcher] - } - - global$1 = { - setGlobalDispatcher, - getGlobalDispatcher - }; - return global$1; -} - -var decoratorHandler; -var hasRequiredDecoratorHandler; - -function requireDecoratorHandler () { - if (hasRequiredDecoratorHandler) return decoratorHandler; - hasRequiredDecoratorHandler = 1; - - decoratorHandler = class DecoratorHandler { - #handler - - constructor (handler) { - if (typeof handler !== 'object' || handler === null) { - throw new TypeError('handler must be an object') - } - this.#handler = handler; - } - - onConnect (...args) { - return this.#handler.onConnect?.(...args) - } - - onError (...args) { - return this.#handler.onError?.(...args) - } - - onUpgrade (...args) { - return this.#handler.onUpgrade?.(...args) - } - - onResponseStarted (...args) { - return this.#handler.onResponseStarted?.(...args) - } - - onHeaders (...args) { - return this.#handler.onHeaders?.(...args) - } - - onData (...args) { - return this.#handler.onData?.(...args) - } - - onComplete (...args) { - return this.#handler.onComplete?.(...args) - } - - onBodySent (...args) { - return this.#handler.onBodySent?.(...args) - } - }; - return decoratorHandler; -} - -var redirect; -var hasRequiredRedirect; - -function requireRedirect () { - if (hasRequiredRedirect) return redirect; - hasRequiredRedirect = 1; - const RedirectHandler = requireRedirectHandler(); - - redirect = opts => { - const globalMaxRedirections = opts?.maxRedirections; - return dispatch => { - return function redirectInterceptor (opts, handler) { - const { maxRedirections = globalMaxRedirections, ...baseOpts } = opts; - - if (!maxRedirections) { - return dispatch(opts, handler) - } - - const redirectHandler = new RedirectHandler( - dispatch, - maxRedirections, - opts, - handler - ); - - return dispatch(baseOpts, redirectHandler) - } - } - }; - return redirect; -} - -var retry; -var hasRequiredRetry; - -function requireRetry () { - if (hasRequiredRetry) return retry; - hasRequiredRetry = 1; - const RetryHandler = requireRetryHandler(); - - retry = globalOpts => { - return dispatch => { - return function retryInterceptor (opts, handler) { - return dispatch( - opts, - new RetryHandler( - { ...opts, retryOptions: { ...globalOpts, ...opts.retryOptions } }, - { - handler, - dispatch - } - ) - ) - } - } - }; - return retry; -} - -var dump; -var hasRequiredDump; - -function requireDump () { - if (hasRequiredDump) return dump; - hasRequiredDump = 1; - - const util = requireUtil$7(); - const { InvalidArgumentError, RequestAbortedError } = requireErrors(); - const DecoratorHandler = requireDecoratorHandler(); - - class DumpHandler extends DecoratorHandler { - #maxSize = 1024 * 1024 - #abort = null - #dumped = false - #aborted = false - #size = 0 - #reason = null - #handler = null - - constructor ({ maxSize }, handler) { - super(handler); - - if (maxSize != null && (!Number.isFinite(maxSize) || maxSize < 1)) { - throw new InvalidArgumentError('maxSize must be a number greater than 0') - } - - this.#maxSize = maxSize ?? this.#maxSize; - this.#handler = handler; - } - - onConnect (abort) { - this.#abort = abort; - - this.#handler.onConnect(this.#customAbort.bind(this)); - } - - #customAbort (reason) { - this.#aborted = true; - this.#reason = reason; - } - - // TODO: will require adjustment after new hooks are out - onHeaders (statusCode, rawHeaders, resume, statusMessage) { - const headers = util.parseHeaders(rawHeaders); - const contentLength = headers['content-length']; - - if (contentLength != null && contentLength > this.#maxSize) { - throw new RequestAbortedError( - `Response size (${contentLength}) larger than maxSize (${ - this.#maxSize - })` - ) - } - - if (this.#aborted) { - return true - } - - return this.#handler.onHeaders( - statusCode, - rawHeaders, - resume, - statusMessage - ) - } - - onError (err) { - if (this.#dumped) { - return - } - - err = this.#reason ?? err; - - this.#handler.onError(err); - } - - onData (chunk) { - this.#size = this.#size + chunk.length; - - if (this.#size >= this.#maxSize) { - this.#dumped = true; - - if (this.#aborted) { - this.#handler.onError(this.#reason); - } else { - this.#handler.onComplete([]); - } - } - - return true - } - - onComplete (trailers) { - if (this.#dumped) { - return - } - - if (this.#aborted) { - this.#handler.onError(this.reason); - return - } - - this.#handler.onComplete(trailers); - } - } - - function createDumpInterceptor ( - { maxSize: defaultMaxSize } = { - maxSize: 1024 * 1024 - } - ) { - return dispatch => { - return function Intercept (opts, handler) { - const { dumpMaxSize = defaultMaxSize } = - opts; - - const dumpHandler = new DumpHandler( - { maxSize: dumpMaxSize }, - handler - ); - - return dispatch(opts, dumpHandler) - } - } - } - - dump = createDumpInterceptor; - return dump; -} - -var headers; -var hasRequiredHeaders; - -function requireHeaders () { - if (hasRequiredHeaders) return headers; - hasRequiredHeaders = 1; - - const { kConstruct } = requireSymbols$4(); - const { kEnumerableProperty } = requireUtil$7(); - const { - iteratorMixin, - isValidHeaderName, - isValidHeaderValue - } = requireUtil$6(); - const { webidl } = requireWebidl(); - const assert = require$$0$4; - const util = require$$0$6; - - const kHeadersMap = Symbol('headers map'); - const kHeadersSortedMap = Symbol('headers map sorted'); - - /** - * @param {number} code - */ - function isHTTPWhiteSpaceCharCode (code) { - return code === 0x00a || code === 0x00d || code === 0x009 || code === 0x020 - } - - /** - * @see https://fetch.spec.whatwg.org/#concept-header-value-normalize - * @param {string} potentialValue - */ - function headerValueNormalize (potentialValue) { - // To normalize a byte sequence potentialValue, remove - // any leading and trailing HTTP whitespace bytes from - // potentialValue. - let i = 0; let j = potentialValue.length; - - while (j > i && isHTTPWhiteSpaceCharCode(potentialValue.charCodeAt(j - 1))) --j; - while (j > i && isHTTPWhiteSpaceCharCode(potentialValue.charCodeAt(i))) ++i; - - return i === 0 && j === potentialValue.length ? potentialValue : potentialValue.substring(i, j) - } - - function fill (headers, object) { - // To fill a Headers object headers with a given object object, run these steps: - - // 1. If object is a sequence, then for each header in object: - // Note: webidl conversion to array has already been done. - if (Array.isArray(object)) { - for (let i = 0; i < object.length; ++i) { - const header = object[i]; - // 1. If header does not contain exactly two items, then throw a TypeError. - if (header.length !== 2) { - throw webidl.errors.exception({ - header: 'Headers constructor', - message: `expected name/value pair to be length 2, found ${header.length}.` - }) - } - - // 2. Append (header’s first item, header’s second item) to headers. - appendHeader(headers, header[0], header[1]); - } - } else if (typeof object === 'object' && object !== null) { - // Note: null should throw - - // 2. Otherwise, object is a record, then for each key → value in object, - // append (key, value) to headers - const keys = Object.keys(object); - for (let i = 0; i < keys.length; ++i) { - appendHeader(headers, keys[i], object[keys[i]]); - } - } else { - throw webidl.errors.conversionFailed({ - prefix: 'Headers constructor', - argument: 'Argument 1', - types: ['sequence>', 'record'] - }) - } - } - - /** - * @see https://fetch.spec.whatwg.org/#concept-headers-append - */ - function appendHeader (headers, name, value) { - // 1. Normalize value. - value = headerValueNormalize(value); - - // 2. If name is not a header name or value is not a - // header value, then throw a TypeError. - if (!isValidHeaderName(name)) { - throw webidl.errors.invalidArgument({ - prefix: 'Headers.append', - value: name, - type: 'header name' - }) - } else if (!isValidHeaderValue(value)) { - throw webidl.errors.invalidArgument({ - prefix: 'Headers.append', - value, - type: 'header value' - }) - } - - // 3. If headers’s guard is "immutable", then throw a TypeError. - // 4. Otherwise, if headers’s guard is "request" and name is a - // forbidden header name, return. - // 5. Otherwise, if headers’s guard is "request-no-cors": - // TODO - // Note: undici does not implement forbidden header names - if (getHeadersGuard(headers) === 'immutable') { - throw new TypeError('immutable') - } - - // 6. Otherwise, if headers’s guard is "response" and name is a - // forbidden response-header name, return. - - // 7. Append (name, value) to headers’s header list. - return getHeadersList(headers).append(name, value, false) - - // 8. If headers’s guard is "request-no-cors", then remove - // privileged no-CORS request headers from headers - } - - function compareHeaderName (a, b) { - return a[0] < b[0] ? -1 : 1 - } - - class HeadersList { - /** @type {[string, string][]|null} */ - cookies = null - - constructor (init) { - if (init instanceof HeadersList) { - this[kHeadersMap] = new Map(init[kHeadersMap]); - this[kHeadersSortedMap] = init[kHeadersSortedMap]; - this.cookies = init.cookies === null ? null : [...init.cookies]; - } else { - this[kHeadersMap] = new Map(init); - this[kHeadersSortedMap] = null; - } - } - - /** - * @see https://fetch.spec.whatwg.org/#header-list-contains - * @param {string} name - * @param {boolean} isLowerCase - */ - contains (name, isLowerCase) { - // A header list list contains a header name name if list - // contains a header whose name is a byte-case-insensitive - // match for name. - - return this[kHeadersMap].has(isLowerCase ? name : name.toLowerCase()) - } - - clear () { - this[kHeadersMap].clear(); - this[kHeadersSortedMap] = null; - this.cookies = null; - } - - /** - * @see https://fetch.spec.whatwg.org/#concept-header-list-append - * @param {string} name - * @param {string} value - * @param {boolean} isLowerCase - */ - append (name, value, isLowerCase) { - this[kHeadersSortedMap] = null; - - // 1. If list contains name, then set name to the first such - // header’s name. - const lowercaseName = isLowerCase ? name : name.toLowerCase(); - const exists = this[kHeadersMap].get(lowercaseName); - - // 2. Append (name, value) to list. - if (exists) { - const delimiter = lowercaseName === 'cookie' ? '; ' : ', '; - this[kHeadersMap].set(lowercaseName, { - name: exists.name, - value: `${exists.value}${delimiter}${value}` - }); - } else { - this[kHeadersMap].set(lowercaseName, { name, value }); - } - - if (lowercaseName === 'set-cookie') { - (this.cookies ??= []).push(value); - } - } - - /** - * @see https://fetch.spec.whatwg.org/#concept-header-list-set - * @param {string} name - * @param {string} value - * @param {boolean} isLowerCase - */ - set (name, value, isLowerCase) { - this[kHeadersSortedMap] = null; - const lowercaseName = isLowerCase ? name : name.toLowerCase(); - - if (lowercaseName === 'set-cookie') { - this.cookies = [value]; - } - - // 1. If list contains name, then set the value of - // the first such header to value and remove the - // others. - // 2. Otherwise, append header (name, value) to list. - this[kHeadersMap].set(lowercaseName, { name, value }); - } - - /** - * @see https://fetch.spec.whatwg.org/#concept-header-list-delete - * @param {string} name - * @param {boolean} isLowerCase - */ - delete (name, isLowerCase) { - this[kHeadersSortedMap] = null; - if (!isLowerCase) name = name.toLowerCase(); - - if (name === 'set-cookie') { - this.cookies = null; - } - - this[kHeadersMap].delete(name); - } - - /** - * @see https://fetch.spec.whatwg.org/#concept-header-list-get - * @param {string} name - * @param {boolean} isLowerCase - * @returns {string | null} - */ - get (name, isLowerCase) { - // 1. If list does not contain name, then return null. - // 2. Return the values of all headers in list whose name - // is a byte-case-insensitive match for name, - // separated from each other by 0x2C 0x20, in order. - return this[kHeadersMap].get(isLowerCase ? name : name.toLowerCase())?.value ?? null - } - - * [Symbol.iterator] () { - // use the lowercased name - for (const { 0: name, 1: { value } } of this[kHeadersMap]) { - yield [name, value]; - } - } - - get entries () { - const headers = {}; - - if (this[kHeadersMap].size !== 0) { - for (const { name, value } of this[kHeadersMap].values()) { - headers[name] = value; - } - } - - return headers - } - - rawValues () { - return this[kHeadersMap].values() - } - - get entriesList () { - const headers = []; - - if (this[kHeadersMap].size !== 0) { - for (const { 0: lowerName, 1: { name, value } } of this[kHeadersMap]) { - if (lowerName === 'set-cookie') { - for (const cookie of this.cookies) { - headers.push([name, cookie]); - } - } else { - headers.push([name, value]); - } - } - } - - return headers - } - - // https://fetch.spec.whatwg.org/#convert-header-names-to-a-sorted-lowercase-set - toSortedArray () { - const size = this[kHeadersMap].size; - const array = new Array(size); - // In most cases, you will use the fast-path. - // fast-path: Use binary insertion sort for small arrays. - if (size <= 32) { - if (size === 0) { - // If empty, it is an empty array. To avoid the first index assignment. - return array - } - // Improve performance by unrolling loop and avoiding double-loop. - // Double-loop-less version of the binary insertion sort. - const iterator = this[kHeadersMap][Symbol.iterator](); - const firstValue = iterator.next().value; - // set [name, value] to first index. - array[0] = [firstValue[0], firstValue[1].value]; - // https://fetch.spec.whatwg.org/#concept-header-list-sort-and-combine - // 3.2.2. Assert: value is non-null. - assert(firstValue[1].value !== null); - for ( - let i = 1, j = 0, right = 0, left = 0, pivot = 0, x, value; - i < size; - ++i - ) { - // get next value - value = iterator.next().value; - // set [name, value] to current index. - x = array[i] = [value[0], value[1].value]; - // https://fetch.spec.whatwg.org/#concept-header-list-sort-and-combine - // 3.2.2. Assert: value is non-null. - assert(x[1] !== null); - left = 0; - right = i; - // binary search - while (left < right) { - // middle index - pivot = left + ((right - left) >> 1); - // compare header name - if (array[pivot][0] <= x[0]) { - left = pivot + 1; - } else { - right = pivot; - } - } - if (i !== pivot) { - j = i; - while (j > left) { - array[j] = array[--j]; - } - array[left] = x; - } - } - /* c8 ignore next 4 */ - if (!iterator.next().done) { - // This is for debugging and will never be called. - throw new TypeError('Unreachable') - } - return array - } else { - // This case would be a rare occurrence. - // slow-path: fallback - let i = 0; - for (const { 0: name, 1: { value } } of this[kHeadersMap]) { - array[i++] = [name, value]; - // https://fetch.spec.whatwg.org/#concept-header-list-sort-and-combine - // 3.2.2. Assert: value is non-null. - assert(value !== null); - } - return array.sort(compareHeaderName) - } - } - } - - // https://fetch.spec.whatwg.org/#headers-class - class Headers { - #guard - #headersList - - constructor (init = undefined) { - if (init === kConstruct) { - return - } - - this.#headersList = new HeadersList(); - - // The new Headers(init) constructor steps are: - - // 1. Set this’s guard to "none". - this.#guard = 'none'; - - // 2. If init is given, then fill this with init. - if (init !== undefined) { - init = webidl.converters.HeadersInit(init, 'Headers contructor', 'init'); - fill(this, init); - } - } - - // https://fetch.spec.whatwg.org/#dom-headers-append - append (name, value) { - webidl.brandCheck(this, Headers); - - webidl.argumentLengthCheck(arguments, 2, 'Headers.append'); - - const prefix = 'Headers.append'; - name = webidl.converters.ByteString(name, prefix, 'name'); - value = webidl.converters.ByteString(value, prefix, 'value'); - - return appendHeader(this, name, value) - } - - // https://fetch.spec.whatwg.org/#dom-headers-delete - delete (name) { - webidl.brandCheck(this, Headers); - - webidl.argumentLengthCheck(arguments, 1, 'Headers.delete'); - - const prefix = 'Headers.delete'; - name = webidl.converters.ByteString(name, prefix, 'name'); - - // 1. If name is not a header name, then throw a TypeError. - if (!isValidHeaderName(name)) { - throw webidl.errors.invalidArgument({ - prefix: 'Headers.delete', - value: name, - type: 'header name' - }) - } - - // 2. If this’s guard is "immutable", then throw a TypeError. - // 3. Otherwise, if this’s guard is "request" and name is a - // forbidden header name, return. - // 4. Otherwise, if this’s guard is "request-no-cors", name - // is not a no-CORS-safelisted request-header name, and - // name is not a privileged no-CORS request-header name, - // return. - // 5. Otherwise, if this’s guard is "response" and name is - // a forbidden response-header name, return. - // Note: undici does not implement forbidden header names - if (this.#guard === 'immutable') { - throw new TypeError('immutable') - } - - // 6. If this’s header list does not contain name, then - // return. - if (!this.#headersList.contains(name, false)) { - return - } - - // 7. Delete name from this’s header list. - // 8. If this’s guard is "request-no-cors", then remove - // privileged no-CORS request headers from this. - this.#headersList.delete(name, false); - } - - // https://fetch.spec.whatwg.org/#dom-headers-get - get (name) { - webidl.brandCheck(this, Headers); - - webidl.argumentLengthCheck(arguments, 1, 'Headers.get'); - - const prefix = 'Headers.get'; - name = webidl.converters.ByteString(name, prefix, 'name'); - - // 1. If name is not a header name, then throw a TypeError. - if (!isValidHeaderName(name)) { - throw webidl.errors.invalidArgument({ - prefix, - value: name, - type: 'header name' - }) - } - - // 2. Return the result of getting name from this’s header - // list. - return this.#headersList.get(name, false) - } - - // https://fetch.spec.whatwg.org/#dom-headers-has - has (name) { - webidl.brandCheck(this, Headers); - - webidl.argumentLengthCheck(arguments, 1, 'Headers.has'); - - const prefix = 'Headers.has'; - name = webidl.converters.ByteString(name, prefix, 'name'); - - // 1. If name is not a header name, then throw a TypeError. - if (!isValidHeaderName(name)) { - throw webidl.errors.invalidArgument({ - prefix, - value: name, - type: 'header name' - }) - } - - // 2. Return true if this’s header list contains name; - // otherwise false. - return this.#headersList.contains(name, false) - } - - // https://fetch.spec.whatwg.org/#dom-headers-set - set (name, value) { - webidl.brandCheck(this, Headers); - - webidl.argumentLengthCheck(arguments, 2, 'Headers.set'); - - const prefix = 'Headers.set'; - name = webidl.converters.ByteString(name, prefix, 'name'); - value = webidl.converters.ByteString(value, prefix, 'value'); - - // 1. Normalize value. - value = headerValueNormalize(value); - - // 2. If name is not a header name or value is not a - // header value, then throw a TypeError. - if (!isValidHeaderName(name)) { - throw webidl.errors.invalidArgument({ - prefix, - value: name, - type: 'header name' - }) - } else if (!isValidHeaderValue(value)) { - throw webidl.errors.invalidArgument({ - prefix, - value, - type: 'header value' - }) - } - - // 3. If this’s guard is "immutable", then throw a TypeError. - // 4. Otherwise, if this’s guard is "request" and name is a - // forbidden header name, return. - // 5. Otherwise, if this’s guard is "request-no-cors" and - // name/value is not a no-CORS-safelisted request-header, - // return. - // 6. Otherwise, if this’s guard is "response" and name is a - // forbidden response-header name, return. - // Note: undici does not implement forbidden header names - if (this.#guard === 'immutable') { - throw new TypeError('immutable') - } - - // 7. Set (name, value) in this’s header list. - // 8. If this’s guard is "request-no-cors", then remove - // privileged no-CORS request headers from this - this.#headersList.set(name, value, false); - } - - // https://fetch.spec.whatwg.org/#dom-headers-getsetcookie - getSetCookie () { - webidl.brandCheck(this, Headers); - - // 1. If this’s header list does not contain `Set-Cookie`, then return « ». - // 2. Return the values of all headers in this’s header list whose name is - // a byte-case-insensitive match for `Set-Cookie`, in order. - - const list = this.#headersList.cookies; - - if (list) { - return [...list] - } - - return [] - } - - // https://fetch.spec.whatwg.org/#concept-header-list-sort-and-combine - get [kHeadersSortedMap] () { - if (this.#headersList[kHeadersSortedMap]) { - return this.#headersList[kHeadersSortedMap] - } - - // 1. Let headers be an empty list of headers with the key being the name - // and value the value. - const headers = []; - - // 2. Let names be the result of convert header names to a sorted-lowercase - // set with all the names of the headers in list. - const names = this.#headersList.toSortedArray(); - - const cookies = this.#headersList.cookies; - - // fast-path - if (cookies === null || cookies.length === 1) { - // Note: The non-null assertion of value has already been done by `HeadersList#toSortedArray` - return (this.#headersList[kHeadersSortedMap] = names) - } - - // 3. For each name of names: - for (let i = 0; i < names.length; ++i) { - const { 0: name, 1: value } = names[i]; - // 1. If name is `set-cookie`, then: - if (name === 'set-cookie') { - // 1. Let values be a list of all values of headers in list whose name - // is a byte-case-insensitive match for name, in order. - - // 2. For each value of values: - // 1. Append (name, value) to headers. - for (let j = 0; j < cookies.length; ++j) { - headers.push([name, cookies[j]]); - } - } else { - // 2. Otherwise: - - // 1. Let value be the result of getting name from list. - - // 2. Assert: value is non-null. - // Note: This operation was done by `HeadersList#toSortedArray`. - - // 3. Append (name, value) to headers. - headers.push([name, value]); - } - } - - // 4. Return headers. - return (this.#headersList[kHeadersSortedMap] = headers) - } - - [util.inspect.custom] (depth, options) { - options.depth ??= depth; - - return `Headers ${util.formatWithOptions(options, this.#headersList.entries)}` - } - - static getHeadersGuard (o) { - return o.#guard - } - - static setHeadersGuard (o, guard) { - o.#guard = guard; - } - - static getHeadersList (o) { - return o.#headersList - } - - static setHeadersList (o, list) { - o.#headersList = list; - } - } - - const { getHeadersGuard, setHeadersGuard, getHeadersList, setHeadersList } = Headers; - Reflect.deleteProperty(Headers, 'getHeadersGuard'); - Reflect.deleteProperty(Headers, 'setHeadersGuard'); - Reflect.deleteProperty(Headers, 'getHeadersList'); - Reflect.deleteProperty(Headers, 'setHeadersList'); - - iteratorMixin('Headers', Headers, kHeadersSortedMap, 0, 1); - - Object.defineProperties(Headers.prototype, { - append: kEnumerableProperty, - delete: kEnumerableProperty, - get: kEnumerableProperty, - has: kEnumerableProperty, - set: kEnumerableProperty, - getSetCookie: kEnumerableProperty, - [Symbol.toStringTag]: { - value: 'Headers', - configurable: true - }, - [util.inspect.custom]: { - enumerable: false - } - }); - - webidl.converters.HeadersInit = function (V, prefix, argument) { - if (webidl.util.Type(V) === 'Object') { - const iterator = Reflect.get(V, Symbol.iterator); - - // A work-around to ensure we send the properly-cased Headers when V is a Headers object. - // Read https://github.com/nodejs/undici/pull/3159#issuecomment-2075537226 before touching, please. - if (!util.types.isProxy(V) && iterator === Headers.prototype.entries) { // Headers object - try { - return getHeadersList(V).entriesList - } catch { - // fall-through - } - } - - if (typeof iterator === 'function') { - return webidl.converters['sequence>'](V, prefix, argument, iterator.bind(V)) - } - - return webidl.converters['record'](V, prefix, argument) - } - - throw webidl.errors.conversionFailed({ - prefix: 'Headers constructor', - argument: 'Argument 1', - types: ['sequence>', 'record'] - }) - }; - - headers = { - fill, - // for test. - compareHeaderName, - Headers, - HeadersList, - getHeadersGuard, - setHeadersGuard, - setHeadersList, - getHeadersList - }; - return headers; -} - -var response; -var hasRequiredResponse; - -function requireResponse () { - if (hasRequiredResponse) return response; - hasRequiredResponse = 1; - - const { Headers, HeadersList, fill, getHeadersGuard, setHeadersGuard, setHeadersList } = requireHeaders(); - const { extractBody, cloneBody, mixinBody } = requireBody(); - const util = requireUtil$7(); - const nodeUtil = require$$0$6; - const { kEnumerableProperty } = util; - const { - isValidReasonPhrase, - isCancelled, - isAborted, - isBlobLike, - serializeJavascriptValueToJSONString, - isErrorLike, - isomorphicEncode, - environmentSettingsObject: relevantRealm - } = requireUtil$6(); - const { - redirectStatusSet, - nullBodyStatus - } = requireConstants$2(); - const { kState, kHeaders } = requireSymbols$3(); - const { webidl } = requireWebidl(); - const { FormData } = requireFormdata(); - const { URLSerializer } = requireDataUrl(); - const { kConstruct } = requireSymbols$4(); - const assert = require$$0$4; - const { types } = require$$0$6; - const { isDisturbed, isErrored } = require$$0$5; - - const textEncoder = new TextEncoder('utf-8'); - - const hasFinalizationRegistry = globalThis.FinalizationRegistry && process.version.indexOf('v18') !== 0; - let registry; - - if (hasFinalizationRegistry) { - registry = new FinalizationRegistry((stream) => { - if (!stream.locked && !isDisturbed(stream) && !isErrored(stream)) { - stream.cancel('Response object has been garbage collected').catch(noop); - } - }); - } - - function noop () {} - - // https://fetch.spec.whatwg.org/#response-class - class Response { - // Creates network error Response. - static error () { - // The static error() method steps are to return the result of creating a - // Response object, given a new network error, "immutable", and this’s - // relevant Realm. - const responseObject = fromInnerResponse(makeNetworkError(), 'immutable'); - - return responseObject - } - - // https://fetch.spec.whatwg.org/#dom-response-json - static json (data, init = {}) { - webidl.argumentLengthCheck(arguments, 1, 'Response.json'); - - if (init !== null) { - init = webidl.converters.ResponseInit(init); - } - - // 1. Let bytes the result of running serialize a JavaScript value to JSON bytes on data. - const bytes = textEncoder.encode( - serializeJavascriptValueToJSONString(data) - ); - - // 2. Let body be the result of extracting bytes. - const body = extractBody(bytes); - - // 3. Let responseObject be the result of creating a Response object, given a new response, - // "response", and this’s relevant Realm. - const responseObject = fromInnerResponse(makeResponse({}), 'response'); - - // 4. Perform initialize a response given responseObject, init, and (body, "application/json"). - initializeResponse(responseObject, init, { body: body[0], type: 'application/json' }); - - // 5. Return responseObject. - return responseObject - } - - // Creates a redirect Response that redirects to url with status status. - static redirect (url, status = 302) { - webidl.argumentLengthCheck(arguments, 1, 'Response.redirect'); - - url = webidl.converters.USVString(url); - status = webidl.converters['unsigned short'](status); - - // 1. Let parsedURL be the result of parsing url with current settings - // object’s API base URL. - // 2. If parsedURL is failure, then throw a TypeError. - // TODO: base-URL? - let parsedURL; - try { - parsedURL = new URL(url, relevantRealm.settingsObject.baseUrl); - } catch (err) { - throw new TypeError(`Failed to parse URL from ${url}`, { cause: err }) - } - - // 3. If status is not a redirect status, then throw a RangeError. - if (!redirectStatusSet.has(status)) { - throw new RangeError(`Invalid status code ${status}`) - } - - // 4. Let responseObject be the result of creating a Response object, - // given a new response, "immutable", and this’s relevant Realm. - const responseObject = fromInnerResponse(makeResponse({}), 'immutable'); - - // 5. Set responseObject’s response’s status to status. - responseObject[kState].status = status; - - // 6. Let value be parsedURL, serialized and isomorphic encoded. - const value = isomorphicEncode(URLSerializer(parsedURL)); - - // 7. Append `Location`/value to responseObject’s response’s header list. - responseObject[kState].headersList.append('location', value, true); - - // 8. Return responseObject. - return responseObject - } - - // https://fetch.spec.whatwg.org/#dom-response - constructor (body = null, init = {}) { - if (body === kConstruct) { - return - } - - if (body !== null) { - body = webidl.converters.BodyInit(body); - } - - init = webidl.converters.ResponseInit(init); - - // 1. Set this’s response to a new response. - this[kState] = makeResponse({}); - - // 2. Set this’s headers to a new Headers object with this’s relevant - // Realm, whose header list is this’s response’s header list and guard - // is "response". - this[kHeaders] = new Headers(kConstruct); - setHeadersGuard(this[kHeaders], 'response'); - setHeadersList(this[kHeaders], this[kState].headersList); - - // 3. Let bodyWithType be null. - let bodyWithType = null; - - // 4. If body is non-null, then set bodyWithType to the result of extracting body. - if (body != null) { - const [extractedBody, type] = extractBody(body); - bodyWithType = { body: extractedBody, type }; - } - - // 5. Perform initialize a response given this, init, and bodyWithType. - initializeResponse(this, init, bodyWithType); - } - - // Returns response’s type, e.g., "cors". - get type () { - webidl.brandCheck(this, Response); - - // The type getter steps are to return this’s response’s type. - return this[kState].type - } - - // Returns response’s URL, if it has one; otherwise the empty string. - get url () { - webidl.brandCheck(this, Response); - - const urlList = this[kState].urlList; - - // The url getter steps are to return the empty string if this’s - // response’s URL is null; otherwise this’s response’s URL, - // serialized with exclude fragment set to true. - const url = urlList[urlList.length - 1] ?? null; - - if (url === null) { - return '' - } - - return URLSerializer(url, true) - } - - // Returns whether response was obtained through a redirect. - get redirected () { - webidl.brandCheck(this, Response); - - // The redirected getter steps are to return true if this’s response’s URL - // list has more than one item; otherwise false. - return this[kState].urlList.length > 1 - } - - // Returns response’s status. - get status () { - webidl.brandCheck(this, Response); - - // The status getter steps are to return this’s response’s status. - return this[kState].status - } - - // Returns whether response’s status is an ok status. - get ok () { - webidl.brandCheck(this, Response); - - // The ok getter steps are to return true if this’s response’s status is an - // ok status; otherwise false. - return this[kState].status >= 200 && this[kState].status <= 299 - } - - // Returns response’s status message. - get statusText () { - webidl.brandCheck(this, Response); - - // The statusText getter steps are to return this’s response’s status - // message. - return this[kState].statusText - } - - // Returns response’s headers as Headers. - get headers () { - webidl.brandCheck(this, Response); - - // The headers getter steps are to return this’s headers. - return this[kHeaders] - } - - get body () { - webidl.brandCheck(this, Response); - - return this[kState].body ? this[kState].body.stream : null - } - - get bodyUsed () { - webidl.brandCheck(this, Response); - - return !!this[kState].body && util.isDisturbed(this[kState].body.stream) - } - - // Returns a clone of response. - clone () { - webidl.brandCheck(this, Response); - - // 1. If this is unusable, then throw a TypeError. - if (this.bodyUsed || this.body?.locked) { - throw webidl.errors.exception({ - header: 'Response.clone', - message: 'Body has already been consumed.' - }) - } - - // 2. Let clonedResponse be the result of cloning this’s response. - const clonedResponse = cloneResponse(this[kState]); - - // 3. Return the result of creating a Response object, given - // clonedResponse, this’s headers’s guard, and this’s relevant Realm. - return fromInnerResponse(clonedResponse, getHeadersGuard(this[kHeaders])) - } - - [nodeUtil.inspect.custom] (depth, options) { - if (options.depth === null) { - options.depth = 2; - } - - options.colors ??= true; - - const properties = { - status: this.status, - statusText: this.statusText, - headers: this.headers, - body: this.body, - bodyUsed: this.bodyUsed, - ok: this.ok, - redirected: this.redirected, - type: this.type, - url: this.url - }; - - return `Response ${nodeUtil.formatWithOptions(options, properties)}` - } - } - - mixinBody(Response); - - Object.defineProperties(Response.prototype, { - type: kEnumerableProperty, - url: kEnumerableProperty, - status: kEnumerableProperty, - ok: kEnumerableProperty, - redirected: kEnumerableProperty, - statusText: kEnumerableProperty, - headers: kEnumerableProperty, - clone: kEnumerableProperty, - body: kEnumerableProperty, - bodyUsed: kEnumerableProperty, - [Symbol.toStringTag]: { - value: 'Response', - configurable: true - } - }); - - Object.defineProperties(Response, { - json: kEnumerableProperty, - redirect: kEnumerableProperty, - error: kEnumerableProperty - }); - - // https://fetch.spec.whatwg.org/#concept-response-clone - function cloneResponse (response) { - // To clone a response response, run these steps: - - // 1. If response is a filtered response, then return a new identical - // filtered response whose internal response is a clone of response’s - // internal response. - if (response.internalResponse) { - return filterResponse( - cloneResponse(response.internalResponse), - response.type - ) - } - - // 2. Let newResponse be a copy of response, except for its body. - const newResponse = makeResponse({ ...response, body: null }); - - // 3. If response’s body is non-null, then set newResponse’s body to the - // result of cloning response’s body. - if (response.body != null) { - newResponse.body = cloneBody(response.body); - } - - // 4. Return newResponse. - return newResponse - } - - function makeResponse (init) { - return { - aborted: false, - rangeRequested: false, - timingAllowPassed: false, - requestIncludesCredentials: false, - type: 'default', - status: 200, - timingInfo: null, - cacheState: '', - statusText: '', - ...init, - headersList: init?.headersList - ? new HeadersList(init?.headersList) - : new HeadersList(), - urlList: init?.urlList ? [...init.urlList] : [] - } - } - - function makeNetworkError (reason) { - const isError = isErrorLike(reason); - return makeResponse({ - type: 'error', - status: 0, - error: isError - ? reason - : new Error(reason ? String(reason) : reason), - aborted: reason && reason.name === 'AbortError' - }) - } - - // @see https://fetch.spec.whatwg.org/#concept-network-error - function isNetworkError (response) { - return ( - // A network error is a response whose type is "error", - response.type === 'error' && - // status is 0 - response.status === 0 - ) - } - - function makeFilteredResponse (response, state) { - state = { - internalResponse: response, - ...state - }; - - return new Proxy(response, { - get (target, p) { - return p in state ? state[p] : target[p] - }, - set (target, p, value) { - assert(!(p in state)); - target[p] = value; - return true - } - }) - } - - // https://fetch.spec.whatwg.org/#concept-filtered-response - function filterResponse (response, type) { - // Set response to the following filtered response with response as its - // internal response, depending on request’s response tainting: - if (type === 'basic') { - // A basic filtered response is a filtered response whose type is "basic" - // and header list excludes any headers in internal response’s header list - // whose name is a forbidden response-header name. - - // Note: undici does not implement forbidden response-header names - return makeFilteredResponse(response, { - type: 'basic', - headersList: response.headersList - }) - } else if (type === 'cors') { - // A CORS filtered response is a filtered response whose type is "cors" - // and header list excludes any headers in internal response’s header - // list whose name is not a CORS-safelisted response-header name, given - // internal response’s CORS-exposed header-name list. - - // Note: undici does not implement CORS-safelisted response-header names - return makeFilteredResponse(response, { - type: 'cors', - headersList: response.headersList - }) - } else if (type === 'opaque') { - // An opaque filtered response is a filtered response whose type is - // "opaque", URL list is the empty list, status is 0, status message - // is the empty byte sequence, header list is empty, and body is null. - - return makeFilteredResponse(response, { - type: 'opaque', - urlList: Object.freeze([]), - status: 0, - statusText: '', - body: null - }) - } else if (type === 'opaqueredirect') { - // An opaque-redirect filtered response is a filtered response whose type - // is "opaqueredirect", status is 0, status message is the empty byte - // sequence, header list is empty, and body is null. - - return makeFilteredResponse(response, { - type: 'opaqueredirect', - status: 0, - statusText: '', - headersList: [], - body: null - }) - } else { - assert(false); - } - } - - // https://fetch.spec.whatwg.org/#appropriate-network-error - function makeAppropriateNetworkError (fetchParams, err = null) { - // 1. Assert: fetchParams is canceled. - assert(isCancelled(fetchParams)); - - // 2. Return an aborted network error if fetchParams is aborted; - // otherwise return a network error. - return isAborted(fetchParams) - ? makeNetworkError(Object.assign(new DOMException('The operation was aborted.', 'AbortError'), { cause: err })) - : makeNetworkError(Object.assign(new DOMException('Request was cancelled.'), { cause: err })) - } - - // https://whatpr.org/fetch/1392.html#initialize-a-response - function initializeResponse (response, init, body) { - // 1. If init["status"] is not in the range 200 to 599, inclusive, then - // throw a RangeError. - if (init.status !== null && (init.status < 200 || init.status > 599)) { - throw new RangeError('init["status"] must be in the range of 200 to 599, inclusive.') - } - - // 2. If init["statusText"] does not match the reason-phrase token production, - // then throw a TypeError. - if ('statusText' in init && init.statusText != null) { - // See, https://datatracker.ietf.org/doc/html/rfc7230#section-3.1.2: - // reason-phrase = *( HTAB / SP / VCHAR / obs-text ) - if (!isValidReasonPhrase(String(init.statusText))) { - throw new TypeError('Invalid statusText') - } - } - - // 3. Set response’s response’s status to init["status"]. - if ('status' in init && init.status != null) { - response[kState].status = init.status; - } - - // 4. Set response’s response’s status message to init["statusText"]. - if ('statusText' in init && init.statusText != null) { - response[kState].statusText = init.statusText; - } - - // 5. If init["headers"] exists, then fill response’s headers with init["headers"]. - if ('headers' in init && init.headers != null) { - fill(response[kHeaders], init.headers); - } - - // 6. If body was given, then: - if (body) { - // 1. If response's status is a null body status, then throw a TypeError. - if (nullBodyStatus.includes(response.status)) { - throw webidl.errors.exception({ - header: 'Response constructor', - message: `Invalid response status code ${response.status}` - }) - } - - // 2. Set response's body to body's body. - response[kState].body = body.body; - - // 3. If body's type is non-null and response's header list does not contain - // `Content-Type`, then append (`Content-Type`, body's type) to response's header list. - if (body.type != null && !response[kState].headersList.contains('content-type', true)) { - response[kState].headersList.append('content-type', body.type, true); - } - } - } - - /** - * @see https://fetch.spec.whatwg.org/#response-create - * @param {any} innerResponse - * @param {'request' | 'immutable' | 'request-no-cors' | 'response' | 'none'} guard - * @returns {Response} - */ - function fromInnerResponse (innerResponse, guard) { - const response = new Response(kConstruct); - response[kState] = innerResponse; - response[kHeaders] = new Headers(kConstruct); - setHeadersList(response[kHeaders], innerResponse.headersList); - setHeadersGuard(response[kHeaders], guard); - - if (hasFinalizationRegistry && innerResponse.body?.stream) { - registry.register(response, innerResponse.body.stream); - } - - return response - } - - webidl.converters.ReadableStream = webidl.interfaceConverter( - ReadableStream - ); - - webidl.converters.FormData = webidl.interfaceConverter( - FormData - ); - - webidl.converters.URLSearchParams = webidl.interfaceConverter( - URLSearchParams - ); - - // https://fetch.spec.whatwg.org/#typedefdef-xmlhttprequestbodyinit - webidl.converters.XMLHttpRequestBodyInit = function (V, prefix, name) { - if (typeof V === 'string') { - return webidl.converters.USVString(V, prefix, name) - } - - if (isBlobLike(V)) { - return webidl.converters.Blob(V, prefix, name, { strict: false }) - } - - if (ArrayBuffer.isView(V) || types.isArrayBuffer(V)) { - return webidl.converters.BufferSource(V, prefix, name) - } - - if (util.isFormDataLike(V)) { - return webidl.converters.FormData(V, prefix, name, { strict: false }) - } - - if (V instanceof URLSearchParams) { - return webidl.converters.URLSearchParams(V, prefix, name) - } - - return webidl.converters.DOMString(V, prefix, name) - }; - - // https://fetch.spec.whatwg.org/#bodyinit - webidl.converters.BodyInit = function (V, prefix, argument) { - if (V instanceof ReadableStream) { - return webidl.converters.ReadableStream(V, prefix, argument) - } - - // Note: the spec doesn't include async iterables, - // this is an undici extension. - if (V?.[Symbol.asyncIterator]) { - return V - } - - return webidl.converters.XMLHttpRequestBodyInit(V, prefix, argument) - }; - - webidl.converters.ResponseInit = webidl.dictionaryConverter([ - { - key: 'status', - converter: webidl.converters['unsigned short'], - defaultValue: () => 200 - }, - { - key: 'statusText', - converter: webidl.converters.ByteString, - defaultValue: () => '' - }, - { - key: 'headers', - converter: webidl.converters.HeadersInit - } - ]); - - response = { - isNetworkError, - makeNetworkError, - makeResponse, - makeAppropriateNetworkError, - filterResponse, - Response, - cloneResponse, - fromInnerResponse - }; - return response; -} - -var dispatcherWeakref; -var hasRequiredDispatcherWeakref; - -function requireDispatcherWeakref () { - if (hasRequiredDispatcherWeakref) return dispatcherWeakref; - hasRequiredDispatcherWeakref = 1; - - const { kConnected, kSize } = requireSymbols$4(); - - class CompatWeakRef { - constructor (value) { - this.value = value; - } - - deref () { - return this.value[kConnected] === 0 && this.value[kSize] === 0 - ? undefined - : this.value - } - } - - class CompatFinalizer { - constructor (finalizer) { - this.finalizer = finalizer; - } - - register (dispatcher, key) { - if (dispatcher.on) { - dispatcher.on('disconnect', () => { - if (dispatcher[kConnected] === 0 && dispatcher[kSize] === 0) { - this.finalizer(key); - } - }); - } - } - - unregister (key) {} - } - - dispatcherWeakref = function () { - // FIXME: remove workaround when the Node bug is backported to v18 - // https://github.com/nodejs/node/issues/49344#issuecomment-1741776308 - if (process.env.NODE_V8_COVERAGE && process.version.startsWith('v18')) { - process._rawDebug('Using compatibility WeakRef and FinalizationRegistry'); - return { - WeakRef: CompatWeakRef, - FinalizationRegistry: CompatFinalizer - } - } - return { WeakRef, FinalizationRegistry } - }; - return dispatcherWeakref; -} - -/* globals AbortController */ - -var request; -var hasRequiredRequest; - -function requireRequest () { - if (hasRequiredRequest) return request; - hasRequiredRequest = 1; - - const { extractBody, mixinBody, cloneBody } = requireBody(); - const { Headers, fill: fillHeaders, HeadersList, setHeadersGuard, getHeadersGuard, setHeadersList, getHeadersList } = requireHeaders(); - const { FinalizationRegistry } = requireDispatcherWeakref()(); - const util = requireUtil$7(); - const nodeUtil = require$$0$6; - const { - isValidHTTPToken, - sameOrigin, - environmentSettingsObject - } = requireUtil$6(); - const { - forbiddenMethodsSet, - corsSafeListedMethodsSet, - referrerPolicy, - requestRedirect, - requestMode, - requestCredentials, - requestCache, - requestDuplex - } = requireConstants$2(); - const { kEnumerableProperty, normalizedMethodRecordsBase, normalizedMethodRecords } = util; - const { kHeaders, kSignal, kState, kDispatcher } = requireSymbols$3(); - const { webidl } = requireWebidl(); - const { URLSerializer } = requireDataUrl(); - const { kConstruct } = requireSymbols$4(); - const assert = require$$0$4; - const { getMaxListeners, setMaxListeners, getEventListeners, defaultMaxListeners } = require$$8; - - const kAbortController = Symbol('abortController'); - - const requestFinalizer = new FinalizationRegistry(({ signal, abort }) => { - signal.removeEventListener('abort', abort); - }); - - const dependentControllerMap = new WeakMap(); - - function buildAbort (acRef) { - return abort - - function abort () { - const ac = acRef.deref(); - if (ac !== undefined) { - // Currently, there is a problem with FinalizationRegistry. - // https://github.com/nodejs/node/issues/49344 - // https://github.com/nodejs/node/issues/47748 - // In the case of abort, the first step is to unregister from it. - // If the controller can refer to it, it is still registered. - // It will be removed in the future. - requestFinalizer.unregister(abort); - - // Unsubscribe a listener. - // FinalizationRegistry will no longer be called, so this must be done. - this.removeEventListener('abort', abort); - - ac.abort(this.reason); - - const controllerList = dependentControllerMap.get(ac.signal); - - if (controllerList !== undefined) { - if (controllerList.size !== 0) { - for (const ref of controllerList) { - const ctrl = ref.deref(); - if (ctrl !== undefined) { - ctrl.abort(this.reason); - } - } - controllerList.clear(); - } - dependentControllerMap.delete(ac.signal); - } - } - } - } - - let patchMethodWarning = false; - - // https://fetch.spec.whatwg.org/#request-class - class Request { - // https://fetch.spec.whatwg.org/#dom-request - constructor (input, init = {}) { - if (input === kConstruct) { - return - } - - const prefix = 'Request constructor'; - webidl.argumentLengthCheck(arguments, 1, prefix); - - input = webidl.converters.RequestInfo(input, prefix, 'input'); - init = webidl.converters.RequestInit(init, prefix, 'init'); - - // 1. Let request be null. - let request = null; - - // 2. Let fallbackMode be null. - let fallbackMode = null; - - // 3. Let baseURL be this’s relevant settings object’s API base URL. - const baseUrl = environmentSettingsObject.settingsObject.baseUrl; - - // 4. Let signal be null. - let signal = null; - - // 5. If input is a string, then: - if (typeof input === 'string') { - this[kDispatcher] = init.dispatcher; - - // 1. Let parsedURL be the result of parsing input with baseURL. - // 2. If parsedURL is failure, then throw a TypeError. - let parsedURL; - try { - parsedURL = new URL(input, baseUrl); - } catch (err) { - throw new TypeError('Failed to parse URL from ' + input, { cause: err }) - } - - // 3. If parsedURL includes credentials, then throw a TypeError. - if (parsedURL.username || parsedURL.password) { - throw new TypeError( - 'Request cannot be constructed from a URL that includes credentials: ' + - input - ) - } - - // 4. Set request to a new request whose URL is parsedURL. - request = makeRequest({ urlList: [parsedURL] }); - - // 5. Set fallbackMode to "cors". - fallbackMode = 'cors'; - } else { - this[kDispatcher] = init.dispatcher || input[kDispatcher]; - - // 6. Otherwise: - - // 7. Assert: input is a Request object. - assert(input instanceof Request); - - // 8. Set request to input’s request. - request = input[kState]; - - // 9. Set signal to input’s signal. - signal = input[kSignal]; - } - - // 7. Let origin be this’s relevant settings object’s origin. - const origin = environmentSettingsObject.settingsObject.origin; - - // 8. Let window be "client". - let window = 'client'; - - // 9. If request’s window is an environment settings object and its origin - // is same origin with origin, then set window to request’s window. - if ( - request.window?.constructor?.name === 'EnvironmentSettingsObject' && - sameOrigin(request.window, origin) - ) { - window = request.window; - } - - // 10. If init["window"] exists and is non-null, then throw a TypeError. - if (init.window != null) { - throw new TypeError(`'window' option '${window}' must be null`) - } - - // 11. If init["window"] exists, then set window to "no-window". - if ('window' in init) { - window = 'no-window'; - } - - // 12. Set request to a new request with the following properties: - request = makeRequest({ - // URL request’s URL. - // undici implementation note: this is set as the first item in request's urlList in makeRequest - // method request’s method. - method: request.method, - // header list A copy of request’s header list. - // undici implementation note: headersList is cloned in makeRequest - headersList: request.headersList, - // unsafe-request flag Set. - unsafeRequest: request.unsafeRequest, - // client This’s relevant settings object. - client: environmentSettingsObject.settingsObject, - // window window. - window, - // priority request’s priority. - priority: request.priority, - // origin request’s origin. The propagation of the origin is only significant for navigation requests - // being handled by a service worker. In this scenario a request can have an origin that is different - // from the current client. - origin: request.origin, - // referrer request’s referrer. - referrer: request.referrer, - // referrer policy request’s referrer policy. - referrerPolicy: request.referrerPolicy, - // mode request’s mode. - mode: request.mode, - // credentials mode request’s credentials mode. - credentials: request.credentials, - // cache mode request’s cache mode. - cache: request.cache, - // redirect mode request’s redirect mode. - redirect: request.redirect, - // integrity metadata request’s integrity metadata. - integrity: request.integrity, - // keepalive request’s keepalive. - keepalive: request.keepalive, - // reload-navigation flag request’s reload-navigation flag. - reloadNavigation: request.reloadNavigation, - // history-navigation flag request’s history-navigation flag. - historyNavigation: request.historyNavigation, - // URL list A clone of request’s URL list. - urlList: [...request.urlList] - }); - - const initHasKey = Object.keys(init).length !== 0; - - // 13. If init is not empty, then: - if (initHasKey) { - // 1. If request’s mode is "navigate", then set it to "same-origin". - if (request.mode === 'navigate') { - request.mode = 'same-origin'; - } - - // 2. Unset request’s reload-navigation flag. - request.reloadNavigation = false; - - // 3. Unset request’s history-navigation flag. - request.historyNavigation = false; - - // 4. Set request’s origin to "client". - request.origin = 'client'; - - // 5. Set request’s referrer to "client" - request.referrer = 'client'; - - // 6. Set request’s referrer policy to the empty string. - request.referrerPolicy = ''; - - // 7. Set request’s URL to request’s current URL. - request.url = request.urlList[request.urlList.length - 1]; - - // 8. Set request’s URL list to « request’s URL ». - request.urlList = [request.url]; - } - - // 14. If init["referrer"] exists, then: - if (init.referrer !== undefined) { - // 1. Let referrer be init["referrer"]. - const referrer = init.referrer; - - // 2. If referrer is the empty string, then set request’s referrer to "no-referrer". - if (referrer === '') { - request.referrer = 'no-referrer'; - } else { - // 1. Let parsedReferrer be the result of parsing referrer with - // baseURL. - // 2. If parsedReferrer is failure, then throw a TypeError. - let parsedReferrer; - try { - parsedReferrer = new URL(referrer, baseUrl); - } catch (err) { - throw new TypeError(`Referrer "${referrer}" is not a valid URL.`, { cause: err }) - } - - // 3. If one of the following is true - // - parsedReferrer’s scheme is "about" and path is the string "client" - // - parsedReferrer’s origin is not same origin with origin - // then set request’s referrer to "client". - if ( - (parsedReferrer.protocol === 'about:' && parsedReferrer.hostname === 'client') || - (origin && !sameOrigin(parsedReferrer, environmentSettingsObject.settingsObject.baseUrl)) - ) { - request.referrer = 'client'; - } else { - // 4. Otherwise, set request’s referrer to parsedReferrer. - request.referrer = parsedReferrer; - } - } - } - - // 15. If init["referrerPolicy"] exists, then set request’s referrer policy - // to it. - if (init.referrerPolicy !== undefined) { - request.referrerPolicy = init.referrerPolicy; - } - - // 16. Let mode be init["mode"] if it exists, and fallbackMode otherwise. - let mode; - if (init.mode !== undefined) { - mode = init.mode; - } else { - mode = fallbackMode; - } - - // 17. If mode is "navigate", then throw a TypeError. - if (mode === 'navigate') { - throw webidl.errors.exception({ - header: 'Request constructor', - message: 'invalid request mode navigate.' - }) - } - - // 18. If mode is non-null, set request’s mode to mode. - if (mode != null) { - request.mode = mode; - } - - // 19. If init["credentials"] exists, then set request’s credentials mode - // to it. - if (init.credentials !== undefined) { - request.credentials = init.credentials; - } - - // 18. If init["cache"] exists, then set request’s cache mode to it. - if (init.cache !== undefined) { - request.cache = init.cache; - } - - // 21. If request’s cache mode is "only-if-cached" and request’s mode is - // not "same-origin", then throw a TypeError. - if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') { - throw new TypeError( - "'only-if-cached' can be set only with 'same-origin' mode" - ) - } - - // 22. If init["redirect"] exists, then set request’s redirect mode to it. - if (init.redirect !== undefined) { - request.redirect = init.redirect; - } - - // 23. If init["integrity"] exists, then set request’s integrity metadata to it. - if (init.integrity != null) { - request.integrity = String(init.integrity); - } - - // 24. If init["keepalive"] exists, then set request’s keepalive to it. - if (init.keepalive !== undefined) { - request.keepalive = Boolean(init.keepalive); - } - - // 25. If init["method"] exists, then: - if (init.method !== undefined) { - // 1. Let method be init["method"]. - let method = init.method; - - const mayBeNormalized = normalizedMethodRecords[method]; - - if (mayBeNormalized !== undefined) { - // Note: Bypass validation DELETE, GET, HEAD, OPTIONS, POST, PUT, PATCH and these lowercase ones - request.method = mayBeNormalized; - } else { - // 2. If method is not a method or method is a forbidden method, then - // throw a TypeError. - if (!isValidHTTPToken(method)) { - throw new TypeError(`'${method}' is not a valid HTTP method.`) - } - - const upperCase = method.toUpperCase(); - - if (forbiddenMethodsSet.has(upperCase)) { - throw new TypeError(`'${method}' HTTP method is unsupported.`) - } - - // 3. Normalize method. - // https://fetch.spec.whatwg.org/#concept-method-normalize - // Note: must be in uppercase - method = normalizedMethodRecordsBase[upperCase] ?? method; - - // 4. Set request’s method to method. - request.method = method; - } - - if (!patchMethodWarning && request.method === 'patch') { - process.emitWarning('Using `patch` is highly likely to result in a `405 Method Not Allowed`. `PATCH` is much more likely to succeed.', { - code: 'UNDICI-FETCH-patch' - }); - - patchMethodWarning = true; - } - } - - // 26. If init["signal"] exists, then set signal to it. - if (init.signal !== undefined) { - signal = init.signal; - } - - // 27. Set this’s request to request. - this[kState] = request; - - // 28. Set this’s signal to a new AbortSignal object with this’s relevant - // Realm. - // TODO: could this be simplified with AbortSignal.any - // (https://dom.spec.whatwg.org/#dom-abortsignal-any) - const ac = new AbortController(); - this[kSignal] = ac.signal; - - // 29. If signal is not null, then make this’s signal follow signal. - if (signal != null) { - if ( - !signal || - typeof signal.aborted !== 'boolean' || - typeof signal.addEventListener !== 'function' - ) { - throw new TypeError( - "Failed to construct 'Request': member signal is not of type AbortSignal." - ) - } - - if (signal.aborted) { - ac.abort(signal.reason); - } else { - // Keep a strong ref to ac while request object - // is alive. This is needed to prevent AbortController - // from being prematurely garbage collected. - // See, https://github.com/nodejs/undici/issues/1926. - this[kAbortController] = ac; - - const acRef = new WeakRef(ac); - const abort = buildAbort(acRef); - - // Third-party AbortControllers may not work with these. - // See, https://github.com/nodejs/undici/pull/1910#issuecomment-1464495619. - try { - // If the max amount of listeners is equal to the default, increase it - // This is only available in node >= v19.9.0 - if (typeof getMaxListeners === 'function' && getMaxListeners(signal) === defaultMaxListeners) { - setMaxListeners(1500, signal); - } else if (getEventListeners(signal, 'abort').length >= defaultMaxListeners) { - setMaxListeners(1500, signal); - } - } catch {} - - util.addAbortListener(signal, abort); - // The third argument must be a registry key to be unregistered. - // Without it, you cannot unregister. - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/FinalizationRegistry - // abort is used as the unregister key. (because it is unique) - requestFinalizer.register(ac, { signal, abort }, abort); - } - } - - // 30. Set this’s headers to a new Headers object with this’s relevant - // Realm, whose header list is request’s header list and guard is - // "request". - this[kHeaders] = new Headers(kConstruct); - setHeadersList(this[kHeaders], request.headersList); - setHeadersGuard(this[kHeaders], 'request'); - - // 31. If this’s request’s mode is "no-cors", then: - if (mode === 'no-cors') { - // 1. If this’s request’s method is not a CORS-safelisted method, - // then throw a TypeError. - if (!corsSafeListedMethodsSet.has(request.method)) { - throw new TypeError( - `'${request.method} is unsupported in no-cors mode.` - ) - } - - // 2. Set this’s headers’s guard to "request-no-cors". - setHeadersGuard(this[kHeaders], 'request-no-cors'); - } - - // 32. If init is not empty, then: - if (initHasKey) { - /** @type {HeadersList} */ - const headersList = getHeadersList(this[kHeaders]); - // 1. Let headers be a copy of this’s headers and its associated header - // list. - // 2. If init["headers"] exists, then set headers to init["headers"]. - const headers = init.headers !== undefined ? init.headers : new HeadersList(headersList); - - // 3. Empty this’s headers’s header list. - headersList.clear(); - - // 4. If headers is a Headers object, then for each header in its header - // list, append header’s name/header’s value to this’s headers. - if (headers instanceof HeadersList) { - for (const { name, value } of headers.rawValues()) { - headersList.append(name, value, false); - } - // Note: Copy the `set-cookie` meta-data. - headersList.cookies = headers.cookies; - } else { - // 5. Otherwise, fill this’s headers with headers. - fillHeaders(this[kHeaders], headers); - } - } - - // 33. Let inputBody be input’s request’s body if input is a Request - // object; otherwise null. - const inputBody = input instanceof Request ? input[kState].body : null; - - // 34. If either init["body"] exists and is non-null or inputBody is - // non-null, and request’s method is `GET` or `HEAD`, then throw a - // TypeError. - if ( - (init.body != null || inputBody != null) && - (request.method === 'GET' || request.method === 'HEAD') - ) { - throw new TypeError('Request with GET/HEAD method cannot have body.') - } - - // 35. Let initBody be null. - let initBody = null; - - // 36. If init["body"] exists and is non-null, then: - if (init.body != null) { - // 1. Let Content-Type be null. - // 2. Set initBody and Content-Type to the result of extracting - // init["body"], with keepalive set to request’s keepalive. - const [extractedBody, contentType] = extractBody( - init.body, - request.keepalive - ); - initBody = extractedBody; - - // 3, If Content-Type is non-null and this’s headers’s header list does - // not contain `Content-Type`, then append `Content-Type`/Content-Type to - // this’s headers. - if (contentType && !getHeadersList(this[kHeaders]).contains('content-type', true)) { - this[kHeaders].append('content-type', contentType); - } - } - - // 37. Let inputOrInitBody be initBody if it is non-null; otherwise - // inputBody. - const inputOrInitBody = initBody ?? inputBody; - - // 38. If inputOrInitBody is non-null and inputOrInitBody’s source is - // null, then: - if (inputOrInitBody != null && inputOrInitBody.source == null) { - // 1. If initBody is non-null and init["duplex"] does not exist, - // then throw a TypeError. - if (initBody != null && init.duplex == null) { - throw new TypeError('RequestInit: duplex option is required when sending a body.') - } - - // 2. If this’s request’s mode is neither "same-origin" nor "cors", - // then throw a TypeError. - if (request.mode !== 'same-origin' && request.mode !== 'cors') { - throw new TypeError( - 'If request is made from ReadableStream, mode should be "same-origin" or "cors"' - ) - } - - // 3. Set this’s request’s use-CORS-preflight flag. - request.useCORSPreflightFlag = true; - } - - // 39. Let finalBody be inputOrInitBody. - let finalBody = inputOrInitBody; - - // 40. If initBody is null and inputBody is non-null, then: - if (initBody == null && inputBody != null) { - // 1. If input is unusable, then throw a TypeError. - if (util.isDisturbed(inputBody.stream) || inputBody.stream.locked) { - throw new TypeError( - 'Cannot construct a Request with a Request object that has already been used.' - ) - } - - // 2. Set finalBody to the result of creating a proxy for inputBody. - // https://streams.spec.whatwg.org/#readablestream-create-a-proxy - const identityTransform = new TransformStream(); - inputBody.stream.pipeThrough(identityTransform); - finalBody = { - source: inputBody.source, - length: inputBody.length, - stream: identityTransform.readable - }; - } - - // 41. Set this’s request’s body to finalBody. - this[kState].body = finalBody; - } - - // Returns request’s HTTP method, which is "GET" by default. - get method () { - webidl.brandCheck(this, Request); - - // The method getter steps are to return this’s request’s method. - return this[kState].method - } - - // Returns the URL of request as a string. - get url () { - webidl.brandCheck(this, Request); - - // The url getter steps are to return this’s request’s URL, serialized. - return URLSerializer(this[kState].url) - } - - // Returns a Headers object consisting of the headers associated with request. - // Note that headers added in the network layer by the user agent will not - // be accounted for in this object, e.g., the "Host" header. - get headers () { - webidl.brandCheck(this, Request); - - // The headers getter steps are to return this’s headers. - return this[kHeaders] - } - - // Returns the kind of resource requested by request, e.g., "document" - // or "script". - get destination () { - webidl.brandCheck(this, Request); - - // The destination getter are to return this’s request’s destination. - return this[kState].destination - } - - // Returns the referrer of request. Its value can be a same-origin URL if - // explicitly set in init, the empty string to indicate no referrer, and - // "about:client" when defaulting to the global’s default. This is used - // during fetching to determine the value of the `Referer` header of the - // request being made. - get referrer () { - webidl.brandCheck(this, Request); - - // 1. If this’s request’s referrer is "no-referrer", then return the - // empty string. - if (this[kState].referrer === 'no-referrer') { - return '' - } - - // 2. If this’s request’s referrer is "client", then return - // "about:client". - if (this[kState].referrer === 'client') { - return 'about:client' - } - - // Return this’s request’s referrer, serialized. - return this[kState].referrer.toString() - } - - // Returns the referrer policy associated with request. - // This is used during fetching to compute the value of the request’s - // referrer. - get referrerPolicy () { - webidl.brandCheck(this, Request); - - // The referrerPolicy getter steps are to return this’s request’s referrer policy. - return this[kState].referrerPolicy - } - - // Returns the mode associated with request, which is a string indicating - // whether the request will use CORS, or will be restricted to same-origin - // URLs. - get mode () { - webidl.brandCheck(this, Request); - - // The mode getter steps are to return this’s request’s mode. - return this[kState].mode - } - - // Returns the credentials mode associated with request, - // which is a string indicating whether credentials will be sent with the - // request always, never, or only when sent to a same-origin URL. - get credentials () { - // The credentials getter steps are to return this’s request’s credentials mode. - return this[kState].credentials - } - - // Returns the cache mode associated with request, - // which is a string indicating how the request will - // interact with the browser’s cache when fetching. - get cache () { - webidl.brandCheck(this, Request); - - // The cache getter steps are to return this’s request’s cache mode. - return this[kState].cache - } - - // Returns the redirect mode associated with request, - // which is a string indicating how redirects for the - // request will be handled during fetching. A request - // will follow redirects by default. - get redirect () { - webidl.brandCheck(this, Request); - - // The redirect getter steps are to return this’s request’s redirect mode. - return this[kState].redirect - } - - // Returns request’s subresource integrity metadata, which is a - // cryptographic hash of the resource being fetched. Its value - // consists of multiple hashes separated by whitespace. [SRI] - get integrity () { - webidl.brandCheck(this, Request); - - // The integrity getter steps are to return this’s request’s integrity - // metadata. - return this[kState].integrity - } - - // Returns a boolean indicating whether or not request can outlive the - // global in which it was created. - get keepalive () { - webidl.brandCheck(this, Request); - - // The keepalive getter steps are to return this’s request’s keepalive. - return this[kState].keepalive - } - - // Returns a boolean indicating whether or not request is for a reload - // navigation. - get isReloadNavigation () { - webidl.brandCheck(this, Request); - - // The isReloadNavigation getter steps are to return true if this’s - // request’s reload-navigation flag is set; otherwise false. - return this[kState].reloadNavigation - } - - // Returns a boolean indicating whether or not request is for a history - // navigation (a.k.a. back-forward navigation). - get isHistoryNavigation () { - webidl.brandCheck(this, Request); - - // The isHistoryNavigation getter steps are to return true if this’s request’s - // history-navigation flag is set; otherwise false. - return this[kState].historyNavigation - } - - // Returns the signal associated with request, which is an AbortSignal - // object indicating whether or not request has been aborted, and its - // abort event handler. - get signal () { - webidl.brandCheck(this, Request); - - // The signal getter steps are to return this’s signal. - return this[kSignal] - } - - get body () { - webidl.brandCheck(this, Request); - - return this[kState].body ? this[kState].body.stream : null - } - - get bodyUsed () { - webidl.brandCheck(this, Request); - - return !!this[kState].body && util.isDisturbed(this[kState].body.stream) - } - - get duplex () { - webidl.brandCheck(this, Request); - - return 'half' - } - - // Returns a clone of request. - clone () { - webidl.brandCheck(this, Request); - - // 1. If this is unusable, then throw a TypeError. - if (this.bodyUsed || this.body?.locked) { - throw new TypeError('unusable') - } - - // 2. Let clonedRequest be the result of cloning this’s request. - const clonedRequest = cloneRequest(this[kState]); - - // 3. Let clonedRequestObject be the result of creating a Request object, - // given clonedRequest, this’s headers’s guard, and this’s relevant Realm. - // 4. Make clonedRequestObject’s signal follow this’s signal. - const ac = new AbortController(); - if (this.signal.aborted) { - ac.abort(this.signal.reason); - } else { - let list = dependentControllerMap.get(this.signal); - if (list === undefined) { - list = new Set(); - dependentControllerMap.set(this.signal, list); - } - const acRef = new WeakRef(ac); - list.add(acRef); - util.addAbortListener( - ac.signal, - buildAbort(acRef) - ); - } - - // 4. Return clonedRequestObject. - return fromInnerRequest(clonedRequest, ac.signal, getHeadersGuard(this[kHeaders])) - } - - [nodeUtil.inspect.custom] (depth, options) { - if (options.depth === null) { - options.depth = 2; - } - - options.colors ??= true; - - const properties = { - method: this.method, - url: this.url, - headers: this.headers, - destination: this.destination, - referrer: this.referrer, - referrerPolicy: this.referrerPolicy, - mode: this.mode, - credentials: this.credentials, - cache: this.cache, - redirect: this.redirect, - integrity: this.integrity, - keepalive: this.keepalive, - isReloadNavigation: this.isReloadNavigation, - isHistoryNavigation: this.isHistoryNavigation, - signal: this.signal - }; - - return `Request ${nodeUtil.formatWithOptions(options, properties)}` - } - } - - mixinBody(Request); - - // https://fetch.spec.whatwg.org/#requests - function makeRequest (init) { - return { - method: init.method ?? 'GET', - localURLsOnly: init.localURLsOnly ?? false, - unsafeRequest: init.unsafeRequest ?? false, - body: init.body ?? null, - client: init.client ?? null, - reservedClient: init.reservedClient ?? null, - replacesClientId: init.replacesClientId ?? '', - window: init.window ?? 'client', - keepalive: init.keepalive ?? false, - serviceWorkers: init.serviceWorkers ?? 'all', - initiator: init.initiator ?? '', - destination: init.destination ?? '', - priority: init.priority ?? null, - origin: init.origin ?? 'client', - policyContainer: init.policyContainer ?? 'client', - referrer: init.referrer ?? 'client', - referrerPolicy: init.referrerPolicy ?? '', - mode: init.mode ?? 'no-cors', - useCORSPreflightFlag: init.useCORSPreflightFlag ?? false, - credentials: init.credentials ?? 'same-origin', - useCredentials: init.useCredentials ?? false, - cache: init.cache ?? 'default', - redirect: init.redirect ?? 'follow', - integrity: init.integrity ?? '', - cryptoGraphicsNonceMetadata: init.cryptoGraphicsNonceMetadata ?? '', - parserMetadata: init.parserMetadata ?? '', - reloadNavigation: init.reloadNavigation ?? false, - historyNavigation: init.historyNavigation ?? false, - userActivation: init.userActivation ?? false, - taintedOrigin: init.taintedOrigin ?? false, - redirectCount: init.redirectCount ?? 0, - responseTainting: init.responseTainting ?? 'basic', - preventNoCacheCacheControlHeaderModification: init.preventNoCacheCacheControlHeaderModification ?? false, - done: init.done ?? false, - timingAllowFailed: init.timingAllowFailed ?? false, - urlList: init.urlList, - url: init.urlList[0], - headersList: init.headersList - ? new HeadersList(init.headersList) - : new HeadersList() - } - } - - // https://fetch.spec.whatwg.org/#concept-request-clone - function cloneRequest (request) { - // To clone a request request, run these steps: - - // 1. Let newRequest be a copy of request, except for its body. - const newRequest = makeRequest({ ...request, body: null }); - - // 2. If request’s body is non-null, set newRequest’s body to the - // result of cloning request’s body. - if (request.body != null) { - newRequest.body = cloneBody(request.body); - } - - // 3. Return newRequest. - return newRequest - } - - /** - * @see https://fetch.spec.whatwg.org/#request-create - * @param {any} innerRequest - * @param {AbortSignal} signal - * @param {'request' | 'immutable' | 'request-no-cors' | 'response' | 'none'} guard - * @returns {Request} - */ - function fromInnerRequest (innerRequest, signal, guard) { - const request = new Request(kConstruct); - request[kState] = innerRequest; - request[kSignal] = signal; - request[kHeaders] = new Headers(kConstruct); - setHeadersList(request[kHeaders], innerRequest.headersList); - setHeadersGuard(request[kHeaders], guard); - return request - } - - Object.defineProperties(Request.prototype, { - method: kEnumerableProperty, - url: kEnumerableProperty, - headers: kEnumerableProperty, - redirect: kEnumerableProperty, - clone: kEnumerableProperty, - signal: kEnumerableProperty, - duplex: kEnumerableProperty, - destination: kEnumerableProperty, - body: kEnumerableProperty, - bodyUsed: kEnumerableProperty, - isHistoryNavigation: kEnumerableProperty, - isReloadNavigation: kEnumerableProperty, - keepalive: kEnumerableProperty, - integrity: kEnumerableProperty, - cache: kEnumerableProperty, - credentials: kEnumerableProperty, - attribute: kEnumerableProperty, - referrerPolicy: kEnumerableProperty, - referrer: kEnumerableProperty, - mode: kEnumerableProperty, - [Symbol.toStringTag]: { - value: 'Request', - configurable: true - } - }); - - webidl.converters.Request = webidl.interfaceConverter( - Request - ); - - // https://fetch.spec.whatwg.org/#requestinfo - webidl.converters.RequestInfo = function (V, prefix, argument) { - if (typeof V === 'string') { - return webidl.converters.USVString(V, prefix, argument) - } - - if (V instanceof Request) { - return webidl.converters.Request(V, prefix, argument) - } - - return webidl.converters.USVString(V, prefix, argument) - }; - - webidl.converters.AbortSignal = webidl.interfaceConverter( - AbortSignal - ); - - // https://fetch.spec.whatwg.org/#requestinit - webidl.converters.RequestInit = webidl.dictionaryConverter([ - { - key: 'method', - converter: webidl.converters.ByteString - }, - { - key: 'headers', - converter: webidl.converters.HeadersInit - }, - { - key: 'body', - converter: webidl.nullableConverter( - webidl.converters.BodyInit - ) - }, - { - key: 'referrer', - converter: webidl.converters.USVString - }, - { - key: 'referrerPolicy', - converter: webidl.converters.DOMString, - // https://w3c.github.io/webappsec-referrer-policy/#referrer-policy - allowedValues: referrerPolicy - }, - { - key: 'mode', - converter: webidl.converters.DOMString, - // https://fetch.spec.whatwg.org/#concept-request-mode - allowedValues: requestMode - }, - { - key: 'credentials', - converter: webidl.converters.DOMString, - // https://fetch.spec.whatwg.org/#requestcredentials - allowedValues: requestCredentials - }, - { - key: 'cache', - converter: webidl.converters.DOMString, - // https://fetch.spec.whatwg.org/#requestcache - allowedValues: requestCache - }, - { - key: 'redirect', - converter: webidl.converters.DOMString, - // https://fetch.spec.whatwg.org/#requestredirect - allowedValues: requestRedirect - }, - { - key: 'integrity', - converter: webidl.converters.DOMString - }, - { - key: 'keepalive', - converter: webidl.converters.boolean - }, - { - key: 'signal', - converter: webidl.nullableConverter( - (signal) => webidl.converters.AbortSignal( - signal, - 'RequestInit', - 'signal', - { strict: false } - ) - ) - }, - { - key: 'window', - converter: webidl.converters.any - }, - { - key: 'duplex', - converter: webidl.converters.DOMString, - allowedValues: requestDuplex - }, - { - key: 'dispatcher', // undici specific option - converter: webidl.converters.any - } - ]); - - request = { Request, makeRequest, fromInnerRequest, cloneRequest }; - return request; -} - -var fetch_1; -var hasRequiredFetch; - -function requireFetch () { - if (hasRequiredFetch) return fetch_1; - hasRequiredFetch = 1; - - const { - makeNetworkError, - makeAppropriateNetworkError, - filterResponse, - makeResponse, - fromInnerResponse - } = requireResponse(); - const { HeadersList } = requireHeaders(); - const { Request, cloneRequest } = requireRequest(); - const zlib = require$$1; - const { - bytesMatch, - makePolicyContainer, - clonePolicyContainer, - requestBadPort, - TAOCheck, - appendRequestOriginHeader, - responseLocationURL, - requestCurrentURL, - setRequestReferrerPolicyOnRedirect, - tryUpgradeRequestToAPotentiallyTrustworthyURL, - createOpaqueTimingInfo, - appendFetchMetadata, - corsCheck, - crossOriginResourcePolicyCheck, - determineRequestsReferrer, - coarsenedSharedCurrentTime, - createDeferredPromise, - isBlobLike, - sameOrigin, - isCancelled, - isAborted, - isErrorLike, - fullyReadBody, - readableStreamClose, - isomorphicEncode, - urlIsLocal, - urlIsHttpHttpsScheme, - urlHasHttpsScheme, - clampAndCoarsenConnectionTimingInfo, - simpleRangeHeaderValue, - buildContentRange, - createInflate, - extractMimeType - } = requireUtil$6(); - const { kState, kDispatcher } = requireSymbols$3(); - const assert = require$$0$4; - const { safelyExtractBody, extractBody } = requireBody(); - const { - redirectStatusSet, - nullBodyStatus, - safeMethodsSet, - requestBodyHeader, - subresourceSet - } = requireConstants$2(); - const EE = require$$8; - const { Readable, pipeline, finished } = require$$0$5; - const { addAbortListener, isErrored, isReadable, bufferToLowerCasedHeaderName } = requireUtil$7(); - const { dataURLProcessor, serializeAMimeType, minimizeSupportedMimeType } = requireDataUrl(); - const { getGlobalDispatcher } = requireGlobal(); - const { webidl } = requireWebidl(); - const { STATUS_CODES } = require$$2; - const GET_OR_HEAD = ['GET', 'HEAD']; - - const defaultUserAgent = typeof __UNDICI_IS_NODE__ !== 'undefined' || typeof esbuildDetection !== 'undefined' - ? 'node' - : 'undici'; - - /** @type {import('buffer').resolveObjectURL} */ - let resolveObjectURL; - - class Fetch extends EE { - constructor (dispatcher) { - super(); - - this.dispatcher = dispatcher; - this.connection = null; - this.dump = false; - this.state = 'ongoing'; - } - - terminate (reason) { - if (this.state !== 'ongoing') { - return - } - - this.state = 'terminated'; - this.connection?.destroy(reason); - this.emit('terminated', reason); - } - - // https://fetch.spec.whatwg.org/#fetch-controller-abort - abort (error) { - if (this.state !== 'ongoing') { - return - } - - // 1. Set controller’s state to "aborted". - this.state = 'aborted'; - - // 2. Let fallbackError be an "AbortError" DOMException. - // 3. Set error to fallbackError if it is not given. - if (!error) { - error = new DOMException('The operation was aborted.', 'AbortError'); - } - - // 4. Let serializedError be StructuredSerialize(error). - // If that threw an exception, catch it, and let - // serializedError be StructuredSerialize(fallbackError). - - // 5. Set controller’s serialized abort reason to serializedError. - this.serializedAbortReason = error; - - this.connection?.destroy(error); - this.emit('terminated', error); - } - } - - function handleFetchDone (response) { - finalizeAndReportTiming(response, 'fetch'); - } - - // https://fetch.spec.whatwg.org/#fetch-method - function fetch (input, init = undefined) { - webidl.argumentLengthCheck(arguments, 1, 'globalThis.fetch'); - - // 1. Let p be a new promise. - let p = createDeferredPromise(); - - // 2. Let requestObject be the result of invoking the initial value of - // Request as constructor with input and init as arguments. If this throws - // an exception, reject p with it and return p. - let requestObject; - - try { - requestObject = new Request(input, init); - } catch (e) { - p.reject(e); - return p.promise - } - - // 3. Let request be requestObject’s request. - const request = requestObject[kState]; - - // 4. If requestObject’s signal’s aborted flag is set, then: - if (requestObject.signal.aborted) { - // 1. Abort the fetch() call with p, request, null, and - // requestObject’s signal’s abort reason. - abortFetch(p, request, null, requestObject.signal.reason); - - // 2. Return p. - return p.promise - } - - // 5. Let globalObject be request’s client’s global object. - const globalObject = request.client.globalObject; - - // 6. If globalObject is a ServiceWorkerGlobalScope object, then set - // request’s service-workers mode to "none". - if (globalObject?.constructor?.name === 'ServiceWorkerGlobalScope') { - request.serviceWorkers = 'none'; - } - - // 7. Let responseObject be null. - let responseObject = null; - - // 8. Let relevantRealm be this’s relevant Realm. - - // 9. Let locallyAborted be false. - let locallyAborted = false; - - // 10. Let controller be null. - let controller = null; - - // 11. Add the following abort steps to requestObject’s signal: - addAbortListener( - requestObject.signal, - () => { - // 1. Set locallyAborted to true. - locallyAborted = true; - - // 2. Assert: controller is non-null. - assert(controller != null); - - // 3. Abort controller with requestObject’s signal’s abort reason. - controller.abort(requestObject.signal.reason); - - const realResponse = responseObject?.deref(); - - // 4. Abort the fetch() call with p, request, responseObject, - // and requestObject’s signal’s abort reason. - abortFetch(p, request, realResponse, requestObject.signal.reason); - } - ); - - // 12. Let handleFetchDone given response response be to finalize and - // report timing with response, globalObject, and "fetch". - // see function handleFetchDone - - // 13. Set controller to the result of calling fetch given request, - // with processResponseEndOfBody set to handleFetchDone, and processResponse - // given response being these substeps: - - const processResponse = (response) => { - // 1. If locallyAborted is true, terminate these substeps. - if (locallyAborted) { - return - } - - // 2. If response’s aborted flag is set, then: - if (response.aborted) { - // 1. Let deserializedError be the result of deserialize a serialized - // abort reason given controller’s serialized abort reason and - // relevantRealm. - - // 2. Abort the fetch() call with p, request, responseObject, and - // deserializedError. - - abortFetch(p, request, responseObject, controller.serializedAbortReason); - return - } - - // 3. If response is a network error, then reject p with a TypeError - // and terminate these substeps. - if (response.type === 'error') { - p.reject(new TypeError('fetch failed', { cause: response.error })); - return - } - - // 4. Set responseObject to the result of creating a Response object, - // given response, "immutable", and relevantRealm. - responseObject = new WeakRef(fromInnerResponse(response, 'immutable')); - - // 5. Resolve p with responseObject. - p.resolve(responseObject.deref()); - p = null; - }; - - controller = fetching({ - request, - processResponseEndOfBody: handleFetchDone, - processResponse, - dispatcher: requestObject[kDispatcher] // undici - }); - - // 14. Return p. - return p.promise - } - - // https://fetch.spec.whatwg.org/#finalize-and-report-timing - function finalizeAndReportTiming (response, initiatorType = 'other') { - // 1. If response is an aborted network error, then return. - if (response.type === 'error' && response.aborted) { - return - } - - // 2. If response’s URL list is null or empty, then return. - if (!response.urlList?.length) { - return - } - - // 3. Let originalURL be response’s URL list[0]. - const originalURL = response.urlList[0]; - - // 4. Let timingInfo be response’s timing info. - let timingInfo = response.timingInfo; - - // 5. Let cacheState be response’s cache state. - let cacheState = response.cacheState; - - // 6. If originalURL’s scheme is not an HTTP(S) scheme, then return. - if (!urlIsHttpHttpsScheme(originalURL)) { - return - } - - // 7. If timingInfo is null, then return. - if (timingInfo === null) { - return - } - - // 8. If response’s timing allow passed flag is not set, then: - if (!response.timingAllowPassed) { - // 1. Set timingInfo to a the result of creating an opaque timing info for timingInfo. - timingInfo = createOpaqueTimingInfo({ - startTime: timingInfo.startTime - }); - - // 2. Set cacheState to the empty string. - cacheState = ''; - } - - // 9. Set timingInfo’s end time to the coarsened shared current time - // given global’s relevant settings object’s cross-origin isolated - // capability. - // TODO: given global’s relevant settings object’s cross-origin isolated - // capability? - timingInfo.endTime = coarsenedSharedCurrentTime(); - - // 10. Set response’s timing info to timingInfo. - response.timingInfo = timingInfo; - - // 11. Mark resource timing for timingInfo, originalURL, initiatorType, - // global, and cacheState. - markResourceTiming( - timingInfo, - originalURL.href, - initiatorType, - globalThis, - cacheState - ); - } - - // https://w3c.github.io/resource-timing/#dfn-mark-resource-timing - const markResourceTiming = performance.markResourceTiming; - - // https://fetch.spec.whatwg.org/#abort-fetch - function abortFetch (p, request, responseObject, error) { - // 1. Reject promise with error. - if (p) { - // We might have already resolved the promise at this stage - p.reject(error); - } - - // 2. If request’s body is not null and is readable, then cancel request’s - // body with error. - if (request.body != null && isReadable(request.body?.stream)) { - request.body.stream.cancel(error).catch((err) => { - if (err.code === 'ERR_INVALID_STATE') { - // Node bug? - return - } - throw err - }); - } - - // 3. If responseObject is null, then return. - if (responseObject == null) { - return - } - - // 4. Let response be responseObject’s response. - const response = responseObject[kState]; - - // 5. If response’s body is not null and is readable, then error response’s - // body with error. - if (response.body != null && isReadable(response.body?.stream)) { - response.body.stream.cancel(error).catch((err) => { - if (err.code === 'ERR_INVALID_STATE') { - // Node bug? - return - } - throw err - }); - } - } - - // https://fetch.spec.whatwg.org/#fetching - function fetching ({ - request, - processRequestBodyChunkLength, - processRequestEndOfBody, - processResponse, - processResponseEndOfBody, - processResponseConsumeBody, - useParallelQueue = false, - dispatcher = getGlobalDispatcher() // undici - }) { - // Ensure that the dispatcher is set accordingly - assert(dispatcher); - - // 1. Let taskDestination be null. - let taskDestination = null; - - // 2. Let crossOriginIsolatedCapability be false. - let crossOriginIsolatedCapability = false; - - // 3. If request’s client is non-null, then: - if (request.client != null) { - // 1. Set taskDestination to request’s client’s global object. - taskDestination = request.client.globalObject; - - // 2. Set crossOriginIsolatedCapability to request’s client’s cross-origin - // isolated capability. - crossOriginIsolatedCapability = - request.client.crossOriginIsolatedCapability; - } - - // 4. If useParallelQueue is true, then set taskDestination to the result of - // starting a new parallel queue. - // TODO - - // 5. Let timingInfo be a new fetch timing info whose start time and - // post-redirect start time are the coarsened shared current time given - // crossOriginIsolatedCapability. - const currentTime = coarsenedSharedCurrentTime(crossOriginIsolatedCapability); - const timingInfo = createOpaqueTimingInfo({ - startTime: currentTime - }); - - // 6. Let fetchParams be a new fetch params whose - // request is request, - // timing info is timingInfo, - // process request body chunk length is processRequestBodyChunkLength, - // process request end-of-body is processRequestEndOfBody, - // process response is processResponse, - // process response consume body is processResponseConsumeBody, - // process response end-of-body is processResponseEndOfBody, - // task destination is taskDestination, - // and cross-origin isolated capability is crossOriginIsolatedCapability. - const fetchParams = { - controller: new Fetch(dispatcher), - request, - timingInfo, - processRequestBodyChunkLength, - processRequestEndOfBody, - processResponse, - processResponseConsumeBody, - processResponseEndOfBody, - taskDestination, - crossOriginIsolatedCapability - }; - - // 7. If request’s body is a byte sequence, then set request’s body to - // request’s body as a body. - // NOTE: Since fetching is only called from fetch, body should already be - // extracted. - assert(!request.body || request.body.stream); - - // 8. If request’s window is "client", then set request’s window to request’s - // client, if request’s client’s global object is a Window object; otherwise - // "no-window". - if (request.window === 'client') { - // TODO: What if request.client is null? - request.window = - request.client?.globalObject?.constructor?.name === 'Window' - ? request.client - : 'no-window'; - } - - // 9. If request’s origin is "client", then set request’s origin to request’s - // client’s origin. - if (request.origin === 'client') { - request.origin = request.client.origin; - } - - // 10. If all of the following conditions are true: - // TODO - - // 11. If request’s policy container is "client", then: - if (request.policyContainer === 'client') { - // 1. If request’s client is non-null, then set request’s policy - // container to a clone of request’s client’s policy container. [HTML] - if (request.client != null) { - request.policyContainer = clonePolicyContainer( - request.client.policyContainer - ); - } else { - // 2. Otherwise, set request’s policy container to a new policy - // container. - request.policyContainer = makePolicyContainer(); - } - } - - // 12. If request’s header list does not contain `Accept`, then: - if (!request.headersList.contains('accept', true)) { - // 1. Let value be `*/*`. - const value = '*/*'; - - // 2. A user agent should set value to the first matching statement, if - // any, switching on request’s destination: - // "document" - // "frame" - // "iframe" - // `text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8` - // "image" - // `image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5` - // "style" - // `text/css,*/*;q=0.1` - // TODO - - // 3. Append `Accept`/value to request’s header list. - request.headersList.append('accept', value, true); - } - - // 13. If request’s header list does not contain `Accept-Language`, then - // user agents should append `Accept-Language`/an appropriate value to - // request’s header list. - if (!request.headersList.contains('accept-language', true)) { - request.headersList.append('accept-language', '*', true); - } - - // 14. If request’s priority is null, then use request’s initiator and - // destination appropriately in setting request’s priority to a - // user-agent-defined object. - if (request.priority === null) ; - - // 15. If request is a subresource request, then: - if (subresourceSet.has(request.destination)) ; - - // 16. Run main fetch given fetchParams. - mainFetch(fetchParams) - .catch(err => { - fetchParams.controller.terminate(err); - }); - - // 17. Return fetchParam's controller - return fetchParams.controller - } - - // https://fetch.spec.whatwg.org/#concept-main-fetch - async function mainFetch (fetchParams, recursive = false) { - // 1. Let request be fetchParams’s request. - const request = fetchParams.request; - - // 2. Let response be null. - let response = null; - - // 3. If request’s local-URLs-only flag is set and request’s current URL is - // not local, then set response to a network error. - if (request.localURLsOnly && !urlIsLocal(requestCurrentURL(request))) { - response = makeNetworkError('local URLs only'); - } - - // 4. Run report Content Security Policy violations for request. - // TODO - - // 5. Upgrade request to a potentially trustworthy URL, if appropriate. - tryUpgradeRequestToAPotentiallyTrustworthyURL(request); - - // 6. If should request be blocked due to a bad port, should fetching request - // be blocked as mixed content, or should request be blocked by Content - // Security Policy returns blocked, then set response to a network error. - if (requestBadPort(request) === 'blocked') { - response = makeNetworkError('bad port'); - } - // TODO: should fetching request be blocked as mixed content? - // TODO: should request be blocked by Content Security Policy? - - // 7. If request’s referrer policy is the empty string, then set request’s - // referrer policy to request’s policy container’s referrer policy. - if (request.referrerPolicy === '') { - request.referrerPolicy = request.policyContainer.referrerPolicy; - } - - // 8. If request’s referrer is not "no-referrer", then set request’s - // referrer to the result of invoking determine request’s referrer. - if (request.referrer !== 'no-referrer') { - request.referrer = determineRequestsReferrer(request); - } - - // 9. Set request’s current URL’s scheme to "https" if all of the following - // conditions are true: - // - request’s current URL’s scheme is "http" - // - request’s current URL’s host is a domain - // - Matching request’s current URL’s host per Known HSTS Host Domain Name - // Matching results in either a superdomain match with an asserted - // includeSubDomains directive or a congruent match (with or without an - // asserted includeSubDomains directive). [HSTS] - // TODO - - // 10. If recursive is false, then run the remaining steps in parallel. - // TODO - - // 11. If response is null, then set response to the result of running - // the steps corresponding to the first matching statement: - if (response === null) { - response = await (async () => { - const currentURL = requestCurrentURL(request); - - if ( - // - request’s current URL’s origin is same origin with request’s origin, - // and request’s response tainting is "basic" - (sameOrigin(currentURL, request.url) && request.responseTainting === 'basic') || - // request’s current URL’s scheme is "data" - (currentURL.protocol === 'data:') || - // - request’s mode is "navigate" or "websocket" - (request.mode === 'navigate' || request.mode === 'websocket') - ) { - // 1. Set request’s response tainting to "basic". - request.responseTainting = 'basic'; - - // 2. Return the result of running scheme fetch given fetchParams. - return await schemeFetch(fetchParams) - } - - // request’s mode is "same-origin" - if (request.mode === 'same-origin') { - // 1. Return a network error. - return makeNetworkError('request mode cannot be "same-origin"') - } - - // request’s mode is "no-cors" - if (request.mode === 'no-cors') { - // 1. If request’s redirect mode is not "follow", then return a network - // error. - if (request.redirect !== 'follow') { - return makeNetworkError( - 'redirect mode cannot be "follow" for "no-cors" request' - ) - } - - // 2. Set request’s response tainting to "opaque". - request.responseTainting = 'opaque'; - - // 3. Return the result of running scheme fetch given fetchParams. - return await schemeFetch(fetchParams) - } - - // request’s current URL’s scheme is not an HTTP(S) scheme - if (!urlIsHttpHttpsScheme(requestCurrentURL(request))) { - // Return a network error. - return makeNetworkError('URL scheme must be a HTTP(S) scheme') - } - - // - request’s use-CORS-preflight flag is set - // - request’s unsafe-request flag is set and either request’s method is - // not a CORS-safelisted method or CORS-unsafe request-header names with - // request’s header list is not empty - // 1. Set request’s response tainting to "cors". - // 2. Let corsWithPreflightResponse be the result of running HTTP fetch - // given fetchParams and true. - // 3. If corsWithPreflightResponse is a network error, then clear cache - // entries using request. - // 4. Return corsWithPreflightResponse. - // TODO - - // Otherwise - // 1. Set request’s response tainting to "cors". - request.responseTainting = 'cors'; - - // 2. Return the result of running HTTP fetch given fetchParams. - return await httpFetch(fetchParams) - })(); - } - - // 12. If recursive is true, then return response. - if (recursive) { - return response - } - - // 13. If response is not a network error and response is not a filtered - // response, then: - if (response.status !== 0 && !response.internalResponse) { - // If request’s response tainting is "cors", then: - if (request.responseTainting === 'cors') ; - - // Set response to the following filtered response with response as its - // internal response, depending on request’s response tainting: - if (request.responseTainting === 'basic') { - response = filterResponse(response, 'basic'); - } else if (request.responseTainting === 'cors') { - response = filterResponse(response, 'cors'); - } else if (request.responseTainting === 'opaque') { - response = filterResponse(response, 'opaque'); - } else { - assert(false); - } - } - - // 14. Let internalResponse be response, if response is a network error, - // and response’s internal response otherwise. - let internalResponse = - response.status === 0 ? response : response.internalResponse; - - // 15. If internalResponse’s URL list is empty, then set it to a clone of - // request’s URL list. - if (internalResponse.urlList.length === 0) { - internalResponse.urlList.push(...request.urlList); - } - - // 16. If request’s timing allow failed flag is unset, then set - // internalResponse’s timing allow passed flag. - if (!request.timingAllowFailed) { - response.timingAllowPassed = true; - } - - // 17. If response is not a network error and any of the following returns - // blocked - // - should internalResponse to request be blocked as mixed content - // - should internalResponse to request be blocked by Content Security Policy - // - should internalResponse to request be blocked due to its MIME type - // - should internalResponse to request be blocked due to nosniff - // TODO - - // 18. If response’s type is "opaque", internalResponse’s status is 206, - // internalResponse’s range-requested flag is set, and request’s header - // list does not contain `Range`, then set response and internalResponse - // to a network error. - if ( - response.type === 'opaque' && - internalResponse.status === 206 && - internalResponse.rangeRequested && - !request.headers.contains('range', true) - ) { - response = internalResponse = makeNetworkError(); - } - - // 19. If response is not a network error and either request’s method is - // `HEAD` or `CONNECT`, or internalResponse’s status is a null body status, - // set internalResponse’s body to null and disregard any enqueuing toward - // it (if any). - if ( - response.status !== 0 && - (request.method === 'HEAD' || - request.method === 'CONNECT' || - nullBodyStatus.includes(internalResponse.status)) - ) { - internalResponse.body = null; - fetchParams.controller.dump = true; - } - - // 20. If request’s integrity metadata is not the empty string, then: - if (request.integrity) { - // 1. Let processBodyError be this step: run fetch finale given fetchParams - // and a network error. - const processBodyError = (reason) => - fetchFinale(fetchParams, makeNetworkError(reason)); - - // 2. If request’s response tainting is "opaque", or response’s body is null, - // then run processBodyError and abort these steps. - if (request.responseTainting === 'opaque' || response.body == null) { - processBodyError(response.error); - return - } - - // 3. Let processBody given bytes be these steps: - const processBody = (bytes) => { - // 1. If bytes do not match request’s integrity metadata, - // then run processBodyError and abort these steps. [SRI] - if (!bytesMatch(bytes, request.integrity)) { - processBodyError('integrity mismatch'); - return - } - - // 2. Set response’s body to bytes as a body. - response.body = safelyExtractBody(bytes)[0]; - - // 3. Run fetch finale given fetchParams and response. - fetchFinale(fetchParams, response); - }; - - // 4. Fully read response’s body given processBody and processBodyError. - await fullyReadBody(response.body, processBody, processBodyError); - } else { - // 21. Otherwise, run fetch finale given fetchParams and response. - fetchFinale(fetchParams, response); - } - } - - // https://fetch.spec.whatwg.org/#concept-scheme-fetch - // given a fetch params fetchParams - function schemeFetch (fetchParams) { - // Note: since the connection is destroyed on redirect, which sets fetchParams to a - // cancelled state, we do not want this condition to trigger *unless* there have been - // no redirects. See https://github.com/nodejs/undici/issues/1776 - // 1. If fetchParams is canceled, then return the appropriate network error for fetchParams. - if (isCancelled(fetchParams) && fetchParams.request.redirectCount === 0) { - return Promise.resolve(makeAppropriateNetworkError(fetchParams)) - } - - // 2. Let request be fetchParams’s request. - const { request } = fetchParams; - - const { protocol: scheme } = requestCurrentURL(request); - - // 3. Switch on request’s current URL’s scheme and run the associated steps: - switch (scheme) { - case 'about:': { - // If request’s current URL’s path is the string "blank", then return a new response - // whose status message is `OK`, header list is « (`Content-Type`, `text/html;charset=utf-8`) », - // and body is the empty byte sequence as a body. - - // Otherwise, return a network error. - return Promise.resolve(makeNetworkError('about scheme is not supported')) - } - case 'blob:': { - if (!resolveObjectURL) { - resolveObjectURL = require$$0$3.resolveObjectURL; - } - - // 1. Let blobURLEntry be request’s current URL’s blob URL entry. - const blobURLEntry = requestCurrentURL(request); - - // https://github.com/web-platform-tests/wpt/blob/7b0ebaccc62b566a1965396e5be7bb2bc06f841f/FileAPI/url/resources/fetch-tests.js#L52-L56 - // Buffer.resolveObjectURL does not ignore URL queries. - if (blobURLEntry.search.length !== 0) { - return Promise.resolve(makeNetworkError('NetworkError when attempting to fetch resource.')) - } - - const blob = resolveObjectURL(blobURLEntry.toString()); - - // 2. If request’s method is not `GET`, blobURLEntry is null, or blobURLEntry’s - // object is not a Blob object, then return a network error. - if (request.method !== 'GET' || !isBlobLike(blob)) { - return Promise.resolve(makeNetworkError('invalid method')) - } - - // 3. Let blob be blobURLEntry’s object. - // Note: done above - - // 4. Let response be a new response. - const response = makeResponse(); - - // 5. Let fullLength be blob’s size. - const fullLength = blob.size; - - // 6. Let serializedFullLength be fullLength, serialized and isomorphic encoded. - const serializedFullLength = isomorphicEncode(`${fullLength}`); - - // 7. Let type be blob’s type. - const type = blob.type; - - // 8. If request’s header list does not contain `Range`: - // 9. Otherwise: - if (!request.headersList.contains('range', true)) { - // 1. Let bodyWithType be the result of safely extracting blob. - // Note: in the FileAPI a blob "object" is a Blob *or* a MediaSource. - // In node, this can only ever be a Blob. Therefore we can safely - // use extractBody directly. - const bodyWithType = extractBody(blob); - - // 2. Set response’s status message to `OK`. - response.statusText = 'OK'; - - // 3. Set response’s body to bodyWithType’s body. - response.body = bodyWithType[0]; - - // 4. Set response’s header list to « (`Content-Length`, serializedFullLength), (`Content-Type`, type) ». - response.headersList.set('content-length', serializedFullLength, true); - response.headersList.set('content-type', type, true); - } else { - // 1. Set response’s range-requested flag. - response.rangeRequested = true; - - // 2. Let rangeHeader be the result of getting `Range` from request’s header list. - const rangeHeader = request.headersList.get('range', true); - - // 3. Let rangeValue be the result of parsing a single range header value given rangeHeader and true. - const rangeValue = simpleRangeHeaderValue(rangeHeader, true); - - // 4. If rangeValue is failure, then return a network error. - if (rangeValue === 'failure') { - return Promise.resolve(makeNetworkError('failed to fetch the data URL')) - } - - // 5. Let (rangeStart, rangeEnd) be rangeValue. - let { rangeStartValue: rangeStart, rangeEndValue: rangeEnd } = rangeValue; - - // 6. If rangeStart is null: - // 7. Otherwise: - if (rangeStart === null) { - // 1. Set rangeStart to fullLength − rangeEnd. - rangeStart = fullLength - rangeEnd; - - // 2. Set rangeEnd to rangeStart + rangeEnd − 1. - rangeEnd = rangeStart + rangeEnd - 1; - } else { - // 1. If rangeStart is greater than or equal to fullLength, then return a network error. - if (rangeStart >= fullLength) { - return Promise.resolve(makeNetworkError('Range start is greater than the blob\'s size.')) - } - - // 2. If rangeEnd is null or rangeEnd is greater than or equal to fullLength, then set - // rangeEnd to fullLength − 1. - if (rangeEnd === null || rangeEnd >= fullLength) { - rangeEnd = fullLength - 1; - } - } - - // 8. Let slicedBlob be the result of invoking slice blob given blob, rangeStart, - // rangeEnd + 1, and type. - const slicedBlob = blob.slice(rangeStart, rangeEnd, type); - - // 9. Let slicedBodyWithType be the result of safely extracting slicedBlob. - // Note: same reason as mentioned above as to why we use extractBody - const slicedBodyWithType = extractBody(slicedBlob); - - // 10. Set response’s body to slicedBodyWithType’s body. - response.body = slicedBodyWithType[0]; - - // 11. Let serializedSlicedLength be slicedBlob’s size, serialized and isomorphic encoded. - const serializedSlicedLength = isomorphicEncode(`${slicedBlob.size}`); - - // 12. Let contentRange be the result of invoking build a content range given rangeStart, - // rangeEnd, and fullLength. - const contentRange = buildContentRange(rangeStart, rangeEnd, fullLength); - - // 13. Set response’s status to 206. - response.status = 206; - - // 14. Set response’s status message to `Partial Content`. - response.statusText = 'Partial Content'; - - // 15. Set response’s header list to « (`Content-Length`, serializedSlicedLength), - // (`Content-Type`, type), (`Content-Range`, contentRange) ». - response.headersList.set('content-length', serializedSlicedLength, true); - response.headersList.set('content-type', type, true); - response.headersList.set('content-range', contentRange, true); - } - - // 10. Return response. - return Promise.resolve(response) - } - case 'data:': { - // 1. Let dataURLStruct be the result of running the - // data: URL processor on request’s current URL. - const currentURL = requestCurrentURL(request); - const dataURLStruct = dataURLProcessor(currentURL); - - // 2. If dataURLStruct is failure, then return a - // network error. - if (dataURLStruct === 'failure') { - return Promise.resolve(makeNetworkError('failed to fetch the data URL')) - } - - // 3. Let mimeType be dataURLStruct’s MIME type, serialized. - const mimeType = serializeAMimeType(dataURLStruct.mimeType); - - // 4. Return a response whose status message is `OK`, - // header list is « (`Content-Type`, mimeType) », - // and body is dataURLStruct’s body as a body. - return Promise.resolve(makeResponse({ - statusText: 'OK', - headersList: [ - ['content-type', { name: 'Content-Type', value: mimeType }] - ], - body: safelyExtractBody(dataURLStruct.body)[0] - })) - } - case 'file:': { - // For now, unfortunate as it is, file URLs are left as an exercise for the reader. - // When in doubt, return a network error. - return Promise.resolve(makeNetworkError('not implemented... yet...')) - } - case 'http:': - case 'https:': { - // Return the result of running HTTP fetch given fetchParams. - - return httpFetch(fetchParams) - .catch((err) => makeNetworkError(err)) - } - default: { - return Promise.resolve(makeNetworkError('unknown scheme')) - } - } - } - - // https://fetch.spec.whatwg.org/#finalize-response - function finalizeResponse (fetchParams, response) { - // 1. Set fetchParams’s request’s done flag. - fetchParams.request.done = true; - - // 2, If fetchParams’s process response done is not null, then queue a fetch - // task to run fetchParams’s process response done given response, with - // fetchParams’s task destination. - if (fetchParams.processResponseDone != null) { - queueMicrotask(() => fetchParams.processResponseDone(response)); - } - } - - // https://fetch.spec.whatwg.org/#fetch-finale - function fetchFinale (fetchParams, response) { - // 1. Let timingInfo be fetchParams’s timing info. - let timingInfo = fetchParams.timingInfo; - - // 2. If response is not a network error and fetchParams’s request’s client is a secure context, - // then set timingInfo’s server-timing headers to the result of getting, decoding, and splitting - // `Server-Timing` from response’s internal response’s header list. - // TODO - - // 3. Let processResponseEndOfBody be the following steps: - const processResponseEndOfBody = () => { - // 1. Let unsafeEndTime be the unsafe shared current time. - const unsafeEndTime = Date.now(); // ? - - // 2. If fetchParams’s request’s destination is "document", then set fetchParams’s controller’s - // full timing info to fetchParams’s timing info. - if (fetchParams.request.destination === 'document') { - fetchParams.controller.fullTimingInfo = timingInfo; - } - - // 3. Set fetchParams’s controller’s report timing steps to the following steps given a global object global: - fetchParams.controller.reportTimingSteps = () => { - // 1. If fetchParams’s request’s URL’s scheme is not an HTTP(S) scheme, then return. - if (fetchParams.request.url.protocol !== 'https:') { - return - } - - // 2. Set timingInfo’s end time to the relative high resolution time given unsafeEndTime and global. - timingInfo.endTime = unsafeEndTime; - - // 3. Let cacheState be response’s cache state. - let cacheState = response.cacheState; - - // 4. Let bodyInfo be response’s body info. - const bodyInfo = response.bodyInfo; - - // 5. If response’s timing allow passed flag is not set, then set timingInfo to the result of creating an - // opaque timing info for timingInfo and set cacheState to the empty string. - if (!response.timingAllowPassed) { - timingInfo = createOpaqueTimingInfo(timingInfo); - - cacheState = ''; - } - - // 6. Let responseStatus be 0. - let responseStatus = 0; - - // 7. If fetchParams’s request’s mode is not "navigate" or response’s has-cross-origin-redirects is false: - if (fetchParams.request.mode !== 'navigator' || !response.hasCrossOriginRedirects) { - // 1. Set responseStatus to response’s status. - responseStatus = response.status; - - // 2. Let mimeType be the result of extracting a MIME type from response’s header list. - const mimeType = extractMimeType(response.headersList); - - // 3. If mimeType is not failure, then set bodyInfo’s content type to the result of minimizing a supported MIME type given mimeType. - if (mimeType !== 'failure') { - bodyInfo.contentType = minimizeSupportedMimeType(mimeType); - } - } - - // 8. If fetchParams’s request’s initiator type is non-null, then mark resource timing given timingInfo, - // fetchParams’s request’s URL, fetchParams’s request’s initiator type, global, cacheState, bodyInfo, - // and responseStatus. - if (fetchParams.request.initiatorType != null) { - // TODO: update markresourcetiming - markResourceTiming(timingInfo, fetchParams.request.url.href, fetchParams.request.initiatorType, globalThis, cacheState, bodyInfo, responseStatus); - } - }; - - // 4. Let processResponseEndOfBodyTask be the following steps: - const processResponseEndOfBodyTask = () => { - // 1. Set fetchParams’s request’s done flag. - fetchParams.request.done = true; - - // 2. If fetchParams’s process response end-of-body is non-null, then run fetchParams’s process - // response end-of-body given response. - if (fetchParams.processResponseEndOfBody != null) { - queueMicrotask(() => fetchParams.processResponseEndOfBody(response)); - } - - // 3. If fetchParams’s request’s initiator type is non-null and fetchParams’s request’s client’s - // global object is fetchParams’s task destination, then run fetchParams’s controller’s report - // timing steps given fetchParams’s request’s client’s global object. - if (fetchParams.request.initiatorType != null) { - fetchParams.controller.reportTimingSteps(); - } - }; - - // 5. Queue a fetch task to run processResponseEndOfBodyTask with fetchParams’s task destination - queueMicrotask(() => processResponseEndOfBodyTask()); - }; - - // 4. If fetchParams’s process response is non-null, then queue a fetch task to run fetchParams’s - // process response given response, with fetchParams’s task destination. - if (fetchParams.processResponse != null) { - queueMicrotask(() => { - fetchParams.processResponse(response); - fetchParams.processResponse = null; - }); - } - - // 5. Let internalResponse be response, if response is a network error; otherwise response’s internal response. - const internalResponse = response.type === 'error' ? response : (response.internalResponse ?? response); - - // 6. If internalResponse’s body is null, then run processResponseEndOfBody. - // 7. Otherwise: - if (internalResponse.body == null) { - processResponseEndOfBody(); - } else { - // mcollina: all the following steps of the specs are skipped. - // The internal transform stream is not needed. - // See https://github.com/nodejs/undici/pull/3093#issuecomment-2050198541 - - // 1. Let transformStream be a new TransformStream. - // 2. Let identityTransformAlgorithm be an algorithm which, given chunk, enqueues chunk in transformStream. - // 3. Set up transformStream with transformAlgorithm set to identityTransformAlgorithm and flushAlgorithm - // set to processResponseEndOfBody. - // 4. Set internalResponse’s body’s stream to the result of internalResponse’s body’s stream piped through transformStream. - - finished(internalResponse.body.stream, () => { - processResponseEndOfBody(); - }); - } - } - - // https://fetch.spec.whatwg.org/#http-fetch - async function httpFetch (fetchParams) { - // 1. Let request be fetchParams’s request. - const request = fetchParams.request; - - // 2. Let response be null. - let response = null; - - // 3. Let actualResponse be null. - let actualResponse = null; - - // 4. Let timingInfo be fetchParams’s timing info. - const timingInfo = fetchParams.timingInfo; - - // 5. If request’s service-workers mode is "all", then: - if (request.serviceWorkers === 'all') ; - - // 6. If response is null, then: - if (response === null) { - // 1. If makeCORSPreflight is true and one of these conditions is true: - // TODO - - // 2. If request’s redirect mode is "follow", then set request’s - // service-workers mode to "none". - if (request.redirect === 'follow') { - request.serviceWorkers = 'none'; - } - - // 3. Set response and actualResponse to the result of running - // HTTP-network-or-cache fetch given fetchParams. - actualResponse = response = await httpNetworkOrCacheFetch(fetchParams); - - // 4. If request’s response tainting is "cors" and a CORS check - // for request and response returns failure, then return a network error. - if ( - request.responseTainting === 'cors' && - corsCheck(request, response) === 'failure' - ) { - return makeNetworkError('cors failure') - } - - // 5. If the TAO check for request and response returns failure, then set - // request’s timing allow failed flag. - if (TAOCheck(request, response) === 'failure') { - request.timingAllowFailed = true; - } - } - - // 7. If either request’s response tainting or response’s type - // is "opaque", and the cross-origin resource policy check with - // request’s origin, request’s client, request’s destination, - // and actualResponse returns blocked, then return a network error. - if ( - (request.responseTainting === 'opaque' || response.type === 'opaque') && - crossOriginResourcePolicyCheck( - request.origin, - request.client, - request.destination, - actualResponse - ) === 'blocked' - ) { - return makeNetworkError('blocked') - } - - // 8. If actualResponse’s status is a redirect status, then: - if (redirectStatusSet.has(actualResponse.status)) { - // 1. If actualResponse’s status is not 303, request’s body is not null, - // and the connection uses HTTP/2, then user agents may, and are even - // encouraged to, transmit an RST_STREAM frame. - // See, https://github.com/whatwg/fetch/issues/1288 - if (request.redirect !== 'manual') { - fetchParams.controller.connection.destroy(undefined, false); - } - - // 2. Switch on request’s redirect mode: - if (request.redirect === 'error') { - // Set response to a network error. - response = makeNetworkError('unexpected redirect'); - } else if (request.redirect === 'manual') { - // Set response to an opaque-redirect filtered response whose internal - // response is actualResponse. - // NOTE(spec): On the web this would return an `opaqueredirect` response, - // but that doesn't make sense server side. - // See https://github.com/nodejs/undici/issues/1193. - response = actualResponse; - } else if (request.redirect === 'follow') { - // Set response to the result of running HTTP-redirect fetch given - // fetchParams and response. - response = await httpRedirectFetch(fetchParams, response); - } else { - assert(false); - } - } - - // 9. Set response’s timing info to timingInfo. - response.timingInfo = timingInfo; - - // 10. Return response. - return response - } - - // https://fetch.spec.whatwg.org/#http-redirect-fetch - function httpRedirectFetch (fetchParams, response) { - // 1. Let request be fetchParams’s request. - const request = fetchParams.request; - - // 2. Let actualResponse be response, if response is not a filtered response, - // and response’s internal response otherwise. - const actualResponse = response.internalResponse - ? response.internalResponse - : response; - - // 3. Let locationURL be actualResponse’s location URL given request’s current - // URL’s fragment. - let locationURL; - - try { - locationURL = responseLocationURL( - actualResponse, - requestCurrentURL(request).hash - ); - - // 4. If locationURL is null, then return response. - if (locationURL == null) { - return response - } - } catch (err) { - // 5. If locationURL is failure, then return a network error. - return Promise.resolve(makeNetworkError(err)) - } - - // 6. If locationURL’s scheme is not an HTTP(S) scheme, then return a network - // error. - if (!urlIsHttpHttpsScheme(locationURL)) { - return Promise.resolve(makeNetworkError('URL scheme must be a HTTP(S) scheme')) - } - - // 7. If request’s redirect count is 20, then return a network error. - if (request.redirectCount === 20) { - return Promise.resolve(makeNetworkError('redirect count exceeded')) - } - - // 8. Increase request’s redirect count by 1. - request.redirectCount += 1; - - // 9. If request’s mode is "cors", locationURL includes credentials, and - // request’s origin is not same origin with locationURL’s origin, then return - // a network error. - if ( - request.mode === 'cors' && - (locationURL.username || locationURL.password) && - !sameOrigin(request, locationURL) - ) { - return Promise.resolve(makeNetworkError('cross origin not allowed for request mode "cors"')) - } - - // 10. If request’s response tainting is "cors" and locationURL includes - // credentials, then return a network error. - if ( - request.responseTainting === 'cors' && - (locationURL.username || locationURL.password) - ) { - return Promise.resolve(makeNetworkError( - 'URL cannot contain credentials for request mode "cors"' - )) - } - - // 11. If actualResponse’s status is not 303, request’s body is non-null, - // and request’s body’s source is null, then return a network error. - if ( - actualResponse.status !== 303 && - request.body != null && - request.body.source == null - ) { - return Promise.resolve(makeNetworkError()) - } - - // 12. If one of the following is true - // - actualResponse’s status is 301 or 302 and request’s method is `POST` - // - actualResponse’s status is 303 and request’s method is not `GET` or `HEAD` - if ( - ([301, 302].includes(actualResponse.status) && request.method === 'POST') || - (actualResponse.status === 303 && - !GET_OR_HEAD.includes(request.method)) - ) { - // then: - // 1. Set request’s method to `GET` and request’s body to null. - request.method = 'GET'; - request.body = null; - - // 2. For each headerName of request-body-header name, delete headerName from - // request’s header list. - for (const headerName of requestBodyHeader) { - request.headersList.delete(headerName); - } - } - - // 13. If request’s current URL’s origin is not same origin with locationURL’s - // origin, then for each headerName of CORS non-wildcard request-header name, - // delete headerName from request’s header list. - if (!sameOrigin(requestCurrentURL(request), locationURL)) { - // https://fetch.spec.whatwg.org/#cors-non-wildcard-request-header-name - request.headersList.delete('authorization', true); - - // https://fetch.spec.whatwg.org/#authentication-entries - request.headersList.delete('proxy-authorization', true); - - // "Cookie" and "Host" are forbidden request-headers, which undici doesn't implement. - request.headersList.delete('cookie', true); - request.headersList.delete('host', true); - } - - // 14. If request’s body is non-null, then set request’s body to the first return - // value of safely extracting request’s body’s source. - if (request.body != null) { - assert(request.body.source != null); - request.body = safelyExtractBody(request.body.source)[0]; - } - - // 15. Let timingInfo be fetchParams’s timing info. - const timingInfo = fetchParams.timingInfo; - - // 16. Set timingInfo’s redirect end time and post-redirect start time to the - // coarsened shared current time given fetchParams’s cross-origin isolated - // capability. - timingInfo.redirectEndTime = timingInfo.postRedirectStartTime = - coarsenedSharedCurrentTime(fetchParams.crossOriginIsolatedCapability); - - // 17. If timingInfo’s redirect start time is 0, then set timingInfo’s - // redirect start time to timingInfo’s start time. - if (timingInfo.redirectStartTime === 0) { - timingInfo.redirectStartTime = timingInfo.startTime; - } - - // 18. Append locationURL to request’s URL list. - request.urlList.push(locationURL); - - // 19. Invoke set request’s referrer policy on redirect on request and - // actualResponse. - setRequestReferrerPolicyOnRedirect(request, actualResponse); - - // 20. Return the result of running main fetch given fetchParams and true. - return mainFetch(fetchParams, true) - } - - // https://fetch.spec.whatwg.org/#http-network-or-cache-fetch - async function httpNetworkOrCacheFetch ( - fetchParams, - isAuthenticationFetch = false, - isNewConnectionFetch = false - ) { - // 1. Let request be fetchParams’s request. - const request = fetchParams.request; - - // 2. Let httpFetchParams be null. - let httpFetchParams = null; - - // 3. Let httpRequest be null. - let httpRequest = null; - - // 4. Let response be null. - let response = null; - - // 8. Run these steps, but abort when the ongoing fetch is terminated: - - // 1. If request’s window is "no-window" and request’s redirect mode is - // "error", then set httpFetchParams to fetchParams and httpRequest to - // request. - if (request.window === 'no-window' && request.redirect === 'error') { - httpFetchParams = fetchParams; - httpRequest = request; - } else { - // Otherwise: - - // 1. Set httpRequest to a clone of request. - httpRequest = cloneRequest(request); - - // 2. Set httpFetchParams to a copy of fetchParams. - httpFetchParams = { ...fetchParams }; - - // 3. Set httpFetchParams’s request to httpRequest. - httpFetchParams.request = httpRequest; - } - - // 3. Let includeCredentials be true if one of - const includeCredentials = - request.credentials === 'include' || - (request.credentials === 'same-origin' && - request.responseTainting === 'basic'); - - // 4. Let contentLength be httpRequest’s body’s length, if httpRequest’s - // body is non-null; otherwise null. - const contentLength = httpRequest.body ? httpRequest.body.length : null; - - // 5. Let contentLengthHeaderValue be null. - let contentLengthHeaderValue = null; - - // 6. If httpRequest’s body is null and httpRequest’s method is `POST` or - // `PUT`, then set contentLengthHeaderValue to `0`. - if ( - httpRequest.body == null && - ['POST', 'PUT'].includes(httpRequest.method) - ) { - contentLengthHeaderValue = '0'; - } - - // 7. If contentLength is non-null, then set contentLengthHeaderValue to - // contentLength, serialized and isomorphic encoded. - if (contentLength != null) { - contentLengthHeaderValue = isomorphicEncode(`${contentLength}`); - } - - // 8. If contentLengthHeaderValue is non-null, then append - // `Content-Length`/contentLengthHeaderValue to httpRequest’s header - // list. - if (contentLengthHeaderValue != null) { - httpRequest.headersList.append('content-length', contentLengthHeaderValue, true); - } - - // 9. If contentLengthHeaderValue is non-null, then append (`Content-Length`, - // contentLengthHeaderValue) to httpRequest’s header list. - - // 10. If contentLength is non-null and httpRequest’s keepalive is true, - // then: - if (contentLength != null && httpRequest.keepalive) ; - - // 11. If httpRequest’s referrer is a URL, then append - // `Referer`/httpRequest’s referrer, serialized and isomorphic encoded, - // to httpRequest’s header list. - if (httpRequest.referrer instanceof URL) { - httpRequest.headersList.append('referer', isomorphicEncode(httpRequest.referrer.href), true); - } - - // 12. Append a request `Origin` header for httpRequest. - appendRequestOriginHeader(httpRequest); - - // 13. Append the Fetch metadata headers for httpRequest. [FETCH-METADATA] - appendFetchMetadata(httpRequest); - - // 14. If httpRequest’s header list does not contain `User-Agent`, then - // user agents should append `User-Agent`/default `User-Agent` value to - // httpRequest’s header list. - if (!httpRequest.headersList.contains('user-agent', true)) { - httpRequest.headersList.append('user-agent', defaultUserAgent); - } - - // 15. If httpRequest’s cache mode is "default" and httpRequest’s header - // list contains `If-Modified-Since`, `If-None-Match`, - // `If-Unmodified-Since`, `If-Match`, or `If-Range`, then set - // httpRequest’s cache mode to "no-store". - if ( - httpRequest.cache === 'default' && - (httpRequest.headersList.contains('if-modified-since', true) || - httpRequest.headersList.contains('if-none-match', true) || - httpRequest.headersList.contains('if-unmodified-since', true) || - httpRequest.headersList.contains('if-match', true) || - httpRequest.headersList.contains('if-range', true)) - ) { - httpRequest.cache = 'no-store'; - } - - // 16. If httpRequest’s cache mode is "no-cache", httpRequest’s prevent - // no-cache cache-control header modification flag is unset, and - // httpRequest’s header list does not contain `Cache-Control`, then append - // `Cache-Control`/`max-age=0` to httpRequest’s header list. - if ( - httpRequest.cache === 'no-cache' && - !httpRequest.preventNoCacheCacheControlHeaderModification && - !httpRequest.headersList.contains('cache-control', true) - ) { - httpRequest.headersList.append('cache-control', 'max-age=0', true); - } - - // 17. If httpRequest’s cache mode is "no-store" or "reload", then: - if (httpRequest.cache === 'no-store' || httpRequest.cache === 'reload') { - // 1. If httpRequest’s header list does not contain `Pragma`, then append - // `Pragma`/`no-cache` to httpRequest’s header list. - if (!httpRequest.headersList.contains('pragma', true)) { - httpRequest.headersList.append('pragma', 'no-cache', true); - } - - // 2. If httpRequest’s header list does not contain `Cache-Control`, - // then append `Cache-Control`/`no-cache` to httpRequest’s header list. - if (!httpRequest.headersList.contains('cache-control', true)) { - httpRequest.headersList.append('cache-control', 'no-cache', true); - } - } - - // 18. If httpRequest’s header list contains `Range`, then append - // `Accept-Encoding`/`identity` to httpRequest’s header list. - if (httpRequest.headersList.contains('range', true)) { - httpRequest.headersList.append('accept-encoding', 'identity', true); - } - - // 19. Modify httpRequest’s header list per HTTP. Do not append a given - // header if httpRequest’s header list contains that header’s name. - // TODO: https://github.com/whatwg/fetch/issues/1285#issuecomment-896560129 - if (!httpRequest.headersList.contains('accept-encoding', true)) { - if (urlHasHttpsScheme(requestCurrentURL(httpRequest))) { - httpRequest.headersList.append('accept-encoding', 'br, gzip, deflate', true); - } else { - httpRequest.headersList.append('accept-encoding', 'gzip, deflate', true); - } - } - - httpRequest.headersList.delete('host', true); - - // 21. If there’s a proxy-authentication entry, use it as appropriate. - // TODO: proxy-authentication - - // 22. Set httpCache to the result of determining the HTTP cache - // partition, given httpRequest. - // TODO: cache - - // 23. If httpCache is null, then set httpRequest’s cache mode to - // "no-store". - { - httpRequest.cache = 'no-store'; - } - - // 24. If httpRequest’s cache mode is neither "no-store" nor "reload", - // then: - if (httpRequest.cache !== 'no-store' && httpRequest.cache !== 'reload') ; - - // 9. If aborted, then return the appropriate network error for fetchParams. - // TODO - - // 10. If response is null, then: - if (response == null) { - // 1. If httpRequest’s cache mode is "only-if-cached", then return a - // network error. - if (httpRequest.cache === 'only-if-cached') { - return makeNetworkError('only if cached') - } - - // 2. Let forwardResponse be the result of running HTTP-network fetch - // given httpFetchParams, includeCredentials, and isNewConnectionFetch. - const forwardResponse = await httpNetworkFetch( - httpFetchParams, - includeCredentials, - isNewConnectionFetch - ); - - // 3. If httpRequest’s method is unsafe and forwardResponse’s status is - // in the range 200 to 399, inclusive, invalidate appropriate stored - // responses in httpCache, as per the "Invalidation" chapter of HTTP - // Caching, and set storedResponse to null. [HTTP-CACHING] - if ( - !safeMethodsSet.has(httpRequest.method) && - forwardResponse.status >= 200 && - forwardResponse.status <= 399 - ) ; - - // 5. If response is null, then: - if (response == null) { - // 1. Set response to forwardResponse. - response = forwardResponse; - - // 2. Store httpRequest and forwardResponse in httpCache, as per the - // "Storing Responses in Caches" chapter of HTTP Caching. [HTTP-CACHING] - // TODO: cache - } - } - - // 11. Set response’s URL list to a clone of httpRequest’s URL list. - response.urlList = [...httpRequest.urlList]; - - // 12. If httpRequest’s header list contains `Range`, then set response’s - // range-requested flag. - if (httpRequest.headersList.contains('range', true)) { - response.rangeRequested = true; - } - - // 13. Set response’s request-includes-credentials to includeCredentials. - response.requestIncludesCredentials = includeCredentials; - - // 14. If response’s status is 401, httpRequest’s response tainting is not - // "cors", includeCredentials is true, and request’s window is an environment - // settings object, then: - // TODO - - // 15. If response’s status is 407, then: - if (response.status === 407) { - // 1. If request’s window is "no-window", then return a network error. - if (request.window === 'no-window') { - return makeNetworkError() - } - - // 2. ??? - - // 3. If fetchParams is canceled, then return the appropriate network error for fetchParams. - if (isCancelled(fetchParams)) { - return makeAppropriateNetworkError(fetchParams) - } - - // 4. Prompt the end user as appropriate in request’s window and store - // the result as a proxy-authentication entry. [HTTP-AUTH] - // TODO: Invoke some kind of callback? - - // 5. Set response to the result of running HTTP-network-or-cache fetch given - // fetchParams. - // TODO - return makeNetworkError('proxy authentication required') - } - - // 16. If all of the following are true - if ( - // response’s status is 421 - response.status === 421 && - // isNewConnectionFetch is false - !isNewConnectionFetch && - // request’s body is null, or request’s body is non-null and request’s body’s source is non-null - (request.body == null || request.body.source != null) - ) { - // then: - - // 1. If fetchParams is canceled, then return the appropriate network error for fetchParams. - if (isCancelled(fetchParams)) { - return makeAppropriateNetworkError(fetchParams) - } - - // 2. Set response to the result of running HTTP-network-or-cache - // fetch given fetchParams, isAuthenticationFetch, and true. - - // TODO (spec): The spec doesn't specify this but we need to cancel - // the active response before we can start a new one. - // https://github.com/whatwg/fetch/issues/1293 - fetchParams.controller.connection.destroy(); - - response = await httpNetworkOrCacheFetch( - fetchParams, - isAuthenticationFetch, - true - ); - } - - // 18. Return response. - return response - } - - // https://fetch.spec.whatwg.org/#http-network-fetch - async function httpNetworkFetch ( - fetchParams, - includeCredentials = false, - forceNewConnection = false - ) { - assert(!fetchParams.controller.connection || fetchParams.controller.connection.destroyed); - - fetchParams.controller.connection = { - abort: null, - destroyed: false, - destroy (err, abort = true) { - if (!this.destroyed) { - this.destroyed = true; - if (abort) { - this.abort?.(err ?? new DOMException('The operation was aborted.', 'AbortError')); - } - } - } - }; - - // 1. Let request be fetchParams’s request. - const request = fetchParams.request; - - // 2. Let response be null. - let response = null; - - // 3. Let timingInfo be fetchParams’s timing info. - const timingInfo = fetchParams.timingInfo; - - // 5. If httpCache is null, then set request’s cache mode to "no-store". - { - request.cache = 'no-store'; - } - - // 8. Switch on request’s mode: - if (request.mode === 'websocket') ; - - // 9. Run these steps, but abort when the ongoing fetch is terminated: - - // 1. If connection is failure, then return a network error. - - // 2. Set timingInfo’s final connection timing info to the result of - // calling clamp and coarsen connection timing info with connection’s - // timing info, timingInfo’s post-redirect start time, and fetchParams’s - // cross-origin isolated capability. - - // 3. If connection is not an HTTP/2 connection, request’s body is non-null, - // and request’s body’s source is null, then append (`Transfer-Encoding`, - // `chunked`) to request’s header list. - - // 4. Set timingInfo’s final network-request start time to the coarsened - // shared current time given fetchParams’s cross-origin isolated - // capability. - - // 5. Set response to the result of making an HTTP request over connection - // using request with the following caveats: - - // - Follow the relevant requirements from HTTP. [HTTP] [HTTP-SEMANTICS] - // [HTTP-COND] [HTTP-CACHING] [HTTP-AUTH] - - // - If request’s body is non-null, and request’s body’s source is null, - // then the user agent may have a buffer of up to 64 kibibytes and store - // a part of request’s body in that buffer. If the user agent reads from - // request’s body beyond that buffer’s size and the user agent needs to - // resend request, then instead return a network error. - - // - Set timingInfo’s final network-response start time to the coarsened - // shared current time given fetchParams’s cross-origin isolated capability, - // immediately after the user agent’s HTTP parser receives the first byte - // of the response (e.g., frame header bytes for HTTP/2 or response status - // line for HTTP/1.x). - - // - Wait until all the headers are transmitted. - - // - Any responses whose status is in the range 100 to 199, inclusive, - // and is not 101, are to be ignored, except for the purposes of setting - // timingInfo’s final network-response start time above. - - // - If request’s header list contains `Transfer-Encoding`/`chunked` and - // response is transferred via HTTP/1.0 or older, then return a network - // error. - - // - If the HTTP request results in a TLS client certificate dialog, then: - - // 1. If request’s window is an environment settings object, make the - // dialog available in request’s window. - - // 2. Otherwise, return a network error. - - // To transmit request’s body body, run these steps: - let requestBody = null; - // 1. If body is null and fetchParams’s process request end-of-body is - // non-null, then queue a fetch task given fetchParams’s process request - // end-of-body and fetchParams’s task destination. - if (request.body == null && fetchParams.processRequestEndOfBody) { - queueMicrotask(() => fetchParams.processRequestEndOfBody()); - } else if (request.body != null) { - // 2. Otherwise, if body is non-null: - - // 1. Let processBodyChunk given bytes be these steps: - const processBodyChunk = async function * (bytes) { - // 1. If the ongoing fetch is terminated, then abort these steps. - if (isCancelled(fetchParams)) { - return - } - - // 2. Run this step in parallel: transmit bytes. - yield bytes; - - // 3. If fetchParams’s process request body is non-null, then run - // fetchParams’s process request body given bytes’s length. - fetchParams.processRequestBodyChunkLength?.(bytes.byteLength); - }; - - // 2. Let processEndOfBody be these steps: - const processEndOfBody = () => { - // 1. If fetchParams is canceled, then abort these steps. - if (isCancelled(fetchParams)) { - return - } - - // 2. If fetchParams’s process request end-of-body is non-null, - // then run fetchParams’s process request end-of-body. - if (fetchParams.processRequestEndOfBody) { - fetchParams.processRequestEndOfBody(); - } - }; - - // 3. Let processBodyError given e be these steps: - const processBodyError = (e) => { - // 1. If fetchParams is canceled, then abort these steps. - if (isCancelled(fetchParams)) { - return - } - - // 2. If e is an "AbortError" DOMException, then abort fetchParams’s controller. - if (e.name === 'AbortError') { - fetchParams.controller.abort(); - } else { - fetchParams.controller.terminate(e); - } - }; - - // 4. Incrementally read request’s body given processBodyChunk, processEndOfBody, - // processBodyError, and fetchParams’s task destination. - requestBody = (async function * () { - try { - for await (const bytes of request.body.stream) { - yield * processBodyChunk(bytes); - } - processEndOfBody(); - } catch (err) { - processBodyError(err); - } - })(); - } - - try { - // socket is only provided for websockets - const { body, status, statusText, headersList, socket } = await dispatch({ body: requestBody }); - - if (socket) { - response = makeResponse({ status, statusText, headersList, socket }); - } else { - const iterator = body[Symbol.asyncIterator](); - fetchParams.controller.next = () => iterator.next(); - - response = makeResponse({ status, statusText, headersList }); - } - } catch (err) { - // 10. If aborted, then: - if (err.name === 'AbortError') { - // 1. If connection uses HTTP/2, then transmit an RST_STREAM frame. - fetchParams.controller.connection.destroy(); - - // 2. Return the appropriate network error for fetchParams. - return makeAppropriateNetworkError(fetchParams, err) - } - - return makeNetworkError(err) - } - - // 11. Let pullAlgorithm be an action that resumes the ongoing fetch - // if it is suspended. - const pullAlgorithm = async () => { - await fetchParams.controller.resume(); - }; - - // 12. Let cancelAlgorithm be an algorithm that aborts fetchParams’s - // controller with reason, given reason. - const cancelAlgorithm = (reason) => { - // If the aborted fetch was already terminated, then we do not - // need to do anything. - if (!isCancelled(fetchParams)) { - fetchParams.controller.abort(reason); - } - }; - - // 13. Let highWaterMark be a non-negative, non-NaN number, chosen by - // the user agent. - // TODO - - // 14. Let sizeAlgorithm be an algorithm that accepts a chunk object - // and returns a non-negative, non-NaN, non-infinite number, chosen by the user agent. - // TODO - - // 15. Let stream be a new ReadableStream. - // 16. Set up stream with byte reading support with pullAlgorithm set to pullAlgorithm, - // cancelAlgorithm set to cancelAlgorithm. - const stream = new ReadableStream( - { - async start (controller) { - fetchParams.controller.controller = controller; - }, - async pull (controller) { - await pullAlgorithm(); - }, - async cancel (reason) { - await cancelAlgorithm(reason); - }, - type: 'bytes' - } - ); - - // 17. Run these steps, but abort when the ongoing fetch is terminated: - - // 1. Set response’s body to a new body whose stream is stream. - response.body = { stream, source: null, length: null }; - - // 2. If response is not a network error and request’s cache mode is - // not "no-store", then update response in httpCache for request. - // TODO - - // 3. If includeCredentials is true and the user agent is not configured - // to block cookies for request (see section 7 of [COOKIES]), then run the - // "set-cookie-string" parsing algorithm (see section 5.2 of [COOKIES]) on - // the value of each header whose name is a byte-case-insensitive match for - // `Set-Cookie` in response’s header list, if any, and request’s current URL. - // TODO - - // 18. If aborted, then: - // TODO - - // 19. Run these steps in parallel: - - // 1. Run these steps, but abort when fetchParams is canceled: - fetchParams.controller.onAborted = onAborted; - fetchParams.controller.on('terminated', onAborted); - fetchParams.controller.resume = async () => { - // 1. While true - while (true) { - // 1-3. See onData... - - // 4. Set bytes to the result of handling content codings given - // codings and bytes. - let bytes; - let isFailure; - try { - const { done, value } = await fetchParams.controller.next(); - - if (isAborted(fetchParams)) { - break - } - - bytes = done ? undefined : value; - } catch (err) { - if (fetchParams.controller.ended && !timingInfo.encodedBodySize) { - // zlib doesn't like empty streams. - bytes = undefined; - } else { - bytes = err; - - // err may be propagated from the result of calling readablestream.cancel, - // which might not be an error. https://github.com/nodejs/undici/issues/2009 - isFailure = true; - } - } - - if (bytes === undefined) { - // 2. Otherwise, if the bytes transmission for response’s message - // body is done normally and stream is readable, then close - // stream, finalize response for fetchParams and response, and - // abort these in-parallel steps. - readableStreamClose(fetchParams.controller.controller); - - finalizeResponse(fetchParams, response); - - return - } - - // 5. Increase timingInfo’s decoded body size by bytes’s length. - timingInfo.decodedBodySize += bytes?.byteLength ?? 0; - - // 6. If bytes is failure, then terminate fetchParams’s controller. - if (isFailure) { - fetchParams.controller.terminate(bytes); - return - } - - // 7. Enqueue a Uint8Array wrapping an ArrayBuffer containing bytes - // into stream. - const buffer = new Uint8Array(bytes); - if (buffer.byteLength) { - fetchParams.controller.controller.enqueue(buffer); - } - - // 8. If stream is errored, then terminate the ongoing fetch. - if (isErrored(stream)) { - fetchParams.controller.terminate(); - return - } - - // 9. If stream doesn’t need more data ask the user agent to suspend - // the ongoing fetch. - if (fetchParams.controller.controller.desiredSize <= 0) { - return - } - } - }; - - // 2. If aborted, then: - function onAborted (reason) { - // 2. If fetchParams is aborted, then: - if (isAborted(fetchParams)) { - // 1. Set response’s aborted flag. - response.aborted = true; - - // 2. If stream is readable, then error stream with the result of - // deserialize a serialized abort reason given fetchParams’s - // controller’s serialized abort reason and an - // implementation-defined realm. - if (isReadable(stream)) { - fetchParams.controller.controller.error( - fetchParams.controller.serializedAbortReason - ); - } - } else { - // 3. Otherwise, if stream is readable, error stream with a TypeError. - if (isReadable(stream)) { - fetchParams.controller.controller.error(new TypeError('terminated', { - cause: isErrorLike(reason) ? reason : undefined - })); - } - } - - // 4. If connection uses HTTP/2, then transmit an RST_STREAM frame. - // 5. Otherwise, the user agent should close connection unless it would be bad for performance to do so. - fetchParams.controller.connection.destroy(); - } - - // 20. Return response. - return response - - function dispatch ({ body }) { - const url = requestCurrentURL(request); - /** @type {import('../..').Agent} */ - const agent = fetchParams.controller.dispatcher; - - return new Promise((resolve, reject) => agent.dispatch( - { - path: url.pathname + url.search, - origin: url.origin, - method: request.method, - body: agent.isMockActive ? request.body && (request.body.source || request.body.stream) : body, - headers: request.headersList.entries, - maxRedirections: 0, - upgrade: request.mode === 'websocket' ? 'websocket' : undefined - }, - { - body: null, - abort: null, - - onConnect (abort) { - // TODO (fix): Do we need connection here? - const { connection } = fetchParams.controller; - - // Set timingInfo’s final connection timing info to the result of calling clamp and coarsen - // connection timing info with connection’s timing info, timingInfo’s post-redirect start - // time, and fetchParams’s cross-origin isolated capability. - // TODO: implement connection timing - timingInfo.finalConnectionTimingInfo = clampAndCoarsenConnectionTimingInfo(undefined, timingInfo.postRedirectStartTime, fetchParams.crossOriginIsolatedCapability); - - if (connection.destroyed) { - abort(new DOMException('The operation was aborted.', 'AbortError')); - } else { - fetchParams.controller.on('terminated', abort); - this.abort = connection.abort = abort; - } - - // Set timingInfo’s final network-request start time to the coarsened shared current time given - // fetchParams’s cross-origin isolated capability. - timingInfo.finalNetworkRequestStartTime = coarsenedSharedCurrentTime(fetchParams.crossOriginIsolatedCapability); - }, - - onResponseStarted () { - // Set timingInfo’s final network-response start time to the coarsened shared current - // time given fetchParams’s cross-origin isolated capability, immediately after the - // user agent’s HTTP parser receives the first byte of the response (e.g., frame header - // bytes for HTTP/2 or response status line for HTTP/1.x). - timingInfo.finalNetworkResponseStartTime = coarsenedSharedCurrentTime(fetchParams.crossOriginIsolatedCapability); - }, - - onHeaders (status, rawHeaders, resume, statusText) { - if (status < 200) { - return - } - - /** @type {string[]} */ - let codings = []; - let location = ''; - - const headersList = new HeadersList(); - - for (let i = 0; i < rawHeaders.length; i += 2) { - headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString('latin1'), true); - } - const contentEncoding = headersList.get('content-encoding', true); - if (contentEncoding) { - // https://www.rfc-editor.org/rfc/rfc7231#section-3.1.2.1 - // "All content-coding values are case-insensitive..." - codings = contentEncoding.toLowerCase().split(',').map((x) => x.trim()); - } - location = headersList.get('location', true); - - this.body = new Readable({ read: resume }); - - const decoders = []; - - const willFollow = location && request.redirect === 'follow' && - redirectStatusSet.has(status); - - // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding - if (codings.length !== 0 && request.method !== 'HEAD' && request.method !== 'CONNECT' && !nullBodyStatus.includes(status) && !willFollow) { - for (let i = 0; i < codings.length; ++i) { - const coding = codings[i]; - // https://www.rfc-editor.org/rfc/rfc9112.html#section-7.2 - if (coding === 'x-gzip' || coding === 'gzip') { - decoders.push(zlib.createGunzip({ - // Be less strict when decoding compressed responses, since sometimes - // servers send slightly invalid responses that are still accepted - // by common browsers. - // Always using Z_SYNC_FLUSH is what cURL does. - flush: zlib.constants.Z_SYNC_FLUSH, - finishFlush: zlib.constants.Z_SYNC_FLUSH - })); - } else if (coding === 'deflate') { - decoders.push(createInflate()); - } else if (coding === 'br') { - decoders.push(zlib.createBrotliDecompress()); - } else { - decoders.length = 0; - break - } - } - } - - resolve({ - status, - statusText, - headersList, - body: decoders.length - ? pipeline(this.body, ...decoders, () => { }) - : this.body.on('error', () => { }) - }); - - return true - }, - - onData (chunk) { - if (fetchParams.controller.dump) { - return - } - - // 1. If one or more bytes have been transmitted from response’s - // message body, then: - - // 1. Let bytes be the transmitted bytes. - const bytes = chunk; - - // 2. Let codings be the result of extracting header list values - // given `Content-Encoding` and response’s header list. - // See pullAlgorithm. - - // 3. Increase timingInfo’s encoded body size by bytes’s length. - timingInfo.encodedBodySize += bytes.byteLength; - - // 4. See pullAlgorithm... - - return this.body.push(bytes) - }, - - onComplete () { - if (this.abort) { - fetchParams.controller.off('terminated', this.abort); - } - - if (fetchParams.controller.onAborted) { - fetchParams.controller.off('terminated', fetchParams.controller.onAborted); - } - - fetchParams.controller.ended = true; - - this.body.push(null); - }, - - onError (error) { - if (this.abort) { - fetchParams.controller.off('terminated', this.abort); - } - - this.body?.destroy(error); - - fetchParams.controller.terminate(error); - - reject(error); - }, - - onUpgrade (status, rawHeaders, socket) { - if (status !== 101) { - return - } - - const headersList = new HeadersList(); - - for (let i = 0; i < rawHeaders.length; i += 2) { - headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString('latin1'), true); - } - - resolve({ - status, - statusText: STATUS_CODES[status], - headersList, - socket - }); - - return true - } - } - )) - } - } - - fetch_1 = { - fetch, - Fetch, - fetching, - finalizeAndReportTiming - }; - return fetch_1; -} - -var symbols$2; -var hasRequiredSymbols$2; - -function requireSymbols$2 () { - if (hasRequiredSymbols$2) return symbols$2; - hasRequiredSymbols$2 = 1; - - symbols$2 = { - kState: Symbol('FileReader state'), - kResult: Symbol('FileReader result'), - kError: Symbol('FileReader error'), - kLastProgressEventFired: Symbol('FileReader last progress event fired timestamp'), - kEvents: Symbol('FileReader events'), - kAborted: Symbol('FileReader aborted') - }; - return symbols$2; -} - -var progressevent; -var hasRequiredProgressevent; - -function requireProgressevent () { - if (hasRequiredProgressevent) return progressevent; - hasRequiredProgressevent = 1; - - const { webidl } = requireWebidl(); - - const kState = Symbol('ProgressEvent state'); - - /** - * @see https://xhr.spec.whatwg.org/#progressevent - */ - class ProgressEvent extends Event { - constructor (type, eventInitDict = {}) { - type = webidl.converters.DOMString(type, 'ProgressEvent constructor', 'type'); - eventInitDict = webidl.converters.ProgressEventInit(eventInitDict ?? {}); - - super(type, eventInitDict); - - this[kState] = { - lengthComputable: eventInitDict.lengthComputable, - loaded: eventInitDict.loaded, - total: eventInitDict.total - }; - } - - get lengthComputable () { - webidl.brandCheck(this, ProgressEvent); - - return this[kState].lengthComputable - } - - get loaded () { - webidl.brandCheck(this, ProgressEvent); - - return this[kState].loaded - } - - get total () { - webidl.brandCheck(this, ProgressEvent); - - return this[kState].total - } - } - - webidl.converters.ProgressEventInit = webidl.dictionaryConverter([ - { - key: 'lengthComputable', - converter: webidl.converters.boolean, - defaultValue: () => false - }, - { - key: 'loaded', - converter: webidl.converters['unsigned long long'], - defaultValue: () => 0 - }, - { - key: 'total', - converter: webidl.converters['unsigned long long'], - defaultValue: () => 0 - }, - { - key: 'bubbles', - converter: webidl.converters.boolean, - defaultValue: () => false - }, - { - key: 'cancelable', - converter: webidl.converters.boolean, - defaultValue: () => false - }, - { - key: 'composed', - converter: webidl.converters.boolean, - defaultValue: () => false - } - ]); - - progressevent = { - ProgressEvent - }; - return progressevent; -} - -var encoding; -var hasRequiredEncoding; - -function requireEncoding () { - if (hasRequiredEncoding) return encoding; - hasRequiredEncoding = 1; - - /** - * @see https://encoding.spec.whatwg.org/#concept-encoding-get - * @param {string|undefined} label - */ - function getEncoding (label) { - if (!label) { - return 'failure' - } - - // 1. Remove any leading and trailing ASCII whitespace from label. - // 2. If label is an ASCII case-insensitive match for any of the - // labels listed in the table below, then return the - // corresponding encoding; otherwise return failure. - switch (label.trim().toLowerCase()) { - case 'unicode-1-1-utf-8': - case 'unicode11utf8': - case 'unicode20utf8': - case 'utf-8': - case 'utf8': - case 'x-unicode20utf8': - return 'UTF-8' - case '866': - case 'cp866': - case 'csibm866': - case 'ibm866': - return 'IBM866' - case 'csisolatin2': - case 'iso-8859-2': - case 'iso-ir-101': - case 'iso8859-2': - case 'iso88592': - case 'iso_8859-2': - case 'iso_8859-2:1987': - case 'l2': - case 'latin2': - return 'ISO-8859-2' - case 'csisolatin3': - case 'iso-8859-3': - case 'iso-ir-109': - case 'iso8859-3': - case 'iso88593': - case 'iso_8859-3': - case 'iso_8859-3:1988': - case 'l3': - case 'latin3': - return 'ISO-8859-3' - case 'csisolatin4': - case 'iso-8859-4': - case 'iso-ir-110': - case 'iso8859-4': - case 'iso88594': - case 'iso_8859-4': - case 'iso_8859-4:1988': - case 'l4': - case 'latin4': - return 'ISO-8859-4' - case 'csisolatincyrillic': - case 'cyrillic': - case 'iso-8859-5': - case 'iso-ir-144': - case 'iso8859-5': - case 'iso88595': - case 'iso_8859-5': - case 'iso_8859-5:1988': - return 'ISO-8859-5' - case 'arabic': - case 'asmo-708': - case 'csiso88596e': - case 'csiso88596i': - case 'csisolatinarabic': - case 'ecma-114': - case 'iso-8859-6': - case 'iso-8859-6-e': - case 'iso-8859-6-i': - case 'iso-ir-127': - case 'iso8859-6': - case 'iso88596': - case 'iso_8859-6': - case 'iso_8859-6:1987': - return 'ISO-8859-6' - case 'csisolatingreek': - case 'ecma-118': - case 'elot_928': - case 'greek': - case 'greek8': - case 'iso-8859-7': - case 'iso-ir-126': - case 'iso8859-7': - case 'iso88597': - case 'iso_8859-7': - case 'iso_8859-7:1987': - case 'sun_eu_greek': - return 'ISO-8859-7' - case 'csiso88598e': - case 'csisolatinhebrew': - case 'hebrew': - case 'iso-8859-8': - case 'iso-8859-8-e': - case 'iso-ir-138': - case 'iso8859-8': - case 'iso88598': - case 'iso_8859-8': - case 'iso_8859-8:1988': - case 'visual': - return 'ISO-8859-8' - case 'csiso88598i': - case 'iso-8859-8-i': - case 'logical': - return 'ISO-8859-8-I' - case 'csisolatin6': - case 'iso-8859-10': - case 'iso-ir-157': - case 'iso8859-10': - case 'iso885910': - case 'l6': - case 'latin6': - return 'ISO-8859-10' - case 'iso-8859-13': - case 'iso8859-13': - case 'iso885913': - return 'ISO-8859-13' - case 'iso-8859-14': - case 'iso8859-14': - case 'iso885914': - return 'ISO-8859-14' - case 'csisolatin9': - case 'iso-8859-15': - case 'iso8859-15': - case 'iso885915': - case 'iso_8859-15': - case 'l9': - return 'ISO-8859-15' - case 'iso-8859-16': - return 'ISO-8859-16' - case 'cskoi8r': - case 'koi': - case 'koi8': - case 'koi8-r': - case 'koi8_r': - return 'KOI8-R' - case 'koi8-ru': - case 'koi8-u': - return 'KOI8-U' - case 'csmacintosh': - case 'mac': - case 'macintosh': - case 'x-mac-roman': - return 'macintosh' - case 'iso-8859-11': - case 'iso8859-11': - case 'iso885911': - case 'tis-620': - case 'windows-874': - return 'windows-874' - case 'cp1250': - case 'windows-1250': - case 'x-cp1250': - return 'windows-1250' - case 'cp1251': - case 'windows-1251': - case 'x-cp1251': - return 'windows-1251' - case 'ansi_x3.4-1968': - case 'ascii': - case 'cp1252': - case 'cp819': - case 'csisolatin1': - case 'ibm819': - case 'iso-8859-1': - case 'iso-ir-100': - case 'iso8859-1': - case 'iso88591': - case 'iso_8859-1': - case 'iso_8859-1:1987': - case 'l1': - case 'latin1': - case 'us-ascii': - case 'windows-1252': - case 'x-cp1252': - return 'windows-1252' - case 'cp1253': - case 'windows-1253': - case 'x-cp1253': - return 'windows-1253' - case 'cp1254': - case 'csisolatin5': - case 'iso-8859-9': - case 'iso-ir-148': - case 'iso8859-9': - case 'iso88599': - case 'iso_8859-9': - case 'iso_8859-9:1989': - case 'l5': - case 'latin5': - case 'windows-1254': - case 'x-cp1254': - return 'windows-1254' - case 'cp1255': - case 'windows-1255': - case 'x-cp1255': - return 'windows-1255' - case 'cp1256': - case 'windows-1256': - case 'x-cp1256': - return 'windows-1256' - case 'cp1257': - case 'windows-1257': - case 'x-cp1257': - return 'windows-1257' - case 'cp1258': - case 'windows-1258': - case 'x-cp1258': - return 'windows-1258' - case 'x-mac-cyrillic': - case 'x-mac-ukrainian': - return 'x-mac-cyrillic' - case 'chinese': - case 'csgb2312': - case 'csiso58gb231280': - case 'gb2312': - case 'gb_2312': - case 'gb_2312-80': - case 'gbk': - case 'iso-ir-58': - case 'x-gbk': - return 'GBK' - case 'gb18030': - return 'gb18030' - case 'big5': - case 'big5-hkscs': - case 'cn-big5': - case 'csbig5': - case 'x-x-big5': - return 'Big5' - case 'cseucpkdfmtjapanese': - case 'euc-jp': - case 'x-euc-jp': - return 'EUC-JP' - case 'csiso2022jp': - case 'iso-2022-jp': - return 'ISO-2022-JP' - case 'csshiftjis': - case 'ms932': - case 'ms_kanji': - case 'shift-jis': - case 'shift_jis': - case 'sjis': - case 'windows-31j': - case 'x-sjis': - return 'Shift_JIS' - case 'cseuckr': - case 'csksc56011987': - case 'euc-kr': - case 'iso-ir-149': - case 'korean': - case 'ks_c_5601-1987': - case 'ks_c_5601-1989': - case 'ksc5601': - case 'ksc_5601': - case 'windows-949': - return 'EUC-KR' - case 'csiso2022kr': - case 'hz-gb-2312': - case 'iso-2022-cn': - case 'iso-2022-cn-ext': - case 'iso-2022-kr': - case 'replacement': - return 'replacement' - case 'unicodefffe': - case 'utf-16be': - return 'UTF-16BE' - case 'csunicode': - case 'iso-10646-ucs-2': - case 'ucs-2': - case 'unicode': - case 'unicodefeff': - case 'utf-16': - case 'utf-16le': - return 'UTF-16LE' - case 'x-user-defined': - return 'x-user-defined' - default: return 'failure' - } - } - - encoding = { - getEncoding - }; - return encoding; -} - -var util$4; -var hasRequiredUtil$4; - -function requireUtil$4 () { - if (hasRequiredUtil$4) return util$4; - hasRequiredUtil$4 = 1; - - const { - kState, - kError, - kResult, - kAborted, - kLastProgressEventFired - } = requireSymbols$2(); - const { ProgressEvent } = requireProgressevent(); - const { getEncoding } = requireEncoding(); - const { serializeAMimeType, parseMIMEType } = requireDataUrl(); - const { types } = require$$0$6; - const { StringDecoder } = require$$5$2; - const { btoa } = require$$0$3; - - /** @type {PropertyDescriptor} */ - const staticPropertyDescriptors = { - enumerable: true, - writable: false, - configurable: false - }; - - /** - * @see https://w3c.github.io/FileAPI/#readOperation - * @param {import('./filereader').FileReader} fr - * @param {import('buffer').Blob} blob - * @param {string} type - * @param {string?} encodingName - */ - function readOperation (fr, blob, type, encodingName) { - // 1. If fr’s state is "loading", throw an InvalidStateError - // DOMException. - if (fr[kState] === 'loading') { - throw new DOMException('Invalid state', 'InvalidStateError') - } - - // 2. Set fr’s state to "loading". - fr[kState] = 'loading'; - - // 3. Set fr’s result to null. - fr[kResult] = null; - - // 4. Set fr’s error to null. - fr[kError] = null; - - // 5. Let stream be the result of calling get stream on blob. - /** @type {import('stream/web').ReadableStream} */ - const stream = blob.stream(); - - // 6. Let reader be the result of getting a reader from stream. - const reader = stream.getReader(); - - // 7. Let bytes be an empty byte sequence. - /** @type {Uint8Array[]} */ - const bytes = []; - - // 8. Let chunkPromise be the result of reading a chunk from - // stream with reader. - let chunkPromise = reader.read(); - - // 9. Let isFirstChunk be true. - let isFirstChunk = true - - // 10. In parallel, while true: - // Note: "In parallel" just means non-blocking - // Note 2: readOperation itself cannot be async as double - // reading the body would then reject the promise, instead - // of throwing an error. - ;(async () => { - while (!fr[kAborted]) { - // 1. Wait for chunkPromise to be fulfilled or rejected. - try { - const { done, value } = await chunkPromise; - - // 2. If chunkPromise is fulfilled, and isFirstChunk is - // true, queue a task to fire a progress event called - // loadstart at fr. - if (isFirstChunk && !fr[kAborted]) { - queueMicrotask(() => { - fireAProgressEvent('loadstart', fr); - }); - } - - // 3. Set isFirstChunk to false. - isFirstChunk = false; - - // 4. If chunkPromise is fulfilled with an object whose - // done property is false and whose value property is - // a Uint8Array object, run these steps: - if (!done && types.isUint8Array(value)) { - // 1. Let bs be the byte sequence represented by the - // Uint8Array object. - - // 2. Append bs to bytes. - bytes.push(value); - - // 3. If roughly 50ms have passed since these steps - // were last invoked, queue a task to fire a - // progress event called progress at fr. - if ( - ( - fr[kLastProgressEventFired] === undefined || - Date.now() - fr[kLastProgressEventFired] >= 50 - ) && - !fr[kAborted] - ) { - fr[kLastProgressEventFired] = Date.now(); - queueMicrotask(() => { - fireAProgressEvent('progress', fr); - }); - } - - // 4. Set chunkPromise to the result of reading a - // chunk from stream with reader. - chunkPromise = reader.read(); - } else if (done) { - // 5. Otherwise, if chunkPromise is fulfilled with an - // object whose done property is true, queue a task - // to run the following steps and abort this algorithm: - queueMicrotask(() => { - // 1. Set fr’s state to "done". - fr[kState] = 'done'; - - // 2. Let result be the result of package data given - // bytes, type, blob’s type, and encodingName. - try { - const result = packageData(bytes, type, blob.type, encodingName); - - // 4. Else: - - if (fr[kAborted]) { - return - } - - // 1. Set fr’s result to result. - fr[kResult] = result; - - // 2. Fire a progress event called load at the fr. - fireAProgressEvent('load', fr); - } catch (error) { - // 3. If package data threw an exception error: - - // 1. Set fr’s error to error. - fr[kError] = error; - - // 2. Fire a progress event called error at fr. - fireAProgressEvent('error', fr); - } - - // 5. If fr’s state is not "loading", fire a progress - // event called loadend at the fr. - if (fr[kState] !== 'loading') { - fireAProgressEvent('loadend', fr); - } - }); - - break - } - } catch (error) { - if (fr[kAborted]) { - return - } - - // 6. Otherwise, if chunkPromise is rejected with an - // error error, queue a task to run the following - // steps and abort this algorithm: - queueMicrotask(() => { - // 1. Set fr’s state to "done". - fr[kState] = 'done'; - - // 2. Set fr’s error to error. - fr[kError] = error; - - // 3. Fire a progress event called error at fr. - fireAProgressEvent('error', fr); - - // 4. If fr’s state is not "loading", fire a progress - // event called loadend at fr. - if (fr[kState] !== 'loading') { - fireAProgressEvent('loadend', fr); - } - }); - - break - } - } - })(); - } - - /** - * @see https://w3c.github.io/FileAPI/#fire-a-progress-event - * @see https://dom.spec.whatwg.org/#concept-event-fire - * @param {string} e The name of the event - * @param {import('./filereader').FileReader} reader - */ - function fireAProgressEvent (e, reader) { - // The progress event e does not bubble. e.bubbles must be false - // The progress event e is NOT cancelable. e.cancelable must be false - const event = new ProgressEvent(e, { - bubbles: false, - cancelable: false - }); - - reader.dispatchEvent(event); - } - - /** - * @see https://w3c.github.io/FileAPI/#blob-package-data - * @param {Uint8Array[]} bytes - * @param {string} type - * @param {string?} mimeType - * @param {string?} encodingName - */ - function packageData (bytes, type, mimeType, encodingName) { - // 1. A Blob has an associated package data algorithm, given - // bytes, a type, a optional mimeType, and a optional - // encodingName, which switches on type and runs the - // associated steps: - - switch (type) { - case 'DataURL': { - // 1. Return bytes as a DataURL [RFC2397] subject to - // the considerations below: - // * Use mimeType as part of the Data URL if it is - // available in keeping with the Data URL - // specification [RFC2397]. - // * If mimeType is not available return a Data URL - // without a media-type. [RFC2397]. - - // https://datatracker.ietf.org/doc/html/rfc2397#section-3 - // dataurl := "data:" [ mediatype ] [ ";base64" ] "," data - // mediatype := [ type "/" subtype ] *( ";" parameter ) - // data := *urlchar - // parameter := attribute "=" value - let dataURL = 'data:'; - - const parsed = parseMIMEType(mimeType || 'application/octet-stream'); - - if (parsed !== 'failure') { - dataURL += serializeAMimeType(parsed); - } - - dataURL += ';base64,'; - - const decoder = new StringDecoder('latin1'); - - for (const chunk of bytes) { - dataURL += btoa(decoder.write(chunk)); - } - - dataURL += btoa(decoder.end()); - - return dataURL - } - case 'Text': { - // 1. Let encoding be failure - let encoding = 'failure'; - - // 2. If the encodingName is present, set encoding to the - // result of getting an encoding from encodingName. - if (encodingName) { - encoding = getEncoding(encodingName); - } - - // 3. If encoding is failure, and mimeType is present: - if (encoding === 'failure' && mimeType) { - // 1. Let type be the result of parse a MIME type - // given mimeType. - const type = parseMIMEType(mimeType); - - // 2. If type is not failure, set encoding to the result - // of getting an encoding from type’s parameters["charset"]. - if (type !== 'failure') { - encoding = getEncoding(type.parameters.get('charset')); - } - } - - // 4. If encoding is failure, then set encoding to UTF-8. - if (encoding === 'failure') { - encoding = 'UTF-8'; - } - - // 5. Decode bytes using fallback encoding encoding, and - // return the result. - return decode(bytes, encoding) - } - case 'ArrayBuffer': { - // Return a new ArrayBuffer whose contents are bytes. - const sequence = combineByteSequences(bytes); - - return sequence.buffer - } - case 'BinaryString': { - // Return bytes as a binary string, in which every byte - // is represented by a code unit of equal value [0..255]. - let binaryString = ''; - - const decoder = new StringDecoder('latin1'); - - for (const chunk of bytes) { - binaryString += decoder.write(chunk); - } - - binaryString += decoder.end(); - - return binaryString - } - } - } - - /** - * @see https://encoding.spec.whatwg.org/#decode - * @param {Uint8Array[]} ioQueue - * @param {string} encoding - */ - function decode (ioQueue, encoding) { - const bytes = combineByteSequences(ioQueue); - - // 1. Let BOMEncoding be the result of BOM sniffing ioQueue. - const BOMEncoding = BOMSniffing(bytes); - - let slice = 0; - - // 2. If BOMEncoding is non-null: - if (BOMEncoding !== null) { - // 1. Set encoding to BOMEncoding. - encoding = BOMEncoding; - - // 2. Read three bytes from ioQueue, if BOMEncoding is - // UTF-8; otherwise read two bytes. - // (Do nothing with those bytes.) - slice = BOMEncoding === 'UTF-8' ? 3 : 2; - } - - // 3. Process a queue with an instance of encoding’s - // decoder, ioQueue, output, and "replacement". - - // 4. Return output. - - const sliced = bytes.slice(slice); - return new TextDecoder(encoding).decode(sliced) - } - - /** - * @see https://encoding.spec.whatwg.org/#bom-sniff - * @param {Uint8Array} ioQueue - */ - function BOMSniffing (ioQueue) { - // 1. Let BOM be the result of peeking 3 bytes from ioQueue, - // converted to a byte sequence. - const [a, b, c] = ioQueue; - - // 2. For each of the rows in the table below, starting with - // the first one and going down, if BOM starts with the - // bytes given in the first column, then return the - // encoding given in the cell in the second column of that - // row. Otherwise, return null. - if (a === 0xEF && b === 0xBB && c === 0xBF) { - return 'UTF-8' - } else if (a === 0xFE && b === 0xFF) { - return 'UTF-16BE' - } else if (a === 0xFF && b === 0xFE) { - return 'UTF-16LE' - } - - return null - } - - /** - * @param {Uint8Array[]} sequences - */ - function combineByteSequences (sequences) { - const size = sequences.reduce((a, b) => { - return a + b.byteLength - }, 0); - - let offset = 0; - - return sequences.reduce((a, b) => { - a.set(b, offset); - offset += b.byteLength; - return a - }, new Uint8Array(size)) - } - - util$4 = { - staticPropertyDescriptors, - readOperation, - fireAProgressEvent - }; - return util$4; -} - -var filereader; -var hasRequiredFilereader; - -function requireFilereader () { - if (hasRequiredFilereader) return filereader; - hasRequiredFilereader = 1; - - const { - staticPropertyDescriptors, - readOperation, - fireAProgressEvent - } = requireUtil$4(); - const { - kState, - kError, - kResult, - kEvents, - kAborted - } = requireSymbols$2(); - const { webidl } = requireWebidl(); - const { kEnumerableProperty } = requireUtil$7(); - - class FileReader extends EventTarget { - constructor () { - super(); - - this[kState] = 'empty'; - this[kResult] = null; - this[kError] = null; - this[kEvents] = { - loadend: null, - error: null, - abort: null, - load: null, - progress: null, - loadstart: null - }; - } - - /** - * @see https://w3c.github.io/FileAPI/#dfn-readAsArrayBuffer - * @param {import('buffer').Blob} blob - */ - readAsArrayBuffer (blob) { - webidl.brandCheck(this, FileReader); - - webidl.argumentLengthCheck(arguments, 1, 'FileReader.readAsArrayBuffer'); - - blob = webidl.converters.Blob(blob, { strict: false }); - - // The readAsArrayBuffer(blob) method, when invoked, - // must initiate a read operation for blob with ArrayBuffer. - readOperation(this, blob, 'ArrayBuffer'); - } - - /** - * @see https://w3c.github.io/FileAPI/#readAsBinaryString - * @param {import('buffer').Blob} blob - */ - readAsBinaryString (blob) { - webidl.brandCheck(this, FileReader); - - webidl.argumentLengthCheck(arguments, 1, 'FileReader.readAsBinaryString'); - - blob = webidl.converters.Blob(blob, { strict: false }); - - // The readAsBinaryString(blob) method, when invoked, - // must initiate a read operation for blob with BinaryString. - readOperation(this, blob, 'BinaryString'); - } - - /** - * @see https://w3c.github.io/FileAPI/#readAsDataText - * @param {import('buffer').Blob} blob - * @param {string?} encoding - */ - readAsText (blob, encoding = undefined) { - webidl.brandCheck(this, FileReader); - - webidl.argumentLengthCheck(arguments, 1, 'FileReader.readAsText'); - - blob = webidl.converters.Blob(blob, { strict: false }); - - if (encoding !== undefined) { - encoding = webidl.converters.DOMString(encoding, 'FileReader.readAsText', 'encoding'); - } - - // The readAsText(blob, encoding) method, when invoked, - // must initiate a read operation for blob with Text and encoding. - readOperation(this, blob, 'Text', encoding); - } - - /** - * @see https://w3c.github.io/FileAPI/#dfn-readAsDataURL - * @param {import('buffer').Blob} blob - */ - readAsDataURL (blob) { - webidl.brandCheck(this, FileReader); - - webidl.argumentLengthCheck(arguments, 1, 'FileReader.readAsDataURL'); - - blob = webidl.converters.Blob(blob, { strict: false }); - - // The readAsDataURL(blob) method, when invoked, must - // initiate a read operation for blob with DataURL. - readOperation(this, blob, 'DataURL'); - } - - /** - * @see https://w3c.github.io/FileAPI/#dfn-abort - */ - abort () { - // 1. If this's state is "empty" or if this's state is - // "done" set this's result to null and terminate - // this algorithm. - if (this[kState] === 'empty' || this[kState] === 'done') { - this[kResult] = null; - return - } - - // 2. If this's state is "loading" set this's state to - // "done" and set this's result to null. - if (this[kState] === 'loading') { - this[kState] = 'done'; - this[kResult] = null; - } - - // 3. If there are any tasks from this on the file reading - // task source in an affiliated task queue, then remove - // those tasks from that task queue. - this[kAborted] = true; - - // 4. Terminate the algorithm for the read method being processed. - // TODO - - // 5. Fire a progress event called abort at this. - fireAProgressEvent('abort', this); - - // 6. If this's state is not "loading", fire a progress - // event called loadend at this. - if (this[kState] !== 'loading') { - fireAProgressEvent('loadend', this); - } - } - - /** - * @see https://w3c.github.io/FileAPI/#dom-filereader-readystate - */ - get readyState () { - webidl.brandCheck(this, FileReader); - - switch (this[kState]) { - case 'empty': return this.EMPTY - case 'loading': return this.LOADING - case 'done': return this.DONE - } - } - - /** - * @see https://w3c.github.io/FileAPI/#dom-filereader-result - */ - get result () { - webidl.brandCheck(this, FileReader); - - // The result attribute’s getter, when invoked, must return - // this's result. - return this[kResult] - } - - /** - * @see https://w3c.github.io/FileAPI/#dom-filereader-error - */ - get error () { - webidl.brandCheck(this, FileReader); - - // The error attribute’s getter, when invoked, must return - // this's error. - return this[kError] - } - - get onloadend () { - webidl.brandCheck(this, FileReader); - - return this[kEvents].loadend - } - - set onloadend (fn) { - webidl.brandCheck(this, FileReader); - - if (this[kEvents].loadend) { - this.removeEventListener('loadend', this[kEvents].loadend); - } - - if (typeof fn === 'function') { - this[kEvents].loadend = fn; - this.addEventListener('loadend', fn); - } else { - this[kEvents].loadend = null; - } - } - - get onerror () { - webidl.brandCheck(this, FileReader); - - return this[kEvents].error - } - - set onerror (fn) { - webidl.brandCheck(this, FileReader); - - if (this[kEvents].error) { - this.removeEventListener('error', this[kEvents].error); - } - - if (typeof fn === 'function') { - this[kEvents].error = fn; - this.addEventListener('error', fn); - } else { - this[kEvents].error = null; - } - } - - get onloadstart () { - webidl.brandCheck(this, FileReader); - - return this[kEvents].loadstart - } - - set onloadstart (fn) { - webidl.brandCheck(this, FileReader); - - if (this[kEvents].loadstart) { - this.removeEventListener('loadstart', this[kEvents].loadstart); - } - - if (typeof fn === 'function') { - this[kEvents].loadstart = fn; - this.addEventListener('loadstart', fn); - } else { - this[kEvents].loadstart = null; - } - } - - get onprogress () { - webidl.brandCheck(this, FileReader); - - return this[kEvents].progress - } - - set onprogress (fn) { - webidl.brandCheck(this, FileReader); - - if (this[kEvents].progress) { - this.removeEventListener('progress', this[kEvents].progress); - } - - if (typeof fn === 'function') { - this[kEvents].progress = fn; - this.addEventListener('progress', fn); - } else { - this[kEvents].progress = null; - } - } - - get onload () { - webidl.brandCheck(this, FileReader); - - return this[kEvents].load - } - - set onload (fn) { - webidl.brandCheck(this, FileReader); - - if (this[kEvents].load) { - this.removeEventListener('load', this[kEvents].load); - } - - if (typeof fn === 'function') { - this[kEvents].load = fn; - this.addEventListener('load', fn); - } else { - this[kEvents].load = null; - } - } - - get onabort () { - webidl.brandCheck(this, FileReader); - - return this[kEvents].abort - } - - set onabort (fn) { - webidl.brandCheck(this, FileReader); - - if (this[kEvents].abort) { - this.removeEventListener('abort', this[kEvents].abort); - } - - if (typeof fn === 'function') { - this[kEvents].abort = fn; - this.addEventListener('abort', fn); - } else { - this[kEvents].abort = null; - } - } - } - - // https://w3c.github.io/FileAPI/#dom-filereader-empty - FileReader.EMPTY = FileReader.prototype.EMPTY = 0; - // https://w3c.github.io/FileAPI/#dom-filereader-loading - FileReader.LOADING = FileReader.prototype.LOADING = 1; - // https://w3c.github.io/FileAPI/#dom-filereader-done - FileReader.DONE = FileReader.prototype.DONE = 2; - - Object.defineProperties(FileReader.prototype, { - EMPTY: staticPropertyDescriptors, - LOADING: staticPropertyDescriptors, - DONE: staticPropertyDescriptors, - readAsArrayBuffer: kEnumerableProperty, - readAsBinaryString: kEnumerableProperty, - readAsText: kEnumerableProperty, - readAsDataURL: kEnumerableProperty, - abort: kEnumerableProperty, - readyState: kEnumerableProperty, - result: kEnumerableProperty, - error: kEnumerableProperty, - onloadstart: kEnumerableProperty, - onprogress: kEnumerableProperty, - onload: kEnumerableProperty, - onabort: kEnumerableProperty, - onerror: kEnumerableProperty, - onloadend: kEnumerableProperty, - [Symbol.toStringTag]: { - value: 'FileReader', - writable: false, - enumerable: false, - configurable: true - } - }); - - Object.defineProperties(FileReader, { - EMPTY: staticPropertyDescriptors, - LOADING: staticPropertyDescriptors, - DONE: staticPropertyDescriptors - }); - - filereader = { - FileReader - }; - return filereader; -} - -var symbols$1; -var hasRequiredSymbols$1; - -function requireSymbols$1 () { - if (hasRequiredSymbols$1) return symbols$1; - hasRequiredSymbols$1 = 1; - - symbols$1 = { - kConstruct: requireSymbols$4().kConstruct - }; - return symbols$1; -} - -var util$3; -var hasRequiredUtil$3; - -function requireUtil$3 () { - if (hasRequiredUtil$3) return util$3; - hasRequiredUtil$3 = 1; - - const assert = require$$0$4; - const { URLSerializer } = requireDataUrl(); - const { isValidHeaderName } = requireUtil$6(); - - /** - * @see https://url.spec.whatwg.org/#concept-url-equals - * @param {URL} A - * @param {URL} B - * @param {boolean | undefined} excludeFragment - * @returns {boolean} - */ - function urlEquals (A, B, excludeFragment = false) { - const serializedA = URLSerializer(A, excludeFragment); - - const serializedB = URLSerializer(B, excludeFragment); - - return serializedA === serializedB - } - - /** - * @see https://github.com/chromium/chromium/blob/694d20d134cb553d8d89e5500b9148012b1ba299/content/browser/cache_storage/cache_storage_cache.cc#L260-L262 - * @param {string} header - */ - function getFieldValues (header) { - assert(header !== null); - - const values = []; - - for (let value of header.split(',')) { - value = value.trim(); - - if (isValidHeaderName(value)) { - values.push(value); - } - } - - return values - } - - util$3 = { - urlEquals, - getFieldValues - }; - return util$3; -} - -var cache; -var hasRequiredCache; - -function requireCache () { - if (hasRequiredCache) return cache; - hasRequiredCache = 1; - - const { kConstruct } = requireSymbols$1(); - const { urlEquals, getFieldValues } = requireUtil$3(); - const { kEnumerableProperty, isDisturbed } = requireUtil$7(); - const { webidl } = requireWebidl(); - const { Response, cloneResponse, fromInnerResponse } = requireResponse(); - const { Request, fromInnerRequest } = requireRequest(); - const { kState } = requireSymbols$3(); - const { fetching } = requireFetch(); - const { urlIsHttpHttpsScheme, createDeferredPromise, readAllBytes } = requireUtil$6(); - const assert = require$$0$4; - - /** - * @see https://w3c.github.io/ServiceWorker/#dfn-cache-batch-operation - * @typedef {Object} CacheBatchOperation - * @property {'delete' | 'put'} type - * @property {any} request - * @property {any} response - * @property {import('../../types/cache').CacheQueryOptions} options - */ - - /** - * @see https://w3c.github.io/ServiceWorker/#dfn-request-response-list - * @typedef {[any, any][]} requestResponseList - */ - - class Cache { - /** - * @see https://w3c.github.io/ServiceWorker/#dfn-relevant-request-response-list - * @type {requestResponseList} - */ - #relevantRequestResponseList - - constructor () { - if (arguments[0] !== kConstruct) { - webidl.illegalConstructor(); - } - - this.#relevantRequestResponseList = arguments[1]; - } - - async match (request, options = {}) { - webidl.brandCheck(this, Cache); - - const prefix = 'Cache.match'; - webidl.argumentLengthCheck(arguments, 1, prefix); - - request = webidl.converters.RequestInfo(request, prefix, 'request'); - options = webidl.converters.CacheQueryOptions(options, prefix, 'options'); - - const p = this.#internalMatchAll(request, options, 1); - - if (p.length === 0) { - return - } - - return p[0] - } - - async matchAll (request = undefined, options = {}) { - webidl.brandCheck(this, Cache); - - const prefix = 'Cache.matchAll'; - if (request !== undefined) request = webidl.converters.RequestInfo(request, prefix, 'request'); - options = webidl.converters.CacheQueryOptions(options, prefix, 'options'); - - return this.#internalMatchAll(request, options) - } - - async add (request) { - webidl.brandCheck(this, Cache); - - const prefix = 'Cache.add'; - webidl.argumentLengthCheck(arguments, 1, prefix); - - request = webidl.converters.RequestInfo(request, prefix, 'request'); - - // 1. - const requests = [request]; - - // 2. - const responseArrayPromise = this.addAll(requests); - - // 3. - return await responseArrayPromise - } - - async addAll (requests) { - webidl.brandCheck(this, Cache); - - const prefix = 'Cache.addAll'; - webidl.argumentLengthCheck(arguments, 1, prefix); - - // 1. - const responsePromises = []; - - // 2. - const requestList = []; - - // 3. - for (let request of requests) { - if (request === undefined) { - throw webidl.errors.conversionFailed({ - prefix, - argument: 'Argument 1', - types: ['undefined is not allowed'] - }) - } - - request = webidl.converters.RequestInfo(request); - - if (typeof request === 'string') { - continue - } - - // 3.1 - const r = request[kState]; - - // 3.2 - if (!urlIsHttpHttpsScheme(r.url) || r.method !== 'GET') { - throw webidl.errors.exception({ - header: prefix, - message: 'Expected http/s scheme when method is not GET.' - }) - } - } - - // 4. - /** @type {ReturnType[]} */ - const fetchControllers = []; - - // 5. - for (const request of requests) { - // 5.1 - const r = new Request(request)[kState]; - - // 5.2 - if (!urlIsHttpHttpsScheme(r.url)) { - throw webidl.errors.exception({ - header: prefix, - message: 'Expected http/s scheme.' - }) - } - - // 5.4 - r.initiator = 'fetch'; - r.destination = 'subresource'; - - // 5.5 - requestList.push(r); - - // 5.6 - const responsePromise = createDeferredPromise(); - - // 5.7 - fetchControllers.push(fetching({ - request: r, - processResponse (response) { - // 1. - if (response.type === 'error' || response.status === 206 || response.status < 200 || response.status > 299) { - responsePromise.reject(webidl.errors.exception({ - header: 'Cache.addAll', - message: 'Received an invalid status code or the request failed.' - })); - } else if (response.headersList.contains('vary')) { // 2. - // 2.1 - const fieldValues = getFieldValues(response.headersList.get('vary')); - - // 2.2 - for (const fieldValue of fieldValues) { - // 2.2.1 - if (fieldValue === '*') { - responsePromise.reject(webidl.errors.exception({ - header: 'Cache.addAll', - message: 'invalid vary field value' - })); - - for (const controller of fetchControllers) { - controller.abort(); - } - - return - } - } - } - }, - processResponseEndOfBody (response) { - // 1. - if (response.aborted) { - responsePromise.reject(new DOMException('aborted', 'AbortError')); - return - } - - // 2. - responsePromise.resolve(response); - } - })); - - // 5.8 - responsePromises.push(responsePromise.promise); - } - - // 6. - const p = Promise.all(responsePromises); - - // 7. - const responses = await p; - - // 7.1 - const operations = []; - - // 7.2 - let index = 0; - - // 7.3 - for (const response of responses) { - // 7.3.1 - /** @type {CacheBatchOperation} */ - const operation = { - type: 'put', // 7.3.2 - request: requestList[index], // 7.3.3 - response // 7.3.4 - }; - - operations.push(operation); // 7.3.5 - - index++; // 7.3.6 - } - - // 7.5 - const cacheJobPromise = createDeferredPromise(); - - // 7.6.1 - let errorData = null; - - // 7.6.2 - try { - this.#batchCacheOperations(operations); - } catch (e) { - errorData = e; - } - - // 7.6.3 - queueMicrotask(() => { - // 7.6.3.1 - if (errorData === null) { - cacheJobPromise.resolve(undefined); - } else { - // 7.6.3.2 - cacheJobPromise.reject(errorData); - } - }); - - // 7.7 - return cacheJobPromise.promise - } - - async put (request, response) { - webidl.brandCheck(this, Cache); - - const prefix = 'Cache.put'; - webidl.argumentLengthCheck(arguments, 2, prefix); - - request = webidl.converters.RequestInfo(request, prefix, 'request'); - response = webidl.converters.Response(response, prefix, 'response'); - - // 1. - let innerRequest = null; - - // 2. - if (request instanceof Request) { - innerRequest = request[kState]; - } else { // 3. - innerRequest = new Request(request)[kState]; - } - - // 4. - if (!urlIsHttpHttpsScheme(innerRequest.url) || innerRequest.method !== 'GET') { - throw webidl.errors.exception({ - header: prefix, - message: 'Expected an http/s scheme when method is not GET' - }) - } - - // 5. - const innerResponse = response[kState]; - - // 6. - if (innerResponse.status === 206) { - throw webidl.errors.exception({ - header: prefix, - message: 'Got 206 status' - }) - } - - // 7. - if (innerResponse.headersList.contains('vary')) { - // 7.1. - const fieldValues = getFieldValues(innerResponse.headersList.get('vary')); - - // 7.2. - for (const fieldValue of fieldValues) { - // 7.2.1 - if (fieldValue === '*') { - throw webidl.errors.exception({ - header: prefix, - message: 'Got * vary field value' - }) - } - } - } - - // 8. - if (innerResponse.body && (isDisturbed(innerResponse.body.stream) || innerResponse.body.stream.locked)) { - throw webidl.errors.exception({ - header: prefix, - message: 'Response body is locked or disturbed' - }) - } - - // 9. - const clonedResponse = cloneResponse(innerResponse); - - // 10. - const bodyReadPromise = createDeferredPromise(); - - // 11. - if (innerResponse.body != null) { - // 11.1 - const stream = innerResponse.body.stream; - - // 11.2 - const reader = stream.getReader(); - - // 11.3 - readAllBytes(reader).then(bodyReadPromise.resolve, bodyReadPromise.reject); - } else { - bodyReadPromise.resolve(undefined); - } - - // 12. - /** @type {CacheBatchOperation[]} */ - const operations = []; - - // 13. - /** @type {CacheBatchOperation} */ - const operation = { - type: 'put', // 14. - request: innerRequest, // 15. - response: clonedResponse // 16. - }; - - // 17. - operations.push(operation); - - // 19. - const bytes = await bodyReadPromise.promise; - - if (clonedResponse.body != null) { - clonedResponse.body.source = bytes; - } - - // 19.1 - const cacheJobPromise = createDeferredPromise(); - - // 19.2.1 - let errorData = null; - - // 19.2.2 - try { - this.#batchCacheOperations(operations); - } catch (e) { - errorData = e; - } - - // 19.2.3 - queueMicrotask(() => { - // 19.2.3.1 - if (errorData === null) { - cacheJobPromise.resolve(); - } else { // 19.2.3.2 - cacheJobPromise.reject(errorData); - } - }); - - return cacheJobPromise.promise - } - - async delete (request, options = {}) { - webidl.brandCheck(this, Cache); - - const prefix = 'Cache.delete'; - webidl.argumentLengthCheck(arguments, 1, prefix); - - request = webidl.converters.RequestInfo(request, prefix, 'request'); - options = webidl.converters.CacheQueryOptions(options, prefix, 'options'); - - /** - * @type {Request} - */ - let r = null; - - if (request instanceof Request) { - r = request[kState]; - - if (r.method !== 'GET' && !options.ignoreMethod) { - return false - } - } else { - assert(typeof request === 'string'); - - r = new Request(request)[kState]; - } - - /** @type {CacheBatchOperation[]} */ - const operations = []; - - /** @type {CacheBatchOperation} */ - const operation = { - type: 'delete', - request: r, - options - }; - - operations.push(operation); - - const cacheJobPromise = createDeferredPromise(); - - let errorData = null; - let requestResponses; - - try { - requestResponses = this.#batchCacheOperations(operations); - } catch (e) { - errorData = e; - } - - queueMicrotask(() => { - if (errorData === null) { - cacheJobPromise.resolve(!!requestResponses?.length); - } else { - cacheJobPromise.reject(errorData); - } - }); - - return cacheJobPromise.promise - } - - /** - * @see https://w3c.github.io/ServiceWorker/#dom-cache-keys - * @param {any} request - * @param {import('../../types/cache').CacheQueryOptions} options - * @returns {Promise} - */ - async keys (request = undefined, options = {}) { - webidl.brandCheck(this, Cache); - - const prefix = 'Cache.keys'; - - if (request !== undefined) request = webidl.converters.RequestInfo(request, prefix, 'request'); - options = webidl.converters.CacheQueryOptions(options, prefix, 'options'); - - // 1. - let r = null; - - // 2. - if (request !== undefined) { - // 2.1 - if (request instanceof Request) { - // 2.1.1 - r = request[kState]; - - // 2.1.2 - if (r.method !== 'GET' && !options.ignoreMethod) { - return [] - } - } else if (typeof request === 'string') { // 2.2 - r = new Request(request)[kState]; - } - } - - // 4. - const promise = createDeferredPromise(); - - // 5. - // 5.1 - const requests = []; - - // 5.2 - if (request === undefined) { - // 5.2.1 - for (const requestResponse of this.#relevantRequestResponseList) { - // 5.2.1.1 - requests.push(requestResponse[0]); - } - } else { // 5.3 - // 5.3.1 - const requestResponses = this.#queryCache(r, options); - - // 5.3.2 - for (const requestResponse of requestResponses) { - // 5.3.2.1 - requests.push(requestResponse[0]); - } - } - - // 5.4 - queueMicrotask(() => { - // 5.4.1 - const requestList = []; - - // 5.4.2 - for (const request of requests) { - const requestObject = fromInnerRequest( - request, - new AbortController().signal, - 'immutable' - ); - // 5.4.2.1 - requestList.push(requestObject); - } - - // 5.4.3 - promise.resolve(Object.freeze(requestList)); - }); - - return promise.promise - } - - /** - * @see https://w3c.github.io/ServiceWorker/#batch-cache-operations-algorithm - * @param {CacheBatchOperation[]} operations - * @returns {requestResponseList} - */ - #batchCacheOperations (operations) { - // 1. - const cache = this.#relevantRequestResponseList; - - // 2. - const backupCache = [...cache]; - - // 3. - const addedItems = []; - - // 4.1 - const resultList = []; - - try { - // 4.2 - for (const operation of operations) { - // 4.2.1 - if (operation.type !== 'delete' && operation.type !== 'put') { - throw webidl.errors.exception({ - header: 'Cache.#batchCacheOperations', - message: 'operation type does not match "delete" or "put"' - }) - } - - // 4.2.2 - if (operation.type === 'delete' && operation.response != null) { - throw webidl.errors.exception({ - header: 'Cache.#batchCacheOperations', - message: 'delete operation should not have an associated response' - }) - } - - // 4.2.3 - if (this.#queryCache(operation.request, operation.options, addedItems).length) { - throw new DOMException('???', 'InvalidStateError') - } - - // 4.2.4 - let requestResponses; - - // 4.2.5 - if (operation.type === 'delete') { - // 4.2.5.1 - requestResponses = this.#queryCache(operation.request, operation.options); - - // TODO: the spec is wrong, this is needed to pass WPTs - if (requestResponses.length === 0) { - return [] - } - - // 4.2.5.2 - for (const requestResponse of requestResponses) { - const idx = cache.indexOf(requestResponse); - assert(idx !== -1); - - // 4.2.5.2.1 - cache.splice(idx, 1); - } - } else if (operation.type === 'put') { // 4.2.6 - // 4.2.6.1 - if (operation.response == null) { - throw webidl.errors.exception({ - header: 'Cache.#batchCacheOperations', - message: 'put operation should have an associated response' - }) - } - - // 4.2.6.2 - const r = operation.request; - - // 4.2.6.3 - if (!urlIsHttpHttpsScheme(r.url)) { - throw webidl.errors.exception({ - header: 'Cache.#batchCacheOperations', - message: 'expected http or https scheme' - }) - } - - // 4.2.6.4 - if (r.method !== 'GET') { - throw webidl.errors.exception({ - header: 'Cache.#batchCacheOperations', - message: 'not get method' - }) - } - - // 4.2.6.5 - if (operation.options != null) { - throw webidl.errors.exception({ - header: 'Cache.#batchCacheOperations', - message: 'options must not be defined' - }) - } - - // 4.2.6.6 - requestResponses = this.#queryCache(operation.request); - - // 4.2.6.7 - for (const requestResponse of requestResponses) { - const idx = cache.indexOf(requestResponse); - assert(idx !== -1); - - // 4.2.6.7.1 - cache.splice(idx, 1); - } - - // 4.2.6.8 - cache.push([operation.request, operation.response]); - - // 4.2.6.10 - addedItems.push([operation.request, operation.response]); - } - - // 4.2.7 - resultList.push([operation.request, operation.response]); - } - - // 4.3 - return resultList - } catch (e) { // 5. - // 5.1 - this.#relevantRequestResponseList.length = 0; - - // 5.2 - this.#relevantRequestResponseList = backupCache; - - // 5.3 - throw e - } - } - - /** - * @see https://w3c.github.io/ServiceWorker/#query-cache - * @param {any} requestQuery - * @param {import('../../types/cache').CacheQueryOptions} options - * @param {requestResponseList} targetStorage - * @returns {requestResponseList} - */ - #queryCache (requestQuery, options, targetStorage) { - /** @type {requestResponseList} */ - const resultList = []; - - const storage = targetStorage ?? this.#relevantRequestResponseList; - - for (const requestResponse of storage) { - const [cachedRequest, cachedResponse] = requestResponse; - if (this.#requestMatchesCachedItem(requestQuery, cachedRequest, cachedResponse, options)) { - resultList.push(requestResponse); - } - } - - return resultList - } - - /** - * @see https://w3c.github.io/ServiceWorker/#request-matches-cached-item-algorithm - * @param {any} requestQuery - * @param {any} request - * @param {any | null} response - * @param {import('../../types/cache').CacheQueryOptions | undefined} options - * @returns {boolean} - */ - #requestMatchesCachedItem (requestQuery, request, response = null, options) { - // if (options?.ignoreMethod === false && request.method === 'GET') { - // return false - // } - - const queryURL = new URL(requestQuery.url); - - const cachedURL = new URL(request.url); - - if (options?.ignoreSearch) { - cachedURL.search = ''; - - queryURL.search = ''; - } - - if (!urlEquals(queryURL, cachedURL, true)) { - return false - } - - if ( - response == null || - options?.ignoreVary || - !response.headersList.contains('vary') - ) { - return true - } - - const fieldValues = getFieldValues(response.headersList.get('vary')); - - for (const fieldValue of fieldValues) { - if (fieldValue === '*') { - return false - } - - const requestValue = request.headersList.get(fieldValue); - const queryValue = requestQuery.headersList.get(fieldValue); - - // If one has the header and the other doesn't, or one has - // a different value than the other, return false - if (requestValue !== queryValue) { - return false - } - } - - return true - } - - #internalMatchAll (request, options, maxResponses = Infinity) { - // 1. - let r = null; - - // 2. - if (request !== undefined) { - if (request instanceof Request) { - // 2.1.1 - r = request[kState]; - - // 2.1.2 - if (r.method !== 'GET' && !options.ignoreMethod) { - return [] - } - } else if (typeof request === 'string') { - // 2.2.1 - r = new Request(request)[kState]; - } - } - - // 5. - // 5.1 - const responses = []; - - // 5.2 - if (request === undefined) { - // 5.2.1 - for (const requestResponse of this.#relevantRequestResponseList) { - responses.push(requestResponse[1]); - } - } else { // 5.3 - // 5.3.1 - const requestResponses = this.#queryCache(r, options); - - // 5.3.2 - for (const requestResponse of requestResponses) { - responses.push(requestResponse[1]); - } - } - - // 5.4 - // We don't implement CORs so we don't need to loop over the responses, yay! - - // 5.5.1 - const responseList = []; - - // 5.5.2 - for (const response of responses) { - // 5.5.2.1 - const responseObject = fromInnerResponse(response, 'immutable'); - - responseList.push(responseObject.clone()); - - if (responseList.length >= maxResponses) { - break - } - } - - // 6. - return Object.freeze(responseList) - } - } - - Object.defineProperties(Cache.prototype, { - [Symbol.toStringTag]: { - value: 'Cache', - configurable: true - }, - match: kEnumerableProperty, - matchAll: kEnumerableProperty, - add: kEnumerableProperty, - addAll: kEnumerableProperty, - put: kEnumerableProperty, - delete: kEnumerableProperty, - keys: kEnumerableProperty - }); - - const cacheQueryOptionConverters = [ - { - key: 'ignoreSearch', - converter: webidl.converters.boolean, - defaultValue: () => false - }, - { - key: 'ignoreMethod', - converter: webidl.converters.boolean, - defaultValue: () => false - }, - { - key: 'ignoreVary', - converter: webidl.converters.boolean, - defaultValue: () => false - } - ]; - - webidl.converters.CacheQueryOptions = webidl.dictionaryConverter(cacheQueryOptionConverters); - - webidl.converters.MultiCacheQueryOptions = webidl.dictionaryConverter([ - ...cacheQueryOptionConverters, - { - key: 'cacheName', - converter: webidl.converters.DOMString - } - ]); - - webidl.converters.Response = webidl.interfaceConverter(Response); - - webidl.converters['sequence'] = webidl.sequenceConverter( - webidl.converters.RequestInfo - ); - - cache = { - Cache - }; - return cache; -} - -var cachestorage; -var hasRequiredCachestorage; - -function requireCachestorage () { - if (hasRequiredCachestorage) return cachestorage; - hasRequiredCachestorage = 1; - - const { kConstruct } = requireSymbols$1(); - const { Cache } = requireCache(); - const { webidl } = requireWebidl(); - const { kEnumerableProperty } = requireUtil$7(); - - class CacheStorage { - /** - * @see https://w3c.github.io/ServiceWorker/#dfn-relevant-name-to-cache-map - * @type {Map} - */ - async has (cacheName) { - webidl.brandCheck(this, CacheStorage); - - const prefix = 'CacheStorage.has'; - webidl.argumentLengthCheck(arguments, 1, prefix); - - cacheName = webidl.converters.DOMString(cacheName, prefix, 'cacheName'); - - // 2.1.1 - // 2.2 - return this.#caches.has(cacheName) - } - - /** - * @see https://w3c.github.io/ServiceWorker/#dom-cachestorage-open - * @param {string} cacheName - * @returns {Promise} - */ - async open (cacheName) { - webidl.brandCheck(this, CacheStorage); - - const prefix = 'CacheStorage.open'; - webidl.argumentLengthCheck(arguments, 1, prefix); - - cacheName = webidl.converters.DOMString(cacheName, prefix, 'cacheName'); - - // 2.1 - if (this.#caches.has(cacheName)) { - // await caches.open('v1') !== await caches.open('v1') - - // 2.1.1 - const cache = this.#caches.get(cacheName); - - // 2.1.1.1 - return new Cache(kConstruct, cache) - } - - // 2.2 - const cache = []; - - // 2.3 - this.#caches.set(cacheName, cache); - - // 2.4 - return new Cache(kConstruct, cache) - } - - /** - * @see https://w3c.github.io/ServiceWorker/#cache-storage-delete - * @param {string} cacheName - * @returns {Promise} - */ - async delete (cacheName) { - webidl.brandCheck(this, CacheStorage); - - const prefix = 'CacheStorage.delete'; - webidl.argumentLengthCheck(arguments, 1, prefix); - - cacheName = webidl.converters.DOMString(cacheName, prefix, 'cacheName'); - - return this.#caches.delete(cacheName) - } - - /** - * @see https://w3c.github.io/ServiceWorker/#cache-storage-keys - * @returns {Promise} - */ - async keys () { - webidl.brandCheck(this, CacheStorage); - - // 2.1 - const keys = this.#caches.keys(); - - // 2.2 - return [...keys] - } - } - - Object.defineProperties(CacheStorage.prototype, { - [Symbol.toStringTag]: { - value: 'CacheStorage', - configurable: true - }, - match: kEnumerableProperty, - has: kEnumerableProperty, - open: kEnumerableProperty, - delete: kEnumerableProperty, - keys: kEnumerableProperty - }); - - cachestorage = { - CacheStorage - }; - return cachestorage; -} - -var constants$1; -var hasRequiredConstants$1; - -function requireConstants$1 () { - if (hasRequiredConstants$1) return constants$1; - hasRequiredConstants$1 = 1; - - // https://wicg.github.io/cookie-store/#cookie-maximum-attribute-value-size - const maxAttributeValueSize = 1024; - - // https://wicg.github.io/cookie-store/#cookie-maximum-name-value-pair-size - const maxNameValuePairSize = 4096; - - constants$1 = { - maxAttributeValueSize, - maxNameValuePairSize - }; - return constants$1; -} - -var util$2; -var hasRequiredUtil$2; - -function requireUtil$2 () { - if (hasRequiredUtil$2) return util$2; - hasRequiredUtil$2 = 1; - - /** - * @param {string} value - * @returns {boolean} - */ - function isCTLExcludingHtab (value) { - for (let i = 0; i < value.length; ++i) { - const code = value.charCodeAt(i); - - if ( - (code >= 0x00 && code <= 0x08) || - (code >= 0x0A && code <= 0x1F) || - code === 0x7F - ) { - return true - } - } - return false - } - - /** - CHAR = - token = 1* - separators = "(" | ")" | "<" | ">" | "@" - | "," | ";" | ":" | "\" | <"> - | "/" | "[" | "]" | "?" | "=" - | "{" | "}" | SP | HT - * @param {string} name - */ - function validateCookieName (name) { - for (let i = 0; i < name.length; ++i) { - const code = name.charCodeAt(i); - - if ( - code < 0x21 || // exclude CTLs (0-31), SP and HT - code > 0x7E || // exclude non-ascii and DEL - code === 0x22 || // " - code === 0x28 || // ( - code === 0x29 || // ) - code === 0x3C || // < - code === 0x3E || // > - code === 0x40 || // @ - code === 0x2C || // , - code === 0x3B || // ; - code === 0x3A || // : - code === 0x5C || // \ - code === 0x2F || // / - code === 0x5B || // [ - code === 0x5D || // ] - code === 0x3F || // ? - code === 0x3D || // = - code === 0x7B || // { - code === 0x7D // } - ) { - throw new Error('Invalid cookie name') - } - } - } - - /** - cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE ) - cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E - ; US-ASCII characters excluding CTLs, - ; whitespace DQUOTE, comma, semicolon, - ; and backslash - * @param {string} value - */ - function validateCookieValue (value) { - let len = value.length; - let i = 0; - - // if the value is wrapped in DQUOTE - if (value[0] === '"') { - if (len === 1 || value[len - 1] !== '"') { - throw new Error('Invalid cookie value') - } - --len; - ++i; - } - - while (i < len) { - const code = value.charCodeAt(i++); - - if ( - code < 0x21 || // exclude CTLs (0-31) - code > 0x7E || // non-ascii and DEL (127) - code === 0x22 || // " - code === 0x2C || // , - code === 0x3B || // ; - code === 0x5C // \ - ) { - throw new Error('Invalid cookie value') - } - } - } - - /** - * path-value = - * @param {string} path - */ - function validateCookiePath (path) { - for (let i = 0; i < path.length; ++i) { - const code = path.charCodeAt(i); - - if ( - code < 0x20 || // exclude CTLs (0-31) - code === 0x7F || // DEL - code === 0x3B // ; - ) { - throw new Error('Invalid cookie path') - } - } - } - - /** - * I have no idea why these values aren't allowed to be honest, - * but Deno tests these. - Khafra - * @param {string} domain - */ - function validateCookieDomain (domain) { - if ( - domain.startsWith('-') || - domain.endsWith('.') || - domain.endsWith('-') - ) { - throw new Error('Invalid cookie domain') - } - } - - const IMFDays = [ - 'Sun', 'Mon', 'Tue', 'Wed', - 'Thu', 'Fri', 'Sat' - ]; - - const IMFMonths = [ - 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', - 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' - ]; - - const IMFPaddedNumbers = Array(61).fill(0).map((_, i) => i.toString().padStart(2, '0')); - - /** - * @see https://www.rfc-editor.org/rfc/rfc7231#section-7.1.1.1 - * @param {number|Date} date - IMF-fixdate = day-name "," SP date1 SP time-of-day SP GMT - ; fixed length/zone/capitalization subset of the format - ; see Section 3.3 of [RFC5322] - - day-name = %x4D.6F.6E ; "Mon", case-sensitive - / %x54.75.65 ; "Tue", case-sensitive - / %x57.65.64 ; "Wed", case-sensitive - / %x54.68.75 ; "Thu", case-sensitive - / %x46.72.69 ; "Fri", case-sensitive - / %x53.61.74 ; "Sat", case-sensitive - / %x53.75.6E ; "Sun", case-sensitive - date1 = day SP month SP year - ; e.g., 02 Jun 1982 - - day = 2DIGIT - month = %x4A.61.6E ; "Jan", case-sensitive - / %x46.65.62 ; "Feb", case-sensitive - / %x4D.61.72 ; "Mar", case-sensitive - / %x41.70.72 ; "Apr", case-sensitive - / %x4D.61.79 ; "May", case-sensitive - / %x4A.75.6E ; "Jun", case-sensitive - / %x4A.75.6C ; "Jul", case-sensitive - / %x41.75.67 ; "Aug", case-sensitive - / %x53.65.70 ; "Sep", case-sensitive - / %x4F.63.74 ; "Oct", case-sensitive - / %x4E.6F.76 ; "Nov", case-sensitive - / %x44.65.63 ; "Dec", case-sensitive - year = 4DIGIT - - GMT = %x47.4D.54 ; "GMT", case-sensitive - - time-of-day = hour ":" minute ":" second - ; 00:00:00 - 23:59:60 (leap second) - - hour = 2DIGIT - minute = 2DIGIT - second = 2DIGIT - */ - function toIMFDate (date) { - if (typeof date === 'number') { - date = new Date(date); - } - - return `${IMFDays[date.getUTCDay()]}, ${IMFPaddedNumbers[date.getUTCDate()]} ${IMFMonths[date.getUTCMonth()]} ${date.getUTCFullYear()} ${IMFPaddedNumbers[date.getUTCHours()]}:${IMFPaddedNumbers[date.getUTCMinutes()]}:${IMFPaddedNumbers[date.getUTCSeconds()]} GMT` - } - - /** - max-age-av = "Max-Age=" non-zero-digit *DIGIT - ; In practice, both expires-av and max-age-av - ; are limited to dates representable by the - ; user agent. - * @param {number} maxAge - */ - function validateCookieMaxAge (maxAge) { - if (maxAge < 0) { - throw new Error('Invalid cookie max-age') - } - } - - /** - * @see https://www.rfc-editor.org/rfc/rfc6265#section-4.1.1 - * @param {import('./index').Cookie} cookie - */ - function stringify (cookie) { - if (cookie.name.length === 0) { - return null - } - - validateCookieName(cookie.name); - validateCookieValue(cookie.value); - - const out = [`${cookie.name}=${cookie.value}`]; - - // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-cookie-prefixes-00#section-3.1 - // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-cookie-prefixes-00#section-3.2 - if (cookie.name.startsWith('__Secure-')) { - cookie.secure = true; - } - - if (cookie.name.startsWith('__Host-')) { - cookie.secure = true; - cookie.domain = null; - cookie.path = '/'; - } - - if (cookie.secure) { - out.push('Secure'); - } - - if (cookie.httpOnly) { - out.push('HttpOnly'); - } - - if (typeof cookie.maxAge === 'number') { - validateCookieMaxAge(cookie.maxAge); - out.push(`Max-Age=${cookie.maxAge}`); - } - - if (cookie.domain) { - validateCookieDomain(cookie.domain); - out.push(`Domain=${cookie.domain}`); - } - - if (cookie.path) { - validateCookiePath(cookie.path); - out.push(`Path=${cookie.path}`); - } - - if (cookie.expires && cookie.expires.toString() !== 'Invalid Date') { - out.push(`Expires=${toIMFDate(cookie.expires)}`); - } - - if (cookie.sameSite) { - out.push(`SameSite=${cookie.sameSite}`); - } - - for (const part of cookie.unparsed) { - if (!part.includes('=')) { - throw new Error('Invalid unparsed') - } - - const [key, ...value] = part.split('='); - - out.push(`${key.trim()}=${value.join('=')}`); - } - - return out.join('; ') - } - - util$2 = { - isCTLExcludingHtab, - validateCookieName, - validateCookiePath, - validateCookieValue, - toIMFDate, - stringify - }; - return util$2; -} - -var parse; -var hasRequiredParse; - -function requireParse () { - if (hasRequiredParse) return parse; - hasRequiredParse = 1; - - const { maxNameValuePairSize, maxAttributeValueSize } = requireConstants$1(); - const { isCTLExcludingHtab } = requireUtil$2(); - const { collectASequenceOfCodePointsFast } = requireDataUrl(); - const assert = require$$0$4; - - /** - * @description Parses the field-value attributes of a set-cookie header string. - * @see https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4 - * @param {string} header - * @returns if the header is invalid, null will be returned - */ - function parseSetCookie (header) { - // 1. If the set-cookie-string contains a %x00-08 / %x0A-1F / %x7F - // character (CTL characters excluding HTAB): Abort these steps and - // ignore the set-cookie-string entirely. - if (isCTLExcludingHtab(header)) { - return null - } - - let nameValuePair = ''; - let unparsedAttributes = ''; - let name = ''; - let value = ''; - - // 2. If the set-cookie-string contains a %x3B (";") character: - if (header.includes(';')) { - // 1. The name-value-pair string consists of the characters up to, - // but not including, the first %x3B (";"), and the unparsed- - // attributes consist of the remainder of the set-cookie-string - // (including the %x3B (";") in question). - const position = { position: 0 }; - - nameValuePair = collectASequenceOfCodePointsFast(';', header, position); - unparsedAttributes = header.slice(position.position); - } else { - // Otherwise: - - // 1. The name-value-pair string consists of all the characters - // contained in the set-cookie-string, and the unparsed- - // attributes is the empty string. - nameValuePair = header; - } - - // 3. If the name-value-pair string lacks a %x3D ("=") character, then - // the name string is empty, and the value string is the value of - // name-value-pair. - if (!nameValuePair.includes('=')) { - value = nameValuePair; - } else { - // Otherwise, the name string consists of the characters up to, but - // not including, the first %x3D ("=") character, and the (possibly - // empty) value string consists of the characters after the first - // %x3D ("=") character. - const position = { position: 0 }; - name = collectASequenceOfCodePointsFast( - '=', - nameValuePair, - position - ); - value = nameValuePair.slice(position.position + 1); - } - - // 4. Remove any leading or trailing WSP characters from the name - // string and the value string. - name = name.trim(); - value = value.trim(); - - // 5. If the sum of the lengths of the name string and the value string - // is more than 4096 octets, abort these steps and ignore the set- - // cookie-string entirely. - if (name.length + value.length > maxNameValuePairSize) { - return null - } - - // 6. The cookie-name is the name string, and the cookie-value is the - // value string. - return { - name, value, ...parseUnparsedAttributes(unparsedAttributes) - } - } - - /** - * Parses the remaining attributes of a set-cookie header - * @see https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4 - * @param {string} unparsedAttributes - * @param {[Object.]={}} cookieAttributeList - */ - function parseUnparsedAttributes (unparsedAttributes, cookieAttributeList = {}) { - // 1. If the unparsed-attributes string is empty, skip the rest of - // these steps. - if (unparsedAttributes.length === 0) { - return cookieAttributeList - } - - // 2. Discard the first character of the unparsed-attributes (which - // will be a %x3B (";") character). - assert(unparsedAttributes[0] === ';'); - unparsedAttributes = unparsedAttributes.slice(1); - - let cookieAv = ''; - - // 3. If the remaining unparsed-attributes contains a %x3B (";") - // character: - if (unparsedAttributes.includes(';')) { - // 1. Consume the characters of the unparsed-attributes up to, but - // not including, the first %x3B (";") character. - cookieAv = collectASequenceOfCodePointsFast( - ';', - unparsedAttributes, - { position: 0 } - ); - unparsedAttributes = unparsedAttributes.slice(cookieAv.length); - } else { - // Otherwise: - - // 1. Consume the remainder of the unparsed-attributes. - cookieAv = unparsedAttributes; - unparsedAttributes = ''; - } - - // Let the cookie-av string be the characters consumed in this step. - - let attributeName = ''; - let attributeValue = ''; - - // 4. If the cookie-av string contains a %x3D ("=") character: - if (cookieAv.includes('=')) { - // 1. The (possibly empty) attribute-name string consists of the - // characters up to, but not including, the first %x3D ("=") - // character, and the (possibly empty) attribute-value string - // consists of the characters after the first %x3D ("=") - // character. - const position = { position: 0 }; - - attributeName = collectASequenceOfCodePointsFast( - '=', - cookieAv, - position - ); - attributeValue = cookieAv.slice(position.position + 1); - } else { - // Otherwise: - - // 1. The attribute-name string consists of the entire cookie-av - // string, and the attribute-value string is empty. - attributeName = cookieAv; - } - - // 5. Remove any leading or trailing WSP characters from the attribute- - // name string and the attribute-value string. - attributeName = attributeName.trim(); - attributeValue = attributeValue.trim(); - - // 6. If the attribute-value is longer than 1024 octets, ignore the - // cookie-av string and return to Step 1 of this algorithm. - if (attributeValue.length > maxAttributeValueSize) { - return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList) - } - - // 7. Process the attribute-name and attribute-value according to the - // requirements in the following subsections. (Notice that - // attributes with unrecognized attribute-names are ignored.) - const attributeNameLowercase = attributeName.toLowerCase(); - - // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.1 - // If the attribute-name case-insensitively matches the string - // "Expires", the user agent MUST process the cookie-av as follows. - if (attributeNameLowercase === 'expires') { - // 1. Let the expiry-time be the result of parsing the attribute-value - // as cookie-date (see Section 5.1.1). - const expiryTime = new Date(attributeValue); - - // 2. If the attribute-value failed to parse as a cookie date, ignore - // the cookie-av. - - cookieAttributeList.expires = expiryTime; - } else if (attributeNameLowercase === 'max-age') { - // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.2 - // If the attribute-name case-insensitively matches the string "Max- - // Age", the user agent MUST process the cookie-av as follows. - - // 1. If the first character of the attribute-value is not a DIGIT or a - // "-" character, ignore the cookie-av. - const charCode = attributeValue.charCodeAt(0); - - if ((charCode < 48 || charCode > 57) && attributeValue[0] !== '-') { - return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList) - } - - // 2. If the remainder of attribute-value contains a non-DIGIT - // character, ignore the cookie-av. - if (!/^\d+$/.test(attributeValue)) { - return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList) - } - - // 3. Let delta-seconds be the attribute-value converted to an integer. - const deltaSeconds = Number(attributeValue); - - // 4. Let cookie-age-limit be the maximum age of the cookie (which - // SHOULD be 400 days or less, see Section 4.1.2.2). - - // 5. Set delta-seconds to the smaller of its present value and cookie- - // age-limit. - // deltaSeconds = Math.min(deltaSeconds * 1000, maxExpiresMs) - - // 6. If delta-seconds is less than or equal to zero (0), let expiry- - // time be the earliest representable date and time. Otherwise, let - // the expiry-time be the current date and time plus delta-seconds - // seconds. - // const expiryTime = deltaSeconds <= 0 ? Date.now() : Date.now() + deltaSeconds - - // 7. Append an attribute to the cookie-attribute-list with an - // attribute-name of Max-Age and an attribute-value of expiry-time. - cookieAttributeList.maxAge = deltaSeconds; - } else if (attributeNameLowercase === 'domain') { - // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.3 - // If the attribute-name case-insensitively matches the string "Domain", - // the user agent MUST process the cookie-av as follows. - - // 1. Let cookie-domain be the attribute-value. - let cookieDomain = attributeValue; - - // 2. If cookie-domain starts with %x2E ("."), let cookie-domain be - // cookie-domain without its leading %x2E ("."). - if (cookieDomain[0] === '.') { - cookieDomain = cookieDomain.slice(1); - } - - // 3. Convert the cookie-domain to lower case. - cookieDomain = cookieDomain.toLowerCase(); - - // 4. Append an attribute to the cookie-attribute-list with an - // attribute-name of Domain and an attribute-value of cookie-domain. - cookieAttributeList.domain = cookieDomain; - } else if (attributeNameLowercase === 'path') { - // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.4 - // If the attribute-name case-insensitively matches the string "Path", - // the user agent MUST process the cookie-av as follows. - - // 1. If the attribute-value is empty or if the first character of the - // attribute-value is not %x2F ("/"): - let cookiePath = ''; - if (attributeValue.length === 0 || attributeValue[0] !== '/') { - // 1. Let cookie-path be the default-path. - cookiePath = '/'; - } else { - // Otherwise: - - // 1. Let cookie-path be the attribute-value. - cookiePath = attributeValue; - } - - // 2. Append an attribute to the cookie-attribute-list with an - // attribute-name of Path and an attribute-value of cookie-path. - cookieAttributeList.path = cookiePath; - } else if (attributeNameLowercase === 'secure') { - // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.5 - // If the attribute-name case-insensitively matches the string "Secure", - // the user agent MUST append an attribute to the cookie-attribute-list - // with an attribute-name of Secure and an empty attribute-value. - - cookieAttributeList.secure = true; - } else if (attributeNameLowercase === 'httponly') { - // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.6 - // If the attribute-name case-insensitively matches the string - // "HttpOnly", the user agent MUST append an attribute to the cookie- - // attribute-list with an attribute-name of HttpOnly and an empty - // attribute-value. - - cookieAttributeList.httpOnly = true; - } else if (attributeNameLowercase === 'samesite') { - // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.7 - // If the attribute-name case-insensitively matches the string - // "SameSite", the user agent MUST process the cookie-av as follows: - - // 1. Let enforcement be "Default". - let enforcement = 'Default'; - - const attributeValueLowercase = attributeValue.toLowerCase(); - // 2. If cookie-av's attribute-value is a case-insensitive match for - // "None", set enforcement to "None". - if (attributeValueLowercase.includes('none')) { - enforcement = 'None'; - } - - // 3. If cookie-av's attribute-value is a case-insensitive match for - // "Strict", set enforcement to "Strict". - if (attributeValueLowercase.includes('strict')) { - enforcement = 'Strict'; - } - - // 4. If cookie-av's attribute-value is a case-insensitive match for - // "Lax", set enforcement to "Lax". - if (attributeValueLowercase.includes('lax')) { - enforcement = 'Lax'; - } - - // 5. Append an attribute to the cookie-attribute-list with an - // attribute-name of "SameSite" and an attribute-value of - // enforcement. - cookieAttributeList.sameSite = enforcement; - } else { - cookieAttributeList.unparsed ??= []; - - cookieAttributeList.unparsed.push(`${attributeName}=${attributeValue}`); - } - - // 8. Return to Step 1 of this algorithm. - return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList) - } - - parse = { - parseSetCookie, - parseUnparsedAttributes - }; - return parse; -} - -var cookies; -var hasRequiredCookies; - -function requireCookies () { - if (hasRequiredCookies) return cookies; - hasRequiredCookies = 1; - - const { parseSetCookie } = requireParse(); - const { stringify } = requireUtil$2(); - const { webidl } = requireWebidl(); - const { Headers } = requireHeaders(); - - /** - * @typedef {Object} Cookie - * @property {string} name - * @property {string} value - * @property {Date|number|undefined} expires - * @property {number|undefined} maxAge - * @property {string|undefined} domain - * @property {string|undefined} path - * @property {boolean|undefined} secure - * @property {boolean|undefined} httpOnly - * @property {'Strict'|'Lax'|'None'} sameSite - * @property {string[]} unparsed - */ - - /** - * @param {Headers} headers - * @returns {Record} - */ - function getCookies (headers) { - webidl.argumentLengthCheck(arguments, 1, 'getCookies'); - - webidl.brandCheck(headers, Headers, { strict: false }); - - const cookie = headers.get('cookie'); - const out = {}; - - if (!cookie) { - return out - } - - for (const piece of cookie.split(';')) { - const [name, ...value] = piece.split('='); - - out[name.trim()] = value.join('='); - } - - return out - } - - /** - * @param {Headers} headers - * @param {string} name - * @param {{ path?: string, domain?: string }|undefined} attributes - * @returns {void} - */ - function deleteCookie (headers, name, attributes) { - webidl.brandCheck(headers, Headers, { strict: false }); - - const prefix = 'deleteCookie'; - webidl.argumentLengthCheck(arguments, 2, prefix); - - name = webidl.converters.DOMString(name, prefix, 'name'); - attributes = webidl.converters.DeleteCookieAttributes(attributes); - - // Matches behavior of - // https://github.com/denoland/deno_std/blob/63827b16330b82489a04614027c33b7904e08be5/http/cookie.ts#L278 - setCookie(headers, { - name, - value: '', - expires: new Date(0), - ...attributes - }); - } - - /** - * @param {Headers} headers - * @returns {Cookie[]} - */ - function getSetCookies (headers) { - webidl.argumentLengthCheck(arguments, 1, 'getSetCookies'); - - webidl.brandCheck(headers, Headers, { strict: false }); - - const cookies = headers.getSetCookie(); - - if (!cookies) { - return [] - } - - return cookies.map((pair) => parseSetCookie(pair)) - } - - /** - * @param {Headers} headers - * @param {Cookie} cookie - * @returns {void} - */ - function setCookie (headers, cookie) { - webidl.argumentLengthCheck(arguments, 2, 'setCookie'); - - webidl.brandCheck(headers, Headers, { strict: false }); - - cookie = webidl.converters.Cookie(cookie); - - const str = stringify(cookie); - - if (str) { - headers.append('Set-Cookie', str); - } - } - - webidl.converters.DeleteCookieAttributes = webidl.dictionaryConverter([ - { - converter: webidl.nullableConverter(webidl.converters.DOMString), - key: 'path', - defaultValue: () => null - }, - { - converter: webidl.nullableConverter(webidl.converters.DOMString), - key: 'domain', - defaultValue: () => null - } - ]); - - webidl.converters.Cookie = webidl.dictionaryConverter([ - { - converter: webidl.converters.DOMString, - key: 'name' - }, - { - converter: webidl.converters.DOMString, - key: 'value' - }, - { - converter: webidl.nullableConverter((value) => { - if (typeof value === 'number') { - return webidl.converters['unsigned long long'](value) - } - - return new Date(value) - }), - key: 'expires', - defaultValue: () => null - }, - { - converter: webidl.nullableConverter(webidl.converters['long long']), - key: 'maxAge', - defaultValue: () => null - }, - { - converter: webidl.nullableConverter(webidl.converters.DOMString), - key: 'domain', - defaultValue: () => null - }, - { - converter: webidl.nullableConverter(webidl.converters.DOMString), - key: 'path', - defaultValue: () => null - }, - { - converter: webidl.nullableConverter(webidl.converters.boolean), - key: 'secure', - defaultValue: () => null - }, - { - converter: webidl.nullableConverter(webidl.converters.boolean), - key: 'httpOnly', - defaultValue: () => null - }, - { - converter: webidl.converters.USVString, - key: 'sameSite', - allowedValues: ['Strict', 'Lax', 'None'] - }, - { - converter: webidl.sequenceConverter(webidl.converters.DOMString), - key: 'unparsed', - defaultValue: () => new Array(0) - } - ]); - - cookies = { - getCookies, - deleteCookie, - getSetCookies, - setCookie - }; - return cookies; -} - -var events; -var hasRequiredEvents; - -function requireEvents () { - if (hasRequiredEvents) return events; - hasRequiredEvents = 1; - - const { webidl } = requireWebidl(); - const { kEnumerableProperty } = requireUtil$7(); - const { kConstruct } = requireSymbols$4(); - const { MessagePort } = require$$3; - - /** - * @see https://html.spec.whatwg.org/multipage/comms.html#messageevent - */ - class MessageEvent extends Event { - #eventInit - - constructor (type, eventInitDict = {}) { - if (type === kConstruct) { - super(arguments[1], arguments[2]); - return - } - - const prefix = 'MessageEvent constructor'; - webidl.argumentLengthCheck(arguments, 1, prefix); - - type = webidl.converters.DOMString(type, prefix, 'type'); - eventInitDict = webidl.converters.MessageEventInit(eventInitDict, prefix, 'eventInitDict'); - - super(type, eventInitDict); - - this.#eventInit = eventInitDict; - } - - get data () { - webidl.brandCheck(this, MessageEvent); - - return this.#eventInit.data - } - - get origin () { - webidl.brandCheck(this, MessageEvent); - - return this.#eventInit.origin - } - - get lastEventId () { - webidl.brandCheck(this, MessageEvent); - - return this.#eventInit.lastEventId - } - - get source () { - webidl.brandCheck(this, MessageEvent); - - return this.#eventInit.source - } - - get ports () { - webidl.brandCheck(this, MessageEvent); - - if (!Object.isFrozen(this.#eventInit.ports)) { - Object.freeze(this.#eventInit.ports); - } - - return this.#eventInit.ports - } - - initMessageEvent ( - type, - bubbles = false, - cancelable = false, - data = null, - origin = '', - lastEventId = '', - source = null, - ports = [] - ) { - webidl.brandCheck(this, MessageEvent); - - webidl.argumentLengthCheck(arguments, 1, 'MessageEvent.initMessageEvent'); - - return new MessageEvent(type, { - bubbles, cancelable, data, origin, lastEventId, source, ports - }) - } - - static createFastMessageEvent (type, init) { - const messageEvent = new MessageEvent(kConstruct, type, init); - messageEvent.#eventInit = init; - messageEvent.#eventInit.data ??= null; - messageEvent.#eventInit.origin ??= ''; - messageEvent.#eventInit.lastEventId ??= ''; - messageEvent.#eventInit.source ??= null; - messageEvent.#eventInit.ports ??= []; - return messageEvent - } - } - - const { createFastMessageEvent } = MessageEvent; - delete MessageEvent.createFastMessageEvent; - - /** - * @see https://websockets.spec.whatwg.org/#the-closeevent-interface - */ - class CloseEvent extends Event { - #eventInit - - constructor (type, eventInitDict = {}) { - const prefix = 'CloseEvent constructor'; - webidl.argumentLengthCheck(arguments, 1, prefix); - - type = webidl.converters.DOMString(type, prefix, 'type'); - eventInitDict = webidl.converters.CloseEventInit(eventInitDict); - - super(type, eventInitDict); - - this.#eventInit = eventInitDict; - } - - get wasClean () { - webidl.brandCheck(this, CloseEvent); - - return this.#eventInit.wasClean - } - - get code () { - webidl.brandCheck(this, CloseEvent); - - return this.#eventInit.code - } - - get reason () { - webidl.brandCheck(this, CloseEvent); - - return this.#eventInit.reason - } - } - - // https://html.spec.whatwg.org/multipage/webappapis.html#the-errorevent-interface - class ErrorEvent extends Event { - #eventInit - - constructor (type, eventInitDict) { - const prefix = 'ErrorEvent constructor'; - webidl.argumentLengthCheck(arguments, 1, prefix); - - super(type, eventInitDict); - - type = webidl.converters.DOMString(type, prefix, 'type'); - eventInitDict = webidl.converters.ErrorEventInit(eventInitDict ?? {}); - - this.#eventInit = eventInitDict; - } - - get message () { - webidl.brandCheck(this, ErrorEvent); - - return this.#eventInit.message - } - - get filename () { - webidl.brandCheck(this, ErrorEvent); - - return this.#eventInit.filename - } - - get lineno () { - webidl.brandCheck(this, ErrorEvent); - - return this.#eventInit.lineno - } - - get colno () { - webidl.brandCheck(this, ErrorEvent); - - return this.#eventInit.colno - } - - get error () { - webidl.brandCheck(this, ErrorEvent); - - return this.#eventInit.error - } - } - - Object.defineProperties(MessageEvent.prototype, { - [Symbol.toStringTag]: { - value: 'MessageEvent', - configurable: true - }, - data: kEnumerableProperty, - origin: kEnumerableProperty, - lastEventId: kEnumerableProperty, - source: kEnumerableProperty, - ports: kEnumerableProperty, - initMessageEvent: kEnumerableProperty - }); - - Object.defineProperties(CloseEvent.prototype, { - [Symbol.toStringTag]: { - value: 'CloseEvent', - configurable: true - }, - reason: kEnumerableProperty, - code: kEnumerableProperty, - wasClean: kEnumerableProperty - }); - - Object.defineProperties(ErrorEvent.prototype, { - [Symbol.toStringTag]: { - value: 'ErrorEvent', - configurable: true - }, - message: kEnumerableProperty, - filename: kEnumerableProperty, - lineno: kEnumerableProperty, - colno: kEnumerableProperty, - error: kEnumerableProperty - }); - - webidl.converters.MessagePort = webidl.interfaceConverter(MessagePort); - - webidl.converters['sequence'] = webidl.sequenceConverter( - webidl.converters.MessagePort - ); - - const eventInit = [ - { - key: 'bubbles', - converter: webidl.converters.boolean, - defaultValue: () => false - }, - { - key: 'cancelable', - converter: webidl.converters.boolean, - defaultValue: () => false - }, - { - key: 'composed', - converter: webidl.converters.boolean, - defaultValue: () => false - } - ]; - - webidl.converters.MessageEventInit = webidl.dictionaryConverter([ - ...eventInit, - { - key: 'data', - converter: webidl.converters.any, - defaultValue: () => null - }, - { - key: 'origin', - converter: webidl.converters.USVString, - defaultValue: () => '' - }, - { - key: 'lastEventId', - converter: webidl.converters.DOMString, - defaultValue: () => '' - }, - { - key: 'source', - // Node doesn't implement WindowProxy or ServiceWorker, so the only - // valid value for source is a MessagePort. - converter: webidl.nullableConverter(webidl.converters.MessagePort), - defaultValue: () => null - }, - { - key: 'ports', - converter: webidl.converters['sequence'], - defaultValue: () => new Array(0) - } - ]); - - webidl.converters.CloseEventInit = webidl.dictionaryConverter([ - ...eventInit, - { - key: 'wasClean', - converter: webidl.converters.boolean, - defaultValue: () => false - }, - { - key: 'code', - converter: webidl.converters['unsigned short'], - defaultValue: () => 0 - }, - { - key: 'reason', - converter: webidl.converters.USVString, - defaultValue: () => '' - } - ]); - - webidl.converters.ErrorEventInit = webidl.dictionaryConverter([ - ...eventInit, - { - key: 'message', - converter: webidl.converters.DOMString, - defaultValue: () => '' - }, - { - key: 'filename', - converter: webidl.converters.USVString, - defaultValue: () => '' - }, - { - key: 'lineno', - converter: webidl.converters['unsigned long'], - defaultValue: () => 0 - }, - { - key: 'colno', - converter: webidl.converters['unsigned long'], - defaultValue: () => 0 - }, - { - key: 'error', - converter: webidl.converters.any - } - ]); - - events = { - MessageEvent, - CloseEvent, - ErrorEvent, - createFastMessageEvent - }; - return events; -} - -var constants; -var hasRequiredConstants; - -function requireConstants () { - if (hasRequiredConstants) return constants; - hasRequiredConstants = 1; - - // This is a Globally Unique Identifier unique used - // to validate that the endpoint accepts websocket - // connections. - // See https://www.rfc-editor.org/rfc/rfc6455.html#section-1.3 - const uid = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'; - - /** @type {PropertyDescriptor} */ - const staticPropertyDescriptors = { - enumerable: true, - writable: false, - configurable: false - }; - - const states = { - CONNECTING: 0, - OPEN: 1, - CLOSING: 2, - CLOSED: 3 - }; - - const sentCloseFrameState = { - NOT_SENT: 0, - PROCESSING: 1, - SENT: 2 - }; - - const opcodes = { - CONTINUATION: 0x0, - TEXT: 0x1, - BINARY: 0x2, - CLOSE: 0x8, - PING: 0x9, - PONG: 0xA - }; - - const maxUnsigned16Bit = 2 ** 16 - 1; // 65535 - - const parserStates = { - INFO: 0, - PAYLOADLENGTH_16: 2, - PAYLOADLENGTH_64: 3, - READ_DATA: 4 - }; - - const emptyBuffer = Buffer.allocUnsafe(0); - - const sendHints = { - string: 1, - typedArray: 2, - arrayBuffer: 3, - blob: 4 - }; - - constants = { - uid, - sentCloseFrameState, - staticPropertyDescriptors, - states, - opcodes, - maxUnsigned16Bit, - parserStates, - emptyBuffer, - sendHints - }; - return constants; -} - -var symbols; -var hasRequiredSymbols; - -function requireSymbols () { - if (hasRequiredSymbols) return symbols; - hasRequiredSymbols = 1; - - symbols = { - kWebSocketURL: Symbol('url'), - kReadyState: Symbol('ready state'), - kController: Symbol('controller'), - kResponse: Symbol('response'), - kBinaryType: Symbol('binary type'), - kSentClose: Symbol('sent close'), - kReceivedClose: Symbol('received close'), - kByteParser: Symbol('byte parser') - }; - return symbols; -} - -var util$1; -var hasRequiredUtil$1; - -function requireUtil$1 () { - if (hasRequiredUtil$1) return util$1; - hasRequiredUtil$1 = 1; - - const { kReadyState, kController, kResponse, kBinaryType, kWebSocketURL } = requireSymbols(); - const { states, opcodes } = requireConstants(); - const { ErrorEvent, createFastMessageEvent } = requireEvents(); - const { isUtf8 } = require$$0$3; - const { collectASequenceOfCodePointsFast, removeHTTPWhitespace } = requireDataUrl(); - - /* globals Blob */ - - /** - * @param {import('./websocket').WebSocket} ws - * @returns {boolean} - */ - function isConnecting (ws) { - // If the WebSocket connection is not yet established, and the connection - // is not yet closed, then the WebSocket connection is in the CONNECTING state. - return ws[kReadyState] === states.CONNECTING - } - - /** - * @param {import('./websocket').WebSocket} ws - * @returns {boolean} - */ - function isEstablished (ws) { - // If the server's response is validated as provided for above, it is - // said that _The WebSocket Connection is Established_ and that the - // WebSocket Connection is in the OPEN state. - return ws[kReadyState] === states.OPEN - } - - /** - * @param {import('./websocket').WebSocket} ws - * @returns {boolean} - */ - function isClosing (ws) { - // Upon either sending or receiving a Close control frame, it is said - // that _The WebSocket Closing Handshake is Started_ and that the - // WebSocket connection is in the CLOSING state. - return ws[kReadyState] === states.CLOSING - } - - /** - * @param {import('./websocket').WebSocket} ws - * @returns {boolean} - */ - function isClosed (ws) { - return ws[kReadyState] === states.CLOSED - } - - /** - * @see https://dom.spec.whatwg.org/#concept-event-fire - * @param {string} e - * @param {EventTarget} target - * @param {(...args: ConstructorParameters) => Event} eventFactory - * @param {EventInit | undefined} eventInitDict - */ - function fireEvent (e, target, eventFactory = (type, init) => new Event(type, init), eventInitDict = {}) { - // 1. If eventConstructor is not given, then let eventConstructor be Event. - - // 2. Let event be the result of creating an event given eventConstructor, - // in the relevant realm of target. - // 3. Initialize event’s type attribute to e. - const event = eventFactory(e, eventInitDict); - - // 4. Initialize any other IDL attributes of event as described in the - // invocation of this algorithm. - - // 5. Return the result of dispatching event at target, with legacy target - // override flag set if set. - target.dispatchEvent(event); - } - - /** - * @see https://websockets.spec.whatwg.org/#feedback-from-the-protocol - * @param {import('./websocket').WebSocket} ws - * @param {number} type Opcode - * @param {Buffer} data application data - */ - function websocketMessageReceived (ws, type, data) { - // 1. If ready state is not OPEN (1), then return. - if (ws[kReadyState] !== states.OPEN) { - return - } - - // 2. Let dataForEvent be determined by switching on type and binary type: - let dataForEvent; - - if (type === opcodes.TEXT) { - // -> type indicates that the data is Text - // a new DOMString containing data - try { - dataForEvent = utf8Decode(data); - } catch { - failWebsocketConnection(ws, 'Received invalid UTF-8 in text frame.'); - return - } - } else if (type === opcodes.BINARY) { - if (ws[kBinaryType] === 'blob') { - // -> type indicates that the data is Binary and binary type is "blob" - // a new Blob object, created in the relevant Realm of the WebSocket - // object, that represents data as its raw data - dataForEvent = new Blob([data]); - } else { - // -> type indicates that the data is Binary and binary type is "arraybuffer" - // a new ArrayBuffer object, created in the relevant Realm of the - // WebSocket object, whose contents are data - dataForEvent = toArrayBuffer(data); - } - } - - // 3. Fire an event named message at the WebSocket object, using MessageEvent, - // with the origin attribute initialized to the serialization of the WebSocket - // object’s url's origin, and the data attribute initialized to dataForEvent. - fireEvent('message', ws, createFastMessageEvent, { - origin: ws[kWebSocketURL].origin, - data: dataForEvent - }); - } - - function toArrayBuffer (buffer) { - if (buffer.byteLength === buffer.buffer.byteLength) { - return buffer.buffer - } - return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength) - } - - /** - * @see https://datatracker.ietf.org/doc/html/rfc6455 - * @see https://datatracker.ietf.org/doc/html/rfc2616 - * @see https://bugs.chromium.org/p/chromium/issues/detail?id=398407 - * @param {string} protocol - */ - function isValidSubprotocol (protocol) { - // If present, this value indicates one - // or more comma-separated subprotocol the client wishes to speak, - // ordered by preference. The elements that comprise this value - // MUST be non-empty strings with characters in the range U+0021 to - // U+007E not including separator characters as defined in - // [RFC2616] and MUST all be unique strings. - if (protocol.length === 0) { - return false - } - - for (let i = 0; i < protocol.length; ++i) { - const code = protocol.charCodeAt(i); - - if ( - code < 0x21 || // CTL, contains SP (0x20) and HT (0x09) - code > 0x7E || - code === 0x22 || // " - code === 0x28 || // ( - code === 0x29 || // ) - code === 0x2C || // , - code === 0x2F || // / - code === 0x3A || // : - code === 0x3B || // ; - code === 0x3C || // < - code === 0x3D || // = - code === 0x3E || // > - code === 0x3F || // ? - code === 0x40 || // @ - code === 0x5B || // [ - code === 0x5C || // \ - code === 0x5D || // ] - code === 0x7B || // { - code === 0x7D // } - ) { - return false - } - } - - return true - } - - /** - * @see https://datatracker.ietf.org/doc/html/rfc6455#section-7-4 - * @param {number} code - */ - function isValidStatusCode (code) { - if (code >= 1000 && code < 1015) { - return ( - code !== 1004 && // reserved - code !== 1005 && // "MUST NOT be set as a status code" - code !== 1006 // "MUST NOT be set as a status code" - ) - } - - return code >= 3000 && code <= 4999 - } - - /** - * @param {import('./websocket').WebSocket} ws - * @param {string|undefined} reason - */ - function failWebsocketConnection (ws, reason) { - const { [kController]: controller, [kResponse]: response } = ws; - - controller.abort(); - - if (response?.socket && !response.socket.destroyed) { - response.socket.destroy(); - } - - if (reason) { - // TODO: process.nextTick - fireEvent('error', ws, (type, init) => new ErrorEvent(type, init), { - error: new Error(reason), - message: reason - }); - } - } - - /** - * @see https://datatracker.ietf.org/doc/html/rfc6455#section-5.5 - * @param {number} opcode - */ - function isControlFrame (opcode) { - return ( - opcode === opcodes.CLOSE || - opcode === opcodes.PING || - opcode === opcodes.PONG - ) - } - - function isContinuationFrame (opcode) { - return opcode === opcodes.CONTINUATION - } - - function isTextBinaryFrame (opcode) { - return opcode === opcodes.TEXT || opcode === opcodes.BINARY - } - - function isValidOpcode (opcode) { - return isTextBinaryFrame(opcode) || isContinuationFrame(opcode) || isControlFrame(opcode) - } - - /** - * Parses a Sec-WebSocket-Extensions header value. - * @param {string} extensions - * @returns {Map} - */ - // TODO(@Uzlopak, @KhafraDev): make compliant https://datatracker.ietf.org/doc/html/rfc6455#section-9.1 - function parseExtensions (extensions) { - const position = { position: 0 }; - const extensionList = new Map(); - - while (position.position < extensions.length) { - const pair = collectASequenceOfCodePointsFast(';', extensions, position); - const [name, value = ''] = pair.split('='); - - extensionList.set( - removeHTTPWhitespace(name, true, false), - removeHTTPWhitespace(value, false, true) - ); - - position.position++; - } - - return extensionList - } - - /** - * @see https://www.rfc-editor.org/rfc/rfc7692#section-7.1.2.2 - * @description "client-max-window-bits = 1*DIGIT" - * @param {string} value - */ - function isValidClientWindowBits (value) { - for (let i = 0; i < value.length; i++) { - const byte = value.charCodeAt(i); - - if (byte < 0x30 || byte > 0x39) { - return false - } - } - - return true - } - - // https://nodejs.org/api/intl.html#detecting-internationalization-support - const hasIntl = typeof process.versions.icu === 'string'; - const fatalDecoder = hasIntl ? new TextDecoder('utf-8', { fatal: true }) : undefined; - - /** - * Converts a Buffer to utf-8, even on platforms without icu. - * @param {Buffer} buffer - */ - const utf8Decode = hasIntl - ? fatalDecoder.decode.bind(fatalDecoder) - : function (buffer) { - if (isUtf8(buffer)) { - return buffer.toString('utf-8') - } - throw new TypeError('Invalid utf-8 received.') - }; - - util$1 = { - isConnecting, - isEstablished, - isClosing, - isClosed, - fireEvent, - isValidSubprotocol, - isValidStatusCode, - failWebsocketConnection, - websocketMessageReceived, - utf8Decode, - isControlFrame, - isContinuationFrame, - isTextBinaryFrame, - isValidOpcode, - parseExtensions, - isValidClientWindowBits - }; - return util$1; -} - -var frame; -var hasRequiredFrame; - -function requireFrame () { - if (hasRequiredFrame) return frame; - hasRequiredFrame = 1; - - const { maxUnsigned16Bit } = requireConstants(); - - const BUFFER_SIZE = 16386; - - /** @type {import('crypto')} */ - let crypto; - let buffer = null; - let bufIdx = BUFFER_SIZE; - - try { - crypto = require('node:crypto'); - /* c8 ignore next 3 */ - } catch { - crypto = { - // not full compatibility, but minimum. - randomFillSync: function randomFillSync (buffer, _offset, _size) { - for (let i = 0; i < buffer.length; ++i) { - buffer[i] = Math.random() * 255 | 0; - } - return buffer - } - }; - } - - function generateMask () { - if (bufIdx === BUFFER_SIZE) { - bufIdx = 0; - crypto.randomFillSync((buffer ??= Buffer.allocUnsafe(BUFFER_SIZE)), 0, BUFFER_SIZE); - } - return [buffer[bufIdx++], buffer[bufIdx++], buffer[bufIdx++], buffer[bufIdx++]] - } - - class WebsocketFrameSend { - /** - * @param {Buffer|undefined} data - */ - constructor (data) { - this.frameData = data; - } - - createFrame (opcode) { - const frameData = this.frameData; - const maskKey = generateMask(); - const bodyLength = frameData?.byteLength ?? 0; - - /** @type {number} */ - let payloadLength = bodyLength; // 0-125 - let offset = 6; - - if (bodyLength > maxUnsigned16Bit) { - offset += 8; // payload length is next 8 bytes - payloadLength = 127; - } else if (bodyLength > 125) { - offset += 2; // payload length is next 2 bytes - payloadLength = 126; - } - - const buffer = Buffer.allocUnsafe(bodyLength + offset); - - // Clear first 2 bytes, everything else is overwritten - buffer[0] = buffer[1] = 0; - buffer[0] |= 0x80; // FIN - buffer[0] = (buffer[0] & 0xF0) + opcode; // opcode - - /*! ws. MIT License. Einar Otto Stangvik */ - buffer[offset - 4] = maskKey[0]; - buffer[offset - 3] = maskKey[1]; - buffer[offset - 2] = maskKey[2]; - buffer[offset - 1] = maskKey[3]; - - buffer[1] = payloadLength; - - if (payloadLength === 126) { - buffer.writeUInt16BE(bodyLength, 2); - } else if (payloadLength === 127) { - // Clear extended payload length - buffer[2] = buffer[3] = 0; - buffer.writeUIntBE(bodyLength, 4, 6); - } - - buffer[1] |= 0x80; // MASK - - // mask body - for (let i = 0; i < bodyLength; ++i) { - buffer[offset + i] = frameData[i] ^ maskKey[i & 3]; - } - - return buffer - } - } - - frame = { - WebsocketFrameSend - }; - return frame; -} - -var connection; -var hasRequiredConnection; - -function requireConnection () { - if (hasRequiredConnection) return connection; - hasRequiredConnection = 1; - - const { uid, states, sentCloseFrameState, emptyBuffer, opcodes } = requireConstants(); - const { - kReadyState, - kSentClose, - kByteParser, - kReceivedClose, - kResponse - } = requireSymbols(); - const { fireEvent, failWebsocketConnection, isClosing, isClosed, isEstablished, parseExtensions } = requireUtil$1(); - const { channels } = requireDiagnostics(); - const { CloseEvent } = requireEvents(); - const { makeRequest } = requireRequest(); - const { fetching } = requireFetch(); - const { Headers, getHeadersList } = requireHeaders(); - const { getDecodeSplit } = requireUtil$6(); - const { WebsocketFrameSend } = requireFrame(); - - /** @type {import('crypto')} */ - let crypto; - try { - crypto = require('node:crypto'); - /* c8 ignore next 3 */ - } catch { - - } - - /** - * @see https://websockets.spec.whatwg.org/#concept-websocket-establish - * @param {URL} url - * @param {string|string[]} protocols - * @param {import('./websocket').WebSocket} ws - * @param {(response: any, extensions: string[] | undefined) => void} onEstablish - * @param {Partial} options - */ - function establishWebSocketConnection (url, protocols, client, ws, onEstablish, options) { - // 1. Let requestURL be a copy of url, with its scheme set to "http", if url’s - // scheme is "ws", and to "https" otherwise. - const requestURL = url; - - requestURL.protocol = url.protocol === 'ws:' ? 'http:' : 'https:'; - - // 2. Let request be a new request, whose URL is requestURL, client is client, - // service-workers mode is "none", referrer is "no-referrer", mode is - // "websocket", credentials mode is "include", cache mode is "no-store" , - // and redirect mode is "error". - const request = makeRequest({ - urlList: [requestURL], - client, - serviceWorkers: 'none', - referrer: 'no-referrer', - mode: 'websocket', - credentials: 'include', - cache: 'no-store', - redirect: 'error' - }); - - // Note: undici extension, allow setting custom headers. - if (options.headers) { - const headersList = getHeadersList(new Headers(options.headers)); - - request.headersList = headersList; - } - - // 3. Append (`Upgrade`, `websocket`) to request’s header list. - // 4. Append (`Connection`, `Upgrade`) to request’s header list. - // Note: both of these are handled by undici currently. - // https://github.com/nodejs/undici/blob/68c269c4144c446f3f1220951338daef4a6b5ec4/lib/client.js#L1397 - - // 5. Let keyValue be a nonce consisting of a randomly selected - // 16-byte value that has been forgiving-base64-encoded and - // isomorphic encoded. - const keyValue = crypto.randomBytes(16).toString('base64'); - - // 6. Append (`Sec-WebSocket-Key`, keyValue) to request’s - // header list. - request.headersList.append('sec-websocket-key', keyValue); - - // 7. Append (`Sec-WebSocket-Version`, `13`) to request’s - // header list. - request.headersList.append('sec-websocket-version', '13'); - - // 8. For each protocol in protocols, combine - // (`Sec-WebSocket-Protocol`, protocol) in request’s header - // list. - for (const protocol of protocols) { - request.headersList.append('sec-websocket-protocol', protocol); - } - - // 9. Let permessageDeflate be a user-agent defined - // "permessage-deflate" extension header value. - // https://github.com/mozilla/gecko-dev/blob/ce78234f5e653a5d3916813ff990f053510227bc/netwerk/protocol/websocket/WebSocketChannel.cpp#L2673 - const permessageDeflate = 'permessage-deflate; client_max_window_bits'; - - // 10. Append (`Sec-WebSocket-Extensions`, permessageDeflate) to - // request’s header list. - request.headersList.append('sec-websocket-extensions', permessageDeflate); - - // 11. Fetch request with useParallelQueue set to true, and - // processResponse given response being these steps: - const controller = fetching({ - request, - useParallelQueue: true, - dispatcher: options.dispatcher, - processResponse (response) { - // 1. If response is a network error or its status is not 101, - // fail the WebSocket connection. - if (response.type === 'error' || response.status !== 101) { - failWebsocketConnection(ws, 'Received network error or non-101 status code.'); - return - } - - // 2. If protocols is not the empty list and extracting header - // list values given `Sec-WebSocket-Protocol` and response’s - // header list results in null, failure, or the empty byte - // sequence, then fail the WebSocket connection. - if (protocols.length !== 0 && !response.headersList.get('Sec-WebSocket-Protocol')) { - failWebsocketConnection(ws, 'Server did not respond with sent protocols.'); - return - } - - // 3. Follow the requirements stated step 2 to step 6, inclusive, - // of the last set of steps in section 4.1 of The WebSocket - // Protocol to validate response. This either results in fail - // the WebSocket connection or the WebSocket connection is - // established. - - // 2. If the response lacks an |Upgrade| header field or the |Upgrade| - // header field contains a value that is not an ASCII case- - // insensitive match for the value "websocket", the client MUST - // _Fail the WebSocket Connection_. - if (response.headersList.get('Upgrade')?.toLowerCase() !== 'websocket') { - failWebsocketConnection(ws, 'Server did not set Upgrade header to "websocket".'); - return - } - - // 3. If the response lacks a |Connection| header field or the - // |Connection| header field doesn't contain a token that is an - // ASCII case-insensitive match for the value "Upgrade", the client - // MUST _Fail the WebSocket Connection_. - if (response.headersList.get('Connection')?.toLowerCase() !== 'upgrade') { - failWebsocketConnection(ws, 'Server did not set Connection header to "upgrade".'); - return - } - - // 4. If the response lacks a |Sec-WebSocket-Accept| header field or - // the |Sec-WebSocket-Accept| contains a value other than the - // base64-encoded SHA-1 of the concatenation of the |Sec-WebSocket- - // Key| (as a string, not base64-decoded) with the string "258EAFA5- - // E914-47DA-95CA-C5AB0DC85B11" but ignoring any leading and - // trailing whitespace, the client MUST _Fail the WebSocket - // Connection_. - const secWSAccept = response.headersList.get('Sec-WebSocket-Accept'); - const digest = crypto.createHash('sha1').update(keyValue + uid).digest('base64'); - if (secWSAccept !== digest) { - failWebsocketConnection(ws, 'Incorrect hash received in Sec-WebSocket-Accept header.'); - return - } - - // 5. If the response includes a |Sec-WebSocket-Extensions| header - // field and this header field indicates the use of an extension - // that was not present in the client's handshake (the server has - // indicated an extension not requested by the client), the client - // MUST _Fail the WebSocket Connection_. (The parsing of this - // header field to determine which extensions are requested is - // discussed in Section 9.1.) - const secExtension = response.headersList.get('Sec-WebSocket-Extensions'); - let extensions; - - if (secExtension !== null) { - extensions = parseExtensions(secExtension); - - if (!extensions.has('permessage-deflate')) { - failWebsocketConnection(ws, 'Sec-WebSocket-Extensions header does not match.'); - return - } - } - - // 6. If the response includes a |Sec-WebSocket-Protocol| header field - // and this header field indicates the use of a subprotocol that was - // not present in the client's handshake (the server has indicated a - // subprotocol not requested by the client), the client MUST _Fail - // the WebSocket Connection_. - const secProtocol = response.headersList.get('Sec-WebSocket-Protocol'); - - if (secProtocol !== null) { - const requestProtocols = getDecodeSplit('sec-websocket-protocol', request.headersList); - - // The client can request that the server use a specific subprotocol by - // including the |Sec-WebSocket-Protocol| field in its handshake. If it - // is specified, the server needs to include the same field and one of - // the selected subprotocol values in its response for the connection to - // be established. - if (!requestProtocols.includes(secProtocol)) { - failWebsocketConnection(ws, 'Protocol was not set in the opening handshake.'); - return - } - } - - response.socket.on('data', onSocketData); - response.socket.on('close', onSocketClose); - response.socket.on('error', onSocketError); - - if (channels.open.hasSubscribers) { - channels.open.publish({ - address: response.socket.address(), - protocol: secProtocol, - extensions: secExtension - }); - } - - onEstablish(response, extensions); - } - }); - - return controller - } - - function closeWebSocketConnection (ws, code, reason, reasonByteLength) { - if (isClosing(ws) || isClosed(ws)) ; else if (!isEstablished(ws)) { - // If the WebSocket connection is not yet established - // Fail the WebSocket connection and set this's ready state - // to CLOSING (2). - failWebsocketConnection(ws, 'Connection was closed before it was established.'); - ws[kReadyState] = states.CLOSING; - } else if (ws[kSentClose] === sentCloseFrameState.NOT_SENT) { - // If the WebSocket closing handshake has not yet been started - // Start the WebSocket closing handshake and set this's ready - // state to CLOSING (2). - // - If neither code nor reason is present, the WebSocket Close - // message must not have a body. - // - If code is present, then the status code to use in the - // WebSocket Close message must be the integer given by code. - // - If reason is also present, then reasonBytes must be - // provided in the Close message after the status code. - - ws[kSentClose] = sentCloseFrameState.PROCESSING; - - const frame = new WebsocketFrameSend(); - - // If neither code nor reason is present, the WebSocket Close - // message must not have a body. - - // If code is present, then the status code to use in the - // WebSocket Close message must be the integer given by code. - if (code !== undefined && reason === undefined) { - frame.frameData = Buffer.allocUnsafe(2); - frame.frameData.writeUInt16BE(code, 0); - } else if (code !== undefined && reason !== undefined) { - // If reason is also present, then reasonBytes must be - // provided in the Close message after the status code. - frame.frameData = Buffer.allocUnsafe(2 + reasonByteLength); - frame.frameData.writeUInt16BE(code, 0); - // the body MAY contain UTF-8-encoded data with value /reason/ - frame.frameData.write(reason, 2, 'utf-8'); - } else { - frame.frameData = emptyBuffer; - } - - /** @type {import('stream').Duplex} */ - const socket = ws[kResponse].socket; - - socket.write(frame.createFrame(opcodes.CLOSE)); - - ws[kSentClose] = sentCloseFrameState.SENT; - - // Upon either sending or receiving a Close control frame, it is said - // that _The WebSocket Closing Handshake is Started_ and that the - // WebSocket connection is in the CLOSING state. - ws[kReadyState] = states.CLOSING; - } else { - // Otherwise - // Set this's ready state to CLOSING (2). - ws[kReadyState] = states.CLOSING; - } - } - - /** - * @param {Buffer} chunk - */ - function onSocketData (chunk) { - if (!this.ws[kByteParser].write(chunk)) { - this.pause(); - } - } - - /** - * @see https://websockets.spec.whatwg.org/#feedback-from-the-protocol - * @see https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.4 - */ - function onSocketClose () { - const { ws } = this; - const { [kResponse]: response } = ws; - - response.socket.off('data', onSocketData); - response.socket.off('close', onSocketClose); - response.socket.off('error', onSocketError); - - // If the TCP connection was closed after the - // WebSocket closing handshake was completed, the WebSocket connection - // is said to have been closed _cleanly_. - const wasClean = ws[kSentClose] === sentCloseFrameState.SENT && ws[kReceivedClose]; - - let code = 1005; - let reason = ''; - - const result = ws[kByteParser].closingInfo; - - if (result && !result.error) { - code = result.code ?? 1005; - reason = result.reason; - } else if (!ws[kReceivedClose]) { - // If _The WebSocket - // Connection is Closed_ and no Close control frame was received by the - // endpoint (such as could occur if the underlying transport connection - // is lost), _The WebSocket Connection Close Code_ is considered to be - // 1006. - code = 1006; - } - - // 1. Change the ready state to CLOSED (3). - ws[kReadyState] = states.CLOSED; - - // 2. If the user agent was required to fail the WebSocket - // connection, or if the WebSocket connection was closed - // after being flagged as full, fire an event named error - // at the WebSocket object. - // TODO - - // 3. Fire an event named close at the WebSocket object, - // using CloseEvent, with the wasClean attribute - // initialized to true if the connection closed cleanly - // and false otherwise, the code attribute initialized to - // the WebSocket connection close code, and the reason - // attribute initialized to the result of applying UTF-8 - // decode without BOM to the WebSocket connection close - // reason. - // TODO: process.nextTick - fireEvent('close', ws, (type, init) => new CloseEvent(type, init), { - wasClean, code, reason - }); - - if (channels.close.hasSubscribers) { - channels.close.publish({ - websocket: ws, - code, - reason - }); - } - } - - function onSocketError (error) { - const { ws } = this; - - ws[kReadyState] = states.CLOSING; - - if (channels.socketError.hasSubscribers) { - channels.socketError.publish(error); - } - - this.destroy(); - } - - connection = { - establishWebSocketConnection, - closeWebSocketConnection - }; - return connection; -} - -var permessageDeflate; -var hasRequiredPermessageDeflate; - -function requirePermessageDeflate () { - if (hasRequiredPermessageDeflate) return permessageDeflate; - hasRequiredPermessageDeflate = 1; - - const { createInflateRaw, Z_DEFAULT_WINDOWBITS } = require$$1; - const { isValidClientWindowBits } = requireUtil$1(); - - const tail = Buffer.from([0x00, 0x00, 0xff, 0xff]); - const kBuffer = Symbol('kBuffer'); - const kLength = Symbol('kLength'); - - class PerMessageDeflate { - /** @type {import('node:zlib').InflateRaw} */ - #inflate - - #options = {} - - constructor (extensions) { - this.#options.serverNoContextTakeover = extensions.has('server_no_context_takeover'); - this.#options.serverMaxWindowBits = extensions.get('server_max_window_bits'); - } - - decompress (chunk, fin, callback) { - // An endpoint uses the following algorithm to decompress a message. - // 1. Append 4 octets of 0x00 0x00 0xff 0xff to the tail end of the - // payload of the message. - // 2. Decompress the resulting data using DEFLATE. - - if (!this.#inflate) { - let windowBits = Z_DEFAULT_WINDOWBITS; - - if (this.#options.serverMaxWindowBits) { // empty values default to Z_DEFAULT_WINDOWBITS - if (!isValidClientWindowBits(this.#options.serverMaxWindowBits)) { - callback(new Error('Invalid server_max_window_bits')); - return - } - - windowBits = Number.parseInt(this.#options.serverMaxWindowBits); - } - - this.#inflate = createInflateRaw({ windowBits }); - this.#inflate[kBuffer] = []; - this.#inflate[kLength] = 0; - - this.#inflate.on('data', (data) => { - this.#inflate[kBuffer].push(data); - this.#inflate[kLength] += data.length; - }); - - this.#inflate.on('error', (err) => { - this.#inflate = null; - callback(err); - }); - } - - this.#inflate.write(chunk); - if (fin) { - this.#inflate.write(tail); - } - - this.#inflate.flush(() => { - const full = Buffer.concat(this.#inflate[kBuffer], this.#inflate[kLength]); - - this.#inflate[kBuffer].length = 0; - this.#inflate[kLength] = 0; - - callback(null, full); - }); - } - } - - permessageDeflate = { PerMessageDeflate }; - return permessageDeflate; -} - -var receiver; -var hasRequiredReceiver; - -function requireReceiver () { - if (hasRequiredReceiver) return receiver; - hasRequiredReceiver = 1; - - const { Writable } = require$$0$5; - const assert = require$$0$4; - const { parserStates, opcodes, states, emptyBuffer, sentCloseFrameState } = requireConstants(); - const { kReadyState, kSentClose, kResponse, kReceivedClose } = requireSymbols(); - const { channels } = requireDiagnostics(); - const { - isValidStatusCode, - isValidOpcode, - failWebsocketConnection, - websocketMessageReceived, - utf8Decode, - isControlFrame, - isTextBinaryFrame, - isContinuationFrame - } = requireUtil$1(); - const { WebsocketFrameSend } = requireFrame(); - const { closeWebSocketConnection } = requireConnection(); - const { PerMessageDeflate } = requirePermessageDeflate(); - - // This code was influenced by ws released under the MIT license. - // Copyright (c) 2011 Einar Otto Stangvik - // Copyright (c) 2013 Arnout Kazemier and contributors - // Copyright (c) 2016 Luigi Pinca and contributors - - class ByteParser extends Writable { - #buffers = [] - #byteOffset = 0 - #loop = false - - #state = parserStates.INFO - - #info = {} - #fragments = [] - - /** @type {Map} */ - #extensions - - constructor (ws, extensions) { - super(); - - this.ws = ws; - this.#extensions = extensions == null ? new Map() : extensions; - - if (this.#extensions.has('permessage-deflate')) { - this.#extensions.set('permessage-deflate', new PerMessageDeflate(extensions)); - } - } - - /** - * @param {Buffer} chunk - * @param {() => void} callback - */ - _write (chunk, _, callback) { - this.#buffers.push(chunk); - this.#byteOffset += chunk.length; - this.#loop = true; - - this.run(callback); - } - - /** - * Runs whenever a new chunk is received. - * Callback is called whenever there are no more chunks buffering, - * or not enough bytes are buffered to parse. - */ - run (callback) { - while (this.#loop) { - if (this.#state === parserStates.INFO) { - // If there aren't enough bytes to parse the payload length, etc. - if (this.#byteOffset < 2) { - return callback() - } - - const buffer = this.consume(2); - const fin = (buffer[0] & 0x80) !== 0; - const opcode = buffer[0] & 0x0F; - const masked = (buffer[1] & 0x80) === 0x80; - - const fragmented = !fin && opcode !== opcodes.CONTINUATION; - const payloadLength = buffer[1] & 0x7F; - - const rsv1 = buffer[0] & 0x40; - const rsv2 = buffer[0] & 0x20; - const rsv3 = buffer[0] & 0x10; - - if (!isValidOpcode(opcode)) { - failWebsocketConnection(this.ws, 'Invalid opcode received'); - return callback() - } - - if (masked) { - failWebsocketConnection(this.ws, 'Frame cannot be masked'); - return callback() - } - - // MUST be 0 unless an extension is negotiated that defines meanings - // for non-zero values. If a nonzero value is received and none of - // the negotiated extensions defines the meaning of such a nonzero - // value, the receiving endpoint MUST _Fail the WebSocket - // Connection_. - // This document allocates the RSV1 bit of the WebSocket header for - // PMCEs and calls the bit the "Per-Message Compressed" bit. On a - // WebSocket connection where a PMCE is in use, this bit indicates - // whether a message is compressed or not. - if (rsv1 !== 0 && !this.#extensions.has('permessage-deflate')) { - failWebsocketConnection(this.ws, 'Expected RSV1 to be clear.'); - return - } - - if (rsv2 !== 0 || rsv3 !== 0) { - failWebsocketConnection(this.ws, 'RSV1, RSV2, RSV3 must be clear'); - return - } - - if (fragmented && !isTextBinaryFrame(opcode)) { - // Only text and binary frames can be fragmented - failWebsocketConnection(this.ws, 'Invalid frame type was fragmented.'); - return - } - - // If we are already parsing a text/binary frame and do not receive either - // a continuation frame or close frame, fail the connection. - if (isTextBinaryFrame(opcode) && this.#fragments.length > 0) { - failWebsocketConnection(this.ws, 'Expected continuation frame'); - return - } - - if (this.#info.fragmented && fragmented) { - // A fragmented frame can't be fragmented itself - failWebsocketConnection(this.ws, 'Fragmented frame exceeded 125 bytes.'); - return - } - - // "All control frames MUST have a payload length of 125 bytes or less - // and MUST NOT be fragmented." - if ((payloadLength > 125 || fragmented) && isControlFrame(opcode)) { - failWebsocketConnection(this.ws, 'Control frame either too large or fragmented'); - return - } - - if (isContinuationFrame(opcode) && this.#fragments.length === 0 && !this.#info.compressed) { - failWebsocketConnection(this.ws, 'Unexpected continuation frame'); - return - } - - if (payloadLength <= 125) { - this.#info.payloadLength = payloadLength; - this.#state = parserStates.READ_DATA; - } else if (payloadLength === 126) { - this.#state = parserStates.PAYLOADLENGTH_16; - } else if (payloadLength === 127) { - this.#state = parserStates.PAYLOADLENGTH_64; - } - - if (isTextBinaryFrame(opcode)) { - this.#info.binaryType = opcode; - this.#info.compressed = rsv1 !== 0; - } - - this.#info.opcode = opcode; - this.#info.masked = masked; - this.#info.fin = fin; - this.#info.fragmented = fragmented; - } else if (this.#state === parserStates.PAYLOADLENGTH_16) { - if (this.#byteOffset < 2) { - return callback() - } - - const buffer = this.consume(2); - - this.#info.payloadLength = buffer.readUInt16BE(0); - this.#state = parserStates.READ_DATA; - } else if (this.#state === parserStates.PAYLOADLENGTH_64) { - if (this.#byteOffset < 8) { - return callback() - } - - const buffer = this.consume(8); - const upper = buffer.readUInt32BE(0); - - // 2^31 is the maximum bytes an arraybuffer can contain - // on 32-bit systems. Although, on 64-bit systems, this is - // 2^53-1 bytes. - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Invalid_array_length - // https://source.chromium.org/chromium/chromium/src/+/main:v8/src/common/globals.h;drc=1946212ac0100668f14eb9e2843bdd846e510a1e;bpv=1;bpt=1;l=1275 - // https://source.chromium.org/chromium/chromium/src/+/main:v8/src/objects/js-array-buffer.h;l=34;drc=1946212ac0100668f14eb9e2843bdd846e510a1e - if (upper > 2 ** 31 - 1) { - failWebsocketConnection(this.ws, 'Received payload length > 2^31 bytes.'); - return - } - - const lower = buffer.readUInt32BE(4); - - this.#info.payloadLength = (upper << 8) + lower; - this.#state = parserStates.READ_DATA; - } else if (this.#state === parserStates.READ_DATA) { - if (this.#byteOffset < this.#info.payloadLength) { - return callback() - } - - const body = this.consume(this.#info.payloadLength); - - if (isControlFrame(this.#info.opcode)) { - this.#loop = this.parseControlFrame(body); - this.#state = parserStates.INFO; - } else { - if (!this.#info.compressed) { - this.#fragments.push(body); - - // If the frame is not fragmented, a message has been received. - // If the frame is fragmented, it will terminate with a fin bit set - // and an opcode of 0 (continuation), therefore we handle that when - // parsing continuation frames, not here. - if (!this.#info.fragmented && this.#info.fin) { - const fullMessage = Buffer.concat(this.#fragments); - websocketMessageReceived(this.ws, this.#info.binaryType, fullMessage); - this.#fragments.length = 0; - } - - this.#state = parserStates.INFO; - } else { - this.#extensions.get('permessage-deflate').decompress(body, this.#info.fin, (error, data) => { - if (error) { - closeWebSocketConnection(this.ws, 1007, error.message, error.message.length); - return - } - - this.#fragments.push(data); - - if (!this.#info.fin) { - this.#state = parserStates.INFO; - this.#loop = true; - this.run(callback); - return - } - - websocketMessageReceived(this.ws, this.#info.binaryType, Buffer.concat(this.#fragments)); - - this.#loop = true; - this.#state = parserStates.INFO; - this.#fragments.length = 0; - this.run(callback); - }); - - this.#loop = false; - break - } - } - } - } - } - - /** - * Take n bytes from the buffered Buffers - * @param {number} n - * @returns {Buffer} - */ - consume (n) { - if (n > this.#byteOffset) { - throw new Error('Called consume() before buffers satiated.') - } else if (n === 0) { - return emptyBuffer - } - - if (this.#buffers[0].length === n) { - this.#byteOffset -= this.#buffers[0].length; - return this.#buffers.shift() - } - - const buffer = Buffer.allocUnsafe(n); - let offset = 0; - - while (offset !== n) { - const next = this.#buffers[0]; - const { length } = next; - - if (length + offset === n) { - buffer.set(this.#buffers.shift(), offset); - break - } else if (length + offset > n) { - buffer.set(next.subarray(0, n - offset), offset); - this.#buffers[0] = next.subarray(n - offset); - break - } else { - buffer.set(this.#buffers.shift(), offset); - offset += next.length; - } - } - - this.#byteOffset -= n; - - return buffer - } - - parseCloseBody (data) { - assert(data.length !== 1); - - // https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.5 - /** @type {number|undefined} */ - let code; - - if (data.length >= 2) { - // _The WebSocket Connection Close Code_ is - // defined as the status code (Section 7.4) contained in the first Close - // control frame received by the application - code = data.readUInt16BE(0); - } - - if (code !== undefined && !isValidStatusCode(code)) { - return { code: 1002, reason: 'Invalid status code', error: true } - } - - // https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.6 - /** @type {Buffer} */ - let reason = data.subarray(2); - - // Remove BOM - if (reason[0] === 0xEF && reason[1] === 0xBB && reason[2] === 0xBF) { - reason = reason.subarray(3); - } - - try { - reason = utf8Decode(reason); - } catch { - return { code: 1007, reason: 'Invalid UTF-8', error: true } - } - - return { code, reason, error: false } - } - - /** - * Parses control frames. - * @param {Buffer} body - */ - parseControlFrame (body) { - const { opcode, payloadLength } = this.#info; - - if (opcode === opcodes.CLOSE) { - if (payloadLength === 1) { - failWebsocketConnection(this.ws, 'Received close frame with a 1-byte body.'); - return false - } - - this.#info.closeInfo = this.parseCloseBody(body); - - if (this.#info.closeInfo.error) { - const { code, reason } = this.#info.closeInfo; - - closeWebSocketConnection(this.ws, code, reason, reason.length); - failWebsocketConnection(this.ws, reason); - return false - } - - if (this.ws[kSentClose] !== sentCloseFrameState.SENT) { - // If an endpoint receives a Close frame and did not previously send a - // Close frame, the endpoint MUST send a Close frame in response. (When - // sending a Close frame in response, the endpoint typically echos the - // status code it received.) - let body = emptyBuffer; - if (this.#info.closeInfo.code) { - body = Buffer.allocUnsafe(2); - body.writeUInt16BE(this.#info.closeInfo.code, 0); - } - const closeFrame = new WebsocketFrameSend(body); - - this.ws[kResponse].socket.write( - closeFrame.createFrame(opcodes.CLOSE), - (err) => { - if (!err) { - this.ws[kSentClose] = sentCloseFrameState.SENT; - } - } - ); - } - - // Upon either sending or receiving a Close control frame, it is said - // that _The WebSocket Closing Handshake is Started_ and that the - // WebSocket connection is in the CLOSING state. - this.ws[kReadyState] = states.CLOSING; - this.ws[kReceivedClose] = true; - - return false - } else if (opcode === opcodes.PING) { - // Upon receipt of a Ping frame, an endpoint MUST send a Pong frame in - // response, unless it already received a Close frame. - // A Pong frame sent in response to a Ping frame must have identical - // "Application data" - - if (!this.ws[kReceivedClose]) { - const frame = new WebsocketFrameSend(body); - - this.ws[kResponse].socket.write(frame.createFrame(opcodes.PONG)); - - if (channels.ping.hasSubscribers) { - channels.ping.publish({ - payload: body - }); - } - } - } else if (opcode === opcodes.PONG) { - // A Pong frame MAY be sent unsolicited. This serves as a - // unidirectional heartbeat. A response to an unsolicited Pong frame is - // not expected. - - if (channels.pong.hasSubscribers) { - channels.pong.publish({ - payload: body - }); - } - } - - return true - } - - get closingInfo () { - return this.#info.closeInfo - } - } - - receiver = { - ByteParser - }; - return receiver; -} - -var sender; -var hasRequiredSender; - -function requireSender () { - if (hasRequiredSender) return sender; - hasRequiredSender = 1; - - const { WebsocketFrameSend } = requireFrame(); - const { opcodes, sendHints } = requireConstants(); - const FixedQueue = requireFixedQueue(); - - /** @type {typeof Uint8Array} */ - const FastBuffer = Buffer[Symbol.species]; - - /** - * @typedef {object} SendQueueNode - * @property {Promise | null} promise - * @property {((...args: any[]) => any)} callback - * @property {Buffer | null} frame - */ - - class SendQueue { - /** - * @type {FixedQueue} - */ - #queue = new FixedQueue() - - /** - * @type {boolean} - */ - #running = false - - /** @type {import('node:net').Socket} */ - #socket - - constructor (socket) { - this.#socket = socket; - } - - add (item, cb, hint) { - if (hint !== sendHints.blob) { - const frame = createFrame(item, hint); - if (!this.#running) { - // fast-path - this.#socket.write(frame, cb); - } else { - /** @type {SendQueueNode} */ - const node = { - promise: null, - callback: cb, - frame - }; - this.#queue.push(node); - } - return - } - - /** @type {SendQueueNode} */ - const node = { - promise: item.arrayBuffer().then((ab) => { - node.promise = null; - node.frame = createFrame(ab, hint); - }), - callback: cb, - frame: null - }; - - this.#queue.push(node); - - if (!this.#running) { - this.#run(); - } - } - - async #run () { - this.#running = true; - const queue = this.#queue; - while (!queue.isEmpty()) { - const node = queue.shift(); - // wait pending promise - if (node.promise !== null) { - await node.promise; - } - // write - this.#socket.write(node.frame, node.callback); - // cleanup - node.callback = node.frame = null; - } - this.#running = false; - } - } - - function createFrame (data, hint) { - return new WebsocketFrameSend(toBuffer(data, hint)).createFrame(hint === sendHints.string ? opcodes.TEXT : opcodes.BINARY) - } - - function toBuffer (data, hint) { - switch (hint) { - case sendHints.string: - return Buffer.from(data) - case sendHints.arrayBuffer: - case sendHints.blob: - return new FastBuffer(data) - case sendHints.typedArray: - return new FastBuffer(data.buffer, data.byteOffset, data.byteLength) - } - } - - sender = { SendQueue }; - return sender; -} - -var websocket; -var hasRequiredWebsocket; - -function requireWebsocket () { - if (hasRequiredWebsocket) return websocket; - hasRequiredWebsocket = 1; - - const { webidl } = requireWebidl(); - const { URLSerializer } = requireDataUrl(); - const { environmentSettingsObject } = requireUtil$6(); - const { staticPropertyDescriptors, states, sentCloseFrameState, sendHints } = requireConstants(); - const { - kWebSocketURL, - kReadyState, - kController, - kBinaryType, - kResponse, - kSentClose, - kByteParser - } = requireSymbols(); - const { - isConnecting, - isEstablished, - isClosing, - isValidSubprotocol, - fireEvent - } = requireUtil$1(); - const { establishWebSocketConnection, closeWebSocketConnection } = requireConnection(); - const { ByteParser } = requireReceiver(); - const { kEnumerableProperty, isBlobLike } = requireUtil$7(); - const { getGlobalDispatcher } = requireGlobal(); - const { types } = require$$0$6; - const { ErrorEvent, CloseEvent } = requireEvents(); - const { SendQueue } = requireSender(); - - // https://websockets.spec.whatwg.org/#interface-definition - class WebSocket extends EventTarget { - #events = { - open: null, - error: null, - close: null, - message: null - } - - #bufferedAmount = 0 - #protocol = '' - #extensions = '' - - /** @type {SendQueue} */ - #sendQueue - - /** - * @param {string} url - * @param {string|string[]} protocols - */ - constructor (url, protocols = []) { - super(); - - const prefix = 'WebSocket constructor'; - webidl.argumentLengthCheck(arguments, 1, prefix); - - const options = webidl.converters['DOMString or sequence or WebSocketInit'](protocols, prefix, 'options'); - - url = webidl.converters.USVString(url, prefix, 'url'); - protocols = options.protocols; - - // 1. Let baseURL be this's relevant settings object's API base URL. - const baseURL = environmentSettingsObject.settingsObject.baseUrl; - - // 1. Let urlRecord be the result of applying the URL parser to url with baseURL. - let urlRecord; - - try { - urlRecord = new URL(url, baseURL); - } catch (e) { - // 3. If urlRecord is failure, then throw a "SyntaxError" DOMException. - throw new DOMException(e, 'SyntaxError') - } - - // 4. If urlRecord’s scheme is "http", then set urlRecord’s scheme to "ws". - if (urlRecord.protocol === 'http:') { - urlRecord.protocol = 'ws:'; - } else if (urlRecord.protocol === 'https:') { - // 5. Otherwise, if urlRecord’s scheme is "https", set urlRecord’s scheme to "wss". - urlRecord.protocol = 'wss:'; - } - - // 6. If urlRecord’s scheme is not "ws" or "wss", then throw a "SyntaxError" DOMException. - if (urlRecord.protocol !== 'ws:' && urlRecord.protocol !== 'wss:') { - throw new DOMException( - `Expected a ws: or wss: protocol, got ${urlRecord.protocol}`, - 'SyntaxError' - ) - } - - // 7. If urlRecord’s fragment is non-null, then throw a "SyntaxError" - // DOMException. - if (urlRecord.hash || urlRecord.href.endsWith('#')) { - throw new DOMException('Got fragment', 'SyntaxError') - } - - // 8. If protocols is a string, set protocols to a sequence consisting - // of just that string. - if (typeof protocols === 'string') { - protocols = [protocols]; - } - - // 9. If any of the values in protocols occur more than once or otherwise - // fail to match the requirements for elements that comprise the value - // of `Sec-WebSocket-Protocol` fields as defined by The WebSocket - // protocol, then throw a "SyntaxError" DOMException. - if (protocols.length !== new Set(protocols.map(p => p.toLowerCase())).size) { - throw new DOMException('Invalid Sec-WebSocket-Protocol value', 'SyntaxError') - } - - if (protocols.length > 0 && !protocols.every(p => isValidSubprotocol(p))) { - throw new DOMException('Invalid Sec-WebSocket-Protocol value', 'SyntaxError') - } - - // 10. Set this's url to urlRecord. - this[kWebSocketURL] = new URL(urlRecord.href); - - // 11. Let client be this's relevant settings object. - const client = environmentSettingsObject.settingsObject; - - // 12. Run this step in parallel: - - // 1. Establish a WebSocket connection given urlRecord, protocols, - // and client. - this[kController] = establishWebSocketConnection( - urlRecord, - protocols, - client, - this, - (response, extensions) => this.#onConnectionEstablished(response, extensions), - options - ); - - // Each WebSocket object has an associated ready state, which is a - // number representing the state of the connection. Initially it must - // be CONNECTING (0). - this[kReadyState] = WebSocket.CONNECTING; - - this[kSentClose] = sentCloseFrameState.NOT_SENT; - - // The extensions attribute must initially return the empty string. - - // The protocol attribute must initially return the empty string. - - // Each WebSocket object has an associated binary type, which is a - // BinaryType. Initially it must be "blob". - this[kBinaryType] = 'blob'; - } - - /** - * @see https://websockets.spec.whatwg.org/#dom-websocket-close - * @param {number|undefined} code - * @param {string|undefined} reason - */ - close (code = undefined, reason = undefined) { - webidl.brandCheck(this, WebSocket); - - const prefix = 'WebSocket.close'; - - if (code !== undefined) { - code = webidl.converters['unsigned short'](code, prefix, 'code', { clamp: true }); - } - - if (reason !== undefined) { - reason = webidl.converters.USVString(reason, prefix, 'reason'); - } - - // 1. If code is present, but is neither an integer equal to 1000 nor an - // integer in the range 3000 to 4999, inclusive, throw an - // "InvalidAccessError" DOMException. - if (code !== undefined) { - if (code !== 1000 && (code < 3000 || code > 4999)) { - throw new DOMException('invalid code', 'InvalidAccessError') - } - } - - let reasonByteLength = 0; - - // 2. If reason is present, then run these substeps: - if (reason !== undefined) { - // 1. Let reasonBytes be the result of encoding reason. - // 2. If reasonBytes is longer than 123 bytes, then throw a - // "SyntaxError" DOMException. - reasonByteLength = Buffer.byteLength(reason); - - if (reasonByteLength > 123) { - throw new DOMException( - `Reason must be less than 123 bytes; received ${reasonByteLength}`, - 'SyntaxError' - ) - } - } - - // 3. Run the first matching steps from the following list: - closeWebSocketConnection(this, code, reason, reasonByteLength); - } - - /** - * @see https://websockets.spec.whatwg.org/#dom-websocket-send - * @param {NodeJS.TypedArray|ArrayBuffer|Blob|string} data - */ - send (data) { - webidl.brandCheck(this, WebSocket); - - const prefix = 'WebSocket.send'; - webidl.argumentLengthCheck(arguments, 1, prefix); - - data = webidl.converters.WebSocketSendData(data, prefix, 'data'); - - // 1. If this's ready state is CONNECTING, then throw an - // "InvalidStateError" DOMException. - if (isConnecting(this)) { - throw new DOMException('Sent before connected.', 'InvalidStateError') - } - - // 2. Run the appropriate set of steps from the following list: - // https://datatracker.ietf.org/doc/html/rfc6455#section-6.1 - // https://datatracker.ietf.org/doc/html/rfc6455#section-5.2 - - if (!isEstablished(this) || isClosing(this)) { - return - } - - // If data is a string - if (typeof data === 'string') { - // If the WebSocket connection is established and the WebSocket - // closing handshake has not yet started, then the user agent - // must send a WebSocket Message comprised of the data argument - // using a text frame opcode; if the data cannot be sent, e.g. - // because it would need to be buffered but the buffer is full, - // the user agent must flag the WebSocket as full and then close - // the WebSocket connection. Any invocation of this method with a - // string argument that does not throw an exception must increase - // the bufferedAmount attribute by the number of bytes needed to - // express the argument as UTF-8. - - const length = Buffer.byteLength(data); - - this.#bufferedAmount += length; - this.#sendQueue.add(data, () => { - this.#bufferedAmount -= length; - }, sendHints.string); - } else if (types.isArrayBuffer(data)) { - // If the WebSocket connection is established, and the WebSocket - // closing handshake has not yet started, then the user agent must - // send a WebSocket Message comprised of data using a binary frame - // opcode; if the data cannot be sent, e.g. because it would need - // to be buffered but the buffer is full, the user agent must flag - // the WebSocket as full and then close the WebSocket connection. - // The data to be sent is the data stored in the buffer described - // by the ArrayBuffer object. Any invocation of this method with an - // ArrayBuffer argument that does not throw an exception must - // increase the bufferedAmount attribute by the length of the - // ArrayBuffer in bytes. - - this.#bufferedAmount += data.byteLength; - this.#sendQueue.add(data, () => { - this.#bufferedAmount -= data.byteLength; - }, sendHints.arrayBuffer); - } else if (ArrayBuffer.isView(data)) { - // If the WebSocket connection is established, and the WebSocket - // closing handshake has not yet started, then the user agent must - // send a WebSocket Message comprised of data using a binary frame - // opcode; if the data cannot be sent, e.g. because it would need to - // be buffered but the buffer is full, the user agent must flag the - // WebSocket as full and then close the WebSocket connection. The - // data to be sent is the data stored in the section of the buffer - // described by the ArrayBuffer object that data references. Any - // invocation of this method with this kind of argument that does - // not throw an exception must increase the bufferedAmount attribute - // by the length of data’s buffer in bytes. - - this.#bufferedAmount += data.byteLength; - this.#sendQueue.add(data, () => { - this.#bufferedAmount -= data.byteLength; - }, sendHints.typedArray); - } else if (isBlobLike(data)) { - // If the WebSocket connection is established, and the WebSocket - // closing handshake has not yet started, then the user agent must - // send a WebSocket Message comprised of data using a binary frame - // opcode; if the data cannot be sent, e.g. because it would need to - // be buffered but the buffer is full, the user agent must flag the - // WebSocket as full and then close the WebSocket connection. The data - // to be sent is the raw data represented by the Blob object. Any - // invocation of this method with a Blob argument that does not throw - // an exception must increase the bufferedAmount attribute by the size - // of the Blob object’s raw data, in bytes. - - this.#bufferedAmount += data.size; - this.#sendQueue.add(data, () => { - this.#bufferedAmount -= data.size; - }, sendHints.blob); - } - } - - get readyState () { - webidl.brandCheck(this, WebSocket); - - // The readyState getter steps are to return this's ready state. - return this[kReadyState] - } - - get bufferedAmount () { - webidl.brandCheck(this, WebSocket); - - return this.#bufferedAmount - } - - get url () { - webidl.brandCheck(this, WebSocket); - - // The url getter steps are to return this's url, serialized. - return URLSerializer(this[kWebSocketURL]) - } - - get extensions () { - webidl.brandCheck(this, WebSocket); - - return this.#extensions - } - - get protocol () { - webidl.brandCheck(this, WebSocket); - - return this.#protocol - } - - get onopen () { - webidl.brandCheck(this, WebSocket); - - return this.#events.open - } - - set onopen (fn) { - webidl.brandCheck(this, WebSocket); - - if (this.#events.open) { - this.removeEventListener('open', this.#events.open); - } - - if (typeof fn === 'function') { - this.#events.open = fn; - this.addEventListener('open', fn); - } else { - this.#events.open = null; - } - } - - get onerror () { - webidl.brandCheck(this, WebSocket); - - return this.#events.error - } - - set onerror (fn) { - webidl.brandCheck(this, WebSocket); - - if (this.#events.error) { - this.removeEventListener('error', this.#events.error); - } - - if (typeof fn === 'function') { - this.#events.error = fn; - this.addEventListener('error', fn); - } else { - this.#events.error = null; - } - } - - get onclose () { - webidl.brandCheck(this, WebSocket); - - return this.#events.close - } - - set onclose (fn) { - webidl.brandCheck(this, WebSocket); - - if (this.#events.close) { - this.removeEventListener('close', this.#events.close); - } - - if (typeof fn === 'function') { - this.#events.close = fn; - this.addEventListener('close', fn); - } else { - this.#events.close = null; - } - } - - get onmessage () { - webidl.brandCheck(this, WebSocket); - - return this.#events.message - } - - set onmessage (fn) { - webidl.brandCheck(this, WebSocket); - - if (this.#events.message) { - this.removeEventListener('message', this.#events.message); - } - - if (typeof fn === 'function') { - this.#events.message = fn; - this.addEventListener('message', fn); - } else { - this.#events.message = null; - } - } - - get binaryType () { - webidl.brandCheck(this, WebSocket); - - return this[kBinaryType] - } - - set binaryType (type) { - webidl.brandCheck(this, WebSocket); - - if (type !== 'blob' && type !== 'arraybuffer') { - this[kBinaryType] = 'blob'; - } else { - this[kBinaryType] = type; - } - } - - /** - * @see https://websockets.spec.whatwg.org/#feedback-from-the-protocol - */ - #onConnectionEstablished (response, parsedExtensions) { - // processResponse is called when the "response’s header list has been received and initialized." - // once this happens, the connection is open - this[kResponse] = response; - - const parser = new ByteParser(this, parsedExtensions); - parser.on('drain', onParserDrain); - parser.on('error', onParserError.bind(this)); - - response.socket.ws = this; - this[kByteParser] = parser; - - this.#sendQueue = new SendQueue(response.socket); - - // 1. Change the ready state to OPEN (1). - this[kReadyState] = states.OPEN; - - // 2. Change the extensions attribute’s value to the extensions in use, if - // it is not the null value. - // https://datatracker.ietf.org/doc/html/rfc6455#section-9.1 - const extensions = response.headersList.get('sec-websocket-extensions'); - - if (extensions !== null) { - this.#extensions = extensions; - } - - // 3. Change the protocol attribute’s value to the subprotocol in use, if - // it is not the null value. - // https://datatracker.ietf.org/doc/html/rfc6455#section-1.9 - const protocol = response.headersList.get('sec-websocket-protocol'); - - if (protocol !== null) { - this.#protocol = protocol; - } - - // 4. Fire an event named open at the WebSocket object. - fireEvent('open', this); - } - } - - // https://websockets.spec.whatwg.org/#dom-websocket-connecting - WebSocket.CONNECTING = WebSocket.prototype.CONNECTING = states.CONNECTING; - // https://websockets.spec.whatwg.org/#dom-websocket-open - WebSocket.OPEN = WebSocket.prototype.OPEN = states.OPEN; - // https://websockets.spec.whatwg.org/#dom-websocket-closing - WebSocket.CLOSING = WebSocket.prototype.CLOSING = states.CLOSING; - // https://websockets.spec.whatwg.org/#dom-websocket-closed - WebSocket.CLOSED = WebSocket.prototype.CLOSED = states.CLOSED; - - Object.defineProperties(WebSocket.prototype, { - CONNECTING: staticPropertyDescriptors, - OPEN: staticPropertyDescriptors, - CLOSING: staticPropertyDescriptors, - CLOSED: staticPropertyDescriptors, - url: kEnumerableProperty, - readyState: kEnumerableProperty, - bufferedAmount: kEnumerableProperty, - onopen: kEnumerableProperty, - onerror: kEnumerableProperty, - onclose: kEnumerableProperty, - close: kEnumerableProperty, - onmessage: kEnumerableProperty, - binaryType: kEnumerableProperty, - send: kEnumerableProperty, - extensions: kEnumerableProperty, - protocol: kEnumerableProperty, - [Symbol.toStringTag]: { - value: 'WebSocket', - writable: false, - enumerable: false, - configurable: true - } - }); - - Object.defineProperties(WebSocket, { - CONNECTING: staticPropertyDescriptors, - OPEN: staticPropertyDescriptors, - CLOSING: staticPropertyDescriptors, - CLOSED: staticPropertyDescriptors - }); - - webidl.converters['sequence'] = webidl.sequenceConverter( - webidl.converters.DOMString - ); - - webidl.converters['DOMString or sequence'] = function (V, prefix, argument) { - if (webidl.util.Type(V) === 'Object' && Symbol.iterator in V) { - return webidl.converters['sequence'](V) - } - - return webidl.converters.DOMString(V, prefix, argument) - }; - - // This implements the proposal made in https://github.com/whatwg/websockets/issues/42 - webidl.converters.WebSocketInit = webidl.dictionaryConverter([ - { - key: 'protocols', - converter: webidl.converters['DOMString or sequence'], - defaultValue: () => new Array(0) - }, - { - key: 'dispatcher', - converter: webidl.converters.any, - defaultValue: () => getGlobalDispatcher() - }, - { - key: 'headers', - converter: webidl.nullableConverter(webidl.converters.HeadersInit) - } - ]); - - webidl.converters['DOMString or sequence or WebSocketInit'] = function (V) { - if (webidl.util.Type(V) === 'Object' && !(Symbol.iterator in V)) { - return webidl.converters.WebSocketInit(V) - } - - return { protocols: webidl.converters['DOMString or sequence'](V) } - }; - - webidl.converters.WebSocketSendData = function (V) { - if (webidl.util.Type(V) === 'Object') { - if (isBlobLike(V)) { - return webidl.converters.Blob(V, { strict: false }) - } - - if (ArrayBuffer.isView(V) || types.isArrayBuffer(V)) { - return webidl.converters.BufferSource(V) - } - } - - return webidl.converters.USVString(V) - }; - - function onParserDrain () { - this.ws[kResponse].socket.resume(); - } - - function onParserError (err) { - let message; - let code; - - if (err instanceof CloseEvent) { - message = err.reason; - code = err.code; - } else { - message = err.message; - } - - fireEvent('error', this, () => new ErrorEvent('error', { error: err, message })); - - closeWebSocketConnection(this, code); - } - - websocket = { - WebSocket - }; - return websocket; -} - -var util; -var hasRequiredUtil; - -function requireUtil () { - if (hasRequiredUtil) return util; - hasRequiredUtil = 1; - - /** - * Checks if the given value is a valid LastEventId. - * @param {string} value - * @returns {boolean} - */ - function isValidLastEventId (value) { - // LastEventId should not contain U+0000 NULL - return value.indexOf('\u0000') === -1 - } - - /** - * Checks if the given value is a base 10 digit. - * @param {string} value - * @returns {boolean} - */ - function isASCIINumber (value) { - if (value.length === 0) return false - for (let i = 0; i < value.length; i++) { - if (value.charCodeAt(i) < 0x30 || value.charCodeAt(i) > 0x39) return false - } - return true - } - - // https://github.com/nodejs/undici/issues/2664 - function delay (ms) { - return new Promise((resolve) => { - setTimeout(resolve, ms).unref(); - }) - } - - util = { - isValidLastEventId, - isASCIINumber, - delay - }; - return util; -} - -var eventsourceStream; -var hasRequiredEventsourceStream; - -function requireEventsourceStream () { - if (hasRequiredEventsourceStream) return eventsourceStream; - hasRequiredEventsourceStream = 1; - const { Transform } = require$$0$5; - const { isASCIINumber, isValidLastEventId } = requireUtil(); - - /** - * @type {number[]} BOM - */ - const BOM = [0xEF, 0xBB, 0xBF]; - /** - * @type {10} LF - */ - const LF = 0x0A; - /** - * @type {13} CR - */ - const CR = 0x0D; - /** - * @type {58} COLON - */ - const COLON = 0x3A; - /** - * @type {32} SPACE - */ - const SPACE = 0x20; - - /** - * @typedef {object} EventSourceStreamEvent - * @type {object} - * @property {string} [event] The event type. - * @property {string} [data] The data of the message. - * @property {string} [id] A unique ID for the event. - * @property {string} [retry] The reconnection time, in milliseconds. - */ - - /** - * @typedef eventSourceSettings - * @type {object} - * @property {string} lastEventId The last event ID received from the server. - * @property {string} origin The origin of the event source. - * @property {number} reconnectionTime The reconnection time, in milliseconds. - */ - - class EventSourceStream extends Transform { - /** - * @type {eventSourceSettings} - */ - state = null - - /** - * Leading byte-order-mark check. - * @type {boolean} - */ - checkBOM = true - - /** - * @type {boolean} - */ - crlfCheck = false - - /** - * @type {boolean} - */ - eventEndCheck = false - - /** - * @type {Buffer} - */ - buffer = null - - pos = 0 - - event = { - data: undefined, - event: undefined, - id: undefined, - retry: undefined - } - - /** - * @param {object} options - * @param {eventSourceSettings} options.eventSourceSettings - * @param {Function} [options.push] - */ - constructor (options = {}) { - // Enable object mode as EventSourceStream emits objects of shape - // EventSourceStreamEvent - options.readableObjectMode = true; - - super(options); - - this.state = options.eventSourceSettings || {}; - if (options.push) { - this.push = options.push; - } - } - - /** - * @param {Buffer} chunk - * @param {string} _encoding - * @param {Function} callback - * @returns {void} - */ - _transform (chunk, _encoding, callback) { - if (chunk.length === 0) { - callback(); - return - } - - // Cache the chunk in the buffer, as the data might not be complete while - // processing it - // TODO: Investigate if there is a more performant way to handle - // incoming chunks - // see: https://github.com/nodejs/undici/issues/2630 - if (this.buffer) { - this.buffer = Buffer.concat([this.buffer, chunk]); - } else { - this.buffer = chunk; - } - - // Strip leading byte-order-mark if we opened the stream and started - // the processing of the incoming data - if (this.checkBOM) { - switch (this.buffer.length) { - case 1: - // Check if the first byte is the same as the first byte of the BOM - if (this.buffer[0] === BOM[0]) { - // If it is, we need to wait for more data - callback(); - return - } - // Set the checkBOM flag to false as we don't need to check for the - // BOM anymore - this.checkBOM = false; - - // The buffer only contains one byte so we need to wait for more data - callback(); - return - case 2: - // Check if the first two bytes are the same as the first two bytes - // of the BOM - if ( - this.buffer[0] === BOM[0] && - this.buffer[1] === BOM[1] - ) { - // If it is, we need to wait for more data, because the third byte - // is needed to determine if it is the BOM or not - callback(); - return - } - - // Set the checkBOM flag to false as we don't need to check for the - // BOM anymore - this.checkBOM = false; - break - case 3: - // Check if the first three bytes are the same as the first three - // bytes of the BOM - if ( - this.buffer[0] === BOM[0] && - this.buffer[1] === BOM[1] && - this.buffer[2] === BOM[2] - ) { - // If it is, we can drop the buffered data, as it is only the BOM - this.buffer = Buffer.alloc(0); - // Set the checkBOM flag to false as we don't need to check for the - // BOM anymore - this.checkBOM = false; - - // Await more data - callback(); - return - } - // If it is not the BOM, we can start processing the data - this.checkBOM = false; - break - default: - // The buffer is longer than 3 bytes, so we can drop the BOM if it is - // present - if ( - this.buffer[0] === BOM[0] && - this.buffer[1] === BOM[1] && - this.buffer[2] === BOM[2] - ) { - // Remove the BOM from the buffer - this.buffer = this.buffer.subarray(3); - } - - // Set the checkBOM flag to false as we don't need to check for the - this.checkBOM = false; - break - } - } - - while (this.pos < this.buffer.length) { - // If the previous line ended with an end-of-line, we need to check - // if the next character is also an end-of-line. - if (this.eventEndCheck) { - // If the the current character is an end-of-line, then the event - // is finished and we can process it - - // If the previous line ended with a carriage return, we need to - // check if the current character is a line feed and remove it - // from the buffer. - if (this.crlfCheck) { - // If the current character is a line feed, we can remove it - // from the buffer and reset the crlfCheck flag - if (this.buffer[this.pos] === LF) { - this.buffer = this.buffer.subarray(this.pos + 1); - this.pos = 0; - this.crlfCheck = false; - - // It is possible that the line feed is not the end of the - // event. We need to check if the next character is an - // end-of-line character to determine if the event is - // finished. We simply continue the loop to check the next - // character. - - // As we removed the line feed from the buffer and set the - // crlfCheck flag to false, we basically don't make any - // distinction between a line feed and a carriage return. - continue - } - this.crlfCheck = false; - } - - if (this.buffer[this.pos] === LF || this.buffer[this.pos] === CR) { - // If the current character is a carriage return, we need to - // set the crlfCheck flag to true, as we need to check if the - // next character is a line feed so we can remove it from the - // buffer - if (this.buffer[this.pos] === CR) { - this.crlfCheck = true; - } - - this.buffer = this.buffer.subarray(this.pos + 1); - this.pos = 0; - if ( - this.event.data !== undefined || this.event.event || this.event.id || this.event.retry) { - this.processEvent(this.event); - } - this.clearEvent(); - continue - } - // If the current character is not an end-of-line, then the event - // is not finished and we have to reset the eventEndCheck flag - this.eventEndCheck = false; - continue - } - - // If the current character is an end-of-line, we can process the - // line - if (this.buffer[this.pos] === LF || this.buffer[this.pos] === CR) { - // If the current character is a carriage return, we need to - // set the crlfCheck flag to true, as we need to check if the - // next character is a line feed - if (this.buffer[this.pos] === CR) { - this.crlfCheck = true; - } - - // In any case, we can process the line as we reached an - // end-of-line character - this.parseLine(this.buffer.subarray(0, this.pos), this.event); - - // Remove the processed line from the buffer - this.buffer = this.buffer.subarray(this.pos + 1); - // Reset the position as we removed the processed line from the buffer - this.pos = 0; - // A line was processed and this could be the end of the event. We need - // to check if the next line is empty to determine if the event is - // finished. - this.eventEndCheck = true; - continue - } - - this.pos++; - } - - callback(); - } - - /** - * @param {Buffer} line - * @param {EventStreamEvent} event - */ - parseLine (line, event) { - // If the line is empty (a blank line) - // Dispatch the event, as defined below. - // This will be handled in the _transform method - if (line.length === 0) { - return - } - - // If the line starts with a U+003A COLON character (:) - // Ignore the line. - const colonPosition = line.indexOf(COLON); - if (colonPosition === 0) { - return - } - - let field = ''; - let value = ''; - - // If the line contains a U+003A COLON character (:) - if (colonPosition !== -1) { - // Collect the characters on the line before the first U+003A COLON - // character (:), and let field be that string. - // TODO: Investigate if there is a more performant way to extract the - // field - // see: https://github.com/nodejs/undici/issues/2630 - field = line.subarray(0, colonPosition).toString('utf8'); - - // Collect the characters on the line after the first U+003A COLON - // character (:), and let value be that string. - // If value starts with a U+0020 SPACE character, remove it from value. - let valueStart = colonPosition + 1; - if (line[valueStart] === SPACE) { - ++valueStart; - } - // TODO: Investigate if there is a more performant way to extract the - // value - // see: https://github.com/nodejs/undici/issues/2630 - value = line.subarray(valueStart).toString('utf8'); - - // Otherwise, the string is not empty but does not contain a U+003A COLON - // character (:) - } else { - // Process the field using the steps described below, using the whole - // line as the field name, and the empty string as the field value. - field = line.toString('utf8'); - value = ''; - } - - // Modify the event with the field name and value. The value is also - // decoded as UTF-8 - switch (field) { - case 'data': - if (event[field] === undefined) { - event[field] = value; - } else { - event[field] += `\n${value}`; - } - break - case 'retry': - if (isASCIINumber(value)) { - event[field] = value; - } - break - case 'id': - if (isValidLastEventId(value)) { - event[field] = value; - } - break - case 'event': - if (value.length > 0) { - event[field] = value; - } - break - } - } - - /** - * @param {EventSourceStreamEvent} event - */ - processEvent (event) { - if (event.retry && isASCIINumber(event.retry)) { - this.state.reconnectionTime = parseInt(event.retry, 10); - } - - if (event.id && isValidLastEventId(event.id)) { - this.state.lastEventId = event.id; - } - - // only dispatch event, when data is provided - if (event.data !== undefined) { - this.push({ - type: event.event || 'message', - options: { - data: event.data, - lastEventId: this.state.lastEventId, - origin: this.state.origin - } - }); - } - } - - clearEvent () { - this.event = { - data: undefined, - event: undefined, - id: undefined, - retry: undefined - }; - } - } - - eventsourceStream = { - EventSourceStream - }; - return eventsourceStream; -} - -var eventsource; -var hasRequiredEventsource; - -function requireEventsource () { - if (hasRequiredEventsource) return eventsource; - hasRequiredEventsource = 1; - - const { pipeline } = require$$0$5; - const { fetching } = requireFetch(); - const { makeRequest } = requireRequest(); - const { webidl } = requireWebidl(); - const { EventSourceStream } = requireEventsourceStream(); - const { parseMIMEType } = requireDataUrl(); - const { createFastMessageEvent } = requireEvents(); - const { isNetworkError } = requireResponse(); - const { delay } = requireUtil(); - const { kEnumerableProperty } = requireUtil$7(); - const { environmentSettingsObject } = requireUtil$6(); - - let experimentalWarned = false; - - /** - * A reconnection time, in milliseconds. This must initially be an implementation-defined value, - * probably in the region of a few seconds. - * - * In Comparison: - * - Chrome uses 3000ms. - * - Deno uses 5000ms. - * - * @type {3000} - */ - const defaultReconnectionTime = 3000; - - /** - * The readyState attribute represents the state of the connection. - * @enum - * @readonly - * @see https://html.spec.whatwg.org/multipage/server-sent-events.html#dom-eventsource-readystate-dev - */ - - /** - * The connection has not yet been established, or it was closed and the user - * agent is reconnecting. - * @type {0} - */ - const CONNECTING = 0; - - /** - * The user agent has an open connection and is dispatching events as it - * receives them. - * @type {1} - */ - const OPEN = 1; - - /** - * The connection is not open, and the user agent is not trying to reconnect. - * @type {2} - */ - const CLOSED = 2; - - /** - * Requests for the element will have their mode set to "cors" and their credentials mode set to "same-origin". - * @type {'anonymous'} - */ - const ANONYMOUS = 'anonymous'; - - /** - * Requests for the element will have their mode set to "cors" and their credentials mode set to "include". - * @type {'use-credentials'} - */ - const USE_CREDENTIALS = 'use-credentials'; - - /** - * The EventSource interface is used to receive server-sent events. It - * connects to a server over HTTP and receives events in text/event-stream - * format without closing the connection. - * @extends {EventTarget} - * @see https://html.spec.whatwg.org/multipage/server-sent-events.html#server-sent-events - * @api public - */ - class EventSource extends EventTarget { - #events = { - open: null, - error: null, - message: null - } - - #url = null - #withCredentials = false - - #readyState = CONNECTING - - #request = null - #controller = null - - #dispatcher - - /** - * @type {import('./eventsource-stream').eventSourceSettings} - */ - #state - - /** - * Creates a new EventSource object. - * @param {string} url - * @param {EventSourceInit} [eventSourceInitDict] - * @see https://html.spec.whatwg.org/multipage/server-sent-events.html#the-eventsource-interface - */ - constructor (url, eventSourceInitDict = {}) { - // 1. Let ev be a new EventSource object. - super(); - - const prefix = 'EventSource constructor'; - webidl.argumentLengthCheck(arguments, 1, prefix); - - if (!experimentalWarned) { - experimentalWarned = true; - process.emitWarning('EventSource is experimental, expect them to change at any time.', { - code: 'UNDICI-ES' - }); - } - - url = webidl.converters.USVString(url, prefix, 'url'); - eventSourceInitDict = webidl.converters.EventSourceInitDict(eventSourceInitDict, prefix, 'eventSourceInitDict'); - - this.#dispatcher = eventSourceInitDict.dispatcher; - this.#state = { - lastEventId: '', - reconnectionTime: defaultReconnectionTime - }; - - // 2. Let settings be ev's relevant settings object. - // https://html.spec.whatwg.org/multipage/webappapis.html#environment-settings-object - const settings = environmentSettingsObject; - - let urlRecord; - - try { - // 3. Let urlRecord be the result of encoding-parsing a URL given url, relative to settings. - urlRecord = new URL(url, settings.settingsObject.baseUrl); - this.#state.origin = urlRecord.origin; - } catch (e) { - // 4. If urlRecord is failure, then throw a "SyntaxError" DOMException. - throw new DOMException(e, 'SyntaxError') - } - - // 5. Set ev's url to urlRecord. - this.#url = urlRecord.href; - - // 6. Let corsAttributeState be Anonymous. - let corsAttributeState = ANONYMOUS; - - // 7. If the value of eventSourceInitDict's withCredentials member is true, - // then set corsAttributeState to Use Credentials and set ev's - // withCredentials attribute to true. - if (eventSourceInitDict.withCredentials) { - corsAttributeState = USE_CREDENTIALS; - this.#withCredentials = true; - } - - // 8. Let request be the result of creating a potential-CORS request given - // urlRecord, the empty string, and corsAttributeState. - const initRequest = { - redirect: 'follow', - keepalive: true, - // @see https://html.spec.whatwg.org/multipage/urls-and-fetching.html#cors-settings-attributes - mode: 'cors', - credentials: corsAttributeState === 'anonymous' - ? 'same-origin' - : 'omit', - referrer: 'no-referrer' - }; - - // 9. Set request's client to settings. - initRequest.client = environmentSettingsObject.settingsObject; - - // 10. User agents may set (`Accept`, `text/event-stream`) in request's header list. - initRequest.headersList = [['accept', { name: 'accept', value: 'text/event-stream' }]]; - - // 11. Set request's cache mode to "no-store". - initRequest.cache = 'no-store'; - - // 12. Set request's initiator type to "other". - initRequest.initiator = 'other'; - - initRequest.urlList = [new URL(this.#url)]; - - // 13. Set ev's request to request. - this.#request = makeRequest(initRequest); - - this.#connect(); - } - - /** - * Returns the state of this EventSource object's connection. It can have the - * values described below. - * @returns {0|1|2} - * @readonly - */ - get readyState () { - return this.#readyState - } - - /** - * Returns the URL providing the event stream. - * @readonly - * @returns {string} - */ - get url () { - return this.#url - } - - /** - * Returns a boolean indicating whether the EventSource object was - * instantiated with CORS credentials set (true), or not (false, the default). - */ - get withCredentials () { - return this.#withCredentials - } - - #connect () { - if (this.#readyState === CLOSED) return - - this.#readyState = CONNECTING; - - const fetchParams = { - request: this.#request, - dispatcher: this.#dispatcher - }; - - // 14. Let processEventSourceEndOfBody given response res be the following step: if res is not a network error, then reestablish the connection. - const processEventSourceEndOfBody = (response) => { - if (isNetworkError(response)) { - this.dispatchEvent(new Event('error')); - this.close(); - } - - this.#reconnect(); - }; - - // 15. Fetch request, with processResponseEndOfBody set to processEventSourceEndOfBody... - fetchParams.processResponseEndOfBody = processEventSourceEndOfBody; - - // and processResponse set to the following steps given response res: - fetchParams.processResponse = (response) => { - // 1. If res is an aborted network error, then fail the connection. - - if (isNetworkError(response)) { - // 1. When a user agent is to fail the connection, the user agent - // must queue a task which, if the readyState attribute is set to a - // value other than CLOSED, sets the readyState attribute to CLOSED - // and fires an event named error at the EventSource object. Once the - // user agent has failed the connection, it does not attempt to - // reconnect. - if (response.aborted) { - this.close(); - this.dispatchEvent(new Event('error')); - return - // 2. Otherwise, if res is a network error, then reestablish the - // connection, unless the user agent knows that to be futile, in - // which case the user agent may fail the connection. - } else { - this.#reconnect(); - return - } - } - - // 3. Otherwise, if res's status is not 200, or if res's `Content-Type` - // is not `text/event-stream`, then fail the connection. - const contentType = response.headersList.get('content-type', true); - const mimeType = contentType !== null ? parseMIMEType(contentType) : 'failure'; - const contentTypeValid = mimeType !== 'failure' && mimeType.essence === 'text/event-stream'; - if ( - response.status !== 200 || - contentTypeValid === false - ) { - this.close(); - this.dispatchEvent(new Event('error')); - return - } - - // 4. Otherwise, announce the connection and interpret res's body - // line by line. - - // When a user agent is to announce the connection, the user agent - // must queue a task which, if the readyState attribute is set to a - // value other than CLOSED, sets the readyState attribute to OPEN - // and fires an event named open at the EventSource object. - // @see https://html.spec.whatwg.org/multipage/server-sent-events.html#sse-processing-model - this.#readyState = OPEN; - this.dispatchEvent(new Event('open')); - - // If redirected to a different origin, set the origin to the new origin. - this.#state.origin = response.urlList[response.urlList.length - 1].origin; - - const eventSourceStream = new EventSourceStream({ - eventSourceSettings: this.#state, - push: (event) => { - this.dispatchEvent(createFastMessageEvent( - event.type, - event.options - )); - } - }); - - pipeline(response.body.stream, - eventSourceStream, - (error) => { - if ( - error?.aborted === false - ) { - this.close(); - this.dispatchEvent(new Event('error')); - } - }); - }; - - this.#controller = fetching(fetchParams); - } - - /** - * @see https://html.spec.whatwg.org/multipage/server-sent-events.html#sse-processing-model - * @returns {Promise} - */ - async #reconnect () { - // When a user agent is to reestablish the connection, the user agent must - // run the following steps. These steps are run in parallel, not as part of - // a task. (The tasks that it queues, of course, are run like normal tasks - // and not themselves in parallel.) - - // 1. Queue a task to run the following steps: - - // 1. If the readyState attribute is set to CLOSED, abort the task. - if (this.#readyState === CLOSED) return - - // 2. Set the readyState attribute to CONNECTING. - this.#readyState = CONNECTING; - - // 3. Fire an event named error at the EventSource object. - this.dispatchEvent(new Event('error')); - - // 2. Wait a delay equal to the reconnection time of the event source. - await delay(this.#state.reconnectionTime); - - // 5. Queue a task to run the following steps: - - // 1. If the EventSource object's readyState attribute is not set to - // CONNECTING, then return. - if (this.#readyState !== CONNECTING) return - - // 2. Let request be the EventSource object's request. - // 3. If the EventSource object's last event ID string is not the empty - // string, then: - // 1. Let lastEventIDValue be the EventSource object's last event ID - // string, encoded as UTF-8. - // 2. Set (`Last-Event-ID`, lastEventIDValue) in request's header - // list. - if (this.#state.lastEventId.length) { - this.#request.headersList.set('last-event-id', this.#state.lastEventId, true); - } - - // 4. Fetch request and process the response obtained in this fashion, if any, as described earlier in this section. - this.#connect(); - } - - /** - * Closes the connection, if any, and sets the readyState attribute to - * CLOSED. - */ - close () { - webidl.brandCheck(this, EventSource); - - if (this.#readyState === CLOSED) return - this.#readyState = CLOSED; - this.#controller.abort(); - this.#request = null; - } - - get onopen () { - return this.#events.open - } - - set onopen (fn) { - if (this.#events.open) { - this.removeEventListener('open', this.#events.open); - } - - if (typeof fn === 'function') { - this.#events.open = fn; - this.addEventListener('open', fn); - } else { - this.#events.open = null; - } - } - - get onmessage () { - return this.#events.message - } - - set onmessage (fn) { - if (this.#events.message) { - this.removeEventListener('message', this.#events.message); - } - - if (typeof fn === 'function') { - this.#events.message = fn; - this.addEventListener('message', fn); - } else { - this.#events.message = null; - } - } - - get onerror () { - return this.#events.error - } - - set onerror (fn) { - if (this.#events.error) { - this.removeEventListener('error', this.#events.error); - } - - if (typeof fn === 'function') { - this.#events.error = fn; - this.addEventListener('error', fn); - } else { - this.#events.error = null; - } - } - } - - const constantsPropertyDescriptors = { - CONNECTING: { - __proto__: null, - configurable: false, - enumerable: true, - value: CONNECTING, - writable: false - }, - OPEN: { - __proto__: null, - configurable: false, - enumerable: true, - value: OPEN, - writable: false - }, - CLOSED: { - __proto__: null, - configurable: false, - enumerable: true, - value: CLOSED, - writable: false - } - }; - - Object.defineProperties(EventSource, constantsPropertyDescriptors); - Object.defineProperties(EventSource.prototype, constantsPropertyDescriptors); - - Object.defineProperties(EventSource.prototype, { - close: kEnumerableProperty, - onerror: kEnumerableProperty, - onmessage: kEnumerableProperty, - onopen: kEnumerableProperty, - readyState: kEnumerableProperty, - url: kEnumerableProperty, - withCredentials: kEnumerableProperty - }); - - webidl.converters.EventSourceInitDict = webidl.dictionaryConverter([ - { - key: 'withCredentials', - converter: webidl.converters.boolean, - defaultValue: () => false - }, - { - key: 'dispatcher', // undici only - converter: webidl.converters.any - } - ]); - - eventsource = { - EventSource, - defaultReconnectionTime - }; - return eventsource; -} - -var hasRequiredUndici; - -function requireUndici () { - if (hasRequiredUndici) return undici; - hasRequiredUndici = 1; - - const Client = requireClient(); - const Dispatcher = requireDispatcher(); - const Pool = requirePool(); - const BalancedPool = requireBalancedPool(); - const Agent = requireAgent(); - const ProxyAgent = requireProxyAgent(); - const EnvHttpProxyAgent = requireEnvHttpProxyAgent(); - const RetryAgent = requireRetryAgent(); - const errors = requireErrors(); - const util = requireUtil$7(); - const { InvalidArgumentError } = errors; - const api = requireApi(); - const buildConnector = requireConnect(); - const MockClient = requireMockClient(); - const MockAgent = requireMockAgent(); - const MockPool = requireMockPool(); - const mockErrors = requireMockErrors(); - const RetryHandler = requireRetryHandler(); - const { getGlobalDispatcher, setGlobalDispatcher } = requireGlobal(); - const DecoratorHandler = requireDecoratorHandler(); - const RedirectHandler = requireRedirectHandler(); - const createRedirectInterceptor = requireRedirectInterceptor(); - - Object.assign(Dispatcher.prototype, api); - - undici.Dispatcher = Dispatcher; - undici.Client = Client; - undici.Pool = Pool; - undici.BalancedPool = BalancedPool; - undici.Agent = Agent; - undici.ProxyAgent = ProxyAgent; - undici.EnvHttpProxyAgent = EnvHttpProxyAgent; - undici.RetryAgent = RetryAgent; - undici.RetryHandler = RetryHandler; - - undici.DecoratorHandler = DecoratorHandler; - undici.RedirectHandler = RedirectHandler; - undici.createRedirectInterceptor = createRedirectInterceptor; - undici.interceptors = { - redirect: requireRedirect(), - retry: requireRetry(), - dump: requireDump() - }; - - undici.buildConnector = buildConnector; - undici.errors = errors; - undici.util = { - parseHeaders: util.parseHeaders, - headerNameToString: util.headerNameToString - }; - - function makeDispatcher (fn) { - return (url, opts, handler) => { - if (typeof opts === 'function') { - handler = opts; - opts = null; - } - - if (!url || (typeof url !== 'string' && typeof url !== 'object' && !(url instanceof URL))) { - throw new InvalidArgumentError('invalid url') - } - - if (opts != null && typeof opts !== 'object') { - throw new InvalidArgumentError('invalid opts') - } - - if (opts && opts.path != null) { - if (typeof opts.path !== 'string') { - throw new InvalidArgumentError('invalid opts.path') - } - - let path = opts.path; - if (!opts.path.startsWith('/')) { - path = `/${path}`; - } - - url = new URL(util.parseOrigin(url).origin + path); - } else { - if (!opts) { - opts = typeof url === 'object' ? url : {}; - } - - url = util.parseURL(url); - } - - const { agent, dispatcher = getGlobalDispatcher() } = opts; - - if (agent) { - throw new InvalidArgumentError('unsupported opts.agent. Did you mean opts.client?') - } - - return fn.call(dispatcher, { - ...opts, - origin: url.origin, - path: url.search ? `${url.pathname}${url.search}` : url.pathname, - method: opts.method || (opts.body ? 'PUT' : 'GET') - }, handler) - } - } - - undici.setGlobalDispatcher = setGlobalDispatcher; - undici.getGlobalDispatcher = getGlobalDispatcher; - - const fetchImpl = requireFetch().fetch; - undici.fetch = async function fetch (init, options = undefined) { - try { - return await fetchImpl(init, options) - } catch (err) { - if (err && typeof err === 'object') { - Error.captureStackTrace(err); - } - - throw err - } - }; - undici.Headers = requireHeaders().Headers; - undici.Response = requireResponse().Response; - undici.Request = requireRequest().Request; - undici.FormData = requireFormdata().FormData; - undici.File = globalThis.File ?? require$$0$3.File; - undici.FileReader = requireFilereader().FileReader; - - const { setGlobalOrigin, getGlobalOrigin } = requireGlobal$1(); - - undici.setGlobalOrigin = setGlobalOrigin; - undici.getGlobalOrigin = getGlobalOrigin; - - const { CacheStorage } = requireCachestorage(); - const { kConstruct } = requireSymbols$1(); - - // Cache & CacheStorage are tightly coupled with fetch. Even if it may run - // in an older version of Node, it doesn't have any use without fetch. - undici.caches = new CacheStorage(kConstruct); - - const { deleteCookie, getCookies, getSetCookies, setCookie } = requireCookies(); - - undici.deleteCookie = deleteCookie; - undici.getCookies = getCookies; - undici.getSetCookies = getSetCookies; - undici.setCookie = setCookie; - - const { parseMIMEType, serializeAMimeType } = requireDataUrl(); - - undici.parseMIMEType = parseMIMEType; - undici.serializeAMimeType = serializeAMimeType; - - const { CloseEvent, ErrorEvent, MessageEvent } = requireEvents(); - undici.WebSocket = requireWebsocket().WebSocket; - undici.CloseEvent = CloseEvent; - undici.ErrorEvent = ErrorEvent; - undici.MessageEvent = MessageEvent; - - undici.request = makeDispatcher(api.request); - undici.stream = makeDispatcher(api.stream); - undici.pipeline = makeDispatcher(api.pipeline); - undici.connect = makeDispatcher(api.connect); - undici.upgrade = makeDispatcher(api.upgrade); - - undici.MockClient = MockClient; - undici.MockPool = MockPool; - undici.MockAgent = MockAgent; - undici.mockErrors = mockErrors; - - const { EventSource } = requireEventsource(); - - undici.EventSource = EventSource; - return undici; -} - -var undiciExports = requireUndici(); - -// For local queue, there is no technical limit on the message visibility lifespan, -// but the environment variable can be used for testing purposes to set a max visibility limit. -const LOCAL_QUEUE_MAX_VISIBILITY = parseInt(process.env.WORKFLOW_LOCAL_QUEUE_MAX_VISIBILITY ?? "0", 10) || - Infinity; -// Create a custom agent with unlimited headers timeout for long-running steps -const httpAgent = new undiciExports.Agent({ - headersTimeout: 0, -}); -function createQueue$1(port) { - const transport = new JsonTransport$1(); - const generateId = monotonicFactory(); - /** - * holds inflight messages by idempotency key to ensure - * that we don't queue the same message multiple times - */ - const inflightMessages = new Map(); - const queue = async (queueName, message, opts) => { - const cleanup = []; - if (opts?.idempotencyKey) { - const existing = inflightMessages.get(opts.idempotencyKey); - if (existing) { - return { messageId: existing }; - } - } - const body = transport.serialize(message); - let pathname; - if (queueName.startsWith("__wkf_step_")) { - pathname = `step`; - } - else if (queueName.startsWith("__wkf_workflow_")) { - pathname = `flow`; - } - else { - throw new Error("Unknown queue name prefix"); - } - const messageId = MessageId.parse(`msg_${generateId()}`); - if (opts?.idempotencyKey) { - const key = opts.idempotencyKey; - inflightMessages.set(key, messageId); - cleanup.push(() => { - inflightMessages.delete(key); - }); - } - (async () => { - let defaultRetriesLeft = 3; - const portToUse = port ?? (await getPort()); - for (let attempt = 0; defaultRetriesLeft > 0; attempt++) { - defaultRetriesLeft--; - const response = await fetch(`http://localhost:${portToUse}/.well-known/workflow/v1/${pathname}`, { - method: "POST", - duplex: "half", - // @ts-expect-error undici type differences - dispatcher: httpAgent, - headers: { - "content-type": "application/json", - "x-vqs-queue-name": queueName, - "x-vqs-message-id": messageId, - "x-vqs-message-attempt": String(attempt + 1), - }, - body, - }); - if (response.ok) { - return; - } - const text = await response.text(); - if (response.status === 503) { - try { - const timeoutSeconds = Number(JSON.parse(text).timeoutSeconds); - await setTimeout$1(timeoutSeconds * 1000); - defaultRetriesLeft++; - continue; - } - catch { } - } - console.error(`[embedded world] Failed to queue message`, { - queueName, - text, - status: response.status, - headers: Object.fromEntries(response.headers.entries()), - body: body.toString(), - }); - } - console.error(`[embedded world] Reached max retries of embedded world queue implementation`); - })().finally(() => { - for (const fn of cleanup) { - fn(); - } - }); - return { messageId }; - }; - const HeaderParser = z__default.object({ - "x-vqs-queue-name": ValidQueueName, - "x-vqs-message-id": MessageId, - "x-vqs-message-attempt": z__default.coerce.number(), - }); - const createQueueHandler = (prefix, handler) => { - return async (req) => { - const headers = HeaderParser.safeParse(Object.fromEntries(req.headers)); - if (!headers.success || !req.body) { - console.log(!headers.success); - console.log(!req.body); - return Response.json({ - error: !req.body - ? "Missing request body" - : "Missing required headers", - }, { status: 400 }); - } - const queueName = headers.data["x-vqs-queue-name"]; - const messageId = headers.data["x-vqs-message-id"]; - const attempt = headers.data["x-vqs-message-attempt"]; - if (!queueName.startsWith(prefix)) { - return Response.json({ error: "Unhandled queue" }, { status: 400 }); - } - const body = await new JsonTransport$1().deserialize(req.body); - try { - const result = await handler(body, { attempt, queueName, messageId }); - let timeoutSeconds = null; - if (typeof result?.timeoutSeconds === "number") { - timeoutSeconds = Math.min(result.timeoutSeconds, LOCAL_QUEUE_MAX_VISIBILITY); - } - if (timeoutSeconds) { - return Response.json({ timeoutSeconds }, { status: 503 }); - } - return Response.json({ ok: true }); - } - catch (error) { - return Response.json(String(error), { status: 500 }); - } - }; - }; - const getDeploymentId = async () => { - return "dpl_embedded"; - }; - return { queue, createQueueHandler, getDeploymentId }; -} - -const ulid = monotonicFactory(() => Math.random()); -const Ulid = z$1.string().ulid(); -function ulidToDate(maybeUlid) { - const ulid = Ulid.safeParse(maybeUlid); - if (!ulid.success) { - return null; - } - return new Date(decodeTime(ulid.data)); -} -async function ensureDir(dirPath) { - try { - await promises.mkdir(dirPath, { recursive: true }); - } - catch (_error) { - // Ignore if already exists - } -} -async function writeJSON(filePath, data, opts) { - return write(filePath, JSON.stringify(data, null, 2), opts); -} -async function write(filePath, data, opts) { - if (!opts?.overwrite) { - try { - await promises.access(filePath); - throw new WorkflowAPIError(`File ${filePath} already exists and 'overwrite' is false`, { status: 409 }); - } - catch (error) { - // If file doesn't exist (ENOENT), continue with write - if (error.code !== 'ENOENT') { - throw error; - } - } - } - const tempPath = `${filePath}.tmp.${ulid()}`; - try { - await ensureDir(path.dirname(filePath)); - await promises.writeFile(tempPath, data); - await promises.rename(tempPath, filePath); - } - catch (error) { - await promises.unlink(tempPath).catch(() => { }); - throw error; - } -} -async function readJSON(filePath, decoder) { - try { - const content = await promises.readFile(filePath, 'utf-8'); - return decoder.parse(JSON.parse(content)); - } - catch (error) { - if (error.code === 'ENOENT') - return null; - throw error; - } -} -async function readBuffer(filePath) { - const content = await promises.readFile(filePath); - return content; -} -async function deleteJSON(filePath) { - try { - await promises.unlink(filePath); - } - catch (error) { - if (error.code !== 'ENOENT') - throw error; - } -} -async function listJSONFiles(dirPath) { - try { - const files = await promises.readdir(dirPath); - return files - .filter((f) => f.endsWith('.json')) - .map((f) => f.replace('.json', '')); - } - catch (error) { - if (error.code === 'ENOENT') - return []; - throw error; - } -} -function parseCursor(cursor) { - if (!cursor) - return null; - const parts = cursor.split('|'); - return { - timestamp: new Date(parts[0]), - id: parts[1] || null, - }; -} -function createCursor(timestamp, id) { - return id ? `${timestamp.toISOString()}|${id}` : timestamp.toISOString(); -} -async function paginatedFileSystemQuery(config) { - const { directory, schema, filePrefix, filter, sortOrder = 'desc', limit = 20, cursor, getCreatedAt, getId, } = config; - // 1. Get all JSON files in directory - const fileIds = await listJSONFiles(directory); - // 2. Filter by prefix if provided - const relevantFileIds = filePrefix - ? fileIds.filter((fileId) => fileId.startsWith(filePrefix)) - : fileIds; - // 3. ULID Optimization: Filter by cursor using filename timestamps before loading JSON - const parsedCursor = parseCursor(cursor); - let candidateFileIds = relevantFileIds; - if (parsedCursor) { - candidateFileIds = relevantFileIds.filter((fileId) => { - const filenameDate = getCreatedAt(`${fileId}.json`); - if (filenameDate) { - // Use filename timestamp for cursor filtering - // We need to be careful here: if parsedCursor has an ID (for tie-breaking), - // we need to include items with the same timestamp for later ID-based filtering. - // If no ID, we can use strict inequality for optimization. - const cursorTime = parsedCursor.timestamp.getTime(); - const fileTime = filenameDate.getTime(); - if (parsedCursor.id) { - // Tie-breaking mode: include items at or near cursor timestamp - return sortOrder === 'desc' - ? fileTime <= cursorTime - : fileTime >= cursorTime; - } - else { - // No tie-breaking: strict inequality - return sortOrder === 'desc' - ? fileTime < cursorTime - : fileTime > cursorTime; - } - } - // Skip files where we can't extract timestamp - no optimization benefit - return false; - }); - } - else { - // Even without cursor, skip files where getCreatedAt returns null for consistency - candidateFileIds = relevantFileIds.filter((fileId) => { - return getCreatedAt(`${fileId}.json`) !== null; - }); - } - // 4. Load files individually and collect valid items - const validItems = []; - for (const fileId of candidateFileIds) { - const filePath = path.join(directory, `${fileId}.json`); - const item = await readJSON(filePath, schema); - if (item) { - // Apply custom filter early if provided - if (filter && !filter(item)) - continue; - // Double-check cursor filtering with actual createdAt from JSON - // (in case ULID timestamp differs from stored createdAt) - if (parsedCursor) { - const itemTime = item.createdAt.getTime(); - const cursorTime = parsedCursor.timestamp.getTime(); - if (sortOrder === 'desc') { - // For descending order, skip items >= cursor - if (itemTime > cursorTime) - continue; - // If timestamps are equal, use ID for tie-breaking (skip if ID >= cursorId) - if (itemTime === cursorTime && parsedCursor.id && getId) { - const itemId = getId(item); - if (itemId >= parsedCursor.id) - continue; - } - } - else { - // For ascending order, skip items <= cursor - if (itemTime < cursorTime) - continue; - // If timestamps are equal, use ID for tie-breaking (skip if ID <= cursorId) - if (itemTime === cursorTime && parsedCursor.id && getId) { - const itemId = getId(item); - if (itemId <= parsedCursor.id) - continue; - } - } - } - validItems.push(item); - } - } - // 5. Sort by createdAt (and by ID for tie-breaking if getId is provided) - validItems.sort((a, b) => { - const aTime = a.createdAt.getTime(); - const bTime = b.createdAt.getTime(); - const timeComparison = sortOrder === 'asc' ? aTime - bTime : bTime - aTime; - // If timestamps are equal and we have getId, use ID for stable sorting - if (timeComparison === 0 && getId) { - const aId = getId(a); - const bId = getId(b); - return sortOrder === 'asc' - ? aId.localeCompare(bId) - : bId.localeCompare(aId); - } - return timeComparison; - }); - // 6. Apply pagination - const hasMore = validItems.length > limit; - const items = hasMore ? validItems.slice(0, limit) : validItems; - const nextCursor = items.length > 0 - ? createCursor(items[items.length - 1].createdAt, getId?.(items[items.length - 1])) - : null; - return { - data: items, - cursor: nextCursor, - hasMore, - }; -} - -// Create a monotonic ULID factory that ensures ULIDs are always increasing -// even when generated within the same millisecond -const monotonicUlid$1 = monotonicFactory(() => Math.random()); -// Helper functions to filter data based on resolveData setting -function filterRunData$1(run, resolveData) { - if (resolveData === 'none') { - return { - ...run, - input: [], - output: undefined, - }; - } - return run; -} -function filterStepData$1(step, resolveData) { - if (resolveData === 'none') { - return { - ...step, - input: [], - output: undefined, - }; - } - return step; -} -function filterEventData$1(event, resolveData) { - if (resolveData === 'none') { - const { eventData: _eventData, ...rest } = event; - return rest; - } - return event; -} -function filterHookData$1(hook, resolveData) { - if (resolveData === 'none') { - const { metadata: _metadata, ...rest } = hook; - return rest; - } - return hook; -} -const getObjectCreatedAt = (idPrefix) => (filename) => { - const replaceRegex = new RegExp(`^${idPrefix}_`, 'g'); - const dashIndex = filename.indexOf('-'); - if (dashIndex === -1) { - // No dash - extract ULID from the filename (e.g., wrun_ULID.json, evnt_ULID.json) - const ulid = filename.replace(/\.json$/, '').replace(replaceRegex, ''); - return ulidToDate(ulid); - } - // For composite keys like {runId}-{stepId}, extract from the appropriate part - if (idPrefix === 'step') { - // For steps: wrun_ULID-step_123.json - extract from the runId part - const runId = filename.substring(0, dashIndex); - const ulid = runId.replace(/^wrun_/, ''); - return ulidToDate(ulid); - } - // For events: wrun_ULID-evnt_ULID.json - extract from the eventId part - const id = filename.substring(dashIndex + 1).replace(/\.json$/, ''); - const ulid = id.replace(replaceRegex, ''); - return ulidToDate(ulid); -}; -/** - * Creates a hooks storage implementation using the filesystem. - * Implements the Storage['hooks'] interface with hook CRUD operations. - */ -function createHooksStorage(basedir) { - // Helper function to find a hook by token (shared between create and getByToken) - async function findHookByToken(token) { - const hooksDir = path.join(basedir, 'hooks'); - const files = await listJSONFiles(hooksDir); - for (const file of files) { - const hookPath = path.join(hooksDir, `${file}.json`); - const hook = await readJSON(hookPath, HookSchema); - if (hook && hook.token === token) { - return hook; - } - } - return null; - } - async function create(runId, data) { - // Check if a hook with the same token already exists - // Token uniqueness is enforced globally per embedded environment - const existingHook = await findHookByToken(data.token); - if (existingHook) { - throw new Error(`Hook with token ${data.token} already exists for this project`); - } - const now = new Date(); - const result = { - runId, - hookId: data.hookId, - token: data.token, - metadata: data.metadata, - ownerId: 'embedded-owner', - projectId: 'embedded-project', - environment: 'embedded', - createdAt: now, - }; - const hookPath = path.join(basedir, 'hooks', `${data.hookId}.json`); - await writeJSON(hookPath, result); - return result; - } - async function get(hookId, params) { - const hookPath = path.join(basedir, 'hooks', `${hookId}.json`); - const hook = await readJSON(hookPath, HookSchema); - if (!hook) { - throw new Error(`Hook ${hookId} not found`); - } - const resolveData = params?.resolveData || DEFAULT_RESOLVE_DATA_OPTION$1; - return filterHookData$1(hook, resolveData); - } - async function getByToken(token) { - const hook = await findHookByToken(token); - if (!hook) { - throw new Error(`Hook with token ${token} not found`); - } - return hook; - } - async function list(params) { - const hooksDir = path.join(basedir, 'hooks'); - const resolveData = params.resolveData || DEFAULT_RESOLVE_DATA_OPTION$1; - const result = await paginatedFileSystemQuery({ - directory: hooksDir, - schema: HookSchema, - sortOrder: params.pagination?.sortOrder, - limit: params.pagination?.limit, - cursor: params.pagination?.cursor, - filePrefix: undefined, // Hooks don't have ULIDs, so we can't optimize by filename - filter: (hook) => { - // Filter by runId if provided - if (params.runId && hook.runId !== params.runId) { - return false; - } - return true; - }, - getCreatedAt: () => { - // Hook files don't have ULID timestamps in filename - // We need to read the file to get createdAt, but that's inefficient - // So we return the hook's createdAt directly (item.createdAt will be used for sorting) - // Return a dummy date to pass the null check, actual sorting uses item.createdAt - return new Date(0); - }, - getId: (hook) => hook.hookId, - }); - // Transform the data after pagination - return { - ...result, - data: result.data.map((hook) => filterHookData$1(hook, resolveData)), - }; - } - async function dispose(hookId) { - const hookPath = path.join(basedir, 'hooks', `${hookId}.json`); - const hook = await readJSON(hookPath, HookSchema); - if (!hook) { - throw new Error(`Hook ${hookId} not found`); - } - await deleteJSON(hookPath); - return hook; - } - return { create, get, getByToken, list, dispose }; -} -/** - * Helper function to delete all hooks associated with a workflow run - */ -async function deleteAllHooksForRun(basedir, runId) { - const hooksDir = path.join(basedir, 'hooks'); - const files = await listJSONFiles(hooksDir); - for (const file of files) { - const hookPath = path.join(hooksDir, `${file}.json`); - const hook = await readJSON(hookPath, HookSchema); - if (hook && hook.runId === runId) { - await deleteJSON(hookPath); - } - } -} -function createStorage$1(basedir) { - return { - runs: { - async create(data) { - const runId = `wrun_${monotonicUlid$1()}`; - const now = new Date(); - const result = { - runId, - deploymentId: data.deploymentId, - status: 'pending', - workflowName: data.workflowName, - executionContext: data.executionContext, - input: data.input || [], - output: undefined, - error: undefined, - startedAt: undefined, - completedAt: undefined, - createdAt: now, - updatedAt: now, - }; - const runPath = path.join(basedir, 'runs', `${runId}.json`); - await writeJSON(runPath, result); - return result; - }, - async get(id, params) { - const runPath = path.join(basedir, 'runs', `${id}.json`); - const run = await readJSON(runPath, WorkflowRunSchema); - if (!run) { - throw new WorkflowRunNotFoundError(id); - } - const resolveData = params?.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION$1; - return filterRunData$1(run, resolveData); - }, - async update(id, data) { - const runPath = path.join(basedir, 'runs', `${id}.json`); - const run = await readJSON(runPath, WorkflowRunSchema); - if (!run) { - throw new WorkflowRunNotFoundError(id); - } - const now = new Date(); - const updatedRun = { - ...run, - ...data, - updatedAt: now, - }; - // Only set startedAt the first time the run transitions to 'running' - if (data.status === 'running' && !updatedRun.startedAt) { - updatedRun.startedAt = now; - } - const isBecomingTerminal = data.status === 'completed' || - data.status === 'failed' || - data.status === 'cancelled'; - if (isBecomingTerminal) { - updatedRun.completedAt = now; - } - await writeJSON(runPath, updatedRun, { overwrite: true }); - // If transitioning to a terminal status, clean up all hooks for this run - if (isBecomingTerminal) { - await deleteAllHooksForRun(basedir, id); - } - return updatedRun; - }, - async list(params) { - const resolveData = params?.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION$1; - const result = await paginatedFileSystemQuery({ - directory: path.join(basedir, 'runs'), - schema: WorkflowRunSchema, - filter: (run) => { - if (params?.workflowName && - run.workflowName !== params.workflowName) { - return false; - } - if (params?.status && run.status !== params.status) { - return false; - } - return true; - }, - sortOrder: params?.pagination?.sortOrder ?? 'desc', - limit: params?.pagination?.limit, - cursor: params?.pagination?.cursor, - getCreatedAt: getObjectCreatedAt('wrun'), - getId: (run) => run.runId, - }); - // If resolveData is "none", replace input/output with empty data - if (resolveData === 'none') { - return { - ...result, - data: result.data.map((run) => ({ - ...run, - input: [], - output: undefined, - })), - }; - } - return result; - }, - async cancel(id, params) { - // This will call update which triggers hook cleanup automatically - const run = await this.update(id, { status: 'cancelled' }); - const resolveData = params?.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION$1; - return filterRunData$1(run, resolveData); - }, - async pause(id, params) { - const run = await this.update(id, { status: 'paused' }); - const resolveData = params?.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION$1; - return filterRunData$1(run, resolveData); - }, - async resume(id, params) { - const run = await this.update(id, { status: 'running' }); - const resolveData = params?.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION$1; - return filterRunData$1(run, resolveData); - }, - }, - steps: { - async create(runId, data) { - const now = new Date(); - const result = { - runId, - stepId: data.stepId, - stepName: data.stepName, - status: 'pending', - input: data.input, - output: undefined, - error: undefined, - attempt: 0, - startedAt: undefined, - completedAt: undefined, - createdAt: now, - updatedAt: now, - }; - const compositeKey = `${runId}-${data.stepId}`; - const stepPath = path.join(basedir, 'steps', `${compositeKey}.json`); - await writeJSON(stepPath, result); - return result; - }, - async get(runId, stepId, params) { - if (!runId) { - const fileIds = await listJSONFiles(path.join(basedir, 'steps')); - const fileId = fileIds.find((fileId) => fileId.endsWith(`-${stepId}`)); - if (!fileId) { - throw new Error(`Step ${stepId} not found`); - } - runId = fileId.split('-')[0]; - } - const compositeKey = `${runId}-${stepId}`; - const stepPath = path.join(basedir, 'steps', `${compositeKey}.json`); - const step = await readJSON(stepPath, StepSchema); - if (!step) { - throw new Error(`Step ${stepId} in run ${runId} not found`); - } - const resolveData = params?.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION$1; - return filterStepData$1(step, resolveData); - }, - async update(runId, stepId, data) { - const compositeKey = `${runId}-${stepId}`; - const stepPath = path.join(basedir, 'steps', `${compositeKey}.json`); - const step = await readJSON(stepPath, StepSchema); - if (!step) { - throw new Error(`Step ${stepId} in run ${runId} not found`); - } - const now = new Date(); - const updatedStep = { - ...step, - ...data, - updatedAt: now, - }; - // Only set startedAt the first time the step transitions to 'running' - if (data.status === 'running' && !updatedStep.startedAt) { - updatedStep.startedAt = now; - } - if (data.status === 'completed' || data.status === 'failed') { - updatedStep.completedAt = now; - } - await writeJSON(stepPath, updatedStep, { overwrite: true }); - return updatedStep; - }, - async list(params) { - const resolveData = params.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION$1; - const result = await paginatedFileSystemQuery({ - directory: path.join(basedir, 'steps'), - schema: StepSchema, - filePrefix: `${params.runId}-`, - sortOrder: params.pagination?.sortOrder ?? 'desc', - limit: params.pagination?.limit, - cursor: params.pagination?.cursor, - getCreatedAt: getObjectCreatedAt('step'), - getId: (step) => step.stepId, - }); - // If resolveData is "none", replace input/output with empty data - if (resolveData === 'none') { - return { - ...result, - data: result.data.map((step) => ({ - ...step, - input: [], - output: undefined, - })), - }; - } - return result; - }, - }, - // Events - filesystem-backed storage - events: { - async create(runId, data, params) { - const eventId = `evnt_${monotonicUlid$1()}`; - const now = new Date(); - const result = { - ...data, - runId, - eventId, - createdAt: now, - }; - // Store event using composite key {runId}-{eventId} - const compositeKey = `${runId}-${eventId}`; - const eventPath = path.join(basedir, 'events', `${compositeKey}.json`); - await writeJSON(eventPath, result); - const resolveData = params?.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION$1; - return filterEventData$1(result, resolveData); - }, - async list(params) { - const { runId } = params; - const resolveData = params.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION$1; - const result = await paginatedFileSystemQuery({ - directory: path.join(basedir, 'events'), - schema: EventSchema, - filePrefix: `${runId}-`, - // Events in chronological order (oldest first) by default, - // different from the default for other list calls. - sortOrder: params.pagination?.sortOrder ?? 'asc', - limit: params.pagination?.limit, - cursor: params.pagination?.cursor, - getCreatedAt: getObjectCreatedAt('evnt'), - getId: (event) => event.eventId, - }); - // If resolveData is "none", remove eventData from events - if (resolveData === 'none') { - return { - ...result, - data: result.data.map((event) => { - const { eventData: _eventData, ...rest } = event; - return rest; - }), - }; - } - return result; - }, - async listByCorrelationId(params) { - const correlationId = params.correlationId; - const resolveData = params.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION$1; - const result = await paginatedFileSystemQuery({ - directory: path.join(basedir, 'events'), - schema: EventSchema, - // No filePrefix - search all events - filter: (event) => event.correlationId === correlationId, - // Events in chronological order (oldest first) by default, - // different from the default for other list calls. - sortOrder: params.pagination?.sortOrder ?? 'asc', - limit: params.pagination?.limit, - cursor: params.pagination?.cursor, - getCreatedAt: getObjectCreatedAt('evnt'), - getId: (event) => event.eventId, - }); - // If resolveData is "none", remove eventData from events - if (resolveData === 'none') { - return { - ...result, - data: result.data.map((event) => { - const { eventData: _eventData, ...rest } = event; - return rest; - }), - }; - } - return result; - }, - }, - // Hooks - hooks: createHooksStorage(basedir), - }; -} - -// Create a monotonic ULID factory that ensures ULIDs are always increasing -// even when generated within the same millisecond -const monotonicUlid = monotonicFactory(() => Math.random()); -function serializeChunk(chunk) { - const eofByte = Buffer.from([chunk.eof ? 1 : 0]); - return Buffer.concat([eofByte, chunk.chunk]); -} -function deserializeChunk(serialized) { - const eof = serialized[0] === 1; - const chunk = serialized.subarray(1); - return { eof, chunk }; -} -function createStreamer$1(basedir) { - const streamEmitter = new EventEmitter(); - return { - async writeToStream(name, chunk) { - const chunkId = `strm_${monotonicUlid()}`; - if (typeof chunk === 'string') { - chunk = new TextEncoder().encode(chunk); - } - const serialized = serializeChunk({ - chunk: Buffer.from(chunk), - eof: false, - }); - const chunkPath = path.join(basedir, 'streams', 'chunks', `${name}-${chunkId}.json`); - await write(chunkPath, serialized); - // Emit real-time event - const chunkData = typeof chunk === 'string' - ? new TextEncoder().encode(chunk) - : chunk instanceof Buffer - ? new Uint8Array(chunk) - : chunk; - streamEmitter.emit(`chunk:${name}`, { - streamName: name, - chunkData, - chunkId, - }); - }, - async closeStream(name) { - const chunkId = `strm_${monotonicUlid()}`; - const chunkPath = path.join(basedir, 'streams', 'chunks', `${name}-${chunkId}.json`); - await write(chunkPath, serializeChunk({ chunk: Buffer.from([]), eof: true })); - streamEmitter.emit(`close:${name}`, { streamName: name }); - }, - async readFromStream(name, startIndex = 0) { - const chunksDir = path.join(basedir, 'streams', 'chunks'); - let removeListeners = () => { }; - return new ReadableStream({ - async start(controller) { - // Track chunks delivered via events to prevent duplicates and maintain order. - const deliveredChunkIds = new Set(); - // Buffer for chunks that arrive via events during disk reading - const bufferedEventChunks = []; - let isReadingFromDisk = true; - const chunkListener = (event) => { - deliveredChunkIds.add(event.chunkId); - if (isReadingFromDisk) { - // Buffer chunks that arrive during disk reading to maintain order - bufferedEventChunks.push({ - chunkId: event.chunkId, - chunkData: event.chunkData, - }); - } - else { - // After disk reading is complete, deliver chunks immediately - controller.enqueue(event.chunkData); - } - }; - const closeListener = () => { - // Remove listeners before closing - streamEmitter.off(`chunk:${name}`, chunkListener); - streamEmitter.off(`close:${name}`, closeListener); - controller.close(); - }; - removeListeners = closeListener; - // Set up listeners FIRST to avoid missing events - streamEmitter.on(`chunk:${name}`, chunkListener); - streamEmitter.on(`close:${name}`, closeListener); - // Now load existing chunks from disk - const files = await listJSONFiles(chunksDir); - const chunkFiles = files - .filter((file) => file.startsWith(`${name}-`)) - .sort(); // ULID lexicographic sort = chronological order - // Process existing chunks, skipping any already delivered via events - let isComplete = false; - for (let i = startIndex; i < chunkFiles.length; i++) { - const file = chunkFiles[i]; - // Extract chunk ID from filename: "streamName-chunkId" - const chunkId = file.substring(name.length + 1); - // Skip if already delivered via event - if (deliveredChunkIds.has(chunkId)) { - continue; - } - const chunk = deserializeChunk(await readBuffer(path.join(chunksDir, `${file}.json`))); - if (chunk?.eof === true) { - isComplete = true; - break; - } - if (chunk.chunk.byteLength) { - controller.enqueue(chunk.chunk); - } - } - // Finished reading from disk - now deliver buffered event chunks in chronological order - isReadingFromDisk = false; - // Sort buffered chunks by ULID (chronological order) - bufferedEventChunks.sort((a, b) => a.chunkId.localeCompare(b.chunkId)); - for (const buffered of bufferedEventChunks) { - controller.enqueue(buffered.chunkData); - } - if (isComplete) { - removeListeners(); - controller.close(); - return; - } - }, - cancel() { - removeListeners(); - }, - }); - }, - }; -} - -/** - * Creates an embedded world instance that combines queue, storage, and streamer functionalities. - * - * @param dataDir - The directory to use for storage. If not provided, the default data dir will be used. - * @param port - The port to use for the queue. If not provided, the default port will be used. - */ -function createEmbeddedWorld({ dataDir, port, }) { - const dir = dataDir ?? config.value.dataDir; - const queuePort = port ?? config.value.port; - return { - ...createQueue$1(queuePort), - ...createStorage$1(dir), - ...createStreamer$1(dir), - }; -} - -// src/parser.ts -var MultipartParseError = class extends Error { - constructor(message) { - super(message); - this.name = "MultipartParseError"; - } -}; -function createSearch(pattern) { - const needle = new TextEncoder().encode(pattern); - return (haystack, start = 0) => Buffer.prototype.indexOf.call(haystack, needle, start); -} -function createPartialTailSearch(pattern) { - const needle = new TextEncoder().encode(pattern); - const byteIndexes = {}; - for (let i = 0; i < needle.length; ++i) { - const byte = needle[i]; - if (byteIndexes[byte] === void 0) byteIndexes[byte] = []; - byteIndexes[byte].push(i); - } - return function(haystack) { - const haystackEnd = haystack.length - 1; - if (haystack[haystackEnd] in byteIndexes) { - const indexes = byteIndexes[haystack[haystackEnd]]; - for (let i = indexes.length - 1; i >= 0; --i) { - for (let j = indexes[i], k = haystackEnd; j >= 0 && haystack[k] === needle[j]; --j, --k) { - if (j === 0) return k; - } - } - } - return -1; - }; -} -function parseHeaders(headerBytes) { - const headerText = new TextDecoder("iso-8859-1").decode(headerBytes); - const lines = headerText.trim().split(/\r?\n/); - const headerInit = []; - for (const line of lines) { - const colonIndex = line.indexOf(":"); - if (colonIndex > 0) { - const name = line.slice(0, colonIndex).trim(); - const value = line.slice(colonIndex + 1).trim(); - headerInit.push([name, value]); - } - } - return new Headers(headerInit); -} -function extractBoundary(contentType) { - const boundaryMatch = contentType.match(/boundary=(?:"([^"]+)"|([^;]+))/i); - if (!boundaryMatch) { - throw new MultipartParseError("No boundary found in Content-Type header"); - } - return boundaryMatch[1] ?? boundaryMatch[2]; -} -var AsyncMessageQueue = class { - queue = []; - waiters = []; - finished = false; - cancelled = false; - error = null; - /** - * Producer: Enqueue a message for consumption - */ - enqueue(message) { - if (this.finished || this.cancelled) return; - if (this.waiters.length > 0) { - const waiter = this.waiters.shift(); - waiter.resolve(message); - } else { - this.queue.push(message); - } - } - /** - * Producer: Signal completion (with optional error) - */ - finish(error) { - if (this.finished) return; - this.finished = true; - this.error = error || null; - while (this.waiters.length > 0) { - const waiter = this.waiters.shift(); - if (error) { - waiter.reject(error); - } else { - waiter.resolve(null); - } - } - } - /** - * Consumer: Cancel the queue (stops accepting new messages and notifies waiters) - */ - cancel() { - if (this.cancelled || this.finished) return; - this.cancelled = true; - while (this.waiters.length > 0) { - const waiter = this.waiters.shift(); - waiter.resolve(null); - } - } - /** - * Consumer: Dequeue next message (or null if finished/cancelled) - */ - async dequeue() { - if (this.queue.length > 0) { - return this.queue.shift(); - } - if (this.finished || this.cancelled) { - if (this.error) throw this.error; - return null; - } - return new Promise((resolve, reject) => { - this.waiters.push({ resolve, reject }); - }); - } - /** - * Check if the queue is in a terminal state - */ - get isTerminal() { - return this.finished || this.cancelled; - } -}; -async function* parseMultipartStream(response, options) { - if (!response.body) { - throw new MultipartParseError("Response body is null"); - } - const contentType = response.headers.get("content-type"); - if (!contentType) { - throw new MultipartParseError("Missing Content-Type header"); - } - const boundary = extractBoundary(contentType); - const parser = new StreamingMultipartParser(boundary, options); - yield* parser.parseStream(response.body); -} -var StreamingMultipartParser = class { - boundary; - findOpeningBoundary; - openingBoundaryLength; - findBoundary; - findPartialTailBoundary; - boundaryLength; - findDoubleNewline; - // Safety limits - maxHeaderSize; - maxBoundaryBuffer; - state = 0 /* Start */; - buffer = null; - currentHeaders = new Headers(); - currentPayloadController = null; - constructor(boundary, options = {}) { - this.boundary = boundary; - this.findOpeningBoundary = createSearch(`--${boundary}`); - this.openingBoundaryLength = 2 + boundary.length; - this.findBoundary = createSearch(`\r ---${boundary}`); - this.findPartialTailBoundary = createPartialTailSearch(`\r ---${boundary}`); - this.boundaryLength = 4 + boundary.length; - this.findDoubleNewline = createSearch("\r\n\r\n"); - this.maxHeaderSize = options.maxHeaderSize ?? 65536; - this.maxBoundaryBuffer = options.maxBoundaryBuffer ?? 8192; - } - async *parseStream(stream) { - const reader = stream.getReader(); - const messageQueue = new AsyncMessageQueue(); - const producer = this.startProducer(reader, messageQueue); - try { - yield* this.consumeMessages(messageQueue); - } finally { - messageQueue.cancel(); - this.closeCurrentPayload(); - try { - await reader.cancel(); - } catch (error) { - } - await producer; - } - } - /** - * Producer: Continuously read chunks and parse messages - */ - async startProducer(reader, messageQueue) { - try { - while (!messageQueue.isTerminal) { - let result; - try { - result = await reader.read(); - } catch (readError) { - if (readError instanceof Error && (readError.name === "AbortError" || readError.constructor.name === "AbortError" || readError.name === "TimeoutError" || readError.constructor.name === "TimeoutError")) { - break; - } - throw readError; - } - const { done, value } = result; - if (done) { - if (this.buffer !== null && this.buffer.length > 0) { - const messages2 = this.write(new Uint8Array(0)); - for (const message of messages2) { - if (messageQueue.isTerminal) break; - messageQueue.enqueue(message); - } - } - if (this.state !== 4 /* Done */) { - if (this.state === 0 /* Start */) { - throw new MultipartParseError( - "Invalid multipart stream: missing initial boundary" - ); - } - throw new MultipartParseError("Unexpected end of stream"); - } - break; - } - if (!(value instanceof Uint8Array)) { - throw new MultipartParseError( - `Invalid chunk type: expected Uint8Array, got ${typeof value}` - ); - } - const messages = this.write(value); - for (const message of messages) { - if (messageQueue.isTerminal) break; - messageQueue.enqueue(message); - } - } - if (!messageQueue.isTerminal) { - messageQueue.finish(); - } - } catch (error) { - this.closeCurrentPayload(error); - if (!messageQueue.isTerminal) { - messageQueue.finish(error); - } - } finally { - try { - reader.releaseLock(); - } catch (error) { - } - } - } - /** - * Consumer: Yield messages from the queue - */ - async *consumeMessages(messageQueue) { - while (true) { - const message = await messageQueue.dequeue(); - if (message === null) { - break; - } - yield message; - } - } - /** - * Process a chunk of data through the state machine and return any complete messages. - * - * Returns an array because a single chunk can contain multiple complete messages - * when small messages with headers + body + boundary all fit in one network chunk. - * All messages must be captured and queued to maintain proper message ordering. - */ - write(chunk) { - const newMessages = []; - if (this.state === 4 /* Done */) { - throw new MultipartParseError("Unexpected data after end of stream"); - } - let index = 0; - let chunkLength = chunk.length; - if (this.buffer !== null) { - const newSize = this.buffer.length + chunkLength; - const maxAllowedSize = this.state === 2 /* Header */ ? this.maxHeaderSize : this.maxBoundaryBuffer; - if (newSize > maxAllowedSize) { - throw new MultipartParseError( - `Buffer size limit exceeded: ${newSize} bytes > ${maxAllowedSize} bytes. This may indicate malformed multipart data with ${this.state === 2 /* Header */ ? "oversized headers" : "invalid boundaries"}.` - ); - } - const newChunk = new Uint8Array(newSize); - newChunk.set(this.buffer, 0); - newChunk.set(chunk, this.buffer.length); - chunk = newChunk; - chunkLength = chunk.length; - this.buffer = null; - } - if (chunkLength === 0 && this.state === 0 /* Start */) { - throw new MultipartParseError( - "Invalid multipart stream: missing initial boundary" - ); - } - while (true) { - if (this.state === 3 /* Body */) { - if (chunkLength - index < this.boundaryLength) { - const remainingData = chunk.subarray(index); - if (remainingData.length > this.maxBoundaryBuffer) { - throw new MultipartParseError( - `Boundary buffer limit exceeded: ${remainingData.length} > ${this.maxBoundaryBuffer}` - ); - } - this.buffer = remainingData; - break; - } - const boundaryIndex = this.findBoundary(chunk, index); - if (boundaryIndex === -1) { - const partialTailIndex = this.findPartialTailBoundary(chunk); - if (partialTailIndex === -1) { - this.writeBody(index === 0 ? chunk : chunk.subarray(index)); - } else { - this.writeBody(chunk.subarray(index, partialTailIndex)); - const partialBoundary = chunk.subarray(partialTailIndex); - if (partialBoundary.length > this.maxBoundaryBuffer) { - throw new MultipartParseError( - `Partial boundary too large: ${partialBoundary.length} > ${this.maxBoundaryBuffer}` - ); - } - this.buffer = partialBoundary; - } - break; - } - this.writeBody(chunk.subarray(index, boundaryIndex)); - this.finishMessage(); - index = boundaryIndex + this.boundaryLength; - this.state = 1 /* AfterBoundary */; - } - if (this.state === 1 /* AfterBoundary */) { - if (chunkLength - index < 2) { - const remainingData = chunk.subarray(index); - if (remainingData.length > this.maxBoundaryBuffer) { - throw new MultipartParseError( - `After-boundary buffer limit exceeded: ${remainingData.length} > ${this.maxBoundaryBuffer}` - ); - } - this.buffer = remainingData; - break; - } - if (chunk[index] === 45 && chunk[index + 1] === 45) { - this.state = 4 /* Done */; - break; - } - if (chunk[index] === 13 && chunk[index + 1] === 10) { - index += 2; - } else if (chunk[index] === 10) { - index += 1; - } else { - throw new MultipartParseError( - `Invalid character after boundary: expected CRLF or LF, got 0x${chunk[index].toString(16)}` - ); - } - this.state = 2 /* Header */; - } - if (this.state === 2 /* Header */) { - if (chunkLength - index < 4) { - const remainingData = chunk.subarray(index); - if (remainingData.length > this.maxHeaderSize) { - throw new MultipartParseError( - `Header buffer limit exceeded: ${remainingData.length} > ${this.maxHeaderSize}` - ); - } - this.buffer = remainingData; - break; - } - let headerEndIndex = this.findDoubleNewline(chunk, index); - let headerEndOffset = 4; - if (headerEndIndex === -1) { - const lfDoubleNewline = createSearch("\n\n"); - headerEndIndex = lfDoubleNewline(chunk, index); - headerEndOffset = 2; - } - if (headerEndIndex === -1) { - const headerData = chunk.subarray(index); - if (headerData.length > this.maxHeaderSize) { - throw new MultipartParseError( - `Headers too large: ${headerData.length} > ${this.maxHeaderSize} bytes` - ); - } - this.buffer = headerData; - break; - } - const headerBytes = chunk.subarray(index, headerEndIndex); - this.currentHeaders = parseHeaders(headerBytes); - const message = this.createStreamingMessage(); - newMessages.push(message); - index = headerEndIndex + headerEndOffset; - this.state = 3 /* Body */; - continue; - } - if (this.state === 0 /* Start */) { - if (chunkLength < this.openingBoundaryLength) { - if (chunk.length > this.maxBoundaryBuffer) { - throw new MultipartParseError( - `Initial chunk too large for boundary detection: ${chunk.length} > ${this.maxBoundaryBuffer}` - ); - } - this.buffer = chunk; - break; - } - const boundaryIndex = this.findOpeningBoundary(chunk); - if (boundaryIndex !== 0) { - throw new MultipartParseError( - "Invalid multipart stream: missing initial boundary" - ); - } - index = this.openingBoundaryLength; - this.state = 1 /* AfterBoundary */; - } - } - return newMessages; - } - createStreamingMessage() { - const headers = new Headers(this.currentHeaders); - const payload = new ReadableStream({ - start: (controller) => { - this.currentPayloadController = controller; - } - }); - this.currentHeaders = new Headers(); - return { - headers, - payload - }; - } - writeBody(chunk) { - if (this.currentPayloadController) { - this.currentPayloadController.enqueue(chunk); - } - } - finishMessage() { - if (this.currentPayloadController) { - this.currentPayloadController.close(); - this.currentPayloadController = null; - } - } - /** - * Close current payload controller if open (used during cleanup) - * If an error is provided, forwards it to the payload consumer - */ - closeCurrentPayload(error) { - if (this.currentPayloadController) { - try { - if (error) { - this.currentPayloadController.error(error); - } else { - this.currentPayloadController.close(); - } - } catch (controllerError) { - } - this.currentPayloadController = null; - } - } -}; - -var getContext_1; -var hasRequiredGetContext; - -function requireGetContext () { - if (hasRequiredGetContext) return getContext_1; - hasRequiredGetContext = 1; - var __defProp = Object.defineProperty; - var __getOwnPropDesc = Object.getOwnPropertyDescriptor; - var __getOwnPropNames = Object.getOwnPropertyNames; - var __hasOwnProp = Object.prototype.hasOwnProperty; - var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); - }; - var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; - }; - var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); - var get_context_exports = {}; - __export(get_context_exports, { - SYMBOL_FOR_REQ_CONTEXT: () => SYMBOL_FOR_REQ_CONTEXT, - getContext: () => getContext - }); - getContext_1 = __toCommonJS(get_context_exports); - const SYMBOL_FOR_REQ_CONTEXT = Symbol.for("@vercel/request-context"); - function getContext() { - const fromSymbol = globalThis; - return fromSymbol[SYMBOL_FOR_REQ_CONTEXT]?.get?.() ?? {}; - } - return getContext_1; -} - -var tokenError; -var hasRequiredTokenError; - -function requireTokenError () { - if (hasRequiredTokenError) return tokenError; - hasRequiredTokenError = 1; - var __defProp = Object.defineProperty; - var __getOwnPropDesc = Object.getOwnPropertyDescriptor; - var __getOwnPropNames = Object.getOwnPropertyNames; - var __hasOwnProp = Object.prototype.hasOwnProperty; - var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); - }; - var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; - }; - var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); - var token_error_exports = {}; - __export(token_error_exports, { - VercelOidcTokenError: () => VercelOidcTokenError - }); - tokenError = __toCommonJS(token_error_exports); - class VercelOidcTokenError extends Error { - constructor(message, cause) { - super(message); - this.name = "VercelOidcTokenError"; - this.cause = cause; - } - toString() { - if (this.cause) { - return `${this.name}: ${this.message}: ${this.cause}`; - } - return `${this.name}: ${this.message}`; - } - } - return tokenError; -} - -var getVercelOidcToken_1; -var hasRequiredGetVercelOidcToken; - -function requireGetVercelOidcToken () { - if (hasRequiredGetVercelOidcToken) return getVercelOidcToken_1; - hasRequiredGetVercelOidcToken = 1; - var __defProp = Object.defineProperty; - var __getOwnPropDesc = Object.getOwnPropertyDescriptor; - var __getOwnPropNames = Object.getOwnPropertyNames; - var __hasOwnProp = Object.prototype.hasOwnProperty; - var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); - }; - var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; - }; - var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); - var get_vercel_oidc_token_exports = {}; - __export(get_vercel_oidc_token_exports, { - getVercelOidcToken: () => getVercelOidcToken, - getVercelOidcTokenSync: () => getVercelOidcTokenSync - }); - getVercelOidcToken_1 = __toCommonJS(get_vercel_oidc_token_exports); - var import_get_context = requireGetContext(); - var import_token_error = requireTokenError(); - async function getVercelOidcToken() { - let token = ""; - let err; - try { - token = getVercelOidcTokenSync(); - } catch (error) { - err = error; - } - try { - const [{ getTokenPayload, isExpired }, { refreshToken }] = await Promise.all([ - await import('./token-util_D6r3xWR2.mjs').then(n => n.t), - await import('./token_CrOFk7pc.mjs').then(n => n.t) - ]); - if (!token || isExpired(getTokenPayload(token))) { - await refreshToken(); - token = getVercelOidcTokenSync(); - } - } catch (error) { - if (err?.message && error instanceof Error) { - error.message = `${err.message} -${error.message}`; - } - throw new import_token_error.VercelOidcTokenError(`Failed to refresh OIDC token`, error); - } - return token; - } - function getVercelOidcTokenSync() { - const token = (0, import_get_context.getContext)().headers?.["x-vercel-oidc-token"] ?? process.env.VERCEL_OIDC_TOKEN; - if (!token) { - throw new Error( - `The 'x-vercel-oidc-token' header is missing from the request. Do you have the OIDC option enabled in the Vercel project settings?` - ); - } - return token; - } - return getVercelOidcToken_1; -} - -var dist; -var hasRequiredDist; - -function requireDist () { - if (hasRequiredDist) return dist; - hasRequiredDist = 1; - var __defProp = Object.defineProperty; - var __getOwnPropDesc = Object.getOwnPropertyDescriptor; - var __getOwnPropNames = Object.getOwnPropertyNames; - var __hasOwnProp = Object.prototype.hasOwnProperty; - var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); - }; - var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; - }; - var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); - var src_exports = {}; - __export(src_exports, { - getContext: () => import_get_context.getContext, - getVercelOidcToken: () => import_get_vercel_oidc_token.getVercelOidcToken, - getVercelOidcTokenSync: () => import_get_vercel_oidc_token.getVercelOidcTokenSync - }); - dist = __toCommonJS(src_exports); - var import_get_vercel_oidc_token = requireGetVercelOidcToken(); - var import_get_context = requireGetContext(); - return dist; -} - -var distExports = requireDist(); - -// src/transports.ts -async function streamToBuffer(stream) { - let totalLength = 0; - const reader = stream.getReader(); - const chunks = []; - try { - while (true) { - const { done, value } = await reader.read(); - if (done) break; - chunks.push(value); - totalLength += value.length; - } - } finally { - reader.releaseLock(); - } - return Buffer.concat(chunks, totalLength); -} -var JsonTransport = class { - contentType = "application/json"; - replacer; - reviver; - constructor(options = {}) { - this.replacer = options.replacer; - this.reviver = options.reviver; - } - serialize(value) { - return Buffer.from(JSON.stringify(value, this.replacer), "utf8"); - } - async deserialize(stream) { - const buffer = await streamToBuffer(stream); - return JSON.parse(buffer.toString("utf8"), this.reviver); - } -}; - -// src/types.ts -var MessageNotFoundError = class extends Error { - constructor(messageId) { - super(`Message ${messageId} not found`); - this.name = "MessageNotFoundError"; - } -}; -var MessageNotAvailableError = class extends Error { - constructor(messageId, reason) { - super( - `Message ${messageId} not available for processing${reason ? `: ${reason}` : ""}` - ); - this.name = "MessageNotAvailableError"; - } -}; -var MessageCorruptedError = class extends Error { - constructor(messageId, reason) { - super(`Message ${messageId} is corrupted: ${reason}`); - this.name = "MessageCorruptedError"; - } -}; -var QueueEmptyError = class extends Error { - constructor(queueName, consumerGroup) { - super( - `No messages available in queue "${queueName}" for consumer group "${consumerGroup}"` - ); - this.name = "QueueEmptyError"; - } -}; -var MessageLockedError = class extends Error { - retryAfter; - constructor(messageId, retryAfter) { - const retryMessage = retryAfter ? ` Retry after ${retryAfter} seconds.` : " Try again later."; - super(`Message ${messageId} is temporarily locked.${retryMessage}`); - this.name = "MessageLockedError"; - this.retryAfter = retryAfter; - } -}; -var UnauthorizedError = class extends Error { - constructor(message = "Missing or invalid authentication token") { - super(message); - this.name = "UnauthorizedError"; - } -}; -var ForbiddenError = class extends Error { - constructor(message = "Queue environment doesn't match token environment") { - super(message); - this.name = "ForbiddenError"; - } -}; -var BadRequestError = class extends Error { - constructor(message) { - super(message); - this.name = "BadRequestError"; - } -}; -var InternalServerError = class extends Error { - constructor(message = "Unexpected server error") { - super(message); - this.name = "InternalServerError"; - } -}; -var InvalidLimitError = class extends Error { - constructor(limit, min = 1, max = 10) { - super(`Invalid limit: ${limit}. Limit must be between ${min} and ${max}.`); - this.name = "InvalidLimitError"; - } -}; - -// src/client.ts -async function consumeStream(stream) { - const reader = stream.getReader(); - try { - while (true) { - const { done } = await reader.read(); - if (done) break; - } - } finally { - reader.releaseLock(); - } -} -function parseQueueHeaders(headers) { - const messageId = headers.get("Vqs-Message-Id"); - const deliveryCountStr = headers.get("Vqs-Delivery-Count") || "0"; - const timestamp = headers.get("Vqs-Timestamp"); - const contentType = headers.get("Content-Type") || "application/octet-stream"; - const ticket = headers.get("Vqs-Ticket"); - if (!messageId || !timestamp || !ticket) { - return null; - } - const deliveryCount = parseInt(deliveryCountStr, 10); - if (isNaN(deliveryCount)) { - return null; - } - return { - messageId, - deliveryCount, - createdAt: new Date(timestamp), - contentType, - ticket - }; -} -var QueueClient = class { - baseUrl; - basePath; - customHeaders = {}; - token; - /** - * Create a new Vercel Queue Service client - * @param options Client configuration options - */ - constructor(options = {}) { - this.baseUrl = options.baseUrl || process.env.VERCEL_QUEUE_BASE_URL || "https://vercel-queue.com"; - this.basePath = options.basePath || process.env.VERCEL_QUEUE_BASE_PATH || "/api/v2/messages"; - this.token = options.token || process.env.VERCEL_QUEUE_TOKEN; - const VERCEL_QUEUE_HEADER_PREFIX = "VERCEL_QUEUE_HEADER_"; - this.customHeaders = Object.fromEntries( - Object.entries(process.env).filter(([key]) => key.startsWith(VERCEL_QUEUE_HEADER_PREFIX)).map(([key, value]) => [ - // This allows headers to use dashes independent of shell used - key.replace(VERCEL_QUEUE_HEADER_PREFIX, "").replaceAll("__", "-"), - value || "" - ]) - ); - } - async getToken() { - if (this.token) { - return this.token; - } - const token = await distExports.getVercelOidcToken(); - if (!token) { - throw new Error( - "Failed to get OIDC token from Vercel Functions. Make sure you are running in a Vercel Function environment, or provide a token explicitly.\n\nTo set up your environment:\n1. Link your project: 'vercel link'\n2. Pull environment variables: 'vercel env pull'\n3. Run with environment: 'dotenv -e .env.local -- your-command'" - ); - } - return token; - } - /** - * Send a message to a queue - * @param options Send message options - * @param transport Serializer/deserializer for the payload - * @returns Promise with the message ID - * @throws {BadRequestError} When request parameters are invalid - * @throws {UnauthorizedError} When authentication fails - * @throws {ForbiddenError} When access is denied (environment mismatch) - * @throws {InternalServerError} When server encounters an error - */ - async sendMessage(options, transport) { - const { queueName, payload, idempotencyKey, retentionSeconds } = options; - const headers = new Headers({ - Authorization: `Bearer ${await this.getToken()}`, - "Vqs-Queue-Name": queueName, - "Content-Type": transport.contentType, - ...this.customHeaders - }); - const deploymentId = options.deploymentId || process.env.VERCEL_DEPLOYMENT_ID; - if (deploymentId) { - headers.set("Vqs-Deployment-Id", deploymentId); - } - if (idempotencyKey) { - headers.set("Vqs-Idempotency-Key", idempotencyKey); - } - if (retentionSeconds !== void 0) { - headers.set("Vqs-Retention-Seconds", retentionSeconds.toString()); - } - const body = transport.serialize(payload); - const response = await fetch(`${this.baseUrl}${this.basePath}`, { - method: "POST", - body, - headers - }); - if (!response.ok) { - if (response.status === 400) { - const errorText = await response.text(); - throw new BadRequestError(errorText || "Invalid parameters"); - } - if (response.status === 401) { - throw new UnauthorizedError(); - } - if (response.status === 403) { - throw new ForbiddenError(); - } - if (response.status === 409) { - throw new Error("Duplicate idempotency key detected"); - } - if (response.status >= 500) { - throw new InternalServerError( - `Server error: ${response.status} ${response.statusText}` - ); - } - throw new Error( - `Failed to send message: ${response.status} ${response.statusText}` - ); - } - const responseData = await response.json(); - return responseData; - } - /** - * Receive messages from a queue - * @param options Receive messages options - * @param transport Serializer/deserializer for the payload - * @returns AsyncGenerator that yields messages as they arrive - * @throws {InvalidLimitError} When limit parameter is not between 1 and 10 - * @throws {QueueEmptyError} When no messages are available (204) - * @throws {MessageLockedError} When messages are temporarily locked (423) - * @throws {BadRequestError} When request parameters are invalid - * @throws {UnauthorizedError} When authentication fails - * @throws {ForbiddenError} When access is denied (environment mismatch) - * @throws {InternalServerError} When server encounters an error - */ - async *receiveMessages(options, transport) { - const { queueName, consumerGroup, visibilityTimeoutSeconds, limit } = options; - if (limit !== void 0 && (limit < 1 || limit > 10)) { - throw new InvalidLimitError(limit); - } - const headers = new Headers({ - Authorization: `Bearer ${await this.getToken()}`, - "Vqs-Queue-Name": queueName, - "Vqs-Consumer-Group": consumerGroup, - Accept: "multipart/mixed", - ...this.customHeaders - }); - if (visibilityTimeoutSeconds !== void 0) { - headers.set( - "Vqs-Visibility-Timeout", - visibilityTimeoutSeconds.toString() - ); - } - if (limit !== void 0) { - headers.set("Vqs-Limit", limit.toString()); - } - const response = await fetch(`${this.baseUrl}${this.basePath}`, { - method: "GET", - headers - }); - if (response.status === 204) { - throw new QueueEmptyError(queueName, consumerGroup); - } - if (!response.ok) { - if (response.status === 400) { - const errorText = await response.text(); - throw new BadRequestError(errorText || "Invalid parameters"); - } - if (response.status === 401) { - throw new UnauthorizedError(); - } - if (response.status === 403) { - throw new ForbiddenError(); - } - if (response.status === 423) { - const retryAfterHeader = response.headers.get("Retry-After"); - let retryAfter; - if (retryAfterHeader) { - const parsed = parseInt(retryAfterHeader, 10); - retryAfter = isNaN(parsed) ? void 0 : parsed; - } - throw new MessageLockedError("next message", retryAfter); - } - if (response.status >= 500) { - throw new InternalServerError( - `Server error: ${response.status} ${response.statusText}` - ); - } - throw new Error( - `Failed to receive messages: ${response.status} ${response.statusText}` - ); - } - for await (const multipartMessage of parseMultipartStream(response)) { - try { - const parsedHeaders = parseQueueHeaders(multipartMessage.headers); - if (!parsedHeaders) { - console.warn("Missing required queue headers in multipart part"); - await consumeStream(multipartMessage.payload); - continue; - } - const deserializedPayload = await transport.deserialize( - multipartMessage.payload - ); - const message = { - ...parsedHeaders, - payload: deserializedPayload - }; - yield message; - } catch (error) { - console.warn("Failed to process multipart message:", error); - await consumeStream(multipartMessage.payload); - } - } - } - async receiveMessageById(options, transport) { - const { - queueName, - consumerGroup, - messageId, - visibilityTimeoutSeconds, - skipPayload - } = options; - const headers = new Headers({ - Authorization: `Bearer ${await this.getToken()}`, - "Vqs-Queue-Name": queueName, - "Vqs-Consumer-Group": consumerGroup, - Accept: "multipart/mixed", - ...this.customHeaders - }); - if (visibilityTimeoutSeconds !== void 0) { - headers.set( - "Vqs-Visibility-Timeout", - visibilityTimeoutSeconds.toString() - ); - } - if (skipPayload) { - headers.set("Vqs-Skip-Payload", "1"); - } - const response = await fetch( - `${this.baseUrl}${this.basePath}/${encodeURIComponent(messageId)}`, - { - method: "GET", - headers - } - ); - if (!response.ok) { - if (response.status === 400) { - const errorText = await response.text(); - throw new BadRequestError(errorText || "Invalid parameters"); - } - if (response.status === 401) { - throw new UnauthorizedError(); - } - if (response.status === 403) { - throw new ForbiddenError(); - } - if (response.status === 404) { - throw new MessageNotFoundError(messageId); - } - if (response.status === 423) { - const retryAfterHeader = response.headers.get("Retry-After"); - let retryAfter; - if (retryAfterHeader) { - const parsed = parseInt(retryAfterHeader, 10); - retryAfter = isNaN(parsed) ? void 0 : parsed; - } - throw new MessageLockedError(messageId, retryAfter); - } - if (response.status === 409) { - throw new MessageNotAvailableError(messageId); - } - if (response.status >= 500) { - throw new InternalServerError( - `Server error: ${response.status} ${response.statusText}` - ); - } - throw new Error( - `Failed to receive message by ID: ${response.status} ${response.statusText}` - ); - } - if (skipPayload && response.status === 204) { - const parsedHeaders = parseQueueHeaders(response.headers); - if (!parsedHeaders) { - throw new MessageCorruptedError( - messageId, - "Missing required queue headers in 204 response" - ); - } - const message = { - ...parsedHeaders, - payload: void 0 - }; - return { message }; - } - if (!transport) { - throw new Error("Transport is required when skipPayload is not true"); - } - try { - for await (const multipartMessage of parseMultipartStream(response)) { - try { - const parsedHeaders = parseQueueHeaders(multipartMessage.headers); - if (!parsedHeaders) { - console.warn("Missing required queue headers in multipart part"); - await consumeStream(multipartMessage.payload); - continue; - } - const deserializedPayload = await transport.deserialize( - multipartMessage.payload - ); - const message = { - ...parsedHeaders, - payload: deserializedPayload - }; - return { message }; - } catch (error) { - console.warn("Failed to deserialize message by ID:", error); - await consumeStream(multipartMessage.payload); - throw new MessageCorruptedError( - messageId, - `Failed to deserialize payload: ${error}` - ); - } - } - } catch (error) { - if (error instanceof MessageCorruptedError) { - throw error; - } - throw new MessageCorruptedError( - messageId, - `Failed to parse multipart response: ${error}` - ); - } - throw new MessageNotFoundError(messageId); - } - /** - * Delete a message (acknowledge processing) - * @param options Delete message options - * @returns Promise with delete status - * @throws {MessageNotFoundError} When the message doesn't exist (404) - * @throws {MessageNotAvailableError} When message can't be deleted (409) - * @throws {BadRequestError} When ticket is missing or invalid (400) - * @throws {UnauthorizedError} When authentication fails - * @throws {ForbiddenError} When access is denied (environment mismatch) - * @throws {InternalServerError} When server encounters an error - */ - async deleteMessage(options) { - const { queueName, consumerGroup, messageId, ticket } = options; - const response = await fetch( - `${this.baseUrl}${this.basePath}/${encodeURIComponent(messageId)}`, - { - method: "DELETE", - headers: new Headers({ - Authorization: `Bearer ${await this.getToken()}`, - "Vqs-Queue-Name": queueName, - "Vqs-Consumer-Group": consumerGroup, - "Vqs-Ticket": ticket, - ...this.customHeaders - }) - } - ); - if (!response.ok) { - if (response.status === 400) { - throw new BadRequestError("Missing or invalid ticket"); - } - if (response.status === 401) { - throw new UnauthorizedError(); - } - if (response.status === 403) { - throw new ForbiddenError(); - } - if (response.status === 404) { - throw new MessageNotFoundError(messageId); - } - if (response.status === 409) { - throw new MessageNotAvailableError( - messageId, - "Invalid ticket, message not in correct state, or already processed" - ); - } - if (response.status >= 500) { - throw new InternalServerError( - `Server error: ${response.status} ${response.statusText}` - ); - } - throw new Error( - `Failed to delete message: ${response.status} ${response.statusText}` - ); - } - return { deleted: true }; - } - /** - * Change the visibility timeout of a message - * @param options Change visibility options - * @returns Promise with update status - * @throws {MessageNotFoundError} When the message doesn't exist (404) - * @throws {MessageNotAvailableError} When message can't be updated (409) - * @throws {BadRequestError} When ticket is missing or visibility timeout invalid (400) - * @throws {UnauthorizedError} When authentication fails - * @throws {ForbiddenError} When access is denied (environment mismatch) - * @throws {InternalServerError} When server encounters an error - */ - async changeVisibility(options) { - const { - queueName, - consumerGroup, - messageId, - ticket, - visibilityTimeoutSeconds - } = options; - const response = await fetch( - `${this.baseUrl}${this.basePath}/${encodeURIComponent(messageId)}`, - { - method: "PATCH", - headers: new Headers({ - Authorization: `Bearer ${await this.getToken()}`, - "Vqs-Queue-Name": queueName, - "Vqs-Consumer-Group": consumerGroup, - "Vqs-Ticket": ticket, - "Vqs-Visibility-Timeout": visibilityTimeoutSeconds.toString(), - ...this.customHeaders - }) - } - ); - if (!response.ok) { - if (response.status === 400) { - throw new BadRequestError( - "Missing ticket or invalid visibility timeout" - ); - } - if (response.status === 401) { - throw new UnauthorizedError(); - } - if (response.status === 403) { - throw new ForbiddenError(); - } - if (response.status === 404) { - throw new MessageNotFoundError(messageId); - } - if (response.status === 409) { - throw new MessageNotAvailableError( - messageId, - "Invalid ticket, message not in correct state, or already processed" - ); - } - if (response.status >= 500) { - throw new InternalServerError( - `Server error: ${response.status} ${response.statusText}` - ); - } - throw new Error( - `Failed to change visibility: ${response.status} ${response.statusText}` - ); - } - return { updated: true }; - } -}; - -// src/callback.ts -function validateWildcardPattern(pattern) { - const firstIndex = pattern.indexOf("*"); - const lastIndex = pattern.lastIndexOf("*"); - if (firstIndex !== lastIndex) { - return false; - } - if (firstIndex === -1) { - return false; - } - if (firstIndex !== pattern.length - 1) { - return false; - } - return true; -} -function matchesWildcardPattern(topicName, pattern) { - const prefix = pattern.slice(0, -1); - return topicName.startsWith(prefix); -} -function findTopicHandler(queueName, handlers) { - const exactHandler = handlers[queueName]; - if (exactHandler) { - return exactHandler; - } - for (const pattern in handlers) { - if (pattern.includes("*") && matchesWildcardPattern(queueName, pattern)) { - return handlers[pattern]; - } - } - return null; -} -async function parseCallback(request) { - const contentType = request.headers.get("content-type"); - if (!contentType || !contentType.includes("application/cloudevents+json")) { - throw new Error( - "Invalid content type: expected 'application/cloudevents+json'" - ); - } - let cloudEvent; - try { - cloudEvent = await request.json(); - } catch (error) { - throw new Error("Failed to parse CloudEvent from request body"); - } - if (!cloudEvent.type || !cloudEvent.source || !cloudEvent.id || typeof cloudEvent.data !== "object" || cloudEvent.data == null) { - throw new Error("Invalid CloudEvent: missing required fields"); - } - if (cloudEvent.type !== "com.vercel.queue.v1beta") { - throw new Error( - `Invalid CloudEvent type: expected 'com.vercel.queue.v1beta', got '${cloudEvent.type}'` - ); - } - const missingFields = []; - if (!("queueName" in cloudEvent.data)) missingFields.push("queueName"); - if (!("consumerGroup" in cloudEvent.data)) - missingFields.push("consumerGroup"); - if (!("messageId" in cloudEvent.data)) missingFields.push("messageId"); - if (missingFields.length > 0) { - throw new Error( - `Missing required CloudEvent data fields: ${missingFields.join(", ")}` - ); - } - const { messageId, queueName, consumerGroup } = cloudEvent.data; - return { - queueName, - consumerGroup, - messageId - }; -} -function handleCallback(handlers) { - for (const topicPattern in handlers) { - if (topicPattern.includes("*")) { - if (!validateWildcardPattern(topicPattern)) { - throw new Error( - `Invalid wildcard pattern "${topicPattern}": * may only appear once and must be at the end of the topic name` - ); - } - } - } - const routeHandler = async (request) => { - try { - const { queueName, consumerGroup, messageId } = await parseCallback(request); - const topicHandler = findTopicHandler(queueName, handlers); - if (!topicHandler) { - const availableTopics = Object.keys(handlers).join(", "); - return Response.json( - { - error: `No handler found for topic: ${queueName}`, - availableTopics - }, - { status: 404 } - ); - } - const consumerGroupHandler = topicHandler[consumerGroup]; - if (!consumerGroupHandler) { - const availableGroups = Object.keys(topicHandler).join(", "); - return Response.json( - { - error: `No handler found for consumer group "${consumerGroup}" in topic "${queueName}".`, - availableGroups - }, - { status: 404 } - ); - } - const client = new QueueClient(); - const topic = new Topic(client, queueName); - const cg = topic.consumerGroup(consumerGroup); - await cg.consume(consumerGroupHandler, { messageId }); - return Response.json({ status: "success" }); - } catch (error) { - console.error("Queue callback error:", error); - if (error instanceof Error && (error.message.includes("Missing required CloudEvent data fields") || error.message.includes("Invalid CloudEvent") || error.message.includes("Invalid CloudEvent type") || error.message.includes("Invalid content type") || error.message.includes("Failed to parse CloudEvent"))) { - return Response.json({ error: error.message }, { status: 400 }); - } - return Response.json( - { error: "Failed to process queue message" }, - { status: 500 } - ); - } - }; - if (isDevMode()) { - registerDevRouteHandler(routeHandler, handlers); - } - return routeHandler; -} - -// src/dev.ts -var devRouteHandlers = /* @__PURE__ */ new Map(); -var wildcardRouteHandlers = /* @__PURE__ */ new Map(); -function cleanupDeadRefs(key, refs) { - const aliveRefs = refs.filter((ref) => ref.deref() !== void 0); - if (aliveRefs.length === 0) { - wildcardRouteHandlers.delete(key); - } else if (aliveRefs.length < refs.length) { - wildcardRouteHandlers.set(key, aliveRefs); - } -} -function isDevMode() { - return process.env.NODE_ENV === "development"; -} -function registerDevRouteHandler(routeHandler, handlers) { - for (const topicName in handlers) { - for (const consumerGroup in handlers[topicName]) { - const key = `${topicName}:${consumerGroup}`; - if (topicName.includes("*")) { - const existing = wildcardRouteHandlers.get(key) || []; - cleanupDeadRefs(key, existing); - const cleanedRefs = wildcardRouteHandlers.get(key) || []; - const weakRef = new WeakRef(routeHandler); - cleanedRefs.push(weakRef); - wildcardRouteHandlers.set(key, cleanedRefs); - } else { - devRouteHandlers.set(key, { - routeHandler, - topicPattern: topicName - }); - } - } - } -} -function findRouteHandlersForTopic(topicName) { - const handlersMap = /* @__PURE__ */ new Map(); - for (const [ - key, - { routeHandler, topicPattern } - ] of devRouteHandlers.entries()) { - const [_, consumerGroup] = key.split(":"); - if (topicPattern === topicName) { - if (!handlersMap.has(routeHandler)) { - handlersMap.set(routeHandler, /* @__PURE__ */ new Set()); - } - handlersMap.get(routeHandler).add(consumerGroup); - } - } - for (const [key, refs] of wildcardRouteHandlers.entries()) { - const [pattern, consumerGroup] = key.split(":"); - if (matchesWildcardPattern(topicName, pattern)) { - cleanupDeadRefs(key, refs); - const cleanedRefs = wildcardRouteHandlers.get(key) || []; - for (const ref of cleanedRefs) { - const routeHandler = ref.deref(); - if (routeHandler) { - if (!handlersMap.has(routeHandler)) { - handlersMap.set(routeHandler, /* @__PURE__ */ new Set()); - } - handlersMap.get(routeHandler).add(consumerGroup); - } - } - } - } - return handlersMap; -} -function createMockCloudEventRequest(topicName, consumerGroup, messageId) { - const cloudEvent = { - type: "com.vercel.queue.v1beta", - source: `/topic/${topicName}/consumer/${consumerGroup}`, - id: messageId, - datacontenttype: "application/json", - data: { - messageId, - queueName: topicName, - consumerGroup - }, - time: (/* @__PURE__ */ new Date()).toISOString(), - specversion: "1.0" - }; - return new Request("https://localhost/api/queue/callback", { - method: "POST", - headers: { - "Content-Type": "application/cloudevents+json" - }, - body: JSON.stringify(cloudEvent) - }); -} -var DEV_CALLBACK_DELAY = 1e3; -function scheduleDevTimeout(topicName, messageId, timeoutSeconds) { - console.log( - `[Dev Mode] Message ${messageId} timed out for ${timeoutSeconds}s, will re-trigger` - ); - setTimeout( - () => { - console.log( - `[Dev Mode] Re-triggering callback for timed-out message ${messageId}` - ); - triggerDevCallbacks(topicName, messageId); - }, - timeoutSeconds * 1e3 + DEV_CALLBACK_DELAY - ); -} -function triggerDevCallbacks(topicName, messageId) { - const handlersMap = findRouteHandlersForTopic(topicName); - if (handlersMap.size === 0) { - return; - } - const consumerGroups = Array.from( - new Set( - Array.from(handlersMap.values()).flatMap((groups) => Array.from(groups)) - ) - ); - console.log( - `[Dev Mode] Triggering local callbacks for topic "${topicName}" \u2192 consumers: ${consumerGroups.join(", ")}` - ); - setTimeout(async () => { - for (const [routeHandler, consumerGroups2] of handlersMap.entries()) { - for (const consumerGroup of consumerGroups2) { - try { - const request = createMockCloudEventRequest( - topicName, - consumerGroup, - messageId - ); - const response = await routeHandler(request); - if (response.ok) { - try { - const responseData = await response.json(); - if (responseData.status === "success") { - console.log( - `[Dev Mode] Message processed for ${topicName}/${consumerGroup}` - ); - } - } catch (jsonError) { - console.error( - `[Dev Mode] Failed to parse success response for ${topicName}/${consumerGroup}:`, - jsonError - ); - } - } else { - try { - const errorData = await response.json(); - console.error( - `[Dev Mode] Failed to process message for ${topicName}/${consumerGroup}:`, - errorData.error || response.statusText - ); - } catch (jsonError) { - console.error( - `[Dev Mode] Failed to process message for ${topicName}/${consumerGroup}:`, - response.statusText - ); - } - } - } catch (error) { - console.error( - `[Dev Mode] Error triggering callback for ${topicName}/${consumerGroup}:`, - error - ); - } - } - } - }, DEV_CALLBACK_DELAY); -} -function clearDevHandlers() { - devRouteHandlers.clear(); - wildcardRouteHandlers.clear(); -} -if (process.env.NODE_ENV === "test" || process.env.VITEST) { - globalThis.__clearDevHandlers = clearDevHandlers; -} - -// src/consumer-group.ts -var ConsumerGroup = class { - client; - topicName; - consumerGroupName; - visibilityTimeout; - refreshInterval; - transport; - /** - * Create a new ConsumerGroup instance - * @param client QueueClient instance to use for API calls - * @param topicName Name of the topic to consume from - * @param consumerGroupName Name of the consumer group - * @param options Optional configuration - */ - constructor(client, topicName, consumerGroupName, options = {}) { - this.client = client; - this.topicName = topicName; - this.consumerGroupName = consumerGroupName; - this.visibilityTimeout = options.visibilityTimeoutSeconds || 30; - this.refreshInterval = options.refreshInterval || 10; - this.transport = options.transport || new JsonTransport(); - } - /** - * Starts a background loop that periodically extends the visibility timeout for a message. - * This prevents the message from becoming visible to other consumers while it's being processed. - * - * The extension loop runs every `refreshInterval` seconds and updates the message's - * visibility timeout to `visibilityTimeout` seconds from the current time. - * - * @param messageId - The unique identifier of the message to extend visibility for - * @param ticket - The receipt ticket that proves ownership of the message - * @returns A function that when called will stop the extension loop - * - * @remarks - * - The first extension attempt occurs after `refreshInterval` seconds, not immediately - * - If an extension fails, the loop terminates with an error logged to console - * - The returned stop function is idempotent - calling it multiple times is safe - * - By default, the stop function returns immediately without waiting for in-flight - * - Pass `true` to the stop function to wait for any in-flight extension to complete - */ - startVisibilityExtension(messageId, ticket) { - let isRunning = true; - let resolveLifecycle; - let timeoutId = null; - const lifecyclePromise = new Promise((resolve) => { - resolveLifecycle = resolve; - }); - const extend = async () => { - if (!isRunning) { - resolveLifecycle(); - return; - } - try { - await this.client.changeVisibility({ - queueName: this.topicName, - consumerGroup: this.consumerGroupName, - messageId, - ticket, - visibilityTimeoutSeconds: this.visibilityTimeout - }); - if (isRunning) { - timeoutId = setTimeout(() => extend(), this.refreshInterval * 1e3); - } else { - resolveLifecycle(); - } - } catch (error) { - console.error( - `Failed to extend visibility for message ${messageId}:`, - error - ); - resolveLifecycle(); - } - }; - timeoutId = setTimeout(() => extend(), this.refreshInterval * 1e3); - return async (waitForCompletion = false) => { - isRunning = false; - if (timeoutId) { - clearTimeout(timeoutId); - timeoutId = null; - } - if (waitForCompletion) { - await lifecyclePromise; - } else { - resolveLifecycle(); - } - }; - } - /** - * Process a single message with the given handler - * @param message The message to process - * @param handler Function to process the message - */ - async processMessage(message, handler) { - const stopExtension = this.startVisibilityExtension( - message.messageId, - message.ticket - ); - try { - const result = await handler(message.payload, { - messageId: message.messageId, - deliveryCount: message.deliveryCount, - createdAt: message.createdAt, - topicName: this.topicName, - consumerGroup: this.consumerGroupName - }); - await stopExtension(); - if (result && "timeoutSeconds" in result) { - await this.client.changeVisibility({ - queueName: this.topicName, - consumerGroup: this.consumerGroupName, - messageId: message.messageId, - ticket: message.ticket, - visibilityTimeoutSeconds: result.timeoutSeconds - }); - if (isDevMode()) { - scheduleDevTimeout( - this.topicName, - message.messageId, - result.timeoutSeconds - ); - } - } else { - await this.client.deleteMessage({ - queueName: this.topicName, - consumerGroup: this.consumerGroupName, - messageId: message.messageId, - ticket: message.ticket - }); - } - } catch (error) { - await stopExtension(); - if (this.transport.finalize && message.payload !== void 0 && message.payload !== null) { - try { - await this.transport.finalize(message.payload); - } catch (finalizeError) { - console.warn("Failed to finalize message payload:", finalizeError); - } - } - throw error; - } - } - async consume(handler, options) { - if (options?.messageId) { - if (options.skipPayload) { - const response = await this.client.receiveMessageById( - { - queueName: this.topicName, - consumerGroup: this.consumerGroupName, - messageId: options.messageId, - visibilityTimeoutSeconds: this.visibilityTimeout, - skipPayload: true - }, - this.transport - ); - await this.processMessage( - response.message, - handler - ); - } else { - const response = await this.client.receiveMessageById( - { - queueName: this.topicName, - consumerGroup: this.consumerGroupName, - messageId: options.messageId, - visibilityTimeoutSeconds: this.visibilityTimeout - }, - this.transport - ); - await this.processMessage( - response.message, - handler - ); - } - } else { - let messageFound = false; - for await (const message of this.client.receiveMessages( - { - queueName: this.topicName, - consumerGroup: this.consumerGroupName, - visibilityTimeoutSeconds: this.visibilityTimeout, - limit: 1 - }, - this.transport - )) { - messageFound = true; - await this.processMessage(message, handler); - break; - } - if (!messageFound) { - throw new Error("No messages available"); - } - } - } - /** - * Get the consumer group name - */ - get name() { - return this.consumerGroupName; - } - /** - * Get the topic name this consumer group is subscribed to - */ - get topic() { - return this.topicName; - } -}; - -// src/topic.ts -var Topic = class { - client; - topicName; - transport; - /** - * Create a new Topic instance - * @param client QueueClient instance to use for API calls - * @param topicName Name of the topic to work with - * @param transport Optional serializer/deserializer for the payload (defaults to JSON) - */ - constructor(client, topicName, transport) { - this.client = client; - this.topicName = topicName; - this.transport = transport || new JsonTransport(); - } - /** - * Publish a message to the topic - * @param payload The data to publish - * @param options Optional publish options - * @returns An object containing the message ID - * @throws {BadRequestError} When request parameters are invalid - * @throws {UnauthorizedError} When authentication fails - * @throws {ForbiddenError} When access is denied (environment mismatch) - * @throws {InternalServerError} When server encounters an error - */ - async publish(payload, options) { - const result = await this.client.sendMessage( - { - queueName: this.topicName, - payload, - idempotencyKey: options?.idempotencyKey, - retentionSeconds: options?.retentionSeconds, - deploymentId: options?.deploymentId - }, - this.transport - ); - if (isDevMode()) { - triggerDevCallbacks(this.topicName, result.messageId); - } - return { messageId: result.messageId }; - } - /** - * Create a consumer group for this topic - * @param consumerGroupName Name of the consumer group - * @param options Optional configuration for the consumer group - * @returns A ConsumerGroup instance - */ - consumerGroup(consumerGroupName, options) { - const consumerOptions = { - ...options, - transport: options?.transport || this.transport - }; - return new ConsumerGroup( - this.client, - this.topicName, - consumerGroupName, - consumerOptions - ); - } - /** - * Get the topic name - */ - get name() { - return this.topicName; - } - /** - * Get the transport used by this topic - */ - get serializer() { - return this.transport; - } -}; - -// src/factory.ts -async function send(topicName, payload, options) { - const transport = options?.transport || new JsonTransport(); - const client = new QueueClient(); - const result = await client.sendMessage( - { - queueName: topicName, - payload, - idempotencyKey: options?.idempotencyKey, - retentionSeconds: options?.retentionSeconds, - deploymentId: options?.deploymentId - }, - transport - ); - if (isDevMode()) { - triggerDevCallbacks(topicName, result.messageId); - } - return { messageId: result.messageId }; -} - -// Generated by genversion. -const version = '4.0.1-beta.7'; - -const DEFAULT_RESOLVE_DATA_OPTION = 'all'; -function dateToStringReplacer(_key, value) { - if (value instanceof Date) { - return value.toISOString(); - } - return value; -} -/** - * Helper to serialize error into a JSON string in the error field. - * The error field can be either: - * - A plain string (legacy format, just the error message) - * - A JSON string with { message, stack, code } (new format) - */ -function serializeError(data) { - const { error, ...rest } = data; - // If we have an error, serialize as JSON string - if (error !== undefined) { - return { - ...rest, - error: JSON.stringify({ - message: error.message, - stack: error.stack, - code: error.code, - }), - }; - } - return data; -} -/** - * Helper to deserialize error field from the backend into a StructuredError object. - * Handles backwards compatibility: - * - If error is a JSON string with {message, stack, code} → parse into StructuredError - * - If error is a plain string → treat as error message with no stack - * - If no error → undefined - * - * This function transforms objects from wire format (where error is a JSON string) - * to domain format (where error is a StructuredError object). The generic type - * parameter should be the expected output type (WorkflowRun or Step). - * - * Note: The type assertion is necessary because the wire format types from Zod schemas - * have `error?: string` while the domain types have complex error types (e.g., discriminated - * unions with `error: void` or `error: StructuredError` depending on status), but the - * transformation preserves all other fields correctly. - */ -function deserializeError(obj) { - const { error, ...rest } = obj; - if (!error) { - return obj; - } - // Try to parse as structured error JSON - try { - const parsed = StructuredErrorSchema.parse(JSON.parse(error)); - return { - ...rest, - error: { - message: parsed.message, - stack: parsed.stack, - code: parsed.code, - }, - }; - } - catch { - // Backwards compatibility: error is just a plain string - return { - ...rest, - error: { - message: error, - }, - }; - } -} -const getUserAgent = () => { - return `@workflow/world-vercel/${version} node-${process.version} ${os.platform()} (${os.arch()})`; -}; -const getHttpUrl = (config) => { - const projectConfig = config?.projectConfig; - const defaultUrl = 'https://vercel-workflow.com/api'; - const defaultProxyUrl = 'https://api.vercel.com/v1/workflow'; - const usingProxy = Boolean(config?.baseUrl || (projectConfig?.projectId && projectConfig?.teamId)); - const baseUrl = config?.baseUrl || (usingProxy ? defaultProxyUrl : defaultUrl); - return { baseUrl, usingProxy }; -}; -const getHeaders = (config) => { - const projectConfig = config?.projectConfig; - const headers = new Headers(config?.headers); - headers.set('User-Agent', getUserAgent()); - if (projectConfig) { - headers.set('x-vercel-environment', projectConfig.environment || 'production'); - if (projectConfig.projectId) { - headers.set('x-vercel-project-id', projectConfig.projectId); - } - if (projectConfig.teamId) { - headers.set('x-vercel-team-id', projectConfig.teamId); - } - } - return headers; -}; -async function getHttpConfig(config) { - const headers = getHeaders(config); - const token = config?.token ?? (await distExports.getVercelOidcToken()); - if (token) { - headers.set('Authorization', `Bearer ${token}`); - } - const { baseUrl, usingProxy } = getHttpUrl(config); - return { baseUrl, headers, usingProxy }; -} -async function makeRequest({ endpoint, options = {}, config = {}, schema, }) { - const { baseUrl, headers } = await getHttpConfig(config); - headers.set('Content-Type', 'application/json'); - const url = `${baseUrl}${endpoint}`; - const response = await fetch(url, { - ...options, - headers, - }); - if (!response.ok) { - const errorData = (await response.json().catch(() => ({}))); - if (process.env.DEBUG === '1') { - const stringifiedHeaders = Array.from(headers.entries()) - .map(([key, value]) => `-H "${key}: ${value}"`) - .join(' '); - console.error(`Failed to fetch, reproduce with:\ncurl -X ${options.method} ${stringifiedHeaders} "${url}"`); - } - throw new WorkflowAPIError(errorData.message || - `${options.method ?? 'GET'} ${endpoint} -> HTTP ${response.status}: ${response.statusText}`, { url, status: response.status, code: errorData.code }); - } - try { - const text = await response.text(); - return schema.parse(JSON.parse(text)); - } - catch (error) { - if (error instanceof ZodError) { - throw new WorkflowAPIError(`Failed to parse server response for ${options.method ?? 'GET'} ${endpoint}: ${error.message}`, { url, cause: error }); - } - throw new WorkflowAPIError(`Failed to parse server response for ${options.method ?? 'GET'} ${endpoint}`, { url, cause: error }); - } -} - -const MessageWrapper = z.object({ - payload: QueuePayloadSchema, - queueName: ValidQueueName, -}); -const VERCEL_QUEUE_MAX_VISIBILITY = 82800; // 23 hours in seconds -function createQueue(config) { - const { baseUrl, usingProxy } = getHttpUrl(config); - const headers = getHeaders(config); - if (usingProxy) { - // If we're using a proxy for the Workflow API, we should also go - // through the proxy for the queues API. - process.env.VERCEL_QUEUE_BASE_URL = `${baseUrl}`; - process.env.VERCEL_QUEUE_BASE_PATH = '/queues/v2/messages'; - if (config?.token) { - process.env.VERCEL_QUEUE_TOKEN = config.token; - } - if (headers) { - headers.forEach((value, key) => { - const sanitizedKey = key.replaceAll('-', '__'); - process.env[`VERCEL_QUEUE_HEADER_${sanitizedKey}`] = value; - }); - } - } - const queue = async (queueName, x, opts) => { - const encoded = MessageWrapper.encode({ - payload: x, - queueName, - }); - const sanitizedQueueName = queueName.replace(/[^A-Za-z0-9-_]/g, '-'); - const { messageId } = await send(sanitizedQueueName, encoded, opts); - return { messageId: MessageId.parse(messageId) }; - }; - const createQueueHandler = (prefix, handler) => { - return handleCallback({ - [`${prefix}*`]: { - default: async (body, meta) => { - const { payload, queueName } = MessageWrapper.parse(body); - const result = await handler(payload, { - queueName, - messageId: MessageId.parse(meta.messageId), - attempt: meta.deliveryCount, - }); - if (typeof result?.timeoutSeconds === 'number') { - // For Vercel Queue, enforce the max visibility limit: - // - When a step function throws a `RetryableError`, the retryAfter timestamp is updated and stored on the Step document - const adjustedTimeoutSeconds = Math.min(result.timeoutSeconds, VERCEL_QUEUE_MAX_VISIBILITY); - if (adjustedTimeoutSeconds !== result.timeoutSeconds) { - result.timeoutSeconds = adjustedTimeoutSeconds; - } - } - return result; - }, - }, - }); - }; - const getDeploymentId = async () => { - const deploymentId = process.env.VERCEL_DEPLOYMENT_ID; - if (!deploymentId) { - throw new Error('VERCEL_DEPLOYMENT_ID environment variable is not set'); - } - return deploymentId; - }; - return { queue, createQueueHandler, getDeploymentId }; -} - -// Helper to filter event data based on resolveData setting -function filterEventData(event, resolveData) { - if (resolveData === 'none') { - const { eventData: _eventData, ...rest } = event; - return rest; - } - return event; -} -// Would usually "EventSchema.omit({ eventData: true })" but that doesn't work -// on zod unions. Re-creating the schema manually. -const EventWithRefsSchema = z__default.object({ - eventId: z__default.string(), - runId: z__default.string(), - eventType: EventTypeSchema, - correlationId: z__default.string().optional(), - eventDataRef: z__default.any().optional(), - createdAt: z__default.coerce.date(), -}); -// Functions -async function getWorkflowRunEvents(params, config) { - const searchParams = new URLSearchParams(); - const { pagination, resolveData = DEFAULT_RESOLVE_DATA_OPTION } = params; - let runId; - let correlationId; - if ('runId' in params) { - runId = params.runId; - } - else { - correlationId = params.correlationId; - } - if (!runId && !correlationId) { - throw new Error('Either runId or correlationId must be provided'); - } - if (pagination?.limit) - searchParams.set('limit', pagination.limit.toString()); - if (pagination?.cursor) - searchParams.set('cursor', pagination.cursor); - if (pagination?.sortOrder) - searchParams.set('sortOrder', pagination.sortOrder); - if (correlationId) - searchParams.set('correlationId', correlationId); - const remoteRefBehavior = resolveData === 'none' ? 'lazy' : 'resolve'; - searchParams.set('remoteRefBehavior', remoteRefBehavior); - const queryString = searchParams.toString(); - const query = queryString ? `?${queryString}` : ''; - const endpoint = correlationId - ? `/v1/events${query}` - : `/v1/runs/${runId}/events${query}`; - const response = (await makeRequest({ - endpoint, - options: { method: 'GET' }, - config, - schema: PaginatedResponseSchema(remoteRefBehavior === 'lazy' ? EventWithRefsSchema : EventSchema), - })); - return { - ...response, - data: response.data.map((event) => filterEventData(event, resolveData)), - }; -} -async function createWorkflowRunEvent(id, data, params, config) { - const resolveData = params?.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION; - const event = await makeRequest({ - endpoint: `/v1/runs/${id}/events`, - options: { - method: 'POST', - body: JSON.stringify(data, dateToStringReplacer), - }, - config, - schema: EventSchema, - }); - return filterEventData(event, resolveData); -} - -// Helper to filter hook data based on resolveData setting -function filterHookData(hook, resolveData) { - if (resolveData === 'none') { - const { metadataRef: _metadataRef, ...rest } = hook; - return rest; - } - return hook; -} -const HookWithRefsSchema = HookSchema.omit({ - metadata: true, -}).extend({ - metadataRef: z__default.any().optional(), -}); -async function listHooks(params, config) { - const { runId, pagination, resolveData = DEFAULT_RESOLVE_DATA_OPTION, } = params; - const searchParams = new URLSearchParams(); - if (pagination?.limit) - searchParams.set('limit', pagination.limit.toString()); - if (pagination?.cursor) - searchParams.set('cursor', pagination.cursor); - if (pagination?.sortOrder) - searchParams.set('sortOrder', pagination.sortOrder); - // Map resolveData to internal RemoteRefBehavior - const remoteRefBehavior = resolveData === 'none' ? 'lazy' : 'resolve'; - searchParams.set('remoteRefBehavior', remoteRefBehavior); - if (runId) - searchParams.set('runId', runId); - const queryString = searchParams.toString(); - const endpoint = `/v1/hooks${queryString ? `?${queryString}` : ''}`; - const response = (await makeRequest({ - endpoint, - options: { method: 'GET' }, - config, - schema: PaginatedResponseSchema(remoteRefBehavior === 'lazy' ? HookWithRefsSchema : HookSchema), - })); - return { - ...response, - data: response.data.map((hook) => filterHookData(hook, resolveData)), - }; -} -async function getHook(hookId, params, config) { - const resolveData = params?.resolveData || 'all'; - const endpoint = `/v1/hooks/${hookId}`; - const hook = await makeRequest({ - endpoint, - options: { method: 'GET' }, - config, - schema: HookSchema, - }); - return filterHookData(hook, resolveData); -} -async function createHook(runId, data, config) { - return makeRequest({ - endpoint: `/v1/hooks/create`, - options: { - method: 'POST', - body: JSON.stringify({ - runId, - ...data, - }, dateToStringReplacer), - }, - config, - schema: HookSchema, - }); -} -async function getHookByToken(token, config) { - return makeRequest({ - endpoint: `/v1/hooks/by-token?token=${encodeURIComponent(token)}`, - options: { - method: 'GET', - }, - config, - schema: HookSchema, - }); -} -async function disposeHook(hookId, config) { - return makeRequest({ - endpoint: `/v1/hooks/${hookId}`, - options: { method: 'DELETE' }, - config, - schema: HookSchema, - }); -} - -/** - * Wire format schema for workflow runs coming from the backend. - * The backend returns error as a JSON string, not an object, so we need - * a schema that accepts the wire format before deserialization. - * - * This is used for validation in makeRequest(), then deserializeError() - * transforms the string into the expected StructuredError object. - */ -const WorkflowRunWireBaseSchema = WorkflowRunBaseSchema.omit({ - error: true, -}).extend({ - // Backend returns error as a JSON string, not an object - error: z$1.string().optional(), -}); -// Wire schema for resolved data (full input/output) -const WorkflowRunWireSchema = WorkflowRunWireBaseSchema; -// Wire schema for lazy mode with refs instead of data -const WorkflowRunWireWithRefsSchema = WorkflowRunWireBaseSchema.omit({ - input: true, - output: true, -}).extend({ - // We discard the results of the refs, so we don't care about the type here - inputRef: z$1.any().optional(), - outputRef: z$1.any().optional(), - input: z$1.array(z$1.any()).optional(), - output: z$1.any().optional(), -}); -// Helper to filter run data based on resolveData setting -function filterRunData(run, resolveData) { - if (resolveData === 'none') { - const { inputRef: _inputRef, outputRef: _outputRef, ...rest } = run; - const deserialized = deserializeError(rest); - return { - ...deserialized, - input: [], - output: undefined, - }; - } - return deserializeError(run); -} -// Functions -/** - * This query technically works but should be used sparingly till the backend - * uses CH to resolve this instead of scanning a dynamo table. - */ -async function listWorkflowRuns(params = {}, config) { - const { workflowName, status, pagination, resolveData = DEFAULT_RESOLVE_DATA_OPTION, } = params; - const searchParams = new URLSearchParams(); - if (workflowName) - searchParams.set('workflowName', workflowName); - if (status) - searchParams.set('status', status); - if (pagination?.limit) - searchParams.set('limit', pagination.limit.toString()); - if (pagination?.cursor) - searchParams.set('cursor', pagination.cursor); - if (pagination?.sortOrder) - searchParams.set('sortOrder', pagination.sortOrder); - // Map resolveData to internal RemoteRefBehavior - const remoteRefBehavior = resolveData === 'none' ? 'lazy' : 'resolve'; - searchParams.set('remoteRefBehavior', remoteRefBehavior); - const queryString = searchParams.toString(); - const endpoint = `/v1/runs${queryString ? `?${queryString}` : ''}`; - const response = (await makeRequest({ - endpoint, - options: { method: 'GET' }, - config, - schema: PaginatedResponseSchema(remoteRefBehavior === 'lazy' - ? WorkflowRunWireWithRefsSchema - : WorkflowRunWireSchema), - })); - return { - ...response, - data: response.data.map((run) => filterRunData(run, resolveData)), - }; -} -async function createWorkflowRun(data, config) { - const run = await makeRequest({ - endpoint: '/v1/runs/create', - options: { - method: 'POST', - body: JSON.stringify(data, dateToStringReplacer), - }, - config, - schema: WorkflowRunWireSchema, - }); - return deserializeError(run); -} -async function getWorkflowRun(id, params, config) { - const resolveData = params?.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION; - const remoteRefBehavior = resolveData === 'none' ? 'lazy' : 'resolve'; - const searchParams = new URLSearchParams(); - searchParams.set('remoteRefBehavior', remoteRefBehavior); - const queryString = searchParams.toString(); - const endpoint = `/v1/runs/${id}${queryString ? `?${queryString}` : ''}`; - try { - const run = await makeRequest({ - endpoint, - options: { method: 'GET' }, - config, - schema: (remoteRefBehavior === 'lazy' - ? WorkflowRunWireWithRefsSchema - : WorkflowRunWireSchema), - }); - return filterRunData(run, resolveData); - } - catch (error) { - if (error instanceof WorkflowAPIError && error.status === 404) { - throw new WorkflowRunNotFoundError(id); - } - throw error; - } -} -async function updateWorkflowRun(id, data, config) { - try { - const serialized = serializeError(data); - const run = await makeRequest({ - endpoint: `/v1/runs/${id}`, - options: { - method: 'PUT', - body: JSON.stringify(serialized, dateToStringReplacer), - }, - config, - schema: WorkflowRunWireSchema, - }); - return deserializeError(run); - } - catch (error) { - if (error instanceof WorkflowAPIError && error.status === 404) { - throw new WorkflowRunNotFoundError(id); - } - throw error; - } -} -async function cancelWorkflowRun(id, params, config) { - const resolveData = params?.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION; - const remoteRefBehavior = resolveData === 'none' ? 'lazy' : 'resolve'; - const searchParams = new URLSearchParams(); - searchParams.set('remoteRefBehavior', remoteRefBehavior); - const queryString = searchParams.toString(); - const endpoint = `/v1/runs/${id}/cancel${queryString ? `?${queryString}` : ''}`; - try { - const run = await makeRequest({ - endpoint, - options: { method: 'PUT' }, - config, - schema: (remoteRefBehavior === 'lazy' - ? WorkflowRunWireWithRefsSchema - : WorkflowRunWireSchema), - }); - return filterRunData(run, resolveData); - } - catch (error) { - if (error instanceof WorkflowAPIError && error.status === 404) { - throw new WorkflowRunNotFoundError(id); - } - throw error; - } -} -async function pauseWorkflowRun(id, params, config) { - const resolveData = params?.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION; - const remoteRefBehavior = resolveData === 'none' ? 'lazy' : 'resolve'; - const searchParams = new URLSearchParams(); - searchParams.set('remoteRefBehavior', remoteRefBehavior); - const queryString = searchParams.toString(); - const endpoint = `/v1/runs/${id}/pause${queryString ? `?${queryString}` : ''}`; - try { - const run = await makeRequest({ - endpoint, - options: { method: 'PUT' }, - config, - schema: (remoteRefBehavior === 'lazy' - ? WorkflowRunWireWithRefsSchema - : WorkflowRunWireSchema), - }); - return filterRunData(run, resolveData); - } - catch (error) { - if (error instanceof WorkflowAPIError && error.status === 404) { - throw new WorkflowRunNotFoundError(id); - } - throw error; - } -} -async function resumeWorkflowRun(id, params, config) { - const resolveData = params?.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION; - const remoteRefBehavior = resolveData === 'none' ? 'lazy' : 'resolve'; - const searchParams = new URLSearchParams(); - searchParams.set('remoteRefBehavior', remoteRefBehavior); - const queryString = searchParams.toString(); - const endpoint = `/v1/runs/${id}/resume${queryString ? `?${queryString}` : ''}`; - try { - const run = await makeRequest({ - endpoint, - options: { method: 'PUT' }, - config, - schema: (remoteRefBehavior === 'lazy' - ? WorkflowRunWireWithRefsSchema - : WorkflowRunWireSchema), - }); - return filterRunData(run, resolveData); - } - catch (error) { - if (error instanceof WorkflowAPIError && error.status === 404) { - throw new WorkflowRunNotFoundError(id); - } - throw error; - } -} - -/** - * Wire format schema for steps coming from the backend. - * The backend returns error as a JSON string, not an object, so we need - * a schema that accepts the wire format before deserialization. - * - * This is used for validation in makeRequest(), then deserializeStepError() - * transforms the string into the expected StructuredError object. - */ -const StepWireSchema = StepSchema.omit({ - error: true, -}).extend({ - // Backend returns error as a JSON string, not an object - error: z$1.string().optional(), -}); -// Wire schema for lazy mode with refs instead of data -const StepWireWithRefsSchema = StepWireSchema.omit({ - input: true, - output: true, -}).extend({ - // We discard the results of the refs, so we don't care about the type here - inputRef: z$1.any().optional(), - outputRef: z$1.any().optional(), - input: z$1.array(z$1.any()).optional(), - output: z$1.any().optional(), -}); -// Helper to filter step data based on resolveData setting -function filterStepData(step, resolveData) { - if (resolveData === 'none') { - const { inputRef: _inputRef, outputRef: _outputRef, ...rest } = step; - const deserialized = deserializeError(rest); - return { - ...deserialized, - input: [], - output: undefined, - }; - } - return deserializeError(step); -} -// Functions -async function listWorkflowRunSteps(params, config) { - const { runId, pagination, resolveData = DEFAULT_RESOLVE_DATA_OPTION, } = params; - const searchParams = new URLSearchParams(); - if (pagination?.cursor) - searchParams.set('cursor', pagination.cursor); - if (pagination?.limit) - searchParams.set('limit', pagination.limit.toString()); - if (pagination?.sortOrder) - searchParams.set('sortOrder', pagination.sortOrder); - // Map resolveData to internal RemoteRefBehavior - const remoteRefBehavior = resolveData === 'none' ? 'lazy' : 'resolve'; - searchParams.set('remoteRefBehavior', remoteRefBehavior); - const queryString = searchParams.toString(); - const endpoint = `/v1/runs/${runId}/steps${queryString ? `?${queryString}` : ''}`; - const response = (await makeRequest({ - endpoint, - options: { method: 'GET' }, - config, - schema: PaginatedResponseSchema(remoteRefBehavior === 'lazy' ? StepWireWithRefsSchema : StepWireSchema), - })); - return { - ...response, - data: response.data.map((step) => filterStepData(step, resolveData)), - }; -} -async function createStep(runId, data, config) { - const step = await makeRequest({ - endpoint: `/v1/runs/${runId}/steps`, - options: { - method: 'POST', - body: JSON.stringify(data, dateToStringReplacer), - }, - config, - schema: StepWireSchema, - }); - return deserializeError(step); -} -async function updateStep(runId, stepId, data, config) { - const serialized = serializeError(data); - const step = await makeRequest({ - endpoint: `/v1/runs/${runId}/steps/${stepId}`, - options: { - method: 'PUT', - body: JSON.stringify(serialized, dateToStringReplacer), - }, - config, - schema: StepWireSchema, - }); - return deserializeError(step); -} -async function getStep(runId, stepId, params, config) { - const resolveData = params?.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION; - const remoteRefBehavior = resolveData === 'none' ? 'lazy' : 'resolve'; - const searchParams = new URLSearchParams(); - searchParams.set('remoteRefBehavior', remoteRefBehavior); - const queryString = searchParams.toString(); - const endpoint = runId - ? `/v1/runs/${runId}/steps/${stepId}${queryString ? `?${queryString}` : ''}` - : `/v1/steps/${stepId}${queryString ? `?${queryString}` : ''}`; - const step = await makeRequest({ - endpoint, - options: { method: 'GET' }, - config, - schema: (remoteRefBehavior === 'lazy' - ? StepWireWithRefsSchema - : StepWireSchema), - }); - return filterStepData(step, resolveData); -} - -function createStorage(config) { - return { - // Storage interface with namespaced methods - runs: { - create: (data) => createWorkflowRun(data, config), - get: (id, params) => getWorkflowRun(id, params, config), - update: (id, data) => updateWorkflowRun(id, data, config), - list: (params) => listWorkflowRuns(params, config), - cancel: (id, params) => cancelWorkflowRun(id, params, config), - pause: (id, params) => pauseWorkflowRun(id, params, config), - resume: (id, params) => resumeWorkflowRun(id, params, config), - }, - steps: { - create: (runId, data) => createStep(runId, data, config), - get: (runId, stepId, params) => getStep(runId, stepId, params, config), - update: (runId, stepId, data) => updateStep(runId, stepId, data, config), - list: (params) => listWorkflowRunSteps(params, config), - }, - events: { - create: (runId, data, params) => createWorkflowRunEvent(runId, data, params, config), - list: (params) => getWorkflowRunEvents(params, config), - listByCorrelationId: (params) => getWorkflowRunEvents(params, config), - }, - hooks: { - create: (runId, data) => createHook(runId, data, config), - get: (hookId, params) => getHook(hookId, params, config), - getByToken: (token) => getHookByToken(token, config), - list: (params) => listHooks(params, config), - dispose: (hookId) => disposeHook(hookId, config), - }, - }; -} - -function getStreamUrl(name, httpConfig) { - return new URL(`${httpConfig.baseUrl}/v1/stream/${encodeURIComponent(name)}`); -} -function createStreamer(config) { - return { - async writeToStream(name, chunk) { - const httpConfig = await getHttpConfig(config); - await fetch(getStreamUrl(name, httpConfig), { - method: 'PUT', - body: chunk, - headers: httpConfig.headers, - duplex: 'half', - }); - }, - async closeStream(name) { - const httpConfig = await getHttpConfig(config); - httpConfig.headers.set('X-Stream-Done', 'true'); - await fetch(getStreamUrl(name, httpConfig), { - method: 'PUT', - headers: httpConfig.headers, - }); - }, - async readFromStream(name, startIndex) { - const httpConfig = await getHttpConfig(config); - const url = getStreamUrl(name, httpConfig); - if (typeof startIndex === 'number') { - url.searchParams.set('startIndex', String(startIndex)); - } - const res = await fetch(url, { headers: httpConfig.headers }); - if (!res.ok) - throw new Error(`Failed to fetch stream: ${res.status}`); - return res.body; - }, - }; -} - -function createVercelWorld(config) { - return { - ...createQueue(config), - ...createStorage(config), - ...createStreamer(config), - }; -} - -const require$1 = createRequire(join(process.cwd(), 'index.js')); -let worldCache; -let stubbedWorldCache; -function defaultWorld() { - if (process.env.VERCEL_DEPLOYMENT_ID) { - return 'vercel'; - } - return 'embedded'; -} -/** - * Create a new world instance based on environment variables. - * WORKFLOW_TARGET_WORLD is used to determine the target world. - * All other environment variables are specific to the target world - */ -const createWorld = () => { - const targetWorld = process.env.WORKFLOW_TARGET_WORLD || defaultWorld(); - if (targetWorld === 'vercel') { - return createVercelWorld({ - baseUrl: process.env.WORKFLOW_VERCEL_PROXY_URL, - token: process.env.WORKFLOW_VERCEL_AUTH_TOKEN, - projectConfig: { - environment: process.env.WORKFLOW_VERCEL_ENV, - projectId: process.env.WORKFLOW_VERCEL_PROJECT, - teamId: process.env.WORKFLOW_VERCEL_TEAM, - }, - }); - } - if (targetWorld === 'embedded') { - return createEmbeddedWorld({ - dataDir: process.env.WORKFLOW_EMBEDDED_DATA_DIR, - }); - } - const mod = require$1(targetWorld); - if (typeof mod === 'function') { - return mod(); - } - else if (typeof mod.default === 'function') { - return mod.default(); - } - else if (typeof mod.createWorld === 'function') { - return mod.createWorld(); - } - throw new Error(`Invalid target world module: ${targetWorld}, must export a default function or createWorld function that returns a World instance.`); -}; -/** - * Some functions from the world are needed at build time, but we do NOT want - * to cache the world in those instances for general use, since we don't have - * the correct environment variables set yet. This is a safe function to - * call at build time, that only gives access to non-environment-bound world - * functions. The only binding value should be the target world. - * Once we migrate to a file-based configuration (workflow.config.ts), we should - * be able to re-combine getWorld and getWorldHandlers into one singleton. - */ -const getWorldHandlers = () => { - if (stubbedWorldCache) { - return stubbedWorldCache; - } - const _world = createWorld(); - stubbedWorldCache = _world; - return { - createQueueHandler: _world.createQueueHandler, - }; -}; -const getWorld = () => { - if (worldCache) { - return worldCache; - } - worldCache = createWorld(); - return worldCache; -}; - -// OpenTelemetry trace context for distributed tracing -const TraceCarrierSchema = z$1.record(z$1.string(), z$1.string()); -const WorkflowInvokePayloadSchema = z$1.object({ - runId: z$1.string(), - traceCarrier: TraceCarrierSchema.optional(), -}); -const StepInvokePayloadSchema = z$1.object({ - workflowName: z$1.string(), - workflowRunId: z$1.string(), - workflowStartedAt: z$1.number(), - stepId: z$1.string(), - traceCarrier: TraceCarrierSchema.optional(), -}); - -const WORKFLOW_USE_STEP = Symbol.for('WORKFLOW_USE_STEP'); -const WORKFLOW_CREATE_HOOK = Symbol.for('WORKFLOW_CREATE_HOOK'); -const WORKFLOW_SLEEP = Symbol.for('WORKFLOW_SLEEP'); -const WORKFLOW_GET_STREAM_ID = Symbol.for('WORKFLOW_GET_STREAM_ID'); -const STREAM_NAME_SYMBOL = Symbol.for('WORKFLOW_STREAM_NAME'); -const STREAM_TYPE_SYMBOL = Symbol.for('WORKFLOW_STREAM_TYPE'); -const BODY_INIT_SYMBOL = Symbol.for('BODY_INIT'); -const WEBHOOK_RESPONSE_WRITABLE = Symbol.for('WEBHOOK_RESPONSE_WRITABLE'); -const STEP_FUNCTION_NAME_SYMBOL = Symbol.for('WORKFLOW_STEP_FUNCTION_NAME'); - -/** - * Detect if a readable stream is a byte stream. - * - * @param stream - * @returns `"bytes"` if the stream is a byte stream, `undefined` otherwise - */ -function getStreamType(stream) { - try { - const reader = stream.getReader({ mode: 'byob' }); - reader.releaseLock(); - return 'bytes'; - } - catch { } -} -function getSerializeStream(reducers) { - const encoder = new TextEncoder(); - const stream = new TransformStream({ - transform(chunk, controller) { - try { - const serialized = devalue.stringify(chunk, reducers); - controller.enqueue(encoder.encode(`${serialized}\n`)); - } - catch (error) { - controller.error(new WorkflowRuntimeError("Failed to serialize stream chunk. Ensure you're passing serializable types (plain objects, arrays, primitives, Date, RegExp, Map, Set).", { slug: 'serialization-failed', cause: error })); - } - }, - }); - return stream; -} -function getDeserializeStream(revivers) { - const decoder = new TextDecoder(); - let buffer = ''; - const stream = new TransformStream({ - transform(chunk, controller) { - // Append new chunk to buffer - buffer += decoder.decode(chunk, { stream: true }); - // Process all complete lines - while (true) { - const newlineIndex = buffer.indexOf('\n'); - if (newlineIndex === -1) - break; - const line = buffer.slice(0, newlineIndex); - buffer = buffer.slice(newlineIndex + 1); - if (line.length > 0) { - const obj = devalue.parse(line, revivers); - controller.enqueue(obj); - } - } - }, - flush(controller) { - // Process any remaining data in the buffer at the end of the stream - if (buffer && buffer.length > 0) { - const obj = devalue.parse(buffer, revivers); - controller.enqueue(obj); - } - }, - }); - return stream; -} -class WorkflowServerReadableStream extends ReadableStream { - #reader; - constructor(name, startIndex) { - if (typeof name !== 'string' || name.length === 0) { - throw new Error(`"name" is required, got "${name}"`); - } - super({ - // @ts-expect-error Not sure why TypeScript is complaining about this - type: 'bytes', - pull: async (controller) => { - let reader = this.#reader; - if (!reader) { - const world = getWorld(); - const stream = await world.readFromStream(name, startIndex); - reader = this.#reader = stream.getReader(); - } - if (!reader) { - controller.error(new Error('Failed to get reader')); - return; - } - const result = await reader.read(); - if (result.done) { - this.#reader = undefined; - controller.close(); - } - else { - controller.enqueue(result.value); - } - }, - }); - } -} -class WorkflowServerWritableStream extends WritableStream { - constructor(name) { - if (typeof name !== 'string' || name.length === 0) { - throw new Error(`"name" is required, got "${name}"`); - } - const world = getWorld(); - super({ - async write(chunk) { - await world.writeToStream(name, chunk); - }, - async close() { - await world.closeStream(name); - }, - }); - } -} -function revive(str) { - // biome-ignore lint/security/noGlobalEval: Eval is safe here - we are only passing value from `devalue.stringify()` - // biome-ignore lint/complexity/noCommaOperator: This is how you do global scope eval - return (0, eval)(`(${str})`); -} -function getCommonReducers(global = globalThis) { - const abToBase64 = (value, offset, length) => { - // Avoid returning falsy value for zero-length buffers - if (length === 0) - return '.'; - return Buffer.from(value, offset, length).toString('base64'); - }; - const viewToBase64 = (value) => abToBase64(value.buffer, value.byteOffset, value.byteLength); - return { - ArrayBuffer: (value) => value instanceof global.ArrayBuffer && - abToBase64(value, 0, value.byteLength), - BigInt: (value) => typeof value === 'bigint' && value.toString(), - BigInt64Array: (value) => value instanceof global.BigInt64Array && viewToBase64(value), - BigUint64Array: (value) => value instanceof global.BigUint64Array && viewToBase64(value), - Date: (value) => { - if (!(value instanceof global.Date)) - return false; - const valid = !Number.isNaN(value.getDate()); - // Note: "." is to avoid returning a falsy value when the date is invalid - return valid ? value.toISOString() : '.'; - }, - Error: (value) => { - if (!(value instanceof global.Error)) - return false; - return { - name: value.name, - message: value.message, - stack: value.stack, - }; - }, - Float32Array: (value) => value instanceof global.Float32Array && viewToBase64(value), - Float64Array: (value) => value instanceof global.Float64Array && viewToBase64(value), - Headers: (value) => value instanceof global.Headers && Array.from(value), - Int8Array: (value) => value instanceof global.Int8Array && viewToBase64(value), - Int16Array: (value) => value instanceof global.Int16Array && viewToBase64(value), - Int32Array: (value) => value instanceof global.Int32Array && viewToBase64(value), - Map: (value) => value instanceof global.Map && Array.from(value), - RegExp: (value) => value instanceof global.RegExp && { - source: value.source, - flags: value.flags, - }, - Request: (value) => { - if (!(value instanceof global.Request)) - return false; - const data = { - method: value.method, - url: value.url, - headers: value.headers, - body: value.body, - duplex: value.duplex, - }; - const responseWritable = value[WEBHOOK_RESPONSE_WRITABLE]; - if (responseWritable) { - data.responseWritable = responseWritable; - } - return data; - }, - Response: (value) => { - if (!(value instanceof global.Response)) - return false; - return { - type: value.type, - url: value.url, - status: value.status, - statusText: value.statusText, - headers: value.headers, - body: value.body, - redirected: value.redirected, - }; - }, - Set: (value) => value instanceof global.Set && Array.from(value), - StepFunction: (value) => { - if (typeof value !== 'function') - return false; - const stepName = value[STEP_FUNCTION_NAME_SYMBOL]; - return typeof stepName === 'string' ? stepName : false; - }, - URL: (value) => value instanceof global.URL && value.href, - URLSearchParams: (value) => { - if (!(value instanceof global.URLSearchParams)) - return false; - // Avoid returning a falsy value when the URLSearchParams is empty - if (value.size === 0) - return '.'; - return String(value); - }, - Uint8Array: (value) => value instanceof global.Uint8Array && viewToBase64(value), - Uint8ClampedArray: (value) => value instanceof global.Uint8ClampedArray && viewToBase64(value), - Uint16Array: (value) => value instanceof global.Uint16Array && viewToBase64(value), - Uint32Array: (value) => value instanceof global.Uint32Array && viewToBase64(value), - }; -} -/** - * Reducers for serialization boundary from the client side, passing arguments - * to the workflow handler. - * - * @param global - * @param ops - * @returns - */ -function getExternalReducers(global = globalThis, ops) { - return { - ...getCommonReducers(global), - ReadableStream: (value) => { - if (!(value instanceof global.ReadableStream)) - return false; - // Stream must not be locked when passing across execution boundary - if (value.locked) { - throw new Error('ReadableStream is locked'); - } - const name = global.crypto.randomUUID(); - const type = getStreamType(value); - const writable = new WorkflowServerWritableStream(name); - if (type === 'bytes') { - ops.push(value.pipeTo(writable)); - } - else { - ops.push(value - .pipeThrough(getSerializeStream(getExternalReducers(global, ops))) - .pipeTo(writable)); - } - const s = { name }; - if (type) - s.type = type; - return s; - }, - WritableStream: (value) => { - if (!(value instanceof global.WritableStream)) - return false; - const name = global.crypto.randomUUID(); - ops.push(new WorkflowServerReadableStream(name) - .pipeThrough(getDeserializeStream(getExternalRevivers(global, ops))) - .pipeTo(value)); - return { name }; - }, - }; -} -/** - * Reducers for serialization boundary from within the workflow execution - * environment, passing return value to the client side and into step arguments. - * - * @param global - * @returns - */ -function getWorkflowReducers(global = globalThis) { - return { - ...getCommonReducers(global), - // Readable/Writable streams from within the workflow execution environment - // are simply "handles" that can be passed around to other steps. - ReadableStream: (value) => { - if (!(value instanceof global.ReadableStream)) - return false; - // Check if this is a fake stream storing BodyInit from Request/Response constructor - const bodyInit = value[BODY_INIT_SYMBOL]; - if (bodyInit !== undefined) { - // This is a fake stream - serialize the BodyInit directly - // devalue will handle serializing strings, Uint8Array, etc. - return { bodyInit }; - } - const name = value[STREAM_NAME_SYMBOL]; - if (!name) { - throw new Error('ReadableStream `name` is not set'); - } - const s = { name }; - const type = value[STREAM_TYPE_SYMBOL]; - if (type) - s.type = type; - return s; - }, - WritableStream: (value) => { - if (!(value instanceof global.WritableStream)) - return false; - const name = value[STREAM_NAME_SYMBOL]; - if (!name) { - throw new Error('WritableStream `name` is not set'); - } - return { name }; - }, - }; -} -/** - * Reducers for serialization boundary from within the step execution - * environment, passing return value to the workflow handler. - * - * @param global - * @param ops - * @returns - */ -function getStepReducers(global = globalThis, ops) { - return { - ...getCommonReducers(global), - ReadableStream: (value) => { - if (!(value instanceof global.ReadableStream)) - return false; - // Stream must not be locked when passing across execution boundary - if (value.locked) { - throw new Error('ReadableStream is locked'); - } - // Check if the stream already has the name symbol set, in which case - // it's already being sunk to the server and we can just return the - // name and type. - let name = value[STREAM_NAME_SYMBOL]; - let type = value[STREAM_TYPE_SYMBOL]; - if (!name) { - name = global.crypto.randomUUID(); - type = getStreamType(value); - const writable = new WorkflowServerWritableStream(name); - if (type === 'bytes') { - ops.push(value.pipeTo(writable)); - } - else { - ops.push(value - .pipeThrough(getSerializeStream(getStepReducers(global, ops))) - .pipeTo(writable)); - } - } - const s = { name }; - if (type) - s.type = type; - return s; - }, - WritableStream: (value) => { - if (!(value instanceof global.WritableStream)) - return false; - let name = value[STREAM_NAME_SYMBOL]; - if (!name) { - name = global.crypto.randomUUID(); - ops.push(new WorkflowServerReadableStream(name) - .pipeThrough(getDeserializeStream(getStepRevivers(global, ops))) - .pipeTo(value)); - } - return { name }; - }, - }; -} -function getCommonRevivers(global = globalThis) { - function reviveArrayBuffer(value) { - // Handle sentinel value for zero-length buffers - const base64 = value === '.' ? '' : value; - const buffer = Buffer.from(base64, 'base64'); - const arrayBuffer = new global.ArrayBuffer(buffer.length); - const uint8Array = new global.Uint8Array(arrayBuffer); - uint8Array.set(buffer); - return arrayBuffer; - } - return { - ArrayBuffer: reviveArrayBuffer, - BigInt: (value) => global.BigInt(value), - BigInt64Array: (value) => { - const ab = reviveArrayBuffer(value); - return new global.BigInt64Array(ab); - }, - BigUint64Array: (value) => { - const ab = reviveArrayBuffer(value); - return new global.BigUint64Array(ab); - }, - Date: (value) => new global.Date(value), - Error: (value) => { - const error = new global.Error(value.message); - error.name = value.name; - error.stack = value.stack; - return error; - }, - Float32Array: (value) => { - const ab = reviveArrayBuffer(value); - return new global.Float32Array(ab); - }, - Float64Array: (value) => { - const ab = reviveArrayBuffer(value); - return new global.Float64Array(ab); - }, - Headers: (value) => new global.Headers(value), - Int8Array: (value) => { - const ab = reviveArrayBuffer(value); - return new global.Int8Array(ab); - }, - Int16Array: (value) => { - const ab = reviveArrayBuffer(value); - return new global.Int16Array(ab); - }, - Int32Array: (value) => { - const ab = reviveArrayBuffer(value); - return new global.Int32Array(ab); - }, - Map: (value) => new global.Map(value), - RegExp: (value) => new global.RegExp(value.source, value.flags), - Set: (value) => new global.Set(value), - StepFunction: (value) => { - const stepFn = getStepFunction(value); - if (!stepFn) { - throw new Error(`Step function "${value}" not found. Make sure the step function is registered.`); - } - return stepFn; - }, - URL: (value) => new global.URL(value), - URLSearchParams: (value) => new global.URLSearchParams(value === '.' ? '' : value), - Uint8Array: (value) => { - const ab = reviveArrayBuffer(value); - return new global.Uint8Array(ab); - }, - Uint8ClampedArray: (value) => { - const ab = reviveArrayBuffer(value); - return new global.Uint8ClampedArray(ab); - }, - Uint16Array: (value) => { - const ab = reviveArrayBuffer(value); - return new global.Uint16Array(ab); - }, - Uint32Array: (value) => { - const ab = reviveArrayBuffer(value); - return new global.Uint32Array(ab); - }, - }; -} -/** - * Revivers for deserialization boundary from the client side, - * receiving the return value from the workflow handler. - * - * @param global - * @param ops - */ -function getExternalRevivers(global = globalThis, ops) { - return { - ...getCommonRevivers(global), - Request: (value) => { - return new global.Request(value.url, { - method: value.method, - headers: new global.Headers(value.headers), - body: value.body, - duplex: value.duplex, - }); - }, - Response: (value) => { - // Note: Response constructor only accepts status, statusText, and headers - // The type, url, and redirected properties are read-only and set by the constructor - return new global.Response(value.body, { - status: value.status, - statusText: value.statusText, - headers: new global.Headers(value.headers), - }); - }, - ReadableStream: (value) => { - // If this has bodyInit, it came from a Response constructor - // Convert it to a REAL stream now that we're outside the workflow - if ('bodyInit' in value) { - const bodyInit = value.bodyInit; - // Use the native Response constructor to properly convert BodyInit to ReadableStream - const response = new global.Response(bodyInit); - return response.body; - } - const readable = new WorkflowServerReadableStream(value.name, value.startIndex); - if (value.type === 'bytes') { - return readable; - } - else { - const transform = getDeserializeStream(getExternalRevivers(global, ops)); - ops.push(readable.pipeTo(transform.writable)); - return transform.readable; - } - }, - WritableStream: (value) => { - const serialize = getSerializeStream(getExternalReducers(global, ops)); - ops.push(serialize.readable.pipeTo(new WorkflowServerWritableStream(value.name))); - return serialize.writable; - }, - }; -} -/** - * Revivers for deserialization boundary from within the workflow execution - * environment, receiving arguments from the client side, and return values - * from the steps. - * - * @param global - * @returns - */ -function getWorkflowRevivers(global = globalThis) { - return { - ...getCommonRevivers(global), - Request: (value) => { - Object.setPrototypeOf(value, global.Request.prototype); - const responseWritable = value.responseWritable; - if (responseWritable) { - value[WEBHOOK_RESPONSE_WRITABLE] = responseWritable; - delete value.responseWritable; - value.respondWith = () => { - throw new Error('`respondWith()` must be called from within a step function'); - }; - } - return value; - }, - Response: (value) => { - Object.setPrototypeOf(value, global.Response.prototype); - return value; - }, - ReadableStream: (value) => { - // Check if this is a BodyInit that should be wrapped in a fake stream - if ('bodyInit' in value) { - // Recreate the fake stream with the BodyInit - return Object.create(global.ReadableStream.prototype, { - [BODY_INIT_SYMBOL]: { - value: value.bodyInit, - writable: false, - }, - }); - } - // Regular stream handling - return Object.create(global.ReadableStream.prototype, { - [STREAM_NAME_SYMBOL]: { - value: value.name, - writable: false, - }, - [STREAM_TYPE_SYMBOL]: { - value: value.type, - writable: false, - }, - }); - }, - WritableStream: (value) => { - return Object.create(global.WritableStream.prototype, { - [STREAM_NAME_SYMBOL]: { - value: value.name, - writable: false, - }, - }); - }, - }; -} -/** - * Revivers for deserialization boundary from within the step execution - * environment, receiving arguments from the workflow handler. - * - * @param global - * @param ops - * @returns - */ -function getStepRevivers(global = globalThis, ops) { - return { - ...getCommonRevivers(global), - Request: (value) => { - const responseWritable = value.responseWritable; - const request = new global.Request(value.url, { - method: value.method, - headers: new global.Headers(value.headers), - body: value.body, - duplex: value.duplex, - }); - if (responseWritable) { - request.respondWith = async (response) => { - const writer = responseWritable.getWriter(); - await writer.write(response); - await writer.close(); - }; - } - return request; - }, - Response: (value) => { - // Note: Response constructor only accepts status, statusText, and headers - // The type, url, and redirected properties are read-only and set by the constructor - return new global.Response(value.body, { - status: value.status, - statusText: value.statusText, - headers: new global.Headers(value.headers), - }); - }, - ReadableStream: (value) => { - // If this has bodyInit, it came from a Response constructor - // Convert it to a REAL stream now that we're in the step environment - if ('bodyInit' in value) { - const bodyInit = value.bodyInit; - // Use the native Response constructor to properly convert BodyInit to ReadableStream - const response = new global.Response(bodyInit); - return response.body; - } - const readable = new WorkflowServerReadableStream(value.name); - if (value.type === 'bytes') { - return readable; - } - else { - const transform = getDeserializeStream(getStepRevivers(global, ops)); - ops.push(readable.pipeTo(transform.writable)); - return transform.readable; - } - }, - WritableStream: (value) => { - const serialize = getSerializeStream(getStepReducers(global, ops)); - ops.push(serialize.readable.pipeTo(new WorkflowServerWritableStream(value.name))); - return serialize.writable; - }, - }; -} -/** - * Called from the `start()` function to serialize the workflow arguments - * into a format that can be saved to the database and then hydrated from - * within the workflow execution environment. - * - * @param value - * @param global - * @returns The dehydrated value, ready to be inserted into the database - */ -function dehydrateWorkflowArguments(value, ops, global = globalThis) { - try { - const str = devalue.stringify(value, getExternalReducers(global, ops)); - return revive(str); - } - catch (error) { - throw new WorkflowRuntimeError(`Failed to serialize workflow arguments. Ensure you're passing serializable types (plain objects, arrays, primitives, Date, RegExp, Map, Set).`, { slug: 'serialization-failed', cause: error }); - } -} -/** - * Called from workflow execution environment to hydrate the workflow - * arguments from the database at the start of workflow execution. - * - * @param value - * @param ops - * @param global - * @returns The hydrated value - */ -function hydrateWorkflowArguments(value, global = globalThis, extraRevivers = {}) { - const obj = devalue.unflatten(value, { - ...getWorkflowRevivers(global), - ...extraRevivers, - }); - return obj; -} -/** - * Called at the end of a completed workflow execution to serialize the - * return value into a format that can be saved to the database. - * - * @param value - * @param global - * @returns The dehydrated value, ready to be inserted into the database - */ -function dehydrateWorkflowReturnValue(value, global = globalThis) { - try { - const str = devalue.stringify(value, getWorkflowReducers(global)); - return revive(str); - } - catch (error) { - throw new WorkflowRuntimeError(`Failed to serialize workflow return value. Ensure you're returning serializable types (plain objects, arrays, primitives, Date, RegExp, Map, Set).`, { slug: 'serialization-failed', cause: error }); - } -} -/** - * Called from the client side (i.e. the execution environment where - * the workflow run was initiated from) to hydrate the workflow - * return value of a completed workflow run. - * - * @param value - * @param global - * @returns The hydrated return value, ready to be consumed by the client - */ -function hydrateWorkflowReturnValue(value, ops, global = globalThis, extraRevivers = {}) { - const obj = devalue.unflatten(value, { - ...getExternalRevivers(global, ops), - ...extraRevivers, - }); - return obj; -} -/** - * Called from the workflow handler when a step is being created. - * Dehydrates values from within the workflow execution environment - * into a format that can be saved to the database. - * - * @param value - * @param global - * @returns The dehydrated value, ready to be inserted into the database - */ -function dehydrateStepArguments(value, global) { - try { - const str = devalue.stringify(value, getWorkflowReducers(global)); - return revive(str); - } - catch (error) { - throw new WorkflowRuntimeError(`Failed to serialize step arguments. Ensure you're passing serializable types (plain objects, arrays, primitives, Date, RegExp, Map, Set).`, { slug: 'serialization-failed', cause: error }); - } -} -/** - * Called from the step handler to hydrate the arguments of a step - * from the database at the start of the step execution. - * - * @param value - * @param global - * @returns The hydrated value, ready to be consumed by the step user-code function - */ -function hydrateStepArguments(value, ops, global = globalThis, extraRevivers = {}) { - const obj = devalue.unflatten(value, { - ...getStepRevivers(global, ops), - ...extraRevivers, - }); - return obj; -} -/** - * Called from the step handler when a step has completed. - * Dehydrates values from within the step execution environment - * into a format that can be saved to the database. - * - * @param value - * @param global - * @returns The dehydrated value, ready to be inserted into the database - */ -function dehydrateStepReturnValue(value, ops, global = globalThis) { - try { - const str = devalue.stringify(value, getStepReducers(global, ops)); - return revive(str); - } - catch (error) { - throw new WorkflowRuntimeError(`Failed to serialize step return value. Ensure you're returning serializable types (plain objects, arrays, primitives, Date, RegExp, Map, Set).`, { slug: 'serialization-failed', cause: error }); - } -} -/** - * Called from the workflow handler when replaying the event log of a `step_completed` event. - * Hydrates the return value of a step from the database. - * - * @param value - * @param global - * @returns The hydrated return value of a step, ready to be consumed by the workflow handler - */ -function hydrateStepReturnValue(value, global = globalThis, extraRevivers = {}) { - const obj = devalue.unflatten(value, { - ...getWorkflowRevivers(global), - ...extraRevivers, - }); - return obj; -} - -/** - * OpenTelemetry semantic conventions for Vercel Workflow telemetry. - * - * This module provides standardized telemetry attributes following OpenTelemetry semantic conventions - * for instrumenting workflow execution, step processing, and related operations. Each exported function - * creates a properly formatted attribute object that can be used with OpenTelemetry spans. - * - * The semantic conventions are organized into several categories: - * - **Workflow attributes**: Track workflow lifecycle, status, and metadata - * - **Step attributes**: Monitor individual step execution, retries, and results - * - **Queue attributes**: Instrument message queue operations - * - **Deployment attributes**: Capture deployment environment information - * - * All attribute functions are type-safe and leverage existing backend types to ensure - * consistency between telemetry data and actual system state. - * - * @example - * ```typescript - * import * as Attribute from './telemetry/semantic-conventions.js'; - * - * // Set workflow attributes on a span - * span.setAttributes({ - * ...Attribute.WorkflowName('my-workflow'), - * ...Attribute.WorkflowOperation('start'), - * ...Attribute.WorkflowRunStatus('running'), - * }); - * - * // Set step attributes - * span.setAttributes({ - * ...Attribute.StepName('process-data'), - * ...Attribute.StepStatus('completed'), - * ...Attribute.StepAttempt(1), - * }); - * ``` - * - * @see {@link https://opentelemetry.io/docs/specs/semconv/} OpenTelemetry Semantic Conventions - * @packageDocumentation - */ -/** - * Creates a semantic convention function that returns an attribute object. - * @param name - The attribute name following OpenTelemetry semantic conventions - * @returns A function that takes a value and returns an attribute object - */ -function SemanticConvention(name) { - return (value) => ({ [name]: value }); -} -// Workflow attributes -/** The name of the workflow being executed */ -const WorkflowName = SemanticConvention('workflow.name'); -/** The operation being performed on the workflow */ -const WorkflowOperation = SemanticConvention('workflow.operation'); -/** Unique identifier for a specific workflow run instance */ -const WorkflowRunId = SemanticConvention('workflow.run.id'); -/** Current status of the workflow run */ -const WorkflowRunStatus = SemanticConvention('workflow.run.status'); -/** Timestamp when the workflow execution started (Unix timestamp) */ -const WorkflowStartedAt = SemanticConvention('workflow.started_at'); -/** Number of events processed during workflow execution */ -const WorkflowEventsCount = SemanticConvention('workflow.events.count'); -/** Number of arguments passed to the workflow */ -const WorkflowArgumentsCount = SemanticConvention('workflow.arguments.count'); -/** Type of the workflow result */ -const WorkflowResultType = SemanticConvention('workflow.result.type'); -/** Whether trace context was propagated to this workflow execution */ -const WorkflowTracePropagated = SemanticConvention('workflow.trace.propagated'); -/** Name of the error that caused workflow failure */ -const WorkflowErrorName = SemanticConvention('workflow.error.name'); -/** Error message when workflow fails */ -const WorkflowErrorMessage = SemanticConvention('workflow.error.message'); -/** Number of steps created during workflow execution */ -const WorkflowStepsCreated = SemanticConvention('workflow.steps.created'); -// Step attributes -/** Name of the step function being executed */ -const StepName = SemanticConvention('step.name'); -/** Unique identifier for the step instance */ -const StepId = SemanticConvention('step.id'); -/** Current attempt number for step execution (starts at 1) */ -const StepAttempt = SemanticConvention('step.attempt'); -/** Current status of the step */ -const StepStatus = SemanticConvention('step.status'); -/** Maximum number of retries allowed for this step */ -const StepMaxRetries = SemanticConvention('step.max_retries'); -/** Whether trace context was propagated to this step execution */ -const StepTracePropagated = SemanticConvention('step.trace.propagated'); -/** Whether the step was skipped during execution */ -const StepSkipped = SemanticConvention('step.skipped'); -/** Reason why the step was skipped */ -const StepSkipReason = SemanticConvention('step.skip_reason'); -/** Number of arguments passed to the step function */ -const StepArgumentsCount = SemanticConvention('step.arguments.count'); -/** Type of the step result */ -const StepResultType = SemanticConvention('step.result.type'); -/** Name of the error that caused step failure */ -const StepErrorName = SemanticConvention('step.error.name'); -/** Error message when step fails */ -const StepErrorMessage = SemanticConvention('step.error.message'); -/** Whether the step failed with a fatal error (no retries) */ -const StepFatalError = SemanticConvention('step.fatal_error'); -/** Whether all retry attempts have been exhausted */ -const StepRetryExhausted = SemanticConvention('step.retry.exhausted'); -/** Number of seconds to wait before next retry attempt */ -const StepRetryTimeoutSeconds = SemanticConvention('step.retry.timeout_seconds'); -/** Whether the step will be retried after this failure */ -const StepRetryWillRetry = SemanticConvention('step.retry.will_retry'); -// Queue attributes -/** Name of the queue being used for message processing */ -const QueueName = SemanticConvention('queue.name'); -// Deployment attributes -/** Unique identifier for the deployment environment */ -const DeploymentId = SemanticConvention('deployment.id'); -// Hook attributes -/** Token identifying a specific hook */ -const HookToken = SemanticConvention('workflow.hook.token'); -/** Unique identifier for a hook instance */ -const HookId = SemanticConvention('workflow.hook.id'); -/** Whether a hook was found by its token */ -const HookFound = SemanticConvention('workflow.hook.found'); - -/** - * Builds a workflow suspension log message based on the counts of steps, hooks, and waits. - * @param runId - The workflow run ID - * @param stepCount - Number of steps to be enqueued - * @param hookCount - Number of hooks to be enqueued - * @param waitCount - Number of waits to be enqueued - * @returns The formatted log message or null if all counts are 0 - */ -function buildWorkflowSuspensionMessage(runId, stepCount, hookCount, waitCount) { - if (stepCount === 0 && hookCount === 0 && waitCount === 0) { - return null; - } - const parts = []; - if (stepCount > 0) { - parts.push(`${stepCount} ${stepCount === 1 ? 'step' : 'steps'}`); - } - if (hookCount > 0) { - parts.push(`${hookCount} ${hookCount === 1 ? 'hook' : 'hooks'}`); - } - if (waitCount > 0) { - parts.push(`${waitCount} ${waitCount === 1 ? 'timer' : 'timers'}`); - } - const resumeMsgParts = []; - if (stepCount > 0) { - resumeMsgParts.push('steps are completed'); - } - if (hookCount > 0) { - resumeMsgParts.push('hooks are received'); - } - if (waitCount > 0) { - resumeMsgParts.push('timers have elapsed'); - } - const resumeMsg = resumeMsgParts.join(' and '); - return `[Workflows] "${runId}" - ${parts.join(' and ')} to be enqueued\n Workflow will suspend and resume when ${resumeMsg}`; -} -/** - * Generates a stream ID for a workflow run. - * User-defined streams include a "user" segment for isolation from future system-defined streams. - * Namespaces are base64-encoded to handle characters not allowed in Redis key names. - * - * @param runId - The workflow run ID - * @param namespace - Optional namespace for the stream - * @returns The stream ID in format: `strm_{ULID}_user_{base64(namespace)?}` - */ -function getWorkflowRunStreamId(runId, namespace) { - const streamId = `${runId.replace('wrun_', 'strm_')}_user`; - if (!namespace) { - return streamId; - } - // Base64 encode the namespace to handle special characters that may not be allowed in Redis keys - const encodedNamespace = Buffer.from(namespace, 'utf-8').toString('base64url'); - return `${streamId}_${encodedNamespace}`; -} -/** - * A small wrapper around `waitUntil` that also returns - * the result of the awaited promise. - */ -async function waitedUntil(fn) { - const result = fn(); - functionsExports.waitUntil(result); - return result; -} - -var EventConsumerResult; -(function (EventConsumerResult) { - /** - * Callback consumed the event, but should not be removed from the callbacks list - */ - EventConsumerResult[EventConsumerResult["Consumed"] = 0] = "Consumed"; - /** - * Callback did not consume the event, so it should be passed to the next callback - */ - EventConsumerResult[EventConsumerResult["NotConsumed"] = 1] = "NotConsumed"; - /** - * Callback consumed the event, and should be removed from the callbacks list - */ - EventConsumerResult[EventConsumerResult["Finished"] = 2] = "Finished"; -})(EventConsumerResult || (EventConsumerResult = {})); -class EventsConsumer { - eventIndex; - events = []; - callbacks = []; - constructor(events) { - this.events = events; - this.eventIndex = 0; - eventsLogger.debug('EventsConsumer initialized', { events }); - } - /** - * Registers a callback function to be called after an event has been consumed - * by a different callback. The callback can return: - * - `EventConsumerResult.Consumed` the event is considered consumed and will not be passed to any other callback, but the callback will remain in the callbacks list - * - `EventConsumerResult.NotConsumed` the event is passed to the next callback - * - `EventConsumerResult.Finished` the event is considered consumed and the callback is removed from the callbacks list - * - * @param fn - The callback function to register. - */ - subscribe(fn) { - this.callbacks.push(fn); - process.nextTick(this.consume); - } - consume = () => { - const currentEvent = this.events[this.eventIndex] ?? null; - for (let i = 0; i < this.callbacks.length; i++) { - const callback = this.callbacks[i]; - let handled = EventConsumerResult.NotConsumed; - try { - handled = callback(currentEvent); - } - catch (error) { - eventsLogger.error('EventConsumer callback threw an error', { error }); - // Hopefully shouldn't happen, but we don't want to block the workflow - console.error('EventConsumer callback threw an error', error); - } - eventsLogger.debug('EventConsumer callback result', { - handled: EventConsumerResult[handled], - eventIndex: this.eventIndex, - eventId: currentEvent?.eventId, - }); - if (handled === EventConsumerResult.Consumed || - handled === EventConsumerResult.Finished) { - // consumer handled this event, so increase the event index - this.eventIndex++; - // remove the callback if it has finished - if (handled === EventConsumerResult.Finished) { - this.callbacks.splice(i, 1); - } - // continue to the next event - process.nextTick(this.consume); - return; - } - } - }; -} - -var alea$1 = {exports: {}}; - -var alea = alea$1.exports; - -var hasRequiredAlea; - -function requireAlea () { - if (hasRequiredAlea) return alea$1.exports; - hasRequiredAlea = 1; - (function (module) { - // A port of an algorithm by Johannes Baagøe , 2010 - // http://baagoe.com/en/RandomMusings/javascript/ - // https://github.com/nquinlan/better-random-numbers-for-javascript-mirror - // Original work is under MIT license - - - // Copyright (C) 2010 by Johannes Baagøe - // - // Permission is hereby granted, free of charge, to any person obtaining a copy - // of this software and associated documentation files (the "Software"), to deal - // in the Software without restriction, including without limitation the rights - // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - // copies of the Software, and to permit persons to whom the Software is - // furnished to do so, subject to the following conditions: - // - // The above copyright notice and this permission notice shall be included in - // all copies or substantial portions of the Software. - // - // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - // THE SOFTWARE. - - - - (function(global, module, define) { - - function Alea(seed) { - var me = this, mash = Mash(); - - me.next = function() { - var t = 2091639 * me.s0 + me.c * 2.3283064365386963e-10; // 2^-32 - me.s0 = me.s1; - me.s1 = me.s2; - return me.s2 = t - (me.c = t | 0); - }; - - // Apply the seeding algorithm from Baagoe. - me.c = 1; - me.s0 = mash(' '); - me.s1 = mash(' '); - me.s2 = mash(' '); - me.s0 -= mash(seed); - if (me.s0 < 0) { me.s0 += 1; } - me.s1 -= mash(seed); - if (me.s1 < 0) { me.s1 += 1; } - me.s2 -= mash(seed); - if (me.s2 < 0) { me.s2 += 1; } - mash = null; - } - - function copy(f, t) { - t.c = f.c; - t.s0 = f.s0; - t.s1 = f.s1; - t.s2 = f.s2; - return t; - } - - function impl(seed, opts) { - var xg = new Alea(seed), - state = opts && opts.state, - prng = xg.next; - prng.int32 = function() { return (xg.next() * 0x100000000) | 0; }; - prng.double = function() { - return prng() + (prng() * 0x200000 | 0) * 1.1102230246251565e-16; // 2^-53 - }; - prng.quick = prng; - if (state) { - if (typeof(state) == 'object') copy(state, xg); - prng.state = function() { return copy(xg, {}); }; - } - return prng; - } - - function Mash() { - var n = 0xefc8249d; - - var mash = function(data) { - data = String(data); - for (var i = 0; i < data.length; i++) { - n += data.charCodeAt(i); - var h = 0.02519603282416938 * n; - n = h >>> 0; - h -= n; - h *= n; - n = h >>> 0; - h -= n; - n += h * 0x100000000; // 2^32 - } - return (n >>> 0) * 2.3283064365386963e-10; // 2^-32 - }; - - return mash; - } - - - if (module && module.exports) { - module.exports = impl; - } else { - this.alea = impl; - } - - })( - alea, - module); - } (alea$1)); - return alea$1.exports; -} - -var xor128$1 = {exports: {}}; - -var xor128 = xor128$1.exports; - -var hasRequiredXor128; - -function requireXor128 () { - if (hasRequiredXor128) return xor128$1.exports; - hasRequiredXor128 = 1; - (function (module) { - // A Javascript implementaion of the "xor128" prng algorithm by - // George Marsaglia. See http://www.jstatsoft.org/v08/i14/paper - - (function(global, module, define) { - - function XorGen(seed) { - var me = this, strseed = ''; - - me.x = 0; - me.y = 0; - me.z = 0; - me.w = 0; - - // Set up generator function. - me.next = function() { - var t = me.x ^ (me.x << 11); - me.x = me.y; - me.y = me.z; - me.z = me.w; - return me.w ^= (me.w >>> 19) ^ t ^ (t >>> 8); - }; - - if (seed === (seed | 0)) { - // Integer seed. - me.x = seed; - } else { - // String seed. - strseed += seed; - } - - // Mix in string seed, then discard an initial batch of 64 values. - for (var k = 0; k < strseed.length + 64; k++) { - me.x ^= strseed.charCodeAt(k) | 0; - me.next(); - } - } - - function copy(f, t) { - t.x = f.x; - t.y = f.y; - t.z = f.z; - t.w = f.w; - return t; - } - - function impl(seed, opts) { - var xg = new XorGen(seed), - state = opts && opts.state, - prng = function() { return (xg.next() >>> 0) / 0x100000000; }; - prng.double = function() { - do { - var top = xg.next() >>> 11, - bot = (xg.next() >>> 0) / 0x100000000, - result = (top + bot) / (1 << 21); - } while (result === 0); - return result; - }; - prng.int32 = xg.next; - prng.quick = prng; - if (state) { - if (typeof(state) == 'object') copy(state, xg); - prng.state = function() { return copy(xg, {}); }; - } - return prng; - } - - if (module && module.exports) { - module.exports = impl; - } else { - this.xor128 = impl; - } - - })( - xor128, - module); - } (xor128$1)); - return xor128$1.exports; -} - -var xorwow$1 = {exports: {}}; - -var xorwow = xorwow$1.exports; - -var hasRequiredXorwow; - -function requireXorwow () { - if (hasRequiredXorwow) return xorwow$1.exports; - hasRequiredXorwow = 1; - (function (module) { - // A Javascript implementaion of the "xorwow" prng algorithm by - // George Marsaglia. See http://www.jstatsoft.org/v08/i14/paper - - (function(global, module, define) { - - function XorGen(seed) { - var me = this, strseed = ''; - - // Set up generator function. - me.next = function() { - var t = (me.x ^ (me.x >>> 2)); - me.x = me.y; me.y = me.z; me.z = me.w; me.w = me.v; - return (me.d = (me.d + 362437 | 0)) + - (me.v = (me.v ^ (me.v << 4)) ^ (t ^ (t << 1))) | 0; - }; - - me.x = 0; - me.y = 0; - me.z = 0; - me.w = 0; - me.v = 0; - - if (seed === (seed | 0)) { - // Integer seed. - me.x = seed; - } else { - // String seed. - strseed += seed; - } - - // Mix in string seed, then discard an initial batch of 64 values. - for (var k = 0; k < strseed.length + 64; k++) { - me.x ^= strseed.charCodeAt(k) | 0; - if (k == strseed.length) { - me.d = me.x << 10 ^ me.x >>> 4; - } - me.next(); - } - } - - function copy(f, t) { - t.x = f.x; - t.y = f.y; - t.z = f.z; - t.w = f.w; - t.v = f.v; - t.d = f.d; - return t; - } - - function impl(seed, opts) { - var xg = new XorGen(seed), - state = opts && opts.state, - prng = function() { return (xg.next() >>> 0) / 0x100000000; }; - prng.double = function() { - do { - var top = xg.next() >>> 11, - bot = (xg.next() >>> 0) / 0x100000000, - result = (top + bot) / (1 << 21); - } while (result === 0); - return result; - }; - prng.int32 = xg.next; - prng.quick = prng; - if (state) { - if (typeof(state) == 'object') copy(state, xg); - prng.state = function() { return copy(xg, {}); }; - } - return prng; - } - - if (module && module.exports) { - module.exports = impl; - } else { - this.xorwow = impl; - } - - })( - xorwow, - module); - } (xorwow$1)); - return xorwow$1.exports; -} - -var xorshift7$1 = {exports: {}}; - -var xorshift7 = xorshift7$1.exports; - -var hasRequiredXorshift7; - -function requireXorshift7 () { - if (hasRequiredXorshift7) return xorshift7$1.exports; - hasRequiredXorshift7 = 1; - (function (module) { - // A Javascript implementaion of the "xorshift7" algorithm by - // François Panneton and Pierre L'ecuyer: - // "On the Xorgshift Random Number Generators" - // http://saluc.engr.uconn.edu/refs/crypto/rng/panneton05onthexorshift.pdf - - (function(global, module, define) { - - function XorGen(seed) { - var me = this; - - // Set up generator function. - me.next = function() { - // Update xor generator. - var X = me.x, i = me.i, t, v; - t = X[i]; t ^= (t >>> 7); v = t ^ (t << 24); - t = X[(i + 1) & 7]; v ^= t ^ (t >>> 10); - t = X[(i + 3) & 7]; v ^= t ^ (t >>> 3); - t = X[(i + 4) & 7]; v ^= t ^ (t << 7); - t = X[(i + 7) & 7]; t = t ^ (t << 13); v ^= t ^ (t << 9); - X[i] = v; - me.i = (i + 1) & 7; - return v; - }; - - function init(me, seed) { - var j, X = []; - - if (seed === (seed | 0)) { - // Seed state array using a 32-bit integer. - X[0] = seed; - } else { - // Seed state using a string. - seed = '' + seed; - for (j = 0; j < seed.length; ++j) { - X[j & 7] = (X[j & 7] << 15) ^ - (seed.charCodeAt(j) + X[(j + 1) & 7] << 13); - } - } - // Enforce an array length of 8, not all zeroes. - while (X.length < 8) X.push(0); - for (j = 0; j < 8 && X[j] === 0; ++j); - if (j == 8) X[7] = -1; else X[j]; - - me.x = X; - me.i = 0; - - // Discard an initial 256 values. - for (j = 256; j > 0; --j) { - me.next(); - } - } - - init(me, seed); - } - - function copy(f, t) { - t.x = f.x.slice(); - t.i = f.i; - return t; - } - - function impl(seed, opts) { - if (seed == null) seed = +(new Date); - var xg = new XorGen(seed), - state = opts && opts.state, - prng = function() { return (xg.next() >>> 0) / 0x100000000; }; - prng.double = function() { - do { - var top = xg.next() >>> 11, - bot = (xg.next() >>> 0) / 0x100000000, - result = (top + bot) / (1 << 21); - } while (result === 0); - return result; - }; - prng.int32 = xg.next; - prng.quick = prng; - if (state) { - if (state.x) copy(state, xg); - prng.state = function() { return copy(xg, {}); }; - } - return prng; - } - - if (module && module.exports) { - module.exports = impl; - } else { - this.xorshift7 = impl; - } - - })( - xorshift7, - module); - } (xorshift7$1)); - return xorshift7$1.exports; -} - -var xor4096$1 = {exports: {}}; - -var xor4096 = xor4096$1.exports; - -var hasRequiredXor4096; - -function requireXor4096 () { - if (hasRequiredXor4096) return xor4096$1.exports; - hasRequiredXor4096 = 1; - (function (module) { - // A Javascript implementaion of Richard Brent's Xorgens xor4096 algorithm. - // - // This fast non-cryptographic random number generator is designed for - // use in Monte-Carlo algorithms. It combines a long-period xorshift - // generator with a Weyl generator, and it passes all common batteries - // of stasticial tests for randomness while consuming only a few nanoseconds - // for each prng generated. For background on the generator, see Brent's - // paper: "Some long-period random number generators using shifts and xors." - // http://arxiv.org/pdf/1004.3115v1.pdf - // - // Usage: - // - // var xor4096 = require('xor4096'); - // random = xor4096(1); // Seed with int32 or string. - // assert.equal(random(), 0.1520436450538547); // (0, 1) range, 53 bits. - // assert.equal(random.int32(), 1806534897); // signed int32, 32 bits. - // - // For nonzero numeric keys, this impelementation provides a sequence - // identical to that by Brent's xorgens 3 implementaion in C. This - // implementation also provides for initalizing the generator with - // string seeds, or for saving and restoring the state of the generator. - // - // On Chrome, this prng benchmarks about 2.1 times slower than - // Javascript's built-in Math.random(). - - (function(global, module, define) { - - function XorGen(seed) { - var me = this; - - // Set up generator function. - me.next = function() { - var w = me.w, - X = me.X, i = me.i, t, v; - // Update Weyl generator. - me.w = w = (w + 0x61c88647) | 0; - // Update xor generator. - v = X[(i + 34) & 127]; - t = X[i = ((i + 1) & 127)]; - v ^= v << 13; - t ^= t << 17; - v ^= v >>> 15; - t ^= t >>> 12; - // Update Xor generator array state. - v = X[i] = v ^ t; - me.i = i; - // Result is the combination. - return (v + (w ^ (w >>> 16))) | 0; - }; - - function init(me, seed) { - var t, v, i, j, w, X = [], limit = 128; - if (seed === (seed | 0)) { - // Numeric seeds initialize v, which is used to generates X. - v = seed; - seed = null; - } else { - // String seeds are mixed into v and X one character at a time. - seed = seed + '\0'; - v = 0; - limit = Math.max(limit, seed.length); - } - // Initialize circular array and weyl value. - for (i = 0, j = -32; j < limit; ++j) { - // Put the unicode characters into the array, and shuffle them. - if (seed) v ^= seed.charCodeAt((j + 32) % seed.length); - // After 32 shuffles, take v as the starting w value. - if (j === 0) w = v; - v ^= v << 10; - v ^= v >>> 15; - v ^= v << 4; - v ^= v >>> 13; - if (j >= 0) { - w = (w + 0x61c88647) | 0; // Weyl. - t = (X[j & 127] ^= (v + w)); // Combine xor and weyl to init array. - i = (0 == t) ? i + 1 : 0; // Count zeroes. - } - } - // We have detected all zeroes; make the key nonzero. - if (i >= 128) { - X[(seed && seed.length || 0) & 127] = -1; - } - // Run the generator 512 times to further mix the state before using it. - // Factoring this as a function slows the main generator, so it is just - // unrolled here. The weyl generator is not advanced while warming up. - i = 127; - for (j = 4 * 128; j > 0; --j) { - v = X[(i + 34) & 127]; - t = X[i = ((i + 1) & 127)]; - v ^= v << 13; - t ^= t << 17; - v ^= v >>> 15; - t ^= t >>> 12; - X[i] = v ^ t; - } - // Storing state as object members is faster than using closure variables. - me.w = w; - me.X = X; - me.i = i; - } - - init(me, seed); - } - - function copy(f, t) { - t.i = f.i; - t.w = f.w; - t.X = f.X.slice(); - return t; - } - function impl(seed, opts) { - if (seed == null) seed = +(new Date); - var xg = new XorGen(seed), - state = opts && opts.state, - prng = function() { return (xg.next() >>> 0) / 0x100000000; }; - prng.double = function() { - do { - var top = xg.next() >>> 11, - bot = (xg.next() >>> 0) / 0x100000000, - result = (top + bot) / (1 << 21); - } while (result === 0); - return result; - }; - prng.int32 = xg.next; - prng.quick = prng; - if (state) { - if (state.X) copy(state, xg); - prng.state = function() { return copy(xg, {}); }; - } - return prng; - } - - if (module && module.exports) { - module.exports = impl; - } else { - this.xor4096 = impl; - } - - })( - xor4096, // window object or global - module); - } (xor4096$1)); - return xor4096$1.exports; -} - -var tychei$1 = {exports: {}}; - -var tychei = tychei$1.exports; - -var hasRequiredTychei; - -function requireTychei () { - if (hasRequiredTychei) return tychei$1.exports; - hasRequiredTychei = 1; - (function (module) { - // A Javascript implementaion of the "Tyche-i" prng algorithm by - // Samuel Neves and Filipe Araujo. - // See https://eden.dei.uc.pt/~sneves/pubs/2011-snfa2.pdf - - (function(global, module, define) { - - function XorGen(seed) { - var me = this, strseed = ''; - - // Set up generator function. - me.next = function() { - var b = me.b, c = me.c, d = me.d, a = me.a; - b = (b << 25) ^ (b >>> 7) ^ c; - c = (c - d) | 0; - d = (d << 24) ^ (d >>> 8) ^ a; - a = (a - b) | 0; - me.b = b = (b << 20) ^ (b >>> 12) ^ c; - me.c = c = (c - d) | 0; - me.d = (d << 16) ^ (c >>> 16) ^ a; - return me.a = (a - b) | 0; - }; - - /* The following is non-inverted tyche, which has better internal - * bit diffusion, but which is about 25% slower than tyche-i in JS. - me.next = function() { - var a = me.a, b = me.b, c = me.c, d = me.d; - a = (me.a + me.b | 0) >>> 0; - d = me.d ^ a; d = d << 16 ^ d >>> 16; - c = me.c + d | 0; - b = me.b ^ c; b = b << 12 ^ d >>> 20; - me.a = a = a + b | 0; - d = d ^ a; me.d = d = d << 8 ^ d >>> 24; - me.c = c = c + d | 0; - b = b ^ c; - return me.b = (b << 7 ^ b >>> 25); - } - */ - - me.a = 0; - me.b = 0; - me.c = 2654435769 | 0; - me.d = 1367130551; - - if (seed === Math.floor(seed)) { - // Integer seed. - me.a = (seed / 0x100000000) | 0; - me.b = seed | 0; - } else { - // String seed. - strseed += seed; - } - - // Mix in string seed, then discard an initial batch of 64 values. - for (var k = 0; k < strseed.length + 20; k++) { - me.b ^= strseed.charCodeAt(k) | 0; - me.next(); - } - } - - function copy(f, t) { - t.a = f.a; - t.b = f.b; - t.c = f.c; - t.d = f.d; - return t; - } - function impl(seed, opts) { - var xg = new XorGen(seed), - state = opts && opts.state, - prng = function() { return (xg.next() >>> 0) / 0x100000000; }; - prng.double = function() { - do { - var top = xg.next() >>> 11, - bot = (xg.next() >>> 0) / 0x100000000, - result = (top + bot) / (1 << 21); - } while (result === 0); - return result; - }; - prng.int32 = xg.next; - prng.quick = prng; - if (state) { - if (typeof(state) == 'object') copy(state, xg); - prng.state = function() { return copy(xg, {}); }; - } - return prng; - } - - if (module && module.exports) { - module.exports = impl; - } else { - this.tychei = impl; - } - - })( - tychei, - module); - } (tychei$1)); - return tychei$1.exports; -} - -var seedrandom$3 = {exports: {}}; - -/* -Copyright 2019 David Bau. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -var seedrandom$2 = seedrandom$3.exports; - -var hasRequiredSeedrandom$1; - -function requireSeedrandom$1 () { - if (hasRequiredSeedrandom$1) return seedrandom$3.exports; - hasRequiredSeedrandom$1 = 1; - (function (module) { - (function (global, pool, math) { - // - // The following constants are related to IEEE 754 limits. - // - - var width = 256, // each RC4 output is 0 <= x < 256 - chunks = 6, // at least six RC4 outputs for each double - digits = 52, // there are 52 significant digits in a double - rngname = 'random', // rngname: name for Math.random and Math.seedrandom - startdenom = math.pow(width, chunks), - significance = math.pow(2, digits), - overflow = significance * 2, - mask = width - 1, - nodecrypto; // node.js crypto module, initialized at the bottom. - - // - // seedrandom() - // This is the seedrandom function described above. - // - function seedrandom(seed, options, callback) { - var key = []; - options = (options == true) ? { entropy: true } : (options || {}); - - // Flatten the seed string or build one from local entropy if needed. - var shortseed = mixkey(flatten( - options.entropy ? [seed, tostring(pool)] : - (seed == null) ? autoseed() : seed, 3), key); - - // Use the seed to initialize an ARC4 generator. - var arc4 = new ARC4(key); - - // This function returns a random double in [0, 1) that contains - // randomness in every bit of the mantissa of the IEEE 754 value. - var prng = function() { - var n = arc4.g(chunks), // Start with a numerator n < 2 ^ 48 - d = startdenom, // and denominator d = 2 ^ 48. - x = 0; // and no 'extra last byte'. - while (n < significance) { // Fill up all significant digits by - n = (n + x) * width; // shifting numerator and - d *= width; // denominator and generating a - x = arc4.g(1); // new least-significant-byte. - } - while (n >= overflow) { // To avoid rounding up, before adding - n /= 2; // last byte, shift everything - d /= 2; // right using integer math until - x >>>= 1; // we have exactly the desired bits. - } - return (n + x) / d; // Form the number within [0, 1). - }; - - prng.int32 = function() { return arc4.g(4) | 0; }; - prng.quick = function() { return arc4.g(4) / 0x100000000; }; - prng.double = prng; - - // Mix the randomness into accumulated entropy. - mixkey(tostring(arc4.S), pool); - - // Calling convention: what to return as a function of prng, seed, is_math. - return (options.pass || callback || - function(prng, seed, is_math_call, state) { - if (state) { - // Load the arc4 state from the given state if it has an S array. - if (state.S) { copy(state, arc4); } - // Only provide the .state method if requested via options.state. - prng.state = function() { return copy(arc4, {}); }; - } - - // If called as a method of Math (Math.seedrandom()), mutate - // Math.random because that is how seedrandom.js has worked since v1.0. - if (is_math_call) { math[rngname] = prng; return seed; } - - // Otherwise, it is a newer calling convention, so return the - // prng directly. - else return prng; - })( - prng, - shortseed, - 'global' in options ? options.global : (this == math), - options.state); - } - - // - // ARC4 - // - // An ARC4 implementation. The constructor takes a key in the form of - // an array of at most (width) integers that should be 0 <= x < (width). - // - // The g(count) method returns a pseudorandom integer that concatenates - // the next (count) outputs from ARC4. Its return value is a number x - // that is in the range 0 <= x < (width ^ count). - // - function ARC4(key) { - var t, keylen = key.length, - me = this, i = 0, j = me.i = me.j = 0, s = me.S = []; - - // The empty key [] is treated as [0]. - if (!keylen) { key = [keylen++]; } - - // Set up S using the standard key scheduling algorithm. - while (i < width) { - s[i] = i++; - } - for (i = 0; i < width; i++) { - s[i] = s[j = mask & (j + key[i % keylen] + (t = s[i]))]; - s[j] = t; - } - - // The "g" method returns the next (count) outputs as one number. - (me.g = function(count) { - // Using instance members instead of closure state nearly doubles speed. - var t, r = 0, - i = me.i, j = me.j, s = me.S; - while (count--) { - t = s[i = mask & (i + 1)]; - r = r * width + s[mask & ((s[i] = s[j = mask & (j + t)]) + (s[j] = t))]; - } - me.i = i; me.j = j; - return r; - // For robust unpredictability, the function call below automatically - // discards an initial batch of values. This is called RC4-drop[256]. - // See http://google.com/search?q=rsa+fluhrer+response&btnI - })(width); - } - - // - // copy() - // Copies internal state of ARC4 to or from a plain object. - // - function copy(f, t) { - t.i = f.i; - t.j = f.j; - t.S = f.S.slice(); - return t; - } - // - // flatten() - // Converts an object tree to nested arrays of strings. - // - function flatten(obj, depth) { - var result = [], typ = (typeof obj), prop; - if (depth && typ == 'object') { - for (prop in obj) { - try { result.push(flatten(obj[prop], depth - 1)); } catch (e) {} - } - } - return (result.length ? result : typ == 'string' ? obj : obj + '\0'); - } - - // - // mixkey() - // Mixes a string seed into a key that is an array of integers, and - // returns a shortened string seed that is equivalent to the result key. - // - function mixkey(seed, key) { - var stringseed = seed + '', smear, j = 0; - while (j < stringseed.length) { - key[mask & j] = - mask & ((smear ^= key[mask & j] * 19) + stringseed.charCodeAt(j++)); - } - return tostring(key); - } - - // - // autoseed() - // Returns an object for autoseeding, using window.crypto and Node crypto - // module if available. - // - function autoseed() { - try { - var out; - if (nodecrypto && (out = nodecrypto.randomBytes)) { - // The use of 'out' to remember randomBytes makes tight minified code. - out = out(width); - } else { - out = new Uint8Array(width); - (global.crypto || global.msCrypto).getRandomValues(out); - } - return tostring(out); - } catch (e) { - var browser = global.navigator, - plugins = browser && browser.plugins; - return [+new Date, global, plugins, global.screen, tostring(pool)]; - } - } - - // - // tostring() - // Converts an array of charcodes to a string - // - function tostring(a) { - return String.fromCharCode.apply(0, a); - } - - // - // When seedrandom.js is loaded, we immediately mix a few bits - // from the built-in RNG into the entropy pool. Because we do - // not want to interfere with deterministic PRNG state later, - // seedrandom will not call math.random on its own again after - // initialization. - // - mixkey(math.random(), pool); - - // - // Nodejs and AMD support: export the implementation as a module using - // either convention. - // - if (module.exports) { - module.exports = seedrandom; - // When in node.js, try using crypto package for autoseeding. - try { - nodecrypto = require('crypto'); - } catch (ex) {} - } else { - // When included as a plain script, set up Math.seedrandom global. - math['seed' + rngname] = seedrandom; - } - - - // End anonymous scope, and pass initial values. - })( - // global: `self` in browsers (including strict mode and web workers), - // otherwise `this` in Node and other environments - (typeof self !== 'undefined') ? self : seedrandom$2, - [], // pool: entropy pool starts empty - Math // math: package containing random, pow, and seedrandom - ); - } (seedrandom$3)); - return seedrandom$3.exports; -} - -var seedrandom$1; -var hasRequiredSeedrandom; - -function requireSeedrandom () { - if (hasRequiredSeedrandom) return seedrandom$1; - hasRequiredSeedrandom = 1; - // A library of seedable RNGs implemented in Javascript. - // - // Usage: - // - // var seedrandom = require('seedrandom'); - // var random = seedrandom(1); // or any seed. - // var x = random(); // 0 <= x < 1. Every bit is random. - // var x = random.quick(); // 0 <= x < 1. 32 bits of randomness. - - // alea, a 53-bit multiply-with-carry generator by Johannes Baagøe. - // Period: ~2^116 - // Reported to pass all BigCrush tests. - var alea = requireAlea(); - - // xor128, a pure xor-shift generator by George Marsaglia. - // Period: 2^128-1. - // Reported to fail: MatrixRank and LinearComp. - var xor128 = requireXor128(); - - // xorwow, George Marsaglia's 160-bit xor-shift combined plus weyl. - // Period: 2^192-2^32 - // Reported to fail: CollisionOver, SimpPoker, and LinearComp. - var xorwow = requireXorwow(); - - // xorshift7, by François Panneton and Pierre L'ecuyer, takes - // a different approach: it adds robustness by allowing more shifts - // than Marsaglia's original three. It is a 7-shift generator - // with 256 bits, that passes BigCrush with no systmatic failures. - // Period 2^256-1. - // No systematic BigCrush failures reported. - var xorshift7 = requireXorshift7(); - - // xor4096, by Richard Brent, is a 4096-bit xor-shift with a - // very long period that also adds a Weyl generator. It also passes - // BigCrush with no systematic failures. Its long period may - // be useful if you have many generators and need to avoid - // collisions. - // Period: 2^4128-2^32. - // No systematic BigCrush failures reported. - var xor4096 = requireXor4096(); - - // Tyche-i, by Samuel Neves and Filipe Araujo, is a bit-shifting random - // number generator derived from ChaCha, a modern stream cipher. - // https://eden.dei.uc.pt/~sneves/pubs/2011-snfa2.pdf - // Period: ~2^127 - // No systematic BigCrush failures reported. - var tychei = requireTychei(); - - // The original ARC4-based prng included in this library. - // Period: ~2^1600 - var sr = requireSeedrandom$1(); - - sr.alea = alea; - sr.xor128 = xor128; - sr.xorwow = xorwow; - sr.xorshift7 = xorshift7; - sr.xor4096 = xor4096; - sr.tychei = tychei; - - seedrandom$1 = sr; - return seedrandom$1; -} - -var seedrandomExports = requireSeedrandom(); -const seedrandom = /*@__PURE__*/getDefaultExportFromCjs(seedrandomExports); - -export { hydrateWorkflowReturnValue as $, stepLogger as A, EventConsumerResult as B, hydrateStepReturnValue as C, DeploymentId as D, ERROR_SLUGS as E, FatalError as F, seedrandom as G, HookId as H, webhookLogger as I, parseDurationToDate as J, WorkflowEventsCount as K, getPort as L, monotonicFactory as M, EventsConsumer as N, WORKFLOW_USE_STEP as O, WORKFLOW_CREATE_HOOK as P, WORKFLOW_SLEEP as Q, WORKFLOW_GET_STREAM_ID as R, dehydrateWorkflowReturnValue as S, WorkflowResultType as T, BODY_INIT_SYMBOL as U, getWorldHandlers as V, WorkflowServerWritableStream as W, WorkflowInvokePayloadSchema as X, withTraceContext as Y, StepInvokePayloadSchema as Z, getExternalRevivers as _, getSerializeStream as a, WorkflowRunCancelledError as a0, QueueName as a1, WorkflowTracePropagated as a2, WorkflowStartedAt as a3, buildWorkflowSuspensionMessage as a4, dehydrateStepArguments as a5, WorkflowAPIError as a6, WorkflowStepsCreated as a7, WorkflowErrorMessage as a8, WorkflowErrorName as a9, StepAttempt as aa, StepName as ab, getStepFunction as ac, StepTracePropagated as ad, StepMaxRetries as ae, StepId as af, runtimeLogger as ag, StepStatus as ah, StepRetryTimeoutSeconds as ai, StepSkipReason as aj, StepSkipped as ak, StepArgumentsCount as al, StepResultType as am, StepErrorMessage as an, StepErrorName as ao, StepFatalError as ap, StepRetryExhausted as aq, RetryableError as ar, StepRetryWillRetry as as, requireTokenError as at, getExternalReducers as b, getWorld as c, WEBHOOK_RESPONSE_WRITABLE as d, WorkflowRuntimeError as e, WorkflowRunId as f, getWorkflowRunStreamId as g, hydrateStepArguments as h, HookToken as i, dehydrateStepReturnValue as j, functionsExports as k, WorkflowName as l, getSpanContextForTraceCarrier as m, HookFound as n, WorkflowOperation as o, WorkflowArgumentsCount as p, dehydrateWorkflowArguments as q, registerStepFunction as r, serializeTraceCarrier as s, trace as t, WorkflowRunStatus as u, hydrateWorkflowArguments as v, waitedUntil as w, WorkflowRunNotCompletedError as x, WorkflowRunFailedError as y, withResolvers as z }; diff --git a/workbench/astro/dist/server/chunks/node_C2n6Z2oQ.mjs b/workbench/astro/dist/server/chunks/node_C2n6Z2oQ.mjs deleted file mode 100644 index ba5c8aa58..000000000 --- a/workbench/astro/dist/server/chunks/node_C2n6Z2oQ.mjs +++ /dev/null @@ -1,1669 +0,0 @@ -import { i as isRemoteAllowed, j as joinPaths, a as isRemotePath, r as removeQueryString, b as isParentDirectory } from './remote_OOD9OFqU.mjs'; -import { A as AstroError, E as ExpectedImage, L as LocalImageUsedWrongly, M as MissingImageDimension, U as UnsupportedImageFormat, I as IncompatibleDescriptorOptions, a as UnsupportedImageConversion, t as toStyleString, N as NoImageMetadata, F as FailedToFetchRemoteImageDimensions, b as ExpectedImageOptions, c as ExpectedNotESMImage, d as InvalidImageService, e as createComponent, f as createAstro, g as ImageMissingAlt, m as maybeRenderHead, h as addAttribute, s as spreadAttributes, r as renderTemplate, i as ExperimentalFontsNotEnabled, j as FontFamilyNotFound, u as unescapeHTML } from './astro/server_DhWKww_t.mjs'; -import 'clsx'; -import * as mime from 'mrmime'; -import { readFile } from 'node:fs/promises'; -import { fileURLToPath } from 'node:url'; -import '../renderers.mjs'; - -const VALID_SUPPORTED_FORMATS = [ - "jpeg", - "jpg", - "png", - "tiff", - "webp", - "gif", - "svg", - "avif" -]; -const DEFAULT_OUTPUT_FORMAT = "webp"; -const DEFAULT_HASH_PROPS = [ - "src", - "width", - "height", - "format", - "quality", - "fit", - "position" -]; - -const DEFAULT_RESOLUTIONS = [ - 640, - // older and lower-end phones - 750, - // iPhone 6-8 - 828, - // iPhone XR/11 - 960, - // older horizontal phones - 1080, - // iPhone 6-8 Plus - 1280, - // 720p - 1668, - // Various iPads - 1920, - // 1080p - 2048, - // QXGA - 2560, - // WQXGA - 3200, - // QHD+ - 3840, - // 4K - 4480, - // 4.5K - 5120, - // 5K - 6016 - // 6K -]; -const LIMITED_RESOLUTIONS = [ - 640, - // older and lower-end phones - 750, - // iPhone 6-8 - 828, - // iPhone XR/11 - 1080, - // iPhone 6-8 Plus - 1280, - // 720p - 1668, - // Various iPads - 2048, - // QXGA - 2560 - // WQXGA -]; -const getWidths = ({ - width, - layout, - breakpoints = DEFAULT_RESOLUTIONS, - originalWidth -}) => { - const smallerThanOriginal = (w) => !originalWidth || w <= originalWidth; - if (layout === "full-width") { - return breakpoints.filter(smallerThanOriginal); - } - if (!width) { - return []; - } - const doubleWidth = width * 2; - const maxSize = originalWidth ? Math.min(doubleWidth, originalWidth) : doubleWidth; - if (layout === "fixed") { - return originalWidth && width > originalWidth ? [originalWidth] : [width, maxSize]; - } - if (layout === "constrained") { - return [ - // Always include the image at 1x and 2x the specified width - width, - doubleWidth, - ...breakpoints - ].filter((w) => w <= maxSize).sort((a, b) => a - b); - } - return []; -}; -const getSizesAttribute = ({ - width, - layout -}) => { - if (!width || !layout) { - return void 0; - } - switch (layout) { - // If screen is wider than the max size then image width is the max size, - // otherwise it's the width of the screen - case "constrained": - return `(min-width: ${width}px) ${width}px, 100vw`; - // Image is always the same width, whatever the size of the screen - case "fixed": - return `${width}px`; - // Image is always the width of the screen - case "full-width": - return `100vw`; - case "none": - default: - return void 0; - } -}; - -function isESMImportedImage(src) { - return typeof src === "object" || typeof src === "function" && "src" in src; -} -function isRemoteImage(src) { - return typeof src === "string"; -} -async function resolveSrc(src) { - if (typeof src === "object" && "then" in src) { - const resource = await src; - return resource.default ?? resource; - } - return src; -} - -function isLocalService(service) { - if (!service) { - return false; - } - return "transform" in service; -} -function parseQuality(quality) { - let result = parseInt(quality); - if (Number.isNaN(result)) { - return quality; - } - return result; -} -const sortNumeric = (a, b) => a - b; -const baseService = { - validateOptions(options) { - if (!options.src || !isRemoteImage(options.src) && !isESMImportedImage(options.src)) { - throw new AstroError({ - ...ExpectedImage, - message: ExpectedImage.message( - JSON.stringify(options.src), - typeof options.src, - JSON.stringify(options, (_, v) => v === void 0 ? null : v) - ) - }); - } - if (!isESMImportedImage(options.src)) { - if (options.src.startsWith("/@fs/") || !isRemotePath(options.src) && !options.src.startsWith("/")) { - throw new AstroError({ - ...LocalImageUsedWrongly, - message: LocalImageUsedWrongly.message(options.src) - }); - } - let missingDimension; - if (!options.width && !options.height) { - missingDimension = "both"; - } else if (!options.width && options.height) { - missingDimension = "width"; - } else if (options.width && !options.height) { - missingDimension = "height"; - } - if (missingDimension) { - throw new AstroError({ - ...MissingImageDimension, - message: MissingImageDimension.message(missingDimension, options.src) - }); - } - } else { - if (!VALID_SUPPORTED_FORMATS.includes(options.src.format)) { - throw new AstroError({ - ...UnsupportedImageFormat, - message: UnsupportedImageFormat.message( - options.src.format, - options.src.src, - VALID_SUPPORTED_FORMATS - ) - }); - } - if (options.widths && options.densities) { - throw new AstroError(IncompatibleDescriptorOptions); - } - if (options.src.format === "svg") { - options.format = "svg"; - } - if (options.src.format === "svg" && options.format !== "svg" || options.src.format !== "svg" && options.format === "svg") { - throw new AstroError(UnsupportedImageConversion); - } - } - if (!options.format) { - options.format = DEFAULT_OUTPUT_FORMAT; - } - if (options.width) options.width = Math.round(options.width); - if (options.height) options.height = Math.round(options.height); - if (options.layout && options.width && options.height) { - options.fit ??= "cover"; - delete options.layout; - } - if (options.fit === "none") { - delete options.fit; - } - return options; - }, - getHTMLAttributes(options) { - const { targetWidth, targetHeight } = getTargetDimensions(options); - const { - src, - width, - height, - format, - quality, - densities, - widths, - formats, - layout, - priority, - fit, - position, - ...attributes - } = options; - return { - ...attributes, - width: targetWidth, - height: targetHeight, - loading: attributes.loading ?? "lazy", - decoding: attributes.decoding ?? "async" - }; - }, - getSrcSet(options) { - const { targetWidth, targetHeight } = getTargetDimensions(options); - const aspectRatio = targetWidth / targetHeight; - const { widths, densities } = options; - const targetFormat = options.format ?? DEFAULT_OUTPUT_FORMAT; - let transformedWidths = (widths ?? []).sort(sortNumeric); - let imageWidth = options.width; - let maxWidth = Infinity; - if (isESMImportedImage(options.src)) { - imageWidth = options.src.width; - maxWidth = imageWidth; - if (transformedWidths.length > 0 && transformedWidths.at(-1) > maxWidth) { - transformedWidths = transformedWidths.filter((width) => width <= maxWidth); - transformedWidths.push(maxWidth); - } - } - transformedWidths = Array.from(new Set(transformedWidths)); - const { - width: transformWidth, - height: transformHeight, - ...transformWithoutDimensions - } = options; - let allWidths = []; - if (densities) { - const densityValues = densities.map((density) => { - if (typeof density === "number") { - return density; - } else { - return parseFloat(density); - } - }); - const densityWidths = densityValues.sort(sortNumeric).map((density) => Math.round(targetWidth * density)); - allWidths = densityWidths.map((width, index) => ({ - width, - descriptor: `${densityValues[index]}x` - })); - } else if (transformedWidths.length > 0) { - allWidths = transformedWidths.map((width) => ({ - width, - descriptor: `${width}w` - })); - } - return allWidths.map(({ width, descriptor }) => { - const height = Math.round(width / aspectRatio); - const transform = { ...transformWithoutDimensions, width, height }; - return { - transform, - descriptor, - attributes: { - type: `image/${targetFormat}` - } - }; - }); - }, - getURL(options, imageConfig) { - const searchParams = new URLSearchParams(); - if (isESMImportedImage(options.src)) { - searchParams.append("href", options.src.src); - } else if (isRemoteAllowed(options.src, imageConfig)) { - searchParams.append("href", options.src); - } else { - return options.src; - } - const params = { - w: "width", - h: "height", - q: "quality", - f: "format", - fit: "fit", - position: "position" - }; - Object.entries(params).forEach(([param, key]) => { - options[key] && searchParams.append(param, options[key].toString()); - }); - const imageEndpoint = joinPaths("/", imageConfig.endpoint.route); - let url = `${imageEndpoint}?${searchParams}`; - if (imageConfig.assetQueryParams) { - const assetQueryString = imageConfig.assetQueryParams.toString(); - if (assetQueryString) { - url += "&" + assetQueryString; - } - } - return url; - }, - parseURL(url) { - const params = url.searchParams; - if (!params.has("href")) { - return void 0; - } - const transform = { - src: params.get("href"), - width: params.has("w") ? parseInt(params.get("w")) : void 0, - height: params.has("h") ? parseInt(params.get("h")) : void 0, - format: params.get("f"), - quality: params.get("q"), - fit: params.get("fit"), - position: params.get("position") ?? void 0 - }; - return transform; - } -}; -function getTargetDimensions(options) { - let targetWidth = options.width; - let targetHeight = options.height; - if (isESMImportedImage(options.src)) { - const aspectRatio = options.src.width / options.src.height; - if (targetHeight && !targetWidth) { - targetWidth = Math.round(targetHeight * aspectRatio); - } else if (targetWidth && !targetHeight) { - targetHeight = Math.round(targetWidth / aspectRatio); - } else if (!targetWidth && !targetHeight) { - targetWidth = options.src.width; - targetHeight = options.src.height; - } - } - return { - targetWidth, - targetHeight - }; -} - -function isImageMetadata(src) { - return src.fsPath && !("fsPath" in src); -} - -const cssFitValues = ["fill", "contain", "cover", "scale-down"]; -function addCSSVarsToStyle(vars, styles) { - const cssVars = Object.entries(vars).filter(([_, value]) => value !== void 0 && value !== false).map(([key, value]) => `--${key}: ${value};`).join(" "); - if (!styles) { - return cssVars; - } - const style = typeof styles === "string" ? styles : toStyleString(styles); - return `${cssVars} ${style}`; -} - -const decoder = new TextDecoder(); -const toUTF8String = (input, start = 0, end = input.length) => decoder.decode(input.slice(start, end)); -const toHexString = (input, start = 0, end = input.length) => input.slice(start, end).reduce((memo, i) => memo + ("0" + i.toString(16)).slice(-2), ""); -const readInt16LE = (input, offset = 0) => { - const val = input[offset] + input[offset + 1] * 2 ** 8; - return val | (val & 2 ** 15) * 131070; -}; -const readUInt16BE = (input, offset = 0) => input[offset] * 2 ** 8 + input[offset + 1]; -const readUInt16LE = (input, offset = 0) => input[offset] + input[offset + 1] * 2 ** 8; -const readUInt24LE = (input, offset = 0) => input[offset] + input[offset + 1] * 2 ** 8 + input[offset + 2] * 2 ** 16; -const readInt32LE = (input, offset = 0) => input[offset] + input[offset + 1] * 2 ** 8 + input[offset + 2] * 2 ** 16 + (input[offset + 3] << 24); -const readUInt32BE = (input, offset = 0) => input[offset] * 2 ** 24 + input[offset + 1] * 2 ** 16 + input[offset + 2] * 2 ** 8 + input[offset + 3]; -const readUInt32LE = (input, offset = 0) => input[offset] + input[offset + 1] * 2 ** 8 + input[offset + 2] * 2 ** 16 + input[offset + 3] * 2 ** 24; -const methods = { - readUInt16BE, - readUInt16LE, - readUInt32BE, - readUInt32LE -}; -function readUInt(input, bits, offset, isBigEndian) { - offset = offset || 0; - const endian = isBigEndian ? "BE" : "LE"; - const methodName = "readUInt" + bits + endian; - return methods[methodName](input, offset); -} -function readBox(buffer, offset) { - if (buffer.length - offset < 4) return; - const boxSize = readUInt32BE(buffer, offset); - if (buffer.length - offset < boxSize) return; - return { - name: toUTF8String(buffer, 4 + offset, 8 + offset), - offset, - size: boxSize - }; -} -function findBox(buffer, boxName, offset) { - while (offset < buffer.length) { - const box = readBox(buffer, offset); - if (!box) break; - if (box.name === boxName) return box; - offset += box.size; - } -} - -const BMP = { - validate: (input) => toUTF8String(input, 0, 2) === "BM", - calculate: (input) => ({ - height: Math.abs(readInt32LE(input, 22)), - width: readUInt32LE(input, 18) - }) -}; - -const TYPE_ICON = 1; -const SIZE_HEADER$1 = 2 + 2 + 2; -const SIZE_IMAGE_ENTRY = 1 + 1 + 1 + 1 + 2 + 2 + 4 + 4; -function getSizeFromOffset(input, offset) { - const value = input[offset]; - return value === 0 ? 256 : value; -} -function getImageSize$1(input, imageIndex) { - const offset = SIZE_HEADER$1 + imageIndex * SIZE_IMAGE_ENTRY; - return { - height: getSizeFromOffset(input, offset + 1), - width: getSizeFromOffset(input, offset) - }; -} -const ICO = { - validate(input) { - const reserved = readUInt16LE(input, 0); - const imageCount = readUInt16LE(input, 4); - if (reserved !== 0 || imageCount === 0) return false; - const imageType = readUInt16LE(input, 2); - return imageType === TYPE_ICON; - }, - calculate(input) { - const nbImages = readUInt16LE(input, 4); - const imageSize = getImageSize$1(input, 0); - if (nbImages === 1) return imageSize; - const imgs = [imageSize]; - for (let imageIndex = 1; imageIndex < nbImages; imageIndex += 1) { - imgs.push(getImageSize$1(input, imageIndex)); - } - return { - height: imageSize.height, - images: imgs, - width: imageSize.width - }; - } -}; - -const TYPE_CURSOR = 2; -const CUR = { - validate(input) { - const reserved = readUInt16LE(input, 0); - const imageCount = readUInt16LE(input, 4); - if (reserved !== 0 || imageCount === 0) return false; - const imageType = readUInt16LE(input, 2); - return imageType === TYPE_CURSOR; - }, - calculate: (input) => ICO.calculate(input) -}; - -const DDS = { - validate: (input) => readUInt32LE(input, 0) === 542327876, - calculate: (input) => ({ - height: readUInt32LE(input, 12), - width: readUInt32LE(input, 16) - }) -}; - -const gifRegexp = /^GIF8[79]a/; -const GIF = { - validate: (input) => gifRegexp.test(toUTF8String(input, 0, 6)), - calculate: (input) => ({ - height: readUInt16LE(input, 8), - width: readUInt16LE(input, 6) - }) -}; - -const brandMap = { - avif: "avif", - avis: "avif", - // avif-sequence - mif1: "heif", - msf1: "heif", - // heif-sequence - heic: "heic", - heix: "heic", - hevc: "heic", - // heic-sequence - hevx: "heic" - // heic-sequence -}; -function detectBrands(buffer, start, end) { - let brandsDetected = {}; - for (let i = start; i <= end; i += 4) { - const brand = toUTF8String(buffer, i, i + 4); - if (brand in brandMap) { - brandsDetected[brand] = 1; - } - } - if ("avif" in brandsDetected || "avis" in brandsDetected) { - return "avif"; - } else if ("heic" in brandsDetected || "heix" in brandsDetected || "hevc" in brandsDetected || "hevx" in brandsDetected) { - return "heic"; - } else if ("mif1" in brandsDetected || "msf1" in brandsDetected) { - return "heif"; - } -} -const HEIF = { - validate(buffer) { - const ftype = toUTF8String(buffer, 4, 8); - const brand = toUTF8String(buffer, 8, 12); - return "ftyp" === ftype && brand in brandMap; - }, - calculate(buffer) { - const metaBox = findBox(buffer, "meta", 0); - const iprpBox = metaBox && findBox(buffer, "iprp", metaBox.offset + 12); - const ipcoBox = iprpBox && findBox(buffer, "ipco", iprpBox.offset + 8); - const ispeBox = ipcoBox && findBox(buffer, "ispe", ipcoBox.offset + 8); - if (ispeBox) { - return { - height: readUInt32BE(buffer, ispeBox.offset + 16), - width: readUInt32BE(buffer, ispeBox.offset + 12), - type: detectBrands(buffer, 8, metaBox.offset) - }; - } - throw new TypeError("Invalid HEIF, no size found"); - } -}; - -const SIZE_HEADER = 4 + 4; -const FILE_LENGTH_OFFSET = 4; -const ENTRY_LENGTH_OFFSET = 4; -const ICON_TYPE_SIZE = { - ICON: 32, - "ICN#": 32, - // m => 16 x 16 - "icm#": 16, - icm4: 16, - icm8: 16, - // s => 16 x 16 - "ics#": 16, - ics4: 16, - ics8: 16, - is32: 16, - s8mk: 16, - icp4: 16, - // l => 32 x 32 - icl4: 32, - icl8: 32, - il32: 32, - l8mk: 32, - icp5: 32, - ic11: 32, - // h => 48 x 48 - ich4: 48, - ich8: 48, - ih32: 48, - h8mk: 48, - // . => 64 x 64 - icp6: 64, - ic12: 32, - // t => 128 x 128 - it32: 128, - t8mk: 128, - ic07: 128, - // . => 256 x 256 - ic08: 256, - ic13: 256, - // . => 512 x 512 - ic09: 512, - ic14: 512, - // . => 1024 x 1024 - ic10: 1024 -}; -function readImageHeader(input, imageOffset) { - const imageLengthOffset = imageOffset + ENTRY_LENGTH_OFFSET; - return [ - toUTF8String(input, imageOffset, imageLengthOffset), - readUInt32BE(input, imageLengthOffset) - ]; -} -function getImageSize(type) { - const size = ICON_TYPE_SIZE[type]; - return { width: size, height: size, type }; -} -const ICNS = { - validate: (input) => toUTF8String(input, 0, 4) === "icns", - calculate(input) { - const inputLength = input.length; - const fileLength = readUInt32BE(input, FILE_LENGTH_OFFSET); - let imageOffset = SIZE_HEADER; - let imageHeader = readImageHeader(input, imageOffset); - let imageSize = getImageSize(imageHeader[0]); - imageOffset += imageHeader[1]; - if (imageOffset === fileLength) return imageSize; - const result = { - height: imageSize.height, - images: [imageSize], - width: imageSize.width - }; - while (imageOffset < fileLength && imageOffset < inputLength) { - imageHeader = readImageHeader(input, imageOffset); - imageSize = getImageSize(imageHeader[0]); - imageOffset += imageHeader[1]; - result.images.push(imageSize); - } - return result; - } -}; - -const J2C = { - // TODO: this doesn't seem right. SIZ marker doesn't have to be right after the SOC - validate: (input) => toHexString(input, 0, 4) === "ff4fff51", - calculate: (input) => ({ - height: readUInt32BE(input, 12), - width: readUInt32BE(input, 8) - }) -}; - -const JP2 = { - validate(input) { - if (readUInt32BE(input, 4) !== 1783636e3 || readUInt32BE(input, 0) < 1) return false; - const ftypBox = findBox(input, "ftyp", 0); - if (!ftypBox) return false; - return readUInt32BE(input, ftypBox.offset + 4) === 1718909296; - }, - calculate(input) { - const jp2hBox = findBox(input, "jp2h", 0); - const ihdrBox = jp2hBox && findBox(input, "ihdr", jp2hBox.offset + 8); - if (ihdrBox) { - return { - height: readUInt32BE(input, ihdrBox.offset + 8), - width: readUInt32BE(input, ihdrBox.offset + 12) - }; - } - throw new TypeError("Unsupported JPEG 2000 format"); - } -}; - -const EXIF_MARKER = "45786966"; -const APP1_DATA_SIZE_BYTES = 2; -const EXIF_HEADER_BYTES = 6; -const TIFF_BYTE_ALIGN_BYTES = 2; -const BIG_ENDIAN_BYTE_ALIGN = "4d4d"; -const LITTLE_ENDIAN_BYTE_ALIGN = "4949"; -const IDF_ENTRY_BYTES = 12; -const NUM_DIRECTORY_ENTRIES_BYTES = 2; -function isEXIF(input) { - return toHexString(input, 2, 6) === EXIF_MARKER; -} -function extractSize(input, index) { - return { - height: readUInt16BE(input, index), - width: readUInt16BE(input, index + 2) - }; -} -function extractOrientation(exifBlock, isBigEndian) { - const idfOffset = 8; - const offset = EXIF_HEADER_BYTES + idfOffset; - const idfDirectoryEntries = readUInt(exifBlock, 16, offset, isBigEndian); - for (let directoryEntryNumber = 0; directoryEntryNumber < idfDirectoryEntries; directoryEntryNumber++) { - const start = offset + NUM_DIRECTORY_ENTRIES_BYTES + directoryEntryNumber * IDF_ENTRY_BYTES; - const end = start + IDF_ENTRY_BYTES; - if (start > exifBlock.length) { - return; - } - const block = exifBlock.slice(start, end); - const tagNumber = readUInt(block, 16, 0, isBigEndian); - if (tagNumber === 274) { - const dataFormat = readUInt(block, 16, 2, isBigEndian); - if (dataFormat !== 3) { - return; - } - const numberOfComponents = readUInt(block, 32, 4, isBigEndian); - if (numberOfComponents !== 1) { - return; - } - return readUInt(block, 16, 8, isBigEndian); - } - } -} -function validateExifBlock(input, index) { - const exifBlock = input.slice(APP1_DATA_SIZE_BYTES, index); - const byteAlign = toHexString( - exifBlock, - EXIF_HEADER_BYTES, - EXIF_HEADER_BYTES + TIFF_BYTE_ALIGN_BYTES - ); - const isBigEndian = byteAlign === BIG_ENDIAN_BYTE_ALIGN; - const isLittleEndian = byteAlign === LITTLE_ENDIAN_BYTE_ALIGN; - if (isBigEndian || isLittleEndian) { - return extractOrientation(exifBlock, isBigEndian); - } -} -function validateInput(input, index) { - if (index > input.length) { - throw new TypeError("Corrupt JPG, exceeded buffer limits"); - } -} -const JPG = { - validate: (input) => toHexString(input, 0, 2) === "ffd8", - calculate(input) { - input = input.slice(4); - let orientation; - let next; - while (input.length) { - const i = readUInt16BE(input, 0); - if (input[i] !== 255) { - input = input.slice(i); - continue; - } - if (isEXIF(input)) { - orientation = validateExifBlock(input, i); - } - validateInput(input, i); - next = input[i + 1]; - if (next === 192 || next === 193 || next === 194) { - const size = extractSize(input, i + 5); - if (!orientation) { - return size; - } - return { - height: size.height, - orientation, - width: size.width - }; - } - input = input.slice(i + 2); - } - throw new TypeError("Invalid JPG, no size found"); - } -}; - -const KTX = { - validate: (input) => { - const signature = toUTF8String(input, 1, 7); - return ["KTX 11", "KTX 20"].includes(signature); - }, - calculate: (input) => { - const type = input[5] === 49 ? "ktx" : "ktx2"; - const offset = type === "ktx" ? 36 : 20; - return { - height: readUInt32LE(input, offset + 4), - width: readUInt32LE(input, offset), - type - }; - } -}; - -const pngSignature = "PNG\r\n\n"; -const pngImageHeaderChunkName = "IHDR"; -const pngFriedChunkName = "CgBI"; -const PNG = { - validate(input) { - if (pngSignature === toUTF8String(input, 1, 8)) { - let chunkName = toUTF8String(input, 12, 16); - if (chunkName === pngFriedChunkName) { - chunkName = toUTF8String(input, 28, 32); - } - if (chunkName !== pngImageHeaderChunkName) { - throw new TypeError("Invalid PNG"); - } - return true; - } - return false; - }, - calculate(input) { - if (toUTF8String(input, 12, 16) === pngFriedChunkName) { - return { - height: readUInt32BE(input, 36), - width: readUInt32BE(input, 32) - }; - } - return { - height: readUInt32BE(input, 20), - width: readUInt32BE(input, 16) - }; - } -}; - -const PNMTypes = { - P1: "pbm/ascii", - P2: "pgm/ascii", - P3: "ppm/ascii", - P4: "pbm", - P5: "pgm", - P6: "ppm", - P7: "pam", - PF: "pfm" -}; -const handlers = { - default: (lines) => { - let dimensions = []; - while (lines.length > 0) { - const line = lines.shift(); - if (line[0] === "#") { - continue; - } - dimensions = line.split(" "); - break; - } - if (dimensions.length === 2) { - return { - height: parseInt(dimensions[1], 10), - width: parseInt(dimensions[0], 10) - }; - } else { - throw new TypeError("Invalid PNM"); - } - }, - pam: (lines) => { - const size = {}; - while (lines.length > 0) { - const line = lines.shift(); - if (line.length > 16 || line.charCodeAt(0) > 128) { - continue; - } - const [key, value] = line.split(" "); - if (key && value) { - size[key.toLowerCase()] = parseInt(value, 10); - } - if (size.height && size.width) { - break; - } - } - if (size.height && size.width) { - return { - height: size.height, - width: size.width - }; - } else { - throw new TypeError("Invalid PAM"); - } - } -}; -const PNM = { - validate: (input) => toUTF8String(input, 0, 2) in PNMTypes, - calculate(input) { - const signature = toUTF8String(input, 0, 2); - const type = PNMTypes[signature]; - const lines = toUTF8String(input, 3).split(/[\r\n]+/); - const handler = handlers[type] || handlers.default; - return handler(lines); - } -}; - -const PSD = { - validate: (input) => toUTF8String(input, 0, 4) === "8BPS", - calculate: (input) => ({ - height: readUInt32BE(input, 14), - width: readUInt32BE(input, 18) - }) -}; - -const svgReg = /"']|"[^"]*"|'[^']*')*>/; -const extractorRegExps = { - height: /\sheight=(['"])([^%]+?)\1/, - root: svgReg, - viewbox: /\sviewBox=(['"])(.+?)\1/i, - width: /\swidth=(['"])([^%]+?)\1/ -}; -const INCH_CM = 2.54; -const units = { - in: 96, - cm: 96 / INCH_CM, - em: 16, - ex: 8, - m: 96 / INCH_CM * 100, - mm: 96 / INCH_CM / 10, - pc: 96 / 72 / 12, - pt: 96 / 72, - px: 1 -}; -const unitsReg = new RegExp( - `^([0-9.]+(?:e\\d+)?)(${Object.keys(units).join("|")})?$` -); -function parseLength(len) { - const m = unitsReg.exec(len); - if (!m) { - return void 0; - } - return Math.round(Number(m[1]) * (units[m[2]] || 1)); -} -function parseViewbox(viewbox) { - const bounds = viewbox.split(" "); - return { - height: parseLength(bounds[3]), - width: parseLength(bounds[2]) - }; -} -function parseAttributes(root) { - const width = extractorRegExps.width.exec(root); - const height = extractorRegExps.height.exec(root); - const viewbox = extractorRegExps.viewbox.exec(root); - return { - height: height && parseLength(height[2]), - viewbox: viewbox && parseViewbox(viewbox[2]), - width: width && parseLength(width[2]) - }; -} -function calculateByDimensions(attrs) { - return { - height: attrs.height, - width: attrs.width - }; -} -function calculateByViewbox(attrs, viewbox) { - const ratio = viewbox.width / viewbox.height; - if (attrs.width) { - return { - height: Math.floor(attrs.width / ratio), - width: attrs.width - }; - } - if (attrs.height) { - return { - height: attrs.height, - width: Math.floor(attrs.height * ratio) - }; - } - return { - height: viewbox.height, - width: viewbox.width - }; -} -const SVG = { - // Scan only the first kilo-byte to speed up the check on larger files - validate: (input) => svgReg.test(toUTF8String(input, 0, 1e3)), - calculate(input) { - const root = extractorRegExps.root.exec(toUTF8String(input)); - if (root) { - const attrs = parseAttributes(root[0]); - if (attrs.width && attrs.height) { - return calculateByDimensions(attrs); - } - if (attrs.viewbox) { - return calculateByViewbox(attrs, attrs.viewbox); - } - } - throw new TypeError("Invalid SVG"); - } -}; - -const TGA = { - validate(input) { - return readUInt16LE(input, 0) === 0 && readUInt16LE(input, 4) === 0; - }, - calculate(input) { - return { - height: readUInt16LE(input, 14), - width: readUInt16LE(input, 12) - }; - } -}; - -function readIFD(input, isBigEndian) { - const ifdOffset = readUInt(input, 32, 4, isBigEndian); - return input.slice(ifdOffset + 2); -} -function readValue(input, isBigEndian) { - const low = readUInt(input, 16, 8, isBigEndian); - const high = readUInt(input, 16, 10, isBigEndian); - return (high << 16) + low; -} -function nextTag(input) { - if (input.length > 24) { - return input.slice(12); - } -} -function extractTags(input, isBigEndian) { - const tags = {}; - let temp = input; - while (temp && temp.length) { - const code = readUInt(temp, 16, 0, isBigEndian); - const type = readUInt(temp, 16, 2, isBigEndian); - const length = readUInt(temp, 32, 4, isBigEndian); - if (code === 0) { - break; - } else { - if (length === 1 && (type === 3 || type === 4)) { - tags[code] = readValue(temp, isBigEndian); - } - temp = nextTag(temp); - } - } - return tags; -} -function determineEndianness(input) { - const signature = toUTF8String(input, 0, 2); - if ("II" === signature) { - return "LE"; - } else if ("MM" === signature) { - return "BE"; - } -} -const signatures = [ - // '492049', // currently not supported - "49492a00", - // Little endian - "4d4d002a" - // Big Endian - // '4d4d002a', // BigTIFF > 4GB. currently not supported -]; -const TIFF = { - validate: (input) => signatures.includes(toHexString(input, 0, 4)), - calculate(input) { - const isBigEndian = determineEndianness(input) === "BE"; - const ifdBuffer = readIFD(input, isBigEndian); - const tags = extractTags(ifdBuffer, isBigEndian); - const width = tags[256]; - const height = tags[257]; - if (!width || !height) { - throw new TypeError("Invalid Tiff. Missing tags"); - } - return { height, width }; - } -}; - -function calculateExtended(input) { - return { - height: 1 + readUInt24LE(input, 7), - width: 1 + readUInt24LE(input, 4) - }; -} -function calculateLossless(input) { - return { - height: 1 + ((input[4] & 15) << 10 | input[3] << 2 | (input[2] & 192) >> 6), - width: 1 + ((input[2] & 63) << 8 | input[1]) - }; -} -function calculateLossy(input) { - return { - height: readInt16LE(input, 8) & 16383, - width: readInt16LE(input, 6) & 16383 - }; -} -const WEBP = { - validate(input) { - const riffHeader = "RIFF" === toUTF8String(input, 0, 4); - const webpHeader = "WEBP" === toUTF8String(input, 8, 12); - const vp8Header = "VP8" === toUTF8String(input, 12, 15); - return riffHeader && webpHeader && vp8Header; - }, - calculate(input) { - const chunkHeader = toUTF8String(input, 12, 16); - input = input.slice(20, 30); - if (chunkHeader === "VP8X") { - const extendedHeader = input[0]; - const validStart = (extendedHeader & 192) === 0; - const validEnd = (extendedHeader & 1) === 0; - if (validStart && validEnd) { - return calculateExtended(input); - } else { - throw new TypeError("Invalid WebP"); - } - } - if (chunkHeader === "VP8 " && input[0] !== 47) { - return calculateLossy(input); - } - const signature = toHexString(input, 3, 6); - if (chunkHeader === "VP8L" && signature !== "9d012a") { - return calculateLossless(input); - } - throw new TypeError("Invalid WebP"); - } -}; - -const typeHandlers = /* @__PURE__ */ new Map([ - ["bmp", BMP], - ["cur", CUR], - ["dds", DDS], - ["gif", GIF], - ["heif", HEIF], - ["icns", ICNS], - ["ico", ICO], - ["j2c", J2C], - ["jp2", JP2], - ["jpg", JPG], - ["ktx", KTX], - ["png", PNG], - ["pnm", PNM], - ["psd", PSD], - ["svg", SVG], - ["tga", TGA], - ["tiff", TIFF], - ["webp", WEBP] -]); -const types = Array.from(typeHandlers.keys()); - -const firstBytes = /* @__PURE__ */ new Map([ - [56, "psd"], - [66, "bmp"], - [68, "dds"], - [71, "gif"], - [73, "tiff"], - [77, "tiff"], - [82, "webp"], - [105, "icns"], - [137, "png"], - [255, "jpg"] -]); -function detector(input) { - const byte = input[0]; - const type = firstBytes.get(byte); - if (type && typeHandlers.get(type).validate(input)) { - return type; - } - return types.find((fileType) => typeHandlers.get(fileType).validate(input)); -} - -function lookup(input) { - const type = detector(input); - if (typeof type !== "undefined") { - const size = typeHandlers.get(type).calculate(input); - if (size !== void 0) { - size.type = size.type ?? type; - return size; - } - } - throw new TypeError("unsupported file type: " + type); -} - -async function imageMetadata(data, src) { - let result; - try { - result = lookup(data); - } catch { - throw new AstroError({ - ...NoImageMetadata, - message: NoImageMetadata.message(src) - }); - } - if (!result.height || !result.width || !result.type) { - throw new AstroError({ - ...NoImageMetadata, - message: NoImageMetadata.message(src) - }); - } - const { width, height, type, orientation } = result; - const isPortrait = (orientation || 0) >= 5; - return { - width: isPortrait ? height : width, - height: isPortrait ? width : height, - format: type, - orientation - }; -} - -async function inferRemoteSize(url) { - const response = await fetch(url); - if (!response.body || !response.ok) { - throw new AstroError({ - ...FailedToFetchRemoteImageDimensions, - message: FailedToFetchRemoteImageDimensions.message(url) - }); - } - const reader = response.body.getReader(); - let done, value; - let accumulatedChunks = new Uint8Array(); - while (!done) { - const readResult = await reader.read(); - done = readResult.done; - if (done) break; - if (readResult.value) { - value = readResult.value; - let tmp = new Uint8Array(accumulatedChunks.length + value.length); - tmp.set(accumulatedChunks, 0); - tmp.set(value, accumulatedChunks.length); - accumulatedChunks = tmp; - try { - const dimensions = await imageMetadata(accumulatedChunks, url); - if (dimensions) { - await reader.cancel(); - return dimensions; - } - } catch { - } - } - } - throw new AstroError({ - ...NoImageMetadata, - message: NoImageMetadata.message(url) - }); -} - -const PLACEHOLDER_BASE = "astro://placeholder"; -function createPlaceholderURL(pathOrUrl) { - return new URL(pathOrUrl, PLACEHOLDER_BASE); -} -function stringifyPlaceholderURL(url) { - return url.href.replace(PLACEHOLDER_BASE, ""); -} - -async function getConfiguredImageService() { - if (!globalThis?.astroAsset?.imageService) { - const { default: service } = await import( - // @ts-expect-error - './sharp_CR567j69.mjs' - ).catch((e) => { - const error = new AstroError(InvalidImageService); - error.cause = e; - throw error; - }); - if (!globalThis.astroAsset) globalThis.astroAsset = {}; - globalThis.astroAsset.imageService = service; - return service; - } - return globalThis.astroAsset.imageService; -} -async function getImage$1(options, imageConfig) { - if (!options || typeof options !== "object") { - throw new AstroError({ - ...ExpectedImageOptions, - message: ExpectedImageOptions.message(JSON.stringify(options)) - }); - } - if (typeof options.src === "undefined") { - throw new AstroError({ - ...ExpectedImage, - message: ExpectedImage.message( - options.src, - "undefined", - JSON.stringify(options) - ) - }); - } - if (isImageMetadata(options)) { - throw new AstroError(ExpectedNotESMImage); - } - const service = await getConfiguredImageService(); - const resolvedOptions = { - ...options, - src: await resolveSrc(options.src) - }; - let originalWidth; - let originalHeight; - if (options.inferSize && isRemoteImage(resolvedOptions.src) && isRemotePath(resolvedOptions.src)) { - const result = await inferRemoteSize(resolvedOptions.src); - resolvedOptions.width ??= result.width; - resolvedOptions.height ??= result.height; - originalWidth = result.width; - originalHeight = result.height; - delete resolvedOptions.inferSize; - } - const originalFilePath = isESMImportedImage(resolvedOptions.src) ? resolvedOptions.src.fsPath : void 0; - const clonedSrc = isESMImportedImage(resolvedOptions.src) ? ( - // @ts-expect-error - clone is a private, hidden prop - resolvedOptions.src.clone ?? resolvedOptions.src - ) : resolvedOptions.src; - if (isESMImportedImage(clonedSrc)) { - originalWidth = clonedSrc.width; - originalHeight = clonedSrc.height; - } - if (originalWidth && originalHeight) { - const aspectRatio = originalWidth / originalHeight; - if (resolvedOptions.height && !resolvedOptions.width) { - resolvedOptions.width = Math.round(resolvedOptions.height * aspectRatio); - } else if (resolvedOptions.width && !resolvedOptions.height) { - resolvedOptions.height = Math.round(resolvedOptions.width / aspectRatio); - } else if (!resolvedOptions.width && !resolvedOptions.height) { - resolvedOptions.width = originalWidth; - resolvedOptions.height = originalHeight; - } - } - resolvedOptions.src = clonedSrc; - const layout = options.layout ?? imageConfig.layout ?? "none"; - if (resolvedOptions.priority) { - resolvedOptions.loading ??= "eager"; - resolvedOptions.decoding ??= "sync"; - resolvedOptions.fetchpriority ??= "high"; - delete resolvedOptions.priority; - } else { - resolvedOptions.loading ??= "lazy"; - resolvedOptions.decoding ??= "async"; - resolvedOptions.fetchpriority ??= "auto"; - } - if (layout !== "none") { - resolvedOptions.widths ||= getWidths({ - width: resolvedOptions.width, - layout, - originalWidth, - breakpoints: imageConfig.breakpoints?.length ? imageConfig.breakpoints : isLocalService(service) ? LIMITED_RESOLUTIONS : DEFAULT_RESOLUTIONS - }); - resolvedOptions.sizes ||= getSizesAttribute({ width: resolvedOptions.width, layout }); - delete resolvedOptions.densities; - resolvedOptions.style = addCSSVarsToStyle( - { - fit: cssFitValues.includes(resolvedOptions.fit ?? "") && resolvedOptions.fit, - pos: resolvedOptions.position - }, - resolvedOptions.style - ); - resolvedOptions["data-astro-image"] = layout; - } - const validatedOptions = service.validateOptions ? await service.validateOptions(resolvedOptions, imageConfig) : resolvedOptions; - const srcSetTransforms = service.getSrcSet ? await service.getSrcSet(validatedOptions, imageConfig) : []; - let imageURL = await service.getURL(validatedOptions, imageConfig); - const matchesValidatedTransform = (transform) => transform.width === validatedOptions.width && transform.height === validatedOptions.height && transform.format === validatedOptions.format; - let srcSets = await Promise.all( - srcSetTransforms.map(async (srcSet) => { - return { - transform: srcSet.transform, - url: matchesValidatedTransform(srcSet.transform) ? imageURL : await service.getURL(srcSet.transform, imageConfig), - descriptor: srcSet.descriptor, - attributes: srcSet.attributes - }; - }) - ); - if (isLocalService(service) && globalThis.astroAsset.addStaticImage && !(isRemoteImage(validatedOptions.src) && imageURL === validatedOptions.src)) { - const propsToHash = service.propertiesToHash ?? DEFAULT_HASH_PROPS; - imageURL = globalThis.astroAsset.addStaticImage( - validatedOptions, - propsToHash, - originalFilePath - ); - srcSets = srcSetTransforms.map((srcSet) => { - return { - transform: srcSet.transform, - url: matchesValidatedTransform(srcSet.transform) ? imageURL : globalThis.astroAsset.addStaticImage(srcSet.transform, propsToHash, originalFilePath), - descriptor: srcSet.descriptor, - attributes: srcSet.attributes - }; - }); - } else if (imageConfig.assetQueryParams) { - const imageURLObj = createPlaceholderURL(imageURL); - imageConfig.assetQueryParams.forEach((value, key) => { - imageURLObj.searchParams.set(key, value); - }); - imageURL = stringifyPlaceholderURL(imageURLObj); - srcSets = srcSets.map((srcSet) => { - const urlObj = createPlaceholderURL(srcSet.url); - imageConfig.assetQueryParams.forEach((value, key) => { - urlObj.searchParams.set(key, value); - }); - return { - ...srcSet, - url: stringifyPlaceholderURL(urlObj) - }; - }); - } - return { - rawOptions: resolvedOptions, - options: validatedOptions, - src: imageURL, - srcSet: { - values: srcSets, - attribute: srcSets.map((srcSet) => `${srcSet.url} ${srcSet.descriptor}`).join(", ") - }, - attributes: service.getHTMLAttributes !== void 0 ? await service.getHTMLAttributes(validatedOptions, imageConfig) : {} - }; -} - -const $$Astro$2 = createAstro(); -const $$Image = createComponent(async ($$result, $$props, $$slots) => { - const Astro2 = $$result.createAstro($$Astro$2, $$props, $$slots); - Astro2.self = $$Image; - const props = Astro2.props; - if (props.alt === void 0 || props.alt === null) { - throw new AstroError(ImageMissingAlt); - } - if (typeof props.width === "string") { - props.width = parseInt(props.width); - } - if (typeof props.height === "string") { - props.height = parseInt(props.height); - } - const layout = props.layout ?? imageConfig.layout ?? "none"; - if (layout !== "none") { - props.layout ??= imageConfig.layout; - props.fit ??= imageConfig.objectFit ?? "cover"; - props.position ??= imageConfig.objectPosition ?? "center"; - } - const image = await getImage(props); - const additionalAttributes = {}; - if (image.srcSet.values.length > 0) { - additionalAttributes.srcset = image.srcSet.attribute; - } - const { class: className, ...attributes } = { ...additionalAttributes, ...image.attributes }; - return renderTemplate`${maybeRenderHead()}`; -}, "/Users/adrianlam/GitHub/workflow/node_modules/.pnpm/astro@5.15.6_@netlify+blobs@9.1.2_@types+node@24.6.2_@vercel+functions@3.1.4_@aws-sdk+c_33d54f21a5540c974d08dc1b122d5cc1/node_modules/astro/components/Image.astro", void 0); - -const $$Astro$1 = createAstro(); -const $$Picture = createComponent(async ($$result, $$props, $$slots) => { - const Astro2 = $$result.createAstro($$Astro$1, $$props, $$slots); - Astro2.self = $$Picture; - const defaultFormats = ["webp"]; - const defaultFallbackFormat = "png"; - const specialFormatsFallback = ["gif", "svg", "jpg", "jpeg"]; - const { formats = defaultFormats, pictureAttributes = {}, fallbackFormat, ...props } = Astro2.props; - if (props.alt === void 0 || props.alt === null) { - throw new AstroError(ImageMissingAlt); - } - const scopedStyleClass = props.class?.match(/\bastro-\w{8}\b/)?.[0]; - if (scopedStyleClass) { - if (pictureAttributes.class) { - pictureAttributes.class = `${pictureAttributes.class} ${scopedStyleClass}`; - } else { - pictureAttributes.class = scopedStyleClass; - } - } - const layout = props.layout ?? imageConfig.layout ?? "none"; - const useResponsive = layout !== "none"; - if (useResponsive) { - props.layout ??= imageConfig.layout; - props.fit ??= imageConfig.objectFit ?? "cover"; - props.position ??= imageConfig.objectPosition ?? "center"; - } - for (const key in props) { - if (key.startsWith("data-astro-cid")) { - pictureAttributes[key] = props[key]; - } - } - const originalSrc = await resolveSrc(props.src); - const optimizedImages = await Promise.all( - formats.map( - async (format) => await getImage({ - ...props, - src: originalSrc, - format, - widths: props.widths, - densities: props.densities - }) - ) - ); - let resultFallbackFormat = fallbackFormat ?? defaultFallbackFormat; - if (!fallbackFormat && isESMImportedImage(originalSrc) && specialFormatsFallback.includes(originalSrc.format)) { - resultFallbackFormat = originalSrc.format; - } - const fallbackImage = await getImage({ - ...props, - format: resultFallbackFormat, - widths: props.widths, - densities: props.densities - }); - const imgAdditionalAttributes = {}; - const sourceAdditionalAttributes = {}; - if (props.sizes) { - sourceAdditionalAttributes.sizes = props.sizes; - } - if (fallbackImage.srcSet.values.length > 0) { - imgAdditionalAttributes.srcset = fallbackImage.srcSet.attribute; - } - const { class: className, ...attributes } = { - ...imgAdditionalAttributes, - ...fallbackImage.attributes - }; - return renderTemplate`${maybeRenderHead()} ${Object.entries(optimizedImages).map(([_, image]) => { - const srcsetAttribute = props.densities || !props.densities && !props.widths && !useResponsive ? `${image.src}${image.srcSet.values.length > 0 ? ", " + image.srcSet.attribute : ""}` : image.srcSet.attribute; - return renderTemplate``; - })} `; -}, "/Users/adrianlam/GitHub/workflow/node_modules/.pnpm/astro@5.15.6_@netlify+blobs@9.1.2_@types+node@24.6.2_@vercel+functions@3.1.4_@aws-sdk+c_33d54f21a5540c974d08dc1b122d5cc1/node_modules/astro/components/Picture.astro", void 0); - -const fontsMod = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null -}, Symbol.toStringTag, { value: 'Module' })); - -function filterPreloads(data, preload) { - if (!preload) { - return null; - } - if (preload === true) { - return data; - } - return data.filter( - ({ weight, style, subset }) => preload.some((p) => { - if (p.weight !== void 0 && weight !== void 0 && !checkWeight(p.weight.toString(), weight)) { - return false; - } - if (p.style !== void 0 && p.style !== style) { - return false; - } - if (p.subset !== void 0 && p.subset !== subset) { - return false; - } - return true; - }) - ); -} -function checkWeight(input, target) { - const trimmedInput = input.trim(); - if (trimmedInput.includes(" ")) { - return trimmedInput === target; - } - if (target.includes(" ")) { - const [a, b] = target.split(" "); - const parsedInput = Number.parseInt(input); - return parsedInput >= Number.parseInt(a) && parsedInput <= Number.parseInt(b); - } - return input === target; -} - -const $$Astro = createAstro(); -const $$Font = createComponent(($$result, $$props, $$slots) => { - const Astro2 = $$result.createAstro($$Astro, $$props, $$slots); - Astro2.self = $$Font; - const { internalConsumableMap } = fontsMod; - if (!internalConsumableMap) { - throw new AstroError(ExperimentalFontsNotEnabled); - } - const { cssVariable, preload = false } = Astro2.props; - const data = internalConsumableMap.get(cssVariable); - if (!data) { - throw new AstroError({ - ...FontFamilyNotFound, - message: FontFamilyNotFound.message(cssVariable) - }); - } - const filteredPreloadData = filterPreloads(data.preloadData, preload); - return renderTemplate`${filteredPreloadData?.map(({ url, type }) => renderTemplate``)}`; -}, "/Users/adrianlam/GitHub/workflow/node_modules/.pnpm/astro@5.15.6_@netlify+blobs@9.1.2_@types+node@24.6.2_@vercel+functions@3.1.4_@aws-sdk+c_33d54f21a5540c974d08dc1b122d5cc1/node_modules/astro/components/Font.astro", void 0); - -const assetQueryParams = undefined; - const imageConfig = {"endpoint":{"route":"/_image","entrypoint":"astro/assets/endpoint/node"},"service":{"entrypoint":"astro/assets/services/sharp","config":{}},"domains":[],"remotePatterns":[],"responsiveStyles":false}; - Object.defineProperty(imageConfig, 'assetQueryParams', { - value: assetQueryParams, - enumerable: false, - configurable: true, - }); - // This is used by the @astrojs/node integration to locate images. - // It's unused on other platforms, but on some platforms like Netlify (and presumably also Vercel) - // new URL("dist/...") is interpreted by the bundler as a signal to include that directory - // in the Lambda bundle, which would bloat the bundle with images. - // To prevent this, we mark the URL construction as pure, - // so that it's tree-shaken away for all platforms that don't need it. - const outDir = /* #__PURE__ */ new URL("file:///Users/adrianlam/GitHub/workflow/workbench/astro/dist/client/"); - const getImage = async (options) => await getImage$1(options, imageConfig); - -const fnv1a52 = (str) => { - const len = str.length; - let i = 0, t0 = 0, v0 = 8997, t1 = 0, v1 = 33826, t2 = 0, v2 = 40164, t3 = 0, v3 = 52210; - while (i < len) { - v0 ^= str.charCodeAt(i++); - t0 = v0 * 435; - t1 = v1 * 435; - t2 = v2 * 435; - t3 = v3 * 435; - t2 += v0 << 8; - t3 += v1 << 8; - t1 += t0 >>> 16; - v0 = t0 & 65535; - t2 += t1 >>> 16; - v1 = t1 & 65535; - v3 = t3 + (t2 >>> 16) & 65535; - v2 = t2 & 65535; - } - return (v3 & 15) * 281474976710656 + v2 * 4294967296 + v1 * 65536 + (v0 ^ v3 >> 4); -}; -const etag = (payload, weak = false) => { - const prefix = weak ? 'W/"' : '"'; - return prefix + fnv1a52(payload).toString(36) + payload.length.toString(36) + '"'; -}; - -async function loadRemoteImage(src) { - try { - const res = await fetch(src); - if (!res.ok) { - return void 0; - } - return Buffer.from(await res.arrayBuffer()); - } catch { - return void 0; - } -} -const handleImageRequest = async ({ - request, - loadLocalImage -}) => { - const imageService = await getConfiguredImageService(); - if (!("transform" in imageService)) { - throw new Error("Configured image service is not a local service"); - } - const url = new URL(request.url); - const transform = await imageService.parseURL(url, imageConfig); - if (!transform?.src) { - return new Response("Invalid request", { status: 400 }); - } - let inputBuffer = void 0; - if (isRemotePath(transform.src)) { - if (!isRemoteAllowed(transform.src, imageConfig)) { - return new Response("Forbidden", { status: 403 }); - } - inputBuffer = await loadRemoteImage(new URL(transform.src)); - } else { - inputBuffer = await loadLocalImage(removeQueryString(transform.src), url); - } - if (!inputBuffer) { - return new Response("Internal Server Error", { status: 500 }); - } - const { data, format } = await imageService.transform(inputBuffer, transform, imageConfig); - return new Response(data, { - status: 200, - headers: { - "Content-Type": mime.lookup(format) ?? `image/${format}`, - "Cache-Control": "public, max-age=31536000", - ETag: etag(data.toString()), - Date: (/* @__PURE__ */ new Date()).toUTCString() - } - }); -}; - -async function loadLocalImage(src, url) { - const idx = url.pathname.indexOf("/_image"); - if (idx > 0) { - src = src.slice(idx); - } - if (!URL.canParse("." + src, outDir)) { - return void 0; - } - const fileUrl = new URL("." + src, outDir); - if (fileUrl.protocol !== "file:") { - return void 0; - } - if (!isParentDirectory(fileURLToPath(outDir), fileURLToPath(fileUrl))) { - return void 0; - } - try { - return await readFile(fileUrl); - } catch { - return void 0; - } -} -const GET = async ({ request }) => { - try { - return await handleImageRequest({ request, loadLocalImage }); - } catch (err) { - console.error("Could not process image request:", err); - return new Response("Internal Server Error", { - status: 500 - }); - } -}; - -const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - GET -}, Symbol.toStringTag, { value: 'Module' })); - -const page = () => _page; - -export { page as a, baseService as b, parseQuality as p }; diff --git a/workbench/astro/dist/server/chunks/remote_OOD9OFqU.mjs b/workbench/astro/dist/server/chunks/remote_OOD9OFqU.mjs deleted file mode 100644 index 33d88f004..000000000 --- a/workbench/astro/dist/server/chunks/remote_OOD9OFqU.mjs +++ /dev/null @@ -1,188 +0,0 @@ -function appendForwardSlash(path) { - return path.endsWith("/") ? path : path + "/"; -} -function prependForwardSlash(path) { - return path[0] === "/" ? path : "/" + path; -} -const MANY_TRAILING_SLASHES = /\/{2,}$/g; -function collapseDuplicateTrailingSlashes(path, trailingSlash) { - if (!path) { - return path; - } - return path.replace(MANY_TRAILING_SLASHES, trailingSlash ? "/" : "") || "/"; -} -function removeTrailingForwardSlash(path) { - return path.endsWith("/") ? path.slice(0, path.length - 1) : path; -} -function removeLeadingForwardSlash(path) { - return path.startsWith("/") ? path.substring(1) : path; -} -function trimSlashes(path) { - return path.replace(/^\/|\/$/g, ""); -} -function isString(path) { - return typeof path === "string" || path instanceof String; -} -const INTERNAL_PREFIXES = /* @__PURE__ */ new Set(["/_", "/@", "/.", "//"]); -const JUST_SLASHES = /^\/{2,}$/; -function isInternalPath(path) { - return INTERNAL_PREFIXES.has(path.slice(0, 2)) && !JUST_SLASHES.test(path); -} -function joinPaths(...paths) { - return paths.filter(isString).map((path, i) => { - if (i === 0) { - return removeTrailingForwardSlash(path); - } else if (i === paths.length - 1) { - return removeLeadingForwardSlash(path); - } else { - return trimSlashes(path); - } - }).join("/"); -} -function removeQueryString(path) { - const index = path.lastIndexOf("?"); - return index > 0 ? path.substring(0, index) : path; -} -function isRemotePath(src) { - if (!src) return false; - const trimmed = src.trim(); - if (!trimmed) return false; - let decoded = trimmed; - let previousDecoded = ""; - let maxIterations = 10; - while (decoded !== previousDecoded && maxIterations > 0) { - previousDecoded = decoded; - try { - decoded = decodeURIComponent(decoded); - } catch { - break; - } - maxIterations--; - } - if (/^[a-zA-Z]:/.test(decoded)) { - return false; - } - if (decoded[0] === "/" && decoded[1] !== "/" && decoded[1] !== "\\") { - return false; - } - if (decoded[0] === "\\") { - return true; - } - if (decoded.startsWith("//")) { - return true; - } - try { - const url = new URL(decoded, "http://n"); - if (url.username || url.password) { - return true; - } - if (decoded.includes("@") && !url.pathname.includes("@") && !url.search.includes("@")) { - return true; - } - if (url.origin !== "http://n") { - const protocol = url.protocol.toLowerCase(); - if (protocol === "file:") { - return false; - } - return true; - } - if (URL.canParse(decoded)) { - return true; - } - return false; - } catch { - return true; - } -} -function isParentDirectory(parentPath, childPath) { - if (!parentPath || !childPath) { - return false; - } - if (parentPath.includes("://") || childPath.includes("://")) { - return false; - } - if (isRemotePath(parentPath) || isRemotePath(childPath)) { - return false; - } - if (parentPath.includes("..") || childPath.includes("..")) { - return false; - } - if (parentPath.includes("\0") || childPath.includes("\0")) { - return false; - } - const normalizedParent = appendForwardSlash(slash(parentPath).toLowerCase()); - const normalizedChild = slash(childPath).toLowerCase(); - if (normalizedParent === normalizedChild || normalizedParent === normalizedChild + "/") { - return false; - } - return normalizedChild.startsWith(normalizedParent); -} -function slash(path) { - return path.replace(/\\/g, "/"); -} -function fileExtension(path) { - const ext = path.split(".").pop(); - return ext !== path ? `.${ext}` : ""; -} -const WITH_FILE_EXT = /\/[^/]+\.\w+$/; -function hasFileExtension(path) { - return WITH_FILE_EXT.test(path); -} - -function matchPattern(url, remotePattern) { - return matchProtocol(url, remotePattern.protocol) && matchHostname(url, remotePattern.hostname, true) && matchPort(url, remotePattern.port) && matchPathname(url, remotePattern.pathname, true); -} -function matchPort(url, port) { - return !port || port === url.port; -} -function matchProtocol(url, protocol) { - return !protocol || protocol === url.protocol.slice(0, -1); -} -function matchHostname(url, hostname, allowWildcard = false) { - if (!hostname) { - return true; - } else if (!allowWildcard || !hostname.startsWith("*")) { - return hostname === url.hostname; - } else if (hostname.startsWith("**.")) { - const slicedHostname = hostname.slice(2); - return slicedHostname !== url.hostname && url.hostname.endsWith(slicedHostname); - } else if (hostname.startsWith("*.")) { - const slicedHostname = hostname.slice(1); - const additionalSubdomains = url.hostname.replace(slicedHostname, "").split(".").filter(Boolean); - return additionalSubdomains.length === 1; - } - return false; -} -function matchPathname(url, pathname, allowWildcard = false) { - if (!pathname) { - return true; - } else if (!allowWildcard || !pathname.endsWith("*")) { - return pathname === url.pathname; - } else if (pathname.endsWith("/**")) { - const slicedPathname = pathname.slice(0, -2); - return slicedPathname !== url.pathname && url.pathname.startsWith(slicedPathname); - } else if (pathname.endsWith("/*")) { - const slicedPathname = pathname.slice(0, -1); - const additionalPathChunks = url.pathname.replace(slicedPathname, "").split("/").filter(Boolean); - return additionalPathChunks.length === 1; - } - return false; -} -function isRemoteAllowed(src, { - domains, - remotePatterns -}) { - if (!URL.canParse(src)) { - return false; - } - const url = new URL(src); - if (url.protocol === "data:") { - return true; - } - if (!["http:", "https:"].includes(url.protocol)) { - return false; - } - return domains.some((domain) => matchHostname(url, domain)) || remotePatterns.some((remotePattern) => matchPattern(url, remotePattern)); -} - -export { isRemotePath as a, isParentDirectory as b, appendForwardSlash as c, removeTrailingForwardSlash as d, isInternalPath as e, fileExtension as f, collapseDuplicateTrailingSlashes as g, hasFileExtension as h, isRemoteAllowed as i, joinPaths as j, matchPattern as m, prependForwardSlash as p, removeQueryString as r, slash as s, trimSlashes as t }; diff --git a/workbench/astro/dist/server/chunks/resume-hook_BHshEMMl.mjs b/workbench/astro/dist/server/chunks/resume-hook_BHshEMMl.mjs deleted file mode 100644 index f524da81b..000000000 --- a/workbench/astro/dist/server/chunks/resume-hook_BHshEMMl.mjs +++ /dev/null @@ -1,181 +0,0 @@ -import { c as getWorld, h as hydrateStepArguments, w as waitedUntil, d as WEBHOOK_RESPONSE_WRITABLE, e as WorkflowRuntimeError, E as ERROR_SLUGS, t as trace, f as WorkflowRunId, H as HookId, i as HookToken, j as dehydrateStepReturnValue, k as functionsExports, l as WorkflowName, m as getSpanContextForTraceCarrier, n as HookFound } from './index_ePTMDSOu.mjs'; - -/** - * Get the hook by token to find the associated workflow run, - * and hydrate the `metadata` property if it was set from within - * the workflow run. - * - * @param token - The unique token identifying the hook - */ -async function getHookByToken(token) { - const world = getWorld(); - const hook = await world.hooks.getByToken(token); - if (typeof hook.metadata !== 'undefined') { - hook.metadata = hydrateStepArguments(hook.metadata, [], globalThis); - } - return hook; -} -/** - * Resumes a workflow run by sending a payload to a hook identified by its token. - * - * This function is called externally (e.g., from an API route or server action) - * to send data to a hook and resume the associated workflow run. - * - * @param token - The unique token identifying the hook - * @param payload - The data payload to send to the hook - * @returns Promise resolving to the hook - * @throws Error if the hook is not found or if there's an error during the process - * - * @example - * - * ```ts - * // In an API route - * import { resumeHook } from '@workflow/core/runtime'; - * - * export async function POST(request: Request) { - * const { token, data } = await request.json(); - * - * try { - * const hook = await resumeHook(token, data); - * return Response.json({ runId: hook.runId }); - * } catch (error) { - * return new Response('Hook not found', { status: 404 }); - * } - * } - * ``` - */ -async function resumeHook(token, payload) { - return await waitedUntil(() => { - return trace('HOOK.resume', async (span) => { - const world = getWorld(); - try { - const hook = await getHookByToken(token); - span?.setAttributes({ - ...HookToken(token), - ...HookId(hook.hookId), - ...WorkflowRunId(hook.runId), - }); - // Dehydrate the payload for storage - const ops = []; - const dehydratedPayload = dehydrateStepReturnValue(payload, ops, globalThis); - functionsExports.waitUntil(Promise.all(ops)); - // Create a hook_received event with the payload - await world.events.create(hook.runId, { - eventType: 'hook_received', - correlationId: hook.hookId, - eventData: { - payload: dehydratedPayload, - }, - }); - const workflowRun = await world.runs.get(hook.runId); - span?.setAttributes({ - ...WorkflowName(workflowRun.workflowName), - }); - const traceCarrier = workflowRun.executionContext?.traceCarrier; - if (traceCarrier) { - const context = await getSpanContextForTraceCarrier(traceCarrier); - if (context) { - span?.addLink?.({ context }); - } - } - // Re-trigger the workflow against the deployment ID associated - // with the workflow run that the hook belongs to - await world.queue(`__wkf_workflow_${workflowRun.workflowName}`, { - runId: hook.runId, - // attach the trace carrier from the workflow run - traceCarrier: workflowRun.executionContext?.traceCarrier ?? undefined, - }, { - deploymentId: workflowRun.deploymentId, - }); - return hook; - } - catch (err) { - span?.setAttributes({ - ...HookToken(token), - ...HookFound(false), - }); - throw err; - } - }); - }); -} -/** - * Resumes a webhook by sending a {@link https://developer.mozilla.org/en-US/docs/Web/API/Request | Request} - * object to a hook identified by its token. - * - * This function is called externally (e.g., from an API route or server action) - * to send a request to a webhook and resume the associated workflow run. - * - * @param token - The unique token identifying the hook - * @param request - The request to send to the hook - * @returns Promise resolving to the response - * @throws Error if the hook is not found or if there's an error during the process - * - * @example - * - * ```ts - * // In an API route - * import { resumeWebhook } from '@workflow/core/runtime'; - * - * export async function POST(request: Request) { - * const url = new URL(request.url); - * const token = url.searchParams.get('token'); - * - * if (!token) { - * return new Response('Missing token', { status: 400 }); - * } - * - * try { - * const response = await resumeWebhook(token, request); - * return response; - * } catch (error) { - * return new Response('Webhook not found', { status: 404 }); - * } - * } - * ``` - */ -async function resumeWebhook(token, request) { - const hook = await getHookByToken(token); - let response; - let responseReadable; - if (hook.metadata && - typeof hook.metadata === 'object' && - 'respondWith' in hook.metadata) { - if (hook.metadata.respondWith === 'manual') { - const { readable, writable } = new TransformStream(); - responseReadable = readable; - // The request instance includes the writable stream which will be used - // to write the response to the client from within the workflow run - request[WEBHOOK_RESPONSE_WRITABLE] = writable; - } - else if (hook.metadata.respondWith instanceof Response) { - response = hook.metadata.respondWith; - } - else { - throw new WorkflowRuntimeError(`Invalid \`respondWith\` value: ${hook.metadata.respondWith}`, { slug: ERROR_SLUGS.WEBHOOK_INVALID_RESPOND_WITH_VALUE }); - } - } - else { - // No `respondWith` value implies the default behavior of returning a 202 - response = new Response(null, { status: 202 }); - } - await resumeHook(hook.token, request); - if (responseReadable) { - // Wait for the readable stream to emit one chunk, - // which is the `Response` object - const reader = responseReadable.getReader(); - const chunk = await reader.read(); - if (chunk.value) { - response = chunk.value; - } - reader.cancel(); - } - if (!response) { - throw new WorkflowRuntimeError('Workflow run did not send a response', { - slug: ERROR_SLUGS.WEBHOOK_RESPONSE_NOT_SENT, - }); - } - return response; -} - -export { resumeHook as a, getHookByToken as g, resumeWebhook as r }; diff --git a/workbench/astro/dist/server/chunks/runtime_CxdH0OC2.mjs b/workbench/astro/dist/server/chunks/runtime_CxdH0OC2.mjs deleted file mode 100644 index 07a56f19e..000000000 --- a/workbench/astro/dist/server/chunks/runtime_CxdH0OC2.mjs +++ /dev/null @@ -1,2039 +0,0 @@ -import { z as withResolvers, A as stepLogger, B as EventConsumerResult, e as WorkflowRuntimeError, F as FatalError, C as hydrateStepReturnValue, G as seedrandom, I as webhookLogger, J as parseDurationToDate, t as trace, K as WorkflowEventsCount, u as WorkflowRunStatus, f as WorkflowRunId, l as WorkflowName, L as getPort, M as monotonicFactory, N as EventsConsumer, O as WORKFLOW_USE_STEP, P as WORKFLOW_CREATE_HOOK, Q as WORKFLOW_SLEEP, g as getWorkflowRunStreamId, R as WORKFLOW_GET_STREAM_ID, E as ERROR_SLUGS, v as hydrateWorkflowArguments, p as WorkflowArgumentsCount, S as dehydrateWorkflowReturnValue, T as WorkflowResultType, U as BODY_INIT_SYMBOL, V as getWorldHandlers, X as WorkflowInvokePayloadSchema, Y as withTraceContext, Z as StepInvokePayloadSchema, c as getWorld, _ as getExternalRevivers, $ as hydrateWorkflowReturnValue, a0 as WorkflowRunCancelledError, y as WorkflowRunFailedError, x as WorkflowRunNotCompletedError, a1 as QueueName, o as WorkflowOperation, a2 as WorkflowTracePropagated, a3 as WorkflowStartedAt, a4 as buildWorkflowSuspensionMessage, a5 as dehydrateStepArguments, k as functionsExports, s as serializeTraceCarrier, a6 as WorkflowAPIError, a7 as WorkflowStepsCreated, a8 as WorkflowErrorMessage, a9 as WorkflowErrorName, aa as StepAttempt, ab as StepName, ac as getStepFunction, ad as StepTracePropagated, ae as StepMaxRetries, af as StepId, ag as runtimeLogger, ah as StepStatus, ai as StepRetryTimeoutSeconds, aj as StepSkipReason, ak as StepSkipped, h as hydrateStepArguments, al as StepArgumentsCount, j as dehydrateStepReturnValue, am as StepResultType, an as StepErrorMessage, ao as StepErrorName, ap as StepFatalError, aq as StepRetryExhausted, ar as RetryableError, as as StepRetryWillRetry } from './index_ePTMDSOu.mjs'; -import { decode } from '@jridgewell/sourcemap-codec'; -import { AsyncLocalStorage } from 'node:async_hooks'; -import { types } from 'node:util'; -import { createContext as createContext$1, runInContext } from 'node:vm'; -import * as nanoid from 'nanoid'; - -/** - * An error that is thrown when one or more operations (steps/hooks/etc.) are called but do - * not yet have corresponding entries in the event log. The workflow - * dispatcher will catch this error and push the operations - * onto the queue. - */ -class WorkflowSuspension extends Error { - steps; - globalThis; - stepCount; - hookCount; - waitCount; - constructor(steps, global) { - const stepCount = steps.filter((s) => s.type === 'step').length; - const hookCount = steps.filter((s) => s.type === 'hook').length; - const waitCount = steps.filter((s) => s.type === 'wait').length; - // Build description parts - const parts = []; - if (stepCount > 0) { - parts.push(`${stepCount} ${stepCount === 1 ? 'step' : 'steps'}`); - } - if (hookCount > 0) { - parts.push(`${hookCount} ${hookCount === 1 ? 'hook' : 'hooks'}`); - } - if (waitCount > 0) { - parts.push(`${waitCount} ${waitCount === 1 ? 'wait' : 'waits'}`); - } - // Determine verb (has/have) and action (run/created/received) - const totalCount = stepCount + hookCount + waitCount; - const hasOrHave = totalCount === 1 ? 'has' : 'have'; - let action; - if (stepCount > 0) { - action = 'run'; - } - else if (hookCount > 0) { - action = 'created'; - } - else if (waitCount > 0) { - action = 'created'; - } - else { - action = 'received'; - } - const description = parts.length > 0 - ? `${parts.join(' and ')} ${hasOrHave} not been ${action} yet` - : '0 steps have not been run yet'; // Default case for empty array - super(description); - this.name = 'WorkflowSuspension'; - this.steps = steps; - this.globalThis = global; - this.stepCount = stepCount; - this.hookCount = hookCount; - this.waitCount = waitCount; - } - static is(value) { - return value instanceof WorkflowSuspension; - } -} -function ENOTSUP() { - throw new Error('Not supported in workflow functions'); -} - -/** - * Parse a machine readable name. - * - * @see {@link ../../swc-plugin-workflow/transform/src/naming.rs} for the naming scheme. - */ -function parseName(tag, name) { - if (typeof name !== 'string') { - return null; - } - const [prefix, path, ...functionNameParts] = name.split('//'); - if (prefix !== tag || !path || functionNameParts.length === 0) { - return null; - } - return { - shortName: functionNameParts.at(-1) ?? '', - path, - functionName: functionNameParts.join('//'), - }; -} -/** - * Parse a workflow name into its components. - * - * @param name - The workflow name to parse. - * @returns An object with `shortName`, `path`, and `functionName` properties. - * When the name is invalid, returns `null`. - */ -function parseWorkflowName(name) { - return parseName('workflow', name); -} - -// Matches the scheme of a URL, eg "http://" -const schemeRegex = /^[\w+.-]+:\/\//; -/** - * Matches the parts of a URL: - * 1. Scheme, including ":", guaranteed. - * 2. User/password, including "@", optional. - * 3. Host, guaranteed. - * 4. Port, including ":", optional. - * 5. Path, including "/", optional. - * 6. Query, including "?", optional. - * 7. Hash, including "#", optional. - */ -const urlRegex = /^([\w+.-]+:)\/\/([^@/#?]*@)?([^:/#?]*)(:\d+)?(\/[^#?]*)?(\?[^#]*)?(#.*)?/; -/** - * File URLs are weird. They dont' need the regular `//` in the scheme, they may or may not start - * with a leading `/`, they can have a domain (but only if they don't start with a Windows drive). - * - * 1. Host, optional. - * 2. Path, which may include "/", guaranteed. - * 3. Query, including "?", optional. - * 4. Hash, including "#", optional. - */ -const fileRegex = /^file:(?:\/\/((?![a-z]:)[^/#?]*)?)?(\/?[^#?]*)(\?[^#]*)?(#.*)?/i; -function isAbsoluteUrl(input) { - return schemeRegex.test(input); -} -function isSchemeRelativeUrl(input) { - return input.startsWith('//'); -} -function isAbsolutePath(input) { - return input.startsWith('/'); -} -function isFileUrl(input) { - return input.startsWith('file:'); -} -function isRelative(input) { - return /^[.?#]/.test(input); -} -function parseAbsoluteUrl(input) { - const match = urlRegex.exec(input); - return makeUrl(match[1], match[2] || '', match[3], match[4] || '', match[5] || '/', match[6] || '', match[7] || ''); -} -function parseFileUrl(input) { - const match = fileRegex.exec(input); - const path = match[2]; - return makeUrl('file:', '', match[1] || '', '', isAbsolutePath(path) ? path : '/' + path, match[3] || '', match[4] || ''); -} -function makeUrl(scheme, user, host, port, path, query, hash) { - return { - scheme, - user, - host, - port, - path, - query, - hash, - type: 7 /* Absolute */, - }; -} -function parseUrl(input) { - if (isSchemeRelativeUrl(input)) { - const url = parseAbsoluteUrl('http:' + input); - url.scheme = ''; - url.type = 6 /* SchemeRelative */; - return url; - } - if (isAbsolutePath(input)) { - const url = parseAbsoluteUrl('http://foo.com' + input); - url.scheme = ''; - url.host = ''; - url.type = 5 /* AbsolutePath */; - return url; - } - if (isFileUrl(input)) - return parseFileUrl(input); - if (isAbsoluteUrl(input)) - return parseAbsoluteUrl(input); - const url = parseAbsoluteUrl('http://foo.com/' + input); - url.scheme = ''; - url.host = ''; - url.type = input - ? input.startsWith('?') - ? 3 /* Query */ - : input.startsWith('#') - ? 2 /* Hash */ - : 4 /* RelativePath */ - : 1 /* Empty */; - return url; -} -function stripPathFilename(path) { - // If a path ends with a parent directory "..", then it's a relative path with excess parent - // paths. It's not a file, so we can't strip it. - if (path.endsWith('/..')) - return path; - const index = path.lastIndexOf('/'); - return path.slice(0, index + 1); -} -function mergePaths(url, base) { - normalizePath(base, base.type); - // If the path is just a "/", then it was an empty path to begin with (remember, we're a relative - // path). - if (url.path === '/') { - url.path = base.path; - } - else { - // Resolution happens relative to the base path's directory, not the file. - url.path = stripPathFilename(base.path) + url.path; - } -} -/** - * The path can have empty directories "//", unneeded parents "foo/..", or current directory - * "foo/.". We need to normalize to a standard representation. - */ -function normalizePath(url, type) { - const rel = type <= 4 /* RelativePath */; - const pieces = url.path.split('/'); - // We need to preserve the first piece always, so that we output a leading slash. The item at - // pieces[0] is an empty string. - let pointer = 1; - // Positive is the number of real directories we've output, used for popping a parent directory. - // Eg, "foo/bar/.." will have a positive 2, and we can decrement to be left with just "foo". - let positive = 0; - // We need to keep a trailing slash if we encounter an empty directory (eg, splitting "foo/" will - // generate `["foo", ""]` pieces). And, if we pop a parent directory. But once we encounter a - // real directory, we won't need to append, unless the other conditions happen again. - let addTrailingSlash = false; - for (let i = 1; i < pieces.length; i++) { - const piece = pieces[i]; - // An empty directory, could be a trailing slash, or just a double "//" in the path. - if (!piece) { - addTrailingSlash = true; - continue; - } - // If we encounter a real directory, then we don't need to append anymore. - addTrailingSlash = false; - // A current directory, which we can always drop. - if (piece === '.') - continue; - // A parent directory, we need to see if there are any real directories we can pop. Else, we - // have an excess of parents, and we'll need to keep the "..". - if (piece === '..') { - if (positive) { - addTrailingSlash = true; - positive--; - pointer--; - } - else if (rel) { - // If we're in a relativePath, then we need to keep the excess parents. Else, in an absolute - // URL, protocol relative URL, or an absolute path, we don't need to keep excess. - pieces[pointer++] = piece; - } - continue; - } - // We've encountered a real directory. Move it to the next insertion pointer, which accounts for - // any popped or dropped directories. - pieces[pointer++] = piece; - positive++; - } - let path = ''; - for (let i = 1; i < pointer; i++) { - path += '/' + pieces[i]; - } - if (!path || (addTrailingSlash && !path.endsWith('/..'))) { - path += '/'; - } - url.path = path; -} -/** - * Attempts to resolve `input` URL/path relative to `base`. - */ -function resolve(input, base) { - if (!input && !base) - return ''; - const url = parseUrl(input); - let inputType = url.type; - if (base && inputType !== 7 /* Absolute */) { - const baseUrl = parseUrl(base); - const baseType = baseUrl.type; - switch (inputType) { - case 1 /* Empty */: - url.hash = baseUrl.hash; - // fall through - case 2 /* Hash */: - url.query = baseUrl.query; - // fall through - case 3 /* Query */: - case 4 /* RelativePath */: - mergePaths(url, baseUrl); - // fall through - case 5 /* AbsolutePath */: - // The host, user, and port are joined, you can't copy one without the others. - url.user = baseUrl.user; - url.host = baseUrl.host; - url.port = baseUrl.port; - // fall through - case 6 /* SchemeRelative */: - // The input doesn't have a schema at least, so we need to copy at least that over. - url.scheme = baseUrl.scheme; - } - if (baseType > inputType) - inputType = baseType; - } - normalizePath(url, inputType); - const queryHash = url.query + url.hash; - switch (inputType) { - // This is impossible, because of the empty checks at the start of the function. - // case UrlType.Empty: - case 2 /* Hash */: - case 3 /* Query */: - return queryHash; - case 4 /* RelativePath */: { - // The first char is always a "/", and we need it to be relative. - const path = url.path.slice(1); - if (!path) - return queryHash || '.'; - if (isRelative(base || input) && !isRelative(path)) { - // If base started with a leading ".", or there is no base and input started with a ".", - // then we need to ensure that the relative path starts with a ".". We don't know if - // relative starts with a "..", though, so check before prepending. - return './' + path + queryHash; - } - return path + queryHash; - } - case 5 /* AbsolutePath */: - return url.path + queryHash; - default: - return url.scheme + '//' + url.user + url.host + url.port + url.path + queryHash; - } -} - -// src/trace-mapping.ts - -// src/strip-filename.ts -function stripFilename(path) { - if (!path) return ""; - const index = path.lastIndexOf("/"); - return path.slice(0, index + 1); -} - -// src/resolve.ts -function resolver(mapUrl, sourceRoot) { - const from = stripFilename(mapUrl); - const prefix = sourceRoot ? sourceRoot + "/" : ""; - return (source) => resolve(prefix + (source || ""), from); -} - -// src/sourcemap-segment.ts -var COLUMN = 0; -var SOURCES_INDEX = 1; -var SOURCE_LINE = 2; -var SOURCE_COLUMN = 3; -var NAMES_INDEX = 4; - -// src/sort.ts -function maybeSort(mappings, owned) { - const unsortedIndex = nextUnsortedSegmentLine(mappings, 0); - if (unsortedIndex === mappings.length) return mappings; - if (!owned) mappings = mappings.slice(); - for (let i = unsortedIndex; i < mappings.length; i = nextUnsortedSegmentLine(mappings, i + 1)) { - mappings[i] = sortSegments(mappings[i], owned); - } - return mappings; -} -function nextUnsortedSegmentLine(mappings, start) { - for (let i = start; i < mappings.length; i++) { - if (!isSorted(mappings[i])) return i; - } - return mappings.length; -} -function isSorted(line) { - for (let j = 1; j < line.length; j++) { - if (line[j][COLUMN] < line[j - 1][COLUMN]) { - return false; - } - } - return true; -} -function sortSegments(line, owned) { - if (!owned) line = line.slice(); - return line.sort(sortComparator); -} -function sortComparator(a, b) { - return a[COLUMN] - b[COLUMN]; -} - -// src/binary-search.ts -var found = false; -function binarySearch(haystack, needle, low, high) { - while (low <= high) { - const mid = low + (high - low >> 1); - const cmp = haystack[mid][COLUMN] - needle; - if (cmp === 0) { - found = true; - return mid; - } - if (cmp < 0) { - low = mid + 1; - } else { - high = mid - 1; - } - } - found = false; - return low - 1; -} -function upperBound(haystack, needle, index) { - for (let i = index + 1; i < haystack.length; index = i++) { - if (haystack[i][COLUMN] !== needle) break; - } - return index; -} -function lowerBound(haystack, needle, index) { - for (let i = index - 1; i >= 0; index = i--) { - if (haystack[i][COLUMN] !== needle) break; - } - return index; -} -function memoizedState() { - return { - lastKey: -1, - lastNeedle: -1, - lastIndex: -1 - }; -} -function memoizedBinarySearch(haystack, needle, state, key) { - const { lastKey, lastNeedle, lastIndex } = state; - let low = 0; - let high = haystack.length - 1; - if (key === lastKey) { - if (needle === lastNeedle) { - found = lastIndex !== -1 && haystack[lastIndex][COLUMN] === needle; - return lastIndex; - } - if (needle >= lastNeedle) { - low = lastIndex === -1 ? 0 : lastIndex; - } else { - high = lastIndex; - } - } - state.lastKey = key; - state.lastNeedle = needle; - return state.lastIndex = binarySearch(haystack, needle, low, high); -} - -// src/types.ts -function parse(map) { - return typeof map === "string" ? JSON.parse(map) : map; -} - -// src/trace-mapping.ts -var LINE_GTR_ZERO = "`line` must be greater than 0 (lines start at line 1)"; -var COL_GTR_EQ_ZERO = "`column` must be greater than or equal to 0 (columns start at column 0)"; -var LEAST_UPPER_BOUND = -1; -var GREATEST_LOWER_BOUND = 1; -var TraceMap = class { - constructor(map, mapUrl) { - const isString = typeof map === "string"; - if (!isString && map._decodedMemo) return map; - const parsed = parse(map); - const { version, file, names, sourceRoot, sources, sourcesContent } = parsed; - this.version = version; - this.file = file; - this.names = names || []; - this.sourceRoot = sourceRoot; - this.sources = sources; - this.sourcesContent = sourcesContent; - this.ignoreList = parsed.ignoreList || parsed.x_google_ignoreList || void 0; - const resolve = resolver(mapUrl, sourceRoot); - this.resolvedSources = sources.map(resolve); - const { mappings } = parsed; - if (typeof mappings === "string") { - this._encoded = mappings; - this._decoded = void 0; - } else if (Array.isArray(mappings)) { - this._encoded = void 0; - this._decoded = maybeSort(mappings, isString); - } else if (parsed.sections) { - throw new Error(`TraceMap passed sectioned source map, please use FlattenMap export instead`); - } else { - throw new Error(`invalid source map: ${JSON.stringify(parsed)}`); - } - this._decodedMemo = memoizedState(); - this._bySources = void 0; - this._bySourceMemos = void 0; - } -}; -function cast(map) { - return map; -} -function decodedMappings(map) { - var _a; - return (_a = cast(map))._decoded || (_a._decoded = decode(cast(map)._encoded)); -} -function originalPositionFor(map, needle) { - let { line, column, bias } = needle; - line--; - if (line < 0) throw new Error(LINE_GTR_ZERO); - if (column < 0) throw new Error(COL_GTR_EQ_ZERO); - const decoded = decodedMappings(map); - if (line >= decoded.length) return OMapping(null, null, null, null); - const segments = decoded[line]; - const index = traceSegmentInternal( - segments, - cast(map)._decodedMemo, - line, - column, - bias || GREATEST_LOWER_BOUND - ); - if (index === -1) return OMapping(null, null, null, null); - const segment = segments[index]; - if (segment.length === 1) return OMapping(null, null, null, null); - const { names, resolvedSources } = map; - return OMapping( - resolvedSources[segment[SOURCES_INDEX]], - segment[SOURCE_LINE] + 1, - segment[SOURCE_COLUMN], - segment.length === 5 ? names[segment[NAMES_INDEX]] : null - ); -} -function OMapping(source, line, column, name) { - return { source, line, column, name }; -} -function traceSegmentInternal(segments, memo, line, column, bias) { - let index = memoizedBinarySearch(segments, column, memo, line); - if (found) { - index = (bias === LEAST_UPPER_BOUND ? upperBound : lowerBound)(segments, column, index); - } else if (bias === LEAST_UPPER_BOUND) index++; - if (index === -1 || index === segments.length) return -1; - return index; -} - -/** - * Remaps an error stack trace using inline source maps to show original source locations. - * - * @param stack - The error stack trace to remap - * @param filename - The workflow filename to match in stack frames - * @param workflowCode - The workflow bundle code containing inline source maps - * @returns The remapped stack trace with original source locations - */ -function remapErrorStack(stack, filename, workflowCode) { - // Extract inline source map from workflow code - const sourceMapMatch = workflowCode.match(/\/\/# sourceMappingURL=data:application\/json;base64,(.+)/); - if (!sourceMapMatch) { - return stack; // No source map found - } - try { - const base64 = sourceMapMatch[1]; - const sourceMapJson = Buffer.from(base64, 'base64').toString('utf-8'); - const sourceMapData = JSON.parse(sourceMapJson); - // Use TraceMap (pure JS, no WASM required) - const tracer = new TraceMap(sourceMapData); - // Parse and remap each line in the stack trace - const lines = stack.split('\n'); - const remappedLines = lines.map((line) => { - // Match stack frames: "at functionName (filename:line:column)" or "at filename:line:column" - const frameMatch = line.match(/^\s*at\s+(?:(.+?)\s+\()?(.+?):(\d+):(\d+)\)?$/); - if (!frameMatch) { - return line; // Not a stack frame, return as-is - } - const [, functionName, file, lineStr, colStr] = frameMatch; - // Only remap frames from our workflow file - if (!file.includes(filename)) { - return line; - } - const lineNumber = parseInt(lineStr, 10); - const columnNumber = parseInt(colStr, 10); - // Map to original source position - const original = originalPositionFor(tracer, { - line: lineNumber, - column: columnNumber, - }); - if (original.source && original.line !== null) { - const func = functionName || original.name || 'anonymous'; - const col = original.column !== null ? original.column : columnNumber; - return ` at ${func} (${original.source}:${original.line}:${col})`; - } - return line; // Couldn't map, return original - }); - return remappedLines.join('\n'); - } - catch (e) { - // If source map processing fails, return original stack - return stack; - } -} - -const contextStorage = /* @__PURE__ */ new AsyncLocalStorage(); - -function getErrorName(v) { - if (types.isNativeError(v)) { - return v.name; - } - return 'Error'; -} -function getErrorStack(v) { - if (types.isNativeError(v)) { - return v.stack ?? ''; - } - return ''; -} - -function createUseStep(ctx) { - return function useStep(stepName) { - return (...args) => { - const { promise, resolve, reject } = withResolvers(); - const correlationId = `step_${ctx.generateUlid()}`; - ctx.invocationsQueue.push({ - type: 'step', - correlationId, - stepName, - args, - }); - // Track whether we've already seen a "step_started" event for this step. - // This is important because after a retryable failure, the step moves back to - // "pending" status which causes another "step_started" event to be emitted. - let hasSeenStepStarted = false; - stepLogger.debug('Step consumer setup', { - correlationId, - stepName, - args, - }); - ctx.eventsConsumer.subscribe((event) => { - if (!event) { - // We've reached the end of the events, so this step has either not been run or is currently running. - // Crucially, if we got here, then this step Promise does - // not resolve so that the user workflow code does not proceed any further. - // Notify the workflow handler that this step has not been run / has not completed yet. - setTimeout(() => { - ctx.onWorkflowError(new WorkflowSuspension(ctx.invocationsQueue, ctx.globalThis)); - }, 0); - return EventConsumerResult.NotConsumed; - } - stepLogger.debug('Step consumer event processing', { - correlationId, - stepName, - args: args.join(', '), - incomingCorrelationId: event.correlationId, - isMatch: correlationId === event.correlationId, - eventType: event.eventType, - }); - if (event.correlationId !== correlationId) { - // We're not interested in this event - the correlationId belongs to a different step - return EventConsumerResult.NotConsumed; - } - if (event.eventType === 'step_started') { - // Step has started - so remove from the invocations queue (only on the first "step_started" event) - if (!hasSeenStepStarted) { - const invocationsQueueIndex = ctx.invocationsQueue.findIndex((invocation) => invocation.type === 'step' && - invocation.correlationId === correlationId); - if (invocationsQueueIndex !== -1) { - ctx.invocationsQueue.splice(invocationsQueueIndex, 1); - } - else { - setTimeout(() => { - reject(new WorkflowRuntimeError(`Corrupted event log: step ${correlationId} (${stepName}) started but not found in invocation queue`)); - }, 0); - return EventConsumerResult.Finished; - } - hasSeenStepStarted = true; - } - // If this is a subsequent "step_started" event (after a retry), we just consume it - // without trying to remove from the queue again or logging a warning - return EventConsumerResult.Consumed; - } - if (event.eventType === 'step_failed') { - // Step failed - bubble up to workflow - if (event.eventData.fatal) { - setTimeout(() => { - reject(new FatalError(event.eventData.error)); - }, 0); - return EventConsumerResult.Finished; - } - else { - // This is a retryable error, so nothing to do here, - // but we will consume the event - return EventConsumerResult.Consumed; - } - } - else if (event.eventType === 'step_completed') { - // Step has already completed, so resolve the Promise with the cached result - const hydratedResult = hydrateStepReturnValue(event.eventData.result, ctx.globalThis); - setTimeout(() => { - resolve(hydratedResult); - }, 0); - return EventConsumerResult.Finished; - } - else { - // An unexpected event type has been received, but it does belong to this step (matching `correlationId`) - setTimeout(() => { - reject(new WorkflowRuntimeError(`Unexpected event type: "${event.eventType}"`)); - }, 0); - return EventConsumerResult.Finished; - } - }); - return promise; - }; - }; -} - -/** - * Returns a function that generates a random UUID, based on the given RNG. - * - * `rng` is expected to be a seeded random number generator (i.e. `seedrandom.PRNG` instance). - * - * @param rng - A function that returns a random number between 0 and 1. - * @returns A `crypto.randomUUID`-like function. - */ -function createRandomUUID(rng) { - return function randomUUID() { - const chars = '0123456789abcdef'; - let uuid = ''; - for (let i = 0; i < 36; i++) { - if (i === 8 || i === 13 || i === 18 || i === 23) { - uuid += '-'; - } - else if (i === 14) { - uuid += '4'; // Version 4 UUID - } - else if (i === 19) { - uuid += chars[Math.floor(rng() * 4) + 8]; // 8, 9, a, or b - } - else { - uuid += chars[Math.floor(rng() * 16)]; - } - } - return uuid; - }; -} - -/** - * Creates a Node.js `vm.Context` configured to be usable for - * executing workflow logic in a deterministic environment. - * - * @param options - The options for the context. - * @returns The context. - */ -function createContext(options) { - let { fixedTimestamp } = options; - const { seed } = options; - const rng = seedrandom(seed); - const context = createContext$1(); - const g = runInContext('globalThis', context); - // Deterministic `Math.random()` - g.Math.random = rng; - // Override `Date` constructor to return fixed time when called without arguments - const Date_ = g.Date; - // biome-ignore lint/suspicious/noShadowRestrictedNames: We're shadowing the global `Date` property to make it deterministic. - g.Date = function Date(...args) { - if (args.length === 0) { - return new Date_(fixedTimestamp); - } - // @ts-expect-error - Args is `Date` constructor arguments - return new Date_(...args); - }; - g.Date.prototype = Date_.prototype; - // Preserve static methods - Object.setPrototypeOf(g.Date, Date_); - g.Date.now = () => fixedTimestamp; - // Deterministic `crypto` using Proxy to avoid mutating global objects - const originalCrypto = globalThis.crypto; - const originalSubtle = originalCrypto.subtle; - function getRandomValues(array) { - for (let i = 0; i < array.length; i++) { - array[i] = Math.floor(rng() * 256); - } - return array; - } - const randomUUID = createRandomUUID(rng); - const boundDigest = originalSubtle.digest.bind(originalSubtle); - g.crypto = new Proxy(originalCrypto, { - get(target, prop) { - if (prop === 'getRandomValues') { - return getRandomValues; - } - if (prop === 'randomUUID') { - return randomUUID; - } - if (prop === 'subtle') { - return new Proxy(originalSubtle, { - get(target, prop) { - if (prop === 'generateKey') { - return () => { - throw new Error('Not implemented'); - }; - } - else if (prop === 'digest') { - return boundDigest; - } - return target[prop]; - }, - }); - } - return target[prop]; - }, - }); - // Propagate environment variables - g.process = { - env: Object.freeze({ ...process.env }), - }; - // Stateless + synchronous Web APIs that are made available inside the sandbox - g.Headers = globalThis.Headers; - g.TextEncoder = globalThis.TextEncoder; - g.TextDecoder = globalThis.TextDecoder; - g.console = globalThis.console; - g.URL = globalThis.URL; - g.URLSearchParams = globalThis.URLSearchParams; - g.structuredClone = globalThis.structuredClone; - // HACK: Shim `exports` for the bundle - g.exports = {}; - g.module = { exports: g.exports }; - return { - context, - globalThis: g, - updateTimestamp: (timestamp) => { - fixedTimestamp = timestamp; - }, - }; -} - -const WORKFLOW_CONTEXT_SYMBOL = -/* @__PURE__ */ Symbol.for('WORKFLOW_CONTEXT'); - -function createCreateHook(ctx) { - return function createHookImpl(options = {}) { - // Generate hook ID and token - const correlationId = `hook_${ctx.generateUlid()}`; - const token = options.token ?? ctx.generateNanoid(); - // Add hook creation to invocations queue - ctx.invocationsQueue.push({ - type: 'hook', - correlationId, - token, - metadata: options.metadata, - }); - // Queue of hook events that have been received but not yet processed - const payloadsQueue = []; - // Queue of promises that resolve to the next hook payload - const promises = []; - let eventLogEmpty = false; - webhookLogger.debug('Hook consumer setup', { correlationId, token }); - ctx.eventsConsumer.subscribe((event) => { - // If there are no events and there are promises waiting, - // it means the hook has been awaited, but an incoming payload has not yet been received. - // In this case, the workflow should be suspended until the hook is resumed. - if (!event) { - eventLogEmpty = true; - if (promises.length > 0) { - setTimeout(() => { - ctx.onWorkflowError(new WorkflowSuspension(ctx.invocationsQueue, ctx.globalThis)); - }, 0); - return EventConsumerResult.Finished; - } - } - // Check for hook_created event to remove this hook from the queue if it was already created - if (event?.eventType === 'hook_created' && - event.correlationId === correlationId) { - // Remove this hook from the invocations queue if it exists - const index = ctx.invocationsQueue.findIndex((item) => item.type === 'hook' && item.correlationId === correlationId); - if (index !== -1) { - ctx.invocationsQueue.splice(index, 1); - } - return EventConsumerResult.Consumed; - } - if (event?.eventType === 'hook_received' && - event.correlationId === correlationId) { - if (promises.length > 0) { - const next = promises.shift(); - if (next) { - // Reconstruct the payload from the event data - const payload = hydrateStepReturnValue(event.eventData.payload, ctx.globalThis); - next.resolve(payload); - } - } - else { - payloadsQueue.push(event); - } - return EventConsumerResult.Consumed; - } - return EventConsumerResult.NotConsumed; - }); - // Helper function to create a new promise that waits for the next hook payload - function createHookPromise() { - const resolvers = withResolvers(); - if (payloadsQueue.length > 0) { - const nextPayload = payloadsQueue.shift(); - if (nextPayload) { - const payload = hydrateStepReturnValue(nextPayload.eventData.payload, ctx.globalThis); - resolvers.resolve(payload); - return resolvers.promise; - } - } - if (eventLogEmpty) { - // If the event log is already empty then we know the hook will not be resolved. - // Treat this case as a "step not run" scenario and suspend the workflow. - setTimeout(() => { - ctx.onWorkflowError(new WorkflowSuspension(ctx.invocationsQueue, ctx.globalThis)); - }, 0); - } - promises.push(resolvers); - return resolvers.promise; - } - const hook = { - token, - // biome-ignore lint/suspicious/noThenProperty: Intentionally thenable - then(onfulfilled, onrejected) { - return createHookPromise().then(onfulfilled, onrejected); - }, - // Support `for await (const payload of hook) { … }` syntax - async *[Symbol.asyncIterator]() { - while (true) { - yield await this; - } - }, - }; - return hook; - }; -} - -function createSleep(ctx) { - return async function sleepImpl(param) { - const { promise, resolve } = withResolvers(); - const correlationId = `wait_${ctx.generateUlid()}`; - // Calculate the resume time - const resumeAt = parseDurationToDate(param); - // Add wait to invocations queue - ctx.invocationsQueue.push({ - type: 'wait', - correlationId, - resumeAt, - }); - ctx.eventsConsumer.subscribe((event) => { - // If there are no events and we're waiting for wait_completed, - // suspend the workflow until the wait fires - if (!event) { - setTimeout(() => { - ctx.onWorkflowError(new WorkflowSuspension(ctx.invocationsQueue, ctx.globalThis)); - }, 0); - return EventConsumerResult.NotConsumed; - } - // Check for wait_created event to mark this wait as having the event created - if (event?.eventType === 'wait_created' && - event.correlationId === correlationId) { - // Mark this wait as having the created event, but keep it in the queue - const waitItem = ctx.invocationsQueue.find((item) => item.type === 'wait' && item.correlationId === correlationId); - if (waitItem) { - waitItem.hasCreatedEvent = true; - waitItem.resumeAt = event.eventData.resumeAt; - } - return EventConsumerResult.Consumed; - } - // Check for wait_completed event - if (event?.eventType === 'wait_completed' && - event.correlationId === correlationId) { - // Remove this wait from the invocations queue - const index = ctx.invocationsQueue.findIndex((item) => item.type === 'wait' && item.correlationId === correlationId); - if (index !== -1) { - ctx.invocationsQueue.splice(index, 1); - } - // Wait has elapsed, resolve the sleep - setTimeout(() => { - resolve(); - }, 0); - return EventConsumerResult.Finished; - } - return EventConsumerResult.NotConsumed; - }); - return promise; - }; -} - -async function runWorkflow(workflowCode, workflowRun, events) { - return trace(`WORKFLOW.run ${workflowRun.workflowName}`, async (span) => { - span?.setAttributes({ - ...WorkflowName(workflowRun.workflowName), - ...WorkflowRunId(workflowRun.runId), - ...WorkflowRunStatus(workflowRun.status), - ...WorkflowEventsCount(events.length), - }); - const startedAt = workflowRun.startedAt; - if (!startedAt) { - throw new Error(`Workflow run "${workflowRun.runId}" has no "startedAt" timestamp (should not happen)`); - } - // Get the port before creating VM context to avoid async operations - // affecting the deterministic timestamp - const port = await getPort(); - const { context, globalThis: vmGlobalThis, updateTimestamp, } = createContext({ - seed: workflowRun.runId, - fixedTimestamp: +startedAt, - }); - const workflowDiscontinuation = withResolvers(); - const ulid = monotonicFactory(() => vmGlobalThis.Math.random()); - const generateNanoid = nanoid.customRandom(nanoid.urlAlphabet, 21, (size) => new Uint8Array(size).map(() => 256 * vmGlobalThis.Math.random())); - const workflowContext = { - globalThis: vmGlobalThis, - onWorkflowError: workflowDiscontinuation.reject, - eventsConsumer: new EventsConsumer(events), - generateUlid: () => ulid(+startedAt), - generateNanoid, - invocationsQueue: [], - }; - // Subscribe to the events log to update the timestamp in the vm context - workflowContext.eventsConsumer.subscribe((event) => { - const createdAt = event?.createdAt; - if (createdAt) { - updateTimestamp(+createdAt); - } - // Never consume events - this is only a passive subscriber - return EventConsumerResult.NotConsumed; - }); - const useStep = createUseStep(workflowContext); - const createHook = createCreateHook(workflowContext); - const sleep = createSleep(workflowContext); - // @ts-expect-error - `@types/node` says symbol is not valid, but it does work - vmGlobalThis[WORKFLOW_USE_STEP] = useStep; - // @ts-expect-error - `@types/node` says symbol is not valid, but it does work - vmGlobalThis[WORKFLOW_CREATE_HOOK] = createHook; - // @ts-expect-error - `@types/node` says symbol is not valid, but it does work - vmGlobalThis[WORKFLOW_SLEEP] = sleep; - // @ts-expect-error - `@types/node` says symbol is not valid, but it does work - vmGlobalThis[WORKFLOW_GET_STREAM_ID] = (namespace) => getWorkflowRunStreamId(workflowRun.runId, namespace); - // TODO: there should be a getUrl method on the world interface itself. This - // solution only works for vercel + embedded worlds. - const url = process.env.VERCEL_URL - ? `https://${process.env.VERCEL_URL}` - : `http://localhost:${port ?? 3000}`; - // For the workflow VM, we store the context in a symbol on the `globalThis` object - const ctx = { - workflowRunId: workflowRun.runId, - workflowStartedAt: new vmGlobalThis.Date(+startedAt), - url, - }; - // @ts-expect-error - `@types/node` says symbol is not valid, but it does work - vmGlobalThis[WORKFLOW_CONTEXT_SYMBOL] = ctx; - // NOTE: Will have a config override to use the custom fetch step. - // For now `fetch` must be explicitly imported from `workflow`. - vmGlobalThis.fetch = () => { - throw new vmGlobalThis.Error(`Global "fetch" is unavailable in workflow functions. Use the "fetch" step function from "workflow" to make HTTP requests.\n\nLearn more: https://useworkflow.dev/err/${ERROR_SLUGS.FETCH_IN_WORKFLOW_FUNCTION}`); - }; - // `Request` and `Response` are special built-in classes that invoke steps - // for the `json()`, `text()` and `arrayBuffer()` instance methods - class Request { - cache; - credentials; - destination; - headers; - integrity; - method; - mode; - redirect; - referrer; - referrerPolicy; - url; - keepalive; - signal; - duplex; - body; - constructor(input, init) { - // Handle URL input - if (typeof input === 'string' || input instanceof vmGlobalThis.URL) { - const urlString = String(input); - // Validate URL format - try { - new vmGlobalThis.URL(urlString); - this.url = urlString; - } - catch (cause) { - throw new TypeError(`Failed to parse URL from ${urlString}`, { - cause, - }); - } - } - else { - // Input is a Request object - clone its properties - this.url = input.url; - if (!init) { - this.method = input.method; - this.headers = new vmGlobalThis.Headers(input.headers); - this.body = input.body; - this.mode = input.mode; - this.credentials = input.credentials; - this.cache = input.cache; - this.redirect = input.redirect; - this.referrer = input.referrer; - this.referrerPolicy = input.referrerPolicy; - this.integrity = input.integrity; - this.keepalive = input.keepalive; - this.signal = input.signal; - this.duplex = input.duplex; - this.destination = input.destination; - return; - } - // If init is provided, merge: use source properties, then override with init - // Copy all properties from the source Request first - this.method = input.method; - this.headers = new vmGlobalThis.Headers(input.headers); - this.body = input.body; - this.mode = input.mode; - this.credentials = input.credentials; - this.cache = input.cache; - this.redirect = input.redirect; - this.referrer = input.referrer; - this.referrerPolicy = input.referrerPolicy; - this.integrity = input.integrity; - this.keepalive = input.keepalive; - this.signal = input.signal; - this.duplex = input.duplex; - this.destination = input.destination; - } - // Override with init options if provided - // Set method - if (init?.method) { - this.method = init.method.toUpperCase(); - } - else if (typeof this.method !== 'string') { - // Fallback to default for string input case - this.method = 'GET'; - } - // Set headers - if (init?.headers) { - this.headers = new vmGlobalThis.Headers(init.headers); - } - else if (typeof input === 'string' || - input instanceof vmGlobalThis.URL) { - // For string/URL input, create empty headers - this.headers = new vmGlobalThis.Headers(); - } - // Set other properties with init values or defaults - if (init?.mode !== undefined) { - this.mode = init.mode; - } - else if (typeof this.mode !== 'string') { - this.mode = 'cors'; - } - if (init?.credentials !== undefined) { - this.credentials = init.credentials; - } - else if (typeof this.credentials !== 'string') { - this.credentials = 'same-origin'; - } - // `any` cast here because @types/node v22 does not yet have `cache` - if (init?.cache !== undefined) { - this.cache = init.cache; - } - else if (typeof this.cache !== 'string') { - this.cache = 'default'; - } - if (init?.redirect !== undefined) { - this.redirect = init.redirect; - } - else if (typeof this.redirect !== 'string') { - this.redirect = 'follow'; - } - if (init?.referrer !== undefined) { - this.referrer = init.referrer; - } - else if (typeof this.referrer !== 'string') { - this.referrer = 'about:client'; - } - if (init?.referrerPolicy !== undefined) { - this.referrerPolicy = init.referrerPolicy; - } - else if (typeof this.referrerPolicy !== 'string') { - this.referrerPolicy = ''; - } - if (init?.integrity !== undefined) { - this.integrity = init.integrity; - } - else if (typeof this.integrity !== 'string') { - this.integrity = ''; - } - if (init?.keepalive !== undefined) { - this.keepalive = init.keepalive; - } - else if (typeof this.keepalive !== 'boolean') { - this.keepalive = false; - } - if (init?.signal !== undefined) { - // @ts-expect-error - AbortSignal stub - this.signal = init.signal; - } - else if (!this.signal) { - // @ts-expect-error - AbortSignal stub - this.signal = { aborted: false }; - } - if (!this.duplex) { - this.duplex = 'half'; - } - if (!this.destination) { - this.destination = 'document'; - } - const body = init?.body; - // Validate that GET/HEAD methods don't have a body - if (body !== null && - body !== undefined && - (this.method === 'GET' || this.method === 'HEAD')) { - throw new TypeError(`Request with GET/HEAD method cannot have body.`); - } - // Store the original BodyInit for serialization - if (body !== null && body !== undefined) { - // Create a "fake" ReadableStream that stores the original body - // This avoids doing async work during workflow replay - this.body = Object.create(vmGlobalThis.ReadableStream.prototype, { - [BODY_INIT_SYMBOL]: { - value: body, - writable: false, - }, - }); - } - else { - this.body = null; - } - } - clone() { - ENOTSUP(); - } - get bodyUsed() { - return false; - } - // TODO: implement these - blob; - formData; - async arrayBuffer() { - return resArrayBuffer(this); - } - async bytes() { - return new Uint8Array(await resArrayBuffer(this)); - } - async json() { - return resJson(this); - } - async text() { - return resText(this); - } - } - vmGlobalThis.Request = Request; - const resJson = useStep('__builtin_response_json'); - const resText = useStep('__builtin_response_text'); - const resArrayBuffer = useStep('__builtin_response_array_buffer'); - class Response { - type; - url; - status; - statusText; - body; - headers; - redirected; - constructor(body, init) { - this.status = init?.status ?? 200; - this.statusText = init?.statusText ?? ''; - this.headers = new vmGlobalThis.Headers(init?.headers); - this.type = 'default'; - this.url = ''; - this.redirected = false; - // Validate that null-body status codes don't have a body - // Per HTTP spec: 204 (No Content), 205 (Reset Content), and 304 (Not Modified) - if (body !== null && - body !== undefined && - (this.status === 204 || this.status === 205 || this.status === 304)) { - throw new TypeError(`Response constructor: Invalid response status code ${this.status}`); - } - // Store the original BodyInit for serialization - if (body !== null && body !== undefined) { - // Create a "fake" ReadableStream that stores the original body - // This avoids doing async work during workflow replay - this.body = Object.create(vmGlobalThis.ReadableStream.prototype, { - [BODY_INIT_SYMBOL]: { - value: body, - writable: false, - }, - }); - } - else { - this.body = null; - } - } - // TODO: implement these - clone; - blob; - formData; - get ok() { - return this.status >= 200 && this.status < 300; - } - get bodyUsed() { - return false; - } - async arrayBuffer() { - return resArrayBuffer(this); - } - async bytes() { - return new Uint8Array(await resArrayBuffer(this)); - } - async json() { - return resJson(this); - } - static json(data, init) { - const body = JSON.stringify(data); - const headers = new vmGlobalThis.Headers(init?.headers); - if (!headers.has('content-type')) { - headers.set('content-type', 'application/json'); - } - return new Response(body, { ...init, headers }); - } - async text() { - return resText(this); - } - static error() { - ENOTSUP(); - } - static redirect(url, status = 302) { - // Validate status code - only specific redirect codes are allowed - if (![301, 302, 303, 307, 308].includes(status)) { - throw new RangeError(`Invalid redirect status code: ${status}. Must be one of: 301, 302, 303, 307, 308`); - } - // Create response with Location header - const headers = new vmGlobalThis.Headers(); - headers.set('Location', String(url)); - const response = Object.create(Response.prototype); - response.status = status; - response.statusText = ''; - response.headers = headers; - response.body = null; - response.type = 'default'; - response.url = ''; - response.redirected = false; - return response; - } - } - vmGlobalThis.Response = Response; - class ReadableStream { - constructor() { - ENOTSUP(); - } - get locked() { - return false; - } - cancel() { - ENOTSUP(); - } - getReader() { - ENOTSUP(); - } - pipeThrough() { - ENOTSUP(); - } - pipeTo() { - ENOTSUP(); - } - tee() { - ENOTSUP(); - } - values() { - ENOTSUP(); - } - static from() { - ENOTSUP(); - } - [Symbol.asyncIterator]() { - ENOTSUP(); - } - } - vmGlobalThis.ReadableStream = ReadableStream; - class WritableStream { - constructor() { - ENOTSUP(); - } - get locked() { - return false; - } - abort() { - ENOTSUP(); - } - close() { - ENOTSUP(); - } - getWriter() { - ENOTSUP(); - } - } - vmGlobalThis.WritableStream = WritableStream; - class TransformStream { - readable; - writable; - constructor() { - ENOTSUP(); - } - } - vmGlobalThis.TransformStream = TransformStream; - // Eventually we'll probably want to provide our own `console` object, - // but for now we'll just expose the global one. - vmGlobalThis.console = globalThis.console; - // HACK: propagate symbol needed for AI gateway usage - const SYMBOL_FOR_REQ_CONTEXT = Symbol.for('@vercel/request-context'); - // @ts-expect-error - `@types/node` says symbol is not valid, but it does work - vmGlobalThis[SYMBOL_FOR_REQ_CONTEXT] = globalThis[SYMBOL_FOR_REQ_CONTEXT]; - // Get a reference to the user-defined workflow function. - // The filename parameter ensures stack traces show a meaningful name - // (e.g., "example/workflows/99_e2e.ts") instead of "evalmachine.". - const parsedName = parseWorkflowName(workflowRun.workflowName); - const filename = parsedName?.path || workflowRun.workflowName; - const workflowFn = runInContext(`${workflowCode}; globalThis.__private_workflows?.get(${JSON.stringify(workflowRun.workflowName)})`, context, { filename }); - if (typeof workflowFn !== 'function') { - throw new ReferenceError(`Workflow ${JSON.stringify(workflowRun.workflowName)} must be a function, but got "${typeof workflowFn}" instead`); - } - const args = hydrateWorkflowArguments(workflowRun.input, vmGlobalThis); - span?.setAttributes({ - ...WorkflowArgumentsCount(args.length), - }); - // Invoke user workflow - const result = await Promise.race([ - workflowFn(...args), - workflowDiscontinuation.promise, - ]); - const dehydrated = dehydrateWorkflowReturnValue(result, vmGlobalThis); - span?.setAttributes({ - ...WorkflowResultType(typeof result), - }); - return dehydrated; - }); -} - -/** - * A handler class for a workflow run. - */ -class Run { - /** - * The ID of the workflow run. - */ - runId; - /** - * The world object. - * @internal - */ - world; - constructor(runId) { - this.runId = runId; - this.world = getWorld(); - } - /** - * Cancels the workflow run. - */ - async cancel() { - await this.world.runs.cancel(this.runId); - } - /** - * The status of the workflow run. - */ - get status() { - return this.world.runs.get(this.runId).then((run) => run.status); - } - /** - * The return value of the workflow run. - * Polls the workflow return value until it is completed. - */ - get returnValue() { - return this.pollReturnValue(); - } - /** - * The name of the workflow. - */ - get workflowName() { - return this.world.runs.get(this.runId).then((run) => run.workflowName); - } - /** - * The timestamp when the workflow run was created. - */ - get createdAt() { - return this.world.runs.get(this.runId).then((run) => run.createdAt); - } - /** - * The timestamp when the workflow run started execution. - * Returns undefined if the workflow has not started yet. - */ - get startedAt() { - return this.world.runs.get(this.runId).then((run) => run.startedAt); - } - /** - * The timestamp when the workflow run completed. - * Returns undefined if the workflow has not completed yet. - */ - get completedAt() { - return this.world.runs.get(this.runId).then((run) => run.completedAt); - } - /** - * The readable stream of the workflow run. - */ - get readable() { - return this.getReadable(); - } - /** - * Retrieves the workflow run's default readable stream, which reads chunks - * written to the corresponding writable stream {@link getWritable}. - * - * @param options - The options for the readable stream. - * @returns The `ReadableStream` for the workflow run. - */ - getReadable(options = {}) { - const { ops = [], global = globalThis, startIndex, namespace } = options; - const name = getWorkflowRunStreamId(this.runId, namespace); - return getExternalRevivers(global, ops).ReadableStream({ - name, - startIndex, - }); - } - /** - * Polls the workflow return value every 1 second until it is completed. - * @internal - * @returns The workflow return value. - */ - async pollReturnValue() { - while (true) { - try { - const run = await this.world.runs.get(this.runId); - if (run.status === 'completed') { - return hydrateWorkflowReturnValue(run.output, [], globalThis); - } - if (run.status === 'cancelled') { - throw new WorkflowRunCancelledError(this.runId); - } - if (run.status === 'failed') { - throw new WorkflowRunFailedError(this.runId, run.error); - } - throw new WorkflowRunNotCompletedError(this.runId, run.status); - } - catch (error) { - if (WorkflowRunNotCompletedError.is(error)) { - await new Promise((resolve) => setTimeout(resolve, 1_000)); - continue; - } - throw error; - } - } - } -} -/** - * Retrieves a `Run` object for a given run ID. - * - * @param runId - The workflow run ID obtained from {@link start}. - * @returns A `Run` object. - * @throws WorkflowRunNotFoundError if the run ID is not found. - */ -function getRun(runId) { - return new Run(runId); -} -/** - * Loads all workflow run events by iterating through all pages of paginated results. - * This ensures that *all* events are loaded into memory before running the workflow. - * Events must be in chronological order (ascending) for proper workflow replay. - */ -async function getAllWorkflowRunEvents(runId) { - const allEvents = []; - let cursor = null; - let hasMore = true; - const world = getWorld(); - while (hasMore) { - const response = await world.events.list({ - runId, - pagination: { - sortOrder: 'asc', // Required: events must be in chronological order for replay - cursor: cursor ?? undefined, - }, - }); - allEvents.push(...response.data); - hasMore = response.hasMore; - cursor = response.cursor; - } - return allEvents; -} -/** - * Function that creates a single route which handles any workflow execution - * request and routes to the appropriate workflow function. - * - * @param workflowCode - The workflow bundle code containing all the workflow - * functions at the top level. - * @returns A function that can be used as a Vercel API route. - */ -function workflowEntrypoint(workflowCode) { - return getWorldHandlers().createQueueHandler('__wkf_workflow_', async (message_, metadata) => { - const { runId, traceCarrier: traceContext } = WorkflowInvokePayloadSchema.parse(message_); - // Extract the workflow name from the topic name - const workflowName = metadata.queueName.slice('__wkf_workflow_'.length); - // Invoke user workflow within the propagated trace context - return await withTraceContext(traceContext, async () => { - const world = getWorld(); - return trace(`WORKFLOW ${workflowName}`, async (span) => { - span?.setAttributes({ - ...WorkflowName(workflowName), - ...WorkflowOperation('execute'), - ...QueueName(metadata.queueName), - }); - // TODO: validate `workflowName` exists before consuming message? - span?.setAttributes({ - ...WorkflowRunId(runId), - ...WorkflowTracePropagated(!!traceContext), - }); - let workflowStartedAt = -1; - try { - let workflowRun = await world.runs.get(runId); - if (workflowRun.status === 'pending') { - workflowRun = await world.runs.update(runId, { - // This sets the `startedAt` timestamp at the database level - status: 'running', - }); - } - // At this point, the workflow is "running" and `startedAt` should - // definitely be set. - if (!workflowRun.startedAt) { - throw new Error(`Workflow run "${runId}" has no "startedAt" timestamp`); - } - workflowStartedAt = +workflowRun.startedAt; - span?.setAttributes({ - ...WorkflowRunStatus(workflowRun.status), - ...WorkflowStartedAt(workflowStartedAt), - }); - if (workflowRun.status !== 'running') { - // Workflow has already completed or failed, so we can skip it - console.warn(`Workflow "${runId}" has status "${workflowRun.status}", skipping`); - // TODO: for `cancel`, we actually want to propagate a WorkflowCancelled event - // inside the workflow context so the user can gracefully exit. this is SIGTERM - // TODO: furthermore, there should be a timeout or a way to force cancel SIGKILL - // so that we actually exit here without replaying the workflow at all, in the case - // the replaying the workflow is itself failing. - return; - } - // Load all events into memory before running - const events = await getAllWorkflowRunEvents(workflowRun.runId); - // Check for any elapsed waits and create wait_completed events - const now = Date.now(); - for (const event of events) { - if (event.eventType === 'wait_created') { - const resumeAt = event.eventData.resumeAt; - const hasCompleted = events.some((e) => e.eventType === 'wait_completed' && - e.correlationId === event.correlationId); - // If wait has elapsed and hasn't been completed yet - if (!hasCompleted && now >= resumeAt.getTime()) { - const completedEvent = await world.events.create(runId, { - eventType: 'wait_completed', - correlationId: event.correlationId, - }); - // Add the event to the events array so the workflow can see it - events.push(completedEvent); - } - } - } - const result = await runWorkflow(workflowCode, workflowRun, events); - // Update the workflow run with the result - await world.runs.update(runId, { - status: 'completed', - output: result, - }); - span?.setAttributes({ - ...WorkflowRunStatus('completed'), - ...WorkflowEventsCount(events.length), - }); - } - catch (err) { - if (WorkflowSuspension.is(err)) { - buildWorkflowSuspensionMessage(runId, err.stepCount, err.hookCount, err.waitCount); - // Process each operation in the queue (steps and hooks) - let minTimeoutSeconds = null; - for (const queueItem of err.steps) { - if (queueItem.type === 'step') { - // Handle step operations - const ops = []; - const dehydratedArgs = dehydrateStepArguments(queueItem.args, err.globalThis); - try { - const step = await world.steps.create(runId, { - stepId: queueItem.correlationId, - stepName: queueItem.stepName, - input: dehydratedArgs, - }); - functionsExports.waitUntil(Promise.all(ops)); - await world.queue(`__wkf_step_${queueItem.stepName}`, { - workflowName, - workflowRunId: runId, - workflowStartedAt, - stepId: step.stepId, - traceCarrier: await serializeTraceCarrier(), - }, { - idempotencyKey: queueItem.correlationId, - }); - } - catch (err) { - if (WorkflowAPIError.is(err) && err.status === 409) { - // Step already exists, so we can skip it - console.warn(`Step "${queueItem.stepName}" with correlation ID "${queueItem.correlationId}" already exists, skipping: ${err.message}`); - continue; - } - throw err; - } - } - else if (queueItem.type === 'hook') { - // Handle hook operations - try { - // Create hook in database - const hookMetadata = typeof queueItem.metadata === 'undefined' - ? undefined - : dehydrateStepArguments(queueItem.metadata, err.globalThis); - await world.hooks.create(runId, { - hookId: queueItem.correlationId, - token: queueItem.token, - metadata: hookMetadata, - }); - // Create hook_created event in event log - await world.events.create(runId, { - eventType: 'hook_created', - correlationId: queueItem.correlationId, - }); - } - catch (err) { - if (WorkflowAPIError.is(err)) { - if (err.status === 409) { - // Hook already exists (duplicate hook_id constraint), so we can skip it - console.warn(`Hook with correlation ID "${queueItem.correlationId}" already exists, skipping: ${err.message}`); - continue; - } - else if (err.status === 410) { - // Workflow has already completed, so no-op - console.warn(`Workflow run "${runId}" has already completed, skipping hook "${queueItem.correlationId}": ${err.message}`); - continue; - } - } - throw err; - } - } - else if (queueItem.type === 'wait') { - // Handle wait operations - try { - // Only create wait_created event if it hasn't been created yet - if (!queueItem.hasCreatedEvent) { - await world.events.create(runId, { - eventType: 'wait_created', - correlationId: queueItem.correlationId, - eventData: { - resumeAt: queueItem.resumeAt, - }, - }); - } - // Calculate how long to wait before resuming - const now = Date.now(); - const resumeAtMs = queueItem.resumeAt.getTime(); - const delayMs = Math.max(1000, resumeAtMs - now); - const timeoutSeconds = Math.ceil(delayMs / 1000); - // Track the minimum timeout across all waits - if (minTimeoutSeconds === null || - timeoutSeconds < minTimeoutSeconds) { - minTimeoutSeconds = timeoutSeconds; - } - } - catch (err) { - if (WorkflowAPIError.is(err) && err.status === 409) { - // Wait already exists, so we can skip it - console.warn(`Wait with correlation ID "${queueItem.correlationId}" already exists, skipping: ${err.message}`); - continue; - } - throw err; - } - } - } - span?.setAttributes({ - ...WorkflowRunStatus('pending_steps'), - ...WorkflowStepsCreated(err.steps.length), - }); - // If we encountered any waits, return the minimum timeout - if (minTimeoutSeconds !== null) { - return { timeoutSeconds: minTimeoutSeconds }; - } - } - else { - const errorName = getErrorName(err); - const errorMessage = err instanceof Error ? err.message : String(err); - let errorStack = getErrorStack(err); - // Remap error stack using source maps to show original source locations - if (errorStack) { - const parsedName = parseWorkflowName(workflowName); - const filename = parsedName?.path || workflowName; - errorStack = remapErrorStack(errorStack, filename, workflowCode); - } - console.error(`${errorName} while running "${runId}" workflow:\n\n${errorStack}`); - await world.runs.update(runId, { - status: 'failed', - error: { - message: errorMessage, - stack: errorStack, - // TODO: include error codes when we define them - }, - }); - span?.setAttributes({ - ...WorkflowRunStatus('failed'), - ...WorkflowErrorName(errorName), - ...WorkflowErrorMessage(String(err)), - }); - } - } - }); // End withTraceContext - }); - }); -} -/** - * A single route that handles any step execution request and routes to the - * appropriate step function. We may eventually want to create different bundles - * for each step, this is temporary. - */ -const stepEntrypoint = -/* @__PURE__ */ getWorldHandlers().createQueueHandler('__wkf_step_', async (message_, metadata) => { - const { workflowName, workflowRunId, workflowStartedAt, stepId, traceCarrier: traceContext, } = StepInvokePayloadSchema.parse(message_); - // Execute step within the propagated trace context - return await withTraceContext(traceContext, async () => { - // Extract the step name from the topic name - const stepName = metadata.queueName.slice('__wkf_step_'.length); - const world = getWorld(); - // Get the port early to avoid async operations during step execution - const port = await getPort(); - return trace(`STEP ${stepName}`, async (span) => { - span?.setAttributes({ - ...StepName(stepName), - ...StepAttempt(metadata.attempt), - ...QueueName(metadata.queueName), - }); - const stepFn = getStepFunction(stepName); - if (!stepFn) { - throw new Error(`Step "${stepName}" not found`); - } - if (typeof stepFn !== 'function') { - throw new Error(`Step "${stepName}" is not a function (got ${typeof stepFn})`); - } - span?.setAttributes({ - ...WorkflowName(workflowName), - ...WorkflowRunId(workflowRunId), - ...StepId(stepId), - ...StepMaxRetries(stepFn.maxRetries ?? 3), - ...StepTracePropagated(!!traceContext), - }); - let step = await world.steps.get(workflowRunId, stepId); - runtimeLogger.debug('Step execution details', { - stepName, - stepId: step.stepId, - status: step.status, - attempt: step.attempt, - }); - span?.setAttributes({ - ...StepStatus(step.status), - }); - // Check if the step has a `retryAfter` timestamp that hasn't been reached yet - const now = Date.now(); - if (step.retryAfter && step.retryAfter.getTime() > now) { - const timeoutSeconds = Math.ceil((step.retryAfter.getTime() - now) / 1000); - span?.setAttributes({ - ...StepRetryTimeoutSeconds(timeoutSeconds), - }); - runtimeLogger.debug('Step retryAfter timestamp not yet reached', { - stepName, - stepId: step.stepId, - retryAfter: step.retryAfter, - timeoutSeconds, - }); - return { timeoutSeconds }; - } - let result; - const attempt = step.attempt + 1; - try { - if (step.status !== 'pending') { - // We should only be running the step if it's pending - // (initial state, or state set on re-try), so the step has been - // invoked erroneously. - console.error(`[Workflows] "${workflowRunId}" - Step invoked erroneously, expected status "pending", got "${step.status}" instead, skipping execution`); - span?.setAttributes({ - ...StepSkipped(true), - ...StepSkipReason(step.status), - }); - return; - } - await world.events.create(workflowRunId, { - eventType: 'step_started', // TODO: Replace with 'step_retrying' - correlationId: stepId, - }); - step = await world.steps.update(workflowRunId, stepId, { - attempt, - status: 'running', - }); - if (!step.startedAt) { - throw new WorkflowRuntimeError(`Step "${stepId}" has no "startedAt" timestamp`); - } - // Hydrate the step input arguments - const ops = []; - const args = hydrateStepArguments(step.input, ops); - span?.setAttributes({ - ...StepArgumentsCount(args.length), - }); - result = await contextStorage.run({ - stepMetadata: { - stepId, - stepStartedAt: new Date(+step.startedAt), - attempt, - }, - workflowMetadata: { - workflowRunId, - workflowStartedAt: new Date(+workflowStartedAt), - // TODO: there should be a getUrl method on the world interface itself. This - // solution only works for vercel + local worlds. - url: process.env.VERCEL_URL - ? `https://${process.env.VERCEL_URL}` - : `http://localhost:${port ?? 3000}`, - }, - ops, - }, () => stepFn(...args)); - result = dehydrateStepReturnValue(result, ops); - functionsExports.waitUntil(Promise.all(ops)); - // Update the event log with the step result - await world.events.create(workflowRunId, { - eventType: 'step_completed', - correlationId: stepId, - eventData: { - result: result, - }, - }); - await world.steps.update(workflowRunId, stepId, { - status: 'completed', - output: result, - }); - span?.setAttributes({ - ...StepStatus('completed'), - ...StepResultType(typeof result), - }); - } - catch (err) { - span?.setAttributes({ - ...StepErrorName(getErrorName(err)), - ...StepErrorMessage(String(err)), - }); - if (WorkflowAPIError.is(err)) { - if (err.status === 410) { - // Workflow has already completed, so no-op - console.warn(`Workflow run "${workflowRunId}" has already completed, skipping step "${stepId}": ${err.message}`); - return; - } - } - if (FatalError.is(err)) { - const errorStack = getErrorStack(err); - const stackLines = errorStack.split('\n').slice(0, 4); - console.error(`[Workflows] "${workflowRunId}" - Encountered \`FatalError\` while executing step "${stepName}":\n > ${stackLines.join('\n > ')}\n\nBubbling up error to parent workflow`); - // Fatal error - store the error in the event log and re-invoke the workflow - await world.events.create(workflowRunId, { - eventType: 'step_failed', - correlationId: stepId, - eventData: { - error: String(err), - stack: errorStack, - fatal: true, - }, - }); - await world.steps.update(workflowRunId, stepId, { - status: 'failed', - error: { - message: err.message || String(err), - stack: errorStack, - // TODO: include error codes when we define them - }, - }); - span?.setAttributes({ - ...StepStatus('failed'), - ...StepFatalError(true), - }); - } - else { - const maxRetries = stepFn.maxRetries ?? 3; - span?.setAttributes({ - ...StepAttempt(attempt), - ...StepMaxRetries(maxRetries), - }); - if (attempt >= maxRetries) { - // Max retries reached - const errorStack = getErrorStack(err); - const stackLines = errorStack.split('\n').slice(0, 4); - console.error(`[Workflows] "${workflowRunId}" - Encountered \`Error\` while executing step "${stepName}" (attempt ${attempt}):\n > ${stackLines.join('\n > ')}\n\n Max retries reached\n Bubbling error to parent workflow`); - const errorMessage = `Step "${stepName}" failed after max retries: ${String(err)}`; - await world.events.create(workflowRunId, { - eventType: 'step_failed', - correlationId: stepId, - eventData: { - error: errorMessage, - stack: errorStack, - fatal: true, - }, - }); - await world.steps.update(workflowRunId, stepId, { - status: 'failed', - error: { - message: errorMessage, - stack: errorStack, - }, - }); - span?.setAttributes({ - ...StepStatus('failed'), - ...StepRetryExhausted(true), - }); - } - else { - // Not at max retries yet - log as a retryable error - if (RetryableError.is(err)) { - console.warn(`[Workflows] "${workflowRunId}" - Encountered \`RetryableError\` while executing step "${stepName}" (attempt ${attempt}):\n > ${String(err.message)}\n\n This step has failed but will be retried`); - } - else { - const stackLines = getErrorStack(err).split('\n').slice(0, 4); - console.error(`[Workflows] "${workflowRunId}" - Encountered \`Error\` while executing step "${stepName}" (attempt ${attempt}):\n > ${stackLines.join('\n > ')}\n\n This step has failed but will be retried`); - } - await world.events.create(workflowRunId, { - eventType: 'step_failed', - correlationId: stepId, - eventData: { - error: String(err), - stack: getErrorStack(err), - }, - }); - await world.steps.update(workflowRunId, stepId, { - status: 'pending', // TODO: Should be "retrying" once we have that status - ...(RetryableError.is(err) && { - retryAfter: err.retryAfter, - }), - }); - const timeoutSeconds = Math.max(1, RetryableError.is(err) - ? Math.ceil((+err.retryAfter.getTime() - Date.now()) / 1000) - : 1); - span?.setAttributes({ - ...StepRetryTimeoutSeconds(timeoutSeconds), - ...StepRetryWillRetry(true), - }); - // It's a retryable error - so have the queue keep the message visible - // so that it gets retried. - return { timeoutSeconds }; - } - } - } - await world.queue(`__wkf_workflow_${workflowName}`, { - runId: workflowRunId, - traceCarrier: await serializeTraceCarrier(), - }); - }); - }); -}); - -export { Run as R, contextStorage as c, getRun as g, stepEntrypoint as s, workflowEntrypoint as w }; diff --git a/workbench/astro/dist/server/chunks/sharp_CR567j69.mjs b/workbench/astro/dist/server/chunks/sharp_CR567j69.mjs deleted file mode 100644 index 0efeb7f3e..000000000 --- a/workbench/astro/dist/server/chunks/sharp_CR567j69.mjs +++ /dev/null @@ -1,99 +0,0 @@ -import { A as AstroError, al as MissingSharp } from './astro/server_DhWKww_t.mjs'; -import { b as baseService, p as parseQuality } from './node_C2n6Z2oQ.mjs'; - -let sharp; -const qualityTable = { - low: 25, - mid: 50, - high: 80, - max: 100 -}; -async function loadSharp() { - let sharpImport; - try { - sharpImport = (await import('sharp')).default; - } catch { - throw new AstroError(MissingSharp); - } - sharpImport.cache(false); - return sharpImport; -} -const fitMap = { - fill: "fill", - contain: "inside", - cover: "cover", - none: "outside", - "scale-down": "inside", - outside: "outside", - inside: "inside" -}; -const sharpService = { - validateOptions: baseService.validateOptions, - getURL: baseService.getURL, - parseURL: baseService.parseURL, - getHTMLAttributes: baseService.getHTMLAttributes, - getSrcSet: baseService.getSrcSet, - async transform(inputBuffer, transformOptions, config) { - if (!sharp) sharp = await loadSharp(); - const transform = transformOptions; - if (transform.format === "svg") return { data: inputBuffer, format: "svg" }; - const result = sharp(inputBuffer, { - failOnError: false, - pages: -1, - limitInputPixels: config.service.config.limitInputPixels - }); - result.rotate(); - const withoutEnlargement = Boolean(transform.fit); - if (transform.width && transform.height && transform.fit) { - const fit = fitMap[transform.fit] ?? "inside"; - result.resize({ - width: Math.round(transform.width), - height: Math.round(transform.height), - fit, - position: transform.position, - withoutEnlargement - }); - } else if (transform.height && !transform.width) { - result.resize({ - height: Math.round(transform.height), - withoutEnlargement - }); - } else if (transform.width) { - result.resize({ - width: Math.round(transform.width), - withoutEnlargement - }); - } - if (transform.format) { - let quality = void 0; - if (transform.quality) { - const parsedQuality = parseQuality(transform.quality); - if (typeof parsedQuality === "number") { - quality = parsedQuality; - } else { - quality = transform.quality in qualityTable ? qualityTable[transform.quality] : void 0; - } - } - const isGifInput = inputBuffer[0] === 71 && // 'G' - inputBuffer[1] === 73 && // 'I' - inputBuffer[2] === 70 && // 'F' - inputBuffer[3] === 56 && // '8' - (inputBuffer[4] === 57 || inputBuffer[4] === 55) && // '9' or '7' - inputBuffer[5] === 97; - if (transform.format === "webp" && isGifInput) { - result.webp({ quality: typeof quality === "number" ? quality : void 0, loop: 0 }); - } else { - result.toFormat(transform.format, { quality }); - } - } - const { data, info } = await result.toBuffer({ resolveWithObject: true }); - const needsCopy = "buffer" in data && data.buffer instanceof SharedArrayBuffer; - return { - data: needsCopy ? new Uint8Array(data) : data, - format: info.format - }; - } -}; -var sharp_default = sharpService; - -export { sharp_default as default }; diff --git a/workbench/astro/dist/server/chunks/token-util_8GTOk-OQ.mjs b/workbench/astro/dist/server/chunks/token-util_8GTOk-OQ.mjs deleted file mode 100644 index 39e4b353e..000000000 --- a/workbench/astro/dist/server/chunks/token-util_8GTOk-OQ.mjs +++ /dev/null @@ -1,260 +0,0 @@ -import require$$0 from 'path'; -import require$$0$1 from 'fs'; -import { at as requireTokenError } from './index_ePTMDSOu.mjs'; -import require$$2 from 'os'; - -var tokenIo; -var hasRequiredTokenIo; - -function requireTokenIo () { - if (hasRequiredTokenIo) return tokenIo; - hasRequiredTokenIo = 1; - var __create = Object.create; - var __defProp = Object.defineProperty; - var __getOwnPropDesc = Object.getOwnPropertyDescriptor; - var __getOwnPropNames = Object.getOwnPropertyNames; - var __getProtoOf = Object.getPrototypeOf; - var __hasOwnProp = Object.prototype.hasOwnProperty; - var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); - }; - var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; - }; - var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( - // If the importer is in node compatibility mode or this is not an ESM - // file that has been converted to a CommonJS file using a Babel- - // compatible transform (i.e. "__esModule" has not been set), then set - // "default" to the CommonJS "module.exports" for node compatibility. - !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, - mod - )); - var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); - var token_io_exports = {}; - __export(token_io_exports, { - findRootDir: () => findRootDir, - getUserDataDir: () => getUserDataDir - }); - tokenIo = __toCommonJS(token_io_exports); - var import_path = __toESM(require$$0); - var import_fs = __toESM(require$$0$1); - var import_os = __toESM(require$$2); - var import_token_error = requireTokenError(); - function findRootDir() { - try { - let dir = process.cwd(); - while (dir !== import_path.default.dirname(dir)) { - const pkgPath = import_path.default.join(dir, ".vercel"); - if (import_fs.default.existsSync(pkgPath)) { - return dir; - } - dir = import_path.default.dirname(dir); - } - } catch (e) { - throw new import_token_error.VercelOidcTokenError( - "Token refresh only supported in node server environments" - ); - } - throw new import_token_error.VercelOidcTokenError("Unable to find root directory"); - } - function getUserDataDir() { - if (process.env.XDG_DATA_HOME) { - return process.env.XDG_DATA_HOME; - } - switch (import_os.default.platform()) { - case "darwin": - return import_path.default.join(import_os.default.homedir(), "Library/Application Support"); - case "linux": - return import_path.default.join(import_os.default.homedir(), ".local/share"); - case "win32": - if (process.env.LOCALAPPDATA) { - return process.env.LOCALAPPDATA; - } - return null; - default: - return null; - } - } - return tokenIo; -} - -var tokenUtil; -var hasRequiredTokenUtil; - -function requireTokenUtil () { - if (hasRequiredTokenUtil) return tokenUtil; - hasRequiredTokenUtil = 1; - var __create = Object.create; - var __defProp = Object.defineProperty; - var __getOwnPropDesc = Object.getOwnPropertyDescriptor; - var __getOwnPropNames = Object.getOwnPropertyNames; - var __getProtoOf = Object.getPrototypeOf; - var __hasOwnProp = Object.prototype.hasOwnProperty; - var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); - }; - var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; - }; - var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( - // If the importer is in node compatibility mode or this is not an ESM - // file that has been converted to a CommonJS file using a Babel- - // compatible transform (i.e. "__esModule" has not been set), then set - // "default" to the CommonJS "module.exports" for node compatibility. - !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, - mod - )); - var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); - var token_util_exports = {}; - __export(token_util_exports, { - assertVercelOidcTokenResponse: () => assertVercelOidcTokenResponse, - findProjectInfo: () => findProjectInfo, - getTokenPayload: () => getTokenPayload, - getVercelCliToken: () => getVercelCliToken, - getVercelDataDir: () => getVercelDataDir, - getVercelOidcToken: () => getVercelOidcToken, - isExpired: () => isExpired, - loadToken: () => loadToken, - saveToken: () => saveToken - }); - tokenUtil = __toCommonJS(token_util_exports); - var path = __toESM(require$$0); - var fs = __toESM(require$$0$1); - var import_token_error = requireTokenError(); - var import_token_io = requireTokenIo(); - function getVercelDataDir() { - const vercelFolder = "com.vercel.cli"; - const dataDir = (0, import_token_io.getUserDataDir)(); - if (!dataDir) { - return null; - } - return path.join(dataDir, vercelFolder); - } - function getVercelCliToken() { - const dataDir = getVercelDataDir(); - if (!dataDir) { - return null; - } - const tokenPath = path.join(dataDir, "auth.json"); - if (!fs.existsSync(tokenPath)) { - return null; - } - const token = fs.readFileSync(tokenPath, "utf8"); - if (!token) { - return null; - } - return JSON.parse(token).token; - } - async function getVercelOidcToken(authToken, projectId, teamId) { - try { - const url = `https://api.vercel.com/v1/projects/${projectId}/token?source=vercel-oidc-refresh${teamId ? `&teamId=${teamId}` : ""}`; - const res = await fetch(url, { - method: "POST", - headers: { - Authorization: `Bearer ${authToken}` - } - }); - if (!res.ok) { - throw new import_token_error.VercelOidcTokenError( - `Failed to refresh OIDC token: ${res.statusText}` - ); - } - const tokenRes = await res.json(); - assertVercelOidcTokenResponse(tokenRes); - return tokenRes; - } catch (e) { - throw new import_token_error.VercelOidcTokenError(`Failed to refresh OIDC token`, e); - } - } - function assertVercelOidcTokenResponse(res) { - if (!res || typeof res !== "object") { - throw new TypeError("Expected an object"); - } - if (!("token" in res) || typeof res.token !== "string") { - throw new TypeError("Expected a string-valued token property"); - } - } - function findProjectInfo() { - const dir = (0, import_token_io.findRootDir)(); - if (!dir) { - throw new import_token_error.VercelOidcTokenError("Unable to find root directory"); - } - try { - const prjPath = path.join(dir, ".vercel", "project.json"); - if (!fs.existsSync(prjPath)) { - throw new import_token_error.VercelOidcTokenError("project.json not found"); - } - const prj = JSON.parse(fs.readFileSync(prjPath, "utf8")); - if (typeof prj.projectId !== "string" && typeof prj.orgId !== "string") { - throw new TypeError("Expected a string-valued projectId property"); - } - return { projectId: prj.projectId, teamId: prj.orgId }; - } catch (e) { - throw new import_token_error.VercelOidcTokenError(`Unable to find project ID`, e); - } - } - function saveToken(token, projectId) { - try { - const dir = (0, import_token_io.getUserDataDir)(); - if (!dir) { - throw new import_token_error.VercelOidcTokenError("Unable to find user data directory"); - } - const tokenPath = path.join(dir, "com.vercel.token", `${projectId}.json`); - const tokenJson = JSON.stringify(token); - fs.mkdirSync(path.dirname(tokenPath), { mode: 432, recursive: true }); - fs.writeFileSync(tokenPath, tokenJson); - fs.chmodSync(tokenPath, 432); - return; - } catch (e) { - throw new import_token_error.VercelOidcTokenError(`Failed to save token`, e); - } - } - function loadToken(projectId) { - try { - const dir = (0, import_token_io.getUserDataDir)(); - if (!dir) { - return null; - } - const tokenPath = path.join(dir, "com.vercel.token", `${projectId}.json`); - if (!fs.existsSync(tokenPath)) { - return null; - } - const token = JSON.parse(fs.readFileSync(tokenPath, "utf8")); - assertVercelOidcTokenResponse(token); - return token; - } catch (e) { - throw new import_token_error.VercelOidcTokenError(`Failed to load token`, e); - } - } - function getTokenPayload(token) { - const tokenParts = token.split("."); - if (tokenParts.length !== 3) { - throw new import_token_error.VercelOidcTokenError("Invalid token"); - } - const base64 = tokenParts[1].replace(/-/g, "+").replace(/_/g, "/"); - const padded = base64.padEnd( - base64.length + (4 - base64.length % 4) % 4, - "=" - ); - return JSON.parse(Buffer.from(padded, "base64").toString("utf8")); - } - const TIME_15_MINUTES_IN_MS = 15 * 60 * 1e3; - function isExpired(token) { - return token.exp * 1e3 < Date.now() + TIME_15_MINUTES_IN_MS; - } - return tokenUtil; -} - -export { requireTokenUtil as r }; diff --git a/workbench/astro/dist/server/chunks/token-util_D6r3xWR2.mjs b/workbench/astro/dist/server/chunks/token-util_D6r3xWR2.mjs deleted file mode 100644 index da9cf584d..000000000 --- a/workbench/astro/dist/server/chunks/token-util_D6r3xWR2.mjs +++ /dev/null @@ -1,30 +0,0 @@ -import { g as getDefaultExportFromCjs } from './_commonjsHelpers_BFTU3MAI.mjs'; -import { r as requireTokenUtil } from './token-util_8GTOk-OQ.mjs'; - -function _mergeNamespaces(n, m) { - for (var i = 0; i < m.length; i++) { - const e = m[i]; - if (typeof e !== 'string' && !Array.isArray(e)) { for (const k in e) { - if (k !== 'default' && !(k in n)) { - const d = Object.getOwnPropertyDescriptor(e, k); - if (d) { - Object.defineProperty(n, k, d.get ? d : { - enumerable: true, - get: () => e[k] - }); - } - } - } } - } - return Object.freeze(Object.defineProperty(n, Symbol.toStringTag, { value: 'Module' })); -} - -var tokenUtilExports = requireTokenUtil(); -const tokenUtil = /*@__PURE__*/getDefaultExportFromCjs(tokenUtilExports); - -const tokenUtil$1 = /*#__PURE__*/_mergeNamespaces({ - __proto__: null, - default: tokenUtil -}, [tokenUtilExports]); - -export { tokenUtil$1 as t }; diff --git a/workbench/astro/dist/server/chunks/token_CrOFk7pc.mjs b/workbench/astro/dist/server/chunks/token_CrOFk7pc.mjs deleted file mode 100644 index 312b8d434..000000000 --- a/workbench/astro/dist/server/chunks/token_CrOFk7pc.mjs +++ /dev/null @@ -1,88 +0,0 @@ -import { g as getDefaultExportFromCjs } from './_commonjsHelpers_BFTU3MAI.mjs'; -import { at as requireTokenError } from './index_ePTMDSOu.mjs'; -import { r as requireTokenUtil } from './token-util_8GTOk-OQ.mjs'; - -function _mergeNamespaces(n, m) { - for (var i = 0; i < m.length; i++) { - const e = m[i]; - if (typeof e !== 'string' && !Array.isArray(e)) { for (const k in e) { - if (k !== 'default' && !(k in n)) { - const d = Object.getOwnPropertyDescriptor(e, k); - if (d) { - Object.defineProperty(n, k, d.get ? d : { - enumerable: true, - get: () => e[k] - }); - } - } - } } - } - return Object.freeze(Object.defineProperty(n, Symbol.toStringTag, { value: 'Module' })); -} - -var token$2; -var hasRequiredToken; - -function requireToken () { - if (hasRequiredToken) return token$2; - hasRequiredToken = 1; - var __defProp = Object.defineProperty; - var __getOwnPropDesc = Object.getOwnPropertyDescriptor; - var __getOwnPropNames = Object.getOwnPropertyNames; - var __hasOwnProp = Object.prototype.hasOwnProperty; - var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); - }; - var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; - }; - var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); - var token_exports = {}; - __export(token_exports, { - refreshToken: () => refreshToken - }); - token$2 = __toCommonJS(token_exports); - var import_token_error = requireTokenError(); - var import_token_util = requireTokenUtil(); - async function refreshToken() { - const { projectId, teamId } = (0, import_token_util.findProjectInfo)(); - let maybeToken = (0, import_token_util.loadToken)(projectId); - if (!maybeToken || (0, import_token_util.isExpired)((0, import_token_util.getTokenPayload)(maybeToken.token))) { - const authToken = (0, import_token_util.getVercelCliToken)(); - if (!authToken) { - throw new import_token_error.VercelOidcTokenError( - "Failed to refresh OIDC token: login to vercel cli" - ); - } - if (!projectId) { - throw new import_token_error.VercelOidcTokenError( - "Failed to refresh OIDC token: project id not found" - ); - } - maybeToken = await (0, import_token_util.getVercelOidcToken)(authToken, projectId, teamId); - if (!maybeToken) { - throw new import_token_error.VercelOidcTokenError("Failed to refresh OIDC token"); - } - (0, import_token_util.saveToken)(maybeToken, projectId); - } - process.env.VERCEL_OIDC_TOKEN = maybeToken.token; - return; - } - return token$2; -} - -var tokenExports = requireToken(); -const token = /*@__PURE__*/getDefaultExportFromCjs(tokenExports); - -const token$1 = /*#__PURE__*/_mergeNamespaces({ - __proto__: null, - default: token -}, [tokenExports]); - -export { token$1 as t }; diff --git a/workbench/astro/dist/server/entry.mjs b/workbench/astro/dist/server/entry.mjs deleted file mode 100644 index 4688832ce..000000000 --- a/workbench/astro/dist/server/entry.mjs +++ /dev/null @@ -1,51 +0,0 @@ -import { renderers } from './renderers.mjs'; -import { c as createExports, s as serverEntrypointModule } from './chunks/_@astrojs-ssr-adapter_9__r_ZjJ.mjs'; -import { manifest } from './manifest_Dl93wae-.mjs'; - -const serverIslandMap = new Map();; - -const _page0 = () => import('./pages/_image.astro.mjs'); -const _page1 = () => import('./pages/.well-known/workflow/v1/flow.astro.mjs'); -const _page2 = () => import('./pages/.well-known/workflow/v1/step.astro.mjs'); -const _page3 = () => import('./pages/.well-known/workflow/v1/webhook/_token_.astro.mjs'); -const _page4 = () => import('./pages/api/hook.astro.mjs'); -const _page5 = () => import('./pages/api/test-direct-step-call.astro.mjs'); -const _page6 = () => import('./pages/api/trigger.astro.mjs'); -const _page7 = () => import('./pages/index.astro.mjs'); -const pageMap = new Map([ - ["../../node_modules/.pnpm/astro@5.15.6_@netlify+blobs@9.1.2_@types+node@24.6.2_@vercel+functions@3.1.4_@aws-sdk+c_33d54f21a5540c974d08dc1b122d5cc1/node_modules/astro/dist/assets/endpoint/node.js", _page0], - ["src/pages/.well-known/workflow/v1/flow.js", _page1], - ["src/pages/.well-known/workflow/v1/step.js", _page2], - ["src/pages/.well-known/workflow/v1/webhook/[token].js", _page3], - ["src/pages/api/hook.ts", _page4], - ["src/pages/api/test-direct-step-call.ts", _page5], - ["src/pages/api/trigger.ts", _page6], - ["src/pages/index.astro", _page7] -]); - -const _manifest = Object.assign(manifest, { - pageMap, - serverIslandMap, - renderers, - actions: () => import('./noop-entrypoint.mjs'), - middleware: () => import('./_noop-middleware.mjs') -}); -const _args = { - "mode": "standalone", - "client": "file:///Users/adrianlam/GitHub/workflow/workbench/astro/dist/client/", - "server": "file:///Users/adrianlam/GitHub/workflow/workbench/astro/dist/server/", - "host": false, - "port": 4321, - "assets": "_astro", - "experimentalStaticHeaders": false -}; -const _exports = createExports(_manifest, _args); -const handler = _exports['handler']; -const startServer = _exports['startServer']; -const options = _exports['options']; -const _start = 'start'; -if (Object.prototype.hasOwnProperty.call(serverEntrypointModule, _start)) { - serverEntrypointModule[_start](_manifest, _args); -} - -export { handler, options, pageMap, startServer }; diff --git a/workbench/astro/dist/server/manifest_Dl93wae-.mjs b/workbench/astro/dist/server/manifest_Dl93wae-.mjs deleted file mode 100644 index 71fbed9a3..000000000 --- a/workbench/astro/dist/server/manifest_Dl93wae-.mjs +++ /dev/null @@ -1,101 +0,0 @@ -import { l as decodeKey } from './chunks/astro/server_DhWKww_t.mjs'; -import 'clsx'; -import 'cookie'; -import { N as NOOP_MIDDLEWARE_FN } from './chunks/astro-designed-error-pages_pFA87nEA.mjs'; -import 'es-module-lexer'; - -function sanitizeParams(params) { - return Object.fromEntries( - Object.entries(params).map(([key, value]) => { - if (typeof value === "string") { - return [key, value.normalize().replace(/#/g, "%23").replace(/\?/g, "%3F")]; - } - return [key, value]; - }) - ); -} -function getParameter(part, params) { - if (part.spread) { - return params[part.content.slice(3)] || ""; - } - if (part.dynamic) { - if (!params[part.content]) { - throw new TypeError(`Missing parameter: ${part.content}`); - } - return params[part.content]; - } - return part.content.normalize().replace(/\?/g, "%3F").replace(/#/g, "%23").replace(/%5B/g, "[").replace(/%5D/g, "]"); -} -function getSegment(segment, params) { - const segmentPath = segment.map((part) => getParameter(part, params)).join(""); - return segmentPath ? "/" + segmentPath : ""; -} -function getRouteGenerator(segments, addTrailingSlash) { - return (params) => { - const sanitizedParams = sanitizeParams(params); - let trailing = ""; - if (addTrailingSlash === "always" && segments.length) { - trailing = "/"; - } - const path = segments.map((segment) => getSegment(segment, sanitizedParams)).join("") + trailing; - return path || "/"; - }; -} - -function deserializeRouteData(rawRouteData) { - return { - route: rawRouteData.route, - type: rawRouteData.type, - pattern: new RegExp(rawRouteData.pattern), - params: rawRouteData.params, - component: rawRouteData.component, - generate: getRouteGenerator(rawRouteData.segments, rawRouteData._meta.trailingSlash), - pathname: rawRouteData.pathname || void 0, - segments: rawRouteData.segments, - prerender: rawRouteData.prerender, - redirect: rawRouteData.redirect, - redirectRoute: rawRouteData.redirectRoute ? deserializeRouteData(rawRouteData.redirectRoute) : void 0, - fallbackRoutes: rawRouteData.fallbackRoutes.map((fallback) => { - return deserializeRouteData(fallback); - }), - isIndex: rawRouteData.isIndex, - origin: rawRouteData.origin - }; -} - -function deserializeManifest(serializedManifest) { - const routes = []; - for (const serializedRoute of serializedManifest.routes) { - routes.push({ - ...serializedRoute, - routeData: deserializeRouteData(serializedRoute.routeData) - }); - const route = serializedRoute; - route.routeData = deserializeRouteData(serializedRoute.routeData); - } - const assets = new Set(serializedManifest.assets); - const componentMetadata = new Map(serializedManifest.componentMetadata); - const inlinedScripts = new Map(serializedManifest.inlinedScripts); - const clientDirectives = new Map(serializedManifest.clientDirectives); - const serverIslandNameMap = new Map(serializedManifest.serverIslandNameMap); - const key = decodeKey(serializedManifest.key); - return { - // in case user middleware exists, this no-op middleware will be reassigned (see plugin-ssr.ts) - middleware() { - return { onRequest: NOOP_MIDDLEWARE_FN }; - }, - ...serializedManifest, - assets, - componentMetadata, - inlinedScripts, - clientDirectives, - routes, - serverIslandNameMap, - key - }; -} - -const manifest = deserializeManifest({"hrefRoot":"file:///Users/adrianlam/GitHub/workflow/workbench/astro/","cacheDir":"file:///Users/adrianlam/GitHub/workflow/workbench/astro/node_modules/.astro/","outDir":"file:///Users/adrianlam/GitHub/workflow/workbench/astro/dist/","srcDir":"file:///Users/adrianlam/GitHub/workflow/workbench/astro/src/","publicDir":"file:///Users/adrianlam/GitHub/workflow/workbench/astro/public/","buildClientDir":"file:///Users/adrianlam/GitHub/workflow/workbench/astro/dist/client/","buildServerDir":"file:///Users/adrianlam/GitHub/workflow/workbench/astro/dist/server/","adapterName":"@astrojs/node","routes":[{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"type":"page","component":"_server-islands.astro","params":["name"],"segments":[[{"content":"_server-islands","dynamic":false,"spread":false}],[{"content":"name","dynamic":true,"spread":false}]],"pattern":"^\\/_server-islands\\/([^/]+?)\\/?$","prerender":false,"isIndex":false,"fallbackRoutes":[],"route":"/_server-islands/[name]","origin":"internal","_meta":{"trailingSlash":"ignore"}}},{"file":"index.html","links":[],"scripts":[],"styles":[],"routeData":{"route":"/","isIndex":true,"type":"page","pattern":"^\\/$","segments":[],"params":[],"component":"src/pages/index.astro","pathname":"/","prerender":true,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"type":"endpoint","isIndex":false,"route":"/_image","pattern":"^\\/_image\\/?$","segments":[[{"content":"_image","dynamic":false,"spread":false}]],"params":[],"component":"../../node_modules/.pnpm/astro@5.15.6_@netlify+blobs@9.1.2_@types+node@24.6.2_@vercel+functions@3.1.4_@aws-sdk+c_33d54f21a5540c974d08dc1b122d5cc1/node_modules/astro/dist/assets/endpoint/node.js","pathname":"/_image","prerender":false,"fallbackRoutes":[],"origin":"internal","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"route":"/.well-known/workflow/v1/flow","isIndex":false,"type":"endpoint","pattern":"^\\/\\.well-known\\/workflow\\/v1\\/flow\\/?$","segments":[[{"content":".well-known","dynamic":false,"spread":false}],[{"content":"workflow","dynamic":false,"spread":false}],[{"content":"v1","dynamic":false,"spread":false}],[{"content":"flow","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/.well-known/workflow/v1/flow.js","pathname":"/.well-known/workflow/v1/flow","prerender":false,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"route":"/.well-known/workflow/v1/step","isIndex":false,"type":"endpoint","pattern":"^\\/\\.well-known\\/workflow\\/v1\\/step\\/?$","segments":[[{"content":".well-known","dynamic":false,"spread":false}],[{"content":"workflow","dynamic":false,"spread":false}],[{"content":"v1","dynamic":false,"spread":false}],[{"content":"step","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/.well-known/workflow/v1/step.js","pathname":"/.well-known/workflow/v1/step","prerender":false,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"route":"/.well-known/workflow/v1/webhook/[token]","isIndex":false,"type":"endpoint","pattern":"^\\/\\.well-known\\/workflow\\/v1\\/webhook\\/([^/]+?)\\/?$","segments":[[{"content":".well-known","dynamic":false,"spread":false}],[{"content":"workflow","dynamic":false,"spread":false}],[{"content":"v1","dynamic":false,"spread":false}],[{"content":"webhook","dynamic":false,"spread":false}],[{"content":"token","dynamic":true,"spread":false}]],"params":["token"],"component":"src/pages/.well-known/workflow/v1/webhook/[token].js","prerender":false,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"route":"/api/hook","isIndex":false,"type":"endpoint","pattern":"^\\/api\\/hook\\/?$","segments":[[{"content":"api","dynamic":false,"spread":false}],[{"content":"hook","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/api/hook.ts","pathname":"/api/hook","prerender":false,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"route":"/api/test-direct-step-call","isIndex":false,"type":"endpoint","pattern":"^\\/api\\/test-direct-step-call\\/?$","segments":[[{"content":"api","dynamic":false,"spread":false}],[{"content":"test-direct-step-call","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/api/test-direct-step-call.ts","pathname":"/api/test-direct-step-call","prerender":false,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"route":"/api/trigger","isIndex":false,"type":"endpoint","pattern":"^\\/api\\/trigger\\/?$","segments":[[{"content":"api","dynamic":false,"spread":false}],[{"content":"trigger","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/api/trigger.ts","pathname":"/api/trigger","prerender":false,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}}],"base":"/","trailingSlash":"ignore","compressHTML":true,"componentMetadata":[["/Users/adrianlam/GitHub/workflow/workbench/astro/src/pages/index.astro",{"propagation":"none","containsHead":true}]],"renderers":[],"clientDirectives":[["idle","(()=>{var l=(n,t)=>{let i=async()=>{await(await n())()},e=typeof t.value==\"object\"?t.value:void 0,s={timeout:e==null?void 0:e.timeout};\"requestIdleCallback\"in window?window.requestIdleCallback(i,s):setTimeout(i,s.timeout||200)};(self.Astro||(self.Astro={})).idle=l;window.dispatchEvent(new Event(\"astro:idle\"));})();"],["load","(()=>{var e=async t=>{await(await t())()};(self.Astro||(self.Astro={})).load=e;window.dispatchEvent(new Event(\"astro:load\"));})();"],["media","(()=>{var n=(a,t)=>{let i=async()=>{await(await a())()};if(t.value){let e=matchMedia(t.value);e.matches?i():e.addEventListener(\"change\",i,{once:!0})}};(self.Astro||(self.Astro={})).media=n;window.dispatchEvent(new Event(\"astro:media\"));})();"],["only","(()=>{var e=async t=>{await(await t())()};(self.Astro||(self.Astro={})).only=e;window.dispatchEvent(new Event(\"astro:only\"));})();"],["visible","(()=>{var a=(s,i,o)=>{let r=async()=>{await(await s())()},t=typeof i.value==\"object\"?i.value:void 0,c={rootMargin:t==null?void 0:t.rootMargin},n=new IntersectionObserver(e=>{for(let l of e)if(l.isIntersecting){n.disconnect(),r();break}},c);for(let e of o.children)n.observe(e)};(self.Astro||(self.Astro={})).visible=a;window.dispatchEvent(new Event(\"astro:visible\"));})();"]],"entryModules":{"\u0000noop-middleware":"_noop-middleware.mjs","\u0000virtual:astro:actions/noop-entrypoint":"noop-entrypoint.mjs","\u0000@astro-page:src/pages/.well-known/workflow/v1/flow@_@js":"pages/.well-known/workflow/v1/flow.astro.mjs","\u0000@astro-page:src/pages/.well-known/workflow/v1/step@_@js":"pages/.well-known/workflow/v1/step.astro.mjs","\u0000@astro-page:src/pages/.well-known/workflow/v1/webhook/[token]@_@js":"pages/.well-known/workflow/v1/webhook/_token_.astro.mjs","\u0000@astro-page:src/pages/api/hook@_@ts":"pages/api/hook.astro.mjs","\u0000@astro-page:src/pages/api/test-direct-step-call@_@ts":"pages/api/test-direct-step-call.astro.mjs","\u0000@astro-page:src/pages/api/trigger@_@ts":"pages/api/trigger.astro.mjs","\u0000@astro-page:src/pages/index@_@astro":"pages/index.astro.mjs","\u0000@astrojs-ssr-virtual-entry":"entry.mjs","\u0000@astro-renderers":"renderers.mjs","\u0000@astro-page:../../node_modules/.pnpm/astro@5.15.6_@netlify+blobs@9.1.2_@types+node@24.6.2_@vercel+functions@3.1.4_@aws-sdk+c_33d54f21a5540c974d08dc1b122d5cc1/node_modules/astro/dist/assets/endpoint/node@_@js":"pages/_image.astro.mjs","\u0000@astrojs-ssr-adapter":"_@astrojs-ssr-adapter.mjs","\u0000@astrojs-manifest":"manifest_Dl93wae-.mjs","/Users/adrianlam/GitHub/workflow/node_modules/.pnpm/unstorage@1.17.2_@netlify+blobs@9.1.2_@vercel+functions@3.1.4_@aws-sdk+credential-provi_3128ad0acdbf5fcd10d3fd4ae6facc53/node_modules/unstorage/drivers/fs-lite.mjs":"chunks/fs-lite_COtHaKzy.mjs","/Users/adrianlam/GitHub/workflow/node_modules/.pnpm/astro@5.15.6_@netlify+blobs@9.1.2_@types+node@24.6.2_@vercel+functions@3.1.4_@aws-sdk+c_33d54f21a5540c974d08dc1b122d5cc1/node_modules/astro/dist/assets/services/sharp.js":"chunks/sharp_CR567j69.mjs","/Users/adrianlam/GitHub/workflow/node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/esm/index.js":"chunks/index_DqQ8k47W.mjs","astro:scripts/before-hydration.js":""},"inlinedScripts":[],"assets":["/favicon.svg","/index.html"],"buildFormat":"directory","checkOrigin":true,"allowedDomains":[],"serverIslandNameMap":[],"key":"HL0UuLEHejpYckGtqBgG3AGwkjtu7IQ2osDhkMDvjVM=","sessionConfig":{"driver":"fs-lite","options":{"base":"/Users/adrianlam/GitHub/workflow/workbench/astro/node_modules/.astro/sessions"}}}); -if (manifest.sessionConfig) manifest.sessionConfig.driverModule = () => import('./chunks/fs-lite_COtHaKzy.mjs'); - -export { manifest }; diff --git a/workbench/astro/dist/server/noop-entrypoint.mjs b/workbench/astro/dist/server/noop-entrypoint.mjs deleted file mode 100644 index f30dc327c..000000000 --- a/workbench/astro/dist/server/noop-entrypoint.mjs +++ /dev/null @@ -1,3 +0,0 @@ -const server = {}; - -export { server }; diff --git a/workbench/astro/dist/server/pages/.well-known/workflow/v1/flow.astro.mjs b/workbench/astro/dist/server/pages/.well-known/workflow/v1/flow.astro.mjs deleted file mode 100644 index 26c14c40d..000000000 --- a/workbench/astro/dist/server/pages/.well-known/workflow/v1/flow.astro.mjs +++ /dev/null @@ -1,27439 +0,0 @@ -import { w as workflowEntrypoint } from '../../../../chunks/runtime_CxdH0OC2.mjs'; -export { renderers } from '../../../../renderers.mjs'; - -// biome-ignore-all lint: generated file -/* eslint-disable */ - -const workflowCode = `var __create = Object.create; -var __defProp = Object.defineProperty; -var __getOwnPropDesc = Object.getOwnPropertyDescriptor; -var __getOwnPropNames = Object.getOwnPropertyNames; -var __getProtoOf = Object.getPrototypeOf; -var __hasOwnProp = Object.prototype.hasOwnProperty; -var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); -var __commonJS = (cb, mod) => function __require() { - return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; -}; -var __export = (target, all) => { - for (var name17 in all) - __defProp(target, name17, { get: all[name17], enumerable: true }); -}; -var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; -}; -var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( - // If the importer is in node compatibility mode or this is not an ESM - // file that has been converted to a CommonJS file using a Babel- - // compatible transform (i.e. "__esModule" has not been set), then set - // "default" to the CommonJS "module.exports" for node compatibility. - isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, - mod -)); - -// ../../node_modules/.pnpm/ms@2.1.3/node_modules/ms/index.js -var require_ms = __commonJS({ - "../../node_modules/.pnpm/ms@2.1.3/node_modules/ms/index.js"(exports, module2) { - var s = 1e3; - var m = s * 60; - var h = m * 60; - var d = h * 24; - var w = d * 7; - var y = d * 365.25; - module2.exports = function(val, options) { - options = options || {}; - var type = typeof val; - if (type === "string" && val.length > 0) { - return parse3(val); - } else if (type === "number" && isFinite(val)) { - return options.long ? fmtLong(val) : fmtShort(val); - } - throw new Error("val is not a non-empty string or a valid number. val=" + JSON.stringify(val)); - }; - function parse3(str) { - str = String(str); - if (str.length > 100) { - return; - } - var match = /^(-?(?:\\d+)?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?\$/i.exec(str); - if (!match) { - return; - } - var n = parseFloat(match[1]); - var type = (match[2] || "ms").toLowerCase(); - switch (type) { - case "years": - case "year": - case "yrs": - case "yr": - case "y": - return n * y; - case "weeks": - case "week": - case "w": - return n * w; - case "days": - case "day": - case "d": - return n * d; - case "hours": - case "hour": - case "hrs": - case "hr": - case "h": - return n * h; - case "minutes": - case "minute": - case "mins": - case "min": - case "m": - return n * m; - case "seconds": - case "second": - case "secs": - case "sec": - case "s": - return n * s; - case "milliseconds": - case "millisecond": - case "msecs": - case "msec": - case "ms": - return n; - default: - return void 0; - } - } - __name(parse3, "parse"); - function fmtShort(ms2) { - var msAbs = Math.abs(ms2); - if (msAbs >= d) { - return Math.round(ms2 / d) + "d"; - } - if (msAbs >= h) { - return Math.round(ms2 / h) + "h"; - } - if (msAbs >= m) { - return Math.round(ms2 / m) + "m"; - } - if (msAbs >= s) { - return Math.round(ms2 / s) + "s"; - } - return ms2 + "ms"; - } - __name(fmtShort, "fmtShort"); - function fmtLong(ms2) { - var msAbs = Math.abs(ms2); - if (msAbs >= d) { - return plural(ms2, msAbs, d, "day"); - } - if (msAbs >= h) { - return plural(ms2, msAbs, h, "hour"); - } - if (msAbs >= m) { - return plural(ms2, msAbs, m, "minute"); - } - if (msAbs >= s) { - return plural(ms2, msAbs, s, "second"); - } - return ms2 + " ms"; - } - __name(fmtLong, "fmtLong"); - function plural(ms2, msAbs, n, name17) { - var isPlural = msAbs >= n * 1.5; - return Math.round(ms2 / n) + " " + name17 + (isPlural ? "s" : ""); - } - __name(plural, "plural"); - } -}); - -// ../../node_modules/.pnpm/lodash.chunk@4.2.0/node_modules/lodash.chunk/index.js -var require_lodash = __commonJS({ - "../../node_modules/.pnpm/lodash.chunk@4.2.0/node_modules/lodash.chunk/index.js"(exports, module2) { - var INFINITY = 1 / 0; - var MAX_SAFE_INTEGER = 9007199254740991; - var MAX_INTEGER = 17976931348623157e292; - var NAN = 0 / 0; - var funcTag = "[object Function]"; - var genTag = "[object GeneratorFunction]"; - var symbolTag = "[object Symbol]"; - var reTrim = /^\\s+|\\s+\$/g; - var reIsBadHex = /^[-+]0x[0-9a-f]+\$/i; - var reIsBinary = /^0b[01]+\$/i; - var reIsOctal = /^0o[0-7]+\$/i; - var reIsUint = /^(?:0|[1-9]\\d*)\$/; - var freeParseInt = parseInt; - var objectProto = Object.prototype; - var objectToString = objectProto.toString; - var nativeCeil = Math.ceil; - var nativeMax = Math.max; - function baseSlice(array2, start, end) { - var index = -1, length = array2.length; - if (start < 0) { - start = -start > length ? 0 : length + start; - } - end = end > length ? length : end; - if (end < 0) { - end += length; - } - length = start > end ? 0 : end - start >>> 0; - start >>>= 0; - var result = Array(length); - while (++index < length) { - result[index] = array2[index + start]; - } - return result; - } - __name(baseSlice, "baseSlice"); - function isIndex(value, length) { - length = length == null ? MAX_SAFE_INTEGER : length; - return !!length && (typeof value == "number" || reIsUint.test(value)) && value > -1 && value % 1 == 0 && value < length; - } - __name(isIndex, "isIndex"); - function isIterateeCall(value, index, object3) { - if (!isObject2(object3)) { - return false; - } - var type = typeof index; - if (type == "number" ? isArrayLike(object3) && isIndex(index, object3.length) : type == "string" && index in object3) { - return eq(object3[index], value); - } - return false; - } - __name(isIterateeCall, "isIterateeCall"); - function chunk2(array2, size, guard) { - if (guard ? isIterateeCall(array2, size, guard) : size === void 0) { - size = 1; - } else { - size = nativeMax(toInteger(size), 0); - } - var length = array2 ? array2.length : 0; - if (!length || size < 1) { - return []; - } - var index = 0, resIndex = 0, result = Array(nativeCeil(length / size)); - while (index < length) { - result[resIndex++] = baseSlice(array2, index, index += size); - } - return result; - } - __name(chunk2, "chunk"); - function eq(value, other) { - return value === other || value !== value && other !== other; - } - __name(eq, "eq"); - function isArrayLike(value) { - return value != null && isLength(value.length) && !isFunction(value); - } - __name(isArrayLike, "isArrayLike"); - function isFunction(value) { - var tag = isObject2(value) ? objectToString.call(value) : ""; - return tag == funcTag || tag == genTag; - } - __name(isFunction, "isFunction"); - function isLength(value) { - return typeof value == "number" && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; - } - __name(isLength, "isLength"); - function isObject2(value) { - var type = typeof value; - return !!value && (type == "object" || type == "function"); - } - __name(isObject2, "isObject"); - function isObjectLike(value) { - return !!value && typeof value == "object"; - } - __name(isObjectLike, "isObjectLike"); - function isSymbol(value) { - return typeof value == "symbol" || isObjectLike(value) && objectToString.call(value) == symbolTag; - } - __name(isSymbol, "isSymbol"); - function toFinite(value) { - if (!value) { - return value === 0 ? value : 0; - } - value = toNumber(value); - if (value === INFINITY || value === -INFINITY) { - var sign = value < 0 ? -1 : 1; - return sign * MAX_INTEGER; - } - return value === value ? value : 0; - } - __name(toFinite, "toFinite"); - function toInteger(value) { - var result = toFinite(value), remainder = result % 1; - return result === result ? remainder ? result - remainder : result : 0; - } - __name(toInteger, "toInteger"); - function toNumber(value) { - if (typeof value == "number") { - return value; - } - if (isSymbol(value)) { - return NAN; - } - if (isObject2(value)) { - var other = typeof value.valueOf == "function" ? value.valueOf() : value; - value = isObject2(other) ? other + "" : other; - } - if (typeof value != "string") { - return value === 0 ? value : +value; - } - value = value.replace(reTrim, ""); - var isBinary = reIsBinary.test(value); - return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value; - } - __name(toNumber, "toNumber"); - module2.exports = chunk2; - } -}); - -// ../../node_modules/.pnpm/@vercel+oidc@3.0.3/node_modules/@vercel/oidc/dist/get-context.js -var require_get_context = __commonJS({ - "../../node_modules/.pnpm/@vercel+oidc@3.0.3/node_modules/@vercel/oidc/dist/get-context.js"(exports, module2) { - "use strict"; - var __defProp3 = Object.defineProperty; - var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; - var __getOwnPropNames2 = Object.getOwnPropertyNames; - var __hasOwnProp2 = Object.prototype.hasOwnProperty; - var __export3 = /* @__PURE__ */ __name((target, all) => { - for (var name17 in all) __defProp3(target, name17, { - get: all[name17], - enumerable: true - }); - }, "__export"); - var __copyProps2 = /* @__PURE__ */ __name((to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames2(from)) if (!__hasOwnProp2.call(to, key) && key !== except) __defProp3(to, key, { - get: /* @__PURE__ */ __name(() => from[key], "get"), - enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable - }); - } - return to; - }, "__copyProps"); - var __toCommonJS = /* @__PURE__ */ __name((mod) => __copyProps2(__defProp3({}, "__esModule", { - value: true - }), mod), "__toCommonJS"); - var get_context_exports = {}; - __export3(get_context_exports, { - SYMBOL_FOR_REQ_CONTEXT: /* @__PURE__ */ __name(() => SYMBOL_FOR_REQ_CONTEXT, "SYMBOL_FOR_REQ_CONTEXT"), - getContext: /* @__PURE__ */ __name(() => getContext3, "getContext") - }); - module2.exports = __toCommonJS(get_context_exports); - var SYMBOL_FOR_REQ_CONTEXT = Symbol.for("@vercel/request-context"); - function getContext3() { - const fromSymbol = globalThis; - return fromSymbol[SYMBOL_FOR_REQ_CONTEXT]?.get?.() ?? {}; - } - __name(getContext3, "getContext"); - } -}); - -// ../../node_modules/.pnpm/@vercel+oidc@3.0.3/node_modules/@vercel/oidc/dist/index-browser.js -var require_index_browser = __commonJS({ - "../../node_modules/.pnpm/@vercel+oidc@3.0.3/node_modules/@vercel/oidc/dist/index-browser.js"(exports, module2) { - "use strict"; - var __defProp3 = Object.defineProperty; - var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; - var __getOwnPropNames2 = Object.getOwnPropertyNames; - var __hasOwnProp2 = Object.prototype.hasOwnProperty; - var __export3 = /* @__PURE__ */ __name((target, all) => { - for (var name17 in all) __defProp3(target, name17, { - get: all[name17], - enumerable: true - }); - }, "__export"); - var __copyProps2 = /* @__PURE__ */ __name((to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames2(from)) if (!__hasOwnProp2.call(to, key) && key !== except) __defProp3(to, key, { - get: /* @__PURE__ */ __name(() => from[key], "get"), - enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable - }); - } - return to; - }, "__copyProps"); - var __toCommonJS = /* @__PURE__ */ __name((mod) => __copyProps2(__defProp3({}, "__esModule", { - value: true - }), mod), "__toCommonJS"); - var index_browser_exports = {}; - __export3(index_browser_exports, { - getContext: /* @__PURE__ */ __name(() => import_get_context.getContext, "getContext"), - getVercelOidcToken: /* @__PURE__ */ __name(() => getVercelOidcToken2, "getVercelOidcToken"), - getVercelOidcTokenSync: /* @__PURE__ */ __name(() => getVercelOidcTokenSync, "getVercelOidcTokenSync") - }); - module2.exports = __toCommonJS(index_browser_exports); - var import_get_context = require_get_context(); - async function getVercelOidcToken2() { - return ""; - } - __name(getVercelOidcToken2, "getVercelOidcToken"); - function getVercelOidcTokenSync() { - return ""; - } - __name(getVercelOidcTokenSync, "getVercelOidcTokenSync"); - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/platform/node/globalThis.js -var require_globalThis = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/platform/node/globalThis.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports._globalThis = void 0; - exports._globalThis = typeof globalThis === "object" ? globalThis : global; - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/platform/node/index.js -var require_node = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/platform/node/index.js"(exports) { - "use strict"; - var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) { - if (k2 === void 0) k2 = k; - Object.defineProperty(o, k2, { - enumerable: true, - get: /* @__PURE__ */ __name(function() { - return m[k]; - }, "get") - }); - } : function(o, m, k, k2) { - if (k2 === void 0) k2 = k; - o[k2] = m[k]; - }); - var __exportStar = exports && exports.__exportStar || function(m, exports1) { - for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports1, p)) __createBinding(exports1, m, p); - }; - Object.defineProperty(exports, "__esModule", { - value: true - }); - __exportStar(require_globalThis(), exports); - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/platform/index.js -var require_platform = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/platform/index.js"(exports) { - "use strict"; - var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) { - if (k2 === void 0) k2 = k; - Object.defineProperty(o, k2, { - enumerable: true, - get: /* @__PURE__ */ __name(function() { - return m[k]; - }, "get") - }); - } : function(o, m, k, k2) { - if (k2 === void 0) k2 = k; - o[k2] = m[k]; - }); - var __exportStar = exports && exports.__exportStar || function(m, exports1) { - for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports1, p)) __createBinding(exports1, m, p); - }; - Object.defineProperty(exports, "__esModule", { - value: true - }); - __exportStar(require_node(), exports); - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/version.js -var require_version = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/version.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.VERSION = void 0; - exports.VERSION = "1.9.0"; - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/internal/semver.js -var require_semver = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/internal/semver.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.isCompatible = exports._makeCompatibilityCheck = void 0; - var version_1 = require_version(); - var re = /^(\\d+)\\.(\\d+)\\.(\\d+)(-(.+))?\$/; - function _makeCompatibilityCheck(ownVersion) { - const acceptedVersions = /* @__PURE__ */ new Set([ - ownVersion - ]); - const rejectedVersions = /* @__PURE__ */ new Set(); - const myVersionMatch = ownVersion.match(re); - if (!myVersionMatch) { - return () => false; - } - const ownVersionParsed = { - major: +myVersionMatch[1], - minor: +myVersionMatch[2], - patch: +myVersionMatch[3], - prerelease: myVersionMatch[4] - }; - if (ownVersionParsed.prerelease != null) { - return /* @__PURE__ */ __name(function isExactmatch(globalVersion) { - return globalVersion === ownVersion; - }, "isExactmatch"); - } - function _reject(v) { - rejectedVersions.add(v); - return false; - } - __name(_reject, "_reject"); - function _accept(v) { - acceptedVersions.add(v); - return true; - } - __name(_accept, "_accept"); - return /* @__PURE__ */ __name(function isCompatible(globalVersion) { - if (acceptedVersions.has(globalVersion)) { - return true; - } - if (rejectedVersions.has(globalVersion)) { - return false; - } - const globalVersionMatch = globalVersion.match(re); - if (!globalVersionMatch) { - return _reject(globalVersion); - } - const globalVersionParsed = { - major: +globalVersionMatch[1], - minor: +globalVersionMatch[2], - patch: +globalVersionMatch[3], - prerelease: globalVersionMatch[4] - }; - if (globalVersionParsed.prerelease != null) { - return _reject(globalVersion); - } - if (ownVersionParsed.major !== globalVersionParsed.major) { - return _reject(globalVersion); - } - if (ownVersionParsed.major === 0) { - if (ownVersionParsed.minor === globalVersionParsed.minor && ownVersionParsed.patch <= globalVersionParsed.patch) { - return _accept(globalVersion); - } - return _reject(globalVersion); - } - if (ownVersionParsed.minor <= globalVersionParsed.minor) { - return _accept(globalVersion); - } - return _reject(globalVersion); - }, "isCompatible"); - } - __name(_makeCompatibilityCheck, "_makeCompatibilityCheck"); - exports._makeCompatibilityCheck = _makeCompatibilityCheck; - exports.isCompatible = _makeCompatibilityCheck(version_1.VERSION); - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/internal/global-utils.js -var require_global_utils = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/internal/global-utils.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.unregisterGlobal = exports.getGlobal = exports.registerGlobal = void 0; - var platform_1 = require_platform(); - var version_1 = require_version(); - var semver_1 = require_semver(); - var major = version_1.VERSION.split(".")[0]; - var GLOBAL_OPENTELEMETRY_API_KEY = Symbol.for(\`opentelemetry.js.api.\${major}\`); - var _global = platform_1._globalThis; - function registerGlobal(type, instance, diag, allowOverride = false) { - var _a17; - const api = _global[GLOBAL_OPENTELEMETRY_API_KEY] = (_a17 = _global[GLOBAL_OPENTELEMETRY_API_KEY]) !== null && _a17 !== void 0 ? _a17 : { - version: version_1.VERSION - }; - if (!allowOverride && api[type]) { - const err = new Error(\`@opentelemetry/api: Attempted duplicate registration of API: \${type}\`); - diag.error(err.stack || err.message); - return false; - } - if (api.version !== version_1.VERSION) { - const err = new Error(\`@opentelemetry/api: Registration of version v\${api.version} for \${type} does not match previously registered API v\${version_1.VERSION}\`); - diag.error(err.stack || err.message); - return false; - } - api[type] = instance; - diag.debug(\`@opentelemetry/api: Registered a global for \${type} v\${version_1.VERSION}.\`); - return true; - } - __name(registerGlobal, "registerGlobal"); - exports.registerGlobal = registerGlobal; - function getGlobal(type) { - var _a17, _b8; - const globalVersion = (_a17 = _global[GLOBAL_OPENTELEMETRY_API_KEY]) === null || _a17 === void 0 ? void 0 : _a17.version; - if (!globalVersion || !(0, semver_1.isCompatible)(globalVersion)) { - return; - } - return (_b8 = _global[GLOBAL_OPENTELEMETRY_API_KEY]) === null || _b8 === void 0 ? void 0 : _b8[type]; - } - __name(getGlobal, "getGlobal"); - exports.getGlobal = getGlobal; - function unregisterGlobal(type, diag) { - diag.debug(\`@opentelemetry/api: Unregistering a global for \${type} v\${version_1.VERSION}.\`); - const api = _global[GLOBAL_OPENTELEMETRY_API_KEY]; - if (api) { - delete api[type]; - } - } - __name(unregisterGlobal, "unregisterGlobal"); - exports.unregisterGlobal = unregisterGlobal; - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/diag/ComponentLogger.js -var require_ComponentLogger = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/diag/ComponentLogger.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.DiagComponentLogger = void 0; - var global_utils_1 = require_global_utils(); - var DiagComponentLogger = class { - static { - __name(this, "DiagComponentLogger"); - } - constructor(props) { - this._namespace = props.namespace || "DiagComponentLogger"; - } - debug(...args) { - return logProxy("debug", this._namespace, args); - } - error(...args) { - return logProxy("error", this._namespace, args); - } - info(...args) { - return logProxy("info", this._namespace, args); - } - warn(...args) { - return logProxy("warn", this._namespace, args); - } - verbose(...args) { - return logProxy("verbose", this._namespace, args); - } - }; - exports.DiagComponentLogger = DiagComponentLogger; - function logProxy(funcName, namespace, args) { - const logger = (0, global_utils_1.getGlobal)("diag"); - if (!logger) { - return; - } - args.unshift(namespace); - return logger[funcName](...args); - } - __name(logProxy, "logProxy"); - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/diag/types.js -var require_types = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/diag/types.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.DiagLogLevel = void 0; - var DiagLogLevel; - (function(DiagLogLevel2) { - DiagLogLevel2[DiagLogLevel2["NONE"] = 0] = "NONE"; - DiagLogLevel2[DiagLogLevel2["ERROR"] = 30] = "ERROR"; - DiagLogLevel2[DiagLogLevel2["WARN"] = 50] = "WARN"; - DiagLogLevel2[DiagLogLevel2["INFO"] = 60] = "INFO"; - DiagLogLevel2[DiagLogLevel2["DEBUG"] = 70] = "DEBUG"; - DiagLogLevel2[DiagLogLevel2["VERBOSE"] = 80] = "VERBOSE"; - DiagLogLevel2[DiagLogLevel2["ALL"] = 9999] = "ALL"; - })(DiagLogLevel = exports.DiagLogLevel || (exports.DiagLogLevel = {})); - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/diag/internal/logLevelLogger.js -var require_logLevelLogger = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/diag/internal/logLevelLogger.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.createLogLevelDiagLogger = void 0; - var types_1 = require_types(); - function createLogLevelDiagLogger(maxLevel, logger) { - if (maxLevel < types_1.DiagLogLevel.NONE) { - maxLevel = types_1.DiagLogLevel.NONE; - } else if (maxLevel > types_1.DiagLogLevel.ALL) { - maxLevel = types_1.DiagLogLevel.ALL; - } - logger = logger || {}; - function _filterFunc(funcName, theLevel) { - const theFunc = logger[funcName]; - if (typeof theFunc === "function" && maxLevel >= theLevel) { - return theFunc.bind(logger); - } - return function() { - }; - } - __name(_filterFunc, "_filterFunc"); - return { - error: _filterFunc("error", types_1.DiagLogLevel.ERROR), - warn: _filterFunc("warn", types_1.DiagLogLevel.WARN), - info: _filterFunc("info", types_1.DiagLogLevel.INFO), - debug: _filterFunc("debug", types_1.DiagLogLevel.DEBUG), - verbose: _filterFunc("verbose", types_1.DiagLogLevel.VERBOSE) - }; - } - __name(createLogLevelDiagLogger, "createLogLevelDiagLogger"); - exports.createLogLevelDiagLogger = createLogLevelDiagLogger; - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/api/diag.js -var require_diag = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/api/diag.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.DiagAPI = void 0; - var ComponentLogger_1 = require_ComponentLogger(); - var logLevelLogger_1 = require_logLevelLogger(); - var types_1 = require_types(); - var global_utils_1 = require_global_utils(); - var API_NAME = "diag"; - var DiagAPI = class _DiagAPI { - static { - __name(this, "DiagAPI"); - } - /** - * Private internal constructor - * @private - */ - constructor() { - function _logProxy(funcName) { - return function(...args) { - const logger = (0, global_utils_1.getGlobal)("diag"); - if (!logger) return; - return logger[funcName](...args); - }; - } - __name(_logProxy, "_logProxy"); - const self = this; - const setLogger = /* @__PURE__ */ __name((logger, optionsOrLogLevel = { - logLevel: types_1.DiagLogLevel.INFO - }) => { - var _a17, _b8, _c; - if (logger === self) { - const err = new Error("Cannot use diag as the logger for itself. Please use a DiagLogger implementation like ConsoleDiagLogger or a custom implementation"); - self.error((_a17 = err.stack) !== null && _a17 !== void 0 ? _a17 : err.message); - return false; - } - if (typeof optionsOrLogLevel === "number") { - optionsOrLogLevel = { - logLevel: optionsOrLogLevel - }; - } - const oldLogger = (0, global_utils_1.getGlobal)("diag"); - const newLogger = (0, logLevelLogger_1.createLogLevelDiagLogger)((_b8 = optionsOrLogLevel.logLevel) !== null && _b8 !== void 0 ? _b8 : types_1.DiagLogLevel.INFO, logger); - if (oldLogger && !optionsOrLogLevel.suppressOverrideMessage) { - const stack = (_c = new Error().stack) !== null && _c !== void 0 ? _c : ""; - oldLogger.warn(\`Current logger will be overwritten from \${stack}\`); - newLogger.warn(\`Current logger will overwrite one already registered from \${stack}\`); - } - return (0, global_utils_1.registerGlobal)("diag", newLogger, self, true); - }, "setLogger"); - self.setLogger = setLogger; - self.disable = () => { - (0, global_utils_1.unregisterGlobal)(API_NAME, self); - }; - self.createComponentLogger = (options) => { - return new ComponentLogger_1.DiagComponentLogger(options); - }; - self.verbose = _logProxy("verbose"); - self.debug = _logProxy("debug"); - self.info = _logProxy("info"); - self.warn = _logProxy("warn"); - self.error = _logProxy("error"); - } - /** Get the singleton instance of the DiagAPI API */ - static instance() { - if (!this._instance) { - this._instance = new _DiagAPI(); - } - return this._instance; - } - }; - exports.DiagAPI = DiagAPI; - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/baggage/internal/baggage-impl.js -var require_baggage_impl = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/baggage/internal/baggage-impl.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.BaggageImpl = void 0; - var BaggageImpl = class _BaggageImpl { - static { - __name(this, "BaggageImpl"); - } - constructor(entries) { - this._entries = entries ? new Map(entries) : /* @__PURE__ */ new Map(); - } - getEntry(key) { - const entry = this._entries.get(key); - if (!entry) { - return void 0; - } - return Object.assign({}, entry); - } - getAllEntries() { - return Array.from(this._entries.entries()).map(([k, v]) => [ - k, - v - ]); - } - setEntry(key, entry) { - const newBaggage = new _BaggageImpl(this._entries); - newBaggage._entries.set(key, entry); - return newBaggage; - } - removeEntry(key) { - const newBaggage = new _BaggageImpl(this._entries); - newBaggage._entries.delete(key); - return newBaggage; - } - removeEntries(...keys) { - const newBaggage = new _BaggageImpl(this._entries); - for (const key of keys) { - newBaggage._entries.delete(key); - } - return newBaggage; - } - clear() { - return new _BaggageImpl(); - } - }; - exports.BaggageImpl = BaggageImpl; - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/baggage/internal/symbol.js -var require_symbol = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/baggage/internal/symbol.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.baggageEntryMetadataSymbol = void 0; - exports.baggageEntryMetadataSymbol = Symbol("BaggageEntryMetadata"); - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/baggage/utils.js -var require_utils = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/baggage/utils.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.baggageEntryMetadataFromString = exports.createBaggage = void 0; - var diag_1 = require_diag(); - var baggage_impl_1 = require_baggage_impl(); - var symbol_1 = require_symbol(); - var diag = diag_1.DiagAPI.instance(); - function createBaggage(entries = {}) { - return new baggage_impl_1.BaggageImpl(new Map(Object.entries(entries))); - } - __name(createBaggage, "createBaggage"); - exports.createBaggage = createBaggage; - function baggageEntryMetadataFromString(str) { - if (typeof str !== "string") { - diag.error(\`Cannot create baggage metadata from unknown type: \${typeof str}\`); - str = ""; - } - return { - __TYPE__: symbol_1.baggageEntryMetadataSymbol, - toString() { - return str; - } - }; - } - __name(baggageEntryMetadataFromString, "baggageEntryMetadataFromString"); - exports.baggageEntryMetadataFromString = baggageEntryMetadataFromString; - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/context/context.js -var require_context = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/context/context.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.ROOT_CONTEXT = exports.createContextKey = void 0; - function createContextKey(description) { - return Symbol.for(description); - } - __name(createContextKey, "createContextKey"); - exports.createContextKey = createContextKey; - var BaseContext = class _BaseContext { - static { - __name(this, "BaseContext"); - } - /** - * Construct a new context which inherits values from an optional parent context. - * - * @param parentContext a context from which to inherit values - */ - constructor(parentContext) { - const self = this; - self._currentContext = parentContext ? new Map(parentContext) : /* @__PURE__ */ new Map(); - self.getValue = (key) => self._currentContext.get(key); - self.setValue = (key, value) => { - const context = new _BaseContext(self._currentContext); - context._currentContext.set(key, value); - return context; - }; - self.deleteValue = (key) => { - const context = new _BaseContext(self._currentContext); - context._currentContext.delete(key); - return context; - }; - } - }; - exports.ROOT_CONTEXT = new BaseContext(); - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/diag/consoleLogger.js -var require_consoleLogger = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/diag/consoleLogger.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.DiagConsoleLogger = void 0; - var consoleMap = [ - { - n: "error", - c: "error" - }, - { - n: "warn", - c: "warn" - }, - { - n: "info", - c: "info" - }, - { - n: "debug", - c: "debug" - }, - { - n: "verbose", - c: "trace" - } - ]; - var DiagConsoleLogger = class { - static { - __name(this, "DiagConsoleLogger"); - } - constructor() { - function _consoleFunc(funcName) { - return function(...args) { - if (console) { - let theFunc = console[funcName]; - if (typeof theFunc !== "function") { - theFunc = console.log; - } - if (typeof theFunc === "function") { - return theFunc.apply(console, args); - } - } - }; - } - __name(_consoleFunc, "_consoleFunc"); - for (let i = 0; i < consoleMap.length; i++) { - this[consoleMap[i].n] = _consoleFunc(consoleMap[i].c); - } - } - }; - exports.DiagConsoleLogger = DiagConsoleLogger; - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/metrics/NoopMeter.js -var require_NoopMeter = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/metrics/NoopMeter.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.createNoopMeter = exports.NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC = exports.NOOP_OBSERVABLE_GAUGE_METRIC = exports.NOOP_OBSERVABLE_COUNTER_METRIC = exports.NOOP_UP_DOWN_COUNTER_METRIC = exports.NOOP_HISTOGRAM_METRIC = exports.NOOP_GAUGE_METRIC = exports.NOOP_COUNTER_METRIC = exports.NOOP_METER = exports.NoopObservableUpDownCounterMetric = exports.NoopObservableGaugeMetric = exports.NoopObservableCounterMetric = exports.NoopObservableMetric = exports.NoopHistogramMetric = exports.NoopGaugeMetric = exports.NoopUpDownCounterMetric = exports.NoopCounterMetric = exports.NoopMetric = exports.NoopMeter = void 0; - var NoopMeter = class { - static { - __name(this, "NoopMeter"); - } - constructor() { - } - /** - * @see {@link Meter.createGauge} - */ - createGauge(_name, _options) { - return exports.NOOP_GAUGE_METRIC; - } - /** - * @see {@link Meter.createHistogram} - */ - createHistogram(_name, _options) { - return exports.NOOP_HISTOGRAM_METRIC; - } - /** - * @see {@link Meter.createCounter} - */ - createCounter(_name, _options) { - return exports.NOOP_COUNTER_METRIC; - } - /** - * @see {@link Meter.createUpDownCounter} - */ - createUpDownCounter(_name, _options) { - return exports.NOOP_UP_DOWN_COUNTER_METRIC; - } - /** - * @see {@link Meter.createObservableGauge} - */ - createObservableGauge(_name, _options) { - return exports.NOOP_OBSERVABLE_GAUGE_METRIC; - } - /** - * @see {@link Meter.createObservableCounter} - */ - createObservableCounter(_name, _options) { - return exports.NOOP_OBSERVABLE_COUNTER_METRIC; - } - /** - * @see {@link Meter.createObservableUpDownCounter} - */ - createObservableUpDownCounter(_name, _options) { - return exports.NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC; - } - /** - * @see {@link Meter.addBatchObservableCallback} - */ - addBatchObservableCallback(_callback, _observables) { - } - /** - * @see {@link Meter.removeBatchObservableCallback} - */ - removeBatchObservableCallback(_callback) { - } - }; - exports.NoopMeter = NoopMeter; - var NoopMetric = class { - static { - __name(this, "NoopMetric"); - } - }; - exports.NoopMetric = NoopMetric; - var NoopCounterMetric = class extends NoopMetric { - static { - __name(this, "NoopCounterMetric"); - } - add(_value, _attributes) { - } - }; - exports.NoopCounterMetric = NoopCounterMetric; - var NoopUpDownCounterMetric = class extends NoopMetric { - static { - __name(this, "NoopUpDownCounterMetric"); - } - add(_value, _attributes) { - } - }; - exports.NoopUpDownCounterMetric = NoopUpDownCounterMetric; - var NoopGaugeMetric = class extends NoopMetric { - static { - __name(this, "NoopGaugeMetric"); - } - record(_value, _attributes) { - } - }; - exports.NoopGaugeMetric = NoopGaugeMetric; - var NoopHistogramMetric = class extends NoopMetric { - static { - __name(this, "NoopHistogramMetric"); - } - record(_value, _attributes) { - } - }; - exports.NoopHistogramMetric = NoopHistogramMetric; - var NoopObservableMetric = class { - static { - __name(this, "NoopObservableMetric"); - } - addCallback(_callback) { - } - removeCallback(_callback) { - } - }; - exports.NoopObservableMetric = NoopObservableMetric; - var NoopObservableCounterMetric = class extends NoopObservableMetric { - static { - __name(this, "NoopObservableCounterMetric"); - } - }; - exports.NoopObservableCounterMetric = NoopObservableCounterMetric; - var NoopObservableGaugeMetric = class extends NoopObservableMetric { - static { - __name(this, "NoopObservableGaugeMetric"); - } - }; - exports.NoopObservableGaugeMetric = NoopObservableGaugeMetric; - var NoopObservableUpDownCounterMetric = class extends NoopObservableMetric { - static { - __name(this, "NoopObservableUpDownCounterMetric"); - } - }; - exports.NoopObservableUpDownCounterMetric = NoopObservableUpDownCounterMetric; - exports.NOOP_METER = new NoopMeter(); - exports.NOOP_COUNTER_METRIC = new NoopCounterMetric(); - exports.NOOP_GAUGE_METRIC = new NoopGaugeMetric(); - exports.NOOP_HISTOGRAM_METRIC = new NoopHistogramMetric(); - exports.NOOP_UP_DOWN_COUNTER_METRIC = new NoopUpDownCounterMetric(); - exports.NOOP_OBSERVABLE_COUNTER_METRIC = new NoopObservableCounterMetric(); - exports.NOOP_OBSERVABLE_GAUGE_METRIC = new NoopObservableGaugeMetric(); - exports.NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC = new NoopObservableUpDownCounterMetric(); - function createNoopMeter() { - return exports.NOOP_METER; - } - __name(createNoopMeter, "createNoopMeter"); - exports.createNoopMeter = createNoopMeter; - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/metrics/Metric.js -var require_Metric = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/metrics/Metric.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.ValueType = void 0; - var ValueType; - (function(ValueType2) { - ValueType2[ValueType2["INT"] = 0] = "INT"; - ValueType2[ValueType2["DOUBLE"] = 1] = "DOUBLE"; - })(ValueType = exports.ValueType || (exports.ValueType = {})); - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/propagation/TextMapPropagator.js -var require_TextMapPropagator = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/propagation/TextMapPropagator.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.defaultTextMapSetter = exports.defaultTextMapGetter = void 0; - exports.defaultTextMapGetter = { - get(carrier, key) { - if (carrier == null) { - return void 0; - } - return carrier[key]; - }, - keys(carrier) { - if (carrier == null) { - return []; - } - return Object.keys(carrier); - } - }; - exports.defaultTextMapSetter = { - set(carrier, key, value) { - if (carrier == null) { - return; - } - carrier[key] = value; - } - }; - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/context/NoopContextManager.js -var require_NoopContextManager = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/context/NoopContextManager.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.NoopContextManager = void 0; - var context_1 = require_context(); - var NoopContextManager = class { - static { - __name(this, "NoopContextManager"); - } - active() { - return context_1.ROOT_CONTEXT; - } - with(_context, fn, thisArg, ...args) { - return fn.call(thisArg, ...args); - } - bind(_context, target) { - return target; - } - enable() { - return this; - } - disable() { - return this; - } - }; - exports.NoopContextManager = NoopContextManager; - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/api/context.js -var require_context2 = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/api/context.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.ContextAPI = void 0; - var NoopContextManager_1 = require_NoopContextManager(); - var global_utils_1 = require_global_utils(); - var diag_1 = require_diag(); - var API_NAME = "context"; - var NOOP_CONTEXT_MANAGER = new NoopContextManager_1.NoopContextManager(); - var ContextAPI = class _ContextAPI { - static { - __name(this, "ContextAPI"); - } - /** Empty private constructor prevents end users from constructing a new instance of the API */ - constructor() { - } - /** Get the singleton instance of the Context API */ - static getInstance() { - if (!this._instance) { - this._instance = new _ContextAPI(); - } - return this._instance; - } - /** - * Set the current context manager. - * - * @returns true if the context manager was successfully registered, else false - */ - setGlobalContextManager(contextManager) { - return (0, global_utils_1.registerGlobal)(API_NAME, contextManager, diag_1.DiagAPI.instance()); - } - /** - * Get the currently active context - */ - active() { - return this._getContextManager().active(); - } - /** - * Execute a function with an active context - * - * @param context context to be active during function execution - * @param fn function to execute in a context - * @param thisArg optional receiver to be used for calling fn - * @param args optional arguments forwarded to fn - */ - with(context, fn, thisArg, ...args) { - return this._getContextManager().with(context, fn, thisArg, ...args); - } - /** - * Bind a context to a target function or event emitter - * - * @param context context to bind to the event emitter or function. Defaults to the currently active context - * @param target function or event emitter to bind - */ - bind(context, target) { - return this._getContextManager().bind(context, target); - } - _getContextManager() { - return (0, global_utils_1.getGlobal)(API_NAME) || NOOP_CONTEXT_MANAGER; - } - /** Disable and remove the global context manager */ - disable() { - this._getContextManager().disable(); - (0, global_utils_1.unregisterGlobal)(API_NAME, diag_1.DiagAPI.instance()); - } - }; - exports.ContextAPI = ContextAPI; - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/trace_flags.js -var require_trace_flags = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/trace_flags.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.TraceFlags = void 0; - var TraceFlags; - (function(TraceFlags2) { - TraceFlags2[TraceFlags2["NONE"] = 0] = "NONE"; - TraceFlags2[TraceFlags2["SAMPLED"] = 1] = "SAMPLED"; - })(TraceFlags = exports.TraceFlags || (exports.TraceFlags = {})); - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/invalid-span-constants.js -var require_invalid_span_constants = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/invalid-span-constants.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.INVALID_SPAN_CONTEXT = exports.INVALID_TRACEID = exports.INVALID_SPANID = void 0; - var trace_flags_1 = require_trace_flags(); - exports.INVALID_SPANID = "0000000000000000"; - exports.INVALID_TRACEID = "00000000000000000000000000000000"; - exports.INVALID_SPAN_CONTEXT = { - traceId: exports.INVALID_TRACEID, - spanId: exports.INVALID_SPANID, - traceFlags: trace_flags_1.TraceFlags.NONE - }; - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/NonRecordingSpan.js -var require_NonRecordingSpan = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/NonRecordingSpan.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.NonRecordingSpan = void 0; - var invalid_span_constants_1 = require_invalid_span_constants(); - var NonRecordingSpan = class { - static { - __name(this, "NonRecordingSpan"); - } - constructor(_spanContext = invalid_span_constants_1.INVALID_SPAN_CONTEXT) { - this._spanContext = _spanContext; - } - // Returns a SpanContext. - spanContext() { - return this._spanContext; - } - // By default does nothing - setAttribute(_key, _value) { - return this; - } - // By default does nothing - setAttributes(_attributes) { - return this; - } - // By default does nothing - addEvent(_name, _attributes) { - return this; - } - addLink(_link) { - return this; - } - addLinks(_links) { - return this; - } - // By default does nothing - setStatus(_status) { - return this; - } - // By default does nothing - updateName(_name) { - return this; - } - // By default does nothing - end(_endTime) { - } - // isRecording always returns false for NonRecordingSpan. - isRecording() { - return false; - } - // By default does nothing - recordException(_exception, _time) { - } - }; - exports.NonRecordingSpan = NonRecordingSpan; - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/context-utils.js -var require_context_utils = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/context-utils.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.getSpanContext = exports.setSpanContext = exports.deleteSpan = exports.setSpan = exports.getActiveSpan = exports.getSpan = void 0; - var context_1 = require_context(); - var NonRecordingSpan_1 = require_NonRecordingSpan(); - var context_2 = require_context2(); - var SPAN_KEY = (0, context_1.createContextKey)("OpenTelemetry Context Key SPAN"); - function getSpan(context) { - return context.getValue(SPAN_KEY) || void 0; - } - __name(getSpan, "getSpan"); - exports.getSpan = getSpan; - function getActiveSpan() { - return getSpan(context_2.ContextAPI.getInstance().active()); - } - __name(getActiveSpan, "getActiveSpan"); - exports.getActiveSpan = getActiveSpan; - function setSpan(context, span) { - return context.setValue(SPAN_KEY, span); - } - __name(setSpan, "setSpan"); - exports.setSpan = setSpan; - function deleteSpan(context) { - return context.deleteValue(SPAN_KEY); - } - __name(deleteSpan, "deleteSpan"); - exports.deleteSpan = deleteSpan; - function setSpanContext(context, spanContext) { - return setSpan(context, new NonRecordingSpan_1.NonRecordingSpan(spanContext)); - } - __name(setSpanContext, "setSpanContext"); - exports.setSpanContext = setSpanContext; - function getSpanContext(context) { - var _a17; - return (_a17 = getSpan(context)) === null || _a17 === void 0 ? void 0 : _a17.spanContext(); - } - __name(getSpanContext, "getSpanContext"); - exports.getSpanContext = getSpanContext; - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/spancontext-utils.js -var require_spancontext_utils = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/spancontext-utils.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.wrapSpanContext = exports.isSpanContextValid = exports.isValidSpanId = exports.isValidTraceId = void 0; - var invalid_span_constants_1 = require_invalid_span_constants(); - var NonRecordingSpan_1 = require_NonRecordingSpan(); - var VALID_TRACEID_REGEX = /^([0-9a-f]{32})\$/i; - var VALID_SPANID_REGEX = /^[0-9a-f]{16}\$/i; - function isValidTraceId(traceId) { - return VALID_TRACEID_REGEX.test(traceId) && traceId !== invalid_span_constants_1.INVALID_TRACEID; - } - __name(isValidTraceId, "isValidTraceId"); - exports.isValidTraceId = isValidTraceId; - function isValidSpanId(spanId) { - return VALID_SPANID_REGEX.test(spanId) && spanId !== invalid_span_constants_1.INVALID_SPANID; - } - __name(isValidSpanId, "isValidSpanId"); - exports.isValidSpanId = isValidSpanId; - function isSpanContextValid(spanContext) { - return isValidTraceId(spanContext.traceId) && isValidSpanId(spanContext.spanId); - } - __name(isSpanContextValid, "isSpanContextValid"); - exports.isSpanContextValid = isSpanContextValid; - function wrapSpanContext(spanContext) { - return new NonRecordingSpan_1.NonRecordingSpan(spanContext); - } - __name(wrapSpanContext, "wrapSpanContext"); - exports.wrapSpanContext = wrapSpanContext; - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/NoopTracer.js -var require_NoopTracer = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/NoopTracer.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.NoopTracer = void 0; - var context_1 = require_context2(); - var context_utils_1 = require_context_utils(); - var NonRecordingSpan_1 = require_NonRecordingSpan(); - var spancontext_utils_1 = require_spancontext_utils(); - var contextApi = context_1.ContextAPI.getInstance(); - var NoopTracer = class { - static { - __name(this, "NoopTracer"); - } - // startSpan starts a noop span. - startSpan(name17, options, context = contextApi.active()) { - const root = Boolean(options === null || options === void 0 ? void 0 : options.root); - if (root) { - return new NonRecordingSpan_1.NonRecordingSpan(); - } - const parentFromContext = context && (0, context_utils_1.getSpanContext)(context); - if (isSpanContext(parentFromContext) && (0, spancontext_utils_1.isSpanContextValid)(parentFromContext)) { - return new NonRecordingSpan_1.NonRecordingSpan(parentFromContext); - } else { - return new NonRecordingSpan_1.NonRecordingSpan(); - } - } - startActiveSpan(name17, arg2, arg3, arg4) { - let opts; - let ctx; - let fn; - if (arguments.length < 2) { - return; - } else if (arguments.length === 2) { - fn = arg2; - } else if (arguments.length === 3) { - opts = arg2; - fn = arg3; - } else { - opts = arg2; - ctx = arg3; - fn = arg4; - } - const parentContext = ctx !== null && ctx !== void 0 ? ctx : contextApi.active(); - const span = this.startSpan(name17, opts, parentContext); - const contextWithSpanSet = (0, context_utils_1.setSpan)(parentContext, span); - return contextApi.with(contextWithSpanSet, fn, void 0, span); - } - }; - exports.NoopTracer = NoopTracer; - function isSpanContext(spanContext) { - return typeof spanContext === "object" && typeof spanContext["spanId"] === "string" && typeof spanContext["traceId"] === "string" && typeof spanContext["traceFlags"] === "number"; - } - __name(isSpanContext, "isSpanContext"); - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/ProxyTracer.js -var require_ProxyTracer = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/ProxyTracer.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.ProxyTracer = void 0; - var NoopTracer_1 = require_NoopTracer(); - var NOOP_TRACER = new NoopTracer_1.NoopTracer(); - var ProxyTracer = class { - static { - __name(this, "ProxyTracer"); - } - constructor(_provider, name17, version2, options) { - this._provider = _provider; - this.name = name17; - this.version = version2; - this.options = options; - } - startSpan(name17, options, context) { - return this._getTracer().startSpan(name17, options, context); - } - startActiveSpan(_name, _options, _context, _fn) { - const tracer = this._getTracer(); - return Reflect.apply(tracer.startActiveSpan, tracer, arguments); - } - /** - * Try to get a tracer from the proxy tracer provider. - * If the proxy tracer provider has no delegate, return a noop tracer. - */ - _getTracer() { - if (this._delegate) { - return this._delegate; - } - const tracer = this._provider.getDelegateTracer(this.name, this.version, this.options); - if (!tracer) { - return NOOP_TRACER; - } - this._delegate = tracer; - return this._delegate; - } - }; - exports.ProxyTracer = ProxyTracer; - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/NoopTracerProvider.js -var require_NoopTracerProvider = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/NoopTracerProvider.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.NoopTracerProvider = void 0; - var NoopTracer_1 = require_NoopTracer(); - var NoopTracerProvider = class { - static { - __name(this, "NoopTracerProvider"); - } - getTracer(_name, _version, _options) { - return new NoopTracer_1.NoopTracer(); - } - }; - exports.NoopTracerProvider = NoopTracerProvider; - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/ProxyTracerProvider.js -var require_ProxyTracerProvider = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/ProxyTracerProvider.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.ProxyTracerProvider = void 0; - var ProxyTracer_1 = require_ProxyTracer(); - var NoopTracerProvider_1 = require_NoopTracerProvider(); - var NOOP_TRACER_PROVIDER = new NoopTracerProvider_1.NoopTracerProvider(); - var ProxyTracerProvider = class { - static { - __name(this, "ProxyTracerProvider"); - } - /** - * Get a {@link ProxyTracer} - */ - getTracer(name17, version2, options) { - var _a17; - return (_a17 = this.getDelegateTracer(name17, version2, options)) !== null && _a17 !== void 0 ? _a17 : new ProxyTracer_1.ProxyTracer(this, name17, version2, options); - } - getDelegate() { - var _a17; - return (_a17 = this._delegate) !== null && _a17 !== void 0 ? _a17 : NOOP_TRACER_PROVIDER; - } - /** - * Set the delegate tracer provider - */ - setDelegate(delegate) { - this._delegate = delegate; - } - getDelegateTracer(name17, version2, options) { - var _a17; - return (_a17 = this._delegate) === null || _a17 === void 0 ? void 0 : _a17.getTracer(name17, version2, options); - } - }; - exports.ProxyTracerProvider = ProxyTracerProvider; - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/SamplingResult.js -var require_SamplingResult = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/SamplingResult.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.SamplingDecision = void 0; - var SamplingDecision; - (function(SamplingDecision2) { - SamplingDecision2[SamplingDecision2["NOT_RECORD"] = 0] = "NOT_RECORD"; - SamplingDecision2[SamplingDecision2["RECORD"] = 1] = "RECORD"; - SamplingDecision2[SamplingDecision2["RECORD_AND_SAMPLED"] = 2] = "RECORD_AND_SAMPLED"; - })(SamplingDecision = exports.SamplingDecision || (exports.SamplingDecision = {})); - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/span_kind.js -var require_span_kind = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/span_kind.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.SpanKind = void 0; - var SpanKind; - (function(SpanKind2) { - SpanKind2[SpanKind2["INTERNAL"] = 0] = "INTERNAL"; - SpanKind2[SpanKind2["SERVER"] = 1] = "SERVER"; - SpanKind2[SpanKind2["CLIENT"] = 2] = "CLIENT"; - SpanKind2[SpanKind2["PRODUCER"] = 3] = "PRODUCER"; - SpanKind2[SpanKind2["CONSUMER"] = 4] = "CONSUMER"; - })(SpanKind = exports.SpanKind || (exports.SpanKind = {})); - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/status.js -var require_status = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/status.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.SpanStatusCode = void 0; - var SpanStatusCode2; - (function(SpanStatusCode3) { - SpanStatusCode3[SpanStatusCode3["UNSET"] = 0] = "UNSET"; - SpanStatusCode3[SpanStatusCode3["OK"] = 1] = "OK"; - SpanStatusCode3[SpanStatusCode3["ERROR"] = 2] = "ERROR"; - })(SpanStatusCode2 = exports.SpanStatusCode || (exports.SpanStatusCode = {})); - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/internal/tracestate-validators.js -var require_tracestate_validators = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/internal/tracestate-validators.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.validateValue = exports.validateKey = void 0; - var VALID_KEY_CHAR_RANGE = "[_0-9a-z-*/]"; - var VALID_KEY = \`[a-z]\${VALID_KEY_CHAR_RANGE}{0,255}\`; - var VALID_VENDOR_KEY = \`[a-z0-9]\${VALID_KEY_CHAR_RANGE}{0,240}@[a-z]\${VALID_KEY_CHAR_RANGE}{0,13}\`; - var VALID_KEY_REGEX = new RegExp(\`^(?:\${VALID_KEY}|\${VALID_VENDOR_KEY})\$\`); - var VALID_VALUE_BASE_REGEX = /^[ -~]{0,255}[!-~]\$/; - var INVALID_VALUE_COMMA_EQUAL_REGEX = /,|=/; - function validateKey(key) { - return VALID_KEY_REGEX.test(key); - } - __name(validateKey, "validateKey"); - exports.validateKey = validateKey; - function validateValue(value) { - return VALID_VALUE_BASE_REGEX.test(value) && !INVALID_VALUE_COMMA_EQUAL_REGEX.test(value); - } - __name(validateValue, "validateValue"); - exports.validateValue = validateValue; - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/internal/tracestate-impl.js -var require_tracestate_impl = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/internal/tracestate-impl.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.TraceStateImpl = void 0; - var tracestate_validators_1 = require_tracestate_validators(); - var MAX_TRACE_STATE_ITEMS = 32; - var MAX_TRACE_STATE_LEN = 512; - var LIST_MEMBERS_SEPARATOR = ","; - var LIST_MEMBER_KEY_VALUE_SPLITTER = "="; - var TraceStateImpl = class _TraceStateImpl { - static { - __name(this, "TraceStateImpl"); - } - constructor(rawTraceState) { - this._internalState = /* @__PURE__ */ new Map(); - if (rawTraceState) this._parse(rawTraceState); - } - set(key, value) { - const traceState = this._clone(); - if (traceState._internalState.has(key)) { - traceState._internalState.delete(key); - } - traceState._internalState.set(key, value); - return traceState; - } - unset(key) { - const traceState = this._clone(); - traceState._internalState.delete(key); - return traceState; - } - get(key) { - return this._internalState.get(key); - } - serialize() { - return this._keys().reduce((agg, key) => { - agg.push(key + LIST_MEMBER_KEY_VALUE_SPLITTER + this.get(key)); - return agg; - }, []).join(LIST_MEMBERS_SEPARATOR); - } - _parse(rawTraceState) { - if (rawTraceState.length > MAX_TRACE_STATE_LEN) return; - this._internalState = rawTraceState.split(LIST_MEMBERS_SEPARATOR).reverse().reduce((agg, part) => { - const listMember = part.trim(); - const i = listMember.indexOf(LIST_MEMBER_KEY_VALUE_SPLITTER); - if (i !== -1) { - const key = listMember.slice(0, i); - const value = listMember.slice(i + 1, part.length); - if ((0, tracestate_validators_1.validateKey)(key) && (0, tracestate_validators_1.validateValue)(value)) { - agg.set(key, value); - } else { - } - } - return agg; - }, /* @__PURE__ */ new Map()); - if (this._internalState.size > MAX_TRACE_STATE_ITEMS) { - this._internalState = new Map(Array.from(this._internalState.entries()).reverse().slice(0, MAX_TRACE_STATE_ITEMS)); - } - } - _keys() { - return Array.from(this._internalState.keys()).reverse(); - } - _clone() { - const traceState = new _TraceStateImpl(); - traceState._internalState = new Map(this._internalState); - return traceState; - } - }; - exports.TraceStateImpl = TraceStateImpl; - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/internal/utils.js -var require_utils2 = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace/internal/utils.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.createTraceState = void 0; - var tracestate_impl_1 = require_tracestate_impl(); - function createTraceState(rawTraceState) { - return new tracestate_impl_1.TraceStateImpl(rawTraceState); - } - __name(createTraceState, "createTraceState"); - exports.createTraceState = createTraceState; - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/context-api.js -var require_context_api = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/context-api.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.context = void 0; - var context_1 = require_context2(); - exports.context = context_1.ContextAPI.getInstance(); - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/diag-api.js -var require_diag_api = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/diag-api.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.diag = void 0; - var diag_1 = require_diag(); - exports.diag = diag_1.DiagAPI.instance(); - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/metrics/NoopMeterProvider.js -var require_NoopMeterProvider = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/metrics/NoopMeterProvider.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.NOOP_METER_PROVIDER = exports.NoopMeterProvider = void 0; - var NoopMeter_1 = require_NoopMeter(); - var NoopMeterProvider = class { - static { - __name(this, "NoopMeterProvider"); - } - getMeter(_name, _version, _options) { - return NoopMeter_1.NOOP_METER; - } - }; - exports.NoopMeterProvider = NoopMeterProvider; - exports.NOOP_METER_PROVIDER = new NoopMeterProvider(); - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/api/metrics.js -var require_metrics = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/api/metrics.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.MetricsAPI = void 0; - var NoopMeterProvider_1 = require_NoopMeterProvider(); - var global_utils_1 = require_global_utils(); - var diag_1 = require_diag(); - var API_NAME = "metrics"; - var MetricsAPI = class _MetricsAPI { - static { - __name(this, "MetricsAPI"); - } - /** Empty private constructor prevents end users from constructing a new instance of the API */ - constructor() { - } - /** Get the singleton instance of the Metrics API */ - static getInstance() { - if (!this._instance) { - this._instance = new _MetricsAPI(); - } - return this._instance; - } - /** - * Set the current global meter provider. - * Returns true if the meter provider was successfully registered, else false. - */ - setGlobalMeterProvider(provider) { - return (0, global_utils_1.registerGlobal)(API_NAME, provider, diag_1.DiagAPI.instance()); - } - /** - * Returns the global meter provider. - */ - getMeterProvider() { - return (0, global_utils_1.getGlobal)(API_NAME) || NoopMeterProvider_1.NOOP_METER_PROVIDER; - } - /** - * Returns a meter from the global meter provider. - */ - getMeter(name17, version2, options) { - return this.getMeterProvider().getMeter(name17, version2, options); - } - /** Remove the global meter provider */ - disable() { - (0, global_utils_1.unregisterGlobal)(API_NAME, diag_1.DiagAPI.instance()); - } - }; - exports.MetricsAPI = MetricsAPI; - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/metrics-api.js -var require_metrics_api = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/metrics-api.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.metrics = void 0; - var metrics_1 = require_metrics(); - exports.metrics = metrics_1.MetricsAPI.getInstance(); - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/propagation/NoopTextMapPropagator.js -var require_NoopTextMapPropagator = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/propagation/NoopTextMapPropagator.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.NoopTextMapPropagator = void 0; - var NoopTextMapPropagator = class { - static { - __name(this, "NoopTextMapPropagator"); - } - /** Noop inject function does nothing */ - inject(_context, _carrier) { - } - /** Noop extract function does nothing and returns the input context */ - extract(context, _carrier) { - return context; - } - fields() { - return []; - } - }; - exports.NoopTextMapPropagator = NoopTextMapPropagator; - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/baggage/context-helpers.js -var require_context_helpers = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/baggage/context-helpers.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.deleteBaggage = exports.setBaggage = exports.getActiveBaggage = exports.getBaggage = void 0; - var context_1 = require_context2(); - var context_2 = require_context(); - var BAGGAGE_KEY = (0, context_2.createContextKey)("OpenTelemetry Baggage Key"); - function getBaggage(context) { - return context.getValue(BAGGAGE_KEY) || void 0; - } - __name(getBaggage, "getBaggage"); - exports.getBaggage = getBaggage; - function getActiveBaggage() { - return getBaggage(context_1.ContextAPI.getInstance().active()); - } - __name(getActiveBaggage, "getActiveBaggage"); - exports.getActiveBaggage = getActiveBaggage; - function setBaggage(context, baggage) { - return context.setValue(BAGGAGE_KEY, baggage); - } - __name(setBaggage, "setBaggage"); - exports.setBaggage = setBaggage; - function deleteBaggage(context) { - return context.deleteValue(BAGGAGE_KEY); - } - __name(deleteBaggage, "deleteBaggage"); - exports.deleteBaggage = deleteBaggage; - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/api/propagation.js -var require_propagation = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/api/propagation.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.PropagationAPI = void 0; - var global_utils_1 = require_global_utils(); - var NoopTextMapPropagator_1 = require_NoopTextMapPropagator(); - var TextMapPropagator_1 = require_TextMapPropagator(); - var context_helpers_1 = require_context_helpers(); - var utils_1 = require_utils(); - var diag_1 = require_diag(); - var API_NAME = "propagation"; - var NOOP_TEXT_MAP_PROPAGATOR = new NoopTextMapPropagator_1.NoopTextMapPropagator(); - var PropagationAPI = class _PropagationAPI { - static { - __name(this, "PropagationAPI"); - } - /** Empty private constructor prevents end users from constructing a new instance of the API */ - constructor() { - this.createBaggage = utils_1.createBaggage; - this.getBaggage = context_helpers_1.getBaggage; - this.getActiveBaggage = context_helpers_1.getActiveBaggage; - this.setBaggage = context_helpers_1.setBaggage; - this.deleteBaggage = context_helpers_1.deleteBaggage; - } - /** Get the singleton instance of the Propagator API */ - static getInstance() { - if (!this._instance) { - this._instance = new _PropagationAPI(); - } - return this._instance; - } - /** - * Set the current propagator. - * - * @returns true if the propagator was successfully registered, else false - */ - setGlobalPropagator(propagator) { - return (0, global_utils_1.registerGlobal)(API_NAME, propagator, diag_1.DiagAPI.instance()); - } - /** - * Inject context into a carrier to be propagated inter-process - * - * @param context Context carrying tracing data to inject - * @param carrier carrier to inject context into - * @param setter Function used to set values on the carrier - */ - inject(context, carrier, setter = TextMapPropagator_1.defaultTextMapSetter) { - return this._getGlobalPropagator().inject(context, carrier, setter); - } - /** - * Extract context from a carrier - * - * @param context Context which the newly created context will inherit from - * @param carrier Carrier to extract context from - * @param getter Function used to extract keys from a carrier - */ - extract(context, carrier, getter = TextMapPropagator_1.defaultTextMapGetter) { - return this._getGlobalPropagator().extract(context, carrier, getter); - } - /** - * Return a list of all fields which may be used by the propagator. - */ - fields() { - return this._getGlobalPropagator().fields(); - } - /** Remove the global propagator */ - disable() { - (0, global_utils_1.unregisterGlobal)(API_NAME, diag_1.DiagAPI.instance()); - } - _getGlobalPropagator() { - return (0, global_utils_1.getGlobal)(API_NAME) || NOOP_TEXT_MAP_PROPAGATOR; - } - }; - exports.PropagationAPI = PropagationAPI; - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/propagation-api.js -var require_propagation_api = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/propagation-api.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.propagation = void 0; - var propagation_1 = require_propagation(); - exports.propagation = propagation_1.PropagationAPI.getInstance(); - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/api/trace.js -var require_trace = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/api/trace.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.TraceAPI = void 0; - var global_utils_1 = require_global_utils(); - var ProxyTracerProvider_1 = require_ProxyTracerProvider(); - var spancontext_utils_1 = require_spancontext_utils(); - var context_utils_1 = require_context_utils(); - var diag_1 = require_diag(); - var API_NAME = "trace"; - var TraceAPI = class _TraceAPI { - static { - __name(this, "TraceAPI"); - } - /** Empty private constructor prevents end users from constructing a new instance of the API */ - constructor() { - this._proxyTracerProvider = new ProxyTracerProvider_1.ProxyTracerProvider(); - this.wrapSpanContext = spancontext_utils_1.wrapSpanContext; - this.isSpanContextValid = spancontext_utils_1.isSpanContextValid; - this.deleteSpan = context_utils_1.deleteSpan; - this.getSpan = context_utils_1.getSpan; - this.getActiveSpan = context_utils_1.getActiveSpan; - this.getSpanContext = context_utils_1.getSpanContext; - this.setSpan = context_utils_1.setSpan; - this.setSpanContext = context_utils_1.setSpanContext; - } - /** Get the singleton instance of the Trace API */ - static getInstance() { - if (!this._instance) { - this._instance = new _TraceAPI(); - } - return this._instance; - } - /** - * Set the current global tracer. - * - * @returns true if the tracer provider was successfully registered, else false - */ - setGlobalTracerProvider(provider) { - const success2 = (0, global_utils_1.registerGlobal)(API_NAME, this._proxyTracerProvider, diag_1.DiagAPI.instance()); - if (success2) { - this._proxyTracerProvider.setDelegate(provider); - } - return success2; - } - /** - * Returns the global tracer provider. - */ - getTracerProvider() { - return (0, global_utils_1.getGlobal)(API_NAME) || this._proxyTracerProvider; - } - /** - * Returns a tracer from the global tracer provider. - */ - getTracer(name17, version2) { - return this.getTracerProvider().getTracer(name17, version2); - } - /** Remove the global tracer provider */ - disable() { - (0, global_utils_1.unregisterGlobal)(API_NAME, diag_1.DiagAPI.instance()); - this._proxyTracerProvider = new ProxyTracerProvider_1.ProxyTracerProvider(); - } - }; - exports.TraceAPI = TraceAPI; - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace-api.js -var require_trace_api = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/trace-api.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.trace = void 0; - var trace_1 = require_trace(); - exports.trace = trace_1.TraceAPI.getInstance(); - } -}); - -// ../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/index.js -var require_src = __commonJS({ - "../../node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/src/index.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.trace = exports.propagation = exports.metrics = exports.diag = exports.context = exports.INVALID_SPAN_CONTEXT = exports.INVALID_TRACEID = exports.INVALID_SPANID = exports.isValidSpanId = exports.isValidTraceId = exports.isSpanContextValid = exports.createTraceState = exports.TraceFlags = exports.SpanStatusCode = exports.SpanKind = exports.SamplingDecision = exports.ProxyTracerProvider = exports.ProxyTracer = exports.defaultTextMapSetter = exports.defaultTextMapGetter = exports.ValueType = exports.createNoopMeter = exports.DiagLogLevel = exports.DiagConsoleLogger = exports.ROOT_CONTEXT = exports.createContextKey = exports.baggageEntryMetadataFromString = void 0; - var utils_1 = require_utils(); - Object.defineProperty(exports, "baggageEntryMetadataFromString", { - enumerable: true, - get: /* @__PURE__ */ __name(function() { - return utils_1.baggageEntryMetadataFromString; - }, "get") - }); - var context_1 = require_context(); - Object.defineProperty(exports, "createContextKey", { - enumerable: true, - get: /* @__PURE__ */ __name(function() { - return context_1.createContextKey; - }, "get") - }); - Object.defineProperty(exports, "ROOT_CONTEXT", { - enumerable: true, - get: /* @__PURE__ */ __name(function() { - return context_1.ROOT_CONTEXT; - }, "get") - }); - var consoleLogger_1 = require_consoleLogger(); - Object.defineProperty(exports, "DiagConsoleLogger", { - enumerable: true, - get: /* @__PURE__ */ __name(function() { - return consoleLogger_1.DiagConsoleLogger; - }, "get") - }); - var types_1 = require_types(); - Object.defineProperty(exports, "DiagLogLevel", { - enumerable: true, - get: /* @__PURE__ */ __name(function() { - return types_1.DiagLogLevel; - }, "get") - }); - var NoopMeter_1 = require_NoopMeter(); - Object.defineProperty(exports, "createNoopMeter", { - enumerable: true, - get: /* @__PURE__ */ __name(function() { - return NoopMeter_1.createNoopMeter; - }, "get") - }); - var Metric_1 = require_Metric(); - Object.defineProperty(exports, "ValueType", { - enumerable: true, - get: /* @__PURE__ */ __name(function() { - return Metric_1.ValueType; - }, "get") - }); - var TextMapPropagator_1 = require_TextMapPropagator(); - Object.defineProperty(exports, "defaultTextMapGetter", { - enumerable: true, - get: /* @__PURE__ */ __name(function() { - return TextMapPropagator_1.defaultTextMapGetter; - }, "get") - }); - Object.defineProperty(exports, "defaultTextMapSetter", { - enumerable: true, - get: /* @__PURE__ */ __name(function() { - return TextMapPropagator_1.defaultTextMapSetter; - }, "get") - }); - var ProxyTracer_1 = require_ProxyTracer(); - Object.defineProperty(exports, "ProxyTracer", { - enumerable: true, - get: /* @__PURE__ */ __name(function() { - return ProxyTracer_1.ProxyTracer; - }, "get") - }); - var ProxyTracerProvider_1 = require_ProxyTracerProvider(); - Object.defineProperty(exports, "ProxyTracerProvider", { - enumerable: true, - get: /* @__PURE__ */ __name(function() { - return ProxyTracerProvider_1.ProxyTracerProvider; - }, "get") - }); - var SamplingResult_1 = require_SamplingResult(); - Object.defineProperty(exports, "SamplingDecision", { - enumerable: true, - get: /* @__PURE__ */ __name(function() { - return SamplingResult_1.SamplingDecision; - }, "get") - }); - var span_kind_1 = require_span_kind(); - Object.defineProperty(exports, "SpanKind", { - enumerable: true, - get: /* @__PURE__ */ __name(function() { - return span_kind_1.SpanKind; - }, "get") - }); - var status_1 = require_status(); - Object.defineProperty(exports, "SpanStatusCode", { - enumerable: true, - get: /* @__PURE__ */ __name(function() { - return status_1.SpanStatusCode; - }, "get") - }); - var trace_flags_1 = require_trace_flags(); - Object.defineProperty(exports, "TraceFlags", { - enumerable: true, - get: /* @__PURE__ */ __name(function() { - return trace_flags_1.TraceFlags; - }, "get") - }); - var utils_2 = require_utils2(); - Object.defineProperty(exports, "createTraceState", { - enumerable: true, - get: /* @__PURE__ */ __name(function() { - return utils_2.createTraceState; - }, "get") - }); - var spancontext_utils_1 = require_spancontext_utils(); - Object.defineProperty(exports, "isSpanContextValid", { - enumerable: true, - get: /* @__PURE__ */ __name(function() { - return spancontext_utils_1.isSpanContextValid; - }, "get") - }); - Object.defineProperty(exports, "isValidTraceId", { - enumerable: true, - get: /* @__PURE__ */ __name(function() { - return spancontext_utils_1.isValidTraceId; - }, "get") - }); - Object.defineProperty(exports, "isValidSpanId", { - enumerable: true, - get: /* @__PURE__ */ __name(function() { - return spancontext_utils_1.isValidSpanId; - }, "get") - }); - var invalid_span_constants_1 = require_invalid_span_constants(); - Object.defineProperty(exports, "INVALID_SPANID", { - enumerable: true, - get: /* @__PURE__ */ __name(function() { - return invalid_span_constants_1.INVALID_SPANID; - }, "get") - }); - Object.defineProperty(exports, "INVALID_TRACEID", { - enumerable: true, - get: /* @__PURE__ */ __name(function() { - return invalid_span_constants_1.INVALID_TRACEID; - }, "get") - }); - Object.defineProperty(exports, "INVALID_SPAN_CONTEXT", { - enumerable: true, - get: /* @__PURE__ */ __name(function() { - return invalid_span_constants_1.INVALID_SPAN_CONTEXT; - }, "get") - }); - var context_api_1 = require_context_api(); - Object.defineProperty(exports, "context", { - enumerable: true, - get: /* @__PURE__ */ __name(function() { - return context_api_1.context; - }, "get") - }); - var diag_api_1 = require_diag_api(); - Object.defineProperty(exports, "diag", { - enumerable: true, - get: /* @__PURE__ */ __name(function() { - return diag_api_1.diag; - }, "get") - }); - var metrics_api_1 = require_metrics_api(); - Object.defineProperty(exports, "metrics", { - enumerable: true, - get: /* @__PURE__ */ __name(function() { - return metrics_api_1.metrics; - }, "get") - }); - var propagation_api_1 = require_propagation_api(); - Object.defineProperty(exports, "propagation", { - enumerable: true, - get: /* @__PURE__ */ __name(function() { - return propagation_api_1.propagation; - }, "get") - }); - var trace_api_1 = require_trace_api(); - Object.defineProperty(exports, "trace", { - enumerable: true, - get: /* @__PURE__ */ __name(function() { - return trace_api_1.trace; - }, "get") - }); - exports.default = { - context: context_api_1.context, - diag: diag_api_1.diag, - metrics: metrics_api_1.metrics, - propagation: propagation_api_1.propagation, - trace: trace_api_1.trace - }; - } -}); - -// ../example/workflows/99_e2e.ts -var e2e_exports = {}; -__export(e2e_exports, { - add: () => add, - addTenWorkflow: () => addTenWorkflow, - crossFileErrorWorkflow: () => crossFileErrorWorkflow, - fetchWorkflow: () => fetchWorkflow, - hookCleanupTestWorkflow: () => hookCleanupTestWorkflow, - hookWorkflow: () => hookWorkflow, - nestedErrorWorkflow: () => nestedErrorWorkflow, - nullByteWorkflow: () => nullByteWorkflow, - outputStreamInsideStepWorkflow: () => outputStreamInsideStepWorkflow, - outputStreamWorkflow: () => outputStreamWorkflow, - promiseAllWorkflow: () => promiseAllWorkflow, - promiseAnyWorkflow: () => promiseAnyWorkflow, - promiseRaceStressTestDelayStep: () => promiseRaceStressTestDelayStep, - promiseRaceStressTestWorkflow: () => promiseRaceStressTestWorkflow, - promiseRaceWorkflow: () => promiseRaceWorkflow, - readableStreamWorkflow: () => readableStreamWorkflow, - retryAttemptCounterWorkflow: () => retryAttemptCounterWorkflow, - retryableAndFatalErrorWorkflow: () => retryableAndFatalErrorWorkflow, - sleepingWorkflow: () => sleepingWorkflow, - stepFunctionPassingWorkflow: () => stepFunctionPassingWorkflow, - webhookWorkflow: () => webhookWorkflow, - workflowAndStepMetadataWorkflow: () => workflowAndStepMetadataWorkflow -}); - -// ../../packages/utils/dist/index.js -var import_ms = __toESM(require_ms(), 1); - -// ../../packages/errors/dist/index.js -function isError(value) { - return typeof value === "object" && value !== null && "name" in value && "message" in value; -} -__name(isError, "isError"); -var FatalError = class extends Error { - static { - __name(this, "FatalError"); - } - fatal = true; - constructor(message) { - super(message); - this.name = "FatalError"; - } - static is(value) { - return isError(value) && value.name === "FatalError"; - } -}; - -// ../../packages/core/dist/symbols.js -var WORKFLOW_USE_STEP = Symbol.for("WORKFLOW_USE_STEP"); -var WORKFLOW_CREATE_HOOK = Symbol.for("WORKFLOW_CREATE_HOOK"); -var WORKFLOW_SLEEP = Symbol.for("WORKFLOW_SLEEP"); -var WORKFLOW_CONTEXT = Symbol.for("WORKFLOW_CONTEXT"); -var WORKFLOW_GET_STREAM_ID = Symbol.for("WORKFLOW_GET_STREAM_ID"); -var STREAM_NAME_SYMBOL = Symbol.for("WORKFLOW_STREAM_NAME"); -var STREAM_TYPE_SYMBOL = Symbol.for("WORKFLOW_STREAM_TYPE"); -var BODY_INIT_SYMBOL = Symbol.for("BODY_INIT"); -var WEBHOOK_RESPONSE_WRITABLE = Symbol.for("WEBHOOK_RESPONSE_WRITABLE"); -var STEP_FUNCTION_NAME_SYMBOL = Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"); - -// ../../packages/core/dist/workflow/get-workflow-metadata.js -var WORKFLOW_CONTEXT_SYMBOL = /* @__PURE__ */ Symbol.for("WORKFLOW_CONTEXT"); -function getWorkflowMetadata() { - const ctx = globalThis[WORKFLOW_CONTEXT_SYMBOL]; - if (!ctx) { - throw new Error("\`getWorkflowMetadata()\` can only be called inside a workflow or step function"); - } - return ctx; -} -__name(getWorkflowMetadata, "getWorkflowMetadata"); - -// ../../packages/core/dist/workflow/create-hook.js -function createHook(options) { - const createHookFn = globalThis[WORKFLOW_CREATE_HOOK]; - if (!createHookFn) { - throw new Error("\`createHook()\` can only be called inside a workflow function"); - } - return createHookFn(options); -} -__name(createHook, "createHook"); -function createWebhook(options) { - const { respondWith, ...rest } = options ?? {}; - let metadata; - if (typeof respondWith !== "undefined") { - metadata = { - respondWith - }; - } - const hook = createHook({ - ...rest, - metadata - }); - const { url: url2 } = getWorkflowMetadata(); - hook.url = \`\${url2}/.well-known/workflow/v1/webhook/\${encodeURIComponent(hook.token)}\`; - return hook; -} -__name(createWebhook, "createWebhook"); - -// ../../packages/core/dist/sleep.js -async function sleep(param) { - const sleepFn = globalThis[WORKFLOW_SLEEP]; - if (!sleepFn) { - throw new Error("\`sleep()\` can only be called inside a workflow function"); - } - return sleepFn(param); -} -__name(sleep, "sleep"); - -// ../../packages/core/dist/workflow/writable-stream.js -function getWritable(options = {}) { - const { namespace } = options; - const name17 = globalThis[WORKFLOW_GET_STREAM_ID](namespace); - return Object.create(globalThis.WritableStream.prototype, { - [STREAM_NAME_SYMBOL]: { - value: name17, - writable: false - } - }); -} -__name(getWritable, "getWritable"); - -// ../../packages/workflow/dist/stdlib.js -async function fetch2(...args) { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//packages/workflow/dist/stdlib.js//fetch")(...args); -} -__name(fetch2, "fetch"); -Object.defineProperty(fetch2, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//packages/workflow/dist/stdlib.js//fetch", - writable: false, - enumerable: false, - configurable: false -}); - -// ../example/workflows/helpers.ts -function throwError() { - throw new Error("Error from imported helper module"); -} -__name(throwError, "throwError"); -function callThrower() { - throwError(); -} -__name(callThrower, "callThrower"); - -// ../example/workflows/99_e2e.ts -async function add(a, b) { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//add")(a, b); -} -__name(add, "add"); -async function addTenWorkflow(input) { - const a = await add(input, 2); - const b = await add(a, 3); - const c = await add(b, 5); - return c; -} -__name(addTenWorkflow, "addTenWorkflow"); -function deepFunction() { - throw new Error("Error from deeply nested function"); -} -__name(deepFunction, "deepFunction"); -function middleFunction() { - deepFunction(); -} -__name(middleFunction, "middleFunction"); -function topLevelHelper() { - middleFunction(); -} -__name(topLevelHelper, "topLevelHelper"); -async function nestedErrorWorkflow() { - topLevelHelper(); - return "never reached"; -} -__name(nestedErrorWorkflow, "nestedErrorWorkflow"); -async function randomDelay(v) { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//randomDelay")(v); -} -__name(randomDelay, "randomDelay"); -async function promiseAllWorkflow() { - const [a, b, c] = await Promise.all([ - randomDelay("a"), - randomDelay("b"), - randomDelay("c") - ]); - return a + b + c; -} -__name(promiseAllWorkflow, "promiseAllWorkflow"); -async function specificDelay(delay2, v) { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//specificDelay")(delay2, v); -} -__name(specificDelay, "specificDelay"); -async function promiseRaceWorkflow() { - const winner = await Promise.race([ - specificDelay(1e4, "a"), - specificDelay(100, "b"), - specificDelay(2e4, "c") - ]); - return winner; -} -__name(promiseRaceWorkflow, "promiseRaceWorkflow"); -async function stepThatFails() { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//stepThatFails")(); -} -__name(stepThatFails, "stepThatFails"); -async function promiseAnyWorkflow() { - const winner = await Promise.any([ - stepThatFails(), - specificDelay(1e3, "b"), - specificDelay(3e3, "c") - ]); - return winner; -} -__name(promiseAnyWorkflow, "promiseAnyWorkflow"); -async function genReadableStream() { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//genReadableStream")(); -} -__name(genReadableStream, "genReadableStream"); -async function readableStreamWorkflow() { - console.log("calling genReadableStream"); - const stream = await genReadableStream(); - console.log("genReadableStream returned", stream); - return stream; -} -__name(readableStreamWorkflow, "readableStreamWorkflow"); -async function hookWorkflow(token, customData) { - const hook = createHook({ - token, - metadata: { - customData - } - }); - const payloads = []; - for await (const payload of hook) { - payloads.push(payload); - if (payload.done) { - break; - } - } - return payloads; -} -__name(hookWorkflow, "hookWorkflow"); -async function sendWebhookResponse(req) { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//sendWebhookResponse")(req); -} -__name(sendWebhookResponse, "sendWebhookResponse"); -async function webhookWorkflow(token, token2, token3) { - const payloads = []; - const webhookWithDefaultResponse = createWebhook({ - token - }); - const res = new Response("Hello from static response!", { - status: 402 - }); - console.log("res", res); - const webhookWithStaticResponse = createWebhook({ - token: token2, - respondWith: res - }); - const webhookWithManualResponse = createWebhook({ - token: token3, - respondWith: "manual" - }); - { - const req = await webhookWithDefaultResponse; - const body = await req.text(); - payloads.push({ - url: req.url, - method: req.method, - body - }); - } - { - const req = await webhookWithStaticResponse; - const body = await req.text(); - payloads.push({ - url: req.url, - method: req.method, - body - }); - } - { - const req = await webhookWithManualResponse; - const body = await sendWebhookResponse(req); - payloads.push({ - url: req.url, - method: req.method, - body - }); - } - return payloads; -} -__name(webhookWorkflow, "webhookWorkflow"); -async function sleepingWorkflow() { - const startTime = Date.now(); - await sleep("10s"); - const endTime = Date.now(); - return { - startTime, - endTime - }; -} -__name(sleepingWorkflow, "sleepingWorkflow"); -async function nullByteStep() { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//nullByteStep")(); -} -__name(nullByteStep, "nullByteStep"); -async function nullByteWorkflow() { - const a = await nullByteStep(); - return a; -} -__name(nullByteWorkflow, "nullByteWorkflow"); -async function stepWithMetadata() { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//stepWithMetadata")(); -} -__name(stepWithMetadata, "stepWithMetadata"); -async function workflowAndStepMetadataWorkflow() { - const workflowMetadata = getWorkflowMetadata(); - const { stepMetadata, workflowMetadata: innerWorkflowMetadata } = await stepWithMetadata(); - return { - workflowMetadata: { - workflowRunId: workflowMetadata.workflowRunId, - workflowStartedAt: workflowMetadata.workflowStartedAt, - url: workflowMetadata.url - }, - stepMetadata, - innerWorkflowMetadata - }; -} -__name(workflowAndStepMetadataWorkflow, "workflowAndStepMetadataWorkflow"); -async function stepWithOutputStreamBinary(writable, text2) { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//stepWithOutputStreamBinary")(writable, text2); -} -__name(stepWithOutputStreamBinary, "stepWithOutputStreamBinary"); -async function stepWithOutputStreamObject(writable, obj) { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//stepWithOutputStreamObject")(writable, obj); -} -__name(stepWithOutputStreamObject, "stepWithOutputStreamObject"); -async function stepCloseOutputStream(writable) { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//stepCloseOutputStream")(writable); -} -__name(stepCloseOutputStream, "stepCloseOutputStream"); -async function outputStreamWorkflow() { - const writable = getWritable(); - const namedWritable = getWritable({ - namespace: "test" - }); - await sleep("1s"); - await stepWithOutputStreamBinary(writable, "Hello, world!"); - await sleep("1s"); - await stepWithOutputStreamBinary(namedWritable, "Hello, named stream!"); - await sleep("1s"); - await stepWithOutputStreamObject(writable, { - foo: "test" - }); - await sleep("1s"); - await stepWithOutputStreamObject(namedWritable, { - foo: "bar" - }); - await sleep("1s"); - await stepCloseOutputStream(writable); - await stepCloseOutputStream(namedWritable); - return "done"; -} -__name(outputStreamWorkflow, "outputStreamWorkflow"); -async function stepWithOutputStreamInsideStep(text2) { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//stepWithOutputStreamInsideStep")(text2); -} -__name(stepWithOutputStreamInsideStep, "stepWithOutputStreamInsideStep"); -async function stepWithNamedOutputStreamInsideStep(namespace, obj) { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//stepWithNamedOutputStreamInsideStep")(namespace, obj); -} -__name(stepWithNamedOutputStreamInsideStep, "stepWithNamedOutputStreamInsideStep"); -async function stepCloseOutputStreamInsideStep(namespace) { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//stepCloseOutputStreamInsideStep")(namespace); -} -__name(stepCloseOutputStreamInsideStep, "stepCloseOutputStreamInsideStep"); -async function outputStreamInsideStepWorkflow() { - await sleep("1s"); - await stepWithOutputStreamInsideStep("Hello from step!"); - await sleep("1s"); - await stepWithNamedOutputStreamInsideStep("step-ns", { - message: "Hello from named stream in step!" - }); - await sleep("1s"); - await stepWithOutputStreamInsideStep("Second message"); - await sleep("1s"); - await stepWithNamedOutputStreamInsideStep("step-ns", { - counter: 42 - }); - await sleep("1s"); - await stepCloseOutputStreamInsideStep(); - await stepCloseOutputStreamInsideStep("step-ns"); - return "done"; -} -__name(outputStreamInsideStepWorkflow, "outputStreamInsideStepWorkflow"); -async function fetchWorkflow() { - const response = await fetch2("https://jsonplaceholder.typicode.com/todos/1"); - const data = await response.json(); - return data; -} -__name(fetchWorkflow, "fetchWorkflow"); -async function promiseRaceStressTestDelayStep(dur, resp) { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//promiseRaceStressTestDelayStep")(dur, resp); -} -__name(promiseRaceStressTestDelayStep, "promiseRaceStressTestDelayStep"); -async function promiseRaceStressTestWorkflow() { - const promises = /* @__PURE__ */ new Map(); - const done = []; - for (let i = 0; i < 5; i++) { - const resp = i; - const dur = 1e3 * 5 * i; - console.log(\`sched\`, resp, \`/\`, dur); - promises.set(i, promiseRaceStressTestDelayStep(dur, resp)); - } - while (promises.size > 0) { - console.log(\`promises.size\`, promises.size); - const res = await Promise.race(promises.values()); - console.log(res); - done.push(res); - promises.delete(res); - } - return done; -} -__name(promiseRaceStressTestWorkflow, "promiseRaceStressTestWorkflow"); -async function stepThatRetriesAndSucceeds() { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//stepThatRetriesAndSucceeds")(); -} -__name(stepThatRetriesAndSucceeds, "stepThatRetriesAndSucceeds"); -async function retryAttemptCounterWorkflow() { - console.log("Starting retry attempt counter workflow"); - const finalAttempt = await stepThatRetriesAndSucceeds(); - console.log(\`Workflow completed with final attempt: \${finalAttempt}\`); - return { - finalAttempt - }; -} -__name(retryAttemptCounterWorkflow, "retryAttemptCounterWorkflow"); -async function stepThatThrowsRetryableError() { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//stepThatThrowsRetryableError")(); -} -__name(stepThatThrowsRetryableError, "stepThatThrowsRetryableError"); -async function crossFileErrorWorkflow() { - callThrower(); - return "never reached"; -} -__name(crossFileErrorWorkflow, "crossFileErrorWorkflow"); -async function retryableAndFatalErrorWorkflow() { - const retryableResult = await stepThatThrowsRetryableError(); - let gotFatalError = false; - try { - await stepThatFails(); - } catch (error45) { - if (FatalError.is(error45)) { - gotFatalError = true; - } - } - return { - retryableResult, - gotFatalError - }; -} -__name(retryableAndFatalErrorWorkflow, "retryableAndFatalErrorWorkflow"); -async function hookCleanupTestWorkflow(token, customData) { - const hook = createHook({ - token, - metadata: { - customData - } - }); - const payload = await hook; - return { - message: payload.message, - customData: payload.customData, - hookCleanupTestData: "workflow_completed" - }; -} -__name(hookCleanupTestWorkflow, "hookCleanupTestWorkflow"); -async function stepFunctionPassingWorkflow() { - const result = await stepWithStepFunctionArg(doubleNumber); - return result; -} -__name(stepFunctionPassingWorkflow, "stepFunctionPassingWorkflow"); -async function stepWithStepFunctionArg(stepFn) { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//stepWithStepFunctionArg")(stepFn); -} -__name(stepWithStepFunctionArg, "stepWithStepFunctionArg"); -async function doubleNumber(x) { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/99_e2e.ts//doubleNumber")(x); -} -__name(doubleNumber, "doubleNumber"); -addTenWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//addTenWorkflow"; -nestedErrorWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//nestedErrorWorkflow"; -promiseAllWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//promiseAllWorkflow"; -promiseRaceWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//promiseRaceWorkflow"; -promiseAnyWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//promiseAnyWorkflow"; -readableStreamWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//readableStreamWorkflow"; -hookWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//hookWorkflow"; -webhookWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//webhookWorkflow"; -sleepingWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//sleepingWorkflow"; -nullByteWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//nullByteWorkflow"; -workflowAndStepMetadataWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//workflowAndStepMetadataWorkflow"; -outputStreamWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//outputStreamWorkflow"; -outputStreamInsideStepWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//outputStreamInsideStepWorkflow"; -fetchWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//fetchWorkflow"; -promiseRaceStressTestWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//promiseRaceStressTestWorkflow"; -retryAttemptCounterWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//retryAttemptCounterWorkflow"; -crossFileErrorWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//crossFileErrorWorkflow"; -retryableAndFatalErrorWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//retryableAndFatalErrorWorkflow"; -hookCleanupTestWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//hookCleanupTestWorkflow"; -stepFunctionPassingWorkflow.workflowId = "workflow//example/workflows/99_e2e.ts//stepFunctionPassingWorkflow"; -Object.defineProperty(add, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/99_e2e.ts//add", - writable: false, - enumerable: false, - configurable: false -}); -Object.defineProperty(randomDelay, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/99_e2e.ts//randomDelay", - writable: false, - enumerable: false, - configurable: false -}); -Object.defineProperty(specificDelay, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/99_e2e.ts//specificDelay", - writable: false, - enumerable: false, - configurable: false -}); -Object.defineProperty(stepThatFails, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/99_e2e.ts//stepThatFails", - writable: false, - enumerable: false, - configurable: false -}); -Object.defineProperty(genReadableStream, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/99_e2e.ts//genReadableStream", - writable: false, - enumerable: false, - configurable: false -}); -Object.defineProperty(sendWebhookResponse, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/99_e2e.ts//sendWebhookResponse", - writable: false, - enumerable: false, - configurable: false -}); -Object.defineProperty(nullByteStep, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/99_e2e.ts//nullByteStep", - writable: false, - enumerable: false, - configurable: false -}); -Object.defineProperty(stepWithMetadata, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/99_e2e.ts//stepWithMetadata", - writable: false, - enumerable: false, - configurable: false -}); -Object.defineProperty(stepWithOutputStreamBinary, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/99_e2e.ts//stepWithOutputStreamBinary", - writable: false, - enumerable: false, - configurable: false -}); -Object.defineProperty(stepWithOutputStreamObject, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/99_e2e.ts//stepWithOutputStreamObject", - writable: false, - enumerable: false, - configurable: false -}); -Object.defineProperty(stepCloseOutputStream, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/99_e2e.ts//stepCloseOutputStream", - writable: false, - enumerable: false, - configurable: false -}); -Object.defineProperty(stepWithOutputStreamInsideStep, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/99_e2e.ts//stepWithOutputStreamInsideStep", - writable: false, - enumerable: false, - configurable: false -}); -Object.defineProperty(stepWithNamedOutputStreamInsideStep, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/99_e2e.ts//stepWithNamedOutputStreamInsideStep", - writable: false, - enumerable: false, - configurable: false -}); -Object.defineProperty(stepCloseOutputStreamInsideStep, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/99_e2e.ts//stepCloseOutputStreamInsideStep", - writable: false, - enumerable: false, - configurable: false -}); -Object.defineProperty(promiseRaceStressTestDelayStep, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/99_e2e.ts//promiseRaceStressTestDelayStep", - writable: false, - enumerable: false, - configurable: false -}); -Object.defineProperty(stepThatRetriesAndSucceeds, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/99_e2e.ts//stepThatRetriesAndSucceeds", - writable: false, - enumerable: false, - configurable: false -}); -Object.defineProperty(stepThatThrowsRetryableError, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/99_e2e.ts//stepThatThrowsRetryableError", - writable: false, - enumerable: false, - configurable: false -}); -Object.defineProperty(stepWithStepFunctionArg, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/99_e2e.ts//stepWithStepFunctionArg", - writable: false, - enumerable: false, - configurable: false -}); -Object.defineProperty(doubleNumber, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/99_e2e.ts//doubleNumber", - writable: false, - enumerable: false, - configurable: false -}); - -// ../example/workflows/2_control_flow.ts -var control_flow_exports = {}; -__export(control_flow_exports, { - control_flow: () => control_flow -}); -async function delayedMessage(ms2, message) { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/2_control_flow.ts//delayedMessage")(ms2, message); -} -__name(delayedMessage, "delayedMessage"); -async function add2(a, b) { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/2_control_flow.ts//add")(a, b); -} -__name(add2, "add"); -async function failingStep() { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/2_control_flow.ts//failingStep")(); -} -__name(failingStep, "failingStep"); -async function retryableStep() { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/2_control_flow.ts//retryableStep")(); -} -__name(retryableStep, "retryableStep"); -async function control_flow() { - console.log("Control flow workflow started"); - const raceResult = await Promise.race([ - delayedMessage(2e3, "I won the race!"), - delayedMessage(1e4, "I lost the race") - ]); - console.log("Race result:", raceResult); - const allResults = await Promise.all([ - delayedMessage(1e3, "First task"), - delayedMessage(2e3, "Second task"), - add2(10, 20) - ]); - console.log("All results:", allResults); - const backgroundPromise = delayedMessage(5e3, "Background task completed"); - const foregroundResults = await Promise.all([ - delayedMessage(1e3, "First task"), - delayedMessage(2e3, "Second task") - ]); - console.log("Foreground response:", foregroundResults); - const backgroundResult = await backgroundPromise; - console.log("Background response:", backgroundResult); - try { - await failingStep(); - } catch (error45) { - console.log("Caught error:", String(error45)); - } - await retryableStep(); - console.log("Control flow workflow completed. See logs for results."); - return { - raceResult, - allResults, - foregroundResults, - backgroundResult - }; -} -__name(control_flow, "control_flow"); -control_flow.workflowId = "workflow//example/workflows/2_control_flow.ts//control_flow"; -Object.defineProperty(delayedMessage, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/2_control_flow.ts//delayedMessage", - writable: false, - enumerable: false, - configurable: false -}); -Object.defineProperty(add2, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/2_control_flow.ts//add", - writable: false, - enumerable: false, - configurable: false -}); -Object.defineProperty(failingStep, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/2_control_flow.ts//failingStep", - writable: false, - enumerable: false, - configurable: false -}); -Object.defineProperty(retryableStep, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/2_control_flow.ts//retryableStep", - writable: false, - enumerable: false, - configurable: false -}); - -// ../nitro-v3/workflows/0_demo.ts -var demo_exports = {}; -__export(demo_exports, { - calc: () => calc -}); -async function calc(n) { - console.log("Simple workflow started"); - n = await pow(n); - console.log("Simple workflow finished"); - return n; -} -__name(calc, "calc"); -async function pow(a) { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//nitro-v3/workflows/0_demo.ts//pow")(a); -} -__name(pow, "pow"); -calc.workflowId = "workflow//nitro-v3/workflows/0_demo.ts//calc"; -Object.defineProperty(pow, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//nitro-v3/workflows/0_demo.ts//pow", - writable: false, - enumerable: false, - configurable: false -}); - -// ../example/workflows/98_duplicate_case.ts -var duplicate_case_exports = {}; -__export(duplicate_case_exports, { - add: () => add3, - addTenWorkflow: () => addTenWorkflow2 -}); -async function addTenWorkflow2(input) { - const a = await add3(input, 2); - const b = await add3(a, 3); - const c = await add3(b, 5); - return c; -} -__name(addTenWorkflow2, "addTenWorkflow"); -async function add3(a, b) { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/98_duplicate_case.ts//add")(a, b); -} -__name(add3, "add"); -addTenWorkflow2.workflowId = "workflow//example/workflows/98_duplicate_case.ts//addTenWorkflow"; -Object.defineProperty(add3, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/98_duplicate_case.ts//add", - writable: false, - enumerable: false, - configurable: false -}); - -// ../example/workflows/6_batching.ts -var batching_exports = {}; -__export(batching_exports, { - batchInStep: () => batchInStep, - batchOverSteps: () => batchOverSteps -}); -var import_lodash = __toESM(require_lodash(), 1); -var ARRAY_LENGTH = 250; -var CHUNK_SIZE = 50; -async function batchOverSteps() { - console.log("Workflow started"); - const arr = Array.from({ - length: ARRAY_LENGTH - }, (_, i) => i + 1); - const chunkSize = CHUNK_SIZE; - console.log(\`Chunking array with size: \${arr.length} and chunk size: \${chunkSize}\`); - const chunks = (0, import_lodash.default)(arr, chunkSize); - console.log(\`Created \${chunks.length} chunks (\${chunks[0].length} items each)\`); - console.log("Starting batch processing"); - for (const [index, batch] of chunks.entries()) { - console.log(\`Batch \${index + 1}/\${chunks.length}\`); - await Promise.all(batch.map(logItem)); - } - console.log("Batch processing completed"); - console.log("Workflow completed"); -} -__name(batchOverSteps, "batchOverSteps"); -async function logItem(item) { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/6_batching.ts//logItem")(item); -} -__name(logItem, "logItem"); -async function batchInStep() { - console.log("Workflow started"); - const arr = Array.from({ - length: ARRAY_LENGTH - }, (_, i) => i + 1); - const chunkSize = CHUNK_SIZE; - console.log(\`Chunking array with size: \${arr.length} and chunk size: \${chunkSize}\`); - const chunks = (0, import_lodash.default)(arr, chunkSize); - console.log(\`Created \${chunks.length} chunks (\${chunks[0].length} items each)\`); - console.log("Starting batch processing"); - for (const [index, batch] of chunks.entries()) { - console.log(\`Batch \${index + 1}/\${chunks.length}\`); - await processItems(batch); - } - console.log("Batch processing completed"); - console.log("Workflow completed"); -} -__name(batchInStep, "batchInStep"); -async function processItems(items) { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/6_batching.ts//processItems")(items); -} -__name(processItems, "processItems"); -batchOverSteps.workflowId = "workflow//example/workflows/6_batching.ts//batchOverSteps"; -batchInStep.workflowId = "workflow//example/workflows/6_batching.ts//batchInStep"; -Object.defineProperty(logItem, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/6_batching.ts//logItem", - writable: false, - enumerable: false, - configurable: false -}); -Object.defineProperty(processItems, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/6_batching.ts//processItems", - writable: false, - enumerable: false, - configurable: false -}); - -// ../example/workflows/1_simple.ts -var simple_exports = {}; -__export(simple_exports, { - simple: () => simple -}); -async function add4(a, b) { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/1_simple.ts//add")(a, b); -} -__name(add4, "add"); -async function simple(i) { - console.log("Simple workflow started"); - const a = await add4(i, 7); - console.log("Workflow step 1 completed - Result:", a); - const b = await add4(a, 8); - console.log("Simple workflow completed. Result:", b); - return b; -} -__name(simple, "simple"); -simple.workflowId = "workflow//example/workflows/1_simple.ts//simple"; -Object.defineProperty(add4, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/1_simple.ts//add", - writable: false, - enumerable: false, - configurable: false -}); - -// ../example/workflows/5_hooks.ts -var hooks_exports = {}; -__export(hooks_exports, { - withCreateHook: () => withCreateHook, - withWorkflowMetadata: () => withWorkflowMetadata -}); -async function stepWithGetMetadata() { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/5_hooks.ts//stepWithGetMetadata")(); -} -__name(stepWithGetMetadata, "stepWithGetMetadata"); -async function withWorkflowMetadata() { - const ctx = getWorkflowMetadata(); - console.log("workflow context", ctx); - await stepWithGetMetadata(); -} -__name(withWorkflowMetadata, "withWorkflowMetadata"); -async function initiateOpenAIResponse() { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/5_hooks.ts//initiateOpenAIResponse")(); -} -__name(initiateOpenAIResponse, "initiateOpenAIResponse"); -async function getOpenAIResponse(respId) { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/5_hooks.ts//getOpenAIResponse")(respId); -} -__name(getOpenAIResponse, "getOpenAIResponse"); -async function withCreateHook() { - const respId = await initiateOpenAIResponse(); - const hook = createHook({ - token: \`openai:\${respId}\` - }); - console.log("Registered hook:", hook.token); - const payload = await hook; - console.log("Received hook payload:", payload); - if (payload.type === "response.completed") { - const text2 = await getOpenAIResponse(payload.data.id); - console.log("OpenAI response text:", text2); - } - console.log("Hook demo workflow completed"); -} -__name(withCreateHook, "withCreateHook"); -withWorkflowMetadata.workflowId = "workflow//example/workflows/5_hooks.ts//withWorkflowMetadata"; -withCreateHook.workflowId = "workflow//example/workflows/5_hooks.ts//withCreateHook"; -Object.defineProperty(stepWithGetMetadata, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/5_hooks.ts//stepWithGetMetadata", - writable: false, - enumerable: false, - configurable: false -}); -Object.defineProperty(initiateOpenAIResponse, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/5_hooks.ts//initiateOpenAIResponse", - writable: false, - enumerable: false, - configurable: false -}); -Object.defineProperty(getOpenAIResponse, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/5_hooks.ts//getOpenAIResponse", - writable: false, - enumerable: false, - configurable: false -}); - -// ../example/workflows/4_ai.ts -var ai_exports = {}; -__export(ai_exports, { - agent: () => agent, - ai: () => ai -}); - -// ../../node_modules/.pnpm/@ai-sdk+provider@2.0.0/node_modules/@ai-sdk/provider/dist/index.mjs -var marker = "vercel.ai.error"; -var symbol = Symbol.for(marker); -var _a; -var _AISDKError = class _AISDKError2 extends Error { - static { - __name(this, "_AISDKError"); - } - /** - * Creates an AI SDK Error. - * - * @param {Object} params - The parameters for creating the error. - * @param {string} params.name - The name of the error. - * @param {string} params.message - The error message. - * @param {unknown} [params.cause] - The underlying cause of the error. - */ - constructor({ name: name143, message, cause }) { - super(message); - this[_a] = true; - this.name = name143; - this.cause = cause; - } - /** - * Checks if the given error is an AI SDK Error. - * @param {unknown} error - The error to check. - * @returns {boolean} True if the error is an AI SDK Error, false otherwise. - */ - static isInstance(error45) { - return _AISDKError2.hasMarker(error45, marker); - } - static hasMarker(error45, marker153) { - const markerSymbol = Symbol.for(marker153); - return error45 != null && typeof error45 === "object" && markerSymbol in error45 && typeof error45[markerSymbol] === "boolean" && error45[markerSymbol] === true; - } -}; -_a = symbol; -var AISDKError = _AISDKError; -var name = "AI_APICallError"; -var marker2 = \`vercel.ai.error.\${name}\`; -var symbol2 = Symbol.for(marker2); -var _a2; -var APICallError = class extends AISDKError { - static { - __name(this, "APICallError"); - } - constructor({ - message, - url: url2, - requestBodyValues, - statusCode, - responseHeaders, - responseBody, - cause, - isRetryable = statusCode != null && (statusCode === 408 || // request timeout - statusCode === 409 || // conflict - statusCode === 429 || // too many requests - statusCode >= 500), - // server error - data - }) { - super({ - name, - message, - cause - }); - this[_a2] = true; - this.url = url2; - this.requestBodyValues = requestBodyValues; - this.statusCode = statusCode; - this.responseHeaders = responseHeaders; - this.responseBody = responseBody; - this.isRetryable = isRetryable; - this.data = data; - } - static isInstance(error45) { - return AISDKError.hasMarker(error45, marker2); - } -}; -_a2 = symbol2; -var name2 = "AI_EmptyResponseBodyError"; -var marker3 = \`vercel.ai.error.\${name2}\`; -var symbol3 = Symbol.for(marker3); -var _a3; -var EmptyResponseBodyError = class extends AISDKError { - static { - __name(this, "EmptyResponseBodyError"); - } - // used in isInstance - constructor({ message = "Empty response body" } = {}) { - super({ - name: name2, - message - }); - this[_a3] = true; - } - static isInstance(error45) { - return AISDKError.hasMarker(error45, marker3); - } -}; -_a3 = symbol3; -function getErrorMessage(error45) { - if (error45 == null) { - return "unknown error"; - } - if (typeof error45 === "string") { - return error45; - } - if (error45 instanceof Error) { - return error45.message; - } - return JSON.stringify(error45); -} -__name(getErrorMessage, "getErrorMessage"); -var name3 = "AI_InvalidArgumentError"; -var marker4 = \`vercel.ai.error.\${name3}\`; -var symbol4 = Symbol.for(marker4); -var _a4; -var InvalidArgumentError = class extends AISDKError { - static { - __name(this, "InvalidArgumentError"); - } - constructor({ message, cause, argument }) { - super({ - name: name3, - message, - cause - }); - this[_a4] = true; - this.argument = argument; - } - static isInstance(error45) { - return AISDKError.hasMarker(error45, marker4); - } -}; -_a4 = symbol4; -var name4 = "AI_InvalidPromptError"; -var marker5 = \`vercel.ai.error.\${name4}\`; -var symbol5 = Symbol.for(marker5); -var _a5; -var InvalidPromptError = class extends AISDKError { - static { - __name(this, "InvalidPromptError"); - } - constructor({ prompt, message, cause }) { - super({ - name: name4, - message: \`Invalid prompt: \${message}\`, - cause - }); - this[_a5] = true; - this.prompt = prompt; - } - static isInstance(error45) { - return AISDKError.hasMarker(error45, marker5); - } -}; -_a5 = symbol5; -var name5 = "AI_InvalidResponseDataError"; -var marker6 = \`vercel.ai.error.\${name5}\`; -var symbol6 = Symbol.for(marker6); -var _a6; -_a6 = symbol6; -var name6 = "AI_JSONParseError"; -var marker7 = \`vercel.ai.error.\${name6}\`; -var symbol7 = Symbol.for(marker7); -var _a7; -var JSONParseError = class extends AISDKError { - static { - __name(this, "JSONParseError"); - } - constructor({ text: text2, cause }) { - super({ - name: name6, - message: \`JSON parsing failed: Text: \${text2}. -Error message: \${getErrorMessage(cause)}\`, - cause - }); - this[_a7] = true; - this.text = text2; - } - static isInstance(error45) { - return AISDKError.hasMarker(error45, marker7); - } -}; -_a7 = symbol7; -var name7 = "AI_LoadAPIKeyError"; -var marker8 = \`vercel.ai.error.\${name7}\`; -var symbol8 = Symbol.for(marker8); -var _a8; -_a8 = symbol8; -var name8 = "AI_LoadSettingError"; -var marker9 = \`vercel.ai.error.\${name8}\`; -var symbol9 = Symbol.for(marker9); -var _a9; -_a9 = symbol9; -var name9 = "AI_NoContentGeneratedError"; -var marker10 = \`vercel.ai.error.\${name9}\`; -var symbol10 = Symbol.for(marker10); -var _a10; -_a10 = symbol10; -var name10 = "AI_NoSuchModelError"; -var marker11 = \`vercel.ai.error.\${name10}\`; -var symbol11 = Symbol.for(marker11); -var _a11; -var NoSuchModelError = class extends AISDKError { - static { - __name(this, "NoSuchModelError"); - } - constructor({ errorName = name10, modelId, modelType, message = \`No such \${modelType}: \${modelId}\` }) { - super({ - name: errorName, - message - }); - this[_a11] = true; - this.modelId = modelId; - this.modelType = modelType; - } - static isInstance(error45) { - return AISDKError.hasMarker(error45, marker11); - } -}; -_a11 = symbol11; -var name11 = "AI_TooManyEmbeddingValuesForCallError"; -var marker12 = \`vercel.ai.error.\${name11}\`; -var symbol12 = Symbol.for(marker12); -var _a12; -_a12 = symbol12; -var name12 = "AI_TypeValidationError"; -var marker13 = \`vercel.ai.error.\${name12}\`; -var symbol13 = Symbol.for(marker13); -var _a13; -var _TypeValidationError = class _TypeValidationError2 extends AISDKError { - static { - __name(this, "_TypeValidationError"); - } - constructor({ value, cause }) { - super({ - name: name12, - message: \`Type validation failed: Value: \${JSON.stringify(value)}. -Error message: \${getErrorMessage(cause)}\`, - cause - }); - this[_a13] = true; - this.value = value; - } - static isInstance(error45) { - return AISDKError.hasMarker(error45, marker13); - } - /** - * Wraps an error into a TypeValidationError. - * If the cause is already a TypeValidationError with the same value, it returns the cause. - * Otherwise, it creates a new TypeValidationError. - * - * @param {Object} params - The parameters for wrapping the error. - * @param {unknown} params.value - The value that failed validation. - * @param {unknown} params.cause - The original error or cause of the validation failure. - * @returns {TypeValidationError} A TypeValidationError instance. - */ - static wrap({ value, cause }) { - return _TypeValidationError2.isInstance(cause) && cause.value === value ? cause : new _TypeValidationError2({ - value, - cause - }); - } -}; -_a13 = symbol13; -var TypeValidationError = _TypeValidationError; -var name13 = "AI_UnsupportedFunctionalityError"; -var marker14 = \`vercel.ai.error.\${name13}\`; -var symbol14 = Symbol.for(marker14); -var _a14; -_a14 = symbol14; - -// ../../node_modules/.pnpm/eventsource-parser@3.0.6/node_modules/eventsource-parser/dist/index.js -var ParseError = class extends Error { - static { - __name(this, "ParseError"); - } - constructor(message, options) { - super(message), this.name = "ParseError", this.type = options.type, this.field = options.field, this.value = options.value, this.line = options.line; - } -}; -function createParser(callbacks) { - if (typeof callbacks == "function") throw new TypeError("\`callbacks\` must be an object, got a function instead. Did you mean \`{onEvent: fn}\`?"); - const { onEvent = noop, onError = noop, onRetry = noop, onComment } = callbacks; - let incompleteLine = "", isFirstChunk = true, id, data = "", eventType = ""; - function feed(newChunk) { - const chunk2 = isFirstChunk ? newChunk.replace(/^\\xEF\\xBB\\xBF/, "") : newChunk, [complete, incomplete] = splitLines(\`\${incompleteLine}\${chunk2}\`); - for (const line of complete) parseLine(line); - incompleteLine = incomplete, isFirstChunk = false; - } - __name(feed, "feed"); - function parseLine(line) { - if (line === "") { - dispatchEvent(); - return; - } - if (line.startsWith(":")) { - onComment && onComment(line.slice(line.startsWith(": ") ? 2 : 1)); - return; - } - const fieldSeparatorIndex = line.indexOf(":"); - if (fieldSeparatorIndex !== -1) { - const field = line.slice(0, fieldSeparatorIndex), offset = line[fieldSeparatorIndex + 1] === " " ? 2 : 1, value = line.slice(fieldSeparatorIndex + offset); - processField(field, value, line); - return; - } - processField(line, "", line); - } - __name(parseLine, "parseLine"); - function processField(field, value, line) { - switch (field) { - case "event": - eventType = value; - break; - case "data": - data = \`\${data}\${value} -\`; - break; - case "id": - id = value.includes("\\0") ? void 0 : value; - break; - case "retry": - /^\\d+\$/.test(value) ? onRetry(parseInt(value, 10)) : onError(new ParseError(\`Invalid \\\`retry\\\` value: "\${value}"\`, { - type: "invalid-retry", - value, - line - })); - break; - default: - onError(new ParseError(\`Unknown field "\${field.length > 20 ? \`\${field.slice(0, 20)}\\u2026\` : field}"\`, { - type: "unknown-field", - field, - value, - line - })); - break; - } - } - __name(processField, "processField"); - function dispatchEvent() { - data.length > 0 && onEvent({ - id, - event: eventType || void 0, - // If the data buffer's last character is a U+000A LINE FEED (LF) character, - // then remove the last character from the data buffer. - data: data.endsWith(\` -\`) ? data.slice(0, -1) : data - }), id = void 0, data = "", eventType = ""; - } - __name(dispatchEvent, "dispatchEvent"); - function reset(options = {}) { - incompleteLine && options.consume && parseLine(incompleteLine), isFirstChunk = true, id = void 0, data = "", eventType = "", incompleteLine = ""; - } - __name(reset, "reset"); - return { - feed, - reset - }; -} -__name(createParser, "createParser"); -function splitLines(chunk2) { - const lines = []; - let incompleteLine = "", searchIndex = 0; - for (; searchIndex < chunk2.length; ) { - const crIndex = chunk2.indexOf("\\r", searchIndex), lfIndex = chunk2.indexOf(\` -\`, searchIndex); - let lineEnd = -1; - if (crIndex !== -1 && lfIndex !== -1 ? lineEnd = Math.min(crIndex, lfIndex) : crIndex !== -1 ? crIndex === chunk2.length - 1 ? lineEnd = -1 : lineEnd = crIndex : lfIndex !== -1 && (lineEnd = lfIndex), lineEnd === -1) { - incompleteLine = chunk2.slice(searchIndex); - break; - } else { - const line = chunk2.slice(searchIndex, lineEnd); - lines.push(line), searchIndex = lineEnd + 1, chunk2[searchIndex - 1] === "\\r" && chunk2[searchIndex] === \` -\` && searchIndex++; - } - } - return [ - lines, - incompleteLine - ]; -} -__name(splitLines, "splitLines"); - -// ../../node_modules/.pnpm/eventsource-parser@3.0.6/node_modules/eventsource-parser/dist/stream.js -var EventSourceParserStream = class extends TransformStream { - static { - __name(this, "EventSourceParserStream"); - } - constructor({ onError, onRetry, onComment } = {}) { - let parser; - super({ - start(controller) { - parser = createParser({ - onEvent: /* @__PURE__ */ __name((event) => { - controller.enqueue(event); - }, "onEvent"), - onError(error45) { - onError === "terminate" ? controller.error(error45) : typeof onError == "function" && onError(error45); - }, - onRetry, - onComment - }); - }, - transform(chunk2) { - parser.feed(chunk2); - } - }); - } -}; - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/classic/external.js -var external_exports = {}; -__export(external_exports, { - \$brand: () => \$brand, - \$input: () => \$input, - \$output: () => \$output, - NEVER: () => NEVER, - TimePrecision: () => TimePrecision, - ZodAny: () => ZodAny, - ZodArray: () => ZodArray, - ZodBase64: () => ZodBase64, - ZodBase64URL: () => ZodBase64URL, - ZodBigInt: () => ZodBigInt, - ZodBigIntFormat: () => ZodBigIntFormat, - ZodBoolean: () => ZodBoolean, - ZodCIDRv4: () => ZodCIDRv4, - ZodCIDRv6: () => ZodCIDRv6, - ZodCUID: () => ZodCUID, - ZodCUID2: () => ZodCUID2, - ZodCatch: () => ZodCatch, - ZodCodec: () => ZodCodec, - ZodCustom: () => ZodCustom, - ZodCustomStringFormat: () => ZodCustomStringFormat, - ZodDate: () => ZodDate, - ZodDefault: () => ZodDefault, - ZodDiscriminatedUnion: () => ZodDiscriminatedUnion, - ZodE164: () => ZodE164, - ZodEmail: () => ZodEmail, - ZodEmoji: () => ZodEmoji, - ZodEnum: () => ZodEnum, - ZodError: () => ZodError, - ZodFile: () => ZodFile, - ZodFirstPartyTypeKind: () => ZodFirstPartyTypeKind, - ZodFunction: () => ZodFunction, - ZodGUID: () => ZodGUID, - ZodIPv4: () => ZodIPv4, - ZodIPv6: () => ZodIPv6, - ZodISODate: () => ZodISODate, - ZodISODateTime: () => ZodISODateTime, - ZodISODuration: () => ZodISODuration, - ZodISOTime: () => ZodISOTime, - ZodIntersection: () => ZodIntersection, - ZodIssueCode: () => ZodIssueCode, - ZodJWT: () => ZodJWT, - ZodKSUID: () => ZodKSUID, - ZodLazy: () => ZodLazy, - ZodLiteral: () => ZodLiteral, - ZodMap: () => ZodMap, - ZodNaN: () => ZodNaN, - ZodNanoID: () => ZodNanoID, - ZodNever: () => ZodNever, - ZodNonOptional: () => ZodNonOptional, - ZodNull: () => ZodNull, - ZodNullable: () => ZodNullable, - ZodNumber: () => ZodNumber, - ZodNumberFormat: () => ZodNumberFormat, - ZodObject: () => ZodObject, - ZodOptional: () => ZodOptional, - ZodPipe: () => ZodPipe, - ZodPrefault: () => ZodPrefault, - ZodPromise: () => ZodPromise, - ZodReadonly: () => ZodReadonly, - ZodRealError: () => ZodRealError, - ZodRecord: () => ZodRecord, - ZodSet: () => ZodSet, - ZodString: () => ZodString, - ZodStringFormat: () => ZodStringFormat, - ZodSuccess: () => ZodSuccess, - ZodSymbol: () => ZodSymbol, - ZodTemplateLiteral: () => ZodTemplateLiteral, - ZodTransform: () => ZodTransform, - ZodTuple: () => ZodTuple, - ZodType: () => ZodType, - ZodULID: () => ZodULID, - ZodURL: () => ZodURL, - ZodUUID: () => ZodUUID, - ZodUndefined: () => ZodUndefined, - ZodUnion: () => ZodUnion, - ZodUnknown: () => ZodUnknown, - ZodVoid: () => ZodVoid, - ZodXID: () => ZodXID, - _ZodString: () => _ZodString, - _default: () => _default2, - _function: () => _function, - any: () => any, - array: () => array, - base64: () => base642, - base64url: () => base64url2, - bigint: () => bigint2, - boolean: () => boolean2, - catch: () => _catch2, - check: () => check, - cidrv4: () => cidrv42, - cidrv6: () => cidrv62, - clone: () => clone, - codec: () => codec, - coerce: () => coerce_exports, - config: () => config, - core: () => core_exports2, - cuid: () => cuid3, - cuid2: () => cuid22, - custom: () => custom, - date: () => date3, - decode: () => decode2, - decodeAsync: () => decodeAsync2, - discriminatedUnion: () => discriminatedUnion, - e164: () => e1642, - email: () => email2, - emoji: () => emoji2, - encode: () => encode2, - encodeAsync: () => encodeAsync2, - endsWith: () => _endsWith, - enum: () => _enum2, - file: () => file, - flattenError: () => flattenError, - float32: () => float32, - float64: () => float64, - formatError: () => formatError, - function: () => _function, - getErrorMap: () => getErrorMap, - globalRegistry: () => globalRegistry, - gt: () => _gt, - gte: () => _gte, - guid: () => guid2, - hash: () => hash, - hex: () => hex2, - hostname: () => hostname2, - httpUrl: () => httpUrl, - includes: () => _includes, - instanceof: () => _instanceof, - int: () => int, - int32: () => int32, - int64: () => int64, - intersection: () => intersection, - ipv4: () => ipv42, - ipv6: () => ipv62, - iso: () => iso_exports, - json: () => json, - jwt: () => jwt, - keyof: () => keyof, - ksuid: () => ksuid2, - lazy: () => lazy, - length: () => _length, - literal: () => literal, - locales: () => locales_exports, - looseObject: () => looseObject, - lowercase: () => _lowercase, - lt: () => _lt, - lte: () => _lte, - map: () => map, - maxLength: () => _maxLength, - maxSize: () => _maxSize, - mime: () => _mime, - minLength: () => _minLength, - minSize: () => _minSize, - multipleOf: () => _multipleOf, - nan: () => nan, - nanoid: () => nanoid2, - nativeEnum: () => nativeEnum, - negative: () => _negative, - never: () => never, - nonnegative: () => _nonnegative, - nonoptional: () => nonoptional, - nonpositive: () => _nonpositive, - normalize: () => _normalize, - null: () => _null3, - nullable: () => nullable, - nullish: () => nullish2, - number: () => number2, - object: () => object, - optional: () => optional, - overwrite: () => _overwrite, - parse: () => parse2, - parseAsync: () => parseAsync2, - partialRecord: () => partialRecord, - pipe: () => pipe, - positive: () => _positive, - prefault: () => prefault, - preprocess: () => preprocess, - prettifyError: () => prettifyError, - promise: () => promise, - property: () => _property, - readonly: () => readonly, - record: () => record, - refine: () => refine, - regex: () => _regex, - regexes: () => regexes_exports, - registry: () => registry, - safeDecode: () => safeDecode2, - safeDecodeAsync: () => safeDecodeAsync2, - safeEncode: () => safeEncode2, - safeEncodeAsync: () => safeEncodeAsync2, - safeParse: () => safeParse2, - safeParseAsync: () => safeParseAsync2, - set: () => set, - setErrorMap: () => setErrorMap, - size: () => _size, - startsWith: () => _startsWith, - strictObject: () => strictObject, - string: () => string2, - stringFormat: () => stringFormat, - stringbool: () => stringbool, - success: () => success, - superRefine: () => superRefine, - symbol: () => symbol15, - templateLiteral: () => templateLiteral, - toJSONSchema: () => toJSONSchema, - toLowerCase: () => _toLowerCase, - toUpperCase: () => _toUpperCase, - transform: () => transform, - treeifyError: () => treeifyError, - trim: () => _trim, - tuple: () => tuple, - uint32: () => uint32, - uint64: () => uint64, - ulid: () => ulid2, - undefined: () => _undefined3, - union: () => union, - unknown: () => unknown, - uppercase: () => _uppercase, - url: () => url, - util: () => util_exports, - uuid: () => uuid2, - uuidv4: () => uuidv4, - uuidv6: () => uuidv6, - uuidv7: () => uuidv7, - void: () => _void2, - xid: () => xid2 -}); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/core/index.js -var core_exports2 = {}; -__export(core_exports2, { - \$ZodAny: () => \$ZodAny, - \$ZodArray: () => \$ZodArray, - \$ZodAsyncError: () => \$ZodAsyncError, - \$ZodBase64: () => \$ZodBase64, - \$ZodBase64URL: () => \$ZodBase64URL, - \$ZodBigInt: () => \$ZodBigInt, - \$ZodBigIntFormat: () => \$ZodBigIntFormat, - \$ZodBoolean: () => \$ZodBoolean, - \$ZodCIDRv4: () => \$ZodCIDRv4, - \$ZodCIDRv6: () => \$ZodCIDRv6, - \$ZodCUID: () => \$ZodCUID, - \$ZodCUID2: () => \$ZodCUID2, - \$ZodCatch: () => \$ZodCatch, - \$ZodCheck: () => \$ZodCheck, - \$ZodCheckBigIntFormat: () => \$ZodCheckBigIntFormat, - \$ZodCheckEndsWith: () => \$ZodCheckEndsWith, - \$ZodCheckGreaterThan: () => \$ZodCheckGreaterThan, - \$ZodCheckIncludes: () => \$ZodCheckIncludes, - \$ZodCheckLengthEquals: () => \$ZodCheckLengthEquals, - \$ZodCheckLessThan: () => \$ZodCheckLessThan, - \$ZodCheckLowerCase: () => \$ZodCheckLowerCase, - \$ZodCheckMaxLength: () => \$ZodCheckMaxLength, - \$ZodCheckMaxSize: () => \$ZodCheckMaxSize, - \$ZodCheckMimeType: () => \$ZodCheckMimeType, - \$ZodCheckMinLength: () => \$ZodCheckMinLength, - \$ZodCheckMinSize: () => \$ZodCheckMinSize, - \$ZodCheckMultipleOf: () => \$ZodCheckMultipleOf, - \$ZodCheckNumberFormat: () => \$ZodCheckNumberFormat, - \$ZodCheckOverwrite: () => \$ZodCheckOverwrite, - \$ZodCheckProperty: () => \$ZodCheckProperty, - \$ZodCheckRegex: () => \$ZodCheckRegex, - \$ZodCheckSizeEquals: () => \$ZodCheckSizeEquals, - \$ZodCheckStartsWith: () => \$ZodCheckStartsWith, - \$ZodCheckStringFormat: () => \$ZodCheckStringFormat, - \$ZodCheckUpperCase: () => \$ZodCheckUpperCase, - \$ZodCodec: () => \$ZodCodec, - \$ZodCustom: () => \$ZodCustom, - \$ZodCustomStringFormat: () => \$ZodCustomStringFormat, - \$ZodDate: () => \$ZodDate, - \$ZodDefault: () => \$ZodDefault, - \$ZodDiscriminatedUnion: () => \$ZodDiscriminatedUnion, - \$ZodE164: () => \$ZodE164, - \$ZodEmail: () => \$ZodEmail, - \$ZodEmoji: () => \$ZodEmoji, - \$ZodEncodeError: () => \$ZodEncodeError, - \$ZodEnum: () => \$ZodEnum, - \$ZodError: () => \$ZodError, - \$ZodFile: () => \$ZodFile, - \$ZodFunction: () => \$ZodFunction, - \$ZodGUID: () => \$ZodGUID, - \$ZodIPv4: () => \$ZodIPv4, - \$ZodIPv6: () => \$ZodIPv6, - \$ZodISODate: () => \$ZodISODate, - \$ZodISODateTime: () => \$ZodISODateTime, - \$ZodISODuration: () => \$ZodISODuration, - \$ZodISOTime: () => \$ZodISOTime, - \$ZodIntersection: () => \$ZodIntersection, - \$ZodJWT: () => \$ZodJWT, - \$ZodKSUID: () => \$ZodKSUID, - \$ZodLazy: () => \$ZodLazy, - \$ZodLiteral: () => \$ZodLiteral, - \$ZodMap: () => \$ZodMap, - \$ZodNaN: () => \$ZodNaN, - \$ZodNanoID: () => \$ZodNanoID, - \$ZodNever: () => \$ZodNever, - \$ZodNonOptional: () => \$ZodNonOptional, - \$ZodNull: () => \$ZodNull, - \$ZodNullable: () => \$ZodNullable, - \$ZodNumber: () => \$ZodNumber, - \$ZodNumberFormat: () => \$ZodNumberFormat, - \$ZodObject: () => \$ZodObject, - \$ZodObjectJIT: () => \$ZodObjectJIT, - \$ZodOptional: () => \$ZodOptional, - \$ZodPipe: () => \$ZodPipe, - \$ZodPrefault: () => \$ZodPrefault, - \$ZodPromise: () => \$ZodPromise, - \$ZodReadonly: () => \$ZodReadonly, - \$ZodRealError: () => \$ZodRealError, - \$ZodRecord: () => \$ZodRecord, - \$ZodRegistry: () => \$ZodRegistry, - \$ZodSet: () => \$ZodSet, - \$ZodString: () => \$ZodString, - \$ZodStringFormat: () => \$ZodStringFormat, - \$ZodSuccess: () => \$ZodSuccess, - \$ZodSymbol: () => \$ZodSymbol, - \$ZodTemplateLiteral: () => \$ZodTemplateLiteral, - \$ZodTransform: () => \$ZodTransform, - \$ZodTuple: () => \$ZodTuple, - \$ZodType: () => \$ZodType, - \$ZodULID: () => \$ZodULID, - \$ZodURL: () => \$ZodURL, - \$ZodUUID: () => \$ZodUUID, - \$ZodUndefined: () => \$ZodUndefined, - \$ZodUnion: () => \$ZodUnion, - \$ZodUnknown: () => \$ZodUnknown, - \$ZodVoid: () => \$ZodVoid, - \$ZodXID: () => \$ZodXID, - \$brand: () => \$brand, - \$constructor: () => \$constructor, - \$input: () => \$input, - \$output: () => \$output, - Doc: () => Doc, - JSONSchema: () => json_schema_exports, - JSONSchemaGenerator: () => JSONSchemaGenerator, - NEVER: () => NEVER, - TimePrecision: () => TimePrecision, - _any: () => _any, - _array: () => _array, - _base64: () => _base64, - _base64url: () => _base64url, - _bigint: () => _bigint, - _boolean: () => _boolean, - _catch: () => _catch, - _check: () => _check, - _cidrv4: () => _cidrv4, - _cidrv6: () => _cidrv6, - _coercedBigint: () => _coercedBigint, - _coercedBoolean: () => _coercedBoolean, - _coercedDate: () => _coercedDate, - _coercedNumber: () => _coercedNumber, - _coercedString: () => _coercedString, - _cuid: () => _cuid, - _cuid2: () => _cuid2, - _custom: () => _custom, - _date: () => _date, - _decode: () => _decode, - _decodeAsync: () => _decodeAsync, - _default: () => _default, - _discriminatedUnion: () => _discriminatedUnion, - _e164: () => _e164, - _email: () => _email, - _emoji: () => _emoji2, - _encode: () => _encode, - _encodeAsync: () => _encodeAsync, - _endsWith: () => _endsWith, - _enum: () => _enum, - _file: () => _file, - _float32: () => _float32, - _float64: () => _float64, - _gt: () => _gt, - _gte: () => _gte, - _guid: () => _guid, - _includes: () => _includes, - _int: () => _int, - _int32: () => _int32, - _int64: () => _int64, - _intersection: () => _intersection, - _ipv4: () => _ipv4, - _ipv6: () => _ipv6, - _isoDate: () => _isoDate, - _isoDateTime: () => _isoDateTime, - _isoDuration: () => _isoDuration, - _isoTime: () => _isoTime, - _jwt: () => _jwt, - _ksuid: () => _ksuid, - _lazy: () => _lazy, - _length: () => _length, - _literal: () => _literal, - _lowercase: () => _lowercase, - _lt: () => _lt, - _lte: () => _lte, - _map: () => _map, - _max: () => _lte, - _maxLength: () => _maxLength, - _maxSize: () => _maxSize, - _mime: () => _mime, - _min: () => _gte, - _minLength: () => _minLength, - _minSize: () => _minSize, - _multipleOf: () => _multipleOf, - _nan: () => _nan, - _nanoid: () => _nanoid, - _nativeEnum: () => _nativeEnum, - _negative: () => _negative, - _never: () => _never, - _nonnegative: () => _nonnegative, - _nonoptional: () => _nonoptional, - _nonpositive: () => _nonpositive, - _normalize: () => _normalize, - _null: () => _null2, - _nullable: () => _nullable, - _number: () => _number, - _optional: () => _optional, - _overwrite: () => _overwrite, - _parse: () => _parse, - _parseAsync: () => _parseAsync, - _pipe: () => _pipe, - _positive: () => _positive, - _promise: () => _promise, - _property: () => _property, - _readonly: () => _readonly, - _record: () => _record, - _refine: () => _refine, - _regex: () => _regex, - _safeDecode: () => _safeDecode, - _safeDecodeAsync: () => _safeDecodeAsync, - _safeEncode: () => _safeEncode, - _safeEncodeAsync: () => _safeEncodeAsync, - _safeParse: () => _safeParse, - _safeParseAsync: () => _safeParseAsync, - _set: () => _set, - _size: () => _size, - _startsWith: () => _startsWith, - _string: () => _string, - _stringFormat: () => _stringFormat, - _stringbool: () => _stringbool, - _success: () => _success, - _superRefine: () => _superRefine, - _symbol: () => _symbol, - _templateLiteral: () => _templateLiteral, - _toLowerCase: () => _toLowerCase, - _toUpperCase: () => _toUpperCase, - _transform: () => _transform, - _trim: () => _trim, - _tuple: () => _tuple, - _uint32: () => _uint32, - _uint64: () => _uint64, - _ulid: () => _ulid, - _undefined: () => _undefined2, - _union: () => _union, - _unknown: () => _unknown, - _uppercase: () => _uppercase, - _url: () => _url, - _uuid: () => _uuid, - _uuidv4: () => _uuidv4, - _uuidv6: () => _uuidv6, - _uuidv7: () => _uuidv7, - _void: () => _void, - _xid: () => _xid, - clone: () => clone, - config: () => config, - decode: () => decode, - decodeAsync: () => decodeAsync, - encode: () => encode, - encodeAsync: () => encodeAsync, - flattenError: () => flattenError, - formatError: () => formatError, - globalConfig: () => globalConfig, - globalRegistry: () => globalRegistry, - isValidBase64: () => isValidBase64, - isValidBase64URL: () => isValidBase64URL, - isValidJWT: () => isValidJWT, - locales: () => locales_exports, - parse: () => parse, - parseAsync: () => parseAsync, - prettifyError: () => prettifyError, - regexes: () => regexes_exports, - registry: () => registry, - safeDecode: () => safeDecode, - safeDecodeAsync: () => safeDecodeAsync, - safeEncode: () => safeEncode, - safeEncodeAsync: () => safeEncodeAsync, - safeParse: () => safeParse, - safeParseAsync: () => safeParseAsync, - toDotPath: () => toDotPath, - toJSONSchema: () => toJSONSchema, - treeifyError: () => treeifyError, - util: () => util_exports, - version: () => version -}); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/core/core.js -var NEVER = Object.freeze({ - status: "aborted" -}); -// @__NO_SIDE_EFFECTS__ -function \$constructor(name17, initializer3, params) { - function init(inst, def) { - var _a17; - Object.defineProperty(inst, "_zod", { - value: inst._zod ?? {}, - enumerable: false - }); - (_a17 = inst._zod).traits ?? (_a17.traits = /* @__PURE__ */ new Set()); - inst._zod.traits.add(name17); - initializer3(inst, def); - for (const k in _.prototype) { - if (!(k in inst)) Object.defineProperty(inst, k, { - value: _.prototype[k].bind(inst) - }); - } - inst._zod.constr = _; - inst._zod.def = def; - } - __name(init, "init"); - const Parent = params?.Parent ?? Object; - class Definition extends Parent { - static { - __name(this, "Definition"); - } - } - Object.defineProperty(Definition, "name", { - value: name17 - }); - function _(def) { - var _a17; - const inst = params?.Parent ? new Definition() : this; - init(inst, def); - (_a17 = inst._zod).deferred ?? (_a17.deferred = []); - for (const fn of inst._zod.deferred) { - fn(); - } - return inst; - } - __name(_, "_"); - Object.defineProperty(_, "init", { - value: init - }); - Object.defineProperty(_, Symbol.hasInstance, { - value: /* @__PURE__ */ __name((inst) => { - if (params?.Parent && inst instanceof params.Parent) return true; - return inst?._zod?.traits?.has(name17); - }, "value") - }); - Object.defineProperty(_, "name", { - value: name17 - }); - return _; -} -__name(\$constructor, "\$constructor"); -var \$brand = Symbol("zod_brand"); -var \$ZodAsyncError = class extends Error { - static { - __name(this, "\$ZodAsyncError"); - } - constructor() { - super(\`Encountered Promise during synchronous parse. Use .parseAsync() instead.\`); - } -}; -var \$ZodEncodeError = class extends Error { - static { - __name(this, "\$ZodEncodeError"); - } - constructor(name17) { - super(\`Encountered unidirectional transform during encode: \${name17}\`); - this.name = "ZodEncodeError"; - } -}; -var globalConfig = {}; -function config(newConfig) { - if (newConfig) Object.assign(globalConfig, newConfig); - return globalConfig; -} -__name(config, "config"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/core/util.js -var util_exports = {}; -__export(util_exports, { - BIGINT_FORMAT_RANGES: () => BIGINT_FORMAT_RANGES, - Class: () => Class, - NUMBER_FORMAT_RANGES: () => NUMBER_FORMAT_RANGES, - aborted: () => aborted, - allowsEval: () => allowsEval, - assert: () => assert, - assertEqual: () => assertEqual, - assertIs: () => assertIs, - assertNever: () => assertNever, - assertNotEqual: () => assertNotEqual, - assignProp: () => assignProp, - base64ToUint8Array: () => base64ToUint8Array, - base64urlToUint8Array: () => base64urlToUint8Array, - cached: () => cached, - captureStackTrace: () => captureStackTrace, - cleanEnum: () => cleanEnum, - cleanRegex: () => cleanRegex, - clone: () => clone, - cloneDef: () => cloneDef, - createTransparentProxy: () => createTransparentProxy, - defineLazy: () => defineLazy, - esc: () => esc, - escapeRegex: () => escapeRegex, - extend: () => extend, - finalizeIssue: () => finalizeIssue, - floatSafeRemainder: () => floatSafeRemainder, - getElementAtPath: () => getElementAtPath, - getEnumValues: () => getEnumValues, - getLengthableOrigin: () => getLengthableOrigin, - getParsedType: () => getParsedType, - getSizableOrigin: () => getSizableOrigin, - hexToUint8Array: () => hexToUint8Array, - isObject: () => isObject, - isPlainObject: () => isPlainObject, - issue: () => issue, - joinValues: () => joinValues, - jsonStringifyReplacer: () => jsonStringifyReplacer, - merge: () => merge, - mergeDefs: () => mergeDefs, - normalizeParams: () => normalizeParams, - nullish: () => nullish, - numKeys: () => numKeys, - objectClone: () => objectClone, - omit: () => omit, - optionalKeys: () => optionalKeys, - partial: () => partial, - pick: () => pick, - prefixIssues: () => prefixIssues, - primitiveTypes: () => primitiveTypes, - promiseAllObject: () => promiseAllObject, - propertyKeyTypes: () => propertyKeyTypes, - randomString: () => randomString, - required: () => required, - safeExtend: () => safeExtend, - shallowClone: () => shallowClone, - stringifyPrimitive: () => stringifyPrimitive, - uint8ArrayToBase64: () => uint8ArrayToBase64, - uint8ArrayToBase64url: () => uint8ArrayToBase64url, - uint8ArrayToHex: () => uint8ArrayToHex, - unwrapMessage: () => unwrapMessage -}); -function assertEqual(val) { - return val; -} -__name(assertEqual, "assertEqual"); -function assertNotEqual(val) { - return val; -} -__name(assertNotEqual, "assertNotEqual"); -function assertIs(_arg) { -} -__name(assertIs, "assertIs"); -function assertNever(_x) { - throw new Error(); -} -__name(assertNever, "assertNever"); -function assert(_) { -} -__name(assert, "assert"); -function getEnumValues(entries) { - const numericValues = Object.values(entries).filter((v) => typeof v === "number"); - const values = Object.entries(entries).filter(([k, _]) => numericValues.indexOf(+k) === -1).map(([_, v]) => v); - return values; -} -__name(getEnumValues, "getEnumValues"); -function joinValues(array2, separator = "|") { - return array2.map((val) => stringifyPrimitive(val)).join(separator); -} -__name(joinValues, "joinValues"); -function jsonStringifyReplacer(_, value) { - if (typeof value === "bigint") return value.toString(); - return value; -} -__name(jsonStringifyReplacer, "jsonStringifyReplacer"); -function cached(getter) { - const set2 = false; - return { - get value() { - if (!set2) { - const value = getter(); - Object.defineProperty(this, "value", { - value - }); - return value; - } - throw new Error("cached value already set"); - } - }; -} -__name(cached, "cached"); -function nullish(input) { - return input === null || input === void 0; -} -__name(nullish, "nullish"); -function cleanRegex(source) { - const start = source.startsWith("^") ? 1 : 0; - const end = source.endsWith("\$") ? source.length - 1 : source.length; - return source.slice(start, end); -} -__name(cleanRegex, "cleanRegex"); -function floatSafeRemainder(val, step) { - const valDecCount = (val.toString().split(".")[1] || "").length; - const stepString = step.toString(); - let stepDecCount = (stepString.split(".")[1] || "").length; - if (stepDecCount === 0 && /\\d?e-\\d?/.test(stepString)) { - const match = stepString.match(/\\d?e-(\\d?)/); - if (match?.[1]) { - stepDecCount = Number.parseInt(match[1]); - } - } - const decCount = valDecCount > stepDecCount ? valDecCount : stepDecCount; - const valInt = Number.parseInt(val.toFixed(decCount).replace(".", "")); - const stepInt = Number.parseInt(step.toFixed(decCount).replace(".", "")); - return valInt % stepInt / 10 ** decCount; -} -__name(floatSafeRemainder, "floatSafeRemainder"); -var EVALUATING = Symbol("evaluating"); -function defineLazy(object3, key, getter) { - let value = void 0; - Object.defineProperty(object3, key, { - get() { - if (value === EVALUATING) { - return void 0; - } - if (value === void 0) { - value = EVALUATING; - value = getter(); - } - return value; - }, - set(v) { - Object.defineProperty(object3, key, { - value: v - }); - }, - configurable: true - }); -} -__name(defineLazy, "defineLazy"); -function objectClone(obj) { - return Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj)); -} -__name(objectClone, "objectClone"); -function assignProp(target, prop, value) { - Object.defineProperty(target, prop, { - value, - writable: true, - enumerable: true, - configurable: true - }); -} -__name(assignProp, "assignProp"); -function mergeDefs(...defs) { - const mergedDescriptors = {}; - for (const def of defs) { - const descriptors = Object.getOwnPropertyDescriptors(def); - Object.assign(mergedDescriptors, descriptors); - } - return Object.defineProperties({}, mergedDescriptors); -} -__name(mergeDefs, "mergeDefs"); -function cloneDef(schema) { - return mergeDefs(schema._zod.def); -} -__name(cloneDef, "cloneDef"); -function getElementAtPath(obj, path) { - if (!path) return obj; - return path.reduce((acc, key) => acc?.[key], obj); -} -__name(getElementAtPath, "getElementAtPath"); -function promiseAllObject(promisesObj) { - const keys = Object.keys(promisesObj); - const promises = keys.map((key) => promisesObj[key]); - return Promise.all(promises).then((results) => { - const resolvedObj = {}; - for (let i = 0; i < keys.length; i++) { - resolvedObj[keys[i]] = results[i]; - } - return resolvedObj; - }); -} -__name(promiseAllObject, "promiseAllObject"); -function randomString(length = 10) { - const chars = "abcdefghijklmnopqrstuvwxyz"; - let str = ""; - for (let i = 0; i < length; i++) { - str += chars[Math.floor(Math.random() * chars.length)]; - } - return str; -} -__name(randomString, "randomString"); -function esc(str) { - return JSON.stringify(str); -} -__name(esc, "esc"); -var captureStackTrace = "captureStackTrace" in Error ? Error.captureStackTrace : (..._args) => { -}; -function isObject(data) { - return typeof data === "object" && data !== null && !Array.isArray(data); -} -__name(isObject, "isObject"); -var allowsEval = cached(() => { - if (typeof navigator !== "undefined" && navigator?.userAgent?.includes("Cloudflare")) { - return false; - } - try { - const F = Function; - new F(""); - return true; - } catch (_) { - return false; - } -}); -function isPlainObject(o) { - if (isObject(o) === false) return false; - const ctor = o.constructor; - if (ctor === void 0) return true; - const prot = ctor.prototype; - if (isObject(prot) === false) return false; - if (Object.prototype.hasOwnProperty.call(prot, "isPrototypeOf") === false) { - return false; - } - return true; -} -__name(isPlainObject, "isPlainObject"); -function shallowClone(o) { - if (isPlainObject(o)) return { - ...o - }; - if (Array.isArray(o)) return [ - ...o - ]; - return o; -} -__name(shallowClone, "shallowClone"); -function numKeys(data) { - let keyCount = 0; - for (const key in data) { - if (Object.prototype.hasOwnProperty.call(data, key)) { - keyCount++; - } - } - return keyCount; -} -__name(numKeys, "numKeys"); -var getParsedType = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "undefined": - return "undefined"; - case "string": - return "string"; - case "number": - return Number.isNaN(data) ? "nan" : "number"; - case "boolean": - return "boolean"; - case "function": - return "function"; - case "bigint": - return "bigint"; - case "symbol": - return "symbol"; - case "object": - if (Array.isArray(data)) { - return "array"; - } - if (data === null) { - return "null"; - } - if (data.then && typeof data.then === "function" && data.catch && typeof data.catch === "function") { - return "promise"; - } - if (typeof Map !== "undefined" && data instanceof Map) { - return "map"; - } - if (typeof Set !== "undefined" && data instanceof Set) { - return "set"; - } - if (typeof Date !== "undefined" && data instanceof Date) { - return "date"; - } - if (typeof File !== "undefined" && data instanceof File) { - return "file"; - } - return "object"; - default: - throw new Error(\`Unknown data type: \${t}\`); - } -}, "getParsedType"); -var propertyKeyTypes = /* @__PURE__ */ new Set([ - "string", - "number", - "symbol" -]); -var primitiveTypes = /* @__PURE__ */ new Set([ - "string", - "number", - "bigint", - "boolean", - "symbol", - "undefined" -]); -function escapeRegex(str) { - return str.replace(/[.*+?^\${}()|[\\]\\\\]/g, "\\\\\$&"); -} -__name(escapeRegex, "escapeRegex"); -function clone(inst, def, params) { - const cl = new inst._zod.constr(def ?? inst._zod.def); - if (!def || params?.parent) cl._zod.parent = inst; - return cl; -} -__name(clone, "clone"); -function normalizeParams(_params) { - const params = _params; - if (!params) return {}; - if (typeof params === "string") return { - error: /* @__PURE__ */ __name(() => params, "error") - }; - if (params?.message !== void 0) { - if (params?.error !== void 0) throw new Error("Cannot specify both \`message\` and \`error\` params"); - params.error = params.message; - } - delete params.message; - if (typeof params.error === "string") return { - ...params, - error: /* @__PURE__ */ __name(() => params.error, "error") - }; - return params; -} -__name(normalizeParams, "normalizeParams"); -function createTransparentProxy(getter) { - let target; - return new Proxy({}, { - get(_, prop, receiver) { - target ?? (target = getter()); - return Reflect.get(target, prop, receiver); - }, - set(_, prop, value, receiver) { - target ?? (target = getter()); - return Reflect.set(target, prop, value, receiver); - }, - has(_, prop) { - target ?? (target = getter()); - return Reflect.has(target, prop); - }, - deleteProperty(_, prop) { - target ?? (target = getter()); - return Reflect.deleteProperty(target, prop); - }, - ownKeys(_) { - target ?? (target = getter()); - return Reflect.ownKeys(target); - }, - getOwnPropertyDescriptor(_, prop) { - target ?? (target = getter()); - return Reflect.getOwnPropertyDescriptor(target, prop); - }, - defineProperty(_, prop, descriptor) { - target ?? (target = getter()); - return Reflect.defineProperty(target, prop, descriptor); - } - }); -} -__name(createTransparentProxy, "createTransparentProxy"); -function stringifyPrimitive(value) { - if (typeof value === "bigint") return value.toString() + "n"; - if (typeof value === "string") return \`"\${value}"\`; - return \`\${value}\`; -} -__name(stringifyPrimitive, "stringifyPrimitive"); -function optionalKeys(shape) { - return Object.keys(shape).filter((k) => { - return shape[k]._zod.optin === "optional" && shape[k]._zod.optout === "optional"; - }); -} -__name(optionalKeys, "optionalKeys"); -var NUMBER_FORMAT_RANGES = { - safeint: [ - Number.MIN_SAFE_INTEGER, - Number.MAX_SAFE_INTEGER - ], - int32: [ - -2147483648, - 2147483647 - ], - uint32: [ - 0, - 4294967295 - ], - float32: [ - -34028234663852886e22, - 34028234663852886e22 - ], - float64: [ - -Number.MAX_VALUE, - Number.MAX_VALUE - ] -}; -var BIGINT_FORMAT_RANGES = { - int64: [ - /* @__PURE__ */ BigInt("-9223372036854775808"), - /* @__PURE__ */ BigInt("9223372036854775807") - ], - uint64: [ - /* @__PURE__ */ BigInt(0), - /* @__PURE__ */ BigInt("18446744073709551615") - ] -}; -function pick(schema, mask) { - const currDef = schema._zod.def; - const def = mergeDefs(schema._zod.def, { - get shape() { - const newShape = {}; - for (const key in mask) { - if (!(key in currDef.shape)) { - throw new Error(\`Unrecognized key: "\${key}"\`); - } - if (!mask[key]) continue; - newShape[key] = currDef.shape[key]; - } - assignProp(this, "shape", newShape); - return newShape; - }, - checks: [] - }); - return clone(schema, def); -} -__name(pick, "pick"); -function omit(schema, mask) { - const currDef = schema._zod.def; - const def = mergeDefs(schema._zod.def, { - get shape() { - const newShape = { - ...schema._zod.def.shape - }; - for (const key in mask) { - if (!(key in currDef.shape)) { - throw new Error(\`Unrecognized key: "\${key}"\`); - } - if (!mask[key]) continue; - delete newShape[key]; - } - assignProp(this, "shape", newShape); - return newShape; - }, - checks: [] - }); - return clone(schema, def); -} -__name(omit, "omit"); -function extend(schema, shape) { - if (!isPlainObject(shape)) { - throw new Error("Invalid input to extend: expected a plain object"); - } - const checks = schema._zod.def.checks; - const hasChecks = checks && checks.length > 0; - if (hasChecks) { - throw new Error("Object schemas containing refinements cannot be extended. Use \`.safeExtend()\` instead."); - } - const def = mergeDefs(schema._zod.def, { - get shape() { - const _shape = { - ...schema._zod.def.shape, - ...shape - }; - assignProp(this, "shape", _shape); - return _shape; - }, - checks: [] - }); - return clone(schema, def); -} -__name(extend, "extend"); -function safeExtend(schema, shape) { - if (!isPlainObject(shape)) { - throw new Error("Invalid input to safeExtend: expected a plain object"); - } - const def = { - ...schema._zod.def, - get shape() { - const _shape = { - ...schema._zod.def.shape, - ...shape - }; - assignProp(this, "shape", _shape); - return _shape; - }, - checks: schema._zod.def.checks - }; - return clone(schema, def); -} -__name(safeExtend, "safeExtend"); -function merge(a, b) { - const def = mergeDefs(a._zod.def, { - get shape() { - const _shape = { - ...a._zod.def.shape, - ...b._zod.def.shape - }; - assignProp(this, "shape", _shape); - return _shape; - }, - get catchall() { - return b._zod.def.catchall; - }, - checks: [] - }); - return clone(a, def); -} -__name(merge, "merge"); -function partial(Class2, schema, mask) { - const def = mergeDefs(schema._zod.def, { - get shape() { - const oldShape = schema._zod.def.shape; - const shape = { - ...oldShape - }; - if (mask) { - for (const key in mask) { - if (!(key in oldShape)) { - throw new Error(\`Unrecognized key: "\${key}"\`); - } - if (!mask[key]) continue; - shape[key] = Class2 ? new Class2({ - type: "optional", - innerType: oldShape[key] - }) : oldShape[key]; - } - } else { - for (const key in oldShape) { - shape[key] = Class2 ? new Class2({ - type: "optional", - innerType: oldShape[key] - }) : oldShape[key]; - } - } - assignProp(this, "shape", shape); - return shape; - }, - checks: [] - }); - return clone(schema, def); -} -__name(partial, "partial"); -function required(Class2, schema, mask) { - const def = mergeDefs(schema._zod.def, { - get shape() { - const oldShape = schema._zod.def.shape; - const shape = { - ...oldShape - }; - if (mask) { - for (const key in mask) { - if (!(key in shape)) { - throw new Error(\`Unrecognized key: "\${key}"\`); - } - if (!mask[key]) continue; - shape[key] = new Class2({ - type: "nonoptional", - innerType: oldShape[key] - }); - } - } else { - for (const key in oldShape) { - shape[key] = new Class2({ - type: "nonoptional", - innerType: oldShape[key] - }); - } - } - assignProp(this, "shape", shape); - return shape; - }, - checks: [] - }); - return clone(schema, def); -} -__name(required, "required"); -function aborted(x, startIndex = 0) { - if (x.aborted === true) return true; - for (let i = startIndex; i < x.issues.length; i++) { - if (x.issues[i]?.continue !== true) { - return true; - } - } - return false; -} -__name(aborted, "aborted"); -function prefixIssues(path, issues) { - return issues.map((iss) => { - var _a17; - (_a17 = iss).path ?? (_a17.path = []); - iss.path.unshift(path); - return iss; - }); -} -__name(prefixIssues, "prefixIssues"); -function unwrapMessage(message) { - return typeof message === "string" ? message : message?.message; -} -__name(unwrapMessage, "unwrapMessage"); -function finalizeIssue(iss, ctx, config2) { - const full = { - ...iss, - path: iss.path ?? [] - }; - if (!iss.message) { - const message = unwrapMessage(iss.inst?._zod.def?.error?.(iss)) ?? unwrapMessage(ctx?.error?.(iss)) ?? unwrapMessage(config2.customError?.(iss)) ?? unwrapMessage(config2.localeError?.(iss)) ?? "Invalid input"; - full.message = message; - } - delete full.inst; - delete full.continue; - if (!ctx?.reportInput) { - delete full.input; - } - return full; -} -__name(finalizeIssue, "finalizeIssue"); -function getSizableOrigin(input) { - if (input instanceof Set) return "set"; - if (input instanceof Map) return "map"; - if (input instanceof File) return "file"; - return "unknown"; -} -__name(getSizableOrigin, "getSizableOrigin"); -function getLengthableOrigin(input) { - if (Array.isArray(input)) return "array"; - if (typeof input === "string") return "string"; - return "unknown"; -} -__name(getLengthableOrigin, "getLengthableOrigin"); -function issue(...args) { - const [iss, input, inst] = args; - if (typeof iss === "string") { - return { - message: iss, - code: "custom", - input, - inst - }; - } - return { - ...iss - }; -} -__name(issue, "issue"); -function cleanEnum(obj) { - return Object.entries(obj).filter(([k, _]) => { - return Number.isNaN(Number.parseInt(k, 10)); - }).map((el) => el[1]); -} -__name(cleanEnum, "cleanEnum"); -function base64ToUint8Array(base643) { - const binaryString = atob(base643); - const bytes = new Uint8Array(binaryString.length); - for (let i = 0; i < binaryString.length; i++) { - bytes[i] = binaryString.charCodeAt(i); - } - return bytes; -} -__name(base64ToUint8Array, "base64ToUint8Array"); -function uint8ArrayToBase64(bytes) { - let binaryString = ""; - for (let i = 0; i < bytes.length; i++) { - binaryString += String.fromCharCode(bytes[i]); - } - return btoa(binaryString); -} -__name(uint8ArrayToBase64, "uint8ArrayToBase64"); -function base64urlToUint8Array(base64url3) { - const base643 = base64url3.replace(/-/g, "+").replace(/_/g, "/"); - const padding = "=".repeat((4 - base643.length % 4) % 4); - return base64ToUint8Array(base643 + padding); -} -__name(base64urlToUint8Array, "base64urlToUint8Array"); -function uint8ArrayToBase64url(bytes) { - return uint8ArrayToBase64(bytes).replace(/\\+/g, "-").replace(/\\//g, "_").replace(/=/g, ""); -} -__name(uint8ArrayToBase64url, "uint8ArrayToBase64url"); -function hexToUint8Array(hex3) { - const cleanHex = hex3.replace(/^0x/, ""); - if (cleanHex.length % 2 !== 0) { - throw new Error("Invalid hex string length"); - } - const bytes = new Uint8Array(cleanHex.length / 2); - for (let i = 0; i < cleanHex.length; i += 2) { - bytes[i / 2] = Number.parseInt(cleanHex.slice(i, i + 2), 16); - } - return bytes; -} -__name(hexToUint8Array, "hexToUint8Array"); -function uint8ArrayToHex(bytes) { - return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join(""); -} -__name(uint8ArrayToHex, "uint8ArrayToHex"); -var Class = class { - static { - __name(this, "Class"); - } - constructor(..._args) { - } -}; - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/core/errors.js -var initializer = /* @__PURE__ */ __name((inst, def) => { - inst.name = "\$ZodError"; - Object.defineProperty(inst, "_zod", { - value: inst._zod, - enumerable: false - }); - Object.defineProperty(inst, "issues", { - value: def, - enumerable: false - }); - inst.message = JSON.stringify(def, jsonStringifyReplacer, 2); - Object.defineProperty(inst, "toString", { - value: /* @__PURE__ */ __name(() => inst.message, "value"), - enumerable: false - }); -}, "initializer"); -var \$ZodError = \$constructor("\$ZodError", initializer); -var \$ZodRealError = \$constructor("\$ZodError", initializer, { - Parent: Error -}); -function flattenError(error45, mapper = (issue2) => issue2.message) { - const fieldErrors = {}; - const formErrors = []; - for (const sub of error45.issues) { - if (sub.path.length > 0) { - fieldErrors[sub.path[0]] = fieldErrors[sub.path[0]] || []; - fieldErrors[sub.path[0]].push(mapper(sub)); - } else { - formErrors.push(mapper(sub)); - } - } - return { - formErrors, - fieldErrors - }; -} -__name(flattenError, "flattenError"); -function formatError(error45, _mapper) { - const mapper = _mapper || function(issue2) { - return issue2.message; - }; - const fieldErrors = { - _errors: [] - }; - const processError = /* @__PURE__ */ __name((error46) => { - for (const issue2 of error46.issues) { - if (issue2.code === "invalid_union" && issue2.errors.length) { - issue2.errors.map((issues) => processError({ - issues - })); - } else if (issue2.code === "invalid_key") { - processError({ - issues: issue2.issues - }); - } else if (issue2.code === "invalid_element") { - processError({ - issues: issue2.issues - }); - } else if (issue2.path.length === 0) { - fieldErrors._errors.push(mapper(issue2)); - } else { - let curr = fieldErrors; - let i = 0; - while (i < issue2.path.length) { - const el = issue2.path[i]; - const terminal = i === issue2.path.length - 1; - if (!terminal) { - curr[el] = curr[el] || { - _errors: [] - }; - } else { - curr[el] = curr[el] || { - _errors: [] - }; - curr[el]._errors.push(mapper(issue2)); - } - curr = curr[el]; - i++; - } - } - } - }, "processError"); - processError(error45); - return fieldErrors; -} -__name(formatError, "formatError"); -function treeifyError(error45, _mapper) { - const mapper = _mapper || function(issue2) { - return issue2.message; - }; - const result = { - errors: [] - }; - const processError = /* @__PURE__ */ __name((error46, path = []) => { - var _a17, _b8; - for (const issue2 of error46.issues) { - if (issue2.code === "invalid_union" && issue2.errors.length) { - issue2.errors.map((issues) => processError({ - issues - }, issue2.path)); - } else if (issue2.code === "invalid_key") { - processError({ - issues: issue2.issues - }, issue2.path); - } else if (issue2.code === "invalid_element") { - processError({ - issues: issue2.issues - }, issue2.path); - } else { - const fullpath = [ - ...path, - ...issue2.path - ]; - if (fullpath.length === 0) { - result.errors.push(mapper(issue2)); - continue; - } - let curr = result; - let i = 0; - while (i < fullpath.length) { - const el = fullpath[i]; - const terminal = i === fullpath.length - 1; - if (typeof el === "string") { - curr.properties ?? (curr.properties = {}); - (_a17 = curr.properties)[el] ?? (_a17[el] = { - errors: [] - }); - curr = curr.properties[el]; - } else { - curr.items ?? (curr.items = []); - (_b8 = curr.items)[el] ?? (_b8[el] = { - errors: [] - }); - curr = curr.items[el]; - } - if (terminal) { - curr.errors.push(mapper(issue2)); - } - i++; - } - } - } - }, "processError"); - processError(error45); - return result; -} -__name(treeifyError, "treeifyError"); -function toDotPath(_path) { - const segs = []; - const path = _path.map((seg) => typeof seg === "object" ? seg.key : seg); - for (const seg of path) { - if (typeof seg === "number") segs.push(\`[\${seg}]\`); - else if (typeof seg === "symbol") segs.push(\`[\${JSON.stringify(String(seg))}]\`); - else if (/[^\\w\$]/.test(seg)) segs.push(\`[\${JSON.stringify(seg)}]\`); - else { - if (segs.length) segs.push("."); - segs.push(seg); - } - } - return segs.join(""); -} -__name(toDotPath, "toDotPath"); -function prettifyError(error45) { - const lines = []; - const issues = [ - ...error45.issues - ].sort((a, b) => (a.path ?? []).length - (b.path ?? []).length); - for (const issue2 of issues) { - lines.push(\`\\u2716 \${issue2.message}\`); - if (issue2.path?.length) lines.push(\` \\u2192 at \${toDotPath(issue2.path)}\`); - } - return lines.join("\\n"); -} -__name(prettifyError, "prettifyError"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/core/parse.js -var _parse = /* @__PURE__ */ __name((_Err) => (schema, value, _ctx, _params) => { - const ctx = _ctx ? Object.assign(_ctx, { - async: false - }) : { - async: false - }; - const result = schema._zod.run({ - value, - issues: [] - }, ctx); - if (result instanceof Promise) { - throw new \$ZodAsyncError(); - } - if (result.issues.length) { - const e = new (_params?.Err ?? _Err)(result.issues.map((iss) => finalizeIssue(iss, ctx, config()))); - captureStackTrace(e, _params?.callee); - throw e; - } - return result.value; -}, "_parse"); -var parse = /* @__PURE__ */ _parse(\$ZodRealError); -var _parseAsync = /* @__PURE__ */ __name((_Err) => async (schema, value, _ctx, params) => { - const ctx = _ctx ? Object.assign(_ctx, { - async: true - }) : { - async: true - }; - let result = schema._zod.run({ - value, - issues: [] - }, ctx); - if (result instanceof Promise) result = await result; - if (result.issues.length) { - const e = new (params?.Err ?? _Err)(result.issues.map((iss) => finalizeIssue(iss, ctx, config()))); - captureStackTrace(e, params?.callee); - throw e; - } - return result.value; -}, "_parseAsync"); -var parseAsync = /* @__PURE__ */ _parseAsync(\$ZodRealError); -var _safeParse = /* @__PURE__ */ __name((_Err) => (schema, value, _ctx) => { - const ctx = _ctx ? { - ..._ctx, - async: false - } : { - async: false - }; - const result = schema._zod.run({ - value, - issues: [] - }, ctx); - if (result instanceof Promise) { - throw new \$ZodAsyncError(); - } - return result.issues.length ? { - success: false, - error: new (_Err ?? \$ZodError)(result.issues.map((iss) => finalizeIssue(iss, ctx, config()))) - } : { - success: true, - data: result.value - }; -}, "_safeParse"); -var safeParse = /* @__PURE__ */ _safeParse(\$ZodRealError); -var _safeParseAsync = /* @__PURE__ */ __name((_Err) => async (schema, value, _ctx) => { - const ctx = _ctx ? Object.assign(_ctx, { - async: true - }) : { - async: true - }; - let result = schema._zod.run({ - value, - issues: [] - }, ctx); - if (result instanceof Promise) result = await result; - return result.issues.length ? { - success: false, - error: new _Err(result.issues.map((iss) => finalizeIssue(iss, ctx, config()))) - } : { - success: true, - data: result.value - }; -}, "_safeParseAsync"); -var safeParseAsync = /* @__PURE__ */ _safeParseAsync(\$ZodRealError); -var _encode = /* @__PURE__ */ __name((_Err) => (schema, value, _ctx) => { - const ctx = _ctx ? Object.assign(_ctx, { - direction: "backward" - }) : { - direction: "backward" - }; - return _parse(_Err)(schema, value, ctx); -}, "_encode"); -var encode = /* @__PURE__ */ _encode(\$ZodRealError); -var _decode = /* @__PURE__ */ __name((_Err) => (schema, value, _ctx) => { - return _parse(_Err)(schema, value, _ctx); -}, "_decode"); -var decode = /* @__PURE__ */ _decode(\$ZodRealError); -var _encodeAsync = /* @__PURE__ */ __name((_Err) => async (schema, value, _ctx) => { - const ctx = _ctx ? Object.assign(_ctx, { - direction: "backward" - }) : { - direction: "backward" - }; - return _parseAsync(_Err)(schema, value, ctx); -}, "_encodeAsync"); -var encodeAsync = /* @__PURE__ */ _encodeAsync(\$ZodRealError); -var _decodeAsync = /* @__PURE__ */ __name((_Err) => async (schema, value, _ctx) => { - return _parseAsync(_Err)(schema, value, _ctx); -}, "_decodeAsync"); -var decodeAsync = /* @__PURE__ */ _decodeAsync(\$ZodRealError); -var _safeEncode = /* @__PURE__ */ __name((_Err) => (schema, value, _ctx) => { - const ctx = _ctx ? Object.assign(_ctx, { - direction: "backward" - }) : { - direction: "backward" - }; - return _safeParse(_Err)(schema, value, ctx); -}, "_safeEncode"); -var safeEncode = /* @__PURE__ */ _safeEncode(\$ZodRealError); -var _safeDecode = /* @__PURE__ */ __name((_Err) => (schema, value, _ctx) => { - return _safeParse(_Err)(schema, value, _ctx); -}, "_safeDecode"); -var safeDecode = /* @__PURE__ */ _safeDecode(\$ZodRealError); -var _safeEncodeAsync = /* @__PURE__ */ __name((_Err) => async (schema, value, _ctx) => { - const ctx = _ctx ? Object.assign(_ctx, { - direction: "backward" - }) : { - direction: "backward" - }; - return _safeParseAsync(_Err)(schema, value, ctx); -}, "_safeEncodeAsync"); -var safeEncodeAsync = /* @__PURE__ */ _safeEncodeAsync(\$ZodRealError); -var _safeDecodeAsync = /* @__PURE__ */ __name((_Err) => async (schema, value, _ctx) => { - return _safeParseAsync(_Err)(schema, value, _ctx); -}, "_safeDecodeAsync"); -var safeDecodeAsync = /* @__PURE__ */ _safeDecodeAsync(\$ZodRealError); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/core/regexes.js -var regexes_exports = {}; -__export(regexes_exports, { - base64: () => base64, - base64url: () => base64url, - bigint: () => bigint, - boolean: () => boolean, - browserEmail: () => browserEmail, - cidrv4: () => cidrv4, - cidrv6: () => cidrv6, - cuid: () => cuid, - cuid2: () => cuid2, - date: () => date, - datetime: () => datetime, - domain: () => domain, - duration: () => duration, - e164: () => e164, - email: () => email, - emoji: () => emoji, - extendedDuration: () => extendedDuration, - guid: () => guid, - hex: () => hex, - hostname: () => hostname, - html5Email: () => html5Email, - idnEmail: () => idnEmail, - integer: () => integer, - ipv4: () => ipv4, - ipv6: () => ipv6, - ksuid: () => ksuid, - lowercase: () => lowercase, - md5_base64: () => md5_base64, - md5_base64url: () => md5_base64url, - md5_hex: () => md5_hex, - nanoid: () => nanoid, - null: () => _null, - number: () => number, - rfc5322Email: () => rfc5322Email, - sha1_base64: () => sha1_base64, - sha1_base64url: () => sha1_base64url, - sha1_hex: () => sha1_hex, - sha256_base64: () => sha256_base64, - sha256_base64url: () => sha256_base64url, - sha256_hex: () => sha256_hex, - sha384_base64: () => sha384_base64, - sha384_base64url: () => sha384_base64url, - sha384_hex: () => sha384_hex, - sha512_base64: () => sha512_base64, - sha512_base64url: () => sha512_base64url, - sha512_hex: () => sha512_hex, - string: () => string, - time: () => time, - ulid: () => ulid, - undefined: () => _undefined, - unicodeEmail: () => unicodeEmail, - uppercase: () => uppercase, - uuid: () => uuid, - uuid4: () => uuid4, - uuid6: () => uuid6, - uuid7: () => uuid7, - xid: () => xid -}); -var cuid = /^[cC][^\\s-]{8,}\$/; -var cuid2 = /^[0-9a-z]+\$/; -var ulid = /^[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}\$/; -var xid = /^[0-9a-vA-V]{20}\$/; -var ksuid = /^[A-Za-z0-9]{27}\$/; -var nanoid = /^[a-zA-Z0-9_-]{21}\$/; -var duration = /^P(?:(\\d+W)|(?!.*W)(?=\\d|T\\d)(\\d+Y)?(\\d+M)?(\\d+D)?(T(?=\\d)(\\d+H)?(\\d+M)?(\\d+([.,]\\d+)?S)?)?)\$/; -var extendedDuration = /^[-+]?P(?!\$)(?:(?:[-+]?\\d+Y)|(?:[-+]?\\d+[.,]\\d+Y\$))?(?:(?:[-+]?\\d+M)|(?:[-+]?\\d+[.,]\\d+M\$))?(?:(?:[-+]?\\d+W)|(?:[-+]?\\d+[.,]\\d+W\$))?(?:(?:[-+]?\\d+D)|(?:[-+]?\\d+[.,]\\d+D\$))?(?:T(?=[\\d+-])(?:(?:[-+]?\\d+H)|(?:[-+]?\\d+[.,]\\d+H\$))?(?:(?:[-+]?\\d+M)|(?:[-+]?\\d+[.,]\\d+M\$))?(?:[-+]?\\d+(?:[.,]\\d+)?S)?)??\$/; -var guid = /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})\$/; -var uuid = /* @__PURE__ */ __name((version2) => { - if (!version2) return /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)\$/; - return new RegExp(\`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-\${version2}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})\$\`); -}, "uuid"); -var uuid4 = /* @__PURE__ */ uuid(4); -var uuid6 = /* @__PURE__ */ uuid(6); -var uuid7 = /* @__PURE__ */ uuid(7); -var email = /^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}\$/; -var html5Email = /^[a-zA-Z0-9.!#\$%&'*+/=?^_\`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\$/; -var rfc5322Email = /^(([^<>()\\[\\]\\\\.,;:\\s@"]+(\\.[^<>()\\[\\]\\\\.,;:\\s@"]+)*)|(".+"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))\$/; -var unicodeEmail = /^[^\\s@"]{1,64}@[^\\s@]{1,255}\$/u; -var idnEmail = unicodeEmail; -var browserEmail = /^[a-zA-Z0-9.!#\$%&'*+/=?^_\`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\$/; -var _emoji = \`^(\\\\p{Extended_Pictographic}|\\\\p{Emoji_Component})+\$\`; -function emoji() { - return new RegExp(_emoji, "u"); -} -__name(emoji, "emoji"); -var ipv4 = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\$/; -var ipv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))\$/; -var cidrv4 = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\/([0-9]|[1-2][0-9]|3[0-2])\$/; -var cidrv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::|([0-9a-fA-F]{1,4})?::([0-9a-fA-F]{1,4}:?){0,6})\\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])\$/; -var base64 = /^\$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?\$/; -var base64url = /^[A-Za-z0-9_-]*\$/; -var hostname = /^(?=.{1,253}\\.?\$)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[-0-9a-zA-Z]{0,61}[0-9a-zA-Z])?)*\\.?\$/; -var domain = /^([a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,}\$/; -var e164 = /^\\+(?:[0-9]){6,14}[0-9]\$/; -var dateSource = \`(?:(?:\\\\d\\\\d[2468][048]|\\\\d\\\\d[13579][26]|\\\\d\\\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\\\d|30)|(?:02)-(?:0[1-9]|1\\\\d|2[0-8])))\`; -var date = /* @__PURE__ */ new RegExp(\`^\${dateSource}\$\`); -function timeSource(args) { - const hhmm = \`(?:[01]\\\\d|2[0-3]):[0-5]\\\\d\`; - const regex = typeof args.precision === "number" ? args.precision === -1 ? \`\${hhmm}\` : args.precision === 0 ? \`\${hhmm}:[0-5]\\\\d\` : \`\${hhmm}:[0-5]\\\\d\\\\.\\\\d{\${args.precision}}\` : \`\${hhmm}(?::[0-5]\\\\d(?:\\\\.\\\\d+)?)?\`; - return regex; -} -__name(timeSource, "timeSource"); -function time(args) { - return new RegExp(\`^\${timeSource(args)}\$\`); -} -__name(time, "time"); -function datetime(args) { - const time3 = timeSource({ - precision: args.precision - }); - const opts = [ - "Z" - ]; - if (args.local) opts.push(""); - if (args.offset) opts.push(\`([+-](?:[01]\\\\d|2[0-3]):[0-5]\\\\d)\`); - const timeRegex2 = \`\${time3}(?:\${opts.join("|")})\`; - return new RegExp(\`^\${dateSource}T(?:\${timeRegex2})\$\`); -} -__name(datetime, "datetime"); -var string = /* @__PURE__ */ __name((params) => { - const regex = params ? \`[\\\\s\\\\S]{\${params?.minimum ?? 0},\${params?.maximum ?? ""}}\` : \`[\\\\s\\\\S]*\`; - return new RegExp(\`^\${regex}\$\`); -}, "string"); -var bigint = /^-?\\d+n?\$/; -var integer = /^-?\\d+\$/; -var number = /^-?\\d+(?:\\.\\d+)?/; -var boolean = /^(?:true|false)\$/i; -var _null = /^null\$/i; -var _undefined = /^undefined\$/i; -var lowercase = /^[^A-Z]*\$/; -var uppercase = /^[^a-z]*\$/; -var hex = /^[0-9a-fA-F]*\$/; -function fixedBase64(bodyLength, padding) { - return new RegExp(\`^[A-Za-z0-9+/]{\${bodyLength}}\${padding}\$\`); -} -__name(fixedBase64, "fixedBase64"); -function fixedBase64url(length) { - return new RegExp(\`^[A-Za-z0-9_-]{\${length}}\$\`); -} -__name(fixedBase64url, "fixedBase64url"); -var md5_hex = /^[0-9a-fA-F]{32}\$/; -var md5_base64 = /* @__PURE__ */ fixedBase64(22, "=="); -var md5_base64url = /* @__PURE__ */ fixedBase64url(22); -var sha1_hex = /^[0-9a-fA-F]{40}\$/; -var sha1_base64 = /* @__PURE__ */ fixedBase64(27, "="); -var sha1_base64url = /* @__PURE__ */ fixedBase64url(27); -var sha256_hex = /^[0-9a-fA-F]{64}\$/; -var sha256_base64 = /* @__PURE__ */ fixedBase64(43, "="); -var sha256_base64url = /* @__PURE__ */ fixedBase64url(43); -var sha384_hex = /^[0-9a-fA-F]{96}\$/; -var sha384_base64 = /* @__PURE__ */ fixedBase64(64, ""); -var sha384_base64url = /* @__PURE__ */ fixedBase64url(64); -var sha512_hex = /^[0-9a-fA-F]{128}\$/; -var sha512_base64 = /* @__PURE__ */ fixedBase64(86, "=="); -var sha512_base64url = /* @__PURE__ */ fixedBase64url(86); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/core/checks.js -var \$ZodCheck = /* @__PURE__ */ \$constructor("\$ZodCheck", (inst, def) => { - var _a17; - inst._zod ?? (inst._zod = {}); - inst._zod.def = def; - (_a17 = inst._zod).onattach ?? (_a17.onattach = []); -}); -var numericOriginMap = { - number: "number", - bigint: "bigint", - object: "date" -}; -var \$ZodCheckLessThan = /* @__PURE__ */ \$constructor("\$ZodCheckLessThan", (inst, def) => { - \$ZodCheck.init(inst, def); - const origin = numericOriginMap[typeof def.value]; - inst._zod.onattach.push((inst2) => { - const bag = inst2._zod.bag; - const curr = (def.inclusive ? bag.maximum : bag.exclusiveMaximum) ?? Number.POSITIVE_INFINITY; - if (def.value < curr) { - if (def.inclusive) bag.maximum = def.value; - else bag.exclusiveMaximum = def.value; - } - }); - inst._zod.check = (payload) => { - if (def.inclusive ? payload.value <= def.value : payload.value < def.value) { - return; - } - payload.issues.push({ - origin, - code: "too_big", - maximum: def.value, - input: payload.value, - inclusive: def.inclusive, - inst, - continue: !def.abort - }); - }; -}); -var \$ZodCheckGreaterThan = /* @__PURE__ */ \$constructor("\$ZodCheckGreaterThan", (inst, def) => { - \$ZodCheck.init(inst, def); - const origin = numericOriginMap[typeof def.value]; - inst._zod.onattach.push((inst2) => { - const bag = inst2._zod.bag; - const curr = (def.inclusive ? bag.minimum : bag.exclusiveMinimum) ?? Number.NEGATIVE_INFINITY; - if (def.value > curr) { - if (def.inclusive) bag.minimum = def.value; - else bag.exclusiveMinimum = def.value; - } - }); - inst._zod.check = (payload) => { - if (def.inclusive ? payload.value >= def.value : payload.value > def.value) { - return; - } - payload.issues.push({ - origin, - code: "too_small", - minimum: def.value, - input: payload.value, - inclusive: def.inclusive, - inst, - continue: !def.abort - }); - }; -}); -var \$ZodCheckMultipleOf = /* @__PURE__ */ \$constructor("\$ZodCheckMultipleOf", (inst, def) => { - \$ZodCheck.init(inst, def); - inst._zod.onattach.push((inst2) => { - var _a17; - (_a17 = inst2._zod.bag).multipleOf ?? (_a17.multipleOf = def.value); - }); - inst._zod.check = (payload) => { - if (typeof payload.value !== typeof def.value) throw new Error("Cannot mix number and bigint in multiple_of check."); - const isMultiple = typeof payload.value === "bigint" ? payload.value % def.value === BigInt(0) : floatSafeRemainder(payload.value, def.value) === 0; - if (isMultiple) return; - payload.issues.push({ - origin: typeof payload.value, - code: "not_multiple_of", - divisor: def.value, - input: payload.value, - inst, - continue: !def.abort - }); - }; -}); -var \$ZodCheckNumberFormat = /* @__PURE__ */ \$constructor("\$ZodCheckNumberFormat", (inst, def) => { - \$ZodCheck.init(inst, def); - def.format = def.format || "float64"; - const isInt = def.format?.includes("int"); - const origin = isInt ? "int" : "number"; - const [minimum, maximum] = NUMBER_FORMAT_RANGES[def.format]; - inst._zod.onattach.push((inst2) => { - const bag = inst2._zod.bag; - bag.format = def.format; - bag.minimum = minimum; - bag.maximum = maximum; - if (isInt) bag.pattern = integer; - }); - inst._zod.check = (payload) => { - const input = payload.value; - if (isInt) { - if (!Number.isInteger(input)) { - payload.issues.push({ - expected: origin, - format: def.format, - code: "invalid_type", - continue: false, - input, - inst - }); - return; - } - if (!Number.isSafeInteger(input)) { - if (input > 0) { - payload.issues.push({ - input, - code: "too_big", - maximum: Number.MAX_SAFE_INTEGER, - note: "Integers must be within the safe integer range.", - inst, - origin, - continue: !def.abort - }); - } else { - payload.issues.push({ - input, - code: "too_small", - minimum: Number.MIN_SAFE_INTEGER, - note: "Integers must be within the safe integer range.", - inst, - origin, - continue: !def.abort - }); - } - return; - } - } - if (input < minimum) { - payload.issues.push({ - origin: "number", - input, - code: "too_small", - minimum, - inclusive: true, - inst, - continue: !def.abort - }); - } - if (input > maximum) { - payload.issues.push({ - origin: "number", - input, - code: "too_big", - maximum, - inst - }); - } - }; -}); -var \$ZodCheckBigIntFormat = /* @__PURE__ */ \$constructor("\$ZodCheckBigIntFormat", (inst, def) => { - \$ZodCheck.init(inst, def); - const [minimum, maximum] = BIGINT_FORMAT_RANGES[def.format]; - inst._zod.onattach.push((inst2) => { - const bag = inst2._zod.bag; - bag.format = def.format; - bag.minimum = minimum; - bag.maximum = maximum; - }); - inst._zod.check = (payload) => { - const input = payload.value; - if (input < minimum) { - payload.issues.push({ - origin: "bigint", - input, - code: "too_small", - minimum, - inclusive: true, - inst, - continue: !def.abort - }); - } - if (input > maximum) { - payload.issues.push({ - origin: "bigint", - input, - code: "too_big", - maximum, - inst - }); - } - }; -}); -var \$ZodCheckMaxSize = /* @__PURE__ */ \$constructor("\$ZodCheckMaxSize", (inst, def) => { - var _a17; - \$ZodCheck.init(inst, def); - (_a17 = inst._zod.def).when ?? (_a17.when = (payload) => { - const val = payload.value; - return !nullish(val) && val.size !== void 0; - }); - inst._zod.onattach.push((inst2) => { - const curr = inst2._zod.bag.maximum ?? Number.POSITIVE_INFINITY; - if (def.maximum < curr) inst2._zod.bag.maximum = def.maximum; - }); - inst._zod.check = (payload) => { - const input = payload.value; - const size = input.size; - if (size <= def.maximum) return; - payload.issues.push({ - origin: getSizableOrigin(input), - code: "too_big", - maximum: def.maximum, - inclusive: true, - input, - inst, - continue: !def.abort - }); - }; -}); -var \$ZodCheckMinSize = /* @__PURE__ */ \$constructor("\$ZodCheckMinSize", (inst, def) => { - var _a17; - \$ZodCheck.init(inst, def); - (_a17 = inst._zod.def).when ?? (_a17.when = (payload) => { - const val = payload.value; - return !nullish(val) && val.size !== void 0; - }); - inst._zod.onattach.push((inst2) => { - const curr = inst2._zod.bag.minimum ?? Number.NEGATIVE_INFINITY; - if (def.minimum > curr) inst2._zod.bag.minimum = def.minimum; - }); - inst._zod.check = (payload) => { - const input = payload.value; - const size = input.size; - if (size >= def.minimum) return; - payload.issues.push({ - origin: getSizableOrigin(input), - code: "too_small", - minimum: def.minimum, - inclusive: true, - input, - inst, - continue: !def.abort - }); - }; -}); -var \$ZodCheckSizeEquals = /* @__PURE__ */ \$constructor("\$ZodCheckSizeEquals", (inst, def) => { - var _a17; - \$ZodCheck.init(inst, def); - (_a17 = inst._zod.def).when ?? (_a17.when = (payload) => { - const val = payload.value; - return !nullish(val) && val.size !== void 0; - }); - inst._zod.onattach.push((inst2) => { - const bag = inst2._zod.bag; - bag.minimum = def.size; - bag.maximum = def.size; - bag.size = def.size; - }); - inst._zod.check = (payload) => { - const input = payload.value; - const size = input.size; - if (size === def.size) return; - const tooBig = size > def.size; - payload.issues.push({ - origin: getSizableOrigin(input), - ...tooBig ? { - code: "too_big", - maximum: def.size - } : { - code: "too_small", - minimum: def.size - }, - inclusive: true, - exact: true, - input: payload.value, - inst, - continue: !def.abort - }); - }; -}); -var \$ZodCheckMaxLength = /* @__PURE__ */ \$constructor("\$ZodCheckMaxLength", (inst, def) => { - var _a17; - \$ZodCheck.init(inst, def); - (_a17 = inst._zod.def).when ?? (_a17.when = (payload) => { - const val = payload.value; - return !nullish(val) && val.length !== void 0; - }); - inst._zod.onattach.push((inst2) => { - const curr = inst2._zod.bag.maximum ?? Number.POSITIVE_INFINITY; - if (def.maximum < curr) inst2._zod.bag.maximum = def.maximum; - }); - inst._zod.check = (payload) => { - const input = payload.value; - const length = input.length; - if (length <= def.maximum) return; - const origin = getLengthableOrigin(input); - payload.issues.push({ - origin, - code: "too_big", - maximum: def.maximum, - inclusive: true, - input, - inst, - continue: !def.abort - }); - }; -}); -var \$ZodCheckMinLength = /* @__PURE__ */ \$constructor("\$ZodCheckMinLength", (inst, def) => { - var _a17; - \$ZodCheck.init(inst, def); - (_a17 = inst._zod.def).when ?? (_a17.when = (payload) => { - const val = payload.value; - return !nullish(val) && val.length !== void 0; - }); - inst._zod.onattach.push((inst2) => { - const curr = inst2._zod.bag.minimum ?? Number.NEGATIVE_INFINITY; - if (def.minimum > curr) inst2._zod.bag.minimum = def.minimum; - }); - inst._zod.check = (payload) => { - const input = payload.value; - const length = input.length; - if (length >= def.minimum) return; - const origin = getLengthableOrigin(input); - payload.issues.push({ - origin, - code: "too_small", - minimum: def.minimum, - inclusive: true, - input, - inst, - continue: !def.abort - }); - }; -}); -var \$ZodCheckLengthEquals = /* @__PURE__ */ \$constructor("\$ZodCheckLengthEquals", (inst, def) => { - var _a17; - \$ZodCheck.init(inst, def); - (_a17 = inst._zod.def).when ?? (_a17.when = (payload) => { - const val = payload.value; - return !nullish(val) && val.length !== void 0; - }); - inst._zod.onattach.push((inst2) => { - const bag = inst2._zod.bag; - bag.minimum = def.length; - bag.maximum = def.length; - bag.length = def.length; - }); - inst._zod.check = (payload) => { - const input = payload.value; - const length = input.length; - if (length === def.length) return; - const origin = getLengthableOrigin(input); - const tooBig = length > def.length; - payload.issues.push({ - origin, - ...tooBig ? { - code: "too_big", - maximum: def.length - } : { - code: "too_small", - minimum: def.length - }, - inclusive: true, - exact: true, - input: payload.value, - inst, - continue: !def.abort - }); - }; -}); -var \$ZodCheckStringFormat = /* @__PURE__ */ \$constructor("\$ZodCheckStringFormat", (inst, def) => { - var _a17, _b8; - \$ZodCheck.init(inst, def); - inst._zod.onattach.push((inst2) => { - const bag = inst2._zod.bag; - bag.format = def.format; - if (def.pattern) { - bag.patterns ?? (bag.patterns = /* @__PURE__ */ new Set()); - bag.patterns.add(def.pattern); - } - }); - if (def.pattern) (_a17 = inst._zod).check ?? (_a17.check = (payload) => { - def.pattern.lastIndex = 0; - if (def.pattern.test(payload.value)) return; - payload.issues.push({ - origin: "string", - code: "invalid_format", - format: def.format, - input: payload.value, - ...def.pattern ? { - pattern: def.pattern.toString() - } : {}, - inst, - continue: !def.abort - }); - }); - else (_b8 = inst._zod).check ?? (_b8.check = () => { - }); -}); -var \$ZodCheckRegex = /* @__PURE__ */ \$constructor("\$ZodCheckRegex", (inst, def) => { - \$ZodCheckStringFormat.init(inst, def); - inst._zod.check = (payload) => { - def.pattern.lastIndex = 0; - if (def.pattern.test(payload.value)) return; - payload.issues.push({ - origin: "string", - code: "invalid_format", - format: "regex", - input: payload.value, - pattern: def.pattern.toString(), - inst, - continue: !def.abort - }); - }; -}); -var \$ZodCheckLowerCase = /* @__PURE__ */ \$constructor("\$ZodCheckLowerCase", (inst, def) => { - def.pattern ?? (def.pattern = lowercase); - \$ZodCheckStringFormat.init(inst, def); -}); -var \$ZodCheckUpperCase = /* @__PURE__ */ \$constructor("\$ZodCheckUpperCase", (inst, def) => { - def.pattern ?? (def.pattern = uppercase); - \$ZodCheckStringFormat.init(inst, def); -}); -var \$ZodCheckIncludes = /* @__PURE__ */ \$constructor("\$ZodCheckIncludes", (inst, def) => { - \$ZodCheck.init(inst, def); - const escapedRegex = escapeRegex(def.includes); - const pattern = new RegExp(typeof def.position === "number" ? \`^.{\${def.position}}\${escapedRegex}\` : escapedRegex); - def.pattern = pattern; - inst._zod.onattach.push((inst2) => { - const bag = inst2._zod.bag; - bag.patterns ?? (bag.patterns = /* @__PURE__ */ new Set()); - bag.patterns.add(pattern); - }); - inst._zod.check = (payload) => { - if (payload.value.includes(def.includes, def.position)) return; - payload.issues.push({ - origin: "string", - code: "invalid_format", - format: "includes", - includes: def.includes, - input: payload.value, - inst, - continue: !def.abort - }); - }; -}); -var \$ZodCheckStartsWith = /* @__PURE__ */ \$constructor("\$ZodCheckStartsWith", (inst, def) => { - \$ZodCheck.init(inst, def); - const pattern = new RegExp(\`^\${escapeRegex(def.prefix)}.*\`); - def.pattern ?? (def.pattern = pattern); - inst._zod.onattach.push((inst2) => { - const bag = inst2._zod.bag; - bag.patterns ?? (bag.patterns = /* @__PURE__ */ new Set()); - bag.patterns.add(pattern); - }); - inst._zod.check = (payload) => { - if (payload.value.startsWith(def.prefix)) return; - payload.issues.push({ - origin: "string", - code: "invalid_format", - format: "starts_with", - prefix: def.prefix, - input: payload.value, - inst, - continue: !def.abort - }); - }; -}); -var \$ZodCheckEndsWith = /* @__PURE__ */ \$constructor("\$ZodCheckEndsWith", (inst, def) => { - \$ZodCheck.init(inst, def); - const pattern = new RegExp(\`.*\${escapeRegex(def.suffix)}\$\`); - def.pattern ?? (def.pattern = pattern); - inst._zod.onattach.push((inst2) => { - const bag = inst2._zod.bag; - bag.patterns ?? (bag.patterns = /* @__PURE__ */ new Set()); - bag.patterns.add(pattern); - }); - inst._zod.check = (payload) => { - if (payload.value.endsWith(def.suffix)) return; - payload.issues.push({ - origin: "string", - code: "invalid_format", - format: "ends_with", - suffix: def.suffix, - input: payload.value, - inst, - continue: !def.abort - }); - }; -}); -function handleCheckPropertyResult(result, payload, property) { - if (result.issues.length) { - payload.issues.push(...prefixIssues(property, result.issues)); - } -} -__name(handleCheckPropertyResult, "handleCheckPropertyResult"); -var \$ZodCheckProperty = /* @__PURE__ */ \$constructor("\$ZodCheckProperty", (inst, def) => { - \$ZodCheck.init(inst, def); - inst._zod.check = (payload) => { - const result = def.schema._zod.run({ - value: payload.value[def.property], - issues: [] - }, {}); - if (result instanceof Promise) { - return result.then((result2) => handleCheckPropertyResult(result2, payload, def.property)); - } - handleCheckPropertyResult(result, payload, def.property); - return; - }; -}); -var \$ZodCheckMimeType = /* @__PURE__ */ \$constructor("\$ZodCheckMimeType", (inst, def) => { - \$ZodCheck.init(inst, def); - const mimeSet = new Set(def.mime); - inst._zod.onattach.push((inst2) => { - inst2._zod.bag.mime = def.mime; - }); - inst._zod.check = (payload) => { - if (mimeSet.has(payload.value.type)) return; - payload.issues.push({ - code: "invalid_value", - values: def.mime, - input: payload.value.type, - inst, - continue: !def.abort - }); - }; -}); -var \$ZodCheckOverwrite = /* @__PURE__ */ \$constructor("\$ZodCheckOverwrite", (inst, def) => { - \$ZodCheck.init(inst, def); - inst._zod.check = (payload) => { - payload.value = def.tx(payload.value); - }; -}); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/core/doc.js -var Doc = class { - static { - __name(this, "Doc"); - } - constructor(args = []) { - this.content = []; - this.indent = 0; - if (this) this.args = args; - } - indented(fn) { - this.indent += 1; - fn(this); - this.indent -= 1; - } - write(arg) { - if (typeof arg === "function") { - arg(this, { - execution: "sync" - }); - arg(this, { - execution: "async" - }); - return; - } - const content = arg; - const lines = content.split("\\n").filter((x) => x); - const minIndent = Math.min(...lines.map((x) => x.length - x.trimStart().length)); - const dedented = lines.map((x) => x.slice(minIndent)).map((x) => " ".repeat(this.indent * 2) + x); - for (const line of dedented) { - this.content.push(line); - } - } - compile() { - const F = Function; - const args = this?.args; - const content = this?.content ?? [ - \`\` - ]; - const lines = [ - ...content.map((x) => \` \${x}\`) - ]; - return new F(...args, lines.join("\\n")); - } -}; - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/core/versions.js -var version = { - major: 4, - minor: 1, - patch: 11 -}; - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/core/schemas.js -var \$ZodType = /* @__PURE__ */ \$constructor("\$ZodType", (inst, def) => { - var _a17; - inst ?? (inst = {}); - inst._zod.def = def; - inst._zod.bag = inst._zod.bag || {}; - inst._zod.version = version; - const checks = [ - ...inst._zod.def.checks ?? [] - ]; - if (inst._zod.traits.has("\$ZodCheck")) { - checks.unshift(inst); - } - for (const ch of checks) { - for (const fn of ch._zod.onattach) { - fn(inst); - } - } - if (checks.length === 0) { - (_a17 = inst._zod).deferred ?? (_a17.deferred = []); - inst._zod.deferred?.push(() => { - inst._zod.run = inst._zod.parse; - }); - } else { - const runChecks = /* @__PURE__ */ __name((payload, checks2, ctx) => { - let isAborted2 = aborted(payload); - let asyncResult; - for (const ch of checks2) { - if (ch._zod.def.when) { - const shouldRun = ch._zod.def.when(payload); - if (!shouldRun) continue; - } else if (isAborted2) { - continue; - } - const currLen = payload.issues.length; - const _ = ch._zod.check(payload); - if (_ instanceof Promise && ctx?.async === false) { - throw new \$ZodAsyncError(); - } - if (asyncResult || _ instanceof Promise) { - asyncResult = (asyncResult ?? Promise.resolve()).then(async () => { - await _; - const nextLen = payload.issues.length; - if (nextLen === currLen) return; - if (!isAborted2) isAborted2 = aborted(payload, currLen); - }); - } else { - const nextLen = payload.issues.length; - if (nextLen === currLen) continue; - if (!isAborted2) isAborted2 = aborted(payload, currLen); - } - } - if (asyncResult) { - return asyncResult.then(() => { - return payload; - }); - } - return payload; - }, "runChecks"); - const handleCanaryResult = /* @__PURE__ */ __name((canary, payload, ctx) => { - if (aborted(canary)) { - canary.aborted = true; - return canary; - } - const checkResult = runChecks(payload, checks, ctx); - if (checkResult instanceof Promise) { - if (ctx.async === false) throw new \$ZodAsyncError(); - return checkResult.then((checkResult2) => inst._zod.parse(checkResult2, ctx)); - } - return inst._zod.parse(checkResult, ctx); - }, "handleCanaryResult"); - inst._zod.run = (payload, ctx) => { - if (ctx.skipChecks) { - return inst._zod.parse(payload, ctx); - } - if (ctx.direction === "backward") { - const canary = inst._zod.parse({ - value: payload.value, - issues: [] - }, { - ...ctx, - skipChecks: true - }); - if (canary instanceof Promise) { - return canary.then((canary2) => { - return handleCanaryResult(canary2, payload, ctx); - }); - } - return handleCanaryResult(canary, payload, ctx); - } - const result = inst._zod.parse(payload, ctx); - if (result instanceof Promise) { - if (ctx.async === false) throw new \$ZodAsyncError(); - return result.then((result2) => runChecks(result2, checks, ctx)); - } - return runChecks(result, checks, ctx); - }; - } - inst["~standard"] = { - validate: /* @__PURE__ */ __name((value) => { - try { - const r = safeParse(inst, value); - return r.success ? { - value: r.data - } : { - issues: r.error?.issues - }; - } catch (_) { - return safeParseAsync(inst, value).then((r) => r.success ? { - value: r.data - } : { - issues: r.error?.issues - }); - } - }, "validate"), - vendor: "zod", - version: 1 - }; -}); -var \$ZodString = /* @__PURE__ */ \$constructor("\$ZodString", (inst, def) => { - \$ZodType.init(inst, def); - inst._zod.pattern = [ - ...inst?._zod.bag?.patterns ?? [] - ].pop() ?? string(inst._zod.bag); - inst._zod.parse = (payload, _) => { - if (def.coerce) try { - payload.value = String(payload.value); - } catch (_2) { - } - if (typeof payload.value === "string") return payload; - payload.issues.push({ - expected: "string", - code: "invalid_type", - input: payload.value, - inst - }); - return payload; - }; -}); -var \$ZodStringFormat = /* @__PURE__ */ \$constructor("\$ZodStringFormat", (inst, def) => { - \$ZodCheckStringFormat.init(inst, def); - \$ZodString.init(inst, def); -}); -var \$ZodGUID = /* @__PURE__ */ \$constructor("\$ZodGUID", (inst, def) => { - def.pattern ?? (def.pattern = guid); - \$ZodStringFormat.init(inst, def); -}); -var \$ZodUUID = /* @__PURE__ */ \$constructor("\$ZodUUID", (inst, def) => { - if (def.version) { - const versionMap = { - v1: 1, - v2: 2, - v3: 3, - v4: 4, - v5: 5, - v6: 6, - v7: 7, - v8: 8 - }; - const v = versionMap[def.version]; - if (v === void 0) throw new Error(\`Invalid UUID version: "\${def.version}"\`); - def.pattern ?? (def.pattern = uuid(v)); - } else def.pattern ?? (def.pattern = uuid()); - \$ZodStringFormat.init(inst, def); -}); -var \$ZodEmail = /* @__PURE__ */ \$constructor("\$ZodEmail", (inst, def) => { - def.pattern ?? (def.pattern = email); - \$ZodStringFormat.init(inst, def); -}); -var \$ZodURL = /* @__PURE__ */ \$constructor("\$ZodURL", (inst, def) => { - \$ZodStringFormat.init(inst, def); - inst._zod.check = (payload) => { - try { - const trimmed = payload.value.trim(); - const url2 = new URL(trimmed); - if (def.hostname) { - def.hostname.lastIndex = 0; - if (!def.hostname.test(url2.hostname)) { - payload.issues.push({ - code: "invalid_format", - format: "url", - note: "Invalid hostname", - pattern: hostname.source, - input: payload.value, - inst, - continue: !def.abort - }); - } - } - if (def.protocol) { - def.protocol.lastIndex = 0; - if (!def.protocol.test(url2.protocol.endsWith(":") ? url2.protocol.slice(0, -1) : url2.protocol)) { - payload.issues.push({ - code: "invalid_format", - format: "url", - note: "Invalid protocol", - pattern: def.protocol.source, - input: payload.value, - inst, - continue: !def.abort - }); - } - } - if (def.normalize) { - payload.value = url2.href; - } else { - payload.value = trimmed; - } - return; - } catch (_) { - payload.issues.push({ - code: "invalid_format", - format: "url", - input: payload.value, - inst, - continue: !def.abort - }); - } - }; -}); -var \$ZodEmoji = /* @__PURE__ */ \$constructor("\$ZodEmoji", (inst, def) => { - def.pattern ?? (def.pattern = emoji()); - \$ZodStringFormat.init(inst, def); -}); -var \$ZodNanoID = /* @__PURE__ */ \$constructor("\$ZodNanoID", (inst, def) => { - def.pattern ?? (def.pattern = nanoid); - \$ZodStringFormat.init(inst, def); -}); -var \$ZodCUID = /* @__PURE__ */ \$constructor("\$ZodCUID", (inst, def) => { - def.pattern ?? (def.pattern = cuid); - \$ZodStringFormat.init(inst, def); -}); -var \$ZodCUID2 = /* @__PURE__ */ \$constructor("\$ZodCUID2", (inst, def) => { - def.pattern ?? (def.pattern = cuid2); - \$ZodStringFormat.init(inst, def); -}); -var \$ZodULID = /* @__PURE__ */ \$constructor("\$ZodULID", (inst, def) => { - def.pattern ?? (def.pattern = ulid); - \$ZodStringFormat.init(inst, def); -}); -var \$ZodXID = /* @__PURE__ */ \$constructor("\$ZodXID", (inst, def) => { - def.pattern ?? (def.pattern = xid); - \$ZodStringFormat.init(inst, def); -}); -var \$ZodKSUID = /* @__PURE__ */ \$constructor("\$ZodKSUID", (inst, def) => { - def.pattern ?? (def.pattern = ksuid); - \$ZodStringFormat.init(inst, def); -}); -var \$ZodISODateTime = /* @__PURE__ */ \$constructor("\$ZodISODateTime", (inst, def) => { - def.pattern ?? (def.pattern = datetime(def)); - \$ZodStringFormat.init(inst, def); -}); -var \$ZodISODate = /* @__PURE__ */ \$constructor("\$ZodISODate", (inst, def) => { - def.pattern ?? (def.pattern = date); - \$ZodStringFormat.init(inst, def); -}); -var \$ZodISOTime = /* @__PURE__ */ \$constructor("\$ZodISOTime", (inst, def) => { - def.pattern ?? (def.pattern = time(def)); - \$ZodStringFormat.init(inst, def); -}); -var \$ZodISODuration = /* @__PURE__ */ \$constructor("\$ZodISODuration", (inst, def) => { - def.pattern ?? (def.pattern = duration); - \$ZodStringFormat.init(inst, def); -}); -var \$ZodIPv4 = /* @__PURE__ */ \$constructor("\$ZodIPv4", (inst, def) => { - def.pattern ?? (def.pattern = ipv4); - \$ZodStringFormat.init(inst, def); - inst._zod.onattach.push((inst2) => { - const bag = inst2._zod.bag; - bag.format = \`ipv4\`; - }); -}); -var \$ZodIPv6 = /* @__PURE__ */ \$constructor("\$ZodIPv6", (inst, def) => { - def.pattern ?? (def.pattern = ipv6); - \$ZodStringFormat.init(inst, def); - inst._zod.onattach.push((inst2) => { - const bag = inst2._zod.bag; - bag.format = \`ipv6\`; - }); - inst._zod.check = (payload) => { - try { - new URL(\`http://[\${payload.value}]\`); - } catch { - payload.issues.push({ - code: "invalid_format", - format: "ipv6", - input: payload.value, - inst, - continue: !def.abort - }); - } - }; -}); -var \$ZodCIDRv4 = /* @__PURE__ */ \$constructor("\$ZodCIDRv4", (inst, def) => { - def.pattern ?? (def.pattern = cidrv4); - \$ZodStringFormat.init(inst, def); -}); -var \$ZodCIDRv6 = /* @__PURE__ */ \$constructor("\$ZodCIDRv6", (inst, def) => { - def.pattern ?? (def.pattern = cidrv6); - \$ZodStringFormat.init(inst, def); - inst._zod.check = (payload) => { - const parts = payload.value.split("/"); - try { - if (parts.length !== 2) throw new Error(); - const [address, prefix] = parts; - if (!prefix) throw new Error(); - const prefixNum = Number(prefix); - if (\`\${prefixNum}\` !== prefix) throw new Error(); - if (prefixNum < 0 || prefixNum > 128) throw new Error(); - new URL(\`http://[\${address}]\`); - } catch { - payload.issues.push({ - code: "invalid_format", - format: "cidrv6", - input: payload.value, - inst, - continue: !def.abort - }); - } - }; -}); -function isValidBase64(data) { - if (data === "") return true; - if (data.length % 4 !== 0) return false; - try { - atob(data); - return true; - } catch { - return false; - } -} -__name(isValidBase64, "isValidBase64"); -var \$ZodBase64 = /* @__PURE__ */ \$constructor("\$ZodBase64", (inst, def) => { - def.pattern ?? (def.pattern = base64); - \$ZodStringFormat.init(inst, def); - inst._zod.onattach.push((inst2) => { - inst2._zod.bag.contentEncoding = "base64"; - }); - inst._zod.check = (payload) => { - if (isValidBase64(payload.value)) return; - payload.issues.push({ - code: "invalid_format", - format: "base64", - input: payload.value, - inst, - continue: !def.abort - }); - }; -}); -function isValidBase64URL(data) { - if (!base64url.test(data)) return false; - const base643 = data.replace(/[-_]/g, (c) => c === "-" ? "+" : "/"); - const padded = base643.padEnd(Math.ceil(base643.length / 4) * 4, "="); - return isValidBase64(padded); -} -__name(isValidBase64URL, "isValidBase64URL"); -var \$ZodBase64URL = /* @__PURE__ */ \$constructor("\$ZodBase64URL", (inst, def) => { - def.pattern ?? (def.pattern = base64url); - \$ZodStringFormat.init(inst, def); - inst._zod.onattach.push((inst2) => { - inst2._zod.bag.contentEncoding = "base64url"; - }); - inst._zod.check = (payload) => { - if (isValidBase64URL(payload.value)) return; - payload.issues.push({ - code: "invalid_format", - format: "base64url", - input: payload.value, - inst, - continue: !def.abort - }); - }; -}); -var \$ZodE164 = /* @__PURE__ */ \$constructor("\$ZodE164", (inst, def) => { - def.pattern ?? (def.pattern = e164); - \$ZodStringFormat.init(inst, def); -}); -function isValidJWT(token, algorithm = null) { - try { - const tokensParts = token.split("."); - if (tokensParts.length !== 3) return false; - const [header] = tokensParts; - if (!header) return false; - const parsedHeader = JSON.parse(atob(header)); - if ("typ" in parsedHeader && parsedHeader?.typ !== "JWT") return false; - if (!parsedHeader.alg) return false; - if (algorithm && (!("alg" in parsedHeader) || parsedHeader.alg !== algorithm)) return false; - return true; - } catch { - return false; - } -} -__name(isValidJWT, "isValidJWT"); -var \$ZodJWT = /* @__PURE__ */ \$constructor("\$ZodJWT", (inst, def) => { - \$ZodStringFormat.init(inst, def); - inst._zod.check = (payload) => { - if (isValidJWT(payload.value, def.alg)) return; - payload.issues.push({ - code: "invalid_format", - format: "jwt", - input: payload.value, - inst, - continue: !def.abort - }); - }; -}); -var \$ZodCustomStringFormat = /* @__PURE__ */ \$constructor("\$ZodCustomStringFormat", (inst, def) => { - \$ZodStringFormat.init(inst, def); - inst._zod.check = (payload) => { - if (def.fn(payload.value)) return; - payload.issues.push({ - code: "invalid_format", - format: def.format, - input: payload.value, - inst, - continue: !def.abort - }); - }; -}); -var \$ZodNumber = /* @__PURE__ */ \$constructor("\$ZodNumber", (inst, def) => { - \$ZodType.init(inst, def); - inst._zod.pattern = inst._zod.bag.pattern ?? number; - inst._zod.parse = (payload, _ctx) => { - if (def.coerce) try { - payload.value = Number(payload.value); - } catch (_) { - } - const input = payload.value; - if (typeof input === "number" && !Number.isNaN(input) && Number.isFinite(input)) { - return payload; - } - const received = typeof input === "number" ? Number.isNaN(input) ? "NaN" : !Number.isFinite(input) ? "Infinity" : void 0 : void 0; - payload.issues.push({ - expected: "number", - code: "invalid_type", - input, - inst, - ...received ? { - received - } : {} - }); - return payload; - }; -}); -var \$ZodNumberFormat = /* @__PURE__ */ \$constructor("\$ZodNumber", (inst, def) => { - \$ZodCheckNumberFormat.init(inst, def); - \$ZodNumber.init(inst, def); -}); -var \$ZodBoolean = /* @__PURE__ */ \$constructor("\$ZodBoolean", (inst, def) => { - \$ZodType.init(inst, def); - inst._zod.pattern = boolean; - inst._zod.parse = (payload, _ctx) => { - if (def.coerce) try { - payload.value = Boolean(payload.value); - } catch (_) { - } - const input = payload.value; - if (typeof input === "boolean") return payload; - payload.issues.push({ - expected: "boolean", - code: "invalid_type", - input, - inst - }); - return payload; - }; -}); -var \$ZodBigInt = /* @__PURE__ */ \$constructor("\$ZodBigInt", (inst, def) => { - \$ZodType.init(inst, def); - inst._zod.pattern = bigint; - inst._zod.parse = (payload, _ctx) => { - if (def.coerce) try { - payload.value = BigInt(payload.value); - } catch (_) { - } - if (typeof payload.value === "bigint") return payload; - payload.issues.push({ - expected: "bigint", - code: "invalid_type", - input: payload.value, - inst - }); - return payload; - }; -}); -var \$ZodBigIntFormat = /* @__PURE__ */ \$constructor("\$ZodBigInt", (inst, def) => { - \$ZodCheckBigIntFormat.init(inst, def); - \$ZodBigInt.init(inst, def); -}); -var \$ZodSymbol = /* @__PURE__ */ \$constructor("\$ZodSymbol", (inst, def) => { - \$ZodType.init(inst, def); - inst._zod.parse = (payload, _ctx) => { - const input = payload.value; - if (typeof input === "symbol") return payload; - payload.issues.push({ - expected: "symbol", - code: "invalid_type", - input, - inst - }); - return payload; - }; -}); -var \$ZodUndefined = /* @__PURE__ */ \$constructor("\$ZodUndefined", (inst, def) => { - \$ZodType.init(inst, def); - inst._zod.pattern = _undefined; - inst._zod.values = /* @__PURE__ */ new Set([ - void 0 - ]); - inst._zod.optin = "optional"; - inst._zod.optout = "optional"; - inst._zod.parse = (payload, _ctx) => { - const input = payload.value; - if (typeof input === "undefined") return payload; - payload.issues.push({ - expected: "undefined", - code: "invalid_type", - input, - inst - }); - return payload; - }; -}); -var \$ZodNull = /* @__PURE__ */ \$constructor("\$ZodNull", (inst, def) => { - \$ZodType.init(inst, def); - inst._zod.pattern = _null; - inst._zod.values = /* @__PURE__ */ new Set([ - null - ]); - inst._zod.parse = (payload, _ctx) => { - const input = payload.value; - if (input === null) return payload; - payload.issues.push({ - expected: "null", - code: "invalid_type", - input, - inst - }); - return payload; - }; -}); -var \$ZodAny = /* @__PURE__ */ \$constructor("\$ZodAny", (inst, def) => { - \$ZodType.init(inst, def); - inst._zod.parse = (payload) => payload; -}); -var \$ZodUnknown = /* @__PURE__ */ \$constructor("\$ZodUnknown", (inst, def) => { - \$ZodType.init(inst, def); - inst._zod.parse = (payload) => payload; -}); -var \$ZodNever = /* @__PURE__ */ \$constructor("\$ZodNever", (inst, def) => { - \$ZodType.init(inst, def); - inst._zod.parse = (payload, _ctx) => { - payload.issues.push({ - expected: "never", - code: "invalid_type", - input: payload.value, - inst - }); - return payload; - }; -}); -var \$ZodVoid = /* @__PURE__ */ \$constructor("\$ZodVoid", (inst, def) => { - \$ZodType.init(inst, def); - inst._zod.parse = (payload, _ctx) => { - const input = payload.value; - if (typeof input === "undefined") return payload; - payload.issues.push({ - expected: "void", - code: "invalid_type", - input, - inst - }); - return payload; - }; -}); -var \$ZodDate = /* @__PURE__ */ \$constructor("\$ZodDate", (inst, def) => { - \$ZodType.init(inst, def); - inst._zod.parse = (payload, _ctx) => { - if (def.coerce) { - try { - payload.value = new Date(payload.value); - } catch (_err) { - } - } - const input = payload.value; - const isDate = input instanceof Date; - const isValidDate = isDate && !Number.isNaN(input.getTime()); - if (isValidDate) return payload; - payload.issues.push({ - expected: "date", - code: "invalid_type", - input, - ...isDate ? { - received: "Invalid Date" - } : {}, - inst - }); - return payload; - }; -}); -function handleArrayResult(result, final, index) { - if (result.issues.length) { - final.issues.push(...prefixIssues(index, result.issues)); - } - final.value[index] = result.value; -} -__name(handleArrayResult, "handleArrayResult"); -var \$ZodArray = /* @__PURE__ */ \$constructor("\$ZodArray", (inst, def) => { - \$ZodType.init(inst, def); - inst._zod.parse = (payload, ctx) => { - const input = payload.value; - if (!Array.isArray(input)) { - payload.issues.push({ - expected: "array", - code: "invalid_type", - input, - inst - }); - return payload; - } - payload.value = Array(input.length); - const proms = []; - for (let i = 0; i < input.length; i++) { - const item = input[i]; - const result = def.element._zod.run({ - value: item, - issues: [] - }, ctx); - if (result instanceof Promise) { - proms.push(result.then((result2) => handleArrayResult(result2, payload, i))); - } else { - handleArrayResult(result, payload, i); - } - } - if (proms.length) { - return Promise.all(proms).then(() => payload); - } - return payload; - }; -}); -function handlePropertyResult(result, final, key, input) { - if (result.issues.length) { - final.issues.push(...prefixIssues(key, result.issues)); - } - if (result.value === void 0) { - if (key in input) { - final.value[key] = void 0; - } - } else { - final.value[key] = result.value; - } -} -__name(handlePropertyResult, "handlePropertyResult"); -function normalizeDef(def) { - const keys = Object.keys(def.shape); - for (const k of keys) { - if (!def.shape?.[k]?._zod?.traits?.has("\$ZodType")) { - throw new Error(\`Invalid element at key "\${k}": expected a Zod schema\`); - } - } - const okeys = optionalKeys(def.shape); - return { - ...def, - keys, - keySet: new Set(keys), - numKeys: keys.length, - optionalKeys: new Set(okeys) - }; -} -__name(normalizeDef, "normalizeDef"); -function handleCatchall(proms, input, payload, ctx, def, inst) { - const unrecognized = []; - const keySet = def.keySet; - const _catchall = def.catchall._zod; - const t = _catchall.def.type; - for (const key of Object.keys(input)) { - if (keySet.has(key)) continue; - if (t === "never") { - unrecognized.push(key); - continue; - } - const r = _catchall.run({ - value: input[key], - issues: [] - }, ctx); - if (r instanceof Promise) { - proms.push(r.then((r2) => handlePropertyResult(r2, payload, key, input))); - } else { - handlePropertyResult(r, payload, key, input); - } - } - if (unrecognized.length) { - payload.issues.push({ - code: "unrecognized_keys", - keys: unrecognized, - input, - inst - }); - } - if (!proms.length) return payload; - return Promise.all(proms).then(() => { - return payload; - }); -} -__name(handleCatchall, "handleCatchall"); -var \$ZodObject = /* @__PURE__ */ \$constructor("\$ZodObject", (inst, def) => { - \$ZodType.init(inst, def); - const desc = Object.getOwnPropertyDescriptor(def, "shape"); - if (!desc?.get) { - const sh = def.shape; - Object.defineProperty(def, "shape", { - get: /* @__PURE__ */ __name(() => { - const newSh = { - ...sh - }; - Object.defineProperty(def, "shape", { - value: newSh - }); - return newSh; - }, "get") - }); - } - const _normalized = cached(() => normalizeDef(def)); - defineLazy(inst._zod, "propValues", () => { - const shape = def.shape; - const propValues = {}; - for (const key in shape) { - const field = shape[key]._zod; - if (field.values) { - propValues[key] ?? (propValues[key] = /* @__PURE__ */ new Set()); - for (const v of field.values) propValues[key].add(v); - } - } - return propValues; - }); - const isObject2 = isObject; - const catchall = def.catchall; - let value; - inst._zod.parse = (payload, ctx) => { - value ?? (value = _normalized.value); - const input = payload.value; - if (!isObject2(input)) { - payload.issues.push({ - expected: "object", - code: "invalid_type", - input, - inst - }); - return payload; - } - payload.value = {}; - const proms = []; - const shape = value.shape; - for (const key of value.keys) { - const el = shape[key]; - const r = el._zod.run({ - value: input[key], - issues: [] - }, ctx); - if (r instanceof Promise) { - proms.push(r.then((r2) => handlePropertyResult(r2, payload, key, input))); - } else { - handlePropertyResult(r, payload, key, input); - } - } - if (!catchall) { - return proms.length ? Promise.all(proms).then(() => payload) : payload; - } - return handleCatchall(proms, input, payload, ctx, _normalized.value, inst); - }; -}); -var \$ZodObjectJIT = /* @__PURE__ */ \$constructor("\$ZodObjectJIT", (inst, def) => { - \$ZodObject.init(inst, def); - const superParse = inst._zod.parse; - const _normalized = cached(() => normalizeDef(def)); - const generateFastpass = /* @__PURE__ */ __name((shape) => { - const doc = new Doc([ - "shape", - "payload", - "ctx" - ]); - const normalized = _normalized.value; - const parseStr = /* @__PURE__ */ __name((key) => { - const k = esc(key); - return \`shape[\${k}]._zod.run({ value: input[\${k}], issues: [] }, ctx)\`; - }, "parseStr"); - doc.write(\`const input = payload.value;\`); - const ids = /* @__PURE__ */ Object.create(null); - let counter = 0; - for (const key of normalized.keys) { - ids[key] = \`key_\${counter++}\`; - } - doc.write(\`const newResult = {};\`); - for (const key of normalized.keys) { - const id = ids[key]; - const k = esc(key); - doc.write(\`const \${id} = \${parseStr(key)};\`); - doc.write(\` - if (\${id}.issues.length) { - payload.issues = payload.issues.concat(\${id}.issues.map(iss => ({ - ...iss, - path: iss.path ? [\${k}, ...iss.path] : [\${k}] - }))); - } - - - if (\${id}.value === undefined) { - if (\${k} in input) { - newResult[\${k}] = undefined; - } - } else { - newResult[\${k}] = \${id}.value; - } - - \`); - } - doc.write(\`payload.value = newResult;\`); - doc.write(\`return payload;\`); - const fn = doc.compile(); - return (payload, ctx) => fn(shape, payload, ctx); - }, "generateFastpass"); - let fastpass; - const isObject2 = isObject; - const jit = !globalConfig.jitless; - const allowsEval2 = allowsEval; - const fastEnabled = jit && allowsEval2.value; - const catchall = def.catchall; - let value; - inst._zod.parse = (payload, ctx) => { - value ?? (value = _normalized.value); - const input = payload.value; - if (!isObject2(input)) { - payload.issues.push({ - expected: "object", - code: "invalid_type", - input, - inst - }); - return payload; - } - if (jit && fastEnabled && ctx?.async === false && ctx.jitless !== true) { - if (!fastpass) fastpass = generateFastpass(def.shape); - payload = fastpass(payload, ctx); - if (!catchall) return payload; - return handleCatchall([], input, payload, ctx, value, inst); - } - return superParse(payload, ctx); - }; -}); -function handleUnionResults(results, final, inst, ctx) { - for (const result of results) { - if (result.issues.length === 0) { - final.value = result.value; - return final; - } - } - const nonaborted = results.filter((r) => !aborted(r)); - if (nonaborted.length === 1) { - final.value = nonaborted[0].value; - return nonaborted[0]; - } - final.issues.push({ - code: "invalid_union", - input: final.value, - inst, - errors: results.map((result) => result.issues.map((iss) => finalizeIssue(iss, ctx, config()))) - }); - return final; -} -__name(handleUnionResults, "handleUnionResults"); -var \$ZodUnion = /* @__PURE__ */ \$constructor("\$ZodUnion", (inst, def) => { - \$ZodType.init(inst, def); - defineLazy(inst._zod, "optin", () => def.options.some((o) => o._zod.optin === "optional") ? "optional" : void 0); - defineLazy(inst._zod, "optout", () => def.options.some((o) => o._zod.optout === "optional") ? "optional" : void 0); - defineLazy(inst._zod, "values", () => { - if (def.options.every((o) => o._zod.values)) { - return new Set(def.options.flatMap((option) => Array.from(option._zod.values))); - } - return void 0; - }); - defineLazy(inst._zod, "pattern", () => { - if (def.options.every((o) => o._zod.pattern)) { - const patterns = def.options.map((o) => o._zod.pattern); - return new RegExp(\`^(\${patterns.map((p) => cleanRegex(p.source)).join("|")})\$\`); - } - return void 0; - }); - const single = def.options.length === 1; - const first = def.options[0]._zod.run; - inst._zod.parse = (payload, ctx) => { - if (single) { - return first(payload, ctx); - } - let async = false; - const results = []; - for (const option of def.options) { - const result = option._zod.run({ - value: payload.value, - issues: [] - }, ctx); - if (result instanceof Promise) { - results.push(result); - async = true; - } else { - if (result.issues.length === 0) return result; - results.push(result); - } - } - if (!async) return handleUnionResults(results, payload, inst, ctx); - return Promise.all(results).then((results2) => { - return handleUnionResults(results2, payload, inst, ctx); - }); - }; -}); -var \$ZodDiscriminatedUnion = /* @__PURE__ */ \$constructor("\$ZodDiscriminatedUnion", (inst, def) => { - \$ZodUnion.init(inst, def); - const _super = inst._zod.parse; - defineLazy(inst._zod, "propValues", () => { - const propValues = {}; - for (const option of def.options) { - const pv = option._zod.propValues; - if (!pv || Object.keys(pv).length === 0) throw new Error(\`Invalid discriminated union option at index "\${def.options.indexOf(option)}"\`); - for (const [k, v] of Object.entries(pv)) { - if (!propValues[k]) propValues[k] = /* @__PURE__ */ new Set(); - for (const val of v) { - propValues[k].add(val); - } - } - } - return propValues; - }); - const disc = cached(() => { - const opts = def.options; - const map2 = /* @__PURE__ */ new Map(); - for (const o of opts) { - const values = o._zod.propValues?.[def.discriminator]; - if (!values || values.size === 0) throw new Error(\`Invalid discriminated union option at index "\${def.options.indexOf(o)}"\`); - for (const v of values) { - if (map2.has(v)) { - throw new Error(\`Duplicate discriminator value "\${String(v)}"\`); - } - map2.set(v, o); - } - } - return map2; - }); - inst._zod.parse = (payload, ctx) => { - const input = payload.value; - if (!isObject(input)) { - payload.issues.push({ - code: "invalid_type", - expected: "object", - input, - inst - }); - return payload; - } - const opt = disc.value.get(input?.[def.discriminator]); - if (opt) { - return opt._zod.run(payload, ctx); - } - if (def.unionFallback) { - return _super(payload, ctx); - } - payload.issues.push({ - code: "invalid_union", - errors: [], - note: "No matching discriminator", - discriminator: def.discriminator, - input, - path: [ - def.discriminator - ], - inst - }); - return payload; - }; -}); -var \$ZodIntersection = /* @__PURE__ */ \$constructor("\$ZodIntersection", (inst, def) => { - \$ZodType.init(inst, def); - inst._zod.parse = (payload, ctx) => { - const input = payload.value; - const left = def.left._zod.run({ - value: input, - issues: [] - }, ctx); - const right = def.right._zod.run({ - value: input, - issues: [] - }, ctx); - const async = left instanceof Promise || right instanceof Promise; - if (async) { - return Promise.all([ - left, - right - ]).then(([left2, right2]) => { - return handleIntersectionResults(payload, left2, right2); - }); - } - return handleIntersectionResults(payload, left, right); - }; -}); -function mergeValues(a, b) { - if (a === b) { - return { - valid: true, - data: a - }; - } - if (a instanceof Date && b instanceof Date && +a === +b) { - return { - valid: true, - data: a - }; - } - if (isPlainObject(a) && isPlainObject(b)) { - const bKeys = Object.keys(b); - const sharedKeys = Object.keys(a).filter((key) => bKeys.indexOf(key) !== -1); - const newObj = { - ...a, - ...b - }; - for (const key of sharedKeys) { - const sharedValue = mergeValues(a[key], b[key]); - if (!sharedValue.valid) { - return { - valid: false, - mergeErrorPath: [ - key, - ...sharedValue.mergeErrorPath - ] - }; - } - newObj[key] = sharedValue.data; - } - return { - valid: true, - data: newObj - }; - } - if (Array.isArray(a) && Array.isArray(b)) { - if (a.length !== b.length) { - return { - valid: false, - mergeErrorPath: [] - }; - } - const newArray = []; - for (let index = 0; index < a.length; index++) { - const itemA = a[index]; - const itemB = b[index]; - const sharedValue = mergeValues(itemA, itemB); - if (!sharedValue.valid) { - return { - valid: false, - mergeErrorPath: [ - index, - ...sharedValue.mergeErrorPath - ] - }; - } - newArray.push(sharedValue.data); - } - return { - valid: true, - data: newArray - }; - } - return { - valid: false, - mergeErrorPath: [] - }; -} -__name(mergeValues, "mergeValues"); -function handleIntersectionResults(result, left, right) { - if (left.issues.length) { - result.issues.push(...left.issues); - } - if (right.issues.length) { - result.issues.push(...right.issues); - } - if (aborted(result)) return result; - const merged = mergeValues(left.value, right.value); - if (!merged.valid) { - throw new Error(\`Unmergable intersection. Error path: \${JSON.stringify(merged.mergeErrorPath)}\`); - } - result.value = merged.data; - return result; -} -__name(handleIntersectionResults, "handleIntersectionResults"); -var \$ZodTuple = /* @__PURE__ */ \$constructor("\$ZodTuple", (inst, def) => { - \$ZodType.init(inst, def); - const items = def.items; - const optStart = items.length - [ - ...items - ].reverse().findIndex((item) => item._zod.optin !== "optional"); - inst._zod.parse = (payload, ctx) => { - const input = payload.value; - if (!Array.isArray(input)) { - payload.issues.push({ - input, - inst, - expected: "tuple", - code: "invalid_type" - }); - return payload; - } - payload.value = []; - const proms = []; - if (!def.rest) { - const tooBig = input.length > items.length; - const tooSmall = input.length < optStart - 1; - if (tooBig || tooSmall) { - payload.issues.push({ - ...tooBig ? { - code: "too_big", - maximum: items.length - } : { - code: "too_small", - minimum: items.length - }, - input, - inst, - origin: "array" - }); - return payload; - } - } - let i = -1; - for (const item of items) { - i++; - if (i >= input.length) { - if (i >= optStart) continue; - } - const result = item._zod.run({ - value: input[i], - issues: [] - }, ctx); - if (result instanceof Promise) { - proms.push(result.then((result2) => handleTupleResult(result2, payload, i))); - } else { - handleTupleResult(result, payload, i); - } - } - if (def.rest) { - const rest = input.slice(items.length); - for (const el of rest) { - i++; - const result = def.rest._zod.run({ - value: el, - issues: [] - }, ctx); - if (result instanceof Promise) { - proms.push(result.then((result2) => handleTupleResult(result2, payload, i))); - } else { - handleTupleResult(result, payload, i); - } - } - } - if (proms.length) return Promise.all(proms).then(() => payload); - return payload; - }; -}); -function handleTupleResult(result, final, index) { - if (result.issues.length) { - final.issues.push(...prefixIssues(index, result.issues)); - } - final.value[index] = result.value; -} -__name(handleTupleResult, "handleTupleResult"); -var \$ZodRecord = /* @__PURE__ */ \$constructor("\$ZodRecord", (inst, def) => { - \$ZodType.init(inst, def); - inst._zod.parse = (payload, ctx) => { - const input = payload.value; - if (!isPlainObject(input)) { - payload.issues.push({ - expected: "record", - code: "invalid_type", - input, - inst - }); - return payload; - } - const proms = []; - if (def.keyType._zod.values) { - const values = def.keyType._zod.values; - payload.value = {}; - for (const key of values) { - if (typeof key === "string" || typeof key === "number" || typeof key === "symbol") { - const result = def.valueType._zod.run({ - value: input[key], - issues: [] - }, ctx); - if (result instanceof Promise) { - proms.push(result.then((result2) => { - if (result2.issues.length) { - payload.issues.push(...prefixIssues(key, result2.issues)); - } - payload.value[key] = result2.value; - })); - } else { - if (result.issues.length) { - payload.issues.push(...prefixIssues(key, result.issues)); - } - payload.value[key] = result.value; - } - } - } - let unrecognized; - for (const key in input) { - if (!values.has(key)) { - unrecognized = unrecognized ?? []; - unrecognized.push(key); - } - } - if (unrecognized && unrecognized.length > 0) { - payload.issues.push({ - code: "unrecognized_keys", - input, - inst, - keys: unrecognized - }); - } - } else { - payload.value = {}; - for (const key of Reflect.ownKeys(input)) { - if (key === "__proto__") continue; - const keyResult = def.keyType._zod.run({ - value: key, - issues: [] - }, ctx); - if (keyResult instanceof Promise) { - throw new Error("Async schemas not supported in object keys currently"); - } - if (keyResult.issues.length) { - payload.issues.push({ - code: "invalid_key", - origin: "record", - issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config())), - input: key, - path: [ - key - ], - inst - }); - payload.value[keyResult.value] = keyResult.value; - continue; - } - const result = def.valueType._zod.run({ - value: input[key], - issues: [] - }, ctx); - if (result instanceof Promise) { - proms.push(result.then((result2) => { - if (result2.issues.length) { - payload.issues.push(...prefixIssues(key, result2.issues)); - } - payload.value[keyResult.value] = result2.value; - })); - } else { - if (result.issues.length) { - payload.issues.push(...prefixIssues(key, result.issues)); - } - payload.value[keyResult.value] = result.value; - } - } - } - if (proms.length) { - return Promise.all(proms).then(() => payload); - } - return payload; - }; -}); -var \$ZodMap = /* @__PURE__ */ \$constructor("\$ZodMap", (inst, def) => { - \$ZodType.init(inst, def); - inst._zod.parse = (payload, ctx) => { - const input = payload.value; - if (!(input instanceof Map)) { - payload.issues.push({ - expected: "map", - code: "invalid_type", - input, - inst - }); - return payload; - } - const proms = []; - payload.value = /* @__PURE__ */ new Map(); - for (const [key, value] of input) { - const keyResult = def.keyType._zod.run({ - value: key, - issues: [] - }, ctx); - const valueResult = def.valueType._zod.run({ - value, - issues: [] - }, ctx); - if (keyResult instanceof Promise || valueResult instanceof Promise) { - proms.push(Promise.all([ - keyResult, - valueResult - ]).then(([keyResult2, valueResult2]) => { - handleMapResult(keyResult2, valueResult2, payload, key, input, inst, ctx); - })); - } else { - handleMapResult(keyResult, valueResult, payload, key, input, inst, ctx); - } - } - if (proms.length) return Promise.all(proms).then(() => payload); - return payload; - }; -}); -function handleMapResult(keyResult, valueResult, final, key, input, inst, ctx) { - if (keyResult.issues.length) { - if (propertyKeyTypes.has(typeof key)) { - final.issues.push(...prefixIssues(key, keyResult.issues)); - } else { - final.issues.push({ - code: "invalid_key", - origin: "map", - input, - inst, - issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config())) - }); - } - } - if (valueResult.issues.length) { - if (propertyKeyTypes.has(typeof key)) { - final.issues.push(...prefixIssues(key, valueResult.issues)); - } else { - final.issues.push({ - origin: "map", - code: "invalid_element", - input, - inst, - key, - issues: valueResult.issues.map((iss) => finalizeIssue(iss, ctx, config())) - }); - } - } - final.value.set(keyResult.value, valueResult.value); -} -__name(handleMapResult, "handleMapResult"); -var \$ZodSet = /* @__PURE__ */ \$constructor("\$ZodSet", (inst, def) => { - \$ZodType.init(inst, def); - inst._zod.parse = (payload, ctx) => { - const input = payload.value; - if (!(input instanceof Set)) { - payload.issues.push({ - input, - inst, - expected: "set", - code: "invalid_type" - }); - return payload; - } - const proms = []; - payload.value = /* @__PURE__ */ new Set(); - for (const item of input) { - const result = def.valueType._zod.run({ - value: item, - issues: [] - }, ctx); - if (result instanceof Promise) { - proms.push(result.then((result2) => handleSetResult(result2, payload))); - } else handleSetResult(result, payload); - } - if (proms.length) return Promise.all(proms).then(() => payload); - return payload; - }; -}); -function handleSetResult(result, final) { - if (result.issues.length) { - final.issues.push(...result.issues); - } - final.value.add(result.value); -} -__name(handleSetResult, "handleSetResult"); -var \$ZodEnum = /* @__PURE__ */ \$constructor("\$ZodEnum", (inst, def) => { - \$ZodType.init(inst, def); - const values = getEnumValues(def.entries); - const valuesSet = new Set(values); - inst._zod.values = valuesSet; - inst._zod.pattern = new RegExp(\`^(\${values.filter((k) => propertyKeyTypes.has(typeof k)).map((o) => typeof o === "string" ? escapeRegex(o) : o.toString()).join("|")})\$\`); - inst._zod.parse = (payload, _ctx) => { - const input = payload.value; - if (valuesSet.has(input)) { - return payload; - } - payload.issues.push({ - code: "invalid_value", - values, - input, - inst - }); - return payload; - }; -}); -var \$ZodLiteral = /* @__PURE__ */ \$constructor("\$ZodLiteral", (inst, def) => { - \$ZodType.init(inst, def); - if (def.values.length === 0) { - throw new Error("Cannot create literal schema with no valid values"); - } - inst._zod.values = new Set(def.values); - inst._zod.pattern = new RegExp(\`^(\${def.values.map((o) => typeof o === "string" ? escapeRegex(o) : o ? escapeRegex(o.toString()) : String(o)).join("|")})\$\`); - inst._zod.parse = (payload, _ctx) => { - const input = payload.value; - if (inst._zod.values.has(input)) { - return payload; - } - payload.issues.push({ - code: "invalid_value", - values: def.values, - input, - inst - }); - return payload; - }; -}); -var \$ZodFile = /* @__PURE__ */ \$constructor("\$ZodFile", (inst, def) => { - \$ZodType.init(inst, def); - inst._zod.parse = (payload, _ctx) => { - const input = payload.value; - if (input instanceof File) return payload; - payload.issues.push({ - expected: "file", - code: "invalid_type", - input, - inst - }); - return payload; - }; -}); -var \$ZodTransform = /* @__PURE__ */ \$constructor("\$ZodTransform", (inst, def) => { - \$ZodType.init(inst, def); - inst._zod.parse = (payload, ctx) => { - if (ctx.direction === "backward") { - throw new \$ZodEncodeError(inst.constructor.name); - } - const _out = def.transform(payload.value, payload); - if (ctx.async) { - const output = _out instanceof Promise ? _out : Promise.resolve(_out); - return output.then((output2) => { - payload.value = output2; - return payload; - }); - } - if (_out instanceof Promise) { - throw new \$ZodAsyncError(); - } - payload.value = _out; - return payload; - }; -}); -function handleOptionalResult(result, input) { - if (result.issues.length && input === void 0) { - return { - issues: [], - value: void 0 - }; - } - return result; -} -__name(handleOptionalResult, "handleOptionalResult"); -var \$ZodOptional = /* @__PURE__ */ \$constructor("\$ZodOptional", (inst, def) => { - \$ZodType.init(inst, def); - inst._zod.optin = "optional"; - inst._zod.optout = "optional"; - defineLazy(inst._zod, "values", () => { - return def.innerType._zod.values ? /* @__PURE__ */ new Set([ - ...def.innerType._zod.values, - void 0 - ]) : void 0; - }); - defineLazy(inst._zod, "pattern", () => { - const pattern = def.innerType._zod.pattern; - return pattern ? new RegExp(\`^(\${cleanRegex(pattern.source)})?\$\`) : void 0; - }); - inst._zod.parse = (payload, ctx) => { - if (def.innerType._zod.optin === "optional") { - const result = def.innerType._zod.run(payload, ctx); - if (result instanceof Promise) return result.then((r) => handleOptionalResult(r, payload.value)); - return handleOptionalResult(result, payload.value); - } - if (payload.value === void 0) { - return payload; - } - return def.innerType._zod.run(payload, ctx); - }; -}); -var \$ZodNullable = /* @__PURE__ */ \$constructor("\$ZodNullable", (inst, def) => { - \$ZodType.init(inst, def); - defineLazy(inst._zod, "optin", () => def.innerType._zod.optin); - defineLazy(inst._zod, "optout", () => def.innerType._zod.optout); - defineLazy(inst._zod, "pattern", () => { - const pattern = def.innerType._zod.pattern; - return pattern ? new RegExp(\`^(\${cleanRegex(pattern.source)}|null)\$\`) : void 0; - }); - defineLazy(inst._zod, "values", () => { - return def.innerType._zod.values ? /* @__PURE__ */ new Set([ - ...def.innerType._zod.values, - null - ]) : void 0; - }); - inst._zod.parse = (payload, ctx) => { - if (payload.value === null) return payload; - return def.innerType._zod.run(payload, ctx); - }; -}); -var \$ZodDefault = /* @__PURE__ */ \$constructor("\$ZodDefault", (inst, def) => { - \$ZodType.init(inst, def); - inst._zod.optin = "optional"; - defineLazy(inst._zod, "values", () => def.innerType._zod.values); - inst._zod.parse = (payload, ctx) => { - if (ctx.direction === "backward") { - return def.innerType._zod.run(payload, ctx); - } - if (payload.value === void 0) { - payload.value = def.defaultValue; - return payload; - } - const result = def.innerType._zod.run(payload, ctx); - if (result instanceof Promise) { - return result.then((result2) => handleDefaultResult(result2, def)); - } - return handleDefaultResult(result, def); - }; -}); -function handleDefaultResult(payload, def) { - if (payload.value === void 0) { - payload.value = def.defaultValue; - } - return payload; -} -__name(handleDefaultResult, "handleDefaultResult"); -var \$ZodPrefault = /* @__PURE__ */ \$constructor("\$ZodPrefault", (inst, def) => { - \$ZodType.init(inst, def); - inst._zod.optin = "optional"; - defineLazy(inst._zod, "values", () => def.innerType._zod.values); - inst._zod.parse = (payload, ctx) => { - if (ctx.direction === "backward") { - return def.innerType._zod.run(payload, ctx); - } - if (payload.value === void 0) { - payload.value = def.defaultValue; - } - return def.innerType._zod.run(payload, ctx); - }; -}); -var \$ZodNonOptional = /* @__PURE__ */ \$constructor("\$ZodNonOptional", (inst, def) => { - \$ZodType.init(inst, def); - defineLazy(inst._zod, "values", () => { - const v = def.innerType._zod.values; - return v ? new Set([ - ...v - ].filter((x) => x !== void 0)) : void 0; - }); - inst._zod.parse = (payload, ctx) => { - const result = def.innerType._zod.run(payload, ctx); - if (result instanceof Promise) { - return result.then((result2) => handleNonOptionalResult(result2, inst)); - } - return handleNonOptionalResult(result, inst); - }; -}); -function handleNonOptionalResult(payload, inst) { - if (!payload.issues.length && payload.value === void 0) { - payload.issues.push({ - code: "invalid_type", - expected: "nonoptional", - input: payload.value, - inst - }); - } - return payload; -} -__name(handleNonOptionalResult, "handleNonOptionalResult"); -var \$ZodSuccess = /* @__PURE__ */ \$constructor("\$ZodSuccess", (inst, def) => { - \$ZodType.init(inst, def); - inst._zod.parse = (payload, ctx) => { - if (ctx.direction === "backward") { - throw new \$ZodEncodeError("ZodSuccess"); - } - const result = def.innerType._zod.run(payload, ctx); - if (result instanceof Promise) { - return result.then((result2) => { - payload.value = result2.issues.length === 0; - return payload; - }); - } - payload.value = result.issues.length === 0; - return payload; - }; -}); -var \$ZodCatch = /* @__PURE__ */ \$constructor("\$ZodCatch", (inst, def) => { - \$ZodType.init(inst, def); - defineLazy(inst._zod, "optin", () => def.innerType._zod.optin); - defineLazy(inst._zod, "optout", () => def.innerType._zod.optout); - defineLazy(inst._zod, "values", () => def.innerType._zod.values); - inst._zod.parse = (payload, ctx) => { - if (ctx.direction === "backward") { - return def.innerType._zod.run(payload, ctx); - } - const result = def.innerType._zod.run(payload, ctx); - if (result instanceof Promise) { - return result.then((result2) => { - payload.value = result2.value; - if (result2.issues.length) { - payload.value = def.catchValue({ - ...payload, - error: { - issues: result2.issues.map((iss) => finalizeIssue(iss, ctx, config())) - }, - input: payload.value - }); - payload.issues = []; - } - return payload; - }); - } - payload.value = result.value; - if (result.issues.length) { - payload.value = def.catchValue({ - ...payload, - error: { - issues: result.issues.map((iss) => finalizeIssue(iss, ctx, config())) - }, - input: payload.value - }); - payload.issues = []; - } - return payload; - }; -}); -var \$ZodNaN = /* @__PURE__ */ \$constructor("\$ZodNaN", (inst, def) => { - \$ZodType.init(inst, def); - inst._zod.parse = (payload, _ctx) => { - if (typeof payload.value !== "number" || !Number.isNaN(payload.value)) { - payload.issues.push({ - input: payload.value, - inst, - expected: "nan", - code: "invalid_type" - }); - return payload; - } - return payload; - }; -}); -var \$ZodPipe = /* @__PURE__ */ \$constructor("\$ZodPipe", (inst, def) => { - \$ZodType.init(inst, def); - defineLazy(inst._zod, "values", () => def.in._zod.values); - defineLazy(inst._zod, "optin", () => def.in._zod.optin); - defineLazy(inst._zod, "optout", () => def.out._zod.optout); - defineLazy(inst._zod, "propValues", () => def.in._zod.propValues); - inst._zod.parse = (payload, ctx) => { - if (ctx.direction === "backward") { - const right = def.out._zod.run(payload, ctx); - if (right instanceof Promise) { - return right.then((right2) => handlePipeResult(right2, def.in, ctx)); - } - return handlePipeResult(right, def.in, ctx); - } - const left = def.in._zod.run(payload, ctx); - if (left instanceof Promise) { - return left.then((left2) => handlePipeResult(left2, def.out, ctx)); - } - return handlePipeResult(left, def.out, ctx); - }; -}); -function handlePipeResult(left, next, ctx) { - if (left.issues.length) { - left.aborted = true; - return left; - } - return next._zod.run({ - value: left.value, - issues: left.issues - }, ctx); -} -__name(handlePipeResult, "handlePipeResult"); -var \$ZodCodec = /* @__PURE__ */ \$constructor("\$ZodCodec", (inst, def) => { - \$ZodType.init(inst, def); - defineLazy(inst._zod, "values", () => def.in._zod.values); - defineLazy(inst._zod, "optin", () => def.in._zod.optin); - defineLazy(inst._zod, "optout", () => def.out._zod.optout); - defineLazy(inst._zod, "propValues", () => def.in._zod.propValues); - inst._zod.parse = (payload, ctx) => { - const direction = ctx.direction || "forward"; - if (direction === "forward") { - const left = def.in._zod.run(payload, ctx); - if (left instanceof Promise) { - return left.then((left2) => handleCodecAResult(left2, def, ctx)); - } - return handleCodecAResult(left, def, ctx); - } else { - const right = def.out._zod.run(payload, ctx); - if (right instanceof Promise) { - return right.then((right2) => handleCodecAResult(right2, def, ctx)); - } - return handleCodecAResult(right, def, ctx); - } - }; -}); -function handleCodecAResult(result, def, ctx) { - if (result.issues.length) { - result.aborted = true; - return result; - } - const direction = ctx.direction || "forward"; - if (direction === "forward") { - const transformed = def.transform(result.value, result); - if (transformed instanceof Promise) { - return transformed.then((value) => handleCodecTxResult(result, value, def.out, ctx)); - } - return handleCodecTxResult(result, transformed, def.out, ctx); - } else { - const transformed = def.reverseTransform(result.value, result); - if (transformed instanceof Promise) { - return transformed.then((value) => handleCodecTxResult(result, value, def.in, ctx)); - } - return handleCodecTxResult(result, transformed, def.in, ctx); - } -} -__name(handleCodecAResult, "handleCodecAResult"); -function handleCodecTxResult(left, value, nextSchema, ctx) { - if (left.issues.length) { - left.aborted = true; - return left; - } - return nextSchema._zod.run({ - value, - issues: left.issues - }, ctx); -} -__name(handleCodecTxResult, "handleCodecTxResult"); -var \$ZodReadonly = /* @__PURE__ */ \$constructor("\$ZodReadonly", (inst, def) => { - \$ZodType.init(inst, def); - defineLazy(inst._zod, "propValues", () => def.innerType._zod.propValues); - defineLazy(inst._zod, "values", () => def.innerType._zod.values); - defineLazy(inst._zod, "optin", () => def.innerType._zod.optin); - defineLazy(inst._zod, "optout", () => def.innerType._zod.optout); - inst._zod.parse = (payload, ctx) => { - if (ctx.direction === "backward") { - return def.innerType._zod.run(payload, ctx); - } - const result = def.innerType._zod.run(payload, ctx); - if (result instanceof Promise) { - return result.then(handleReadonlyResult); - } - return handleReadonlyResult(result); - }; -}); -function handleReadonlyResult(payload) { - payload.value = Object.freeze(payload.value); - return payload; -} -__name(handleReadonlyResult, "handleReadonlyResult"); -var \$ZodTemplateLiteral = /* @__PURE__ */ \$constructor("\$ZodTemplateLiteral", (inst, def) => { - \$ZodType.init(inst, def); - const regexParts = []; - for (const part of def.parts) { - if (typeof part === "object" && part !== null) { - if (!part._zod.pattern) { - throw new Error(\`Invalid template literal part, no pattern found: \${[ - ...part._zod.traits - ].shift()}\`); - } - const source = part._zod.pattern instanceof RegExp ? part._zod.pattern.source : part._zod.pattern; - if (!source) throw new Error(\`Invalid template literal part: \${part._zod.traits}\`); - const start = source.startsWith("^") ? 1 : 0; - const end = source.endsWith("\$") ? source.length - 1 : source.length; - regexParts.push(source.slice(start, end)); - } else if (part === null || primitiveTypes.has(typeof part)) { - regexParts.push(escapeRegex(\`\${part}\`)); - } else { - throw new Error(\`Invalid template literal part: \${part}\`); - } - } - inst._zod.pattern = new RegExp(\`^\${regexParts.join("")}\$\`); - inst._zod.parse = (payload, _ctx) => { - if (typeof payload.value !== "string") { - payload.issues.push({ - input: payload.value, - inst, - expected: "template_literal", - code: "invalid_type" - }); - return payload; - } - inst._zod.pattern.lastIndex = 0; - if (!inst._zod.pattern.test(payload.value)) { - payload.issues.push({ - input: payload.value, - inst, - code: "invalid_format", - format: def.format ?? "template_literal", - pattern: inst._zod.pattern.source - }); - return payload; - } - return payload; - }; -}); -var \$ZodFunction = /* @__PURE__ */ \$constructor("\$ZodFunction", (inst, def) => { - \$ZodType.init(inst, def); - inst._def = def; - inst._zod.def = def; - inst.implement = (func) => { - if (typeof func !== "function") { - throw new Error("implement() must be called with a function"); - } - return function(...args) { - const parsedArgs = inst._def.input ? parse(inst._def.input, args) : args; - const result = Reflect.apply(func, this, parsedArgs); - if (inst._def.output) { - return parse(inst._def.output, result); - } - return result; - }; - }; - inst.implementAsync = (func) => { - if (typeof func !== "function") { - throw new Error("implementAsync() must be called with a function"); - } - return async function(...args) { - const parsedArgs = inst._def.input ? await parseAsync(inst._def.input, args) : args; - const result = await Reflect.apply(func, this, parsedArgs); - if (inst._def.output) { - return await parseAsync(inst._def.output, result); - } - return result; - }; - }; - inst._zod.parse = (payload, _ctx) => { - if (typeof payload.value !== "function") { - payload.issues.push({ - code: "invalid_type", - expected: "function", - input: payload.value, - inst - }); - return payload; - } - const hasPromiseOutput = inst._def.output && inst._def.output._zod.def.type === "promise"; - if (hasPromiseOutput) { - payload.value = inst.implementAsync(payload.value); - } else { - payload.value = inst.implement(payload.value); - } - return payload; - }; - inst.input = (...args) => { - const F = inst.constructor; - if (Array.isArray(args[0])) { - return new F({ - type: "function", - input: new \$ZodTuple({ - type: "tuple", - items: args[0], - rest: args[1] - }), - output: inst._def.output - }); - } - return new F({ - type: "function", - input: args[0], - output: inst._def.output - }); - }; - inst.output = (output) => { - const F = inst.constructor; - return new F({ - type: "function", - input: inst._def.input, - output - }); - }; - return inst; -}); -var \$ZodPromise = /* @__PURE__ */ \$constructor("\$ZodPromise", (inst, def) => { - \$ZodType.init(inst, def); - inst._zod.parse = (payload, ctx) => { - return Promise.resolve(payload.value).then((inner) => def.innerType._zod.run({ - value: inner, - issues: [] - }, ctx)); - }; -}); -var \$ZodLazy = /* @__PURE__ */ \$constructor("\$ZodLazy", (inst, def) => { - \$ZodType.init(inst, def); - defineLazy(inst._zod, "innerType", () => def.getter()); - defineLazy(inst._zod, "pattern", () => inst._zod.innerType._zod.pattern); - defineLazy(inst._zod, "propValues", () => inst._zod.innerType._zod.propValues); - defineLazy(inst._zod, "optin", () => inst._zod.innerType._zod.optin ?? void 0); - defineLazy(inst._zod, "optout", () => inst._zod.innerType._zod.optout ?? void 0); - inst._zod.parse = (payload, ctx) => { - const inner = inst._zod.innerType; - return inner._zod.run(payload, ctx); - }; -}); -var \$ZodCustom = /* @__PURE__ */ \$constructor("\$ZodCustom", (inst, def) => { - \$ZodCheck.init(inst, def); - \$ZodType.init(inst, def); - inst._zod.parse = (payload, _) => { - return payload; - }; - inst._zod.check = (payload) => { - const input = payload.value; - const r = def.fn(input); - if (r instanceof Promise) { - return r.then((r2) => handleRefineResult(r2, payload, input, inst)); - } - handleRefineResult(r, payload, input, inst); - return; - }; -}); -function handleRefineResult(result, payload, input, inst) { - if (!result) { - const _iss = { - code: "custom", - input, - inst, - path: [ - ...inst._zod.def.path ?? [] - ], - continue: !inst._zod.def.abort - }; - if (inst._zod.def.params) _iss.params = inst._zod.def.params; - payload.issues.push(issue(_iss)); - } -} -__name(handleRefineResult, "handleRefineResult"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/index.js -var locales_exports = {}; -__export(locales_exports, { - ar: () => ar_default, - az: () => az_default, - be: () => be_default, - ca: () => ca_default, - cs: () => cs_default, - da: () => da_default, - de: () => de_default, - en: () => en_default, - eo: () => eo_default, - es: () => es_default, - fa: () => fa_default, - fi: () => fi_default, - fr: () => fr_default, - frCA: () => fr_CA_default, - he: () => he_default, - hu: () => hu_default, - id: () => id_default, - is: () => is_default, - it: () => it_default, - ja: () => ja_default, - ka: () => ka_default, - kh: () => kh_default, - km: () => km_default, - ko: () => ko_default, - lt: () => lt_default, - mk: () => mk_default, - ms: () => ms_default, - nl: () => nl_default, - no: () => no_default, - ota: () => ota_default, - pl: () => pl_default, - ps: () => ps_default, - pt: () => pt_default, - ru: () => ru_default, - sl: () => sl_default, - sv: () => sv_default, - ta: () => ta_default, - th: () => th_default, - tr: () => tr_default, - ua: () => ua_default, - uk: () => uk_default, - ur: () => ur_default, - vi: () => vi_default, - yo: () => yo_default, - zhCN: () => zh_CN_default, - zhTW: () => zh_TW_default -}); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/ar.js -var error = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "\\u062D\\u0631\\u0641", - verb: "\\u0623\\u0646 \\u064A\\u062D\\u0648\\u064A" - }, - file: { - unit: "\\u0628\\u0627\\u064A\\u062A", - verb: "\\u0623\\u0646 \\u064A\\u062D\\u0648\\u064A" - }, - array: { - unit: "\\u0639\\u0646\\u0635\\u0631", - verb: "\\u0623\\u0646 \\u064A\\u062D\\u0648\\u064A" - }, - set: { - unit: "\\u0639\\u0646\\u0635\\u0631", - verb: "\\u0623\\u0646 \\u064A\\u062D\\u0648\\u064A" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "number"; - } - case "object": { - if (Array.isArray(data)) { - return "array"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "\\u0645\\u062F\\u062E\\u0644", - email: "\\u0628\\u0631\\u064A\\u062F \\u0625\\u0644\\u0643\\u062A\\u0631\\u0648\\u0646\\u064A", - url: "\\u0631\\u0627\\u0628\\u0637", - emoji: "\\u0625\\u064A\\u0645\\u0648\\u062C\\u064A", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "\\u062A\\u0627\\u0631\\u064A\\u062E \\u0648\\u0648\\u0642\\u062A \\u0628\\u0645\\u0639\\u064A\\u0627\\u0631 ISO", - date: "\\u062A\\u0627\\u0631\\u064A\\u062E \\u0628\\u0645\\u0639\\u064A\\u0627\\u0631 ISO", - time: "\\u0648\\u0642\\u062A \\u0628\\u0645\\u0639\\u064A\\u0627\\u0631 ISO", - duration: "\\u0645\\u062F\\u0629 \\u0628\\u0645\\u0639\\u064A\\u0627\\u0631 ISO", - ipv4: "\\u0639\\u0646\\u0648\\u0627\\u0646 IPv4", - ipv6: "\\u0639\\u0646\\u0648\\u0627\\u0646 IPv6", - cidrv4: "\\u0645\\u062F\\u0649 \\u0639\\u0646\\u0627\\u0648\\u064A\\u0646 \\u0628\\u0635\\u064A\\u063A\\u0629 IPv4", - cidrv6: "\\u0645\\u062F\\u0649 \\u0639\\u0646\\u0627\\u0648\\u064A\\u0646 \\u0628\\u0635\\u064A\\u063A\\u0629 IPv6", - base64: "\\u0646\\u064E\\u0635 \\u0628\\u062A\\u0631\\u0645\\u064A\\u0632 base64-encoded", - base64url: "\\u0646\\u064E\\u0635 \\u0628\\u062A\\u0631\\u0645\\u064A\\u0632 base64url-encoded", - json_string: "\\u0646\\u064E\\u0635 \\u0639\\u0644\\u0649 \\u0647\\u064A\\u0626\\u0629 JSON", - e164: "\\u0631\\u0642\\u0645 \\u0647\\u0627\\u062A\\u0641 \\u0628\\u0645\\u0639\\u064A\\u0627\\u0631 E.164", - jwt: "JWT", - template_literal: "\\u0645\\u062F\\u062E\\u0644" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`\\u0645\\u062F\\u062E\\u0644\\u0627\\u062A \\u063A\\u064A\\u0631 \\u0645\\u0642\\u0628\\u0648\\u0644\\u0629: \\u064A\\u0641\\u062A\\u0631\\u0636 \\u0625\\u062F\\u062E\\u0627\\u0644 \${issue2.expected}\\u060C \\u0648\\u0644\\u0643\\u0646 \\u062A\\u0645 \\u0625\\u062F\\u062E\\u0627\\u0644 \${parsedType7(issue2.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`\\u0645\\u062F\\u062E\\u0644\\u0627\\u062A \\u063A\\u064A\\u0631 \\u0645\\u0642\\u0628\\u0648\\u0644\\u0629: \\u064A\\u0641\\u062A\\u0631\\u0636 \\u0625\\u062F\\u062E\\u0627\\u0644 \${stringifyPrimitive(issue2.values[0])}\`; - return \`\\u0627\\u062E\\u062A\\u064A\\u0627\\u0631 \\u063A\\u064A\\u0631 \\u0645\\u0642\\u0628\\u0648\\u0644: \\u064A\\u062A\\u0648\\u0642\\u0639 \\u0627\\u0646\\u062A\\u0642\\u0627\\u0621 \\u0623\\u062D\\u062F \\u0647\\u0630\\u0647 \\u0627\\u0644\\u062E\\u064A\\u0627\\u0631\\u0627\\u062A: \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) return \` \\u0623\\u0643\\u0628\\u0631 \\u0645\\u0646 \\u0627\\u0644\\u0644\\u0627\\u0632\\u0645: \\u064A\\u0641\\u062A\\u0631\\u0636 \\u0623\\u0646 \\u062A\\u0643\\u0648\\u0646 \${issue2.origin ?? "\\u0627\\u0644\\u0642\\u064A\\u0645\\u0629"} \${adj} \${issue2.maximum.toString()} \${sizing.unit ?? "\\u0639\\u0646\\u0635\\u0631"}\`; - return \`\\u0623\\u0643\\u0628\\u0631 \\u0645\\u0646 \\u0627\\u0644\\u0644\\u0627\\u0632\\u0645: \\u064A\\u0641\\u062A\\u0631\\u0636 \\u0623\\u0646 \\u062A\\u0643\\u0648\\u0646 \${issue2.origin ?? "\\u0627\\u0644\\u0642\\u064A\\u0645\\u0629"} \${adj} \${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`\\u0623\\u0635\\u063A\\u0631 \\u0645\\u0646 \\u0627\\u0644\\u0644\\u0627\\u0632\\u0645: \\u064A\\u0641\\u062A\\u0631\\u0636 \\u0644\\u0640 \${issue2.origin} \\u0623\\u0646 \\u064A\\u0643\\u0648\\u0646 \${adj} \${issue2.minimum.toString()} \${sizing.unit}\`; - } - return \`\\u0623\\u0635\\u063A\\u0631 \\u0645\\u0646 \\u0627\\u0644\\u0644\\u0627\\u0632\\u0645: \\u064A\\u0641\\u062A\\u0631\\u0636 \\u0644\\u0640 \${issue2.origin} \\u0623\\u0646 \\u064A\\u0643\\u0648\\u0646 \${adj} \${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") return \`\\u0646\\u064E\\u0635 \\u063A\\u064A\\u0631 \\u0645\\u0642\\u0628\\u0648\\u0644: \\u064A\\u062C\\u0628 \\u0623\\u0646 \\u064A\\u0628\\u062F\\u0623 \\u0628\\u0640 "\${issue2.prefix}"\`; - if (_issue.format === "ends_with") return \`\\u0646\\u064E\\u0635 \\u063A\\u064A\\u0631 \\u0645\\u0642\\u0628\\u0648\\u0644: \\u064A\\u062C\\u0628 \\u0623\\u0646 \\u064A\\u0646\\u062A\\u0647\\u064A \\u0628\\u0640 "\${_issue.suffix}"\`; - if (_issue.format === "includes") return \`\\u0646\\u064E\\u0635 \\u063A\\u064A\\u0631 \\u0645\\u0642\\u0628\\u0648\\u0644: \\u064A\\u062C\\u0628 \\u0623\\u0646 \\u064A\\u062A\\u0636\\u0645\\u0651\\u064E\\u0646 "\${_issue.includes}"\`; - if (_issue.format === "regex") return \`\\u0646\\u064E\\u0635 \\u063A\\u064A\\u0631 \\u0645\\u0642\\u0628\\u0648\\u0644: \\u064A\\u062C\\u0628 \\u0623\\u0646 \\u064A\\u0637\\u0627\\u0628\\u0642 \\u0627\\u0644\\u0646\\u0645\\u0637 \${_issue.pattern}\`; - return \`\${Nouns[_issue.format] ?? issue2.format} \\u063A\\u064A\\u0631 \\u0645\\u0642\\u0628\\u0648\\u0644\`; - } - case "not_multiple_of": - return \`\\u0631\\u0642\\u0645 \\u063A\\u064A\\u0631 \\u0645\\u0642\\u0628\\u0648\\u0644: \\u064A\\u062C\\u0628 \\u0623\\u0646 \\u064A\\u0643\\u0648\\u0646 \\u0645\\u0646 \\u0645\\u0636\\u0627\\u0639\\u0641\\u0627\\u062A \${issue2.divisor}\`; - case "unrecognized_keys": - return \`\\u0645\\u0639\\u0631\\u0641\${issue2.keys.length > 1 ? "\\u0627\\u062A" : ""} \\u063A\\u0631\\u064A\\u0628\${issue2.keys.length > 1 ? "\\u0629" : ""}: \${joinValues(issue2.keys, "\\u060C ")}\`; - case "invalid_key": - return \`\\u0645\\u0639\\u0631\\u0641 \\u063A\\u064A\\u0631 \\u0645\\u0642\\u0628\\u0648\\u0644 \\u0641\\u064A \${issue2.origin}\`; - case "invalid_union": - return "\\u0645\\u062F\\u062E\\u0644 \\u063A\\u064A\\u0631 \\u0645\\u0642\\u0628\\u0648\\u0644"; - case "invalid_element": - return \`\\u0645\\u062F\\u062E\\u0644 \\u063A\\u064A\\u0631 \\u0645\\u0642\\u0628\\u0648\\u0644 \\u0641\\u064A \${issue2.origin}\`; - default: - return "\\u0645\\u062F\\u062E\\u0644 \\u063A\\u064A\\u0631 \\u0645\\u0642\\u0628\\u0648\\u0644"; - } - }; -}, "error"); -function ar_default() { - return { - localeError: error() - }; -} -__name(ar_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/az.js -var error2 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "simvol", - verb: "olmal\\u0131d\\u0131r" - }, - file: { - unit: "bayt", - verb: "olmal\\u0131d\\u0131r" - }, - array: { - unit: "element", - verb: "olmal\\u0131d\\u0131r" - }, - set: { - unit: "element", - verb: "olmal\\u0131d\\u0131r" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "number"; - } - case "object": { - if (Array.isArray(data)) { - return "array"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "input", - email: "email address", - url: "URL", - emoji: "emoji", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "ISO datetime", - date: "ISO date", - time: "ISO time", - duration: "ISO duration", - ipv4: "IPv4 address", - ipv6: "IPv6 address", - cidrv4: "IPv4 range", - cidrv6: "IPv6 range", - base64: "base64-encoded string", - base64url: "base64url-encoded string", - json_string: "JSON string", - e164: "E.164 number", - jwt: "JWT", - template_literal: "input" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`Yanl\\u0131\\u015F d\\u0259y\\u0259r: g\\xF6zl\\u0259nil\\u0259n \${issue2.expected}, daxil olan \${parsedType7(issue2.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`Yanl\\u0131\\u015F d\\u0259y\\u0259r: g\\xF6zl\\u0259nil\\u0259n \${stringifyPrimitive(issue2.values[0])}\`; - return \`Yanl\\u0131\\u015F se\\xE7im: a\\u015Fa\\u011F\\u0131dak\\u0131lardan biri olmal\\u0131d\\u0131r: \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`\\xC7ox b\\xF6y\\xFCk: g\\xF6zl\\u0259nil\\u0259n \${issue2.origin ?? "d\\u0259y\\u0259r"} \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "element"}\`; - return \`\\xC7ox b\\xF6y\\xFCk: g\\xF6zl\\u0259nil\\u0259n \${issue2.origin ?? "d\\u0259y\\u0259r"} \${adj}\${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`\\xC7ox ki\\xE7ik: g\\xF6zl\\u0259nil\\u0259n \${issue2.origin} \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; - return \`\\xC7ox ki\\xE7ik: g\\xF6zl\\u0259nil\\u0259n \${issue2.origin} \${adj}\${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") return \`Yanl\\u0131\\u015F m\\u0259tn: "\${_issue.prefix}" il\\u0259 ba\\u015Flamal\\u0131d\\u0131r\`; - if (_issue.format === "ends_with") return \`Yanl\\u0131\\u015F m\\u0259tn: "\${_issue.suffix}" il\\u0259 bitm\\u0259lidir\`; - if (_issue.format === "includes") return \`Yanl\\u0131\\u015F m\\u0259tn: "\${_issue.includes}" daxil olmal\\u0131d\\u0131r\`; - if (_issue.format === "regex") return \`Yanl\\u0131\\u015F m\\u0259tn: \${_issue.pattern} \\u015Fablonuna uy\\u011Fun olmal\\u0131d\\u0131r\`; - return \`Yanl\\u0131\\u015F \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`Yanl\\u0131\\u015F \\u0259d\\u0259d: \${issue2.divisor} il\\u0259 b\\xF6l\\xFCn\\u0259 bil\\u0259n olmal\\u0131d\\u0131r\`; - case "unrecognized_keys": - return \`Tan\\u0131nmayan a\\xE7ar\${issue2.keys.length > 1 ? "lar" : ""}: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`\${issue2.origin} daxilind\\u0259 yanl\\u0131\\u015F a\\xE7ar\`; - case "invalid_union": - return "Yanl\\u0131\\u015F d\\u0259y\\u0259r"; - case "invalid_element": - return \`\${issue2.origin} daxilind\\u0259 yanl\\u0131\\u015F d\\u0259y\\u0259r\`; - default: - return \`Yanl\\u0131\\u015F d\\u0259y\\u0259r\`; - } - }; -}, "error"); -function az_default() { - return { - localeError: error2() - }; -} -__name(az_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/be.js -function getBelarusianPlural(count, one, few, many) { - const absCount = Math.abs(count); - const lastDigit = absCount % 10; - const lastTwoDigits = absCount % 100; - if (lastTwoDigits >= 11 && lastTwoDigits <= 19) { - return many; - } - if (lastDigit === 1) { - return one; - } - if (lastDigit >= 2 && lastDigit <= 4) { - return few; - } - return many; -} -__name(getBelarusianPlural, "getBelarusianPlural"); -var error3 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: { - one: "\\u0441\\u0456\\u043C\\u0432\\u0430\\u043B", - few: "\\u0441\\u0456\\u043C\\u0432\\u0430\\u043B\\u044B", - many: "\\u0441\\u0456\\u043C\\u0432\\u0430\\u043B\\u0430\\u045E" - }, - verb: "\\u043C\\u0435\\u0446\\u044C" - }, - array: { - unit: { - one: "\\u044D\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442", - few: "\\u044D\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442\\u044B", - many: "\\u044D\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442\\u0430\\u045E" - }, - verb: "\\u043C\\u0435\\u0446\\u044C" - }, - set: { - unit: { - one: "\\u044D\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442", - few: "\\u044D\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442\\u044B", - many: "\\u044D\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442\\u0430\\u045E" - }, - verb: "\\u043C\\u0435\\u0446\\u044C" - }, - file: { - unit: { - one: "\\u0431\\u0430\\u0439\\u0442", - few: "\\u0431\\u0430\\u0439\\u0442\\u044B", - many: "\\u0431\\u0430\\u0439\\u0442\\u0430\\u045E" - }, - verb: "\\u043C\\u0435\\u0446\\u044C" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "\\u043B\\u0456\\u043A"; - } - case "object": { - if (Array.isArray(data)) { - return "\\u043C\\u0430\\u0441\\u0456\\u045E"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "\\u0443\\u0432\\u043E\\u0434", - email: "email \\u0430\\u0434\\u0440\\u0430\\u0441", - url: "URL", - emoji: "\\u044D\\u043C\\u043E\\u0434\\u0437\\u0456", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "ISO \\u0434\\u0430\\u0442\\u0430 \\u0456 \\u0447\\u0430\\u0441", - date: "ISO \\u0434\\u0430\\u0442\\u0430", - time: "ISO \\u0447\\u0430\\u0441", - duration: "ISO \\u043F\\u0440\\u0430\\u0446\\u044F\\u0433\\u043B\\u0430\\u0441\\u0446\\u044C", - ipv4: "IPv4 \\u0430\\u0434\\u0440\\u0430\\u0441", - ipv6: "IPv6 \\u0430\\u0434\\u0440\\u0430\\u0441", - cidrv4: "IPv4 \\u0434\\u044B\\u044F\\u043F\\u0430\\u0437\\u043E\\u043D", - cidrv6: "IPv6 \\u0434\\u044B\\u044F\\u043F\\u0430\\u0437\\u043E\\u043D", - base64: "\\u0440\\u0430\\u0434\\u043E\\u043A \\u0443 \\u0444\\u0430\\u0440\\u043C\\u0430\\u0446\\u0435 base64", - base64url: "\\u0440\\u0430\\u0434\\u043E\\u043A \\u0443 \\u0444\\u0430\\u0440\\u043C\\u0430\\u0446\\u0435 base64url", - json_string: "JSON \\u0440\\u0430\\u0434\\u043E\\u043A", - e164: "\\u043D\\u0443\\u043C\\u0430\\u0440 E.164", - jwt: "JWT", - template_literal: "\\u0443\\u0432\\u043E\\u0434" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`\\u041D\\u044F\\u043F\\u0440\\u0430\\u0432\\u0456\\u043B\\u044C\\u043D\\u044B \\u045E\\u0432\\u043E\\u0434: \\u0447\\u0430\\u043A\\u0430\\u045E\\u0441\\u044F \${issue2.expected}, \\u0430\\u0442\\u0440\\u044B\\u043C\\u0430\\u043D\\u0430 \${parsedType7(issue2.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`\\u041D\\u044F\\u043F\\u0440\\u0430\\u0432\\u0456\\u043B\\u044C\\u043D\\u044B \\u045E\\u0432\\u043E\\u0434: \\u0447\\u0430\\u043A\\u0430\\u043B\\u0430\\u0441\\u044F \${stringifyPrimitive(issue2.values[0])}\`; - return \`\\u041D\\u044F\\u043F\\u0440\\u0430\\u0432\\u0456\\u043B\\u044C\\u043D\\u044B \\u0432\\u0430\\u0440\\u044B\\u044F\\u043D\\u0442: \\u0447\\u0430\\u043A\\u0430\\u045E\\u0441\\u044F \\u0430\\u0434\\u0437\\u0456\\u043D \\u0437 \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) { - const maxValue = Number(issue2.maximum); - const unit = getBelarusianPlural(maxValue, sizing.unit.one, sizing.unit.few, sizing.unit.many); - return \`\\u0417\\u0430\\u043D\\u0430\\u0434\\u0442\\u0430 \\u0432\\u044F\\u043B\\u0456\\u043A\\u0456: \\u0447\\u0430\\u043A\\u0430\\u043B\\u0430\\u0441\\u044F, \\u0448\\u0442\\u043E \${issue2.origin ?? "\\u0437\\u043D\\u0430\\u0447\\u044D\\u043D\\u043D\\u0435"} \\u043F\\u0430\\u0432\\u0456\\u043D\\u043D\\u0430 \${sizing.verb} \${adj}\${issue2.maximum.toString()} \${unit}\`; - } - return \`\\u0417\\u0430\\u043D\\u0430\\u0434\\u0442\\u0430 \\u0432\\u044F\\u043B\\u0456\\u043A\\u0456: \\u0447\\u0430\\u043A\\u0430\\u043B\\u0430\\u0441\\u044F, \\u0448\\u0442\\u043E \${issue2.origin ?? "\\u0437\\u043D\\u0430\\u0447\\u044D\\u043D\\u043D\\u0435"} \\u043F\\u0430\\u0432\\u0456\\u043D\\u043D\\u0430 \\u0431\\u044B\\u0446\\u044C \${adj}\${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - const minValue = Number(issue2.minimum); - const unit = getBelarusianPlural(minValue, sizing.unit.one, sizing.unit.few, sizing.unit.many); - return \`\\u0417\\u0430\\u043D\\u0430\\u0434\\u0442\\u0430 \\u043C\\u0430\\u043B\\u044B: \\u0447\\u0430\\u043A\\u0430\\u043B\\u0430\\u0441\\u044F, \\u0448\\u0442\\u043E \${issue2.origin} \\u043F\\u0430\\u0432\\u0456\\u043D\\u043D\\u0430 \${sizing.verb} \${adj}\${issue2.minimum.toString()} \${unit}\`; - } - return \`\\u0417\\u0430\\u043D\\u0430\\u0434\\u0442\\u0430 \\u043C\\u0430\\u043B\\u044B: \\u0447\\u0430\\u043A\\u0430\\u043B\\u0430\\u0441\\u044F, \\u0448\\u0442\\u043E \${issue2.origin} \\u043F\\u0430\\u0432\\u0456\\u043D\\u043D\\u0430 \\u0431\\u044B\\u0446\\u044C \${adj}\${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") return \`\\u041D\\u044F\\u043F\\u0440\\u0430\\u0432\\u0456\\u043B\\u044C\\u043D\\u044B \\u0440\\u0430\\u0434\\u043E\\u043A: \\u043F\\u0430\\u0432\\u0456\\u043D\\u0435\\u043D \\u043F\\u0430\\u0447\\u044B\\u043D\\u0430\\u0446\\u0446\\u0430 \\u0437 "\${_issue.prefix}"\`; - if (_issue.format === "ends_with") return \`\\u041D\\u044F\\u043F\\u0440\\u0430\\u0432\\u0456\\u043B\\u044C\\u043D\\u044B \\u0440\\u0430\\u0434\\u043E\\u043A: \\u043F\\u0430\\u0432\\u0456\\u043D\\u0435\\u043D \\u0437\\u0430\\u043A\\u0430\\u043D\\u0447\\u0432\\u0430\\u0446\\u0446\\u0430 \\u043D\\u0430 "\${_issue.suffix}"\`; - if (_issue.format === "includes") return \`\\u041D\\u044F\\u043F\\u0440\\u0430\\u0432\\u0456\\u043B\\u044C\\u043D\\u044B \\u0440\\u0430\\u0434\\u043E\\u043A: \\u043F\\u0430\\u0432\\u0456\\u043D\\u0435\\u043D \\u0437\\u043C\\u044F\\u0448\\u0447\\u0430\\u0446\\u044C "\${_issue.includes}"\`; - if (_issue.format === "regex") return \`\\u041D\\u044F\\u043F\\u0440\\u0430\\u0432\\u0456\\u043B\\u044C\\u043D\\u044B \\u0440\\u0430\\u0434\\u043E\\u043A: \\u043F\\u0430\\u0432\\u0456\\u043D\\u0435\\u043D \\u0430\\u0434\\u043F\\u0430\\u0432\\u044F\\u0434\\u0430\\u0446\\u044C \\u0448\\u0430\\u0431\\u043B\\u043E\\u043D\\u0443 \${_issue.pattern}\`; - return \`\\u041D\\u044F\\u043F\\u0440\\u0430\\u0432\\u0456\\u043B\\u044C\\u043D\\u044B \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`\\u041D\\u044F\\u043F\\u0440\\u0430\\u0432\\u0456\\u043B\\u044C\\u043D\\u044B \\u043B\\u0456\\u043A: \\u043F\\u0430\\u0432\\u0456\\u043D\\u0435\\u043D \\u0431\\u044B\\u0446\\u044C \\u043A\\u0440\\u0430\\u0442\\u043D\\u044B\\u043C \${issue2.divisor}\`; - case "unrecognized_keys": - return \`\\u041D\\u0435\\u0440\\u0430\\u0441\\u043F\\u0430\\u0437\\u043D\\u0430\\u043D\\u044B \${issue2.keys.length > 1 ? "\\u043A\\u043B\\u044E\\u0447\\u044B" : "\\u043A\\u043B\\u044E\\u0447"}: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`\\u041D\\u044F\\u043F\\u0440\\u0430\\u0432\\u0456\\u043B\\u044C\\u043D\\u044B \\u043A\\u043B\\u044E\\u0447 \\u0443 \${issue2.origin}\`; - case "invalid_union": - return "\\u041D\\u044F\\u043F\\u0440\\u0430\\u0432\\u0456\\u043B\\u044C\\u043D\\u044B \\u045E\\u0432\\u043E\\u0434"; - case "invalid_element": - return \`\\u041D\\u044F\\u043F\\u0440\\u0430\\u0432\\u0456\\u043B\\u044C\\u043D\\u0430\\u0435 \\u0437\\u043D\\u0430\\u0447\\u044D\\u043D\\u043D\\u0435 \\u045E \${issue2.origin}\`; - default: - return \`\\u041D\\u044F\\u043F\\u0440\\u0430\\u0432\\u0456\\u043B\\u044C\\u043D\\u044B \\u045E\\u0432\\u043E\\u0434\`; - } - }; -}, "error"); -function be_default() { - return { - localeError: error3() - }; -} -__name(be_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/ca.js -var error4 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "car\\xE0cters", - verb: "contenir" - }, - file: { - unit: "bytes", - verb: "contenir" - }, - array: { - unit: "elements", - verb: "contenir" - }, - set: { - unit: "elements", - verb: "contenir" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "number"; - } - case "object": { - if (Array.isArray(data)) { - return "array"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "entrada", - email: "adre\\xE7a electr\\xF2nica", - url: "URL", - emoji: "emoji", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "data i hora ISO", - date: "data ISO", - time: "hora ISO", - duration: "durada ISO", - ipv4: "adre\\xE7a IPv4", - ipv6: "adre\\xE7a IPv6", - cidrv4: "rang IPv4", - cidrv6: "rang IPv6", - base64: "cadena codificada en base64", - base64url: "cadena codificada en base64url", - json_string: "cadena JSON", - e164: "n\\xFAmero E.164", - jwt: "JWT", - template_literal: "entrada" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`Tipus inv\\xE0lid: s'esperava \${issue2.expected}, s'ha rebut \${parsedType7(issue2.input)}\`; - // return \`Tipus invàlid: s'esperava \${issue.expected}, s'ha rebut \${util.getParsedType(issue.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`Valor inv\\xE0lid: s'esperava \${stringifyPrimitive(issue2.values[0])}\`; - return \`Opci\\xF3 inv\\xE0lida: s'esperava una de \${joinValues(issue2.values, " o ")}\`; - case "too_big": { - const adj = issue2.inclusive ? "com a m\\xE0xim" : "menys de"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`Massa gran: s'esperava que \${issue2.origin ?? "el valor"} contingu\\xE9s \${adj} \${issue2.maximum.toString()} \${sizing.unit ?? "elements"}\`; - return \`Massa gran: s'esperava que \${issue2.origin ?? "el valor"} fos \${adj} \${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? "com a m\\xEDnim" : "m\\xE9s de"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`Massa petit: s'esperava que \${issue2.origin} contingu\\xE9s \${adj} \${issue2.minimum.toString()} \${sizing.unit}\`; - } - return \`Massa petit: s'esperava que \${issue2.origin} fos \${adj} \${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") { - return \`Format inv\\xE0lid: ha de comen\\xE7ar amb "\${_issue.prefix}"\`; - } - if (_issue.format === "ends_with") return \`Format inv\\xE0lid: ha d'acabar amb "\${_issue.suffix}"\`; - if (_issue.format === "includes") return \`Format inv\\xE0lid: ha d'incloure "\${_issue.includes}"\`; - if (_issue.format === "regex") return \`Format inv\\xE0lid: ha de coincidir amb el patr\\xF3 \${_issue.pattern}\`; - return \`Format inv\\xE0lid per a \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`N\\xFAmero inv\\xE0lid: ha de ser m\\xFAltiple de \${issue2.divisor}\`; - case "unrecognized_keys": - return \`Clau\${issue2.keys.length > 1 ? "s" : ""} no reconeguda\${issue2.keys.length > 1 ? "s" : ""}: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`Clau inv\\xE0lida a \${issue2.origin}\`; - case "invalid_union": - return "Entrada inv\\xE0lida"; - // Could also be "Tipus d'unió invàlid" but "Entrada invàlida" is more general - case "invalid_element": - return \`Element inv\\xE0lid a \${issue2.origin}\`; - default: - return \`Entrada inv\\xE0lida\`; - } - }; -}, "error"); -function ca_default() { - return { - localeError: error4() - }; -} -__name(ca_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/cs.js -var error5 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "znak\\u016F", - verb: "m\\xEDt" - }, - file: { - unit: "bajt\\u016F", - verb: "m\\xEDt" - }, - array: { - unit: "prvk\\u016F", - verb: "m\\xEDt" - }, - set: { - unit: "prvk\\u016F", - verb: "m\\xEDt" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "\\u010D\\xEDslo"; - } - case "string": { - return "\\u0159et\\u011Bzec"; - } - case "boolean": { - return "boolean"; - } - case "bigint": { - return "bigint"; - } - case "function": { - return "funkce"; - } - case "symbol": { - return "symbol"; - } - case "undefined": { - return "undefined"; - } - case "object": { - if (Array.isArray(data)) { - return "pole"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "regul\\xE1rn\\xED v\\xFDraz", - email: "e-mailov\\xE1 adresa", - url: "URL", - emoji: "emoji", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "datum a \\u010Das ve form\\xE1tu ISO", - date: "datum ve form\\xE1tu ISO", - time: "\\u010Das ve form\\xE1tu ISO", - duration: "doba trv\\xE1n\\xED ISO", - ipv4: "IPv4 adresa", - ipv6: "IPv6 adresa", - cidrv4: "rozsah IPv4", - cidrv6: "rozsah IPv6", - base64: "\\u0159et\\u011Bzec zak\\xF3dovan\\xFD ve form\\xE1tu base64", - base64url: "\\u0159et\\u011Bzec zak\\xF3dovan\\xFD ve form\\xE1tu base64url", - json_string: "\\u0159et\\u011Bzec ve form\\xE1tu JSON", - e164: "\\u010D\\xEDslo E.164", - jwt: "JWT", - template_literal: "vstup" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`Neplatn\\xFD vstup: o\\u010Dek\\xE1v\\xE1no \${issue2.expected}, obdr\\u017Eeno \${parsedType7(issue2.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`Neplatn\\xFD vstup: o\\u010Dek\\xE1v\\xE1no \${stringifyPrimitive(issue2.values[0])}\`; - return \`Neplatn\\xE1 mo\\u017Enost: o\\u010Dek\\xE1v\\xE1na jedna z hodnot \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`Hodnota je p\\u0159\\xEDli\\u0161 velk\\xE1: \${issue2.origin ?? "hodnota"} mus\\xED m\\xEDt \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "prvk\\u016F"}\`; - } - return \`Hodnota je p\\u0159\\xEDli\\u0161 velk\\xE1: \${issue2.origin ?? "hodnota"} mus\\xED b\\xFDt \${adj}\${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`Hodnota je p\\u0159\\xEDli\\u0161 mal\\xE1: \${issue2.origin ?? "hodnota"} mus\\xED m\\xEDt \${adj}\${issue2.minimum.toString()} \${sizing.unit ?? "prvk\\u016F"}\`; - } - return \`Hodnota je p\\u0159\\xEDli\\u0161 mal\\xE1: \${issue2.origin ?? "hodnota"} mus\\xED b\\xFDt \${adj}\${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") return \`Neplatn\\xFD \\u0159et\\u011Bzec: mus\\xED za\\u010D\\xEDnat na "\${_issue.prefix}"\`; - if (_issue.format === "ends_with") return \`Neplatn\\xFD \\u0159et\\u011Bzec: mus\\xED kon\\u010Dit na "\${_issue.suffix}"\`; - if (_issue.format === "includes") return \`Neplatn\\xFD \\u0159et\\u011Bzec: mus\\xED obsahovat "\${_issue.includes}"\`; - if (_issue.format === "regex") return \`Neplatn\\xFD \\u0159et\\u011Bzec: mus\\xED odpov\\xEDdat vzoru \${_issue.pattern}\`; - return \`Neplatn\\xFD form\\xE1t \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`Neplatn\\xE9 \\u010D\\xEDslo: mus\\xED b\\xFDt n\\xE1sobkem \${issue2.divisor}\`; - case "unrecognized_keys": - return \`Nezn\\xE1m\\xE9 kl\\xED\\u010De: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`Neplatn\\xFD kl\\xED\\u010D v \${issue2.origin}\`; - case "invalid_union": - return "Neplatn\\xFD vstup"; - case "invalid_element": - return \`Neplatn\\xE1 hodnota v \${issue2.origin}\`; - default: - return \`Neplatn\\xFD vstup\`; - } - }; -}, "error"); -function cs_default() { - return { - localeError: error5() - }; -} -__name(cs_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/da.js -var error6 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "tegn", - verb: "havde" - }, - file: { - unit: "bytes", - verb: "havde" - }, - array: { - unit: "elementer", - verb: "indeholdt" - }, - set: { - unit: "elementer", - verb: "indeholdt" - } - }; - const TypeNames = { - string: "streng", - number: "tal", - boolean: "boolean", - array: "liste", - object: "objekt", - set: "s\\xE6t", - file: "fil" - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - function getTypeName(type) { - return TypeNames[type] ?? type; - } - __name(getTypeName, "getTypeName"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "tal"; - } - case "object": { - if (Array.isArray(data)) { - return "liste"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - return "objekt"; - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "input", - email: "e-mailadresse", - url: "URL", - emoji: "emoji", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "ISO dato- og klokkesl\\xE6t", - date: "ISO-dato", - time: "ISO-klokkesl\\xE6t", - duration: "ISO-varighed", - ipv4: "IPv4-omr\\xE5de", - ipv6: "IPv6-omr\\xE5de", - cidrv4: "IPv4-spektrum", - cidrv6: "IPv6-spektrum", - base64: "base64-kodet streng", - base64url: "base64url-kodet streng", - json_string: "JSON-streng", - e164: "E.164-nummer", - jwt: "JWT", - template_literal: "input" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`Ugyldigt input: forventede \${getTypeName(issue2.expected)}, fik \${getTypeName(parsedType7(issue2.input))}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`Ugyldig v\\xE6rdi: forventede \${stringifyPrimitive(issue2.values[0])}\`; - return \`Ugyldigt valg: forventede en af f\\xF8lgende \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - const origin = getTypeName(issue2.origin); - if (sizing) return \`For stor: forventede \${origin ?? "value"} \${sizing.verb} \${adj} \${issue2.maximum.toString()} \${sizing.unit ?? "elementer"}\`; - return \`For stor: forventede \${origin ?? "value"} havde \${adj} \${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - const origin = getTypeName(issue2.origin); - if (sizing) { - return \`For lille: forventede \${origin} \${sizing.verb} \${adj} \${issue2.minimum.toString()} \${sizing.unit}\`; - } - return \`For lille: forventede \${origin} havde \${adj} \${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") return \`Ugyldig streng: skal starte med "\${_issue.prefix}"\`; - if (_issue.format === "ends_with") return \`Ugyldig streng: skal ende med "\${_issue.suffix}"\`; - if (_issue.format === "includes") return \`Ugyldig streng: skal indeholde "\${_issue.includes}"\`; - if (_issue.format === "regex") return \`Ugyldig streng: skal matche m\\xF8nsteret \${_issue.pattern}\`; - return \`Ugyldig \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`Ugyldigt tal: skal v\\xE6re deleligt med \${issue2.divisor}\`; - case "unrecognized_keys": - return \`\${issue2.keys.length > 1 ? "Ukendte n\\xF8gler" : "Ukendt n\\xF8gle"}: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`Ugyldig n\\xF8gle i \${issue2.origin}\`; - case "invalid_union": - return "Ugyldigt input: matcher ingen af de tilladte typer"; - case "invalid_element": - return \`Ugyldig v\\xE6rdi i \${issue2.origin}\`; - default: - return \`Ugyldigt input\`; - } - }; -}, "error"); -function da_default() { - return { - localeError: error6() - }; -} -__name(da_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/de.js -var error7 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "Zeichen", - verb: "zu haben" - }, - file: { - unit: "Bytes", - verb: "zu haben" - }, - array: { - unit: "Elemente", - verb: "zu haben" - }, - set: { - unit: "Elemente", - verb: "zu haben" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "Zahl"; - } - case "object": { - if (Array.isArray(data)) { - return "Array"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "Eingabe", - email: "E-Mail-Adresse", - url: "URL", - emoji: "Emoji", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "ISO-Datum und -Uhrzeit", - date: "ISO-Datum", - time: "ISO-Uhrzeit", - duration: "ISO-Dauer", - ipv4: "IPv4-Adresse", - ipv6: "IPv6-Adresse", - cidrv4: "IPv4-Bereich", - cidrv6: "IPv6-Bereich", - base64: "Base64-codierter String", - base64url: "Base64-URL-codierter String", - json_string: "JSON-String", - e164: "E.164-Nummer", - jwt: "JWT", - template_literal: "Eingabe" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`Ung\\xFCltige Eingabe: erwartet \${issue2.expected}, erhalten \${parsedType7(issue2.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`Ung\\xFCltige Eingabe: erwartet \${stringifyPrimitive(issue2.values[0])}\`; - return \`Ung\\xFCltige Option: erwartet eine von \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`Zu gro\\xDF: erwartet, dass \${issue2.origin ?? "Wert"} \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "Elemente"} hat\`; - return \`Zu gro\\xDF: erwartet, dass \${issue2.origin ?? "Wert"} \${adj}\${issue2.maximum.toString()} ist\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`Zu klein: erwartet, dass \${issue2.origin} \${adj}\${issue2.minimum.toString()} \${sizing.unit} hat\`; - } - return \`Zu klein: erwartet, dass \${issue2.origin} \${adj}\${issue2.minimum.toString()} ist\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") return \`Ung\\xFCltiger String: muss mit "\${_issue.prefix}" beginnen\`; - if (_issue.format === "ends_with") return \`Ung\\xFCltiger String: muss mit "\${_issue.suffix}" enden\`; - if (_issue.format === "includes") return \`Ung\\xFCltiger String: muss "\${_issue.includes}" enthalten\`; - if (_issue.format === "regex") return \`Ung\\xFCltiger String: muss dem Muster \${_issue.pattern} entsprechen\`; - return \`Ung\\xFCltig: \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`Ung\\xFCltige Zahl: muss ein Vielfaches von \${issue2.divisor} sein\`; - case "unrecognized_keys": - return \`\${issue2.keys.length > 1 ? "Unbekannte Schl\\xFCssel" : "Unbekannter Schl\\xFCssel"}: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`Ung\\xFCltiger Schl\\xFCssel in \${issue2.origin}\`; - case "invalid_union": - return "Ung\\xFCltige Eingabe"; - case "invalid_element": - return \`Ung\\xFCltiger Wert in \${issue2.origin}\`; - default: - return \`Ung\\xFCltige Eingabe\`; - } - }; -}, "error"); -function de_default() { - return { - localeError: error7() - }; -} -__name(de_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/en.js -var parsedType = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "number"; - } - case "object": { - if (Array.isArray(data)) { - return "array"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; -}, "parsedType"); -var error8 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "characters", - verb: "to have" - }, - file: { - unit: "bytes", - verb: "to have" - }, - array: { - unit: "items", - verb: "to have" - }, - set: { - unit: "items", - verb: "to have" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const Nouns = { - regex: "input", - email: "email address", - url: "URL", - emoji: "emoji", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "ISO datetime", - date: "ISO date", - time: "ISO time", - duration: "ISO duration", - ipv4: "IPv4 address", - ipv6: "IPv6 address", - cidrv4: "IPv4 range", - cidrv6: "IPv6 range", - base64: "base64-encoded string", - base64url: "base64url-encoded string", - json_string: "JSON string", - e164: "E.164 number", - jwt: "JWT", - template_literal: "input" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`Invalid input: expected \${issue2.expected}, received \${parsedType(issue2.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`Invalid input: expected \${stringifyPrimitive(issue2.values[0])}\`; - return \`Invalid option: expected one of \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`Too big: expected \${issue2.origin ?? "value"} to have \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "elements"}\`; - return \`Too big: expected \${issue2.origin ?? "value"} to be \${adj}\${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`Too small: expected \${issue2.origin} to have \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; - } - return \`Too small: expected \${issue2.origin} to be \${adj}\${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") { - return \`Invalid string: must start with "\${_issue.prefix}"\`; - } - if (_issue.format === "ends_with") return \`Invalid string: must end with "\${_issue.suffix}"\`; - if (_issue.format === "includes") return \`Invalid string: must include "\${_issue.includes}"\`; - if (_issue.format === "regex") return \`Invalid string: must match pattern \${_issue.pattern}\`; - return \`Invalid \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`Invalid number: must be a multiple of \${issue2.divisor}\`; - case "unrecognized_keys": - return \`Unrecognized key\${issue2.keys.length > 1 ? "s" : ""}: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`Invalid key in \${issue2.origin}\`; - case "invalid_union": - return "Invalid input"; - case "invalid_element": - return \`Invalid value in \${issue2.origin}\`; - default: - return \`Invalid input\`; - } - }; -}, "error"); -function en_default() { - return { - localeError: error8() - }; -} -__name(en_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/eo.js -var parsedType2 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "nombro"; - } - case "object": { - if (Array.isArray(data)) { - return "tabelo"; - } - if (data === null) { - return "senvalora"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; -}, "parsedType"); -var error9 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "karaktrojn", - verb: "havi" - }, - file: { - unit: "bajtojn", - verb: "havi" - }, - array: { - unit: "elementojn", - verb: "havi" - }, - set: { - unit: "elementojn", - verb: "havi" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const Nouns = { - regex: "enigo", - email: "retadreso", - url: "URL", - emoji: "emo\\u011Dio", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "ISO-datotempo", - date: "ISO-dato", - time: "ISO-tempo", - duration: "ISO-da\\u016Dro", - ipv4: "IPv4-adreso", - ipv6: "IPv6-adreso", - cidrv4: "IPv4-rango", - cidrv6: "IPv6-rango", - base64: "64-ume kodita karaktraro", - base64url: "URL-64-ume kodita karaktraro", - json_string: "JSON-karaktraro", - e164: "E.164-nombro", - jwt: "JWT", - template_literal: "enigo" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`Nevalida enigo: atendi\\u011Dis \${issue2.expected}, ricevi\\u011Dis \${parsedType2(issue2.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`Nevalida enigo: atendi\\u011Dis \${stringifyPrimitive(issue2.values[0])}\`; - return \`Nevalida opcio: atendi\\u011Dis unu el \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`Tro granda: atendi\\u011Dis ke \${issue2.origin ?? "valoro"} havu \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "elementojn"}\`; - return \`Tro granda: atendi\\u011Dis ke \${issue2.origin ?? "valoro"} havu \${adj}\${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`Tro malgranda: atendi\\u011Dis ke \${issue2.origin} havu \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; - } - return \`Tro malgranda: atendi\\u011Dis ke \${issue2.origin} estu \${adj}\${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") return \`Nevalida karaktraro: devas komenci\\u011Di per "\${_issue.prefix}"\`; - if (_issue.format === "ends_with") return \`Nevalida karaktraro: devas fini\\u011Di per "\${_issue.suffix}"\`; - if (_issue.format === "includes") return \`Nevalida karaktraro: devas inkluzivi "\${_issue.includes}"\`; - if (_issue.format === "regex") return \`Nevalida karaktraro: devas kongrui kun la modelo \${_issue.pattern}\`; - return \`Nevalida \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`Nevalida nombro: devas esti oblo de \${issue2.divisor}\`; - case "unrecognized_keys": - return \`Nekonata\${issue2.keys.length > 1 ? "j" : ""} \\u015Dlosilo\${issue2.keys.length > 1 ? "j" : ""}: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`Nevalida \\u015Dlosilo en \${issue2.origin}\`; - case "invalid_union": - return "Nevalida enigo"; - case "invalid_element": - return \`Nevalida valoro en \${issue2.origin}\`; - default: - return \`Nevalida enigo\`; - } - }; -}, "error"); -function eo_default() { - return { - localeError: error9() - }; -} -__name(eo_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/es.js -var error10 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "caracteres", - verb: "tener" - }, - file: { - unit: "bytes", - verb: "tener" - }, - array: { - unit: "elementos", - verb: "tener" - }, - set: { - unit: "elementos", - verb: "tener" - } - }; - const TypeNames = { - string: "texto", - number: "n\\xFAmero", - boolean: "booleano", - array: "arreglo", - object: "objeto", - set: "conjunto", - file: "archivo", - date: "fecha", - bigint: "n\\xFAmero grande", - symbol: "s\\xEDmbolo", - undefined: "indefinido", - null: "nulo", - function: "funci\\xF3n", - map: "mapa", - record: "registro", - tuple: "tupla", - enum: "enumeraci\\xF3n", - union: "uni\\xF3n", - literal: "literal", - promise: "promesa", - void: "vac\\xEDo", - never: "nunca", - unknown: "desconocido", - any: "cualquiera" - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - function getTypeName(type) { - return TypeNames[type] ?? type; - } - __name(getTypeName, "getTypeName"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "number"; - } - case "object": { - if (Array.isArray(data)) { - return "array"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype) { - return data.constructor.name; - } - return "object"; - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "entrada", - email: "direcci\\xF3n de correo electr\\xF3nico", - url: "URL", - emoji: "emoji", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "fecha y hora ISO", - date: "fecha ISO", - time: "hora ISO", - duration: "duraci\\xF3n ISO", - ipv4: "direcci\\xF3n IPv4", - ipv6: "direcci\\xF3n IPv6", - cidrv4: "rango IPv4", - cidrv6: "rango IPv6", - base64: "cadena codificada en base64", - base64url: "URL codificada en base64", - json_string: "cadena JSON", - e164: "n\\xFAmero E.164", - jwt: "JWT", - template_literal: "entrada" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`Entrada inv\\xE1lida: se esperaba \${getTypeName(issue2.expected)}, recibido \${getTypeName(parsedType7(issue2.input))}\`; - // return \`Entrada inválida: se esperaba \${issue.expected}, recibido \${util.getParsedType(issue.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`Entrada inv\\xE1lida: se esperaba \${stringifyPrimitive(issue2.values[0])}\`; - return \`Opci\\xF3n inv\\xE1lida: se esperaba una de \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - const origin = getTypeName(issue2.origin); - if (sizing) return \`Demasiado grande: se esperaba que \${origin ?? "valor"} tuviera \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "elementos"}\`; - return \`Demasiado grande: se esperaba que \${origin ?? "valor"} fuera \${adj}\${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - const origin = getTypeName(issue2.origin); - if (sizing) { - return \`Demasiado peque\\xF1o: se esperaba que \${origin} tuviera \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; - } - return \`Demasiado peque\\xF1o: se esperaba que \${origin} fuera \${adj}\${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") return \`Cadena inv\\xE1lida: debe comenzar con "\${_issue.prefix}"\`; - if (_issue.format === "ends_with") return \`Cadena inv\\xE1lida: debe terminar en "\${_issue.suffix}"\`; - if (_issue.format === "includes") return \`Cadena inv\\xE1lida: debe incluir "\${_issue.includes}"\`; - if (_issue.format === "regex") return \`Cadena inv\\xE1lida: debe coincidir con el patr\\xF3n \${_issue.pattern}\`; - return \`Inv\\xE1lido \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`N\\xFAmero inv\\xE1lido: debe ser m\\xFAltiplo de \${issue2.divisor}\`; - case "unrecognized_keys": - return \`Llave\${issue2.keys.length > 1 ? "s" : ""} desconocida\${issue2.keys.length > 1 ? "s" : ""}: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`Llave inv\\xE1lida en \${getTypeName(issue2.origin)}\`; - case "invalid_union": - return "Entrada inv\\xE1lida"; - case "invalid_element": - return \`Valor inv\\xE1lido en \${getTypeName(issue2.origin)}\`; - default: - return \`Entrada inv\\xE1lida\`; - } - }; -}, "error"); -function es_default() { - return { - localeError: error10() - }; -} -__name(es_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/fa.js -var error11 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "\\u06A9\\u0627\\u0631\\u0627\\u06A9\\u062A\\u0631", - verb: "\\u062F\\u0627\\u0634\\u062A\\u0647 \\u0628\\u0627\\u0634\\u062F" - }, - file: { - unit: "\\u0628\\u0627\\u06CC\\u062A", - verb: "\\u062F\\u0627\\u0634\\u062A\\u0647 \\u0628\\u0627\\u0634\\u062F" - }, - array: { - unit: "\\u0622\\u06CC\\u062A\\u0645", - verb: "\\u062F\\u0627\\u0634\\u062A\\u0647 \\u0628\\u0627\\u0634\\u062F" - }, - set: { - unit: "\\u0622\\u06CC\\u062A\\u0645", - verb: "\\u062F\\u0627\\u0634\\u062A\\u0647 \\u0628\\u0627\\u0634\\u062F" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "\\u0639\\u062F\\u062F"; - } - case "object": { - if (Array.isArray(data)) { - return "\\u0622\\u0631\\u0627\\u06CC\\u0647"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "\\u0648\\u0631\\u0648\\u062F\\u06CC", - email: "\\u0622\\u062F\\u0631\\u0633 \\u0627\\u06CC\\u0645\\u06CC\\u0644", - url: "URL", - emoji: "\\u0627\\u06CC\\u0645\\u0648\\u062C\\u06CC", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "\\u062A\\u0627\\u0631\\u06CC\\u062E \\u0648 \\u0632\\u0645\\u0627\\u0646 \\u0627\\u06CC\\u0632\\u0648", - date: "\\u062A\\u0627\\u0631\\u06CC\\u062E \\u0627\\u06CC\\u0632\\u0648", - time: "\\u0632\\u0645\\u0627\\u0646 \\u0627\\u06CC\\u0632\\u0648", - duration: "\\u0645\\u062F\\u062A \\u0632\\u0645\\u0627\\u0646 \\u0627\\u06CC\\u0632\\u0648", - ipv4: "IPv4 \\u0622\\u062F\\u0631\\u0633", - ipv6: "IPv6 \\u0622\\u062F\\u0631\\u0633", - cidrv4: "IPv4 \\u062F\\u0627\\u0645\\u0646\\u0647", - cidrv6: "IPv6 \\u062F\\u0627\\u0645\\u0646\\u0647", - base64: "base64-encoded \\u0631\\u0634\\u062A\\u0647", - base64url: "base64url-encoded \\u0631\\u0634\\u062A\\u0647", - json_string: "JSON \\u0631\\u0634\\u062A\\u0647", - e164: "E.164 \\u0639\\u062F\\u062F", - jwt: "JWT", - template_literal: "\\u0648\\u0631\\u0648\\u062F\\u06CC" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`\\u0648\\u0631\\u0648\\u062F\\u06CC \\u0646\\u0627\\u0645\\u0639\\u062A\\u0628\\u0631: \\u0645\\u06CC\\u200C\\u0628\\u0627\\u06CC\\u0633\\u062A \${issue2.expected} \\u0645\\u06CC\\u200C\\u0628\\u0648\\u062F\\u060C \${parsedType7(issue2.input)} \\u062F\\u0631\\u06CC\\u0627\\u0641\\u062A \\u0634\\u062F\`; - case "invalid_value": - if (issue2.values.length === 1) { - return \`\\u0648\\u0631\\u0648\\u062F\\u06CC \\u0646\\u0627\\u0645\\u0639\\u062A\\u0628\\u0631: \\u0645\\u06CC\\u200C\\u0628\\u0627\\u06CC\\u0633\\u062A \${stringifyPrimitive(issue2.values[0])} \\u0645\\u06CC\\u200C\\u0628\\u0648\\u062F\`; - } - return \`\\u06AF\\u0632\\u06CC\\u0646\\u0647 \\u0646\\u0627\\u0645\\u0639\\u062A\\u0628\\u0631: \\u0645\\u06CC\\u200C\\u0628\\u0627\\u06CC\\u0633\\u062A \\u06CC\\u06A9\\u06CC \\u0627\\u0632 \${joinValues(issue2.values, "|")} \\u0645\\u06CC\\u200C\\u0628\\u0648\\u062F\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`\\u062E\\u06CC\\u0644\\u06CC \\u0628\\u0632\\u0631\\u06AF: \${issue2.origin ?? "\\u0645\\u0642\\u062F\\u0627\\u0631"} \\u0628\\u0627\\u06CC\\u062F \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "\\u0639\\u0646\\u0635\\u0631"} \\u0628\\u0627\\u0634\\u062F\`; - } - return \`\\u062E\\u06CC\\u0644\\u06CC \\u0628\\u0632\\u0631\\u06AF: \${issue2.origin ?? "\\u0645\\u0642\\u062F\\u0627\\u0631"} \\u0628\\u0627\\u06CC\\u062F \${adj}\${issue2.maximum.toString()} \\u0628\\u0627\\u0634\\u062F\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`\\u062E\\u06CC\\u0644\\u06CC \\u06A9\\u0648\\u0686\\u06A9: \${issue2.origin} \\u0628\\u0627\\u06CC\\u062F \${adj}\${issue2.minimum.toString()} \${sizing.unit} \\u0628\\u0627\\u0634\\u062F\`; - } - return \`\\u062E\\u06CC\\u0644\\u06CC \\u06A9\\u0648\\u0686\\u06A9: \${issue2.origin} \\u0628\\u0627\\u06CC\\u062F \${adj}\${issue2.minimum.toString()} \\u0628\\u0627\\u0634\\u062F\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") { - return \`\\u0631\\u0634\\u062A\\u0647 \\u0646\\u0627\\u0645\\u0639\\u062A\\u0628\\u0631: \\u0628\\u0627\\u06CC\\u062F \\u0628\\u0627 "\${_issue.prefix}" \\u0634\\u0631\\u0648\\u0639 \\u0634\\u0648\\u062F\`; - } - if (_issue.format === "ends_with") { - return \`\\u0631\\u0634\\u062A\\u0647 \\u0646\\u0627\\u0645\\u0639\\u062A\\u0628\\u0631: \\u0628\\u0627\\u06CC\\u062F \\u0628\\u0627 "\${_issue.suffix}" \\u062A\\u0645\\u0627\\u0645 \\u0634\\u0648\\u062F\`; - } - if (_issue.format === "includes") { - return \`\\u0631\\u0634\\u062A\\u0647 \\u0646\\u0627\\u0645\\u0639\\u062A\\u0628\\u0631: \\u0628\\u0627\\u06CC\\u062F \\u0634\\u0627\\u0645\\u0644 "\${_issue.includes}" \\u0628\\u0627\\u0634\\u062F\`; - } - if (_issue.format === "regex") { - return \`\\u0631\\u0634\\u062A\\u0647 \\u0646\\u0627\\u0645\\u0639\\u062A\\u0628\\u0631: \\u0628\\u0627\\u06CC\\u062F \\u0628\\u0627 \\u0627\\u0644\\u06AF\\u0648\\u06CC \${_issue.pattern} \\u0645\\u0637\\u0627\\u0628\\u0642\\u062A \\u062F\\u0627\\u0634\\u062A\\u0647 \\u0628\\u0627\\u0634\\u062F\`; - } - return \`\${Nouns[_issue.format] ?? issue2.format} \\u0646\\u0627\\u0645\\u0639\\u062A\\u0628\\u0631\`; - } - case "not_multiple_of": - return \`\\u0639\\u062F\\u062F \\u0646\\u0627\\u0645\\u0639\\u062A\\u0628\\u0631: \\u0628\\u0627\\u06CC\\u062F \\u0645\\u0636\\u0631\\u0628 \${issue2.divisor} \\u0628\\u0627\\u0634\\u062F\`; - case "unrecognized_keys": - return \`\\u06A9\\u0644\\u06CC\\u062F\${issue2.keys.length > 1 ? "\\u0647\\u0627\\u06CC" : ""} \\u0646\\u0627\\u0634\\u0646\\u0627\\u0633: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`\\u06A9\\u0644\\u06CC\\u062F \\u0646\\u0627\\u0634\\u0646\\u0627\\u0633 \\u062F\\u0631 \${issue2.origin}\`; - case "invalid_union": - return \`\\u0648\\u0631\\u0648\\u062F\\u06CC \\u0646\\u0627\\u0645\\u0639\\u062A\\u0628\\u0631\`; - case "invalid_element": - return \`\\u0645\\u0642\\u062F\\u0627\\u0631 \\u0646\\u0627\\u0645\\u0639\\u062A\\u0628\\u0631 \\u062F\\u0631 \${issue2.origin}\`; - default: - return \`\\u0648\\u0631\\u0648\\u062F\\u06CC \\u0646\\u0627\\u0645\\u0639\\u062A\\u0628\\u0631\`; - } - }; -}, "error"); -function fa_default() { - return { - localeError: error11() - }; -} -__name(fa_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/fi.js -var error12 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "merkki\\xE4", - subject: "merkkijonon" - }, - file: { - unit: "tavua", - subject: "tiedoston" - }, - array: { - unit: "alkiota", - subject: "listan" - }, - set: { - unit: "alkiota", - subject: "joukon" - }, - number: { - unit: "", - subject: "luvun" - }, - bigint: { - unit: "", - subject: "suuren kokonaisluvun" - }, - int: { - unit: "", - subject: "kokonaisluvun" - }, - date: { - unit: "", - subject: "p\\xE4iv\\xE4m\\xE4\\xE4r\\xE4n" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "number"; - } - case "object": { - if (Array.isArray(data)) { - return "array"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "s\\xE4\\xE4nn\\xF6llinen lauseke", - email: "s\\xE4hk\\xF6postiosoite", - url: "URL-osoite", - emoji: "emoji", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "ISO-aikaleima", - date: "ISO-p\\xE4iv\\xE4m\\xE4\\xE4r\\xE4", - time: "ISO-aika", - duration: "ISO-kesto", - ipv4: "IPv4-osoite", - ipv6: "IPv6-osoite", - cidrv4: "IPv4-alue", - cidrv6: "IPv6-alue", - base64: "base64-koodattu merkkijono", - base64url: "base64url-koodattu merkkijono", - json_string: "JSON-merkkijono", - e164: "E.164-luku", - jwt: "JWT", - template_literal: "templaattimerkkijono" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`Virheellinen tyyppi: odotettiin \${issue2.expected}, oli \${parsedType7(issue2.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`Virheellinen sy\\xF6te: t\\xE4ytyy olla \${stringifyPrimitive(issue2.values[0])}\`; - return \`Virheellinen valinta: t\\xE4ytyy olla yksi seuraavista: \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`Liian suuri: \${sizing.subject} t\\xE4ytyy olla \${adj}\${issue2.maximum.toString()} \${sizing.unit}\`.trim(); - } - return \`Liian suuri: arvon t\\xE4ytyy olla \${adj}\${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`Liian pieni: \${sizing.subject} t\\xE4ytyy olla \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`.trim(); - } - return \`Liian pieni: arvon t\\xE4ytyy olla \${adj}\${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") return \`Virheellinen sy\\xF6te: t\\xE4ytyy alkaa "\${_issue.prefix}"\`; - if (_issue.format === "ends_with") return \`Virheellinen sy\\xF6te: t\\xE4ytyy loppua "\${_issue.suffix}"\`; - if (_issue.format === "includes") return \`Virheellinen sy\\xF6te: t\\xE4ytyy sis\\xE4lt\\xE4\\xE4 "\${_issue.includes}"\`; - if (_issue.format === "regex") { - return \`Virheellinen sy\\xF6te: t\\xE4ytyy vastata s\\xE4\\xE4nn\\xF6llist\\xE4 lauseketta \${_issue.pattern}\`; - } - return \`Virheellinen \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`Virheellinen luku: t\\xE4ytyy olla luvun \${issue2.divisor} monikerta\`; - case "unrecognized_keys": - return \`\${issue2.keys.length > 1 ? "Tuntemattomat avaimet" : "Tuntematon avain"}: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return "Virheellinen avain tietueessa"; - case "invalid_union": - return "Virheellinen unioni"; - case "invalid_element": - return "Virheellinen arvo joukossa"; - default: - return \`Virheellinen sy\\xF6te\`; - } - }; -}, "error"); -function fi_default() { - return { - localeError: error12() - }; -} -__name(fi_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/fr.js -var error13 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "caract\\xE8res", - verb: "avoir" - }, - file: { - unit: "octets", - verb: "avoir" - }, - array: { - unit: "\\xE9l\\xE9ments", - verb: "avoir" - }, - set: { - unit: "\\xE9l\\xE9ments", - verb: "avoir" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "nombre"; - } - case "object": { - if (Array.isArray(data)) { - return "tableau"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "entr\\xE9e", - email: "adresse e-mail", - url: "URL", - emoji: "emoji", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "date et heure ISO", - date: "date ISO", - time: "heure ISO", - duration: "dur\\xE9e ISO", - ipv4: "adresse IPv4", - ipv6: "adresse IPv6", - cidrv4: "plage IPv4", - cidrv6: "plage IPv6", - base64: "cha\\xEEne encod\\xE9e en base64", - base64url: "cha\\xEEne encod\\xE9e en base64url", - json_string: "cha\\xEEne JSON", - e164: "num\\xE9ro E.164", - jwt: "JWT", - template_literal: "entr\\xE9e" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`Entr\\xE9e invalide : \${issue2.expected} attendu, \${parsedType7(issue2.input)} re\\xE7u\`; - case "invalid_value": - if (issue2.values.length === 1) return \`Entr\\xE9e invalide : \${stringifyPrimitive(issue2.values[0])} attendu\`; - return \`Option invalide : une valeur parmi \${joinValues(issue2.values, "|")} attendue\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`Trop grand : \${issue2.origin ?? "valeur"} doit \${sizing.verb} \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "\\xE9l\\xE9ment(s)"}\`; - return \`Trop grand : \${issue2.origin ?? "valeur"} doit \\xEAtre \${adj}\${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`Trop petit : \${issue2.origin} doit \${sizing.verb} \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; - } - return \`Trop petit : \${issue2.origin} doit \\xEAtre \${adj}\${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") return \`Cha\\xEEne invalide : doit commencer par "\${_issue.prefix}"\`; - if (_issue.format === "ends_with") return \`Cha\\xEEne invalide : doit se terminer par "\${_issue.suffix}"\`; - if (_issue.format === "includes") return \`Cha\\xEEne invalide : doit inclure "\${_issue.includes}"\`; - if (_issue.format === "regex") return \`Cha\\xEEne invalide : doit correspondre au mod\\xE8le \${_issue.pattern}\`; - return \`\${Nouns[_issue.format] ?? issue2.format} invalide\`; - } - case "not_multiple_of": - return \`Nombre invalide : doit \\xEAtre un multiple de \${issue2.divisor}\`; - case "unrecognized_keys": - return \`Cl\\xE9\${issue2.keys.length > 1 ? "s" : ""} non reconnue\${issue2.keys.length > 1 ? "s" : ""} : \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`Cl\\xE9 invalide dans \${issue2.origin}\`; - case "invalid_union": - return "Entr\\xE9e invalide"; - case "invalid_element": - return \`Valeur invalide dans \${issue2.origin}\`; - default: - return \`Entr\\xE9e invalide\`; - } - }; -}, "error"); -function fr_default() { - return { - localeError: error13() - }; -} -__name(fr_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/fr-CA.js -var error14 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "caract\\xE8res", - verb: "avoir" - }, - file: { - unit: "octets", - verb: "avoir" - }, - array: { - unit: "\\xE9l\\xE9ments", - verb: "avoir" - }, - set: { - unit: "\\xE9l\\xE9ments", - verb: "avoir" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "number"; - } - case "object": { - if (Array.isArray(data)) { - return "array"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "entr\\xE9e", - email: "adresse courriel", - url: "URL", - emoji: "emoji", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "date-heure ISO", - date: "date ISO", - time: "heure ISO", - duration: "dur\\xE9e ISO", - ipv4: "adresse IPv4", - ipv6: "adresse IPv6", - cidrv4: "plage IPv4", - cidrv6: "plage IPv6", - base64: "cha\\xEEne encod\\xE9e en base64", - base64url: "cha\\xEEne encod\\xE9e en base64url", - json_string: "cha\\xEEne JSON", - e164: "num\\xE9ro E.164", - jwt: "JWT", - template_literal: "entr\\xE9e" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`Entr\\xE9e invalide : attendu \${issue2.expected}, re\\xE7u \${parsedType7(issue2.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`Entr\\xE9e invalide : attendu \${stringifyPrimitive(issue2.values[0])}\`; - return \`Option invalide : attendu l'une des valeurs suivantes \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "\\u2264" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`Trop grand : attendu que \${issue2.origin ?? "la valeur"} ait \${adj}\${issue2.maximum.toString()} \${sizing.unit}\`; - return \`Trop grand : attendu que \${issue2.origin ?? "la valeur"} soit \${adj}\${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? "\\u2265" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`Trop petit : attendu que \${issue2.origin} ait \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; - } - return \`Trop petit : attendu que \${issue2.origin} soit \${adj}\${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") { - return \`Cha\\xEEne invalide : doit commencer par "\${_issue.prefix}"\`; - } - if (_issue.format === "ends_with") return \`Cha\\xEEne invalide : doit se terminer par "\${_issue.suffix}"\`; - if (_issue.format === "includes") return \`Cha\\xEEne invalide : doit inclure "\${_issue.includes}"\`; - if (_issue.format === "regex") return \`Cha\\xEEne invalide : doit correspondre au motif \${_issue.pattern}\`; - return \`\${Nouns[_issue.format] ?? issue2.format} invalide\`; - } - case "not_multiple_of": - return \`Nombre invalide : doit \\xEAtre un multiple de \${issue2.divisor}\`; - case "unrecognized_keys": - return \`Cl\\xE9\${issue2.keys.length > 1 ? "s" : ""} non reconnue\${issue2.keys.length > 1 ? "s" : ""} : \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`Cl\\xE9 invalide dans \${issue2.origin}\`; - case "invalid_union": - return "Entr\\xE9e invalide"; - case "invalid_element": - return \`Valeur invalide dans \${issue2.origin}\`; - default: - return \`Entr\\xE9e invalide\`; - } - }; -}, "error"); -function fr_CA_default() { - return { - localeError: error14() - }; -} -__name(fr_CA_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/he.js -var error15 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "\\u05D0\\u05D5\\u05EA\\u05D9\\u05D5\\u05EA", - verb: "\\u05DC\\u05DB\\u05DC\\u05D5\\u05DC" - }, - file: { - unit: "\\u05D1\\u05D9\\u05D9\\u05D8\\u05D9\\u05DD", - verb: "\\u05DC\\u05DB\\u05DC\\u05D5\\u05DC" - }, - array: { - unit: "\\u05E4\\u05E8\\u05D9\\u05D8\\u05D9\\u05DD", - verb: "\\u05DC\\u05DB\\u05DC\\u05D5\\u05DC" - }, - set: { - unit: "\\u05E4\\u05E8\\u05D9\\u05D8\\u05D9\\u05DD", - verb: "\\u05DC\\u05DB\\u05DC\\u05D5\\u05DC" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "number"; - } - case "object": { - if (Array.isArray(data)) { - return "array"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "\\u05E7\\u05DC\\u05D8", - email: "\\u05DB\\u05EA\\u05D5\\u05D1\\u05EA \\u05D0\\u05D9\\u05DE\\u05D9\\u05D9\\u05DC", - url: "\\u05DB\\u05EA\\u05D5\\u05D1\\u05EA \\u05E8\\u05E9\\u05EA", - emoji: "\\u05D0\\u05D9\\u05DE\\u05D5\\u05D2'\\u05D9", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "\\u05EA\\u05D0\\u05E8\\u05D9\\u05DA \\u05D5\\u05D6\\u05DE\\u05DF ISO", - date: "\\u05EA\\u05D0\\u05E8\\u05D9\\u05DA ISO", - time: "\\u05D6\\u05DE\\u05DF ISO", - duration: "\\u05DE\\u05E9\\u05DA \\u05D6\\u05DE\\u05DF ISO", - ipv4: "\\u05DB\\u05EA\\u05D5\\u05D1\\u05EA IPv4", - ipv6: "\\u05DB\\u05EA\\u05D5\\u05D1\\u05EA IPv6", - cidrv4: "\\u05D8\\u05D5\\u05D5\\u05D7 IPv4", - cidrv6: "\\u05D8\\u05D5\\u05D5\\u05D7 IPv6", - base64: "\\u05DE\\u05D7\\u05E8\\u05D5\\u05D6\\u05EA \\u05D1\\u05D1\\u05E1\\u05D9\\u05E1 64", - base64url: "\\u05DE\\u05D7\\u05E8\\u05D5\\u05D6\\u05EA \\u05D1\\u05D1\\u05E1\\u05D9\\u05E1 64 \\u05DC\\u05DB\\u05EA\\u05D5\\u05D1\\u05D5\\u05EA \\u05E8\\u05E9\\u05EA", - json_string: "\\u05DE\\u05D7\\u05E8\\u05D5\\u05D6\\u05EA JSON", - e164: "\\u05DE\\u05E1\\u05E4\\u05E8 E.164", - jwt: "JWT", - template_literal: "\\u05E7\\u05DC\\u05D8" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`\\u05E7\\u05DC\\u05D8 \\u05DC\\u05D0 \\u05EA\\u05E7\\u05D9\\u05DF: \\u05E6\\u05E8\\u05D9\\u05DA \${issue2.expected}, \\u05D4\\u05EA\\u05E7\\u05D1\\u05DC \${parsedType7(issue2.input)}\`; - // return \`Invalid input: expected \${issue.expected}, received \${util.getParsedType(issue.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`\\u05E7\\u05DC\\u05D8 \\u05DC\\u05D0 \\u05EA\\u05E7\\u05D9\\u05DF: \\u05E6\\u05E8\\u05D9\\u05DA \${stringifyPrimitive(issue2.values[0])}\`; - return \`\\u05E7\\u05DC\\u05D8 \\u05DC\\u05D0 \\u05EA\\u05E7\\u05D9\\u05DF: \\u05E6\\u05E8\\u05D9\\u05DA \\u05D0\\u05D7\\u05EA \\u05DE\\u05D4\\u05D0\\u05E4\\u05E9\\u05E8\\u05D5\\u05D9\\u05D5\\u05EA \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`\\u05D2\\u05D3\\u05D5\\u05DC \\u05DE\\u05D3\\u05D9: \${issue2.origin ?? "value"} \\u05E6\\u05E8\\u05D9\\u05DA \\u05DC\\u05D4\\u05D9\\u05D5\\u05EA \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "elements"}\`; - return \`\\u05D2\\u05D3\\u05D5\\u05DC \\u05DE\\u05D3\\u05D9: \${issue2.origin ?? "value"} \\u05E6\\u05E8\\u05D9\\u05DA \\u05DC\\u05D4\\u05D9\\u05D5\\u05EA \${adj}\${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`\\u05E7\\u05D8\\u05DF \\u05DE\\u05D3\\u05D9: \${issue2.origin} \\u05E6\\u05E8\\u05D9\\u05DA \\u05DC\\u05D4\\u05D9\\u05D5\\u05EA \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; - } - return \`\\u05E7\\u05D8\\u05DF \\u05DE\\u05D3\\u05D9: \${issue2.origin} \\u05E6\\u05E8\\u05D9\\u05DA \\u05DC\\u05D4\\u05D9\\u05D5\\u05EA \${adj}\${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") return \`\\u05DE\\u05D7\\u05E8\\u05D5\\u05D6\\u05EA \\u05DC\\u05D0 \\u05EA\\u05E7\\u05D9\\u05E0\\u05D4: \\u05D7\\u05D9\\u05D9\\u05D1\\u05EA \\u05DC\\u05D4\\u05EA\\u05D7\\u05D9\\u05DC \\u05D1"\${_issue.prefix}"\`; - if (_issue.format === "ends_with") return \`\\u05DE\\u05D7\\u05E8\\u05D5\\u05D6\\u05EA \\u05DC\\u05D0 \\u05EA\\u05E7\\u05D9\\u05E0\\u05D4: \\u05D7\\u05D9\\u05D9\\u05D1\\u05EA \\u05DC\\u05D4\\u05E1\\u05EA\\u05D9\\u05D9\\u05DD \\u05D1 "\${_issue.suffix}"\`; - if (_issue.format === "includes") return \`\\u05DE\\u05D7\\u05E8\\u05D5\\u05D6\\u05EA \\u05DC\\u05D0 \\u05EA\\u05E7\\u05D9\\u05E0\\u05D4: \\u05D7\\u05D9\\u05D9\\u05D1\\u05EA \\u05DC\\u05DB\\u05DC\\u05D5\\u05DC "\${_issue.includes}"\`; - if (_issue.format === "regex") return \`\\u05DE\\u05D7\\u05E8\\u05D5\\u05D6\\u05EA \\u05DC\\u05D0 \\u05EA\\u05E7\\u05D9\\u05E0\\u05D4: \\u05D7\\u05D9\\u05D9\\u05D1\\u05EA \\u05DC\\u05D4\\u05EA\\u05D0\\u05D9\\u05DD \\u05DC\\u05EA\\u05D1\\u05E0\\u05D9\\u05EA \${_issue.pattern}\`; - return \`\${Nouns[_issue.format] ?? issue2.format} \\u05DC\\u05D0 \\u05EA\\u05E7\\u05D9\\u05DF\`; - } - case "not_multiple_of": - return \`\\u05DE\\u05E1\\u05E4\\u05E8 \\u05DC\\u05D0 \\u05EA\\u05E7\\u05D9\\u05DF: \\u05D7\\u05D9\\u05D9\\u05D1 \\u05DC\\u05D4\\u05D9\\u05D5\\u05EA \\u05DE\\u05DB\\u05E4\\u05DC\\u05D4 \\u05E9\\u05DC \${issue2.divisor}\`; - case "unrecognized_keys": - return \`\\u05DE\\u05E4\\u05EA\\u05D7\${issue2.keys.length > 1 ? "\\u05D5\\u05EA" : ""} \\u05DC\\u05D0 \\u05DE\\u05D6\\u05D5\\u05D4\${issue2.keys.length > 1 ? "\\u05D9\\u05DD" : "\\u05D4"}: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`\\u05DE\\u05E4\\u05EA\\u05D7 \\u05DC\\u05D0 \\u05EA\\u05E7\\u05D9\\u05DF \\u05D1\${issue2.origin}\`; - case "invalid_union": - return "\\u05E7\\u05DC\\u05D8 \\u05DC\\u05D0 \\u05EA\\u05E7\\u05D9\\u05DF"; - case "invalid_element": - return \`\\u05E2\\u05E8\\u05DA \\u05DC\\u05D0 \\u05EA\\u05E7\\u05D9\\u05DF \\u05D1\${issue2.origin}\`; - default: - return \`\\u05E7\\u05DC\\u05D8 \\u05DC\\u05D0 \\u05EA\\u05E7\\u05D9\\u05DF\`; - } - }; -}, "error"); -function he_default() { - return { - localeError: error15() - }; -} -__name(he_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/hu.js -var error16 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "karakter", - verb: "legyen" - }, - file: { - unit: "byte", - verb: "legyen" - }, - array: { - unit: "elem", - verb: "legyen" - }, - set: { - unit: "elem", - verb: "legyen" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "sz\\xE1m"; - } - case "object": { - if (Array.isArray(data)) { - return "t\\xF6mb"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "bemenet", - email: "email c\\xEDm", - url: "URL", - emoji: "emoji", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "ISO id\\u0151b\\xE9lyeg", - date: "ISO d\\xE1tum", - time: "ISO id\\u0151", - duration: "ISO id\\u0151intervallum", - ipv4: "IPv4 c\\xEDm", - ipv6: "IPv6 c\\xEDm", - cidrv4: "IPv4 tartom\\xE1ny", - cidrv6: "IPv6 tartom\\xE1ny", - base64: "base64-k\\xF3dolt string", - base64url: "base64url-k\\xF3dolt string", - json_string: "JSON string", - e164: "E.164 sz\\xE1m", - jwt: "JWT", - template_literal: "bemenet" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`\\xC9rv\\xE9nytelen bemenet: a v\\xE1rt \\xE9rt\\xE9k \${issue2.expected}, a kapott \\xE9rt\\xE9k \${parsedType7(issue2.input)}\`; - // return \`Invalid input: expected \${issue.expected}, received \${util.getParsedType(issue.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`\\xC9rv\\xE9nytelen bemenet: a v\\xE1rt \\xE9rt\\xE9k \${stringifyPrimitive(issue2.values[0])}\`; - return \`\\xC9rv\\xE9nytelen opci\\xF3: valamelyik \\xE9rt\\xE9k v\\xE1rt \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`T\\xFAl nagy: \${issue2.origin ?? "\\xE9rt\\xE9k"} m\\xE9rete t\\xFAl nagy \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "elem"}\`; - return \`T\\xFAl nagy: a bemeneti \\xE9rt\\xE9k \${issue2.origin ?? "\\xE9rt\\xE9k"} t\\xFAl nagy: \${adj}\${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`T\\xFAl kicsi: a bemeneti \\xE9rt\\xE9k \${issue2.origin} m\\xE9rete t\\xFAl kicsi \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; - } - return \`T\\xFAl kicsi: a bemeneti \\xE9rt\\xE9k \${issue2.origin} t\\xFAl kicsi \${adj}\${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") return \`\\xC9rv\\xE9nytelen string: "\${_issue.prefix}" \\xE9rt\\xE9kkel kell kezd\\u0151dnie\`; - if (_issue.format === "ends_with") return \`\\xC9rv\\xE9nytelen string: "\${_issue.suffix}" \\xE9rt\\xE9kkel kell v\\xE9gz\\u0151dnie\`; - if (_issue.format === "includes") return \`\\xC9rv\\xE9nytelen string: "\${_issue.includes}" \\xE9rt\\xE9ket kell tartalmaznia\`; - if (_issue.format === "regex") return \`\\xC9rv\\xE9nytelen string: \${_issue.pattern} mint\\xE1nak kell megfelelnie\`; - return \`\\xC9rv\\xE9nytelen \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`\\xC9rv\\xE9nytelen sz\\xE1m: \${issue2.divisor} t\\xF6bbsz\\xF6r\\xF6s\\xE9nek kell lennie\`; - case "unrecognized_keys": - return \`Ismeretlen kulcs\${issue2.keys.length > 1 ? "s" : ""}: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`\\xC9rv\\xE9nytelen kulcs \${issue2.origin}\`; - case "invalid_union": - return "\\xC9rv\\xE9nytelen bemenet"; - case "invalid_element": - return \`\\xC9rv\\xE9nytelen \\xE9rt\\xE9k: \${issue2.origin}\`; - default: - return \`\\xC9rv\\xE9nytelen bemenet\`; - } - }; -}, "error"); -function hu_default() { - return { - localeError: error16() - }; -} -__name(hu_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/id.js -var error17 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "karakter", - verb: "memiliki" - }, - file: { - unit: "byte", - verb: "memiliki" - }, - array: { - unit: "item", - verb: "memiliki" - }, - set: { - unit: "item", - verb: "memiliki" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "number"; - } - case "object": { - if (Array.isArray(data)) { - return "array"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "input", - email: "alamat email", - url: "URL", - emoji: "emoji", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "tanggal dan waktu format ISO", - date: "tanggal format ISO", - time: "jam format ISO", - duration: "durasi format ISO", - ipv4: "alamat IPv4", - ipv6: "alamat IPv6", - cidrv4: "rentang alamat IPv4", - cidrv6: "rentang alamat IPv6", - base64: "string dengan enkode base64", - base64url: "string dengan enkode base64url", - json_string: "string JSON", - e164: "angka E.164", - jwt: "JWT", - template_literal: "input" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`Input tidak valid: diharapkan \${issue2.expected}, diterima \${parsedType7(issue2.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`Input tidak valid: diharapkan \${stringifyPrimitive(issue2.values[0])}\`; - return \`Pilihan tidak valid: diharapkan salah satu dari \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`Terlalu besar: diharapkan \${issue2.origin ?? "value"} memiliki \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "elemen"}\`; - return \`Terlalu besar: diharapkan \${issue2.origin ?? "value"} menjadi \${adj}\${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`Terlalu kecil: diharapkan \${issue2.origin} memiliki \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; - } - return \`Terlalu kecil: diharapkan \${issue2.origin} menjadi \${adj}\${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") return \`String tidak valid: harus dimulai dengan "\${_issue.prefix}"\`; - if (_issue.format === "ends_with") return \`String tidak valid: harus berakhir dengan "\${_issue.suffix}"\`; - if (_issue.format === "includes") return \`String tidak valid: harus menyertakan "\${_issue.includes}"\`; - if (_issue.format === "regex") return \`String tidak valid: harus sesuai pola \${_issue.pattern}\`; - return \`\${Nouns[_issue.format] ?? issue2.format} tidak valid\`; - } - case "not_multiple_of": - return \`Angka tidak valid: harus kelipatan dari \${issue2.divisor}\`; - case "unrecognized_keys": - return \`Kunci tidak dikenali \${issue2.keys.length > 1 ? "s" : ""}: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`Kunci tidak valid di \${issue2.origin}\`; - case "invalid_union": - return "Input tidak valid"; - case "invalid_element": - return \`Nilai tidak valid di \${issue2.origin}\`; - default: - return \`Input tidak valid\`; - } - }; -}, "error"); -function id_default() { - return { - localeError: error17() - }; -} -__name(id_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/is.js -var parsedType3 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "n\\xFAmer"; - } - case "object": { - if (Array.isArray(data)) { - return "fylki"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; -}, "parsedType"); -var error18 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "stafi", - verb: "a\\xF0 hafa" - }, - file: { - unit: "b\\xE6ti", - verb: "a\\xF0 hafa" - }, - array: { - unit: "hluti", - verb: "a\\xF0 hafa" - }, - set: { - unit: "hluti", - verb: "a\\xF0 hafa" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const Nouns = { - regex: "gildi", - email: "netfang", - url: "vefsl\\xF3\\xF0", - emoji: "emoji", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "ISO dagsetning og t\\xEDmi", - date: "ISO dagsetning", - time: "ISO t\\xEDmi", - duration: "ISO t\\xEDmalengd", - ipv4: "IPv4 address", - ipv6: "IPv6 address", - cidrv4: "IPv4 range", - cidrv6: "IPv6 range", - base64: "base64-encoded strengur", - base64url: "base64url-encoded strengur", - json_string: "JSON strengur", - e164: "E.164 t\\xF6lugildi", - jwt: "JWT", - template_literal: "gildi" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`Rangt gildi: \\xDE\\xFA sl\\xF3st inn \${parsedType3(issue2.input)} \\xFEar sem \\xE1 a\\xF0 vera \${issue2.expected}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`Rangt gildi: gert r\\xE1\\xF0 fyrir \${stringifyPrimitive(issue2.values[0])}\`; - return \`\\xD3gilt val: m\\xE1 vera eitt af eftirfarandi \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`Of st\\xF3rt: gert er r\\xE1\\xF0 fyrir a\\xF0 \${issue2.origin ?? "gildi"} hafi \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "hluti"}\`; - return \`Of st\\xF3rt: gert er r\\xE1\\xF0 fyrir a\\xF0 \${issue2.origin ?? "gildi"} s\\xE9 \${adj}\${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`Of l\\xEDti\\xF0: gert er r\\xE1\\xF0 fyrir a\\xF0 \${issue2.origin} hafi \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; - } - return \`Of l\\xEDti\\xF0: gert er r\\xE1\\xF0 fyrir a\\xF0 \${issue2.origin} s\\xE9 \${adj}\${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") { - return \`\\xD3gildur strengur: ver\\xF0ur a\\xF0 byrja \\xE1 "\${_issue.prefix}"\`; - } - if (_issue.format === "ends_with") return \`\\xD3gildur strengur: ver\\xF0ur a\\xF0 enda \\xE1 "\${_issue.suffix}"\`; - if (_issue.format === "includes") return \`\\xD3gildur strengur: ver\\xF0ur a\\xF0 innihalda "\${_issue.includes}"\`; - if (_issue.format === "regex") return \`\\xD3gildur strengur: ver\\xF0ur a\\xF0 fylgja mynstri \${_issue.pattern}\`; - return \`Rangt \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`R\\xF6ng tala: ver\\xF0ur a\\xF0 vera margfeldi af \${issue2.divisor}\`; - case "unrecognized_keys": - return \`\\xD3\\xFEekkt \${issue2.keys.length > 1 ? "ir lyklar" : "ur lykill"}: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`Rangur lykill \\xED \${issue2.origin}\`; - case "invalid_union": - return "Rangt gildi"; - case "invalid_element": - return \`Rangt gildi \\xED \${issue2.origin}\`; - default: - return \`Rangt gildi\`; - } - }; -}, "error"); -function is_default() { - return { - localeError: error18() - }; -} -__name(is_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/it.js -var error19 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "caratteri", - verb: "avere" - }, - file: { - unit: "byte", - verb: "avere" - }, - array: { - unit: "elementi", - verb: "avere" - }, - set: { - unit: "elementi", - verb: "avere" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "numero"; - } - case "object": { - if (Array.isArray(data)) { - return "vettore"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "input", - email: "indirizzo email", - url: "URL", - emoji: "emoji", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "data e ora ISO", - date: "data ISO", - time: "ora ISO", - duration: "durata ISO", - ipv4: "indirizzo IPv4", - ipv6: "indirizzo IPv6", - cidrv4: "intervallo IPv4", - cidrv6: "intervallo IPv6", - base64: "stringa codificata in base64", - base64url: "URL codificata in base64", - json_string: "stringa JSON", - e164: "numero E.164", - jwt: "JWT", - template_literal: "input" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`Input non valido: atteso \${issue2.expected}, ricevuto \${parsedType7(issue2.input)}\`; - // return \`Input non valido: atteso \${issue.expected}, ricevuto \${util.getParsedType(issue.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`Input non valido: atteso \${stringifyPrimitive(issue2.values[0])}\`; - return \`Opzione non valida: atteso uno tra \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`Troppo grande: \${issue2.origin ?? "valore"} deve avere \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "elementi"}\`; - return \`Troppo grande: \${issue2.origin ?? "valore"} deve essere \${adj}\${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`Troppo piccolo: \${issue2.origin} deve avere \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; - } - return \`Troppo piccolo: \${issue2.origin} deve essere \${adj}\${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") return \`Stringa non valida: deve iniziare con "\${_issue.prefix}"\`; - if (_issue.format === "ends_with") return \`Stringa non valida: deve terminare con "\${_issue.suffix}"\`; - if (_issue.format === "includes") return \`Stringa non valida: deve includere "\${_issue.includes}"\`; - if (_issue.format === "regex") return \`Stringa non valida: deve corrispondere al pattern \${_issue.pattern}\`; - return \`Invalid \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`Numero non valido: deve essere un multiplo di \${issue2.divisor}\`; - case "unrecognized_keys": - return \`Chiav\${issue2.keys.length > 1 ? "i" : "e"} non riconosciut\${issue2.keys.length > 1 ? "e" : "a"}: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`Chiave non valida in \${issue2.origin}\`; - case "invalid_union": - return "Input non valido"; - case "invalid_element": - return \`Valore non valido in \${issue2.origin}\`; - default: - return \`Input non valido\`; - } - }; -}, "error"); -function it_default() { - return { - localeError: error19() - }; -} -__name(it_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/ja.js -var error20 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "\\u6587\\u5B57", - verb: "\\u3067\\u3042\\u308B" - }, - file: { - unit: "\\u30D0\\u30A4\\u30C8", - verb: "\\u3067\\u3042\\u308B" - }, - array: { - unit: "\\u8981\\u7D20", - verb: "\\u3067\\u3042\\u308B" - }, - set: { - unit: "\\u8981\\u7D20", - verb: "\\u3067\\u3042\\u308B" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "\\u6570\\u5024"; - } - case "object": { - if (Array.isArray(data)) { - return "\\u914D\\u5217"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "\\u5165\\u529B\\u5024", - email: "\\u30E1\\u30FC\\u30EB\\u30A2\\u30C9\\u30EC\\u30B9", - url: "URL", - emoji: "\\u7D75\\u6587\\u5B57", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "ISO\\u65E5\\u6642", - date: "ISO\\u65E5\\u4ED8", - time: "ISO\\u6642\\u523B", - duration: "ISO\\u671F\\u9593", - ipv4: "IPv4\\u30A2\\u30C9\\u30EC\\u30B9", - ipv6: "IPv6\\u30A2\\u30C9\\u30EC\\u30B9", - cidrv4: "IPv4\\u7BC4\\u56F2", - cidrv6: "IPv6\\u7BC4\\u56F2", - base64: "base64\\u30A8\\u30F3\\u30B3\\u30FC\\u30C9\\u6587\\u5B57\\u5217", - base64url: "base64url\\u30A8\\u30F3\\u30B3\\u30FC\\u30C9\\u6587\\u5B57\\u5217", - json_string: "JSON\\u6587\\u5B57\\u5217", - e164: "E.164\\u756A\\u53F7", - jwt: "JWT", - template_literal: "\\u5165\\u529B\\u5024" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`\\u7121\\u52B9\\u306A\\u5165\\u529B: \${issue2.expected}\\u304C\\u671F\\u5F85\\u3055\\u308C\\u307E\\u3057\\u305F\\u304C\\u3001\${parsedType7(issue2.input)}\\u304C\\u5165\\u529B\\u3055\\u308C\\u307E\\u3057\\u305F\`; - case "invalid_value": - if (issue2.values.length === 1) return \`\\u7121\\u52B9\\u306A\\u5165\\u529B: \${stringifyPrimitive(issue2.values[0])}\\u304C\\u671F\\u5F85\\u3055\\u308C\\u307E\\u3057\\u305F\`; - return \`\\u7121\\u52B9\\u306A\\u9078\\u629E: \${joinValues(issue2.values, "\\u3001")}\\u306E\\u3044\\u305A\\u308C\\u304B\\u3067\\u3042\\u308B\\u5FC5\\u8981\\u304C\\u3042\\u308A\\u307E\\u3059\`; - case "too_big": { - const adj = issue2.inclusive ? "\\u4EE5\\u4E0B\\u3067\\u3042\\u308B" : "\\u3088\\u308A\\u5C0F\\u3055\\u3044"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`\\u5927\\u304D\\u3059\\u304E\\u308B\\u5024: \${issue2.origin ?? "\\u5024"}\\u306F\${issue2.maximum.toString()}\${sizing.unit ?? "\\u8981\\u7D20"}\${adj}\\u5FC5\\u8981\\u304C\\u3042\\u308A\\u307E\\u3059\`; - return \`\\u5927\\u304D\\u3059\\u304E\\u308B\\u5024: \${issue2.origin ?? "\\u5024"}\\u306F\${issue2.maximum.toString()}\${adj}\\u5FC5\\u8981\\u304C\\u3042\\u308A\\u307E\\u3059\`; - } - case "too_small": { - const adj = issue2.inclusive ? "\\u4EE5\\u4E0A\\u3067\\u3042\\u308B" : "\\u3088\\u308A\\u5927\\u304D\\u3044"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`\\u5C0F\\u3055\\u3059\\u304E\\u308B\\u5024: \${issue2.origin}\\u306F\${issue2.minimum.toString()}\${sizing.unit}\${adj}\\u5FC5\\u8981\\u304C\\u3042\\u308A\\u307E\\u3059\`; - return \`\\u5C0F\\u3055\\u3059\\u304E\\u308B\\u5024: \${issue2.origin}\\u306F\${issue2.minimum.toString()}\${adj}\\u5FC5\\u8981\\u304C\\u3042\\u308A\\u307E\\u3059\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") return \`\\u7121\\u52B9\\u306A\\u6587\\u5B57\\u5217: "\${_issue.prefix}"\\u3067\\u59CB\\u307E\\u308B\\u5FC5\\u8981\\u304C\\u3042\\u308A\\u307E\\u3059\`; - if (_issue.format === "ends_with") return \`\\u7121\\u52B9\\u306A\\u6587\\u5B57\\u5217: "\${_issue.suffix}"\\u3067\\u7D42\\u308F\\u308B\\u5FC5\\u8981\\u304C\\u3042\\u308A\\u307E\\u3059\`; - if (_issue.format === "includes") return \`\\u7121\\u52B9\\u306A\\u6587\\u5B57\\u5217: "\${_issue.includes}"\\u3092\\u542B\\u3080\\u5FC5\\u8981\\u304C\\u3042\\u308A\\u307E\\u3059\`; - if (_issue.format === "regex") return \`\\u7121\\u52B9\\u306A\\u6587\\u5B57\\u5217: \\u30D1\\u30BF\\u30FC\\u30F3\${_issue.pattern}\\u306B\\u4E00\\u81F4\\u3059\\u308B\\u5FC5\\u8981\\u304C\\u3042\\u308A\\u307E\\u3059\`; - return \`\\u7121\\u52B9\\u306A\${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`\\u7121\\u52B9\\u306A\\u6570\\u5024: \${issue2.divisor}\\u306E\\u500D\\u6570\\u3067\\u3042\\u308B\\u5FC5\\u8981\\u304C\\u3042\\u308A\\u307E\\u3059\`; - case "unrecognized_keys": - return \`\\u8A8D\\u8B58\\u3055\\u308C\\u3066\\u3044\\u306A\\u3044\\u30AD\\u30FC\${issue2.keys.length > 1 ? "\\u7FA4" : ""}: \${joinValues(issue2.keys, "\\u3001")}\`; - case "invalid_key": - return \`\${issue2.origin}\\u5185\\u306E\\u7121\\u52B9\\u306A\\u30AD\\u30FC\`; - case "invalid_union": - return "\\u7121\\u52B9\\u306A\\u5165\\u529B"; - case "invalid_element": - return \`\${issue2.origin}\\u5185\\u306E\\u7121\\u52B9\\u306A\\u5024\`; - default: - return \`\\u7121\\u52B9\\u306A\\u5165\\u529B\`; - } - }; -}, "error"); -function ja_default() { - return { - localeError: error20() - }; -} -__name(ja_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/ka.js -var parsedType4 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "\\u10E0\\u10D8\\u10EA\\u10EE\\u10D5\\u10D8"; - } - case "object": { - if (Array.isArray(data)) { - return "\\u10DB\\u10D0\\u10E1\\u10D8\\u10D5\\u10D8"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - const typeMap = { - string: "\\u10E1\\u10E2\\u10E0\\u10D8\\u10DC\\u10D2\\u10D8", - boolean: "\\u10D1\\u10E3\\u10DA\\u10D4\\u10D0\\u10DC\\u10D8", - undefined: "undefined", - bigint: "bigint", - symbol: "symbol", - function: "\\u10E4\\u10E3\\u10DC\\u10E5\\u10EA\\u10D8\\u10D0" - }; - return typeMap[t] ?? t; -}, "parsedType"); -var error21 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "\\u10E1\\u10D8\\u10DB\\u10D1\\u10DD\\u10DA\\u10DD", - verb: "\\u10E3\\u10DC\\u10D3\\u10D0 \\u10E8\\u10D4\\u10D8\\u10EA\\u10D0\\u10D5\\u10D3\\u10D4\\u10E1" - }, - file: { - unit: "\\u10D1\\u10D0\\u10D8\\u10E2\\u10D8", - verb: "\\u10E3\\u10DC\\u10D3\\u10D0 \\u10E8\\u10D4\\u10D8\\u10EA\\u10D0\\u10D5\\u10D3\\u10D4\\u10E1" - }, - array: { - unit: "\\u10D4\\u10DA\\u10D4\\u10DB\\u10D4\\u10DC\\u10E2\\u10D8", - verb: "\\u10E3\\u10DC\\u10D3\\u10D0 \\u10E8\\u10D4\\u10D8\\u10EA\\u10D0\\u10D5\\u10D3\\u10D4\\u10E1" - }, - set: { - unit: "\\u10D4\\u10DA\\u10D4\\u10DB\\u10D4\\u10DC\\u10E2\\u10D8", - verb: "\\u10E3\\u10DC\\u10D3\\u10D0 \\u10E8\\u10D4\\u10D8\\u10EA\\u10D0\\u10D5\\u10D3\\u10D4\\u10E1" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const Nouns = { - regex: "\\u10E8\\u10D4\\u10E7\\u10D5\\u10D0\\u10DC\\u10D0", - email: "\\u10D4\\u10DA-\\u10E4\\u10DD\\u10E1\\u10E2\\u10D8\\u10E1 \\u10DB\\u10D8\\u10E1\\u10D0\\u10DB\\u10D0\\u10E0\\u10D7\\u10D8", - url: "URL", - emoji: "\\u10D4\\u10DB\\u10DD\\u10EF\\u10D8", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "\\u10D7\\u10D0\\u10E0\\u10D8\\u10E6\\u10D8-\\u10D3\\u10E0\\u10DD", - date: "\\u10D7\\u10D0\\u10E0\\u10D8\\u10E6\\u10D8", - time: "\\u10D3\\u10E0\\u10DD", - duration: "\\u10EE\\u10D0\\u10DC\\u10D2\\u10E0\\u10EB\\u10DA\\u10D8\\u10D5\\u10DD\\u10D1\\u10D0", - ipv4: "IPv4 \\u10DB\\u10D8\\u10E1\\u10D0\\u10DB\\u10D0\\u10E0\\u10D7\\u10D8", - ipv6: "IPv6 \\u10DB\\u10D8\\u10E1\\u10D0\\u10DB\\u10D0\\u10E0\\u10D7\\u10D8", - cidrv4: "IPv4 \\u10D3\\u10D8\\u10D0\\u10DE\\u10D0\\u10D6\\u10DD\\u10DC\\u10D8", - cidrv6: "IPv6 \\u10D3\\u10D8\\u10D0\\u10DE\\u10D0\\u10D6\\u10DD\\u10DC\\u10D8", - base64: "base64-\\u10D9\\u10DD\\u10D3\\u10D8\\u10E0\\u10D4\\u10D1\\u10E3\\u10DA\\u10D8 \\u10E1\\u10E2\\u10E0\\u10D8\\u10DC\\u10D2\\u10D8", - base64url: "base64url-\\u10D9\\u10DD\\u10D3\\u10D8\\u10E0\\u10D4\\u10D1\\u10E3\\u10DA\\u10D8 \\u10E1\\u10E2\\u10E0\\u10D8\\u10DC\\u10D2\\u10D8", - json_string: "JSON \\u10E1\\u10E2\\u10E0\\u10D8\\u10DC\\u10D2\\u10D8", - e164: "E.164 \\u10DC\\u10DD\\u10DB\\u10D4\\u10E0\\u10D8", - jwt: "JWT", - template_literal: "\\u10E8\\u10D4\\u10E7\\u10D5\\u10D0\\u10DC\\u10D0" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`\\u10D0\\u10E0\\u10D0\\u10E1\\u10EC\\u10DD\\u10E0\\u10D8 \\u10E8\\u10D4\\u10E7\\u10D5\\u10D0\\u10DC\\u10D0: \\u10DB\\u10DD\\u10E1\\u10D0\\u10DA\\u10DD\\u10D3\\u10DC\\u10D4\\u10DA\\u10D8 \${issue2.expected}, \\u10DB\\u10D8\\u10E6\\u10D4\\u10D1\\u10E3\\u10DA\\u10D8 \${parsedType4(issue2.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`\\u10D0\\u10E0\\u10D0\\u10E1\\u10EC\\u10DD\\u10E0\\u10D8 \\u10E8\\u10D4\\u10E7\\u10D5\\u10D0\\u10DC\\u10D0: \\u10DB\\u10DD\\u10E1\\u10D0\\u10DA\\u10DD\\u10D3\\u10DC\\u10D4\\u10DA\\u10D8 \${stringifyPrimitive(issue2.values[0])}\`; - return \`\\u10D0\\u10E0\\u10D0\\u10E1\\u10EC\\u10DD\\u10E0\\u10D8 \\u10D5\\u10D0\\u10E0\\u10D8\\u10D0\\u10DC\\u10E2\\u10D8: \\u10DB\\u10DD\\u10E1\\u10D0\\u10DA\\u10DD\\u10D3\\u10DC\\u10D4\\u10DA\\u10D8\\u10D0 \\u10D4\\u10E0\\u10D7-\\u10D4\\u10E0\\u10D7\\u10D8 \${joinValues(issue2.values, "|")}-\\u10D3\\u10D0\\u10DC\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`\\u10D6\\u10D4\\u10D3\\u10DB\\u10D4\\u10E2\\u10D0\\u10D3 \\u10D3\\u10D8\\u10D3\\u10D8: \\u10DB\\u10DD\\u10E1\\u10D0\\u10DA\\u10DD\\u10D3\\u10DC\\u10D4\\u10DA\\u10D8 \${issue2.origin ?? "\\u10DB\\u10DC\\u10D8\\u10E8\\u10D5\\u10DC\\u10D4\\u10DA\\u10DD\\u10D1\\u10D0"} \${sizing.verb} \${adj}\${issue2.maximum.toString()} \${sizing.unit}\`; - return \`\\u10D6\\u10D4\\u10D3\\u10DB\\u10D4\\u10E2\\u10D0\\u10D3 \\u10D3\\u10D8\\u10D3\\u10D8: \\u10DB\\u10DD\\u10E1\\u10D0\\u10DA\\u10DD\\u10D3\\u10DC\\u10D4\\u10DA\\u10D8 \${issue2.origin ?? "\\u10DB\\u10DC\\u10D8\\u10E8\\u10D5\\u10DC\\u10D4\\u10DA\\u10DD\\u10D1\\u10D0"} \\u10D8\\u10E7\\u10DD\\u10E1 \${adj}\${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`\\u10D6\\u10D4\\u10D3\\u10DB\\u10D4\\u10E2\\u10D0\\u10D3 \\u10DE\\u10D0\\u10E2\\u10D0\\u10E0\\u10D0: \\u10DB\\u10DD\\u10E1\\u10D0\\u10DA\\u10DD\\u10D3\\u10DC\\u10D4\\u10DA\\u10D8 \${issue2.origin} \${sizing.verb} \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; - } - return \`\\u10D6\\u10D4\\u10D3\\u10DB\\u10D4\\u10E2\\u10D0\\u10D3 \\u10DE\\u10D0\\u10E2\\u10D0\\u10E0\\u10D0: \\u10DB\\u10DD\\u10E1\\u10D0\\u10DA\\u10DD\\u10D3\\u10DC\\u10D4\\u10DA\\u10D8 \${issue2.origin} \\u10D8\\u10E7\\u10DD\\u10E1 \${adj}\${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") { - return \`\\u10D0\\u10E0\\u10D0\\u10E1\\u10EC\\u10DD\\u10E0\\u10D8 \\u10E1\\u10E2\\u10E0\\u10D8\\u10DC\\u10D2\\u10D8: \\u10E3\\u10DC\\u10D3\\u10D0 \\u10D8\\u10EC\\u10E7\\u10D4\\u10D1\\u10DD\\u10D3\\u10D4\\u10E1 "\${_issue.prefix}"-\\u10D8\\u10D7\`; - } - if (_issue.format === "ends_with") return \`\\u10D0\\u10E0\\u10D0\\u10E1\\u10EC\\u10DD\\u10E0\\u10D8 \\u10E1\\u10E2\\u10E0\\u10D8\\u10DC\\u10D2\\u10D8: \\u10E3\\u10DC\\u10D3\\u10D0 \\u10DB\\u10D7\\u10D0\\u10D5\\u10E0\\u10D3\\u10D4\\u10D1\\u10DD\\u10D3\\u10D4\\u10E1 "\${_issue.suffix}"-\\u10D8\\u10D7\`; - if (_issue.format === "includes") return \`\\u10D0\\u10E0\\u10D0\\u10E1\\u10EC\\u10DD\\u10E0\\u10D8 \\u10E1\\u10E2\\u10E0\\u10D8\\u10DC\\u10D2\\u10D8: \\u10E3\\u10DC\\u10D3\\u10D0 \\u10E8\\u10D4\\u10D8\\u10EA\\u10D0\\u10D5\\u10D3\\u10D4\\u10E1 "\${_issue.includes}"-\\u10E1\`; - if (_issue.format === "regex") return \`\\u10D0\\u10E0\\u10D0\\u10E1\\u10EC\\u10DD\\u10E0\\u10D8 \\u10E1\\u10E2\\u10E0\\u10D8\\u10DC\\u10D2\\u10D8: \\u10E3\\u10DC\\u10D3\\u10D0 \\u10E8\\u10D4\\u10D4\\u10E1\\u10D0\\u10D1\\u10D0\\u10DB\\u10D4\\u10D1\\u10DD\\u10D3\\u10D4\\u10E1 \\u10E8\\u10D0\\u10D1\\u10DA\\u10DD\\u10DC\\u10E1 \${_issue.pattern}\`; - return \`\\u10D0\\u10E0\\u10D0\\u10E1\\u10EC\\u10DD\\u10E0\\u10D8 \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`\\u10D0\\u10E0\\u10D0\\u10E1\\u10EC\\u10DD\\u10E0\\u10D8 \\u10E0\\u10D8\\u10EA\\u10EE\\u10D5\\u10D8: \\u10E3\\u10DC\\u10D3\\u10D0 \\u10D8\\u10E7\\u10DD\\u10E1 \${issue2.divisor}-\\u10D8\\u10E1 \\u10EF\\u10D4\\u10E0\\u10D0\\u10D3\\u10D8\`; - case "unrecognized_keys": - return \`\\u10E3\\u10EA\\u10DC\\u10DD\\u10D1\\u10D8 \\u10D2\\u10D0\\u10E1\\u10D0\\u10E6\\u10D4\\u10D1\${issue2.keys.length > 1 ? "\\u10D4\\u10D1\\u10D8" : "\\u10D8"}: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`\\u10D0\\u10E0\\u10D0\\u10E1\\u10EC\\u10DD\\u10E0\\u10D8 \\u10D2\\u10D0\\u10E1\\u10D0\\u10E6\\u10D4\\u10D1\\u10D8 \${issue2.origin}-\\u10E8\\u10D8\`; - case "invalid_union": - return "\\u10D0\\u10E0\\u10D0\\u10E1\\u10EC\\u10DD\\u10E0\\u10D8 \\u10E8\\u10D4\\u10E7\\u10D5\\u10D0\\u10DC\\u10D0"; - case "invalid_element": - return \`\\u10D0\\u10E0\\u10D0\\u10E1\\u10EC\\u10DD\\u10E0\\u10D8 \\u10DB\\u10DC\\u10D8\\u10E8\\u10D5\\u10DC\\u10D4\\u10DA\\u10DD\\u10D1\\u10D0 \${issue2.origin}-\\u10E8\\u10D8\`; - default: - return \`\\u10D0\\u10E0\\u10D0\\u10E1\\u10EC\\u10DD\\u10E0\\u10D8 \\u10E8\\u10D4\\u10E7\\u10D5\\u10D0\\u10DC\\u10D0\`; - } - }; -}, "error"); -function ka_default() { - return { - localeError: error21() - }; -} -__name(ka_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/km.js -var error22 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "\\u178F\\u17BD\\u17A2\\u1780\\u17D2\\u179F\\u179A", - verb: "\\u1782\\u17BD\\u179A\\u1798\\u17B6\\u1793" - }, - file: { - unit: "\\u1794\\u17C3", - verb: "\\u1782\\u17BD\\u179A\\u1798\\u17B6\\u1793" - }, - array: { - unit: "\\u1792\\u17B6\\u178F\\u17BB", - verb: "\\u1782\\u17BD\\u179A\\u1798\\u17B6\\u1793" - }, - set: { - unit: "\\u1792\\u17B6\\u178F\\u17BB", - verb: "\\u1782\\u17BD\\u179A\\u1798\\u17B6\\u1793" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "\\u1798\\u17B7\\u1793\\u1798\\u17C2\\u1793\\u1787\\u17B6\\u179B\\u17C1\\u1781 (NaN)" : "\\u179B\\u17C1\\u1781"; - } - case "object": { - if (Array.isArray(data)) { - return "\\u17A2\\u17B6\\u179A\\u17C1 (Array)"; - } - if (data === null) { - return "\\u1782\\u17D2\\u1798\\u17B6\\u1793\\u178F\\u1798\\u17D2\\u179B\\u17C3 (null)"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "\\u1791\\u17B7\\u1793\\u17D2\\u1793\\u1793\\u17D0\\u1799\\u1794\\u1789\\u17D2\\u1785\\u17BC\\u179B", - email: "\\u17A2\\u17B6\\u179F\\u1799\\u178A\\u17D2\\u178B\\u17B6\\u1793\\u17A2\\u17CA\\u17B8\\u1798\\u17C2\\u179B", - url: "URL", - emoji: "\\u179F\\u1789\\u17D2\\u1789\\u17B6\\u17A2\\u17B6\\u179A\\u1798\\u17D2\\u1798\\u178E\\u17CD", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "\\u1780\\u17B6\\u179B\\u1794\\u179A\\u17B7\\u1785\\u17D2\\u1786\\u17C1\\u1791 \\u1793\\u17B7\\u1784\\u1798\\u17C9\\u17C4\\u1784 ISO", - date: "\\u1780\\u17B6\\u179B\\u1794\\u179A\\u17B7\\u1785\\u17D2\\u1786\\u17C1\\u1791 ISO", - time: "\\u1798\\u17C9\\u17C4\\u1784 ISO", - duration: "\\u179A\\u1799\\u17C8\\u1796\\u17C1\\u179B ISO", - ipv4: "\\u17A2\\u17B6\\u179F\\u1799\\u178A\\u17D2\\u178B\\u17B6\\u1793 IPv4", - ipv6: "\\u17A2\\u17B6\\u179F\\u1799\\u178A\\u17D2\\u178B\\u17B6\\u1793 IPv6", - cidrv4: "\\u178A\\u17C2\\u1793\\u17A2\\u17B6\\u179F\\u1799\\u178A\\u17D2\\u178B\\u17B6\\u1793 IPv4", - cidrv6: "\\u178A\\u17C2\\u1793\\u17A2\\u17B6\\u179F\\u1799\\u178A\\u17D2\\u178B\\u17B6\\u1793 IPv6", - base64: "\\u1781\\u17D2\\u179F\\u17C2\\u17A2\\u1780\\u17D2\\u179F\\u179A\\u17A2\\u17CA\\u17B7\\u1780\\u17BC\\u178A base64", - base64url: "\\u1781\\u17D2\\u179F\\u17C2\\u17A2\\u1780\\u17D2\\u179F\\u179A\\u17A2\\u17CA\\u17B7\\u1780\\u17BC\\u178A base64url", - json_string: "\\u1781\\u17D2\\u179F\\u17C2\\u17A2\\u1780\\u17D2\\u179F\\u179A JSON", - e164: "\\u179B\\u17C1\\u1781 E.164", - jwt: "JWT", - template_literal: "\\u1791\\u17B7\\u1793\\u17D2\\u1793\\u1793\\u17D0\\u1799\\u1794\\u1789\\u17D2\\u1785\\u17BC\\u179B" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`\\u1791\\u17B7\\u1793\\u17D2\\u1793\\u1793\\u17D0\\u1799\\u1794\\u1789\\u17D2\\u1785\\u17BC\\u179B\\u1798\\u17B7\\u1793\\u178F\\u17D2\\u179A\\u17B9\\u1798\\u178F\\u17D2\\u179A\\u17BC\\u179C\\u17D6 \\u178F\\u17D2\\u179A\\u17BC\\u179C\\u1780\\u17B6\\u179A \${issue2.expected} \\u1794\\u17C9\\u17BB\\u1793\\u17D2\\u178F\\u17C2\\u1791\\u1791\\u17BD\\u179B\\u1794\\u17B6\\u1793 \${parsedType7(issue2.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`\\u1791\\u17B7\\u1793\\u17D2\\u1793\\u1793\\u17D0\\u1799\\u1794\\u1789\\u17D2\\u1785\\u17BC\\u179B\\u1798\\u17B7\\u1793\\u178F\\u17D2\\u179A\\u17B9\\u1798\\u178F\\u17D2\\u179A\\u17BC\\u179C\\u17D6 \\u178F\\u17D2\\u179A\\u17BC\\u179C\\u1780\\u17B6\\u179A \${stringifyPrimitive(issue2.values[0])}\`; - return \`\\u1787\\u1798\\u17D2\\u179A\\u17BE\\u179F\\u1798\\u17B7\\u1793\\u178F\\u17D2\\u179A\\u17B9\\u1798\\u178F\\u17D2\\u179A\\u17BC\\u179C\\u17D6 \\u178F\\u17D2\\u179A\\u17BC\\u179C\\u1787\\u17B6\\u1798\\u17BD\\u1799\\u1780\\u17D2\\u1793\\u17BB\\u1784\\u1785\\u17C6\\u178E\\u17C4\\u1798 \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`\\u1792\\u17C6\\u1796\\u17C1\\u1780\\u17D6 \\u178F\\u17D2\\u179A\\u17BC\\u179C\\u1780\\u17B6\\u179A \${issue2.origin ?? "\\u178F\\u1798\\u17D2\\u179B\\u17C3"} \${adj} \${issue2.maximum.toString()} \${sizing.unit ?? "\\u1792\\u17B6\\u178F\\u17BB"}\`; - return \`\\u1792\\u17C6\\u1796\\u17C1\\u1780\\u17D6 \\u178F\\u17D2\\u179A\\u17BC\\u179C\\u1780\\u17B6\\u179A \${issue2.origin ?? "\\u178F\\u1798\\u17D2\\u179B\\u17C3"} \${adj} \${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`\\u178F\\u17BC\\u1785\\u1796\\u17C1\\u1780\\u17D6 \\u178F\\u17D2\\u179A\\u17BC\\u179C\\u1780\\u17B6\\u179A \${issue2.origin} \${adj} \${issue2.minimum.toString()} \${sizing.unit}\`; - } - return \`\\u178F\\u17BC\\u1785\\u1796\\u17C1\\u1780\\u17D6 \\u178F\\u17D2\\u179A\\u17BC\\u179C\\u1780\\u17B6\\u179A \${issue2.origin} \${adj} \${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") { - return \`\\u1781\\u17D2\\u179F\\u17C2\\u17A2\\u1780\\u17D2\\u179F\\u179A\\u1798\\u17B7\\u1793\\u178F\\u17D2\\u179A\\u17B9\\u1798\\u178F\\u17D2\\u179A\\u17BC\\u179C\\u17D6 \\u178F\\u17D2\\u179A\\u17BC\\u179C\\u1785\\u17B6\\u1794\\u17CB\\u1795\\u17D2\\u178F\\u17BE\\u1798\\u178A\\u17C4\\u1799 "\${_issue.prefix}"\`; - } - if (_issue.format === "ends_with") return \`\\u1781\\u17D2\\u179F\\u17C2\\u17A2\\u1780\\u17D2\\u179F\\u179A\\u1798\\u17B7\\u1793\\u178F\\u17D2\\u179A\\u17B9\\u1798\\u178F\\u17D2\\u179A\\u17BC\\u179C\\u17D6 \\u178F\\u17D2\\u179A\\u17BC\\u179C\\u1794\\u1789\\u17D2\\u1785\\u1794\\u17CB\\u178A\\u17C4\\u1799 "\${_issue.suffix}"\`; - if (_issue.format === "includes") return \`\\u1781\\u17D2\\u179F\\u17C2\\u17A2\\u1780\\u17D2\\u179F\\u179A\\u1798\\u17B7\\u1793\\u178F\\u17D2\\u179A\\u17B9\\u1798\\u178F\\u17D2\\u179A\\u17BC\\u179C\\u17D6 \\u178F\\u17D2\\u179A\\u17BC\\u179C\\u1798\\u17B6\\u1793 "\${_issue.includes}"\`; - if (_issue.format === "regex") return \`\\u1781\\u17D2\\u179F\\u17C2\\u17A2\\u1780\\u17D2\\u179F\\u179A\\u1798\\u17B7\\u1793\\u178F\\u17D2\\u179A\\u17B9\\u1798\\u178F\\u17D2\\u179A\\u17BC\\u179C\\u17D6 \\u178F\\u17D2\\u179A\\u17BC\\u179C\\u178F\\u17C2\\u1795\\u17D2\\u1782\\u17BC\\u1795\\u17D2\\u1782\\u1784\\u1793\\u17B9\\u1784\\u1791\\u1798\\u17D2\\u179A\\u1784\\u17CB\\u178A\\u17C2\\u179B\\u1794\\u17B6\\u1793\\u1780\\u17C6\\u178E\\u178F\\u17CB \${_issue.pattern}\`; - return \`\\u1798\\u17B7\\u1793\\u178F\\u17D2\\u179A\\u17B9\\u1798\\u178F\\u17D2\\u179A\\u17BC\\u179C\\u17D6 \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`\\u179B\\u17C1\\u1781\\u1798\\u17B7\\u1793\\u178F\\u17D2\\u179A\\u17B9\\u1798\\u178F\\u17D2\\u179A\\u17BC\\u179C\\u17D6 \\u178F\\u17D2\\u179A\\u17BC\\u179C\\u178F\\u17C2\\u1787\\u17B6\\u1796\\u17A0\\u17BB\\u1782\\u17BB\\u178E\\u1793\\u17C3 \${issue2.divisor}\`; - case "unrecognized_keys": - return \`\\u179A\\u1780\\u1783\\u17BE\\u1789\\u179F\\u17C4\\u1798\\u17B7\\u1793\\u179F\\u17D2\\u1782\\u17B6\\u179B\\u17CB\\u17D6 \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`\\u179F\\u17C4\\u1798\\u17B7\\u1793\\u178F\\u17D2\\u179A\\u17B9\\u1798\\u178F\\u17D2\\u179A\\u17BC\\u179C\\u1793\\u17C5\\u1780\\u17D2\\u1793\\u17BB\\u1784 \${issue2.origin}\`; - case "invalid_union": - return \`\\u1791\\u17B7\\u1793\\u17D2\\u1793\\u1793\\u17D0\\u1799\\u1798\\u17B7\\u1793\\u178F\\u17D2\\u179A\\u17B9\\u1798\\u178F\\u17D2\\u179A\\u17BC\\u179C\`; - case "invalid_element": - return \`\\u1791\\u17B7\\u1793\\u17D2\\u1793\\u1793\\u17D0\\u1799\\u1798\\u17B7\\u1793\\u178F\\u17D2\\u179A\\u17B9\\u1798\\u178F\\u17D2\\u179A\\u17BC\\u179C\\u1793\\u17C5\\u1780\\u17D2\\u1793\\u17BB\\u1784 \${issue2.origin}\`; - default: - return \`\\u1791\\u17B7\\u1793\\u17D2\\u1793\\u1793\\u17D0\\u1799\\u1798\\u17B7\\u1793\\u178F\\u17D2\\u179A\\u17B9\\u1798\\u178F\\u17D2\\u179A\\u17BC\\u179C\`; - } - }; -}, "error"); -function km_default() { - return { - localeError: error22() - }; -} -__name(km_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/kh.js -function kh_default() { - return km_default(); -} -__name(kh_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/ko.js -var error23 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "\\uBB38\\uC790", - verb: "to have" - }, - file: { - unit: "\\uBC14\\uC774\\uD2B8", - verb: "to have" - }, - array: { - unit: "\\uAC1C", - verb: "to have" - }, - set: { - unit: "\\uAC1C", - verb: "to have" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "number"; - } - case "object": { - if (Array.isArray(data)) { - return "array"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "\\uC785\\uB825", - email: "\\uC774\\uBA54\\uC77C \\uC8FC\\uC18C", - url: "URL", - emoji: "\\uC774\\uBAA8\\uC9C0", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "ISO \\uB0A0\\uC9DC\\uC2DC\\uAC04", - date: "ISO \\uB0A0\\uC9DC", - time: "ISO \\uC2DC\\uAC04", - duration: "ISO \\uAE30\\uAC04", - ipv4: "IPv4 \\uC8FC\\uC18C", - ipv6: "IPv6 \\uC8FC\\uC18C", - cidrv4: "IPv4 \\uBC94\\uC704", - cidrv6: "IPv6 \\uBC94\\uC704", - base64: "base64 \\uC778\\uCF54\\uB529 \\uBB38\\uC790\\uC5F4", - base64url: "base64url \\uC778\\uCF54\\uB529 \\uBB38\\uC790\\uC5F4", - json_string: "JSON \\uBB38\\uC790\\uC5F4", - e164: "E.164 \\uBC88\\uD638", - jwt: "JWT", - template_literal: "\\uC785\\uB825" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`\\uC798\\uBABB\\uB41C \\uC785\\uB825: \\uC608\\uC0C1 \\uD0C0\\uC785\\uC740 \${issue2.expected}, \\uBC1B\\uC740 \\uD0C0\\uC785\\uC740 \${parsedType7(issue2.input)}\\uC785\\uB2C8\\uB2E4\`; - case "invalid_value": - if (issue2.values.length === 1) return \`\\uC798\\uBABB\\uB41C \\uC785\\uB825: \\uAC12\\uC740 \${stringifyPrimitive(issue2.values[0])} \\uC774\\uC5B4\\uC57C \\uD569\\uB2C8\\uB2E4\`; - return \`\\uC798\\uBABB\\uB41C \\uC635\\uC158: \${joinValues(issue2.values, "\\uB610\\uB294 ")} \\uC911 \\uD558\\uB098\\uC5EC\\uC57C \\uD569\\uB2C8\\uB2E4\`; - case "too_big": { - const adj = issue2.inclusive ? "\\uC774\\uD558" : "\\uBBF8\\uB9CC"; - const suffix = adj === "\\uBBF8\\uB9CC" ? "\\uC774\\uC5B4\\uC57C \\uD569\\uB2C8\\uB2E4" : "\\uC5EC\\uC57C \\uD569\\uB2C8\\uB2E4"; - const sizing = getSizing(issue2.origin); - const unit = sizing?.unit ?? "\\uC694\\uC18C"; - if (sizing) return \`\${issue2.origin ?? "\\uAC12"}\\uC774 \\uB108\\uBB34 \\uD07D\\uB2C8\\uB2E4: \${issue2.maximum.toString()}\${unit} \${adj}\${suffix}\`; - return \`\${issue2.origin ?? "\\uAC12"}\\uC774 \\uB108\\uBB34 \\uD07D\\uB2C8\\uB2E4: \${issue2.maximum.toString()} \${adj}\${suffix}\`; - } - case "too_small": { - const adj = issue2.inclusive ? "\\uC774\\uC0C1" : "\\uCD08\\uACFC"; - const suffix = adj === "\\uC774\\uC0C1" ? "\\uC774\\uC5B4\\uC57C \\uD569\\uB2C8\\uB2E4" : "\\uC5EC\\uC57C \\uD569\\uB2C8\\uB2E4"; - const sizing = getSizing(issue2.origin); - const unit = sizing?.unit ?? "\\uC694\\uC18C"; - if (sizing) { - return \`\${issue2.origin ?? "\\uAC12"}\\uC774 \\uB108\\uBB34 \\uC791\\uC2B5\\uB2C8\\uB2E4: \${issue2.minimum.toString()}\${unit} \${adj}\${suffix}\`; - } - return \`\${issue2.origin ?? "\\uAC12"}\\uC774 \\uB108\\uBB34 \\uC791\\uC2B5\\uB2C8\\uB2E4: \${issue2.minimum.toString()} \${adj}\${suffix}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") { - return \`\\uC798\\uBABB\\uB41C \\uBB38\\uC790\\uC5F4: "\${_issue.prefix}"(\\uC73C)\\uB85C \\uC2DC\\uC791\\uD574\\uC57C \\uD569\\uB2C8\\uB2E4\`; - } - if (_issue.format === "ends_with") return \`\\uC798\\uBABB\\uB41C \\uBB38\\uC790\\uC5F4: "\${_issue.suffix}"(\\uC73C)\\uB85C \\uB05D\\uB098\\uC57C \\uD569\\uB2C8\\uB2E4\`; - if (_issue.format === "includes") return \`\\uC798\\uBABB\\uB41C \\uBB38\\uC790\\uC5F4: "\${_issue.includes}"\\uC744(\\uB97C) \\uD3EC\\uD568\\uD574\\uC57C \\uD569\\uB2C8\\uB2E4\`; - if (_issue.format === "regex") return \`\\uC798\\uBABB\\uB41C \\uBB38\\uC790\\uC5F4: \\uC815\\uADDC\\uC2DD \${_issue.pattern} \\uD328\\uD134\\uACFC \\uC77C\\uCE58\\uD574\\uC57C \\uD569\\uB2C8\\uB2E4\`; - return \`\\uC798\\uBABB\\uB41C \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`\\uC798\\uBABB\\uB41C \\uC22B\\uC790: \${issue2.divisor}\\uC758 \\uBC30\\uC218\\uC5EC\\uC57C \\uD569\\uB2C8\\uB2E4\`; - case "unrecognized_keys": - return \`\\uC778\\uC2DD\\uD560 \\uC218 \\uC5C6\\uB294 \\uD0A4: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`\\uC798\\uBABB\\uB41C \\uD0A4: \${issue2.origin}\`; - case "invalid_union": - return \`\\uC798\\uBABB\\uB41C \\uC785\\uB825\`; - case "invalid_element": - return \`\\uC798\\uBABB\\uB41C \\uAC12: \${issue2.origin}\`; - default: - return \`\\uC798\\uBABB\\uB41C \\uC785\\uB825\`; - } - }; -}, "error"); -function ko_default() { - return { - localeError: error23() - }; -} -__name(ko_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/lt.js -var parsedType5 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - return parsedTypeFromType(t, data); -}, "parsedType"); -var parsedTypeFromType = /* @__PURE__ */ __name((t, data = void 0) => { - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "skai\\u010Dius"; - } - case "bigint": { - return "sveikasis skai\\u010Dius"; - } - case "string": { - return "eilut\\u0117"; - } - case "boolean": { - return "login\\u0117 reik\\u0161m\\u0117"; - } - case "undefined": - case "void": { - return "neapibr\\u0117\\u017Eta reik\\u0161m\\u0117"; - } - case "function": { - return "funkcija"; - } - case "symbol": { - return "simbolis"; - } - case "object": { - if (data === void 0) return "ne\\u017Einomas objektas"; - if (data === null) return "nulin\\u0117 reik\\u0161m\\u0117"; - if (Array.isArray(data)) return "masyvas"; - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - return "objektas"; - } - //Zod types below - case "null": { - return "nulin\\u0117 reik\\u0161m\\u0117"; - } - } - return t; -}, "parsedTypeFromType"); -var capitalizeFirstCharacter = /* @__PURE__ */ __name((text2) => { - return text2.charAt(0).toUpperCase() + text2.slice(1); -}, "capitalizeFirstCharacter"); -function getUnitTypeFromNumber(number4) { - const abs = Math.abs(number4); - const last = abs % 10; - const last2 = abs % 100; - if (last2 >= 11 && last2 <= 19 || last === 0) return "many"; - if (last === 1) return "one"; - return "few"; -} -__name(getUnitTypeFromNumber, "getUnitTypeFromNumber"); -var error24 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: { - one: "simbolis", - few: "simboliai", - many: "simboli\\u0173" - }, - verb: { - smaller: { - inclusive: "turi b\\u016Bti ne ilgesn\\u0117 kaip", - notInclusive: "turi b\\u016Bti trumpesn\\u0117 kaip" - }, - bigger: { - inclusive: "turi b\\u016Bti ne trumpesn\\u0117 kaip", - notInclusive: "turi b\\u016Bti ilgesn\\u0117 kaip" - } - } - }, - file: { - unit: { - one: "baitas", - few: "baitai", - many: "bait\\u0173" - }, - verb: { - smaller: { - inclusive: "turi b\\u016Bti ne didesnis kaip", - notInclusive: "turi b\\u016Bti ma\\u017Eesnis kaip" - }, - bigger: { - inclusive: "turi b\\u016Bti ne ma\\u017Eesnis kaip", - notInclusive: "turi b\\u016Bti didesnis kaip" - } - } - }, - array: { - unit: { - one: "element\\u0105", - few: "elementus", - many: "element\\u0173" - }, - verb: { - smaller: { - inclusive: "turi tur\\u0117ti ne daugiau kaip", - notInclusive: "turi tur\\u0117ti ma\\u017Eiau kaip" - }, - bigger: { - inclusive: "turi tur\\u0117ti ne ma\\u017Eiau kaip", - notInclusive: "turi tur\\u0117ti daugiau kaip" - } - } - }, - set: { - unit: { - one: "element\\u0105", - few: "elementus", - many: "element\\u0173" - }, - verb: { - smaller: { - inclusive: "turi tur\\u0117ti ne daugiau kaip", - notInclusive: "turi tur\\u0117ti ma\\u017Eiau kaip" - }, - bigger: { - inclusive: "turi tur\\u0117ti ne ma\\u017Eiau kaip", - notInclusive: "turi tur\\u0117ti daugiau kaip" - } - } - } - }; - function getSizing(origin, unitType, inclusive, targetShouldBe) { - const result = Sizable[origin] ?? null; - if (result === null) return result; - return { - unit: result.unit[unitType], - verb: result.verb[targetShouldBe][inclusive ? "inclusive" : "notInclusive"] - }; - } - __name(getSizing, "getSizing"); - const Nouns = { - regex: "\\u012Fvestis", - email: "el. pa\\u0161to adresas", - url: "URL", - emoji: "jaustukas", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "ISO data ir laikas", - date: "ISO data", - time: "ISO laikas", - duration: "ISO trukm\\u0117", - ipv4: "IPv4 adresas", - ipv6: "IPv6 adresas", - cidrv4: "IPv4 tinklo prefiksas (CIDR)", - cidrv6: "IPv6 tinklo prefiksas (CIDR)", - base64: "base64 u\\u017Ekoduota eilut\\u0117", - base64url: "base64url u\\u017Ekoduota eilut\\u0117", - json_string: "JSON eilut\\u0117", - e164: "E.164 numeris", - jwt: "JWT", - template_literal: "\\u012Fvestis" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`Gautas tipas \${parsedType5(issue2.input)}, o tik\\u0117tasi - \${parsedTypeFromType(issue2.expected)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`Privalo b\\u016Bti \${stringifyPrimitive(issue2.values[0])}\`; - return \`Privalo b\\u016Bti vienas i\\u0161 \${joinValues(issue2.values, "|")} pasirinkim\\u0173\`; - case "too_big": { - const origin = parsedTypeFromType(issue2.origin); - const sizing = getSizing(issue2.origin, getUnitTypeFromNumber(Number(issue2.maximum)), issue2.inclusive ?? false, "smaller"); - if (sizing?.verb) return \`\${capitalizeFirstCharacter(origin ?? issue2.origin ?? "reik\\u0161m\\u0117")} \${sizing.verb} \${issue2.maximum.toString()} \${sizing.unit ?? "element\\u0173"}\`; - const adj = issue2.inclusive ? "ne didesnis kaip" : "ma\\u017Eesnis kaip"; - return \`\${capitalizeFirstCharacter(origin ?? issue2.origin ?? "reik\\u0161m\\u0117")} turi b\\u016Bti \${adj} \${issue2.maximum.toString()} \${sizing?.unit}\`; - } - case "too_small": { - const origin = parsedTypeFromType(issue2.origin); - const sizing = getSizing(issue2.origin, getUnitTypeFromNumber(Number(issue2.minimum)), issue2.inclusive ?? false, "bigger"); - if (sizing?.verb) return \`\${capitalizeFirstCharacter(origin ?? issue2.origin ?? "reik\\u0161m\\u0117")} \${sizing.verb} \${issue2.minimum.toString()} \${sizing.unit ?? "element\\u0173"}\`; - const adj = issue2.inclusive ? "ne ma\\u017Eesnis kaip" : "didesnis kaip"; - return \`\${capitalizeFirstCharacter(origin ?? issue2.origin ?? "reik\\u0161m\\u0117")} turi b\\u016Bti \${adj} \${issue2.minimum.toString()} \${sizing?.unit}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") { - return \`Eilut\\u0117 privalo prasid\\u0117ti "\${_issue.prefix}"\`; - } - if (_issue.format === "ends_with") return \`Eilut\\u0117 privalo pasibaigti "\${_issue.suffix}"\`; - if (_issue.format === "includes") return \`Eilut\\u0117 privalo \\u012Ftraukti "\${_issue.includes}"\`; - if (_issue.format === "regex") return \`Eilut\\u0117 privalo atitikti \${_issue.pattern}\`; - return \`Neteisingas \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`Skai\\u010Dius privalo b\\u016Bti \${issue2.divisor} kartotinis.\`; - case "unrecognized_keys": - return \`Neatpa\\u017Eint\${issue2.keys.length > 1 ? "i" : "as"} rakt\${issue2.keys.length > 1 ? "ai" : "as"}: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return "Rastas klaidingas raktas"; - case "invalid_union": - return "Klaidinga \\u012Fvestis"; - case "invalid_element": { - const origin = parsedTypeFromType(issue2.origin); - return \`\${capitalizeFirstCharacter(origin ?? issue2.origin ?? "reik\\u0161m\\u0117")} turi klaiding\\u0105 \\u012Fvest\\u012F\`; - } - default: - return "Klaidinga \\u012Fvestis"; - } - }; -}, "error"); -function lt_default() { - return { - localeError: error24() - }; -} -__name(lt_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/mk.js -var error25 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "\\u0437\\u043D\\u0430\\u0446\\u0438", - verb: "\\u0434\\u0430 \\u0438\\u043C\\u0430\\u0430\\u0442" - }, - file: { - unit: "\\u0431\\u0430\\u0458\\u0442\\u0438", - verb: "\\u0434\\u0430 \\u0438\\u043C\\u0430\\u0430\\u0442" - }, - array: { - unit: "\\u0441\\u0442\\u0430\\u0432\\u043A\\u0438", - verb: "\\u0434\\u0430 \\u0438\\u043C\\u0430\\u0430\\u0442" - }, - set: { - unit: "\\u0441\\u0442\\u0430\\u0432\\u043A\\u0438", - verb: "\\u0434\\u0430 \\u0438\\u043C\\u0430\\u0430\\u0442" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "\\u0431\\u0440\\u043E\\u0458"; - } - case "object": { - if (Array.isArray(data)) { - return "\\u043D\\u0438\\u0437\\u0430"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "\\u0432\\u043D\\u0435\\u0441", - email: "\\u0430\\u0434\\u0440\\u0435\\u0441\\u0430 \\u043D\\u0430 \\u0435-\\u043F\\u043E\\u0448\\u0442\\u0430", - url: "URL", - emoji: "\\u0435\\u043C\\u043E\\u045F\\u0438", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "ISO \\u0434\\u0430\\u0442\\u0443\\u043C \\u0438 \\u0432\\u0440\\u0435\\u043C\\u0435", - date: "ISO \\u0434\\u0430\\u0442\\u0443\\u043C", - time: "ISO \\u0432\\u0440\\u0435\\u043C\\u0435", - duration: "ISO \\u0432\\u0440\\u0435\\u043C\\u0435\\u0442\\u0440\\u0430\\u0435\\u045A\\u0435", - ipv4: "IPv4 \\u0430\\u0434\\u0440\\u0435\\u0441\\u0430", - ipv6: "IPv6 \\u0430\\u0434\\u0440\\u0435\\u0441\\u0430", - cidrv4: "IPv4 \\u043E\\u043F\\u0441\\u0435\\u0433", - cidrv6: "IPv6 \\u043E\\u043F\\u0441\\u0435\\u0433", - base64: "base64-\\u0435\\u043D\\u043A\\u043E\\u0434\\u0438\\u0440\\u0430\\u043D\\u0430 \\u043D\\u0438\\u0437\\u0430", - base64url: "base64url-\\u0435\\u043D\\u043A\\u043E\\u0434\\u0438\\u0440\\u0430\\u043D\\u0430 \\u043D\\u0438\\u0437\\u0430", - json_string: "JSON \\u043D\\u0438\\u0437\\u0430", - e164: "E.164 \\u0431\\u0440\\u043E\\u0458", - jwt: "JWT", - template_literal: "\\u0432\\u043D\\u0435\\u0441" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`\\u0413\\u0440\\u0435\\u0448\\u0435\\u043D \\u0432\\u043D\\u0435\\u0441: \\u0441\\u0435 \\u043E\\u0447\\u0435\\u043A\\u0443\\u0432\\u0430 \${issue2.expected}, \\u043F\\u0440\\u0438\\u043C\\u0435\\u043D\\u043E \${parsedType7(issue2.input)}\`; - // return \`Invalid input: expected \${issue.expected}, received \${util.getParsedType(issue.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`Invalid input: expected \${stringifyPrimitive(issue2.values[0])}\`; - return \`\\u0413\\u0440\\u0435\\u0448\\u0430\\u043D\\u0430 \\u043E\\u043F\\u0446\\u0438\\u0458\\u0430: \\u0441\\u0435 \\u043E\\u0447\\u0435\\u043A\\u0443\\u0432\\u0430 \\u0435\\u0434\\u043D\\u0430 \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`\\u041F\\u0440\\u0435\\u043C\\u043D\\u043E\\u0433\\u0443 \\u0433\\u043E\\u043B\\u0435\\u043C: \\u0441\\u0435 \\u043E\\u0447\\u0435\\u043A\\u0443\\u0432\\u0430 \${issue2.origin ?? "\\u0432\\u0440\\u0435\\u0434\\u043D\\u043E\\u0441\\u0442\\u0430"} \\u0434\\u0430 \\u0438\\u043C\\u0430 \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "\\u0435\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442\\u0438"}\`; - return \`\\u041F\\u0440\\u0435\\u043C\\u043D\\u043E\\u0433\\u0443 \\u0433\\u043E\\u043B\\u0435\\u043C: \\u0441\\u0435 \\u043E\\u0447\\u0435\\u043A\\u0443\\u0432\\u0430 \${issue2.origin ?? "\\u0432\\u0440\\u0435\\u0434\\u043D\\u043E\\u0441\\u0442\\u0430"} \\u0434\\u0430 \\u0431\\u0438\\u0434\\u0435 \${adj}\${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`\\u041F\\u0440\\u0435\\u043C\\u043D\\u043E\\u0433\\u0443 \\u043C\\u0430\\u043B: \\u0441\\u0435 \\u043E\\u0447\\u0435\\u043A\\u0443\\u0432\\u0430 \${issue2.origin} \\u0434\\u0430 \\u0438\\u043C\\u0430 \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; - } - return \`\\u041F\\u0440\\u0435\\u043C\\u043D\\u043E\\u0433\\u0443 \\u043C\\u0430\\u043B: \\u0441\\u0435 \\u043E\\u0447\\u0435\\u043A\\u0443\\u0432\\u0430 \${issue2.origin} \\u0434\\u0430 \\u0431\\u0438\\u0434\\u0435 \${adj}\${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") { - return \`\\u041D\\u0435\\u0432\\u0430\\u0436\\u0435\\u0447\\u043A\\u0430 \\u043D\\u0438\\u0437\\u0430: \\u043C\\u043E\\u0440\\u0430 \\u0434\\u0430 \\u0437\\u0430\\u043F\\u043E\\u0447\\u043D\\u0443\\u0432\\u0430 \\u0441\\u043E "\${_issue.prefix}"\`; - } - if (_issue.format === "ends_with") return \`\\u041D\\u0435\\u0432\\u0430\\u0436\\u0435\\u0447\\u043A\\u0430 \\u043D\\u0438\\u0437\\u0430: \\u043C\\u043E\\u0440\\u0430 \\u0434\\u0430 \\u0437\\u0430\\u0432\\u0440\\u0448\\u0443\\u0432\\u0430 \\u0441\\u043E "\${_issue.suffix}"\`; - if (_issue.format === "includes") return \`\\u041D\\u0435\\u0432\\u0430\\u0436\\u0435\\u0447\\u043A\\u0430 \\u043D\\u0438\\u0437\\u0430: \\u043C\\u043E\\u0440\\u0430 \\u0434\\u0430 \\u0432\\u043A\\u043B\\u0443\\u0447\\u0443\\u0432\\u0430 "\${_issue.includes}"\`; - if (_issue.format === "regex") return \`\\u041D\\u0435\\u0432\\u0430\\u0436\\u0435\\u0447\\u043A\\u0430 \\u043D\\u0438\\u0437\\u0430: \\u043C\\u043E\\u0440\\u0430 \\u0434\\u0430 \\u043E\\u0434\\u0433\\u043E\\u0430\\u0440\\u0430 \\u043D\\u0430 \\u043F\\u0430\\u0442\\u0435\\u0440\\u043D\\u043E\\u0442 \${_issue.pattern}\`; - return \`Invalid \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`\\u0413\\u0440\\u0435\\u0448\\u0435\\u043D \\u0431\\u0440\\u043E\\u0458: \\u043C\\u043E\\u0440\\u0430 \\u0434\\u0430 \\u0431\\u0438\\u0434\\u0435 \\u0434\\u0435\\u043B\\u0438\\u0432 \\u0441\\u043E \${issue2.divisor}\`; - case "unrecognized_keys": - return \`\${issue2.keys.length > 1 ? "\\u041D\\u0435\\u043F\\u0440\\u0435\\u043F\\u043E\\u0437\\u043D\\u0430\\u0435\\u043D\\u0438 \\u043A\\u043B\\u0443\\u0447\\u0435\\u0432\\u0438" : "\\u041D\\u0435\\u043F\\u0440\\u0435\\u043F\\u043E\\u0437\\u043D\\u0430\\u0435\\u043D \\u043A\\u043B\\u0443\\u0447"}: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`\\u0413\\u0440\\u0435\\u0448\\u0435\\u043D \\u043A\\u043B\\u0443\\u0447 \\u0432\\u043E \${issue2.origin}\`; - case "invalid_union": - return "\\u0413\\u0440\\u0435\\u0448\\u0435\\u043D \\u0432\\u043D\\u0435\\u0441"; - case "invalid_element": - return \`\\u0413\\u0440\\u0435\\u0448\\u043D\\u0430 \\u0432\\u0440\\u0435\\u0434\\u043D\\u043E\\u0441\\u0442 \\u0432\\u043E \${issue2.origin}\`; - default: - return \`\\u0413\\u0440\\u0435\\u0448\\u0435\\u043D \\u0432\\u043D\\u0435\\u0441\`; - } - }; -}, "error"); -function mk_default() { - return { - localeError: error25() - }; -} -__name(mk_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/ms.js -var error26 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "aksara", - verb: "mempunyai" - }, - file: { - unit: "bait", - verb: "mempunyai" - }, - array: { - unit: "elemen", - verb: "mempunyai" - }, - set: { - unit: "elemen", - verb: "mempunyai" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "nombor"; - } - case "object": { - if (Array.isArray(data)) { - return "array"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "input", - email: "alamat e-mel", - url: "URL", - emoji: "emoji", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "tarikh masa ISO", - date: "tarikh ISO", - time: "masa ISO", - duration: "tempoh ISO", - ipv4: "alamat IPv4", - ipv6: "alamat IPv6", - cidrv4: "julat IPv4", - cidrv6: "julat IPv6", - base64: "string dikodkan base64", - base64url: "string dikodkan base64url", - json_string: "string JSON", - e164: "nombor E.164", - jwt: "JWT", - template_literal: "input" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`Input tidak sah: dijangka \${issue2.expected}, diterima \${parsedType7(issue2.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`Input tidak sah: dijangka \${stringifyPrimitive(issue2.values[0])}\`; - return \`Pilihan tidak sah: dijangka salah satu daripada \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`Terlalu besar: dijangka \${issue2.origin ?? "nilai"} \${sizing.verb} \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "elemen"}\`; - return \`Terlalu besar: dijangka \${issue2.origin ?? "nilai"} adalah \${adj}\${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`Terlalu kecil: dijangka \${issue2.origin} \${sizing.verb} \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; - } - return \`Terlalu kecil: dijangka \${issue2.origin} adalah \${adj}\${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") return \`String tidak sah: mesti bermula dengan "\${_issue.prefix}"\`; - if (_issue.format === "ends_with") return \`String tidak sah: mesti berakhir dengan "\${_issue.suffix}"\`; - if (_issue.format === "includes") return \`String tidak sah: mesti mengandungi "\${_issue.includes}"\`; - if (_issue.format === "regex") return \`String tidak sah: mesti sepadan dengan corak \${_issue.pattern}\`; - return \`\${Nouns[_issue.format] ?? issue2.format} tidak sah\`; - } - case "not_multiple_of": - return \`Nombor tidak sah: perlu gandaan \${issue2.divisor}\`; - case "unrecognized_keys": - return \`Kunci tidak dikenali: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`Kunci tidak sah dalam \${issue2.origin}\`; - case "invalid_union": - return "Input tidak sah"; - case "invalid_element": - return \`Nilai tidak sah dalam \${issue2.origin}\`; - default: - return \`Input tidak sah\`; - } - }; -}, "error"); -function ms_default() { - return { - localeError: error26() - }; -} -__name(ms_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/nl.js -var error27 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "tekens" - }, - file: { - unit: "bytes" - }, - array: { - unit: "elementen" - }, - set: { - unit: "elementen" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "getal"; - } - case "object": { - if (Array.isArray(data)) { - return "array"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "invoer", - email: "emailadres", - url: "URL", - emoji: "emoji", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "ISO datum en tijd", - date: "ISO datum", - time: "ISO tijd", - duration: "ISO duur", - ipv4: "IPv4-adres", - ipv6: "IPv6-adres", - cidrv4: "IPv4-bereik", - cidrv6: "IPv6-bereik", - base64: "base64-gecodeerde tekst", - base64url: "base64 URL-gecodeerde tekst", - json_string: "JSON string", - e164: "E.164-nummer", - jwt: "JWT", - template_literal: "invoer" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`Ongeldige invoer: verwacht \${issue2.expected}, ontving \${parsedType7(issue2.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`Ongeldige invoer: verwacht \${stringifyPrimitive(issue2.values[0])}\`; - return \`Ongeldige optie: verwacht \\xE9\\xE9n van \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`Te lang: verwacht dat \${issue2.origin ?? "waarde"} \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "elementen"} bevat\`; - return \`Te lang: verwacht dat \${issue2.origin ?? "waarde"} \${adj}\${issue2.maximum.toString()} is\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`Te kort: verwacht dat \${issue2.origin} \${adj}\${issue2.minimum.toString()} \${sizing.unit} bevat\`; - } - return \`Te kort: verwacht dat \${issue2.origin} \${adj}\${issue2.minimum.toString()} is\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") { - return \`Ongeldige tekst: moet met "\${_issue.prefix}" beginnen\`; - } - if (_issue.format === "ends_with") return \`Ongeldige tekst: moet op "\${_issue.suffix}" eindigen\`; - if (_issue.format === "includes") return \`Ongeldige tekst: moet "\${_issue.includes}" bevatten\`; - if (_issue.format === "regex") return \`Ongeldige tekst: moet overeenkomen met patroon \${_issue.pattern}\`; - return \`Ongeldig: \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`Ongeldig getal: moet een veelvoud van \${issue2.divisor} zijn\`; - case "unrecognized_keys": - return \`Onbekende key\${issue2.keys.length > 1 ? "s" : ""}: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`Ongeldige key in \${issue2.origin}\`; - case "invalid_union": - return "Ongeldige invoer"; - case "invalid_element": - return \`Ongeldige waarde in \${issue2.origin}\`; - default: - return \`Ongeldige invoer\`; - } - }; -}, "error"); -function nl_default() { - return { - localeError: error27() - }; -} -__name(nl_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/no.js -var error28 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "tegn", - verb: "\\xE5 ha" - }, - file: { - unit: "bytes", - verb: "\\xE5 ha" - }, - array: { - unit: "elementer", - verb: "\\xE5 inneholde" - }, - set: { - unit: "elementer", - verb: "\\xE5 inneholde" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "tall"; - } - case "object": { - if (Array.isArray(data)) { - return "liste"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "input", - email: "e-postadresse", - url: "URL", - emoji: "emoji", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "ISO dato- og klokkeslett", - date: "ISO-dato", - time: "ISO-klokkeslett", - duration: "ISO-varighet", - ipv4: "IPv4-omr\\xE5de", - ipv6: "IPv6-omr\\xE5de", - cidrv4: "IPv4-spekter", - cidrv6: "IPv6-spekter", - base64: "base64-enkodet streng", - base64url: "base64url-enkodet streng", - json_string: "JSON-streng", - e164: "E.164-nummer", - jwt: "JWT", - template_literal: "input" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`Ugyldig input: forventet \${issue2.expected}, fikk \${parsedType7(issue2.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`Ugyldig verdi: forventet \${stringifyPrimitive(issue2.values[0])}\`; - return \`Ugyldig valg: forventet en av \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`For stor(t): forventet \${issue2.origin ?? "value"} til \\xE5 ha \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "elementer"}\`; - return \`For stor(t): forventet \${issue2.origin ?? "value"} til \\xE5 ha \${adj}\${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`For lite(n): forventet \${issue2.origin} til \\xE5 ha \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; - } - return \`For lite(n): forventet \${issue2.origin} til \\xE5 ha \${adj}\${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") return \`Ugyldig streng: m\\xE5 starte med "\${_issue.prefix}"\`; - if (_issue.format === "ends_with") return \`Ugyldig streng: m\\xE5 ende med "\${_issue.suffix}"\`; - if (_issue.format === "includes") return \`Ugyldig streng: m\\xE5 inneholde "\${_issue.includes}"\`; - if (_issue.format === "regex") return \`Ugyldig streng: m\\xE5 matche m\\xF8nsteret \${_issue.pattern}\`; - return \`Ugyldig \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`Ugyldig tall: m\\xE5 v\\xE6re et multiplum av \${issue2.divisor}\`; - case "unrecognized_keys": - return \`\${issue2.keys.length > 1 ? "Ukjente n\\xF8kler" : "Ukjent n\\xF8kkel"}: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`Ugyldig n\\xF8kkel i \${issue2.origin}\`; - case "invalid_union": - return "Ugyldig input"; - case "invalid_element": - return \`Ugyldig verdi i \${issue2.origin}\`; - default: - return \`Ugyldig input\`; - } - }; -}, "error"); -function no_default() { - return { - localeError: error28() - }; -} -__name(no_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/ota.js -var error29 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "harf", - verb: "olmal\\u0131d\\u0131r" - }, - file: { - unit: "bayt", - verb: "olmal\\u0131d\\u0131r" - }, - array: { - unit: "unsur", - verb: "olmal\\u0131d\\u0131r" - }, - set: { - unit: "unsur", - verb: "olmal\\u0131d\\u0131r" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "numara"; - } - case "object": { - if (Array.isArray(data)) { - return "saf"; - } - if (data === null) { - return "gayb"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "giren", - email: "epostag\\xE2h", - url: "URL", - emoji: "emoji", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "ISO heng\\xE2m\\u0131", - date: "ISO tarihi", - time: "ISO zaman\\u0131", - duration: "ISO m\\xFCddeti", - ipv4: "IPv4 ni\\u015F\\xE2n\\u0131", - ipv6: "IPv6 ni\\u015F\\xE2n\\u0131", - cidrv4: "IPv4 menzili", - cidrv6: "IPv6 menzili", - base64: "base64-\\u015Fifreli metin", - base64url: "base64url-\\u015Fifreli metin", - json_string: "JSON metin", - e164: "E.164 say\\u0131s\\u0131", - jwt: "JWT", - template_literal: "giren" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`F\\xE2sit giren: umulan \${issue2.expected}, al\\u0131nan \${parsedType7(issue2.input)}\`; - // return \`Fâsit giren: umulan \${issue.expected}, alınan \${util.getParsedType(issue.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`F\\xE2sit giren: umulan \${stringifyPrimitive(issue2.values[0])}\`; - return \`F\\xE2sit tercih: m\\xFBteberler \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`Fazla b\\xFCy\\xFCk: \${issue2.origin ?? "value"}, \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "elements"} sahip olmal\\u0131yd\\u0131.\`; - return \`Fazla b\\xFCy\\xFCk: \${issue2.origin ?? "value"}, \${adj}\${issue2.maximum.toString()} olmal\\u0131yd\\u0131.\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`Fazla k\\xFC\\xE7\\xFCk: \${issue2.origin}, \${adj}\${issue2.minimum.toString()} \${sizing.unit} sahip olmal\\u0131yd\\u0131.\`; - } - return \`Fazla k\\xFC\\xE7\\xFCk: \${issue2.origin}, \${adj}\${issue2.minimum.toString()} olmal\\u0131yd\\u0131.\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") return \`F\\xE2sit metin: "\${_issue.prefix}" ile ba\\u015Flamal\\u0131.\`; - if (_issue.format === "ends_with") return \`F\\xE2sit metin: "\${_issue.suffix}" ile bitmeli.\`; - if (_issue.format === "includes") return \`F\\xE2sit metin: "\${_issue.includes}" ihtiv\\xE2 etmeli.\`; - if (_issue.format === "regex") return \`F\\xE2sit metin: \${_issue.pattern} nak\\u015F\\u0131na uymal\\u0131.\`; - return \`F\\xE2sit \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`F\\xE2sit say\\u0131: \${issue2.divisor} kat\\u0131 olmal\\u0131yd\\u0131.\`; - case "unrecognized_keys": - return \`Tan\\u0131nmayan anahtar \${issue2.keys.length > 1 ? "s" : ""}: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`\${issue2.origin} i\\xE7in tan\\u0131nmayan anahtar var.\`; - case "invalid_union": - return "Giren tan\\u0131namad\\u0131."; - case "invalid_element": - return \`\${issue2.origin} i\\xE7in tan\\u0131nmayan k\\u0131ymet var.\`; - default: - return \`K\\u0131ymet tan\\u0131namad\\u0131.\`; - } - }; -}, "error"); -function ota_default() { - return { - localeError: error29() - }; -} -__name(ota_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/ps.js -var error30 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "\\u062A\\u0648\\u06A9\\u064A", - verb: "\\u0648\\u0644\\u0631\\u064A" - }, - file: { - unit: "\\u0628\\u0627\\u06CC\\u067C\\u0633", - verb: "\\u0648\\u0644\\u0631\\u064A" - }, - array: { - unit: "\\u062A\\u0648\\u06A9\\u064A", - verb: "\\u0648\\u0644\\u0631\\u064A" - }, - set: { - unit: "\\u062A\\u0648\\u06A9\\u064A", - verb: "\\u0648\\u0644\\u0631\\u064A" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "\\u0639\\u062F\\u062F"; - } - case "object": { - if (Array.isArray(data)) { - return "\\u0627\\u0631\\u06D0"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "\\u0648\\u0631\\u0648\\u062F\\u064A", - email: "\\u0628\\u0631\\u06CC\\u069A\\u0646\\u0627\\u0644\\u06CC\\u06A9", - url: "\\u06CC\\u0648 \\u0622\\u0631 \\u0627\\u0644", - emoji: "\\u0627\\u06CC\\u0645\\u0648\\u062C\\u064A", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "\\u0646\\u06CC\\u067C\\u0647 \\u0627\\u0648 \\u0648\\u062E\\u062A", - date: "\\u0646\\u06D0\\u067C\\u0647", - time: "\\u0648\\u062E\\u062A", - duration: "\\u0645\\u0648\\u062F\\u0647", - ipv4: "\\u062F IPv4 \\u067E\\u062A\\u0647", - ipv6: "\\u062F IPv6 \\u067E\\u062A\\u0647", - cidrv4: "\\u062F IPv4 \\u0633\\u0627\\u062D\\u0647", - cidrv6: "\\u062F IPv6 \\u0633\\u0627\\u062D\\u0647", - base64: "base64-encoded \\u0645\\u062A\\u0646", - base64url: "base64url-encoded \\u0645\\u062A\\u0646", - json_string: "JSON \\u0645\\u062A\\u0646", - e164: "\\u062F E.164 \\u0634\\u0645\\u06D0\\u0631\\u0647", - jwt: "JWT", - template_literal: "\\u0648\\u0631\\u0648\\u062F\\u064A" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`\\u0646\\u0627\\u0633\\u0645 \\u0648\\u0631\\u0648\\u062F\\u064A: \\u0628\\u0627\\u06CC\\u062F \${issue2.expected} \\u0648\\u0627\\u06CC, \\u0645\\u06AB\\u0631 \${parsedType7(issue2.input)} \\u062A\\u0631\\u0644\\u0627\\u0633\\u0647 \\u0634\\u0648\`; - case "invalid_value": - if (issue2.values.length === 1) { - return \`\\u0646\\u0627\\u0633\\u0645 \\u0648\\u0631\\u0648\\u062F\\u064A: \\u0628\\u0627\\u06CC\\u062F \${stringifyPrimitive(issue2.values[0])} \\u0648\\u0627\\u06CC\`; - } - return \`\\u0646\\u0627\\u0633\\u0645 \\u0627\\u0646\\u062A\\u062E\\u0627\\u0628: \\u0628\\u0627\\u06CC\\u062F \\u06CC\\u0648 \\u0644\\u0647 \${joinValues(issue2.values, "|")} \\u0685\\u062E\\u0647 \\u0648\\u0627\\u06CC\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`\\u0689\\u06CC\\u0631 \\u0644\\u0648\\u06CC: \${issue2.origin ?? "\\u0627\\u0631\\u0632\\u069A\\u062A"} \\u0628\\u0627\\u06CC\\u062F \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "\\u0639\\u0646\\u0635\\u0631\\u0648\\u0646\\u0647"} \\u0648\\u0644\\u0631\\u064A\`; - } - return \`\\u0689\\u06CC\\u0631 \\u0644\\u0648\\u06CC: \${issue2.origin ?? "\\u0627\\u0631\\u0632\\u069A\\u062A"} \\u0628\\u0627\\u06CC\\u062F \${adj}\${issue2.maximum.toString()} \\u0648\\u064A\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`\\u0689\\u06CC\\u0631 \\u06A9\\u0648\\u0686\\u0646\\u06CC: \${issue2.origin} \\u0628\\u0627\\u06CC\\u062F \${adj}\${issue2.minimum.toString()} \${sizing.unit} \\u0648\\u0644\\u0631\\u064A\`; - } - return \`\\u0689\\u06CC\\u0631 \\u06A9\\u0648\\u0686\\u0646\\u06CC: \${issue2.origin} \\u0628\\u0627\\u06CC\\u062F \${adj}\${issue2.minimum.toString()} \\u0648\\u064A\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") { - return \`\\u0646\\u0627\\u0633\\u0645 \\u0645\\u062A\\u0646: \\u0628\\u0627\\u06CC\\u062F \\u062F "\${_issue.prefix}" \\u0633\\u0631\\u0647 \\u067E\\u06CC\\u0644 \\u0634\\u064A\`; - } - if (_issue.format === "ends_with") { - return \`\\u0646\\u0627\\u0633\\u0645 \\u0645\\u062A\\u0646: \\u0628\\u0627\\u06CC\\u062F \\u062F "\${_issue.suffix}" \\u0633\\u0631\\u0647 \\u067E\\u0627\\u06CC \\u062A\\u0647 \\u0648\\u0631\\u0633\\u064A\\u0696\\u064A\`; - } - if (_issue.format === "includes") { - return \`\\u0646\\u0627\\u0633\\u0645 \\u0645\\u062A\\u0646: \\u0628\\u0627\\u06CC\\u062F "\${_issue.includes}" \\u0648\\u0644\\u0631\\u064A\`; - } - if (_issue.format === "regex") { - return \`\\u0646\\u0627\\u0633\\u0645 \\u0645\\u062A\\u0646: \\u0628\\u0627\\u06CC\\u062F \\u062F \${_issue.pattern} \\u0633\\u0631\\u0647 \\u0645\\u0637\\u0627\\u0628\\u0642\\u062A \\u0648\\u0644\\u0631\\u064A\`; - } - return \`\${Nouns[_issue.format] ?? issue2.format} \\u0646\\u0627\\u0633\\u0645 \\u062F\\u06CC\`; - } - case "not_multiple_of": - return \`\\u0646\\u0627\\u0633\\u0645 \\u0639\\u062F\\u062F: \\u0628\\u0627\\u06CC\\u062F \\u062F \${issue2.divisor} \\u0645\\u0636\\u0631\\u0628 \\u0648\\u064A\`; - case "unrecognized_keys": - return \`\\u0646\\u0627\\u0633\\u0645 \${issue2.keys.length > 1 ? "\\u06A9\\u0644\\u06CC\\u0689\\u0648\\u0646\\u0647" : "\\u06A9\\u0644\\u06CC\\u0689"}: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`\\u0646\\u0627\\u0633\\u0645 \\u06A9\\u0644\\u06CC\\u0689 \\u067E\\u0647 \${issue2.origin} \\u06A9\\u06D0\`; - case "invalid_union": - return \`\\u0646\\u0627\\u0633\\u0645\\u0647 \\u0648\\u0631\\u0648\\u062F\\u064A\`; - case "invalid_element": - return \`\\u0646\\u0627\\u0633\\u0645 \\u0639\\u0646\\u0635\\u0631 \\u067E\\u0647 \${issue2.origin} \\u06A9\\u06D0\`; - default: - return \`\\u0646\\u0627\\u0633\\u0645\\u0647 \\u0648\\u0631\\u0648\\u062F\\u064A\`; - } - }; -}, "error"); -function ps_default() { - return { - localeError: error30() - }; -} -__name(ps_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/pl.js -var error31 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "znak\\xF3w", - verb: "mie\\u0107" - }, - file: { - unit: "bajt\\xF3w", - verb: "mie\\u0107" - }, - array: { - unit: "element\\xF3w", - verb: "mie\\u0107" - }, - set: { - unit: "element\\xF3w", - verb: "mie\\u0107" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "liczba"; - } - case "object": { - if (Array.isArray(data)) { - return "tablica"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "wyra\\u017Cenie", - email: "adres email", - url: "URL", - emoji: "emoji", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "data i godzina w formacie ISO", - date: "data w formacie ISO", - time: "godzina w formacie ISO", - duration: "czas trwania ISO", - ipv4: "adres IPv4", - ipv6: "adres IPv6", - cidrv4: "zakres IPv4", - cidrv6: "zakres IPv6", - base64: "ci\\u0105g znak\\xF3w zakodowany w formacie base64", - base64url: "ci\\u0105g znak\\xF3w zakodowany w formacie base64url", - json_string: "ci\\u0105g znak\\xF3w w formacie JSON", - e164: "liczba E.164", - jwt: "JWT", - template_literal: "wej\\u015Bcie" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`Nieprawid\\u0142owe dane wej\\u015Bciowe: oczekiwano \${issue2.expected}, otrzymano \${parsedType7(issue2.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`Nieprawid\\u0142owe dane wej\\u015Bciowe: oczekiwano \${stringifyPrimitive(issue2.values[0])}\`; - return \`Nieprawid\\u0142owa opcja: oczekiwano jednej z warto\\u015Bci \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`Za du\\u017Ca warto\\u015B\\u0107: oczekiwano, \\u017Ce \${issue2.origin ?? "warto\\u015B\\u0107"} b\\u0119dzie mie\\u0107 \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "element\\xF3w"}\`; - } - return \`Zbyt du\\u017C(y/a/e): oczekiwano, \\u017Ce \${issue2.origin ?? "warto\\u015B\\u0107"} b\\u0119dzie wynosi\\u0107 \${adj}\${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`Za ma\\u0142a warto\\u015B\\u0107: oczekiwano, \\u017Ce \${issue2.origin ?? "warto\\u015B\\u0107"} b\\u0119dzie mie\\u0107 \${adj}\${issue2.minimum.toString()} \${sizing.unit ?? "element\\xF3w"}\`; - } - return \`Zbyt ma\\u0142(y/a/e): oczekiwano, \\u017Ce \${issue2.origin ?? "warto\\u015B\\u0107"} b\\u0119dzie wynosi\\u0107 \${adj}\${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") return \`Nieprawid\\u0142owy ci\\u0105g znak\\xF3w: musi zaczyna\\u0107 si\\u0119 od "\${_issue.prefix}"\`; - if (_issue.format === "ends_with") return \`Nieprawid\\u0142owy ci\\u0105g znak\\xF3w: musi ko\\u0144czy\\u0107 si\\u0119 na "\${_issue.suffix}"\`; - if (_issue.format === "includes") return \`Nieprawid\\u0142owy ci\\u0105g znak\\xF3w: musi zawiera\\u0107 "\${_issue.includes}"\`; - if (_issue.format === "regex") return \`Nieprawid\\u0142owy ci\\u0105g znak\\xF3w: musi odpowiada\\u0107 wzorcowi \${_issue.pattern}\`; - return \`Nieprawid\\u0142ow(y/a/e) \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`Nieprawid\\u0142owa liczba: musi by\\u0107 wielokrotno\\u015Bci\\u0105 \${issue2.divisor}\`; - case "unrecognized_keys": - return \`Nierozpoznane klucze\${issue2.keys.length > 1 ? "s" : ""}: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`Nieprawid\\u0142owy klucz w \${issue2.origin}\`; - case "invalid_union": - return "Nieprawid\\u0142owe dane wej\\u015Bciowe"; - case "invalid_element": - return \`Nieprawid\\u0142owa warto\\u015B\\u0107 w \${issue2.origin}\`; - default: - return \`Nieprawid\\u0142owe dane wej\\u015Bciowe\`; - } - }; -}, "error"); -function pl_default() { - return { - localeError: error31() - }; -} -__name(pl_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/pt.js -var error32 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "caracteres", - verb: "ter" - }, - file: { - unit: "bytes", - verb: "ter" - }, - array: { - unit: "itens", - verb: "ter" - }, - set: { - unit: "itens", - verb: "ter" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "n\\xFAmero"; - } - case "object": { - if (Array.isArray(data)) { - return "array"; - } - if (data === null) { - return "nulo"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "padr\\xE3o", - email: "endere\\xE7o de e-mail", - url: "URL", - emoji: "emoji", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "data e hora ISO", - date: "data ISO", - time: "hora ISO", - duration: "dura\\xE7\\xE3o ISO", - ipv4: "endere\\xE7o IPv4", - ipv6: "endere\\xE7o IPv6", - cidrv4: "faixa de IPv4", - cidrv6: "faixa de IPv6", - base64: "texto codificado em base64", - base64url: "URL codificada em base64", - json_string: "texto JSON", - e164: "n\\xFAmero E.164", - jwt: "JWT", - template_literal: "entrada" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`Tipo inv\\xE1lido: esperado \${issue2.expected}, recebido \${parsedType7(issue2.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`Entrada inv\\xE1lida: esperado \${stringifyPrimitive(issue2.values[0])}\`; - return \`Op\\xE7\\xE3o inv\\xE1lida: esperada uma das \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`Muito grande: esperado que \${issue2.origin ?? "valor"} tivesse \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "elementos"}\`; - return \`Muito grande: esperado que \${issue2.origin ?? "valor"} fosse \${adj}\${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`Muito pequeno: esperado que \${issue2.origin} tivesse \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; - } - return \`Muito pequeno: esperado que \${issue2.origin} fosse \${adj}\${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") return \`Texto inv\\xE1lido: deve come\\xE7ar com "\${_issue.prefix}"\`; - if (_issue.format === "ends_with") return \`Texto inv\\xE1lido: deve terminar com "\${_issue.suffix}"\`; - if (_issue.format === "includes") return \`Texto inv\\xE1lido: deve incluir "\${_issue.includes}"\`; - if (_issue.format === "regex") return \`Texto inv\\xE1lido: deve corresponder ao padr\\xE3o \${_issue.pattern}\`; - return \`\${Nouns[_issue.format] ?? issue2.format} inv\\xE1lido\`; - } - case "not_multiple_of": - return \`N\\xFAmero inv\\xE1lido: deve ser m\\xFAltiplo de \${issue2.divisor}\`; - case "unrecognized_keys": - return \`Chave\${issue2.keys.length > 1 ? "s" : ""} desconhecida\${issue2.keys.length > 1 ? "s" : ""}: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`Chave inv\\xE1lida em \${issue2.origin}\`; - case "invalid_union": - return "Entrada inv\\xE1lida"; - case "invalid_element": - return \`Valor inv\\xE1lido em \${issue2.origin}\`; - default: - return \`Campo inv\\xE1lido\`; - } - }; -}, "error"); -function pt_default() { - return { - localeError: error32() - }; -} -__name(pt_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/ru.js -function getRussianPlural(count, one, few, many) { - const absCount = Math.abs(count); - const lastDigit = absCount % 10; - const lastTwoDigits = absCount % 100; - if (lastTwoDigits >= 11 && lastTwoDigits <= 19) { - return many; - } - if (lastDigit === 1) { - return one; - } - if (lastDigit >= 2 && lastDigit <= 4) { - return few; - } - return many; -} -__name(getRussianPlural, "getRussianPlural"); -var error33 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: { - one: "\\u0441\\u0438\\u043C\\u0432\\u043E\\u043B", - few: "\\u0441\\u0438\\u043C\\u0432\\u043E\\u043B\\u0430", - many: "\\u0441\\u0438\\u043C\\u0432\\u043E\\u043B\\u043E\\u0432" - }, - verb: "\\u0438\\u043C\\u0435\\u0442\\u044C" - }, - file: { - unit: { - one: "\\u0431\\u0430\\u0439\\u0442", - few: "\\u0431\\u0430\\u0439\\u0442\\u0430", - many: "\\u0431\\u0430\\u0439\\u0442" - }, - verb: "\\u0438\\u043C\\u0435\\u0442\\u044C" - }, - array: { - unit: { - one: "\\u044D\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442", - few: "\\u044D\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442\\u0430", - many: "\\u044D\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442\\u043E\\u0432" - }, - verb: "\\u0438\\u043C\\u0435\\u0442\\u044C" - }, - set: { - unit: { - one: "\\u044D\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442", - few: "\\u044D\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442\\u0430", - many: "\\u044D\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442\\u043E\\u0432" - }, - verb: "\\u0438\\u043C\\u0435\\u0442\\u044C" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "\\u0447\\u0438\\u0441\\u043B\\u043E"; - } - case "object": { - if (Array.isArray(data)) { - return "\\u043C\\u0430\\u0441\\u0441\\u0438\\u0432"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "\\u0432\\u0432\\u043E\\u0434", - email: "email \\u0430\\u0434\\u0440\\u0435\\u0441", - url: "URL", - emoji: "\\u044D\\u043C\\u043E\\u0434\\u0437\\u0438", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "ISO \\u0434\\u0430\\u0442\\u0430 \\u0438 \\u0432\\u0440\\u0435\\u043C\\u044F", - date: "ISO \\u0434\\u0430\\u0442\\u0430", - time: "ISO \\u0432\\u0440\\u0435\\u043C\\u044F", - duration: "ISO \\u0434\\u043B\\u0438\\u0442\\u0435\\u043B\\u044C\\u043D\\u043E\\u0441\\u0442\\u044C", - ipv4: "IPv4 \\u0430\\u0434\\u0440\\u0435\\u0441", - ipv6: "IPv6 \\u0430\\u0434\\u0440\\u0435\\u0441", - cidrv4: "IPv4 \\u0434\\u0438\\u0430\\u043F\\u0430\\u0437\\u043E\\u043D", - cidrv6: "IPv6 \\u0434\\u0438\\u0430\\u043F\\u0430\\u0437\\u043E\\u043D", - base64: "\\u0441\\u0442\\u0440\\u043E\\u043A\\u0430 \\u0432 \\u0444\\u043E\\u0440\\u043C\\u0430\\u0442\\u0435 base64", - base64url: "\\u0441\\u0442\\u0440\\u043E\\u043A\\u0430 \\u0432 \\u0444\\u043E\\u0440\\u043C\\u0430\\u0442\\u0435 base64url", - json_string: "JSON \\u0441\\u0442\\u0440\\u043E\\u043A\\u0430", - e164: "\\u043D\\u043E\\u043C\\u0435\\u0440 E.164", - jwt: "JWT", - template_literal: "\\u0432\\u0432\\u043E\\u0434" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`\\u041D\\u0435\\u0432\\u0435\\u0440\\u043D\\u044B\\u0439 \\u0432\\u0432\\u043E\\u0434: \\u043E\\u0436\\u0438\\u0434\\u0430\\u043B\\u043E\\u0441\\u044C \${issue2.expected}, \\u043F\\u043E\\u043B\\u0443\\u0447\\u0435\\u043D\\u043E \${parsedType7(issue2.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`\\u041D\\u0435\\u0432\\u0435\\u0440\\u043D\\u044B\\u0439 \\u0432\\u0432\\u043E\\u0434: \\u043E\\u0436\\u0438\\u0434\\u0430\\u043B\\u043E\\u0441\\u044C \${stringifyPrimitive(issue2.values[0])}\`; - return \`\\u041D\\u0435\\u0432\\u0435\\u0440\\u043D\\u044B\\u0439 \\u0432\\u0430\\u0440\\u0438\\u0430\\u043D\\u0442: \\u043E\\u0436\\u0438\\u0434\\u0430\\u043B\\u043E\\u0441\\u044C \\u043E\\u0434\\u043D\\u043E \\u0438\\u0437 \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) { - const maxValue = Number(issue2.maximum); - const unit = getRussianPlural(maxValue, sizing.unit.one, sizing.unit.few, sizing.unit.many); - return \`\\u0421\\u043B\\u0438\\u0448\\u043A\\u043E\\u043C \\u0431\\u043E\\u043B\\u044C\\u0448\\u043E\\u0435 \\u0437\\u043D\\u0430\\u0447\\u0435\\u043D\\u0438\\u0435: \\u043E\\u0436\\u0438\\u0434\\u0430\\u043B\\u043E\\u0441\\u044C, \\u0447\\u0442\\u043E \${issue2.origin ?? "\\u0437\\u043D\\u0430\\u0447\\u0435\\u043D\\u0438\\u0435"} \\u0431\\u0443\\u0434\\u0435\\u0442 \\u0438\\u043C\\u0435\\u0442\\u044C \${adj}\${issue2.maximum.toString()} \${unit}\`; - } - return \`\\u0421\\u043B\\u0438\\u0448\\u043A\\u043E\\u043C \\u0431\\u043E\\u043B\\u044C\\u0448\\u043E\\u0435 \\u0437\\u043D\\u0430\\u0447\\u0435\\u043D\\u0438\\u0435: \\u043E\\u0436\\u0438\\u0434\\u0430\\u043B\\u043E\\u0441\\u044C, \\u0447\\u0442\\u043E \${issue2.origin ?? "\\u0437\\u043D\\u0430\\u0447\\u0435\\u043D\\u0438\\u0435"} \\u0431\\u0443\\u0434\\u0435\\u0442 \${adj}\${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - const minValue = Number(issue2.minimum); - const unit = getRussianPlural(minValue, sizing.unit.one, sizing.unit.few, sizing.unit.many); - return \`\\u0421\\u043B\\u0438\\u0448\\u043A\\u043E\\u043C \\u043C\\u0430\\u043B\\u0435\\u043D\\u044C\\u043A\\u043E\\u0435 \\u0437\\u043D\\u0430\\u0447\\u0435\\u043D\\u0438\\u0435: \\u043E\\u0436\\u0438\\u0434\\u0430\\u043B\\u043E\\u0441\\u044C, \\u0447\\u0442\\u043E \${issue2.origin} \\u0431\\u0443\\u0434\\u0435\\u0442 \\u0438\\u043C\\u0435\\u0442\\u044C \${adj}\${issue2.minimum.toString()} \${unit}\`; - } - return \`\\u0421\\u043B\\u0438\\u0448\\u043A\\u043E\\u043C \\u043C\\u0430\\u043B\\u0435\\u043D\\u044C\\u043A\\u043E\\u0435 \\u0437\\u043D\\u0430\\u0447\\u0435\\u043D\\u0438\\u0435: \\u043E\\u0436\\u0438\\u0434\\u0430\\u043B\\u043E\\u0441\\u044C, \\u0447\\u0442\\u043E \${issue2.origin} \\u0431\\u0443\\u0434\\u0435\\u0442 \${adj}\${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") return \`\\u041D\\u0435\\u0432\\u0435\\u0440\\u043D\\u0430\\u044F \\u0441\\u0442\\u0440\\u043E\\u043A\\u0430: \\u0434\\u043E\\u043B\\u0436\\u043D\\u0430 \\u043D\\u0430\\u0447\\u0438\\u043D\\u0430\\u0442\\u044C\\u0441\\u044F \\u0441 "\${_issue.prefix}"\`; - if (_issue.format === "ends_with") return \`\\u041D\\u0435\\u0432\\u0435\\u0440\\u043D\\u0430\\u044F \\u0441\\u0442\\u0440\\u043E\\u043A\\u0430: \\u0434\\u043E\\u043B\\u0436\\u043D\\u0430 \\u0437\\u0430\\u043A\\u0430\\u043D\\u0447\\u0438\\u0432\\u0430\\u0442\\u044C\\u0441\\u044F \\u043D\\u0430 "\${_issue.suffix}"\`; - if (_issue.format === "includes") return \`\\u041D\\u0435\\u0432\\u0435\\u0440\\u043D\\u0430\\u044F \\u0441\\u0442\\u0440\\u043E\\u043A\\u0430: \\u0434\\u043E\\u043B\\u0436\\u043D\\u0430 \\u0441\\u043E\\u0434\\u0435\\u0440\\u0436\\u0430\\u0442\\u044C "\${_issue.includes}"\`; - if (_issue.format === "regex") return \`\\u041D\\u0435\\u0432\\u0435\\u0440\\u043D\\u0430\\u044F \\u0441\\u0442\\u0440\\u043E\\u043A\\u0430: \\u0434\\u043E\\u043B\\u0436\\u043D\\u0430 \\u0441\\u043E\\u043E\\u0442\\u0432\\u0435\\u0442\\u0441\\u0442\\u0432\\u043E\\u0432\\u0430\\u0442\\u044C \\u0448\\u0430\\u0431\\u043B\\u043E\\u043D\\u0443 \${_issue.pattern}\`; - return \`\\u041D\\u0435\\u0432\\u0435\\u0440\\u043D\\u044B\\u0439 \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`\\u041D\\u0435\\u0432\\u0435\\u0440\\u043D\\u043E\\u0435 \\u0447\\u0438\\u0441\\u043B\\u043E: \\u0434\\u043E\\u043B\\u0436\\u043D\\u043E \\u0431\\u044B\\u0442\\u044C \\u043A\\u0440\\u0430\\u0442\\u043D\\u044B\\u043C \${issue2.divisor}\`; - case "unrecognized_keys": - return \`\\u041D\\u0435\\u0440\\u0430\\u0441\\u043F\\u043E\\u0437\\u043D\\u0430\\u043D\\u043D\${issue2.keys.length > 1 ? "\\u044B\\u0435" : "\\u044B\\u0439"} \\u043A\\u043B\\u044E\\u0447\${issue2.keys.length > 1 ? "\\u0438" : ""}: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`\\u041D\\u0435\\u0432\\u0435\\u0440\\u043D\\u044B\\u0439 \\u043A\\u043B\\u044E\\u0447 \\u0432 \${issue2.origin}\`; - case "invalid_union": - return "\\u041D\\u0435\\u0432\\u0435\\u0440\\u043D\\u044B\\u0435 \\u0432\\u0445\\u043E\\u0434\\u043D\\u044B\\u0435 \\u0434\\u0430\\u043D\\u043D\\u044B\\u0435"; - case "invalid_element": - return \`\\u041D\\u0435\\u0432\\u0435\\u0440\\u043D\\u043E\\u0435 \\u0437\\u043D\\u0430\\u0447\\u0435\\u043D\\u0438\\u0435 \\u0432 \${issue2.origin}\`; - default: - return \`\\u041D\\u0435\\u0432\\u0435\\u0440\\u043D\\u044B\\u0435 \\u0432\\u0445\\u043E\\u0434\\u043D\\u044B\\u0435 \\u0434\\u0430\\u043D\\u043D\\u044B\\u0435\`; - } - }; -}, "error"); -function ru_default() { - return { - localeError: error33() - }; -} -__name(ru_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/sl.js -var error34 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "znakov", - verb: "imeti" - }, - file: { - unit: "bajtov", - verb: "imeti" - }, - array: { - unit: "elementov", - verb: "imeti" - }, - set: { - unit: "elementov", - verb: "imeti" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "\\u0161tevilo"; - } - case "object": { - if (Array.isArray(data)) { - return "tabela"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "vnos", - email: "e-po\\u0161tni naslov", - url: "URL", - emoji: "emoji", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "ISO datum in \\u010Das", - date: "ISO datum", - time: "ISO \\u010Das", - duration: "ISO trajanje", - ipv4: "IPv4 naslov", - ipv6: "IPv6 naslov", - cidrv4: "obseg IPv4", - cidrv6: "obseg IPv6", - base64: "base64 kodiran niz", - base64url: "base64url kodiran niz", - json_string: "JSON niz", - e164: "E.164 \\u0161tevilka", - jwt: "JWT", - template_literal: "vnos" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`Neveljaven vnos: pri\\u010Dakovano \${issue2.expected}, prejeto \${parsedType7(issue2.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`Neveljaven vnos: pri\\u010Dakovano \${stringifyPrimitive(issue2.values[0])}\`; - return \`Neveljavna mo\\u017Enost: pri\\u010Dakovano eno izmed \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`Preveliko: pri\\u010Dakovano, da bo \${issue2.origin ?? "vrednost"} imelo \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "elementov"}\`; - return \`Preveliko: pri\\u010Dakovano, da bo \${issue2.origin ?? "vrednost"} \${adj}\${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`Premajhno: pri\\u010Dakovano, da bo \${issue2.origin} imelo \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; - } - return \`Premajhno: pri\\u010Dakovano, da bo \${issue2.origin} \${adj}\${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") { - return \`Neveljaven niz: mora se za\\u010Deti z "\${_issue.prefix}"\`; - } - if (_issue.format === "ends_with") return \`Neveljaven niz: mora se kon\\u010Dati z "\${_issue.suffix}"\`; - if (_issue.format === "includes") return \`Neveljaven niz: mora vsebovati "\${_issue.includes}"\`; - if (_issue.format === "regex") return \`Neveljaven niz: mora ustrezati vzorcu \${_issue.pattern}\`; - return \`Neveljaven \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`Neveljavno \\u0161tevilo: mora biti ve\\u010Dkratnik \${issue2.divisor}\`; - case "unrecognized_keys": - return \`Neprepoznan\${issue2.keys.length > 1 ? "i klju\\u010Di" : " klju\\u010D"}: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`Neveljaven klju\\u010D v \${issue2.origin}\`; - case "invalid_union": - return "Neveljaven vnos"; - case "invalid_element": - return \`Neveljavna vrednost v \${issue2.origin}\`; - default: - return "Neveljaven vnos"; - } - }; -}, "error"); -function sl_default() { - return { - localeError: error34() - }; -} -__name(sl_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/sv.js -var error35 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "tecken", - verb: "att ha" - }, - file: { - unit: "bytes", - verb: "att ha" - }, - array: { - unit: "objekt", - verb: "att inneh\\xE5lla" - }, - set: { - unit: "objekt", - verb: "att inneh\\xE5lla" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "antal"; - } - case "object": { - if (Array.isArray(data)) { - return "lista"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "regulj\\xE4rt uttryck", - email: "e-postadress", - url: "URL", - emoji: "emoji", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "ISO-datum och tid", - date: "ISO-datum", - time: "ISO-tid", - duration: "ISO-varaktighet", - ipv4: "IPv4-intervall", - ipv6: "IPv6-intervall", - cidrv4: "IPv4-spektrum", - cidrv6: "IPv6-spektrum", - base64: "base64-kodad str\\xE4ng", - base64url: "base64url-kodad str\\xE4ng", - json_string: "JSON-str\\xE4ng", - e164: "E.164-nummer", - jwt: "JWT", - template_literal: "mall-literal" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`Ogiltig inmatning: f\\xF6rv\\xE4ntat \${issue2.expected}, fick \${parsedType7(issue2.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`Ogiltig inmatning: f\\xF6rv\\xE4ntat \${stringifyPrimitive(issue2.values[0])}\`; - return \`Ogiltigt val: f\\xF6rv\\xE4ntade en av \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`F\\xF6r stor(t): f\\xF6rv\\xE4ntade \${issue2.origin ?? "v\\xE4rdet"} att ha \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "element"}\`; - } - return \`F\\xF6r stor(t): f\\xF6rv\\xE4ntat \${issue2.origin ?? "v\\xE4rdet"} att ha \${adj}\${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`F\\xF6r lite(t): f\\xF6rv\\xE4ntade \${issue2.origin ?? "v\\xE4rdet"} att ha \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; - } - return \`F\\xF6r lite(t): f\\xF6rv\\xE4ntade \${issue2.origin ?? "v\\xE4rdet"} att ha \${adj}\${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") { - return \`Ogiltig str\\xE4ng: m\\xE5ste b\\xF6rja med "\${_issue.prefix}"\`; - } - if (_issue.format === "ends_with") return \`Ogiltig str\\xE4ng: m\\xE5ste sluta med "\${_issue.suffix}"\`; - if (_issue.format === "includes") return \`Ogiltig str\\xE4ng: m\\xE5ste inneh\\xE5lla "\${_issue.includes}"\`; - if (_issue.format === "regex") return \`Ogiltig str\\xE4ng: m\\xE5ste matcha m\\xF6nstret "\${_issue.pattern}"\`; - return \`Ogiltig(t) \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`Ogiltigt tal: m\\xE5ste vara en multipel av \${issue2.divisor}\`; - case "unrecognized_keys": - return \`\${issue2.keys.length > 1 ? "Ok\\xE4nda nycklar" : "Ok\\xE4nd nyckel"}: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`Ogiltig nyckel i \${issue2.origin ?? "v\\xE4rdet"}\`; - case "invalid_union": - return "Ogiltig input"; - case "invalid_element": - return \`Ogiltigt v\\xE4rde i \${issue2.origin ?? "v\\xE4rdet"}\`; - default: - return \`Ogiltig input\`; - } - }; -}, "error"); -function sv_default() { - return { - localeError: error35() - }; -} -__name(sv_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/ta.js -var error36 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "\\u0B8E\\u0BB4\\u0BC1\\u0BA4\\u0BCD\\u0BA4\\u0BC1\\u0B95\\u0BCD\\u0B95\\u0BB3\\u0BCD", - verb: "\\u0B95\\u0BCA\\u0BA3\\u0BCD\\u0B9F\\u0BBF\\u0BB0\\u0BC1\\u0B95\\u0BCD\\u0B95 \\u0BB5\\u0BC7\\u0BA3\\u0BCD\\u0B9F\\u0BC1\\u0BAE\\u0BCD" - }, - file: { - unit: "\\u0BAA\\u0BC8\\u0B9F\\u0BCD\\u0B9F\\u0BC1\\u0B95\\u0BB3\\u0BCD", - verb: "\\u0B95\\u0BCA\\u0BA3\\u0BCD\\u0B9F\\u0BBF\\u0BB0\\u0BC1\\u0B95\\u0BCD\\u0B95 \\u0BB5\\u0BC7\\u0BA3\\u0BCD\\u0B9F\\u0BC1\\u0BAE\\u0BCD" - }, - array: { - unit: "\\u0B89\\u0BB1\\u0BC1\\u0BAA\\u0BCD\\u0BAA\\u0BC1\\u0B95\\u0BB3\\u0BCD", - verb: "\\u0B95\\u0BCA\\u0BA3\\u0BCD\\u0B9F\\u0BBF\\u0BB0\\u0BC1\\u0B95\\u0BCD\\u0B95 \\u0BB5\\u0BC7\\u0BA3\\u0BCD\\u0B9F\\u0BC1\\u0BAE\\u0BCD" - }, - set: { - unit: "\\u0B89\\u0BB1\\u0BC1\\u0BAA\\u0BCD\\u0BAA\\u0BC1\\u0B95\\u0BB3\\u0BCD", - verb: "\\u0B95\\u0BCA\\u0BA3\\u0BCD\\u0B9F\\u0BBF\\u0BB0\\u0BC1\\u0B95\\u0BCD\\u0B95 \\u0BB5\\u0BC7\\u0BA3\\u0BCD\\u0B9F\\u0BC1\\u0BAE\\u0BCD" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "\\u0B8E\\u0BA3\\u0BCD \\u0B85\\u0BB2\\u0BCD\\u0BB2\\u0BBE\\u0BA4\\u0BA4\\u0BC1" : "\\u0B8E\\u0BA3\\u0BCD"; - } - case "object": { - if (Array.isArray(data)) { - return "\\u0B85\\u0BA3\\u0BBF"; - } - if (data === null) { - return "\\u0BB5\\u0BC6\\u0BB1\\u0BC1\\u0BAE\\u0BC8"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "\\u0B89\\u0BB3\\u0BCD\\u0BB3\\u0BC0\\u0B9F\\u0BC1", - email: "\\u0BAE\\u0BBF\\u0BA9\\u0BCD\\u0BA9\\u0B9E\\u0BCD\\u0B9A\\u0BB2\\u0BCD \\u0BAE\\u0BC1\\u0B95\\u0BB5\\u0BB0\\u0BBF", - url: "URL", - emoji: "emoji", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "ISO \\u0BA4\\u0BC7\\u0BA4\\u0BBF \\u0BA8\\u0BC7\\u0BB0\\u0BAE\\u0BCD", - date: "ISO \\u0BA4\\u0BC7\\u0BA4\\u0BBF", - time: "ISO \\u0BA8\\u0BC7\\u0BB0\\u0BAE\\u0BCD", - duration: "ISO \\u0B95\\u0BBE\\u0BB2 \\u0B85\\u0BB3\\u0BB5\\u0BC1", - ipv4: "IPv4 \\u0BAE\\u0BC1\\u0B95\\u0BB5\\u0BB0\\u0BBF", - ipv6: "IPv6 \\u0BAE\\u0BC1\\u0B95\\u0BB5\\u0BB0\\u0BBF", - cidrv4: "IPv4 \\u0BB5\\u0BB0\\u0BAE\\u0BCD\\u0BAA\\u0BC1", - cidrv6: "IPv6 \\u0BB5\\u0BB0\\u0BAE\\u0BCD\\u0BAA\\u0BC1", - base64: "base64-encoded \\u0B9A\\u0BB0\\u0BAE\\u0BCD", - base64url: "base64url-encoded \\u0B9A\\u0BB0\\u0BAE\\u0BCD", - json_string: "JSON \\u0B9A\\u0BB0\\u0BAE\\u0BCD", - e164: "E.164 \\u0B8E\\u0BA3\\u0BCD", - jwt: "JWT", - template_literal: "input" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`\\u0BA4\\u0BB5\\u0BB1\\u0BBE\\u0BA9 \\u0B89\\u0BB3\\u0BCD\\u0BB3\\u0BC0\\u0B9F\\u0BC1: \\u0B8E\\u0BA4\\u0BBF\\u0BB0\\u0BCD\\u0BAA\\u0BBE\\u0BB0\\u0BCD\\u0B95\\u0BCD\\u0B95\\u0BAA\\u0BCD\\u0BAA\\u0B9F\\u0BCD\\u0B9F\\u0BA4\\u0BC1 \${issue2.expected}, \\u0BAA\\u0BC6\\u0BB1\\u0BAA\\u0BCD\\u0BAA\\u0B9F\\u0BCD\\u0B9F\\u0BA4\\u0BC1 \${parsedType7(issue2.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`\\u0BA4\\u0BB5\\u0BB1\\u0BBE\\u0BA9 \\u0B89\\u0BB3\\u0BCD\\u0BB3\\u0BC0\\u0B9F\\u0BC1: \\u0B8E\\u0BA4\\u0BBF\\u0BB0\\u0BCD\\u0BAA\\u0BBE\\u0BB0\\u0BCD\\u0B95\\u0BCD\\u0B95\\u0BAA\\u0BCD\\u0BAA\\u0B9F\\u0BCD\\u0B9F\\u0BA4\\u0BC1 \${stringifyPrimitive(issue2.values[0])}\`; - return \`\\u0BA4\\u0BB5\\u0BB1\\u0BBE\\u0BA9 \\u0BB5\\u0BBF\\u0BB0\\u0BC1\\u0BAA\\u0BCD\\u0BAA\\u0BAE\\u0BCD: \\u0B8E\\u0BA4\\u0BBF\\u0BB0\\u0BCD\\u0BAA\\u0BBE\\u0BB0\\u0BCD\\u0B95\\u0BCD\\u0B95\\u0BAA\\u0BCD\\u0BAA\\u0B9F\\u0BCD\\u0B9F\\u0BA4\\u0BC1 \${joinValues(issue2.values, "|")} \\u0B87\\u0BB2\\u0BCD \\u0B92\\u0BA9\\u0BCD\\u0BB1\\u0BC1\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`\\u0BAE\\u0BBF\\u0B95 \\u0BAA\\u0BC6\\u0BB0\\u0BBF\\u0BAF\\u0BA4\\u0BC1: \\u0B8E\\u0BA4\\u0BBF\\u0BB0\\u0BCD\\u0BAA\\u0BBE\\u0BB0\\u0BCD\\u0B95\\u0BCD\\u0B95\\u0BAA\\u0BCD\\u0BAA\\u0B9F\\u0BCD\\u0B9F\\u0BA4\\u0BC1 \${issue2.origin ?? "\\u0BAE\\u0BA4\\u0BBF\\u0BAA\\u0BCD\\u0BAA\\u0BC1"} \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "\\u0B89\\u0BB1\\u0BC1\\u0BAA\\u0BCD\\u0BAA\\u0BC1\\u0B95\\u0BB3\\u0BCD"} \\u0B86\\u0B95 \\u0B87\\u0BB0\\u0BC1\\u0B95\\u0BCD\\u0B95 \\u0BB5\\u0BC7\\u0BA3\\u0BCD\\u0B9F\\u0BC1\\u0BAE\\u0BCD\`; - } - return \`\\u0BAE\\u0BBF\\u0B95 \\u0BAA\\u0BC6\\u0BB0\\u0BBF\\u0BAF\\u0BA4\\u0BC1: \\u0B8E\\u0BA4\\u0BBF\\u0BB0\\u0BCD\\u0BAA\\u0BBE\\u0BB0\\u0BCD\\u0B95\\u0BCD\\u0B95\\u0BAA\\u0BCD\\u0BAA\\u0B9F\\u0BCD\\u0B9F\\u0BA4\\u0BC1 \${issue2.origin ?? "\\u0BAE\\u0BA4\\u0BBF\\u0BAA\\u0BCD\\u0BAA\\u0BC1"} \${adj}\${issue2.maximum.toString()} \\u0B86\\u0B95 \\u0B87\\u0BB0\\u0BC1\\u0B95\\u0BCD\\u0B95 \\u0BB5\\u0BC7\\u0BA3\\u0BCD\\u0B9F\\u0BC1\\u0BAE\\u0BCD\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`\\u0BAE\\u0BBF\\u0B95\\u0B9A\\u0BCD \\u0B9A\\u0BBF\\u0BB1\\u0BBF\\u0BAF\\u0BA4\\u0BC1: \\u0B8E\\u0BA4\\u0BBF\\u0BB0\\u0BCD\\u0BAA\\u0BBE\\u0BB0\\u0BCD\\u0B95\\u0BCD\\u0B95\\u0BAA\\u0BCD\\u0BAA\\u0B9F\\u0BCD\\u0B9F\\u0BA4\\u0BC1 \${issue2.origin} \${adj}\${issue2.minimum.toString()} \${sizing.unit} \\u0B86\\u0B95 \\u0B87\\u0BB0\\u0BC1\\u0B95\\u0BCD\\u0B95 \\u0BB5\\u0BC7\\u0BA3\\u0BCD\\u0B9F\\u0BC1\\u0BAE\\u0BCD\`; - } - return \`\\u0BAE\\u0BBF\\u0B95\\u0B9A\\u0BCD \\u0B9A\\u0BBF\\u0BB1\\u0BBF\\u0BAF\\u0BA4\\u0BC1: \\u0B8E\\u0BA4\\u0BBF\\u0BB0\\u0BCD\\u0BAA\\u0BBE\\u0BB0\\u0BCD\\u0B95\\u0BCD\\u0B95\\u0BAA\\u0BCD\\u0BAA\\u0B9F\\u0BCD\\u0B9F\\u0BA4\\u0BC1 \${issue2.origin} \${adj}\${issue2.minimum.toString()} \\u0B86\\u0B95 \\u0B87\\u0BB0\\u0BC1\\u0B95\\u0BCD\\u0B95 \\u0BB5\\u0BC7\\u0BA3\\u0BCD\\u0B9F\\u0BC1\\u0BAE\\u0BCD\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") return \`\\u0BA4\\u0BB5\\u0BB1\\u0BBE\\u0BA9 \\u0B9A\\u0BB0\\u0BAE\\u0BCD: "\${_issue.prefix}" \\u0B87\\u0BB2\\u0BCD \\u0BA4\\u0BCA\\u0B9F\\u0B99\\u0BCD\\u0B95 \\u0BB5\\u0BC7\\u0BA3\\u0BCD\\u0B9F\\u0BC1\\u0BAE\\u0BCD\`; - if (_issue.format === "ends_with") return \`\\u0BA4\\u0BB5\\u0BB1\\u0BBE\\u0BA9 \\u0B9A\\u0BB0\\u0BAE\\u0BCD: "\${_issue.suffix}" \\u0B87\\u0BB2\\u0BCD \\u0BAE\\u0BC1\\u0B9F\\u0BBF\\u0BB5\\u0B9F\\u0BC8\\u0BAF \\u0BB5\\u0BC7\\u0BA3\\u0BCD\\u0B9F\\u0BC1\\u0BAE\\u0BCD\`; - if (_issue.format === "includes") return \`\\u0BA4\\u0BB5\\u0BB1\\u0BBE\\u0BA9 \\u0B9A\\u0BB0\\u0BAE\\u0BCD: "\${_issue.includes}" \\u0B90 \\u0B89\\u0BB3\\u0BCD\\u0BB3\\u0B9F\\u0B95\\u0BCD\\u0B95 \\u0BB5\\u0BC7\\u0BA3\\u0BCD\\u0B9F\\u0BC1\\u0BAE\\u0BCD\`; - if (_issue.format === "regex") return \`\\u0BA4\\u0BB5\\u0BB1\\u0BBE\\u0BA9 \\u0B9A\\u0BB0\\u0BAE\\u0BCD: \${_issue.pattern} \\u0BAE\\u0BC1\\u0BB1\\u0BC8\\u0BAA\\u0BBE\\u0B9F\\u0BCD\\u0B9F\\u0BC1\\u0B9F\\u0BA9\\u0BCD \\u0BAA\\u0BCA\\u0BB0\\u0BC1\\u0BA8\\u0BCD\\u0BA4 \\u0BB5\\u0BC7\\u0BA3\\u0BCD\\u0B9F\\u0BC1\\u0BAE\\u0BCD\`; - return \`\\u0BA4\\u0BB5\\u0BB1\\u0BBE\\u0BA9 \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`\\u0BA4\\u0BB5\\u0BB1\\u0BBE\\u0BA9 \\u0B8E\\u0BA3\\u0BCD: \${issue2.divisor} \\u0B87\\u0BA9\\u0BCD \\u0BAA\\u0BB2\\u0BAE\\u0BBE\\u0B95 \\u0B87\\u0BB0\\u0BC1\\u0B95\\u0BCD\\u0B95 \\u0BB5\\u0BC7\\u0BA3\\u0BCD\\u0B9F\\u0BC1\\u0BAE\\u0BCD\`; - case "unrecognized_keys": - return \`\\u0B85\\u0B9F\\u0BC8\\u0BAF\\u0BBE\\u0BB3\\u0BAE\\u0BCD \\u0BA4\\u0BC6\\u0BB0\\u0BBF\\u0BAF\\u0BBE\\u0BA4 \\u0BB5\\u0BBF\\u0B9A\\u0BC8\${issue2.keys.length > 1 ? "\\u0B95\\u0BB3\\u0BCD" : ""}: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`\${issue2.origin} \\u0B87\\u0BB2\\u0BCD \\u0BA4\\u0BB5\\u0BB1\\u0BBE\\u0BA9 \\u0BB5\\u0BBF\\u0B9A\\u0BC8\`; - case "invalid_union": - return "\\u0BA4\\u0BB5\\u0BB1\\u0BBE\\u0BA9 \\u0B89\\u0BB3\\u0BCD\\u0BB3\\u0BC0\\u0B9F\\u0BC1"; - case "invalid_element": - return \`\${issue2.origin} \\u0B87\\u0BB2\\u0BCD \\u0BA4\\u0BB5\\u0BB1\\u0BBE\\u0BA9 \\u0BAE\\u0BA4\\u0BBF\\u0BAA\\u0BCD\\u0BAA\\u0BC1\`; - default: - return \`\\u0BA4\\u0BB5\\u0BB1\\u0BBE\\u0BA9 \\u0B89\\u0BB3\\u0BCD\\u0BB3\\u0BC0\\u0B9F\\u0BC1\`; - } - }; -}, "error"); -function ta_default() { - return { - localeError: error36() - }; -} -__name(ta_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/th.js -var error37 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "\\u0E15\\u0E31\\u0E27\\u0E2D\\u0E31\\u0E01\\u0E29\\u0E23", - verb: "\\u0E04\\u0E27\\u0E23\\u0E21\\u0E35" - }, - file: { - unit: "\\u0E44\\u0E1A\\u0E15\\u0E4C", - verb: "\\u0E04\\u0E27\\u0E23\\u0E21\\u0E35" - }, - array: { - unit: "\\u0E23\\u0E32\\u0E22\\u0E01\\u0E32\\u0E23", - verb: "\\u0E04\\u0E27\\u0E23\\u0E21\\u0E35" - }, - set: { - unit: "\\u0E23\\u0E32\\u0E22\\u0E01\\u0E32\\u0E23", - verb: "\\u0E04\\u0E27\\u0E23\\u0E21\\u0E35" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "\\u0E44\\u0E21\\u0E48\\u0E43\\u0E0A\\u0E48\\u0E15\\u0E31\\u0E27\\u0E40\\u0E25\\u0E02 (NaN)" : "\\u0E15\\u0E31\\u0E27\\u0E40\\u0E25\\u0E02"; - } - case "object": { - if (Array.isArray(data)) { - return "\\u0E2D\\u0E32\\u0E23\\u0E4C\\u0E40\\u0E23\\u0E22\\u0E4C (Array)"; - } - if (data === null) { - return "\\u0E44\\u0E21\\u0E48\\u0E21\\u0E35\\u0E04\\u0E48\\u0E32 (null)"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "\\u0E02\\u0E49\\u0E2D\\u0E21\\u0E39\\u0E25\\u0E17\\u0E35\\u0E48\\u0E1B\\u0E49\\u0E2D\\u0E19", - email: "\\u0E17\\u0E35\\u0E48\\u0E2D\\u0E22\\u0E39\\u0E48\\u0E2D\\u0E35\\u0E40\\u0E21\\u0E25", - url: "URL", - emoji: "\\u0E2D\\u0E34\\u0E42\\u0E21\\u0E08\\u0E34", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "\\u0E27\\u0E31\\u0E19\\u0E17\\u0E35\\u0E48\\u0E40\\u0E27\\u0E25\\u0E32\\u0E41\\u0E1A\\u0E1A ISO", - date: "\\u0E27\\u0E31\\u0E19\\u0E17\\u0E35\\u0E48\\u0E41\\u0E1A\\u0E1A ISO", - time: "\\u0E40\\u0E27\\u0E25\\u0E32\\u0E41\\u0E1A\\u0E1A ISO", - duration: "\\u0E0A\\u0E48\\u0E27\\u0E07\\u0E40\\u0E27\\u0E25\\u0E32\\u0E41\\u0E1A\\u0E1A ISO", - ipv4: "\\u0E17\\u0E35\\u0E48\\u0E2D\\u0E22\\u0E39\\u0E48 IPv4", - ipv6: "\\u0E17\\u0E35\\u0E48\\u0E2D\\u0E22\\u0E39\\u0E48 IPv6", - cidrv4: "\\u0E0A\\u0E48\\u0E27\\u0E07 IP \\u0E41\\u0E1A\\u0E1A IPv4", - cidrv6: "\\u0E0A\\u0E48\\u0E27\\u0E07 IP \\u0E41\\u0E1A\\u0E1A IPv6", - base64: "\\u0E02\\u0E49\\u0E2D\\u0E04\\u0E27\\u0E32\\u0E21\\u0E41\\u0E1A\\u0E1A Base64", - base64url: "\\u0E02\\u0E49\\u0E2D\\u0E04\\u0E27\\u0E32\\u0E21\\u0E41\\u0E1A\\u0E1A Base64 \\u0E2A\\u0E33\\u0E2B\\u0E23\\u0E31\\u0E1A URL", - json_string: "\\u0E02\\u0E49\\u0E2D\\u0E04\\u0E27\\u0E32\\u0E21\\u0E41\\u0E1A\\u0E1A JSON", - e164: "\\u0E40\\u0E1A\\u0E2D\\u0E23\\u0E4C\\u0E42\\u0E17\\u0E23\\u0E28\\u0E31\\u0E1E\\u0E17\\u0E4C\\u0E23\\u0E30\\u0E2B\\u0E27\\u0E48\\u0E32\\u0E07\\u0E1B\\u0E23\\u0E30\\u0E40\\u0E17\\u0E28 (E.164)", - jwt: "\\u0E42\\u0E17\\u0E40\\u0E04\\u0E19 JWT", - template_literal: "\\u0E02\\u0E49\\u0E2D\\u0E21\\u0E39\\u0E25\\u0E17\\u0E35\\u0E48\\u0E1B\\u0E49\\u0E2D\\u0E19" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`\\u0E1B\\u0E23\\u0E30\\u0E40\\u0E20\\u0E17\\u0E02\\u0E49\\u0E2D\\u0E21\\u0E39\\u0E25\\u0E44\\u0E21\\u0E48\\u0E16\\u0E39\\u0E01\\u0E15\\u0E49\\u0E2D\\u0E07: \\u0E04\\u0E27\\u0E23\\u0E40\\u0E1B\\u0E47\\u0E19 \${issue2.expected} \\u0E41\\u0E15\\u0E48\\u0E44\\u0E14\\u0E49\\u0E23\\u0E31\\u0E1A \${parsedType7(issue2.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`\\u0E04\\u0E48\\u0E32\\u0E44\\u0E21\\u0E48\\u0E16\\u0E39\\u0E01\\u0E15\\u0E49\\u0E2D\\u0E07: \\u0E04\\u0E27\\u0E23\\u0E40\\u0E1B\\u0E47\\u0E19 \${stringifyPrimitive(issue2.values[0])}\`; - return \`\\u0E15\\u0E31\\u0E27\\u0E40\\u0E25\\u0E37\\u0E2D\\u0E01\\u0E44\\u0E21\\u0E48\\u0E16\\u0E39\\u0E01\\u0E15\\u0E49\\u0E2D\\u0E07: \\u0E04\\u0E27\\u0E23\\u0E40\\u0E1B\\u0E47\\u0E19\\u0E2B\\u0E19\\u0E36\\u0E48\\u0E07\\u0E43\\u0E19 \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "\\u0E44\\u0E21\\u0E48\\u0E40\\u0E01\\u0E34\\u0E19" : "\\u0E19\\u0E49\\u0E2D\\u0E22\\u0E01\\u0E27\\u0E48\\u0E32"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`\\u0E40\\u0E01\\u0E34\\u0E19\\u0E01\\u0E33\\u0E2B\\u0E19\\u0E14: \${issue2.origin ?? "\\u0E04\\u0E48\\u0E32"} \\u0E04\\u0E27\\u0E23\\u0E21\\u0E35\${adj} \${issue2.maximum.toString()} \${sizing.unit ?? "\\u0E23\\u0E32\\u0E22\\u0E01\\u0E32\\u0E23"}\`; - return \`\\u0E40\\u0E01\\u0E34\\u0E19\\u0E01\\u0E33\\u0E2B\\u0E19\\u0E14: \${issue2.origin ?? "\\u0E04\\u0E48\\u0E32"} \\u0E04\\u0E27\\u0E23\\u0E21\\u0E35\${adj} \${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? "\\u0E2D\\u0E22\\u0E48\\u0E32\\u0E07\\u0E19\\u0E49\\u0E2D\\u0E22" : "\\u0E21\\u0E32\\u0E01\\u0E01\\u0E27\\u0E48\\u0E32"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`\\u0E19\\u0E49\\u0E2D\\u0E22\\u0E01\\u0E27\\u0E48\\u0E32\\u0E01\\u0E33\\u0E2B\\u0E19\\u0E14: \${issue2.origin} \\u0E04\\u0E27\\u0E23\\u0E21\\u0E35\${adj} \${issue2.minimum.toString()} \${sizing.unit}\`; - } - return \`\\u0E19\\u0E49\\u0E2D\\u0E22\\u0E01\\u0E27\\u0E48\\u0E32\\u0E01\\u0E33\\u0E2B\\u0E19\\u0E14: \${issue2.origin} \\u0E04\\u0E27\\u0E23\\u0E21\\u0E35\${adj} \${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") { - return \`\\u0E23\\u0E39\\u0E1B\\u0E41\\u0E1A\\u0E1A\\u0E44\\u0E21\\u0E48\\u0E16\\u0E39\\u0E01\\u0E15\\u0E49\\u0E2D\\u0E07: \\u0E02\\u0E49\\u0E2D\\u0E04\\u0E27\\u0E32\\u0E21\\u0E15\\u0E49\\u0E2D\\u0E07\\u0E02\\u0E36\\u0E49\\u0E19\\u0E15\\u0E49\\u0E19\\u0E14\\u0E49\\u0E27\\u0E22 "\${_issue.prefix}"\`; - } - if (_issue.format === "ends_with") return \`\\u0E23\\u0E39\\u0E1B\\u0E41\\u0E1A\\u0E1A\\u0E44\\u0E21\\u0E48\\u0E16\\u0E39\\u0E01\\u0E15\\u0E49\\u0E2D\\u0E07: \\u0E02\\u0E49\\u0E2D\\u0E04\\u0E27\\u0E32\\u0E21\\u0E15\\u0E49\\u0E2D\\u0E07\\u0E25\\u0E07\\u0E17\\u0E49\\u0E32\\u0E22\\u0E14\\u0E49\\u0E27\\u0E22 "\${_issue.suffix}"\`; - if (_issue.format === "includes") return \`\\u0E23\\u0E39\\u0E1B\\u0E41\\u0E1A\\u0E1A\\u0E44\\u0E21\\u0E48\\u0E16\\u0E39\\u0E01\\u0E15\\u0E49\\u0E2D\\u0E07: \\u0E02\\u0E49\\u0E2D\\u0E04\\u0E27\\u0E32\\u0E21\\u0E15\\u0E49\\u0E2D\\u0E07\\u0E21\\u0E35 "\${_issue.includes}" \\u0E2D\\u0E22\\u0E39\\u0E48\\u0E43\\u0E19\\u0E02\\u0E49\\u0E2D\\u0E04\\u0E27\\u0E32\\u0E21\`; - if (_issue.format === "regex") return \`\\u0E23\\u0E39\\u0E1B\\u0E41\\u0E1A\\u0E1A\\u0E44\\u0E21\\u0E48\\u0E16\\u0E39\\u0E01\\u0E15\\u0E49\\u0E2D\\u0E07: \\u0E15\\u0E49\\u0E2D\\u0E07\\u0E15\\u0E23\\u0E07\\u0E01\\u0E31\\u0E1A\\u0E23\\u0E39\\u0E1B\\u0E41\\u0E1A\\u0E1A\\u0E17\\u0E35\\u0E48\\u0E01\\u0E33\\u0E2B\\u0E19\\u0E14 \${_issue.pattern}\`; - return \`\\u0E23\\u0E39\\u0E1B\\u0E41\\u0E1A\\u0E1A\\u0E44\\u0E21\\u0E48\\u0E16\\u0E39\\u0E01\\u0E15\\u0E49\\u0E2D\\u0E07: \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`\\u0E15\\u0E31\\u0E27\\u0E40\\u0E25\\u0E02\\u0E44\\u0E21\\u0E48\\u0E16\\u0E39\\u0E01\\u0E15\\u0E49\\u0E2D\\u0E07: \\u0E15\\u0E49\\u0E2D\\u0E07\\u0E40\\u0E1B\\u0E47\\u0E19\\u0E08\\u0E33\\u0E19\\u0E27\\u0E19\\u0E17\\u0E35\\u0E48\\u0E2B\\u0E32\\u0E23\\u0E14\\u0E49\\u0E27\\u0E22 \${issue2.divisor} \\u0E44\\u0E14\\u0E49\\u0E25\\u0E07\\u0E15\\u0E31\\u0E27\`; - case "unrecognized_keys": - return \`\\u0E1E\\u0E1A\\u0E04\\u0E35\\u0E22\\u0E4C\\u0E17\\u0E35\\u0E48\\u0E44\\u0E21\\u0E48\\u0E23\\u0E39\\u0E49\\u0E08\\u0E31\\u0E01: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`\\u0E04\\u0E35\\u0E22\\u0E4C\\u0E44\\u0E21\\u0E48\\u0E16\\u0E39\\u0E01\\u0E15\\u0E49\\u0E2D\\u0E07\\u0E43\\u0E19 \${issue2.origin}\`; - case "invalid_union": - return "\\u0E02\\u0E49\\u0E2D\\u0E21\\u0E39\\u0E25\\u0E44\\u0E21\\u0E48\\u0E16\\u0E39\\u0E01\\u0E15\\u0E49\\u0E2D\\u0E07: \\u0E44\\u0E21\\u0E48\\u0E15\\u0E23\\u0E07\\u0E01\\u0E31\\u0E1A\\u0E23\\u0E39\\u0E1B\\u0E41\\u0E1A\\u0E1A\\u0E22\\u0E39\\u0E40\\u0E19\\u0E35\\u0E22\\u0E19\\u0E17\\u0E35\\u0E48\\u0E01\\u0E33\\u0E2B\\u0E19\\u0E14\\u0E44\\u0E27\\u0E49"; - case "invalid_element": - return \`\\u0E02\\u0E49\\u0E2D\\u0E21\\u0E39\\u0E25\\u0E44\\u0E21\\u0E48\\u0E16\\u0E39\\u0E01\\u0E15\\u0E49\\u0E2D\\u0E07\\u0E43\\u0E19 \${issue2.origin}\`; - default: - return \`\\u0E02\\u0E49\\u0E2D\\u0E21\\u0E39\\u0E25\\u0E44\\u0E21\\u0E48\\u0E16\\u0E39\\u0E01\\u0E15\\u0E49\\u0E2D\\u0E07\`; - } - }; -}, "error"); -function th_default() { - return { - localeError: error37() - }; -} -__name(th_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/tr.js -var parsedType6 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "number"; - } - case "object": { - if (Array.isArray(data)) { - return "array"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; -}, "parsedType"); -var error38 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "karakter", - verb: "olmal\\u0131" - }, - file: { - unit: "bayt", - verb: "olmal\\u0131" - }, - array: { - unit: "\\xF6\\u011Fe", - verb: "olmal\\u0131" - }, - set: { - unit: "\\xF6\\u011Fe", - verb: "olmal\\u0131" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const Nouns = { - regex: "girdi", - email: "e-posta adresi", - url: "URL", - emoji: "emoji", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "ISO tarih ve saat", - date: "ISO tarih", - time: "ISO saat", - duration: "ISO s\\xFCre", - ipv4: "IPv4 adresi", - ipv6: "IPv6 adresi", - cidrv4: "IPv4 aral\\u0131\\u011F\\u0131", - cidrv6: "IPv6 aral\\u0131\\u011F\\u0131", - base64: "base64 ile \\u015Fifrelenmi\\u015F metin", - base64url: "base64url ile \\u015Fifrelenmi\\u015F metin", - json_string: "JSON dizesi", - e164: "E.164 say\\u0131s\\u0131", - jwt: "JWT", - template_literal: "\\u015Eablon dizesi" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`Ge\\xE7ersiz de\\u011Fer: beklenen \${issue2.expected}, al\\u0131nan \${parsedType6(issue2.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`Ge\\xE7ersiz de\\u011Fer: beklenen \${stringifyPrimitive(issue2.values[0])}\`; - return \`Ge\\xE7ersiz se\\xE7enek: a\\u015Fa\\u011F\\u0131dakilerden biri olmal\\u0131: \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`\\xC7ok b\\xFCy\\xFCk: beklenen \${issue2.origin ?? "de\\u011Fer"} \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "\\xF6\\u011Fe"}\`; - return \`\\xC7ok b\\xFCy\\xFCk: beklenen \${issue2.origin ?? "de\\u011Fer"} \${adj}\${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`\\xC7ok k\\xFC\\xE7\\xFCk: beklenen \${issue2.origin} \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; - return \`\\xC7ok k\\xFC\\xE7\\xFCk: beklenen \${issue2.origin} \${adj}\${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") return \`Ge\\xE7ersiz metin: "\${_issue.prefix}" ile ba\\u015Flamal\\u0131\`; - if (_issue.format === "ends_with") return \`Ge\\xE7ersiz metin: "\${_issue.suffix}" ile bitmeli\`; - if (_issue.format === "includes") return \`Ge\\xE7ersiz metin: "\${_issue.includes}" i\\xE7ermeli\`; - if (_issue.format === "regex") return \`Ge\\xE7ersiz metin: \${_issue.pattern} desenine uymal\\u0131\`; - return \`Ge\\xE7ersiz \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`Ge\\xE7ersiz say\\u0131: \${issue2.divisor} ile tam b\\xF6l\\xFCnebilmeli\`; - case "unrecognized_keys": - return \`Tan\\u0131nmayan anahtar\${issue2.keys.length > 1 ? "lar" : ""}: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`\${issue2.origin} i\\xE7inde ge\\xE7ersiz anahtar\`; - case "invalid_union": - return "Ge\\xE7ersiz de\\u011Fer"; - case "invalid_element": - return \`\${issue2.origin} i\\xE7inde ge\\xE7ersiz de\\u011Fer\`; - default: - return \`Ge\\xE7ersiz de\\u011Fer\`; - } - }; -}, "error"); -function tr_default() { - return { - localeError: error38() - }; -} -__name(tr_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/uk.js -var error39 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "\\u0441\\u0438\\u043C\\u0432\\u043E\\u043B\\u0456\\u0432", - verb: "\\u043C\\u0430\\u0442\\u0438\\u043C\\u0435" - }, - file: { - unit: "\\u0431\\u0430\\u0439\\u0442\\u0456\\u0432", - verb: "\\u043C\\u0430\\u0442\\u0438\\u043C\\u0435" - }, - array: { - unit: "\\u0435\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442\\u0456\\u0432", - verb: "\\u043C\\u0430\\u0442\\u0438\\u043C\\u0435" - }, - set: { - unit: "\\u0435\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442\\u0456\\u0432", - verb: "\\u043C\\u0430\\u0442\\u0438\\u043C\\u0435" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "\\u0447\\u0438\\u0441\\u043B\\u043E"; - } - case "object": { - if (Array.isArray(data)) { - return "\\u043C\\u0430\\u0441\\u0438\\u0432"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "\\u0432\\u0445\\u0456\\u0434\\u043D\\u0456 \\u0434\\u0430\\u043D\\u0456", - email: "\\u0430\\u0434\\u0440\\u0435\\u0441\\u0430 \\u0435\\u043B\\u0435\\u043A\\u0442\\u0440\\u043E\\u043D\\u043D\\u043E\\u0457 \\u043F\\u043E\\u0448\\u0442\\u0438", - url: "URL", - emoji: "\\u0435\\u043C\\u043E\\u0434\\u0437\\u0456", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "\\u0434\\u0430\\u0442\\u0430 \\u0442\\u0430 \\u0447\\u0430\\u0441 ISO", - date: "\\u0434\\u0430\\u0442\\u0430 ISO", - time: "\\u0447\\u0430\\u0441 ISO", - duration: "\\u0442\\u0440\\u0438\\u0432\\u0430\\u043B\\u0456\\u0441\\u0442\\u044C ISO", - ipv4: "\\u0430\\u0434\\u0440\\u0435\\u0441\\u0430 IPv4", - ipv6: "\\u0430\\u0434\\u0440\\u0435\\u0441\\u0430 IPv6", - cidrv4: "\\u0434\\u0456\\u0430\\u043F\\u0430\\u0437\\u043E\\u043D IPv4", - cidrv6: "\\u0434\\u0456\\u0430\\u043F\\u0430\\u0437\\u043E\\u043D IPv6", - base64: "\\u0440\\u044F\\u0434\\u043E\\u043A \\u0443 \\u043A\\u043E\\u0434\\u0443\\u0432\\u0430\\u043D\\u043D\\u0456 base64", - base64url: "\\u0440\\u044F\\u0434\\u043E\\u043A \\u0443 \\u043A\\u043E\\u0434\\u0443\\u0432\\u0430\\u043D\\u043D\\u0456 base64url", - json_string: "\\u0440\\u044F\\u0434\\u043E\\u043A JSON", - e164: "\\u043D\\u043E\\u043C\\u0435\\u0440 E.164", - jwt: "JWT", - template_literal: "\\u0432\\u0445\\u0456\\u0434\\u043D\\u0456 \\u0434\\u0430\\u043D\\u0456" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`\\u041D\\u0435\\u043F\\u0440\\u0430\\u0432\\u0438\\u043B\\u044C\\u043D\\u0456 \\u0432\\u0445\\u0456\\u0434\\u043D\\u0456 \\u0434\\u0430\\u043D\\u0456: \\u043E\\u0447\\u0456\\u043A\\u0443\\u0454\\u0442\\u044C\\u0441\\u044F \${issue2.expected}, \\u043E\\u0442\\u0440\\u0438\\u043C\\u0430\\u043D\\u043E \${parsedType7(issue2.input)}\`; - // return \`Неправильні вхідні дані: очікується \${issue.expected}, отримано \${util.getParsedType(issue.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`\\u041D\\u0435\\u043F\\u0440\\u0430\\u0432\\u0438\\u043B\\u044C\\u043D\\u0456 \\u0432\\u0445\\u0456\\u0434\\u043D\\u0456 \\u0434\\u0430\\u043D\\u0456: \\u043E\\u0447\\u0456\\u043A\\u0443\\u0454\\u0442\\u044C\\u0441\\u044F \${stringifyPrimitive(issue2.values[0])}\`; - return \`\\u041D\\u0435\\u043F\\u0440\\u0430\\u0432\\u0438\\u043B\\u044C\\u043D\\u0430 \\u043E\\u043F\\u0446\\u0456\\u044F: \\u043E\\u0447\\u0456\\u043A\\u0443\\u0454\\u0442\\u044C\\u0441\\u044F \\u043E\\u0434\\u043D\\u0435 \\u0437 \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`\\u0417\\u0430\\u043D\\u0430\\u0434\\u0442\\u043E \\u0432\\u0435\\u043B\\u0438\\u043A\\u0435: \\u043E\\u0447\\u0456\\u043A\\u0443\\u0454\\u0442\\u044C\\u0441\\u044F, \\u0449\\u043E \${issue2.origin ?? "\\u0437\\u043D\\u0430\\u0447\\u0435\\u043D\\u043D\\u044F"} \${sizing.verb} \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "\\u0435\\u043B\\u0435\\u043C\\u0435\\u043D\\u0442\\u0456\\u0432"}\`; - return \`\\u0417\\u0430\\u043D\\u0430\\u0434\\u0442\\u043E \\u0432\\u0435\\u043B\\u0438\\u043A\\u0435: \\u043E\\u0447\\u0456\\u043A\\u0443\\u0454\\u0442\\u044C\\u0441\\u044F, \\u0449\\u043E \${issue2.origin ?? "\\u0437\\u043D\\u0430\\u0447\\u0435\\u043D\\u043D\\u044F"} \\u0431\\u0443\\u0434\\u0435 \${adj}\${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`\\u0417\\u0430\\u043D\\u0430\\u0434\\u0442\\u043E \\u043C\\u0430\\u043B\\u0435: \\u043E\\u0447\\u0456\\u043A\\u0443\\u0454\\u0442\\u044C\\u0441\\u044F, \\u0449\\u043E \${issue2.origin} \${sizing.verb} \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; - } - return \`\\u0417\\u0430\\u043D\\u0430\\u0434\\u0442\\u043E \\u043C\\u0430\\u043B\\u0435: \\u043E\\u0447\\u0456\\u043A\\u0443\\u0454\\u0442\\u044C\\u0441\\u044F, \\u0449\\u043E \${issue2.origin} \\u0431\\u0443\\u0434\\u0435 \${adj}\${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") return \`\\u041D\\u0435\\u043F\\u0440\\u0430\\u0432\\u0438\\u043B\\u044C\\u043D\\u0438\\u0439 \\u0440\\u044F\\u0434\\u043E\\u043A: \\u043F\\u043E\\u0432\\u0438\\u043D\\u0435\\u043D \\u043F\\u043E\\u0447\\u0438\\u043D\\u0430\\u0442\\u0438\\u0441\\u044F \\u0437 "\${_issue.prefix}"\`; - if (_issue.format === "ends_with") return \`\\u041D\\u0435\\u043F\\u0440\\u0430\\u0432\\u0438\\u043B\\u044C\\u043D\\u0438\\u0439 \\u0440\\u044F\\u0434\\u043E\\u043A: \\u043F\\u043E\\u0432\\u0438\\u043D\\u0435\\u043D \\u0437\\u0430\\u043A\\u0456\\u043D\\u0447\\u0443\\u0432\\u0430\\u0442\\u0438\\u0441\\u044F \\u043D\\u0430 "\${_issue.suffix}"\`; - if (_issue.format === "includes") return \`\\u041D\\u0435\\u043F\\u0440\\u0430\\u0432\\u0438\\u043B\\u044C\\u043D\\u0438\\u0439 \\u0440\\u044F\\u0434\\u043E\\u043A: \\u043F\\u043E\\u0432\\u0438\\u043D\\u0435\\u043D \\u043C\\u0456\\u0441\\u0442\\u0438\\u0442\\u0438 "\${_issue.includes}"\`; - if (_issue.format === "regex") return \`\\u041D\\u0435\\u043F\\u0440\\u0430\\u0432\\u0438\\u043B\\u044C\\u043D\\u0438\\u0439 \\u0440\\u044F\\u0434\\u043E\\u043A: \\u043F\\u043E\\u0432\\u0438\\u043D\\u0435\\u043D \\u0432\\u0456\\u0434\\u043F\\u043E\\u0432\\u0456\\u0434\\u0430\\u0442\\u0438 \\u0448\\u0430\\u0431\\u043B\\u043E\\u043D\\u0443 \${_issue.pattern}\`; - return \`\\u041D\\u0435\\u043F\\u0440\\u0430\\u0432\\u0438\\u043B\\u044C\\u043D\\u0438\\u0439 \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`\\u041D\\u0435\\u043F\\u0440\\u0430\\u0432\\u0438\\u043B\\u044C\\u043D\\u0435 \\u0447\\u0438\\u0441\\u043B\\u043E: \\u043F\\u043E\\u0432\\u0438\\u043D\\u043D\\u043E \\u0431\\u0443\\u0442\\u0438 \\u043A\\u0440\\u0430\\u0442\\u043D\\u0438\\u043C \${issue2.divisor}\`; - case "unrecognized_keys": - return \`\\u041D\\u0435\\u0440\\u043E\\u0437\\u043F\\u0456\\u0437\\u043D\\u0430\\u043D\\u0438\\u0439 \\u043A\\u043B\\u044E\\u0447\${issue2.keys.length > 1 ? "\\u0456" : ""}: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`\\u041D\\u0435\\u043F\\u0440\\u0430\\u0432\\u0438\\u043B\\u044C\\u043D\\u0438\\u0439 \\u043A\\u043B\\u044E\\u0447 \\u0443 \${issue2.origin}\`; - case "invalid_union": - return "\\u041D\\u0435\\u043F\\u0440\\u0430\\u0432\\u0438\\u043B\\u044C\\u043D\\u0456 \\u0432\\u0445\\u0456\\u0434\\u043D\\u0456 \\u0434\\u0430\\u043D\\u0456"; - case "invalid_element": - return \`\\u041D\\u0435\\u043F\\u0440\\u0430\\u0432\\u0438\\u043B\\u044C\\u043D\\u0435 \\u0437\\u043D\\u0430\\u0447\\u0435\\u043D\\u043D\\u044F \\u0443 \${issue2.origin}\`; - default: - return \`\\u041D\\u0435\\u043F\\u0440\\u0430\\u0432\\u0438\\u043B\\u044C\\u043D\\u0456 \\u0432\\u0445\\u0456\\u0434\\u043D\\u0456 \\u0434\\u0430\\u043D\\u0456\`; - } - }; -}, "error"); -function uk_default() { - return { - localeError: error39() - }; -} -__name(uk_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/ua.js -function ua_default() { - return uk_default(); -} -__name(ua_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/ur.js -var error40 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "\\u062D\\u0631\\u0648\\u0641", - verb: "\\u06C1\\u0648\\u0646\\u0627" - }, - file: { - unit: "\\u0628\\u0627\\u0626\\u0679\\u0633", - verb: "\\u06C1\\u0648\\u0646\\u0627" - }, - array: { - unit: "\\u0622\\u0626\\u0679\\u0645\\u0632", - verb: "\\u06C1\\u0648\\u0646\\u0627" - }, - set: { - unit: "\\u0622\\u0626\\u0679\\u0645\\u0632", - verb: "\\u06C1\\u0648\\u0646\\u0627" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "\\u0646\\u0645\\u0628\\u0631"; - } - case "object": { - if (Array.isArray(data)) { - return "\\u0622\\u0631\\u06D2"; - } - if (data === null) { - return "\\u0646\\u0644"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "\\u0627\\u0646 \\u067E\\u0679", - email: "\\u0627\\u06CC \\u0645\\u06CC\\u0644 \\u0627\\u06CC\\u0688\\u0631\\u06CC\\u0633", - url: "\\u06CC\\u0648 \\u0622\\u0631 \\u0627\\u06CC\\u0644", - emoji: "\\u0627\\u06CC\\u0645\\u0648\\u062C\\u06CC", - uuid: "\\u06CC\\u0648 \\u06CC\\u0648 \\u0622\\u0626\\u06CC \\u0688\\u06CC", - uuidv4: "\\u06CC\\u0648 \\u06CC\\u0648 \\u0622\\u0626\\u06CC \\u0688\\u06CC \\u0648\\u06CC 4", - uuidv6: "\\u06CC\\u0648 \\u06CC\\u0648 \\u0622\\u0626\\u06CC \\u0688\\u06CC \\u0648\\u06CC 6", - nanoid: "\\u0646\\u06CC\\u0646\\u0648 \\u0622\\u0626\\u06CC \\u0688\\u06CC", - guid: "\\u062C\\u06CC \\u06CC\\u0648 \\u0622\\u0626\\u06CC \\u0688\\u06CC", - cuid: "\\u0633\\u06CC \\u06CC\\u0648 \\u0622\\u0626\\u06CC \\u0688\\u06CC", - cuid2: "\\u0633\\u06CC \\u06CC\\u0648 \\u0622\\u0626\\u06CC \\u0688\\u06CC 2", - ulid: "\\u06CC\\u0648 \\u0627\\u06CC\\u0644 \\u0622\\u0626\\u06CC \\u0688\\u06CC", - xid: "\\u0627\\u06CC\\u06A9\\u0633 \\u0622\\u0626\\u06CC \\u0688\\u06CC", - ksuid: "\\u06A9\\u06D2 \\u0627\\u06CC\\u0633 \\u06CC\\u0648 \\u0622\\u0626\\u06CC \\u0688\\u06CC", - datetime: "\\u0622\\u0626\\u06CC \\u0627\\u06CC\\u0633 \\u0627\\u0648 \\u0688\\u06CC\\u0679 \\u0679\\u0627\\u0626\\u0645", - date: "\\u0622\\u0626\\u06CC \\u0627\\u06CC\\u0633 \\u0627\\u0648 \\u062A\\u0627\\u0631\\u06CC\\u062E", - time: "\\u0622\\u0626\\u06CC \\u0627\\u06CC\\u0633 \\u0627\\u0648 \\u0648\\u0642\\u062A", - duration: "\\u0622\\u0626\\u06CC \\u0627\\u06CC\\u0633 \\u0627\\u0648 \\u0645\\u062F\\u062A", - ipv4: "\\u0622\\u0626\\u06CC \\u067E\\u06CC \\u0648\\u06CC 4 \\u0627\\u06CC\\u0688\\u0631\\u06CC\\u0633", - ipv6: "\\u0622\\u0626\\u06CC \\u067E\\u06CC \\u0648\\u06CC 6 \\u0627\\u06CC\\u0688\\u0631\\u06CC\\u0633", - cidrv4: "\\u0622\\u0626\\u06CC \\u067E\\u06CC \\u0648\\u06CC 4 \\u0631\\u06CC\\u0646\\u062C", - cidrv6: "\\u0622\\u0626\\u06CC \\u067E\\u06CC \\u0648\\u06CC 6 \\u0631\\u06CC\\u0646\\u062C", - base64: "\\u0628\\u06CC\\u0633 64 \\u0627\\u0646 \\u06A9\\u0648\\u0688\\u0688 \\u0633\\u0679\\u0631\\u0646\\u06AF", - base64url: "\\u0628\\u06CC\\u0633 64 \\u06CC\\u0648 \\u0622\\u0631 \\u0627\\u06CC\\u0644 \\u0627\\u0646 \\u06A9\\u0648\\u0688\\u0688 \\u0633\\u0679\\u0631\\u0646\\u06AF", - json_string: "\\u062C\\u06D2 \\u0627\\u06CC\\u0633 \\u0627\\u0648 \\u0627\\u06CC\\u0646 \\u0633\\u0679\\u0631\\u0646\\u06AF", - e164: "\\u0627\\u06CC 164 \\u0646\\u0645\\u0628\\u0631", - jwt: "\\u062C\\u06D2 \\u0688\\u0628\\u0644\\u06CC\\u0648 \\u0679\\u06CC", - template_literal: "\\u0627\\u0646 \\u067E\\u0679" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`\\u063A\\u0644\\u0637 \\u0627\\u0646 \\u067E\\u0679: \${issue2.expected} \\u0645\\u062A\\u0648\\u0642\\u0639 \\u062A\\u06BE\\u0627\\u060C \${parsedType7(issue2.input)} \\u0645\\u0648\\u0635\\u0648\\u0644 \\u06C1\\u0648\\u0627\`; - case "invalid_value": - if (issue2.values.length === 1) return \`\\u063A\\u0644\\u0637 \\u0627\\u0646 \\u067E\\u0679: \${stringifyPrimitive(issue2.values[0])} \\u0645\\u062A\\u0648\\u0642\\u0639 \\u062A\\u06BE\\u0627\`; - return \`\\u063A\\u0644\\u0637 \\u0622\\u067E\\u0634\\u0646: \${joinValues(issue2.values, "|")} \\u0645\\u06CC\\u06BA \\u0633\\u06D2 \\u0627\\u06CC\\u06A9 \\u0645\\u062A\\u0648\\u0642\\u0639 \\u062A\\u06BE\\u0627\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`\\u0628\\u06C1\\u062A \\u0628\\u0691\\u0627: \${issue2.origin ?? "\\u0648\\u06CC\\u0644\\u06CC\\u0648"} \\u06A9\\u06D2 \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "\\u0639\\u0646\\u0627\\u0635\\u0631"} \\u06C1\\u0648\\u0646\\u06D2 \\u0645\\u062A\\u0648\\u0642\\u0639 \\u062A\\u06BE\\u06D2\`; - return \`\\u0628\\u06C1\\u062A \\u0628\\u0691\\u0627: \${issue2.origin ?? "\\u0648\\u06CC\\u0644\\u06CC\\u0648"} \\u06A9\\u0627 \${adj}\${issue2.maximum.toString()} \\u06C1\\u0648\\u0646\\u0627 \\u0645\\u062A\\u0648\\u0642\\u0639 \\u062A\\u06BE\\u0627\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`\\u0628\\u06C1\\u062A \\u0686\\u06BE\\u0648\\u0679\\u0627: \${issue2.origin} \\u06A9\\u06D2 \${adj}\${issue2.minimum.toString()} \${sizing.unit} \\u06C1\\u0648\\u0646\\u06D2 \\u0645\\u062A\\u0648\\u0642\\u0639 \\u062A\\u06BE\\u06D2\`; - } - return \`\\u0628\\u06C1\\u062A \\u0686\\u06BE\\u0648\\u0679\\u0627: \${issue2.origin} \\u06A9\\u0627 \${adj}\${issue2.minimum.toString()} \\u06C1\\u0648\\u0646\\u0627 \\u0645\\u062A\\u0648\\u0642\\u0639 \\u062A\\u06BE\\u0627\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") { - return \`\\u063A\\u0644\\u0637 \\u0633\\u0679\\u0631\\u0646\\u06AF: "\${_issue.prefix}" \\u0633\\u06D2 \\u0634\\u0631\\u0648\\u0639 \\u06C1\\u0648\\u0646\\u0627 \\u0686\\u0627\\u06C1\\u06CC\\u06D2\`; - } - if (_issue.format === "ends_with") return \`\\u063A\\u0644\\u0637 \\u0633\\u0679\\u0631\\u0646\\u06AF: "\${_issue.suffix}" \\u067E\\u0631 \\u062E\\u062A\\u0645 \\u06C1\\u0648\\u0646\\u0627 \\u0686\\u0627\\u06C1\\u06CC\\u06D2\`; - if (_issue.format === "includes") return \`\\u063A\\u0644\\u0637 \\u0633\\u0679\\u0631\\u0646\\u06AF: "\${_issue.includes}" \\u0634\\u0627\\u0645\\u0644 \\u06C1\\u0648\\u0646\\u0627 \\u0686\\u0627\\u06C1\\u06CC\\u06D2\`; - if (_issue.format === "regex") return \`\\u063A\\u0644\\u0637 \\u0633\\u0679\\u0631\\u0646\\u06AF: \\u067E\\u06CC\\u0679\\u0631\\u0646 \${_issue.pattern} \\u0633\\u06D2 \\u0645\\u06CC\\u0686 \\u06C1\\u0648\\u0646\\u0627 \\u0686\\u0627\\u06C1\\u06CC\\u06D2\`; - return \`\\u063A\\u0644\\u0637 \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`\\u063A\\u0644\\u0637 \\u0646\\u0645\\u0628\\u0631: \${issue2.divisor} \\u06A9\\u0627 \\u0645\\u0636\\u0627\\u0639\\u0641 \\u06C1\\u0648\\u0646\\u0627 \\u0686\\u0627\\u06C1\\u06CC\\u06D2\`; - case "unrecognized_keys": - return \`\\u063A\\u06CC\\u0631 \\u062A\\u0633\\u0644\\u06CC\\u0645 \\u0634\\u062F\\u06C1 \\u06A9\\u06CC\${issue2.keys.length > 1 ? "\\u0632" : ""}: \${joinValues(issue2.keys, "\\u060C ")}\`; - case "invalid_key": - return \`\${issue2.origin} \\u0645\\u06CC\\u06BA \\u063A\\u0644\\u0637 \\u06A9\\u06CC\`; - case "invalid_union": - return "\\u063A\\u0644\\u0637 \\u0627\\u0646 \\u067E\\u0679"; - case "invalid_element": - return \`\${issue2.origin} \\u0645\\u06CC\\u06BA \\u063A\\u0644\\u0637 \\u0648\\u06CC\\u0644\\u06CC\\u0648\`; - default: - return \`\\u063A\\u0644\\u0637 \\u0627\\u0646 \\u067E\\u0679\`; - } - }; -}, "error"); -function ur_default() { - return { - localeError: error40() - }; -} -__name(ur_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/vi.js -var error41 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "k\\xFD t\\u1EF1", - verb: "c\\xF3" - }, - file: { - unit: "byte", - verb: "c\\xF3" - }, - array: { - unit: "ph\\u1EA7n t\\u1EED", - verb: "c\\xF3" - }, - set: { - unit: "ph\\u1EA7n t\\u1EED", - verb: "c\\xF3" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "s\\u1ED1"; - } - case "object": { - if (Array.isArray(data)) { - return "m\\u1EA3ng"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "\\u0111\\u1EA7u v\\xE0o", - email: "\\u0111\\u1ECBa ch\\u1EC9 email", - url: "URL", - emoji: "emoji", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "ng\\xE0y gi\\u1EDD ISO", - date: "ng\\xE0y ISO", - time: "gi\\u1EDD ISO", - duration: "kho\\u1EA3ng th\\u1EDDi gian ISO", - ipv4: "\\u0111\\u1ECBa ch\\u1EC9 IPv4", - ipv6: "\\u0111\\u1ECBa ch\\u1EC9 IPv6", - cidrv4: "d\\u1EA3i IPv4", - cidrv6: "d\\u1EA3i IPv6", - base64: "chu\\u1ED7i m\\xE3 h\\xF3a base64", - base64url: "chu\\u1ED7i m\\xE3 h\\xF3a base64url", - json_string: "chu\\u1ED7i JSON", - e164: "s\\u1ED1 E.164", - jwt: "JWT", - template_literal: "\\u0111\\u1EA7u v\\xE0o" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`\\u0110\\u1EA7u v\\xE0o kh\\xF4ng h\\u1EE3p l\\u1EC7: mong \\u0111\\u1EE3i \${issue2.expected}, nh\\u1EADn \\u0111\\u01B0\\u1EE3c \${parsedType7(issue2.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`\\u0110\\u1EA7u v\\xE0o kh\\xF4ng h\\u1EE3p l\\u1EC7: mong \\u0111\\u1EE3i \${stringifyPrimitive(issue2.values[0])}\`; - return \`T\\xF9y ch\\u1ECDn kh\\xF4ng h\\u1EE3p l\\u1EC7: mong \\u0111\\u1EE3i m\\u1ED9t trong c\\xE1c gi\\xE1 tr\\u1ECB \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`Qu\\xE1 l\\u1EDBn: mong \\u0111\\u1EE3i \${issue2.origin ?? "gi\\xE1 tr\\u1ECB"} \${sizing.verb} \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "ph\\u1EA7n t\\u1EED"}\`; - return \`Qu\\xE1 l\\u1EDBn: mong \\u0111\\u1EE3i \${issue2.origin ?? "gi\\xE1 tr\\u1ECB"} \${adj}\${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`Qu\\xE1 nh\\u1ECF: mong \\u0111\\u1EE3i \${issue2.origin} \${sizing.verb} \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; - } - return \`Qu\\xE1 nh\\u1ECF: mong \\u0111\\u1EE3i \${issue2.origin} \${adj}\${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") return \`Chu\\u1ED7i kh\\xF4ng h\\u1EE3p l\\u1EC7: ph\\u1EA3i b\\u1EAFt \\u0111\\u1EA7u b\\u1EB1ng "\${_issue.prefix}"\`; - if (_issue.format === "ends_with") return \`Chu\\u1ED7i kh\\xF4ng h\\u1EE3p l\\u1EC7: ph\\u1EA3i k\\u1EBFt th\\xFAc b\\u1EB1ng "\${_issue.suffix}"\`; - if (_issue.format === "includes") return \`Chu\\u1ED7i kh\\xF4ng h\\u1EE3p l\\u1EC7: ph\\u1EA3i bao g\\u1ED3m "\${_issue.includes}"\`; - if (_issue.format === "regex") return \`Chu\\u1ED7i kh\\xF4ng h\\u1EE3p l\\u1EC7: ph\\u1EA3i kh\\u1EDBp v\\u1EDBi m\\u1EABu \${_issue.pattern}\`; - return \`\${Nouns[_issue.format] ?? issue2.format} kh\\xF4ng h\\u1EE3p l\\u1EC7\`; - } - case "not_multiple_of": - return \`S\\u1ED1 kh\\xF4ng h\\u1EE3p l\\u1EC7: ph\\u1EA3i l\\xE0 b\\u1ED9i s\\u1ED1 c\\u1EE7a \${issue2.divisor}\`; - case "unrecognized_keys": - return \`Kh\\xF3a kh\\xF4ng \\u0111\\u01B0\\u1EE3c nh\\u1EADn d\\u1EA1ng: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`Kh\\xF3a kh\\xF4ng h\\u1EE3p l\\u1EC7 trong \${issue2.origin}\`; - case "invalid_union": - return "\\u0110\\u1EA7u v\\xE0o kh\\xF4ng h\\u1EE3p l\\u1EC7"; - case "invalid_element": - return \`Gi\\xE1 tr\\u1ECB kh\\xF4ng h\\u1EE3p l\\u1EC7 trong \${issue2.origin}\`; - default: - return \`\\u0110\\u1EA7u v\\xE0o kh\\xF4ng h\\u1EE3p l\\u1EC7\`; - } - }; -}, "error"); -function vi_default() { - return { - localeError: error41() - }; -} -__name(vi_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/zh-CN.js -var error42 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "\\u5B57\\u7B26", - verb: "\\u5305\\u542B" - }, - file: { - unit: "\\u5B57\\u8282", - verb: "\\u5305\\u542B" - }, - array: { - unit: "\\u9879", - verb: "\\u5305\\u542B" - }, - set: { - unit: "\\u9879", - verb: "\\u5305\\u542B" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "\\u975E\\u6570\\u5B57(NaN)" : "\\u6570\\u5B57"; - } - case "object": { - if (Array.isArray(data)) { - return "\\u6570\\u7EC4"; - } - if (data === null) { - return "\\u7A7A\\u503C(null)"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "\\u8F93\\u5165", - email: "\\u7535\\u5B50\\u90AE\\u4EF6", - url: "URL", - emoji: "\\u8868\\u60C5\\u7B26\\u53F7", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "ISO\\u65E5\\u671F\\u65F6\\u95F4", - date: "ISO\\u65E5\\u671F", - time: "ISO\\u65F6\\u95F4", - duration: "ISO\\u65F6\\u957F", - ipv4: "IPv4\\u5730\\u5740", - ipv6: "IPv6\\u5730\\u5740", - cidrv4: "IPv4\\u7F51\\u6BB5", - cidrv6: "IPv6\\u7F51\\u6BB5", - base64: "base64\\u7F16\\u7801\\u5B57\\u7B26\\u4E32", - base64url: "base64url\\u7F16\\u7801\\u5B57\\u7B26\\u4E32", - json_string: "JSON\\u5B57\\u7B26\\u4E32", - e164: "E.164\\u53F7\\u7801", - jwt: "JWT", - template_literal: "\\u8F93\\u5165" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`\\u65E0\\u6548\\u8F93\\u5165\\uFF1A\\u671F\\u671B \${issue2.expected}\\uFF0C\\u5B9E\\u9645\\u63A5\\u6536 \${parsedType7(issue2.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`\\u65E0\\u6548\\u8F93\\u5165\\uFF1A\\u671F\\u671B \${stringifyPrimitive(issue2.values[0])}\`; - return \`\\u65E0\\u6548\\u9009\\u9879\\uFF1A\\u671F\\u671B\\u4EE5\\u4E0B\\u4E4B\\u4E00 \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`\\u6570\\u503C\\u8FC7\\u5927\\uFF1A\\u671F\\u671B \${issue2.origin ?? "\\u503C"} \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "\\u4E2A\\u5143\\u7D20"}\`; - return \`\\u6570\\u503C\\u8FC7\\u5927\\uFF1A\\u671F\\u671B \${issue2.origin ?? "\\u503C"} \${adj}\${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`\\u6570\\u503C\\u8FC7\\u5C0F\\uFF1A\\u671F\\u671B \${issue2.origin} \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; - } - return \`\\u6570\\u503C\\u8FC7\\u5C0F\\uFF1A\\u671F\\u671B \${issue2.origin} \${adj}\${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") return \`\\u65E0\\u6548\\u5B57\\u7B26\\u4E32\\uFF1A\\u5FC5\\u987B\\u4EE5 "\${_issue.prefix}" \\u5F00\\u5934\`; - if (_issue.format === "ends_with") return \`\\u65E0\\u6548\\u5B57\\u7B26\\u4E32\\uFF1A\\u5FC5\\u987B\\u4EE5 "\${_issue.suffix}" \\u7ED3\\u5C3E\`; - if (_issue.format === "includes") return \`\\u65E0\\u6548\\u5B57\\u7B26\\u4E32\\uFF1A\\u5FC5\\u987B\\u5305\\u542B "\${_issue.includes}"\`; - if (_issue.format === "regex") return \`\\u65E0\\u6548\\u5B57\\u7B26\\u4E32\\uFF1A\\u5FC5\\u987B\\u6EE1\\u8DB3\\u6B63\\u5219\\u8868\\u8FBE\\u5F0F \${_issue.pattern}\`; - return \`\\u65E0\\u6548\${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`\\u65E0\\u6548\\u6570\\u5B57\\uFF1A\\u5FC5\\u987B\\u662F \${issue2.divisor} \\u7684\\u500D\\u6570\`; - case "unrecognized_keys": - return \`\\u51FA\\u73B0\\u672A\\u77E5\\u7684\\u952E(key): \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`\${issue2.origin} \\u4E2D\\u7684\\u952E(key)\\u65E0\\u6548\`; - case "invalid_union": - return "\\u65E0\\u6548\\u8F93\\u5165"; - case "invalid_element": - return \`\${issue2.origin} \\u4E2D\\u5305\\u542B\\u65E0\\u6548\\u503C(value)\`; - default: - return \`\\u65E0\\u6548\\u8F93\\u5165\`; - } - }; -}, "error"); -function zh_CN_default() { - return { - localeError: error42() - }; -} -__name(zh_CN_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/zh-TW.js -var error43 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "\\u5B57\\u5143", - verb: "\\u64C1\\u6709" - }, - file: { - unit: "\\u4F4D\\u5143\\u7D44", - verb: "\\u64C1\\u6709" - }, - array: { - unit: "\\u9805\\u76EE", - verb: "\\u64C1\\u6709" - }, - set: { - unit: "\\u9805\\u76EE", - verb: "\\u64C1\\u6709" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "number"; - } - case "object": { - if (Array.isArray(data)) { - return "array"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "\\u8F38\\u5165", - email: "\\u90F5\\u4EF6\\u5730\\u5740", - url: "URL", - emoji: "emoji", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "ISO \\u65E5\\u671F\\u6642\\u9593", - date: "ISO \\u65E5\\u671F", - time: "ISO \\u6642\\u9593", - duration: "ISO \\u671F\\u9593", - ipv4: "IPv4 \\u4F4D\\u5740", - ipv6: "IPv6 \\u4F4D\\u5740", - cidrv4: "IPv4 \\u7BC4\\u570D", - cidrv6: "IPv6 \\u7BC4\\u570D", - base64: "base64 \\u7DE8\\u78BC\\u5B57\\u4E32", - base64url: "base64url \\u7DE8\\u78BC\\u5B57\\u4E32", - json_string: "JSON \\u5B57\\u4E32", - e164: "E.164 \\u6578\\u503C", - jwt: "JWT", - template_literal: "\\u8F38\\u5165" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`\\u7121\\u6548\\u7684\\u8F38\\u5165\\u503C\\uFF1A\\u9810\\u671F\\u70BA \${issue2.expected}\\uFF0C\\u4F46\\u6536\\u5230 \${parsedType7(issue2.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`\\u7121\\u6548\\u7684\\u8F38\\u5165\\u503C\\uFF1A\\u9810\\u671F\\u70BA \${stringifyPrimitive(issue2.values[0])}\`; - return \`\\u7121\\u6548\\u7684\\u9078\\u9805\\uFF1A\\u9810\\u671F\\u70BA\\u4EE5\\u4E0B\\u5176\\u4E2D\\u4E4B\\u4E00 \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`\\u6578\\u503C\\u904E\\u5927\\uFF1A\\u9810\\u671F \${issue2.origin ?? "\\u503C"} \\u61C9\\u70BA \${adj}\${issue2.maximum.toString()} \${sizing.unit ?? "\\u500B\\u5143\\u7D20"}\`; - return \`\\u6578\\u503C\\u904E\\u5927\\uFF1A\\u9810\\u671F \${issue2.origin ?? "\\u503C"} \\u61C9\\u70BA \${adj}\${issue2.maximum.toString()}\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) { - return \`\\u6578\\u503C\\u904E\\u5C0F\\uFF1A\\u9810\\u671F \${issue2.origin} \\u61C9\\u70BA \${adj}\${issue2.minimum.toString()} \${sizing.unit}\`; - } - return \`\\u6578\\u503C\\u904E\\u5C0F\\uFF1A\\u9810\\u671F \${issue2.origin} \\u61C9\\u70BA \${adj}\${issue2.minimum.toString()}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") { - return \`\\u7121\\u6548\\u7684\\u5B57\\u4E32\\uFF1A\\u5FC5\\u9808\\u4EE5 "\${_issue.prefix}" \\u958B\\u982D\`; - } - if (_issue.format === "ends_with") return \`\\u7121\\u6548\\u7684\\u5B57\\u4E32\\uFF1A\\u5FC5\\u9808\\u4EE5 "\${_issue.suffix}" \\u7D50\\u5C3E\`; - if (_issue.format === "includes") return \`\\u7121\\u6548\\u7684\\u5B57\\u4E32\\uFF1A\\u5FC5\\u9808\\u5305\\u542B "\${_issue.includes}"\`; - if (_issue.format === "regex") return \`\\u7121\\u6548\\u7684\\u5B57\\u4E32\\uFF1A\\u5FC5\\u9808\\u7B26\\u5408\\u683C\\u5F0F \${_issue.pattern}\`; - return \`\\u7121\\u6548\\u7684 \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`\\u7121\\u6548\\u7684\\u6578\\u5B57\\uFF1A\\u5FC5\\u9808\\u70BA \${issue2.divisor} \\u7684\\u500D\\u6578\`; - case "unrecognized_keys": - return \`\\u7121\\u6CD5\\u8B58\\u5225\\u7684\\u9375\\u503C\${issue2.keys.length > 1 ? "\\u5011" : ""}\\uFF1A\${joinValues(issue2.keys, "\\u3001")}\`; - case "invalid_key": - return \`\${issue2.origin} \\u4E2D\\u6709\\u7121\\u6548\\u7684\\u9375\\u503C\`; - case "invalid_union": - return "\\u7121\\u6548\\u7684\\u8F38\\u5165\\u503C"; - case "invalid_element": - return \`\${issue2.origin} \\u4E2D\\u6709\\u7121\\u6548\\u7684\\u503C\`; - default: - return \`\\u7121\\u6548\\u7684\\u8F38\\u5165\\u503C\`; - } - }; -}, "error"); -function zh_TW_default() { - return { - localeError: error43() - }; -} -__name(zh_TW_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/locales/yo.js -var error44 = /* @__PURE__ */ __name(() => { - const Sizable = { - string: { - unit: "\\xE0mi", - verb: "n\\xED" - }, - file: { - unit: "bytes", - verb: "n\\xED" - }, - array: { - unit: "nkan", - verb: "n\\xED" - }, - set: { - unit: "nkan", - verb: "n\\xED" - } - }; - function getSizing(origin) { - return Sizable[origin] ?? null; - } - __name(getSizing, "getSizing"); - const parsedType7 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "number": { - return Number.isNaN(data) ? "NaN" : "n\\u1ECD\\u0301mb\\xE0"; - } - case "object": { - if (Array.isArray(data)) { - return "akop\\u1ECD"; - } - if (data === null) { - return "null"; - } - if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) { - return data.constructor.name; - } - } - } - return t; - }, "parsedType"); - const Nouns = { - regex: "\\u1EB9\\u0300r\\u1ECD \\xECb\\xE1w\\u1ECDl\\xE9", - email: "\\xE0d\\xEDr\\u1EB9\\u0301s\\xEC \\xECm\\u1EB9\\u0301l\\xEC", - url: "URL", - emoji: "emoji", - uuid: "UUID", - uuidv4: "UUIDv4", - uuidv6: "UUIDv6", - nanoid: "nanoid", - guid: "GUID", - cuid: "cuid", - cuid2: "cuid2", - ulid: "ULID", - xid: "XID", - ksuid: "KSUID", - datetime: "\\xE0k\\xF3k\\xF2 ISO", - date: "\\u1ECDj\\u1ECD\\u0301 ISO", - time: "\\xE0k\\xF3k\\xF2 ISO", - duration: "\\xE0k\\xF3k\\xF2 t\\xF3 p\\xE9 ISO", - ipv4: "\\xE0d\\xEDr\\u1EB9\\u0301s\\xEC IPv4", - ipv6: "\\xE0d\\xEDr\\u1EB9\\u0301s\\xEC IPv6", - cidrv4: "\\xE0gb\\xE8gb\\xE8 IPv4", - cidrv6: "\\xE0gb\\xE8gb\\xE8 IPv6", - base64: "\\u1ECD\\u0300r\\u1ECD\\u0300 t\\xED a k\\u1ECD\\u0301 n\\xED base64", - base64url: "\\u1ECD\\u0300r\\u1ECD\\u0300 base64url", - json_string: "\\u1ECD\\u0300r\\u1ECD\\u0300 JSON", - e164: "n\\u1ECD\\u0301mb\\xE0 E.164", - jwt: "JWT", - template_literal: "\\u1EB9\\u0300r\\u1ECD \\xECb\\xE1w\\u1ECDl\\xE9" - }; - return (issue2) => { - switch (issue2.code) { - case "invalid_type": - return \`\\xCCb\\xE1w\\u1ECDl\\xE9 a\\u1E63\\xEC\\u1E63e: a n\\xED l\\xE1ti fi \${issue2.expected}, \\xE0m\\u1ECD\\u0300 a r\\xED \${parsedType7(issue2.input)}\`; - case "invalid_value": - if (issue2.values.length === 1) return \`\\xCCb\\xE1w\\u1ECDl\\xE9 a\\u1E63\\xEC\\u1E63e: a n\\xED l\\xE1ti fi \${stringifyPrimitive(issue2.values[0])}\`; - return \`\\xC0\\u1E63\\xE0y\\xE0n a\\u1E63\\xEC\\u1E63e: yan \\u1ECD\\u0300kan l\\xE1ra \${joinValues(issue2.values, "|")}\`; - case "too_big": { - const adj = issue2.inclusive ? "<=" : "<"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`T\\xF3 p\\u1ECD\\u0300 j\\xF9: a n\\xED l\\xE1ti j\\u1EB9\\u0301 p\\xE9 \${issue2.origin ?? "iye"} \${sizing.verb} \${adj}\${issue2.maximum} \${sizing.unit}\`; - return \`T\\xF3 p\\u1ECD\\u0300 j\\xF9: a n\\xED l\\xE1ti j\\u1EB9\\u0301 \${adj}\${issue2.maximum}\`; - } - case "too_small": { - const adj = issue2.inclusive ? ">=" : ">"; - const sizing = getSizing(issue2.origin); - if (sizing) return \`K\\xE9r\\xE9 ju: a n\\xED l\\xE1ti j\\u1EB9\\u0301 p\\xE9 \${issue2.origin} \${sizing.verb} \${adj}\${issue2.minimum} \${sizing.unit}\`; - return \`K\\xE9r\\xE9 ju: a n\\xED l\\xE1ti j\\u1EB9\\u0301 \${adj}\${issue2.minimum}\`; - } - case "invalid_format": { - const _issue = issue2; - if (_issue.format === "starts_with") return \`\\u1ECC\\u0300r\\u1ECD\\u0300 a\\u1E63\\xEC\\u1E63e: gb\\u1ECD\\u0301d\\u1ECD\\u0300 b\\u1EB9\\u0300r\\u1EB9\\u0300 p\\u1EB9\\u0300l\\xFA "\${_issue.prefix}"\`; - if (_issue.format === "ends_with") return \`\\u1ECC\\u0300r\\u1ECD\\u0300 a\\u1E63\\xEC\\u1E63e: gb\\u1ECD\\u0301d\\u1ECD\\u0300 par\\xED p\\u1EB9\\u0300l\\xFA "\${_issue.suffix}"\`; - if (_issue.format === "includes") return \`\\u1ECC\\u0300r\\u1ECD\\u0300 a\\u1E63\\xEC\\u1E63e: gb\\u1ECD\\u0301d\\u1ECD\\u0300 n\\xED "\${_issue.includes}"\`; - if (_issue.format === "regex") return \`\\u1ECC\\u0300r\\u1ECD\\u0300 a\\u1E63\\xEC\\u1E63e: gb\\u1ECD\\u0301d\\u1ECD\\u0300 b\\xE1 \\xE0p\\u1EB9\\u1EB9r\\u1EB9 mu \${_issue.pattern}\`; - return \`A\\u1E63\\xEC\\u1E63e: \${Nouns[_issue.format] ?? issue2.format}\`; - } - case "not_multiple_of": - return \`N\\u1ECD\\u0301mb\\xE0 a\\u1E63\\xEC\\u1E63e: gb\\u1ECD\\u0301d\\u1ECD\\u0300 j\\u1EB9\\u0301 \\xE8y\\xE0 p\\xEDp\\xEDn ti \${issue2.divisor}\`; - case "unrecognized_keys": - return \`B\\u1ECDt\\xECn\\xEC \\xE0\\xECm\\u1ECD\\u0300: \${joinValues(issue2.keys, ", ")}\`; - case "invalid_key": - return \`B\\u1ECDt\\xECn\\xEC a\\u1E63\\xEC\\u1E63e n\\xEDn\\xFA \${issue2.origin}\`; - case "invalid_union": - return "\\xCCb\\xE1w\\u1ECDl\\xE9 a\\u1E63\\xEC\\u1E63e"; - case "invalid_element": - return \`Iye a\\u1E63\\xEC\\u1E63e n\\xEDn\\xFA \${issue2.origin}\`; - default: - return "\\xCCb\\xE1w\\u1ECDl\\xE9 a\\u1E63\\xEC\\u1E63e"; - } - }; -}, "error"); -function yo_default() { - return { - localeError: error44() - }; -} -__name(yo_default, "default"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/core/registries.js -var \$output = Symbol("ZodOutput"); -var \$input = Symbol("ZodInput"); -var \$ZodRegistry = class { - static { - __name(this, "\$ZodRegistry"); - } - constructor() { - this._map = /* @__PURE__ */ new WeakMap(); - this._idmap = /* @__PURE__ */ new Map(); - } - add(schema, ..._meta) { - const meta = _meta[0]; - this._map.set(schema, meta); - if (meta && typeof meta === "object" && "id" in meta) { - if (this._idmap.has(meta.id)) { - throw new Error(\`ID \${meta.id} already exists in the registry\`); - } - this._idmap.set(meta.id, schema); - } - return this; - } - clear() { - this._map = /* @__PURE__ */ new WeakMap(); - this._idmap = /* @__PURE__ */ new Map(); - return this; - } - remove(schema) { - const meta = this._map.get(schema); - if (meta && typeof meta === "object" && "id" in meta) { - this._idmap.delete(meta.id); - } - this._map.delete(schema); - return this; - } - get(schema) { - const p = schema._zod.parent; - if (p) { - const pm = { - ...this.get(p) ?? {} - }; - delete pm.id; - const f = { - ...pm, - ...this._map.get(schema) - }; - return Object.keys(f).length ? f : void 0; - } - return this._map.get(schema); - } - has(schema) { - return this._map.has(schema); - } -}; -function registry() { - return new \$ZodRegistry(); -} -__name(registry, "registry"); -var globalRegistry = /* @__PURE__ */ registry(); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/core/api.js -function _string(Class2, params) { - return new Class2({ - type: "string", - ...normalizeParams(params) - }); -} -__name(_string, "_string"); -function _coercedString(Class2, params) { - return new Class2({ - type: "string", - coerce: true, - ...normalizeParams(params) - }); -} -__name(_coercedString, "_coercedString"); -function _email(Class2, params) { - return new Class2({ - type: "string", - format: "email", - check: "string_format", - abort: false, - ...normalizeParams(params) - }); -} -__name(_email, "_email"); -function _guid(Class2, params) { - return new Class2({ - type: "string", - format: "guid", - check: "string_format", - abort: false, - ...normalizeParams(params) - }); -} -__name(_guid, "_guid"); -function _uuid(Class2, params) { - return new Class2({ - type: "string", - format: "uuid", - check: "string_format", - abort: false, - ...normalizeParams(params) - }); -} -__name(_uuid, "_uuid"); -function _uuidv4(Class2, params) { - return new Class2({ - type: "string", - format: "uuid", - check: "string_format", - abort: false, - version: "v4", - ...normalizeParams(params) - }); -} -__name(_uuidv4, "_uuidv4"); -function _uuidv6(Class2, params) { - return new Class2({ - type: "string", - format: "uuid", - check: "string_format", - abort: false, - version: "v6", - ...normalizeParams(params) - }); -} -__name(_uuidv6, "_uuidv6"); -function _uuidv7(Class2, params) { - return new Class2({ - type: "string", - format: "uuid", - check: "string_format", - abort: false, - version: "v7", - ...normalizeParams(params) - }); -} -__name(_uuidv7, "_uuidv7"); -function _url(Class2, params) { - return new Class2({ - type: "string", - format: "url", - check: "string_format", - abort: false, - ...normalizeParams(params) - }); -} -__name(_url, "_url"); -function _emoji2(Class2, params) { - return new Class2({ - type: "string", - format: "emoji", - check: "string_format", - abort: false, - ...normalizeParams(params) - }); -} -__name(_emoji2, "_emoji"); -function _nanoid(Class2, params) { - return new Class2({ - type: "string", - format: "nanoid", - check: "string_format", - abort: false, - ...normalizeParams(params) - }); -} -__name(_nanoid, "_nanoid"); -function _cuid(Class2, params) { - return new Class2({ - type: "string", - format: "cuid", - check: "string_format", - abort: false, - ...normalizeParams(params) - }); -} -__name(_cuid, "_cuid"); -function _cuid2(Class2, params) { - return new Class2({ - type: "string", - format: "cuid2", - check: "string_format", - abort: false, - ...normalizeParams(params) - }); -} -__name(_cuid2, "_cuid2"); -function _ulid(Class2, params) { - return new Class2({ - type: "string", - format: "ulid", - check: "string_format", - abort: false, - ...normalizeParams(params) - }); -} -__name(_ulid, "_ulid"); -function _xid(Class2, params) { - return new Class2({ - type: "string", - format: "xid", - check: "string_format", - abort: false, - ...normalizeParams(params) - }); -} -__name(_xid, "_xid"); -function _ksuid(Class2, params) { - return new Class2({ - type: "string", - format: "ksuid", - check: "string_format", - abort: false, - ...normalizeParams(params) - }); -} -__name(_ksuid, "_ksuid"); -function _ipv4(Class2, params) { - return new Class2({ - type: "string", - format: "ipv4", - check: "string_format", - abort: false, - ...normalizeParams(params) - }); -} -__name(_ipv4, "_ipv4"); -function _ipv6(Class2, params) { - return new Class2({ - type: "string", - format: "ipv6", - check: "string_format", - abort: false, - ...normalizeParams(params) - }); -} -__name(_ipv6, "_ipv6"); -function _cidrv4(Class2, params) { - return new Class2({ - type: "string", - format: "cidrv4", - check: "string_format", - abort: false, - ...normalizeParams(params) - }); -} -__name(_cidrv4, "_cidrv4"); -function _cidrv6(Class2, params) { - return new Class2({ - type: "string", - format: "cidrv6", - check: "string_format", - abort: false, - ...normalizeParams(params) - }); -} -__name(_cidrv6, "_cidrv6"); -function _base64(Class2, params) { - return new Class2({ - type: "string", - format: "base64", - check: "string_format", - abort: false, - ...normalizeParams(params) - }); -} -__name(_base64, "_base64"); -function _base64url(Class2, params) { - return new Class2({ - type: "string", - format: "base64url", - check: "string_format", - abort: false, - ...normalizeParams(params) - }); -} -__name(_base64url, "_base64url"); -function _e164(Class2, params) { - return new Class2({ - type: "string", - format: "e164", - check: "string_format", - abort: false, - ...normalizeParams(params) - }); -} -__name(_e164, "_e164"); -function _jwt(Class2, params) { - return new Class2({ - type: "string", - format: "jwt", - check: "string_format", - abort: false, - ...normalizeParams(params) - }); -} -__name(_jwt, "_jwt"); -var TimePrecision = { - Any: null, - Minute: -1, - Second: 0, - Millisecond: 3, - Microsecond: 6 -}; -function _isoDateTime(Class2, params) { - return new Class2({ - type: "string", - format: "datetime", - check: "string_format", - offset: false, - local: false, - precision: null, - ...normalizeParams(params) - }); -} -__name(_isoDateTime, "_isoDateTime"); -function _isoDate(Class2, params) { - return new Class2({ - type: "string", - format: "date", - check: "string_format", - ...normalizeParams(params) - }); -} -__name(_isoDate, "_isoDate"); -function _isoTime(Class2, params) { - return new Class2({ - type: "string", - format: "time", - check: "string_format", - precision: null, - ...normalizeParams(params) - }); -} -__name(_isoTime, "_isoTime"); -function _isoDuration(Class2, params) { - return new Class2({ - type: "string", - format: "duration", - check: "string_format", - ...normalizeParams(params) - }); -} -__name(_isoDuration, "_isoDuration"); -function _number(Class2, params) { - return new Class2({ - type: "number", - checks: [], - ...normalizeParams(params) - }); -} -__name(_number, "_number"); -function _coercedNumber(Class2, params) { - return new Class2({ - type: "number", - coerce: true, - checks: [], - ...normalizeParams(params) - }); -} -__name(_coercedNumber, "_coercedNumber"); -function _int(Class2, params) { - return new Class2({ - type: "number", - check: "number_format", - abort: false, - format: "safeint", - ...normalizeParams(params) - }); -} -__name(_int, "_int"); -function _float32(Class2, params) { - return new Class2({ - type: "number", - check: "number_format", - abort: false, - format: "float32", - ...normalizeParams(params) - }); -} -__name(_float32, "_float32"); -function _float64(Class2, params) { - return new Class2({ - type: "number", - check: "number_format", - abort: false, - format: "float64", - ...normalizeParams(params) - }); -} -__name(_float64, "_float64"); -function _int32(Class2, params) { - return new Class2({ - type: "number", - check: "number_format", - abort: false, - format: "int32", - ...normalizeParams(params) - }); -} -__name(_int32, "_int32"); -function _uint32(Class2, params) { - return new Class2({ - type: "number", - check: "number_format", - abort: false, - format: "uint32", - ...normalizeParams(params) - }); -} -__name(_uint32, "_uint32"); -function _boolean(Class2, params) { - return new Class2({ - type: "boolean", - ...normalizeParams(params) - }); -} -__name(_boolean, "_boolean"); -function _coercedBoolean(Class2, params) { - return new Class2({ - type: "boolean", - coerce: true, - ...normalizeParams(params) - }); -} -__name(_coercedBoolean, "_coercedBoolean"); -function _bigint(Class2, params) { - return new Class2({ - type: "bigint", - ...normalizeParams(params) - }); -} -__name(_bigint, "_bigint"); -function _coercedBigint(Class2, params) { - return new Class2({ - type: "bigint", - coerce: true, - ...normalizeParams(params) - }); -} -__name(_coercedBigint, "_coercedBigint"); -function _int64(Class2, params) { - return new Class2({ - type: "bigint", - check: "bigint_format", - abort: false, - format: "int64", - ...normalizeParams(params) - }); -} -__name(_int64, "_int64"); -function _uint64(Class2, params) { - return new Class2({ - type: "bigint", - check: "bigint_format", - abort: false, - format: "uint64", - ...normalizeParams(params) - }); -} -__name(_uint64, "_uint64"); -function _symbol(Class2, params) { - return new Class2({ - type: "symbol", - ...normalizeParams(params) - }); -} -__name(_symbol, "_symbol"); -function _undefined2(Class2, params) { - return new Class2({ - type: "undefined", - ...normalizeParams(params) - }); -} -__name(_undefined2, "_undefined"); -function _null2(Class2, params) { - return new Class2({ - type: "null", - ...normalizeParams(params) - }); -} -__name(_null2, "_null"); -function _any(Class2) { - return new Class2({ - type: "any" - }); -} -__name(_any, "_any"); -function _unknown(Class2) { - return new Class2({ - type: "unknown" - }); -} -__name(_unknown, "_unknown"); -function _never(Class2, params) { - return new Class2({ - type: "never", - ...normalizeParams(params) - }); -} -__name(_never, "_never"); -function _void(Class2, params) { - return new Class2({ - type: "void", - ...normalizeParams(params) - }); -} -__name(_void, "_void"); -function _date(Class2, params) { - return new Class2({ - type: "date", - ...normalizeParams(params) - }); -} -__name(_date, "_date"); -function _coercedDate(Class2, params) { - return new Class2({ - type: "date", - coerce: true, - ...normalizeParams(params) - }); -} -__name(_coercedDate, "_coercedDate"); -function _nan(Class2, params) { - return new Class2({ - type: "nan", - ...normalizeParams(params) - }); -} -__name(_nan, "_nan"); -function _lt(value, params) { - return new \$ZodCheckLessThan({ - check: "less_than", - ...normalizeParams(params), - value, - inclusive: false - }); -} -__name(_lt, "_lt"); -function _lte(value, params) { - return new \$ZodCheckLessThan({ - check: "less_than", - ...normalizeParams(params), - value, - inclusive: true - }); -} -__name(_lte, "_lte"); -function _gt(value, params) { - return new \$ZodCheckGreaterThan({ - check: "greater_than", - ...normalizeParams(params), - value, - inclusive: false - }); -} -__name(_gt, "_gt"); -function _gte(value, params) { - return new \$ZodCheckGreaterThan({ - check: "greater_than", - ...normalizeParams(params), - value, - inclusive: true - }); -} -__name(_gte, "_gte"); -function _positive(params) { - return _gt(0, params); -} -__name(_positive, "_positive"); -function _negative(params) { - return _lt(0, params); -} -__name(_negative, "_negative"); -function _nonpositive(params) { - return _lte(0, params); -} -__name(_nonpositive, "_nonpositive"); -function _nonnegative(params) { - return _gte(0, params); -} -__name(_nonnegative, "_nonnegative"); -function _multipleOf(value, params) { - return new \$ZodCheckMultipleOf({ - check: "multiple_of", - ...normalizeParams(params), - value - }); -} -__name(_multipleOf, "_multipleOf"); -function _maxSize(maximum, params) { - return new \$ZodCheckMaxSize({ - check: "max_size", - ...normalizeParams(params), - maximum - }); -} -__name(_maxSize, "_maxSize"); -function _minSize(minimum, params) { - return new \$ZodCheckMinSize({ - check: "min_size", - ...normalizeParams(params), - minimum - }); -} -__name(_minSize, "_minSize"); -function _size(size, params) { - return new \$ZodCheckSizeEquals({ - check: "size_equals", - ...normalizeParams(params), - size - }); -} -__name(_size, "_size"); -function _maxLength(maximum, params) { - const ch = new \$ZodCheckMaxLength({ - check: "max_length", - ...normalizeParams(params), - maximum - }); - return ch; -} -__name(_maxLength, "_maxLength"); -function _minLength(minimum, params) { - return new \$ZodCheckMinLength({ - check: "min_length", - ...normalizeParams(params), - minimum - }); -} -__name(_minLength, "_minLength"); -function _length(length, params) { - return new \$ZodCheckLengthEquals({ - check: "length_equals", - ...normalizeParams(params), - length - }); -} -__name(_length, "_length"); -function _regex(pattern, params) { - return new \$ZodCheckRegex({ - check: "string_format", - format: "regex", - ...normalizeParams(params), - pattern - }); -} -__name(_regex, "_regex"); -function _lowercase(params) { - return new \$ZodCheckLowerCase({ - check: "string_format", - format: "lowercase", - ...normalizeParams(params) - }); -} -__name(_lowercase, "_lowercase"); -function _uppercase(params) { - return new \$ZodCheckUpperCase({ - check: "string_format", - format: "uppercase", - ...normalizeParams(params) - }); -} -__name(_uppercase, "_uppercase"); -function _includes(includes, params) { - return new \$ZodCheckIncludes({ - check: "string_format", - format: "includes", - ...normalizeParams(params), - includes - }); -} -__name(_includes, "_includes"); -function _startsWith(prefix, params) { - return new \$ZodCheckStartsWith({ - check: "string_format", - format: "starts_with", - ...normalizeParams(params), - prefix - }); -} -__name(_startsWith, "_startsWith"); -function _endsWith(suffix, params) { - return new \$ZodCheckEndsWith({ - check: "string_format", - format: "ends_with", - ...normalizeParams(params), - suffix - }); -} -__name(_endsWith, "_endsWith"); -function _property(property, schema, params) { - return new \$ZodCheckProperty({ - check: "property", - property, - schema, - ...normalizeParams(params) - }); -} -__name(_property, "_property"); -function _mime(types, params) { - return new \$ZodCheckMimeType({ - check: "mime_type", - mime: types, - ...normalizeParams(params) - }); -} -__name(_mime, "_mime"); -function _overwrite(tx) { - return new \$ZodCheckOverwrite({ - check: "overwrite", - tx - }); -} -__name(_overwrite, "_overwrite"); -function _normalize(form) { - return _overwrite((input) => input.normalize(form)); -} -__name(_normalize, "_normalize"); -function _trim() { - return _overwrite((input) => input.trim()); -} -__name(_trim, "_trim"); -function _toLowerCase() { - return _overwrite((input) => input.toLowerCase()); -} -__name(_toLowerCase, "_toLowerCase"); -function _toUpperCase() { - return _overwrite((input) => input.toUpperCase()); -} -__name(_toUpperCase, "_toUpperCase"); -function _array(Class2, element, params) { - return new Class2({ - type: "array", - element, - // get element() { - // return element; - // }, - ...normalizeParams(params) - }); -} -__name(_array, "_array"); -function _union(Class2, options, params) { - return new Class2({ - type: "union", - options, - ...normalizeParams(params) - }); -} -__name(_union, "_union"); -function _discriminatedUnion(Class2, discriminator, options, params) { - return new Class2({ - type: "union", - options, - discriminator, - ...normalizeParams(params) - }); -} -__name(_discriminatedUnion, "_discriminatedUnion"); -function _intersection(Class2, left, right) { - return new Class2({ - type: "intersection", - left, - right - }); -} -__name(_intersection, "_intersection"); -function _tuple(Class2, items, _paramsOrRest, _params) { - const hasRest = _paramsOrRest instanceof \$ZodType; - const params = hasRest ? _params : _paramsOrRest; - const rest = hasRest ? _paramsOrRest : null; - return new Class2({ - type: "tuple", - items, - rest, - ...normalizeParams(params) - }); -} -__name(_tuple, "_tuple"); -function _record(Class2, keyType, valueType, params) { - return new Class2({ - type: "record", - keyType, - valueType, - ...normalizeParams(params) - }); -} -__name(_record, "_record"); -function _map(Class2, keyType, valueType, params) { - return new Class2({ - type: "map", - keyType, - valueType, - ...normalizeParams(params) - }); -} -__name(_map, "_map"); -function _set(Class2, valueType, params) { - return new Class2({ - type: "set", - valueType, - ...normalizeParams(params) - }); -} -__name(_set, "_set"); -function _enum(Class2, values, params) { - const entries = Array.isArray(values) ? Object.fromEntries(values.map((v) => [ - v, - v - ])) : values; - return new Class2({ - type: "enum", - entries, - ...normalizeParams(params) - }); -} -__name(_enum, "_enum"); -function _nativeEnum(Class2, entries, params) { - return new Class2({ - type: "enum", - entries, - ...normalizeParams(params) - }); -} -__name(_nativeEnum, "_nativeEnum"); -function _literal(Class2, value, params) { - return new Class2({ - type: "literal", - values: Array.isArray(value) ? value : [ - value - ], - ...normalizeParams(params) - }); -} -__name(_literal, "_literal"); -function _file(Class2, params) { - return new Class2({ - type: "file", - ...normalizeParams(params) - }); -} -__name(_file, "_file"); -function _transform(Class2, fn) { - return new Class2({ - type: "transform", - transform: fn - }); -} -__name(_transform, "_transform"); -function _optional(Class2, innerType) { - return new Class2({ - type: "optional", - innerType - }); -} -__name(_optional, "_optional"); -function _nullable(Class2, innerType) { - return new Class2({ - type: "nullable", - innerType - }); -} -__name(_nullable, "_nullable"); -function _default(Class2, innerType, defaultValue) { - return new Class2({ - type: "default", - innerType, - get defaultValue() { - return typeof defaultValue === "function" ? defaultValue() : shallowClone(defaultValue); - } - }); -} -__name(_default, "_default"); -function _nonoptional(Class2, innerType, params) { - return new Class2({ - type: "nonoptional", - innerType, - ...normalizeParams(params) - }); -} -__name(_nonoptional, "_nonoptional"); -function _success(Class2, innerType) { - return new Class2({ - type: "success", - innerType - }); -} -__name(_success, "_success"); -function _catch(Class2, innerType, catchValue) { - return new Class2({ - type: "catch", - innerType, - catchValue: typeof catchValue === "function" ? catchValue : () => catchValue - }); -} -__name(_catch, "_catch"); -function _pipe(Class2, in_, out) { - return new Class2({ - type: "pipe", - in: in_, - out - }); -} -__name(_pipe, "_pipe"); -function _readonly(Class2, innerType) { - return new Class2({ - type: "readonly", - innerType - }); -} -__name(_readonly, "_readonly"); -function _templateLiteral(Class2, parts, params) { - return new Class2({ - type: "template_literal", - parts, - ...normalizeParams(params) - }); -} -__name(_templateLiteral, "_templateLiteral"); -function _lazy(Class2, getter) { - return new Class2({ - type: "lazy", - getter - }); -} -__name(_lazy, "_lazy"); -function _promise(Class2, innerType) { - return new Class2({ - type: "promise", - innerType - }); -} -__name(_promise, "_promise"); -function _custom(Class2, fn, _params) { - const norm = normalizeParams(_params); - norm.abort ?? (norm.abort = true); - const schema = new Class2({ - type: "custom", - check: "custom", - fn, - ...norm - }); - return schema; -} -__name(_custom, "_custom"); -function _refine(Class2, fn, _params) { - const schema = new Class2({ - type: "custom", - check: "custom", - fn, - ...normalizeParams(_params) - }); - return schema; -} -__name(_refine, "_refine"); -function _superRefine(fn) { - const ch = _check((payload) => { - payload.addIssue = (issue2) => { - if (typeof issue2 === "string") { - payload.issues.push(issue(issue2, payload.value, ch._zod.def)); - } else { - const _issue = issue2; - if (_issue.fatal) _issue.continue = false; - _issue.code ?? (_issue.code = "custom"); - _issue.input ?? (_issue.input = payload.value); - _issue.inst ?? (_issue.inst = ch); - _issue.continue ?? (_issue.continue = !ch._zod.def.abort); - payload.issues.push(issue(_issue)); - } - }; - return fn(payload.value, payload); - }); - return ch; -} -__name(_superRefine, "_superRefine"); -function _check(fn, params) { - const ch = new \$ZodCheck({ - check: "custom", - ...normalizeParams(params) - }); - ch._zod.check = fn; - return ch; -} -__name(_check, "_check"); -function _stringbool(Classes, _params) { - const params = normalizeParams(_params); - let truthyArray = params.truthy ?? [ - "true", - "1", - "yes", - "on", - "y", - "enabled" - ]; - let falsyArray = params.falsy ?? [ - "false", - "0", - "no", - "off", - "n", - "disabled" - ]; - if (params.case !== "sensitive") { - truthyArray = truthyArray.map((v) => typeof v === "string" ? v.toLowerCase() : v); - falsyArray = falsyArray.map((v) => typeof v === "string" ? v.toLowerCase() : v); - } - const truthySet = new Set(truthyArray); - const falsySet = new Set(falsyArray); - const _Codec = Classes.Codec ?? \$ZodCodec; - const _Boolean = Classes.Boolean ?? \$ZodBoolean; - const _String = Classes.String ?? \$ZodString; - const stringSchema = new _String({ - type: "string", - error: params.error - }); - const booleanSchema = new _Boolean({ - type: "boolean", - error: params.error - }); - const codec2 = new _Codec({ - type: "pipe", - in: stringSchema, - out: booleanSchema, - transform: /* @__PURE__ */ __name((input, payload) => { - let data = input; - if (params.case !== "sensitive") data = data.toLowerCase(); - if (truthySet.has(data)) { - return true; - } else if (falsySet.has(data)) { - return false; - } else { - payload.issues.push({ - code: "invalid_value", - expected: "stringbool", - values: [ - ...truthySet, - ...falsySet - ], - input: payload.value, - inst: codec2, - continue: false - }); - return {}; - } - }, "transform"), - reverseTransform: /* @__PURE__ */ __name((input, _payload) => { - if (input === true) { - return truthyArray[0] || "true"; - } else { - return falsyArray[0] || "false"; - } - }, "reverseTransform"), - error: params.error - }); - return codec2; -} -__name(_stringbool, "_stringbool"); -function _stringFormat(Class2, format, fnOrRegex, _params = {}) { - const params = normalizeParams(_params); - const def = { - ...normalizeParams(_params), - check: "string_format", - type: "string", - format, - fn: typeof fnOrRegex === "function" ? fnOrRegex : (val) => fnOrRegex.test(val), - ...params - }; - if (fnOrRegex instanceof RegExp) { - def.pattern = fnOrRegex; - } - const inst = new Class2(def); - return inst; -} -__name(_stringFormat, "_stringFormat"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/core/to-json-schema.js -var JSONSchemaGenerator = class { - static { - __name(this, "JSONSchemaGenerator"); - } - constructor(params) { - this.counter = 0; - this.metadataRegistry = params?.metadata ?? globalRegistry; - this.target = params?.target ?? "draft-2020-12"; - this.unrepresentable = params?.unrepresentable ?? "throw"; - this.override = params?.override ?? (() => { - }); - this.io = params?.io ?? "output"; - this.seen = /* @__PURE__ */ new Map(); - } - process(schema, _params = { - path: [], - schemaPath: [] - }) { - var _a17; - const def = schema._zod.def; - const formatMap = { - guid: "uuid", - url: "uri", - datetime: "date-time", - json_string: "json-string", - regex: "" - }; - const seen = this.seen.get(schema); - if (seen) { - seen.count++; - const isCycle = _params.schemaPath.includes(schema); - if (isCycle) { - seen.cycle = _params.path; - } - return seen.schema; - } - const result = { - schema: {}, - count: 1, - cycle: void 0, - path: _params.path - }; - this.seen.set(schema, result); - const overrideSchema = schema._zod.toJSONSchema?.(); - if (overrideSchema) { - result.schema = overrideSchema; - } else { - const params = { - ..._params, - schemaPath: [ - ..._params.schemaPath, - schema - ], - path: _params.path - }; - const parent = schema._zod.parent; - if (parent) { - result.ref = parent; - this.process(parent, params); - this.seen.get(parent).isParent = true; - } else { - const _json = result.schema; - switch (def.type) { - case "string": { - const json2 = _json; - json2.type = "string"; - const { minimum, maximum, format, patterns, contentEncoding } = schema._zod.bag; - if (typeof minimum === "number") json2.minLength = minimum; - if (typeof maximum === "number") json2.maxLength = maximum; - if (format) { - json2.format = formatMap[format] ?? format; - if (json2.format === "") delete json2.format; - } - if (contentEncoding) json2.contentEncoding = contentEncoding; - if (patterns && patterns.size > 0) { - const regexes = [ - ...patterns - ]; - if (regexes.length === 1) json2.pattern = regexes[0].source; - else if (regexes.length > 1) { - result.schema.allOf = [ - ...regexes.map((regex) => ({ - ...this.target === "draft-7" || this.target === "draft-4" || this.target === "openapi-3.0" ? { - type: "string" - } : {}, - pattern: regex.source - })) - ]; - } - } - break; - } - case "number": { - const json2 = _json; - const { minimum, maximum, format, multipleOf, exclusiveMaximum, exclusiveMinimum } = schema._zod.bag; - if (typeof format === "string" && format.includes("int")) json2.type = "integer"; - else json2.type = "number"; - if (typeof exclusiveMinimum === "number") { - if (this.target === "draft-4" || this.target === "openapi-3.0") { - json2.minimum = exclusiveMinimum; - json2.exclusiveMinimum = true; - } else { - json2.exclusiveMinimum = exclusiveMinimum; - } - } - if (typeof minimum === "number") { - json2.minimum = minimum; - if (typeof exclusiveMinimum === "number" && this.target !== "draft-4") { - if (exclusiveMinimum >= minimum) delete json2.minimum; - else delete json2.exclusiveMinimum; - } - } - if (typeof exclusiveMaximum === "number") { - if (this.target === "draft-4" || this.target === "openapi-3.0") { - json2.maximum = exclusiveMaximum; - json2.exclusiveMaximum = true; - } else { - json2.exclusiveMaximum = exclusiveMaximum; - } - } - if (typeof maximum === "number") { - json2.maximum = maximum; - if (typeof exclusiveMaximum === "number" && this.target !== "draft-4") { - if (exclusiveMaximum <= maximum) delete json2.maximum; - else delete json2.exclusiveMaximum; - } - } - if (typeof multipleOf === "number") json2.multipleOf = multipleOf; - break; - } - case "boolean": { - const json2 = _json; - json2.type = "boolean"; - break; - } - case "bigint": { - if (this.unrepresentable === "throw") { - throw new Error("BigInt cannot be represented in JSON Schema"); - } - break; - } - case "symbol": { - if (this.unrepresentable === "throw") { - throw new Error("Symbols cannot be represented in JSON Schema"); - } - break; - } - case "null": { - if (this.target === "openapi-3.0") { - _json.type = "string"; - _json.nullable = true; - _json.enum = [ - null - ]; - } else _json.type = "null"; - break; - } - case "any": { - break; - } - case "unknown": { - break; - } - case "undefined": { - if (this.unrepresentable === "throw") { - throw new Error("Undefined cannot be represented in JSON Schema"); - } - break; - } - case "void": { - if (this.unrepresentable === "throw") { - throw new Error("Void cannot be represented in JSON Schema"); - } - break; - } - case "never": { - _json.not = {}; - break; - } - case "date": { - if (this.unrepresentable === "throw") { - throw new Error("Date cannot be represented in JSON Schema"); - } - break; - } - case "array": { - const json2 = _json; - const { minimum, maximum } = schema._zod.bag; - if (typeof minimum === "number") json2.minItems = minimum; - if (typeof maximum === "number") json2.maxItems = maximum; - json2.type = "array"; - json2.items = this.process(def.element, { - ...params, - path: [ - ...params.path, - "items" - ] - }); - break; - } - case "object": { - const json2 = _json; - json2.type = "object"; - json2.properties = {}; - const shape = def.shape; - for (const key in shape) { - json2.properties[key] = this.process(shape[key], { - ...params, - path: [ - ...params.path, - "properties", - key - ] - }); - } - const allKeys = new Set(Object.keys(shape)); - const requiredKeys = new Set([ - ...allKeys - ].filter((key) => { - const v = def.shape[key]._zod; - if (this.io === "input") { - return v.optin === void 0; - } else { - return v.optout === void 0; - } - })); - if (requiredKeys.size > 0) { - json2.required = Array.from(requiredKeys); - } - if (def.catchall?._zod.def.type === "never") { - json2.additionalProperties = false; - } else if (!def.catchall) { - if (this.io === "output") json2.additionalProperties = false; - } else if (def.catchall) { - json2.additionalProperties = this.process(def.catchall, { - ...params, - path: [ - ...params.path, - "additionalProperties" - ] - }); - } - break; - } - case "union": { - const json2 = _json; - const options = def.options.map((x, i) => this.process(x, { - ...params, - path: [ - ...params.path, - "anyOf", - i - ] - })); - json2.anyOf = options; - break; - } - case "intersection": { - const json2 = _json; - const a = this.process(def.left, { - ...params, - path: [ - ...params.path, - "allOf", - 0 - ] - }); - const b = this.process(def.right, { - ...params, - path: [ - ...params.path, - "allOf", - 1 - ] - }); - const isSimpleIntersection = /* @__PURE__ */ __name((val) => "allOf" in val && Object.keys(val).length === 1, "isSimpleIntersection"); - const allOf = [ - ...isSimpleIntersection(a) ? a.allOf : [ - a - ], - ...isSimpleIntersection(b) ? b.allOf : [ - b - ] - ]; - json2.allOf = allOf; - break; - } - case "tuple": { - const json2 = _json; - json2.type = "array"; - const prefixPath = this.target === "draft-2020-12" ? "prefixItems" : "items"; - const restPath = this.target === "draft-2020-12" ? "items" : this.target === "openapi-3.0" ? "items" : "additionalItems"; - const prefixItems = def.items.map((x, i) => this.process(x, { - ...params, - path: [ - ...params.path, - prefixPath, - i - ] - })); - const rest = def.rest ? this.process(def.rest, { - ...params, - path: [ - ...params.path, - restPath, - ...this.target === "openapi-3.0" ? [ - def.items.length - ] : [] - ] - }) : null; - if (this.target === "draft-2020-12") { - json2.prefixItems = prefixItems; - if (rest) { - json2.items = rest; - } - } else if (this.target === "openapi-3.0") { - json2.items = { - anyOf: prefixItems - }; - if (rest) { - json2.items.anyOf.push(rest); - } - json2.minItems = prefixItems.length; - if (!rest) { - json2.maxItems = prefixItems.length; - } - } else { - json2.items = prefixItems; - if (rest) { - json2.additionalItems = rest; - } - } - const { minimum, maximum } = schema._zod.bag; - if (typeof minimum === "number") json2.minItems = minimum; - if (typeof maximum === "number") json2.maxItems = maximum; - break; - } - case "record": { - const json2 = _json; - json2.type = "object"; - if (this.target === "draft-7" || this.target === "draft-2020-12") { - json2.propertyNames = this.process(def.keyType, { - ...params, - path: [ - ...params.path, - "propertyNames" - ] - }); - } - json2.additionalProperties = this.process(def.valueType, { - ...params, - path: [ - ...params.path, - "additionalProperties" - ] - }); - break; - } - case "map": { - if (this.unrepresentable === "throw") { - throw new Error("Map cannot be represented in JSON Schema"); - } - break; - } - case "set": { - if (this.unrepresentable === "throw") { - throw new Error("Set cannot be represented in JSON Schema"); - } - break; - } - case "enum": { - const json2 = _json; - const values = getEnumValues(def.entries); - if (values.every((v) => typeof v === "number")) json2.type = "number"; - if (values.every((v) => typeof v === "string")) json2.type = "string"; - json2.enum = values; - break; - } - case "literal": { - const json2 = _json; - const vals = []; - for (const val of def.values) { - if (val === void 0) { - if (this.unrepresentable === "throw") { - throw new Error("Literal \`undefined\` cannot be represented in JSON Schema"); - } else { - } - } else if (typeof val === "bigint") { - if (this.unrepresentable === "throw") { - throw new Error("BigInt literals cannot be represented in JSON Schema"); - } else { - vals.push(Number(val)); - } - } else { - vals.push(val); - } - } - if (vals.length === 0) { - } else if (vals.length === 1) { - const val = vals[0]; - json2.type = val === null ? "null" : typeof val; - if (this.target === "draft-4" || this.target === "openapi-3.0") { - json2.enum = [ - val - ]; - } else { - json2.const = val; - } - } else { - if (vals.every((v) => typeof v === "number")) json2.type = "number"; - if (vals.every((v) => typeof v === "string")) json2.type = "string"; - if (vals.every((v) => typeof v === "boolean")) json2.type = "string"; - if (vals.every((v) => v === null)) json2.type = "null"; - json2.enum = vals; - } - break; - } - case "file": { - const json2 = _json; - const file2 = { - type: "string", - format: "binary", - contentEncoding: "binary" - }; - const { minimum, maximum, mime } = schema._zod.bag; - if (minimum !== void 0) file2.minLength = minimum; - if (maximum !== void 0) file2.maxLength = maximum; - if (mime) { - if (mime.length === 1) { - file2.contentMediaType = mime[0]; - Object.assign(json2, file2); - } else { - json2.anyOf = mime.map((m) => { - const mFile = { - ...file2, - contentMediaType: m - }; - return mFile; - }); - } - } else { - Object.assign(json2, file2); - } - break; - } - case "transform": { - if (this.unrepresentable === "throw") { - throw new Error("Transforms cannot be represented in JSON Schema"); - } - break; - } - case "nullable": { - const inner = this.process(def.innerType, params); - if (this.target === "openapi-3.0") { - result.ref = def.innerType; - _json.nullable = true; - } else { - _json.anyOf = [ - inner, - { - type: "null" - } - ]; - } - break; - } - case "nonoptional": { - this.process(def.innerType, params); - result.ref = def.innerType; - break; - } - case "success": { - const json2 = _json; - json2.type = "boolean"; - break; - } - case "default": { - this.process(def.innerType, params); - result.ref = def.innerType; - _json.default = JSON.parse(JSON.stringify(def.defaultValue)); - break; - } - case "prefault": { - this.process(def.innerType, params); - result.ref = def.innerType; - if (this.io === "input") _json._prefault = JSON.parse(JSON.stringify(def.defaultValue)); - break; - } - case "catch": { - this.process(def.innerType, params); - result.ref = def.innerType; - let catchValue; - try { - catchValue = def.catchValue(void 0); - } catch { - throw new Error("Dynamic catch values are not supported in JSON Schema"); - } - _json.default = catchValue; - break; - } - case "nan": { - if (this.unrepresentable === "throw") { - throw new Error("NaN cannot be represented in JSON Schema"); - } - break; - } - case "template_literal": { - const json2 = _json; - const pattern = schema._zod.pattern; - if (!pattern) throw new Error("Pattern not found in template literal"); - json2.type = "string"; - json2.pattern = pattern.source; - break; - } - case "pipe": { - const innerType = this.io === "input" ? def.in._zod.def.type === "transform" ? def.out : def.in : def.out; - this.process(innerType, params); - result.ref = innerType; - break; - } - case "readonly": { - this.process(def.innerType, params); - result.ref = def.innerType; - _json.readOnly = true; - break; - } - // passthrough types - case "promise": { - this.process(def.innerType, params); - result.ref = def.innerType; - break; - } - case "optional": { - this.process(def.innerType, params); - result.ref = def.innerType; - break; - } - case "lazy": { - const innerType = schema._zod.innerType; - this.process(innerType, params); - result.ref = innerType; - break; - } - case "custom": { - if (this.unrepresentable === "throw") { - throw new Error("Custom types cannot be represented in JSON Schema"); - } - break; - } - case "function": { - if (this.unrepresentable === "throw") { - throw new Error("Function types cannot be represented in JSON Schema"); - } - break; - } - default: { - def; - } - } - } - } - const meta = this.metadataRegistry.get(schema); - if (meta) Object.assign(result.schema, meta); - if (this.io === "input" && isTransforming(schema)) { - delete result.schema.examples; - delete result.schema.default; - } - if (this.io === "input" && result.schema._prefault) (_a17 = result.schema).default ?? (_a17.default = result.schema._prefault); - delete result.schema._prefault; - const _result = this.seen.get(schema); - return _result.schema; - } - emit(schema, _params) { - const params = { - cycles: _params?.cycles ?? "ref", - reused: _params?.reused ?? "inline", - // unrepresentable: _params?.unrepresentable ?? "throw", - // uri: _params?.uri ?? ((id) => \`\${id}\`), - external: _params?.external ?? void 0 - }; - const root = this.seen.get(schema); - if (!root) throw new Error("Unprocessed schema. This is a bug in Zod."); - const makeURI = /* @__PURE__ */ __name((entry) => { - const defsSegment = this.target === "draft-2020-12" ? "\$defs" : "definitions"; - if (params.external) { - const externalId = params.external.registry.get(entry[0])?.id; - const uriGenerator = params.external.uri ?? ((id2) => id2); - if (externalId) { - return { - ref: uriGenerator(externalId) - }; - } - const id = entry[1].defId ?? entry[1].schema.id ?? \`schema\${this.counter++}\`; - entry[1].defId = id; - return { - defId: id, - ref: \`\${uriGenerator("__shared")}#/\${defsSegment}/\${id}\` - }; - } - if (entry[1] === root) { - return { - ref: "#" - }; - } - const uriPrefix = \`#\`; - const defUriPrefix = \`\${uriPrefix}/\${defsSegment}/\`; - const defId = entry[1].schema.id ?? \`__schema\${this.counter++}\`; - return { - defId, - ref: defUriPrefix + defId - }; - }, "makeURI"); - const extractToDef = /* @__PURE__ */ __name((entry) => { - if (entry[1].schema.\$ref) { - return; - } - const seen = entry[1]; - const { ref, defId } = makeURI(entry); - seen.def = { - ...seen.schema - }; - if (defId) seen.defId = defId; - const schema2 = seen.schema; - for (const key in schema2) { - delete schema2[key]; - } - schema2.\$ref = ref; - }, "extractToDef"); - if (params.cycles === "throw") { - for (const entry of this.seen.entries()) { - const seen = entry[1]; - if (seen.cycle) { - throw new Error(\`Cycle detected: #/\${seen.cycle?.join("/")}/ - -Set the \\\`cycles\\\` parameter to \\\`"ref"\\\` to resolve cyclical schemas with defs.\`); - } - } - } - for (const entry of this.seen.entries()) { - const seen = entry[1]; - if (schema === entry[0]) { - extractToDef(entry); - continue; - } - if (params.external) { - const ext = params.external.registry.get(entry[0])?.id; - if (schema !== entry[0] && ext) { - extractToDef(entry); - continue; - } - } - const id = this.metadataRegistry.get(entry[0])?.id; - if (id) { - extractToDef(entry); - continue; - } - if (seen.cycle) { - extractToDef(entry); - continue; - } - if (seen.count > 1) { - if (params.reused === "ref") { - extractToDef(entry); - continue; - } - } - } - const flattenRef = /* @__PURE__ */ __name((zodSchema2, params2) => { - const seen = this.seen.get(zodSchema2); - const schema2 = seen.def ?? seen.schema; - const _cached = { - ...schema2 - }; - if (seen.ref === null) { - return; - } - const ref = seen.ref; - seen.ref = null; - if (ref) { - flattenRef(ref, params2); - const refSchema = this.seen.get(ref).schema; - if (refSchema.\$ref && (params2.target === "draft-7" || params2.target === "draft-4" || params2.target === "openapi-3.0")) { - schema2.allOf = schema2.allOf ?? []; - schema2.allOf.push(refSchema); - } else { - Object.assign(schema2, refSchema); - Object.assign(schema2, _cached); - } - } - if (!seen.isParent) this.override({ - zodSchema: zodSchema2, - jsonSchema: schema2, - path: seen.path ?? [] - }); - }, "flattenRef"); - for (const entry of [ - ...this.seen.entries() - ].reverse()) { - flattenRef(entry[0], { - target: this.target - }); - } - const result = {}; - if (this.target === "draft-2020-12") { - result.\$schema = "https://json-schema.org/draft/2020-12/schema"; - } else if (this.target === "draft-7") { - result.\$schema = "http://json-schema.org/draft-07/schema#"; - } else if (this.target === "draft-4") { - result.\$schema = "http://json-schema.org/draft-04/schema#"; - } else if (this.target === "openapi-3.0") { - } else { - console.warn(\`Invalid target: \${this.target}\`); - } - if (params.external?.uri) { - const id = params.external.registry.get(schema)?.id; - if (!id) throw new Error("Schema is missing an \`id\` property"); - result.\$id = params.external.uri(id); - } - Object.assign(result, root.def); - const defs = params.external?.defs ?? {}; - for (const entry of this.seen.entries()) { - const seen = entry[1]; - if (seen.def && seen.defId) { - defs[seen.defId] = seen.def; - } - } - if (params.external) { - } else { - if (Object.keys(defs).length > 0) { - if (this.target === "draft-2020-12") { - result.\$defs = defs; - } else { - result.definitions = defs; - } - } - } - try { - return JSON.parse(JSON.stringify(result)); - } catch (_err) { - throw new Error("Error converting schema to JSON."); - } - } -}; -function toJSONSchema(input, _params) { - if (input instanceof \$ZodRegistry) { - const gen2 = new JSONSchemaGenerator(_params); - const defs = {}; - for (const entry of input._idmap.entries()) { - const [_, schema] = entry; - gen2.process(schema); - } - const schemas = {}; - const external = { - registry: input, - uri: _params?.uri, - defs - }; - for (const entry of input._idmap.entries()) { - const [key, schema] = entry; - schemas[key] = gen2.emit(schema, { - ..._params, - external - }); - } - if (Object.keys(defs).length > 0) { - const defsSegment = gen2.target === "draft-2020-12" ? "\$defs" : "definitions"; - schemas.__shared = { - [defsSegment]: defs - }; - } - return { - schemas - }; - } - const gen = new JSONSchemaGenerator(_params); - gen.process(input); - return gen.emit(input, _params); -} -__name(toJSONSchema, "toJSONSchema"); -function isTransforming(_schema, _ctx) { - const ctx = _ctx ?? { - seen: /* @__PURE__ */ new Set() - }; - if (ctx.seen.has(_schema)) return false; - ctx.seen.add(_schema); - const schema = _schema; - const def = schema._zod.def; - switch (def.type) { - case "string": - case "number": - case "bigint": - case "boolean": - case "date": - case "symbol": - case "undefined": - case "null": - case "any": - case "unknown": - case "never": - case "void": - case "literal": - case "enum": - case "nan": - case "file": - case "template_literal": - return false; - case "array": { - return isTransforming(def.element, ctx); - } - case "object": { - for (const key in def.shape) { - if (isTransforming(def.shape[key], ctx)) return true; - } - return false; - } - case "union": { - for (const option of def.options) { - if (isTransforming(option, ctx)) return true; - } - return false; - } - case "intersection": { - return isTransforming(def.left, ctx) || isTransforming(def.right, ctx); - } - case "tuple": { - for (const item of def.items) { - if (isTransforming(item, ctx)) return true; - } - if (def.rest && isTransforming(def.rest, ctx)) return true; - return false; - } - case "record": { - return isTransforming(def.keyType, ctx) || isTransforming(def.valueType, ctx); - } - case "map": { - return isTransforming(def.keyType, ctx) || isTransforming(def.valueType, ctx); - } - case "set": { - return isTransforming(def.valueType, ctx); - } - // inner types - case "promise": - case "optional": - case "nonoptional": - case "nullable": - case "readonly": - return isTransforming(def.innerType, ctx); - case "lazy": - return isTransforming(def.getter(), ctx); - case "default": { - return isTransforming(def.innerType, ctx); - } - case "prefault": { - return isTransforming(def.innerType, ctx); - } - case "custom": { - return false; - } - case "transform": { - return true; - } - case "pipe": { - return isTransforming(def.in, ctx) || isTransforming(def.out, ctx); - } - case "success": { - return false; - } - case "catch": { - return false; - } - case "function": { - return false; - } - default: - def; - } - throw new Error(\`Unknown schema type: \${def.type}\`); -} -__name(isTransforming, "isTransforming"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/core/json-schema.js -var json_schema_exports = {}; - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/classic/iso.js -var iso_exports = {}; -__export(iso_exports, { - ZodISODate: () => ZodISODate, - ZodISODateTime: () => ZodISODateTime, - ZodISODuration: () => ZodISODuration, - ZodISOTime: () => ZodISOTime, - date: () => date2, - datetime: () => datetime2, - duration: () => duration2, - time: () => time2 -}); -var ZodISODateTime = /* @__PURE__ */ \$constructor("ZodISODateTime", (inst, def) => { - \$ZodISODateTime.init(inst, def); - ZodStringFormat.init(inst, def); -}); -function datetime2(params) { - return _isoDateTime(ZodISODateTime, params); -} -__name(datetime2, "datetime"); -var ZodISODate = /* @__PURE__ */ \$constructor("ZodISODate", (inst, def) => { - \$ZodISODate.init(inst, def); - ZodStringFormat.init(inst, def); -}); -function date2(params) { - return _isoDate(ZodISODate, params); -} -__name(date2, "date"); -var ZodISOTime = /* @__PURE__ */ \$constructor("ZodISOTime", (inst, def) => { - \$ZodISOTime.init(inst, def); - ZodStringFormat.init(inst, def); -}); -function time2(params) { - return _isoTime(ZodISOTime, params); -} -__name(time2, "time"); -var ZodISODuration = /* @__PURE__ */ \$constructor("ZodISODuration", (inst, def) => { - \$ZodISODuration.init(inst, def); - ZodStringFormat.init(inst, def); -}); -function duration2(params) { - return _isoDuration(ZodISODuration, params); -} -__name(duration2, "duration"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/classic/errors.js -var initializer2 = /* @__PURE__ */ __name((inst, issues) => { - \$ZodError.init(inst, issues); - inst.name = "ZodError"; - Object.defineProperties(inst, { - format: { - value: /* @__PURE__ */ __name((mapper) => formatError(inst, mapper), "value") - }, - flatten: { - value: /* @__PURE__ */ __name((mapper) => flattenError(inst, mapper), "value") - }, - addIssue: { - value: /* @__PURE__ */ __name((issue2) => { - inst.issues.push(issue2); - inst.message = JSON.stringify(inst.issues, jsonStringifyReplacer, 2); - }, "value") - }, - addIssues: { - value: /* @__PURE__ */ __name((issues2) => { - inst.issues.push(...issues2); - inst.message = JSON.stringify(inst.issues, jsonStringifyReplacer, 2); - }, "value") - }, - isEmpty: { - get() { - return inst.issues.length === 0; - } - } - }); -}, "initializer"); -var ZodError = \$constructor("ZodError", initializer2); -var ZodRealError = \$constructor("ZodError", initializer2, { - Parent: Error -}); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/classic/parse.js -var parse2 = /* @__PURE__ */ _parse(ZodRealError); -var parseAsync2 = /* @__PURE__ */ _parseAsync(ZodRealError); -var safeParse2 = /* @__PURE__ */ _safeParse(ZodRealError); -var safeParseAsync2 = /* @__PURE__ */ _safeParseAsync(ZodRealError); -var encode2 = /* @__PURE__ */ _encode(ZodRealError); -var decode2 = /* @__PURE__ */ _decode(ZodRealError); -var encodeAsync2 = /* @__PURE__ */ _encodeAsync(ZodRealError); -var decodeAsync2 = /* @__PURE__ */ _decodeAsync(ZodRealError); -var safeEncode2 = /* @__PURE__ */ _safeEncode(ZodRealError); -var safeDecode2 = /* @__PURE__ */ _safeDecode(ZodRealError); -var safeEncodeAsync2 = /* @__PURE__ */ _safeEncodeAsync(ZodRealError); -var safeDecodeAsync2 = /* @__PURE__ */ _safeDecodeAsync(ZodRealError); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/classic/schemas.js -var ZodType = /* @__PURE__ */ \$constructor("ZodType", (inst, def) => { - \$ZodType.init(inst, def); - inst.def = def; - inst.type = def.type; - Object.defineProperty(inst, "_def", { - value: def - }); - inst.check = (...checks) => { - return inst.clone(util_exports.mergeDefs(def, { - checks: [ - ...def.checks ?? [], - ...checks.map((ch) => typeof ch === "function" ? { - _zod: { - check: ch, - def: { - check: "custom" - }, - onattach: [] - } - } : ch) - ] - })); - }; - inst.clone = (def2, params) => clone(inst, def2, params); - inst.brand = () => inst; - inst.register = (reg, meta) => { - reg.add(inst, meta); - return inst; - }; - inst.parse = (data, params) => parse2(inst, data, params, { - callee: inst.parse - }); - inst.safeParse = (data, params) => safeParse2(inst, data, params); - inst.parseAsync = async (data, params) => parseAsync2(inst, data, params, { - callee: inst.parseAsync - }); - inst.safeParseAsync = async (data, params) => safeParseAsync2(inst, data, params); - inst.spa = inst.safeParseAsync; - inst.encode = (data, params) => encode2(inst, data, params); - inst.decode = (data, params) => decode2(inst, data, params); - inst.encodeAsync = async (data, params) => encodeAsync2(inst, data, params); - inst.decodeAsync = async (data, params) => decodeAsync2(inst, data, params); - inst.safeEncode = (data, params) => safeEncode2(inst, data, params); - inst.safeDecode = (data, params) => safeDecode2(inst, data, params); - inst.safeEncodeAsync = async (data, params) => safeEncodeAsync2(inst, data, params); - inst.safeDecodeAsync = async (data, params) => safeDecodeAsync2(inst, data, params); - inst.refine = (check2, params) => inst.check(refine(check2, params)); - inst.superRefine = (refinement) => inst.check(superRefine(refinement)); - inst.overwrite = (fn) => inst.check(_overwrite(fn)); - inst.optional = () => optional(inst); - inst.nullable = () => nullable(inst); - inst.nullish = () => optional(nullable(inst)); - inst.nonoptional = (params) => nonoptional(inst, params); - inst.array = () => array(inst); - inst.or = (arg) => union([ - inst, - arg - ]); - inst.and = (arg) => intersection(inst, arg); - inst.transform = (tx) => pipe(inst, transform(tx)); - inst.default = (def2) => _default2(inst, def2); - inst.prefault = (def2) => prefault(inst, def2); - inst.catch = (params) => _catch2(inst, params); - inst.pipe = (target) => pipe(inst, target); - inst.readonly = () => readonly(inst); - inst.describe = (description) => { - const cl = inst.clone(); - globalRegistry.add(cl, { - description - }); - return cl; - }; - Object.defineProperty(inst, "description", { - get() { - return globalRegistry.get(inst)?.description; - }, - configurable: true - }); - inst.meta = (...args) => { - if (args.length === 0) { - return globalRegistry.get(inst); - } - const cl = inst.clone(); - globalRegistry.add(cl, args[0]); - return cl; - }; - inst.isOptional = () => inst.safeParse(void 0).success; - inst.isNullable = () => inst.safeParse(null).success; - return inst; -}); -var _ZodString = /* @__PURE__ */ \$constructor("_ZodString", (inst, def) => { - \$ZodString.init(inst, def); - ZodType.init(inst, def); - const bag = inst._zod.bag; - inst.format = bag.format ?? null; - inst.minLength = bag.minimum ?? null; - inst.maxLength = bag.maximum ?? null; - inst.regex = (...args) => inst.check(_regex(...args)); - inst.includes = (...args) => inst.check(_includes(...args)); - inst.startsWith = (...args) => inst.check(_startsWith(...args)); - inst.endsWith = (...args) => inst.check(_endsWith(...args)); - inst.min = (...args) => inst.check(_minLength(...args)); - inst.max = (...args) => inst.check(_maxLength(...args)); - inst.length = (...args) => inst.check(_length(...args)); - inst.nonempty = (...args) => inst.check(_minLength(1, ...args)); - inst.lowercase = (params) => inst.check(_lowercase(params)); - inst.uppercase = (params) => inst.check(_uppercase(params)); - inst.trim = () => inst.check(_trim()); - inst.normalize = (...args) => inst.check(_normalize(...args)); - inst.toLowerCase = () => inst.check(_toLowerCase()); - inst.toUpperCase = () => inst.check(_toUpperCase()); -}); -var ZodString = /* @__PURE__ */ \$constructor("ZodString", (inst, def) => { - \$ZodString.init(inst, def); - _ZodString.init(inst, def); - inst.email = (params) => inst.check(_email(ZodEmail, params)); - inst.url = (params) => inst.check(_url(ZodURL, params)); - inst.jwt = (params) => inst.check(_jwt(ZodJWT, params)); - inst.emoji = (params) => inst.check(_emoji2(ZodEmoji, params)); - inst.guid = (params) => inst.check(_guid(ZodGUID, params)); - inst.uuid = (params) => inst.check(_uuid(ZodUUID, params)); - inst.uuidv4 = (params) => inst.check(_uuidv4(ZodUUID, params)); - inst.uuidv6 = (params) => inst.check(_uuidv6(ZodUUID, params)); - inst.uuidv7 = (params) => inst.check(_uuidv7(ZodUUID, params)); - inst.nanoid = (params) => inst.check(_nanoid(ZodNanoID, params)); - inst.guid = (params) => inst.check(_guid(ZodGUID, params)); - inst.cuid = (params) => inst.check(_cuid(ZodCUID, params)); - inst.cuid2 = (params) => inst.check(_cuid2(ZodCUID2, params)); - inst.ulid = (params) => inst.check(_ulid(ZodULID, params)); - inst.base64 = (params) => inst.check(_base64(ZodBase64, params)); - inst.base64url = (params) => inst.check(_base64url(ZodBase64URL, params)); - inst.xid = (params) => inst.check(_xid(ZodXID, params)); - inst.ksuid = (params) => inst.check(_ksuid(ZodKSUID, params)); - inst.ipv4 = (params) => inst.check(_ipv4(ZodIPv4, params)); - inst.ipv6 = (params) => inst.check(_ipv6(ZodIPv6, params)); - inst.cidrv4 = (params) => inst.check(_cidrv4(ZodCIDRv4, params)); - inst.cidrv6 = (params) => inst.check(_cidrv6(ZodCIDRv6, params)); - inst.e164 = (params) => inst.check(_e164(ZodE164, params)); - inst.datetime = (params) => inst.check(datetime2(params)); - inst.date = (params) => inst.check(date2(params)); - inst.time = (params) => inst.check(time2(params)); - inst.duration = (params) => inst.check(duration2(params)); -}); -function string2(params) { - return _string(ZodString, params); -} -__name(string2, "string"); -var ZodStringFormat = /* @__PURE__ */ \$constructor("ZodStringFormat", (inst, def) => { - \$ZodStringFormat.init(inst, def); - _ZodString.init(inst, def); -}); -var ZodEmail = /* @__PURE__ */ \$constructor("ZodEmail", (inst, def) => { - \$ZodEmail.init(inst, def); - ZodStringFormat.init(inst, def); -}); -function email2(params) { - return _email(ZodEmail, params); -} -__name(email2, "email"); -var ZodGUID = /* @__PURE__ */ \$constructor("ZodGUID", (inst, def) => { - \$ZodGUID.init(inst, def); - ZodStringFormat.init(inst, def); -}); -function guid2(params) { - return _guid(ZodGUID, params); -} -__name(guid2, "guid"); -var ZodUUID = /* @__PURE__ */ \$constructor("ZodUUID", (inst, def) => { - \$ZodUUID.init(inst, def); - ZodStringFormat.init(inst, def); -}); -function uuid2(params) { - return _uuid(ZodUUID, params); -} -__name(uuid2, "uuid"); -function uuidv4(params) { - return _uuidv4(ZodUUID, params); -} -__name(uuidv4, "uuidv4"); -function uuidv6(params) { - return _uuidv6(ZodUUID, params); -} -__name(uuidv6, "uuidv6"); -function uuidv7(params) { - return _uuidv7(ZodUUID, params); -} -__name(uuidv7, "uuidv7"); -var ZodURL = /* @__PURE__ */ \$constructor("ZodURL", (inst, def) => { - \$ZodURL.init(inst, def); - ZodStringFormat.init(inst, def); -}); -function url(params) { - return _url(ZodURL, params); -} -__name(url, "url"); -function httpUrl(params) { - return _url(ZodURL, { - protocol: /^https?\$/, - hostname: regexes_exports.domain, - ...util_exports.normalizeParams(params) - }); -} -__name(httpUrl, "httpUrl"); -var ZodEmoji = /* @__PURE__ */ \$constructor("ZodEmoji", (inst, def) => { - \$ZodEmoji.init(inst, def); - ZodStringFormat.init(inst, def); -}); -function emoji2(params) { - return _emoji2(ZodEmoji, params); -} -__name(emoji2, "emoji"); -var ZodNanoID = /* @__PURE__ */ \$constructor("ZodNanoID", (inst, def) => { - \$ZodNanoID.init(inst, def); - ZodStringFormat.init(inst, def); -}); -function nanoid2(params) { - return _nanoid(ZodNanoID, params); -} -__name(nanoid2, "nanoid"); -var ZodCUID = /* @__PURE__ */ \$constructor("ZodCUID", (inst, def) => { - \$ZodCUID.init(inst, def); - ZodStringFormat.init(inst, def); -}); -function cuid3(params) { - return _cuid(ZodCUID, params); -} -__name(cuid3, "cuid"); -var ZodCUID2 = /* @__PURE__ */ \$constructor("ZodCUID2", (inst, def) => { - \$ZodCUID2.init(inst, def); - ZodStringFormat.init(inst, def); -}); -function cuid22(params) { - return _cuid2(ZodCUID2, params); -} -__name(cuid22, "cuid2"); -var ZodULID = /* @__PURE__ */ \$constructor("ZodULID", (inst, def) => { - \$ZodULID.init(inst, def); - ZodStringFormat.init(inst, def); -}); -function ulid2(params) { - return _ulid(ZodULID, params); -} -__name(ulid2, "ulid"); -var ZodXID = /* @__PURE__ */ \$constructor("ZodXID", (inst, def) => { - \$ZodXID.init(inst, def); - ZodStringFormat.init(inst, def); -}); -function xid2(params) { - return _xid(ZodXID, params); -} -__name(xid2, "xid"); -var ZodKSUID = /* @__PURE__ */ \$constructor("ZodKSUID", (inst, def) => { - \$ZodKSUID.init(inst, def); - ZodStringFormat.init(inst, def); -}); -function ksuid2(params) { - return _ksuid(ZodKSUID, params); -} -__name(ksuid2, "ksuid"); -var ZodIPv4 = /* @__PURE__ */ \$constructor("ZodIPv4", (inst, def) => { - \$ZodIPv4.init(inst, def); - ZodStringFormat.init(inst, def); -}); -function ipv42(params) { - return _ipv4(ZodIPv4, params); -} -__name(ipv42, "ipv4"); -var ZodIPv6 = /* @__PURE__ */ \$constructor("ZodIPv6", (inst, def) => { - \$ZodIPv6.init(inst, def); - ZodStringFormat.init(inst, def); -}); -function ipv62(params) { - return _ipv6(ZodIPv6, params); -} -__name(ipv62, "ipv6"); -var ZodCIDRv4 = /* @__PURE__ */ \$constructor("ZodCIDRv4", (inst, def) => { - \$ZodCIDRv4.init(inst, def); - ZodStringFormat.init(inst, def); -}); -function cidrv42(params) { - return _cidrv4(ZodCIDRv4, params); -} -__name(cidrv42, "cidrv4"); -var ZodCIDRv6 = /* @__PURE__ */ \$constructor("ZodCIDRv6", (inst, def) => { - \$ZodCIDRv6.init(inst, def); - ZodStringFormat.init(inst, def); -}); -function cidrv62(params) { - return _cidrv6(ZodCIDRv6, params); -} -__name(cidrv62, "cidrv6"); -var ZodBase64 = /* @__PURE__ */ \$constructor("ZodBase64", (inst, def) => { - \$ZodBase64.init(inst, def); - ZodStringFormat.init(inst, def); -}); -function base642(params) { - return _base64(ZodBase64, params); -} -__name(base642, "base64"); -var ZodBase64URL = /* @__PURE__ */ \$constructor("ZodBase64URL", (inst, def) => { - \$ZodBase64URL.init(inst, def); - ZodStringFormat.init(inst, def); -}); -function base64url2(params) { - return _base64url(ZodBase64URL, params); -} -__name(base64url2, "base64url"); -var ZodE164 = /* @__PURE__ */ \$constructor("ZodE164", (inst, def) => { - \$ZodE164.init(inst, def); - ZodStringFormat.init(inst, def); -}); -function e1642(params) { - return _e164(ZodE164, params); -} -__name(e1642, "e164"); -var ZodJWT = /* @__PURE__ */ \$constructor("ZodJWT", (inst, def) => { - \$ZodJWT.init(inst, def); - ZodStringFormat.init(inst, def); -}); -function jwt(params) { - return _jwt(ZodJWT, params); -} -__name(jwt, "jwt"); -var ZodCustomStringFormat = /* @__PURE__ */ \$constructor("ZodCustomStringFormat", (inst, def) => { - \$ZodCustomStringFormat.init(inst, def); - ZodStringFormat.init(inst, def); -}); -function stringFormat(format, fnOrRegex, _params = {}) { - return _stringFormat(ZodCustomStringFormat, format, fnOrRegex, _params); -} -__name(stringFormat, "stringFormat"); -function hostname2(_params) { - return _stringFormat(ZodCustomStringFormat, "hostname", regexes_exports.hostname, _params); -} -__name(hostname2, "hostname"); -function hex2(_params) { - return _stringFormat(ZodCustomStringFormat, "hex", regexes_exports.hex, _params); -} -__name(hex2, "hex"); -function hash(alg, params) { - const enc = params?.enc ?? "hex"; - const format = \`\${alg}_\${enc}\`; - const regex = regexes_exports[format]; - if (!regex) throw new Error(\`Unrecognized hash format: \${format}\`); - return _stringFormat(ZodCustomStringFormat, format, regex, params); -} -__name(hash, "hash"); -var ZodNumber = /* @__PURE__ */ \$constructor("ZodNumber", (inst, def) => { - \$ZodNumber.init(inst, def); - ZodType.init(inst, def); - inst.gt = (value, params) => inst.check(_gt(value, params)); - inst.gte = (value, params) => inst.check(_gte(value, params)); - inst.min = (value, params) => inst.check(_gte(value, params)); - inst.lt = (value, params) => inst.check(_lt(value, params)); - inst.lte = (value, params) => inst.check(_lte(value, params)); - inst.max = (value, params) => inst.check(_lte(value, params)); - inst.int = (params) => inst.check(int(params)); - inst.safe = (params) => inst.check(int(params)); - inst.positive = (params) => inst.check(_gt(0, params)); - inst.nonnegative = (params) => inst.check(_gte(0, params)); - inst.negative = (params) => inst.check(_lt(0, params)); - inst.nonpositive = (params) => inst.check(_lte(0, params)); - inst.multipleOf = (value, params) => inst.check(_multipleOf(value, params)); - inst.step = (value, params) => inst.check(_multipleOf(value, params)); - inst.finite = () => inst; - const bag = inst._zod.bag; - inst.minValue = Math.max(bag.minimum ?? Number.NEGATIVE_INFINITY, bag.exclusiveMinimum ?? Number.NEGATIVE_INFINITY) ?? null; - inst.maxValue = Math.min(bag.maximum ?? Number.POSITIVE_INFINITY, bag.exclusiveMaximum ?? Number.POSITIVE_INFINITY) ?? null; - inst.isInt = (bag.format ?? "").includes("int") || Number.isSafeInteger(bag.multipleOf ?? 0.5); - inst.isFinite = true; - inst.format = bag.format ?? null; -}); -function number2(params) { - return _number(ZodNumber, params); -} -__name(number2, "number"); -var ZodNumberFormat = /* @__PURE__ */ \$constructor("ZodNumberFormat", (inst, def) => { - \$ZodNumberFormat.init(inst, def); - ZodNumber.init(inst, def); -}); -function int(params) { - return _int(ZodNumberFormat, params); -} -__name(int, "int"); -function float32(params) { - return _float32(ZodNumberFormat, params); -} -__name(float32, "float32"); -function float64(params) { - return _float64(ZodNumberFormat, params); -} -__name(float64, "float64"); -function int32(params) { - return _int32(ZodNumberFormat, params); -} -__name(int32, "int32"); -function uint32(params) { - return _uint32(ZodNumberFormat, params); -} -__name(uint32, "uint32"); -var ZodBoolean = /* @__PURE__ */ \$constructor("ZodBoolean", (inst, def) => { - \$ZodBoolean.init(inst, def); - ZodType.init(inst, def); -}); -function boolean2(params) { - return _boolean(ZodBoolean, params); -} -__name(boolean2, "boolean"); -var ZodBigInt = /* @__PURE__ */ \$constructor("ZodBigInt", (inst, def) => { - \$ZodBigInt.init(inst, def); - ZodType.init(inst, def); - inst.gte = (value, params) => inst.check(_gte(value, params)); - inst.min = (value, params) => inst.check(_gte(value, params)); - inst.gt = (value, params) => inst.check(_gt(value, params)); - inst.gte = (value, params) => inst.check(_gte(value, params)); - inst.min = (value, params) => inst.check(_gte(value, params)); - inst.lt = (value, params) => inst.check(_lt(value, params)); - inst.lte = (value, params) => inst.check(_lte(value, params)); - inst.max = (value, params) => inst.check(_lte(value, params)); - inst.positive = (params) => inst.check(_gt(BigInt(0), params)); - inst.negative = (params) => inst.check(_lt(BigInt(0), params)); - inst.nonpositive = (params) => inst.check(_lte(BigInt(0), params)); - inst.nonnegative = (params) => inst.check(_gte(BigInt(0), params)); - inst.multipleOf = (value, params) => inst.check(_multipleOf(value, params)); - const bag = inst._zod.bag; - inst.minValue = bag.minimum ?? null; - inst.maxValue = bag.maximum ?? null; - inst.format = bag.format ?? null; -}); -function bigint2(params) { - return _bigint(ZodBigInt, params); -} -__name(bigint2, "bigint"); -var ZodBigIntFormat = /* @__PURE__ */ \$constructor("ZodBigIntFormat", (inst, def) => { - \$ZodBigIntFormat.init(inst, def); - ZodBigInt.init(inst, def); -}); -function int64(params) { - return _int64(ZodBigIntFormat, params); -} -__name(int64, "int64"); -function uint64(params) { - return _uint64(ZodBigIntFormat, params); -} -__name(uint64, "uint64"); -var ZodSymbol = /* @__PURE__ */ \$constructor("ZodSymbol", (inst, def) => { - \$ZodSymbol.init(inst, def); - ZodType.init(inst, def); -}); -function symbol15(params) { - return _symbol(ZodSymbol, params); -} -__name(symbol15, "symbol"); -var ZodUndefined = /* @__PURE__ */ \$constructor("ZodUndefined", (inst, def) => { - \$ZodUndefined.init(inst, def); - ZodType.init(inst, def); -}); -function _undefined3(params) { - return _undefined2(ZodUndefined, params); -} -__name(_undefined3, "_undefined"); -var ZodNull = /* @__PURE__ */ \$constructor("ZodNull", (inst, def) => { - \$ZodNull.init(inst, def); - ZodType.init(inst, def); -}); -function _null3(params) { - return _null2(ZodNull, params); -} -__name(_null3, "_null"); -var ZodAny = /* @__PURE__ */ \$constructor("ZodAny", (inst, def) => { - \$ZodAny.init(inst, def); - ZodType.init(inst, def); -}); -function any() { - return _any(ZodAny); -} -__name(any, "any"); -var ZodUnknown = /* @__PURE__ */ \$constructor("ZodUnknown", (inst, def) => { - \$ZodUnknown.init(inst, def); - ZodType.init(inst, def); -}); -function unknown() { - return _unknown(ZodUnknown); -} -__name(unknown, "unknown"); -var ZodNever = /* @__PURE__ */ \$constructor("ZodNever", (inst, def) => { - \$ZodNever.init(inst, def); - ZodType.init(inst, def); -}); -function never(params) { - return _never(ZodNever, params); -} -__name(never, "never"); -var ZodVoid = /* @__PURE__ */ \$constructor("ZodVoid", (inst, def) => { - \$ZodVoid.init(inst, def); - ZodType.init(inst, def); -}); -function _void2(params) { - return _void(ZodVoid, params); -} -__name(_void2, "_void"); -var ZodDate = /* @__PURE__ */ \$constructor("ZodDate", (inst, def) => { - \$ZodDate.init(inst, def); - ZodType.init(inst, def); - inst.min = (value, params) => inst.check(_gte(value, params)); - inst.max = (value, params) => inst.check(_lte(value, params)); - const c = inst._zod.bag; - inst.minDate = c.minimum ? new Date(c.minimum) : null; - inst.maxDate = c.maximum ? new Date(c.maximum) : null; -}); -function date3(params) { - return _date(ZodDate, params); -} -__name(date3, "date"); -var ZodArray = /* @__PURE__ */ \$constructor("ZodArray", (inst, def) => { - \$ZodArray.init(inst, def); - ZodType.init(inst, def); - inst.element = def.element; - inst.min = (minLength, params) => inst.check(_minLength(minLength, params)); - inst.nonempty = (params) => inst.check(_minLength(1, params)); - inst.max = (maxLength, params) => inst.check(_maxLength(maxLength, params)); - inst.length = (len, params) => inst.check(_length(len, params)); - inst.unwrap = () => inst.element; -}); -function array(element, params) { - return _array(ZodArray, element, params); -} -__name(array, "array"); -function keyof(schema) { - const shape = schema._zod.def.shape; - return _enum2(Object.keys(shape)); -} -__name(keyof, "keyof"); -var ZodObject = /* @__PURE__ */ \$constructor("ZodObject", (inst, def) => { - \$ZodObjectJIT.init(inst, def); - ZodType.init(inst, def); - util_exports.defineLazy(inst, "shape", () => { - return def.shape; - }); - inst.keyof = () => _enum2(Object.keys(inst._zod.def.shape)); - inst.catchall = (catchall) => inst.clone({ - ...inst._zod.def, - catchall - }); - inst.passthrough = () => inst.clone({ - ...inst._zod.def, - catchall: unknown() - }); - inst.loose = () => inst.clone({ - ...inst._zod.def, - catchall: unknown() - }); - inst.strict = () => inst.clone({ - ...inst._zod.def, - catchall: never() - }); - inst.strip = () => inst.clone({ - ...inst._zod.def, - catchall: void 0 - }); - inst.extend = (incoming) => { - return util_exports.extend(inst, incoming); - }; - inst.safeExtend = (incoming) => { - return util_exports.safeExtend(inst, incoming); - }; - inst.merge = (other) => util_exports.merge(inst, other); - inst.pick = (mask) => util_exports.pick(inst, mask); - inst.omit = (mask) => util_exports.omit(inst, mask); - inst.partial = (...args) => util_exports.partial(ZodOptional, inst, args[0]); - inst.required = (...args) => util_exports.required(ZodNonOptional, inst, args[0]); -}); -function object(shape, params) { - const def = { - type: "object", - shape: shape ?? {}, - ...util_exports.normalizeParams(params) - }; - return new ZodObject(def); -} -__name(object, "object"); -function strictObject(shape, params) { - return new ZodObject({ - type: "object", - shape, - catchall: never(), - ...util_exports.normalizeParams(params) - }); -} -__name(strictObject, "strictObject"); -function looseObject(shape, params) { - return new ZodObject({ - type: "object", - shape, - catchall: unknown(), - ...util_exports.normalizeParams(params) - }); -} -__name(looseObject, "looseObject"); -var ZodUnion = /* @__PURE__ */ \$constructor("ZodUnion", (inst, def) => { - \$ZodUnion.init(inst, def); - ZodType.init(inst, def); - inst.options = def.options; -}); -function union(options, params) { - return new ZodUnion({ - type: "union", - options, - ...util_exports.normalizeParams(params) - }); -} -__name(union, "union"); -var ZodDiscriminatedUnion = /* @__PURE__ */ \$constructor("ZodDiscriminatedUnion", (inst, def) => { - ZodUnion.init(inst, def); - \$ZodDiscriminatedUnion.init(inst, def); -}); -function discriminatedUnion(discriminator, options, params) { - return new ZodDiscriminatedUnion({ - type: "union", - options, - discriminator, - ...util_exports.normalizeParams(params) - }); -} -__name(discriminatedUnion, "discriminatedUnion"); -var ZodIntersection = /* @__PURE__ */ \$constructor("ZodIntersection", (inst, def) => { - \$ZodIntersection.init(inst, def); - ZodType.init(inst, def); -}); -function intersection(left, right) { - return new ZodIntersection({ - type: "intersection", - left, - right - }); -} -__name(intersection, "intersection"); -var ZodTuple = /* @__PURE__ */ \$constructor("ZodTuple", (inst, def) => { - \$ZodTuple.init(inst, def); - ZodType.init(inst, def); - inst.rest = (rest) => inst.clone({ - ...inst._zod.def, - rest - }); -}); -function tuple(items, _paramsOrRest, _params) { - const hasRest = _paramsOrRest instanceof \$ZodType; - const params = hasRest ? _params : _paramsOrRest; - const rest = hasRest ? _paramsOrRest : null; - return new ZodTuple({ - type: "tuple", - items, - rest, - ...util_exports.normalizeParams(params) - }); -} -__name(tuple, "tuple"); -var ZodRecord = /* @__PURE__ */ \$constructor("ZodRecord", (inst, def) => { - \$ZodRecord.init(inst, def); - ZodType.init(inst, def); - inst.keyType = def.keyType; - inst.valueType = def.valueType; -}); -function record(keyType, valueType, params) { - return new ZodRecord({ - type: "record", - keyType, - valueType, - ...util_exports.normalizeParams(params) - }); -} -__name(record, "record"); -function partialRecord(keyType, valueType, params) { - const k = clone(keyType); - k._zod.values = void 0; - return new ZodRecord({ - type: "record", - keyType: k, - valueType, - ...util_exports.normalizeParams(params) - }); -} -__name(partialRecord, "partialRecord"); -var ZodMap = /* @__PURE__ */ \$constructor("ZodMap", (inst, def) => { - \$ZodMap.init(inst, def); - ZodType.init(inst, def); - inst.keyType = def.keyType; - inst.valueType = def.valueType; -}); -function map(keyType, valueType, params) { - return new ZodMap({ - type: "map", - keyType, - valueType, - ...util_exports.normalizeParams(params) - }); -} -__name(map, "map"); -var ZodSet = /* @__PURE__ */ \$constructor("ZodSet", (inst, def) => { - \$ZodSet.init(inst, def); - ZodType.init(inst, def); - inst.min = (...args) => inst.check(_minSize(...args)); - inst.nonempty = (params) => inst.check(_minSize(1, params)); - inst.max = (...args) => inst.check(_maxSize(...args)); - inst.size = (...args) => inst.check(_size(...args)); -}); -function set(valueType, params) { - return new ZodSet({ - type: "set", - valueType, - ...util_exports.normalizeParams(params) - }); -} -__name(set, "set"); -var ZodEnum = /* @__PURE__ */ \$constructor("ZodEnum", (inst, def) => { - \$ZodEnum.init(inst, def); - ZodType.init(inst, def); - inst.enum = def.entries; - inst.options = Object.values(def.entries); - const keys = new Set(Object.keys(def.entries)); - inst.extract = (values, params) => { - const newEntries = {}; - for (const value of values) { - if (keys.has(value)) { - newEntries[value] = def.entries[value]; - } else throw new Error(\`Key \${value} not found in enum\`); - } - return new ZodEnum({ - ...def, - checks: [], - ...util_exports.normalizeParams(params), - entries: newEntries - }); - }; - inst.exclude = (values, params) => { - const newEntries = { - ...def.entries - }; - for (const value of values) { - if (keys.has(value)) { - delete newEntries[value]; - } else throw new Error(\`Key \${value} not found in enum\`); - } - return new ZodEnum({ - ...def, - checks: [], - ...util_exports.normalizeParams(params), - entries: newEntries - }); - }; -}); -function _enum2(values, params) { - const entries = Array.isArray(values) ? Object.fromEntries(values.map((v) => [ - v, - v - ])) : values; - return new ZodEnum({ - type: "enum", - entries, - ...util_exports.normalizeParams(params) - }); -} -__name(_enum2, "_enum"); -function nativeEnum(entries, params) { - return new ZodEnum({ - type: "enum", - entries, - ...util_exports.normalizeParams(params) - }); -} -__name(nativeEnum, "nativeEnum"); -var ZodLiteral = /* @__PURE__ */ \$constructor("ZodLiteral", (inst, def) => { - \$ZodLiteral.init(inst, def); - ZodType.init(inst, def); - inst.values = new Set(def.values); - Object.defineProperty(inst, "value", { - get() { - if (def.values.length > 1) { - throw new Error("This schema contains multiple valid literal values. Use \`.values\` instead."); - } - return def.values[0]; - } - }); -}); -function literal(value, params) { - return new ZodLiteral({ - type: "literal", - values: Array.isArray(value) ? value : [ - value - ], - ...util_exports.normalizeParams(params) - }); -} -__name(literal, "literal"); -var ZodFile = /* @__PURE__ */ \$constructor("ZodFile", (inst, def) => { - \$ZodFile.init(inst, def); - ZodType.init(inst, def); - inst.min = (size, params) => inst.check(_minSize(size, params)); - inst.max = (size, params) => inst.check(_maxSize(size, params)); - inst.mime = (types, params) => inst.check(_mime(Array.isArray(types) ? types : [ - types - ], params)); -}); -function file(params) { - return _file(ZodFile, params); -} -__name(file, "file"); -var ZodTransform = /* @__PURE__ */ \$constructor("ZodTransform", (inst, def) => { - \$ZodTransform.init(inst, def); - ZodType.init(inst, def); - inst._zod.parse = (payload, _ctx) => { - if (_ctx.direction === "backward") { - throw new \$ZodEncodeError(inst.constructor.name); - } - payload.addIssue = (issue2) => { - if (typeof issue2 === "string") { - payload.issues.push(util_exports.issue(issue2, payload.value, def)); - } else { - const _issue = issue2; - if (_issue.fatal) _issue.continue = false; - _issue.code ?? (_issue.code = "custom"); - _issue.input ?? (_issue.input = payload.value); - _issue.inst ?? (_issue.inst = inst); - payload.issues.push(util_exports.issue(_issue)); - } - }; - const output = def.transform(payload.value, payload); - if (output instanceof Promise) { - return output.then((output2) => { - payload.value = output2; - return payload; - }); - } - payload.value = output; - return payload; - }; -}); -function transform(fn) { - return new ZodTransform({ - type: "transform", - transform: fn - }); -} -__name(transform, "transform"); -var ZodOptional = /* @__PURE__ */ \$constructor("ZodOptional", (inst, def) => { - \$ZodOptional.init(inst, def); - ZodType.init(inst, def); - inst.unwrap = () => inst._zod.def.innerType; -}); -function optional(innerType) { - return new ZodOptional({ - type: "optional", - innerType - }); -} -__name(optional, "optional"); -var ZodNullable = /* @__PURE__ */ \$constructor("ZodNullable", (inst, def) => { - \$ZodNullable.init(inst, def); - ZodType.init(inst, def); - inst.unwrap = () => inst._zod.def.innerType; -}); -function nullable(innerType) { - return new ZodNullable({ - type: "nullable", - innerType - }); -} -__name(nullable, "nullable"); -function nullish2(innerType) { - return optional(nullable(innerType)); -} -__name(nullish2, "nullish"); -var ZodDefault = /* @__PURE__ */ \$constructor("ZodDefault", (inst, def) => { - \$ZodDefault.init(inst, def); - ZodType.init(inst, def); - inst.unwrap = () => inst._zod.def.innerType; - inst.removeDefault = inst.unwrap; -}); -function _default2(innerType, defaultValue) { - return new ZodDefault({ - type: "default", - innerType, - get defaultValue() { - return typeof defaultValue === "function" ? defaultValue() : util_exports.shallowClone(defaultValue); - } - }); -} -__name(_default2, "_default"); -var ZodPrefault = /* @__PURE__ */ \$constructor("ZodPrefault", (inst, def) => { - \$ZodPrefault.init(inst, def); - ZodType.init(inst, def); - inst.unwrap = () => inst._zod.def.innerType; -}); -function prefault(innerType, defaultValue) { - return new ZodPrefault({ - type: "prefault", - innerType, - get defaultValue() { - return typeof defaultValue === "function" ? defaultValue() : util_exports.shallowClone(defaultValue); - } - }); -} -__name(prefault, "prefault"); -var ZodNonOptional = /* @__PURE__ */ \$constructor("ZodNonOptional", (inst, def) => { - \$ZodNonOptional.init(inst, def); - ZodType.init(inst, def); - inst.unwrap = () => inst._zod.def.innerType; -}); -function nonoptional(innerType, params) { - return new ZodNonOptional({ - type: "nonoptional", - innerType, - ...util_exports.normalizeParams(params) - }); -} -__name(nonoptional, "nonoptional"); -var ZodSuccess = /* @__PURE__ */ \$constructor("ZodSuccess", (inst, def) => { - \$ZodSuccess.init(inst, def); - ZodType.init(inst, def); - inst.unwrap = () => inst._zod.def.innerType; -}); -function success(innerType) { - return new ZodSuccess({ - type: "success", - innerType - }); -} -__name(success, "success"); -var ZodCatch = /* @__PURE__ */ \$constructor("ZodCatch", (inst, def) => { - \$ZodCatch.init(inst, def); - ZodType.init(inst, def); - inst.unwrap = () => inst._zod.def.innerType; - inst.removeCatch = inst.unwrap; -}); -function _catch2(innerType, catchValue) { - return new ZodCatch({ - type: "catch", - innerType, - catchValue: typeof catchValue === "function" ? catchValue : () => catchValue - }); -} -__name(_catch2, "_catch"); -var ZodNaN = /* @__PURE__ */ \$constructor("ZodNaN", (inst, def) => { - \$ZodNaN.init(inst, def); - ZodType.init(inst, def); -}); -function nan(params) { - return _nan(ZodNaN, params); -} -__name(nan, "nan"); -var ZodPipe = /* @__PURE__ */ \$constructor("ZodPipe", (inst, def) => { - \$ZodPipe.init(inst, def); - ZodType.init(inst, def); - inst.in = def.in; - inst.out = def.out; -}); -function pipe(in_, out) { - return new ZodPipe({ - type: "pipe", - in: in_, - out - }); -} -__name(pipe, "pipe"); -var ZodCodec = /* @__PURE__ */ \$constructor("ZodCodec", (inst, def) => { - ZodPipe.init(inst, def); - \$ZodCodec.init(inst, def); -}); -function codec(in_, out, params) { - return new ZodCodec({ - type: "pipe", - in: in_, - out, - transform: params.decode, - reverseTransform: params.encode - }); -} -__name(codec, "codec"); -var ZodReadonly = /* @__PURE__ */ \$constructor("ZodReadonly", (inst, def) => { - \$ZodReadonly.init(inst, def); - ZodType.init(inst, def); - inst.unwrap = () => inst._zod.def.innerType; -}); -function readonly(innerType) { - return new ZodReadonly({ - type: "readonly", - innerType - }); -} -__name(readonly, "readonly"); -var ZodTemplateLiteral = /* @__PURE__ */ \$constructor("ZodTemplateLiteral", (inst, def) => { - \$ZodTemplateLiteral.init(inst, def); - ZodType.init(inst, def); -}); -function templateLiteral(parts, params) { - return new ZodTemplateLiteral({ - type: "template_literal", - parts, - ...util_exports.normalizeParams(params) - }); -} -__name(templateLiteral, "templateLiteral"); -var ZodLazy = /* @__PURE__ */ \$constructor("ZodLazy", (inst, def) => { - \$ZodLazy.init(inst, def); - ZodType.init(inst, def); - inst.unwrap = () => inst._zod.def.getter(); -}); -function lazy(getter) { - return new ZodLazy({ - type: "lazy", - getter - }); -} -__name(lazy, "lazy"); -var ZodPromise = /* @__PURE__ */ \$constructor("ZodPromise", (inst, def) => { - \$ZodPromise.init(inst, def); - ZodType.init(inst, def); - inst.unwrap = () => inst._zod.def.innerType; -}); -function promise(innerType) { - return new ZodPromise({ - type: "promise", - innerType - }); -} -__name(promise, "promise"); -var ZodFunction = /* @__PURE__ */ \$constructor("ZodFunction", (inst, def) => { - \$ZodFunction.init(inst, def); - ZodType.init(inst, def); -}); -function _function(params) { - return new ZodFunction({ - type: "function", - input: Array.isArray(params?.input) ? tuple(params?.input) : params?.input ?? array(unknown()), - output: params?.output ?? unknown() - }); -} -__name(_function, "_function"); -var ZodCustom = /* @__PURE__ */ \$constructor("ZodCustom", (inst, def) => { - \$ZodCustom.init(inst, def); - ZodType.init(inst, def); -}); -function check(fn) { - const ch = new \$ZodCheck({ - check: "custom" - }); - ch._zod.check = fn; - return ch; -} -__name(check, "check"); -function custom(fn, _params) { - return _custom(ZodCustom, fn ?? (() => true), _params); -} -__name(custom, "custom"); -function refine(fn, _params = {}) { - return _refine(ZodCustom, fn, _params); -} -__name(refine, "refine"); -function superRefine(fn) { - return _superRefine(fn); -} -__name(superRefine, "superRefine"); -function _instanceof(cls, params = { - error: \`Input not instance of \${cls.name}\` -}) { - const inst = new ZodCustom({ - type: "custom", - check: "custom", - fn: /* @__PURE__ */ __name((data) => data instanceof cls, "fn"), - abort: true, - ...util_exports.normalizeParams(params) - }); - inst._zod.bag.Class = cls; - return inst; -} -__name(_instanceof, "_instanceof"); -var stringbool = /* @__PURE__ */ __name((...args) => _stringbool({ - Codec: ZodCodec, - Boolean: ZodBoolean, - String: ZodString -}, ...args), "stringbool"); -function json(params) { - const jsonSchema2 = lazy(() => { - return union([ - string2(params), - number2(), - boolean2(), - _null3(), - array(jsonSchema2), - record(string2(), jsonSchema2) - ]); - }); - return jsonSchema2; -} -__name(json, "json"); -function preprocess(fn, schema) { - return pipe(transform(fn), schema); -} -__name(preprocess, "preprocess"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/classic/compat.js -var ZodIssueCode = { - invalid_type: "invalid_type", - too_big: "too_big", - too_small: "too_small", - invalid_format: "invalid_format", - not_multiple_of: "not_multiple_of", - unrecognized_keys: "unrecognized_keys", - invalid_union: "invalid_union", - invalid_key: "invalid_key", - invalid_element: "invalid_element", - invalid_value: "invalid_value", - custom: "custom" -}; -function setErrorMap(map2) { - config({ - customError: map2 - }); -} -__name(setErrorMap, "setErrorMap"); -function getErrorMap() { - return config().customError; -} -__name(getErrorMap, "getErrorMap"); -var ZodFirstPartyTypeKind; -/* @__PURE__ */ (function(ZodFirstPartyTypeKind3) { -})(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {})); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/classic/coerce.js -var coerce_exports = {}; -__export(coerce_exports, { - bigint: () => bigint3, - boolean: () => boolean3, - date: () => date4, - number: () => number3, - string: () => string3 -}); -function string3(params) { - return _coercedString(ZodString, params); -} -__name(string3, "string"); -function number3(params) { - return _coercedNumber(ZodNumber, params); -} -__name(number3, "number"); -function boolean3(params) { - return _coercedBoolean(ZodBoolean, params); -} -__name(boolean3, "boolean"); -function bigint3(params) { - return _coercedBigint(ZodBigInt, params); -} -__name(bigint3, "bigint"); -function date4(params) { - return _coercedDate(ZodDate, params); -} -__name(date4, "date"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/classic/external.js -config(en_default()); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/classic/index.js -var classic_default = external_exports; - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v4/index.js -var v4_default = classic_default; - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v3/helpers/util.js -var util; -(function(util2) { - util2.assertEqual = (_) => { - }; - function assertIs2(_arg) { - } - __name(assertIs2, "assertIs"); - util2.assertIs = assertIs2; - function assertNever2(_x) { - throw new Error(); - } - __name(assertNever2, "assertNever"); - util2.assertNever = assertNever2; - util2.arrayToEnum = (items) => { - const obj = {}; - for (const item of items) { - obj[item] = item; - } - return obj; - }; - util2.getValidEnumValues = (obj) => { - const validKeys = util2.objectKeys(obj).filter((k) => typeof obj[obj[k]] !== "number"); - const filtered = {}; - for (const k of validKeys) { - filtered[k] = obj[k]; - } - return util2.objectValues(filtered); - }; - util2.objectValues = (obj) => { - return util2.objectKeys(obj).map(function(e) { - return obj[e]; - }); - }; - util2.objectKeys = typeof Object.keys === "function" ? (obj) => Object.keys(obj) : (object3) => { - const keys = []; - for (const key in object3) { - if (Object.prototype.hasOwnProperty.call(object3, key)) { - keys.push(key); - } - } - return keys; - }; - util2.find = (arr, checker) => { - for (const item of arr) { - if (checker(item)) return item; - } - return void 0; - }; - util2.isInteger = typeof Number.isInteger === "function" ? (val) => Number.isInteger(val) : (val) => typeof val === "number" && Number.isFinite(val) && Math.floor(val) === val; - function joinValues2(array2, separator = " | ") { - return array2.map((val) => typeof val === "string" ? \`'\${val}'\` : val).join(separator); - } - __name(joinValues2, "joinValues"); - util2.joinValues = joinValues2; - util2.jsonStringifyReplacer = (_, value) => { - if (typeof value === "bigint") { - return value.toString(); - } - return value; - }; -})(util || (util = {})); -var objectUtil; -(function(objectUtil2) { - objectUtil2.mergeShapes = (first, second) => { - return { - ...first, - ...second - }; - }; -})(objectUtil || (objectUtil = {})); -var ZodParsedType = util.arrayToEnum([ - "string", - "nan", - "number", - "integer", - "float", - "boolean", - "date", - "bigint", - "symbol", - "function", - "undefined", - "null", - "array", - "object", - "unknown", - "promise", - "void", - "never", - "map", - "set" -]); -var getParsedType2 = /* @__PURE__ */ __name((data) => { - const t = typeof data; - switch (t) { - case "undefined": - return ZodParsedType.undefined; - case "string": - return ZodParsedType.string; - case "number": - return Number.isNaN(data) ? ZodParsedType.nan : ZodParsedType.number; - case "boolean": - return ZodParsedType.boolean; - case "function": - return ZodParsedType.function; - case "bigint": - return ZodParsedType.bigint; - case "symbol": - return ZodParsedType.symbol; - case "object": - if (Array.isArray(data)) { - return ZodParsedType.array; - } - if (data === null) { - return ZodParsedType.null; - } - if (data.then && typeof data.then === "function" && data.catch && typeof data.catch === "function") { - return ZodParsedType.promise; - } - if (typeof Map !== "undefined" && data instanceof Map) { - return ZodParsedType.map; - } - if (typeof Set !== "undefined" && data instanceof Set) { - return ZodParsedType.set; - } - if (typeof Date !== "undefined" && data instanceof Date) { - return ZodParsedType.date; - } - return ZodParsedType.object; - default: - return ZodParsedType.unknown; - } -}, "getParsedType"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v3/ZodError.js -var ZodIssueCode2 = util.arrayToEnum([ - "invalid_type", - "invalid_literal", - "custom", - "invalid_union", - "invalid_union_discriminator", - "invalid_enum_value", - "unrecognized_keys", - "invalid_arguments", - "invalid_return_type", - "invalid_date", - "invalid_string", - "too_small", - "too_big", - "invalid_intersection_types", - "not_multiple_of", - "not_finite" -]); -var ZodError2 = class _ZodError extends Error { - static { - __name(this, "ZodError"); - } - get errors() { - return this.issues; - } - constructor(issues) { - super(); - this.issues = []; - this.addIssue = (sub) => { - this.issues = [ - ...this.issues, - sub - ]; - }; - this.addIssues = (subs = []) => { - this.issues = [ - ...this.issues, - ...subs - ]; - }; - const actualProto = new.target.prototype; - if (Object.setPrototypeOf) { - Object.setPrototypeOf(this, actualProto); - } else { - this.__proto__ = actualProto; - } - this.name = "ZodError"; - this.issues = issues; - } - format(_mapper) { - const mapper = _mapper || function(issue2) { - return issue2.message; - }; - const fieldErrors = { - _errors: [] - }; - const processError = /* @__PURE__ */ __name((error45) => { - for (const issue2 of error45.issues) { - if (issue2.code === "invalid_union") { - issue2.unionErrors.map(processError); - } else if (issue2.code === "invalid_return_type") { - processError(issue2.returnTypeError); - } else if (issue2.code === "invalid_arguments") { - processError(issue2.argumentsError); - } else if (issue2.path.length === 0) { - fieldErrors._errors.push(mapper(issue2)); - } else { - let curr = fieldErrors; - let i = 0; - while (i < issue2.path.length) { - const el = issue2.path[i]; - const terminal = i === issue2.path.length - 1; - if (!terminal) { - curr[el] = curr[el] || { - _errors: [] - }; - } else { - curr[el] = curr[el] || { - _errors: [] - }; - curr[el]._errors.push(mapper(issue2)); - } - curr = curr[el]; - i++; - } - } - } - }, "processError"); - processError(this); - return fieldErrors; - } - static assert(value) { - if (!(value instanceof _ZodError)) { - throw new Error(\`Not a ZodError: \${value}\`); - } - } - toString() { - return this.message; - } - get message() { - return JSON.stringify(this.issues, util.jsonStringifyReplacer, 2); - } - get isEmpty() { - return this.issues.length === 0; - } - flatten(mapper = (issue2) => issue2.message) { - const fieldErrors = {}; - const formErrors = []; - for (const sub of this.issues) { - if (sub.path.length > 0) { - const firstEl = sub.path[0]; - fieldErrors[firstEl] = fieldErrors[firstEl] || []; - fieldErrors[firstEl].push(mapper(sub)); - } else { - formErrors.push(mapper(sub)); - } - } - return { - formErrors, - fieldErrors - }; - } - get formErrors() { - return this.flatten(); - } -}; -ZodError2.create = (issues) => { - const error45 = new ZodError2(issues); - return error45; -}; - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v3/locales/en.js -var errorMap = /* @__PURE__ */ __name((issue2, _ctx) => { - let message; - switch (issue2.code) { - case ZodIssueCode2.invalid_type: - if (issue2.received === ZodParsedType.undefined) { - message = "Required"; - } else { - message = \`Expected \${issue2.expected}, received \${issue2.received}\`; - } - break; - case ZodIssueCode2.invalid_literal: - message = \`Invalid literal value, expected \${JSON.stringify(issue2.expected, util.jsonStringifyReplacer)}\`; - break; - case ZodIssueCode2.unrecognized_keys: - message = \`Unrecognized key(s) in object: \${util.joinValues(issue2.keys, ", ")}\`; - break; - case ZodIssueCode2.invalid_union: - message = \`Invalid input\`; - break; - case ZodIssueCode2.invalid_union_discriminator: - message = \`Invalid discriminator value. Expected \${util.joinValues(issue2.options)}\`; - break; - case ZodIssueCode2.invalid_enum_value: - message = \`Invalid enum value. Expected \${util.joinValues(issue2.options)}, received '\${issue2.received}'\`; - break; - case ZodIssueCode2.invalid_arguments: - message = \`Invalid function arguments\`; - break; - case ZodIssueCode2.invalid_return_type: - message = \`Invalid function return type\`; - break; - case ZodIssueCode2.invalid_date: - message = \`Invalid date\`; - break; - case ZodIssueCode2.invalid_string: - if (typeof issue2.validation === "object") { - if ("includes" in issue2.validation) { - message = \`Invalid input: must include "\${issue2.validation.includes}"\`; - if (typeof issue2.validation.position === "number") { - message = \`\${message} at one or more positions greater than or equal to \${issue2.validation.position}\`; - } - } else if ("startsWith" in issue2.validation) { - message = \`Invalid input: must start with "\${issue2.validation.startsWith}"\`; - } else if ("endsWith" in issue2.validation) { - message = \`Invalid input: must end with "\${issue2.validation.endsWith}"\`; - } else { - util.assertNever(issue2.validation); - } - } else if (issue2.validation !== "regex") { - message = \`Invalid \${issue2.validation}\`; - } else { - message = "Invalid"; - } - break; - case ZodIssueCode2.too_small: - if (issue2.type === "array") message = \`Array must contain \${issue2.exact ? "exactly" : issue2.inclusive ? \`at least\` : \`more than\`} \${issue2.minimum} element(s)\`; - else if (issue2.type === "string") message = \`String must contain \${issue2.exact ? "exactly" : issue2.inclusive ? \`at least\` : \`over\`} \${issue2.minimum} character(s)\`; - else if (issue2.type === "number") message = \`Number must be \${issue2.exact ? \`exactly equal to \` : issue2.inclusive ? \`greater than or equal to \` : \`greater than \`}\${issue2.minimum}\`; - else if (issue2.type === "bigint") message = \`Number must be \${issue2.exact ? \`exactly equal to \` : issue2.inclusive ? \`greater than or equal to \` : \`greater than \`}\${issue2.minimum}\`; - else if (issue2.type === "date") message = \`Date must be \${issue2.exact ? \`exactly equal to \` : issue2.inclusive ? \`greater than or equal to \` : \`greater than \`}\${new Date(Number(issue2.minimum))}\`; - else message = "Invalid input"; - break; - case ZodIssueCode2.too_big: - if (issue2.type === "array") message = \`Array must contain \${issue2.exact ? \`exactly\` : issue2.inclusive ? \`at most\` : \`less than\`} \${issue2.maximum} element(s)\`; - else if (issue2.type === "string") message = \`String must contain \${issue2.exact ? \`exactly\` : issue2.inclusive ? \`at most\` : \`under\`} \${issue2.maximum} character(s)\`; - else if (issue2.type === "number") message = \`Number must be \${issue2.exact ? \`exactly\` : issue2.inclusive ? \`less than or equal to\` : \`less than\`} \${issue2.maximum}\`; - else if (issue2.type === "bigint") message = \`BigInt must be \${issue2.exact ? \`exactly\` : issue2.inclusive ? \`less than or equal to\` : \`less than\`} \${issue2.maximum}\`; - else if (issue2.type === "date") message = \`Date must be \${issue2.exact ? \`exactly\` : issue2.inclusive ? \`smaller than or equal to\` : \`smaller than\`} \${new Date(Number(issue2.maximum))}\`; - else message = "Invalid input"; - break; - case ZodIssueCode2.custom: - message = \`Invalid input\`; - break; - case ZodIssueCode2.invalid_intersection_types: - message = \`Intersection results could not be merged\`; - break; - case ZodIssueCode2.not_multiple_of: - message = \`Number must be a multiple of \${issue2.multipleOf}\`; - break; - case ZodIssueCode2.not_finite: - message = "Number must be finite"; - break; - default: - message = _ctx.defaultError; - util.assertNever(issue2); - } - return { - message - }; -}, "errorMap"); -var en_default2 = errorMap; - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v3/errors.js -var overrideErrorMap = en_default2; -function getErrorMap2() { - return overrideErrorMap; -} -__name(getErrorMap2, "getErrorMap"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v3/helpers/parseUtil.js -var makeIssue = /* @__PURE__ */ __name((params) => { - const { data, path, errorMaps, issueData } = params; - const fullPath = [ - ...path, - ...issueData.path || [] - ]; - const fullIssue = { - ...issueData, - path: fullPath - }; - if (issueData.message !== void 0) { - return { - ...issueData, - path: fullPath, - message: issueData.message - }; - } - let errorMessage = ""; - const maps = errorMaps.filter((m) => !!m).slice().reverse(); - for (const map2 of maps) { - errorMessage = map2(fullIssue, { - data, - defaultError: errorMessage - }).message; - } - return { - ...issueData, - path: fullPath, - message: errorMessage - }; -}, "makeIssue"); -function addIssueToContext(ctx, issueData) { - const overrideMap = getErrorMap2(); - const issue2 = makeIssue({ - issueData, - data: ctx.data, - path: ctx.path, - errorMaps: [ - ctx.common.contextualErrorMap, - ctx.schemaErrorMap, - overrideMap, - overrideMap === en_default2 ? void 0 : en_default2 - ].filter((x) => !!x) - }); - ctx.common.issues.push(issue2); -} -__name(addIssueToContext, "addIssueToContext"); -var ParseStatus = class _ParseStatus { - static { - __name(this, "ParseStatus"); - } - constructor() { - this.value = "valid"; - } - dirty() { - if (this.value === "valid") this.value = "dirty"; - } - abort() { - if (this.value !== "aborted") this.value = "aborted"; - } - static mergeArray(status, results) { - const arrayValue = []; - for (const s of results) { - if (s.status === "aborted") return INVALID; - if (s.status === "dirty") status.dirty(); - arrayValue.push(s.value); - } - return { - status: status.value, - value: arrayValue - }; - } - static async mergeObjectAsync(status, pairs) { - const syncPairs = []; - for (const pair of pairs) { - const key = await pair.key; - const value = await pair.value; - syncPairs.push({ - key, - value - }); - } - return _ParseStatus.mergeObjectSync(status, syncPairs); - } - static mergeObjectSync(status, pairs) { - const finalObject = {}; - for (const pair of pairs) { - const { key, value } = pair; - if (key.status === "aborted") return INVALID; - if (value.status === "aborted") return INVALID; - if (key.status === "dirty") status.dirty(); - if (value.status === "dirty") status.dirty(); - if (key.value !== "__proto__" && (typeof value.value !== "undefined" || pair.alwaysSet)) { - finalObject[key.value] = value.value; - } - } - return { - status: status.value, - value: finalObject - }; - } -}; -var INVALID = Object.freeze({ - status: "aborted" -}); -var DIRTY = /* @__PURE__ */ __name((value) => ({ - status: "dirty", - value -}), "DIRTY"); -var OK = /* @__PURE__ */ __name((value) => ({ - status: "valid", - value -}), "OK"); -var isAborted = /* @__PURE__ */ __name((x) => x.status === "aborted", "isAborted"); -var isDirty = /* @__PURE__ */ __name((x) => x.status === "dirty", "isDirty"); -var isValid = /* @__PURE__ */ __name((x) => x.status === "valid", "isValid"); -var isAsync = /* @__PURE__ */ __name((x) => typeof Promise !== "undefined" && x instanceof Promise, "isAsync"); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v3/helpers/errorUtil.js -var errorUtil; -(function(errorUtil2) { - errorUtil2.errToObj = (message) => typeof message === "string" ? { - message - } : message || {}; - errorUtil2.toString = (message) => typeof message === "string" ? message : message?.message; -})(errorUtil || (errorUtil = {})); - -// ../../node_modules/.pnpm/zod@4.1.11/node_modules/zod/v3/types.js -var ParseInputLazyPath = class { - static { - __name(this, "ParseInputLazyPath"); - } - constructor(parent, value, path, key) { - this._cachedPath = []; - this.parent = parent; - this.data = value; - this._path = path; - this._key = key; - } - get path() { - if (!this._cachedPath.length) { - if (Array.isArray(this._key)) { - this._cachedPath.push(...this._path, ...this._key); - } else { - this._cachedPath.push(...this._path, this._key); - } - } - return this._cachedPath; - } -}; -var handleResult = /* @__PURE__ */ __name((ctx, result) => { - if (isValid(result)) { - return { - success: true, - data: result.value - }; - } else { - if (!ctx.common.issues.length) { - throw new Error("Validation failed but no issues detected."); - } - return { - success: false, - get error() { - if (this._error) return this._error; - const error45 = new ZodError2(ctx.common.issues); - this._error = error45; - return this._error; - } - }; - } -}, "handleResult"); -function processCreateParams(params) { - if (!params) return {}; - const { errorMap: errorMap2, invalid_type_error, required_error, description } = params; - if (errorMap2 && (invalid_type_error || required_error)) { - throw new Error(\`Can't use "invalid_type_error" or "required_error" in conjunction with custom error map.\`); - } - if (errorMap2) return { - errorMap: errorMap2, - description - }; - const customMap = /* @__PURE__ */ __name((iss, ctx) => { - const { message } = params; - if (iss.code === "invalid_enum_value") { - return { - message: message ?? ctx.defaultError - }; - } - if (typeof ctx.data === "undefined") { - return { - message: message ?? required_error ?? ctx.defaultError - }; - } - if (iss.code !== "invalid_type") return { - message: ctx.defaultError - }; - return { - message: message ?? invalid_type_error ?? ctx.defaultError - }; - }, "customMap"); - return { - errorMap: customMap, - description - }; -} -__name(processCreateParams, "processCreateParams"); -var ZodType2 = class { - static { - __name(this, "ZodType"); - } - get description() { - return this._def.description; - } - _getType(input) { - return getParsedType2(input.data); - } - _getOrReturnCtx(input, ctx) { - return ctx || { - common: input.parent.common, - data: input.data, - parsedType: getParsedType2(input.data), - schemaErrorMap: this._def.errorMap, - path: input.path, - parent: input.parent - }; - } - _processInputParams(input) { - return { - status: new ParseStatus(), - ctx: { - common: input.parent.common, - data: input.data, - parsedType: getParsedType2(input.data), - schemaErrorMap: this._def.errorMap, - path: input.path, - parent: input.parent - } - }; - } - _parseSync(input) { - const result = this._parse(input); - if (isAsync(result)) { - throw new Error("Synchronous parse encountered promise."); - } - return result; - } - _parseAsync(input) { - const result = this._parse(input); - return Promise.resolve(result); - } - parse(data, params) { - const result = this.safeParse(data, params); - if (result.success) return result.data; - throw result.error; - } - safeParse(data, params) { - const ctx = { - common: { - issues: [], - async: params?.async ?? false, - contextualErrorMap: params?.errorMap - }, - path: params?.path || [], - schemaErrorMap: this._def.errorMap, - parent: null, - data, - parsedType: getParsedType2(data) - }; - const result = this._parseSync({ - data, - path: ctx.path, - parent: ctx - }); - return handleResult(ctx, result); - } - "~validate"(data) { - const ctx = { - common: { - issues: [], - async: !!this["~standard"].async - }, - path: [], - schemaErrorMap: this._def.errorMap, - parent: null, - data, - parsedType: getParsedType2(data) - }; - if (!this["~standard"].async) { - try { - const result = this._parseSync({ - data, - path: [], - parent: ctx - }); - return isValid(result) ? { - value: result.value - } : { - issues: ctx.common.issues - }; - } catch (err) { - if (err?.message?.toLowerCase()?.includes("encountered")) { - this["~standard"].async = true; - } - ctx.common = { - issues: [], - async: true - }; - } - } - return this._parseAsync({ - data, - path: [], - parent: ctx - }).then((result) => isValid(result) ? { - value: result.value - } : { - issues: ctx.common.issues - }); - } - async parseAsync(data, params) { - const result = await this.safeParseAsync(data, params); - if (result.success) return result.data; - throw result.error; - } - async safeParseAsync(data, params) { - const ctx = { - common: { - issues: [], - contextualErrorMap: params?.errorMap, - async: true - }, - path: params?.path || [], - schemaErrorMap: this._def.errorMap, - parent: null, - data, - parsedType: getParsedType2(data) - }; - const maybeAsyncResult = this._parse({ - data, - path: ctx.path, - parent: ctx - }); - const result = await (isAsync(maybeAsyncResult) ? maybeAsyncResult : Promise.resolve(maybeAsyncResult)); - return handleResult(ctx, result); - } - refine(check2, message) { - const getIssueProperties = /* @__PURE__ */ __name((val) => { - if (typeof message === "string" || typeof message === "undefined") { - return { - message - }; - } else if (typeof message === "function") { - return message(val); - } else { - return message; - } - }, "getIssueProperties"); - return this._refinement((val, ctx) => { - const result = check2(val); - const setError = /* @__PURE__ */ __name(() => ctx.addIssue({ - code: ZodIssueCode2.custom, - ...getIssueProperties(val) - }), "setError"); - if (typeof Promise !== "undefined" && result instanceof Promise) { - return result.then((data) => { - if (!data) { - setError(); - return false; - } else { - return true; - } - }); - } - if (!result) { - setError(); - return false; - } else { - return true; - } - }); - } - refinement(check2, refinementData) { - return this._refinement((val, ctx) => { - if (!check2(val)) { - ctx.addIssue(typeof refinementData === "function" ? refinementData(val, ctx) : refinementData); - return false; - } else { - return true; - } - }); - } - _refinement(refinement) { - return new ZodEffects({ - schema: this, - typeName: ZodFirstPartyTypeKind2.ZodEffects, - effect: { - type: "refinement", - refinement - } - }); - } - superRefine(refinement) { - return this._refinement(refinement); - } - constructor(def) { - this.spa = this.safeParseAsync; - this._def = def; - this.parse = this.parse.bind(this); - this.safeParse = this.safeParse.bind(this); - this.parseAsync = this.parseAsync.bind(this); - this.safeParseAsync = this.safeParseAsync.bind(this); - this.spa = this.spa.bind(this); - this.refine = this.refine.bind(this); - this.refinement = this.refinement.bind(this); - this.superRefine = this.superRefine.bind(this); - this.optional = this.optional.bind(this); - this.nullable = this.nullable.bind(this); - this.nullish = this.nullish.bind(this); - this.array = this.array.bind(this); - this.promise = this.promise.bind(this); - this.or = this.or.bind(this); - this.and = this.and.bind(this); - this.transform = this.transform.bind(this); - this.brand = this.brand.bind(this); - this.default = this.default.bind(this); - this.catch = this.catch.bind(this); - this.describe = this.describe.bind(this); - this.pipe = this.pipe.bind(this); - this.readonly = this.readonly.bind(this); - this.isNullable = this.isNullable.bind(this); - this.isOptional = this.isOptional.bind(this); - this["~standard"] = { - version: 1, - vendor: "zod", - validate: /* @__PURE__ */ __name((data) => this["~validate"](data), "validate") - }; - } - optional() { - return ZodOptional2.create(this, this._def); - } - nullable() { - return ZodNullable2.create(this, this._def); - } - nullish() { - return this.nullable().optional(); - } - array() { - return ZodArray2.create(this); - } - promise() { - return ZodPromise2.create(this, this._def); - } - or(option) { - return ZodUnion2.create([ - this, - option - ], this._def); - } - and(incoming) { - return ZodIntersection2.create(this, incoming, this._def); - } - transform(transform2) { - return new ZodEffects({ - ...processCreateParams(this._def), - schema: this, - typeName: ZodFirstPartyTypeKind2.ZodEffects, - effect: { - type: "transform", - transform: transform2 - } - }); - } - default(def) { - const defaultValueFunc = typeof def === "function" ? def : () => def; - return new ZodDefault2({ - ...processCreateParams(this._def), - innerType: this, - defaultValue: defaultValueFunc, - typeName: ZodFirstPartyTypeKind2.ZodDefault - }); - } - brand() { - return new ZodBranded({ - typeName: ZodFirstPartyTypeKind2.ZodBranded, - type: this, - ...processCreateParams(this._def) - }); - } - catch(def) { - const catchValueFunc = typeof def === "function" ? def : () => def; - return new ZodCatch2({ - ...processCreateParams(this._def), - innerType: this, - catchValue: catchValueFunc, - typeName: ZodFirstPartyTypeKind2.ZodCatch - }); - } - describe(description) { - const This = this.constructor; - return new This({ - ...this._def, - description - }); - } - pipe(target) { - return ZodPipeline.create(this, target); - } - readonly() { - return ZodReadonly2.create(this); - } - isOptional() { - return this.safeParse(void 0).success; - } - isNullable() { - return this.safeParse(null).success; - } -}; -var cuidRegex = /^c[^\\s-]{8,}\$/i; -var cuid2Regex = /^[0-9a-z]+\$/; -var ulidRegex = /^[0-9A-HJKMNP-TV-Z]{26}\$/i; -var uuidRegex = /^[0-9a-fA-F]{8}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{12}\$/i; -var nanoidRegex = /^[a-z0-9_-]{21}\$/i; -var jwtRegex = /^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*\$/; -var durationRegex = /^[-+]?P(?!\$)(?:(?:[-+]?\\d+Y)|(?:[-+]?\\d+[.,]\\d+Y\$))?(?:(?:[-+]?\\d+M)|(?:[-+]?\\d+[.,]\\d+M\$))?(?:(?:[-+]?\\d+W)|(?:[-+]?\\d+[.,]\\d+W\$))?(?:(?:[-+]?\\d+D)|(?:[-+]?\\d+[.,]\\d+D\$))?(?:T(?=[\\d+-])(?:(?:[-+]?\\d+H)|(?:[-+]?\\d+[.,]\\d+H\$))?(?:(?:[-+]?\\d+M)|(?:[-+]?\\d+[.,]\\d+M\$))?(?:[-+]?\\d+(?:[.,]\\d+)?S)?)??\$/; -var emailRegex = /^(?!\\.)(?!.*\\.\\.)([A-Z0-9_'+\\-\\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\\-]*\\.)+[A-Z]{2,}\$/i; -var _emojiRegex = \`^(\\\\p{Extended_Pictographic}|\\\\p{Emoji_Component})+\$\`; -var emojiRegex; -var ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\$/; -var ipv4CidrRegex = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\/(3[0-2]|[12]?[0-9])\$/; -var ipv6Regex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\$/; -var ipv6CidrRegex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])\$/; -var base64Regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?\$/; -var base64urlRegex = /^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?\$/; -var dateRegexSource = \`((\\\\d\\\\d[2468][048]|\\\\d\\\\d[13579][26]|\\\\d\\\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\\\d|30)|(02)-(0[1-9]|1\\\\d|2[0-8])))\`; -var dateRegex = new RegExp(\`^\${dateRegexSource}\$\`); -function timeRegexSource(args) { - let secondsRegexSource = \`[0-5]\\\\d\`; - if (args.precision) { - secondsRegexSource = \`\${secondsRegexSource}\\\\.\\\\d{\${args.precision}}\`; - } else if (args.precision == null) { - secondsRegexSource = \`\${secondsRegexSource}(\\\\.\\\\d+)?\`; - } - const secondsQuantifier = args.precision ? "+" : "?"; - return \`([01]\\\\d|2[0-3]):[0-5]\\\\d(:\${secondsRegexSource})\${secondsQuantifier}\`; -} -__name(timeRegexSource, "timeRegexSource"); -function timeRegex(args) { - return new RegExp(\`^\${timeRegexSource(args)}\$\`); -} -__name(timeRegex, "timeRegex"); -function datetimeRegex(args) { - let regex = \`\${dateRegexSource}T\${timeRegexSource(args)}\`; - const opts = []; - opts.push(args.local ? \`Z?\` : \`Z\`); - if (args.offset) opts.push(\`([+-]\\\\d{2}:?\\\\d{2})\`); - regex = \`\${regex}(\${opts.join("|")})\`; - return new RegExp(\`^\${regex}\$\`); -} -__name(datetimeRegex, "datetimeRegex"); -function isValidIP(ip, version2) { - if ((version2 === "v4" || !version2) && ipv4Regex.test(ip)) { - return true; - } - if ((version2 === "v6" || !version2) && ipv6Regex.test(ip)) { - return true; - } - return false; -} -__name(isValidIP, "isValidIP"); -function isValidJWT2(jwt2, alg) { - if (!jwtRegex.test(jwt2)) return false; - try { - const [header] = jwt2.split("."); - if (!header) return false; - const base643 = header.replace(/-/g, "+").replace(/_/g, "/").padEnd(header.length + (4 - header.length % 4) % 4, "="); - const decoded = JSON.parse(atob(base643)); - if (typeof decoded !== "object" || decoded === null) return false; - if ("typ" in decoded && decoded?.typ !== "JWT") return false; - if (!decoded.alg) return false; - if (alg && decoded.alg !== alg) return false; - return true; - } catch { - return false; - } -} -__name(isValidJWT2, "isValidJWT"); -function isValidCidr(ip, version2) { - if ((version2 === "v4" || !version2) && ipv4CidrRegex.test(ip)) { - return true; - } - if ((version2 === "v6" || !version2) && ipv6CidrRegex.test(ip)) { - return true; - } - return false; -} -__name(isValidCidr, "isValidCidr"); -var ZodString2 = class _ZodString2 extends ZodType2 { - static { - __name(this, "ZodString"); - } - _parse(input) { - if (this._def.coerce) { - input.data = String(input.data); - } - const parsedType7 = this._getType(input); - if (parsedType7 !== ZodParsedType.string) { - const ctx2 = this._getOrReturnCtx(input); - addIssueToContext(ctx2, { - code: ZodIssueCode2.invalid_type, - expected: ZodParsedType.string, - received: ctx2.parsedType - }); - return INVALID; - } - const status = new ParseStatus(); - let ctx = void 0; - for (const check2 of this._def.checks) { - if (check2.kind === "min") { - if (input.data.length < check2.value) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - code: ZodIssueCode2.too_small, - minimum: check2.value, - type: "string", - inclusive: true, - exact: false, - message: check2.message - }); - status.dirty(); - } - } else if (check2.kind === "max") { - if (input.data.length > check2.value) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - code: ZodIssueCode2.too_big, - maximum: check2.value, - type: "string", - inclusive: true, - exact: false, - message: check2.message - }); - status.dirty(); - } - } else if (check2.kind === "length") { - const tooBig = input.data.length > check2.value; - const tooSmall = input.data.length < check2.value; - if (tooBig || tooSmall) { - ctx = this._getOrReturnCtx(input, ctx); - if (tooBig) { - addIssueToContext(ctx, { - code: ZodIssueCode2.too_big, - maximum: check2.value, - type: "string", - inclusive: true, - exact: true, - message: check2.message - }); - } else if (tooSmall) { - addIssueToContext(ctx, { - code: ZodIssueCode2.too_small, - minimum: check2.value, - type: "string", - inclusive: true, - exact: true, - message: check2.message - }); - } - status.dirty(); - } - } else if (check2.kind === "email") { - if (!emailRegex.test(input.data)) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - validation: "email", - code: ZodIssueCode2.invalid_string, - message: check2.message - }); - status.dirty(); - } - } else if (check2.kind === "emoji") { - if (!emojiRegex) { - emojiRegex = new RegExp(_emojiRegex, "u"); - } - if (!emojiRegex.test(input.data)) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - validation: "emoji", - code: ZodIssueCode2.invalid_string, - message: check2.message - }); - status.dirty(); - } - } else if (check2.kind === "uuid") { - if (!uuidRegex.test(input.data)) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - validation: "uuid", - code: ZodIssueCode2.invalid_string, - message: check2.message - }); - status.dirty(); - } - } else if (check2.kind === "nanoid") { - if (!nanoidRegex.test(input.data)) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - validation: "nanoid", - code: ZodIssueCode2.invalid_string, - message: check2.message - }); - status.dirty(); - } - } else if (check2.kind === "cuid") { - if (!cuidRegex.test(input.data)) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - validation: "cuid", - code: ZodIssueCode2.invalid_string, - message: check2.message - }); - status.dirty(); - } - } else if (check2.kind === "cuid2") { - if (!cuid2Regex.test(input.data)) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - validation: "cuid2", - code: ZodIssueCode2.invalid_string, - message: check2.message - }); - status.dirty(); - } - } else if (check2.kind === "ulid") { - if (!ulidRegex.test(input.data)) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - validation: "ulid", - code: ZodIssueCode2.invalid_string, - message: check2.message - }); - status.dirty(); - } - } else if (check2.kind === "url") { - try { - new URL(input.data); - } catch { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - validation: "url", - code: ZodIssueCode2.invalid_string, - message: check2.message - }); - status.dirty(); - } - } else if (check2.kind === "regex") { - check2.regex.lastIndex = 0; - const testResult = check2.regex.test(input.data); - if (!testResult) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - validation: "regex", - code: ZodIssueCode2.invalid_string, - message: check2.message - }); - status.dirty(); - } - } else if (check2.kind === "trim") { - input.data = input.data.trim(); - } else if (check2.kind === "includes") { - if (!input.data.includes(check2.value, check2.position)) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - code: ZodIssueCode2.invalid_string, - validation: { - includes: check2.value, - position: check2.position - }, - message: check2.message - }); - status.dirty(); - } - } else if (check2.kind === "toLowerCase") { - input.data = input.data.toLowerCase(); - } else if (check2.kind === "toUpperCase") { - input.data = input.data.toUpperCase(); - } else if (check2.kind === "startsWith") { - if (!input.data.startsWith(check2.value)) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - code: ZodIssueCode2.invalid_string, - validation: { - startsWith: check2.value - }, - message: check2.message - }); - status.dirty(); - } - } else if (check2.kind === "endsWith") { - if (!input.data.endsWith(check2.value)) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - code: ZodIssueCode2.invalid_string, - validation: { - endsWith: check2.value - }, - message: check2.message - }); - status.dirty(); - } - } else if (check2.kind === "datetime") { - const regex = datetimeRegex(check2); - if (!regex.test(input.data)) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - code: ZodIssueCode2.invalid_string, - validation: "datetime", - message: check2.message - }); - status.dirty(); - } - } else if (check2.kind === "date") { - const regex = dateRegex; - if (!regex.test(input.data)) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - code: ZodIssueCode2.invalid_string, - validation: "date", - message: check2.message - }); - status.dirty(); - } - } else if (check2.kind === "time") { - const regex = timeRegex(check2); - if (!regex.test(input.data)) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - code: ZodIssueCode2.invalid_string, - validation: "time", - message: check2.message - }); - status.dirty(); - } - } else if (check2.kind === "duration") { - if (!durationRegex.test(input.data)) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - validation: "duration", - code: ZodIssueCode2.invalid_string, - message: check2.message - }); - status.dirty(); - } - } else if (check2.kind === "ip") { - if (!isValidIP(input.data, check2.version)) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - validation: "ip", - code: ZodIssueCode2.invalid_string, - message: check2.message - }); - status.dirty(); - } - } else if (check2.kind === "jwt") { - if (!isValidJWT2(input.data, check2.alg)) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - validation: "jwt", - code: ZodIssueCode2.invalid_string, - message: check2.message - }); - status.dirty(); - } - } else if (check2.kind === "cidr") { - if (!isValidCidr(input.data, check2.version)) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - validation: "cidr", - code: ZodIssueCode2.invalid_string, - message: check2.message - }); - status.dirty(); - } - } else if (check2.kind === "base64") { - if (!base64Regex.test(input.data)) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - validation: "base64", - code: ZodIssueCode2.invalid_string, - message: check2.message - }); - status.dirty(); - } - } else if (check2.kind === "base64url") { - if (!base64urlRegex.test(input.data)) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - validation: "base64url", - code: ZodIssueCode2.invalid_string, - message: check2.message - }); - status.dirty(); - } - } else { - util.assertNever(check2); - } - } - return { - status: status.value, - value: input.data - }; - } - _regex(regex, validation, message) { - return this.refinement((data) => regex.test(data), { - validation, - code: ZodIssueCode2.invalid_string, - ...errorUtil.errToObj(message) - }); - } - _addCheck(check2) { - return new _ZodString2({ - ...this._def, - checks: [ - ...this._def.checks, - check2 - ] - }); - } - email(message) { - return this._addCheck({ - kind: "email", - ...errorUtil.errToObj(message) - }); - } - url(message) { - return this._addCheck({ - kind: "url", - ...errorUtil.errToObj(message) - }); - } - emoji(message) { - return this._addCheck({ - kind: "emoji", - ...errorUtil.errToObj(message) - }); - } - uuid(message) { - return this._addCheck({ - kind: "uuid", - ...errorUtil.errToObj(message) - }); - } - nanoid(message) { - return this._addCheck({ - kind: "nanoid", - ...errorUtil.errToObj(message) - }); - } - cuid(message) { - return this._addCheck({ - kind: "cuid", - ...errorUtil.errToObj(message) - }); - } - cuid2(message) { - return this._addCheck({ - kind: "cuid2", - ...errorUtil.errToObj(message) - }); - } - ulid(message) { - return this._addCheck({ - kind: "ulid", - ...errorUtil.errToObj(message) - }); - } - base64(message) { - return this._addCheck({ - kind: "base64", - ...errorUtil.errToObj(message) - }); - } - base64url(message) { - return this._addCheck({ - kind: "base64url", - ...errorUtil.errToObj(message) - }); - } - jwt(options) { - return this._addCheck({ - kind: "jwt", - ...errorUtil.errToObj(options) - }); - } - ip(options) { - return this._addCheck({ - kind: "ip", - ...errorUtil.errToObj(options) - }); - } - cidr(options) { - return this._addCheck({ - kind: "cidr", - ...errorUtil.errToObj(options) - }); - } - datetime(options) { - if (typeof options === "string") { - return this._addCheck({ - kind: "datetime", - precision: null, - offset: false, - local: false, - message: options - }); - } - return this._addCheck({ - kind: "datetime", - precision: typeof options?.precision === "undefined" ? null : options?.precision, - offset: options?.offset ?? false, - local: options?.local ?? false, - ...errorUtil.errToObj(options?.message) - }); - } - date(message) { - return this._addCheck({ - kind: "date", - message - }); - } - time(options) { - if (typeof options === "string") { - return this._addCheck({ - kind: "time", - precision: null, - message: options - }); - } - return this._addCheck({ - kind: "time", - precision: typeof options?.precision === "undefined" ? null : options?.precision, - ...errorUtil.errToObj(options?.message) - }); - } - duration(message) { - return this._addCheck({ - kind: "duration", - ...errorUtil.errToObj(message) - }); - } - regex(regex, message) { - return this._addCheck({ - kind: "regex", - regex, - ...errorUtil.errToObj(message) - }); - } - includes(value, options) { - return this._addCheck({ - kind: "includes", - value, - position: options?.position, - ...errorUtil.errToObj(options?.message) - }); - } - startsWith(value, message) { - return this._addCheck({ - kind: "startsWith", - value, - ...errorUtil.errToObj(message) - }); - } - endsWith(value, message) { - return this._addCheck({ - kind: "endsWith", - value, - ...errorUtil.errToObj(message) - }); - } - min(minLength, message) { - return this._addCheck({ - kind: "min", - value: minLength, - ...errorUtil.errToObj(message) - }); - } - max(maxLength, message) { - return this._addCheck({ - kind: "max", - value: maxLength, - ...errorUtil.errToObj(message) - }); - } - length(len, message) { - return this._addCheck({ - kind: "length", - value: len, - ...errorUtil.errToObj(message) - }); - } - /** - * Equivalent to \`.min(1)\` - */ - nonempty(message) { - return this.min(1, errorUtil.errToObj(message)); - } - trim() { - return new _ZodString2({ - ...this._def, - checks: [ - ...this._def.checks, - { - kind: "trim" - } - ] - }); - } - toLowerCase() { - return new _ZodString2({ - ...this._def, - checks: [ - ...this._def.checks, - { - kind: "toLowerCase" - } - ] - }); - } - toUpperCase() { - return new _ZodString2({ - ...this._def, - checks: [ - ...this._def.checks, - { - kind: "toUpperCase" - } - ] - }); - } - get isDatetime() { - return !!this._def.checks.find((ch) => ch.kind === "datetime"); - } - get isDate() { - return !!this._def.checks.find((ch) => ch.kind === "date"); - } - get isTime() { - return !!this._def.checks.find((ch) => ch.kind === "time"); - } - get isDuration() { - return !!this._def.checks.find((ch) => ch.kind === "duration"); - } - get isEmail() { - return !!this._def.checks.find((ch) => ch.kind === "email"); - } - get isURL() { - return !!this._def.checks.find((ch) => ch.kind === "url"); - } - get isEmoji() { - return !!this._def.checks.find((ch) => ch.kind === "emoji"); - } - get isUUID() { - return !!this._def.checks.find((ch) => ch.kind === "uuid"); - } - get isNANOID() { - return !!this._def.checks.find((ch) => ch.kind === "nanoid"); - } - get isCUID() { - return !!this._def.checks.find((ch) => ch.kind === "cuid"); - } - get isCUID2() { - return !!this._def.checks.find((ch) => ch.kind === "cuid2"); - } - get isULID() { - return !!this._def.checks.find((ch) => ch.kind === "ulid"); - } - get isIP() { - return !!this._def.checks.find((ch) => ch.kind === "ip"); - } - get isCIDR() { - return !!this._def.checks.find((ch) => ch.kind === "cidr"); - } - get isBase64() { - return !!this._def.checks.find((ch) => ch.kind === "base64"); - } - get isBase64url() { - return !!this._def.checks.find((ch) => ch.kind === "base64url"); - } - get minLength() { - let min = null; - for (const ch of this._def.checks) { - if (ch.kind === "min") { - if (min === null || ch.value > min) min = ch.value; - } - } - return min; - } - get maxLength() { - let max = null; - for (const ch of this._def.checks) { - if (ch.kind === "max") { - if (max === null || ch.value < max) max = ch.value; - } - } - return max; - } -}; -ZodString2.create = (params) => { - return new ZodString2({ - checks: [], - typeName: ZodFirstPartyTypeKind2.ZodString, - coerce: params?.coerce ?? false, - ...processCreateParams(params) - }); -}; -function floatSafeRemainder2(val, step) { - const valDecCount = (val.toString().split(".")[1] || "").length; - const stepDecCount = (step.toString().split(".")[1] || "").length; - const decCount = valDecCount > stepDecCount ? valDecCount : stepDecCount; - const valInt = Number.parseInt(val.toFixed(decCount).replace(".", "")); - const stepInt = Number.parseInt(step.toFixed(decCount).replace(".", "")); - return valInt % stepInt / 10 ** decCount; -} -__name(floatSafeRemainder2, "floatSafeRemainder"); -var ZodNumber2 = class _ZodNumber extends ZodType2 { - static { - __name(this, "ZodNumber"); - } - constructor() { - super(...arguments); - this.min = this.gte; - this.max = this.lte; - this.step = this.multipleOf; - } - _parse(input) { - if (this._def.coerce) { - input.data = Number(input.data); - } - const parsedType7 = this._getType(input); - if (parsedType7 !== ZodParsedType.number) { - const ctx2 = this._getOrReturnCtx(input); - addIssueToContext(ctx2, { - code: ZodIssueCode2.invalid_type, - expected: ZodParsedType.number, - received: ctx2.parsedType - }); - return INVALID; - } - let ctx = void 0; - const status = new ParseStatus(); - for (const check2 of this._def.checks) { - if (check2.kind === "int") { - if (!util.isInteger(input.data)) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - code: ZodIssueCode2.invalid_type, - expected: "integer", - received: "float", - message: check2.message - }); - status.dirty(); - } - } else if (check2.kind === "min") { - const tooSmall = check2.inclusive ? input.data < check2.value : input.data <= check2.value; - if (tooSmall) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - code: ZodIssueCode2.too_small, - minimum: check2.value, - type: "number", - inclusive: check2.inclusive, - exact: false, - message: check2.message - }); - status.dirty(); - } - } else if (check2.kind === "max") { - const tooBig = check2.inclusive ? input.data > check2.value : input.data >= check2.value; - if (tooBig) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - code: ZodIssueCode2.too_big, - maximum: check2.value, - type: "number", - inclusive: check2.inclusive, - exact: false, - message: check2.message - }); - status.dirty(); - } - } else if (check2.kind === "multipleOf") { - if (floatSafeRemainder2(input.data, check2.value) !== 0) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - code: ZodIssueCode2.not_multiple_of, - multipleOf: check2.value, - message: check2.message - }); - status.dirty(); - } - } else if (check2.kind === "finite") { - if (!Number.isFinite(input.data)) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - code: ZodIssueCode2.not_finite, - message: check2.message - }); - status.dirty(); - } - } else { - util.assertNever(check2); - } - } - return { - status: status.value, - value: input.data - }; - } - gte(value, message) { - return this.setLimit("min", value, true, errorUtil.toString(message)); - } - gt(value, message) { - return this.setLimit("min", value, false, errorUtil.toString(message)); - } - lte(value, message) { - return this.setLimit("max", value, true, errorUtil.toString(message)); - } - lt(value, message) { - return this.setLimit("max", value, false, errorUtil.toString(message)); - } - setLimit(kind, value, inclusive, message) { - return new _ZodNumber({ - ...this._def, - checks: [ - ...this._def.checks, - { - kind, - value, - inclusive, - message: errorUtil.toString(message) - } - ] - }); - } - _addCheck(check2) { - return new _ZodNumber({ - ...this._def, - checks: [ - ...this._def.checks, - check2 - ] - }); - } - int(message) { - return this._addCheck({ - kind: "int", - message: errorUtil.toString(message) - }); - } - positive(message) { - return this._addCheck({ - kind: "min", - value: 0, - inclusive: false, - message: errorUtil.toString(message) - }); - } - negative(message) { - return this._addCheck({ - kind: "max", - value: 0, - inclusive: false, - message: errorUtil.toString(message) - }); - } - nonpositive(message) { - return this._addCheck({ - kind: "max", - value: 0, - inclusive: true, - message: errorUtil.toString(message) - }); - } - nonnegative(message) { - return this._addCheck({ - kind: "min", - value: 0, - inclusive: true, - message: errorUtil.toString(message) - }); - } - multipleOf(value, message) { - return this._addCheck({ - kind: "multipleOf", - value, - message: errorUtil.toString(message) - }); - } - finite(message) { - return this._addCheck({ - kind: "finite", - message: errorUtil.toString(message) - }); - } - safe(message) { - return this._addCheck({ - kind: "min", - inclusive: true, - value: Number.MIN_SAFE_INTEGER, - message: errorUtil.toString(message) - })._addCheck({ - kind: "max", - inclusive: true, - value: Number.MAX_SAFE_INTEGER, - message: errorUtil.toString(message) - }); - } - get minValue() { - let min = null; - for (const ch of this._def.checks) { - if (ch.kind === "min") { - if (min === null || ch.value > min) min = ch.value; - } - } - return min; - } - get maxValue() { - let max = null; - for (const ch of this._def.checks) { - if (ch.kind === "max") { - if (max === null || ch.value < max) max = ch.value; - } - } - return max; - } - get isInt() { - return !!this._def.checks.find((ch) => ch.kind === "int" || ch.kind === "multipleOf" && util.isInteger(ch.value)); - } - get isFinite() { - let max = null; - let min = null; - for (const ch of this._def.checks) { - if (ch.kind === "finite" || ch.kind === "int" || ch.kind === "multipleOf") { - return true; - } else if (ch.kind === "min") { - if (min === null || ch.value > min) min = ch.value; - } else if (ch.kind === "max") { - if (max === null || ch.value < max) max = ch.value; - } - } - return Number.isFinite(min) && Number.isFinite(max); - } -}; -ZodNumber2.create = (params) => { - return new ZodNumber2({ - checks: [], - typeName: ZodFirstPartyTypeKind2.ZodNumber, - coerce: params?.coerce || false, - ...processCreateParams(params) - }); -}; -var ZodBigInt2 = class _ZodBigInt extends ZodType2 { - static { - __name(this, "ZodBigInt"); - } - constructor() { - super(...arguments); - this.min = this.gte; - this.max = this.lte; - } - _parse(input) { - if (this._def.coerce) { - try { - input.data = BigInt(input.data); - } catch { - return this._getInvalidInput(input); - } - } - const parsedType7 = this._getType(input); - if (parsedType7 !== ZodParsedType.bigint) { - return this._getInvalidInput(input); - } - let ctx = void 0; - const status = new ParseStatus(); - for (const check2 of this._def.checks) { - if (check2.kind === "min") { - const tooSmall = check2.inclusive ? input.data < check2.value : input.data <= check2.value; - if (tooSmall) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - code: ZodIssueCode2.too_small, - type: "bigint", - minimum: check2.value, - inclusive: check2.inclusive, - message: check2.message - }); - status.dirty(); - } - } else if (check2.kind === "max") { - const tooBig = check2.inclusive ? input.data > check2.value : input.data >= check2.value; - if (tooBig) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - code: ZodIssueCode2.too_big, - type: "bigint", - maximum: check2.value, - inclusive: check2.inclusive, - message: check2.message - }); - status.dirty(); - } - } else if (check2.kind === "multipleOf") { - if (input.data % check2.value !== BigInt(0)) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - code: ZodIssueCode2.not_multiple_of, - multipleOf: check2.value, - message: check2.message - }); - status.dirty(); - } - } else { - util.assertNever(check2); - } - } - return { - status: status.value, - value: input.data - }; - } - _getInvalidInput(input) { - const ctx = this._getOrReturnCtx(input); - addIssueToContext(ctx, { - code: ZodIssueCode2.invalid_type, - expected: ZodParsedType.bigint, - received: ctx.parsedType - }); - return INVALID; - } - gte(value, message) { - return this.setLimit("min", value, true, errorUtil.toString(message)); - } - gt(value, message) { - return this.setLimit("min", value, false, errorUtil.toString(message)); - } - lte(value, message) { - return this.setLimit("max", value, true, errorUtil.toString(message)); - } - lt(value, message) { - return this.setLimit("max", value, false, errorUtil.toString(message)); - } - setLimit(kind, value, inclusive, message) { - return new _ZodBigInt({ - ...this._def, - checks: [ - ...this._def.checks, - { - kind, - value, - inclusive, - message: errorUtil.toString(message) - } - ] - }); - } - _addCheck(check2) { - return new _ZodBigInt({ - ...this._def, - checks: [ - ...this._def.checks, - check2 - ] - }); - } - positive(message) { - return this._addCheck({ - kind: "min", - value: BigInt(0), - inclusive: false, - message: errorUtil.toString(message) - }); - } - negative(message) { - return this._addCheck({ - kind: "max", - value: BigInt(0), - inclusive: false, - message: errorUtil.toString(message) - }); - } - nonpositive(message) { - return this._addCheck({ - kind: "max", - value: BigInt(0), - inclusive: true, - message: errorUtil.toString(message) - }); - } - nonnegative(message) { - return this._addCheck({ - kind: "min", - value: BigInt(0), - inclusive: true, - message: errorUtil.toString(message) - }); - } - multipleOf(value, message) { - return this._addCheck({ - kind: "multipleOf", - value, - message: errorUtil.toString(message) - }); - } - get minValue() { - let min = null; - for (const ch of this._def.checks) { - if (ch.kind === "min") { - if (min === null || ch.value > min) min = ch.value; - } - } - return min; - } - get maxValue() { - let max = null; - for (const ch of this._def.checks) { - if (ch.kind === "max") { - if (max === null || ch.value < max) max = ch.value; - } - } - return max; - } -}; -ZodBigInt2.create = (params) => { - return new ZodBigInt2({ - checks: [], - typeName: ZodFirstPartyTypeKind2.ZodBigInt, - coerce: params?.coerce ?? false, - ...processCreateParams(params) - }); -}; -var ZodBoolean2 = class extends ZodType2 { - static { - __name(this, "ZodBoolean"); - } - _parse(input) { - if (this._def.coerce) { - input.data = Boolean(input.data); - } - const parsedType7 = this._getType(input); - if (parsedType7 !== ZodParsedType.boolean) { - const ctx = this._getOrReturnCtx(input); - addIssueToContext(ctx, { - code: ZodIssueCode2.invalid_type, - expected: ZodParsedType.boolean, - received: ctx.parsedType - }); - return INVALID; - } - return OK(input.data); - } -}; -ZodBoolean2.create = (params) => { - return new ZodBoolean2({ - typeName: ZodFirstPartyTypeKind2.ZodBoolean, - coerce: params?.coerce || false, - ...processCreateParams(params) - }); -}; -var ZodDate2 = class _ZodDate extends ZodType2 { - static { - __name(this, "ZodDate"); - } - _parse(input) { - if (this._def.coerce) { - input.data = new Date(input.data); - } - const parsedType7 = this._getType(input); - if (parsedType7 !== ZodParsedType.date) { - const ctx2 = this._getOrReturnCtx(input); - addIssueToContext(ctx2, { - code: ZodIssueCode2.invalid_type, - expected: ZodParsedType.date, - received: ctx2.parsedType - }); - return INVALID; - } - if (Number.isNaN(input.data.getTime())) { - const ctx2 = this._getOrReturnCtx(input); - addIssueToContext(ctx2, { - code: ZodIssueCode2.invalid_date - }); - return INVALID; - } - const status = new ParseStatus(); - let ctx = void 0; - for (const check2 of this._def.checks) { - if (check2.kind === "min") { - if (input.data.getTime() < check2.value) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - code: ZodIssueCode2.too_small, - message: check2.message, - inclusive: true, - exact: false, - minimum: check2.value, - type: "date" - }); - status.dirty(); - } - } else if (check2.kind === "max") { - if (input.data.getTime() > check2.value) { - ctx = this._getOrReturnCtx(input, ctx); - addIssueToContext(ctx, { - code: ZodIssueCode2.too_big, - message: check2.message, - inclusive: true, - exact: false, - maximum: check2.value, - type: "date" - }); - status.dirty(); - } - } else { - util.assertNever(check2); - } - } - return { - status: status.value, - value: new Date(input.data.getTime()) - }; - } - _addCheck(check2) { - return new _ZodDate({ - ...this._def, - checks: [ - ...this._def.checks, - check2 - ] - }); - } - min(minDate, message) { - return this._addCheck({ - kind: "min", - value: minDate.getTime(), - message: errorUtil.toString(message) - }); - } - max(maxDate, message) { - return this._addCheck({ - kind: "max", - value: maxDate.getTime(), - message: errorUtil.toString(message) - }); - } - get minDate() { - let min = null; - for (const ch of this._def.checks) { - if (ch.kind === "min") { - if (min === null || ch.value > min) min = ch.value; - } - } - return min != null ? new Date(min) : null; - } - get maxDate() { - let max = null; - for (const ch of this._def.checks) { - if (ch.kind === "max") { - if (max === null || ch.value < max) max = ch.value; - } - } - return max != null ? new Date(max) : null; - } -}; -ZodDate2.create = (params) => { - return new ZodDate2({ - checks: [], - coerce: params?.coerce || false, - typeName: ZodFirstPartyTypeKind2.ZodDate, - ...processCreateParams(params) - }); -}; -var ZodSymbol2 = class extends ZodType2 { - static { - __name(this, "ZodSymbol"); - } - _parse(input) { - const parsedType7 = this._getType(input); - if (parsedType7 !== ZodParsedType.symbol) { - const ctx = this._getOrReturnCtx(input); - addIssueToContext(ctx, { - code: ZodIssueCode2.invalid_type, - expected: ZodParsedType.symbol, - received: ctx.parsedType - }); - return INVALID; - } - return OK(input.data); - } -}; -ZodSymbol2.create = (params) => { - return new ZodSymbol2({ - typeName: ZodFirstPartyTypeKind2.ZodSymbol, - ...processCreateParams(params) - }); -}; -var ZodUndefined2 = class extends ZodType2 { - static { - __name(this, "ZodUndefined"); - } - _parse(input) { - const parsedType7 = this._getType(input); - if (parsedType7 !== ZodParsedType.undefined) { - const ctx = this._getOrReturnCtx(input); - addIssueToContext(ctx, { - code: ZodIssueCode2.invalid_type, - expected: ZodParsedType.undefined, - received: ctx.parsedType - }); - return INVALID; - } - return OK(input.data); - } -}; -ZodUndefined2.create = (params) => { - return new ZodUndefined2({ - typeName: ZodFirstPartyTypeKind2.ZodUndefined, - ...processCreateParams(params) - }); -}; -var ZodNull2 = class extends ZodType2 { - static { - __name(this, "ZodNull"); - } - _parse(input) { - const parsedType7 = this._getType(input); - if (parsedType7 !== ZodParsedType.null) { - const ctx = this._getOrReturnCtx(input); - addIssueToContext(ctx, { - code: ZodIssueCode2.invalid_type, - expected: ZodParsedType.null, - received: ctx.parsedType - }); - return INVALID; - } - return OK(input.data); - } -}; -ZodNull2.create = (params) => { - return new ZodNull2({ - typeName: ZodFirstPartyTypeKind2.ZodNull, - ...processCreateParams(params) - }); -}; -var ZodAny2 = class extends ZodType2 { - static { - __name(this, "ZodAny"); - } - constructor() { - super(...arguments); - this._any = true; - } - _parse(input) { - return OK(input.data); - } -}; -ZodAny2.create = (params) => { - return new ZodAny2({ - typeName: ZodFirstPartyTypeKind2.ZodAny, - ...processCreateParams(params) - }); -}; -var ZodUnknown2 = class extends ZodType2 { - static { - __name(this, "ZodUnknown"); - } - constructor() { - super(...arguments); - this._unknown = true; - } - _parse(input) { - return OK(input.data); - } -}; -ZodUnknown2.create = (params) => { - return new ZodUnknown2({ - typeName: ZodFirstPartyTypeKind2.ZodUnknown, - ...processCreateParams(params) - }); -}; -var ZodNever2 = class extends ZodType2 { - static { - __name(this, "ZodNever"); - } - _parse(input) { - const ctx = this._getOrReturnCtx(input); - addIssueToContext(ctx, { - code: ZodIssueCode2.invalid_type, - expected: ZodParsedType.never, - received: ctx.parsedType - }); - return INVALID; - } -}; -ZodNever2.create = (params) => { - return new ZodNever2({ - typeName: ZodFirstPartyTypeKind2.ZodNever, - ...processCreateParams(params) - }); -}; -var ZodVoid2 = class extends ZodType2 { - static { - __name(this, "ZodVoid"); - } - _parse(input) { - const parsedType7 = this._getType(input); - if (parsedType7 !== ZodParsedType.undefined) { - const ctx = this._getOrReturnCtx(input); - addIssueToContext(ctx, { - code: ZodIssueCode2.invalid_type, - expected: ZodParsedType.void, - received: ctx.parsedType - }); - return INVALID; - } - return OK(input.data); - } -}; -ZodVoid2.create = (params) => { - return new ZodVoid2({ - typeName: ZodFirstPartyTypeKind2.ZodVoid, - ...processCreateParams(params) - }); -}; -var ZodArray2 = class _ZodArray extends ZodType2 { - static { - __name(this, "ZodArray"); - } - _parse(input) { - const { ctx, status } = this._processInputParams(input); - const def = this._def; - if (ctx.parsedType !== ZodParsedType.array) { - addIssueToContext(ctx, { - code: ZodIssueCode2.invalid_type, - expected: ZodParsedType.array, - received: ctx.parsedType - }); - return INVALID; - } - if (def.exactLength !== null) { - const tooBig = ctx.data.length > def.exactLength.value; - const tooSmall = ctx.data.length < def.exactLength.value; - if (tooBig || tooSmall) { - addIssueToContext(ctx, { - code: tooBig ? ZodIssueCode2.too_big : ZodIssueCode2.too_small, - minimum: tooSmall ? def.exactLength.value : void 0, - maximum: tooBig ? def.exactLength.value : void 0, - type: "array", - inclusive: true, - exact: true, - message: def.exactLength.message - }); - status.dirty(); - } - } - if (def.minLength !== null) { - if (ctx.data.length < def.minLength.value) { - addIssueToContext(ctx, { - code: ZodIssueCode2.too_small, - minimum: def.minLength.value, - type: "array", - inclusive: true, - exact: false, - message: def.minLength.message - }); - status.dirty(); - } - } - if (def.maxLength !== null) { - if (ctx.data.length > def.maxLength.value) { - addIssueToContext(ctx, { - code: ZodIssueCode2.too_big, - maximum: def.maxLength.value, - type: "array", - inclusive: true, - exact: false, - message: def.maxLength.message - }); - status.dirty(); - } - } - if (ctx.common.async) { - return Promise.all([ - ...ctx.data - ].map((item, i) => { - return def.type._parseAsync(new ParseInputLazyPath(ctx, item, ctx.path, i)); - })).then((result2) => { - return ParseStatus.mergeArray(status, result2); - }); - } - const result = [ - ...ctx.data - ].map((item, i) => { - return def.type._parseSync(new ParseInputLazyPath(ctx, item, ctx.path, i)); - }); - return ParseStatus.mergeArray(status, result); - } - get element() { - return this._def.type; - } - min(minLength, message) { - return new _ZodArray({ - ...this._def, - minLength: { - value: minLength, - message: errorUtil.toString(message) - } - }); - } - max(maxLength, message) { - return new _ZodArray({ - ...this._def, - maxLength: { - value: maxLength, - message: errorUtil.toString(message) - } - }); - } - length(len, message) { - return new _ZodArray({ - ...this._def, - exactLength: { - value: len, - message: errorUtil.toString(message) - } - }); - } - nonempty(message) { - return this.min(1, message); - } -}; -ZodArray2.create = (schema, params) => { - return new ZodArray2({ - type: schema, - minLength: null, - maxLength: null, - exactLength: null, - typeName: ZodFirstPartyTypeKind2.ZodArray, - ...processCreateParams(params) - }); -}; -function deepPartialify(schema) { - if (schema instanceof ZodObject2) { - const newShape = {}; - for (const key in schema.shape) { - const fieldSchema = schema.shape[key]; - newShape[key] = ZodOptional2.create(deepPartialify(fieldSchema)); - } - return new ZodObject2({ - ...schema._def, - shape: /* @__PURE__ */ __name(() => newShape, "shape") - }); - } else if (schema instanceof ZodArray2) { - return new ZodArray2({ - ...schema._def, - type: deepPartialify(schema.element) - }); - } else if (schema instanceof ZodOptional2) { - return ZodOptional2.create(deepPartialify(schema.unwrap())); - } else if (schema instanceof ZodNullable2) { - return ZodNullable2.create(deepPartialify(schema.unwrap())); - } else if (schema instanceof ZodTuple2) { - return ZodTuple2.create(schema.items.map((item) => deepPartialify(item))); - } else { - return schema; - } -} -__name(deepPartialify, "deepPartialify"); -var ZodObject2 = class _ZodObject extends ZodType2 { - static { - __name(this, "ZodObject"); - } - constructor() { - super(...arguments); - this._cached = null; - this.nonstrict = this.passthrough; - this.augment = this.extend; - } - _getCached() { - if (this._cached !== null) return this._cached; - const shape = this._def.shape(); - const keys = util.objectKeys(shape); - this._cached = { - shape, - keys - }; - return this._cached; - } - _parse(input) { - const parsedType7 = this._getType(input); - if (parsedType7 !== ZodParsedType.object) { - const ctx2 = this._getOrReturnCtx(input); - addIssueToContext(ctx2, { - code: ZodIssueCode2.invalid_type, - expected: ZodParsedType.object, - received: ctx2.parsedType - }); - return INVALID; - } - const { status, ctx } = this._processInputParams(input); - const { shape, keys: shapeKeys } = this._getCached(); - const extraKeys = []; - if (!(this._def.catchall instanceof ZodNever2 && this._def.unknownKeys === "strip")) { - for (const key in ctx.data) { - if (!shapeKeys.includes(key)) { - extraKeys.push(key); - } - } - } - const pairs = []; - for (const key of shapeKeys) { - const keyValidator = shape[key]; - const value = ctx.data[key]; - pairs.push({ - key: { - status: "valid", - value: key - }, - value: keyValidator._parse(new ParseInputLazyPath(ctx, value, ctx.path, key)), - alwaysSet: key in ctx.data - }); - } - if (this._def.catchall instanceof ZodNever2) { - const unknownKeys = this._def.unknownKeys; - if (unknownKeys === "passthrough") { - for (const key of extraKeys) { - pairs.push({ - key: { - status: "valid", - value: key - }, - value: { - status: "valid", - value: ctx.data[key] - } - }); - } - } else if (unknownKeys === "strict") { - if (extraKeys.length > 0) { - addIssueToContext(ctx, { - code: ZodIssueCode2.unrecognized_keys, - keys: extraKeys - }); - status.dirty(); - } - } else if (unknownKeys === "strip") { - } else { - throw new Error(\`Internal ZodObject error: invalid unknownKeys value.\`); - } - } else { - const catchall = this._def.catchall; - for (const key of extraKeys) { - const value = ctx.data[key]; - pairs.push({ - key: { - status: "valid", - value: key - }, - value: catchall._parse( - new ParseInputLazyPath(ctx, value, ctx.path, key) - //, ctx.child(key), value, getParsedType(value) - ), - alwaysSet: key in ctx.data - }); - } - } - if (ctx.common.async) { - return Promise.resolve().then(async () => { - const syncPairs = []; - for (const pair of pairs) { - const key = await pair.key; - const value = await pair.value; - syncPairs.push({ - key, - value, - alwaysSet: pair.alwaysSet - }); - } - return syncPairs; - }).then((syncPairs) => { - return ParseStatus.mergeObjectSync(status, syncPairs); - }); - } else { - return ParseStatus.mergeObjectSync(status, pairs); - } - } - get shape() { - return this._def.shape(); - } - strict(message) { - errorUtil.errToObj; - return new _ZodObject({ - ...this._def, - unknownKeys: "strict", - ...message !== void 0 ? { - errorMap: /* @__PURE__ */ __name((issue2, ctx) => { - const defaultError = this._def.errorMap?.(issue2, ctx).message ?? ctx.defaultError; - if (issue2.code === "unrecognized_keys") return { - message: errorUtil.errToObj(message).message ?? defaultError - }; - return { - message: defaultError - }; - }, "errorMap") - } : {} - }); - } - strip() { - return new _ZodObject({ - ...this._def, - unknownKeys: "strip" - }); - } - passthrough() { - return new _ZodObject({ - ...this._def, - unknownKeys: "passthrough" - }); - } - // const AugmentFactory = - // (def: Def) => - // ( - // augmentation: Augmentation - // ): ZodObject< - // extendShape, Augmentation>, - // Def["unknownKeys"], - // Def["catchall"] - // > => { - // return new ZodObject({ - // ...def, - // shape: () => ({ - // ...def.shape(), - // ...augmentation, - // }), - // }) as any; - // }; - extend(augmentation) { - return new _ZodObject({ - ...this._def, - shape: /* @__PURE__ */ __name(() => ({ - ...this._def.shape(), - ...augmentation - }), "shape") - }); - } - /** - * Prior to zod@1.0.12 there was a bug in the - * inferred type of merged objects. Please - * upgrade if you are experiencing issues. - */ - merge(merging) { - const merged = new _ZodObject({ - unknownKeys: merging._def.unknownKeys, - catchall: merging._def.catchall, - shape: /* @__PURE__ */ __name(() => ({ - ...this._def.shape(), - ...merging._def.shape() - }), "shape"), - typeName: ZodFirstPartyTypeKind2.ZodObject - }); - return merged; - } - // merge< - // Incoming extends AnyZodObject, - // Augmentation extends Incoming["shape"], - // NewOutput extends { - // [k in keyof Augmentation | keyof Output]: k extends keyof Augmentation - // ? Augmentation[k]["_output"] - // : k extends keyof Output - // ? Output[k] - // : never; - // }, - // NewInput extends { - // [k in keyof Augmentation | keyof Input]: k extends keyof Augmentation - // ? Augmentation[k]["_input"] - // : k extends keyof Input - // ? Input[k] - // : never; - // } - // >( - // merging: Incoming - // ): ZodObject< - // extendShape>, - // Incoming["_def"]["unknownKeys"], - // Incoming["_def"]["catchall"], - // NewOutput, - // NewInput - // > { - // const merged: any = new ZodObject({ - // unknownKeys: merging._def.unknownKeys, - // catchall: merging._def.catchall, - // shape: () => - // objectUtil.mergeShapes(this._def.shape(), merging._def.shape()), - // typeName: ZodFirstPartyTypeKind.ZodObject, - // }) as any; - // return merged; - // } - setKey(key, schema) { - return this.augment({ - [key]: schema - }); - } - // merge( - // merging: Incoming - // ): //ZodObject = (merging) => { - // ZodObject< - // extendShape>, - // Incoming["_def"]["unknownKeys"], - // Incoming["_def"]["catchall"] - // > { - // // const mergedShape = objectUtil.mergeShapes( - // // this._def.shape(), - // // merging._def.shape() - // // ); - // const merged: any = new ZodObject({ - // unknownKeys: merging._def.unknownKeys, - // catchall: merging._def.catchall, - // shape: () => - // objectUtil.mergeShapes(this._def.shape(), merging._def.shape()), - // typeName: ZodFirstPartyTypeKind.ZodObject, - // }) as any; - // return merged; - // } - catchall(index) { - return new _ZodObject({ - ...this._def, - catchall: index - }); - } - pick(mask) { - const shape = {}; - for (const key of util.objectKeys(mask)) { - if (mask[key] && this.shape[key]) { - shape[key] = this.shape[key]; - } - } - return new _ZodObject({ - ...this._def, - shape: /* @__PURE__ */ __name(() => shape, "shape") - }); - } - omit(mask) { - const shape = {}; - for (const key of util.objectKeys(this.shape)) { - if (!mask[key]) { - shape[key] = this.shape[key]; - } - } - return new _ZodObject({ - ...this._def, - shape: /* @__PURE__ */ __name(() => shape, "shape") - }); - } - /** - * @deprecated - */ - deepPartial() { - return deepPartialify(this); - } - partial(mask) { - const newShape = {}; - for (const key of util.objectKeys(this.shape)) { - const fieldSchema = this.shape[key]; - if (mask && !mask[key]) { - newShape[key] = fieldSchema; - } else { - newShape[key] = fieldSchema.optional(); - } - } - return new _ZodObject({ - ...this._def, - shape: /* @__PURE__ */ __name(() => newShape, "shape") - }); - } - required(mask) { - const newShape = {}; - for (const key of util.objectKeys(this.shape)) { - if (mask && !mask[key]) { - newShape[key] = this.shape[key]; - } else { - const fieldSchema = this.shape[key]; - let newField = fieldSchema; - while (newField instanceof ZodOptional2) { - newField = newField._def.innerType; - } - newShape[key] = newField; - } - } - return new _ZodObject({ - ...this._def, - shape: /* @__PURE__ */ __name(() => newShape, "shape") - }); - } - keyof() { - return createZodEnum(util.objectKeys(this.shape)); - } -}; -ZodObject2.create = (shape, params) => { - return new ZodObject2({ - shape: /* @__PURE__ */ __name(() => shape, "shape"), - unknownKeys: "strip", - catchall: ZodNever2.create(), - typeName: ZodFirstPartyTypeKind2.ZodObject, - ...processCreateParams(params) - }); -}; -ZodObject2.strictCreate = (shape, params) => { - return new ZodObject2({ - shape: /* @__PURE__ */ __name(() => shape, "shape"), - unknownKeys: "strict", - catchall: ZodNever2.create(), - typeName: ZodFirstPartyTypeKind2.ZodObject, - ...processCreateParams(params) - }); -}; -ZodObject2.lazycreate = (shape, params) => { - return new ZodObject2({ - shape, - unknownKeys: "strip", - catchall: ZodNever2.create(), - typeName: ZodFirstPartyTypeKind2.ZodObject, - ...processCreateParams(params) - }); -}; -var ZodUnion2 = class extends ZodType2 { - static { - __name(this, "ZodUnion"); - } - _parse(input) { - const { ctx } = this._processInputParams(input); - const options = this._def.options; - function handleResults(results) { - for (const result of results) { - if (result.result.status === "valid") { - return result.result; - } - } - for (const result of results) { - if (result.result.status === "dirty") { - ctx.common.issues.push(...result.ctx.common.issues); - return result.result; - } - } - const unionErrors = results.map((result) => new ZodError2(result.ctx.common.issues)); - addIssueToContext(ctx, { - code: ZodIssueCode2.invalid_union, - unionErrors - }); - return INVALID; - } - __name(handleResults, "handleResults"); - if (ctx.common.async) { - return Promise.all(options.map(async (option) => { - const childCtx = { - ...ctx, - common: { - ...ctx.common, - issues: [] - }, - parent: null - }; - return { - result: await option._parseAsync({ - data: ctx.data, - path: ctx.path, - parent: childCtx - }), - ctx: childCtx - }; - })).then(handleResults); - } else { - let dirty = void 0; - const issues = []; - for (const option of options) { - const childCtx = { - ...ctx, - common: { - ...ctx.common, - issues: [] - }, - parent: null - }; - const result = option._parseSync({ - data: ctx.data, - path: ctx.path, - parent: childCtx - }); - if (result.status === "valid") { - return result; - } else if (result.status === "dirty" && !dirty) { - dirty = { - result, - ctx: childCtx - }; - } - if (childCtx.common.issues.length) { - issues.push(childCtx.common.issues); - } - } - if (dirty) { - ctx.common.issues.push(...dirty.ctx.common.issues); - return dirty.result; - } - const unionErrors = issues.map((issues2) => new ZodError2(issues2)); - addIssueToContext(ctx, { - code: ZodIssueCode2.invalid_union, - unionErrors - }); - return INVALID; - } - } - get options() { - return this._def.options; - } -}; -ZodUnion2.create = (types, params) => { - return new ZodUnion2({ - options: types, - typeName: ZodFirstPartyTypeKind2.ZodUnion, - ...processCreateParams(params) - }); -}; -var getDiscriminator = /* @__PURE__ */ __name((type) => { - if (type instanceof ZodLazy2) { - return getDiscriminator(type.schema); - } else if (type instanceof ZodEffects) { - return getDiscriminator(type.innerType()); - } else if (type instanceof ZodLiteral2) { - return [ - type.value - ]; - } else if (type instanceof ZodEnum2) { - return type.options; - } else if (type instanceof ZodNativeEnum) { - return util.objectValues(type.enum); - } else if (type instanceof ZodDefault2) { - return getDiscriminator(type._def.innerType); - } else if (type instanceof ZodUndefined2) { - return [ - void 0 - ]; - } else if (type instanceof ZodNull2) { - return [ - null - ]; - } else if (type instanceof ZodOptional2) { - return [ - void 0, - ...getDiscriminator(type.unwrap()) - ]; - } else if (type instanceof ZodNullable2) { - return [ - null, - ...getDiscriminator(type.unwrap()) - ]; - } else if (type instanceof ZodBranded) { - return getDiscriminator(type.unwrap()); - } else if (type instanceof ZodReadonly2) { - return getDiscriminator(type.unwrap()); - } else if (type instanceof ZodCatch2) { - return getDiscriminator(type._def.innerType); - } else { - return []; - } -}, "getDiscriminator"); -var ZodDiscriminatedUnion2 = class _ZodDiscriminatedUnion extends ZodType2 { - static { - __name(this, "ZodDiscriminatedUnion"); - } - _parse(input) { - const { ctx } = this._processInputParams(input); - if (ctx.parsedType !== ZodParsedType.object) { - addIssueToContext(ctx, { - code: ZodIssueCode2.invalid_type, - expected: ZodParsedType.object, - received: ctx.parsedType - }); - return INVALID; - } - const discriminator = this.discriminator; - const discriminatorValue = ctx.data[discriminator]; - const option = this.optionsMap.get(discriminatorValue); - if (!option) { - addIssueToContext(ctx, { - code: ZodIssueCode2.invalid_union_discriminator, - options: Array.from(this.optionsMap.keys()), - path: [ - discriminator - ] - }); - return INVALID; - } - if (ctx.common.async) { - return option._parseAsync({ - data: ctx.data, - path: ctx.path, - parent: ctx - }); - } else { - return option._parseSync({ - data: ctx.data, - path: ctx.path, - parent: ctx - }); - } - } - get discriminator() { - return this._def.discriminator; - } - get options() { - return this._def.options; - } - get optionsMap() { - return this._def.optionsMap; - } - /** - * The constructor of the discriminated union schema. Its behaviour is very similar to that of the normal z.union() constructor. - * However, it only allows a union of objects, all of which need to share a discriminator property. This property must - * have a different value for each object in the union. - * @param discriminator the name of the discriminator property - * @param types an array of object schemas - * @param params - */ - static create(discriminator, options, params) { - const optionsMap = /* @__PURE__ */ new Map(); - for (const type of options) { - const discriminatorValues = getDiscriminator(type.shape[discriminator]); - if (!discriminatorValues.length) { - throw new Error(\`A discriminator value for key \\\`\${discriminator}\\\` could not be extracted from all schema options\`); - } - for (const value of discriminatorValues) { - if (optionsMap.has(value)) { - throw new Error(\`Discriminator property \${String(discriminator)} has duplicate value \${String(value)}\`); - } - optionsMap.set(value, type); - } - } - return new _ZodDiscriminatedUnion({ - typeName: ZodFirstPartyTypeKind2.ZodDiscriminatedUnion, - discriminator, - options, - optionsMap, - ...processCreateParams(params) - }); - } -}; -function mergeValues2(a, b) { - const aType = getParsedType2(a); - const bType = getParsedType2(b); - if (a === b) { - return { - valid: true, - data: a - }; - } else if (aType === ZodParsedType.object && bType === ZodParsedType.object) { - const bKeys = util.objectKeys(b); - const sharedKeys = util.objectKeys(a).filter((key) => bKeys.indexOf(key) !== -1); - const newObj = { - ...a, - ...b - }; - for (const key of sharedKeys) { - const sharedValue = mergeValues2(a[key], b[key]); - if (!sharedValue.valid) { - return { - valid: false - }; - } - newObj[key] = sharedValue.data; - } - return { - valid: true, - data: newObj - }; - } else if (aType === ZodParsedType.array && bType === ZodParsedType.array) { - if (a.length !== b.length) { - return { - valid: false - }; - } - const newArray = []; - for (let index = 0; index < a.length; index++) { - const itemA = a[index]; - const itemB = b[index]; - const sharedValue = mergeValues2(itemA, itemB); - if (!sharedValue.valid) { - return { - valid: false - }; - } - newArray.push(sharedValue.data); - } - return { - valid: true, - data: newArray - }; - } else if (aType === ZodParsedType.date && bType === ZodParsedType.date && +a === +b) { - return { - valid: true, - data: a - }; - } else { - return { - valid: false - }; - } -} -__name(mergeValues2, "mergeValues"); -var ZodIntersection2 = class extends ZodType2 { - static { - __name(this, "ZodIntersection"); - } - _parse(input) { - const { status, ctx } = this._processInputParams(input); - const handleParsed = /* @__PURE__ */ __name((parsedLeft, parsedRight) => { - if (isAborted(parsedLeft) || isAborted(parsedRight)) { - return INVALID; - } - const merged = mergeValues2(parsedLeft.value, parsedRight.value); - if (!merged.valid) { - addIssueToContext(ctx, { - code: ZodIssueCode2.invalid_intersection_types - }); - return INVALID; - } - if (isDirty(parsedLeft) || isDirty(parsedRight)) { - status.dirty(); - } - return { - status: status.value, - value: merged.data - }; - }, "handleParsed"); - if (ctx.common.async) { - return Promise.all([ - this._def.left._parseAsync({ - data: ctx.data, - path: ctx.path, - parent: ctx - }), - this._def.right._parseAsync({ - data: ctx.data, - path: ctx.path, - parent: ctx - }) - ]).then(([left, right]) => handleParsed(left, right)); - } else { - return handleParsed(this._def.left._parseSync({ - data: ctx.data, - path: ctx.path, - parent: ctx - }), this._def.right._parseSync({ - data: ctx.data, - path: ctx.path, - parent: ctx - })); - } - } -}; -ZodIntersection2.create = (left, right, params) => { - return new ZodIntersection2({ - left, - right, - typeName: ZodFirstPartyTypeKind2.ZodIntersection, - ...processCreateParams(params) - }); -}; -var ZodTuple2 = class _ZodTuple extends ZodType2 { - static { - __name(this, "ZodTuple"); - } - _parse(input) { - const { status, ctx } = this._processInputParams(input); - if (ctx.parsedType !== ZodParsedType.array) { - addIssueToContext(ctx, { - code: ZodIssueCode2.invalid_type, - expected: ZodParsedType.array, - received: ctx.parsedType - }); - return INVALID; - } - if (ctx.data.length < this._def.items.length) { - addIssueToContext(ctx, { - code: ZodIssueCode2.too_small, - minimum: this._def.items.length, - inclusive: true, - exact: false, - type: "array" - }); - return INVALID; - } - const rest = this._def.rest; - if (!rest && ctx.data.length > this._def.items.length) { - addIssueToContext(ctx, { - code: ZodIssueCode2.too_big, - maximum: this._def.items.length, - inclusive: true, - exact: false, - type: "array" - }); - status.dirty(); - } - const items = [ - ...ctx.data - ].map((item, itemIndex) => { - const schema = this._def.items[itemIndex] || this._def.rest; - if (!schema) return null; - return schema._parse(new ParseInputLazyPath(ctx, item, ctx.path, itemIndex)); - }).filter((x) => !!x); - if (ctx.common.async) { - return Promise.all(items).then((results) => { - return ParseStatus.mergeArray(status, results); - }); - } else { - return ParseStatus.mergeArray(status, items); - } - } - get items() { - return this._def.items; - } - rest(rest) { - return new _ZodTuple({ - ...this._def, - rest - }); - } -}; -ZodTuple2.create = (schemas, params) => { - if (!Array.isArray(schemas)) { - throw new Error("You must pass an array of schemas to z.tuple([ ... ])"); - } - return new ZodTuple2({ - items: schemas, - typeName: ZodFirstPartyTypeKind2.ZodTuple, - rest: null, - ...processCreateParams(params) - }); -}; -var ZodRecord2 = class _ZodRecord extends ZodType2 { - static { - __name(this, "ZodRecord"); - } - get keySchema() { - return this._def.keyType; - } - get valueSchema() { - return this._def.valueType; - } - _parse(input) { - const { status, ctx } = this._processInputParams(input); - if (ctx.parsedType !== ZodParsedType.object) { - addIssueToContext(ctx, { - code: ZodIssueCode2.invalid_type, - expected: ZodParsedType.object, - received: ctx.parsedType - }); - return INVALID; - } - const pairs = []; - const keyType = this._def.keyType; - const valueType = this._def.valueType; - for (const key in ctx.data) { - pairs.push({ - key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, key)), - value: valueType._parse(new ParseInputLazyPath(ctx, ctx.data[key], ctx.path, key)), - alwaysSet: key in ctx.data - }); - } - if (ctx.common.async) { - return ParseStatus.mergeObjectAsync(status, pairs); - } else { - return ParseStatus.mergeObjectSync(status, pairs); - } - } - get element() { - return this._def.valueType; - } - static create(first, second, third) { - if (second instanceof ZodType2) { - return new _ZodRecord({ - keyType: first, - valueType: second, - typeName: ZodFirstPartyTypeKind2.ZodRecord, - ...processCreateParams(third) - }); - } - return new _ZodRecord({ - keyType: ZodString2.create(), - valueType: first, - typeName: ZodFirstPartyTypeKind2.ZodRecord, - ...processCreateParams(second) - }); - } -}; -var ZodMap2 = class extends ZodType2 { - static { - __name(this, "ZodMap"); - } - get keySchema() { - return this._def.keyType; - } - get valueSchema() { - return this._def.valueType; - } - _parse(input) { - const { status, ctx } = this._processInputParams(input); - if (ctx.parsedType !== ZodParsedType.map) { - addIssueToContext(ctx, { - code: ZodIssueCode2.invalid_type, - expected: ZodParsedType.map, - received: ctx.parsedType - }); - return INVALID; - } - const keyType = this._def.keyType; - const valueType = this._def.valueType; - const pairs = [ - ...ctx.data.entries() - ].map(([key, value], index) => { - return { - key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, [ - index, - "key" - ])), - value: valueType._parse(new ParseInputLazyPath(ctx, value, ctx.path, [ - index, - "value" - ])) - }; - }); - if (ctx.common.async) { - const finalMap = /* @__PURE__ */ new Map(); - return Promise.resolve().then(async () => { - for (const pair of pairs) { - const key = await pair.key; - const value = await pair.value; - if (key.status === "aborted" || value.status === "aborted") { - return INVALID; - } - if (key.status === "dirty" || value.status === "dirty") { - status.dirty(); - } - finalMap.set(key.value, value.value); - } - return { - status: status.value, - value: finalMap - }; - }); - } else { - const finalMap = /* @__PURE__ */ new Map(); - for (const pair of pairs) { - const key = pair.key; - const value = pair.value; - if (key.status === "aborted" || value.status === "aborted") { - return INVALID; - } - if (key.status === "dirty" || value.status === "dirty") { - status.dirty(); - } - finalMap.set(key.value, value.value); - } - return { - status: status.value, - value: finalMap - }; - } - } -}; -ZodMap2.create = (keyType, valueType, params) => { - return new ZodMap2({ - valueType, - keyType, - typeName: ZodFirstPartyTypeKind2.ZodMap, - ...processCreateParams(params) - }); -}; -var ZodSet2 = class _ZodSet extends ZodType2 { - static { - __name(this, "ZodSet"); - } - _parse(input) { - const { status, ctx } = this._processInputParams(input); - if (ctx.parsedType !== ZodParsedType.set) { - addIssueToContext(ctx, { - code: ZodIssueCode2.invalid_type, - expected: ZodParsedType.set, - received: ctx.parsedType - }); - return INVALID; - } - const def = this._def; - if (def.minSize !== null) { - if (ctx.data.size < def.minSize.value) { - addIssueToContext(ctx, { - code: ZodIssueCode2.too_small, - minimum: def.minSize.value, - type: "set", - inclusive: true, - exact: false, - message: def.minSize.message - }); - status.dirty(); - } - } - if (def.maxSize !== null) { - if (ctx.data.size > def.maxSize.value) { - addIssueToContext(ctx, { - code: ZodIssueCode2.too_big, - maximum: def.maxSize.value, - type: "set", - inclusive: true, - exact: false, - message: def.maxSize.message - }); - status.dirty(); - } - } - const valueType = this._def.valueType; - function finalizeSet(elements2) { - const parsedSet = /* @__PURE__ */ new Set(); - for (const element of elements2) { - if (element.status === "aborted") return INVALID; - if (element.status === "dirty") status.dirty(); - parsedSet.add(element.value); - } - return { - status: status.value, - value: parsedSet - }; - } - __name(finalizeSet, "finalizeSet"); - const elements = [ - ...ctx.data.values() - ].map((item, i) => valueType._parse(new ParseInputLazyPath(ctx, item, ctx.path, i))); - if (ctx.common.async) { - return Promise.all(elements).then((elements2) => finalizeSet(elements2)); - } else { - return finalizeSet(elements); - } - } - min(minSize, message) { - return new _ZodSet({ - ...this._def, - minSize: { - value: minSize, - message: errorUtil.toString(message) - } - }); - } - max(maxSize, message) { - return new _ZodSet({ - ...this._def, - maxSize: { - value: maxSize, - message: errorUtil.toString(message) - } - }); - } - size(size, message) { - return this.min(size, message).max(size, message); - } - nonempty(message) { - return this.min(1, message); - } -}; -ZodSet2.create = (valueType, params) => { - return new ZodSet2({ - valueType, - minSize: null, - maxSize: null, - typeName: ZodFirstPartyTypeKind2.ZodSet, - ...processCreateParams(params) - }); -}; -var ZodFunction2 = class _ZodFunction extends ZodType2 { - static { - __name(this, "ZodFunction"); - } - constructor() { - super(...arguments); - this.validate = this.implement; - } - _parse(input) { - const { ctx } = this._processInputParams(input); - if (ctx.parsedType !== ZodParsedType.function) { - addIssueToContext(ctx, { - code: ZodIssueCode2.invalid_type, - expected: ZodParsedType.function, - received: ctx.parsedType - }); - return INVALID; - } - function makeArgsIssue(args, error45) { - return makeIssue({ - data: args, - path: ctx.path, - errorMaps: [ - ctx.common.contextualErrorMap, - ctx.schemaErrorMap, - getErrorMap2(), - en_default2 - ].filter((x) => !!x), - issueData: { - code: ZodIssueCode2.invalid_arguments, - argumentsError: error45 - } - }); - } - __name(makeArgsIssue, "makeArgsIssue"); - function makeReturnsIssue(returns, error45) { - return makeIssue({ - data: returns, - path: ctx.path, - errorMaps: [ - ctx.common.contextualErrorMap, - ctx.schemaErrorMap, - getErrorMap2(), - en_default2 - ].filter((x) => !!x), - issueData: { - code: ZodIssueCode2.invalid_return_type, - returnTypeError: error45 - } - }); - } - __name(makeReturnsIssue, "makeReturnsIssue"); - const params = { - errorMap: ctx.common.contextualErrorMap - }; - const fn = ctx.data; - if (this._def.returns instanceof ZodPromise2) { - const me = this; - return OK(async function(...args) { - const error45 = new ZodError2([]); - const parsedArgs = await me._def.args.parseAsync(args, params).catch((e) => { - error45.addIssue(makeArgsIssue(args, e)); - throw error45; - }); - const result = await Reflect.apply(fn, this, parsedArgs); - const parsedReturns = await me._def.returns._def.type.parseAsync(result, params).catch((e) => { - error45.addIssue(makeReturnsIssue(result, e)); - throw error45; - }); - return parsedReturns; - }); - } else { - const me = this; - return OK(function(...args) { - const parsedArgs = me._def.args.safeParse(args, params); - if (!parsedArgs.success) { - throw new ZodError2([ - makeArgsIssue(args, parsedArgs.error) - ]); - } - const result = Reflect.apply(fn, this, parsedArgs.data); - const parsedReturns = me._def.returns.safeParse(result, params); - if (!parsedReturns.success) { - throw new ZodError2([ - makeReturnsIssue(result, parsedReturns.error) - ]); - } - return parsedReturns.data; - }); - } - } - parameters() { - return this._def.args; - } - returnType() { - return this._def.returns; - } - args(...items) { - return new _ZodFunction({ - ...this._def, - args: ZodTuple2.create(items).rest(ZodUnknown2.create()) - }); - } - returns(returnType) { - return new _ZodFunction({ - ...this._def, - returns: returnType - }); - } - implement(func) { - const validatedFunc = this.parse(func); - return validatedFunc; - } - strictImplement(func) { - const validatedFunc = this.parse(func); - return validatedFunc; - } - static create(args, returns, params) { - return new _ZodFunction({ - args: args ? args : ZodTuple2.create([]).rest(ZodUnknown2.create()), - returns: returns || ZodUnknown2.create(), - typeName: ZodFirstPartyTypeKind2.ZodFunction, - ...processCreateParams(params) - }); - } -}; -var ZodLazy2 = class extends ZodType2 { - static { - __name(this, "ZodLazy"); - } - get schema() { - return this._def.getter(); - } - _parse(input) { - const { ctx } = this._processInputParams(input); - const lazySchema = this._def.getter(); - return lazySchema._parse({ - data: ctx.data, - path: ctx.path, - parent: ctx - }); - } -}; -ZodLazy2.create = (getter, params) => { - return new ZodLazy2({ - getter, - typeName: ZodFirstPartyTypeKind2.ZodLazy, - ...processCreateParams(params) - }); -}; -var ZodLiteral2 = class extends ZodType2 { - static { - __name(this, "ZodLiteral"); - } - _parse(input) { - if (input.data !== this._def.value) { - const ctx = this._getOrReturnCtx(input); - addIssueToContext(ctx, { - received: ctx.data, - code: ZodIssueCode2.invalid_literal, - expected: this._def.value - }); - return INVALID; - } - return { - status: "valid", - value: input.data - }; - } - get value() { - return this._def.value; - } -}; -ZodLiteral2.create = (value, params) => { - return new ZodLiteral2({ - value, - typeName: ZodFirstPartyTypeKind2.ZodLiteral, - ...processCreateParams(params) - }); -}; -function createZodEnum(values, params) { - return new ZodEnum2({ - values, - typeName: ZodFirstPartyTypeKind2.ZodEnum, - ...processCreateParams(params) - }); -} -__name(createZodEnum, "createZodEnum"); -var ZodEnum2 = class _ZodEnum extends ZodType2 { - static { - __name(this, "ZodEnum"); - } - _parse(input) { - if (typeof input.data !== "string") { - const ctx = this._getOrReturnCtx(input); - const expectedValues = this._def.values; - addIssueToContext(ctx, { - expected: util.joinValues(expectedValues), - received: ctx.parsedType, - code: ZodIssueCode2.invalid_type - }); - return INVALID; - } - if (!this._cache) { - this._cache = new Set(this._def.values); - } - if (!this._cache.has(input.data)) { - const ctx = this._getOrReturnCtx(input); - const expectedValues = this._def.values; - addIssueToContext(ctx, { - received: ctx.data, - code: ZodIssueCode2.invalid_enum_value, - options: expectedValues - }); - return INVALID; - } - return OK(input.data); - } - get options() { - return this._def.values; - } - get enum() { - const enumValues = {}; - for (const val of this._def.values) { - enumValues[val] = val; - } - return enumValues; - } - get Values() { - const enumValues = {}; - for (const val of this._def.values) { - enumValues[val] = val; - } - return enumValues; - } - get Enum() { - const enumValues = {}; - for (const val of this._def.values) { - enumValues[val] = val; - } - return enumValues; - } - extract(values, newDef = this._def) { - return _ZodEnum.create(values, { - ...this._def, - ...newDef - }); - } - exclude(values, newDef = this._def) { - return _ZodEnum.create(this.options.filter((opt) => !values.includes(opt)), { - ...this._def, - ...newDef - }); - } -}; -ZodEnum2.create = createZodEnum; -var ZodNativeEnum = class extends ZodType2 { - static { - __name(this, "ZodNativeEnum"); - } - _parse(input) { - const nativeEnumValues = util.getValidEnumValues(this._def.values); - const ctx = this._getOrReturnCtx(input); - if (ctx.parsedType !== ZodParsedType.string && ctx.parsedType !== ZodParsedType.number) { - const expectedValues = util.objectValues(nativeEnumValues); - addIssueToContext(ctx, { - expected: util.joinValues(expectedValues), - received: ctx.parsedType, - code: ZodIssueCode2.invalid_type - }); - return INVALID; - } - if (!this._cache) { - this._cache = new Set(util.getValidEnumValues(this._def.values)); - } - if (!this._cache.has(input.data)) { - const expectedValues = util.objectValues(nativeEnumValues); - addIssueToContext(ctx, { - received: ctx.data, - code: ZodIssueCode2.invalid_enum_value, - options: expectedValues - }); - return INVALID; - } - return OK(input.data); - } - get enum() { - return this._def.values; - } -}; -ZodNativeEnum.create = (values, params) => { - return new ZodNativeEnum({ - values, - typeName: ZodFirstPartyTypeKind2.ZodNativeEnum, - ...processCreateParams(params) - }); -}; -var ZodPromise2 = class extends ZodType2 { - static { - __name(this, "ZodPromise"); - } - unwrap() { - return this._def.type; - } - _parse(input) { - const { ctx } = this._processInputParams(input); - if (ctx.parsedType !== ZodParsedType.promise && ctx.common.async === false) { - addIssueToContext(ctx, { - code: ZodIssueCode2.invalid_type, - expected: ZodParsedType.promise, - received: ctx.parsedType - }); - return INVALID; - } - const promisified = ctx.parsedType === ZodParsedType.promise ? ctx.data : Promise.resolve(ctx.data); - return OK(promisified.then((data) => { - return this._def.type.parseAsync(data, { - path: ctx.path, - errorMap: ctx.common.contextualErrorMap - }); - })); - } -}; -ZodPromise2.create = (schema, params) => { - return new ZodPromise2({ - type: schema, - typeName: ZodFirstPartyTypeKind2.ZodPromise, - ...processCreateParams(params) - }); -}; -var ZodEffects = class extends ZodType2 { - static { - __name(this, "ZodEffects"); - } - innerType() { - return this._def.schema; - } - sourceType() { - return this._def.schema._def.typeName === ZodFirstPartyTypeKind2.ZodEffects ? this._def.schema.sourceType() : this._def.schema; - } - _parse(input) { - const { status, ctx } = this._processInputParams(input); - const effect = this._def.effect || null; - const checkCtx = { - addIssue: /* @__PURE__ */ __name((arg) => { - addIssueToContext(ctx, arg); - if (arg.fatal) { - status.abort(); - } else { - status.dirty(); - } - }, "addIssue"), - get path() { - return ctx.path; - } - }; - checkCtx.addIssue = checkCtx.addIssue.bind(checkCtx); - if (effect.type === "preprocess") { - const processed = effect.transform(ctx.data, checkCtx); - if (ctx.common.async) { - return Promise.resolve(processed).then(async (processed2) => { - if (status.value === "aborted") return INVALID; - const result = await this._def.schema._parseAsync({ - data: processed2, - path: ctx.path, - parent: ctx - }); - if (result.status === "aborted") return INVALID; - if (result.status === "dirty") return DIRTY(result.value); - if (status.value === "dirty") return DIRTY(result.value); - return result; - }); - } else { - if (status.value === "aborted") return INVALID; - const result = this._def.schema._parseSync({ - data: processed, - path: ctx.path, - parent: ctx - }); - if (result.status === "aborted") return INVALID; - if (result.status === "dirty") return DIRTY(result.value); - if (status.value === "dirty") return DIRTY(result.value); - return result; - } - } - if (effect.type === "refinement") { - const executeRefinement = /* @__PURE__ */ __name((acc) => { - const result = effect.refinement(acc, checkCtx); - if (ctx.common.async) { - return Promise.resolve(result); - } - if (result instanceof Promise) { - throw new Error("Async refinement encountered during synchronous parse operation. Use .parseAsync instead."); - } - return acc; - }, "executeRefinement"); - if (ctx.common.async === false) { - const inner = this._def.schema._parseSync({ - data: ctx.data, - path: ctx.path, - parent: ctx - }); - if (inner.status === "aborted") return INVALID; - if (inner.status === "dirty") status.dirty(); - executeRefinement(inner.value); - return { - status: status.value, - value: inner.value - }; - } else { - return this._def.schema._parseAsync({ - data: ctx.data, - path: ctx.path, - parent: ctx - }).then((inner) => { - if (inner.status === "aborted") return INVALID; - if (inner.status === "dirty") status.dirty(); - return executeRefinement(inner.value).then(() => { - return { - status: status.value, - value: inner.value - }; - }); - }); - } - } - if (effect.type === "transform") { - if (ctx.common.async === false) { - const base = this._def.schema._parseSync({ - data: ctx.data, - path: ctx.path, - parent: ctx - }); - if (!isValid(base)) return INVALID; - const result = effect.transform(base.value, checkCtx); - if (result instanceof Promise) { - throw new Error(\`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.\`); - } - return { - status: status.value, - value: result - }; - } else { - return this._def.schema._parseAsync({ - data: ctx.data, - path: ctx.path, - parent: ctx - }).then((base) => { - if (!isValid(base)) return INVALID; - return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({ - status: status.value, - value: result - })); - }); - } - } - util.assertNever(effect); - } -}; -ZodEffects.create = (schema, effect, params) => { - return new ZodEffects({ - schema, - typeName: ZodFirstPartyTypeKind2.ZodEffects, - effect, - ...processCreateParams(params) - }); -}; -ZodEffects.createWithPreprocess = (preprocess2, schema, params) => { - return new ZodEffects({ - schema, - effect: { - type: "preprocess", - transform: preprocess2 - }, - typeName: ZodFirstPartyTypeKind2.ZodEffects, - ...processCreateParams(params) - }); -}; -var ZodOptional2 = class extends ZodType2 { - static { - __name(this, "ZodOptional"); - } - _parse(input) { - const parsedType7 = this._getType(input); - if (parsedType7 === ZodParsedType.undefined) { - return OK(void 0); - } - return this._def.innerType._parse(input); - } - unwrap() { - return this._def.innerType; - } -}; -ZodOptional2.create = (type, params) => { - return new ZodOptional2({ - innerType: type, - typeName: ZodFirstPartyTypeKind2.ZodOptional, - ...processCreateParams(params) - }); -}; -var ZodNullable2 = class extends ZodType2 { - static { - __name(this, "ZodNullable"); - } - _parse(input) { - const parsedType7 = this._getType(input); - if (parsedType7 === ZodParsedType.null) { - return OK(null); - } - return this._def.innerType._parse(input); - } - unwrap() { - return this._def.innerType; - } -}; -ZodNullable2.create = (type, params) => { - return new ZodNullable2({ - innerType: type, - typeName: ZodFirstPartyTypeKind2.ZodNullable, - ...processCreateParams(params) - }); -}; -var ZodDefault2 = class extends ZodType2 { - static { - __name(this, "ZodDefault"); - } - _parse(input) { - const { ctx } = this._processInputParams(input); - let data = ctx.data; - if (ctx.parsedType === ZodParsedType.undefined) { - data = this._def.defaultValue(); - } - return this._def.innerType._parse({ - data, - path: ctx.path, - parent: ctx - }); - } - removeDefault() { - return this._def.innerType; - } -}; -ZodDefault2.create = (type, params) => { - return new ZodDefault2({ - innerType: type, - typeName: ZodFirstPartyTypeKind2.ZodDefault, - defaultValue: typeof params.default === "function" ? params.default : () => params.default, - ...processCreateParams(params) - }); -}; -var ZodCatch2 = class extends ZodType2 { - static { - __name(this, "ZodCatch"); - } - _parse(input) { - const { ctx } = this._processInputParams(input); - const newCtx = { - ...ctx, - common: { - ...ctx.common, - issues: [] - } - }; - const result = this._def.innerType._parse({ - data: newCtx.data, - path: newCtx.path, - parent: { - ...newCtx - } - }); - if (isAsync(result)) { - return result.then((result2) => { - return { - status: "valid", - value: result2.status === "valid" ? result2.value : this._def.catchValue({ - get error() { - return new ZodError2(newCtx.common.issues); - }, - input: newCtx.data - }) - }; - }); - } else { - return { - status: "valid", - value: result.status === "valid" ? result.value : this._def.catchValue({ - get error() { - return new ZodError2(newCtx.common.issues); - }, - input: newCtx.data - }) - }; - } - } - removeCatch() { - return this._def.innerType; - } -}; -ZodCatch2.create = (type, params) => { - return new ZodCatch2({ - innerType: type, - typeName: ZodFirstPartyTypeKind2.ZodCatch, - catchValue: typeof params.catch === "function" ? params.catch : () => params.catch, - ...processCreateParams(params) - }); -}; -var ZodNaN2 = class extends ZodType2 { - static { - __name(this, "ZodNaN"); - } - _parse(input) { - const parsedType7 = this._getType(input); - if (parsedType7 !== ZodParsedType.nan) { - const ctx = this._getOrReturnCtx(input); - addIssueToContext(ctx, { - code: ZodIssueCode2.invalid_type, - expected: ZodParsedType.nan, - received: ctx.parsedType - }); - return INVALID; - } - return { - status: "valid", - value: input.data - }; - } -}; -ZodNaN2.create = (params) => { - return new ZodNaN2({ - typeName: ZodFirstPartyTypeKind2.ZodNaN, - ...processCreateParams(params) - }); -}; -var BRAND = Symbol("zod_brand"); -var ZodBranded = class extends ZodType2 { - static { - __name(this, "ZodBranded"); - } - _parse(input) { - const { ctx } = this._processInputParams(input); - const data = ctx.data; - return this._def.type._parse({ - data, - path: ctx.path, - parent: ctx - }); - } - unwrap() { - return this._def.type; - } -}; -var ZodPipeline = class _ZodPipeline extends ZodType2 { - static { - __name(this, "ZodPipeline"); - } - _parse(input) { - const { status, ctx } = this._processInputParams(input); - if (ctx.common.async) { - const handleAsync = /* @__PURE__ */ __name(async () => { - const inResult = await this._def.in._parseAsync({ - data: ctx.data, - path: ctx.path, - parent: ctx - }); - if (inResult.status === "aborted") return INVALID; - if (inResult.status === "dirty") { - status.dirty(); - return DIRTY(inResult.value); - } else { - return this._def.out._parseAsync({ - data: inResult.value, - path: ctx.path, - parent: ctx - }); - } - }, "handleAsync"); - return handleAsync(); - } else { - const inResult = this._def.in._parseSync({ - data: ctx.data, - path: ctx.path, - parent: ctx - }); - if (inResult.status === "aborted") return INVALID; - if (inResult.status === "dirty") { - status.dirty(); - return { - status: "dirty", - value: inResult.value - }; - } else { - return this._def.out._parseSync({ - data: inResult.value, - path: ctx.path, - parent: ctx - }); - } - } - } - static create(a, b) { - return new _ZodPipeline({ - in: a, - out: b, - typeName: ZodFirstPartyTypeKind2.ZodPipeline - }); - } -}; -var ZodReadonly2 = class extends ZodType2 { - static { - __name(this, "ZodReadonly"); - } - _parse(input) { - const result = this._def.innerType._parse(input); - const freeze = /* @__PURE__ */ __name((data) => { - if (isValid(data)) { - data.value = Object.freeze(data.value); - } - return data; - }, "freeze"); - return isAsync(result) ? result.then((data) => freeze(data)) : freeze(result); - } - unwrap() { - return this._def.innerType; - } -}; -ZodReadonly2.create = (type, params) => { - return new ZodReadonly2({ - innerType: type, - typeName: ZodFirstPartyTypeKind2.ZodReadonly, - ...processCreateParams(params) - }); -}; -var late = { - object: ZodObject2.lazycreate -}; -var ZodFirstPartyTypeKind2; -(function(ZodFirstPartyTypeKind3) { - ZodFirstPartyTypeKind3["ZodString"] = "ZodString"; - ZodFirstPartyTypeKind3["ZodNumber"] = "ZodNumber"; - ZodFirstPartyTypeKind3["ZodNaN"] = "ZodNaN"; - ZodFirstPartyTypeKind3["ZodBigInt"] = "ZodBigInt"; - ZodFirstPartyTypeKind3["ZodBoolean"] = "ZodBoolean"; - ZodFirstPartyTypeKind3["ZodDate"] = "ZodDate"; - ZodFirstPartyTypeKind3["ZodSymbol"] = "ZodSymbol"; - ZodFirstPartyTypeKind3["ZodUndefined"] = "ZodUndefined"; - ZodFirstPartyTypeKind3["ZodNull"] = "ZodNull"; - ZodFirstPartyTypeKind3["ZodAny"] = "ZodAny"; - ZodFirstPartyTypeKind3["ZodUnknown"] = "ZodUnknown"; - ZodFirstPartyTypeKind3["ZodNever"] = "ZodNever"; - ZodFirstPartyTypeKind3["ZodVoid"] = "ZodVoid"; - ZodFirstPartyTypeKind3["ZodArray"] = "ZodArray"; - ZodFirstPartyTypeKind3["ZodObject"] = "ZodObject"; - ZodFirstPartyTypeKind3["ZodUnion"] = "ZodUnion"; - ZodFirstPartyTypeKind3["ZodDiscriminatedUnion"] = "ZodDiscriminatedUnion"; - ZodFirstPartyTypeKind3["ZodIntersection"] = "ZodIntersection"; - ZodFirstPartyTypeKind3["ZodTuple"] = "ZodTuple"; - ZodFirstPartyTypeKind3["ZodRecord"] = "ZodRecord"; - ZodFirstPartyTypeKind3["ZodMap"] = "ZodMap"; - ZodFirstPartyTypeKind3["ZodSet"] = "ZodSet"; - ZodFirstPartyTypeKind3["ZodFunction"] = "ZodFunction"; - ZodFirstPartyTypeKind3["ZodLazy"] = "ZodLazy"; - ZodFirstPartyTypeKind3["ZodLiteral"] = "ZodLiteral"; - ZodFirstPartyTypeKind3["ZodEnum"] = "ZodEnum"; - ZodFirstPartyTypeKind3["ZodEffects"] = "ZodEffects"; - ZodFirstPartyTypeKind3["ZodNativeEnum"] = "ZodNativeEnum"; - ZodFirstPartyTypeKind3["ZodOptional"] = "ZodOptional"; - ZodFirstPartyTypeKind3["ZodNullable"] = "ZodNullable"; - ZodFirstPartyTypeKind3["ZodDefault"] = "ZodDefault"; - ZodFirstPartyTypeKind3["ZodCatch"] = "ZodCatch"; - ZodFirstPartyTypeKind3["ZodPromise"] = "ZodPromise"; - ZodFirstPartyTypeKind3["ZodBranded"] = "ZodBranded"; - ZodFirstPartyTypeKind3["ZodPipeline"] = "ZodPipeline"; - ZodFirstPartyTypeKind3["ZodReadonly"] = "ZodReadonly"; -})(ZodFirstPartyTypeKind2 || (ZodFirstPartyTypeKind2 = {})); -var stringType = ZodString2.create; -var numberType = ZodNumber2.create; -var nanType = ZodNaN2.create; -var bigIntType = ZodBigInt2.create; -var booleanType = ZodBoolean2.create; -var dateType = ZodDate2.create; -var symbolType = ZodSymbol2.create; -var undefinedType = ZodUndefined2.create; -var nullType = ZodNull2.create; -var anyType = ZodAny2.create; -var unknownType = ZodUnknown2.create; -var neverType = ZodNever2.create; -var voidType = ZodVoid2.create; -var arrayType = ZodArray2.create; -var objectType = ZodObject2.create; -var strictObjectType = ZodObject2.strictCreate; -var unionType = ZodUnion2.create; -var discriminatedUnionType = ZodDiscriminatedUnion2.create; -var intersectionType = ZodIntersection2.create; -var tupleType = ZodTuple2.create; -var recordType = ZodRecord2.create; -var mapType = ZodMap2.create; -var setType = ZodSet2.create; -var functionType = ZodFunction2.create; -var lazyType = ZodLazy2.create; -var literalType = ZodLiteral2.create; -var enumType = ZodEnum2.create; -var nativeEnumType = ZodNativeEnum.create; -var promiseType = ZodPromise2.create; -var effectsType = ZodEffects.create; -var optionalType = ZodOptional2.create; -var nullableType = ZodNullable2.create; -var preprocessType = ZodEffects.createWithPreprocess; -var pipelineType = ZodPipeline.create; - -// ../../node_modules/.pnpm/@ai-sdk+provider-utils@3.0.12_zod@4.1.11/node_modules/@ai-sdk/provider-utils/dist/index.mjs -function combineHeaders(...headers) { - return headers.reduce((combinedHeaders, currentHeaders) => ({ - ...combinedHeaders, - ...currentHeaders != null ? currentHeaders : {} - }), {}); -} -__name(combineHeaders, "combineHeaders"); -async function delay(delayInMs, options) { - if (delayInMs == null) { - return Promise.resolve(); - } - const signal = options == null ? void 0 : options.abortSignal; - return new Promise((resolve2, reject) => { - if (signal == null ? void 0 : signal.aborted) { - reject(createAbortError()); - return; - } - const timeoutId = setTimeout(() => { - cleanup(); - resolve2(); - }, delayInMs); - const cleanup = /* @__PURE__ */ __name(() => { - clearTimeout(timeoutId); - signal == null ? void 0 : signal.removeEventListener("abort", onAbort); - }, "cleanup"); - const onAbort = /* @__PURE__ */ __name(() => { - cleanup(); - reject(createAbortError()); - }, "onAbort"); - signal == null ? void 0 : signal.addEventListener("abort", onAbort); - }); -} -__name(delay, "delay"); -function createAbortError() { - return new DOMException("Delay was aborted", "AbortError"); -} -__name(createAbortError, "createAbortError"); -function extractResponseHeaders(response) { - return Object.fromEntries([ - ...response.headers - ]); -} -__name(extractResponseHeaders, "extractResponseHeaders"); -var createIdGenerator = /* @__PURE__ */ __name(({ prefix, size = 16, alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", separator = "-" } = {}) => { - const generator = /* @__PURE__ */ __name(() => { - const alphabetLength = alphabet.length; - const chars = new Array(size); - for (let i = 0; i < size; i++) { - chars[i] = alphabet[Math.random() * alphabetLength | 0]; - } - return chars.join(""); - }, "generator"); - if (prefix == null) { - return generator; - } - if (alphabet.includes(separator)) { - throw new InvalidArgumentError({ - argument: "separator", - message: \`The separator "\${separator}" must not be part of the alphabet "\${alphabet}".\` - }); - } - return () => \`\${prefix}\${separator}\${generator()}\`; -}, "createIdGenerator"); -var generateId = createIdGenerator(); -function getErrorMessage2(error45) { - if (error45 == null) { - return "unknown error"; - } - if (typeof error45 === "string") { - return error45; - } - if (error45 instanceof Error) { - return error45.message; - } - return JSON.stringify(error45); -} -__name(getErrorMessage2, "getErrorMessage"); -function isAbortError(error45) { - return (error45 instanceof Error || error45 instanceof DOMException) && (error45.name === "AbortError" || error45.name === "ResponseAborted" || // Next.js - error45.name === "TimeoutError"); -} -__name(isAbortError, "isAbortError"); -var FETCH_FAILED_ERROR_MESSAGES = [ - "fetch failed", - "failed to fetch" -]; -function handleFetchError({ error: error45, url: url2, requestBodyValues }) { - if (isAbortError(error45)) { - return error45; - } - if (error45 instanceof TypeError && FETCH_FAILED_ERROR_MESSAGES.includes(error45.message.toLowerCase())) { - const cause = error45.cause; - if (cause != null) { - return new APICallError({ - message: \`Cannot connect to API: \${cause.message}\`, - cause, - url: url2, - requestBodyValues, - isRetryable: true - }); - } - } - return error45; -} -__name(handleFetchError, "handleFetchError"); -function getRuntimeEnvironmentUserAgent(globalThisAny = globalThis) { - var _a17, _b8, _c; - if (globalThisAny.window) { - return \`runtime/browser\`; - } - if ((_a17 = globalThisAny.navigator) == null ? void 0 : _a17.userAgent) { - return \`runtime/\${globalThisAny.navigator.userAgent.toLowerCase()}\`; - } - if ((_c = (_b8 = globalThisAny.process) == null ? void 0 : _b8.versions) == null ? void 0 : _c.node) { - return \`runtime/node.js/\${globalThisAny.process.version.substring(0)}\`; - } - if (globalThisAny.EdgeRuntime) { - return \`runtime/vercel-edge\`; - } - return "runtime/unknown"; -} -__name(getRuntimeEnvironmentUserAgent, "getRuntimeEnvironmentUserAgent"); -function removeUndefinedEntries(record2) { - return Object.fromEntries(Object.entries(record2).filter(([_key, value]) => value != null)); -} -__name(removeUndefinedEntries, "removeUndefinedEntries"); -function withUserAgentSuffix(headers, ...userAgentSuffixParts) { - const cleanedHeaders = removeUndefinedEntries(headers != null ? headers : {}); - const normalizedHeaders = new Headers(cleanedHeaders); - const currentUserAgentHeader = normalizedHeaders.get("user-agent") || ""; - normalizedHeaders.set("user-agent", [ - currentUserAgentHeader, - ...userAgentSuffixParts - ].filter(Boolean).join(" ")); - return Object.fromEntries(normalizedHeaders); -} -__name(withUserAgentSuffix, "withUserAgentSuffix"); -var VERSION = true ? "3.0.12" : "0.0.0-test"; -var getOriginalFetch = /* @__PURE__ */ __name(() => globalThis.fetch, "getOriginalFetch"); -var getFromApi = /* @__PURE__ */ __name(async ({ url: url2, headers = {}, successfulResponseHandler, failedResponseHandler, abortSignal, fetch: fetch3 = getOriginalFetch() }) => { - try { - const response = await fetch3(url2, { - method: "GET", - headers: withUserAgentSuffix(headers, \`ai-sdk/provider-utils/\${VERSION}\`, getRuntimeEnvironmentUserAgent()), - signal: abortSignal - }); - const responseHeaders = extractResponseHeaders(response); - if (!response.ok) { - let errorInformation; - try { - errorInformation = await failedResponseHandler({ - response, - url: url2, - requestBodyValues: {} - }); - } catch (error45) { - if (isAbortError(error45) || APICallError.isInstance(error45)) { - throw error45; - } - throw new APICallError({ - message: "Failed to process error response", - cause: error45, - statusCode: response.status, - url: url2, - responseHeaders, - requestBodyValues: {} - }); - } - throw errorInformation.value; - } - try { - return await successfulResponseHandler({ - response, - url: url2, - requestBodyValues: {} - }); - } catch (error45) { - if (error45 instanceof Error) { - if (isAbortError(error45) || APICallError.isInstance(error45)) { - throw error45; - } - } - throw new APICallError({ - message: "Failed to process successful response", - cause: error45, - statusCode: response.status, - url: url2, - responseHeaders, - requestBodyValues: {} - }); - } - } catch (error45) { - throw handleFetchError({ - error: error45, - url: url2, - requestBodyValues: {} - }); - } -}, "getFromApi"); -function isUrlSupported({ mediaType, url: url2, supportedUrls }) { - url2 = url2.toLowerCase(); - mediaType = mediaType.toLowerCase(); - return Object.entries(supportedUrls).map(([key, value]) => { - const mediaType2 = key.toLowerCase(); - return mediaType2 === "*" || mediaType2 === "*/*" ? { - mediaTypePrefix: "", - regexes: value - } : { - mediaTypePrefix: mediaType2.replace(/\\*/, ""), - regexes: value - }; - }).filter(({ mediaTypePrefix }) => mediaType.startsWith(mediaTypePrefix)).flatMap(({ regexes }) => regexes).some((pattern) => pattern.test(url2)); -} -__name(isUrlSupported, "isUrlSupported"); -function loadOptionalSetting({ settingValue, environmentVariableName }) { - if (typeof settingValue === "string") { - return settingValue; - } - if (settingValue != null || typeof process === "undefined") { - return void 0; - } - settingValue = process.env[environmentVariableName]; - if (settingValue == null || typeof settingValue !== "string") { - return void 0; - } - return settingValue; -} -__name(loadOptionalSetting, "loadOptionalSetting"); -var suspectProtoRx = /"__proto__"\\s*:/; -var suspectConstructorRx = /"constructor"\\s*:/; -function _parse2(text2) { - const obj = JSON.parse(text2); - if (obj === null || typeof obj !== "object") { - return obj; - } - if (suspectProtoRx.test(text2) === false && suspectConstructorRx.test(text2) === false) { - return obj; - } - return filter(obj); -} -__name(_parse2, "_parse"); -function filter(obj) { - let next = [ - obj - ]; - while (next.length) { - const nodes = next; - next = []; - for (const node of nodes) { - if (Object.prototype.hasOwnProperty.call(node, "__proto__")) { - throw new SyntaxError("Object contains forbidden prototype property"); - } - if (Object.prototype.hasOwnProperty.call(node, "constructor") && Object.prototype.hasOwnProperty.call(node.constructor, "prototype")) { - throw new SyntaxError("Object contains forbidden prototype property"); - } - for (const key in node) { - const value = node[key]; - if (value && typeof value === "object") { - next.push(value); - } - } - } - } - return obj; -} -__name(filter, "filter"); -function secureJsonParse(text2) { - const { stackTraceLimit } = Error; - Error.stackTraceLimit = 0; - try { - return _parse2(text2); - } finally { - Error.stackTraceLimit = stackTraceLimit; - } -} -__name(secureJsonParse, "secureJsonParse"); -var validatorSymbol = Symbol.for("vercel.ai.validator"); -function validator(validate) { - return { - [validatorSymbol]: true, - validate - }; -} -__name(validator, "validator"); -function isValidator(value) { - return typeof value === "object" && value !== null && validatorSymbol in value && value[validatorSymbol] === true && "validate" in value; -} -__name(isValidator, "isValidator"); -function lazyValidator(createValidator) { - let validator2; - return () => { - if (validator2 == null) { - validator2 = createValidator(); - } - return validator2; - }; -} -__name(lazyValidator, "lazyValidator"); -function asValidator(value) { - return isValidator(value) ? value : typeof value === "function" ? value() : standardSchemaValidator(value); -} -__name(asValidator, "asValidator"); -function standardSchemaValidator(standardSchema) { - return validator(async (value) => { - const result = await standardSchema["~standard"].validate(value); - return result.issues == null ? { - success: true, - value: result.value - } : { - success: false, - error: new TypeValidationError({ - value, - cause: result.issues - }) - }; - }); -} -__name(standardSchemaValidator, "standardSchemaValidator"); -async function validateTypes({ value, schema }) { - const result = await safeValidateTypes({ - value, - schema - }); - if (!result.success) { - throw TypeValidationError.wrap({ - value, - cause: result.error - }); - } - return result.value; -} -__name(validateTypes, "validateTypes"); -async function safeValidateTypes({ value, schema }) { - const validator2 = asValidator(schema); - try { - if (validator2.validate == null) { - return { - success: true, - value, - rawValue: value - }; - } - const result = await validator2.validate(value); - if (result.success) { - return { - success: true, - value: result.value, - rawValue: value - }; - } - return { - success: false, - error: TypeValidationError.wrap({ - value, - cause: result.error - }), - rawValue: value - }; - } catch (error45) { - return { - success: false, - error: TypeValidationError.wrap({ - value, - cause: error45 - }), - rawValue: value - }; - } -} -__name(safeValidateTypes, "safeValidateTypes"); -async function parseJSON({ text: text2, schema }) { - try { - const value = secureJsonParse(text2); - if (schema == null) { - return value; - } - return validateTypes({ - value, - schema - }); - } catch (error45) { - if (JSONParseError.isInstance(error45) || TypeValidationError.isInstance(error45)) { - throw error45; - } - throw new JSONParseError({ - text: text2, - cause: error45 - }); - } -} -__name(parseJSON, "parseJSON"); -async function safeParseJSON({ text: text2, schema }) { - try { - const value = secureJsonParse(text2); - if (schema == null) { - return { - success: true, - value, - rawValue: value - }; - } - return await safeValidateTypes({ - value, - schema - }); - } catch (error45) { - return { - success: false, - error: JSONParseError.isInstance(error45) ? error45 : new JSONParseError({ - text: text2, - cause: error45 - }), - rawValue: void 0 - }; - } -} -__name(safeParseJSON, "safeParseJSON"); -function parseJsonEventStream({ stream, schema }) { - return stream.pipeThrough(new TextDecoderStream()).pipeThrough(new EventSourceParserStream()).pipeThrough(new TransformStream({ - async transform({ data }, controller) { - if (data === "[DONE]") { - return; - } - controller.enqueue(await safeParseJSON({ - text: data, - schema - })); - } - })); -} -__name(parseJsonEventStream, "parseJsonEventStream"); -var getOriginalFetch2 = /* @__PURE__ */ __name(() => globalThis.fetch, "getOriginalFetch2"); -var postJsonToApi = /* @__PURE__ */ __name(async ({ url: url2, headers, body, failedResponseHandler, successfulResponseHandler, abortSignal, fetch: fetch3 }) => postToApi({ - url: url2, - headers: { - "Content-Type": "application/json", - ...headers - }, - body: { - content: JSON.stringify(body), - values: body - }, - failedResponseHandler, - successfulResponseHandler, - abortSignal, - fetch: fetch3 -}), "postJsonToApi"); -var postToApi = /* @__PURE__ */ __name(async ({ url: url2, headers = {}, body, successfulResponseHandler, failedResponseHandler, abortSignal, fetch: fetch3 = getOriginalFetch2() }) => { - try { - const response = await fetch3(url2, { - method: "POST", - headers: withUserAgentSuffix(headers, \`ai-sdk/provider-utils/\${VERSION}\`, getRuntimeEnvironmentUserAgent()), - body: body.content, - signal: abortSignal - }); - const responseHeaders = extractResponseHeaders(response); - if (!response.ok) { - let errorInformation; - try { - errorInformation = await failedResponseHandler({ - response, - url: url2, - requestBodyValues: body.values - }); - } catch (error45) { - if (isAbortError(error45) || APICallError.isInstance(error45)) { - throw error45; - } - throw new APICallError({ - message: "Failed to process error response", - cause: error45, - statusCode: response.status, - url: url2, - responseHeaders, - requestBodyValues: body.values - }); - } - throw errorInformation.value; - } - try { - return await successfulResponseHandler({ - response, - url: url2, - requestBodyValues: body.values - }); - } catch (error45) { - if (error45 instanceof Error) { - if (isAbortError(error45) || APICallError.isInstance(error45)) { - throw error45; - } - } - throw new APICallError({ - message: "Failed to process successful response", - cause: error45, - statusCode: response.status, - url: url2, - responseHeaders, - requestBodyValues: body.values - }); - } - } catch (error45) { - throw handleFetchError({ - error: error45, - url: url2, - requestBodyValues: body.values - }); - } -}, "postToApi"); -async function resolve(value) { - if (typeof value === "function") { - value = value(); - } - return Promise.resolve(value); -} -__name(resolve, "resolve"); -var createJsonErrorResponseHandler = /* @__PURE__ */ __name(({ errorSchema, errorToMessage, isRetryable }) => async ({ response, url: url2, requestBodyValues }) => { - const responseBody = await response.text(); - const responseHeaders = extractResponseHeaders(response); - if (responseBody.trim() === "") { - return { - responseHeaders, - value: new APICallError({ - message: response.statusText, - url: url2, - requestBodyValues, - statusCode: response.status, - responseHeaders, - responseBody, - isRetryable: isRetryable == null ? void 0 : isRetryable(response) - }) - }; - } - try { - const parsedError = await parseJSON({ - text: responseBody, - schema: errorSchema - }); - return { - responseHeaders, - value: new APICallError({ - message: errorToMessage(parsedError), - url: url2, - requestBodyValues, - statusCode: response.status, - responseHeaders, - responseBody, - data: parsedError, - isRetryable: isRetryable == null ? void 0 : isRetryable(response, parsedError) - }) - }; - } catch (parseError) { - return { - responseHeaders, - value: new APICallError({ - message: response.statusText, - url: url2, - requestBodyValues, - statusCode: response.status, - responseHeaders, - responseBody, - isRetryable: isRetryable == null ? void 0 : isRetryable(response) - }) - }; - } -}, "createJsonErrorResponseHandler"); -var createEventSourceResponseHandler = /* @__PURE__ */ __name((chunkSchema) => async ({ response }) => { - const responseHeaders = extractResponseHeaders(response); - if (response.body == null) { - throw new EmptyResponseBodyError({}); - } - return { - responseHeaders, - value: parseJsonEventStream({ - stream: response.body, - schema: chunkSchema - }) - }; -}, "createEventSourceResponseHandler"); -var createJsonResponseHandler = /* @__PURE__ */ __name((responseSchema) => async ({ response, url: url2, requestBodyValues }) => { - const responseBody = await response.text(); - const parsedResult = await safeParseJSON({ - text: responseBody, - schema: responseSchema - }); - const responseHeaders = extractResponseHeaders(response); - if (!parsedResult.success) { - throw new APICallError({ - message: "Invalid JSON response", - cause: parsedResult.error, - statusCode: response.status, - responseHeaders, - responseBody, - url: url2, - requestBodyValues - }); - } - return { - responseHeaders, - value: parsedResult.value, - rawValue: parsedResult.rawValue - }; -}, "createJsonResponseHandler"); -var getRelativePath = /* @__PURE__ */ __name((pathA, pathB) => { - let i = 0; - for (; i < pathA.length && i < pathB.length; i++) { - if (pathA[i] !== pathB[i]) break; - } - return [ - (pathA.length - i).toString(), - ...pathB.slice(i) - ].join("/"); -}, "getRelativePath"); -var ignoreOverride = Symbol("Let zodToJsonSchema decide on which parser to use"); -var defaultOptions = { - name: void 0, - \$refStrategy: "root", - basePath: [ - "#" - ], - effectStrategy: "input", - pipeStrategy: "all", - dateStrategy: "format:date-time", - mapStrategy: "entries", - removeAdditionalStrategy: "passthrough", - allowedAdditionalProperties: true, - rejectedAdditionalProperties: false, - definitionPath: "definitions", - strictUnions: false, - definitions: {}, - errorMessages: false, - patternStrategy: "escape", - applyRegexFlags: false, - emailStrategy: "format:email", - base64Strategy: "contentEncoding:base64", - nameStrategy: "ref" -}; -var getDefaultOptions = /* @__PURE__ */ __name((options) => typeof options === "string" ? { - ...defaultOptions, - name: options -} : { - ...defaultOptions, - ...options -}, "getDefaultOptions"); -function parseAnyDef() { - return {}; -} -__name(parseAnyDef, "parseAnyDef"); -function parseArrayDef(def, refs) { - var _a17, _b8, _c; - const res = { - type: "array" - }; - if (((_a17 = def.type) == null ? void 0 : _a17._def) && ((_c = (_b8 = def.type) == null ? void 0 : _b8._def) == null ? void 0 : _c.typeName) !== ZodFirstPartyTypeKind2.ZodAny) { - res.items = parseDef(def.type._def, { - ...refs, - currentPath: [ - ...refs.currentPath, - "items" - ] - }); - } - if (def.minLength) { - res.minItems = def.minLength.value; - } - if (def.maxLength) { - res.maxItems = def.maxLength.value; - } - if (def.exactLength) { - res.minItems = def.exactLength.value; - res.maxItems = def.exactLength.value; - } - return res; -} -__name(parseArrayDef, "parseArrayDef"); -function parseBigintDef(def) { - const res = { - type: "integer", - format: "int64" - }; - if (!def.checks) return res; - for (const check2 of def.checks) { - switch (check2.kind) { - case "min": - if (check2.inclusive) { - res.minimum = check2.value; - } else { - res.exclusiveMinimum = check2.value; - } - break; - case "max": - if (check2.inclusive) { - res.maximum = check2.value; - } else { - res.exclusiveMaximum = check2.value; - } - break; - case "multipleOf": - res.multipleOf = check2.value; - break; - } - } - return res; -} -__name(parseBigintDef, "parseBigintDef"); -function parseBooleanDef() { - return { - type: "boolean" - }; -} -__name(parseBooleanDef, "parseBooleanDef"); -function parseBrandedDef(_def, refs) { - return parseDef(_def.type._def, refs); -} -__name(parseBrandedDef, "parseBrandedDef"); -var parseCatchDef = /* @__PURE__ */ __name((def, refs) => { - return parseDef(def.innerType._def, refs); -}, "parseCatchDef"); -function parseDateDef(def, refs, overrideDateStrategy) { - const strategy = overrideDateStrategy != null ? overrideDateStrategy : refs.dateStrategy; - if (Array.isArray(strategy)) { - return { - anyOf: strategy.map((item, i) => parseDateDef(def, refs, item)) - }; - } - switch (strategy) { - case "string": - case "format:date-time": - return { - type: "string", - format: "date-time" - }; - case "format:date": - return { - type: "string", - format: "date" - }; - case "integer": - return integerDateParser(def); - } -} -__name(parseDateDef, "parseDateDef"); -var integerDateParser = /* @__PURE__ */ __name((def) => { - const res = { - type: "integer", - format: "unix-time" - }; - for (const check2 of def.checks) { - switch (check2.kind) { - case "min": - res.minimum = check2.value; - break; - case "max": - res.maximum = check2.value; - break; - } - } - return res; -}, "integerDateParser"); -function parseDefaultDef(_def, refs) { - return { - ...parseDef(_def.innerType._def, refs), - default: _def.defaultValue() - }; -} -__name(parseDefaultDef, "parseDefaultDef"); -function parseEffectsDef(_def, refs) { - return refs.effectStrategy === "input" ? parseDef(_def.schema._def, refs) : parseAnyDef(); -} -__name(parseEffectsDef, "parseEffectsDef"); -function parseEnumDef(def) { - return { - type: "string", - enum: Array.from(def.values) - }; -} -__name(parseEnumDef, "parseEnumDef"); -var isJsonSchema7AllOfType = /* @__PURE__ */ __name((type) => { - if ("type" in type && type.type === "string") return false; - return "allOf" in type; -}, "isJsonSchema7AllOfType"); -function parseIntersectionDef(def, refs) { - const allOf = [ - parseDef(def.left._def, { - ...refs, - currentPath: [ - ...refs.currentPath, - "allOf", - "0" - ] - }), - parseDef(def.right._def, { - ...refs, - currentPath: [ - ...refs.currentPath, - "allOf", - "1" - ] - }) - ].filter((x) => !!x); - const mergedAllOf = []; - allOf.forEach((schema) => { - if (isJsonSchema7AllOfType(schema)) { - mergedAllOf.push(...schema.allOf); - } else { - let nestedSchema = schema; - if ("additionalProperties" in schema && schema.additionalProperties === false) { - const { additionalProperties, ...rest } = schema; - nestedSchema = rest; - } - mergedAllOf.push(nestedSchema); - } - }); - return mergedAllOf.length ? { - allOf: mergedAllOf - } : void 0; -} -__name(parseIntersectionDef, "parseIntersectionDef"); -function parseLiteralDef(def) { - const parsedType7 = typeof def.value; - if (parsedType7 !== "bigint" && parsedType7 !== "number" && parsedType7 !== "boolean" && parsedType7 !== "string") { - return { - type: Array.isArray(def.value) ? "array" : "object" - }; - } - return { - type: parsedType7 === "bigint" ? "integer" : parsedType7, - const: def.value - }; -} -__name(parseLiteralDef, "parseLiteralDef"); -var emojiRegex2 = void 0; -var zodPatterns = { - /** - * \`c\` was changed to \`[cC]\` to replicate /i flag - */ - cuid: /^[cC][^\\s-]{8,}\$/, - cuid2: /^[0-9a-z]+\$/, - ulid: /^[0-9A-HJKMNP-TV-Z]{26}\$/, - /** - * \`a-z\` was added to replicate /i flag - */ - email: /^(?!\\.)(?!.*\\.\\.)([a-zA-Z0-9_'+\\-\\.]*)[a-zA-Z0-9_+-]@([a-zA-Z0-9][a-zA-Z0-9\\-]*\\.)+[a-zA-Z]{2,}\$/, - /** - * Constructed a valid Unicode RegExp - * - * Lazily instantiate since this type of regex isn't supported - * in all envs (e.g. React Native). - * - * See: - * https://github.com/colinhacks/zod/issues/2433 - * Fix in Zod: - * https://github.com/colinhacks/zod/commit/9340fd51e48576a75adc919bff65dbc4a5d4c99b - */ - emoji: /* @__PURE__ */ __name(() => { - if (emojiRegex2 === void 0) { - emojiRegex2 = RegExp("^(\\\\p{Extended_Pictographic}|\\\\p{Emoji_Component})+\$", "u"); - } - return emojiRegex2; - }, "emoji"), - /** - * Unused - */ - uuid: /^[0-9a-fA-F]{8}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{12}\$/, - /** - * Unused - */ - ipv4: /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\$/, - ipv4Cidr: /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\/(3[0-2]|[12]?[0-9])\$/, - /** - * Unused - */ - ipv6: /^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))\$/, - ipv6Cidr: /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])\$/, - base64: /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?\$/, - base64url: /^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?\$/, - nanoid: /^[a-zA-Z0-9_-]{21}\$/, - jwt: /^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*\$/ -}; -function parseStringDef(def, refs) { - const res = { - type: "string" - }; - if (def.checks) { - for (const check2 of def.checks) { - switch (check2.kind) { - case "min": - res.minLength = typeof res.minLength === "number" ? Math.max(res.minLength, check2.value) : check2.value; - break; - case "max": - res.maxLength = typeof res.maxLength === "number" ? Math.min(res.maxLength, check2.value) : check2.value; - break; - case "email": - switch (refs.emailStrategy) { - case "format:email": - addFormat(res, "email", check2.message, refs); - break; - case "format:idn-email": - addFormat(res, "idn-email", check2.message, refs); - break; - case "pattern:zod": - addPattern(res, zodPatterns.email, check2.message, refs); - break; - } - break; - case "url": - addFormat(res, "uri", check2.message, refs); - break; - case "uuid": - addFormat(res, "uuid", check2.message, refs); - break; - case "regex": - addPattern(res, check2.regex, check2.message, refs); - break; - case "cuid": - addPattern(res, zodPatterns.cuid, check2.message, refs); - break; - case "cuid2": - addPattern(res, zodPatterns.cuid2, check2.message, refs); - break; - case "startsWith": - addPattern(res, RegExp(\`^\${escapeLiteralCheckValue(check2.value, refs)}\`), check2.message, refs); - break; - case "endsWith": - addPattern(res, RegExp(\`\${escapeLiteralCheckValue(check2.value, refs)}\$\`), check2.message, refs); - break; - case "datetime": - addFormat(res, "date-time", check2.message, refs); - break; - case "date": - addFormat(res, "date", check2.message, refs); - break; - case "time": - addFormat(res, "time", check2.message, refs); - break; - case "duration": - addFormat(res, "duration", check2.message, refs); - break; - case "length": - res.minLength = typeof res.minLength === "number" ? Math.max(res.minLength, check2.value) : check2.value; - res.maxLength = typeof res.maxLength === "number" ? Math.min(res.maxLength, check2.value) : check2.value; - break; - case "includes": { - addPattern(res, RegExp(escapeLiteralCheckValue(check2.value, refs)), check2.message, refs); - break; - } - case "ip": { - if (check2.version !== "v6") { - addFormat(res, "ipv4", check2.message, refs); - } - if (check2.version !== "v4") { - addFormat(res, "ipv6", check2.message, refs); - } - break; - } - case "base64url": - addPattern(res, zodPatterns.base64url, check2.message, refs); - break; - case "jwt": - addPattern(res, zodPatterns.jwt, check2.message, refs); - break; - case "cidr": { - if (check2.version !== "v6") { - addPattern(res, zodPatterns.ipv4Cidr, check2.message, refs); - } - if (check2.version !== "v4") { - addPattern(res, zodPatterns.ipv6Cidr, check2.message, refs); - } - break; - } - case "emoji": - addPattern(res, zodPatterns.emoji(), check2.message, refs); - break; - case "ulid": { - addPattern(res, zodPatterns.ulid, check2.message, refs); - break; - } - case "base64": { - switch (refs.base64Strategy) { - case "format:binary": { - addFormat(res, "binary", check2.message, refs); - break; - } - case "contentEncoding:base64": { - res.contentEncoding = "base64"; - break; - } - case "pattern:zod": { - addPattern(res, zodPatterns.base64, check2.message, refs); - break; - } - } - break; - } - case "nanoid": { - addPattern(res, zodPatterns.nanoid, check2.message, refs); - } - case "toLowerCase": - case "toUpperCase": - case "trim": - break; - default: - /* @__PURE__ */ ((_) => { - })(check2); - } - } - } - return res; -} -__name(parseStringDef, "parseStringDef"); -function escapeLiteralCheckValue(literal2, refs) { - return refs.patternStrategy === "escape" ? escapeNonAlphaNumeric(literal2) : literal2; -} -__name(escapeLiteralCheckValue, "escapeLiteralCheckValue"); -var ALPHA_NUMERIC = new Set("ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz0123456789"); -function escapeNonAlphaNumeric(source) { - let result = ""; - for (let i = 0; i < source.length; i++) { - if (!ALPHA_NUMERIC.has(source[i])) { - result += "\\\\"; - } - result += source[i]; - } - return result; -} -__name(escapeNonAlphaNumeric, "escapeNonAlphaNumeric"); -function addFormat(schema, value, message, refs) { - var _a17; - if (schema.format || ((_a17 = schema.anyOf) == null ? void 0 : _a17.some((x) => x.format))) { - if (!schema.anyOf) { - schema.anyOf = []; - } - if (schema.format) { - schema.anyOf.push({ - format: schema.format - }); - delete schema.format; - } - schema.anyOf.push({ - format: value, - ...message && refs.errorMessages && { - errorMessage: { - format: message - } - } - }); - } else { - schema.format = value; - } -} -__name(addFormat, "addFormat"); -function addPattern(schema, regex, message, refs) { - var _a17; - if (schema.pattern || ((_a17 = schema.allOf) == null ? void 0 : _a17.some((x) => x.pattern))) { - if (!schema.allOf) { - schema.allOf = []; - } - if (schema.pattern) { - schema.allOf.push({ - pattern: schema.pattern - }); - delete schema.pattern; - } - schema.allOf.push({ - pattern: stringifyRegExpWithFlags(regex, refs), - ...message && refs.errorMessages && { - errorMessage: { - pattern: message - } - } - }); - } else { - schema.pattern = stringifyRegExpWithFlags(regex, refs); - } -} -__name(addPattern, "addPattern"); -function stringifyRegExpWithFlags(regex, refs) { - var _a17; - if (!refs.applyRegexFlags || !regex.flags) { - return regex.source; - } - const flags = { - i: regex.flags.includes("i"), - // Case-insensitive - m: regex.flags.includes("m"), - // \`^\` and \`\$\` matches adjacent to newline characters - s: regex.flags.includes("s") - }; - const source = flags.i ? regex.source.toLowerCase() : regex.source; - let pattern = ""; - let isEscaped = false; - let inCharGroup = false; - let inCharRange = false; - for (let i = 0; i < source.length; i++) { - if (isEscaped) { - pattern += source[i]; - isEscaped = false; - continue; - } - if (flags.i) { - if (inCharGroup) { - if (source[i].match(/[a-z]/)) { - if (inCharRange) { - pattern += source[i]; - pattern += \`\${source[i - 2]}-\${source[i]}\`.toUpperCase(); - inCharRange = false; - } else if (source[i + 1] === "-" && ((_a17 = source[i + 2]) == null ? void 0 : _a17.match(/[a-z]/))) { - pattern += source[i]; - inCharRange = true; - } else { - pattern += \`\${source[i]}\${source[i].toUpperCase()}\`; - } - continue; - } - } else if (source[i].match(/[a-z]/)) { - pattern += \`[\${source[i]}\${source[i].toUpperCase()}]\`; - continue; - } - } - if (flags.m) { - if (source[i] === "^") { - pattern += \`(^|(?<=[\\r -]))\`; - continue; - } else if (source[i] === "\$") { - pattern += \`(\$|(?=[\\r -]))\`; - continue; - } - } - if (flags.s && source[i] === ".") { - pattern += inCharGroup ? \`\${source[i]}\\r -\` : \`[\${source[i]}\\r -]\`; - continue; - } - pattern += source[i]; - if (source[i] === "\\\\") { - isEscaped = true; - } else if (inCharGroup && source[i] === "]") { - inCharGroup = false; - } else if (!inCharGroup && source[i] === "[") { - inCharGroup = true; - } - } - try { - new RegExp(pattern); - } catch (e) { - console.warn(\`Could not convert regex pattern at \${refs.currentPath.join("/")} to a flag-independent form! Falling back to the flag-ignorant source\`); - return regex.source; - } - return pattern; -} -__name(stringifyRegExpWithFlags, "stringifyRegExpWithFlags"); -function parseRecordDef(def, refs) { - var _a17, _b8, _c, _d, _e, _f; - const schema = { - type: "object", - additionalProperties: (_a17 = parseDef(def.valueType._def, { - ...refs, - currentPath: [ - ...refs.currentPath, - "additionalProperties" - ] - })) != null ? _a17 : refs.allowedAdditionalProperties - }; - if (((_b8 = def.keyType) == null ? void 0 : _b8._def.typeName) === ZodFirstPartyTypeKind2.ZodString && ((_c = def.keyType._def.checks) == null ? void 0 : _c.length)) { - const { type, ...keyType } = parseStringDef(def.keyType._def, refs); - return { - ...schema, - propertyNames: keyType - }; - } else if (((_d = def.keyType) == null ? void 0 : _d._def.typeName) === ZodFirstPartyTypeKind2.ZodEnum) { - return { - ...schema, - propertyNames: { - enum: def.keyType._def.values - } - }; - } else if (((_e = def.keyType) == null ? void 0 : _e._def.typeName) === ZodFirstPartyTypeKind2.ZodBranded && def.keyType._def.type._def.typeName === ZodFirstPartyTypeKind2.ZodString && ((_f = def.keyType._def.type._def.checks) == null ? void 0 : _f.length)) { - const { type, ...keyType } = parseBrandedDef(def.keyType._def, refs); - return { - ...schema, - propertyNames: keyType - }; - } - return schema; -} -__name(parseRecordDef, "parseRecordDef"); -function parseMapDef(def, refs) { - if (refs.mapStrategy === "record") { - return parseRecordDef(def, refs); - } - const keys = parseDef(def.keyType._def, { - ...refs, - currentPath: [ - ...refs.currentPath, - "items", - "items", - "0" - ] - }) || parseAnyDef(); - const values = parseDef(def.valueType._def, { - ...refs, - currentPath: [ - ...refs.currentPath, - "items", - "items", - "1" - ] - }) || parseAnyDef(); - return { - type: "array", - maxItems: 125, - items: { - type: "array", - items: [ - keys, - values - ], - minItems: 2, - maxItems: 2 - } - }; -} -__name(parseMapDef, "parseMapDef"); -function parseNativeEnumDef(def) { - const object3 = def.values; - const actualKeys = Object.keys(def.values).filter((key) => { - return typeof object3[object3[key]] !== "number"; - }); - const actualValues = actualKeys.map((key) => object3[key]); - const parsedTypes = Array.from(new Set(actualValues.map((values) => typeof values))); - return { - type: parsedTypes.length === 1 ? parsedTypes[0] === "string" ? "string" : "number" : [ - "string", - "number" - ], - enum: actualValues - }; -} -__name(parseNativeEnumDef, "parseNativeEnumDef"); -function parseNeverDef() { - return { - not: parseAnyDef() - }; -} -__name(parseNeverDef, "parseNeverDef"); -function parseNullDef() { - return { - type: "null" - }; -} -__name(parseNullDef, "parseNullDef"); -var primitiveMappings = { - ZodString: "string", - ZodNumber: "number", - ZodBigInt: "integer", - ZodBoolean: "boolean", - ZodNull: "null" -}; -function parseUnionDef(def, refs) { - const options = def.options instanceof Map ? Array.from(def.options.values()) : def.options; - if (options.every((x) => x._def.typeName in primitiveMappings && (!x._def.checks || !x._def.checks.length))) { - const types = options.reduce((types2, x) => { - const type = primitiveMappings[x._def.typeName]; - return type && !types2.includes(type) ? [ - ...types2, - type - ] : types2; - }, []); - return { - type: types.length > 1 ? types : types[0] - }; - } else if (options.every((x) => x._def.typeName === "ZodLiteral" && !x.description)) { - const types = options.reduce((acc, x) => { - const type = typeof x._def.value; - switch (type) { - case "string": - case "number": - case "boolean": - return [ - ...acc, - type - ]; - case "bigint": - return [ - ...acc, - "integer" - ]; - case "object": - if (x._def.value === null) return [ - ...acc, - "null" - ]; - case "symbol": - case "undefined": - case "function": - default: - return acc; - } - }, []); - if (types.length === options.length) { - const uniqueTypes = types.filter((x, i, a) => a.indexOf(x) === i); - return { - type: uniqueTypes.length > 1 ? uniqueTypes : uniqueTypes[0], - enum: options.reduce((acc, x) => { - return acc.includes(x._def.value) ? acc : [ - ...acc, - x._def.value - ]; - }, []) - }; - } - } else if (options.every((x) => x._def.typeName === "ZodEnum")) { - return { - type: "string", - enum: options.reduce((acc, x) => [ - ...acc, - ...x._def.values.filter((x2) => !acc.includes(x2)) - ], []) - }; - } - return asAnyOf(def, refs); -} -__name(parseUnionDef, "parseUnionDef"); -var asAnyOf = /* @__PURE__ */ __name((def, refs) => { - const anyOf = (def.options instanceof Map ? Array.from(def.options.values()) : def.options).map((x, i) => parseDef(x._def, { - ...refs, - currentPath: [ - ...refs.currentPath, - "anyOf", - \`\${i}\` - ] - })).filter((x) => !!x && (!refs.strictUnions || typeof x === "object" && Object.keys(x).length > 0)); - return anyOf.length ? { - anyOf - } : void 0; -}, "asAnyOf"); -function parseNullableDef(def, refs) { - if ([ - "ZodString", - "ZodNumber", - "ZodBigInt", - "ZodBoolean", - "ZodNull" - ].includes(def.innerType._def.typeName) && (!def.innerType._def.checks || !def.innerType._def.checks.length)) { - return { - type: [ - primitiveMappings[def.innerType._def.typeName], - "null" - ] - }; - } - const base = parseDef(def.innerType._def, { - ...refs, - currentPath: [ - ...refs.currentPath, - "anyOf", - "0" - ] - }); - return base && { - anyOf: [ - base, - { - type: "null" - } - ] - }; -} -__name(parseNullableDef, "parseNullableDef"); -function parseNumberDef(def) { - const res = { - type: "number" - }; - if (!def.checks) return res; - for (const check2 of def.checks) { - switch (check2.kind) { - case "int": - res.type = "integer"; - break; - case "min": - if (check2.inclusive) { - res.minimum = check2.value; - } else { - res.exclusiveMinimum = check2.value; - } - break; - case "max": - if (check2.inclusive) { - res.maximum = check2.value; - } else { - res.exclusiveMaximum = check2.value; - } - break; - case "multipleOf": - res.multipleOf = check2.value; - break; - } - } - return res; -} -__name(parseNumberDef, "parseNumberDef"); -function parseObjectDef(def, refs) { - const result = { - type: "object", - properties: {} - }; - const required2 = []; - const shape = def.shape(); - for (const propName in shape) { - let propDef = shape[propName]; - if (propDef === void 0 || propDef._def === void 0) { - continue; - } - const propOptional = safeIsOptional(propDef); - const parsedDef = parseDef(propDef._def, { - ...refs, - currentPath: [ - ...refs.currentPath, - "properties", - propName - ], - propertyPath: [ - ...refs.currentPath, - "properties", - propName - ] - }); - if (parsedDef === void 0) { - continue; - } - result.properties[propName] = parsedDef; - if (!propOptional) { - required2.push(propName); - } - } - if (required2.length) { - result.required = required2; - } - const additionalProperties = decideAdditionalProperties(def, refs); - if (additionalProperties !== void 0) { - result.additionalProperties = additionalProperties; - } - return result; -} -__name(parseObjectDef, "parseObjectDef"); -function decideAdditionalProperties(def, refs) { - if (def.catchall._def.typeName !== "ZodNever") { - return parseDef(def.catchall._def, { - ...refs, - currentPath: [ - ...refs.currentPath, - "additionalProperties" - ] - }); - } - switch (def.unknownKeys) { - case "passthrough": - return refs.allowedAdditionalProperties; - case "strict": - return refs.rejectedAdditionalProperties; - case "strip": - return refs.removeAdditionalStrategy === "strict" ? refs.allowedAdditionalProperties : refs.rejectedAdditionalProperties; - } -} -__name(decideAdditionalProperties, "decideAdditionalProperties"); -function safeIsOptional(schema) { - try { - return schema.isOptional(); - } catch (e) { - return true; - } -} -__name(safeIsOptional, "safeIsOptional"); -var parseOptionalDef = /* @__PURE__ */ __name((def, refs) => { - var _a17; - if (refs.currentPath.toString() === ((_a17 = refs.propertyPath) == null ? void 0 : _a17.toString())) { - return parseDef(def.innerType._def, refs); - } - const innerSchema = parseDef(def.innerType._def, { - ...refs, - currentPath: [ - ...refs.currentPath, - "anyOf", - "1" - ] - }); - return innerSchema ? { - anyOf: [ - { - not: parseAnyDef() - }, - innerSchema - ] - } : parseAnyDef(); -}, "parseOptionalDef"); -var parsePipelineDef = /* @__PURE__ */ __name((def, refs) => { - if (refs.pipeStrategy === "input") { - return parseDef(def.in._def, refs); - } else if (refs.pipeStrategy === "output") { - return parseDef(def.out._def, refs); - } - const a = parseDef(def.in._def, { - ...refs, - currentPath: [ - ...refs.currentPath, - "allOf", - "0" - ] - }); - const b = parseDef(def.out._def, { - ...refs, - currentPath: [ - ...refs.currentPath, - "allOf", - a ? "1" : "0" - ] - }); - return { - allOf: [ - a, - b - ].filter((x) => x !== void 0) - }; -}, "parsePipelineDef"); -function parsePromiseDef(def, refs) { - return parseDef(def.type._def, refs); -} -__name(parsePromiseDef, "parsePromiseDef"); -function parseSetDef(def, refs) { - const items = parseDef(def.valueType._def, { - ...refs, - currentPath: [ - ...refs.currentPath, - "items" - ] - }); - const schema = { - type: "array", - uniqueItems: true, - items - }; - if (def.minSize) { - schema.minItems = def.minSize.value; - } - if (def.maxSize) { - schema.maxItems = def.maxSize.value; - } - return schema; -} -__name(parseSetDef, "parseSetDef"); -function parseTupleDef(def, refs) { - if (def.rest) { - return { - type: "array", - minItems: def.items.length, - items: def.items.map((x, i) => parseDef(x._def, { - ...refs, - currentPath: [ - ...refs.currentPath, - "items", - \`\${i}\` - ] - })).reduce((acc, x) => x === void 0 ? acc : [ - ...acc, - x - ], []), - additionalItems: parseDef(def.rest._def, { - ...refs, - currentPath: [ - ...refs.currentPath, - "additionalItems" - ] - }) - }; - } else { - return { - type: "array", - minItems: def.items.length, - maxItems: def.items.length, - items: def.items.map((x, i) => parseDef(x._def, { - ...refs, - currentPath: [ - ...refs.currentPath, - "items", - \`\${i}\` - ] - })).reduce((acc, x) => x === void 0 ? acc : [ - ...acc, - x - ], []) - }; - } -} -__name(parseTupleDef, "parseTupleDef"); -function parseUndefinedDef() { - return { - not: parseAnyDef() - }; -} -__name(parseUndefinedDef, "parseUndefinedDef"); -function parseUnknownDef() { - return parseAnyDef(); -} -__name(parseUnknownDef, "parseUnknownDef"); -var parseReadonlyDef = /* @__PURE__ */ __name((def, refs) => { - return parseDef(def.innerType._def, refs); -}, "parseReadonlyDef"); -var selectParser = /* @__PURE__ */ __name((def, typeName, refs) => { - switch (typeName) { - case ZodFirstPartyTypeKind2.ZodString: - return parseStringDef(def, refs); - case ZodFirstPartyTypeKind2.ZodNumber: - return parseNumberDef(def); - case ZodFirstPartyTypeKind2.ZodObject: - return parseObjectDef(def, refs); - case ZodFirstPartyTypeKind2.ZodBigInt: - return parseBigintDef(def); - case ZodFirstPartyTypeKind2.ZodBoolean: - return parseBooleanDef(); - case ZodFirstPartyTypeKind2.ZodDate: - return parseDateDef(def, refs); - case ZodFirstPartyTypeKind2.ZodUndefined: - return parseUndefinedDef(); - case ZodFirstPartyTypeKind2.ZodNull: - return parseNullDef(); - case ZodFirstPartyTypeKind2.ZodArray: - return parseArrayDef(def, refs); - case ZodFirstPartyTypeKind2.ZodUnion: - case ZodFirstPartyTypeKind2.ZodDiscriminatedUnion: - return parseUnionDef(def, refs); - case ZodFirstPartyTypeKind2.ZodIntersection: - return parseIntersectionDef(def, refs); - case ZodFirstPartyTypeKind2.ZodTuple: - return parseTupleDef(def, refs); - case ZodFirstPartyTypeKind2.ZodRecord: - return parseRecordDef(def, refs); - case ZodFirstPartyTypeKind2.ZodLiteral: - return parseLiteralDef(def); - case ZodFirstPartyTypeKind2.ZodEnum: - return parseEnumDef(def); - case ZodFirstPartyTypeKind2.ZodNativeEnum: - return parseNativeEnumDef(def); - case ZodFirstPartyTypeKind2.ZodNullable: - return parseNullableDef(def, refs); - case ZodFirstPartyTypeKind2.ZodOptional: - return parseOptionalDef(def, refs); - case ZodFirstPartyTypeKind2.ZodMap: - return parseMapDef(def, refs); - case ZodFirstPartyTypeKind2.ZodSet: - return parseSetDef(def, refs); - case ZodFirstPartyTypeKind2.ZodLazy: - return () => def.getter()._def; - case ZodFirstPartyTypeKind2.ZodPromise: - return parsePromiseDef(def, refs); - case ZodFirstPartyTypeKind2.ZodNaN: - case ZodFirstPartyTypeKind2.ZodNever: - return parseNeverDef(); - case ZodFirstPartyTypeKind2.ZodEffects: - return parseEffectsDef(def, refs); - case ZodFirstPartyTypeKind2.ZodAny: - return parseAnyDef(); - case ZodFirstPartyTypeKind2.ZodUnknown: - return parseUnknownDef(); - case ZodFirstPartyTypeKind2.ZodDefault: - return parseDefaultDef(def, refs); - case ZodFirstPartyTypeKind2.ZodBranded: - return parseBrandedDef(def, refs); - case ZodFirstPartyTypeKind2.ZodReadonly: - return parseReadonlyDef(def, refs); - case ZodFirstPartyTypeKind2.ZodCatch: - return parseCatchDef(def, refs); - case ZodFirstPartyTypeKind2.ZodPipeline: - return parsePipelineDef(def, refs); - case ZodFirstPartyTypeKind2.ZodFunction: - case ZodFirstPartyTypeKind2.ZodVoid: - case ZodFirstPartyTypeKind2.ZodSymbol: - return void 0; - default: - return /* @__PURE__ */ ((_) => void 0)(typeName); - } -}, "selectParser"); -function parseDef(def, refs, forceResolution = false) { - var _a17; - const seenItem = refs.seen.get(def); - if (refs.override) { - const overrideResult = (_a17 = refs.override) == null ? void 0 : _a17.call(refs, def, refs, seenItem, forceResolution); - if (overrideResult !== ignoreOverride) { - return overrideResult; - } - } - if (seenItem && !forceResolution) { - const seenSchema = get\$ref(seenItem, refs); - if (seenSchema !== void 0) { - return seenSchema; - } - } - const newItem = { - def, - path: refs.currentPath, - jsonSchema: void 0 - }; - refs.seen.set(def, newItem); - const jsonSchemaOrGetter = selectParser(def, def.typeName, refs); - const jsonSchema2 = typeof jsonSchemaOrGetter === "function" ? parseDef(jsonSchemaOrGetter(), refs) : jsonSchemaOrGetter; - if (jsonSchema2) { - addMeta(def, refs, jsonSchema2); - } - if (refs.postProcess) { - const postProcessResult = refs.postProcess(jsonSchema2, def, refs); - newItem.jsonSchema = jsonSchema2; - return postProcessResult; - } - newItem.jsonSchema = jsonSchema2; - return jsonSchema2; -} -__name(parseDef, "parseDef"); -var get\$ref = /* @__PURE__ */ __name((item, refs) => { - switch (refs.\$refStrategy) { - case "root": - return { - \$ref: item.path.join("/") - }; - case "relative": - return { - \$ref: getRelativePath(refs.currentPath, item.path) - }; - case "none": - case "seen": { - if (item.path.length < refs.currentPath.length && item.path.every((value, index) => refs.currentPath[index] === value)) { - console.warn(\`Recursive reference detected at \${refs.currentPath.join("/")}! Defaulting to any\`); - return parseAnyDef(); - } - return refs.\$refStrategy === "seen" ? parseAnyDef() : void 0; - } - } -}, "get\$ref"); -var addMeta = /* @__PURE__ */ __name((def, refs, jsonSchema2) => { - if (def.description) { - jsonSchema2.description = def.description; - } - return jsonSchema2; -}, "addMeta"); -var getRefs = /* @__PURE__ */ __name((options) => { - const _options = getDefaultOptions(options); - const currentPath = _options.name !== void 0 ? [ - ..._options.basePath, - _options.definitionPath, - _options.name - ] : _options.basePath; - return { - ..._options, - currentPath, - propertyPath: void 0, - seen: new Map(Object.entries(_options.definitions).map(([name17, def]) => [ - def._def, - { - def: def._def, - path: [ - ..._options.basePath, - _options.definitionPath, - name17 - ], - // Resolution of references will be forced even though seen, so it's ok that the schema is undefined here for now. - jsonSchema: void 0 - } - ])) - }; -}, "getRefs"); -var zodToJsonSchema = /* @__PURE__ */ __name((schema, options) => { - var _a17; - const refs = getRefs(options); - let definitions = typeof options === "object" && options.definitions ? Object.entries(options.definitions).reduce((acc, [name24, schema2]) => { - var _a24; - return { - ...acc, - [name24]: (_a24 = parseDef(schema2._def, { - ...refs, - currentPath: [ - ...refs.basePath, - refs.definitionPath, - name24 - ] - }, true)) != null ? _a24 : parseAnyDef() - }; - }, {}) : void 0; - const name17 = typeof options === "string" ? options : (options == null ? void 0 : options.nameStrategy) === "title" ? void 0 : options == null ? void 0 : options.name; - const main = (_a17 = parseDef(schema._def, name17 === void 0 ? refs : { - ...refs, - currentPath: [ - ...refs.basePath, - refs.definitionPath, - name17 - ] - }, false)) != null ? _a17 : parseAnyDef(); - const title = typeof options === "object" && options.name !== void 0 && options.nameStrategy === "title" ? options.name : void 0; - if (title !== void 0) { - main.title = title; - } - const combined = name17 === void 0 ? definitions ? { - ...main, - [refs.definitionPath]: definitions - } : main : { - \$ref: [ - ...refs.\$refStrategy === "relative" ? [] : refs.basePath, - refs.definitionPath, - name17 - ].join("/"), - [refs.definitionPath]: { - ...definitions, - [name17]: main - } - }; - combined.\$schema = "http://json-schema.org/draft-07/schema#"; - return combined; -}, "zodToJsonSchema"); -var zod_to_json_schema_default = zodToJsonSchema; -function zod3Schema(zodSchema2, options) { - var _a17; - const useReferences = (_a17 = options == null ? void 0 : options.useReferences) != null ? _a17 : false; - return jsonSchema( - // defer json schema creation to avoid unnecessary computation when only validation is needed - () => zod_to_json_schema_default(zodSchema2, { - \$refStrategy: useReferences ? "root" : "none" - }), - { - validate: /* @__PURE__ */ __name(async (value) => { - const result = await zodSchema2.safeParseAsync(value); - return result.success ? { - success: true, - value: result.data - } : { - success: false, - error: result.error - }; - }, "validate") - } - ); -} -__name(zod3Schema, "zod3Schema"); -function zod4Schema(zodSchema2, options) { - var _a17; - const useReferences = (_a17 = options == null ? void 0 : options.useReferences) != null ? _a17 : false; - return jsonSchema( - // defer json schema creation to avoid unnecessary computation when only validation is needed - () => toJSONSchema(zodSchema2, { - target: "draft-7", - io: "output", - reused: useReferences ? "ref" : "inline" - }), - { - validate: /* @__PURE__ */ __name(async (value) => { - const result = await safeParseAsync2(zodSchema2, value); - return result.success ? { - success: true, - value: result.data - } : { - success: false, - error: result.error - }; - }, "validate") - } - ); -} -__name(zod4Schema, "zod4Schema"); -function isZod4Schema(zodSchema2) { - return "_zod" in zodSchema2; -} -__name(isZod4Schema, "isZod4Schema"); -function zodSchema(zodSchema2, options) { - if (isZod4Schema(zodSchema2)) { - return zod4Schema(zodSchema2, options); - } else { - return zod3Schema(zodSchema2, options); - } -} -__name(zodSchema, "zodSchema"); -var schemaSymbol = Symbol.for("vercel.ai.schema"); -function jsonSchema(jsonSchema2, { validate } = {}) { - return { - [schemaSymbol]: true, - _type: void 0, - // should never be used directly - [validatorSymbol]: true, - get jsonSchema() { - if (typeof jsonSchema2 === "function") { - jsonSchema2 = jsonSchema2(); - } - return jsonSchema2; - }, - validate - }; -} -__name(jsonSchema, "jsonSchema"); -function isSchema(value) { - return typeof value === "object" && value !== null && schemaSymbol in value && value[schemaSymbol] === true && "jsonSchema" in value && "validate" in value; -} -__name(isSchema, "isSchema"); -function asSchema(schema) { - return schema == null ? jsonSchema({ - properties: {}, - additionalProperties: false - }) : isSchema(schema) ? schema : typeof schema === "function" ? schema() : zodSchema(schema); -} -__name(asSchema, "asSchema"); -var { btoa: btoa2, atob: atob2 } = globalThis; -function convertBase64ToUint8Array(base64String) { - const base64Url = base64String.replace(/-/g, "+").replace(/_/g, "/"); - const latin1string = atob2(base64Url); - return Uint8Array.from(latin1string, (byte) => byte.codePointAt(0)); -} -__name(convertBase64ToUint8Array, "convertBase64ToUint8Array"); -function convertUint8ArrayToBase64(array2) { - let latin1string = ""; - for (let i = 0; i < array2.length; i++) { - latin1string += String.fromCodePoint(array2[i]); - } - return btoa2(latin1string); -} -__name(convertUint8ArrayToBase64, "convertUint8ArrayToBase64"); -function withoutTrailingSlash(url2) { - return url2 == null ? void 0 : url2.replace(/\\/\$/, ""); -} -__name(withoutTrailingSlash, "withoutTrailingSlash"); -function isAsyncIterable(obj) { - return obj != null && typeof obj[Symbol.asyncIterator] === "function"; -} -__name(isAsyncIterable, "isAsyncIterable"); -async function* executeTool({ execute, input, options }) { - const result = execute(input, options); - if (isAsyncIterable(result)) { - let lastOutput; - for await (const output of result) { - lastOutput = output; - yield { - type: "preliminary", - output - }; - } - yield { - type: "final", - output: lastOutput - }; - } else { - yield { - type: "final", - output: await result - }; - } -} -__name(executeTool, "executeTool"); - -// ../../node_modules/.pnpm/@ai-sdk+gateway@2.0.0_zod@4.1.11/node_modules/@ai-sdk/gateway/dist/index.mjs -var import_oidc = __toESM(require_index_browser(), 1); -var import_oidc2 = __toESM(require_index_browser(), 1); -var marker15 = "vercel.ai.gateway.error"; -var symbol16 = Symbol.for(marker15); -var _a15; -var _b; -var GatewayError = class _GatewayError extends (_b = Error, _a15 = symbol16, _b) { - static { - __name(this, "_GatewayError"); - } - constructor({ message, statusCode = 500, cause }) { - super(message); - this[_a15] = true; - this.statusCode = statusCode; - this.cause = cause; - } - /** - * Checks if the given error is a Gateway Error. - * @param {unknown} error - The error to check. - * @returns {boolean} True if the error is a Gateway Error, false otherwise. - */ - static isInstance(error45) { - return _GatewayError.hasMarker(error45); - } - static hasMarker(error45) { - return typeof error45 === "object" && error45 !== null && symbol16 in error45 && error45[symbol16] === true; - } -}; -var name14 = "GatewayAuthenticationError"; -var marker22 = \`vercel.ai.gateway.error.\${name14}\`; -var symbol22 = Symbol.for(marker22); -var _a22; -var _b2; -var GatewayAuthenticationError = class _GatewayAuthenticationError extends (_b2 = GatewayError, _a22 = symbol22, _b2) { - static { - __name(this, "_GatewayAuthenticationError"); - } - constructor({ message = "Authentication failed", statusCode = 401, cause } = {}) { - super({ - message, - statusCode, - cause - }); - this[_a22] = true; - this.name = name14; - this.type = "authentication_error"; - } - static isInstance(error45) { - return GatewayError.hasMarker(error45) && symbol22 in error45; - } - /** - * Creates a contextual error message when authentication fails - */ - static createContextualError({ apiKeyProvided, oidcTokenProvided, message = "Authentication failed", statusCode = 401, cause }) { - let contextualMessage; - if (apiKeyProvided) { - contextualMessage = \`AI Gateway authentication failed: Invalid API key. - -Create a new API key: https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fai%2Fapi-keys - -Provide via 'apiKey' option or 'AI_GATEWAY_API_KEY' environment variable.\`; - } else if (oidcTokenProvided) { - contextualMessage = \`AI Gateway authentication failed: Invalid OIDC token. - -Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the token. - -Alternatively, use an API key: https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fai%2Fapi-keys\`; - } else { - contextualMessage = \`AI Gateway authentication failed: No authentication provided. - -Option 1 - API key: -Create an API key: https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fai%2Fapi-keys -Provide via 'apiKey' option or 'AI_GATEWAY_API_KEY' environment variable. - -Option 2 - OIDC token: -Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the token.\`; - } - return new _GatewayAuthenticationError({ - message: contextualMessage, - statusCode, - cause - }); - } -}; -var name22 = "GatewayInvalidRequestError"; -var marker32 = \`vercel.ai.gateway.error.\${name22}\`; -var symbol32 = Symbol.for(marker32); -var _a32; -var _b3; -var GatewayInvalidRequestError = class extends (_b3 = GatewayError, _a32 = symbol32, _b3) { - static { - __name(this, "GatewayInvalidRequestError"); - } - constructor({ message = "Invalid request", statusCode = 400, cause } = {}) { - super({ - message, - statusCode, - cause - }); - this[_a32] = true; - this.name = name22; - this.type = "invalid_request_error"; - } - static isInstance(error45) { - return GatewayError.hasMarker(error45) && symbol32 in error45; - } -}; -var name32 = "GatewayRateLimitError"; -var marker42 = \`vercel.ai.gateway.error.\${name32}\`; -var symbol42 = Symbol.for(marker42); -var _a42; -var _b4; -var GatewayRateLimitError = class extends (_b4 = GatewayError, _a42 = symbol42, _b4) { - static { - __name(this, "GatewayRateLimitError"); - } - constructor({ message = "Rate limit exceeded", statusCode = 429, cause } = {}) { - super({ - message, - statusCode, - cause - }); - this[_a42] = true; - this.name = name32; - this.type = "rate_limit_exceeded"; - } - static isInstance(error45) { - return GatewayError.hasMarker(error45) && symbol42 in error45; - } -}; -var name42 = "GatewayModelNotFoundError"; -var marker52 = \`vercel.ai.gateway.error.\${name42}\`; -var symbol52 = Symbol.for(marker52); -var modelNotFoundParamSchema = lazyValidator(() => zodSchema(external_exports.object({ - modelId: external_exports.string() -}))); -var _a52; -var _b5; -var GatewayModelNotFoundError = class extends (_b5 = GatewayError, _a52 = symbol52, _b5) { - static { - __name(this, "GatewayModelNotFoundError"); - } - constructor({ message = "Model not found", statusCode = 404, modelId, cause } = {}) { - super({ - message, - statusCode, - cause - }); - this[_a52] = true; - this.name = name42; - this.type = "model_not_found"; - this.modelId = modelId; - } - static isInstance(error45) { - return GatewayError.hasMarker(error45) && symbol52 in error45; - } -}; -var name52 = "GatewayInternalServerError"; -var marker62 = \`vercel.ai.gateway.error.\${name52}\`; -var symbol62 = Symbol.for(marker62); -var _a62; -var _b6; -var GatewayInternalServerError = class extends (_b6 = GatewayError, _a62 = symbol62, _b6) { - static { - __name(this, "GatewayInternalServerError"); - } - constructor({ message = "Internal server error", statusCode = 500, cause } = {}) { - super({ - message, - statusCode, - cause - }); - this[_a62] = true; - this.name = name52; - this.type = "internal_server_error"; - } - static isInstance(error45) { - return GatewayError.hasMarker(error45) && symbol62 in error45; - } -}; -var name62 = "GatewayResponseError"; -var marker72 = \`vercel.ai.gateway.error.\${name62}\`; -var symbol72 = Symbol.for(marker72); -var _a72; -var _b7; -var GatewayResponseError = class extends (_b7 = GatewayError, _a72 = symbol72, _b7) { - static { - __name(this, "GatewayResponseError"); - } - constructor({ message = "Invalid response from Gateway", statusCode = 502, response, validationError, cause } = {}) { - super({ - message, - statusCode, - cause - }); - this[_a72] = true; - this.name = name62; - this.type = "response_error"; - this.response = response; - this.validationError = validationError; - } - static isInstance(error45) { - return GatewayError.hasMarker(error45) && symbol72 in error45; - } -}; -async function createGatewayErrorFromResponse({ response, statusCode, defaultMessage = "Gateway request failed", cause, authMethod }) { - const parseResult = await safeValidateTypes({ - value: response, - schema: gatewayErrorResponseSchema - }); - if (!parseResult.success) { - return new GatewayResponseError({ - message: \`Invalid error response format: \${defaultMessage}\`, - statusCode, - response, - validationError: parseResult.error, - cause - }); - } - const validatedResponse = parseResult.value; - const errorType = validatedResponse.error.type; - const message = validatedResponse.error.message; - switch (errorType) { - case "authentication_error": - return GatewayAuthenticationError.createContextualError({ - apiKeyProvided: authMethod === "api-key", - oidcTokenProvided: authMethod === "oidc", - statusCode, - cause - }); - case "invalid_request_error": - return new GatewayInvalidRequestError({ - message, - statusCode, - cause - }); - case "rate_limit_exceeded": - return new GatewayRateLimitError({ - message, - statusCode, - cause - }); - case "model_not_found": { - const modelResult = await safeValidateTypes({ - value: validatedResponse.error.param, - schema: modelNotFoundParamSchema - }); - return new GatewayModelNotFoundError({ - message, - statusCode, - modelId: modelResult.success ? modelResult.value.modelId : void 0, - cause - }); - } - case "internal_server_error": - return new GatewayInternalServerError({ - message, - statusCode, - cause - }); - default: - return new GatewayInternalServerError({ - message, - statusCode, - cause - }); - } -} -__name(createGatewayErrorFromResponse, "createGatewayErrorFromResponse"); -var gatewayErrorResponseSchema = lazyValidator(() => zodSchema(external_exports.object({ - error: external_exports.object({ - message: external_exports.string(), - type: external_exports.string().nullish(), - param: external_exports.unknown().nullish(), - code: external_exports.union([ - external_exports.string(), - external_exports.number() - ]).nullish() - }) -}))); -function asGatewayError(error45, authMethod) { - var _a83; - if (GatewayError.isInstance(error45)) { - return error45; - } - if (APICallError.isInstance(error45)) { - return createGatewayErrorFromResponse({ - response: extractApiCallResponse(error45), - statusCode: (_a83 = error45.statusCode) != null ? _a83 : 500, - defaultMessage: "Gateway request failed", - cause: error45, - authMethod - }); - } - return createGatewayErrorFromResponse({ - response: {}, - statusCode: 500, - defaultMessage: error45 instanceof Error ? \`Gateway request failed: \${error45.message}\` : "Unknown Gateway error", - cause: error45, - authMethod - }); -} -__name(asGatewayError, "asGatewayError"); -function extractApiCallResponse(error45) { - if (error45.data !== void 0) { - return error45.data; - } - if (error45.responseBody != null) { - try { - return JSON.parse(error45.responseBody); - } catch (e) { - return error45.responseBody; - } - } - return {}; -} -__name(extractApiCallResponse, "extractApiCallResponse"); -var GATEWAY_AUTH_METHOD_HEADER = "ai-gateway-auth-method"; -async function parseAuthMethod(headers) { - const result = await safeValidateTypes({ - value: headers[GATEWAY_AUTH_METHOD_HEADER], - schema: gatewayAuthMethodSchema - }); - return result.success ? result.value : void 0; -} -__name(parseAuthMethod, "parseAuthMethod"); -var gatewayAuthMethodSchema = lazyValidator(() => zodSchema(external_exports.union([ - external_exports.literal("api-key"), - external_exports.literal("oidc") -]))); -var GatewayFetchMetadata = class { - static { - __name(this, "GatewayFetchMetadata"); - } - constructor(config2) { - this.config = config2; - } - async getAvailableModels() { - try { - const { value } = await getFromApi({ - url: \`\${this.config.baseURL}/config\`, - headers: await resolve(this.config.headers()), - successfulResponseHandler: createJsonResponseHandler(gatewayAvailableModelsResponseSchema), - failedResponseHandler: createJsonErrorResponseHandler({ - errorSchema: external_exports.any(), - errorToMessage: /* @__PURE__ */ __name((data) => data, "errorToMessage") - }), - fetch: this.config.fetch - }); - return value; - } catch (error45) { - throw await asGatewayError(error45); - } - } - async getCredits() { - try { - const baseUrl = new URL(this.config.baseURL); - const { value } = await getFromApi({ - url: \`\${baseUrl.origin}/v1/credits\`, - headers: await resolve(this.config.headers()), - successfulResponseHandler: createJsonResponseHandler(gatewayCreditsResponseSchema), - failedResponseHandler: createJsonErrorResponseHandler({ - errorSchema: external_exports.any(), - errorToMessage: /* @__PURE__ */ __name((data) => data, "errorToMessage") - }), - fetch: this.config.fetch - }); - return value; - } catch (error45) { - throw await asGatewayError(error45); - } - } -}; -var gatewayAvailableModelsResponseSchema = lazyValidator(() => zodSchema(external_exports.object({ - models: external_exports.array(external_exports.object({ - id: external_exports.string(), - name: external_exports.string(), - description: external_exports.string().nullish(), - pricing: external_exports.object({ - input: external_exports.string(), - output: external_exports.string(), - input_cache_read: external_exports.string().nullish(), - input_cache_write: external_exports.string().nullish() - }).transform(({ input, output, input_cache_read, input_cache_write }) => ({ - input, - output, - ...input_cache_read ? { - cachedInputTokens: input_cache_read - } : {}, - ...input_cache_write ? { - cacheCreationInputTokens: input_cache_write - } : {} - })).nullish(), - specification: external_exports.object({ - specificationVersion: external_exports.literal("v2"), - provider: external_exports.string(), - modelId: external_exports.string() - }), - modelType: external_exports.enum([ - "language", - "embedding", - "image" - ]).nullish() - })) -}))); -var gatewayCreditsResponseSchema = lazyValidator(() => zodSchema(external_exports.object({ - balance: external_exports.string(), - total_used: external_exports.string() -}).transform(({ balance, total_used }) => ({ - balance, - totalUsed: total_used -})))); -var GatewayLanguageModel = class { - static { - __name(this, "GatewayLanguageModel"); - } - constructor(modelId, config2) { - this.modelId = modelId; - this.config = config2; - this.specificationVersion = "v2"; - this.supportedUrls = { - "*/*": [ - /.*/ - ] - }; - } - get provider() { - return this.config.provider; - } - async getArgs(options) { - const { abortSignal: _abortSignal, ...optionsWithoutSignal } = options; - return { - args: this.maybeEncodeFileParts(optionsWithoutSignal), - warnings: [] - }; - } - async doGenerate(options) { - const { args, warnings } = await this.getArgs(options); - const { abortSignal } = options; - const resolvedHeaders = await resolve(this.config.headers()); - try { - const { responseHeaders, value: responseBody, rawValue: rawResponse } = await postJsonToApi({ - url: this.getUrl(), - headers: combineHeaders(resolvedHeaders, options.headers, this.getModelConfigHeaders(this.modelId, false), await resolve(this.config.o11yHeaders)), - body: args, - successfulResponseHandler: createJsonResponseHandler(external_exports.any()), - failedResponseHandler: createJsonErrorResponseHandler({ - errorSchema: external_exports.any(), - errorToMessage: /* @__PURE__ */ __name((data) => data, "errorToMessage") - }), - ...abortSignal && { - abortSignal - }, - fetch: this.config.fetch - }); - return { - ...responseBody, - request: { - body: args - }, - response: { - headers: responseHeaders, - body: rawResponse - }, - warnings - }; - } catch (error45) { - throw await asGatewayError(error45, await parseAuthMethod(resolvedHeaders)); - } - } - async doStream(options) { - const { args, warnings } = await this.getArgs(options); - const { abortSignal } = options; - const resolvedHeaders = await resolve(this.config.headers()); - try { - const { value: response, responseHeaders } = await postJsonToApi({ - url: this.getUrl(), - headers: combineHeaders(resolvedHeaders, options.headers, this.getModelConfigHeaders(this.modelId, true), await resolve(this.config.o11yHeaders)), - body: args, - successfulResponseHandler: createEventSourceResponseHandler(external_exports.any()), - failedResponseHandler: createJsonErrorResponseHandler({ - errorSchema: external_exports.any(), - errorToMessage: /* @__PURE__ */ __name((data) => data, "errorToMessage") - }), - ...abortSignal && { - abortSignal - }, - fetch: this.config.fetch - }); - return { - stream: response.pipeThrough(new TransformStream({ - start(controller) { - if (warnings.length > 0) { - controller.enqueue({ - type: "stream-start", - warnings - }); - } - }, - transform(chunk2, controller) { - if (chunk2.success) { - const streamPart = chunk2.value; - if (streamPart.type === "raw" && !options.includeRawChunks) { - return; - } - if (streamPart.type === "response-metadata" && streamPart.timestamp && typeof streamPart.timestamp === "string") { - streamPart.timestamp = new Date(streamPart.timestamp); - } - controller.enqueue(streamPart); - } else { - controller.error(chunk2.error); - } - } - })), - request: { - body: args - }, - response: { - headers: responseHeaders - } - }; - } catch (error45) { - throw await asGatewayError(error45, await parseAuthMethod(resolvedHeaders)); - } - } - isFilePart(part) { - return part && typeof part === "object" && "type" in part && part.type === "file"; - } - /** - * Encodes file parts in the prompt to base64. Mutates the passed options - * instance directly to avoid copying the file data. - * @param options - The options to encode. - * @returns The options with the file parts encoded. - */ - maybeEncodeFileParts(options) { - for (const message of options.prompt) { - for (const part of message.content) { - if (this.isFilePart(part)) { - const filePart = part; - if (filePart.data instanceof Uint8Array) { - const buffer = Uint8Array.from(filePart.data); - const base64Data = Buffer.from(buffer).toString("base64"); - filePart.data = new URL(\`data:\${filePart.mediaType || "application/octet-stream"};base64,\${base64Data}\`); - } - } - } - } - return options; - } - getUrl() { - return \`\${this.config.baseURL}/language-model\`; - } - getModelConfigHeaders(modelId, streaming) { - return { - "ai-language-model-specification-version": "2", - "ai-language-model-id": modelId, - "ai-language-model-streaming": String(streaming) - }; - } -}; -var GatewayEmbeddingModel = class { - static { - __name(this, "GatewayEmbeddingModel"); - } - constructor(modelId, config2) { - this.modelId = modelId; - this.config = config2; - this.specificationVersion = "v2"; - this.maxEmbeddingsPerCall = 2048; - this.supportsParallelCalls = true; - } - get provider() { - return this.config.provider; - } - async doEmbed({ values, headers, abortSignal, providerOptions }) { - var _a83; - const resolvedHeaders = await resolve(this.config.headers()); - try { - const { responseHeaders, value: responseBody, rawValue } = await postJsonToApi({ - url: this.getUrl(), - headers: combineHeaders(resolvedHeaders, headers != null ? headers : {}, this.getModelConfigHeaders(), await resolve(this.config.o11yHeaders)), - body: { - input: values.length === 1 ? values[0] : values, - ...providerOptions ? { - providerOptions - } : {} - }, - successfulResponseHandler: createJsonResponseHandler(gatewayEmbeddingResponseSchema), - failedResponseHandler: createJsonErrorResponseHandler({ - errorSchema: external_exports.any(), - errorToMessage: /* @__PURE__ */ __name((data) => data, "errorToMessage") - }), - ...abortSignal && { - abortSignal - }, - fetch: this.config.fetch - }); - return { - embeddings: responseBody.embeddings, - usage: (_a83 = responseBody.usage) != null ? _a83 : void 0, - providerMetadata: responseBody.providerMetadata, - response: { - headers: responseHeaders, - body: rawValue - } - }; - } catch (error45) { - throw await asGatewayError(error45, await parseAuthMethod(resolvedHeaders)); - } - } - getUrl() { - return \`\${this.config.baseURL}/embedding-model\`; - } - getModelConfigHeaders() { - return { - "ai-embedding-model-specification-version": "2", - "ai-model-id": this.modelId - }; - } -}; -var gatewayEmbeddingResponseSchema = lazyValidator(() => zodSchema(external_exports.object({ - embeddings: external_exports.array(external_exports.array(external_exports.number())), - usage: external_exports.object({ - tokens: external_exports.number() - }).nullish(), - providerMetadata: external_exports.record(external_exports.string(), external_exports.record(external_exports.string(), external_exports.unknown())).optional() -}))); -async function getVercelRequestId() { - var _a83; - return (_a83 = (0, import_oidc.getContext)().headers) == null ? void 0 : _a83["x-vercel-id"]; -} -__name(getVercelRequestId, "getVercelRequestId"); -var VERSION2 = true ? "2.0.0" : "0.0.0-test"; -var AI_GATEWAY_PROTOCOL_VERSION = "0.0.1"; -function createGatewayProvider(options = {}) { - var _a83, _b8; - let pendingMetadata = null; - let metadataCache = null; - const cacheRefreshMillis = (_a83 = options.metadataCacheRefreshMillis) != null ? _a83 : 1e3 * 60 * 5; - let lastFetchTime = 0; - const baseURL = (_b8 = withoutTrailingSlash(options.baseURL)) != null ? _b8 : "https://ai-gateway.vercel.sh/v1/ai"; - const getHeaders = /* @__PURE__ */ __name(async () => { - const auth = await getGatewayAuthToken(options); - if (auth) { - return withUserAgentSuffix({ - Authorization: \`Bearer \${auth.token}\`, - "ai-gateway-protocol-version": AI_GATEWAY_PROTOCOL_VERSION, - [GATEWAY_AUTH_METHOD_HEADER]: auth.authMethod, - ...options.headers - }, \`ai-sdk/gateway/\${VERSION2}\`); - } - throw GatewayAuthenticationError.createContextualError({ - apiKeyProvided: false, - oidcTokenProvided: false, - statusCode: 401 - }); - }, "getHeaders"); - const createO11yHeaders = /* @__PURE__ */ __name(() => { - const deploymentId = loadOptionalSetting({ - settingValue: void 0, - environmentVariableName: "VERCEL_DEPLOYMENT_ID" - }); - const environment = loadOptionalSetting({ - settingValue: void 0, - environmentVariableName: "VERCEL_ENV" - }); - const region = loadOptionalSetting({ - settingValue: void 0, - environmentVariableName: "VERCEL_REGION" - }); - return async () => { - const requestId = await getVercelRequestId(); - return { - ...deploymentId && { - "ai-o11y-deployment-id": deploymentId - }, - ...environment && { - "ai-o11y-environment": environment - }, - ...region && { - "ai-o11y-region": region - }, - ...requestId && { - "ai-o11y-request-id": requestId - } - }; - }; - }, "createO11yHeaders"); - const createLanguageModel = /* @__PURE__ */ __name((modelId) => { - return new GatewayLanguageModel(modelId, { - provider: "gateway", - baseURL, - headers: getHeaders, - fetch: options.fetch, - o11yHeaders: createO11yHeaders() - }); - }, "createLanguageModel"); - const getAvailableModels = /* @__PURE__ */ __name(async () => { - var _a93, _b9, _c; - const now2 = (_c = (_b9 = (_a93 = options._internal) == null ? void 0 : _a93.currentDate) == null ? void 0 : _b9.call(_a93).getTime()) != null ? _c : Date.now(); - if (!pendingMetadata || now2 - lastFetchTime > cacheRefreshMillis) { - lastFetchTime = now2; - pendingMetadata = new GatewayFetchMetadata({ - baseURL, - headers: getHeaders, - fetch: options.fetch - }).getAvailableModels().then((metadata) => { - metadataCache = metadata; - return metadata; - }).catch(async (error45) => { - throw await asGatewayError(error45, await parseAuthMethod(await getHeaders())); - }); - } - return metadataCache ? Promise.resolve(metadataCache) : pendingMetadata; - }, "getAvailableModels"); - const getCredits = /* @__PURE__ */ __name(async () => { - return new GatewayFetchMetadata({ - baseURL, - headers: getHeaders, - fetch: options.fetch - }).getCredits().catch(async (error45) => { - throw await asGatewayError(error45, await parseAuthMethod(await getHeaders())); - }); - }, "getCredits"); - const provider = /* @__PURE__ */ __name(function(modelId) { - if (new.target) { - throw new Error("The Gateway Provider model function cannot be called with the new keyword."); - } - return createLanguageModel(modelId); - }, "provider"); - provider.getAvailableModels = getAvailableModels; - provider.getCredits = getCredits; - provider.imageModel = (modelId) => { - throw new NoSuchModelError({ - modelId, - modelType: "imageModel" - }); - }; - provider.languageModel = createLanguageModel; - provider.textEmbeddingModel = (modelId) => { - return new GatewayEmbeddingModel(modelId, { - provider: "gateway", - baseURL, - headers: getHeaders, - fetch: options.fetch, - o11yHeaders: createO11yHeaders() - }); - }; - return provider; -} -__name(createGatewayProvider, "createGatewayProvider"); -var gateway = createGatewayProvider(); -async function getGatewayAuthToken(options) { - const apiKey = loadOptionalSetting({ - settingValue: options.apiKey, - environmentVariableName: "AI_GATEWAY_API_KEY" - }); - if (apiKey) { - return { - token: apiKey, - authMethod: "api-key" - }; - } - try { - const oidcToken = await (0, import_oidc2.getVercelOidcToken)(); - return { - token: oidcToken, - authMethod: "oidc" - }; - } catch (e) { - return null; - } -} -__name(getGatewayAuthToken, "getGatewayAuthToken"); - -// ../../node_modules/.pnpm/ai@5.0.76_zod@4.1.11/node_modules/ai/dist/index.mjs -var import_api = __toESM(require_src(), 1); -var import_api2 = __toESM(require_src(), 1); -var __defProp2 = Object.defineProperty; -var __export2 = /* @__PURE__ */ __name((target, all) => { - for (var name17 in all) __defProp2(target, name17, { - get: all[name17], - enumerable: true - }); -}, "__export"); -var name15 = "AI_NoOutputSpecifiedError"; -var marker16 = \`vercel.ai.error.\${name15}\`; -var symbol17 = Symbol.for(marker16); -var _a16; -var NoOutputSpecifiedError = class extends AISDKError { - static { - __name(this, "NoOutputSpecifiedError"); - } - // used in isInstance - constructor({ message = "No output specified." } = {}) { - super({ - name: name15, - message - }); - this[_a16] = true; - } - static isInstance(error45) { - return AISDKError.hasMarker(error45, marker16); - } -}; -_a16 = symbol17; -function formatWarning(warning) { - const prefix = "AI SDK Warning:"; - switch (warning.type) { - case "unsupported-setting": { - let message = \`\${prefix} The "\${warning.setting}" setting is not supported by this model\`; - if (warning.details) { - message += \` - \${warning.details}\`; - } - return message; - } - case "unsupported-tool": { - const toolName = "name" in warning.tool ? warning.tool.name : "unknown tool"; - let message = \`\${prefix} The tool "\${toolName}" is not supported by this model\`; - if (warning.details) { - message += \` - \${warning.details}\`; - } - return message; - } - case "other": { - return \`\${prefix} \${warning.message}\`; - } - default: { - return \`\${prefix} \${JSON.stringify(warning, null, 2)}\`; - } - } -} -__name(formatWarning, "formatWarning"); -var FIRST_WARNING_INFO_MESSAGE = "AI SDK Warning System: To turn off warning logging, set the AI_SDK_LOG_WARNINGS global to false."; -var hasLoggedBefore = false; -var logWarnings = /* @__PURE__ */ __name((warnings) => { - if (warnings.length === 0) { - return; - } - const logger = globalThis.AI_SDK_LOG_WARNINGS; - if (logger === false) { - return; - } - if (typeof logger === "function") { - logger(warnings); - return; - } - if (!hasLoggedBefore) { - hasLoggedBefore = true; - console.info(FIRST_WARNING_INFO_MESSAGE); - } - for (const warning of warnings) { - console.warn(formatWarning(warning)); - } -}, "logWarnings"); -var name23 = "AI_InvalidArgumentError"; -var marker23 = \`vercel.ai.error.\${name23}\`; -var symbol23 = Symbol.for(marker23); -var _a23; -var InvalidArgumentError2 = class extends AISDKError { - static { - __name(this, "InvalidArgumentError"); - } - constructor({ parameter, value, message }) { - super({ - name: name23, - message: \`Invalid argument for parameter \${parameter}: \${message}\` - }); - this[_a23] = true; - this.parameter = parameter; - this.value = value; - } - static isInstance(error45) { - return AISDKError.hasMarker(error45, marker23); - } -}; -_a23 = symbol23; -var name33 = "AI_InvalidStreamPartError"; -var marker33 = \`vercel.ai.error.\${name33}\`; -var symbol33 = Symbol.for(marker33); -var _a33; -_a33 = symbol33; -var name43 = "AI_InvalidToolInputError"; -var marker43 = \`vercel.ai.error.\${name43}\`; -var symbol43 = Symbol.for(marker43); -var _a43; -var InvalidToolInputError = class extends AISDKError { - static { - __name(this, "InvalidToolInputError"); - } - constructor({ toolInput, toolName, cause, message = \`Invalid input for tool \${toolName}: \${getErrorMessage(cause)}\` }) { - super({ - name: name43, - message, - cause - }); - this[_a43] = true; - this.toolInput = toolInput; - this.toolName = toolName; - } - static isInstance(error45) { - return AISDKError.hasMarker(error45, marker43); - } -}; -_a43 = symbol43; -var name53 = "AI_MCPClientError"; -var marker53 = \`vercel.ai.error.\${name53}\`; -var symbol53 = Symbol.for(marker53); -var _a53; -_a53 = symbol53; -var name63 = "AI_NoImageGeneratedError"; -var marker63 = \`vercel.ai.error.\${name63}\`; -var symbol63 = Symbol.for(marker63); -var _a63; -_a63 = symbol63; -var name72 = "AI_NoObjectGeneratedError"; -var marker73 = \`vercel.ai.error.\${name72}\`; -var symbol73 = Symbol.for(marker73); -var _a73; -var NoObjectGeneratedError = class extends AISDKError { - static { - __name(this, "NoObjectGeneratedError"); - } - constructor({ message = "No object generated.", cause, text: text2, response, usage, finishReason }) { - super({ - name: name72, - message, - cause - }); - this[_a73] = true; - this.text = text2; - this.response = response; - this.usage = usage; - this.finishReason = finishReason; - } - static isInstance(error45) { - return AISDKError.hasMarker(error45, marker73); - } -}; -_a73 = symbol73; -var name82 = "AI_NoOutputGeneratedError"; -var marker82 = \`vercel.ai.error.\${name82}\`; -var symbol82 = Symbol.for(marker82); -var _a82; -_a82 = symbol82; -var name92 = "AI_NoSuchToolError"; -var marker92 = \`vercel.ai.error.\${name92}\`; -var symbol92 = Symbol.for(marker92); -var _a92; -var NoSuchToolError = class extends AISDKError { - static { - __name(this, "NoSuchToolError"); - } - constructor({ toolName, availableTools = void 0, message = \`Model tried to call unavailable tool '\${toolName}'. \${availableTools === void 0 ? "No tools are available." : \`Available tools: \${availableTools.join(", ")}.\`}\` }) { - super({ - name: name92, - message - }); - this[_a92] = true; - this.toolName = toolName; - this.availableTools = availableTools; - } - static isInstance(error45) { - return AISDKError.hasMarker(error45, marker92); - } -}; -_a92 = symbol92; -var name102 = "AI_ToolCallRepairError"; -var marker102 = \`vercel.ai.error.\${name102}\`; -var symbol102 = Symbol.for(marker102); -var _a102; -var ToolCallRepairError = class extends AISDKError { - static { - __name(this, "ToolCallRepairError"); - } - constructor({ cause, originalError, message = \`Error repairing tool call: \${getErrorMessage(cause)}\` }) { - super({ - name: name102, - message, - cause - }); - this[_a102] = true; - this.originalError = originalError; - } - static isInstance(error45) { - return AISDKError.hasMarker(error45, marker102); - } -}; -_a102 = symbol102; -var UnsupportedModelVersionError = class extends AISDKError { - static { - __name(this, "UnsupportedModelVersionError"); - } - constructor(options) { - super({ - name: "AI_UnsupportedModelVersionError", - message: \`Unsupported model version \${options.version} for provider "\${options.provider}" and model "\${options.modelId}". AI SDK 5 only supports models that implement specification version "v2".\` - }); - this.version = options.version; - this.provider = options.provider; - this.modelId = options.modelId; - } -}; -var name112 = "AI_InvalidDataContentError"; -var marker112 = \`vercel.ai.error.\${name112}\`; -var symbol112 = Symbol.for(marker112); -var _a112; -_a112 = symbol112; -var name122 = "AI_InvalidMessageRoleError"; -var marker122 = \`vercel.ai.error.\${name122}\`; -var symbol122 = Symbol.for(marker122); -var _a122; -var InvalidMessageRoleError = class extends AISDKError { - static { - __name(this, "InvalidMessageRoleError"); - } - constructor({ role, message = \`Invalid message role: '\${role}'. Must be one of: "system", "user", "assistant", "tool".\` }) { - super({ - name: name122, - message - }); - this[_a122] = true; - this.role = role; - } - static isInstance(error45) { - return AISDKError.hasMarker(error45, marker122); - } -}; -_a122 = symbol122; -var name132 = "AI_MessageConversionError"; -var marker132 = \`vercel.ai.error.\${name132}\`; -var symbol132 = Symbol.for(marker132); -var _a132; -_a132 = symbol132; -var name142 = "AI_DownloadError"; -var marker142 = \`vercel.ai.error.\${name142}\`; -var symbol142 = Symbol.for(marker142); -var _a142; -var DownloadError = class extends AISDKError { - static { - __name(this, "DownloadError"); - } - constructor({ url: url2, statusCode, statusText, cause, message = cause == null ? \`Failed to download \${url2}: \${statusCode} \${statusText}\` : \`Failed to download \${url2}: \${cause}\` }) { - super({ - name: name142, - message, - cause - }); - this[_a142] = true; - this.url = url2; - this.statusCode = statusCode; - this.statusText = statusText; - } - static isInstance(error45) { - return AISDKError.hasMarker(error45, marker142); - } -}; -_a142 = symbol142; -var name152 = "AI_RetryError"; -var marker152 = \`vercel.ai.error.\${name152}\`; -var symbol152 = Symbol.for(marker152); -var _a152; -var RetryError = class extends AISDKError { - static { - __name(this, "RetryError"); - } - constructor({ message, reason, errors }) { - super({ - name: name152, - message - }); - this[_a152] = true; - this.reason = reason; - this.errors = errors; - this.lastError = errors[errors.length - 1]; - } - static isInstance(error45) { - return AISDKError.hasMarker(error45, marker152); - } -}; -_a152 = symbol152; -function resolveLanguageModel(model) { - if (typeof model !== "string") { - if (model.specificationVersion !== "v2") { - throw new UnsupportedModelVersionError({ - version: model.specificationVersion, - provider: model.provider, - modelId: model.modelId - }); - } - return model; - } - return getGlobalProvider().languageModel(model); -} -__name(resolveLanguageModel, "resolveLanguageModel"); -function getGlobalProvider() { - var _a17; - return (_a17 = globalThis.AI_SDK_DEFAULT_PROVIDER) != null ? _a17 : gateway; -} -__name(getGlobalProvider, "getGlobalProvider"); -var imageMediaTypeSignatures = [ - { - mediaType: "image/gif", - bytesPrefix: [ - 71, - 73, - 70 - ] - }, - { - mediaType: "image/png", - bytesPrefix: [ - 137, - 80, - 78, - 71 - ] - }, - { - mediaType: "image/jpeg", - bytesPrefix: [ - 255, - 216 - ] - }, - { - mediaType: "image/webp", - bytesPrefix: [ - 82, - 73, - 70, - 70, - // "RIFF" - null, - null, - null, - null, - // file size (variable) - 87, - 69, - 66, - 80 - ] - }, - { - mediaType: "image/bmp", - bytesPrefix: [ - 66, - 77 - ] - }, - { - mediaType: "image/tiff", - bytesPrefix: [ - 73, - 73, - 42, - 0 - ] - }, - { - mediaType: "image/tiff", - bytesPrefix: [ - 77, - 77, - 0, - 42 - ] - }, - { - mediaType: "image/avif", - bytesPrefix: [ - 0, - 0, - 0, - 32, - 102, - 116, - 121, - 112, - 97, - 118, - 105, - 102 - ] - }, - { - mediaType: "image/heic", - bytesPrefix: [ - 0, - 0, - 0, - 32, - 102, - 116, - 121, - 112, - 104, - 101, - 105, - 99 - ] - } -]; -var stripID3 = /* @__PURE__ */ __name((data) => { - const bytes = typeof data === "string" ? convertBase64ToUint8Array(data) : data; - const id3Size = (bytes[6] & 127) << 21 | (bytes[7] & 127) << 14 | (bytes[8] & 127) << 7 | bytes[9] & 127; - return bytes.slice(id3Size + 10); -}, "stripID3"); -function stripID3TagsIfPresent(data) { - const hasId3 = typeof data === "string" && data.startsWith("SUQz") || typeof data !== "string" && data.length > 10 && data[0] === 73 && // 'I' - data[1] === 68 && // 'D' - data[2] === 51; - return hasId3 ? stripID3(data) : data; -} -__name(stripID3TagsIfPresent, "stripID3TagsIfPresent"); -function detectMediaType({ data, signatures }) { - const processedData = stripID3TagsIfPresent(data); - const bytes = typeof processedData === "string" ? convertBase64ToUint8Array(processedData.substring(0, Math.min(processedData.length, 24))) : processedData; - for (const signature of signatures) { - if (bytes.length >= signature.bytesPrefix.length && signature.bytesPrefix.every((byte, index) => byte === null || bytes[index] === byte)) { - return signature.mediaType; - } - } - return void 0; -} -__name(detectMediaType, "detectMediaType"); -var VERSION3 = true ? "5.0.76" : "0.0.0-test"; -var download = /* @__PURE__ */ __name(async ({ url: url2 }) => { - var _a17; - const urlText = url2.toString(); - try { - const response = await fetch(urlText, { - headers: withUserAgentSuffix({}, \`ai-sdk/\${VERSION3}\`, getRuntimeEnvironmentUserAgent()) - }); - if (!response.ok) { - throw new DownloadError({ - url: urlText, - statusCode: response.status, - statusText: response.statusText - }); - } - return { - data: new Uint8Array(await response.arrayBuffer()), - mediaType: (_a17 = response.headers.get("content-type")) != null ? _a17 : void 0 - }; - } catch (error45) { - if (DownloadError.isInstance(error45)) { - throw error45; - } - throw new DownloadError({ - url: urlText, - cause: error45 - }); - } -}, "download"); -var createDefaultDownloadFunction = /* @__PURE__ */ __name((download2 = download) => (requestedDownloads) => Promise.all(requestedDownloads.map(async (requestedDownload) => requestedDownload.isUrlSupportedByModel ? null : download2(requestedDownload))), "createDefaultDownloadFunction"); -function splitDataUrl(dataUrl) { - try { - const [header, base64Content] = dataUrl.split(","); - return { - mediaType: header.split(";")[0].split(":")[1], - base64Content - }; - } catch (error45) { - return { - mediaType: void 0, - base64Content: void 0 - }; - } -} -__name(splitDataUrl, "splitDataUrl"); -var dataContentSchema = external_exports.union([ - external_exports.string(), - external_exports.instanceof(Uint8Array), - external_exports.instanceof(ArrayBuffer), - external_exports.custom( - // Buffer might not be available in some environments such as CloudFlare: - (value) => { - var _a17, _b8; - return (_b8 = (_a17 = globalThis.Buffer) == null ? void 0 : _a17.isBuffer(value)) != null ? _b8 : false; - }, - { - message: "Must be a Buffer" - } - ) -]); -function convertToLanguageModelV2DataContent(content) { - if (content instanceof Uint8Array) { - return { - data: content, - mediaType: void 0 - }; - } - if (content instanceof ArrayBuffer) { - return { - data: new Uint8Array(content), - mediaType: void 0 - }; - } - if (typeof content === "string") { - try { - content = new URL(content); - } catch (error45) { - } - } - if (content instanceof URL && content.protocol === "data:") { - const { mediaType: dataUrlMediaType, base64Content } = splitDataUrl(content.toString()); - if (dataUrlMediaType == null || base64Content == null) { - throw new AISDKError({ - name: "InvalidDataContentError", - message: \`Invalid data URL format in content \${content.toString()}\` - }); - } - return { - data: base64Content, - mediaType: dataUrlMediaType - }; - } - return { - data: content, - mediaType: void 0 - }; -} -__name(convertToLanguageModelV2DataContent, "convertToLanguageModelV2DataContent"); -function convertDataContentToBase64String(content) { - if (typeof content === "string") { - return content; - } - if (content instanceof ArrayBuffer) { - return convertUint8ArrayToBase64(new Uint8Array(content)); - } - return convertUint8ArrayToBase64(content); -} -__name(convertDataContentToBase64String, "convertDataContentToBase64String"); -async function convertToLanguageModelPrompt({ prompt, supportedUrls, download: download2 = createDefaultDownloadFunction() }) { - const downloadedAssets = await downloadAssets(prompt.messages, download2, supportedUrls); - return [ - ...prompt.system != null ? [ - { - role: "system", - content: prompt.system - } - ] : [], - ...prompt.messages.map((message) => convertToLanguageModelMessage({ - message, - downloadedAssets - })) - ]; -} -__name(convertToLanguageModelPrompt, "convertToLanguageModelPrompt"); -function convertToLanguageModelMessage({ message, downloadedAssets }) { - const role = message.role; - switch (role) { - case "system": { - return { - role: "system", - content: message.content, - providerOptions: message.providerOptions - }; - } - case "user": { - if (typeof message.content === "string") { - return { - role: "user", - content: [ - { - type: "text", - text: message.content - } - ], - providerOptions: message.providerOptions - }; - } - return { - role: "user", - content: message.content.map((part) => convertPartToLanguageModelPart(part, downloadedAssets)).filter((part) => part.type !== "text" || part.text !== ""), - providerOptions: message.providerOptions - }; - } - case "assistant": { - if (typeof message.content === "string") { - return { - role: "assistant", - content: [ - { - type: "text", - text: message.content - } - ], - providerOptions: message.providerOptions - }; - } - return { - role: "assistant", - content: message.content.filter( - // remove empty text parts (no text, and no provider options): - (part) => part.type !== "text" || part.text !== "" || part.providerOptions != null - ).map((part) => { - const providerOptions = part.providerOptions; - switch (part.type) { - case "file": { - const { data, mediaType } = convertToLanguageModelV2DataContent(part.data); - return { - type: "file", - data, - filename: part.filename, - mediaType: mediaType != null ? mediaType : part.mediaType, - providerOptions - }; - } - case "reasoning": { - return { - type: "reasoning", - text: part.text, - providerOptions - }; - } - case "text": { - return { - type: "text", - text: part.text, - providerOptions - }; - } - case "tool-call": { - return { - type: "tool-call", - toolCallId: part.toolCallId, - toolName: part.toolName, - input: part.input, - providerExecuted: part.providerExecuted, - providerOptions - }; - } - case "tool-result": { - return { - type: "tool-result", - toolCallId: part.toolCallId, - toolName: part.toolName, - output: part.output, - providerOptions - }; - } - } - }), - providerOptions: message.providerOptions - }; - } - case "tool": { - return { - role: "tool", - content: message.content.map((part) => ({ - type: "tool-result", - toolCallId: part.toolCallId, - toolName: part.toolName, - output: part.output, - providerOptions: part.providerOptions - })), - providerOptions: message.providerOptions - }; - } - default: { - const _exhaustiveCheck = role; - throw new InvalidMessageRoleError({ - role: _exhaustiveCheck - }); - } - } -} -__name(convertToLanguageModelMessage, "convertToLanguageModelMessage"); -async function downloadAssets(messages, download2, supportedUrls) { - const plannedDownloads = messages.filter((message) => message.role === "user").map((message) => message.content).filter((content) => Array.isArray(content)).flat().filter((part) => part.type === "image" || part.type === "file").map((part) => { - var _a17; - const mediaType = (_a17 = part.mediaType) != null ? _a17 : part.type === "image" ? "image/*" : void 0; - let data = part.type === "image" ? part.image : part.data; - if (typeof data === "string") { - try { - data = new URL(data); - } catch (ignored) { - } - } - return { - mediaType, - data - }; - }).filter((part) => part.data instanceof URL).map((part) => ({ - url: part.data, - isUrlSupportedByModel: part.mediaType != null && isUrlSupported({ - url: part.data.toString(), - mediaType: part.mediaType, - supportedUrls - }) - })); - const downloadedFiles = await download2(plannedDownloads); - return Object.fromEntries(downloadedFiles.map((file2, index) => file2 == null ? null : [ - plannedDownloads[index].url.toString(), - { - data: file2.data, - mediaType: file2.mediaType - } - ]).filter((file2) => file2 != null)); -} -__name(downloadAssets, "downloadAssets"); -function convertPartToLanguageModelPart(part, downloadedAssets) { - var _a17; - if (part.type === "text") { - return { - type: "text", - text: part.text, - providerOptions: part.providerOptions - }; - } - let originalData; - const type = part.type; - switch (type) { - case "image": - originalData = part.image; - break; - case "file": - originalData = part.data; - break; - default: - throw new Error(\`Unsupported part type: \${type}\`); - } - const { data: convertedData, mediaType: convertedMediaType } = convertToLanguageModelV2DataContent(originalData); - let mediaType = convertedMediaType != null ? convertedMediaType : part.mediaType; - let data = convertedData; - if (data instanceof URL) { - const downloadedFile = downloadedAssets[data.toString()]; - if (downloadedFile) { - data = downloadedFile.data; - mediaType != null ? mediaType : mediaType = downloadedFile.mediaType; - } - } - switch (type) { - case "image": { - if (data instanceof Uint8Array || typeof data === "string") { - mediaType = (_a17 = detectMediaType({ - data, - signatures: imageMediaTypeSignatures - })) != null ? _a17 : mediaType; - } - return { - type: "file", - mediaType: mediaType != null ? mediaType : "image/*", - // any image - filename: void 0, - data, - providerOptions: part.providerOptions - }; - } - case "file": { - if (mediaType == null) { - throw new Error(\`Media type is missing for file part\`); - } - return { - type: "file", - mediaType, - filename: part.filename, - data, - providerOptions: part.providerOptions - }; - } - } -} -__name(convertPartToLanguageModelPart, "convertPartToLanguageModelPart"); -function prepareCallSettings({ maxOutputTokens, temperature, topP, topK, presencePenalty, frequencyPenalty, seed, stopSequences }) { - if (maxOutputTokens != null) { - if (!Number.isInteger(maxOutputTokens)) { - throw new InvalidArgumentError2({ - parameter: "maxOutputTokens", - value: maxOutputTokens, - message: "maxOutputTokens must be an integer" - }); - } - if (maxOutputTokens < 1) { - throw new InvalidArgumentError2({ - parameter: "maxOutputTokens", - value: maxOutputTokens, - message: "maxOutputTokens must be >= 1" - }); - } - } - if (temperature != null) { - if (typeof temperature !== "number") { - throw new InvalidArgumentError2({ - parameter: "temperature", - value: temperature, - message: "temperature must be a number" - }); - } - } - if (topP != null) { - if (typeof topP !== "number") { - throw new InvalidArgumentError2({ - parameter: "topP", - value: topP, - message: "topP must be a number" - }); - } - } - if (topK != null) { - if (typeof topK !== "number") { - throw new InvalidArgumentError2({ - parameter: "topK", - value: topK, - message: "topK must be a number" - }); - } - } - if (presencePenalty != null) { - if (typeof presencePenalty !== "number") { - throw new InvalidArgumentError2({ - parameter: "presencePenalty", - value: presencePenalty, - message: "presencePenalty must be a number" - }); - } - } - if (frequencyPenalty != null) { - if (typeof frequencyPenalty !== "number") { - throw new InvalidArgumentError2({ - parameter: "frequencyPenalty", - value: frequencyPenalty, - message: "frequencyPenalty must be a number" - }); - } - } - if (seed != null) { - if (!Number.isInteger(seed)) { - throw new InvalidArgumentError2({ - parameter: "seed", - value: seed, - message: "seed must be an integer" - }); - } - } - return { - maxOutputTokens, - temperature, - topP, - topK, - presencePenalty, - frequencyPenalty, - stopSequences, - seed - }; -} -__name(prepareCallSettings, "prepareCallSettings"); -function isNonEmptyObject(object22) { - return object22 != null && Object.keys(object22).length > 0; -} -__name(isNonEmptyObject, "isNonEmptyObject"); -function prepareToolsAndToolChoice({ tools, toolChoice, activeTools }) { - if (!isNonEmptyObject(tools)) { - return { - tools: void 0, - toolChoice: void 0 - }; - } - const filteredTools = activeTools != null ? Object.entries(tools).filter(([name17]) => activeTools.includes(name17)) : Object.entries(tools); - return { - tools: filteredTools.map(([name17, tool3]) => { - const toolType = tool3.type; - switch (toolType) { - case void 0: - case "dynamic": - case "function": - return { - type: "function", - name: name17, - description: tool3.description, - inputSchema: asSchema(tool3.inputSchema).jsonSchema, - providerOptions: tool3.providerOptions - }; - case "provider-defined": - return { - type: "provider-defined", - name: name17, - id: tool3.id, - args: tool3.args - }; - default: { - const exhaustiveCheck = toolType; - throw new Error(\`Unsupported tool type: \${exhaustiveCheck}\`); - } - } - }), - toolChoice: toolChoice == null ? { - type: "auto" - } : typeof toolChoice === "string" ? { - type: toolChoice - } : { - type: "tool", - toolName: toolChoice.toolName - } - }; -} -__name(prepareToolsAndToolChoice, "prepareToolsAndToolChoice"); -var jsonValueSchema = external_exports.lazy(() => external_exports.union([ - external_exports.null(), - external_exports.string(), - external_exports.number(), - external_exports.boolean(), - external_exports.record(external_exports.string(), jsonValueSchema), - external_exports.array(jsonValueSchema) -])); -var providerMetadataSchema = external_exports.record(external_exports.string(), external_exports.record(external_exports.string(), jsonValueSchema)); -var textPartSchema = external_exports.object({ - type: external_exports.literal("text"), - text: external_exports.string(), - providerOptions: providerMetadataSchema.optional() -}); -var imagePartSchema = external_exports.object({ - type: external_exports.literal("image"), - image: external_exports.union([ - dataContentSchema, - external_exports.instanceof(URL) - ]), - mediaType: external_exports.string().optional(), - providerOptions: providerMetadataSchema.optional() -}); -var filePartSchema = external_exports.object({ - type: external_exports.literal("file"), - data: external_exports.union([ - dataContentSchema, - external_exports.instanceof(URL) - ]), - filename: external_exports.string().optional(), - mediaType: external_exports.string(), - providerOptions: providerMetadataSchema.optional() -}); -var reasoningPartSchema = external_exports.object({ - type: external_exports.literal("reasoning"), - text: external_exports.string(), - providerOptions: providerMetadataSchema.optional() -}); -var toolCallPartSchema = external_exports.object({ - type: external_exports.literal("tool-call"), - toolCallId: external_exports.string(), - toolName: external_exports.string(), - input: external_exports.unknown(), - providerOptions: providerMetadataSchema.optional(), - providerExecuted: external_exports.boolean().optional() -}); -var outputSchema = external_exports.discriminatedUnion("type", [ - external_exports.object({ - type: external_exports.literal("text"), - value: external_exports.string() - }), - external_exports.object({ - type: external_exports.literal("json"), - value: jsonValueSchema - }), - external_exports.object({ - type: external_exports.literal("error-text"), - value: external_exports.string() - }), - external_exports.object({ - type: external_exports.literal("error-json"), - value: jsonValueSchema - }), - external_exports.object({ - type: external_exports.literal("content"), - value: external_exports.array(external_exports.union([ - external_exports.object({ - type: external_exports.literal("text"), - text: external_exports.string() - }), - external_exports.object({ - type: external_exports.literal("media"), - data: external_exports.string(), - mediaType: external_exports.string() - }) - ])) - }) -]); -var toolResultPartSchema = external_exports.object({ - type: external_exports.literal("tool-result"), - toolCallId: external_exports.string(), - toolName: external_exports.string(), - output: outputSchema, - providerOptions: providerMetadataSchema.optional() -}); -var systemModelMessageSchema = external_exports.object({ - role: external_exports.literal("system"), - content: external_exports.string(), - providerOptions: providerMetadataSchema.optional() -}); -var userModelMessageSchema = external_exports.object({ - role: external_exports.literal("user"), - content: external_exports.union([ - external_exports.string(), - external_exports.array(external_exports.union([ - textPartSchema, - imagePartSchema, - filePartSchema - ])) - ]), - providerOptions: providerMetadataSchema.optional() -}); -var assistantModelMessageSchema = external_exports.object({ - role: external_exports.literal("assistant"), - content: external_exports.union([ - external_exports.string(), - external_exports.array(external_exports.union([ - textPartSchema, - filePartSchema, - reasoningPartSchema, - toolCallPartSchema, - toolResultPartSchema - ])) - ]), - providerOptions: providerMetadataSchema.optional() -}); -var toolModelMessageSchema = external_exports.object({ - role: external_exports.literal("tool"), - content: external_exports.array(toolResultPartSchema), - providerOptions: providerMetadataSchema.optional() -}); -var modelMessageSchema = external_exports.union([ - systemModelMessageSchema, - userModelMessageSchema, - assistantModelMessageSchema, - toolModelMessageSchema -]); -async function standardizePrompt(prompt) { - if (prompt.prompt == null && prompt.messages == null) { - throw new InvalidPromptError({ - prompt, - message: "prompt or messages must be defined" - }); - } - if (prompt.prompt != null && prompt.messages != null) { - throw new InvalidPromptError({ - prompt, - message: "prompt and messages cannot be defined at the same time" - }); - } - if (prompt.system != null && typeof prompt.system !== "string") { - throw new InvalidPromptError({ - prompt, - message: "system must be a string" - }); - } - let messages; - if (prompt.prompt != null && typeof prompt.prompt === "string") { - messages = [ - { - role: "user", - content: prompt.prompt - } - ]; - } else if (prompt.prompt != null && Array.isArray(prompt.prompt)) { - messages = prompt.prompt; - } else if (prompt.messages != null) { - messages = prompt.messages; - } else { - throw new InvalidPromptError({ - prompt, - message: "prompt or messages must be defined" - }); - } - if (messages.length === 0) { - throw new InvalidPromptError({ - prompt, - message: "messages must not be empty" - }); - } - const validationResult = await safeValidateTypes({ - value: messages, - schema: external_exports.array(modelMessageSchema) - }); - if (!validationResult.success) { - throw new InvalidPromptError({ - prompt, - message: "The messages must be a ModelMessage[]. If you have passed a UIMessage[], you can use convertToModelMessages to convert them.", - cause: validationResult.error - }); - } - return { - messages, - system: prompt.system - }; -} -__name(standardizePrompt, "standardizePrompt"); -function wrapGatewayError(error45) { - if (GatewayAuthenticationError.isInstance(error45) || GatewayModelNotFoundError.isInstance(error45)) { - return new AISDKError({ - name: "GatewayError", - message: "Vercel AI Gateway access failed. If you want to use AI SDK providers directly, use the providers, e.g. @ai-sdk/openai, or register a different global default provider.", - cause: error45 - }); - } - return error45; -} -__name(wrapGatewayError, "wrapGatewayError"); -function assembleOperationName({ operationId, telemetry }) { - return { - // standardized operation and resource name: - "operation.name": \`\${operationId}\${(telemetry == null ? void 0 : telemetry.functionId) != null ? \` \${telemetry.functionId}\` : ""}\`, - "resource.name": telemetry == null ? void 0 : telemetry.functionId, - // detailed, AI SDK specific data: - "ai.operationId": operationId, - "ai.telemetry.functionId": telemetry == null ? void 0 : telemetry.functionId - }; -} -__name(assembleOperationName, "assembleOperationName"); -function getBaseTelemetryAttributes({ model, settings, telemetry, headers }) { - var _a17; - return { - "ai.model.provider": model.provider, - "ai.model.id": model.modelId, - // settings: - ...Object.entries(settings).reduce((attributes, [key, value]) => { - attributes[\`ai.settings.\${key}\`] = value; - return attributes; - }, {}), - // add metadata as attributes: - ...Object.entries((_a17 = telemetry == null ? void 0 : telemetry.metadata) != null ? _a17 : {}).reduce((attributes, [key, value]) => { - attributes[\`ai.telemetry.metadata.\${key}\`] = value; - return attributes; - }, {}), - // request headers - ...Object.entries(headers != null ? headers : {}).reduce((attributes, [key, value]) => { - if (value !== void 0) { - attributes[\`ai.request.headers.\${key}\`] = value; - } - return attributes; - }, {}) - }; -} -__name(getBaseTelemetryAttributes, "getBaseTelemetryAttributes"); -var noopTracer = { - startSpan() { - return noopSpan; - }, - startActiveSpan(name17, arg1, arg2, arg3) { - if (typeof arg1 === "function") { - return arg1(noopSpan); - } - if (typeof arg2 === "function") { - return arg2(noopSpan); - } - if (typeof arg3 === "function") { - return arg3(noopSpan); - } - } -}; -var noopSpan = { - spanContext() { - return noopSpanContext; - }, - setAttribute() { - return this; - }, - setAttributes() { - return this; - }, - addEvent() { - return this; - }, - addLink() { - return this; - }, - addLinks() { - return this; - }, - setStatus() { - return this; - }, - updateName() { - return this; - }, - end() { - return this; - }, - isRecording() { - return false; - }, - recordException() { - return this; - } -}; -var noopSpanContext = { - traceId: "", - spanId: "", - traceFlags: 0 -}; -function getTracer({ isEnabled = false, tracer } = {}) { - if (!isEnabled) { - return noopTracer; - } - if (tracer) { - return tracer; - } - return import_api.trace.getTracer("ai"); -} -__name(getTracer, "getTracer"); -function recordSpan({ name: name17, tracer, attributes, fn, endWhenDone = true }) { - return tracer.startActiveSpan(name17, { - attributes - }, async (span) => { - try { - const result = await fn(span); - if (endWhenDone) { - span.end(); - } - return result; - } catch (error45) { - try { - recordErrorOnSpan(span, error45); - } finally { - span.end(); - } - throw error45; - } - }); -} -__name(recordSpan, "recordSpan"); -function recordErrorOnSpan(span, error45) { - if (error45 instanceof Error) { - span.recordException({ - name: error45.name, - message: error45.message, - stack: error45.stack - }); - span.setStatus({ - code: import_api2.SpanStatusCode.ERROR, - message: error45.message - }); - } else { - span.setStatus({ - code: import_api2.SpanStatusCode.ERROR - }); - } -} -__name(recordErrorOnSpan, "recordErrorOnSpan"); -function selectTelemetryAttributes({ telemetry, attributes }) { - if ((telemetry == null ? void 0 : telemetry.isEnabled) !== true) { - return {}; - } - return Object.entries(attributes).reduce((attributes2, [key, value]) => { - if (value == null) { - return attributes2; - } - if (typeof value === "object" && "input" in value && typeof value.input === "function") { - if ((telemetry == null ? void 0 : telemetry.recordInputs) === false) { - return attributes2; - } - const result = value.input(); - return result == null ? attributes2 : { - ...attributes2, - [key]: result - }; - } - if (typeof value === "object" && "output" in value && typeof value.output === "function") { - if ((telemetry == null ? void 0 : telemetry.recordOutputs) === false) { - return attributes2; - } - const result = value.output(); - return result == null ? attributes2 : { - ...attributes2, - [key]: result - }; - } - return { - ...attributes2, - [key]: value - }; - }, {}); -} -__name(selectTelemetryAttributes, "selectTelemetryAttributes"); -function stringifyForTelemetry(prompt) { - return JSON.stringify(prompt.map((message) => ({ - ...message, - content: typeof message.content === "string" ? message.content : message.content.map((part) => part.type === "file" ? { - ...part, - data: part.data instanceof Uint8Array ? convertDataContentToBase64String(part.data) : part.data - } : part) - }))); -} -__name(stringifyForTelemetry, "stringifyForTelemetry"); -function addLanguageModelUsage(usage1, usage2) { - return { - inputTokens: addTokenCounts(usage1.inputTokens, usage2.inputTokens), - outputTokens: addTokenCounts(usage1.outputTokens, usage2.outputTokens), - totalTokens: addTokenCounts(usage1.totalTokens, usage2.totalTokens), - reasoningTokens: addTokenCounts(usage1.reasoningTokens, usage2.reasoningTokens), - cachedInputTokens: addTokenCounts(usage1.cachedInputTokens, usage2.cachedInputTokens) - }; -} -__name(addLanguageModelUsage, "addLanguageModelUsage"); -function addTokenCounts(tokenCount1, tokenCount2) { - return tokenCount1 == null && tokenCount2 == null ? void 0 : (tokenCount1 != null ? tokenCount1 : 0) + (tokenCount2 != null ? tokenCount2 : 0); -} -__name(addTokenCounts, "addTokenCounts"); -function asArray(value) { - return value === void 0 ? [] : Array.isArray(value) ? value : [ - value - ]; -} -__name(asArray, "asArray"); -function getRetryDelayInMs({ error: error45, exponentialBackoffDelay }) { - const headers = error45.responseHeaders; - if (!headers) return exponentialBackoffDelay; - let ms2; - const retryAfterMs = headers["retry-after-ms"]; - if (retryAfterMs) { - const timeoutMs = parseFloat(retryAfterMs); - if (!Number.isNaN(timeoutMs)) { - ms2 = timeoutMs; - } - } - const retryAfter = headers["retry-after"]; - if (retryAfter && ms2 === void 0) { - const timeoutSeconds = parseFloat(retryAfter); - if (!Number.isNaN(timeoutSeconds)) { - ms2 = timeoutSeconds * 1e3; - } else { - ms2 = Date.parse(retryAfter) - Date.now(); - } - } - if (ms2 != null && !Number.isNaN(ms2) && 0 <= ms2 && (ms2 < 60 * 1e3 || ms2 < exponentialBackoffDelay)) { - return ms2; - } - return exponentialBackoffDelay; -} -__name(getRetryDelayInMs, "getRetryDelayInMs"); -var retryWithExponentialBackoffRespectingRetryHeaders = /* @__PURE__ */ __name(({ maxRetries = 2, initialDelayInMs = 2e3, backoffFactor = 2, abortSignal } = {}) => async (f) => _retryWithExponentialBackoff(f, { - maxRetries, - delayInMs: initialDelayInMs, - backoffFactor, - abortSignal -}), "retryWithExponentialBackoffRespectingRetryHeaders"); -async function _retryWithExponentialBackoff(f, { maxRetries, delayInMs, backoffFactor, abortSignal }, errors = []) { - try { - return await f(); - } catch (error45) { - if (isAbortError(error45)) { - throw error45; - } - if (maxRetries === 0) { - throw error45; - } - const errorMessage = getErrorMessage2(error45); - const newErrors = [ - ...errors, - error45 - ]; - const tryNumber = newErrors.length; - if (tryNumber > maxRetries) { - throw new RetryError({ - message: \`Failed after \${tryNumber} attempts. Last error: \${errorMessage}\`, - reason: "maxRetriesExceeded", - errors: newErrors - }); - } - if (error45 instanceof Error && APICallError.isInstance(error45) && error45.isRetryable === true && tryNumber <= maxRetries) { - await delay(getRetryDelayInMs({ - error: error45, - exponentialBackoffDelay: delayInMs - }), { - abortSignal - }); - return _retryWithExponentialBackoff(f, { - maxRetries, - delayInMs: backoffFactor * delayInMs, - backoffFactor, - abortSignal - }, newErrors); - } - if (tryNumber === 1) { - throw error45; - } - throw new RetryError({ - message: \`Failed after \${tryNumber} attempts with non-retryable error: '\${errorMessage}'\`, - reason: "errorNotRetryable", - errors: newErrors - }); - } -} -__name(_retryWithExponentialBackoff, "_retryWithExponentialBackoff"); -function prepareRetries({ maxRetries, abortSignal }) { - if (maxRetries != null) { - if (!Number.isInteger(maxRetries)) { - throw new InvalidArgumentError2({ - parameter: "maxRetries", - value: maxRetries, - message: "maxRetries must be an integer" - }); - } - if (maxRetries < 0) { - throw new InvalidArgumentError2({ - parameter: "maxRetries", - value: maxRetries, - message: "maxRetries must be >= 0" - }); - } - } - const maxRetriesResult = maxRetries != null ? maxRetries : 2; - return { - maxRetries: maxRetriesResult, - retry: retryWithExponentialBackoffRespectingRetryHeaders({ - maxRetries: maxRetriesResult, - abortSignal - }) - }; -} -__name(prepareRetries, "prepareRetries"); -function extractTextContent(content) { - const parts = content.filter((content2) => content2.type === "text"); - if (parts.length === 0) { - return void 0; - } - return parts.map((content2) => content2.text).join(""); -} -__name(extractTextContent, "extractTextContent"); -var DefaultGeneratedFile = class { - static { - __name(this, "DefaultGeneratedFile"); - } - constructor({ data, mediaType }) { - const isUint8Array = data instanceof Uint8Array; - this.base64Data = isUint8Array ? void 0 : data; - this.uint8ArrayData = isUint8Array ? data : void 0; - this.mediaType = mediaType; - } - // lazy conversion with caching to avoid unnecessary conversion overhead: - get base64() { - if (this.base64Data == null) { - this.base64Data = convertUint8ArrayToBase64(this.uint8ArrayData); - } - return this.base64Data; - } - // lazy conversion with caching to avoid unnecessary conversion overhead: - get uint8Array() { - if (this.uint8ArrayData == null) { - this.uint8ArrayData = convertBase64ToUint8Array(this.base64Data); - } - return this.uint8ArrayData; - } -}; -async function parseToolCall({ toolCall, tools, repairToolCall, system, messages }) { - try { - if (tools == null) { - throw new NoSuchToolError({ - toolName: toolCall.toolName - }); - } - try { - return await doParseToolCall({ - toolCall, - tools - }); - } catch (error45) { - if (repairToolCall == null || !(NoSuchToolError.isInstance(error45) || InvalidToolInputError.isInstance(error45))) { - throw error45; - } - let repairedToolCall = null; - try { - repairedToolCall = await repairToolCall({ - toolCall, - tools, - inputSchema: /* @__PURE__ */ __name(({ toolName }) => { - const { inputSchema } = tools[toolName]; - return asSchema(inputSchema).jsonSchema; - }, "inputSchema"), - system, - messages, - error: error45 - }); - } catch (repairError) { - throw new ToolCallRepairError({ - cause: repairError, - originalError: error45 - }); - } - if (repairedToolCall == null) { - throw error45; - } - return await doParseToolCall({ - toolCall: repairedToolCall, - tools - }); - } - } catch (error45) { - const parsedInput = await safeParseJSON({ - text: toolCall.input - }); - const input = parsedInput.success ? parsedInput.value : toolCall.input; - return { - type: "tool-call", - toolCallId: toolCall.toolCallId, - toolName: toolCall.toolName, - input, - dynamic: true, - invalid: true, - error: error45 - }; - } -} -__name(parseToolCall, "parseToolCall"); -async function doParseToolCall({ toolCall, tools }) { - const toolName = toolCall.toolName; - const tool3 = tools[toolName]; - if (tool3 == null) { - throw new NoSuchToolError({ - toolName: toolCall.toolName, - availableTools: Object.keys(tools) - }); - } - const schema = asSchema(tool3.inputSchema); - const parseResult = toolCall.input.trim() === "" ? await safeValidateTypes({ - value: {}, - schema - }) : await safeParseJSON({ - text: toolCall.input, - schema - }); - if (parseResult.success === false) { - throw new InvalidToolInputError({ - toolName, - toolInput: toolCall.input, - cause: parseResult.error - }); - } - return tool3.type === "dynamic" ? { - type: "tool-call", - toolCallId: toolCall.toolCallId, - toolName: toolCall.toolName, - input: parseResult.value, - providerExecuted: toolCall.providerExecuted, - providerMetadata: toolCall.providerMetadata, - dynamic: true - } : { - type: "tool-call", - toolCallId: toolCall.toolCallId, - toolName, - input: parseResult.value, - providerExecuted: toolCall.providerExecuted, - providerMetadata: toolCall.providerMetadata - }; -} -__name(doParseToolCall, "doParseToolCall"); -var DefaultStepResult = class { - static { - __name(this, "DefaultStepResult"); - } - constructor({ content, finishReason, usage, warnings, request, response, providerMetadata }) { - this.content = content; - this.finishReason = finishReason; - this.usage = usage; - this.warnings = warnings; - this.request = request; - this.response = response; - this.providerMetadata = providerMetadata; - } - get text() { - return this.content.filter((part) => part.type === "text").map((part) => part.text).join(""); - } - get reasoning() { - return this.content.filter((part) => part.type === "reasoning"); - } - get reasoningText() { - return this.reasoning.length === 0 ? void 0 : this.reasoning.map((part) => part.text).join(""); - } - get files() { - return this.content.filter((part) => part.type === "file").map((part) => part.file); - } - get sources() { - return this.content.filter((part) => part.type === "source"); - } - get toolCalls() { - return this.content.filter((part) => part.type === "tool-call"); - } - get staticToolCalls() { - return this.toolCalls.filter((toolCall) => toolCall.dynamic !== true); - } - get dynamicToolCalls() { - return this.toolCalls.filter((toolCall) => toolCall.dynamic === true); - } - get toolResults() { - return this.content.filter((part) => part.type === "tool-result"); - } - get staticToolResults() { - return this.toolResults.filter((toolResult) => toolResult.dynamic !== true); - } - get dynamicToolResults() { - return this.toolResults.filter((toolResult) => toolResult.dynamic === true); - } -}; -function stepCountIs(stepCount) { - return ({ steps }) => steps.length === stepCount; -} -__name(stepCountIs, "stepCountIs"); -async function isStopConditionMet({ stopConditions, steps }) { - return (await Promise.all(stopConditions.map((condition) => condition({ - steps - })))).some((result) => result); -} -__name(isStopConditionMet, "isStopConditionMet"); -function createToolModelOutput({ output, tool: tool3, errorMode }) { - if (errorMode === "text") { - return { - type: "error-text", - value: getErrorMessage(output) - }; - } else if (errorMode === "json") { - return { - type: "error-json", - value: toJSONValue(output) - }; - } - if (tool3 == null ? void 0 : tool3.toModelOutput) { - return tool3.toModelOutput(output); - } - return typeof output === "string" ? { - type: "text", - value: output - } : { - type: "json", - value: toJSONValue(output) - }; -} -__name(createToolModelOutput, "createToolModelOutput"); -function toJSONValue(value) { - return value === void 0 ? null : value; -} -__name(toJSONValue, "toJSONValue"); -function toResponseMessages({ content: inputContent, tools }) { - const responseMessages = []; - const content = inputContent.filter((part) => part.type !== "source").filter((part) => (part.type !== "tool-result" || part.providerExecuted) && (part.type !== "tool-error" || part.providerExecuted)).filter((part) => part.type !== "text" || part.text.length > 0).map((part) => { - switch (part.type) { - case "text": - return { - type: "text", - text: part.text, - providerOptions: part.providerMetadata - }; - case "reasoning": - return { - type: "reasoning", - text: part.text, - providerOptions: part.providerMetadata - }; - case "file": - return { - type: "file", - data: part.file.base64, - mediaType: part.file.mediaType, - providerOptions: part.providerMetadata - }; - case "tool-call": - return { - type: "tool-call", - toolCallId: part.toolCallId, - toolName: part.toolName, - input: part.input, - providerExecuted: part.providerExecuted, - providerOptions: part.providerMetadata - }; - case "tool-result": - return { - type: "tool-result", - toolCallId: part.toolCallId, - toolName: part.toolName, - output: createToolModelOutput({ - tool: tools == null ? void 0 : tools[part.toolName], - output: part.output, - errorMode: "none" - }), - providerExecuted: true, - providerOptions: part.providerMetadata - }; - case "tool-error": - return { - type: "tool-result", - toolCallId: part.toolCallId, - toolName: part.toolName, - output: createToolModelOutput({ - tool: tools == null ? void 0 : tools[part.toolName], - output: part.error, - errorMode: "json" - }), - providerOptions: part.providerMetadata - }; - } - }); - if (content.length > 0) { - responseMessages.push({ - role: "assistant", - content - }); - } - const toolResultContent = inputContent.filter((part) => part.type === "tool-result" || part.type === "tool-error").filter((part) => !part.providerExecuted).map((toolResult) => ({ - type: "tool-result", - toolCallId: toolResult.toolCallId, - toolName: toolResult.toolName, - output: createToolModelOutput({ - tool: tools == null ? void 0 : tools[toolResult.toolName], - output: toolResult.type === "tool-result" ? toolResult.output : toolResult.error, - errorMode: toolResult.type === "tool-error" ? "text" : "none" - }) - })); - if (toolResultContent.length > 0) { - responseMessages.push({ - role: "tool", - content: toolResultContent - }); - } - return responseMessages; -} -__name(toResponseMessages, "toResponseMessages"); -async function generateText({ model: modelArg, tools, toolChoice, system, prompt, messages, maxRetries: maxRetriesArg, abortSignal, headers, stopWhen = stepCountIs(1), experimental_output: output, experimental_telemetry: telemetry, providerOptions, experimental_activeTools, activeTools = experimental_activeTools, experimental_prepareStep, prepareStep = experimental_prepareStep, experimental_repairToolCall: repairToolCall, experimental_download: download2, experimental_context, _internal: { generateId: generateId3 = originalGenerateId, currentDate = /* @__PURE__ */ __name(() => /* @__PURE__ */ new Date(), "currentDate") } = {}, onStepFinish, ...settings }) { - const model = resolveLanguageModel(modelArg); - const stopConditions = asArray(stopWhen); - const { maxRetries, retry } = prepareRetries({ - maxRetries: maxRetriesArg, - abortSignal - }); - const callSettings = prepareCallSettings(settings); - const headersWithUserAgent = withUserAgentSuffix(headers != null ? headers : {}, \`ai/\${VERSION3}\`); - const baseTelemetryAttributes = getBaseTelemetryAttributes({ - model, - telemetry, - headers: headersWithUserAgent, - settings: { - ...callSettings, - maxRetries - } - }); - const initialPrompt = await standardizePrompt({ - system, - prompt, - messages - }); - const tracer = getTracer(telemetry); - try { - return await recordSpan({ - name: "ai.generateText", - attributes: selectTelemetryAttributes({ - telemetry, - attributes: { - ...assembleOperationName({ - operationId: "ai.generateText", - telemetry - }), - ...baseTelemetryAttributes, - // model: - "ai.model.provider": model.provider, - "ai.model.id": model.modelId, - // specific settings that only make sense on the outer level: - "ai.prompt": { - input: /* @__PURE__ */ __name(() => JSON.stringify({ - system, - prompt, - messages - }), "input") - } - } - }), - tracer, - fn: /* @__PURE__ */ __name(async (span) => { - var _a17, _b8, _c, _d, _e, _f, _g; - const callSettings2 = prepareCallSettings(settings); - let currentModelResponse; - let clientToolCalls = []; - let clientToolOutputs = []; - const responseMessages = []; - const steps = []; - do { - const stepInputMessages = [ - ...initialPrompt.messages, - ...responseMessages - ]; - const prepareStepResult = await (prepareStep == null ? void 0 : prepareStep({ - model, - steps, - stepNumber: steps.length, - messages: stepInputMessages - })); - const stepModel = resolveLanguageModel((_a17 = prepareStepResult == null ? void 0 : prepareStepResult.model) != null ? _a17 : model); - const promptMessages = await convertToLanguageModelPrompt({ - prompt: { - system: (_b8 = prepareStepResult == null ? void 0 : prepareStepResult.system) != null ? _b8 : initialPrompt.system, - messages: (_c = prepareStepResult == null ? void 0 : prepareStepResult.messages) != null ? _c : stepInputMessages - }, - supportedUrls: await stepModel.supportedUrls, - download: download2 - }); - const { toolChoice: stepToolChoice, tools: stepTools } = prepareToolsAndToolChoice({ - tools, - toolChoice: (_d = prepareStepResult == null ? void 0 : prepareStepResult.toolChoice) != null ? _d : toolChoice, - activeTools: (_e = prepareStepResult == null ? void 0 : prepareStepResult.activeTools) != null ? _e : activeTools - }); - currentModelResponse = await retry(() => { - var _a18; - return recordSpan({ - name: "ai.generateText.doGenerate", - attributes: selectTelemetryAttributes({ - telemetry, - attributes: { - ...assembleOperationName({ - operationId: "ai.generateText.doGenerate", - telemetry - }), - ...baseTelemetryAttributes, - // model: - "ai.model.provider": stepModel.provider, - "ai.model.id": stepModel.modelId, - // prompt: - "ai.prompt.messages": { - input: /* @__PURE__ */ __name(() => stringifyForTelemetry(promptMessages), "input") - }, - "ai.prompt.tools": { - // convert the language model level tools: - input: /* @__PURE__ */ __name(() => stepTools == null ? void 0 : stepTools.map((tool3) => JSON.stringify(tool3)), "input") - }, - "ai.prompt.toolChoice": { - input: /* @__PURE__ */ __name(() => stepToolChoice != null ? JSON.stringify(stepToolChoice) : void 0, "input") - }, - // standardized gen-ai llm span attributes: - "gen_ai.system": stepModel.provider, - "gen_ai.request.model": stepModel.modelId, - "gen_ai.request.frequency_penalty": settings.frequencyPenalty, - "gen_ai.request.max_tokens": settings.maxOutputTokens, - "gen_ai.request.presence_penalty": settings.presencePenalty, - "gen_ai.request.stop_sequences": settings.stopSequences, - "gen_ai.request.temperature": (_a18 = settings.temperature) != null ? _a18 : void 0, - "gen_ai.request.top_k": settings.topK, - "gen_ai.request.top_p": settings.topP - } - }), - tracer, - fn: /* @__PURE__ */ __name(async (span2) => { - var _a19, _b22, _c2, _d2, _e2, _f2, _g2, _h; - const result = await stepModel.doGenerate({ - ...callSettings2, - tools: stepTools, - toolChoice: stepToolChoice, - responseFormat: output == null ? void 0 : output.responseFormat, - prompt: promptMessages, - providerOptions, - abortSignal, - headers: headersWithUserAgent - }); - const responseData = { - id: (_b22 = (_a19 = result.response) == null ? void 0 : _a19.id) != null ? _b22 : generateId3(), - timestamp: (_d2 = (_c2 = result.response) == null ? void 0 : _c2.timestamp) != null ? _d2 : currentDate(), - modelId: (_f2 = (_e2 = result.response) == null ? void 0 : _e2.modelId) != null ? _f2 : stepModel.modelId, - headers: (_g2 = result.response) == null ? void 0 : _g2.headers, - body: (_h = result.response) == null ? void 0 : _h.body - }; - span2.setAttributes(selectTelemetryAttributes({ - telemetry, - attributes: { - "ai.response.finishReason": result.finishReason, - "ai.response.text": { - output: /* @__PURE__ */ __name(() => extractTextContent(result.content), "output") - }, - "ai.response.toolCalls": { - output: /* @__PURE__ */ __name(() => { - const toolCalls = asToolCalls(result.content); - return toolCalls == null ? void 0 : JSON.stringify(toolCalls); - }, "output") - }, - "ai.response.id": responseData.id, - "ai.response.model": responseData.modelId, - "ai.response.timestamp": responseData.timestamp.toISOString(), - "ai.response.providerMetadata": JSON.stringify(result.providerMetadata), - // TODO rename telemetry attributes to inputTokens and outputTokens - "ai.usage.promptTokens": result.usage.inputTokens, - "ai.usage.completionTokens": result.usage.outputTokens, - // standardized gen-ai llm span attributes: - "gen_ai.response.finish_reasons": [ - result.finishReason - ], - "gen_ai.response.id": responseData.id, - "gen_ai.response.model": responseData.modelId, - "gen_ai.usage.input_tokens": result.usage.inputTokens, - "gen_ai.usage.output_tokens": result.usage.outputTokens - } - })); - return { - ...result, - response: responseData - }; - }, "fn") - }); - }); - const stepToolCalls = await Promise.all(currentModelResponse.content.filter((part) => part.type === "tool-call").map((toolCall) => parseToolCall({ - toolCall, - tools, - repairToolCall, - system, - messages: stepInputMessages - }))); - for (const toolCall of stepToolCalls) { - if (toolCall.invalid) { - continue; - } - const tool3 = tools[toolCall.toolName]; - if ((tool3 == null ? void 0 : tool3.onInputAvailable) != null) { - await tool3.onInputAvailable({ - input: toolCall.input, - toolCallId: toolCall.toolCallId, - messages: stepInputMessages, - abortSignal, - experimental_context - }); - } - } - const invalidToolCalls = stepToolCalls.filter((toolCall) => toolCall.invalid && toolCall.dynamic); - clientToolOutputs = []; - for (const toolCall of invalidToolCalls) { - clientToolOutputs.push({ - type: "tool-error", - toolCallId: toolCall.toolCallId, - toolName: toolCall.toolName, - input: toolCall.input, - error: getErrorMessage2(toolCall.error), - dynamic: true - }); - } - clientToolCalls = stepToolCalls.filter((toolCall) => !toolCall.providerExecuted); - if (tools != null) { - clientToolOutputs.push(...await executeTools({ - toolCalls: clientToolCalls.filter((toolCall) => !toolCall.invalid), - tools, - tracer, - telemetry, - messages: stepInputMessages, - abortSignal, - experimental_context - })); - } - const stepContent = asContent({ - content: currentModelResponse.content, - toolCalls: stepToolCalls, - toolOutputs: clientToolOutputs - }); - responseMessages.push(...toResponseMessages({ - content: stepContent, - tools - })); - const currentStepResult = new DefaultStepResult({ - content: stepContent, - finishReason: currentModelResponse.finishReason, - usage: currentModelResponse.usage, - warnings: currentModelResponse.warnings, - providerMetadata: currentModelResponse.providerMetadata, - request: (_f = currentModelResponse.request) != null ? _f : {}, - response: { - ...currentModelResponse.response, - // deep clone msgs to avoid mutating past messages in multi-step: - messages: structuredClone(responseMessages) - } - }); - logWarnings((_g = currentModelResponse.warnings) != null ? _g : []); - steps.push(currentStepResult); - await (onStepFinish == null ? void 0 : onStepFinish(currentStepResult)); - } while ( - // there are tool calls: - clientToolCalls.length > 0 && // all current tool calls have outputs (incl. execution errors): - clientToolOutputs.length === clientToolCalls.length && // continue until a stop condition is met: - !await isStopConditionMet({ - stopConditions, - steps - }) - ); - span.setAttributes(selectTelemetryAttributes({ - telemetry, - attributes: { - "ai.response.finishReason": currentModelResponse.finishReason, - "ai.response.text": { - output: /* @__PURE__ */ __name(() => extractTextContent(currentModelResponse.content), "output") - }, - "ai.response.toolCalls": { - output: /* @__PURE__ */ __name(() => { - const toolCalls = asToolCalls(currentModelResponse.content); - return toolCalls == null ? void 0 : JSON.stringify(toolCalls); - }, "output") - }, - "ai.response.providerMetadata": JSON.stringify(currentModelResponse.providerMetadata), - // TODO rename telemetry attributes to inputTokens and outputTokens - "ai.usage.promptTokens": currentModelResponse.usage.inputTokens, - "ai.usage.completionTokens": currentModelResponse.usage.outputTokens - } - })); - const lastStep = steps[steps.length - 1]; - let resolvedOutput; - if (lastStep.finishReason === "stop") { - resolvedOutput = await (output == null ? void 0 : output.parseOutput({ - text: lastStep.text - }, { - response: lastStep.response, - usage: lastStep.usage, - finishReason: lastStep.finishReason - })); - } - return new DefaultGenerateTextResult({ - steps, - resolvedOutput - }); - }, "fn") - }); - } catch (error45) { - throw wrapGatewayError(error45); - } -} -__name(generateText, "generateText"); -async function executeTools({ toolCalls, tools, tracer, telemetry, messages, abortSignal, experimental_context }) { - const toolOutputs = await Promise.all(toolCalls.map(async ({ toolCallId, toolName, input }) => { - const tool3 = tools[toolName]; - if ((tool3 == null ? void 0 : tool3.execute) == null) { - return void 0; - } - return recordSpan({ - name: "ai.toolCall", - attributes: selectTelemetryAttributes({ - telemetry, - attributes: { - ...assembleOperationName({ - operationId: "ai.toolCall", - telemetry - }), - "ai.toolCall.name": toolName, - "ai.toolCall.id": toolCallId, - "ai.toolCall.args": { - output: /* @__PURE__ */ __name(() => JSON.stringify(input), "output") - } - } - }), - tracer, - fn: /* @__PURE__ */ __name(async (span) => { - try { - const stream = executeTool({ - execute: tool3.execute.bind(tool3), - input, - options: { - toolCallId, - messages, - abortSignal, - experimental_context - } - }); - let output; - for await (const part of stream) { - if (part.type === "final") { - output = part.output; - } - } - try { - span.setAttributes(selectTelemetryAttributes({ - telemetry, - attributes: { - "ai.toolCall.result": { - output: /* @__PURE__ */ __name(() => JSON.stringify(output), "output") - } - } - })); - } catch (ignored) { - } - return { - type: "tool-result", - toolCallId, - toolName, - input, - output, - dynamic: tool3.type === "dynamic" - }; - } catch (error45) { - recordErrorOnSpan(span, error45); - return { - type: "tool-error", - toolCallId, - toolName, - input, - error: error45, - dynamic: tool3.type === "dynamic" - }; - } - }, "fn") - }); - })); - return toolOutputs.filter((output) => output != null); -} -__name(executeTools, "executeTools"); -var DefaultGenerateTextResult = class { - static { - __name(this, "DefaultGenerateTextResult"); - } - constructor(options) { - this.steps = options.steps; - this.resolvedOutput = options.resolvedOutput; - } - get finalStep() { - return this.steps[this.steps.length - 1]; - } - get content() { - return this.finalStep.content; - } - get text() { - return this.finalStep.text; - } - get files() { - return this.finalStep.files; - } - get reasoningText() { - return this.finalStep.reasoningText; - } - get reasoning() { - return this.finalStep.reasoning; - } - get toolCalls() { - return this.finalStep.toolCalls; - } - get staticToolCalls() { - return this.finalStep.staticToolCalls; - } - get dynamicToolCalls() { - return this.finalStep.dynamicToolCalls; - } - get toolResults() { - return this.finalStep.toolResults; - } - get staticToolResults() { - return this.finalStep.staticToolResults; - } - get dynamicToolResults() { - return this.finalStep.dynamicToolResults; - } - get sources() { - return this.finalStep.sources; - } - get finishReason() { - return this.finalStep.finishReason; - } - get warnings() { - return this.finalStep.warnings; - } - get providerMetadata() { - return this.finalStep.providerMetadata; - } - get response() { - return this.finalStep.response; - } - get request() { - return this.finalStep.request; - } - get usage() { - return this.finalStep.usage; - } - get totalUsage() { - return this.steps.reduce((totalUsage, step) => { - return addLanguageModelUsage(totalUsage, step.usage); - }, { - inputTokens: void 0, - outputTokens: void 0, - totalTokens: void 0, - reasoningTokens: void 0, - cachedInputTokens: void 0 - }); - } - get experimental_output() { - if (this.resolvedOutput == null) { - throw new NoOutputSpecifiedError(); - } - return this.resolvedOutput; - } -}; -function asToolCalls(content) { - const parts = content.filter((part) => part.type === "tool-call"); - if (parts.length === 0) { - return void 0; - } - return parts.map((toolCall) => ({ - toolCallId: toolCall.toolCallId, - toolName: toolCall.toolName, - input: toolCall.input - })); -} -__name(asToolCalls, "asToolCalls"); -function asContent({ content, toolCalls, toolOutputs }) { - return [ - ...content.map((part) => { - switch (part.type) { - case "text": - case "reasoning": - case "source": - return part; - case "file": { - return { - type: "file", - file: new DefaultGeneratedFile(part) - }; - } - case "tool-call": { - return toolCalls.find((toolCall) => toolCall.toolCallId === part.toolCallId); - } - case "tool-result": { - const toolCall = toolCalls.find((toolCall2) => toolCall2.toolCallId === part.toolCallId); - if (toolCall == null) { - throw new Error(\`Tool call \${part.toolCallId} not found.\`); - } - if (part.isError) { - return { - type: "tool-error", - toolCallId: part.toolCallId, - toolName: part.toolName, - input: toolCall.input, - error: part.result, - providerExecuted: true, - dynamic: toolCall.dynamic - }; - } - return { - type: "tool-result", - toolCallId: part.toolCallId, - toolName: part.toolName, - input: toolCall.input, - output: part.result, - providerExecuted: true, - dynamic: toolCall.dynamic - }; - } - } - }), - ...toolOutputs - ]; -} -__name(asContent, "asContent"); -var JsonToSseTransformStream = class extends TransformStream { - static { - __name(this, "JsonToSseTransformStream"); - } - constructor() { - super({ - transform(part, controller) { - controller.enqueue(\`data: \${JSON.stringify(part)} - -\`); - }, - flush(controller) { - controller.enqueue("data: [DONE]\\n\\n"); - } - }); - } -}; -var uiMessageChunkSchema = lazyValidator(() => zodSchema(external_exports.union([ - external_exports.strictObject({ - type: external_exports.literal("text-start"), - id: external_exports.string(), - providerMetadata: providerMetadataSchema.optional() - }), - external_exports.strictObject({ - type: external_exports.literal("text-delta"), - id: external_exports.string(), - delta: external_exports.string(), - providerMetadata: providerMetadataSchema.optional() - }), - external_exports.strictObject({ - type: external_exports.literal("text-end"), - id: external_exports.string(), - providerMetadata: providerMetadataSchema.optional() - }), - external_exports.strictObject({ - type: external_exports.literal("error"), - errorText: external_exports.string() - }), - external_exports.strictObject({ - type: external_exports.literal("tool-input-start"), - toolCallId: external_exports.string(), - toolName: external_exports.string(), - providerExecuted: external_exports.boolean().optional(), - dynamic: external_exports.boolean().optional() - }), - external_exports.strictObject({ - type: external_exports.literal("tool-input-delta"), - toolCallId: external_exports.string(), - inputTextDelta: external_exports.string() - }), - external_exports.strictObject({ - type: external_exports.literal("tool-input-available"), - toolCallId: external_exports.string(), - toolName: external_exports.string(), - input: external_exports.unknown(), - providerExecuted: external_exports.boolean().optional(), - providerMetadata: providerMetadataSchema.optional(), - dynamic: external_exports.boolean().optional() - }), - external_exports.strictObject({ - type: external_exports.literal("tool-input-error"), - toolCallId: external_exports.string(), - toolName: external_exports.string(), - input: external_exports.unknown(), - providerExecuted: external_exports.boolean().optional(), - providerMetadata: providerMetadataSchema.optional(), - dynamic: external_exports.boolean().optional(), - errorText: external_exports.string() - }), - external_exports.strictObject({ - type: external_exports.literal("tool-output-available"), - toolCallId: external_exports.string(), - output: external_exports.unknown(), - providerExecuted: external_exports.boolean().optional(), - dynamic: external_exports.boolean().optional(), - preliminary: external_exports.boolean().optional() - }), - external_exports.strictObject({ - type: external_exports.literal("tool-output-error"), - toolCallId: external_exports.string(), - errorText: external_exports.string(), - providerExecuted: external_exports.boolean().optional(), - dynamic: external_exports.boolean().optional() - }), - external_exports.strictObject({ - type: external_exports.literal("reasoning-start"), - id: external_exports.string(), - providerMetadata: providerMetadataSchema.optional() - }), - external_exports.strictObject({ - type: external_exports.literal("reasoning-delta"), - id: external_exports.string(), - delta: external_exports.string(), - providerMetadata: providerMetadataSchema.optional() - }), - external_exports.strictObject({ - type: external_exports.literal("reasoning-end"), - id: external_exports.string(), - providerMetadata: providerMetadataSchema.optional() - }), - external_exports.strictObject({ - type: external_exports.literal("source-url"), - sourceId: external_exports.string(), - url: external_exports.string(), - title: external_exports.string().optional(), - providerMetadata: providerMetadataSchema.optional() - }), - external_exports.strictObject({ - type: external_exports.literal("source-document"), - sourceId: external_exports.string(), - mediaType: external_exports.string(), - title: external_exports.string(), - filename: external_exports.string().optional(), - providerMetadata: providerMetadataSchema.optional() - }), - external_exports.strictObject({ - type: external_exports.literal("file"), - url: external_exports.string(), - mediaType: external_exports.string(), - providerMetadata: providerMetadataSchema.optional() - }), - external_exports.strictObject({ - type: external_exports.custom((value) => typeof value === "string" && value.startsWith("data-"), { - message: 'Type must start with "data-"' - }), - id: external_exports.string().optional(), - data: external_exports.unknown(), - transient: external_exports.boolean().optional() - }), - external_exports.strictObject({ - type: external_exports.literal("start-step") - }), - external_exports.strictObject({ - type: external_exports.literal("finish-step") - }), - external_exports.strictObject({ - type: external_exports.literal("start"), - messageId: external_exports.string().optional(), - messageMetadata: external_exports.unknown().optional() - }), - external_exports.strictObject({ - type: external_exports.literal("finish"), - messageMetadata: external_exports.unknown().optional() - }), - external_exports.strictObject({ - type: external_exports.literal("abort") - }), - external_exports.strictObject({ - type: external_exports.literal("message-metadata"), - messageMetadata: external_exports.unknown() - }) -]))); -function fixJson(input) { - const stack = [ - "ROOT" - ]; - let lastValidIndex = -1; - let literalStart = null; - function processValueStart(char, i, swapState) { - { - switch (char) { - case '"': { - lastValidIndex = i; - stack.pop(); - stack.push(swapState); - stack.push("INSIDE_STRING"); - break; - } - case "f": - case "t": - case "n": { - lastValidIndex = i; - literalStart = i; - stack.pop(); - stack.push(swapState); - stack.push("INSIDE_LITERAL"); - break; - } - case "-": { - stack.pop(); - stack.push(swapState); - stack.push("INSIDE_NUMBER"); - break; - } - case "0": - case "1": - case "2": - case "3": - case "4": - case "5": - case "6": - case "7": - case "8": - case "9": { - lastValidIndex = i; - stack.pop(); - stack.push(swapState); - stack.push("INSIDE_NUMBER"); - break; - } - case "{": { - lastValidIndex = i; - stack.pop(); - stack.push(swapState); - stack.push("INSIDE_OBJECT_START"); - break; - } - case "[": { - lastValidIndex = i; - stack.pop(); - stack.push(swapState); - stack.push("INSIDE_ARRAY_START"); - break; - } - } - } - } - __name(processValueStart, "processValueStart"); - function processAfterObjectValue(char, i) { - switch (char) { - case ",": { - stack.pop(); - stack.push("INSIDE_OBJECT_AFTER_COMMA"); - break; - } - case "}": { - lastValidIndex = i; - stack.pop(); - break; - } - } - } - __name(processAfterObjectValue, "processAfterObjectValue"); - function processAfterArrayValue(char, i) { - switch (char) { - case ",": { - stack.pop(); - stack.push("INSIDE_ARRAY_AFTER_COMMA"); - break; - } - case "]": { - lastValidIndex = i; - stack.pop(); - break; - } - } - } - __name(processAfterArrayValue, "processAfterArrayValue"); - for (let i = 0; i < input.length; i++) { - const char = input[i]; - const currentState = stack[stack.length - 1]; - switch (currentState) { - case "ROOT": - processValueStart(char, i, "FINISH"); - break; - case "INSIDE_OBJECT_START": { - switch (char) { - case '"': { - stack.pop(); - stack.push("INSIDE_OBJECT_KEY"); - break; - } - case "}": { - lastValidIndex = i; - stack.pop(); - break; - } - } - break; - } - case "INSIDE_OBJECT_AFTER_COMMA": { - switch (char) { - case '"': { - stack.pop(); - stack.push("INSIDE_OBJECT_KEY"); - break; - } - } - break; - } - case "INSIDE_OBJECT_KEY": { - switch (char) { - case '"': { - stack.pop(); - stack.push("INSIDE_OBJECT_AFTER_KEY"); - break; - } - } - break; - } - case "INSIDE_OBJECT_AFTER_KEY": { - switch (char) { - case ":": { - stack.pop(); - stack.push("INSIDE_OBJECT_BEFORE_VALUE"); - break; - } - } - break; - } - case "INSIDE_OBJECT_BEFORE_VALUE": { - processValueStart(char, i, "INSIDE_OBJECT_AFTER_VALUE"); - break; - } - case "INSIDE_OBJECT_AFTER_VALUE": { - processAfterObjectValue(char, i); - break; - } - case "INSIDE_STRING": { - switch (char) { - case '"': { - stack.pop(); - lastValidIndex = i; - break; - } - case "\\\\": { - stack.push("INSIDE_STRING_ESCAPE"); - break; - } - default: { - lastValidIndex = i; - } - } - break; - } - case "INSIDE_ARRAY_START": { - switch (char) { - case "]": { - lastValidIndex = i; - stack.pop(); - break; - } - default: { - lastValidIndex = i; - processValueStart(char, i, "INSIDE_ARRAY_AFTER_VALUE"); - break; - } - } - break; - } - case "INSIDE_ARRAY_AFTER_VALUE": { - switch (char) { - case ",": { - stack.pop(); - stack.push("INSIDE_ARRAY_AFTER_COMMA"); - break; - } - case "]": { - lastValidIndex = i; - stack.pop(); - break; - } - default: { - lastValidIndex = i; - break; - } - } - break; - } - case "INSIDE_ARRAY_AFTER_COMMA": { - processValueStart(char, i, "INSIDE_ARRAY_AFTER_VALUE"); - break; - } - case "INSIDE_STRING_ESCAPE": { - stack.pop(); - lastValidIndex = i; - break; - } - case "INSIDE_NUMBER": { - switch (char) { - case "0": - case "1": - case "2": - case "3": - case "4": - case "5": - case "6": - case "7": - case "8": - case "9": { - lastValidIndex = i; - break; - } - case "e": - case "E": - case "-": - case ".": { - break; - } - case ",": { - stack.pop(); - if (stack[stack.length - 1] === "INSIDE_ARRAY_AFTER_VALUE") { - processAfterArrayValue(char, i); - } - if (stack[stack.length - 1] === "INSIDE_OBJECT_AFTER_VALUE") { - processAfterObjectValue(char, i); - } - break; - } - case "}": { - stack.pop(); - if (stack[stack.length - 1] === "INSIDE_OBJECT_AFTER_VALUE") { - processAfterObjectValue(char, i); - } - break; - } - case "]": { - stack.pop(); - if (stack[stack.length - 1] === "INSIDE_ARRAY_AFTER_VALUE") { - processAfterArrayValue(char, i); - } - break; - } - default: { - stack.pop(); - break; - } - } - break; - } - case "INSIDE_LITERAL": { - const partialLiteral = input.substring(literalStart, i + 1); - if (!"false".startsWith(partialLiteral) && !"true".startsWith(partialLiteral) && !"null".startsWith(partialLiteral)) { - stack.pop(); - if (stack[stack.length - 1] === "INSIDE_OBJECT_AFTER_VALUE") { - processAfterObjectValue(char, i); - } else if (stack[stack.length - 1] === "INSIDE_ARRAY_AFTER_VALUE") { - processAfterArrayValue(char, i); - } - } else { - lastValidIndex = i; - } - break; - } - } - } - let result = input.slice(0, lastValidIndex + 1); - for (let i = stack.length - 1; i >= 0; i--) { - const state = stack[i]; - switch (state) { - case "INSIDE_STRING": { - result += '"'; - break; - } - case "INSIDE_OBJECT_KEY": - case "INSIDE_OBJECT_AFTER_KEY": - case "INSIDE_OBJECT_AFTER_COMMA": - case "INSIDE_OBJECT_START": - case "INSIDE_OBJECT_BEFORE_VALUE": - case "INSIDE_OBJECT_AFTER_VALUE": { - result += "}"; - break; - } - case "INSIDE_ARRAY_START": - case "INSIDE_ARRAY_AFTER_COMMA": - case "INSIDE_ARRAY_AFTER_VALUE": { - result += "]"; - break; - } - case "INSIDE_LITERAL": { - const partialLiteral = input.substring(literalStart, input.length); - if ("true".startsWith(partialLiteral)) { - result += "true".slice(partialLiteral.length); - } else if ("false".startsWith(partialLiteral)) { - result += "false".slice(partialLiteral.length); - } else if ("null".startsWith(partialLiteral)) { - result += "null".slice(partialLiteral.length); - } - } - } - } - return result; -} -__name(fixJson, "fixJson"); -async function parsePartialJson(jsonText) { - if (jsonText === void 0) { - return { - value: void 0, - state: "undefined-input" - }; - } - let result = await safeParseJSON({ - text: jsonText - }); - if (result.success) { - return { - value: result.value, - state: "successful-parse" - }; - } - result = await safeParseJSON({ - text: fixJson(jsonText) - }); - if (result.success) { - return { - value: result.value, - state: "repaired-parse" - }; - } - return { - value: void 0, - state: "failed-parse" - }; -} -__name(parsePartialJson, "parsePartialJson"); -var output_exports = {}; -__export2(output_exports, { - object: /* @__PURE__ */ __name(() => object2, "object"), - text: /* @__PURE__ */ __name(() => text, "text") -}); -var text = /* @__PURE__ */ __name(() => ({ - type: "text", - responseFormat: { - type: "text" - }, - async parsePartial({ text: text2 }) { - return { - partial: text2 - }; - }, - async parseOutput({ text: text2 }) { - return text2; - } -}), "text"); -var object2 = /* @__PURE__ */ __name(({ schema: inputSchema }) => { - const schema = asSchema(inputSchema); - return { - type: "object", - responseFormat: { - type: "json", - schema: schema.jsonSchema - }, - async parsePartial({ text: text2 }) { - const result = await parsePartialJson(text2); - switch (result.state) { - case "failed-parse": - case "undefined-input": - return void 0; - case "repaired-parse": - case "successful-parse": - return { - // Note: currently no validation of partial results: - partial: result.value - }; - default: { - const _exhaustiveCheck = result.state; - throw new Error(\`Unsupported parse state: \${_exhaustiveCheck}\`); - } - } - }, - async parseOutput({ text: text2 }, context) { - const parseResult = await safeParseJSON({ - text: text2 - }); - if (!parseResult.success) { - throw new NoObjectGeneratedError({ - message: "No object generated: could not parse the response.", - cause: parseResult.error, - text: text2, - response: context.response, - usage: context.usage, - finishReason: context.finishReason - }); - } - const validationResult = await safeValidateTypes({ - value: parseResult.value, - schema - }); - if (!validationResult.success) { - throw new NoObjectGeneratedError({ - message: "No object generated: response did not match schema.", - cause: validationResult.error, - text: text2, - response: context.response, - usage: context.usage, - finishReason: context.finishReason - }); - } - return validationResult.value; - } - }; -}, "object"); -var name16 = "AI_NoSuchProviderError"; -var marker162 = \`vercel.ai.error.\${name16}\`; -var symbol162 = Symbol.for(marker162); -var _a162; -_a162 = symbol162; -var ClientOrServerImplementationSchema = external_exports.looseObject({ - name: external_exports.string(), - version: external_exports.string() -}); -var BaseParamsSchema = external_exports.looseObject({ - _meta: external_exports.optional(external_exports.object({}).loose()) -}); -var ResultSchema = BaseParamsSchema; -var RequestSchema = external_exports.object({ - method: external_exports.string(), - params: external_exports.optional(BaseParamsSchema) -}); -var ServerCapabilitiesSchema = external_exports.looseObject({ - experimental: external_exports.optional(external_exports.object({}).loose()), - logging: external_exports.optional(external_exports.object({}).loose()), - prompts: external_exports.optional(external_exports.looseObject({ - listChanged: external_exports.optional(external_exports.boolean()) - })), - resources: external_exports.optional(external_exports.looseObject({ - subscribe: external_exports.optional(external_exports.boolean()), - listChanged: external_exports.optional(external_exports.boolean()) - })), - tools: external_exports.optional(external_exports.looseObject({ - listChanged: external_exports.optional(external_exports.boolean()) - })) -}); -var InitializeResultSchema = ResultSchema.extend({ - protocolVersion: external_exports.string(), - capabilities: ServerCapabilitiesSchema, - serverInfo: ClientOrServerImplementationSchema, - instructions: external_exports.optional(external_exports.string()) -}); -var PaginatedResultSchema = ResultSchema.extend({ - nextCursor: external_exports.optional(external_exports.string()) -}); -var ToolSchema = external_exports.object({ - name: external_exports.string(), - description: external_exports.optional(external_exports.string()), - inputSchema: external_exports.object({ - type: external_exports.literal("object"), - properties: external_exports.optional(external_exports.object({}).loose()) - }).loose() -}).loose(); -var ListToolsResultSchema = PaginatedResultSchema.extend({ - tools: external_exports.array(ToolSchema) -}); -var TextContentSchema = external_exports.object({ - type: external_exports.literal("text"), - text: external_exports.string() -}).loose(); -var ImageContentSchema = external_exports.object({ - type: external_exports.literal("image"), - data: external_exports.base64(), - mimeType: external_exports.string() -}).loose(); -var ResourceContentsSchema = external_exports.object({ - /** - * The URI of this resource. - */ - uri: external_exports.string(), - /** - * The MIME type of this resource, if known. - */ - mimeType: external_exports.optional(external_exports.string()) -}).loose(); -var TextResourceContentsSchema = ResourceContentsSchema.extend({ - text: external_exports.string() -}); -var BlobResourceContentsSchema = ResourceContentsSchema.extend({ - blob: external_exports.base64() -}); -var EmbeddedResourceSchema = external_exports.object({ - type: external_exports.literal("resource"), - resource: external_exports.union([ - TextResourceContentsSchema, - BlobResourceContentsSchema - ]) -}).loose(); -var CallToolResultSchema = ResultSchema.extend({ - content: external_exports.array(external_exports.union([ - TextContentSchema, - ImageContentSchema, - EmbeddedResourceSchema - ])), - isError: external_exports.boolean().default(false).optional() -}).or(ResultSchema.extend({ - toolResult: external_exports.unknown() -})); -var JSONRPC_VERSION = "2.0"; -var JSONRPCRequestSchema = external_exports.object({ - jsonrpc: external_exports.literal(JSONRPC_VERSION), - id: external_exports.union([ - external_exports.string(), - external_exports.number().int() - ]) -}).merge(RequestSchema).strict(); -var JSONRPCResponseSchema = external_exports.object({ - jsonrpc: external_exports.literal(JSONRPC_VERSION), - id: external_exports.union([ - external_exports.string(), - external_exports.number().int() - ]), - result: ResultSchema -}).strict(); -var JSONRPCErrorSchema = external_exports.object({ - jsonrpc: external_exports.literal(JSONRPC_VERSION), - id: external_exports.union([ - external_exports.string(), - external_exports.number().int() - ]), - error: external_exports.object({ - code: external_exports.number().int(), - message: external_exports.string(), - data: external_exports.optional(external_exports.unknown()) - }) -}).strict(); -var JSONRPCNotificationSchema = external_exports.object({ - jsonrpc: external_exports.literal(JSONRPC_VERSION) -}).merge(external_exports.object({ - method: external_exports.string(), - params: external_exports.optional(BaseParamsSchema) -})).strict(); -var JSONRPCMessageSchema = external_exports.union([ - JSONRPCRequestSchema, - JSONRPCNotificationSchema, - JSONRPCResponseSchema, - JSONRPCErrorSchema -]); -var uiMessagesSchema = lazyValidator(() => zodSchema(external_exports.array(external_exports.object({ - id: external_exports.string(), - role: external_exports.enum([ - "system", - "user", - "assistant" - ]), - metadata: external_exports.unknown().optional(), - parts: external_exports.array(external_exports.union([ - external_exports.object({ - type: external_exports.literal("text"), - text: external_exports.string(), - state: external_exports.enum([ - "streaming", - "done" - ]).optional(), - providerMetadata: providerMetadataSchema.optional() - }), - external_exports.object({ - type: external_exports.literal("reasoning"), - text: external_exports.string(), - state: external_exports.enum([ - "streaming", - "done" - ]).optional(), - providerMetadata: providerMetadataSchema.optional() - }), - external_exports.object({ - type: external_exports.literal("source-url"), - sourceId: external_exports.string(), - url: external_exports.string(), - title: external_exports.string().optional(), - providerMetadata: providerMetadataSchema.optional() - }), - external_exports.object({ - type: external_exports.literal("source-document"), - sourceId: external_exports.string(), - mediaType: external_exports.string(), - title: external_exports.string(), - filename: external_exports.string().optional(), - providerMetadata: providerMetadataSchema.optional() - }), - external_exports.object({ - type: external_exports.literal("file"), - mediaType: external_exports.string(), - filename: external_exports.string().optional(), - url: external_exports.string(), - providerMetadata: providerMetadataSchema.optional() - }), - external_exports.object({ - type: external_exports.literal("step-start") - }), - external_exports.object({ - type: external_exports.string().startsWith("data-"), - id: external_exports.string().optional(), - data: external_exports.unknown() - }), - external_exports.object({ - type: external_exports.literal("dynamic-tool"), - toolName: external_exports.string(), - toolCallId: external_exports.string(), - state: external_exports.literal("input-streaming"), - input: external_exports.unknown().optional(), - output: external_exports.never().optional(), - errorText: external_exports.never().optional() - }), - external_exports.object({ - type: external_exports.literal("dynamic-tool"), - toolName: external_exports.string(), - toolCallId: external_exports.string(), - state: external_exports.literal("input-available"), - input: external_exports.unknown(), - output: external_exports.never().optional(), - errorText: external_exports.never().optional(), - callProviderMetadata: providerMetadataSchema.optional() - }), - external_exports.object({ - type: external_exports.literal("dynamic-tool"), - toolName: external_exports.string(), - toolCallId: external_exports.string(), - state: external_exports.literal("output-available"), - input: external_exports.unknown(), - output: external_exports.unknown(), - errorText: external_exports.never().optional(), - callProviderMetadata: providerMetadataSchema.optional(), - preliminary: external_exports.boolean().optional() - }), - external_exports.object({ - type: external_exports.literal("dynamic-tool"), - toolName: external_exports.string(), - toolCallId: external_exports.string(), - state: external_exports.literal("output-error"), - input: external_exports.unknown(), - output: external_exports.never().optional(), - errorText: external_exports.string(), - callProviderMetadata: providerMetadataSchema.optional() - }), - external_exports.object({ - type: external_exports.string().startsWith("tool-"), - toolCallId: external_exports.string(), - state: external_exports.literal("input-streaming"), - providerExecuted: external_exports.boolean().optional(), - input: external_exports.unknown().optional(), - output: external_exports.never().optional(), - errorText: external_exports.never().optional(), - approval: external_exports.never().optional() - }), - external_exports.object({ - type: external_exports.string().startsWith("tool-"), - toolCallId: external_exports.string(), - state: external_exports.literal("input-available"), - providerExecuted: external_exports.boolean().optional(), - input: external_exports.unknown(), - output: external_exports.never().optional(), - errorText: external_exports.never().optional(), - callProviderMetadata: providerMetadataSchema.optional(), - approval: external_exports.never().optional() - }), - external_exports.object({ - type: external_exports.string().startsWith("tool-"), - toolCallId: external_exports.string(), - state: external_exports.literal("approval-requested"), - input: external_exports.unknown(), - providerExecuted: external_exports.boolean().optional(), - output: external_exports.never().optional(), - errorText: external_exports.never().optional(), - callProviderMetadata: providerMetadataSchema.optional(), - approval: external_exports.object({ - id: external_exports.string(), - approved: external_exports.never().optional(), - reason: external_exports.never().optional() - }) - }), - external_exports.object({ - type: external_exports.string().startsWith("tool-"), - toolCallId: external_exports.string(), - state: external_exports.literal("approval-responded"), - input: external_exports.unknown(), - providerExecuted: external_exports.boolean().optional(), - output: external_exports.never().optional(), - errorText: external_exports.never().optional(), - callProviderMetadata: providerMetadataSchema.optional(), - approval: external_exports.object({ - id: external_exports.string(), - approved: external_exports.boolean(), - reason: external_exports.string().optional() - }) - }), - external_exports.object({ - type: external_exports.string().startsWith("tool-"), - toolCallId: external_exports.string(), - state: external_exports.literal("output-available"), - providerExecuted: external_exports.boolean().optional(), - input: external_exports.unknown(), - output: external_exports.unknown(), - errorText: external_exports.never().optional(), - callProviderMetadata: providerMetadataSchema.optional(), - preliminary: external_exports.boolean().optional(), - approval: external_exports.object({ - id: external_exports.string(), - approved: external_exports.literal(true), - reason: external_exports.string().optional() - }).optional() - }), - external_exports.object({ - type: external_exports.string().startsWith("tool-"), - toolCallId: external_exports.string(), - state: external_exports.literal("output-error"), - providerExecuted: external_exports.boolean().optional(), - input: external_exports.unknown(), - output: external_exports.never().optional(), - errorText: external_exports.string(), - callProviderMetadata: providerMetadataSchema.optional(), - approval: external_exports.object({ - id: external_exports.string(), - approved: external_exports.literal(true), - reason: external_exports.string().optional() - }).optional() - }), - external_exports.object({ - type: external_exports.string().startsWith("tool-"), - toolCallId: external_exports.string(), - state: external_exports.literal("output-denied"), - providerExecuted: external_exports.boolean().optional(), - input: external_exports.unknown(), - output: external_exports.never().optional(), - errorText: external_exports.never().optional(), - callProviderMetadata: providerMetadataSchema.optional(), - approval: external_exports.object({ - id: external_exports.string(), - approved: external_exports.literal(false), - reason: external_exports.string().optional() - }) - }) - ])) -})))); - -// ../example/workflows/4_ai.ts -async function getWeatherInformation({ city }) { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/4_ai.ts//getWeatherInformation")({ - city - }); -} -__name(getWeatherInformation, "getWeatherInformation"); -async function ai(prompt) { - console.log("AI workflow started"); - const { text: text2 } = await generateText({ - model: "openai/o3", - prompt - }); - console.log(\`AI workflow completed. Result: \${text2}\`); - return text2; -} -__name(ai, "ai"); -async function agent(prompt) { - console.log("Agent workflow started"); - const { text: text2 } = await generateText({ - model: "anthropic/claude-4-opus-20250514", - prompt, - tools: { - getWeatherInformation: { - description: "show the weather in a given city to the user", - inputSchema: v4_default.object({ - city: v4_default.string() - }), - execute: getWeatherInformation - } - }, - // This can be a high as you want - no restriction on the lambda workflow runtime - stopWhen: stepCountIs(10) - }); - console.log(\`Agent workflow completed. Result: \${text2}\`); - return text2; -} -__name(agent, "agent"); -ai.workflowId = "workflow//example/workflows/4_ai.ts//ai"; -agent.workflowId = "workflow//example/workflows/4_ai.ts//agent"; -Object.defineProperty(getWeatherInformation, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/4_ai.ts//getWeatherInformation", - writable: false, - enumerable: false, - configurable: false -}); - -// ../example/workflows/3_streams.ts -var streams_exports = {}; -__export(streams_exports, { - consumeStreams: () => consumeStreams, - genStream: () => genStream, - streams: () => streams -}); -async function genStream() { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/3_streams.ts//genStream")(); -} -__name(genStream, "genStream"); -async function consumeStreams(...streams2) { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/3_streams.ts//consumeStreams")(...streams2); -} -__name(consumeStreams, "consumeStreams"); -async function streams() { - console.log("Streams workflow started"); - const [s1, s2] = await Promise.all([ - genStream(), - genStream() - ]); - const result = await consumeStreams(s1, s2); - console.log(\`Streams workflow completed. Result: \${result.slice(0, 100)}\`); - return { - message: "Streams processed successfully", - dataLength: result.length, - preview: result.slice(0, 100) - }; -} -__name(streams, "streams"); -streams.workflowId = "workflow//example/workflows/3_streams.ts//streams"; -Object.defineProperty(genStream, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/3_streams.ts//genStream", - writable: false, - enumerable: false, - configurable: false -}); -Object.defineProperty(consumeStreams, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/3_streams.ts//consumeStreams", - writable: false, - enumerable: false, - configurable: false -}); - -// ../example/workflows/7_full.ts -var full_exports = {}; -__export(full_exports, { - handleUserSignup: () => handleUserSignup -}); -async function handleUserSignup(email3) { - const user = await createUser(email3); - await sendWelcomeEmail(user); - await sleep("5s"); - const webhook = createWebhook(); - await sendOnboardingEmail(user, webhook.url); - await webhook; - console.log("Webhook Resolved"); - return { - userId: user.id, - status: "onboarded" - }; -} -__name(handleUserSignup, "handleUserSignup"); -async function createUser(email3) { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/7_full.ts//createUser")(email3); -} -__name(createUser, "createUser"); -async function sendWelcomeEmail(user) { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/7_full.ts//sendWelcomeEmail")(user); -} -__name(sendWelcomeEmail, "sendWelcomeEmail"); -async function sendOnboardingEmail(user, callback) { - return globalThis[Symbol.for("WORKFLOW_USE_STEP")]("step//example/workflows/7_full.ts//sendOnboardingEmail")(user, callback); -} -__name(sendOnboardingEmail, "sendOnboardingEmail"); -handleUserSignup.workflowId = "workflow//example/workflows/7_full.ts//handleUserSignup"; -Object.defineProperty(createUser, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/7_full.ts//createUser", - writable: false, - enumerable: false, - configurable: false -}); -Object.defineProperty(sendWelcomeEmail, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/7_full.ts//sendWelcomeEmail", - writable: false, - enumerable: false, - configurable: false -}); -Object.defineProperty(sendOnboardingEmail, Symbol.for("WORKFLOW_STEP_FUNCTION_NAME"), { - value: "step//example/workflows/7_full.ts//sendOnboardingEmail", - writable: false, - enumerable: false, - configurable: false -}); - -// virtual-entry.js -globalThis.__private_workflows = /* @__PURE__ */ new Map(); -Object.values(e2e_exports).map((item) => item?.workflowId && globalThis.__private_workflows.set(item.workflowId, item)); -Object.values(control_flow_exports).map((item) => item?.workflowId && globalThis.__private_workflows.set(item.workflowId, item)); -Object.values(demo_exports).map((item) => item?.workflowId && globalThis.__private_workflows.set(item.workflowId, item)); -Object.values(duplicate_case_exports).map((item) => item?.workflowId && globalThis.__private_workflows.set(item.workflowId, item)); -Object.values(batching_exports).map((item) => item?.workflowId && globalThis.__private_workflows.set(item.workflowId, item)); -Object.values(simple_exports).map((item) => item?.workflowId && globalThis.__private_workflows.set(item.workflowId, item)); -Object.values(hooks_exports).map((item) => item?.workflowId && globalThis.__private_workflows.set(item.workflowId, item)); -Object.values(ai_exports).map((item) => item?.workflowId && globalThis.__private_workflows.set(item.workflowId, item)); -Object.values(streams_exports).map((item) => item?.workflowId && globalThis.__private_workflows.set(item.workflowId, item)); -Object.values(full_exports).map((item) => item?.workflowId && globalThis.__private_workflows.set(item.workflowId, item)); -//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL21zQDIuMS4zL25vZGVfbW9kdWxlcy9tcy9pbmRleC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vbG9kYXNoLmNodW5rQDQuMi4wL25vZGVfbW9kdWxlcy9sb2Rhc2guY2h1bmsvaW5kZXguanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B2ZXJjZWwrb2lkY0AzLjAuMy9ub2RlX21vZHVsZXMvQHZlcmNlbC9vaWRjL2Rpc3QvZ2V0LWNvbnRleHQuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B2ZXJjZWwrb2lkY0AzLjAuMy9ub2RlX21vZHVsZXMvQHZlcmNlbC9vaWRjL2Rpc3QvaW5kZXgtYnJvd3Nlci5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL3BsYXRmb3JtL25vZGUvZ2xvYmFsVGhpcy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL3BsYXRmb3JtL25vZGUvaW5kZXgudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BvcGVudGVsZW1ldHJ5K2FwaUAxLjkuMC9ub2RlX21vZHVsZXMvQG9wZW50ZWxlbWV0cnkvYXBpL3NyYy9wbGF0Zm9ybS9pbmRleC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL3ZlcnNpb24udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BvcGVudGVsZW1ldHJ5K2FwaUAxLjkuMC9ub2RlX21vZHVsZXMvQG9wZW50ZWxlbWV0cnkvYXBpL3NyYy9pbnRlcm5hbC9zZW12ZXIudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BvcGVudGVsZW1ldHJ5K2FwaUAxLjkuMC9ub2RlX21vZHVsZXMvQG9wZW50ZWxlbWV0cnkvYXBpL3NyYy9pbnRlcm5hbC9nbG9iYWwtdXRpbHMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BvcGVudGVsZW1ldHJ5K2FwaUAxLjkuMC9ub2RlX21vZHVsZXMvQG9wZW50ZWxlbWV0cnkvYXBpL3NyYy9kaWFnL0NvbXBvbmVudExvZ2dlci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL2RpYWcvdHlwZXMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BvcGVudGVsZW1ldHJ5K2FwaUAxLjkuMC9ub2RlX21vZHVsZXMvQG9wZW50ZWxlbWV0cnkvYXBpL3NyYy9kaWFnL2ludGVybmFsL2xvZ0xldmVsTG9nZ2VyLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjAvbm9kZV9tb2R1bGVzL0BvcGVudGVsZW1ldHJ5L2FwaS9zcmMvYXBpL2RpYWcudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BvcGVudGVsZW1ldHJ5K2FwaUAxLjkuMC9ub2RlX21vZHVsZXMvQG9wZW50ZWxlbWV0cnkvYXBpL3NyYy9iYWdnYWdlL2ludGVybmFsL2JhZ2dhZ2UtaW1wbC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL2JhZ2dhZ2UvaW50ZXJuYWwvc3ltYm9sLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjAvbm9kZV9tb2R1bGVzL0BvcGVudGVsZW1ldHJ5L2FwaS9zcmMvYmFnZ2FnZS91dGlscy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL2NvbnRleHQvY29udGV4dC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL2RpYWcvY29uc29sZUxvZ2dlci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL21ldHJpY3MvTm9vcE1ldGVyLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjAvbm9kZV9tb2R1bGVzL0BvcGVudGVsZW1ldHJ5L2FwaS9zcmMvbWV0cmljcy9NZXRyaWMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BvcGVudGVsZW1ldHJ5K2FwaUAxLjkuMC9ub2RlX21vZHVsZXMvQG9wZW50ZWxlbWV0cnkvYXBpL3NyYy9wcm9wYWdhdGlvbi9UZXh0TWFwUHJvcGFnYXRvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL2NvbnRleHQvTm9vcENvbnRleHRNYW5hZ2VyLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjAvbm9kZV9tb2R1bGVzL0BvcGVudGVsZW1ldHJ5L2FwaS9zcmMvYXBpL2NvbnRleHQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BvcGVudGVsZW1ldHJ5K2FwaUAxLjkuMC9ub2RlX21vZHVsZXMvQG9wZW50ZWxlbWV0cnkvYXBpL3NyYy90cmFjZS90cmFjZV9mbGFncy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL3RyYWNlL2ludmFsaWQtc3Bhbi1jb25zdGFudHMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BvcGVudGVsZW1ldHJ5K2FwaUAxLjkuMC9ub2RlX21vZHVsZXMvQG9wZW50ZWxlbWV0cnkvYXBpL3NyYy90cmFjZS9Ob25SZWNvcmRpbmdTcGFuLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjAvbm9kZV9tb2R1bGVzL0BvcGVudGVsZW1ldHJ5L2FwaS9zcmMvdHJhY2UvY29udGV4dC11dGlscy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL3RyYWNlL3NwYW5jb250ZXh0LXV0aWxzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjAvbm9kZV9tb2R1bGVzL0BvcGVudGVsZW1ldHJ5L2FwaS9zcmMvdHJhY2UvTm9vcFRyYWNlci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL3RyYWNlL1Byb3h5VHJhY2VyLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjAvbm9kZV9tb2R1bGVzL0BvcGVudGVsZW1ldHJ5L2FwaS9zcmMvdHJhY2UvTm9vcFRyYWNlclByb3ZpZGVyLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjAvbm9kZV9tb2R1bGVzL0BvcGVudGVsZW1ldHJ5L2FwaS9zcmMvdHJhY2UvUHJveHlUcmFjZXJQcm92aWRlci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL3RyYWNlL1NhbXBsaW5nUmVzdWx0LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjAvbm9kZV9tb2R1bGVzL0BvcGVudGVsZW1ldHJ5L2FwaS9zcmMvdHJhY2Uvc3Bhbl9raW5kLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjAvbm9kZV9tb2R1bGVzL0BvcGVudGVsZW1ldHJ5L2FwaS9zcmMvdHJhY2Uvc3RhdHVzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjAvbm9kZV9tb2R1bGVzL0BvcGVudGVsZW1ldHJ5L2FwaS9zcmMvdHJhY2UvaW50ZXJuYWwvdHJhY2VzdGF0ZS12YWxpZGF0b3JzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjAvbm9kZV9tb2R1bGVzL0BvcGVudGVsZW1ldHJ5L2FwaS9zcmMvdHJhY2UvaW50ZXJuYWwvdHJhY2VzdGF0ZS1pbXBsLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjAvbm9kZV9tb2R1bGVzL0BvcGVudGVsZW1ldHJ5L2FwaS9zcmMvdHJhY2UvaW50ZXJuYWwvdXRpbHMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BvcGVudGVsZW1ldHJ5K2FwaUAxLjkuMC9ub2RlX21vZHVsZXMvQG9wZW50ZWxlbWV0cnkvYXBpL3NyYy9jb250ZXh0LWFwaS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL2RpYWctYXBpLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjAvbm9kZV9tb2R1bGVzL0BvcGVudGVsZW1ldHJ5L2FwaS9zcmMvbWV0cmljcy9Ob29wTWV0ZXJQcm92aWRlci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL2FwaS9tZXRyaWNzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjAvbm9kZV9tb2R1bGVzL0BvcGVudGVsZW1ldHJ5L2FwaS9zcmMvbWV0cmljcy1hcGkudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BvcGVudGVsZW1ldHJ5K2FwaUAxLjkuMC9ub2RlX21vZHVsZXMvQG9wZW50ZWxlbWV0cnkvYXBpL3NyYy9wcm9wYWdhdGlvbi9Ob29wVGV4dE1hcFByb3BhZ2F0b3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BvcGVudGVsZW1ldHJ5K2FwaUAxLjkuMC9ub2RlX21vZHVsZXMvQG9wZW50ZWxlbWV0cnkvYXBpL3NyYy9iYWdnYWdlL2NvbnRleHQtaGVscGVycy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL2FwaS9wcm9wYWdhdGlvbi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL3Byb3BhZ2F0aW9uLWFwaS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL2FwaS90cmFjZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL3RyYWNlLWFwaS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQG9wZW50ZWxlbWV0cnkrYXBpQDEuOS4wL25vZGVfbW9kdWxlcy9Ab3BlbnRlbGVtZXRyeS9hcGkvc3JjL2luZGV4LnRzIiwgIi4uL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cyIsICIuLi8uLi9wYWNrYWdlcy91dGlscy9zcmMvaW5kZXgudHMiLCAiLi4vLi4vcGFja2FnZXMvZXJyb3JzL3NyYy9pbmRleC50cyIsICIuLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy9zeW1ib2xzLnRzIiwgIi4uLy4uL3BhY2thZ2VzL2NvcmUvc3JjL3dvcmtmbG93L2dldC13b3JrZmxvdy1tZXRhZGF0YS50cyIsICIuLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy93b3JrZmxvdy9jcmVhdGUtaG9vay50cyIsICIuLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy9zbGVlcC50cyIsICIuLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy93b3JrZmxvdy93cml0YWJsZS1zdHJlYW0udHMiLCAiLi4vLi4vcGFja2FnZXMvd29ya2Zsb3cvc3JjL3N0ZGxpYi50cyIsICIuLi9leGFtcGxlL3dvcmtmbG93cy9oZWxwZXJzLnRzIiwgIi4uL2V4YW1wbGUvd29ya2Zsb3dzLzJfY29udHJvbF9mbG93LnRzIiwgIi4uL25pdHJvLXYzL3dvcmtmbG93cy8wX2RlbW8udHMiLCAiLi4vZXhhbXBsZS93b3JrZmxvd3MvOThfZHVwbGljYXRlX2Nhc2UudHMiLCAiLi4vZXhhbXBsZS93b3JrZmxvd3MvNl9iYXRjaGluZy50cyIsICIuLi9leGFtcGxlL3dvcmtmbG93cy8xX3NpbXBsZS50cyIsICIuLi9leGFtcGxlL3dvcmtmbG93cy81X2hvb2tzLnRzIiwgIi4uL2V4YW1wbGUvd29ya2Zsb3dzLzRfYWkudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXJAMi4wLjAvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXIvc3JjL2Vycm9ycy9haS1zZGstZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXJAMi4wLjAvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXIvc3JjL2Vycm9ycy9hcGktY2FsbC1lcnJvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlckAyLjAuMC9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci9zcmMvZXJyb3JzL2VtcHR5LXJlc3BvbnNlLWJvZHktZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXJAMi4wLjAvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXIvc3JjL2Vycm9ycy9nZXQtZXJyb3ItbWVzc2FnZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlckAyLjAuMC9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci9zcmMvZXJyb3JzL2ludmFsaWQtYXJndW1lbnQtZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXJAMi4wLjAvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXIvc3JjL2Vycm9ycy9pbnZhbGlkLXByb21wdC1lcnJvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlckAyLjAuMC9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci9zcmMvZXJyb3JzL2ludmFsaWQtcmVzcG9uc2UtZGF0YS1lcnJvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlckAyLjAuMC9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci9zcmMvZXJyb3JzL2pzb24tcGFyc2UtZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXJAMi4wLjAvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXIvc3JjL2Vycm9ycy9sb2FkLWFwaS1rZXktZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXJAMi4wLjAvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXIvc3JjL2Vycm9ycy9sb2FkLXNldHRpbmctZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXJAMi4wLjAvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXIvc3JjL2Vycm9ycy9uby1jb250ZW50LWdlbmVyYXRlZC1lcnJvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlckAyLjAuMC9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci9zcmMvZXJyb3JzL25vLXN1Y2gtbW9kZWwtZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXJAMi4wLjAvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXIvc3JjL2Vycm9ycy90b28tbWFueS1lbWJlZGRpbmctdmFsdWVzLWZvci1jYWxsLWVycm9yLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyQDIuMC4wL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyL3NyYy9lcnJvcnMvdHlwZS12YWxpZGF0aW9uLWVycm9yLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyQDIuMC4wL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyL3NyYy9lcnJvcnMvdW5zdXBwb3J0ZWQtZnVuY3Rpb25hbGl0eS1lcnJvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlckAyLjAuMC9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci9zcmMvanNvbi12YWx1ZS9pcy1qc29uLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9ldmVudHNvdXJjZS1wYXJzZXJAMy4wLjYvbm9kZV9tb2R1bGVzL2V2ZW50c291cmNlLXBhcnNlci9zcmMvZXJyb3JzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9ldmVudHNvdXJjZS1wYXJzZXJAMy4wLjYvbm9kZV9tb2R1bGVzL2V2ZW50c291cmNlLXBhcnNlci9zcmMvcGFyc2UudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2V2ZW50c291cmNlLXBhcnNlckAzLjAuNi9ub2RlX21vZHVsZXMvZXZlbnRzb3VyY2UtcGFyc2VyL3NyYy9zdHJlYW0udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9jbGFzc2ljL2V4dGVybmFsLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvY29yZS9pbmRleC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2NvcmUvY29yZS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2NvcmUvdXRpbC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2NvcmUvZXJyb3JzLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvY29yZS9wYXJzZS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2NvcmUvcmVnZXhlcy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2NvcmUvY2hlY2tzLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvY29yZS9kb2MuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9jb3JlL3ZlcnNpb25zLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvY29yZS9zY2hlbWFzLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy9pbmRleC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2xvY2FsZXMvYXIuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL2F6LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy9iZS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2xvY2FsZXMvY2EuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL2NzLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy9kYS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2xvY2FsZXMvZGUuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL2VuLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy9lby5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2xvY2FsZXMvZXMuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL2ZhLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy9maS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2xvY2FsZXMvZnIuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL2ZyLUNBLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy9oZS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2xvY2FsZXMvaHUuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL2lkLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy9pcy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2xvY2FsZXMvaXQuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL2phLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy9rYS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2xvY2FsZXMva20uanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL2toLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy9rby5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2xvY2FsZXMvbHQuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL21rLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy9tcy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2xvY2FsZXMvbmwuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL25vLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy9vdGEuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL3BzLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy9wbC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2xvY2FsZXMvcHQuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL3J1LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy9zbC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2xvY2FsZXMvc3YuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL3RhLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy90aC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2xvY2FsZXMvdHIuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL3VrLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy91YS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2xvY2FsZXMvdXIuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL3ZpLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvbG9jYWxlcy96aC1DTi5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2xvY2FsZXMvemgtVFcuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9sb2NhbGVzL3lvLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvY29yZS9yZWdpc3RyaWVzLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvY29yZS9hcGkuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9jb3JlL3RvLWpzb24tc2NoZW1hLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvY29yZS9qc29uLXNjaGVtYS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2NsYXNzaWMvaXNvLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvY2xhc3NpYy9lcnJvcnMuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9jbGFzc2ljL3BhcnNlLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvY2xhc3NpYy9zY2hlbWFzLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjQvY2xhc3NpYy9jb21wYXQuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9jbGFzc2ljL2NvZXJjZS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3Y0L2NsYXNzaWMvaW5kZXguanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92NC9pbmRleC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3YzL2hlbHBlcnMvdXRpbC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3YzL1pvZEVycm9yLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjMvbG9jYWxlcy9lbi5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3YzL2Vycm9ycy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvem9kL3YzL2hlbHBlcnMvcGFyc2VVdGlsLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS96b2RANC4xLjExL25vZGVfbW9kdWxlcy96b2QvdjMvaGVscGVycy9lcnJvclV0aWwuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL3pvZC92My90eXBlcy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvY29tYmluZS1oZWFkZXJzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyLXV0aWxzQDMuMC4xMl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyLXV0aWxzL3NyYy9jb252ZXJ0LWFzeW5jLWl0ZXJhdG9yLXRvLXJlYWRhYmxlLXN0cmVhbS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvZGVsYXkudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL2V4dHJhY3QtcmVzcG9uc2UtaGVhZGVycy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvZ2VuZXJhdGUtaWQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL2dldC1lcnJvci1tZXNzYWdlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyLXV0aWxzQDMuMC4xMl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyLXV0aWxzL3NyYy9nZXQtZnJvbS1hcGkudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL2hhbmRsZS1mZXRjaC1lcnJvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvaXMtYWJvcnQtZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL2dldC1ydW50aW1lLWVudmlyb25tZW50LXVzZXItYWdlbnQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3JlbW92ZS11bmRlZmluZWQtZW50cmllcy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvd2l0aC11c2VyLWFnZW50LXN1ZmZpeC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvdmVyc2lvbi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvaW5qZWN0LWpzb24taW5zdHJ1Y3Rpb24udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL2lzLXVybC1zdXBwb3J0ZWQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL2xvYWQtYXBpLWtleS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvbG9hZC1vcHRpb25hbC1zZXR0aW5nLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyLXV0aWxzQDMuMC4xMl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyLXV0aWxzL3NyYy9sb2FkLXNldHRpbmcudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL21lZGlhLXR5cGUtdG8tZXh0ZW5zaW9uLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyLXV0aWxzQDMuMC4xMl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyLXV0aWxzL3NyYy9wYXJzZS1qc29uLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyLXV0aWxzQDMuMC4xMl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyLXV0aWxzL3NyYy9zZWN1cmUtanNvbi1wYXJzZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvdmFsaWRhdGUtdHlwZXMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3ZhbGlkYXRvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvcGFyc2UtanNvbi1ldmVudC1zdHJlYW0udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3BhcnNlLXByb3ZpZGVyLW9wdGlvbnMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3Bvc3QtdG8tYXBpLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyLXV0aWxzQDMuMC4xMl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyLXV0aWxzL3NyYy90eXBlcy90b29sLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyLXV0aWxzQDMuMC4xMl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyLXV0aWxzL3NyYy9wcm92aWRlci1kZWZpbmVkLXRvb2wtZmFjdG9yeS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvcmVzb2x2ZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvcmVzcG9uc2UtaGFuZGxlci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXNjaGVtYS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXRvLWpzb24tc2NoZW1hL2dldC1yZWxhdGl2ZS1wYXRoLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyLXV0aWxzQDMuMC4xMl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyLXV0aWxzL3NyYy96b2QtdG8tanNvbi1zY2hlbWEvb3B0aW9ucy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXRvLWpzb24tc2NoZW1hL3NlbGVjdC1wYXJzZXIudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3pvZC10by1qc29uLXNjaGVtYS9wYXJzZXJzL2FueS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXRvLWpzb24tc2NoZW1hL3BhcnNlcnMvYXJyYXkudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3pvZC10by1qc29uLXNjaGVtYS9wYXJzZXJzL2JpZ2ludC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXRvLWpzb24tc2NoZW1hL3BhcnNlcnMvYm9vbGVhbi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXRvLWpzb24tc2NoZW1hL3BhcnNlcnMvYnJhbmRlZC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXRvLWpzb24tc2NoZW1hL3BhcnNlcnMvY2F0Y2gudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3pvZC10by1qc29uLXNjaGVtYS9wYXJzZXJzL2RhdGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3pvZC10by1qc29uLXNjaGVtYS9wYXJzZXJzL2RlZmF1bHQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3pvZC10by1qc29uLXNjaGVtYS9wYXJzZXJzL2VmZmVjdHMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3pvZC10by1qc29uLXNjaGVtYS9wYXJzZXJzL2VudW0udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3pvZC10by1qc29uLXNjaGVtYS9wYXJzZXJzL2ludGVyc2VjdGlvbi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXRvLWpzb24tc2NoZW1hL3BhcnNlcnMvbGl0ZXJhbC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXRvLWpzb24tc2NoZW1hL3BhcnNlcnMvcmVjb3JkLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyLXV0aWxzQDMuMC4xMl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyLXV0aWxzL3NyYy96b2QtdG8tanNvbi1zY2hlbWEvcGFyc2Vycy9zdHJpbmcudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3pvZC10by1qc29uLXNjaGVtYS9wYXJzZXJzL21hcC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXRvLWpzb24tc2NoZW1hL3BhcnNlcnMvbmF0aXZlLWVudW0udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3pvZC10by1qc29uLXNjaGVtYS9wYXJzZXJzL25ldmVyLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyLXV0aWxzQDMuMC4xMl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyLXV0aWxzL3NyYy96b2QtdG8tanNvbi1zY2hlbWEvcGFyc2Vycy9udWxsLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyLXV0aWxzQDMuMC4xMl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyLXV0aWxzL3NyYy96b2QtdG8tanNvbi1zY2hlbWEvcGFyc2Vycy91bmlvbi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXRvLWpzb24tc2NoZW1hL3BhcnNlcnMvbnVsbGFibGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3pvZC10by1qc29uLXNjaGVtYS9wYXJzZXJzL251bWJlci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXRvLWpzb24tc2NoZW1hL3BhcnNlcnMvb2JqZWN0LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyLXV0aWxzQDMuMC4xMl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyLXV0aWxzL3NyYy96b2QtdG8tanNvbi1zY2hlbWEvcGFyc2Vycy9vcHRpb25hbC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXRvLWpzb24tc2NoZW1hL3BhcnNlcnMvcGlwZWxpbmUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3pvZC10by1qc29uLXNjaGVtYS9wYXJzZXJzL3Byb21pc2UudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3pvZC10by1qc29uLXNjaGVtYS9wYXJzZXJzL3NldC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXRvLWpzb24tc2NoZW1hL3BhcnNlcnMvdHVwbGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3pvZC10by1qc29uLXNjaGVtYS9wYXJzZXJzL3VuZGVmaW5lZC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXRvLWpzb24tc2NoZW1hL3BhcnNlcnMvdW5rbm93bi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvem9kLXRvLWpzb24tc2NoZW1hL3BhcnNlcnMvcmVhZG9ubHkudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3pvZC10by1qc29uLXNjaGVtYS9wYXJzZS1kZWYudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3pvZC10by1qc29uLXNjaGVtYS9yZWZzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyLXV0aWxzQDMuMC4xMl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyLXV0aWxzL3NyYy96b2QtdG8tanNvbi1zY2hlbWEvem9kLXRvLWpzb24tc2NoZW1hLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyLXV0aWxzQDMuMC4xMl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyLXV0aWxzL3NyYy96b2QtdG8tanNvbi1zY2hlbWEvaW5kZXgudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3NjaGVtYS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytwcm92aWRlci11dGlsc0AzLjAuMTJfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9wcm92aWRlci11dGlscy9zcmMvdWludDgtdXRpbHMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL3dpdGhvdXQtdHJhaWxpbmctc2xhc2gudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL2lzLWFzeW5jLWl0ZXJhYmxlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK3Byb3ZpZGVyLXV0aWxzQDMuMC4xMl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL3Byb3ZpZGVyLXV0aWxzL3NyYy90eXBlcy9leGVjdXRlLXRvb2wudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrcHJvdmlkZXItdXRpbHNAMy4wLjEyX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvcHJvdmlkZXItdXRpbHMvc3JjL2luZGV4LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK2dhdGV3YXlAMi4wLjBfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9nYXRld2F5L3NyYy9nYXRld2F5LXByb3ZpZGVyLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK2dhdGV3YXlAMi4wLjBfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9nYXRld2F5L3NyYy9lcnJvcnMvYXMtZ2F0ZXdheS1lcnJvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytnYXRld2F5QDIuMC4wX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvZ2F0ZXdheS9zcmMvZXJyb3JzL2NyZWF0ZS1nYXRld2F5LWVycm9yLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK2dhdGV3YXlAMi4wLjBfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9nYXRld2F5L3NyYy9lcnJvcnMvZ2F0ZXdheS1lcnJvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytnYXRld2F5QDIuMC4wX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvZ2F0ZXdheS9zcmMvZXJyb3JzL2dhdGV3YXktYXV0aGVudGljYXRpb24tZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrZ2F0ZXdheUAyLjAuMF96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL2dhdGV3YXkvc3JjL2Vycm9ycy9nYXRld2F5LWludmFsaWQtcmVxdWVzdC1lcnJvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytnYXRld2F5QDIuMC4wX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvZ2F0ZXdheS9zcmMvZXJyb3JzL2dhdGV3YXktcmF0ZS1saW1pdC1lcnJvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytnYXRld2F5QDIuMC4wX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvZ2F0ZXdheS9zcmMvZXJyb3JzL2dhdGV3YXktbW9kZWwtbm90LWZvdW5kLWVycm9yLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK2dhdGV3YXlAMi4wLjBfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9nYXRld2F5L3NyYy9lcnJvcnMvZ2F0ZXdheS1pbnRlcm5hbC1zZXJ2ZXItZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0BhaS1zZGsrZ2F0ZXdheUAyLjAuMF96b2RANC4xLjExL25vZGVfbW9kdWxlcy9AYWktc2RrL2dhdGV3YXkvc3JjL2Vycm9ycy9nYXRld2F5LXJlc3BvbnNlLWVycm9yLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK2dhdGV3YXlAMi4wLjBfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9nYXRld2F5L3NyYy9lcnJvcnMvZXh0cmFjdC1hcGktY2FsbC1yZXNwb25zZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytnYXRld2F5QDIuMC4wX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvZ2F0ZXdheS9zcmMvZXJyb3JzL3BhcnNlLWF1dGgtbWV0aG9kLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK2dhdGV3YXlAMi4wLjBfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9nYXRld2F5L3NyYy9nYXRld2F5LWZldGNoLW1ldGFkYXRhLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK2dhdGV3YXlAMi4wLjBfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9nYXRld2F5L3NyYy9nYXRld2F5LWxhbmd1YWdlLW1vZGVsLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK2dhdGV3YXlAMi4wLjBfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9nYXRld2F5L3NyYy9nYXRld2F5LWVtYmVkZGluZy1tb2RlbC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQGFpLXNkaytnYXRld2F5QDIuMC4wX3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL0BhaS1zZGsvZ2F0ZXdheS9zcmMvdmVyY2VsLWVudmlyb25tZW50LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AYWktc2RrK2dhdGV3YXlAMi4wLjBfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvQGFpLXNkay9nYXRld2F5L3NyYy92ZXJzaW9uLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL2luZGV4LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL2dlbmVyYXRlLXRleHQvZ2VuZXJhdGUtdGV4dC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9lcnJvci9uby1vdXRwdXQtc3BlY2lmaWVkLWVycm9yLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL2xvZ2dlci9sb2ctd2FybmluZ3MudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvbW9kZWwvcmVzb2x2ZS1tb2RlbC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9lcnJvci9pbmRleC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9lcnJvci9pbnZhbGlkLWFyZ3VtZW50LWVycm9yLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL2Vycm9yL2ludmFsaWQtc3RyZWFtLXBhcnQtZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvZXJyb3IvaW52YWxpZC10b29sLWlucHV0LWVycm9yLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL2Vycm9yL21jcC1jbGllbnQtZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvZXJyb3Ivbm8taW1hZ2UtZ2VuZXJhdGVkLWVycm9yLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL2Vycm9yL25vLW9iamVjdC1nZW5lcmF0ZWQtZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvZXJyb3Ivbm8tb3V0cHV0LWdlbmVyYXRlZC1lcnJvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9lcnJvci9uby1zcGVlY2gtZ2VuZXJhdGVkLWVycm9yLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL2Vycm9yL25vLXN1Y2gtdG9vbC1lcnJvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9lcnJvci90b29sLWNhbGwtcmVwYWlyLWVycm9yLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL2Vycm9yL3Vuc3VwcG9ydGVkLW1vZGVsLXZlcnNpb24tZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvcHJvbXB0L2ludmFsaWQtZGF0YS1jb250ZW50LWVycm9yLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3Byb21wdC9pbnZhbGlkLW1lc3NhZ2Utcm9sZS1lcnJvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9wcm9tcHQvbWVzc2FnZS1jb252ZXJzaW9uLWVycm9yLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3V0aWwvZG93bmxvYWQvZG93bmxvYWQtZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdXRpbC9yZXRyeS1lcnJvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9wcm9tcHQvY29udmVydC10by1sYW5ndWFnZS1tb2RlbC1wcm9tcHQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdXRpbC9kZXRlY3QtbWVkaWEtdHlwZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91dGlsL2Rvd25sb2FkL2Rvd25sb2FkLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3ZlcnNpb24udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdXRpbC9kb3dubG9hZC9kb3dubG9hZC1mdW5jdGlvbi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9wcm9tcHQvZGF0YS1jb250ZW50LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3Byb21wdC9zcGxpdC1kYXRhLXVybC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9wcm9tcHQvcHJlcGFyZS1jYWxsLXNldHRpbmdzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3Byb21wdC9wcmVwYXJlLXRvb2xzLWFuZC10b29sLWNob2ljZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91dGlsL2lzLW5vbi1lbXB0eS1vYmplY3QudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvcHJvbXB0L3N0YW5kYXJkaXplLXByb21wdC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9wcm9tcHQvbWVzc2FnZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy90eXBlcy9wcm92aWRlci1tZXRhZGF0YS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy90eXBlcy9qc29uLXZhbHVlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3Byb21wdC9jb250ZW50LXBhcnQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvcHJvbXB0L3dyYXAtZ2F0ZXdheS1lcnJvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy90ZWxlbWV0cnkvYXNzZW1ibGUtb3BlcmF0aW9uLW5hbWUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdGVsZW1ldHJ5L2dldC1iYXNlLXRlbGVtZXRyeS1hdHRyaWJ1dGVzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3RlbGVtZXRyeS9nZXQtdHJhY2VyLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3RlbGVtZXRyeS9ub29wLXRyYWNlci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy90ZWxlbWV0cnkvcmVjb3JkLXNwYW4udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdGVsZW1ldHJ5L3NlbGVjdC10ZWxlbWV0cnktYXR0cmlidXRlcy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy90ZWxlbWV0cnkvc3RyaW5naWZ5LWZvci10ZWxlbWV0cnkudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdHlwZXMvdXNhZ2UudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdXRpbC9hcy1hcnJheS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91dGlsL3JldHJ5LXdpdGgtZXhwb25lbnRpYWwtYmFja29mZi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91dGlsL3ByZXBhcmUtcmV0cmllcy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9nZW5lcmF0ZS10ZXh0L2V4dHJhY3QtdGV4dC1jb250ZW50LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL2dlbmVyYXRlLXRleHQvZ2VuZXJhdGVkLWZpbGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvZ2VuZXJhdGUtdGV4dC9wYXJzZS10b29sLWNhbGwudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvZ2VuZXJhdGUtdGV4dC9zdGVwLXJlc3VsdC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9nZW5lcmF0ZS10ZXh0L3N0b3AtY29uZGl0aW9uLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3Byb21wdC9jcmVhdGUtdG9vbC1tb2RlbC1vdXRwdXQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvZ2VuZXJhdGUtdGV4dC90by1yZXNwb25zZS1tZXNzYWdlcy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9nZW5lcmF0ZS10ZXh0L3N0cmVhbS10ZXh0LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3V0aWwvcHJlcGFyZS1oZWFkZXJzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3RleHQtc3RyZWFtL2NyZWF0ZS10ZXh0LXN0cmVhbS1yZXNwb25zZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91dGlsL3dyaXRlLXRvLXNlcnZlci1yZXNwb25zZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy90ZXh0LXN0cmVhbS9waXBlLXRleHQtc3RyZWFtLXRvLXJlc3BvbnNlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3VpLW1lc3NhZ2Utc3RyZWFtL2pzb24tdG8tc3NlLXRyYW5zZm9ybS1zdHJlYW0udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdWktbWVzc2FnZS1zdHJlYW0vdWktbWVzc2FnZS1zdHJlYW0taGVhZGVycy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91aS1tZXNzYWdlLXN0cmVhbS9jcmVhdGUtdWktbWVzc2FnZS1zdHJlYW0tcmVzcG9uc2UudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdWktbWVzc2FnZS1zdHJlYW0vZ2V0LXJlc3BvbnNlLXVpLW1lc3NhZ2UtaWQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdWkvcHJvY2Vzcy11aS1tZXNzYWdlLXN0cmVhbS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91aS1tZXNzYWdlLXN0cmVhbS91aS1tZXNzYWdlLWNodW5rcy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91dGlsL21lcmdlLW9iamVjdHMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdXRpbC9wYXJzZS1wYXJ0aWFsLWpzb24udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdXRpbC9maXgtanNvbi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91aS91aS1tZXNzYWdlcy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91aS1tZXNzYWdlLXN0cmVhbS9oYW5kbGUtdWktbWVzc2FnZS1zdHJlYW0tZmluaXNoLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3VpLW1lc3NhZ2Utc3RyZWFtL3BpcGUtdWktbWVzc2FnZS1zdHJlYW0tdG8tcmVzcG9uc2UudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdXRpbC9hc3luYy1pdGVyYWJsZS1zdHJlYW0udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdXRpbC9jb25zdW1lLXN0cmVhbS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91dGlsL2NyZWF0ZS1yZXNvbHZhYmxlLXByb21pc2UudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdXRpbC9jcmVhdGUtc3RpdGNoYWJsZS1zdHJlYW0udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdXRpbC9kZWxheWVkLXByb21pc2UudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdXRpbC9ub3cudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvZ2VuZXJhdGUtdGV4dC9ydW4tdG9vbHMtdHJhbnNmb3JtYXRpb24udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdWkvY29udmVydC10by1tb2RlbC1tZXNzYWdlcy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9hZ2VudC9hZ2VudC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9lbWJlZC9lbWJlZC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9lbWJlZC9lbWJlZC1tYW55LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3V0aWwvc3BsaXQtYXJyYXkudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvZ2VuZXJhdGUtaW1hZ2UvZ2VuZXJhdGUtaW1hZ2UudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvZ2VuZXJhdGUtb2JqZWN0L2dlbmVyYXRlLW9iamVjdC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9nZW5lcmF0ZS10ZXh0L2V4dHJhY3QtcmVhc29uaW5nLWNvbnRlbnQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvZ2VuZXJhdGUtb2JqZWN0L291dHB1dC1zdHJhdGVneS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9nZW5lcmF0ZS1vYmplY3QvcGFyc2UtYW5kLXZhbGlkYXRlLW9iamVjdC1yZXN1bHQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvZ2VuZXJhdGUtb2JqZWN0L3ZhbGlkYXRlLW9iamVjdC1nZW5lcmF0aW9uLWlucHV0LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL2dlbmVyYXRlLW9iamVjdC9zdHJlYW0tb2JqZWN0LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3V0aWwvY29zaW5lLXNpbWlsYXJpdHkudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdXRpbC9kYXRhLXVybC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91dGlsL2lzLWRlZXAtZXF1YWwtZGF0YS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91dGlsL3NlcmlhbC1qb2ItZXhlY3V0b3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdXRpbC9zaW11bGF0ZS1yZWFkYWJsZS1zdHJlYW0udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvZ2VuZXJhdGUtc3BlZWNoL2dlbmVyYXRlLXNwZWVjaC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9nZW5lcmF0ZS1zcGVlY2gvZ2VuZXJhdGVkLWF1ZGlvLWZpbGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvZ2VuZXJhdGUtdGV4dC9vdXRwdXQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvZ2VuZXJhdGUtdGV4dC9wcnVuZS1tZXNzYWdlcy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9nZW5lcmF0ZS10ZXh0L3Ntb290aC1zdHJlYW0udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvbWlkZGxld2FyZS9kZWZhdWx0LXNldHRpbmdzLW1pZGRsZXdhcmUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdXRpbC9nZXQtcG90ZW50aWFsLXN0YXJ0LWluZGV4LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL21pZGRsZXdhcmUvZXh0cmFjdC1yZWFzb25pbmctbWlkZGxld2FyZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9taWRkbGV3YXJlL3NpbXVsYXRlLXN0cmVhbWluZy1taWRkbGV3YXJlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL21pZGRsZXdhcmUvd3JhcC1sYW5ndWFnZS1tb2RlbC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy9taWRkbGV3YXJlL3dyYXAtcHJvdmlkZXIudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvcmVnaXN0cnkvY3VzdG9tLXByb3ZpZGVyLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3JlZ2lzdHJ5L25vLXN1Y2gtcHJvdmlkZXItZXJyb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvcmVnaXN0cnkvcHJvdmlkZXItcmVnaXN0cnkudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdG9vbC9tY3AvbWNwLWNsaWVudC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy90b29sL21jcC9tY3Atc3NlLXRyYW5zcG9ydC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy90b29sL21jcC9qc29uLXJwYy1tZXNzYWdlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3Rvb2wvbWNwL3R5cGVzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3Rvb2wvbWNwL21jcC10cmFuc3BvcnQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdHJhbnNjcmliZS90cmFuc2NyaWJlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL2Vycm9yL25vLXRyYW5zY3JpcHQtZ2VuZXJhdGVkLWVycm9yLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3VpL2NhbGwtY29tcGxldGlvbi1hcGkudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdWkvcHJvY2Vzcy10ZXh0LXN0cmVhbS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91aS9jaGF0LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3VpL2NvbnZlcnQtZmlsZS1saXN0LXRvLWZpbGUtdWktcGFydHMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2FpQDUuMC43Nl96b2RANC4xLjExL25vZGVfbW9kdWxlcy9haS9zcmMvdWkvZGVmYXVsdC1jaGF0LXRyYW5zcG9ydC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91aS9odHRwLWNoYXQtdHJhbnNwb3J0LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3VpL2xhc3QtYXNzaXN0YW50LW1lc3NhZ2UtaXMtY29tcGxldGUtd2l0aC10b29sLWNhbGxzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3VpL3RyYW5zZm9ybS10ZXh0LXRvLXVpLW1lc3NhZ2Utc3RyZWFtLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3VpL3RleHQtc3RyZWFtLWNoYXQtdHJhbnNwb3J0LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3VpL3ZhbGlkYXRlLXVpLW1lc3NhZ2VzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9haUA1LjAuNzZfem9kQDQuMS4xMS9ub2RlX21vZHVsZXMvYWkvc3JjL3VpLW1lc3NhZ2Utc3RyZWFtL2NyZWF0ZS11aS1tZXNzYWdlLXN0cmVhbS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYWlANS4wLjc2X3pvZEA0LjEuMTEvbm9kZV9tb2R1bGVzL2FpL3NyYy91aS1tZXNzYWdlLXN0cmVhbS9yZWFkLXVpLW1lc3NhZ2Utc3RyZWFtLnRzIiwgIi4uL2V4YW1wbGUvd29ya2Zsb3dzLzNfc3RyZWFtcy50cyIsICIuLi9leGFtcGxlL3dvcmtmbG93cy83X2Z1bGwudHMiLCAidmlydHVhbC1lbnRyeS5qcyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBIZWxwZXJzLlxuICovIHZhciBzID0gMTAwMDtcbnZhciBtID0gcyAqIDYwO1xudmFyIGggPSBtICogNjA7XG52YXIgZCA9IGggKiAyNDtcbnZhciB3ID0gZCAqIDc7XG52YXIgeSA9IGQgKiAzNjUuMjU7XG4vKipcbiAqIFBhcnNlIG9yIGZvcm1hdCB0aGUgZ2l2ZW4gYHZhbGAuXG4gKlxuICogT3B0aW9uczpcbiAqXG4gKiAgLSBgbG9uZ2AgdmVyYm9zZSBmb3JtYXR0aW5nIFtmYWxzZV1cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ3xOdW1iZXJ9IHZhbFxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICogQHRocm93cyB7RXJyb3J9IHRocm93IGFuIGVycm9yIGlmIHZhbCBpcyBub3QgYSBub24tZW1wdHkgc3RyaW5nIG9yIGEgbnVtYmVyXG4gKiBAcmV0dXJuIHtTdHJpbmd8TnVtYmVyfVxuICogQGFwaSBwdWJsaWNcbiAqLyBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKHZhbCwgb3B0aW9ucykge1xuICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICAgIHZhciB0eXBlID0gdHlwZW9mIHZhbDtcbiAgICBpZiAodHlwZSA9PT0gJ3N0cmluZycgJiYgdmFsLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmV0dXJuIHBhcnNlKHZhbCk7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJyAmJiBpc0Zpbml0ZSh2YWwpKSB7XG4gICAgICAgIHJldHVybiBvcHRpb25zLmxvbmcgPyBmbXRMb25nKHZhbCkgOiBmbXRTaG9ydCh2YWwpO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3ZhbCBpcyBub3QgYSBub24tZW1wdHkgc3RyaW5nIG9yIGEgdmFsaWQgbnVtYmVyLiB2YWw9JyArIEpTT04uc3RyaW5naWZ5KHZhbCkpO1xufTtcbi8qKlxuICogUGFyc2UgdGhlIGdpdmVuIGBzdHJgIGFuZCByZXR1cm4gbWlsbGlzZWNvbmRzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge051bWJlcn1cbiAqIEBhcGkgcHJpdmF0ZVxuICovIGZ1bmN0aW9uIHBhcnNlKHN0cikge1xuICAgIHN0ciA9IFN0cmluZyhzdHIpO1xuICAgIGlmIChzdHIubGVuZ3RoID4gMTAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIG1hdGNoID0gL14oLT8oPzpcXGQrKT9cXC4/XFxkKykgKihtaWxsaXNlY29uZHM/fG1zZWNzP3xtc3xzZWNvbmRzP3xzZWNzP3xzfG1pbnV0ZXM/fG1pbnM/fG18aG91cnM/fGhycz98aHxkYXlzP3xkfHdlZWtzP3x3fHllYXJzP3x5cnM/fHkpPyQvaS5leGVjKHN0cik7XG4gICAgaWYgKCFtYXRjaCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciBuID0gcGFyc2VGbG9hdChtYXRjaFsxXSk7XG4gICAgdmFyIHR5cGUgPSAobWF0Y2hbMl0gfHwgJ21zJykudG9Mb3dlckNhc2UoKTtcbiAgICBzd2l0Y2godHlwZSl7XG4gICAgICAgIGNhc2UgJ3llYXJzJzpcbiAgICAgICAgY2FzZSAneWVhcic6XG4gICAgICAgIGNhc2UgJ3lycyc6XG4gICAgICAgIGNhc2UgJ3lyJzpcbiAgICAgICAgY2FzZSAneSc6XG4gICAgICAgICAgICByZXR1cm4gbiAqIHk7XG4gICAgICAgIGNhc2UgJ3dlZWtzJzpcbiAgICAgICAgY2FzZSAnd2Vlayc6XG4gICAgICAgIGNhc2UgJ3cnOlxuICAgICAgICAgICAgcmV0dXJuIG4gKiB3O1xuICAgICAgICBjYXNlICdkYXlzJzpcbiAgICAgICAgY2FzZSAnZGF5JzpcbiAgICAgICAgY2FzZSAnZCc6XG4gICAgICAgICAgICByZXR1cm4gbiAqIGQ7XG4gICAgICAgIGNhc2UgJ2hvdXJzJzpcbiAgICAgICAgY2FzZSAnaG91cic6XG4gICAgICAgIGNhc2UgJ2hycyc6XG4gICAgICAgIGNhc2UgJ2hyJzpcbiAgICAgICAgY2FzZSAnaCc6XG4gICAgICAgICAgICByZXR1cm4gbiAqIGg7XG4gICAgICAgIGNhc2UgJ21pbnV0ZXMnOlxuICAgICAgICBjYXNlICdtaW51dGUnOlxuICAgICAgICBjYXNlICdtaW5zJzpcbiAgICAgICAgY2FzZSAnbWluJzpcbiAgICAgICAgY2FzZSAnbSc6XG4gICAgICAgICAgICByZXR1cm4gbiAqIG07XG4gICAgICAgIGNhc2UgJ3NlY29uZHMnOlxuICAgICAgICBjYXNlICdzZWNvbmQnOlxuICAgICAgICBjYXNlICdzZWNzJzpcbiAgICAgICAgY2FzZSAnc2VjJzpcbiAgICAgICAgY2FzZSAncyc6XG4gICAgICAgICAgICByZXR1cm4gbiAqIHM7XG4gICAgICAgIGNhc2UgJ21pbGxpc2Vjb25kcyc6XG4gICAgICAgIGNhc2UgJ21pbGxpc2Vjb25kJzpcbiAgICAgICAgY2FzZSAnbXNlY3MnOlxuICAgICAgICBjYXNlICdtc2VjJzpcbiAgICAgICAgY2FzZSAnbXMnOlxuICAgICAgICAgICAgcmV0dXJuIG47XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbn1cbi8qKlxuICogU2hvcnQgZm9ybWF0IGZvciBgbXNgLlxuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSBtc1xuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwcml2YXRlXG4gKi8gZnVuY3Rpb24gZm10U2hvcnQobXMpIHtcbiAgICB2YXIgbXNBYnMgPSBNYXRoLmFicyhtcyk7XG4gICAgaWYgKG1zQWJzID49IGQpIHtcbiAgICAgICAgcmV0dXJuIE1hdGgucm91bmQobXMgLyBkKSArICdkJztcbiAgICB9XG4gICAgaWYgKG1zQWJzID49IGgpIHtcbiAgICAgICAgcmV0dXJuIE1hdGgucm91bmQobXMgLyBoKSArICdoJztcbiAgICB9XG4gICAgaWYgKG1zQWJzID49IG0pIHtcbiAgICAgICAgcmV0dXJuIE1hdGgucm91bmQobXMgLyBtKSArICdtJztcbiAgICB9XG4gICAgaWYgKG1zQWJzID49IHMpIHtcbiAgICAgICAgcmV0dXJuIE1hdGgucm91bmQobXMgLyBzKSArICdzJztcbiAgICB9XG4gICAgcmV0dXJuIG1zICsgJ21zJztcbn1cbi8qKlxuICogTG9uZyBmb3JtYXQgZm9yIGBtc2AuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IG1zXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqLyBmdW5jdGlvbiBmbXRMb25nKG1zKSB7XG4gICAgdmFyIG1zQWJzID0gTWF0aC5hYnMobXMpO1xuICAgIGlmIChtc0FicyA+PSBkKSB7XG4gICAgICAgIHJldHVybiBwbHVyYWwobXMsIG1zQWJzLCBkLCAnZGF5Jyk7XG4gICAgfVxuICAgIGlmIChtc0FicyA+PSBoKSB7XG4gICAgICAgIHJldHVybiBwbHVyYWwobXMsIG1zQWJzLCBoLCAnaG91cicpO1xuICAgIH1cbiAgICBpZiAobXNBYnMgPj0gbSkge1xuICAgICAgICByZXR1cm4gcGx1cmFsKG1zLCBtc0FicywgbSwgJ21pbnV0ZScpO1xuICAgIH1cbiAgICBpZiAobXNBYnMgPj0gcykge1xuICAgICAgICByZXR1cm4gcGx1cmFsKG1zLCBtc0FicywgcywgJ3NlY29uZCcpO1xuICAgIH1cbiAgICByZXR1cm4gbXMgKyAnIG1zJztcbn1cbi8qKlxuICogUGx1cmFsaXphdGlvbiBoZWxwZXIuXG4gKi8gZnVuY3Rpb24gcGx1cmFsKG1zLCBtc0FicywgbiwgbmFtZSkge1xuICAgIHZhciBpc1BsdXJhbCA9IG1zQWJzID49IG4gKiAxLjU7XG4gICAgcmV0dXJuIE1hdGgucm91bmQobXMgLyBuKSArICcgJyArIG5hbWUgKyAoaXNQbHVyYWwgPyAncycgOiAnJyk7XG59XG4iLCAiLyoqXG4gKiBsb2Rhc2ggKEN1c3RvbSBCdWlsZCkgPGh0dHBzOi8vbG9kYXNoLmNvbS8+XG4gKiBCdWlsZDogYGxvZGFzaCBtb2R1bGFyaXplIGV4cG9ydHM9XCJucG1cIiAtbyAuL2BcbiAqIENvcHlyaWdodCBqUXVlcnkgRm91bmRhdGlvbiBhbmQgb3RoZXIgY29udHJpYnV0b3JzIDxodHRwczovL2pxdWVyeS5vcmcvPlxuICogUmVsZWFzZWQgdW5kZXIgTUlUIGxpY2Vuc2UgPGh0dHBzOi8vbG9kYXNoLmNvbS9saWNlbnNlPlxuICogQmFzZWQgb24gVW5kZXJzY29yZS5qcyAxLjguMyA8aHR0cDovL3VuZGVyc2NvcmVqcy5vcmcvTElDRU5TRT5cbiAqIENvcHlyaWdodCBKZXJlbXkgQXNoa2VuYXMsIERvY3VtZW50Q2xvdWQgYW5kIEludmVzdGlnYXRpdmUgUmVwb3J0ZXJzICYgRWRpdG9yc1xuICovIC8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqLyB2YXIgSU5GSU5JVFkgPSAxIC8gMCwgTUFYX1NBRkVfSU5URUdFUiA9IDkwMDcxOTkyNTQ3NDA5OTEsIE1BWF9JTlRFR0VSID0gMS43OTc2OTMxMzQ4NjIzMTU3ZSszMDgsIE5BTiA9IDAgLyAwO1xuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqLyB2YXIgZnVuY1RhZyA9ICdbb2JqZWN0IEZ1bmN0aW9uXScsIGdlblRhZyA9ICdbb2JqZWN0IEdlbmVyYXRvckZ1bmN0aW9uXScsIHN5bWJvbFRhZyA9ICdbb2JqZWN0IFN5bWJvbF0nO1xuLyoqIFVzZWQgdG8gbWF0Y2ggbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZS4gKi8gdmFyIHJlVHJpbSA9IC9eXFxzK3xcXHMrJC9nO1xuLyoqIFVzZWQgdG8gZGV0ZWN0IGJhZCBzaWduZWQgaGV4YWRlY2ltYWwgc3RyaW5nIHZhbHVlcy4gKi8gdmFyIHJlSXNCYWRIZXggPSAvXlstK10weFswLTlhLWZdKyQvaTtcbi8qKiBVc2VkIHRvIGRldGVjdCBiaW5hcnkgc3RyaW5nIHZhbHVlcy4gKi8gdmFyIHJlSXNCaW5hcnkgPSAvXjBiWzAxXSskL2k7XG4vKiogVXNlZCB0byBkZXRlY3Qgb2N0YWwgc3RyaW5nIHZhbHVlcy4gKi8gdmFyIHJlSXNPY3RhbCA9IC9eMG9bMC03XSskL2k7XG4vKiogVXNlZCB0byBkZXRlY3QgdW5zaWduZWQgaW50ZWdlciB2YWx1ZXMuICovIHZhciByZUlzVWludCA9IC9eKD86MHxbMS05XVxcZCopJC87XG4vKiogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgd2l0aG91dCBhIGRlcGVuZGVuY3kgb24gYHJvb3RgLiAqLyB2YXIgZnJlZVBhcnNlSW50ID0gcGFyc2VJbnQ7XG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovIHZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGVcbiAqIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovIHZhciBvYmplY3RUb1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqLyB2YXIgbmF0aXZlQ2VpbCA9IE1hdGguY2VpbCwgbmF0aXZlTWF4ID0gTWF0aC5tYXg7XG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnNsaWNlYCB3aXRob3V0IGFuIGl0ZXJhdGVlIGNhbGwgZ3VhcmQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzbGljZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9MF0gVGhlIHN0YXJ0IHBvc2l0aW9uLlxuICogQHBhcmFtIHtudW1iZXJ9IFtlbmQ9YXJyYXkubGVuZ3RoXSBUaGUgZW5kIHBvc2l0aW9uLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBzbGljZSBvZiBgYXJyYXlgLlxuICovIGZ1bmN0aW9uIGJhc2VTbGljZShhcnJheSwgc3RhcnQsIGVuZCkge1xuICAgIHZhciBpbmRleCA9IC0xLCBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG4gICAgaWYgKHN0YXJ0IDwgMCkge1xuICAgICAgICBzdGFydCA9IC1zdGFydCA+IGxlbmd0aCA/IDAgOiBsZW5ndGggKyBzdGFydDtcbiAgICB9XG4gICAgZW5kID0gZW5kID4gbGVuZ3RoID8gbGVuZ3RoIDogZW5kO1xuICAgIGlmIChlbmQgPCAwKSB7XG4gICAgICAgIGVuZCArPSBsZW5ndGg7XG4gICAgfVxuICAgIGxlbmd0aCA9IHN0YXJ0ID4gZW5kID8gMCA6IGVuZCAtIHN0YXJ0ID4+PiAwO1xuICAgIHN0YXJ0ID4+Pj0gMDtcbiAgICB2YXIgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKTtcbiAgICB3aGlsZSgrK2luZGV4IDwgbGVuZ3RoKXtcbiAgICAgICAgcmVzdWx0W2luZGV4XSA9IGFycmF5W2luZGV4ICsgc3RhcnRdO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGFycmF5LWxpa2UgaW5kZXguXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGg9TUFYX1NBRkVfSU5URUdFUl0gVGhlIHVwcGVyIGJvdW5kcyBvZiBhIHZhbGlkIGluZGV4LlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBpbmRleCwgZWxzZSBgZmFsc2VgLlxuICovIGZ1bmN0aW9uIGlzSW5kZXgodmFsdWUsIGxlbmd0aCkge1xuICAgIGxlbmd0aCA9IGxlbmd0aCA9PSBudWxsID8gTUFYX1NBRkVfSU5URUdFUiA6IGxlbmd0aDtcbiAgICByZXR1cm4gISFsZW5ndGggJiYgKHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyB8fCByZUlzVWludC50ZXN0KHZhbHVlKSkgJiYgdmFsdWUgPiAtMSAmJiB2YWx1ZSAlIDEgPT0gMCAmJiB2YWx1ZSA8IGxlbmd0aDtcbn1cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBhcmd1bWVudHMgYXJlIGZyb20gYW4gaXRlcmF0ZWUgY2FsbC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgcG90ZW50aWFsIGl0ZXJhdGVlIHZhbHVlIGFyZ3VtZW50LlxuICogQHBhcmFtIHsqfSBpbmRleCBUaGUgcG90ZW50aWFsIGl0ZXJhdGVlIGluZGV4IG9yIGtleSBhcmd1bWVudC5cbiAqIEBwYXJhbSB7Kn0gb2JqZWN0IFRoZSBwb3RlbnRpYWwgaXRlcmF0ZWUgb2JqZWN0IGFyZ3VtZW50LlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBhcmd1bWVudHMgYXJlIGZyb20gYW4gaXRlcmF0ZWUgY2FsbCxcbiAqICBlbHNlIGBmYWxzZWAuXG4gKi8gZnVuY3Rpb24gaXNJdGVyYXRlZUNhbGwodmFsdWUsIGluZGV4LCBvYmplY3QpIHtcbiAgICBpZiAoIWlzT2JqZWN0KG9iamVjdCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB2YXIgdHlwZSA9IHR5cGVvZiBpbmRleDtcbiAgICBpZiAodHlwZSA9PSAnbnVtYmVyJyA/IGlzQXJyYXlMaWtlKG9iamVjdCkgJiYgaXNJbmRleChpbmRleCwgb2JqZWN0Lmxlbmd0aCkgOiB0eXBlID09ICdzdHJpbmcnICYmIGluZGV4IGluIG9iamVjdCkge1xuICAgICAgICByZXR1cm4gZXEob2JqZWN0W2luZGV4XSwgdmFsdWUpO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgZWxlbWVudHMgc3BsaXQgaW50byBncm91cHMgdGhlIGxlbmd0aCBvZiBgc2l6ZWAuXG4gKiBJZiBgYXJyYXlgIGNhbid0IGJlIHNwbGl0IGV2ZW5seSwgdGhlIGZpbmFsIGNodW5rIHdpbGwgYmUgdGhlIHJlbWFpbmluZ1xuICogZWxlbWVudHMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAzLjAuMFxuICogQGNhdGVnb3J5IEFycmF5XG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcHJvY2Vzcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbc2l6ZT0xXSBUaGUgbGVuZ3RoIG9mIGVhY2ggY2h1bmtcbiAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBjaHVua3MuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uY2h1bmsoWydhJywgJ2InLCAnYycsICdkJ10sIDIpO1xuICogLy8gPT4gW1snYScsICdiJ10sIFsnYycsICdkJ11dXG4gKlxuICogXy5jaHVuayhbJ2EnLCAnYicsICdjJywgJ2QnXSwgMyk7XG4gKiAvLyA9PiBbWydhJywgJ2InLCAnYyddLCBbJ2QnXV1cbiAqLyBmdW5jdGlvbiBjaHVuayhhcnJheSwgc2l6ZSwgZ3VhcmQpIHtcbiAgICBpZiAoZ3VhcmQgPyBpc0l0ZXJhdGVlQ2FsbChhcnJheSwgc2l6ZSwgZ3VhcmQpIDogc2l6ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHNpemUgPSAxO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHNpemUgPSBuYXRpdmVNYXgodG9JbnRlZ2VyKHNpemUpLCAwKTtcbiAgICB9XG4gICAgdmFyIGxlbmd0aCA9IGFycmF5ID8gYXJyYXkubGVuZ3RoIDogMDtcbiAgICBpZiAoIWxlbmd0aCB8fCBzaXplIDwgMSkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIHZhciBpbmRleCA9IDAsIHJlc0luZGV4ID0gMCwgcmVzdWx0ID0gQXJyYXkobmF0aXZlQ2VpbChsZW5ndGggLyBzaXplKSk7XG4gICAgd2hpbGUoaW5kZXggPCBsZW5ndGgpe1xuICAgICAgICByZXN1bHRbcmVzSW5kZXgrK10gPSBiYXNlU2xpY2UoYXJyYXksIGluZGV4LCBpbmRleCArPSBzaXplKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbi8qKlxuICogUGVyZm9ybXMgYVxuICogW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAqIGNvbXBhcmlzb24gYmV0d2VlbiB0d28gdmFsdWVzIHRvIGRldGVybWluZSBpZiB0aGV5IGFyZSBlcXVpdmFsZW50LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4wLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgdmFsdWVzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBvYmplY3QgPSB7ICdhJzogMSB9O1xuICogdmFyIG90aGVyID0geyAnYSc6IDEgfTtcbiAqXG4gKiBfLmVxKG9iamVjdCwgb2JqZWN0KTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmVxKG9iamVjdCwgb3RoZXIpO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmVxKCdhJywgJ2EnKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmVxKCdhJywgT2JqZWN0KCdhJykpO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmVxKE5hTiwgTmFOKTtcbiAqIC8vID0+IHRydWVcbiAqLyBmdW5jdGlvbiBlcSh2YWx1ZSwgb3RoZXIpIHtcbiAgICByZXR1cm4gdmFsdWUgPT09IG90aGVyIHx8IHZhbHVlICE9PSB2YWx1ZSAmJiBvdGhlciAhPT0gb3RoZXI7XG59XG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGFycmF5LWxpa2UuIEEgdmFsdWUgaXMgY29uc2lkZXJlZCBhcnJheS1saWtlIGlmIGl0J3NcbiAqIG5vdCBhIGZ1bmN0aW9uIGFuZCBoYXMgYSBgdmFsdWUubGVuZ3RoYCB0aGF0J3MgYW4gaW50ZWdlciBncmVhdGVyIHRoYW4gb3JcbiAqIGVxdWFsIHRvIGAwYCBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIGBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUmAuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYXJyYXktbGlrZSwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzQXJyYXlMaWtlKFsxLCAyLCAzXSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0FycmF5TGlrZShkb2N1bWVudC5ib2R5LmNoaWxkcmVuKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzQXJyYXlMaWtlKCdhYmMnKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzQXJyYXlMaWtlKF8ubm9vcCk7XG4gKiAvLyA9PiBmYWxzZVxuICovIGZ1bmN0aW9uIGlzQXJyYXlMaWtlKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlICE9IG51bGwgJiYgaXNMZW5ndGgodmFsdWUubGVuZ3RoKSAmJiAhaXNGdW5jdGlvbih2YWx1ZSk7XG59XG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgRnVuY3Rpb25gIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMS4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIGZ1bmN0aW9uLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNGdW5jdGlvbihfKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzRnVuY3Rpb24oL2FiYy8pO1xuICogLy8gPT4gZmFsc2VcbiAqLyBmdW5jdGlvbiBpc0Z1bmN0aW9uKHZhbHVlKSB7XG4gICAgLy8gVGhlIHVzZSBvZiBgT2JqZWN0I3RvU3RyaW5nYCBhdm9pZHMgaXNzdWVzIHdpdGggdGhlIGB0eXBlb2ZgIG9wZXJhdG9yXG4gICAgLy8gaW4gU2FmYXJpIDgtOSB3aGljaCByZXR1cm5zICdvYmplY3QnIGZvciB0eXBlZCBhcnJheSBhbmQgb3RoZXIgY29uc3RydWN0b3JzLlxuICAgIHZhciB0YWcgPSBpc09iamVjdCh2YWx1ZSkgPyBvYmplY3RUb1N0cmluZy5jYWxsKHZhbHVlKSA6ICcnO1xuICAgIHJldHVybiB0YWcgPT0gZnVuY1RhZyB8fCB0YWcgPT0gZ2VuVGFnO1xufVxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGFycmF5LWxpa2UgbGVuZ3RoLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBsb29zZWx5IGJhc2VkIG9uXG4gKiBbYFRvTGVuZ3RoYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtdG9sZW5ndGgpLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4wLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgbGVuZ3RoLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNMZW5ndGgoMyk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0xlbmd0aChOdW1iZXIuTUlOX1ZBTFVFKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc0xlbmd0aChJbmZpbml0eSk7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uaXNMZW5ndGgoJzMnKTtcbiAqIC8vID0+IGZhbHNlXG4gKi8gZnVuY3Rpb24gaXNMZW5ndGgodmFsdWUpIHtcbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09ICdudW1iZXInICYmIHZhbHVlID4gLTEgJiYgdmFsdWUgJSAxID09IDAgJiYgdmFsdWUgPD0gTUFYX1NBRkVfSU5URUdFUjtcbn1cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgdGhlXG4gKiBbbGFuZ3VhZ2UgdHlwZV0oaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLWVjbWFzY3JpcHQtbGFuZ3VhZ2UtdHlwZXMpXG4gKiBvZiBgT2JqZWN0YC4gKGUuZy4gYXJyYXlzLCBmdW5jdGlvbnMsIG9iamVjdHMsIHJlZ2V4ZXMsIGBuZXcgTnVtYmVyKDApYCwgYW5kIGBuZXcgU3RyaW5nKCcnKWApXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAwLjEuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNPYmplY3Qoe30pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3QoWzEsIDIsIDNdKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0KF8ubm9vcCk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdChudWxsKTtcbiAqIC8vID0+IGZhbHNlXG4gKi8gZnVuY3Rpb24gaXNPYmplY3QodmFsdWUpIHtcbiAgICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgICByZXR1cm4gISF2YWx1ZSAmJiAodHlwZSA9PSAnb2JqZWN0JyB8fCB0eXBlID09ICdmdW5jdGlvbicpO1xufVxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBvYmplY3QtbGlrZS4gQSB2YWx1ZSBpcyBvYmplY3QtbGlrZSBpZiBpdCdzIG5vdCBgbnVsbGBcbiAqIGFuZCBoYXMgYSBgdHlwZW9mYCByZXN1bHQgb2YgXCJvYmplY3RcIi5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMC4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBvYmplY3QtbGlrZSwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzT2JqZWN0TGlrZSh7fSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdExpa2UoWzEsIDIsIDNdKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0TGlrZShfLm5vb3ApO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzT2JqZWN0TGlrZShudWxsKTtcbiAqIC8vID0+IGZhbHNlXG4gKi8gZnVuY3Rpb24gaXNPYmplY3RMaWtlKHZhbHVlKSB7XG4gICAgcmV0dXJuICEhdmFsdWUgJiYgdHlwZW9mIHZhbHVlID09ICdvYmplY3QnO1xufVxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYFN5bWJvbGAgcHJpbWl0aXZlIG9yIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMC4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHN5bWJvbCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzU3ltYm9sKFN5bWJvbC5pdGVyYXRvcik7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc1N5bWJvbCgnYWJjJyk7XG4gKiAvLyA9PiBmYWxzZVxuICovIGZ1bmN0aW9uIGlzU3ltYm9sKHZhbHVlKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnc3ltYm9sJyB8fCBpc09iamVjdExpa2UodmFsdWUpICYmIG9iamVjdFRvU3RyaW5nLmNhbGwodmFsdWUpID09IHN5bWJvbFRhZztcbn1cbi8qKlxuICogQ29udmVydHMgYHZhbHVlYCB0byBhIGZpbml0ZSBudW1iZXIuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjEyLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb252ZXJ0LlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgY29udmVydGVkIG51bWJlci5cbiAqIEBleGFtcGxlXG4gKlxuICogXy50b0Zpbml0ZSgzLjIpO1xuICogLy8gPT4gMy4yXG4gKlxuICogXy50b0Zpbml0ZShOdW1iZXIuTUlOX1ZBTFVFKTtcbiAqIC8vID0+IDVlLTMyNFxuICpcbiAqIF8udG9GaW5pdGUoSW5maW5pdHkpO1xuICogLy8gPT4gMS43OTc2OTMxMzQ4NjIzMTU3ZSszMDhcbiAqXG4gKiBfLnRvRmluaXRlKCczLjInKTtcbiAqIC8vID0+IDMuMlxuICovIGZ1bmN0aW9uIHRvRmluaXRlKHZhbHVlKSB7XG4gICAgaWYgKCF2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdmFsdWUgPT09IDAgPyB2YWx1ZSA6IDA7XG4gICAgfVxuICAgIHZhbHVlID0gdG9OdW1iZXIodmFsdWUpO1xuICAgIGlmICh2YWx1ZSA9PT0gSU5GSU5JVFkgfHwgdmFsdWUgPT09IC1JTkZJTklUWSkge1xuICAgICAgICB2YXIgc2lnbiA9IHZhbHVlIDwgMCA/IC0xIDogMTtcbiAgICAgICAgcmV0dXJuIHNpZ24gKiBNQVhfSU5URUdFUjtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlID09PSB2YWx1ZSA/IHZhbHVlIDogMDtcbn1cbi8qKlxuICogQ29udmVydHMgYHZhbHVlYCB0byBhbiBpbnRlZ2VyLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBsb29zZWx5IGJhc2VkIG9uXG4gKiBbYFRvSW50ZWdlcmBdKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy10b2ludGVnZXIpLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4wLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb252ZXJ0LlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgY29udmVydGVkIGludGVnZXIuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8udG9JbnRlZ2VyKDMuMik7XG4gKiAvLyA9PiAzXG4gKlxuICogXy50b0ludGVnZXIoTnVtYmVyLk1JTl9WQUxVRSk7XG4gKiAvLyA9PiAwXG4gKlxuICogXy50b0ludGVnZXIoSW5maW5pdHkpO1xuICogLy8gPT4gMS43OTc2OTMxMzQ4NjIzMTU3ZSszMDhcbiAqXG4gKiBfLnRvSW50ZWdlcignMy4yJyk7XG4gKiAvLyA9PiAzXG4gKi8gZnVuY3Rpb24gdG9JbnRlZ2VyKHZhbHVlKSB7XG4gICAgdmFyIHJlc3VsdCA9IHRvRmluaXRlKHZhbHVlKSwgcmVtYWluZGVyID0gcmVzdWx0ICUgMTtcbiAgICByZXR1cm4gcmVzdWx0ID09PSByZXN1bHQgPyByZW1haW5kZXIgPyByZXN1bHQgLSByZW1haW5kZXIgOiByZXN1bHQgOiAwO1xufVxuLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgbnVtYmVyLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4wLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwcm9jZXNzLlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgbnVtYmVyLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLnRvTnVtYmVyKDMuMik7XG4gKiAvLyA9PiAzLjJcbiAqXG4gKiBfLnRvTnVtYmVyKE51bWJlci5NSU5fVkFMVUUpO1xuICogLy8gPT4gNWUtMzI0XG4gKlxuICogXy50b051bWJlcihJbmZpbml0eSk7XG4gKiAvLyA9PiBJbmZpbml0eVxuICpcbiAqIF8udG9OdW1iZXIoJzMuMicpO1xuICogLy8gPT4gMy4yXG4gKi8gZnVuY3Rpb24gdG9OdW1iZXIodmFsdWUpIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09ICdudW1iZXInKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gICAgaWYgKGlzU3ltYm9sKHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gTkFOO1xuICAgIH1cbiAgICBpZiAoaXNPYmplY3QodmFsdWUpKSB7XG4gICAgICAgIHZhciBvdGhlciA9IHR5cGVvZiB2YWx1ZS52YWx1ZU9mID09ICdmdW5jdGlvbicgPyB2YWx1ZS52YWx1ZU9mKCkgOiB2YWx1ZTtcbiAgICAgICAgdmFsdWUgPSBpc09iamVjdChvdGhlcikgPyBvdGhlciArICcnIDogb3RoZXI7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdmFsdWUgIT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlID09PSAwID8gdmFsdWUgOiArdmFsdWU7XG4gICAgfVxuICAgIHZhbHVlID0gdmFsdWUucmVwbGFjZShyZVRyaW0sICcnKTtcbiAgICB2YXIgaXNCaW5hcnkgPSByZUlzQmluYXJ5LnRlc3QodmFsdWUpO1xuICAgIHJldHVybiBpc0JpbmFyeSB8fCByZUlzT2N0YWwudGVzdCh2YWx1ZSkgPyBmcmVlUGFyc2VJbnQodmFsdWUuc2xpY2UoMiksIGlzQmluYXJ5ID8gMiA6IDgpIDogcmVJc0JhZEhleC50ZXN0KHZhbHVlKSA/IE5BTiA6ICt2YWx1ZTtcbn1cbm1vZHVsZS5leHBvcnRzID0gY2h1bms7XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgX19kZWZQcm9wID0gT2JqZWN0LmRlZmluZVByb3BlcnR5O1xudmFyIF9fZ2V0T3duUHJvcERlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yO1xudmFyIF9fZ2V0T3duUHJvcE5hbWVzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXM7XG52YXIgX19oYXNPd25Qcm9wID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbnZhciBfX2V4cG9ydCA9ICh0YXJnZXQsIGFsbCk9PntcbiAgICBmb3IodmFyIG5hbWUgaW4gYWxsKV9fZGVmUHJvcCh0YXJnZXQsIG5hbWUsIHtcbiAgICAgICAgZ2V0OiBhbGxbbmFtZV0sXG4gICAgICAgIGVudW1lcmFibGU6IHRydWVcbiAgICB9KTtcbn07XG52YXIgX19jb3B5UHJvcHMgPSAodG8sIGZyb20sIGV4Y2VwdCwgZGVzYyk9PntcbiAgICBpZiAoZnJvbSAmJiB0eXBlb2YgZnJvbSA9PT0gXCJvYmplY3RcIiB8fCB0eXBlb2YgZnJvbSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGZvciAobGV0IGtleSBvZiBfX2dldE93blByb3BOYW1lcyhmcm9tKSlpZiAoIV9faGFzT3duUHJvcC5jYWxsKHRvLCBrZXkpICYmIGtleSAhPT0gZXhjZXB0KSBfX2RlZlByb3AodG8sIGtleSwge1xuICAgICAgICAgICAgZ2V0OiAoKT0+ZnJvbVtrZXldLFxuICAgICAgICAgICAgZW51bWVyYWJsZTogIShkZXNjID0gX19nZXRPd25Qcm9wRGVzYyhmcm9tLCBrZXkpKSB8fCBkZXNjLmVudW1lcmFibGVcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiB0bztcbn07XG52YXIgX190b0NvbW1vbkpTID0gKG1vZCk9Pl9fY29weVByb3BzKF9fZGVmUHJvcCh7fSwgXCJfX2VzTW9kdWxlXCIsIHtcbiAgICAgICAgdmFsdWU6IHRydWVcbiAgICB9KSwgbW9kKTtcbnZhciBnZXRfY29udGV4dF9leHBvcnRzID0ge307XG5fX2V4cG9ydChnZXRfY29udGV4dF9leHBvcnRzLCB7XG4gICAgU1lNQk9MX0ZPUl9SRVFfQ09OVEVYVDogKCk9PlNZTUJPTF9GT1JfUkVRX0NPTlRFWFQsXG4gICAgZ2V0Q29udGV4dDogKCk9PmdldENvbnRleHRcbn0pO1xubW9kdWxlLmV4cG9ydHMgPSBfX3RvQ29tbW9uSlMoZ2V0X2NvbnRleHRfZXhwb3J0cyk7XG5jb25zdCBTWU1CT0xfRk9SX1JFUV9DT05URVhUID0gU3ltYm9sLmZvcihcIkB2ZXJjZWwvcmVxdWVzdC1jb250ZXh0XCIpO1xuZnVuY3Rpb24gZ2V0Q29udGV4dCgpIHtcbiAgICBjb25zdCBmcm9tU3ltYm9sID0gZ2xvYmFsVGhpcztcbiAgICByZXR1cm4gZnJvbVN5bWJvbFtTWU1CT0xfRk9SX1JFUV9DT05URVhUXT8uZ2V0Py4oKSA/PyB7fTtcbn1cbi8vIEFubm90YXRlIHRoZSBDb21tb25KUyBleHBvcnQgbmFtZXMgZm9yIEVTTSBpbXBvcnQgaW4gbm9kZTpcbjAgJiYgKG1vZHVsZS5leHBvcnRzID0ge1xuICAgIFNZTUJPTF9GT1JfUkVRX0NPTlRFWFQsXG4gICAgZ2V0Q29udGV4dFxufSk7XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgX19kZWZQcm9wID0gT2JqZWN0LmRlZmluZVByb3BlcnR5O1xudmFyIF9fZ2V0T3duUHJvcERlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yO1xudmFyIF9fZ2V0T3duUHJvcE5hbWVzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXM7XG52YXIgX19oYXNPd25Qcm9wID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbnZhciBfX2V4cG9ydCA9ICh0YXJnZXQsIGFsbCk9PntcbiAgICBmb3IodmFyIG5hbWUgaW4gYWxsKV9fZGVmUHJvcCh0YXJnZXQsIG5hbWUsIHtcbiAgICAgICAgZ2V0OiBhbGxbbmFtZV0sXG4gICAgICAgIGVudW1lcmFibGU6IHRydWVcbiAgICB9KTtcbn07XG52YXIgX19jb3B5UHJvcHMgPSAodG8sIGZyb20sIGV4Y2VwdCwgZGVzYyk9PntcbiAgICBpZiAoZnJvbSAmJiB0eXBlb2YgZnJvbSA9PT0gXCJvYmplY3RcIiB8fCB0eXBlb2YgZnJvbSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGZvciAobGV0IGtleSBvZiBfX2dldE93blByb3BOYW1lcyhmcm9tKSlpZiAoIV9faGFzT3duUHJvcC5jYWxsKHRvLCBrZXkpICYmIGtleSAhPT0gZXhjZXB0KSBfX2RlZlByb3AodG8sIGtleSwge1xuICAgICAgICAgICAgZ2V0OiAoKT0+ZnJvbVtrZXldLFxuICAgICAgICAgICAgZW51bWVyYWJsZTogIShkZXNjID0gX19nZXRPd25Qcm9wRGVzYyhmcm9tLCBrZXkpKSB8fCBkZXNjLmVudW1lcmFibGVcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiB0bztcbn07XG52YXIgX190b0NvbW1vbkpTID0gKG1vZCk9Pl9fY29weVByb3BzKF9fZGVmUHJvcCh7fSwgXCJfX2VzTW9kdWxlXCIsIHtcbiAgICAgICAgdmFsdWU6IHRydWVcbiAgICB9KSwgbW9kKTtcbnZhciBpbmRleF9icm93c2VyX2V4cG9ydHMgPSB7fTtcbl9fZXhwb3J0KGluZGV4X2Jyb3dzZXJfZXhwb3J0cywge1xuICAgIGdldENvbnRleHQ6ICgpPT5pbXBvcnRfZ2V0X2NvbnRleHQuZ2V0Q29udGV4dCxcbiAgICBnZXRWZXJjZWxPaWRjVG9rZW46ICgpPT5nZXRWZXJjZWxPaWRjVG9rZW4sXG4gICAgZ2V0VmVyY2VsT2lkY1Rva2VuU3luYzogKCk9PmdldFZlcmNlbE9pZGNUb2tlblN5bmNcbn0pO1xubW9kdWxlLmV4cG9ydHMgPSBfX3RvQ29tbW9uSlMoaW5kZXhfYnJvd3Nlcl9leHBvcnRzKTtcbnZhciBpbXBvcnRfZ2V0X2NvbnRleHQgPSByZXF1aXJlKFwiLi9nZXQtY29udGV4dFwiKTtcbmFzeW5jIGZ1bmN0aW9uIGdldFZlcmNlbE9pZGNUb2tlbigpIHtcbiAgICByZXR1cm4gXCJcIjtcbn1cbmZ1bmN0aW9uIGdldFZlcmNlbE9pZGNUb2tlblN5bmMoKSB7XG4gICAgcmV0dXJuIFwiXCI7XG59XG4vLyBBbm5vdGF0ZSB0aGUgQ29tbW9uSlMgZXhwb3J0IG5hbWVzIGZvciBFU00gaW1wb3J0IGluIG5vZGU6XG4wICYmIChtb2R1bGUuZXhwb3J0cyA9IHtcbiAgICBnZXRDb250ZXh0LFxuICAgIGdldFZlcmNlbE9pZGNUb2tlbixcbiAgICBnZXRWZXJjZWxPaWRjVG9rZW5TeW5jXG59KTtcbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG4vKiogb25seSBnbG9iYWxzIHRoYXQgY29tbW9uIHRvIG5vZGUgYW5kIGJyb3dzZXJzIGFyZSBhbGxvd2VkICovXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm9kZS9uby11bnN1cHBvcnRlZC1mZWF0dXJlcy9lcy1idWlsdGluc1xuZXhwb3J0IGNvbnN0IF9nbG9iYWxUaGlzID0gdHlwZW9mIGdsb2JhbFRoaXMgPT09ICdvYmplY3QnID8gZ2xvYmFsVGhpcyA6IGdsb2JhbDtcbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5leHBvcnQgKiBmcm9tICcuL2dsb2JhbFRoaXMnO1xuIiwgIi8qXG4gKiBDb3B5cmlnaHQgVGhlIE9wZW5UZWxlbWV0cnkgQXV0aG9yc1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgIGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vbm9kZSc7XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuLy8gdGhpcyBpcyBhdXRvZ2VuZXJhdGVkIGZpbGUsIHNlZSBzY3JpcHRzL3ZlcnNpb24tdXBkYXRlLmpzXG5leHBvcnQgY29uc3QgVkVSU0lPTiA9ICcxLjkuMCc7XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuaW1wb3J0IHsgVkVSU0lPTiB9IGZyb20gJy4uL3ZlcnNpb24nO1xuXG5jb25zdCByZSA9IC9eKFxcZCspXFwuKFxcZCspXFwuKFxcZCspKC0oLispKT8kLztcblxuLyoqXG4gKiBDcmVhdGUgYSBmdW5jdGlvbiB0byB0ZXN0IGFuIEFQSSB2ZXJzaW9uIHRvIHNlZSBpZiBpdCBpcyBjb21wYXRpYmxlIHdpdGggdGhlIHByb3ZpZGVkIG93blZlcnNpb24uXG4gKlxuICogVGhlIHJldHVybmVkIGZ1bmN0aW9uIGhhcyB0aGUgZm9sbG93aW5nIHNlbWFudGljczpcbiAqIC0gRXhhY3QgbWF0Y2ggaXMgYWx3YXlzIGNvbXBhdGlibGVcbiAqIC0gTWFqb3IgdmVyc2lvbnMgbXVzdCBtYXRjaCBleGFjdGx5XG4gKiAgICAtIDEueCBwYWNrYWdlIGNhbm5vdCB1c2UgZ2xvYmFsIDIueCBwYWNrYWdlXG4gKiAgICAtIDIueCBwYWNrYWdlIGNhbm5vdCB1c2UgZ2xvYmFsIDEueCBwYWNrYWdlXG4gKiAtIFRoZSBtaW5vciB2ZXJzaW9uIG9mIHRoZSBBUEkgbW9kdWxlIHJlcXVlc3RpbmcgYWNjZXNzIHRvIHRoZSBnbG9iYWwgQVBJIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHRoZSBtaW5vciB2ZXJzaW9uIG9mIHRoaXMgQVBJXG4gKiAgICAtIDEuMyBwYWNrYWdlIG1heSB1c2UgMS40IGdsb2JhbCBiZWNhdXNlIHRoZSBsYXRlciBnbG9iYWwgY29udGFpbnMgYWxsIGZ1bmN0aW9ucyAxLjMgZXhwZWN0c1xuICogICAgLSAxLjQgcGFja2FnZSBtYXkgTk9UIHVzZSAxLjMgZ2xvYmFsIGJlY2F1c2UgaXQgbWF5IHRyeSB0byBjYWxsIGZ1bmN0aW9ucyB3aGljaCBkb24ndCBleGlzdCBvbiAxLjNcbiAqIC0gSWYgdGhlIG1ham9yIHZlcnNpb24gaXMgMCwgdGhlIG1pbm9yIHZlcnNpb24gaXMgdHJlYXRlZCBhcyB0aGUgbWFqb3IgYW5kIHRoZSBwYXRjaCBpcyB0cmVhdGVkIGFzIHRoZSBtaW5vclxuICogLSBQYXRjaCBhbmQgYnVpbGQgdGFnIGRpZmZlcmVuY2VzIGFyZSBub3QgY29uc2lkZXJlZCBhdCB0aGlzIHRpbWVcbiAqXG4gKiBAcGFyYW0gb3duVmVyc2lvbiB2ZXJzaW9uIHdoaWNoIHNob3VsZCBiZSBjaGVja2VkIGFnYWluc3RcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9tYWtlQ29tcGF0aWJpbGl0eUNoZWNrKFxuICBvd25WZXJzaW9uOiBzdHJpbmdcbik6IChnbG9iYWxWZXJzaW9uOiBzdHJpbmcpID0+IGJvb2xlYW4ge1xuICBjb25zdCBhY2NlcHRlZFZlcnNpb25zID0gbmV3IFNldDxzdHJpbmc+KFtvd25WZXJzaW9uXSk7XG4gIGNvbnN0IHJlamVjdGVkVmVyc2lvbnMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuICBjb25zdCBteVZlcnNpb25NYXRjaCA9IG93blZlcnNpb24ubWF0Y2gocmUpO1xuICBpZiAoIW15VmVyc2lvbk1hdGNoKSB7XG4gICAgLy8gd2UgY2Fubm90IGd1YXJhbnRlZSBjb21wYXRpYmlsaXR5IHNvIHdlIGFsd2F5cyByZXR1cm4gbm9vcFxuICAgIHJldHVybiAoKSA9PiBmYWxzZTtcbiAgfVxuXG4gIGNvbnN0IG93blZlcnNpb25QYXJzZWQgPSB7XG4gICAgbWFqb3I6ICtteVZlcnNpb25NYXRjaFsxXSxcbiAgICBtaW5vcjogK215VmVyc2lvbk1hdGNoWzJdLFxuICAgIHBhdGNoOiArbXlWZXJzaW9uTWF0Y2hbM10sXG4gICAgcHJlcmVsZWFzZTogbXlWZXJzaW9uTWF0Y2hbNF0sXG4gIH07XG5cbiAgLy8gaWYgb3duVmVyc2lvbiBoYXMgYSBwcmVyZWxlYXNlIHRhZywgdmVyc2lvbnMgbXVzdCBtYXRjaCBleGFjdGx5XG4gIGlmIChvd25WZXJzaW9uUGFyc2VkLnByZXJlbGVhc2UgIT0gbnVsbCkge1xuICAgIHJldHVybiBmdW5jdGlvbiBpc0V4YWN0bWF0Y2goZ2xvYmFsVmVyc2lvbjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICByZXR1cm4gZ2xvYmFsVmVyc2lvbiA9PT0gb3duVmVyc2lvbjtcbiAgICB9O1xuICB9XG5cbiAgZnVuY3Rpb24gX3JlamVjdCh2OiBzdHJpbmcpIHtcbiAgICByZWplY3RlZFZlcnNpb25zLmFkZCh2KTtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBmdW5jdGlvbiBfYWNjZXB0KHY6IHN0cmluZykge1xuICAgIGFjY2VwdGVkVmVyc2lvbnMuYWRkKHYpO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIGlzQ29tcGF0aWJsZShnbG9iYWxWZXJzaW9uOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBpZiAoYWNjZXB0ZWRWZXJzaW9ucy5oYXMoZ2xvYmFsVmVyc2lvbikpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGlmIChyZWplY3RlZFZlcnNpb25zLmhhcyhnbG9iYWxWZXJzaW9uKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IGdsb2JhbFZlcnNpb25NYXRjaCA9IGdsb2JhbFZlcnNpb24ubWF0Y2gocmUpO1xuICAgIGlmICghZ2xvYmFsVmVyc2lvbk1hdGNoKSB7XG4gICAgICAvLyBjYW5ub3QgcGFyc2Ugb3RoZXIgdmVyc2lvblxuICAgICAgLy8gd2UgY2Fubm90IGd1YXJhbnRlZSBjb21wYXRpYmlsaXR5IHNvIHdlIGFsd2F5cyBub29wXG4gICAgICByZXR1cm4gX3JlamVjdChnbG9iYWxWZXJzaW9uKTtcbiAgICB9XG5cbiAgICBjb25zdCBnbG9iYWxWZXJzaW9uUGFyc2VkID0ge1xuICAgICAgbWFqb3I6ICtnbG9iYWxWZXJzaW9uTWF0Y2hbMV0sXG4gICAgICBtaW5vcjogK2dsb2JhbFZlcnNpb25NYXRjaFsyXSxcbiAgICAgIHBhdGNoOiArZ2xvYmFsVmVyc2lvbk1hdGNoWzNdLFxuICAgICAgcHJlcmVsZWFzZTogZ2xvYmFsVmVyc2lvbk1hdGNoWzRdLFxuICAgIH07XG5cbiAgICAvLyBpZiBnbG9iYWxWZXJzaW9uIGhhcyBhIHByZXJlbGVhc2UgdGFnLCB2ZXJzaW9ucyBtdXN0IG1hdGNoIGV4YWN0bHlcbiAgICBpZiAoZ2xvYmFsVmVyc2lvblBhcnNlZC5wcmVyZWxlYXNlICE9IG51bGwpIHtcbiAgICAgIHJldHVybiBfcmVqZWN0KGdsb2JhbFZlcnNpb24pO1xuICAgIH1cblxuICAgIC8vIG1ham9yIHZlcnNpb25zIG11c3QgbWF0Y2hcbiAgICBpZiAob3duVmVyc2lvblBhcnNlZC5tYWpvciAhPT0gZ2xvYmFsVmVyc2lvblBhcnNlZC5tYWpvcikge1xuICAgICAgcmV0dXJuIF9yZWplY3QoZ2xvYmFsVmVyc2lvbik7XG4gICAgfVxuXG4gICAgaWYgKG93blZlcnNpb25QYXJzZWQubWFqb3IgPT09IDApIHtcbiAgICAgIGlmIChcbiAgICAgICAgb3duVmVyc2lvblBhcnNlZC5taW5vciA9PT0gZ2xvYmFsVmVyc2lvblBhcnNlZC5taW5vciAmJlxuICAgICAgICBvd25WZXJzaW9uUGFyc2VkLnBhdGNoIDw9IGdsb2JhbFZlcnNpb25QYXJzZWQucGF0Y2hcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gX2FjY2VwdChnbG9iYWxWZXJzaW9uKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIF9yZWplY3QoZ2xvYmFsVmVyc2lvbik7XG4gICAgfVxuXG4gICAgaWYgKG93blZlcnNpb25QYXJzZWQubWlub3IgPD0gZ2xvYmFsVmVyc2lvblBhcnNlZC5taW5vcikge1xuICAgICAgcmV0dXJuIF9hY2NlcHQoZ2xvYmFsVmVyc2lvbik7XG4gICAgfVxuXG4gICAgcmV0dXJuIF9yZWplY3QoZ2xvYmFsVmVyc2lvbik7XG4gIH07XG59XG5cbi8qKlxuICogVGVzdCBhbiBBUEkgdmVyc2lvbiB0byBzZWUgaWYgaXQgaXMgY29tcGF0aWJsZSB3aXRoIHRoaXMgQVBJLlxuICpcbiAqIC0gRXhhY3QgbWF0Y2ggaXMgYWx3YXlzIGNvbXBhdGlibGVcbiAqIC0gTWFqb3IgdmVyc2lvbnMgbXVzdCBtYXRjaCBleGFjdGx5XG4gKiAgICAtIDEueCBwYWNrYWdlIGNhbm5vdCB1c2UgZ2xvYmFsIDIueCBwYWNrYWdlXG4gKiAgICAtIDIueCBwYWNrYWdlIGNhbm5vdCB1c2UgZ2xvYmFsIDEueCBwYWNrYWdlXG4gKiAtIFRoZSBtaW5vciB2ZXJzaW9uIG9mIHRoZSBBUEkgbW9kdWxlIHJlcXVlc3RpbmcgYWNjZXNzIHRvIHRoZSBnbG9iYWwgQVBJIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHRoZSBtaW5vciB2ZXJzaW9uIG9mIHRoaXMgQVBJXG4gKiAgICAtIDEuMyBwYWNrYWdlIG1heSB1c2UgMS40IGdsb2JhbCBiZWNhdXNlIHRoZSBsYXRlciBnbG9iYWwgY29udGFpbnMgYWxsIGZ1bmN0aW9ucyAxLjMgZXhwZWN0c1xuICogICAgLSAxLjQgcGFja2FnZSBtYXkgTk9UIHVzZSAxLjMgZ2xvYmFsIGJlY2F1c2UgaXQgbWF5IHRyeSB0byBjYWxsIGZ1bmN0aW9ucyB3aGljaCBkb24ndCBleGlzdCBvbiAxLjNcbiAqIC0gSWYgdGhlIG1ham9yIHZlcnNpb24gaXMgMCwgdGhlIG1pbm9yIHZlcnNpb24gaXMgdHJlYXRlZCBhcyB0aGUgbWFqb3IgYW5kIHRoZSBwYXRjaCBpcyB0cmVhdGVkIGFzIHRoZSBtaW5vclxuICogLSBQYXRjaCBhbmQgYnVpbGQgdGFnIGRpZmZlcmVuY2VzIGFyZSBub3QgY29uc2lkZXJlZCBhdCB0aGlzIHRpbWVcbiAqXG4gKiBAcGFyYW0gdmVyc2lvbiB2ZXJzaW9uIG9mIHRoZSBBUEkgcmVxdWVzdGluZyBhbiBpbnN0YW5jZSBvZiB0aGUgZ2xvYmFsIEFQSVxuICovXG5leHBvcnQgY29uc3QgaXNDb21wYXRpYmxlID0gX21ha2VDb21wYXRpYmlsaXR5Q2hlY2soVkVSU0lPTik7XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuaW1wb3J0IHsgTWV0ZXJQcm92aWRlciB9IGZyb20gJy4uL21ldHJpY3MvTWV0ZXJQcm92aWRlcic7XG5pbXBvcnQgeyBDb250ZXh0TWFuYWdlciB9IGZyb20gJy4uL2NvbnRleHQvdHlwZXMnO1xuaW1wb3J0IHsgRGlhZ0xvZ2dlciB9IGZyb20gJy4uL2RpYWcvdHlwZXMnO1xuaW1wb3J0IHsgX2dsb2JhbFRoaXMgfSBmcm9tICcuLi9wbGF0Zm9ybSc7XG5pbXBvcnQgeyBUZXh0TWFwUHJvcGFnYXRvciB9IGZyb20gJy4uL3Byb3BhZ2F0aW9uL1RleHRNYXBQcm9wYWdhdG9yJztcbmltcG9ydCB0eXBlIHsgVHJhY2VyUHJvdmlkZXIgfSBmcm9tICcuLi90cmFjZS90cmFjZXJfcHJvdmlkZXInO1xuaW1wb3J0IHsgVkVSU0lPTiB9IGZyb20gJy4uL3ZlcnNpb24nO1xuaW1wb3J0IHsgaXNDb21wYXRpYmxlIH0gZnJvbSAnLi9zZW12ZXInO1xuXG5jb25zdCBtYWpvciA9IFZFUlNJT04uc3BsaXQoJy4nKVswXTtcbmNvbnN0IEdMT0JBTF9PUEVOVEVMRU1FVFJZX0FQSV9LRVkgPSBTeW1ib2wuZm9yKFxuICBgb3BlbnRlbGVtZXRyeS5qcy5hcGkuJHttYWpvcn1gXG4pO1xuXG5jb25zdCBfZ2xvYmFsID0gX2dsb2JhbFRoaXMgYXMgT1RlbEdsb2JhbDtcblxuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyR2xvYmFsPFR5cGUgZXh0ZW5kcyBrZXlvZiBPVGVsR2xvYmFsQVBJPihcbiAgdHlwZTogVHlwZSxcbiAgaW5zdGFuY2U6IE9UZWxHbG9iYWxBUElbVHlwZV0sXG4gIGRpYWc6IERpYWdMb2dnZXIsXG4gIGFsbG93T3ZlcnJpZGUgPSBmYWxzZVxuKTogYm9vbGVhbiB7XG4gIGNvbnN0IGFwaSA9IChfZ2xvYmFsW0dMT0JBTF9PUEVOVEVMRU1FVFJZX0FQSV9LRVldID0gX2dsb2JhbFtcbiAgICBHTE9CQUxfT1BFTlRFTEVNRVRSWV9BUElfS0VZXG4gIF0gPz8ge1xuICAgIHZlcnNpb246IFZFUlNJT04sXG4gIH0pO1xuXG4gIGlmICghYWxsb3dPdmVycmlkZSAmJiBhcGlbdHlwZV0pIHtcbiAgICAvLyBhbHJlYWR5IHJlZ2lzdGVyZWQgYW4gQVBJIG9mIHRoaXMgdHlwZVxuICAgIGNvbnN0IGVyciA9IG5ldyBFcnJvcihcbiAgICAgIGBAb3BlbnRlbGVtZXRyeS9hcGk6IEF0dGVtcHRlZCBkdXBsaWNhdGUgcmVnaXN0cmF0aW9uIG9mIEFQSTogJHt0eXBlfWBcbiAgICApO1xuICAgIGRpYWcuZXJyb3IoZXJyLnN0YWNrIHx8IGVyci5tZXNzYWdlKTtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAoYXBpLnZlcnNpb24gIT09IFZFUlNJT04pIHtcbiAgICAvLyBBbGwgcmVnaXN0ZXJlZCBBUElzIG11c3QgYmUgb2YgdGhlIHNhbWUgdmVyc2lvbiBleGFjdGx5XG4gICAgY29uc3QgZXJyID0gbmV3IEVycm9yKFxuICAgICAgYEBvcGVudGVsZW1ldHJ5L2FwaTogUmVnaXN0cmF0aW9uIG9mIHZlcnNpb24gdiR7YXBpLnZlcnNpb259IGZvciAke3R5cGV9IGRvZXMgbm90IG1hdGNoIHByZXZpb3VzbHkgcmVnaXN0ZXJlZCBBUEkgdiR7VkVSU0lPTn1gXG4gICAgKTtcbiAgICBkaWFnLmVycm9yKGVyci5zdGFjayB8fCBlcnIubWVzc2FnZSk7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgYXBpW3R5cGVdID0gaW5zdGFuY2U7XG4gIGRpYWcuZGVidWcoXG4gICAgYEBvcGVudGVsZW1ldHJ5L2FwaTogUmVnaXN0ZXJlZCBhIGdsb2JhbCBmb3IgJHt0eXBlfSB2JHtWRVJTSU9OfS5gXG4gICk7XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRHbG9iYWw8VHlwZSBleHRlbmRzIGtleW9mIE9UZWxHbG9iYWxBUEk+KFxuICB0eXBlOiBUeXBlXG4pOiBPVGVsR2xvYmFsQVBJW1R5cGVdIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgZ2xvYmFsVmVyc2lvbiA9IF9nbG9iYWxbR0xPQkFMX09QRU5URUxFTUVUUllfQVBJX0tFWV0/LnZlcnNpb247XG4gIGlmICghZ2xvYmFsVmVyc2lvbiB8fCAhaXNDb21wYXRpYmxlKGdsb2JhbFZlcnNpb24pKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHJldHVybiBfZ2xvYmFsW0dMT0JBTF9PUEVOVEVMRU1FVFJZX0FQSV9LRVldPy5bdHlwZV07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB1bnJlZ2lzdGVyR2xvYmFsKHR5cGU6IGtleW9mIE9UZWxHbG9iYWxBUEksIGRpYWc6IERpYWdMb2dnZXIpIHtcbiAgZGlhZy5kZWJ1ZyhcbiAgICBgQG9wZW50ZWxlbWV0cnkvYXBpOiBVbnJlZ2lzdGVyaW5nIGEgZ2xvYmFsIGZvciAke3R5cGV9IHYke1ZFUlNJT059LmBcbiAgKTtcbiAgY29uc3QgYXBpID0gX2dsb2JhbFtHTE9CQUxfT1BFTlRFTEVNRVRSWV9BUElfS0VZXTtcblxuICBpZiAoYXBpKSB7XG4gICAgZGVsZXRlIGFwaVt0eXBlXTtcbiAgfVxufVxuXG50eXBlIE9UZWxHbG9iYWwgPSB7XG4gIFtHTE9CQUxfT1BFTlRFTEVNRVRSWV9BUElfS0VZXT86IE9UZWxHbG9iYWxBUEk7XG59O1xuXG50eXBlIE9UZWxHbG9iYWxBUEkgPSB7XG4gIHZlcnNpb246IHN0cmluZztcblxuICBkaWFnPzogRGlhZ0xvZ2dlcjtcbiAgdHJhY2U/OiBUcmFjZXJQcm92aWRlcjtcbiAgY29udGV4dD86IENvbnRleHRNYW5hZ2VyO1xuICBtZXRyaWNzPzogTWV0ZXJQcm92aWRlcjtcbiAgcHJvcGFnYXRpb24/OiBUZXh0TWFwUHJvcGFnYXRvcjtcbn07XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuaW1wb3J0IHsgZ2V0R2xvYmFsIH0gZnJvbSAnLi4vaW50ZXJuYWwvZ2xvYmFsLXV0aWxzJztcbmltcG9ydCB7IENvbXBvbmVudExvZ2dlck9wdGlvbnMsIERpYWdMb2dnZXIsIERpYWdMb2dGdW5jdGlvbiB9IGZyb20gJy4vdHlwZXMnO1xuXG4vKipcbiAqIENvbXBvbmVudCBMb2dnZXIgd2hpY2ggaXMgbWVhbnQgdG8gYmUgdXNlZCBhcyBwYXJ0IG9mIGFueSBjb21wb25lbnQgd2hpY2hcbiAqIHdpbGwgYWRkIGF1dG9tYXRpY2FsbHkgYWRkaXRpb25hbCBuYW1lc3BhY2UgaW4gZnJvbnQgb2YgdGhlIGxvZyBtZXNzYWdlLlxuICogSXQgd2lsbCB0aGVuIGZvcndhcmQgYWxsIG1lc3NhZ2UgdG8gZ2xvYmFsIGRpYWcgbG9nZ2VyXG4gKiBAZXhhbXBsZVxuICogY29uc3QgY0xvZ2dlciA9IGRpYWcuY3JlYXRlQ29tcG9uZW50TG9nZ2VyKHsgbmFtZXNwYWNlOiAnQG9wZW50ZWxlbWV0cnkvaW5zdHJ1bWVudGF0aW9uLWh0dHAnIH0pO1xuICogY0xvZ2dlci5kZWJ1ZygndGVzdCcpO1xuICogLy8gQG9wZW50ZWxlbWV0cnkvaW5zdHJ1bWVudGF0aW9uLWh0dHAgdGVzdFxuICovXG5leHBvcnQgY2xhc3MgRGlhZ0NvbXBvbmVudExvZ2dlciBpbXBsZW1lbnRzIERpYWdMb2dnZXIge1xuICBwcml2YXRlIF9uYW1lc3BhY2U6IHN0cmluZztcblxuICBjb25zdHJ1Y3Rvcihwcm9wczogQ29tcG9uZW50TG9nZ2VyT3B0aW9ucykge1xuICAgIHRoaXMuX25hbWVzcGFjZSA9IHByb3BzLm5hbWVzcGFjZSB8fCAnRGlhZ0NvbXBvbmVudExvZ2dlcic7XG4gIH1cblxuICBwdWJsaWMgZGVidWcoLi4uYXJnczogYW55W10pOiB2b2lkIHtcbiAgICByZXR1cm4gbG9nUHJveHkoJ2RlYnVnJywgdGhpcy5fbmFtZXNwYWNlLCBhcmdzKTtcbiAgfVxuXG4gIHB1YmxpYyBlcnJvciguLi5hcmdzOiBhbnlbXSk6IHZvaWQge1xuICAgIHJldHVybiBsb2dQcm94eSgnZXJyb3InLCB0aGlzLl9uYW1lc3BhY2UsIGFyZ3MpO1xuICB9XG5cbiAgcHVibGljIGluZm8oLi4uYXJnczogYW55W10pOiB2b2lkIHtcbiAgICByZXR1cm4gbG9nUHJveHkoJ2luZm8nLCB0aGlzLl9uYW1lc3BhY2UsIGFyZ3MpO1xuICB9XG5cbiAgcHVibGljIHdhcm4oLi4uYXJnczogYW55W10pOiB2b2lkIHtcbiAgICByZXR1cm4gbG9nUHJveHkoJ3dhcm4nLCB0aGlzLl9uYW1lc3BhY2UsIGFyZ3MpO1xuICB9XG5cbiAgcHVibGljIHZlcmJvc2UoLi4uYXJnczogYW55W10pOiB2b2lkIHtcbiAgICByZXR1cm4gbG9nUHJveHkoJ3ZlcmJvc2UnLCB0aGlzLl9uYW1lc3BhY2UsIGFyZ3MpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGxvZ1Byb3h5KFxuICBmdW5jTmFtZToga2V5b2YgRGlhZ0xvZ2dlcixcbiAgbmFtZXNwYWNlOiBzdHJpbmcsXG4gIGFyZ3M6IGFueVxuKTogdm9pZCB7XG4gIGNvbnN0IGxvZ2dlciA9IGdldEdsb2JhbCgnZGlhZycpO1xuICAvLyBzaG9ydGN1dCBpZiBsb2dnZXIgbm90IHNldFxuICBpZiAoIWxvZ2dlcikge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGFyZ3MudW5zaGlmdChuYW1lc3BhY2UpO1xuICByZXR1cm4gbG9nZ2VyW2Z1bmNOYW1lXSguLi4oYXJncyBhcyBQYXJhbWV0ZXJzPERpYWdMb2dGdW5jdGlvbj4pKTtcbn1cbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5leHBvcnQgdHlwZSBEaWFnTG9nRnVuY3Rpb24gPSAobWVzc2FnZTogc3RyaW5nLCAuLi5hcmdzOiB1bmtub3duW10pID0+IHZvaWQ7XG5cbi8qKlxuICogRGVmaW5lcyBhbiBpbnRlcm5hbCBkaWFnbm9zdGljIGxvZ2dlciBpbnRlcmZhY2Ugd2hpY2ggaXMgdXNlZCB0byBsb2cgaW50ZXJuYWwgZGlhZ25vc3RpY1xuICogbWVzc2FnZXMsIHlvdSBjYW4gc2V0IHRoZSBkZWZhdWx0IGRpYWdub3N0aWMgbG9nZ2VyIHZpYSB0aGUge0BsaW5rIERpYWdBUEl9IHNldExvZ2dlciBmdW5jdGlvbi5cbiAqIEFQSSBwcm92aWRlZCBpbXBsZW1lbnRhdGlvbnMgaW5jbHVkZSA6LVxuICogLSBhIE5vLU9wIHtAbGluayBjcmVhdGVOb29wRGlhZ0xvZ2dlcn1cbiAqIC0gYSB7QGxpbmsgRGlhZ0xvZ0xldmVsfSBmaWx0ZXJpbmcgd3JhcHBlciB7QGxpbmsgY3JlYXRlTG9nTGV2ZWxEaWFnTG9nZ2VyfVxuICogLSBhIGdlbmVyYWwgQ29uc29sZSB7QGxpbmsgRGlhZ0NvbnNvbGVMb2dnZXJ9IHZlcnNpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRGlhZ0xvZ2dlciB7XG4gIC8qKiBMb2cgYW4gZXJyb3Igc2NlbmFyaW8gdGhhdCB3YXMgbm90IGV4cGVjdGVkIGFuZCBjYXVzZWQgdGhlIHJlcXVlc3RlZCBvcGVyYXRpb24gdG8gZmFpbC4gKi9cbiAgZXJyb3I6IERpYWdMb2dGdW5jdGlvbjtcblxuICAvKipcbiAgICogTG9nIGEgd2FybmluZyBzY2VuYXJpbyB0byBpbmZvcm0gdGhlIGRldmVsb3BlciBvZiBhbiBpc3N1ZXMgdGhhdCBzaG91bGQgYmUgaW52ZXN0aWdhdGVkLlxuICAgKiBUaGUgcmVxdWVzdGVkIG9wZXJhdGlvbiBtYXkgb3IgbWF5IG5vdCBoYXZlIHN1Y2NlZWRlZCBvciBjb21wbGV0ZWQuXG4gICAqL1xuICB3YXJuOiBEaWFnTG9nRnVuY3Rpb247XG5cbiAgLyoqXG4gICAqIExvZyBhIGdlbmVyYWwgaW5mb3JtYXRpb25hbCBtZXNzYWdlLCB0aGlzIHNob3VsZCBub3QgYWZmZWN0IGZ1bmN0aW9uYWxpdHkuXG4gICAqIFRoaXMgaXMgYWxzbyB0aGUgZGVmYXVsdCBsb2dnaW5nIGxldmVsIHNvIHRoaXMgc2hvdWxkIE5PVCBiZSB1c2VkIGZvciBsb2dnaW5nXG4gICAqIGRlYnVnZ2luZyBsZXZlbCBpbmZvcm1hdGlvbi5cbiAgICovXG4gIGluZm86IERpYWdMb2dGdW5jdGlvbjtcblxuICAvKipcbiAgICogTG9nIGEgZ2VuZXJhbCBkZWJ1ZyBtZXNzYWdlIHRoYXQgY2FuIGJlIHVzZWZ1bCBmb3IgaWRlbnRpZnlpbmcgYSBmYWlsdXJlLlxuICAgKiBJbmZvcm1hdGlvbiBsb2dnZWQgYXQgdGhpcyBsZXZlbCBtYXkgaW5jbHVkZSBkaWFnbm9zdGljIGRldGFpbHMgdGhhdCB3b3VsZFxuICAgKiBoZWxwIGlkZW50aWZ5IGEgZmFpbHVyZSBzY2VuYXJpby5cbiAgICogRm9yIGV4YW1wbGU6IExvZ2dpbmcgdGhlIG9yZGVyIG9mIGV4ZWN1dGlvbiBvZiBhc3luYyBvcGVyYXRpb25zLlxuICAgKi9cbiAgZGVidWc6IERpYWdMb2dGdW5jdGlvbjtcblxuICAvKipcbiAgICogTG9nIGEgZGV0YWlsZWQgKHZlcmJvc2UpIHRyYWNlIGxldmVsIGxvZ2dpbmcgdGhhdCBjYW4gYmUgdXNlZCB0byBpZGVudGlmeSBmYWlsdXJlc1xuICAgKiB3aGVyZSBkZWJ1ZyBsZXZlbCBsb2dnaW5nIHdvdWxkIGJlIGluc3VmZmljaWVudCwgdGhpcyBsZXZlbCBvZiB0cmFjaW5nIGNhbiBpbmNsdWRlXG4gICAqIGlucHV0IGFuZCBvdXRwdXQgcGFyYW1ldGVycyBhbmQgYXMgc3VjaCBtYXkgaW5jbHVkZSBQSUkgaW5mb3JtYXRpb24gcGFzc2luZyB0aHJvdWdoXG4gICAqIHRoZSBBUEkuIEFzIHN1Y2ggaXQgaXMgcmVjb21tZW5kZWQgdGhhdCB0aGlzIGxldmVsIG9mIHRyYWNpbmcgc2hvdWxkIG5vdCBiZSBlbmFibGVkXG4gICAqIGluIGEgcHJvZHVjdGlvbiBlbnZpcm9ubWVudC5cbiAgICovXG4gIHZlcmJvc2U6IERpYWdMb2dGdW5jdGlvbjtcbn1cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBhdmFpbGFibGUgaW50ZXJuYWwgbG9nZ2luZyBsZXZlbHMgZm9yIHRoZSBkaWFnbm9zdGljIGxvZ2dlciwgdGhlIG51bWVyaWMgdmFsdWVzXG4gKiBvZiB0aGUgbGV2ZWxzIGFyZSBkZWZpbmVkIHRvIG1hdGNoIHRoZSBvcmlnaW5hbCB2YWx1ZXMgZnJvbSB0aGUgaW5pdGlhbCBMb2dMZXZlbCB0byBhdm9pZFxuICogY29tcGF0aWJpbGl0eS9taWdyYXRpb24gaXNzdWVzIGZvciBhbnkgaW1wbGVtZW50YXRpb24gdGhhdCBhc3N1bWUgdGhlIG51bWVyaWMgb3JkZXJpbmcuXG4gKi9cbmV4cG9ydCBlbnVtIERpYWdMb2dMZXZlbCB7XG4gIC8qKiBEaWFnbm9zdGljIExvZ2dpbmcgbGV2ZWwgc2V0dGluZyB0byBkaXNhYmxlIGFsbCBsb2dnaW5nIChleGNlcHQgYW5kIGZvcmNlZCBsb2dzKSAqL1xuICBOT05FID0gMCxcblxuICAvKiogSWRlbnRpZmllcyBhbiBlcnJvciBzY2VuYXJpbyAqL1xuICBFUlJPUiA9IDMwLFxuXG4gIC8qKiBJZGVudGlmaWVzIGEgd2FybmluZyBzY2VuYXJpbyAqL1xuICBXQVJOID0gNTAsXG5cbiAgLyoqIEdlbmVyYWwgaW5mb3JtYXRpb25hbCBsb2cgbWVzc2FnZSAqL1xuICBJTkZPID0gNjAsXG5cbiAgLyoqIEdlbmVyYWwgZGVidWcgbG9nIG1lc3NhZ2UgKi9cbiAgREVCVUcgPSA3MCxcblxuICAvKipcbiAgICogRGV0YWlsZWQgdHJhY2UgbGV2ZWwgbG9nZ2luZyBzaG91bGQgb25seSBiZSB1c2VkIGZvciBkZXZlbG9wbWVudCwgc2hvdWxkIG9ubHkgYmUgc2V0XG4gICAqIGluIGEgZGV2ZWxvcG1lbnQgZW52aXJvbm1lbnQuXG4gICAqL1xuICBWRVJCT1NFID0gODAsXG5cbiAgLyoqIFVzZWQgdG8gc2V0IHRoZSBsb2dnaW5nIGxldmVsIHRvIGluY2x1ZGUgYWxsIGxvZ2dpbmcgKi9cbiAgQUxMID0gOTk5OSxcbn1cblxuLyoqXG4gKiBEZWZpbmVzIG9wdGlvbnMgZm9yIENvbXBvbmVudExvZ2dlclxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvbXBvbmVudExvZ2dlck9wdGlvbnMge1xuICBuYW1lc3BhY2U6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBEaWFnTG9nZ2VyT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUge0BsaW5rIERpYWdMb2dMZXZlbH0gdXNlZCB0byBmaWx0ZXIgbG9ncyBzZW50IHRvIHRoZSBsb2dnZXIuXG4gICAqXG4gICAqIEBkZWZhdWx0VmFsdWUgRGlhZ0xvZ0xldmVsLklORk9cbiAgICovXG4gIGxvZ0xldmVsPzogRGlhZ0xvZ0xldmVsO1xuXG4gIC8qKlxuICAgKiBTZXR0aW5nIHRoaXMgdmFsdWUgdG8gYHRydWVgIHdpbGwgc3VwcHJlc3MgdGhlIHdhcm5pbmcgbWVzc2FnZSBub3JtYWxseSBlbWl0dGVkIHdoZW4gcmVnaXN0ZXJpbmcgYSBsb2dnZXIgd2hlbiBhbm90aGVyIGxvZ2dlciBpcyBhbHJlYWR5IHJlZ2lzdGVyZWQuXG4gICAqL1xuICBzdXBwcmVzc092ZXJyaWRlTWVzc2FnZT86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGlhZ0xvZ2dlckFwaSB7XG4gIC8qKlxuICAgKiBTZXQgdGhlIGdsb2JhbCBEaWFnTG9nZ2VyIGFuZCBEaWFnTG9nTGV2ZWwuXG4gICAqIElmIGEgZ2xvYmFsIGRpYWcgbG9nZ2VyIGlzIGFscmVhZHkgc2V0LCB0aGlzIHdpbGwgb3ZlcnJpZGUgaXQuXG4gICAqXG4gICAqIEBwYXJhbSBsb2dnZXIgLSBUaGUge0BsaW5rIERpYWdMb2dnZXJ9IGluc3RhbmNlIHRvIHNldCBhcyB0aGUgZGVmYXVsdCBsb2dnZXIuXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gQSB7QGxpbmsgRGlhZ0xvZ2dlck9wdGlvbnN9IG9iamVjdC4gSWYgbm90IHByb3ZpZGVkLCBkZWZhdWx0IHZhbHVlcyB3aWxsIGJlIHNldC5cbiAgICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBsb2dnZXIgd2FzIHN1Y2Nlc3NmdWxseSByZWdpc3RlcmVkLCBlbHNlIGBmYWxzZWBcbiAgICovXG4gIHNldExvZ2dlcihsb2dnZXI6IERpYWdMb2dnZXIsIG9wdGlvbnM/OiBEaWFnTG9nZ2VyT3B0aW9ucyk6IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqXG4gICAqIEBwYXJhbSBsb2dnZXIgLSBUaGUge0BsaW5rIERpYWdMb2dnZXJ9IGluc3RhbmNlIHRvIHNldCBhcyB0aGUgZGVmYXVsdCBsb2dnZXIuXG4gICAqIEBwYXJhbSBsb2dMZXZlbCAtIFRoZSB7QGxpbmsgRGlhZ0xvZ0xldmVsfSB1c2VkIHRvIGZpbHRlciBsb2dzIHNlbnQgdG8gdGhlIGxvZ2dlci4gSWYgbm90IHByb3ZpZGVkIGl0IHdpbGwgZGVmYXVsdCB0byB7QGxpbmsgRGlhZ0xvZ0xldmVsLklORk99LlxuICAgKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGxvZ2dlciB3YXMgc3VjY2Vzc2Z1bGx5IHJlZ2lzdGVyZWQsIGVsc2UgYGZhbHNlYFxuICAgKi9cbiAgc2V0TG9nZ2VyKGxvZ2dlcjogRGlhZ0xvZ2dlciwgbG9nTGV2ZWw/OiBEaWFnTG9nTGV2ZWwpOiBib29sZWFuO1xufVxuIiwgIi8qXG4gKiBDb3B5cmlnaHQgVGhlIE9wZW5UZWxlbWV0cnkgQXV0aG9yc1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgIGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IERpYWdMb2dGdW5jdGlvbiwgRGlhZ0xvZ2dlciwgRGlhZ0xvZ0xldmVsIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlTG9nTGV2ZWxEaWFnTG9nZ2VyKFxuICBtYXhMZXZlbDogRGlhZ0xvZ0xldmVsLFxuICBsb2dnZXI6IERpYWdMb2dnZXJcbik6IERpYWdMb2dnZXIge1xuICBpZiAobWF4TGV2ZWwgPCBEaWFnTG9nTGV2ZWwuTk9ORSkge1xuICAgIG1heExldmVsID0gRGlhZ0xvZ0xldmVsLk5PTkU7XG4gIH0gZWxzZSBpZiAobWF4TGV2ZWwgPiBEaWFnTG9nTGV2ZWwuQUxMKSB7XG4gICAgbWF4TGV2ZWwgPSBEaWFnTG9nTGV2ZWwuQUxMO1xuICB9XG5cbiAgLy8gSW4gY2FzZSB0aGUgbG9nZ2VyIGlzIG51bGwgb3IgdW5kZWZpbmVkXG4gIGxvZ2dlciA9IGxvZ2dlciB8fCB7fTtcblxuICBmdW5jdGlvbiBfZmlsdGVyRnVuYyhcbiAgICBmdW5jTmFtZToga2V5b2YgRGlhZ0xvZ2dlcixcbiAgICB0aGVMZXZlbDogRGlhZ0xvZ0xldmVsXG4gICk6IERpYWdMb2dGdW5jdGlvbiB7XG4gICAgY29uc3QgdGhlRnVuYyA9IGxvZ2dlcltmdW5jTmFtZV07XG5cbiAgICBpZiAodHlwZW9mIHRoZUZ1bmMgPT09ICdmdW5jdGlvbicgJiYgbWF4TGV2ZWwgPj0gdGhlTGV2ZWwpIHtcbiAgICAgIHJldHVybiB0aGVGdW5jLmJpbmQobG9nZ2VyKTtcbiAgICB9XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHt9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBlcnJvcjogX2ZpbHRlckZ1bmMoJ2Vycm9yJywgRGlhZ0xvZ0xldmVsLkVSUk9SKSxcbiAgICB3YXJuOiBfZmlsdGVyRnVuYygnd2FybicsIERpYWdMb2dMZXZlbC5XQVJOKSxcbiAgICBpbmZvOiBfZmlsdGVyRnVuYygnaW5mbycsIERpYWdMb2dMZXZlbC5JTkZPKSxcbiAgICBkZWJ1ZzogX2ZpbHRlckZ1bmMoJ2RlYnVnJywgRGlhZ0xvZ0xldmVsLkRFQlVHKSxcbiAgICB2ZXJib3NlOiBfZmlsdGVyRnVuYygndmVyYm9zZScsIERpYWdMb2dMZXZlbC5WRVJCT1NFKSxcbiAgfTtcbn1cbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5pbXBvcnQgeyBEaWFnQ29tcG9uZW50TG9nZ2VyIH0gZnJvbSAnLi4vZGlhZy9Db21wb25lbnRMb2dnZXInO1xuaW1wb3J0IHsgY3JlYXRlTG9nTGV2ZWxEaWFnTG9nZ2VyIH0gZnJvbSAnLi4vZGlhZy9pbnRlcm5hbC9sb2dMZXZlbExvZ2dlcic7XG5pbXBvcnQge1xuICBDb21wb25lbnRMb2dnZXJPcHRpb25zLFxuICBEaWFnTG9nRnVuY3Rpb24sXG4gIERpYWdMb2dnZXIsXG4gIERpYWdMb2dnZXJBcGksXG4gIERpYWdMb2dMZXZlbCxcbn0gZnJvbSAnLi4vZGlhZy90eXBlcyc7XG5pbXBvcnQge1xuICBnZXRHbG9iYWwsXG4gIHJlZ2lzdGVyR2xvYmFsLFxuICB1bnJlZ2lzdGVyR2xvYmFsLFxufSBmcm9tICcuLi9pbnRlcm5hbC9nbG9iYWwtdXRpbHMnO1xuXG5jb25zdCBBUElfTkFNRSA9ICdkaWFnJztcblxuLyoqXG4gKiBTaW5nbGV0b24gb2JqZWN0IHdoaWNoIHJlcHJlc2VudHMgdGhlIGVudHJ5IHBvaW50IHRvIHRoZSBPcGVuVGVsZW1ldHJ5IGludGVybmFsXG4gKiBkaWFnbm9zdGljIEFQSVxuICovXG5leHBvcnQgY2xhc3MgRGlhZ0FQSSBpbXBsZW1lbnRzIERpYWdMb2dnZXIsIERpYWdMb2dnZXJBcGkge1xuICBwcml2YXRlIHN0YXRpYyBfaW5zdGFuY2U/OiBEaWFnQVBJO1xuXG4gIC8qKiBHZXQgdGhlIHNpbmdsZXRvbiBpbnN0YW5jZSBvZiB0aGUgRGlhZ0FQSSBBUEkgKi9cbiAgcHVibGljIHN0YXRpYyBpbnN0YW5jZSgpOiBEaWFnQVBJIHtcbiAgICBpZiAoIXRoaXMuX2luc3RhbmNlKSB7XG4gICAgICB0aGlzLl9pbnN0YW5jZSA9IG5ldyBEaWFnQVBJKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX2luc3RhbmNlO1xuICB9XG5cbiAgLyoqXG4gICAqIFByaXZhdGUgaW50ZXJuYWwgY29uc3RydWN0b3JcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgY29uc3RydWN0b3IoKSB7XG4gICAgZnVuY3Rpb24gX2xvZ1Byb3h5KGZ1bmNOYW1lOiBrZXlvZiBEaWFnTG9nZ2VyKTogRGlhZ0xvZ0Z1bmN0aW9uIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbiAoLi4uYXJncykge1xuICAgICAgICBjb25zdCBsb2dnZXIgPSBnZXRHbG9iYWwoJ2RpYWcnKTtcbiAgICAgICAgLy8gc2hvcnRjdXQgaWYgbG9nZ2VyIG5vdCBzZXRcbiAgICAgICAgaWYgKCFsb2dnZXIpIHJldHVybjtcbiAgICAgICAgcmV0dXJuIGxvZ2dlcltmdW5jTmFtZV0oLi4uYXJncyk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIFVzaW5nIHNlbGYgbG9jYWwgdmFyaWFibGUgZm9yIG1pbmlmaWNhdGlvbiBwdXJwb3NlcyBhcyAndGhpcycgY2Fubm90IGJlIG1pbmlmaWVkXG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICAvLyBEaWFnQVBJIHNwZWNpZmljIGZ1bmN0aW9uc1xuXG4gICAgY29uc3Qgc2V0TG9nZ2VyOiBEaWFnTG9nZ2VyQXBpWydzZXRMb2dnZXInXSA9IChcbiAgICAgIGxvZ2dlcixcbiAgICAgIG9wdGlvbnNPckxvZ0xldmVsID0geyBsb2dMZXZlbDogRGlhZ0xvZ0xldmVsLklORk8gfVxuICAgICkgPT4ge1xuICAgICAgaWYgKGxvZ2dlciA9PT0gc2VsZikge1xuICAgICAgICAvLyBUaGVyZSBpc24ndCBtdWNoIHdlIGNhbiBkbyBoZXJlLlxuICAgICAgICAvLyBMb2dnaW5nIHRvIHRoZSBjb25zb2xlIG1pZ2h0IGJyZWFrIHRoZSB1c2VyIGFwcGxpY2F0aW9uLlxuICAgICAgICAvLyBUcnkgdG8gbG9nIHRvIHNlbGYuIElmIGEgbG9nZ2VyIHdhcyBwcmV2aW91c2x5IHJlZ2lzdGVyZWQgaXQgd2lsbCByZWNlaXZlIHRoZSBsb2cuXG4gICAgICAgIGNvbnN0IGVyciA9IG5ldyBFcnJvcihcbiAgICAgICAgICAnQ2Fubm90IHVzZSBkaWFnIGFzIHRoZSBsb2dnZXIgZm9yIGl0c2VsZi4gUGxlYXNlIHVzZSBhIERpYWdMb2dnZXIgaW1wbGVtZW50YXRpb24gbGlrZSBDb25zb2xlRGlhZ0xvZ2dlciBvciBhIGN1c3RvbSBpbXBsZW1lbnRhdGlvbidcbiAgICAgICAgKTtcbiAgICAgICAgc2VsZi5lcnJvcihlcnIuc3RhY2sgPz8gZXJyLm1lc3NhZ2UpO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9uc09yTG9nTGV2ZWwgPT09ICdudW1iZXInKSB7XG4gICAgICAgIG9wdGlvbnNPckxvZ0xldmVsID0ge1xuICAgICAgICAgIGxvZ0xldmVsOiBvcHRpb25zT3JMb2dMZXZlbCxcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgb2xkTG9nZ2VyID0gZ2V0R2xvYmFsKCdkaWFnJyk7XG4gICAgICBjb25zdCBuZXdMb2dnZXIgPSBjcmVhdGVMb2dMZXZlbERpYWdMb2dnZXIoXG4gICAgICAgIG9wdGlvbnNPckxvZ0xldmVsLmxvZ0xldmVsID8/IERpYWdMb2dMZXZlbC5JTkZPLFxuICAgICAgICBsb2dnZXJcbiAgICAgICk7XG4gICAgICAvLyBUaGVyZSBhbHJlYWR5IGlzIGFuIGxvZ2dlciByZWdpc3RlcmVkLiBXZSdsbCBsZXQgaXQga25vdyBiZWZvcmUgb3ZlcndyaXRpbmcgaXQuXG4gICAgICBpZiAob2xkTG9nZ2VyICYmICFvcHRpb25zT3JMb2dMZXZlbC5zdXBwcmVzc092ZXJyaWRlTWVzc2FnZSkge1xuICAgICAgICBjb25zdCBzdGFjayA9IG5ldyBFcnJvcigpLnN0YWNrID8/ICc8ZmFpbGVkIHRvIGdlbmVyYXRlIHN0YWNrdHJhY2U+JztcbiAgICAgICAgb2xkTG9nZ2VyLndhcm4oYEN1cnJlbnQgbG9nZ2VyIHdpbGwgYmUgb3ZlcndyaXR0ZW4gZnJvbSAke3N0YWNrfWApO1xuICAgICAgICBuZXdMb2dnZXIud2FybihcbiAgICAgICAgICBgQ3VycmVudCBsb2dnZXIgd2lsbCBvdmVyd3JpdGUgb25lIGFscmVhZHkgcmVnaXN0ZXJlZCBmcm9tICR7c3RhY2t9YFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVnaXN0ZXJHbG9iYWwoJ2RpYWcnLCBuZXdMb2dnZXIsIHNlbGYsIHRydWUpO1xuICAgIH07XG5cbiAgICBzZWxmLnNldExvZ2dlciA9IHNldExvZ2dlcjtcblxuICAgIHNlbGYuZGlzYWJsZSA9ICgpID0+IHtcbiAgICAgIHVucmVnaXN0ZXJHbG9iYWwoQVBJX05BTUUsIHNlbGYpO1xuICAgIH07XG5cbiAgICBzZWxmLmNyZWF0ZUNvbXBvbmVudExvZ2dlciA9IChvcHRpb25zOiBDb21wb25lbnRMb2dnZXJPcHRpb25zKSA9PiB7XG4gICAgICByZXR1cm4gbmV3IERpYWdDb21wb25lbnRMb2dnZXIob3B0aW9ucyk7XG4gICAgfTtcblxuICAgIHNlbGYudmVyYm9zZSA9IF9sb2dQcm94eSgndmVyYm9zZScpO1xuICAgIHNlbGYuZGVidWcgPSBfbG9nUHJveHkoJ2RlYnVnJyk7XG4gICAgc2VsZi5pbmZvID0gX2xvZ1Byb3h5KCdpbmZvJyk7XG4gICAgc2VsZi53YXJuID0gX2xvZ1Byb3h5KCd3YXJuJyk7XG4gICAgc2VsZi5lcnJvciA9IF9sb2dQcm94eSgnZXJyb3InKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRMb2dnZXIhOiBEaWFnTG9nZ2VyQXBpWydzZXRMb2dnZXInXTtcbiAgLyoqXG4gICAqXG4gICAqL1xuICBwdWJsaWMgY3JlYXRlQ29tcG9uZW50TG9nZ2VyITogKFxuICAgIG9wdGlvbnM6IENvbXBvbmVudExvZ2dlck9wdGlvbnNcbiAgKSA9PiBEaWFnTG9nZ2VyO1xuXG4gIC8vIERpYWdMb2dnZXIgaW1wbGVtZW50YXRpb25cbiAgcHVibGljIHZlcmJvc2UhOiBEaWFnTG9nRnVuY3Rpb247XG4gIHB1YmxpYyBkZWJ1ZyE6IERpYWdMb2dGdW5jdGlvbjtcbiAgcHVibGljIGluZm8hOiBEaWFnTG9nRnVuY3Rpb247XG4gIHB1YmxpYyB3YXJuITogRGlhZ0xvZ0Z1bmN0aW9uO1xuICBwdWJsaWMgZXJyb3IhOiBEaWFnTG9nRnVuY3Rpb247XG5cbiAgLyoqXG4gICAqIFVucmVnaXN0ZXIgdGhlIGdsb2JhbCBsb2dnZXIgYW5kIHJldHVybiB0byBOb29wXG4gICAqL1xuICBwdWJsaWMgZGlzYWJsZSE6ICgpID0+IHZvaWQ7XG59XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBCYWdnYWdlLCBCYWdnYWdlRW50cnkgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBjbGFzcyBCYWdnYWdlSW1wbCBpbXBsZW1lbnRzIEJhZ2dhZ2Uge1xuICBwcml2YXRlIF9lbnRyaWVzOiBNYXA8c3RyaW5nLCBCYWdnYWdlRW50cnk+O1xuXG4gIGNvbnN0cnVjdG9yKGVudHJpZXM/OiBNYXA8c3RyaW5nLCBCYWdnYWdlRW50cnk+KSB7XG4gICAgdGhpcy5fZW50cmllcyA9IGVudHJpZXMgPyBuZXcgTWFwKGVudHJpZXMpIDogbmV3IE1hcCgpO1xuICB9XG5cbiAgZ2V0RW50cnkoa2V5OiBzdHJpbmcpOiBCYWdnYWdlRW50cnkgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGVudHJ5ID0gdGhpcy5fZW50cmllcy5nZXQoa2V5KTtcbiAgICBpZiAoIWVudHJ5KSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBlbnRyeSk7XG4gIH1cblxuICBnZXRBbGxFbnRyaWVzKCk6IFtzdHJpbmcsIEJhZ2dhZ2VFbnRyeV1bXSB7XG4gICAgcmV0dXJuIEFycmF5LmZyb20odGhpcy5fZW50cmllcy5lbnRyaWVzKCkpLm1hcCgoW2ssIHZdKSA9PiBbaywgdl0pO1xuICB9XG5cbiAgc2V0RW50cnkoa2V5OiBzdHJpbmcsIGVudHJ5OiBCYWdnYWdlRW50cnkpOiBCYWdnYWdlSW1wbCB7XG4gICAgY29uc3QgbmV3QmFnZ2FnZSA9IG5ldyBCYWdnYWdlSW1wbCh0aGlzLl9lbnRyaWVzKTtcbiAgICBuZXdCYWdnYWdlLl9lbnRyaWVzLnNldChrZXksIGVudHJ5KTtcbiAgICByZXR1cm4gbmV3QmFnZ2FnZTtcbiAgfVxuXG4gIHJlbW92ZUVudHJ5KGtleTogc3RyaW5nKTogQmFnZ2FnZUltcGwge1xuICAgIGNvbnN0IG5ld0JhZ2dhZ2UgPSBuZXcgQmFnZ2FnZUltcGwodGhpcy5fZW50cmllcyk7XG4gICAgbmV3QmFnZ2FnZS5fZW50cmllcy5kZWxldGUoa2V5KTtcbiAgICByZXR1cm4gbmV3QmFnZ2FnZTtcbiAgfVxuXG4gIHJlbW92ZUVudHJpZXMoLi4ua2V5czogc3RyaW5nW10pOiBCYWdnYWdlSW1wbCB7XG4gICAgY29uc3QgbmV3QmFnZ2FnZSA9IG5ldyBCYWdnYWdlSW1wbCh0aGlzLl9lbnRyaWVzKTtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzKSB7XG4gICAgICBuZXdCYWdnYWdlLl9lbnRyaWVzLmRlbGV0ZShrZXkpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3QmFnZ2FnZTtcbiAgfVxuXG4gIGNsZWFyKCk6IEJhZ2dhZ2VJbXBsIHtcbiAgICByZXR1cm4gbmV3IEJhZ2dhZ2VJbXBsKCk7XG4gIH1cbn1cbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG4vKipcbiAqIFN5bWJvbCB1c2VkIHRvIG1ha2UgQmFnZ2FnZUVudHJ5TWV0YWRhdGEgYW4gb3BhcXVlIHR5cGVcbiAqL1xuZXhwb3J0IGNvbnN0IGJhZ2dhZ2VFbnRyeU1ldGFkYXRhU3ltYm9sID0gU3ltYm9sKCdCYWdnYWdlRW50cnlNZXRhZGF0YScpO1xuIiwgIi8qXG4gKiBDb3B5cmlnaHQgVGhlIE9wZW5UZWxlbWV0cnkgQXV0aG9yc1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgIGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IERpYWdBUEkgfSBmcm9tICcuLi9hcGkvZGlhZyc7XG5pbXBvcnQgeyBCYWdnYWdlSW1wbCB9IGZyb20gJy4vaW50ZXJuYWwvYmFnZ2FnZS1pbXBsJztcbmltcG9ydCB7IGJhZ2dhZ2VFbnRyeU1ldGFkYXRhU3ltYm9sIH0gZnJvbSAnLi9pbnRlcm5hbC9zeW1ib2wnO1xuaW1wb3J0IHsgQmFnZ2FnZSwgQmFnZ2FnZUVudHJ5LCBCYWdnYWdlRW50cnlNZXRhZGF0YSB9IGZyb20gJy4vdHlwZXMnO1xuXG5jb25zdCBkaWFnID0gRGlhZ0FQSS5pbnN0YW5jZSgpO1xuXG4vKipcbiAqIENyZWF0ZSBhIG5ldyBCYWdnYWdlIHdpdGggb3B0aW9uYWwgZW50cmllc1xuICpcbiAqIEBwYXJhbSBlbnRyaWVzIEFuIGFycmF5IG9mIGJhZ2dhZ2UgZW50cmllcyB0aGUgbmV3IGJhZ2dhZ2Ugc2hvdWxkIGNvbnRhaW5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUJhZ2dhZ2UoXG4gIGVudHJpZXM6IFJlY29yZDxzdHJpbmcsIEJhZ2dhZ2VFbnRyeT4gPSB7fVxuKTogQmFnZ2FnZSB7XG4gIHJldHVybiBuZXcgQmFnZ2FnZUltcGwobmV3IE1hcChPYmplY3QuZW50cmllcyhlbnRyaWVzKSkpO1xufVxuXG4vKipcbiAqIENyZWF0ZSBhIHNlcmlhbGl6YWJsZSBCYWdnYWdlRW50cnlNZXRhZGF0YSBvYmplY3QgZnJvbSBhIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0gc3RyIHN0cmluZyBtZXRhZGF0YS4gRm9ybWF0IGlzIGN1cnJlbnRseSBub3QgZGVmaW5lZCBieSB0aGUgc3BlYyBhbmQgaGFzIG5vIHNwZWNpYWwgbWVhbmluZy5cbiAqXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBiYWdnYWdlRW50cnlNZXRhZGF0YUZyb21TdHJpbmcoXG4gIHN0cjogc3RyaW5nXG4pOiBCYWdnYWdlRW50cnlNZXRhZGF0YSB7XG4gIGlmICh0eXBlb2Ygc3RyICE9PSAnc3RyaW5nJykge1xuICAgIGRpYWcuZXJyb3IoXG4gICAgICBgQ2Fubm90IGNyZWF0ZSBiYWdnYWdlIG1ldGFkYXRhIGZyb20gdW5rbm93biB0eXBlOiAke3R5cGVvZiBzdHJ9YFxuICAgICk7XG4gICAgc3RyID0gJyc7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIF9fVFlQRV9fOiBiYWdnYWdlRW50cnlNZXRhZGF0YVN5bWJvbCxcbiAgICB0b1N0cmluZygpIHtcbiAgICAgIHJldHVybiBzdHI7XG4gICAgfSxcbiAgfTtcbn1cbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5pbXBvcnQgeyBDb250ZXh0IH0gZnJvbSAnLi90eXBlcyc7XG5cbi8qKiBHZXQgYSBrZXkgdG8gdW5pcXVlbHkgaWRlbnRpZnkgYSBjb250ZXh0IHZhbHVlICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQ29udGV4dEtleShkZXNjcmlwdGlvbjogc3RyaW5nKSB7XG4gIC8vIFRoZSBzcGVjaWZpY2F0aW9uIHN0YXRlcyB0aGF0IGZvciB0aGUgc2FtZSBpbnB1dCwgbXVsdGlwbGUgY2FsbHMgc2hvdWxkXG4gIC8vIHJldHVybiBkaWZmZXJlbnQga2V5cy4gRHVlIHRvIHRoZSBuYXR1cmUgb2YgdGhlIEpTIGRlcGVuZGVuY3kgbWFuYWdlbWVudFxuICAvLyBzeXN0ZW0sIHRoaXMgY3JlYXRlcyBwcm9ibGVtcyB3aGVyZSBtdWx0aXBsZSB2ZXJzaW9ucyBvZiBzb21lIHBhY2thZ2VcbiAgLy8gY291bGQgaG9sZCBkaWZmZXJlbnQga2V5cyBmb3IgdGhlIHNhbWUgcHJvcGVydHkuXG4gIC8vXG4gIC8vIFRoZXJlZm9yZSwgd2UgdXNlIFN5bWJvbC5mb3Igd2hpY2ggcmV0dXJucyB0aGUgc2FtZSBrZXkgZm9yIHRoZSBzYW1lIGlucHV0LlxuICByZXR1cm4gU3ltYm9sLmZvcihkZXNjcmlwdGlvbik7XG59XG5cbmNsYXNzIEJhc2VDb250ZXh0IGltcGxlbWVudHMgQ29udGV4dCB7XG4gIHByaXZhdGUgX2N1cnJlbnRDb250ZXh0ITogTWFwPHN5bWJvbCwgdW5rbm93bj47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBjb250ZXh0IHdoaWNoIGluaGVyaXRzIHZhbHVlcyBmcm9tIGFuIG9wdGlvbmFsIHBhcmVudCBjb250ZXh0LlxuICAgKlxuICAgKiBAcGFyYW0gcGFyZW50Q29udGV4dCBhIGNvbnRleHQgZnJvbSB3aGljaCB0byBpbmhlcml0IHZhbHVlc1xuICAgKi9cbiAgY29uc3RydWN0b3IocGFyZW50Q29udGV4dD86IE1hcDxzeW1ib2wsIHVua25vd24+KSB7XG4gICAgLy8gZm9yIG1pbmlmaWNhdGlvblxuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgc2VsZi5fY3VycmVudENvbnRleHQgPSBwYXJlbnRDb250ZXh0ID8gbmV3IE1hcChwYXJlbnRDb250ZXh0KSA6IG5ldyBNYXAoKTtcblxuICAgIHNlbGYuZ2V0VmFsdWUgPSAoa2V5OiBzeW1ib2wpID0+IHNlbGYuX2N1cnJlbnRDb250ZXh0LmdldChrZXkpO1xuXG4gICAgc2VsZi5zZXRWYWx1ZSA9IChrZXk6IHN5bWJvbCwgdmFsdWU6IHVua25vd24pOiBDb250ZXh0ID0+IHtcbiAgICAgIGNvbnN0IGNvbnRleHQgPSBuZXcgQmFzZUNvbnRleHQoc2VsZi5fY3VycmVudENvbnRleHQpO1xuICAgICAgY29udGV4dC5fY3VycmVudENvbnRleHQuc2V0KGtleSwgdmFsdWUpO1xuICAgICAgcmV0dXJuIGNvbnRleHQ7XG4gICAgfTtcblxuICAgIHNlbGYuZGVsZXRlVmFsdWUgPSAoa2V5OiBzeW1ib2wpOiBDb250ZXh0ID0+IHtcbiAgICAgIGNvbnN0IGNvbnRleHQgPSBuZXcgQmFzZUNvbnRleHQoc2VsZi5fY3VycmVudENvbnRleHQpO1xuICAgICAgY29udGV4dC5fY3VycmVudENvbnRleHQuZGVsZXRlKGtleSk7XG4gICAgICByZXR1cm4gY29udGV4dDtcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhIHZhbHVlIGZyb20gdGhlIGNvbnRleHQuXG4gICAqXG4gICAqIEBwYXJhbSBrZXkga2V5IHdoaWNoIGlkZW50aWZpZXMgYSBjb250ZXh0IHZhbHVlXG4gICAqL1xuICBwdWJsaWMgZ2V0VmFsdWUhOiAoa2V5OiBzeW1ib2wpID0+IHVua25vd247XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIG5ldyBjb250ZXh0IHdoaWNoIGluaGVyaXRzIGZyb20gdGhpcyBjb250ZXh0IGFuZCBoYXNcbiAgICogdGhlIGdpdmVuIGtleSBzZXQgdG8gdGhlIGdpdmVuIHZhbHVlLlxuICAgKlxuICAgKiBAcGFyYW0ga2V5IGNvbnRleHQga2V5IGZvciB3aGljaCB0byBzZXQgdGhlIHZhbHVlXG4gICAqIEBwYXJhbSB2YWx1ZSB2YWx1ZSB0byBzZXQgZm9yIHRoZSBnaXZlbiBrZXlcbiAgICovXG4gIHB1YmxpYyBzZXRWYWx1ZSE6IChrZXk6IHN5bWJvbCwgdmFsdWU6IHVua25vd24pID0+IENvbnRleHQ7XG5cbiAgLyoqXG4gICAqIFJldHVybiBhIG5ldyBjb250ZXh0IHdoaWNoIGluaGVyaXRzIGZyb20gdGhpcyBjb250ZXh0IGJ1dCBkb2VzXG4gICAqIG5vdCBjb250YWluIGEgdmFsdWUgZm9yIHRoZSBnaXZlbiBrZXkuXG4gICAqXG4gICAqIEBwYXJhbSBrZXkgY29udGV4dCBrZXkgZm9yIHdoaWNoIHRvIGNsZWFyIGEgdmFsdWVcbiAgICovXG4gIHB1YmxpYyBkZWxldGVWYWx1ZSE6IChrZXk6IHN5bWJvbCkgPT4gQ29udGV4dDtcbn1cblxuLyoqIFRoZSByb290IGNvbnRleHQgaXMgdXNlZCBhcyB0aGUgZGVmYXVsdCBwYXJlbnQgY29udGV4dCB3aGVuIHRoZXJlIGlzIG5vIGFjdGl2ZSBjb250ZXh0ICovXG5leHBvcnQgY29uc3QgUk9PVF9DT05URVhUOiBDb250ZXh0ID0gbmV3IEJhc2VDb250ZXh0KCk7XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuaW1wb3J0IHsgRGlhZ0xvZ2dlciwgRGlhZ0xvZ0Z1bmN0aW9uIH0gZnJvbSAnLi90eXBlcyc7XG5cbnR5cGUgQ29uc29sZU1hcEtleXMgPSAnZXJyb3InIHwgJ3dhcm4nIHwgJ2luZm8nIHwgJ2RlYnVnJyB8ICd0cmFjZSc7XG5jb25zdCBjb25zb2xlTWFwOiB7IG46IGtleW9mIERpYWdMb2dnZXI7IGM6IENvbnNvbGVNYXBLZXlzIH1bXSA9IFtcbiAgeyBuOiAnZXJyb3InLCBjOiAnZXJyb3InIH0sXG4gIHsgbjogJ3dhcm4nLCBjOiAnd2FybicgfSxcbiAgeyBuOiAnaW5mbycsIGM6ICdpbmZvJyB9LFxuICB7IG46ICdkZWJ1ZycsIGM6ICdkZWJ1ZycgfSxcbiAgeyBuOiAndmVyYm9zZScsIGM6ICd0cmFjZScgfSxcbl07XG5cbi8qKlxuICogQSBzaW1wbGUgSW1tdXRhYmxlIENvbnNvbGUgYmFzZWQgZGlhZ25vc3RpYyBsb2dnZXIgd2hpY2ggd2lsbCBvdXRwdXQgYW55IG1lc3NhZ2VzIHRvIHRoZSBDb25zb2xlLlxuICogSWYgeW91IHdhbnQgdG8gbGltaXQgdGhlIGFtb3VudCBvZiBsb2dnaW5nIHRvIGEgc3BlY2lmaWMgbGV2ZWwgb3IgbG93ZXIgdXNlIHRoZVxuICoge0BsaW5rIGNyZWF0ZUxvZ0xldmVsRGlhZ0xvZ2dlcn1cbiAqL1xuZXhwb3J0IGNsYXNzIERpYWdDb25zb2xlTG9nZ2VyIGltcGxlbWVudHMgRGlhZ0xvZ2dlciB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIGZ1bmN0aW9uIF9jb25zb2xlRnVuYyhmdW5jTmFtZTogQ29uc29sZU1hcEtleXMpOiBEaWFnTG9nRnVuY3Rpb24ge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uICguLi5hcmdzKSB7XG4gICAgICAgIGlmIChjb25zb2xlKSB7XG4gICAgICAgICAgLy8gU29tZSBlbnZpcm9ubWVudHMgb25seSBleHBvc2UgdGhlIGNvbnNvbGUgd2hlbiB0aGUgRjEyIGRldmVsb3BlciBjb25zb2xlIGlzIG9wZW5cbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgICAgIGxldCB0aGVGdW5jID0gY29uc29sZVtmdW5jTmFtZV07XG4gICAgICAgICAgaWYgKHR5cGVvZiB0aGVGdW5jICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAvLyBOb3QgYWxsIGVudmlyb25tZW50cyBzdXBwb3J0IGFsbCBmdW5jdGlvbnNcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgICAgICB0aGVGdW5jID0gY29uc29sZS5sb2c7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gT25lIGxhc3QgZmluYWwgY2hlY2tcbiAgICAgICAgICBpZiAodHlwZW9mIHRoZUZ1bmMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGVGdW5jLmFwcGx5KGNvbnNvbGUsIGFyZ3MpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbnNvbGVNYXAubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXNbY29uc29sZU1hcFtpXS5uXSA9IF9jb25zb2xlRnVuYyhjb25zb2xlTWFwW2ldLmMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBMb2cgYW4gZXJyb3Igc2NlbmFyaW8gdGhhdCB3YXMgbm90IGV4cGVjdGVkIGFuZCBjYXVzZWQgdGhlIHJlcXVlc3RlZCBvcGVyYXRpb24gdG8gZmFpbC4gKi9cbiAgcHVibGljIGVycm9yITogRGlhZ0xvZ0Z1bmN0aW9uO1xuXG4gIC8qKlxuICAgKiBMb2cgYSB3YXJuaW5nIHNjZW5hcmlvIHRvIGluZm9ybSB0aGUgZGV2ZWxvcGVyIG9mIGFuIGlzc3VlcyB0aGF0IHNob3VsZCBiZSBpbnZlc3RpZ2F0ZWQuXG4gICAqIFRoZSByZXF1ZXN0ZWQgb3BlcmF0aW9uIG1heSBvciBtYXkgbm90IGhhdmUgc3VjY2VlZGVkIG9yIGNvbXBsZXRlZC5cbiAgICovXG4gIHB1YmxpYyB3YXJuITogRGlhZ0xvZ0Z1bmN0aW9uO1xuXG4gIC8qKlxuICAgKiBMb2cgYSBnZW5lcmFsIGluZm9ybWF0aW9uYWwgbWVzc2FnZSwgdGhpcyBzaG91bGQgbm90IGFmZmVjdCBmdW5jdGlvbmFsaXR5LlxuICAgKiBUaGlzIGlzIGFsc28gdGhlIGRlZmF1bHQgbG9nZ2luZyBsZXZlbCBzbyB0aGlzIHNob3VsZCBOT1QgYmUgdXNlZCBmb3IgbG9nZ2luZ1xuICAgKiBkZWJ1Z2dpbmcgbGV2ZWwgaW5mb3JtYXRpb24uXG4gICAqL1xuICBwdWJsaWMgaW5mbyE6IERpYWdMb2dGdW5jdGlvbjtcblxuICAvKipcbiAgICogTG9nIGEgZ2VuZXJhbCBkZWJ1ZyBtZXNzYWdlIHRoYXQgY2FuIGJlIHVzZWZ1bCBmb3IgaWRlbnRpZnlpbmcgYSBmYWlsdXJlLlxuICAgKiBJbmZvcm1hdGlvbiBsb2dnZWQgYXQgdGhpcyBsZXZlbCBtYXkgaW5jbHVkZSBkaWFnbm9zdGljIGRldGFpbHMgdGhhdCB3b3VsZFxuICAgKiBoZWxwIGlkZW50aWZ5IGEgZmFpbHVyZSBzY2VuYXJpby4gVXNlZnVsIHNjZW5hcmlvcyB3b3VsZCBiZSB0byBsb2cgdGhlIGV4ZWN1dGlvblxuICAgKiBvcmRlciBvZiBhc3luYyBvcGVyYXRpb25zXG4gICAqL1xuICBwdWJsaWMgZGVidWchOiBEaWFnTG9nRnVuY3Rpb247XG5cbiAgLyoqXG4gICAqIExvZyBhIGRldGFpbGVkICh2ZXJib3NlKSB0cmFjZSBsZXZlbCBsb2dnaW5nIHRoYXQgY2FuIGJlIHVzZWQgdG8gaWRlbnRpZnkgZmFpbHVyZXNcbiAgICogd2hlcmUgZGVidWcgbGV2ZWwgbG9nZ2luZyB3b3VsZCBiZSBpbnN1ZmZpY2llbnQsIHRoaXMgbGV2ZWwgb2YgdHJhY2luZyBjYW4gaW5jbHVkZVxuICAgKiBpbnB1dCBhbmQgb3V0cHV0IHBhcmFtZXRlcnMgYW5kIGFzIHN1Y2ggbWF5IGluY2x1ZGUgUElJIGluZm9ybWF0aW9uIHBhc3NpbmcgdGhyb3VnaFxuICAgKiB0aGUgQVBJLiBBcyBzdWNoIGl0IGlzIHJlY29tbWVuZGVkIHRoYXQgdGhpcyBsZXZlbCBvZiB0cmFjaW5nIHNob3VsZCBub3QgYmUgZW5hYmxlZFxuICAgKiBpbiBhIHByb2R1Y3Rpb24gZW52aXJvbm1lbnQuXG4gICAqL1xuICBwdWJsaWMgdmVyYm9zZSE6IERpYWdMb2dGdW5jdGlvbjtcbn1cbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5pbXBvcnQgeyBNZXRlciB9IGZyb20gJy4vTWV0ZXInO1xuaW1wb3J0IHtcbiAgQmF0Y2hPYnNlcnZhYmxlQ2FsbGJhY2ssXG4gIENvdW50ZXIsXG4gIEdhdWdlLFxuICBIaXN0b2dyYW0sXG4gIE1ldHJpY0F0dHJpYnV0ZXMsXG4gIE1ldHJpY09wdGlvbnMsXG4gIE9ic2VydmFibGUsXG4gIE9ic2VydmFibGVDYWxsYmFjayxcbiAgT2JzZXJ2YWJsZUNvdW50ZXIsXG4gIE9ic2VydmFibGVHYXVnZSxcbiAgT2JzZXJ2YWJsZVVwRG93bkNvdW50ZXIsXG4gIFVwRG93bkNvdW50ZXIsXG59IGZyb20gJy4vTWV0cmljJztcblxuLyoqXG4gKiBOb29wTWV0ZXIgaXMgYSBub29wIGltcGxlbWVudGF0aW9uIG9mIHRoZSB7QGxpbmsgTWV0ZXJ9IGludGVyZmFjZS4gSXQgcmV1c2VzXG4gKiBjb25zdGFudCBOb29wTWV0cmljcyBmb3IgYWxsIG9mIGl0cyBtZXRob2RzLlxuICovXG5leHBvcnQgY2xhc3MgTm9vcE1ldGVyIGltcGxlbWVudHMgTWV0ZXIge1xuICBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgLyoqXG4gICAqIEBzZWUge0BsaW5rIE1ldGVyLmNyZWF0ZUdhdWdlfVxuICAgKi9cbiAgY3JlYXRlR2F1Z2UoX25hbWU6IHN0cmluZywgX29wdGlvbnM/OiBNZXRyaWNPcHRpb25zKTogR2F1Z2Uge1xuICAgIHJldHVybiBOT09QX0dBVUdFX01FVFJJQztcbiAgfVxuXG4gIC8qKlxuICAgKiBAc2VlIHtAbGluayBNZXRlci5jcmVhdGVIaXN0b2dyYW19XG4gICAqL1xuICBjcmVhdGVIaXN0b2dyYW0oX25hbWU6IHN0cmluZywgX29wdGlvbnM/OiBNZXRyaWNPcHRpb25zKTogSGlzdG9ncmFtIHtcbiAgICByZXR1cm4gTk9PUF9ISVNUT0dSQU1fTUVUUklDO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzZWUge0BsaW5rIE1ldGVyLmNyZWF0ZUNvdW50ZXJ9XG4gICAqL1xuICBjcmVhdGVDb3VudGVyKF9uYW1lOiBzdHJpbmcsIF9vcHRpb25zPzogTWV0cmljT3B0aW9ucyk6IENvdW50ZXIge1xuICAgIHJldHVybiBOT09QX0NPVU5URVJfTUVUUklDO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzZWUge0BsaW5rIE1ldGVyLmNyZWF0ZVVwRG93bkNvdW50ZXJ9XG4gICAqL1xuICBjcmVhdGVVcERvd25Db3VudGVyKF9uYW1lOiBzdHJpbmcsIF9vcHRpb25zPzogTWV0cmljT3B0aW9ucyk6IFVwRG93bkNvdW50ZXIge1xuICAgIHJldHVybiBOT09QX1VQX0RPV05fQ09VTlRFUl9NRVRSSUM7XG4gIH1cblxuICAvKipcbiAgICogQHNlZSB7QGxpbmsgTWV0ZXIuY3JlYXRlT2JzZXJ2YWJsZUdhdWdlfVxuICAgKi9cbiAgY3JlYXRlT2JzZXJ2YWJsZUdhdWdlKFxuICAgIF9uYW1lOiBzdHJpbmcsXG4gICAgX29wdGlvbnM/OiBNZXRyaWNPcHRpb25zXG4gICk6IE9ic2VydmFibGVHYXVnZSB7XG4gICAgcmV0dXJuIE5PT1BfT0JTRVJWQUJMRV9HQVVHRV9NRVRSSUM7XG4gIH1cblxuICAvKipcbiAgICogQHNlZSB7QGxpbmsgTWV0ZXIuY3JlYXRlT2JzZXJ2YWJsZUNvdW50ZXJ9XG4gICAqL1xuICBjcmVhdGVPYnNlcnZhYmxlQ291bnRlcihcbiAgICBfbmFtZTogc3RyaW5nLFxuICAgIF9vcHRpb25zPzogTWV0cmljT3B0aW9uc1xuICApOiBPYnNlcnZhYmxlQ291bnRlciB7XG4gICAgcmV0dXJuIE5PT1BfT0JTRVJWQUJMRV9DT1VOVEVSX01FVFJJQztcbiAgfVxuXG4gIC8qKlxuICAgKiBAc2VlIHtAbGluayBNZXRlci5jcmVhdGVPYnNlcnZhYmxlVXBEb3duQ291bnRlcn1cbiAgICovXG4gIGNyZWF0ZU9ic2VydmFibGVVcERvd25Db3VudGVyKFxuICAgIF9uYW1lOiBzdHJpbmcsXG4gICAgX29wdGlvbnM/OiBNZXRyaWNPcHRpb25zXG4gICk6IE9ic2VydmFibGVVcERvd25Db3VudGVyIHtcbiAgICByZXR1cm4gTk9PUF9PQlNFUlZBQkxFX1VQX0RPV05fQ09VTlRFUl9NRVRSSUM7XG4gIH1cblxuICAvKipcbiAgICogQHNlZSB7QGxpbmsgTWV0ZXIuYWRkQmF0Y2hPYnNlcnZhYmxlQ2FsbGJhY2t9XG4gICAqL1xuICBhZGRCYXRjaE9ic2VydmFibGVDYWxsYmFjayhcbiAgICBfY2FsbGJhY2s6IEJhdGNoT2JzZXJ2YWJsZUNhbGxiYWNrLFxuICAgIF9vYnNlcnZhYmxlczogT2JzZXJ2YWJsZVtdXG4gICk6IHZvaWQge31cblxuICAvKipcbiAgICogQHNlZSB7QGxpbmsgTWV0ZXIucmVtb3ZlQmF0Y2hPYnNlcnZhYmxlQ2FsbGJhY2t9XG4gICAqL1xuICByZW1vdmVCYXRjaE9ic2VydmFibGVDYWxsYmFjayhfY2FsbGJhY2s6IEJhdGNoT2JzZXJ2YWJsZUNhbGxiYWNrKTogdm9pZCB7fVxufVxuXG5leHBvcnQgY2xhc3MgTm9vcE1ldHJpYyB7fVxuXG5leHBvcnQgY2xhc3MgTm9vcENvdW50ZXJNZXRyaWMgZXh0ZW5kcyBOb29wTWV0cmljIGltcGxlbWVudHMgQ291bnRlciB7XG4gIGFkZChfdmFsdWU6IG51bWJlciwgX2F0dHJpYnV0ZXM6IE1ldHJpY0F0dHJpYnV0ZXMpOiB2b2lkIHt9XG59XG5cbmV4cG9ydCBjbGFzcyBOb29wVXBEb3duQ291bnRlck1ldHJpY1xuICBleHRlbmRzIE5vb3BNZXRyaWNcbiAgaW1wbGVtZW50cyBVcERvd25Db3VudGVyXG57XG4gIGFkZChfdmFsdWU6IG51bWJlciwgX2F0dHJpYnV0ZXM6IE1ldHJpY0F0dHJpYnV0ZXMpOiB2b2lkIHt9XG59XG5cbmV4cG9ydCBjbGFzcyBOb29wR2F1Z2VNZXRyaWMgZXh0ZW5kcyBOb29wTWV0cmljIGltcGxlbWVudHMgR2F1Z2Uge1xuICByZWNvcmQoX3ZhbHVlOiBudW1iZXIsIF9hdHRyaWJ1dGVzOiBNZXRyaWNBdHRyaWJ1dGVzKTogdm9pZCB7fVxufVxuXG5leHBvcnQgY2xhc3MgTm9vcEhpc3RvZ3JhbU1ldHJpYyBleHRlbmRzIE5vb3BNZXRyaWMgaW1wbGVtZW50cyBIaXN0b2dyYW0ge1xuICByZWNvcmQoX3ZhbHVlOiBudW1iZXIsIF9hdHRyaWJ1dGVzOiBNZXRyaWNBdHRyaWJ1dGVzKTogdm9pZCB7fVxufVxuXG5leHBvcnQgY2xhc3MgTm9vcE9ic2VydmFibGVNZXRyaWMge1xuICBhZGRDYWxsYmFjayhfY2FsbGJhY2s6IE9ic2VydmFibGVDYWxsYmFjaykge31cblxuICByZW1vdmVDYWxsYmFjayhfY2FsbGJhY2s6IE9ic2VydmFibGVDYWxsYmFjaykge31cbn1cblxuZXhwb3J0IGNsYXNzIE5vb3BPYnNlcnZhYmxlQ291bnRlck1ldHJpY1xuICBleHRlbmRzIE5vb3BPYnNlcnZhYmxlTWV0cmljXG4gIGltcGxlbWVudHMgT2JzZXJ2YWJsZUNvdW50ZXIge31cblxuZXhwb3J0IGNsYXNzIE5vb3BPYnNlcnZhYmxlR2F1Z2VNZXRyaWNcbiAgZXh0ZW5kcyBOb29wT2JzZXJ2YWJsZU1ldHJpY1xuICBpbXBsZW1lbnRzIE9ic2VydmFibGVHYXVnZSB7fVxuXG5leHBvcnQgY2xhc3MgTm9vcE9ic2VydmFibGVVcERvd25Db3VudGVyTWV0cmljXG4gIGV4dGVuZHMgTm9vcE9ic2VydmFibGVNZXRyaWNcbiAgaW1wbGVtZW50cyBPYnNlcnZhYmxlVXBEb3duQ291bnRlciB7fVxuXG5leHBvcnQgY29uc3QgTk9PUF9NRVRFUiA9IG5ldyBOb29wTWV0ZXIoKTtcblxuLy8gU3luY2hyb25vdXMgaW5zdHJ1bWVudHNcbmV4cG9ydCBjb25zdCBOT09QX0NPVU5URVJfTUVUUklDID0gbmV3IE5vb3BDb3VudGVyTWV0cmljKCk7XG5leHBvcnQgY29uc3QgTk9PUF9HQVVHRV9NRVRSSUMgPSBuZXcgTm9vcEdhdWdlTWV0cmljKCk7XG5leHBvcnQgY29uc3QgTk9PUF9ISVNUT0dSQU1fTUVUUklDID0gbmV3IE5vb3BIaXN0b2dyYW1NZXRyaWMoKTtcbmV4cG9ydCBjb25zdCBOT09QX1VQX0RPV05fQ09VTlRFUl9NRVRSSUMgPSBuZXcgTm9vcFVwRG93bkNvdW50ZXJNZXRyaWMoKTtcblxuLy8gQXN5bmNocm9ub3VzIGluc3RydW1lbnRzXG5leHBvcnQgY29uc3QgTk9PUF9PQlNFUlZBQkxFX0NPVU5URVJfTUVUUklDID0gbmV3IE5vb3BPYnNlcnZhYmxlQ291bnRlck1ldHJpYygpO1xuZXhwb3J0IGNvbnN0IE5PT1BfT0JTRVJWQUJMRV9HQVVHRV9NRVRSSUMgPSBuZXcgTm9vcE9ic2VydmFibGVHYXVnZU1ldHJpYygpO1xuZXhwb3J0IGNvbnN0IE5PT1BfT0JTRVJWQUJMRV9VUF9ET1dOX0NPVU5URVJfTUVUUklDID1cbiAgbmV3IE5vb3BPYnNlcnZhYmxlVXBEb3duQ291bnRlck1ldHJpYygpO1xuXG4vKipcbiAqIENyZWF0ZSBhIG5vLW9wIE1ldGVyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVOb29wTWV0ZXIoKTogTWV0ZXIge1xuICByZXR1cm4gTk9PUF9NRVRFUjtcbn1cbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5pbXBvcnQgeyBBdHRyaWJ1dGVzLCBBdHRyaWJ1dGVWYWx1ZSB9IGZyb20gJy4uL2NvbW1vbi9BdHRyaWJ1dGVzJztcbmltcG9ydCB7IENvbnRleHQgfSBmcm9tICcuLi9jb250ZXh0L3R5cGVzJztcbmltcG9ydCB7IEJhdGNoT2JzZXJ2YWJsZVJlc3VsdCwgT2JzZXJ2YWJsZVJlc3VsdCB9IGZyb20gJy4vT2JzZXJ2YWJsZVJlc3VsdCc7XG5cbi8qKlxuICogQWR2aXNvcnkgb3B0aW9ucyBpbmZsdWVuY2luZyBhZ2dyZWdhdGlvbiBjb25maWd1cmF0aW9uIHBhcmFtZXRlcnMuXG4gKiBAZXhwZXJpbWVudGFsXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWV0cmljQWR2aWNlIHtcbiAgLyoqXG4gICAqIEhpbnQgdGhlIGV4cGxpY2l0IGJ1Y2tldCBib3VuZGFyaWVzIGZvciBTREsgaWYgdGhlIG1ldHJpYyBpcyBiZWVuXG4gICAqIGFnZ3JlZ2F0ZWQgd2l0aCBhIEhpc3RvZ3JhbUFnZ3JlZ2F0b3IuXG4gICAqL1xuICBleHBsaWNpdEJ1Y2tldEJvdW5kYXJpZXM/OiBudW1iZXJbXTtcbn1cblxuLyoqXG4gKiBPcHRpb25zIG5lZWRlZCBmb3IgbWV0cmljIGNyZWF0aW9uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWV0cmljT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgZGVzY3JpcHRpb24gb2YgdGhlIE1ldHJpYy5cbiAgICogQGRlZmF1bHQgJydcbiAgICovXG4gIGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgdW5pdCBvZiB0aGUgTWV0cmljIHZhbHVlcy5cbiAgICogQGRlZmF1bHQgJydcbiAgICovXG4gIHVuaXQ/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyB0aGUgdHlwZSBvZiB0aGUgcmVjb3JkZWQgdmFsdWUuXG4gICAqIEBkZWZhdWx0IHtAbGluayBWYWx1ZVR5cGUuRE9VQkxFfVxuICAgKi9cbiAgdmFsdWVUeXBlPzogVmFsdWVUeXBlO1xuXG4gIC8qKlxuICAgKiBUaGUgYWR2aWNlIGluZmx1ZW5jaW5nIGFnZ3JlZ2F0aW9uIGNvbmZpZ3VyYXRpb24gcGFyYW1ldGVycy5cbiAgICogQGV4cGVyaW1lbnRhbFxuICAgKi9cbiAgYWR2aWNlPzogTWV0cmljQWR2aWNlO1xufVxuXG4vKiogVGhlIFR5cGUgb2YgdmFsdWUuIEl0IGRlc2NyaWJlcyBob3cgdGhlIGRhdGEgaXMgcmVwb3J0ZWQuICovXG5leHBvcnQgZW51bSBWYWx1ZVR5cGUge1xuICBJTlQsXG4gIERPVUJMRSxcbn1cblxuLyoqXG4gKiBDb3VudGVyIGlzIHRoZSBtb3N0IGNvbW1vbiBzeW5jaHJvbm91cyBpbnN0cnVtZW50LiBUaGlzIGluc3RydW1lbnQgc3VwcG9ydHNcbiAqIGFuIGBBZGQoaW5jcmVtZW50KWAgZnVuY3Rpb24gZm9yIHJlcG9ydGluZyBhIHN1bSwgYW5kIGlzIHJlc3RyaWN0ZWQgdG9cbiAqIG5vbi1uZWdhdGl2ZSBpbmNyZW1lbnRzLiBUaGUgZGVmYXVsdCBhZ2dyZWdhdGlvbiBpcyBTdW0sIGFzIGZvciBhbnkgYWRkaXRpdmVcbiAqIGluc3RydW1lbnQuXG4gKlxuICogRXhhbXBsZSB1c2VzIGZvciBDb3VudGVyOlxuICogPG9sPlxuICogICA8bGk+IGNvdW50IHRoZSBudW1iZXIgb2YgYnl0ZXMgcmVjZWl2ZWQuIDwvbGk+XG4gKiAgIDxsaT4gY291bnQgdGhlIG51bWJlciBvZiByZXF1ZXN0cyBjb21wbGV0ZWQuIDwvbGk+XG4gKiAgIDxsaT4gY291bnQgdGhlIG51bWJlciBvZiBhY2NvdW50cyBjcmVhdGVkLiA8L2xpPlxuICogICA8bGk+IGNvdW50IHRoZSBudW1iZXIgb2YgY2hlY2twb2ludHMgcnVuLiA8L2xpPlxuICogICA8bGk+IGNvdW50IHRoZSBudW1iZXIgb2YgNXh4IGVycm9ycy4gPC9saT5cbiAqIDxvbD5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDb3VudGVyPFxuICBBdHRyaWJ1dGVzVHlwZXMgZXh0ZW5kcyBNZXRyaWNBdHRyaWJ1dGVzID0gTWV0cmljQXR0cmlidXRlcyxcbj4ge1xuICAvKipcbiAgICogSW5jcmVtZW50IHZhbHVlIG9mIGNvdW50ZXIgYnkgdGhlIGlucHV0LiBJbnB1dHMgbXVzdCBub3QgYmUgbmVnYXRpdmUuXG4gICAqL1xuICBhZGQodmFsdWU6IG51bWJlciwgYXR0cmlidXRlcz86IEF0dHJpYnV0ZXNUeXBlcywgY29udGV4dD86IENvbnRleHQpOiB2b2lkO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFVwRG93bkNvdW50ZXI8XG4gIEF0dHJpYnV0ZXNUeXBlcyBleHRlbmRzIE1ldHJpY0F0dHJpYnV0ZXMgPSBNZXRyaWNBdHRyaWJ1dGVzLFxuPiB7XG4gIC8qKlxuICAgKiBJbmNyZW1lbnQgdmFsdWUgb2YgY291bnRlciBieSB0aGUgaW5wdXQuIElucHV0cyBtYXkgYmUgbmVnYXRpdmUuXG4gICAqL1xuICBhZGQodmFsdWU6IG51bWJlciwgYXR0cmlidXRlcz86IEF0dHJpYnV0ZXNUeXBlcywgY29udGV4dD86IENvbnRleHQpOiB2b2lkO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEdhdWdlPFxuICBBdHRyaWJ1dGVzVHlwZXMgZXh0ZW5kcyBNZXRyaWNBdHRyaWJ1dGVzID0gTWV0cmljQXR0cmlidXRlcyxcbj4ge1xuICAvKipcbiAgICogUmVjb3JkcyBhIG1lYXN1cmVtZW50LlxuICAgKi9cbiAgcmVjb3JkKHZhbHVlOiBudW1iZXIsIGF0dHJpYnV0ZXM/OiBBdHRyaWJ1dGVzVHlwZXMsIGNvbnRleHQ/OiBDb250ZXh0KTogdm9pZDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBIaXN0b2dyYW08XG4gIEF0dHJpYnV0ZXNUeXBlcyBleHRlbmRzIE1ldHJpY0F0dHJpYnV0ZXMgPSBNZXRyaWNBdHRyaWJ1dGVzLFxuPiB7XG4gIC8qKlxuICAgKiBSZWNvcmRzIGEgbWVhc3VyZW1lbnQuIFZhbHVlIG9mIHRoZSBtZWFzdXJlbWVudCBtdXN0IG5vdCBiZSBuZWdhdGl2ZS5cbiAgICovXG4gIHJlY29yZCh2YWx1ZTogbnVtYmVyLCBhdHRyaWJ1dGVzPzogQXR0cmlidXRlc1R5cGVzLCBjb250ZXh0PzogQ29udGV4dCk6IHZvaWQ7XG59XG5cbi8qKlxuICogQGRlcHJlY2F0ZWQgcGxlYXNlIHVzZSB7QGxpbmsgQXR0cmlidXRlc31cbiAqL1xuZXhwb3J0IHR5cGUgTWV0cmljQXR0cmlidXRlcyA9IEF0dHJpYnV0ZXM7XG5cbi8qKlxuICogQGRlcHJlY2F0ZWQgcGxlYXNlIHVzZSB7QGxpbmsgQXR0cmlidXRlVmFsdWV9XG4gKi9cbmV4cG9ydCB0eXBlIE1ldHJpY0F0dHJpYnV0ZVZhbHVlID0gQXR0cmlidXRlVmFsdWU7XG5cbi8qKlxuICogVGhlIG9ic2VydmFibGUgY2FsbGJhY2sgZm9yIE9ic2VydmFibGUgaW5zdHJ1bWVudHMuXG4gKi9cbmV4cG9ydCB0eXBlIE9ic2VydmFibGVDYWxsYmFjazxcbiAgQXR0cmlidXRlc1R5cGVzIGV4dGVuZHMgTWV0cmljQXR0cmlidXRlcyA9IE1ldHJpY0F0dHJpYnV0ZXMsXG4+ID0gKFxuICBvYnNlcnZhYmxlUmVzdWx0OiBPYnNlcnZhYmxlUmVzdWx0PEF0dHJpYnV0ZXNUeXBlcz5cbikgPT4gdm9pZCB8IFByb21pc2U8dm9pZD47XG5cbi8qKlxuICogVGhlIG9ic2VydmFibGUgY2FsbGJhY2sgZm9yIGEgYmF0Y2ggb2YgT2JzZXJ2YWJsZSBpbnN0cnVtZW50cy5cbiAqL1xuZXhwb3J0IHR5cGUgQmF0Y2hPYnNlcnZhYmxlQ2FsbGJhY2s8XG4gIEF0dHJpYnV0ZXNUeXBlcyBleHRlbmRzIE1ldHJpY0F0dHJpYnV0ZXMgPSBNZXRyaWNBdHRyaWJ1dGVzLFxuPiA9IChcbiAgb2JzZXJ2YWJsZVJlc3VsdDogQmF0Y2hPYnNlcnZhYmxlUmVzdWx0PEF0dHJpYnV0ZXNUeXBlcz5cbikgPT4gdm9pZCB8IFByb21pc2U8dm9pZD47XG5cbmV4cG9ydCBpbnRlcmZhY2UgT2JzZXJ2YWJsZTxcbiAgQXR0cmlidXRlc1R5cGVzIGV4dGVuZHMgTWV0cmljQXR0cmlidXRlcyA9IE1ldHJpY0F0dHJpYnV0ZXMsXG4+IHtcbiAgLyoqXG4gICAqIFNldHMgdXAgYSBmdW5jdGlvbiB0aGF0IHdpbGwgYmUgY2FsbGVkIHdoZW5ldmVyIGEgbWV0cmljIGNvbGxlY3Rpb24gaXMgaW5pdGlhdGVkLlxuICAgKlxuICAgKiBJZiB0aGUgZnVuY3Rpb24gaXMgYWxyZWFkeSBpbiB0aGUgbGlzdCBvZiBjYWxsYmFja3MgZm9yIHRoaXMgT2JzZXJ2YWJsZSwgdGhlIGZ1bmN0aW9uIGlzIG5vdCBhZGRlZCBhIHNlY29uZCB0aW1lLlxuICAgKi9cbiAgYWRkQ2FsbGJhY2soY2FsbGJhY2s6IE9ic2VydmFibGVDYWxsYmFjazxBdHRyaWJ1dGVzVHlwZXM+KTogdm9pZDtcblxuICAvKipcbiAgICogUmVtb3ZlcyBhIGNhbGxiYWNrIHByZXZpb3VzbHkgcmVnaXN0ZXJlZCB3aXRoIHtAbGluayBPYnNlcnZhYmxlLmFkZENhbGxiYWNrfS5cbiAgICovXG4gIHJlbW92ZUNhbGxiYWNrKGNhbGxiYWNrOiBPYnNlcnZhYmxlQ2FsbGJhY2s8QXR0cmlidXRlc1R5cGVzPik6IHZvaWQ7XG59XG5cbmV4cG9ydCB0eXBlIE9ic2VydmFibGVDb3VudGVyPFxuICBBdHRyaWJ1dGVzVHlwZXMgZXh0ZW5kcyBNZXRyaWNBdHRyaWJ1dGVzID0gTWV0cmljQXR0cmlidXRlcyxcbj4gPSBPYnNlcnZhYmxlPEF0dHJpYnV0ZXNUeXBlcz47XG5leHBvcnQgdHlwZSBPYnNlcnZhYmxlVXBEb3duQ291bnRlcjxcbiAgQXR0cmlidXRlc1R5cGVzIGV4dGVuZHMgTWV0cmljQXR0cmlidXRlcyA9IE1ldHJpY0F0dHJpYnV0ZXMsXG4+ID0gT2JzZXJ2YWJsZTxBdHRyaWJ1dGVzVHlwZXM+O1xuZXhwb3J0IHR5cGUgT2JzZXJ2YWJsZUdhdWdlPFxuICBBdHRyaWJ1dGVzVHlwZXMgZXh0ZW5kcyBNZXRyaWNBdHRyaWJ1dGVzID0gTWV0cmljQXR0cmlidXRlcyxcbj4gPSBPYnNlcnZhYmxlPEF0dHJpYnV0ZXNUeXBlcz47XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuaW1wb3J0IHsgQ29udGV4dCB9IGZyb20gJy4uL2NvbnRleHQvdHlwZXMnO1xuXG4vKipcbiAqIEluamVjdHMgYENvbnRleHRgIGludG8gYW5kIGV4dHJhY3RzIGl0IGZyb20gY2FycmllcnMgdGhhdCB0cmF2ZWxcbiAqIGluLWJhbmQgYWNyb3NzIHByb2Nlc3MgYm91bmRhcmllcy4gRW5jb2RpbmcgaXMgZXhwZWN0ZWQgdG8gY29uZm9ybSB0byB0aGVcbiAqIEhUVFAgSGVhZGVyIEZpZWxkIHNlbWFudGljcy4gVmFsdWVzIGFyZSBvZnRlbiBlbmNvZGVkIGFzIFJQQy9IVFRQIHJlcXVlc3RcbiAqIGhlYWRlcnMuXG4gKlxuICogVGhlIGNhcnJpZXIgb2YgcHJvcGFnYXRlZCBkYXRhIG9uIGJvdGggdGhlIGNsaWVudCAoaW5qZWN0b3IpIGFuZCBzZXJ2ZXJcbiAqIChleHRyYWN0b3IpIHNpZGUgaXMgdXN1YWxseSBhbiBvYmplY3Qgc3VjaCBhcyBodHRwIGhlYWRlcnMuIFByb3BhZ2F0aW9uIGlzXG4gKiB1c3VhbGx5IGltcGxlbWVudGVkIHZpYSBsaWJyYXJ5LXNwZWNpZmljIHJlcXVlc3QgaW50ZXJjZXB0b3JzLCB3aGVyZSB0aGVcbiAqIGNsaWVudC1zaWRlIGluamVjdHMgdmFsdWVzIGFuZCB0aGUgc2VydmVyLXNpZGUgZXh0cmFjdHMgdGhlbS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBUZXh0TWFwUHJvcGFnYXRvcjxDYXJyaWVyID0gYW55PiB7XG4gIC8qKlxuICAgKiBJbmplY3RzIHZhbHVlcyBmcm9tIGEgZ2l2ZW4gYENvbnRleHRgIGludG8gYSBjYXJyaWVyLlxuICAgKlxuICAgKiBPcGVuVGVsZW1ldHJ5IGRlZmluZXMgYSBjb21tb24gc2V0IG9mIGZvcm1hdCB2YWx1ZXMgKFRleHRNYXBQcm9wYWdhdG9yKSxcbiAgICogYW5kIGVhY2ggaGFzIGFuIGV4cGVjdGVkIGBjYXJyaWVyYCB0eXBlLlxuICAgKlxuICAgKiBAcGFyYW0gY29udGV4dCB0aGUgQ29udGV4dCBmcm9tIHdoaWNoIHRvIGV4dHJhY3QgdmFsdWVzIHRvIHRyYW5zbWl0IG92ZXJcbiAgICogICAgIHRoZSB3aXJlLlxuICAgKiBAcGFyYW0gY2FycmllciB0aGUgY2FycmllciBvZiBwcm9wYWdhdGlvbiBmaWVsZHMsIHN1Y2ggYXMgaHR0cCByZXF1ZXN0XG4gICAqICAgICBoZWFkZXJzLlxuICAgKiBAcGFyYW0gc2V0dGVyIGFuIG9wdGlvbmFsIHtAbGluayBUZXh0TWFwU2V0dGVyfS4gSWYgdW5kZWZpbmVkLCB2YWx1ZXMgd2lsbCBiZVxuICAgKiAgICAgc2V0IGJ5IGRpcmVjdCBvYmplY3QgYXNzaWdubWVudC5cbiAgICovXG4gIGluamVjdChcbiAgICBjb250ZXh0OiBDb250ZXh0LFxuICAgIGNhcnJpZXI6IENhcnJpZXIsXG4gICAgc2V0dGVyOiBUZXh0TWFwU2V0dGVyPENhcnJpZXI+XG4gICk6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIEdpdmVuIGEgYENvbnRleHRgIGFuZCBhIGNhcnJpZXIsIGV4dHJhY3QgY29udGV4dCB2YWx1ZXMgZnJvbSBhXG4gICAqIGNhcnJpZXIgYW5kIHJldHVybiBhIG5ldyBjb250ZXh0LCBjcmVhdGVkIGZyb20gdGhlIG9sZCBjb250ZXh0LCB3aXRoIHRoZVxuICAgKiBleHRyYWN0ZWQgdmFsdWVzLlxuICAgKlxuICAgKiBAcGFyYW0gY29udGV4dCB0aGUgQ29udGV4dCBmcm9tIHdoaWNoIHRvIGV4dHJhY3QgdmFsdWVzIHRvIHRyYW5zbWl0IG92ZXJcbiAgICogICAgIHRoZSB3aXJlLlxuICAgKiBAcGFyYW0gY2FycmllciB0aGUgY2FycmllciBvZiBwcm9wYWdhdGlvbiBmaWVsZHMsIHN1Y2ggYXMgaHR0cCByZXF1ZXN0XG4gICAqICAgICBoZWFkZXJzLlxuICAgKiBAcGFyYW0gZ2V0dGVyIGFuIG9wdGlvbmFsIHtAbGluayBUZXh0TWFwR2V0dGVyfS4gSWYgdW5kZWZpbmVkLCBrZXlzIHdpbGwgYmUgYWxsXG4gICAqICAgICBvd24gcHJvcGVydGllcywgYW5kIGtleXMgd2lsbCBiZSBhY2Nlc3NlZCBieSBkaXJlY3Qgb2JqZWN0IGFjY2Vzcy5cbiAgICovXG4gIGV4dHJhY3QoXG4gICAgY29udGV4dDogQ29udGV4dCxcbiAgICBjYXJyaWVyOiBDYXJyaWVyLFxuICAgIGdldHRlcjogVGV4dE1hcEdldHRlcjxDYXJyaWVyPlxuICApOiBDb250ZXh0O1xuXG4gIC8qKlxuICAgKiBSZXR1cm4gYSBsaXN0IG9mIGFsbCBmaWVsZHMgd2hpY2ggbWF5IGJlIHVzZWQgYnkgdGhlIHByb3BhZ2F0b3IuXG4gICAqL1xuICBmaWVsZHMoKTogc3RyaW5nW107XG59XG5cbi8qKlxuICogQSBzZXR0ZXIgaXMgc3BlY2lmaWVkIGJ5IHRoZSBjYWxsZXIgdG8gZGVmaW5lIGEgc3BlY2lmaWMgbWV0aG9kXG4gKiB0byBzZXQga2V5L3ZhbHVlIHBhaXJzIG9uIHRoZSBjYXJyaWVyIHdpdGhpbiBhIHByb3BhZ2F0b3IuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGV4dE1hcFNldHRlcjxDYXJyaWVyID0gYW55PiB7XG4gIC8qKlxuICAgKiBDYWxsYmFjayB1c2VkIHRvIHNldCBhIGtleS92YWx1ZSBwYWlyIG9uIGFuIG9iamVjdC5cbiAgICpcbiAgICogU2hvdWxkIGJlIGNhbGxlZCBieSB0aGUgcHJvcGFnYXRvciBlYWNoIHRpbWUgYSBrZXkvdmFsdWUgcGFpclxuICAgKiBzaG91bGQgYmUgc2V0LCBhbmQgc2hvdWxkIHNldCB0aGF0IGtleS92YWx1ZSBwYWlyIG9uIHRoZSBwcm9wYWdhdG9yLlxuICAgKlxuICAgKiBAcGFyYW0gY2FycmllciBvYmplY3Qgb3IgY2xhc3Mgd2hpY2ggY2FycmllcyBrZXkvdmFsdWUgcGFpcnNcbiAgICogQHBhcmFtIGtleSBzdHJpbmcga2V5IHRvIG1vZGlmeVxuICAgKiBAcGFyYW0gdmFsdWUgdmFsdWUgdG8gYmUgc2V0IHRvIHRoZSBrZXkgb24gdGhlIGNhcnJpZXJcbiAgICovXG4gIHNldChjYXJyaWVyOiBDYXJyaWVyLCBrZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZyk6IHZvaWQ7XG59XG5cbi8qKlxuICogQSBnZXR0ZXIgaXMgc3BlY2lmaWVkIGJ5IHRoZSBjYWxsZXIgdG8gZGVmaW5lIGEgc3BlY2lmaWMgbWV0aG9kXG4gKiB0byBnZXQgdGhlIHZhbHVlIG9mIGEga2V5IGZyb20gYSBjYXJyaWVyLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRleHRNYXBHZXR0ZXI8Q2FycmllciA9IGFueT4ge1xuICAvKipcbiAgICogR2V0IGEgbGlzdCBvZiBhbGwga2V5cyBhdmFpbGFibGUgb24gdGhlIGNhcnJpZXIuXG4gICAqXG4gICAqIEBwYXJhbSBjYXJyaWVyXG4gICAqL1xuICBrZXlzKGNhcnJpZXI6IENhcnJpZXIpOiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogR2V0IHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmljIGtleSBmcm9tIHRoZSBjYXJyaWVyLlxuICAgKlxuICAgKiBAcGFyYW0gY2FycmllclxuICAgKiBAcGFyYW0ga2V5XG4gICAqL1xuICBnZXQoY2FycmllcjogQ2Fycmllciwga2V5OiBzdHJpbmcpOiB1bmRlZmluZWQgfCBzdHJpbmcgfCBzdHJpbmdbXTtcbn1cblxuZXhwb3J0IGNvbnN0IGRlZmF1bHRUZXh0TWFwR2V0dGVyOiBUZXh0TWFwR2V0dGVyID0ge1xuICBnZXQoY2Fycmllciwga2V5KSB7XG4gICAgaWYgKGNhcnJpZXIgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcmV0dXJuIGNhcnJpZXJba2V5XTtcbiAgfSxcblxuICBrZXlzKGNhcnJpZXIpIHtcbiAgICBpZiAoY2FycmllciA9PSBudWxsKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIHJldHVybiBPYmplY3Qua2V5cyhjYXJyaWVyKTtcbiAgfSxcbn07XG5cbmV4cG9ydCBjb25zdCBkZWZhdWx0VGV4dE1hcFNldHRlcjogVGV4dE1hcFNldHRlciA9IHtcbiAgc2V0KGNhcnJpZXIsIGtleSwgdmFsdWUpIHtcbiAgICBpZiAoY2FycmllciA9PSBudWxsKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY2FycmllcltrZXldID0gdmFsdWU7XG4gIH0sXG59O1xuIiwgIi8qXG4gKiBDb3B5cmlnaHQgVGhlIE9wZW5UZWxlbWV0cnkgQXV0aG9yc1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgIGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IFJPT1RfQ09OVEVYVCB9IGZyb20gJy4vY29udGV4dCc7XG5pbXBvcnQgKiBhcyB0eXBlcyBmcm9tICcuL3R5cGVzJztcblxuZXhwb3J0IGNsYXNzIE5vb3BDb250ZXh0TWFuYWdlciBpbXBsZW1lbnRzIHR5cGVzLkNvbnRleHRNYW5hZ2VyIHtcbiAgYWN0aXZlKCk6IHR5cGVzLkNvbnRleHQge1xuICAgIHJldHVybiBST09UX0NPTlRFWFQ7XG4gIH1cblxuICB3aXRoPEEgZXh0ZW5kcyB1bmtub3duW10sIEYgZXh0ZW5kcyAoLi4uYXJnczogQSkgPT4gUmV0dXJuVHlwZTxGPj4oXG4gICAgX2NvbnRleHQ6IHR5cGVzLkNvbnRleHQsXG4gICAgZm46IEYsXG4gICAgdGhpc0FyZz86IFRoaXNQYXJhbWV0ZXJUeXBlPEY+LFxuICAgIC4uLmFyZ3M6IEFcbiAgKTogUmV0dXJuVHlwZTxGPiB7XG4gICAgcmV0dXJuIGZuLmNhbGwodGhpc0FyZywgLi4uYXJncyk7XG4gIH1cblxuICBiaW5kPFQ+KF9jb250ZXh0OiB0eXBlcy5Db250ZXh0LCB0YXJnZXQ6IFQpOiBUIHtcbiAgICByZXR1cm4gdGFyZ2V0O1xuICB9XG5cbiAgZW5hYmxlKCk6IHRoaXMge1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgZGlzYWJsZSgpOiB0aGlzIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxufVxuIiwgIi8qXG4gKiBDb3B5cmlnaHQgVGhlIE9wZW5UZWxlbWV0cnkgQXV0aG9yc1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgIGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IE5vb3BDb250ZXh0TWFuYWdlciB9IGZyb20gJy4uL2NvbnRleHQvTm9vcENvbnRleHRNYW5hZ2VyJztcbmltcG9ydCB7IENvbnRleHQsIENvbnRleHRNYW5hZ2VyIH0gZnJvbSAnLi4vY29udGV4dC90eXBlcyc7XG5pbXBvcnQge1xuICBnZXRHbG9iYWwsXG4gIHJlZ2lzdGVyR2xvYmFsLFxuICB1bnJlZ2lzdGVyR2xvYmFsLFxufSBmcm9tICcuLi9pbnRlcm5hbC9nbG9iYWwtdXRpbHMnO1xuaW1wb3J0IHsgRGlhZ0FQSSB9IGZyb20gJy4vZGlhZyc7XG5cbmNvbnN0IEFQSV9OQU1FID0gJ2NvbnRleHQnO1xuY29uc3QgTk9PUF9DT05URVhUX01BTkFHRVIgPSBuZXcgTm9vcENvbnRleHRNYW5hZ2VyKCk7XG5cbi8qKlxuICogU2luZ2xldG9uIG9iamVjdCB3aGljaCByZXByZXNlbnRzIHRoZSBlbnRyeSBwb2ludCB0byB0aGUgT3BlblRlbGVtZXRyeSBDb250ZXh0IEFQSVxuICovXG5leHBvcnQgY2xhc3MgQ29udGV4dEFQSSB7XG4gIHByaXZhdGUgc3RhdGljIF9pbnN0YW5jZT86IENvbnRleHRBUEk7XG5cbiAgLyoqIEVtcHR5IHByaXZhdGUgY29uc3RydWN0b3IgcHJldmVudHMgZW5kIHVzZXJzIGZyb20gY29uc3RydWN0aW5nIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBBUEkgKi9cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgLyoqIEdldCB0aGUgc2luZ2xldG9uIGluc3RhbmNlIG9mIHRoZSBDb250ZXh0IEFQSSAqL1xuICBwdWJsaWMgc3RhdGljIGdldEluc3RhbmNlKCk6IENvbnRleHRBUEkge1xuICAgIGlmICghdGhpcy5faW5zdGFuY2UpIHtcbiAgICAgIHRoaXMuX2luc3RhbmNlID0gbmV3IENvbnRleHRBUEkoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5faW5zdGFuY2U7XG4gIH1cblxuICAvKipcbiAgICogU2V0IHRoZSBjdXJyZW50IGNvbnRleHQgbWFuYWdlci5cbiAgICpcbiAgICogQHJldHVybnMgdHJ1ZSBpZiB0aGUgY29udGV4dCBtYW5hZ2VyIHdhcyBzdWNjZXNzZnVsbHkgcmVnaXN0ZXJlZCwgZWxzZSBmYWxzZVxuICAgKi9cbiAgcHVibGljIHNldEdsb2JhbENvbnRleHRNYW5hZ2VyKGNvbnRleHRNYW5hZ2VyOiBDb250ZXh0TWFuYWdlcik6IGJvb2xlYW4ge1xuICAgIHJldHVybiByZWdpc3Rlckdsb2JhbChBUElfTkFNRSwgY29udGV4dE1hbmFnZXIsIERpYWdBUEkuaW5zdGFuY2UoKSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBjdXJyZW50bHkgYWN0aXZlIGNvbnRleHRcbiAgICovXG4gIHB1YmxpYyBhY3RpdmUoKTogQ29udGV4dCB7XG4gICAgcmV0dXJuIHRoaXMuX2dldENvbnRleHRNYW5hZ2VyKCkuYWN0aXZlKCk7XG4gIH1cblxuICAvKipcbiAgICogRXhlY3V0ZSBhIGZ1bmN0aW9uIHdpdGggYW4gYWN0aXZlIGNvbnRleHRcbiAgICpcbiAgICogQHBhcmFtIGNvbnRleHQgY29udGV4dCB0byBiZSBhY3RpdmUgZHVyaW5nIGZ1bmN0aW9uIGV4ZWN1dGlvblxuICAgKiBAcGFyYW0gZm4gZnVuY3Rpb24gdG8gZXhlY3V0ZSBpbiBhIGNvbnRleHRcbiAgICogQHBhcmFtIHRoaXNBcmcgb3B0aW9uYWwgcmVjZWl2ZXIgdG8gYmUgdXNlZCBmb3IgY2FsbGluZyBmblxuICAgKiBAcGFyYW0gYXJncyBvcHRpb25hbCBhcmd1bWVudHMgZm9yd2FyZGVkIHRvIGZuXG4gICAqL1xuICBwdWJsaWMgd2l0aDxBIGV4dGVuZHMgdW5rbm93bltdLCBGIGV4dGVuZHMgKC4uLmFyZ3M6IEEpID0+IFJldHVyblR5cGU8Rj4+KFxuICAgIGNvbnRleHQ6IENvbnRleHQsXG4gICAgZm46IEYsXG4gICAgdGhpc0FyZz86IFRoaXNQYXJhbWV0ZXJUeXBlPEY+LFxuICAgIC4uLmFyZ3M6IEFcbiAgKTogUmV0dXJuVHlwZTxGPiB7XG4gICAgcmV0dXJuIHRoaXMuX2dldENvbnRleHRNYW5hZ2VyKCkud2l0aChjb250ZXh0LCBmbiwgdGhpc0FyZywgLi4uYXJncyk7XG4gIH1cblxuICAvKipcbiAgICogQmluZCBhIGNvbnRleHQgdG8gYSB0YXJnZXQgZnVuY3Rpb24gb3IgZXZlbnQgZW1pdHRlclxuICAgKlxuICAgKiBAcGFyYW0gY29udGV4dCBjb250ZXh0IHRvIGJpbmQgdG8gdGhlIGV2ZW50IGVtaXR0ZXIgb3IgZnVuY3Rpb24uIERlZmF1bHRzIHRvIHRoZSBjdXJyZW50bHkgYWN0aXZlIGNvbnRleHRcbiAgICogQHBhcmFtIHRhcmdldCBmdW5jdGlvbiBvciBldmVudCBlbWl0dGVyIHRvIGJpbmRcbiAgICovXG4gIHB1YmxpYyBiaW5kPFQ+KGNvbnRleHQ6IENvbnRleHQsIHRhcmdldDogVCk6IFQge1xuICAgIHJldHVybiB0aGlzLl9nZXRDb250ZXh0TWFuYWdlcigpLmJpbmQoY29udGV4dCwgdGFyZ2V0KTtcbiAgfVxuXG4gIHByaXZhdGUgX2dldENvbnRleHRNYW5hZ2VyKCk6IENvbnRleHRNYW5hZ2VyIHtcbiAgICByZXR1cm4gZ2V0R2xvYmFsKEFQSV9OQU1FKSB8fCBOT09QX0NPTlRFWFRfTUFOQUdFUjtcbiAgfVxuXG4gIC8qKiBEaXNhYmxlIGFuZCByZW1vdmUgdGhlIGdsb2JhbCBjb250ZXh0IG1hbmFnZXIgKi9cbiAgcHVibGljIGRpc2FibGUoKSB7XG4gICAgdGhpcy5fZ2V0Q29udGV4dE1hbmFnZXIoKS5kaXNhYmxlKCk7XG4gICAgdW5yZWdpc3Rlckdsb2JhbChBUElfTkFNRSwgRGlhZ0FQSS5pbnN0YW5jZSgpKTtcbiAgfVxufVxuIiwgIi8qXG4gKiBDb3B5cmlnaHQgVGhlIE9wZW5UZWxlbWV0cnkgQXV0aG9yc1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgIGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5leHBvcnQgZW51bSBUcmFjZUZsYWdzIHtcbiAgLyoqIFJlcHJlc2VudHMgbm8gZmxhZyBzZXQuICovXG4gIE5PTkUgPSAweDAsXG4gIC8qKiBCaXQgdG8gcmVwcmVzZW50IHdoZXRoZXIgdHJhY2UgaXMgc2FtcGxlZCBpbiB0cmFjZSBmbGFncy4gKi9cbiAgU0FNUExFRCA9IDB4MSA8PCAwLFxufVxuIiwgIi8qXG4gKiBDb3B5cmlnaHQgVGhlIE9wZW5UZWxlbWV0cnkgQXV0aG9yc1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgIGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IFNwYW5Db250ZXh0IH0gZnJvbSAnLi9zcGFuX2NvbnRleHQnO1xuaW1wb3J0IHsgVHJhY2VGbGFncyB9IGZyb20gJy4vdHJhY2VfZmxhZ3MnO1xuXG5leHBvcnQgY29uc3QgSU5WQUxJRF9TUEFOSUQgPSAnMDAwMDAwMDAwMDAwMDAwMCc7XG5leHBvcnQgY29uc3QgSU5WQUxJRF9UUkFDRUlEID0gJzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwJztcbmV4cG9ydCBjb25zdCBJTlZBTElEX1NQQU5fQ09OVEVYVDogU3BhbkNvbnRleHQgPSB7XG4gIHRyYWNlSWQ6IElOVkFMSURfVFJBQ0VJRCxcbiAgc3BhbklkOiBJTlZBTElEX1NQQU5JRCxcbiAgdHJhY2VGbGFnczogVHJhY2VGbGFncy5OT05FLFxufTtcbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5pbXBvcnQgeyBFeGNlcHRpb24gfSBmcm9tICcuLi9jb21tb24vRXhjZXB0aW9uJztcbmltcG9ydCB7IFRpbWVJbnB1dCB9IGZyb20gJy4uL2NvbW1vbi9UaW1lJztcbmltcG9ydCB7IFNwYW5BdHRyaWJ1dGVzIH0gZnJvbSAnLi9hdHRyaWJ1dGVzJztcbmltcG9ydCB7IElOVkFMSURfU1BBTl9DT05URVhUIH0gZnJvbSAnLi9pbnZhbGlkLXNwYW4tY29uc3RhbnRzJztcbmltcG9ydCB7IFNwYW4gfSBmcm9tICcuL3NwYW4nO1xuaW1wb3J0IHsgU3BhbkNvbnRleHQgfSBmcm9tICcuL3NwYW5fY29udGV4dCc7XG5pbXBvcnQgeyBTcGFuU3RhdHVzIH0gZnJvbSAnLi9zdGF0dXMnO1xuaW1wb3J0IHsgTGluayB9IGZyb20gJy4vbGluayc7XG5cbi8qKlxuICogVGhlIE5vblJlY29yZGluZ1NwYW4gaXMgdGhlIGRlZmF1bHQge0BsaW5rIFNwYW59IHRoYXQgaXMgdXNlZCB3aGVuIG5vIFNwYW5cbiAqIGltcGxlbWVudGF0aW9uIGlzIGF2YWlsYWJsZS4gQWxsIG9wZXJhdGlvbnMgYXJlIG5vLW9wIGluY2x1ZGluZyBjb250ZXh0XG4gKiBwcm9wYWdhdGlvbi5cbiAqL1xuZXhwb3J0IGNsYXNzIE5vblJlY29yZGluZ1NwYW4gaW1wbGVtZW50cyBTcGFuIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBfc3BhbkNvbnRleHQ6IFNwYW5Db250ZXh0ID0gSU5WQUxJRF9TUEFOX0NPTlRFWFRcbiAgKSB7fVxuXG4gIC8vIFJldHVybnMgYSBTcGFuQ29udGV4dC5cbiAgc3BhbkNvbnRleHQoKTogU3BhbkNvbnRleHQge1xuICAgIHJldHVybiB0aGlzLl9zcGFuQ29udGV4dDtcbiAgfVxuXG4gIC8vIEJ5IGRlZmF1bHQgZG9lcyBub3RoaW5nXG4gIHNldEF0dHJpYnV0ZShfa2V5OiBzdHJpbmcsIF92YWx1ZTogdW5rbm93bik6IHRoaXMge1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gQnkgZGVmYXVsdCBkb2VzIG5vdGhpbmdcbiAgc2V0QXR0cmlidXRlcyhfYXR0cmlidXRlczogU3BhbkF0dHJpYnV0ZXMpOiB0aGlzIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIEJ5IGRlZmF1bHQgZG9lcyBub3RoaW5nXG4gIGFkZEV2ZW50KF9uYW1lOiBzdHJpbmcsIF9hdHRyaWJ1dGVzPzogU3BhbkF0dHJpYnV0ZXMpOiB0aGlzIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGFkZExpbmsoX2xpbms6IExpbmspOiB0aGlzIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGFkZExpbmtzKF9saW5rczogTGlua1tdKTogdGhpcyB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBCeSBkZWZhdWx0IGRvZXMgbm90aGluZ1xuICBzZXRTdGF0dXMoX3N0YXR1czogU3BhblN0YXR1cyk6IHRoaXMge1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gQnkgZGVmYXVsdCBkb2VzIG5vdGhpbmdcbiAgdXBkYXRlTmFtZShfbmFtZTogc3RyaW5nKTogdGhpcyB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBCeSBkZWZhdWx0IGRvZXMgbm90aGluZ1xuICBlbmQoX2VuZFRpbWU/OiBUaW1lSW5wdXQpOiB2b2lkIHt9XG5cbiAgLy8gaXNSZWNvcmRpbmcgYWx3YXlzIHJldHVybnMgZmFsc2UgZm9yIE5vblJlY29yZGluZ1NwYW4uXG4gIGlzUmVjb3JkaW5nKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIEJ5IGRlZmF1bHQgZG9lcyBub3RoaW5nXG4gIHJlY29yZEV4Y2VwdGlvbihfZXhjZXB0aW9uOiBFeGNlcHRpb24sIF90aW1lPzogVGltZUlucHV0KTogdm9pZCB7fVxufVxuIiwgIi8qXG4gKiBDb3B5cmlnaHQgVGhlIE9wZW5UZWxlbWV0cnkgQXV0aG9yc1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgIGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IGNyZWF0ZUNvbnRleHRLZXkgfSBmcm9tICcuLi9jb250ZXh0L2NvbnRleHQnO1xuaW1wb3J0IHsgQ29udGV4dCB9IGZyb20gJy4uL2NvbnRleHQvdHlwZXMnO1xuaW1wb3J0IHsgU3BhbiB9IGZyb20gJy4vc3Bhbic7XG5pbXBvcnQgeyBTcGFuQ29udGV4dCB9IGZyb20gJy4vc3Bhbl9jb250ZXh0JztcbmltcG9ydCB7IE5vblJlY29yZGluZ1NwYW4gfSBmcm9tICcuL05vblJlY29yZGluZ1NwYW4nO1xuaW1wb3J0IHsgQ29udGV4dEFQSSB9IGZyb20gJy4uL2FwaS9jb250ZXh0JztcblxuLyoqXG4gKiBzcGFuIGtleVxuICovXG5jb25zdCBTUEFOX0tFWSA9IGNyZWF0ZUNvbnRleHRLZXkoJ09wZW5UZWxlbWV0cnkgQ29udGV4dCBLZXkgU1BBTicpO1xuXG4vKipcbiAqIFJldHVybiB0aGUgc3BhbiBpZiBvbmUgZXhpc3RzXG4gKlxuICogQHBhcmFtIGNvbnRleHQgY29udGV4dCB0byBnZXQgc3BhbiBmcm9tXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRTcGFuKGNvbnRleHQ6IENvbnRleHQpOiBTcGFuIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIChjb250ZXh0LmdldFZhbHVlKFNQQU5fS0VZKSBhcyBTcGFuKSB8fCB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogR2V0cyB0aGUgc3BhbiBmcm9tIHRoZSBjdXJyZW50IGNvbnRleHQsIGlmIG9uZSBleGlzdHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRBY3RpdmVTcGFuKCk6IFNwYW4gfCB1bmRlZmluZWQge1xuICByZXR1cm4gZ2V0U3BhbihDb250ZXh0QVBJLmdldEluc3RhbmNlKCkuYWN0aXZlKCkpO1xufVxuXG4vKipcbiAqIFNldCB0aGUgc3BhbiBvbiBhIGNvbnRleHRcbiAqXG4gKiBAcGFyYW0gY29udGV4dCBjb250ZXh0IHRvIHVzZSBhcyBwYXJlbnRcbiAqIEBwYXJhbSBzcGFuIHNwYW4gdG8gc2V0IGFjdGl2ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0U3Bhbihjb250ZXh0OiBDb250ZXh0LCBzcGFuOiBTcGFuKTogQ29udGV4dCB7XG4gIHJldHVybiBjb250ZXh0LnNldFZhbHVlKFNQQU5fS0VZLCBzcGFuKTtcbn1cblxuLyoqXG4gKiBSZW1vdmUgY3VycmVudCBzcGFuIHN0b3JlZCBpbiB0aGUgY29udGV4dFxuICpcbiAqIEBwYXJhbSBjb250ZXh0IGNvbnRleHQgdG8gZGVsZXRlIHNwYW4gZnJvbVxuICovXG5leHBvcnQgZnVuY3Rpb24gZGVsZXRlU3Bhbihjb250ZXh0OiBDb250ZXh0KTogQ29udGV4dCB7XG4gIHJldHVybiBjb250ZXh0LmRlbGV0ZVZhbHVlKFNQQU5fS0VZKTtcbn1cblxuLyoqXG4gKiBXcmFwIHNwYW4gY29udGV4dCBpbiBhIE5vb3BTcGFuIGFuZCBzZXQgYXMgc3BhbiBpbiBhIG5ld1xuICogY29udGV4dFxuICpcbiAqIEBwYXJhbSBjb250ZXh0IGNvbnRleHQgdG8gc2V0IGFjdGl2ZSBzcGFuIG9uXG4gKiBAcGFyYW0gc3BhbkNvbnRleHQgc3BhbiBjb250ZXh0IHRvIGJlIHdyYXBwZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldFNwYW5Db250ZXh0KFxuICBjb250ZXh0OiBDb250ZXh0LFxuICBzcGFuQ29udGV4dDogU3BhbkNvbnRleHRcbik6IENvbnRleHQge1xuICByZXR1cm4gc2V0U3Bhbihjb250ZXh0LCBuZXcgTm9uUmVjb3JkaW5nU3BhbihzcGFuQ29udGV4dCkpO1xufVxuXG4vKipcbiAqIEdldCB0aGUgc3BhbiBjb250ZXh0IG9mIHRoZSBzcGFuIGlmIGl0IGV4aXN0cy5cbiAqXG4gKiBAcGFyYW0gY29udGV4dCBjb250ZXh0IHRvIGdldCB2YWx1ZXMgZnJvbVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0U3BhbkNvbnRleHQoY29udGV4dDogQ29udGV4dCk6IFNwYW5Db250ZXh0IHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIGdldFNwYW4oY29udGV4dCk/LnNwYW5Db250ZXh0KCk7XG59XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbmltcG9ydCB7IElOVkFMSURfU1BBTklELCBJTlZBTElEX1RSQUNFSUQgfSBmcm9tICcuL2ludmFsaWQtc3Bhbi1jb25zdGFudHMnO1xuaW1wb3J0IHsgTm9uUmVjb3JkaW5nU3BhbiB9IGZyb20gJy4vTm9uUmVjb3JkaW5nU3Bhbic7XG5pbXBvcnQgeyBTcGFuIH0gZnJvbSAnLi9zcGFuJztcbmltcG9ydCB7IFNwYW5Db250ZXh0IH0gZnJvbSAnLi9zcGFuX2NvbnRleHQnO1xuXG5jb25zdCBWQUxJRF9UUkFDRUlEX1JFR0VYID0gL14oWzAtOWEtZl17MzJ9KSQvaTtcbmNvbnN0IFZBTElEX1NQQU5JRF9SRUdFWCA9IC9eWzAtOWEtZl17MTZ9JC9pO1xuXG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZFRyYWNlSWQodHJhY2VJZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBWQUxJRF9UUkFDRUlEX1JFR0VYLnRlc3QodHJhY2VJZCkgJiYgdHJhY2VJZCAhPT0gSU5WQUxJRF9UUkFDRUlEO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZFNwYW5JZChzcGFuSWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gVkFMSURfU1BBTklEX1JFR0VYLnRlc3Qoc3BhbklkKSAmJiBzcGFuSWQgIT09IElOVkFMSURfU1BBTklEO1xufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIHtAbGluayBTcGFuQ29udGV4dH0gaXMgdmFsaWQuXG4gKiBAcmV0dXJuIHRydWUgaWYgdGhpcyB7QGxpbmsgU3BhbkNvbnRleHR9IGlzIHZhbGlkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNTcGFuQ29udGV4dFZhbGlkKHNwYW5Db250ZXh0OiBTcGFuQ29udGV4dCk6IGJvb2xlYW4ge1xuICByZXR1cm4gKFxuICAgIGlzVmFsaWRUcmFjZUlkKHNwYW5Db250ZXh0LnRyYWNlSWQpICYmIGlzVmFsaWRTcGFuSWQoc3BhbkNvbnRleHQuc3BhbklkKVxuICApO1xufVxuXG4vKipcbiAqIFdyYXAgdGhlIGdpdmVuIHtAbGluayBTcGFuQ29udGV4dH0gaW4gYSBuZXcgbm9uLXJlY29yZGluZyB7QGxpbmsgU3Bhbn1cbiAqXG4gKiBAcGFyYW0gc3BhbkNvbnRleHQgc3BhbiBjb250ZXh0IHRvIGJlIHdyYXBwZWRcbiAqIEByZXR1cm5zIGEgbmV3IG5vbi1yZWNvcmRpbmcge0BsaW5rIFNwYW59IHdpdGggdGhlIHByb3ZpZGVkIGNvbnRleHRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdyYXBTcGFuQ29udGV4dChzcGFuQ29udGV4dDogU3BhbkNvbnRleHQpOiBTcGFuIHtcbiAgcmV0dXJuIG5ldyBOb25SZWNvcmRpbmdTcGFuKHNwYW5Db250ZXh0KTtcbn1cbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5pbXBvcnQgeyBDb250ZXh0QVBJIH0gZnJvbSAnLi4vYXBpL2NvbnRleHQnO1xuaW1wb3J0IHsgQ29udGV4dCB9IGZyb20gJy4uL2NvbnRleHQvdHlwZXMnO1xuaW1wb3J0IHsgZ2V0U3BhbkNvbnRleHQsIHNldFNwYW4gfSBmcm9tICcuLi90cmFjZS9jb250ZXh0LXV0aWxzJztcbmltcG9ydCB7IE5vblJlY29yZGluZ1NwYW4gfSBmcm9tICcuL05vblJlY29yZGluZ1NwYW4nO1xuaW1wb3J0IHsgU3BhbiB9IGZyb20gJy4vc3Bhbic7XG5pbXBvcnQgeyBpc1NwYW5Db250ZXh0VmFsaWQgfSBmcm9tICcuL3NwYW5jb250ZXh0LXV0aWxzJztcbmltcG9ydCB7IFNwYW5PcHRpb25zIH0gZnJvbSAnLi9TcGFuT3B0aW9ucyc7XG5pbXBvcnQgeyBTcGFuQ29udGV4dCB9IGZyb20gJy4vc3Bhbl9jb250ZXh0JztcbmltcG9ydCB7IFRyYWNlciB9IGZyb20gJy4vdHJhY2VyJztcblxuY29uc3QgY29udGV4dEFwaSA9IENvbnRleHRBUEkuZ2V0SW5zdGFuY2UoKTtcblxuLyoqXG4gKiBOby1vcCBpbXBsZW1lbnRhdGlvbnMgb2Yge0BsaW5rIFRyYWNlcn0uXG4gKi9cbmV4cG9ydCBjbGFzcyBOb29wVHJhY2VyIGltcGxlbWVudHMgVHJhY2VyIHtcbiAgLy8gc3RhcnRTcGFuIHN0YXJ0cyBhIG5vb3Agc3Bhbi5cbiAgc3RhcnRTcGFuKFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBvcHRpb25zPzogU3Bhbk9wdGlvbnMsXG4gICAgY29udGV4dCA9IGNvbnRleHRBcGkuYWN0aXZlKClcbiAgKTogU3BhbiB7XG4gICAgY29uc3Qgcm9vdCA9IEJvb2xlYW4ob3B0aW9ucz8ucm9vdCk7XG4gICAgaWYgKHJvb3QpIHtcbiAgICAgIHJldHVybiBuZXcgTm9uUmVjb3JkaW5nU3BhbigpO1xuICAgIH1cblxuICAgIGNvbnN0IHBhcmVudEZyb21Db250ZXh0ID0gY29udGV4dCAmJiBnZXRTcGFuQ29udGV4dChjb250ZXh0KTtcblxuICAgIGlmIChcbiAgICAgIGlzU3BhbkNvbnRleHQocGFyZW50RnJvbUNvbnRleHQpICYmXG4gICAgICBpc1NwYW5Db250ZXh0VmFsaWQocGFyZW50RnJvbUNvbnRleHQpXG4gICAgKSB7XG4gICAgICByZXR1cm4gbmV3IE5vblJlY29yZGluZ1NwYW4ocGFyZW50RnJvbUNvbnRleHQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbmV3IE5vblJlY29yZGluZ1NwYW4oKTtcbiAgICB9XG4gIH1cblxuICBzdGFydEFjdGl2ZVNwYW48RiBleHRlbmRzIChzcGFuOiBTcGFuKSA9PiBSZXR1cm5UeXBlPEY+PihcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgZm46IEZcbiAgKTogUmV0dXJuVHlwZTxGPjtcbiAgc3RhcnRBY3RpdmVTcGFuPEYgZXh0ZW5kcyAoc3BhbjogU3BhbikgPT4gUmV0dXJuVHlwZTxGPj4oXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIG9wdHM6IFNwYW5PcHRpb25zIHwgdW5kZWZpbmVkLFxuICAgIGZuOiBGXG4gICk6IFJldHVyblR5cGU8Rj47XG4gIHN0YXJ0QWN0aXZlU3BhbjxGIGV4dGVuZHMgKHNwYW46IFNwYW4pID0+IFJldHVyblR5cGU8Rj4+KFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBvcHRzOiBTcGFuT3B0aW9ucyB8IHVuZGVmaW5lZCxcbiAgICBjdHg6IENvbnRleHQgfCB1bmRlZmluZWQsXG4gICAgZm46IEZcbiAgKTogUmV0dXJuVHlwZTxGPjtcbiAgc3RhcnRBY3RpdmVTcGFuPEYgZXh0ZW5kcyAoc3BhbjogU3BhbikgPT4gUmV0dXJuVHlwZTxGPj4oXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIGFyZzI/OiBGIHwgU3Bhbk9wdGlvbnMsXG4gICAgYXJnMz86IEYgfCBDb250ZXh0LFxuICAgIGFyZzQ/OiBGXG4gICk6IFJldHVyblR5cGU8Rj4gfCB1bmRlZmluZWQge1xuICAgIGxldCBvcHRzOiBTcGFuT3B0aW9ucyB8IHVuZGVmaW5lZDtcbiAgICBsZXQgY3R4OiBDb250ZXh0IHwgdW5kZWZpbmVkO1xuICAgIGxldCBmbjogRjtcblxuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMikge1xuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMikge1xuICAgICAgZm4gPSBhcmcyIGFzIEY7XG4gICAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAzKSB7XG4gICAgICBvcHRzID0gYXJnMiBhcyBTcGFuT3B0aW9ucyB8IHVuZGVmaW5lZDtcbiAgICAgIGZuID0gYXJnMyBhcyBGO1xuICAgIH0gZWxzZSB7XG4gICAgICBvcHRzID0gYXJnMiBhcyBTcGFuT3B0aW9ucyB8IHVuZGVmaW5lZDtcbiAgICAgIGN0eCA9IGFyZzMgYXMgQ29udGV4dCB8IHVuZGVmaW5lZDtcbiAgICAgIGZuID0gYXJnNCBhcyBGO1xuICAgIH1cblxuICAgIGNvbnN0IHBhcmVudENvbnRleHQgPSBjdHggPz8gY29udGV4dEFwaS5hY3RpdmUoKTtcbiAgICBjb25zdCBzcGFuID0gdGhpcy5zdGFydFNwYW4obmFtZSwgb3B0cywgcGFyZW50Q29udGV4dCk7XG4gICAgY29uc3QgY29udGV4dFdpdGhTcGFuU2V0ID0gc2V0U3BhbihwYXJlbnRDb250ZXh0LCBzcGFuKTtcblxuICAgIHJldHVybiBjb250ZXh0QXBpLndpdGgoY29udGV4dFdpdGhTcGFuU2V0LCBmbiwgdW5kZWZpbmVkLCBzcGFuKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpc1NwYW5Db250ZXh0KHNwYW5Db250ZXh0OiBhbnkpOiBzcGFuQ29udGV4dCBpcyBTcGFuQ29udGV4dCB7XG4gIHJldHVybiAoXG4gICAgdHlwZW9mIHNwYW5Db250ZXh0ID09PSAnb2JqZWN0JyAmJlxuICAgIHR5cGVvZiBzcGFuQ29udGV4dFsnc3BhbklkJ10gPT09ICdzdHJpbmcnICYmXG4gICAgdHlwZW9mIHNwYW5Db250ZXh0Wyd0cmFjZUlkJ10gPT09ICdzdHJpbmcnICYmXG4gICAgdHlwZW9mIHNwYW5Db250ZXh0Wyd0cmFjZUZsYWdzJ10gPT09ICdudW1iZXInXG4gICk7XG59XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuaW1wb3J0IHsgQ29udGV4dCB9IGZyb20gJy4uL2NvbnRleHQvdHlwZXMnO1xuaW1wb3J0IHsgTm9vcFRyYWNlciB9IGZyb20gJy4vTm9vcFRyYWNlcic7XG5pbXBvcnQgeyBTcGFuIH0gZnJvbSAnLi9zcGFuJztcbmltcG9ydCB7IFNwYW5PcHRpb25zIH0gZnJvbSAnLi9TcGFuT3B0aW9ucyc7XG5pbXBvcnQgeyBUcmFjZXIgfSBmcm9tICcuL3RyYWNlcic7XG5pbXBvcnQgeyBUcmFjZXJPcHRpb25zIH0gZnJvbSAnLi90cmFjZXJfb3B0aW9ucyc7XG5cbmNvbnN0IE5PT1BfVFJBQ0VSID0gbmV3IE5vb3BUcmFjZXIoKTtcblxuLyoqXG4gKiBQcm94eSB0cmFjZXIgcHJvdmlkZWQgYnkgdGhlIHByb3h5IHRyYWNlciBwcm92aWRlclxuICovXG5leHBvcnQgY2xhc3MgUHJveHlUcmFjZXIgaW1wbGVtZW50cyBUcmFjZXIge1xuICAvLyBXaGVuIGEgcmVhbCBpbXBsZW1lbnRhdGlvbiBpcyBwcm92aWRlZCwgdGhpcyB3aWxsIGJlIGl0XG4gIHByaXZhdGUgX2RlbGVnYXRlPzogVHJhY2VyO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgX3Byb3ZpZGVyOiBUcmFjZXJEZWxlZ2F0b3IsXG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWU6IHN0cmluZyxcbiAgICBwdWJsaWMgcmVhZG9ubHkgdmVyc2lvbj86IHN0cmluZyxcbiAgICBwdWJsaWMgcmVhZG9ubHkgb3B0aW9ucz86IFRyYWNlck9wdGlvbnNcbiAgKSB7fVxuXG4gIHN0YXJ0U3BhbihuYW1lOiBzdHJpbmcsIG9wdGlvbnM/OiBTcGFuT3B0aW9ucywgY29udGV4dD86IENvbnRleHQpOiBTcGFuIHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0VHJhY2VyKCkuc3RhcnRTcGFuKG5hbWUsIG9wdGlvbnMsIGNvbnRleHQpO1xuICB9XG5cbiAgc3RhcnRBY3RpdmVTcGFuPEYgZXh0ZW5kcyAoc3BhbjogU3BhbikgPT4gdW5rbm93bj4oXG4gICAgX25hbWU6IHN0cmluZyxcbiAgICBfb3B0aW9uczogRiB8IFNwYW5PcHRpb25zLFxuICAgIF9jb250ZXh0PzogRiB8IENvbnRleHQsXG4gICAgX2ZuPzogRlxuICApOiBSZXR1cm5UeXBlPEY+IHtcbiAgICBjb25zdCB0cmFjZXIgPSB0aGlzLl9nZXRUcmFjZXIoKTtcbiAgICByZXR1cm4gUmVmbGVjdC5hcHBseSh0cmFjZXIuc3RhcnRBY3RpdmVTcGFuLCB0cmFjZXIsIGFyZ3VtZW50cyk7XG4gIH1cblxuICAvKipcbiAgICogVHJ5IHRvIGdldCBhIHRyYWNlciBmcm9tIHRoZSBwcm94eSB0cmFjZXIgcHJvdmlkZXIuXG4gICAqIElmIHRoZSBwcm94eSB0cmFjZXIgcHJvdmlkZXIgaGFzIG5vIGRlbGVnYXRlLCByZXR1cm4gYSBub29wIHRyYWNlci5cbiAgICovXG4gIHByaXZhdGUgX2dldFRyYWNlcigpIHtcbiAgICBpZiAodGhpcy5fZGVsZWdhdGUpIHtcbiAgICAgIHJldHVybiB0aGlzLl9kZWxlZ2F0ZTtcbiAgICB9XG5cbiAgICBjb25zdCB0cmFjZXIgPSB0aGlzLl9wcm92aWRlci5nZXREZWxlZ2F0ZVRyYWNlcihcbiAgICAgIHRoaXMubmFtZSxcbiAgICAgIHRoaXMudmVyc2lvbixcbiAgICAgIHRoaXMub3B0aW9uc1xuICAgICk7XG5cbiAgICBpZiAoIXRyYWNlcikge1xuICAgICAgcmV0dXJuIE5PT1BfVFJBQ0VSO1xuICAgIH1cblxuICAgIHRoaXMuX2RlbGVnYXRlID0gdHJhY2VyO1xuICAgIHJldHVybiB0aGlzLl9kZWxlZ2F0ZTtcbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRyYWNlckRlbGVnYXRvciB7XG4gIGdldERlbGVnYXRlVHJhY2VyKFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICB2ZXJzaW9uPzogc3RyaW5nLFxuICAgIG9wdGlvbnM/OiBUcmFjZXJPcHRpb25zXG4gICk6IFRyYWNlciB8IHVuZGVmaW5lZDtcbn1cbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5pbXBvcnQgeyBOb29wVHJhY2VyIH0gZnJvbSAnLi9Ob29wVHJhY2VyJztcbmltcG9ydCB7IFRyYWNlciB9IGZyb20gJy4vdHJhY2VyJztcbmltcG9ydCB7IFRyYWNlck9wdGlvbnMgfSBmcm9tICcuL3RyYWNlcl9vcHRpb25zJztcbmltcG9ydCB7IFRyYWNlclByb3ZpZGVyIH0gZnJvbSAnLi90cmFjZXJfcHJvdmlkZXInO1xuXG4vKipcbiAqIEFuIGltcGxlbWVudGF0aW9uIG9mIHRoZSB7QGxpbmsgVHJhY2VyUHJvdmlkZXJ9IHdoaWNoIHJldHVybnMgYW4gaW1wb3RlbnRcbiAqIFRyYWNlciBmb3IgYWxsIGNhbGxzIHRvIGBnZXRUcmFjZXJgLlxuICpcbiAqIEFsbCBvcGVyYXRpb25zIGFyZSBuby1vcC5cbiAqL1xuZXhwb3J0IGNsYXNzIE5vb3BUcmFjZXJQcm92aWRlciBpbXBsZW1lbnRzIFRyYWNlclByb3ZpZGVyIHtcbiAgZ2V0VHJhY2VyKFxuICAgIF9uYW1lPzogc3RyaW5nLFxuICAgIF92ZXJzaW9uPzogc3RyaW5nLFxuICAgIF9vcHRpb25zPzogVHJhY2VyT3B0aW9uc1xuICApOiBUcmFjZXIge1xuICAgIHJldHVybiBuZXcgTm9vcFRyYWNlcigpO1xuICB9XG59XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuaW1wb3J0IHsgVHJhY2VyIH0gZnJvbSAnLi90cmFjZXInO1xuaW1wb3J0IHsgVHJhY2VyUHJvdmlkZXIgfSBmcm9tICcuL3RyYWNlcl9wcm92aWRlcic7XG5pbXBvcnQgeyBQcm94eVRyYWNlciB9IGZyb20gJy4vUHJveHlUcmFjZXInO1xuaW1wb3J0IHsgTm9vcFRyYWNlclByb3ZpZGVyIH0gZnJvbSAnLi9Ob29wVHJhY2VyUHJvdmlkZXInO1xuaW1wb3J0IHsgVHJhY2VyT3B0aW9ucyB9IGZyb20gJy4vdHJhY2VyX29wdGlvbnMnO1xuXG5jb25zdCBOT09QX1RSQUNFUl9QUk9WSURFUiA9IG5ldyBOb29wVHJhY2VyUHJvdmlkZXIoKTtcblxuLyoqXG4gKiBUcmFjZXIgcHJvdmlkZXIgd2hpY2ggcHJvdmlkZXMge0BsaW5rIFByb3h5VHJhY2VyfXMuXG4gKlxuICogQmVmb3JlIGEgZGVsZWdhdGUgaXMgc2V0LCB0cmFjZXJzIHByb3ZpZGVkIGFyZSBOb09wLlxuICogICBXaGVuIGEgZGVsZWdhdGUgaXMgc2V0LCB0cmFjZXMgYXJlIHByb3ZpZGVkIGZyb20gdGhlIGRlbGVnYXRlLlxuICogICBXaGVuIGEgZGVsZWdhdGUgaXMgc2V0IGFmdGVyIHRyYWNlcnMgaGF2ZSBhbHJlYWR5IGJlZW4gcHJvdmlkZWQsXG4gKiAgIGFsbCB0cmFjZXJzIGFscmVhZHkgcHJvdmlkZWQgd2lsbCB1c2UgdGhlIHByb3ZpZGVkIGRlbGVnYXRlIGltcGxlbWVudGF0aW9uLlxuICovXG5leHBvcnQgY2xhc3MgUHJveHlUcmFjZXJQcm92aWRlciBpbXBsZW1lbnRzIFRyYWNlclByb3ZpZGVyIHtcbiAgcHJpdmF0ZSBfZGVsZWdhdGU/OiBUcmFjZXJQcm92aWRlcjtcblxuICAvKipcbiAgICogR2V0IGEge0BsaW5rIFByb3h5VHJhY2VyfVxuICAgKi9cbiAgZ2V0VHJhY2VyKG5hbWU6IHN0cmluZywgdmVyc2lvbj86IHN0cmluZywgb3B0aW9ucz86IFRyYWNlck9wdGlvbnMpOiBUcmFjZXIge1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLmdldERlbGVnYXRlVHJhY2VyKG5hbWUsIHZlcnNpb24sIG9wdGlvbnMpID8/XG4gICAgICBuZXcgUHJveHlUcmFjZXIodGhpcywgbmFtZSwgdmVyc2lvbiwgb3B0aW9ucylcbiAgICApO1xuICB9XG5cbiAgZ2V0RGVsZWdhdGUoKTogVHJhY2VyUHJvdmlkZXIge1xuICAgIHJldHVybiB0aGlzLl9kZWxlZ2F0ZSA/PyBOT09QX1RSQUNFUl9QUk9WSURFUjtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgdGhlIGRlbGVnYXRlIHRyYWNlciBwcm92aWRlclxuICAgKi9cbiAgc2V0RGVsZWdhdGUoZGVsZWdhdGU6IFRyYWNlclByb3ZpZGVyKSB7XG4gICAgdGhpcy5fZGVsZWdhdGUgPSBkZWxlZ2F0ZTtcbiAgfVxuXG4gIGdldERlbGVnYXRlVHJhY2VyKFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICB2ZXJzaW9uPzogc3RyaW5nLFxuICAgIG9wdGlvbnM/OiBUcmFjZXJPcHRpb25zXG4gICk6IFRyYWNlciB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuX2RlbGVnYXRlPy5nZXRUcmFjZXIobmFtZSwgdmVyc2lvbiwgb3B0aW9ucyk7XG4gIH1cbn1cbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5pbXBvcnQgeyBTcGFuQXR0cmlidXRlcyB9IGZyb20gJy4vYXR0cmlidXRlcyc7XG5pbXBvcnQgeyBUcmFjZVN0YXRlIH0gZnJvbSAnLi90cmFjZV9zdGF0ZSc7XG5cbi8qKlxuICogQGRlcHJlY2F0ZWQgdXNlIHRoZSBvbmUgZGVjbGFyZWQgaW4gQG9wZW50ZWxlbWV0cnkvc2RrLXRyYWNlLWJhc2UgaW5zdGVhZC5cbiAqIEEgc2FtcGxpbmcgZGVjaXNpb24gdGhhdCBkZXRlcm1pbmVzIGhvdyBhIHtAbGluayBTcGFufSB3aWxsIGJlIHJlY29yZGVkXG4gKiBhbmQgY29sbGVjdGVkLlxuICovXG5leHBvcnQgZW51bSBTYW1wbGluZ0RlY2lzaW9uIHtcbiAgLyoqXG4gICAqIGBTcGFuLmlzUmVjb3JkaW5nKCkgPT09IGZhbHNlYCwgc3BhbiB3aWxsIG5vdCBiZSByZWNvcmRlZCBhbmQgYWxsIGV2ZW50c1xuICAgKiBhbmQgYXR0cmlidXRlcyB3aWxsIGJlIGRyb3BwZWQuXG4gICAqL1xuICBOT1RfUkVDT1JELFxuICAvKipcbiAgICogYFNwYW4uaXNSZWNvcmRpbmcoKSA9PT0gdHJ1ZWAsIGJ1dCBgU2FtcGxlZGAgZmxhZyBpbiB7QGxpbmsgVHJhY2VGbGFnc31cbiAgICogTVVTVCBOT1QgYmUgc2V0LlxuICAgKi9cbiAgUkVDT1JELFxuICAvKipcbiAgICogYFNwYW4uaXNSZWNvcmRpbmcoKSA9PT0gdHJ1ZWAgQU5EIGBTYW1wbGVkYCBmbGFnIGluIHtAbGluayBUcmFjZUZsYWdzfVxuICAgKiBNVVNUIGJlIHNldC5cbiAgICovXG4gIFJFQ09SRF9BTkRfU0FNUExFRCxcbn1cblxuLyoqXG4gKiBAZGVwcmVjYXRlZCB1c2UgdGhlIG9uZSBkZWNsYXJlZCBpbiBAb3BlbnRlbGVtZXRyeS9zZGstdHJhY2UtYmFzZSBpbnN0ZWFkLlxuICogQSBzYW1wbGluZyByZXN1bHQgY29udGFpbnMgYSBkZWNpc2lvbiBmb3IgYSB7QGxpbmsgU3Bhbn0gYW5kIGFkZGl0aW9uYWxcbiAqIGF0dHJpYnV0ZXMgdGhlIHNhbXBsZXIgd291bGQgbGlrZSB0byBhZGRlZCB0byB0aGUgU3Bhbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTYW1wbGluZ1Jlc3VsdCB7XG4gIC8qKlxuICAgKiBBIHNhbXBsaW5nIGRlY2lzaW9uLCByZWZlciB0byB7QGxpbmsgU2FtcGxpbmdEZWNpc2lvbn0gZm9yIGRldGFpbHMuXG4gICAqL1xuICBkZWNpc2lvbjogU2FtcGxpbmdEZWNpc2lvbjtcbiAgLyoqXG4gICAqIFRoZSBsaXN0IG9mIGF0dHJpYnV0ZXMgcmV0dXJuZWQgYnkgU2FtcGxpbmdSZXN1bHQgTVVTVCBiZSBpbW11dGFibGUuXG4gICAqIENhbGxlciBtYXkgY2FsbCB7QGxpbmsgU2FtcGxlcn0uc2hvdWxkU2FtcGxlIGFueSBudW1iZXIgb2YgdGltZXMgYW5kXG4gICAqIGNhbiBzYWZlbHkgY2FjaGUgdGhlIHJldHVybmVkIHZhbHVlLlxuICAgKi9cbiAgYXR0cmlidXRlcz86IFJlYWRvbmx5PFNwYW5BdHRyaWJ1dGVzPjtcbiAgLyoqXG4gICAqIEEge0BsaW5rIFRyYWNlU3RhdGV9IHRoYXQgd2lsbCBiZSBhc3NvY2lhdGVkIHdpdGggdGhlIHtAbGluayBTcGFufSB0aHJvdWdoXG4gICAqIHRoZSBuZXcge0BsaW5rIFNwYW5Db250ZXh0fS4gU2FtcGxlcnMgU0hPVUxEIHJldHVybiB0aGUgVHJhY2VTdGF0ZSBmcm9tXG4gICAqIHRoZSBwYXNzZWQtaW4ge0BsaW5rIENvbnRleHR9IGlmIHRoZXkgZG8gbm90IGludGVuZCB0byBjaGFuZ2UgaXQuIExlYXZpbmdcbiAgICogdGhlIHZhbHVlIHVuZGVmaW5lZCB3aWxsIGFsc28gbGVhdmUgdGhlIFRyYWNlU3RhdGUgdW5jaGFuZ2VkLlxuICAgKi9cbiAgdHJhY2VTdGF0ZT86IFRyYWNlU3RhdGU7XG59XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbmV4cG9ydCBlbnVtIFNwYW5LaW5kIHtcbiAgLyoqIERlZmF1bHQgdmFsdWUuIEluZGljYXRlcyB0aGF0IHRoZSBzcGFuIGlzIHVzZWQgaW50ZXJuYWxseS4gKi9cbiAgSU5URVJOQUwgPSAwLFxuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgdGhhdCB0aGUgc3BhbiBjb3ZlcnMgc2VydmVyLXNpZGUgaGFuZGxpbmcgb2YgYW4gUlBDIG9yIG90aGVyXG4gICAqIHJlbW90ZSByZXF1ZXN0LlxuICAgKi9cbiAgU0VSVkVSID0gMSxcblxuICAvKipcbiAgICogSW5kaWNhdGVzIHRoYXQgdGhlIHNwYW4gY292ZXJzIHRoZSBjbGllbnQtc2lkZSB3cmFwcGVyIGFyb3VuZCBhbiBSUEMgb3JcbiAgICogb3RoZXIgcmVtb3RlIHJlcXVlc3QuXG4gICAqL1xuICBDTElFTlQgPSAyLFxuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgdGhhdCB0aGUgc3BhbiBkZXNjcmliZXMgcHJvZHVjZXIgc2VuZGluZyBhIG1lc3NhZ2UgdG8gYVxuICAgKiBicm9rZXIuIFVubGlrZSBjbGllbnQgYW5kIHNlcnZlciwgdGhlcmUgaXMgbm8gZGlyZWN0IGNyaXRpY2FsIHBhdGggbGF0ZW5jeVxuICAgKiByZWxhdGlvbnNoaXAgYmV0d2VlbiBwcm9kdWNlciBhbmQgY29uc3VtZXIgc3BhbnMuXG4gICAqL1xuICBQUk9EVUNFUiA9IDMsXG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyB0aGF0IHRoZSBzcGFuIGRlc2NyaWJlcyBjb25zdW1lciByZWNlaXZpbmcgYSBtZXNzYWdlIGZyb20gYVxuICAgKiBicm9rZXIuIFVubGlrZSBjbGllbnQgYW5kIHNlcnZlciwgdGhlcmUgaXMgbm8gZGlyZWN0IGNyaXRpY2FsIHBhdGggbGF0ZW5jeVxuICAgKiByZWxhdGlvbnNoaXAgYmV0d2VlbiBwcm9kdWNlciBhbmQgY29uc3VtZXIgc3BhbnMuXG4gICAqL1xuICBDT05TVU1FUiA9IDQsXG59XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3BhblN0YXR1cyB7XG4gIC8qKiBUaGUgc3RhdHVzIGNvZGUgb2YgdGhpcyBtZXNzYWdlLiAqL1xuICBjb2RlOiBTcGFuU3RhdHVzQ29kZTtcbiAgLyoqIEEgZGV2ZWxvcGVyLWZhY2luZyBlcnJvciBtZXNzYWdlLiAqL1xuICBtZXNzYWdlPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIEFuIGVudW1lcmF0aW9uIG9mIHN0YXR1cyBjb2Rlcy5cbiAqL1xuZXhwb3J0IGVudW0gU3BhblN0YXR1c0NvZGUge1xuICAvKipcbiAgICogVGhlIGRlZmF1bHQgc3RhdHVzLlxuICAgKi9cbiAgVU5TRVQgPSAwLFxuICAvKipcbiAgICogVGhlIG9wZXJhdGlvbiBoYXMgYmVlbiB2YWxpZGF0ZWQgYnkgYW4gQXBwbGljYXRpb24gZGV2ZWxvcGVyIG9yXG4gICAqIE9wZXJhdG9yIHRvIGhhdmUgY29tcGxldGVkIHN1Y2Nlc3NmdWxseS5cbiAgICovXG4gIE9LID0gMSxcbiAgLyoqXG4gICAqIFRoZSBvcGVyYXRpb24gY29udGFpbnMgYW4gZXJyb3IuXG4gICAqL1xuICBFUlJPUiA9IDIsXG59XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuY29uc3QgVkFMSURfS0VZX0NIQVJfUkFOR0UgPSAnW18wLTlhLXotKi9dJztcbmNvbnN0IFZBTElEX0tFWSA9IGBbYS16XSR7VkFMSURfS0VZX0NIQVJfUkFOR0V9ezAsMjU1fWA7XG5jb25zdCBWQUxJRF9WRU5ET1JfS0VZID0gYFthLXowLTldJHtWQUxJRF9LRVlfQ0hBUl9SQU5HRX17MCwyNDB9QFthLXpdJHtWQUxJRF9LRVlfQ0hBUl9SQU5HRX17MCwxM31gO1xuY29uc3QgVkFMSURfS0VZX1JFR0VYID0gbmV3IFJlZ0V4cChgXig/OiR7VkFMSURfS0VZfXwke1ZBTElEX1ZFTkRPUl9LRVl9KSRgKTtcbmNvbnN0IFZBTElEX1ZBTFVFX0JBU0VfUkVHRVggPSAvXlsgLX5dezAsMjU1fVshLX5dJC87XG5jb25zdCBJTlZBTElEX1ZBTFVFX0NPTU1BX0VRVUFMX1JFR0VYID0gLyx8PS87XG5cbi8qKlxuICogS2V5IGlzIG9wYXF1ZSBzdHJpbmcgdXAgdG8gMjU2IGNoYXJhY3RlcnMgcHJpbnRhYmxlLiBJdCBNVVNUIGJlZ2luIHdpdGggYVxuICogbG93ZXJjYXNlIGxldHRlciwgYW5kIGNhbiBvbmx5IGNvbnRhaW4gbG93ZXJjYXNlIGxldHRlcnMgYS16LCBkaWdpdHMgMC05LFxuICogdW5kZXJzY29yZXMgXywgZGFzaGVzIC0sIGFzdGVyaXNrcyAqLCBhbmQgZm9yd2FyZCBzbGFzaGVzIC8uXG4gKiBGb3IgbXVsdGktdGVuYW50IHZlbmRvciBzY2VuYXJpb3MsIGFuIGF0IHNpZ24gKEApIGNhbiBiZSB1c2VkIHRvIHByZWZpeCB0aGVcbiAqIHZlbmRvciBuYW1lLiBWZW5kb3JzIFNIT1VMRCBzZXQgdGhlIHRlbmFudCBJRCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBrZXkuXG4gKiBzZWUgaHR0cHM6Ly93d3cudzMub3JnL1RSL3RyYWNlLWNvbnRleHQvI2tleVxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVLZXkoa2V5OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIFZBTElEX0tFWV9SRUdFWC50ZXN0KGtleSk7XG59XG5cbi8qKlxuICogVmFsdWUgaXMgb3BhcXVlIHN0cmluZyB1cCB0byAyNTYgY2hhcmFjdGVycyBwcmludGFibGUgQVNDSUkgUkZDMDAyMFxuICogY2hhcmFjdGVycyAoaS5lLiwgdGhlIHJhbmdlIDB4MjAgdG8gMHg3RSkgZXhjZXB0IGNvbW1hICwgYW5kID0uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZVZhbHVlKHZhbHVlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIChcbiAgICBWQUxJRF9WQUxVRV9CQVNFX1JFR0VYLnRlc3QodmFsdWUpICYmXG4gICAgIUlOVkFMSURfVkFMVUVfQ09NTUFfRVFVQUxfUkVHRVgudGVzdCh2YWx1ZSlcbiAgKTtcbn1cbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5pbXBvcnQgeyBUcmFjZVN0YXRlIH0gZnJvbSAnLi4vdHJhY2Vfc3RhdGUnO1xuaW1wb3J0IHsgdmFsaWRhdGVLZXksIHZhbGlkYXRlVmFsdWUgfSBmcm9tICcuL3RyYWNlc3RhdGUtdmFsaWRhdG9ycyc7XG5cbmNvbnN0IE1BWF9UUkFDRV9TVEFURV9JVEVNUyA9IDMyO1xuY29uc3QgTUFYX1RSQUNFX1NUQVRFX0xFTiA9IDUxMjtcbmNvbnN0IExJU1RfTUVNQkVSU19TRVBBUkFUT1IgPSAnLCc7XG5jb25zdCBMSVNUX01FTUJFUl9LRVlfVkFMVUVfU1BMSVRURVIgPSAnPSc7XG5cbi8qKlxuICogVHJhY2VTdGF0ZSBtdXN0IGJlIGEgY2xhc3MgYW5kIG5vdCBhIHNpbXBsZSBvYmplY3QgdHlwZSBiZWNhdXNlIG9mIHRoZSBzcGVjXG4gKiByZXF1aXJlbWVudCAoaHR0cHM6Ly93d3cudzMub3JnL1RSL3RyYWNlLWNvbnRleHQvI3RyYWNlc3RhdGUtZmllbGQpLlxuICpcbiAqIEhlcmUgaXMgdGhlIGxpc3Qgb2YgYWxsb3dlZCBtdXRhdGlvbnM6XG4gKiAtIE5ldyBrZXktdmFsdWUgcGFpciBzaG91bGQgYmUgYWRkZWQgaW50byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBsaXN0XG4gKiAtIFRoZSB2YWx1ZSBvZiBhbnkga2V5IGNhbiBiZSB1cGRhdGVkLiBNb2RpZmllZCBrZXlzIE1VU1QgYmUgbW92ZWQgdG8gdGhlXG4gKiBiZWdpbm5pbmcgb2YgdGhlIGxpc3QuXG4gKi9cbmV4cG9ydCBjbGFzcyBUcmFjZVN0YXRlSW1wbCBpbXBsZW1lbnRzIFRyYWNlU3RhdGUge1xuICBwcml2YXRlIF9pbnRlcm5hbFN0YXRlOiBNYXA8c3RyaW5nLCBzdHJpbmc+ID0gbmV3IE1hcCgpO1xuXG4gIGNvbnN0cnVjdG9yKHJhd1RyYWNlU3RhdGU/OiBzdHJpbmcpIHtcbiAgICBpZiAocmF3VHJhY2VTdGF0ZSkgdGhpcy5fcGFyc2UocmF3VHJhY2VTdGF0ZSk7XG4gIH1cblxuICBzZXQoa2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpOiBUcmFjZVN0YXRlSW1wbCB7XG4gICAgLy8gVE9ETzogQmVuY2htYXJrIHRoZSBkaWZmZXJlbnQgYXBwcm9hY2hlcyhtYXAgdnMgbGlzdCkgYW5kXG4gICAgLy8gdXNlIHRoZSBmYXN0ZXIgb25lLlxuICAgIGNvbnN0IHRyYWNlU3RhdGUgPSB0aGlzLl9jbG9uZSgpO1xuICAgIGlmICh0cmFjZVN0YXRlLl9pbnRlcm5hbFN0YXRlLmhhcyhrZXkpKSB7XG4gICAgICB0cmFjZVN0YXRlLl9pbnRlcm5hbFN0YXRlLmRlbGV0ZShrZXkpO1xuICAgIH1cbiAgICB0cmFjZVN0YXRlLl9pbnRlcm5hbFN0YXRlLnNldChrZXksIHZhbHVlKTtcbiAgICByZXR1cm4gdHJhY2VTdGF0ZTtcbiAgfVxuXG4gIHVuc2V0KGtleTogc3RyaW5nKTogVHJhY2VTdGF0ZUltcGwge1xuICAgIGNvbnN0IHRyYWNlU3RhdGUgPSB0aGlzLl9jbG9uZSgpO1xuICAgIHRyYWNlU3RhdGUuX2ludGVybmFsU3RhdGUuZGVsZXRlKGtleSk7XG4gICAgcmV0dXJuIHRyYWNlU3RhdGU7XG4gIH1cblxuICBnZXQoa2V5OiBzdHJpbmcpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLl9pbnRlcm5hbFN0YXRlLmdldChrZXkpO1xuICB9XG5cbiAgc2VyaWFsaXplKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuX2tleXMoKVxuICAgICAgLnJlZHVjZSgoYWdnOiBzdHJpbmdbXSwga2V5KSA9PiB7XG4gICAgICAgIGFnZy5wdXNoKGtleSArIExJU1RfTUVNQkVSX0tFWV9WQUxVRV9TUExJVFRFUiArIHRoaXMuZ2V0KGtleSkpO1xuICAgICAgICByZXR1cm4gYWdnO1xuICAgICAgfSwgW10pXG4gICAgICAuam9pbihMSVNUX01FTUJFUlNfU0VQQVJBVE9SKTtcbiAgfVxuXG4gIHByaXZhdGUgX3BhcnNlKHJhd1RyYWNlU3RhdGU6IHN0cmluZykge1xuICAgIGlmIChyYXdUcmFjZVN0YXRlLmxlbmd0aCA+IE1BWF9UUkFDRV9TVEFURV9MRU4pIHJldHVybjtcbiAgICB0aGlzLl9pbnRlcm5hbFN0YXRlID0gcmF3VHJhY2VTdGF0ZVxuICAgICAgLnNwbGl0KExJU1RfTUVNQkVSU19TRVBBUkFUT1IpXG4gICAgICAucmV2ZXJzZSgpIC8vIFN0b3JlIGluIHJldmVyc2Ugc28gbmV3IGtleXMgKC5zZXQoLi4uKSkgd2lsbCBiZSBwbGFjZWQgYXQgdGhlIGJlZ2lubmluZ1xuICAgICAgLnJlZHVjZSgoYWdnOiBNYXA8c3RyaW5nLCBzdHJpbmc+LCBwYXJ0OiBzdHJpbmcpID0+IHtcbiAgICAgICAgY29uc3QgbGlzdE1lbWJlciA9IHBhcnQudHJpbSgpOyAvLyBPcHRpb25hbCBXaGl0ZXNwYWNlIChPV1MpIGhhbmRsaW5nXG4gICAgICAgIGNvbnN0IGkgPSBsaXN0TWVtYmVyLmluZGV4T2YoTElTVF9NRU1CRVJfS0VZX1ZBTFVFX1NQTElUVEVSKTtcbiAgICAgICAgaWYgKGkgIT09IC0xKSB7XG4gICAgICAgICAgY29uc3Qga2V5ID0gbGlzdE1lbWJlci5zbGljZSgwLCBpKTtcbiAgICAgICAgICBjb25zdCB2YWx1ZSA9IGxpc3RNZW1iZXIuc2xpY2UoaSArIDEsIHBhcnQubGVuZ3RoKTtcbiAgICAgICAgICBpZiAodmFsaWRhdGVLZXkoa2V5KSAmJiB2YWxpZGF0ZVZhbHVlKHZhbHVlKSkge1xuICAgICAgICAgICAgYWdnLnNldChrZXksIHZhbHVlKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gVE9ETzogQ29uc2lkZXIgdG8gYWRkIHdhcm5pbmcgbG9nXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhZ2c7XG4gICAgICB9LCBuZXcgTWFwKCkpO1xuXG4gICAgLy8gQmVjYXVzZSBvZiB0aGUgcmV2ZXJzZSgpIHJlcXVpcmVtZW50LCB0cnVuYyBtdXN0IGJlIGRvbmUgYWZ0ZXIgbWFwIGlzIGNyZWF0ZWRcbiAgICBpZiAodGhpcy5faW50ZXJuYWxTdGF0ZS5zaXplID4gTUFYX1RSQUNFX1NUQVRFX0lURU1TKSB7XG4gICAgICB0aGlzLl9pbnRlcm5hbFN0YXRlID0gbmV3IE1hcChcbiAgICAgICAgQXJyYXkuZnJvbSh0aGlzLl9pbnRlcm5hbFN0YXRlLmVudHJpZXMoKSlcbiAgICAgICAgICAucmV2ZXJzZSgpIC8vIFVzZSByZXZlcnNlIHNhbWUgYXMgb3JpZ2luYWwgdHJhY2VzdGF0ZSBwYXJzZSBjaGFpblxuICAgICAgICAgIC5zbGljZSgwLCBNQVhfVFJBQ0VfU1RBVEVfSVRFTVMpXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2tleXMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMuX2ludGVybmFsU3RhdGUua2V5cygpKS5yZXZlcnNlKCk7XG4gIH1cblxuICBwcml2YXRlIF9jbG9uZSgpOiBUcmFjZVN0YXRlSW1wbCB7XG4gICAgY29uc3QgdHJhY2VTdGF0ZSA9IG5ldyBUcmFjZVN0YXRlSW1wbCgpO1xuICAgIHRyYWNlU3RhdGUuX2ludGVybmFsU3RhdGUgPSBuZXcgTWFwKHRoaXMuX2ludGVybmFsU3RhdGUpO1xuICAgIHJldHVybiB0cmFjZVN0YXRlO1xuICB9XG59XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuaW1wb3J0IHsgVHJhY2VTdGF0ZSB9IGZyb20gJy4uL3RyYWNlX3N0YXRlJztcbmltcG9ydCB7IFRyYWNlU3RhdGVJbXBsIH0gZnJvbSAnLi90cmFjZXN0YXRlLWltcGwnO1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlVHJhY2VTdGF0ZShyYXdUcmFjZVN0YXRlPzogc3RyaW5nKTogVHJhY2VTdGF0ZSB7XG4gIHJldHVybiBuZXcgVHJhY2VTdGF0ZUltcGwocmF3VHJhY2VTdGF0ZSk7XG59XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuLy8gU3BsaXQgbW9kdWxlLWxldmVsIHZhcmlhYmxlIGRlZmluaXRpb24gaW50byBzZXBhcmF0ZSBmaWxlcyB0byBhbGxvd1xuLy8gdHJlZS1zaGFraW5nIG9uIGVhY2ggYXBpIGluc3RhbmNlLlxuaW1wb3J0IHsgQ29udGV4dEFQSSB9IGZyb20gJy4vYXBpL2NvbnRleHQnO1xuLyoqIEVudHJ5cG9pbnQgZm9yIGNvbnRleHQgQVBJICovXG5leHBvcnQgY29uc3QgY29udGV4dCA9IENvbnRleHRBUEkuZ2V0SW5zdGFuY2UoKTtcbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG4vLyBTcGxpdCBtb2R1bGUtbGV2ZWwgdmFyaWFibGUgZGVmaW5pdGlvbiBpbnRvIHNlcGFyYXRlIGZpbGVzIHRvIGFsbG93XG4vLyB0cmVlLXNoYWtpbmcgb24gZWFjaCBhcGkgaW5zdGFuY2UuXG5pbXBvcnQgeyBEaWFnQVBJIH0gZnJvbSAnLi9hcGkvZGlhZyc7XG4vKipcbiAqIEVudHJ5cG9pbnQgZm9yIERpYWcgQVBJLlxuICogRGVmaW5lcyBEaWFnbm9zdGljIGhhbmRsZXIgdXNlZCBmb3IgaW50ZXJuYWwgZGlhZ25vc3RpYyBsb2dnaW5nIG9wZXJhdGlvbnMuXG4gKiBUaGUgZGVmYXVsdCBwcm92aWRlcyBhIE5vb3AgRGlhZ0xvZ2dlciBpbXBsZW1lbnRhdGlvbiB3aGljaCBtYXkgYmUgY2hhbmdlZCB2aWEgdGhlXG4gKiBkaWFnLnNldExvZ2dlcihsb2dnZXI6IERpYWdMb2dnZXIpIGZ1bmN0aW9uLlxuICovXG5leHBvcnQgY29uc3QgZGlhZyA9IERpYWdBUEkuaW5zdGFuY2UoKTtcbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5pbXBvcnQgeyBNZXRlciwgTWV0ZXJPcHRpb25zIH0gZnJvbSAnLi9NZXRlcic7XG5pbXBvcnQgeyBNZXRlclByb3ZpZGVyIH0gZnJvbSAnLi9NZXRlclByb3ZpZGVyJztcbmltcG9ydCB7IE5PT1BfTUVURVIgfSBmcm9tICcuL05vb3BNZXRlcic7XG5cbi8qKlxuICogQW4gaW1wbGVtZW50YXRpb24gb2YgdGhlIHtAbGluayBNZXRlclByb3ZpZGVyfSB3aGljaCByZXR1cm5zIGFuIGltcG90ZW50IE1ldGVyXG4gKiBmb3IgYWxsIGNhbGxzIHRvIGBnZXRNZXRlcmBcbiAqL1xuZXhwb3J0IGNsYXNzIE5vb3BNZXRlclByb3ZpZGVyIGltcGxlbWVudHMgTWV0ZXJQcm92aWRlciB7XG4gIGdldE1ldGVyKF9uYW1lOiBzdHJpbmcsIF92ZXJzaW9uPzogc3RyaW5nLCBfb3B0aW9ucz86IE1ldGVyT3B0aW9ucyk6IE1ldGVyIHtcbiAgICByZXR1cm4gTk9PUF9NRVRFUjtcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgTk9PUF9NRVRFUl9QUk9WSURFUiA9IG5ldyBOb29wTWV0ZXJQcm92aWRlcigpO1xuIiwgIi8qXG4gKiBDb3B5cmlnaHQgVGhlIE9wZW5UZWxlbWV0cnkgQXV0aG9yc1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgIGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IE1ldGVyLCBNZXRlck9wdGlvbnMgfSBmcm9tICcuLi9tZXRyaWNzL01ldGVyJztcbmltcG9ydCB7IE1ldGVyUHJvdmlkZXIgfSBmcm9tICcuLi9tZXRyaWNzL01ldGVyUHJvdmlkZXInO1xuaW1wb3J0IHsgTk9PUF9NRVRFUl9QUk9WSURFUiB9IGZyb20gJy4uL21ldHJpY3MvTm9vcE1ldGVyUHJvdmlkZXInO1xuaW1wb3J0IHtcbiAgZ2V0R2xvYmFsLFxuICByZWdpc3Rlckdsb2JhbCxcbiAgdW5yZWdpc3Rlckdsb2JhbCxcbn0gZnJvbSAnLi4vaW50ZXJuYWwvZ2xvYmFsLXV0aWxzJztcbmltcG9ydCB7IERpYWdBUEkgfSBmcm9tICcuL2RpYWcnO1xuXG5jb25zdCBBUElfTkFNRSA9ICdtZXRyaWNzJztcblxuLyoqXG4gKiBTaW5nbGV0b24gb2JqZWN0IHdoaWNoIHJlcHJlc2VudHMgdGhlIGVudHJ5IHBvaW50IHRvIHRoZSBPcGVuVGVsZW1ldHJ5IE1ldHJpY3MgQVBJXG4gKi9cbmV4cG9ydCBjbGFzcyBNZXRyaWNzQVBJIHtcbiAgcHJpdmF0ZSBzdGF0aWMgX2luc3RhbmNlPzogTWV0cmljc0FQSTtcblxuICAvKiogRW1wdHkgcHJpdmF0ZSBjb25zdHJ1Y3RvciBwcmV2ZW50cyBlbmQgdXNlcnMgZnJvbSBjb25zdHJ1Y3RpbmcgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIEFQSSAqL1xuICBwcml2YXRlIGNvbnN0cnVjdG9yKCkge31cblxuICAvKiogR2V0IHRoZSBzaW5nbGV0b24gaW5zdGFuY2Ugb2YgdGhlIE1ldHJpY3MgQVBJICovXG4gIHB1YmxpYyBzdGF0aWMgZ2V0SW5zdGFuY2UoKTogTWV0cmljc0FQSSB7XG4gICAgaWYgKCF0aGlzLl9pbnN0YW5jZSkge1xuICAgICAgdGhpcy5faW5zdGFuY2UgPSBuZXcgTWV0cmljc0FQSSgpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9pbnN0YW5jZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgdGhlIGN1cnJlbnQgZ2xvYmFsIG1ldGVyIHByb3ZpZGVyLlxuICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIG1ldGVyIHByb3ZpZGVyIHdhcyBzdWNjZXNzZnVsbHkgcmVnaXN0ZXJlZCwgZWxzZSBmYWxzZS5cbiAgICovXG4gIHB1YmxpYyBzZXRHbG9iYWxNZXRlclByb3ZpZGVyKHByb3ZpZGVyOiBNZXRlclByb3ZpZGVyKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHJlZ2lzdGVyR2xvYmFsKEFQSV9OQU1FLCBwcm92aWRlciwgRGlhZ0FQSS5pbnN0YW5jZSgpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBnbG9iYWwgbWV0ZXIgcHJvdmlkZXIuXG4gICAqL1xuICBwdWJsaWMgZ2V0TWV0ZXJQcm92aWRlcigpOiBNZXRlclByb3ZpZGVyIHtcbiAgICByZXR1cm4gZ2V0R2xvYmFsKEFQSV9OQU1FKSB8fCBOT09QX01FVEVSX1BST1ZJREVSO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBtZXRlciBmcm9tIHRoZSBnbG9iYWwgbWV0ZXIgcHJvdmlkZXIuXG4gICAqL1xuICBwdWJsaWMgZ2V0TWV0ZXIoXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIHZlcnNpb24/OiBzdHJpbmcsXG4gICAgb3B0aW9ucz86IE1ldGVyT3B0aW9uc1xuICApOiBNZXRlciB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0TWV0ZXJQcm92aWRlcigpLmdldE1ldGVyKG5hbWUsIHZlcnNpb24sIG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqIFJlbW92ZSB0aGUgZ2xvYmFsIG1ldGVyIHByb3ZpZGVyICovXG4gIHB1YmxpYyBkaXNhYmxlKCk6IHZvaWQge1xuICAgIHVucmVnaXN0ZXJHbG9iYWwoQVBJX05BTUUsIERpYWdBUEkuaW5zdGFuY2UoKSk7XG4gIH1cbn1cbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG4vLyBTcGxpdCBtb2R1bGUtbGV2ZWwgdmFyaWFibGUgZGVmaW5pdGlvbiBpbnRvIHNlcGFyYXRlIGZpbGVzIHRvIGFsbG93XG4vLyB0cmVlLXNoYWtpbmcgb24gZWFjaCBhcGkgaW5zdGFuY2UuXG5pbXBvcnQgeyBNZXRyaWNzQVBJIH0gZnJvbSAnLi9hcGkvbWV0cmljcyc7XG4vKiogRW50cnlwb2ludCBmb3IgbWV0cmljcyBBUEkgKi9cbmV4cG9ydCBjb25zdCBtZXRyaWNzID0gTWV0cmljc0FQSS5nZXRJbnN0YW5jZSgpO1xuIiwgIi8qXG4gKiBDb3B5cmlnaHQgVGhlIE9wZW5UZWxlbWV0cnkgQXV0aG9yc1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgIGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IENvbnRleHQgfSBmcm9tICcuLi9jb250ZXh0L3R5cGVzJztcbmltcG9ydCB7IFRleHRNYXBQcm9wYWdhdG9yIH0gZnJvbSAnLi9UZXh0TWFwUHJvcGFnYXRvcic7XG5cbi8qKlxuICogTm8tb3AgaW1wbGVtZW50YXRpb25zIG9mIHtAbGluayBUZXh0TWFwUHJvcGFnYXRvcn0uXG4gKi9cbmV4cG9ydCBjbGFzcyBOb29wVGV4dE1hcFByb3BhZ2F0b3IgaW1wbGVtZW50cyBUZXh0TWFwUHJvcGFnYXRvciB7XG4gIC8qKiBOb29wIGluamVjdCBmdW5jdGlvbiBkb2VzIG5vdGhpbmcgKi9cbiAgaW5qZWN0KF9jb250ZXh0OiBDb250ZXh0LCBfY2FycmllcjogdW5rbm93bik6IHZvaWQge31cbiAgLyoqIE5vb3AgZXh0cmFjdCBmdW5jdGlvbiBkb2VzIG5vdGhpbmcgYW5kIHJldHVybnMgdGhlIGlucHV0IGNvbnRleHQgKi9cbiAgZXh0cmFjdChjb250ZXh0OiBDb250ZXh0LCBfY2FycmllcjogdW5rbm93bik6IENvbnRleHQge1xuICAgIHJldHVybiBjb250ZXh0O1xuICB9XG4gIGZpZWxkcygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG59XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuaW1wb3J0IHsgQ29udGV4dEFQSSB9IGZyb20gJy4uL2FwaS9jb250ZXh0JztcbmltcG9ydCB7IGNyZWF0ZUNvbnRleHRLZXkgfSBmcm9tICcuLi9jb250ZXh0L2NvbnRleHQnO1xuaW1wb3J0IHsgQ29udGV4dCB9IGZyb20gJy4uL2NvbnRleHQvdHlwZXMnO1xuaW1wb3J0IHsgQmFnZ2FnZSB9IGZyb20gJy4vdHlwZXMnO1xuXG4vKipcbiAqIEJhZ2dhZ2Uga2V5XG4gKi9cbmNvbnN0IEJBR0dBR0VfS0VZID0gY3JlYXRlQ29udGV4dEtleSgnT3BlblRlbGVtZXRyeSBCYWdnYWdlIEtleScpO1xuXG4vKipcbiAqIFJldHJpZXZlIHRoZSBjdXJyZW50IGJhZ2dhZ2UgZnJvbSB0aGUgZ2l2ZW4gY29udGV4dFxuICpcbiAqIEBwYXJhbSB7Q29udGV4dH0gQ29udGV4dCB0aGF0IG1hbmFnZSBhbGwgY29udGV4dCB2YWx1ZXNcbiAqIEByZXR1cm5zIHtCYWdnYWdlfSBFeHRyYWN0ZWQgYmFnZ2FnZSBmcm9tIHRoZSBjb250ZXh0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRCYWdnYWdlKGNvbnRleHQ6IENvbnRleHQpOiBCYWdnYWdlIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIChjb250ZXh0LmdldFZhbHVlKEJBR0dBR0VfS0VZKSBhcyBCYWdnYWdlKSB8fCB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogUmV0cmlldmUgdGhlIGN1cnJlbnQgYmFnZ2FnZSBmcm9tIHRoZSBhY3RpdmUvY3VycmVudCBjb250ZXh0XG4gKlxuICogQHJldHVybnMge0JhZ2dhZ2V9IEV4dHJhY3RlZCBiYWdnYWdlIGZyb20gdGhlIGNvbnRleHRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEFjdGl2ZUJhZ2dhZ2UoKTogQmFnZ2FnZSB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiBnZXRCYWdnYWdlKENvbnRleHRBUEkuZ2V0SW5zdGFuY2UoKS5hY3RpdmUoKSk7XG59XG5cbi8qKlxuICogU3RvcmUgYSBiYWdnYWdlIGluIHRoZSBnaXZlbiBjb250ZXh0XG4gKlxuICogQHBhcmFtIHtDb250ZXh0fSBDb250ZXh0IHRoYXQgbWFuYWdlIGFsbCBjb250ZXh0IHZhbHVlc1xuICogQHBhcmFtIHtCYWdnYWdlfSBiYWdnYWdlIHRoYXQgd2lsbCBiZSBzZXQgaW4gdGhlIGFjdHVhbCBjb250ZXh0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRCYWdnYWdlKGNvbnRleHQ6IENvbnRleHQsIGJhZ2dhZ2U6IEJhZ2dhZ2UpOiBDb250ZXh0IHtcbiAgcmV0dXJuIGNvbnRleHQuc2V0VmFsdWUoQkFHR0FHRV9LRVksIGJhZ2dhZ2UpO1xufVxuXG4vKipcbiAqIERlbGV0ZSB0aGUgYmFnZ2FnZSBzdG9yZWQgaW4gdGhlIGdpdmVuIGNvbnRleHRcbiAqXG4gKiBAcGFyYW0ge0NvbnRleHR9IENvbnRleHQgdGhhdCBtYW5hZ2UgYWxsIGNvbnRleHQgdmFsdWVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWxldGVCYWdnYWdlKGNvbnRleHQ6IENvbnRleHQpOiBDb250ZXh0IHtcbiAgcmV0dXJuIGNvbnRleHQuZGVsZXRlVmFsdWUoQkFHR0FHRV9LRVkpO1xufVxuIiwgIi8qXG4gKiBDb3B5cmlnaHQgVGhlIE9wZW5UZWxlbWV0cnkgQXV0aG9yc1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgIGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IENvbnRleHQgfSBmcm9tICcuLi9jb250ZXh0L3R5cGVzJztcbmltcG9ydCB7XG4gIGdldEdsb2JhbCxcbiAgcmVnaXN0ZXJHbG9iYWwsXG4gIHVucmVnaXN0ZXJHbG9iYWwsXG59IGZyb20gJy4uL2ludGVybmFsL2dsb2JhbC11dGlscyc7XG5pbXBvcnQgeyBOb29wVGV4dE1hcFByb3BhZ2F0b3IgfSBmcm9tICcuLi9wcm9wYWdhdGlvbi9Ob29wVGV4dE1hcFByb3BhZ2F0b3InO1xuaW1wb3J0IHtcbiAgZGVmYXVsdFRleHRNYXBHZXR0ZXIsXG4gIGRlZmF1bHRUZXh0TWFwU2V0dGVyLFxuICBUZXh0TWFwR2V0dGVyLFxuICBUZXh0TWFwUHJvcGFnYXRvcixcbiAgVGV4dE1hcFNldHRlcixcbn0gZnJvbSAnLi4vcHJvcGFnYXRpb24vVGV4dE1hcFByb3BhZ2F0b3InO1xuaW1wb3J0IHtcbiAgZ2V0QmFnZ2FnZSxcbiAgZ2V0QWN0aXZlQmFnZ2FnZSxcbiAgc2V0QmFnZ2FnZSxcbiAgZGVsZXRlQmFnZ2FnZSxcbn0gZnJvbSAnLi4vYmFnZ2FnZS9jb250ZXh0LWhlbHBlcnMnO1xuaW1wb3J0IHsgY3JlYXRlQmFnZ2FnZSB9IGZyb20gJy4uL2JhZ2dhZ2UvdXRpbHMnO1xuaW1wb3J0IHsgRGlhZ0FQSSB9IGZyb20gJy4vZGlhZyc7XG5cbmNvbnN0IEFQSV9OQU1FID0gJ3Byb3BhZ2F0aW9uJztcbmNvbnN0IE5PT1BfVEVYVF9NQVBfUFJPUEFHQVRPUiA9IG5ldyBOb29wVGV4dE1hcFByb3BhZ2F0b3IoKTtcblxuLyoqXG4gKiBTaW5nbGV0b24gb2JqZWN0IHdoaWNoIHJlcHJlc2VudHMgdGhlIGVudHJ5IHBvaW50IHRvIHRoZSBPcGVuVGVsZW1ldHJ5IFByb3BhZ2F0aW9uIEFQSVxuICovXG5leHBvcnQgY2xhc3MgUHJvcGFnYXRpb25BUEkge1xuICBwcml2YXRlIHN0YXRpYyBfaW5zdGFuY2U/OiBQcm9wYWdhdGlvbkFQSTtcblxuICAvKiogRW1wdHkgcHJpdmF0ZSBjb25zdHJ1Y3RvciBwcmV2ZW50cyBlbmQgdXNlcnMgZnJvbSBjb25zdHJ1Y3RpbmcgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIEFQSSAqL1xuICBwcml2YXRlIGNvbnN0cnVjdG9yKCkge31cblxuICAvKiogR2V0IHRoZSBzaW5nbGV0b24gaW5zdGFuY2Ugb2YgdGhlIFByb3BhZ2F0b3IgQVBJICovXG4gIHB1YmxpYyBzdGF0aWMgZ2V0SW5zdGFuY2UoKTogUHJvcGFnYXRpb25BUEkge1xuICAgIGlmICghdGhpcy5faW5zdGFuY2UpIHtcbiAgICAgIHRoaXMuX2luc3RhbmNlID0gbmV3IFByb3BhZ2F0aW9uQVBJKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX2luc3RhbmNlO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldCB0aGUgY3VycmVudCBwcm9wYWdhdG9yLlxuICAgKlxuICAgKiBAcmV0dXJucyB0cnVlIGlmIHRoZSBwcm9wYWdhdG9yIHdhcyBzdWNjZXNzZnVsbHkgcmVnaXN0ZXJlZCwgZWxzZSBmYWxzZVxuICAgKi9cbiAgcHVibGljIHNldEdsb2JhbFByb3BhZ2F0b3IocHJvcGFnYXRvcjogVGV4dE1hcFByb3BhZ2F0b3IpOiBib29sZWFuIHtcbiAgICByZXR1cm4gcmVnaXN0ZXJHbG9iYWwoQVBJX05BTUUsIHByb3BhZ2F0b3IsIERpYWdBUEkuaW5zdGFuY2UoKSk7XG4gIH1cblxuICAvKipcbiAgICogSW5qZWN0IGNvbnRleHQgaW50byBhIGNhcnJpZXIgdG8gYmUgcHJvcGFnYXRlZCBpbnRlci1wcm9jZXNzXG4gICAqXG4gICAqIEBwYXJhbSBjb250ZXh0IENvbnRleHQgY2FycnlpbmcgdHJhY2luZyBkYXRhIHRvIGluamVjdFxuICAgKiBAcGFyYW0gY2FycmllciBjYXJyaWVyIHRvIGluamVjdCBjb250ZXh0IGludG9cbiAgICogQHBhcmFtIHNldHRlciBGdW5jdGlvbiB1c2VkIHRvIHNldCB2YWx1ZXMgb24gdGhlIGNhcnJpZXJcbiAgICovXG4gIHB1YmxpYyBpbmplY3Q8Q2Fycmllcj4oXG4gICAgY29udGV4dDogQ29udGV4dCxcbiAgICBjYXJyaWVyOiBDYXJyaWVyLFxuICAgIHNldHRlcjogVGV4dE1hcFNldHRlcjxDYXJyaWVyPiA9IGRlZmF1bHRUZXh0TWFwU2V0dGVyXG4gICk6IHZvaWQge1xuICAgIHJldHVybiB0aGlzLl9nZXRHbG9iYWxQcm9wYWdhdG9yKCkuaW5qZWN0KGNvbnRleHQsIGNhcnJpZXIsIHNldHRlcik7XG4gIH1cblxuICAvKipcbiAgICogRXh0cmFjdCBjb250ZXh0IGZyb20gYSBjYXJyaWVyXG4gICAqXG4gICAqIEBwYXJhbSBjb250ZXh0IENvbnRleHQgd2hpY2ggdGhlIG5ld2x5IGNyZWF0ZWQgY29udGV4dCB3aWxsIGluaGVyaXQgZnJvbVxuICAgKiBAcGFyYW0gY2FycmllciBDYXJyaWVyIHRvIGV4dHJhY3QgY29udGV4dCBmcm9tXG4gICAqIEBwYXJhbSBnZXR0ZXIgRnVuY3Rpb24gdXNlZCB0byBleHRyYWN0IGtleXMgZnJvbSBhIGNhcnJpZXJcbiAgICovXG4gIHB1YmxpYyBleHRyYWN0PENhcnJpZXI+KFxuICAgIGNvbnRleHQ6IENvbnRleHQsXG4gICAgY2FycmllcjogQ2FycmllcixcbiAgICBnZXR0ZXI6IFRleHRNYXBHZXR0ZXI8Q2Fycmllcj4gPSBkZWZhdWx0VGV4dE1hcEdldHRlclxuICApOiBDb250ZXh0IHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0R2xvYmFsUHJvcGFnYXRvcigpLmV4dHJhY3QoY29udGV4dCwgY2FycmllciwgZ2V0dGVyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYSBsaXN0IG9mIGFsbCBmaWVsZHMgd2hpY2ggbWF5IGJlIHVzZWQgYnkgdGhlIHByb3BhZ2F0b3IuXG4gICAqL1xuICBwdWJsaWMgZmllbGRzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0R2xvYmFsUHJvcGFnYXRvcigpLmZpZWxkcygpO1xuICB9XG5cbiAgLyoqIFJlbW92ZSB0aGUgZ2xvYmFsIHByb3BhZ2F0b3IgKi9cbiAgcHVibGljIGRpc2FibGUoKSB7XG4gICAgdW5yZWdpc3Rlckdsb2JhbChBUElfTkFNRSwgRGlhZ0FQSS5pbnN0YW5jZSgpKTtcbiAgfVxuXG4gIHB1YmxpYyBjcmVhdGVCYWdnYWdlID0gY3JlYXRlQmFnZ2FnZTtcblxuICBwdWJsaWMgZ2V0QmFnZ2FnZSA9IGdldEJhZ2dhZ2U7XG5cbiAgcHVibGljIGdldEFjdGl2ZUJhZ2dhZ2UgPSBnZXRBY3RpdmVCYWdnYWdlO1xuXG4gIHB1YmxpYyBzZXRCYWdnYWdlID0gc2V0QmFnZ2FnZTtcblxuICBwdWJsaWMgZGVsZXRlQmFnZ2FnZSA9IGRlbGV0ZUJhZ2dhZ2U7XG5cbiAgcHJpdmF0ZSBfZ2V0R2xvYmFsUHJvcGFnYXRvcigpOiBUZXh0TWFwUHJvcGFnYXRvciB7XG4gICAgcmV0dXJuIGdldEdsb2JhbChBUElfTkFNRSkgfHwgTk9PUF9URVhUX01BUF9QUk9QQUdBVE9SO1xuICB9XG59XG4iLCAiLypcbiAqIENvcHlyaWdodCBUaGUgT3BlblRlbGVtZXRyeSBBdXRob3JzXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cHM6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuLy8gU3BsaXQgbW9kdWxlLWxldmVsIHZhcmlhYmxlIGRlZmluaXRpb24gaW50byBzZXBhcmF0ZSBmaWxlcyB0byBhbGxvd1xuLy8gdHJlZS1zaGFraW5nIG9uIGVhY2ggYXBpIGluc3RhbmNlLlxuaW1wb3J0IHsgUHJvcGFnYXRpb25BUEkgfSBmcm9tICcuL2FwaS9wcm9wYWdhdGlvbic7XG4vKiogRW50cnlwb2ludCBmb3IgcHJvcGFnYXRpb24gQVBJICovXG5leHBvcnQgY29uc3QgcHJvcGFnYXRpb24gPSBQcm9wYWdhdGlvbkFQSS5nZXRJbnN0YW5jZSgpO1xuIiwgIi8qXG4gKiBDb3B5cmlnaHQgVGhlIE9wZW5UZWxlbWV0cnkgQXV0aG9yc1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgIGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7XG4gIGdldEdsb2JhbCxcbiAgcmVnaXN0ZXJHbG9iYWwsXG4gIHVucmVnaXN0ZXJHbG9iYWwsXG59IGZyb20gJy4uL2ludGVybmFsL2dsb2JhbC11dGlscyc7XG5pbXBvcnQgeyBQcm94eVRyYWNlclByb3ZpZGVyIH0gZnJvbSAnLi4vdHJhY2UvUHJveHlUcmFjZXJQcm92aWRlcic7XG5pbXBvcnQge1xuICBpc1NwYW5Db250ZXh0VmFsaWQsXG4gIHdyYXBTcGFuQ29udGV4dCxcbn0gZnJvbSAnLi4vdHJhY2Uvc3BhbmNvbnRleHQtdXRpbHMnO1xuaW1wb3J0IHsgVHJhY2VyIH0gZnJvbSAnLi4vdHJhY2UvdHJhY2VyJztcbmltcG9ydCB7IFRyYWNlclByb3ZpZGVyIH0gZnJvbSAnLi4vdHJhY2UvdHJhY2VyX3Byb3ZpZGVyJztcbmltcG9ydCB7XG4gIGRlbGV0ZVNwYW4sXG4gIGdldEFjdGl2ZVNwYW4sXG4gIGdldFNwYW4sXG4gIGdldFNwYW5Db250ZXh0LFxuICBzZXRTcGFuLFxuICBzZXRTcGFuQ29udGV4dCxcbn0gZnJvbSAnLi4vdHJhY2UvY29udGV4dC11dGlscyc7XG5pbXBvcnQgeyBEaWFnQVBJIH0gZnJvbSAnLi9kaWFnJztcblxuY29uc3QgQVBJX05BTUUgPSAndHJhY2UnO1xuXG4vKipcbiAqIFNpbmdsZXRvbiBvYmplY3Qgd2hpY2ggcmVwcmVzZW50cyB0aGUgZW50cnkgcG9pbnQgdG8gdGhlIE9wZW5UZWxlbWV0cnkgVHJhY2luZyBBUElcbiAqL1xuZXhwb3J0IGNsYXNzIFRyYWNlQVBJIHtcbiAgcHJpdmF0ZSBzdGF0aWMgX2luc3RhbmNlPzogVHJhY2VBUEk7XG5cbiAgcHJpdmF0ZSBfcHJveHlUcmFjZXJQcm92aWRlciA9IG5ldyBQcm94eVRyYWNlclByb3ZpZGVyKCk7XG5cbiAgLyoqIEVtcHR5IHByaXZhdGUgY29uc3RydWN0b3IgcHJldmVudHMgZW5kIHVzZXJzIGZyb20gY29uc3RydWN0aW5nIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBBUEkgKi9cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgLyoqIEdldCB0aGUgc2luZ2xldG9uIGluc3RhbmNlIG9mIHRoZSBUcmFjZSBBUEkgKi9cbiAgcHVibGljIHN0YXRpYyBnZXRJbnN0YW5jZSgpOiBUcmFjZUFQSSB7XG4gICAgaWYgKCF0aGlzLl9pbnN0YW5jZSkge1xuICAgICAgdGhpcy5faW5zdGFuY2UgPSBuZXcgVHJhY2VBUEkoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5faW5zdGFuY2U7XG4gIH1cblxuICAvKipcbiAgICogU2V0IHRoZSBjdXJyZW50IGdsb2JhbCB0cmFjZXIuXG4gICAqXG4gICAqIEByZXR1cm5zIHRydWUgaWYgdGhlIHRyYWNlciBwcm92aWRlciB3YXMgc3VjY2Vzc2Z1bGx5IHJlZ2lzdGVyZWQsIGVsc2UgZmFsc2VcbiAgICovXG4gIHB1YmxpYyBzZXRHbG9iYWxUcmFjZXJQcm92aWRlcihwcm92aWRlcjogVHJhY2VyUHJvdmlkZXIpOiBib29sZWFuIHtcbiAgICBjb25zdCBzdWNjZXNzID0gcmVnaXN0ZXJHbG9iYWwoXG4gICAgICBBUElfTkFNRSxcbiAgICAgIHRoaXMuX3Byb3h5VHJhY2VyUHJvdmlkZXIsXG4gICAgICBEaWFnQVBJLmluc3RhbmNlKClcbiAgICApO1xuICAgIGlmIChzdWNjZXNzKSB7XG4gICAgICB0aGlzLl9wcm94eVRyYWNlclByb3ZpZGVyLnNldERlbGVnYXRlKHByb3ZpZGVyKTtcbiAgICB9XG4gICAgcmV0dXJuIHN1Y2Nlc3M7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgZ2xvYmFsIHRyYWNlciBwcm92aWRlci5cbiAgICovXG4gIHB1YmxpYyBnZXRUcmFjZXJQcm92aWRlcigpOiBUcmFjZXJQcm92aWRlciB7XG4gICAgcmV0dXJuIGdldEdsb2JhbChBUElfTkFNRSkgfHwgdGhpcy5fcHJveHlUcmFjZXJQcm92aWRlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgdHJhY2VyIGZyb20gdGhlIGdsb2JhbCB0cmFjZXIgcHJvdmlkZXIuXG4gICAqL1xuICBwdWJsaWMgZ2V0VHJhY2VyKG5hbWU6IHN0cmluZywgdmVyc2lvbj86IHN0cmluZyk6IFRyYWNlciB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0VHJhY2VyUHJvdmlkZXIoKS5nZXRUcmFjZXIobmFtZSwgdmVyc2lvbik7XG4gIH1cblxuICAvKiogUmVtb3ZlIHRoZSBnbG9iYWwgdHJhY2VyIHByb3ZpZGVyICovXG4gIHB1YmxpYyBkaXNhYmxlKCkge1xuICAgIHVucmVnaXN0ZXJHbG9iYWwoQVBJX05BTUUsIERpYWdBUEkuaW5zdGFuY2UoKSk7XG4gICAgdGhpcy5fcHJveHlUcmFjZXJQcm92aWRlciA9IG5ldyBQcm94eVRyYWNlclByb3ZpZGVyKCk7XG4gIH1cblxuICBwdWJsaWMgd3JhcFNwYW5Db250ZXh0ID0gd3JhcFNwYW5Db250ZXh0O1xuXG4gIHB1YmxpYyBpc1NwYW5Db250ZXh0VmFsaWQgPSBpc1NwYW5Db250ZXh0VmFsaWQ7XG5cbiAgcHVibGljIGRlbGV0ZVNwYW4gPSBkZWxldGVTcGFuO1xuXG4gIHB1YmxpYyBnZXRTcGFuID0gZ2V0U3BhbjtcblxuICBwdWJsaWMgZ2V0QWN0aXZlU3BhbiA9IGdldEFjdGl2ZVNwYW47XG5cbiAgcHVibGljIGdldFNwYW5Db250ZXh0ID0gZ2V0U3BhbkNvbnRleHQ7XG5cbiAgcHVibGljIHNldFNwYW4gPSBzZXRTcGFuO1xuXG4gIHB1YmxpYyBzZXRTcGFuQ29udGV4dCA9IHNldFNwYW5Db250ZXh0O1xufVxuIiwgIi8qXG4gKiBDb3B5cmlnaHQgVGhlIE9wZW5UZWxlbWV0cnkgQXV0aG9yc1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgIGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbi8vIFNwbGl0IG1vZHVsZS1sZXZlbCB2YXJpYWJsZSBkZWZpbml0aW9uIGludG8gc2VwYXJhdGUgZmlsZXMgdG8gYWxsb3dcbi8vIHRyZWUtc2hha2luZyBvbiBlYWNoIGFwaSBpbnN0YW5jZS5cbmltcG9ydCB7IFRyYWNlQVBJIH0gZnJvbSAnLi9hcGkvdHJhY2UnO1xuLyoqIEVudHJ5cG9pbnQgZm9yIHRyYWNlIEFQSSAqL1xuZXhwb3J0IGNvbnN0IHRyYWNlID0gVHJhY2VBUEkuZ2V0SW5zdGFuY2UoKTtcbiIsICIvKlxuICogQ29weXJpZ2h0IFRoZSBPcGVuVGVsZW1ldHJ5IEF1dGhvcnNcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwczovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5leHBvcnQgeyBCYWdnYWdlRW50cnksIEJhZ2dhZ2VFbnRyeU1ldGFkYXRhLCBCYWdnYWdlIH0gZnJvbSAnLi9iYWdnYWdlL3R5cGVzJztcbmV4cG9ydCB7IGJhZ2dhZ2VFbnRyeU1ldGFkYXRhRnJvbVN0cmluZyB9IGZyb20gJy4vYmFnZ2FnZS91dGlscyc7XG5leHBvcnQgeyBFeGNlcHRpb24gfSBmcm9tICcuL2NvbW1vbi9FeGNlcHRpb24nO1xuZXhwb3J0IHsgSHJUaW1lLCBUaW1lSW5wdXQgfSBmcm9tICcuL2NvbW1vbi9UaW1lJztcbmV4cG9ydCB7IEF0dHJpYnV0ZXMsIEF0dHJpYnV0ZVZhbHVlIH0gZnJvbSAnLi9jb21tb24vQXR0cmlidXRlcyc7XG5cbi8vIENvbnRleHQgQVBJc1xuZXhwb3J0IHsgY3JlYXRlQ29udGV4dEtleSwgUk9PVF9DT05URVhUIH0gZnJvbSAnLi9jb250ZXh0L2NvbnRleHQnO1xuZXhwb3J0IHsgQ29udGV4dCwgQ29udGV4dE1hbmFnZXIgfSBmcm9tICcuL2NvbnRleHQvdHlwZXMnO1xuZXhwb3J0IHR5cGUgeyBDb250ZXh0QVBJIH0gZnJvbSAnLi9hcGkvY29udGV4dCc7XG5cbi8vIERpYWcgQVBJc1xuZXhwb3J0IHsgRGlhZ0NvbnNvbGVMb2dnZXIgfSBmcm9tICcuL2RpYWcvY29uc29sZUxvZ2dlcic7XG5leHBvcnQge1xuICBEaWFnTG9nRnVuY3Rpb24sXG4gIERpYWdMb2dnZXIsXG4gIERpYWdMb2dMZXZlbCxcbiAgQ29tcG9uZW50TG9nZ2VyT3B0aW9ucyxcbiAgRGlhZ0xvZ2dlck9wdGlvbnMsXG59IGZyb20gJy4vZGlhZy90eXBlcyc7XG5leHBvcnQgdHlwZSB7IERpYWdBUEkgfSBmcm9tICcuL2FwaS9kaWFnJztcblxuLy8gTWV0cmljcyBBUElzXG5leHBvcnQgeyBjcmVhdGVOb29wTWV0ZXIgfSBmcm9tICcuL21ldHJpY3MvTm9vcE1ldGVyJztcbmV4cG9ydCB7IE1ldGVyT3B0aW9ucywgTWV0ZXIgfSBmcm9tICcuL21ldHJpY3MvTWV0ZXInO1xuZXhwb3J0IHsgTWV0ZXJQcm92aWRlciB9IGZyb20gJy4vbWV0cmljcy9NZXRlclByb3ZpZGVyJztcbmV4cG9ydCB7XG4gIFZhbHVlVHlwZSxcbiAgQ291bnRlcixcbiAgR2F1Z2UsXG4gIEhpc3RvZ3JhbSxcbiAgTWV0cmljT3B0aW9ucyxcbiAgT2JzZXJ2YWJsZSxcbiAgT2JzZXJ2YWJsZUNvdW50ZXIsXG4gIE9ic2VydmFibGVHYXVnZSxcbiAgT2JzZXJ2YWJsZVVwRG93bkNvdW50ZXIsXG4gIFVwRG93bkNvdW50ZXIsXG4gIEJhdGNoT2JzZXJ2YWJsZUNhbGxiYWNrLFxuICBNZXRyaWNBZHZpY2UsXG4gIE1ldHJpY0F0dHJpYnV0ZXMsXG4gIE1ldHJpY0F0dHJpYnV0ZVZhbHVlLFxuICBPYnNlcnZhYmxlQ2FsbGJhY2ssXG59IGZyb20gJy4vbWV0cmljcy9NZXRyaWMnO1xuZXhwb3J0IHtcbiAgQmF0Y2hPYnNlcnZhYmxlUmVzdWx0LFxuICBPYnNlcnZhYmxlUmVzdWx0LFxufSBmcm9tICcuL21ldHJpY3MvT2JzZXJ2YWJsZVJlc3VsdCc7XG5leHBvcnQgdHlwZSB7IE1ldHJpY3NBUEkgfSBmcm9tICcuL2FwaS9tZXRyaWNzJztcblxuLy8gUHJvcGFnYXRpb24gQVBJc1xuZXhwb3J0IHtcbiAgVGV4dE1hcFByb3BhZ2F0b3IsXG4gIFRleHRNYXBTZXR0ZXIsXG4gIFRleHRNYXBHZXR0ZXIsXG4gIGRlZmF1bHRUZXh0TWFwR2V0dGVyLFxuICBkZWZhdWx0VGV4dE1hcFNldHRlcixcbn0gZnJvbSAnLi9wcm9wYWdhdGlvbi9UZXh0TWFwUHJvcGFnYXRvcic7XG5leHBvcnQgdHlwZSB7IFByb3BhZ2F0aW9uQVBJIH0gZnJvbSAnLi9hcGkvcHJvcGFnYXRpb24nO1xuXG4vLyBUcmFjZSBBUElzXG5leHBvcnQgeyBTcGFuQXR0cmlidXRlcywgU3BhbkF0dHJpYnV0ZVZhbHVlIH0gZnJvbSAnLi90cmFjZS9hdHRyaWJ1dGVzJztcbmV4cG9ydCB7IExpbmsgfSBmcm9tICcuL3RyYWNlL2xpbmsnO1xuZXhwb3J0IHsgUHJveHlUcmFjZXIsIFRyYWNlckRlbGVnYXRvciB9IGZyb20gJy4vdHJhY2UvUHJveHlUcmFjZXInO1xuZXhwb3J0IHsgUHJveHlUcmFjZXJQcm92aWRlciB9IGZyb20gJy4vdHJhY2UvUHJveHlUcmFjZXJQcm92aWRlcic7XG5leHBvcnQgeyBTYW1wbGVyIH0gZnJvbSAnLi90cmFjZS9TYW1wbGVyJztcbmV4cG9ydCB7IFNhbXBsaW5nRGVjaXNpb24sIFNhbXBsaW5nUmVzdWx0IH0gZnJvbSAnLi90cmFjZS9TYW1wbGluZ1Jlc3VsdCc7XG5leHBvcnQgeyBTcGFuQ29udGV4dCB9IGZyb20gJy4vdHJhY2Uvc3Bhbl9jb250ZXh0JztcbmV4cG9ydCB7IFNwYW5LaW5kIH0gZnJvbSAnLi90cmFjZS9zcGFuX2tpbmQnO1xuZXhwb3J0IHsgU3BhbiB9IGZyb20gJy4vdHJhY2Uvc3Bhbic7XG5leHBvcnQgeyBTcGFuT3B0aW9ucyB9IGZyb20gJy4vdHJhY2UvU3Bhbk9wdGlvbnMnO1xuZXhwb3J0IHsgU3BhblN0YXR1cywgU3BhblN0YXR1c0NvZGUgfSBmcm9tICcuL3RyYWNlL3N0YXR1cyc7XG5leHBvcnQgeyBUcmFjZUZsYWdzIH0gZnJvbSAnLi90cmFjZS90cmFjZV9mbGFncyc7XG5leHBvcnQgeyBUcmFjZVN0YXRlIH0gZnJvbSAnLi90cmFjZS90cmFjZV9zdGF0ZSc7XG5leHBvcnQgeyBjcmVhdGVUcmFjZVN0YXRlIH0gZnJvbSAnLi90cmFjZS9pbnRlcm5hbC91dGlscyc7XG5leHBvcnQgeyBUcmFjZXJQcm92aWRlciB9IGZyb20gJy4vdHJhY2UvdHJhY2VyX3Byb3ZpZGVyJztcbmV4cG9ydCB7IFRyYWNlciB9IGZyb20gJy4vdHJhY2UvdHJhY2VyJztcbmV4cG9ydCB7IFRyYWNlck9wdGlvbnMgfSBmcm9tICcuL3RyYWNlL3RyYWNlcl9vcHRpb25zJztcbmV4cG9ydCB7XG4gIGlzU3BhbkNvbnRleHRWYWxpZCxcbiAgaXNWYWxpZFRyYWNlSWQsXG4gIGlzVmFsaWRTcGFuSWQsXG59IGZyb20gJy4vdHJhY2Uvc3BhbmNvbnRleHQtdXRpbHMnO1xuZXhwb3J0IHtcbiAgSU5WQUxJRF9TUEFOSUQsXG4gIElOVkFMSURfVFJBQ0VJRCxcbiAgSU5WQUxJRF9TUEFOX0NPTlRFWFQsXG59IGZyb20gJy4vdHJhY2UvaW52YWxpZC1zcGFuLWNvbnN0YW50cyc7XG5leHBvcnQgdHlwZSB7IFRyYWNlQVBJIH0gZnJvbSAnLi9hcGkvdHJhY2UnO1xuXG4vLyBTcGxpdCBtb2R1bGUtbGV2ZWwgdmFyaWFibGUgZGVmaW5pdGlvbiBpbnRvIHNlcGFyYXRlIGZpbGVzIHRvIGFsbG93XG4vLyB0cmVlLXNoYWtpbmcgb24gZWFjaCBhcGkgaW5zdGFuY2UuXG5pbXBvcnQgeyBjb250ZXh0IH0gZnJvbSAnLi9jb250ZXh0LWFwaSc7XG5pbXBvcnQgeyBkaWFnIH0gZnJvbSAnLi9kaWFnLWFwaSc7XG5pbXBvcnQgeyBtZXRyaWNzIH0gZnJvbSAnLi9tZXRyaWNzLWFwaSc7XG5pbXBvcnQgeyBwcm9wYWdhdGlvbiB9IGZyb20gJy4vcHJvcGFnYXRpb24tYXBpJztcbmltcG9ydCB7IHRyYWNlIH0gZnJvbSAnLi90cmFjZS1hcGknO1xuXG4vLyBOYW1lZCBleHBvcnQuXG5leHBvcnQgeyBjb250ZXh0LCBkaWFnLCBtZXRyaWNzLCBwcm9wYWdhdGlvbiwgdHJhY2UgfTtcbi8vIERlZmF1bHQgZXhwb3J0LlxuZXhwb3J0IGRlZmF1bHQge1xuICBjb250ZXh0LFxuICBkaWFnLFxuICBtZXRyaWNzLFxuICBwcm9wYWdhdGlvbixcbiAgdHJhY2UsXG59O1xuIiwgImltcG9ydCB7IGNyZWF0ZUhvb2ssIGNyZWF0ZVdlYmhvb2ssIEZhdGFsRXJyb3IsIGZldGNoLCBnZXRXb3JrZmxvd01ldGFkYXRhLCBnZXRXcml0YWJsZSwgc2xlZXAgfSBmcm9tIFwid29ya2Zsb3dcIjtcbmltcG9ydCB7IGNhbGxUaHJvd2VyIH0gZnJvbSBcIi4vaGVscGVycy5qc1wiO1xuLyoqX19pbnRlcm5hbF93b3JrZmxvd3N7XCJ3b3JrZmxvd3NcIjp7XCJleGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHNcIjp7XCJhZGRUZW5Xb3JrZmxvd1wiOntcIndvcmtmbG93SWRcIjpcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL2FkZFRlbldvcmtmbG93XCJ9LFwiY3Jvc3NGaWxlRXJyb3JXb3JrZmxvd1wiOntcIndvcmtmbG93SWRcIjpcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL2Nyb3NzRmlsZUVycm9yV29ya2Zsb3dcIn0sXCJmZXRjaFdvcmtmbG93XCI6e1wid29ya2Zsb3dJZFwiOlwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vZmV0Y2hXb3JrZmxvd1wifSxcImhvb2tDbGVhbnVwVGVzdFdvcmtmbG93XCI6e1wid29ya2Zsb3dJZFwiOlwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vaG9va0NsZWFudXBUZXN0V29ya2Zsb3dcIn0sXCJob29rV29ya2Zsb3dcIjp7XCJ3b3JrZmxvd0lkXCI6XCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9ob29rV29ya2Zsb3dcIn0sXCJuZXN0ZWRFcnJvcldvcmtmbG93XCI6e1wid29ya2Zsb3dJZFwiOlwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vbmVzdGVkRXJyb3JXb3JrZmxvd1wifSxcIm51bGxCeXRlV29ya2Zsb3dcIjp7XCJ3b3JrZmxvd0lkXCI6XCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9udWxsQnl0ZVdvcmtmbG93XCJ9LFwib3V0cHV0U3RyZWFtSW5zaWRlU3RlcFdvcmtmbG93XCI6e1wid29ya2Zsb3dJZFwiOlwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vb3V0cHV0U3RyZWFtSW5zaWRlU3RlcFdvcmtmbG93XCJ9LFwib3V0cHV0U3RyZWFtV29ya2Zsb3dcIjp7XCJ3b3JrZmxvd0lkXCI6XCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9vdXRwdXRTdHJlYW1Xb3JrZmxvd1wifSxcInByb21pc2VBbGxXb3JrZmxvd1wiOntcIndvcmtmbG93SWRcIjpcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3Byb21pc2VBbGxXb3JrZmxvd1wifSxcInByb21pc2VBbnlXb3JrZmxvd1wiOntcIndvcmtmbG93SWRcIjpcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3Byb21pc2VBbnlXb3JrZmxvd1wifSxcInByb21pc2VSYWNlU3RyZXNzVGVzdFdvcmtmbG93XCI6e1wid29ya2Zsb3dJZFwiOlwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vcHJvbWlzZVJhY2VTdHJlc3NUZXN0V29ya2Zsb3dcIn0sXCJwcm9taXNlUmFjZVdvcmtmbG93XCI6e1wid29ya2Zsb3dJZFwiOlwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vcHJvbWlzZVJhY2VXb3JrZmxvd1wifSxcInJlYWRhYmxlU3RyZWFtV29ya2Zsb3dcIjp7XCJ3b3JrZmxvd0lkXCI6XCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9yZWFkYWJsZVN0cmVhbVdvcmtmbG93XCJ9LFwicmV0cnlBdHRlbXB0Q291bnRlcldvcmtmbG93XCI6e1wid29ya2Zsb3dJZFwiOlwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vcmV0cnlBdHRlbXB0Q291bnRlcldvcmtmbG93XCJ9LFwicmV0cnlhYmxlQW5kRmF0YWxFcnJvcldvcmtmbG93XCI6e1wid29ya2Zsb3dJZFwiOlwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vcmV0cnlhYmxlQW5kRmF0YWxFcnJvcldvcmtmbG93XCJ9LFwic2xlZXBpbmdXb3JrZmxvd1wiOntcIndvcmtmbG93SWRcIjpcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3NsZWVwaW5nV29ya2Zsb3dcIn0sXCJzdGVwRnVuY3Rpb25QYXNzaW5nV29ya2Zsb3dcIjp7XCJ3b3JrZmxvd0lkXCI6XCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9zdGVwRnVuY3Rpb25QYXNzaW5nV29ya2Zsb3dcIn0sXCJ3ZWJob29rV29ya2Zsb3dcIjp7XCJ3b3JrZmxvd0lkXCI6XCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy93ZWJob29rV29ya2Zsb3dcIn0sXCJ3b3JrZmxvd0FuZFN0ZXBNZXRhZGF0YVdvcmtmbG93XCI6e1wid29ya2Zsb3dJZFwiOlwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vd29ya2Zsb3dBbmRTdGVwTWV0YWRhdGFXb3JrZmxvd1wifX19LFwic3RlcHNcIjp7XCJleGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHNcIjp7XCJhZGRcIjp7XCJzdGVwSWRcIjpcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vYWRkXCJ9LFwiZG91YmxlTnVtYmVyXCI6e1wic3RlcElkXCI6XCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL2RvdWJsZU51bWJlclwifSxcImdlblJlYWRhYmxlU3RyZWFtXCI6e1wic3RlcElkXCI6XCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL2dlblJlYWRhYmxlU3RyZWFtXCJ9LFwibnVsbEJ5dGVTdGVwXCI6e1wic3RlcElkXCI6XCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL251bGxCeXRlU3RlcFwifSxcInByb21pc2VSYWNlU3RyZXNzVGVzdERlbGF5U3RlcFwiOntcInN0ZXBJZFwiOlwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9wcm9taXNlUmFjZVN0cmVzc1Rlc3REZWxheVN0ZXBcIn0sXCJyYW5kb21EZWxheVwiOntcInN0ZXBJZFwiOlwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9yYW5kb21EZWxheVwifSxcInNlbmRXZWJob29rUmVzcG9uc2VcIjp7XCJzdGVwSWRcIjpcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc2VuZFdlYmhvb2tSZXNwb25zZVwifSxcInNwZWNpZmljRGVsYXlcIjp7XCJzdGVwSWRcIjpcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc3BlY2lmaWNEZWxheVwifSxcInN0ZXBDbG9zZU91dHB1dFN0cmVhbVwiOntcInN0ZXBJZFwiOlwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9zdGVwQ2xvc2VPdXRwdXRTdHJlYW1cIn0sXCJzdGVwQ2xvc2VPdXRwdXRTdHJlYW1JbnNpZGVTdGVwXCI6e1wic3RlcElkXCI6XCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3N0ZXBDbG9zZU91dHB1dFN0cmVhbUluc2lkZVN0ZXBcIn0sXCJzdGVwVGhhdEZhaWxzXCI6e1wic3RlcElkXCI6XCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3N0ZXBUaGF0RmFpbHNcIn0sXCJzdGVwVGhhdFJldHJpZXNBbmRTdWNjZWVkc1wiOntcInN0ZXBJZFwiOlwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9zdGVwVGhhdFJldHJpZXNBbmRTdWNjZWVkc1wifSxcInN0ZXBUaGF0VGhyb3dzUmV0cnlhYmxlRXJyb3JcIjp7XCJzdGVwSWRcIjpcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc3RlcFRoYXRUaHJvd3NSZXRyeWFibGVFcnJvclwifSxcInN0ZXBXaXRoTWV0YWRhdGFcIjp7XCJzdGVwSWRcIjpcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc3RlcFdpdGhNZXRhZGF0YVwifSxcInN0ZXBXaXRoTmFtZWRPdXRwdXRTdHJlYW1JbnNpZGVTdGVwXCI6e1wic3RlcElkXCI6XCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3N0ZXBXaXRoTmFtZWRPdXRwdXRTdHJlYW1JbnNpZGVTdGVwXCJ9LFwic3RlcFdpdGhPdXRwdXRTdHJlYW1CaW5hcnlcIjp7XCJzdGVwSWRcIjpcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc3RlcFdpdGhPdXRwdXRTdHJlYW1CaW5hcnlcIn0sXCJzdGVwV2l0aE91dHB1dFN0cmVhbUluc2lkZVN0ZXBcIjp7XCJzdGVwSWRcIjpcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc3RlcFdpdGhPdXRwdXRTdHJlYW1JbnNpZGVTdGVwXCJ9LFwic3RlcFdpdGhPdXRwdXRTdHJlYW1PYmplY3RcIjp7XCJzdGVwSWRcIjpcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc3RlcFdpdGhPdXRwdXRTdHJlYW1PYmplY3RcIn0sXCJzdGVwV2l0aFN0ZXBGdW5jdGlvbkFyZ1wiOntcInN0ZXBJZFwiOlwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9zdGVwV2l0aFN0ZXBGdW5jdGlvbkFyZ1wifX19fSovO1xuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGFkZChhLCBiKSB7XG4gICAgcmV0dXJuIGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1VTRV9TVEVQXCIpXShcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vYWRkXCIpKGEsIGIpO1xufVxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGFkZFRlbldvcmtmbG93KGlucHV0KSB7XG4gICAgY29uc3QgYSA9IGF3YWl0IGFkZChpbnB1dCwgMik7XG4gICAgY29uc3QgYiA9IGF3YWl0IGFkZChhLCAzKTtcbiAgICBjb25zdCBjID0gYXdhaXQgYWRkKGIsIDUpO1xuICAgIHJldHVybiBjO1xufVxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gSGVscGVyIGZ1bmN0aW9ucyB0byB0ZXN0IG5lc3RlZCBzdGFjayB0cmFjZXNcbmZ1bmN0aW9uIGRlZXBGdW5jdGlvbigpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0Vycm9yIGZyb20gZGVlcGx5IG5lc3RlZCBmdW5jdGlvbicpO1xufVxuZnVuY3Rpb24gbWlkZGxlRnVuY3Rpb24oKSB7XG4gICAgZGVlcEZ1bmN0aW9uKCk7XG59XG5mdW5jdGlvbiB0b3BMZXZlbEhlbHBlcigpIHtcbiAgICBtaWRkbGVGdW5jdGlvbigpO1xufVxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG5lc3RlZEVycm9yV29ya2Zsb3coKSB7XG4gICAgdG9wTGV2ZWxIZWxwZXIoKTtcbiAgICByZXR1cm4gJ25ldmVyIHJlYWNoZWQnO1xufVxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuYXN5bmMgZnVuY3Rpb24gcmFuZG9tRGVsYXkodikge1xuICAgIHJldHVybiBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19VU0VfU1RFUFwiKV0oXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3JhbmRvbURlbGF5XCIpKHYpO1xufVxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHByb21pc2VBbGxXb3JrZmxvdygpIHtcbiAgICBjb25zdCBbYSwgYiwgY10gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgIHJhbmRvbURlbGF5KCdhJyksXG4gICAgICAgIHJhbmRvbURlbGF5KCdiJyksXG4gICAgICAgIHJhbmRvbURlbGF5KCdjJylcbiAgICBdKTtcbiAgICByZXR1cm4gYSArIGIgKyBjO1xufVxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuYXN5bmMgZnVuY3Rpb24gc3BlY2lmaWNEZWxheShkZWxheSwgdikge1xuICAgIHJldHVybiBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19VU0VfU1RFUFwiKV0oXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3NwZWNpZmljRGVsYXlcIikoZGVsYXksIHYpO1xufVxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHByb21pc2VSYWNlV29ya2Zsb3coKSB7XG4gICAgY29uc3Qgd2lubmVyID0gYXdhaXQgUHJvbWlzZS5yYWNlKFtcbiAgICAgICAgc3BlY2lmaWNEZWxheSgxMDAwMCwgJ2EnKSxcbiAgICAgICAgc3BlY2lmaWNEZWxheSgxMDAsICdiJyksXG4gICAgICAgIHNwZWNpZmljRGVsYXkoMjAwMDAsICdjJylcbiAgICBdKTtcbiAgICByZXR1cm4gd2lubmVyO1xufVxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuYXN5bmMgZnVuY3Rpb24gc3RlcFRoYXRGYWlscygpIHtcbiAgICByZXR1cm4gZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildKFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9zdGVwVGhhdEZhaWxzXCIpKCk7XG59XG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcHJvbWlzZUFueVdvcmtmbG93KCkge1xuICAgIGNvbnN0IHdpbm5lciA9IGF3YWl0IFByb21pc2UuYW55KFtcbiAgICAgICAgc3RlcFRoYXRGYWlscygpLFxuICAgICAgICBzcGVjaWZpY0RlbGF5KDEwMDAsICdiJyksXG4gICAgICAgIHNwZWNpZmljRGVsYXkoMzAwMCwgJ2MnKVxuICAgIF0pO1xuICAgIHJldHVybiB3aW5uZXI7XG59XG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBOYW1lIHNob3VsZCBub3QgY29uZmxpY3Qgd2l0aCBnZW5TdHJlYW0gaW4gM19zdHJlYW1zLnRzXG4vLyBUT0RPOiBzd2MgdHJhbnNmb3JtIHNob3VsZCBtYW5nbGUgbmFtZXMgdG8gYXZvaWQgY29uZmxpY3RzXG5hc3luYyBmdW5jdGlvbiBnZW5SZWFkYWJsZVN0cmVhbSgpIHtcbiAgICByZXR1cm4gZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildKFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9nZW5SZWFkYWJsZVN0cmVhbVwiKSgpO1xufVxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlYWRhYmxlU3RyZWFtV29ya2Zsb3coKSB7XG4gICAgY29uc29sZS5sb2coJ2NhbGxpbmcgZ2VuUmVhZGFibGVTdHJlYW0nKTtcbiAgICBjb25zdCBzdHJlYW0gPSBhd2FpdCBnZW5SZWFkYWJsZVN0cmVhbSgpO1xuICAgIGNvbnNvbGUubG9nKCdnZW5SZWFkYWJsZVN0cmVhbSByZXR1cm5lZCcsIHN0cmVhbSk7XG4gICAgcmV0dXJuIHN0cmVhbTtcbn1cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBob29rV29ya2Zsb3codG9rZW4sIGN1c3RvbURhdGEpIHtcbiAgICBjb25zdCBob29rID0gY3JlYXRlSG9vayh7XG4gICAgICAgIHRva2VuLFxuICAgICAgICBtZXRhZGF0YToge1xuICAgICAgICAgICAgY3VzdG9tRGF0YVxuICAgICAgICB9XG4gICAgfSk7XG4gICAgY29uc3QgcGF5bG9hZHMgPSBbXTtcbiAgICBmb3IgYXdhaXQgKGNvbnN0IHBheWxvYWQgb2YgaG9vayl7XG4gICAgICAgIHBheWxvYWRzLnB1c2gocGF5bG9hZCk7XG4gICAgICAgIGlmIChwYXlsb2FkLmRvbmUpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBwYXlsb2Fkcztcbn1cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbmFzeW5jIGZ1bmN0aW9uIHNlbmRXZWJob29rUmVzcG9uc2UocmVxKSB7XG4gICAgcmV0dXJuIGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1VTRV9TVEVQXCIpXShcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc2VuZFdlYmhvb2tSZXNwb25zZVwiKShyZXEpO1xufVxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdlYmhvb2tXb3JrZmxvdyh0b2tlbiwgdG9rZW4yLCB0b2tlbjMpIHtcbiAgICBjb25zdCBwYXlsb2FkcyA9IFtdO1xuICAgIGNvbnN0IHdlYmhvb2tXaXRoRGVmYXVsdFJlc3BvbnNlID0gY3JlYXRlV2ViaG9vayh7XG4gICAgICAgIHRva2VuXG4gICAgfSk7XG4gICAgY29uc3QgcmVzID0gbmV3IFJlc3BvbnNlKCdIZWxsbyBmcm9tIHN0YXRpYyByZXNwb25zZSEnLCB7XG4gICAgICAgIHN0YXR1czogNDAyXG4gICAgfSk7XG4gICAgY29uc29sZS5sb2coJ3JlcycsIHJlcyk7XG4gICAgY29uc3Qgd2ViaG9va1dpdGhTdGF0aWNSZXNwb25zZSA9IGNyZWF0ZVdlYmhvb2soe1xuICAgICAgICB0b2tlbjogdG9rZW4yLFxuICAgICAgICByZXNwb25kV2l0aDogcmVzXG4gICAgfSk7XG4gICAgY29uc3Qgd2ViaG9va1dpdGhNYW51YWxSZXNwb25zZSA9IGNyZWF0ZVdlYmhvb2soe1xuICAgICAgICB0b2tlbjogdG9rZW4zLFxuICAgICAgICByZXNwb25kV2l0aDogJ21hbnVhbCdcbiAgICB9KTtcbiAgICAvLyBXZWJob29rIHdpdGggZGVmYXVsdCByZXNwb25zZVxuICAgIHtcbiAgICAgICAgY29uc3QgcmVxID0gYXdhaXQgd2ViaG9va1dpdGhEZWZhdWx0UmVzcG9uc2U7XG4gICAgICAgIGNvbnN0IGJvZHkgPSBhd2FpdCByZXEudGV4dCgpO1xuICAgICAgICBwYXlsb2Fkcy5wdXNoKHtcbiAgICAgICAgICAgIHVybDogcmVxLnVybCxcbiAgICAgICAgICAgIG1ldGhvZDogcmVxLm1ldGhvZCxcbiAgICAgICAgICAgIGJvZHlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8vIFdlYmhvb2sgd2l0aCBzdGF0aWMgcmVzcG9uc2VcbiAgICB7XG4gICAgICAgIGNvbnN0IHJlcSA9IGF3YWl0IHdlYmhvb2tXaXRoU3RhdGljUmVzcG9uc2U7XG4gICAgICAgIGNvbnN0IGJvZHkgPSBhd2FpdCByZXEudGV4dCgpO1xuICAgICAgICBwYXlsb2Fkcy5wdXNoKHtcbiAgICAgICAgICAgIHVybDogcmVxLnVybCxcbiAgICAgICAgICAgIG1ldGhvZDogcmVxLm1ldGhvZCxcbiAgICAgICAgICAgIGJvZHlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8vIFdlYmhvb2sgd2l0aCBtYW51YWwgcmVzcG9uc2VcbiAgICB7XG4gICAgICAgIGNvbnN0IHJlcSA9IGF3YWl0IHdlYmhvb2tXaXRoTWFudWFsUmVzcG9uc2U7XG4gICAgICAgIGNvbnN0IGJvZHkgPSBhd2FpdCBzZW5kV2ViaG9va1Jlc3BvbnNlKHJlcSk7XG4gICAgICAgIHBheWxvYWRzLnB1c2goe1xuICAgICAgICAgICAgdXJsOiByZXEudXJsLFxuICAgICAgICAgICAgbWV0aG9kOiByZXEubWV0aG9kLFxuICAgICAgICAgICAgYm9keVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHBheWxvYWRzO1xufVxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNsZWVwaW5nV29ya2Zsb3coKSB7XG4gICAgY29uc3Qgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICBhd2FpdCBzbGVlcCgnMTBzJyk7XG4gICAgY29uc3QgZW5kVGltZSA9IERhdGUubm93KCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgc3RhcnRUaW1lLFxuICAgICAgICBlbmRUaW1lXG4gICAgfTtcbn1cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbmFzeW5jIGZ1bmN0aW9uIG51bGxCeXRlU3RlcCgpIHtcbiAgICByZXR1cm4gZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildKFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9udWxsQnl0ZVN0ZXBcIikoKTtcbn1cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBudWxsQnl0ZVdvcmtmbG93KCkge1xuICAgIGNvbnN0IGEgPSBhd2FpdCBudWxsQnl0ZVN0ZXAoKTtcbiAgICByZXR1cm4gYTtcbn1cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbmFzeW5jIGZ1bmN0aW9uIHN0ZXBXaXRoTWV0YWRhdGEoKSB7XG4gICAgcmV0dXJuIGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1VTRV9TVEVQXCIpXShcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc3RlcFdpdGhNZXRhZGF0YVwiKSgpO1xufVxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdvcmtmbG93QW5kU3RlcE1ldGFkYXRhV29ya2Zsb3coKSB7XG4gICAgY29uc3Qgd29ya2Zsb3dNZXRhZGF0YSA9IGdldFdvcmtmbG93TWV0YWRhdGEoKTtcbiAgICBjb25zdCB7IHN0ZXBNZXRhZGF0YSwgd29ya2Zsb3dNZXRhZGF0YTogaW5uZXJXb3JrZmxvd01ldGFkYXRhIH0gPSBhd2FpdCBzdGVwV2l0aE1ldGFkYXRhKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgd29ya2Zsb3dNZXRhZGF0YToge1xuICAgICAgICAgICAgd29ya2Zsb3dSdW5JZDogd29ya2Zsb3dNZXRhZGF0YS53b3JrZmxvd1J1bklkLFxuICAgICAgICAgICAgd29ya2Zsb3dTdGFydGVkQXQ6IHdvcmtmbG93TWV0YWRhdGEud29ya2Zsb3dTdGFydGVkQXQsXG4gICAgICAgICAgICB1cmw6IHdvcmtmbG93TWV0YWRhdGEudXJsXG4gICAgICAgIH0sXG4gICAgICAgIHN0ZXBNZXRhZGF0YSxcbiAgICAgICAgaW5uZXJXb3JrZmxvd01ldGFkYXRhXG4gICAgfTtcbn1cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbmFzeW5jIGZ1bmN0aW9uIHN0ZXBXaXRoT3V0cHV0U3RyZWFtQmluYXJ5KHdyaXRhYmxlLCB0ZXh0KSB7XG4gICAgcmV0dXJuIGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1VTRV9TVEVQXCIpXShcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc3RlcFdpdGhPdXRwdXRTdHJlYW1CaW5hcnlcIikod3JpdGFibGUsIHRleHQpO1xufVxuYXN5bmMgZnVuY3Rpb24gc3RlcFdpdGhPdXRwdXRTdHJlYW1PYmplY3Qod3JpdGFibGUsIG9iaikge1xuICAgIHJldHVybiBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19VU0VfU1RFUFwiKV0oXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3N0ZXBXaXRoT3V0cHV0U3RyZWFtT2JqZWN0XCIpKHdyaXRhYmxlLCBvYmopO1xufVxuYXN5bmMgZnVuY3Rpb24gc3RlcENsb3NlT3V0cHV0U3RyZWFtKHdyaXRhYmxlKSB7XG4gICAgcmV0dXJuIGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1VTRV9TVEVQXCIpXShcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc3RlcENsb3NlT3V0cHV0U3RyZWFtXCIpKHdyaXRhYmxlKTtcbn1cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvdXRwdXRTdHJlYW1Xb3JrZmxvdygpIHtcbiAgICBjb25zdCB3cml0YWJsZSA9IGdldFdyaXRhYmxlKCk7XG4gICAgY29uc3QgbmFtZWRXcml0YWJsZSA9IGdldFdyaXRhYmxlKHtcbiAgICAgICAgbmFtZXNwYWNlOiAndGVzdCdcbiAgICB9KTtcbiAgICBhd2FpdCBzbGVlcCgnMXMnKTtcbiAgICBhd2FpdCBzdGVwV2l0aE91dHB1dFN0cmVhbUJpbmFyeSh3cml0YWJsZSwgJ0hlbGxvLCB3b3JsZCEnKTtcbiAgICBhd2FpdCBzbGVlcCgnMXMnKTtcbiAgICBhd2FpdCBzdGVwV2l0aE91dHB1dFN0cmVhbUJpbmFyeShuYW1lZFdyaXRhYmxlLCAnSGVsbG8sIG5hbWVkIHN0cmVhbSEnKTtcbiAgICBhd2FpdCBzbGVlcCgnMXMnKTtcbiAgICBhd2FpdCBzdGVwV2l0aE91dHB1dFN0cmVhbU9iamVjdCh3cml0YWJsZSwge1xuICAgICAgICBmb286ICd0ZXN0J1xuICAgIH0pO1xuICAgIGF3YWl0IHNsZWVwKCcxcycpO1xuICAgIGF3YWl0IHN0ZXBXaXRoT3V0cHV0U3RyZWFtT2JqZWN0KG5hbWVkV3JpdGFibGUsIHtcbiAgICAgICAgZm9vOiAnYmFyJ1xuICAgIH0pO1xuICAgIGF3YWl0IHNsZWVwKCcxcycpO1xuICAgIGF3YWl0IHN0ZXBDbG9zZU91dHB1dFN0cmVhbSh3cml0YWJsZSk7XG4gICAgYXdhaXQgc3RlcENsb3NlT3V0cHV0U3RyZWFtKG5hbWVkV3JpdGFibGUpO1xuICAgIHJldHVybiAnZG9uZSc7XG59XG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5hc3luYyBmdW5jdGlvbiBzdGVwV2l0aE91dHB1dFN0cmVhbUluc2lkZVN0ZXAodGV4dCkge1xuICAgIHJldHVybiBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19VU0VfU1RFUFwiKV0oXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3N0ZXBXaXRoT3V0cHV0U3RyZWFtSW5zaWRlU3RlcFwiKSh0ZXh0KTtcbn1cbmFzeW5jIGZ1bmN0aW9uIHN0ZXBXaXRoTmFtZWRPdXRwdXRTdHJlYW1JbnNpZGVTdGVwKG5hbWVzcGFjZSwgb2JqKSB7XG4gICAgcmV0dXJuIGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1VTRV9TVEVQXCIpXShcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc3RlcFdpdGhOYW1lZE91dHB1dFN0cmVhbUluc2lkZVN0ZXBcIikobmFtZXNwYWNlLCBvYmopO1xufVxuYXN5bmMgZnVuY3Rpb24gc3RlcENsb3NlT3V0cHV0U3RyZWFtSW5zaWRlU3RlcChuYW1lc3BhY2UpIHtcbiAgICByZXR1cm4gZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildKFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9zdGVwQ2xvc2VPdXRwdXRTdHJlYW1JbnNpZGVTdGVwXCIpKG5hbWVzcGFjZSk7XG59XG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gb3V0cHV0U3RyZWFtSW5zaWRlU3RlcFdvcmtmbG93KCkge1xuICAgIGF3YWl0IHNsZWVwKCcxcycpO1xuICAgIGF3YWl0IHN0ZXBXaXRoT3V0cHV0U3RyZWFtSW5zaWRlU3RlcCgnSGVsbG8gZnJvbSBzdGVwIScpO1xuICAgIGF3YWl0IHNsZWVwKCcxcycpO1xuICAgIGF3YWl0IHN0ZXBXaXRoTmFtZWRPdXRwdXRTdHJlYW1JbnNpZGVTdGVwKCdzdGVwLW5zJywge1xuICAgICAgICBtZXNzYWdlOiAnSGVsbG8gZnJvbSBuYW1lZCBzdHJlYW0gaW4gc3RlcCEnXG4gICAgfSk7XG4gICAgYXdhaXQgc2xlZXAoJzFzJyk7XG4gICAgYXdhaXQgc3RlcFdpdGhPdXRwdXRTdHJlYW1JbnNpZGVTdGVwKCdTZWNvbmQgbWVzc2FnZScpO1xuICAgIGF3YWl0IHNsZWVwKCcxcycpO1xuICAgIGF3YWl0IHN0ZXBXaXRoTmFtZWRPdXRwdXRTdHJlYW1JbnNpZGVTdGVwKCdzdGVwLW5zJywge1xuICAgICAgICBjb3VudGVyOiA0MlxuICAgIH0pO1xuICAgIGF3YWl0IHNsZWVwKCcxcycpO1xuICAgIGF3YWl0IHN0ZXBDbG9zZU91dHB1dFN0cmVhbUluc2lkZVN0ZXAoKTtcbiAgICBhd2FpdCBzdGVwQ2xvc2VPdXRwdXRTdHJlYW1JbnNpZGVTdGVwKCdzdGVwLW5zJyk7XG4gICAgcmV0dXJuICdkb25lJztcbn1cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBmZXRjaFdvcmtmbG93KCkge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goJ2h0dHBzOi8vanNvbnBsYWNlaG9sZGVyLnR5cGljb2RlLmNvbS90b2Rvcy8xJyk7XG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICByZXR1cm4gZGF0YTtcbn1cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwcm9taXNlUmFjZVN0cmVzc1Rlc3REZWxheVN0ZXAoZHVyLCByZXNwKSB7XG4gICAgcmV0dXJuIGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1VTRV9TVEVQXCIpXShcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vcHJvbWlzZVJhY2VTdHJlc3NUZXN0RGVsYXlTdGVwXCIpKGR1ciwgcmVzcCk7XG59XG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcHJvbWlzZVJhY2VTdHJlc3NUZXN0V29ya2Zsb3coKSB7XG4gICAgY29uc3QgcHJvbWlzZXMgPSBuZXcgTWFwKCk7XG4gICAgY29uc3QgZG9uZSA9IFtdO1xuICAgIGZvcihsZXQgaSA9IDA7IGkgPCA1OyBpKyspe1xuICAgICAgICBjb25zdCByZXNwID0gaTtcbiAgICAgICAgY29uc3QgZHVyID0gMTAwMCAqIDUgKiBpOyAvLyA1IHNlY29uZHMgYXBhcnRcbiAgICAgICAgY29uc29sZS5sb2coYHNjaGVkYCwgcmVzcCwgYC9gLCBkdXIpO1xuICAgICAgICBwcm9taXNlcy5zZXQoaSwgcHJvbWlzZVJhY2VTdHJlc3NUZXN0RGVsYXlTdGVwKGR1ciwgcmVzcCkpO1xuICAgIH1cbiAgICB3aGlsZShwcm9taXNlcy5zaXplID4gMCl7XG4gICAgICAgIGNvbnNvbGUubG9nKGBwcm9taXNlcy5zaXplYCwgcHJvbWlzZXMuc2l6ZSk7XG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IFByb21pc2UucmFjZShwcm9taXNlcy52YWx1ZXMoKSk7XG4gICAgICAgIGNvbnNvbGUubG9nKHJlcyk7XG4gICAgICAgIGRvbmUucHVzaChyZXMpO1xuICAgICAgICBwcm9taXNlcy5kZWxldGUocmVzKTtcbiAgICB9XG4gICAgcmV0dXJuIGRvbmU7XG59XG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5hc3luYyBmdW5jdGlvbiBzdGVwVGhhdFJldHJpZXNBbmRTdWNjZWVkcygpIHtcbiAgICByZXR1cm4gZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildKFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9zdGVwVGhhdFJldHJpZXNBbmRTdWNjZWVkc1wiKSgpO1xufVxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJldHJ5QXR0ZW1wdENvdW50ZXJXb3JrZmxvdygpIHtcbiAgICBjb25zb2xlLmxvZygnU3RhcnRpbmcgcmV0cnkgYXR0ZW1wdCBjb3VudGVyIHdvcmtmbG93Jyk7XG4gICAgLy8gVGhpcyBzdGVwIHNob3VsZCBmYWlsIHR3aWNlIGFuZCBzdWNjZWVkIG9uIHRoZSB0aGlyZCBhdHRlbXB0XG4gICAgY29uc3QgZmluYWxBdHRlbXB0ID0gYXdhaXQgc3RlcFRoYXRSZXRyaWVzQW5kU3VjY2VlZHMoKTtcbiAgICBjb25zb2xlLmxvZyhgV29ya2Zsb3cgY29tcGxldGVkIHdpdGggZmluYWwgYXR0ZW1wdDogJHtmaW5hbEF0dGVtcHR9YCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgZmluYWxBdHRlbXB0XG4gICAgfTtcbn1cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbmFzeW5jIGZ1bmN0aW9uIHN0ZXBUaGF0VGhyb3dzUmV0cnlhYmxlRXJyb3IoKSB7XG4gICAgcmV0dXJuIGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1VTRV9TVEVQXCIpXShcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc3RlcFRoYXRUaHJvd3NSZXRyeWFibGVFcnJvclwiKSgpO1xufVxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNyb3NzRmlsZUVycm9yV29ya2Zsb3coKSB7XG4gICAgLy8gVGhpcyB3aWxsIHRocm93IGFuIGVycm9yIGZyb20gdGhlIGltcG9ydGVkIGhlbHBlcnMudHMgZmlsZVxuICAgIGNhbGxUaHJvd2VyKCk7XG4gICAgcmV0dXJuICduZXZlciByZWFjaGVkJztcbn1cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZXRyeWFibGVBbmRGYXRhbEVycm9yV29ya2Zsb3coKSB7XG4gICAgY29uc3QgcmV0cnlhYmxlUmVzdWx0ID0gYXdhaXQgc3RlcFRoYXRUaHJvd3NSZXRyeWFibGVFcnJvcigpO1xuICAgIGxldCBnb3RGYXRhbEVycm9yID0gZmFsc2U7XG4gICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgc3RlcFRoYXRGYWlscygpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGlmIChGYXRhbEVycm9yLmlzKGVycm9yKSkge1xuICAgICAgICAgICAgZ290RmF0YWxFcnJvciA9IHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgcmV0cnlhYmxlUmVzdWx0LFxuICAgICAgICBnb3RGYXRhbEVycm9yXG4gICAgfTtcbn1cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBob29rQ2xlYW51cFRlc3RXb3JrZmxvdyh0b2tlbiwgY3VzdG9tRGF0YSkge1xuICAgIGNvbnN0IGhvb2sgPSBjcmVhdGVIb29rKHtcbiAgICAgICAgdG9rZW4sXG4gICAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgICAgICBjdXN0b21EYXRhXG4gICAgICAgIH1cbiAgICB9KTtcbiAgICAvLyBXYWl0IGZvciBleGFjdGx5IG9uZSBwYXlsb2FkXG4gICAgY29uc3QgcGF5bG9hZCA9IGF3YWl0IGhvb2s7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbWVzc2FnZTogcGF5bG9hZC5tZXNzYWdlLFxuICAgICAgICBjdXN0b21EYXRhOiBwYXlsb2FkLmN1c3RvbURhdGEsXG4gICAgICAgIGhvb2tDbGVhbnVwVGVzdERhdGE6ICd3b3JrZmxvd19jb21wbGV0ZWQnXG4gICAgfTtcbn1cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzdGVwRnVuY3Rpb25QYXNzaW5nV29ya2Zsb3coKSB7XG4gICAgLy8gUGFzcyBhIHN0ZXAgZnVuY3Rpb24gcmVmZXJlbmNlIHRvIGFub3RoZXIgc3RlcFxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHN0ZXBXaXRoU3RlcEZ1bmN0aW9uQXJnKGRvdWJsZU51bWJlcik7XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbmFzeW5jIGZ1bmN0aW9uIHN0ZXBXaXRoU3RlcEZ1bmN0aW9uQXJnKHN0ZXBGbikge1xuICAgIHJldHVybiBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19VU0VfU1RFUFwiKV0oXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3N0ZXBXaXRoU3RlcEZ1bmN0aW9uQXJnXCIpKHN0ZXBGbik7XG59XG5hc3luYyBmdW5jdGlvbiBkb3VibGVOdW1iZXIoeCkge1xuICAgIHJldHVybiBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19VU0VfU1RFUFwiKV0oXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL2RvdWJsZU51bWJlclwiKSh4KTtcbn1cbmFkZFRlbldvcmtmbG93LndvcmtmbG93SWQgPSBcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL2FkZFRlbldvcmtmbG93XCI7XG5uZXN0ZWRFcnJvcldvcmtmbG93LndvcmtmbG93SWQgPSBcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL25lc3RlZEVycm9yV29ya2Zsb3dcIjtcbnByb21pc2VBbGxXb3JrZmxvdy53b3JrZmxvd0lkID0gXCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9wcm9taXNlQWxsV29ya2Zsb3dcIjtcbnByb21pc2VSYWNlV29ya2Zsb3cud29ya2Zsb3dJZCA9IFwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vcHJvbWlzZVJhY2VXb3JrZmxvd1wiO1xucHJvbWlzZUFueVdvcmtmbG93LndvcmtmbG93SWQgPSBcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3Byb21pc2VBbnlXb3JrZmxvd1wiO1xucmVhZGFibGVTdHJlYW1Xb3JrZmxvdy53b3JrZmxvd0lkID0gXCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9yZWFkYWJsZVN0cmVhbVdvcmtmbG93XCI7XG5ob29rV29ya2Zsb3cud29ya2Zsb3dJZCA9IFwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vaG9va1dvcmtmbG93XCI7XG53ZWJob29rV29ya2Zsb3cud29ya2Zsb3dJZCA9IFwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vd2ViaG9va1dvcmtmbG93XCI7XG5zbGVlcGluZ1dvcmtmbG93LndvcmtmbG93SWQgPSBcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3NsZWVwaW5nV29ya2Zsb3dcIjtcbm51bGxCeXRlV29ya2Zsb3cud29ya2Zsb3dJZCA9IFwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vbnVsbEJ5dGVXb3JrZmxvd1wiO1xud29ya2Zsb3dBbmRTdGVwTWV0YWRhdGFXb3JrZmxvdy53b3JrZmxvd0lkID0gXCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy93b3JrZmxvd0FuZFN0ZXBNZXRhZGF0YVdvcmtmbG93XCI7XG5vdXRwdXRTdHJlYW1Xb3JrZmxvdy53b3JrZmxvd0lkID0gXCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9vdXRwdXRTdHJlYW1Xb3JrZmxvd1wiO1xub3V0cHV0U3RyZWFtSW5zaWRlU3RlcFdvcmtmbG93LndvcmtmbG93SWQgPSBcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL291dHB1dFN0cmVhbUluc2lkZVN0ZXBXb3JrZmxvd1wiO1xuZmV0Y2hXb3JrZmxvdy53b3JrZmxvd0lkID0gXCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9mZXRjaFdvcmtmbG93XCI7XG5wcm9taXNlUmFjZVN0cmVzc1Rlc3RXb3JrZmxvdy53b3JrZmxvd0lkID0gXCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9wcm9taXNlUmFjZVN0cmVzc1Rlc3RXb3JrZmxvd1wiO1xucmV0cnlBdHRlbXB0Q291bnRlcldvcmtmbG93LndvcmtmbG93SWQgPSBcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3JldHJ5QXR0ZW1wdENvdW50ZXJXb3JrZmxvd1wiO1xuY3Jvc3NGaWxlRXJyb3JXb3JrZmxvdy53b3JrZmxvd0lkID0gXCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9jcm9zc0ZpbGVFcnJvcldvcmtmbG93XCI7XG5yZXRyeWFibGVBbmRGYXRhbEVycm9yV29ya2Zsb3cud29ya2Zsb3dJZCA9IFwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vcmV0cnlhYmxlQW5kRmF0YWxFcnJvcldvcmtmbG93XCI7XG5ob29rQ2xlYW51cFRlc3RXb3JrZmxvdy53b3JrZmxvd0lkID0gXCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9ob29rQ2xlYW51cFRlc3RXb3JrZmxvd1wiO1xuc3RlcEZ1bmN0aW9uUGFzc2luZ1dvcmtmbG93LndvcmtmbG93SWQgPSBcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3N0ZXBGdW5jdGlvblBhc3NpbmdXb3JrZmxvd1wiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGFkZCwgU3ltYm9sLmZvcihcIldPUktGTE9XX1NURVBfRlVOQ1RJT05fTkFNRVwiKSwge1xuICAgIHZhbHVlOiBcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vYWRkXCIsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2Vcbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHJhbmRvbURlbGF5LCBTeW1ib2wuZm9yKFwiV09SS0ZMT1dfU1RFUF9GVU5DVElPTl9OQU1FXCIpLCB7XG4gICAgdmFsdWU6IFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9yYW5kb21EZWxheVwiLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlXG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShzcGVjaWZpY0RlbGF5LCBTeW1ib2wuZm9yKFwiV09SS0ZMT1dfU1RFUF9GVU5DVElPTl9OQU1FXCIpLCB7XG4gICAgdmFsdWU6IFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9zcGVjaWZpY0RlbGF5XCIsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2Vcbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHN0ZXBUaGF0RmFpbHMsIFN5bWJvbC5mb3IoXCJXT1JLRkxPV19TVEVQX0ZVTkNUSU9OX05BTUVcIiksIHtcbiAgICB2YWx1ZTogXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3N0ZXBUaGF0RmFpbHNcIixcbiAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiBmYWxzZVxufSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZ2VuUmVhZGFibGVTdHJlYW0sIFN5bWJvbC5mb3IoXCJXT1JLRkxPV19TVEVQX0ZVTkNUSU9OX05BTUVcIiksIHtcbiAgICB2YWx1ZTogXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL2dlblJlYWRhYmxlU3RyZWFtXCIsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2Vcbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHNlbmRXZWJob29rUmVzcG9uc2UsIFN5bWJvbC5mb3IoXCJXT1JLRkxPV19TVEVQX0ZVTkNUSU9OX05BTUVcIiksIHtcbiAgICB2YWx1ZTogXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3NlbmRXZWJob29rUmVzcG9uc2VcIixcbiAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiBmYWxzZVxufSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkobnVsbEJ5dGVTdGVwLCBTeW1ib2wuZm9yKFwiV09SS0ZMT1dfU1RFUF9GVU5DVElPTl9OQU1FXCIpLCB7XG4gICAgdmFsdWU6IFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9udWxsQnl0ZVN0ZXBcIixcbiAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiBmYWxzZVxufSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoc3RlcFdpdGhNZXRhZGF0YSwgU3ltYm9sLmZvcihcIldPUktGTE9XX1NURVBfRlVOQ1RJT05fTkFNRVwiKSwge1xuICAgIHZhbHVlOiBcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc3RlcFdpdGhNZXRhZGF0YVwiLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlXG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShzdGVwV2l0aE91dHB1dFN0cmVhbUJpbmFyeSwgU3ltYm9sLmZvcihcIldPUktGTE9XX1NURVBfRlVOQ1RJT05fTkFNRVwiKSwge1xuICAgIHZhbHVlOiBcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc3RlcFdpdGhPdXRwdXRTdHJlYW1CaW5hcnlcIixcbiAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiBmYWxzZVxufSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoc3RlcFdpdGhPdXRwdXRTdHJlYW1PYmplY3QsIFN5bWJvbC5mb3IoXCJXT1JLRkxPV19TVEVQX0ZVTkNUSU9OX05BTUVcIiksIHtcbiAgICB2YWx1ZTogXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL3N0ZXBXaXRoT3V0cHV0U3RyZWFtT2JqZWN0XCIsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2Vcbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHN0ZXBDbG9zZU91dHB1dFN0cmVhbSwgU3ltYm9sLmZvcihcIldPUktGTE9XX1NURVBfRlVOQ1RJT05fTkFNRVwiKSwge1xuICAgIHZhbHVlOiBcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc3RlcENsb3NlT3V0cHV0U3RyZWFtXCIsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2Vcbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHN0ZXBXaXRoT3V0cHV0U3RyZWFtSW5zaWRlU3RlcCwgU3ltYm9sLmZvcihcIldPUktGTE9XX1NURVBfRlVOQ1RJT05fTkFNRVwiKSwge1xuICAgIHZhbHVlOiBcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vc3RlcFdpdGhPdXRwdXRTdHJlYW1JbnNpZGVTdGVwXCIsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2Vcbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHN0ZXBXaXRoTmFtZWRPdXRwdXRTdHJlYW1JbnNpZGVTdGVwLCBTeW1ib2wuZm9yKFwiV09SS0ZMT1dfU1RFUF9GVU5DVElPTl9OQU1FXCIpLCB7XG4gICAgdmFsdWU6IFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9zdGVwV2l0aE5hbWVkT3V0cHV0U3RyZWFtSW5zaWRlU3RlcFwiLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlXG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShzdGVwQ2xvc2VPdXRwdXRTdHJlYW1JbnNpZGVTdGVwLCBTeW1ib2wuZm9yKFwiV09SS0ZMT1dfU1RFUF9GVU5DVElPTl9OQU1FXCIpLCB7XG4gICAgdmFsdWU6IFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9zdGVwQ2xvc2VPdXRwdXRTdHJlYW1JbnNpZGVTdGVwXCIsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2Vcbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHByb21pc2VSYWNlU3RyZXNzVGVzdERlbGF5U3RlcCwgU3ltYm9sLmZvcihcIldPUktGTE9XX1NURVBfRlVOQ1RJT05fTkFNRVwiKSwge1xuICAgIHZhbHVlOiBcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk5X2UyZS50cy8vcHJvbWlzZVJhY2VTdHJlc3NUZXN0RGVsYXlTdGVwXCIsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2Vcbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHN0ZXBUaGF0UmV0cmllc0FuZFN1Y2NlZWRzLCBTeW1ib2wuZm9yKFwiV09SS0ZMT1dfU1RFUF9GVU5DVElPTl9OQU1FXCIpLCB7XG4gICAgdmFsdWU6IFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9zdGVwVGhhdFJldHJpZXNBbmRTdWNjZWVkc1wiLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlXG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShzdGVwVGhhdFRocm93c1JldHJ5YWJsZUVycm9yLCBTeW1ib2wuZm9yKFwiV09SS0ZMT1dfU1RFUF9GVU5DVElPTl9OQU1FXCIpLCB7XG4gICAgdmFsdWU6IFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9zdGVwVGhhdFRocm93c1JldHJ5YWJsZUVycm9yXCIsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2Vcbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHN0ZXBXaXRoU3RlcEZ1bmN0aW9uQXJnLCBTeW1ib2wuZm9yKFwiV09SS0ZMT1dfU1RFUF9GVU5DVElPTl9OQU1FXCIpLCB7XG4gICAgdmFsdWU6IFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvOTlfZTJlLnRzLy9zdGVwV2l0aFN0ZXBGdW5jdGlvbkFyZ1wiLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlXG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShkb3VibGVOdW1iZXIsIFN5bWJvbC5mb3IoXCJXT1JLRkxPV19TVEVQX0ZVTkNUSU9OX05BTUVcIiksIHtcbiAgICB2YWx1ZTogXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMvL2RvdWJsZU51bWJlclwiLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlXG59KTtcbiIsICJpbXBvcnQgdHlwZSB7IFN0cmluZ1ZhbHVlIH0gZnJvbSAnbXMnO1xuaW1wb3J0IG1zIGZyb20gJ21zJztcblxuZXhwb3J0IGludGVyZmFjZSBQcm9taXNlV2l0aFJlc29sdmVyczxUPiB7XG4gIHByb21pc2U6IFByb21pc2U8VD47XG4gIHJlc29sdmU6ICh2YWx1ZTogVCkgPT4gdm9pZDtcbiAgcmVqZWN0OiAocmVhc29uPzogYW55KSA9PiB2b2lkO1xufVxuXG4vKipcbiAqIFBvbHlmaWxsIGZvciBgUHJvbWlzZS53aXRoUmVzb2x2ZXJzKClgLlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvUHJvbWlzZS93aXRoUmVzb2x2ZXJzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3aXRoUmVzb2x2ZXJzPFQ+KCk6IFByb21pc2VXaXRoUmVzb2x2ZXJzPFQ+IHtcbiAgbGV0IHJlc29sdmUhOiAodmFsdWU6IFQpID0+IHZvaWQ7XG4gIGxldCByZWplY3QhOiAocmVhc29uPzogYW55KSA9PiB2b2lkO1xuICBjb25zdCBwcm9taXNlID0gbmV3IFByb21pc2U8VD4oKF9yZXNvbHZlLCBfcmVqZWN0KSA9PiB7XG4gICAgcmVzb2x2ZSA9IF9yZXNvbHZlO1xuICAgIHJlamVjdCA9IF9yZWplY3Q7XG4gIH0pO1xuICByZXR1cm4geyBwcm9taXNlLCByZXNvbHZlLCByZWplY3QgfTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbGF6aWx5LWV2YWx1YXRlZCwgbWVtb2l6ZWQgdmVyc2lvbiBvZiB0aGUgcHJvdmlkZWQgZnVuY3Rpb24uXG4gKlxuICogVGhlIHJldHVybmVkIG9iamVjdCBleHBvc2VzIGEgYHZhbHVlYCBnZXR0ZXIgdGhhdCBjYWxscyBgZm5gIG9ubHkgb25jZSxcbiAqIGNhY2hlcyBpdHMgcmVzdWx0LCBhbmQgcmV0dXJucyB0aGUgY2FjaGVkIHZhbHVlIG9uIHN1YnNlcXVlbnQgYWNjZXNzZXMuXG4gKlxuICogQHR5cGVQYXJhbSBUIC0gVGhlIHJldHVybiB0eXBlIG9mIHRoZSBwcm92aWRlZCBmdW5jdGlvbi5cbiAqIEBwYXJhbSBmbiAtIFRoZSBmdW5jdGlvbiB0byBiZSBjYWxsZWQgb25jZSBhbmQgd2hvc2UgcmVzdWx0IHdpbGwgYmUgY2FjaGVkLlxuICogQHJldHVybnMgQW4gb2JqZWN0IHdpdGggYSBgdmFsdWVgIHByb3BlcnR5IHRoYXQgcmV0dXJucyB0aGUgbWVtb2l6ZWQgcmVzdWx0IG9mIGBmbmAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvbmNlPFQ+KGZuOiAoKSA9PiBUKSB7XG4gIGNvbnN0IHJlc3VsdCA9IHtcbiAgICBnZXQgdmFsdWUoKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IGZuKCk7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocmVzdWx0LCAndmFsdWUnLCB7IHZhbHVlIH0pO1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH0sXG4gIH07XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogUGFyc2VzIGEgZHVyYXRpb24gcGFyYW1ldGVyIChzdHJpbmcsIG51bWJlciwgb3IgRGF0ZSkgYW5kIHJldHVybnMgYSBEYXRlIG9iamVjdFxuICogcmVwcmVzZW50aW5nIHdoZW4gdGhlIGR1cmF0aW9uIHNob3VsZCBlbGFwc2UuXG4gKlxuICogLSBGb3Igc3RyaW5nczogUGFyc2VzIGR1cmF0aW9uIHN0cmluZ3MgbGlrZSBcIjFzXCIsIFwiNW1cIiwgXCIxaFwiLCBldGMuIHVzaW5nIHRoZSBgbXNgIGxpYnJhcnlcbiAqIC0gRm9yIG51bWJlcnM6IFRyZWF0cyBhcyBtaWxsaXNlY29uZHMgZnJvbSBub3dcbiAqIC0gRm9yIERhdGUgb2JqZWN0czogUmV0dXJucyB0aGUgZGF0ZSBkaXJlY3RseSAoaGFuZGxlcyBib3RoIERhdGUgaW5zdGFuY2VzIGFuZCBkYXRlLWxpa2Ugb2JqZWN0cyBmcm9tIGRlc2VyaWFsaXphdGlvbilcbiAqXG4gKiBAcGFyYW0gcGFyYW0gLSBUaGUgZHVyYXRpb24gcGFyYW1ldGVyIChTdHJpbmdWYWx1ZSwgRGF0ZSwgb3IgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcylcbiAqIEByZXR1cm5zIEEgRGF0ZSBvYmplY3QgcmVwcmVzZW50aW5nIHdoZW4gdGhlIGR1cmF0aW9uIHNob3VsZCBlbGFwc2VcbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGFyYW1ldGVyIGlzIGludmFsaWQgb3IgY2Fubm90IGJlIHBhcnNlZFxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VEdXJhdGlvblRvRGF0ZShwYXJhbTogU3RyaW5nVmFsdWUgfCBEYXRlIHwgbnVtYmVyKTogRGF0ZSB7XG4gIGlmICh0eXBlb2YgcGFyYW0gPT09ICdzdHJpbmcnKSB7XG4gICAgY29uc3QgZHVyYXRpb25NcyA9IG1zKHBhcmFtKTtcbiAgICBpZiAodHlwZW9mIGR1cmF0aW9uTXMgIT09ICdudW1iZXInIHx8IGR1cmF0aW9uTXMgPCAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBJbnZhbGlkIGR1cmF0aW9uOiBcIiR7cGFyYW19XCIuIEV4cGVjdGVkIGEgdmFsaWQgZHVyYXRpb24gc3RyaW5nIGxpa2UgXCIxc1wiLCBcIjFtXCIsIFwiMWhcIiwgZXRjLmBcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgRGF0ZShEYXRlLm5vdygpICsgZHVyYXRpb25Ncyk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIHBhcmFtID09PSAnbnVtYmVyJykge1xuICAgIGlmIChwYXJhbSA8IDAgfHwgIU51bWJlci5pc0Zpbml0ZShwYXJhbSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEludmFsaWQgZHVyYXRpb246ICR7cGFyYW19LiBFeHBlY3RlZCBhIG5vbi1uZWdhdGl2ZSBmaW5pdGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcy5gXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IERhdGUoRGF0ZS5ub3coKSArIHBhcmFtKTtcbiAgfSBlbHNlIGlmIChcbiAgICBwYXJhbSBpbnN0YW5jZW9mIERhdGUgfHxcbiAgICAocGFyYW0gJiZcbiAgICAgIHR5cGVvZiBwYXJhbSA9PT0gJ29iamVjdCcgJiZcbiAgICAgIHR5cGVvZiAocGFyYW0gYXMgYW55KS5nZXRUaW1lID09PSAnZnVuY3Rpb24nKVxuICApIHtcbiAgICAvLyBIYW5kbGUgYm90aCBEYXRlIGluc3RhbmNlcyBhbmQgZGF0ZS1saWtlIG9iamVjdHMgKGZyb20gZGVzZXJpYWxpemF0aW9uKVxuICAgIHJldHVybiBwYXJhbSBpbnN0YW5jZW9mIERhdGUgPyBwYXJhbSA6IG5ldyBEYXRlKChwYXJhbSBhcyBhbnkpLmdldFRpbWUoKSk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYEludmFsaWQgZHVyYXRpb24gcGFyYW1ldGVyLiBFeHBlY3RlZCBhIGR1cmF0aW9uIHN0cmluZywgbnVtYmVyIChtaWxsaXNlY29uZHMpLCBvciBEYXRlIG9iamVjdC5gXG4gICAgKTtcbiAgfVxufVxuIiwgImltcG9ydCB7IHBhcnNlRHVyYXRpb25Ub0RhdGUgfSBmcm9tICdAd29ya2Zsb3cvdXRpbHMnO1xuaW1wb3J0IHR5cGUgeyBTdHJ1Y3R1cmVkRXJyb3IgfSBmcm9tICdAd29ya2Zsb3cvd29ybGQnO1xuaW1wb3J0IHR5cGUgeyBTdHJpbmdWYWx1ZSB9IGZyb20gJ21zJztcblxuY29uc3QgQkFTRV9VUkwgPSAnaHR0cHM6Ly91c2V3b3JrZmxvdy5kZXYvZXJyJztcblxuLyoqXG4gKiBAaW50ZXJuYWxcbiAqIENoZWNrIGlmIGEgdmFsdWUgaXMgYW4gRXJyb3Igd2l0aG91dCByZWx5aW5nIG9uIE5vZGUuanMgdXRpbGl0aWVzLlxuICogVGhpcyBpcyBuZWVkZWQgZm9yIGVycm9yIGNsYXNzZXMgdGhhdCBjYW4gYmUgdXNlZCBpbiBWTSBjb250ZXh0cyB3aGVyZVxuICogTm9kZS5qcyBpbXBvcnRzIGFyZSBub3QgYXZhaWxhYmxlLlxuICovXG5mdW5jdGlvbiBpc0Vycm9yKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgeyBuYW1lOiBzdHJpbmc7IG1lc3NhZ2U6IHN0cmluZyB9IHtcbiAgcmV0dXJuIChcbiAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXG4gICAgdmFsdWUgIT09IG51bGwgJiZcbiAgICAnbmFtZScgaW4gdmFsdWUgJiZcbiAgICAnbWVzc2FnZScgaW4gdmFsdWVcbiAgKTtcbn1cblxuLyoqXG4gKiBAaW50ZXJuYWxcbiAqIEFsbCB0aGUgc2x1Z3Mgb2YgdGhlIGVycm9ycyB1c2VkIGZvciBkb2N1bWVudGF0aW9uIGxpbmtzLlxuICovXG5leHBvcnQgY29uc3QgRVJST1JfU0xVR1MgPSB7XG4gIE5PREVfSlNfTU9EVUxFX0lOX1dPUktGTE9XOiAnbm9kZS1qcy1tb2R1bGUtaW4td29ya2Zsb3cnLFxuICBTVEFSVF9JTlZBTElEX1dPUktGTE9XX0ZVTkNUSU9OOiAnc3RhcnQtaW52YWxpZC13b3JrZmxvdy1mdW5jdGlvbicsXG4gIFNFUklBTElaQVRJT05fRkFJTEVEOiAnc2VyaWFsaXphdGlvbi1mYWlsZWQnLFxuICBXRUJIT09LX0lOVkFMSURfUkVTUE9ORF9XSVRIX1ZBTFVFOiAnd2ViaG9vay1pbnZhbGlkLXJlc3BvbmQtd2l0aC12YWx1ZScsXG4gIFdFQkhPT0tfUkVTUE9OU0VfTk9UX1NFTlQ6ICd3ZWJob29rLXJlc3BvbnNlLW5vdC1zZW50JyxcbiAgRkVUQ0hfSU5fV09SS0ZMT1dfRlVOQ1RJT046ICdmZXRjaC1pbi13b3JrZmxvdycsXG59IGFzIGNvbnN0O1xuXG50eXBlIEVycm9yU2x1ZyA9ICh0eXBlb2YgRVJST1JfU0xVR1MpW2tleW9mIHR5cGVvZiBFUlJPUl9TTFVHU107XG5cbmludGVyZmFjZSBXb3JrZmxvd0Vycm9yT3B0aW9ucyBleHRlbmRzIEVycm9yT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgc2x1ZyBvZiB0aGUgZXJyb3IuIFRoaXMgd2lsbCBiZSB1c2VkIHRvIGdlbmVyYXRlIGEgbGluayB0byB0aGUgZXJyb3IgZG9jdW1lbnRhdGlvbi5cbiAgICovXG4gIHNsdWc/OiBFcnJvclNsdWc7XG59XG5cbi8qKlxuICogVGhlIGJhc2UgY2xhc3MgZm9yIGFsbCBXb3JrZmxvdy1yZWxhdGVkIGVycm9ycy5cbiAqXG4gKiBUaGlzIGVycm9yIGlzIHRocm93biBieSB0aGUgV29ya2Zsb3cgRGV2S2l0IHdoZW4gaW50ZXJuYWwgb3BlcmF0aW9ucyBmYWlsLlxuICogWW91IGNhbiB1c2UgdGhpcyBjbGFzcyB3aXRoIGBpbnN0YW5jZW9mYCB0byBjYXRjaCBhbnkgV29ya2Zsb3cgRGV2S2l0IGVycm9yLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0c1xuICogdHJ5IHtcbiAqICAgYXdhaXQgZ2V0UnVuKHJ1bklkKTtcbiAqIH0gY2F0Y2ggKGVycm9yKSB7XG4gKiAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFdvcmtmbG93RXJyb3IpIHtcbiAqICAgICBjb25zb2xlLmVycm9yKCdXb3JrZmxvdyBEZXZLaXQgZXJyb3I6JywgZXJyb3IubWVzc2FnZSk7XG4gKiAgIH1cbiAqIH1cbiAqIGBgYFxuICovXG5leHBvcnQgY2xhc3MgV29ya2Zsb3dFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgcmVhZG9ubHkgY2F1c2U/OiB1bmtub3duO1xuXG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZywgb3B0aW9ucz86IFdvcmtmbG93RXJyb3JPcHRpb25zKSB7XG4gICAgY29uc3QgbXNnRG9jcyA9IG9wdGlvbnM/LnNsdWdcbiAgICAgID8gYCR7bWVzc2FnZX1cXG5cXG5MZWFybiBtb3JlOiAke0JBU0VfVVJMfS8ke29wdGlvbnMuc2x1Z31gXG4gICAgICA6IG1lc3NhZ2U7XG4gICAgc3VwZXIobXNnRG9jcywgeyBjYXVzZTogb3B0aW9ucz8uY2F1c2UgfSk7XG4gICAgdGhpcy5jYXVzZSA9IG9wdGlvbnM/LmNhdXNlO1xuXG4gICAgaWYgKG9wdGlvbnM/LmNhdXNlIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIHRoaXMuc3RhY2sgPSBgJHt0aGlzLnN0YWNrfVxcbkNhdXNlZCBieTogJHtvcHRpb25zLmNhdXNlLnN0YWNrfWA7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIGlzKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgV29ya2Zsb3dFcnJvciB7XG4gICAgcmV0dXJuIGlzRXJyb3IodmFsdWUpICYmIHZhbHVlLm5hbWUgPT09ICdXb3JrZmxvd0Vycm9yJztcbiAgfVxufVxuXG4vKipcbiAqIFRocm93biB3aGVuIGEgV29ya2Zsb3cgQVBJIHJlcXVlc3QgZmFpbHMuXG4gKlxuICogVGhpcyBlcnJvciBpcyB0aHJvd24gd2hlbiBIVFRQIHJlcXVlc3RzIHRvIHRoZSBXb3JrZmxvdyBiYWNrZW5kIGZhaWwsXG4gKiB0eXBpY2FsbHkgZHVlIHRvIG5ldHdvcmsgaXNzdWVzLCBpbnZhbGlkIHJlcXVlc3RzLCBvciBzZXJ2ZXIgZXJyb3JzLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0c1xuICogdHJ5IHtcbiAqICAgYXdhaXQgc3RhcnRXb3JrZmxvdygnbXlXb3JrZmxvdycsIGlucHV0KTtcbiAqIH0gY2F0Y2ggKGVycm9yKSB7XG4gKiAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFdvcmtmbG93QVBJRXJyb3IpIHtcbiAqICAgICBjb25zb2xlLmVycm9yKGBBUEkgZXJyb3IgKCR7ZXJyb3Iuc3RhdHVzfSk6YCwgZXJyb3IubWVzc2FnZSk7XG4gKiAgIH1cbiAqIH1cbiAqIGBgYFxuICovXG5leHBvcnQgY2xhc3MgV29ya2Zsb3dBUElFcnJvciBleHRlbmRzIFdvcmtmbG93RXJyb3Ige1xuICBzdGF0dXM/OiBudW1iZXI7XG4gIGNvZGU/OiBzdHJpbmc7XG4gIHVybD86IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBtZXNzYWdlOiBzdHJpbmcsXG4gICAgb3B0aW9ucz86IHsgc3RhdHVzPzogbnVtYmVyOyB1cmw/OiBzdHJpbmc7IGNvZGU/OiBzdHJpbmc7IGNhdXNlPzogdW5rbm93biB9XG4gICkge1xuICAgIHN1cGVyKG1lc3NhZ2UsIHtcbiAgICAgIGNhdXNlOiBvcHRpb25zPy5jYXVzZSxcbiAgICB9KTtcbiAgICB0aGlzLm5hbWUgPSAnV29ya2Zsb3dBUElFcnJvcic7XG4gICAgdGhpcy5zdGF0dXMgPSBvcHRpb25zPy5zdGF0dXM7XG4gICAgdGhpcy5jb2RlID0gb3B0aW9ucz8uY29kZTtcbiAgICB0aGlzLnVybCA9IG9wdGlvbnM/LnVybDtcbiAgfVxuXG4gIHN0YXRpYyBpcyh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIFdvcmtmbG93QVBJRXJyb3Ige1xuICAgIHJldHVybiBpc0Vycm9yKHZhbHVlKSAmJiB2YWx1ZS5uYW1lID09PSAnV29ya2Zsb3dBUElFcnJvcic7XG4gIH1cbn1cblxuLyoqXG4gKiBUaHJvd24gd2hlbiBhIHdvcmtmbG93IHJ1biBmYWlscyBkdXJpbmcgZXhlY3V0aW9uLlxuICpcbiAqIFRoaXMgZXJyb3IgaW5kaWNhdGVzIHRoYXQgdGhlIHdvcmtmbG93IGVuY291bnRlcmVkIGEgZmF0YWwgZXJyb3JcbiAqIGFuZCBjYW5ub3QgY29udGludWUuIFRoZSBgY2F1c2VgIHByb3BlcnR5IGNvbnRhaW5zIHRoZSB1bmRlcmx5aW5nXG4gKiBlcnJvciB3aXRoIGl0cyBtZXNzYWdlLCBzdGFjayB0cmFjZSwgYW5kIG9wdGlvbmFsIGVycm9yIGNvZGUuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYFxuICogY29uc3QgcnVuID0gYXdhaXQgZ2V0UnVuKHJ1bklkKTtcbiAqIGlmIChydW4uc3RhdHVzID09PSAnZmFpbGVkJykge1xuICogICAvLyBXb3JrZmxvd1J1bkZhaWxlZEVycm9yIHdpbGwgYmUgdGhyb3duXG4gKiB9XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNsYXNzIFdvcmtmbG93UnVuRmFpbGVkRXJyb3IgZXh0ZW5kcyBXb3JrZmxvd0Vycm9yIHtcbiAgcnVuSWQ6IHN0cmluZztcbiAgZGVjbGFyZSBjYXVzZTogRXJyb3IgJiB7IGNvZGU/OiBzdHJpbmcgfTtcblxuICBjb25zdHJ1Y3RvcihydW5JZDogc3RyaW5nLCBlcnJvcjogU3RydWN0dXJlZEVycm9yKSB7XG4gICAgLy8gQ3JlYXRlIGEgcHJvcGVyIEVycm9yIGluc3RhbmNlIGZyb20gdGhlIFN0cnVjdHVyZWRFcnJvciB0byBzZXQgYXMgY2F1c2VcbiAgICAvLyBOT1RFOiBjdXN0b20gZXJyb3IgdHlwZXMgZG8gbm90IGdldCBzZXJpYWxpemVkL2Rlc2VyaWFsaXplZC4gRXZlcnl0aGluZyBpcyBhbiBFcnJvclxuICAgIGNvbnN0IGNhdXNlRXJyb3IgPSBuZXcgRXJyb3IoZXJyb3IubWVzc2FnZSk7XG4gICAgaWYgKGVycm9yLnN0YWNrKSB7XG4gICAgICBjYXVzZUVycm9yLnN0YWNrID0gZXJyb3Iuc3RhY2s7XG4gICAgfVxuICAgIGlmIChlcnJvci5jb2RlKSB7XG4gICAgICAoY2F1c2VFcnJvciBhcyBhbnkpLmNvZGUgPSBlcnJvci5jb2RlO1xuICAgIH1cblxuICAgIHN1cGVyKGBXb3JrZmxvdyBydW4gXCIke3J1bklkfVwiIGZhaWxlZDogJHtlcnJvci5tZXNzYWdlfWAsIHtcbiAgICAgIGNhdXNlOiBjYXVzZUVycm9yLFxuICAgIH0pO1xuICAgIHRoaXMubmFtZSA9ICdXb3JrZmxvd1J1bkZhaWxlZEVycm9yJztcbiAgICB0aGlzLnJ1bklkID0gcnVuSWQ7XG4gIH1cblxuICBzdGF0aWMgaXModmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBXb3JrZmxvd1J1bkZhaWxlZEVycm9yIHtcbiAgICByZXR1cm4gaXNFcnJvcih2YWx1ZSkgJiYgdmFsdWUubmFtZSA9PT0gJ1dvcmtmbG93UnVuRmFpbGVkRXJyb3InO1xuICB9XG59XG5cbi8qKlxuICogVGhyb3duIHdoZW4gYXR0ZW1wdGluZyB0byBnZXQgcmVzdWx0cyBmcm9tIGFuIGluY29tcGxldGUgd29ya2Zsb3cgcnVuLlxuICpcbiAqIFRoaXMgZXJyb3Igb2NjdXJzIHdoZW4geW91IHRyeSB0byBhY2Nlc3MgdGhlIHJlc3VsdCBvZiBhIHdvcmtmbG93XG4gKiB0aGF0IGlzIHN0aWxsIHJ1bm5pbmcgb3IgaGFzbid0IGNvbXBsZXRlZCB5ZXQuXG4gKi9cbmV4cG9ydCBjbGFzcyBXb3JrZmxvd1J1bk5vdENvbXBsZXRlZEVycm9yIGV4dGVuZHMgV29ya2Zsb3dFcnJvciB7XG4gIHJ1bklkOiBzdHJpbmc7XG4gIHN0YXR1czogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHJ1bklkOiBzdHJpbmcsIHN0YXR1czogc3RyaW5nKSB7XG4gICAgc3VwZXIoYFdvcmtmbG93IHJ1biBcIiR7cnVuSWR9XCIgaGFzIG5vdCBjb21wbGV0ZWRgLCB7fSk7XG4gICAgdGhpcy5uYW1lID0gJ1dvcmtmbG93UnVuTm90Q29tcGxldGVkRXJyb3InO1xuICAgIHRoaXMucnVuSWQgPSBydW5JZDtcbiAgICB0aGlzLnN0YXR1cyA9IHN0YXR1cztcbiAgfVxuXG4gIHN0YXRpYyBpcyh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIFdvcmtmbG93UnVuTm90Q29tcGxldGVkRXJyb3Ige1xuICAgIHJldHVybiBpc0Vycm9yKHZhbHVlKSAmJiB2YWx1ZS5uYW1lID09PSAnV29ya2Zsb3dSdW5Ob3RDb21wbGV0ZWRFcnJvcic7XG4gIH1cbn1cblxuLyoqXG4gKiBUaHJvd24gd2hlbiB0aGUgV29ya2Zsb3cgcnVudGltZSBlbmNvdW50ZXJzIGFuIGludGVybmFsIGVycm9yLlxuICpcbiAqIFRoaXMgZXJyb3IgaW5kaWNhdGVzIGFuIGlzc3VlIHdpdGggd29ya2Zsb3cgZXhlY3V0aW9uLCBzdWNoIGFzXG4gKiBzZXJpYWxpemF0aW9uIGZhaWx1cmVzLCBzdGFydGluZyBhbiBpbnZhbGlkIHdvcmtmbG93IGZ1bmN0aW9uLCBvclxuICogb3RoZXIgcnVudGltZSBwcm9ibGVtcy5cbiAqL1xuZXhwb3J0IGNsYXNzIFdvcmtmbG93UnVudGltZUVycm9yIGV4dGVuZHMgV29ya2Zsb3dFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZywgb3B0aW9ucz86IFdvcmtmbG93RXJyb3JPcHRpb25zKSB7XG4gICAgc3VwZXIobWVzc2FnZSwge1xuICAgICAgLi4ub3B0aW9ucyxcbiAgICB9KTtcbiAgICB0aGlzLm5hbWUgPSAnV29ya2Zsb3dSdW50aW1lRXJyb3InO1xuICB9XG5cbiAgc3RhdGljIGlzKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgV29ya2Zsb3dSdW50aW1lRXJyb3Ige1xuICAgIHJldHVybiBpc0Vycm9yKHZhbHVlKSAmJiB2YWx1ZS5uYW1lID09PSAnV29ya2Zsb3dSdW50aW1lRXJyb3InO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBXb3JrZmxvd1J1bk5vdEZvdW5kRXJyb3IgZXh0ZW5kcyBXb3JrZmxvd0Vycm9yIHtcbiAgcnVuSWQ6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihydW5JZDogc3RyaW5nKSB7XG4gICAgc3VwZXIoYFdvcmtmbG93IHJ1biBcIiR7cnVuSWR9XCIgbm90IGZvdW5kYCwge30pO1xuICAgIHRoaXMubmFtZSA9ICdXb3JrZmxvd1J1bk5vdEZvdW5kRXJyb3InO1xuICAgIHRoaXMucnVuSWQgPSBydW5JZDtcbiAgfVxuXG4gIHN0YXRpYyBpcyh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIFdvcmtmbG93UnVuTm90Rm91bmRFcnJvciB7XG4gICAgcmV0dXJuIGlzRXJyb3IodmFsdWUpICYmIHZhbHVlLm5hbWUgPT09ICdXb3JrZmxvd1J1bk5vdEZvdW5kRXJyb3InO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBXb3JrZmxvd1J1bkNhbmNlbGxlZEVycm9yIGV4dGVuZHMgV29ya2Zsb3dFcnJvciB7XG4gIHJ1bklkOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IocnVuSWQ6IHN0cmluZykge1xuICAgIHN1cGVyKGBXb3JrZmxvdyBydW4gXCIke3J1bklkfVwiIGNhbmNlbGxlZGAsIHt9KTtcbiAgICB0aGlzLm5hbWUgPSAnV29ya2Zsb3dSdW5DYW5jZWxsZWRFcnJvcic7XG4gICAgdGhpcy5ydW5JZCA9IHJ1bklkO1xuICB9XG5cbiAgc3RhdGljIGlzKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgV29ya2Zsb3dSdW5DYW5jZWxsZWRFcnJvciB7XG4gICAgcmV0dXJuIGlzRXJyb3IodmFsdWUpICYmIHZhbHVlLm5hbWUgPT09ICdXb3JrZmxvd1J1bkNhbmNlbGxlZEVycm9yJztcbiAgfVxufVxuXG4vKipcbiAqIEEgZmF0YWwgZXJyb3IgaXMgYW4gZXJyb3IgdGhhdCBjYW5ub3QgYmUgcmV0cmllZC5cbiAqIEl0IHdpbGwgY2F1c2UgdGhlIHN0ZXAgdG8gZmFpbCBhbmQgdGhlIGVycm9yIHdpbGxcbiAqIGJlIGJ1YmJsZWQgdXAgdG8gdGhlIHdvcmtmbG93IGxvZ2ljLlxuICovXG5leHBvcnQgY2xhc3MgRmF0YWxFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgZmF0YWwgPSB0cnVlO1xuXG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZykge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIHRoaXMubmFtZSA9ICdGYXRhbEVycm9yJztcbiAgfVxuXG4gIHN0YXRpYyBpcyh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIEZhdGFsRXJyb3Ige1xuICAgIHJldHVybiBpc0Vycm9yKHZhbHVlKSAmJiB2YWx1ZS5uYW1lID09PSAnRmF0YWxFcnJvcic7XG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZXRyeWFibGVFcnJvck9wdGlvbnMge1xuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgdG8gd2FpdCBiZWZvcmUgcmV0cnlpbmcgdGhlIHN0ZXAuXG4gICAqIENhbiBhbHNvIGJlIGEgZHVyYXRpb24gc3RyaW5nIChlLmcuLCBcIjVzXCIsIFwiMm1cIikgb3IgYSBEYXRlIG9iamVjdC5cbiAgICogSWYgbm90IHByb3ZpZGVkLCB0aGUgc3RlcCB3aWxsIGJlIHJldHJpZWQgYWZ0ZXIgMSBzZWNvbmQgKDEwMDAgbWlsbGlzZWNvbmRzKS5cbiAgICovXG4gIHJldHJ5QWZ0ZXI/OiBudW1iZXIgfCBTdHJpbmdWYWx1ZSB8IERhdGU7XG59XG5cbi8qKlxuICogQW4gZXJyb3IgdGhhdCBjYW4gaGFwcGVuIGR1cmluZyBhIHN0ZXAgZXhlY3V0aW9uLCBhbGxvd2luZ1xuICogZm9yIGNvbmZpZ3VyYXRpb24gb2YgdGhlIHJldHJ5IGJlaGF2aW9yLlxuICovXG5leHBvcnQgY2xhc3MgUmV0cnlhYmxlRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIC8qKlxuICAgKiBUaGUgRGF0ZSB3aGVuIHRoZSBzdGVwIHNob3VsZCBiZSByZXRyaWVkLlxuICAgKi9cbiAgcmV0cnlBZnRlcjogRGF0ZTtcblxuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcsIG9wdGlvbnM6IFJldHJ5YWJsZUVycm9yT3B0aW9ucyA9IHt9KSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gICAgdGhpcy5uYW1lID0gJ1JldHJ5YWJsZUVycm9yJztcblxuICAgIGlmIChvcHRpb25zLnJldHJ5QWZ0ZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5yZXRyeUFmdGVyID0gcGFyc2VEdXJhdGlvblRvRGF0ZShvcHRpb25zLnJldHJ5QWZ0ZXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBEZWZhdWx0IHRvIDEgc2Vjb25kICgxMDAwIG1pbGxpc2Vjb25kcylcbiAgICAgIHRoaXMucmV0cnlBZnRlciA9IG5ldyBEYXRlKERhdGUubm93KCkgKyAxMDAwKTtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgaXModmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBSZXRyeWFibGVFcnJvciB7XG4gICAgcmV0dXJuIGlzRXJyb3IodmFsdWUpICYmIHZhbHVlLm5hbWUgPT09ICdSZXRyeWFibGVFcnJvcic7XG4gIH1cbn1cbiIsICJleHBvcnQgY29uc3QgV09SS0ZMT1dfVVNFX1NURVAgPSBTeW1ib2wuZm9yKCdXT1JLRkxPV19VU0VfU1RFUCcpO1xuZXhwb3J0IGNvbnN0IFdPUktGTE9XX0NSRUFURV9IT09LID0gU3ltYm9sLmZvcignV09SS0ZMT1dfQ1JFQVRFX0hPT0snKTtcbmV4cG9ydCBjb25zdCBXT1JLRkxPV19TTEVFUCA9IFN5bWJvbC5mb3IoJ1dPUktGTE9XX1NMRUVQJyk7XG5leHBvcnQgY29uc3QgV09SS0ZMT1dfQ09OVEVYVCA9IFN5bWJvbC5mb3IoJ1dPUktGTE9XX0NPTlRFWFQnKTtcbmV4cG9ydCBjb25zdCBXT1JLRkxPV19HRVRfU1RSRUFNX0lEID0gU3ltYm9sLmZvcignV09SS0ZMT1dfR0VUX1NUUkVBTV9JRCcpO1xuZXhwb3J0IGNvbnN0IFNUUkVBTV9OQU1FX1NZTUJPTCA9IFN5bWJvbC5mb3IoJ1dPUktGTE9XX1NUUkVBTV9OQU1FJyk7XG5leHBvcnQgY29uc3QgU1RSRUFNX1RZUEVfU1lNQk9MID0gU3ltYm9sLmZvcignV09SS0ZMT1dfU1RSRUFNX1RZUEUnKTtcbmV4cG9ydCBjb25zdCBCT0RZX0lOSVRfU1lNQk9MID0gU3ltYm9sLmZvcignQk9EWV9JTklUJyk7XG5leHBvcnQgY29uc3QgV0VCSE9PS19SRVNQT05TRV9XUklUQUJMRSA9IFN5bWJvbC5mb3IoXG4gICdXRUJIT09LX1JFU1BPTlNFX1dSSVRBQkxFJ1xuKTtcbmV4cG9ydCBjb25zdCBTVEVQX0ZVTkNUSU9OX05BTUVfU1lNQk9MID0gU3ltYm9sLmZvcihcbiAgJ1dPUktGTE9XX1NURVBfRlVOQ1RJT05fTkFNRSdcbik7XG4iLCAiZXhwb3J0IGludGVyZmFjZSBXb3JrZmxvd01ldGFkYXRhIHtcbiAgLyoqXG4gICAqIFVuaXF1ZSBpZGVudGlmaWVyIGZvciB0aGUgd29ya2Zsb3cgcnVuLlxuICAgKi9cbiAgd29ya2Zsb3dSdW5JZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaW1lc3RhbXAgd2hlbiB0aGUgd29ya2Zsb3cgcnVuIHN0YXJ0ZWQuXG4gICAqL1xuICB3b3JrZmxvd1N0YXJ0ZWRBdDogRGF0ZTtcblxuICAvKipcbiAgICogVGhlIFVSTCB3aGVyZSB0aGUgd29ya2Zsb3cgY2FuIGJlIHRyaWdnZXJlZC5cbiAgICovXG4gIHVybDogc3RyaW5nO1xufVxuXG5leHBvcnQgY29uc3QgV09SS0ZMT1dfQ09OVEVYVF9TWU1CT0wgPVxuICAvKiBAX19QVVJFX18gKi8gU3ltYm9sLmZvcignV09SS0ZMT1dfQ09OVEVYVCcpO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0V29ya2Zsb3dNZXRhZGF0YSgpOiBXb3JrZmxvd01ldGFkYXRhIHtcbiAgLy8gSW5zaWRlIHRoZSB3b3JrZmxvdyBWTSwgdGhlIGNvbnRleHQgaXMgc3RvcmVkIGluIHRoZSBnbG9iYWxUaGlzIG9iamVjdCBiZWhpbmQgYSBzeW1ib2xcbiAgY29uc3QgY3R4ID0gKGdsb2JhbFRoaXMgYXMgYW55KVtXT1JLRkxPV19DT05URVhUX1NZTUJPTF0gYXMgV29ya2Zsb3dNZXRhZGF0YTtcbiAgaWYgKCFjdHgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnYGdldFdvcmtmbG93TWV0YWRhdGEoKWAgY2FuIG9ubHkgYmUgY2FsbGVkIGluc2lkZSBhIHdvcmtmbG93IG9yIHN0ZXAgZnVuY3Rpb24nXG4gICAgKTtcbiAgfVxuICByZXR1cm4gY3R4O1xufVxuIiwgImltcG9ydCB0eXBlIHtcbiAgSG9vayxcbiAgSG9va09wdGlvbnMsXG4gIFJlcXVlc3RXaXRoUmVzcG9uc2UsXG4gIFdlYmhvb2ssXG4gIFdlYmhvb2tPcHRpb25zLFxufSBmcm9tICcuLi9jcmVhdGUtaG9vay5qcyc7XG5pbXBvcnQgeyBXT1JLRkxPV19DUkVBVEVfSE9PSyB9IGZyb20gJy4uL3N5bWJvbHMuanMnO1xuaW1wb3J0IHsgZ2V0V29ya2Zsb3dNZXRhZGF0YSB9IGZyb20gJy4vZ2V0LXdvcmtmbG93LW1ldGFkYXRhLmpzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUhvb2s8VCA9IGFueT4ob3B0aW9ucz86IEhvb2tPcHRpb25zKTogSG9vazxUPiB7XG4gIC8vIEluc2lkZSB0aGUgd29ya2Zsb3cgVk0sIHRoZSBob29rIGZ1bmN0aW9uIGlzIHN0b3JlZCBpbiB0aGUgZ2xvYmFsVGhpcyBvYmplY3QgYmVoaW5kIGEgc3ltYm9sXG4gIGNvbnN0IGNyZWF0ZUhvb2tGbiA9IChnbG9iYWxUaGlzIGFzIGFueSlbXG4gICAgV09SS0ZMT1dfQ1JFQVRFX0hPT0tcbiAgXSBhcyB0eXBlb2YgY3JlYXRlSG9vazxUPjtcbiAgaWYgKCFjcmVhdGVIb29rRm4pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnYGNyZWF0ZUhvb2soKWAgY2FuIG9ubHkgYmUgY2FsbGVkIGluc2lkZSBhIHdvcmtmbG93IGZ1bmN0aW9uJ1xuICAgICk7XG4gIH1cbiAgcmV0dXJuIGNyZWF0ZUhvb2tGbihvcHRpb25zKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVdlYmhvb2soXG4gIG9wdGlvbnM6IFdlYmhvb2tPcHRpb25zICYgeyByZXNwb25kV2l0aDogJ21hbnVhbCcgfVxuKTogV2ViaG9vazxSZXF1ZXN0V2l0aFJlc3BvbnNlPjtcbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVXZWJob29rKG9wdGlvbnM/OiBXZWJob29rT3B0aW9ucyk6IFdlYmhvb2s8UmVxdWVzdD47XG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlV2ViaG9vayhcbiAgb3B0aW9ucz86IFdlYmhvb2tPcHRpb25zXG4pOiBXZWJob29rPFJlcXVlc3Q+IHwgV2ViaG9vazxSZXF1ZXN0V2l0aFJlc3BvbnNlPiB7XG4gIGNvbnN0IHsgcmVzcG9uZFdpdGgsIC4uLnJlc3QgfSA9IG9wdGlvbnMgPz8ge307XG4gIGxldCBtZXRhZGF0YTogUGljazxXZWJob29rT3B0aW9ucywgJ3Jlc3BvbmRXaXRoJz4gfCB1bmRlZmluZWQ7XG4gIGlmICh0eXBlb2YgcmVzcG9uZFdpdGggIT09ICd1bmRlZmluZWQnKSB7XG4gICAgbWV0YWRhdGEgPSB7IHJlc3BvbmRXaXRoIH07XG4gIH1cblxuICBjb25zdCBob29rID0gY3JlYXRlSG9vayh7IC4uLnJlc3QsIG1ldGFkYXRhIH0pIGFzXG4gICAgfCBXZWJob29rPFJlcXVlc3Q+XG4gICAgfCBXZWJob29rPFJlcXVlc3RXaXRoUmVzcG9uc2U+O1xuXG4gIGNvbnN0IHsgdXJsIH0gPSBnZXRXb3JrZmxvd01ldGFkYXRhKCk7XG4gIGhvb2sudXJsID0gYCR7dXJsfS8ud2VsbC1rbm93bi93b3JrZmxvdy92MS93ZWJob29rLyR7ZW5jb2RlVVJJQ29tcG9uZW50KGhvb2sudG9rZW4pfWA7XG5cbiAgcmV0dXJuIGhvb2s7XG59XG4iLCAiaW1wb3J0IHR5cGUgeyBTdHJpbmdWYWx1ZSB9IGZyb20gJ21zJztcbmltcG9ydCB7IFdPUktGTE9XX1NMRUVQIH0gZnJvbSAnLi9zeW1ib2xzLmpzJztcblxuLyoqXG4gKiBTbGVlcCB3aXRoaW4gYSB3b3JrZmxvdyBmb3IgYSBnaXZlbiBkdXJhdGlvbi5cbiAqXG4gKiBUaGlzIGlzIGEgYnVpbHQtaW4gcnVudGltZSBmdW5jdGlvbiB0aGF0IHVzZXMgdGltZXIgZXZlbnRzIGluIHRoZSBldmVudCBsb2cuXG4gKlxuICogQHBhcmFtIGR1cmF0aW9uIC0gVGhlIGR1cmF0aW9uIHRvIHNsZWVwIGZvciwgdGhpcyBpcyBhIHN0cmluZyBpbiB0aGUgZm9ybWF0XG4gKiBvZiBgXCIxMDAwbXNcImAsIGBcIjFzXCJgLCBgXCIxbVwiYCwgYFwiMWhcImAsIG9yIGBcIjFkXCJgLlxuICogQG92ZXJsb2FkXG4gKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBzbGVlcCBpcyBjb21wbGV0ZS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNsZWVwKGR1cmF0aW9uOiBTdHJpbmdWYWx1ZSk6IFByb21pc2U8dm9pZD47XG5cbi8qKlxuICogU2xlZXAgd2l0aGluIGEgd29ya2Zsb3cgdW50aWwgYSBzcGVjaWZpYyBkYXRlLlxuICpcbiAqIFRoaXMgaXMgYSBidWlsdC1pbiBydW50aW1lIGZ1bmN0aW9uIHRoYXQgdXNlcyB0aW1lciBldmVudHMgaW4gdGhlIGV2ZW50IGxvZy5cbiAqXG4gKiBAcGFyYW0gZGF0ZSAtIFRoZSBkYXRlIHRvIHNsZWVwIHVudGlsLCB0aGlzIG11c3QgYmUgYSBmdXR1cmUgZGF0ZS5cbiAqIEBvdmVybG9hZFxuICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgc2xlZXAgaXMgY29tcGxldGUuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzbGVlcChkYXRlOiBEYXRlKTogUHJvbWlzZTx2b2lkPjtcblxuLyoqXG4gKiBTbGVlcCB3aXRoaW4gYSB3b3JrZmxvdyBmb3IgYSBnaXZlbiBkdXJhdGlvbiBpbiBtaWxsaXNlY29uZHMuXG4gKlxuICogVGhpcyBpcyBhIGJ1aWx0LWluIHJ1bnRpbWUgZnVuY3Rpb24gdGhhdCB1c2VzIHRpbWVyIGV2ZW50cyBpbiB0aGUgZXZlbnQgbG9nLlxuICpcbiAqIEBwYXJhbSBkdXJhdGlvbk1zIC0gVGhlIGR1cmF0aW9uIHRvIHNsZWVwIGZvciBpbiBtaWxsaXNlY29uZHMuXG4gKiBAb3ZlcmxvYWRcbiAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIHNsZWVwIGlzIGNvbXBsZXRlLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc2xlZXAoZHVyYXRpb25NczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPjtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNsZWVwKHBhcmFtOiBTdHJpbmdWYWx1ZSB8IERhdGUgfCBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgLy8gSW5zaWRlIHRoZSB3b3JrZmxvdyBWTSwgdGhlIHNsZWVwIGZ1bmN0aW9uIGlzIHN0b3JlZCBpbiB0aGUgZ2xvYmFsVGhpcyBvYmplY3QgYmVoaW5kIGEgc3ltYm9sXG4gIGNvbnN0IHNsZWVwRm4gPSAoZ2xvYmFsVGhpcyBhcyBhbnkpW1dPUktGTE9XX1NMRUVQXTtcbiAgaWYgKCFzbGVlcEZuKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdgc2xlZXAoKWAgY2FuIG9ubHkgYmUgY2FsbGVkIGluc2lkZSBhIHdvcmtmbG93IGZ1bmN0aW9uJyk7XG4gIH1cbiAgcmV0dXJuIHNsZWVwRm4ocGFyYW0pO1xufVxuIiwgImltcG9ydCB7IFNUUkVBTV9OQU1FX1NZTUJPTCwgV09SS0ZMT1dfR0VUX1NUUkVBTV9JRCB9IGZyb20gJy4uL3N5bWJvbHMuanMnO1xuaW1wb3J0IHR5cGUgeyBXb3JrZmxvd1dyaXRhYmxlU3RyZWFtT3B0aW9ucyB9IGZyb20gJy4uL3dyaXRhYmxlLXN0cmVhbS5qcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRXcml0YWJsZTxXID0gYW55PihcbiAgb3B0aW9uczogV29ya2Zsb3dXcml0YWJsZVN0cmVhbU9wdGlvbnMgPSB7fVxuKTogV3JpdGFibGVTdHJlYW08Vz4ge1xuICBjb25zdCB7IG5hbWVzcGFjZSB9ID0gb3B0aW9ucztcbiAgY29uc3QgbmFtZSA9IChnbG9iYWxUaGlzIGFzIGFueSlbV09SS0ZMT1dfR0VUX1NUUkVBTV9JRF0obmFtZXNwYWNlKTtcbiAgcmV0dXJuIE9iamVjdC5jcmVhdGUoZ2xvYmFsVGhpcy5Xcml0YWJsZVN0cmVhbS5wcm90b3R5cGUsIHtcbiAgICBbU1RSRUFNX05BTUVfU1lNQk9MXToge1xuICAgICAgdmFsdWU6IG5hbWUsXG4gICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgfSxcbiAgfSk7XG59XG4iLCAiLyoqXG4gKiBUaGlzIGlzIHRoZSBcInN0YW5kYXJkIGxpYnJhcnlcIiBvZiBzdGVwcyB0aGF0IHdlIG1ha2UgYXZhaWxhYmxlIHRvIGFsbCB3b3JrZmxvdyB1c2Vycy5cbiAqIFRoZSBjYW4gYmUgaW1wb3J0ZWQgbGlrZSBzbzogYGltcG9ydCB7IGZldGNoIH0gZnJvbSAnd29ya2Zsb3cnYC4gYW5kIHVzZWQgaW4gd29ya2Zsb3cuXG4gKiBUaGUgbmVlZCB0byBiZSBleHBvcnRlZCBkaXJlY3RseSBpbiB0aGlzIHBhY2thZ2UgYW5kIGNhbm5vdCBsaXZlIGluIGBjb3JlYCB0byBwcmV2ZW50XG4gKiBjaXJjdWxhciBkZXBlbmRlbmNpZXMgcG9zdC1jb21waWxhdGlvbi5cbiAqL1xuXG4vKipcbiAqIEEgaG9pc3RlZCBgZmV0Y2goKWAgZnVuY3Rpb24gdGhhdCBpcyBleGVjdXRlZCBhcyBhIFwic3RlcFwiIGZ1bmN0aW9uLFxuICogZm9yIHVzZSB3aXRoaW4gd29ya2Zsb3cgZnVuY3Rpb25zLlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0ZldGNoX0FQSVxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZmV0Y2goLi4uYXJnczogUGFyYW1ldGVyczx0eXBlb2YgZ2xvYmFsVGhpcy5mZXRjaD4pIHtcbiAgJ3VzZSBzdGVwJztcbiAgcmV0dXJuIGdsb2JhbFRoaXMuZmV0Y2goLi4uYXJncyk7XG59XG4iLCAiLy8gU2hhcmVkIGhlbHBlciBmdW5jdGlvbnMgdGhhdCBjYW4gYmUgaW1wb3J0ZWQgYnkgd29ya2Zsb3dzXG5leHBvcnQgZnVuY3Rpb24gdGhyb3dFcnJvcigpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0Vycm9yIGZyb20gaW1wb3J0ZWQgaGVscGVyIG1vZHVsZScpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGNhbGxUaHJvd2VyKCkge1xuICAgIHRocm93RXJyb3IoKTtcbn1cbiIsICIvKipfX2ludGVybmFsX3dvcmtmbG93c3tcIndvcmtmbG93c1wiOntcImV4YW1wbGUvd29ya2Zsb3dzLzJfY29udHJvbF9mbG93LnRzXCI6e1wiY29udHJvbF9mbG93XCI6e1wid29ya2Zsb3dJZFwiOlwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzJfY29udHJvbF9mbG93LnRzLy9jb250cm9sX2Zsb3dcIn19fSxcInN0ZXBzXCI6e1wiZXhhbXBsZS93b3JrZmxvd3MvMl9jb250cm9sX2Zsb3cudHNcIjp7XCJhZGRcIjp7XCJzdGVwSWRcIjpcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzJfY29udHJvbF9mbG93LnRzLy9hZGRcIn0sXCJkZWxheWVkTWVzc2FnZVwiOntcInN0ZXBJZFwiOlwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvMl9jb250cm9sX2Zsb3cudHMvL2RlbGF5ZWRNZXNzYWdlXCJ9LFwiZmFpbGluZ1N0ZXBcIjp7XCJzdGVwSWRcIjpcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzJfY29udHJvbF9mbG93LnRzLy9mYWlsaW5nU3RlcFwifSxcInJldHJ5YWJsZVN0ZXBcIjp7XCJzdGVwSWRcIjpcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzJfY29udHJvbF9mbG93LnRzLy9yZXRyeWFibGVTdGVwXCJ9fX19Ki87XG5hc3luYyBmdW5jdGlvbiBkZWxheWVkTWVzc2FnZShtcywgbWVzc2FnZSkge1xuICAgIHJldHVybiBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19VU0VfU1RFUFwiKV0oXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy8yX2NvbnRyb2xfZmxvdy50cy8vZGVsYXllZE1lc3NhZ2VcIikobXMsIG1lc3NhZ2UpO1xufVxuYXN5bmMgZnVuY3Rpb24gYWRkKGEsIGIpIHtcbiAgICByZXR1cm4gZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildKFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvMl9jb250cm9sX2Zsb3cudHMvL2FkZFwiKShhLCBiKTtcbn1cbmFzeW5jIGZ1bmN0aW9uIGZhaWxpbmdTdGVwKCkge1xuICAgIHJldHVybiBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19VU0VfU1RFUFwiKV0oXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy8yX2NvbnRyb2xfZmxvdy50cy8vZmFpbGluZ1N0ZXBcIikoKTtcbn1cbmFzeW5jIGZ1bmN0aW9uIHJldHJ5YWJsZVN0ZXAoKSB7XG4gICAgcmV0dXJuIGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1VTRV9TVEVQXCIpXShcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzJfY29udHJvbF9mbG93LnRzLy9yZXRyeWFibGVTdGVwXCIpKCk7XG59XG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY29udHJvbF9mbG93KCkge1xuICAgIGNvbnNvbGUubG9nKCdDb250cm9sIGZsb3cgd29ya2Zsb3cgc3RhcnRlZCcpO1xuICAgIC8vIERlbW8gUHJvbWlzZS5yYWNlXG4gICAgY29uc3QgcmFjZVJlc3VsdCA9IGF3YWl0IFByb21pc2UucmFjZShbXG4gICAgICAgIGRlbGF5ZWRNZXNzYWdlKDIwMDAsICdJIHdvbiB0aGUgcmFjZSEnKSxcbiAgICAgICAgZGVsYXllZE1lc3NhZ2UoMTAwMDAsICdJIGxvc3QgdGhlIHJhY2UnKVxuICAgIF0pO1xuICAgIGNvbnNvbGUubG9nKCdSYWNlIHJlc3VsdDonLCByYWNlUmVzdWx0KTtcbiAgICAvLyBEZW1vIFByb21pc2UuYWxsXG4gICAgY29uc3QgYWxsUmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgZGVsYXllZE1lc3NhZ2UoMTAwMCwgJ0ZpcnN0IHRhc2snKSxcbiAgICAgICAgZGVsYXllZE1lc3NhZ2UoMjAwMCwgJ1NlY29uZCB0YXNrJyksXG4gICAgICAgIGFkZCgxMCwgMjApXG4gICAgXSk7XG4gICAgY29uc29sZS5sb2coJ0FsbCByZXN1bHRzOicsIGFsbFJlc3VsdHMpO1xuICAgIC8vIEtpY2sgb2ZmIGEgc3RlcCBub3csIGFuZCByZXNvbHZlIGl0IGxhdGVyXG4gICAgY29uc3QgYmFja2dyb3VuZFByb21pc2UgPSBkZWxheWVkTWVzc2FnZSg1MDAwLCAnQmFja2dyb3VuZCB0YXNrIGNvbXBsZXRlZCcpO1xuICAgIGNvbnN0IGZvcmVncm91bmRSZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICBkZWxheWVkTWVzc2FnZSgxMDAwLCAnRmlyc3QgdGFzaycpLFxuICAgICAgICBkZWxheWVkTWVzc2FnZSgyMDAwLCAnU2Vjb25kIHRhc2snKVxuICAgIF0pO1xuICAgIGNvbnNvbGUubG9nKCdGb3JlZ3JvdW5kIHJlc3BvbnNlOicsIGZvcmVncm91bmRSZXN1bHRzKTtcbiAgICBjb25zdCBiYWNrZ3JvdW5kUmVzdWx0ID0gYXdhaXQgYmFja2dyb3VuZFByb21pc2U7XG4gICAgY29uc29sZS5sb2coJ0JhY2tncm91bmQgcmVzcG9uc2U6JywgYmFja2dyb3VuZFJlc3VsdCk7XG4gICAgLy8gRGVtbyBlcnJvciBoYW5kbGluZyAtIGNhdGNoIHJlZ3VsYXIgZXJyb3JzIGJ1dCBsZXQgRmF0YWxFcnJvcnMgYnViYmxlIHVwXG4gICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgZmFpbGluZ1N0ZXAoKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBPbmx5IEZhdGFsRXJyb3JzIHdpbGwgYnViYmxlIHVwIGhlcmUuIE5vbi1mYXRhbCBlcnJvcnMgYXJlIHJldHJpZWRcbiAgICAgICAgY29uc29sZS5sb2coJ0NhdWdodCBlcnJvcjonLCBTdHJpbmcoZXJyb3IpKTtcbiAgICB9XG4gICAgLy8gRGVtbyByZXRyeWFibGUgZXJyb3IgLSB0aGlzIHdpbGwgZmFpbCB0aGUgZmlyc3QgdGltZSxcbiAgICAvLyBhbmQgd2lsbCBiZSByZXRyaWVkIGFmdGVyIG9uZSBtaW51dGUuXG4gICAgYXdhaXQgcmV0cnlhYmxlU3RlcCgpO1xuICAgIGNvbnNvbGUubG9nKCdDb250cm9sIGZsb3cgd29ya2Zsb3cgY29tcGxldGVkLiBTZWUgbG9ncyBmb3IgcmVzdWx0cy4nKTtcbiAgICByZXR1cm4ge1xuICAgICAgICByYWNlUmVzdWx0LFxuICAgICAgICBhbGxSZXN1bHRzLFxuICAgICAgICBmb3JlZ3JvdW5kUmVzdWx0cyxcbiAgICAgICAgYmFja2dyb3VuZFJlc3VsdFxuICAgIH07XG59XG5jb250cm9sX2Zsb3cud29ya2Zsb3dJZCA9IFwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzJfY29udHJvbF9mbG93LnRzLy9jb250cm9sX2Zsb3dcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShkZWxheWVkTWVzc2FnZSwgU3ltYm9sLmZvcihcIldPUktGTE9XX1NURVBfRlVOQ1RJT05fTkFNRVwiKSwge1xuICAgIHZhbHVlOiBcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzJfY29udHJvbF9mbG93LnRzLy9kZWxheWVkTWVzc2FnZVwiLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlXG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShhZGQsIFN5bWJvbC5mb3IoXCJXT1JLRkxPV19TVEVQX0ZVTkNUSU9OX05BTUVcIiksIHtcbiAgICB2YWx1ZTogXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy8yX2NvbnRyb2xfZmxvdy50cy8vYWRkXCIsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2Vcbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGZhaWxpbmdTdGVwLCBTeW1ib2wuZm9yKFwiV09SS0ZMT1dfU1RFUF9GVU5DVElPTl9OQU1FXCIpLCB7XG4gICAgdmFsdWU6IFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvMl9jb250cm9sX2Zsb3cudHMvL2ZhaWxpbmdTdGVwXCIsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2Vcbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHJldHJ5YWJsZVN0ZXAsIFN5bWJvbC5mb3IoXCJXT1JLRkxPV19TVEVQX0ZVTkNUSU9OX05BTUVcIiksIHtcbiAgICB2YWx1ZTogXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy8yX2NvbnRyb2xfZmxvdy50cy8vcmV0cnlhYmxlU3RlcFwiLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlXG59KTtcbiIsICIvLyBpbXBvcnQgeyBGYXRhbEVycm9yIH0gZnJvbSAnd29ya2Zsb3cnO1xuLyoqX19pbnRlcm5hbF93b3JrZmxvd3N7XCJ3b3JrZmxvd3NcIjp7XCJuaXRyby12My93b3JrZmxvd3MvMF9kZW1vLnRzXCI6e1wiY2FsY1wiOntcIndvcmtmbG93SWRcIjpcIndvcmtmbG93Ly9uaXRyby12My93b3JrZmxvd3MvMF9kZW1vLnRzLy9jYWxjXCJ9fX0sXCJzdGVwc1wiOntcIm5pdHJvLXYzL3dvcmtmbG93cy8wX2RlbW8udHNcIjp7XCJwb3dcIjp7XCJzdGVwSWRcIjpcInN0ZXAvL25pdHJvLXYzL3dvcmtmbG93cy8wX2RlbW8udHMvL3Bvd1wifX19fSovO1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNhbGMobikge1xuICAgIGNvbnNvbGUubG9nKCdTaW1wbGUgd29ya2Zsb3cgc3RhcnRlZCcpO1xuICAgIG4gPSBhd2FpdCBwb3cobik7XG4gICAgY29uc29sZS5sb2coJ1NpbXBsZSB3b3JrZmxvdyBmaW5pc2hlZCcpO1xuICAgIHJldHVybiBuO1xufVxuYXN5bmMgZnVuY3Rpb24gcG93KGEpIHtcbiAgICByZXR1cm4gZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildKFwic3RlcC8vbml0cm8tdjMvd29ya2Zsb3dzLzBfZGVtby50cy8vcG93XCIpKGEpO1xufVxuY2FsYy53b3JrZmxvd0lkID0gXCJ3b3JrZmxvdy8vbml0cm8tdjMvd29ya2Zsb3dzLzBfZGVtby50cy8vY2FsY1wiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHBvdywgU3ltYm9sLmZvcihcIldPUktGTE9XX1NURVBfRlVOQ1RJT05fTkFNRVwiKSwge1xuICAgIHZhbHVlOiBcInN0ZXAvL25pdHJvLXYzL3dvcmtmbG93cy8wX2RlbW8udHMvL3Bvd1wiLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlXG59KTtcbiIsICIvLyBEdXBsaWNhdGUgd29ya2Zsb3cgZnJvbSA5OV9lMmUudHMgdG8gZW5zdXJlIHdlIGhhbmRsZSB1bmlxdWUgSURzXG4vLyBhbmQgdGhlIGZ1bmN0aW9uIGlzbid0IGRyb3BwZWQgZnJvbSBjb2xsaWRpbmcgZXhwb3J0IG5hbWVzXG4vKipfX2ludGVybmFsX3dvcmtmbG93c3tcIndvcmtmbG93c1wiOntcImV4YW1wbGUvd29ya2Zsb3dzLzk4X2R1cGxpY2F0ZV9jYXNlLnRzXCI6e1wiYWRkVGVuV29ya2Zsb3dcIjp7XCJ3b3JrZmxvd0lkXCI6XCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvOThfZHVwbGljYXRlX2Nhc2UudHMvL2FkZFRlbldvcmtmbG93XCJ9fX0sXCJzdGVwc1wiOntcImV4YW1wbGUvd29ya2Zsb3dzLzk4X2R1cGxpY2F0ZV9jYXNlLnRzXCI6e1wiYWRkXCI6e1wic3RlcElkXCI6XCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OF9kdXBsaWNhdGVfY2FzZS50cy8vYWRkXCJ9fX19Ki87XG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYWRkVGVuV29ya2Zsb3coaW5wdXQpIHtcbiAgICBjb25zdCBhID0gYXdhaXQgYWRkKGlucHV0LCAyKTtcbiAgICBjb25zdCBiID0gYXdhaXQgYWRkKGEsIDMpO1xuICAgIGNvbnN0IGMgPSBhd2FpdCBhZGQoYiwgNSk7XG4gICAgcmV0dXJuIGM7XG59XG4vLyBEdXBsaWNhdGUgc3RlcCBmcm9tIDk5X2UyZS50cyB0byBlbnN1cmUgd2UgaGFuZGxlIHVuaXF1ZSBJRHNcbi8vIGFuZCB0aGUgZnVuY3Rpb24gaXNuJ3QgZHJvcHBlZCBmcm9tIGNvbGxpZGluZyBleHBvcnQgbmFtZXNcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhZGQoYSwgYikge1xuICAgIHJldHVybiBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19VU0VfU1RFUFwiKV0oXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy85OF9kdXBsaWNhdGVfY2FzZS50cy8vYWRkXCIpKGEsIGIpO1xufVxuYWRkVGVuV29ya2Zsb3cud29ya2Zsb3dJZCA9IFwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzk4X2R1cGxpY2F0ZV9jYXNlLnRzLy9hZGRUZW5Xb3JrZmxvd1wiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGFkZCwgU3ltYm9sLmZvcihcIldPUktGTE9XX1NURVBfRlVOQ1RJT05fTkFNRVwiKSwge1xuICAgIHZhbHVlOiBcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzk4X2R1cGxpY2F0ZV9jYXNlLnRzLy9hZGRcIixcbiAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiBmYWxzZVxufSk7XG4iLCAiaW1wb3J0IGNodW5rIGZyb20gXCJsb2Rhc2guY2h1bmtcIjtcbi8qKl9faW50ZXJuYWxfd29ya2Zsb3dze1wid29ya2Zsb3dzXCI6e1wiZXhhbXBsZS93b3JrZmxvd3MvNl9iYXRjaGluZy50c1wiOntcImJhdGNoSW5TdGVwXCI6e1wid29ya2Zsb3dJZFwiOlwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzZfYmF0Y2hpbmcudHMvL2JhdGNoSW5TdGVwXCJ9LFwiYmF0Y2hPdmVyU3RlcHNcIjp7XCJ3b3JrZmxvd0lkXCI6XCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvNl9iYXRjaGluZy50cy8vYmF0Y2hPdmVyU3RlcHNcIn19fSxcInN0ZXBzXCI6e1wiZXhhbXBsZS93b3JrZmxvd3MvNl9iYXRjaGluZy50c1wiOntcImxvZ0l0ZW1cIjp7XCJzdGVwSWRcIjpcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzZfYmF0Y2hpbmcudHMvL2xvZ0l0ZW1cIn0sXCJwcm9jZXNzSXRlbXNcIjp7XCJzdGVwSWRcIjpcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzZfYmF0Y2hpbmcudHMvL3Byb2Nlc3NJdGVtc1wifX19fSovO1xuY29uc3QgQVJSQVlfTEVOR1RIID0gMjUwO1xuY29uc3QgQ0hVTktfU0laRSA9IDUwO1xuLyoqXG4gKiBQYXR0ZXJuIDE6IEVhY2ggaXRlbSBpbiBhIGJhdGNoIGdldHMgcHJvY2Vzc2VkIGluIGEgc3RlcCBmdW5jdGlvblxuICpcbiAqIElmIGEgc3RlcCBmYWlscywgZG9lc24ndCBmYWlsIHRoZSBlbnRpcmUgYmF0Y2guXG4gKi8gZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGJhdGNoT3ZlclN0ZXBzKCkge1xuICAgIGNvbnNvbGUubG9nKCdXb3JrZmxvdyBzdGFydGVkJyk7XG4gICAgY29uc3QgYXJyID0gQXJyYXkuZnJvbSh7XG4gICAgICAgIGxlbmd0aDogQVJSQVlfTEVOR1RIXG4gICAgfSwgKF8sIGkpPT5pICsgMSk7XG4gICAgY29uc3QgY2h1bmtTaXplID0gQ0hVTktfU0laRTtcbiAgICBjb25zb2xlLmxvZyhgQ2h1bmtpbmcgYXJyYXkgd2l0aCBzaXplOiAke2Fyci5sZW5ndGh9IGFuZCBjaHVuayBzaXplOiAke2NodW5rU2l6ZX1gKTtcbiAgICBjb25zdCBjaHVua3MgPSBjaHVuayhhcnIsIGNodW5rU2l6ZSk7IC8vIENyZWF0ZSB0aGUgYmF0Y2hlc1xuICAgIGNvbnNvbGUubG9nKGBDcmVhdGVkICR7Y2h1bmtzLmxlbmd0aH0gY2h1bmtzICgke2NodW5rc1swXS5sZW5ndGh9IGl0ZW1zIGVhY2gpYCk7XG4gICAgY29uc29sZS5sb2coJ1N0YXJ0aW5nIGJhdGNoIHByb2Nlc3NpbmcnKTtcbiAgICBmb3IgKGNvbnN0IFtpbmRleCwgYmF0Y2hdIG9mIGNodW5rcy5lbnRyaWVzKCkpe1xuICAgICAgICBjb25zb2xlLmxvZyhgQmF0Y2ggJHtpbmRleCArIDF9LyR7Y2h1bmtzLmxlbmd0aH1gKTtcbiAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoYmF0Y2gubWFwKGxvZ0l0ZW0pKTtcbiAgICB9XG4gICAgY29uc29sZS5sb2coJ0JhdGNoIHByb2Nlc3NpbmcgY29tcGxldGVkJyk7XG4gICAgY29uc29sZS5sb2coJ1dvcmtmbG93IGNvbXBsZXRlZCcpO1xufVxuYXN5bmMgZnVuY3Rpb24gbG9nSXRlbShpdGVtKSB7XG4gICAgcmV0dXJuIGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1VTRV9TVEVQXCIpXShcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzZfYmF0Y2hpbmcudHMvL2xvZ0l0ZW1cIikoaXRlbSk7XG59XG4vKipcbiAqIFBhdHRlcm4gMjogRWFjaCBiYXRjaCBnZXRzIHByb2Nlc3NlZCBpbiBhIHN0ZXAgZnVuY3Rpb25cbiAqXG4gKiBOT1RFOiBJZiBhIGJhdGNoIGZhaWxzLCB0aGUgZW50aXJlIGJhdGNoIHdpbGwgYmUgcmV0cmllZCBmcm9tIHRoZSBiZWdpbm5pbmcuXG4gKi8gZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGJhdGNoSW5TdGVwKCkge1xuICAgIGNvbnNvbGUubG9nKCdXb3JrZmxvdyBzdGFydGVkJyk7XG4gICAgY29uc3QgYXJyID0gQXJyYXkuZnJvbSh7XG4gICAgICAgIGxlbmd0aDogQVJSQVlfTEVOR1RIXG4gICAgfSwgKF8sIGkpPT5pICsgMSk7XG4gICAgY29uc3QgY2h1bmtTaXplID0gQ0hVTktfU0laRTtcbiAgICBjb25zb2xlLmxvZyhgQ2h1bmtpbmcgYXJyYXkgd2l0aCBzaXplOiAke2Fyci5sZW5ndGh9IGFuZCBjaHVuayBzaXplOiAke2NodW5rU2l6ZX1gKTtcbiAgICBjb25zdCBjaHVua3MgPSBjaHVuayhhcnIsIGNodW5rU2l6ZSk7IC8vIENyZWF0ZSB0aGUgYmF0Y2hlc1xuICAgIGNvbnNvbGUubG9nKGBDcmVhdGVkICR7Y2h1bmtzLmxlbmd0aH0gY2h1bmtzICgke2NodW5rc1swXS5sZW5ndGh9IGl0ZW1zIGVhY2gpYCk7XG4gICAgY29uc29sZS5sb2coJ1N0YXJ0aW5nIGJhdGNoIHByb2Nlc3NpbmcnKTtcbiAgICBmb3IgKGNvbnN0IFtpbmRleCwgYmF0Y2hdIG9mIGNodW5rcy5lbnRyaWVzKCkpe1xuICAgICAgICBjb25zb2xlLmxvZyhgQmF0Y2ggJHtpbmRleCArIDF9LyR7Y2h1bmtzLmxlbmd0aH1gKTtcbiAgICAgICAgYXdhaXQgcHJvY2Vzc0l0ZW1zKGJhdGNoKTtcbiAgICB9XG4gICAgY29uc29sZS5sb2coJ0JhdGNoIHByb2Nlc3NpbmcgY29tcGxldGVkJyk7XG4gICAgY29uc29sZS5sb2coJ1dvcmtmbG93IGNvbXBsZXRlZCcpO1xufVxuLyoqXG4gKiBTdGVwIGZ1bmN0aW9uIHRoYXQgcHJvY2Vzc2VzIGEgYmF0Y2ggb2YgaXRlbXMgd2l0aCBpbnRlcm5hbCBwYXJhbGxlbGlzbS5cbiAqIENhbGxlZCBvbmNlIHBlciBiYXRjaCwgd2l0aCBhbGwgaXRlbXMgcHJvY2Vzc2VkIGluIHBhcmFsbGVsIGluc2lkZSB0aGUgc3RlcC5cbiAqLyBhc3luYyBmdW5jdGlvbiBwcm9jZXNzSXRlbXMoaXRlbXMpIHtcbiAgICByZXR1cm4gZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildKFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvNl9iYXRjaGluZy50cy8vcHJvY2Vzc0l0ZW1zXCIpKGl0ZW1zKTtcbn1cbmJhdGNoT3ZlclN0ZXBzLndvcmtmbG93SWQgPSBcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy82X2JhdGNoaW5nLnRzLy9iYXRjaE92ZXJTdGVwc1wiO1xuYmF0Y2hJblN0ZXAud29ya2Zsb3dJZCA9IFwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzZfYmF0Y2hpbmcudHMvL2JhdGNoSW5TdGVwXCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkobG9nSXRlbSwgU3ltYm9sLmZvcihcIldPUktGTE9XX1NURVBfRlVOQ1RJT05fTkFNRVwiKSwge1xuICAgIHZhbHVlOiBcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzZfYmF0Y2hpbmcudHMvL2xvZ0l0ZW1cIixcbiAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiBmYWxzZVxufSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkocHJvY2Vzc0l0ZW1zLCBTeW1ib2wuZm9yKFwiV09SS0ZMT1dfU1RFUF9GVU5DVElPTl9OQU1FXCIpLCB7XG4gICAgdmFsdWU6IFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvNl9iYXRjaGluZy50cy8vcHJvY2Vzc0l0ZW1zXCIsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2Vcbn0pO1xuIiwgIi8qKl9faW50ZXJuYWxfd29ya2Zsb3dze1wid29ya2Zsb3dzXCI6e1wiZXhhbXBsZS93b3JrZmxvd3MvMV9zaW1wbGUudHNcIjp7XCJzaW1wbGVcIjp7XCJ3b3JrZmxvd0lkXCI6XCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvMV9zaW1wbGUudHMvL3NpbXBsZVwifX19LFwic3RlcHNcIjp7XCJleGFtcGxlL3dvcmtmbG93cy8xX3NpbXBsZS50c1wiOntcImFkZFwiOntcInN0ZXBJZFwiOlwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvMV9zaW1wbGUudHMvL2FkZFwifX19fSovO1xuYXN5bmMgZnVuY3Rpb24gYWRkKGEsIGIpIHtcbiAgICByZXR1cm4gZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildKFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvMV9zaW1wbGUudHMvL2FkZFwiKShhLCBiKTtcbn1cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzaW1wbGUoaSkge1xuICAgIGNvbnNvbGUubG9nKCdTaW1wbGUgd29ya2Zsb3cgc3RhcnRlZCcpO1xuICAgIGNvbnN0IGEgPSBhd2FpdCBhZGQoaSwgNyk7XG4gICAgY29uc29sZS5sb2coJ1dvcmtmbG93IHN0ZXAgMSBjb21wbGV0ZWQgLSBSZXN1bHQ6JywgYSk7XG4gICAgY29uc3QgYiA9IGF3YWl0IGFkZChhLCA4KTtcbiAgICBjb25zb2xlLmxvZygnU2ltcGxlIHdvcmtmbG93IGNvbXBsZXRlZC4gUmVzdWx0OicsIGIpO1xuICAgIHJldHVybiBiO1xufVxuc2ltcGxlLndvcmtmbG93SWQgPSBcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy8xX3NpbXBsZS50cy8vc2ltcGxlXCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoYWRkLCBTeW1ib2wuZm9yKFwiV09SS0ZMT1dfU1RFUF9GVU5DVElPTl9OQU1FXCIpLCB7XG4gICAgdmFsdWU6IFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvMV9zaW1wbGUudHMvL2FkZFwiLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlXG59KTtcbiIsICJpbXBvcnQgeyBjcmVhdGVIb29rLCBnZXRXb3JrZmxvd01ldGFkYXRhIH0gZnJvbSBcIndvcmtmbG93XCI7XG4vKipfX2ludGVybmFsX3dvcmtmbG93c3tcIndvcmtmbG93c1wiOntcImV4YW1wbGUvd29ya2Zsb3dzLzVfaG9va3MudHNcIjp7XCJ3aXRoQ3JlYXRlSG9va1wiOntcIndvcmtmbG93SWRcIjpcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy81X2hvb2tzLnRzLy93aXRoQ3JlYXRlSG9va1wifSxcIndpdGhXb3JrZmxvd01ldGFkYXRhXCI6e1wid29ya2Zsb3dJZFwiOlwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzVfaG9va3MudHMvL3dpdGhXb3JrZmxvd01ldGFkYXRhXCJ9fX0sXCJzdGVwc1wiOntcImV4YW1wbGUvd29ya2Zsb3dzLzVfaG9va3MudHNcIjp7XCJnZXRPcGVuQUlSZXNwb25zZVwiOntcInN0ZXBJZFwiOlwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvNV9ob29rcy50cy8vZ2V0T3BlbkFJUmVzcG9uc2VcIn0sXCJpbml0aWF0ZU9wZW5BSVJlc3BvbnNlXCI6e1wic3RlcElkXCI6XCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy81X2hvb2tzLnRzLy9pbml0aWF0ZU9wZW5BSVJlc3BvbnNlXCJ9LFwic3RlcFdpdGhHZXRNZXRhZGF0YVwiOntcInN0ZXBJZFwiOlwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvNV9ob29rcy50cy8vc3RlcFdpdGhHZXRNZXRhZGF0YVwifX19fSovO1xuLyoqXG4gKiBgZ2V0U3RlcE1ldGFkYXRhKClgIGlzIGEgaG9vayB0aGF0IGFsbG93cyB5b3UgdG8gYWNjZXNzIHRoZSBzdGVwJ3MgY29udGV4dFxuICogb2YgdGhlIGN1cnJlbnQgd29ya2Zsb3cgcnVuLlxuICpcbiAqIEl0IGlzIHVzZWZ1bCBmb3IgYWNjZXNzaW5nIHRoZSBjb250ZXh0IG9mIHRoZSBjdXJyZW50IHdvcmtmbG93IHJ1biwgc3VjaCBhc1xuICogdGhlIHdvcmtmbG93IHJ1biBJRCwgdGhlIHdvcmtmbG93IHN0YXJ0ZWQgYXQsIGFuZCB0aGUgYXR0ZW1wdCBudW1iZXIuXG4gKi8gYXN5bmMgZnVuY3Rpb24gc3RlcFdpdGhHZXRNZXRhZGF0YSgpIHtcbiAgICByZXR1cm4gZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildKFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvNV9ob29rcy50cy8vc3RlcFdpdGhHZXRNZXRhZGF0YVwiKSgpO1xufVxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdpdGhXb3JrZmxvd01ldGFkYXRhKCkge1xuICAgIGNvbnN0IGN0eCA9IGdldFdvcmtmbG93TWV0YWRhdGEoKTtcbiAgICBjb25zb2xlLmxvZygnd29ya2Zsb3cgY29udGV4dCcsIGN0eCk7XG4gICAgYXdhaXQgc3RlcFdpdGhHZXRNZXRhZGF0YSgpO1xufVxuYXN5bmMgZnVuY3Rpb24gaW5pdGlhdGVPcGVuQUlSZXNwb25zZSgpIHtcbiAgICByZXR1cm4gZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildKFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvNV9ob29rcy50cy8vaW5pdGlhdGVPcGVuQUlSZXNwb25zZVwiKSgpO1xufVxuYXN5bmMgZnVuY3Rpb24gZ2V0T3BlbkFJUmVzcG9uc2UocmVzcElkKSB7XG4gICAgcmV0dXJuIGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1VTRV9TVEVQXCIpXShcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzVfaG9va3MudHMvL2dldE9wZW5BSVJlc3BvbnNlXCIpKHJlc3BJZCk7XG59XG4vKipcbiAqIGBjcmVhdGVIb29rKClgIHJlZ2lzdGVycyBhIHRva2VuIHRoYXQgY2FuIGJlIHVzZWQgdG8gcmVzdW1lIHRoZSB3b3JrZmxvdyBydW4uXG4gKiBUaGUgdG9rZW4gY2FuIGJlIHBhc3NlZCB0byBleHRlcm5hbCBzZXJ2aWNlcyBhcyBhIGNhbGxiYWNrIFVSTCwgb3IgdXNlZFxuICogZm9yIGh1bWFuLWluLXRoZS1sb29wIHdvcmtmbG93cyBieSwgZm9yIGV4YW1wbGUsIGluY2x1ZGluZyBpbiBhbiBlbWFpbC5cbiAqXG4gKiBUaGUgd29ya2Zsb3cgcnVuIHdpbGwgYmUgc3VzcGVuZGVkIHVudGlsIHRoZSBob29rIGlzIGludm9rZWQuXG4gKi8gZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdpdGhDcmVhdGVIb29rKCkge1xuICAgIC8vIEluaXRpYXRlIGEgYmFja2dyb3VuZCBcIlJlc3BvbnNlXCIgcmVxdWVzdCB0byBPcGVuQUksXG4gICAgLy8gd2hpY2ggd2lsbCBpbnZva2UgdGhlIGhvb2sgd2hlbiBpdCdzIGRvbmUuXG4gICAgY29uc3QgcmVzcElkID0gYXdhaXQgaW5pdGlhdGVPcGVuQUlSZXNwb25zZSgpO1xuICAgIC8vIFJlZ2lzdGVyIHRoZSBob29rIHdpdGggdGhlIHRva2VuIHRoYXQgaXMgc3BlY2lmaWNcbiAgICAvLyB0byB0aGUgcmVzcG9uc2UgSUQgdGhhdCB3ZSBhcmUgaW50ZXJlc3RlZCBpbi5cbiAgICBjb25zdCBob29rID0gY3JlYXRlSG9vayh7XG4gICAgICAgIHRva2VuOiBgb3BlbmFpOiR7cmVzcElkfWBcbiAgICB9KTtcbiAgICBjb25zb2xlLmxvZygnUmVnaXN0ZXJlZCBob29rOicsIGhvb2sudG9rZW4pO1xuICAgIC8vIFdhaXQgZm9yIHRoZSBob29rIHRvIGJlIGNhbGxlZC5cbiAgICBjb25zdCBwYXlsb2FkID0gYXdhaXQgaG9vaztcbiAgICBjb25zb2xlLmxvZygnUmVjZWl2ZWQgaG9vayBwYXlsb2FkOicsIHBheWxvYWQpO1xuICAgIGlmIChwYXlsb2FkLnR5cGUgPT09ICdyZXNwb25zZS5jb21wbGV0ZWQnKSB7XG4gICAgICAgIGNvbnN0IHRleHQgPSBhd2FpdCBnZXRPcGVuQUlSZXNwb25zZShwYXlsb2FkLmRhdGEuaWQpO1xuICAgICAgICBjb25zb2xlLmxvZygnT3BlbkFJIHJlc3BvbnNlIHRleHQ6JywgdGV4dCk7XG4gICAgfVxuICAgIGNvbnNvbGUubG9nKCdIb29rIGRlbW8gd29ya2Zsb3cgY29tcGxldGVkJyk7XG59XG53aXRoV29ya2Zsb3dNZXRhZGF0YS53b3JrZmxvd0lkID0gXCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvNV9ob29rcy50cy8vd2l0aFdvcmtmbG93TWV0YWRhdGFcIjtcbndpdGhDcmVhdGVIb29rLndvcmtmbG93SWQgPSBcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy81X2hvb2tzLnRzLy93aXRoQ3JlYXRlSG9va1wiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHN0ZXBXaXRoR2V0TWV0YWRhdGEsIFN5bWJvbC5mb3IoXCJXT1JLRkxPV19TVEVQX0ZVTkNUSU9OX05BTUVcIiksIHtcbiAgICB2YWx1ZTogXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy81X2hvb2tzLnRzLy9zdGVwV2l0aEdldE1ldGFkYXRhXCIsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2Vcbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGluaXRpYXRlT3BlbkFJUmVzcG9uc2UsIFN5bWJvbC5mb3IoXCJXT1JLRkxPV19TVEVQX0ZVTkNUSU9OX05BTUVcIiksIHtcbiAgICB2YWx1ZTogXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy81X2hvb2tzLnRzLy9pbml0aWF0ZU9wZW5BSVJlc3BvbnNlXCIsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2Vcbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGdldE9wZW5BSVJlc3BvbnNlLCBTeW1ib2wuZm9yKFwiV09SS0ZMT1dfU1RFUF9GVU5DVElPTl9OQU1FXCIpLCB7XG4gICAgdmFsdWU6IFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvNV9ob29rcy50cy8vZ2V0T3BlbkFJUmVzcG9uc2VcIixcbiAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiBmYWxzZVxufSk7XG4iLCAiaW1wb3J0IHsgZ2VuZXJhdGVUZXh0LCBzdGVwQ291bnRJcyB9IGZyb20gXCJhaVwiO1xuaW1wb3J0IHogZnJvbSBcInpvZC92NFwiO1xuLyoqX19pbnRlcm5hbF93b3JrZmxvd3N7XCJ3b3JrZmxvd3NcIjp7XCJleGFtcGxlL3dvcmtmbG93cy80X2FpLnRzXCI6e1wiYWdlbnRcIjp7XCJ3b3JrZmxvd0lkXCI6XCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvNF9haS50cy8vYWdlbnRcIn0sXCJhaVwiOntcIndvcmtmbG93SWRcIjpcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy80X2FpLnRzLy9haVwifX19LFwic3RlcHNcIjp7XCJleGFtcGxlL3dvcmtmbG93cy80X2FpLnRzXCI6e1wiZ2V0V2VhdGhlckluZm9ybWF0aW9uXCI6e1wic3RlcElkXCI6XCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy80X2FpLnRzLy9nZXRXZWF0aGVySW5mb3JtYXRpb25cIn19fX0qLztcbmFzeW5jIGZ1bmN0aW9uIGdldFdlYXRoZXJJbmZvcm1hdGlvbih7IGNpdHkgfSkge1xuICAgIHJldHVybiBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19VU0VfU1RFUFwiKV0oXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy80X2FpLnRzLy9nZXRXZWF0aGVySW5mb3JtYXRpb25cIikoe1xuICAgICAgICBjaXR5XG4gICAgfSk7XG59XG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYWkocHJvbXB0KSB7XG4gICAgY29uc29sZS5sb2coJ0FJIHdvcmtmbG93IHN0YXJ0ZWQnKTtcbiAgICAvLyBBSSBTREsncyBgZ2VuZXJhdGVUZXh0YCBqdXN0IHdvcmtzIG5hdGl2ZWx5IGluIGEgd29ya2Zsb3cgdGhhbmtzIHRvXG4gICAgLy8gd29ya2Zsb3cncyBhdXRvbWF0aWMgZmV0Y2ggaG9pc3RpbmcgZnVuY3Rpb25hbGl0eVxuICAgIGNvbnN0IHsgdGV4dCB9ID0gYXdhaXQgZ2VuZXJhdGVUZXh0KHtcbiAgICAgICAgbW9kZWw6ICdvcGVuYWkvbzMnLFxuICAgICAgICBwcm9tcHRcbiAgICB9KTtcbiAgICBjb25zb2xlLmxvZyhgQUkgd29ya2Zsb3cgY29tcGxldGVkLiBSZXN1bHQ6ICR7dGV4dH1gKTtcbiAgICByZXR1cm4gdGV4dDtcbn1cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhZ2VudChwcm9tcHQpIHtcbiAgICBjb25zb2xlLmxvZygnQWdlbnQgd29ya2Zsb3cgc3RhcnRlZCcpO1xuICAgIC8vIFlvdSBjYW4gYWxzbyBwcm92aWRlIHRvb2xzLCBhbmQgaWYgdGhvc2UgdG9vbHMgYXJlIGBzdGVwc2AgLSB2b2lsYSwgeW91IGhhdmUgeW91cnNlbGZcbiAgICAvLyBhIGR1cmFibGUgYWdlbnQgd2l0aCBmZXRjaGVzIGFuZCBzdGVwcyBiZWluZyBvZmZsb2FkZWRcbiAgICBjb25zdCB7IHRleHQgfSA9IGF3YWl0IGdlbmVyYXRlVGV4dCh7XG4gICAgICAgIG1vZGVsOiAnYW50aHJvcGljL2NsYXVkZS00LW9wdXMtMjAyNTA1MTQnLFxuICAgICAgICBwcm9tcHQsXG4gICAgICAgIHRvb2xzOiB7XG4gICAgICAgICAgICBnZXRXZWF0aGVySW5mb3JtYXRpb246IHtcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogJ3Nob3cgdGhlIHdlYXRoZXIgaW4gYSBnaXZlbiBjaXR5IHRvIHRoZSB1c2VyJyxcbiAgICAgICAgICAgICAgICBpbnB1dFNjaGVtYTogei5vYmplY3Qoe1xuICAgICAgICAgICAgICAgICAgICBjaXR5OiB6LnN0cmluZygpXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgZXhlY3V0ZTogZ2V0V2VhdGhlckluZm9ybWF0aW9uXG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIC8vIFRoaXMgY2FuIGJlIGEgaGlnaCBhcyB5b3Ugd2FudCAtIG5vIHJlc3RyaWN0aW9uIG9uIHRoZSBsYW1iZGEgd29ya2Zsb3cgcnVudGltZVxuICAgICAgICBzdG9wV2hlbjogc3RlcENvdW50SXMoMTApXG4gICAgfSk7XG4gICAgY29uc29sZS5sb2coYEFnZW50IHdvcmtmbG93IGNvbXBsZXRlZC4gUmVzdWx0OiAke3RleHR9YCk7XG4gICAgcmV0dXJuIHRleHQ7XG59XG5haS53b3JrZmxvd0lkID0gXCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvNF9haS50cy8vYWlcIjtcbmFnZW50LndvcmtmbG93SWQgPSBcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy80X2FpLnRzLy9hZ2VudFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGdldFdlYXRoZXJJbmZvcm1hdGlvbiwgU3ltYm9sLmZvcihcIldPUktGTE9XX1NURVBfRlVOQ1RJT05fTkFNRVwiKSwge1xuICAgIHZhbHVlOiBcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzRfYWkudHMvL2dldFdlYXRoZXJJbmZvcm1hdGlvblwiLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlXG59KTtcbiIsICIvKipcbiAqIFN5bWJvbCB1c2VkIGZvciBpZGVudGlmeWluZyBBSSBTREsgRXJyb3IgaW5zdGFuY2VzLlxuICogRW5hYmxlcyBjaGVja2luZyBpZiBhbiBlcnJvciBpcyBhbiBpbnN0YW5jZSBvZiBBSVNES0Vycm9yIGFjcm9zcyBwYWNrYWdlIHZlcnNpb25zLlxuICovXG5jb25zdCBtYXJrZXIgPSAndmVyY2VsLmFpLmVycm9yJztcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuLyoqXG4gKiBDdXN0b20gZXJyb3IgY2xhc3MgZm9yIEFJIFNESyByZWxhdGVkIGVycm9ycy5cbiAqIEBleHRlbmRzIEVycm9yXG4gKi9cbmV4cG9ydCBjbGFzcyBBSVNES0Vycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBwcml2YXRlIHJlYWRvbmx5IFtzeW1ib2xdID0gdHJ1ZTsgLy8gdXNlZCBpbiBpc0luc3RhbmNlXG5cbiAgLyoqXG4gICAqIFRoZSB1bmRlcmx5aW5nIGNhdXNlIG9mIHRoZSBlcnJvciwgaWYgYW55LlxuICAgKi9cbiAgcmVhZG9ubHkgY2F1c2U/OiB1bmtub3duO1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIEFJIFNESyBFcnJvci5cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciBjcmVhdGluZyB0aGUgZXJyb3IuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwYXJhbXMubmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBlcnJvci5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHBhcmFtcy5tZXNzYWdlIC0gVGhlIGVycm9yIG1lc3NhZ2UuXG4gICAqIEBwYXJhbSB7dW5rbm93bn0gW3BhcmFtcy5jYXVzZV0gLSBUaGUgdW5kZXJseWluZyBjYXVzZSBvZiB0aGUgZXJyb3IuXG4gICAqL1xuICBjb25zdHJ1Y3Rvcih7XG4gICAgbmFtZSxcbiAgICBtZXNzYWdlLFxuICAgIGNhdXNlLFxuICB9OiB7XG4gICAgbmFtZTogc3RyaW5nO1xuICAgIG1lc3NhZ2U6IHN0cmluZztcbiAgICBjYXVzZT86IHVua25vd247XG4gIH0pIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcblxuICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgdGhpcy5jYXVzZSA9IGNhdXNlO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gZXJyb3IgaXMgYW4gQUkgU0RLIEVycm9yLlxuICAgKiBAcGFyYW0ge3Vua25vd259IGVycm9yIC0gVGhlIGVycm9yIHRvIGNoZWNrLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgZXJyb3IgaXMgYW4gQUkgU0RLIEVycm9yLCBmYWxzZSBvdGhlcndpc2UuXG4gICAqL1xuICBzdGF0aWMgaXNJbnN0YW5jZShlcnJvcjogdW5rbm93bik6IGVycm9yIGlzIEFJU0RLRXJyb3Ige1xuICAgIHJldHVybiBBSVNES0Vycm9yLmhhc01hcmtlcihlcnJvciwgbWFya2VyKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBzdGF0aWMgaGFzTWFya2VyKGVycm9yOiB1bmtub3duLCBtYXJrZXI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IG1hcmtlclN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcbiAgICByZXR1cm4gKFxuICAgICAgZXJyb3IgIT0gbnVsbCAmJlxuICAgICAgdHlwZW9mIGVycm9yID09PSAnb2JqZWN0JyAmJlxuICAgICAgbWFya2VyU3ltYm9sIGluIGVycm9yICYmXG4gICAgICB0eXBlb2YgZXJyb3JbbWFya2VyU3ltYm9sXSA9PT0gJ2Jvb2xlYW4nICYmXG4gICAgICBlcnJvclttYXJrZXJTeW1ib2xdID09PSB0cnVlXG4gICAgKTtcbiAgfVxufVxuIiwgImltcG9ydCB7IEFJU0RLRXJyb3IgfSBmcm9tICcuL2FpLXNkay1lcnJvcic7XG5cbmNvbnN0IG5hbWUgPSAnQUlfQVBJQ2FsbEVycm9yJztcbmNvbnN0IG1hcmtlciA9IGB2ZXJjZWwuYWkuZXJyb3IuJHtuYW1lfWA7XG5jb25zdCBzeW1ib2wgPSBTeW1ib2wuZm9yKG1hcmtlcik7XG5cbmV4cG9ydCBjbGFzcyBBUElDYWxsRXJyb3IgZXh0ZW5kcyBBSVNES0Vycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7IC8vIHVzZWQgaW4gaXNJbnN0YW5jZVxuXG4gIHJlYWRvbmx5IHVybDogc3RyaW5nO1xuICByZWFkb25seSByZXF1ZXN0Qm9keVZhbHVlczogdW5rbm93bjtcbiAgcmVhZG9ubHkgc3RhdHVzQ29kZT86IG51bWJlcjtcblxuICByZWFkb25seSByZXNwb25zZUhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICByZWFkb25seSByZXNwb25zZUJvZHk/OiBzdHJpbmc7XG5cbiAgcmVhZG9ubHkgaXNSZXRyeWFibGU6IGJvb2xlYW47XG4gIHJlYWRvbmx5IGRhdGE/OiB1bmtub3duO1xuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICBtZXNzYWdlLFxuICAgIHVybCxcbiAgICByZXF1ZXN0Qm9keVZhbHVlcyxcbiAgICBzdGF0dXNDb2RlLFxuICAgIHJlc3BvbnNlSGVhZGVycyxcbiAgICByZXNwb25zZUJvZHksXG4gICAgY2F1c2UsXG4gICAgaXNSZXRyeWFibGUgPSBzdGF0dXNDb2RlICE9IG51bGwgJiZcbiAgICAgIChzdGF0dXNDb2RlID09PSA0MDggfHwgLy8gcmVxdWVzdCB0aW1lb3V0XG4gICAgICAgIHN0YXR1c0NvZGUgPT09IDQwOSB8fCAvLyBjb25mbGljdFxuICAgICAgICBzdGF0dXNDb2RlID09PSA0MjkgfHwgLy8gdG9vIG1hbnkgcmVxdWVzdHNcbiAgICAgICAgc3RhdHVzQ29kZSA+PSA1MDApLCAvLyBzZXJ2ZXIgZXJyb3JcbiAgICBkYXRhLFxuICB9OiB7XG4gICAgbWVzc2FnZTogc3RyaW5nO1xuICAgIHVybDogc3RyaW5nO1xuICAgIHJlcXVlc3RCb2R5VmFsdWVzOiB1bmtub3duO1xuICAgIHN0YXR1c0NvZGU/OiBudW1iZXI7XG4gICAgcmVzcG9uc2VIZWFkZXJzPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgICByZXNwb25zZUJvZHk/OiBzdHJpbmc7XG4gICAgY2F1c2U/OiB1bmtub3duO1xuICAgIGlzUmV0cnlhYmxlPzogYm9vbGVhbjtcbiAgICBkYXRhPzogdW5rbm93bjtcbiAgfSkge1xuICAgIHN1cGVyKHsgbmFtZSwgbWVzc2FnZSwgY2F1c2UgfSk7XG5cbiAgICB0aGlzLnVybCA9IHVybDtcbiAgICB0aGlzLnJlcXVlc3RCb2R5VmFsdWVzID0gcmVxdWVzdEJvZHlWYWx1ZXM7XG4gICAgdGhpcy5zdGF0dXNDb2RlID0gc3RhdHVzQ29kZTtcbiAgICB0aGlzLnJlc3BvbnNlSGVhZGVycyA9IHJlc3BvbnNlSGVhZGVycztcbiAgICB0aGlzLnJlc3BvbnNlQm9keSA9IHJlc3BvbnNlQm9keTtcbiAgICB0aGlzLmlzUmV0cnlhYmxlID0gaXNSZXRyeWFibGU7XG4gICAgdGhpcy5kYXRhID0gZGF0YTtcbiAgfVxuXG4gIHN0YXRpYyBpc0luc3RhbmNlKGVycm9yOiB1bmtub3duKTogZXJyb3IgaXMgQVBJQ2FsbEVycm9yIHtcbiAgICByZXR1cm4gQUlTREtFcnJvci5oYXNNYXJrZXIoZXJyb3IsIG1hcmtlcik7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBBSVNES0Vycm9yIH0gZnJvbSAnLi9haS1zZGstZXJyb3InO1xuXG5jb25zdCBuYW1lID0gJ0FJX0VtcHR5UmVzcG9uc2VCb2R5RXJyb3InO1xuY29uc3QgbWFya2VyID0gYHZlcmNlbC5haS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuZXhwb3J0IGNsYXNzIEVtcHR5UmVzcG9uc2VCb2R5RXJyb3IgZXh0ZW5kcyBBSVNES0Vycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7IC8vIHVzZWQgaW4gaXNJbnN0YW5jZVxuXG4gIGNvbnN0cnVjdG9yKHsgbWVzc2FnZSA9ICdFbXB0eSByZXNwb25zZSBib2R5JyB9OiB7IG1lc3NhZ2U/OiBzdHJpbmcgfSA9IHt9KSB7XG4gICAgc3VwZXIoeyBuYW1lLCBtZXNzYWdlIH0pO1xuICB9XG5cbiAgc3RhdGljIGlzSW5zdGFuY2UoZXJyb3I6IHVua25vd24pOiBlcnJvciBpcyBFbXB0eVJlc3BvbnNlQm9keUVycm9yIHtcbiAgICByZXR1cm4gQUlTREtFcnJvci5oYXNNYXJrZXIoZXJyb3IsIG1hcmtlcik7XG4gIH1cbn1cbiIsICJleHBvcnQgZnVuY3Rpb24gZ2V0RXJyb3JNZXNzYWdlKGVycm9yOiB1bmtub3duIHwgdW5kZWZpbmVkKSB7XG4gIGlmIChlcnJvciA9PSBudWxsKSB7XG4gICAgcmV0dXJuICd1bmtub3duIGVycm9yJztcbiAgfVxuXG4gIGlmICh0eXBlb2YgZXJyb3IgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGVycm9yO1xuICB9XG5cbiAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICByZXR1cm4gZXJyb3IubWVzc2FnZTtcbiAgfVxuXG4gIHJldHVybiBKU09OLnN0cmluZ2lmeShlcnJvcik7XG59XG4iLCAiaW1wb3J0IHsgQUlTREtFcnJvciB9IGZyb20gJy4vYWktc2RrLWVycm9yJztcblxuY29uc3QgbmFtZSA9ICdBSV9JbnZhbGlkQXJndW1lbnRFcnJvcic7XG5jb25zdCBtYXJrZXIgPSBgdmVyY2VsLmFpLmVycm9yLiR7bmFtZX1gO1xuY29uc3Qgc3ltYm9sID0gU3ltYm9sLmZvcihtYXJrZXIpO1xuXG4vKipcbiAqIEEgZnVuY3Rpb24gYXJndW1lbnQgaXMgaW52YWxpZC5cbiAqL1xuZXhwb3J0IGNsYXNzIEludmFsaWRBcmd1bWVudEVycm9yIGV4dGVuZHMgQUlTREtFcnJvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgW3N5bWJvbF0gPSB0cnVlOyAvLyB1c2VkIGluIGlzSW5zdGFuY2VcblxuICByZWFkb25seSBhcmd1bWVudDogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICBtZXNzYWdlLFxuICAgIGNhdXNlLFxuICAgIGFyZ3VtZW50LFxuICB9OiB7XG4gICAgYXJndW1lbnQ6IHN0cmluZztcbiAgICBtZXNzYWdlOiBzdHJpbmc7XG4gICAgY2F1c2U/OiB1bmtub3duO1xuICB9KSB7XG4gICAgc3VwZXIoeyBuYW1lLCBtZXNzYWdlLCBjYXVzZSB9KTtcblxuICAgIHRoaXMuYXJndW1lbnQgPSBhcmd1bWVudDtcbiAgfVxuXG4gIHN0YXRpYyBpc0luc3RhbmNlKGVycm9yOiB1bmtub3duKTogZXJyb3IgaXMgSW52YWxpZEFyZ3VtZW50RXJyb3Ige1xuICAgIHJldHVybiBBSVNES0Vycm9yLmhhc01hcmtlcihlcnJvciwgbWFya2VyKTtcbiAgfVxufVxuIiwgImltcG9ydCB7IEFJU0RLRXJyb3IgfSBmcm9tICcuL2FpLXNkay1lcnJvcic7XG5cbmNvbnN0IG5hbWUgPSAnQUlfSW52YWxpZFByb21wdEVycm9yJztcbmNvbnN0IG1hcmtlciA9IGB2ZXJjZWwuYWkuZXJyb3IuJHtuYW1lfWA7XG5jb25zdCBzeW1ib2wgPSBTeW1ib2wuZm9yKG1hcmtlcik7XG5cbi8qKlxuICogQSBwcm9tcHQgaXMgaW52YWxpZC4gVGhpcyBlcnJvciBzaG91bGQgYmUgdGhyb3duIGJ5IHByb3ZpZGVycyB3aGVuIHRoZXkgY2Fubm90XG4gKiBwcm9jZXNzIGEgcHJvbXB0LlxuICovXG5leHBvcnQgY2xhc3MgSW52YWxpZFByb21wdEVycm9yIGV4dGVuZHMgQUlTREtFcnJvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgW3N5bWJvbF0gPSB0cnVlOyAvLyB1c2VkIGluIGlzSW5zdGFuY2VcblxuICByZWFkb25seSBwcm9tcHQ6IHVua25vd247XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIHByb21wdCxcbiAgICBtZXNzYWdlLFxuICAgIGNhdXNlLFxuICB9OiB7XG4gICAgcHJvbXB0OiB1bmtub3duO1xuICAgIG1lc3NhZ2U6IHN0cmluZztcbiAgICBjYXVzZT86IHVua25vd247XG4gIH0pIHtcbiAgICBzdXBlcih7IG5hbWUsIG1lc3NhZ2U6IGBJbnZhbGlkIHByb21wdDogJHttZXNzYWdlfWAsIGNhdXNlIH0pO1xuXG4gICAgdGhpcy5wcm9tcHQgPSBwcm9tcHQ7XG4gIH1cblxuICBzdGF0aWMgaXNJbnN0YW5jZShlcnJvcjogdW5rbm93bik6IGVycm9yIGlzIEludmFsaWRQcm9tcHRFcnJvciB7XG4gICAgcmV0dXJuIEFJU0RLRXJyb3IuaGFzTWFya2VyKGVycm9yLCBtYXJrZXIpO1xuICB9XG59XG4iLCAiaW1wb3J0IHsgQUlTREtFcnJvciB9IGZyb20gJy4vYWktc2RrLWVycm9yJztcblxuY29uc3QgbmFtZSA9ICdBSV9JbnZhbGlkUmVzcG9uc2VEYXRhRXJyb3InO1xuY29uc3QgbWFya2VyID0gYHZlcmNlbC5haS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuLyoqXG4gKiBTZXJ2ZXIgcmV0dXJuZWQgYSByZXNwb25zZSB3aXRoIGludmFsaWQgZGF0YSBjb250ZW50LlxuICogVGhpcyBzaG91bGQgYmUgdGhyb3duIGJ5IHByb3ZpZGVycyB3aGVuIHRoZXkgY2Fubm90IHBhcnNlIHRoZSByZXNwb25zZSBmcm9tIHRoZSBBUEkuXG4gKi9cbmV4cG9ydCBjbGFzcyBJbnZhbGlkUmVzcG9uc2VEYXRhRXJyb3IgZXh0ZW5kcyBBSVNES0Vycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7IC8vIHVzZWQgaW4gaXNJbnN0YW5jZVxuXG4gIHJlYWRvbmx5IGRhdGE6IHVua25vd247XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIGRhdGEsXG4gICAgbWVzc2FnZSA9IGBJbnZhbGlkIHJlc3BvbnNlIGRhdGE6ICR7SlNPTi5zdHJpbmdpZnkoZGF0YSl9LmAsXG4gIH06IHtcbiAgICBkYXRhOiB1bmtub3duO1xuICAgIG1lc3NhZ2U/OiBzdHJpbmc7XG4gIH0pIHtcbiAgICBzdXBlcih7IG5hbWUsIG1lc3NhZ2UgfSk7XG5cbiAgICB0aGlzLmRhdGEgPSBkYXRhO1xuICB9XG5cbiAgc3RhdGljIGlzSW5zdGFuY2UoZXJyb3I6IHVua25vd24pOiBlcnJvciBpcyBJbnZhbGlkUmVzcG9uc2VEYXRhRXJyb3Ige1xuICAgIHJldHVybiBBSVNES0Vycm9yLmhhc01hcmtlcihlcnJvciwgbWFya2VyKTtcbiAgfVxufVxuIiwgImltcG9ydCB7IEFJU0RLRXJyb3IgfSBmcm9tICcuL2FpLXNkay1lcnJvcic7XG5pbXBvcnQgeyBnZXRFcnJvck1lc3NhZ2UgfSBmcm9tICcuL2dldC1lcnJvci1tZXNzYWdlJztcblxuY29uc3QgbmFtZSA9ICdBSV9KU09OUGFyc2VFcnJvcic7XG5jb25zdCBtYXJrZXIgPSBgdmVyY2VsLmFpLmVycm9yLiR7bmFtZX1gO1xuY29uc3Qgc3ltYm9sID0gU3ltYm9sLmZvcihtYXJrZXIpO1xuXG4vLyBUT0RPIHY1OiByZW5hbWUgdG8gUGFyc2VFcnJvclxuZXhwb3J0IGNsYXNzIEpTT05QYXJzZUVycm9yIGV4dGVuZHMgQUlTREtFcnJvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgW3N5bWJvbF0gPSB0cnVlOyAvLyB1c2VkIGluIGlzSW5zdGFuY2VcblxuICByZWFkb25seSB0ZXh0OiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoeyB0ZXh0LCBjYXVzZSB9OiB7IHRleHQ6IHN0cmluZzsgY2F1c2U6IHVua25vd24gfSkge1xuICAgIHN1cGVyKHtcbiAgICAgIG5hbWUsXG4gICAgICBtZXNzYWdlOlxuICAgICAgICBgSlNPTiBwYXJzaW5nIGZhaWxlZDogYCArXG4gICAgICAgIGBUZXh0OiAke3RleHR9LlxcbmAgK1xuICAgICAgICBgRXJyb3IgbWVzc2FnZTogJHtnZXRFcnJvck1lc3NhZ2UoY2F1c2UpfWAsXG4gICAgICBjYXVzZSxcbiAgICB9KTtcblxuICAgIHRoaXMudGV4dCA9IHRleHQ7XG4gIH1cblxuICBzdGF0aWMgaXNJbnN0YW5jZShlcnJvcjogdW5rbm93bik6IGVycm9yIGlzIEpTT05QYXJzZUVycm9yIHtcbiAgICByZXR1cm4gQUlTREtFcnJvci5oYXNNYXJrZXIoZXJyb3IsIG1hcmtlcik7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBBSVNES0Vycm9yIH0gZnJvbSAnLi9haS1zZGstZXJyb3InO1xuXG5jb25zdCBuYW1lID0gJ0FJX0xvYWRBUElLZXlFcnJvcic7XG5jb25zdCBtYXJrZXIgPSBgdmVyY2VsLmFpLmVycm9yLiR7bmFtZX1gO1xuY29uc3Qgc3ltYm9sID0gU3ltYm9sLmZvcihtYXJrZXIpO1xuXG5leHBvcnQgY2xhc3MgTG9hZEFQSUtleUVycm9yIGV4dGVuZHMgQUlTREtFcnJvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgW3N5bWJvbF0gPSB0cnVlOyAvLyB1c2VkIGluIGlzSW5zdGFuY2VcblxuICBjb25zdHJ1Y3Rvcih7IG1lc3NhZ2UgfTogeyBtZXNzYWdlOiBzdHJpbmcgfSkge1xuICAgIHN1cGVyKHsgbmFtZSwgbWVzc2FnZSB9KTtcbiAgfVxuXG4gIHN0YXRpYyBpc0luc3RhbmNlKGVycm9yOiB1bmtub3duKTogZXJyb3IgaXMgTG9hZEFQSUtleUVycm9yIHtcbiAgICByZXR1cm4gQUlTREtFcnJvci5oYXNNYXJrZXIoZXJyb3IsIG1hcmtlcik7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBBSVNES0Vycm9yIH0gZnJvbSAnLi9haS1zZGstZXJyb3InO1xuXG5jb25zdCBuYW1lID0gJ0FJX0xvYWRTZXR0aW5nRXJyb3InO1xuY29uc3QgbWFya2VyID0gYHZlcmNlbC5haS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuZXhwb3J0IGNsYXNzIExvYWRTZXR0aW5nRXJyb3IgZXh0ZW5kcyBBSVNES0Vycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7IC8vIHVzZWQgaW4gaXNJbnN0YW5jZVxuXG4gIGNvbnN0cnVjdG9yKHsgbWVzc2FnZSB9OiB7IG1lc3NhZ2U6IHN0cmluZyB9KSB7XG4gICAgc3VwZXIoeyBuYW1lLCBtZXNzYWdlIH0pO1xuICB9XG5cbiAgc3RhdGljIGlzSW5zdGFuY2UoZXJyb3I6IHVua25vd24pOiBlcnJvciBpcyBMb2FkU2V0dGluZ0Vycm9yIHtcbiAgICByZXR1cm4gQUlTREtFcnJvci5oYXNNYXJrZXIoZXJyb3IsIG1hcmtlcik7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBBSVNES0Vycm9yIH0gZnJvbSAnLi9haS1zZGstZXJyb3InO1xuXG5jb25zdCBuYW1lID0gJ0FJX05vQ29udGVudEdlbmVyYXRlZEVycm9yJztcbmNvbnN0IG1hcmtlciA9IGB2ZXJjZWwuYWkuZXJyb3IuJHtuYW1lfWA7XG5jb25zdCBzeW1ib2wgPSBTeW1ib2wuZm9yKG1hcmtlcik7XG5cbi8qKlxuVGhyb3duIHdoZW4gdGhlIEFJIHByb3ZpZGVyIGZhaWxzIHRvIGdlbmVyYXRlIGFueSBjb250ZW50LlxuICovXG5leHBvcnQgY2xhc3MgTm9Db250ZW50R2VuZXJhdGVkRXJyb3IgZXh0ZW5kcyBBSVNES0Vycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7IC8vIHVzZWQgaW4gaXNJbnN0YW5jZVxuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICBtZXNzYWdlID0gJ05vIGNvbnRlbnQgZ2VuZXJhdGVkLicsXG4gIH06IHsgbWVzc2FnZT86IHN0cmluZyB9ID0ge30pIHtcbiAgICBzdXBlcih7IG5hbWUsIG1lc3NhZ2UgfSk7XG4gIH1cblxuICBzdGF0aWMgaXNJbnN0YW5jZShlcnJvcjogdW5rbm93bik6IGVycm9yIGlzIE5vQ29udGVudEdlbmVyYXRlZEVycm9yIHtcbiAgICByZXR1cm4gQUlTREtFcnJvci5oYXNNYXJrZXIoZXJyb3IsIG1hcmtlcik7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBBSVNES0Vycm9yIH0gZnJvbSAnLi9haS1zZGstZXJyb3InO1xuXG5jb25zdCBuYW1lID0gJ0FJX05vU3VjaE1vZGVsRXJyb3InO1xuY29uc3QgbWFya2VyID0gYHZlcmNlbC5haS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuZXhwb3J0IGNsYXNzIE5vU3VjaE1vZGVsRXJyb3IgZXh0ZW5kcyBBSVNES0Vycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7IC8vIHVzZWQgaW4gaXNJbnN0YW5jZVxuXG4gIHJlYWRvbmx5IG1vZGVsSWQ6IHN0cmluZztcbiAgcmVhZG9ubHkgbW9kZWxUeXBlOlxuICAgIHwgJ2xhbmd1YWdlTW9kZWwnXG4gICAgfCAndGV4dEVtYmVkZGluZ01vZGVsJ1xuICAgIHwgJ2ltYWdlTW9kZWwnXG4gICAgfCAndHJhbnNjcmlwdGlvbk1vZGVsJ1xuICAgIHwgJ3NwZWVjaE1vZGVsJztcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgZXJyb3JOYW1lID0gbmFtZSxcbiAgICBtb2RlbElkLFxuICAgIG1vZGVsVHlwZSxcbiAgICBtZXNzYWdlID0gYE5vIHN1Y2ggJHttb2RlbFR5cGV9OiAke21vZGVsSWR9YCxcbiAgfToge1xuICAgIGVycm9yTmFtZT86IHN0cmluZztcbiAgICBtb2RlbElkOiBzdHJpbmc7XG4gICAgbW9kZWxUeXBlOlxuICAgICAgfCAnbGFuZ3VhZ2VNb2RlbCdcbiAgICAgIHwgJ3RleHRFbWJlZGRpbmdNb2RlbCdcbiAgICAgIHwgJ2ltYWdlTW9kZWwnXG4gICAgICB8ICd0cmFuc2NyaXB0aW9uTW9kZWwnXG4gICAgICB8ICdzcGVlY2hNb2RlbCc7XG4gICAgbWVzc2FnZT86IHN0cmluZztcbiAgfSkge1xuICAgIHN1cGVyKHsgbmFtZTogZXJyb3JOYW1lLCBtZXNzYWdlIH0pO1xuXG4gICAgdGhpcy5tb2RlbElkID0gbW9kZWxJZDtcbiAgICB0aGlzLm1vZGVsVHlwZSA9IG1vZGVsVHlwZTtcbiAgfVxuXG4gIHN0YXRpYyBpc0luc3RhbmNlKGVycm9yOiB1bmtub3duKTogZXJyb3IgaXMgTm9TdWNoTW9kZWxFcnJvciB7XG4gICAgcmV0dXJuIEFJU0RLRXJyb3IuaGFzTWFya2VyKGVycm9yLCBtYXJrZXIpO1xuICB9XG59XG4iLCAiaW1wb3J0IHsgQUlTREtFcnJvciB9IGZyb20gJy4vYWktc2RrLWVycm9yJztcblxuY29uc3QgbmFtZSA9ICdBSV9Ub29NYW55RW1iZWRkaW5nVmFsdWVzRm9yQ2FsbEVycm9yJztcbmNvbnN0IG1hcmtlciA9IGB2ZXJjZWwuYWkuZXJyb3IuJHtuYW1lfWA7XG5jb25zdCBzeW1ib2wgPSBTeW1ib2wuZm9yKG1hcmtlcik7XG5cbmV4cG9ydCBjbGFzcyBUb29NYW55RW1iZWRkaW5nVmFsdWVzRm9yQ2FsbEVycm9yIGV4dGVuZHMgQUlTREtFcnJvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgW3N5bWJvbF0gPSB0cnVlOyAvLyB1c2VkIGluIGlzSW5zdGFuY2VcblxuICByZWFkb25seSBwcm92aWRlcjogc3RyaW5nO1xuICByZWFkb25seSBtb2RlbElkOiBzdHJpbmc7XG4gIHJlYWRvbmx5IG1heEVtYmVkZGluZ3NQZXJDYWxsOiBudW1iZXI7XG4gIHJlYWRvbmx5IHZhbHVlczogQXJyYXk8dW5rbm93bj47XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczoge1xuICAgIHByb3ZpZGVyOiBzdHJpbmc7XG4gICAgbW9kZWxJZDogc3RyaW5nO1xuICAgIG1heEVtYmVkZGluZ3NQZXJDYWxsOiBudW1iZXI7XG4gICAgdmFsdWVzOiBBcnJheTx1bmtub3duPjtcbiAgfSkge1xuICAgIHN1cGVyKHtcbiAgICAgIG5hbWUsXG4gICAgICBtZXNzYWdlOlxuICAgICAgICBgVG9vIG1hbnkgdmFsdWVzIGZvciBhIHNpbmdsZSBlbWJlZGRpbmcgY2FsbC4gYCArXG4gICAgICAgIGBUaGUgJHtvcHRpb25zLnByb3ZpZGVyfSBtb2RlbCBcIiR7b3B0aW9ucy5tb2RlbElkfVwiIGNhbiBvbmx5IGVtYmVkIHVwIHRvIGAgK1xuICAgICAgICBgJHtvcHRpb25zLm1heEVtYmVkZGluZ3NQZXJDYWxsfSB2YWx1ZXMgcGVyIGNhbGwsIGJ1dCAke29wdGlvbnMudmFsdWVzLmxlbmd0aH0gdmFsdWVzIHdlcmUgcHJvdmlkZWQuYCxcbiAgICB9KTtcblxuICAgIHRoaXMucHJvdmlkZXIgPSBvcHRpb25zLnByb3ZpZGVyO1xuICAgIHRoaXMubW9kZWxJZCA9IG9wdGlvbnMubW9kZWxJZDtcbiAgICB0aGlzLm1heEVtYmVkZGluZ3NQZXJDYWxsID0gb3B0aW9ucy5tYXhFbWJlZGRpbmdzUGVyQ2FsbDtcbiAgICB0aGlzLnZhbHVlcyA9IG9wdGlvbnMudmFsdWVzO1xuICB9XG5cbiAgc3RhdGljIGlzSW5zdGFuY2UoXG4gICAgZXJyb3I6IHVua25vd24sXG4gICk6IGVycm9yIGlzIFRvb01hbnlFbWJlZGRpbmdWYWx1ZXNGb3JDYWxsRXJyb3Ige1xuICAgIHJldHVybiBBSVNES0Vycm9yLmhhc01hcmtlcihlcnJvciwgbWFya2VyKTtcbiAgfVxufVxuIiwgImltcG9ydCB7IEFJU0RLRXJyb3IgfSBmcm9tICcuL2FpLXNkay1lcnJvcic7XG5pbXBvcnQgeyBnZXRFcnJvck1lc3NhZ2UgfSBmcm9tICcuL2dldC1lcnJvci1tZXNzYWdlJztcblxuY29uc3QgbmFtZSA9ICdBSV9UeXBlVmFsaWRhdGlvbkVycm9yJztcbmNvbnN0IG1hcmtlciA9IGB2ZXJjZWwuYWkuZXJyb3IuJHtuYW1lfWA7XG5jb25zdCBzeW1ib2wgPSBTeW1ib2wuZm9yKG1hcmtlcik7XG5cbmV4cG9ydCBjbGFzcyBUeXBlVmFsaWRhdGlvbkVycm9yIGV4dGVuZHMgQUlTREtFcnJvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgW3N5bWJvbF0gPSB0cnVlOyAvLyB1c2VkIGluIGlzSW5zdGFuY2VcblxuICByZWFkb25seSB2YWx1ZTogdW5rbm93bjtcblxuICBjb25zdHJ1Y3Rvcih7IHZhbHVlLCBjYXVzZSB9OiB7IHZhbHVlOiB1bmtub3duOyBjYXVzZTogdW5rbm93biB9KSB7XG4gICAgc3VwZXIoe1xuICAgICAgbmFtZSxcbiAgICAgIG1lc3NhZ2U6XG4gICAgICAgIGBUeXBlIHZhbGlkYXRpb24gZmFpbGVkOiBgICtcbiAgICAgICAgYFZhbHVlOiAke0pTT04uc3RyaW5naWZ5KHZhbHVlKX0uXFxuYCArXG4gICAgICAgIGBFcnJvciBtZXNzYWdlOiAke2dldEVycm9yTWVzc2FnZShjYXVzZSl9YCxcbiAgICAgIGNhdXNlLFxuICAgIH0pO1xuXG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICB9XG5cbiAgc3RhdGljIGlzSW5zdGFuY2UoZXJyb3I6IHVua25vd24pOiBlcnJvciBpcyBUeXBlVmFsaWRhdGlvbkVycm9yIHtcbiAgICByZXR1cm4gQUlTREtFcnJvci5oYXNNYXJrZXIoZXJyb3IsIG1hcmtlcik7XG4gIH1cblxuICAvKipcbiAgICogV3JhcHMgYW4gZXJyb3IgaW50byBhIFR5cGVWYWxpZGF0aW9uRXJyb3IuXG4gICAqIElmIHRoZSBjYXVzZSBpcyBhbHJlYWR5IGEgVHlwZVZhbGlkYXRpb25FcnJvciB3aXRoIHRoZSBzYW1lIHZhbHVlLCBpdCByZXR1cm5zIHRoZSBjYXVzZS5cbiAgICogT3RoZXJ3aXNlLCBpdCBjcmVhdGVzIGEgbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IuXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwYXJhbXMgLSBUaGUgcGFyYW1ldGVycyBmb3Igd3JhcHBpbmcgdGhlIGVycm9yLlxuICAgKiBAcGFyYW0ge3Vua25vd259IHBhcmFtcy52YWx1ZSAtIFRoZSB2YWx1ZSB0aGF0IGZhaWxlZCB2YWxpZGF0aW9uLlxuICAgKiBAcGFyYW0ge3Vua25vd259IHBhcmFtcy5jYXVzZSAtIFRoZSBvcmlnaW5hbCBlcnJvciBvciBjYXVzZSBvZiB0aGUgdmFsaWRhdGlvbiBmYWlsdXJlLlxuICAgKiBAcmV0dXJucyB7VHlwZVZhbGlkYXRpb25FcnJvcn0gQSBUeXBlVmFsaWRhdGlvbkVycm9yIGluc3RhbmNlLlxuICAgKi9cbiAgc3RhdGljIHdyYXAoe1xuICAgIHZhbHVlLFxuICAgIGNhdXNlLFxuICB9OiB7XG4gICAgdmFsdWU6IHVua25vd247XG4gICAgY2F1c2U6IHVua25vd247XG4gIH0pOiBUeXBlVmFsaWRhdGlvbkVycm9yIHtcbiAgICByZXR1cm4gVHlwZVZhbGlkYXRpb25FcnJvci5pc0luc3RhbmNlKGNhdXNlKSAmJiBjYXVzZS52YWx1ZSA9PT0gdmFsdWVcbiAgICAgID8gY2F1c2VcbiAgICAgIDogbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IoeyB2YWx1ZSwgY2F1c2UgfSk7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBBSVNES0Vycm9yIH0gZnJvbSAnLi9haS1zZGstZXJyb3InO1xuXG5jb25zdCBuYW1lID0gJ0FJX1Vuc3VwcG9ydGVkRnVuY3Rpb25hbGl0eUVycm9yJztcbmNvbnN0IG1hcmtlciA9IGB2ZXJjZWwuYWkuZXJyb3IuJHtuYW1lfWA7XG5jb25zdCBzeW1ib2wgPSBTeW1ib2wuZm9yKG1hcmtlcik7XG5cbmV4cG9ydCBjbGFzcyBVbnN1cHBvcnRlZEZ1bmN0aW9uYWxpdHlFcnJvciBleHRlbmRzIEFJU0RLRXJyb3Ige1xuICBwcml2YXRlIHJlYWRvbmx5IFtzeW1ib2xdID0gdHJ1ZTsgLy8gdXNlZCBpbiBpc0luc3RhbmNlXG5cbiAgcmVhZG9ubHkgZnVuY3Rpb25hbGl0eTogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICBmdW5jdGlvbmFsaXR5LFxuICAgIG1lc3NhZ2UgPSBgJyR7ZnVuY3Rpb25hbGl0eX0nIGZ1bmN0aW9uYWxpdHkgbm90IHN1cHBvcnRlZC5gLFxuICB9OiB7XG4gICAgZnVuY3Rpb25hbGl0eTogc3RyaW5nO1xuICAgIG1lc3NhZ2U/OiBzdHJpbmc7XG4gIH0pIHtcbiAgICBzdXBlcih7IG5hbWUsIG1lc3NhZ2UgfSk7XG4gICAgdGhpcy5mdW5jdGlvbmFsaXR5ID0gZnVuY3Rpb25hbGl0eTtcbiAgfVxuXG4gIHN0YXRpYyBpc0luc3RhbmNlKGVycm9yOiB1bmtub3duKTogZXJyb3IgaXMgVW5zdXBwb3J0ZWRGdW5jdGlvbmFsaXR5RXJyb3Ige1xuICAgIHJldHVybiBBSVNES0Vycm9yLmhhc01hcmtlcihlcnJvciwgbWFya2VyKTtcbiAgfVxufVxuIiwgImltcG9ydCB7IEpTT05BcnJheSwgSlNPTk9iamVjdCwgSlNPTlZhbHVlIH0gZnJvbSAnLi9qc29uLXZhbHVlJztcblxuZXhwb3J0IGZ1bmN0aW9uIGlzSlNPTlZhbHVlKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgSlNPTlZhbHVlIHtcbiAgaWYgKFxuICAgIHZhbHVlID09PSBudWxsIHx8XG4gICAgdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyB8fFxuICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgfHxcbiAgICB0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJ1xuICApIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgIHJldHVybiB2YWx1ZS5ldmVyeShpc0pTT05WYWx1ZSk7XG4gIH1cblxuICBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jykge1xuICAgIHJldHVybiBPYmplY3QuZW50cmllcyh2YWx1ZSkuZXZlcnkoXG4gICAgICAoW2tleSwgdmFsXSkgPT4gdHlwZW9mIGtleSA9PT0gJ3N0cmluZycgJiYgaXNKU09OVmFsdWUodmFsKSxcbiAgICApO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNKU09OQXJyYXkodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBKU09OQXJyYXkge1xuICByZXR1cm4gQXJyYXkuaXNBcnJheSh2YWx1ZSkgJiYgdmFsdWUuZXZlcnkoaXNKU09OVmFsdWUpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNKU09OT2JqZWN0KHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgSlNPTk9iamVjdCB7XG4gIHJldHVybiAoXG4gICAgdmFsdWUgIT0gbnVsbCAmJlxuICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiZcbiAgICBPYmplY3QuZW50cmllcyh2YWx1ZSkuZXZlcnkoXG4gICAgICAoW2tleSwgdmFsXSkgPT4gdHlwZW9mIGtleSA9PT0gJ3N0cmluZycgJiYgaXNKU09OVmFsdWUodmFsKSxcbiAgICApXG4gICk7XG59XG4iLCAiLyoqXG4gKiBUaGUgdHlwZSBvZiBlcnJvciB0aGF0IG9jY3VycmVkLlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgdHlwZSBFcnJvclR5cGUgPSAnaW52YWxpZC1yZXRyeScgfCAndW5rbm93bi1maWVsZCdcblxuLyoqXG4gKiBFcnJvciB0aHJvd24gd2hlbiBlbmNvdW50ZXJpbmcgYW4gaXNzdWUgZHVyaW5nIHBhcnNpbmcuXG4gKlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY2xhc3MgUGFyc2VFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgLyoqXG4gICAqIFRoZSB0eXBlIG9mIGVycm9yIHRoYXQgb2NjdXJyZWQuXG4gICAqL1xuICB0eXBlOiBFcnJvclR5cGVcblxuICAvKipcbiAgICogSW4gdGhlIGNhc2Ugb2YgYW4gdW5rbm93biBmaWVsZCBlbmNvdW50ZXJlZCBpbiB0aGUgc3RyZWFtLCB0aGlzIHdpbGwgYmUgdGhlIGZpZWxkIG5hbWUuXG4gICAqL1xuICBmaWVsZD86IHN0cmluZyB8IHVuZGVmaW5lZFxuXG4gIC8qKlxuICAgKiBJbiB0aGUgY2FzZSBvZiBhbiB1bmtub3duIGZpZWxkIGVuY291bnRlcmVkIGluIHRoZSBzdHJlYW0sIHRoaXMgd2lsbCBiZSB0aGUgdmFsdWUgb2YgdGhlIGZpZWxkLlxuICAgKi9cbiAgdmFsdWU/OiBzdHJpbmcgfCB1bmRlZmluZWRcblxuICAvKipcbiAgICogVGhlIGxpbmUgdGhhdCBjYXVzZWQgdGhlIGVycm9yLCBpZiBhdmFpbGFibGUuXG4gICAqL1xuICBsaW5lPzogc3RyaW5nIHwgdW5kZWZpbmVkXG5cbiAgY29uc3RydWN0b3IoXG4gICAgbWVzc2FnZTogc3RyaW5nLFxuICAgIG9wdGlvbnM6IHt0eXBlOiBFcnJvclR5cGU7IGZpZWxkPzogc3RyaW5nOyB2YWx1ZT86IHN0cmluZzsgbGluZT86IHN0cmluZ30sXG4gICkge1xuICAgIHN1cGVyKG1lc3NhZ2UpXG4gICAgdGhpcy5uYW1lID0gJ1BhcnNlRXJyb3InXG4gICAgdGhpcy50eXBlID0gb3B0aW9ucy50eXBlXG4gICAgdGhpcy5maWVsZCA9IG9wdGlvbnMuZmllbGRcbiAgICB0aGlzLnZhbHVlID0gb3B0aW9ucy52YWx1ZVxuICAgIHRoaXMubGluZSA9IG9wdGlvbnMubGluZVxuICB9XG59XG4iLCAiLyoqXG4gKiBFdmVudFNvdXJjZS9TZXJ2ZXItU2VudCBFdmVudHMgcGFyc2VyXG4gKiBAc2VlIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3NlcnZlci1zZW50LWV2ZW50cy5odG1sXG4gKi9cbmltcG9ydCB7UGFyc2VFcnJvcn0gZnJvbSAnLi9lcnJvcnMudHMnXG5pbXBvcnQgdHlwZSB7RXZlbnRTb3VyY2VQYXJzZXIsIFBhcnNlckNhbGxiYWNrc30gZnJvbSAnLi90eXBlcy50cydcblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuZnVuY3Rpb24gbm9vcChfYXJnOiB1bmtub3duKSB7XG4gIC8vIGludGVudGlvbmFsIG5vb3Bcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IEV2ZW50U291cmNlIHBhcnNlci5cbiAqXG4gKiBAcGFyYW0gY2FsbGJhY2tzIC0gQ2FsbGJhY2tzIHRvIGludm9rZSBvbiBkaWZmZXJlbnQgcGFyc2luZyBldmVudHM6XG4gKiAgIC0gYG9uRXZlbnRgIHdoZW4gYSBuZXcgZXZlbnQgaXMgcGFyc2VkXG4gKiAgIC0gYG9uRXJyb3JgIHdoZW4gYW4gZXJyb3Igb2NjdXJzXG4gKiAgIC0gYG9uUmV0cnlgIHdoZW4gYSBuZXcgcmVjb25uZWN0aW9uIGludGVydmFsIGhhcyBiZWVuIHNlbnQgZnJvbSB0aGUgc2VydmVyXG4gKiAgIC0gYG9uQ29tbWVudGAgd2hlbiBhIGNvbW1lbnQgaXMgZW5jb3VudGVyZWQgaW4gdGhlIHN0cmVhbVxuICpcbiAqIEByZXR1cm5zIEEgbmV3IEV2ZW50U291cmNlIHBhcnNlciwgd2l0aCBgcGFyc2VgIGFuZCBgcmVzZXRgIG1ldGhvZHMuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVQYXJzZXIoY2FsbGJhY2tzOiBQYXJzZXJDYWxsYmFja3MpOiBFdmVudFNvdXJjZVBhcnNlciB7XG4gIGlmICh0eXBlb2YgY2FsbGJhY2tzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICdgY2FsbGJhY2tzYCBtdXN0IGJlIGFuIG9iamVjdCwgZ290IGEgZnVuY3Rpb24gaW5zdGVhZC4gRGlkIHlvdSBtZWFuIGB7b25FdmVudDogZm59YD8nLFxuICAgIClcbiAgfVxuXG4gIGNvbnN0IHtvbkV2ZW50ID0gbm9vcCwgb25FcnJvciA9IG5vb3AsIG9uUmV0cnkgPSBub29wLCBvbkNvbW1lbnR9ID0gY2FsbGJhY2tzXG5cbiAgbGV0IGluY29tcGxldGVMaW5lID0gJydcblxuICBsZXQgaXNGaXJzdENodW5rID0gdHJ1ZVxuICBsZXQgaWQ6IHN0cmluZyB8IHVuZGVmaW5lZFxuICBsZXQgZGF0YSA9ICcnXG4gIGxldCBldmVudFR5cGUgPSAnJ1xuXG4gIGZ1bmN0aW9uIGZlZWQobmV3Q2h1bms6IHN0cmluZykge1xuICAgIC8vIFN0cmlwIGFueSBVVEY4IGJ5dGUgb3JkZXIgbWFyayAoQk9NKSBhdCB0aGUgc3RhcnQgb2YgdGhlIHN0cmVhbVxuICAgIGNvbnN0IGNodW5rID0gaXNGaXJzdENodW5rID8gbmV3Q2h1bmsucmVwbGFjZSgvXlxceEVGXFx4QkJcXHhCRi8sICcnKSA6IG5ld0NodW5rXG5cbiAgICAvLyBJZiB0aGVyZSB3YXMgYSBwcmV2aW91cyBpbmNvbXBsZXRlIGxpbmUsIGFwcGVuZCBpdCB0byB0aGUgbmV3IGNodW5rLFxuICAgIC8vIHNvIHdlIG1heSBwcm9jZXNzIGl0IHRvZ2V0aGVyIGFzIGEgbmV3IChob3BlZnVsbHkgY29tcGxldGUpIGNodW5rLlxuICAgIGNvbnN0IFtjb21wbGV0ZSwgaW5jb21wbGV0ZV0gPSBzcGxpdExpbmVzKGAke2luY29tcGxldGVMaW5lfSR7Y2h1bmt9YClcblxuICAgIGZvciAoY29uc3QgbGluZSBvZiBjb21wbGV0ZSkge1xuICAgICAgcGFyc2VMaW5lKGxpbmUpXG4gICAgfVxuXG4gICAgaW5jb21wbGV0ZUxpbmUgPSBpbmNvbXBsZXRlXG4gICAgaXNGaXJzdENodW5rID0gZmFsc2VcbiAgfVxuXG4gIGZ1bmN0aW9uIHBhcnNlTGluZShsaW5lOiBzdHJpbmcpIHtcbiAgICAvLyBJZiB0aGUgbGluZSBpcyBlbXB0eSAoYSBibGFuayBsaW5lKSwgZGlzcGF0Y2ggdGhlIGV2ZW50XG4gICAgaWYgKGxpbmUgPT09ICcnKSB7XG4gICAgICBkaXNwYXRjaEV2ZW50KClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIC8vIElmIHRoZSBsaW5lIHN0YXJ0cyB3aXRoIGEgVSswMDNBIENPTE9OIGNoYXJhY3RlciAoOiksIGlnbm9yZSB0aGUgbGluZS5cbiAgICBpZiAobGluZS5zdGFydHNXaXRoKCc6JykpIHtcbiAgICAgIGlmIChvbkNvbW1lbnQpIHtcbiAgICAgICAgb25Db21tZW50KGxpbmUuc2xpY2UobGluZS5zdGFydHNXaXRoKCc6ICcpID8gMiA6IDEpKVxuICAgICAgfVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLy8gSWYgdGhlIGxpbmUgY29udGFpbnMgYSBVKzAwM0EgQ09MT04gY2hhcmFjdGVyICg6KVxuICAgIGNvbnN0IGZpZWxkU2VwYXJhdG9ySW5kZXggPSBsaW5lLmluZGV4T2YoJzonKVxuICAgIGlmIChmaWVsZFNlcGFyYXRvckluZGV4ICE9PSAtMSkge1xuICAgICAgLy8gQ29sbGVjdCB0aGUgY2hhcmFjdGVycyBvbiB0aGUgbGluZSBiZWZvcmUgdGhlIGZpcnN0IFUrMDAzQSBDT0xPTiBjaGFyYWN0ZXIgKDopLFxuICAgICAgLy8gYW5kIGxldCBgZmllbGRgIGJlIHRoYXQgc3RyaW5nLlxuICAgICAgY29uc3QgZmllbGQgPSBsaW5lLnNsaWNlKDAsIGZpZWxkU2VwYXJhdG9ySW5kZXgpXG5cbiAgICAgIC8vIENvbGxlY3QgdGhlIGNoYXJhY3RlcnMgb24gdGhlIGxpbmUgYWZ0ZXIgdGhlIGZpcnN0IFUrMDAzQSBDT0xPTiBjaGFyYWN0ZXIgKDopLFxuICAgICAgLy8gYW5kIGxldCBgdmFsdWVgIGJlIHRoYXQgc3RyaW5nLiBJZiB2YWx1ZSBzdGFydHMgd2l0aCBhIFUrMDAyMCBTUEFDRSBjaGFyYWN0ZXIsXG4gICAgICAvLyByZW1vdmUgaXQgZnJvbSB2YWx1ZS5cbiAgICAgIGNvbnN0IG9mZnNldCA9IGxpbmVbZmllbGRTZXBhcmF0b3JJbmRleCArIDFdID09PSAnICcgPyAyIDogMVxuICAgICAgY29uc3QgdmFsdWUgPSBsaW5lLnNsaWNlKGZpZWxkU2VwYXJhdG9ySW5kZXggKyBvZmZzZXQpXG5cbiAgICAgIHByb2Nlc3NGaWVsZChmaWVsZCwgdmFsdWUsIGxpbmUpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyBPdGhlcndpc2UsIHRoZSBzdHJpbmcgaXMgbm90IGVtcHR5IGJ1dCBkb2VzIG5vdCBjb250YWluIGEgVSswMDNBIENPTE9OIGNoYXJhY3RlciAoOilcbiAgICAvLyBQcm9jZXNzIHRoZSBmaWVsZCB1c2luZyB0aGUgd2hvbGUgbGluZSBhcyB0aGUgZmllbGQgbmFtZSwgYW5kIGFuIGVtcHR5IHN0cmluZyBhcyB0aGUgZmllbGQgdmFsdWUuXG4gICAgLy8g8J+RhiBUaGlzIGlzIGFjY29yZGluZyB0byBzcGVjLiBUaGF0IG1lYW5zIHRoYXQgYSBsaW5lIHRoYXQgaGFzIHRoZSB2YWx1ZSBgZGF0YWAgd2lsbCByZXN1bHQgaW5cbiAgICAvLyBhIG5ld2xpbmUgYmVpbmcgYWRkZWQgdG8gdGhlIGN1cnJlbnQgYGRhdGFgIGJ1ZmZlciwgZm9yIGluc3RhbmNlLlxuICAgIHByb2Nlc3NGaWVsZChsaW5lLCAnJywgbGluZSlcbiAgfVxuXG4gIGZ1bmN0aW9uIHByb2Nlc3NGaWVsZChmaWVsZDogc3RyaW5nLCB2YWx1ZTogc3RyaW5nLCBsaW5lOiBzdHJpbmcpIHtcbiAgICAvLyBGaWVsZCBuYW1lcyBtdXN0IGJlIGNvbXBhcmVkIGxpdGVyYWxseSwgd2l0aCBubyBjYXNlIGZvbGRpbmcgcGVyZm9ybWVkLlxuICAgIHN3aXRjaCAoZmllbGQpIHtcbiAgICAgIGNhc2UgJ2V2ZW50JzpcbiAgICAgICAgLy8gU2V0IHRoZSBgZXZlbnQgdHlwZWAgYnVmZmVyIHRvIGZpZWxkIHZhbHVlXG4gICAgICAgIGV2ZW50VHlwZSA9IHZhbHVlXG4gICAgICAgIGJyZWFrXG4gICAgICBjYXNlICdkYXRhJzpcbiAgICAgICAgLy8gQXBwZW5kIHRoZSBmaWVsZCB2YWx1ZSB0byB0aGUgYGRhdGFgIGJ1ZmZlciwgdGhlbiBhcHBlbmQgYSBzaW5nbGUgVSswMDBBIExJTkUgRkVFRChMRilcbiAgICAgICAgLy8gY2hhcmFjdGVyIHRvIHRoZSBgZGF0YWAgYnVmZmVyLlxuICAgICAgICBkYXRhID0gYCR7ZGF0YX0ke3ZhbHVlfVxcbmBcbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgJ2lkJzpcbiAgICAgICAgLy8gSWYgdGhlIGZpZWxkIHZhbHVlIGRvZXMgbm90IGNvbnRhaW4gVSswMDAwIE5VTEwsIHRoZW4gc2V0IHRoZSBgSURgIGJ1ZmZlciB0b1xuICAgICAgICAvLyB0aGUgZmllbGQgdmFsdWUuIE90aGVyd2lzZSwgaWdub3JlIHRoZSBmaWVsZC5cbiAgICAgICAgaWQgPSB2YWx1ZS5pbmNsdWRlcygnXFwwJykgPyB1bmRlZmluZWQgOiB2YWx1ZVxuICAgICAgICBicmVha1xuICAgICAgY2FzZSAncmV0cnknOlxuICAgICAgICAvLyBJZiB0aGUgZmllbGQgdmFsdWUgY29uc2lzdHMgb2Ygb25seSBBU0NJSSBkaWdpdHMsIHRoZW4gaW50ZXJwcmV0IHRoZSBmaWVsZCB2YWx1ZSBhcyBhblxuICAgICAgICAvLyBpbnRlZ2VyIGluIGJhc2UgdGVuLCBhbmQgc2V0IHRoZSBldmVudCBzdHJlYW0ncyByZWNvbm5lY3Rpb24gdGltZSB0byB0aGF0IGludGVnZXIuXG4gICAgICAgIC8vIE90aGVyd2lzZSwgaWdub3JlIHRoZSBmaWVsZC5cbiAgICAgICAgaWYgKC9eXFxkKyQvLnRlc3QodmFsdWUpKSB7XG4gICAgICAgICAgb25SZXRyeShwYXJzZUludCh2YWx1ZSwgMTApKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG9uRXJyb3IoXG4gICAgICAgICAgICBuZXcgUGFyc2VFcnJvcihgSW52YWxpZCBcXGByZXRyeVxcYCB2YWx1ZTogXCIke3ZhbHVlfVwiYCwge1xuICAgICAgICAgICAgICB0eXBlOiAnaW52YWxpZC1yZXRyeScsXG4gICAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgICBsaW5lLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKVxuICAgICAgICB9XG4gICAgICAgIGJyZWFrXG4gICAgICBkZWZhdWx0OlxuICAgICAgICAvLyBPdGhlcndpc2UsIHRoZSBmaWVsZCBpcyBpZ25vcmVkLlxuICAgICAgICBvbkVycm9yKFxuICAgICAgICAgIG5ldyBQYXJzZUVycm9yKFxuICAgICAgICAgICAgYFVua25vd24gZmllbGQgXCIke2ZpZWxkLmxlbmd0aCA+IDIwID8gYCR7ZmllbGQuc2xpY2UoMCwgMjApfeKApmAgOiBmaWVsZH1cImAsXG4gICAgICAgICAgICB7dHlwZTogJ3Vua25vd24tZmllbGQnLCBmaWVsZCwgdmFsdWUsIGxpbmV9LFxuICAgICAgICAgICksXG4gICAgICAgIClcbiAgICAgICAgYnJlYWtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBkaXNwYXRjaEV2ZW50KCkge1xuICAgIGNvbnN0IHNob3VsZERpc3BhdGNoID0gZGF0YS5sZW5ndGggPiAwXG4gICAgaWYgKHNob3VsZERpc3BhdGNoKSB7XG4gICAgICBvbkV2ZW50KHtcbiAgICAgICAgaWQsXG4gICAgICAgIGV2ZW50OiBldmVudFR5cGUgfHwgdW5kZWZpbmVkLFxuICAgICAgICAvLyBJZiB0aGUgZGF0YSBidWZmZXIncyBsYXN0IGNoYXJhY3RlciBpcyBhIFUrMDAwQSBMSU5FIEZFRUQgKExGKSBjaGFyYWN0ZXIsXG4gICAgICAgIC8vIHRoZW4gcmVtb3ZlIHRoZSBsYXN0IGNoYXJhY3RlciBmcm9tIHRoZSBkYXRhIGJ1ZmZlci5cbiAgICAgICAgZGF0YTogZGF0YS5lbmRzV2l0aCgnXFxuJykgPyBkYXRhLnNsaWNlKDAsIC0xKSA6IGRhdGEsXG4gICAgICB9KVxuICAgIH1cblxuICAgIC8vIFJlc2V0IGZvciB0aGUgbmV4dCBldmVudFxuICAgIGlkID0gdW5kZWZpbmVkXG4gICAgZGF0YSA9ICcnXG4gICAgZXZlbnRUeXBlID0gJydcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlc2V0KG9wdGlvbnM6IHtjb25zdW1lPzogYm9vbGVhbn0gPSB7fSkge1xuICAgIGlmIChpbmNvbXBsZXRlTGluZSAmJiBvcHRpb25zLmNvbnN1bWUpIHtcbiAgICAgIHBhcnNlTGluZShpbmNvbXBsZXRlTGluZSlcbiAgICB9XG5cbiAgICBpc0ZpcnN0Q2h1bmsgPSB0cnVlXG4gICAgaWQgPSB1bmRlZmluZWRcbiAgICBkYXRhID0gJydcbiAgICBldmVudFR5cGUgPSAnJ1xuICAgIGluY29tcGxldGVMaW5lID0gJydcbiAgfVxuXG4gIHJldHVybiB7ZmVlZCwgcmVzZXR9XG59XG5cbi8qKlxuICogRm9yIHRoZSBnaXZlbiBgY2h1bmtgLCBzcGxpdCBpdCBpbnRvIGxpbmVzIGFjY29yZGluZyB0byBzcGVjLCBhbmQgcmV0dXJuIGFueSByZW1haW5pbmcgaW5jb21wbGV0ZSBsaW5lLlxuICpcbiAqIEBwYXJhbSBjaHVuayAtIFRoZSBjaHVuayB0byBzcGxpdCBpbnRvIGxpbmVzXG4gKiBAcmV0dXJucyBBIHR1cGxlIGNvbnRhaW5pbmcgYW4gYXJyYXkgb2YgY29tcGxldGUgbGluZXMsIGFuZCBhbnkgcmVtYWluaW5nIGluY29tcGxldGUgbGluZVxuICogQGludGVybmFsXG4gKi9cbmZ1bmN0aW9uIHNwbGl0TGluZXMoY2h1bms6IHN0cmluZyk6IFtjb21wbGV0ZTogQXJyYXk8c3RyaW5nPiwgaW5jb21wbGV0ZTogc3RyaW5nXSB7XG4gIC8qKlxuICAgKiBBY2NvcmRpbmcgdG8gdGhlIHNwZWMsIGEgbGluZSBpcyB0ZXJtaW5hdGVkIGJ5IGVpdGhlcjpcbiAgICogLSBVKzAwMEQgQ0FSUklBR0UgUkVUVVJOIFUrMDAwQSBMSU5FIEZFRUQgKENSTEYpIGNoYXJhY3RlciBwYWlyXG4gICAqIC0gYSBzaW5nbGUgVSswMDBBIExJTkUgRkVFRChMRikgY2hhcmFjdGVyIG5vdCBwcmVjZWRlZCBieSBhIFUrMDAwRCBDQVJSSUFHRSBSRVRVUk4oQ1IpIGNoYXJhY3RlclxuICAgKiAtIGEgc2luZ2xlIFUrMDAwRCBDQVJSSUFHRSBSRVRVUk4oQ1IpIGNoYXJhY3RlciBub3QgZm9sbG93ZWQgYnkgYSBVKzAwMEEgTElORSBGRUVEKExGKSBjaGFyYWN0ZXJcbiAgICovXG4gIGNvbnN0IGxpbmVzOiBBcnJheTxzdHJpbmc+ID0gW11cbiAgbGV0IGluY29tcGxldGVMaW5lID0gJydcbiAgbGV0IHNlYXJjaEluZGV4ID0gMFxuXG4gIHdoaWxlIChzZWFyY2hJbmRleCA8IGNodW5rLmxlbmd0aCkge1xuICAgIC8vIEZpbmQgbmV4dCBsaW5lIHRlcm1pbmF0b3JcbiAgICBjb25zdCBjckluZGV4ID0gY2h1bmsuaW5kZXhPZignXFxyJywgc2VhcmNoSW5kZXgpXG4gICAgY29uc3QgbGZJbmRleCA9IGNodW5rLmluZGV4T2YoJ1xcbicsIHNlYXJjaEluZGV4KVxuXG4gICAgLy8gRGV0ZXJtaW5lIGxpbmUgZW5kXG4gICAgbGV0IGxpbmVFbmQgPSAtMVxuICAgIGlmIChjckluZGV4ICE9PSAtMSAmJiBsZkluZGV4ICE9PSAtMSkge1xuICAgICAgLy8gQ1JMRiBjYXNlXG4gICAgICBsaW5lRW5kID0gTWF0aC5taW4oY3JJbmRleCwgbGZJbmRleClcbiAgICB9IGVsc2UgaWYgKGNySW5kZXggIT09IC0xKSB7XG4gICAgICAvLyBDUiBhdCB0aGUgZW5kIG9mIGEgY2h1bmsgbWlnaHQgYmUgcGFydCBvZiBhIENSTEYgc2VxdWVuY2UgdGhhdCBzcGFucyBjaHVua3MsXG4gICAgICAvLyBzbyB3ZSBzaG91bGRuJ3QgdHJlYXQgaXQgYXMgYSBsaW5lIHRlcm1pbmF0b3IgKHlldClcbiAgICAgIGlmIChjckluZGV4ID09PSBjaHVuay5sZW5ndGggLSAxKSB7XG4gICAgICAgIGxpbmVFbmQgPSAtMVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGluZUVuZCA9IGNySW5kZXhcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGxmSW5kZXggIT09IC0xKSB7XG4gICAgICBsaW5lRW5kID0gbGZJbmRleFxuICAgIH1cblxuICAgIC8vIEV4dHJhY3QgbGluZSBpZiB0ZXJtaW5hdG9yIGZvdW5kXG4gICAgaWYgKGxpbmVFbmQgPT09IC0xKSB7XG4gICAgICAvLyBObyB0ZXJtaW5hdG9yIGZvdW5kLCByZXN0IGlzIGluY29tcGxldGVcbiAgICAgIGluY29tcGxldGVMaW5lID0gY2h1bmsuc2xpY2Uoc2VhcmNoSW5kZXgpXG4gICAgICBicmVha1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBsaW5lID0gY2h1bmsuc2xpY2Uoc2VhcmNoSW5kZXgsIGxpbmVFbmQpXG4gICAgICBsaW5lcy5wdXNoKGxpbmUpXG5cbiAgICAgIC8vIE1vdmUgcGFzdCBsaW5lIHRlcm1pbmF0b3JcbiAgICAgIHNlYXJjaEluZGV4ID0gbGluZUVuZCArIDFcbiAgICAgIGlmIChjaHVua1tzZWFyY2hJbmRleCAtIDFdID09PSAnXFxyJyAmJiBjaHVua1tzZWFyY2hJbmRleF0gPT09ICdcXG4nKSB7XG4gICAgICAgIHNlYXJjaEluZGV4KytcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gW2xpbmVzLCBpbmNvbXBsZXRlTGluZV1cbn1cbiIsICJpbXBvcnQge2NyZWF0ZVBhcnNlcn0gZnJvbSAnLi9wYXJzZS50cydcbmltcG9ydCB0eXBlIHtFdmVudFNvdXJjZU1lc3NhZ2UsIEV2ZW50U291cmNlUGFyc2VyfSBmcm9tICcuL3R5cGVzLnRzJ1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHRoZSBFdmVudFNvdXJjZVBhcnNlclN0cmVhbS5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RyZWFtT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBCZWhhdmlvciB3aGVuIGEgcGFyc2luZyBlcnJvciBvY2N1cnMuXG4gICAqXG4gICAqIC0gQSBjdXN0b20gZnVuY3Rpb24gY2FuIGJlIHByb3ZpZGVkIHRvIGhhbmRsZSB0aGUgZXJyb3IuXG4gICAqIC0gYCd0ZXJtaW5hdGUnYCB3aWxsIGVycm9yIHRoZSBzdHJlYW0gYW5kIHN0b3AgcGFyc2luZy5cbiAgICogLSBBbnkgb3RoZXIgdmFsdWUgd2lsbCBpZ25vcmUgdGhlIGVycm9yIGFuZCBjb250aW51ZSBwYXJzaW5nLlxuICAgKlxuICAgKiBAZGVmYXVsdFZhbHVlIGB1bmRlZmluZWRgXG4gICAqL1xuICBvbkVycm9yPzogKCd0ZXJtaW5hdGUnIHwgKChlcnJvcjogRXJyb3IpID0+IHZvaWQpKSB8IHVuZGVmaW5lZFxuXG4gIC8qKlxuICAgKiBDYWxsYmFjayBmb3Igd2hlbiBhIHJlY29ubmVjdGlvbiBpbnRlcnZhbCBpcyBzZW50IGZyb20gdGhlIHNlcnZlci5cbiAgICpcbiAgICogQHBhcmFtIHJldHJ5IC0gVGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgdG8gd2FpdCBiZWZvcmUgcmVjb25uZWN0aW5nLlxuICAgKi9cbiAgb25SZXRyeT86ICgocmV0cnk6IG51bWJlcikgPT4gdm9pZCkgfCB1bmRlZmluZWRcblxuICAvKipcbiAgICogQ2FsbGJhY2sgZm9yIHdoZW4gYSBjb21tZW50IGlzIGVuY291bnRlcmVkIGluIHRoZSBzdHJlYW0uXG4gICAqXG4gICAqIEBwYXJhbSBjb21tZW50IC0gVGhlIGNvbW1lbnQgZW5jb3VudGVyZWQgaW4gdGhlIHN0cmVhbS5cbiAgICovXG4gIG9uQ29tbWVudD86ICgoY29tbWVudDogc3RyaW5nKSA9PiB2b2lkKSB8IHVuZGVmaW5lZFxufVxuXG4vKipcbiAqIEEgVHJhbnNmb3JtU3RyZWFtIHRoYXQgaW5nZXN0cyBhIHN0cmVhbSBvZiBzdHJpbmdzIGFuZCBwcm9kdWNlcyBhIHN0cmVhbSBvZiBgRXZlbnRTb3VyY2VNZXNzYWdlYC5cbiAqXG4gKiBAZXhhbXBsZSBCYXNpYyB1c2FnZVxuICogYGBgXG4gKiBjb25zdCBldmVudFN0cmVhbSA9XG4gKiAgIHJlc3BvbnNlLmJvZHlcbiAqICAgICAucGlwZVRocm91Z2gobmV3IFRleHREZWNvZGVyU3RyZWFtKCkpXG4gKiAgICAgLnBpcGVUaHJvdWdoKG5ldyBFdmVudFNvdXJjZVBhcnNlclN0cmVhbSgpKVxuICogYGBgXG4gKlxuICogQGV4YW1wbGUgVGVybWluYXRlIHN0cmVhbSBvbiBwYXJzaW5nIGVycm9yc1xuICogYGBgXG4gKiBjb25zdCBldmVudFN0cmVhbSA9XG4gKiAgcmVzcG9uc2UuYm9keVxuICogICAucGlwZVRocm91Z2gobmV3IFRleHREZWNvZGVyU3RyZWFtKCkpXG4gKiAgIC5waXBlVGhyb3VnaChuZXcgRXZlbnRTb3VyY2VQYXJzZXJTdHJlYW0oe3Rlcm1pbmF0ZU9uRXJyb3I6IHRydWV9KSlcbiAqIGBgYFxuICpcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNsYXNzIEV2ZW50U291cmNlUGFyc2VyU3RyZWFtIGV4dGVuZHMgVHJhbnNmb3JtU3RyZWFtPHN0cmluZywgRXZlbnRTb3VyY2VNZXNzYWdlPiB7XG4gIGNvbnN0cnVjdG9yKHtvbkVycm9yLCBvblJldHJ5LCBvbkNvbW1lbnR9OiBTdHJlYW1PcHRpb25zID0ge30pIHtcbiAgICBsZXQgcGFyc2VyITogRXZlbnRTb3VyY2VQYXJzZXJcblxuICAgIHN1cGVyKHtcbiAgICAgIHN0YXJ0KGNvbnRyb2xsZXIpIHtcbiAgICAgICAgcGFyc2VyID0gY3JlYXRlUGFyc2VyKHtcbiAgICAgICAgICBvbkV2ZW50OiAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShldmVudClcbiAgICAgICAgICB9LFxuICAgICAgICAgIG9uRXJyb3IoZXJyb3IpIHtcbiAgICAgICAgICAgIGlmIChvbkVycm9yID09PSAndGVybWluYXRlJykge1xuICAgICAgICAgICAgICBjb250cm9sbGVyLmVycm9yKGVycm9yKVxuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2Ygb25FcnJvciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICBvbkVycm9yKGVycm9yKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBJZ25vcmUgYnkgZGVmYXVsdFxuICAgICAgICAgIH0sXG4gICAgICAgICAgb25SZXRyeSxcbiAgICAgICAgICBvbkNvbW1lbnQsXG4gICAgICAgIH0pXG4gICAgICB9LFxuICAgICAgdHJhbnNmb3JtKGNodW5rKSB7XG4gICAgICAgIHBhcnNlci5mZWVkKGNodW5rKVxuICAgICAgfSxcbiAgICB9KVxuICB9XG59XG5cbmV4cG9ydCB7dHlwZSBFcnJvclR5cGUsIFBhcnNlRXJyb3J9IGZyb20gJy4vZXJyb3JzLnRzJ1xuZXhwb3J0IHR5cGUge0V2ZW50U291cmNlTWVzc2FnZX0gZnJvbSAnLi90eXBlcy50cydcbiIsICJleHBvcnQgKiBhcyBjb3JlIGZyb20gXCIuLi9jb3JlL2luZGV4LmpzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9zY2hlbWFzLmpzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGVja3MuanNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2Vycm9ycy5qc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vcGFyc2UuanNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvbXBhdC5qc1wiO1xuLy8gem9kLXNwZWNpZmllZFxuaW1wb3J0IHsgY29uZmlnIH0gZnJvbSBcIi4uL2NvcmUvaW5kZXguanNcIjtcbmltcG9ydCBlbiBmcm9tIFwiLi4vbG9jYWxlcy9lbi5qc1wiO1xuY29uZmlnKGVuKCkpO1xuZXhwb3J0IHsgZ2xvYmFsUmVnaXN0cnksIHJlZ2lzdHJ5LCBjb25maWcsICRvdXRwdXQsICRpbnB1dCwgJGJyYW5kLCBjbG9uZSwgcmVnZXhlcywgdHJlZWlmeUVycm9yLCBwcmV0dGlmeUVycm9yLCBmb3JtYXRFcnJvciwgZmxhdHRlbkVycm9yLCB0b0pTT05TY2hlbWEsIFRpbWVQcmVjaXNpb24sIHV0aWwsIE5FVkVSIH0gZnJvbSBcIi4uL2NvcmUvaW5kZXguanNcIjtcbmV4cG9ydCAqIGFzIGxvY2FsZXMgZnJvbSBcIi4uL2xvY2FsZXMvaW5kZXguanNcIjtcbi8vIGlzb1xuLy8gbXVzdCBiZSBleHBvcnRlZCBmcm9tIHRvcC1sZXZlbFxuLy8gaHR0cHM6Ly9naXRodWIuY29tL2NvbGluaGFja3Mvem9kL2lzc3Vlcy80NDkxXG5leHBvcnQgeyBab2RJU09EYXRlVGltZSwgWm9kSVNPRGF0ZSwgWm9kSVNPVGltZSwgWm9kSVNPRHVyYXRpb24gfSBmcm9tIFwiLi9pc28uanNcIjtcbmV4cG9ydCAqIGFzIGlzbyBmcm9tIFwiLi9pc28uanNcIjtcbmV4cG9ydCAqIGFzIGNvZXJjZSBmcm9tIFwiLi9jb2VyY2UuanNcIjtcbiIsICJleHBvcnQgKiBmcm9tIFwiLi9jb3JlLmpzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9wYXJzZS5qc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vZXJyb3JzLmpzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9zY2hlbWFzLmpzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGVja3MuanNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3ZlcnNpb25zLmpzXCI7XG5leHBvcnQgKiBhcyB1dGlsIGZyb20gXCIuL3V0aWwuanNcIjtcbmV4cG9ydCAqIGFzIHJlZ2V4ZXMgZnJvbSBcIi4vcmVnZXhlcy5qc1wiO1xuZXhwb3J0ICogYXMgbG9jYWxlcyBmcm9tIFwiLi4vbG9jYWxlcy9pbmRleC5qc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vcmVnaXN0cmllcy5qc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vZG9jLmpzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9hcGkuanNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3RvLWpzb24tc2NoZW1hLmpzXCI7XG5leHBvcnQgKiBhcyBKU09OU2NoZW1hIGZyb20gXCIuL2pzb24tc2NoZW1hLmpzXCI7XG4iLCAiLyoqIEEgc3BlY2lhbCBjb25zdGFudCB3aXRoIHR5cGUgYG5ldmVyYCAqLyBleHBvcnQgY29uc3QgTkVWRVIgPSBPYmplY3QuZnJlZXplKHtcbiAgICBzdGF0dXM6IFwiYWJvcnRlZFwiXG59KTtcbmV4cG9ydCAvKkBfX05PX1NJREVfRUZGRUNUU19fKi8gZnVuY3Rpb24gJGNvbnN0cnVjdG9yKG5hbWUsIGluaXRpYWxpemVyLCBwYXJhbXMpIHtcbiAgICBmdW5jdGlvbiBpbml0KGluc3QsIGRlZikge1xuICAgICAgICB2YXIgX2E7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShpbnN0LCBcIl96b2RcIiwge1xuICAgICAgICAgICAgdmFsdWU6IGluc3QuX3pvZCA/PyB7fSxcbiAgICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlXG4gICAgICAgIH0pO1xuICAgICAgICAoX2EgPSBpbnN0Ll96b2QpLnRyYWl0cyA/PyAoX2EudHJhaXRzID0gbmV3IFNldCgpKTtcbiAgICAgICAgaW5zdC5fem9kLnRyYWl0cy5hZGQobmFtZSk7XG4gICAgICAgIGluaXRpYWxpemVyKGluc3QsIGRlZik7XG4gICAgICAgIC8vIHN1cHBvcnQgcHJvdG90eXBlIG1vZGlmaWNhdGlvbnNcbiAgICAgICAgZm9yKGNvbnN0IGsgaW4gXy5wcm90b3R5cGUpe1xuICAgICAgICAgICAgaWYgKCEoayBpbiBpbnN0KSkgT2JqZWN0LmRlZmluZVByb3BlcnR5KGluc3QsIGssIHtcbiAgICAgICAgICAgICAgICB2YWx1ZTogXy5wcm90b3R5cGVba10uYmluZChpbnN0KVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaW5zdC5fem9kLmNvbnN0ciA9IF87XG4gICAgICAgIGluc3QuX3pvZC5kZWYgPSBkZWY7XG4gICAgfVxuICAgIC8vIGRvZXNuJ3Qgd29yayBpZiBQYXJlbnQgaGFzIGEgY29uc3RydWN0b3Igd2l0aCBhcmd1bWVudHNcbiAgICBjb25zdCBQYXJlbnQgPSBwYXJhbXM/LlBhcmVudCA/PyBPYmplY3Q7XG4gICAgY2xhc3MgRGVmaW5pdGlvbiBleHRlbmRzIFBhcmVudCB7XG4gICAgfVxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShEZWZpbml0aW9uLCBcIm5hbWVcIiwge1xuICAgICAgICB2YWx1ZTogbmFtZVxuICAgIH0pO1xuICAgIGZ1bmN0aW9uIF8oZGVmKSB7XG4gICAgICAgIHZhciBfYTtcbiAgICAgICAgY29uc3QgaW5zdCA9IHBhcmFtcz8uUGFyZW50ID8gbmV3IERlZmluaXRpb24oKSA6IHRoaXM7XG4gICAgICAgIGluaXQoaW5zdCwgZGVmKTtcbiAgICAgICAgKF9hID0gaW5zdC5fem9kKS5kZWZlcnJlZCA/PyAoX2EuZGVmZXJyZWQgPSBbXSk7XG4gICAgICAgIGZvciAoY29uc3QgZm4gb2YgaW5zdC5fem9kLmRlZmVycmVkKXtcbiAgICAgICAgICAgIGZuKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGluc3Q7XG4gICAgfVxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShfLCBcImluaXRcIiwge1xuICAgICAgICB2YWx1ZTogaW5pdFxuICAgIH0pO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShfLCBTeW1ib2wuaGFzSW5zdGFuY2UsIHtcbiAgICAgICAgdmFsdWU6IChpbnN0KT0+e1xuICAgICAgICAgICAgaWYgKHBhcmFtcz8uUGFyZW50ICYmIGluc3QgaW5zdGFuY2VvZiBwYXJhbXMuUGFyZW50KSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIHJldHVybiBpbnN0Py5fem9kPy50cmFpdHM/LmhhcyhuYW1lKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShfLCBcIm5hbWVcIiwge1xuICAgICAgICB2YWx1ZTogbmFtZVxuICAgIH0pO1xuICAgIHJldHVybiBfO1xufVxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vICAgVVRJTElUSUVTICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5leHBvcnQgY29uc3QgJGJyYW5kID0gU3ltYm9sKFwiem9kX2JyYW5kXCIpO1xuZXhwb3J0IGNsYXNzICRab2RBc3luY0Vycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAgIGNvbnN0cnVjdG9yKCl7XG4gICAgICAgIHN1cGVyKGBFbmNvdW50ZXJlZCBQcm9taXNlIGR1cmluZyBzeW5jaHJvbm91cyBwYXJzZS4gVXNlIC5wYXJzZUFzeW5jKCkgaW5zdGVhZC5gKTtcbiAgICB9XG59XG5leHBvcnQgY2xhc3MgJFpvZEVuY29kZUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAgIGNvbnN0cnVjdG9yKG5hbWUpe1xuICAgICAgICBzdXBlcihgRW5jb3VudGVyZWQgdW5pZGlyZWN0aW9uYWwgdHJhbnNmb3JtIGR1cmluZyBlbmNvZGU6ICR7bmFtZX1gKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJab2RFbmNvZGVFcnJvclwiO1xuICAgIH1cbn1cbmV4cG9ydCBjb25zdCBnbG9iYWxDb25maWcgPSB7fTtcbmV4cG9ydCBmdW5jdGlvbiBjb25maWcobmV3Q29uZmlnKSB7XG4gICAgaWYgKG5ld0NvbmZpZykgT2JqZWN0LmFzc2lnbihnbG9iYWxDb25maWcsIG5ld0NvbmZpZyk7XG4gICAgcmV0dXJuIGdsb2JhbENvbmZpZztcbn1cbiIsICIvLyBmdW5jdGlvbnNcbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnRFcXVhbCh2YWwpIHtcbiAgICByZXR1cm4gdmFsO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydE5vdEVxdWFsKHZhbCkge1xuICAgIHJldHVybiB2YWw7XG59XG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0SXMoX2FyZykge31cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnROZXZlcihfeCkge1xuICAgIHRocm93IG5ldyBFcnJvcigpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydChfKSB7fVxuZXhwb3J0IGZ1bmN0aW9uIGdldEVudW1WYWx1ZXMoZW50cmllcykge1xuICAgIGNvbnN0IG51bWVyaWNWYWx1ZXMgPSBPYmplY3QudmFsdWVzKGVudHJpZXMpLmZpbHRlcigodik9PnR5cGVvZiB2ID09PSBcIm51bWJlclwiKTtcbiAgICBjb25zdCB2YWx1ZXMgPSBPYmplY3QuZW50cmllcyhlbnRyaWVzKS5maWx0ZXIoKFtrLCBfXSk9Pm51bWVyaWNWYWx1ZXMuaW5kZXhPZigraykgPT09IC0xKS5tYXAoKFtfLCB2XSk9PnYpO1xuICAgIHJldHVybiB2YWx1ZXM7XG59XG5leHBvcnQgZnVuY3Rpb24gam9pblZhbHVlcyhhcnJheSwgc2VwYXJhdG9yID0gXCJ8XCIpIHtcbiAgICByZXR1cm4gYXJyYXkubWFwKCh2YWwpPT5zdHJpbmdpZnlQcmltaXRpdmUodmFsKSkuam9pbihzZXBhcmF0b3IpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGpzb25TdHJpbmdpZnlSZXBsYWNlcihfLCB2YWx1ZSkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwiYmlnaW50XCIpIHJldHVybiB2YWx1ZS50b1N0cmluZygpO1xuICAgIHJldHVybiB2YWx1ZTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBjYWNoZWQoZ2V0dGVyKSB7XG4gICAgY29uc3Qgc2V0ID0gZmFsc2U7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgZ2V0IHZhbHVlICgpIHtcbiAgICAgICAgICAgIGlmICghc2V0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBnZXR0ZXIoKTtcbiAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgXCJ2YWx1ZVwiLCB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiY2FjaGVkIHZhbHVlIGFscmVhZHkgc2V0XCIpO1xuICAgICAgICB9XG4gICAgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBudWxsaXNoKGlucHV0KSB7XG4gICAgcmV0dXJuIGlucHV0ID09PSBudWxsIHx8IGlucHV0ID09PSB1bmRlZmluZWQ7XG59XG5leHBvcnQgZnVuY3Rpb24gY2xlYW5SZWdleChzb3VyY2UpIHtcbiAgICBjb25zdCBzdGFydCA9IHNvdXJjZS5zdGFydHNXaXRoKFwiXlwiKSA/IDEgOiAwO1xuICAgIGNvbnN0IGVuZCA9IHNvdXJjZS5lbmRzV2l0aChcIiRcIikgPyBzb3VyY2UubGVuZ3RoIC0gMSA6IHNvdXJjZS5sZW5ndGg7XG4gICAgcmV0dXJuIHNvdXJjZS5zbGljZShzdGFydCwgZW5kKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBmbG9hdFNhZmVSZW1haW5kZXIodmFsLCBzdGVwKSB7XG4gICAgY29uc3QgdmFsRGVjQ291bnQgPSAodmFsLnRvU3RyaW5nKCkuc3BsaXQoXCIuXCIpWzFdIHx8IFwiXCIpLmxlbmd0aDtcbiAgICBjb25zdCBzdGVwU3RyaW5nID0gc3RlcC50b1N0cmluZygpO1xuICAgIGxldCBzdGVwRGVjQ291bnQgPSAoc3RlcFN0cmluZy5zcGxpdChcIi5cIilbMV0gfHwgXCJcIikubGVuZ3RoO1xuICAgIGlmIChzdGVwRGVjQ291bnQgPT09IDAgJiYgL1xcZD9lLVxcZD8vLnRlc3Qoc3RlcFN0cmluZykpIHtcbiAgICAgICAgY29uc3QgbWF0Y2ggPSBzdGVwU3RyaW5nLm1hdGNoKC9cXGQ/ZS0oXFxkPykvKTtcbiAgICAgICAgaWYgKG1hdGNoPy5bMV0pIHtcbiAgICAgICAgICAgIHN0ZXBEZWNDb3VudCA9IE51bWJlci5wYXJzZUludChtYXRjaFsxXSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgZGVjQ291bnQgPSB2YWxEZWNDb3VudCA+IHN0ZXBEZWNDb3VudCA/IHZhbERlY0NvdW50IDogc3RlcERlY0NvdW50O1xuICAgIGNvbnN0IHZhbEludCA9IE51bWJlci5wYXJzZUludCh2YWwudG9GaXhlZChkZWNDb3VudCkucmVwbGFjZShcIi5cIiwgXCJcIikpO1xuICAgIGNvbnN0IHN0ZXBJbnQgPSBOdW1iZXIucGFyc2VJbnQoc3RlcC50b0ZpeGVkKGRlY0NvdW50KS5yZXBsYWNlKFwiLlwiLCBcIlwiKSk7XG4gICAgcmV0dXJuIHZhbEludCAlIHN0ZXBJbnQgLyAxMCAqKiBkZWNDb3VudDtcbn1cbmNvbnN0IEVWQUxVQVRJTkcgPSBTeW1ib2woXCJldmFsdWF0aW5nXCIpO1xuZXhwb3J0IGZ1bmN0aW9uIGRlZmluZUxhenkob2JqZWN0LCBrZXksIGdldHRlcikge1xuICAgIGxldCB2YWx1ZSA9IHVuZGVmaW5lZDtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqZWN0LCBrZXksIHtcbiAgICAgICAgZ2V0ICgpIHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gRVZBTFVBVElORykge1xuICAgICAgICAgICAgICAgIC8vIENpcmN1bGFyIHJlZmVyZW5jZSBkZXRlY3RlZCwgcmV0dXJuIHVuZGVmaW5lZCB0byBicmVhayB0aGUgY3ljbGVcbiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IEVWQUxVQVRJTkc7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBnZXR0ZXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfSxcbiAgICAgICAgc2V0ICh2KSB7XG4gICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqZWN0LCBrZXksIHtcbiAgICAgICAgICAgICAgICB2YWx1ZTogdlxuICAgICAgICAgICAgfSk7XG4gICAgICAgIC8vIG9iamVjdFtrZXldID0gdjtcbiAgICAgICAgfSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gb2JqZWN0Q2xvbmUob2JqKSB7XG4gICAgcmV0dXJuIE9iamVjdC5jcmVhdGUoT2JqZWN0LmdldFByb3RvdHlwZU9mKG9iaiksIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKG9iaikpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGFzc2lnblByb3AodGFyZ2V0LCBwcm9wLCB2YWx1ZSkge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIHByb3AsIHtcbiAgICAgICAgdmFsdWUsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBtZXJnZURlZnMoLi4uZGVmcykge1xuICAgIGNvbnN0IG1lcmdlZERlc2NyaXB0b3JzID0ge307XG4gICAgZm9yIChjb25zdCBkZWYgb2YgZGVmcyl7XG4gICAgICAgIGNvbnN0IGRlc2NyaXB0b3JzID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMoZGVmKTtcbiAgICAgICAgT2JqZWN0LmFzc2lnbihtZXJnZWREZXNjcmlwdG9ycywgZGVzY3JpcHRvcnMpO1xuICAgIH1cbiAgICByZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoe30sIG1lcmdlZERlc2NyaXB0b3JzKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBjbG9uZURlZihzY2hlbWEpIHtcbiAgICByZXR1cm4gbWVyZ2VEZWZzKHNjaGVtYS5fem9kLmRlZik7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2V0RWxlbWVudEF0UGF0aChvYmosIHBhdGgpIHtcbiAgICBpZiAoIXBhdGgpIHJldHVybiBvYmo7XG4gICAgcmV0dXJuIHBhdGgucmVkdWNlKChhY2MsIGtleSk9PmFjYz8uW2tleV0sIG9iaik7XG59XG5leHBvcnQgZnVuY3Rpb24gcHJvbWlzZUFsbE9iamVjdChwcm9taXNlc09iaikge1xuICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhwcm9taXNlc09iaik7XG4gICAgY29uc3QgcHJvbWlzZXMgPSBrZXlzLm1hcCgoa2V5KT0+cHJvbWlzZXNPYmpba2V5XSk7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKChyZXN1bHRzKT0+e1xuICAgICAgICBjb25zdCByZXNvbHZlZE9iaiA9IHt9O1xuICAgICAgICBmb3IobGV0IGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKyl7XG4gICAgICAgICAgICByZXNvbHZlZE9ialtrZXlzW2ldXSA9IHJlc3VsdHNbaV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc29sdmVkT2JqO1xuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHJhbmRvbVN0cmluZyhsZW5ndGggPSAxMCkge1xuICAgIGNvbnN0IGNoYXJzID0gXCJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5elwiO1xuICAgIGxldCBzdHIgPSBcIlwiO1xuICAgIGZvcihsZXQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKyl7XG4gICAgICAgIHN0ciArPSBjaGFyc1tNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBjaGFycy5sZW5ndGgpXTtcbiAgICB9XG4gICAgcmV0dXJuIHN0cjtcbn1cbmV4cG9ydCBmdW5jdGlvbiBlc2Moc3RyKSB7XG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHN0cik7XG59XG5leHBvcnQgY29uc3QgY2FwdHVyZVN0YWNrVHJhY2UgPSBcImNhcHR1cmVTdGFja1RyYWNlXCIgaW4gRXJyb3IgPyBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSA6ICguLi5fYXJncyk9Pnt9O1xuZXhwb3J0IGZ1bmN0aW9uIGlzT2JqZWN0KGRhdGEpIHtcbiAgICByZXR1cm4gdHlwZW9mIGRhdGEgPT09IFwib2JqZWN0XCIgJiYgZGF0YSAhPT0gbnVsbCAmJiAhQXJyYXkuaXNBcnJheShkYXRhKTtcbn1cbmV4cG9ydCBjb25zdCBhbGxvd3NFdmFsID0gY2FjaGVkKCgpPT57XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIGlmICh0eXBlb2YgbmF2aWdhdG9yICE9PSBcInVuZGVmaW5lZFwiICYmIG5hdmlnYXRvcj8udXNlckFnZW50Py5pbmNsdWRlcyhcIkNsb3VkZmxhcmVcIikpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICBjb25zdCBGID0gRnVuY3Rpb247XG4gICAgICAgIG5ldyBGKFwiXCIpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChfKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBpc1BsYWluT2JqZWN0KG8pIHtcbiAgICBpZiAoaXNPYmplY3QobykgPT09IGZhbHNlKSByZXR1cm4gZmFsc2U7XG4gICAgLy8gbW9kaWZpZWQgY29uc3RydWN0b3JcbiAgICBjb25zdCBjdG9yID0gby5jb25zdHJ1Y3RvcjtcbiAgICBpZiAoY3RvciA9PT0gdW5kZWZpbmVkKSByZXR1cm4gdHJ1ZTtcbiAgICAvLyBtb2RpZmllZCBwcm90b3R5cGVcbiAgICBjb25zdCBwcm90ID0gY3Rvci5wcm90b3R5cGU7XG4gICAgaWYgKGlzT2JqZWN0KHByb3QpID09PSBmYWxzZSkgcmV0dXJuIGZhbHNlO1xuICAgIC8vIGN0b3IgZG9lc24ndCBoYXZlIHN0YXRpYyBgaXNQcm90b3R5cGVPZmBcbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHByb3QsIFwiaXNQcm90b3R5cGVPZlwiKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBzaGFsbG93Q2xvbmUobykge1xuICAgIGlmIChpc1BsYWluT2JqZWN0KG8pKSByZXR1cm4ge1xuICAgICAgICAuLi5vXG4gICAgfTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShvKSkgcmV0dXJuIFtcbiAgICAgICAgLi4ub1xuICAgIF07XG4gICAgcmV0dXJuIG87XG59XG5leHBvcnQgZnVuY3Rpb24gbnVtS2V5cyhkYXRhKSB7XG4gICAgbGV0IGtleUNvdW50ID0gMDtcbiAgICBmb3IoY29uc3Qga2V5IGluIGRhdGEpe1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGRhdGEsIGtleSkpIHtcbiAgICAgICAgICAgIGtleUNvdW50Kys7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGtleUNvdW50O1xufVxuZXhwb3J0IGNvbnN0IGdldFBhcnNlZFR5cGUgPSAoZGF0YSk9PntcbiAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgc3dpdGNoKHQpe1xuICAgICAgICBjYXNlIFwidW5kZWZpbmVkXCI6XG4gICAgICAgICAgICByZXR1cm4gXCJ1bmRlZmluZWRcIjtcbiAgICAgICAgY2FzZSBcInN0cmluZ1wiOlxuICAgICAgICAgICAgcmV0dXJuIFwic3RyaW5nXCI7XG4gICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIm5hblwiIDogXCJudW1iZXJcIjtcbiAgICAgICAgY2FzZSBcImJvb2xlYW5cIjpcbiAgICAgICAgICAgIHJldHVybiBcImJvb2xlYW5cIjtcbiAgICAgICAgY2FzZSBcImZ1bmN0aW9uXCI6XG4gICAgICAgICAgICByZXR1cm4gXCJmdW5jdGlvblwiO1xuICAgICAgICBjYXNlIFwiYmlnaW50XCI6XG4gICAgICAgICAgICByZXR1cm4gXCJiaWdpbnRcIjtcbiAgICAgICAgY2FzZSBcInN5bWJvbFwiOlxuICAgICAgICAgICAgcmV0dXJuIFwic3ltYm9sXCI7XG4gICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiYXJyYXlcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGRhdGEudGhlbiAmJiB0eXBlb2YgZGF0YS50aGVuID09PSBcImZ1bmN0aW9uXCIgJiYgZGF0YS5jYXRjaCAmJiB0eXBlb2YgZGF0YS5jYXRjaCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwicHJvbWlzZVwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGVvZiBNYXAgIT09IFwidW5kZWZpbmVkXCIgJiYgZGF0YSBpbnN0YW5jZW9mIE1hcCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBcIm1hcFwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGVvZiBTZXQgIT09IFwidW5kZWZpbmVkXCIgJiYgZGF0YSBpbnN0YW5jZW9mIFNldCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBcInNldFwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGVvZiBEYXRlICE9PSBcInVuZGVmaW5lZFwiICYmIGRhdGEgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiZGF0ZVwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgaWYgKHR5cGVvZiBGaWxlICE9PSBcInVuZGVmaW5lZFwiICYmIGRhdGEgaW5zdGFuY2VvZiBGaWxlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiZmlsZVwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIFwib2JqZWN0XCI7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gZGF0YSB0eXBlOiAke3R9YCk7XG4gICAgfVxufTtcbmV4cG9ydCBjb25zdCBwcm9wZXJ0eUtleVR5cGVzID0gbmV3IFNldChbXG4gICAgXCJzdHJpbmdcIixcbiAgICBcIm51bWJlclwiLFxuICAgIFwic3ltYm9sXCJcbl0pO1xuZXhwb3J0IGNvbnN0IHByaW1pdGl2ZVR5cGVzID0gbmV3IFNldChbXG4gICAgXCJzdHJpbmdcIixcbiAgICBcIm51bWJlclwiLFxuICAgIFwiYmlnaW50XCIsXG4gICAgXCJib29sZWFuXCIsXG4gICAgXCJzeW1ib2xcIixcbiAgICBcInVuZGVmaW5lZFwiXG5dKTtcbmV4cG9ydCBmdW5jdGlvbiBlc2NhcGVSZWdleChzdHIpIHtcbiAgICByZXR1cm4gc3RyLnJlcGxhY2UoL1suKis/XiR7fSgpfFtcXF1cXFxcXS9nLCBcIlxcXFwkJlwiKTtcbn1cbi8vIHpvZC1zcGVjaWZpYyB1dGlsc1xuZXhwb3J0IGZ1bmN0aW9uIGNsb25lKGluc3QsIGRlZiwgcGFyYW1zKSB7XG4gICAgY29uc3QgY2wgPSBuZXcgaW5zdC5fem9kLmNvbnN0cihkZWYgPz8gaW5zdC5fem9kLmRlZik7XG4gICAgaWYgKCFkZWYgfHwgcGFyYW1zPy5wYXJlbnQpIGNsLl96b2QucGFyZW50ID0gaW5zdDtcbiAgICByZXR1cm4gY2w7XG59XG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplUGFyYW1zKF9wYXJhbXMpIHtcbiAgICBjb25zdCBwYXJhbXMgPSBfcGFyYW1zO1xuICAgIGlmICghcGFyYW1zKSByZXR1cm4ge307XG4gICAgaWYgKHR5cGVvZiBwYXJhbXMgPT09IFwic3RyaW5nXCIpIHJldHVybiB7XG4gICAgICAgIGVycm9yOiAoKT0+cGFyYW1zXG4gICAgfTtcbiAgICBpZiAocGFyYW1zPy5tZXNzYWdlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKHBhcmFtcz8uZXJyb3IgIT09IHVuZGVmaW5lZCkgdGhyb3cgbmV3IEVycm9yKFwiQ2Fubm90IHNwZWNpZnkgYm90aCBgbWVzc2FnZWAgYW5kIGBlcnJvcmAgcGFyYW1zXCIpO1xuICAgICAgICBwYXJhbXMuZXJyb3IgPSBwYXJhbXMubWVzc2FnZTtcbiAgICB9XG4gICAgZGVsZXRlIHBhcmFtcy5tZXNzYWdlO1xuICAgIGlmICh0eXBlb2YgcGFyYW1zLmVycm9yID09PSBcInN0cmluZ1wiKSByZXR1cm4ge1xuICAgICAgICAuLi5wYXJhbXMsXG4gICAgICAgIGVycm9yOiAoKT0+cGFyYW1zLmVycm9yXG4gICAgfTtcbiAgICByZXR1cm4gcGFyYW1zO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVRyYW5zcGFyZW50UHJveHkoZ2V0dGVyKSB7XG4gICAgbGV0IHRhcmdldDtcbiAgICByZXR1cm4gbmV3IFByb3h5KHt9LCB7XG4gICAgICAgIGdldCAoXywgcHJvcCwgcmVjZWl2ZXIpIHtcbiAgICAgICAgICAgIHRhcmdldCA/PyAodGFyZ2V0ID0gZ2V0dGVyKCkpO1xuICAgICAgICAgICAgcmV0dXJuIFJlZmxlY3QuZ2V0KHRhcmdldCwgcHJvcCwgcmVjZWl2ZXIpO1xuICAgICAgICB9LFxuICAgICAgICBzZXQgKF8sIHByb3AsIHZhbHVlLCByZWNlaXZlcikge1xuICAgICAgICAgICAgdGFyZ2V0ID8/ICh0YXJnZXQgPSBnZXR0ZXIoKSk7XG4gICAgICAgICAgICByZXR1cm4gUmVmbGVjdC5zZXQodGFyZ2V0LCBwcm9wLCB2YWx1ZSwgcmVjZWl2ZXIpO1xuICAgICAgICB9LFxuICAgICAgICBoYXMgKF8sIHByb3ApIHtcbiAgICAgICAgICAgIHRhcmdldCA/PyAodGFyZ2V0ID0gZ2V0dGVyKCkpO1xuICAgICAgICAgICAgcmV0dXJuIFJlZmxlY3QuaGFzKHRhcmdldCwgcHJvcCk7XG4gICAgICAgIH0sXG4gICAgICAgIGRlbGV0ZVByb3BlcnR5IChfLCBwcm9wKSB7XG4gICAgICAgICAgICB0YXJnZXQgPz8gKHRhcmdldCA9IGdldHRlcigpKTtcbiAgICAgICAgICAgIHJldHVybiBSZWZsZWN0LmRlbGV0ZVByb3BlcnR5KHRhcmdldCwgcHJvcCk7XG4gICAgICAgIH0sXG4gICAgICAgIG93bktleXMgKF8pIHtcbiAgICAgICAgICAgIHRhcmdldCA/PyAodGFyZ2V0ID0gZ2V0dGVyKCkpO1xuICAgICAgICAgICAgcmV0dXJuIFJlZmxlY3Qub3duS2V5cyh0YXJnZXQpO1xuICAgICAgICB9LFxuICAgICAgICBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgKF8sIHByb3ApIHtcbiAgICAgICAgICAgIHRhcmdldCA/PyAodGFyZ2V0ID0gZ2V0dGVyKCkpO1xuICAgICAgICAgICAgcmV0dXJuIFJlZmxlY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwgcHJvcCk7XG4gICAgICAgIH0sXG4gICAgICAgIGRlZmluZVByb3BlcnR5IChfLCBwcm9wLCBkZXNjcmlwdG9yKSB7XG4gICAgICAgICAgICB0YXJnZXQgPz8gKHRhcmdldCA9IGdldHRlcigpKTtcbiAgICAgICAgICAgIHJldHVybiBSZWZsZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgcHJvcCwgZGVzY3JpcHRvcik7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBzdHJpbmdpZnlQcmltaXRpdmUodmFsdWUpIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcImJpZ2ludFwiKSByZXR1cm4gdmFsdWUudG9TdHJpbmcoKSArIFwiblwiO1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIpIHJldHVybiBgXCIke3ZhbHVlfVwiYDtcbiAgICByZXR1cm4gYCR7dmFsdWV9YDtcbn1cbmV4cG9ydCBmdW5jdGlvbiBvcHRpb25hbEtleXMoc2hhcGUpIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXMoc2hhcGUpLmZpbHRlcigoayk9PntcbiAgICAgICAgcmV0dXJuIHNoYXBlW2tdLl96b2Qub3B0aW4gPT09IFwib3B0aW9uYWxcIiAmJiBzaGFwZVtrXS5fem9kLm9wdG91dCA9PT0gXCJvcHRpb25hbFwiO1xuICAgIH0pO1xufVxuZXhwb3J0IGNvbnN0IE5VTUJFUl9GT1JNQVRfUkFOR0VTID0ge1xuICAgIHNhZmVpbnQ6IFtcbiAgICAgICAgTnVtYmVyLk1JTl9TQUZFX0lOVEVHRVIsXG4gICAgICAgIE51bWJlci5NQVhfU0FGRV9JTlRFR0VSXG4gICAgXSxcbiAgICBpbnQzMjogW1xuICAgICAgICAtMjE0NzQ4MzY0OCxcbiAgICAgICAgMjE0NzQ4MzY0N1xuICAgIF0sXG4gICAgdWludDMyOiBbXG4gICAgICAgIDAsXG4gICAgICAgIDQyOTQ5NjcyOTVcbiAgICBdLFxuICAgIGZsb2F0MzI6IFtcbiAgICAgICAgLTMuNDAyODIzNDY2Mzg1Mjg4NmUzOCxcbiAgICAgICAgMy40MDI4MjM0NjYzODUyODg2ZTM4XG4gICAgXSxcbiAgICBmbG9hdDY0OiBbXG4gICAgICAgIC1OdW1iZXIuTUFYX1ZBTFVFLFxuICAgICAgICBOdW1iZXIuTUFYX1ZBTFVFXG4gICAgXVxufTtcbmV4cG9ydCBjb25zdCBCSUdJTlRfRk9STUFUX1JBTkdFUyA9IHtcbiAgICBpbnQ2NDogW1xuICAgICAgICAvKiBAX19QVVJFX18qLyBCaWdJbnQoXCItOTIyMzM3MjAzNjg1NDc3NTgwOFwiKSxcbiAgICAgICAgLyogQF9fUFVSRV9fKi8gQmlnSW50KFwiOTIyMzM3MjAzNjg1NDc3NTgwN1wiKVxuICAgIF0sXG4gICAgdWludDY0OiBbXG4gICAgICAgIC8qIEBfX1BVUkVfXyovIEJpZ0ludCgwKSxcbiAgICAgICAgLyogQF9fUFVSRV9fKi8gQmlnSW50KFwiMTg0NDY3NDQwNzM3MDk1NTE2MTVcIilcbiAgICBdXG59O1xuZXhwb3J0IGZ1bmN0aW9uIHBpY2soc2NoZW1hLCBtYXNrKSB7XG4gICAgY29uc3QgY3VyckRlZiA9IHNjaGVtYS5fem9kLmRlZjtcbiAgICBjb25zdCBkZWYgPSBtZXJnZURlZnMoc2NoZW1hLl96b2QuZGVmLCB7XG4gICAgICAgIGdldCBzaGFwZSAoKSB7XG4gICAgICAgICAgICBjb25zdCBuZXdTaGFwZSA9IHt9O1xuICAgICAgICAgICAgZm9yKGNvbnN0IGtleSBpbiBtYXNrKXtcbiAgICAgICAgICAgICAgICBpZiAoIShrZXkgaW4gY3VyckRlZi5zaGFwZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnJlY29nbml6ZWQga2V5OiBcIiR7a2V5fVwiYCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghbWFza1trZXldKSBjb250aW51ZTtcbiAgICAgICAgICAgICAgICBuZXdTaGFwZVtrZXldID0gY3VyckRlZi5zaGFwZVtrZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXNzaWduUHJvcCh0aGlzLCBcInNoYXBlXCIsIG5ld1NoYXBlKTsgLy8gc2VsZi1jYWNoaW5nXG4gICAgICAgICAgICByZXR1cm4gbmV3U2hhcGU7XG4gICAgICAgIH0sXG4gICAgICAgIGNoZWNrczogW11cbiAgICB9KTtcbiAgICByZXR1cm4gY2xvbmUoc2NoZW1hLCBkZWYpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIG9taXQoc2NoZW1hLCBtYXNrKSB7XG4gICAgY29uc3QgY3VyckRlZiA9IHNjaGVtYS5fem9kLmRlZjtcbiAgICBjb25zdCBkZWYgPSBtZXJnZURlZnMoc2NoZW1hLl96b2QuZGVmLCB7XG4gICAgICAgIGdldCBzaGFwZSAoKSB7XG4gICAgICAgICAgICBjb25zdCBuZXdTaGFwZSA9IHtcbiAgICAgICAgICAgICAgICAuLi5zY2hlbWEuX3pvZC5kZWYuc2hhcGVcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBmb3IoY29uc3Qga2V5IGluIG1hc2spe1xuICAgICAgICAgICAgICAgIGlmICghKGtleSBpbiBjdXJyRGVmLnNoYXBlKSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVucmVjb2duaXplZCBrZXk6IFwiJHtrZXl9XCJgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCFtYXNrW2tleV0pIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBuZXdTaGFwZVtrZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXNzaWduUHJvcCh0aGlzLCBcInNoYXBlXCIsIG5ld1NoYXBlKTsgLy8gc2VsZi1jYWNoaW5nXG4gICAgICAgICAgICByZXR1cm4gbmV3U2hhcGU7XG4gICAgICAgIH0sXG4gICAgICAgIGNoZWNrczogW11cbiAgICB9KTtcbiAgICByZXR1cm4gY2xvbmUoc2NoZW1hLCBkZWYpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGV4dGVuZChzY2hlbWEsIHNoYXBlKSB7XG4gICAgaWYgKCFpc1BsYWluT2JqZWN0KHNoYXBlKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGlucHV0IHRvIGV4dGVuZDogZXhwZWN0ZWQgYSBwbGFpbiBvYmplY3RcIik7XG4gICAgfVxuICAgIGNvbnN0IGNoZWNrcyA9IHNjaGVtYS5fem9kLmRlZi5jaGVja3M7XG4gICAgY29uc3QgaGFzQ2hlY2tzID0gY2hlY2tzICYmIGNoZWNrcy5sZW5ndGggPiAwO1xuICAgIGlmIChoYXNDaGVja3MpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiT2JqZWN0IHNjaGVtYXMgY29udGFpbmluZyByZWZpbmVtZW50cyBjYW5ub3QgYmUgZXh0ZW5kZWQuIFVzZSBgLnNhZmVFeHRlbmQoKWAgaW5zdGVhZC5cIik7XG4gICAgfVxuICAgIGNvbnN0IGRlZiA9IG1lcmdlRGVmcyhzY2hlbWEuX3pvZC5kZWYsIHtcbiAgICAgICAgZ2V0IHNoYXBlICgpIHtcbiAgICAgICAgICAgIGNvbnN0IF9zaGFwZSA9IHtcbiAgICAgICAgICAgICAgICAuLi5zY2hlbWEuX3pvZC5kZWYuc2hhcGUsXG4gICAgICAgICAgICAgICAgLi4uc2hhcGVcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBhc3NpZ25Qcm9wKHRoaXMsIFwic2hhcGVcIiwgX3NoYXBlKTsgLy8gc2VsZi1jYWNoaW5nXG4gICAgICAgICAgICByZXR1cm4gX3NoYXBlO1xuICAgICAgICB9LFxuICAgICAgICBjaGVja3M6IFtdXG4gICAgfSk7XG4gICAgcmV0dXJuIGNsb25lKHNjaGVtYSwgZGVmKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBzYWZlRXh0ZW5kKHNjaGVtYSwgc2hhcGUpIHtcbiAgICBpZiAoIWlzUGxhaW5PYmplY3Qoc2hhcGUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgaW5wdXQgdG8gc2FmZUV4dGVuZDogZXhwZWN0ZWQgYSBwbGFpbiBvYmplY3RcIik7XG4gICAgfVxuICAgIGNvbnN0IGRlZiA9IHtcbiAgICAgICAgLi4uc2NoZW1hLl96b2QuZGVmLFxuICAgICAgICBnZXQgc2hhcGUgKCkge1xuICAgICAgICAgICAgY29uc3QgX3NoYXBlID0ge1xuICAgICAgICAgICAgICAgIC4uLnNjaGVtYS5fem9kLmRlZi5zaGFwZSxcbiAgICAgICAgICAgICAgICAuLi5zaGFwZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGFzc2lnblByb3AodGhpcywgXCJzaGFwZVwiLCBfc2hhcGUpOyAvLyBzZWxmLWNhY2hpbmdcbiAgICAgICAgICAgIHJldHVybiBfc2hhcGU7XG4gICAgICAgIH0sXG4gICAgICAgIGNoZWNrczogc2NoZW1hLl96b2QuZGVmLmNoZWNrc1xuICAgIH07XG4gICAgcmV0dXJuIGNsb25lKHNjaGVtYSwgZGVmKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBtZXJnZShhLCBiKSB7XG4gICAgY29uc3QgZGVmID0gbWVyZ2VEZWZzKGEuX3pvZC5kZWYsIHtcbiAgICAgICAgZ2V0IHNoYXBlICgpIHtcbiAgICAgICAgICAgIGNvbnN0IF9zaGFwZSA9IHtcbiAgICAgICAgICAgICAgICAuLi5hLl96b2QuZGVmLnNoYXBlLFxuICAgICAgICAgICAgICAgIC4uLmIuX3pvZC5kZWYuc2hhcGVcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBhc3NpZ25Qcm9wKHRoaXMsIFwic2hhcGVcIiwgX3NoYXBlKTsgLy8gc2VsZi1jYWNoaW5nXG4gICAgICAgICAgICByZXR1cm4gX3NoYXBlO1xuICAgICAgICB9LFxuICAgICAgICBnZXQgY2F0Y2hhbGwgKCkge1xuICAgICAgICAgICAgcmV0dXJuIGIuX3pvZC5kZWYuY2F0Y2hhbGw7XG4gICAgICAgIH0sXG4gICAgICAgIGNoZWNrczogW11cbiAgICB9KTtcbiAgICByZXR1cm4gY2xvbmUoYSwgZGVmKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBwYXJ0aWFsKENsYXNzLCBzY2hlbWEsIG1hc2spIHtcbiAgICBjb25zdCBkZWYgPSBtZXJnZURlZnMoc2NoZW1hLl96b2QuZGVmLCB7XG4gICAgICAgIGdldCBzaGFwZSAoKSB7XG4gICAgICAgICAgICBjb25zdCBvbGRTaGFwZSA9IHNjaGVtYS5fem9kLmRlZi5zaGFwZTtcbiAgICAgICAgICAgIGNvbnN0IHNoYXBlID0ge1xuICAgICAgICAgICAgICAgIC4uLm9sZFNoYXBlXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKG1hc2spIHtcbiAgICAgICAgICAgICAgICBmb3IoY29uc3Qga2V5IGluIG1hc2spe1xuICAgICAgICAgICAgICAgICAgICBpZiAoIShrZXkgaW4gb2xkU2hhcGUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVucmVjb2duaXplZCBrZXk6IFwiJHtrZXl9XCJgKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoIW1hc2tba2V5XSkgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgIC8vIGlmIChvbGRTaGFwZVtrZXldIS5fem9kLm9wdGluID09PSBcIm9wdGlvbmFsXCIpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgICBzaGFwZVtrZXldID0gQ2xhc3MgPyBuZXcgQ2xhc3Moe1xuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJvcHRpb25hbFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgaW5uZXJUeXBlOiBvbGRTaGFwZVtrZXldXG4gICAgICAgICAgICAgICAgICAgIH0pIDogb2xkU2hhcGVba2V5XTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGZvcihjb25zdCBrZXkgaW4gb2xkU2hhcGUpe1xuICAgICAgICAgICAgICAgICAgICAvLyBpZiAob2xkU2hhcGVba2V5XSEuX3pvZC5vcHRpbiA9PT0gXCJvcHRpb25hbFwiKSBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgc2hhcGVba2V5XSA9IENsYXNzID8gbmV3IENsYXNzKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IFwib3B0aW9uYWxcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGlubmVyVHlwZTogb2xkU2hhcGVba2V5XVxuICAgICAgICAgICAgICAgICAgICB9KSA6IG9sZFNoYXBlW2tleV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXNzaWduUHJvcCh0aGlzLCBcInNoYXBlXCIsIHNoYXBlKTsgLy8gc2VsZi1jYWNoaW5nXG4gICAgICAgICAgICByZXR1cm4gc2hhcGU7XG4gICAgICAgIH0sXG4gICAgICAgIGNoZWNrczogW11cbiAgICB9KTtcbiAgICByZXR1cm4gY2xvbmUoc2NoZW1hLCBkZWYpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVkKENsYXNzLCBzY2hlbWEsIG1hc2spIHtcbiAgICBjb25zdCBkZWYgPSBtZXJnZURlZnMoc2NoZW1hLl96b2QuZGVmLCB7XG4gICAgICAgIGdldCBzaGFwZSAoKSB7XG4gICAgICAgICAgICBjb25zdCBvbGRTaGFwZSA9IHNjaGVtYS5fem9kLmRlZi5zaGFwZTtcbiAgICAgICAgICAgIGNvbnN0IHNoYXBlID0ge1xuICAgICAgICAgICAgICAgIC4uLm9sZFNoYXBlXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKG1hc2spIHtcbiAgICAgICAgICAgICAgICBmb3IoY29uc3Qga2V5IGluIG1hc2spe1xuICAgICAgICAgICAgICAgICAgICBpZiAoIShrZXkgaW4gc2hhcGUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVucmVjb2duaXplZCBrZXk6IFwiJHtrZXl9XCJgKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoIW1hc2tba2V5XSkgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgIC8vIG92ZXJ3cml0ZSB3aXRoIG5vbi1vcHRpb25hbFxuICAgICAgICAgICAgICAgICAgICBzaGFwZVtrZXldID0gbmV3IENsYXNzKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IFwibm9ub3B0aW9uYWxcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGlubmVyVHlwZTogb2xkU2hhcGVba2V5XVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGZvcihjb25zdCBrZXkgaW4gb2xkU2hhcGUpe1xuICAgICAgICAgICAgICAgICAgICAvLyBvdmVyd3JpdGUgd2l0aCBub24tb3B0aW9uYWxcbiAgICAgICAgICAgICAgICAgICAgc2hhcGVba2V5XSA9IG5ldyBDbGFzcyh7XG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiBcIm5vbm9wdGlvbmFsXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbm5lclR5cGU6IG9sZFNoYXBlW2tleV1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXNzaWduUHJvcCh0aGlzLCBcInNoYXBlXCIsIHNoYXBlKTsgLy8gc2VsZi1jYWNoaW5nXG4gICAgICAgICAgICByZXR1cm4gc2hhcGU7XG4gICAgICAgIH0sXG4gICAgICAgIGNoZWNrczogW11cbiAgICB9KTtcbiAgICByZXR1cm4gY2xvbmUoc2NoZW1hLCBkZWYpO1xufVxuLy8gaW52YWxpZF90eXBlIHwgdG9vX2JpZyB8IHRvb19zbWFsbCB8IGludmFsaWRfZm9ybWF0IHwgbm90X211bHRpcGxlX29mIHwgdW5yZWNvZ25pemVkX2tleXMgfCBpbnZhbGlkX3VuaW9uIHwgaW52YWxpZF9rZXkgfCBpbnZhbGlkX2VsZW1lbnQgfCBpbnZhbGlkX3ZhbHVlIHwgY3VzdG9tXG5leHBvcnQgZnVuY3Rpb24gYWJvcnRlZCh4LCBzdGFydEluZGV4ID0gMCkge1xuICAgIGlmICh4LmFib3J0ZWQgPT09IHRydWUpIHJldHVybiB0cnVlO1xuICAgIGZvcihsZXQgaSA9IHN0YXJ0SW5kZXg7IGkgPCB4Lmlzc3Vlcy5sZW5ndGg7IGkrKyl7XG4gICAgICAgIGlmICh4Lmlzc3Vlc1tpXT8uY29udGludWUgIT09IHRydWUpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBwcmVmaXhJc3N1ZXMocGF0aCwgaXNzdWVzKSB7XG4gICAgcmV0dXJuIGlzc3Vlcy5tYXAoKGlzcyk9PntcbiAgICAgICAgdmFyIF9hO1xuICAgICAgICAoX2EgPSBpc3MpLnBhdGggPz8gKF9hLnBhdGggPSBbXSk7XG4gICAgICAgIGlzcy5wYXRoLnVuc2hpZnQocGF0aCk7XG4gICAgICAgIHJldHVybiBpc3M7XG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gdW53cmFwTWVzc2FnZShtZXNzYWdlKSB7XG4gICAgcmV0dXJuIHR5cGVvZiBtZXNzYWdlID09PSBcInN0cmluZ1wiID8gbWVzc2FnZSA6IG1lc3NhZ2U/Lm1lc3NhZ2U7XG59XG5leHBvcnQgZnVuY3Rpb24gZmluYWxpemVJc3N1ZShpc3MsIGN0eCwgY29uZmlnKSB7XG4gICAgY29uc3QgZnVsbCA9IHtcbiAgICAgICAgLi4uaXNzLFxuICAgICAgICBwYXRoOiBpc3MucGF0aCA/PyBbXVxuICAgIH07XG4gICAgLy8gZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5XG4gICAgaWYgKCFpc3MubWVzc2FnZSkge1xuICAgICAgICBjb25zdCBtZXNzYWdlID0gdW53cmFwTWVzc2FnZShpc3MuaW5zdD8uX3pvZC5kZWY/LmVycm9yPy4oaXNzKSkgPz8gdW53cmFwTWVzc2FnZShjdHg/LmVycm9yPy4oaXNzKSkgPz8gdW53cmFwTWVzc2FnZShjb25maWcuY3VzdG9tRXJyb3I/Lihpc3MpKSA/PyB1bndyYXBNZXNzYWdlKGNvbmZpZy5sb2NhbGVFcnJvcj8uKGlzcykpID8/IFwiSW52YWxpZCBpbnB1dFwiO1xuICAgICAgICBmdWxsLm1lc3NhZ2UgPSBtZXNzYWdlO1xuICAgIH1cbiAgICAvLyBkZWxldGUgKGZ1bGwgYXMgYW55KS5kZWY7XG4gICAgZGVsZXRlIGZ1bGwuaW5zdDtcbiAgICBkZWxldGUgZnVsbC5jb250aW51ZTtcbiAgICBpZiAoIWN0eD8ucmVwb3J0SW5wdXQpIHtcbiAgICAgICAgZGVsZXRlIGZ1bGwuaW5wdXQ7XG4gICAgfVxuICAgIHJldHVybiBmdWxsO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdldFNpemFibGVPcmlnaW4oaW5wdXQpIHtcbiAgICBpZiAoaW5wdXQgaW5zdGFuY2VvZiBTZXQpIHJldHVybiBcInNldFwiO1xuICAgIGlmIChpbnB1dCBpbnN0YW5jZW9mIE1hcCkgcmV0dXJuIFwibWFwXCI7XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIGlmIChpbnB1dCBpbnN0YW5jZW9mIEZpbGUpIHJldHVybiBcImZpbGVcIjtcbiAgICByZXR1cm4gXCJ1bmtub3duXCI7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2V0TGVuZ3RoYWJsZU9yaWdpbihpbnB1dCkge1xuICAgIGlmIChBcnJheS5pc0FycmF5KGlucHV0KSkgcmV0dXJuIFwiYXJyYXlcIjtcbiAgICBpZiAodHlwZW9mIGlucHV0ID09PSBcInN0cmluZ1wiKSByZXR1cm4gXCJzdHJpbmdcIjtcbiAgICByZXR1cm4gXCJ1bmtub3duXCI7XG59XG5leHBvcnQgZnVuY3Rpb24gaXNzdWUoLi4uYXJncykge1xuICAgIGNvbnN0IFtpc3MsIGlucHV0LCBpbnN0XSA9IGFyZ3M7XG4gICAgaWYgKHR5cGVvZiBpc3MgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG1lc3NhZ2U6IGlzcyxcbiAgICAgICAgICAgIGNvZGU6IFwiY3VzdG9tXCIsXG4gICAgICAgICAgICBpbnB1dCxcbiAgICAgICAgICAgIGluc3RcbiAgICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgLi4uaXNzXG4gICAgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBjbGVhbkVudW0ob2JqKSB7XG4gICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKG9iaikuZmlsdGVyKChbaywgX10pPT57XG4gICAgICAgIC8vIHJldHVybiB0cnVlIGlmIE5hTiwgbWVhbmluZyBpdCdzIG5vdCBhIG51bWJlciwgdGh1cyBhIHN0cmluZyBrZXlcbiAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihOdW1iZXIucGFyc2VJbnQoaywgMTApKTtcbiAgICB9KS5tYXAoKGVsKT0+ZWxbMV0pO1xufVxuLy8gQ29kZWMgdXRpbGl0eSBmdW5jdGlvbnNcbmV4cG9ydCBmdW5jdGlvbiBiYXNlNjRUb1VpbnQ4QXJyYXkoYmFzZTY0KSB7XG4gICAgY29uc3QgYmluYXJ5U3RyaW5nID0gYXRvYihiYXNlNjQpO1xuICAgIGNvbnN0IGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoYmluYXJ5U3RyaW5nLmxlbmd0aCk7XG4gICAgZm9yKGxldCBpID0gMDsgaSA8IGJpbmFyeVN0cmluZy5sZW5ndGg7IGkrKyl7XG4gICAgICAgIGJ5dGVzW2ldID0gYmluYXJ5U3RyaW5nLmNoYXJDb2RlQXQoaSk7XG4gICAgfVxuICAgIHJldHVybiBieXRlcztcbn1cbmV4cG9ydCBmdW5jdGlvbiB1aW50OEFycmF5VG9CYXNlNjQoYnl0ZXMpIHtcbiAgICBsZXQgYmluYXJ5U3RyaW5nID0gXCJcIjtcbiAgICBmb3IobGV0IGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpKyspe1xuICAgICAgICBiaW5hcnlTdHJpbmcgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSk7XG4gICAgfVxuICAgIHJldHVybiBidG9hKGJpbmFyeVN0cmluZyk7XG59XG5leHBvcnQgZnVuY3Rpb24gYmFzZTY0dXJsVG9VaW50OEFycmF5KGJhc2U2NHVybCkge1xuICAgIGNvbnN0IGJhc2U2NCA9IGJhc2U2NHVybC5yZXBsYWNlKC8tL2csIFwiK1wiKS5yZXBsYWNlKC9fL2csIFwiL1wiKTtcbiAgICBjb25zdCBwYWRkaW5nID0gXCI9XCIucmVwZWF0KCg0IC0gYmFzZTY0Lmxlbmd0aCAlIDQpICUgNCk7XG4gICAgcmV0dXJuIGJhc2U2NFRvVWludDhBcnJheShiYXNlNjQgKyBwYWRkaW5nKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiB1aW50OEFycmF5VG9CYXNlNjR1cmwoYnl0ZXMpIHtcbiAgICByZXR1cm4gdWludDhBcnJheVRvQmFzZTY0KGJ5dGVzKS5yZXBsYWNlKC9cXCsvZywgXCItXCIpLnJlcGxhY2UoL1xcLy9nLCBcIl9cIikucmVwbGFjZSgvPS9nLCBcIlwiKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBoZXhUb1VpbnQ4QXJyYXkoaGV4KSB7XG4gICAgY29uc3QgY2xlYW5IZXggPSBoZXgucmVwbGFjZSgvXjB4LywgXCJcIik7XG4gICAgaWYgKGNsZWFuSGV4Lmxlbmd0aCAlIDIgIT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBoZXggc3RyaW5nIGxlbmd0aFwiKTtcbiAgICB9XG4gICAgY29uc3QgYnl0ZXMgPSBuZXcgVWludDhBcnJheShjbGVhbkhleC5sZW5ndGggLyAyKTtcbiAgICBmb3IobGV0IGkgPSAwOyBpIDwgY2xlYW5IZXgubGVuZ3RoOyBpICs9IDIpe1xuICAgICAgICBieXRlc1tpIC8gMl0gPSBOdW1iZXIucGFyc2VJbnQoY2xlYW5IZXguc2xpY2UoaSwgaSArIDIpLCAxNik7XG4gICAgfVxuICAgIHJldHVybiBieXRlcztcbn1cbmV4cG9ydCBmdW5jdGlvbiB1aW50OEFycmF5VG9IZXgoYnl0ZXMpIHtcbiAgICByZXR1cm4gQXJyYXkuZnJvbShieXRlcykubWFwKChiKT0+Yi50b1N0cmluZygxNikucGFkU3RhcnQoMiwgXCIwXCIpKS5qb2luKFwiXCIpO1xufVxuLy8gaW5zdGFuY2VvZlxuZXhwb3J0IGNsYXNzIENsYXNzIHtcbiAgICBjb25zdHJ1Y3RvciguLi5fYXJncyl7fVxufVxuIiwgImltcG9ydCB7ICRjb25zdHJ1Y3RvciB9IGZyb20gXCIuL2NvcmUuanNcIjtcbmltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4vdXRpbC5qc1wiO1xuY29uc3QgaW5pdGlhbGl6ZXIgPSAoaW5zdCwgZGVmKT0+e1xuICAgIGluc3QubmFtZSA9IFwiJFpvZEVycm9yXCI7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGluc3QsIFwiX3pvZFwiLCB7XG4gICAgICAgIHZhbHVlOiBpbnN0Ll96b2QsXG4gICAgICAgIGVudW1lcmFibGU6IGZhbHNlXG4gICAgfSk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGluc3QsIFwiaXNzdWVzXCIsIHtcbiAgICAgICAgdmFsdWU6IGRlZixcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2VcbiAgICB9KTtcbiAgICBpbnN0Lm1lc3NhZ2UgPSBKU09OLnN0cmluZ2lmeShkZWYsIHV0aWwuanNvblN0cmluZ2lmeVJlcGxhY2VyLCAyKTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoaW5zdCwgXCJ0b1N0cmluZ1wiLCB7XG4gICAgICAgIHZhbHVlOiAoKT0+aW5zdC5tZXNzYWdlLFxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZVxuICAgIH0pO1xufTtcbmV4cG9ydCBjb25zdCAkWm9kRXJyb3IgPSAkY29uc3RydWN0b3IoXCIkWm9kRXJyb3JcIiwgaW5pdGlhbGl6ZXIpO1xuZXhwb3J0IGNvbnN0ICRab2RSZWFsRXJyb3IgPSAkY29uc3RydWN0b3IoXCIkWm9kRXJyb3JcIiwgaW5pdGlhbGl6ZXIsIHtcbiAgICBQYXJlbnQ6IEVycm9yXG59KTtcbmV4cG9ydCBmdW5jdGlvbiBmbGF0dGVuRXJyb3IoZXJyb3IsIG1hcHBlciA9IChpc3N1ZSk9Pmlzc3VlLm1lc3NhZ2UpIHtcbiAgICBjb25zdCBmaWVsZEVycm9ycyA9IHt9O1xuICAgIGNvbnN0IGZvcm1FcnJvcnMgPSBbXTtcbiAgICBmb3IgKGNvbnN0IHN1YiBvZiBlcnJvci5pc3N1ZXMpe1xuICAgICAgICBpZiAoc3ViLnBhdGgubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgZmllbGRFcnJvcnNbc3ViLnBhdGhbMF1dID0gZmllbGRFcnJvcnNbc3ViLnBhdGhbMF1dIHx8IFtdO1xuICAgICAgICAgICAgZmllbGRFcnJvcnNbc3ViLnBhdGhbMF1dLnB1c2gobWFwcGVyKHN1YikpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZm9ybUVycm9ycy5wdXNoKG1hcHBlcihzdWIpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBmb3JtRXJyb3JzLFxuICAgICAgICBmaWVsZEVycm9yc1xuICAgIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZm9ybWF0RXJyb3IoZXJyb3IsIF9tYXBwZXIpIHtcbiAgICBjb25zdCBtYXBwZXIgPSBfbWFwcGVyIHx8IGZ1bmN0aW9uKGlzc3VlKSB7XG4gICAgICAgIHJldHVybiBpc3N1ZS5tZXNzYWdlO1xuICAgIH07XG4gICAgY29uc3QgZmllbGRFcnJvcnMgPSB7XG4gICAgICAgIF9lcnJvcnM6IFtdXG4gICAgfTtcbiAgICBjb25zdCBwcm9jZXNzRXJyb3IgPSAoZXJyb3IpPT57XG4gICAgICAgIGZvciAoY29uc3QgaXNzdWUgb2YgZXJyb3IuaXNzdWVzKXtcbiAgICAgICAgICAgIGlmIChpc3N1ZS5jb2RlID09PSBcImludmFsaWRfdW5pb25cIiAmJiBpc3N1ZS5lcnJvcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgaXNzdWUuZXJyb3JzLm1hcCgoaXNzdWVzKT0+cHJvY2Vzc0Vycm9yKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzc3Vlc1xuICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGlzc3VlLmNvZGUgPT09IFwiaW52YWxpZF9rZXlcIikge1xuICAgICAgICAgICAgICAgIHByb2Nlc3NFcnJvcih7XG4gICAgICAgICAgICAgICAgICAgIGlzc3VlczogaXNzdWUuaXNzdWVzXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGlzc3VlLmNvZGUgPT09IFwiaW52YWxpZF9lbGVtZW50XCIpIHtcbiAgICAgICAgICAgICAgICBwcm9jZXNzRXJyb3Ioe1xuICAgICAgICAgICAgICAgICAgICBpc3N1ZXM6IGlzc3VlLmlzc3Vlc1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChpc3N1ZS5wYXRoLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGZpZWxkRXJyb3JzLl9lcnJvcnMucHVzaChtYXBwZXIoaXNzdWUpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbGV0IGN1cnIgPSBmaWVsZEVycm9ycztcbiAgICAgICAgICAgICAgICBsZXQgaSA9IDA7XG4gICAgICAgICAgICAgICAgd2hpbGUoaSA8IGlzc3VlLnBhdGgubGVuZ3RoKXtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZWwgPSBpc3N1ZS5wYXRoW2ldO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB0ZXJtaW5hbCA9IGkgPT09IGlzc3VlLnBhdGgubGVuZ3RoIC0gMTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0ZXJtaW5hbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY3VycltlbF0gPSBjdXJyW2VsXSB8fCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2Vycm9yczogW11cbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJyW2VsXSA9IGN1cnJbZWxdIHx8IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfZXJyb3JzOiBbXVxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJbZWxdLl9lcnJvcnMucHVzaChtYXBwZXIoaXNzdWUpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjdXJyID0gY3VycltlbF07XG4gICAgICAgICAgICAgICAgICAgIGkrKztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHByb2Nlc3NFcnJvcihlcnJvcik7XG4gICAgcmV0dXJuIGZpZWxkRXJyb3JzO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHRyZWVpZnlFcnJvcihlcnJvciwgX21hcHBlcikge1xuICAgIGNvbnN0IG1hcHBlciA9IF9tYXBwZXIgfHwgZnVuY3Rpb24oaXNzdWUpIHtcbiAgICAgICAgcmV0dXJuIGlzc3VlLm1lc3NhZ2U7XG4gICAgfTtcbiAgICBjb25zdCByZXN1bHQgPSB7XG4gICAgICAgIGVycm9yczogW11cbiAgICB9O1xuICAgIGNvbnN0IHByb2Nlc3NFcnJvciA9IChlcnJvciwgcGF0aCA9IFtdKT0+e1xuICAgICAgICB2YXIgX2EsIF9iO1xuICAgICAgICBmb3IgKGNvbnN0IGlzc3VlIG9mIGVycm9yLmlzc3Vlcyl7XG4gICAgICAgICAgICBpZiAoaXNzdWUuY29kZSA9PT0gXCJpbnZhbGlkX3VuaW9uXCIgJiYgaXNzdWUuZXJyb3JzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIC8vIHJlZ3VsYXIgdW5pb24gZXJyb3JcbiAgICAgICAgICAgICAgICBpc3N1ZS5lcnJvcnMubWFwKChpc3N1ZXMpPT5wcm9jZXNzRXJyb3Ioe1xuICAgICAgICAgICAgICAgICAgICAgICAgaXNzdWVzXG4gICAgICAgICAgICAgICAgICAgIH0sIGlzc3VlLnBhdGgpKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNzdWUuY29kZSA9PT0gXCJpbnZhbGlkX2tleVwiKSB7XG4gICAgICAgICAgICAgICAgcHJvY2Vzc0Vycm9yKHtcbiAgICAgICAgICAgICAgICAgICAgaXNzdWVzOiBpc3N1ZS5pc3N1ZXNcbiAgICAgICAgICAgICAgICB9LCBpc3N1ZS5wYXRoKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNzdWUuY29kZSA9PT0gXCJpbnZhbGlkX2VsZW1lbnRcIikge1xuICAgICAgICAgICAgICAgIHByb2Nlc3NFcnJvcih7XG4gICAgICAgICAgICAgICAgICAgIGlzc3VlczogaXNzdWUuaXNzdWVzXG4gICAgICAgICAgICAgICAgfSwgaXNzdWUucGF0aCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IGZ1bGxwYXRoID0gW1xuICAgICAgICAgICAgICAgICAgICAuLi5wYXRoLFxuICAgICAgICAgICAgICAgICAgICAuLi5pc3N1ZS5wYXRoXG4gICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICAgICBpZiAoZnVsbHBhdGgubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdC5lcnJvcnMucHVzaChtYXBwZXIoaXNzdWUpKTtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxldCBjdXJyID0gcmVzdWx0O1xuICAgICAgICAgICAgICAgIGxldCBpID0gMDtcbiAgICAgICAgICAgICAgICB3aGlsZShpIDwgZnVsbHBhdGgubGVuZ3RoKXtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZWwgPSBmdWxscGF0aFtpXTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdGVybWluYWwgPSBpID09PSBmdWxscGF0aC5sZW5ndGggLSAxO1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGVsID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJyLnByb3BlcnRpZXMgPz8gKGN1cnIucHJvcGVydGllcyA9IHt9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIChfYSA9IGN1cnIucHJvcGVydGllcylbZWxdID8/IChfYVtlbF0gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JzOiBbXVxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJyID0gY3Vyci5wcm9wZXJ0aWVzW2VsXTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnIuaXRlbXMgPz8gKGN1cnIuaXRlbXMgPSBbXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAoX2IgPSBjdXJyLml0ZW1zKVtlbF0gPz8gKF9iW2VsXSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcnM6IFtdXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnIgPSBjdXJyLml0ZW1zW2VsXTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAodGVybWluYWwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnIuZXJyb3JzLnB1c2gobWFwcGVyKGlzc3VlKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaSsrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgcHJvY2Vzc0Vycm9yKGVycm9yKTtcbiAgICByZXR1cm4gcmVzdWx0O1xufVxuLyoqIEZvcm1hdCBhIFpvZEVycm9yIGFzIGEgaHVtYW4tcmVhZGFibGUgc3RyaW5nIGluIHRoZSBmb2xsb3dpbmcgZm9ybS5cbiAqXG4gKiBGcm9tXG4gKlxuICogYGBgdHNcbiAqIFpvZEVycm9yIHtcbiAqICAgaXNzdWVzOiBbXG4gKiAgICAge1xuICogICAgICAgZXhwZWN0ZWQ6ICdzdHJpbmcnLFxuICogICAgICAgY29kZTogJ2ludmFsaWRfdHlwZScsXG4gKiAgICAgICBwYXRoOiBbICd1c2VybmFtZScgXSxcbiAqICAgICAgIG1lc3NhZ2U6ICdJbnZhbGlkIGlucHV0OiBleHBlY3RlZCBzdHJpbmcnXG4gKiAgICAgfSxcbiAqICAgICB7XG4gKiAgICAgICBleHBlY3RlZDogJ251bWJlcicsXG4gKiAgICAgICBjb2RlOiAnaW52YWxpZF90eXBlJyxcbiAqICAgICAgIHBhdGg6IFsgJ2Zhdm9yaXRlTnVtYmVycycsIDEgXSxcbiAqICAgICAgIG1lc3NhZ2U6ICdJbnZhbGlkIGlucHV0OiBleHBlY3RlZCBudW1iZXInXG4gKiAgICAgfVxuICogICBdO1xuICogfVxuICogYGBgXG4gKlxuICogdG9cbiAqXG4gKiBgYGBcbiAqIHVzZXJuYW1lXG4gKiAgIFx1MjcxNiBFeHBlY3RlZCBudW1iZXIsIHJlY2VpdmVkIHN0cmluZyBhdCBcInVzZXJuYW1lXG4gKiBmYXZvcml0ZU51bWJlcnNbMF1cbiAqICAgXHUyNzE2IEludmFsaWQgaW5wdXQ6IGV4cGVjdGVkIG51bWJlclxuICogYGBgXG4gKi8gZXhwb3J0IGZ1bmN0aW9uIHRvRG90UGF0aChfcGF0aCkge1xuICAgIGNvbnN0IHNlZ3MgPSBbXTtcbiAgICBjb25zdCBwYXRoID0gX3BhdGgubWFwKChzZWcpPT50eXBlb2Ygc2VnID09PSBcIm9iamVjdFwiID8gc2VnLmtleSA6IHNlZyk7XG4gICAgZm9yIChjb25zdCBzZWcgb2YgcGF0aCl7XG4gICAgICAgIGlmICh0eXBlb2Ygc2VnID09PSBcIm51bWJlclwiKSBzZWdzLnB1c2goYFske3NlZ31dYCk7XG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiBzZWcgPT09IFwic3ltYm9sXCIpIHNlZ3MucHVzaChgWyR7SlNPTi5zdHJpbmdpZnkoU3RyaW5nKHNlZykpfV1gKTtcbiAgICAgICAgZWxzZSBpZiAoL1teXFx3JF0vLnRlc3Qoc2VnKSkgc2Vncy5wdXNoKGBbJHtKU09OLnN0cmluZ2lmeShzZWcpfV1gKTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpZiAoc2Vncy5sZW5ndGgpIHNlZ3MucHVzaChcIi5cIik7XG4gICAgICAgICAgICBzZWdzLnB1c2goc2VnKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gc2Vncy5qb2luKFwiXCIpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHByZXR0aWZ5RXJyb3IoZXJyb3IpIHtcbiAgICBjb25zdCBsaW5lcyA9IFtdO1xuICAgIC8vIHNvcnQgYnkgcGF0aCBsZW5ndGhcbiAgICBjb25zdCBpc3N1ZXMgPSBbXG4gICAgICAgIC4uLmVycm9yLmlzc3Vlc1xuICAgIF0uc29ydCgoYSwgYik9PihhLnBhdGggPz8gW10pLmxlbmd0aCAtIChiLnBhdGggPz8gW10pLmxlbmd0aCk7XG4gICAgLy8gUHJvY2VzcyBlYWNoIGlzc3VlXG4gICAgZm9yIChjb25zdCBpc3N1ZSBvZiBpc3N1ZXMpe1xuICAgICAgICBsaW5lcy5wdXNoKGBcdTI3MTYgJHtpc3N1ZS5tZXNzYWdlfWApO1xuICAgICAgICBpZiAoaXNzdWUucGF0aD8ubGVuZ3RoKSBsaW5lcy5wdXNoKGAgIFx1MjE5MiBhdCAke3RvRG90UGF0aChpc3N1ZS5wYXRoKX1gKTtcbiAgICB9XG4gICAgLy8gQ29udmVydCBNYXAgdG8gZm9ybWF0dGVkIHN0cmluZ1xuICAgIHJldHVybiBsaW5lcy5qb2luKFwiXFxuXCIpO1xufVxuIiwgImltcG9ydCAqIGFzIGNvcmUgZnJvbSBcIi4vY29yZS5qc1wiO1xuaW1wb3J0ICogYXMgZXJyb3JzIGZyb20gXCIuL2Vycm9ycy5qc1wiO1xuaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi91dGlsLmpzXCI7XG5leHBvcnQgY29uc3QgX3BhcnNlID0gKF9FcnIpPT4oc2NoZW1hLCB2YWx1ZSwgX2N0eCwgX3BhcmFtcyk9PntcbiAgICAgICAgY29uc3QgY3R4ID0gX2N0eCA/IE9iamVjdC5hc3NpZ24oX2N0eCwge1xuICAgICAgICAgICAgYXN5bmM6IGZhbHNlXG4gICAgICAgIH0pIDoge1xuICAgICAgICAgICAgYXN5bmM6IGZhbHNlXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHNjaGVtYS5fem9kLnJ1bih7XG4gICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgIGlzc3VlczogW11cbiAgICAgICAgfSwgY3R4KTtcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBjb3JlLiRab2RBc3luY0Vycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlc3VsdC5pc3N1ZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICBjb25zdCBlID0gbmV3IChfcGFyYW1zPy5FcnIgPz8gX0VycikocmVzdWx0Lmlzc3Vlcy5tYXAoKGlzcyk9PnV0aWwuZmluYWxpemVJc3N1ZShpc3MsIGN0eCwgY29yZS5jb25maWcoKSkpKTtcbiAgICAgICAgICAgIHV0aWwuY2FwdHVyZVN0YWNrVHJhY2UoZSwgX3BhcmFtcz8uY2FsbGVlKTtcbiAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdC52YWx1ZTtcbiAgICB9O1xuZXhwb3J0IGNvbnN0IHBhcnNlID0gLyogQF9fUFVSRV9fKi8gX3BhcnNlKGVycm9ycy4kWm9kUmVhbEVycm9yKTtcbmV4cG9ydCBjb25zdCBfcGFyc2VBc3luYyA9IChfRXJyKT0+YXN5bmMgKHNjaGVtYSwgdmFsdWUsIF9jdHgsIHBhcmFtcyk9PntcbiAgICAgICAgY29uc3QgY3R4ID0gX2N0eCA/IE9iamVjdC5hc3NpZ24oX2N0eCwge1xuICAgICAgICAgICAgYXN5bmM6IHRydWVcbiAgICAgICAgfSkgOiB7XG4gICAgICAgICAgICBhc3luYzogdHJ1ZVxuICAgICAgICB9O1xuICAgICAgICBsZXQgcmVzdWx0ID0gc2NoZW1hLl96b2QucnVuKHtcbiAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgaXNzdWVzOiBbXVxuICAgICAgICB9LCBjdHgpO1xuICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkgcmVzdWx0ID0gYXdhaXQgcmVzdWx0O1xuICAgICAgICBpZiAocmVzdWx0Lmlzc3Vlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNvbnN0IGUgPSBuZXcgKHBhcmFtcz8uRXJyID8/IF9FcnIpKHJlc3VsdC5pc3N1ZXMubWFwKChpc3MpPT51dGlsLmZpbmFsaXplSXNzdWUoaXNzLCBjdHgsIGNvcmUuY29uZmlnKCkpKSk7XG4gICAgICAgICAgICB1dGlsLmNhcHR1cmVTdGFja1RyYWNlKGUsIHBhcmFtcz8uY2FsbGVlKTtcbiAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdC52YWx1ZTtcbiAgICB9O1xuZXhwb3J0IGNvbnN0IHBhcnNlQXN5bmMgPSAvKiBAX19QVVJFX18qLyBfcGFyc2VBc3luYyhlcnJvcnMuJFpvZFJlYWxFcnJvcik7XG5leHBvcnQgY29uc3QgX3NhZmVQYXJzZSA9IChfRXJyKT0+KHNjaGVtYSwgdmFsdWUsIF9jdHgpPT57XG4gICAgICAgIGNvbnN0IGN0eCA9IF9jdHggPyB7XG4gICAgICAgICAgICAuLi5fY3R4LFxuICAgICAgICAgICAgYXN5bmM6IGZhbHNlXG4gICAgICAgIH0gOiB7XG4gICAgICAgICAgICBhc3luYzogZmFsc2VcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gc2NoZW1hLl96b2QucnVuKHtcbiAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgaXNzdWVzOiBbXVxuICAgICAgICB9LCBjdHgpO1xuICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IGNvcmUuJFpvZEFzeW5jRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0Lmlzc3Vlcy5sZW5ndGggPyB7XG4gICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgIGVycm9yOiBuZXcgKF9FcnIgPz8gZXJyb3JzLiRab2RFcnJvcikocmVzdWx0Lmlzc3Vlcy5tYXAoKGlzcyk9PnV0aWwuZmluYWxpemVJc3N1ZShpc3MsIGN0eCwgY29yZS5jb25maWcoKSkpKVxuICAgICAgICB9IDoge1xuICAgICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICAgIGRhdGE6IHJlc3VsdC52YWx1ZVxuICAgICAgICB9O1xuICAgIH07XG5leHBvcnQgY29uc3Qgc2FmZVBhcnNlID0gLyogQF9fUFVSRV9fKi8gX3NhZmVQYXJzZShlcnJvcnMuJFpvZFJlYWxFcnJvcik7XG5leHBvcnQgY29uc3QgX3NhZmVQYXJzZUFzeW5jID0gKF9FcnIpPT5hc3luYyAoc2NoZW1hLCB2YWx1ZSwgX2N0eCk9PntcbiAgICAgICAgY29uc3QgY3R4ID0gX2N0eCA/IE9iamVjdC5hc3NpZ24oX2N0eCwge1xuICAgICAgICAgICAgYXN5bmM6IHRydWVcbiAgICAgICAgfSkgOiB7XG4gICAgICAgICAgICBhc3luYzogdHJ1ZVxuICAgICAgICB9O1xuICAgICAgICBsZXQgcmVzdWx0ID0gc2NoZW1hLl96b2QucnVuKHtcbiAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgaXNzdWVzOiBbXVxuICAgICAgICB9LCBjdHgpO1xuICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkgcmVzdWx0ID0gYXdhaXQgcmVzdWx0O1xuICAgICAgICByZXR1cm4gcmVzdWx0Lmlzc3Vlcy5sZW5ndGggPyB7XG4gICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgIGVycm9yOiBuZXcgX0VycihyZXN1bHQuaXNzdWVzLm1hcCgoaXNzKT0+dXRpbC5maW5hbGl6ZUlzc3VlKGlzcywgY3R4LCBjb3JlLmNvbmZpZygpKSkpXG4gICAgICAgIH0gOiB7XG4gICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgZGF0YTogcmVzdWx0LnZhbHVlXG4gICAgICAgIH07XG4gICAgfTtcbmV4cG9ydCBjb25zdCBzYWZlUGFyc2VBc3luYyA9IC8qIEBfX1BVUkVfXyovIF9zYWZlUGFyc2VBc3luYyhlcnJvcnMuJFpvZFJlYWxFcnJvcik7XG5leHBvcnQgY29uc3QgX2VuY29kZSA9IChfRXJyKT0+KHNjaGVtYSwgdmFsdWUsIF9jdHgpPT57XG4gICAgICAgIGNvbnN0IGN0eCA9IF9jdHggPyBPYmplY3QuYXNzaWduKF9jdHgsIHtcbiAgICAgICAgICAgIGRpcmVjdGlvbjogXCJiYWNrd2FyZFwiXG4gICAgICAgIH0pIDoge1xuICAgICAgICAgICAgZGlyZWN0aW9uOiBcImJhY2t3YXJkXCJcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIF9wYXJzZShfRXJyKShzY2hlbWEsIHZhbHVlLCBjdHgpO1xuICAgIH07XG5leHBvcnQgY29uc3QgZW5jb2RlID0gLyogQF9fUFVSRV9fKi8gX2VuY29kZShlcnJvcnMuJFpvZFJlYWxFcnJvcik7XG5leHBvcnQgY29uc3QgX2RlY29kZSA9IChfRXJyKT0+KHNjaGVtYSwgdmFsdWUsIF9jdHgpPT57XG4gICAgICAgIHJldHVybiBfcGFyc2UoX0Vycikoc2NoZW1hLCB2YWx1ZSwgX2N0eCk7XG4gICAgfTtcbmV4cG9ydCBjb25zdCBkZWNvZGUgPSAvKiBAX19QVVJFX18qLyBfZGVjb2RlKGVycm9ycy4kWm9kUmVhbEVycm9yKTtcbmV4cG9ydCBjb25zdCBfZW5jb2RlQXN5bmMgPSAoX0Vycik9PmFzeW5jIChzY2hlbWEsIHZhbHVlLCBfY3R4KT0+e1xuICAgICAgICBjb25zdCBjdHggPSBfY3R4ID8gT2JqZWN0LmFzc2lnbihfY3R4LCB7XG4gICAgICAgICAgICBkaXJlY3Rpb246IFwiYmFja3dhcmRcIlxuICAgICAgICB9KSA6IHtcbiAgICAgICAgICAgIGRpcmVjdGlvbjogXCJiYWNrd2FyZFwiXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBfcGFyc2VBc3luYyhfRXJyKShzY2hlbWEsIHZhbHVlLCBjdHgpO1xuICAgIH07XG5leHBvcnQgY29uc3QgZW5jb2RlQXN5bmMgPSAvKiBAX19QVVJFX18qLyBfZW5jb2RlQXN5bmMoZXJyb3JzLiRab2RSZWFsRXJyb3IpO1xuZXhwb3J0IGNvbnN0IF9kZWNvZGVBc3luYyA9IChfRXJyKT0+YXN5bmMgKHNjaGVtYSwgdmFsdWUsIF9jdHgpPT57XG4gICAgICAgIHJldHVybiBfcGFyc2VBc3luYyhfRXJyKShzY2hlbWEsIHZhbHVlLCBfY3R4KTtcbiAgICB9O1xuZXhwb3J0IGNvbnN0IGRlY29kZUFzeW5jID0gLyogQF9fUFVSRV9fKi8gX2RlY29kZUFzeW5jKGVycm9ycy4kWm9kUmVhbEVycm9yKTtcbmV4cG9ydCBjb25zdCBfc2FmZUVuY29kZSA9IChfRXJyKT0+KHNjaGVtYSwgdmFsdWUsIF9jdHgpPT57XG4gICAgICAgIGNvbnN0IGN0eCA9IF9jdHggPyBPYmplY3QuYXNzaWduKF9jdHgsIHtcbiAgICAgICAgICAgIGRpcmVjdGlvbjogXCJiYWNrd2FyZFwiXG4gICAgICAgIH0pIDoge1xuICAgICAgICAgICAgZGlyZWN0aW9uOiBcImJhY2t3YXJkXCJcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIF9zYWZlUGFyc2UoX0Vycikoc2NoZW1hLCB2YWx1ZSwgY3R4KTtcbiAgICB9O1xuZXhwb3J0IGNvbnN0IHNhZmVFbmNvZGUgPSAvKiBAX19QVVJFX18qLyBfc2FmZUVuY29kZShlcnJvcnMuJFpvZFJlYWxFcnJvcik7XG5leHBvcnQgY29uc3QgX3NhZmVEZWNvZGUgPSAoX0Vycik9PihzY2hlbWEsIHZhbHVlLCBfY3R4KT0+e1xuICAgICAgICByZXR1cm4gX3NhZmVQYXJzZShfRXJyKShzY2hlbWEsIHZhbHVlLCBfY3R4KTtcbiAgICB9O1xuZXhwb3J0IGNvbnN0IHNhZmVEZWNvZGUgPSAvKiBAX19QVVJFX18qLyBfc2FmZURlY29kZShlcnJvcnMuJFpvZFJlYWxFcnJvcik7XG5leHBvcnQgY29uc3QgX3NhZmVFbmNvZGVBc3luYyA9IChfRXJyKT0+YXN5bmMgKHNjaGVtYSwgdmFsdWUsIF9jdHgpPT57XG4gICAgICAgIGNvbnN0IGN0eCA9IF9jdHggPyBPYmplY3QuYXNzaWduKF9jdHgsIHtcbiAgICAgICAgICAgIGRpcmVjdGlvbjogXCJiYWNrd2FyZFwiXG4gICAgICAgIH0pIDoge1xuICAgICAgICAgICAgZGlyZWN0aW9uOiBcImJhY2t3YXJkXCJcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIF9zYWZlUGFyc2VBc3luYyhfRXJyKShzY2hlbWEsIHZhbHVlLCBjdHgpO1xuICAgIH07XG5leHBvcnQgY29uc3Qgc2FmZUVuY29kZUFzeW5jID0gLyogQF9fUFVSRV9fKi8gX3NhZmVFbmNvZGVBc3luYyhlcnJvcnMuJFpvZFJlYWxFcnJvcik7XG5leHBvcnQgY29uc3QgX3NhZmVEZWNvZGVBc3luYyA9IChfRXJyKT0+YXN5bmMgKHNjaGVtYSwgdmFsdWUsIF9jdHgpPT57XG4gICAgICAgIHJldHVybiBfc2FmZVBhcnNlQXN5bmMoX0Vycikoc2NoZW1hLCB2YWx1ZSwgX2N0eCk7XG4gICAgfTtcbmV4cG9ydCBjb25zdCBzYWZlRGVjb2RlQXN5bmMgPSAvKiBAX19QVVJFX18qLyBfc2FmZURlY29kZUFzeW5jKGVycm9ycy4kWm9kUmVhbEVycm9yKTtcbiIsICJleHBvcnQgY29uc3QgY3VpZCA9IC9eW2NDXVteXFxzLV17OCx9JC87XG5leHBvcnQgY29uc3QgY3VpZDIgPSAvXlswLTlhLXpdKyQvO1xuZXhwb3J0IGNvbnN0IHVsaWQgPSAvXlswLTlBLUhKS01OUC1UVi1aYS1oamttbnAtdHYtel17MjZ9JC87XG5leHBvcnQgY29uc3QgeGlkID0gL15bMC05YS12QS1WXXsyMH0kLztcbmV4cG9ydCBjb25zdCBrc3VpZCA9IC9eW0EtWmEtejAtOV17Mjd9JC87XG5leHBvcnQgY29uc3QgbmFub2lkID0gL15bYS16QS1aMC05Xy1dezIxfSQvO1xuLyoqIElTTyA4NjAxLTEgZHVyYXRpb24gcmVnZXguIERvZXMgbm90IHN1cHBvcnQgdGhlIDg2MDEtMiBleHRlbnNpb25zIGxpa2UgbmVnYXRpdmUgZHVyYXRpb25zIG9yIGZyYWN0aW9uYWwvbmVnYXRpdmUgY29tcG9uZW50cy4gKi8gZXhwb3J0IGNvbnN0IGR1cmF0aW9uID0gL15QKD86KFxcZCtXKXwoPyEuKlcpKD89XFxkfFRcXGQpKFxcZCtZKT8oXFxkK00pPyhcXGQrRCk/KFQoPz1cXGQpKFxcZCtIKT8oXFxkK00pPyhcXGQrKFsuLF1cXGQrKT9TKT8pPykkLztcbi8qKiBJbXBsZW1lbnRzIElTTyA4NjAxLTIgZXh0ZW5zaW9ucyBsaWtlIGV4cGxpY2l0ICstIHByZWZpeGVzLCBtaXhpbmcgd2Vla3Mgd2l0aCBvdGhlciB1bml0cywgYW5kIGZyYWN0aW9uYWwvbmVnYXRpdmUgY29tcG9uZW50cy4gKi8gZXhwb3J0IGNvbnN0IGV4dGVuZGVkRHVyYXRpb24gPSAvXlstK10/UCg/ISQpKD86KD86Wy0rXT9cXGQrWSl8KD86Wy0rXT9cXGQrWy4sXVxcZCtZJCkpPyg/Oig/OlstK10/XFxkK00pfCg/OlstK10/XFxkK1suLF1cXGQrTSQpKT8oPzooPzpbLStdP1xcZCtXKXwoPzpbLStdP1xcZCtbLixdXFxkK1ckKSk/KD86KD86Wy0rXT9cXGQrRCl8KD86Wy0rXT9cXGQrWy4sXVxcZCtEJCkpPyg/OlQoPz1bXFxkKy1dKSg/Oig/OlstK10/XFxkK0gpfCg/OlstK10/XFxkK1suLF1cXGQrSCQpKT8oPzooPzpbLStdP1xcZCtNKXwoPzpbLStdP1xcZCtbLixdXFxkK00kKSk/KD86Wy0rXT9cXGQrKD86Wy4sXVxcZCspP1MpPyk/PyQvO1xuLyoqIEEgcmVnZXggZm9yIGFueSBVVUlELWxpa2UgaWRlbnRpZmllcjogOC00LTQtNC0xMiBoZXggcGF0dGVybiAqLyBleHBvcnQgY29uc3QgZ3VpZCA9IC9eKFswLTlhLWZBLUZdezh9LVswLTlhLWZBLUZdezR9LVswLTlhLWZBLUZdezR9LVswLTlhLWZBLUZdezR9LVswLTlhLWZBLUZdezEyfSkkLztcbi8qKiBSZXR1cm5zIGEgcmVnZXggZm9yIHZhbGlkYXRpbmcgYW4gUkZDIDk1NjIvNDEyMiBVVUlELlxuICpcbiAqIEBwYXJhbSB2ZXJzaW9uIE9wdGlvbmFsbHkgc3BlY2lmeSBhIHZlcnNpb24gMS04LiBJZiBubyB2ZXJzaW9uIGlzIHNwZWNpZmllZCwgYWxsIHZlcnNpb25zIGFyZSBzdXBwb3J0ZWQuICovIGV4cG9ydCBjb25zdCB1dWlkID0gKHZlcnNpb24pPT57XG4gICAgaWYgKCF2ZXJzaW9uKSByZXR1cm4gL14oWzAtOWEtZkEtRl17OH0tWzAtOWEtZkEtRl17NH0tWzEtOF1bMC05YS1mQS1GXXszfS1bODlhYkFCXVswLTlhLWZBLUZdezN9LVswLTlhLWZBLUZdezEyfXwwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDB8ZmZmZmZmZmYtZmZmZi1mZmZmLWZmZmYtZmZmZmZmZmZmZmZmKSQvO1xuICAgIHJldHVybiBuZXcgUmVnRXhwKGBeKFswLTlhLWZBLUZdezh9LVswLTlhLWZBLUZdezR9LSR7dmVyc2lvbn1bMC05YS1mQS1GXXszfS1bODlhYkFCXVswLTlhLWZBLUZdezN9LVswLTlhLWZBLUZdezEyfSkkYCk7XG59O1xuZXhwb3J0IGNvbnN0IHV1aWQ0ID0gLypAX19QVVJFX18qLyB1dWlkKDQpO1xuZXhwb3J0IGNvbnN0IHV1aWQ2ID0gLypAX19QVVJFX18qLyB1dWlkKDYpO1xuZXhwb3J0IGNvbnN0IHV1aWQ3ID0gLypAX19QVVJFX18qLyB1dWlkKDcpO1xuLyoqIFByYWN0aWNhbCBlbWFpbCB2YWxpZGF0aW9uICovIGV4cG9ydCBjb25zdCBlbWFpbCA9IC9eKD8hXFwuKSg/IS4qXFwuXFwuKShbQS1aYS16MC05XycrXFwtXFwuXSopW0EtWmEtejAtOV8rLV1AKFtBLVphLXowLTldW0EtWmEtejAtOVxcLV0qXFwuKStbQS1aYS16XXsyLH0kLztcbi8qKiBFcXVpdmFsZW50IHRvIHRoZSBIVE1MNSBpbnB1dFt0eXBlPWVtYWlsXSB2YWxpZGF0aW9uIGltcGxlbWVudGVkIGJ5IGJyb3dzZXJzLiBTb3VyY2U6IGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvRWxlbWVudC9pbnB1dC9lbWFpbCAqLyBleHBvcnQgY29uc3QgaHRtbDVFbWFpbCA9IC9eW2EtekEtWjAtOS4hIyQlJicqKy89P15fYHt8fX4tXStAW2EtekEtWjAtOV0oPzpbYS16QS1aMC05LV17MCw2MX1bYS16QS1aMC05XSk/KD86XFwuW2EtekEtWjAtOV0oPzpbYS16QS1aMC05LV17MCw2MX1bYS16QS1aMC05XSk/KSokLztcbi8qKiBUaGUgY2xhc3NpYyBlbWFpbHJlZ2V4LmNvbSByZWdleCBmb3IgUkZDIDUzMjItY29tcGxpYW50IGVtYWlscyAqLyBleHBvcnQgY29uc3QgcmZjNTMyMkVtYWlsID0gL14oKFtePD4oKVxcW1xcXVxcXFwuLDs6XFxzQFwiXSsoXFwuW148PigpXFxbXFxdXFxcXC4sOzpcXHNAXCJdKykqKXwoXCIuK1wiKSlAKChcXFtbMC05XXsxLDN9XFwuWzAtOV17MSwzfVxcLlswLTldezEsM31cXC5bMC05XXsxLDN9XSl8KChbYS16QS1aXFwtMC05XStcXC4pK1thLXpBLVpdezIsfSkpJC87XG4vKiogQSBsb29zZSByZWdleCB0aGF0IGFsbG93cyBVbmljb2RlIGNoYXJhY3RlcnMsIGVuZm9yY2VzIGxlbmd0aCBsaW1pdHMsIGFuZCB0aGF0J3MgYWJvdXQgaXQuICovIGV4cG9ydCBjb25zdCB1bmljb2RlRW1haWwgPSAvXlteXFxzQFwiXXsxLDY0fUBbXlxcc0BdezEsMjU1fSQvdTtcbmV4cG9ydCBjb25zdCBpZG5FbWFpbCA9IHVuaWNvZGVFbWFpbDtcbmV4cG9ydCBjb25zdCBicm93c2VyRW1haWwgPSAvXlthLXpBLVowLTkuISMkJSYnKisvPT9eX2B7fH1+LV0rQFthLXpBLVowLTldKD86W2EtekEtWjAtOS1dezAsNjF9W2EtekEtWjAtOV0pPyg/OlxcLlthLXpBLVowLTldKD86W2EtekEtWjAtOS1dezAsNjF9W2EtekEtWjAtOV0pPykqJC87XG4vLyBmcm9tIGh0dHBzOi8vdGhla2V2aW5zY290dC5jb20vZW1vamlzLWluLWphdmFzY3JpcHQvI3dyaXRpbmctYS1yZWd1bGFyLWV4cHJlc3Npb25cbmNvbnN0IF9lbW9qaSA9IGBeKFxcXFxwe0V4dGVuZGVkX1BpY3RvZ3JhcGhpY318XFxcXHB7RW1vamlfQ29tcG9uZW50fSkrJGA7XG5leHBvcnQgZnVuY3Rpb24gZW1vamkoKSB7XG4gICAgcmV0dXJuIG5ldyBSZWdFeHAoX2Vtb2ppLCBcInVcIik7XG59XG5leHBvcnQgY29uc3QgaXB2NCA9IC9eKD86KD86MjVbMC01XXwyWzAtNF1bMC05XXwxWzAtOV1bMC05XXxbMS05XVswLTldfFswLTldKVxcLil7M30oPzoyNVswLTVdfDJbMC00XVswLTldfDFbMC05XVswLTldfFsxLTldWzAtOV18WzAtOV0pJC87XG5leHBvcnQgY29uc3QgaXB2NiA9IC9eKChbMC05YS1mQS1GXXsxLDR9Oil7N31bMC05YS1mQS1GXXsxLDR9fChbMC05YS1mQS1GXXsxLDR9Oil7MSw3fTp8KFswLTlhLWZBLUZdezEsNH06KXsxLDZ9OlswLTlhLWZBLUZdezEsNH18KFswLTlhLWZBLUZdezEsNH06KXsxLDV9KDpbMC05YS1mQS1GXXsxLDR9KXsxLDJ9fChbMC05YS1mQS1GXXsxLDR9Oil7MSw0fSg6WzAtOWEtZkEtRl17MSw0fSl7MSwzfXwoWzAtOWEtZkEtRl17MSw0fTopezEsM30oOlswLTlhLWZBLUZdezEsNH0pezEsNH18KFswLTlhLWZBLUZdezEsNH06KXsxLDJ9KDpbMC05YS1mQS1GXXsxLDR9KXsxLDV9fFswLTlhLWZBLUZdezEsNH06KCg6WzAtOWEtZkEtRl17MSw0fSl7MSw2fSl8OigoOlswLTlhLWZBLUZdezEsNH0pezEsN318OikpJC87XG5leHBvcnQgY29uc3QgY2lkcnY0ID0gL14oKDI1WzAtNV18MlswLTRdWzAtOV18MVswLTldWzAtOV18WzEtOV1bMC05XXxbMC05XSlcXC4pezN9KDI1WzAtNV18MlswLTRdWzAtOV18MVswLTldWzAtOV18WzEtOV1bMC05XXxbMC05XSlcXC8oWzAtOV18WzEtMl1bMC05XXwzWzAtMl0pJC87XG5leHBvcnQgY29uc3QgY2lkcnY2ID0gL14oKFswLTlhLWZBLUZdezEsNH06KXs3fVswLTlhLWZBLUZdezEsNH18Ojp8KFswLTlhLWZBLUZdezEsNH0pPzo6KFswLTlhLWZBLUZdezEsNH06Pyl7MCw2fSlcXC8oMTJbMC04XXwxWzAxXVswLTldfFsxLTldP1swLTldKSQvO1xuLy8gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNzg2MDM5Mi9kZXRlcm1pbmUtaWYtc3RyaW5nLWlzLWluLWJhc2U2NC11c2luZy1qYXZhc2NyaXB0XG5leHBvcnQgY29uc3QgYmFzZTY0ID0gL14kfF4oPzpbMC05YS16QS1aKy9dezR9KSooPzooPzpbMC05YS16QS1aKy9dezJ9PT0pfCg/OlswLTlhLXpBLVorL117M309KSk/JC87XG5leHBvcnQgY29uc3QgYmFzZTY0dXJsID0gL15bQS1aYS16MC05Xy1dKiQvO1xuLy8gYmFzZWQgb24gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTA2MTc5L3JlZ3VsYXItZXhwcmVzc2lvbi10by1tYXRjaC1kbnMtaG9zdG5hbWUtb3ItaXAtYWRkcmVzc1xuLy8gZXhwb3J0IGNvbnN0IGhvc3RuYW1lOiBSZWdFeHAgPSAvXihbYS16QS1aMC05LV0rXFwuKSpbYS16QS1aMC05LV0rJC87XG5leHBvcnQgY29uc3QgaG9zdG5hbWUgPSAvXig/PS57MSwyNTN9XFwuPyQpW2EtekEtWjAtOV0oPzpbYS16QS1aMC05LV17MCw2MX1bYS16QS1aMC05XSk/KD86XFwuW2EtekEtWjAtOV0oPzpbLTAtOWEtekEtWl17MCw2MX1bMC05YS16QS1aXSk/KSpcXC4/JC87XG5leHBvcnQgY29uc3QgZG9tYWluID0gL14oW2EtekEtWjAtOV0oPzpbYS16QS1aMC05LV17MCw2MX1bYS16QS1aMC05XSk/XFwuKStbYS16QS1aXXsyLH0kLztcbi8vIGh0dHBzOi8vYmxvZy5zdGV2ZW5sZXZpdGhhbi5jb20vYXJjaGl2ZXMvdmFsaWRhdGUtcGhvbmUtbnVtYmVyI3I0LTMgKHJlZ2V4IHNhbnMgc3BhY2VzKVxuZXhwb3J0IGNvbnN0IGUxNjQgPSAvXlxcKyg/OlswLTldKXs2LDE0fVswLTldJC87XG4vLyBjb25zdCBkYXRlU291cmNlID0gYCgoXFxcXGRcXFxcZFsyNDY4XVswNDhdfFxcXFxkXFxcXGRbMTM1NzldWzI2XXxcXFxcZFxcXFxkMFs0OF18WzAyNDY4XVswNDhdMDB8WzEzNTc5XVsyNl0wMCktMDItMjl8XFxcXGR7NH0tKCgwWzEzNTc4XXwxWzAyXSktKDBbMS05XXxbMTJdXFxcXGR8M1swMV0pfCgwWzQ2OV18MTEpLSgwWzEtOV18WzEyXVxcXFxkfDMwKXwoMDIpLSgwWzEtOV18MVxcXFxkfDJbMC04XSkpKWA7XG5jb25zdCBkYXRlU291cmNlID0gYCg/Oig/OlxcXFxkXFxcXGRbMjQ2OF1bMDQ4XXxcXFxcZFxcXFxkWzEzNTc5XVsyNl18XFxcXGRcXFxcZDBbNDhdfFswMjQ2OF1bMDQ4XTAwfFsxMzU3OV1bMjZdMDApLTAyLTI5fFxcXFxkezR9LSg/Oig/OjBbMTM1NzhdfDFbMDJdKS0oPzowWzEtOV18WzEyXVxcXFxkfDNbMDFdKXwoPzowWzQ2OV18MTEpLSg/OjBbMS05XXxbMTJdXFxcXGR8MzApfCg/OjAyKS0oPzowWzEtOV18MVxcXFxkfDJbMC04XSkpKWA7XG5leHBvcnQgY29uc3QgZGF0ZSA9IC8qQF9fUFVSRV9fKi8gbmV3IFJlZ0V4cChgXiR7ZGF0ZVNvdXJjZX0kYCk7XG5mdW5jdGlvbiB0aW1lU291cmNlKGFyZ3MpIHtcbiAgICBjb25zdCBoaG1tID0gYCg/OlswMV1cXFxcZHwyWzAtM10pOlswLTVdXFxcXGRgO1xuICAgIGNvbnN0IHJlZ2V4ID0gdHlwZW9mIGFyZ3MucHJlY2lzaW9uID09PSBcIm51bWJlclwiID8gYXJncy5wcmVjaXNpb24gPT09IC0xID8gYCR7aGhtbX1gIDogYXJncy5wcmVjaXNpb24gPT09IDAgPyBgJHtoaG1tfTpbMC01XVxcXFxkYCA6IGAke2hobW19OlswLTVdXFxcXGRcXFxcLlxcXFxkeyR7YXJncy5wcmVjaXNpb259fWAgOiBgJHtoaG1tfSg/OjpbMC01XVxcXFxkKD86XFxcXC5cXFxcZCspPyk/YDtcbiAgICByZXR1cm4gcmVnZXg7XG59XG5leHBvcnQgZnVuY3Rpb24gdGltZShhcmdzKSB7XG4gICAgcmV0dXJuIG5ldyBSZWdFeHAoYF4ke3RpbWVTb3VyY2UoYXJncyl9JGApO1xufVxuLy8gQWRhcHRlZCBmcm9tIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8zMTQzMjMxXG5leHBvcnQgZnVuY3Rpb24gZGF0ZXRpbWUoYXJncykge1xuICAgIGNvbnN0IHRpbWUgPSB0aW1lU291cmNlKHtcbiAgICAgICAgcHJlY2lzaW9uOiBhcmdzLnByZWNpc2lvblxuICAgIH0pO1xuICAgIGNvbnN0IG9wdHMgPSBbXG4gICAgICAgIFwiWlwiXG4gICAgXTtcbiAgICBpZiAoYXJncy5sb2NhbCkgb3B0cy5wdXNoKFwiXCIpO1xuICAgIC8vIGlmIChhcmdzLm9mZnNldCkgb3B0cy5wdXNoKGAoWystXVxcXFxkezJ9OlxcXFxkezJ9KWApO1xuICAgIGlmIChhcmdzLm9mZnNldCkgb3B0cy5wdXNoKGAoWystXSg/OlswMV1cXFxcZHwyWzAtM10pOlswLTVdXFxcXGQpYCk7XG4gICAgY29uc3QgdGltZVJlZ2V4ID0gYCR7dGltZX0oPzoke29wdHMuam9pbihcInxcIil9KWA7XG4gICAgcmV0dXJuIG5ldyBSZWdFeHAoYF4ke2RhdGVTb3VyY2V9VCg/OiR7dGltZVJlZ2V4fSkkYCk7XG59XG5leHBvcnQgY29uc3Qgc3RyaW5nID0gKHBhcmFtcyk9PntcbiAgICBjb25zdCByZWdleCA9IHBhcmFtcyA/IGBbXFxcXHNcXFxcU117JHtwYXJhbXM/Lm1pbmltdW0gPz8gMH0sJHtwYXJhbXM/Lm1heGltdW0gPz8gXCJcIn19YCA6IGBbXFxcXHNcXFxcU10qYDtcbiAgICByZXR1cm4gbmV3IFJlZ0V4cChgXiR7cmVnZXh9JGApO1xufTtcbmV4cG9ydCBjb25zdCBiaWdpbnQgPSAvXi0/XFxkK24/JC87XG5leHBvcnQgY29uc3QgaW50ZWdlciA9IC9eLT9cXGQrJC87XG5leHBvcnQgY29uc3QgbnVtYmVyID0gL14tP1xcZCsoPzpcXC5cXGQrKT8vO1xuZXhwb3J0IGNvbnN0IGJvb2xlYW4gPSAvXig/OnRydWV8ZmFsc2UpJC9pO1xuY29uc3QgX251bGwgPSAvXm51bGwkL2k7XG5leHBvcnQgeyBfbnVsbCBhcyBudWxsIH07XG5jb25zdCBfdW5kZWZpbmVkID0gL151bmRlZmluZWQkL2k7XG5leHBvcnQgeyBfdW5kZWZpbmVkIGFzIHVuZGVmaW5lZCB9O1xuLy8gcmVnZXggZm9yIHN0cmluZyB3aXRoIG5vIHVwcGVyY2FzZSBsZXR0ZXJzXG5leHBvcnQgY29uc3QgbG93ZXJjYXNlID0gL15bXkEtWl0qJC87XG4vLyByZWdleCBmb3Igc3RyaW5nIHdpdGggbm8gbG93ZXJjYXNlIGxldHRlcnNcbmV4cG9ydCBjb25zdCB1cHBlcmNhc2UgPSAvXlteYS16XSokLztcbi8vIHJlZ2V4IGZvciBoZXhhZGVjaW1hbCBzdHJpbmdzIChhbnkgbGVuZ3RoKVxuZXhwb3J0IGNvbnN0IGhleCA9IC9eWzAtOWEtZkEtRl0qJC87XG4vLyBIYXNoIHJlZ2V4ZXMgZm9yIGRpZmZlcmVudCBhbGdvcml0aG1zIGFuZCBlbmNvZGluZ3Ncbi8vIEhlbHBlciBmdW5jdGlvbiB0byBjcmVhdGUgYmFzZTY0IHJlZ2V4IHdpdGggZXhhY3QgbGVuZ3RoIGFuZCBwYWRkaW5nXG5mdW5jdGlvbiBmaXhlZEJhc2U2NChib2R5TGVuZ3RoLCBwYWRkaW5nKSB7XG4gICAgcmV0dXJuIG5ldyBSZWdFeHAoYF5bQS1aYS16MC05Ky9deyR7Ym9keUxlbmd0aH19JHtwYWRkaW5nfSRgKTtcbn1cbi8vIEhlbHBlciBmdW5jdGlvbiB0byBjcmVhdGUgYmFzZTY0dXJsIHJlZ2V4IHdpdGggZXhhY3QgbGVuZ3RoIChubyBwYWRkaW5nKVxuZnVuY3Rpb24gZml4ZWRCYXNlNjR1cmwobGVuZ3RoKSB7XG4gICAgcmV0dXJuIG5ldyBSZWdFeHAoYF5bQS1aYS16MC05Xy1deyR7bGVuZ3RofX0kYCk7XG59XG4vLyBNRDUgKDE2IGJ5dGVzKTogYmFzZTY0ID0gMjQgY2hhcnMgdG90YWwgKDIyICsgXCI9PVwiKVxuZXhwb3J0IGNvbnN0IG1kNV9oZXggPSAvXlswLTlhLWZBLUZdezMyfSQvO1xuZXhwb3J0IGNvbnN0IG1kNV9iYXNlNjQgPSAvKkBfX1BVUkVfXyovIGZpeGVkQmFzZTY0KDIyLCBcIj09XCIpO1xuZXhwb3J0IGNvbnN0IG1kNV9iYXNlNjR1cmwgPSAvKkBfX1BVUkVfXyovIGZpeGVkQmFzZTY0dXJsKDIyKTtcbi8vIFNIQTEgKDIwIGJ5dGVzKTogYmFzZTY0ID0gMjggY2hhcnMgdG90YWwgKDI3ICsgXCI9XCIpXG5leHBvcnQgY29uc3Qgc2hhMV9oZXggPSAvXlswLTlhLWZBLUZdezQwfSQvO1xuZXhwb3J0IGNvbnN0IHNoYTFfYmFzZTY0ID0gLypAX19QVVJFX18qLyBmaXhlZEJhc2U2NCgyNywgXCI9XCIpO1xuZXhwb3J0IGNvbnN0IHNoYTFfYmFzZTY0dXJsID0gLypAX19QVVJFX18qLyBmaXhlZEJhc2U2NHVybCgyNyk7XG4vLyBTSEEyNTYgKDMyIGJ5dGVzKTogYmFzZTY0ID0gNDQgY2hhcnMgdG90YWwgKDQzICsgXCI9XCIpXG5leHBvcnQgY29uc3Qgc2hhMjU2X2hleCA9IC9eWzAtOWEtZkEtRl17NjR9JC87XG5leHBvcnQgY29uc3Qgc2hhMjU2X2Jhc2U2NCA9IC8qQF9fUFVSRV9fKi8gZml4ZWRCYXNlNjQoNDMsIFwiPVwiKTtcbmV4cG9ydCBjb25zdCBzaGEyNTZfYmFzZTY0dXJsID0gLypAX19QVVJFX18qLyBmaXhlZEJhc2U2NHVybCg0Myk7XG4vLyBTSEEzODQgKDQ4IGJ5dGVzKTogYmFzZTY0ID0gNjQgY2hhcnMgdG90YWwgKG5vIHBhZGRpbmcpXG5leHBvcnQgY29uc3Qgc2hhMzg0X2hleCA9IC9eWzAtOWEtZkEtRl17OTZ9JC87XG5leHBvcnQgY29uc3Qgc2hhMzg0X2Jhc2U2NCA9IC8qQF9fUFVSRV9fKi8gZml4ZWRCYXNlNjQoNjQsIFwiXCIpO1xuZXhwb3J0IGNvbnN0IHNoYTM4NF9iYXNlNjR1cmwgPSAvKkBfX1BVUkVfXyovIGZpeGVkQmFzZTY0dXJsKDY0KTtcbi8vIFNIQTUxMiAoNjQgYnl0ZXMpOiBiYXNlNjQgPSA4OCBjaGFycyB0b3RhbCAoODYgKyBcIj09XCIpXG5leHBvcnQgY29uc3Qgc2hhNTEyX2hleCA9IC9eWzAtOWEtZkEtRl17MTI4fSQvO1xuZXhwb3J0IGNvbnN0IHNoYTUxMl9iYXNlNjQgPSAvKkBfX1BVUkVfXyovIGZpeGVkQmFzZTY0KDg2LCBcIj09XCIpO1xuZXhwb3J0IGNvbnN0IHNoYTUxMl9iYXNlNjR1cmwgPSAvKkBfX1BVUkVfXyovIGZpeGVkQmFzZTY0dXJsKDg2KTtcbiIsICIvLyBpbXBvcnQgeyAkWm9kVHlwZSB9IGZyb20gXCIuL3NjaGVtYXMuanNcIjtcbmltcG9ydCAqIGFzIGNvcmUgZnJvbSBcIi4vY29yZS5qc1wiO1xuaW1wb3J0ICogYXMgcmVnZXhlcyBmcm9tIFwiLi9yZWdleGVzLmpzXCI7XG5pbXBvcnQgKiBhcyB1dGlsIGZyb20gXCIuL3V0aWwuanNcIjtcbmV4cG9ydCBjb25zdCAkWm9kQ2hlY2sgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZENoZWNrXCIsIChpbnN0LCBkZWYpPT57XG4gICAgdmFyIF9hO1xuICAgIGluc3QuX3pvZCA/PyAoaW5zdC5fem9kID0ge30pO1xuICAgIGluc3QuX3pvZC5kZWYgPSBkZWY7XG4gICAgKF9hID0gaW5zdC5fem9kKS5vbmF0dGFjaCA/PyAoX2Eub25hdHRhY2ggPSBbXSk7XG59KTtcbmNvbnN0IG51bWVyaWNPcmlnaW5NYXAgPSB7XG4gICAgbnVtYmVyOiBcIm51bWJlclwiLFxuICAgIGJpZ2ludDogXCJiaWdpbnRcIixcbiAgICBvYmplY3Q6IFwiZGF0ZVwiXG59O1xuZXhwb3J0IGNvbnN0ICRab2RDaGVja0xlc3NUaGFuID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RDaGVja0xlc3NUaGFuXCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZENoZWNrLmluaXQoaW5zdCwgZGVmKTtcbiAgICBjb25zdCBvcmlnaW4gPSBudW1lcmljT3JpZ2luTWFwW3R5cGVvZiBkZWYudmFsdWVdO1xuICAgIGluc3QuX3pvZC5vbmF0dGFjaC5wdXNoKChpbnN0KT0+e1xuICAgICAgICBjb25zdCBiYWcgPSBpbnN0Ll96b2QuYmFnO1xuICAgICAgICBjb25zdCBjdXJyID0gKGRlZi5pbmNsdXNpdmUgPyBiYWcubWF4aW11bSA6IGJhZy5leGNsdXNpdmVNYXhpbXVtKSA/PyBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7XG4gICAgICAgIGlmIChkZWYudmFsdWUgPCBjdXJyKSB7XG4gICAgICAgICAgICBpZiAoZGVmLmluY2x1c2l2ZSkgYmFnLm1heGltdW0gPSBkZWYudmFsdWU7XG4gICAgICAgICAgICBlbHNlIGJhZy5leGNsdXNpdmVNYXhpbXVtID0gZGVmLnZhbHVlO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgaW5zdC5fem9kLmNoZWNrID0gKHBheWxvYWQpPT57XG4gICAgICAgIGlmIChkZWYuaW5jbHVzaXZlID8gcGF5bG9hZC52YWx1ZSA8PSBkZWYudmFsdWUgOiBwYXlsb2FkLnZhbHVlIDwgZGVmLnZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICBvcmlnaW4sXG4gICAgICAgICAgICBjb2RlOiBcInRvb19iaWdcIixcbiAgICAgICAgICAgIG1heGltdW06IGRlZi52YWx1ZSxcbiAgICAgICAgICAgIGlucHV0OiBwYXlsb2FkLnZhbHVlLFxuICAgICAgICAgICAgaW5jbHVzaXZlOiBkZWYuaW5jbHVzaXZlLFxuICAgICAgICAgICAgaW5zdCxcbiAgICAgICAgICAgIGNvbnRpbnVlOiAhZGVmLmFib3J0XG4gICAgICAgIH0pO1xuICAgIH07XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kQ2hlY2tHcmVhdGVyVGhhbiA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kQ2hlY2tHcmVhdGVyVGhhblwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RDaGVjay5pbml0KGluc3QsIGRlZik7XG4gICAgY29uc3Qgb3JpZ2luID0gbnVtZXJpY09yaWdpbk1hcFt0eXBlb2YgZGVmLnZhbHVlXTtcbiAgICBpbnN0Ll96b2Qub25hdHRhY2gucHVzaCgoaW5zdCk9PntcbiAgICAgICAgY29uc3QgYmFnID0gaW5zdC5fem9kLmJhZztcbiAgICAgICAgY29uc3QgY3VyciA9IChkZWYuaW5jbHVzaXZlID8gYmFnLm1pbmltdW0gOiBiYWcuZXhjbHVzaXZlTWluaW11bSkgPz8gTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZO1xuICAgICAgICBpZiAoZGVmLnZhbHVlID4gY3Vycikge1xuICAgICAgICAgICAgaWYgKGRlZi5pbmNsdXNpdmUpIGJhZy5taW5pbXVtID0gZGVmLnZhbHVlO1xuICAgICAgICAgICAgZWxzZSBiYWcuZXhjbHVzaXZlTWluaW11bSA9IGRlZi52YWx1ZTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIGluc3QuX3pvZC5jaGVjayA9IChwYXlsb2FkKT0+e1xuICAgICAgICBpZiAoZGVmLmluY2x1c2l2ZSA/IHBheWxvYWQudmFsdWUgPj0gZGVmLnZhbHVlIDogcGF5bG9hZC52YWx1ZSA+IGRlZi52YWx1ZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgb3JpZ2luLFxuICAgICAgICAgICAgY29kZTogXCJ0b29fc21hbGxcIixcbiAgICAgICAgICAgIG1pbmltdW06IGRlZi52YWx1ZSxcbiAgICAgICAgICAgIGlucHV0OiBwYXlsb2FkLnZhbHVlLFxuICAgICAgICAgICAgaW5jbHVzaXZlOiBkZWYuaW5jbHVzaXZlLFxuICAgICAgICAgICAgaW5zdCxcbiAgICAgICAgICAgIGNvbnRpbnVlOiAhZGVmLmFib3J0XG4gICAgICAgIH0pO1xuICAgIH07XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kQ2hlY2tNdWx0aXBsZU9mID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RDaGVja011bHRpcGxlT2ZcIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kQ2hlY2suaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5vbmF0dGFjaC5wdXNoKChpbnN0KT0+e1xuICAgICAgICB2YXIgX2E7XG4gICAgICAgIChfYSA9IGluc3QuX3pvZC5iYWcpLm11bHRpcGxlT2YgPz8gKF9hLm11bHRpcGxlT2YgPSBkZWYudmFsdWUpO1xuICAgIH0pO1xuICAgIGluc3QuX3pvZC5jaGVjayA9IChwYXlsb2FkKT0+e1xuICAgICAgICBpZiAodHlwZW9mIHBheWxvYWQudmFsdWUgIT09IHR5cGVvZiBkZWYudmFsdWUpIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBtaXggbnVtYmVyIGFuZCBiaWdpbnQgaW4gbXVsdGlwbGVfb2YgY2hlY2suXCIpO1xuICAgICAgICBjb25zdCBpc011bHRpcGxlID0gdHlwZW9mIHBheWxvYWQudmFsdWUgPT09IFwiYmlnaW50XCIgPyBwYXlsb2FkLnZhbHVlICUgZGVmLnZhbHVlID09PSBCaWdJbnQoMCkgOiB1dGlsLmZsb2F0U2FmZVJlbWFpbmRlcihwYXlsb2FkLnZhbHVlLCBkZWYudmFsdWUpID09PSAwO1xuICAgICAgICBpZiAoaXNNdWx0aXBsZSkgcmV0dXJuO1xuICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICAgIG9yaWdpbjogdHlwZW9mIHBheWxvYWQudmFsdWUsXG4gICAgICAgICAgICBjb2RlOiBcIm5vdF9tdWx0aXBsZV9vZlwiLFxuICAgICAgICAgICAgZGl2aXNvcjogZGVmLnZhbHVlLFxuICAgICAgICAgICAgaW5wdXQ6IHBheWxvYWQudmFsdWUsXG4gICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgfSk7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RDaGVja051bWJlckZvcm1hdCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kQ2hlY2tOdW1iZXJGb3JtYXRcIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kQ2hlY2suaW5pdChpbnN0LCBkZWYpOyAvLyBubyBmb3JtYXQgY2hlY2tzXG4gICAgZGVmLmZvcm1hdCA9IGRlZi5mb3JtYXQgfHwgXCJmbG9hdDY0XCI7XG4gICAgY29uc3QgaXNJbnQgPSBkZWYuZm9ybWF0Py5pbmNsdWRlcyhcImludFwiKTtcbiAgICBjb25zdCBvcmlnaW4gPSBpc0ludCA/IFwiaW50XCIgOiBcIm51bWJlclwiO1xuICAgIGNvbnN0IFttaW5pbXVtLCBtYXhpbXVtXSA9IHV0aWwuTlVNQkVSX0ZPUk1BVF9SQU5HRVNbZGVmLmZvcm1hdF07XG4gICAgaW5zdC5fem9kLm9uYXR0YWNoLnB1c2goKGluc3QpPT57XG4gICAgICAgIGNvbnN0IGJhZyA9IGluc3QuX3pvZC5iYWc7XG4gICAgICAgIGJhZy5mb3JtYXQgPSBkZWYuZm9ybWF0O1xuICAgICAgICBiYWcubWluaW11bSA9IG1pbmltdW07XG4gICAgICAgIGJhZy5tYXhpbXVtID0gbWF4aW11bTtcbiAgICAgICAgaWYgKGlzSW50KSBiYWcucGF0dGVybiA9IHJlZ2V4ZXMuaW50ZWdlcjtcbiAgICB9KTtcbiAgICBpbnN0Ll96b2QuY2hlY2sgPSAocGF5bG9hZCk9PntcbiAgICAgICAgY29uc3QgaW5wdXQgPSBwYXlsb2FkLnZhbHVlO1xuICAgICAgICBpZiAoaXNJbnQpIHtcbiAgICAgICAgICAgIGlmICghTnVtYmVyLmlzSW50ZWdlcihpbnB1dCkpIHtcbiAgICAgICAgICAgICAgICAvLyBpbnZhbGlkX2Zvcm1hdCBpc3N1ZVxuICAgICAgICAgICAgICAgIC8vIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgICAgIC8vICAgZXhwZWN0ZWQ6IGRlZi5mb3JtYXQsXG4gICAgICAgICAgICAgICAgLy8gICBmb3JtYXQ6IGRlZi5mb3JtYXQsXG4gICAgICAgICAgICAgICAgLy8gICBjb2RlOiBcImludmFsaWRfZm9ybWF0XCIsXG4gICAgICAgICAgICAgICAgLy8gICBpbnB1dCxcbiAgICAgICAgICAgICAgICAvLyAgIGluc3QsXG4gICAgICAgICAgICAgICAgLy8gfSk7XG4gICAgICAgICAgICAgICAgLy8gaW52YWxpZF90eXBlIGlzc3VlXG4gICAgICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBvcmlnaW4sXG4gICAgICAgICAgICAgICAgICAgIGZvcm1hdDogZGVmLmZvcm1hdCxcbiAgICAgICAgICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX3R5cGVcIixcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBpbnB1dCxcbiAgICAgICAgICAgICAgICAgICAgaW5zdFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIC8vIG5vdF9tdWx0aXBsZV9vZiBpc3N1ZVxuICAgICAgICAgICAgLy8gcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAvLyAgIGNvZGU6IFwibm90X211bHRpcGxlX29mXCIsXG4gICAgICAgICAgICAvLyAgIG9yaWdpbjogXCJudW1iZXJcIixcbiAgICAgICAgICAgIC8vICAgaW5wdXQsXG4gICAgICAgICAgICAvLyAgIGluc3QsXG4gICAgICAgICAgICAvLyAgIGRpdmlzb3I6IDEsXG4gICAgICAgICAgICAvLyB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghTnVtYmVyLmlzU2FmZUludGVnZXIoaW5wdXQpKSB7XG4gICAgICAgICAgICAgICAgaWYgKGlucHV0ID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAvLyB0b29fYmlnXG4gICAgICAgICAgICAgICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBcInRvb19iaWdcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIG1heGltdW06IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSLFxuICAgICAgICAgICAgICAgICAgICAgICAgbm90ZTogXCJJbnRlZ2VycyBtdXN0IGJlIHdpdGhpbiB0aGUgc2FmZSBpbnRlZ2VyIHJhbmdlLlwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgaW5zdCxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbixcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOiAhZGVmLmFib3J0XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHRvb19zbWFsbFxuICAgICAgICAgICAgICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogXCJ0b29fc21hbGxcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIG1pbmltdW06IE51bWJlci5NSU5fU0FGRV9JTlRFR0VSLFxuICAgICAgICAgICAgICAgICAgICAgICAgbm90ZTogXCJJbnRlZ2VycyBtdXN0IGJlIHdpdGhpbiB0aGUgc2FmZSBpbnRlZ2VyIHJhbmdlLlwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgaW5zdCxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbixcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOiAhZGVmLmFib3J0XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlucHV0IDwgbWluaW11bSkge1xuICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgb3JpZ2luOiBcIm51bWJlclwiLFxuICAgICAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgICAgIGNvZGU6IFwidG9vX3NtYWxsXCIsXG4gICAgICAgICAgICAgICAgbWluaW11bSxcbiAgICAgICAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsXG4gICAgICAgICAgICAgICAgaW5zdCxcbiAgICAgICAgICAgICAgICBjb250aW51ZTogIWRlZi5hYm9ydFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlucHV0ID4gbWF4aW11bSkge1xuICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgb3JpZ2luOiBcIm51bWJlclwiLFxuICAgICAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgICAgIGNvZGU6IFwidG9vX2JpZ1wiLFxuICAgICAgICAgICAgICAgIG1heGltdW0sXG4gICAgICAgICAgICAgICAgaW5zdFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZENoZWNrQmlnSW50Rm9ybWF0ID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RDaGVja0JpZ0ludEZvcm1hdFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RDaGVjay5pbml0KGluc3QsIGRlZik7IC8vIG5vIGZvcm1hdCBjaGVja3NcbiAgICBjb25zdCBbbWluaW11bSwgbWF4aW11bV0gPSB1dGlsLkJJR0lOVF9GT1JNQVRfUkFOR0VTW2RlZi5mb3JtYXRdO1xuICAgIGluc3QuX3pvZC5vbmF0dGFjaC5wdXNoKChpbnN0KT0+e1xuICAgICAgICBjb25zdCBiYWcgPSBpbnN0Ll96b2QuYmFnO1xuICAgICAgICBiYWcuZm9ybWF0ID0gZGVmLmZvcm1hdDtcbiAgICAgICAgYmFnLm1pbmltdW0gPSBtaW5pbXVtO1xuICAgICAgICBiYWcubWF4aW11bSA9IG1heGltdW07XG4gICAgfSk7XG4gICAgaW5zdC5fem9kLmNoZWNrID0gKHBheWxvYWQpPT57XG4gICAgICAgIGNvbnN0IGlucHV0ID0gcGF5bG9hZC52YWx1ZTtcbiAgICAgICAgaWYgKGlucHV0IDwgbWluaW11bSkge1xuICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgb3JpZ2luOiBcImJpZ2ludFwiLFxuICAgICAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgICAgIGNvZGU6IFwidG9vX3NtYWxsXCIsXG4gICAgICAgICAgICAgICAgbWluaW11bTogbWluaW11bSxcbiAgICAgICAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsXG4gICAgICAgICAgICAgICAgaW5zdCxcbiAgICAgICAgICAgICAgICBjb250aW51ZTogIWRlZi5hYm9ydFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlucHV0ID4gbWF4aW11bSkge1xuICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgb3JpZ2luOiBcImJpZ2ludFwiLFxuICAgICAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgICAgIGNvZGU6IFwidG9vX2JpZ1wiLFxuICAgICAgICAgICAgICAgIG1heGltdW0sXG4gICAgICAgICAgICAgICAgaW5zdFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZENoZWNrTWF4U2l6ZSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kQ2hlY2tNYXhTaXplXCIsIChpbnN0LCBkZWYpPT57XG4gICAgdmFyIF9hO1xuICAgICRab2RDaGVjay5pbml0KGluc3QsIGRlZik7XG4gICAgKF9hID0gaW5zdC5fem9kLmRlZikud2hlbiA/PyAoX2Eud2hlbiA9IChwYXlsb2FkKT0+e1xuICAgICAgICBjb25zdCB2YWwgPSBwYXlsb2FkLnZhbHVlO1xuICAgICAgICByZXR1cm4gIXV0aWwubnVsbGlzaCh2YWwpICYmIHZhbC5zaXplICE9PSB1bmRlZmluZWQ7XG4gICAgfSk7XG4gICAgaW5zdC5fem9kLm9uYXR0YWNoLnB1c2goKGluc3QpPT57XG4gICAgICAgIGNvbnN0IGN1cnIgPSBpbnN0Ll96b2QuYmFnLm1heGltdW0gPz8gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZO1xuICAgICAgICBpZiAoZGVmLm1heGltdW0gPCBjdXJyKSBpbnN0Ll96b2QuYmFnLm1heGltdW0gPSBkZWYubWF4aW11bTtcbiAgICB9KTtcbiAgICBpbnN0Ll96b2QuY2hlY2sgPSAocGF5bG9hZCk9PntcbiAgICAgICAgY29uc3QgaW5wdXQgPSBwYXlsb2FkLnZhbHVlO1xuICAgICAgICBjb25zdCBzaXplID0gaW5wdXQuc2l6ZTtcbiAgICAgICAgaWYgKHNpemUgPD0gZGVmLm1heGltdW0pIHJldHVybjtcbiAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICBvcmlnaW46IHV0aWwuZ2V0U2l6YWJsZU9yaWdpbihpbnB1dCksXG4gICAgICAgICAgICBjb2RlOiBcInRvb19iaWdcIixcbiAgICAgICAgICAgIG1heGltdW06IGRlZi5tYXhpbXVtLFxuICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgfSk7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RDaGVja01pblNpemUgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZENoZWNrTWluU2l6ZVwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIHZhciBfYTtcbiAgICAkWm9kQ2hlY2suaW5pdChpbnN0LCBkZWYpO1xuICAgIChfYSA9IGluc3QuX3pvZC5kZWYpLndoZW4gPz8gKF9hLndoZW4gPSAocGF5bG9hZCk9PntcbiAgICAgICAgY29uc3QgdmFsID0gcGF5bG9hZC52YWx1ZTtcbiAgICAgICAgcmV0dXJuICF1dGlsLm51bGxpc2godmFsKSAmJiB2YWwuc2l6ZSAhPT0gdW5kZWZpbmVkO1xuICAgIH0pO1xuICAgIGluc3QuX3pvZC5vbmF0dGFjaC5wdXNoKChpbnN0KT0+e1xuICAgICAgICBjb25zdCBjdXJyID0gaW5zdC5fem9kLmJhZy5taW5pbXVtID8/IE51bWJlci5ORUdBVElWRV9JTkZJTklUWTtcbiAgICAgICAgaWYgKGRlZi5taW5pbXVtID4gY3VycikgaW5zdC5fem9kLmJhZy5taW5pbXVtID0gZGVmLm1pbmltdW07XG4gICAgfSk7XG4gICAgaW5zdC5fem9kLmNoZWNrID0gKHBheWxvYWQpPT57XG4gICAgICAgIGNvbnN0IGlucHV0ID0gcGF5bG9hZC52YWx1ZTtcbiAgICAgICAgY29uc3Qgc2l6ZSA9IGlucHV0LnNpemU7XG4gICAgICAgIGlmIChzaXplID49IGRlZi5taW5pbXVtKSByZXR1cm47XG4gICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgb3JpZ2luOiB1dGlsLmdldFNpemFibGVPcmlnaW4oaW5wdXQpLFxuICAgICAgICAgICAgY29kZTogXCJ0b29fc21hbGxcIixcbiAgICAgICAgICAgIG1pbmltdW06IGRlZi5taW5pbXVtLFxuICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgfSk7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RDaGVja1NpemVFcXVhbHMgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZENoZWNrU2l6ZUVxdWFsc1wiLCAoaW5zdCwgZGVmKT0+e1xuICAgIHZhciBfYTtcbiAgICAkWm9kQ2hlY2suaW5pdChpbnN0LCBkZWYpO1xuICAgIChfYSA9IGluc3QuX3pvZC5kZWYpLndoZW4gPz8gKF9hLndoZW4gPSAocGF5bG9hZCk9PntcbiAgICAgICAgY29uc3QgdmFsID0gcGF5bG9hZC52YWx1ZTtcbiAgICAgICAgcmV0dXJuICF1dGlsLm51bGxpc2godmFsKSAmJiB2YWwuc2l6ZSAhPT0gdW5kZWZpbmVkO1xuICAgIH0pO1xuICAgIGluc3QuX3pvZC5vbmF0dGFjaC5wdXNoKChpbnN0KT0+e1xuICAgICAgICBjb25zdCBiYWcgPSBpbnN0Ll96b2QuYmFnO1xuICAgICAgICBiYWcubWluaW11bSA9IGRlZi5zaXplO1xuICAgICAgICBiYWcubWF4aW11bSA9IGRlZi5zaXplO1xuICAgICAgICBiYWcuc2l6ZSA9IGRlZi5zaXplO1xuICAgIH0pO1xuICAgIGluc3QuX3pvZC5jaGVjayA9IChwYXlsb2FkKT0+e1xuICAgICAgICBjb25zdCBpbnB1dCA9IHBheWxvYWQudmFsdWU7XG4gICAgICAgIGNvbnN0IHNpemUgPSBpbnB1dC5zaXplO1xuICAgICAgICBpZiAoc2l6ZSA9PT0gZGVmLnNpemUpIHJldHVybjtcbiAgICAgICAgY29uc3QgdG9vQmlnID0gc2l6ZSA+IGRlZi5zaXplO1xuICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICAgIG9yaWdpbjogdXRpbC5nZXRTaXphYmxlT3JpZ2luKGlucHV0KSxcbiAgICAgICAgICAgIC4uLnRvb0JpZyA/IHtcbiAgICAgICAgICAgICAgICBjb2RlOiBcInRvb19iaWdcIixcbiAgICAgICAgICAgICAgICBtYXhpbXVtOiBkZWYuc2l6ZVxuICAgICAgICAgICAgfSA6IHtcbiAgICAgICAgICAgICAgICBjb2RlOiBcInRvb19zbWFsbFwiLFxuICAgICAgICAgICAgICAgIG1pbmltdW06IGRlZi5zaXplXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgZXhhY3Q6IHRydWUsXG4gICAgICAgICAgICBpbnB1dDogcGF5bG9hZC52YWx1ZSxcbiAgICAgICAgICAgIGluc3QsXG4gICAgICAgICAgICBjb250aW51ZTogIWRlZi5hYm9ydFxuICAgICAgICB9KTtcbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZENoZWNrTWF4TGVuZ3RoID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RDaGVja01heExlbmd0aFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIHZhciBfYTtcbiAgICAkWm9kQ2hlY2suaW5pdChpbnN0LCBkZWYpO1xuICAgIChfYSA9IGluc3QuX3pvZC5kZWYpLndoZW4gPz8gKF9hLndoZW4gPSAocGF5bG9hZCk9PntcbiAgICAgICAgY29uc3QgdmFsID0gcGF5bG9hZC52YWx1ZTtcbiAgICAgICAgcmV0dXJuICF1dGlsLm51bGxpc2godmFsKSAmJiB2YWwubGVuZ3RoICE9PSB1bmRlZmluZWQ7XG4gICAgfSk7XG4gICAgaW5zdC5fem9kLm9uYXR0YWNoLnB1c2goKGluc3QpPT57XG4gICAgICAgIGNvbnN0IGN1cnIgPSBpbnN0Ll96b2QuYmFnLm1heGltdW0gPz8gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZO1xuICAgICAgICBpZiAoZGVmLm1heGltdW0gPCBjdXJyKSBpbnN0Ll96b2QuYmFnLm1heGltdW0gPSBkZWYubWF4aW11bTtcbiAgICB9KTtcbiAgICBpbnN0Ll96b2QuY2hlY2sgPSAocGF5bG9hZCk9PntcbiAgICAgICAgY29uc3QgaW5wdXQgPSBwYXlsb2FkLnZhbHVlO1xuICAgICAgICBjb25zdCBsZW5ndGggPSBpbnB1dC5sZW5ndGg7XG4gICAgICAgIGlmIChsZW5ndGggPD0gZGVmLm1heGltdW0pIHJldHVybjtcbiAgICAgICAgY29uc3Qgb3JpZ2luID0gdXRpbC5nZXRMZW5ndGhhYmxlT3JpZ2luKGlucHV0KTtcbiAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICBvcmlnaW4sXG4gICAgICAgICAgICBjb2RlOiBcInRvb19iaWdcIixcbiAgICAgICAgICAgIG1heGltdW06IGRlZi5tYXhpbXVtLFxuICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgfSk7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RDaGVja01pbkxlbmd0aCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kQ2hlY2tNaW5MZW5ndGhcIiwgKGluc3QsIGRlZik9PntcbiAgICB2YXIgX2E7XG4gICAgJFpvZENoZWNrLmluaXQoaW5zdCwgZGVmKTtcbiAgICAoX2EgPSBpbnN0Ll96b2QuZGVmKS53aGVuID8/IChfYS53aGVuID0gKHBheWxvYWQpPT57XG4gICAgICAgIGNvbnN0IHZhbCA9IHBheWxvYWQudmFsdWU7XG4gICAgICAgIHJldHVybiAhdXRpbC5udWxsaXNoKHZhbCkgJiYgdmFsLmxlbmd0aCAhPT0gdW5kZWZpbmVkO1xuICAgIH0pO1xuICAgIGluc3QuX3pvZC5vbmF0dGFjaC5wdXNoKChpbnN0KT0+e1xuICAgICAgICBjb25zdCBjdXJyID0gaW5zdC5fem9kLmJhZy5taW5pbXVtID8/IE51bWJlci5ORUdBVElWRV9JTkZJTklUWTtcbiAgICAgICAgaWYgKGRlZi5taW5pbXVtID4gY3VycikgaW5zdC5fem9kLmJhZy5taW5pbXVtID0gZGVmLm1pbmltdW07XG4gICAgfSk7XG4gICAgaW5zdC5fem9kLmNoZWNrID0gKHBheWxvYWQpPT57XG4gICAgICAgIGNvbnN0IGlucHV0ID0gcGF5bG9hZC52YWx1ZTtcbiAgICAgICAgY29uc3QgbGVuZ3RoID0gaW5wdXQubGVuZ3RoO1xuICAgICAgICBpZiAobGVuZ3RoID49IGRlZi5taW5pbXVtKSByZXR1cm47XG4gICAgICAgIGNvbnN0IG9yaWdpbiA9IHV0aWwuZ2V0TGVuZ3RoYWJsZU9yaWdpbihpbnB1dCk7XG4gICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgb3JpZ2luLFxuICAgICAgICAgICAgY29kZTogXCJ0b29fc21hbGxcIixcbiAgICAgICAgICAgIG1pbmltdW06IGRlZi5taW5pbXVtLFxuICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgfSk7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RDaGVja0xlbmd0aEVxdWFscyA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kQ2hlY2tMZW5ndGhFcXVhbHNcIiwgKGluc3QsIGRlZik9PntcbiAgICB2YXIgX2E7XG4gICAgJFpvZENoZWNrLmluaXQoaW5zdCwgZGVmKTtcbiAgICAoX2EgPSBpbnN0Ll96b2QuZGVmKS53aGVuID8/IChfYS53aGVuID0gKHBheWxvYWQpPT57XG4gICAgICAgIGNvbnN0IHZhbCA9IHBheWxvYWQudmFsdWU7XG4gICAgICAgIHJldHVybiAhdXRpbC5udWxsaXNoKHZhbCkgJiYgdmFsLmxlbmd0aCAhPT0gdW5kZWZpbmVkO1xuICAgIH0pO1xuICAgIGluc3QuX3pvZC5vbmF0dGFjaC5wdXNoKChpbnN0KT0+e1xuICAgICAgICBjb25zdCBiYWcgPSBpbnN0Ll96b2QuYmFnO1xuICAgICAgICBiYWcubWluaW11bSA9IGRlZi5sZW5ndGg7XG4gICAgICAgIGJhZy5tYXhpbXVtID0gZGVmLmxlbmd0aDtcbiAgICAgICAgYmFnLmxlbmd0aCA9IGRlZi5sZW5ndGg7XG4gICAgfSk7XG4gICAgaW5zdC5fem9kLmNoZWNrID0gKHBheWxvYWQpPT57XG4gICAgICAgIGNvbnN0IGlucHV0ID0gcGF5bG9hZC52YWx1ZTtcbiAgICAgICAgY29uc3QgbGVuZ3RoID0gaW5wdXQubGVuZ3RoO1xuICAgICAgICBpZiAobGVuZ3RoID09PSBkZWYubGVuZ3RoKSByZXR1cm47XG4gICAgICAgIGNvbnN0IG9yaWdpbiA9IHV0aWwuZ2V0TGVuZ3RoYWJsZU9yaWdpbihpbnB1dCk7XG4gICAgICAgIGNvbnN0IHRvb0JpZyA9IGxlbmd0aCA+IGRlZi5sZW5ndGg7XG4gICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgb3JpZ2luLFxuICAgICAgICAgICAgLi4udG9vQmlnID8ge1xuICAgICAgICAgICAgICAgIGNvZGU6IFwidG9vX2JpZ1wiLFxuICAgICAgICAgICAgICAgIG1heGltdW06IGRlZi5sZW5ndGhcbiAgICAgICAgICAgIH0gOiB7XG4gICAgICAgICAgICAgICAgY29kZTogXCJ0b29fc21hbGxcIixcbiAgICAgICAgICAgICAgICBtaW5pbXVtOiBkZWYubGVuZ3RoXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgZXhhY3Q6IHRydWUsXG4gICAgICAgICAgICBpbnB1dDogcGF5bG9hZC52YWx1ZSxcbiAgICAgICAgICAgIGluc3QsXG4gICAgICAgICAgICBjb250aW51ZTogIWRlZi5hYm9ydFxuICAgICAgICB9KTtcbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZENoZWNrU3RyaW5nRm9ybWF0ID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RDaGVja1N0cmluZ0Zvcm1hdFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIHZhciBfYSwgX2I7XG4gICAgJFpvZENoZWNrLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0Ll96b2Qub25hdHRhY2gucHVzaCgoaW5zdCk9PntcbiAgICAgICAgY29uc3QgYmFnID0gaW5zdC5fem9kLmJhZztcbiAgICAgICAgYmFnLmZvcm1hdCA9IGRlZi5mb3JtYXQ7XG4gICAgICAgIGlmIChkZWYucGF0dGVybikge1xuICAgICAgICAgICAgYmFnLnBhdHRlcm5zID8/IChiYWcucGF0dGVybnMgPSBuZXcgU2V0KCkpO1xuICAgICAgICAgICAgYmFnLnBhdHRlcm5zLmFkZChkZWYucGF0dGVybik7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICBpZiAoZGVmLnBhdHRlcm4pIChfYSA9IGluc3QuX3pvZCkuY2hlY2sgPz8gKF9hLmNoZWNrID0gKHBheWxvYWQpPT57XG4gICAgICAgIGRlZi5wYXR0ZXJuLmxhc3RJbmRleCA9IDA7XG4gICAgICAgIGlmIChkZWYucGF0dGVybi50ZXN0KHBheWxvYWQudmFsdWUpKSByZXR1cm47XG4gICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgb3JpZ2luOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX2Zvcm1hdFwiLFxuICAgICAgICAgICAgZm9ybWF0OiBkZWYuZm9ybWF0LFxuICAgICAgICAgICAgaW5wdXQ6IHBheWxvYWQudmFsdWUsXG4gICAgICAgICAgICAuLi5kZWYucGF0dGVybiA/IHtcbiAgICAgICAgICAgICAgICBwYXR0ZXJuOiBkZWYucGF0dGVybi50b1N0cmluZygpXG4gICAgICAgICAgICB9IDoge30sXG4gICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gICAgZWxzZSAoX2IgPSBpbnN0Ll96b2QpLmNoZWNrID8/IChfYi5jaGVjayA9ICgpPT57fSk7XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kQ2hlY2tSZWdleCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kQ2hlY2tSZWdleFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RDaGVja1N0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5fem9kLmNoZWNrID0gKHBheWxvYWQpPT57XG4gICAgICAgIGRlZi5wYXR0ZXJuLmxhc3RJbmRleCA9IDA7XG4gICAgICAgIGlmIChkZWYucGF0dGVybi50ZXN0KHBheWxvYWQudmFsdWUpKSByZXR1cm47XG4gICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgb3JpZ2luOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX2Zvcm1hdFwiLFxuICAgICAgICAgICAgZm9ybWF0OiBcInJlZ2V4XCIsXG4gICAgICAgICAgICBpbnB1dDogcGF5bG9hZC52YWx1ZSxcbiAgICAgICAgICAgIHBhdHRlcm46IGRlZi5wYXR0ZXJuLnRvU3RyaW5nKCksXG4gICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgfSk7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RDaGVja0xvd2VyQ2FzZSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kQ2hlY2tMb3dlckNhc2VcIiwgKGluc3QsIGRlZik9PntcbiAgICBkZWYucGF0dGVybiA/PyAoZGVmLnBhdHRlcm4gPSByZWdleGVzLmxvd2VyY2FzZSk7XG4gICAgJFpvZENoZWNrU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RDaGVja1VwcGVyQ2FzZSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kQ2hlY2tVcHBlckNhc2VcIiwgKGluc3QsIGRlZik9PntcbiAgICBkZWYucGF0dGVybiA/PyAoZGVmLnBhdHRlcm4gPSByZWdleGVzLnVwcGVyY2FzZSk7XG4gICAgJFpvZENoZWNrU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RDaGVja0luY2x1ZGVzID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RDaGVja0luY2x1ZGVzXCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZENoZWNrLmluaXQoaW5zdCwgZGVmKTtcbiAgICBjb25zdCBlc2NhcGVkUmVnZXggPSB1dGlsLmVzY2FwZVJlZ2V4KGRlZi5pbmNsdWRlcyk7XG4gICAgY29uc3QgcGF0dGVybiA9IG5ldyBSZWdFeHAodHlwZW9mIGRlZi5wb3NpdGlvbiA9PT0gXCJudW1iZXJcIiA/IGBeLnske2RlZi5wb3NpdGlvbn19JHtlc2NhcGVkUmVnZXh9YCA6IGVzY2FwZWRSZWdleCk7XG4gICAgZGVmLnBhdHRlcm4gPSBwYXR0ZXJuO1xuICAgIGluc3QuX3pvZC5vbmF0dGFjaC5wdXNoKChpbnN0KT0+e1xuICAgICAgICBjb25zdCBiYWcgPSBpbnN0Ll96b2QuYmFnO1xuICAgICAgICBiYWcucGF0dGVybnMgPz8gKGJhZy5wYXR0ZXJucyA9IG5ldyBTZXQoKSk7XG4gICAgICAgIGJhZy5wYXR0ZXJucy5hZGQocGF0dGVybik7XG4gICAgfSk7XG4gICAgaW5zdC5fem9kLmNoZWNrID0gKHBheWxvYWQpPT57XG4gICAgICAgIGlmIChwYXlsb2FkLnZhbHVlLmluY2x1ZGVzKGRlZi5pbmNsdWRlcywgZGVmLnBvc2l0aW9uKSkgcmV0dXJuO1xuICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICAgIG9yaWdpbjogXCJzdHJpbmdcIixcbiAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF9mb3JtYXRcIixcbiAgICAgICAgICAgIGZvcm1hdDogXCJpbmNsdWRlc1wiLFxuICAgICAgICAgICAgaW5jbHVkZXM6IGRlZi5pbmNsdWRlcyxcbiAgICAgICAgICAgIGlucHV0OiBwYXlsb2FkLnZhbHVlLFxuICAgICAgICAgICAgaW5zdCxcbiAgICAgICAgICAgIGNvbnRpbnVlOiAhZGVmLmFib3J0XG4gICAgICAgIH0pO1xuICAgIH07XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kQ2hlY2tTdGFydHNXaXRoID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RDaGVja1N0YXJ0c1dpdGhcIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kQ2hlY2suaW5pdChpbnN0LCBkZWYpO1xuICAgIGNvbnN0IHBhdHRlcm4gPSBuZXcgUmVnRXhwKGBeJHt1dGlsLmVzY2FwZVJlZ2V4KGRlZi5wcmVmaXgpfS4qYCk7XG4gICAgZGVmLnBhdHRlcm4gPz8gKGRlZi5wYXR0ZXJuID0gcGF0dGVybik7XG4gICAgaW5zdC5fem9kLm9uYXR0YWNoLnB1c2goKGluc3QpPT57XG4gICAgICAgIGNvbnN0IGJhZyA9IGluc3QuX3pvZC5iYWc7XG4gICAgICAgIGJhZy5wYXR0ZXJucyA/PyAoYmFnLnBhdHRlcm5zID0gbmV3IFNldCgpKTtcbiAgICAgICAgYmFnLnBhdHRlcm5zLmFkZChwYXR0ZXJuKTtcbiAgICB9KTtcbiAgICBpbnN0Ll96b2QuY2hlY2sgPSAocGF5bG9hZCk9PntcbiAgICAgICAgaWYgKHBheWxvYWQudmFsdWUuc3RhcnRzV2l0aChkZWYucHJlZml4KSkgcmV0dXJuO1xuICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICAgIG9yaWdpbjogXCJzdHJpbmdcIixcbiAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF9mb3JtYXRcIixcbiAgICAgICAgICAgIGZvcm1hdDogXCJzdGFydHNfd2l0aFwiLFxuICAgICAgICAgICAgcHJlZml4OiBkZWYucHJlZml4LFxuICAgICAgICAgICAgaW5wdXQ6IHBheWxvYWQudmFsdWUsXG4gICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgfSk7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RDaGVja0VuZHNXaXRoID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RDaGVja0VuZHNXaXRoXCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZENoZWNrLmluaXQoaW5zdCwgZGVmKTtcbiAgICBjb25zdCBwYXR0ZXJuID0gbmV3IFJlZ0V4cChgLioke3V0aWwuZXNjYXBlUmVnZXgoZGVmLnN1ZmZpeCl9JGApO1xuICAgIGRlZi5wYXR0ZXJuID8/IChkZWYucGF0dGVybiA9IHBhdHRlcm4pO1xuICAgIGluc3QuX3pvZC5vbmF0dGFjaC5wdXNoKChpbnN0KT0+e1xuICAgICAgICBjb25zdCBiYWcgPSBpbnN0Ll96b2QuYmFnO1xuICAgICAgICBiYWcucGF0dGVybnMgPz8gKGJhZy5wYXR0ZXJucyA9IG5ldyBTZXQoKSk7XG4gICAgICAgIGJhZy5wYXR0ZXJucy5hZGQocGF0dGVybik7XG4gICAgfSk7XG4gICAgaW5zdC5fem9kLmNoZWNrID0gKHBheWxvYWQpPT57XG4gICAgICAgIGlmIChwYXlsb2FkLnZhbHVlLmVuZHNXaXRoKGRlZi5zdWZmaXgpKSByZXR1cm47XG4gICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgb3JpZ2luOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX2Zvcm1hdFwiLFxuICAgICAgICAgICAgZm9ybWF0OiBcImVuZHNfd2l0aFwiLFxuICAgICAgICAgICAgc3VmZml4OiBkZWYuc3VmZml4LFxuICAgICAgICAgICAgaW5wdXQ6IHBheWxvYWQudmFsdWUsXG4gICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgfSk7XG4gICAgfTtcbn0pO1xuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vLy8vICAgICRab2RDaGVja1Byb3BlcnR5ICAgIC8vLy8vXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuZnVuY3Rpb24gaGFuZGxlQ2hlY2tQcm9wZXJ0eVJlc3VsdChyZXN1bHQsIHBheWxvYWQsIHByb3BlcnR5KSB7XG4gICAgaWYgKHJlc3VsdC5pc3N1ZXMubGVuZ3RoKSB7XG4gICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goLi4udXRpbC5wcmVmaXhJc3N1ZXMocHJvcGVydHksIHJlc3VsdC5pc3N1ZXMpKTtcbiAgICB9XG59XG5leHBvcnQgY29uc3QgJFpvZENoZWNrUHJvcGVydHkgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZENoZWNrUHJvcGVydHlcIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kQ2hlY2suaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5jaGVjayA9IChwYXlsb2FkKT0+e1xuICAgICAgICBjb25zdCByZXN1bHQgPSBkZWYuc2NoZW1hLl96b2QucnVuKHtcbiAgICAgICAgICAgIHZhbHVlOiBwYXlsb2FkLnZhbHVlW2RlZi5wcm9wZXJ0eV0sXG4gICAgICAgICAgICBpc3N1ZXM6IFtdXG4gICAgICAgIH0sIHt9KTtcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQudGhlbigocmVzdWx0KT0+aGFuZGxlQ2hlY2tQcm9wZXJ0eVJlc3VsdChyZXN1bHQsIHBheWxvYWQsIGRlZi5wcm9wZXJ0eSkpO1xuICAgICAgICB9XG4gICAgICAgIGhhbmRsZUNoZWNrUHJvcGVydHlSZXN1bHQocmVzdWx0LCBwYXlsb2FkLCBkZWYucHJvcGVydHkpO1xuICAgICAgICByZXR1cm47XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RDaGVja01pbWVUeXBlID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RDaGVja01pbWVUeXBlXCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZENoZWNrLmluaXQoaW5zdCwgZGVmKTtcbiAgICBjb25zdCBtaW1lU2V0ID0gbmV3IFNldChkZWYubWltZSk7XG4gICAgaW5zdC5fem9kLm9uYXR0YWNoLnB1c2goKGluc3QpPT57XG4gICAgICAgIGluc3QuX3pvZC5iYWcubWltZSA9IGRlZi5taW1lO1xuICAgIH0pO1xuICAgIGluc3QuX3pvZC5jaGVjayA9IChwYXlsb2FkKT0+e1xuICAgICAgICBpZiAobWltZVNldC5oYXMocGF5bG9hZC52YWx1ZS50eXBlKSkgcmV0dXJuO1xuICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF92YWx1ZVwiLFxuICAgICAgICAgICAgdmFsdWVzOiBkZWYubWltZSxcbiAgICAgICAgICAgIGlucHV0OiBwYXlsb2FkLnZhbHVlLnR5cGUsXG4gICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgfSk7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RDaGVja092ZXJ3cml0ZSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kQ2hlY2tPdmVyd3JpdGVcIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kQ2hlY2suaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5jaGVjayA9IChwYXlsb2FkKT0+e1xuICAgICAgICBwYXlsb2FkLnZhbHVlID0gZGVmLnR4KHBheWxvYWQudmFsdWUpO1xuICAgIH07XG59KTtcbiIsICJleHBvcnQgY2xhc3MgRG9jIHtcbiAgICBjb25zdHJ1Y3RvcihhcmdzID0gW10pe1xuICAgICAgICB0aGlzLmNvbnRlbnQgPSBbXTtcbiAgICAgICAgdGhpcy5pbmRlbnQgPSAwO1xuICAgICAgICBpZiAodGhpcykgdGhpcy5hcmdzID0gYXJncztcbiAgICB9XG4gICAgaW5kZW50ZWQoZm4pIHtcbiAgICAgICAgdGhpcy5pbmRlbnQgKz0gMTtcbiAgICAgICAgZm4odGhpcyk7XG4gICAgICAgIHRoaXMuaW5kZW50IC09IDE7XG4gICAgfVxuICAgIHdyaXRlKGFyZykge1xuICAgICAgICBpZiAodHlwZW9mIGFyZyA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICBhcmcodGhpcywge1xuICAgICAgICAgICAgICAgIGV4ZWN1dGlvbjogXCJzeW5jXCJcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgYXJnKHRoaXMsIHtcbiAgICAgICAgICAgICAgICBleGVjdXRpb246IFwiYXN5bmNcIlxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY29udGVudCA9IGFyZztcbiAgICAgICAgY29uc3QgbGluZXMgPSBjb250ZW50LnNwbGl0KFwiXFxuXCIpLmZpbHRlcigoeCk9PngpO1xuICAgICAgICBjb25zdCBtaW5JbmRlbnQgPSBNYXRoLm1pbiguLi5saW5lcy5tYXAoKHgpPT54Lmxlbmd0aCAtIHgudHJpbVN0YXJ0KCkubGVuZ3RoKSk7XG4gICAgICAgIGNvbnN0IGRlZGVudGVkID0gbGluZXMubWFwKCh4KT0+eC5zbGljZShtaW5JbmRlbnQpKS5tYXAoKHgpPT5cIiBcIi5yZXBlYXQodGhpcy5pbmRlbnQgKiAyKSArIHgpO1xuICAgICAgICBmb3IgKGNvbnN0IGxpbmUgb2YgZGVkZW50ZWQpe1xuICAgICAgICAgICAgdGhpcy5jb250ZW50LnB1c2gobGluZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY29tcGlsZSgpIHtcbiAgICAgICAgY29uc3QgRiA9IEZ1bmN0aW9uO1xuICAgICAgICBjb25zdCBhcmdzID0gdGhpcz8uYXJncztcbiAgICAgICAgY29uc3QgY29udGVudCA9IHRoaXM/LmNvbnRlbnQgPz8gW1xuICAgICAgICAgICAgYGBcbiAgICAgICAgXTtcbiAgICAgICAgY29uc3QgbGluZXMgPSBbXG4gICAgICAgICAgICAuLi5jb250ZW50Lm1hcCgoeCk9PmAgICR7eH1gKVxuICAgICAgICBdO1xuICAgICAgICAvLyBjb25zb2xlLmxvZyhsaW5lcy5qb2luKFwiXFxuXCIpKTtcbiAgICAgICAgcmV0dXJuIG5ldyBGKC4uLmFyZ3MsIGxpbmVzLmpvaW4oXCJcXG5cIikpO1xuICAgIH1cbn1cbiIsICJleHBvcnQgY29uc3QgdmVyc2lvbiA9IHtcbiAgICBtYWpvcjogNCxcbiAgICBtaW5vcjogMSxcbiAgICBwYXRjaDogMTFcbn07XG4iLCAiaW1wb3J0ICogYXMgY2hlY2tzIGZyb20gXCIuL2NoZWNrcy5qc1wiO1xuaW1wb3J0ICogYXMgY29yZSBmcm9tIFwiLi9jb3JlLmpzXCI7XG5pbXBvcnQgeyBEb2MgfSBmcm9tIFwiLi9kb2MuanNcIjtcbmltcG9ydCB7IHBhcnNlLCBwYXJzZUFzeW5jLCBzYWZlUGFyc2UsIHNhZmVQYXJzZUFzeW5jIH0gZnJvbSBcIi4vcGFyc2UuanNcIjtcbmltcG9ydCAqIGFzIHJlZ2V4ZXMgZnJvbSBcIi4vcmVnZXhlcy5qc1wiO1xuaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi91dGlsLmpzXCI7XG5pbXBvcnQgeyB2ZXJzaW9uIH0gZnJvbSBcIi4vdmVyc2lvbnMuanNcIjtcbmV4cG9ydCBjb25zdCAkWm9kVHlwZSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kVHlwZVwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIHZhciBfYTtcbiAgICBpbnN0ID8/IChpbnN0ID0ge30pO1xuICAgIGluc3QuX3pvZC5kZWYgPSBkZWY7IC8vIHNldCBfZGVmIHByb3BlcnR5XG4gICAgaW5zdC5fem9kLmJhZyA9IGluc3QuX3pvZC5iYWcgfHwge307IC8vIGluaXRpYWxpemUgX2JhZyBvYmplY3RcbiAgICBpbnN0Ll96b2QudmVyc2lvbiA9IHZlcnNpb247XG4gICAgY29uc3QgY2hlY2tzID0gW1xuICAgICAgICAuLi5pbnN0Ll96b2QuZGVmLmNoZWNrcyA/PyBbXVxuICAgIF07XG4gICAgLy8gaWYgaW5zdCBpcyBpdHNlbGYgYSBjaGVja3MuJFpvZENoZWNrLCBydW4gaXQgYXMgYSBjaGVja1xuICAgIGlmIChpbnN0Ll96b2QudHJhaXRzLmhhcyhcIiRab2RDaGVja1wiKSkge1xuICAgICAgICBjaGVja3MudW5zaGlmdChpbnN0KTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBjaCBvZiBjaGVja3Mpe1xuICAgICAgICBmb3IgKGNvbnN0IGZuIG9mIGNoLl96b2Qub25hdHRhY2gpe1xuICAgICAgICAgICAgZm4oaW5zdCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKGNoZWNrcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgLy8gZGVmZXJyZWQgaW5pdGlhbGl6ZXJcbiAgICAgICAgLy8gaW5zdC5fem9kLnBhcnNlIGlzIG5vdCB5ZXQgZGVmaW5lZFxuICAgICAgICAoX2EgPSBpbnN0Ll96b2QpLmRlZmVycmVkID8/IChfYS5kZWZlcnJlZCA9IFtdKTtcbiAgICAgICAgaW5zdC5fem9kLmRlZmVycmVkPy5wdXNoKCgpPT57XG4gICAgICAgICAgICBpbnN0Ll96b2QucnVuID0gaW5zdC5fem9kLnBhcnNlO1xuICAgICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBydW5DaGVja3MgPSAocGF5bG9hZCwgY2hlY2tzLCBjdHgpPT57XG4gICAgICAgICAgICBsZXQgaXNBYm9ydGVkID0gdXRpbC5hYm9ydGVkKHBheWxvYWQpO1xuICAgICAgICAgICAgbGV0IGFzeW5jUmVzdWx0O1xuICAgICAgICAgICAgZm9yIChjb25zdCBjaCBvZiBjaGVja3Mpe1xuICAgICAgICAgICAgICAgIGlmIChjaC5fem9kLmRlZi53aGVuKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNob3VsZFJ1biA9IGNoLl96b2QuZGVmLndoZW4ocGF5bG9hZCk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghc2hvdWxkUnVuKSBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGlzQWJvcnRlZCkge1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgY3VyckxlbiA9IHBheWxvYWQuaXNzdWVzLmxlbmd0aDtcbiAgICAgICAgICAgICAgICBjb25zdCBfID0gY2guX3pvZC5jaGVjayhwYXlsb2FkKTtcbiAgICAgICAgICAgICAgICBpZiAoXyBpbnN0YW5jZW9mIFByb21pc2UgJiYgY3R4Py5hc3luYyA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IGNvcmUuJFpvZEFzeW5jRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGFzeW5jUmVzdWx0IHx8IF8gaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICAgICAgICAgIGFzeW5jUmVzdWx0ID0gKGFzeW5jUmVzdWx0ID8/IFByb21pc2UucmVzb2x2ZSgpKS50aGVuKGFzeW5jICgpPT57XG4gICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCBfO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV4dExlbiA9IHBheWxvYWQuaXNzdWVzLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXh0TGVuID09PSBjdXJyTGVuKSByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlzQWJvcnRlZCkgaXNBYm9ydGVkID0gdXRpbC5hYm9ydGVkKHBheWxvYWQsIGN1cnJMZW4pO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXh0TGVuID0gcGF5bG9hZC5pc3N1ZXMubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICBpZiAobmV4dExlbiA9PT0gY3VyckxlbikgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgIGlmICghaXNBYm9ydGVkKSBpc0Fib3J0ZWQgPSB1dGlsLmFib3J0ZWQocGF5bG9hZCwgY3Vyckxlbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGFzeW5jUmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFzeW5jUmVzdWx0LnRoZW4oKCk9PntcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgfTtcbiAgICAgICAgLy8gY29uc3QgaGFuZGxlQ2hlY2tzUmVzdWx0ID0gKFxuICAgICAgICAvLyAgIGNoZWNrUmVzdWx0OiBQYXJzZVBheWxvYWQsXG4gICAgICAgIC8vICAgb3JpZ2luYWxSZXN1bHQ6IFBhcnNlUGF5bG9hZCxcbiAgICAgICAgLy8gICBjdHg6IFBhcnNlQ29udGV4dEludGVybmFsXG4gICAgICAgIC8vICk6IHV0aWwuTWF5YmVBc3luYzxQYXJzZVBheWxvYWQ+ID0+IHtcbiAgICAgICAgLy8gICAvLyBpZiB0aGUgY2hlY2tzIG11dGF0ZWQgdGhlIHZhbHVlICYmIHRoZXJlIGFyZSBubyBpc3N1ZXMsIHJlLXBhcnNlIHRoZSByZXN1bHRcbiAgICAgICAgLy8gICBpZiAoY2hlY2tSZXN1bHQudmFsdWUgIT09IG9yaWdpbmFsUmVzdWx0LnZhbHVlICYmICFjaGVja1Jlc3VsdC5pc3N1ZXMubGVuZ3RoKVxuICAgICAgICAvLyAgICAgcmV0dXJuIGluc3QuX3pvZC5wYXJzZShjaGVja1Jlc3VsdCwgY3R4KTtcbiAgICAgICAgLy8gICByZXR1cm4gb3JpZ2luYWxSZXN1bHQ7XG4gICAgICAgIC8vIH07XG4gICAgICAgIGNvbnN0IGhhbmRsZUNhbmFyeVJlc3VsdCA9IChjYW5hcnksIHBheWxvYWQsIGN0eCk9PntcbiAgICAgICAgICAgIC8vIGFib3J0IGlmIHRoZSBjYW5hcnkgaXMgYWJvcnRlZFxuICAgICAgICAgICAgaWYgKHV0aWwuYWJvcnRlZChjYW5hcnkpKSB7XG4gICAgICAgICAgICAgICAgY2FuYXJ5LmFib3J0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHJldHVybiBjYW5hcnk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBydW4gY2hlY2tzIGZpcnN0LCB0aGVuXG4gICAgICAgICAgICBjb25zdCBjaGVja1Jlc3VsdCA9IHJ1bkNoZWNrcyhwYXlsb2FkLCBjaGVja3MsIGN0eCk7XG4gICAgICAgICAgICBpZiAoY2hlY2tSZXN1bHQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICAgICAgaWYgKGN0eC5hc3luYyA9PT0gZmFsc2UpIHRocm93IG5ldyBjb3JlLiRab2RBc3luY0Vycm9yKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNoZWNrUmVzdWx0LnRoZW4oKGNoZWNrUmVzdWx0KT0+aW5zdC5fem9kLnBhcnNlKGNoZWNrUmVzdWx0LCBjdHgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBpbnN0Ll96b2QucGFyc2UoY2hlY2tSZXN1bHQsIGN0eCk7XG4gICAgICAgIH07XG4gICAgICAgIGluc3QuX3pvZC5ydW4gPSAocGF5bG9hZCwgY3R4KT0+e1xuICAgICAgICAgICAgaWYgKGN0eC5za2lwQ2hlY2tzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGluc3QuX3pvZC5wYXJzZShwYXlsb2FkLCBjdHgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGN0eC5kaXJlY3Rpb24gPT09IFwiYmFja3dhcmRcIikge1xuICAgICAgICAgICAgICAgIC8vIHJ1biBjYW5hcnlcbiAgICAgICAgICAgICAgICAvLyBpbml0aWFsIHBhc3MgKG5vIGNoZWNrcylcbiAgICAgICAgICAgICAgICBjb25zdCBjYW5hcnkgPSBpbnN0Ll96b2QucGFyc2Uoe1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogcGF5bG9hZC52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgaXNzdWVzOiBbXVxuICAgICAgICAgICAgICAgIH0sIHtcbiAgICAgICAgICAgICAgICAgICAgLi4uY3R4LFxuICAgICAgICAgICAgICAgICAgICBza2lwQ2hlY2tzOiB0cnVlXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgaWYgKGNhbmFyeSBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNhbmFyeS50aGVuKChjYW5hcnkpPT57XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlQ2FuYXJ5UmVzdWx0KGNhbmFyeSwgcGF5bG9hZCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBoYW5kbGVDYW5hcnlSZXN1bHQoY2FuYXJ5LCBwYXlsb2FkLCBjdHgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gZm9yd2FyZFxuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gaW5zdC5fem9kLnBhcnNlKHBheWxvYWQsIGN0eCk7XG4gICAgICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgICAgIGlmIChjdHguYXN5bmMgPT09IGZhbHNlKSB0aHJvdyBuZXcgY29yZS4kWm9kQXN5bmNFcnJvcigpO1xuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQudGhlbigocmVzdWx0KT0+cnVuQ2hlY2tzKHJlc3VsdCwgY2hlY2tzLCBjdHgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBydW5DaGVja3MocmVzdWx0LCBjaGVja3MsIGN0eCk7XG4gICAgICAgIH07XG4gICAgfVxuICAgIGluc3RbXCJ+c3RhbmRhcmRcIl0gPSB7XG4gICAgICAgIHZhbGlkYXRlOiAodmFsdWUpPT57XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHIgPSBzYWZlUGFyc2UoaW5zdCwgdmFsdWUpO1xuICAgICAgICAgICAgICAgIHJldHVybiByLnN1Y2Nlc3MgPyB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiByLmRhdGFcbiAgICAgICAgICAgICAgICB9IDoge1xuICAgICAgICAgICAgICAgICAgICBpc3N1ZXM6IHIuZXJyb3I/Lmlzc3Vlc1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9IGNhdGNoIChfKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNhZmVQYXJzZUFzeW5jKGluc3QsIHZhbHVlKS50aGVuKChyKT0+ci5zdWNjZXNzID8ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHIuZGF0YVxuICAgICAgICAgICAgICAgICAgICB9IDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgaXNzdWVzOiByLmVycm9yPy5pc3N1ZXNcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIHZlbmRvcjogXCJ6b2RcIixcbiAgICAgICAgdmVyc2lvbjogMVxuICAgIH07XG59KTtcbmV4cG9ydCB7IGNsb25lIH0gZnJvbSBcIi4vdXRpbC5qc1wiO1xuZXhwb3J0IGNvbnN0ICRab2RTdHJpbmcgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZFN0cmluZ1wiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0Ll96b2QucGF0dGVybiA9IFtcbiAgICAgICAgLi4uaW5zdD8uX3pvZC5iYWc/LnBhdHRlcm5zID8/IFtdXG4gICAgXS5wb3AoKSA/PyByZWdleGVzLnN0cmluZyhpbnN0Ll96b2QuYmFnKTtcbiAgICBpbnN0Ll96b2QucGFyc2UgPSAocGF5bG9hZCwgXyk9PntcbiAgICAgICAgaWYgKGRlZi5jb2VyY2UpIHRyeSB7XG4gICAgICAgICAgICBwYXlsb2FkLnZhbHVlID0gU3RyaW5nKHBheWxvYWQudmFsdWUpO1xuICAgICAgICB9IGNhdGNoIChfKSB7fVxuICAgICAgICBpZiAodHlwZW9mIHBheWxvYWQudmFsdWUgPT09IFwic3RyaW5nXCIpIHJldHVybiBwYXlsb2FkO1xuICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICAgIGV4cGVjdGVkOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX3R5cGVcIixcbiAgICAgICAgICAgIGlucHV0OiBwYXlsb2FkLnZhbHVlLFxuICAgICAgICAgICAgaW5zdFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RTdHJpbmdGb3JtYXQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZFN0cmluZ0Zvcm1hdFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIC8vIGNoZWNrIGluaXRpYWxpemF0aW9uIG11c3QgY29tZSBmaXJzdFxuICAgIGNoZWNrcy4kWm9kQ2hlY2tTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xuICAgICRab2RTdHJpbmcuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgY29uc3QgJFpvZEdVSUQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZEdVSURcIiwgKGluc3QsIGRlZik9PntcbiAgICBkZWYucGF0dGVybiA/PyAoZGVmLnBhdHRlcm4gPSByZWdleGVzLmd1aWQpO1xuICAgICRab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgY29uc3QgJFpvZFVVSUQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZFVVSURcIiwgKGluc3QsIGRlZik9PntcbiAgICBpZiAoZGVmLnZlcnNpb24pIHtcbiAgICAgICAgY29uc3QgdmVyc2lvbk1hcCA9IHtcbiAgICAgICAgICAgIHYxOiAxLFxuICAgICAgICAgICAgdjI6IDIsXG4gICAgICAgICAgICB2MzogMyxcbiAgICAgICAgICAgIHY0OiA0LFxuICAgICAgICAgICAgdjU6IDUsXG4gICAgICAgICAgICB2NjogNixcbiAgICAgICAgICAgIHY3OiA3LFxuICAgICAgICAgICAgdjg6IDhcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgdiA9IHZlcnNpb25NYXBbZGVmLnZlcnNpb25dO1xuICAgICAgICBpZiAodiA9PT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgVVVJRCB2ZXJzaW9uOiBcIiR7ZGVmLnZlcnNpb259XCJgKTtcbiAgICAgICAgZGVmLnBhdHRlcm4gPz8gKGRlZi5wYXR0ZXJuID0gcmVnZXhlcy51dWlkKHYpKTtcbiAgICB9IGVsc2UgZGVmLnBhdHRlcm4gPz8gKGRlZi5wYXR0ZXJuID0gcmVnZXhlcy51dWlkKCkpO1xuICAgICRab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgY29uc3QgJFpvZEVtYWlsID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RFbWFpbFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGRlZi5wYXR0ZXJuID8/IChkZWYucGF0dGVybiA9IHJlZ2V4ZXMuZW1haWwpO1xuICAgICRab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgY29uc3QgJFpvZFVSTCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kVVJMXCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5fem9kLmNoZWNrID0gKHBheWxvYWQpPT57XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBUcmltIHdoaXRlc3BhY2UgZnJvbSBpbnB1dFxuICAgICAgICAgICAgY29uc3QgdHJpbW1lZCA9IHBheWxvYWQudmFsdWUudHJpbSgpO1xuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgY29uc3QgdXJsID0gbmV3IFVSTCh0cmltbWVkKTtcbiAgICAgICAgICAgIGlmIChkZWYuaG9zdG5hbWUpIHtcbiAgICAgICAgICAgICAgICBkZWYuaG9zdG5hbWUubGFzdEluZGV4ID0gMDtcbiAgICAgICAgICAgICAgICBpZiAoIWRlZi5ob3N0bmFtZS50ZXN0KHVybC5ob3N0bmFtZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBcImludmFsaWRfZm9ybWF0XCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3JtYXQ6IFwidXJsXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBub3RlOiBcIkludmFsaWQgaG9zdG5hbWVcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhdHRlcm46IHJlZ2V4ZXMuaG9zdG5hbWUuc291cmNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQ6IHBheWxvYWQudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGRlZi5wcm90b2NvbCkge1xuICAgICAgICAgICAgICAgIGRlZi5wcm90b2NvbC5sYXN0SW5kZXggPSAwO1xuICAgICAgICAgICAgICAgIGlmICghZGVmLnByb3RvY29sLnRlc3QodXJsLnByb3RvY29sLmVuZHNXaXRoKFwiOlwiKSA/IHVybC5wcm90b2NvbC5zbGljZSgwLCAtMSkgOiB1cmwucHJvdG9jb2wpKSB7XG4gICAgICAgICAgICAgICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX2Zvcm1hdFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0OiBcInVybFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgbm90ZTogXCJJbnZhbGlkIHByb3RvY29sXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuOiBkZWYucHJvdG9jb2wuc291cmNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQ6IHBheWxvYWQudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gU2V0IHRoZSBvdXRwdXQgdmFsdWUgYmFzZWQgb24gbm9ybWFsaXplIGZsYWdcbiAgICAgICAgICAgIGlmIChkZWYubm9ybWFsaXplKSB7XG4gICAgICAgICAgICAgICAgLy8gVXNlIG5vcm1hbGl6ZWQgVVJMXG4gICAgICAgICAgICAgICAgcGF5bG9hZC52YWx1ZSA9IHVybC5ocmVmO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBQcmVzZXJ2ZSB0aGUgb3JpZ2luYWwgaW5wdXQgKHRyaW1tZWQpXG4gICAgICAgICAgICAgICAgcGF5bG9hZC52YWx1ZSA9IHRyaW1tZWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gY2F0Y2ggKF8pIHtcbiAgICAgICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF9mb3JtYXRcIixcbiAgICAgICAgICAgICAgICBmb3JtYXQ6IFwidXJsXCIsXG4gICAgICAgICAgICAgICAgaW5wdXQ6IHBheWxvYWQudmFsdWUsXG4gICAgICAgICAgICAgICAgaW5zdCxcbiAgICAgICAgICAgICAgICBjb250aW51ZTogIWRlZi5hYm9ydFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZEVtb2ppID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RFbW9qaVwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGRlZi5wYXR0ZXJuID8/IChkZWYucGF0dGVybiA9IHJlZ2V4ZXMuZW1vamkoKSk7XG4gICAgJFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kTmFub0lEID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2ROYW5vSURcIiwgKGluc3QsIGRlZik9PntcbiAgICBkZWYucGF0dGVybiA/PyAoZGVmLnBhdHRlcm4gPSByZWdleGVzLm5hbm9pZCk7XG4gICAgJFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kQ1VJRCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kQ1VJRFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGRlZi5wYXR0ZXJuID8/IChkZWYucGF0dGVybiA9IHJlZ2V4ZXMuY3VpZCk7XG4gICAgJFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kQ1VJRDIgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZENVSUQyXCIsIChpbnN0LCBkZWYpPT57XG4gICAgZGVmLnBhdHRlcm4gPz8gKGRlZi5wYXR0ZXJuID0gcmVnZXhlcy5jdWlkMik7XG4gICAgJFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kVUxJRCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kVUxJRFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGRlZi5wYXR0ZXJuID8/IChkZWYucGF0dGVybiA9IHJlZ2V4ZXMudWxpZCk7XG4gICAgJFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kWElEID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RYSURcIiwgKGluc3QsIGRlZik9PntcbiAgICBkZWYucGF0dGVybiA/PyAoZGVmLnBhdHRlcm4gPSByZWdleGVzLnhpZCk7XG4gICAgJFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kS1NVSUQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZEtTVUlEXCIsIChpbnN0LCBkZWYpPT57XG4gICAgZGVmLnBhdHRlcm4gPz8gKGRlZi5wYXR0ZXJuID0gcmVnZXhlcy5rc3VpZCk7XG4gICAgJFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kSVNPRGF0ZVRpbWUgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZElTT0RhdGVUaW1lXCIsIChpbnN0LCBkZWYpPT57XG4gICAgZGVmLnBhdHRlcm4gPz8gKGRlZi5wYXR0ZXJuID0gcmVnZXhlcy5kYXRldGltZShkZWYpKTtcbiAgICAkWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RJU09EYXRlID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RJU09EYXRlXCIsIChpbnN0LCBkZWYpPT57XG4gICAgZGVmLnBhdHRlcm4gPz8gKGRlZi5wYXR0ZXJuID0gcmVnZXhlcy5kYXRlKTtcbiAgICAkWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RJU09UaW1lID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RJU09UaW1lXCIsIChpbnN0LCBkZWYpPT57XG4gICAgZGVmLnBhdHRlcm4gPz8gKGRlZi5wYXR0ZXJuID0gcmVnZXhlcy50aW1lKGRlZikpO1xuICAgICRab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgY29uc3QgJFpvZElTT0R1cmF0aW9uID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RJU09EdXJhdGlvblwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGRlZi5wYXR0ZXJuID8/IChkZWYucGF0dGVybiA9IHJlZ2V4ZXMuZHVyYXRpb24pO1xuICAgICRab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgY29uc3QgJFpvZElQdjQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZElQdjRcIiwgKGluc3QsIGRlZik9PntcbiAgICBkZWYucGF0dGVybiA/PyAoZGVmLnBhdHRlcm4gPSByZWdleGVzLmlwdjQpO1xuICAgICRab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5vbmF0dGFjaC5wdXNoKChpbnN0KT0+e1xuICAgICAgICBjb25zdCBiYWcgPSBpbnN0Ll96b2QuYmFnO1xuICAgICAgICBiYWcuZm9ybWF0ID0gYGlwdjRgO1xuICAgIH0pO1xufSk7XG5leHBvcnQgY29uc3QgJFpvZElQdjYgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZElQdjZcIiwgKGluc3QsIGRlZik9PntcbiAgICBkZWYucGF0dGVybiA/PyAoZGVmLnBhdHRlcm4gPSByZWdleGVzLmlwdjYpO1xuICAgICRab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5vbmF0dGFjaC5wdXNoKChpbnN0KT0+e1xuICAgICAgICBjb25zdCBiYWcgPSBpbnN0Ll96b2QuYmFnO1xuICAgICAgICBiYWcuZm9ybWF0ID0gYGlwdjZgO1xuICAgIH0pO1xuICAgIGluc3QuX3pvZC5jaGVjayA9IChwYXlsb2FkKT0+e1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgbmV3IFVSTChgaHR0cDovL1ske3BheWxvYWQudmFsdWV9XWApO1xuICAgICAgICAvLyByZXR1cm47XG4gICAgICAgIH0gY2F0Y2ggIHtcbiAgICAgICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF9mb3JtYXRcIixcbiAgICAgICAgICAgICAgICBmb3JtYXQ6IFwiaXB2NlwiLFxuICAgICAgICAgICAgICAgIGlucHV0OiBwYXlsb2FkLnZhbHVlLFxuICAgICAgICAgICAgICAgIGluc3QsXG4gICAgICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RDSURSdjQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZENJRFJ2NFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGRlZi5wYXR0ZXJuID8/IChkZWYucGF0dGVybiA9IHJlZ2V4ZXMuY2lkcnY0KTtcbiAgICAkWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RDSURSdjYgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZENJRFJ2NlwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGRlZi5wYXR0ZXJuID8/IChkZWYucGF0dGVybiA9IHJlZ2V4ZXMuY2lkcnY2KTsgLy8gbm90IHVzZWQgZm9yIHZhbGlkYXRpb25cbiAgICAkWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0Ll96b2QuY2hlY2sgPSAocGF5bG9hZCk9PntcbiAgICAgICAgY29uc3QgcGFydHMgPSBwYXlsb2FkLnZhbHVlLnNwbGl0KFwiL1wiKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmIChwYXJ0cy5sZW5ndGggIT09IDIpIHRocm93IG5ldyBFcnJvcigpO1xuICAgICAgICAgICAgY29uc3QgW2FkZHJlc3MsIHByZWZpeF0gPSBwYXJ0cztcbiAgICAgICAgICAgIGlmICghcHJlZml4KSB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgICAgICAgICAgIGNvbnN0IHByZWZpeE51bSA9IE51bWJlcihwcmVmaXgpO1xuICAgICAgICAgICAgaWYgKGAke3ByZWZpeE51bX1gICE9PSBwcmVmaXgpIHRocm93IG5ldyBFcnJvcigpO1xuICAgICAgICAgICAgaWYgKHByZWZpeE51bSA8IDAgfHwgcHJlZml4TnVtID4gMTI4KSB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgIG5ldyBVUkwoYGh0dHA6Ly9bJHthZGRyZXNzfV1gKTtcbiAgICAgICAgfSBjYXRjaCAge1xuICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX2Zvcm1hdFwiLFxuICAgICAgICAgICAgICAgIGZvcm1hdDogXCJjaWRydjZcIixcbiAgICAgICAgICAgICAgICBpbnB1dDogcGF5bG9hZC52YWx1ZSxcbiAgICAgICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgICAgIGNvbnRpbnVlOiAhZGVmLmFib3J0XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG59KTtcbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyAgIFpvZEJhc2U2NCAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVmFsaWRCYXNlNjQoZGF0YSkge1xuICAgIGlmIChkYXRhID09PSBcIlwiKSByZXR1cm4gdHJ1ZTtcbiAgICBpZiAoZGF0YS5sZW5ndGggJSA0ICE9PSAwKSByZXR1cm4gZmFsc2U7XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICBhdG9iKGRhdGEpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoICB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG59XG5leHBvcnQgY29uc3QgJFpvZEJhc2U2NCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kQmFzZTY0XCIsIChpbnN0LCBkZWYpPT57XG4gICAgZGVmLnBhdHRlcm4gPz8gKGRlZi5wYXR0ZXJuID0gcmVnZXhlcy5iYXNlNjQpO1xuICAgICRab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5vbmF0dGFjaC5wdXNoKChpbnN0KT0+e1xuICAgICAgICBpbnN0Ll96b2QuYmFnLmNvbnRlbnRFbmNvZGluZyA9IFwiYmFzZTY0XCI7XG4gICAgfSk7XG4gICAgaW5zdC5fem9kLmNoZWNrID0gKHBheWxvYWQpPT57XG4gICAgICAgIGlmIChpc1ZhbGlkQmFzZTY0KHBheWxvYWQudmFsdWUpKSByZXR1cm47XG4gICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX2Zvcm1hdFwiLFxuICAgICAgICAgICAgZm9ybWF0OiBcImJhc2U2NFwiLFxuICAgICAgICAgICAgaW5wdXQ6IHBheWxvYWQudmFsdWUsXG4gICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgfSk7XG4gICAgfTtcbn0pO1xuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vICAgWm9kQmFzZTY0ICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZEJhc2U2NFVSTChkYXRhKSB7XG4gICAgaWYgKCFyZWdleGVzLmJhc2U2NHVybC50ZXN0KGRhdGEpKSByZXR1cm4gZmFsc2U7XG4gICAgY29uc3QgYmFzZTY0ID0gZGF0YS5yZXBsYWNlKC9bLV9dL2csIChjKT0+YyA9PT0gXCItXCIgPyBcIitcIiA6IFwiL1wiKTtcbiAgICBjb25zdCBwYWRkZWQgPSBiYXNlNjQucGFkRW5kKE1hdGguY2VpbChiYXNlNjQubGVuZ3RoIC8gNCkgKiA0LCBcIj1cIik7XG4gICAgcmV0dXJuIGlzVmFsaWRCYXNlNjQocGFkZGVkKTtcbn1cbmV4cG9ydCBjb25zdCAkWm9kQmFzZTY0VVJMID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RCYXNlNjRVUkxcIiwgKGluc3QsIGRlZik9PntcbiAgICBkZWYucGF0dGVybiA/PyAoZGVmLnBhdHRlcm4gPSByZWdleGVzLmJhc2U2NHVybCk7XG4gICAgJFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5fem9kLm9uYXR0YWNoLnB1c2goKGluc3QpPT57XG4gICAgICAgIGluc3QuX3pvZC5iYWcuY29udGVudEVuY29kaW5nID0gXCJiYXNlNjR1cmxcIjtcbiAgICB9KTtcbiAgICBpbnN0Ll96b2QuY2hlY2sgPSAocGF5bG9hZCk9PntcbiAgICAgICAgaWYgKGlzVmFsaWRCYXNlNjRVUkwocGF5bG9hZC52YWx1ZSkpIHJldHVybjtcbiAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICBjb2RlOiBcImludmFsaWRfZm9ybWF0XCIsXG4gICAgICAgICAgICBmb3JtYXQ6IFwiYmFzZTY0dXJsXCIsXG4gICAgICAgICAgICBpbnB1dDogcGF5bG9hZC52YWx1ZSxcbiAgICAgICAgICAgIGluc3QsXG4gICAgICAgICAgICBjb250aW51ZTogIWRlZi5hYm9ydFxuICAgICAgICB9KTtcbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZEUxNjQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZEUxNjRcIiwgKGluc3QsIGRlZik9PntcbiAgICBkZWYucGF0dGVybiA/PyAoZGVmLnBhdHRlcm4gPSByZWdleGVzLmUxNjQpO1xuICAgICRab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8gICBab2RKV1QgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkSldUKHRva2VuLCBhbGdvcml0aG0gPSBudWxsKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgY29uc3QgdG9rZW5zUGFydHMgPSB0b2tlbi5zcGxpdChcIi5cIik7XG4gICAgICAgIGlmICh0b2tlbnNQYXJ0cy5sZW5ndGggIT09IDMpIHJldHVybiBmYWxzZTtcbiAgICAgICAgY29uc3QgW2hlYWRlcl0gPSB0b2tlbnNQYXJ0cztcbiAgICAgICAgaWYgKCFoZWFkZXIpIHJldHVybiBmYWxzZTtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICBjb25zdCBwYXJzZWRIZWFkZXIgPSBKU09OLnBhcnNlKGF0b2IoaGVhZGVyKSk7XG4gICAgICAgIGlmIChcInR5cFwiIGluIHBhcnNlZEhlYWRlciAmJiBwYXJzZWRIZWFkZXI/LnR5cCAhPT0gXCJKV1RcIikgcmV0dXJuIGZhbHNlO1xuICAgICAgICBpZiAoIXBhcnNlZEhlYWRlci5hbGcpIHJldHVybiBmYWxzZTtcbiAgICAgICAgaWYgKGFsZ29yaXRobSAmJiAoIShcImFsZ1wiIGluIHBhcnNlZEhlYWRlcikgfHwgcGFyc2VkSGVhZGVyLmFsZyAhPT0gYWxnb3JpdGhtKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoICB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG59XG5leHBvcnQgY29uc3QgJFpvZEpXVCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kSldUXCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5fem9kLmNoZWNrID0gKHBheWxvYWQpPT57XG4gICAgICAgIGlmIChpc1ZhbGlkSldUKHBheWxvYWQudmFsdWUsIGRlZi5hbGcpKSByZXR1cm47XG4gICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX2Zvcm1hdFwiLFxuICAgICAgICAgICAgZm9ybWF0OiBcImp3dFwiLFxuICAgICAgICAgICAgaW5wdXQ6IHBheWxvYWQudmFsdWUsXG4gICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgfSk7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RDdXN0b21TdHJpbmdGb3JtYXQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZEN1c3RvbVN0cmluZ0Zvcm1hdFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5jaGVjayA9IChwYXlsb2FkKT0+e1xuICAgICAgICBpZiAoZGVmLmZuKHBheWxvYWQudmFsdWUpKSByZXR1cm47XG4gICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX2Zvcm1hdFwiLFxuICAgICAgICAgICAgZm9ybWF0OiBkZWYuZm9ybWF0LFxuICAgICAgICAgICAgaW5wdXQ6IHBheWxvYWQudmFsdWUsXG4gICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgY29udGludWU6ICFkZWYuYWJvcnRcbiAgICAgICAgfSk7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2ROdW1iZXIgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZE51bWJlclwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0Ll96b2QucGF0dGVybiA9IGluc3QuX3pvZC5iYWcucGF0dGVybiA/PyByZWdleGVzLm51bWJlcjtcbiAgICBpbnN0Ll96b2QucGFyc2UgPSAocGF5bG9hZCwgX2N0eCk9PntcbiAgICAgICAgaWYgKGRlZi5jb2VyY2UpIHRyeSB7XG4gICAgICAgICAgICBwYXlsb2FkLnZhbHVlID0gTnVtYmVyKHBheWxvYWQudmFsdWUpO1xuICAgICAgICB9IGNhdGNoIChfKSB7fVxuICAgICAgICBjb25zdCBpbnB1dCA9IHBheWxvYWQudmFsdWU7XG4gICAgICAgIGlmICh0eXBlb2YgaW5wdXQgPT09IFwibnVtYmVyXCIgJiYgIU51bWJlci5pc05hTihpbnB1dCkgJiYgTnVtYmVyLmlzRmluaXRlKGlucHV0KSkge1xuICAgICAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVjZWl2ZWQgPSB0eXBlb2YgaW5wdXQgPT09IFwibnVtYmVyXCIgPyBOdW1iZXIuaXNOYU4oaW5wdXQpID8gXCJOYU5cIiA6ICFOdW1iZXIuaXNGaW5pdGUoaW5wdXQpID8gXCJJbmZpbml0eVwiIDogdW5kZWZpbmVkIDogdW5kZWZpbmVkO1xuICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICAgIGV4cGVjdGVkOiBcIm51bWJlclwiLFxuICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX3R5cGVcIixcbiAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgaW5zdCxcbiAgICAgICAgICAgIC4uLnJlY2VpdmVkID8ge1xuICAgICAgICAgICAgICAgIHJlY2VpdmVkXG4gICAgICAgICAgICB9IDoge31cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgIH07XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kTnVtYmVyRm9ybWF0ID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2ROdW1iZXJcIiwgKGluc3QsIGRlZik9PntcbiAgICBjaGVja3MuJFpvZENoZWNrTnVtYmVyRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbiAgICAkWm9kTnVtYmVyLmluaXQoaW5zdCwgZGVmKTsgLy8gbm8gZm9ybWF0IGNoZWNrc3Bcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RCb29sZWFuID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RCb29sZWFuXCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5wYXR0ZXJuID0gcmVnZXhlcy5ib29sZWFuO1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkLCBfY3R4KT0+e1xuICAgICAgICBpZiAoZGVmLmNvZXJjZSkgdHJ5IHtcbiAgICAgICAgICAgIHBheWxvYWQudmFsdWUgPSBCb29sZWFuKHBheWxvYWQudmFsdWUpO1xuICAgICAgICB9IGNhdGNoIChfKSB7fVxuICAgICAgICBjb25zdCBpbnB1dCA9IHBheWxvYWQudmFsdWU7XG4gICAgICAgIGlmICh0eXBlb2YgaW5wdXQgPT09IFwiYm9vbGVhblwiKSByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICBleHBlY3RlZDogXCJib29sZWFuXCIsXG4gICAgICAgICAgICBjb2RlOiBcImludmFsaWRfdHlwZVwiLFxuICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICBpbnN0XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZEJpZ0ludCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kQmlnSW50XCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5wYXR0ZXJuID0gcmVnZXhlcy5iaWdpbnQ7XG4gICAgaW5zdC5fem9kLnBhcnNlID0gKHBheWxvYWQsIF9jdHgpPT57XG4gICAgICAgIGlmIChkZWYuY29lcmNlKSB0cnkge1xuICAgICAgICAgICAgcGF5bG9hZC52YWx1ZSA9IEJpZ0ludChwYXlsb2FkLnZhbHVlKTtcbiAgICAgICAgfSBjYXRjaCAoXykge31cbiAgICAgICAgaWYgKHR5cGVvZiBwYXlsb2FkLnZhbHVlID09PSBcImJpZ2ludFwiKSByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICBleHBlY3RlZDogXCJiaWdpbnRcIixcbiAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF90eXBlXCIsXG4gICAgICAgICAgICBpbnB1dDogcGF5bG9hZC52YWx1ZSxcbiAgICAgICAgICAgIGluc3RcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgIH07XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kQmlnSW50Rm9ybWF0ID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RCaWdJbnRcIiwgKGluc3QsIGRlZik9PntcbiAgICBjaGVja3MuJFpvZENoZWNrQmlnSW50Rm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbiAgICAkWm9kQmlnSW50LmluaXQoaW5zdCwgZGVmKTsgLy8gbm8gZm9ybWF0IGNoZWNrc1xufSk7XG5leHBvcnQgY29uc3QgJFpvZFN5bWJvbCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kU3ltYm9sXCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkLCBfY3R4KT0+e1xuICAgICAgICBjb25zdCBpbnB1dCA9IHBheWxvYWQudmFsdWU7XG4gICAgICAgIGlmICh0eXBlb2YgaW5wdXQgPT09IFwic3ltYm9sXCIpIHJldHVybiBwYXlsb2FkO1xuICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICAgIGV4cGVjdGVkOiBcInN5bWJvbFwiLFxuICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX3R5cGVcIixcbiAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgaW5zdFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RVbmRlZmluZWQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZFVuZGVmaW5lZFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0Ll96b2QucGF0dGVybiA9IHJlZ2V4ZXMudW5kZWZpbmVkO1xuICAgIGluc3QuX3pvZC52YWx1ZXMgPSBuZXcgU2V0KFtcbiAgICAgICAgdW5kZWZpbmVkXG4gICAgXSk7XG4gICAgaW5zdC5fem9kLm9wdGluID0gXCJvcHRpb25hbFwiO1xuICAgIGluc3QuX3pvZC5vcHRvdXQgPSBcIm9wdGlvbmFsXCI7XG4gICAgaW5zdC5fem9kLnBhcnNlID0gKHBheWxvYWQsIF9jdHgpPT57XG4gICAgICAgIGNvbnN0IGlucHV0ID0gcGF5bG9hZC52YWx1ZTtcbiAgICAgICAgaWYgKHR5cGVvZiBpbnB1dCA9PT0gXCJ1bmRlZmluZWRcIikgcmV0dXJuIHBheWxvYWQ7XG4gICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgZXhwZWN0ZWQ6IFwidW5kZWZpbmVkXCIsXG4gICAgICAgICAgICBjb2RlOiBcImludmFsaWRfdHlwZVwiLFxuICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICBpbnN0XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZE51bGwgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZE51bGxcIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5fem9kLnBhdHRlcm4gPSByZWdleGVzLm51bGw7XG4gICAgaW5zdC5fem9kLnZhbHVlcyA9IG5ldyBTZXQoW1xuICAgICAgICBudWxsXG4gICAgXSk7XG4gICAgaW5zdC5fem9kLnBhcnNlID0gKHBheWxvYWQsIF9jdHgpPT57XG4gICAgICAgIGNvbnN0IGlucHV0ID0gcGF5bG9hZC52YWx1ZTtcbiAgICAgICAgaWYgKGlucHV0ID09PSBudWxsKSByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICBleHBlY3RlZDogXCJudWxsXCIsXG4gICAgICAgICAgICBjb2RlOiBcImludmFsaWRfdHlwZVwiLFxuICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICBpbnN0XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZEFueSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kQW55XCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkKT0+cGF5bG9hZDtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RVbmtub3duID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RVbmtub3duXCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkKT0+cGF5bG9hZDtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2ROZXZlciA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kTmV2ZXJcIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5fem9kLnBhcnNlID0gKHBheWxvYWQsIF9jdHgpPT57XG4gICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgZXhwZWN0ZWQ6IFwibmV2ZXJcIixcbiAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF90eXBlXCIsXG4gICAgICAgICAgICBpbnB1dDogcGF5bG9hZC52YWx1ZSxcbiAgICAgICAgICAgIGluc3RcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgIH07XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kVm9pZCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kVm9pZFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0Ll96b2QucGFyc2UgPSAocGF5bG9hZCwgX2N0eCk9PntcbiAgICAgICAgY29uc3QgaW5wdXQgPSBwYXlsb2FkLnZhbHVlO1xuICAgICAgICBpZiAodHlwZW9mIGlucHV0ID09PSBcInVuZGVmaW5lZFwiKSByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICBleHBlY3RlZDogXCJ2b2lkXCIsXG4gICAgICAgICAgICBjb2RlOiBcImludmFsaWRfdHlwZVwiLFxuICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICBpbnN0XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZERhdGUgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZERhdGVcIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5fem9kLnBhcnNlID0gKHBheWxvYWQsIF9jdHgpPT57XG4gICAgICAgIGlmIChkZWYuY29lcmNlKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHBheWxvYWQudmFsdWUgPSBuZXcgRGF0ZShwYXlsb2FkLnZhbHVlKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKF9lcnIpIHt9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaW5wdXQgPSBwYXlsb2FkLnZhbHVlO1xuICAgICAgICBjb25zdCBpc0RhdGUgPSBpbnB1dCBpbnN0YW5jZW9mIERhdGU7XG4gICAgICAgIGNvbnN0IGlzVmFsaWREYXRlID0gaXNEYXRlICYmICFOdW1iZXIuaXNOYU4oaW5wdXQuZ2V0VGltZSgpKTtcbiAgICAgICAgaWYgKGlzVmFsaWREYXRlKSByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICBleHBlY3RlZDogXCJkYXRlXCIsXG4gICAgICAgICAgICBjb2RlOiBcImludmFsaWRfdHlwZVwiLFxuICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICAuLi5pc0RhdGUgPyB7XG4gICAgICAgICAgICAgICAgcmVjZWl2ZWQ6IFwiSW52YWxpZCBEYXRlXCJcbiAgICAgICAgICAgIH0gOiB7fSxcbiAgICAgICAgICAgIGluc3RcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgIH07XG59KTtcbmZ1bmN0aW9uIGhhbmRsZUFycmF5UmVzdWx0KHJlc3VsdCwgZmluYWwsIGluZGV4KSB7XG4gICAgaWYgKHJlc3VsdC5pc3N1ZXMubGVuZ3RoKSB7XG4gICAgICAgIGZpbmFsLmlzc3Vlcy5wdXNoKC4uLnV0aWwucHJlZml4SXNzdWVzKGluZGV4LCByZXN1bHQuaXNzdWVzKSk7XG4gICAgfVxuICAgIGZpbmFsLnZhbHVlW2luZGV4XSA9IHJlc3VsdC52YWx1ZTtcbn1cbmV4cG9ydCBjb25zdCAkWm9kQXJyYXkgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZEFycmF5XCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkLCBjdHgpPT57XG4gICAgICAgIGNvbnN0IGlucHV0ID0gcGF5bG9hZC52YWx1ZTtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGlucHV0KSkge1xuICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IFwiYXJyYXlcIixcbiAgICAgICAgICAgICAgICBjb2RlOiBcImludmFsaWRfdHlwZVwiLFxuICAgICAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgICAgIGluc3RcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgICAgIH1cbiAgICAgICAgcGF5bG9hZC52YWx1ZSA9IEFycmF5KGlucHV0Lmxlbmd0aCk7XG4gICAgICAgIGNvbnN0IHByb21zID0gW107XG4gICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCBpbnB1dC5sZW5ndGg7IGkrKyl7XG4gICAgICAgICAgICBjb25zdCBpdGVtID0gaW5wdXRbaV07XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBkZWYuZWxlbWVudC5fem9kLnJ1bih7XG4gICAgICAgICAgICAgICAgdmFsdWU6IGl0ZW0sXG4gICAgICAgICAgICAgICAgaXNzdWVzOiBbXVxuICAgICAgICAgICAgfSwgY3R4KTtcbiAgICAgICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICAgICAgcHJvbXMucHVzaChyZXN1bHQudGhlbigocmVzdWx0KT0+aGFuZGxlQXJyYXlSZXN1bHQocmVzdWx0LCBwYXlsb2FkLCBpKSkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBoYW5kbGVBcnJheVJlc3VsdChyZXN1bHQsIHBheWxvYWQsIGkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9tcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9tcykudGhlbigoKT0+cGF5bG9hZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBheWxvYWQ7IC8vaGFuZGxlQXJyYXlSZXN1bHRzQXN5bmMocGFyc2VSZXN1bHRzLCBmaW5hbCk7XG4gICAgfTtcbn0pO1xuZnVuY3Rpb24gaGFuZGxlUHJvcGVydHlSZXN1bHQocmVzdWx0LCBmaW5hbCwga2V5LCBpbnB1dCkge1xuICAgIGlmIChyZXN1bHQuaXNzdWVzLmxlbmd0aCkge1xuICAgICAgICBmaW5hbC5pc3N1ZXMucHVzaCguLi51dGlsLnByZWZpeElzc3VlcyhrZXksIHJlc3VsdC5pc3N1ZXMpKTtcbiAgICB9XG4gICAgaWYgKHJlc3VsdC52YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmIChrZXkgaW4gaW5wdXQpIHtcbiAgICAgICAgICAgIGZpbmFsLnZhbHVlW2tleV0gPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICBmaW5hbC52YWx1ZVtrZXldID0gcmVzdWx0LnZhbHVlO1xuICAgIH1cbn1cbmZ1bmN0aW9uIG5vcm1hbGl6ZURlZihkZWYpIHtcbiAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoZGVmLnNoYXBlKTtcbiAgICBmb3IgKGNvbnN0IGsgb2Yga2V5cyl7XG4gICAgICAgIGlmICghZGVmLnNoYXBlPy5ba10/Ll96b2Q/LnRyYWl0cz8uaGFzKFwiJFpvZFR5cGVcIikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBlbGVtZW50IGF0IGtleSBcIiR7a31cIjogZXhwZWN0ZWQgYSBab2Qgc2NoZW1hYCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY29uc3Qgb2tleXMgPSB1dGlsLm9wdGlvbmFsS2V5cyhkZWYuc2hhcGUpO1xuICAgIHJldHVybiB7XG4gICAgICAgIC4uLmRlZixcbiAgICAgICAga2V5cyxcbiAgICAgICAga2V5U2V0OiBuZXcgU2V0KGtleXMpLFxuICAgICAgICBudW1LZXlzOiBrZXlzLmxlbmd0aCxcbiAgICAgICAgb3B0aW9uYWxLZXlzOiBuZXcgU2V0KG9rZXlzKVxuICAgIH07XG59XG5mdW5jdGlvbiBoYW5kbGVDYXRjaGFsbChwcm9tcywgaW5wdXQsIHBheWxvYWQsIGN0eCwgZGVmLCBpbnN0KSB7XG4gICAgY29uc3QgdW5yZWNvZ25pemVkID0gW107XG4gICAgLy8gaXRlcmF0ZSBvdmVyIGlucHV0IGtleXNcbiAgICBjb25zdCBrZXlTZXQgPSBkZWYua2V5U2V0O1xuICAgIGNvbnN0IF9jYXRjaGFsbCA9IGRlZi5jYXRjaGFsbC5fem9kO1xuICAgIGNvbnN0IHQgPSBfY2F0Y2hhbGwuZGVmLnR5cGU7XG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoaW5wdXQpKXtcbiAgICAgICAgaWYgKGtleVNldC5oYXMoa2V5KSkgY29udGludWU7XG4gICAgICAgIGlmICh0ID09PSBcIm5ldmVyXCIpIHtcbiAgICAgICAgICAgIHVucmVjb2duaXplZC5wdXNoKGtleSk7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByID0gX2NhdGNoYWxsLnJ1bih7XG4gICAgICAgICAgICB2YWx1ZTogaW5wdXRba2V5XSxcbiAgICAgICAgICAgIGlzc3VlczogW11cbiAgICAgICAgfSwgY3R4KTtcbiAgICAgICAgaWYgKHIgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICBwcm9tcy5wdXNoKHIudGhlbigocik9PmhhbmRsZVByb3BlcnR5UmVzdWx0KHIsIHBheWxvYWQsIGtleSwgaW5wdXQpKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBoYW5kbGVQcm9wZXJ0eVJlc3VsdChyLCBwYXlsb2FkLCBrZXksIGlucHV0KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAodW5yZWNvZ25pemVkLmxlbmd0aCkge1xuICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICAgIGNvZGU6IFwidW5yZWNvZ25pemVkX2tleXNcIixcbiAgICAgICAgICAgIGtleXM6IHVucmVjb2duaXplZCxcbiAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgaW5zdFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgaWYgKCFwcm9tcy5sZW5ndGgpIHJldHVybiBwYXlsb2FkO1xuICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9tcykudGhlbigoKT0+e1xuICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICB9KTtcbn1cbmV4cG9ydCBjb25zdCAkWm9kT2JqZWN0ID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RPYmplY3RcIiwgKGluc3QsIGRlZik9PntcbiAgICAvLyByZXF1aXJlcyBjYXN0IGJlY2F1c2UgdGVjaG5pY2FsbHkgJFpvZE9iamVjdCBkb2Vzbid0IGV4dGVuZFxuICAgICRab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICAvLyBjb25zdCBzaCA9IGRlZi5zaGFwZTtcbiAgICBjb25zdCBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihkZWYsIFwic2hhcGVcIik7XG4gICAgaWYgKCFkZXNjPy5nZXQpIHtcbiAgICAgICAgY29uc3Qgc2ggPSBkZWYuc2hhcGU7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShkZWYsIFwic2hhcGVcIiwge1xuICAgICAgICAgICAgZ2V0OiAoKT0+e1xuICAgICAgICAgICAgICAgIGNvbnN0IG5ld1NoID0ge1xuICAgICAgICAgICAgICAgICAgICAuLi5zaFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGRlZiwgXCJzaGFwZVwiLCB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiBuZXdTaFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXdTaDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGNvbnN0IF9ub3JtYWxpemVkID0gdXRpbC5jYWNoZWQoKCk9Pm5vcm1hbGl6ZURlZihkZWYpKTtcbiAgICB1dGlsLmRlZmluZUxhenkoaW5zdC5fem9kLCBcInByb3BWYWx1ZXNcIiwgKCk9PntcbiAgICAgICAgY29uc3Qgc2hhcGUgPSBkZWYuc2hhcGU7XG4gICAgICAgIGNvbnN0IHByb3BWYWx1ZXMgPSB7fTtcbiAgICAgICAgZm9yKGNvbnN0IGtleSBpbiBzaGFwZSl7XG4gICAgICAgICAgICBjb25zdCBmaWVsZCA9IHNoYXBlW2tleV0uX3pvZDtcbiAgICAgICAgICAgIGlmIChmaWVsZC52YWx1ZXMpIHtcbiAgICAgICAgICAgICAgICBwcm9wVmFsdWVzW2tleV0gPz8gKHByb3BWYWx1ZXNba2V5XSA9IG5ldyBTZXQoKSk7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCB2IG9mIGZpZWxkLnZhbHVlcylwcm9wVmFsdWVzW2tleV0uYWRkKHYpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwcm9wVmFsdWVzO1xuICAgIH0pO1xuICAgIGNvbnN0IGlzT2JqZWN0ID0gdXRpbC5pc09iamVjdDtcbiAgICBjb25zdCBjYXRjaGFsbCA9IGRlZi5jYXRjaGFsbDtcbiAgICBsZXQgdmFsdWU7XG4gICAgaW5zdC5fem9kLnBhcnNlID0gKHBheWxvYWQsIGN0eCk9PntcbiAgICAgICAgdmFsdWUgPz8gKHZhbHVlID0gX25vcm1hbGl6ZWQudmFsdWUpO1xuICAgICAgICBjb25zdCBpbnB1dCA9IHBheWxvYWQudmFsdWU7XG4gICAgICAgIGlmICghaXNPYmplY3QoaW5wdXQpKSB7XG4gICAgICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogXCJvYmplY3RcIixcbiAgICAgICAgICAgICAgICBjb2RlOiBcImludmFsaWRfdHlwZVwiLFxuICAgICAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgICAgIGluc3RcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgICAgIH1cbiAgICAgICAgcGF5bG9hZC52YWx1ZSA9IHt9O1xuICAgICAgICBjb25zdCBwcm9tcyA9IFtdO1xuICAgICAgICBjb25zdCBzaGFwZSA9IHZhbHVlLnNoYXBlO1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiB2YWx1ZS5rZXlzKXtcbiAgICAgICAgICAgIGNvbnN0IGVsID0gc2hhcGVba2V5XTtcbiAgICAgICAgICAgIGNvbnN0IHIgPSBlbC5fem9kLnJ1bih7XG4gICAgICAgICAgICAgICAgdmFsdWU6IGlucHV0W2tleV0sXG4gICAgICAgICAgICAgICAgaXNzdWVzOiBbXVxuICAgICAgICAgICAgfSwgY3R4KTtcbiAgICAgICAgICAgIGlmIChyIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgICAgIHByb21zLnB1c2goci50aGVuKChyKT0+aGFuZGxlUHJvcGVydHlSZXN1bHQociwgcGF5bG9hZCwga2V5LCBpbnB1dCkpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaGFuZGxlUHJvcGVydHlSZXN1bHQociwgcGF5bG9hZCwga2V5LCBpbnB1dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFjYXRjaGFsbCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21zLmxlbmd0aCA/IFByb21pc2UuYWxsKHByb21zKS50aGVuKCgpPT5wYXlsb2FkKSA6IHBheWxvYWQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGhhbmRsZUNhdGNoYWxsKHByb21zLCBpbnB1dCwgcGF5bG9hZCwgY3R4LCBfbm9ybWFsaXplZC52YWx1ZSwgaW5zdCk7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RPYmplY3RKSVQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZE9iamVjdEpJVFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIC8vIHJlcXVpcmVzIGNhc3QgYmVjYXVzZSB0ZWNobmljYWxseSAkWm9kT2JqZWN0IGRvZXNuJ3QgZXh0ZW5kXG4gICAgJFpvZE9iamVjdC5pbml0KGluc3QsIGRlZik7XG4gICAgY29uc3Qgc3VwZXJQYXJzZSA9IGluc3QuX3pvZC5wYXJzZTtcbiAgICBjb25zdCBfbm9ybWFsaXplZCA9IHV0aWwuY2FjaGVkKCgpPT5ub3JtYWxpemVEZWYoZGVmKSk7XG4gICAgY29uc3QgZ2VuZXJhdGVGYXN0cGFzcyA9IChzaGFwZSk9PntcbiAgICAgICAgY29uc3QgZG9jID0gbmV3IERvYyhbXG4gICAgICAgICAgICBcInNoYXBlXCIsXG4gICAgICAgICAgICBcInBheWxvYWRcIixcbiAgICAgICAgICAgIFwiY3R4XCJcbiAgICAgICAgXSk7XG4gICAgICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSBfbm9ybWFsaXplZC52YWx1ZTtcbiAgICAgICAgY29uc3QgcGFyc2VTdHIgPSAoa2V5KT0+e1xuICAgICAgICAgICAgY29uc3QgayA9IHV0aWwuZXNjKGtleSk7XG4gICAgICAgICAgICByZXR1cm4gYHNoYXBlWyR7a31dLl96b2QucnVuKHsgdmFsdWU6IGlucHV0WyR7a31dLCBpc3N1ZXM6IFtdIH0sIGN0eClgO1xuICAgICAgICB9O1xuICAgICAgICBkb2Mud3JpdGUoYGNvbnN0IGlucHV0ID0gcGF5bG9hZC52YWx1ZTtgKTtcbiAgICAgICAgY29uc3QgaWRzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgbGV0IGNvdW50ZXIgPSAwO1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBub3JtYWxpemVkLmtleXMpe1xuICAgICAgICAgICAgaWRzW2tleV0gPSBga2V5XyR7Y291bnRlcisrfWA7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQTogcHJlc2VydmUga2V5IG9yZGVyIHtcbiAgICAgICAgZG9jLndyaXRlKGBjb25zdCBuZXdSZXN1bHQgPSB7fTtgKTtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2Ygbm9ybWFsaXplZC5rZXlzKXtcbiAgICAgICAgICAgIGNvbnN0IGlkID0gaWRzW2tleV07XG4gICAgICAgICAgICBjb25zdCBrID0gdXRpbC5lc2Moa2V5KTtcbiAgICAgICAgICAgIGRvYy53cml0ZShgY29uc3QgJHtpZH0gPSAke3BhcnNlU3RyKGtleSl9O2ApO1xuICAgICAgICAgICAgZG9jLndyaXRlKGBcbiAgICAgICAgaWYgKCR7aWR9Lmlzc3Vlcy5sZW5ndGgpIHtcbiAgICAgICAgICBwYXlsb2FkLmlzc3VlcyA9IHBheWxvYWQuaXNzdWVzLmNvbmNhdCgke2lkfS5pc3N1ZXMubWFwKGlzcyA9PiAoe1xuICAgICAgICAgICAgLi4uaXNzLFxuICAgICAgICAgICAgcGF0aDogaXNzLnBhdGggPyBbJHtrfSwgLi4uaXNzLnBhdGhdIDogWyR7a31dXG4gICAgICAgICAgfSkpKTtcbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgXG4gICAgICAgIGlmICgke2lkfS52YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaWYgKCR7a30gaW4gaW5wdXQpIHtcbiAgICAgICAgICAgIG5ld1Jlc3VsdFske2t9XSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbmV3UmVzdWx0WyR7a31dID0gJHtpZH0udmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICBgKTtcbiAgICAgICAgfVxuICAgICAgICBkb2Mud3JpdGUoYHBheWxvYWQudmFsdWUgPSBuZXdSZXN1bHQ7YCk7XG4gICAgICAgIGRvYy53cml0ZShgcmV0dXJuIHBheWxvYWQ7YCk7XG4gICAgICAgIGNvbnN0IGZuID0gZG9jLmNvbXBpbGUoKTtcbiAgICAgICAgcmV0dXJuIChwYXlsb2FkLCBjdHgpPT5mbihzaGFwZSwgcGF5bG9hZCwgY3R4KTtcbiAgICB9O1xuICAgIGxldCBmYXN0cGFzcztcbiAgICBjb25zdCBpc09iamVjdCA9IHV0aWwuaXNPYmplY3Q7XG4gICAgY29uc3Qgaml0ID0gIWNvcmUuZ2xvYmFsQ29uZmlnLmppdGxlc3M7XG4gICAgY29uc3QgYWxsb3dzRXZhbCA9IHV0aWwuYWxsb3dzRXZhbDtcbiAgICBjb25zdCBmYXN0RW5hYmxlZCA9IGppdCAmJiBhbGxvd3NFdmFsLnZhbHVlOyAvLyAmJiAhZGVmLmNhdGNoYWxsO1xuICAgIGNvbnN0IGNhdGNoYWxsID0gZGVmLmNhdGNoYWxsO1xuICAgIGxldCB2YWx1ZTtcbiAgICBpbnN0Ll96b2QucGFyc2UgPSAocGF5bG9hZCwgY3R4KT0+e1xuICAgICAgICB2YWx1ZSA/PyAodmFsdWUgPSBfbm9ybWFsaXplZC52YWx1ZSk7XG4gICAgICAgIGNvbnN0IGlucHV0ID0gcGF5bG9hZC52YWx1ZTtcbiAgICAgICAgaWYgKCFpc09iamVjdChpbnB1dCkpIHtcbiAgICAgICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBcIm9iamVjdFwiLFxuICAgICAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF90eXBlXCIsXG4gICAgICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICAgICAgaW5zdFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaml0ICYmIGZhc3RFbmFibGVkICYmIGN0eD8uYXN5bmMgPT09IGZhbHNlICYmIGN0eC5qaXRsZXNzICE9PSB0cnVlKSB7XG4gICAgICAgICAgICAvLyBhbHdheXMgc3luY2hyb25vdXNcbiAgICAgICAgICAgIGlmICghZmFzdHBhc3MpIGZhc3RwYXNzID0gZ2VuZXJhdGVGYXN0cGFzcyhkZWYuc2hhcGUpO1xuICAgICAgICAgICAgcGF5bG9hZCA9IGZhc3RwYXNzKHBheWxvYWQsIGN0eCk7XG4gICAgICAgICAgICBpZiAoIWNhdGNoYWxsKSByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgICAgIHJldHVybiBoYW5kbGVDYXRjaGFsbChbXSwgaW5wdXQsIHBheWxvYWQsIGN0eCwgdmFsdWUsIGluc3QpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzdXBlclBhcnNlKHBheWxvYWQsIGN0eCk7XG4gICAgfTtcbn0pO1xuZnVuY3Rpb24gaGFuZGxlVW5pb25SZXN1bHRzKHJlc3VsdHMsIGZpbmFsLCBpbnN0LCBjdHgpIHtcbiAgICBmb3IgKGNvbnN0IHJlc3VsdCBvZiByZXN1bHRzKXtcbiAgICAgICAgaWYgKHJlc3VsdC5pc3N1ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICBmaW5hbC52YWx1ZSA9IHJlc3VsdC52YWx1ZTtcbiAgICAgICAgICAgIHJldHVybiBmaW5hbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBub25hYm9ydGVkID0gcmVzdWx0cy5maWx0ZXIoKHIpPT4hdXRpbC5hYm9ydGVkKHIpKTtcbiAgICBpZiAobm9uYWJvcnRlZC5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgZmluYWwudmFsdWUgPSBub25hYm9ydGVkWzBdLnZhbHVlO1xuICAgICAgICByZXR1cm4gbm9uYWJvcnRlZFswXTtcbiAgICB9XG4gICAgZmluYWwuaXNzdWVzLnB1c2goe1xuICAgICAgICBjb2RlOiBcImludmFsaWRfdW5pb25cIixcbiAgICAgICAgaW5wdXQ6IGZpbmFsLnZhbHVlLFxuICAgICAgICBpbnN0LFxuICAgICAgICBlcnJvcnM6IHJlc3VsdHMubWFwKChyZXN1bHQpPT5yZXN1bHQuaXNzdWVzLm1hcCgoaXNzKT0+dXRpbC5maW5hbGl6ZUlzc3VlKGlzcywgY3R4LCBjb3JlLmNvbmZpZygpKSkpXG4gICAgfSk7XG4gICAgcmV0dXJuIGZpbmFsO1xufVxuZXhwb3J0IGNvbnN0ICRab2RVbmlvbiA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kVW5pb25cIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgdXRpbC5kZWZpbmVMYXp5KGluc3QuX3pvZCwgXCJvcHRpblwiLCAoKT0+ZGVmLm9wdGlvbnMuc29tZSgobyk9Pm8uX3pvZC5vcHRpbiA9PT0gXCJvcHRpb25hbFwiKSA/IFwib3B0aW9uYWxcIiA6IHVuZGVmaW5lZCk7XG4gICAgdXRpbC5kZWZpbmVMYXp5KGluc3QuX3pvZCwgXCJvcHRvdXRcIiwgKCk9PmRlZi5vcHRpb25zLnNvbWUoKG8pPT5vLl96b2Qub3B0b3V0ID09PSBcIm9wdGlvbmFsXCIpID8gXCJvcHRpb25hbFwiIDogdW5kZWZpbmVkKTtcbiAgICB1dGlsLmRlZmluZUxhenkoaW5zdC5fem9kLCBcInZhbHVlc1wiLCAoKT0+e1xuICAgICAgICBpZiAoZGVmLm9wdGlvbnMuZXZlcnkoKG8pPT5vLl96b2QudmFsdWVzKSkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBTZXQoZGVmLm9wdGlvbnMuZmxhdE1hcCgob3B0aW9uKT0+QXJyYXkuZnJvbShvcHRpb24uX3pvZC52YWx1ZXMpKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9KTtcbiAgICB1dGlsLmRlZmluZUxhenkoaW5zdC5fem9kLCBcInBhdHRlcm5cIiwgKCk9PntcbiAgICAgICAgaWYgKGRlZi5vcHRpb25zLmV2ZXJ5KChvKT0+by5fem9kLnBhdHRlcm4pKSB7XG4gICAgICAgICAgICBjb25zdCBwYXR0ZXJucyA9IGRlZi5vcHRpb25zLm1hcCgobyk9Pm8uX3pvZC5wYXR0ZXJuKTtcbiAgICAgICAgICAgIHJldHVybiBuZXcgUmVnRXhwKGBeKCR7cGF0dGVybnMubWFwKChwKT0+dXRpbC5jbGVhblJlZ2V4KHAuc291cmNlKSkuam9pbihcInxcIil9KSRgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH0pO1xuICAgIGNvbnN0IHNpbmdsZSA9IGRlZi5vcHRpb25zLmxlbmd0aCA9PT0gMTtcbiAgICBjb25zdCBmaXJzdCA9IGRlZi5vcHRpb25zWzBdLl96b2QucnVuO1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkLCBjdHgpPT57XG4gICAgICAgIGlmIChzaW5nbGUpIHtcbiAgICAgICAgICAgIHJldHVybiBmaXJzdChwYXlsb2FkLCBjdHgpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBhc3luYyA9IGZhbHNlO1xuICAgICAgICBjb25zdCByZXN1bHRzID0gW107XG4gICAgICAgIGZvciAoY29uc3Qgb3B0aW9uIG9mIGRlZi5vcHRpb25zKXtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IG9wdGlvbi5fem9kLnJ1bih7XG4gICAgICAgICAgICAgICAgdmFsdWU6IHBheWxvYWQudmFsdWUsXG4gICAgICAgICAgICAgICAgaXNzdWVzOiBbXVxuICAgICAgICAgICAgfSwgY3R4KTtcbiAgICAgICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0cy5wdXNoKHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgYXN5bmMgPSB0cnVlO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0Lmlzc3Vlcy5sZW5ndGggPT09IDApIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICAgICAgcmVzdWx0cy5wdXNoKHJlc3VsdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFhc3luYykgcmV0dXJuIGhhbmRsZVVuaW9uUmVzdWx0cyhyZXN1bHRzLCBwYXlsb2FkLCBpbnN0LCBjdHgpO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocmVzdWx0cykudGhlbigocmVzdWx0cyk9PntcbiAgICAgICAgICAgIHJldHVybiBoYW5kbGVVbmlvblJlc3VsdHMocmVzdWx0cywgcGF5bG9hZCwgaW5zdCwgY3R4KTtcbiAgICAgICAgfSk7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2REaXNjcmltaW5hdGVkVW5pb24gPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZERpc2NyaW1pbmF0ZWRVbmlvblwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RVbmlvbi5pbml0KGluc3QsIGRlZik7XG4gICAgY29uc3QgX3N1cGVyID0gaW5zdC5fem9kLnBhcnNlO1xuICAgIHV0aWwuZGVmaW5lTGF6eShpbnN0Ll96b2QsIFwicHJvcFZhbHVlc1wiLCAoKT0+e1xuICAgICAgICBjb25zdCBwcm9wVmFsdWVzID0ge307XG4gICAgICAgIGZvciAoY29uc3Qgb3B0aW9uIG9mIGRlZi5vcHRpb25zKXtcbiAgICAgICAgICAgIGNvbnN0IHB2ID0gb3B0aW9uLl96b2QucHJvcFZhbHVlcztcbiAgICAgICAgICAgIGlmICghcHYgfHwgT2JqZWN0LmtleXMocHYpLmxlbmd0aCA9PT0gMCkgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGRpc2NyaW1pbmF0ZWQgdW5pb24gb3B0aW9uIGF0IGluZGV4IFwiJHtkZWYub3B0aW9ucy5pbmRleE9mKG9wdGlvbil9XCJgKTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgW2ssIHZdIG9mIE9iamVjdC5lbnRyaWVzKHB2KSl7XG4gICAgICAgICAgICAgICAgaWYgKCFwcm9wVmFsdWVzW2tdKSBwcm9wVmFsdWVzW2tdID0gbmV3IFNldCgpO1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgdmFsIG9mIHYpe1xuICAgICAgICAgICAgICAgICAgICBwcm9wVmFsdWVzW2tdLmFkZCh2YWwpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcHJvcFZhbHVlcztcbiAgICB9KTtcbiAgICBjb25zdCBkaXNjID0gdXRpbC5jYWNoZWQoKCk9PntcbiAgICAgICAgY29uc3Qgb3B0cyA9IGRlZi5vcHRpb25zO1xuICAgICAgICBjb25zdCBtYXAgPSBuZXcgTWFwKCk7XG4gICAgICAgIGZvciAoY29uc3QgbyBvZiBvcHRzKXtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlcyA9IG8uX3pvZC5wcm9wVmFsdWVzPy5bZGVmLmRpc2NyaW1pbmF0b3JdO1xuICAgICAgICAgICAgaWYgKCF2YWx1ZXMgfHwgdmFsdWVzLnNpemUgPT09IDApIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBkaXNjcmltaW5hdGVkIHVuaW9uIG9wdGlvbiBhdCBpbmRleCBcIiR7ZGVmLm9wdGlvbnMuaW5kZXhPZihvKX1cImApO1xuICAgICAgICAgICAgZm9yIChjb25zdCB2IG9mIHZhbHVlcyl7XG4gICAgICAgICAgICAgICAgaWYgKG1hcC5oYXModikpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBEdXBsaWNhdGUgZGlzY3JpbWluYXRvciB2YWx1ZSBcIiR7U3RyaW5nKHYpfVwiYCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG1hcC5zZXQodiwgbyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1hcDtcbiAgICB9KTtcbiAgICBpbnN0Ll96b2QucGFyc2UgPSAocGF5bG9hZCwgY3R4KT0+e1xuICAgICAgICBjb25zdCBpbnB1dCA9IHBheWxvYWQudmFsdWU7XG4gICAgICAgIGlmICghdXRpbC5pc09iamVjdChpbnB1dCkpIHtcbiAgICAgICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF90eXBlXCIsXG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IFwib2JqZWN0XCIsXG4gICAgICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICAgICAgaW5zdFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBvcHQgPSBkaXNjLnZhbHVlLmdldChpbnB1dD8uW2RlZi5kaXNjcmltaW5hdG9yXSk7XG4gICAgICAgIGlmIChvcHQpIHtcbiAgICAgICAgICAgIHJldHVybiBvcHQuX3pvZC5ydW4ocGF5bG9hZCwgY3R4KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGVmLnVuaW9uRmFsbGJhY2spIHtcbiAgICAgICAgICAgIHJldHVybiBfc3VwZXIocGF5bG9hZCwgY3R4KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBubyBtYXRjaGluZyBkaXNjcmltaW5hdG9yXG4gICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX3VuaW9uXCIsXG4gICAgICAgICAgICBlcnJvcnM6IFtdLFxuICAgICAgICAgICAgbm90ZTogXCJObyBtYXRjaGluZyBkaXNjcmltaW5hdG9yXCIsXG4gICAgICAgICAgICBkaXNjcmltaW5hdG9yOiBkZWYuZGlzY3JpbWluYXRvcixcbiAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgcGF0aDogW1xuICAgICAgICAgICAgICAgIGRlZi5kaXNjcmltaW5hdG9yXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgaW5zdFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RJbnRlcnNlY3Rpb24gPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZEludGVyc2VjdGlvblwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0Ll96b2QucGFyc2UgPSAocGF5bG9hZCwgY3R4KT0+e1xuICAgICAgICBjb25zdCBpbnB1dCA9IHBheWxvYWQudmFsdWU7XG4gICAgICAgIGNvbnN0IGxlZnQgPSBkZWYubGVmdC5fem9kLnJ1bih7XG4gICAgICAgICAgICB2YWx1ZTogaW5wdXQsXG4gICAgICAgICAgICBpc3N1ZXM6IFtdXG4gICAgICAgIH0sIGN0eCk7XG4gICAgICAgIGNvbnN0IHJpZ2h0ID0gZGVmLnJpZ2h0Ll96b2QucnVuKHtcbiAgICAgICAgICAgIHZhbHVlOiBpbnB1dCxcbiAgICAgICAgICAgIGlzc3VlczogW11cbiAgICAgICAgfSwgY3R4KTtcbiAgICAgICAgY29uc3QgYXN5bmMgPSBsZWZ0IGluc3RhbmNlb2YgUHJvbWlzZSB8fCByaWdodCBpbnN0YW5jZW9mIFByb21pc2U7XG4gICAgICAgIGlmIChhc3luYykge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFtcbiAgICAgICAgICAgICAgICBsZWZ0LFxuICAgICAgICAgICAgICAgIHJpZ2h0XG4gICAgICAgICAgICBdKS50aGVuKChbbGVmdCwgcmlnaHRdKT0+e1xuICAgICAgICAgICAgICAgIHJldHVybiBoYW5kbGVJbnRlcnNlY3Rpb25SZXN1bHRzKHBheWxvYWQsIGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBoYW5kbGVJbnRlcnNlY3Rpb25SZXN1bHRzKHBheWxvYWQsIGxlZnQsIHJpZ2h0KTtcbiAgICB9O1xufSk7XG5mdW5jdGlvbiBtZXJnZVZhbHVlcyhhLCBiKSB7XG4gICAgLy8gY29uc3QgYVR5cGUgPSBwYXJzZS50KGEpO1xuICAgIC8vIGNvbnN0IGJUeXBlID0gcGFyc2UudChiKTtcbiAgICBpZiAoYSA9PT0gYikge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdmFsaWQ6IHRydWUsXG4gICAgICAgICAgICBkYXRhOiBhXG4gICAgICAgIH07XG4gICAgfVxuICAgIGlmIChhIGluc3RhbmNlb2YgRGF0ZSAmJiBiIGluc3RhbmNlb2YgRGF0ZSAmJiArYSA9PT0gK2IpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHZhbGlkOiB0cnVlLFxuICAgICAgICAgICAgZGF0YTogYVxuICAgICAgICB9O1xuICAgIH1cbiAgICBpZiAodXRpbC5pc1BsYWluT2JqZWN0KGEpICYmIHV0aWwuaXNQbGFpbk9iamVjdChiKSkge1xuICAgICAgICBjb25zdCBiS2V5cyA9IE9iamVjdC5rZXlzKGIpO1xuICAgICAgICBjb25zdCBzaGFyZWRLZXlzID0gT2JqZWN0LmtleXMoYSkuZmlsdGVyKChrZXkpPT5iS2V5cy5pbmRleE9mKGtleSkgIT09IC0xKTtcbiAgICAgICAgY29uc3QgbmV3T2JqID0ge1xuICAgICAgICAgICAgLi4uYSxcbiAgICAgICAgICAgIC4uLmJcbiAgICAgICAgfTtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2Ygc2hhcmVkS2V5cyl7XG4gICAgICAgICAgICBjb25zdCBzaGFyZWRWYWx1ZSA9IG1lcmdlVmFsdWVzKGFba2V5XSwgYltrZXldKTtcbiAgICAgICAgICAgIGlmICghc2hhcmVkVmFsdWUudmFsaWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICB2YWxpZDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIG1lcmdlRXJyb3JQYXRoOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgICAgICAgICAuLi5zaGFyZWRWYWx1ZS5tZXJnZUVycm9yUGF0aFxuICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG5ld09ialtrZXldID0gc2hhcmVkVmFsdWUuZGF0YTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdmFsaWQ6IHRydWUsXG4gICAgICAgICAgICBkYXRhOiBuZXdPYmpcbiAgICAgICAgfTtcbiAgICB9XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoYSkgJiYgQXJyYXkuaXNBcnJheShiKSkge1xuICAgICAgICBpZiAoYS5sZW5ndGggIT09IGIubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHZhbGlkOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBtZXJnZUVycm9yUGF0aDogW11cbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmV3QXJyYXkgPSBbXTtcbiAgICAgICAgZm9yKGxldCBpbmRleCA9IDA7IGluZGV4IDwgYS5sZW5ndGg7IGluZGV4Kyspe1xuICAgICAgICAgICAgY29uc3QgaXRlbUEgPSBhW2luZGV4XTtcbiAgICAgICAgICAgIGNvbnN0IGl0ZW1CID0gYltpbmRleF07XG4gICAgICAgICAgICBjb25zdCBzaGFyZWRWYWx1ZSA9IG1lcmdlVmFsdWVzKGl0ZW1BLCBpdGVtQik7XG4gICAgICAgICAgICBpZiAoIXNoYXJlZFZhbHVlLnZhbGlkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsaWQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBtZXJnZUVycm9yUGF0aDogW1xuICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXgsXG4gICAgICAgICAgICAgICAgICAgICAgICAuLi5zaGFyZWRWYWx1ZS5tZXJnZUVycm9yUGF0aFxuICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG5ld0FycmF5LnB1c2goc2hhcmVkVmFsdWUuZGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHZhbGlkOiB0cnVlLFxuICAgICAgICAgICAgZGF0YTogbmV3QXJyYXlcbiAgICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgdmFsaWQ6IGZhbHNlLFxuICAgICAgICBtZXJnZUVycm9yUGF0aDogW11cbiAgICB9O1xufVxuZnVuY3Rpb24gaGFuZGxlSW50ZXJzZWN0aW9uUmVzdWx0cyhyZXN1bHQsIGxlZnQsIHJpZ2h0KSB7XG4gICAgaWYgKGxlZnQuaXNzdWVzLmxlbmd0aCkge1xuICAgICAgICByZXN1bHQuaXNzdWVzLnB1c2goLi4ubGVmdC5pc3N1ZXMpO1xuICAgIH1cbiAgICBpZiAocmlnaHQuaXNzdWVzLmxlbmd0aCkge1xuICAgICAgICByZXN1bHQuaXNzdWVzLnB1c2goLi4ucmlnaHQuaXNzdWVzKTtcbiAgICB9XG4gICAgaWYgKHV0aWwuYWJvcnRlZChyZXN1bHQpKSByZXR1cm4gcmVzdWx0O1xuICAgIGNvbnN0IG1lcmdlZCA9IG1lcmdlVmFsdWVzKGxlZnQudmFsdWUsIHJpZ2h0LnZhbHVlKTtcbiAgICBpZiAoIW1lcmdlZC52YWxpZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVubWVyZ2FibGUgaW50ZXJzZWN0aW9uLiBFcnJvciBwYXRoOiBgICsgYCR7SlNPTi5zdHJpbmdpZnkobWVyZ2VkLm1lcmdlRXJyb3JQYXRoKX1gKTtcbiAgICB9XG4gICAgcmVzdWx0LnZhbHVlID0gbWVyZ2VkLmRhdGE7XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbmV4cG9ydCBjb25zdCAkWm9kVHVwbGUgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZFR1cGxlXCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGNvbnN0IGl0ZW1zID0gZGVmLml0ZW1zO1xuICAgIGNvbnN0IG9wdFN0YXJ0ID0gaXRlbXMubGVuZ3RoIC0gW1xuICAgICAgICAuLi5pdGVtc1xuICAgIF0ucmV2ZXJzZSgpLmZpbmRJbmRleCgoaXRlbSk9Pml0ZW0uX3pvZC5vcHRpbiAhPT0gXCJvcHRpb25hbFwiKTtcbiAgICBpbnN0Ll96b2QucGFyc2UgPSAocGF5bG9hZCwgY3R4KT0+e1xuICAgICAgICBjb25zdCBpbnB1dCA9IHBheWxvYWQudmFsdWU7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShpbnB1dCkpIHtcbiAgICAgICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgICAgIGluc3QsXG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IFwidHVwbGVcIixcbiAgICAgICAgICAgICAgICBjb2RlOiBcImludmFsaWRfdHlwZVwiXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgICAgICB9XG4gICAgICAgIHBheWxvYWQudmFsdWUgPSBbXTtcbiAgICAgICAgY29uc3QgcHJvbXMgPSBbXTtcbiAgICAgICAgaWYgKCFkZWYucmVzdCkge1xuICAgICAgICAgICAgY29uc3QgdG9vQmlnID0gaW5wdXQubGVuZ3RoID4gaXRlbXMubGVuZ3RoO1xuICAgICAgICAgICAgY29uc3QgdG9vU21hbGwgPSBpbnB1dC5sZW5ndGggPCBvcHRTdGFydCAtIDE7XG4gICAgICAgICAgICBpZiAodG9vQmlnIHx8IHRvb1NtYWxsKSB7XG4gICAgICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIC4uLnRvb0JpZyA/IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFwidG9vX2JpZ1wiLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWF4aW11bTogaXRlbXMubGVuZ3RoXG4gICAgICAgICAgICAgICAgICAgIH0gOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBcInRvb19zbWFsbFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWluaW11bTogaXRlbXMubGVuZ3RoXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgICAgICAgICBvcmlnaW46IFwiYXJyYXlcIlxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxldCBpID0gLTE7XG4gICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcyl7XG4gICAgICAgICAgICBpKys7XG4gICAgICAgICAgICBpZiAoaSA+PSBpbnB1dC5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBpZiAoaSA+PSBvcHRTdGFydCkgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBpdGVtLl96b2QucnVuKHtcbiAgICAgICAgICAgICAgICB2YWx1ZTogaW5wdXRbaV0sXG4gICAgICAgICAgICAgICAgaXNzdWVzOiBbXVxuICAgICAgICAgICAgfSwgY3R4KTtcbiAgICAgICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICAgICAgcHJvbXMucHVzaChyZXN1bHQudGhlbigocmVzdWx0KT0+aGFuZGxlVHVwbGVSZXN1bHQocmVzdWx0LCBwYXlsb2FkLCBpKSkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBoYW5kbGVUdXBsZVJlc3VsdChyZXN1bHQsIHBheWxvYWQsIGkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChkZWYucmVzdCkge1xuICAgICAgICAgICAgY29uc3QgcmVzdCA9IGlucHV0LnNsaWNlKGl0ZW1zLmxlbmd0aCk7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGVsIG9mIHJlc3Qpe1xuICAgICAgICAgICAgICAgIGkrKztcbiAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSBkZWYucmVzdC5fem9kLnJ1bih7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiBlbCxcbiAgICAgICAgICAgICAgICAgICAgaXNzdWVzOiBbXVxuICAgICAgICAgICAgICAgIH0sIGN0eCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgcHJvbXMucHVzaChyZXN1bHQudGhlbigocmVzdWx0KT0+aGFuZGxlVHVwbGVSZXN1bHQocmVzdWx0LCBwYXlsb2FkLCBpKSkpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGhhbmRsZVR1cGxlUmVzdWx0KHJlc3VsdCwgcGF5bG9hZCwgaSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9tcy5sZW5ndGgpIHJldHVybiBQcm9taXNlLmFsbChwcm9tcykudGhlbigoKT0+cGF5bG9hZCk7XG4gICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgIH07XG59KTtcbmZ1bmN0aW9uIGhhbmRsZVR1cGxlUmVzdWx0KHJlc3VsdCwgZmluYWwsIGluZGV4KSB7XG4gICAgaWYgKHJlc3VsdC5pc3N1ZXMubGVuZ3RoKSB7XG4gICAgICAgIGZpbmFsLmlzc3Vlcy5wdXNoKC4uLnV0aWwucHJlZml4SXNzdWVzKGluZGV4LCByZXN1bHQuaXNzdWVzKSk7XG4gICAgfVxuICAgIGZpbmFsLnZhbHVlW2luZGV4XSA9IHJlc3VsdC52YWx1ZTtcbn1cbmV4cG9ydCBjb25zdCAkWm9kUmVjb3JkID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RSZWNvcmRcIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5fem9kLnBhcnNlID0gKHBheWxvYWQsIGN0eCk9PntcbiAgICAgICAgY29uc3QgaW5wdXQgPSBwYXlsb2FkLnZhbHVlO1xuICAgICAgICBpZiAoIXV0aWwuaXNQbGFpbk9iamVjdChpbnB1dCkpIHtcbiAgICAgICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBcInJlY29yZFwiLFxuICAgICAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF90eXBlXCIsXG4gICAgICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICAgICAgaW5zdFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwcm9tcyA9IFtdO1xuICAgICAgICBpZiAoZGVmLmtleVR5cGUuX3pvZC52YWx1ZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlcyA9IGRlZi5rZXlUeXBlLl96b2QudmFsdWVzO1xuICAgICAgICAgICAgcGF5bG9hZC52YWx1ZSA9IHt9O1xuICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgdmFsdWVzKXtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGtleSA9PT0gXCJzdHJpbmdcIiB8fCB0eXBlb2Yga2V5ID09PSBcIm51bWJlclwiIHx8IHR5cGVvZiBrZXkgPT09IFwic3ltYm9sXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gZGVmLnZhbHVlVHlwZS5fem9kLnJ1bih7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogaW5wdXRba2V5XSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzc3VlczogW11cbiAgICAgICAgICAgICAgICAgICAgfSwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb21zLnB1c2gocmVzdWx0LnRoZW4oKHJlc3VsdCk9PntcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0Lmlzc3Vlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCguLi51dGlsLnByZWZpeElzc3VlcyhrZXksIHJlc3VsdC5pc3N1ZXMpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF5bG9hZC52YWx1ZVtrZXldID0gcmVzdWx0LnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5pc3N1ZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCguLi51dGlsLnByZWZpeElzc3VlcyhrZXksIHJlc3VsdC5pc3N1ZXMpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHBheWxvYWQudmFsdWVba2V5XSA9IHJlc3VsdC52YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCB1bnJlY29nbml6ZWQ7XG4gICAgICAgICAgICBmb3IoY29uc3Qga2V5IGluIGlucHV0KXtcbiAgICAgICAgICAgICAgICBpZiAoIXZhbHVlcy5oYXMoa2V5KSkge1xuICAgICAgICAgICAgICAgICAgICB1bnJlY29nbml6ZWQgPSB1bnJlY29nbml6ZWQgPz8gW107XG4gICAgICAgICAgICAgICAgICAgIHVucmVjb2duaXplZC5wdXNoKGtleSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHVucmVjb2duaXplZCAmJiB1bnJlY29nbml6ZWQubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBjb2RlOiBcInVucmVjb2duaXplZF9rZXlzXCIsXG4gICAgICAgICAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgICAgICAgICBrZXlzOiB1bnJlY29nbml6ZWRcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBheWxvYWQudmFsdWUgPSB7fTtcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IG9mIFJlZmxlY3Qub3duS2V5cyhpbnB1dCkpe1xuICAgICAgICAgICAgICAgIGlmIChrZXkgPT09IFwiX19wcm90b19fXCIpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIGNvbnN0IGtleVJlc3VsdCA9IGRlZi5rZXlUeXBlLl96b2QucnVuKHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGtleSxcbiAgICAgICAgICAgICAgICAgICAgaXNzdWVzOiBbXVxuICAgICAgICAgICAgICAgIH0sIGN0eCk7XG4gICAgICAgICAgICAgICAgaWYgKGtleVJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQXN5bmMgc2NoZW1hcyBub3Qgc3VwcG9ydGVkIGluIG9iamVjdCBrZXlzIGN1cnJlbnRseVwiKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGtleVJlc3VsdC5pc3N1ZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX2tleVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luOiBcInJlY29yZFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgaXNzdWVzOiBrZXlSZXN1bHQuaXNzdWVzLm1hcCgoaXNzKT0+dXRpbC5maW5hbGl6ZUlzc3VlKGlzcywgY3R4LCBjb3JlLmNvbmZpZygpKSksXG4gICAgICAgICAgICAgICAgICAgICAgICBpbnB1dDoga2V5LFxuICAgICAgICAgICAgICAgICAgICAgICAgcGF0aDogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleVxuICAgICAgICAgICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGluc3RcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHBheWxvYWQudmFsdWVba2V5UmVzdWx0LnZhbHVlXSA9IGtleVJlc3VsdC52YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGRlZi52YWx1ZVR5cGUuX3pvZC5ydW4oe1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogaW5wdXRba2V5XSxcbiAgICAgICAgICAgICAgICAgICAgaXNzdWVzOiBbXVxuICAgICAgICAgICAgICAgIH0sIGN0eCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgcHJvbXMucHVzaChyZXN1bHQudGhlbigocmVzdWx0KT0+e1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5pc3N1ZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCguLi51dGlsLnByZWZpeElzc3VlcyhrZXksIHJlc3VsdC5pc3N1ZXMpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHBheWxvYWQudmFsdWVba2V5UmVzdWx0LnZhbHVlXSA9IHJlc3VsdC52YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQuaXNzdWVzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCguLi51dGlsLnByZWZpeElzc3VlcyhrZXksIHJlc3VsdC5pc3N1ZXMpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBwYXlsb2FkLnZhbHVlW2tleVJlc3VsdC52YWx1ZV0gPSByZXN1bHQudmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9tcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9tcykudGhlbigoKT0+cGF5bG9hZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2RNYXAgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZE1hcFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0Ll96b2QucGFyc2UgPSAocGF5bG9hZCwgY3R4KT0+e1xuICAgICAgICBjb25zdCBpbnB1dCA9IHBheWxvYWQudmFsdWU7XG4gICAgICAgIGlmICghKGlucHV0IGluc3RhbmNlb2YgTWFwKSkge1xuICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IFwibWFwXCIsXG4gICAgICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX3R5cGVcIixcbiAgICAgICAgICAgICAgICBpbnB1dCxcbiAgICAgICAgICAgICAgICBpbnN0XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHByb21zID0gW107XG4gICAgICAgIHBheWxvYWQudmFsdWUgPSBuZXcgTWFwKCk7XG4gICAgICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIGlucHV0KXtcbiAgICAgICAgICAgIGNvbnN0IGtleVJlc3VsdCA9IGRlZi5rZXlUeXBlLl96b2QucnVuKHtcbiAgICAgICAgICAgICAgICB2YWx1ZToga2V5LFxuICAgICAgICAgICAgICAgIGlzc3VlczogW11cbiAgICAgICAgICAgIH0sIGN0eCk7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZVJlc3VsdCA9IGRlZi52YWx1ZVR5cGUuX3pvZC5ydW4oe1xuICAgICAgICAgICAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICBpc3N1ZXM6IFtdXG4gICAgICAgICAgICB9LCBjdHgpO1xuICAgICAgICAgICAgaWYgKGtleVJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UgfHwgdmFsdWVSZXN1bHQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICAgICAgcHJvbXMucHVzaChQcm9taXNlLmFsbChbXG4gICAgICAgICAgICAgICAgICAgIGtleVJlc3VsdCxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWVSZXN1bHRcbiAgICAgICAgICAgICAgICBdKS50aGVuKChba2V5UmVzdWx0LCB2YWx1ZVJlc3VsdF0pPT57XG4gICAgICAgICAgICAgICAgICAgIGhhbmRsZU1hcFJlc3VsdChrZXlSZXN1bHQsIHZhbHVlUmVzdWx0LCBwYXlsb2FkLCBrZXksIGlucHV0LCBpbnN0LCBjdHgpO1xuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaGFuZGxlTWFwUmVzdWx0KGtleVJlc3VsdCwgdmFsdWVSZXN1bHQsIHBheWxvYWQsIGtleSwgaW5wdXQsIGluc3QsIGN0eCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb21zLmxlbmd0aCkgcmV0dXJuIFByb21pc2UuYWxsKHByb21zKS50aGVuKCgpPT5wYXlsb2FkKTtcbiAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgfTtcbn0pO1xuZnVuY3Rpb24gaGFuZGxlTWFwUmVzdWx0KGtleVJlc3VsdCwgdmFsdWVSZXN1bHQsIGZpbmFsLCBrZXksIGlucHV0LCBpbnN0LCBjdHgpIHtcbiAgICBpZiAoa2V5UmVzdWx0Lmlzc3Vlcy5sZW5ndGgpIHtcbiAgICAgICAgaWYgKHV0aWwucHJvcGVydHlLZXlUeXBlcy5oYXModHlwZW9mIGtleSkpIHtcbiAgICAgICAgICAgIGZpbmFsLmlzc3Vlcy5wdXNoKC4uLnV0aWwucHJlZml4SXNzdWVzKGtleSwga2V5UmVzdWx0Lmlzc3VlcykpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZmluYWwuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF9rZXlcIixcbiAgICAgICAgICAgICAgICBvcmlnaW46IFwibWFwXCIsXG4gICAgICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICAgICAgaW5zdCxcbiAgICAgICAgICAgICAgICBpc3N1ZXM6IGtleVJlc3VsdC5pc3N1ZXMubWFwKChpc3MpPT51dGlsLmZpbmFsaXplSXNzdWUoaXNzLCBjdHgsIGNvcmUuY29uZmlnKCkpKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKHZhbHVlUmVzdWx0Lmlzc3Vlcy5sZW5ndGgpIHtcbiAgICAgICAgaWYgKHV0aWwucHJvcGVydHlLZXlUeXBlcy5oYXModHlwZW9mIGtleSkpIHtcbiAgICAgICAgICAgIGZpbmFsLmlzc3Vlcy5wdXNoKC4uLnV0aWwucHJlZml4SXNzdWVzKGtleSwgdmFsdWVSZXN1bHQuaXNzdWVzKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmaW5hbC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgb3JpZ2luOiBcIm1hcFwiLFxuICAgICAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF9lbGVtZW50XCIsXG4gICAgICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICAgICAgaW5zdCxcbiAgICAgICAgICAgICAgICBrZXk6IGtleSxcbiAgICAgICAgICAgICAgICBpc3N1ZXM6IHZhbHVlUmVzdWx0Lmlzc3Vlcy5tYXAoKGlzcyk9PnV0aWwuZmluYWxpemVJc3N1ZShpc3MsIGN0eCwgY29yZS5jb25maWcoKSkpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBmaW5hbC52YWx1ZS5zZXQoa2V5UmVzdWx0LnZhbHVlLCB2YWx1ZVJlc3VsdC52YWx1ZSk7XG59XG5leHBvcnQgY29uc3QgJFpvZFNldCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kU2V0XCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkLCBjdHgpPT57XG4gICAgICAgIGNvbnN0IGlucHV0ID0gcGF5bG9hZC52YWx1ZTtcbiAgICAgICAgaWYgKCEoaW5wdXQgaW5zdGFuY2VvZiBTZXQpKSB7XG4gICAgICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICBpbnB1dCxcbiAgICAgICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBcInNldFwiLFxuICAgICAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF90eXBlXCJcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcHJvbXMgPSBbXTtcbiAgICAgICAgcGF5bG9hZC52YWx1ZSA9IG5ldyBTZXQoKTtcbiAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIGlucHV0KXtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGRlZi52YWx1ZVR5cGUuX3pvZC5ydW4oe1xuICAgICAgICAgICAgICAgIHZhbHVlOiBpdGVtLFxuICAgICAgICAgICAgICAgIGlzc3VlczogW11cbiAgICAgICAgICAgIH0sIGN0eCk7XG4gICAgICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgICAgIHByb21zLnB1c2gocmVzdWx0LnRoZW4oKHJlc3VsdCk9PmhhbmRsZVNldFJlc3VsdChyZXN1bHQsIHBheWxvYWQpKSk7XG4gICAgICAgICAgICB9IGVsc2UgaGFuZGxlU2V0UmVzdWx0KHJlc3VsdCwgcGF5bG9hZCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb21zLmxlbmd0aCkgcmV0dXJuIFByb21pc2UuYWxsKHByb21zKS50aGVuKCgpPT5wYXlsb2FkKTtcbiAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgfTtcbn0pO1xuZnVuY3Rpb24gaGFuZGxlU2V0UmVzdWx0KHJlc3VsdCwgZmluYWwpIHtcbiAgICBpZiAocmVzdWx0Lmlzc3Vlcy5sZW5ndGgpIHtcbiAgICAgICAgZmluYWwuaXNzdWVzLnB1c2goLi4ucmVzdWx0Lmlzc3Vlcyk7XG4gICAgfVxuICAgIGZpbmFsLnZhbHVlLmFkZChyZXN1bHQudmFsdWUpO1xufVxuZXhwb3J0IGNvbnN0ICRab2RFbnVtID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RFbnVtXCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGNvbnN0IHZhbHVlcyA9IHV0aWwuZ2V0RW51bVZhbHVlcyhkZWYuZW50cmllcyk7XG4gICAgY29uc3QgdmFsdWVzU2V0ID0gbmV3IFNldCh2YWx1ZXMpO1xuICAgIGluc3QuX3pvZC52YWx1ZXMgPSB2YWx1ZXNTZXQ7XG4gICAgaW5zdC5fem9kLnBhdHRlcm4gPSBuZXcgUmVnRXhwKGBeKCR7dmFsdWVzLmZpbHRlcigoayk9PnV0aWwucHJvcGVydHlLZXlUeXBlcy5oYXModHlwZW9mIGspKS5tYXAoKG8pPT50eXBlb2YgbyA9PT0gXCJzdHJpbmdcIiA/IHV0aWwuZXNjYXBlUmVnZXgobykgOiBvLnRvU3RyaW5nKCkpLmpvaW4oXCJ8XCIpfSkkYCk7XG4gICAgaW5zdC5fem9kLnBhcnNlID0gKHBheWxvYWQsIF9jdHgpPT57XG4gICAgICAgIGNvbnN0IGlucHV0ID0gcGF5bG9hZC52YWx1ZTtcbiAgICAgICAgaWYgKHZhbHVlc1NldC5oYXMoaW5wdXQpKSB7XG4gICAgICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgfVxuICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF92YWx1ZVwiLFxuICAgICAgICAgICAgdmFsdWVzLFxuICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICBpbnN0XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZExpdGVyYWwgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZExpdGVyYWxcIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaWYgKGRlZi52YWx1ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBjcmVhdGUgbGl0ZXJhbCBzY2hlbWEgd2l0aCBubyB2YWxpZCB2YWx1ZXNcIik7XG4gICAgfVxuICAgIGluc3QuX3pvZC52YWx1ZXMgPSBuZXcgU2V0KGRlZi52YWx1ZXMpO1xuICAgIGluc3QuX3pvZC5wYXR0ZXJuID0gbmV3IFJlZ0V4cChgXigke2RlZi52YWx1ZXMubWFwKChvKT0+dHlwZW9mIG8gPT09IFwic3RyaW5nXCIgPyB1dGlsLmVzY2FwZVJlZ2V4KG8pIDogbyA/IHV0aWwuZXNjYXBlUmVnZXgoby50b1N0cmluZygpKSA6IFN0cmluZyhvKSkuam9pbihcInxcIil9KSRgKTtcbiAgICBpbnN0Ll96b2QucGFyc2UgPSAocGF5bG9hZCwgX2N0eCk9PntcbiAgICAgICAgY29uc3QgaW5wdXQgPSBwYXlsb2FkLnZhbHVlO1xuICAgICAgICBpZiAoaW5zdC5fem9kLnZhbHVlcy5oYXMoaW5wdXQpKSB7XG4gICAgICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgfVxuICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF92YWx1ZVwiLFxuICAgICAgICAgICAgdmFsdWVzOiBkZWYudmFsdWVzLFxuICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICBpbnN0XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZEZpbGUgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZEZpbGVcIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5fem9kLnBhcnNlID0gKHBheWxvYWQsIF9jdHgpPT57XG4gICAgICAgIGNvbnN0IGlucHV0ID0gcGF5bG9hZC52YWx1ZTtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICBpZiAoaW5wdXQgaW5zdGFuY2VvZiBGaWxlKSByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICBleHBlY3RlZDogXCJmaWxlXCIsXG4gICAgICAgICAgICBjb2RlOiBcImludmFsaWRfdHlwZVwiLFxuICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICBpbnN0XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZFRyYW5zZm9ybSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kVHJhbnNmb3JtXCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkLCBjdHgpPT57XG4gICAgICAgIGlmIChjdHguZGlyZWN0aW9uID09PSBcImJhY2t3YXJkXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBjb3JlLiRab2RFbmNvZGVFcnJvcihpbnN0LmNvbnN0cnVjdG9yLm5hbWUpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IF9vdXQgPSBkZWYudHJhbnNmb3JtKHBheWxvYWQudmFsdWUsIHBheWxvYWQpO1xuICAgICAgICBpZiAoY3R4LmFzeW5jKSB7XG4gICAgICAgICAgICBjb25zdCBvdXRwdXQgPSBfb3V0IGluc3RhbmNlb2YgUHJvbWlzZSA/IF9vdXQgOiBQcm9taXNlLnJlc29sdmUoX291dCk7XG4gICAgICAgICAgICByZXR1cm4gb3V0cHV0LnRoZW4oKG91dHB1dCk9PntcbiAgICAgICAgICAgICAgICBwYXlsb2FkLnZhbHVlID0gb3V0cHV0O1xuICAgICAgICAgICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKF9vdXQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgY29yZS4kWm9kQXN5bmNFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIHBheWxvYWQudmFsdWUgPSBfb3V0O1xuICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICB9O1xufSk7XG5mdW5jdGlvbiBoYW5kbGVPcHRpb25hbFJlc3VsdChyZXN1bHQsIGlucHV0KSB7XG4gICAgaWYgKHJlc3VsdC5pc3N1ZXMubGVuZ3RoICYmIGlucHV0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGlzc3VlczogW10sXG4gICAgICAgICAgICB2YWx1ZTogdW5kZWZpbmVkXG4gICAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59XG5leHBvcnQgY29uc3QgJFpvZE9wdGlvbmFsID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RPcHRpb25hbFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0Ll96b2Qub3B0aW4gPSBcIm9wdGlvbmFsXCI7XG4gICAgaW5zdC5fem9kLm9wdG91dCA9IFwib3B0aW9uYWxcIjtcbiAgICB1dGlsLmRlZmluZUxhenkoaW5zdC5fem9kLCBcInZhbHVlc1wiLCAoKT0+e1xuICAgICAgICByZXR1cm4gZGVmLmlubmVyVHlwZS5fem9kLnZhbHVlcyA/IG5ldyBTZXQoW1xuICAgICAgICAgICAgLi4uZGVmLmlubmVyVHlwZS5fem9kLnZhbHVlcyxcbiAgICAgICAgICAgIHVuZGVmaW5lZFxuICAgICAgICBdKSA6IHVuZGVmaW5lZDtcbiAgICB9KTtcbiAgICB1dGlsLmRlZmluZUxhenkoaW5zdC5fem9kLCBcInBhdHRlcm5cIiwgKCk9PntcbiAgICAgICAgY29uc3QgcGF0dGVybiA9IGRlZi5pbm5lclR5cGUuX3pvZC5wYXR0ZXJuO1xuICAgICAgICByZXR1cm4gcGF0dGVybiA/IG5ldyBSZWdFeHAoYF4oJHt1dGlsLmNsZWFuUmVnZXgocGF0dGVybi5zb3VyY2UpfSk/JGApIDogdW5kZWZpbmVkO1xuICAgIH0pO1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkLCBjdHgpPT57XG4gICAgICAgIGlmIChkZWYuaW5uZXJUeXBlLl96b2Qub3B0aW4gPT09IFwib3B0aW9uYWxcIikge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gZGVmLmlubmVyVHlwZS5fem9kLnJ1bihwYXlsb2FkLCBjdHgpO1xuICAgICAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHJldHVybiByZXN1bHQudGhlbigocik9PmhhbmRsZU9wdGlvbmFsUmVzdWx0KHIsIHBheWxvYWQudmFsdWUpKTtcbiAgICAgICAgICAgIHJldHVybiBoYW5kbGVPcHRpb25hbFJlc3VsdChyZXN1bHQsIHBheWxvYWQudmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwYXlsb2FkLnZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkZWYuaW5uZXJUeXBlLl96b2QucnVuKHBheWxvYWQsIGN0eCk7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2ROdWxsYWJsZSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kTnVsbGFibGVcIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgdXRpbC5kZWZpbmVMYXp5KGluc3QuX3pvZCwgXCJvcHRpblwiLCAoKT0+ZGVmLmlubmVyVHlwZS5fem9kLm9wdGluKTtcbiAgICB1dGlsLmRlZmluZUxhenkoaW5zdC5fem9kLCBcIm9wdG91dFwiLCAoKT0+ZGVmLmlubmVyVHlwZS5fem9kLm9wdG91dCk7XG4gICAgdXRpbC5kZWZpbmVMYXp5KGluc3QuX3pvZCwgXCJwYXR0ZXJuXCIsICgpPT57XG4gICAgICAgIGNvbnN0IHBhdHRlcm4gPSBkZWYuaW5uZXJUeXBlLl96b2QucGF0dGVybjtcbiAgICAgICAgcmV0dXJuIHBhdHRlcm4gPyBuZXcgUmVnRXhwKGBeKCR7dXRpbC5jbGVhblJlZ2V4KHBhdHRlcm4uc291cmNlKX18bnVsbCkkYCkgOiB1bmRlZmluZWQ7XG4gICAgfSk7XG4gICAgdXRpbC5kZWZpbmVMYXp5KGluc3QuX3pvZCwgXCJ2YWx1ZXNcIiwgKCk9PntcbiAgICAgICAgcmV0dXJuIGRlZi5pbm5lclR5cGUuX3pvZC52YWx1ZXMgPyBuZXcgU2V0KFtcbiAgICAgICAgICAgIC4uLmRlZi5pbm5lclR5cGUuX3pvZC52YWx1ZXMsXG4gICAgICAgICAgICBudWxsXG4gICAgICAgIF0pIDogdW5kZWZpbmVkO1xuICAgIH0pO1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkLCBjdHgpPT57XG4gICAgICAgIC8vIEZvcndhcmQgZGlyZWN0aW9uIChkZWNvZGUpOiBhbGxvdyBudWxsIHRvIHBhc3MgdGhyb3VnaFxuICAgICAgICBpZiAocGF5bG9hZC52YWx1ZSA9PT0gbnVsbCkgcmV0dXJuIHBheWxvYWQ7XG4gICAgICAgIHJldHVybiBkZWYuaW5uZXJUeXBlLl96b2QucnVuKHBheWxvYWQsIGN0eCk7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2REZWZhdWx0ID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2REZWZhdWx0XCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIC8vIGluc3QuX3pvZC5xaW4gPSBcInRydWVcIjtcbiAgICBpbnN0Ll96b2Qub3B0aW4gPSBcIm9wdGlvbmFsXCI7XG4gICAgdXRpbC5kZWZpbmVMYXp5KGluc3QuX3pvZCwgXCJ2YWx1ZXNcIiwgKCk9PmRlZi5pbm5lclR5cGUuX3pvZC52YWx1ZXMpO1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkLCBjdHgpPT57XG4gICAgICAgIGlmIChjdHguZGlyZWN0aW9uID09PSBcImJhY2t3YXJkXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBkZWYuaW5uZXJUeXBlLl96b2QucnVuKHBheWxvYWQsIGN0eCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRm9yd2FyZCBkaXJlY3Rpb24gKGRlY29kZSk6IGFwcGx5IGRlZmF1bHRzIGZvciB1bmRlZmluZWQgaW5wdXRcbiAgICAgICAgaWYgKHBheWxvYWQudmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcGF5bG9hZC52YWx1ZSA9IGRlZi5kZWZhdWx0VmFsdWU7XG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqICRab2REZWZhdWx0IHJldHVybnMgdGhlIGRlZmF1bHQgdmFsdWUgaW1tZWRpYXRlbHkgaW4gZm9yd2FyZCBkaXJlY3Rpb24uXG4gICAgICAgICAgICAgKiBJdCBkb2Vzbid0IHBhc3MgdGhlIGRlZmF1bHQgdmFsdWUgaW50byB0aGUgdmFsaWRhdG9yIChcInByZWZhdWx0XCIpLiBUaGVyZSdzIG5vIHJlYXNvbiB0byBwYXNzIHRoZSBkZWZhdWx0IHZhbHVlIHRocm91Z2ggdmFsaWRhdGlvbi4gVGhlIHZhbGlkaXR5IG9mIHRoZSBkZWZhdWx0IGlzIGVuZm9yY2VkIGJ5IFR5cGVTY3JpcHQgc3RhdGljYWxseS4gT3RoZXJ3aXNlLCBpdCdzIHRoZSByZXNwb25zaWJpbGl0eSBvZiB0aGUgdXNlciB0byBlbnN1cmUgdGhlIGRlZmF1bHQgaXMgdmFsaWQuIEluIHRoZSBjYXNlIG9mIHBpcGVzIHdpdGggZGl2ZXJnZW50IGluL291dCB0eXBlcywgeW91IGNhbiBzcGVjaWZ5IHRoZSBkZWZhdWx0IG9uIHRoZSBgaW5gIHNjaGVtYSBvZiB5b3VyIFpvZFBpcGUgdG8gc2V0IGEgXCJwcmVmYXVsdFwiIGZvciB0aGUgcGlwZS4gICAqLyByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgfVxuICAgICAgICAvLyBGb3J3YXJkIGRpcmVjdGlvbjogY29udGludWUgd2l0aCBkZWZhdWx0IGhhbmRsaW5nXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGRlZi5pbm5lclR5cGUuX3pvZC5ydW4ocGF5bG9hZCwgY3R4KTtcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQudGhlbigocmVzdWx0KT0+aGFuZGxlRGVmYXVsdFJlc3VsdChyZXN1bHQsIGRlZikpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBoYW5kbGVEZWZhdWx0UmVzdWx0KHJlc3VsdCwgZGVmKTtcbiAgICB9O1xufSk7XG5mdW5jdGlvbiBoYW5kbGVEZWZhdWx0UmVzdWx0KHBheWxvYWQsIGRlZikge1xuICAgIGlmIChwYXlsb2FkLnZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcGF5bG9hZC52YWx1ZSA9IGRlZi5kZWZhdWx0VmFsdWU7XG4gICAgfVxuICAgIHJldHVybiBwYXlsb2FkO1xufVxuZXhwb3J0IGNvbnN0ICRab2RQcmVmYXVsdCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kUHJlZmF1bHRcIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5fem9kLm9wdGluID0gXCJvcHRpb25hbFwiO1xuICAgIHV0aWwuZGVmaW5lTGF6eShpbnN0Ll96b2QsIFwidmFsdWVzXCIsICgpPT5kZWYuaW5uZXJUeXBlLl96b2QudmFsdWVzKTtcbiAgICBpbnN0Ll96b2QucGFyc2UgPSAocGF5bG9hZCwgY3R4KT0+e1xuICAgICAgICBpZiAoY3R4LmRpcmVjdGlvbiA9PT0gXCJiYWNrd2FyZFwiKSB7XG4gICAgICAgICAgICByZXR1cm4gZGVmLmlubmVyVHlwZS5fem9kLnJ1bihwYXlsb2FkLCBjdHgpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEZvcndhcmQgZGlyZWN0aW9uIChkZWNvZGUpOiBhcHBseSBwcmVmYXVsdCBmb3IgdW5kZWZpbmVkIGlucHV0XG4gICAgICAgIGlmIChwYXlsb2FkLnZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHBheWxvYWQudmFsdWUgPSBkZWYuZGVmYXVsdFZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkZWYuaW5uZXJUeXBlLl96b2QucnVuKHBheWxvYWQsIGN0eCk7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2ROb25PcHRpb25hbCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kTm9uT3B0aW9uYWxcIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgdXRpbC5kZWZpbmVMYXp5KGluc3QuX3pvZCwgXCJ2YWx1ZXNcIiwgKCk9PntcbiAgICAgICAgY29uc3QgdiA9IGRlZi5pbm5lclR5cGUuX3pvZC52YWx1ZXM7XG4gICAgICAgIHJldHVybiB2ID8gbmV3IFNldChbXG4gICAgICAgICAgICAuLi52XG4gICAgICAgIF0uZmlsdGVyKCh4KT0+eCAhPT0gdW5kZWZpbmVkKSkgOiB1bmRlZmluZWQ7XG4gICAgfSk7XG4gICAgaW5zdC5fem9kLnBhcnNlID0gKHBheWxvYWQsIGN0eCk9PntcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gZGVmLmlubmVyVHlwZS5fem9kLnJ1bihwYXlsb2FkLCBjdHgpO1xuICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC50aGVuKChyZXN1bHQpPT5oYW5kbGVOb25PcHRpb25hbFJlc3VsdChyZXN1bHQsIGluc3QpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaGFuZGxlTm9uT3B0aW9uYWxSZXN1bHQocmVzdWx0LCBpbnN0KTtcbiAgICB9O1xufSk7XG5mdW5jdGlvbiBoYW5kbGVOb25PcHRpb25hbFJlc3VsdChwYXlsb2FkLCBpbnN0KSB7XG4gICAgaWYgKCFwYXlsb2FkLmlzc3Vlcy5sZW5ndGggJiYgcGF5bG9hZC52YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX3R5cGVcIixcbiAgICAgICAgICAgIGV4cGVjdGVkOiBcIm5vbm9wdGlvbmFsXCIsXG4gICAgICAgICAgICBpbnB1dDogcGF5bG9hZC52YWx1ZSxcbiAgICAgICAgICAgIGluc3RcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBwYXlsb2FkO1xufVxuZXhwb3J0IGNvbnN0ICRab2RTdWNjZXNzID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RTdWNjZXNzXCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkLCBjdHgpPT57XG4gICAgICAgIGlmIChjdHguZGlyZWN0aW9uID09PSBcImJhY2t3YXJkXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBjb3JlLiRab2RFbmNvZGVFcnJvcihcIlpvZFN1Y2Nlc3NcIik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gZGVmLmlubmVyVHlwZS5fem9kLnJ1bihwYXlsb2FkLCBjdHgpO1xuICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC50aGVuKChyZXN1bHQpPT57XG4gICAgICAgICAgICAgICAgcGF5bG9hZC52YWx1ZSA9IHJlc3VsdC5pc3N1ZXMubGVuZ3RoID09PSAwO1xuICAgICAgICAgICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcGF5bG9hZC52YWx1ZSA9IHJlc3VsdC5pc3N1ZXMubGVuZ3RoID09PSAwO1xuICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZENhdGNoID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RDYXRjaFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICB1dGlsLmRlZmluZUxhenkoaW5zdC5fem9kLCBcIm9wdGluXCIsICgpPT5kZWYuaW5uZXJUeXBlLl96b2Qub3B0aW4pO1xuICAgIHV0aWwuZGVmaW5lTGF6eShpbnN0Ll96b2QsIFwib3B0b3V0XCIsICgpPT5kZWYuaW5uZXJUeXBlLl96b2Qub3B0b3V0KTtcbiAgICB1dGlsLmRlZmluZUxhenkoaW5zdC5fem9kLCBcInZhbHVlc1wiLCAoKT0+ZGVmLmlubmVyVHlwZS5fem9kLnZhbHVlcyk7XG4gICAgaW5zdC5fem9kLnBhcnNlID0gKHBheWxvYWQsIGN0eCk9PntcbiAgICAgICAgaWYgKGN0eC5kaXJlY3Rpb24gPT09IFwiYmFja3dhcmRcIikge1xuICAgICAgICAgICAgcmV0dXJuIGRlZi5pbm5lclR5cGUuX3pvZC5ydW4ocGF5bG9hZCwgY3R4KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBGb3J3YXJkIGRpcmVjdGlvbiAoZGVjb2RlKTogYXBwbHkgY2F0Y2ggbG9naWNcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gZGVmLmlubmVyVHlwZS5fem9kLnJ1bihwYXlsb2FkLCBjdHgpO1xuICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC50aGVuKChyZXN1bHQpPT57XG4gICAgICAgICAgICAgICAgcGF5bG9hZC52YWx1ZSA9IHJlc3VsdC52YWx1ZTtcbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0Lmlzc3Vlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgcGF5bG9hZC52YWx1ZSA9IGRlZi5jYXRjaFZhbHVlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC4uLnBheWxvYWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvcjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzc3VlczogcmVzdWx0Lmlzc3Vlcy5tYXAoKGlzcyk9PnV0aWwuZmluYWxpemVJc3N1ZShpc3MsIGN0eCwgY29yZS5jb25maWcoKSkpXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQ6IHBheWxvYWQudmFsdWVcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHBheWxvYWQuaXNzdWVzID0gW107XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcGF5bG9hZC52YWx1ZSA9IHJlc3VsdC52YWx1ZTtcbiAgICAgICAgaWYgKHJlc3VsdC5pc3N1ZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICBwYXlsb2FkLnZhbHVlID0gZGVmLmNhdGNoVmFsdWUoe1xuICAgICAgICAgICAgICAgIC4uLnBheWxvYWQsXG4gICAgICAgICAgICAgICAgZXJyb3I6IHtcbiAgICAgICAgICAgICAgICAgICAgaXNzdWVzOiByZXN1bHQuaXNzdWVzLm1hcCgoaXNzKT0+dXRpbC5maW5hbGl6ZUlzc3VlKGlzcywgY3R4LCBjb3JlLmNvbmZpZygpKSlcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGlucHV0OiBwYXlsb2FkLnZhbHVlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHBheWxvYWQuaXNzdWVzID0gW107XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGNvbnN0ICRab2ROYU4gPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZE5hTlwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0Ll96b2QucGFyc2UgPSAocGF5bG9hZCwgX2N0eCk9PntcbiAgICAgICAgaWYgKHR5cGVvZiBwYXlsb2FkLnZhbHVlICE9PSBcIm51bWJlclwiIHx8ICFOdW1iZXIuaXNOYU4ocGF5bG9hZC52YWx1ZSkpIHtcbiAgICAgICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgICAgIGlucHV0OiBwYXlsb2FkLnZhbHVlLFxuICAgICAgICAgICAgICAgIGluc3QsXG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IFwibmFuXCIsXG4gICAgICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX3R5cGVcIlxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZFBpcGUgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZFBpcGVcIiwgKGluc3QsIGRlZik9PntcbiAgICAkWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgdXRpbC5kZWZpbmVMYXp5KGluc3QuX3pvZCwgXCJ2YWx1ZXNcIiwgKCk9PmRlZi5pbi5fem9kLnZhbHVlcyk7XG4gICAgdXRpbC5kZWZpbmVMYXp5KGluc3QuX3pvZCwgXCJvcHRpblwiLCAoKT0+ZGVmLmluLl96b2Qub3B0aW4pO1xuICAgIHV0aWwuZGVmaW5lTGF6eShpbnN0Ll96b2QsIFwib3B0b3V0XCIsICgpPT5kZWYub3V0Ll96b2Qub3B0b3V0KTtcbiAgICB1dGlsLmRlZmluZUxhenkoaW5zdC5fem9kLCBcInByb3BWYWx1ZXNcIiwgKCk9PmRlZi5pbi5fem9kLnByb3BWYWx1ZXMpO1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkLCBjdHgpPT57XG4gICAgICAgIGlmIChjdHguZGlyZWN0aW9uID09PSBcImJhY2t3YXJkXCIpIHtcbiAgICAgICAgICAgIGNvbnN0IHJpZ2h0ID0gZGVmLm91dC5fem9kLnJ1bihwYXlsb2FkLCBjdHgpO1xuICAgICAgICAgICAgaWYgKHJpZ2h0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiByaWdodC50aGVuKChyaWdodCk9PmhhbmRsZVBpcGVSZXN1bHQocmlnaHQsIGRlZi5pbiwgY3R4KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gaGFuZGxlUGlwZVJlc3VsdChyaWdodCwgZGVmLmluLCBjdHgpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGxlZnQgPSBkZWYuaW4uX3pvZC5ydW4ocGF5bG9hZCwgY3R4KTtcbiAgICAgICAgaWYgKGxlZnQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm4gbGVmdC50aGVuKChsZWZ0KT0+aGFuZGxlUGlwZVJlc3VsdChsZWZ0LCBkZWYub3V0LCBjdHgpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaGFuZGxlUGlwZVJlc3VsdChsZWZ0LCBkZWYub3V0LCBjdHgpO1xuICAgIH07XG59KTtcbmZ1bmN0aW9uIGhhbmRsZVBpcGVSZXN1bHQobGVmdCwgbmV4dCwgY3R4KSB7XG4gICAgaWYgKGxlZnQuaXNzdWVzLmxlbmd0aCkge1xuICAgICAgICAvLyBwcmV2ZW50IGZ1cnRoZXIgY2hlY2tzXG4gICAgICAgIGxlZnQuYWJvcnRlZCA9IHRydWU7XG4gICAgICAgIHJldHVybiBsZWZ0O1xuICAgIH1cbiAgICByZXR1cm4gbmV4dC5fem9kLnJ1bih7XG4gICAgICAgIHZhbHVlOiBsZWZ0LnZhbHVlLFxuICAgICAgICBpc3N1ZXM6IGxlZnQuaXNzdWVzXG4gICAgfSwgY3R4KTtcbn1cbmV4cG9ydCBjb25zdCAkWm9kQ29kZWMgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZENvZGVjXCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIHV0aWwuZGVmaW5lTGF6eShpbnN0Ll96b2QsIFwidmFsdWVzXCIsICgpPT5kZWYuaW4uX3pvZC52YWx1ZXMpO1xuICAgIHV0aWwuZGVmaW5lTGF6eShpbnN0Ll96b2QsIFwib3B0aW5cIiwgKCk9PmRlZi5pbi5fem9kLm9wdGluKTtcbiAgICB1dGlsLmRlZmluZUxhenkoaW5zdC5fem9kLCBcIm9wdG91dFwiLCAoKT0+ZGVmLm91dC5fem9kLm9wdG91dCk7XG4gICAgdXRpbC5kZWZpbmVMYXp5KGluc3QuX3pvZCwgXCJwcm9wVmFsdWVzXCIsICgpPT5kZWYuaW4uX3pvZC5wcm9wVmFsdWVzKTtcbiAgICBpbnN0Ll96b2QucGFyc2UgPSAocGF5bG9hZCwgY3R4KT0+e1xuICAgICAgICBjb25zdCBkaXJlY3Rpb24gPSBjdHguZGlyZWN0aW9uIHx8IFwiZm9yd2FyZFwiO1xuICAgICAgICBpZiAoZGlyZWN0aW9uID09PSBcImZvcndhcmRcIikge1xuICAgICAgICAgICAgY29uc3QgbGVmdCA9IGRlZi5pbi5fem9kLnJ1bihwYXlsb2FkLCBjdHgpO1xuICAgICAgICAgICAgaWYgKGxlZnQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGxlZnQudGhlbigobGVmdCk9PmhhbmRsZUNvZGVjQVJlc3VsdChsZWZ0LCBkZWYsIGN0eCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGhhbmRsZUNvZGVjQVJlc3VsdChsZWZ0LCBkZWYsIGN0eCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCByaWdodCA9IGRlZi5vdXQuX3pvZC5ydW4ocGF5bG9hZCwgY3R4KTtcbiAgICAgICAgICAgIGlmIChyaWdodCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmlnaHQudGhlbigocmlnaHQpPT5oYW5kbGVDb2RlY0FSZXN1bHQocmlnaHQsIGRlZiwgY3R4KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gaGFuZGxlQ29kZWNBUmVzdWx0KHJpZ2h0LCBkZWYsIGN0eCk7XG4gICAgICAgIH1cbiAgICB9O1xufSk7XG5mdW5jdGlvbiBoYW5kbGVDb2RlY0FSZXN1bHQocmVzdWx0LCBkZWYsIGN0eCkge1xuICAgIGlmIChyZXN1bHQuaXNzdWVzLmxlbmd0aCkge1xuICAgICAgICAvLyBwcmV2ZW50IGZ1cnRoZXIgY2hlY2tzXG4gICAgICAgIHJlc3VsdC5hYm9ydGVkID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgY29uc3QgZGlyZWN0aW9uID0gY3R4LmRpcmVjdGlvbiB8fCBcImZvcndhcmRcIjtcbiAgICBpZiAoZGlyZWN0aW9uID09PSBcImZvcndhcmRcIikge1xuICAgICAgICBjb25zdCB0cmFuc2Zvcm1lZCA9IGRlZi50cmFuc2Zvcm0ocmVzdWx0LnZhbHVlLCByZXN1bHQpO1xuICAgICAgICBpZiAodHJhbnNmb3JtZWQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJhbnNmb3JtZWQudGhlbigodmFsdWUpPT5oYW5kbGVDb2RlY1R4UmVzdWx0KHJlc3VsdCwgdmFsdWUsIGRlZi5vdXQsIGN0eCkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBoYW5kbGVDb2RlY1R4UmVzdWx0KHJlc3VsdCwgdHJhbnNmb3JtZWQsIGRlZi5vdXQsIGN0eCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgdHJhbnNmb3JtZWQgPSBkZWYucmV2ZXJzZVRyYW5zZm9ybShyZXN1bHQudmFsdWUsIHJlc3VsdCk7XG4gICAgICAgIGlmICh0cmFuc2Zvcm1lZCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybiB0cmFuc2Zvcm1lZC50aGVuKCh2YWx1ZSk9PmhhbmRsZUNvZGVjVHhSZXN1bHQocmVzdWx0LCB2YWx1ZSwgZGVmLmluLCBjdHgpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaGFuZGxlQ29kZWNUeFJlc3VsdChyZXN1bHQsIHRyYW5zZm9ybWVkLCBkZWYuaW4sIGN0eCk7XG4gICAgfVxufVxuZnVuY3Rpb24gaGFuZGxlQ29kZWNUeFJlc3VsdChsZWZ0LCB2YWx1ZSwgbmV4dFNjaGVtYSwgY3R4KSB7XG4gICAgLy8gQ2hlY2sgaWYgdHJhbnNmb3JtIGFkZGVkIGFueSBpc3N1ZXNcbiAgICBpZiAobGVmdC5pc3N1ZXMubGVuZ3RoKSB7XG4gICAgICAgIGxlZnQuYWJvcnRlZCA9IHRydWU7XG4gICAgICAgIHJldHVybiBsZWZ0O1xuICAgIH1cbiAgICByZXR1cm4gbmV4dFNjaGVtYS5fem9kLnJ1bih7XG4gICAgICAgIHZhbHVlLFxuICAgICAgICBpc3N1ZXM6IGxlZnQuaXNzdWVzXG4gICAgfSwgY3R4KTtcbn1cbmV4cG9ydCBjb25zdCAkWm9kUmVhZG9ubHkgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZFJlYWRvbmx5XCIsIChpbnN0LCBkZWYpPT57XG4gICAgJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIHV0aWwuZGVmaW5lTGF6eShpbnN0Ll96b2QsIFwicHJvcFZhbHVlc1wiLCAoKT0+ZGVmLmlubmVyVHlwZS5fem9kLnByb3BWYWx1ZXMpO1xuICAgIHV0aWwuZGVmaW5lTGF6eShpbnN0Ll96b2QsIFwidmFsdWVzXCIsICgpPT5kZWYuaW5uZXJUeXBlLl96b2QudmFsdWVzKTtcbiAgICB1dGlsLmRlZmluZUxhenkoaW5zdC5fem9kLCBcIm9wdGluXCIsICgpPT5kZWYuaW5uZXJUeXBlLl96b2Qub3B0aW4pO1xuICAgIHV0aWwuZGVmaW5lTGF6eShpbnN0Ll96b2QsIFwib3B0b3V0XCIsICgpPT5kZWYuaW5uZXJUeXBlLl96b2Qub3B0b3V0KTtcbiAgICBpbnN0Ll96b2QucGFyc2UgPSAocGF5bG9hZCwgY3R4KT0+e1xuICAgICAgICBpZiAoY3R4LmRpcmVjdGlvbiA9PT0gXCJiYWNrd2FyZFwiKSB7XG4gICAgICAgICAgICByZXR1cm4gZGVmLmlubmVyVHlwZS5fem9kLnJ1bihwYXlsb2FkLCBjdHgpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGRlZi5pbm5lclR5cGUuX3pvZC5ydW4ocGF5bG9hZCwgY3R4KTtcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQudGhlbihoYW5kbGVSZWFkb25seVJlc3VsdCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGhhbmRsZVJlYWRvbmx5UmVzdWx0KHJlc3VsdCk7XG4gICAgfTtcbn0pO1xuZnVuY3Rpb24gaGFuZGxlUmVhZG9ubHlSZXN1bHQocGF5bG9hZCkge1xuICAgIHBheWxvYWQudmFsdWUgPSBPYmplY3QuZnJlZXplKHBheWxvYWQudmFsdWUpO1xuICAgIHJldHVybiBwYXlsb2FkO1xufVxuZXhwb3J0IGNvbnN0ICRab2RUZW1wbGF0ZUxpdGVyYWwgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiJFpvZFRlbXBsYXRlTGl0ZXJhbFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBjb25zdCByZWdleFBhcnRzID0gW107XG4gICAgZm9yIChjb25zdCBwYXJ0IG9mIGRlZi5wYXJ0cyl7XG4gICAgICAgIGlmICh0eXBlb2YgcGFydCA9PT0gXCJvYmplY3RcIiAmJiBwYXJ0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAvLyBpcyBab2Qgc2NoZW1hXG4gICAgICAgICAgICBpZiAoIXBhcnQuX3pvZC5wYXR0ZXJuKSB7XG4gICAgICAgICAgICAgICAgLy8gaWYgKCFzb3VyY2UpXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHRlbXBsYXRlIGxpdGVyYWwgcGFydCwgbm8gcGF0dGVybiBmb3VuZDogJHtbXG4gICAgICAgICAgICAgICAgICAgIC4uLnBhcnQuX3pvZC50cmFpdHNcbiAgICAgICAgICAgICAgICBdLnNoaWZ0KCl9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBzb3VyY2UgPSBwYXJ0Ll96b2QucGF0dGVybiBpbnN0YW5jZW9mIFJlZ0V4cCA/IHBhcnQuX3pvZC5wYXR0ZXJuLnNvdXJjZSA6IHBhcnQuX3pvZC5wYXR0ZXJuO1xuICAgICAgICAgICAgaWYgKCFzb3VyY2UpIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCB0ZW1wbGF0ZSBsaXRlcmFsIHBhcnQ6ICR7cGFydC5fem9kLnRyYWl0c31gKTtcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0ID0gc291cmNlLnN0YXJ0c1dpdGgoXCJeXCIpID8gMSA6IDA7XG4gICAgICAgICAgICBjb25zdCBlbmQgPSBzb3VyY2UuZW5kc1dpdGgoXCIkXCIpID8gc291cmNlLmxlbmd0aCAtIDEgOiBzb3VyY2UubGVuZ3RoO1xuICAgICAgICAgICAgcmVnZXhQYXJ0cy5wdXNoKHNvdXJjZS5zbGljZShzdGFydCwgZW5kKSk7XG4gICAgICAgIH0gZWxzZSBpZiAocGFydCA9PT0gbnVsbCB8fCB1dGlsLnByaW1pdGl2ZVR5cGVzLmhhcyh0eXBlb2YgcGFydCkpIHtcbiAgICAgICAgICAgIHJlZ2V4UGFydHMucHVzaCh1dGlsLmVzY2FwZVJlZ2V4KGAke3BhcnR9YCkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHRlbXBsYXRlIGxpdGVyYWwgcGFydDogJHtwYXJ0fWApO1xuICAgICAgICB9XG4gICAgfVxuICAgIGluc3QuX3pvZC5wYXR0ZXJuID0gbmV3IFJlZ0V4cChgXiR7cmVnZXhQYXJ0cy5qb2luKFwiXCIpfSRgKTtcbiAgICBpbnN0Ll96b2QucGFyc2UgPSAocGF5bG9hZCwgX2N0eCk9PntcbiAgICAgICAgaWYgKHR5cGVvZiBwYXlsb2FkLnZhbHVlICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICBpbnB1dDogcGF5bG9hZC52YWx1ZSxcbiAgICAgICAgICAgICAgICBpbnN0LFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBcInRlbXBsYXRlX2xpdGVyYWxcIixcbiAgICAgICAgICAgICAgICBjb2RlOiBcImludmFsaWRfdHlwZVwiXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgICAgICB9XG4gICAgICAgIGluc3QuX3pvZC5wYXR0ZXJuLmxhc3RJbmRleCA9IDA7XG4gICAgICAgIGlmICghaW5zdC5fem9kLnBhdHRlcm4udGVzdChwYXlsb2FkLnZhbHVlKSkge1xuICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgaW5wdXQ6IHBheWxvYWQudmFsdWUsXG4gICAgICAgICAgICAgICAgaW5zdCxcbiAgICAgICAgICAgICAgICBjb2RlOiBcImludmFsaWRfZm9ybWF0XCIsXG4gICAgICAgICAgICAgICAgZm9ybWF0OiBkZWYuZm9ybWF0ID8/IFwidGVtcGxhdGVfbGl0ZXJhbFwiLFxuICAgICAgICAgICAgICAgIHBhdHRlcm46IGluc3QuX3pvZC5wYXR0ZXJuLnNvdXJjZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZEZ1bmN0aW9uID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIiRab2RGdW5jdGlvblwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0Ll9kZWYgPSBkZWY7XG4gICAgaW5zdC5fem9kLmRlZiA9IGRlZjtcbiAgICBpbnN0LmltcGxlbWVudCA9IChmdW5jKT0+e1xuICAgICAgICBpZiAodHlwZW9mIGZ1bmMgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiaW1wbGVtZW50KCkgbXVzdCBiZSBjYWxsZWQgd2l0aCBhIGZ1bmN0aW9uXCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiguLi5hcmdzKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJzZWRBcmdzID0gaW5zdC5fZGVmLmlucHV0ID8gcGFyc2UoaW5zdC5fZGVmLmlucHV0LCBhcmdzKSA6IGFyZ3M7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBSZWZsZWN0LmFwcGx5KGZ1bmMsIHRoaXMsIHBhcnNlZEFyZ3MpO1xuICAgICAgICAgICAgaWYgKGluc3QuX2RlZi5vdXRwdXQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2UoaW5zdC5fZGVmLm91dHB1dCwgcmVzdWx0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH07XG4gICAgfTtcbiAgICBpbnN0LmltcGxlbWVudEFzeW5jID0gKGZ1bmMpPT57XG4gICAgICAgIGlmICh0eXBlb2YgZnVuYyAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJpbXBsZW1lbnRBc3luYygpIG11c3QgYmUgY2FsbGVkIHdpdGggYSBmdW5jdGlvblwiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYXN5bmMgZnVuY3Rpb24oLi4uYXJncykge1xuICAgICAgICAgICAgY29uc3QgcGFyc2VkQXJncyA9IGluc3QuX2RlZi5pbnB1dCA/IGF3YWl0IHBhcnNlQXN5bmMoaW5zdC5fZGVmLmlucHV0LCBhcmdzKSA6IGFyZ3M7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBSZWZsZWN0LmFwcGx5KGZ1bmMsIHRoaXMsIHBhcnNlZEFyZ3MpO1xuICAgICAgICAgICAgaWYgKGluc3QuX2RlZi5vdXRwdXQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXdhaXQgcGFyc2VBc3luYyhpbnN0Ll9kZWYub3V0cHV0LCByZXN1bHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkLCBfY3R4KT0+e1xuICAgICAgICBpZiAodHlwZW9mIHBheWxvYWQudmFsdWUgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgY29kZTogXCJpbnZhbGlkX3R5cGVcIixcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogXCJmdW5jdGlvblwiLFxuICAgICAgICAgICAgICAgIGlucHV0OiBwYXlsb2FkLnZhbHVlLFxuICAgICAgICAgICAgICAgIGluc3RcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQ2hlY2sgaWYgb3V0cHV0IGlzIGEgcHJvbWlzZSB0eXBlIHRvIGRldGVybWluZSBpZiB3ZSBzaG91bGQgdXNlIGFzeW5jIGltcGxlbWVudGF0aW9uXG4gICAgICAgIGNvbnN0IGhhc1Byb21pc2VPdXRwdXQgPSBpbnN0Ll9kZWYub3V0cHV0ICYmIGluc3QuX2RlZi5vdXRwdXQuX3pvZC5kZWYudHlwZSA9PT0gXCJwcm9taXNlXCI7XG4gICAgICAgIGlmIChoYXNQcm9taXNlT3V0cHV0KSB7XG4gICAgICAgICAgICBwYXlsb2FkLnZhbHVlID0gaW5zdC5pbXBsZW1lbnRBc3luYyhwYXlsb2FkLnZhbHVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBheWxvYWQudmFsdWUgPSBpbnN0LmltcGxlbWVudChwYXlsb2FkLnZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICB9O1xuICAgIGluc3QuaW5wdXQgPSAoLi4uYXJncyk9PntcbiAgICAgICAgY29uc3QgRiA9IGluc3QuY29uc3RydWN0b3I7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGFyZ3NbMF0pKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEYoe1xuICAgICAgICAgICAgICAgIHR5cGU6IFwiZnVuY3Rpb25cIixcbiAgICAgICAgICAgICAgICBpbnB1dDogbmV3ICRab2RUdXBsZSh7XG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IFwidHVwbGVcIixcbiAgICAgICAgICAgICAgICAgICAgaXRlbXM6IGFyZ3NbMF0sXG4gICAgICAgICAgICAgICAgICAgIHJlc3Q6IGFyZ3NbMV1cbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICBvdXRwdXQ6IGluc3QuX2RlZi5vdXRwdXRcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgRih7XG4gICAgICAgICAgICB0eXBlOiBcImZ1bmN0aW9uXCIsXG4gICAgICAgICAgICBpbnB1dDogYXJnc1swXSxcbiAgICAgICAgICAgIG91dHB1dDogaW5zdC5fZGVmLm91dHB1dFxuICAgICAgICB9KTtcbiAgICB9O1xuICAgIGluc3Qub3V0cHV0ID0gKG91dHB1dCk9PntcbiAgICAgICAgY29uc3QgRiA9IGluc3QuY29uc3RydWN0b3I7XG4gICAgICAgIHJldHVybiBuZXcgRih7XG4gICAgICAgICAgICB0eXBlOiBcImZ1bmN0aW9uXCIsXG4gICAgICAgICAgICBpbnB1dDogaW5zdC5fZGVmLmlucHV0LFxuICAgICAgICAgICAgb3V0cHV0XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgcmV0dXJuIGluc3Q7XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kUHJvbWlzZSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kUHJvbWlzZVwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0Ll96b2QucGFyc2UgPSAocGF5bG9hZCwgY3R4KT0+e1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHBheWxvYWQudmFsdWUpLnRoZW4oKGlubmVyKT0+ZGVmLmlubmVyVHlwZS5fem9kLnJ1bih7XG4gICAgICAgICAgICAgICAgdmFsdWU6IGlubmVyLFxuICAgICAgICAgICAgICAgIGlzc3VlczogW11cbiAgICAgICAgICAgIH0sIGN0eCkpO1xuICAgIH07XG59KTtcbmV4cG9ydCBjb25zdCAkWm9kTGF6eSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kTGF6eVwiLCAoaW5zdCwgZGVmKT0+e1xuICAgICRab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICAvLyBsZXQgX2lubmVyVHlwZSE6IGFueTtcbiAgICAvLyB1dGlsLmRlZmluZUxhenkoZGVmLCBcImdldHRlclwiLCAoKSA9PiB7XG4gICAgLy8gICBpZiAoIV9pbm5lclR5cGUpIHtcbiAgICAvLyAgICAgX2lubmVyVHlwZSA9IGRlZi5nZXR0ZXIoKTtcbiAgICAvLyAgIH1cbiAgICAvLyAgIHJldHVybiAoKSA9PiBfaW5uZXJUeXBlO1xuICAgIC8vIH0pO1xuICAgIHV0aWwuZGVmaW5lTGF6eShpbnN0Ll96b2QsIFwiaW5uZXJUeXBlXCIsICgpPT5kZWYuZ2V0dGVyKCkpO1xuICAgIHV0aWwuZGVmaW5lTGF6eShpbnN0Ll96b2QsIFwicGF0dGVyblwiLCAoKT0+aW5zdC5fem9kLmlubmVyVHlwZS5fem9kLnBhdHRlcm4pO1xuICAgIHV0aWwuZGVmaW5lTGF6eShpbnN0Ll96b2QsIFwicHJvcFZhbHVlc1wiLCAoKT0+aW5zdC5fem9kLmlubmVyVHlwZS5fem9kLnByb3BWYWx1ZXMpO1xuICAgIHV0aWwuZGVmaW5lTGF6eShpbnN0Ll96b2QsIFwib3B0aW5cIiwgKCk9Pmluc3QuX3pvZC5pbm5lclR5cGUuX3pvZC5vcHRpbiA/PyB1bmRlZmluZWQpO1xuICAgIHV0aWwuZGVmaW5lTGF6eShpbnN0Ll96b2QsIFwib3B0b3V0XCIsICgpPT5pbnN0Ll96b2QuaW5uZXJUeXBlLl96b2Qub3B0b3V0ID8/IHVuZGVmaW5lZCk7XG4gICAgaW5zdC5fem9kLnBhcnNlID0gKHBheWxvYWQsIGN0eCk9PntcbiAgICAgICAgY29uc3QgaW5uZXIgPSBpbnN0Ll96b2QuaW5uZXJUeXBlO1xuICAgICAgICByZXR1cm4gaW5uZXIuX3pvZC5ydW4ocGF5bG9hZCwgY3R4KTtcbiAgICB9O1xufSk7XG5leHBvcnQgY29uc3QgJFpvZEN1c3RvbSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCIkWm9kQ3VzdG9tXCIsIChpbnN0LCBkZWYpPT57XG4gICAgY2hlY2tzLiRab2RDaGVjay5pbml0KGluc3QsIGRlZik7XG4gICAgJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkLCBfKT0+e1xuICAgICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICB9O1xuICAgIGluc3QuX3pvZC5jaGVjayA9IChwYXlsb2FkKT0+e1xuICAgICAgICBjb25zdCBpbnB1dCA9IHBheWxvYWQudmFsdWU7XG4gICAgICAgIGNvbnN0IHIgPSBkZWYuZm4oaW5wdXQpO1xuICAgICAgICBpZiAociBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybiByLnRoZW4oKHIpPT5oYW5kbGVSZWZpbmVSZXN1bHQociwgcGF5bG9hZCwgaW5wdXQsIGluc3QpKTtcbiAgICAgICAgfVxuICAgICAgICBoYW5kbGVSZWZpbmVSZXN1bHQociwgcGF5bG9hZCwgaW5wdXQsIGluc3QpO1xuICAgICAgICByZXR1cm47XG4gICAgfTtcbn0pO1xuZnVuY3Rpb24gaGFuZGxlUmVmaW5lUmVzdWx0KHJlc3VsdCwgcGF5bG9hZCwgaW5wdXQsIGluc3QpIHtcbiAgICBpZiAoIXJlc3VsdCkge1xuICAgICAgICBjb25zdCBfaXNzID0ge1xuICAgICAgICAgICAgY29kZTogXCJjdXN0b21cIixcbiAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgaW5zdCxcbiAgICAgICAgICAgIHBhdGg6IFtcbiAgICAgICAgICAgICAgICAuLi5pbnN0Ll96b2QuZGVmLnBhdGggPz8gW11cbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBjb250aW51ZTogIWluc3QuX3pvZC5kZWYuYWJvcnRcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKGluc3QuX3pvZC5kZWYucGFyYW1zKSBfaXNzLnBhcmFtcyA9IGluc3QuX3pvZC5kZWYucGFyYW1zO1xuICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHV0aWwuaXNzdWUoX2lzcykpO1xuICAgIH1cbn1cbiIsICJleHBvcnQgeyBkZWZhdWx0IGFzIGFyIH0gZnJvbSBcIi4vYXIuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgYXogfSBmcm9tIFwiLi9hei5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBiZSB9IGZyb20gXCIuL2JlLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGNhIH0gZnJvbSBcIi4vY2EuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgY3MgfSBmcm9tIFwiLi9jcy5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBkYSB9IGZyb20gXCIuL2RhLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGRlIH0gZnJvbSBcIi4vZGUuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgZW4gfSBmcm9tIFwiLi9lbi5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBlbyB9IGZyb20gXCIuL2VvLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGVzIH0gZnJvbSBcIi4vZXMuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgZmEgfSBmcm9tIFwiLi9mYS5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBmaSB9IGZyb20gXCIuL2ZpLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGZyIH0gZnJvbSBcIi4vZnIuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgZnJDQSB9IGZyb20gXCIuL2ZyLUNBLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGhlIH0gZnJvbSBcIi4vaGUuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgaHUgfSBmcm9tIFwiLi9odS5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBpZCB9IGZyb20gXCIuL2lkLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGlzIH0gZnJvbSBcIi4vaXMuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgaXQgfSBmcm9tIFwiLi9pdC5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBqYSB9IGZyb20gXCIuL2phLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGthIH0gZnJvbSBcIi4va2EuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMga2ggfSBmcm9tIFwiLi9raC5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBrbSB9IGZyb20gXCIuL2ttLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGtvIH0gZnJvbSBcIi4va28uanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgbHQgfSBmcm9tIFwiLi9sdC5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBtayB9IGZyb20gXCIuL21rLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIG1zIH0gZnJvbSBcIi4vbXMuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgbmwgfSBmcm9tIFwiLi9ubC5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBubyB9IGZyb20gXCIuL25vLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIG90YSB9IGZyb20gXCIuL290YS5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBwcyB9IGZyb20gXCIuL3BzLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIHBsIH0gZnJvbSBcIi4vcGwuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgcHQgfSBmcm9tIFwiLi9wdC5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBydSB9IGZyb20gXCIuL3J1LmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIHNsIH0gZnJvbSBcIi4vc2wuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgc3YgfSBmcm9tIFwiLi9zdi5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyB0YSB9IGZyb20gXCIuL3RhLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIHRoIH0gZnJvbSBcIi4vdGguanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgdHIgfSBmcm9tIFwiLi90ci5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyB1YSB9IGZyb20gXCIuL3VhLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIHVrIH0gZnJvbSBcIi4vdWsuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgdXIgfSBmcm9tIFwiLi91ci5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyB2aSB9IGZyb20gXCIuL3ZpLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIHpoQ04gfSBmcm9tIFwiLi96aC1DTi5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyB6aFRXIH0gZnJvbSBcIi4vemgtVFcuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgeW8gfSBmcm9tIFwiLi95by5qc1wiO1xuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJcdTA2MkRcdTA2MzFcdTA2NDFcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwNjIzXHUwNjQ2IFx1MDY0QVx1MDYyRFx1MDY0OFx1MDY0QVwiXG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHUwNjI4XHUwNjI3XHUwNjRBXHUwNjJBXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MDYyM1x1MDY0NiBcdTA2NEFcdTA2MkRcdTA2NDhcdTA2NEFcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJcdTA2MzlcdTA2NDZcdTA2MzVcdTA2MzFcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwNjIzXHUwNjQ2IFx1MDY0QVx1MDYyRFx1MDY0OFx1MDY0QVwiXG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDogXCJcdTA2MzlcdTA2NDZcdTA2MzVcdTA2MzFcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwNjIzXHUwNjQ2IFx1MDY0QVx1MDYyRFx1MDY0OFx1MDY0QVwiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4pIHtcbiAgICAgICAgcmV0dXJuIFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWRUeXBlID0gKGRhdGEpPT57XG4gICAgICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICAgICAgc3dpdGNoKHQpe1xuICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIm51bWJlclwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJhcnJheVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJudWxsXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcIlx1MDY0NVx1MDYyRlx1MDYyRVx1MDY0NFwiLFxuICAgICAgICBlbWFpbDogXCJcdTA2MjhcdTA2MzFcdTA2NEFcdTA2MkYgXHUwNjI1XHUwNjQ0XHUwNjQzXHUwNjJBXHUwNjMxXHUwNjQ4XHUwNjQ2XHUwNjRBXCIsXG4gICAgICAgIHVybDogXCJcdTA2MzFcdTA2MjdcdTA2MjhcdTA2MzdcIixcbiAgICAgICAgZW1vamk6IFwiXHUwNjI1XHUwNjRBXHUwNjQ1XHUwNjQ4XHUwNjJDXHUwNjRBXCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcIlx1MDYyQVx1MDYyN1x1MDYzMVx1MDY0QVx1MDYyRSBcdTA2NDhcdTA2NDhcdTA2NDJcdTA2MkEgXHUwNjI4XHUwNjQ1XHUwNjM5XHUwNjRBXHUwNjI3XHUwNjMxIElTT1wiLFxuICAgICAgICBkYXRlOiBcIlx1MDYyQVx1MDYyN1x1MDYzMVx1MDY0QVx1MDYyRSBcdTA2MjhcdTA2NDVcdTA2MzlcdTA2NEFcdTA2MjdcdTA2MzEgSVNPXCIsXG4gICAgICAgIHRpbWU6IFwiXHUwNjQ4XHUwNjQyXHUwNjJBIFx1MDYyOFx1MDY0NVx1MDYzOVx1MDY0QVx1MDYyN1x1MDYzMSBJU09cIixcbiAgICAgICAgZHVyYXRpb246IFwiXHUwNjQ1XHUwNjJGXHUwNjI5IFx1MDYyOFx1MDY0NVx1MDYzOVx1MDY0QVx1MDYyN1x1MDYzMSBJU09cIixcbiAgICAgICAgaXB2NDogXCJcdTA2MzlcdTA2NDZcdTA2NDhcdTA2MjdcdTA2NDYgSVB2NFwiLFxuICAgICAgICBpcHY2OiBcIlx1MDYzOVx1MDY0Nlx1MDY0OFx1MDYyN1x1MDY0NiBJUHY2XCIsXG4gICAgICAgIGNpZHJ2NDogXCJcdTA2NDVcdTA2MkZcdTA2NDkgXHUwNjM5XHUwNjQ2XHUwNjI3XHUwNjQ4XHUwNjRBXHUwNjQ2IFx1MDYyOFx1MDYzNVx1MDY0QVx1MDYzQVx1MDYyOSBJUHY0XCIsXG4gICAgICAgIGNpZHJ2NjogXCJcdTA2NDVcdTA2MkZcdTA2NDkgXHUwNjM5XHUwNjQ2XHUwNjI3XHUwNjQ4XHUwNjRBXHUwNjQ2IFx1MDYyOFx1MDYzNVx1MDY0QVx1MDYzQVx1MDYyOSBJUHY2XCIsXG4gICAgICAgIGJhc2U2NDogXCJcdTA2NDZcdTA2NEVcdTA2MzUgXHUwNjI4XHUwNjJBXHUwNjMxXHUwNjQ1XHUwNjRBXHUwNjMyIGJhc2U2NC1lbmNvZGVkXCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJcdTA2NDZcdTA2NEVcdTA2MzUgXHUwNjI4XHUwNjJBXHUwNjMxXHUwNjQ1XHUwNjRBXHUwNjMyIGJhc2U2NHVybC1lbmNvZGVkXCIsXG4gICAgICAgIGpzb25fc3RyaW5nOiBcIlx1MDY0Nlx1MDY0RVx1MDYzNSBcdTA2MzlcdTA2NDRcdTA2NDkgXHUwNjQ3XHUwNjRBXHUwNjI2XHUwNjI5IEpTT05cIixcbiAgICAgICAgZTE2NDogXCJcdTA2MzFcdTA2NDJcdTA2NDUgXHUwNjQ3XHUwNjI3XHUwNjJBXHUwNjQxIFx1MDYyOFx1MDY0NVx1MDYzOVx1MDY0QVx1MDYyN1x1MDYzMSBFLjE2NFwiLFxuICAgICAgICBqd3Q6IFwiSldUXCIsXG4gICAgICAgIHRlbXBsYXRlX2xpdGVyYWw6IFwiXHUwNjQ1XHUwNjJGXHUwNjJFXHUwNjQ0XCJcbiAgICB9O1xuICAgIHJldHVybiAoaXNzdWUpPT57XG4gICAgICAgIHN3aXRjaChpc3N1ZS5jb2RlKXtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3R5cGVcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDY0NVx1MDYyRlx1MDYyRVx1MDY0NFx1MDYyN1x1MDYyQSBcdTA2M0FcdTA2NEFcdTA2MzEgXHUwNjQ1XHUwNjQyXHUwNjI4XHUwNjQ4XHUwNjQ0XHUwNjI5OiBcdTA2NEFcdTA2NDFcdTA2MkFcdTA2MzFcdTA2MzYgXHUwNjI1XHUwNjJGXHUwNjJFXHUwNjI3XHUwNjQ0ICR7aXNzdWUuZXhwZWN0ZWR9XHUwNjBDIFx1MDY0OFx1MDY0NFx1MDY0M1x1MDY0NiBcdTA2MkFcdTA2NDUgXHUwNjI1XHUwNjJGXHUwNjJFXHUwNjI3XHUwNjQ0ICR7cGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgXHUwNjQ1XHUwNjJGXHUwNjJFXHUwNjQ0XHUwNjI3XHUwNjJBIFx1MDYzQVx1MDY0QVx1MDYzMSBcdTA2NDVcdTA2NDJcdTA2MjhcdTA2NDhcdTA2NDRcdTA2Mjk6IFx1MDY0QVx1MDY0MVx1MDYyQVx1MDYzMVx1MDYzNiBcdTA2MjVcdTA2MkZcdTA2MkVcdTA2MjdcdTA2NDQgJHt1dGlsLnN0cmluZ2lmeVByaW1pdGl2ZShpc3N1ZS52YWx1ZXNbMF0pfWA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2MjdcdTA2MkVcdTA2MkFcdTA2NEFcdTA2MjdcdTA2MzEgXHUwNjNBXHUwNjRBXHUwNjMxIFx1MDY0NVx1MDY0Mlx1MDYyOFx1MDY0OFx1MDY0NDogXHUwNjRBXHUwNjJBXHUwNjQ4XHUwNjQyXHUwNjM5IFx1MDYyN1x1MDY0Nlx1MDYyQVx1MDY0Mlx1MDYyN1x1MDYyMSBcdTA2MjNcdTA2MkRcdTA2MkYgXHUwNjQ3XHUwNjMwXHUwNjQ3IFx1MDYyN1x1MDY0NFx1MDYyRVx1MDY0QVx1MDYyN1x1MDYzMVx1MDYyN1x1MDYyQTogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIjw9XCIgOiBcIjxcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgIFx1MDYyM1x1MDY0M1x1MDYyOFx1MDYzMSBcdTA2NDVcdTA2NDYgXHUwNjI3XHUwNjQ0XHUwNjQ0XHUwNjI3XHUwNjMyXHUwNjQ1OiBcdTA2NEFcdTA2NDFcdTA2MkFcdTA2MzFcdTA2MzYgXHUwNjIzXHUwNjQ2IFx1MDYyQVx1MDY0M1x1MDY0OFx1MDY0NiAke2lzc3VlLm9yaWdpbiA/PyBcIlx1MDYyN1x1MDY0NFx1MDY0Mlx1MDY0QVx1MDY0NVx1MDYyOVwifSAke2Fkan0gJHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXQgPz8gXCJcdTA2MzlcdTA2NDZcdTA2MzVcdTA2MzFcIn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDYyM1x1MDY0M1x1MDYyOFx1MDYzMSBcdTA2NDVcdTA2NDYgXHUwNjI3XHUwNjQ0XHUwNjQ0XHUwNjI3XHUwNjMyXHUwNjQ1OiBcdTA2NEFcdTA2NDFcdTA2MkFcdTA2MzFcdTA2MzYgXHUwNjIzXHUwNjQ2IFx1MDYyQVx1MDY0M1x1MDY0OFx1MDY0NiAke2lzc3VlLm9yaWdpbiA/PyBcIlx1MDYyN1x1MDY0NFx1MDY0Mlx1MDY0QVx1MDY0NVx1MDYyOVwifSAke2Fkan0gJHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIj49XCIgOiBcIj5cIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjIzXHUwNjM1XHUwNjNBXHUwNjMxIFx1MDY0NVx1MDY0NiBcdTA2MjdcdTA2NDRcdTA2NDRcdTA2MjdcdTA2MzJcdTA2NDU6IFx1MDY0QVx1MDY0MVx1MDYyQVx1MDYzMVx1MDYzNiBcdTA2NDRcdTA2NDAgJHtpc3N1ZS5vcmlnaW59IFx1MDYyM1x1MDY0NiBcdTA2NEFcdTA2NDNcdTA2NDhcdTA2NDYgJHthZGp9ICR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0fWA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2MjNcdTA2MzVcdTA2M0FcdTA2MzEgXHUwNjQ1XHUwNjQ2IFx1MDYyN1x1MDY0NFx1MDY0NFx1MDYyN1x1MDYzMlx1MDY0NTogXHUwNjRBXHUwNjQxXHUwNjJBXHUwNjMxXHUwNjM2IFx1MDY0NFx1MDY0MCAke2lzc3VlLm9yaWdpbn0gXHUwNjIzXHUwNjQ2IFx1MDY0QVx1MDY0M1x1MDY0OFx1MDY0NiAke2Fkan0gJHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSByZXR1cm4gYFx1MDY0Nlx1MDY0RVx1MDYzNSBcdTA2M0FcdTA2NEFcdTA2MzEgXHUwNjQ1XHUwNjQyXHUwNjI4XHUwNjQ4XHUwNjQ0OiBcdTA2NEFcdTA2MkNcdTA2MjggXHUwNjIzXHUwNjQ2IFx1MDY0QVx1MDYyOFx1MDYyRlx1MDYyMyBcdTA2MjhcdTA2NDAgXCIke2lzc3VlLnByZWZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYFx1MDY0Nlx1MDY0RVx1MDYzNSBcdTA2M0FcdTA2NEFcdTA2MzEgXHUwNjQ1XHUwNjQyXHUwNjI4XHUwNjQ4XHUwNjQ0OiBcdTA2NEFcdTA2MkNcdTA2MjggXHUwNjIzXHUwNjQ2IFx1MDY0QVx1MDY0Nlx1MDYyQVx1MDY0N1x1MDY0QSBcdTA2MjhcdTA2NDAgXCIke19pc3N1ZS5zdWZmaXh9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJpbmNsdWRlc1wiKSByZXR1cm4gYFx1MDY0Nlx1MDY0RVx1MDYzNSBcdTA2M0FcdTA2NEFcdTA2MzEgXHUwNjQ1XHUwNjQyXHUwNjI4XHUwNjQ4XHUwNjQ0OiBcdTA2NEFcdTA2MkNcdTA2MjggXHUwNjIzXHUwNjQ2IFx1MDY0QVx1MDYyQVx1MDYzNlx1MDY0NVx1MDY1MVx1MDY0RVx1MDY0NiBcIiR7X2lzc3VlLmluY2x1ZGVzfVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBcdTA2NDZcdTA2NEVcdTA2MzUgXHUwNjNBXHUwNjRBXHUwNjMxIFx1MDY0NVx1MDY0Mlx1MDYyOFx1MDY0OFx1MDY0NDogXHUwNjRBXHUwNjJDXHUwNjI4IFx1MDYyM1x1MDY0NiBcdTA2NEFcdTA2MzdcdTA2MjdcdTA2MjhcdTA2NDIgXHUwNjI3XHUwNjQ0XHUwNjQ2XHUwNjQ1XHUwNjM3ICR7X2lzc3VlLnBhdHRlcm59YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGAke05vdW5zW19pc3N1ZS5mb3JtYXRdID8/IGlzc3VlLmZvcm1hdH0gXHUwNjNBXHUwNjRBXHUwNjMxIFx1MDY0NVx1MDY0Mlx1MDYyOFx1MDY0OFx1MDY0NGA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm5vdF9tdWx0aXBsZV9vZlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjMxXHUwNjQyXHUwNjQ1IFx1MDYzQVx1MDY0QVx1MDYzMSBcdTA2NDVcdTA2NDJcdTA2MjhcdTA2NDhcdTA2NDQ6IFx1MDY0QVx1MDYyQ1x1MDYyOCBcdTA2MjNcdTA2NDYgXHUwNjRBXHUwNjQzXHUwNjQ4XHUwNjQ2IFx1MDY0NVx1MDY0NiBcdTA2NDVcdTA2MzZcdTA2MjdcdTA2MzlcdTA2NDFcdTA2MjdcdTA2MkEgJHtpc3N1ZS5kaXZpc29yfWA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDY0NVx1MDYzOVx1MDYzMVx1MDY0MSR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJcdTA2MjdcdTA2MkFcIiA6IFwiXCJ9IFx1MDYzQVx1MDYzMVx1MDY0QVx1MDYyOCR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJcdTA2MjlcIiA6IFwiXCJ9OiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIlx1MDYwQyBcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2tleVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjQ1XHUwNjM5XHUwNjMxXHUwNjQxIFx1MDYzQVx1MDY0QVx1MDYzMSBcdTA2NDVcdTA2NDJcdTA2MjhcdTA2NDhcdTA2NDQgXHUwNjQxXHUwNjRBICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF91bmlvblwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIlx1MDY0NVx1MDYyRlx1MDYyRVx1MDY0NCBcdTA2M0FcdTA2NEFcdTA2MzEgXHUwNjQ1XHUwNjQyXHUwNjI4XHUwNjQ4XHUwNjQ0XCI7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9lbGVtZW50XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2NDVcdTA2MkZcdTA2MkVcdTA2NDQgXHUwNjNBXHUwNjRBXHUwNjMxIFx1MDY0NVx1MDY0Mlx1MDYyOFx1MDY0OFx1MDY0NCBcdTA2NDFcdTA2NEEgJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiXHUwNjQ1XHUwNjJGXHUwNjJFXHUwNjQ0IFx1MDYzQVx1MDY0QVx1MDYzMSBcdTA2NDVcdTA2NDJcdTA2MjhcdTA2NDhcdTA2NDRcIjtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJzaW12b2xcIixcbiAgICAgICAgICAgIHZlcmI6IFwib2xtYWxcdTAxMzFkXHUwMTMxclwiXG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiYmF5dFwiLFxuICAgICAgICAgICAgdmVyYjogXCJvbG1hbFx1MDEzMWRcdTAxMzFyXCJcbiAgICAgICAgfSxcbiAgICAgICAgYXJyYXk6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiZWxlbWVudFwiLFxuICAgICAgICAgICAgdmVyYjogXCJvbG1hbFx1MDEzMWRcdTAxMzFyXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcImVsZW1lbnRcIixcbiAgICAgICAgICAgIHZlcmI6IFwib2xtYWxcdTAxMzFkXHUwMTMxclwiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4pIHtcbiAgICAgICAgcmV0dXJuIFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWRUeXBlID0gKGRhdGEpPT57XG4gICAgICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICAgICAgc3dpdGNoKHQpe1xuICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIm51bWJlclwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJhcnJheVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJudWxsXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcImlucHV0XCIsXG4gICAgICAgIGVtYWlsOiBcImVtYWlsIGFkZHJlc3NcIixcbiAgICAgICAgdXJsOiBcIlVSTFwiLFxuICAgICAgICBlbW9qaTogXCJlbW9qaVwiLFxuICAgICAgICB1dWlkOiBcIlVVSURcIixcbiAgICAgICAgdXVpZHY0OiBcIlVVSUR2NFwiLFxuICAgICAgICB1dWlkdjY6IFwiVVVJRHY2XCIsXG4gICAgICAgIG5hbm9pZDogXCJuYW5vaWRcIixcbiAgICAgICAgZ3VpZDogXCJHVUlEXCIsXG4gICAgICAgIGN1aWQ6IFwiY3VpZFwiLFxuICAgICAgICBjdWlkMjogXCJjdWlkMlwiLFxuICAgICAgICB1bGlkOiBcIlVMSURcIixcbiAgICAgICAgeGlkOiBcIlhJRFwiLFxuICAgICAgICBrc3VpZDogXCJLU1VJRFwiLFxuICAgICAgICBkYXRldGltZTogXCJJU08gZGF0ZXRpbWVcIixcbiAgICAgICAgZGF0ZTogXCJJU08gZGF0ZVwiLFxuICAgICAgICB0aW1lOiBcIklTTyB0aW1lXCIsXG4gICAgICAgIGR1cmF0aW9uOiBcIklTTyBkdXJhdGlvblwiLFxuICAgICAgICBpcHY0OiBcIklQdjQgYWRkcmVzc1wiLFxuICAgICAgICBpcHY2OiBcIklQdjYgYWRkcmVzc1wiLFxuICAgICAgICBjaWRydjQ6IFwiSVB2NCByYW5nZVwiLFxuICAgICAgICBjaWRydjY6IFwiSVB2NiByYW5nZVwiLFxuICAgICAgICBiYXNlNjQ6IFwiYmFzZTY0LWVuY29kZWQgc3RyaW5nXCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJiYXNlNjR1cmwtZW5jb2RlZCBzdHJpbmdcIixcbiAgICAgICAganNvbl9zdHJpbmc6IFwiSlNPTiBzdHJpbmdcIixcbiAgICAgICAgZTE2NDogXCJFLjE2NCBudW1iZXJcIixcbiAgICAgICAgand0OiBcIkpXVFwiLFxuICAgICAgICB0ZW1wbGF0ZV9saXRlcmFsOiBcImlucHV0XCJcbiAgICB9O1xuICAgIHJldHVybiAoaXNzdWUpPT57XG4gICAgICAgIHN3aXRjaChpc3N1ZS5jb2RlKXtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3R5cGVcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFlhbmxcdTAxMzFcdTAxNUYgZFx1MDI1OXlcdTAyNTlyOiBnXHUwMEY2emxcdTAyNTluaWxcdTAyNTluICR7aXNzdWUuZXhwZWN0ZWR9LCBkYXhpbCBvbGFuICR7cGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgWWFubFx1MDEzMVx1MDE1RiBkXHUwMjU5eVx1MDI1OXI6IGdcdTAwRjZ6bFx1MDI1OW5pbFx1MDI1OW4gJHt1dGlsLnN0cmluZ2lmeVByaW1pdGl2ZShpc3N1ZS52YWx1ZXNbMF0pfWA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBZYW5sXHUwMTMxXHUwMTVGIHNlXHUwMEU3aW06IGFcdTAxNUZhXHUwMTFGXHUwMTMxZGFrXHUwMTMxbGFyZGFuIGJpcmkgb2xtYWxcdTAxMzFkXHUwMTMxcjogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIjw9XCIgOiBcIjxcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgXHUwMEM3b3ggYlx1MDBGNnlcdTAwRkNrOiBnXHUwMEY2emxcdTAyNTluaWxcdTAyNTluICR7aXNzdWUub3JpZ2luID8/IFwiZFx1MDI1OXlcdTAyNTlyXCJ9ICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0ID8/IFwiZWxlbWVudFwifWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwMEM3b3ggYlx1MDBGNnlcdTAwRkNrOiBnXHUwMEY2emxcdTAyNTluaWxcdTAyNTluICR7aXNzdWUub3JpZ2luID8/IFwiZFx1MDI1OXlcdTAyNTlyXCJ9ICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInRvb19zbWFsbFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI+PVwiIDogXCI+XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSByZXR1cm4gYFx1MDBDN294IGtpXHUwMEU3aWs6IGdcdTAwRjZ6bFx1MDI1OW5pbFx1MDI1OW4gJHtpc3N1ZS5vcmlnaW59ICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0fWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwMEM3b3gga2lcdTAwRTdpazogZ1x1MDBGNnpsXHUwMjU5bmlsXHUwMjU5biAke2lzc3VlLm9yaWdpbn0gJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSByZXR1cm4gYFlhbmxcdTAxMzFcdTAxNUYgbVx1MDI1OXRuOiBcIiR7X2lzc3VlLnByZWZpeH1cIiBpbFx1MDI1OSBiYVx1MDE1RmxhbWFsXHUwMTMxZFx1MDEzMXJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJlbmRzX3dpdGhcIikgcmV0dXJuIGBZYW5sXHUwMTMxXHUwMTVGIG1cdTAyNTl0bjogXCIke19pc3N1ZS5zdWZmaXh9XCIgaWxcdTAyNTkgYml0bVx1MDI1OWxpZGlyYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBZYW5sXHUwMTMxXHUwMTVGIG1cdTAyNTl0bjogXCIke19pc3N1ZS5pbmNsdWRlc31cIiBkYXhpbCBvbG1hbFx1MDEzMWRcdTAxMzFyYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBZYW5sXHUwMTMxXHUwMTVGIG1cdTAyNTl0bjogJHtfaXNzdWUucGF0dGVybn0gXHUwMTVGYWJsb251bmEgdXlcdTAxMUZ1biBvbG1hbFx1MDEzMWRcdTAxMzFyYDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBZYW5sXHUwMTMxXHUwMTVGICR7Tm91bnNbX2lzc3VlLmZvcm1hdF0gPz8gaXNzdWUuZm9ybWF0fWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm5vdF9tdWx0aXBsZV9vZlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgWWFubFx1MDEzMVx1MDE1RiBcdTAyNTlkXHUwMjU5ZDogJHtpc3N1ZS5kaXZpc29yfSBpbFx1MDI1OSBiXHUwMEY2bFx1MDBGQ25cdTAyNTkgYmlsXHUwMjU5biBvbG1hbFx1MDEzMWRcdTAxMzFyYDtcbiAgICAgICAgICAgIGNhc2UgXCJ1bnJlY29nbml6ZWRfa2V5c1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgVGFuXHUwMTMxbm1heWFuIGFcdTAwRTdhciR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJsYXJcIiA6IFwiXCJ9OiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIiwgXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYCR7aXNzdWUub3JpZ2lufSBkYXhpbGluZFx1MDI1OSB5YW5sXHUwMTMxXHUwMTVGIGFcdTAwRTdhcmA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF91bmlvblwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIllhbmxcdTAxMzFcdTAxNUYgZFx1MDI1OXlcdTAyNTlyXCI7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9lbGVtZW50XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGAke2lzc3VlLm9yaWdpbn0gZGF4aWxpbmRcdTAyNTkgeWFubFx1MDEzMVx1MDE1RiBkXHUwMjU5eVx1MDI1OXJgO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFlhbmxcdTAxMzFcdTAxNUYgZFx1MDI1OXlcdTAyNTlyYDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuZnVuY3Rpb24gZ2V0QmVsYXJ1c2lhblBsdXJhbChjb3VudCwgb25lLCBmZXcsIG1hbnkpIHtcbiAgICBjb25zdCBhYnNDb3VudCA9IE1hdGguYWJzKGNvdW50KTtcbiAgICBjb25zdCBsYXN0RGlnaXQgPSBhYnNDb3VudCAlIDEwO1xuICAgIGNvbnN0IGxhc3RUd29EaWdpdHMgPSBhYnNDb3VudCAlIDEwMDtcbiAgICBpZiAobGFzdFR3b0RpZ2l0cyA+PSAxMSAmJiBsYXN0VHdvRGlnaXRzIDw9IDE5KSB7XG4gICAgICAgIHJldHVybiBtYW55O1xuICAgIH1cbiAgICBpZiAobGFzdERpZ2l0ID09PSAxKSB7XG4gICAgICAgIHJldHVybiBvbmU7XG4gICAgfVxuICAgIGlmIChsYXN0RGlnaXQgPj0gMiAmJiBsYXN0RGlnaXQgPD0gNCkge1xuICAgICAgICByZXR1cm4gZmV3O1xuICAgIH1cbiAgICByZXR1cm4gbWFueTtcbn1cbmNvbnN0IGVycm9yID0gKCk9PntcbiAgICBjb25zdCBTaXphYmxlID0ge1xuICAgICAgICBzdHJpbmc6IHtcbiAgICAgICAgICAgIHVuaXQ6IHtcbiAgICAgICAgICAgICAgICBvbmU6IFwiXHUwNDQxXHUwNDU2XHUwNDNDXHUwNDMyXHUwNDMwXHUwNDNCXCIsXG4gICAgICAgICAgICAgICAgZmV3OiBcIlx1MDQ0MVx1MDQ1Nlx1MDQzQ1x1MDQzMlx1MDQzMFx1MDQzQlx1MDQ0QlwiLFxuICAgICAgICAgICAgICAgIG1hbnk6IFwiXHUwNDQxXHUwNDU2XHUwNDNDXHUwNDMyXHUwNDMwXHUwNDNCXHUwNDMwXHUwNDVFXCJcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MDQzQ1x1MDQzNVx1MDQ0Nlx1MDQ0Q1wiXG4gICAgICAgIH0sXG4gICAgICAgIGFycmF5OiB7XG4gICAgICAgICAgICB1bml0OiB7XG4gICAgICAgICAgICAgICAgb25lOiBcIlx1MDQ0RFx1MDQzQlx1MDQzNVx1MDQzQ1x1MDQzNVx1MDQzRFx1MDQ0MlwiLFxuICAgICAgICAgICAgICAgIGZldzogXCJcdTA0NERcdTA0M0JcdTA0MzVcdTA0M0NcdTA0MzVcdTA0M0RcdTA0NDJcdTA0NEJcIixcbiAgICAgICAgICAgICAgICBtYW55OiBcIlx1MDQ0RFx1MDQzQlx1MDQzNVx1MDQzQ1x1MDQzNVx1MDQzRFx1MDQ0Mlx1MDQzMFx1MDQ1RVwiXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdmVyYjogXCJcdTA0M0NcdTA0MzVcdTA0NDZcdTA0NENcIlxuICAgICAgICB9LFxuICAgICAgICBzZXQ6IHtcbiAgICAgICAgICAgIHVuaXQ6IHtcbiAgICAgICAgICAgICAgICBvbmU6IFwiXHUwNDREXHUwNDNCXHUwNDM1XHUwNDNDXHUwNDM1XHUwNDNEXHUwNDQyXCIsXG4gICAgICAgICAgICAgICAgZmV3OiBcIlx1MDQ0RFx1MDQzQlx1MDQzNVx1MDQzQ1x1MDQzNVx1MDQzRFx1MDQ0Mlx1MDQ0QlwiLFxuICAgICAgICAgICAgICAgIG1hbnk6IFwiXHUwNDREXHUwNDNCXHUwNDM1XHUwNDNDXHUwNDM1XHUwNDNEXHUwNDQyXHUwNDMwXHUwNDVFXCJcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MDQzQ1x1MDQzNVx1MDQ0Nlx1MDQ0Q1wiXG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IHtcbiAgICAgICAgICAgICAgICBvbmU6IFwiXHUwNDMxXHUwNDMwXHUwNDM5XHUwNDQyXCIsXG4gICAgICAgICAgICAgICAgZmV3OiBcIlx1MDQzMVx1MDQzMFx1MDQzOVx1MDQ0Mlx1MDQ0QlwiLFxuICAgICAgICAgICAgICAgIG1hbnk6IFwiXHUwNDMxXHUwNDMwXHUwNDM5XHUwNDQyXHUwNDMwXHUwNDVFXCJcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MDQzQ1x1MDQzNVx1MDQ0Nlx1MDQ0Q1wiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4pIHtcbiAgICAgICAgcmV0dXJuIFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWRUeXBlID0gKGRhdGEpPT57XG4gICAgICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICAgICAgc3dpdGNoKHQpe1xuICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIlx1MDQzQlx1MDQ1Nlx1MDQzQVwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTA0M0NcdTA0MzBcdTA0NDFcdTA0NTZcdTA0NUVcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YoZGF0YSkgIT09IE9iamVjdC5wcm90b3R5cGUgJiYgZGF0YS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdDtcbiAgICB9O1xuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJcdTA0NDNcdTA0MzJcdTA0M0VcdTA0MzRcIixcbiAgICAgICAgZW1haWw6IFwiZW1haWwgXHUwNDMwXHUwNDM0XHUwNDQwXHUwNDMwXHUwNDQxXCIsXG4gICAgICAgIHVybDogXCJVUkxcIixcbiAgICAgICAgZW1vamk6IFwiXHUwNDREXHUwNDNDXHUwNDNFXHUwNDM0XHUwNDM3XHUwNDU2XCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcIklTTyBcdTA0MzRcdTA0MzBcdTA0NDJcdTA0MzAgXHUwNDU2IFx1MDQ0N1x1MDQzMFx1MDQ0MVwiLFxuICAgICAgICBkYXRlOiBcIklTTyBcdTA0MzRcdTA0MzBcdTA0NDJcdTA0MzBcIixcbiAgICAgICAgdGltZTogXCJJU08gXHUwNDQ3XHUwNDMwXHUwNDQxXCIsXG4gICAgICAgIGR1cmF0aW9uOiBcIklTTyBcdTA0M0ZcdTA0NDBcdTA0MzBcdTA0NDZcdTA0NEZcdTA0MzNcdTA0M0JcdTA0MzBcdTA0NDFcdTA0NDZcdTA0NENcIixcbiAgICAgICAgaXB2NDogXCJJUHY0IFx1MDQzMFx1MDQzNFx1MDQ0MFx1MDQzMFx1MDQ0MVwiLFxuICAgICAgICBpcHY2OiBcIklQdjYgXHUwNDMwXHUwNDM0XHUwNDQwXHUwNDMwXHUwNDQxXCIsXG4gICAgICAgIGNpZHJ2NDogXCJJUHY0IFx1MDQzNFx1MDQ0Qlx1MDQ0Rlx1MDQzRlx1MDQzMFx1MDQzN1x1MDQzRVx1MDQzRFwiLFxuICAgICAgICBjaWRydjY6IFwiSVB2NiBcdTA0MzRcdTA0NEJcdTA0NEZcdTA0M0ZcdTA0MzBcdTA0MzdcdTA0M0VcdTA0M0RcIixcbiAgICAgICAgYmFzZTY0OiBcIlx1MDQ0MFx1MDQzMFx1MDQzNFx1MDQzRVx1MDQzQSBcdTA0NDMgXHUwNDQ0XHUwNDMwXHUwNDQwXHUwNDNDXHUwNDMwXHUwNDQ2XHUwNDM1IGJhc2U2NFwiLFxuICAgICAgICBiYXNlNjR1cmw6IFwiXHUwNDQwXHUwNDMwXHUwNDM0XHUwNDNFXHUwNDNBIFx1MDQ0MyBcdTA0NDRcdTA0MzBcdTA0NDBcdTA0M0NcdTA0MzBcdTA0NDZcdTA0MzUgYmFzZTY0dXJsXCIsXG4gICAgICAgIGpzb25fc3RyaW5nOiBcIkpTT04gXHUwNDQwXHUwNDMwXHUwNDM0XHUwNDNFXHUwNDNBXCIsXG4gICAgICAgIGUxNjQ6IFwiXHUwNDNEXHUwNDQzXHUwNDNDXHUwNDMwXHUwNDQwIEUuMTY0XCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJcdTA0NDNcdTA0MzJcdTA0M0VcdTA0MzRcIlxuICAgIH07XG4gICAgcmV0dXJuIChpc3N1ZSk9PntcbiAgICAgICAgc3dpdGNoKGlzc3VlLmNvZGUpe1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdHlwZVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNDFEXHUwNDRGXHUwNDNGXHUwNDQwXHUwNDMwXHUwNDMyXHUwNDU2XHUwNDNCXHUwNDRDXHUwNDNEXHUwNDRCIFx1MDQ1RVx1MDQzMlx1MDQzRVx1MDQzNDogXHUwNDQ3XHUwNDMwXHUwNDNBXHUwNDMwXHUwNDVFXHUwNDQxXHUwNDRGICR7aXNzdWUuZXhwZWN0ZWR9LCBcdTA0MzBcdTA0NDJcdTA0NDBcdTA0NEJcdTA0M0NcdTA0MzBcdTA0M0RcdTA0MzAgJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBcdTA0MURcdTA0NEZcdTA0M0ZcdTA0NDBcdTA0MzBcdTA0MzJcdTA0NTZcdTA0M0JcdTA0NENcdTA0M0RcdTA0NEIgXHUwNDVFXHUwNDMyXHUwNDNFXHUwNDM0OiBcdTA0NDdcdTA0MzBcdTA0M0FcdTA0MzBcdTA0M0JcdTA0MzBcdTA0NDFcdTA0NEYgJHt1dGlsLnN0cmluZ2lmeVByaW1pdGl2ZShpc3N1ZS52YWx1ZXNbMF0pfWA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MURcdTA0NEZcdTA0M0ZcdTA0NDBcdTA0MzBcdTA0MzJcdTA0NTZcdTA0M0JcdTA0NENcdTA0M0RcdTA0NEIgXHUwNDMyXHUwNDMwXHUwNDQwXHUwNDRCXHUwNDRGXHUwNDNEXHUwNDQyOiBcdTA0NDdcdTA0MzBcdTA0M0FcdTA0MzBcdTA0NUVcdTA0NDFcdTA0NEYgXHUwNDMwXHUwNDM0XHUwNDM3XHUwNDU2XHUwNDNEIFx1MDQzNyAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS52YWx1ZXMsIFwifFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPD1cIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF4VmFsdWUgPSBOdW1iZXIoaXNzdWUubWF4aW11bSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bml0ID0gZ2V0QmVsYXJ1c2lhblBsdXJhbChtYXhWYWx1ZSwgc2l6aW5nLnVuaXQub25lLCBzaXppbmcudW5pdC5mZXcsIHNpemluZy51bml0Lm1hbnkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MTdcdTA0MzBcdTA0M0RcdTA0MzBcdTA0MzRcdTA0NDJcdTA0MzAgXHUwNDMyXHUwNDRGXHUwNDNCXHUwNDU2XHUwNDNBXHUwNDU2OiBcdTA0NDdcdTA0MzBcdTA0M0FcdTA0MzBcdTA0M0JcdTA0MzBcdTA0NDFcdTA0NEYsIFx1MDQ0OFx1MDQ0Mlx1MDQzRSAke2lzc3VlLm9yaWdpbiA/PyBcIlx1MDQzN1x1MDQzRFx1MDQzMFx1MDQ0N1x1MDQ0RFx1MDQzRFx1MDQzRFx1MDQzNVwifSBcdTA0M0ZcdTA0MzBcdTA0MzJcdTA0NTZcdTA0M0RcdTA0M0RcdTA0MzAgJHtzaXppbmcudmVyYn0gJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7dW5pdH1gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNDE3XHUwNDMwXHUwNDNEXHUwNDMwXHUwNDM0XHUwNDQyXHUwNDMwIFx1MDQzMlx1MDQ0Rlx1MDQzQlx1MDQ1Nlx1MDQzQVx1MDQ1NjogXHUwNDQ3XHUwNDMwXHUwNDNBXHUwNDMwXHUwNDNCXHUwNDMwXHUwNDQxXHUwNDRGLCBcdTA0NDhcdTA0NDJcdTA0M0UgJHtpc3N1ZS5vcmlnaW4gPz8gXCJcdTA0MzdcdTA0M0RcdTA0MzBcdTA0NDdcdTA0NERcdTA0M0RcdTA0M0RcdTA0MzVcIn0gXHUwNDNGXHUwNDMwXHUwNDMyXHUwNDU2XHUwNDNEXHUwNDNEXHUwNDMwIFx1MDQzMVx1MDQ0Qlx1MDQ0Nlx1MDQ0QyAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJ0b29fc21hbGxcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPj1cIiA6IFwiPlwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWluVmFsdWUgPSBOdW1iZXIoaXNzdWUubWluaW11bSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bml0ID0gZ2V0QmVsYXJ1c2lhblBsdXJhbChtaW5WYWx1ZSwgc2l6aW5nLnVuaXQub25lLCBzaXppbmcudW5pdC5mZXcsIHNpemluZy51bml0Lm1hbnkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MTdcdTA0MzBcdTA0M0RcdTA0MzBcdTA0MzRcdTA0NDJcdTA0MzAgXHUwNDNDXHUwNDMwXHUwNDNCXHUwNDRCOiBcdTA0NDdcdTA0MzBcdTA0M0FcdTA0MzBcdTA0M0JcdTA0MzBcdTA0NDFcdTA0NEYsIFx1MDQ0OFx1MDQ0Mlx1MDQzRSAke2lzc3VlLm9yaWdpbn0gXHUwNDNGXHUwNDMwXHUwNDMyXHUwNDU2XHUwNDNEXHUwNDNEXHUwNDMwICR7c2l6aW5nLnZlcmJ9ICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3VuaXR9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDQxN1x1MDQzMFx1MDQzRFx1MDQzMFx1MDQzNFx1MDQ0Mlx1MDQzMCBcdTA0M0NcdTA0MzBcdTA0M0JcdTA0NEI6IFx1MDQ0N1x1MDQzMFx1MDQzQVx1MDQzMFx1MDQzQlx1MDQzMFx1MDQ0MVx1MDQ0RiwgXHUwNDQ4XHUwNDQyXHUwNDNFICR7aXNzdWUub3JpZ2lufSBcdTA0M0ZcdTA0MzBcdTA0MzJcdTA0NTZcdTA0M0RcdTA0M0RcdTA0MzAgXHUwNDMxXHUwNDRCXHUwNDQ2XHUwNDRDICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZm9ybWF0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBfaXNzdWUgPSBpc3N1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwic3RhcnRzX3dpdGhcIikgcmV0dXJuIGBcdTA0MURcdTA0NEZcdTA0M0ZcdTA0NDBcdTA0MzBcdTA0MzJcdTA0NTZcdTA0M0JcdTA0NENcdTA0M0RcdTA0NEIgXHUwNDQwXHUwNDMwXHUwNDM0XHUwNDNFXHUwNDNBOiBcdTA0M0ZcdTA0MzBcdTA0MzJcdTA0NTZcdTA0M0RcdTA0MzVcdTA0M0QgXHUwNDNGXHUwNDMwXHUwNDQ3XHUwNDRCXHUwNDNEXHUwNDMwXHUwNDQ2XHUwNDQ2XHUwNDMwIFx1MDQzNyBcIiR7X2lzc3VlLnByZWZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYFx1MDQxRFx1MDQ0Rlx1MDQzRlx1MDQ0MFx1MDQzMFx1MDQzMlx1MDQ1Nlx1MDQzQlx1MDQ0Q1x1MDQzRFx1MDQ0QiBcdTA0NDBcdTA0MzBcdTA0MzRcdTA0M0VcdTA0M0E6IFx1MDQzRlx1MDQzMFx1MDQzMlx1MDQ1Nlx1MDQzRFx1MDQzNVx1MDQzRCBcdTA0MzdcdTA0MzBcdTA0M0FcdTA0MzBcdTA0M0RcdTA0NDdcdTA0MzJcdTA0MzBcdTA0NDZcdTA0NDZcdTA0MzAgXHUwNDNEXHUwNDMwIFwiJHtfaXNzdWUuc3VmZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBcdTA0MURcdTA0NEZcdTA0M0ZcdTA0NDBcdTA0MzBcdTA0MzJcdTA0NTZcdTA0M0JcdTA0NENcdTA0M0RcdTA0NEIgXHUwNDQwXHUwNDMwXHUwNDM0XHUwNDNFXHUwNDNBOiBcdTA0M0ZcdTA0MzBcdTA0MzJcdTA0NTZcdTA0M0RcdTA0MzVcdTA0M0QgXHUwNDM3XHUwNDNDXHUwNDRGXHUwNDQ4XHUwNDQ3XHUwNDMwXHUwNDQ2XHUwNDRDIFwiJHtfaXNzdWUuaW5jbHVkZXN9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYFx1MDQxRFx1MDQ0Rlx1MDQzRlx1MDQ0MFx1MDQzMFx1MDQzMlx1MDQ1Nlx1MDQzQlx1MDQ0Q1x1MDQzRFx1MDQ0QiBcdTA0NDBcdTA0MzBcdTA0MzRcdTA0M0VcdTA0M0E6IFx1MDQzRlx1MDQzMFx1MDQzMlx1MDQ1Nlx1MDQzRFx1MDQzNVx1MDQzRCBcdTA0MzBcdTA0MzRcdTA0M0ZcdTA0MzBcdTA0MzJcdTA0NEZcdTA0MzRcdTA0MzBcdTA0NDZcdTA0NEMgXHUwNDQ4XHUwNDMwXHUwNDMxXHUwNDNCXHUwNDNFXHUwNDNEXHUwNDQzICR7X2lzc3VlLnBhdHRlcm59YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MURcdTA0NEZcdTA0M0ZcdTA0NDBcdTA0MzBcdTA0MzJcdTA0NTZcdTA0M0JcdTA0NENcdTA0M0RcdTA0NEIgJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MURcdTA0NEZcdTA0M0ZcdTA0NDBcdTA0MzBcdTA0MzJcdTA0NTZcdTA0M0JcdTA0NENcdTA0M0RcdTA0NEIgXHUwNDNCXHUwNDU2XHUwNDNBOiBcdTA0M0ZcdTA0MzBcdTA0MzJcdTA0NTZcdTA0M0RcdTA0MzVcdTA0M0QgXHUwNDMxXHUwNDRCXHUwNDQ2XHUwNDRDIFx1MDQzQVx1MDQ0MFx1MDQzMFx1MDQ0Mlx1MDQzRFx1MDQ0Qlx1MDQzQyAke2lzc3VlLmRpdmlzb3J9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ1bnJlY29nbml6ZWRfa2V5c1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNDFEXHUwNDM1XHUwNDQwXHUwNDMwXHUwNDQxXHUwNDNGXHUwNDMwXHUwNDM3XHUwNDNEXHUwNDMwXHUwNDNEXHUwNDRCICR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJcdTA0M0FcdTA0M0JcdTA0NEVcdTA0NDdcdTA0NEJcIiA6IFwiXHUwNDNBXHUwNDNCXHUwNDRFXHUwNDQ3XCJ9OiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIiwgXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDQxRFx1MDQ0Rlx1MDQzRlx1MDQ0MFx1MDQzMFx1MDQzMlx1MDQ1Nlx1MDQzQlx1MDQ0Q1x1MDQzRFx1MDQ0QiBcdTA0M0FcdTA0M0JcdTA0NEVcdTA0NDcgXHUwNDQzICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF91bmlvblwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIlx1MDQxRFx1MDQ0Rlx1MDQzRlx1MDQ0MFx1MDQzMFx1MDQzMlx1MDQ1Nlx1MDQzQlx1MDQ0Q1x1MDQzRFx1MDQ0QiBcdTA0NUVcdTA0MzJcdTA0M0VcdTA0MzRcIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDQxRFx1MDQ0Rlx1MDQzRlx1MDQ0MFx1MDQzMFx1MDQzMlx1MDQ1Nlx1MDQzQlx1MDQ0Q1x1MDQzRFx1MDQzMFx1MDQzNSBcdTA0MzdcdTA0M0RcdTA0MzBcdTA0NDdcdTA0NERcdTA0M0RcdTA0M0RcdTA0MzUgXHUwNDVFICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNDFEXHUwNDRGXHUwNDNGXHUwNDQwXHUwNDMwXHUwNDMyXHUwNDU2XHUwNDNCXHUwNDRDXHUwNDNEXHUwNDRCIFx1MDQ1RVx1MDQzMlx1MDQzRVx1MDQzNGA7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGxvY2FsZUVycm9yOiBlcnJvcigpXG4gICAgfTtcbn1cbiIsICJpbXBvcnQgKiBhcyB1dGlsIGZyb20gXCIuLi9jb3JlL3V0aWwuanNcIjtcbmNvbnN0IGVycm9yID0gKCk9PntcbiAgICBjb25zdCBTaXphYmxlID0ge1xuICAgICAgICBzdHJpbmc6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiY2FyXHUwMEUwY3RlcnNcIixcbiAgICAgICAgICAgIHZlcmI6IFwiY29udGVuaXJcIlxuICAgICAgICB9LFxuICAgICAgICBmaWxlOiB7XG4gICAgICAgICAgICB1bml0OiBcImJ5dGVzXCIsXG4gICAgICAgICAgICB2ZXJiOiBcImNvbnRlbmlyXCJcbiAgICAgICAgfSxcbiAgICAgICAgYXJyYXk6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiZWxlbWVudHNcIixcbiAgICAgICAgICAgIHZlcmI6IFwiY29udGVuaXJcIlxuICAgICAgICB9LFxuICAgICAgICBzZXQ6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiZWxlbWVudHNcIixcbiAgICAgICAgICAgIHZlcmI6IFwiY29udGVuaXJcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIk5hTlwiIDogXCJudW1iZXJcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiYXJyYXlcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YoZGF0YSkgIT09IE9iamVjdC5wcm90b3R5cGUgJiYgZGF0YS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdDtcbiAgICB9O1xuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJlbnRyYWRhXCIsXG4gICAgICAgIGVtYWlsOiBcImFkcmVcdTAwRTdhIGVsZWN0clx1MDBGMm5pY2FcIixcbiAgICAgICAgdXJsOiBcIlVSTFwiLFxuICAgICAgICBlbW9qaTogXCJlbW9qaVwiLFxuICAgICAgICB1dWlkOiBcIlVVSURcIixcbiAgICAgICAgdXVpZHY0OiBcIlVVSUR2NFwiLFxuICAgICAgICB1dWlkdjY6IFwiVVVJRHY2XCIsXG4gICAgICAgIG5hbm9pZDogXCJuYW5vaWRcIixcbiAgICAgICAgZ3VpZDogXCJHVUlEXCIsXG4gICAgICAgIGN1aWQ6IFwiY3VpZFwiLFxuICAgICAgICBjdWlkMjogXCJjdWlkMlwiLFxuICAgICAgICB1bGlkOiBcIlVMSURcIixcbiAgICAgICAgeGlkOiBcIlhJRFwiLFxuICAgICAgICBrc3VpZDogXCJLU1VJRFwiLFxuICAgICAgICBkYXRldGltZTogXCJkYXRhIGkgaG9yYSBJU09cIixcbiAgICAgICAgZGF0ZTogXCJkYXRhIElTT1wiLFxuICAgICAgICB0aW1lOiBcImhvcmEgSVNPXCIsXG4gICAgICAgIGR1cmF0aW9uOiBcImR1cmFkYSBJU09cIixcbiAgICAgICAgaXB2NDogXCJhZHJlXHUwMEU3YSBJUHY0XCIsXG4gICAgICAgIGlwdjY6IFwiYWRyZVx1MDBFN2EgSVB2NlwiLFxuICAgICAgICBjaWRydjQ6IFwicmFuZyBJUHY0XCIsXG4gICAgICAgIGNpZHJ2NjogXCJyYW5nIElQdjZcIixcbiAgICAgICAgYmFzZTY0OiBcImNhZGVuYSBjb2RpZmljYWRhIGVuIGJhc2U2NFwiLFxuICAgICAgICBiYXNlNjR1cmw6IFwiY2FkZW5hIGNvZGlmaWNhZGEgZW4gYmFzZTY0dXJsXCIsXG4gICAgICAgIGpzb25fc3RyaW5nOiBcImNhZGVuYSBKU09OXCIsXG4gICAgICAgIGUxNjQ6IFwiblx1MDBGQW1lcm8gRS4xNjRcIixcbiAgICAgICAgand0OiBcIkpXVFwiLFxuICAgICAgICB0ZW1wbGF0ZV9saXRlcmFsOiBcImVudHJhZGFcIlxuICAgIH07XG4gICAgcmV0dXJuIChpc3N1ZSk9PntcbiAgICAgICAgc3dpdGNoKGlzc3VlLmNvZGUpe1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdHlwZVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgVGlwdXMgaW52XHUwMEUwbGlkOiBzJ2VzcGVyYXZhICR7aXNzdWUuZXhwZWN0ZWR9LCBzJ2hhIHJlYnV0ICR7cGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9YDtcbiAgICAgICAgICAgIC8vIHJldHVybiBgVGlwdXMgaW52XHUwMEUwbGlkOiBzJ2VzcGVyYXZhICR7aXNzdWUuZXhwZWN0ZWR9LCBzJ2hhIHJlYnV0ICR7dXRpbC5nZXRQYXJzZWRUeXBlKGlzc3VlLmlucHV0KX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBWYWxvciBpbnZcdTAwRTBsaWQ6IHMnZXNwZXJhdmEgJHt1dGlsLnN0cmluZ2lmeVByaW1pdGl2ZShpc3N1ZS52YWx1ZXNbMF0pfWA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBPcGNpXHUwMEYzIGludlx1MDBFMGxpZGE6IHMnZXNwZXJhdmEgdW5hIGRlICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLnZhbHVlcywgXCIgbyBcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcImNvbSBhIG1cdTAwRTB4aW1cIiA6IFwibWVueXMgZGVcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgTWFzc2EgZ3Jhbjogcydlc3BlcmF2YSBxdWUgJHtpc3N1ZS5vcmlnaW4gPz8gXCJlbCB2YWxvclwifSBjb250aW5ndVx1MDBFOXMgJHthZGp9ICR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0ID8/IFwiZWxlbWVudHNcIn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYE1hc3NhIGdyYW46IHMnZXNwZXJhdmEgcXVlICR7aXNzdWUub3JpZ2luID8/IFwiZWwgdmFsb3JcIn0gZm9zICR7YWRqfSAke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJ0b29fc21hbGxcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiY29tIGEgbVx1MDBFRG5pbVwiIDogXCJtXHUwMEU5cyBkZVwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBNYXNzYSBwZXRpdDogcydlc3BlcmF2YSBxdWUgJHtpc3N1ZS5vcmlnaW59IGNvbnRpbmd1XHUwMEU5cyAke2Fkan0gJHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXR9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYE1hc3NhIHBldGl0OiBzJ2VzcGVyYXZhIHF1ZSAke2lzc3VlLm9yaWdpbn0gZm9zICR7YWRqfSAke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2Zvcm1hdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgX2lzc3VlID0gaXNzdWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInN0YXJ0c193aXRoXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgRm9ybWF0IGludlx1MDBFMGxpZDogaGEgZGUgY29tZW5cdTAwRTdhciBhbWIgXCIke19pc3N1ZS5wcmVmaXh9XCJgO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYEZvcm1hdCBpbnZcdTAwRTBsaWQ6IGhhIGQnYWNhYmFyIGFtYiBcIiR7X2lzc3VlLnN1ZmZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImluY2x1ZGVzXCIpIHJldHVybiBgRm9ybWF0IGludlx1MDBFMGxpZDogaGEgZCdpbmNsb3VyZSBcIiR7X2lzc3VlLmluY2x1ZGVzfVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBGb3JtYXQgaW52XHUwMEUwbGlkOiBoYSBkZSBjb2luY2lkaXIgYW1iIGVsIHBhdHJcdTAwRjMgJHtfaXNzdWUucGF0dGVybn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYEZvcm1hdCBpbnZcdTAwRTBsaWQgcGVyIGEgJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOXHUwMEZBbWVybyBpbnZcdTAwRTBsaWQ6IGhhIGRlIHNlciBtXHUwMEZBbHRpcGxlIGRlICR7aXNzdWUuZGl2aXNvcn1gO1xuICAgICAgICAgICAgY2FzZSBcInVucmVjb2duaXplZF9rZXlzXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBDbGF1JHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcInNcIiA6IFwiXCJ9IG5vIHJlY29uZWd1ZGEke2lzc3VlLmtleXMubGVuZ3RoID4gMSA/IFwic1wiIDogXCJcIn06ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLmtleXMsIFwiLCBcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2tleVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgQ2xhdSBpbnZcdTAwRTBsaWRhIGEgJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3VuaW9uXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiRW50cmFkYSBpbnZcdTAwRTBsaWRhXCI7IC8vIENvdWxkIGFsc28gYmUgXCJUaXB1cyBkJ3VuaVx1MDBGMyBpbnZcdTAwRTBsaWRcIiBidXQgXCJFbnRyYWRhIGludlx1MDBFMGxpZGFcIiBpcyBtb3JlIGdlbmVyYWxcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYEVsZW1lbnQgaW52XHUwMEUwbGlkIGEgJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBFbnRyYWRhIGludlx1MDBFMGxpZGFgO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBsb2NhbGVFcnJvcjogZXJyb3IoKVxuICAgIH07XG59XG4iLCAiaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi4vY29yZS91dGlsLmpzXCI7XG5jb25zdCBlcnJvciA9ICgpPT57XG4gICAgY29uc3QgU2l6YWJsZSA9IHtcbiAgICAgICAgc3RyaW5nOiB7XG4gICAgICAgICAgICB1bml0OiBcInpuYWtcdTAxNkZcIixcbiAgICAgICAgICAgIHZlcmI6IFwibVx1MDBFRHRcIlxuICAgICAgICB9LFxuICAgICAgICBmaWxlOiB7XG4gICAgICAgICAgICB1bml0OiBcImJhanRcdTAxNkZcIixcbiAgICAgICAgICAgIHZlcmI6IFwibVx1MDBFRHRcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJwcnZrXHUwMTZGXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIm1cdTAwRUR0XCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcInBydmtcdTAxNkZcIixcbiAgICAgICAgICAgIHZlcmI6IFwibVx1MDBFRHRcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIk5hTlwiIDogXCJcdTAxMERcdTAwRURzbG9cIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwic3RyaW5nXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTAxNTlldFx1MDExQnplY1wiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJib29sZWFuXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJib29sZWFuXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImJpZ2ludFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiYmlnaW50XCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImZ1bmN0aW9uXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJmdW5rY2VcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwic3ltYm9sXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJzeW1ib2xcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidW5kZWZpbmVkXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJ1bmRlZmluZWRcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwicG9sZVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJudWxsXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcInJlZ3VsXHUwMEUxcm5cdTAwRUQgdlx1MDBGRHJhelwiLFxuICAgICAgICBlbWFpbDogXCJlLW1haWxvdlx1MDBFMSBhZHJlc2FcIixcbiAgICAgICAgdXJsOiBcIlVSTFwiLFxuICAgICAgICBlbW9qaTogXCJlbW9qaVwiLFxuICAgICAgICB1dWlkOiBcIlVVSURcIixcbiAgICAgICAgdXVpZHY0OiBcIlVVSUR2NFwiLFxuICAgICAgICB1dWlkdjY6IFwiVVVJRHY2XCIsXG4gICAgICAgIG5hbm9pZDogXCJuYW5vaWRcIixcbiAgICAgICAgZ3VpZDogXCJHVUlEXCIsXG4gICAgICAgIGN1aWQ6IFwiY3VpZFwiLFxuICAgICAgICBjdWlkMjogXCJjdWlkMlwiLFxuICAgICAgICB1bGlkOiBcIlVMSURcIixcbiAgICAgICAgeGlkOiBcIlhJRFwiLFxuICAgICAgICBrc3VpZDogXCJLU1VJRFwiLFxuICAgICAgICBkYXRldGltZTogXCJkYXR1bSBhIFx1MDEwRGFzIHZlIGZvcm1cdTAwRTF0dSBJU09cIixcbiAgICAgICAgZGF0ZTogXCJkYXR1bSB2ZSBmb3JtXHUwMEUxdHUgSVNPXCIsXG4gICAgICAgIHRpbWU6IFwiXHUwMTBEYXMgdmUgZm9ybVx1MDBFMXR1IElTT1wiLFxuICAgICAgICBkdXJhdGlvbjogXCJkb2JhIHRydlx1MDBFMW5cdTAwRUQgSVNPXCIsXG4gICAgICAgIGlwdjQ6IFwiSVB2NCBhZHJlc2FcIixcbiAgICAgICAgaXB2NjogXCJJUHY2IGFkcmVzYVwiLFxuICAgICAgICBjaWRydjQ6IFwicm96c2FoIElQdjRcIixcbiAgICAgICAgY2lkcnY2OiBcInJvenNhaCBJUHY2XCIsXG4gICAgICAgIGJhc2U2NDogXCJcdTAxNTlldFx1MDExQnplYyB6YWtcdTAwRjNkb3Zhblx1MDBGRCB2ZSBmb3JtXHUwMEUxdHUgYmFzZTY0XCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJcdTAxNTlldFx1MDExQnplYyB6YWtcdTAwRjNkb3Zhblx1MDBGRCB2ZSBmb3JtXHUwMEUxdHUgYmFzZTY0dXJsXCIsXG4gICAgICAgIGpzb25fc3RyaW5nOiBcIlx1MDE1OWV0XHUwMTFCemVjIHZlIGZvcm1cdTAwRTF0dSBKU09OXCIsXG4gICAgICAgIGUxNjQ6IFwiXHUwMTBEXHUwMEVEc2xvIEUuMTY0XCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJ2c3R1cFwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOZXBsYXRuXHUwMEZEIHZzdHVwOiBvXHUwMTBEZWtcdTAwRTF2XHUwMEUxbm8gJHtpc3N1ZS5leHBlY3RlZH0sIG9iZHJcdTAxN0Vlbm8gJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBOZXBsYXRuXHUwMEZEIHZzdHVwOiBvXHUwMTBEZWtcdTAwRTF2XHUwMEUxbm8gJHt1dGlsLnN0cmluZ2lmeVByaW1pdGl2ZShpc3N1ZS52YWx1ZXNbMF0pfWA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOZXBsYXRuXHUwMEUxIG1vXHUwMTdFbm9zdDogb1x1MDEwRGVrXHUwMEUxdlx1MDBFMW5hIGplZG5hIHogaG9kbm90ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLnZhbHVlcywgXCJ8XCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwidG9vX2JpZ1wiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI8PVwiIDogXCI8XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYEhvZG5vdGEgamUgcFx1MDE1OVx1MDBFRGxpXHUwMTYxIHZlbGtcdTAwRTE6ICR7aXNzdWUub3JpZ2luID8/IFwiaG9kbm90YVwifSBtdXNcdTAwRUQgbVx1MDBFRHQgJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXQgPz8gXCJwcnZrXHUwMTZGXCJ9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYEhvZG5vdGEgamUgcFx1MDE1OVx1MDBFRGxpXHUwMTYxIHZlbGtcdTAwRTE6ICR7aXNzdWUub3JpZ2luID8/IFwiaG9kbm90YVwifSBtdXNcdTAwRUQgYlx1MDBGRHQgJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIj49XCIgOiBcIj5cIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgSG9kbm90YSBqZSBwXHUwMTU5XHUwMEVEbGlcdTAxNjEgbWFsXHUwMEUxOiAke2lzc3VlLm9yaWdpbiA/PyBcImhvZG5vdGFcIn0gbXVzXHUwMEVEIG1cdTAwRUR0ICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0ID8/IFwicHJ2a1x1MDE2RlwifWA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBIb2Rub3RhIGplIHBcdTAxNTlcdTAwRURsaVx1MDE2MSBtYWxcdTAwRTE6ICR7aXNzdWUub3JpZ2luID8/IFwiaG9kbm90YVwifSBtdXNcdTAwRUQgYlx1MDBGRHQgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSByZXR1cm4gYE5lcGxhdG5cdTAwRkQgXHUwMTU5ZXRcdTAxMUJ6ZWM6IG11c1x1MDBFRCB6YVx1MDEwRFx1MDBFRG5hdCBuYSBcIiR7X2lzc3VlLnByZWZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYE5lcGxhdG5cdTAwRkQgXHUwMTU5ZXRcdTAxMUJ6ZWM6IG11c1x1MDBFRCBrb25cdTAxMERpdCBuYSBcIiR7X2lzc3VlLnN1ZmZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImluY2x1ZGVzXCIpIHJldHVybiBgTmVwbGF0blx1MDBGRCBcdTAxNTlldFx1MDExQnplYzogbXVzXHUwMEVEIG9ic2Fob3ZhdCBcIiR7X2lzc3VlLmluY2x1ZGVzfVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBOZXBsYXRuXHUwMEZEIFx1MDE1OWV0XHUwMTFCemVjOiBtdXNcdTAwRUQgb2Rwb3ZcdTAwRURkYXQgdnpvcnUgJHtfaXNzdWUucGF0dGVybn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYE5lcGxhdG5cdTAwRkQgZm9ybVx1MDBFMXQgJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOZXBsYXRuXHUwMEU5IFx1MDEwRFx1MDBFRHNsbzogbXVzXHUwMEVEIGJcdTAwRkR0IG5cdTAwRTFzb2JrZW0gJHtpc3N1ZS5kaXZpc29yfWA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYE5lem5cdTAwRTFtXHUwMEU5IGtsXHUwMEVEXHUwMTBEZTogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgXCIsIFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfa2V5XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOZXBsYXRuXHUwMEZEIGtsXHUwMEVEXHUwMTBEIHYgJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3VuaW9uXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiTmVwbGF0blx1MDBGRCB2c3R1cFwiO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZWxlbWVudFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgTmVwbGF0blx1MDBFMSBob2Rub3RhIHYgJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOZXBsYXRuXHUwMEZEIHZzdHVwYDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJ0ZWduXCIsXG4gICAgICAgICAgICB2ZXJiOiBcImhhdmRlXCJcbiAgICAgICAgfSxcbiAgICAgICAgZmlsZToge1xuICAgICAgICAgICAgdW5pdDogXCJieXRlc1wiLFxuICAgICAgICAgICAgdmVyYjogXCJoYXZkZVwiXG4gICAgICAgIH0sXG4gICAgICAgIGFycmF5OiB7XG4gICAgICAgICAgICB1bml0OiBcImVsZW1lbnRlclwiLFxuICAgICAgICAgICAgdmVyYjogXCJpbmRlaG9sZHRcIlxuICAgICAgICB9LFxuICAgICAgICBzZXQ6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiZWxlbWVudGVyXCIsXG4gICAgICAgICAgICB2ZXJiOiBcImluZGVob2xkdFwiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGNvbnN0IFR5cGVOYW1lcyA9IHtcbiAgICAgICAgc3RyaW5nOiBcInN0cmVuZ1wiLFxuICAgICAgICBudW1iZXI6IFwidGFsXCIsXG4gICAgICAgIGJvb2xlYW46IFwiYm9vbGVhblwiLFxuICAgICAgICBhcnJheTogXCJsaXN0ZVwiLFxuICAgICAgICBvYmplY3Q6IFwib2JqZWt0XCIsXG4gICAgICAgIHNldDogXCJzXHUwMEU2dFwiLFxuICAgICAgICBmaWxlOiBcImZpbFwiXG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgZnVuY3Rpb24gZ2V0VHlwZU5hbWUodHlwZSkge1xuICAgICAgICByZXR1cm4gVHlwZU5hbWVzW3R5cGVdID8/IHR5cGU7XG4gICAgfVxuICAgIGNvbnN0IHBhcnNlZFR5cGUgPSAoZGF0YSk9PntcbiAgICAgICAgY29uc3QgdCA9IHR5cGVvZiBkYXRhO1xuICAgICAgICBzd2l0Y2godCl7XG4gICAgICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gTnVtYmVyLmlzTmFOKGRhdGEpID8gXCJOYU5cIiA6IFwidGFsXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm9iamVjdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcImxpc3RlXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGEgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm51bGxcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKGRhdGEpICE9PSBPYmplY3QucHJvdG90eXBlICYmIGRhdGEuY29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwib2JqZWt0XCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcImlucHV0XCIsXG4gICAgICAgIGVtYWlsOiBcImUtbWFpbGFkcmVzc2VcIixcbiAgICAgICAgdXJsOiBcIlVSTFwiLFxuICAgICAgICBlbW9qaTogXCJlbW9qaVwiLFxuICAgICAgICB1dWlkOiBcIlVVSURcIixcbiAgICAgICAgdXVpZHY0OiBcIlVVSUR2NFwiLFxuICAgICAgICB1dWlkdjY6IFwiVVVJRHY2XCIsXG4gICAgICAgIG5hbm9pZDogXCJuYW5vaWRcIixcbiAgICAgICAgZ3VpZDogXCJHVUlEXCIsXG4gICAgICAgIGN1aWQ6IFwiY3VpZFwiLFxuICAgICAgICBjdWlkMjogXCJjdWlkMlwiLFxuICAgICAgICB1bGlkOiBcIlVMSURcIixcbiAgICAgICAgeGlkOiBcIlhJRFwiLFxuICAgICAgICBrc3VpZDogXCJLU1VJRFwiLFxuICAgICAgICBkYXRldGltZTogXCJJU08gZGF0by0gb2cga2xva2tlc2xcdTAwRTZ0XCIsXG4gICAgICAgIGRhdGU6IFwiSVNPLWRhdG9cIixcbiAgICAgICAgdGltZTogXCJJU08ta2xva2tlc2xcdTAwRTZ0XCIsXG4gICAgICAgIGR1cmF0aW9uOiBcIklTTy12YXJpZ2hlZFwiLFxuICAgICAgICBpcHY0OiBcIklQdjQtb21yXHUwMEU1ZGVcIixcbiAgICAgICAgaXB2NjogXCJJUHY2LW9tclx1MDBFNWRlXCIsXG4gICAgICAgIGNpZHJ2NDogXCJJUHY0LXNwZWt0cnVtXCIsXG4gICAgICAgIGNpZHJ2NjogXCJJUHY2LXNwZWt0cnVtXCIsXG4gICAgICAgIGJhc2U2NDogXCJiYXNlNjQta29kZXQgc3RyZW5nXCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJiYXNlNjR1cmwta29kZXQgc3RyZW5nXCIsXG4gICAgICAgIGpzb25fc3RyaW5nOiBcIkpTT04tc3RyZW5nXCIsXG4gICAgICAgIGUxNjQ6IFwiRS4xNjQtbnVtbWVyXCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJpbnB1dFwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBVZ3lsZGlndCBpbnB1dDogZm9ydmVudGVkZSAke2dldFR5cGVOYW1lKGlzc3VlLmV4cGVjdGVkKX0sIGZpayAke2dldFR5cGVOYW1lKHBhcnNlZFR5cGUoaXNzdWUuaW5wdXQpKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBVZ3lsZGlnIHZcdTAwRTZyZGk6IGZvcnZlbnRlZGUgJHt1dGlsLnN0cmluZ2lmeVByaW1pdGl2ZShpc3N1ZS52YWx1ZXNbMF0pfWA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBVZ3lsZGlndCB2YWxnOiBmb3J2ZW50ZWRlIGVuIGFmIGZcdTAwRjhsZ2VuZGUgJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIjw9XCIgOiBcIjxcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG9yaWdpbiA9IGdldFR5cGVOYW1lKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgRm9yIHN0b3I6IGZvcnZlbnRlZGUgJHtvcmlnaW4gPz8gXCJ2YWx1ZVwifSAke3NpemluZy52ZXJifSAke2Fkan0gJHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXQgPz8gXCJlbGVtZW50ZXJcIn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYEZvciBzdG9yOiBmb3J2ZW50ZWRlICR7b3JpZ2luID8/IFwidmFsdWVcIn0gaGF2ZGUgJHthZGp9ICR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInRvb19zbWFsbFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI+PVwiIDogXCI+XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBvcmlnaW4gPSBnZXRUeXBlTmFtZShpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYEZvciBsaWxsZTogZm9ydmVudGVkZSAke29yaWdpbn0gJHtzaXppbmcudmVyYn0gJHthZGp9ICR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0fWA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBGb3IgbGlsbGU6IGZvcnZlbnRlZGUgJHtvcmlnaW59IGhhdmRlICR7YWRqfSAke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2Zvcm1hdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgX2lzc3VlID0gaXNzdWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInN0YXJ0c193aXRoXCIpIHJldHVybiBgVWd5bGRpZyBzdHJlbmc6IHNrYWwgc3RhcnRlIG1lZCBcIiR7X2lzc3VlLnByZWZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYFVneWxkaWcgc3RyZW5nOiBza2FsIGVuZGUgbWVkIFwiJHtfaXNzdWUuc3VmZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBVZ3lsZGlnIHN0cmVuZzogc2thbCBpbmRlaG9sZGUgXCIke19pc3N1ZS5pbmNsdWRlc31cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInJlZ2V4XCIpIHJldHVybiBgVWd5bGRpZyBzdHJlbmc6IHNrYWwgbWF0Y2hlIG1cdTAwRjhuc3RlcmV0ICR7X2lzc3VlLnBhdHRlcm59YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBVZ3lsZGlnICR7Tm91bnNbX2lzc3VlLmZvcm1hdF0gPz8gaXNzdWUuZm9ybWF0fWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm5vdF9tdWx0aXBsZV9vZlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgVWd5bGRpZ3QgdGFsOiBza2FsIHZcdTAwRTZyZSBkZWxlbGlndCBtZWQgJHtpc3N1ZS5kaXZpc29yfWA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYCR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJVa2VuZHRlIG5cdTAwRjhnbGVyXCIgOiBcIlVrZW5kdCBuXHUwMEY4Z2xlXCJ9OiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIiwgXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFVneWxkaWcgblx1MDBGOGdsZSBpICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF91bmlvblwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIlVneWxkaWd0IGlucHV0OiBtYXRjaGVyIGluZ2VuIGFmIGRlIHRpbGxhZHRlIHR5cGVyXCI7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9lbGVtZW50XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBVZ3lsZGlnIHZcdTAwRTZyZGkgaSAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFVneWxkaWd0IGlucHV0YDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJaZWljaGVuXCIsXG4gICAgICAgICAgICB2ZXJiOiBcInp1IGhhYmVuXCJcbiAgICAgICAgfSxcbiAgICAgICAgZmlsZToge1xuICAgICAgICAgICAgdW5pdDogXCJCeXRlc1wiLFxuICAgICAgICAgICAgdmVyYjogXCJ6dSBoYWJlblwiXG4gICAgICAgIH0sXG4gICAgICAgIGFycmF5OiB7XG4gICAgICAgICAgICB1bml0OiBcIkVsZW1lbnRlXCIsXG4gICAgICAgICAgICB2ZXJiOiBcInp1IGhhYmVuXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcIkVsZW1lbnRlXCIsXG4gICAgICAgICAgICB2ZXJiOiBcInp1IGhhYmVuXCJcbiAgICAgICAgfVxuICAgIH07XG4gICAgZnVuY3Rpb24gZ2V0U2l6aW5nKG9yaWdpbikge1xuICAgICAgICByZXR1cm4gU2l6YWJsZVtvcmlnaW5dID8/IG51bGw7XG4gICAgfVxuICAgIGNvbnN0IHBhcnNlZFR5cGUgPSAoZGF0YSk9PntcbiAgICAgICAgY29uc3QgdCA9IHR5cGVvZiBkYXRhO1xuICAgICAgICBzd2l0Y2godCl7XG4gICAgICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gTnVtYmVyLmlzTmFOKGRhdGEpID8gXCJOYU5cIiA6IFwiWmFobFwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJBcnJheVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJudWxsXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcIkVpbmdhYmVcIixcbiAgICAgICAgZW1haWw6IFwiRS1NYWlsLUFkcmVzc2VcIixcbiAgICAgICAgdXJsOiBcIlVSTFwiLFxuICAgICAgICBlbW9qaTogXCJFbW9qaVwiLFxuICAgICAgICB1dWlkOiBcIlVVSURcIixcbiAgICAgICAgdXVpZHY0OiBcIlVVSUR2NFwiLFxuICAgICAgICB1dWlkdjY6IFwiVVVJRHY2XCIsXG4gICAgICAgIG5hbm9pZDogXCJuYW5vaWRcIixcbiAgICAgICAgZ3VpZDogXCJHVUlEXCIsXG4gICAgICAgIGN1aWQ6IFwiY3VpZFwiLFxuICAgICAgICBjdWlkMjogXCJjdWlkMlwiLFxuICAgICAgICB1bGlkOiBcIlVMSURcIixcbiAgICAgICAgeGlkOiBcIlhJRFwiLFxuICAgICAgICBrc3VpZDogXCJLU1VJRFwiLFxuICAgICAgICBkYXRldGltZTogXCJJU08tRGF0dW0gdW5kIC1VaHJ6ZWl0XCIsXG4gICAgICAgIGRhdGU6IFwiSVNPLURhdHVtXCIsXG4gICAgICAgIHRpbWU6IFwiSVNPLVVocnplaXRcIixcbiAgICAgICAgZHVyYXRpb246IFwiSVNPLURhdWVyXCIsXG4gICAgICAgIGlwdjQ6IFwiSVB2NC1BZHJlc3NlXCIsXG4gICAgICAgIGlwdjY6IFwiSVB2Ni1BZHJlc3NlXCIsXG4gICAgICAgIGNpZHJ2NDogXCJJUHY0LUJlcmVpY2hcIixcbiAgICAgICAgY2lkcnY2OiBcIklQdjYtQmVyZWljaFwiLFxuICAgICAgICBiYXNlNjQ6IFwiQmFzZTY0LWNvZGllcnRlciBTdHJpbmdcIixcbiAgICAgICAgYmFzZTY0dXJsOiBcIkJhc2U2NC1VUkwtY29kaWVydGVyIFN0cmluZ1wiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJKU09OLVN0cmluZ1wiLFxuICAgICAgICBlMTY0OiBcIkUuMTY0LU51bW1lclwiLFxuICAgICAgICBqd3Q6IFwiSldUXCIsXG4gICAgICAgIHRlbXBsYXRlX2xpdGVyYWw6IFwiRWluZ2FiZVwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBVbmdcdTAwRkNsdGlnZSBFaW5nYWJlOiBlcndhcnRldCAke2lzc3VlLmV4cGVjdGVkfSwgZXJoYWx0ZW4gJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBVbmdcdTAwRkNsdGlnZSBFaW5nYWJlOiBlcndhcnRldCAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYFVuZ1x1MDBGQ2x0aWdlIE9wdGlvbjogZXJ3YXJ0ZXQgZWluZSB2b24gJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIjw9XCIgOiBcIjxcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgWnUgZ3JvXHUwMERGOiBlcndhcnRldCwgZGFzcyAke2lzc3VlLm9yaWdpbiA/PyBcIldlcnRcIn0gJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXQgPz8gXCJFbGVtZW50ZVwifSBoYXRgO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFp1IGdyb1x1MDBERjogZXJ3YXJ0ZXQsIGRhc3MgJHtpc3N1ZS5vcmlnaW4gPz8gXCJXZXJ0XCJ9ICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSBpc3RgO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJ0b29fc21hbGxcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPj1cIiA6IFwiPlwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBadSBrbGVpbjogZXJ3YXJ0ZXQsIGRhc3MgJHtpc3N1ZS5vcmlnaW59ICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0fSBoYXRgO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgWnUga2xlaW46IGVyd2FydGV0LCBkYXNzICR7aXNzdWUub3JpZ2lufSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gaXN0YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSByZXR1cm4gYFVuZ1x1MDBGQ2x0aWdlciBTdHJpbmc6IG11c3MgbWl0IFwiJHtfaXNzdWUucHJlZml4fVwiIGJlZ2lubmVuYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiZW5kc193aXRoXCIpIHJldHVybiBgVW5nXHUwMEZDbHRpZ2VyIFN0cmluZzogbXVzcyBtaXQgXCIke19pc3N1ZS5zdWZmaXh9XCIgZW5kZW5gO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJpbmNsdWRlc1wiKSByZXR1cm4gYFVuZ1x1MDBGQ2x0aWdlciBTdHJpbmc6IG11c3MgXCIke19pc3N1ZS5pbmNsdWRlc31cIiBlbnRoYWx0ZW5gO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYFVuZ1x1MDBGQ2x0aWdlciBTdHJpbmc6IG11c3MgZGVtIE11c3RlciAke19pc3N1ZS5wYXR0ZXJufSBlbnRzcHJlY2hlbmA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgVW5nXHUwMEZDbHRpZzogJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBVbmdcdTAwRkNsdGlnZSBaYWhsOiBtdXNzIGVpbiBWaWVsZmFjaGVzIHZvbiAke2lzc3VlLmRpdmlzb3J9IHNlaW5gO1xuICAgICAgICAgICAgY2FzZSBcInVucmVjb2duaXplZF9rZXlzXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGAke2lzc3VlLmtleXMubGVuZ3RoID4gMSA/IFwiVW5iZWthbm50ZSBTY2hsXHUwMEZDc3NlbFwiIDogXCJVbmJla2FubnRlciBTY2hsXHUwMEZDc3NlbFwifTogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgXCIsIFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfa2V5XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBVbmdcdTAwRkNsdGlnZXIgU2NobFx1MDBGQ3NzZWwgaW4gJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3VuaW9uXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiVW5nXHUwMEZDbHRpZ2UgRWluZ2FiZVwiO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZWxlbWVudFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgVW5nXHUwMEZDbHRpZ2VyIFdlcnQgaW4gJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBVbmdcdTAwRkNsdGlnZSBFaW5nYWJlYDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuZXhwb3J0IGNvbnN0IHBhcnNlZFR5cGUgPSAoZGF0YSk9PntcbiAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgc3dpdGNoKHQpe1xuICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIm51bWJlclwiO1xuICAgICAgICAgICAgfVxuICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiYXJyYXlcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGRhdGEgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKGRhdGEpICE9PSBPYmplY3QucHJvdG90eXBlICYmIGRhdGEuY29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0O1xufTtcbmNvbnN0IGVycm9yID0gKCk9PntcbiAgICBjb25zdCBTaXphYmxlID0ge1xuICAgICAgICBzdHJpbmc6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiY2hhcmFjdGVyc1wiLFxuICAgICAgICAgICAgdmVyYjogXCJ0byBoYXZlXCJcbiAgICAgICAgfSxcbiAgICAgICAgZmlsZToge1xuICAgICAgICAgICAgdW5pdDogXCJieXRlc1wiLFxuICAgICAgICAgICAgdmVyYjogXCJ0byBoYXZlXCJcbiAgICAgICAgfSxcbiAgICAgICAgYXJyYXk6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiaXRlbXNcIixcbiAgICAgICAgICAgIHZlcmI6IFwidG8gaGF2ZVwiXG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDogXCJpdGVtc1wiLFxuICAgICAgICAgICAgdmVyYjogXCJ0byBoYXZlXCJcbiAgICAgICAgfVxuICAgIH07XG4gICAgZnVuY3Rpb24gZ2V0U2l6aW5nKG9yaWdpbikge1xuICAgICAgICByZXR1cm4gU2l6YWJsZVtvcmlnaW5dID8/IG51bGw7XG4gICAgfVxuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJpbnB1dFwiLFxuICAgICAgICBlbWFpbDogXCJlbWFpbCBhZGRyZXNzXCIsXG4gICAgICAgIHVybDogXCJVUkxcIixcbiAgICAgICAgZW1vamk6IFwiZW1vamlcIixcbiAgICAgICAgdXVpZDogXCJVVUlEXCIsXG4gICAgICAgIHV1aWR2NDogXCJVVUlEdjRcIixcbiAgICAgICAgdXVpZHY2OiBcIlVVSUR2NlwiLFxuICAgICAgICBuYW5vaWQ6IFwibmFub2lkXCIsXG4gICAgICAgIGd1aWQ6IFwiR1VJRFwiLFxuICAgICAgICBjdWlkOiBcImN1aWRcIixcbiAgICAgICAgY3VpZDI6IFwiY3VpZDJcIixcbiAgICAgICAgdWxpZDogXCJVTElEXCIsXG4gICAgICAgIHhpZDogXCJYSURcIixcbiAgICAgICAga3N1aWQ6IFwiS1NVSURcIixcbiAgICAgICAgZGF0ZXRpbWU6IFwiSVNPIGRhdGV0aW1lXCIsXG4gICAgICAgIGRhdGU6IFwiSVNPIGRhdGVcIixcbiAgICAgICAgdGltZTogXCJJU08gdGltZVwiLFxuICAgICAgICBkdXJhdGlvbjogXCJJU08gZHVyYXRpb25cIixcbiAgICAgICAgaXB2NDogXCJJUHY0IGFkZHJlc3NcIixcbiAgICAgICAgaXB2NjogXCJJUHY2IGFkZHJlc3NcIixcbiAgICAgICAgY2lkcnY0OiBcIklQdjQgcmFuZ2VcIixcbiAgICAgICAgY2lkcnY2OiBcIklQdjYgcmFuZ2VcIixcbiAgICAgICAgYmFzZTY0OiBcImJhc2U2NC1lbmNvZGVkIHN0cmluZ1wiLFxuICAgICAgICBiYXNlNjR1cmw6IFwiYmFzZTY0dXJsLWVuY29kZWQgc3RyaW5nXCIsXG4gICAgICAgIGpzb25fc3RyaW5nOiBcIkpTT04gc3RyaW5nXCIsXG4gICAgICAgIGUxNjQ6IFwiRS4xNjQgbnVtYmVyXCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJpbnB1dFwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBJbnZhbGlkIGlucHV0OiBleHBlY3RlZCAke2lzc3VlLmV4cGVjdGVkfSwgcmVjZWl2ZWQgJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBJbnZhbGlkIGlucHV0OiBleHBlY3RlZCAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYEludmFsaWQgb3B0aW9uOiBleHBlY3RlZCBvbmUgb2YgJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIjw9XCIgOiBcIjxcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgVG9vIGJpZzogZXhwZWN0ZWQgJHtpc3N1ZS5vcmlnaW4gPz8gXCJ2YWx1ZVwifSB0byBoYXZlICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0ID8/IFwiZWxlbWVudHNcIn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFRvbyBiaWc6IGV4cGVjdGVkICR7aXNzdWUub3JpZ2luID8/IFwidmFsdWVcIn0gdG8gYmUgJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIj49XCIgOiBcIj5cIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgVG9vIHNtYWxsOiBleHBlY3RlZCAke2lzc3VlLm9yaWdpbn0gdG8gaGF2ZSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdH1gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgVG9vIHNtYWxsOiBleHBlY3RlZCAke2lzc3VlLm9yaWdpbn0gdG8gYmUgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYEludmFsaWQgc3RyaW5nOiBtdXN0IHN0YXJ0IHdpdGggXCIke19pc3N1ZS5wcmVmaXh9XCJgO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYEludmFsaWQgc3RyaW5nOiBtdXN0IGVuZCB3aXRoIFwiJHtfaXNzdWUuc3VmZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBJbnZhbGlkIHN0cmluZzogbXVzdCBpbmNsdWRlIFwiJHtfaXNzdWUuaW5jbHVkZXN9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYEludmFsaWQgc3RyaW5nOiBtdXN0IG1hdGNoIHBhdHRlcm4gJHtfaXNzdWUucGF0dGVybn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYEludmFsaWQgJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBJbnZhbGlkIG51bWJlcjogbXVzdCBiZSBhIG11bHRpcGxlIG9mICR7aXNzdWUuZGl2aXNvcn1gO1xuICAgICAgICAgICAgY2FzZSBcInVucmVjb2duaXplZF9rZXlzXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBVbnJlY29nbml6ZWQga2V5JHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcInNcIiA6IFwiXCJ9OiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIiwgXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYEludmFsaWQga2V5IGluICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF91bmlvblwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIkludmFsaWQgaW5wdXRcIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYEludmFsaWQgdmFsdWUgaW4gJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBJbnZhbGlkIGlucHV0YDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuZXhwb3J0IGNvbnN0IHBhcnNlZFR5cGUgPSAoZGF0YSk9PntcbiAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgc3dpdGNoKHQpe1xuICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIm5vbWJyb1wiO1xuICAgICAgICAgICAgfVxuICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwidGFiZWxvXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcInNlbnZhbG9yYVwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKGRhdGEpICE9PSBPYmplY3QucHJvdG90eXBlICYmIGRhdGEuY29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0O1xufTtcbmNvbnN0IGVycm9yID0gKCk9PntcbiAgICBjb25zdCBTaXphYmxlID0ge1xuICAgICAgICBzdHJpbmc6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwia2FyYWt0cm9qblwiLFxuICAgICAgICAgICAgdmVyYjogXCJoYXZpXCJcbiAgICAgICAgfSxcbiAgICAgICAgZmlsZToge1xuICAgICAgICAgICAgdW5pdDogXCJiYWp0b2puXCIsXG4gICAgICAgICAgICB2ZXJiOiBcImhhdmlcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJlbGVtZW50b2puXCIsXG4gICAgICAgICAgICB2ZXJiOiBcImhhdmlcIlxuICAgICAgICB9LFxuICAgICAgICBzZXQ6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiZWxlbWVudG9qblwiLFxuICAgICAgICAgICAgdmVyYjogXCJoYXZpXCJcbiAgICAgICAgfVxuICAgIH07XG4gICAgZnVuY3Rpb24gZ2V0U2l6aW5nKG9yaWdpbikge1xuICAgICAgICByZXR1cm4gU2l6YWJsZVtvcmlnaW5dID8/IG51bGw7XG4gICAgfVxuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJlbmlnb1wiLFxuICAgICAgICBlbWFpbDogXCJyZXRhZHJlc29cIixcbiAgICAgICAgdXJsOiBcIlVSTFwiLFxuICAgICAgICBlbW9qaTogXCJlbW9cdTAxMURpb1wiLFxuICAgICAgICB1dWlkOiBcIlVVSURcIixcbiAgICAgICAgdXVpZHY0OiBcIlVVSUR2NFwiLFxuICAgICAgICB1dWlkdjY6IFwiVVVJRHY2XCIsXG4gICAgICAgIG5hbm9pZDogXCJuYW5vaWRcIixcbiAgICAgICAgZ3VpZDogXCJHVUlEXCIsXG4gICAgICAgIGN1aWQ6IFwiY3VpZFwiLFxuICAgICAgICBjdWlkMjogXCJjdWlkMlwiLFxuICAgICAgICB1bGlkOiBcIlVMSURcIixcbiAgICAgICAgeGlkOiBcIlhJRFwiLFxuICAgICAgICBrc3VpZDogXCJLU1VJRFwiLFxuICAgICAgICBkYXRldGltZTogXCJJU08tZGF0b3RlbXBvXCIsXG4gICAgICAgIGRhdGU6IFwiSVNPLWRhdG9cIixcbiAgICAgICAgdGltZTogXCJJU08tdGVtcG9cIixcbiAgICAgICAgZHVyYXRpb246IFwiSVNPLWRhXHUwMTZEcm9cIixcbiAgICAgICAgaXB2NDogXCJJUHY0LWFkcmVzb1wiLFxuICAgICAgICBpcHY2OiBcIklQdjYtYWRyZXNvXCIsXG4gICAgICAgIGNpZHJ2NDogXCJJUHY0LXJhbmdvXCIsXG4gICAgICAgIGNpZHJ2NjogXCJJUHY2LXJhbmdvXCIsXG4gICAgICAgIGJhc2U2NDogXCI2NC11bWUga29kaXRhIGthcmFrdHJhcm9cIixcbiAgICAgICAgYmFzZTY0dXJsOiBcIlVSTC02NC11bWUga29kaXRhIGthcmFrdHJhcm9cIixcbiAgICAgICAganNvbl9zdHJpbmc6IFwiSlNPTi1rYXJha3RyYXJvXCIsXG4gICAgICAgIGUxNjQ6IFwiRS4xNjQtbm9tYnJvXCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJlbmlnb1wiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOZXZhbGlkYSBlbmlnbzogYXRlbmRpXHUwMTFEaXMgJHtpc3N1ZS5leHBlY3RlZH0sIHJpY2V2aVx1MDExRGlzICR7cGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgTmV2YWxpZGEgZW5pZ286IGF0ZW5kaVx1MDExRGlzICR7dXRpbC5zdHJpbmdpZnlQcmltaXRpdmUoaXNzdWUudmFsdWVzWzBdKX1gO1xuICAgICAgICAgICAgICAgIHJldHVybiBgTmV2YWxpZGEgb3BjaW86IGF0ZW5kaVx1MDExRGlzIHVudSBlbCAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS52YWx1ZXMsIFwifFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPD1cIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykgcmV0dXJuIGBUcm8gZ3JhbmRhOiBhdGVuZGlcdTAxMURpcyBrZSAke2lzc3VlLm9yaWdpbiA/PyBcInZhbG9yb1wifSBoYXZ1ICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0ID8/IFwiZWxlbWVudG9qblwifWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgVHJvIGdyYW5kYTogYXRlbmRpXHUwMTFEaXMga2UgJHtpc3N1ZS5vcmlnaW4gPz8gXCJ2YWxvcm9cIn0gaGF2dSAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJ0b29fc21hbGxcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPj1cIiA6IFwiPlwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBUcm8gbWFsZ3JhbmRhOiBhdGVuZGlcdTAxMURpcyBrZSAke2lzc3VlLm9yaWdpbn0gaGF2dSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdH1gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgVHJvIG1hbGdyYW5kYTogYXRlbmRpXHUwMTFEaXMga2UgJHtpc3N1ZS5vcmlnaW59IGVzdHUgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSByZXR1cm4gYE5ldmFsaWRhIGthcmFrdHJhcm86IGRldmFzIGtvbWVuY2lcdTAxMURpIHBlciBcIiR7X2lzc3VlLnByZWZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYE5ldmFsaWRhIGthcmFrdHJhcm86IGRldmFzIGZpbmlcdTAxMURpIHBlciBcIiR7X2lzc3VlLnN1ZmZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImluY2x1ZGVzXCIpIHJldHVybiBgTmV2YWxpZGEga2FyYWt0cmFybzogZGV2YXMgaW5rbHV6aXZpIFwiJHtfaXNzdWUuaW5jbHVkZXN9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYE5ldmFsaWRhIGthcmFrdHJhcm86IGRldmFzIGtvbmdydWkga3VuIGxhIG1vZGVsbyAke19pc3N1ZS5wYXR0ZXJufWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgTmV2YWxpZGEgJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOZXZhbGlkYSBub21icm86IGRldmFzIGVzdGkgb2JsbyBkZSAke2lzc3VlLmRpdmlzb3J9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ1bnJlY29nbml6ZWRfa2V5c1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgTmVrb25hdGEke2lzc3VlLmtleXMubGVuZ3RoID4gMSA/IFwialwiIDogXCJcIn0gXHUwMTVEbG9zaWxvJHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcImpcIiA6IFwiXCJ9OiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIiwgXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYE5ldmFsaWRhIFx1MDE1RGxvc2lsbyBlbiAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJOZXZhbGlkYSBlbmlnb1wiO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZWxlbWVudFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgTmV2YWxpZGEgdmFsb3JvIGVuICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBgTmV2YWxpZGEgZW5pZ29gO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBsb2NhbGVFcnJvcjogZXJyb3IoKVxuICAgIH07XG59XG4iLCAiaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi4vY29yZS91dGlsLmpzXCI7XG5jb25zdCBlcnJvciA9ICgpPT57XG4gICAgY29uc3QgU2l6YWJsZSA9IHtcbiAgICAgICAgc3RyaW5nOiB7XG4gICAgICAgICAgICB1bml0OiBcImNhcmFjdGVyZXNcIixcbiAgICAgICAgICAgIHZlcmI6IFwidGVuZXJcIlxuICAgICAgICB9LFxuICAgICAgICBmaWxlOiB7XG4gICAgICAgICAgICB1bml0OiBcImJ5dGVzXCIsXG4gICAgICAgICAgICB2ZXJiOiBcInRlbmVyXCJcbiAgICAgICAgfSxcbiAgICAgICAgYXJyYXk6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiZWxlbWVudG9zXCIsXG4gICAgICAgICAgICB2ZXJiOiBcInRlbmVyXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcImVsZW1lbnRvc1wiLFxuICAgICAgICAgICAgdmVyYjogXCJ0ZW5lclwiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGNvbnN0IFR5cGVOYW1lcyA9IHtcbiAgICAgICAgc3RyaW5nOiBcInRleHRvXCIsXG4gICAgICAgIG51bWJlcjogXCJuXHUwMEZBbWVyb1wiLFxuICAgICAgICBib29sZWFuOiBcImJvb2xlYW5vXCIsXG4gICAgICAgIGFycmF5OiBcImFycmVnbG9cIixcbiAgICAgICAgb2JqZWN0OiBcIm9iamV0b1wiLFxuICAgICAgICBzZXQ6IFwiY29uanVudG9cIixcbiAgICAgICAgZmlsZTogXCJhcmNoaXZvXCIsXG4gICAgICAgIGRhdGU6IFwiZmVjaGFcIixcbiAgICAgICAgYmlnaW50OiBcIm5cdTAwRkFtZXJvIGdyYW5kZVwiLFxuICAgICAgICBzeW1ib2w6IFwic1x1MDBFRG1ib2xvXCIsXG4gICAgICAgIHVuZGVmaW5lZDogXCJpbmRlZmluaWRvXCIsXG4gICAgICAgIG51bGw6IFwibnVsb1wiLFxuICAgICAgICBmdW5jdGlvbjogXCJmdW5jaVx1MDBGM25cIixcbiAgICAgICAgbWFwOiBcIm1hcGFcIixcbiAgICAgICAgcmVjb3JkOiBcInJlZ2lzdHJvXCIsXG4gICAgICAgIHR1cGxlOiBcInR1cGxhXCIsXG4gICAgICAgIGVudW06IFwiZW51bWVyYWNpXHUwMEYzblwiLFxuICAgICAgICB1bmlvbjogXCJ1bmlcdTAwRjNuXCIsXG4gICAgICAgIGxpdGVyYWw6IFwibGl0ZXJhbFwiLFxuICAgICAgICBwcm9taXNlOiBcInByb21lc2FcIixcbiAgICAgICAgdm9pZDogXCJ2YWNcdTAwRURvXCIsXG4gICAgICAgIG5ldmVyOiBcIm51bmNhXCIsXG4gICAgICAgIHVua25vd246IFwiZGVzY29ub2NpZG9cIixcbiAgICAgICAgYW55OiBcImN1YWxxdWllcmFcIlxuICAgIH07XG4gICAgZnVuY3Rpb24gZ2V0U2l6aW5nKG9yaWdpbikge1xuICAgICAgICByZXR1cm4gU2l6YWJsZVtvcmlnaW5dID8/IG51bGw7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGdldFR5cGVOYW1lKHR5cGUpIHtcbiAgICAgICAgcmV0dXJuIFR5cGVOYW1lc1t0eXBlXSA/PyB0eXBlO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWRUeXBlID0gKGRhdGEpPT57XG4gICAgICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICAgICAgc3dpdGNoKHQpe1xuICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIm51bWJlclwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJhcnJheVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJudWxsXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJvYmplY3RcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHQ7XG4gICAgfTtcbiAgICBjb25zdCBOb3VucyA9IHtcbiAgICAgICAgcmVnZXg6IFwiZW50cmFkYVwiLFxuICAgICAgICBlbWFpbDogXCJkaXJlY2NpXHUwMEYzbiBkZSBjb3JyZW8gZWxlY3RyXHUwMEYzbmljb1wiLFxuICAgICAgICB1cmw6IFwiVVJMXCIsXG4gICAgICAgIGVtb2ppOiBcImVtb2ppXCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcImZlY2hhIHkgaG9yYSBJU09cIixcbiAgICAgICAgZGF0ZTogXCJmZWNoYSBJU09cIixcbiAgICAgICAgdGltZTogXCJob3JhIElTT1wiLFxuICAgICAgICBkdXJhdGlvbjogXCJkdXJhY2lcdTAwRjNuIElTT1wiLFxuICAgICAgICBpcHY0OiBcImRpcmVjY2lcdTAwRjNuIElQdjRcIixcbiAgICAgICAgaXB2NjogXCJkaXJlY2NpXHUwMEYzbiBJUHY2XCIsXG4gICAgICAgIGNpZHJ2NDogXCJyYW5nbyBJUHY0XCIsXG4gICAgICAgIGNpZHJ2NjogXCJyYW5nbyBJUHY2XCIsXG4gICAgICAgIGJhc2U2NDogXCJjYWRlbmEgY29kaWZpY2FkYSBlbiBiYXNlNjRcIixcbiAgICAgICAgYmFzZTY0dXJsOiBcIlVSTCBjb2RpZmljYWRhIGVuIGJhc2U2NFwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJjYWRlbmEgSlNPTlwiLFxuICAgICAgICBlMTY0OiBcIm5cdTAwRkFtZXJvIEUuMTY0XCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJlbnRyYWRhXCJcbiAgICB9O1xuICAgIHJldHVybiAoaXNzdWUpPT57XG4gICAgICAgIHN3aXRjaChpc3N1ZS5jb2RlKXtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3R5cGVcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYEVudHJhZGEgaW52XHUwMEUxbGlkYTogc2UgZXNwZXJhYmEgJHtnZXRUeXBlTmFtZShpc3N1ZS5leHBlY3RlZCl9LCByZWNpYmlkbyAke2dldFR5cGVOYW1lKHBhcnNlZFR5cGUoaXNzdWUuaW5wdXQpKX1gO1xuICAgICAgICAgICAgLy8gcmV0dXJuIGBFbnRyYWRhIGludlx1MDBFMWxpZGE6IHNlIGVzcGVyYWJhICR7aXNzdWUuZXhwZWN0ZWR9LCByZWNpYmlkbyAke3V0aWwuZ2V0UGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgRW50cmFkYSBpbnZcdTAwRTFsaWRhOiBzZSBlc3BlcmFiYSAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYE9wY2lcdTAwRjNuIGludlx1MDBFMWxpZGE6IHNlIGVzcGVyYWJhIHVuYSBkZSAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS52YWx1ZXMsIFwifFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPD1cIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3JpZ2luID0gZ2V0VHlwZU5hbWUoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykgcmV0dXJuIGBEZW1hc2lhZG8gZ3JhbmRlOiBzZSBlc3BlcmFiYSBxdWUgJHtvcmlnaW4gPz8gXCJ2YWxvclwifSB0dXZpZXJhICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0ID8/IFwiZWxlbWVudG9zXCJ9YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBEZW1hc2lhZG8gZ3JhbmRlOiBzZSBlc3BlcmFiYSBxdWUgJHtvcmlnaW4gPz8gXCJ2YWxvclwifSBmdWVyYSAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJ0b29fc21hbGxcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPj1cIiA6IFwiPlwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3JpZ2luID0gZ2V0VHlwZU5hbWUoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBEZW1hc2lhZG8gcGVxdWVcdTAwRjFvOiBzZSBlc3BlcmFiYSBxdWUgJHtvcmlnaW59IHR1dmllcmEgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXR9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYERlbWFzaWFkbyBwZXF1ZVx1MDBGMW86IHNlIGVzcGVyYWJhIHF1ZSAke29yaWdpbn0gZnVlcmEgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSByZXR1cm4gYENhZGVuYSBpbnZcdTAwRTFsaWRhOiBkZWJlIGNvbWVuemFyIGNvbiBcIiR7X2lzc3VlLnByZWZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYENhZGVuYSBpbnZcdTAwRTFsaWRhOiBkZWJlIHRlcm1pbmFyIGVuIFwiJHtfaXNzdWUuc3VmZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBDYWRlbmEgaW52XHUwMEUxbGlkYTogZGViZSBpbmNsdWlyIFwiJHtfaXNzdWUuaW5jbHVkZXN9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYENhZGVuYSBpbnZcdTAwRTFsaWRhOiBkZWJlIGNvaW5jaWRpciBjb24gZWwgcGF0clx1MDBGM24gJHtfaXNzdWUucGF0dGVybn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYEludlx1MDBFMWxpZG8gJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOXHUwMEZBbWVybyBpbnZcdTAwRTFsaWRvOiBkZWJlIHNlciBtXHUwMEZBbHRpcGxvIGRlICR7aXNzdWUuZGl2aXNvcn1gO1xuICAgICAgICAgICAgY2FzZSBcInVucmVjb2duaXplZF9rZXlzXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBMbGF2ZSR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJzXCIgOiBcIlwifSBkZXNjb25vY2lkYSR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJzXCIgOiBcIlwifTogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgXCIsIFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfa2V5XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBMbGF2ZSBpbnZcdTAwRTFsaWRhIGVuICR7Z2V0VHlwZU5hbWUoaXNzdWUub3JpZ2luKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJFbnRyYWRhIGludlx1MDBFMWxpZGFcIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFZhbG9yIGludlx1MDBFMWxpZG8gZW4gJHtnZXRUeXBlTmFtZShpc3N1ZS5vcmlnaW4pfWA7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBgRW50cmFkYSBpbnZcdTAwRTFsaWRhYDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJcdTA2QTlcdTA2MjdcdTA2MzFcdTA2MjdcdTA2QTlcdTA2MkFcdTA2MzFcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwNjJGXHUwNjI3XHUwNjM0XHUwNjJBXHUwNjQ3IFx1MDYyOFx1MDYyN1x1MDYzNFx1MDYyRlwiXG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHUwNjI4XHUwNjI3XHUwNkNDXHUwNjJBXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MDYyRlx1MDYyN1x1MDYzNFx1MDYyQVx1MDY0NyBcdTA2MjhcdTA2MjdcdTA2MzRcdTA2MkZcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJcdTA2MjJcdTA2Q0NcdTA2MkFcdTA2NDVcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwNjJGXHUwNjI3XHUwNjM0XHUwNjJBXHUwNjQ3IFx1MDYyOFx1MDYyN1x1MDYzNFx1MDYyRlwiXG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDogXCJcdTA2MjJcdTA2Q0NcdTA2MkFcdTA2NDVcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwNjJGXHUwNjI3XHUwNjM0XHUwNjJBXHUwNjQ3IFx1MDYyOFx1MDYyN1x1MDYzNFx1MDYyRlwiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4pIHtcbiAgICAgICAgcmV0dXJuIFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWRUeXBlID0gKGRhdGEpPT57XG4gICAgICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICAgICAgc3dpdGNoKHQpe1xuICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIlx1MDYzOVx1MDYyRlx1MDYyRlwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTA2MjJcdTA2MzFcdTA2MjdcdTA2Q0NcdTA2NDdcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YoZGF0YSkgIT09IE9iamVjdC5wcm90b3R5cGUgJiYgZGF0YS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdDtcbiAgICB9O1xuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJcdTA2NDhcdTA2MzFcdTA2NDhcdTA2MkZcdTA2Q0NcIixcbiAgICAgICAgZW1haWw6IFwiXHUwNjIyXHUwNjJGXHUwNjMxXHUwNjMzIFx1MDYyN1x1MDZDQ1x1MDY0NVx1MDZDQ1x1MDY0NFwiLFxuICAgICAgICB1cmw6IFwiVVJMXCIsXG4gICAgICAgIGVtb2ppOiBcIlx1MDYyN1x1MDZDQ1x1MDY0NVx1MDY0OFx1MDYyQ1x1MDZDQ1wiLFxuICAgICAgICB1dWlkOiBcIlVVSURcIixcbiAgICAgICAgdXVpZHY0OiBcIlVVSUR2NFwiLFxuICAgICAgICB1dWlkdjY6IFwiVVVJRHY2XCIsXG4gICAgICAgIG5hbm9pZDogXCJuYW5vaWRcIixcbiAgICAgICAgZ3VpZDogXCJHVUlEXCIsXG4gICAgICAgIGN1aWQ6IFwiY3VpZFwiLFxuICAgICAgICBjdWlkMjogXCJjdWlkMlwiLFxuICAgICAgICB1bGlkOiBcIlVMSURcIixcbiAgICAgICAgeGlkOiBcIlhJRFwiLFxuICAgICAgICBrc3VpZDogXCJLU1VJRFwiLFxuICAgICAgICBkYXRldGltZTogXCJcdTA2MkFcdTA2MjdcdTA2MzFcdTA2Q0NcdTA2MkUgXHUwNjQ4IFx1MDYzMlx1MDY0NVx1MDYyN1x1MDY0NiBcdTA2MjdcdTA2Q0NcdTA2MzJcdTA2NDhcIixcbiAgICAgICAgZGF0ZTogXCJcdTA2MkFcdTA2MjdcdTA2MzFcdTA2Q0NcdTA2MkUgXHUwNjI3XHUwNkNDXHUwNjMyXHUwNjQ4XCIsXG4gICAgICAgIHRpbWU6IFwiXHUwNjMyXHUwNjQ1XHUwNjI3XHUwNjQ2IFx1MDYyN1x1MDZDQ1x1MDYzMlx1MDY0OFwiLFxuICAgICAgICBkdXJhdGlvbjogXCJcdTA2NDVcdTA2MkZcdTA2MkEgXHUwNjMyXHUwNjQ1XHUwNjI3XHUwNjQ2IFx1MDYyN1x1MDZDQ1x1MDYzMlx1MDY0OFwiLFxuICAgICAgICBpcHY0OiBcIklQdjQgXHUwNjIyXHUwNjJGXHUwNjMxXHUwNjMzXCIsXG4gICAgICAgIGlwdjY6IFwiSVB2NiBcdTA2MjJcdTA2MkZcdTA2MzFcdTA2MzNcIixcbiAgICAgICAgY2lkcnY0OiBcIklQdjQgXHUwNjJGXHUwNjI3XHUwNjQ1XHUwNjQ2XHUwNjQ3XCIsXG4gICAgICAgIGNpZHJ2NjogXCJJUHY2IFx1MDYyRlx1MDYyN1x1MDY0NVx1MDY0Nlx1MDY0N1wiLFxuICAgICAgICBiYXNlNjQ6IFwiYmFzZTY0LWVuY29kZWQgXHUwNjMxXHUwNjM0XHUwNjJBXHUwNjQ3XCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJiYXNlNjR1cmwtZW5jb2RlZCBcdTA2MzFcdTA2MzRcdTA2MkFcdTA2NDdcIixcbiAgICAgICAganNvbl9zdHJpbmc6IFwiSlNPTiBcdTA2MzFcdTA2MzRcdTA2MkFcdTA2NDdcIixcbiAgICAgICAgZTE2NDogXCJFLjE2NCBcdTA2MzlcdTA2MkZcdTA2MkZcIixcbiAgICAgICAgand0OiBcIkpXVFwiLFxuICAgICAgICB0ZW1wbGF0ZV9saXRlcmFsOiBcIlx1MDY0OFx1MDYzMVx1MDY0OFx1MDYyRlx1MDZDQ1wiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2NDhcdTA2MzFcdTA2NDhcdTA2MkZcdTA2Q0MgXHUwNjQ2XHUwNjI3XHUwNjQ1XHUwNjM5XHUwNjJBXHUwNjI4XHUwNjMxOiBcdTA2NDVcdTA2Q0NcdTIwMENcdTA2MjhcdTA2MjdcdTA2Q0NcdTA2MzNcdTA2MkEgJHtpc3N1ZS5leHBlY3RlZH0gXHUwNjQ1XHUwNkNDXHUyMDBDXHUwNjI4XHUwNjQ4XHUwNjJGXHUwNjBDICR7cGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9IFx1MDYyRlx1MDYzMVx1MDZDQ1x1MDYyN1x1MDY0MVx1MDYyQSBcdTA2MzRcdTA2MkZgO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDY0OFx1MDYzMVx1MDY0OFx1MDYyRlx1MDZDQyBcdTA2NDZcdTA2MjdcdTA2NDVcdTA2MzlcdTA2MkFcdTA2MjhcdTA2MzE6IFx1MDY0NVx1MDZDQ1x1MjAwQ1x1MDYyOFx1MDYyN1x1MDZDQ1x1MDYzM1x1MDYyQSAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9IFx1MDY0NVx1MDZDQ1x1MjAwQ1x1MDYyOFx1MDY0OFx1MDYyRmA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNkFGXHUwNjMyXHUwNkNDXHUwNjQ2XHUwNjQ3IFx1MDY0Nlx1MDYyN1x1MDY0NVx1MDYzOVx1MDYyQVx1MDYyOFx1MDYzMTogXHUwNjQ1XHUwNkNDXHUyMDBDXHUwNjI4XHUwNjI3XHUwNkNDXHUwNjMzXHUwNjJBIFx1MDZDQ1x1MDZBOVx1MDZDQyBcdTA2MjdcdTA2MzIgJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9IFx1MDY0NVx1MDZDQ1x1MjAwQ1x1MDYyOFx1MDY0OFx1MDYyRmA7XG4gICAgICAgICAgICBjYXNlIFwidG9vX2JpZ1wiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI8PVwiIDogXCI8XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDYyRVx1MDZDQ1x1MDY0NFx1MDZDQyBcdTA2MjhcdTA2MzJcdTA2MzFcdTA2QUY6ICR7aXNzdWUub3JpZ2luID8/IFwiXHUwNjQ1XHUwNjQyXHUwNjJGXHUwNjI3XHUwNjMxXCJ9IFx1MDYyOFx1MDYyN1x1MDZDQ1x1MDYyRiAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdCA/PyBcIlx1MDYzOVx1MDY0Nlx1MDYzNVx1MDYzMVwifSBcdTA2MjhcdTA2MjdcdTA2MzRcdTA2MkZgO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjJFXHUwNkNDXHUwNjQ0XHUwNkNDIFx1MDYyOFx1MDYzMlx1MDYzMVx1MDZBRjogJHtpc3N1ZS5vcmlnaW4gPz8gXCJcdTA2NDVcdTA2NDJcdTA2MkZcdTA2MjdcdTA2MzFcIn0gXHUwNjI4XHUwNjI3XHUwNkNDXHUwNjJGICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSBcdTA2MjhcdTA2MjdcdTA2MzRcdTA2MkZgO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJ0b29fc21hbGxcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPj1cIiA6IFwiPlwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2MkVcdTA2Q0NcdTA2NDRcdTA2Q0MgXHUwNkE5XHUwNjQ4XHUwNjg2XHUwNkE5OiAke2lzc3VlLm9yaWdpbn0gXHUwNjI4XHUwNjI3XHUwNkNDXHUwNjJGICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0fSBcdTA2MjhcdTA2MjdcdTA2MzRcdTA2MkZgO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjJFXHUwNkNDXHUwNjQ0XHUwNkNDIFx1MDZBOVx1MDY0OFx1MDY4Nlx1MDZBOTogJHtpc3N1ZS5vcmlnaW59IFx1MDYyOFx1MDYyN1x1MDZDQ1x1MDYyRiAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gXHUwNjI4XHUwNjI3XHUwNjM0XHUwNjJGYDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDYzMVx1MDYzNFx1MDYyQVx1MDY0NyBcdTA2NDZcdTA2MjdcdTA2NDVcdTA2MzlcdTA2MkFcdTA2MjhcdTA2MzE6IFx1MDYyOFx1MDYyN1x1MDZDQ1x1MDYyRiBcdTA2MjhcdTA2MjcgXCIke19pc3N1ZS5wcmVmaXh9XCIgXHUwNjM0XHUwNjMxXHUwNjQ4XHUwNjM5IFx1MDYzNFx1MDY0OFx1MDYyRmA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiZW5kc193aXRoXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjMxXHUwNjM0XHUwNjJBXHUwNjQ3IFx1MDY0Nlx1MDYyN1x1MDY0NVx1MDYzOVx1MDYyQVx1MDYyOFx1MDYzMTogXHUwNjI4XHUwNjI3XHUwNkNDXHUwNjJGIFx1MDYyOFx1MDYyNyBcIiR7X2lzc3VlLnN1ZmZpeH1cIiBcdTA2MkFcdTA2NDVcdTA2MjdcdTA2NDUgXHUwNjM0XHUwNjQ4XHUwNjJGYDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJpbmNsdWRlc1wiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDYzMVx1MDYzNFx1MDYyQVx1MDY0NyBcdTA2NDZcdTA2MjdcdTA2NDVcdTA2MzlcdTA2MkFcdTA2MjhcdTA2MzE6IFx1MDYyOFx1MDYyN1x1MDZDQ1x1MDYyRiBcdTA2MzRcdTA2MjdcdTA2NDVcdTA2NDQgXCIke19pc3N1ZS5pbmNsdWRlc31cIiBcdTA2MjhcdTA2MjdcdTA2MzRcdTA2MkZgO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInJlZ2V4XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjMxXHUwNjM0XHUwNjJBXHUwNjQ3IFx1MDY0Nlx1MDYyN1x1MDY0NVx1MDYzOVx1MDYyQVx1MDYyOFx1MDYzMTogXHUwNjI4XHUwNjI3XHUwNkNDXHUwNjJGIFx1MDYyOFx1MDYyNyBcdTA2MjdcdTA2NDRcdTA2QUZcdTA2NDhcdTA2Q0MgJHtfaXNzdWUucGF0dGVybn0gXHUwNjQ1XHUwNjM3XHUwNjI3XHUwNjI4XHUwNjQyXHUwNjJBIFx1MDYyRlx1MDYyN1x1MDYzNFx1MDYyQVx1MDY0NyBcdTA2MjhcdTA2MjdcdTA2MzRcdTA2MkZgO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9IFx1MDY0Nlx1MDYyN1x1MDY0NVx1MDYzOVx1MDYyQVx1MDYyOFx1MDYzMWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm5vdF9tdWx0aXBsZV9vZlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjM5XHUwNjJGXHUwNjJGIFx1MDY0Nlx1MDYyN1x1MDY0NVx1MDYzOVx1MDYyQVx1MDYyOFx1MDYzMTogXHUwNjI4XHUwNjI3XHUwNkNDXHUwNjJGIFx1MDY0NVx1MDYzNlx1MDYzMVx1MDYyOCAke2lzc3VlLmRpdmlzb3J9IFx1MDYyOFx1MDYyN1x1MDYzNFx1MDYyRmA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDZBOVx1MDY0NFx1MDZDQ1x1MDYyRiR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJcdTA2NDdcdTA2MjdcdTA2Q0NcIiA6IFwiXCJ9IFx1MDY0Nlx1MDYyN1x1MDYzNFx1MDY0Nlx1MDYyN1x1MDYzMzogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgXCIsIFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfa2V5XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2QTlcdTA2NDRcdTA2Q0NcdTA2MkYgXHUwNjQ2XHUwNjI3XHUwNjM0XHUwNjQ2XHUwNjI3XHUwNjMzIFx1MDYyRlx1MDYzMSAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDY0OFx1MDYzMVx1MDY0OFx1MDYyRlx1MDZDQyBcdTA2NDZcdTA2MjdcdTA2NDVcdTA2MzlcdTA2MkFcdTA2MjhcdTA2MzFgO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZWxlbWVudFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjQ1XHUwNjQyXHUwNjJGXHUwNjI3XHUwNjMxIFx1MDY0Nlx1MDYyN1x1MDY0NVx1MDYzOVx1MDYyQVx1MDYyOFx1MDYzMSBcdTA2MkZcdTA2MzEgJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2NDhcdTA2MzFcdTA2NDhcdTA2MkZcdTA2Q0MgXHUwNjQ2XHUwNjI3XHUwNjQ1XHUwNjM5XHUwNjJBXHUwNjI4XHUwNjMxYDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJtZXJra2lcdTAwRTRcIixcbiAgICAgICAgICAgIHN1YmplY3Q6IFwibWVya2tpam9ub25cIlxuICAgICAgICB9LFxuICAgICAgICBmaWxlOiB7XG4gICAgICAgICAgICB1bml0OiBcInRhdnVhXCIsXG4gICAgICAgICAgICBzdWJqZWN0OiBcInRpZWRvc3RvblwiXG4gICAgICAgIH0sXG4gICAgICAgIGFycmF5OiB7XG4gICAgICAgICAgICB1bml0OiBcImFsa2lvdGFcIixcbiAgICAgICAgICAgIHN1YmplY3Q6IFwibGlzdGFuXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcImFsa2lvdGFcIixcbiAgICAgICAgICAgIHN1YmplY3Q6IFwiam91a29uXCJcbiAgICAgICAgfSxcbiAgICAgICAgbnVtYmVyOiB7XG4gICAgICAgICAgICB1bml0OiBcIlwiLFxuICAgICAgICAgICAgc3ViamVjdDogXCJsdXZ1blwiXG4gICAgICAgIH0sXG4gICAgICAgIGJpZ2ludDoge1xuICAgICAgICAgICAgdW5pdDogXCJcIixcbiAgICAgICAgICAgIHN1YmplY3Q6IFwic3V1cmVuIGtva29uYWlzbHV2dW5cIlxuICAgICAgICB9LFxuICAgICAgICBpbnQ6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXCIsXG4gICAgICAgICAgICBzdWJqZWN0OiBcImtva29uYWlzbHV2dW5cIlxuICAgICAgICB9LFxuICAgICAgICBkYXRlOiB7XG4gICAgICAgICAgICB1bml0OiBcIlwiLFxuICAgICAgICAgICAgc3ViamVjdDogXCJwXHUwMEU0aXZcdTAwRTRtXHUwMEU0XHUwMEU0clx1MDBFNG5cIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIk5hTlwiIDogXCJudW1iZXJcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiYXJyYXlcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YoZGF0YSkgIT09IE9iamVjdC5wcm90b3R5cGUgJiYgZGF0YS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdDtcbiAgICB9O1xuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJzXHUwMEU0XHUwMEU0bm5cdTAwRjZsbGluZW4gbGF1c2VrZVwiLFxuICAgICAgICBlbWFpbDogXCJzXHUwMEU0aGtcdTAwRjZwb3N0aW9zb2l0ZVwiLFxuICAgICAgICB1cmw6IFwiVVJMLW9zb2l0ZVwiLFxuICAgICAgICBlbW9qaTogXCJlbW9qaVwiLFxuICAgICAgICB1dWlkOiBcIlVVSURcIixcbiAgICAgICAgdXVpZHY0OiBcIlVVSUR2NFwiLFxuICAgICAgICB1dWlkdjY6IFwiVVVJRHY2XCIsXG4gICAgICAgIG5hbm9pZDogXCJuYW5vaWRcIixcbiAgICAgICAgZ3VpZDogXCJHVUlEXCIsXG4gICAgICAgIGN1aWQ6IFwiY3VpZFwiLFxuICAgICAgICBjdWlkMjogXCJjdWlkMlwiLFxuICAgICAgICB1bGlkOiBcIlVMSURcIixcbiAgICAgICAgeGlkOiBcIlhJRFwiLFxuICAgICAgICBrc3VpZDogXCJLU1VJRFwiLFxuICAgICAgICBkYXRldGltZTogXCJJU08tYWlrYWxlaW1hXCIsXG4gICAgICAgIGRhdGU6IFwiSVNPLXBcdTAwRTRpdlx1MDBFNG1cdTAwRTRcdTAwRTRyXHUwMEU0XCIsXG4gICAgICAgIHRpbWU6IFwiSVNPLWFpa2FcIixcbiAgICAgICAgZHVyYXRpb246IFwiSVNPLWtlc3RvXCIsXG4gICAgICAgIGlwdjQ6IFwiSVB2NC1vc29pdGVcIixcbiAgICAgICAgaXB2NjogXCJJUHY2LW9zb2l0ZVwiLFxuICAgICAgICBjaWRydjQ6IFwiSVB2NC1hbHVlXCIsXG4gICAgICAgIGNpZHJ2NjogXCJJUHY2LWFsdWVcIixcbiAgICAgICAgYmFzZTY0OiBcImJhc2U2NC1rb29kYXR0dSBtZXJra2lqb25vXCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJiYXNlNjR1cmwta29vZGF0dHUgbWVya2tpam9ub1wiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJKU09OLW1lcmtraWpvbm9cIixcbiAgICAgICAgZTE2NDogXCJFLjE2NC1sdWt1XCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJ0ZW1wbGFhdHRpbWVya2tpam9ub1wiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBWaXJoZWVsbGluZW4gdHl5cHBpOiBvZG90ZXR0aWluICR7aXNzdWUuZXhwZWN0ZWR9LCBvbGkgJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBWaXJoZWVsbGluZW4gc3lcdTAwRjZ0ZTogdFx1MDBFNHl0eXkgb2xsYSAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYFZpcmhlZWxsaW5lbiB2YWxpbnRhOiB0XHUwMEU0eXR5eSBvbGxhIHlrc2kgc2V1cmFhdmlzdGE6ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLnZhbHVlcywgXCJ8XCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwidG9vX2JpZ1wiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI8PVwiIDogXCI8XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYExpaWFuIHN1dXJpOiAke3NpemluZy5zdWJqZWN0fSB0XHUwMEU0eXR5eSBvbGxhICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0fWAudHJpbSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgTGlpYW4gc3V1cmk6IGFydm9uIHRcdTAwRTR5dHl5IG9sbGEgJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIj49XCIgOiBcIj5cIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgTGlpYW4gcGllbmk6ICR7c2l6aW5nLnN1YmplY3R9IHRcdTAwRTR5dHl5IG9sbGEgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXR9YC50cmltKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBMaWlhbiBwaWVuaTogYXJ2b24gdFx1MDBFNHl0eXkgb2xsYSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2Zvcm1hdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgX2lzc3VlID0gaXNzdWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInN0YXJ0c193aXRoXCIpIHJldHVybiBgVmlyaGVlbGxpbmVuIHN5XHUwMEY2dGU6IHRcdTAwRTR5dHl5IGFsa2FhIFwiJHtfaXNzdWUucHJlZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiZW5kc193aXRoXCIpIHJldHVybiBgVmlyaGVlbGxpbmVuIHN5XHUwMEY2dGU6IHRcdTAwRTR5dHl5IGxvcHB1YSBcIiR7X2lzc3VlLnN1ZmZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImluY2x1ZGVzXCIpIHJldHVybiBgVmlyaGVlbGxpbmVuIHN5XHUwMEY2dGU6IHRcdTAwRTR5dHl5IHNpc1x1MDBFNGx0XHUwMEU0XHUwMEU0IFwiJHtfaXNzdWUuaW5jbHVkZXN9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFZpcmhlZWxsaW5lbiBzeVx1MDBGNnRlOiB0XHUwMEU0eXR5eSB2YXN0YXRhIHNcdTAwRTRcdTAwRTRublx1MDBGNmxsaXN0XHUwMEU0IGxhdXNla2V0dGEgJHtfaXNzdWUucGF0dGVybn1gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgVmlyaGVlbGxpbmVuICR7Tm91bnNbX2lzc3VlLmZvcm1hdF0gPz8gaXNzdWUuZm9ybWF0fWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm5vdF9tdWx0aXBsZV9vZlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgVmlyaGVlbGxpbmVuIGx1a3U6IHRcdTAwRTR5dHl5IG9sbGEgbHV2dW4gJHtpc3N1ZS5kaXZpc29yfSBtb25pa2VydGFgO1xuICAgICAgICAgICAgY2FzZSBcInVucmVjb2duaXplZF9rZXlzXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGAke2lzc3VlLmtleXMubGVuZ3RoID4gMSA/IFwiVHVudGVtYXR0b21hdCBhdmFpbWV0XCIgOiBcIlR1bnRlbWF0b24gYXZhaW5cIn06ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLmtleXMsIFwiLCBcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2tleVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIlZpcmhlZWxsaW5lbiBhdmFpbiB0aWV0dWVlc3NhXCI7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF91bmlvblwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIlZpcmhlZWxsaW5lbiB1bmlvbmlcIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJWaXJoZWVsbGluZW4gYXJ2byBqb3Vrb3NzYVwiO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFZpcmhlZWxsaW5lbiBzeVx1MDBGNnRlYDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJjYXJhY3RcdTAwRThyZXNcIixcbiAgICAgICAgICAgIHZlcmI6IFwiYXZvaXJcIlxuICAgICAgICB9LFxuICAgICAgICBmaWxlOiB7XG4gICAgICAgICAgICB1bml0OiBcIm9jdGV0c1wiLFxuICAgICAgICAgICAgdmVyYjogXCJhdm9pclwiXG4gICAgICAgIH0sXG4gICAgICAgIGFycmF5OiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MDBFOWxcdTAwRTltZW50c1wiLFxuICAgICAgICAgICAgdmVyYjogXCJhdm9pclwiXG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDogXCJcdTAwRTlsXHUwMEU5bWVudHNcIixcbiAgICAgICAgICAgIHZlcmI6IFwiYXZvaXJcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIk5hTlwiIDogXCJub21icmVcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwidGFibGVhdVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJudWxsXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcImVudHJcdTAwRTllXCIsXG4gICAgICAgIGVtYWlsOiBcImFkcmVzc2UgZS1tYWlsXCIsXG4gICAgICAgIHVybDogXCJVUkxcIixcbiAgICAgICAgZW1vamk6IFwiZW1vamlcIixcbiAgICAgICAgdXVpZDogXCJVVUlEXCIsXG4gICAgICAgIHV1aWR2NDogXCJVVUlEdjRcIixcbiAgICAgICAgdXVpZHY2OiBcIlVVSUR2NlwiLFxuICAgICAgICBuYW5vaWQ6IFwibmFub2lkXCIsXG4gICAgICAgIGd1aWQ6IFwiR1VJRFwiLFxuICAgICAgICBjdWlkOiBcImN1aWRcIixcbiAgICAgICAgY3VpZDI6IFwiY3VpZDJcIixcbiAgICAgICAgdWxpZDogXCJVTElEXCIsXG4gICAgICAgIHhpZDogXCJYSURcIixcbiAgICAgICAga3N1aWQ6IFwiS1NVSURcIixcbiAgICAgICAgZGF0ZXRpbWU6IFwiZGF0ZSBldCBoZXVyZSBJU09cIixcbiAgICAgICAgZGF0ZTogXCJkYXRlIElTT1wiLFxuICAgICAgICB0aW1lOiBcImhldXJlIElTT1wiLFxuICAgICAgICBkdXJhdGlvbjogXCJkdXJcdTAwRTllIElTT1wiLFxuICAgICAgICBpcHY0OiBcImFkcmVzc2UgSVB2NFwiLFxuICAgICAgICBpcHY2OiBcImFkcmVzc2UgSVB2NlwiLFxuICAgICAgICBjaWRydjQ6IFwicGxhZ2UgSVB2NFwiLFxuICAgICAgICBjaWRydjY6IFwicGxhZ2UgSVB2NlwiLFxuICAgICAgICBiYXNlNjQ6IFwiY2hhXHUwMEVFbmUgZW5jb2RcdTAwRTllIGVuIGJhc2U2NFwiLFxuICAgICAgICBiYXNlNjR1cmw6IFwiY2hhXHUwMEVFbmUgZW5jb2RcdTAwRTllIGVuIGJhc2U2NHVybFwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJjaGFcdTAwRUVuZSBKU09OXCIsXG4gICAgICAgIGUxNjQ6IFwibnVtXHUwMEU5cm8gRS4xNjRcIixcbiAgICAgICAgand0OiBcIkpXVFwiLFxuICAgICAgICB0ZW1wbGF0ZV9saXRlcmFsOiBcImVudHJcdTAwRTllXCJcbiAgICB9O1xuICAgIHJldHVybiAoaXNzdWUpPT57XG4gICAgICAgIHN3aXRjaChpc3N1ZS5jb2RlKXtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3R5cGVcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYEVudHJcdTAwRTllIGludmFsaWRlIDogJHtpc3N1ZS5leHBlY3RlZH0gYXR0ZW5kdSwgJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX0gcmVcdTAwRTd1YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgRW50clx1MDBFOWUgaW52YWxpZGUgOiAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9IGF0dGVuZHVgO1xuICAgICAgICAgICAgICAgIHJldHVybiBgT3B0aW9uIGludmFsaWRlIDogdW5lIHZhbGV1ciBwYXJtaSAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS52YWx1ZXMsIFwifFwiKX0gYXR0ZW5kdWVgO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPD1cIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykgcmV0dXJuIGBUcm9wIGdyYW5kIDogJHtpc3N1ZS5vcmlnaW4gPz8gXCJ2YWxldXJcIn0gZG9pdCAke3NpemluZy52ZXJifSAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdCA/PyBcIlx1MDBFOWxcdTAwRTltZW50KHMpXCJ9YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBUcm9wIGdyYW5kIDogJHtpc3N1ZS5vcmlnaW4gPz8gXCJ2YWxldXJcIn0gZG9pdCBcdTAwRUF0cmUgJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIj49XCIgOiBcIj5cIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgVHJvcCBwZXRpdCA6ICR7aXNzdWUub3JpZ2lufSBkb2l0ICR7c2l6aW5nLnZlcmJ9ICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0fWA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBUcm9wIHBldGl0IDogJHtpc3N1ZS5vcmlnaW59IGRvaXQgXHUwMEVBdHJlICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZm9ybWF0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBfaXNzdWUgPSBpc3N1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwic3RhcnRzX3dpdGhcIikgcmV0dXJuIGBDaGFcdTAwRUVuZSBpbnZhbGlkZSA6IGRvaXQgY29tbWVuY2VyIHBhciBcIiR7X2lzc3VlLnByZWZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYENoYVx1MDBFRW5lIGludmFsaWRlIDogZG9pdCBzZSB0ZXJtaW5lciBwYXIgXCIke19pc3N1ZS5zdWZmaXh9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJpbmNsdWRlc1wiKSByZXR1cm4gYENoYVx1MDBFRW5lIGludmFsaWRlIDogZG9pdCBpbmNsdXJlIFwiJHtfaXNzdWUuaW5jbHVkZXN9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYENoYVx1MDBFRW5lIGludmFsaWRlIDogZG9pdCBjb3JyZXNwb25kcmUgYXUgbW9kXHUwMEU4bGUgJHtfaXNzdWUucGF0dGVybn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYCR7Tm91bnNbX2lzc3VlLmZvcm1hdF0gPz8gaXNzdWUuZm9ybWF0fSBpbnZhbGlkZWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm5vdF9tdWx0aXBsZV9vZlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgTm9tYnJlIGludmFsaWRlIDogZG9pdCBcdTAwRUF0cmUgdW4gbXVsdGlwbGUgZGUgJHtpc3N1ZS5kaXZpc29yfWA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYENsXHUwMEU5JHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcInNcIiA6IFwiXCJ9IG5vbiByZWNvbm51ZSR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJzXCIgOiBcIlwifSA6ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLmtleXMsIFwiLCBcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2tleVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgQ2xcdTAwRTkgaW52YWxpZGUgZGFucyAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJFbnRyXHUwMEU5ZSBpbnZhbGlkZVwiO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZWxlbWVudFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgVmFsZXVyIGludmFsaWRlIGRhbnMgJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBFbnRyXHUwMEU5ZSBpbnZhbGlkZWA7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGxvY2FsZUVycm9yOiBlcnJvcigpXG4gICAgfTtcbn1cbiIsICJpbXBvcnQgKiBhcyB1dGlsIGZyb20gXCIuLi9jb3JlL3V0aWwuanNcIjtcbmNvbnN0IGVycm9yID0gKCk9PntcbiAgICBjb25zdCBTaXphYmxlID0ge1xuICAgICAgICBzdHJpbmc6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiY2FyYWN0XHUwMEU4cmVzXCIsXG4gICAgICAgICAgICB2ZXJiOiBcImF2b2lyXCJcbiAgICAgICAgfSxcbiAgICAgICAgZmlsZToge1xuICAgICAgICAgICAgdW5pdDogXCJvY3RldHNcIixcbiAgICAgICAgICAgIHZlcmI6IFwiYXZvaXJcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJcdTAwRTlsXHUwMEU5bWVudHNcIixcbiAgICAgICAgICAgIHZlcmI6IFwiYXZvaXJcIlxuICAgICAgICB9LFxuICAgICAgICBzZXQ6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHUwMEU5bFx1MDBFOW1lbnRzXCIsXG4gICAgICAgICAgICB2ZXJiOiBcImF2b2lyXCJcbiAgICAgICAgfVxuICAgIH07XG4gICAgZnVuY3Rpb24gZ2V0U2l6aW5nKG9yaWdpbikge1xuICAgICAgICByZXR1cm4gU2l6YWJsZVtvcmlnaW5dID8/IG51bGw7XG4gICAgfVxuICAgIGNvbnN0IHBhcnNlZFR5cGUgPSAoZGF0YSk9PntcbiAgICAgICAgY29uc3QgdCA9IHR5cGVvZiBkYXRhO1xuICAgICAgICBzd2l0Y2godCl7XG4gICAgICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gTnVtYmVyLmlzTmFOKGRhdGEpID8gXCJOYU5cIiA6IFwibnVtYmVyXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm9iamVjdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcImFycmF5XCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGEgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm51bGxcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKGRhdGEpICE9PSBPYmplY3QucHJvdG90eXBlICYmIGRhdGEuY29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHQ7XG4gICAgfTtcbiAgICBjb25zdCBOb3VucyA9IHtcbiAgICAgICAgcmVnZXg6IFwiZW50clx1MDBFOWVcIixcbiAgICAgICAgZW1haWw6IFwiYWRyZXNzZSBjb3VycmllbFwiLFxuICAgICAgICB1cmw6IFwiVVJMXCIsXG4gICAgICAgIGVtb2ppOiBcImVtb2ppXCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcImRhdGUtaGV1cmUgSVNPXCIsXG4gICAgICAgIGRhdGU6IFwiZGF0ZSBJU09cIixcbiAgICAgICAgdGltZTogXCJoZXVyZSBJU09cIixcbiAgICAgICAgZHVyYXRpb246IFwiZHVyXHUwMEU5ZSBJU09cIixcbiAgICAgICAgaXB2NDogXCJhZHJlc3NlIElQdjRcIixcbiAgICAgICAgaXB2NjogXCJhZHJlc3NlIElQdjZcIixcbiAgICAgICAgY2lkcnY0OiBcInBsYWdlIElQdjRcIixcbiAgICAgICAgY2lkcnY2OiBcInBsYWdlIElQdjZcIixcbiAgICAgICAgYmFzZTY0OiBcImNoYVx1MDBFRW5lIGVuY29kXHUwMEU5ZSBlbiBiYXNlNjRcIixcbiAgICAgICAgYmFzZTY0dXJsOiBcImNoYVx1MDBFRW5lIGVuY29kXHUwMEU5ZSBlbiBiYXNlNjR1cmxcIixcbiAgICAgICAganNvbl9zdHJpbmc6IFwiY2hhXHUwMEVFbmUgSlNPTlwiLFxuICAgICAgICBlMTY0OiBcIm51bVx1MDBFOXJvIEUuMTY0XCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJlbnRyXHUwMEU5ZVwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBFbnRyXHUwMEU5ZSBpbnZhbGlkZSA6IGF0dGVuZHUgJHtpc3N1ZS5leHBlY3RlZH0sIHJlXHUwMEU3dSAke3BhcnNlZFR5cGUoaXNzdWUuaW5wdXQpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF92YWx1ZVwiOlxuICAgICAgICAgICAgICAgIGlmIChpc3N1ZS52YWx1ZXMubGVuZ3RoID09PSAxKSByZXR1cm4gYEVudHJcdTAwRTllIGludmFsaWRlIDogYXR0ZW5kdSAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYE9wdGlvbiBpbnZhbGlkZSA6IGF0dGVuZHUgbCd1bmUgZGVzIHZhbGV1cnMgc3VpdmFudGVzICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLnZhbHVlcywgXCJ8XCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwidG9vX2JpZ1wiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCJcdTIyNjRcIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykgcmV0dXJuIGBUcm9wIGdyYW5kIDogYXR0ZW5kdSBxdWUgJHtpc3N1ZS5vcmlnaW4gPz8gXCJsYSB2YWxldXJcIn0gYWl0ICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0fWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgVHJvcCBncmFuZCA6IGF0dGVuZHUgcXVlICR7aXNzdWUub3JpZ2luID8/IFwibGEgdmFsZXVyXCJ9IHNvaXQgJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIlx1MjI2NVwiIDogXCI+XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFRyb3AgcGV0aXQgOiBhdHRlbmR1IHF1ZSAke2lzc3VlLm9yaWdpbn0gYWl0ICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0fWA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBUcm9wIHBldGl0IDogYXR0ZW5kdSBxdWUgJHtpc3N1ZS5vcmlnaW59IHNvaXQgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYENoYVx1MDBFRW5lIGludmFsaWRlIDogZG9pdCBjb21tZW5jZXIgcGFyIFwiJHtfaXNzdWUucHJlZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJlbmRzX3dpdGhcIikgcmV0dXJuIGBDaGFcdTAwRUVuZSBpbnZhbGlkZSA6IGRvaXQgc2UgdGVybWluZXIgcGFyIFwiJHtfaXNzdWUuc3VmZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBDaGFcdTAwRUVuZSBpbnZhbGlkZSA6IGRvaXQgaW5jbHVyZSBcIiR7X2lzc3VlLmluY2x1ZGVzfVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBDaGFcdTAwRUVuZSBpbnZhbGlkZSA6IGRvaXQgY29ycmVzcG9uZHJlIGF1IG1vdGlmICR7X2lzc3VlLnBhdHRlcm59YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGAke05vdW5zW19pc3N1ZS5mb3JtYXRdID8/IGlzc3VlLmZvcm1hdH0gaW52YWxpZGVgO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJub3RfbXVsdGlwbGVfb2ZcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYE5vbWJyZSBpbnZhbGlkZSA6IGRvaXQgXHUwMEVBdHJlIHVuIG11bHRpcGxlIGRlICR7aXNzdWUuZGl2aXNvcn1gO1xuICAgICAgICAgICAgY2FzZSBcInVucmVjb2duaXplZF9rZXlzXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBDbFx1MDBFOSR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJzXCIgOiBcIlwifSBub24gcmVjb25udWUke2lzc3VlLmtleXMubGVuZ3RoID4gMSA/IFwic1wiIDogXCJcIn0gOiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIiwgXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYENsXHUwMEU5IGludmFsaWRlIGRhbnMgJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3VuaW9uXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiRW50clx1MDBFOWUgaW52YWxpZGVcIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFZhbGV1ciBpbnZhbGlkZSBkYW5zICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBgRW50clx1MDBFOWUgaW52YWxpZGVgO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBsb2NhbGVFcnJvcjogZXJyb3IoKVxuICAgIH07XG59XG4iLCAiaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi4vY29yZS91dGlsLmpzXCI7XG5jb25zdCBlcnJvciA9ICgpPT57XG4gICAgY29uc3QgU2l6YWJsZSA9IHtcbiAgICAgICAgc3RyaW5nOiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MDVEMFx1MDVENVx1MDVFQVx1MDVEOVx1MDVENVx1MDVFQVwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTA1RENcdTA1REJcdTA1RENcdTA1RDVcdTA1RENcIlxuICAgICAgICB9LFxuICAgICAgICBmaWxlOiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MDVEMVx1MDVEOVx1MDVEOVx1MDVEOFx1MDVEOVx1MDVERFwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTA1RENcdTA1REJcdTA1RENcdTA1RDVcdTA1RENcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJcdTA1RTRcdTA1RThcdTA1RDlcdTA1RDhcdTA1RDlcdTA1RERcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwNURDXHUwNURCXHUwNURDXHUwNUQ1XHUwNURDXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MDVFNFx1MDVFOFx1MDVEOVx1MDVEOFx1MDVEOVx1MDVERFwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTA1RENcdTA1REJcdTA1RENcdTA1RDVcdTA1RENcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIk5hTlwiIDogXCJudW1iZXJcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiYXJyYXlcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YoZGF0YSkgIT09IE9iamVjdC5wcm90b3R5cGUgJiYgZGF0YS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdDtcbiAgICB9O1xuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJcdTA1RTdcdTA1RENcdTA1RDhcIixcbiAgICAgICAgZW1haWw6IFwiXHUwNURCXHUwNUVBXHUwNUQ1XHUwNUQxXHUwNUVBIFx1MDVEMFx1MDVEOVx1MDVERVx1MDVEOVx1MDVEOVx1MDVEQ1wiLFxuICAgICAgICB1cmw6IFwiXHUwNURCXHUwNUVBXHUwNUQ1XHUwNUQxXHUwNUVBIFx1MDVFOFx1MDVFOVx1MDVFQVwiLFxuICAgICAgICBlbW9qaTogXCJcdTA1RDBcdTA1RDlcdTA1REVcdTA1RDVcdTA1RDInXHUwNUQ5XCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcIlx1MDVFQVx1MDVEMFx1MDVFOFx1MDVEOVx1MDVEQSBcdTA1RDVcdTA1RDZcdTA1REVcdTA1REYgSVNPXCIsXG4gICAgICAgIGRhdGU6IFwiXHUwNUVBXHUwNUQwXHUwNUU4XHUwNUQ5XHUwNURBIElTT1wiLFxuICAgICAgICB0aW1lOiBcIlx1MDVENlx1MDVERVx1MDVERiBJU09cIixcbiAgICAgICAgZHVyYXRpb246IFwiXHUwNURFXHUwNUU5XHUwNURBIFx1MDVENlx1MDVERVx1MDVERiBJU09cIixcbiAgICAgICAgaXB2NDogXCJcdTA1REJcdTA1RUFcdTA1RDVcdTA1RDFcdTA1RUEgSVB2NFwiLFxuICAgICAgICBpcHY2OiBcIlx1MDVEQlx1MDVFQVx1MDVENVx1MDVEMVx1MDVFQSBJUHY2XCIsXG4gICAgICAgIGNpZHJ2NDogXCJcdTA1RDhcdTA1RDVcdTA1RDVcdTA1RDcgSVB2NFwiLFxuICAgICAgICBjaWRydjY6IFwiXHUwNUQ4XHUwNUQ1XHUwNUQ1XHUwNUQ3IElQdjZcIixcbiAgICAgICAgYmFzZTY0OiBcIlx1MDVERVx1MDVEN1x1MDVFOFx1MDVENVx1MDVENlx1MDVFQSBcdTA1RDFcdTA1RDFcdTA1RTFcdTA1RDlcdTA1RTEgNjRcIixcbiAgICAgICAgYmFzZTY0dXJsOiBcIlx1MDVERVx1MDVEN1x1MDVFOFx1MDVENVx1MDVENlx1MDVFQSBcdTA1RDFcdTA1RDFcdTA1RTFcdTA1RDlcdTA1RTEgNjQgXHUwNURDXHUwNURCXHUwNUVBXHUwNUQ1XHUwNUQxXHUwNUQ1XHUwNUVBIFx1MDVFOFx1MDVFOVx1MDVFQVwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJcdTA1REVcdTA1RDdcdTA1RThcdTA1RDVcdTA1RDZcdTA1RUEgSlNPTlwiLFxuICAgICAgICBlMTY0OiBcIlx1MDVERVx1MDVFMVx1MDVFNFx1MDVFOCBFLjE2NFwiLFxuICAgICAgICBqd3Q6IFwiSldUXCIsXG4gICAgICAgIHRlbXBsYXRlX2xpdGVyYWw6IFwiXHUwNUU3XHUwNURDXHUwNUQ4XCJcbiAgICB9O1xuICAgIHJldHVybiAoaXNzdWUpPT57XG4gICAgICAgIHN3aXRjaChpc3N1ZS5jb2RlKXtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3R5cGVcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDVFN1x1MDVEQ1x1MDVEOCBcdTA1RENcdTA1RDAgXHUwNUVBXHUwNUU3XHUwNUQ5XHUwNURGOiBcdTA1RTZcdTA1RThcdTA1RDlcdTA1REEgJHtpc3N1ZS5leHBlY3RlZH0sIFx1MDVENFx1MDVFQVx1MDVFN1x1MDVEMVx1MDVEQyAke3BhcnNlZFR5cGUoaXNzdWUuaW5wdXQpfWA7XG4gICAgICAgICAgICAvLyByZXR1cm4gYEludmFsaWQgaW5wdXQ6IGV4cGVjdGVkICR7aXNzdWUuZXhwZWN0ZWR9LCByZWNlaXZlZCAke3V0aWwuZ2V0UGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgXHUwNUU3XHUwNURDXHUwNUQ4IFx1MDVEQ1x1MDVEMCBcdTA1RUFcdTA1RTdcdTA1RDlcdTA1REY6IFx1MDVFNlx1MDVFOFx1MDVEOVx1MDVEQSAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDVFN1x1MDVEQ1x1MDVEOCBcdTA1RENcdTA1RDAgXHUwNUVBXHUwNUU3XHUwNUQ5XHUwNURGOiBcdTA1RTZcdTA1RThcdTA1RDlcdTA1REEgXHUwNUQwXHUwNUQ3XHUwNUVBIFx1MDVERVx1MDVENFx1MDVEMFx1MDVFNFx1MDVFOVx1MDVFOFx1MDVENVx1MDVEOVx1MDVENVx1MDVFQSAgJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIjw9XCIgOiBcIjxcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgXHUwNUQyXHUwNUQzXHUwNUQ1XHUwNURDIFx1MDVERVx1MDVEM1x1MDVEOTogJHtpc3N1ZS5vcmlnaW4gPz8gXCJ2YWx1ZVwifSBcdTA1RTZcdTA1RThcdTA1RDlcdTA1REEgXHUwNURDXHUwNUQ0XHUwNUQ5XHUwNUQ1XHUwNUVBICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0ID8/IFwiZWxlbWVudHNcIn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDVEMlx1MDVEM1x1MDVENVx1MDVEQyBcdTA1REVcdTA1RDNcdTA1RDk6ICR7aXNzdWUub3JpZ2luID8/IFwidmFsdWVcIn0gXHUwNUU2XHUwNUU4XHUwNUQ5XHUwNURBIFx1MDVEQ1x1MDVENFx1MDVEOVx1MDVENVx1MDVFQSAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJ0b29fc21hbGxcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPj1cIiA6IFwiPlwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA1RTdcdTA1RDhcdTA1REYgXHUwNURFXHUwNUQzXHUwNUQ5OiAke2lzc3VlLm9yaWdpbn0gXHUwNUU2XHUwNUU4XHUwNUQ5XHUwNURBIFx1MDVEQ1x1MDVENFx1MDVEOVx1MDVENVx1MDVFQSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdH1gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNUU3XHUwNUQ4XHUwNURGIFx1MDVERVx1MDVEM1x1MDVEOTogJHtpc3N1ZS5vcmlnaW59IFx1MDVFNlx1MDVFOFx1MDVEOVx1MDVEQSBcdTA1RENcdTA1RDRcdTA1RDlcdTA1RDVcdTA1RUEgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSByZXR1cm4gYFx1MDVERVx1MDVEN1x1MDVFOFx1MDVENVx1MDVENlx1MDVFQSBcdTA1RENcdTA1RDAgXHUwNUVBXHUwNUU3XHUwNUQ5XHUwNUUwXHUwNUQ0OiBcdTA1RDdcdTA1RDlcdTA1RDlcdTA1RDFcdTA1RUEgXHUwNURDXHUwNUQ0XHUwNUVBXHUwNUQ3XHUwNUQ5XHUwNURDIFx1MDVEMVwiJHtfaXNzdWUucHJlZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiZW5kc193aXRoXCIpIHJldHVybiBgXHUwNURFXHUwNUQ3XHUwNUU4XHUwNUQ1XHUwNUQ2XHUwNUVBIFx1MDVEQ1x1MDVEMCBcdTA1RUFcdTA1RTdcdTA1RDlcdTA1RTBcdTA1RDQ6IFx1MDVEN1x1MDVEOVx1MDVEOVx1MDVEMVx1MDVFQSBcdTA1RENcdTA1RDRcdTA1RTFcdTA1RUFcdTA1RDlcdTA1RDlcdTA1REQgXHUwNUQxIFwiJHtfaXNzdWUuc3VmZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBcdTA1REVcdTA1RDdcdTA1RThcdTA1RDVcdTA1RDZcdTA1RUEgXHUwNURDXHUwNUQwIFx1MDVFQVx1MDVFN1x1MDVEOVx1MDVFMFx1MDVENDogXHUwNUQ3XHUwNUQ5XHUwNUQ5XHUwNUQxXHUwNUVBIFx1MDVEQ1x1MDVEQlx1MDVEQ1x1MDVENVx1MDVEQyBcIiR7X2lzc3VlLmluY2x1ZGVzfVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBcdTA1REVcdTA1RDdcdTA1RThcdTA1RDVcdTA1RDZcdTA1RUEgXHUwNURDXHUwNUQwIFx1MDVFQVx1MDVFN1x1MDVEOVx1MDVFMFx1MDVENDogXHUwNUQ3XHUwNUQ5XHUwNUQ5XHUwNUQxXHUwNUVBIFx1MDVEQ1x1MDVENFx1MDVFQVx1MDVEMFx1MDVEOVx1MDVERCBcdTA1RENcdTA1RUFcdTA1RDFcdTA1RTBcdTA1RDlcdTA1RUEgJHtfaXNzdWUucGF0dGVybn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYCR7Tm91bnNbX2lzc3VlLmZvcm1hdF0gPz8gaXNzdWUuZm9ybWF0fSBcdTA1RENcdTA1RDAgXHUwNUVBXHUwNUU3XHUwNUQ5XHUwNURGYDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA1REVcdTA1RTFcdTA1RTRcdTA1RTggXHUwNURDXHUwNUQwIFx1MDVFQVx1MDVFN1x1MDVEOVx1MDVERjogXHUwNUQ3XHUwNUQ5XHUwNUQ5XHUwNUQxIFx1MDVEQ1x1MDVENFx1MDVEOVx1MDVENVx1MDVFQSBcdTA1REVcdTA1REJcdTA1RTRcdTA1RENcdTA1RDQgXHUwNUU5XHUwNURDICR7aXNzdWUuZGl2aXNvcn1gO1xuICAgICAgICAgICAgY2FzZSBcInVucmVjb2duaXplZF9rZXlzXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA1REVcdTA1RTRcdTA1RUFcdTA1RDcke2lzc3VlLmtleXMubGVuZ3RoID4gMSA/IFwiXHUwNUQ1XHUwNUVBXCIgOiBcIlwifSBcdTA1RENcdTA1RDAgXHUwNURFXHUwNUQ2XHUwNUQ1XHUwNUQ0JHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcIlx1MDVEOVx1MDVERFwiIDogXCJcdTA1RDRcIn06ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLmtleXMsIFwiLCBcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2tleVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNURFXHUwNUU0XHUwNUVBXHUwNUQ3IFx1MDVEQ1x1MDVEMCBcdTA1RUFcdTA1RTdcdTA1RDlcdTA1REYgXHUwNUQxJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3VuaW9uXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiXHUwNUU3XHUwNURDXHUwNUQ4IFx1MDVEQ1x1MDVEMCBcdTA1RUFcdTA1RTdcdTA1RDlcdTA1REZcIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDVFMlx1MDVFOFx1MDVEQSBcdTA1RENcdTA1RDAgXHUwNUVBXHUwNUU3XHUwNUQ5XHUwNURGIFx1MDVEMSR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNUU3XHUwNURDXHUwNUQ4IFx1MDVEQ1x1MDVEMCBcdTA1RUFcdTA1RTdcdTA1RDlcdTA1REZgO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBsb2NhbGVFcnJvcjogZXJyb3IoKVxuICAgIH07XG59XG4iLCAiaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi4vY29yZS91dGlsLmpzXCI7XG5jb25zdCBlcnJvciA9ICgpPT57XG4gICAgY29uc3QgU2l6YWJsZSA9IHtcbiAgICAgICAgc3RyaW5nOiB7XG4gICAgICAgICAgICB1bml0OiBcImthcmFrdGVyXCIsXG4gICAgICAgICAgICB2ZXJiOiBcImxlZ3llblwiXG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiYnl0ZVwiLFxuICAgICAgICAgICAgdmVyYjogXCJsZWd5ZW5cIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJlbGVtXCIsXG4gICAgICAgICAgICB2ZXJiOiBcImxlZ3llblwiXG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDogXCJlbGVtXCIsXG4gICAgICAgICAgICB2ZXJiOiBcImxlZ3llblwiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4pIHtcbiAgICAgICAgcmV0dXJuIFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWRUeXBlID0gKGRhdGEpPT57XG4gICAgICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICAgICAgc3dpdGNoKHQpe1xuICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcInN6XHUwMEUxbVwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJ0XHUwMEY2bWJcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YoZGF0YSkgIT09IE9iamVjdC5wcm90b3R5cGUgJiYgZGF0YS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdDtcbiAgICB9O1xuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJiZW1lbmV0XCIsXG4gICAgICAgIGVtYWlsOiBcImVtYWlsIGNcdTAwRURtXCIsXG4gICAgICAgIHVybDogXCJVUkxcIixcbiAgICAgICAgZW1vamk6IFwiZW1vamlcIixcbiAgICAgICAgdXVpZDogXCJVVUlEXCIsXG4gICAgICAgIHV1aWR2NDogXCJVVUlEdjRcIixcbiAgICAgICAgdXVpZHY2OiBcIlVVSUR2NlwiLFxuICAgICAgICBuYW5vaWQ6IFwibmFub2lkXCIsXG4gICAgICAgIGd1aWQ6IFwiR1VJRFwiLFxuICAgICAgICBjdWlkOiBcImN1aWRcIixcbiAgICAgICAgY3VpZDI6IFwiY3VpZDJcIixcbiAgICAgICAgdWxpZDogXCJVTElEXCIsXG4gICAgICAgIHhpZDogXCJYSURcIixcbiAgICAgICAga3N1aWQ6IFwiS1NVSURcIixcbiAgICAgICAgZGF0ZXRpbWU6IFwiSVNPIGlkXHUwMTUxYlx1MDBFOWx5ZWdcIixcbiAgICAgICAgZGF0ZTogXCJJU08gZFx1MDBFMXR1bVwiLFxuICAgICAgICB0aW1lOiBcIklTTyBpZFx1MDE1MVwiLFxuICAgICAgICBkdXJhdGlvbjogXCJJU08gaWRcdTAxNTFpbnRlcnZhbGx1bVwiLFxuICAgICAgICBpcHY0OiBcIklQdjQgY1x1MDBFRG1cIixcbiAgICAgICAgaXB2NjogXCJJUHY2IGNcdTAwRURtXCIsXG4gICAgICAgIGNpZHJ2NDogXCJJUHY0IHRhcnRvbVx1MDBFMW55XCIsXG4gICAgICAgIGNpZHJ2NjogXCJJUHY2IHRhcnRvbVx1MDBFMW55XCIsXG4gICAgICAgIGJhc2U2NDogXCJiYXNlNjQta1x1MDBGM2RvbHQgc3RyaW5nXCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJiYXNlNjR1cmwta1x1MDBGM2RvbHQgc3RyaW5nXCIsXG4gICAgICAgIGpzb25fc3RyaW5nOiBcIkpTT04gc3RyaW5nXCIsXG4gICAgICAgIGUxNjQ6IFwiRS4xNjQgc3pcdTAwRTFtXCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJiZW1lbmV0XCJcbiAgICB9O1xuICAgIHJldHVybiAoaXNzdWUpPT57XG4gICAgICAgIHN3aXRjaChpc3N1ZS5jb2RlKXtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3R5cGVcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDBDOXJ2XHUwMEU5bnl0ZWxlbiBiZW1lbmV0OiBhIHZcdTAwRTFydCBcdTAwRTlydFx1MDBFOWsgJHtpc3N1ZS5leHBlY3RlZH0sIGEga2Fwb3R0IFx1MDBFOXJ0XHUwMEU5ayAke3BhcnNlZFR5cGUoaXNzdWUuaW5wdXQpfWA7XG4gICAgICAgICAgICAvLyByZXR1cm4gYEludmFsaWQgaW5wdXQ6IGV4cGVjdGVkICR7aXNzdWUuZXhwZWN0ZWR9LCByZWNlaXZlZCAke3V0aWwuZ2V0UGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgXHUwMEM5cnZcdTAwRTlueXRlbGVuIGJlbWVuZXQ6IGEgdlx1MDBFMXJ0IFx1MDBFOXJ0XHUwMEU5ayAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDBDOXJ2XHUwMEU5bnl0ZWxlbiBvcGNpXHUwMEYzOiB2YWxhbWVseWlrIFx1MDBFOXJ0XHUwMEU5ayB2XHUwMEUxcnQgJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIjw9XCIgOiBcIjxcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgVFx1MDBGQWwgbmFneTogJHtpc3N1ZS5vcmlnaW4gPz8gXCJcdTAwRTlydFx1MDBFOWtcIn0gbVx1MDBFOXJldGUgdFx1MDBGQWwgbmFneSAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdCA/PyBcImVsZW1cIn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFRcdTAwRkFsIG5hZ3k6IGEgYmVtZW5ldGkgXHUwMEU5cnRcdTAwRTlrICR7aXNzdWUub3JpZ2luID8/IFwiXHUwMEU5cnRcdTAwRTlrXCJ9IHRcdTAwRkFsIG5hZ3k6ICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInRvb19zbWFsbFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI+PVwiIDogXCI+XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFRcdTAwRkFsIGtpY3NpOiBhIGJlbWVuZXRpIFx1MDBFOXJ0XHUwMEU5ayAke2lzc3VlLm9yaWdpbn0gbVx1MDBFOXJldGUgdFx1MDBGQWwga2ljc2kgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXR9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFRcdTAwRkFsIGtpY3NpOiBhIGJlbWVuZXRpIFx1MDBFOXJ0XHUwMEU5ayAke2lzc3VlLm9yaWdpbn0gdFx1MDBGQWwga2ljc2kgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSByZXR1cm4gYFx1MDBDOXJ2XHUwMEU5bnl0ZWxlbiBzdHJpbmc6IFwiJHtfaXNzdWUucHJlZml4fVwiIFx1MDBFOXJ0XHUwMEU5a2tlbCBrZWxsIGtlemRcdTAxNTFkbmllYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiZW5kc193aXRoXCIpIHJldHVybiBgXHUwMEM5cnZcdTAwRTlueXRlbGVuIHN0cmluZzogXCIke19pc3N1ZS5zdWZmaXh9XCIgXHUwMEU5cnRcdTAwRTlra2VsIGtlbGwgdlx1MDBFOWd6XHUwMTUxZG5pZWA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImluY2x1ZGVzXCIpIHJldHVybiBgXHUwMEM5cnZcdTAwRTlueXRlbGVuIHN0cmluZzogXCIke19pc3N1ZS5pbmNsdWRlc31cIiBcdTAwRTlydFx1MDBFOWtldCBrZWxsIHRhcnRhbG1hem5pYWA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInJlZ2V4XCIpIHJldHVybiBgXHUwMEM5cnZcdTAwRTlueXRlbGVuIHN0cmluZzogJHtfaXNzdWUucGF0dGVybn0gbWludFx1MDBFMW5hayBrZWxsIG1lZ2ZlbGVsbmllYDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTAwQzlydlx1MDBFOW55dGVsZW4gJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTAwQzlydlx1MDBFOW55dGVsZW4gc3pcdTAwRTFtOiAke2lzc3VlLmRpdmlzb3J9IHRcdTAwRjZiYnN6XHUwMEY2clx1MDBGNnNcdTAwRTluZWsga2VsbCBsZW5uaWVgO1xuICAgICAgICAgICAgY2FzZSBcInVucmVjb2duaXplZF9rZXlzXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBJc21lcmV0bGVuIGt1bGNzJHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcInNcIiA6IFwiXCJ9OiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIiwgXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDBDOXJ2XHUwMEU5bnl0ZWxlbiBrdWxjcyAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTAwQzlydlx1MDBFOW55dGVsZW4gYmVtZW5ldFwiO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZWxlbWVudFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwMEM5cnZcdTAwRTlueXRlbGVuIFx1MDBFOXJ0XHUwMEU5azogJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTAwQzlydlx1MDBFOW55dGVsZW4gYmVtZW5ldGA7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGxvY2FsZUVycm9yOiBlcnJvcigpXG4gICAgfTtcbn1cbiIsICJpbXBvcnQgKiBhcyB1dGlsIGZyb20gXCIuLi9jb3JlL3V0aWwuanNcIjtcbmNvbnN0IGVycm9yID0gKCk9PntcbiAgICBjb25zdCBTaXphYmxlID0ge1xuICAgICAgICBzdHJpbmc6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwia2FyYWt0ZXJcIixcbiAgICAgICAgICAgIHZlcmI6IFwibWVtaWxpa2lcIlxuICAgICAgICB9LFxuICAgICAgICBmaWxlOiB7XG4gICAgICAgICAgICB1bml0OiBcImJ5dGVcIixcbiAgICAgICAgICAgIHZlcmI6IFwibWVtaWxpa2lcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJpdGVtXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIm1lbWlsaWtpXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcIml0ZW1cIixcbiAgICAgICAgICAgIHZlcmI6IFwibWVtaWxpa2lcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIk5hTlwiIDogXCJudW1iZXJcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiYXJyYXlcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YoZGF0YSkgIT09IE9iamVjdC5wcm90b3R5cGUgJiYgZGF0YS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdDtcbiAgICB9O1xuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJpbnB1dFwiLFxuICAgICAgICBlbWFpbDogXCJhbGFtYXQgZW1haWxcIixcbiAgICAgICAgdXJsOiBcIlVSTFwiLFxuICAgICAgICBlbW9qaTogXCJlbW9qaVwiLFxuICAgICAgICB1dWlkOiBcIlVVSURcIixcbiAgICAgICAgdXVpZHY0OiBcIlVVSUR2NFwiLFxuICAgICAgICB1dWlkdjY6IFwiVVVJRHY2XCIsXG4gICAgICAgIG5hbm9pZDogXCJuYW5vaWRcIixcbiAgICAgICAgZ3VpZDogXCJHVUlEXCIsXG4gICAgICAgIGN1aWQ6IFwiY3VpZFwiLFxuICAgICAgICBjdWlkMjogXCJjdWlkMlwiLFxuICAgICAgICB1bGlkOiBcIlVMSURcIixcbiAgICAgICAgeGlkOiBcIlhJRFwiLFxuICAgICAgICBrc3VpZDogXCJLU1VJRFwiLFxuICAgICAgICBkYXRldGltZTogXCJ0YW5nZ2FsIGRhbiB3YWt0dSBmb3JtYXQgSVNPXCIsXG4gICAgICAgIGRhdGU6IFwidGFuZ2dhbCBmb3JtYXQgSVNPXCIsXG4gICAgICAgIHRpbWU6IFwiamFtIGZvcm1hdCBJU09cIixcbiAgICAgICAgZHVyYXRpb246IFwiZHVyYXNpIGZvcm1hdCBJU09cIixcbiAgICAgICAgaXB2NDogXCJhbGFtYXQgSVB2NFwiLFxuICAgICAgICBpcHY2OiBcImFsYW1hdCBJUHY2XCIsXG4gICAgICAgIGNpZHJ2NDogXCJyZW50YW5nIGFsYW1hdCBJUHY0XCIsXG4gICAgICAgIGNpZHJ2NjogXCJyZW50YW5nIGFsYW1hdCBJUHY2XCIsXG4gICAgICAgIGJhc2U2NDogXCJzdHJpbmcgZGVuZ2FuIGVua29kZSBiYXNlNjRcIixcbiAgICAgICAgYmFzZTY0dXJsOiBcInN0cmluZyBkZW5nYW4gZW5rb2RlIGJhc2U2NHVybFwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJzdHJpbmcgSlNPTlwiLFxuICAgICAgICBlMTY0OiBcImFuZ2thIEUuMTY0XCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJpbnB1dFwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBJbnB1dCB0aWRhayB2YWxpZDogZGloYXJhcGthbiAke2lzc3VlLmV4cGVjdGVkfSwgZGl0ZXJpbWEgJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBJbnB1dCB0aWRhayB2YWxpZDogZGloYXJhcGthbiAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYFBpbGloYW4gdGlkYWsgdmFsaWQ6IGRpaGFyYXBrYW4gc2FsYWggc2F0dSBkYXJpICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLnZhbHVlcywgXCJ8XCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwidG9vX2JpZ1wiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI8PVwiIDogXCI8XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSByZXR1cm4gYFRlcmxhbHUgYmVzYXI6IGRpaGFyYXBrYW4gJHtpc3N1ZS5vcmlnaW4gPz8gXCJ2YWx1ZVwifSBtZW1pbGlraSAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdCA/PyBcImVsZW1lblwifWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgVGVybGFsdSBiZXNhcjogZGloYXJhcGthbiAke2lzc3VlLm9yaWdpbiA/PyBcInZhbHVlXCJ9IG1lbmphZGkgJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIj49XCIgOiBcIj5cIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgVGVybGFsdSBrZWNpbDogZGloYXJhcGthbiAke2lzc3VlLm9yaWdpbn0gbWVtaWxpa2kgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXR9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFRlcmxhbHUga2VjaWw6IGRpaGFyYXBrYW4gJHtpc3N1ZS5vcmlnaW59IG1lbmphZGkgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSByZXR1cm4gYFN0cmluZyB0aWRhayB2YWxpZDogaGFydXMgZGltdWxhaSBkZW5nYW4gXCIke19pc3N1ZS5wcmVmaXh9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJlbmRzX3dpdGhcIikgcmV0dXJuIGBTdHJpbmcgdGlkYWsgdmFsaWQ6IGhhcnVzIGJlcmFraGlyIGRlbmdhbiBcIiR7X2lzc3VlLnN1ZmZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImluY2x1ZGVzXCIpIHJldHVybiBgU3RyaW5nIHRpZGFrIHZhbGlkOiBoYXJ1cyBtZW55ZXJ0YWthbiBcIiR7X2lzc3VlLmluY2x1ZGVzfVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBTdHJpbmcgdGlkYWsgdmFsaWQ6IGhhcnVzIHNlc3VhaSBwb2xhICR7X2lzc3VlLnBhdHRlcm59YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGAke05vdW5zW19pc3N1ZS5mb3JtYXRdID8/IGlzc3VlLmZvcm1hdH0gdGlkYWsgdmFsaWRgO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJub3RfbXVsdGlwbGVfb2ZcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYEFuZ2thIHRpZGFrIHZhbGlkOiBoYXJ1cyBrZWxpcGF0YW4gZGFyaSAke2lzc3VlLmRpdmlzb3J9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ1bnJlY29nbml6ZWRfa2V5c1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgS3VuY2kgdGlkYWsgZGlrZW5hbGkgJHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcInNcIiA6IFwiXCJ9OiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIiwgXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYEt1bmNpIHRpZGFrIHZhbGlkIGRpICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF91bmlvblwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIklucHV0IHRpZGFrIHZhbGlkXCI7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9lbGVtZW50XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOaWxhaSB0aWRhayB2YWxpZCBkaSAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gYElucHV0IHRpZGFrIHZhbGlkYDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuZXhwb3J0IGNvbnN0IHBhcnNlZFR5cGUgPSAoZGF0YSk9PntcbiAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgc3dpdGNoKHQpe1xuICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIm5cdTAwRkFtZXJcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgY2FzZSBcIm9iamVjdFwiOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcImZ5bGtpXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm51bGxcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdDtcbn07XG5jb25zdCBlcnJvciA9ICgpPT57XG4gICAgY29uc3QgU2l6YWJsZSA9IHtcbiAgICAgICAgc3RyaW5nOiB7XG4gICAgICAgICAgICB1bml0OiBcInN0YWZpXCIsXG4gICAgICAgICAgICB2ZXJiOiBcImFcdTAwRjAgaGFmYVwiXG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiYlx1MDBFNnRpXCIsXG4gICAgICAgICAgICB2ZXJiOiBcImFcdTAwRjAgaGFmYVwiXG4gICAgICAgIH0sXG4gICAgICAgIGFycmF5OiB7XG4gICAgICAgICAgICB1bml0OiBcImhsdXRpXCIsXG4gICAgICAgICAgICB2ZXJiOiBcImFcdTAwRjAgaGFmYVwiXG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDogXCJobHV0aVwiLFxuICAgICAgICAgICAgdmVyYjogXCJhXHUwMEYwIGhhZmFcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcImdpbGRpXCIsXG4gICAgICAgIGVtYWlsOiBcIm5ldGZhbmdcIixcbiAgICAgICAgdXJsOiBcInZlZnNsXHUwMEYzXHUwMEYwXCIsXG4gICAgICAgIGVtb2ppOiBcImVtb2ppXCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcIklTTyBkYWdzZXRuaW5nIG9nIHRcdTAwRURtaVwiLFxuICAgICAgICBkYXRlOiBcIklTTyBkYWdzZXRuaW5nXCIsXG4gICAgICAgIHRpbWU6IFwiSVNPIHRcdTAwRURtaVwiLFxuICAgICAgICBkdXJhdGlvbjogXCJJU08gdFx1MDBFRG1hbGVuZ2RcIixcbiAgICAgICAgaXB2NDogXCJJUHY0IGFkZHJlc3NcIixcbiAgICAgICAgaXB2NjogXCJJUHY2IGFkZHJlc3NcIixcbiAgICAgICAgY2lkcnY0OiBcIklQdjQgcmFuZ2VcIixcbiAgICAgICAgY2lkcnY2OiBcIklQdjYgcmFuZ2VcIixcbiAgICAgICAgYmFzZTY0OiBcImJhc2U2NC1lbmNvZGVkIHN0cmVuZ3VyXCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJiYXNlNjR1cmwtZW5jb2RlZCBzdHJlbmd1clwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJKU09OIHN0cmVuZ3VyXCIsXG4gICAgICAgIGUxNjQ6IFwiRS4xNjQgdFx1MDBGNmx1Z2lsZGlcIixcbiAgICAgICAgand0OiBcIkpXVFwiLFxuICAgICAgICB0ZW1wbGF0ZV9saXRlcmFsOiBcImdpbGRpXCJcbiAgICB9O1xuICAgIHJldHVybiAoaXNzdWUpPT57XG4gICAgICAgIHN3aXRjaChpc3N1ZS5jb2RlKXtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3R5cGVcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFJhbmd0IGdpbGRpOiBcdTAwREVcdTAwRkEgc2xcdTAwRjNzdCBpbm4gJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX0gXHUwMEZFYXIgc2VtIFx1MDBFMSBhXHUwMEYwIHZlcmEgJHtpc3N1ZS5leHBlY3RlZH1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBSYW5ndCBnaWxkaTogZ2VydCByXHUwMEUxXHUwMEYwIGZ5cmlyICR7dXRpbC5zdHJpbmdpZnlQcmltaXRpdmUoaXNzdWUudmFsdWVzWzBdKX1gO1xuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwMEQzZ2lsdCB2YWw6IG1cdTAwRTEgdmVyYSBlaXR0IGFmIGVmdGlyZmFyYW5kaSAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS52YWx1ZXMsIFwifFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPD1cIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykgcmV0dXJuIGBPZiBzdFx1MDBGM3J0OiBnZXJ0IGVyIHJcdTAwRTFcdTAwRjAgZnlyaXIgYVx1MDBGMCAke2lzc3VlLm9yaWdpbiA/PyBcImdpbGRpXCJ9IGhhZmkgJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXQgPz8gXCJobHV0aVwifWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgT2Ygc3RcdTAwRjNydDogZ2VydCBlciByXHUwMEUxXHUwMEYwIGZ5cmlyIGFcdTAwRjAgJHtpc3N1ZS5vcmlnaW4gPz8gXCJnaWxkaVwifSBzXHUwMEU5ICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInRvb19zbWFsbFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI+PVwiIDogXCI+XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYE9mIGxcdTAwRUR0aVx1MDBGMDogZ2VydCBlciByXHUwMEUxXHUwMEYwIGZ5cmlyIGFcdTAwRjAgJHtpc3N1ZS5vcmlnaW59IGhhZmkgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXR9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYE9mIGxcdTAwRUR0aVx1MDBGMDogZ2VydCBlciByXHUwMEUxXHUwMEYwIGZ5cmlyIGFcdTAwRjAgJHtpc3N1ZS5vcmlnaW59IHNcdTAwRTkgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDBEM2dpbGR1ciBzdHJlbmd1cjogdmVyXHUwMEYwdXIgYVx1MDBGMCBieXJqYSBcdTAwRTEgXCIke19pc3N1ZS5wcmVmaXh9XCJgO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYFx1MDBEM2dpbGR1ciBzdHJlbmd1cjogdmVyXHUwMEYwdXIgYVx1MDBGMCBlbmRhIFx1MDBFMSBcIiR7X2lzc3VlLnN1ZmZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImluY2x1ZGVzXCIpIHJldHVybiBgXHUwMEQzZ2lsZHVyIHN0cmVuZ3VyOiB2ZXJcdTAwRjB1ciBhXHUwMEYwIGlubmloYWxkYSBcIiR7X2lzc3VlLmluY2x1ZGVzfVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBcdTAwRDNnaWxkdXIgc3RyZW5ndXI6IHZlclx1MDBGMHVyIGFcdTAwRjAgZnlsZ2phIG15bnN0cmkgJHtfaXNzdWUucGF0dGVybn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFJhbmd0ICR7Tm91bnNbX2lzc3VlLmZvcm1hdF0gPz8gaXNzdWUuZm9ybWF0fWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm5vdF9tdWx0aXBsZV9vZlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgUlx1MDBGNm5nIHRhbGE6IHZlclx1MDBGMHVyIGFcdTAwRjAgdmVyYSBtYXJnZmVsZGkgYWYgJHtpc3N1ZS5kaXZpc29yfWA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDBEM1x1MDBGRWVra3QgJHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcImlyIGx5a2xhclwiIDogXCJ1ciBseWtpbGxcIn06ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLmtleXMsIFwiLCBcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2tleVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgUmFuZ3VyIGx5a2lsbCBcdTAwRUQgJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3VuaW9uXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiUmFuZ3QgZ2lsZGlcIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFJhbmd0IGdpbGRpIFx1MDBFRCAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFJhbmd0IGdpbGRpYDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJjYXJhdHRlcmlcIixcbiAgICAgICAgICAgIHZlcmI6IFwiYXZlcmVcIlxuICAgICAgICB9LFxuICAgICAgICBmaWxlOiB7XG4gICAgICAgICAgICB1bml0OiBcImJ5dGVcIixcbiAgICAgICAgICAgIHZlcmI6IFwiYXZlcmVcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJlbGVtZW50aVwiLFxuICAgICAgICAgICAgdmVyYjogXCJhdmVyZVwiXG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDogXCJlbGVtZW50aVwiLFxuICAgICAgICAgICAgdmVyYjogXCJhdmVyZVwiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4pIHtcbiAgICAgICAgcmV0dXJuIFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWRUeXBlID0gKGRhdGEpPT57XG4gICAgICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICAgICAgc3dpdGNoKHQpe1xuICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIm51bWVyb1wiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJ2ZXR0b3JlXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGEgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm51bGxcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKGRhdGEpICE9PSBPYmplY3QucHJvdG90eXBlICYmIGRhdGEuY29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHQ7XG4gICAgfTtcbiAgICBjb25zdCBOb3VucyA9IHtcbiAgICAgICAgcmVnZXg6IFwiaW5wdXRcIixcbiAgICAgICAgZW1haWw6IFwiaW5kaXJpenpvIGVtYWlsXCIsXG4gICAgICAgIHVybDogXCJVUkxcIixcbiAgICAgICAgZW1vamk6IFwiZW1vamlcIixcbiAgICAgICAgdXVpZDogXCJVVUlEXCIsXG4gICAgICAgIHV1aWR2NDogXCJVVUlEdjRcIixcbiAgICAgICAgdXVpZHY2OiBcIlVVSUR2NlwiLFxuICAgICAgICBuYW5vaWQ6IFwibmFub2lkXCIsXG4gICAgICAgIGd1aWQ6IFwiR1VJRFwiLFxuICAgICAgICBjdWlkOiBcImN1aWRcIixcbiAgICAgICAgY3VpZDI6IFwiY3VpZDJcIixcbiAgICAgICAgdWxpZDogXCJVTElEXCIsXG4gICAgICAgIHhpZDogXCJYSURcIixcbiAgICAgICAga3N1aWQ6IFwiS1NVSURcIixcbiAgICAgICAgZGF0ZXRpbWU6IFwiZGF0YSBlIG9yYSBJU09cIixcbiAgICAgICAgZGF0ZTogXCJkYXRhIElTT1wiLFxuICAgICAgICB0aW1lOiBcIm9yYSBJU09cIixcbiAgICAgICAgZHVyYXRpb246IFwiZHVyYXRhIElTT1wiLFxuICAgICAgICBpcHY0OiBcImluZGlyaXp6byBJUHY0XCIsXG4gICAgICAgIGlwdjY6IFwiaW5kaXJpenpvIElQdjZcIixcbiAgICAgICAgY2lkcnY0OiBcImludGVydmFsbG8gSVB2NFwiLFxuICAgICAgICBjaWRydjY6IFwiaW50ZXJ2YWxsbyBJUHY2XCIsXG4gICAgICAgIGJhc2U2NDogXCJzdHJpbmdhIGNvZGlmaWNhdGEgaW4gYmFzZTY0XCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJVUkwgY29kaWZpY2F0YSBpbiBiYXNlNjRcIixcbiAgICAgICAganNvbl9zdHJpbmc6IFwic3RyaW5nYSBKU09OXCIsXG4gICAgICAgIGUxNjQ6IFwibnVtZXJvIEUuMTY0XCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJpbnB1dFwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBJbnB1dCBub24gdmFsaWRvOiBhdHRlc28gJHtpc3N1ZS5leHBlY3RlZH0sIHJpY2V2dXRvICR7cGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9YDtcbiAgICAgICAgICAgIC8vIHJldHVybiBgSW5wdXQgbm9uIHZhbGlkbzogYXR0ZXNvICR7aXNzdWUuZXhwZWN0ZWR9LCByaWNldnV0byAke3V0aWwuZ2V0UGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgSW5wdXQgbm9uIHZhbGlkbzogYXR0ZXNvICR7dXRpbC5zdHJpbmdpZnlQcmltaXRpdmUoaXNzdWUudmFsdWVzWzBdKX1gO1xuICAgICAgICAgICAgICAgIHJldHVybiBgT3B6aW9uZSBub24gdmFsaWRhOiBhdHRlc28gdW5vIHRyYSAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS52YWx1ZXMsIFwifFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPD1cIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykgcmV0dXJuIGBUcm9wcG8gZ3JhbmRlOiAke2lzc3VlLm9yaWdpbiA/PyBcInZhbG9yZVwifSBkZXZlIGF2ZXJlICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0ID8/IFwiZWxlbWVudGlcIn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFRyb3BwbyBncmFuZGU6ICR7aXNzdWUub3JpZ2luID8/IFwidmFsb3JlXCJ9IGRldmUgZXNzZXJlICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInRvb19zbWFsbFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI+PVwiIDogXCI+XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFRyb3BwbyBwaWNjb2xvOiAke2lzc3VlLm9yaWdpbn0gZGV2ZSBhdmVyZSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdH1gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgVHJvcHBvIHBpY2NvbG86ICR7aXNzdWUub3JpZ2lufSBkZXZlIGVzc2VyZSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2Zvcm1hdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgX2lzc3VlID0gaXNzdWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInN0YXJ0c193aXRoXCIpIHJldHVybiBgU3RyaW5nYSBub24gdmFsaWRhOiBkZXZlIGluaXppYXJlIGNvbiBcIiR7X2lzc3VlLnByZWZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYFN0cmluZ2Egbm9uIHZhbGlkYTogZGV2ZSB0ZXJtaW5hcmUgY29uIFwiJHtfaXNzdWUuc3VmZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBTdHJpbmdhIG5vbiB2YWxpZGE6IGRldmUgaW5jbHVkZXJlIFwiJHtfaXNzdWUuaW5jbHVkZXN9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYFN0cmluZ2Egbm9uIHZhbGlkYTogZGV2ZSBjb3JyaXNwb25kZXJlIGFsIHBhdHRlcm4gJHtfaXNzdWUucGF0dGVybn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYEludmFsaWQgJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOdW1lcm8gbm9uIHZhbGlkbzogZGV2ZSBlc3NlcmUgdW4gbXVsdGlwbG8gZGkgJHtpc3N1ZS5kaXZpc29yfWA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYENoaWF2JHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcImlcIiA6IFwiZVwifSBub24gcmljb25vc2NpdXQke2lzc3VlLmtleXMubGVuZ3RoID4gMSA/IFwiZVwiIDogXCJhXCJ9OiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIiwgXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYENoaWF2ZSBub24gdmFsaWRhIGluICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF91bmlvblwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIklucHV0IG5vbiB2YWxpZG9cIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFZhbG9yZSBub24gdmFsaWRvIGluICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBgSW5wdXQgbm9uIHZhbGlkb2A7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGxvY2FsZUVycm9yOiBlcnJvcigpXG4gICAgfTtcbn1cbiIsICJpbXBvcnQgKiBhcyB1dGlsIGZyb20gXCIuLi9jb3JlL3V0aWwuanNcIjtcbmNvbnN0IGVycm9yID0gKCk9PntcbiAgICBjb25zdCBTaXphYmxlID0ge1xuICAgICAgICBzdHJpbmc6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHU2NTg3XHU1QjU3XCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MzA2N1x1MzA0Mlx1MzA4QlwiXG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHUzMEQwXHUzMEE0XHUzMEM4XCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MzA2N1x1MzA0Mlx1MzA4QlwiXG4gICAgICAgIH0sXG4gICAgICAgIGFycmF5OiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1ODk4MVx1N0QyMFwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTMwNjdcdTMwNDJcdTMwOEJcIlxuICAgICAgICB9LFxuICAgICAgICBzZXQ6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHU4OTgxXHU3RDIwXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MzA2N1x1MzA0Mlx1MzA4QlwiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4pIHtcbiAgICAgICAgcmV0dXJuIFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWRUeXBlID0gKGRhdGEpPT57XG4gICAgICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICAgICAgc3dpdGNoKHQpe1xuICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIlx1NjU3MFx1NTAyNFwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTkxNERcdTUyMTdcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YoZGF0YSkgIT09IE9iamVjdC5wcm90b3R5cGUgJiYgZGF0YS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdDtcbiAgICB9O1xuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJcdTUxNjVcdTUyOUJcdTUwMjRcIixcbiAgICAgICAgZW1haWw6IFwiXHUzMEUxXHUzMEZDXHUzMEVCXHUzMEEyXHUzMEM5XHUzMEVDXHUzMEI5XCIsXG4gICAgICAgIHVybDogXCJVUkxcIixcbiAgICAgICAgZW1vamk6IFwiXHU3RDc1XHU2NTg3XHU1QjU3XCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcIklTT1x1NjVFNVx1NjY0MlwiLFxuICAgICAgICBkYXRlOiBcIklTT1x1NjVFNVx1NEVEOFwiLFxuICAgICAgICB0aW1lOiBcIklTT1x1NjY0Mlx1NTIzQlwiLFxuICAgICAgICBkdXJhdGlvbjogXCJJU09cdTY3MUZcdTk1OTNcIixcbiAgICAgICAgaXB2NDogXCJJUHY0XHUzMEEyXHUzMEM5XHUzMEVDXHUzMEI5XCIsXG4gICAgICAgIGlwdjY6IFwiSVB2Nlx1MzBBMlx1MzBDOVx1MzBFQ1x1MzBCOVwiLFxuICAgICAgICBjaWRydjQ6IFwiSVB2NFx1N0JDNFx1NTZGMlwiLFxuICAgICAgICBjaWRydjY6IFwiSVB2Nlx1N0JDNFx1NTZGMlwiLFxuICAgICAgICBiYXNlNjQ6IFwiYmFzZTY0XHUzMEE4XHUzMEYzXHUzMEIzXHUzMEZDXHUzMEM5XHU2NTg3XHU1QjU3XHU1MjE3XCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJiYXNlNjR1cmxcdTMwQThcdTMwRjNcdTMwQjNcdTMwRkNcdTMwQzlcdTY1ODdcdTVCNTdcdTUyMTdcIixcbiAgICAgICAganNvbl9zdHJpbmc6IFwiSlNPTlx1NjU4N1x1NUI1N1x1NTIxN1wiLFxuICAgICAgICBlMTY0OiBcIkUuMTY0XHU3NTZBXHU1M0Y3XCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJcdTUxNjVcdTUyOUJcdTUwMjRcIlxuICAgIH07XG4gICAgcmV0dXJuIChpc3N1ZSk9PntcbiAgICAgICAgc3dpdGNoKGlzc3VlLmNvZGUpe1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdHlwZVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHU3MTIxXHU1MkI5XHUzMDZBXHU1MTY1XHU1MjlCOiAke2lzc3VlLmV4cGVjdGVkfVx1MzA0Q1x1NjcxRlx1NUY4NVx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzA0Q1x1MzAwMSR7cGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9XHUzMDRDXHU1MTY1XHU1MjlCXHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU3XHUzMDVGYDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgXHU3MTIxXHU1MkI5XHUzMDZBXHU1MTY1XHU1MjlCOiAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9XHUzMDRDXHU2NzFGXHU1Rjg1XHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU3XHUzMDVGYDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1NzEyMVx1NTJCOVx1MzA2QVx1OTA3OFx1NjI5RTogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcIlx1MzAwMVwiKX1cdTMwNkVcdTMwNDRcdTMwNUFcdTMwOENcdTMwNEJcdTMwNjdcdTMwNDJcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlgO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiXHU0RUU1XHU0RTBCXHUzMDY3XHUzMDQyXHUzMDhCXCIgOiBcIlx1MzA4OFx1MzA4QVx1NUMwRlx1MzA1NVx1MzA0NFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykgcmV0dXJuIGBcdTU5MjdcdTMwNERcdTMwNTlcdTMwNEVcdTMwOEJcdTUwMjQ6ICR7aXNzdWUub3JpZ2luID8/IFwiXHU1MDI0XCJ9XHUzMDZGJHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9JHtzaXppbmcudW5pdCA/PyBcIlx1ODk4MVx1N0QyMFwifSR7YWRqfVx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHU1OTI3XHUzMDREXHUzMDU5XHUzMDRFXHUzMDhCXHU1MDI0OiAke2lzc3VlLm9yaWdpbiA/PyBcIlx1NTAyNFwifVx1MzA2RiR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSR7YWRqfVx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInRvb19zbWFsbFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCJcdTRFRTVcdTRFMEFcdTMwNjdcdTMwNDJcdTMwOEJcIiA6IFwiXHUzMDg4XHUzMDhBXHU1OTI3XHUzMDREXHUzMDQ0XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSByZXR1cm4gYFx1NUMwRlx1MzA1NVx1MzA1OVx1MzA0RVx1MzA4Qlx1NTAyNDogJHtpc3N1ZS5vcmlnaW59XHUzMDZGJHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9JHtzaXppbmcudW5pdH0ke2Fkan1cdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlgO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1NUMwRlx1MzA1NVx1MzA1OVx1MzA0RVx1MzA4Qlx1NTAyNDogJHtpc3N1ZS5vcmlnaW59XHUzMDZGJHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9JHthZGp9XHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSByZXR1cm4gYFx1NzEyMVx1NTJCOVx1MzA2QVx1NjU4N1x1NUI1N1x1NTIxNzogXCIke19pc3N1ZS5wcmVmaXh9XCJcdTMwNjdcdTU5Q0JcdTMwN0VcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJlbmRzX3dpdGhcIikgcmV0dXJuIGBcdTcxMjFcdTUyQjlcdTMwNkFcdTY1ODdcdTVCNTdcdTUyMTc6IFwiJHtfaXNzdWUuc3VmZml4fVwiXHUzMDY3XHU3RDQyXHUzMDhGXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5YDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBcdTcxMjFcdTUyQjlcdTMwNkFcdTY1ODdcdTVCNTdcdTUyMTc6IFwiJHtfaXNzdWUuaW5jbHVkZXN9XCJcdTMwOTJcdTU0MkJcdTMwODBcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYFx1NzEyMVx1NTJCOVx1MzA2QVx1NjU4N1x1NUI1N1x1NTIxNzogXHUzMEQxXHUzMEJGXHUzMEZDXHUzMEYzJHtfaXNzdWUucGF0dGVybn1cdTMwNkJcdTRFMDBcdTgxRjRcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlgO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1NzEyMVx1NTJCOVx1MzA2QSR7Tm91bnNbX2lzc3VlLmZvcm1hdF0gPz8gaXNzdWUuZm9ybWF0fWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm5vdF9tdWx0aXBsZV9vZlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHU3MTIxXHU1MkI5XHUzMDZBXHU2NTcwXHU1MDI0OiAke2lzc3VlLmRpdmlzb3J9XHUzMDZFXHU1MDBEXHU2NTcwXHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5YDtcbiAgICAgICAgICAgIGNhc2UgXCJ1bnJlY29nbml6ZWRfa2V5c1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHU4QThEXHU4QjU4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDZBXHUzMDQ0XHUzMEFEXHUzMEZDJHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcIlx1N0ZBNFwiIDogXCJcIn06ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLmtleXMsIFwiXHUzMDAxXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYCR7aXNzdWUub3JpZ2lufVx1NTE4NVx1MzA2RVx1NzEyMVx1NTJCOVx1MzA2QVx1MzBBRFx1MzBGQ2A7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF91bmlvblwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIlx1NzEyMVx1NTJCOVx1MzA2QVx1NTE2NVx1NTI5QlwiO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZWxlbWVudFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgJHtpc3N1ZS5vcmlnaW59XHU1MTg1XHUzMDZFXHU3MTIxXHU1MkI5XHUzMDZBXHU1MDI0YDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTcxMjFcdTUyQjlcdTMwNkFcdTUxNjVcdTUyOUJgO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBsb2NhbGVFcnJvcjogZXJyb3IoKVxuICAgIH07XG59XG4iLCAiaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi4vY29yZS91dGlsLmpzXCI7XG5leHBvcnQgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICBzd2l0Y2godCl7XG4gICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gTnVtYmVyLmlzTmFOKGRhdGEpID8gXCJOYU5cIiA6IFwiXHUxMEUwXHUxMEQ4XHUxMEVBXHUxMEVFXHUxMEQ1XHUxMEQ4XCI7XG4gICAgICAgICAgICB9XG4gICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTEwREJcdTEwRDBcdTEwRTFcdTEwRDhcdTEwRDVcdTEwRDhcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGRhdGEgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKGRhdGEpICE9PSBPYmplY3QucHJvdG90eXBlICYmIGRhdGEuY29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgfVxuICAgIGNvbnN0IHR5cGVNYXAgPSB7XG4gICAgICAgIHN0cmluZzogXCJcdTEwRTFcdTEwRTJcdTEwRTBcdTEwRDhcdTEwRENcdTEwRDJcdTEwRDhcIixcbiAgICAgICAgYm9vbGVhbjogXCJcdTEwRDFcdTEwRTNcdTEwREFcdTEwRDRcdTEwRDBcdTEwRENcdTEwRDhcIixcbiAgICAgICAgdW5kZWZpbmVkOiBcInVuZGVmaW5lZFwiLFxuICAgICAgICBiaWdpbnQ6IFwiYmlnaW50XCIsXG4gICAgICAgIHN5bWJvbDogXCJzeW1ib2xcIixcbiAgICAgICAgZnVuY3Rpb246IFwiXHUxMEU0XHUxMEUzXHUxMERDXHUxMEU1XHUxMEVBXHUxMEQ4XHUxMEQwXCJcbiAgICB9O1xuICAgIHJldHVybiB0eXBlTWFwW3RdID8/IHQ7XG59O1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJcdTEwRTFcdTEwRDhcdTEwREJcdTEwRDFcdTEwRERcdTEwREFcdTEwRERcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUxMEUzXHUxMERDXHUxMEQzXHUxMEQwIFx1MTBFOFx1MTBENFx1MTBEOFx1MTBFQVx1MTBEMFx1MTBENVx1MTBEM1x1MTBENFx1MTBFMVwiXG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHUxMEQxXHUxMEQwXHUxMEQ4XHUxMEUyXHUxMEQ4XCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MTBFM1x1MTBEQ1x1MTBEM1x1MTBEMCBcdTEwRThcdTEwRDRcdTEwRDhcdTEwRUFcdTEwRDBcdTEwRDVcdTEwRDNcdTEwRDRcdTEwRTFcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJcdTEwRDRcdTEwREFcdTEwRDRcdTEwREJcdTEwRDRcdTEwRENcdTEwRTJcdTEwRDhcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUxMEUzXHUxMERDXHUxMEQzXHUxMEQwIFx1MTBFOFx1MTBENFx1MTBEOFx1MTBFQVx1MTBEMFx1MTBENVx1MTBEM1x1MTBENFx1MTBFMVwiXG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDogXCJcdTEwRDRcdTEwREFcdTEwRDRcdTEwREJcdTEwRDRcdTEwRENcdTEwRTJcdTEwRDhcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUxMEUzXHUxMERDXHUxMEQzXHUxMEQwIFx1MTBFOFx1MTBENFx1MTBEOFx1MTBFQVx1MTBEMFx1MTBENVx1MTBEM1x1MTBENFx1MTBFMVwiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4pIHtcbiAgICAgICAgcmV0dXJuIFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgIH1cbiAgICBjb25zdCBOb3VucyA9IHtcbiAgICAgICAgcmVnZXg6IFwiXHUxMEU4XHUxMEQ0XHUxMEU3XHUxMEQ1XHUxMEQwXHUxMERDXHUxMEQwXCIsXG4gICAgICAgIGVtYWlsOiBcIlx1MTBENFx1MTBEQS1cdTEwRTRcdTEwRERcdTEwRTFcdTEwRTJcdTEwRDhcdTEwRTEgXHUxMERCXHUxMEQ4XHUxMEUxXHUxMEQwXHUxMERCXHUxMEQwXHUxMEUwXHUxMEQ3XHUxMEQ4XCIsXG4gICAgICAgIHVybDogXCJVUkxcIixcbiAgICAgICAgZW1vamk6IFwiXHUxMEQ0XHUxMERCXHUxMEREXHUxMEVGXHUxMEQ4XCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcIlx1MTBEN1x1MTBEMFx1MTBFMFx1MTBEOFx1MTBFNlx1MTBEOC1cdTEwRDNcdTEwRTBcdTEwRERcIixcbiAgICAgICAgZGF0ZTogXCJcdTEwRDdcdTEwRDBcdTEwRTBcdTEwRDhcdTEwRTZcdTEwRDhcIixcbiAgICAgICAgdGltZTogXCJcdTEwRDNcdTEwRTBcdTEwRERcIixcbiAgICAgICAgZHVyYXRpb246IFwiXHUxMEVFXHUxMEQwXHUxMERDXHUxMEQyXHUxMEUwXHUxMEVCXHUxMERBXHUxMEQ4XHUxMEQ1XHUxMEREXHUxMEQxXHUxMEQwXCIsXG4gICAgICAgIGlwdjQ6IFwiSVB2NCBcdTEwREJcdTEwRDhcdTEwRTFcdTEwRDBcdTEwREJcdTEwRDBcdTEwRTBcdTEwRDdcdTEwRDhcIixcbiAgICAgICAgaXB2NjogXCJJUHY2IFx1MTBEQlx1MTBEOFx1MTBFMVx1MTBEMFx1MTBEQlx1MTBEMFx1MTBFMFx1MTBEN1x1MTBEOFwiLFxuICAgICAgICBjaWRydjQ6IFwiSVB2NCBcdTEwRDNcdTEwRDhcdTEwRDBcdTEwREVcdTEwRDBcdTEwRDZcdTEwRERcdTEwRENcdTEwRDhcIixcbiAgICAgICAgY2lkcnY2OiBcIklQdjYgXHUxMEQzXHUxMEQ4XHUxMEQwXHUxMERFXHUxMEQwXHUxMEQ2XHUxMEREXHUxMERDXHUxMEQ4XCIsXG4gICAgICAgIGJhc2U2NDogXCJiYXNlNjQtXHUxMEQ5XHUxMEREXHUxMEQzXHUxMEQ4XHUxMEUwXHUxMEQ0XHUxMEQxXHUxMEUzXHUxMERBXHUxMEQ4IFx1MTBFMVx1MTBFMlx1MTBFMFx1MTBEOFx1MTBEQ1x1MTBEMlx1MTBEOFwiLFxuICAgICAgICBiYXNlNjR1cmw6IFwiYmFzZTY0dXJsLVx1MTBEOVx1MTBERFx1MTBEM1x1MTBEOFx1MTBFMFx1MTBENFx1MTBEMVx1MTBFM1x1MTBEQVx1MTBEOCBcdTEwRTFcdTEwRTJcdTEwRTBcdTEwRDhcdTEwRENcdTEwRDJcdTEwRDhcIixcbiAgICAgICAganNvbl9zdHJpbmc6IFwiSlNPTiBcdTEwRTFcdTEwRTJcdTEwRTBcdTEwRDhcdTEwRENcdTEwRDJcdTEwRDhcIixcbiAgICAgICAgZTE2NDogXCJFLjE2NCBcdTEwRENcdTEwRERcdTEwREJcdTEwRDRcdTEwRTBcdTEwRDhcIixcbiAgICAgICAgand0OiBcIkpXVFwiLFxuICAgICAgICB0ZW1wbGF0ZV9saXRlcmFsOiBcIlx1MTBFOFx1MTBENFx1MTBFN1x1MTBENVx1MTBEMFx1MTBEQ1x1MTBEMFwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTEwRDBcdTEwRTBcdTEwRDBcdTEwRTFcdTEwRUNcdTEwRERcdTEwRTBcdTEwRDggXHUxMEU4XHUxMEQ0XHUxMEU3XHUxMEQ1XHUxMEQwXHUxMERDXHUxMEQwOiBcdTEwREJcdTEwRERcdTEwRTFcdTEwRDBcdTEwREFcdTEwRERcdTEwRDNcdTEwRENcdTEwRDRcdTEwREFcdTEwRDggJHtpc3N1ZS5leHBlY3RlZH0sIFx1MTBEQlx1MTBEOFx1MTBFNlx1MTBENFx1MTBEMVx1MTBFM1x1MTBEQVx1MTBEOCAke3BhcnNlZFR5cGUoaXNzdWUuaW5wdXQpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF92YWx1ZVwiOlxuICAgICAgICAgICAgICAgIGlmIChpc3N1ZS52YWx1ZXMubGVuZ3RoID09PSAxKSByZXR1cm4gYFx1MTBEMFx1MTBFMFx1MTBEMFx1MTBFMVx1MTBFQ1x1MTBERFx1MTBFMFx1MTBEOCBcdTEwRThcdTEwRDRcdTEwRTdcdTEwRDVcdTEwRDBcdTEwRENcdTEwRDA6IFx1MTBEQlx1MTBERFx1MTBFMVx1MTBEMFx1MTBEQVx1MTBERFx1MTBEM1x1MTBEQ1x1MTBENFx1MTBEQVx1MTBEOCAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MTBEMFx1MTBFMFx1MTBEMFx1MTBFMVx1MTBFQ1x1MTBERFx1MTBFMFx1MTBEOCBcdTEwRDVcdTEwRDBcdTEwRTBcdTEwRDhcdTEwRDBcdTEwRENcdTEwRTJcdTEwRDg6IFx1MTBEQlx1MTBERFx1MTBFMVx1MTBEMFx1MTBEQVx1MTBERFx1MTBEM1x1MTBEQ1x1MTBENFx1MTBEQVx1MTBEOFx1MTBEMCBcdTEwRDRcdTEwRTBcdTEwRDctXHUxMEQ0XHUxMEUwXHUxMEQ3XHUxMEQ4ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLnZhbHVlcywgXCJ8XCIpfS1cdTEwRDNcdTEwRDBcdTEwRENgO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPD1cIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykgcmV0dXJuIGBcdTEwRDZcdTEwRDRcdTEwRDNcdTEwREJcdTEwRDRcdTEwRTJcdTEwRDBcdTEwRDMgXHUxMEQzXHUxMEQ4XHUxMEQzXHUxMEQ4OiBcdTEwREJcdTEwRERcdTEwRTFcdTEwRDBcdTEwREFcdTEwRERcdTEwRDNcdTEwRENcdTEwRDRcdTEwREFcdTEwRDggJHtpc3N1ZS5vcmlnaW4gPz8gXCJcdTEwREJcdTEwRENcdTEwRDhcdTEwRThcdTEwRDVcdTEwRENcdTEwRDRcdTEwREFcdTEwRERcdTEwRDFcdTEwRDBcIn0gJHtzaXppbmcudmVyYn0gJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXR9YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTEwRDZcdTEwRDRcdTEwRDNcdTEwREJcdTEwRDRcdTEwRTJcdTEwRDBcdTEwRDMgXHUxMEQzXHUxMEQ4XHUxMEQzXHUxMEQ4OiBcdTEwREJcdTEwRERcdTEwRTFcdTEwRDBcdTEwREFcdTEwRERcdTEwRDNcdTEwRENcdTEwRDRcdTEwREFcdTEwRDggJHtpc3N1ZS5vcmlnaW4gPz8gXCJcdTEwREJcdTEwRENcdTEwRDhcdTEwRThcdTEwRDVcdTEwRENcdTEwRDRcdTEwREFcdTEwRERcdTEwRDFcdTEwRDBcIn0gXHUxMEQ4XHUxMEU3XHUxMEREXHUxMEUxICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInRvb19zbWFsbFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI+PVwiIDogXCI+XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MTBENlx1MTBENFx1MTBEM1x1MTBEQlx1MTBENFx1MTBFMlx1MTBEMFx1MTBEMyBcdTEwREVcdTEwRDBcdTEwRTJcdTEwRDBcdTEwRTBcdTEwRDA6IFx1MTBEQlx1MTBERFx1MTBFMVx1MTBEMFx1MTBEQVx1MTBERFx1MTBEM1x1MTBEQ1x1MTBENFx1MTBEQVx1MTBEOCAke2lzc3VlLm9yaWdpbn0gJHtzaXppbmcudmVyYn0gJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXR9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MTBENlx1MTBENFx1MTBEM1x1MTBEQlx1MTBENFx1MTBFMlx1MTBEMFx1MTBEMyBcdTEwREVcdTEwRDBcdTEwRTJcdTEwRDBcdTEwRTBcdTEwRDA6IFx1MTBEQlx1MTBERFx1MTBFMVx1MTBEMFx1MTBEQVx1MTBERFx1MTBEM1x1MTBEQ1x1MTBENFx1MTBEQVx1MTBEOCAke2lzc3VlLm9yaWdpbn0gXHUxMEQ4XHUxMEU3XHUxMEREXHUxMEUxICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZm9ybWF0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBfaXNzdWUgPSBpc3N1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwic3RhcnRzX3dpdGhcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTEwRDBcdTEwRTBcdTEwRDBcdTEwRTFcdTEwRUNcdTEwRERcdTEwRTBcdTEwRDggXHUxMEUxXHUxMEUyXHUxMEUwXHUxMEQ4XHUxMERDXHUxMEQyXHUxMEQ4OiBcdTEwRTNcdTEwRENcdTEwRDNcdTEwRDAgXHUxMEQ4XHUxMEVDXHUxMEU3XHUxMEQ0XHUxMEQxXHUxMEREXHUxMEQzXHUxMEQ0XHUxMEUxIFwiJHtfaXNzdWUucHJlZml4fVwiLVx1MTBEOFx1MTBEN2A7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiZW5kc193aXRoXCIpIHJldHVybiBgXHUxMEQwXHUxMEUwXHUxMEQwXHUxMEUxXHUxMEVDXHUxMEREXHUxMEUwXHUxMEQ4IFx1MTBFMVx1MTBFMlx1MTBFMFx1MTBEOFx1MTBEQ1x1MTBEMlx1MTBEODogXHUxMEUzXHUxMERDXHUxMEQzXHUxMEQwIFx1MTBEQlx1MTBEN1x1MTBEMFx1MTBENVx1MTBFMFx1MTBEM1x1MTBENFx1MTBEMVx1MTBERFx1MTBEM1x1MTBENFx1MTBFMSBcIiR7X2lzc3VlLnN1ZmZpeH1cIi1cdTEwRDhcdTEwRDdgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJpbmNsdWRlc1wiKSByZXR1cm4gYFx1MTBEMFx1MTBFMFx1MTBEMFx1MTBFMVx1MTBFQ1x1MTBERFx1MTBFMFx1MTBEOCBcdTEwRTFcdTEwRTJcdTEwRTBcdTEwRDhcdTEwRENcdTEwRDJcdTEwRDg6IFx1MTBFM1x1MTBEQ1x1MTBEM1x1MTBEMCBcdTEwRThcdTEwRDRcdTEwRDhcdTEwRUFcdTEwRDBcdTEwRDVcdTEwRDNcdTEwRDRcdTEwRTEgXCIke19pc3N1ZS5pbmNsdWRlc31cIi1cdTEwRTFgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYFx1MTBEMFx1MTBFMFx1MTBEMFx1MTBFMVx1MTBFQ1x1MTBERFx1MTBFMFx1MTBEOCBcdTEwRTFcdTEwRTJcdTEwRTBcdTEwRDhcdTEwRENcdTEwRDJcdTEwRDg6IFx1MTBFM1x1MTBEQ1x1MTBEM1x1MTBEMCBcdTEwRThcdTEwRDRcdTEwRDRcdTEwRTFcdTEwRDBcdTEwRDFcdTEwRDBcdTEwREJcdTEwRDRcdTEwRDFcdTEwRERcdTEwRDNcdTEwRDRcdTEwRTEgXHUxMEU4XHUxMEQwXHUxMEQxXHUxMERBXHUxMEREXHUxMERDXHUxMEUxICR7X2lzc3VlLnBhdHRlcm59YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTEwRDBcdTEwRTBcdTEwRDBcdTEwRTFcdTEwRUNcdTEwRERcdTEwRTBcdTEwRDggJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTEwRDBcdTEwRTBcdTEwRDBcdTEwRTFcdTEwRUNcdTEwRERcdTEwRTBcdTEwRDggXHUxMEUwXHUxMEQ4XHUxMEVBXHUxMEVFXHUxMEQ1XHUxMEQ4OiBcdTEwRTNcdTEwRENcdTEwRDNcdTEwRDAgXHUxMEQ4XHUxMEU3XHUxMEREXHUxMEUxICR7aXNzdWUuZGl2aXNvcn0tXHUxMEQ4XHUxMEUxIFx1MTBFRlx1MTBENFx1MTBFMFx1MTBEMFx1MTBEM1x1MTBEOGA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MTBFM1x1MTBFQVx1MTBEQ1x1MTBERFx1MTBEMVx1MTBEOCBcdTEwRDJcdTEwRDBcdTEwRTFcdTEwRDBcdTEwRTZcdTEwRDRcdTEwRDEke2lzc3VlLmtleXMubGVuZ3RoID4gMSA/IFwiXHUxMEQ0XHUxMEQxXHUxMEQ4XCIgOiBcIlx1MTBEOFwifTogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgXCIsIFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfa2V5XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTEwRDBcdTEwRTBcdTEwRDBcdTEwRTFcdTEwRUNcdTEwRERcdTEwRTBcdTEwRDggXHUxMEQyXHUxMEQwXHUxMEUxXHUxMEQwXHUxMEU2XHUxMEQ0XHUxMEQxXHUxMEQ4ICR7aXNzdWUub3JpZ2lufS1cdTEwRThcdTEwRDhgO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTEwRDBcdTEwRTBcdTEwRDBcdTEwRTFcdTEwRUNcdTEwRERcdTEwRTBcdTEwRDggXHUxMEU4XHUxMEQ0XHUxMEU3XHUxMEQ1XHUxMEQwXHUxMERDXHUxMEQwXCI7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9lbGVtZW50XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTEwRDBcdTEwRTBcdTEwRDBcdTEwRTFcdTEwRUNcdTEwRERcdTEwRTBcdTEwRDggXHUxMERCXHUxMERDXHUxMEQ4XHUxMEU4XHUxMEQ1XHUxMERDXHUxMEQ0XHUxMERBXHUxMEREXHUxMEQxXHUxMEQwICR7aXNzdWUub3JpZ2lufS1cdTEwRThcdTEwRDhgO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MTBEMFx1MTBFMFx1MTBEMFx1MTBFMVx1MTBFQ1x1MTBERFx1MTBFMFx1MTBEOCBcdTEwRThcdTEwRDRcdTEwRTdcdTEwRDVcdTEwRDBcdTEwRENcdTEwRDBgO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBsb2NhbGVFcnJvcjogZXJyb3IoKVxuICAgIH07XG59XG4iLCAiaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi4vY29yZS91dGlsLmpzXCI7XG5jb25zdCBlcnJvciA9ICgpPT57XG4gICAgY29uc3QgU2l6YWJsZSA9IHtcbiAgICAgICAgc3RyaW5nOiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MTc4Rlx1MTdCRFx1MTdBMlx1MTc4MFx1MTdEMlx1MTc5Rlx1MTc5QVwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTE3ODJcdTE3QkRcdTE3OUFcdTE3OThcdTE3QjZcdTE3OTNcIlxuICAgICAgICB9LFxuICAgICAgICBmaWxlOiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MTc5NFx1MTdDM1wiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTE3ODJcdTE3QkRcdTE3OUFcdTE3OThcdTE3QjZcdTE3OTNcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJcdTE3OTJcdTE3QjZcdTE3OEZcdTE3QkJcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUxNzgyXHUxN0JEXHUxNzlBXHUxNzk4XHUxN0I2XHUxNzkzXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MTc5Mlx1MTdCNlx1MTc4Rlx1MTdCQlwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTE3ODJcdTE3QkRcdTE3OUFcdTE3OThcdTE3QjZcdTE3OTNcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIlx1MTc5OFx1MTdCN1x1MTc5M1x1MTc5OFx1MTdDMlx1MTc5M1x1MTc4N1x1MTdCNlx1MTc5Qlx1MTdDMVx1MTc4MSAoTmFOKVwiIDogXCJcdTE3OUJcdTE3QzFcdTE3ODFcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiXHUxN0EyXHUxN0I2XHUxNzlBXHUxN0MxIChBcnJheSlcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiXHUxNzgyXHUxN0QyXHUxNzk4XHUxN0I2XHUxNzkzXHUxNzhGXHUxNzk4XHUxN0QyXHUxNzlCXHUxN0MzIChudWxsKVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YoZGF0YSkgIT09IE9iamVjdC5wcm90b3R5cGUgJiYgZGF0YS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdDtcbiAgICB9O1xuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJcdTE3OTFcdTE3QjdcdTE3OTNcdTE3RDJcdTE3OTNcdTE3OTNcdTE3RDBcdTE3OTlcdTE3OTRcdTE3ODlcdTE3RDJcdTE3ODVcdTE3QkNcdTE3OUJcIixcbiAgICAgICAgZW1haWw6IFwiXHUxN0EyXHUxN0I2XHUxNzlGXHUxNzk5XHUxNzhBXHUxN0QyXHUxNzhCXHUxN0I2XHUxNzkzXHUxN0EyXHUxN0NBXHUxN0I4XHUxNzk4XHUxN0MyXHUxNzlCXCIsXG4gICAgICAgIHVybDogXCJVUkxcIixcbiAgICAgICAgZW1vamk6IFwiXHUxNzlGXHUxNzg5XHUxN0QyXHUxNzg5XHUxN0I2XHUxN0EyXHUxN0I2XHUxNzlBXHUxNzk4XHUxN0QyXHUxNzk4XHUxNzhFXHUxN0NEXCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcIlx1MTc4MFx1MTdCNlx1MTc5Qlx1MTc5NFx1MTc5QVx1MTdCN1x1MTc4NVx1MTdEMlx1MTc4Nlx1MTdDMVx1MTc5MSBcdTE3OTNcdTE3QjdcdTE3ODRcdTE3OThcdTE3QzlcdTE3QzRcdTE3ODQgSVNPXCIsXG4gICAgICAgIGRhdGU6IFwiXHUxNzgwXHUxN0I2XHUxNzlCXHUxNzk0XHUxNzlBXHUxN0I3XHUxNzg1XHUxN0QyXHUxNzg2XHUxN0MxXHUxNzkxIElTT1wiLFxuICAgICAgICB0aW1lOiBcIlx1MTc5OFx1MTdDOVx1MTdDNFx1MTc4NCBJU09cIixcbiAgICAgICAgZHVyYXRpb246IFwiXHUxNzlBXHUxNzk5XHUxN0M4XHUxNzk2XHUxN0MxXHUxNzlCIElTT1wiLFxuICAgICAgICBpcHY0OiBcIlx1MTdBMlx1MTdCNlx1MTc5Rlx1MTc5OVx1MTc4QVx1MTdEMlx1MTc4Qlx1MTdCNlx1MTc5MyBJUHY0XCIsXG4gICAgICAgIGlwdjY6IFwiXHUxN0EyXHUxN0I2XHUxNzlGXHUxNzk5XHUxNzhBXHUxN0QyXHUxNzhCXHUxN0I2XHUxNzkzIElQdjZcIixcbiAgICAgICAgY2lkcnY0OiBcIlx1MTc4QVx1MTdDMlx1MTc5M1x1MTdBMlx1MTdCNlx1MTc5Rlx1MTc5OVx1MTc4QVx1MTdEMlx1MTc4Qlx1MTdCNlx1MTc5MyBJUHY0XCIsXG4gICAgICAgIGNpZHJ2NjogXCJcdTE3OEFcdTE3QzJcdTE3OTNcdTE3QTJcdTE3QjZcdTE3OUZcdTE3OTlcdTE3OEFcdTE3RDJcdTE3OEJcdTE3QjZcdTE3OTMgSVB2NlwiLFxuICAgICAgICBiYXNlNjQ6IFwiXHUxNzgxXHUxN0QyXHUxNzlGXHUxN0MyXHUxN0EyXHUxNzgwXHUxN0QyXHUxNzlGXHUxNzlBXHUxN0EyXHUxN0NBXHUxN0I3XHUxNzgwXHUxN0JDXHUxNzhBIGJhc2U2NFwiLFxuICAgICAgICBiYXNlNjR1cmw6IFwiXHUxNzgxXHUxN0QyXHUxNzlGXHUxN0MyXHUxN0EyXHUxNzgwXHUxN0QyXHUxNzlGXHUxNzlBXHUxN0EyXHUxN0NBXHUxN0I3XHUxNzgwXHUxN0JDXHUxNzhBIGJhc2U2NHVybFwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJcdTE3ODFcdTE3RDJcdTE3OUZcdTE3QzJcdTE3QTJcdTE3ODBcdTE3RDJcdTE3OUZcdTE3OUEgSlNPTlwiLFxuICAgICAgICBlMTY0OiBcIlx1MTc5Qlx1MTdDMVx1MTc4MSBFLjE2NFwiLFxuICAgICAgICBqd3Q6IFwiSldUXCIsXG4gICAgICAgIHRlbXBsYXRlX2xpdGVyYWw6IFwiXHUxNzkxXHUxN0I3XHUxNzkzXHUxN0QyXHUxNzkzXHUxNzkzXHUxN0QwXHUxNzk5XHUxNzk0XHUxNzg5XHUxN0QyXHUxNzg1XHUxN0JDXHUxNzlCXCJcbiAgICB9O1xuICAgIHJldHVybiAoaXNzdWUpPT57XG4gICAgICAgIHN3aXRjaChpc3N1ZS5jb2RlKXtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3R5cGVcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MTc5MVx1MTdCN1x1MTc5M1x1MTdEMlx1MTc5M1x1MTc5M1x1MTdEMFx1MTc5OVx1MTc5NFx1MTc4OVx1MTdEMlx1MTc4NVx1MTdCQ1x1MTc5Qlx1MTc5OFx1MTdCN1x1MTc5M1x1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCOVx1MTc5OFx1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCQ1x1MTc5Q1x1MTdENiBcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QkNcdTE3OUNcdTE3ODBcdTE3QjZcdTE3OUEgJHtpc3N1ZS5leHBlY3RlZH0gXHUxNzk0XHUxN0M5XHUxN0JCXHUxNzkzXHUxN0QyXHUxNzhGXHUxN0MyXHUxNzkxXHUxNzkxXHUxN0JEXHUxNzlCXHUxNzk0XHUxN0I2XHUxNzkzICR7cGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgXHUxNzkxXHUxN0I3XHUxNzkzXHUxN0QyXHUxNzkzXHUxNzkzXHUxN0QwXHUxNzk5XHUxNzk0XHUxNzg5XHUxN0QyXHUxNzg1XHUxN0JDXHUxNzlCXHUxNzk4XHUxN0I3XHUxNzkzXHUxNzhGXHUxN0QyXHUxNzlBXHUxN0I5XHUxNzk4XHUxNzhGXHUxN0QyXHUxNzlBXHUxN0JDXHUxNzlDXHUxN0Q2IFx1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCQ1x1MTc5Q1x1MTc4MFx1MTdCNlx1MTc5QSAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MTc4N1x1MTc5OFx1MTdEMlx1MTc5QVx1MTdCRVx1MTc5Rlx1MTc5OFx1MTdCN1x1MTc5M1x1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCOVx1MTc5OFx1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCQ1x1MTc5Q1x1MTdENiBcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QkNcdTE3OUNcdTE3ODdcdTE3QjZcdTE3OThcdTE3QkRcdTE3OTlcdTE3ODBcdTE3RDJcdTE3OTNcdTE3QkJcdTE3ODRcdTE3ODVcdTE3QzZcdTE3OEVcdTE3QzRcdTE3OTggJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIjw9XCIgOiBcIjxcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgXHUxNzkyXHUxN0M2XHUxNzk2XHUxN0MxXHUxNzgwXHUxN0Q2IFx1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCQ1x1MTc5Q1x1MTc4MFx1MTdCNlx1MTc5QSAke2lzc3VlLm9yaWdpbiA/PyBcIlx1MTc4Rlx1MTc5OFx1MTdEMlx1MTc5Qlx1MTdDM1wifSAke2Fkan0gJHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXQgPz8gXCJcdTE3OTJcdTE3QjZcdTE3OEZcdTE3QkJcIn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MTc5Mlx1MTdDNlx1MTc5Nlx1MTdDMVx1MTc4MFx1MTdENiBcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QkNcdTE3OUNcdTE3ODBcdTE3QjZcdTE3OUEgJHtpc3N1ZS5vcmlnaW4gPz8gXCJcdTE3OEZcdTE3OThcdTE3RDJcdTE3OUJcdTE3QzNcIn0gJHthZGp9ICR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInRvb19zbWFsbFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI+PVwiIDogXCI+XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MTc4Rlx1MTdCQ1x1MTc4NVx1MTc5Nlx1MTdDMVx1MTc4MFx1MTdENiBcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QkNcdTE3OUNcdTE3ODBcdTE3QjZcdTE3OUEgJHtpc3N1ZS5vcmlnaW59ICR7YWRqfSAke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdH1gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUxNzhGXHUxN0JDXHUxNzg1XHUxNzk2XHUxN0MxXHUxNzgwXHUxN0Q2IFx1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCQ1x1MTc5Q1x1MTc4MFx1MTdCNlx1MTc5QSAke2lzc3VlLm9yaWdpbn0gJHthZGp9ICR7aXNzdWUubWluaW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZm9ybWF0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBfaXNzdWUgPSBpc3N1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwic3RhcnRzX3dpdGhcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTE3ODFcdTE3RDJcdTE3OUZcdTE3QzJcdTE3QTJcdTE3ODBcdTE3RDJcdTE3OUZcdTE3OUFcdTE3OThcdTE3QjdcdTE3OTNcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QjlcdTE3OThcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QkNcdTE3OUNcdTE3RDYgXHUxNzhGXHUxN0QyXHUxNzlBXHUxN0JDXHUxNzlDXHUxNzg1XHUxN0I2XHUxNzk0XHUxN0NCXHUxNzk1XHUxN0QyXHUxNzhGXHUxN0JFXHUxNzk4XHUxNzhBXHUxN0M0XHUxNzk5IFwiJHtfaXNzdWUucHJlZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJlbmRzX3dpdGhcIikgcmV0dXJuIGBcdTE3ODFcdTE3RDJcdTE3OUZcdTE3QzJcdTE3QTJcdTE3ODBcdTE3RDJcdTE3OUZcdTE3OUFcdTE3OThcdTE3QjdcdTE3OTNcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QjlcdTE3OThcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QkNcdTE3OUNcdTE3RDYgXHUxNzhGXHUxN0QyXHUxNzlBXHUxN0JDXHUxNzlDXHUxNzk0XHUxNzg5XHUxN0QyXHUxNzg1XHUxNzk0XHUxN0NCXHUxNzhBXHUxN0M0XHUxNzk5IFwiJHtfaXNzdWUuc3VmZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBcdTE3ODFcdTE3RDJcdTE3OUZcdTE3QzJcdTE3QTJcdTE3ODBcdTE3RDJcdTE3OUZcdTE3OUFcdTE3OThcdTE3QjdcdTE3OTNcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QjlcdTE3OThcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QkNcdTE3OUNcdTE3RDYgXHUxNzhGXHUxN0QyXHUxNzlBXHUxN0JDXHUxNzlDXHUxNzk4XHUxN0I2XHUxNzkzIFwiJHtfaXNzdWUuaW5jbHVkZXN9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYFx1MTc4MVx1MTdEMlx1MTc5Rlx1MTdDMlx1MTdBMlx1MTc4MFx1MTdEMlx1MTc5Rlx1MTc5QVx1MTc5OFx1MTdCN1x1MTc5M1x1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCOVx1MTc5OFx1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCQ1x1MTc5Q1x1MTdENiBcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QkNcdTE3OUNcdTE3OEZcdTE3QzJcdTE3OTVcdTE3RDJcdTE3ODJcdTE3QkNcdTE3OTVcdTE3RDJcdTE3ODJcdTE3ODRcdTE3OTNcdTE3QjlcdTE3ODRcdTE3OTFcdTE3OThcdTE3RDJcdTE3OUFcdTE3ODRcdTE3Q0JcdTE3OEFcdTE3QzJcdTE3OUJcdTE3OTRcdTE3QjZcdTE3OTNcdTE3ODBcdTE3QzZcdTE3OEVcdTE3OEZcdTE3Q0IgJHtfaXNzdWUucGF0dGVybn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MTc5OFx1MTdCN1x1MTc5M1x1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCOVx1MTc5OFx1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCQ1x1MTc5Q1x1MTdENiAke05vdW5zW19pc3N1ZS5mb3JtYXRdID8/IGlzc3VlLmZvcm1hdH1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJub3RfbXVsdGlwbGVfb2ZcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MTc5Qlx1MTdDMVx1MTc4MVx1MTc5OFx1MTdCN1x1MTc5M1x1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCOVx1MTc5OFx1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCQ1x1MTc5Q1x1MTdENiBcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QkNcdTE3OUNcdTE3OEZcdTE3QzJcdTE3ODdcdTE3QjZcdTE3OTZcdTE3QTBcdTE3QkJcdTE3ODJcdTE3QkJcdTE3OEVcdTE3OTNcdTE3QzMgJHtpc3N1ZS5kaXZpc29yfWA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MTc5QVx1MTc4MFx1MTc4M1x1MTdCRVx1MTc4OVx1MTc5Rlx1MTdDNFx1MTc5OFx1MTdCN1x1MTc5M1x1MTc5Rlx1MTdEMlx1MTc4Mlx1MTdCNlx1MTc5Qlx1MTdDQlx1MTdENiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIiwgXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MTc5Rlx1MTdDNFx1MTc5OFx1MTdCN1x1MTc5M1x1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCOVx1MTc5OFx1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCQ1x1MTc5Q1x1MTc5M1x1MTdDNVx1MTc4MFx1MTdEMlx1MTc5M1x1MTdCQlx1MTc4NCAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MTc5MVx1MTdCN1x1MTc5M1x1MTdEMlx1MTc5M1x1MTc5M1x1MTdEMFx1MTc5OVx1MTc5OFx1MTdCN1x1MTc5M1x1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCOVx1MTc5OFx1MTc4Rlx1MTdEMlx1MTc5QVx1MTdCQ1x1MTc5Q2A7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9lbGVtZW50XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTE3OTFcdTE3QjdcdTE3OTNcdTE3RDJcdTE3OTNcdTE3OTNcdTE3RDBcdTE3OTlcdTE3OThcdTE3QjdcdTE3OTNcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QjlcdTE3OThcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QkNcdTE3OUNcdTE3OTNcdTE3QzVcdTE3ODBcdTE3RDJcdTE3OTNcdTE3QkJcdTE3ODQgJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTE3OTFcdTE3QjdcdTE3OTNcdTE3RDJcdTE3OTNcdTE3OTNcdTE3RDBcdTE3OTlcdTE3OThcdTE3QjdcdTE3OTNcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QjlcdTE3OThcdTE3OEZcdTE3RDJcdTE3OUFcdTE3QkNcdTE3OUNgO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBsb2NhbGVFcnJvcjogZXJyb3IoKVxuICAgIH07XG59XG4iLCAiaW1wb3J0IGttIGZyb20gXCIuL2ttLmpzXCI7XG4vKiogQGRlcHJlY2F0ZWQgVXNlIGBrbWAgaW5zdGVhZC4gKi8gZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGttKCk7XG59XG4iLCAiaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi4vY29yZS91dGlsLmpzXCI7XG5jb25zdCBlcnJvciA9ICgpPT57XG4gICAgY29uc3QgU2l6YWJsZSA9IHtcbiAgICAgICAgc3RyaW5nOiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1QkIzOFx1Qzc5MFwiLFxuICAgICAgICAgICAgdmVyYjogXCJ0byBoYXZlXCJcbiAgICAgICAgfSxcbiAgICAgICAgZmlsZToge1xuICAgICAgICAgICAgdW5pdDogXCJcdUJDMTRcdUM3NzRcdUQyQjhcIixcbiAgICAgICAgICAgIHZlcmI6IFwidG8gaGF2ZVwiXG4gICAgICAgIH0sXG4gICAgICAgIGFycmF5OiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1QUMxQ1wiLFxuICAgICAgICAgICAgdmVyYjogXCJ0byBoYXZlXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1QUMxQ1wiLFxuICAgICAgICAgICAgdmVyYjogXCJ0byBoYXZlXCJcbiAgICAgICAgfVxuICAgIH07XG4gICAgZnVuY3Rpb24gZ2V0U2l6aW5nKG9yaWdpbikge1xuICAgICAgICByZXR1cm4gU2l6YWJsZVtvcmlnaW5dID8/IG51bGw7XG4gICAgfVxuICAgIGNvbnN0IHBhcnNlZFR5cGUgPSAoZGF0YSk9PntcbiAgICAgICAgY29uc3QgdCA9IHR5cGVvZiBkYXRhO1xuICAgICAgICBzd2l0Y2godCl7XG4gICAgICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gTnVtYmVyLmlzTmFOKGRhdGEpID8gXCJOYU5cIiA6IFwibnVtYmVyXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm9iamVjdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcImFycmF5XCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGEgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm51bGxcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKGRhdGEpICE9PSBPYmplY3QucHJvdG90eXBlICYmIGRhdGEuY29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHQ7XG4gICAgfTtcbiAgICBjb25zdCBOb3VucyA9IHtcbiAgICAgICAgcmVnZXg6IFwiXHVDNzg1XHVCODI1XCIsXG4gICAgICAgIGVtYWlsOiBcIlx1Qzc3NFx1QkE1NFx1Qzc3QyBcdUM4RkNcdUMxOENcIixcbiAgICAgICAgdXJsOiBcIlVSTFwiLFxuICAgICAgICBlbW9qaTogXCJcdUM3NzRcdUJBQThcdUM5QzBcIixcbiAgICAgICAgdXVpZDogXCJVVUlEXCIsXG4gICAgICAgIHV1aWR2NDogXCJVVUlEdjRcIixcbiAgICAgICAgdXVpZHY2OiBcIlVVSUR2NlwiLFxuICAgICAgICBuYW5vaWQ6IFwibmFub2lkXCIsXG4gICAgICAgIGd1aWQ6IFwiR1VJRFwiLFxuICAgICAgICBjdWlkOiBcImN1aWRcIixcbiAgICAgICAgY3VpZDI6IFwiY3VpZDJcIixcbiAgICAgICAgdWxpZDogXCJVTElEXCIsXG4gICAgICAgIHhpZDogXCJYSURcIixcbiAgICAgICAga3N1aWQ6IFwiS1NVSURcIixcbiAgICAgICAgZGF0ZXRpbWU6IFwiSVNPIFx1QjBBMFx1QzlEQ1x1QzJEQ1x1QUMwNFwiLFxuICAgICAgICBkYXRlOiBcIklTTyBcdUIwQTBcdUM5RENcIixcbiAgICAgICAgdGltZTogXCJJU08gXHVDMkRDXHVBQzA0XCIsXG4gICAgICAgIGR1cmF0aW9uOiBcIklTTyBcdUFFMzBcdUFDMDRcIixcbiAgICAgICAgaXB2NDogXCJJUHY0IFx1QzhGQ1x1QzE4Q1wiLFxuICAgICAgICBpcHY2OiBcIklQdjYgXHVDOEZDXHVDMThDXCIsXG4gICAgICAgIGNpZHJ2NDogXCJJUHY0IFx1QkM5NFx1QzcwNFwiLFxuICAgICAgICBjaWRydjY6IFwiSVB2NiBcdUJDOTRcdUM3MDRcIixcbiAgICAgICAgYmFzZTY0OiBcImJhc2U2NCBcdUM3NzhcdUNGNTRcdUI1MjkgXHVCQjM4XHVDNzkwXHVDNUY0XCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJiYXNlNjR1cmwgXHVDNzc4XHVDRjU0XHVCNTI5IFx1QkIzOFx1Qzc5MFx1QzVGNFwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJKU09OIFx1QkIzOFx1Qzc5MFx1QzVGNFwiLFxuICAgICAgICBlMTY0OiBcIkUuMTY0IFx1QkM4OFx1RDYzOFwiLFxuICAgICAgICBqd3Q6IFwiSldUXCIsXG4gICAgICAgIHRlbXBsYXRlX2xpdGVyYWw6IFwiXHVDNzg1XHVCODI1XCJcbiAgICB9O1xuICAgIHJldHVybiAoaXNzdWUpPT57XG4gICAgICAgIHN3aXRjaChpc3N1ZS5jb2RlKXtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3R5cGVcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1Qzc5OFx1QkFCQlx1QjQxQyBcdUM3ODVcdUI4MjU6IFx1QzYwOFx1QzBDMSBcdUQwQzBcdUM3ODVcdUM3NDAgJHtpc3N1ZS5leHBlY3RlZH0sIFx1QkMxQlx1Qzc0MCBcdUQwQzBcdUM3ODVcdUM3NDAgJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX1cdUM3ODVcdUIyQzhcdUIyRTRgO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBcdUM3OThcdUJBQkJcdUI0MUMgXHVDNzg1XHVCODI1OiBcdUFDMTJcdUM3NDAgJHt1dGlsLnN0cmluZ2lmeVByaW1pdGl2ZShpc3N1ZS52YWx1ZXNbMF0pfSBcdUM3NzRcdUM1QjRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1Qzc5OFx1QkFCQlx1QjQxQyBcdUM2MzVcdUMxNTg6ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLnZhbHVlcywgXCJcdUI2MTBcdUIyOTQgXCIpfSBcdUM5MTEgXHVENTU4XHVCMDk4XHVDNUVDXHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNGA7XG4gICAgICAgICAgICBjYXNlIFwidG9vX2JpZ1wiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCJcdUM3NzRcdUQ1NThcIiA6IFwiXHVCQkY4XHVCOUNDXCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN1ZmZpeCA9IGFkaiA9PT0gXCJcdUJCRjhcdUI5Q0NcIiA/IFwiXHVDNzc0XHVDNUI0XHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNFwiIDogXCJcdUM1RUNcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB1bml0ID0gc2l6aW5nPy51bml0ID8/IFwiXHVDNjk0XHVDMThDXCI7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgJHtpc3N1ZS5vcmlnaW4gPz8gXCJcdUFDMTJcIn1cdUM3NzQgXHVCMTA4XHVCQjM0IFx1RDA3RFx1QjJDOFx1QjJFNDogJHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9JHt1bml0fSAke2Fkan0ke3N1ZmZpeH1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYCR7aXNzdWUub3JpZ2luID8/IFwiXHVBQzEyXCJ9XHVDNzc0IFx1QjEwOFx1QkIzNCBcdUQwN0RcdUIyQzhcdUIyRTQ6ICR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke2Fkan0ke3N1ZmZpeH1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJ0b29fc21hbGxcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiXHVDNzc0XHVDMEMxXCIgOiBcIlx1Q0QwOFx1QUNGQ1wiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdWZmaXggPSBhZGogPT09IFwiXHVDNzc0XHVDMEMxXCIgPyBcIlx1Qzc3NFx1QzVCNFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTRcIiA6IFwiXHVDNUVDXHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5pdCA9IHNpemluZz8udW5pdCA/PyBcIlx1QzY5NFx1QzE4Q1wiO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYCR7aXNzdWUub3JpZ2luID8/IFwiXHVBQzEyXCJ9XHVDNzc0IFx1QjEwOFx1QkIzNCBcdUM3OTFcdUMyQjVcdUIyQzhcdUIyRTQ6ICR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSR7dW5pdH0gJHthZGp9JHtzdWZmaXh9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYCR7aXNzdWUub3JpZ2luID8/IFwiXHVBQzEyXCJ9XHVDNzc0IFx1QjEwOFx1QkIzNCBcdUM3OTFcdUMyQjVcdUIyQzhcdUIyRTQ6ICR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke2Fkan0ke3N1ZmZpeH1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2Zvcm1hdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgX2lzc3VlID0gaXNzdWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInN0YXJ0c193aXRoXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHVDNzk4XHVCQUJCXHVCNDFDIFx1QkIzOFx1Qzc5MFx1QzVGNDogXCIke19pc3N1ZS5wcmVmaXh9XCIoXHVDNzNDKVx1Qjg1QyBcdUMyRENcdUM3OTFcdUQ1NzRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJlbmRzX3dpdGhcIikgcmV0dXJuIGBcdUM3OThcdUJBQkJcdUI0MUMgXHVCQjM4XHVDNzkwXHVDNUY0OiBcIiR7X2lzc3VlLnN1ZmZpeH1cIihcdUM3M0MpXHVCODVDIFx1QjA1RFx1QjA5OFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTRgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJpbmNsdWRlc1wiKSByZXR1cm4gYFx1Qzc5OFx1QkFCQlx1QjQxQyBcdUJCMzhcdUM3OTBcdUM1RjQ6IFwiJHtfaXNzdWUuaW5jbHVkZXN9XCJcdUM3NDQoXHVCOTdDKSBcdUQzRUNcdUQ1NjhcdUQ1NzRcdUM1N0MgXHVENTY5XHVCMkM4XHVCMkU0YDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBcdUM3OThcdUJBQkJcdUI0MUMgXHVCQjM4XHVDNzkwXHVDNUY0OiBcdUM4MTVcdUFERENcdUMyREQgJHtfaXNzdWUucGF0dGVybn0gXHVEMzI4XHVEMTM0XHVBQ0ZDIFx1Qzc3Q1x1Q0U1OFx1RDU3NFx1QzU3QyBcdUQ1NjlcdUIyQzhcdUIyRTRgO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1Qzc5OFx1QkFCQlx1QjQxQyAke05vdW5zW19pc3N1ZS5mb3JtYXRdID8/IGlzc3VlLmZvcm1hdH1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJub3RfbXVsdGlwbGVfb2ZcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1Qzc5OFx1QkFCQlx1QjQxQyBcdUMyMkJcdUM3OTA6ICR7aXNzdWUuZGl2aXNvcn1cdUM3NTggXHVCQzMwXHVDMjE4XHVDNUVDXHVDNTdDIFx1RDU2OVx1QjJDOFx1QjJFNGA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1Qzc3OFx1QzJERFx1RDU2MCBcdUMyMTggXHVDNUM2XHVCMjk0IFx1RDBBNDogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgXCIsIFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfa2V5XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdUM3OThcdUJBQkJcdUI0MUMgXHVEMEE0OiAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1Qzc5OFx1QkFCQlx1QjQxQyBcdUM3ODVcdUI4MjVgO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZWxlbWVudFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHVDNzk4XHVCQUJCXHVCNDFDIFx1QUMxMjogJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdUM3OThcdUJBQkJcdUI0MUMgXHVDNzg1XHVCODI1YDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuZXhwb3J0IGNvbnN0IHBhcnNlZFR5cGUgPSAoZGF0YSk9PntcbiAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgcmV0dXJuIHBhcnNlZFR5cGVGcm9tVHlwZSh0LCBkYXRhKTtcbn07XG5jb25zdCBwYXJzZWRUeXBlRnJvbVR5cGUgPSAodCwgZGF0YSA9IHVuZGVmaW5lZCk9PntcbiAgICBzd2l0Y2godCl7XG4gICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gTnVtYmVyLmlzTmFOKGRhdGEpID8gXCJOYU5cIiA6IFwic2thaVx1MDEwRGl1c1wiO1xuICAgICAgICAgICAgfVxuICAgICAgICBjYXNlIFwiYmlnaW50XCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwic3ZlaWthc2lzIHNrYWlcdTAxMERpdXNcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgY2FzZSBcInN0cmluZ1wiOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHJldHVybiBcImVpbHV0XHUwMTE3XCI7XG4gICAgICAgICAgICB9XG4gICAgICAgIGNhc2UgXCJib29sZWFuXCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwibG9naW5cdTAxMTcgcmVpa1x1MDE2MW1cdTAxMTdcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgY2FzZSBcInVuZGVmaW5lZFwiOlxuICAgICAgICBjYXNlIFwidm9pZFwiOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHJldHVybiBcIm5lYXBpYnJcdTAxMTdcdTAxN0V0YSByZWlrXHUwMTYxbVx1MDExN1wiO1xuICAgICAgICAgICAgfVxuICAgICAgICBjYXNlIFwiZnVuY3Rpb25cIjpcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJmdW5rY2lqYVwiO1xuICAgICAgICAgICAgfVxuICAgICAgICBjYXNlIFwic3ltYm9sXCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwic2ltYm9saXNcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgY2FzZSBcIm9iamVjdFwiOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSB1bmRlZmluZWQpIHJldHVybiBcIm5lXHUwMTdFaW5vbWFzIG9iamVrdGFzXCI7XG4gICAgICAgICAgICAgICAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiBcIm51bGluXHUwMTE3IHJlaWtcdTAxNjFtXHUwMTE3XCI7XG4gICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHJldHVybiBcIm1hc3l2YXNcIjtcbiAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKGRhdGEpICE9PSBPYmplY3QucHJvdG90eXBlICYmIGRhdGEuY29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwib2JqZWt0YXNcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgLy9ab2QgdHlwZXMgYmVsb3dcbiAgICAgICAgY2FzZSBcIm51bGxcIjpcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJudWxpblx1MDExNyByZWlrXHUwMTYxbVx1MDExN1wiO1xuICAgICAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdDtcbn07XG5jb25zdCBjYXBpdGFsaXplRmlyc3RDaGFyYWN0ZXIgPSAodGV4dCk9PntcbiAgICByZXR1cm4gdGV4dC5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHRleHQuc2xpY2UoMSk7XG59O1xuZnVuY3Rpb24gZ2V0VW5pdFR5cGVGcm9tTnVtYmVyKG51bWJlcikge1xuICAgIGNvbnN0IGFicyA9IE1hdGguYWJzKG51bWJlcik7XG4gICAgY29uc3QgbGFzdCA9IGFicyAlIDEwO1xuICAgIGNvbnN0IGxhc3QyID0gYWJzICUgMTAwO1xuICAgIGlmIChsYXN0MiA+PSAxMSAmJiBsYXN0MiA8PSAxOSB8fCBsYXN0ID09PSAwKSByZXR1cm4gXCJtYW55XCI7XG4gICAgaWYgKGxhc3QgPT09IDEpIHJldHVybiBcIm9uZVwiO1xuICAgIHJldHVybiBcImZld1wiO1xufVxuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDoge1xuICAgICAgICAgICAgICAgIG9uZTogXCJzaW1ib2xpc1wiLFxuICAgICAgICAgICAgICAgIGZldzogXCJzaW1ib2xpYWlcIixcbiAgICAgICAgICAgICAgICBtYW55OiBcInNpbWJvbGlcdTAxNzNcIlxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHZlcmI6IHtcbiAgICAgICAgICAgICAgICBzbWFsbGVyOiB7XG4gICAgICAgICAgICAgICAgICAgIGluY2x1c2l2ZTogXCJ0dXJpIGJcdTAxNkJ0aSBuZSBpbGdlc25cdTAxMTcga2FpcFwiLFxuICAgICAgICAgICAgICAgICAgICBub3RJbmNsdXNpdmU6IFwidHVyaSBiXHUwMTZCdGkgdHJ1bXBlc25cdTAxMTcga2FpcFwiXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBiaWdnZXI6IHtcbiAgICAgICAgICAgICAgICAgICAgaW5jbHVzaXZlOiBcInR1cmkgYlx1MDE2QnRpIG5lIHRydW1wZXNuXHUwMTE3IGthaXBcIixcbiAgICAgICAgICAgICAgICAgICAgbm90SW5jbHVzaXZlOiBcInR1cmkgYlx1MDE2QnRpIGlsZ2Vzblx1MDExNyBrYWlwXCJcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IHtcbiAgICAgICAgICAgICAgICBvbmU6IFwiYmFpdGFzXCIsXG4gICAgICAgICAgICAgICAgZmV3OiBcImJhaXRhaVwiLFxuICAgICAgICAgICAgICAgIG1hbnk6IFwiYmFpdFx1MDE3M1wiXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdmVyYjoge1xuICAgICAgICAgICAgICAgIHNtYWxsZXI6IHtcbiAgICAgICAgICAgICAgICAgICAgaW5jbHVzaXZlOiBcInR1cmkgYlx1MDE2QnRpIG5lIGRpZGVzbmlzIGthaXBcIixcbiAgICAgICAgICAgICAgICAgICAgbm90SW5jbHVzaXZlOiBcInR1cmkgYlx1MDE2QnRpIG1hXHUwMTdFZXNuaXMga2FpcFwiXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBiaWdnZXI6IHtcbiAgICAgICAgICAgICAgICAgICAgaW5jbHVzaXZlOiBcInR1cmkgYlx1MDE2QnRpIG5lIG1hXHUwMTdFZXNuaXMga2FpcFwiLFxuICAgICAgICAgICAgICAgICAgICBub3RJbmNsdXNpdmU6IFwidHVyaSBiXHUwMTZCdGkgZGlkZXNuaXMga2FpcFwiXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDoge1xuICAgICAgICAgICAgICAgIG9uZTogXCJlbGVtZW50XHUwMTA1XCIsXG4gICAgICAgICAgICAgICAgZmV3OiBcImVsZW1lbnR1c1wiLFxuICAgICAgICAgICAgICAgIG1hbnk6IFwiZWxlbWVudFx1MDE3M1wiXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdmVyYjoge1xuICAgICAgICAgICAgICAgIHNtYWxsZXI6IHtcbiAgICAgICAgICAgICAgICAgICAgaW5jbHVzaXZlOiBcInR1cmkgdHVyXHUwMTE3dGkgbmUgZGF1Z2lhdSBrYWlwXCIsXG4gICAgICAgICAgICAgICAgICAgIG5vdEluY2x1c2l2ZTogXCJ0dXJpIHR1clx1MDExN3RpIG1hXHUwMTdFaWF1IGthaXBcIlxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgYmlnZ2VyOiB7XG4gICAgICAgICAgICAgICAgICAgIGluY2x1c2l2ZTogXCJ0dXJpIHR1clx1MDExN3RpIG5lIG1hXHUwMTdFaWF1IGthaXBcIixcbiAgICAgICAgICAgICAgICAgICAgbm90SW5jbHVzaXZlOiBcInR1cmkgdHVyXHUwMTE3dGkgZGF1Z2lhdSBrYWlwXCJcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDoge1xuICAgICAgICAgICAgICAgIG9uZTogXCJlbGVtZW50XHUwMTA1XCIsXG4gICAgICAgICAgICAgICAgZmV3OiBcImVsZW1lbnR1c1wiLFxuICAgICAgICAgICAgICAgIG1hbnk6IFwiZWxlbWVudFx1MDE3M1wiXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdmVyYjoge1xuICAgICAgICAgICAgICAgIHNtYWxsZXI6IHtcbiAgICAgICAgICAgICAgICAgICAgaW5jbHVzaXZlOiBcInR1cmkgdHVyXHUwMTE3dGkgbmUgZGF1Z2lhdSBrYWlwXCIsXG4gICAgICAgICAgICAgICAgICAgIG5vdEluY2x1c2l2ZTogXCJ0dXJpIHR1clx1MDExN3RpIG1hXHUwMTdFaWF1IGthaXBcIlxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgYmlnZ2VyOiB7XG4gICAgICAgICAgICAgICAgICAgIGluY2x1c2l2ZTogXCJ0dXJpIHR1clx1MDExN3RpIG5lIG1hXHUwMTdFaWF1IGthaXBcIixcbiAgICAgICAgICAgICAgICAgICAgbm90SW5jbHVzaXZlOiBcInR1cmkgdHVyXHUwMTE3dGkgZGF1Z2lhdSBrYWlwXCJcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4sIHVuaXRUeXBlLCBpbmNsdXNpdmUsIHRhcmdldFNob3VsZEJlKSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgICAgICBpZiAocmVzdWx0ID09PSBudWxsKSByZXR1cm4gcmVzdWx0O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdW5pdDogcmVzdWx0LnVuaXRbdW5pdFR5cGVdLFxuICAgICAgICAgICAgdmVyYjogcmVzdWx0LnZlcmJbdGFyZ2V0U2hvdWxkQmVdW2luY2x1c2l2ZSA/IFwiaW5jbHVzaXZlXCIgOiBcIm5vdEluY2x1c2l2ZVwiXVxuICAgICAgICB9O1xuICAgIH1cbiAgICBjb25zdCBOb3VucyA9IHtcbiAgICAgICAgcmVnZXg6IFwiXHUwMTJGdmVzdGlzXCIsXG4gICAgICAgIGVtYWlsOiBcImVsLiBwYVx1MDE2MXRvIGFkcmVzYXNcIixcbiAgICAgICAgdXJsOiBcIlVSTFwiLFxuICAgICAgICBlbW9qaTogXCJqYXVzdHVrYXNcIixcbiAgICAgICAgdXVpZDogXCJVVUlEXCIsXG4gICAgICAgIHV1aWR2NDogXCJVVUlEdjRcIixcbiAgICAgICAgdXVpZHY2OiBcIlVVSUR2NlwiLFxuICAgICAgICBuYW5vaWQ6IFwibmFub2lkXCIsXG4gICAgICAgIGd1aWQ6IFwiR1VJRFwiLFxuICAgICAgICBjdWlkOiBcImN1aWRcIixcbiAgICAgICAgY3VpZDI6IFwiY3VpZDJcIixcbiAgICAgICAgdWxpZDogXCJVTElEXCIsXG4gICAgICAgIHhpZDogXCJYSURcIixcbiAgICAgICAga3N1aWQ6IFwiS1NVSURcIixcbiAgICAgICAgZGF0ZXRpbWU6IFwiSVNPIGRhdGEgaXIgbGFpa2FzXCIsXG4gICAgICAgIGRhdGU6IFwiSVNPIGRhdGFcIixcbiAgICAgICAgdGltZTogXCJJU08gbGFpa2FzXCIsXG4gICAgICAgIGR1cmF0aW9uOiBcIklTTyB0cnVrbVx1MDExN1wiLFxuICAgICAgICBpcHY0OiBcIklQdjQgYWRyZXNhc1wiLFxuICAgICAgICBpcHY2OiBcIklQdjYgYWRyZXNhc1wiLFxuICAgICAgICBjaWRydjQ6IFwiSVB2NCB0aW5rbG8gcHJlZmlrc2FzIChDSURSKVwiLFxuICAgICAgICBjaWRydjY6IFwiSVB2NiB0aW5rbG8gcHJlZmlrc2FzIChDSURSKVwiLFxuICAgICAgICBiYXNlNjQ6IFwiYmFzZTY0IHVcdTAxN0Vrb2R1b3RhIGVpbHV0XHUwMTE3XCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJiYXNlNjR1cmwgdVx1MDE3RWtvZHVvdGEgZWlsdXRcdTAxMTdcIixcbiAgICAgICAganNvbl9zdHJpbmc6IFwiSlNPTiBlaWx1dFx1MDExN1wiLFxuICAgICAgICBlMTY0OiBcIkUuMTY0IG51bWVyaXNcIixcbiAgICAgICAgand0OiBcIkpXVFwiLFxuICAgICAgICB0ZW1wbGF0ZV9saXRlcmFsOiBcIlx1MDEyRnZlc3Rpc1wiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBHYXV0YXMgdGlwYXMgJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX0sIG8gdGlrXHUwMTE3dGFzaSAtICR7cGFyc2VkVHlwZUZyb21UeXBlKGlzc3VlLmV4cGVjdGVkKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBQcml2YWxvIGJcdTAxNkJ0aSAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYFByaXZhbG8gYlx1MDE2QnRpIHZpZW5hcyBpXHUwMTYxICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLnZhbHVlcywgXCJ8XCIpfSBwYXNpcmlua2ltXHUwMTczYDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBvcmlnaW4gPSBwYXJzZWRUeXBlRnJvbVR5cGUoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbiwgZ2V0VW5pdFR5cGVGcm9tTnVtYmVyKE51bWJlcihpc3N1ZS5tYXhpbXVtKSksIGlzc3VlLmluY2x1c2l2ZSA/PyBmYWxzZSwgXCJzbWFsbGVyXCIpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nPy52ZXJiKSByZXR1cm4gYCR7Y2FwaXRhbGl6ZUZpcnN0Q2hhcmFjdGVyKG9yaWdpbiA/PyBpc3N1ZS5vcmlnaW4gPz8gXCJyZWlrXHUwMTYxbVx1MDExN1wiKX0gJHtzaXppbmcudmVyYn0gJHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXQgPz8gXCJlbGVtZW50XHUwMTczXCJ9YDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCJuZSBkaWRlc25pcyBrYWlwXCIgOiBcIm1hXHUwMTdFZXNuaXMga2FpcFwiO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYCR7Y2FwaXRhbGl6ZUZpcnN0Q2hhcmFjdGVyKG9yaWdpbiA/PyBpc3N1ZS5vcmlnaW4gPz8gXCJyZWlrXHUwMTYxbVx1MDExN1wiKX0gdHVyaSBiXHUwMTZCdGkgJHthZGp9ICR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke3NpemluZz8udW5pdH1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJ0b29fc21hbGxcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG9yaWdpbiA9IHBhcnNlZFR5cGVGcm9tVHlwZShpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luLCBnZXRVbml0VHlwZUZyb21OdW1iZXIoTnVtYmVyKGlzc3VlLm1pbmltdW0pKSwgaXNzdWUuaW5jbHVzaXZlID8/IGZhbHNlLCBcImJpZ2dlclwiKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZz8udmVyYikgcmV0dXJuIGAke2NhcGl0YWxpemVGaXJzdENoYXJhY3RlcihvcmlnaW4gPz8gaXNzdWUub3JpZ2luID8/IFwicmVpa1x1MDE2MW1cdTAxMTdcIil9ICR7c2l6aW5nLnZlcmJ9ICR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0ID8/IFwiZWxlbWVudFx1MDE3M1wifWA7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwibmUgbWFcdTAxN0Vlc25pcyBrYWlwXCIgOiBcImRpZGVzbmlzIGthaXBcIjtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGAke2NhcGl0YWxpemVGaXJzdENoYXJhY3RlcihvcmlnaW4gPz8gaXNzdWUub3JpZ2luID8/IFwicmVpa1x1MDE2MW1cdTAxMTdcIil9IHR1cmkgYlx1MDE2QnRpICR7YWRqfSAke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gJHtzaXppbmc/LnVuaXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYEVpbHV0XHUwMTE3IHByaXZhbG8gcHJhc2lkXHUwMTE3dGkgXCIke19pc3N1ZS5wcmVmaXh9XCJgO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYEVpbHV0XHUwMTE3IHByaXZhbG8gcGFzaWJhaWd0aSBcIiR7X2lzc3VlLnN1ZmZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImluY2x1ZGVzXCIpIHJldHVybiBgRWlsdXRcdTAxMTcgcHJpdmFsbyBcdTAxMkZ0cmF1a3RpIFwiJHtfaXNzdWUuaW5jbHVkZXN9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYEVpbHV0XHUwMTE3IHByaXZhbG8gYXRpdGlrdGkgJHtfaXNzdWUucGF0dGVybn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYE5ldGVpc2luZ2FzICR7Tm91bnNbX2lzc3VlLmZvcm1hdF0gPz8gaXNzdWUuZm9ybWF0fWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm5vdF9tdWx0aXBsZV9vZlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgU2thaVx1MDEwRGl1cyBwcml2YWxvIGJcdTAxNkJ0aSAke2lzc3VlLmRpdmlzb3J9IGthcnRvdGluaXMuYDtcbiAgICAgICAgICAgIGNhc2UgXCJ1bnJlY29nbml6ZWRfa2V5c1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgTmVhdHBhXHUwMTdFaW50JHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcImlcIiA6IFwiYXNcIn0gcmFrdCR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJhaVwiIDogXCJhc1wifTogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgXCIsIFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfa2V5XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiUmFzdGFzIGtsYWlkaW5nYXMgcmFrdGFzXCI7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF91bmlvblwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIktsYWlkaW5nYSBcdTAxMkZ2ZXN0aXNcIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG9yaWdpbiA9IHBhcnNlZFR5cGVGcm9tVHlwZShpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYCR7Y2FwaXRhbGl6ZUZpcnN0Q2hhcmFjdGVyKG9yaWdpbiA/PyBpc3N1ZS5vcmlnaW4gPz8gXCJyZWlrXHUwMTYxbVx1MDExN1wiKX0gdHVyaSBrbGFpZGluZ1x1MDEwNSBcdTAxMkZ2ZXN0XHUwMTJGYDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBcIktsYWlkaW5nYSBcdTAxMkZ2ZXN0aXNcIjtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJcdTA0MzdcdTA0M0RcdTA0MzBcdTA0NDZcdTA0MzhcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwNDM0XHUwNDMwIFx1MDQzOFx1MDQzQ1x1MDQzMFx1MDQzMFx1MDQ0MlwiXG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHUwNDMxXHUwNDMwXHUwNDU4XHUwNDQyXHUwNDM4XCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MDQzNFx1MDQzMCBcdTA0MzhcdTA0M0NcdTA0MzBcdTA0MzBcdTA0NDJcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJcdTA0NDFcdTA0NDJcdTA0MzBcdTA0MzJcdTA0M0FcdTA0MzhcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwNDM0XHUwNDMwIFx1MDQzOFx1MDQzQ1x1MDQzMFx1MDQzMFx1MDQ0MlwiXG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDogXCJcdTA0NDFcdTA0NDJcdTA0MzBcdTA0MzJcdTA0M0FcdTA0MzhcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwNDM0XHUwNDMwIFx1MDQzOFx1MDQzQ1x1MDQzMFx1MDQzMFx1MDQ0MlwiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4pIHtcbiAgICAgICAgcmV0dXJuIFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWRUeXBlID0gKGRhdGEpPT57XG4gICAgICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICAgICAgc3dpdGNoKHQpe1xuICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIlx1MDQzMVx1MDQ0MFx1MDQzRVx1MDQ1OFwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTA0M0RcdTA0MzhcdTA0MzdcdTA0MzBcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YoZGF0YSkgIT09IE9iamVjdC5wcm90b3R5cGUgJiYgZGF0YS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdDtcbiAgICB9O1xuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJcdTA0MzJcdTA0M0RcdTA0MzVcdTA0NDFcIixcbiAgICAgICAgZW1haWw6IFwiXHUwNDMwXHUwNDM0XHUwNDQwXHUwNDM1XHUwNDQxXHUwNDMwIFx1MDQzRFx1MDQzMCBcdTA0MzUtXHUwNDNGXHUwNDNFXHUwNDQ4XHUwNDQyXHUwNDMwXCIsXG4gICAgICAgIHVybDogXCJVUkxcIixcbiAgICAgICAgZW1vamk6IFwiXHUwNDM1XHUwNDNDXHUwNDNFXHUwNDVGXHUwNDM4XCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcIklTTyBcdTA0MzRcdTA0MzBcdTA0NDJcdTA0NDNcdTA0M0MgXHUwNDM4IFx1MDQzMlx1MDQ0MFx1MDQzNVx1MDQzQ1x1MDQzNVwiLFxuICAgICAgICBkYXRlOiBcIklTTyBcdTA0MzRcdTA0MzBcdTA0NDJcdTA0NDNcdTA0M0NcIixcbiAgICAgICAgdGltZTogXCJJU08gXHUwNDMyXHUwNDQwXHUwNDM1XHUwNDNDXHUwNDM1XCIsXG4gICAgICAgIGR1cmF0aW9uOiBcIklTTyBcdTA0MzJcdTA0NDBcdTA0MzVcdTA0M0NcdTA0MzVcdTA0NDJcdTA0NDBcdTA0MzBcdTA0MzVcdTA0NUFcdTA0MzVcIixcbiAgICAgICAgaXB2NDogXCJJUHY0IFx1MDQzMFx1MDQzNFx1MDQ0MFx1MDQzNVx1MDQ0MVx1MDQzMFwiLFxuICAgICAgICBpcHY2OiBcIklQdjYgXHUwNDMwXHUwNDM0XHUwNDQwXHUwNDM1XHUwNDQxXHUwNDMwXCIsXG4gICAgICAgIGNpZHJ2NDogXCJJUHY0IFx1MDQzRVx1MDQzRlx1MDQ0MVx1MDQzNVx1MDQzM1wiLFxuICAgICAgICBjaWRydjY6IFwiSVB2NiBcdTA0M0VcdTA0M0ZcdTA0NDFcdTA0MzVcdTA0MzNcIixcbiAgICAgICAgYmFzZTY0OiBcImJhc2U2NC1cdTA0MzVcdTA0M0RcdTA0M0FcdTA0M0VcdTA0MzRcdTA0MzhcdTA0NDBcdTA0MzBcdTA0M0RcdTA0MzAgXHUwNDNEXHUwNDM4XHUwNDM3XHUwNDMwXCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJiYXNlNjR1cmwtXHUwNDM1XHUwNDNEXHUwNDNBXHUwNDNFXHUwNDM0XHUwNDM4XHUwNDQwXHUwNDMwXHUwNDNEXHUwNDMwIFx1MDQzRFx1MDQzOFx1MDQzN1x1MDQzMFwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJKU09OIFx1MDQzRFx1MDQzOFx1MDQzN1x1MDQzMFwiLFxuICAgICAgICBlMTY0OiBcIkUuMTY0IFx1MDQzMVx1MDQ0MFx1MDQzRVx1MDQ1OFwiLFxuICAgICAgICBqd3Q6IFwiSldUXCIsXG4gICAgICAgIHRlbXBsYXRlX2xpdGVyYWw6IFwiXHUwNDMyXHUwNDNEXHUwNDM1XHUwNDQxXCJcbiAgICB9O1xuICAgIHJldHVybiAoaXNzdWUpPT57XG4gICAgICAgIHN3aXRjaChpc3N1ZS5jb2RlKXtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3R5cGVcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDQxM1x1MDQ0MFx1MDQzNVx1MDQ0OFx1MDQzNVx1MDQzRCBcdTA0MzJcdTA0M0RcdTA0MzVcdTA0NDE6IFx1MDQ0MVx1MDQzNSBcdTA0M0VcdTA0NDdcdTA0MzVcdTA0M0FcdTA0NDNcdTA0MzJcdTA0MzAgJHtpc3N1ZS5leHBlY3RlZH0sIFx1MDQzRlx1MDQ0MFx1MDQzOFx1MDQzQ1x1MDQzNVx1MDQzRFx1MDQzRSAke3BhcnNlZFR5cGUoaXNzdWUuaW5wdXQpfWA7XG4gICAgICAgICAgICAvLyByZXR1cm4gYEludmFsaWQgaW5wdXQ6IGV4cGVjdGVkICR7aXNzdWUuZXhwZWN0ZWR9LCByZWNlaXZlZCAke3V0aWwuZ2V0UGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgSW52YWxpZCBpbnB1dDogZXhwZWN0ZWQgJHt1dGlsLnN0cmluZ2lmeVByaW1pdGl2ZShpc3N1ZS52YWx1ZXNbMF0pfWA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MTNcdTA0NDBcdTA0MzVcdTA0NDhcdTA0MzBcdTA0M0RcdTA0MzAgXHUwNDNFXHUwNDNGXHUwNDQ2XHUwNDM4XHUwNDU4XHUwNDMwOiBcdTA0NDFcdTA0MzUgXHUwNDNFXHUwNDQ3XHUwNDM1XHUwNDNBXHUwNDQzXHUwNDMyXHUwNDMwIFx1MDQzNVx1MDQzNFx1MDQzRFx1MDQzMCAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS52YWx1ZXMsIFwifFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPD1cIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykgcmV0dXJuIGBcdTA0MUZcdTA0NDBcdTA0MzVcdTA0M0NcdTA0M0RcdTA0M0VcdTA0MzNcdTA0NDMgXHUwNDMzXHUwNDNFXHUwNDNCXHUwNDM1XHUwNDNDOiBcdTA0NDFcdTA0MzUgXHUwNDNFXHUwNDQ3XHUwNDM1XHUwNDNBXHUwNDQzXHUwNDMyXHUwNDMwICR7aXNzdWUub3JpZ2luID8/IFwiXHUwNDMyXHUwNDQwXHUwNDM1XHUwNDM0XHUwNDNEXHUwNDNFXHUwNDQxXHUwNDQyXHUwNDMwXCJ9IFx1MDQzNFx1MDQzMCBcdTA0MzhcdTA0M0NcdTA0MzAgJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXQgPz8gXCJcdTA0MzVcdTA0M0JcdTA0MzVcdTA0M0NcdTA0MzVcdTA0M0RcdTA0NDJcdTA0MzhcIn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDQxRlx1MDQ0MFx1MDQzNVx1MDQzQ1x1MDQzRFx1MDQzRVx1MDQzM1x1MDQ0MyBcdTA0MzNcdTA0M0VcdTA0M0JcdTA0MzVcdTA0M0M6IFx1MDQ0MVx1MDQzNSBcdTA0M0VcdTA0NDdcdTA0MzVcdTA0M0FcdTA0NDNcdTA0MzJcdTA0MzAgJHtpc3N1ZS5vcmlnaW4gPz8gXCJcdTA0MzJcdTA0NDBcdTA0MzVcdTA0MzRcdTA0M0RcdTA0M0VcdTA0NDFcdTA0NDJcdTA0MzBcIn0gXHUwNDM0XHUwNDMwIFx1MDQzMVx1MDQzOFx1MDQzNFx1MDQzNSAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJ0b29fc21hbGxcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPj1cIiA6IFwiPlwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MUZcdTA0NDBcdTA0MzVcdTA0M0NcdTA0M0RcdTA0M0VcdTA0MzNcdTA0NDMgXHUwNDNDXHUwNDMwXHUwNDNCOiBcdTA0NDFcdTA0MzUgXHUwNDNFXHUwNDQ3XHUwNDM1XHUwNDNBXHUwNDQzXHUwNDMyXHUwNDMwICR7aXNzdWUub3JpZ2lufSBcdTA0MzRcdTA0MzAgXHUwNDM4XHUwNDNDXHUwNDMwICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0fWA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MUZcdTA0NDBcdTA0MzVcdTA0M0NcdTA0M0RcdTA0M0VcdTA0MzNcdTA0NDMgXHUwNDNDXHUwNDMwXHUwNDNCOiBcdTA0NDFcdTA0MzUgXHUwNDNFXHUwNDQ3XHUwNDM1XHUwNDNBXHUwNDQzXHUwNDMyXHUwNDMwICR7aXNzdWUub3JpZ2lufSBcdTA0MzRcdTA0MzAgXHUwNDMxXHUwNDM4XHUwNDM0XHUwNDM1ICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZm9ybWF0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBfaXNzdWUgPSBpc3N1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwic3RhcnRzX3dpdGhcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MURcdTA0MzVcdTA0MzJcdTA0MzBcdTA0MzZcdTA0MzVcdTA0NDdcdTA0M0FcdTA0MzAgXHUwNDNEXHUwNDM4XHUwNDM3XHUwNDMwOiBcdTA0M0NcdTA0M0VcdTA0NDBcdTA0MzAgXHUwNDM0XHUwNDMwIFx1MDQzN1x1MDQzMFx1MDQzRlx1MDQzRVx1MDQ0N1x1MDQzRFx1MDQ0M1x1MDQzMlx1MDQzMCBcdTA0NDFcdTA0M0UgXCIke19pc3N1ZS5wcmVmaXh9XCJgO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYFx1MDQxRFx1MDQzNVx1MDQzMlx1MDQzMFx1MDQzNlx1MDQzNVx1MDQ0N1x1MDQzQVx1MDQzMCBcdTA0M0RcdTA0MzhcdTA0MzdcdTA0MzA6IFx1MDQzQ1x1MDQzRVx1MDQ0MFx1MDQzMCBcdTA0MzRcdTA0MzAgXHUwNDM3XHUwNDMwXHUwNDMyXHUwNDQwXHUwNDQ4XHUwNDQzXHUwNDMyXHUwNDMwIFx1MDQ0MVx1MDQzRSBcIiR7X2lzc3VlLnN1ZmZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImluY2x1ZGVzXCIpIHJldHVybiBgXHUwNDFEXHUwNDM1XHUwNDMyXHUwNDMwXHUwNDM2XHUwNDM1XHUwNDQ3XHUwNDNBXHUwNDMwIFx1MDQzRFx1MDQzOFx1MDQzN1x1MDQzMDogXHUwNDNDXHUwNDNFXHUwNDQwXHUwNDMwIFx1MDQzNFx1MDQzMCBcdTA0MzJcdTA0M0FcdTA0M0JcdTA0NDNcdTA0NDdcdTA0NDNcdTA0MzJcdTA0MzAgXCIke19pc3N1ZS5pbmNsdWRlc31cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInJlZ2V4XCIpIHJldHVybiBgXHUwNDFEXHUwNDM1XHUwNDMyXHUwNDMwXHUwNDM2XHUwNDM1XHUwNDQ3XHUwNDNBXHUwNDMwIFx1MDQzRFx1MDQzOFx1MDQzN1x1MDQzMDogXHUwNDNDXHUwNDNFXHUwNDQwXHUwNDMwIFx1MDQzNFx1MDQzMCBcdTA0M0VcdTA0MzRcdTA0MzNcdTA0M0VcdTA0MzBcdTA0NDBcdTA0MzAgXHUwNDNEXHUwNDMwIFx1MDQzRlx1MDQzMFx1MDQ0Mlx1MDQzNVx1MDQ0MFx1MDQzRFx1MDQzRVx1MDQ0MiAke19pc3N1ZS5wYXR0ZXJufWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgSW52YWxpZCAke05vdW5zW19pc3N1ZS5mb3JtYXRdID8/IGlzc3VlLmZvcm1hdH1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJub3RfbXVsdGlwbGVfb2ZcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDQxM1x1MDQ0MFx1MDQzNVx1MDQ0OFx1MDQzNVx1MDQzRCBcdTA0MzFcdTA0NDBcdTA0M0VcdTA0NTg6IFx1MDQzQ1x1MDQzRVx1MDQ0MFx1MDQzMCBcdTA0MzRcdTA0MzAgXHUwNDMxXHUwNDM4XHUwNDM0XHUwNDM1IFx1MDQzNFx1MDQzNVx1MDQzQlx1MDQzOFx1MDQzMiBcdTA0NDFcdTA0M0UgJHtpc3N1ZS5kaXZpc29yfWA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYCR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJcdTA0MURcdTA0MzVcdTA0M0ZcdTA0NDBcdTA0MzVcdTA0M0ZcdTA0M0VcdTA0MzdcdTA0M0RcdTA0MzBcdTA0MzVcdTA0M0RcdTA0MzggXHUwNDNBXHUwNDNCXHUwNDQzXHUwNDQ3XHUwNDM1XHUwNDMyXHUwNDM4XCIgOiBcIlx1MDQxRFx1MDQzNVx1MDQzRlx1MDQ0MFx1MDQzNVx1MDQzRlx1MDQzRVx1MDQzN1x1MDQzRFx1MDQzMFx1MDQzNVx1MDQzRCBcdTA0M0FcdTA0M0JcdTA0NDNcdTA0NDdcIn06ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLmtleXMsIFwiLCBcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2tleVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNDEzXHUwNDQwXHUwNDM1XHUwNDQ4XHUwNDM1XHUwNDNEIFx1MDQzQVx1MDQzQlx1MDQ0M1x1MDQ0NyBcdTA0MzJcdTA0M0UgJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3VuaW9uXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiXHUwNDEzXHUwNDQwXHUwNDM1XHUwNDQ4XHUwNDM1XHUwNDNEIFx1MDQzMlx1MDQzRFx1MDQzNVx1MDQ0MVwiO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZWxlbWVudFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNDEzXHUwNDQwXHUwNDM1XHUwNDQ4XHUwNDNEXHUwNDMwIFx1MDQzMlx1MDQ0MFx1MDQzNVx1MDQzNFx1MDQzRFx1MDQzRVx1MDQ0MVx1MDQ0MiBcdTA0MzJcdTA0M0UgJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MTNcdTA0NDBcdTA0MzVcdTA0NDhcdTA0MzVcdTA0M0QgXHUwNDMyXHUwNDNEXHUwNDM1XHUwNDQxYDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJha3NhcmFcIixcbiAgICAgICAgICAgIHZlcmI6IFwibWVtcHVueWFpXCJcbiAgICAgICAgfSxcbiAgICAgICAgZmlsZToge1xuICAgICAgICAgICAgdW5pdDogXCJiYWl0XCIsXG4gICAgICAgICAgICB2ZXJiOiBcIm1lbXB1bnlhaVwiXG4gICAgICAgIH0sXG4gICAgICAgIGFycmF5OiB7XG4gICAgICAgICAgICB1bml0OiBcImVsZW1lblwiLFxuICAgICAgICAgICAgdmVyYjogXCJtZW1wdW55YWlcIlxuICAgICAgICB9LFxuICAgICAgICBzZXQ6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiZWxlbWVuXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIm1lbXB1bnlhaVwiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4pIHtcbiAgICAgICAgcmV0dXJuIFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWRUeXBlID0gKGRhdGEpPT57XG4gICAgICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICAgICAgc3dpdGNoKHQpe1xuICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIm5vbWJvclwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJhcnJheVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJudWxsXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcImlucHV0XCIsXG4gICAgICAgIGVtYWlsOiBcImFsYW1hdCBlLW1lbFwiLFxuICAgICAgICB1cmw6IFwiVVJMXCIsXG4gICAgICAgIGVtb2ppOiBcImVtb2ppXCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcInRhcmlraCBtYXNhIElTT1wiLFxuICAgICAgICBkYXRlOiBcInRhcmlraCBJU09cIixcbiAgICAgICAgdGltZTogXCJtYXNhIElTT1wiLFxuICAgICAgICBkdXJhdGlvbjogXCJ0ZW1wb2ggSVNPXCIsXG4gICAgICAgIGlwdjQ6IFwiYWxhbWF0IElQdjRcIixcbiAgICAgICAgaXB2NjogXCJhbGFtYXQgSVB2NlwiLFxuICAgICAgICBjaWRydjQ6IFwianVsYXQgSVB2NFwiLFxuICAgICAgICBjaWRydjY6IFwianVsYXQgSVB2NlwiLFxuICAgICAgICBiYXNlNjQ6IFwic3RyaW5nIGRpa29ka2FuIGJhc2U2NFwiLFxuICAgICAgICBiYXNlNjR1cmw6IFwic3RyaW5nIGRpa29ka2FuIGJhc2U2NHVybFwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJzdHJpbmcgSlNPTlwiLFxuICAgICAgICBlMTY0OiBcIm5vbWJvciBFLjE2NFwiLFxuICAgICAgICBqd3Q6IFwiSldUXCIsXG4gICAgICAgIHRlbXBsYXRlX2xpdGVyYWw6IFwiaW5wdXRcIlxuICAgIH07XG4gICAgcmV0dXJuIChpc3N1ZSk9PntcbiAgICAgICAgc3dpdGNoKGlzc3VlLmNvZGUpe1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdHlwZVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgSW5wdXQgdGlkYWsgc2FoOiBkaWphbmdrYSAke2lzc3VlLmV4cGVjdGVkfSwgZGl0ZXJpbWEgJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBJbnB1dCB0aWRhayBzYWg6IGRpamFuZ2thICR7dXRpbC5zdHJpbmdpZnlQcmltaXRpdmUoaXNzdWUudmFsdWVzWzBdKX1gO1xuICAgICAgICAgICAgICAgIHJldHVybiBgUGlsaWhhbiB0aWRhayBzYWg6IGRpamFuZ2thIHNhbGFoIHNhdHUgZGFyaXBhZGEgJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIjw9XCIgOiBcIjxcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgVGVybGFsdSBiZXNhcjogZGlqYW5na2EgJHtpc3N1ZS5vcmlnaW4gPz8gXCJuaWxhaVwifSAke3NpemluZy52ZXJifSAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdCA/PyBcImVsZW1lblwifWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgVGVybGFsdSBiZXNhcjogZGlqYW5na2EgJHtpc3N1ZS5vcmlnaW4gPz8gXCJuaWxhaVwifSBhZGFsYWggJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIj49XCIgOiBcIj5cIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgVGVybGFsdSBrZWNpbDogZGlqYW5na2EgJHtpc3N1ZS5vcmlnaW59ICR7c2l6aW5nLnZlcmJ9ICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0fWA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBUZXJsYWx1IGtlY2lsOiBkaWphbmdrYSAke2lzc3VlLm9yaWdpbn0gYWRhbGFoICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZm9ybWF0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBfaXNzdWUgPSBpc3N1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwic3RhcnRzX3dpdGhcIikgcmV0dXJuIGBTdHJpbmcgdGlkYWsgc2FoOiBtZXN0aSBiZXJtdWxhIGRlbmdhbiBcIiR7X2lzc3VlLnByZWZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYFN0cmluZyB0aWRhayBzYWg6IG1lc3RpIGJlcmFraGlyIGRlbmdhbiBcIiR7X2lzc3VlLnN1ZmZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImluY2x1ZGVzXCIpIHJldHVybiBgU3RyaW5nIHRpZGFrIHNhaDogbWVzdGkgbWVuZ2FuZHVuZ2kgXCIke19pc3N1ZS5pbmNsdWRlc31cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInJlZ2V4XCIpIHJldHVybiBgU3RyaW5nIHRpZGFrIHNhaDogbWVzdGkgc2VwYWRhbiBkZW5nYW4gY29yYWsgJHtfaXNzdWUucGF0dGVybn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYCR7Tm91bnNbX2lzc3VlLmZvcm1hdF0gPz8gaXNzdWUuZm9ybWF0fSB0aWRhayBzYWhgO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJub3RfbXVsdGlwbGVfb2ZcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYE5vbWJvciB0aWRhayBzYWg6IHBlcmx1IGdhbmRhYW4gJHtpc3N1ZS5kaXZpc29yfWA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYEt1bmNpIHRpZGFrIGRpa2VuYWxpOiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIiwgXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYEt1bmNpIHRpZGFrIHNhaCBkYWxhbSAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJJbnB1dCB0aWRhayBzYWhcIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYE5pbGFpIHRpZGFrIHNhaCBkYWxhbSAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gYElucHV0IHRpZGFrIHNhaGA7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGxvY2FsZUVycm9yOiBlcnJvcigpXG4gICAgfTtcbn1cbiIsICJpbXBvcnQgKiBhcyB1dGlsIGZyb20gXCIuLi9jb3JlL3V0aWwuanNcIjtcbmNvbnN0IGVycm9yID0gKCk9PntcbiAgICBjb25zdCBTaXphYmxlID0ge1xuICAgICAgICBzdHJpbmc6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwidGVrZW5zXCJcbiAgICAgICAgfSxcbiAgICAgICAgZmlsZToge1xuICAgICAgICAgICAgdW5pdDogXCJieXRlc1wiXG4gICAgICAgIH0sXG4gICAgICAgIGFycmF5OiB7XG4gICAgICAgICAgICB1bml0OiBcImVsZW1lbnRlblwiXG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDogXCJlbGVtZW50ZW5cIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIk5hTlwiIDogXCJnZXRhbFwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJhcnJheVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJudWxsXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcImludm9lclwiLFxuICAgICAgICBlbWFpbDogXCJlbWFpbGFkcmVzXCIsXG4gICAgICAgIHVybDogXCJVUkxcIixcbiAgICAgICAgZW1vamk6IFwiZW1vamlcIixcbiAgICAgICAgdXVpZDogXCJVVUlEXCIsXG4gICAgICAgIHV1aWR2NDogXCJVVUlEdjRcIixcbiAgICAgICAgdXVpZHY2OiBcIlVVSUR2NlwiLFxuICAgICAgICBuYW5vaWQ6IFwibmFub2lkXCIsXG4gICAgICAgIGd1aWQ6IFwiR1VJRFwiLFxuICAgICAgICBjdWlkOiBcImN1aWRcIixcbiAgICAgICAgY3VpZDI6IFwiY3VpZDJcIixcbiAgICAgICAgdWxpZDogXCJVTElEXCIsXG4gICAgICAgIHhpZDogXCJYSURcIixcbiAgICAgICAga3N1aWQ6IFwiS1NVSURcIixcbiAgICAgICAgZGF0ZXRpbWU6IFwiSVNPIGRhdHVtIGVuIHRpamRcIixcbiAgICAgICAgZGF0ZTogXCJJU08gZGF0dW1cIixcbiAgICAgICAgdGltZTogXCJJU08gdGlqZFwiLFxuICAgICAgICBkdXJhdGlvbjogXCJJU08gZHV1clwiLFxuICAgICAgICBpcHY0OiBcIklQdjQtYWRyZXNcIixcbiAgICAgICAgaXB2NjogXCJJUHY2LWFkcmVzXCIsXG4gICAgICAgIGNpZHJ2NDogXCJJUHY0LWJlcmVpa1wiLFxuICAgICAgICBjaWRydjY6IFwiSVB2Ni1iZXJlaWtcIixcbiAgICAgICAgYmFzZTY0OiBcImJhc2U2NC1nZWNvZGVlcmRlIHRla3N0XCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJiYXNlNjQgVVJMLWdlY29kZWVyZGUgdGVrc3RcIixcbiAgICAgICAganNvbl9zdHJpbmc6IFwiSlNPTiBzdHJpbmdcIixcbiAgICAgICAgZTE2NDogXCJFLjE2NC1udW1tZXJcIixcbiAgICAgICAgand0OiBcIkpXVFwiLFxuICAgICAgICB0ZW1wbGF0ZV9saXRlcmFsOiBcImludm9lclwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBPbmdlbGRpZ2UgaW52b2VyOiB2ZXJ3YWNodCAke2lzc3VlLmV4cGVjdGVkfSwgb250dmluZyAke3BhcnNlZFR5cGUoaXNzdWUuaW5wdXQpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF92YWx1ZVwiOlxuICAgICAgICAgICAgICAgIGlmIChpc3N1ZS52YWx1ZXMubGVuZ3RoID09PSAxKSByZXR1cm4gYE9uZ2VsZGlnZSBpbnZvZXI6IHZlcndhY2h0ICR7dXRpbC5zdHJpbmdpZnlQcmltaXRpdmUoaXNzdWUudmFsdWVzWzBdKX1gO1xuICAgICAgICAgICAgICAgIHJldHVybiBgT25nZWxkaWdlIG9wdGllOiB2ZXJ3YWNodCBcdTAwRTlcdTAwRTluIHZhbiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS52YWx1ZXMsIFwifFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPD1cIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykgcmV0dXJuIGBUZSBsYW5nOiB2ZXJ3YWNodCBkYXQgJHtpc3N1ZS5vcmlnaW4gPz8gXCJ3YWFyZGVcIn0gJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXQgPz8gXCJlbGVtZW50ZW5cIn0gYmV2YXRgO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFRlIGxhbmc6IHZlcndhY2h0IGRhdCAke2lzc3VlLm9yaWdpbiA/PyBcIndhYXJkZVwifSAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX0gaXNgO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJ0b29fc21hbGxcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPj1cIiA6IFwiPlwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBUZSBrb3J0OiB2ZXJ3YWNodCBkYXQgJHtpc3N1ZS5vcmlnaW59ICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0fSBiZXZhdGA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBUZSBrb3J0OiB2ZXJ3YWNodCBkYXQgJHtpc3N1ZS5vcmlnaW59ICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSBpc2A7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZm9ybWF0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBfaXNzdWUgPSBpc3N1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwic3RhcnRzX3dpdGhcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBPbmdlbGRpZ2UgdGVrc3Q6IG1vZXQgbWV0IFwiJHtfaXNzdWUucHJlZml4fVwiIGJlZ2lubmVuYDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJlbmRzX3dpdGhcIikgcmV0dXJuIGBPbmdlbGRpZ2UgdGVrc3Q6IG1vZXQgb3AgXCIke19pc3N1ZS5zdWZmaXh9XCIgZWluZGlnZW5gO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJpbmNsdWRlc1wiKSByZXR1cm4gYE9uZ2VsZGlnZSB0ZWtzdDogbW9ldCBcIiR7X2lzc3VlLmluY2x1ZGVzfVwiIGJldmF0dGVuYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBPbmdlbGRpZ2UgdGVrc3Q6IG1vZXQgb3ZlcmVlbmtvbWVuIG1ldCBwYXRyb29uICR7X2lzc3VlLnBhdHRlcm59YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBPbmdlbGRpZzogJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBPbmdlbGRpZyBnZXRhbDogbW9ldCBlZW4gdmVlbHZvdWQgdmFuICR7aXNzdWUuZGl2aXNvcn0gemlqbmA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYE9uYmVrZW5kZSBrZXkke2lzc3VlLmtleXMubGVuZ3RoID4gMSA/IFwic1wiIDogXCJcIn06ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLmtleXMsIFwiLCBcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2tleVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgT25nZWxkaWdlIGtleSBpbiAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJPbmdlbGRpZ2UgaW52b2VyXCI7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9lbGVtZW50XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBPbmdlbGRpZ2Ugd2FhcmRlIGluICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBgT25nZWxkaWdlIGludm9lcmA7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGxvY2FsZUVycm9yOiBlcnJvcigpXG4gICAgfTtcbn1cbiIsICJpbXBvcnQgKiBhcyB1dGlsIGZyb20gXCIuLi9jb3JlL3V0aWwuanNcIjtcbmNvbnN0IGVycm9yID0gKCk9PntcbiAgICBjb25zdCBTaXphYmxlID0ge1xuICAgICAgICBzdHJpbmc6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwidGVnblwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTAwRTUgaGFcIlxuICAgICAgICB9LFxuICAgICAgICBmaWxlOiB7XG4gICAgICAgICAgICB1bml0OiBcImJ5dGVzXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MDBFNSBoYVwiXG4gICAgICAgIH0sXG4gICAgICAgIGFycmF5OiB7XG4gICAgICAgICAgICB1bml0OiBcImVsZW1lbnRlclwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTAwRTUgaW5uZWhvbGRlXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcImVsZW1lbnRlclwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTAwRTUgaW5uZWhvbGRlXCJcbiAgICAgICAgfVxuICAgIH07XG4gICAgZnVuY3Rpb24gZ2V0U2l6aW5nKG9yaWdpbikge1xuICAgICAgICByZXR1cm4gU2l6YWJsZVtvcmlnaW5dID8/IG51bGw7XG4gICAgfVxuICAgIGNvbnN0IHBhcnNlZFR5cGUgPSAoZGF0YSk9PntcbiAgICAgICAgY29uc3QgdCA9IHR5cGVvZiBkYXRhO1xuICAgICAgICBzd2l0Y2godCl7XG4gICAgICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gTnVtYmVyLmlzTmFOKGRhdGEpID8gXCJOYU5cIiA6IFwidGFsbFwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJsaXN0ZVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJudWxsXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcImlucHV0XCIsXG4gICAgICAgIGVtYWlsOiBcImUtcG9zdGFkcmVzc2VcIixcbiAgICAgICAgdXJsOiBcIlVSTFwiLFxuICAgICAgICBlbW9qaTogXCJlbW9qaVwiLFxuICAgICAgICB1dWlkOiBcIlVVSURcIixcbiAgICAgICAgdXVpZHY0OiBcIlVVSUR2NFwiLFxuICAgICAgICB1dWlkdjY6IFwiVVVJRHY2XCIsXG4gICAgICAgIG5hbm9pZDogXCJuYW5vaWRcIixcbiAgICAgICAgZ3VpZDogXCJHVUlEXCIsXG4gICAgICAgIGN1aWQ6IFwiY3VpZFwiLFxuICAgICAgICBjdWlkMjogXCJjdWlkMlwiLFxuICAgICAgICB1bGlkOiBcIlVMSURcIixcbiAgICAgICAgeGlkOiBcIlhJRFwiLFxuICAgICAgICBrc3VpZDogXCJLU1VJRFwiLFxuICAgICAgICBkYXRldGltZTogXCJJU08gZGF0by0gb2cga2xva2tlc2xldHRcIixcbiAgICAgICAgZGF0ZTogXCJJU08tZGF0b1wiLFxuICAgICAgICB0aW1lOiBcIklTTy1rbG9ra2VzbGV0dFwiLFxuICAgICAgICBkdXJhdGlvbjogXCJJU08tdmFyaWdoZXRcIixcbiAgICAgICAgaXB2NDogXCJJUHY0LW9tclx1MDBFNWRlXCIsXG4gICAgICAgIGlwdjY6IFwiSVB2Ni1vbXJcdTAwRTVkZVwiLFxuICAgICAgICBjaWRydjQ6IFwiSVB2NC1zcGVrdGVyXCIsXG4gICAgICAgIGNpZHJ2NjogXCJJUHY2LXNwZWt0ZXJcIixcbiAgICAgICAgYmFzZTY0OiBcImJhc2U2NC1lbmtvZGV0IHN0cmVuZ1wiLFxuICAgICAgICBiYXNlNjR1cmw6IFwiYmFzZTY0dXJsLWVua29kZXQgc3RyZW5nXCIsXG4gICAgICAgIGpzb25fc3RyaW5nOiBcIkpTT04tc3RyZW5nXCIsXG4gICAgICAgIGUxNjQ6IFwiRS4xNjQtbnVtbWVyXCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJpbnB1dFwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBVZ3lsZGlnIGlucHV0OiBmb3J2ZW50ZXQgJHtpc3N1ZS5leHBlY3RlZH0sIGZpa2sgJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBVZ3lsZGlnIHZlcmRpOiBmb3J2ZW50ZXQgJHt1dGlsLnN0cmluZ2lmeVByaW1pdGl2ZShpc3N1ZS52YWx1ZXNbMF0pfWA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBVZ3lsZGlnIHZhbGc6IGZvcnZlbnRldCBlbiBhdiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS52YWx1ZXMsIFwifFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPD1cIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykgcmV0dXJuIGBGb3Igc3Rvcih0KTogZm9ydmVudGV0ICR7aXNzdWUub3JpZ2luID8/IFwidmFsdWVcIn0gdGlsIFx1MDBFNSBoYSAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdCA/PyBcImVsZW1lbnRlclwifWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgRm9yIHN0b3IodCk6IGZvcnZlbnRldCAke2lzc3VlLm9yaWdpbiA/PyBcInZhbHVlXCJ9IHRpbCBcdTAwRTUgaGEgJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIj49XCIgOiBcIj5cIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgRm9yIGxpdGUobik6IGZvcnZlbnRldCAke2lzc3VlLm9yaWdpbn0gdGlsIFx1MDBFNSBoYSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdH1gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgRm9yIGxpdGUobik6IGZvcnZlbnRldCAke2lzc3VlLm9yaWdpbn0gdGlsIFx1MDBFNSBoYSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2Zvcm1hdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgX2lzc3VlID0gaXNzdWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInN0YXJ0c193aXRoXCIpIHJldHVybiBgVWd5bGRpZyBzdHJlbmc6IG1cdTAwRTUgc3RhcnRlIG1lZCBcIiR7X2lzc3VlLnByZWZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYFVneWxkaWcgc3RyZW5nOiBtXHUwMEU1IGVuZGUgbWVkIFwiJHtfaXNzdWUuc3VmZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBVZ3lsZGlnIHN0cmVuZzogbVx1MDBFNSBpbm5laG9sZGUgXCIke19pc3N1ZS5pbmNsdWRlc31cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInJlZ2V4XCIpIHJldHVybiBgVWd5bGRpZyBzdHJlbmc6IG1cdTAwRTUgbWF0Y2hlIG1cdTAwRjhuc3RlcmV0ICR7X2lzc3VlLnBhdHRlcm59YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBVZ3lsZGlnICR7Tm91bnNbX2lzc3VlLmZvcm1hdF0gPz8gaXNzdWUuZm9ybWF0fWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm5vdF9tdWx0aXBsZV9vZlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgVWd5bGRpZyB0YWxsOiBtXHUwMEU1IHZcdTAwRTZyZSBldCBtdWx0aXBsdW0gYXYgJHtpc3N1ZS5kaXZpc29yfWA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYCR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJVa2plbnRlIG5cdTAwRjhrbGVyXCIgOiBcIlVramVudCBuXHUwMEY4a2tlbFwifTogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgXCIsIFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfa2V5XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBVZ3lsZGlnIG5cdTAwRjhra2VsIGkgJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3VuaW9uXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiVWd5bGRpZyBpbnB1dFwiO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZWxlbWVudFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgVWd5bGRpZyB2ZXJkaSBpICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBgVWd5bGRpZyBpbnB1dGA7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGxvY2FsZUVycm9yOiBlcnJvcigpXG4gICAgfTtcbn1cbiIsICJpbXBvcnQgKiBhcyB1dGlsIGZyb20gXCIuLi9jb3JlL3V0aWwuanNcIjtcbmNvbnN0IGVycm9yID0gKCk9PntcbiAgICBjb25zdCBTaXphYmxlID0ge1xuICAgICAgICBzdHJpbmc6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiaGFyZlwiLFxuICAgICAgICAgICAgdmVyYjogXCJvbG1hbFx1MDEzMWRcdTAxMzFyXCJcbiAgICAgICAgfSxcbiAgICAgICAgZmlsZToge1xuICAgICAgICAgICAgdW5pdDogXCJiYXl0XCIsXG4gICAgICAgICAgICB2ZXJiOiBcIm9sbWFsXHUwMTMxZFx1MDEzMXJcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJ1bnN1clwiLFxuICAgICAgICAgICAgdmVyYjogXCJvbG1hbFx1MDEzMWRcdTAxMzFyXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcInVuc3VyXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIm9sbWFsXHUwMTMxZFx1MDEzMXJcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIk5hTlwiIDogXCJudW1hcmFcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwic2FmXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGEgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcImdheWJcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKGRhdGEpICE9PSBPYmplY3QucHJvdG90eXBlICYmIGRhdGEuY29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHQ7XG4gICAgfTtcbiAgICBjb25zdCBOb3VucyA9IHtcbiAgICAgICAgcmVnZXg6IFwiZ2lyZW5cIixcbiAgICAgICAgZW1haWw6IFwiZXBvc3RhZ1x1MDBFMmhcIixcbiAgICAgICAgdXJsOiBcIlVSTFwiLFxuICAgICAgICBlbW9qaTogXCJlbW9qaVwiLFxuICAgICAgICB1dWlkOiBcIlVVSURcIixcbiAgICAgICAgdXVpZHY0OiBcIlVVSUR2NFwiLFxuICAgICAgICB1dWlkdjY6IFwiVVVJRHY2XCIsXG4gICAgICAgIG5hbm9pZDogXCJuYW5vaWRcIixcbiAgICAgICAgZ3VpZDogXCJHVUlEXCIsXG4gICAgICAgIGN1aWQ6IFwiY3VpZFwiLFxuICAgICAgICBjdWlkMjogXCJjdWlkMlwiLFxuICAgICAgICB1bGlkOiBcIlVMSURcIixcbiAgICAgICAgeGlkOiBcIlhJRFwiLFxuICAgICAgICBrc3VpZDogXCJLU1VJRFwiLFxuICAgICAgICBkYXRldGltZTogXCJJU08gaGVuZ1x1MDBFMm1cdTAxMzFcIixcbiAgICAgICAgZGF0ZTogXCJJU08gdGFyaWhpXCIsXG4gICAgICAgIHRpbWU6IFwiSVNPIHphbWFuXHUwMTMxXCIsXG4gICAgICAgIGR1cmF0aW9uOiBcIklTTyBtXHUwMEZDZGRldGlcIixcbiAgICAgICAgaXB2NDogXCJJUHY0IG5pXHUwMTVGXHUwMEUyblx1MDEzMVwiLFxuICAgICAgICBpcHY2OiBcIklQdjYgbmlcdTAxNUZcdTAwRTJuXHUwMTMxXCIsXG4gICAgICAgIGNpZHJ2NDogXCJJUHY0IG1lbnppbGlcIixcbiAgICAgICAgY2lkcnY2OiBcIklQdjYgbWVuemlsaVwiLFxuICAgICAgICBiYXNlNjQ6IFwiYmFzZTY0LVx1MDE1RmlmcmVsaSBtZXRpblwiLFxuICAgICAgICBiYXNlNjR1cmw6IFwiYmFzZTY0dXJsLVx1MDE1RmlmcmVsaSBtZXRpblwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJKU09OIG1ldGluXCIsXG4gICAgICAgIGUxNjQ6IFwiRS4xNjQgc2F5XHUwMTMxc1x1MDEzMVwiLFxuICAgICAgICBqd3Q6IFwiSldUXCIsXG4gICAgICAgIHRlbXBsYXRlX2xpdGVyYWw6IFwiZ2lyZW5cIlxuICAgIH07XG4gICAgcmV0dXJuIChpc3N1ZSk9PntcbiAgICAgICAgc3dpdGNoKGlzc3VlLmNvZGUpe1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdHlwZVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgRlx1MDBFMnNpdCBnaXJlbjogdW11bGFuICR7aXNzdWUuZXhwZWN0ZWR9LCBhbFx1MDEzMW5hbiAke3BhcnNlZFR5cGUoaXNzdWUuaW5wdXQpfWA7XG4gICAgICAgICAgICAvLyByZXR1cm4gYEZcdTAwRTJzaXQgZ2lyZW46IHVtdWxhbiAke2lzc3VlLmV4cGVjdGVkfSwgYWxcdTAxMzFuYW4gJHt1dGlsLmdldFBhcnNlZFR5cGUoaXNzdWUuaW5wdXQpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF92YWx1ZVwiOlxuICAgICAgICAgICAgICAgIGlmIChpc3N1ZS52YWx1ZXMubGVuZ3RoID09PSAxKSByZXR1cm4gYEZcdTAwRTJzaXQgZ2lyZW46IHVtdWxhbiAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYEZcdTAwRTJzaXQgdGVyY2loOiBtXHUwMEZCdGViZXJsZXIgJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIjw9XCIgOiBcIjxcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgRmF6bGEgYlx1MDBGQ3lcdTAwRkNrOiAke2lzc3VlLm9yaWdpbiA/PyBcInZhbHVlXCJ9LCAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdCA/PyBcImVsZW1lbnRzXCJ9IHNhaGlwIG9sbWFsXHUwMTMxeWRcdTAxMzEuYDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBGYXpsYSBiXHUwMEZDeVx1MDBGQ2s6ICR7aXNzdWUub3JpZ2luID8/IFwidmFsdWVcIn0sICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSBvbG1hbFx1MDEzMXlkXHUwMTMxLmA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInRvb19zbWFsbFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI+PVwiIDogXCI+XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYEZhemxhIGtcdTAwRkNcdTAwRTdcdTAwRkNrOiAke2lzc3VlLm9yaWdpbn0sICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0fSBzYWhpcCBvbG1hbFx1MDEzMXlkXHUwMTMxLmA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBGYXpsYSBrXHUwMEZDXHUwMEU3XHUwMEZDazogJHtpc3N1ZS5vcmlnaW59LCAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gb2xtYWxcdTAxMzF5ZFx1MDEzMS5gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2Zvcm1hdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgX2lzc3VlID0gaXNzdWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInN0YXJ0c193aXRoXCIpIHJldHVybiBgRlx1MDBFMnNpdCBtZXRpbjogXCIke19pc3N1ZS5wcmVmaXh9XCIgaWxlIGJhXHUwMTVGbGFtYWxcdTAxMzEuYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiZW5kc193aXRoXCIpIHJldHVybiBgRlx1MDBFMnNpdCBtZXRpbjogXCIke19pc3N1ZS5zdWZmaXh9XCIgaWxlIGJpdG1lbGkuYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBGXHUwMEUyc2l0IG1ldGluOiBcIiR7X2lzc3VlLmluY2x1ZGVzfVwiIGlodGl2XHUwMEUyIGV0bWVsaS5gO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYEZcdTAwRTJzaXQgbWV0aW46ICR7X2lzc3VlLnBhdHRlcm59IG5ha1x1MDE1Rlx1MDEzMW5hIHV5bWFsXHUwMTMxLmA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgRlx1MDBFMnNpdCAke05vdW5zW19pc3N1ZS5mb3JtYXRdID8/IGlzc3VlLmZvcm1hdH1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJub3RfbXVsdGlwbGVfb2ZcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYEZcdTAwRTJzaXQgc2F5XHUwMTMxOiAke2lzc3VlLmRpdmlzb3J9IGthdFx1MDEzMSBvbG1hbFx1MDEzMXlkXHUwMTMxLmA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFRhblx1MDEzMW5tYXlhbiBhbmFodGFyICR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJzXCIgOiBcIlwifTogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgXCIsIFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfa2V5XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGAke2lzc3VlLm9yaWdpbn0gaVx1MDBFN2luIHRhblx1MDEzMW5tYXlhbiBhbmFodGFyIHZhci5gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJHaXJlbiB0YW5cdTAxMzFuYW1hZFx1MDEzMS5cIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYCR7aXNzdWUub3JpZ2lufSBpXHUwMEU3aW4gdGFuXHUwMTMxbm1heWFuIGtcdTAxMzF5bWV0IHZhci5gO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gYEtcdTAxMzF5bWV0IHRhblx1MDEzMW5hbWFkXHUwMTMxLmA7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGxvY2FsZUVycm9yOiBlcnJvcigpXG4gICAgfTtcbn1cbiIsICJpbXBvcnQgKiBhcyB1dGlsIGZyb20gXCIuLi9jb3JlL3V0aWwuanNcIjtcbmNvbnN0IGVycm9yID0gKCk9PntcbiAgICBjb25zdCBTaXphYmxlID0ge1xuICAgICAgICBzdHJpbmc6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHUwNjJBXHUwNjQ4XHUwNkE5XHUwNjRBXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MDY0OFx1MDY0NFx1MDYzMVx1MDY0QVwiXG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHUwNjI4XHUwNjI3XHUwNkNDXHUwNjdDXHUwNjMzXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MDY0OFx1MDY0NFx1MDYzMVx1MDY0QVwiXG4gICAgICAgIH0sXG4gICAgICAgIGFycmF5OiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MDYyQVx1MDY0OFx1MDZBOVx1MDY0QVwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTA2NDhcdTA2NDRcdTA2MzFcdTA2NEFcIlxuICAgICAgICB9LFxuICAgICAgICBzZXQ6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHUwNjJBXHUwNjQ4XHUwNkE5XHUwNjRBXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MDY0OFx1MDY0NFx1MDYzMVx1MDY0QVwiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4pIHtcbiAgICAgICAgcmV0dXJuIFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWRUeXBlID0gKGRhdGEpPT57XG4gICAgICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICAgICAgc3dpdGNoKHQpe1xuICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIlx1MDYzOVx1MDYyRlx1MDYyRlwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTA2MjdcdTA2MzFcdTA2RDBcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YoZGF0YSkgIT09IE9iamVjdC5wcm90b3R5cGUgJiYgZGF0YS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdDtcbiAgICB9O1xuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJcdTA2NDhcdTA2MzFcdTA2NDhcdTA2MkZcdTA2NEFcIixcbiAgICAgICAgZW1haWw6IFwiXHUwNjI4XHUwNjMxXHUwNkNDXHUwNjlBXHUwNjQ2XHUwNjI3XHUwNjQ0XHUwNkNDXHUwNkE5XCIsXG4gICAgICAgIHVybDogXCJcdTA2Q0NcdTA2NDggXHUwNjIyXHUwNjMxIFx1MDYyN1x1MDY0NFwiLFxuICAgICAgICBlbW9qaTogXCJcdTA2MjdcdTA2Q0NcdTA2NDVcdTA2NDhcdTA2MkNcdTA2NEFcIixcbiAgICAgICAgdXVpZDogXCJVVUlEXCIsXG4gICAgICAgIHV1aWR2NDogXCJVVUlEdjRcIixcbiAgICAgICAgdXVpZHY2OiBcIlVVSUR2NlwiLFxuICAgICAgICBuYW5vaWQ6IFwibmFub2lkXCIsXG4gICAgICAgIGd1aWQ6IFwiR1VJRFwiLFxuICAgICAgICBjdWlkOiBcImN1aWRcIixcbiAgICAgICAgY3VpZDI6IFwiY3VpZDJcIixcbiAgICAgICAgdWxpZDogXCJVTElEXCIsXG4gICAgICAgIHhpZDogXCJYSURcIixcbiAgICAgICAga3N1aWQ6IFwiS1NVSURcIixcbiAgICAgICAgZGF0ZXRpbWU6IFwiXHUwNjQ2XHUwNkNDXHUwNjdDXHUwNjQ3IFx1MDYyN1x1MDY0OCBcdTA2NDhcdTA2MkVcdTA2MkFcIixcbiAgICAgICAgZGF0ZTogXCJcdTA2NDZcdTA2RDBcdTA2N0NcdTA2NDdcIixcbiAgICAgICAgdGltZTogXCJcdTA2NDhcdTA2MkVcdTA2MkFcIixcbiAgICAgICAgZHVyYXRpb246IFwiXHUwNjQ1XHUwNjQ4XHUwNjJGXHUwNjQ3XCIsXG4gICAgICAgIGlwdjQ6IFwiXHUwNjJGIElQdjQgXHUwNjdFXHUwNjJBXHUwNjQ3XCIsXG4gICAgICAgIGlwdjY6IFwiXHUwNjJGIElQdjYgXHUwNjdFXHUwNjJBXHUwNjQ3XCIsXG4gICAgICAgIGNpZHJ2NDogXCJcdTA2MkYgSVB2NCBcdTA2MzNcdTA2MjdcdTA2MkRcdTA2NDdcIixcbiAgICAgICAgY2lkcnY2OiBcIlx1MDYyRiBJUHY2IFx1MDYzM1x1MDYyN1x1MDYyRFx1MDY0N1wiLFxuICAgICAgICBiYXNlNjQ6IFwiYmFzZTY0LWVuY29kZWQgXHUwNjQ1XHUwNjJBXHUwNjQ2XCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJiYXNlNjR1cmwtZW5jb2RlZCBcdTA2NDVcdTA2MkFcdTA2NDZcIixcbiAgICAgICAganNvbl9zdHJpbmc6IFwiSlNPTiBcdTA2NDVcdTA2MkFcdTA2NDZcIixcbiAgICAgICAgZTE2NDogXCJcdTA2MkYgRS4xNjQgXHUwNjM0XHUwNjQ1XHUwNkQwXHUwNjMxXHUwNjQ3XCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJcdTA2NDhcdTA2MzFcdTA2NDhcdTA2MkZcdTA2NEFcIlxuICAgIH07XG4gICAgcmV0dXJuIChpc3N1ZSk9PntcbiAgICAgICAgc3dpdGNoKGlzc3VlLmNvZGUpe1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdHlwZVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjQ2XHUwNjI3XHUwNjMzXHUwNjQ1IFx1MDY0OFx1MDYzMVx1MDY0OFx1MDYyRlx1MDY0QTogXHUwNjI4XHUwNjI3XHUwNkNDXHUwNjJGICR7aXNzdWUuZXhwZWN0ZWR9IFx1MDY0OFx1MDYyN1x1MDZDQywgXHUwNjQ1XHUwNkFCXHUwNjMxICR7cGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9IFx1MDYyQVx1MDYzMVx1MDY0NFx1MDYyN1x1MDYzM1x1MDY0NyBcdTA2MzRcdTA2NDhgO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDY0Nlx1MDYyN1x1MDYzM1x1MDY0NSBcdTA2NDhcdTA2MzFcdTA2NDhcdTA2MkZcdTA2NEE6IFx1MDYyOFx1MDYyN1x1MDZDQ1x1MDYyRiAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9IFx1MDY0OFx1MDYyN1x1MDZDQ2A7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjQ2XHUwNjI3XHUwNjMzXHUwNjQ1IFx1MDYyN1x1MDY0Nlx1MDYyQVx1MDYyRVx1MDYyN1x1MDYyODogXHUwNjI4XHUwNjI3XHUwNkNDXHUwNjJGIFx1MDZDQ1x1MDY0OCBcdTA2NDRcdTA2NDcgJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9IFx1MDY4NVx1MDYyRVx1MDY0NyBcdTA2NDhcdTA2MjdcdTA2Q0NgO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPD1cIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2ODlcdTA2Q0NcdTA2MzEgXHUwNjQ0XHUwNjQ4XHUwNkNDOiAke2lzc3VlLm9yaWdpbiA/PyBcIlx1MDYyN1x1MDYzMVx1MDYzMlx1MDY5QVx1MDYyQVwifSBcdTA2MjhcdTA2MjdcdTA2Q0NcdTA2MkYgJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXQgPz8gXCJcdTA2MzlcdTA2NDZcdTA2MzVcdTA2MzFcdTA2NDhcdTA2NDZcdTA2NDdcIn0gXHUwNjQ4XHUwNjQ0XHUwNjMxXHUwNjRBYDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDY4OVx1MDZDQ1x1MDYzMSBcdTA2NDRcdTA2NDhcdTA2Q0M6ICR7aXNzdWUub3JpZ2luID8/IFwiXHUwNjI3XHUwNjMxXHUwNjMyXHUwNjlBXHUwNjJBXCJ9IFx1MDYyOFx1MDYyN1x1MDZDQ1x1MDYyRiAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX0gXHUwNjQ4XHUwNjRBYDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIj49XCIgOiBcIj5cIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjg5XHUwNkNDXHUwNjMxIFx1MDZBOVx1MDY0OFx1MDY4Nlx1MDY0Nlx1MDZDQzogJHtpc3N1ZS5vcmlnaW59IFx1MDYyOFx1MDYyN1x1MDZDQ1x1MDYyRiAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdH0gXHUwNjQ4XHUwNjQ0XHUwNjMxXHUwNjRBYDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDY4OVx1MDZDQ1x1MDYzMSBcdTA2QTlcdTA2NDhcdTA2ODZcdTA2NDZcdTA2Q0M6ICR7aXNzdWUub3JpZ2lufSBcdTA2MjhcdTA2MjdcdTA2Q0NcdTA2MkYgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9IFx1MDY0OFx1MDY0QWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZm9ybWF0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBfaXNzdWUgPSBpc3N1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwic3RhcnRzX3dpdGhcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2NDZcdTA2MjdcdTA2MzNcdTA2NDUgXHUwNjQ1XHUwNjJBXHUwNjQ2OiBcdTA2MjhcdTA2MjdcdTA2Q0NcdTA2MkYgXHUwNjJGIFwiJHtfaXNzdWUucHJlZml4fVwiIFx1MDYzM1x1MDYzMVx1MDY0NyBcdTA2N0VcdTA2Q0NcdTA2NDQgXHUwNjM0XHUwNjRBYDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJlbmRzX3dpdGhcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2NDZcdTA2MjdcdTA2MzNcdTA2NDUgXHUwNjQ1XHUwNjJBXHUwNjQ2OiBcdTA2MjhcdTA2MjdcdTA2Q0NcdTA2MkYgXHUwNjJGIFwiJHtfaXNzdWUuc3VmZml4fVwiIFx1MDYzM1x1MDYzMVx1MDY0NyBcdTA2N0VcdTA2MjdcdTA2Q0MgXHUwNjJBXHUwNjQ3IFx1MDY0OFx1MDYzMVx1MDYzM1x1MDY0QVx1MDY5Nlx1MDY0QWA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2NDZcdTA2MjdcdTA2MzNcdTA2NDUgXHUwNjQ1XHUwNjJBXHUwNjQ2OiBcdTA2MjhcdTA2MjdcdTA2Q0NcdTA2MkYgXCIke19pc3N1ZS5pbmNsdWRlc31cIiBcdTA2NDhcdTA2NDRcdTA2MzFcdTA2NEFgO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInJlZ2V4XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjQ2XHUwNjI3XHUwNjMzXHUwNjQ1IFx1MDY0NVx1MDYyQVx1MDY0NjogXHUwNjI4XHUwNjI3XHUwNkNDXHUwNjJGIFx1MDYyRiAke19pc3N1ZS5wYXR0ZXJufSBcdTA2MzNcdTA2MzFcdTA2NDcgXHUwNjQ1XHUwNjM3XHUwNjI3XHUwNjI4XHUwNjQyXHUwNjJBIFx1MDY0OFx1MDY0NFx1MDYzMVx1MDY0QWA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGAke05vdW5zW19pc3N1ZS5mb3JtYXRdID8/IGlzc3VlLmZvcm1hdH0gXHUwNjQ2XHUwNjI3XHUwNjMzXHUwNjQ1IFx1MDYyRlx1MDZDQ2A7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm5vdF9tdWx0aXBsZV9vZlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjQ2XHUwNjI3XHUwNjMzXHUwNjQ1IFx1MDYzOVx1MDYyRlx1MDYyRjogXHUwNjI4XHUwNjI3XHUwNkNDXHUwNjJGIFx1MDYyRiAke2lzc3VlLmRpdmlzb3J9IFx1MDY0NVx1MDYzNlx1MDYzMVx1MDYyOCBcdTA2NDhcdTA2NEFgO1xuICAgICAgICAgICAgY2FzZSBcInVucmVjb2duaXplZF9rZXlzXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2NDZcdTA2MjdcdTA2MzNcdTA2NDUgJHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcIlx1MDZBOVx1MDY0NFx1MDZDQ1x1MDY4OVx1MDY0OFx1MDY0Nlx1MDY0N1wiIDogXCJcdTA2QTlcdTA2NDRcdTA2Q0NcdTA2ODlcIn06ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLmtleXMsIFwiLCBcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2tleVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjQ2XHUwNjI3XHUwNjMzXHUwNjQ1IFx1MDZBOVx1MDY0NFx1MDZDQ1x1MDY4OSBcdTA2N0VcdTA2NDcgJHtpc3N1ZS5vcmlnaW59IFx1MDZBOVx1MDZEMGA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF91bmlvblwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjQ2XHUwNjI3XHUwNjMzXHUwNjQ1XHUwNjQ3IFx1MDY0OFx1MDYzMVx1MDY0OFx1MDYyRlx1MDY0QWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9lbGVtZW50XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2NDZcdTA2MjdcdTA2MzNcdTA2NDUgXHUwNjM5XHUwNjQ2XHUwNjM1XHUwNjMxIFx1MDY3RVx1MDY0NyAke2lzc3VlLm9yaWdpbn0gXHUwNkE5XHUwNkQwYDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2NDZcdTA2MjdcdTA2MzNcdTA2NDVcdTA2NDcgXHUwNjQ4XHUwNjMxXHUwNjQ4XHUwNjJGXHUwNjRBYDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJ6bmFrXHUwMEYzd1wiLFxuICAgICAgICAgICAgdmVyYjogXCJtaWVcdTAxMDdcIlxuICAgICAgICB9LFxuICAgICAgICBmaWxlOiB7XG4gICAgICAgICAgICB1bml0OiBcImJhanRcdTAwRjN3XCIsXG4gICAgICAgICAgICB2ZXJiOiBcIm1pZVx1MDEwN1wiXG4gICAgICAgIH0sXG4gICAgICAgIGFycmF5OiB7XG4gICAgICAgICAgICB1bml0OiBcImVsZW1lbnRcdTAwRjN3XCIsXG4gICAgICAgICAgICB2ZXJiOiBcIm1pZVx1MDEwN1wiXG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDogXCJlbGVtZW50XHUwMEYzd1wiLFxuICAgICAgICAgICAgdmVyYjogXCJtaWVcdTAxMDdcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIk5hTlwiIDogXCJsaWN6YmFcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwidGFibGljYVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJudWxsXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcInd5cmFcdTAxN0NlbmllXCIsXG4gICAgICAgIGVtYWlsOiBcImFkcmVzIGVtYWlsXCIsXG4gICAgICAgIHVybDogXCJVUkxcIixcbiAgICAgICAgZW1vamk6IFwiZW1vamlcIixcbiAgICAgICAgdXVpZDogXCJVVUlEXCIsXG4gICAgICAgIHV1aWR2NDogXCJVVUlEdjRcIixcbiAgICAgICAgdXVpZHY2OiBcIlVVSUR2NlwiLFxuICAgICAgICBuYW5vaWQ6IFwibmFub2lkXCIsXG4gICAgICAgIGd1aWQ6IFwiR1VJRFwiLFxuICAgICAgICBjdWlkOiBcImN1aWRcIixcbiAgICAgICAgY3VpZDI6IFwiY3VpZDJcIixcbiAgICAgICAgdWxpZDogXCJVTElEXCIsXG4gICAgICAgIHhpZDogXCJYSURcIixcbiAgICAgICAga3N1aWQ6IFwiS1NVSURcIixcbiAgICAgICAgZGF0ZXRpbWU6IFwiZGF0YSBpIGdvZHppbmEgdyBmb3JtYWNpZSBJU09cIixcbiAgICAgICAgZGF0ZTogXCJkYXRhIHcgZm9ybWFjaWUgSVNPXCIsXG4gICAgICAgIHRpbWU6IFwiZ29kemluYSB3IGZvcm1hY2llIElTT1wiLFxuICAgICAgICBkdXJhdGlvbjogXCJjemFzIHRyd2FuaWEgSVNPXCIsXG4gICAgICAgIGlwdjQ6IFwiYWRyZXMgSVB2NFwiLFxuICAgICAgICBpcHY2OiBcImFkcmVzIElQdjZcIixcbiAgICAgICAgY2lkcnY0OiBcInpha3JlcyBJUHY0XCIsXG4gICAgICAgIGNpZHJ2NjogXCJ6YWtyZXMgSVB2NlwiLFxuICAgICAgICBiYXNlNjQ6IFwiY2lcdTAxMDVnIHpuYWtcdTAwRjN3IHpha29kb3dhbnkgdyBmb3JtYWNpZSBiYXNlNjRcIixcbiAgICAgICAgYmFzZTY0dXJsOiBcImNpXHUwMTA1ZyB6bmFrXHUwMEYzdyB6YWtvZG93YW55IHcgZm9ybWFjaWUgYmFzZTY0dXJsXCIsXG4gICAgICAgIGpzb25fc3RyaW5nOiBcImNpXHUwMTA1ZyB6bmFrXHUwMEYzdyB3IGZvcm1hY2llIEpTT05cIixcbiAgICAgICAgZTE2NDogXCJsaWN6YmEgRS4xNjRcIixcbiAgICAgICAgand0OiBcIkpXVFwiLFxuICAgICAgICB0ZW1wbGF0ZV9saXRlcmFsOiBcIndlalx1MDE1QmNpZVwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOaWVwcmF3aWRcdTAxNDJvd2UgZGFuZSB3ZWpcdTAxNUJjaW93ZTogb2N6ZWtpd2FubyAke2lzc3VlLmV4cGVjdGVkfSwgb3RyenltYW5vICR7cGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgTmllcHJhd2lkXHUwMTQyb3dlIGRhbmUgd2VqXHUwMTVCY2lvd2U6IG9jemVraXdhbm8gJHt1dGlsLnN0cmluZ2lmeVByaW1pdGl2ZShpc3N1ZS52YWx1ZXNbMF0pfWA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOaWVwcmF3aWRcdTAxNDJvd2Egb3BjamE6IG9jemVraXdhbm8gamVkbmVqIHogd2FydG9cdTAxNUJjaSAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS52YWx1ZXMsIFwifFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPD1cIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBaYSBkdVx1MDE3Q2Egd2FydG9cdTAxNUJcdTAxMDc6IG9jemVraXdhbm8sIFx1MDE3Q2UgJHtpc3N1ZS5vcmlnaW4gPz8gXCJ3YXJ0b1x1MDE1Qlx1MDEwN1wifSBiXHUwMTE5ZHppZSBtaWVcdTAxMDcgJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXQgPz8gXCJlbGVtZW50XHUwMEYzd1wifWA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBaYnl0IGR1XHUwMTdDKHkvYS9lKTogb2N6ZWtpd2FubywgXHUwMTdDZSAke2lzc3VlLm9yaWdpbiA/PyBcIndhcnRvXHUwMTVCXHUwMTA3XCJ9IGJcdTAxMTlkemllIHd5bm9zaVx1MDEwNyAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJ0b29fc21hbGxcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPj1cIiA6IFwiPlwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBaYSBtYVx1MDE0MmEgd2FydG9cdTAxNUJcdTAxMDc6IG9jemVraXdhbm8sIFx1MDE3Q2UgJHtpc3N1ZS5vcmlnaW4gPz8gXCJ3YXJ0b1x1MDE1Qlx1MDEwN1wifSBiXHUwMTE5ZHppZSBtaWVcdTAxMDcgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXQgPz8gXCJlbGVtZW50XHUwMEYzd1wifWA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBaYnl0IG1hXHUwMTQyKHkvYS9lKTogb2N6ZWtpd2FubywgXHUwMTdDZSAke2lzc3VlLm9yaWdpbiA/PyBcIndhcnRvXHUwMTVCXHUwMTA3XCJ9IGJcdTAxMTlkemllIHd5bm9zaVx1MDEwNyAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2Zvcm1hdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgX2lzc3VlID0gaXNzdWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInN0YXJ0c193aXRoXCIpIHJldHVybiBgTmllcHJhd2lkXHUwMTQyb3d5IGNpXHUwMTA1ZyB6bmFrXHUwMEYzdzogbXVzaSB6YWN6eW5hXHUwMTA3IHNpXHUwMTE5IG9kIFwiJHtfaXNzdWUucHJlZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiZW5kc193aXRoXCIpIHJldHVybiBgTmllcHJhd2lkXHUwMTQyb3d5IGNpXHUwMTA1ZyB6bmFrXHUwMEYzdzogbXVzaSBrb1x1MDE0NGN6eVx1MDEwNyBzaVx1MDExOSBuYSBcIiR7X2lzc3VlLnN1ZmZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImluY2x1ZGVzXCIpIHJldHVybiBgTmllcHJhd2lkXHUwMTQyb3d5IGNpXHUwMTA1ZyB6bmFrXHUwMEYzdzogbXVzaSB6YXdpZXJhXHUwMTA3IFwiJHtfaXNzdWUuaW5jbHVkZXN9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYE5pZXByYXdpZFx1MDE0Mm93eSBjaVx1MDEwNWcgem5ha1x1MDBGM3c6IG11c2kgb2Rwb3dpYWRhXHUwMTA3IHd6b3Jjb3dpICR7X2lzc3VlLnBhdHRlcm59YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBOaWVwcmF3aWRcdTAxNDJvdyh5L2EvZSkgJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOaWVwcmF3aWRcdTAxNDJvd2EgbGljemJhOiBtdXNpIGJ5XHUwMTA3IHdpZWxva3JvdG5vXHUwMTVCY2lcdTAxMDUgJHtpc3N1ZS5kaXZpc29yfWA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYE5pZXJvenBvem5hbmUga2x1Y3plJHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcInNcIiA6IFwiXCJ9OiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIiwgXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYE5pZXByYXdpZFx1MDE0Mm93eSBrbHVjeiB3ICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF91bmlvblwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIk5pZXByYXdpZFx1MDE0Mm93ZSBkYW5lIHdlalx1MDE1QmNpb3dlXCI7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9lbGVtZW50XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOaWVwcmF3aWRcdTAxNDJvd2Egd2FydG9cdTAxNUJcdTAxMDcgdyAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gYE5pZXByYXdpZFx1MDE0Mm93ZSBkYW5lIHdlalx1MDE1QmNpb3dlYDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJjYXJhY3RlcmVzXCIsXG4gICAgICAgICAgICB2ZXJiOiBcInRlclwiXG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiYnl0ZXNcIixcbiAgICAgICAgICAgIHZlcmI6IFwidGVyXCJcbiAgICAgICAgfSxcbiAgICAgICAgYXJyYXk6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiaXRlbnNcIixcbiAgICAgICAgICAgIHZlcmI6IFwidGVyXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcIml0ZW5zXCIsXG4gICAgICAgICAgICB2ZXJiOiBcInRlclwiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4pIHtcbiAgICAgICAgcmV0dXJuIFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWRUeXBlID0gKGRhdGEpPT57XG4gICAgICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICAgICAgc3dpdGNoKHQpe1xuICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIm5cdTAwRkFtZXJvXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm9iamVjdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcImFycmF5XCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGEgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm51bG9cIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKGRhdGEpICE9PSBPYmplY3QucHJvdG90eXBlICYmIGRhdGEuY29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHQ7XG4gICAgfTtcbiAgICBjb25zdCBOb3VucyA9IHtcbiAgICAgICAgcmVnZXg6IFwicGFkclx1MDBFM29cIixcbiAgICAgICAgZW1haWw6IFwiZW5kZXJlXHUwMEU3byBkZSBlLW1haWxcIixcbiAgICAgICAgdXJsOiBcIlVSTFwiLFxuICAgICAgICBlbW9qaTogXCJlbW9qaVwiLFxuICAgICAgICB1dWlkOiBcIlVVSURcIixcbiAgICAgICAgdXVpZHY0OiBcIlVVSUR2NFwiLFxuICAgICAgICB1dWlkdjY6IFwiVVVJRHY2XCIsXG4gICAgICAgIG5hbm9pZDogXCJuYW5vaWRcIixcbiAgICAgICAgZ3VpZDogXCJHVUlEXCIsXG4gICAgICAgIGN1aWQ6IFwiY3VpZFwiLFxuICAgICAgICBjdWlkMjogXCJjdWlkMlwiLFxuICAgICAgICB1bGlkOiBcIlVMSURcIixcbiAgICAgICAgeGlkOiBcIlhJRFwiLFxuICAgICAgICBrc3VpZDogXCJLU1VJRFwiLFxuICAgICAgICBkYXRldGltZTogXCJkYXRhIGUgaG9yYSBJU09cIixcbiAgICAgICAgZGF0ZTogXCJkYXRhIElTT1wiLFxuICAgICAgICB0aW1lOiBcImhvcmEgSVNPXCIsXG4gICAgICAgIGR1cmF0aW9uOiBcImR1cmFcdTAwRTdcdTAwRTNvIElTT1wiLFxuICAgICAgICBpcHY0OiBcImVuZGVyZVx1MDBFN28gSVB2NFwiLFxuICAgICAgICBpcHY2OiBcImVuZGVyZVx1MDBFN28gSVB2NlwiLFxuICAgICAgICBjaWRydjQ6IFwiZmFpeGEgZGUgSVB2NFwiLFxuICAgICAgICBjaWRydjY6IFwiZmFpeGEgZGUgSVB2NlwiLFxuICAgICAgICBiYXNlNjQ6IFwidGV4dG8gY29kaWZpY2FkbyBlbSBiYXNlNjRcIixcbiAgICAgICAgYmFzZTY0dXJsOiBcIlVSTCBjb2RpZmljYWRhIGVtIGJhc2U2NFwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJ0ZXh0byBKU09OXCIsXG4gICAgICAgIGUxNjQ6IFwiblx1MDBGQW1lcm8gRS4xNjRcIixcbiAgICAgICAgand0OiBcIkpXVFwiLFxuICAgICAgICB0ZW1wbGF0ZV9saXRlcmFsOiBcImVudHJhZGFcIlxuICAgIH07XG4gICAgcmV0dXJuIChpc3N1ZSk9PntcbiAgICAgICAgc3dpdGNoKGlzc3VlLmNvZGUpe1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdHlwZVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgVGlwbyBpbnZcdTAwRTFsaWRvOiBlc3BlcmFkbyAke2lzc3VlLmV4cGVjdGVkfSwgcmVjZWJpZG8gJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBFbnRyYWRhIGludlx1MDBFMWxpZGE6IGVzcGVyYWRvICR7dXRpbC5zdHJpbmdpZnlQcmltaXRpdmUoaXNzdWUudmFsdWVzWzBdKX1gO1xuICAgICAgICAgICAgICAgIHJldHVybiBgT3BcdTAwRTdcdTAwRTNvIGludlx1MDBFMWxpZGE6IGVzcGVyYWRhIHVtYSBkYXMgJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIjw9XCIgOiBcIjxcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgTXVpdG8gZ3JhbmRlOiBlc3BlcmFkbyBxdWUgJHtpc3N1ZS5vcmlnaW4gPz8gXCJ2YWxvclwifSB0aXZlc3NlICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0ID8/IFwiZWxlbWVudG9zXCJ9YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBNdWl0byBncmFuZGU6IGVzcGVyYWRvIHF1ZSAke2lzc3VlLm9yaWdpbiA/PyBcInZhbG9yXCJ9IGZvc3NlICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInRvb19zbWFsbFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI+PVwiIDogXCI+XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYE11aXRvIHBlcXVlbm86IGVzcGVyYWRvIHF1ZSAke2lzc3VlLm9yaWdpbn0gdGl2ZXNzZSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdH1gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgTXVpdG8gcGVxdWVubzogZXNwZXJhZG8gcXVlICR7aXNzdWUub3JpZ2lufSBmb3NzZSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2Zvcm1hdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgX2lzc3VlID0gaXNzdWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInN0YXJ0c193aXRoXCIpIHJldHVybiBgVGV4dG8gaW52XHUwMEUxbGlkbzogZGV2ZSBjb21lXHUwMEU3YXIgY29tIFwiJHtfaXNzdWUucHJlZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiZW5kc193aXRoXCIpIHJldHVybiBgVGV4dG8gaW52XHUwMEUxbGlkbzogZGV2ZSB0ZXJtaW5hciBjb20gXCIke19pc3N1ZS5zdWZmaXh9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJpbmNsdWRlc1wiKSByZXR1cm4gYFRleHRvIGludlx1MDBFMWxpZG86IGRldmUgaW5jbHVpciBcIiR7X2lzc3VlLmluY2x1ZGVzfVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBUZXh0byBpbnZcdTAwRTFsaWRvOiBkZXZlIGNvcnJlc3BvbmRlciBhbyBwYWRyXHUwMEUzbyAke19pc3N1ZS5wYXR0ZXJufWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9IGludlx1MDBFMWxpZG9gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJub3RfbXVsdGlwbGVfb2ZcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYE5cdTAwRkFtZXJvIGludlx1MDBFMWxpZG86IGRldmUgc2VyIG1cdTAwRkFsdGlwbG8gZGUgJHtpc3N1ZS5kaXZpc29yfWA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYENoYXZlJHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcInNcIiA6IFwiXCJ9IGRlc2NvbmhlY2lkYSR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJzXCIgOiBcIlwifTogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgXCIsIFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfa2V5XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBDaGF2ZSBpbnZcdTAwRTFsaWRhIGVtICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF91bmlvblwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIkVudHJhZGEgaW52XHUwMEUxbGlkYVwiO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZWxlbWVudFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgVmFsb3IgaW52XHUwMEUxbGlkbyBlbSAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gYENhbXBvIGludlx1MDBFMWxpZG9gO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBsb2NhbGVFcnJvcjogZXJyb3IoKVxuICAgIH07XG59XG4iLCAiaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi4vY29yZS91dGlsLmpzXCI7XG5mdW5jdGlvbiBnZXRSdXNzaWFuUGx1cmFsKGNvdW50LCBvbmUsIGZldywgbWFueSkge1xuICAgIGNvbnN0IGFic0NvdW50ID0gTWF0aC5hYnMoY291bnQpO1xuICAgIGNvbnN0IGxhc3REaWdpdCA9IGFic0NvdW50ICUgMTA7XG4gICAgY29uc3QgbGFzdFR3b0RpZ2l0cyA9IGFic0NvdW50ICUgMTAwO1xuICAgIGlmIChsYXN0VHdvRGlnaXRzID49IDExICYmIGxhc3RUd29EaWdpdHMgPD0gMTkpIHtcbiAgICAgICAgcmV0dXJuIG1hbnk7XG4gICAgfVxuICAgIGlmIChsYXN0RGlnaXQgPT09IDEpIHtcbiAgICAgICAgcmV0dXJuIG9uZTtcbiAgICB9XG4gICAgaWYgKGxhc3REaWdpdCA+PSAyICYmIGxhc3REaWdpdCA8PSA0KSB7XG4gICAgICAgIHJldHVybiBmZXc7XG4gICAgfVxuICAgIHJldHVybiBtYW55O1xufVxuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDoge1xuICAgICAgICAgICAgICAgIG9uZTogXCJcdTA0NDFcdTA0MzhcdTA0M0NcdTA0MzJcdTA0M0VcdTA0M0JcIixcbiAgICAgICAgICAgICAgICBmZXc6IFwiXHUwNDQxXHUwNDM4XHUwNDNDXHUwNDMyXHUwNDNFXHUwNDNCXHUwNDMwXCIsXG4gICAgICAgICAgICAgICAgbWFueTogXCJcdTA0NDFcdTA0MzhcdTA0M0NcdTA0MzJcdTA0M0VcdTA0M0JcdTA0M0VcdTA0MzJcIlxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwNDM4XHUwNDNDXHUwNDM1XHUwNDQyXHUwNDRDXCJcbiAgICAgICAgfSxcbiAgICAgICAgZmlsZToge1xuICAgICAgICAgICAgdW5pdDoge1xuICAgICAgICAgICAgICAgIG9uZTogXCJcdTA0MzFcdTA0MzBcdTA0MzlcdTA0NDJcIixcbiAgICAgICAgICAgICAgICBmZXc6IFwiXHUwNDMxXHUwNDMwXHUwNDM5XHUwNDQyXHUwNDMwXCIsXG4gICAgICAgICAgICAgICAgbWFueTogXCJcdTA0MzFcdTA0MzBcdTA0MzlcdTA0NDJcIlxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwNDM4XHUwNDNDXHUwNDM1XHUwNDQyXHUwNDRDXCJcbiAgICAgICAgfSxcbiAgICAgICAgYXJyYXk6IHtcbiAgICAgICAgICAgIHVuaXQ6IHtcbiAgICAgICAgICAgICAgICBvbmU6IFwiXHUwNDREXHUwNDNCXHUwNDM1XHUwNDNDXHUwNDM1XHUwNDNEXHUwNDQyXCIsXG4gICAgICAgICAgICAgICAgZmV3OiBcIlx1MDQ0RFx1MDQzQlx1MDQzNVx1MDQzQ1x1MDQzNVx1MDQzRFx1MDQ0Mlx1MDQzMFwiLFxuICAgICAgICAgICAgICAgIG1hbnk6IFwiXHUwNDREXHUwNDNCXHUwNDM1XHUwNDNDXHUwNDM1XHUwNDNEXHUwNDQyXHUwNDNFXHUwNDMyXCJcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MDQzOFx1MDQzQ1x1MDQzNVx1MDQ0Mlx1MDQ0Q1wiXG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDoge1xuICAgICAgICAgICAgICAgIG9uZTogXCJcdTA0NERcdTA0M0JcdTA0MzVcdTA0M0NcdTA0MzVcdTA0M0RcdTA0NDJcIixcbiAgICAgICAgICAgICAgICBmZXc6IFwiXHUwNDREXHUwNDNCXHUwNDM1XHUwNDNDXHUwNDM1XHUwNDNEXHUwNDQyXHUwNDMwXCIsXG4gICAgICAgICAgICAgICAgbWFueTogXCJcdTA0NERcdTA0M0JcdTA0MzVcdTA0M0NcdTA0MzVcdTA0M0RcdTA0NDJcdTA0M0VcdTA0MzJcIlxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwNDM4XHUwNDNDXHUwNDM1XHUwNDQyXHUwNDRDXCJcbiAgICAgICAgfVxuICAgIH07XG4gICAgZnVuY3Rpb24gZ2V0U2l6aW5nKG9yaWdpbikge1xuICAgICAgICByZXR1cm4gU2l6YWJsZVtvcmlnaW5dID8/IG51bGw7XG4gICAgfVxuICAgIGNvbnN0IHBhcnNlZFR5cGUgPSAoZGF0YSk9PntcbiAgICAgICAgY29uc3QgdCA9IHR5cGVvZiBkYXRhO1xuICAgICAgICBzd2l0Y2godCl7XG4gICAgICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gTnVtYmVyLmlzTmFOKGRhdGEpID8gXCJOYU5cIiA6IFwiXHUwNDQ3XHUwNDM4XHUwNDQxXHUwNDNCXHUwNDNFXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm9iamVjdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIlx1MDQzQ1x1MDQzMFx1MDQ0MVx1MDQ0MVx1MDQzOFx1MDQzMlwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJudWxsXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcIlx1MDQzMlx1MDQzMlx1MDQzRVx1MDQzNFwiLFxuICAgICAgICBlbWFpbDogXCJlbWFpbCBcdTA0MzBcdTA0MzRcdTA0NDBcdTA0MzVcdTA0NDFcIixcbiAgICAgICAgdXJsOiBcIlVSTFwiLFxuICAgICAgICBlbW9qaTogXCJcdTA0NERcdTA0M0NcdTA0M0VcdTA0MzRcdTA0MzdcdTA0MzhcIixcbiAgICAgICAgdXVpZDogXCJVVUlEXCIsXG4gICAgICAgIHV1aWR2NDogXCJVVUlEdjRcIixcbiAgICAgICAgdXVpZHY2OiBcIlVVSUR2NlwiLFxuICAgICAgICBuYW5vaWQ6IFwibmFub2lkXCIsXG4gICAgICAgIGd1aWQ6IFwiR1VJRFwiLFxuICAgICAgICBjdWlkOiBcImN1aWRcIixcbiAgICAgICAgY3VpZDI6IFwiY3VpZDJcIixcbiAgICAgICAgdWxpZDogXCJVTElEXCIsXG4gICAgICAgIHhpZDogXCJYSURcIixcbiAgICAgICAga3N1aWQ6IFwiS1NVSURcIixcbiAgICAgICAgZGF0ZXRpbWU6IFwiSVNPIFx1MDQzNFx1MDQzMFx1MDQ0Mlx1MDQzMCBcdTA0MzggXHUwNDMyXHUwNDQwXHUwNDM1XHUwNDNDXHUwNDRGXCIsXG4gICAgICAgIGRhdGU6IFwiSVNPIFx1MDQzNFx1MDQzMFx1MDQ0Mlx1MDQzMFwiLFxuICAgICAgICB0aW1lOiBcIklTTyBcdTA0MzJcdTA0NDBcdTA0MzVcdTA0M0NcdTA0NEZcIixcbiAgICAgICAgZHVyYXRpb246IFwiSVNPIFx1MDQzNFx1MDQzQlx1MDQzOFx1MDQ0Mlx1MDQzNVx1MDQzQlx1MDQ0Q1x1MDQzRFx1MDQzRVx1MDQ0MVx1MDQ0Mlx1MDQ0Q1wiLFxuICAgICAgICBpcHY0OiBcIklQdjQgXHUwNDMwXHUwNDM0XHUwNDQwXHUwNDM1XHUwNDQxXCIsXG4gICAgICAgIGlwdjY6IFwiSVB2NiBcdTA0MzBcdTA0MzRcdTA0NDBcdTA0MzVcdTA0NDFcIixcbiAgICAgICAgY2lkcnY0OiBcIklQdjQgXHUwNDM0XHUwNDM4XHUwNDMwXHUwNDNGXHUwNDMwXHUwNDM3XHUwNDNFXHUwNDNEXCIsXG4gICAgICAgIGNpZHJ2NjogXCJJUHY2IFx1MDQzNFx1MDQzOFx1MDQzMFx1MDQzRlx1MDQzMFx1MDQzN1x1MDQzRVx1MDQzRFwiLFxuICAgICAgICBiYXNlNjQ6IFwiXHUwNDQxXHUwNDQyXHUwNDQwXHUwNDNFXHUwNDNBXHUwNDMwIFx1MDQzMiBcdTA0NDRcdTA0M0VcdTA0NDBcdTA0M0NcdTA0MzBcdTA0NDJcdTA0MzUgYmFzZTY0XCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJcdTA0NDFcdTA0NDJcdTA0NDBcdTA0M0VcdTA0M0FcdTA0MzAgXHUwNDMyIFx1MDQ0NFx1MDQzRVx1MDQ0MFx1MDQzQ1x1MDQzMFx1MDQ0Mlx1MDQzNSBiYXNlNjR1cmxcIixcbiAgICAgICAganNvbl9zdHJpbmc6IFwiSlNPTiBcdTA0NDFcdTA0NDJcdTA0NDBcdTA0M0VcdTA0M0FcdTA0MzBcIixcbiAgICAgICAgZTE2NDogXCJcdTA0M0RcdTA0M0VcdTA0M0NcdTA0MzVcdTA0NDAgRS4xNjRcIixcbiAgICAgICAgand0OiBcIkpXVFwiLFxuICAgICAgICB0ZW1wbGF0ZV9saXRlcmFsOiBcIlx1MDQzMlx1MDQzMlx1MDQzRVx1MDQzNFwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MURcdTA0MzVcdTA0MzJcdTA0MzVcdTA0NDBcdTA0M0RcdTA0NEJcdTA0MzkgXHUwNDMyXHUwNDMyXHUwNDNFXHUwNDM0OiBcdTA0M0VcdTA0MzZcdTA0MzhcdTA0MzRcdTA0MzBcdTA0M0JcdTA0M0VcdTA0NDFcdTA0NEMgJHtpc3N1ZS5leHBlY3RlZH0sIFx1MDQzRlx1MDQzRVx1MDQzQlx1MDQ0M1x1MDQ0N1x1MDQzNVx1MDQzRFx1MDQzRSAke3BhcnNlZFR5cGUoaXNzdWUuaW5wdXQpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF92YWx1ZVwiOlxuICAgICAgICAgICAgICAgIGlmIChpc3N1ZS52YWx1ZXMubGVuZ3RoID09PSAxKSByZXR1cm4gYFx1MDQxRFx1MDQzNVx1MDQzMlx1MDQzNVx1MDQ0MFx1MDQzRFx1MDQ0Qlx1MDQzOSBcdTA0MzJcdTA0MzJcdTA0M0VcdTA0MzQ6IFx1MDQzRVx1MDQzNlx1MDQzOFx1MDQzNFx1MDQzMFx1MDQzQlx1MDQzRVx1MDQ0MVx1MDQ0QyAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDQxRFx1MDQzNVx1MDQzMlx1MDQzNVx1MDQ0MFx1MDQzRFx1MDQ0Qlx1MDQzOSBcdTA0MzJcdTA0MzBcdTA0NDBcdTA0MzhcdTA0MzBcdTA0M0RcdTA0NDI6IFx1MDQzRVx1MDQzNlx1MDQzOFx1MDQzNFx1MDQzMFx1MDQzQlx1MDQzRVx1MDQ0MVx1MDQ0QyBcdTA0M0VcdTA0MzRcdTA0M0RcdTA0M0UgXHUwNDM4XHUwNDM3ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLnZhbHVlcywgXCJ8XCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwidG9vX2JpZ1wiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI8PVwiIDogXCI8XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtYXhWYWx1ZSA9IE51bWJlcihpc3N1ZS5tYXhpbXVtKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVuaXQgPSBnZXRSdXNzaWFuUGx1cmFsKG1heFZhbHVlLCBzaXppbmcudW5pdC5vbmUsIHNpemluZy51bml0LmZldywgc2l6aW5nLnVuaXQubWFueSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDQyMVx1MDQzQlx1MDQzOFx1MDQ0OFx1MDQzQVx1MDQzRVx1MDQzQyBcdTA0MzFcdTA0M0VcdTA0M0JcdTA0NENcdTA0NDhcdTA0M0VcdTA0MzUgXHUwNDM3XHUwNDNEXHUwNDMwXHUwNDQ3XHUwNDM1XHUwNDNEXHUwNDM4XHUwNDM1OiBcdTA0M0VcdTA0MzZcdTA0MzhcdTA0MzRcdTA0MzBcdTA0M0JcdTA0M0VcdTA0NDFcdTA0NEMsIFx1MDQ0N1x1MDQ0Mlx1MDQzRSAke2lzc3VlLm9yaWdpbiA/PyBcIlx1MDQzN1x1MDQzRFx1MDQzMFx1MDQ0N1x1MDQzNVx1MDQzRFx1MDQzOFx1MDQzNVwifSBcdTA0MzFcdTA0NDNcdTA0MzRcdTA0MzVcdTA0NDIgXHUwNDM4XHUwNDNDXHUwNDM1XHUwNDQyXHUwNDRDICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke3VuaXR9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDQyMVx1MDQzQlx1MDQzOFx1MDQ0OFx1MDQzQVx1MDQzRVx1MDQzQyBcdTA0MzFcdTA0M0VcdTA0M0JcdTA0NENcdTA0NDhcdTA0M0VcdTA0MzUgXHUwNDM3XHUwNDNEXHUwNDMwXHUwNDQ3XHUwNDM1XHUwNDNEXHUwNDM4XHUwNDM1OiBcdTA0M0VcdTA0MzZcdTA0MzhcdTA0MzRcdTA0MzBcdTA0M0JcdTA0M0VcdTA0NDFcdTA0NEMsIFx1MDQ0N1x1MDQ0Mlx1MDQzRSAke2lzc3VlLm9yaWdpbiA/PyBcIlx1MDQzN1x1MDQzRFx1MDQzMFx1MDQ0N1x1MDQzNVx1MDQzRFx1MDQzOFx1MDQzNVwifSBcdTA0MzFcdTA0NDNcdTA0MzRcdTA0MzVcdTA0NDIgJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIj49XCIgOiBcIj5cIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1pblZhbHVlID0gTnVtYmVyKGlzc3VlLm1pbmltdW0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5pdCA9IGdldFJ1c3NpYW5QbHVyYWwobWluVmFsdWUsIHNpemluZy51bml0Lm9uZSwgc2l6aW5nLnVuaXQuZmV3LCBzaXppbmcudW5pdC5tYW55KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNDIxXHUwNDNCXHUwNDM4XHUwNDQ4XHUwNDNBXHUwNDNFXHUwNDNDIFx1MDQzQ1x1MDQzMFx1MDQzQlx1MDQzNVx1MDQzRFx1MDQ0Q1x1MDQzQVx1MDQzRVx1MDQzNSBcdTA0MzdcdTA0M0RcdTA0MzBcdTA0NDdcdTA0MzVcdTA0M0RcdTA0MzhcdTA0MzU6IFx1MDQzRVx1MDQzNlx1MDQzOFx1MDQzNFx1MDQzMFx1MDQzQlx1MDQzRVx1MDQ0MVx1MDQ0QywgXHUwNDQ3XHUwNDQyXHUwNDNFICR7aXNzdWUub3JpZ2lufSBcdTA0MzFcdTA0NDNcdTA0MzRcdTA0MzVcdTA0NDIgXHUwNDM4XHUwNDNDXHUwNDM1XHUwNDQyXHUwNDRDICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3VuaXR9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDQyMVx1MDQzQlx1MDQzOFx1MDQ0OFx1MDQzQVx1MDQzRVx1MDQzQyBcdTA0M0NcdTA0MzBcdTA0M0JcdTA0MzVcdTA0M0RcdTA0NENcdTA0M0FcdTA0M0VcdTA0MzUgXHUwNDM3XHUwNDNEXHUwNDMwXHUwNDQ3XHUwNDM1XHUwNDNEXHUwNDM4XHUwNDM1OiBcdTA0M0VcdTA0MzZcdTA0MzhcdTA0MzRcdTA0MzBcdTA0M0JcdTA0M0VcdTA0NDFcdTA0NEMsIFx1MDQ0N1x1MDQ0Mlx1MDQzRSAke2lzc3VlLm9yaWdpbn0gXHUwNDMxXHUwNDQzXHUwNDM0XHUwNDM1XHUwNDQyICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZm9ybWF0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBfaXNzdWUgPSBpc3N1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwic3RhcnRzX3dpdGhcIikgcmV0dXJuIGBcdTA0MURcdTA0MzVcdTA0MzJcdTA0MzVcdTA0NDBcdTA0M0RcdTA0MzBcdTA0NEYgXHUwNDQxXHUwNDQyXHUwNDQwXHUwNDNFXHUwNDNBXHUwNDMwOiBcdTA0MzRcdTA0M0VcdTA0M0JcdTA0MzZcdTA0M0RcdTA0MzAgXHUwNDNEXHUwNDMwXHUwNDQ3XHUwNDM4XHUwNDNEXHUwNDMwXHUwNDQyXHUwNDRDXHUwNDQxXHUwNDRGIFx1MDQ0MSBcIiR7X2lzc3VlLnByZWZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYFx1MDQxRFx1MDQzNVx1MDQzMlx1MDQzNVx1MDQ0MFx1MDQzRFx1MDQzMFx1MDQ0RiBcdTA0NDFcdTA0NDJcdTA0NDBcdTA0M0VcdTA0M0FcdTA0MzA6IFx1MDQzNFx1MDQzRVx1MDQzQlx1MDQzNlx1MDQzRFx1MDQzMCBcdTA0MzdcdTA0MzBcdTA0M0FcdTA0MzBcdTA0M0RcdTA0NDdcdTA0MzhcdTA0MzJcdTA0MzBcdTA0NDJcdTA0NENcdTA0NDFcdTA0NEYgXHUwNDNEXHUwNDMwIFwiJHtfaXNzdWUuc3VmZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBcdTA0MURcdTA0MzVcdTA0MzJcdTA0MzVcdTA0NDBcdTA0M0RcdTA0MzBcdTA0NEYgXHUwNDQxXHUwNDQyXHUwNDQwXHUwNDNFXHUwNDNBXHUwNDMwOiBcdTA0MzRcdTA0M0VcdTA0M0JcdTA0MzZcdTA0M0RcdTA0MzAgXHUwNDQxXHUwNDNFXHUwNDM0XHUwNDM1XHUwNDQwXHUwNDM2XHUwNDMwXHUwNDQyXHUwNDRDIFwiJHtfaXNzdWUuaW5jbHVkZXN9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYFx1MDQxRFx1MDQzNVx1MDQzMlx1MDQzNVx1MDQ0MFx1MDQzRFx1MDQzMFx1MDQ0RiBcdTA0NDFcdTA0NDJcdTA0NDBcdTA0M0VcdTA0M0FcdTA0MzA6IFx1MDQzNFx1MDQzRVx1MDQzQlx1MDQzNlx1MDQzRFx1MDQzMCBcdTA0NDFcdTA0M0VcdTA0M0VcdTA0NDJcdTA0MzJcdTA0MzVcdTA0NDJcdTA0NDFcdTA0NDJcdTA0MzJcdTA0M0VcdTA0MzJcdTA0MzBcdTA0NDJcdTA0NEMgXHUwNDQ4XHUwNDMwXHUwNDMxXHUwNDNCXHUwNDNFXHUwNDNEXHUwNDQzICR7X2lzc3VlLnBhdHRlcm59YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MURcdTA0MzVcdTA0MzJcdTA0MzVcdTA0NDBcdTA0M0RcdTA0NEJcdTA0MzkgJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MURcdTA0MzVcdTA0MzJcdTA0MzVcdTA0NDBcdTA0M0RcdTA0M0VcdTA0MzUgXHUwNDQ3XHUwNDM4XHUwNDQxXHUwNDNCXHUwNDNFOiBcdTA0MzRcdTA0M0VcdTA0M0JcdTA0MzZcdTA0M0RcdTA0M0UgXHUwNDMxXHUwNDRCXHUwNDQyXHUwNDRDIFx1MDQzQVx1MDQ0MFx1MDQzMFx1MDQ0Mlx1MDQzRFx1MDQ0Qlx1MDQzQyAke2lzc3VlLmRpdmlzb3J9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ1bnJlY29nbml6ZWRfa2V5c1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNDFEXHUwNDM1XHUwNDQwXHUwNDMwXHUwNDQxXHUwNDNGXHUwNDNFXHUwNDM3XHUwNDNEXHUwNDMwXHUwNDNEXHUwNDNEJHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcIlx1MDQ0Qlx1MDQzNVwiIDogXCJcdTA0NEJcdTA0MzlcIn0gXHUwNDNBXHUwNDNCXHUwNDRFXHUwNDQ3JHtpc3N1ZS5rZXlzLmxlbmd0aCA+IDEgPyBcIlx1MDQzOFwiIDogXCJcIn06ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLmtleXMsIFwiLCBcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2tleVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNDFEXHUwNDM1XHUwNDMyXHUwNDM1XHUwNDQwXHUwNDNEXHUwNDRCXHUwNDM5IFx1MDQzQVx1MDQzQlx1MDQ0RVx1MDQ0NyBcdTA0MzIgJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3VuaW9uXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiXHUwNDFEXHUwNDM1XHUwNDMyXHUwNDM1XHUwNDQwXHUwNDNEXHUwNDRCXHUwNDM1IFx1MDQzMlx1MDQ0NVx1MDQzRVx1MDQzNFx1MDQzRFx1MDQ0Qlx1MDQzNSBcdTA0MzRcdTA0MzBcdTA0M0RcdTA0M0RcdTA0NEJcdTA0MzVcIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDQxRFx1MDQzNVx1MDQzMlx1MDQzNVx1MDQ0MFx1MDQzRFx1MDQzRVx1MDQzNSBcdTA0MzdcdTA0M0RcdTA0MzBcdTA0NDdcdTA0MzVcdTA0M0RcdTA0MzhcdTA0MzUgXHUwNDMyICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNDFEXHUwNDM1XHUwNDMyXHUwNDM1XHUwNDQwXHUwNDNEXHUwNDRCXHUwNDM1IFx1MDQzMlx1MDQ0NVx1MDQzRVx1MDQzNFx1MDQzRFx1MDQ0Qlx1MDQzNSBcdTA0MzRcdTA0MzBcdTA0M0RcdTA0M0RcdTA0NEJcdTA0MzVgO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBsb2NhbGVFcnJvcjogZXJyb3IoKVxuICAgIH07XG59XG4iLCAiaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi4vY29yZS91dGlsLmpzXCI7XG5jb25zdCBlcnJvciA9ICgpPT57XG4gICAgY29uc3QgU2l6YWJsZSA9IHtcbiAgICAgICAgc3RyaW5nOiB7XG4gICAgICAgICAgICB1bml0OiBcInpuYWtvdlwiLFxuICAgICAgICAgICAgdmVyYjogXCJpbWV0aVwiXG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiYmFqdG92XCIsXG4gICAgICAgICAgICB2ZXJiOiBcImltZXRpXCJcbiAgICAgICAgfSxcbiAgICAgICAgYXJyYXk6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiZWxlbWVudG92XCIsXG4gICAgICAgICAgICB2ZXJiOiBcImltZXRpXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcImVsZW1lbnRvdlwiLFxuICAgICAgICAgICAgdmVyYjogXCJpbWV0aVwiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4pIHtcbiAgICAgICAgcmV0dXJuIFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWRUeXBlID0gKGRhdGEpPT57XG4gICAgICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICAgICAgc3dpdGNoKHQpe1xuICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIlx1MDE2MXRldmlsb1wiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJ0YWJlbGFcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YoZGF0YSkgIT09IE9iamVjdC5wcm90b3R5cGUgJiYgZGF0YS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdDtcbiAgICB9O1xuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJ2bm9zXCIsXG4gICAgICAgIGVtYWlsOiBcImUtcG9cdTAxNjF0bmkgbmFzbG92XCIsXG4gICAgICAgIHVybDogXCJVUkxcIixcbiAgICAgICAgZW1vamk6IFwiZW1vamlcIixcbiAgICAgICAgdXVpZDogXCJVVUlEXCIsXG4gICAgICAgIHV1aWR2NDogXCJVVUlEdjRcIixcbiAgICAgICAgdXVpZHY2OiBcIlVVSUR2NlwiLFxuICAgICAgICBuYW5vaWQ6IFwibmFub2lkXCIsXG4gICAgICAgIGd1aWQ6IFwiR1VJRFwiLFxuICAgICAgICBjdWlkOiBcImN1aWRcIixcbiAgICAgICAgY3VpZDI6IFwiY3VpZDJcIixcbiAgICAgICAgdWxpZDogXCJVTElEXCIsXG4gICAgICAgIHhpZDogXCJYSURcIixcbiAgICAgICAga3N1aWQ6IFwiS1NVSURcIixcbiAgICAgICAgZGF0ZXRpbWU6IFwiSVNPIGRhdHVtIGluIFx1MDEwRGFzXCIsXG4gICAgICAgIGRhdGU6IFwiSVNPIGRhdHVtXCIsXG4gICAgICAgIHRpbWU6IFwiSVNPIFx1MDEwRGFzXCIsXG4gICAgICAgIGR1cmF0aW9uOiBcIklTTyB0cmFqYW5qZVwiLFxuICAgICAgICBpcHY0OiBcIklQdjQgbmFzbG92XCIsXG4gICAgICAgIGlwdjY6IFwiSVB2NiBuYXNsb3ZcIixcbiAgICAgICAgY2lkcnY0OiBcIm9ic2VnIElQdjRcIixcbiAgICAgICAgY2lkcnY2OiBcIm9ic2VnIElQdjZcIixcbiAgICAgICAgYmFzZTY0OiBcImJhc2U2NCBrb2RpcmFuIG5pelwiLFxuICAgICAgICBiYXNlNjR1cmw6IFwiYmFzZTY0dXJsIGtvZGlyYW4gbml6XCIsXG4gICAgICAgIGpzb25fc3RyaW5nOiBcIkpTT04gbml6XCIsXG4gICAgICAgIGUxNjQ6IFwiRS4xNjQgXHUwMTYxdGV2aWxrYVwiLFxuICAgICAgICBqd3Q6IFwiSldUXCIsXG4gICAgICAgIHRlbXBsYXRlX2xpdGVyYWw6IFwidm5vc1wiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOZXZlbGphdmVuIHZub3M6IHByaVx1MDEwRGFrb3Zhbm8gJHtpc3N1ZS5leHBlY3RlZH0sIHByZWpldG8gJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBOZXZlbGphdmVuIHZub3M6IHByaVx1MDEwRGFrb3Zhbm8gJHt1dGlsLnN0cmluZ2lmeVByaW1pdGl2ZShpc3N1ZS52YWx1ZXNbMF0pfWA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOZXZlbGphdm5hIG1vXHUwMTdFbm9zdDogcHJpXHUwMTBEYWtvdmFubyBlbm8gaXptZWQgJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIjw9XCIgOiBcIjxcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgUHJldmVsaWtvOiBwcmlcdTAxMERha292YW5vLCBkYSBibyAke2lzc3VlLm9yaWdpbiA/PyBcInZyZWRub3N0XCJ9IGltZWxvICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0ID8/IFwiZWxlbWVudG92XCJ9YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBQcmV2ZWxpa286IHByaVx1MDEwRGFrb3Zhbm8sIGRhIGJvICR7aXNzdWUub3JpZ2luID8/IFwidnJlZG5vc3RcIn0gJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIj49XCIgOiBcIj5cIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgUHJlbWFqaG5vOiBwcmlcdTAxMERha292YW5vLCBkYSBibyAke2lzc3VlLm9yaWdpbn0gaW1lbG8gJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXR9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFByZW1hamhubzogcHJpXHUwMTBEYWtvdmFubywgZGEgYm8gJHtpc3N1ZS5vcmlnaW59ICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZm9ybWF0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBfaXNzdWUgPSBpc3N1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwic3RhcnRzX3dpdGhcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBOZXZlbGphdmVuIG5pejogbW9yYSBzZSB6YVx1MDEwRGV0aSB6IFwiJHtfaXNzdWUucHJlZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJlbmRzX3dpdGhcIikgcmV0dXJuIGBOZXZlbGphdmVuIG5pejogbW9yYSBzZSBrb25cdTAxMERhdGkgeiBcIiR7X2lzc3VlLnN1ZmZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImluY2x1ZGVzXCIpIHJldHVybiBgTmV2ZWxqYXZlbiBuaXo6IG1vcmEgdnNlYm92YXRpIFwiJHtfaXNzdWUuaW5jbHVkZXN9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYE5ldmVsamF2ZW4gbml6OiBtb3JhIHVzdHJlemF0aSB2em9yY3UgJHtfaXNzdWUucGF0dGVybn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYE5ldmVsamF2ZW4gJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOZXZlbGphdm5vIFx1MDE2MXRldmlsbzogbW9yYSBiaXRpIHZlXHUwMTBEa3JhdG5payAke2lzc3VlLmRpdmlzb3J9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ1bnJlY29nbml6ZWRfa2V5c1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgTmVwcmVwb3puYW4ke2lzc3VlLmtleXMubGVuZ3RoID4gMSA/IFwiaSBrbGp1XHUwMTBEaVwiIDogXCIga2xqdVx1MDEwRFwifTogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgXCIsIFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfa2V5XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBOZXZlbGphdmVuIGtsanVcdTAxMEQgdiAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJOZXZlbGphdmVuIHZub3NcIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYE5ldmVsamF2bmEgdnJlZG5vc3QgdiAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJOZXZlbGphdmVuIHZub3NcIjtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJ0ZWNrZW5cIixcbiAgICAgICAgICAgIHZlcmI6IFwiYXR0IGhhXCJcbiAgICAgICAgfSxcbiAgICAgICAgZmlsZToge1xuICAgICAgICAgICAgdW5pdDogXCJieXRlc1wiLFxuICAgICAgICAgICAgdmVyYjogXCJhdHQgaGFcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJvYmpla3RcIixcbiAgICAgICAgICAgIHZlcmI6IFwiYXR0IGlubmVoXHUwMEU1bGxhXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcIm9iamVrdFwiLFxuICAgICAgICAgICAgdmVyYjogXCJhdHQgaW5uZWhcdTAwRTVsbGFcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIk5hTlwiIDogXCJhbnRhbFwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJsaXN0YVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJudWxsXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcInJlZ3Vsalx1MDBFNHJ0IHV0dHJ5Y2tcIixcbiAgICAgICAgZW1haWw6IFwiZS1wb3N0YWRyZXNzXCIsXG4gICAgICAgIHVybDogXCJVUkxcIixcbiAgICAgICAgZW1vamk6IFwiZW1vamlcIixcbiAgICAgICAgdXVpZDogXCJVVUlEXCIsXG4gICAgICAgIHV1aWR2NDogXCJVVUlEdjRcIixcbiAgICAgICAgdXVpZHY2OiBcIlVVSUR2NlwiLFxuICAgICAgICBuYW5vaWQ6IFwibmFub2lkXCIsXG4gICAgICAgIGd1aWQ6IFwiR1VJRFwiLFxuICAgICAgICBjdWlkOiBcImN1aWRcIixcbiAgICAgICAgY3VpZDI6IFwiY3VpZDJcIixcbiAgICAgICAgdWxpZDogXCJVTElEXCIsXG4gICAgICAgIHhpZDogXCJYSURcIixcbiAgICAgICAga3N1aWQ6IFwiS1NVSURcIixcbiAgICAgICAgZGF0ZXRpbWU6IFwiSVNPLWRhdHVtIG9jaCB0aWRcIixcbiAgICAgICAgZGF0ZTogXCJJU08tZGF0dW1cIixcbiAgICAgICAgdGltZTogXCJJU08tdGlkXCIsXG4gICAgICAgIGR1cmF0aW9uOiBcIklTTy12YXJha3RpZ2hldFwiLFxuICAgICAgICBpcHY0OiBcIklQdjQtaW50ZXJ2YWxsXCIsXG4gICAgICAgIGlwdjY6IFwiSVB2Ni1pbnRlcnZhbGxcIixcbiAgICAgICAgY2lkcnY0OiBcIklQdjQtc3Bla3RydW1cIixcbiAgICAgICAgY2lkcnY2OiBcIklQdjYtc3Bla3RydW1cIixcbiAgICAgICAgYmFzZTY0OiBcImJhc2U2NC1rb2RhZCBzdHJcdTAwRTRuZ1wiLFxuICAgICAgICBiYXNlNjR1cmw6IFwiYmFzZTY0dXJsLWtvZGFkIHN0clx1MDBFNG5nXCIsXG4gICAgICAgIGpzb25fc3RyaW5nOiBcIkpTT04tc3RyXHUwMEU0bmdcIixcbiAgICAgICAgZTE2NDogXCJFLjE2NC1udW1tZXJcIixcbiAgICAgICAgand0OiBcIkpXVFwiLFxuICAgICAgICB0ZW1wbGF0ZV9saXRlcmFsOiBcIm1hbGwtbGl0ZXJhbFwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBPZ2lsdGlnIGlubWF0bmluZzogZlx1MDBGNnJ2XHUwMEU0bnRhdCAke2lzc3VlLmV4cGVjdGVkfSwgZmljayAke3BhcnNlZFR5cGUoaXNzdWUuaW5wdXQpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF92YWx1ZVwiOlxuICAgICAgICAgICAgICAgIGlmIChpc3N1ZS52YWx1ZXMubGVuZ3RoID09PSAxKSByZXR1cm4gYE9naWx0aWcgaW5tYXRuaW5nOiBmXHUwMEY2cnZcdTAwRTRudGF0ICR7dXRpbC5zdHJpbmdpZnlQcmltaXRpdmUoaXNzdWUudmFsdWVzWzBdKX1gO1xuICAgICAgICAgICAgICAgIHJldHVybiBgT2dpbHRpZ3QgdmFsOiBmXHUwMEY2cnZcdTAwRTRudGFkZSBlbiBhdiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS52YWx1ZXMsIFwifFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPD1cIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBGXHUwMEY2ciBzdG9yKHQpOiBmXHUwMEY2cnZcdTAwRTRudGFkZSAke2lzc3VlLm9yaWdpbiA/PyBcInZcdTAwRTRyZGV0XCJ9IGF0dCBoYSAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdCA/PyBcImVsZW1lbnRcIn1gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgRlx1MDBGNnIgc3Rvcih0KTogZlx1MDBGNnJ2XHUwMEU0bnRhdCAke2lzc3VlLm9yaWdpbiA/PyBcInZcdTAwRTRyZGV0XCJ9IGF0dCBoYSAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJ0b29fc21hbGxcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPj1cIiA6IFwiPlwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBGXHUwMEY2ciBsaXRlKHQpOiBmXHUwMEY2cnZcdTAwRTRudGFkZSAke2lzc3VlLm9yaWdpbiA/PyBcInZcdTAwRTRyZGV0XCJ9IGF0dCBoYSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdH1gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgRlx1MDBGNnIgbGl0ZSh0KTogZlx1MDBGNnJ2XHUwMEU0bnRhZGUgJHtpc3N1ZS5vcmlnaW4gPz8gXCJ2XHUwMEU0cmRldFwifSBhdHQgaGEgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYE9naWx0aWcgc3RyXHUwMEU0bmc6IG1cdTAwRTVzdGUgYlx1MDBGNnJqYSBtZWQgXCIke19pc3N1ZS5wcmVmaXh9XCJgO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYE9naWx0aWcgc3RyXHUwMEU0bmc6IG1cdTAwRTVzdGUgc2x1dGEgbWVkIFwiJHtfaXNzdWUuc3VmZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBPZ2lsdGlnIHN0clx1MDBFNG5nOiBtXHUwMEU1c3RlIGlubmVoXHUwMEU1bGxhIFwiJHtfaXNzdWUuaW5jbHVkZXN9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJyZWdleFwiKSByZXR1cm4gYE9naWx0aWcgc3RyXHUwMEU0bmc6IG1cdTAwRTVzdGUgbWF0Y2hhIG1cdTAwRjZuc3RyZXQgXCIke19pc3N1ZS5wYXR0ZXJufVwiYDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBPZ2lsdGlnKHQpICR7Tm91bnNbX2lzc3VlLmZvcm1hdF0gPz8gaXNzdWUuZm9ybWF0fWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm5vdF9tdWx0aXBsZV9vZlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgT2dpbHRpZ3QgdGFsOiBtXHUwMEU1c3RlIHZhcmEgZW4gbXVsdGlwZWwgYXYgJHtpc3N1ZS5kaXZpc29yfWA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYCR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJPa1x1MDBFNG5kYSBueWNrbGFyXCIgOiBcIk9rXHUwMEU0bmQgbnlja2VsXCJ9OiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIiwgXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYE9naWx0aWcgbnlja2VsIGkgJHtpc3N1ZS5vcmlnaW4gPz8gXCJ2XHUwMEU0cmRldFwifWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF91bmlvblwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIk9naWx0aWcgaW5wdXRcIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYE9naWx0aWd0IHZcdTAwRTRyZGUgaSAke2lzc3VlLm9yaWdpbiA/PyBcInZcdTAwRTRyZGV0XCJ9YDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBPZ2lsdGlnIGlucHV0YDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJcdTBCOEVcdTBCQjRcdTBCQzFcdTBCQTRcdTBCQ0RcdTBCQTRcdTBCQzFcdTBCOTVcdTBCQ0RcdTBCOTVcdTBCQjNcdTBCQ0RcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwQjk1XHUwQkNBXHUwQkEzXHUwQkNEXHUwQjlGXHUwQkJGXHUwQkIwXHUwQkMxXHUwQjk1XHUwQkNEXHUwQjk1IFx1MEJCNVx1MEJDN1x1MEJBM1x1MEJDRFx1MEI5Rlx1MEJDMVx1MEJBRVx1MEJDRFwiXG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHUwQkFBXHUwQkM4XHUwQjlGXHUwQkNEXHUwQjlGXHUwQkMxXHUwQjk1XHUwQkIzXHUwQkNEXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MEI5NVx1MEJDQVx1MEJBM1x1MEJDRFx1MEI5Rlx1MEJCRlx1MEJCMFx1MEJDMVx1MEI5NVx1MEJDRFx1MEI5NSBcdTBCQjVcdTBCQzdcdTBCQTNcdTBCQ0RcdTBCOUZcdTBCQzFcdTBCQUVcdTBCQ0RcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJcdTBCODlcdTBCQjFcdTBCQzFcdTBCQUFcdTBCQ0RcdTBCQUFcdTBCQzFcdTBCOTVcdTBCQjNcdTBCQ0RcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwQjk1XHUwQkNBXHUwQkEzXHUwQkNEXHUwQjlGXHUwQkJGXHUwQkIwXHUwQkMxXHUwQjk1XHUwQkNEXHUwQjk1IFx1MEJCNVx1MEJDN1x1MEJBM1x1MEJDRFx1MEI5Rlx1MEJDMVx1MEJBRVx1MEJDRFwiXG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDogXCJcdTBCODlcdTBCQjFcdTBCQzFcdTBCQUFcdTBCQ0RcdTBCQUFcdTBCQzFcdTBCOTVcdTBCQjNcdTBCQ0RcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwQjk1XHUwQkNBXHUwQkEzXHUwQkNEXHUwQjlGXHUwQkJGXHUwQkIwXHUwQkMxXHUwQjk1XHUwQkNEXHUwQjk1IFx1MEJCNVx1MEJDN1x1MEJBM1x1MEJDRFx1MEI5Rlx1MEJDMVx1MEJBRVx1MEJDRFwiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4pIHtcbiAgICAgICAgcmV0dXJuIFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWRUeXBlID0gKGRhdGEpPT57XG4gICAgICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICAgICAgc3dpdGNoKHQpe1xuICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiXHUwQjhFXHUwQkEzXHUwQkNEIFx1MEI4NVx1MEJCMlx1MEJDRFx1MEJCMlx1MEJCRVx1MEJBNFx1MEJBNFx1MEJDMVwiIDogXCJcdTBCOEVcdTBCQTNcdTBCQ0RcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiXHUwQjg1XHUwQkEzXHUwQkJGXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGEgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIlx1MEJCNVx1MEJDNlx1MEJCMVx1MEJDMVx1MEJBRVx1MEJDOFwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YoZGF0YSkgIT09IE9iamVjdC5wcm90b3R5cGUgJiYgZGF0YS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdDtcbiAgICB9O1xuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJcdTBCODlcdTBCQjNcdTBCQ0RcdTBCQjNcdTBCQzBcdTBCOUZcdTBCQzFcIixcbiAgICAgICAgZW1haWw6IFwiXHUwQkFFXHUwQkJGXHUwQkE5XHUwQkNEXHUwQkE5XHUwQjlFXHUwQkNEXHUwQjlBXHUwQkIyXHUwQkNEIFx1MEJBRVx1MEJDMVx1MEI5NVx1MEJCNVx1MEJCMFx1MEJCRlwiLFxuICAgICAgICB1cmw6IFwiVVJMXCIsXG4gICAgICAgIGVtb2ppOiBcImVtb2ppXCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcIklTTyBcdTBCQTRcdTBCQzdcdTBCQTRcdTBCQkYgXHUwQkE4XHUwQkM3XHUwQkIwXHUwQkFFXHUwQkNEXCIsXG4gICAgICAgIGRhdGU6IFwiSVNPIFx1MEJBNFx1MEJDN1x1MEJBNFx1MEJCRlwiLFxuICAgICAgICB0aW1lOiBcIklTTyBcdTBCQThcdTBCQzdcdTBCQjBcdTBCQUVcdTBCQ0RcIixcbiAgICAgICAgZHVyYXRpb246IFwiSVNPIFx1MEI5NVx1MEJCRVx1MEJCMiBcdTBCODVcdTBCQjNcdTBCQjVcdTBCQzFcIixcbiAgICAgICAgaXB2NDogXCJJUHY0IFx1MEJBRVx1MEJDMVx1MEI5NVx1MEJCNVx1MEJCMFx1MEJCRlwiLFxuICAgICAgICBpcHY2OiBcIklQdjYgXHUwQkFFXHUwQkMxXHUwQjk1XHUwQkI1XHUwQkIwXHUwQkJGXCIsXG4gICAgICAgIGNpZHJ2NDogXCJJUHY0IFx1MEJCNVx1MEJCMFx1MEJBRVx1MEJDRFx1MEJBQVx1MEJDMVwiLFxuICAgICAgICBjaWRydjY6IFwiSVB2NiBcdTBCQjVcdTBCQjBcdTBCQUVcdTBCQ0RcdTBCQUFcdTBCQzFcIixcbiAgICAgICAgYmFzZTY0OiBcImJhc2U2NC1lbmNvZGVkIFx1MEI5QVx1MEJCMFx1MEJBRVx1MEJDRFwiLFxuICAgICAgICBiYXNlNjR1cmw6IFwiYmFzZTY0dXJsLWVuY29kZWQgXHUwQjlBXHUwQkIwXHUwQkFFXHUwQkNEXCIsXG4gICAgICAgIGpzb25fc3RyaW5nOiBcIkpTT04gXHUwQjlBXHUwQkIwXHUwQkFFXHUwQkNEXCIsXG4gICAgICAgIGUxNjQ6IFwiRS4xNjQgXHUwQjhFXHUwQkEzXHUwQkNEXCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJpbnB1dFwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTBCQTRcdTBCQjVcdTBCQjFcdTBCQkVcdTBCQTkgXHUwQjg5XHUwQkIzXHUwQkNEXHUwQkIzXHUwQkMwXHUwQjlGXHUwQkMxOiBcdTBCOEVcdTBCQTRcdTBCQkZcdTBCQjBcdTBCQ0RcdTBCQUFcdTBCQkVcdTBCQjBcdTBCQ0RcdTBCOTVcdTBCQ0RcdTBCOTVcdTBCQUFcdTBCQ0RcdTBCQUFcdTBCOUZcdTBCQ0RcdTBCOUZcdTBCQTRcdTBCQzEgJHtpc3N1ZS5leHBlY3RlZH0sIFx1MEJBQVx1MEJDNlx1MEJCMVx1MEJBQVx1MEJDRFx1MEJBQVx1MEI5Rlx1MEJDRFx1MEI5Rlx1MEJBNFx1MEJDMSAke3BhcnNlZFR5cGUoaXNzdWUuaW5wdXQpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF92YWx1ZVwiOlxuICAgICAgICAgICAgICAgIGlmIChpc3N1ZS52YWx1ZXMubGVuZ3RoID09PSAxKSByZXR1cm4gYFx1MEJBNFx1MEJCNVx1MEJCMVx1MEJCRVx1MEJBOSBcdTBCODlcdTBCQjNcdTBCQ0RcdTBCQjNcdTBCQzBcdTBCOUZcdTBCQzE6IFx1MEI4RVx1MEJBNFx1MEJCRlx1MEJCMFx1MEJDRFx1MEJBQVx1MEJCRVx1MEJCMFx1MEJDRFx1MEI5NVx1MEJDRFx1MEI5NVx1MEJBQVx1MEJDRFx1MEJBQVx1MEI5Rlx1MEJDRFx1MEI5Rlx1MEJBNFx1MEJDMSAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MEJBNFx1MEJCNVx1MEJCMVx1MEJCRVx1MEJBOSBcdTBCQjVcdTBCQkZcdTBCQjBcdTBCQzFcdTBCQUFcdTBCQ0RcdTBCQUFcdTBCQUVcdTBCQ0Q6IFx1MEI4RVx1MEJBNFx1MEJCRlx1MEJCMFx1MEJDRFx1MEJBQVx1MEJCRVx1MEJCMFx1MEJDRFx1MEI5NVx1MEJDRFx1MEI5NVx1MEJBQVx1MEJDRFx1MEJBQVx1MEI5Rlx1MEJDRFx1MEI5Rlx1MEJBNFx1MEJDMSAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS52YWx1ZXMsIFwifFwiKX0gXHUwQjg3XHUwQkIyXHUwQkNEIFx1MEI5Mlx1MEJBOVx1MEJDRFx1MEJCMVx1MEJDMWA7XG4gICAgICAgICAgICBjYXNlIFwidG9vX2JpZ1wiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI8PVwiIDogXCI8XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MEJBRVx1MEJCRlx1MEI5NSBcdTBCQUFcdTBCQzZcdTBCQjBcdTBCQkZcdTBCQUZcdTBCQTRcdTBCQzE6IFx1MEI4RVx1MEJBNFx1MEJCRlx1MEJCMFx1MEJDRFx1MEJBQVx1MEJCRVx1MEJCMFx1MEJDRFx1MEI5NVx1MEJDRFx1MEI5NVx1MEJBQVx1MEJDRFx1MEJBQVx1MEI5Rlx1MEJDRFx1MEI5Rlx1MEJBNFx1MEJDMSAke2lzc3VlLm9yaWdpbiA/PyBcIlx1MEJBRVx1MEJBNFx1MEJCRlx1MEJBQVx1MEJDRFx1MEJBQVx1MEJDMVwifSAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdCA/PyBcIlx1MEI4OVx1MEJCMVx1MEJDMVx1MEJBQVx1MEJDRFx1MEJBQVx1MEJDMVx1MEI5NVx1MEJCM1x1MEJDRFwifSBcdTBCODZcdTBCOTUgXHUwQjg3XHUwQkIwXHUwQkMxXHUwQjk1XHUwQkNEXHUwQjk1IFx1MEJCNVx1MEJDN1x1MEJBM1x1MEJDRFx1MEI5Rlx1MEJDMVx1MEJBRVx1MEJDRGA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTBCQUVcdTBCQkZcdTBCOTUgXHUwQkFBXHUwQkM2XHUwQkIwXHUwQkJGXHUwQkFGXHUwQkE0XHUwQkMxOiBcdTBCOEVcdTBCQTRcdTBCQkZcdTBCQjBcdTBCQ0RcdTBCQUFcdTBCQkVcdTBCQjBcdTBCQ0RcdTBCOTVcdTBCQ0RcdTBCOTVcdTBCQUFcdTBCQ0RcdTBCQUFcdTBCOUZcdTBCQ0RcdTBCOUZcdTBCQTRcdTBCQzEgJHtpc3N1ZS5vcmlnaW4gPz8gXCJcdTBCQUVcdTBCQTRcdTBCQkZcdTBCQUFcdTBCQ0RcdTBCQUFcdTBCQzFcIn0gJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9IFx1MEI4Nlx1MEI5NSBcdTBCODdcdTBCQjBcdTBCQzFcdTBCOTVcdTBCQ0RcdTBCOTUgXHUwQkI1XHUwQkM3XHUwQkEzXHUwQkNEXHUwQjlGXHUwQkMxXHUwQkFFXHUwQkNEYDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIj49XCIgOiBcIj5cIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwQkFFXHUwQkJGXHUwQjk1XHUwQjlBXHUwQkNEIFx1MEI5QVx1MEJCRlx1MEJCMVx1MEJCRlx1MEJBRlx1MEJBNFx1MEJDMTogXHUwQjhFXHUwQkE0XHUwQkJGXHUwQkIwXHUwQkNEXHUwQkFBXHUwQkJFXHUwQkIwXHUwQkNEXHUwQjk1XHUwQkNEXHUwQjk1XHUwQkFBXHUwQkNEXHUwQkFBXHUwQjlGXHUwQkNEXHUwQjlGXHUwQkE0XHUwQkMxICR7aXNzdWUub3JpZ2lufSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdH0gXHUwQjg2XHUwQjk1IFx1MEI4N1x1MEJCMFx1MEJDMVx1MEI5NVx1MEJDRFx1MEI5NSBcdTBCQjVcdTBCQzdcdTBCQTNcdTBCQ0RcdTBCOUZcdTBCQzFcdTBCQUVcdTBCQ0RgOyAvL1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwQkFFXHUwQkJGXHUwQjk1XHUwQjlBXHUwQkNEIFx1MEI5QVx1MEJCRlx1MEJCMVx1MEJCRlx1MEJBRlx1MEJBNFx1MEJDMTogXHUwQjhFXHUwQkE0XHUwQkJGXHUwQkIwXHUwQkNEXHUwQkFBXHUwQkJFXHUwQkIwXHUwQkNEXHUwQjk1XHUwQkNEXHUwQjk1XHUwQkFBXHUwQkNEXHUwQkFBXHUwQjlGXHUwQkNEXHUwQjlGXHUwQkE0XHUwQkMxICR7aXNzdWUub3JpZ2lufSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gXHUwQjg2XHUwQjk1IFx1MEI4N1x1MEJCMFx1MEJDMVx1MEI5NVx1MEJDRFx1MEI5NSBcdTBCQjVcdTBCQzdcdTBCQTNcdTBCQ0RcdTBCOUZcdTBCQzFcdTBCQUVcdTBCQ0RgO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2Zvcm1hdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgX2lzc3VlID0gaXNzdWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInN0YXJ0c193aXRoXCIpIHJldHVybiBgXHUwQkE0XHUwQkI1XHUwQkIxXHUwQkJFXHUwQkE5IFx1MEI5QVx1MEJCMFx1MEJBRVx1MEJDRDogXCIke19pc3N1ZS5wcmVmaXh9XCIgXHUwQjg3XHUwQkIyXHUwQkNEIFx1MEJBNFx1MEJDQVx1MEI5Rlx1MEI5OVx1MEJDRFx1MEI5NSBcdTBCQjVcdTBCQzdcdTBCQTNcdTBCQ0RcdTBCOUZcdTBCQzFcdTBCQUVcdTBCQ0RgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJlbmRzX3dpdGhcIikgcmV0dXJuIGBcdTBCQTRcdTBCQjVcdTBCQjFcdTBCQkVcdTBCQTkgXHUwQjlBXHUwQkIwXHUwQkFFXHUwQkNEOiBcIiR7X2lzc3VlLnN1ZmZpeH1cIiBcdTBCODdcdTBCQjJcdTBCQ0QgXHUwQkFFXHUwQkMxXHUwQjlGXHUwQkJGXHUwQkI1XHUwQjlGXHUwQkM4XHUwQkFGIFx1MEJCNVx1MEJDN1x1MEJBM1x1MEJDRFx1MEI5Rlx1MEJDMVx1MEJBRVx1MEJDRGA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImluY2x1ZGVzXCIpIHJldHVybiBgXHUwQkE0XHUwQkI1XHUwQkIxXHUwQkJFXHUwQkE5IFx1MEI5QVx1MEJCMFx1MEJBRVx1MEJDRDogXCIke19pc3N1ZS5pbmNsdWRlc31cIiBcdTBCOTAgXHUwQjg5XHUwQkIzXHUwQkNEXHUwQkIzXHUwQjlGXHUwQjk1XHUwQkNEXHUwQjk1IFx1MEJCNVx1MEJDN1x1MEJBM1x1MEJDRFx1MEI5Rlx1MEJDMVx1MEJBRVx1MEJDRGA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInJlZ2V4XCIpIHJldHVybiBgXHUwQkE0XHUwQkI1XHUwQkIxXHUwQkJFXHUwQkE5IFx1MEI5QVx1MEJCMFx1MEJBRVx1MEJDRDogJHtfaXNzdWUucGF0dGVybn0gXHUwQkFFXHUwQkMxXHUwQkIxXHUwQkM4XHUwQkFBXHUwQkJFXHUwQjlGXHUwQkNEXHUwQjlGXHUwQkMxXHUwQjlGXHUwQkE5XHUwQkNEIFx1MEJBQVx1MEJDQVx1MEJCMFx1MEJDMVx1MEJBOFx1MEJDRFx1MEJBNCBcdTBCQjVcdTBCQzdcdTBCQTNcdTBCQ0RcdTBCOUZcdTBCQzFcdTBCQUVcdTBCQ0RgO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MEJBNFx1MEJCNVx1MEJCMVx1MEJCRVx1MEJBOSAke05vdW5zW19pc3N1ZS5mb3JtYXRdID8/IGlzc3VlLmZvcm1hdH1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJub3RfbXVsdGlwbGVfb2ZcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MEJBNFx1MEJCNVx1MEJCMVx1MEJCRVx1MEJBOSBcdTBCOEVcdTBCQTNcdTBCQ0Q6ICR7aXNzdWUuZGl2aXNvcn0gXHUwQjg3XHUwQkE5XHUwQkNEIFx1MEJBQVx1MEJCMlx1MEJBRVx1MEJCRVx1MEI5NSBcdTBCODdcdTBCQjBcdTBCQzFcdTBCOTVcdTBCQ0RcdTBCOTUgXHUwQkI1XHUwQkM3XHUwQkEzXHUwQkNEXHUwQjlGXHUwQkMxXHUwQkFFXHUwQkNEYDtcbiAgICAgICAgICAgIGNhc2UgXCJ1bnJlY29nbml6ZWRfa2V5c1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwQjg1XHUwQjlGXHUwQkM4XHUwQkFGXHUwQkJFXHUwQkIzXHUwQkFFXHUwQkNEIFx1MEJBNFx1MEJDNlx1MEJCMFx1MEJCRlx1MEJBRlx1MEJCRVx1MEJBNCBcdTBCQjVcdTBCQkZcdTBCOUFcdTBCQzgke2lzc3VlLmtleXMubGVuZ3RoID4gMSA/IFwiXHUwQjk1XHUwQkIzXHUwQkNEXCIgOiBcIlwifTogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgXCIsIFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfa2V5XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGAke2lzc3VlLm9yaWdpbn0gXHUwQjg3XHUwQkIyXHUwQkNEIFx1MEJBNFx1MEJCNVx1MEJCMVx1MEJCRVx1MEJBOSBcdTBCQjVcdTBCQkZcdTBCOUFcdTBCQzhgO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTBCQTRcdTBCQjVcdTBCQjFcdTBCQkVcdTBCQTkgXHUwQjg5XHUwQkIzXHUwQkNEXHUwQkIzXHUwQkMwXHUwQjlGXHUwQkMxXCI7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9lbGVtZW50XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGAke2lzc3VlLm9yaWdpbn0gXHUwQjg3XHUwQkIyXHUwQkNEIFx1MEJBNFx1MEJCNVx1MEJCMVx1MEJCRVx1MEJBOSBcdTBCQUVcdTBCQTRcdTBCQkZcdTBCQUFcdTBCQ0RcdTBCQUFcdTBCQzFgO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MEJBNFx1MEJCNVx1MEJCMVx1MEJCRVx1MEJBOSBcdTBCODlcdTBCQjNcdTBCQ0RcdTBCQjNcdTBCQzBcdTBCOUZcdTBCQzFgO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBsb2NhbGVFcnJvcjogZXJyb3IoKVxuICAgIH07XG59XG4iLCAiaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi4vY29yZS91dGlsLmpzXCI7XG5jb25zdCBlcnJvciA9ICgpPT57XG4gICAgY29uc3QgU2l6YWJsZSA9IHtcbiAgICAgICAgc3RyaW5nOiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MEUxNVx1MEUzMVx1MEUyN1x1MEUyRFx1MEUzMVx1MEUwMVx1MEUyOVx1MEUyM1wiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTBFMDRcdTBFMjdcdTBFMjNcdTBFMjFcdTBFMzVcIlxuICAgICAgICB9LFxuICAgICAgICBmaWxlOiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MEU0NFx1MEUxQVx1MEUxNVx1MEU0Q1wiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTBFMDRcdTBFMjdcdTBFMjNcdTBFMjFcdTBFMzVcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJcdTBFMjNcdTBFMzJcdTBFMjJcdTBFMDFcdTBFMzJcdTBFMjNcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwRTA0XHUwRTI3XHUwRTIzXHUwRTIxXHUwRTM1XCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MEUyM1x1MEUzMlx1MEUyMlx1MEUwMVx1MEUzMlx1MEUyM1wiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTBFMDRcdTBFMjdcdTBFMjNcdTBFMjFcdTBFMzVcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIlx1MEU0NFx1MEUyMVx1MEU0OFx1MEU0M1x1MEUwQVx1MEU0OFx1MEUxNVx1MEUzMVx1MEUyN1x1MEU0MFx1MEUyNVx1MEUwMiAoTmFOKVwiIDogXCJcdTBFMTVcdTBFMzFcdTBFMjdcdTBFNDBcdTBFMjVcdTBFMDJcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiXHUwRTJEXHUwRTMyXHUwRTIzXHUwRTRDXHUwRTQwXHUwRTIzXHUwRTIyXHUwRTRDIChBcnJheSlcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiXHUwRTQ0XHUwRTIxXHUwRTQ4XHUwRTIxXHUwRTM1XHUwRTA0XHUwRTQ4XHUwRTMyIChudWxsKVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YoZGF0YSkgIT09IE9iamVjdC5wcm90b3R5cGUgJiYgZGF0YS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdDtcbiAgICB9O1xuICAgIGNvbnN0IE5vdW5zID0ge1xuICAgICAgICByZWdleDogXCJcdTBFMDJcdTBFNDlcdTBFMkRcdTBFMjFcdTBFMzlcdTBFMjVcdTBFMTdcdTBFMzVcdTBFNDhcdTBFMUJcdTBFNDlcdTBFMkRcdTBFMTlcIixcbiAgICAgICAgZW1haWw6IFwiXHUwRTE3XHUwRTM1XHUwRTQ4XHUwRTJEXHUwRTIyXHUwRTM5XHUwRTQ4XHUwRTJEXHUwRTM1XHUwRTQwXHUwRTIxXHUwRTI1XCIsXG4gICAgICAgIHVybDogXCJVUkxcIixcbiAgICAgICAgZW1vamk6IFwiXHUwRTJEXHUwRTM0XHUwRTQyXHUwRTIxXHUwRTA4XHUwRTM0XCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcIlx1MEUyN1x1MEUzMVx1MEUxOVx1MEUxN1x1MEUzNVx1MEU0OFx1MEU0MFx1MEUyN1x1MEUyNVx1MEUzMlx1MEU0MVx1MEUxQVx1MEUxQSBJU09cIixcbiAgICAgICAgZGF0ZTogXCJcdTBFMjdcdTBFMzFcdTBFMTlcdTBFMTdcdTBFMzVcdTBFNDhcdTBFNDFcdTBFMUFcdTBFMUEgSVNPXCIsXG4gICAgICAgIHRpbWU6IFwiXHUwRTQwXHUwRTI3XHUwRTI1XHUwRTMyXHUwRTQxXHUwRTFBXHUwRTFBIElTT1wiLFxuICAgICAgICBkdXJhdGlvbjogXCJcdTBFMEFcdTBFNDhcdTBFMjdcdTBFMDdcdTBFNDBcdTBFMjdcdTBFMjVcdTBFMzJcdTBFNDFcdTBFMUFcdTBFMUEgSVNPXCIsXG4gICAgICAgIGlwdjQ6IFwiXHUwRTE3XHUwRTM1XHUwRTQ4XHUwRTJEXHUwRTIyXHUwRTM5XHUwRTQ4IElQdjRcIixcbiAgICAgICAgaXB2NjogXCJcdTBFMTdcdTBFMzVcdTBFNDhcdTBFMkRcdTBFMjJcdTBFMzlcdTBFNDggSVB2NlwiLFxuICAgICAgICBjaWRydjQ6IFwiXHUwRTBBXHUwRTQ4XHUwRTI3XHUwRTA3IElQIFx1MEU0MVx1MEUxQVx1MEUxQSBJUHY0XCIsXG4gICAgICAgIGNpZHJ2NjogXCJcdTBFMEFcdTBFNDhcdTBFMjdcdTBFMDcgSVAgXHUwRTQxXHUwRTFBXHUwRTFBIElQdjZcIixcbiAgICAgICAgYmFzZTY0OiBcIlx1MEUwMlx1MEU0OVx1MEUyRFx1MEUwNFx1MEUyN1x1MEUzMlx1MEUyMVx1MEU0MVx1MEUxQVx1MEUxQSBCYXNlNjRcIixcbiAgICAgICAgYmFzZTY0dXJsOiBcIlx1MEUwMlx1MEU0OVx1MEUyRFx1MEUwNFx1MEUyN1x1MEUzMlx1MEUyMVx1MEU0MVx1MEUxQVx1MEUxQSBCYXNlNjQgXHUwRTJBXHUwRTMzXHUwRTJCXHUwRTIzXHUwRTMxXHUwRTFBIFVSTFwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJcdTBFMDJcdTBFNDlcdTBFMkRcdTBFMDRcdTBFMjdcdTBFMzJcdTBFMjFcdTBFNDFcdTBFMUFcdTBFMUEgSlNPTlwiLFxuICAgICAgICBlMTY0OiBcIlx1MEU0MFx1MEUxQVx1MEUyRFx1MEUyM1x1MEU0Q1x1MEU0Mlx1MEUxN1x1MEUyM1x1MEUyOFx1MEUzMVx1MEUxRVx1MEUxN1x1MEU0Q1x1MEUyM1x1MEUzMFx1MEUyQlx1MEUyN1x1MEU0OFx1MEUzMlx1MEUwN1x1MEUxQlx1MEUyM1x1MEUzMFx1MEU0MFx1MEUxN1x1MEUyOCAoRS4xNjQpXCIsXG4gICAgICAgIGp3dDogXCJcdTBFNDJcdTBFMTdcdTBFNDBcdTBFMDRcdTBFMTkgSldUXCIsXG4gICAgICAgIHRlbXBsYXRlX2xpdGVyYWw6IFwiXHUwRTAyXHUwRTQ5XHUwRTJEXHUwRTIxXHUwRTM5XHUwRTI1XHUwRTE3XHUwRTM1XHUwRTQ4XHUwRTFCXHUwRTQ5XHUwRTJEXHUwRTE5XCJcbiAgICB9O1xuICAgIHJldHVybiAoaXNzdWUpPT57XG4gICAgICAgIHN3aXRjaChpc3N1ZS5jb2RlKXtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3R5cGVcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MEUxQlx1MEUyM1x1MEUzMFx1MEU0MFx1MEUyMFx1MEUxN1x1MEUwMlx1MEU0OVx1MEUyRFx1MEUyMVx1MEUzOVx1MEUyNVx1MEU0NFx1MEUyMVx1MEU0OFx1MEUxNlx1MEUzOVx1MEUwMVx1MEUxNVx1MEU0OVx1MEUyRFx1MEUwNzogXHUwRTA0XHUwRTI3XHUwRTIzXHUwRTQwXHUwRTFCXHUwRTQ3XHUwRTE5ICR7aXNzdWUuZXhwZWN0ZWR9IFx1MEU0MVx1MEUxNVx1MEU0OFx1MEU0NFx1MEUxNFx1MEU0OVx1MEUyM1x1MEUzMVx1MEUxQSAke3BhcnNlZFR5cGUoaXNzdWUuaW5wdXQpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF92YWx1ZVwiOlxuICAgICAgICAgICAgICAgIGlmIChpc3N1ZS52YWx1ZXMubGVuZ3RoID09PSAxKSByZXR1cm4gYFx1MEUwNFx1MEU0OFx1MEUzMlx1MEU0NFx1MEUyMVx1MEU0OFx1MEUxNlx1MEUzOVx1MEUwMVx1MEUxNVx1MEU0OVx1MEUyRFx1MEUwNzogXHUwRTA0XHUwRTI3XHUwRTIzXHUwRTQwXHUwRTFCXHUwRTQ3XHUwRTE5ICR7dXRpbC5zdHJpbmdpZnlQcmltaXRpdmUoaXNzdWUudmFsdWVzWzBdKX1gO1xuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwRTE1XHUwRTMxXHUwRTI3XHUwRTQwXHUwRTI1XHUwRTM3XHUwRTJEXHUwRTAxXHUwRTQ0XHUwRTIxXHUwRTQ4XHUwRTE2XHUwRTM5XHUwRTAxXHUwRTE1XHUwRTQ5XHUwRTJEXHUwRTA3OiBcdTBFMDRcdTBFMjdcdTBFMjNcdTBFNDBcdTBFMUJcdTBFNDdcdTBFMTlcdTBFMkJcdTBFMTlcdTBFMzZcdTBFNDhcdTBFMDdcdTBFNDNcdTBFMTkgJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIlx1MEU0NFx1MEUyMVx1MEU0OFx1MEU0MFx1MEUwMVx1MEUzNFx1MEUxOVwiIDogXCJcdTBFMTlcdTBFNDlcdTBFMkRcdTBFMjJcdTBFMDFcdTBFMjdcdTBFNDhcdTBFMzJcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgXHUwRTQwXHUwRTAxXHUwRTM0XHUwRTE5XHUwRTAxXHUwRTMzXHUwRTJCXHUwRTE5XHUwRTE0OiAke2lzc3VlLm9yaWdpbiA/PyBcIlx1MEUwNFx1MEU0OFx1MEUzMlwifSBcdTBFMDRcdTBFMjdcdTBFMjNcdTBFMjFcdTBFMzUke2Fkan0gJHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXQgPz8gXCJcdTBFMjNcdTBFMzJcdTBFMjJcdTBFMDFcdTBFMzJcdTBFMjNcIn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MEU0MFx1MEUwMVx1MEUzNFx1MEUxOVx1MEUwMVx1MEUzM1x1MEUyQlx1MEUxOVx1MEUxNDogJHtpc3N1ZS5vcmlnaW4gPz8gXCJcdTBFMDRcdTBFNDhcdTBFMzJcIn0gXHUwRTA0XHUwRTI3XHUwRTIzXHUwRTIxXHUwRTM1JHthZGp9ICR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInRvb19zbWFsbFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCJcdTBFMkRcdTBFMjJcdTBFNDhcdTBFMzJcdTBFMDdcdTBFMTlcdTBFNDlcdTBFMkRcdTBFMjJcIiA6IFwiXHUwRTIxXHUwRTMyXHUwRTAxXHUwRTAxXHUwRTI3XHUwRTQ4XHUwRTMyXCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MEUxOVx1MEU0OVx1MEUyRFx1MEUyMlx1MEUwMVx1MEUyN1x1MEU0OFx1MEUzMlx1MEUwMVx1MEUzM1x1MEUyQlx1MEUxOVx1MEUxNDogJHtpc3N1ZS5vcmlnaW59IFx1MEUwNFx1MEUyN1x1MEUyM1x1MEUyMVx1MEUzNSR7YWRqfSAke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdH1gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwRTE5XHUwRTQ5XHUwRTJEXHUwRTIyXHUwRTAxXHUwRTI3XHUwRTQ4XHUwRTMyXHUwRTAxXHUwRTMzXHUwRTJCXHUwRTE5XHUwRTE0OiAke2lzc3VlLm9yaWdpbn0gXHUwRTA0XHUwRTI3XHUwRTIzXHUwRTIxXHUwRTM1JHthZGp9ICR7aXNzdWUubWluaW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZm9ybWF0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBfaXNzdWUgPSBpc3N1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwic3RhcnRzX3dpdGhcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTBFMjNcdTBFMzlcdTBFMUJcdTBFNDFcdTBFMUFcdTBFMUFcdTBFNDRcdTBFMjFcdTBFNDhcdTBFMTZcdTBFMzlcdTBFMDFcdTBFMTVcdTBFNDlcdTBFMkRcdTBFMDc6IFx1MEUwMlx1MEU0OVx1MEUyRFx1MEUwNFx1MEUyN1x1MEUzMlx1MEUyMVx1MEUxNVx1MEU0OVx1MEUyRFx1MEUwN1x1MEUwMlx1MEUzNlx1MEU0OVx1MEUxOVx1MEUxNVx1MEU0OVx1MEUxOVx1MEUxNFx1MEU0OVx1MEUyN1x1MEUyMiBcIiR7X2lzc3VlLnByZWZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiZW5kc193aXRoXCIpIHJldHVybiBgXHUwRTIzXHUwRTM5XHUwRTFCXHUwRTQxXHUwRTFBXHUwRTFBXHUwRTQ0XHUwRTIxXHUwRTQ4XHUwRTE2XHUwRTM5XHUwRTAxXHUwRTE1XHUwRTQ5XHUwRTJEXHUwRTA3OiBcdTBFMDJcdTBFNDlcdTBFMkRcdTBFMDRcdTBFMjdcdTBFMzJcdTBFMjFcdTBFMTVcdTBFNDlcdTBFMkRcdTBFMDdcdTBFMjVcdTBFMDdcdTBFMTdcdTBFNDlcdTBFMzJcdTBFMjJcdTBFMTRcdTBFNDlcdTBFMjdcdTBFMjIgXCIke19pc3N1ZS5zdWZmaXh9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJpbmNsdWRlc1wiKSByZXR1cm4gYFx1MEUyM1x1MEUzOVx1MEUxQlx1MEU0MVx1MEUxQVx1MEUxQVx1MEU0NFx1MEUyMVx1MEU0OFx1MEUxNlx1MEUzOVx1MEUwMVx1MEUxNVx1MEU0OVx1MEUyRFx1MEUwNzogXHUwRTAyXHUwRTQ5XHUwRTJEXHUwRTA0XHUwRTI3XHUwRTMyXHUwRTIxXHUwRTE1XHUwRTQ5XHUwRTJEXHUwRTA3XHUwRTIxXHUwRTM1IFwiJHtfaXNzdWUuaW5jbHVkZXN9XCIgXHUwRTJEXHUwRTIyXHUwRTM5XHUwRTQ4XHUwRTQzXHUwRTE5XHUwRTAyXHUwRTQ5XHUwRTJEXHUwRTA0XHUwRTI3XHUwRTMyXHUwRTIxYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBcdTBFMjNcdTBFMzlcdTBFMUJcdTBFNDFcdTBFMUFcdTBFMUFcdTBFNDRcdTBFMjFcdTBFNDhcdTBFMTZcdTBFMzlcdTBFMDFcdTBFMTVcdTBFNDlcdTBFMkRcdTBFMDc6IFx1MEUxNVx1MEU0OVx1MEUyRFx1MEUwN1x1MEUxNVx1MEUyM1x1MEUwN1x1MEUwMVx1MEUzMVx1MEUxQVx1MEUyM1x1MEUzOVx1MEUxQlx1MEU0MVx1MEUxQVx1MEUxQVx1MEUxN1x1MEUzNVx1MEU0OFx1MEUwMVx1MEUzM1x1MEUyQlx1MEUxOVx1MEUxNCAke19pc3N1ZS5wYXR0ZXJufWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwRTIzXHUwRTM5XHUwRTFCXHUwRTQxXHUwRTFBXHUwRTFBXHUwRTQ0XHUwRTIxXHUwRTQ4XHUwRTE2XHUwRTM5XHUwRTAxXHUwRTE1XHUwRTQ5XHUwRTJEXHUwRTA3OiAke05vdW5zW19pc3N1ZS5mb3JtYXRdID8/IGlzc3VlLmZvcm1hdH1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJub3RfbXVsdGlwbGVfb2ZcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MEUxNVx1MEUzMVx1MEUyN1x1MEU0MFx1MEUyNVx1MEUwMlx1MEU0NFx1MEUyMVx1MEU0OFx1MEUxNlx1MEUzOVx1MEUwMVx1MEUxNVx1MEU0OVx1MEUyRFx1MEUwNzogXHUwRTE1XHUwRTQ5XHUwRTJEXHUwRTA3XHUwRTQwXHUwRTFCXHUwRTQ3XHUwRTE5XHUwRTA4XHUwRTMzXHUwRTE5XHUwRTI3XHUwRTE5XHUwRTE3XHUwRTM1XHUwRTQ4XHUwRTJCXHUwRTMyXHUwRTIzXHUwRTE0XHUwRTQ5XHUwRTI3XHUwRTIyICR7aXNzdWUuZGl2aXNvcn0gXHUwRTQ0XHUwRTE0XHUwRTQ5XHUwRTI1XHUwRTA3XHUwRTE1XHUwRTMxXHUwRTI3YDtcbiAgICAgICAgICAgIGNhc2UgXCJ1bnJlY29nbml6ZWRfa2V5c1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwRTFFXHUwRTFBXHUwRTA0XHUwRTM1XHUwRTIyXHUwRTRDXHUwRTE3XHUwRTM1XHUwRTQ4XHUwRTQ0XHUwRTIxXHUwRTQ4XHUwRTIzXHUwRTM5XHUwRTQ5XHUwRTA4XHUwRTMxXHUwRTAxOiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIiwgXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MEUwNFx1MEUzNVx1MEUyMlx1MEU0Q1x1MEU0NFx1MEUyMVx1MEU0OFx1MEUxNlx1MEUzOVx1MEUwMVx1MEUxNVx1MEU0OVx1MEUyRFx1MEUwN1x1MEU0M1x1MEUxOSAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTBFMDJcdTBFNDlcdTBFMkRcdTBFMjFcdTBFMzlcdTBFMjVcdTBFNDRcdTBFMjFcdTBFNDhcdTBFMTZcdTBFMzlcdTBFMDFcdTBFMTVcdTBFNDlcdTBFMkRcdTBFMDc6IFx1MEU0NFx1MEUyMVx1MEU0OFx1MEUxNVx1MEUyM1x1MEUwN1x1MEUwMVx1MEUzMVx1MEUxQVx1MEUyM1x1MEUzOVx1MEUxQlx1MEU0MVx1MEUxQVx1MEUxQVx1MEUyMlx1MEUzOVx1MEU0MFx1MEUxOVx1MEUzNVx1MEUyMlx1MEUxOVx1MEUxN1x1MEUzNVx1MEU0OFx1MEUwMVx1MEUzM1x1MEUyQlx1MEUxOVx1MEUxNFx1MEU0NFx1MEUyN1x1MEU0OVwiO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZWxlbWVudFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwRTAyXHUwRTQ5XHUwRTJEXHUwRTIxXHUwRTM5XHUwRTI1XHUwRTQ0XHUwRTIxXHUwRTQ4XHUwRTE2XHUwRTM5XHUwRTAxXHUwRTE1XHUwRTQ5XHUwRTJEXHUwRTA3XHUwRTQzXHUwRTE5ICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwRTAyXHUwRTQ5XHUwRTJEXHUwRTIxXHUwRTM5XHUwRTI1XHUwRTQ0XHUwRTIxXHUwRTQ4XHUwRTE2XHUwRTM5XHUwRTAxXHUwRTE1XHUwRTQ5XHUwRTJEXHUwRTA3YDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuZXhwb3J0IGNvbnN0IHBhcnNlZFR5cGUgPSAoZGF0YSk9PntcbiAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgc3dpdGNoKHQpe1xuICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIm51bWJlclwiO1xuICAgICAgICAgICAgfVxuICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiYXJyYXlcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGRhdGEgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKGRhdGEpICE9PSBPYmplY3QucHJvdG90eXBlICYmIGRhdGEuY29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0O1xufTtcbmNvbnN0IGVycm9yID0gKCk9PntcbiAgICBjb25zdCBTaXphYmxlID0ge1xuICAgICAgICBzdHJpbmc6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwia2FyYWt0ZXJcIixcbiAgICAgICAgICAgIHZlcmI6IFwib2xtYWxcdTAxMzFcIlxuICAgICAgICB9LFxuICAgICAgICBmaWxlOiB7XG4gICAgICAgICAgICB1bml0OiBcImJheXRcIixcbiAgICAgICAgICAgIHZlcmI6IFwib2xtYWxcdTAxMzFcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJcdTAwRjZcdTAxMUZlXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIm9sbWFsXHUwMTMxXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MDBGNlx1MDExRmVcIixcbiAgICAgICAgICAgIHZlcmI6IFwib2xtYWxcdTAxMzFcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcImdpcmRpXCIsXG4gICAgICAgIGVtYWlsOiBcImUtcG9zdGEgYWRyZXNpXCIsXG4gICAgICAgIHVybDogXCJVUkxcIixcbiAgICAgICAgZW1vamk6IFwiZW1vamlcIixcbiAgICAgICAgdXVpZDogXCJVVUlEXCIsXG4gICAgICAgIHV1aWR2NDogXCJVVUlEdjRcIixcbiAgICAgICAgdXVpZHY2OiBcIlVVSUR2NlwiLFxuICAgICAgICBuYW5vaWQ6IFwibmFub2lkXCIsXG4gICAgICAgIGd1aWQ6IFwiR1VJRFwiLFxuICAgICAgICBjdWlkOiBcImN1aWRcIixcbiAgICAgICAgY3VpZDI6IFwiY3VpZDJcIixcbiAgICAgICAgdWxpZDogXCJVTElEXCIsXG4gICAgICAgIHhpZDogXCJYSURcIixcbiAgICAgICAga3N1aWQ6IFwiS1NVSURcIixcbiAgICAgICAgZGF0ZXRpbWU6IFwiSVNPIHRhcmloIHZlIHNhYXRcIixcbiAgICAgICAgZGF0ZTogXCJJU08gdGFyaWhcIixcbiAgICAgICAgdGltZTogXCJJU08gc2FhdFwiLFxuICAgICAgICBkdXJhdGlvbjogXCJJU08gc1x1MDBGQ3JlXCIsXG4gICAgICAgIGlwdjQ6IFwiSVB2NCBhZHJlc2lcIixcbiAgICAgICAgaXB2NjogXCJJUHY2IGFkcmVzaVwiLFxuICAgICAgICBjaWRydjQ6IFwiSVB2NCBhcmFsXHUwMTMxXHUwMTFGXHUwMTMxXCIsXG4gICAgICAgIGNpZHJ2NjogXCJJUHY2IGFyYWxcdTAxMzFcdTAxMUZcdTAxMzFcIixcbiAgICAgICAgYmFzZTY0OiBcImJhc2U2NCBpbGUgXHUwMTVGaWZyZWxlbm1pXHUwMTVGIG1ldGluXCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJiYXNlNjR1cmwgaWxlIFx1MDE1RmlmcmVsZW5taVx1MDE1RiBtZXRpblwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJKU09OIGRpemVzaVwiLFxuICAgICAgICBlMTY0OiBcIkUuMTY0IHNheVx1MDEzMXNcdTAxMzFcIixcbiAgICAgICAgand0OiBcIkpXVFwiLFxuICAgICAgICB0ZW1wbGF0ZV9saXRlcmFsOiBcIlx1MDE1RWFibG9uIGRpemVzaVwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBHZVx1MDBFN2Vyc2l6IGRlXHUwMTFGZXI6IGJla2xlbmVuICR7aXNzdWUuZXhwZWN0ZWR9LCBhbFx1MDEzMW5hbiAke3BhcnNlZFR5cGUoaXNzdWUuaW5wdXQpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF92YWx1ZVwiOlxuICAgICAgICAgICAgICAgIGlmIChpc3N1ZS52YWx1ZXMubGVuZ3RoID09PSAxKSByZXR1cm4gYEdlXHUwMEU3ZXJzaXogZGVcdTAxMUZlcjogYmVrbGVuZW4gJHt1dGlsLnN0cmluZ2lmeVByaW1pdGl2ZShpc3N1ZS52YWx1ZXNbMF0pfWA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBHZVx1MDBFN2Vyc2l6IHNlXHUwMEU3ZW5lazogYVx1MDE1RmFcdTAxMUZcdTAxMzFkYWtpbGVyZGVuIGJpcmkgb2xtYWxcdTAxMzE6ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLnZhbHVlcywgXCJ8XCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwidG9vX2JpZ1wiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI8PVwiIDogXCI8XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSByZXR1cm4gYFx1MDBDN29rIGJcdTAwRkN5XHUwMEZDazogYmVrbGVuZW4gJHtpc3N1ZS5vcmlnaW4gPz8gXCJkZVx1MDExRmVyXCJ9ICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0ID8/IFwiXHUwMEY2XHUwMTFGZVwifWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwMEM3b2sgYlx1MDBGQ3lcdTAwRkNrOiBiZWtsZW5lbiAke2lzc3VlLm9yaWdpbiA/PyBcImRlXHUwMTFGZXJcIn0gJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIj49XCIgOiBcIj5cIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgXHUwMEM3b2sga1x1MDBGQ1x1MDBFN1x1MDBGQ2s6IGJla2xlbmVuICR7aXNzdWUub3JpZ2lufSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdH1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDBDN29rIGtcdTAwRkNcdTAwRTdcdTAwRkNrOiBiZWtsZW5lbiAke2lzc3VlLm9yaWdpbn0gJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSByZXR1cm4gYEdlXHUwMEU3ZXJzaXogbWV0aW46IFwiJHtfaXNzdWUucHJlZml4fVwiIGlsZSBiYVx1MDE1RmxhbWFsXHUwMTMxYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiZW5kc193aXRoXCIpIHJldHVybiBgR2VcdTAwRTdlcnNpeiBtZXRpbjogXCIke19pc3N1ZS5zdWZmaXh9XCIgaWxlIGJpdG1lbGlgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJpbmNsdWRlc1wiKSByZXR1cm4gYEdlXHUwMEU3ZXJzaXogbWV0aW46IFwiJHtfaXNzdWUuaW5jbHVkZXN9XCIgaVx1MDBFN2VybWVsaWA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInJlZ2V4XCIpIHJldHVybiBgR2VcdTAwRTdlcnNpeiBtZXRpbjogJHtfaXNzdWUucGF0dGVybn0gZGVzZW5pbmUgdXltYWxcdTAxMzFgO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYEdlXHUwMEU3ZXJzaXogJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBHZVx1MDBFN2Vyc2l6IHNheVx1MDEzMTogJHtpc3N1ZS5kaXZpc29yfSBpbGUgdGFtIGJcdTAwRjZsXHUwMEZDbmViaWxtZWxpYDtcbiAgICAgICAgICAgIGNhc2UgXCJ1bnJlY29nbml6ZWRfa2V5c1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgVGFuXHUwMTMxbm1heWFuIGFuYWh0YXIke2lzc3VlLmtleXMubGVuZ3RoID4gMSA/IFwibGFyXCIgOiBcIlwifTogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgXCIsIFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfa2V5XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGAke2lzc3VlLm9yaWdpbn0gaVx1MDBFN2luZGUgZ2VcdTAwRTdlcnNpeiBhbmFodGFyYDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3VuaW9uXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiR2VcdTAwRTdlcnNpeiBkZVx1MDExRmVyXCI7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9lbGVtZW50XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGAke2lzc3VlLm9yaWdpbn0gaVx1MDBFN2luZGUgZ2VcdTAwRTdlcnNpeiBkZVx1MDExRmVyYDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBHZVx1MDBFN2Vyc2l6IGRlXHUwMTFGZXJgO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBsb2NhbGVFcnJvcjogZXJyb3IoKVxuICAgIH07XG59XG4iLCAiaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi4vY29yZS91dGlsLmpzXCI7XG5jb25zdCBlcnJvciA9ICgpPT57XG4gICAgY29uc3QgU2l6YWJsZSA9IHtcbiAgICAgICAgc3RyaW5nOiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MDQ0MVx1MDQzOFx1MDQzQ1x1MDQzMlx1MDQzRVx1MDQzQlx1MDQ1Nlx1MDQzMlwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTA0M0NcdTA0MzBcdTA0NDJcdTA0MzhcdTA0M0NcdTA0MzVcIlxuICAgICAgICB9LFxuICAgICAgICBmaWxlOiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MDQzMVx1MDQzMFx1MDQzOVx1MDQ0Mlx1MDQ1Nlx1MDQzMlwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTA0M0NcdTA0MzBcdTA0NDJcdTA0MzhcdTA0M0NcdTA0MzVcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJcdTA0MzVcdTA0M0JcdTA0MzVcdTA0M0NcdTA0MzVcdTA0M0RcdTA0NDJcdTA0NTZcdTA0MzJcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHUwNDNDXHUwNDMwXHUwNDQyXHUwNDM4XHUwNDNDXHUwNDM1XCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MDQzNVx1MDQzQlx1MDQzNVx1MDQzQ1x1MDQzNVx1MDQzRFx1MDQ0Mlx1MDQ1Nlx1MDQzMlwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTA0M0NcdTA0MzBcdTA0NDJcdTA0MzhcdTA0M0NcdTA0MzVcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIk5hTlwiIDogXCJcdTA0NDdcdTA0MzhcdTA0NDFcdTA0M0JcdTA0M0VcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiXHUwNDNDXHUwNDMwXHUwNDQxXHUwNDM4XHUwNDMyXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGEgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm51bGxcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKGRhdGEpICE9PSBPYmplY3QucHJvdG90eXBlICYmIGRhdGEuY29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHQ7XG4gICAgfTtcbiAgICBjb25zdCBOb3VucyA9IHtcbiAgICAgICAgcmVnZXg6IFwiXHUwNDMyXHUwNDQ1XHUwNDU2XHUwNDM0XHUwNDNEXHUwNDU2IFx1MDQzNFx1MDQzMFx1MDQzRFx1MDQ1NlwiLFxuICAgICAgICBlbWFpbDogXCJcdTA0MzBcdTA0MzRcdTA0NDBcdTA0MzVcdTA0NDFcdTA0MzAgXHUwNDM1XHUwNDNCXHUwNDM1XHUwNDNBXHUwNDQyXHUwNDQwXHUwNDNFXHUwNDNEXHUwNDNEXHUwNDNFXHUwNDU3IFx1MDQzRlx1MDQzRVx1MDQ0OFx1MDQ0Mlx1MDQzOFwiLFxuICAgICAgICB1cmw6IFwiVVJMXCIsXG4gICAgICAgIGVtb2ppOiBcIlx1MDQzNVx1MDQzQ1x1MDQzRVx1MDQzNFx1MDQzN1x1MDQ1NlwiLFxuICAgICAgICB1dWlkOiBcIlVVSURcIixcbiAgICAgICAgdXVpZHY0OiBcIlVVSUR2NFwiLFxuICAgICAgICB1dWlkdjY6IFwiVVVJRHY2XCIsXG4gICAgICAgIG5hbm9pZDogXCJuYW5vaWRcIixcbiAgICAgICAgZ3VpZDogXCJHVUlEXCIsXG4gICAgICAgIGN1aWQ6IFwiY3VpZFwiLFxuICAgICAgICBjdWlkMjogXCJjdWlkMlwiLFxuICAgICAgICB1bGlkOiBcIlVMSURcIixcbiAgICAgICAgeGlkOiBcIlhJRFwiLFxuICAgICAgICBrc3VpZDogXCJLU1VJRFwiLFxuICAgICAgICBkYXRldGltZTogXCJcdTA0MzRcdTA0MzBcdTA0NDJcdTA0MzAgXHUwNDQyXHUwNDMwIFx1MDQ0N1x1MDQzMFx1MDQ0MSBJU09cIixcbiAgICAgICAgZGF0ZTogXCJcdTA0MzRcdTA0MzBcdTA0NDJcdTA0MzAgSVNPXCIsXG4gICAgICAgIHRpbWU6IFwiXHUwNDQ3XHUwNDMwXHUwNDQxIElTT1wiLFxuICAgICAgICBkdXJhdGlvbjogXCJcdTA0NDJcdTA0NDBcdTA0MzhcdTA0MzJcdTA0MzBcdTA0M0JcdTA0NTZcdTA0NDFcdTA0NDJcdTA0NEMgSVNPXCIsXG4gICAgICAgIGlwdjQ6IFwiXHUwNDMwXHUwNDM0XHUwNDQwXHUwNDM1XHUwNDQxXHUwNDMwIElQdjRcIixcbiAgICAgICAgaXB2NjogXCJcdTA0MzBcdTA0MzRcdTA0NDBcdTA0MzVcdTA0NDFcdTA0MzAgSVB2NlwiLFxuICAgICAgICBjaWRydjQ6IFwiXHUwNDM0XHUwNDU2XHUwNDMwXHUwNDNGXHUwNDMwXHUwNDM3XHUwNDNFXHUwNDNEIElQdjRcIixcbiAgICAgICAgY2lkcnY2OiBcIlx1MDQzNFx1MDQ1Nlx1MDQzMFx1MDQzRlx1MDQzMFx1MDQzN1x1MDQzRVx1MDQzRCBJUHY2XCIsXG4gICAgICAgIGJhc2U2NDogXCJcdTA0NDBcdTA0NEZcdTA0MzRcdTA0M0VcdTA0M0EgXHUwNDQzIFx1MDQzQVx1MDQzRVx1MDQzNFx1MDQ0M1x1MDQzMlx1MDQzMFx1MDQzRFx1MDQzRFx1MDQ1NiBiYXNlNjRcIixcbiAgICAgICAgYmFzZTY0dXJsOiBcIlx1MDQ0MFx1MDQ0Rlx1MDQzNFx1MDQzRVx1MDQzQSBcdTA0NDMgXHUwNDNBXHUwNDNFXHUwNDM0XHUwNDQzXHUwNDMyXHUwNDMwXHUwNDNEXHUwNDNEXHUwNDU2IGJhc2U2NHVybFwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJcdTA0NDBcdTA0NEZcdTA0MzRcdTA0M0VcdTA0M0EgSlNPTlwiLFxuICAgICAgICBlMTY0OiBcIlx1MDQzRFx1MDQzRVx1MDQzQ1x1MDQzNVx1MDQ0MCBFLjE2NFwiLFxuICAgICAgICBqd3Q6IFwiSldUXCIsXG4gICAgICAgIHRlbXBsYXRlX2xpdGVyYWw6IFwiXHUwNDMyXHUwNDQ1XHUwNDU2XHUwNDM0XHUwNDNEXHUwNDU2IFx1MDQzNFx1MDQzMFx1MDQzRFx1MDQ1NlwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MURcdTA0MzVcdTA0M0ZcdTA0NDBcdTA0MzBcdTA0MzJcdTA0MzhcdTA0M0JcdTA0NENcdTA0M0RcdTA0NTYgXHUwNDMyXHUwNDQ1XHUwNDU2XHUwNDM0XHUwNDNEXHUwNDU2IFx1MDQzNFx1MDQzMFx1MDQzRFx1MDQ1NjogXHUwNDNFXHUwNDQ3XHUwNDU2XHUwNDNBXHUwNDQzXHUwNDU0XHUwNDQyXHUwNDRDXHUwNDQxXHUwNDRGICR7aXNzdWUuZXhwZWN0ZWR9LCBcdTA0M0VcdTA0NDJcdTA0NDBcdTA0MzhcdTA0M0NcdTA0MzBcdTA0M0RcdTA0M0UgJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX1gO1xuICAgICAgICAgICAgLy8gcmV0dXJuIGBcdTA0MURcdTA0MzVcdTA0M0ZcdTA0NDBcdTA0MzBcdTA0MzJcdTA0MzhcdTA0M0JcdTA0NENcdTA0M0RcdTA0NTYgXHUwNDMyXHUwNDQ1XHUwNDU2XHUwNDM0XHUwNDNEXHUwNDU2IFx1MDQzNFx1MDQzMFx1MDQzRFx1MDQ1NjogXHUwNDNFXHUwNDQ3XHUwNDU2XHUwNDNBXHUwNDQzXHUwNDU0XHUwNDQyXHUwNDRDXHUwNDQxXHUwNDRGICR7aXNzdWUuZXhwZWN0ZWR9LCBcdTA0M0VcdTA0NDJcdTA0NDBcdTA0MzhcdTA0M0NcdTA0MzBcdTA0M0RcdTA0M0UgJHt1dGlsLmdldFBhcnNlZFR5cGUoaXNzdWUuaW5wdXQpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF92YWx1ZVwiOlxuICAgICAgICAgICAgICAgIGlmIChpc3N1ZS52YWx1ZXMubGVuZ3RoID09PSAxKSByZXR1cm4gYFx1MDQxRFx1MDQzNVx1MDQzRlx1MDQ0MFx1MDQzMFx1MDQzMlx1MDQzOFx1MDQzQlx1MDQ0Q1x1MDQzRFx1MDQ1NiBcdTA0MzJcdTA0NDVcdTA0NTZcdTA0MzRcdTA0M0RcdTA0NTYgXHUwNDM0XHUwNDMwXHUwNDNEXHUwNDU2OiBcdTA0M0VcdTA0NDdcdTA0NTZcdTA0M0FcdTA0NDNcdTA0NTRcdTA0NDJcdTA0NENcdTA0NDFcdTA0NEYgJHt1dGlsLnN0cmluZ2lmeVByaW1pdGl2ZShpc3N1ZS52YWx1ZXNbMF0pfWA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MURcdTA0MzVcdTA0M0ZcdTA0NDBcdTA0MzBcdTA0MzJcdTA0MzhcdTA0M0JcdTA0NENcdTA0M0RcdTA0MzAgXHUwNDNFXHUwNDNGXHUwNDQ2XHUwNDU2XHUwNDRGOiBcdTA0M0VcdTA0NDdcdTA0NTZcdTA0M0FcdTA0NDNcdTA0NTRcdTA0NDJcdTA0NENcdTA0NDFcdTA0NEYgXHUwNDNFXHUwNDM0XHUwNDNEXHUwNDM1IFx1MDQzNyAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS52YWx1ZXMsIFwifFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPD1cIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykgcmV0dXJuIGBcdTA0MTdcdTA0MzBcdTA0M0RcdTA0MzBcdTA0MzRcdTA0NDJcdTA0M0UgXHUwNDMyXHUwNDM1XHUwNDNCXHUwNDM4XHUwNDNBXHUwNDM1OiBcdTA0M0VcdTA0NDdcdTA0NTZcdTA0M0FcdTA0NDNcdTA0NTRcdTA0NDJcdTA0NENcdTA0NDFcdTA0NEYsIFx1MDQ0OVx1MDQzRSAke2lzc3VlLm9yaWdpbiA/PyBcIlx1MDQzN1x1MDQzRFx1MDQzMFx1MDQ0N1x1MDQzNVx1MDQzRFx1MDQzRFx1MDQ0RlwifSAke3NpemluZy52ZXJifSAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdCA/PyBcIlx1MDQzNVx1MDQzQlx1MDQzNVx1MDQzQ1x1MDQzNVx1MDQzRFx1MDQ0Mlx1MDQ1Nlx1MDQzMlwifWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNDE3XHUwNDMwXHUwNDNEXHUwNDMwXHUwNDM0XHUwNDQyXHUwNDNFIFx1MDQzMlx1MDQzNVx1MDQzQlx1MDQzOFx1MDQzQVx1MDQzNTogXHUwNDNFXHUwNDQ3XHUwNDU2XHUwNDNBXHUwNDQzXHUwNDU0XHUwNDQyXHUwNDRDXHUwNDQxXHUwNDRGLCBcdTA0NDlcdTA0M0UgJHtpc3N1ZS5vcmlnaW4gPz8gXCJcdTA0MzdcdTA0M0RcdTA0MzBcdTA0NDdcdTA0MzVcdTA0M0RcdTA0M0RcdTA0NEZcIn0gXHUwNDMxXHUwNDQzXHUwNDM0XHUwNDM1ICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInRvb19zbWFsbFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI+PVwiIDogXCI+XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDQxN1x1MDQzMFx1MDQzRFx1MDQzMFx1MDQzNFx1MDQ0Mlx1MDQzRSBcdTA0M0NcdTA0MzBcdTA0M0JcdTA0MzU6IFx1MDQzRVx1MDQ0N1x1MDQ1Nlx1MDQzQVx1MDQ0M1x1MDQ1NFx1MDQ0Mlx1MDQ0Q1x1MDQ0MVx1MDQ0RiwgXHUwNDQ5XHUwNDNFICR7aXNzdWUub3JpZ2lufSAke3NpemluZy52ZXJifSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdH1gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNDE3XHUwNDMwXHUwNDNEXHUwNDMwXHUwNDM0XHUwNDQyXHUwNDNFIFx1MDQzQ1x1MDQzMFx1MDQzQlx1MDQzNTogXHUwNDNFXHUwNDQ3XHUwNDU2XHUwNDNBXHUwNDQzXHUwNDU0XHUwNDQyXHUwNDRDXHUwNDQxXHUwNDRGLCBcdTA0NDlcdTA0M0UgJHtpc3N1ZS5vcmlnaW59IFx1MDQzMVx1MDQ0M1x1MDQzNFx1MDQzNSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2Zvcm1hdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgX2lzc3VlID0gaXNzdWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInN0YXJ0c193aXRoXCIpIHJldHVybiBgXHUwNDFEXHUwNDM1XHUwNDNGXHUwNDQwXHUwNDMwXHUwNDMyXHUwNDM4XHUwNDNCXHUwNDRDXHUwNDNEXHUwNDM4XHUwNDM5IFx1MDQ0MFx1MDQ0Rlx1MDQzNFx1MDQzRVx1MDQzQTogXHUwNDNGXHUwNDNFXHUwNDMyXHUwNDM4XHUwNDNEXHUwNDM1XHUwNDNEIFx1MDQzRlx1MDQzRVx1MDQ0N1x1MDQzOFx1MDQzRFx1MDQzMFx1MDQ0Mlx1MDQzOFx1MDQ0MVx1MDQ0RiBcdTA0MzcgXCIke19pc3N1ZS5wcmVmaXh9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJlbmRzX3dpdGhcIikgcmV0dXJuIGBcdTA0MURcdTA0MzVcdTA0M0ZcdTA0NDBcdTA0MzBcdTA0MzJcdTA0MzhcdTA0M0JcdTA0NENcdTA0M0RcdTA0MzhcdTA0MzkgXHUwNDQwXHUwNDRGXHUwNDM0XHUwNDNFXHUwNDNBOiBcdTA0M0ZcdTA0M0VcdTA0MzJcdTA0MzhcdTA0M0RcdTA0MzVcdTA0M0QgXHUwNDM3XHUwNDMwXHUwNDNBXHUwNDU2XHUwNDNEXHUwNDQ3XHUwNDQzXHUwNDMyXHUwNDMwXHUwNDQyXHUwNDM4XHUwNDQxXHUwNDRGIFx1MDQzRFx1MDQzMCBcIiR7X2lzc3VlLnN1ZmZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImluY2x1ZGVzXCIpIHJldHVybiBgXHUwNDFEXHUwNDM1XHUwNDNGXHUwNDQwXHUwNDMwXHUwNDMyXHUwNDM4XHUwNDNCXHUwNDRDXHUwNDNEXHUwNDM4XHUwNDM5IFx1MDQ0MFx1MDQ0Rlx1MDQzNFx1MDQzRVx1MDQzQTogXHUwNDNGXHUwNDNFXHUwNDMyXHUwNDM4XHUwNDNEXHUwNDM1XHUwNDNEIFx1MDQzQ1x1MDQ1Nlx1MDQ0MVx1MDQ0Mlx1MDQzOFx1MDQ0Mlx1MDQzOCBcIiR7X2lzc3VlLmluY2x1ZGVzfVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBcdTA0MURcdTA0MzVcdTA0M0ZcdTA0NDBcdTA0MzBcdTA0MzJcdTA0MzhcdTA0M0JcdTA0NENcdTA0M0RcdTA0MzhcdTA0MzkgXHUwNDQwXHUwNDRGXHUwNDM0XHUwNDNFXHUwNDNBOiBcdTA0M0ZcdTA0M0VcdTA0MzJcdTA0MzhcdTA0M0RcdTA0MzVcdTA0M0QgXHUwNDMyXHUwNDU2XHUwNDM0XHUwNDNGXHUwNDNFXHUwNDMyXHUwNDU2XHUwNDM0XHUwNDMwXHUwNDQyXHUwNDM4IFx1MDQ0OFx1MDQzMFx1MDQzMVx1MDQzQlx1MDQzRVx1MDQzRFx1MDQ0MyAke19pc3N1ZS5wYXR0ZXJufWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNDFEXHUwNDM1XHUwNDNGXHUwNDQwXHUwNDMwXHUwNDMyXHUwNDM4XHUwNDNCXHUwNDRDXHUwNDNEXHUwNDM4XHUwNDM5ICR7Tm91bnNbX2lzc3VlLmZvcm1hdF0gPz8gaXNzdWUuZm9ybWF0fWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm5vdF9tdWx0aXBsZV9vZlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNDFEXHUwNDM1XHUwNDNGXHUwNDQwXHUwNDMwXHUwNDMyXHUwNDM4XHUwNDNCXHUwNDRDXHUwNDNEXHUwNDM1IFx1MDQ0N1x1MDQzOFx1MDQ0MVx1MDQzQlx1MDQzRTogXHUwNDNGXHUwNDNFXHUwNDMyXHUwNDM4XHUwNDNEXHUwNDNEXHUwNDNFIFx1MDQzMVx1MDQ0M1x1MDQ0Mlx1MDQzOCBcdTA0M0FcdTA0NDBcdTA0MzBcdTA0NDJcdTA0M0RcdTA0MzhcdTA0M0MgJHtpc3N1ZS5kaXZpc29yfWA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDQxRFx1MDQzNVx1MDQ0MFx1MDQzRVx1MDQzN1x1MDQzRlx1MDQ1Nlx1MDQzN1x1MDQzRFx1MDQzMFx1MDQzRFx1MDQzOFx1MDQzOSBcdTA0M0FcdTA0M0JcdTA0NEVcdTA0NDcke2lzc3VlLmtleXMubGVuZ3RoID4gMSA/IFwiXHUwNDU2XCIgOiBcIlwifTogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgXCIsIFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfa2V5XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MURcdTA0MzVcdTA0M0ZcdTA0NDBcdTA0MzBcdTA0MzJcdTA0MzhcdTA0M0JcdTA0NENcdTA0M0RcdTA0MzhcdTA0MzkgXHUwNDNBXHUwNDNCXHUwNDRFXHUwNDQ3IFx1MDQ0MyAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTA0MURcdTA0MzVcdTA0M0ZcdTA0NDBcdTA0MzBcdTA0MzJcdTA0MzhcdTA0M0JcdTA0NENcdTA0M0RcdTA0NTYgXHUwNDMyXHUwNDQ1XHUwNDU2XHUwNDM0XHUwNDNEXHUwNDU2IFx1MDQzNFx1MDQzMFx1MDQzRFx1MDQ1NlwiO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZWxlbWVudFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNDFEXHUwNDM1XHUwNDNGXHUwNDQwXHUwNDMwXHUwNDMyXHUwNDM4XHUwNDNCXHUwNDRDXHUwNDNEXHUwNDM1IFx1MDQzN1x1MDQzRFx1MDQzMFx1MDQ0N1x1MDQzNVx1MDQzRFx1MDQzRFx1MDQ0RiBcdTA0NDMgJHtpc3N1ZS5vcmlnaW59YDtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA0MURcdTA0MzVcdTA0M0ZcdTA0NDBcdTA0MzBcdTA0MzJcdTA0MzhcdTA0M0JcdTA0NENcdTA0M0RcdTA0NTYgXHUwNDMyXHUwNDQ1XHUwNDU2XHUwNDM0XHUwNDNEXHUwNDU2IFx1MDQzNFx1MDQzMFx1MDQzRFx1MDQ1NmA7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGxvY2FsZUVycm9yOiBlcnJvcigpXG4gICAgfTtcbn1cbiIsICJpbXBvcnQgdWsgZnJvbSBcIi4vdWsuanNcIjtcbi8qKiBAZGVwcmVjYXRlZCBVc2UgYHVrYCBpbnN0ZWFkLiAqLyBleHBvcnQgZGVmYXVsdCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdWsoKTtcbn1cbiIsICJpbXBvcnQgKiBhcyB1dGlsIGZyb20gXCIuLi9jb3JlL3V0aWwuanNcIjtcbmNvbnN0IGVycm9yID0gKCk9PntcbiAgICBjb25zdCBTaXphYmxlID0ge1xuICAgICAgICBzdHJpbmc6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHUwNjJEXHUwNjMxXHUwNjQ4XHUwNjQxXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MDZDMVx1MDY0OFx1MDY0Nlx1MDYyN1wiXG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHUwNjI4XHUwNjI3XHUwNjI2XHUwNjc5XHUwNjMzXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MDZDMVx1MDY0OFx1MDY0Nlx1MDYyN1wiXG4gICAgICAgIH0sXG4gICAgICAgIGFycmF5OiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1MDYyMlx1MDYyNlx1MDY3OVx1MDY0NVx1MDYzMlwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTA2QzFcdTA2NDhcdTA2NDZcdTA2MjdcIlxuICAgICAgICB9LFxuICAgICAgICBzZXQ6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHUwNjIyXHUwNjI2XHUwNjc5XHUwNjQ1XHUwNjMyXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1MDZDMVx1MDY0OFx1MDY0Nlx1MDYyN1wiXG4gICAgICAgIH1cbiAgICB9O1xuICAgIGZ1bmN0aW9uIGdldFNpemluZyhvcmlnaW4pIHtcbiAgICAgICAgcmV0dXJuIFNpemFibGVbb3JpZ2luXSA/PyBudWxsO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWRUeXBlID0gKGRhdGEpPT57XG4gICAgICAgIGNvbnN0IHQgPSB0eXBlb2YgZGF0YTtcbiAgICAgICAgc3dpdGNoKHQpe1xuICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFwiTmFOXCIgOiBcIlx1MDY0Nlx1MDY0NVx1MDYyOFx1MDYzMVwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTA2MjJcdTA2MzFcdTA2RDJcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiXHUwNjQ2XHUwNjQ0XCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcIlx1MDYyN1x1MDY0NiBcdTA2N0VcdTA2NzlcIixcbiAgICAgICAgZW1haWw6IFwiXHUwNjI3XHUwNkNDIFx1MDY0NVx1MDZDQ1x1MDY0NCBcdTA2MjdcdTA2Q0NcdTA2ODhcdTA2MzFcdTA2Q0NcdTA2MzNcIixcbiAgICAgICAgdXJsOiBcIlx1MDZDQ1x1MDY0OCBcdTA2MjJcdTA2MzEgXHUwNjI3XHUwNkNDXHUwNjQ0XCIsXG4gICAgICAgIGVtb2ppOiBcIlx1MDYyN1x1MDZDQ1x1MDY0NVx1MDY0OFx1MDYyQ1x1MDZDQ1wiLFxuICAgICAgICB1dWlkOiBcIlx1MDZDQ1x1MDY0OCBcdTA2Q0NcdTA2NDggXHUwNjIyXHUwNjI2XHUwNkNDIFx1MDY4OFx1MDZDQ1wiLFxuICAgICAgICB1dWlkdjQ6IFwiXHUwNkNDXHUwNjQ4IFx1MDZDQ1x1MDY0OCBcdTA2MjJcdTA2MjZcdTA2Q0MgXHUwNjg4XHUwNkNDIFx1MDY0OFx1MDZDQyA0XCIsXG4gICAgICAgIHV1aWR2NjogXCJcdTA2Q0NcdTA2NDggXHUwNkNDXHUwNjQ4IFx1MDYyMlx1MDYyNlx1MDZDQyBcdTA2ODhcdTA2Q0MgXHUwNjQ4XHUwNkNDIDZcIixcbiAgICAgICAgbmFub2lkOiBcIlx1MDY0Nlx1MDZDQ1x1MDY0Nlx1MDY0OCBcdTA2MjJcdTA2MjZcdTA2Q0MgXHUwNjg4XHUwNkNDXCIsXG4gICAgICAgIGd1aWQ6IFwiXHUwNjJDXHUwNkNDIFx1MDZDQ1x1MDY0OCBcdTA2MjJcdTA2MjZcdTA2Q0MgXHUwNjg4XHUwNkNDXCIsXG4gICAgICAgIGN1aWQ6IFwiXHUwNjMzXHUwNkNDIFx1MDZDQ1x1MDY0OCBcdTA2MjJcdTA2MjZcdTA2Q0MgXHUwNjg4XHUwNkNDXCIsXG4gICAgICAgIGN1aWQyOiBcIlx1MDYzM1x1MDZDQyBcdTA2Q0NcdTA2NDggXHUwNjIyXHUwNjI2XHUwNkNDIFx1MDY4OFx1MDZDQyAyXCIsXG4gICAgICAgIHVsaWQ6IFwiXHUwNkNDXHUwNjQ4IFx1MDYyN1x1MDZDQ1x1MDY0NCBcdTA2MjJcdTA2MjZcdTA2Q0MgXHUwNjg4XHUwNkNDXCIsXG4gICAgICAgIHhpZDogXCJcdTA2MjdcdTA2Q0NcdTA2QTlcdTA2MzMgXHUwNjIyXHUwNjI2XHUwNkNDIFx1MDY4OFx1MDZDQ1wiLFxuICAgICAgICBrc3VpZDogXCJcdTA2QTlcdTA2RDIgXHUwNjI3XHUwNkNDXHUwNjMzIFx1MDZDQ1x1MDY0OCBcdTA2MjJcdTA2MjZcdTA2Q0MgXHUwNjg4XHUwNkNDXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcIlx1MDYyMlx1MDYyNlx1MDZDQyBcdTA2MjdcdTA2Q0NcdTA2MzMgXHUwNjI3XHUwNjQ4IFx1MDY4OFx1MDZDQ1x1MDY3OSBcdTA2NzlcdTA2MjdcdTA2MjZcdTA2NDVcIixcbiAgICAgICAgZGF0ZTogXCJcdTA2MjJcdTA2MjZcdTA2Q0MgXHUwNjI3XHUwNkNDXHUwNjMzIFx1MDYyN1x1MDY0OCBcdTA2MkFcdTA2MjdcdTA2MzFcdTA2Q0NcdTA2MkVcIixcbiAgICAgICAgdGltZTogXCJcdTA2MjJcdTA2MjZcdTA2Q0MgXHUwNjI3XHUwNkNDXHUwNjMzIFx1MDYyN1x1MDY0OCBcdTA2NDhcdTA2NDJcdTA2MkFcIixcbiAgICAgICAgZHVyYXRpb246IFwiXHUwNjIyXHUwNjI2XHUwNkNDIFx1MDYyN1x1MDZDQ1x1MDYzMyBcdTA2MjdcdTA2NDggXHUwNjQ1XHUwNjJGXHUwNjJBXCIsXG4gICAgICAgIGlwdjQ6IFwiXHUwNjIyXHUwNjI2XHUwNkNDIFx1MDY3RVx1MDZDQyBcdTA2NDhcdTA2Q0MgNCBcdTA2MjdcdTA2Q0NcdTA2ODhcdTA2MzFcdTA2Q0NcdTA2MzNcIixcbiAgICAgICAgaXB2NjogXCJcdTA2MjJcdTA2MjZcdTA2Q0MgXHUwNjdFXHUwNkNDIFx1MDY0OFx1MDZDQyA2IFx1MDYyN1x1MDZDQ1x1MDY4OFx1MDYzMVx1MDZDQ1x1MDYzM1wiLFxuICAgICAgICBjaWRydjQ6IFwiXHUwNjIyXHUwNjI2XHUwNkNDIFx1MDY3RVx1MDZDQyBcdTA2NDhcdTA2Q0MgNCBcdTA2MzFcdTA2Q0NcdTA2NDZcdTA2MkNcIixcbiAgICAgICAgY2lkcnY2OiBcIlx1MDYyMlx1MDYyNlx1MDZDQyBcdTA2N0VcdTA2Q0MgXHUwNjQ4XHUwNkNDIDYgXHUwNjMxXHUwNkNDXHUwNjQ2XHUwNjJDXCIsXG4gICAgICAgIGJhc2U2NDogXCJcdTA2MjhcdTA2Q0NcdTA2MzMgNjQgXHUwNjI3XHUwNjQ2IFx1MDZBOVx1MDY0OFx1MDY4OFx1MDY4OCBcdTA2MzNcdTA2NzlcdTA2MzFcdTA2NDZcdTA2QUZcIixcbiAgICAgICAgYmFzZTY0dXJsOiBcIlx1MDYyOFx1MDZDQ1x1MDYzMyA2NCBcdTA2Q0NcdTA2NDggXHUwNjIyXHUwNjMxIFx1MDYyN1x1MDZDQ1x1MDY0NCBcdTA2MjdcdTA2NDYgXHUwNkE5XHUwNjQ4XHUwNjg4XHUwNjg4IFx1MDYzM1x1MDY3OVx1MDYzMVx1MDY0Nlx1MDZBRlwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJcdTA2MkNcdTA2RDIgXHUwNjI3XHUwNkNDXHUwNjMzIFx1MDYyN1x1MDY0OCBcdTA2MjdcdTA2Q0NcdTA2NDYgXHUwNjMzXHUwNjc5XHUwNjMxXHUwNjQ2XHUwNkFGXCIsXG4gICAgICAgIGUxNjQ6IFwiXHUwNjI3XHUwNkNDIDE2NCBcdTA2NDZcdTA2NDVcdTA2MjhcdTA2MzFcIixcbiAgICAgICAgand0OiBcIlx1MDYyQ1x1MDZEMiBcdTA2ODhcdTA2MjhcdTA2NDRcdTA2Q0NcdTA2NDggXHUwNjc5XHUwNkNDXCIsXG4gICAgICAgIHRlbXBsYXRlX2xpdGVyYWw6IFwiXHUwNjI3XHUwNjQ2IFx1MDY3RVx1MDY3OVwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2M0FcdTA2NDRcdTA2MzcgXHUwNjI3XHUwNjQ2IFx1MDY3RVx1MDY3OTogJHtpc3N1ZS5leHBlY3RlZH0gXHUwNjQ1XHUwNjJBXHUwNjQ4XHUwNjQyXHUwNjM5IFx1MDYyQVx1MDZCRVx1MDYyN1x1MDYwQyAke3BhcnNlZFR5cGUoaXNzdWUuaW5wdXQpfSBcdTA2NDVcdTA2NDhcdTA2MzVcdTA2NDhcdTA2NDQgXHUwNkMxXHUwNjQ4XHUwNjI3YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgXHUwNjNBXHUwNjQ0XHUwNjM3IFx1MDYyN1x1MDY0NiBcdTA2N0VcdTA2Nzk6ICR7dXRpbC5zdHJpbmdpZnlQcmltaXRpdmUoaXNzdWUudmFsdWVzWzBdKX0gXHUwNjQ1XHUwNjJBXHUwNjQ4XHUwNjQyXHUwNjM5IFx1MDYyQVx1MDZCRVx1MDYyN2A7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2M0FcdTA2NDRcdTA2MzcgXHUwNjIyXHUwNjdFXHUwNjM0XHUwNjQ2OiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS52YWx1ZXMsIFwifFwiKX0gXHUwNjQ1XHUwNkNDXHUwNkJBIFx1MDYzM1x1MDZEMiBcdTA2MjdcdTA2Q0NcdTA2QTkgXHUwNjQ1XHUwNjJBXHUwNjQ4XHUwNjQyXHUwNjM5IFx1MDYyQVx1MDZCRVx1MDYyN2A7XG4gICAgICAgICAgICBjYXNlIFwidG9vX2JpZ1wiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI8PVwiIDogXCI8XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSByZXR1cm4gYFx1MDYyOFx1MDZDMVx1MDYyQSBcdTA2MjhcdTA2OTFcdTA2Mjc6ICR7aXNzdWUub3JpZ2luID8/IFwiXHUwNjQ4XHUwNkNDXHUwNjQ0XHUwNkNDXHUwNjQ4XCJ9IFx1MDZBOVx1MDZEMiAke2Fkan0ke2lzc3VlLm1heGltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdCA/PyBcIlx1MDYzOVx1MDY0Nlx1MDYyN1x1MDYzNVx1MDYzMVwifSBcdTA2QzFcdTA2NDhcdTA2NDZcdTA2RDIgXHUwNjQ1XHUwNjJBXHUwNjQ4XHUwNjQyXHUwNjM5IFx1MDYyQVx1MDZCRVx1MDZEMmA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjI4XHUwNkMxXHUwNjJBIFx1MDYyOFx1MDY5MVx1MDYyNzogJHtpc3N1ZS5vcmlnaW4gPz8gXCJcdTA2NDhcdTA2Q0NcdTA2NDRcdTA2Q0NcdTA2NDhcIn0gXHUwNkE5XHUwNjI3ICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSBcdTA2QzFcdTA2NDhcdTA2NDZcdTA2MjcgXHUwNjQ1XHUwNjJBXHUwNjQ4XHUwNjQyXHUwNjM5IFx1MDYyQVx1MDZCRVx1MDYyN2A7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInRvb19zbWFsbFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI+PVwiIDogXCI+XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDYyOFx1MDZDMVx1MDYyQSBcdTA2ODZcdTA2QkVcdTA2NDhcdTA2NzlcdTA2Mjc6ICR7aXNzdWUub3JpZ2lufSBcdTA2QTlcdTA2RDIgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXR9IFx1MDZDMVx1MDY0OFx1MDY0Nlx1MDZEMiBcdTA2NDVcdTA2MkFcdTA2NDhcdTA2NDJcdTA2MzkgXHUwNjJBXHUwNkJFXHUwNkQyYDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDYyOFx1MDZDMVx1MDYyQSBcdTA2ODZcdTA2QkVcdTA2NDhcdTA2NzlcdTA2Mjc6ICR7aXNzdWUub3JpZ2lufSBcdTA2QTlcdTA2MjcgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9IFx1MDZDMVx1MDY0OFx1MDY0Nlx1MDYyNyBcdTA2NDVcdTA2MkFcdTA2NDhcdTA2NDJcdTA2MzkgXHUwNjJBXHUwNkJFXHUwNjI3YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9mb3JtYXRcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJzdGFydHNfd2l0aFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDYzQVx1MDY0NFx1MDYzNyBcdTA2MzNcdTA2NzlcdTA2MzFcdTA2NDZcdTA2QUY6IFwiJHtfaXNzdWUucHJlZml4fVwiIFx1MDYzM1x1MDZEMiBcdTA2MzRcdTA2MzFcdTA2NDhcdTA2MzkgXHUwNkMxXHUwNjQ4XHUwNjQ2XHUwNjI3IFx1MDY4Nlx1MDYyN1x1MDZDMVx1MDZDQ1x1MDZEMmA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiZW5kc193aXRoXCIpIHJldHVybiBgXHUwNjNBXHUwNjQ0XHUwNjM3IFx1MDYzM1x1MDY3OVx1MDYzMVx1MDY0Nlx1MDZBRjogXCIke19pc3N1ZS5zdWZmaXh9XCIgXHUwNjdFXHUwNjMxIFx1MDYyRVx1MDYyQVx1MDY0NSBcdTA2QzFcdTA2NDhcdTA2NDZcdTA2MjcgXHUwNjg2XHUwNjI3XHUwNkMxXHUwNkNDXHUwNkQyYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBcdTA2M0FcdTA2NDRcdTA2MzcgXHUwNjMzXHUwNjc5XHUwNjMxXHUwNjQ2XHUwNkFGOiBcIiR7X2lzc3VlLmluY2x1ZGVzfVwiIFx1MDYzNFx1MDYyN1x1MDY0NVx1MDY0NCBcdTA2QzFcdTA2NDhcdTA2NDZcdTA2MjcgXHUwNjg2XHUwNjI3XHUwNkMxXHUwNkNDXHUwNkQyYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBcdTA2M0FcdTA2NDRcdTA2MzcgXHUwNjMzXHUwNjc5XHUwNjMxXHUwNjQ2XHUwNkFGOiBcdTA2N0VcdTA2Q0NcdTA2NzlcdTA2MzFcdTA2NDYgJHtfaXNzdWUucGF0dGVybn0gXHUwNjMzXHUwNkQyIFx1MDY0NVx1MDZDQ1x1MDY4NiBcdTA2QzFcdTA2NDhcdTA2NDZcdTA2MjcgXHUwNjg2XHUwNjI3XHUwNkMxXHUwNkNDXHUwNkQyYDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2M0FcdTA2NDRcdTA2MzcgJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTA2M0FcdTA2NDRcdTA2MzcgXHUwNjQ2XHUwNjQ1XHUwNjI4XHUwNjMxOiAke2lzc3VlLmRpdmlzb3J9IFx1MDZBOVx1MDYyNyBcdTA2NDVcdTA2MzZcdTA2MjdcdTA2MzlcdTA2NDEgXHUwNkMxXHUwNjQ4XHUwNjQ2XHUwNjI3IFx1MDY4Nlx1MDYyN1x1MDZDMVx1MDZDQ1x1MDZEMmA7XG4gICAgICAgICAgICBjYXNlIFwidW5yZWNvZ25pemVkX2tleXNcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDYzQVx1MDZDQ1x1MDYzMSBcdTA2MkFcdTA2MzNcdTA2NDRcdTA2Q0NcdTA2NDUgXHUwNjM0XHUwNjJGXHUwNkMxIFx1MDZBOVx1MDZDQyR7aXNzdWUua2V5cy5sZW5ndGggPiAxID8gXCJcdTA2MzJcIiA6IFwiXCJ9OiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIlx1MDYwQyBcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2tleVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgJHtpc3N1ZS5vcmlnaW59IFx1MDY0NVx1MDZDQ1x1MDZCQSBcdTA2M0FcdTA2NDRcdTA2MzcgXHUwNkE5XHUwNkNDYDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3VuaW9uXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiXHUwNjNBXHUwNjQ0XHUwNjM3IFx1MDYyN1x1MDY0NiBcdTA2N0VcdTA2NzlcIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYCR7aXNzdWUub3JpZ2lufSBcdTA2NDVcdTA2Q0NcdTA2QkEgXHUwNjNBXHUwNjQ0XHUwNjM3IFx1MDY0OFx1MDZDQ1x1MDY0NFx1MDZDQ1x1MDY0OGA7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwNjNBXHUwNjQ0XHUwNjM3IFx1MDYyN1x1MDY0NiBcdTA2N0VcdTA2NzlgO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBsb2NhbGVFcnJvcjogZXJyb3IoKVxuICAgIH07XG59XG4iLCAiaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi4vY29yZS91dGlsLmpzXCI7XG5jb25zdCBlcnJvciA9ICgpPT57XG4gICAgY29uc3QgU2l6YWJsZSA9IHtcbiAgICAgICAgc3RyaW5nOiB7XG4gICAgICAgICAgICB1bml0OiBcImtcdTAwRkQgdFx1MUVGMVwiLFxuICAgICAgICAgICAgdmVyYjogXCJjXHUwMEYzXCJcbiAgICAgICAgfSxcbiAgICAgICAgZmlsZToge1xuICAgICAgICAgICAgdW5pdDogXCJieXRlXCIsXG4gICAgICAgICAgICB2ZXJiOiBcImNcdTAwRjNcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJwaFx1MUVBN24gdFx1MUVFRFwiLFxuICAgICAgICAgICAgdmVyYjogXCJjXHUwMEYzXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcInBoXHUxRUE3biB0XHUxRUVEXCIsXG4gICAgICAgICAgICB2ZXJiOiBcImNcdTAwRjNcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIk5hTlwiIDogXCJzXHUxRUQxXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm9iamVjdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm1cdTFFQTNuZ1wiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJudWxsXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcIlx1MDExMVx1MUVBN3Ugdlx1MDBFMG9cIixcbiAgICAgICAgZW1haWw6IFwiXHUwMTExXHUxRUNCYSBjaFx1MUVDOSBlbWFpbFwiLFxuICAgICAgICB1cmw6IFwiVVJMXCIsXG4gICAgICAgIGVtb2ppOiBcImVtb2ppXCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcIm5nXHUwMEUweSBnaVx1MUVERCBJU09cIixcbiAgICAgICAgZGF0ZTogXCJuZ1x1MDBFMHkgSVNPXCIsXG4gICAgICAgIHRpbWU6IFwiZ2lcdTFFREQgSVNPXCIsXG4gICAgICAgIGR1cmF0aW9uOiBcImtob1x1MUVBM25nIHRoXHUxRUREaSBnaWFuIElTT1wiLFxuICAgICAgICBpcHY0OiBcIlx1MDExMVx1MUVDQmEgY2hcdTFFQzkgSVB2NFwiLFxuICAgICAgICBpcHY2OiBcIlx1MDExMVx1MUVDQmEgY2hcdTFFQzkgSVB2NlwiLFxuICAgICAgICBjaWRydjQ6IFwiZFx1MUVBM2kgSVB2NFwiLFxuICAgICAgICBjaWRydjY6IFwiZFx1MUVBM2kgSVB2NlwiLFxuICAgICAgICBiYXNlNjQ6IFwiY2h1XHUxRUQ3aSBtXHUwMEUzIGhcdTAwRjNhIGJhc2U2NFwiLFxuICAgICAgICBiYXNlNjR1cmw6IFwiY2h1XHUxRUQ3aSBtXHUwMEUzIGhcdTAwRjNhIGJhc2U2NHVybFwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJjaHVcdTFFRDdpIEpTT05cIixcbiAgICAgICAgZTE2NDogXCJzXHUxRUQxIEUuMTY0XCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJcdTAxMTFcdTFFQTd1IHZcdTAwRTBvXCJcbiAgICB9O1xuICAgIHJldHVybiAoaXNzdWUpPT57XG4gICAgICAgIHN3aXRjaChpc3N1ZS5jb2RlKXtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3R5cGVcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1MDExMFx1MUVBN3Ugdlx1MDBFMG8ga2hcdTAwRjRuZyBoXHUxRUUzcCBsXHUxRUM3OiBtb25nIFx1MDExMVx1MUVFM2kgJHtpc3N1ZS5leHBlY3RlZH0sIG5oXHUxRUFEbiBcdTAxMTFcdTAxQjBcdTFFRTNjICR7cGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgXHUwMTEwXHUxRUE3dSB2XHUwMEUwbyBraFx1MDBGNG5nIGhcdTFFRTNwIGxcdTFFQzc6IG1vbmcgXHUwMTExXHUxRUUzaSAke3V0aWwuc3RyaW5naWZ5UHJpbWl0aXZlKGlzc3VlLnZhbHVlc1swXSl9YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYFRcdTAwRjl5IGNoXHUxRUNEbiBraFx1MDBGNG5nIGhcdTFFRTNwIGxcdTFFQzc6IG1vbmcgXHUwMTExXHUxRUUzaSBtXHUxRUQ5dCB0cm9uZyBjXHUwMEUxYyBnaVx1MDBFMSB0clx1MUVDQiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS52YWx1ZXMsIFwifFwiKX1gO1xuICAgICAgICAgICAgY2FzZSBcInRvb19iaWdcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPD1cIiA6IFwiPFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykgcmV0dXJuIGBRdVx1MDBFMSBsXHUxRURCbjogbW9uZyBcdTAxMTFcdTFFRTNpICR7aXNzdWUub3JpZ2luID8/IFwiZ2lcdTAwRTEgdHJcdTFFQ0JcIn0gJHtzaXppbmcudmVyYn0gJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXQgPz8gXCJwaFx1MUVBN24gdFx1MUVFRFwifWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgUXVcdTAwRTEgbFx1MUVEQm46IG1vbmcgXHUwMTExXHUxRUUzaSAke2lzc3VlLm9yaWdpbiA/PyBcImdpXHUwMEUxIHRyXHUxRUNCXCJ9ICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInRvb19zbWFsbFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI+PVwiIDogXCI+XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFF1XHUwMEUxIG5oXHUxRUNGOiBtb25nIFx1MDExMVx1MUVFM2kgJHtpc3N1ZS5vcmlnaW59ICR7c2l6aW5nLnZlcmJ9ICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0fWA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBRdVx1MDBFMSBuaFx1MUVDRjogbW9uZyBcdTAxMTFcdTFFRTNpICR7aXNzdWUub3JpZ2lufSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2Zvcm1hdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgX2lzc3VlID0gaXNzdWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInN0YXJ0c193aXRoXCIpIHJldHVybiBgQ2h1XHUxRUQ3aSBraFx1MDBGNG5nIGhcdTFFRTNwIGxcdTFFQzc6IHBoXHUxRUEzaSBiXHUxRUFGdCBcdTAxMTFcdTFFQTd1IGJcdTFFQjFuZyBcIiR7X2lzc3VlLnByZWZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYENodVx1MUVEN2kga2hcdTAwRjRuZyBoXHUxRUUzcCBsXHUxRUM3OiBwaFx1MUVBM2kga1x1MUVCRnQgdGhcdTAwRkFjIGJcdTFFQjFuZyBcIiR7X2lzc3VlLnN1ZmZpeH1cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImluY2x1ZGVzXCIpIHJldHVybiBgQ2h1XHUxRUQ3aSBraFx1MDBGNG5nIGhcdTFFRTNwIGxcdTFFQzc6IHBoXHUxRUEzaSBiYW8gZ1x1MUVEM20gXCIke19pc3N1ZS5pbmNsdWRlc31cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInJlZ2V4XCIpIHJldHVybiBgQ2h1XHUxRUQ3aSBraFx1MDBGNG5nIGhcdTFFRTNwIGxcdTFFQzc6IHBoXHUxRUEzaSBraFx1MUVEQnAgdlx1MUVEQmkgbVx1MUVBQnUgJHtfaXNzdWUucGF0dGVybn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYCR7Tm91bnNbX2lzc3VlLmZvcm1hdF0gPz8gaXNzdWUuZm9ybWF0fSBraFx1MDBGNG5nIGhcdTFFRTNwIGxcdTFFQzdgO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJub3RfbXVsdGlwbGVfb2ZcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFNcdTFFRDEga2hcdTAwRjRuZyBoXHUxRUUzcCBsXHUxRUM3OiBwaFx1MUVBM2kgbFx1MDBFMCBiXHUxRUQ5aSBzXHUxRUQxIGNcdTFFRTdhICR7aXNzdWUuZGl2aXNvcn1gO1xuICAgICAgICAgICAgY2FzZSBcInVucmVjb2duaXplZF9rZXlzXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBLaFx1MDBGM2Ega2hcdTAwRjRuZyBcdTAxMTFcdTAxQjBcdTFFRTNjIG5oXHUxRUFEbiBkXHUxRUExbmc6ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLmtleXMsIFwiLCBcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2tleVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgS2hcdTAwRjNhIGtoXHUwMEY0bmcgaFx1MUVFM3AgbFx1MUVDNyB0cm9uZyAke2lzc3VlLm9yaWdpbn1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTAxMTBcdTFFQTd1IHZcdTAwRTBvIGtoXHUwMEY0bmcgaFx1MUVFM3AgbFx1MUVDN1wiO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZWxlbWVudFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgR2lcdTAwRTEgdHJcdTFFQ0Iga2hcdTAwRjRuZyBoXHUxRUUzcCBsXHUxRUM3IHRyb25nICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwMTEwXHUxRUE3dSB2XHUwMEUwbyBraFx1MDBGNG5nIGhcdTFFRTNwIGxcdTFFQzdgO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBsb2NhbGVFcnJvcjogZXJyb3IoKVxuICAgIH07XG59XG4iLCAiaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi4vY29yZS91dGlsLmpzXCI7XG5jb25zdCBlcnJvciA9ICgpPT57XG4gICAgY29uc3QgU2l6YWJsZSA9IHtcbiAgICAgICAgc3RyaW5nOiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1NUI1N1x1N0IyNlwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTUzMDVcdTU0MkJcIlxuICAgICAgICB9LFxuICAgICAgICBmaWxlOiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1NUI1N1x1ODI4MlwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTUzMDVcdTU0MkJcIlxuICAgICAgICB9LFxuICAgICAgICBhcnJheToge1xuICAgICAgICAgICAgdW5pdDogXCJcdTk4NzlcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHU1MzA1XHU1NDJCXCJcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgICB1bml0OiBcIlx1OTg3OVwiLFxuICAgICAgICAgICAgdmVyYjogXCJcdTUzMDVcdTU0MkJcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIlx1OTc1RVx1NjU3MFx1NUI1NyhOYU4pXCIgOiBcIlx1NjU3MFx1NUI1N1wiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTY1NzBcdTdFQzRcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiXHU3QTdBXHU1MDNDKG51bGwpXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcIlx1OEY5M1x1NTE2NVwiLFxuICAgICAgICBlbWFpbDogXCJcdTc1MzVcdTVCNTBcdTkwQUVcdTRFRjZcIixcbiAgICAgICAgdXJsOiBcIlVSTFwiLFxuICAgICAgICBlbW9qaTogXCJcdTg4NjhcdTYwQzVcdTdCMjZcdTUzRjdcIixcbiAgICAgICAgdXVpZDogXCJVVUlEXCIsXG4gICAgICAgIHV1aWR2NDogXCJVVUlEdjRcIixcbiAgICAgICAgdXVpZHY2OiBcIlVVSUR2NlwiLFxuICAgICAgICBuYW5vaWQ6IFwibmFub2lkXCIsXG4gICAgICAgIGd1aWQ6IFwiR1VJRFwiLFxuICAgICAgICBjdWlkOiBcImN1aWRcIixcbiAgICAgICAgY3VpZDI6IFwiY3VpZDJcIixcbiAgICAgICAgdWxpZDogXCJVTElEXCIsXG4gICAgICAgIHhpZDogXCJYSURcIixcbiAgICAgICAga3N1aWQ6IFwiS1NVSURcIixcbiAgICAgICAgZGF0ZXRpbWU6IFwiSVNPXHU2NUU1XHU2NzFGXHU2NUY2XHU5NUY0XCIsXG4gICAgICAgIGRhdGU6IFwiSVNPXHU2NUU1XHU2NzFGXCIsXG4gICAgICAgIHRpbWU6IFwiSVNPXHU2NUY2XHU5NUY0XCIsXG4gICAgICAgIGR1cmF0aW9uOiBcIklTT1x1NjVGNlx1OTU3RlwiLFxuICAgICAgICBpcHY0OiBcIklQdjRcdTU3MzBcdTU3NDBcIixcbiAgICAgICAgaXB2NjogXCJJUHY2XHU1NzMwXHU1NzQwXCIsXG4gICAgICAgIGNpZHJ2NDogXCJJUHY0XHU3RjUxXHU2QkI1XCIsXG4gICAgICAgIGNpZHJ2NjogXCJJUHY2XHU3RjUxXHU2QkI1XCIsXG4gICAgICAgIGJhc2U2NDogXCJiYXNlNjRcdTdGMTZcdTc4MDFcdTVCNTdcdTdCMjZcdTRFMzJcIixcbiAgICAgICAgYmFzZTY0dXJsOiBcImJhc2U2NHVybFx1N0YxNlx1NzgwMVx1NUI1N1x1N0IyNlx1NEUzMlwiLFxuICAgICAgICBqc29uX3N0cmluZzogXCJKU09OXHU1QjU3XHU3QjI2XHU0RTMyXCIsXG4gICAgICAgIGUxNjQ6IFwiRS4xNjRcdTUzRjdcdTc4MDFcIixcbiAgICAgICAgand0OiBcIkpXVFwiLFxuICAgICAgICB0ZW1wbGF0ZV9saXRlcmFsOiBcIlx1OEY5M1x1NTE2NVwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTY1RTBcdTY1NDhcdThGOTNcdTUxNjVcdUZGMUFcdTY3MUZcdTY3MUIgJHtpc3N1ZS5leHBlY3RlZH1cdUZGMENcdTVCOUVcdTk2NDVcdTYzQTVcdTY1MzYgJHtwYXJzZWRUeXBlKGlzc3VlLmlucHV0KX1gO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdmFsdWVcIjpcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUudmFsdWVzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGBcdTY1RTBcdTY1NDhcdThGOTNcdTUxNjVcdUZGMUFcdTY3MUZcdTY3MUIgJHt1dGlsLnN0cmluZ2lmeVByaW1pdGl2ZShpc3N1ZS52YWx1ZXNbMF0pfWA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTY1RTBcdTY1NDhcdTkwMDlcdTk4NzlcdUZGMUFcdTY3MUZcdTY3MUJcdTRFRTVcdTRFMEJcdTRFNEJcdTRFMDAgJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUudmFsdWVzLCBcInxcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ0b29fYmlnXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIjw9XCIgOiBcIjxcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHJldHVybiBgXHU2NTcwXHU1MDNDXHU4RkM3XHU1OTI3XHVGRjFBXHU2NzFGXHU2NzFCICR7aXNzdWUub3JpZ2luID8/IFwiXHU1MDNDXCJ9ICR7YWRqfSR7aXNzdWUubWF4aW11bS50b1N0cmluZygpfSAke3NpemluZy51bml0ID8/IFwiXHU0RTJBXHU1MTQzXHU3RDIwXCJ9YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTY1NzBcdTUwM0NcdThGQzdcdTU5MjdcdUZGMUFcdTY3MUZcdTY3MUIgJHtpc3N1ZS5vcmlnaW4gPz8gXCJcdTUwM0NcIn0gJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIj49XCIgOiBcIj5cIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHU2NTcwXHU1MDNDXHU4RkM3XHU1QzBGXHVGRjFBXHU2NzFGXHU2NzFCICR7aXNzdWUub3JpZ2lufSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX0gJHtzaXppbmcudW5pdH1gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHU2NTcwXHU1MDNDXHU4RkM3XHU1QzBGXHVGRjFBXHU2NzFGXHU2NzFCICR7aXNzdWUub3JpZ2lufSAke2Fkan0ke2lzc3VlLm1pbmltdW0udG9TdHJpbmcoKX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2Zvcm1hdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgX2lzc3VlID0gaXNzdWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInN0YXJ0c193aXRoXCIpIHJldHVybiBgXHU2NUUwXHU2NTQ4XHU1QjU3XHU3QjI2XHU0RTMyXHVGRjFBXHU1RkM1XHU5ODdCXHU0RUU1IFwiJHtfaXNzdWUucHJlZml4fVwiIFx1NUYwMFx1NTkzNGA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcImVuZHNfd2l0aFwiKSByZXR1cm4gYFx1NjVFMFx1NjU0OFx1NUI1N1x1N0IyNlx1NEUzMlx1RkYxQVx1NUZDNVx1OTg3Qlx1NEVFNSBcIiR7X2lzc3VlLnN1ZmZpeH1cIiBcdTdFRDNcdTVDM0VgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJpbmNsdWRlc1wiKSByZXR1cm4gYFx1NjVFMFx1NjU0OFx1NUI1N1x1N0IyNlx1NEUzMlx1RkYxQVx1NUZDNVx1OTg3Qlx1NTMwNVx1NTQyQiBcIiR7X2lzc3VlLmluY2x1ZGVzfVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBcdTY1RTBcdTY1NDhcdTVCNTdcdTdCMjZcdTRFMzJcdUZGMUFcdTVGQzVcdTk4N0JcdTZFRTFcdThEQjNcdTZCNjNcdTUyMTlcdTg4NjhcdThGQkVcdTVGMEYgJHtfaXNzdWUucGF0dGVybn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1NjVFMFx1NjU0OCR7Tm91bnNbX2lzc3VlLmZvcm1hdF0gPz8gaXNzdWUuZm9ybWF0fWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm5vdF9tdWx0aXBsZV9vZlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHU2NUUwXHU2NTQ4XHU2NTcwXHU1QjU3XHVGRjFBXHU1RkM1XHU5ODdCXHU2NjJGICR7aXNzdWUuZGl2aXNvcn0gXHU3Njg0XHU1MDBEXHU2NTcwYDtcbiAgICAgICAgICAgIGNhc2UgXCJ1bnJlY29nbml6ZWRfa2V5c1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHU1MUZBXHU3M0IwXHU2NzJBXHU3N0U1XHU3Njg0XHU5NTJFKGtleSk6ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLmtleXMsIFwiLCBcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2tleVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgJHtpc3N1ZS5vcmlnaW59IFx1NEUyRFx1NzY4NFx1OTUyRShrZXkpXHU2NUUwXHU2NTQ4YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3VuaW9uXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiXHU2NUUwXHU2NTQ4XHU4RjkzXHU1MTY1XCI7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9lbGVtZW50XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGAke2lzc3VlLm9yaWdpbn0gXHU0RTJEXHU1MzA1XHU1NDJCXHU2NUUwXHU2NTQ4XHU1MDNDKHZhbHVlKWA7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHU2NUUwXHU2NTQ4XHU4RjkzXHU1MTY1YDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbG9jYWxlRXJyb3I6IGVycm9yKClcbiAgICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHV0aWwgZnJvbSBcIi4uL2NvcmUvdXRpbC5qc1wiO1xuY29uc3QgZXJyb3IgPSAoKT0+e1xuICAgIGNvbnN0IFNpemFibGUgPSB7XG4gICAgICAgIHN0cmluZzoge1xuICAgICAgICAgICAgdW5pdDogXCJcdTVCNTdcdTUxNDNcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHU2NEMxXHU2NzA5XCJcbiAgICAgICAgfSxcbiAgICAgICAgZmlsZToge1xuICAgICAgICAgICAgdW5pdDogXCJcdTRGNERcdTUxNDNcdTdENDRcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHU2NEMxXHU2NzA5XCJcbiAgICAgICAgfSxcbiAgICAgICAgYXJyYXk6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHU5ODA1XHU3NkVFXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIlx1NjRDMVx1NjcwOVwiXG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDogXCJcdTk4MDVcdTc2RUVcIixcbiAgICAgICAgICAgIHZlcmI6IFwiXHU2NEMxXHU2NzA5XCJcbiAgICAgICAgfVxuICAgIH07XG4gICAgZnVuY3Rpb24gZ2V0U2l6aW5nKG9yaWdpbikge1xuICAgICAgICByZXR1cm4gU2l6YWJsZVtvcmlnaW5dID8/IG51bGw7XG4gICAgfVxuICAgIGNvbnN0IHBhcnNlZFR5cGUgPSAoZGF0YSk9PntcbiAgICAgICAgY29uc3QgdCA9IHR5cGVvZiBkYXRhO1xuICAgICAgICBzd2l0Y2godCl7XG4gICAgICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gTnVtYmVyLmlzTmFOKGRhdGEpID8gXCJOYU5cIiA6IFwibnVtYmVyXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm9iamVjdFwiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcImFycmF5XCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGEgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm51bGxcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKGRhdGEpICE9PSBPYmplY3QucHJvdG90eXBlICYmIGRhdGEuY29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHQ7XG4gICAgfTtcbiAgICBjb25zdCBOb3VucyA9IHtcbiAgICAgICAgcmVnZXg6IFwiXHU4RjM4XHU1MTY1XCIsXG4gICAgICAgIGVtYWlsOiBcIlx1OTBGNVx1NEVGNlx1NTczMFx1NTc0MFwiLFxuICAgICAgICB1cmw6IFwiVVJMXCIsXG4gICAgICAgIGVtb2ppOiBcImVtb2ppXCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcIklTTyBcdTY1RTVcdTY3MUZcdTY2NDJcdTk1OTNcIixcbiAgICAgICAgZGF0ZTogXCJJU08gXHU2NUU1XHU2NzFGXCIsXG4gICAgICAgIHRpbWU6IFwiSVNPIFx1NjY0Mlx1OTU5M1wiLFxuICAgICAgICBkdXJhdGlvbjogXCJJU08gXHU2NzFGXHU5NTkzXCIsXG4gICAgICAgIGlwdjQ6IFwiSVB2NCBcdTRGNERcdTU3NDBcIixcbiAgICAgICAgaXB2NjogXCJJUHY2IFx1NEY0RFx1NTc0MFwiLFxuICAgICAgICBjaWRydjQ6IFwiSVB2NCBcdTdCQzRcdTU3MERcIixcbiAgICAgICAgY2lkcnY2OiBcIklQdjYgXHU3QkM0XHU1NzBEXCIsXG4gICAgICAgIGJhc2U2NDogXCJiYXNlNjQgXHU3REU4XHU3OEJDXHU1QjU3XHU0RTMyXCIsXG4gICAgICAgIGJhc2U2NHVybDogXCJiYXNlNjR1cmwgXHU3REU4XHU3OEJDXHU1QjU3XHU0RTMyXCIsXG4gICAgICAgIGpzb25fc3RyaW5nOiBcIkpTT04gXHU1QjU3XHU0RTMyXCIsXG4gICAgICAgIGUxNjQ6IFwiRS4xNjQgXHU2NTc4XHU1MDNDXCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJcdThGMzhcdTUxNjVcIlxuICAgIH07XG4gICAgcmV0dXJuIChpc3N1ZSk9PntcbiAgICAgICAgc3dpdGNoKGlzc3VlLmNvZGUpe1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdHlwZVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgXHU3MTIxXHU2NTQ4XHU3Njg0XHU4RjM4XHU1MTY1XHU1MDNDXHVGRjFBXHU5ODEwXHU2NzFGXHU3MEJBICR7aXNzdWUuZXhwZWN0ZWR9XHVGRjBDXHU0RjQ2XHU2NTM2XHU1MjMwICR7cGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgXHU3MTIxXHU2NTQ4XHU3Njg0XHU4RjM4XHU1MTY1XHU1MDNDXHVGRjFBXHU5ODEwXHU2NzFGXHU3MEJBICR7dXRpbC5zdHJpbmdpZnlQcmltaXRpdmUoaXNzdWUudmFsdWVzWzBdKX1gO1xuICAgICAgICAgICAgICAgIHJldHVybiBgXHU3MTIxXHU2NTQ4XHU3Njg0XHU5MDc4XHU5ODA1XHVGRjFBXHU5ODEwXHU2NzFGXHU3MEJBXHU0RUU1XHU0RTBCXHU1MTc2XHU0RTJEXHU0RTRCXHU0RTAwICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLnZhbHVlcywgXCJ8XCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwidG9vX2JpZ1wiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI8PVwiIDogXCI8XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSByZXR1cm4gYFx1NjU3OFx1NTAzQ1x1OTA0RVx1NTkyN1x1RkYxQVx1OTgxMFx1NjcxRiAke2lzc3VlLm9yaWdpbiA/PyBcIlx1NTAzQ1wifSBcdTYxQzlcdTcwQkEgJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXQgPz8gXCJcdTUwMEJcdTUxNDNcdTdEMjBcIn1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1NjU3OFx1NTAzQ1x1OTA0RVx1NTkyN1x1RkYxQVx1OTgxMFx1NjcxRiAke2lzc3VlLm9yaWdpbiA/PyBcIlx1NTAzQ1wifSBcdTYxQzlcdTcwQkEgJHthZGp9JHtpc3N1ZS5tYXhpbXVtLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwidG9vX3NtYWxsXCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGogPSBpc3N1ZS5pbmNsdXNpdmUgPyBcIj49XCIgOiBcIj5cIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2l6aW5nID0gZ2V0U2l6aW5nKGlzc3VlLm9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXppbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgXHU2NTc4XHU1MDNDXHU5MDRFXHU1QzBGXHVGRjFBXHU5ODEwXHU2NzFGICR7aXNzdWUub3JpZ2lufSBcdTYxQzlcdTcwQkEgJHthZGp9JHtpc3N1ZS5taW5pbXVtLnRvU3RyaW5nKCl9ICR7c2l6aW5nLnVuaXR9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFx1NjU3OFx1NTAzQ1x1OTA0RVx1NUMwRlx1RkYxQVx1OTgxMFx1NjcxRiAke2lzc3VlLm9yaWdpbn0gXHU2MUM5XHU3MEJBICR7YWRqfSR7aXNzdWUubWluaW11bS50b1N0cmluZygpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZm9ybWF0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBfaXNzdWUgPSBpc3N1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwic3RhcnRzX3dpdGhcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTcxMjFcdTY1NDhcdTc2ODRcdTVCNTdcdTRFMzJcdUZGMUFcdTVGQzVcdTk4MDhcdTRFRTUgXCIke19pc3N1ZS5wcmVmaXh9XCIgXHU5NThCXHU5ODJEYDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJlbmRzX3dpdGhcIikgcmV0dXJuIGBcdTcxMjFcdTY1NDhcdTc2ODRcdTVCNTdcdTRFMzJcdUZGMUFcdTVGQzVcdTk4MDhcdTRFRTUgXCIke19pc3N1ZS5zdWZmaXh9XCIgXHU3RDUwXHU1QzNFYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBcdTcxMjFcdTY1NDhcdTc2ODRcdTVCNTdcdTRFMzJcdUZGMUFcdTVGQzVcdTk4MDhcdTUzMDVcdTU0MkIgXCIke19pc3N1ZS5pbmNsdWRlc31cImA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZm9ybWF0ID09PSBcInJlZ2V4XCIpIHJldHVybiBgXHU3MTIxXHU2NTQ4XHU3Njg0XHU1QjU3XHU0RTMyXHVGRjFBXHU1RkM1XHU5ODA4XHU3QjI2XHU1NDA4XHU2ODNDXHU1RjBGICR7X2lzc3VlLnBhdHRlcm59YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcdTcxMjFcdTY1NDhcdTc2ODQgJHtOb3Vuc1tfaXNzdWUuZm9ybWF0XSA/PyBpc3N1ZS5mb3JtYXR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwibm90X211bHRpcGxlX29mXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTcxMjFcdTY1NDhcdTc2ODRcdTY1NzhcdTVCNTdcdUZGMUFcdTVGQzVcdTk4MDhcdTcwQkEgJHtpc3N1ZS5kaXZpc29yfSBcdTc2ODRcdTUwMERcdTY1NzhgO1xuICAgICAgICAgICAgY2FzZSBcInVucmVjb2duaXplZF9rZXlzXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTcxMjFcdTZDRDVcdThCNThcdTUyMjVcdTc2ODRcdTkzNzVcdTUwM0Mke2lzc3VlLmtleXMubGVuZ3RoID4gMSA/IFwiXHU1MDExXCIgOiBcIlwifVx1RkYxQSR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLmtleXMsIFwiXHUzMDAxXCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF9rZXlcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYCR7aXNzdWUub3JpZ2lufSBcdTRFMkRcdTY3MDlcdTcxMjFcdTY1NDhcdTc2ODRcdTkzNzVcdTUwM0NgO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfdW5pb25cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJcdTcxMjFcdTY1NDhcdTc2ODRcdThGMzhcdTUxNjVcdTUwM0NcIjtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2VsZW1lbnRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYCR7aXNzdWUub3JpZ2lufSBcdTRFMkRcdTY3MDlcdTcxMjFcdTY1NDhcdTc2ODRcdTUwM0NgO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gYFx1NzEyMVx1NjU0OFx1NzY4NFx1OEYzOFx1NTE2NVx1NTAzQ2A7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGxvY2FsZUVycm9yOiBlcnJvcigpXG4gICAgfTtcbn1cbiIsICJpbXBvcnQgKiBhcyB1dGlsIGZyb20gXCIuLi9jb3JlL3V0aWwuanNcIjtcbmNvbnN0IGVycm9yID0gKCk9PntcbiAgICBjb25zdCBTaXphYmxlID0ge1xuICAgICAgICBzdHJpbmc6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiXHUwMEUwbWlcIixcbiAgICAgICAgICAgIHZlcmI6IFwiblx1MDBFRFwiXG4gICAgICAgIH0sXG4gICAgICAgIGZpbGU6IHtcbiAgICAgICAgICAgIHVuaXQ6IFwiYnl0ZXNcIixcbiAgICAgICAgICAgIHZlcmI6IFwiblx1MDBFRFwiXG4gICAgICAgIH0sXG4gICAgICAgIGFycmF5OiB7XG4gICAgICAgICAgICB1bml0OiBcIm5rYW5cIixcbiAgICAgICAgICAgIHZlcmI6IFwiblx1MDBFRFwiXG4gICAgICAgIH0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgICAgdW5pdDogXCJua2FuXCIsXG4gICAgICAgICAgICB2ZXJiOiBcIm5cdTAwRURcIlxuICAgICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBnZXRTaXppbmcob3JpZ2luKSB7XG4gICAgICAgIHJldHVybiBTaXphYmxlW29yaWdpbl0gPz8gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkVHlwZSA9IChkYXRhKT0+e1xuICAgICAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgICAgIHN3aXRjaCh0KXtcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0YSkgPyBcIk5hTlwiIDogXCJuXHUxRUNEXHUwMzAxbWJcdTAwRTBcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiYWtvcFx1MUVDRFwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJudWxsXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihkYXRhKSAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiBkYXRhLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0O1xuICAgIH07XG4gICAgY29uc3QgTm91bnMgPSB7XG4gICAgICAgIHJlZ2V4OiBcIlx1MUVCOVx1MDMwMHJcdTFFQ0QgXHUwMEVDYlx1MDBFMXdcdTFFQ0RsXHUwMEU5XCIsXG4gICAgICAgIGVtYWlsOiBcIlx1MDBFMGRcdTAwRURyXHUxRUI5XHUwMzAxc1x1MDBFQyBcdTAwRUNtXHUxRUI5XHUwMzAxbFx1MDBFQ1wiLFxuICAgICAgICB1cmw6IFwiVVJMXCIsXG4gICAgICAgIGVtb2ppOiBcImVtb2ppXCIsXG4gICAgICAgIHV1aWQ6IFwiVVVJRFwiLFxuICAgICAgICB1dWlkdjQ6IFwiVVVJRHY0XCIsXG4gICAgICAgIHV1aWR2NjogXCJVVUlEdjZcIixcbiAgICAgICAgbmFub2lkOiBcIm5hbm9pZFwiLFxuICAgICAgICBndWlkOiBcIkdVSURcIixcbiAgICAgICAgY3VpZDogXCJjdWlkXCIsXG4gICAgICAgIGN1aWQyOiBcImN1aWQyXCIsXG4gICAgICAgIHVsaWQ6IFwiVUxJRFwiLFxuICAgICAgICB4aWQ6IFwiWElEXCIsXG4gICAgICAgIGtzdWlkOiBcIktTVUlEXCIsXG4gICAgICAgIGRhdGV0aW1lOiBcIlx1MDBFMGtcdTAwRjNrXHUwMEYyIElTT1wiLFxuICAgICAgICBkYXRlOiBcIlx1MUVDRGpcdTFFQ0RcdTAzMDEgSVNPXCIsXG4gICAgICAgIHRpbWU6IFwiXHUwMEUwa1x1MDBGM2tcdTAwRjIgSVNPXCIsXG4gICAgICAgIGR1cmF0aW9uOiBcIlx1MDBFMGtcdTAwRjNrXHUwMEYyIHRcdTAwRjMgcFx1MDBFOSBJU09cIixcbiAgICAgICAgaXB2NDogXCJcdTAwRTBkXHUwMEVEclx1MUVCOVx1MDMwMXNcdTAwRUMgSVB2NFwiLFxuICAgICAgICBpcHY2OiBcIlx1MDBFMGRcdTAwRURyXHUxRUI5XHUwMzAxc1x1MDBFQyBJUHY2XCIsXG4gICAgICAgIGNpZHJ2NDogXCJcdTAwRTBnYlx1MDBFOGdiXHUwMEU4IElQdjRcIixcbiAgICAgICAgY2lkcnY2OiBcIlx1MDBFMGdiXHUwMEU4Z2JcdTAwRTggSVB2NlwiLFxuICAgICAgICBiYXNlNjQ6IFwiXHUxRUNEXHUwMzAwclx1MUVDRFx1MDMwMCB0XHUwMEVEIGEga1x1MUVDRFx1MDMwMSBuXHUwMEVEIGJhc2U2NFwiLFxuICAgICAgICBiYXNlNjR1cmw6IFwiXHUxRUNEXHUwMzAwclx1MUVDRFx1MDMwMCBiYXNlNjR1cmxcIixcbiAgICAgICAganNvbl9zdHJpbmc6IFwiXHUxRUNEXHUwMzAwclx1MUVDRFx1MDMwMCBKU09OXCIsXG4gICAgICAgIGUxNjQ6IFwiblx1MUVDRFx1MDMwMW1iXHUwMEUwIEUuMTY0XCIsXG4gICAgICAgIGp3dDogXCJKV1RcIixcbiAgICAgICAgdGVtcGxhdGVfbGl0ZXJhbDogXCJcdTFFQjlcdTAzMDByXHUxRUNEIFx1MDBFQ2JcdTAwRTF3XHUxRUNEbFx1MDBFOVwiXG4gICAgfTtcbiAgICByZXR1cm4gKGlzc3VlKT0+e1xuICAgICAgICBzd2l0Y2goaXNzdWUuY29kZSl7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF90eXBlXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcdTAwQ0NiXHUwMEUxd1x1MUVDRGxcdTAwRTkgYVx1MUU2M1x1MDBFQ1x1MUU2M2U6IGEgblx1MDBFRCBsXHUwMEUxdGkgZmkgJHtpc3N1ZS5leHBlY3RlZH0sIFx1MDBFMG1cdTFFQ0RcdTAzMDAgYSByXHUwMEVEICR7cGFyc2VkVHlwZShpc3N1ZS5pbnB1dCl9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX3ZhbHVlXCI6XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLnZhbHVlcy5sZW5ndGggPT09IDEpIHJldHVybiBgXHUwMENDYlx1MDBFMXdcdTFFQ0RsXHUwMEU5IGFcdTFFNjNcdTAwRUNcdTFFNjNlOiBhIG5cdTAwRUQgbFx1MDBFMXRpIGZpICR7dXRpbC5zdHJpbmdpZnlQcmltaXRpdmUoaXNzdWUudmFsdWVzWzBdKX1gO1xuICAgICAgICAgICAgICAgIHJldHVybiBgXHUwMEMwXHUxRTYzXHUwMEUweVx1MDBFMG4gYVx1MUU2M1x1MDBFQ1x1MUU2M2U6IHlhbiBcdTFFQ0RcdTAzMDBrYW4gbFx1MDBFMXJhICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLnZhbHVlcywgXCJ8XCIpfWA7XG4gICAgICAgICAgICBjYXNlIFwidG9vX2JpZ1wiOlxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRqID0gaXNzdWUuaW5jbHVzaXZlID8gXCI8PVwiIDogXCI8XCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemluZyA9IGdldFNpemluZyhpc3N1ZS5vcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6aW5nKSByZXR1cm4gYFRcdTAwRjMgcFx1MUVDRFx1MDMwMCBqXHUwMEY5OiBhIG5cdTAwRUQgbFx1MDBFMXRpIGpcdTFFQjlcdTAzMDEgcFx1MDBFOSAke2lzc3VlLm9yaWdpbiA/PyBcIml5ZVwifSAke3NpemluZy52ZXJifSAke2Fkan0ke2lzc3VlLm1heGltdW19ICR7c2l6aW5nLnVuaXR9YDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBUXHUwMEYzIHBcdTFFQ0RcdTAzMDAgalx1MDBGOTogYSBuXHUwMEVEIGxcdTAwRTF0aSBqXHUxRUI5XHUwMzAxICR7YWRqfSR7aXNzdWUubWF4aW11bX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJ0b29fc21hbGxcIjpcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkaiA9IGlzc3VlLmluY2x1c2l2ZSA/IFwiPj1cIiA6IFwiPlwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXppbmcgPSBnZXRTaXppbmcoaXNzdWUub3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemluZykgcmV0dXJuIGBLXHUwMEU5clx1MDBFOSBqdTogYSBuXHUwMEVEIGxcdTAwRTF0aSBqXHUxRUI5XHUwMzAxIHBcdTAwRTkgJHtpc3N1ZS5vcmlnaW59ICR7c2l6aW5nLnZlcmJ9ICR7YWRqfSR7aXNzdWUubWluaW11bX0gJHtzaXppbmcudW5pdH1gO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYEtcdTAwRTlyXHUwMEU5IGp1OiBhIG5cdTAwRUQgbFx1MDBFMXRpIGpcdTFFQjlcdTAzMDEgJHthZGp9JHtpc3N1ZS5taW5pbXVtfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZm9ybWF0XCI6XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBfaXNzdWUgPSBpc3N1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwic3RhcnRzX3dpdGhcIikgcmV0dXJuIGBcdTFFQ0NcdTAzMDByXHUxRUNEXHUwMzAwIGFcdTFFNjNcdTAwRUNcdTFFNjNlOiBnYlx1MUVDRFx1MDMwMWRcdTFFQ0RcdTAzMDAgYlx1MUVCOVx1MDMwMHJcdTFFQjlcdTAzMDAgcFx1MUVCOVx1MDMwMGxcdTAwRkEgXCIke19pc3N1ZS5wcmVmaXh9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZvcm1hdCA9PT0gXCJlbmRzX3dpdGhcIikgcmV0dXJuIGBcdTFFQ0NcdTAzMDByXHUxRUNEXHUwMzAwIGFcdTFFNjNcdTAwRUNcdTFFNjNlOiBnYlx1MUVDRFx1MDMwMWRcdTFFQ0RcdTAzMDAgcGFyXHUwMEVEIHBcdTFFQjlcdTAzMDBsXHUwMEZBIFwiJHtfaXNzdWUuc3VmZml4fVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwiaW5jbHVkZXNcIikgcmV0dXJuIGBcdTFFQ0NcdTAzMDByXHUxRUNEXHUwMzAwIGFcdTFFNjNcdTAwRUNcdTFFNjNlOiBnYlx1MUVDRFx1MDMwMWRcdTFFQ0RcdTAzMDAgblx1MDBFRCBcIiR7X2lzc3VlLmluY2x1ZGVzfVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc3N1ZS5mb3JtYXQgPT09IFwicmVnZXhcIikgcmV0dXJuIGBcdTFFQ0NcdTAzMDByXHUxRUNEXHUwMzAwIGFcdTFFNjNcdTAwRUNcdTFFNjNlOiBnYlx1MUVDRFx1MDMwMWRcdTFFQ0RcdTAzMDAgYlx1MDBFMSBcdTAwRTBwXHUxRUI5XHUxRUI5clx1MUVCOSBtdSAke19pc3N1ZS5wYXR0ZXJufWA7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgQVx1MUU2M1x1MDBFQ1x1MUU2M2U6ICR7Tm91bnNbX2lzc3VlLmZvcm1hdF0gPz8gaXNzdWUuZm9ybWF0fWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIm5vdF9tdWx0aXBsZV9vZlwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgTlx1MUVDRFx1MDMwMW1iXHUwMEUwIGFcdTFFNjNcdTAwRUNcdTFFNjNlOiBnYlx1MUVDRFx1MDMwMWRcdTFFQ0RcdTAzMDAgalx1MUVCOVx1MDMwMSBcdTAwRTh5XHUwMEUwIHBcdTAwRURwXHUwMEVEbiB0aSAke2lzc3VlLmRpdmlzb3J9YDtcbiAgICAgICAgICAgIGNhc2UgXCJ1bnJlY29nbml6ZWRfa2V5c1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgQlx1MUVDRHRcdTAwRUNuXHUwMEVDIFx1MDBFMFx1MDBFQ21cdTFFQ0RcdTAzMDA6ICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLmtleXMsIFwiLCBcIil9YDtcbiAgICAgICAgICAgIGNhc2UgXCJpbnZhbGlkX2tleVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgQlx1MUVDRHRcdTAwRUNuXHUwMEVDIGFcdTFFNjNcdTAwRUNcdTFFNjNlIG5cdTAwRURuXHUwMEZBICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBjYXNlIFwiaW52YWxpZF91bmlvblwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBcIlx1MDBDQ2JcdTAwRTF3XHUxRUNEbFx1MDBFOSBhXHUxRTYzXHUwMEVDXHUxRTYzZVwiO1xuICAgICAgICAgICAgY2FzZSBcImludmFsaWRfZWxlbWVudFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBgSXllIGFcdTFFNjNcdTAwRUNcdTFFNjNlIG5cdTAwRURuXHUwMEZBICR7aXNzdWUub3JpZ2lufWA7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBcIlx1MDBDQ2JcdTAwRTF3XHUxRUNEbFx1MDBFOSBhXHUxRTYzXHUwMEVDXHUxRTYzZVwiO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBsb2NhbGVFcnJvcjogZXJyb3IoKVxuICAgIH07XG59XG4iLCAiZXhwb3J0IGNvbnN0ICRvdXRwdXQgPSBTeW1ib2woXCJab2RPdXRwdXRcIik7XG5leHBvcnQgY29uc3QgJGlucHV0ID0gU3ltYm9sKFwiWm9kSW5wdXRcIik7XG5leHBvcnQgY2xhc3MgJFpvZFJlZ2lzdHJ5IHtcbiAgICBjb25zdHJ1Y3Rvcigpe1xuICAgICAgICB0aGlzLl9tYXAgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICB0aGlzLl9pZG1hcCA9IG5ldyBNYXAoKTtcbiAgICB9XG4gICAgYWRkKHNjaGVtYSwgLi4uX21ldGEpIHtcbiAgICAgICAgY29uc3QgbWV0YSA9IF9tZXRhWzBdO1xuICAgICAgICB0aGlzLl9tYXAuc2V0KHNjaGVtYSwgbWV0YSk7XG4gICAgICAgIGlmIChtZXRhICYmIHR5cGVvZiBtZXRhID09PSBcIm9iamVjdFwiICYmIFwiaWRcIiBpbiBtZXRhKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5faWRtYXAuaGFzKG1ldGEuaWQpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJRCAke21ldGEuaWR9IGFscmVhZHkgZXhpc3RzIGluIHRoZSByZWdpc3RyeWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5faWRtYXAuc2V0KG1ldGEuaWQsIHNjaGVtYSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGNsZWFyKCkge1xuICAgICAgICB0aGlzLl9tYXAgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICB0aGlzLl9pZG1hcCA9IG5ldyBNYXAoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHJlbW92ZShzY2hlbWEpIHtcbiAgICAgICAgY29uc3QgbWV0YSA9IHRoaXMuX21hcC5nZXQoc2NoZW1hKTtcbiAgICAgICAgaWYgKG1ldGEgJiYgdHlwZW9mIG1ldGEgPT09IFwib2JqZWN0XCIgJiYgXCJpZFwiIGluIG1ldGEpIHtcbiAgICAgICAgICAgIHRoaXMuX2lkbWFwLmRlbGV0ZShtZXRhLmlkKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9tYXAuZGVsZXRlKHNjaGVtYSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBnZXQoc2NoZW1hKSB7XG4gICAgICAgIC8vIHJldHVybiB0aGlzLl9tYXAuZ2V0KHNjaGVtYSkgYXMgYW55O1xuICAgICAgICAvLyBpbmhlcml0IG1ldGFkYXRhXG4gICAgICAgIGNvbnN0IHAgPSBzY2hlbWEuX3pvZC5wYXJlbnQ7XG4gICAgICAgIGlmIChwKSB7XG4gICAgICAgICAgICBjb25zdCBwbSA9IHtcbiAgICAgICAgICAgICAgICAuLi50aGlzLmdldChwKSA/PyB7fVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGRlbGV0ZSBwbS5pZDsgLy8gZG8gbm90IGluaGVyaXQgaWRcbiAgICAgICAgICAgIGNvbnN0IGYgPSB7XG4gICAgICAgICAgICAgICAgLi4ucG0sXG4gICAgICAgICAgICAgICAgLi4udGhpcy5fbWFwLmdldChzY2hlbWEpXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKGYpLmxlbmd0aCA/IGYgOiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX21hcC5nZXQoc2NoZW1hKTtcbiAgICB9XG4gICAgaGFzKHNjaGVtYSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWFwLmhhcyhzY2hlbWEpO1xuICAgIH1cbn1cbi8vIHJlZ2lzdHJpZXNcbmV4cG9ydCBmdW5jdGlvbiByZWdpc3RyeSgpIHtcbiAgICByZXR1cm4gbmV3ICRab2RSZWdpc3RyeSgpO1xufVxuZXhwb3J0IGNvbnN0IGdsb2JhbFJlZ2lzdHJ5ID0gLypAX19QVVJFX18qLyByZWdpc3RyeSgpO1xuIiwgImltcG9ydCAqIGFzIGNoZWNrcyBmcm9tIFwiLi9jaGVja3MuanNcIjtcbmltcG9ydCAqIGFzIHNjaGVtYXMgZnJvbSBcIi4vc2NoZW1hcy5qc1wiO1xuaW1wb3J0ICogYXMgdXRpbCBmcm9tIFwiLi91dGlsLmpzXCI7XG5leHBvcnQgZnVuY3Rpb24gX3N0cmluZyhDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfY29lcmNlZFN0cmluZyhDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgIGNvZXJjZTogdHJ1ZSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9lbWFpbChDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgIGZvcm1hdDogXCJlbWFpbFwiLFxuICAgICAgICBjaGVjazogXCJzdHJpbmdfZm9ybWF0XCIsXG4gICAgICAgIGFib3J0OiBmYWxzZSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9ndWlkKENsYXNzLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgZm9ybWF0OiBcImd1aWRcIixcbiAgICAgICAgY2hlY2s6IFwic3RyaW5nX2Zvcm1hdFwiLFxuICAgICAgICBhYm9ydDogZmFsc2UsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfdXVpZChDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgIGZvcm1hdDogXCJ1dWlkXCIsXG4gICAgICAgIGNoZWNrOiBcInN0cmluZ19mb3JtYXRcIixcbiAgICAgICAgYWJvcnQ6IGZhbHNlLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX3V1aWR2NChDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgIGZvcm1hdDogXCJ1dWlkXCIsXG4gICAgICAgIGNoZWNrOiBcInN0cmluZ19mb3JtYXRcIixcbiAgICAgICAgYWJvcnQ6IGZhbHNlLFxuICAgICAgICB2ZXJzaW9uOiBcInY0XCIsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfdXVpZHY2KENsYXNzLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgZm9ybWF0OiBcInV1aWRcIixcbiAgICAgICAgY2hlY2s6IFwic3RyaW5nX2Zvcm1hdFwiLFxuICAgICAgICBhYm9ydDogZmFsc2UsXG4gICAgICAgIHZlcnNpb246IFwidjZcIixcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF91dWlkdjcoQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICBmb3JtYXQ6IFwidXVpZFwiLFxuICAgICAgICBjaGVjazogXCJzdHJpbmdfZm9ybWF0XCIsXG4gICAgICAgIGFib3J0OiBmYWxzZSxcbiAgICAgICAgdmVyc2lvbjogXCJ2N1wiLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX3VybChDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgIGZvcm1hdDogXCJ1cmxcIixcbiAgICAgICAgY2hlY2s6IFwic3RyaW5nX2Zvcm1hdFwiLFxuICAgICAgICBhYm9ydDogZmFsc2UsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfZW1vamkoQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICBmb3JtYXQ6IFwiZW1vamlcIixcbiAgICAgICAgY2hlY2s6IFwic3RyaW5nX2Zvcm1hdFwiLFxuICAgICAgICBhYm9ydDogZmFsc2UsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfbmFub2lkKENsYXNzLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgZm9ybWF0OiBcIm5hbm9pZFwiLFxuICAgICAgICBjaGVjazogXCJzdHJpbmdfZm9ybWF0XCIsXG4gICAgICAgIGFib3J0OiBmYWxzZSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9jdWlkKENsYXNzLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgZm9ybWF0OiBcImN1aWRcIixcbiAgICAgICAgY2hlY2s6IFwic3RyaW5nX2Zvcm1hdFwiLFxuICAgICAgICBhYm9ydDogZmFsc2UsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfY3VpZDIoQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICBmb3JtYXQ6IFwiY3VpZDJcIixcbiAgICAgICAgY2hlY2s6IFwic3RyaW5nX2Zvcm1hdFwiLFxuICAgICAgICBhYm9ydDogZmFsc2UsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfdWxpZChDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgIGZvcm1hdDogXCJ1bGlkXCIsXG4gICAgICAgIGNoZWNrOiBcInN0cmluZ19mb3JtYXRcIixcbiAgICAgICAgYWJvcnQ6IGZhbHNlLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX3hpZChDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgIGZvcm1hdDogXCJ4aWRcIixcbiAgICAgICAgY2hlY2s6IFwic3RyaW5nX2Zvcm1hdFwiLFxuICAgICAgICBhYm9ydDogZmFsc2UsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfa3N1aWQoQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICBmb3JtYXQ6IFwia3N1aWRcIixcbiAgICAgICAgY2hlY2s6IFwic3RyaW5nX2Zvcm1hdFwiLFxuICAgICAgICBhYm9ydDogZmFsc2UsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfaXB2NChDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgIGZvcm1hdDogXCJpcHY0XCIsXG4gICAgICAgIGNoZWNrOiBcInN0cmluZ19mb3JtYXRcIixcbiAgICAgICAgYWJvcnQ6IGZhbHNlLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX2lwdjYoQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICBmb3JtYXQ6IFwiaXB2NlwiLFxuICAgICAgICBjaGVjazogXCJzdHJpbmdfZm9ybWF0XCIsXG4gICAgICAgIGFib3J0OiBmYWxzZSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9jaWRydjQoQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICBmb3JtYXQ6IFwiY2lkcnY0XCIsXG4gICAgICAgIGNoZWNrOiBcInN0cmluZ19mb3JtYXRcIixcbiAgICAgICAgYWJvcnQ6IGZhbHNlLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX2NpZHJ2NihDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgIGZvcm1hdDogXCJjaWRydjZcIixcbiAgICAgICAgY2hlY2s6IFwic3RyaW5nX2Zvcm1hdFwiLFxuICAgICAgICBhYm9ydDogZmFsc2UsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfYmFzZTY0KENsYXNzLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgZm9ybWF0OiBcImJhc2U2NFwiLFxuICAgICAgICBjaGVjazogXCJzdHJpbmdfZm9ybWF0XCIsXG4gICAgICAgIGFib3J0OiBmYWxzZSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9iYXNlNjR1cmwoQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICBmb3JtYXQ6IFwiYmFzZTY0dXJsXCIsXG4gICAgICAgIGNoZWNrOiBcInN0cmluZ19mb3JtYXRcIixcbiAgICAgICAgYWJvcnQ6IGZhbHNlLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX2UxNjQoQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICBmb3JtYXQ6IFwiZTE2NFwiLFxuICAgICAgICBjaGVjazogXCJzdHJpbmdfZm9ybWF0XCIsXG4gICAgICAgIGFib3J0OiBmYWxzZSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9qd3QoQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICBmb3JtYXQ6IFwiand0XCIsXG4gICAgICAgIGNoZWNrOiBcInN0cmluZ19mb3JtYXRcIixcbiAgICAgICAgYWJvcnQ6IGZhbHNlLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgY29uc3QgVGltZVByZWNpc2lvbiA9IHtcbiAgICBBbnk6IG51bGwsXG4gICAgTWludXRlOiAtMSxcbiAgICBTZWNvbmQ6IDAsXG4gICAgTWlsbGlzZWNvbmQ6IDMsXG4gICAgTWljcm9zZWNvbmQ6IDZcbn07XG5leHBvcnQgZnVuY3Rpb24gX2lzb0RhdGVUaW1lKENsYXNzLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgZm9ybWF0OiBcImRhdGV0aW1lXCIsXG4gICAgICAgIGNoZWNrOiBcInN0cmluZ19mb3JtYXRcIixcbiAgICAgICAgb2Zmc2V0OiBmYWxzZSxcbiAgICAgICAgbG9jYWw6IGZhbHNlLFxuICAgICAgICBwcmVjaXNpb246IG51bGwsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfaXNvRGF0ZShDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgIGZvcm1hdDogXCJkYXRlXCIsXG4gICAgICAgIGNoZWNrOiBcInN0cmluZ19mb3JtYXRcIixcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9pc29UaW1lKENsYXNzLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgZm9ybWF0OiBcInRpbWVcIixcbiAgICAgICAgY2hlY2s6IFwic3RyaW5nX2Zvcm1hdFwiLFxuICAgICAgICBwcmVjaXNpb246IG51bGwsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfaXNvRHVyYXRpb24oQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICBmb3JtYXQ6IFwiZHVyYXRpb25cIixcbiAgICAgICAgY2hlY2s6IFwic3RyaW5nX2Zvcm1hdFwiLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX251bWJlcihDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwibnVtYmVyXCIsXG4gICAgICAgIGNoZWNrczogW10sXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfY29lcmNlZE51bWJlcihDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwibnVtYmVyXCIsXG4gICAgICAgIGNvZXJjZTogdHJ1ZSxcbiAgICAgICAgY2hlY2tzOiBbXSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9pbnQoQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcIm51bWJlclwiLFxuICAgICAgICBjaGVjazogXCJudW1iZXJfZm9ybWF0XCIsXG4gICAgICAgIGFib3J0OiBmYWxzZSxcbiAgICAgICAgZm9ybWF0OiBcInNhZmVpbnRcIixcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9mbG9hdDMyKENsYXNzLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJudW1iZXJcIixcbiAgICAgICAgY2hlY2s6IFwibnVtYmVyX2Zvcm1hdFwiLFxuICAgICAgICBhYm9ydDogZmFsc2UsXG4gICAgICAgIGZvcm1hdDogXCJmbG9hdDMyXCIsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfZmxvYXQ2NChDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwibnVtYmVyXCIsXG4gICAgICAgIGNoZWNrOiBcIm51bWJlcl9mb3JtYXRcIixcbiAgICAgICAgYWJvcnQ6IGZhbHNlLFxuICAgICAgICBmb3JtYXQ6IFwiZmxvYXQ2NFwiLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX2ludDMyKENsYXNzLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJudW1iZXJcIixcbiAgICAgICAgY2hlY2s6IFwibnVtYmVyX2Zvcm1hdFwiLFxuICAgICAgICBhYm9ydDogZmFsc2UsXG4gICAgICAgIGZvcm1hdDogXCJpbnQzMlwiLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX3VpbnQzMihDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwibnVtYmVyXCIsXG4gICAgICAgIGNoZWNrOiBcIm51bWJlcl9mb3JtYXRcIixcbiAgICAgICAgYWJvcnQ6IGZhbHNlLFxuICAgICAgICBmb3JtYXQ6IFwidWludDMyXCIsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfYm9vbGVhbihDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwiYm9vbGVhblwiLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX2NvZXJjZWRCb29sZWFuKENsYXNzLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJib29sZWFuXCIsXG4gICAgICAgIGNvZXJjZTogdHJ1ZSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9iaWdpbnQoQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcImJpZ2ludFwiLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX2NvZXJjZWRCaWdpbnQoQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcImJpZ2ludFwiLFxuICAgICAgICBjb2VyY2U6IHRydWUsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfaW50NjQoQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcImJpZ2ludFwiLFxuICAgICAgICBjaGVjazogXCJiaWdpbnRfZm9ybWF0XCIsXG4gICAgICAgIGFib3J0OiBmYWxzZSxcbiAgICAgICAgZm9ybWF0OiBcImludDY0XCIsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfdWludDY0KENsYXNzLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJiaWdpbnRcIixcbiAgICAgICAgY2hlY2s6IFwiYmlnaW50X2Zvcm1hdFwiLFxuICAgICAgICBhYm9ydDogZmFsc2UsXG4gICAgICAgIGZvcm1hdDogXCJ1aW50NjRcIixcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9zeW1ib2woQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcInN5bWJvbFwiLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX3VuZGVmaW5lZChDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwidW5kZWZpbmVkXCIsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfbnVsbChDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwibnVsbFwiLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX2FueShDbGFzcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcImFueVwiXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX3Vua25vd24oQ2xhc3MpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJ1bmtub3duXCJcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfbmV2ZXIoQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcIm5ldmVyXCIsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfdm9pZChDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwidm9pZFwiLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX2RhdGUoQ2xhc3MsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcImRhdGVcIixcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9jb2VyY2VkRGF0ZShDbGFzcywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwiZGF0ZVwiLFxuICAgICAgICBjb2VyY2U6IHRydWUsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfbmFuKENsYXNzLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJuYW5cIixcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9sdCh2YWx1ZSwgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBjaGVja3MuJFpvZENoZWNrTGVzc1RoYW4oe1xuICAgICAgICBjaGVjazogXCJsZXNzX3RoYW5cIixcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKSxcbiAgICAgICAgdmFsdWUsXG4gICAgICAgIGluY2x1c2l2ZTogZmFsc2VcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfbHRlKHZhbHVlLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IGNoZWNrcy4kWm9kQ2hlY2tMZXNzVGhhbih7XG4gICAgICAgIGNoZWNrOiBcImxlc3NfdGhhblwiLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpLFxuICAgICAgICB2YWx1ZSxcbiAgICAgICAgaW5jbHVzaXZlOiB0cnVlXG4gICAgfSk7XG59XG5leHBvcnQgeyAvKiogQGRlcHJlY2F0ZWQgVXNlIGB6Lmx0ZSgpYCBpbnN0ZWFkLiAqLyBfbHRlIGFzIF9tYXggfTtcbmV4cG9ydCBmdW5jdGlvbiBfZ3QodmFsdWUsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgY2hlY2tzLiRab2RDaGVja0dyZWF0ZXJUaGFuKHtcbiAgICAgICAgY2hlY2s6IFwiZ3JlYXRlcl90aGFuXCIsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcyksXG4gICAgICAgIHZhbHVlLFxuICAgICAgICBpbmNsdXNpdmU6IGZhbHNlXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX2d0ZSh2YWx1ZSwgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBjaGVja3MuJFpvZENoZWNrR3JlYXRlclRoYW4oe1xuICAgICAgICBjaGVjazogXCJncmVhdGVyX3RoYW5cIixcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKSxcbiAgICAgICAgdmFsdWUsXG4gICAgICAgIGluY2x1c2l2ZTogdHJ1ZVxuICAgIH0pO1xufVxuZXhwb3J0IHsgLyoqIEBkZXByZWNhdGVkIFVzZSBgei5ndGUoKWAgaW5zdGVhZC4gKi8gX2d0ZSBhcyBfbWluIH07XG5leHBvcnQgZnVuY3Rpb24gX3Bvc2l0aXZlKHBhcmFtcykge1xuICAgIHJldHVybiBfZ3QoMCwgcGFyYW1zKTtcbn1cbi8vIG5lZ2F0aXZlXG5leHBvcnQgZnVuY3Rpb24gX25lZ2F0aXZlKHBhcmFtcykge1xuICAgIHJldHVybiBfbHQoMCwgcGFyYW1zKTtcbn1cbi8vIG5vbnBvc2l0aXZlXG5leHBvcnQgZnVuY3Rpb24gX25vbnBvc2l0aXZlKHBhcmFtcykge1xuICAgIHJldHVybiBfbHRlKDAsIHBhcmFtcyk7XG59XG4vLyBub25uZWdhdGl2ZVxuZXhwb3J0IGZ1bmN0aW9uIF9ub25uZWdhdGl2ZShwYXJhbXMpIHtcbiAgICByZXR1cm4gX2d0ZSgwLCBwYXJhbXMpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9tdWx0aXBsZU9mKHZhbHVlLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IGNoZWNrcy4kWm9kQ2hlY2tNdWx0aXBsZU9mKHtcbiAgICAgICAgY2hlY2s6IFwibXVsdGlwbGVfb2ZcIixcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKSxcbiAgICAgICAgdmFsdWVcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfbWF4U2l6ZShtYXhpbXVtLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IGNoZWNrcy4kWm9kQ2hlY2tNYXhTaXplKHtcbiAgICAgICAgY2hlY2s6IFwibWF4X3NpemVcIixcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKSxcbiAgICAgICAgbWF4aW11bVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9taW5TaXplKG1pbmltdW0sIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgY2hlY2tzLiRab2RDaGVja01pblNpemUoe1xuICAgICAgICBjaGVjazogXCJtaW5fc2l6ZVwiLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpLFxuICAgICAgICBtaW5pbXVtXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX3NpemUoc2l6ZSwgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBjaGVja3MuJFpvZENoZWNrU2l6ZUVxdWFscyh7XG4gICAgICAgIGNoZWNrOiBcInNpemVfZXF1YWxzXCIsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcyksXG4gICAgICAgIHNpemVcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfbWF4TGVuZ3RoKG1heGltdW0sIHBhcmFtcykge1xuICAgIGNvbnN0IGNoID0gbmV3IGNoZWNrcy4kWm9kQ2hlY2tNYXhMZW5ndGgoe1xuICAgICAgICBjaGVjazogXCJtYXhfbGVuZ3RoXCIsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcyksXG4gICAgICAgIG1heGltdW1cbiAgICB9KTtcbiAgICByZXR1cm4gY2g7XG59XG5leHBvcnQgZnVuY3Rpb24gX21pbkxlbmd0aChtaW5pbXVtLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IGNoZWNrcy4kWm9kQ2hlY2tNaW5MZW5ndGgoe1xuICAgICAgICBjaGVjazogXCJtaW5fbGVuZ3RoXCIsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcyksXG4gICAgICAgIG1pbmltdW1cbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfbGVuZ3RoKGxlbmd0aCwgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBjaGVja3MuJFpvZENoZWNrTGVuZ3RoRXF1YWxzKHtcbiAgICAgICAgY2hlY2s6IFwibGVuZ3RoX2VxdWFsc1wiLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpLFxuICAgICAgICBsZW5ndGhcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfcmVnZXgocGF0dGVybiwgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBjaGVja3MuJFpvZENoZWNrUmVnZXgoe1xuICAgICAgICBjaGVjazogXCJzdHJpbmdfZm9ybWF0XCIsXG4gICAgICAgIGZvcm1hdDogXCJyZWdleFwiLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpLFxuICAgICAgICBwYXR0ZXJuXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX2xvd2VyY2FzZShwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IGNoZWNrcy4kWm9kQ2hlY2tMb3dlckNhc2Uoe1xuICAgICAgICBjaGVjazogXCJzdHJpbmdfZm9ybWF0XCIsXG4gICAgICAgIGZvcm1hdDogXCJsb3dlcmNhc2VcIixcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF91cHBlcmNhc2UocGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBjaGVja3MuJFpvZENoZWNrVXBwZXJDYXNlKHtcbiAgICAgICAgY2hlY2s6IFwic3RyaW5nX2Zvcm1hdFwiLFxuICAgICAgICBmb3JtYXQ6IFwidXBwZXJjYXNlXCIsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfaW5jbHVkZXMoaW5jbHVkZXMsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgY2hlY2tzLiRab2RDaGVja0luY2x1ZGVzKHtcbiAgICAgICAgY2hlY2s6IFwic3RyaW5nX2Zvcm1hdFwiLFxuICAgICAgICBmb3JtYXQ6IFwiaW5jbHVkZXNcIixcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKSxcbiAgICAgICAgaW5jbHVkZXNcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfc3RhcnRzV2l0aChwcmVmaXgsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgY2hlY2tzLiRab2RDaGVja1N0YXJ0c1dpdGgoe1xuICAgICAgICBjaGVjazogXCJzdHJpbmdfZm9ybWF0XCIsXG4gICAgICAgIGZvcm1hdDogXCJzdGFydHNfd2l0aFwiLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpLFxuICAgICAgICBwcmVmaXhcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfZW5kc1dpdGgoc3VmZml4LCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IGNoZWNrcy4kWm9kQ2hlY2tFbmRzV2l0aCh7XG4gICAgICAgIGNoZWNrOiBcInN0cmluZ19mb3JtYXRcIixcbiAgICAgICAgZm9ybWF0OiBcImVuZHNfd2l0aFwiLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpLFxuICAgICAgICBzdWZmaXhcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfcHJvcGVydHkocHJvcGVydHksIHNjaGVtYSwgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBjaGVja3MuJFpvZENoZWNrUHJvcGVydHkoe1xuICAgICAgICBjaGVjazogXCJwcm9wZXJ0eVwiLFxuICAgICAgICBwcm9wZXJ0eSxcbiAgICAgICAgc2NoZW1hLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX21pbWUodHlwZXMsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgY2hlY2tzLiRab2RDaGVja01pbWVUeXBlKHtcbiAgICAgICAgY2hlY2s6IFwibWltZV90eXBlXCIsXG4gICAgICAgIG1pbWU6IHR5cGVzLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX292ZXJ3cml0ZSh0eCkge1xuICAgIHJldHVybiBuZXcgY2hlY2tzLiRab2RDaGVja092ZXJ3cml0ZSh7XG4gICAgICAgIGNoZWNrOiBcIm92ZXJ3cml0ZVwiLFxuICAgICAgICB0eFxuICAgIH0pO1xufVxuLy8gbm9ybWFsaXplXG5leHBvcnQgZnVuY3Rpb24gX25vcm1hbGl6ZShmb3JtKSB7XG4gICAgcmV0dXJuIF9vdmVyd3JpdGUoKGlucHV0KT0+aW5wdXQubm9ybWFsaXplKGZvcm0pKTtcbn1cbi8vIHRyaW1cbmV4cG9ydCBmdW5jdGlvbiBfdHJpbSgpIHtcbiAgICByZXR1cm4gX292ZXJ3cml0ZSgoaW5wdXQpPT5pbnB1dC50cmltKCkpO1xufVxuLy8gdG9Mb3dlckNhc2VcbmV4cG9ydCBmdW5jdGlvbiBfdG9Mb3dlckNhc2UoKSB7XG4gICAgcmV0dXJuIF9vdmVyd3JpdGUoKGlucHV0KT0+aW5wdXQudG9Mb3dlckNhc2UoKSk7XG59XG4vLyB0b1VwcGVyQ2FzZVxuZXhwb3J0IGZ1bmN0aW9uIF90b1VwcGVyQ2FzZSgpIHtcbiAgICByZXR1cm4gX292ZXJ3cml0ZSgoaW5wdXQpPT5pbnB1dC50b1VwcGVyQ2FzZSgpKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfYXJyYXkoQ2xhc3MsIGVsZW1lbnQsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcImFycmF5XCIsXG4gICAgICAgIGVsZW1lbnQsXG4gICAgICAgIC8vIGdldCBlbGVtZW50KCkge1xuICAgICAgICAvLyAgIHJldHVybiBlbGVtZW50O1xuICAgICAgICAvLyB9LFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX3VuaW9uKENsYXNzLCBvcHRpb25zLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJ1bmlvblwiLFxuICAgICAgICBvcHRpb25zLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX2Rpc2NyaW1pbmF0ZWRVbmlvbihDbGFzcywgZGlzY3JpbWluYXRvciwgb3B0aW9ucywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwidW5pb25cIixcbiAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgZGlzY3JpbWluYXRvcixcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9pbnRlcnNlY3Rpb24oQ2xhc3MsIGxlZnQsIHJpZ2h0KSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwiaW50ZXJzZWN0aW9uXCIsXG4gICAgICAgIGxlZnQsXG4gICAgICAgIHJpZ2h0XG4gICAgfSk7XG59XG4vLyBleHBvcnQgZnVuY3Rpb24gX3R1cGxlKFxuLy8gICBDbGFzczogdXRpbC5TY2hlbWFDbGFzczxzY2hlbWFzLiRab2RUdXBsZT4sXG4vLyAgIGl0ZW1zOiBbXSxcbi8vICAgcGFyYW1zPzogc3RyaW5nIHwgJFpvZFR1cGxlUGFyYW1zXG4vLyApOiBzY2hlbWFzLiRab2RUdXBsZTxbXSwgbnVsbD47XG5leHBvcnQgZnVuY3Rpb24gX3R1cGxlKENsYXNzLCBpdGVtcywgX3BhcmFtc09yUmVzdCwgX3BhcmFtcykge1xuICAgIGNvbnN0IGhhc1Jlc3QgPSBfcGFyYW1zT3JSZXN0IGluc3RhbmNlb2Ygc2NoZW1hcy4kWm9kVHlwZTtcbiAgICBjb25zdCBwYXJhbXMgPSBoYXNSZXN0ID8gX3BhcmFtcyA6IF9wYXJhbXNPclJlc3Q7XG4gICAgY29uc3QgcmVzdCA9IGhhc1Jlc3QgPyBfcGFyYW1zT3JSZXN0IDogbnVsbDtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJ0dXBsZVwiLFxuICAgICAgICBpdGVtcyxcbiAgICAgICAgcmVzdCxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9yZWNvcmQoQ2xhc3MsIGtleVR5cGUsIHZhbHVlVHlwZSwgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwicmVjb3JkXCIsXG4gICAgICAgIGtleVR5cGUsXG4gICAgICAgIHZhbHVlVHlwZSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9tYXAoQ2xhc3MsIGtleVR5cGUsIHZhbHVlVHlwZSwgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwibWFwXCIsXG4gICAgICAgIGtleVR5cGUsXG4gICAgICAgIHZhbHVlVHlwZSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9zZXQoQ2xhc3MsIHZhbHVlVHlwZSwgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwic2V0XCIsXG4gICAgICAgIHZhbHVlVHlwZSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9lbnVtKENsYXNzLCB2YWx1ZXMsIHBhcmFtcykge1xuICAgIGNvbnN0IGVudHJpZXMgPSBBcnJheS5pc0FycmF5KHZhbHVlcykgPyBPYmplY3QuZnJvbUVudHJpZXModmFsdWVzLm1hcCgodik9PltcbiAgICAgICAgICAgIHYsXG4gICAgICAgICAgICB2XG4gICAgICAgIF0pKSA6IHZhbHVlcztcbiAgICAvLyBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZXMpKSB7XG4gICAgLy8gICBmb3IgKGNvbnN0IHZhbHVlIG9mIHZhbHVlcykge1xuICAgIC8vICAgICBlbnRyaWVzW3ZhbHVlXSA9IHZhbHVlO1xuICAgIC8vICAgfVxuICAgIC8vIH0gZWxzZSB7XG4gICAgLy8gICBPYmplY3QuYXNzaWduKGVudHJpZXMsIHZhbHVlcyk7XG4gICAgLy8gfVxuICAgIC8vIGNvbnN0IGVudHJpZXM6IHV0aWwuRW51bUxpa2UgPSB7fTtcbiAgICAvLyBmb3IgKGNvbnN0IHZhbCBvZiB2YWx1ZXMpIHtcbiAgICAvLyAgIGVudHJpZXNbdmFsXSA9IHZhbDtcbiAgICAvLyB9XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwiZW51bVwiLFxuICAgICAgICBlbnRyaWVzLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG4vKiogQGRlcHJlY2F0ZWQgVGhpcyBBUEkgaGFzIGJlZW4gbWVyZ2VkIGludG8gYHouZW51bSgpYC4gVXNlIGB6LmVudW0oKWAgaW5zdGVhZC5cbiAqXG4gKiBgYGB0c1xuICogZW51bSBDb2xvcnMgeyByZWQsIGdyZWVuLCBibHVlIH1cbiAqIHouZW51bShDb2xvcnMpO1xuICogYGBgXG4gKi8gZXhwb3J0IGZ1bmN0aW9uIF9uYXRpdmVFbnVtKENsYXNzLCBlbnRyaWVzLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJlbnVtXCIsXG4gICAgICAgIGVudHJpZXMsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfbGl0ZXJhbChDbGFzcywgdmFsdWUsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcImxpdGVyYWxcIixcbiAgICAgICAgdmFsdWVzOiBBcnJheS5pc0FycmF5KHZhbHVlKSA/IHZhbHVlIDogW1xuICAgICAgICAgICAgdmFsdWVcbiAgICAgICAgXSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9maWxlKENsYXNzLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJmaWxlXCIsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfdHJhbnNmb3JtKENsYXNzLCBmbikge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcInRyYW5zZm9ybVwiLFxuICAgICAgICB0cmFuc2Zvcm06IGZuXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX29wdGlvbmFsKENsYXNzLCBpbm5lclR5cGUpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJvcHRpb25hbFwiLFxuICAgICAgICBpbm5lclR5cGVcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfbnVsbGFibGUoQ2xhc3MsIGlubmVyVHlwZSkge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcIm51bGxhYmxlXCIsXG4gICAgICAgIGlubmVyVHlwZVxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9kZWZhdWx0KENsYXNzLCBpbm5lclR5cGUsIGRlZmF1bHRWYWx1ZSkge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcImRlZmF1bHRcIixcbiAgICAgICAgaW5uZXJUeXBlLFxuICAgICAgICBnZXQgZGVmYXVsdFZhbHVlICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0eXBlb2YgZGVmYXVsdFZhbHVlID09PSBcImZ1bmN0aW9uXCIgPyBkZWZhdWx0VmFsdWUoKSA6IHV0aWwuc2hhbGxvd0Nsb25lKGRlZmF1bHRWYWx1ZSk7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfbm9ub3B0aW9uYWwoQ2xhc3MsIGlubmVyVHlwZSwgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwibm9ub3B0aW9uYWxcIixcbiAgICAgICAgaW5uZXJUeXBlLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX3N1Y2Nlc3MoQ2xhc3MsIGlubmVyVHlwZSkge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcInN1Y2Nlc3NcIixcbiAgICAgICAgaW5uZXJUeXBlXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX2NhdGNoKENsYXNzLCBpbm5lclR5cGUsIGNhdGNoVmFsdWUpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJjYXRjaFwiLFxuICAgICAgICBpbm5lclR5cGUsXG4gICAgICAgIGNhdGNoVmFsdWU6IHR5cGVvZiBjYXRjaFZhbHVlID09PSBcImZ1bmN0aW9uXCIgPyBjYXRjaFZhbHVlIDogKCk9PmNhdGNoVmFsdWVcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfcGlwZShDbGFzcywgaW5fLCBvdXQpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzKHtcbiAgICAgICAgdHlwZTogXCJwaXBlXCIsXG4gICAgICAgIGluOiBpbl8sXG4gICAgICAgIG91dFxuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIF9yZWFkb25seShDbGFzcywgaW5uZXJUeXBlKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwicmVhZG9ubHlcIixcbiAgICAgICAgaW5uZXJUeXBlXG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gX3RlbXBsYXRlTGl0ZXJhbChDbGFzcywgcGFydHMsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcInRlbXBsYXRlX2xpdGVyYWxcIixcbiAgICAgICAgcGFydHMsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfbGF6eShDbGFzcywgZ2V0dGVyKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwibGF6eVwiLFxuICAgICAgICBnZXR0ZXJcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfcHJvbWlzZShDbGFzcywgaW5uZXJUeXBlKSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwicHJvbWlzZVwiLFxuICAgICAgICBpbm5lclR5cGVcbiAgICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfY3VzdG9tKENsYXNzLCBmbiwgX3BhcmFtcykge1xuICAgIGNvbnN0IG5vcm0gPSB1dGlsLm5vcm1hbGl6ZVBhcmFtcyhfcGFyYW1zKTtcbiAgICBub3JtLmFib3J0ID8/IChub3JtLmFib3J0ID0gdHJ1ZSk7IC8vIGRlZmF1bHQgdG8gYWJvcnQ6ZmFsc2VcbiAgICBjb25zdCBzY2hlbWEgPSBuZXcgQ2xhc3Moe1xuICAgICAgICB0eXBlOiBcImN1c3RvbVwiLFxuICAgICAgICBjaGVjazogXCJjdXN0b21cIixcbiAgICAgICAgZm46IGZuLFxuICAgICAgICAuLi5ub3JtXG4gICAgfSk7XG4gICAgcmV0dXJuIHNjaGVtYTtcbn1cbi8vIHNhbWUgYXMgX2N1c3RvbSBidXQgZGVmYXVsdHMgdG8gYWJvcnQ6ZmFsc2VcbmV4cG9ydCBmdW5jdGlvbiBfcmVmaW5lKENsYXNzLCBmbiwgX3BhcmFtcykge1xuICAgIGNvbnN0IHNjaGVtYSA9IG5ldyBDbGFzcyh7XG4gICAgICAgIHR5cGU6IFwiY3VzdG9tXCIsXG4gICAgICAgIGNoZWNrOiBcImN1c3RvbVwiLFxuICAgICAgICBmbjogZm4sXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKF9wYXJhbXMpXG4gICAgfSk7XG4gICAgcmV0dXJuIHNjaGVtYTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfc3VwZXJSZWZpbmUoZm4pIHtcbiAgICBjb25zdCBjaCA9IF9jaGVjaygocGF5bG9hZCk9PntcbiAgICAgICAgcGF5bG9hZC5hZGRJc3N1ZSA9IChpc3N1ZSk9PntcbiAgICAgICAgICAgIGlmICh0eXBlb2YgaXNzdWUgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHV0aWwuaXNzdWUoaXNzdWUsIHBheWxvYWQudmFsdWUsIGNoLl96b2QuZGVmKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIGZvciBab2QgMyBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eVxuICAgICAgICAgICAgICAgIGNvbnN0IF9pc3N1ZSA9IGlzc3VlO1xuICAgICAgICAgICAgICAgIGlmIChfaXNzdWUuZmF0YWwpIF9pc3N1ZS5jb250aW51ZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIF9pc3N1ZS5jb2RlID8/IChfaXNzdWUuY29kZSA9IFwiY3VzdG9tXCIpO1xuICAgICAgICAgICAgICAgIF9pc3N1ZS5pbnB1dCA/PyAoX2lzc3VlLmlucHV0ID0gcGF5bG9hZC52YWx1ZSk7XG4gICAgICAgICAgICAgICAgX2lzc3VlLmluc3QgPz8gKF9pc3N1ZS5pbnN0ID0gY2gpO1xuICAgICAgICAgICAgICAgIF9pc3N1ZS5jb250aW51ZSA/PyAoX2lzc3VlLmNvbnRpbnVlID0gIWNoLl96b2QuZGVmLmFib3J0KTsgLy8gYWJvcnQgaXMgYWx3YXlzIHVuZGVmaW5lZCwgc28gdGhpcyBpcyBhbHdheXMgdHJ1ZS4uLlxuICAgICAgICAgICAgICAgIHBheWxvYWQuaXNzdWVzLnB1c2godXRpbC5pc3N1ZShfaXNzdWUpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIGZuKHBheWxvYWQudmFsdWUsIHBheWxvYWQpO1xuICAgIH0pO1xuICAgIHJldHVybiBjaDtcbn1cbmV4cG9ydCBmdW5jdGlvbiBfY2hlY2soZm4sIHBhcmFtcykge1xuICAgIGNvbnN0IGNoID0gbmV3IGNoZWNrcy4kWm9kQ2hlY2soe1xuICAgICAgICBjaGVjazogXCJjdXN0b21cIixcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xuICAgIGNoLl96b2QuY2hlY2sgPSBmbjtcbiAgICByZXR1cm4gY2g7XG59XG5leHBvcnQgZnVuY3Rpb24gX3N0cmluZ2Jvb2woQ2xhc3NlcywgX3BhcmFtcykge1xuICAgIGNvbnN0IHBhcmFtcyA9IHV0aWwubm9ybWFsaXplUGFyYW1zKF9wYXJhbXMpO1xuICAgIGxldCB0cnV0aHlBcnJheSA9IHBhcmFtcy50cnV0aHkgPz8gW1xuICAgICAgICBcInRydWVcIixcbiAgICAgICAgXCIxXCIsXG4gICAgICAgIFwieWVzXCIsXG4gICAgICAgIFwib25cIixcbiAgICAgICAgXCJ5XCIsXG4gICAgICAgIFwiZW5hYmxlZFwiXG4gICAgXTtcbiAgICBsZXQgZmFsc3lBcnJheSA9IHBhcmFtcy5mYWxzeSA/PyBbXG4gICAgICAgIFwiZmFsc2VcIixcbiAgICAgICAgXCIwXCIsXG4gICAgICAgIFwibm9cIixcbiAgICAgICAgXCJvZmZcIixcbiAgICAgICAgXCJuXCIsXG4gICAgICAgIFwiZGlzYWJsZWRcIlxuICAgIF07XG4gICAgaWYgKHBhcmFtcy5jYXNlICE9PSBcInNlbnNpdGl2ZVwiKSB7XG4gICAgICAgIHRydXRoeUFycmF5ID0gdHJ1dGh5QXJyYXkubWFwKCh2KT0+dHlwZW9mIHYgPT09IFwic3RyaW5nXCIgPyB2LnRvTG93ZXJDYXNlKCkgOiB2KTtcbiAgICAgICAgZmFsc3lBcnJheSA9IGZhbHN5QXJyYXkubWFwKCh2KT0+dHlwZW9mIHYgPT09IFwic3RyaW5nXCIgPyB2LnRvTG93ZXJDYXNlKCkgOiB2KTtcbiAgICB9XG4gICAgY29uc3QgdHJ1dGh5U2V0ID0gbmV3IFNldCh0cnV0aHlBcnJheSk7XG4gICAgY29uc3QgZmFsc3lTZXQgPSBuZXcgU2V0KGZhbHN5QXJyYXkpO1xuICAgIGNvbnN0IF9Db2RlYyA9IENsYXNzZXMuQ29kZWMgPz8gc2NoZW1hcy4kWm9kQ29kZWM7XG4gICAgY29uc3QgX0Jvb2xlYW4gPSBDbGFzc2VzLkJvb2xlYW4gPz8gc2NoZW1hcy4kWm9kQm9vbGVhbjtcbiAgICBjb25zdCBfU3RyaW5nID0gQ2xhc3Nlcy5TdHJpbmcgPz8gc2NoZW1hcy4kWm9kU3RyaW5nO1xuICAgIGNvbnN0IHN0cmluZ1NjaGVtYSA9IG5ldyBfU3RyaW5nKHtcbiAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgZXJyb3I6IHBhcmFtcy5lcnJvclxuICAgIH0pO1xuICAgIGNvbnN0IGJvb2xlYW5TY2hlbWEgPSBuZXcgX0Jvb2xlYW4oe1xuICAgICAgICB0eXBlOiBcImJvb2xlYW5cIixcbiAgICAgICAgZXJyb3I6IHBhcmFtcy5lcnJvclxuICAgIH0pO1xuICAgIGNvbnN0IGNvZGVjID0gbmV3IF9Db2RlYyh7XG4gICAgICAgIHR5cGU6IFwicGlwZVwiLFxuICAgICAgICBpbjogc3RyaW5nU2NoZW1hLFxuICAgICAgICBvdXQ6IGJvb2xlYW5TY2hlbWEsXG4gICAgICAgIHRyYW5zZm9ybTogKGlucHV0LCBwYXlsb2FkKT0+e1xuICAgICAgICAgICAgbGV0IGRhdGEgPSBpbnB1dDtcbiAgICAgICAgICAgIGlmIChwYXJhbXMuY2FzZSAhPT0gXCJzZW5zaXRpdmVcIikgZGF0YSA9IGRhdGEudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgICAgIGlmICh0cnV0aHlTZXQuaGFzKGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGZhbHN5U2V0LmhhcyhkYXRhKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcGF5bG9hZC5pc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIGNvZGU6IFwiaW52YWxpZF92YWx1ZVwiLFxuICAgICAgICAgICAgICAgICAgICBleHBlY3RlZDogXCJzdHJpbmdib29sXCIsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlczogW1xuICAgICAgICAgICAgICAgICAgICAgICAgLi4udHJ1dGh5U2V0LFxuICAgICAgICAgICAgICAgICAgICAgICAgLi4uZmFsc3lTZXRcbiAgICAgICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICAgICAgaW5wdXQ6IHBheWxvYWQudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIGluc3Q6IGNvZGVjLFxuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTogZmFsc2VcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4ge307XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIHJldmVyc2VUcmFuc2Zvcm06IChpbnB1dCwgX3BheWxvYWQpPT57XG4gICAgICAgICAgICBpZiAoaW5wdXQgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1dGh5QXJyYXlbMF0gfHwgXCJ0cnVlXCI7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzeUFycmF5WzBdIHx8IFwiZmFsc2VcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6IHBhcmFtcy5lcnJvclxuICAgIH0pO1xuICAgIHJldHVybiBjb2RlYztcbn1cbmV4cG9ydCBmdW5jdGlvbiBfc3RyaW5nRm9ybWF0KENsYXNzLCBmb3JtYXQsIGZuT3JSZWdleCwgX3BhcmFtcyA9IHt9KSB7XG4gICAgY29uc3QgcGFyYW1zID0gdXRpbC5ub3JtYWxpemVQYXJhbXMoX3BhcmFtcyk7XG4gICAgY29uc3QgZGVmID0ge1xuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhfcGFyYW1zKSxcbiAgICAgICAgY2hlY2s6IFwic3RyaW5nX2Zvcm1hdFwiLFxuICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICBmb3JtYXQsXG4gICAgICAgIGZuOiB0eXBlb2YgZm5PclJlZ2V4ID09PSBcImZ1bmN0aW9uXCIgPyBmbk9yUmVnZXggOiAodmFsKT0+Zm5PclJlZ2V4LnRlc3QodmFsKSxcbiAgICAgICAgLi4ucGFyYW1zXG4gICAgfTtcbiAgICBpZiAoZm5PclJlZ2V4IGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgIGRlZi5wYXR0ZXJuID0gZm5PclJlZ2V4O1xuICAgIH1cbiAgICBjb25zdCBpbnN0ID0gbmV3IENsYXNzKGRlZik7XG4gICAgcmV0dXJuIGluc3Q7XG59XG4iLCAiaW1wb3J0IHsgJFpvZFJlZ2lzdHJ5LCBnbG9iYWxSZWdpc3RyeSB9IGZyb20gXCIuL3JlZ2lzdHJpZXMuanNcIjtcbmltcG9ydCB7IGdldEVudW1WYWx1ZXMgfSBmcm9tIFwiLi91dGlsLmpzXCI7XG5leHBvcnQgY2xhc3MgSlNPTlNjaGVtYUdlbmVyYXRvciB7XG4gICAgY29uc3RydWN0b3IocGFyYW1zKXtcbiAgICAgICAgdGhpcy5jb3VudGVyID0gMDtcbiAgICAgICAgdGhpcy5tZXRhZGF0YVJlZ2lzdHJ5ID0gcGFyYW1zPy5tZXRhZGF0YSA/PyBnbG9iYWxSZWdpc3RyeTtcbiAgICAgICAgdGhpcy50YXJnZXQgPSBwYXJhbXM/LnRhcmdldCA/PyBcImRyYWZ0LTIwMjAtMTJcIjtcbiAgICAgICAgdGhpcy51bnJlcHJlc2VudGFibGUgPSBwYXJhbXM/LnVucmVwcmVzZW50YWJsZSA/PyBcInRocm93XCI7XG4gICAgICAgIHRoaXMub3ZlcnJpZGUgPSBwYXJhbXM/Lm92ZXJyaWRlID8/ICgoKT0+e30pO1xuICAgICAgICB0aGlzLmlvID0gcGFyYW1zPy5pbyA/PyBcIm91dHB1dFwiO1xuICAgICAgICB0aGlzLnNlZW4gPSBuZXcgTWFwKCk7XG4gICAgfVxuICAgIHByb2Nlc3Moc2NoZW1hLCBfcGFyYW1zID0ge1xuICAgICAgICBwYXRoOiBbXSxcbiAgICAgICAgc2NoZW1hUGF0aDogW11cbiAgICB9KSB7XG4gICAgICAgIHZhciBfYTtcbiAgICAgICAgY29uc3QgZGVmID0gc2NoZW1hLl96b2QuZGVmO1xuICAgICAgICBjb25zdCBmb3JtYXRNYXAgPSB7XG4gICAgICAgICAgICBndWlkOiBcInV1aWRcIixcbiAgICAgICAgICAgIHVybDogXCJ1cmlcIixcbiAgICAgICAgICAgIGRhdGV0aW1lOiBcImRhdGUtdGltZVwiLFxuICAgICAgICAgICAganNvbl9zdHJpbmc6IFwianNvbi1zdHJpbmdcIixcbiAgICAgICAgICAgIHJlZ2V4OiBcIlwiXG4gICAgICAgIH07XG4gICAgICAgIC8vIGNoZWNrIGZvciBzY2hlbWEgaW4gc2VlbnNcbiAgICAgICAgY29uc3Qgc2VlbiA9IHRoaXMuc2Vlbi5nZXQoc2NoZW1hKTtcbiAgICAgICAgaWYgKHNlZW4pIHtcbiAgICAgICAgICAgIHNlZW4uY291bnQrKztcbiAgICAgICAgICAgIC8vIGNoZWNrIGlmIGN5Y2xlXG4gICAgICAgICAgICBjb25zdCBpc0N5Y2xlID0gX3BhcmFtcy5zY2hlbWFQYXRoLmluY2x1ZGVzKHNjaGVtYSk7XG4gICAgICAgICAgICBpZiAoaXNDeWNsZSkge1xuICAgICAgICAgICAgICAgIHNlZW4uY3ljbGUgPSBfcGFyYW1zLnBhdGg7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gc2Vlbi5zY2hlbWE7XG4gICAgICAgIH1cbiAgICAgICAgLy8gaW5pdGlhbGl6ZVxuICAgICAgICBjb25zdCByZXN1bHQgPSB7XG4gICAgICAgICAgICBzY2hlbWE6IHt9LFxuICAgICAgICAgICAgY291bnQ6IDEsXG4gICAgICAgICAgICBjeWNsZTogdW5kZWZpbmVkLFxuICAgICAgICAgICAgcGF0aDogX3BhcmFtcy5wYXRoXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuc2Vlbi5zZXQoc2NoZW1hLCByZXN1bHQpO1xuICAgICAgICAvLyBjdXN0b20gbWV0aG9kIG92ZXJyaWRlcyBkZWZhdWx0IGJlaGF2aW9yXG4gICAgICAgIGNvbnN0IG92ZXJyaWRlU2NoZW1hID0gc2NoZW1hLl96b2QudG9KU09OU2NoZW1hPy4oKTtcbiAgICAgICAgaWYgKG92ZXJyaWRlU2NoZW1hKSB7XG4gICAgICAgICAgICByZXN1bHQuc2NoZW1hID0gb3ZlcnJpZGVTY2hlbWE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgICAgICAgLi4uX3BhcmFtcyxcbiAgICAgICAgICAgICAgICBzY2hlbWFQYXRoOiBbXG4gICAgICAgICAgICAgICAgICAgIC4uLl9wYXJhbXMuc2NoZW1hUGF0aCxcbiAgICAgICAgICAgICAgICAgICAgc2NoZW1hXG4gICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICBwYXRoOiBfcGFyYW1zLnBhdGhcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBwYXJlbnQgPSBzY2hlbWEuX3pvZC5wYXJlbnQ7XG4gICAgICAgICAgICBpZiAocGFyZW50KSB7XG4gICAgICAgICAgICAgICAgLy8gc2NoZW1hIHdhcyBjbG9uZWQgZnJvbSBhbm90aGVyIHNjaGVtYVxuICAgICAgICAgICAgICAgIHJlc3VsdC5yZWYgPSBwYXJlbnQ7XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzKHBhcmVudCwgcGFyYW1zKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlZW4uZ2V0KHBhcmVudCkuaXNQYXJlbnQgPSB0cnVlO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBfanNvbiA9IHJlc3VsdC5zY2hlbWE7XG4gICAgICAgICAgICAgICAgc3dpdGNoKGRlZi50eXBlKXtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInN0cmluZ1wiOlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGpzb24gPSBfanNvbjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uLnR5cGUgPSBcInN0cmluZ1wiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgbWluaW11bSwgbWF4aW11bSwgZm9ybWF0LCBwYXR0ZXJucywgY29udGVudEVuY29kaW5nIH0gPSBzY2hlbWEuX3pvZC5iYWc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBtaW5pbXVtID09PSBcIm51bWJlclwiKSBqc29uLm1pbkxlbmd0aCA9IG1pbmltdW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBtYXhpbXVtID09PSBcIm51bWJlclwiKSBqc29uLm1heExlbmd0aCA9IG1heGltdW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY3VzdG9tIHBhdHRlcm4gb3ZlcnJpZGVzIGZvcm1hdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmb3JtYXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi5mb3JtYXQgPSBmb3JtYXRNYXBbZm9ybWF0XSA/PyBmb3JtYXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChqc29uLmZvcm1hdCA9PT0gXCJcIikgZGVsZXRlIGpzb24uZm9ybWF0OyAvLyBlbXB0eSBmb3JtYXQgaXMgbm90IHZhbGlkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50RW5jb2RpbmcpIGpzb24uY29udGVudEVuY29kaW5nID0gY29udGVudEVuY29kaW5nO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXR0ZXJucyAmJiBwYXR0ZXJucy5zaXplID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByZWdleGVzID0gW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4ucGF0dGVybnNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlZ2V4ZXMubGVuZ3RoID09PSAxKSBqc29uLnBhdHRlcm4gPSByZWdleGVzWzBdLnNvdXJjZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAocmVnZXhlcy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuc2NoZW1hLmFsbE9mID0gW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLnJlZ2V4ZXMubWFwKChyZWdleCk9Pih7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi50aGlzLnRhcmdldCA9PT0gXCJkcmFmdC03XCIgfHwgdGhpcy50YXJnZXQgPT09IFwiZHJhZnQtNFwiIHx8IHRoaXMudGFyZ2V0ID09PSBcIm9wZW5hcGktMy4wXCIgPyB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJzdHJpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSA6IHt9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0dGVybjogcmVnZXguc291cmNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGpzb24gPSBfanNvbjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7IG1pbmltdW0sIG1heGltdW0sIGZvcm1hdCwgbXVsdGlwbGVPZiwgZXhjbHVzaXZlTWF4aW11bSwgZXhjbHVzaXZlTWluaW11bSB9ID0gc2NoZW1hLl96b2QuYmFnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgZm9ybWF0ID09PSBcInN0cmluZ1wiICYmIGZvcm1hdC5pbmNsdWRlcyhcImludFwiKSkganNvbi50eXBlID0gXCJpbnRlZ2VyXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBqc29uLnR5cGUgPSBcIm51bWJlclwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgZXhjbHVzaXZlTWluaW11bSA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy50YXJnZXQgPT09IFwiZHJhZnQtNFwiIHx8IHRoaXMudGFyZ2V0ID09PSBcIm9wZW5hcGktMy4wXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24ubWluaW11bSA9IGV4Y2x1c2l2ZU1pbmltdW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uLmV4Y2x1c2l2ZU1pbmltdW0gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi5leGNsdXNpdmVNaW5pbXVtID0gZXhjbHVzaXZlTWluaW11bTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG1pbmltdW0gPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi5taW5pbXVtID0gbWluaW11bTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBleGNsdXNpdmVNaW5pbXVtID09PSBcIm51bWJlclwiICYmIHRoaXMudGFyZ2V0ICE9PSBcImRyYWZ0LTRcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV4Y2x1c2l2ZU1pbmltdW0gPj0gbWluaW11bSkgZGVsZXRlIGpzb24ubWluaW11bTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgZGVsZXRlIGpzb24uZXhjbHVzaXZlTWluaW11bTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGV4Y2x1c2l2ZU1heGltdW0gPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMudGFyZ2V0ID09PSBcImRyYWZ0LTRcIiB8fCB0aGlzLnRhcmdldCA9PT0gXCJvcGVuYXBpLTMuMFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uLm1heGltdW0gPSBleGNsdXNpdmVNYXhpbXVtO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi5leGNsdXNpdmVNYXhpbXVtID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24uZXhjbHVzaXZlTWF4aW11bSA9IGV4Y2x1c2l2ZU1heGltdW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBtYXhpbXVtID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24ubWF4aW11bSA9IG1heGltdW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgZXhjbHVzaXZlTWF4aW11bSA9PT0gXCJudW1iZXJcIiAmJiB0aGlzLnRhcmdldCAhPT0gXCJkcmFmdC00XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChleGNsdXNpdmVNYXhpbXVtIDw9IG1heGltdW0pIGRlbGV0ZSBqc29uLm1heGltdW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGRlbGV0ZSBqc29uLmV4Y2x1c2l2ZU1heGltdW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBtdWx0aXBsZU9mID09PSBcIm51bWJlclwiKSBqc29uLm11bHRpcGxlT2YgPSBtdWx0aXBsZU9mO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiYm9vbGVhblwiOlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGpzb24gPSBfanNvbjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uLnR5cGUgPSBcImJvb2xlYW5cIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImJpZ2ludFwiOlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnVucmVwcmVzZW50YWJsZSA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkJpZ0ludCBjYW5ub3QgYmUgcmVwcmVzZW50ZWQgaW4gSlNPTiBTY2hlbWFcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwic3ltYm9sXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMudW5yZXByZXNlbnRhYmxlID09PSBcInRocm93XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU3ltYm9scyBjYW5ub3QgYmUgcmVwcmVzZW50ZWQgaW4gSlNPTiBTY2hlbWFcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwibnVsbFwiOlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnRhcmdldCA9PT0gXCJvcGVuYXBpLTMuMFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9qc29uLnR5cGUgPSBcInN0cmluZ1wiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfanNvbi5udWxsYWJsZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9qc29uLmVudW0gPSBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIF9qc29uLnR5cGUgPSBcIm51bGxcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImFueVwiOlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwidW5rbm93blwiOlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwidW5kZWZpbmVkXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMudW5yZXByZXNlbnRhYmxlID09PSBcInRocm93XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5kZWZpbmVkIGNhbm5vdCBiZSByZXByZXNlbnRlZCBpbiBKU09OIFNjaGVtYVwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJ2b2lkXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMudW5yZXByZXNlbnRhYmxlID09PSBcInRocm93XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVm9pZCBjYW5ub3QgYmUgcmVwcmVzZW50ZWQgaW4gSlNPTiBTY2hlbWFcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwibmV2ZXJcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfanNvbi5ub3QgPSB7fTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImRhdGVcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy51bnJlcHJlc2VudGFibGUgPT09IFwidGhyb3dcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJEYXRlIGNhbm5vdCBiZSByZXByZXNlbnRlZCBpbiBKU09OIFNjaGVtYVwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJhcnJheVwiOlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGpzb24gPSBfanNvbjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7IG1pbmltdW0sIG1heGltdW0gfSA9IHNjaGVtYS5fem9kLmJhZztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG1pbmltdW0gPT09IFwibnVtYmVyXCIpIGpzb24ubWluSXRlbXMgPSBtaW5pbXVtO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgbWF4aW11bSA9PT0gXCJudW1iZXJcIikganNvbi5tYXhJdGVtcyA9IG1heGltdW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi50eXBlID0gXCJhcnJheVwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24uaXRlbXMgPSB0aGlzLnByb2Nlc3MoZGVmLmVsZW1lbnQsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4ucGFyYW1zLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXRoOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5wYXJhbXMucGF0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiaXRlbXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBqc29uID0gX2pzb247XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi50eXBlID0gXCJvYmplY3RcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uLnByb3BlcnRpZXMgPSB7fTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzaGFwZSA9IGRlZi5zaGFwZTsgLy8gcGFyYW1zLnNoYXBlQ2FjaGUuZ2V0KHNjaGVtYSkhO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcihjb25zdCBrZXkgaW4gc2hhcGUpe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uLnByb3BlcnRpZXNba2V5XSA9IHRoaXMucHJvY2VzcyhzaGFwZVtrZXldLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5wYXJhbXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXRoOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4ucGFyYW1zLnBhdGgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJwcm9wZXJ0aWVzXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyByZXF1aXJlZCBrZXlzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYWxsS2V5cyA9IG5ldyBTZXQoT2JqZWN0LmtleXMoc2hhcGUpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjb25zdCBvcHRpb25hbEtleXMgPSBuZXcgU2V0KGRlZi5vcHRpb25hbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVxdWlyZWRLZXlzID0gbmV3IFNldChbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLmFsbEtleXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLmZpbHRlcigoa2V5KT0+e1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2ID0gZGVmLnNoYXBlW2tleV0uX3pvZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuaW8gPT09IFwiaW5wdXRcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHYub3B0aW4gPT09IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2Lm9wdG91dCA9PT0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXF1aXJlZEtleXMuc2l6ZSA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi5yZXF1aXJlZCA9IEFycmF5LmZyb20ocmVxdWlyZWRLZXlzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2F0Y2hhbGxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGVmLmNhdGNoYWxsPy5fem9kLmRlZi50eXBlID09PSBcIm5ldmVyXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3RyaWN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24uYWRkaXRpb25hbFByb3BlcnRpZXMgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFkZWYuY2F0Y2hhbGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVndWxhclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pbyA9PT0gXCJvdXRwdXRcIikganNvbi5hZGRpdGlvbmFsUHJvcGVydGllcyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZGVmLmNhdGNoYWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24uYWRkaXRpb25hbFByb3BlcnRpZXMgPSB0aGlzLnByb2Nlc3MoZGVmLmNhdGNoYWxsLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5wYXJhbXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXRoOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4ucGFyYW1zLnBhdGgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJhZGRpdGlvbmFsUHJvcGVydGllc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInVuaW9uXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QganNvbiA9IF9qc29uO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSBkZWYub3B0aW9ucy5tYXAoKHgsIGkpPT50aGlzLnByb2Nlc3MoeCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4ucGFyYW1zLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aDogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLnBhcmFtcy5wYXRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiYW55T2ZcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uLmFueU9mID0gb3B0aW9ucztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImludGVyc2VjdGlvblwiOlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGpzb24gPSBfanNvbjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhID0gdGhpcy5wcm9jZXNzKGRlZi5sZWZ0LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLnBhcmFtcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aDogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4ucGFyYW1zLnBhdGgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImFsbE9mXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBiID0gdGhpcy5wcm9jZXNzKGRlZi5yaWdodCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5wYXJhbXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGg6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLnBhcmFtcy5wYXRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJhbGxPZlwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaXNTaW1wbGVJbnRlcnNlY3Rpb24gPSAodmFsKT0+XCJhbGxPZlwiIGluIHZhbCAmJiBPYmplY3Qua2V5cyh2YWwpLmxlbmd0aCA9PT0gMTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhbGxPZiA9IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4uaXNTaW1wbGVJbnRlcnNlY3Rpb24oYSkgPyBhLmFsbE9mIDogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5pc1NpbXBsZUludGVyc2VjdGlvbihiKSA/IGIuYWxsT2YgOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24uYWxsT2YgPSBhbGxPZjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInR1cGxlXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QganNvbiA9IF9qc29uO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24udHlwZSA9IFwiYXJyYXlcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwcmVmaXhQYXRoID0gdGhpcy50YXJnZXQgPT09IFwiZHJhZnQtMjAyMC0xMlwiID8gXCJwcmVmaXhJdGVtc1wiIDogXCJpdGVtc1wiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc3RQYXRoID0gdGhpcy50YXJnZXQgPT09IFwiZHJhZnQtMjAyMC0xMlwiID8gXCJpdGVtc1wiIDogdGhpcy50YXJnZXQgPT09IFwib3BlbmFwaS0zLjBcIiA/IFwiaXRlbXNcIiA6IFwiYWRkaXRpb25hbEl0ZW1zXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcHJlZml4SXRlbXMgPSBkZWYuaXRlbXMubWFwKCh4LCBpKT0+dGhpcy5wcm9jZXNzKHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLnBhcmFtcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGg6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5wYXJhbXMucGF0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXhQYXRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc3QgPSBkZWYucmVzdCA/IHRoaXMucHJvY2VzcyhkZWYucmVzdCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5wYXJhbXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGg6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLnBhcmFtcy5wYXRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdFBhdGgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi50aGlzLnRhcmdldCA9PT0gXCJvcGVuYXBpLTMuMFwiID8gW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZi5pdGVtcy5sZW5ndGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0gOiBbXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkgOiBudWxsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnRhcmdldCA9PT0gXCJkcmFmdC0yMDIwLTEyXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi5wcmVmaXhJdGVtcyA9IHByZWZpeEl0ZW1zO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi5pdGVtcyA9IHJlc3Q7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMudGFyZ2V0ID09PSBcIm9wZW5hcGktMy4wXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi5pdGVtcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFueU9mOiBwcmVmaXhJdGVtc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi5pdGVtcy5hbnlPZi5wdXNoKHJlc3QpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24ubWluSXRlbXMgPSBwcmVmaXhJdGVtcy5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghcmVzdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi5tYXhJdGVtcyA9IHByZWZpeEl0ZW1zLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24uaXRlbXMgPSBwcmVmaXhJdGVtcztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3QpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24uYWRkaXRpb25hbEl0ZW1zID0gcmVzdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBsZW5ndGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7IG1pbmltdW0sIG1heGltdW0gfSA9IHNjaGVtYS5fem9kLmJhZztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG1pbmltdW0gPT09IFwibnVtYmVyXCIpIGpzb24ubWluSXRlbXMgPSBtaW5pbXVtO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgbWF4aW11bSA9PT0gXCJudW1iZXJcIikganNvbi5tYXhJdGVtcyA9IG1heGltdW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJyZWNvcmRcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBqc29uID0gX2pzb247XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi50eXBlID0gXCJvYmplY3RcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy50YXJnZXQgPT09IFwiZHJhZnQtN1wiIHx8IHRoaXMudGFyZ2V0ID09PSBcImRyYWZ0LTIwMjAtMTJcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uLnByb3BlcnR5TmFtZXMgPSB0aGlzLnByb2Nlc3MoZGVmLmtleVR5cGUsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLnBhcmFtcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGg6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5wYXJhbXMucGF0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcInByb3BlcnR5TmFtZXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi5hZGRpdGlvbmFsUHJvcGVydGllcyA9IHRoaXMucHJvY2VzcyhkZWYudmFsdWVUeXBlLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLnBhcmFtcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aDogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4ucGFyYW1zLnBhdGgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImFkZGl0aW9uYWxQcm9wZXJ0aWVzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwibWFwXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMudW5yZXByZXNlbnRhYmxlID09PSBcInRocm93XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWFwIGNhbm5vdCBiZSByZXByZXNlbnRlZCBpbiBKU09OIFNjaGVtYVwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJzZXRcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy51bnJlcHJlc2VudGFibGUgPT09IFwidGhyb3dcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTZXQgY2Fubm90IGJlIHJlcHJlc2VudGVkIGluIEpTT04gU2NoZW1hXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImVudW1cIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBqc29uID0gX2pzb247XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWVzID0gZ2V0RW51bVZhbHVlcyhkZWYuZW50cmllcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTnVtYmVyIGVudW1zIGNhbiBoYXZlIGJvdGggc3RyaW5nIGFuZCBudW1iZXIgdmFsdWVzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlcy5ldmVyeSgodik9PnR5cGVvZiB2ID09PSBcIm51bWJlclwiKSkganNvbi50eXBlID0gXCJudW1iZXJcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWVzLmV2ZXJ5KCh2KT0+dHlwZW9mIHYgPT09IFwic3RyaW5nXCIpKSBqc29uLnR5cGUgPSBcInN0cmluZ1wiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24uZW51bSA9IHZhbHVlcztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImxpdGVyYWxcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBqc29uID0gX2pzb247XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFscyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgdmFsIG9mIGRlZi52YWx1ZXMpe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnVucmVwcmVzZW50YWJsZSA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTGl0ZXJhbCBgdW5kZWZpbmVkYCBjYW5ub3QgYmUgcmVwcmVzZW50ZWQgaW4gSlNPTiBTY2hlbWFcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZG8gbm90IGFkZCB0byB2YWxzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbCA9PT0gXCJiaWdpbnRcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMudW5yZXByZXNlbnRhYmxlID09PSBcInRocm93XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJCaWdJbnQgbGl0ZXJhbHMgY2Fubm90IGJlIHJlcHJlc2VudGVkIGluIEpTT04gU2NoZW1hXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWxzLnB1c2goTnVtYmVyKHZhbCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFscy5wdXNoKHZhbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZG8gbm90aGluZyAoYW4gdW5kZWZpbmVkIGxpdGVyYWwgd2FzIHN0cmlwcGVkKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodmFscy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsID0gdmFsc1swXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi50eXBlID0gdmFsID09PSBudWxsID8gXCJudWxsXCIgOiB0eXBlb2YgdmFsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy50YXJnZXQgPT09IFwiZHJhZnQtNFwiIHx8IHRoaXMudGFyZ2V0ID09PSBcIm9wZW5hcGktMy4wXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24uZW51bSA9IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uLmNvbnN0ID0gdmFsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHMuZXZlcnkoKHYpPT50eXBlb2YgdiA9PT0gXCJudW1iZXJcIikpIGpzb24udHlwZSA9IFwibnVtYmVyXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWxzLmV2ZXJ5KCh2KT0+dHlwZW9mIHYgPT09IFwic3RyaW5nXCIpKSBqc29uLnR5cGUgPSBcInN0cmluZ1wiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFscy5ldmVyeSgodik9PnR5cGVvZiB2ID09PSBcImJvb2xlYW5cIikpIGpzb24udHlwZSA9IFwic3RyaW5nXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWxzLmV2ZXJ5KCh2KT0+diA9PT0gbnVsbCkpIGpzb24udHlwZSA9IFwibnVsbFwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uLmVudW0gPSB2YWxzO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImZpbGVcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBqc29uID0gX2pzb247XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlsZSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0OiBcImJpbmFyeVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50RW5jb2Rpbmc6IFwiYmluYXJ5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgbWluaW11bSwgbWF4aW11bSwgbWltZSB9ID0gc2NoZW1hLl96b2QuYmFnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtaW5pbXVtICE9PSB1bmRlZmluZWQpIGZpbGUubWluTGVuZ3RoID0gbWluaW11bTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobWF4aW11bSAhPT0gdW5kZWZpbmVkKSBmaWxlLm1heExlbmd0aCA9IG1heGltdW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1pbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1pbWUubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlLmNvbnRlbnRNZWRpYVR5cGUgPSBtaW1lWzBdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0LmFzc2lnbihqc29uLCBmaWxlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24uYW55T2YgPSBtaW1lLm1hcCgobSk9PntcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtRmlsZSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4uZmlsZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudE1lZGlhVHlwZTogbVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1GaWxlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QuYXNzaWduKGpzb24sIGZpbGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInRyYW5zZm9ybVwiOlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnVucmVwcmVzZW50YWJsZSA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRyYW5zZm9ybXMgY2Fubm90IGJlIHJlcHJlc2VudGVkIGluIEpTT04gU2NoZW1hXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcIm51bGxhYmxlXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5uZXIgPSB0aGlzLnByb2Nlc3MoZGVmLmlubmVyVHlwZSwgcGFyYW1zKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy50YXJnZXQgPT09IFwib3BlbmFwaS0zLjBcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQucmVmID0gZGVmLmlubmVyVHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2pzb24ubnVsbGFibGUgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9qc29uLmFueU9mID0gW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5uZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJudWxsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJub25vcHRpb25hbFwiOlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJvY2VzcyhkZWYuaW5uZXJUeXBlLCBwYXJhbXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5yZWYgPSBkZWYuaW5uZXJUeXBlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwic3VjY2Vzc1wiOlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGpzb24gPSBfanNvbjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uLnR5cGUgPSBcImJvb2xlYW5cIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImRlZmF1bHRcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnByb2Nlc3MoZGVmLmlubmVyVHlwZSwgcGFyYW1zKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQucmVmID0gZGVmLmlubmVyVHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfanNvbi5kZWZhdWx0ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShkZWYuZGVmYXVsdFZhbHVlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJwcmVmYXVsdFwiOlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJvY2VzcyhkZWYuaW5uZXJUeXBlLCBwYXJhbXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5yZWYgPSBkZWYuaW5uZXJUeXBlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmlvID09PSBcImlucHV0XCIpIF9qc29uLl9wcmVmYXVsdCA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoZGVmLmRlZmF1bHRWYWx1ZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiY2F0Y2hcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB1c2UgY29uZGl0aW9uYWxzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzKGRlZi5pbm5lclR5cGUsIHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LnJlZiA9IGRlZi5pbm5lclR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNhdGNoVmFsdWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2hWYWx1ZSA9IGRlZi5jYXRjaFZhbHVlKHVuZGVmaW5lZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJEeW5hbWljIGNhdGNoIHZhbHVlcyBhcmUgbm90IHN1cHBvcnRlZCBpbiBKU09OIFNjaGVtYVwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2pzb24uZGVmYXVsdCA9IGNhdGNoVmFsdWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJuYW5cIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy51bnJlcHJlc2VudGFibGUgPT09IFwidGhyb3dcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJOYU4gY2Fubm90IGJlIHJlcHJlc2VudGVkIGluIEpTT04gU2NoZW1hXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInRlbXBsYXRlX2xpdGVyYWxcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBqc29uID0gX2pzb247XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcGF0dGVybiA9IHNjaGVtYS5fem9kLnBhdHRlcm47XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFwYXR0ZXJuKSB0aHJvdyBuZXcgRXJyb3IoXCJQYXR0ZXJuIG5vdCBmb3VuZCBpbiB0ZW1wbGF0ZSBsaXRlcmFsXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24udHlwZSA9IFwic3RyaW5nXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi5wYXR0ZXJuID0gcGF0dGVybi5zb3VyY2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJwaXBlXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5uZXJUeXBlID0gdGhpcy5pbyA9PT0gXCJpbnB1dFwiID8gZGVmLmluLl96b2QuZGVmLnR5cGUgPT09IFwidHJhbnNmb3JtXCIgPyBkZWYub3V0IDogZGVmLmluIDogZGVmLm91dDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnByb2Nlc3MoaW5uZXJUeXBlLCBwYXJhbXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5yZWYgPSBpbm5lclR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJyZWFkb25seVwiOlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJvY2VzcyhkZWYuaW5uZXJUeXBlLCBwYXJhbXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5yZWYgPSBkZWYuaW5uZXJUeXBlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9qc29uLnJlYWRPbmx5ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gcGFzc3Rocm91Z2ggdHlwZXNcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInByb21pc2VcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnByb2Nlc3MoZGVmLmlubmVyVHlwZSwgcGFyYW1zKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQucmVmID0gZGVmLmlubmVyVHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcIm9wdGlvbmFsXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzKGRlZi5pbm5lclR5cGUsIHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LnJlZiA9IGRlZi5pbm5lclR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJsYXp5XCI6XG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5uZXJUeXBlID0gc2NoZW1hLl96b2QuaW5uZXJUeXBlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJvY2Vzcyhpbm5lclR5cGUsIHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LnJlZiA9IGlubmVyVHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImN1c3RvbVwiOlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnVucmVwcmVzZW50YWJsZSA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkN1c3RvbSB0eXBlcyBjYW5ub3QgYmUgcmVwcmVzZW50ZWQgaW4gSlNPTiBTY2hlbWFcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiZnVuY3Rpb25cIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy51bnJlcHJlc2VudGFibGUgPT09IFwidGhyb3dcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJGdW5jdGlvbiB0eXBlcyBjYW5ub3QgYmUgcmVwcmVzZW50ZWQgaW4gSlNPTiBTY2hlbWFcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gbWV0YWRhdGFcbiAgICAgICAgY29uc3QgbWV0YSA9IHRoaXMubWV0YWRhdGFSZWdpc3RyeS5nZXQoc2NoZW1hKTtcbiAgICAgICAgaWYgKG1ldGEpIE9iamVjdC5hc3NpZ24ocmVzdWx0LnNjaGVtYSwgbWV0YSk7XG4gICAgICAgIGlmICh0aGlzLmlvID09PSBcImlucHV0XCIgJiYgaXNUcmFuc2Zvcm1pbmcoc2NoZW1hKSkge1xuICAgICAgICAgICAgLy8gZXhhbXBsZXMvZGVmYXVsdHMgb25seSBhcHBseSB0byBvdXRwdXQgdHlwZSBvZiBwaXBlXG4gICAgICAgICAgICBkZWxldGUgcmVzdWx0LnNjaGVtYS5leGFtcGxlcztcbiAgICAgICAgICAgIGRlbGV0ZSByZXN1bHQuc2NoZW1hLmRlZmF1bHQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gc2V0IHByZWZhdWx0IGFzIGRlZmF1bHRcbiAgICAgICAgaWYgKHRoaXMuaW8gPT09IFwiaW5wdXRcIiAmJiByZXN1bHQuc2NoZW1hLl9wcmVmYXVsdCkgKF9hID0gcmVzdWx0LnNjaGVtYSkuZGVmYXVsdCA/PyAoX2EuZGVmYXVsdCA9IHJlc3VsdC5zY2hlbWEuX3ByZWZhdWx0KTtcbiAgICAgICAgZGVsZXRlIHJlc3VsdC5zY2hlbWEuX3ByZWZhdWx0O1xuICAgICAgICAvLyBwdWxsaW5nIGZyZXNoIGZyb20gdGhpcy5zZWVuIGluIGNhc2UgaXQgd2FzIG92ZXJ3cml0dGVuXG4gICAgICAgIGNvbnN0IF9yZXN1bHQgPSB0aGlzLnNlZW4uZ2V0KHNjaGVtYSk7XG4gICAgICAgIHJldHVybiBfcmVzdWx0LnNjaGVtYTtcbiAgICB9XG4gICAgZW1pdChzY2hlbWEsIF9wYXJhbXMpIHtcbiAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgICAgY3ljbGVzOiBfcGFyYW1zPy5jeWNsZXMgPz8gXCJyZWZcIixcbiAgICAgICAgICAgIHJldXNlZDogX3BhcmFtcz8ucmV1c2VkID8/IFwiaW5saW5lXCIsXG4gICAgICAgICAgICAvLyB1bnJlcHJlc2VudGFibGU6IF9wYXJhbXM/LnVucmVwcmVzZW50YWJsZSA/PyBcInRocm93XCIsXG4gICAgICAgICAgICAvLyB1cmk6IF9wYXJhbXM/LnVyaSA/PyAoKGlkKSA9PiBgJHtpZH1gKSxcbiAgICAgICAgICAgIGV4dGVybmFsOiBfcGFyYW1zPy5leHRlcm5hbCA/PyB1bmRlZmluZWRcbiAgICAgICAgfTtcbiAgICAgICAgLy8gaXRlcmF0ZSBvdmVyIHNlZW4gbWFwO1xuICAgICAgICBjb25zdCByb290ID0gdGhpcy5zZWVuLmdldChzY2hlbWEpO1xuICAgICAgICBpZiAoIXJvb3QpIHRocm93IG5ldyBFcnJvcihcIlVucHJvY2Vzc2VkIHNjaGVtYS4gVGhpcyBpcyBhIGJ1ZyBpbiBab2QuXCIpO1xuICAgICAgICAvLyBpbml0aWFsaXplIHJlc3VsdCB3aXRoIHJvb3Qgc2NoZW1hIGZpZWxkc1xuICAgICAgICAvLyBPYmplY3QuYXNzaWduKHJlc3VsdCwgc2Vlbi5jYWNoZWQpO1xuICAgICAgICAvLyByZXR1cm5zIGEgcmVmIHRvIHRoZSBzY2hlbWFcbiAgICAgICAgLy8gZGVmSWQgd2lsbCBiZSBlbXB0eSBpZiB0aGUgcmVmIHBvaW50cyB0byBhbiBleHRlcm5hbCBzY2hlbWEgKG9yICMpXG4gICAgICAgIGNvbnN0IG1ha2VVUkkgPSAoZW50cnkpPT57XG4gICAgICAgICAgICAvLyBjb21wYXJpbmcgdGhlIHNlZW4gb2JqZWN0cyBiZWNhdXNlIHNvbWV0aW1lc1xuICAgICAgICAgICAgLy8gbXVsdGlwbGUgc2NoZW1hcyBtYXAgdG8gdGhlIHNhbWUgc2VlbiBvYmplY3QuXG4gICAgICAgICAgICAvLyBlLmcuIGxhenlcbiAgICAgICAgICAgIC8vIGV4dGVybmFsIGlzIGNvbmZpZ3VyZWRcbiAgICAgICAgICAgIGNvbnN0IGRlZnNTZWdtZW50ID0gdGhpcy50YXJnZXQgPT09IFwiZHJhZnQtMjAyMC0xMlwiID8gXCIkZGVmc1wiIDogXCJkZWZpbml0aW9uc1wiO1xuICAgICAgICAgICAgaWYgKHBhcmFtcy5leHRlcm5hbCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGV4dGVybmFsSWQgPSBwYXJhbXMuZXh0ZXJuYWwucmVnaXN0cnkuZ2V0KGVudHJ5WzBdKT8uaWQ7IC8vID8/IFwiX19zaGFyZWRcIjsvLyBgX19zY2hlbWEke3RoaXMuY291bnRlcisrfWA7XG4gICAgICAgICAgICAgICAgLy8gY2hlY2sgaWYgc2NoZW1hIGlzIGluIHRoZSBleHRlcm5hbCByZWdpc3RyeVxuICAgICAgICAgICAgICAgIGNvbnN0IHVyaUdlbmVyYXRvciA9IHBhcmFtcy5leHRlcm5hbC51cmkgPz8gKChpZCk9PmlkKTtcbiAgICAgICAgICAgICAgICBpZiAoZXh0ZXJuYWxJZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVmOiB1cmlHZW5lcmF0b3IoZXh0ZXJuYWxJZClcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gb3RoZXJ3aXNlLCBhZGQgdG8gX19zaGFyZWRcbiAgICAgICAgICAgICAgICBjb25zdCBpZCA9IGVudHJ5WzFdLmRlZklkID8/IGVudHJ5WzFdLnNjaGVtYS5pZCA/PyBgc2NoZW1hJHt0aGlzLmNvdW50ZXIrK31gO1xuICAgICAgICAgICAgICAgIGVudHJ5WzFdLmRlZklkID0gaWQ7IC8vIHNldCBkZWZJZCBzbyBpdCB3aWxsIGJlIHJldXNlZCBpZiBuZWVkZWRcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBkZWZJZDogaWQsXG4gICAgICAgICAgICAgICAgICAgIHJlZjogYCR7dXJpR2VuZXJhdG9yKFwiX19zaGFyZWRcIil9Iy8ke2RlZnNTZWdtZW50fS8ke2lkfWBcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGVudHJ5WzFdID09PSByb290KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgcmVmOiBcIiNcIlxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBzZWxmLWNvbnRhaW5lZCBzY2hlbWFcbiAgICAgICAgICAgIGNvbnN0IHVyaVByZWZpeCA9IGAjYDtcbiAgICAgICAgICAgIGNvbnN0IGRlZlVyaVByZWZpeCA9IGAke3VyaVByZWZpeH0vJHtkZWZzU2VnbWVudH0vYDtcbiAgICAgICAgICAgIGNvbnN0IGRlZklkID0gZW50cnlbMV0uc2NoZW1hLmlkID8/IGBfX3NjaGVtYSR7dGhpcy5jb3VudGVyKyt9YDtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgZGVmSWQsXG4gICAgICAgICAgICAgICAgcmVmOiBkZWZVcmlQcmVmaXggKyBkZWZJZFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfTtcbiAgICAgICAgLy8gc3RvcmVkIGNhY2hlZCB2ZXJzaW9uIGluIGBkZWZgIHByb3BlcnR5XG4gICAgICAgIC8vIHJlbW92ZSBhbGwgcHJvcGVydGllcywgc2V0ICRyZWZcbiAgICAgICAgY29uc3QgZXh0cmFjdFRvRGVmID0gKGVudHJ5KT0+e1xuICAgICAgICAgICAgLy8gaWYgdGhlIHNjaGVtYSBpcyBhbHJlYWR5IGEgcmVmZXJlbmNlLCBkbyBub3QgZXh0cmFjdCBpdFxuICAgICAgICAgICAgaWYgKGVudHJ5WzFdLnNjaGVtYS4kcmVmKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3Qgc2VlbiA9IGVudHJ5WzFdO1xuICAgICAgICAgICAgY29uc3QgeyByZWYsIGRlZklkIH0gPSBtYWtlVVJJKGVudHJ5KTtcbiAgICAgICAgICAgIHNlZW4uZGVmID0ge1xuICAgICAgICAgICAgICAgIC4uLnNlZW4uc2NoZW1hXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgLy8gZGVmSWQgd29uJ3QgYmUgc2V0IGlmIHRoZSBzY2hlbWEgaXMgYSByZWZlcmVuY2UgdG8gYW4gZXh0ZXJuYWwgc2NoZW1hXG4gICAgICAgICAgICBpZiAoZGVmSWQpIHNlZW4uZGVmSWQgPSBkZWZJZDtcbiAgICAgICAgICAgIC8vIHdpcGUgYXdheSBhbGwgcHJvcGVydGllcyBleGNlcHQgJHJlZlxuICAgICAgICAgICAgY29uc3Qgc2NoZW1hID0gc2Vlbi5zY2hlbWE7XG4gICAgICAgICAgICBmb3IoY29uc3Qga2V5IGluIHNjaGVtYSl7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHNjaGVtYVtrZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc2NoZW1hLiRyZWYgPSByZWY7XG4gICAgICAgIH07XG4gICAgICAgIC8vIHRocm93IG9uIGN5Y2xlc1xuICAgICAgICAvLyBicmVhayBjeWNsZXNcbiAgICAgICAgaWYgKHBhcmFtcy5jeWNsZXMgPT09IFwidGhyb3dcIikge1xuICAgICAgICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiB0aGlzLnNlZW4uZW50cmllcygpKXtcbiAgICAgICAgICAgICAgICBjb25zdCBzZWVuID0gZW50cnlbMV07XG4gICAgICAgICAgICAgICAgaWYgKHNlZW4uY3ljbGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ3ljbGUgZGV0ZWN0ZWQ6IFwiICsgYCMvJHtzZWVuLmN5Y2xlPy5qb2luKFwiL1wiKX0vPHJvb3Q+YCArICdcXG5cXG5TZXQgdGhlIGBjeWNsZXNgIHBhcmFtZXRlciB0byBgXCJyZWZcImAgdG8gcmVzb2x2ZSBjeWNsaWNhbCBzY2hlbWFzIHdpdGggZGVmcy4nKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gZXh0cmFjdCBzY2hlbWFzIGludG8gJGRlZnNcbiAgICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiB0aGlzLnNlZW4uZW50cmllcygpKXtcbiAgICAgICAgICAgIGNvbnN0IHNlZW4gPSBlbnRyeVsxXTtcbiAgICAgICAgICAgIC8vIGNvbnZlcnQgcm9vdCBzY2hlbWEgdG8gIyAkcmVmXG4gICAgICAgICAgICBpZiAoc2NoZW1hID09PSBlbnRyeVswXSkge1xuICAgICAgICAgICAgICAgIGV4dHJhY3RUb0RlZihlbnRyeSk7IC8vIHRoaXMgaGFzIHNwZWNpYWwgaGFuZGxpbmcgZm9yIHRoZSByb290IHNjaGVtYVxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gZXh0cmFjdCBzY2hlbWFzIHRoYXQgYXJlIGluIHRoZSBleHRlcm5hbCByZWdpc3RyeVxuICAgICAgICAgICAgaWYgKHBhcmFtcy5leHRlcm5hbCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGV4dCA9IHBhcmFtcy5leHRlcm5hbC5yZWdpc3RyeS5nZXQoZW50cnlbMF0pPy5pZDtcbiAgICAgICAgICAgICAgICBpZiAoc2NoZW1hICE9PSBlbnRyeVswXSAmJiBleHQpIHtcbiAgICAgICAgICAgICAgICAgICAgZXh0cmFjdFRvRGVmKGVudHJ5KTtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gZXh0cmFjdCBzY2hlbWFzIHdpdGggYGlkYCBtZXRhXG4gICAgICAgICAgICBjb25zdCBpZCA9IHRoaXMubWV0YWRhdGFSZWdpc3RyeS5nZXQoZW50cnlbMF0pPy5pZDtcbiAgICAgICAgICAgIGlmIChpZCkge1xuICAgICAgICAgICAgICAgIGV4dHJhY3RUb0RlZihlbnRyeSk7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBicmVhayBjeWNsZXNcbiAgICAgICAgICAgIGlmIChzZWVuLmN5Y2xlKSB7XG4gICAgICAgICAgICAgICAgLy8gYW55XG4gICAgICAgICAgICAgICAgZXh0cmFjdFRvRGVmKGVudHJ5KTtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIGV4dHJhY3QgcmV1c2VkIHNjaGVtYXNcbiAgICAgICAgICAgIGlmIChzZWVuLmNvdW50ID4gMSkge1xuICAgICAgICAgICAgICAgIGlmIChwYXJhbXMucmV1c2VkID09PSBcInJlZlwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGV4dHJhY3RUb0RlZihlbnRyeSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBmbGF0dGVuIF9yZWZzXG4gICAgICAgIGNvbnN0IGZsYXR0ZW5SZWYgPSAoem9kU2NoZW1hLCBwYXJhbXMpPT57XG4gICAgICAgICAgICBjb25zdCBzZWVuID0gdGhpcy5zZWVuLmdldCh6b2RTY2hlbWEpO1xuICAgICAgICAgICAgY29uc3Qgc2NoZW1hID0gc2Vlbi5kZWYgPz8gc2Vlbi5zY2hlbWE7XG4gICAgICAgICAgICBjb25zdCBfY2FjaGVkID0ge1xuICAgICAgICAgICAgICAgIC4uLnNjaGVtYVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIC8vIGFscmVhZHkgc2VlblxuICAgICAgICAgICAgaWYgKHNlZW4ucmVmID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gZmxhdHRlbiByZWYgaWYgZGVmaW5lZFxuICAgICAgICAgICAgY29uc3QgcmVmID0gc2Vlbi5yZWY7XG4gICAgICAgICAgICBzZWVuLnJlZiA9IG51bGw7IC8vIHByZXZlbnQgcmVjdXJzaW9uXG4gICAgICAgICAgICBpZiAocmVmKSB7XG4gICAgICAgICAgICAgICAgZmxhdHRlblJlZihyZWYsIHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgLy8gbWVyZ2UgcmVmZXJlbmNlZCBzY2hlbWEgaW50byBjdXJyZW50XG4gICAgICAgICAgICAgICAgY29uc3QgcmVmU2NoZW1hID0gdGhpcy5zZWVuLmdldChyZWYpLnNjaGVtYTtcbiAgICAgICAgICAgICAgICBpZiAocmVmU2NoZW1hLiRyZWYgJiYgKHBhcmFtcy50YXJnZXQgPT09IFwiZHJhZnQtN1wiIHx8IHBhcmFtcy50YXJnZXQgPT09IFwiZHJhZnQtNFwiIHx8IHBhcmFtcy50YXJnZXQgPT09IFwib3BlbmFwaS0zLjBcIikpIHtcbiAgICAgICAgICAgICAgICAgICAgc2NoZW1hLmFsbE9mID0gc2NoZW1hLmFsbE9mID8/IFtdO1xuICAgICAgICAgICAgICAgICAgICBzY2hlbWEuYWxsT2YucHVzaChyZWZTY2hlbWEpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIE9iamVjdC5hc3NpZ24oc2NoZW1hLCByZWZTY2hlbWEpO1xuICAgICAgICAgICAgICAgICAgICBPYmplY3QuYXNzaWduKHNjaGVtYSwgX2NhY2hlZCk7IC8vIHByZXZlbnQgb3ZlcndyaXRpbmcgYW55IGZpZWxkcyBpbiB0aGUgb3JpZ2luYWwgc2NoZW1hXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gZXhlY3V0ZSBvdmVycmlkZXNcbiAgICAgICAgICAgIGlmICghc2Vlbi5pc1BhcmVudCkgdGhpcy5vdmVycmlkZSh7XG4gICAgICAgICAgICAgICAgem9kU2NoZW1hOiB6b2RTY2hlbWEsXG4gICAgICAgICAgICAgICAganNvblNjaGVtYTogc2NoZW1hLFxuICAgICAgICAgICAgICAgIHBhdGg6IHNlZW4ucGF0aCA/PyBbXVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG4gICAgICAgIGZvciAoY29uc3QgZW50cnkgb2YgW1xuICAgICAgICAgICAgLi4udGhpcy5zZWVuLmVudHJpZXMoKVxuICAgICAgICBdLnJldmVyc2UoKSl7XG4gICAgICAgICAgICBmbGF0dGVuUmVmKGVudHJ5WzBdLCB7XG4gICAgICAgICAgICAgICAgdGFyZ2V0OiB0aGlzLnRhcmdldFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVzdWx0ID0ge307XG4gICAgICAgIGlmICh0aGlzLnRhcmdldCA9PT0gXCJkcmFmdC0yMDIwLTEyXCIpIHtcbiAgICAgICAgICAgIHJlc3VsdC4kc2NoZW1hID0gXCJodHRwczovL2pzb24tc2NoZW1hLm9yZy9kcmFmdC8yMDIwLTEyL3NjaGVtYVwiO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMudGFyZ2V0ID09PSBcImRyYWZ0LTdcIikge1xuICAgICAgICAgICAgcmVzdWx0LiRzY2hlbWEgPSBcImh0dHA6Ly9qc29uLXNjaGVtYS5vcmcvZHJhZnQtMDcvc2NoZW1hI1wiO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMudGFyZ2V0ID09PSBcImRyYWZ0LTRcIikge1xuICAgICAgICAgICAgcmVzdWx0LiRzY2hlbWEgPSBcImh0dHA6Ly9qc29uLXNjaGVtYS5vcmcvZHJhZnQtMDQvc2NoZW1hI1wiO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMudGFyZ2V0ID09PSBcIm9wZW5hcGktMy4wXCIpIHtcbiAgICAgICAgLy8gT3BlbkFQSSAzLjAgc2NoZW1hIG9iamVjdHMgc2hvdWxkIG5vdCBpbmNsdWRlIGEgJHNjaGVtYSBwcm9wZXJ0eVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgY29uc29sZS53YXJuKGBJbnZhbGlkIHRhcmdldDogJHt0aGlzLnRhcmdldH1gKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocGFyYW1zLmV4dGVybmFsPy51cmkpIHtcbiAgICAgICAgICAgIGNvbnN0IGlkID0gcGFyYW1zLmV4dGVybmFsLnJlZ2lzdHJ5LmdldChzY2hlbWEpPy5pZDtcbiAgICAgICAgICAgIGlmICghaWQpIHRocm93IG5ldyBFcnJvcihcIlNjaGVtYSBpcyBtaXNzaW5nIGFuIGBpZGAgcHJvcGVydHlcIik7XG4gICAgICAgICAgICByZXN1bHQuJGlkID0gcGFyYW1zLmV4dGVybmFsLnVyaShpZCk7XG4gICAgICAgIH1cbiAgICAgICAgT2JqZWN0LmFzc2lnbihyZXN1bHQsIHJvb3QuZGVmKTtcbiAgICAgICAgLy8gYnVpbGQgZGVmcyBvYmplY3RcbiAgICAgICAgY29uc3QgZGVmcyA9IHBhcmFtcy5leHRlcm5hbD8uZGVmcyA/PyB7fTtcbiAgICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiB0aGlzLnNlZW4uZW50cmllcygpKXtcbiAgICAgICAgICAgIGNvbnN0IHNlZW4gPSBlbnRyeVsxXTtcbiAgICAgICAgICAgIGlmIChzZWVuLmRlZiAmJiBzZWVuLmRlZklkKSB7XG4gICAgICAgICAgICAgICAgZGVmc1tzZWVuLmRlZklkXSA9IHNlZW4uZGVmO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIHNldCBkZWZpbml0aW9ucyBpbiByZXN1bHRcbiAgICAgICAgaWYgKHBhcmFtcy5leHRlcm5hbCkge30gZWxzZSB7XG4gICAgICAgICAgICBpZiAoT2JqZWN0LmtleXMoZGVmcykubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnRhcmdldCA9PT0gXCJkcmFmdC0yMDIwLTEyXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0LiRkZWZzID0gZGVmcztcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQuZGVmaW5pdGlvbnMgPSBkZWZzO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gdGhpcyBcImZpbmFsaXplc1wiIHRoaXMgc2NoZW1hIGFuZCBlbnN1cmVzIGFsbCBjeWNsZXMgYXJlIHJlbW92ZWRcbiAgICAgICAgICAgIC8vIGVhY2ggY2FsbCB0byAuZW1pdCgpIGlzIGZ1bmN0aW9uYWxseSBpbmRlcGVuZGVudFxuICAgICAgICAgICAgLy8gdGhvdWdoIHRoZSBzZWVuIG1hcCBpcyBzaGFyZWRcbiAgICAgICAgICAgIHJldHVybiBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHJlc3VsdCkpO1xuICAgICAgICB9IGNhdGNoIChfZXJyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJFcnJvciBjb252ZXJ0aW5nIHNjaGVtYSB0byBKU09OLlwiKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmV4cG9ydCBmdW5jdGlvbiB0b0pTT05TY2hlbWEoaW5wdXQsIF9wYXJhbXMpIHtcbiAgICBpZiAoaW5wdXQgaW5zdGFuY2VvZiAkWm9kUmVnaXN0cnkpIHtcbiAgICAgICAgY29uc3QgZ2VuID0gbmV3IEpTT05TY2hlbWFHZW5lcmF0b3IoX3BhcmFtcyk7XG4gICAgICAgIGNvbnN0IGRlZnMgPSB7fTtcbiAgICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiBpbnB1dC5faWRtYXAuZW50cmllcygpKXtcbiAgICAgICAgICAgIGNvbnN0IFtfLCBzY2hlbWFdID0gZW50cnk7XG4gICAgICAgICAgICBnZW4ucHJvY2VzcyhzY2hlbWEpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHNjaGVtYXMgPSB7fTtcbiAgICAgICAgY29uc3QgZXh0ZXJuYWwgPSB7XG4gICAgICAgICAgICByZWdpc3RyeTogaW5wdXQsXG4gICAgICAgICAgICB1cmk6IF9wYXJhbXM/LnVyaSxcbiAgICAgICAgICAgIGRlZnNcbiAgICAgICAgfTtcbiAgICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiBpbnB1dC5faWRtYXAuZW50cmllcygpKXtcbiAgICAgICAgICAgIGNvbnN0IFtrZXksIHNjaGVtYV0gPSBlbnRyeTtcbiAgICAgICAgICAgIHNjaGVtYXNba2V5XSA9IGdlbi5lbWl0KHNjaGVtYSwge1xuICAgICAgICAgICAgICAgIC4uLl9wYXJhbXMsXG4gICAgICAgICAgICAgICAgZXh0ZXJuYWxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChPYmplY3Qua2V5cyhkZWZzKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBjb25zdCBkZWZzU2VnbWVudCA9IGdlbi50YXJnZXQgPT09IFwiZHJhZnQtMjAyMC0xMlwiID8gXCIkZGVmc1wiIDogXCJkZWZpbml0aW9uc1wiO1xuICAgICAgICAgICAgc2NoZW1hcy5fX3NoYXJlZCA9IHtcbiAgICAgICAgICAgICAgICBbZGVmc1NlZ21lbnRdOiBkZWZzXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzY2hlbWFzXG4gICAgICAgIH07XG4gICAgfVxuICAgIGNvbnN0IGdlbiA9IG5ldyBKU09OU2NoZW1hR2VuZXJhdG9yKF9wYXJhbXMpO1xuICAgIGdlbi5wcm9jZXNzKGlucHV0KTtcbiAgICByZXR1cm4gZ2VuLmVtaXQoaW5wdXQsIF9wYXJhbXMpO1xufVxuZnVuY3Rpb24gaXNUcmFuc2Zvcm1pbmcoX3NjaGVtYSwgX2N0eCkge1xuICAgIGNvbnN0IGN0eCA9IF9jdHggPz8ge1xuICAgICAgICBzZWVuOiBuZXcgU2V0KClcbiAgICB9O1xuICAgIGlmIChjdHguc2Vlbi5oYXMoX3NjaGVtYSkpIHJldHVybiBmYWxzZTtcbiAgICBjdHguc2Vlbi5hZGQoX3NjaGVtYSk7XG4gICAgY29uc3Qgc2NoZW1hID0gX3NjaGVtYTtcbiAgICBjb25zdCBkZWYgPSBzY2hlbWEuX3pvZC5kZWY7XG4gICAgc3dpdGNoKGRlZi50eXBlKXtcbiAgICAgICAgY2FzZSBcInN0cmluZ1wiOlxuICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgIGNhc2UgXCJiaWdpbnRcIjpcbiAgICAgICAgY2FzZSBcImJvb2xlYW5cIjpcbiAgICAgICAgY2FzZSBcImRhdGVcIjpcbiAgICAgICAgY2FzZSBcInN5bWJvbFwiOlxuICAgICAgICBjYXNlIFwidW5kZWZpbmVkXCI6XG4gICAgICAgIGNhc2UgXCJudWxsXCI6XG4gICAgICAgIGNhc2UgXCJhbnlcIjpcbiAgICAgICAgY2FzZSBcInVua25vd25cIjpcbiAgICAgICAgY2FzZSBcIm5ldmVyXCI6XG4gICAgICAgIGNhc2UgXCJ2b2lkXCI6XG4gICAgICAgIGNhc2UgXCJsaXRlcmFsXCI6XG4gICAgICAgIGNhc2UgXCJlbnVtXCI6XG4gICAgICAgIGNhc2UgXCJuYW5cIjpcbiAgICAgICAgY2FzZSBcImZpbGVcIjpcbiAgICAgICAgY2FzZSBcInRlbXBsYXRlX2xpdGVyYWxcIjpcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgY2FzZSBcImFycmF5XCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlzVHJhbnNmb3JtaW5nKGRlZi5lbGVtZW50LCBjdHgpO1xuICAgICAgICAgICAgfVxuICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZm9yKGNvbnN0IGtleSBpbiBkZWYuc2hhcGUpe1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNUcmFuc2Zvcm1pbmcoZGVmLnNoYXBlW2tleV0sIGN0eCkpIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIGNhc2UgXCJ1bmlvblwiOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3Qgb3B0aW9uIG9mIGRlZi5vcHRpb25zKXtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzVHJhbnNmb3JtaW5nKG9wdGlvbiwgY3R4KSkgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgY2FzZSBcImludGVyc2VjdGlvblwiOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHJldHVybiBpc1RyYW5zZm9ybWluZyhkZWYubGVmdCwgY3R4KSB8fCBpc1RyYW5zZm9ybWluZyhkZWYucmlnaHQsIGN0eCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIGNhc2UgXCJ0dXBsZVwiOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBkZWYuaXRlbXMpe1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNUcmFuc2Zvcm1pbmcoaXRlbSwgY3R4KSkgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChkZWYucmVzdCAmJiBpc1RyYW5zZm9ybWluZyhkZWYucmVzdCwgY3R4KSkgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICBjYXNlIFwicmVjb3JkXCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlzVHJhbnNmb3JtaW5nKGRlZi5rZXlUeXBlLCBjdHgpIHx8IGlzVHJhbnNmb3JtaW5nKGRlZi52YWx1ZVR5cGUsIGN0eCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIGNhc2UgXCJtYXBcIjpcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaXNUcmFuc2Zvcm1pbmcoZGVmLmtleVR5cGUsIGN0eCkgfHwgaXNUcmFuc2Zvcm1pbmcoZGVmLnZhbHVlVHlwZSwgY3R4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgY2FzZSBcInNldFwiOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHJldHVybiBpc1RyYW5zZm9ybWluZyhkZWYudmFsdWVUeXBlLCBjdHgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAvLyBpbm5lciB0eXBlc1xuICAgICAgICBjYXNlIFwicHJvbWlzZVwiOlxuICAgICAgICBjYXNlIFwib3B0aW9uYWxcIjpcbiAgICAgICAgY2FzZSBcIm5vbm9wdGlvbmFsXCI6XG4gICAgICAgIGNhc2UgXCJudWxsYWJsZVwiOlxuICAgICAgICBjYXNlIFwicmVhZG9ubHlcIjpcbiAgICAgICAgICAgIHJldHVybiBpc1RyYW5zZm9ybWluZyhkZWYuaW5uZXJUeXBlLCBjdHgpO1xuICAgICAgICBjYXNlIFwibGF6eVwiOlxuICAgICAgICAgICAgcmV0dXJuIGlzVHJhbnNmb3JtaW5nKGRlZi5nZXR0ZXIoKSwgY3R4KTtcbiAgICAgICAgY2FzZSBcImRlZmF1bHRcIjpcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaXNUcmFuc2Zvcm1pbmcoZGVmLmlubmVyVHlwZSwgY3R4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgY2FzZSBcInByZWZhdWx0XCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlzVHJhbnNmb3JtaW5nKGRlZi5pbm5lclR5cGUsIGN0eCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIGNhc2UgXCJjdXN0b21cIjpcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIGNhc2UgXCJ0cmFuc2Zvcm1cIjpcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgY2FzZSBcInBpcGVcIjpcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaXNUcmFuc2Zvcm1pbmcoZGVmLmluLCBjdHgpIHx8IGlzVHJhbnNmb3JtaW5nKGRlZi5vdXQsIGN0eCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIGNhc2UgXCJzdWNjZXNzXCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICBjYXNlIFwiY2F0Y2hcIjpcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIGNhc2UgXCJmdW5jdGlvblwiOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIGRlZjtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIHNjaGVtYSB0eXBlOiAke2RlZi50eXBlfWApO1xufVxuIiwgImV4cG9ydCB7IH07XG4iLCAiaW1wb3J0ICogYXMgY29yZSBmcm9tIFwiLi4vY29yZS9pbmRleC5qc1wiO1xuaW1wb3J0ICogYXMgc2NoZW1hcyBmcm9tIFwiLi9zY2hlbWFzLmpzXCI7XG5leHBvcnQgY29uc3QgWm9kSVNPRGF0ZVRpbWUgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kSVNPRGF0ZVRpbWVcIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RJU09EYXRlVGltZS5pbml0KGluc3QsIGRlZik7XG4gICAgc2NoZW1hcy5ab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gZGF0ZXRpbWUocGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX2lzb0RhdGVUaW1lKFpvZElTT0RhdGVUaW1lLCBwYXJhbXMpO1xufVxuZXhwb3J0IGNvbnN0IFpvZElTT0RhdGUgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kSVNPRGF0ZVwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZElTT0RhdGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIHNjaGVtYXMuWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIGRhdGUocGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX2lzb0RhdGUoWm9kSVNPRGF0ZSwgcGFyYW1zKTtcbn1cbmV4cG9ydCBjb25zdCBab2RJU09UaW1lID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZElTT1RpbWVcIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RJU09UaW1lLmluaXQoaW5zdCwgZGVmKTtcbiAgICBzY2hlbWFzLlpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiB0aW1lKHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9pc29UaW1lKFpvZElTT1RpbWUsIHBhcmFtcyk7XG59XG5leHBvcnQgY29uc3QgWm9kSVNPRHVyYXRpb24gPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kSVNPRHVyYXRpb25cIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RJU09EdXJhdGlvbi5pbml0KGluc3QsIGRlZik7XG4gICAgc2NoZW1hcy5ab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gZHVyYXRpb24ocGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX2lzb0R1cmF0aW9uKFpvZElTT0R1cmF0aW9uLCBwYXJhbXMpO1xufVxuIiwgImltcG9ydCAqIGFzIGNvcmUgZnJvbSBcIi4uL2NvcmUvaW5kZXguanNcIjtcbmltcG9ydCB7ICRab2RFcnJvciB9IGZyb20gXCIuLi9jb3JlL2luZGV4LmpzXCI7XG5pbXBvcnQgKiBhcyB1dGlsIGZyb20gXCIuLi9jb3JlL3V0aWwuanNcIjtcbmNvbnN0IGluaXRpYWxpemVyID0gKGluc3QsIGlzc3Vlcyk9PntcbiAgICAkWm9kRXJyb3IuaW5pdChpbnN0LCBpc3N1ZXMpO1xuICAgIGluc3QubmFtZSA9IFwiWm9kRXJyb3JcIjtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhpbnN0LCB7XG4gICAgICAgIGZvcm1hdDoge1xuICAgICAgICAgICAgdmFsdWU6IChtYXBwZXIpPT5jb3JlLmZvcm1hdEVycm9yKGluc3QsIG1hcHBlcilcbiAgICAgICAgfSxcbiAgICAgICAgZmxhdHRlbjoge1xuICAgICAgICAgICAgdmFsdWU6IChtYXBwZXIpPT5jb3JlLmZsYXR0ZW5FcnJvcihpbnN0LCBtYXBwZXIpXG4gICAgICAgIH0sXG4gICAgICAgIGFkZElzc3VlOiB7XG4gICAgICAgICAgICB2YWx1ZTogKGlzc3VlKT0+e1xuICAgICAgICAgICAgICAgIGluc3QuaXNzdWVzLnB1c2goaXNzdWUpO1xuICAgICAgICAgICAgICAgIGluc3QubWVzc2FnZSA9IEpTT04uc3RyaW5naWZ5KGluc3QuaXNzdWVzLCB1dGlsLmpzb25TdHJpbmdpZnlSZXBsYWNlciwgMik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGFkZElzc3Vlczoge1xuICAgICAgICAgICAgdmFsdWU6IChpc3N1ZXMpPT57XG4gICAgICAgICAgICAgICAgaW5zdC5pc3N1ZXMucHVzaCguLi5pc3N1ZXMpO1xuICAgICAgICAgICAgICAgIGluc3QubWVzc2FnZSA9IEpTT04uc3RyaW5naWZ5KGluc3QuaXNzdWVzLCB1dGlsLmpzb25TdHJpbmdpZnlSZXBsYWNlciwgMik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGlzRW1wdHk6IHtcbiAgICAgICAgICAgIGdldCAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGluc3QuaXNzdWVzLmxlbmd0aCA9PT0gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0pO1xuLy8gT2JqZWN0LmRlZmluZVByb3BlcnR5KGluc3QsIFwiaXNFbXB0eVwiLCB7XG4vLyAgIGdldCgpIHtcbi8vICAgICByZXR1cm4gaW5zdC5pc3N1ZXMubGVuZ3RoID09PSAwO1xuLy8gICB9LFxuLy8gfSk7XG59O1xuZXhwb3J0IGNvbnN0IFpvZEVycm9yID0gY29yZS4kY29uc3RydWN0b3IoXCJab2RFcnJvclwiLCBpbml0aWFsaXplcik7XG5leHBvcnQgY29uc3QgWm9kUmVhbEVycm9yID0gY29yZS4kY29uc3RydWN0b3IoXCJab2RFcnJvclwiLCBpbml0aWFsaXplciwge1xuICAgIFBhcmVudDogRXJyb3Jcbn0pOyAvLyAvKiogQGRlcHJlY2F0ZWQgVXNlIGB6LmNvcmUuJFpvZEVycm9yTWFwQ3R4YCBpbnN0ZWFkLiAqL1xuIC8vIGV4cG9ydCB0eXBlIEVycm9yTWFwQ3R4ID0gY29yZS4kWm9kRXJyb3JNYXBDdHg7XG4iLCAiaW1wb3J0ICogYXMgY29yZSBmcm9tIFwiLi4vY29yZS9pbmRleC5qc1wiO1xuaW1wb3J0IHsgWm9kUmVhbEVycm9yIH0gZnJvbSBcIi4vZXJyb3JzLmpzXCI7XG5leHBvcnQgY29uc3QgcGFyc2UgPSAvKiBAX19QVVJFX18gKi8gY29yZS5fcGFyc2UoWm9kUmVhbEVycm9yKTtcbmV4cG9ydCBjb25zdCBwYXJzZUFzeW5jID0gLyogQF9fUFVSRV9fICovIGNvcmUuX3BhcnNlQXN5bmMoWm9kUmVhbEVycm9yKTtcbmV4cG9ydCBjb25zdCBzYWZlUGFyc2UgPSAvKiBAX19QVVJFX18gKi8gY29yZS5fc2FmZVBhcnNlKFpvZFJlYWxFcnJvcik7XG5leHBvcnQgY29uc3Qgc2FmZVBhcnNlQXN5bmMgPSAvKiBAX19QVVJFX18gKi8gY29yZS5fc2FmZVBhcnNlQXN5bmMoWm9kUmVhbEVycm9yKTtcbi8vIENvZGVjIGZ1bmN0aW9uc1xuZXhwb3J0IGNvbnN0IGVuY29kZSA9IC8qIEBfX1BVUkVfXyAqLyBjb3JlLl9lbmNvZGUoWm9kUmVhbEVycm9yKTtcbmV4cG9ydCBjb25zdCBkZWNvZGUgPSAvKiBAX19QVVJFX18gKi8gY29yZS5fZGVjb2RlKFpvZFJlYWxFcnJvcik7XG5leHBvcnQgY29uc3QgZW5jb2RlQXN5bmMgPSAvKiBAX19QVVJFX18gKi8gY29yZS5fZW5jb2RlQXN5bmMoWm9kUmVhbEVycm9yKTtcbmV4cG9ydCBjb25zdCBkZWNvZGVBc3luYyA9IC8qIEBfX1BVUkVfXyAqLyBjb3JlLl9kZWNvZGVBc3luYyhab2RSZWFsRXJyb3IpO1xuZXhwb3J0IGNvbnN0IHNhZmVFbmNvZGUgPSAvKiBAX19QVVJFX18gKi8gY29yZS5fc2FmZUVuY29kZShab2RSZWFsRXJyb3IpO1xuZXhwb3J0IGNvbnN0IHNhZmVEZWNvZGUgPSAvKiBAX19QVVJFX18gKi8gY29yZS5fc2FmZURlY29kZShab2RSZWFsRXJyb3IpO1xuZXhwb3J0IGNvbnN0IHNhZmVFbmNvZGVBc3luYyA9IC8qIEBfX1BVUkVfXyAqLyBjb3JlLl9zYWZlRW5jb2RlQXN5bmMoWm9kUmVhbEVycm9yKTtcbmV4cG9ydCBjb25zdCBzYWZlRGVjb2RlQXN5bmMgPSAvKiBAX19QVVJFX18gKi8gY29yZS5fc2FmZURlY29kZUFzeW5jKFpvZFJlYWxFcnJvcik7XG4iLCAiaW1wb3J0ICogYXMgY29yZSBmcm9tIFwiLi4vY29yZS9pbmRleC5qc1wiO1xuaW1wb3J0IHsgdXRpbCB9IGZyb20gXCIuLi9jb3JlL2luZGV4LmpzXCI7XG5pbXBvcnQgKiBhcyBjaGVja3MgZnJvbSBcIi4vY2hlY2tzLmpzXCI7XG5pbXBvcnQgKiBhcyBpc28gZnJvbSBcIi4vaXNvLmpzXCI7XG5pbXBvcnQgKiBhcyBwYXJzZSBmcm9tIFwiLi9wYXJzZS5qc1wiO1xuZXhwb3J0IGNvbnN0IFpvZFR5cGUgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kVHlwZVwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuZGVmID0gZGVmO1xuICAgIGluc3QudHlwZSA9IGRlZi50eXBlO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShpbnN0LCBcIl9kZWZcIiwge1xuICAgICAgICB2YWx1ZTogZGVmXG4gICAgfSk7XG4gICAgLy8gYmFzZSBtZXRob2RzXG4gICAgaW5zdC5jaGVjayA9ICguLi5jaGVja3MpPT57XG4gICAgICAgIHJldHVybiBpbnN0LmNsb25lKHV0aWwubWVyZ2VEZWZzKGRlZiwge1xuICAgICAgICAgICAgY2hlY2tzOiBbXG4gICAgICAgICAgICAgICAgLi4uZGVmLmNoZWNrcyA/PyBbXSxcbiAgICAgICAgICAgICAgICAuLi5jaGVja3MubWFwKChjaCk9PnR5cGVvZiBjaCA9PT0gXCJmdW5jdGlvblwiID8ge1xuICAgICAgICAgICAgICAgICAgICAgICAgX3pvZDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrOiBjaCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWY6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2s6IFwiY3VzdG9tXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uYXR0YWNoOiBbXVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IDogY2gpXG4gICAgICAgICAgICBdXG4gICAgICAgIH0pKTtcbiAgICB9O1xuICAgIGluc3QuY2xvbmUgPSAoZGVmLCBwYXJhbXMpPT5jb3JlLmNsb25lKGluc3QsIGRlZiwgcGFyYW1zKTtcbiAgICBpbnN0LmJyYW5kID0gKCk9Pmluc3Q7XG4gICAgaW5zdC5yZWdpc3RlciA9IChyZWcsIG1ldGEpPT57XG4gICAgICAgIHJlZy5hZGQoaW5zdCwgbWV0YSk7XG4gICAgICAgIHJldHVybiBpbnN0O1xuICAgIH07XG4gICAgLy8gcGFyc2luZ1xuICAgIGluc3QucGFyc2UgPSAoZGF0YSwgcGFyYW1zKT0+cGFyc2UucGFyc2UoaW5zdCwgZGF0YSwgcGFyYW1zLCB7XG4gICAgICAgICAgICBjYWxsZWU6IGluc3QucGFyc2VcbiAgICAgICAgfSk7XG4gICAgaW5zdC5zYWZlUGFyc2UgPSAoZGF0YSwgcGFyYW1zKT0+cGFyc2Uuc2FmZVBhcnNlKGluc3QsIGRhdGEsIHBhcmFtcyk7XG4gICAgaW5zdC5wYXJzZUFzeW5jID0gYXN5bmMgKGRhdGEsIHBhcmFtcyk9PnBhcnNlLnBhcnNlQXN5bmMoaW5zdCwgZGF0YSwgcGFyYW1zLCB7XG4gICAgICAgICAgICBjYWxsZWU6IGluc3QucGFyc2VBc3luY1xuICAgICAgICB9KTtcbiAgICBpbnN0LnNhZmVQYXJzZUFzeW5jID0gYXN5bmMgKGRhdGEsIHBhcmFtcyk9PnBhcnNlLnNhZmVQYXJzZUFzeW5jKGluc3QsIGRhdGEsIHBhcmFtcyk7XG4gICAgaW5zdC5zcGEgPSBpbnN0LnNhZmVQYXJzZUFzeW5jO1xuICAgIC8vIGVuY29kaW5nL2RlY29kaW5nXG4gICAgaW5zdC5lbmNvZGUgPSAoZGF0YSwgcGFyYW1zKT0+cGFyc2UuZW5jb2RlKGluc3QsIGRhdGEsIHBhcmFtcyk7XG4gICAgaW5zdC5kZWNvZGUgPSAoZGF0YSwgcGFyYW1zKT0+cGFyc2UuZGVjb2RlKGluc3QsIGRhdGEsIHBhcmFtcyk7XG4gICAgaW5zdC5lbmNvZGVBc3luYyA9IGFzeW5jIChkYXRhLCBwYXJhbXMpPT5wYXJzZS5lbmNvZGVBc3luYyhpbnN0LCBkYXRhLCBwYXJhbXMpO1xuICAgIGluc3QuZGVjb2RlQXN5bmMgPSBhc3luYyAoZGF0YSwgcGFyYW1zKT0+cGFyc2UuZGVjb2RlQXN5bmMoaW5zdCwgZGF0YSwgcGFyYW1zKTtcbiAgICBpbnN0LnNhZmVFbmNvZGUgPSAoZGF0YSwgcGFyYW1zKT0+cGFyc2Uuc2FmZUVuY29kZShpbnN0LCBkYXRhLCBwYXJhbXMpO1xuICAgIGluc3Quc2FmZURlY29kZSA9IChkYXRhLCBwYXJhbXMpPT5wYXJzZS5zYWZlRGVjb2RlKGluc3QsIGRhdGEsIHBhcmFtcyk7XG4gICAgaW5zdC5zYWZlRW5jb2RlQXN5bmMgPSBhc3luYyAoZGF0YSwgcGFyYW1zKT0+cGFyc2Uuc2FmZUVuY29kZUFzeW5jKGluc3QsIGRhdGEsIHBhcmFtcyk7XG4gICAgaW5zdC5zYWZlRGVjb2RlQXN5bmMgPSBhc3luYyAoZGF0YSwgcGFyYW1zKT0+cGFyc2Uuc2FmZURlY29kZUFzeW5jKGluc3QsIGRhdGEsIHBhcmFtcyk7XG4gICAgLy8gcmVmaW5lbWVudHNcbiAgICBpbnN0LnJlZmluZSA9IChjaGVjaywgcGFyYW1zKT0+aW5zdC5jaGVjayhyZWZpbmUoY2hlY2ssIHBhcmFtcykpO1xuICAgIGluc3Quc3VwZXJSZWZpbmUgPSAocmVmaW5lbWVudCk9Pmluc3QuY2hlY2soc3VwZXJSZWZpbmUocmVmaW5lbWVudCkpO1xuICAgIGluc3Qub3ZlcndyaXRlID0gKGZuKT0+aW5zdC5jaGVjayhjaGVja3Mub3ZlcndyaXRlKGZuKSk7XG4gICAgLy8gd3JhcHBlcnNcbiAgICBpbnN0Lm9wdGlvbmFsID0gKCk9Pm9wdGlvbmFsKGluc3QpO1xuICAgIGluc3QubnVsbGFibGUgPSAoKT0+bnVsbGFibGUoaW5zdCk7XG4gICAgaW5zdC5udWxsaXNoID0gKCk9Pm9wdGlvbmFsKG51bGxhYmxlKGluc3QpKTtcbiAgICBpbnN0Lm5vbm9wdGlvbmFsID0gKHBhcmFtcyk9Pm5vbm9wdGlvbmFsKGluc3QsIHBhcmFtcyk7XG4gICAgaW5zdC5hcnJheSA9ICgpPT5hcnJheShpbnN0KTtcbiAgICBpbnN0Lm9yID0gKGFyZyk9PnVuaW9uKFtcbiAgICAgICAgICAgIGluc3QsXG4gICAgICAgICAgICBhcmdcbiAgICAgICAgXSk7XG4gICAgaW5zdC5hbmQgPSAoYXJnKT0+aW50ZXJzZWN0aW9uKGluc3QsIGFyZyk7XG4gICAgaW5zdC50cmFuc2Zvcm0gPSAodHgpPT5waXBlKGluc3QsIHRyYW5zZm9ybSh0eCkpO1xuICAgIGluc3QuZGVmYXVsdCA9IChkZWYpPT5fZGVmYXVsdChpbnN0LCBkZWYpO1xuICAgIGluc3QucHJlZmF1bHQgPSAoZGVmKT0+cHJlZmF1bHQoaW5zdCwgZGVmKTtcbiAgICAvLyBpbnN0LmNvYWxlc2NlID0gKGRlZiwgcGFyYW1zKSA9PiBjb2FsZXNjZShpbnN0LCBkZWYsIHBhcmFtcyk7XG4gICAgaW5zdC5jYXRjaCA9IChwYXJhbXMpPT5fY2F0Y2goaW5zdCwgcGFyYW1zKTtcbiAgICBpbnN0LnBpcGUgPSAodGFyZ2V0KT0+cGlwZShpbnN0LCB0YXJnZXQpO1xuICAgIGluc3QucmVhZG9ubHkgPSAoKT0+cmVhZG9ubHkoaW5zdCk7XG4gICAgLy8gbWV0YVxuICAgIGluc3QuZGVzY3JpYmUgPSAoZGVzY3JpcHRpb24pPT57XG4gICAgICAgIGNvbnN0IGNsID0gaW5zdC5jbG9uZSgpO1xuICAgICAgICBjb3JlLmdsb2JhbFJlZ2lzdHJ5LmFkZChjbCwge1xuICAgICAgICAgICAgZGVzY3JpcHRpb25cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBjbDtcbiAgICB9O1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShpbnN0LCBcImRlc2NyaXB0aW9uXCIsIHtcbiAgICAgICAgZ2V0ICgpIHtcbiAgICAgICAgICAgIHJldHVybiBjb3JlLmdsb2JhbFJlZ2lzdHJ5LmdldChpbnN0KT8uZGVzY3JpcHRpb247XG4gICAgICAgIH0sXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH0pO1xuICAgIGluc3QubWV0YSA9ICguLi5hcmdzKT0+e1xuICAgICAgICBpZiAoYXJncy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBjb3JlLmdsb2JhbFJlZ2lzdHJ5LmdldChpbnN0KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjbCA9IGluc3QuY2xvbmUoKTtcbiAgICAgICAgY29yZS5nbG9iYWxSZWdpc3RyeS5hZGQoY2wsIGFyZ3NbMF0pO1xuICAgICAgICByZXR1cm4gY2w7XG4gICAgfTtcbiAgICAvLyBoZWxwZXJzXG4gICAgaW5zdC5pc09wdGlvbmFsID0gKCk9Pmluc3Quc2FmZVBhcnNlKHVuZGVmaW5lZCkuc3VjY2VzcztcbiAgICBpbnN0LmlzTnVsbGFibGUgPSAoKT0+aW5zdC5zYWZlUGFyc2UobnVsbCkuc3VjY2VzcztcbiAgICByZXR1cm4gaW5zdDtcbn0pO1xuLyoqIEBpbnRlcm5hbCAqLyBleHBvcnQgY29uc3QgX1pvZFN0cmluZyA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJfWm9kU3RyaW5nXCIsIChpbnN0LCBkZWYpPT57XG4gICAgY29yZS4kWm9kU3RyaW5nLmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBjb25zdCBiYWcgPSBpbnN0Ll96b2QuYmFnO1xuICAgIGluc3QuZm9ybWF0ID0gYmFnLmZvcm1hdCA/PyBudWxsO1xuICAgIGluc3QubWluTGVuZ3RoID0gYmFnLm1pbmltdW0gPz8gbnVsbDtcbiAgICBpbnN0Lm1heExlbmd0aCA9IGJhZy5tYXhpbXVtID8/IG51bGw7XG4gICAgLy8gdmFsaWRhdGlvbnNcbiAgICBpbnN0LnJlZ2V4ID0gKC4uLmFyZ3MpPT5pbnN0LmNoZWNrKGNoZWNrcy5yZWdleCguLi5hcmdzKSk7XG4gICAgaW5zdC5pbmNsdWRlcyA9ICguLi5hcmdzKT0+aW5zdC5jaGVjayhjaGVja3MuaW5jbHVkZXMoLi4uYXJncykpO1xuICAgIGluc3Quc3RhcnRzV2l0aCA9ICguLi5hcmdzKT0+aW5zdC5jaGVjayhjaGVja3Muc3RhcnRzV2l0aCguLi5hcmdzKSk7XG4gICAgaW5zdC5lbmRzV2l0aCA9ICguLi5hcmdzKT0+aW5zdC5jaGVjayhjaGVja3MuZW5kc1dpdGgoLi4uYXJncykpO1xuICAgIGluc3QubWluID0gKC4uLmFyZ3MpPT5pbnN0LmNoZWNrKGNoZWNrcy5taW5MZW5ndGgoLi4uYXJncykpO1xuICAgIGluc3QubWF4ID0gKC4uLmFyZ3MpPT5pbnN0LmNoZWNrKGNoZWNrcy5tYXhMZW5ndGgoLi4uYXJncykpO1xuICAgIGluc3QubGVuZ3RoID0gKC4uLmFyZ3MpPT5pbnN0LmNoZWNrKGNoZWNrcy5sZW5ndGgoLi4uYXJncykpO1xuICAgIGluc3Qubm9uZW1wdHkgPSAoLi4uYXJncyk9Pmluc3QuY2hlY2soY2hlY2tzLm1pbkxlbmd0aCgxLCAuLi5hcmdzKSk7XG4gICAgaW5zdC5sb3dlcmNhc2UgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhjaGVja3MubG93ZXJjYXNlKHBhcmFtcykpO1xuICAgIGluc3QudXBwZXJjYXNlID0gKHBhcmFtcyk9Pmluc3QuY2hlY2soY2hlY2tzLnVwcGVyY2FzZShwYXJhbXMpKTtcbiAgICAvLyB0cmFuc2Zvcm1zXG4gICAgaW5zdC50cmltID0gKCk9Pmluc3QuY2hlY2soY2hlY2tzLnRyaW0oKSk7XG4gICAgaW5zdC5ub3JtYWxpemUgPSAoLi4uYXJncyk9Pmluc3QuY2hlY2soY2hlY2tzLm5vcm1hbGl6ZSguLi5hcmdzKSk7XG4gICAgaW5zdC50b0xvd2VyQ2FzZSA9ICgpPT5pbnN0LmNoZWNrKGNoZWNrcy50b0xvd2VyQ2FzZSgpKTtcbiAgICBpbnN0LnRvVXBwZXJDYXNlID0gKCk9Pmluc3QuY2hlY2soY2hlY2tzLnRvVXBwZXJDYXNlKCkpO1xufSk7XG5leHBvcnQgY29uc3QgWm9kU3RyaW5nID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZFN0cmluZ1wiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZFN0cmluZy5pbml0KGluc3QsIGRlZik7XG4gICAgX1pvZFN0cmluZy5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5lbWFpbCA9IChwYXJhbXMpPT5pbnN0LmNoZWNrKGNvcmUuX2VtYWlsKFpvZEVtYWlsLCBwYXJhbXMpKTtcbiAgICBpbnN0LnVybCA9IChwYXJhbXMpPT5pbnN0LmNoZWNrKGNvcmUuX3VybChab2RVUkwsIHBhcmFtcykpO1xuICAgIGluc3Quand0ID0gKHBhcmFtcyk9Pmluc3QuY2hlY2soY29yZS5fand0KFpvZEpXVCwgcGFyYW1zKSk7XG4gICAgaW5zdC5lbW9qaSA9IChwYXJhbXMpPT5pbnN0LmNoZWNrKGNvcmUuX2Vtb2ppKFpvZEVtb2ppLCBwYXJhbXMpKTtcbiAgICBpbnN0Lmd1aWQgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhjb3JlLl9ndWlkKFpvZEdVSUQsIHBhcmFtcykpO1xuICAgIGluc3QudXVpZCA9IChwYXJhbXMpPT5pbnN0LmNoZWNrKGNvcmUuX3V1aWQoWm9kVVVJRCwgcGFyYW1zKSk7XG4gICAgaW5zdC51dWlkdjQgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhjb3JlLl91dWlkdjQoWm9kVVVJRCwgcGFyYW1zKSk7XG4gICAgaW5zdC51dWlkdjYgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhjb3JlLl91dWlkdjYoWm9kVVVJRCwgcGFyYW1zKSk7XG4gICAgaW5zdC51dWlkdjcgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhjb3JlLl91dWlkdjcoWm9kVVVJRCwgcGFyYW1zKSk7XG4gICAgaW5zdC5uYW5vaWQgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhjb3JlLl9uYW5vaWQoWm9kTmFub0lELCBwYXJhbXMpKTtcbiAgICBpbnN0Lmd1aWQgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhjb3JlLl9ndWlkKFpvZEdVSUQsIHBhcmFtcykpO1xuICAgIGluc3QuY3VpZCA9IChwYXJhbXMpPT5pbnN0LmNoZWNrKGNvcmUuX2N1aWQoWm9kQ1VJRCwgcGFyYW1zKSk7XG4gICAgaW5zdC5jdWlkMiA9IChwYXJhbXMpPT5pbnN0LmNoZWNrKGNvcmUuX2N1aWQyKFpvZENVSUQyLCBwYXJhbXMpKTtcbiAgICBpbnN0LnVsaWQgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhjb3JlLl91bGlkKFpvZFVMSUQsIHBhcmFtcykpO1xuICAgIGluc3QuYmFzZTY0ID0gKHBhcmFtcyk9Pmluc3QuY2hlY2soY29yZS5fYmFzZTY0KFpvZEJhc2U2NCwgcGFyYW1zKSk7XG4gICAgaW5zdC5iYXNlNjR1cmwgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhjb3JlLl9iYXNlNjR1cmwoWm9kQmFzZTY0VVJMLCBwYXJhbXMpKTtcbiAgICBpbnN0LnhpZCA9IChwYXJhbXMpPT5pbnN0LmNoZWNrKGNvcmUuX3hpZChab2RYSUQsIHBhcmFtcykpO1xuICAgIGluc3Qua3N1aWQgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhjb3JlLl9rc3VpZChab2RLU1VJRCwgcGFyYW1zKSk7XG4gICAgaW5zdC5pcHY0ID0gKHBhcmFtcyk9Pmluc3QuY2hlY2soY29yZS5faXB2NChab2RJUHY0LCBwYXJhbXMpKTtcbiAgICBpbnN0LmlwdjYgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhjb3JlLl9pcHY2KFpvZElQdjYsIHBhcmFtcykpO1xuICAgIGluc3QuY2lkcnY0ID0gKHBhcmFtcyk9Pmluc3QuY2hlY2soY29yZS5fY2lkcnY0KFpvZENJRFJ2NCwgcGFyYW1zKSk7XG4gICAgaW5zdC5jaWRydjYgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhjb3JlLl9jaWRydjYoWm9kQ0lEUnY2LCBwYXJhbXMpKTtcbiAgICBpbnN0LmUxNjQgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhjb3JlLl9lMTY0KFpvZEUxNjQsIHBhcmFtcykpO1xuICAgIC8vIGlzb1xuICAgIGluc3QuZGF0ZXRpbWUgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhpc28uZGF0ZXRpbWUocGFyYW1zKSk7XG4gICAgaW5zdC5kYXRlID0gKHBhcmFtcyk9Pmluc3QuY2hlY2soaXNvLmRhdGUocGFyYW1zKSk7XG4gICAgaW5zdC50aW1lID0gKHBhcmFtcyk9Pmluc3QuY2hlY2soaXNvLnRpbWUocGFyYW1zKSk7XG4gICAgaW5zdC5kdXJhdGlvbiA9IChwYXJhbXMpPT5pbnN0LmNoZWNrKGlzby5kdXJhdGlvbihwYXJhbXMpKTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIHN0cmluZyhwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fc3RyaW5nKFpvZFN0cmluZywgcGFyYW1zKTtcbn1cbmV4cG9ydCBjb25zdCBab2RTdHJpbmdGb3JtYXQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kU3RyaW5nRm9ybWF0XCIsIChpbnN0LCBkZWYpPT57XG4gICAgY29yZS4kWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbiAgICBfWm9kU3RyaW5nLmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGNvbnN0IFpvZEVtYWlsID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZEVtYWlsXCIsIChpbnN0LCBkZWYpPT57XG4gICAgLy8gWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbiAgICBjb3JlLiRab2RFbWFpbC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIGVtYWlsKHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9lbWFpbChab2RFbWFpbCwgcGFyYW1zKTtcbn1cbmV4cG9ydCBjb25zdCBab2RHVUlEID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZEdVSURcIiwgKGluc3QsIGRlZik9PntcbiAgICAvLyBab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xuICAgIGNvcmUuJFpvZEdVSUQuaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBndWlkKHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9ndWlkKFpvZEdVSUQsIHBhcmFtcyk7XG59XG5leHBvcnQgY29uc3QgWm9kVVVJRCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2RVVUlEXCIsIChpbnN0LCBkZWYpPT57XG4gICAgLy8gWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbiAgICBjb3JlLiRab2RVVUlELmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gdXVpZChwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fdXVpZChab2RVVUlELCBwYXJhbXMpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHV1aWR2NChwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fdXVpZHY0KFpvZFVVSUQsIHBhcmFtcyk7XG59XG4vLyBab2RVVUlEdjZcbmV4cG9ydCBmdW5jdGlvbiB1dWlkdjYocGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX3V1aWR2Nihab2RVVUlELCBwYXJhbXMpO1xufVxuLy8gWm9kVVVJRHY3XG5leHBvcnQgZnVuY3Rpb24gdXVpZHY3KHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl91dWlkdjcoWm9kVVVJRCwgcGFyYW1zKTtcbn1cbmV4cG9ydCBjb25zdCBab2RVUkwgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kVVJMXCIsIChpbnN0LCBkZWYpPT57XG4gICAgLy8gWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbiAgICBjb3JlLiRab2RVUkwuaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiB1cmwocGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX3VybChab2RVUkwsIHBhcmFtcyk7XG59XG5leHBvcnQgZnVuY3Rpb24gaHR0cFVybChwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fdXJsKFpvZFVSTCwge1xuICAgICAgICBwcm90b2NvbDogL15odHRwcz8kLyxcbiAgICAgICAgaG9zdG5hbWU6IGNvcmUucmVnZXhlcy5kb21haW4sXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBjb25zdCBab2RFbW9qaSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2RFbW9qaVwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIC8vIFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG4gICAgY29yZS4kWm9kRW1vamkuaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBlbW9qaShwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fZW1vamkoWm9kRW1vamksIHBhcmFtcyk7XG59XG5leHBvcnQgY29uc3QgWm9kTmFub0lEID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZE5hbm9JRFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIC8vIFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG4gICAgY29yZS4kWm9kTmFub0lELmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gbmFub2lkKHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9uYW5vaWQoWm9kTmFub0lELCBwYXJhbXMpO1xufVxuZXhwb3J0IGNvbnN0IFpvZENVSUQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kQ1VJRFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIC8vIFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG4gICAgY29yZS4kWm9kQ1VJRC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIGN1aWQocGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX2N1aWQoWm9kQ1VJRCwgcGFyYW1zKTtcbn1cbmV4cG9ydCBjb25zdCBab2RDVUlEMiA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2RDVUlEMlwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIC8vIFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG4gICAgY29yZS4kWm9kQ1VJRDIuaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBjdWlkMihwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fY3VpZDIoWm9kQ1VJRDIsIHBhcmFtcyk7XG59XG5leHBvcnQgY29uc3QgWm9kVUxJRCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2RVTElEXCIsIChpbnN0LCBkZWYpPT57XG4gICAgLy8gWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbiAgICBjb3JlLiRab2RVTElELmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gdWxpZChwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fdWxpZChab2RVTElELCBwYXJhbXMpO1xufVxuZXhwb3J0IGNvbnN0IFpvZFhJRCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2RYSURcIiwgKGluc3QsIGRlZik9PntcbiAgICAvLyBab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xuICAgIGNvcmUuJFpvZFhJRC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIHhpZChwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5feGlkKFpvZFhJRCwgcGFyYW1zKTtcbn1cbmV4cG9ydCBjb25zdCBab2RLU1VJRCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2RLU1VJRFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIC8vIFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG4gICAgY29yZS4kWm9kS1NVSUQuaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBrc3VpZChwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fa3N1aWQoWm9kS1NVSUQsIHBhcmFtcyk7XG59XG5leHBvcnQgY29uc3QgWm9kSVB2NCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2RJUHY0XCIsIChpbnN0LCBkZWYpPT57XG4gICAgLy8gWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbiAgICBjb3JlLiRab2RJUHY0LmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gaXB2NChwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5faXB2NChab2RJUHY0LCBwYXJhbXMpO1xufVxuZXhwb3J0IGNvbnN0IFpvZElQdjYgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kSVB2NlwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIC8vIFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG4gICAgY29yZS4kWm9kSVB2Ni5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIGlwdjYocGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX2lwdjYoWm9kSVB2NiwgcGFyYW1zKTtcbn1cbmV4cG9ydCBjb25zdCBab2RDSURSdjQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kQ0lEUnY0XCIsIChpbnN0LCBkZWYpPT57XG4gICAgY29yZS4kWm9kQ0lEUnY0LmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gY2lkcnY0KHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9jaWRydjQoWm9kQ0lEUnY0LCBwYXJhbXMpO1xufVxuZXhwb3J0IGNvbnN0IFpvZENJRFJ2NiA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2RDSURSdjZcIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RDSURSdjYuaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBjaWRydjYocGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX2NpZHJ2Nihab2RDSURSdjYsIHBhcmFtcyk7XG59XG5leHBvcnQgY29uc3QgWm9kQmFzZTY0ID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZEJhc2U2NFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIC8vIFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG4gICAgY29yZS4kWm9kQmFzZTY0LmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gYmFzZTY0KHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9iYXNlNjQoWm9kQmFzZTY0LCBwYXJhbXMpO1xufVxuZXhwb3J0IGNvbnN0IFpvZEJhc2U2NFVSTCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2RCYXNlNjRVUkxcIiwgKGluc3QsIGRlZik9PntcbiAgICAvLyBab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xuICAgIGNvcmUuJFpvZEJhc2U2NFVSTC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIGJhc2U2NHVybChwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fYmFzZTY0dXJsKFpvZEJhc2U2NFVSTCwgcGFyYW1zKTtcbn1cbmV4cG9ydCBjb25zdCBab2RFMTY0ID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZEUxNjRcIiwgKGluc3QsIGRlZik9PntcbiAgICAvLyBab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xuICAgIGNvcmUuJFpvZEUxNjQuaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBlMTY0KHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9lMTY0KFpvZEUxNjQsIHBhcmFtcyk7XG59XG5leHBvcnQgY29uc3QgWm9kSldUID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZEpXVFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIC8vIFpvZFN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG4gICAgY29yZS4kWm9kSldULmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gand0KHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9qd3QoWm9kSldULCBwYXJhbXMpO1xufVxuZXhwb3J0IGNvbnN0IFpvZEN1c3RvbVN0cmluZ0Zvcm1hdCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2RDdXN0b21TdHJpbmdGb3JtYXRcIiwgKGluc3QsIGRlZik9PntcbiAgICAvLyBab2RTdHJpbmdGb3JtYXQuaW5pdChpbnN0LCBkZWYpO1xuICAgIGNvcmUuJFpvZEN1c3RvbVN0cmluZ0Zvcm1hdC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kU3RyaW5nRm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIHN0cmluZ0Zvcm1hdChmb3JtYXQsIGZuT3JSZWdleCwgX3BhcmFtcyA9IHt9KSB7XG4gICAgcmV0dXJuIGNvcmUuX3N0cmluZ0Zvcm1hdChab2RDdXN0b21TdHJpbmdGb3JtYXQsIGZvcm1hdCwgZm5PclJlZ2V4LCBfcGFyYW1zKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBob3N0bmFtZShfcGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX3N0cmluZ0Zvcm1hdChab2RDdXN0b21TdHJpbmdGb3JtYXQsIFwiaG9zdG5hbWVcIiwgY29yZS5yZWdleGVzLmhvc3RuYW1lLCBfcGFyYW1zKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBoZXgoX3BhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9zdHJpbmdGb3JtYXQoWm9kQ3VzdG9tU3RyaW5nRm9ybWF0LCBcImhleFwiLCBjb3JlLnJlZ2V4ZXMuaGV4LCBfcGFyYW1zKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBoYXNoKGFsZywgcGFyYW1zKSB7XG4gICAgY29uc3QgZW5jID0gcGFyYW1zPy5lbmMgPz8gXCJoZXhcIjtcbiAgICBjb25zdCBmb3JtYXQgPSBgJHthbGd9XyR7ZW5jfWA7XG4gICAgY29uc3QgcmVnZXggPSBjb3JlLnJlZ2V4ZXNbZm9ybWF0XTtcbiAgICBpZiAoIXJlZ2V4KSB0aHJvdyBuZXcgRXJyb3IoYFVucmVjb2duaXplZCBoYXNoIGZvcm1hdDogJHtmb3JtYXR9YCk7XG4gICAgcmV0dXJuIGNvcmUuX3N0cmluZ0Zvcm1hdChab2RDdXN0b21TdHJpbmdGb3JtYXQsIGZvcm1hdCwgcmVnZXgsIHBhcmFtcyk7XG59XG5leHBvcnQgY29uc3QgWm9kTnVtYmVyID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZE51bWJlclwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZE51bWJlci5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5ndCA9ICh2YWx1ZSwgcGFyYW1zKT0+aW5zdC5jaGVjayhjaGVja3MuZ3QodmFsdWUsIHBhcmFtcykpO1xuICAgIGluc3QuZ3RlID0gKHZhbHVlLCBwYXJhbXMpPT5pbnN0LmNoZWNrKGNoZWNrcy5ndGUodmFsdWUsIHBhcmFtcykpO1xuICAgIGluc3QubWluID0gKHZhbHVlLCBwYXJhbXMpPT5pbnN0LmNoZWNrKGNoZWNrcy5ndGUodmFsdWUsIHBhcmFtcykpO1xuICAgIGluc3QubHQgPSAodmFsdWUsIHBhcmFtcyk9Pmluc3QuY2hlY2soY2hlY2tzLmx0KHZhbHVlLCBwYXJhbXMpKTtcbiAgICBpbnN0Lmx0ZSA9ICh2YWx1ZSwgcGFyYW1zKT0+aW5zdC5jaGVjayhjaGVja3MubHRlKHZhbHVlLCBwYXJhbXMpKTtcbiAgICBpbnN0Lm1heCA9ICh2YWx1ZSwgcGFyYW1zKT0+aW5zdC5jaGVjayhjaGVja3MubHRlKHZhbHVlLCBwYXJhbXMpKTtcbiAgICBpbnN0LmludCA9IChwYXJhbXMpPT5pbnN0LmNoZWNrKGludChwYXJhbXMpKTtcbiAgICBpbnN0LnNhZmUgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhpbnQocGFyYW1zKSk7XG4gICAgaW5zdC5wb3NpdGl2ZSA9IChwYXJhbXMpPT5pbnN0LmNoZWNrKGNoZWNrcy5ndCgwLCBwYXJhbXMpKTtcbiAgICBpbnN0Lm5vbm5lZ2F0aXZlID0gKHBhcmFtcyk9Pmluc3QuY2hlY2soY2hlY2tzLmd0ZSgwLCBwYXJhbXMpKTtcbiAgICBpbnN0Lm5lZ2F0aXZlID0gKHBhcmFtcyk9Pmluc3QuY2hlY2soY2hlY2tzLmx0KDAsIHBhcmFtcykpO1xuICAgIGluc3Qubm9ucG9zaXRpdmUgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhjaGVja3MubHRlKDAsIHBhcmFtcykpO1xuICAgIGluc3QubXVsdGlwbGVPZiA9ICh2YWx1ZSwgcGFyYW1zKT0+aW5zdC5jaGVjayhjaGVja3MubXVsdGlwbGVPZih2YWx1ZSwgcGFyYW1zKSk7XG4gICAgaW5zdC5zdGVwID0gKHZhbHVlLCBwYXJhbXMpPT5pbnN0LmNoZWNrKGNoZWNrcy5tdWx0aXBsZU9mKHZhbHVlLCBwYXJhbXMpKTtcbiAgICAvLyBpbnN0LmZpbml0ZSA9IChwYXJhbXMpID0+IGluc3QuY2hlY2soY29yZS5maW5pdGUocGFyYW1zKSk7XG4gICAgaW5zdC5maW5pdGUgPSAoKT0+aW5zdDtcbiAgICBjb25zdCBiYWcgPSBpbnN0Ll96b2QuYmFnO1xuICAgIGluc3QubWluVmFsdWUgPSBNYXRoLm1heChiYWcubWluaW11bSA/PyBOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFksIGJhZy5leGNsdXNpdmVNaW5pbXVtID8/IE51bWJlci5ORUdBVElWRV9JTkZJTklUWSkgPz8gbnVsbDtcbiAgICBpbnN0Lm1heFZhbHVlID0gTWF0aC5taW4oYmFnLm1heGltdW0gPz8gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZLCBiYWcuZXhjbHVzaXZlTWF4aW11bSA/PyBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkpID8/IG51bGw7XG4gICAgaW5zdC5pc0ludCA9IChiYWcuZm9ybWF0ID8/IFwiXCIpLmluY2x1ZGVzKFwiaW50XCIpIHx8IE51bWJlci5pc1NhZmVJbnRlZ2VyKGJhZy5tdWx0aXBsZU9mID8/IDAuNSk7XG4gICAgaW5zdC5pc0Zpbml0ZSA9IHRydWU7XG4gICAgaW5zdC5mb3JtYXQgPSBiYWcuZm9ybWF0ID8/IG51bGw7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBudW1iZXIocGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX251bWJlcihab2ROdW1iZXIsIHBhcmFtcyk7XG59XG5leHBvcnQgY29uc3QgWm9kTnVtYmVyRm9ybWF0ID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZE51bWJlckZvcm1hdFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZE51bWJlckZvcm1hdC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kTnVtYmVyLmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIGludChwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5faW50KFpvZE51bWJlckZvcm1hdCwgcGFyYW1zKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBmbG9hdDMyKHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9mbG9hdDMyKFpvZE51bWJlckZvcm1hdCwgcGFyYW1zKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBmbG9hdDY0KHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9mbG9hdDY0KFpvZE51bWJlckZvcm1hdCwgcGFyYW1zKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBpbnQzMihwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5faW50MzIoWm9kTnVtYmVyRm9ybWF0LCBwYXJhbXMpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHVpbnQzMihwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fdWludDMyKFpvZE51bWJlckZvcm1hdCwgcGFyYW1zKTtcbn1cbmV4cG9ydCBjb25zdCBab2RCb29sZWFuID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZEJvb2xlYW5cIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RCb29sZWFuLmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIGJvb2xlYW4ocGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX2Jvb2xlYW4oWm9kQm9vbGVhbiwgcGFyYW1zKTtcbn1cbmV4cG9ydCBjb25zdCBab2RCaWdJbnQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kQmlnSW50XCIsIChpbnN0LCBkZWYpPT57XG4gICAgY29yZS4kWm9kQmlnSW50LmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0Lmd0ZSA9ICh2YWx1ZSwgcGFyYW1zKT0+aW5zdC5jaGVjayhjaGVja3MuZ3RlKHZhbHVlLCBwYXJhbXMpKTtcbiAgICBpbnN0Lm1pbiA9ICh2YWx1ZSwgcGFyYW1zKT0+aW5zdC5jaGVjayhjaGVja3MuZ3RlKHZhbHVlLCBwYXJhbXMpKTtcbiAgICBpbnN0Lmd0ID0gKHZhbHVlLCBwYXJhbXMpPT5pbnN0LmNoZWNrKGNoZWNrcy5ndCh2YWx1ZSwgcGFyYW1zKSk7XG4gICAgaW5zdC5ndGUgPSAodmFsdWUsIHBhcmFtcyk9Pmluc3QuY2hlY2soY2hlY2tzLmd0ZSh2YWx1ZSwgcGFyYW1zKSk7XG4gICAgaW5zdC5taW4gPSAodmFsdWUsIHBhcmFtcyk9Pmluc3QuY2hlY2soY2hlY2tzLmd0ZSh2YWx1ZSwgcGFyYW1zKSk7XG4gICAgaW5zdC5sdCA9ICh2YWx1ZSwgcGFyYW1zKT0+aW5zdC5jaGVjayhjaGVja3MubHQodmFsdWUsIHBhcmFtcykpO1xuICAgIGluc3QubHRlID0gKHZhbHVlLCBwYXJhbXMpPT5pbnN0LmNoZWNrKGNoZWNrcy5sdGUodmFsdWUsIHBhcmFtcykpO1xuICAgIGluc3QubWF4ID0gKHZhbHVlLCBwYXJhbXMpPT5pbnN0LmNoZWNrKGNoZWNrcy5sdGUodmFsdWUsIHBhcmFtcykpO1xuICAgIGluc3QucG9zaXRpdmUgPSAocGFyYW1zKT0+aW5zdC5jaGVjayhjaGVja3MuZ3QoQmlnSW50KDApLCBwYXJhbXMpKTtcbiAgICBpbnN0Lm5lZ2F0aXZlID0gKHBhcmFtcyk9Pmluc3QuY2hlY2soY2hlY2tzLmx0KEJpZ0ludCgwKSwgcGFyYW1zKSk7XG4gICAgaW5zdC5ub25wb3NpdGl2ZSA9IChwYXJhbXMpPT5pbnN0LmNoZWNrKGNoZWNrcy5sdGUoQmlnSW50KDApLCBwYXJhbXMpKTtcbiAgICBpbnN0Lm5vbm5lZ2F0aXZlID0gKHBhcmFtcyk9Pmluc3QuY2hlY2soY2hlY2tzLmd0ZShCaWdJbnQoMCksIHBhcmFtcykpO1xuICAgIGluc3QubXVsdGlwbGVPZiA9ICh2YWx1ZSwgcGFyYW1zKT0+aW5zdC5jaGVjayhjaGVja3MubXVsdGlwbGVPZih2YWx1ZSwgcGFyYW1zKSk7XG4gICAgY29uc3QgYmFnID0gaW5zdC5fem9kLmJhZztcbiAgICBpbnN0Lm1pblZhbHVlID0gYmFnLm1pbmltdW0gPz8gbnVsbDtcbiAgICBpbnN0Lm1heFZhbHVlID0gYmFnLm1heGltdW0gPz8gbnVsbDtcbiAgICBpbnN0LmZvcm1hdCA9IGJhZy5mb3JtYXQgPz8gbnVsbDtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIGJpZ2ludChwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fYmlnaW50KFpvZEJpZ0ludCwgcGFyYW1zKTtcbn1cbmV4cG9ydCBjb25zdCBab2RCaWdJbnRGb3JtYXQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kQmlnSW50Rm9ybWF0XCIsIChpbnN0LCBkZWYpPT57XG4gICAgY29yZS4kWm9kQmlnSW50Rm9ybWF0LmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RCaWdJbnQuaW5pdChpbnN0LCBkZWYpO1xufSk7XG4vLyBpbnQ2NFxuZXhwb3J0IGZ1bmN0aW9uIGludDY0KHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9pbnQ2NChab2RCaWdJbnRGb3JtYXQsIHBhcmFtcyk7XG59XG4vLyB1aW50NjRcbmV4cG9ydCBmdW5jdGlvbiB1aW50NjQocGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX3VpbnQ2NChab2RCaWdJbnRGb3JtYXQsIHBhcmFtcyk7XG59XG5leHBvcnQgY29uc3QgWm9kU3ltYm9sID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZFN5bWJvbFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZFN5bWJvbC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBzeW1ib2wocGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX3N5bWJvbChab2RTeW1ib2wsIHBhcmFtcyk7XG59XG5leHBvcnQgY29uc3QgWm9kVW5kZWZpbmVkID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZFVuZGVmaW5lZFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZFVuZGVmaW5lZC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG59KTtcbmZ1bmN0aW9uIF91bmRlZmluZWQocGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX3VuZGVmaW5lZChab2RVbmRlZmluZWQsIHBhcmFtcyk7XG59XG5leHBvcnQgeyBfdW5kZWZpbmVkIGFzIHVuZGVmaW5lZCB9O1xuZXhwb3J0IGNvbnN0IFpvZE51bGwgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kTnVsbFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZE51bGwuaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5mdW5jdGlvbiBfbnVsbChwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fbnVsbChab2ROdWxsLCBwYXJhbXMpO1xufVxuZXhwb3J0IHsgX251bGwgYXMgbnVsbCB9O1xuZXhwb3J0IGNvbnN0IFpvZEFueSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2RBbnlcIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RBbnkuaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gYW55KCkge1xuICAgIHJldHVybiBjb3JlLl9hbnkoWm9kQW55KTtcbn1cbmV4cG9ydCBjb25zdCBab2RVbmtub3duID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZFVua25vd25cIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RVbmtub3duLmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIHVua25vd24oKSB7XG4gICAgcmV0dXJuIGNvcmUuX3Vua25vd24oWm9kVW5rbm93bik7XG59XG5leHBvcnQgY29uc3QgWm9kTmV2ZXIgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kTmV2ZXJcIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2ROZXZlci5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBuZXZlcihwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fbmV2ZXIoWm9kTmV2ZXIsIHBhcmFtcyk7XG59XG5leHBvcnQgY29uc3QgWm9kVm9pZCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2RWb2lkXCIsIChpbnN0LCBkZWYpPT57XG4gICAgY29yZS4kWm9kVm9pZC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG59KTtcbmZ1bmN0aW9uIF92b2lkKHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl92b2lkKFpvZFZvaWQsIHBhcmFtcyk7XG59XG5leHBvcnQgeyBfdm9pZCBhcyB2b2lkIH07XG5leHBvcnQgY29uc3QgWm9kRGF0ZSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2REYXRlXCIsIChpbnN0LCBkZWYpPT57XG4gICAgY29yZS4kWm9kRGF0ZS5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5taW4gPSAodmFsdWUsIHBhcmFtcyk9Pmluc3QuY2hlY2soY2hlY2tzLmd0ZSh2YWx1ZSwgcGFyYW1zKSk7XG4gICAgaW5zdC5tYXggPSAodmFsdWUsIHBhcmFtcyk9Pmluc3QuY2hlY2soY2hlY2tzLmx0ZSh2YWx1ZSwgcGFyYW1zKSk7XG4gICAgY29uc3QgYyA9IGluc3QuX3pvZC5iYWc7XG4gICAgaW5zdC5taW5EYXRlID0gYy5taW5pbXVtID8gbmV3IERhdGUoYy5taW5pbXVtKSA6IG51bGw7XG4gICAgaW5zdC5tYXhEYXRlID0gYy5tYXhpbXVtID8gbmV3IERhdGUoYy5tYXhpbXVtKSA6IG51bGw7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBkYXRlKHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9kYXRlKFpvZERhdGUsIHBhcmFtcyk7XG59XG5leHBvcnQgY29uc3QgWm9kQXJyYXkgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kQXJyYXlcIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RBcnJheS5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5lbGVtZW50ID0gZGVmLmVsZW1lbnQ7XG4gICAgaW5zdC5taW4gPSAobWluTGVuZ3RoLCBwYXJhbXMpPT5pbnN0LmNoZWNrKGNoZWNrcy5taW5MZW5ndGgobWluTGVuZ3RoLCBwYXJhbXMpKTtcbiAgICBpbnN0Lm5vbmVtcHR5ID0gKHBhcmFtcyk9Pmluc3QuY2hlY2soY2hlY2tzLm1pbkxlbmd0aCgxLCBwYXJhbXMpKTtcbiAgICBpbnN0Lm1heCA9IChtYXhMZW5ndGgsIHBhcmFtcyk9Pmluc3QuY2hlY2soY2hlY2tzLm1heExlbmd0aChtYXhMZW5ndGgsIHBhcmFtcykpO1xuICAgIGluc3QubGVuZ3RoID0gKGxlbiwgcGFyYW1zKT0+aW5zdC5jaGVjayhjaGVja3MubGVuZ3RoKGxlbiwgcGFyYW1zKSk7XG4gICAgaW5zdC51bndyYXAgPSAoKT0+aW5zdC5lbGVtZW50O1xufSk7XG5leHBvcnQgZnVuY3Rpb24gYXJyYXkoZWxlbWVudCwgcGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX2FycmF5KFpvZEFycmF5LCBlbGVtZW50LCBwYXJhbXMpO1xufVxuLy8gLmtleW9mXG5leHBvcnQgZnVuY3Rpb24ga2V5b2Yoc2NoZW1hKSB7XG4gICAgY29uc3Qgc2hhcGUgPSBzY2hlbWEuX3pvZC5kZWYuc2hhcGU7XG4gICAgcmV0dXJuIF9lbnVtKE9iamVjdC5rZXlzKHNoYXBlKSk7XG59XG5leHBvcnQgY29uc3QgWm9kT2JqZWN0ID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZE9iamVjdFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZE9iamVjdEpJVC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgdXRpbC5kZWZpbmVMYXp5KGluc3QsIFwic2hhcGVcIiwgKCk9PntcbiAgICAgICAgcmV0dXJuIGRlZi5zaGFwZTtcbiAgICB9KTtcbiAgICBpbnN0LmtleW9mID0gKCk9Pl9lbnVtKE9iamVjdC5rZXlzKGluc3QuX3pvZC5kZWYuc2hhcGUpKTtcbiAgICBpbnN0LmNhdGNoYWxsID0gKGNhdGNoYWxsKT0+aW5zdC5jbG9uZSh7XG4gICAgICAgICAgICAuLi5pbnN0Ll96b2QuZGVmLFxuICAgICAgICAgICAgY2F0Y2hhbGw6IGNhdGNoYWxsXG4gICAgICAgIH0pO1xuICAgIGluc3QucGFzc3Rocm91Z2ggPSAoKT0+aW5zdC5jbG9uZSh7XG4gICAgICAgICAgICAuLi5pbnN0Ll96b2QuZGVmLFxuICAgICAgICAgICAgY2F0Y2hhbGw6IHVua25vd24oKVxuICAgICAgICB9KTtcbiAgICBpbnN0Lmxvb3NlID0gKCk9Pmluc3QuY2xvbmUoe1xuICAgICAgICAgICAgLi4uaW5zdC5fem9kLmRlZixcbiAgICAgICAgICAgIGNhdGNoYWxsOiB1bmtub3duKClcbiAgICAgICAgfSk7XG4gICAgaW5zdC5zdHJpY3QgPSAoKT0+aW5zdC5jbG9uZSh7XG4gICAgICAgICAgICAuLi5pbnN0Ll96b2QuZGVmLFxuICAgICAgICAgICAgY2F0Y2hhbGw6IG5ldmVyKClcbiAgICAgICAgfSk7XG4gICAgaW5zdC5zdHJpcCA9ICgpPT5pbnN0LmNsb25lKHtcbiAgICAgICAgICAgIC4uLmluc3QuX3pvZC5kZWYsXG4gICAgICAgICAgICBjYXRjaGFsbDogdW5kZWZpbmVkXG4gICAgICAgIH0pO1xuICAgIGluc3QuZXh0ZW5kID0gKGluY29taW5nKT0+e1xuICAgICAgICByZXR1cm4gdXRpbC5leHRlbmQoaW5zdCwgaW5jb21pbmcpO1xuICAgIH07XG4gICAgaW5zdC5zYWZlRXh0ZW5kID0gKGluY29taW5nKT0+e1xuICAgICAgICByZXR1cm4gdXRpbC5zYWZlRXh0ZW5kKGluc3QsIGluY29taW5nKTtcbiAgICB9O1xuICAgIGluc3QubWVyZ2UgPSAob3RoZXIpPT51dGlsLm1lcmdlKGluc3QsIG90aGVyKTtcbiAgICBpbnN0LnBpY2sgPSAobWFzayk9PnV0aWwucGljayhpbnN0LCBtYXNrKTtcbiAgICBpbnN0Lm9taXQgPSAobWFzayk9PnV0aWwub21pdChpbnN0LCBtYXNrKTtcbiAgICBpbnN0LnBhcnRpYWwgPSAoLi4uYXJncyk9PnV0aWwucGFydGlhbChab2RPcHRpb25hbCwgaW5zdCwgYXJnc1swXSk7XG4gICAgaW5zdC5yZXF1aXJlZCA9ICguLi5hcmdzKT0+dXRpbC5yZXF1aXJlZChab2ROb25PcHRpb25hbCwgaW5zdCwgYXJnc1swXSk7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBvYmplY3Qoc2hhcGUsIHBhcmFtcykge1xuICAgIGNvbnN0IGRlZiA9IHtcbiAgICAgICAgdHlwZTogXCJvYmplY3RcIixcbiAgICAgICAgc2hhcGU6IHNoYXBlID8/IHt9LFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfTtcbiAgICByZXR1cm4gbmV3IFpvZE9iamVjdChkZWYpO1xufVxuLy8gc3RyaWN0T2JqZWN0XG5leHBvcnQgZnVuY3Rpb24gc3RyaWN0T2JqZWN0KHNoYXBlLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IFpvZE9iamVjdCh7XG4gICAgICAgIHR5cGU6IFwib2JqZWN0XCIsXG4gICAgICAgIHNoYXBlLFxuICAgICAgICBjYXRjaGFsbDogbmV2ZXIoKSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuLy8gbG9vc2VPYmplY3RcbmV4cG9ydCBmdW5jdGlvbiBsb29zZU9iamVjdChzaGFwZSwgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBab2RPYmplY3Qoe1xuICAgICAgICB0eXBlOiBcIm9iamVjdFwiLFxuICAgICAgICBzaGFwZSxcbiAgICAgICAgY2F0Y2hhbGw6IHVua25vd24oKSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGNvbnN0IFpvZFVuaW9uID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZFVuaW9uXCIsIChpbnN0LCBkZWYpPT57XG4gICAgY29yZS4kWm9kVW5pb24uaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3Qub3B0aW9ucyA9IGRlZi5vcHRpb25zO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gdW5pb24ob3B0aW9ucywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBab2RVbmlvbih7XG4gICAgICAgIHR5cGU6IFwidW5pb25cIixcbiAgICAgICAgb3B0aW9uczogb3B0aW9ucyxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGNvbnN0IFpvZERpc2NyaW1pbmF0ZWRVbmlvbiA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2REaXNjcmltaW5hdGVkVW5pb25cIiwgKGluc3QsIGRlZik9PntcbiAgICBab2RVbmlvbi5pbml0KGluc3QsIGRlZik7XG4gICAgY29yZS4kWm9kRGlzY3JpbWluYXRlZFVuaW9uLmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIGRpc2NyaW1pbmF0ZWRVbmlvbihkaXNjcmltaW5hdG9yLCBvcHRpb25zLCBwYXJhbXMpIHtcbiAgICAvLyBjb25zdCBbb3B0aW9ucywgcGFyYW1zXSA9IGFyZ3M7XG4gICAgcmV0dXJuIG5ldyBab2REaXNjcmltaW5hdGVkVW5pb24oe1xuICAgICAgICB0eXBlOiBcInVuaW9uXCIsXG4gICAgICAgIG9wdGlvbnMsXG4gICAgICAgIGRpc2NyaW1pbmF0b3IsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBjb25zdCBab2RJbnRlcnNlY3Rpb24gPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kSW50ZXJzZWN0aW9uXCIsIChpbnN0LCBkZWYpPT57XG4gICAgY29yZS4kWm9kSW50ZXJzZWN0aW9uLmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIGludGVyc2VjdGlvbihsZWZ0LCByaWdodCkge1xuICAgIHJldHVybiBuZXcgWm9kSW50ZXJzZWN0aW9uKHtcbiAgICAgICAgdHlwZTogXCJpbnRlcnNlY3Rpb25cIixcbiAgICAgICAgbGVmdDogbGVmdCxcbiAgICAgICAgcmlnaHQ6IHJpZ2h0XG4gICAgfSk7XG59XG5leHBvcnQgY29uc3QgWm9kVHVwbGUgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kVHVwbGVcIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RUdXBsZS5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5yZXN0ID0gKHJlc3QpPT5pbnN0LmNsb25lKHtcbiAgICAgICAgICAgIC4uLmluc3QuX3pvZC5kZWYsXG4gICAgICAgICAgICByZXN0OiByZXN0XG4gICAgICAgIH0pO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gdHVwbGUoaXRlbXMsIF9wYXJhbXNPclJlc3QsIF9wYXJhbXMpIHtcbiAgICBjb25zdCBoYXNSZXN0ID0gX3BhcmFtc09yUmVzdCBpbnN0YW5jZW9mIGNvcmUuJFpvZFR5cGU7XG4gICAgY29uc3QgcGFyYW1zID0gaGFzUmVzdCA/IF9wYXJhbXMgOiBfcGFyYW1zT3JSZXN0O1xuICAgIGNvbnN0IHJlc3QgPSBoYXNSZXN0ID8gX3BhcmFtc09yUmVzdCA6IG51bGw7XG4gICAgcmV0dXJuIG5ldyBab2RUdXBsZSh7XG4gICAgICAgIHR5cGU6IFwidHVwbGVcIixcbiAgICAgICAgaXRlbXM6IGl0ZW1zLFxuICAgICAgICByZXN0LFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgY29uc3QgWm9kUmVjb3JkID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZFJlY29yZFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZFJlY29yZC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5rZXlUeXBlID0gZGVmLmtleVR5cGU7XG4gICAgaW5zdC52YWx1ZVR5cGUgPSBkZWYudmFsdWVUeXBlO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gcmVjb3JkKGtleVR5cGUsIHZhbHVlVHlwZSwgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBab2RSZWNvcmQoe1xuICAgICAgICB0eXBlOiBcInJlY29yZFwiLFxuICAgICAgICBrZXlUeXBlLFxuICAgICAgICB2YWx1ZVR5cGU6IHZhbHVlVHlwZSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuLy8gdHlwZSBhbGtzamYgPSBjb3JlLm91dHB1dDxjb3JlLiRab2RSZWNvcmRLZXk+O1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnRpYWxSZWNvcmQoa2V5VHlwZSwgdmFsdWVUeXBlLCBwYXJhbXMpIHtcbiAgICBjb25zdCBrID0gY29yZS5jbG9uZShrZXlUeXBlKTtcbiAgICBrLl96b2QudmFsdWVzID0gdW5kZWZpbmVkO1xuICAgIHJldHVybiBuZXcgWm9kUmVjb3JkKHtcbiAgICAgICAgdHlwZTogXCJyZWNvcmRcIixcbiAgICAgICAga2V5VHlwZTogayxcbiAgICAgICAgdmFsdWVUeXBlOiB2YWx1ZVR5cGUsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBjb25zdCBab2RNYXAgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kTWFwXCIsIChpbnN0LCBkZWYpPT57XG4gICAgY29yZS4kWm9kTWFwLmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0LmtleVR5cGUgPSBkZWYua2V5VHlwZTtcbiAgICBpbnN0LnZhbHVlVHlwZSA9IGRlZi52YWx1ZVR5cGU7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBtYXAoa2V5VHlwZSwgdmFsdWVUeXBlLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IFpvZE1hcCh7XG4gICAgICAgIHR5cGU6IFwibWFwXCIsXG4gICAgICAgIGtleVR5cGU6IGtleVR5cGUsXG4gICAgICAgIHZhbHVlVHlwZTogdmFsdWVUeXBlLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgY29uc3QgWm9kU2V0ID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZFNldFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZFNldC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC5taW4gPSAoLi4uYXJncyk9Pmluc3QuY2hlY2soY29yZS5fbWluU2l6ZSguLi5hcmdzKSk7XG4gICAgaW5zdC5ub25lbXB0eSA9IChwYXJhbXMpPT5pbnN0LmNoZWNrKGNvcmUuX21pblNpemUoMSwgcGFyYW1zKSk7XG4gICAgaW5zdC5tYXggPSAoLi4uYXJncyk9Pmluc3QuY2hlY2soY29yZS5fbWF4U2l6ZSguLi5hcmdzKSk7XG4gICAgaW5zdC5zaXplID0gKC4uLmFyZ3MpPT5pbnN0LmNoZWNrKGNvcmUuX3NpemUoLi4uYXJncykpO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gc2V0KHZhbHVlVHlwZSwgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBab2RTZXQoe1xuICAgICAgICB0eXBlOiBcInNldFwiLFxuICAgICAgICB2YWx1ZVR5cGU6IHZhbHVlVHlwZSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGNvbnN0IFpvZEVudW0gPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kRW51bVwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZEVudW0uaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuZW51bSA9IGRlZi5lbnRyaWVzO1xuICAgIGluc3Qub3B0aW9ucyA9IE9iamVjdC52YWx1ZXMoZGVmLmVudHJpZXMpO1xuICAgIGNvbnN0IGtleXMgPSBuZXcgU2V0KE9iamVjdC5rZXlzKGRlZi5lbnRyaWVzKSk7XG4gICAgaW5zdC5leHRyYWN0ID0gKHZhbHVlcywgcGFyYW1zKT0+e1xuICAgICAgICBjb25zdCBuZXdFbnRyaWVzID0ge307XG4gICAgICAgIGZvciAoY29uc3QgdmFsdWUgb2YgdmFsdWVzKXtcbiAgICAgICAgICAgIGlmIChrZXlzLmhhcyh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICBuZXdFbnRyaWVzW3ZhbHVlXSA9IGRlZi5lbnRyaWVzW3ZhbHVlXTtcbiAgICAgICAgICAgIH0gZWxzZSB0aHJvdyBuZXcgRXJyb3IoYEtleSAke3ZhbHVlfSBub3QgZm91bmQgaW4gZW51bWApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgWm9kRW51bSh7XG4gICAgICAgICAgICAuLi5kZWYsXG4gICAgICAgICAgICBjaGVja3M6IFtdLFxuICAgICAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKSxcbiAgICAgICAgICAgIGVudHJpZXM6IG5ld0VudHJpZXNcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBpbnN0LmV4Y2x1ZGUgPSAodmFsdWVzLCBwYXJhbXMpPT57XG4gICAgICAgIGNvbnN0IG5ld0VudHJpZXMgPSB7XG4gICAgICAgICAgICAuLi5kZWYuZW50cmllc1xuICAgICAgICB9O1xuICAgICAgICBmb3IgKGNvbnN0IHZhbHVlIG9mIHZhbHVlcyl7XG4gICAgICAgICAgICBpZiAoa2V5cy5oYXModmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIG5ld0VudHJpZXNbdmFsdWVdO1xuICAgICAgICAgICAgfSBlbHNlIHRocm93IG5ldyBFcnJvcihgS2V5ICR7dmFsdWV9IG5vdCBmb3VuZCBpbiBlbnVtYCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBab2RFbnVtKHtcbiAgICAgICAgICAgIC4uLmRlZixcbiAgICAgICAgICAgIGNoZWNrczogW10sXG4gICAgICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpLFxuICAgICAgICAgICAgZW50cmllczogbmV3RW50cmllc1xuICAgICAgICB9KTtcbiAgICB9O1xufSk7XG5mdW5jdGlvbiBfZW51bSh2YWx1ZXMsIHBhcmFtcykge1xuICAgIGNvbnN0IGVudHJpZXMgPSBBcnJheS5pc0FycmF5KHZhbHVlcykgPyBPYmplY3QuZnJvbUVudHJpZXModmFsdWVzLm1hcCgodik9PltcbiAgICAgICAgICAgIHYsXG4gICAgICAgICAgICB2XG4gICAgICAgIF0pKSA6IHZhbHVlcztcbiAgICByZXR1cm4gbmV3IFpvZEVudW0oe1xuICAgICAgICB0eXBlOiBcImVudW1cIixcbiAgICAgICAgZW50cmllcyxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IHsgX2VudW0gYXMgZW51bSB9O1xuLyoqIEBkZXByZWNhdGVkIFRoaXMgQVBJIGhhcyBiZWVuIG1lcmdlZCBpbnRvIGB6LmVudW0oKWAuIFVzZSBgei5lbnVtKClgIGluc3RlYWQuXG4gKlxuICogYGBgdHNcbiAqIGVudW0gQ29sb3JzIHsgcmVkLCBncmVlbiwgYmx1ZSB9XG4gKiB6LmVudW0oQ29sb3JzKTtcbiAqIGBgYFxuICovIGV4cG9ydCBmdW5jdGlvbiBuYXRpdmVFbnVtKGVudHJpZXMsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgWm9kRW51bSh7XG4gICAgICAgIHR5cGU6IFwiZW51bVwiLFxuICAgICAgICBlbnRyaWVzLFxuICAgICAgICAuLi51dGlsLm5vcm1hbGl6ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgY29uc3QgWm9kTGl0ZXJhbCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2RMaXRlcmFsXCIsIChpbnN0LCBkZWYpPT57XG4gICAgY29yZS4kWm9kTGl0ZXJhbC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC52YWx1ZXMgPSBuZXcgU2V0KGRlZi52YWx1ZXMpO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShpbnN0LCBcInZhbHVlXCIsIHtcbiAgICAgICAgZ2V0ICgpIHtcbiAgICAgICAgICAgIGlmIChkZWYudmFsdWVzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIHNjaGVtYSBjb250YWlucyBtdWx0aXBsZSB2YWxpZCBsaXRlcmFsIHZhbHVlcy4gVXNlIGAudmFsdWVzYCBpbnN0ZWFkLlwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBkZWYudmFsdWVzWzBdO1xuICAgICAgICB9XG4gICAgfSk7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBsaXRlcmFsKHZhbHVlLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IFpvZExpdGVyYWwoe1xuICAgICAgICB0eXBlOiBcImxpdGVyYWxcIixcbiAgICAgICAgdmFsdWVzOiBBcnJheS5pc0FycmF5KHZhbHVlKSA/IHZhbHVlIDogW1xuICAgICAgICAgICAgdmFsdWVcbiAgICAgICAgXSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufVxuZXhwb3J0IGNvbnN0IFpvZEZpbGUgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kRmlsZVwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZEZpbGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QubWluID0gKHNpemUsIHBhcmFtcyk9Pmluc3QuY2hlY2soY29yZS5fbWluU2l6ZShzaXplLCBwYXJhbXMpKTtcbiAgICBpbnN0Lm1heCA9IChzaXplLCBwYXJhbXMpPT5pbnN0LmNoZWNrKGNvcmUuX21heFNpemUoc2l6ZSwgcGFyYW1zKSk7XG4gICAgaW5zdC5taW1lID0gKHR5cGVzLCBwYXJhbXMpPT5pbnN0LmNoZWNrKGNvcmUuX21pbWUoQXJyYXkuaXNBcnJheSh0eXBlcykgPyB0eXBlcyA6IFtcbiAgICAgICAgICAgIHR5cGVzXG4gICAgICAgIF0sIHBhcmFtcykpO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gZmlsZShwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fZmlsZShab2RGaWxlLCBwYXJhbXMpO1xufVxuZXhwb3J0IGNvbnN0IFpvZFRyYW5zZm9ybSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2RUcmFuc2Zvcm1cIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RUcmFuc2Zvcm0uaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuX3pvZC5wYXJzZSA9IChwYXlsb2FkLCBfY3R4KT0+e1xuICAgICAgICBpZiAoX2N0eC5kaXJlY3Rpb24gPT09IFwiYmFja3dhcmRcIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IGNvcmUuJFpvZEVuY29kZUVycm9yKGluc3QuY29uc3RydWN0b3IubmFtZSk7XG4gICAgICAgIH1cbiAgICAgICAgcGF5bG9hZC5hZGRJc3N1ZSA9IChpc3N1ZSk9PntcbiAgICAgICAgICAgIGlmICh0eXBlb2YgaXNzdWUgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHV0aWwuaXNzdWUoaXNzdWUsIHBheWxvYWQudmFsdWUsIGRlZikpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBmb3IgWm9kIDMgYmFja3dhcmRzIGNvbXBhdGliaWxpdHlcbiAgICAgICAgICAgICAgICBjb25zdCBfaXNzdWUgPSBpc3N1ZTtcbiAgICAgICAgICAgICAgICBpZiAoX2lzc3VlLmZhdGFsKSBfaXNzdWUuY29udGludWUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBfaXNzdWUuY29kZSA/PyAoX2lzc3VlLmNvZGUgPSBcImN1c3RvbVwiKTtcbiAgICAgICAgICAgICAgICBfaXNzdWUuaW5wdXQgPz8gKF9pc3N1ZS5pbnB1dCA9IHBheWxvYWQudmFsdWUpO1xuICAgICAgICAgICAgICAgIF9pc3N1ZS5pbnN0ID8/IChfaXNzdWUuaW5zdCA9IGluc3QpO1xuICAgICAgICAgICAgICAgIC8vIF9pc3N1ZS5jb250aW51ZSA/Pz0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBwYXlsb2FkLmlzc3Vlcy5wdXNoKHV0aWwuaXNzdWUoX2lzc3VlKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IG91dHB1dCA9IGRlZi50cmFuc2Zvcm0ocGF5bG9hZC52YWx1ZSwgcGF5bG9hZCk7XG4gICAgICAgIGlmIChvdXRwdXQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm4gb3V0cHV0LnRoZW4oKG91dHB1dCk9PntcbiAgICAgICAgICAgICAgICBwYXlsb2FkLnZhbHVlID0gb3V0cHV0O1xuICAgICAgICAgICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcGF5bG9hZC52YWx1ZSA9IG91dHB1dDtcbiAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgfTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zZm9ybShmbikge1xuICAgIHJldHVybiBuZXcgWm9kVHJhbnNmb3JtKHtcbiAgICAgICAgdHlwZTogXCJ0cmFuc2Zvcm1cIixcbiAgICAgICAgdHJhbnNmb3JtOiBmblxuICAgIH0pO1xufVxuZXhwb3J0IGNvbnN0IFpvZE9wdGlvbmFsID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZE9wdGlvbmFsXCIsIChpbnN0LCBkZWYpPT57XG4gICAgY29yZS4kWm9kT3B0aW9uYWwuaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QudW53cmFwID0gKCk9Pmluc3QuX3pvZC5kZWYuaW5uZXJUeXBlO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gb3B0aW9uYWwoaW5uZXJUeXBlKSB7XG4gICAgcmV0dXJuIG5ldyBab2RPcHRpb25hbCh7XG4gICAgICAgIHR5cGU6IFwib3B0aW9uYWxcIixcbiAgICAgICAgaW5uZXJUeXBlOiBpbm5lclR5cGVcbiAgICB9KTtcbn1cbmV4cG9ydCBjb25zdCBab2ROdWxsYWJsZSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2ROdWxsYWJsZVwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZE51bGxhYmxlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0LnVud3JhcCA9ICgpPT5pbnN0Ll96b2QuZGVmLmlubmVyVHlwZTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIG51bGxhYmxlKGlubmVyVHlwZSkge1xuICAgIHJldHVybiBuZXcgWm9kTnVsbGFibGUoe1xuICAgICAgICB0eXBlOiBcIm51bGxhYmxlXCIsXG4gICAgICAgIGlubmVyVHlwZTogaW5uZXJUeXBlXG4gICAgfSk7XG59XG4vLyBudWxsaXNoXG5leHBvcnQgZnVuY3Rpb24gbnVsbGlzaChpbm5lclR5cGUpIHtcbiAgICByZXR1cm4gb3B0aW9uYWwobnVsbGFibGUoaW5uZXJUeXBlKSk7XG59XG5leHBvcnQgY29uc3QgWm9kRGVmYXVsdCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2REZWZhdWx0XCIsIChpbnN0LCBkZWYpPT57XG4gICAgY29yZS4kWm9kRGVmYXVsdC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC51bndyYXAgPSAoKT0+aW5zdC5fem9kLmRlZi5pbm5lclR5cGU7XG4gICAgaW5zdC5yZW1vdmVEZWZhdWx0ID0gaW5zdC51bndyYXA7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBfZGVmYXVsdChpbm5lclR5cGUsIGRlZmF1bHRWYWx1ZSkge1xuICAgIHJldHVybiBuZXcgWm9kRGVmYXVsdCh7XG4gICAgICAgIHR5cGU6IFwiZGVmYXVsdFwiLFxuICAgICAgICBpbm5lclR5cGU6IGlubmVyVHlwZSxcbiAgICAgICAgZ2V0IGRlZmF1bHRWYWx1ZSAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdHlwZW9mIGRlZmF1bHRWYWx1ZSA9PT0gXCJmdW5jdGlvblwiID8gZGVmYXVsdFZhbHVlKCkgOiB1dGlsLnNoYWxsb3dDbG9uZShkZWZhdWx0VmFsdWUpO1xuICAgICAgICB9XG4gICAgfSk7XG59XG5leHBvcnQgY29uc3QgWm9kUHJlZmF1bHQgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kUHJlZmF1bHRcIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RQcmVmYXVsdC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC51bndyYXAgPSAoKT0+aW5zdC5fem9kLmRlZi5pbm5lclR5cGU7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBwcmVmYXVsdChpbm5lclR5cGUsIGRlZmF1bHRWYWx1ZSkge1xuICAgIHJldHVybiBuZXcgWm9kUHJlZmF1bHQoe1xuICAgICAgICB0eXBlOiBcInByZWZhdWx0XCIsXG4gICAgICAgIGlubmVyVHlwZTogaW5uZXJUeXBlLFxuICAgICAgICBnZXQgZGVmYXVsdFZhbHVlICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0eXBlb2YgZGVmYXVsdFZhbHVlID09PSBcImZ1bmN0aW9uXCIgPyBkZWZhdWx0VmFsdWUoKSA6IHV0aWwuc2hhbGxvd0Nsb25lKGRlZmF1bHRWYWx1ZSk7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cbmV4cG9ydCBjb25zdCBab2ROb25PcHRpb25hbCA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2ROb25PcHRpb25hbFwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZE5vbk9wdGlvbmFsLmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0LnVud3JhcCA9ICgpPT5pbnN0Ll96b2QuZGVmLmlubmVyVHlwZTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIG5vbm9wdGlvbmFsKGlubmVyVHlwZSwgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBab2ROb25PcHRpb25hbCh7XG4gICAgICAgIHR5cGU6IFwibm9ub3B0aW9uYWxcIixcbiAgICAgICAgaW5uZXJUeXBlOiBpbm5lclR5cGUsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBjb25zdCBab2RTdWNjZXNzID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZFN1Y2Nlc3NcIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RTdWNjZXNzLmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0LnVud3JhcCA9ICgpPT5pbnN0Ll96b2QuZGVmLmlubmVyVHlwZTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIHN1Y2Nlc3MoaW5uZXJUeXBlKSB7XG4gICAgcmV0dXJuIG5ldyBab2RTdWNjZXNzKHtcbiAgICAgICAgdHlwZTogXCJzdWNjZXNzXCIsXG4gICAgICAgIGlubmVyVHlwZTogaW5uZXJUeXBlXG4gICAgfSk7XG59XG5leHBvcnQgY29uc3QgWm9kQ2F0Y2ggPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kQ2F0Y2hcIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RDYXRjaC5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgaW5zdC51bndyYXAgPSAoKT0+aW5zdC5fem9kLmRlZi5pbm5lclR5cGU7XG4gICAgaW5zdC5yZW1vdmVDYXRjaCA9IGluc3QudW53cmFwO1xufSk7XG5mdW5jdGlvbiBfY2F0Y2goaW5uZXJUeXBlLCBjYXRjaFZhbHVlKSB7XG4gICAgcmV0dXJuIG5ldyBab2RDYXRjaCh7XG4gICAgICAgIHR5cGU6IFwiY2F0Y2hcIixcbiAgICAgICAgaW5uZXJUeXBlOiBpbm5lclR5cGUsXG4gICAgICAgIGNhdGNoVmFsdWU6IHR5cGVvZiBjYXRjaFZhbHVlID09PSBcImZ1bmN0aW9uXCIgPyBjYXRjaFZhbHVlIDogKCk9PmNhdGNoVmFsdWVcbiAgICB9KTtcbn1cbmV4cG9ydCB7IF9jYXRjaCBhcyBjYXRjaCB9O1xuZXhwb3J0IGNvbnN0IFpvZE5hTiA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2ROYU5cIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2ROYU4uaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gbmFuKHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9uYW4oWm9kTmFOLCBwYXJhbXMpO1xufVxuZXhwb3J0IGNvbnN0IFpvZFBpcGUgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kUGlwZVwiLCAoaW5zdCwgZGVmKT0+e1xuICAgIGNvcmUuJFpvZFBpcGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QuaW4gPSBkZWYuaW47XG4gICAgaW5zdC5vdXQgPSBkZWYub3V0O1xufSk7XG5leHBvcnQgZnVuY3Rpb24gcGlwZShpbl8sIG91dCkge1xuICAgIHJldHVybiBuZXcgWm9kUGlwZSh7XG4gICAgICAgIHR5cGU6IFwicGlwZVwiLFxuICAgICAgICBpbjogaW5fLFxuICAgICAgICBvdXQ6IG91dFxuICAgIH0pO1xufVxuZXhwb3J0IGNvbnN0IFpvZENvZGVjID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZENvZGVjXCIsIChpbnN0LCBkZWYpPT57XG4gICAgWm9kUGlwZS5pbml0KGluc3QsIGRlZik7XG4gICAgY29yZS4kWm9kQ29kZWMuaW5pdChpbnN0LCBkZWYpO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gY29kZWMoaW5fLCBvdXQsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgWm9kQ29kZWMoe1xuICAgICAgICB0eXBlOiBcInBpcGVcIixcbiAgICAgICAgaW46IGluXyxcbiAgICAgICAgb3V0OiBvdXQsXG4gICAgICAgIHRyYW5zZm9ybTogcGFyYW1zLmRlY29kZSxcbiAgICAgICAgcmV2ZXJzZVRyYW5zZm9ybTogcGFyYW1zLmVuY29kZVxuICAgIH0pO1xufVxuZXhwb3J0IGNvbnN0IFpvZFJlYWRvbmx5ID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZFJlYWRvbmx5XCIsIChpbnN0LCBkZWYpPT57XG4gICAgY29yZS4kWm9kUmVhZG9ubHkuaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xuICAgIGluc3QudW53cmFwID0gKCk9Pmluc3QuX3pvZC5kZWYuaW5uZXJUeXBlO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gcmVhZG9ubHkoaW5uZXJUeXBlKSB7XG4gICAgcmV0dXJuIG5ldyBab2RSZWFkb25seSh7XG4gICAgICAgIHR5cGU6IFwicmVhZG9ubHlcIixcbiAgICAgICAgaW5uZXJUeXBlOiBpbm5lclR5cGVcbiAgICB9KTtcbn1cbmV4cG9ydCBjb25zdCBab2RUZW1wbGF0ZUxpdGVyYWwgPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kVGVtcGxhdGVMaXRlcmFsXCIsIChpbnN0LCBkZWYpPT57XG4gICAgY29yZS4kWm9kVGVtcGxhdGVMaXRlcmFsLmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIHRlbXBsYXRlTGl0ZXJhbChwYXJ0cywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBab2RUZW1wbGF0ZUxpdGVyYWwoe1xuICAgICAgICB0eXBlOiBcInRlbXBsYXRlX2xpdGVyYWxcIixcbiAgICAgICAgcGFydHMsXG4gICAgICAgIC4uLnV0aWwubm9ybWFsaXplUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn1cbmV4cG9ydCBjb25zdCBab2RMYXp5ID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZExhenlcIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RMYXp5LmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0LnVud3JhcCA9ICgpPT5pbnN0Ll96b2QuZGVmLmdldHRlcigpO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gbGF6eShnZXR0ZXIpIHtcbiAgICByZXR1cm4gbmV3IFpvZExhenkoe1xuICAgICAgICB0eXBlOiBcImxhenlcIixcbiAgICAgICAgZ2V0dGVyOiBnZXR0ZXJcbiAgICB9KTtcbn1cbmV4cG9ydCBjb25zdCBab2RQcm9taXNlID0gLypAX19QVVJFX18qLyBjb3JlLiRjb25zdHJ1Y3RvcihcIlpvZFByb21pc2VcIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RQcm9taXNlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBab2RUeXBlLmluaXQoaW5zdCwgZGVmKTtcbiAgICBpbnN0LnVud3JhcCA9ICgpPT5pbnN0Ll96b2QuZGVmLmlubmVyVHlwZTtcbn0pO1xuZXhwb3J0IGZ1bmN0aW9uIHByb21pc2UoaW5uZXJUeXBlKSB7XG4gICAgcmV0dXJuIG5ldyBab2RQcm9taXNlKHtcbiAgICAgICAgdHlwZTogXCJwcm9taXNlXCIsXG4gICAgICAgIGlubmVyVHlwZTogaW5uZXJUeXBlXG4gICAgfSk7XG59XG5leHBvcnQgY29uc3QgWm9kRnVuY3Rpb24gPSAvKkBfX1BVUkVfXyovIGNvcmUuJGNvbnN0cnVjdG9yKFwiWm9kRnVuY3Rpb25cIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RGdW5jdGlvbi5pbml0KGluc3QsIGRlZik7XG4gICAgWm9kVHlwZS5pbml0KGluc3QsIGRlZik7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBfZnVuY3Rpb24ocGFyYW1zKSB7XG4gICAgcmV0dXJuIG5ldyBab2RGdW5jdGlvbih7XG4gICAgICAgIHR5cGU6IFwiZnVuY3Rpb25cIixcbiAgICAgICAgaW5wdXQ6IEFycmF5LmlzQXJyYXkocGFyYW1zPy5pbnB1dCkgPyB0dXBsZShwYXJhbXM/LmlucHV0KSA6IHBhcmFtcz8uaW5wdXQgPz8gYXJyYXkodW5rbm93bigpKSxcbiAgICAgICAgb3V0cHV0OiBwYXJhbXM/Lm91dHB1dCA/PyB1bmtub3duKClcbiAgICB9KTtcbn1cbmV4cG9ydCB7IF9mdW5jdGlvbiBhcyBmdW5jdGlvbiB9O1xuZXhwb3J0IGNvbnN0IFpvZEN1c3RvbSA9IC8qQF9fUFVSRV9fKi8gY29yZS4kY29uc3RydWN0b3IoXCJab2RDdXN0b21cIiwgKGluc3QsIGRlZik9PntcbiAgICBjb3JlLiRab2RDdXN0b20uaW5pdChpbnN0LCBkZWYpO1xuICAgIFpvZFR5cGUuaW5pdChpbnN0LCBkZWYpO1xufSk7XG4vLyBjdXN0b20gY2hlY2tzXG5leHBvcnQgZnVuY3Rpb24gY2hlY2soZm4pIHtcbiAgICBjb25zdCBjaCA9IG5ldyBjb3JlLiRab2RDaGVjayh7XG4gICAgICAgIGNoZWNrOiBcImN1c3RvbVwiXG4gICAgfSk7XG4gICAgY2guX3pvZC5jaGVjayA9IGZuO1xuICAgIHJldHVybiBjaDtcbn1cbmV4cG9ydCBmdW5jdGlvbiBjdXN0b20oZm4sIF9wYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fY3VzdG9tKFpvZEN1c3RvbSwgZm4gPz8gKCgpPT50cnVlKSwgX3BhcmFtcyk7XG59XG5leHBvcnQgZnVuY3Rpb24gcmVmaW5lKGZuLCBfcGFyYW1zID0ge30pIHtcbiAgICByZXR1cm4gY29yZS5fcmVmaW5lKFpvZEN1c3RvbSwgZm4sIF9wYXJhbXMpO1xufVxuLy8gc3VwZXJSZWZpbmVcbmV4cG9ydCBmdW5jdGlvbiBzdXBlclJlZmluZShmbikge1xuICAgIHJldHVybiBjb3JlLl9zdXBlclJlZmluZShmbik7XG59XG5mdW5jdGlvbiBfaW5zdGFuY2VvZihjbHMsIHBhcmFtcyA9IHtcbiAgICBlcnJvcjogYElucHV0IG5vdCBpbnN0YW5jZSBvZiAke2Nscy5uYW1lfWBcbn0pIHtcbiAgICBjb25zdCBpbnN0ID0gbmV3IFpvZEN1c3RvbSh7XG4gICAgICAgIHR5cGU6IFwiY3VzdG9tXCIsXG4gICAgICAgIGNoZWNrOiBcImN1c3RvbVwiLFxuICAgICAgICBmbjogKGRhdGEpPT5kYXRhIGluc3RhbmNlb2YgY2xzLFxuICAgICAgICBhYm9ydDogdHJ1ZSxcbiAgICAgICAgLi4udXRpbC5ub3JtYWxpemVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xuICAgIGluc3QuX3pvZC5iYWcuQ2xhc3MgPSBjbHM7XG4gICAgcmV0dXJuIGluc3Q7XG59XG5leHBvcnQgeyBfaW5zdGFuY2VvZiBhcyBpbnN0YW5jZW9mIH07XG4vLyBzdHJpbmdib29sXG5leHBvcnQgY29uc3Qgc3RyaW5nYm9vbCA9ICguLi5hcmdzKT0+Y29yZS5fc3RyaW5nYm9vbCh7XG4gICAgICAgIENvZGVjOiBab2RDb2RlYyxcbiAgICAgICAgQm9vbGVhbjogWm9kQm9vbGVhbixcbiAgICAgICAgU3RyaW5nOiBab2RTdHJpbmdcbiAgICB9LCAuLi5hcmdzKTtcbmV4cG9ydCBmdW5jdGlvbiBqc29uKHBhcmFtcykge1xuICAgIGNvbnN0IGpzb25TY2hlbWEgPSBsYXp5KCgpPT57XG4gICAgICAgIHJldHVybiB1bmlvbihbXG4gICAgICAgICAgICBzdHJpbmcocGFyYW1zKSxcbiAgICAgICAgICAgIG51bWJlcigpLFxuICAgICAgICAgICAgYm9vbGVhbigpLFxuICAgICAgICAgICAgX251bGwoKSxcbiAgICAgICAgICAgIGFycmF5KGpzb25TY2hlbWEpLFxuICAgICAgICAgICAgcmVjb3JkKHN0cmluZygpLCBqc29uU2NoZW1hKVxuICAgICAgICBdKTtcbiAgICB9KTtcbiAgICByZXR1cm4ganNvblNjaGVtYTtcbn1cbi8vIHByZXByb2Nlc3Ncbi8vIC8qKiBAZGVwcmVjYXRlZCBVc2UgYHoucGlwZSgpYCBhbmQgYHoudHJhbnNmb3JtKClgIGluc3RlYWQuICovXG5leHBvcnQgZnVuY3Rpb24gcHJlcHJvY2Vzcyhmbiwgc2NoZW1hKSB7XG4gICAgcmV0dXJuIHBpcGUodHJhbnNmb3JtKGZuKSwgc2NoZW1hKTtcbn1cbiIsICIvLyBab2QgMyBjb21wYXQgbGF5ZXJcbmltcG9ydCAqIGFzIGNvcmUgZnJvbSBcIi4uL2NvcmUvaW5kZXguanNcIjtcbi8qKiBAZGVwcmVjYXRlZCBVc2UgdGhlIHJhdyBzdHJpbmcgbGl0ZXJhbCBjb2RlcyBpbnN0ZWFkLCBlLmcuIFwiaW52YWxpZF90eXBlXCIuICovIGV4cG9ydCBjb25zdCBab2RJc3N1ZUNvZGUgPSB7XG4gICAgaW52YWxpZF90eXBlOiBcImludmFsaWRfdHlwZVwiLFxuICAgIHRvb19iaWc6IFwidG9vX2JpZ1wiLFxuICAgIHRvb19zbWFsbDogXCJ0b29fc21hbGxcIixcbiAgICBpbnZhbGlkX2Zvcm1hdDogXCJpbnZhbGlkX2Zvcm1hdFwiLFxuICAgIG5vdF9tdWx0aXBsZV9vZjogXCJub3RfbXVsdGlwbGVfb2ZcIixcbiAgICB1bnJlY29nbml6ZWRfa2V5czogXCJ1bnJlY29nbml6ZWRfa2V5c1wiLFxuICAgIGludmFsaWRfdW5pb246IFwiaW52YWxpZF91bmlvblwiLFxuICAgIGludmFsaWRfa2V5OiBcImludmFsaWRfa2V5XCIsXG4gICAgaW52YWxpZF9lbGVtZW50OiBcImludmFsaWRfZWxlbWVudFwiLFxuICAgIGludmFsaWRfdmFsdWU6IFwiaW52YWxpZF92YWx1ZVwiLFxuICAgIGN1c3RvbTogXCJjdXN0b21cIlxufTtcbmV4cG9ydCB7ICRicmFuZCwgY29uZmlnIH0gZnJvbSBcIi4uL2NvcmUvaW5kZXguanNcIjtcbi8qKiBAZGVwcmVjYXRlZCBVc2UgYHouY29uZmlnKHBhcmFtcylgIGluc3RlYWQuICovIGV4cG9ydCBmdW5jdGlvbiBzZXRFcnJvck1hcChtYXApIHtcbiAgICBjb3JlLmNvbmZpZyh7XG4gICAgICAgIGN1c3RvbUVycm9yOiBtYXBcbiAgICB9KTtcbn1cbi8qKiBAZGVwcmVjYXRlZCBVc2UgYHouY29uZmlnKClgIGluc3RlYWQuICovIGV4cG9ydCBmdW5jdGlvbiBnZXRFcnJvck1hcCgpIHtcbiAgICByZXR1cm4gY29yZS5jb25maWcoKS5jdXN0b21FcnJvcjtcbn1cbi8qKiBAZGVwcmVjYXRlZCBEbyBub3QgdXNlLiBTdHViIGRlZmluaXRpb24sIG9ubHkgaW5jbHVkZWQgZm9yIHpvZC10by1qc29uLXNjaGVtYSBjb21wYXRpYmlsaXR5LiAqLyBleHBvcnQgdmFyIFpvZEZpcnN0UGFydHlUeXBlS2luZDtcbihmdW5jdGlvbihab2RGaXJzdFBhcnR5VHlwZUtpbmQpIHt9KShab2RGaXJzdFBhcnR5VHlwZUtpbmQgfHwgKFpvZEZpcnN0UGFydHlUeXBlS2luZCA9IHt9KSk7XG4iLCAiaW1wb3J0ICogYXMgY29yZSBmcm9tIFwiLi4vY29yZS9pbmRleC5qc1wiO1xuaW1wb3J0ICogYXMgc2NoZW1hcyBmcm9tIFwiLi9zY2hlbWFzLmpzXCI7XG5leHBvcnQgZnVuY3Rpb24gc3RyaW5nKHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9jb2VyY2VkU3RyaW5nKHNjaGVtYXMuWm9kU3RyaW5nLCBwYXJhbXMpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIG51bWJlcihwYXJhbXMpIHtcbiAgICByZXR1cm4gY29yZS5fY29lcmNlZE51bWJlcihzY2hlbWFzLlpvZE51bWJlciwgcGFyYW1zKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBib29sZWFuKHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9jb2VyY2VkQm9vbGVhbihzY2hlbWFzLlpvZEJvb2xlYW4sIHBhcmFtcyk7XG59XG5leHBvcnQgZnVuY3Rpb24gYmlnaW50KHBhcmFtcykge1xuICAgIHJldHVybiBjb3JlLl9jb2VyY2VkQmlnaW50KHNjaGVtYXMuWm9kQmlnSW50LCBwYXJhbXMpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGRhdGUocGFyYW1zKSB7XG4gICAgcmV0dXJuIGNvcmUuX2NvZXJjZWREYXRlKHNjaGVtYXMuWm9kRGF0ZSwgcGFyYW1zKTtcbn1cbiIsICJpbXBvcnQgKiBhcyB6IGZyb20gXCIuL2V4dGVybmFsLmpzXCI7XG5leHBvcnQgeyB6IH07XG5leHBvcnQgKiBmcm9tIFwiLi9leHRlcm5hbC5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgejtcbiIsICJpbXBvcnQgejQgZnJvbSBcIi4vY2xhc3NpYy9pbmRleC5qc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2xhc3NpYy9pbmRleC5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgejQ7XG4iLCAiZXhwb3J0IHZhciB1dGlsO1xuKGZ1bmN0aW9uKHV0aWwpIHtcbiAgICB1dGlsLmFzc2VydEVxdWFsID0gKF8pPT57fTtcbiAgICBmdW5jdGlvbiBhc3NlcnRJcyhfYXJnKSB7fVxuICAgIHV0aWwuYXNzZXJ0SXMgPSBhc3NlcnRJcztcbiAgICBmdW5jdGlvbiBhc3NlcnROZXZlcihfeCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgICB9XG4gICAgdXRpbC5hc3NlcnROZXZlciA9IGFzc2VydE5ldmVyO1xuICAgIHV0aWwuYXJyYXlUb0VudW0gPSAoaXRlbXMpPT57XG4gICAgICAgIGNvbnN0IG9iaiA9IHt9O1xuICAgICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgaXRlbXMpe1xuICAgICAgICAgICAgb2JqW2l0ZW1dID0gaXRlbTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb2JqO1xuICAgIH07XG4gICAgdXRpbC5nZXRWYWxpZEVudW1WYWx1ZXMgPSAob2JqKT0+e1xuICAgICAgICBjb25zdCB2YWxpZEtleXMgPSB1dGlsLm9iamVjdEtleXMob2JqKS5maWx0ZXIoKGspPT50eXBlb2Ygb2JqW29ialtrXV0gIT09IFwibnVtYmVyXCIpO1xuICAgICAgICBjb25zdCBmaWx0ZXJlZCA9IHt9O1xuICAgICAgICBmb3IgKGNvbnN0IGsgb2YgdmFsaWRLZXlzKXtcbiAgICAgICAgICAgIGZpbHRlcmVkW2tdID0gb2JqW2tdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB1dGlsLm9iamVjdFZhbHVlcyhmaWx0ZXJlZCk7XG4gICAgfTtcbiAgICB1dGlsLm9iamVjdFZhbHVlcyA9IChvYmopPT57XG4gICAgICAgIHJldHVybiB1dGlsLm9iamVjdEtleXMob2JqKS5tYXAoZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgcmV0dXJuIG9ialtlXTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICB1dGlsLm9iamVjdEtleXMgPSB0eXBlb2YgT2JqZWN0LmtleXMgPT09IFwiZnVuY3Rpb25cIiAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGJhbi9iYW5cbiAgICAgPyAob2JqKT0+T2JqZWN0LmtleXMob2JqKSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGJhbi9iYW5cbiAgICAgOiAob2JqZWN0KT0+e1xuICAgICAgICBjb25zdCBrZXlzID0gW107XG4gICAgICAgIGZvcihjb25zdCBrZXkgaW4gb2JqZWN0KXtcbiAgICAgICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSB7XG4gICAgICAgICAgICAgICAga2V5cy5wdXNoKGtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGtleXM7XG4gICAgfTtcbiAgICB1dGlsLmZpbmQgPSAoYXJyLCBjaGVja2VyKT0+e1xuICAgICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgYXJyKXtcbiAgICAgICAgICAgIGlmIChjaGVja2VyKGl0ZW0pKSByZXR1cm4gaXRlbTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH07XG4gICAgdXRpbC5pc0ludGVnZXIgPSB0eXBlb2YgTnVtYmVyLmlzSW50ZWdlciA9PT0gXCJmdW5jdGlvblwiID8gKHZhbCk9Pk51bWJlci5pc0ludGVnZXIodmFsKSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGJhbi9iYW5cbiAgICAgOiAodmFsKT0+dHlwZW9mIHZhbCA9PT0gXCJudW1iZXJcIiAmJiBOdW1iZXIuaXNGaW5pdGUodmFsKSAmJiBNYXRoLmZsb29yKHZhbCkgPT09IHZhbDtcbiAgICBmdW5jdGlvbiBqb2luVmFsdWVzKGFycmF5LCBzZXBhcmF0b3IgPSBcIiB8IFwiKSB7XG4gICAgICAgIHJldHVybiBhcnJheS5tYXAoKHZhbCk9PnR5cGVvZiB2YWwgPT09IFwic3RyaW5nXCIgPyBgJyR7dmFsfSdgIDogdmFsKS5qb2luKHNlcGFyYXRvcik7XG4gICAgfVxuICAgIHV0aWwuam9pblZhbHVlcyA9IGpvaW5WYWx1ZXM7XG4gICAgdXRpbC5qc29uU3RyaW5naWZ5UmVwbGFjZXIgPSAoXywgdmFsdWUpPT57XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwiYmlnaW50XCIpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZS50b1N0cmluZygpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9O1xufSkodXRpbCB8fCAodXRpbCA9IHt9KSk7XG5leHBvcnQgdmFyIG9iamVjdFV0aWw7XG4oZnVuY3Rpb24ob2JqZWN0VXRpbCkge1xuICAgIG9iamVjdFV0aWwubWVyZ2VTaGFwZXMgPSAoZmlyc3QsIHNlY29uZCk9PntcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLmZpcnN0LFxuICAgICAgICAgICAgLi4uc2Vjb25kXG4gICAgICAgIH07XG4gICAgfTtcbn0pKG9iamVjdFV0aWwgfHwgKG9iamVjdFV0aWwgPSB7fSkpO1xuZXhwb3J0IGNvbnN0IFpvZFBhcnNlZFR5cGUgPSB1dGlsLmFycmF5VG9FbnVtKFtcbiAgICBcInN0cmluZ1wiLFxuICAgIFwibmFuXCIsXG4gICAgXCJudW1iZXJcIixcbiAgICBcImludGVnZXJcIixcbiAgICBcImZsb2F0XCIsXG4gICAgXCJib29sZWFuXCIsXG4gICAgXCJkYXRlXCIsXG4gICAgXCJiaWdpbnRcIixcbiAgICBcInN5bWJvbFwiLFxuICAgIFwiZnVuY3Rpb25cIixcbiAgICBcInVuZGVmaW5lZFwiLFxuICAgIFwibnVsbFwiLFxuICAgIFwiYXJyYXlcIixcbiAgICBcIm9iamVjdFwiLFxuICAgIFwidW5rbm93blwiLFxuICAgIFwicHJvbWlzZVwiLFxuICAgIFwidm9pZFwiLFxuICAgIFwibmV2ZXJcIixcbiAgICBcIm1hcFwiLFxuICAgIFwic2V0XCJcbl0pO1xuZXhwb3J0IGNvbnN0IGdldFBhcnNlZFR5cGUgPSAoZGF0YSk9PntcbiAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgc3dpdGNoKHQpe1xuICAgICAgICBjYXNlIFwidW5kZWZpbmVkXCI6XG4gICAgICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS51bmRlZmluZWQ7XG4gICAgICAgIGNhc2UgXCJzdHJpbmdcIjpcbiAgICAgICAgICAgIHJldHVybiBab2RQYXJzZWRUeXBlLnN0cmluZztcbiAgICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRhKSA/IFpvZFBhcnNlZFR5cGUubmFuIDogWm9kUGFyc2VkVHlwZS5udW1iZXI7XG4gICAgICAgIGNhc2UgXCJib29sZWFuXCI6XG4gICAgICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS5ib29sZWFuO1xuICAgICAgICBjYXNlIFwiZnVuY3Rpb25cIjpcbiAgICAgICAgICAgIHJldHVybiBab2RQYXJzZWRUeXBlLmZ1bmN0aW9uO1xuICAgICAgICBjYXNlIFwiYmlnaW50XCI6XG4gICAgICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS5iaWdpbnQ7XG4gICAgICAgIGNhc2UgXCJzeW1ib2xcIjpcbiAgICAgICAgICAgIHJldHVybiBab2RQYXJzZWRUeXBlLnN5bWJvbDtcbiAgICAgICAgY2FzZSBcIm9iamVjdFwiOlxuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS5hcnJheTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChkYXRhID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFpvZFBhcnNlZFR5cGUubnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChkYXRhLnRoZW4gJiYgdHlwZW9mIGRhdGEudGhlbiA9PT0gXCJmdW5jdGlvblwiICYmIGRhdGEuY2F0Y2ggJiYgdHlwZW9mIGRhdGEuY2F0Y2ggPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgICAgIHJldHVybiBab2RQYXJzZWRUeXBlLnByb21pc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodHlwZW9mIE1hcCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBkYXRhIGluc3RhbmNlb2YgTWFwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFpvZFBhcnNlZFR5cGUubWFwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGVvZiBTZXQgIT09IFwidW5kZWZpbmVkXCIgJiYgZGF0YSBpbnN0YW5jZW9mIFNldCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBab2RQYXJzZWRUeXBlLnNldDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0eXBlb2YgRGF0ZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBkYXRhIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBab2RQYXJzZWRUeXBlLmRhdGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS5vYmplY3Q7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS51bmtub3duO1xuICAgIH1cbn07XG4iLCAiaW1wb3J0IHsgdXRpbCB9IGZyb20gXCIuL2hlbHBlcnMvdXRpbC5qc1wiO1xuZXhwb3J0IGNvbnN0IFpvZElzc3VlQ29kZSA9IHV0aWwuYXJyYXlUb0VudW0oW1xuICAgIFwiaW52YWxpZF90eXBlXCIsXG4gICAgXCJpbnZhbGlkX2xpdGVyYWxcIixcbiAgICBcImN1c3RvbVwiLFxuICAgIFwiaW52YWxpZF91bmlvblwiLFxuICAgIFwiaW52YWxpZF91bmlvbl9kaXNjcmltaW5hdG9yXCIsXG4gICAgXCJpbnZhbGlkX2VudW1fdmFsdWVcIixcbiAgICBcInVucmVjb2duaXplZF9rZXlzXCIsXG4gICAgXCJpbnZhbGlkX2FyZ3VtZW50c1wiLFxuICAgIFwiaW52YWxpZF9yZXR1cm5fdHlwZVwiLFxuICAgIFwiaW52YWxpZF9kYXRlXCIsXG4gICAgXCJpbnZhbGlkX3N0cmluZ1wiLFxuICAgIFwidG9vX3NtYWxsXCIsXG4gICAgXCJ0b29fYmlnXCIsXG4gICAgXCJpbnZhbGlkX2ludGVyc2VjdGlvbl90eXBlc1wiLFxuICAgIFwibm90X211bHRpcGxlX29mXCIsXG4gICAgXCJub3RfZmluaXRlXCJcbl0pO1xuZXhwb3J0IGNvbnN0IHF1b3RlbGVzc0pzb24gPSAob2JqKT0+e1xuICAgIGNvbnN0IGpzb24gPSBKU09OLnN0cmluZ2lmeShvYmosIG51bGwsIDIpO1xuICAgIHJldHVybiBqc29uLnJlcGxhY2UoL1wiKFteXCJdKylcIjovZywgXCIkMTpcIik7XG59O1xuZXhwb3J0IGNsYXNzIFpvZEVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAgIGdldCBlcnJvcnMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmlzc3VlcztcbiAgICB9XG4gICAgY29uc3RydWN0b3IoaXNzdWVzKXtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5pc3N1ZXMgPSBbXTtcbiAgICAgICAgdGhpcy5hZGRJc3N1ZSA9IChzdWIpPT57XG4gICAgICAgICAgICB0aGlzLmlzc3VlcyA9IFtcbiAgICAgICAgICAgICAgICAuLi50aGlzLmlzc3VlcyxcbiAgICAgICAgICAgICAgICBzdWJcbiAgICAgICAgICAgIF07XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuYWRkSXNzdWVzID0gKHN1YnMgPSBbXSk9PntcbiAgICAgICAgICAgIHRoaXMuaXNzdWVzID0gW1xuICAgICAgICAgICAgICAgIC4uLnRoaXMuaXNzdWVzLFxuICAgICAgICAgICAgICAgIC4uLnN1YnNcbiAgICAgICAgICAgIF07XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGFjdHVhbFByb3RvID0gbmV3LnRhcmdldC5wcm90b3R5cGU7XG4gICAgICAgIGlmIChPYmplY3Quc2V0UHJvdG90eXBlT2YpIHtcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBiYW4vYmFuXG4gICAgICAgICAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgYWN0dWFsUHJvdG8pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fX3Byb3RvX18gPSBhY3R1YWxQcm90bztcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm5hbWUgPSBcIlpvZEVycm9yXCI7XG4gICAgICAgIHRoaXMuaXNzdWVzID0gaXNzdWVzO1xuICAgIH1cbiAgICBmb3JtYXQoX21hcHBlcikge1xuICAgICAgICBjb25zdCBtYXBwZXIgPSBfbWFwcGVyIHx8IGZ1bmN0aW9uKGlzc3VlKSB7XG4gICAgICAgICAgICByZXR1cm4gaXNzdWUubWVzc2FnZTtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgZmllbGRFcnJvcnMgPSB7XG4gICAgICAgICAgICBfZXJyb3JzOiBbXVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBwcm9jZXNzRXJyb3IgPSAoZXJyb3IpPT57XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGlzc3VlIG9mIGVycm9yLmlzc3Vlcyl7XG4gICAgICAgICAgICAgICAgaWYgKGlzc3VlLmNvZGUgPT09IFwiaW52YWxpZF91bmlvblwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGlzc3VlLnVuaW9uRXJyb3JzLm1hcChwcm9jZXNzRXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNzdWUuY29kZSA9PT0gXCJpbnZhbGlkX3JldHVybl90eXBlXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc0Vycm9yKGlzc3VlLnJldHVyblR5cGVFcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpc3N1ZS5jb2RlID09PSBcImludmFsaWRfYXJndW1lbnRzXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc0Vycm9yKGlzc3VlLmFyZ3VtZW50c0Vycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGlzc3VlLnBhdGgubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGZpZWxkRXJyb3JzLl9lcnJvcnMucHVzaChtYXBwZXIoaXNzdWUpKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBsZXQgY3VyciA9IGZpZWxkRXJyb3JzO1xuICAgICAgICAgICAgICAgICAgICBsZXQgaSA9IDA7XG4gICAgICAgICAgICAgICAgICAgIHdoaWxlKGkgPCBpc3N1ZS5wYXRoLmxlbmd0aCl7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlbCA9IGlzc3VlLnBhdGhbaV07XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0ZXJtaW5hbCA9IGkgPT09IGlzc3VlLnBhdGgubGVuZ3RoIC0gMTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdGVybWluYWwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyW2VsXSA9IGN1cnJbZWxdIHx8IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2Vycm9yczogW11cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgKHR5cGVvZiBlbCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gICBjdXJyW2VsXSA9IGN1cnJbZWxdIHx8IHsgX2Vycm9yczogW10gfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIH0gZWxzZSBpZiAodHlwZW9mIGVsID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyAgIGNvbnN0IGVycm9yQXJyYXk6IGFueSA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gICBlcnJvckFycmF5Ll9lcnJvcnMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgY3VycltlbF0gPSBjdXJyW2VsXSB8fCBlcnJvckFycmF5O1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gfVxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyW2VsXSA9IGN1cnJbZWxdIHx8IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2Vycm9yczogW11cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJbZWxdLl9lcnJvcnMucHVzaChtYXBwZXIoaXNzdWUpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnIgPSBjdXJyW2VsXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGkrKztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgcHJvY2Vzc0Vycm9yKHRoaXMpO1xuICAgICAgICByZXR1cm4gZmllbGRFcnJvcnM7XG4gICAgfVxuICAgIHN0YXRpYyBhc3NlcnQodmFsdWUpIHtcbiAgICAgICAgaWYgKCEodmFsdWUgaW5zdGFuY2VvZiBab2RFcnJvcikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgTm90IGEgWm9kRXJyb3I6ICR7dmFsdWV9YCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgdG9TdHJpbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1lc3NhZ2U7XG4gICAgfVxuICAgIGdldCBtZXNzYWdlKCkge1xuICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodGhpcy5pc3N1ZXMsIHV0aWwuanNvblN0cmluZ2lmeVJlcGxhY2VyLCAyKTtcbiAgICB9XG4gICAgZ2V0IGlzRW1wdHkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmlzc3Vlcy5sZW5ndGggPT09IDA7XG4gICAgfVxuICAgIGZsYXR0ZW4obWFwcGVyID0gKGlzc3VlKT0+aXNzdWUubWVzc2FnZSkge1xuICAgICAgICBjb25zdCBmaWVsZEVycm9ycyA9IHt9O1xuICAgICAgICBjb25zdCBmb3JtRXJyb3JzID0gW107XG4gICAgICAgIGZvciAoY29uc3Qgc3ViIG9mIHRoaXMuaXNzdWVzKXtcbiAgICAgICAgICAgIGlmIChzdWIucGF0aC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZmlyc3RFbCA9IHN1Yi5wYXRoWzBdO1xuICAgICAgICAgICAgICAgIGZpZWxkRXJyb3JzW2ZpcnN0RWxdID0gZmllbGRFcnJvcnNbZmlyc3RFbF0gfHwgW107XG4gICAgICAgICAgICAgICAgZmllbGRFcnJvcnNbZmlyc3RFbF0ucHVzaChtYXBwZXIoc3ViKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGZvcm1FcnJvcnMucHVzaChtYXBwZXIoc3ViKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGZvcm1FcnJvcnMsXG4gICAgICAgICAgICBmaWVsZEVycm9yc1xuICAgICAgICB9O1xuICAgIH1cbiAgICBnZXQgZm9ybUVycm9ycygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZmxhdHRlbigpO1xuICAgIH1cbn1cblpvZEVycm9yLmNyZWF0ZSA9IChpc3N1ZXMpPT57XG4gICAgY29uc3QgZXJyb3IgPSBuZXcgWm9kRXJyb3IoaXNzdWVzKTtcbiAgICByZXR1cm4gZXJyb3I7XG59O1xuIiwgImltcG9ydCB7IFpvZElzc3VlQ29kZSB9IGZyb20gXCIuLi9ab2RFcnJvci5qc1wiO1xuaW1wb3J0IHsgdXRpbCwgWm9kUGFyc2VkVHlwZSB9IGZyb20gXCIuLi9oZWxwZXJzL3V0aWwuanNcIjtcbmNvbnN0IGVycm9yTWFwID0gKGlzc3VlLCBfY3R4KT0+e1xuICAgIGxldCBtZXNzYWdlO1xuICAgIHN3aXRjaChpc3N1ZS5jb2RlKXtcbiAgICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlOlxuICAgICAgICAgICAgaWYgKGlzc3VlLnJlY2VpdmVkID09PSBab2RQYXJzZWRUeXBlLnVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBcIlJlcXVpcmVkXCI7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBgRXhwZWN0ZWQgJHtpc3N1ZS5leHBlY3RlZH0sIHJlY2VpdmVkICR7aXNzdWUucmVjZWl2ZWR9YDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFpvZElzc3VlQ29kZS5pbnZhbGlkX2xpdGVyYWw6XG4gICAgICAgICAgICBtZXNzYWdlID0gYEludmFsaWQgbGl0ZXJhbCB2YWx1ZSwgZXhwZWN0ZWQgJHtKU09OLnN0cmluZ2lmeShpc3N1ZS5leHBlY3RlZCwgdXRpbC5qc29uU3RyaW5naWZ5UmVwbGFjZXIpfWA7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBab2RJc3N1ZUNvZGUudW5yZWNvZ25pemVkX2tleXM6XG4gICAgICAgICAgICBtZXNzYWdlID0gYFVucmVjb2duaXplZCBrZXkocykgaW4gb2JqZWN0OiAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5rZXlzLCBcIiwgXCIpfWA7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF91bmlvbjpcbiAgICAgICAgICAgIG1lc3NhZ2UgPSBgSW52YWxpZCBpbnB1dGA7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF91bmlvbl9kaXNjcmltaW5hdG9yOlxuICAgICAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkIGRpc2NyaW1pbmF0b3IgdmFsdWUuIEV4cGVjdGVkICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLm9wdGlvbnMpfWA7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF9lbnVtX3ZhbHVlOlxuICAgICAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkIGVudW0gdmFsdWUuIEV4cGVjdGVkICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLm9wdGlvbnMpfSwgcmVjZWl2ZWQgJyR7aXNzdWUucmVjZWl2ZWR9J2A7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF9hcmd1bWVudHM6XG4gICAgICAgICAgICBtZXNzYWdlID0gYEludmFsaWQgZnVuY3Rpb24gYXJndW1lbnRzYDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFpvZElzc3VlQ29kZS5pbnZhbGlkX3JldHVybl90eXBlOlxuICAgICAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkIGZ1bmN0aW9uIHJldHVybiB0eXBlYDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFpvZElzc3VlQ29kZS5pbnZhbGlkX2RhdGU6XG4gICAgICAgICAgICBtZXNzYWdlID0gYEludmFsaWQgZGF0ZWA7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmc6XG4gICAgICAgICAgICBpZiAodHlwZW9mIGlzc3VlLnZhbGlkYXRpb24gPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgICAgICBpZiAoXCJpbmNsdWRlc1wiIGluIGlzc3VlLnZhbGlkYXRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkIGlucHV0OiBtdXN0IGluY2x1ZGUgXCIke2lzc3VlLnZhbGlkYXRpb24uaW5jbHVkZXN9XCJgO1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGlzc3VlLnZhbGlkYXRpb24ucG9zaXRpb24gPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBgJHttZXNzYWdlfSBhdCBvbmUgb3IgbW9yZSBwb3NpdGlvbnMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICR7aXNzdWUudmFsaWRhdGlvbi5wb3NpdGlvbn1gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChcInN0YXJ0c1dpdGhcIiBpbiBpc3N1ZS52YWxpZGF0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBgSW52YWxpZCBpbnB1dDogbXVzdCBzdGFydCB3aXRoIFwiJHtpc3N1ZS52YWxpZGF0aW9uLnN0YXJ0c1dpdGh9XCJgO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoXCJlbmRzV2l0aFwiIGluIGlzc3VlLnZhbGlkYXRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkIGlucHV0OiBtdXN0IGVuZCB3aXRoIFwiJHtpc3N1ZS52YWxpZGF0aW9uLmVuZHNXaXRofVwiYDtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB1dGlsLmFzc2VydE5ldmVyKGlzc3VlLnZhbGlkYXRpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNzdWUudmFsaWRhdGlvbiAhPT0gXCJyZWdleFwiKSB7XG4gICAgICAgICAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkICR7aXNzdWUudmFsaWRhdGlvbn1gO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlID0gXCJJbnZhbGlkXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBab2RJc3N1ZUNvZGUudG9vX3NtYWxsOlxuICAgICAgICAgICAgaWYgKGlzc3VlLnR5cGUgPT09IFwiYXJyYXlcIikgbWVzc2FnZSA9IGBBcnJheSBtdXN0IGNvbnRhaW4gJHtpc3N1ZS5leGFjdCA/IFwiZXhhY3RseVwiIDogaXNzdWUuaW5jbHVzaXZlID8gYGF0IGxlYXN0YCA6IGBtb3JlIHRoYW5gfSAke2lzc3VlLm1pbmltdW19IGVsZW1lbnQocylgO1xuICAgICAgICAgICAgZWxzZSBpZiAoaXNzdWUudHlwZSA9PT0gXCJzdHJpbmdcIikgbWVzc2FnZSA9IGBTdHJpbmcgbXVzdCBjb250YWluICR7aXNzdWUuZXhhY3QgPyBcImV4YWN0bHlcIiA6IGlzc3VlLmluY2x1c2l2ZSA/IGBhdCBsZWFzdGAgOiBgb3ZlcmB9ICR7aXNzdWUubWluaW11bX0gY2hhcmFjdGVyKHMpYDtcbiAgICAgICAgICAgIGVsc2UgaWYgKGlzc3VlLnR5cGUgPT09IFwibnVtYmVyXCIpIG1lc3NhZ2UgPSBgTnVtYmVyIG11c3QgYmUgJHtpc3N1ZS5leGFjdCA/IGBleGFjdGx5IGVxdWFsIHRvIGAgOiBpc3N1ZS5pbmNsdXNpdmUgPyBgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIGAgOiBgZ3JlYXRlciB0aGFuIGB9JHtpc3N1ZS5taW5pbXVtfWA7XG4gICAgICAgICAgICBlbHNlIGlmIChpc3N1ZS50eXBlID09PSBcImJpZ2ludFwiKSBtZXNzYWdlID0gYE51bWJlciBtdXN0IGJlICR7aXNzdWUuZXhhY3QgPyBgZXhhY3RseSBlcXVhbCB0byBgIDogaXNzdWUuaW5jbHVzaXZlID8gYGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBgIDogYGdyZWF0ZXIgdGhhbiBgfSR7aXNzdWUubWluaW11bX1gO1xuICAgICAgICAgICAgZWxzZSBpZiAoaXNzdWUudHlwZSA9PT0gXCJkYXRlXCIpIG1lc3NhZ2UgPSBgRGF0ZSBtdXN0IGJlICR7aXNzdWUuZXhhY3QgPyBgZXhhY3RseSBlcXVhbCB0byBgIDogaXNzdWUuaW5jbHVzaXZlID8gYGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBgIDogYGdyZWF0ZXIgdGhhbiBgfSR7bmV3IERhdGUoTnVtYmVyKGlzc3VlLm1pbmltdW0pKX1gO1xuICAgICAgICAgICAgZWxzZSBtZXNzYWdlID0gXCJJbnZhbGlkIGlucHV0XCI7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBab2RJc3N1ZUNvZGUudG9vX2JpZzpcbiAgICAgICAgICAgIGlmIChpc3N1ZS50eXBlID09PSBcImFycmF5XCIpIG1lc3NhZ2UgPSBgQXJyYXkgbXVzdCBjb250YWluICR7aXNzdWUuZXhhY3QgPyBgZXhhY3RseWAgOiBpc3N1ZS5pbmNsdXNpdmUgPyBgYXQgbW9zdGAgOiBgbGVzcyB0aGFuYH0gJHtpc3N1ZS5tYXhpbXVtfSBlbGVtZW50KHMpYDtcbiAgICAgICAgICAgIGVsc2UgaWYgKGlzc3VlLnR5cGUgPT09IFwic3RyaW5nXCIpIG1lc3NhZ2UgPSBgU3RyaW5nIG11c3QgY29udGFpbiAke2lzc3VlLmV4YWN0ID8gYGV4YWN0bHlgIDogaXNzdWUuaW5jbHVzaXZlID8gYGF0IG1vc3RgIDogYHVuZGVyYH0gJHtpc3N1ZS5tYXhpbXVtfSBjaGFyYWN0ZXIocylgO1xuICAgICAgICAgICAgZWxzZSBpZiAoaXNzdWUudHlwZSA9PT0gXCJudW1iZXJcIikgbWVzc2FnZSA9IGBOdW1iZXIgbXVzdCBiZSAke2lzc3VlLmV4YWN0ID8gYGV4YWN0bHlgIDogaXNzdWUuaW5jbHVzaXZlID8gYGxlc3MgdGhhbiBvciBlcXVhbCB0b2AgOiBgbGVzcyB0aGFuYH0gJHtpc3N1ZS5tYXhpbXVtfWA7XG4gICAgICAgICAgICBlbHNlIGlmIChpc3N1ZS50eXBlID09PSBcImJpZ2ludFwiKSBtZXNzYWdlID0gYEJpZ0ludCBtdXN0IGJlICR7aXNzdWUuZXhhY3QgPyBgZXhhY3RseWAgOiBpc3N1ZS5pbmNsdXNpdmUgPyBgbGVzcyB0aGFuIG9yIGVxdWFsIHRvYCA6IGBsZXNzIHRoYW5gfSAke2lzc3VlLm1heGltdW19YDtcbiAgICAgICAgICAgIGVsc2UgaWYgKGlzc3VlLnR5cGUgPT09IFwiZGF0ZVwiKSBtZXNzYWdlID0gYERhdGUgbXVzdCBiZSAke2lzc3VlLmV4YWN0ID8gYGV4YWN0bHlgIDogaXNzdWUuaW5jbHVzaXZlID8gYHNtYWxsZXIgdGhhbiBvciBlcXVhbCB0b2AgOiBgc21hbGxlciB0aGFuYH0gJHtuZXcgRGF0ZShOdW1iZXIoaXNzdWUubWF4aW11bSkpfWA7XG4gICAgICAgICAgICBlbHNlIG1lc3NhZ2UgPSBcIkludmFsaWQgaW5wdXRcIjtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFpvZElzc3VlQ29kZS5jdXN0b206XG4gICAgICAgICAgICBtZXNzYWdlID0gYEludmFsaWQgaW5wdXRgO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgWm9kSXNzdWVDb2RlLmludmFsaWRfaW50ZXJzZWN0aW9uX3R5cGVzOlxuICAgICAgICAgICAgbWVzc2FnZSA9IGBJbnRlcnNlY3Rpb24gcmVzdWx0cyBjb3VsZCBub3QgYmUgbWVyZ2VkYDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFpvZElzc3VlQ29kZS5ub3RfbXVsdGlwbGVfb2Y6XG4gICAgICAgICAgICBtZXNzYWdlID0gYE51bWJlciBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgJHtpc3N1ZS5tdWx0aXBsZU9mfWA7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBab2RJc3N1ZUNvZGUubm90X2Zpbml0ZTpcbiAgICAgICAgICAgIG1lc3NhZ2UgPSBcIk51bWJlciBtdXN0IGJlIGZpbml0ZVwiO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBtZXNzYWdlID0gX2N0eC5kZWZhdWx0RXJyb3I7XG4gICAgICAgICAgICB1dGlsLmFzc2VydE5ldmVyKGlzc3VlKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbWVzc2FnZVxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZXJyb3JNYXA7XG4iLCAiaW1wb3J0IGRlZmF1bHRFcnJvck1hcCBmcm9tIFwiLi9sb2NhbGVzL2VuLmpzXCI7XG5sZXQgb3ZlcnJpZGVFcnJvck1hcCA9IGRlZmF1bHRFcnJvck1hcDtcbmV4cG9ydCB7IGRlZmF1bHRFcnJvck1hcCB9O1xuZXhwb3J0IGZ1bmN0aW9uIHNldEVycm9yTWFwKG1hcCkge1xuICAgIG92ZXJyaWRlRXJyb3JNYXAgPSBtYXA7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2V0RXJyb3JNYXAoKSB7XG4gICAgcmV0dXJuIG92ZXJyaWRlRXJyb3JNYXA7XG59XG4iLCAiaW1wb3J0IHsgZ2V0RXJyb3JNYXAgfSBmcm9tIFwiLi4vZXJyb3JzLmpzXCI7XG5pbXBvcnQgZGVmYXVsdEVycm9yTWFwIGZyb20gXCIuLi9sb2NhbGVzL2VuLmpzXCI7XG5leHBvcnQgY29uc3QgbWFrZUlzc3VlID0gKHBhcmFtcyk9PntcbiAgICBjb25zdCB7IGRhdGEsIHBhdGgsIGVycm9yTWFwcywgaXNzdWVEYXRhIH0gPSBwYXJhbXM7XG4gICAgY29uc3QgZnVsbFBhdGggPSBbXG4gICAgICAgIC4uLnBhdGgsXG4gICAgICAgIC4uLmlzc3VlRGF0YS5wYXRoIHx8IFtdXG4gICAgXTtcbiAgICBjb25zdCBmdWxsSXNzdWUgPSB7XG4gICAgICAgIC4uLmlzc3VlRGF0YSxcbiAgICAgICAgcGF0aDogZnVsbFBhdGhcbiAgICB9O1xuICAgIGlmIChpc3N1ZURhdGEubWVzc2FnZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi5pc3N1ZURhdGEsXG4gICAgICAgICAgICBwYXRoOiBmdWxsUGF0aCxcbiAgICAgICAgICAgIG1lc3NhZ2U6IGlzc3VlRGF0YS5tZXNzYWdlXG4gICAgICAgIH07XG4gICAgfVxuICAgIGxldCBlcnJvck1lc3NhZ2UgPSBcIlwiO1xuICAgIGNvbnN0IG1hcHMgPSBlcnJvck1hcHMuZmlsdGVyKChtKT0+ISFtKS5zbGljZSgpLnJldmVyc2UoKTtcbiAgICBmb3IgKGNvbnN0IG1hcCBvZiBtYXBzKXtcbiAgICAgICAgZXJyb3JNZXNzYWdlID0gbWFwKGZ1bGxJc3N1ZSwge1xuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgIGRlZmF1bHRFcnJvcjogZXJyb3JNZXNzYWdlXG4gICAgICAgIH0pLm1lc3NhZ2U7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIC4uLmlzc3VlRGF0YSxcbiAgICAgICAgcGF0aDogZnVsbFBhdGgsXG4gICAgICAgIG1lc3NhZ2U6IGVycm9yTWVzc2FnZVxuICAgIH07XG59O1xuZXhwb3J0IGNvbnN0IEVNUFRZX1BBVEggPSBbXTtcbmV4cG9ydCBmdW5jdGlvbiBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIGlzc3VlRGF0YSkge1xuICAgIGNvbnN0IG92ZXJyaWRlTWFwID0gZ2V0RXJyb3JNYXAoKTtcbiAgICBjb25zdCBpc3N1ZSA9IG1ha2VJc3N1ZSh7XG4gICAgICAgIGlzc3VlRGF0YTogaXNzdWVEYXRhLFxuICAgICAgICBkYXRhOiBjdHguZGF0YSxcbiAgICAgICAgcGF0aDogY3R4LnBhdGgsXG4gICAgICAgIGVycm9yTWFwczogW1xuICAgICAgICAgICAgY3R4LmNvbW1vbi5jb250ZXh0dWFsRXJyb3JNYXAsXG4gICAgICAgICAgICBjdHguc2NoZW1hRXJyb3JNYXAsXG4gICAgICAgICAgICBvdmVycmlkZU1hcCxcbiAgICAgICAgICAgIG92ZXJyaWRlTWFwID09PSBkZWZhdWx0RXJyb3JNYXAgPyB1bmRlZmluZWQgOiBkZWZhdWx0RXJyb3JNYXBcbiAgICAgICAgXS5maWx0ZXIoKHgpPT4hIXgpXG4gICAgfSk7XG4gICAgY3R4LmNvbW1vbi5pc3N1ZXMucHVzaChpc3N1ZSk7XG59XG5leHBvcnQgY2xhc3MgUGFyc2VTdGF0dXMge1xuICAgIGNvbnN0cnVjdG9yKCl7XG4gICAgICAgIHRoaXMudmFsdWUgPSBcInZhbGlkXCI7XG4gICAgfVxuICAgIGRpcnR5KCkge1xuICAgICAgICBpZiAodGhpcy52YWx1ZSA9PT0gXCJ2YWxpZFwiKSB0aGlzLnZhbHVlID0gXCJkaXJ0eVwiO1xuICAgIH1cbiAgICBhYm9ydCgpIHtcbiAgICAgICAgaWYgKHRoaXMudmFsdWUgIT09IFwiYWJvcnRlZFwiKSB0aGlzLnZhbHVlID0gXCJhYm9ydGVkXCI7XG4gICAgfVxuICAgIHN0YXRpYyBtZXJnZUFycmF5KHN0YXR1cywgcmVzdWx0cykge1xuICAgICAgICBjb25zdCBhcnJheVZhbHVlID0gW107XG4gICAgICAgIGZvciAoY29uc3QgcyBvZiByZXN1bHRzKXtcbiAgICAgICAgICAgIGlmIChzLnN0YXR1cyA9PT0gXCJhYm9ydGVkXCIpIHJldHVybiBJTlZBTElEO1xuICAgICAgICAgICAgaWYgKHMuc3RhdHVzID09PSBcImRpcnR5XCIpIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgYXJyYXlWYWx1ZS5wdXNoKHMudmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdGF0dXM6IHN0YXR1cy52YWx1ZSxcbiAgICAgICAgICAgIHZhbHVlOiBhcnJheVZhbHVlXG4gICAgICAgIH07XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyBtZXJnZU9iamVjdEFzeW5jKHN0YXR1cywgcGFpcnMpIHtcbiAgICAgICAgY29uc3Qgc3luY1BhaXJzID0gW107XG4gICAgICAgIGZvciAoY29uc3QgcGFpciBvZiBwYWlycyl7XG4gICAgICAgICAgICBjb25zdCBrZXkgPSBhd2FpdCBwYWlyLmtleTtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gYXdhaXQgcGFpci52YWx1ZTtcbiAgICAgICAgICAgIHN5bmNQYWlycy5wdXNoKHtcbiAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgdmFsdWVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBQYXJzZVN0YXR1cy5tZXJnZU9iamVjdFN5bmMoc3RhdHVzLCBzeW5jUGFpcnMpO1xuICAgIH1cbiAgICBzdGF0aWMgbWVyZ2VPYmplY3RTeW5jKHN0YXR1cywgcGFpcnMpIHtcbiAgICAgICAgY29uc3QgZmluYWxPYmplY3QgPSB7fTtcbiAgICAgICAgZm9yIChjb25zdCBwYWlyIG9mIHBhaXJzKXtcbiAgICAgICAgICAgIGNvbnN0IHsga2V5LCB2YWx1ZSB9ID0gcGFpcjtcbiAgICAgICAgICAgIGlmIChrZXkuc3RhdHVzID09PSBcImFib3J0ZWRcIikgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgICAgICBpZiAodmFsdWUuc3RhdHVzID09PSBcImFib3J0ZWRcIikgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgICAgICBpZiAoa2V5LnN0YXR1cyA9PT0gXCJkaXJ0eVwiKSBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgIGlmICh2YWx1ZS5zdGF0dXMgPT09IFwiZGlydHlcIikgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICBpZiAoa2V5LnZhbHVlICE9PSBcIl9fcHJvdG9fX1wiICYmICh0eXBlb2YgdmFsdWUudmFsdWUgIT09IFwidW5kZWZpbmVkXCIgfHwgcGFpci5hbHdheXNTZXQpKSB7XG4gICAgICAgICAgICAgICAgZmluYWxPYmplY3Rba2V5LnZhbHVlXSA9IHZhbHVlLnZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdGF0dXM6IHN0YXR1cy52YWx1ZSxcbiAgICAgICAgICAgIHZhbHVlOiBmaW5hbE9iamVjdFxuICAgICAgICB9O1xuICAgIH1cbn1cbmV4cG9ydCBjb25zdCBJTlZBTElEID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgc3RhdHVzOiBcImFib3J0ZWRcIlxufSk7XG5leHBvcnQgY29uc3QgRElSVFkgPSAodmFsdWUpPT4oe1xuICAgICAgICBzdGF0dXM6IFwiZGlydHlcIixcbiAgICAgICAgdmFsdWVcbiAgICB9KTtcbmV4cG9ydCBjb25zdCBPSyA9ICh2YWx1ZSk9Pih7XG4gICAgICAgIHN0YXR1czogXCJ2YWxpZFwiLFxuICAgICAgICB2YWx1ZVxuICAgIH0pO1xuZXhwb3J0IGNvbnN0IGlzQWJvcnRlZCA9ICh4KT0+eC5zdGF0dXMgPT09IFwiYWJvcnRlZFwiO1xuZXhwb3J0IGNvbnN0IGlzRGlydHkgPSAoeCk9Pnguc3RhdHVzID09PSBcImRpcnR5XCI7XG5leHBvcnQgY29uc3QgaXNWYWxpZCA9ICh4KT0+eC5zdGF0dXMgPT09IFwidmFsaWRcIjtcbmV4cG9ydCBjb25zdCBpc0FzeW5jID0gKHgpPT50eXBlb2YgUHJvbWlzZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiB4IGluc3RhbmNlb2YgUHJvbWlzZTtcbiIsICJleHBvcnQgdmFyIGVycm9yVXRpbDtcbihmdW5jdGlvbihlcnJvclV0aWwpIHtcbiAgICBlcnJvclV0aWwuZXJyVG9PYmogPSAobWVzc2FnZSk9PnR5cGVvZiBtZXNzYWdlID09PSBcInN0cmluZ1wiID8ge1xuICAgICAgICAgICAgbWVzc2FnZVxuICAgICAgICB9IDogbWVzc2FnZSB8fCB7fTtcbiAgICAvLyBiaW9tZS1pZ25vcmUgbGludDpcbiAgICBlcnJvclV0aWwudG9TdHJpbmcgPSAobWVzc2FnZSk9PnR5cGVvZiBtZXNzYWdlID09PSBcInN0cmluZ1wiID8gbWVzc2FnZSA6IG1lc3NhZ2U/Lm1lc3NhZ2U7XG59KShlcnJvclV0aWwgfHwgKGVycm9yVXRpbCA9IHt9KSk7XG4iLCAiaW1wb3J0IHsgWm9kRXJyb3IsIFpvZElzc3VlQ29kZSB9IGZyb20gXCIuL1pvZEVycm9yLmpzXCI7XG5pbXBvcnQgeyBkZWZhdWx0RXJyb3JNYXAsIGdldEVycm9yTWFwIH0gZnJvbSBcIi4vZXJyb3JzLmpzXCI7XG5pbXBvcnQgeyBlcnJvclV0aWwgfSBmcm9tIFwiLi9oZWxwZXJzL2Vycm9yVXRpbC5qc1wiO1xuaW1wb3J0IHsgRElSVFksIElOVkFMSUQsIE9LLCBQYXJzZVN0YXR1cywgYWRkSXNzdWVUb0NvbnRleHQsIGlzQWJvcnRlZCwgaXNBc3luYywgaXNEaXJ0eSwgaXNWYWxpZCwgbWFrZUlzc3VlIH0gZnJvbSBcIi4vaGVscGVycy9wYXJzZVV0aWwuanNcIjtcbmltcG9ydCB7IHV0aWwsIFpvZFBhcnNlZFR5cGUsIGdldFBhcnNlZFR5cGUgfSBmcm9tIFwiLi9oZWxwZXJzL3V0aWwuanNcIjtcbmNsYXNzIFBhcnNlSW5wdXRMYXp5UGF0aCB7XG4gICAgY29uc3RydWN0b3IocGFyZW50LCB2YWx1ZSwgcGF0aCwga2V5KXtcbiAgICAgICAgdGhpcy5fY2FjaGVkUGF0aCA9IFtdO1xuICAgICAgICB0aGlzLnBhcmVudCA9IHBhcmVudDtcbiAgICAgICAgdGhpcy5kYXRhID0gdmFsdWU7XG4gICAgICAgIHRoaXMuX3BhdGggPSBwYXRoO1xuICAgICAgICB0aGlzLl9rZXkgPSBrZXk7XG4gICAgfVxuICAgIGdldCBwYXRoKCkge1xuICAgICAgICBpZiAoIXRoaXMuX2NhY2hlZFBhdGgubGVuZ3RoKSB7XG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh0aGlzLl9rZXkpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fY2FjaGVkUGF0aC5wdXNoKC4uLnRoaXMuX3BhdGgsIC4uLnRoaXMuX2tleSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX2NhY2hlZFBhdGgucHVzaCguLi50aGlzLl9wYXRoLCB0aGlzLl9rZXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9jYWNoZWRQYXRoO1xuICAgIH1cbn1cbmNvbnN0IGhhbmRsZVJlc3VsdCA9IChjdHgsIHJlc3VsdCk9PntcbiAgICBpZiAoaXNWYWxpZChyZXN1bHQpKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgZGF0YTogcmVzdWx0LnZhbHVlXG4gICAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKCFjdHguY29tbW9uLmlzc3Vlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlZhbGlkYXRpb24gZmFpbGVkIGJ1dCBubyBpc3N1ZXMgZGV0ZWN0ZWQuXCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgIGdldCBlcnJvciAoKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2Vycm9yKSByZXR1cm4gdGhpcy5fZXJyb3I7XG4gICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgWm9kRXJyb3IoY3R4LmNvbW1vbi5pc3N1ZXMpO1xuICAgICAgICAgICAgICAgIHRoaXMuX2Vycm9yID0gZXJyb3I7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2Vycm9yO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cbn07XG5mdW5jdGlvbiBwcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykge1xuICAgIGlmICghcGFyYW1zKSByZXR1cm4ge307XG4gICAgY29uc3QgeyBlcnJvck1hcCwgaW52YWxpZF90eXBlX2Vycm9yLCByZXF1aXJlZF9lcnJvciwgZGVzY3JpcHRpb24gfSA9IHBhcmFtcztcbiAgICBpZiAoZXJyb3JNYXAgJiYgKGludmFsaWRfdHlwZV9lcnJvciB8fCByZXF1aXJlZF9lcnJvcikpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW4ndCB1c2UgXCJpbnZhbGlkX3R5cGVfZXJyb3JcIiBvciBcInJlcXVpcmVkX2Vycm9yXCIgaW4gY29uanVuY3Rpb24gd2l0aCBjdXN0b20gZXJyb3IgbWFwLmApO1xuICAgIH1cbiAgICBpZiAoZXJyb3JNYXApIHJldHVybiB7XG4gICAgICAgIGVycm9yTWFwOiBlcnJvck1hcCxcbiAgICAgICAgZGVzY3JpcHRpb25cbiAgICB9O1xuICAgIGNvbnN0IGN1c3RvbU1hcCA9IChpc3MsIGN0eCk9PntcbiAgICAgICAgY29uc3QgeyBtZXNzYWdlIH0gPSBwYXJhbXM7XG4gICAgICAgIGlmIChpc3MuY29kZSA9PT0gXCJpbnZhbGlkX2VudW1fdmFsdWVcIikge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBtZXNzYWdlID8/IGN0eC5kZWZhdWx0RXJyb3JcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBjdHguZGF0YSA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBtZXNzYWdlID8/IHJlcXVpcmVkX2Vycm9yID8/IGN0eC5kZWZhdWx0RXJyb3JcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzcy5jb2RlICE9PSBcImludmFsaWRfdHlwZVwiKSByZXR1cm4ge1xuICAgICAgICAgICAgbWVzc2FnZTogY3R4LmRlZmF1bHRFcnJvclxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbWVzc2FnZTogbWVzc2FnZSA/PyBpbnZhbGlkX3R5cGVfZXJyb3IgPz8gY3R4LmRlZmF1bHRFcnJvclxuICAgICAgICB9O1xuICAgIH07XG4gICAgcmV0dXJuIHtcbiAgICAgICAgZXJyb3JNYXA6IGN1c3RvbU1hcCxcbiAgICAgICAgZGVzY3JpcHRpb25cbiAgICB9O1xufVxuZXhwb3J0IGNsYXNzIFpvZFR5cGUge1xuICAgIGdldCBkZXNjcmlwdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi5kZXNjcmlwdGlvbjtcbiAgICB9XG4gICAgX2dldFR5cGUoaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIGdldFBhcnNlZFR5cGUoaW5wdXQuZGF0YSk7XG4gICAgfVxuICAgIF9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KSB7XG4gICAgICAgIHJldHVybiBjdHggfHwge1xuICAgICAgICAgICAgY29tbW9uOiBpbnB1dC5wYXJlbnQuY29tbW9uLFxuICAgICAgICAgICAgZGF0YTogaW5wdXQuZGF0YSxcbiAgICAgICAgICAgIHBhcnNlZFR5cGU6IGdldFBhcnNlZFR5cGUoaW5wdXQuZGF0YSksXG4gICAgICAgICAgICBzY2hlbWFFcnJvck1hcDogdGhpcy5fZGVmLmVycm9yTWFwLFxuICAgICAgICAgICAgcGF0aDogaW5wdXQucGF0aCxcbiAgICAgICAgICAgIHBhcmVudDogaW5wdXQucGFyZW50XG4gICAgICAgIH07XG4gICAgfVxuICAgIF9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN0YXR1czogbmV3IFBhcnNlU3RhdHVzKCksXG4gICAgICAgICAgICBjdHg6IHtcbiAgICAgICAgICAgICAgICBjb21tb246IGlucHV0LnBhcmVudC5jb21tb24sXG4gICAgICAgICAgICAgICAgZGF0YTogaW5wdXQuZGF0YSxcbiAgICAgICAgICAgICAgICBwYXJzZWRUeXBlOiBnZXRQYXJzZWRUeXBlKGlucHV0LmRhdGEpLFxuICAgICAgICAgICAgICAgIHNjaGVtYUVycm9yTWFwOiB0aGlzLl9kZWYuZXJyb3JNYXAsXG4gICAgICAgICAgICAgICAgcGF0aDogaW5wdXQucGF0aCxcbiAgICAgICAgICAgICAgICBwYXJlbnQ6IGlucHV0LnBhcmVudFxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cbiAgICBfcGFyc2VTeW5jKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuX3BhcnNlKGlucHV0KTtcbiAgICAgICAgaWYgKGlzQXN5bmMocmVzdWx0KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU3luY2hyb25vdXMgcGFyc2UgZW5jb3VudGVyZWQgcHJvbWlzZS5cIik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgX3BhcnNlQXN5bmMoaW5wdXQpIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5fcGFyc2UoaW5wdXQpO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlc3VsdCk7XG4gICAgfVxuICAgIHBhcnNlKGRhdGEsIHBhcmFtcykge1xuICAgICAgICBjb25zdCByZXN1bHQgPSB0aGlzLnNhZmVQYXJzZShkYXRhLCBwYXJhbXMpO1xuICAgICAgICBpZiAocmVzdWx0LnN1Y2Nlc3MpIHJldHVybiByZXN1bHQuZGF0YTtcbiAgICAgICAgdGhyb3cgcmVzdWx0LmVycm9yO1xuICAgIH1cbiAgICBzYWZlUGFyc2UoZGF0YSwgcGFyYW1zKSB7XG4gICAgICAgIGNvbnN0IGN0eCA9IHtcbiAgICAgICAgICAgIGNvbW1vbjoge1xuICAgICAgICAgICAgICAgIGlzc3VlczogW10sXG4gICAgICAgICAgICAgICAgYXN5bmM6IHBhcmFtcz8uYXN5bmMgPz8gZmFsc2UsXG4gICAgICAgICAgICAgICAgY29udGV4dHVhbEVycm9yTWFwOiBwYXJhbXM/LmVycm9yTWFwXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcGF0aDogcGFyYW1zPy5wYXRoIHx8IFtdLFxuICAgICAgICAgICAgc2NoZW1hRXJyb3JNYXA6IHRoaXMuX2RlZi5lcnJvck1hcCxcbiAgICAgICAgICAgIHBhcmVudDogbnVsbCxcbiAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICBwYXJzZWRUeXBlOiBnZXRQYXJzZWRUeXBlKGRhdGEpXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuX3BhcnNlU3luYyh7XG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgcGF0aDogY3R4LnBhdGgsXG4gICAgICAgICAgICBwYXJlbnQ6IGN0eFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGhhbmRsZVJlc3VsdChjdHgsIHJlc3VsdCk7XG4gICAgfVxuICAgIFwifnZhbGlkYXRlXCIoZGF0YSkge1xuICAgICAgICBjb25zdCBjdHggPSB7XG4gICAgICAgICAgICBjb21tb246IHtcbiAgICAgICAgICAgICAgICBpc3N1ZXM6IFtdLFxuICAgICAgICAgICAgICAgIGFzeW5jOiAhIXRoaXNbXCJ+c3RhbmRhcmRcIl0uYXN5bmNcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBwYXRoOiBbXSxcbiAgICAgICAgICAgIHNjaGVtYUVycm9yTWFwOiB0aGlzLl9kZWYuZXJyb3JNYXAsXG4gICAgICAgICAgICBwYXJlbnQ6IG51bGwsXG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgcGFyc2VkVHlwZTogZ2V0UGFyc2VkVHlwZShkYXRhKVxuICAgICAgICB9O1xuICAgICAgICBpZiAoIXRoaXNbXCJ+c3RhbmRhcmRcIl0uYXN5bmMpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5fcGFyc2VTeW5jKHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgICAgICAgICAgcGF0aDogW10sXG4gICAgICAgICAgICAgICAgICAgIHBhcmVudDogY3R4XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlzVmFsaWQocmVzdWx0KSA/IHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHJlc3VsdC52YWx1ZVxuICAgICAgICAgICAgICAgIH0gOiB7XG4gICAgICAgICAgICAgICAgICAgIGlzc3VlczogY3R4LmNvbW1vbi5pc3N1ZXNcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgaWYgKGVycj8ubWVzc2FnZT8udG9Mb3dlckNhc2UoKT8uaW5jbHVkZXMoXCJlbmNvdW50ZXJlZFwiKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzW1wifnN0YW5kYXJkXCJdLmFzeW5jID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY3R4LmNvbW1vbiA9IHtcbiAgICAgICAgICAgICAgICAgICAgaXNzdWVzOiBbXSxcbiAgICAgICAgICAgICAgICAgICAgYXN5bmM6IHRydWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJzZUFzeW5jKHtcbiAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICBwYXRoOiBbXSxcbiAgICAgICAgICAgIHBhcmVudDogY3R4XG4gICAgICAgIH0pLnRoZW4oKHJlc3VsdCk9PmlzVmFsaWQocmVzdWx0KSA/IHtcbiAgICAgICAgICAgICAgICB2YWx1ZTogcmVzdWx0LnZhbHVlXG4gICAgICAgICAgICB9IDoge1xuICAgICAgICAgICAgICAgIGlzc3VlczogY3R4LmNvbW1vbi5pc3N1ZXNcbiAgICAgICAgICAgIH0pO1xuICAgIH1cbiAgICBhc3luYyBwYXJzZUFzeW5jKGRhdGEsIHBhcmFtcykge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnNhZmVQYXJzZUFzeW5jKGRhdGEsIHBhcmFtcyk7XG4gICAgICAgIGlmIChyZXN1bHQuc3VjY2VzcykgcmV0dXJuIHJlc3VsdC5kYXRhO1xuICAgICAgICB0aHJvdyByZXN1bHQuZXJyb3I7XG4gICAgfVxuICAgIGFzeW5jIHNhZmVQYXJzZUFzeW5jKGRhdGEsIHBhcmFtcykge1xuICAgICAgICBjb25zdCBjdHggPSB7XG4gICAgICAgICAgICBjb21tb246IHtcbiAgICAgICAgICAgICAgICBpc3N1ZXM6IFtdLFxuICAgICAgICAgICAgICAgIGNvbnRleHR1YWxFcnJvck1hcDogcGFyYW1zPy5lcnJvck1hcCxcbiAgICAgICAgICAgICAgICBhc3luYzogdHJ1ZVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHBhdGg6IHBhcmFtcz8ucGF0aCB8fCBbXSxcbiAgICAgICAgICAgIHNjaGVtYUVycm9yTWFwOiB0aGlzLl9kZWYuZXJyb3JNYXAsXG4gICAgICAgICAgICBwYXJlbnQ6IG51bGwsXG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgcGFyc2VkVHlwZTogZ2V0UGFyc2VkVHlwZShkYXRhKVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBtYXliZUFzeW5jUmVzdWx0ID0gdGhpcy5fcGFyc2Uoe1xuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgcGFyZW50OiBjdHhcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IChpc0FzeW5jKG1heWJlQXN5bmNSZXN1bHQpID8gbWF5YmVBc3luY1Jlc3VsdCA6IFByb21pc2UucmVzb2x2ZShtYXliZUFzeW5jUmVzdWx0KSk7XG4gICAgICAgIHJldHVybiBoYW5kbGVSZXN1bHQoY3R4LCByZXN1bHQpO1xuICAgIH1cbiAgICByZWZpbmUoY2hlY2ssIG1lc3NhZ2UpIHtcbiAgICAgICAgY29uc3QgZ2V0SXNzdWVQcm9wZXJ0aWVzID0gKHZhbCk9PntcbiAgICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSA9PT0gXCJzdHJpbmdcIiB8fCB0eXBlb2YgbWVzc2FnZSA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgbWVzc2FnZSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2UodmFsKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB0aGlzLl9yZWZpbmVtZW50KCh2YWwsIGN0eCk9PntcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGNoZWNrKHZhbCk7XG4gICAgICAgICAgICBjb25zdCBzZXRFcnJvciA9ICgpPT5jdHguYWRkSXNzdWUoe1xuICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuY3VzdG9tLFxuICAgICAgICAgICAgICAgICAgICAuLi5nZXRJc3N1ZVByb3BlcnRpZXModmFsKVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBQcm9taXNlICE9PSBcInVuZGVmaW5lZFwiICYmIHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0LnRoZW4oKGRhdGEpPT57XG4gICAgICAgICAgICAgICAgICAgIGlmICghZGF0YSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0RXJyb3IoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXJlc3VsdCkge1xuICAgICAgICAgICAgICAgIHNldEVycm9yKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJlZmluZW1lbnQoY2hlY2ssIHJlZmluZW1lbnREYXRhKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9yZWZpbmVtZW50KCh2YWwsIGN0eCk9PntcbiAgICAgICAgICAgIGlmICghY2hlY2sodmFsKSkge1xuICAgICAgICAgICAgICAgIGN0eC5hZGRJc3N1ZSh0eXBlb2YgcmVmaW5lbWVudERhdGEgPT09IFwiZnVuY3Rpb25cIiA/IHJlZmluZW1lbnREYXRhKHZhbCwgY3R4KSA6IHJlZmluZW1lbnREYXRhKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgX3JlZmluZW1lbnQocmVmaW5lbWVudCkge1xuICAgICAgICByZXR1cm4gbmV3IFpvZEVmZmVjdHMoe1xuICAgICAgICAgICAgc2NoZW1hOiB0aGlzLFxuICAgICAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RFZmZlY3RzLFxuICAgICAgICAgICAgZWZmZWN0OiB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJyZWZpbmVtZW50XCIsXG4gICAgICAgICAgICAgICAgcmVmaW5lbWVudFxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgc3VwZXJSZWZpbmUocmVmaW5lbWVudCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcmVmaW5lbWVudChyZWZpbmVtZW50KTtcbiAgICB9XG4gICAgY29uc3RydWN0b3IoZGVmKXtcbiAgICAgICAgLyoqIEFsaWFzIG9mIHNhZmVQYXJzZUFzeW5jICovIHRoaXMuc3BhID0gdGhpcy5zYWZlUGFyc2VBc3luYztcbiAgICAgICAgdGhpcy5fZGVmID0gZGVmO1xuICAgICAgICB0aGlzLnBhcnNlID0gdGhpcy5wYXJzZS5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLnNhZmVQYXJzZSA9IHRoaXMuc2FmZVBhcnNlLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMucGFyc2VBc3luYyA9IHRoaXMucGFyc2VBc3luYy5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLnNhZmVQYXJzZUFzeW5jID0gdGhpcy5zYWZlUGFyc2VBc3luYy5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLnNwYSA9IHRoaXMuc3BhLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMucmVmaW5lID0gdGhpcy5yZWZpbmUuYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5yZWZpbmVtZW50ID0gdGhpcy5yZWZpbmVtZW50LmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMuc3VwZXJSZWZpbmUgPSB0aGlzLnN1cGVyUmVmaW5lLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMub3B0aW9uYWwgPSB0aGlzLm9wdGlvbmFsLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMubnVsbGFibGUgPSB0aGlzLm51bGxhYmxlLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMubnVsbGlzaCA9IHRoaXMubnVsbGlzaC5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLmFycmF5ID0gdGhpcy5hcnJheS5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLnByb21pc2UgPSB0aGlzLnByb21pc2UuYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5vciA9IHRoaXMub3IuYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5hbmQgPSB0aGlzLmFuZC5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLnRyYW5zZm9ybSA9IHRoaXMudHJhbnNmb3JtLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMuYnJhbmQgPSB0aGlzLmJyYW5kLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMuZGVmYXVsdCA9IHRoaXMuZGVmYXVsdC5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLmNhdGNoID0gdGhpcy5jYXRjaC5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLmRlc2NyaWJlID0gdGhpcy5kZXNjcmliZS5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLnBpcGUgPSB0aGlzLnBpcGUuYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5yZWFkb25seSA9IHRoaXMucmVhZG9ubHkuYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5pc051bGxhYmxlID0gdGhpcy5pc051bGxhYmxlLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMuaXNPcHRpb25hbCA9IHRoaXMuaXNPcHRpb25hbC5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzW1wifnN0YW5kYXJkXCJdID0ge1xuICAgICAgICAgICAgdmVyc2lvbjogMSxcbiAgICAgICAgICAgIHZlbmRvcjogXCJ6b2RcIixcbiAgICAgICAgICAgIHZhbGlkYXRlOiAoZGF0YSk9PnRoaXNbXCJ+dmFsaWRhdGVcIl0oZGF0YSlcbiAgICAgICAgfTtcbiAgICB9XG4gICAgb3B0aW9uYWwoKSB7XG4gICAgICAgIHJldHVybiBab2RPcHRpb25hbC5jcmVhdGUodGhpcywgdGhpcy5fZGVmKTtcbiAgICB9XG4gICAgbnVsbGFibGUoKSB7XG4gICAgICAgIHJldHVybiBab2ROdWxsYWJsZS5jcmVhdGUodGhpcywgdGhpcy5fZGVmKTtcbiAgICB9XG4gICAgbnVsbGlzaCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubnVsbGFibGUoKS5vcHRpb25hbCgpO1xuICAgIH1cbiAgICBhcnJheSgpIHtcbiAgICAgICAgcmV0dXJuIFpvZEFycmF5LmNyZWF0ZSh0aGlzKTtcbiAgICB9XG4gICAgcHJvbWlzZSgpIHtcbiAgICAgICAgcmV0dXJuIFpvZFByb21pc2UuY3JlYXRlKHRoaXMsIHRoaXMuX2RlZik7XG4gICAgfVxuICAgIG9yKG9wdGlvbikge1xuICAgICAgICByZXR1cm4gWm9kVW5pb24uY3JlYXRlKFtcbiAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICBvcHRpb25cbiAgICAgICAgXSwgdGhpcy5fZGVmKTtcbiAgICB9XG4gICAgYW5kKGluY29taW5nKSB7XG4gICAgICAgIHJldHVybiBab2RJbnRlcnNlY3Rpb24uY3JlYXRlKHRoaXMsIGluY29taW5nLCB0aGlzLl9kZWYpO1xuICAgIH1cbiAgICB0cmFuc2Zvcm0odHJhbnNmb3JtKSB7XG4gICAgICAgIHJldHVybiBuZXcgWm9kRWZmZWN0cyh7XG4gICAgICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHRoaXMuX2RlZiksXG4gICAgICAgICAgICBzY2hlbWE6IHRoaXMsXG4gICAgICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEVmZmVjdHMsXG4gICAgICAgICAgICBlZmZlY3Q6IHtcbiAgICAgICAgICAgICAgICB0eXBlOiBcInRyYW5zZm9ybVwiLFxuICAgICAgICAgICAgICAgIHRyYW5zZm9ybVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGVmYXVsdChkZWYpIHtcbiAgICAgICAgY29uc3QgZGVmYXVsdFZhbHVlRnVuYyA9IHR5cGVvZiBkZWYgPT09IFwiZnVuY3Rpb25cIiA/IGRlZiA6ICgpPT5kZWY7XG4gICAgICAgIHJldHVybiBuZXcgWm9kRGVmYXVsdCh7XG4gICAgICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHRoaXMuX2RlZiksXG4gICAgICAgICAgICBpbm5lclR5cGU6IHRoaXMsXG4gICAgICAgICAgICBkZWZhdWx0VmFsdWU6IGRlZmF1bHRWYWx1ZUZ1bmMsXG4gICAgICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZERlZmF1bHRcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGJyYW5kKCkge1xuICAgICAgICByZXR1cm4gbmV3IFpvZEJyYW5kZWQoe1xuICAgICAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RCcmFuZGVkLFxuICAgICAgICAgICAgdHlwZTogdGhpcyxcbiAgICAgICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXModGhpcy5fZGVmKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgY2F0Y2goZGVmKSB7XG4gICAgICAgIGNvbnN0IGNhdGNoVmFsdWVGdW5jID0gdHlwZW9mIGRlZiA9PT0gXCJmdW5jdGlvblwiID8gZGVmIDogKCk9PmRlZjtcbiAgICAgICAgcmV0dXJuIG5ldyBab2RDYXRjaCh7XG4gICAgICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHRoaXMuX2RlZiksXG4gICAgICAgICAgICBpbm5lclR5cGU6IHRoaXMsXG4gICAgICAgICAgICBjYXRjaFZhbHVlOiBjYXRjaFZhbHVlRnVuYyxcbiAgICAgICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kQ2F0Y2hcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRlc2NyaWJlKGRlc2NyaXB0aW9uKSB7XG4gICAgICAgIGNvbnN0IFRoaXMgPSB0aGlzLmNvbnN0cnVjdG9yO1xuICAgICAgICByZXR1cm4gbmV3IFRoaXMoe1xuICAgICAgICAgICAgLi4udGhpcy5fZGVmLFxuICAgICAgICAgICAgZGVzY3JpcHRpb25cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHBpcGUodGFyZ2V0KSB7XG4gICAgICAgIHJldHVybiBab2RQaXBlbGluZS5jcmVhdGUodGhpcywgdGFyZ2V0KTtcbiAgICB9XG4gICAgcmVhZG9ubHkoKSB7XG4gICAgICAgIHJldHVybiBab2RSZWFkb25seS5jcmVhdGUodGhpcyk7XG4gICAgfVxuICAgIGlzT3B0aW9uYWwoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNhZmVQYXJzZSh1bmRlZmluZWQpLnN1Y2Nlc3M7XG4gICAgfVxuICAgIGlzTnVsbGFibGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNhZmVQYXJzZShudWxsKS5zdWNjZXNzO1xuICAgIH1cbn1cbmNvbnN0IGN1aWRSZWdleCA9IC9eY1teXFxzLV17OCx9JC9pO1xuY29uc3QgY3VpZDJSZWdleCA9IC9eWzAtOWEtel0rJC87XG5jb25zdCB1bGlkUmVnZXggPSAvXlswLTlBLUhKS01OUC1UVi1aXXsyNn0kL2k7XG4vLyBjb25zdCB1dWlkUmVnZXggPVxuLy8gICAvXihbYS1mMC05XXs4fS1bYS1mMC05XXs0fS1bMS01XVthLWYwLTldezN9LVthLWYwLTldezR9LVthLWYwLTldezEyfXwwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDApJC9pO1xuY29uc3QgdXVpZFJlZ2V4ID0gL15bMC05YS1mQS1GXXs4fVxcYi1bMC05YS1mQS1GXXs0fVxcYi1bMC05YS1mQS1GXXs0fVxcYi1bMC05YS1mQS1GXXs0fVxcYi1bMC05YS1mQS1GXXsxMn0kL2k7XG5jb25zdCBuYW5vaWRSZWdleCA9IC9eW2EtejAtOV8tXXsyMX0kL2k7XG5jb25zdCBqd3RSZWdleCA9IC9eW0EtWmEtejAtOS1fXStcXC5bQS1aYS16MC05LV9dK1xcLltBLVphLXowLTktX10qJC87XG5jb25zdCBkdXJhdGlvblJlZ2V4ID0gL15bLStdP1AoPyEkKSg/Oig/OlstK10/XFxkK1kpfCg/OlstK10/XFxkK1suLF1cXGQrWSQpKT8oPzooPzpbLStdP1xcZCtNKXwoPzpbLStdP1xcZCtbLixdXFxkK00kKSk/KD86KD86Wy0rXT9cXGQrVyl8KD86Wy0rXT9cXGQrWy4sXVxcZCtXJCkpPyg/Oig/OlstK10/XFxkK0QpfCg/OlstK10/XFxkK1suLF1cXGQrRCQpKT8oPzpUKD89W1xcZCstXSkoPzooPzpbLStdP1xcZCtIKXwoPzpbLStdP1xcZCtbLixdXFxkK0gkKSk/KD86KD86Wy0rXT9cXGQrTSl8KD86Wy0rXT9cXGQrWy4sXVxcZCtNJCkpPyg/OlstK10/XFxkKyg/OlsuLF1cXGQrKT9TKT8pPz8kLztcbi8vIGZyb20gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzQ2MTgxLzE1NTAxNTVcbi8vIG9sZCB2ZXJzaW9uOiB0b28gc2xvdywgZGlkbid0IHN1cHBvcnQgdW5pY29kZVxuLy8gY29uc3QgZW1haWxSZWdleCA9IC9eKCgoW2Etel18XFxkfFshI1xcJCUmJ1xcKlxcK1xcLVxcLz1cXD9cXF5fYHtcXHx9fl18W1xcdTAwQTAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRl0pKyhcXC4oW2Etel18XFxkfFshI1xcJCUmJ1xcKlxcK1xcLVxcLz1cXD9cXF5fYHtcXHx9fl18W1xcdTAwQTAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRl0pKykqKXwoKFxceDIyKSgoKChcXHgyMHxcXHgwOSkqKFxceDBkXFx4MGEpKT8oXFx4MjB8XFx4MDkpKyk/KChbXFx4MDEtXFx4MDhcXHgwYlxceDBjXFx4MGUtXFx4MWZcXHg3Zl18XFx4MjF8W1xceDIzLVxceDViXXxbXFx4NWQtXFx4N2VdfFtcXHUwMEEwLVxcdUQ3RkZcXHVGOTAwLVxcdUZEQ0ZcXHVGREYwLVxcdUZGRUZdKXwoXFxcXChbXFx4MDEtXFx4MDlcXHgwYlxceDBjXFx4MGQtXFx4N2ZdfFtcXHUwMEEwLVxcdUQ3RkZcXHVGOTAwLVxcdUZEQ0ZcXHVGREYwLVxcdUZGRUZdKSkpKSooKChcXHgyMHxcXHgwOSkqKFxceDBkXFx4MGEpKT8oXFx4MjB8XFx4MDkpKyk/KFxceDIyKSkpQCgoKFthLXpdfFxcZHxbXFx1MDBBMC1cXHVEN0ZGXFx1RjkwMC1cXHVGRENGXFx1RkRGMC1cXHVGRkVGXSl8KChbYS16XXxcXGR8W1xcdTAwQTAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRl0pKFthLXpdfFxcZHwtfFxcLnxffH58W1xcdTAwQTAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRl0pKihbYS16XXxcXGR8W1xcdTAwQTAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRl0pKSlcXC4pKygoW2Etel18W1xcdTAwQTAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRl0pfCgoW2Etel18W1xcdTAwQTAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRl0pKFthLXpdfFxcZHwtfFxcLnxffH58W1xcdTAwQTAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRl0pKihbYS16XXxbXFx1MDBBMC1cXHVEN0ZGXFx1RjkwMC1cXHVGRENGXFx1RkRGMC1cXHVGRkVGXSkpKSQvaTtcbi8vb2xkIGVtYWlsIHJlZ2V4XG4vLyBjb25zdCBlbWFpbFJlZ2V4ID0gL14oKFtePD4oKVtcXF0uLDs6XFxzQFwiXSsoXFwuW148PigpW1xcXS4sOzpcXHNAXCJdKykqKXwoXCIuK1wiKSlAKCg/IS0pKFtePD4oKVtcXF0uLDs6XFxzQFwiXStcXC4pK1tePD4oKVtcXF0uLDs6XFxzQFwiXXsxLH0pW14tPD4oKVtcXF0uLDs6XFxzQFwiXSQvaTtcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuLy8gY29uc3QgZW1haWxSZWdleCA9XG4vLyAgIC9eKChbXjw+KClbXFxdXFxcXC4sOzpcXHNAXFxcIl0rKFxcLltePD4oKVtcXF1cXFxcLiw7Olxcc0BcXFwiXSspKil8KFxcXCIuK1xcXCIpKUAoKFxcWygoKDI1WzAtNV0pfCgyWzAtNF1bMC05XSl8KDFbMC05XXsyfSl8KFswLTldezEsMn0pKVxcLil7M30oKDI1WzAtNV0pfCgyWzAtNF1bMC05XSl8KDFbMC05XXsyfSl8KFswLTldezEsMn0pKVxcXSl8KFxcW0lQdjY6KChbYS1mMC05XXsxLDR9Oil7N318OjooW2EtZjAtOV17MSw0fTopezAsNn18KFthLWYwLTldezEsNH06KXsxfTooW2EtZjAtOV17MSw0fTopezAsNX18KFthLWYwLTldezEsNH06KXsyfTooW2EtZjAtOV17MSw0fTopezAsNH18KFthLWYwLTldezEsNH06KXszfTooW2EtZjAtOV17MSw0fTopezAsM318KFthLWYwLTldezEsNH06KXs0fTooW2EtZjAtOV17MSw0fTopezAsMn18KFthLWYwLTldezEsNH06KXs1fTooW2EtZjAtOV17MSw0fTopezAsMX0pKFthLWYwLTldezEsNH18KCgoMjVbMC01XSl8KDJbMC00XVswLTldKXwoMVswLTldezJ9KXwoWzAtOV17MSwyfSkpXFwuKXszfSgoMjVbMC01XSl8KDJbMC00XVswLTldKXwoMVswLTldezJ9KXwoWzAtOV17MSwyfSkpKVxcXSl8KFtBLVphLXowLTldKFtBLVphLXowLTktXSpbQS1aYS16MC05XSkqKFxcLltBLVphLXpdezIsfSkrKSkkLztcbi8vIGNvbnN0IGVtYWlsUmVnZXggPVxuLy8gICAvXlthLXpBLVowLTlcXC5cXCFcXCNcXCRcXCVcXCZcXCdcXCpcXCtcXC9cXD1cXD9cXF5cXF9cXGBcXHtcXHxcXH1cXH5cXC1dK0BbYS16QS1aMC05XSg/OlthLXpBLVowLTktXXswLDYxfVthLXpBLVowLTldKT8oPzpcXC5bYS16QS1aMC05XSg/OlthLXpBLVowLTktXXswLDYxfVthLXpBLVowLTldKT8pKiQvO1xuLy8gY29uc3QgZW1haWxSZWdleCA9XG4vLyAgIC9eKD86W2EtejAtOSEjJCUmJyorLz0/Xl9ge3x9fi1dKyg/OlxcLlthLXowLTkhIyQlJicqKy89P15fYHt8fX4tXSspKnxcIig/OltcXHgwMS1cXHgwOFxceDBiXFx4MGNcXHgwZS1cXHgxZlxceDIxXFx4MjMtXFx4NWJcXHg1ZC1cXHg3Zl18XFxcXFtcXHgwMS1cXHgwOVxceDBiXFx4MGNcXHgwZS1cXHg3Zl0pKlwiKUAoPzooPzpbYS16MC05XSg/OlthLXowLTktXSpbYS16MC05XSk/XFwuKStbYS16MC05XSg/OlthLXowLTktXSpbYS16MC05XSk/fFxcWyg/Oig/OjI1WzAtNV18MlswLTRdWzAtOV18WzAxXT9bMC05XVswLTldPylcXC4pezN9KD86MjVbMC01XXwyWzAtNF1bMC05XXxbMDFdP1swLTldWzAtOV0/fFthLXowLTktXSpbYS16MC05XTooPzpbXFx4MDEtXFx4MDhcXHgwYlxceDBjXFx4MGUtXFx4MWZcXHgyMS1cXHg1YVxceDUzLVxceDdmXXxcXFxcW1xceDAxLVxceDA5XFx4MGJcXHgwY1xceDBlLVxceDdmXSkrKVxcXSkkL2k7XG5jb25zdCBlbWFpbFJlZ2V4ID0gL14oPyFcXC4pKD8hLipcXC5cXC4pKFtBLVowLTlfJytcXC1cXC5dKilbQS1aMC05XystXUAoW0EtWjAtOV1bQS1aMC05XFwtXSpcXC4pK1tBLVpdezIsfSQvaTtcbi8vIGNvbnN0IGVtYWlsUmVnZXggPVxuLy8gICAvXlthLXowLTkuISMkJSZcdTIwMTkqKy89P15fYHt8fX4tXStAW2EtejAtOS1dKyg/OlxcLlthLXowLTlcXC1dKykqJC9pO1xuLy8gZnJvbSBodHRwczovL3RoZWtldmluc2NvdHQuY29tL2Vtb2ppcy1pbi1qYXZhc2NyaXB0LyN3cml0aW5nLWEtcmVndWxhci1leHByZXNzaW9uXG5jb25zdCBfZW1vamlSZWdleCA9IGBeKFxcXFxwe0V4dGVuZGVkX1BpY3RvZ3JhcGhpY318XFxcXHB7RW1vamlfQ29tcG9uZW50fSkrJGA7XG5sZXQgZW1vamlSZWdleDtcbi8vIGZhc3Rlciwgc2ltcGxlciwgc2FmZXJcbmNvbnN0IGlwdjRSZWdleCA9IC9eKD86KD86MjVbMC01XXwyWzAtNF1bMC05XXwxWzAtOV1bMC05XXxbMS05XVswLTldfFswLTldKVxcLil7M30oPzoyNVswLTVdfDJbMC00XVswLTldfDFbMC05XVswLTldfFsxLTldWzAtOV18WzAtOV0pJC87XG5jb25zdCBpcHY0Q2lkclJlZ2V4ID0gL14oPzooPzoyNVswLTVdfDJbMC00XVswLTldfDFbMC05XVswLTldfFsxLTldWzAtOV18WzAtOV0pXFwuKXszfSg/OjI1WzAtNV18MlswLTRdWzAtOV18MVswLTldWzAtOV18WzEtOV1bMC05XXxbMC05XSlcXC8oM1swLTJdfFsxMl0/WzAtOV0pJC87XG4vLyBjb25zdCBpcHY2UmVnZXggPVxuLy8gL14oKFthLWYwLTldezEsNH06KXs3fXw6OihbYS1mMC05XXsxLDR9Oil7MCw2fXwoW2EtZjAtOV17MSw0fTopezF9OihbYS1mMC05XXsxLDR9Oil7MCw1fXwoW2EtZjAtOV17MSw0fTopezJ9OihbYS1mMC05XXsxLDR9Oil7MCw0fXwoW2EtZjAtOV17MSw0fTopezN9OihbYS1mMC05XXsxLDR9Oil7MCwzfXwoW2EtZjAtOV17MSw0fTopezR9OihbYS1mMC05XXsxLDR9Oil7MCwyfXwoW2EtZjAtOV17MSw0fTopezV9OihbYS1mMC05XXsxLDR9Oil7MCwxfSkoW2EtZjAtOV17MSw0fXwoKCgyNVswLTVdKXwoMlswLTRdWzAtOV0pfCgxWzAtOV17Mn0pfChbMC05XXsxLDJ9KSlcXC4pezN9KCgyNVswLTVdKXwoMlswLTRdWzAtOV0pfCgxWzAtOV17Mn0pfChbMC05XXsxLDJ9KSkpJC87XG5jb25zdCBpcHY2UmVnZXggPSAvXigoWzAtOWEtZkEtRl17MSw0fTopezcsN31bMC05YS1mQS1GXXsxLDR9fChbMC05YS1mQS1GXXsxLDR9Oil7MSw3fTp8KFswLTlhLWZBLUZdezEsNH06KXsxLDZ9OlswLTlhLWZBLUZdezEsNH18KFswLTlhLWZBLUZdezEsNH06KXsxLDV9KDpbMC05YS1mQS1GXXsxLDR9KXsxLDJ9fChbMC05YS1mQS1GXXsxLDR9Oil7MSw0fSg6WzAtOWEtZkEtRl17MSw0fSl7MSwzfXwoWzAtOWEtZkEtRl17MSw0fTopezEsM30oOlswLTlhLWZBLUZdezEsNH0pezEsNH18KFswLTlhLWZBLUZdezEsNH06KXsxLDJ9KDpbMC05YS1mQS1GXXsxLDR9KXsxLDV9fFswLTlhLWZBLUZdezEsNH06KCg6WzAtOWEtZkEtRl17MSw0fSl7MSw2fSl8OigoOlswLTlhLWZBLUZdezEsNH0pezEsN318Oil8ZmU4MDooOlswLTlhLWZBLUZdezAsNH0pezAsNH0lWzAtOWEtekEtWl17MSx9fDo6KGZmZmYoOjB7MSw0fSl7MCwxfTopezAsMX0oKDI1WzAtNV18KDJbMC00XXwxezAsMX1bMC05XSl7MCwxfVswLTldKVxcLil7MywzfSgyNVswLTVdfCgyWzAtNF18MXswLDF9WzAtOV0pezAsMX1bMC05XSl8KFswLTlhLWZBLUZdezEsNH06KXsxLDR9OigoMjVbMC01XXwoMlswLTRdfDF7MCwxfVswLTldKXswLDF9WzAtOV0pXFwuKXszLDN9KDI1WzAtNV18KDJbMC00XXwxezAsMX1bMC05XSl7MCwxfVswLTldKSkkLztcbmNvbnN0IGlwdjZDaWRyUmVnZXggPSAvXigoWzAtOWEtZkEtRl17MSw0fTopezcsN31bMC05YS1mQS1GXXsxLDR9fChbMC05YS1mQS1GXXsxLDR9Oil7MSw3fTp8KFswLTlhLWZBLUZdezEsNH06KXsxLDZ9OlswLTlhLWZBLUZdezEsNH18KFswLTlhLWZBLUZdezEsNH06KXsxLDV9KDpbMC05YS1mQS1GXXsxLDR9KXsxLDJ9fChbMC05YS1mQS1GXXsxLDR9Oil7MSw0fSg6WzAtOWEtZkEtRl17MSw0fSl7MSwzfXwoWzAtOWEtZkEtRl17MSw0fTopezEsM30oOlswLTlhLWZBLUZdezEsNH0pezEsNH18KFswLTlhLWZBLUZdezEsNH06KXsxLDJ9KDpbMC05YS1mQS1GXXsxLDR9KXsxLDV9fFswLTlhLWZBLUZdezEsNH06KCg6WzAtOWEtZkEtRl17MSw0fSl7MSw2fSl8OigoOlswLTlhLWZBLUZdezEsNH0pezEsN318Oil8ZmU4MDooOlswLTlhLWZBLUZdezAsNH0pezAsNH0lWzAtOWEtekEtWl17MSx9fDo6KGZmZmYoOjB7MSw0fSl7MCwxfTopezAsMX0oKDI1WzAtNV18KDJbMC00XXwxezAsMX1bMC05XSl7MCwxfVswLTldKVxcLil7MywzfSgyNVswLTVdfCgyWzAtNF18MXswLDF9WzAtOV0pezAsMX1bMC05XSl8KFswLTlhLWZBLUZdezEsNH06KXsxLDR9OigoMjVbMC01XXwoMlswLTRdfDF7MCwxfVswLTldKXswLDF9WzAtOV0pXFwuKXszLDN9KDI1WzAtNV18KDJbMC00XXwxezAsMX1bMC05XSl7MCwxfVswLTldKSlcXC8oMTJbMC04XXwxWzAxXVswLTldfFsxLTldP1swLTldKSQvO1xuLy8gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNzg2MDM5Mi9kZXRlcm1pbmUtaWYtc3RyaW5nLWlzLWluLWJhc2U2NC11c2luZy1qYXZhc2NyaXB0XG5jb25zdCBiYXNlNjRSZWdleCA9IC9eKFswLTlhLXpBLVorL117NH0pKigoWzAtOWEtekEtWisvXXsyfT09KXwoWzAtOWEtekEtWisvXXszfT0pKT8kLztcbi8vIGh0dHBzOi8vYmFzZTY0Lmd1cnUvc3RhbmRhcmRzL2Jhc2U2NHVybFxuY29uc3QgYmFzZTY0dXJsUmVnZXggPSAvXihbMC05YS16QS1aLV9dezR9KSooKFswLTlhLXpBLVotX117Mn0oPT0pPyl8KFswLTlhLXpBLVotX117M30oPSk/KSk/JC87XG4vLyBzaW1wbGVcbi8vIGNvbnN0IGRhdGVSZWdleFNvdXJjZSA9IGBcXFxcZHs0fS1cXFxcZHsyfS1cXFxcZHsyfWA7XG4vLyBubyBsZWFwIHllYXIgdmFsaWRhdGlvblxuLy8gY29uc3QgZGF0ZVJlZ2V4U291cmNlID0gYFxcXFxkezR9LSgoMFsxMzU3OF18MTB8MTIpLTMxfCgwWzEzLTldfDFbMC0yXSktMzB8KDBbMS05XXwxWzAtMl0pLSgwWzEtOV18MVxcXFxkfDJcXFxcZCkpYDtcbi8vIHdpdGggbGVhcCB5ZWFyIHZhbGlkYXRpb25cbmNvbnN0IGRhdGVSZWdleFNvdXJjZSA9IGAoKFxcXFxkXFxcXGRbMjQ2OF1bMDQ4XXxcXFxcZFxcXFxkWzEzNTc5XVsyNl18XFxcXGRcXFxcZDBbNDhdfFswMjQ2OF1bMDQ4XTAwfFsxMzU3OV1bMjZdMDApLTAyLTI5fFxcXFxkezR9LSgoMFsxMzU3OF18MVswMl0pLSgwWzEtOV18WzEyXVxcXFxkfDNbMDFdKXwoMFs0NjldfDExKS0oMFsxLTldfFsxMl1cXFxcZHwzMCl8KDAyKS0oMFsxLTldfDFcXFxcZHwyWzAtOF0pKSlgO1xuY29uc3QgZGF0ZVJlZ2V4ID0gbmV3IFJlZ0V4cChgXiR7ZGF0ZVJlZ2V4U291cmNlfSRgKTtcbmZ1bmN0aW9uIHRpbWVSZWdleFNvdXJjZShhcmdzKSB7XG4gICAgbGV0IHNlY29uZHNSZWdleFNvdXJjZSA9IGBbMC01XVxcXFxkYDtcbiAgICBpZiAoYXJncy5wcmVjaXNpb24pIHtcbiAgICAgICAgc2Vjb25kc1JlZ2V4U291cmNlID0gYCR7c2Vjb25kc1JlZ2V4U291cmNlfVxcXFwuXFxcXGR7JHthcmdzLnByZWNpc2lvbn19YDtcbiAgICB9IGVsc2UgaWYgKGFyZ3MucHJlY2lzaW9uID09IG51bGwpIHtcbiAgICAgICAgc2Vjb25kc1JlZ2V4U291cmNlID0gYCR7c2Vjb25kc1JlZ2V4U291cmNlfShcXFxcLlxcXFxkKyk/YDtcbiAgICB9XG4gICAgY29uc3Qgc2Vjb25kc1F1YW50aWZpZXIgPSBhcmdzLnByZWNpc2lvbiA/IFwiK1wiIDogXCI/XCI7IC8vIHJlcXVpcmUgc2Vjb25kcyBpZiBwcmVjaXNpb24gaXMgbm9uemVyb1xuICAgIHJldHVybiBgKFswMV1cXFxcZHwyWzAtM10pOlswLTVdXFxcXGQoOiR7c2Vjb25kc1JlZ2V4U291cmNlfSkke3NlY29uZHNRdWFudGlmaWVyfWA7XG59XG5mdW5jdGlvbiB0aW1lUmVnZXgoYXJncykge1xuICAgIHJldHVybiBuZXcgUmVnRXhwKGBeJHt0aW1lUmVnZXhTb3VyY2UoYXJncyl9JGApO1xufVxuLy8gQWRhcHRlZCBmcm9tIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8zMTQzMjMxXG5leHBvcnQgZnVuY3Rpb24gZGF0ZXRpbWVSZWdleChhcmdzKSB7XG4gICAgbGV0IHJlZ2V4ID0gYCR7ZGF0ZVJlZ2V4U291cmNlfVQke3RpbWVSZWdleFNvdXJjZShhcmdzKX1gO1xuICAgIGNvbnN0IG9wdHMgPSBbXTtcbiAgICBvcHRzLnB1c2goYXJncy5sb2NhbCA/IGBaP2AgOiBgWmApO1xuICAgIGlmIChhcmdzLm9mZnNldCkgb3B0cy5wdXNoKGAoWystXVxcXFxkezJ9Oj9cXFxcZHsyfSlgKTtcbiAgICByZWdleCA9IGAke3JlZ2V4fSgke29wdHMuam9pbihcInxcIil9KWA7XG4gICAgcmV0dXJuIG5ldyBSZWdFeHAoYF4ke3JlZ2V4fSRgKTtcbn1cbmZ1bmN0aW9uIGlzVmFsaWRJUChpcCwgdmVyc2lvbikge1xuICAgIGlmICgodmVyc2lvbiA9PT0gXCJ2NFwiIHx8ICF2ZXJzaW9uKSAmJiBpcHY0UmVnZXgudGVzdChpcCkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmICgodmVyc2lvbiA9PT0gXCJ2NlwiIHx8ICF2ZXJzaW9uKSAmJiBpcHY2UmVnZXgudGVzdChpcCkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cbmZ1bmN0aW9uIGlzVmFsaWRKV1Qoand0LCBhbGcpIHtcbiAgICBpZiAoIWp3dFJlZ2V4LnRlc3Qoand0KSkgcmV0dXJuIGZhbHNlO1xuICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IFtoZWFkZXJdID0gand0LnNwbGl0KFwiLlwiKTtcbiAgICAgICAgaWYgKCFoZWFkZXIpIHJldHVybiBmYWxzZTtcbiAgICAgICAgLy8gQ29udmVydCBiYXNlNjR1cmwgdG8gYmFzZTY0XG4gICAgICAgIGNvbnN0IGJhc2U2NCA9IGhlYWRlci5yZXBsYWNlKC8tL2csIFwiK1wiKS5yZXBsYWNlKC9fL2csIFwiL1wiKS5wYWRFbmQoaGVhZGVyLmxlbmd0aCArICg0IC0gaGVhZGVyLmxlbmd0aCAlIDQpICUgNCwgXCI9XCIpO1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIGNvbnN0IGRlY29kZWQgPSBKU09OLnBhcnNlKGF0b2IoYmFzZTY0KSk7XG4gICAgICAgIGlmICh0eXBlb2YgZGVjb2RlZCAhPT0gXCJvYmplY3RcIiB8fCBkZWNvZGVkID09PSBudWxsKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIGlmIChcInR5cFwiIGluIGRlY29kZWQgJiYgZGVjb2RlZD8udHlwICE9PSBcIkpXVFwiKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIGlmICghZGVjb2RlZC5hbGcpIHJldHVybiBmYWxzZTtcbiAgICAgICAgaWYgKGFsZyAmJiBkZWNvZGVkLmFsZyAhPT0gYWxnKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGlzVmFsaWRDaWRyKGlwLCB2ZXJzaW9uKSB7XG4gICAgaWYgKCh2ZXJzaW9uID09PSBcInY0XCIgfHwgIXZlcnNpb24pICYmIGlwdjRDaWRyUmVnZXgudGVzdChpcCkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmICgodmVyc2lvbiA9PT0gXCJ2NlwiIHx8ICF2ZXJzaW9uKSAmJiBpcHY2Q2lkclJlZ2V4LnRlc3QoaXApKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5leHBvcnQgY2xhc3MgWm9kU3RyaW5nIGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGlmICh0aGlzLl9kZWYuY29lcmNlKSB7XG4gICAgICAgICAgICBpbnB1dC5kYXRhID0gU3RyaW5nKGlucHV0LmRhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHBhcnNlZFR5cGUgPSB0aGlzLl9nZXRUeXBlKGlucHV0KTtcbiAgICAgICAgaWYgKHBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUuc3RyaW5nKSB7XG4gICAgICAgICAgICBjb25zdCBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7XG4gICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLnN0cmluZyxcbiAgICAgICAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc3RhdHVzID0gbmV3IFBhcnNlU3RhdHVzKCk7XG4gICAgICAgIGxldCBjdHggPSB1bmRlZmluZWQ7XG4gICAgICAgIGZvciAoY29uc3QgY2hlY2sgb2YgdGhpcy5fZGVmLmNoZWNrcyl7XG4gICAgICAgICAgICBpZiAoY2hlY2sua2luZCA9PT0gXCJtaW5cIikge1xuICAgICAgICAgICAgICAgIGlmIChpbnB1dC5kYXRhLmxlbmd0aCA8IGNoZWNrLnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS50b29fc21hbGwsXG4gICAgICAgICAgICAgICAgICAgICAgICBtaW5pbXVtOiBjaGVjay52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBleGFjdDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwibWF4XCIpIHtcbiAgICAgICAgICAgICAgICBpZiAoaW5wdXQuZGF0YS5sZW5ndGggPiBjaGVjay52YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX2JpZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1heGltdW06IGNoZWNrLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGluY2x1c2l2ZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4YWN0OiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJsZW5ndGhcIikge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRvb0JpZyA9IGlucHV0LmRhdGEubGVuZ3RoID4gY2hlY2sudmFsdWU7XG4gICAgICAgICAgICAgICAgY29uc3QgdG9vU21hbGwgPSBpbnB1dC5kYXRhLmxlbmd0aCA8IGNoZWNrLnZhbHVlO1xuICAgICAgICAgICAgICAgIGlmICh0b29CaWcgfHwgdG9vU21hbGwpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0b29CaWcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS50b29fYmlnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heGltdW06IGNoZWNrLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4YWN0OiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRvb1NtYWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX3NtYWxsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbmltdW06IGNoZWNrLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4YWN0OiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJlbWFpbFwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFlbWFpbFJlZ2V4LnRlc3QoaW5wdXQuZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGlvbjogXCJlbWFpbFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSBcImVtb2ppXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWVtb2ppUmVnZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgZW1vamlSZWdleCA9IG5ldyBSZWdFeHAoX2Vtb2ppUmVnZXgsIFwidVwiKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCFlbW9qaVJlZ2V4LnRlc3QoaW5wdXQuZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGlvbjogXCJlbW9qaVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSBcInV1aWRcIikge1xuICAgICAgICAgICAgICAgIGlmICghdXVpZFJlZ2V4LnRlc3QoaW5wdXQuZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGlvbjogXCJ1dWlkXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwibmFub2lkXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAoIW5hbm9pZFJlZ2V4LnRlc3QoaW5wdXQuZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGlvbjogXCJuYW5vaWRcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3N0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJjdWlkXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWN1aWRSZWdleC50ZXN0KGlucHV0LmRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb246IFwiY3VpZFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSBcImN1aWQyXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWN1aWQyUmVnZXgudGVzdChpbnB1dC5kYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uOiBcImN1aWQyXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwidWxpZFwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF1bGlkUmVnZXgudGVzdChpbnB1dC5kYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uOiBcInVsaWRcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3N0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJ1cmxcIikge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICAgICAgbmV3IFVSTChpbnB1dC5kYXRhKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoICB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb246IFwidXJsXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwicmVnZXhcIikge1xuICAgICAgICAgICAgICAgIGNoZWNrLnJlZ2V4Lmxhc3RJbmRleCA9IDA7XG4gICAgICAgICAgICAgICAgY29uc3QgdGVzdFJlc3VsdCA9IGNoZWNrLnJlZ2V4LnRlc3QoaW5wdXQuZGF0YSk7XG4gICAgICAgICAgICAgICAgaWYgKCF0ZXN0UmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb246IFwicmVnZXhcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3N0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJ0cmltXCIpIHtcbiAgICAgICAgICAgICAgICBpbnB1dC5kYXRhID0gaW5wdXQuZGF0YS50cmltKCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwiaW5jbHVkZXNcIikge1xuICAgICAgICAgICAgICAgIGlmICghaW5wdXQuZGF0YS5pbmNsdWRlcyhjaGVjay52YWx1ZSwgY2hlY2sucG9zaXRpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3N0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb246IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmNsdWRlczogY2hlY2sudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpb246IGNoZWNrLnBvc2l0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSBcInRvTG93ZXJDYXNlXCIpIHtcbiAgICAgICAgICAgICAgICBpbnB1dC5kYXRhID0gaW5wdXQuZGF0YS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSBcInRvVXBwZXJDYXNlXCIpIHtcbiAgICAgICAgICAgICAgICBpbnB1dC5kYXRhID0gaW5wdXQuZGF0YS50b1VwcGVyQ2FzZSgpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSBcInN0YXJ0c1dpdGhcIikge1xuICAgICAgICAgICAgICAgIGlmICghaW5wdXQuZGF0YS5zdGFydHNXaXRoKGNoZWNrLnZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRzV2l0aDogY2hlY2sudmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwiZW5kc1dpdGhcIikge1xuICAgICAgICAgICAgICAgIGlmICghaW5wdXQuZGF0YS5lbmRzV2l0aChjaGVjay52YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGlvbjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZHNXaXRoOiBjaGVjay52YWx1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJkYXRldGltZVwiKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVnZXggPSBkYXRldGltZVJlZ2V4KGNoZWNrKTtcbiAgICAgICAgICAgICAgICBpZiAoIXJlZ2V4LnRlc3QoaW5wdXQuZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGlvbjogXCJkYXRldGltZVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSBcImRhdGVcIikge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlZ2V4ID0gZGF0ZVJlZ2V4O1xuICAgICAgICAgICAgICAgIGlmICghcmVnZXgudGVzdChpbnB1dC5kYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uOiBcImRhdGVcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJ0aW1lXCIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZWdleCA9IHRpbWVSZWdleChjaGVjayk7XG4gICAgICAgICAgICAgICAgaWYgKCFyZWdleC50ZXN0KGlucHV0LmRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3N0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb246IFwidGltZVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSBcImR1cmF0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWR1cmF0aW9uUmVnZXgudGVzdChpbnB1dC5kYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uOiBcImR1cmF0aW9uXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwiaXBcIikge1xuICAgICAgICAgICAgICAgIGlmICghaXNWYWxpZElQKGlucHV0LmRhdGEsIGNoZWNrLnZlcnNpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb246IFwiaXBcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3N0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJqd3RcIikge1xuICAgICAgICAgICAgICAgIGlmICghaXNWYWxpZEpXVChpbnB1dC5kYXRhLCBjaGVjay5hbGcpKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb246IFwiand0XCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwiY2lkclwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFpc1ZhbGlkQ2lkcihpbnB1dC5kYXRhLCBjaGVjay52ZXJzaW9uKSkge1xuICAgICAgICAgICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uOiBcImNpZHJcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3N0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJiYXNlNjRcIikge1xuICAgICAgICAgICAgICAgIGlmICghYmFzZTY0UmVnZXgudGVzdChpbnB1dC5kYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uOiBcImJhc2U2NFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSBcImJhc2U2NHVybFwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFiYXNlNjR1cmxSZWdleC50ZXN0KGlucHV0LmRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb246IFwiYmFzZTY0dXJsXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHV0aWwuYXNzZXJ0TmV2ZXIoY2hlY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdGF0dXM6IHN0YXR1cy52YWx1ZSxcbiAgICAgICAgICAgIHZhbHVlOiBpbnB1dC5kYXRhXG4gICAgICAgIH07XG4gICAgfVxuICAgIF9yZWdleChyZWdleCwgdmFsaWRhdGlvbiwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWZpbmVtZW50KChkYXRhKT0+cmVnZXgudGVzdChkYXRhKSwge1xuICAgICAgICAgICAgdmFsaWRhdGlvbixcbiAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3N0cmluZyxcbiAgICAgICAgICAgIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgX2FkZENoZWNrKGNoZWNrKSB7XG4gICAgICAgIHJldHVybiBuZXcgWm9kU3RyaW5nKHtcbiAgICAgICAgICAgIC4uLnRoaXMuX2RlZixcbiAgICAgICAgICAgIGNoZWNrczogW1xuICAgICAgICAgICAgICAgIC4uLnRoaXMuX2RlZi5jaGVja3MsXG4gICAgICAgICAgICAgICAgY2hlY2tcbiAgICAgICAgICAgIF1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGVtYWlsKG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgIGtpbmQ6IFwiZW1haWxcIixcbiAgICAgICAgICAgIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgdXJsKG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgIGtpbmQ6IFwidXJsXCIsXG4gICAgICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGVtb2ppKG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgIGtpbmQ6IFwiZW1vamlcIixcbiAgICAgICAgICAgIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgdXVpZChtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcInV1aWRcIixcbiAgICAgICAgICAgIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgbmFub2lkKG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgIGtpbmQ6IFwibmFub2lkXCIsXG4gICAgICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGN1aWQobWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJjdWlkXCIsXG4gICAgICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGN1aWQyKG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgIGtpbmQ6IFwiY3VpZDJcIixcbiAgICAgICAgICAgIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgdWxpZChtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcInVsaWRcIixcbiAgICAgICAgICAgIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgYmFzZTY0KG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgIGtpbmQ6IFwiYmFzZTY0XCIsXG4gICAgICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGJhc2U2NHVybChtZXNzYWdlKSB7XG4gICAgICAgIC8vIGJhc2U2NHVybCBlbmNvZGluZyBpcyBhIG1vZGlmaWNhdGlvbiBvZiBiYXNlNjQgdGhhdCBjYW4gc2FmZWx5IGJlIHVzZWQgaW4gVVJMcyBhbmQgZmlsZW5hbWVzXG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcImJhc2U2NHVybFwiLFxuICAgICAgICAgICAgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBqd3Qob3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJqd3RcIixcbiAgICAgICAgICAgIC4uLmVycm9yVXRpbC5lcnJUb09iaihvcHRpb25zKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgaXAob3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJpcFwiLFxuICAgICAgICAgICAgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG9wdGlvbnMpXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBjaWRyKG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgIGtpbmQ6IFwiY2lkclwiLFxuICAgICAgICAgICAgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG9wdGlvbnMpXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkYXRldGltZShvcHRpb25zKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgICAgICBraW5kOiBcImRhdGV0aW1lXCIsXG4gICAgICAgICAgICAgICAgcHJlY2lzaW9uOiBudWxsLFxuICAgICAgICAgICAgICAgIG9mZnNldDogZmFsc2UsXG4gICAgICAgICAgICAgICAgbG9jYWw6IGZhbHNlLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IG9wdGlvbnNcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcImRhdGV0aW1lXCIsXG4gICAgICAgICAgICBwcmVjaXNpb246IHR5cGVvZiBvcHRpb25zPy5wcmVjaXNpb24gPT09IFwidW5kZWZpbmVkXCIgPyBudWxsIDogb3B0aW9ucz8ucHJlY2lzaW9uLFxuICAgICAgICAgICAgb2Zmc2V0OiBvcHRpb25zPy5vZmZzZXQgPz8gZmFsc2UsXG4gICAgICAgICAgICBsb2NhbDogb3B0aW9ucz8ubG9jYWwgPz8gZmFsc2UsXG4gICAgICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoob3B0aW9ucz8ubWVzc2FnZSlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRhdGUobWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJkYXRlXCIsXG4gICAgICAgICAgICBtZXNzYWdlXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICB0aW1lKG9wdGlvbnMpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvcHRpb25zID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAgICAgIGtpbmQ6IFwidGltZVwiLFxuICAgICAgICAgICAgICAgIHByZWNpc2lvbjogbnVsbCxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBvcHRpb25zXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJ0aW1lXCIsXG4gICAgICAgICAgICBwcmVjaXNpb246IHR5cGVvZiBvcHRpb25zPy5wcmVjaXNpb24gPT09IFwidW5kZWZpbmVkXCIgPyBudWxsIDogb3B0aW9ucz8ucHJlY2lzaW9uLFxuICAgICAgICAgICAgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG9wdGlvbnM/Lm1lc3NhZ2UpXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkdXJhdGlvbihtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcImR1cmF0aW9uXCIsXG4gICAgICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJlZ2V4KHJlZ2V4LCBtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcInJlZ2V4XCIsXG4gICAgICAgICAgICByZWdleDogcmVnZXgsXG4gICAgICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGluY2x1ZGVzKHZhbHVlLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcImluY2x1ZGVzXCIsXG4gICAgICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgICAgICBwb3NpdGlvbjogb3B0aW9ucz8ucG9zaXRpb24sXG4gICAgICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoob3B0aW9ucz8ubWVzc2FnZSlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHN0YXJ0c1dpdGgodmFsdWUsIG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgIGtpbmQ6IFwic3RhcnRzV2l0aFwiLFxuICAgICAgICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgICAgICAgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBlbmRzV2l0aCh2YWx1ZSwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJlbmRzV2l0aFwiLFxuICAgICAgICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgICAgICAgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBtaW4obWluTGVuZ3RoLCBtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcIm1pblwiLFxuICAgICAgICAgICAgdmFsdWU6IG1pbkxlbmd0aCxcbiAgICAgICAgICAgIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgbWF4KG1heExlbmd0aCwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJtYXhcIixcbiAgICAgICAgICAgIHZhbHVlOiBtYXhMZW5ndGgsXG4gICAgICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGxlbmd0aChsZW4sIG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgIGtpbmQ6IFwibGVuZ3RoXCIsXG4gICAgICAgICAgICB2YWx1ZTogbGVuLFxuICAgICAgICAgICAgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBFcXVpdmFsZW50IHRvIGAubWluKDEpYFxuICAgICAqLyBub25lbXB0eShtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1pbigxLCBlcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSkpO1xuICAgIH1cbiAgICB0cmltKCkge1xuICAgICAgICByZXR1cm4gbmV3IFpvZFN0cmluZyh7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICBjaGVja3M6IFtcbiAgICAgICAgICAgICAgICAuLi50aGlzLl9kZWYuY2hlY2tzLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAga2luZDogXCJ0cmltXCJcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICB0b0xvd2VyQ2FzZSgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBab2RTdHJpbmcoe1xuICAgICAgICAgICAgLi4udGhpcy5fZGVmLFxuICAgICAgICAgICAgY2hlY2tzOiBbXG4gICAgICAgICAgICAgICAgLi4udGhpcy5fZGVmLmNoZWNrcyxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGtpbmQ6IFwidG9Mb3dlckNhc2VcIlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHRvVXBwZXJDYXNlKCkge1xuICAgICAgICByZXR1cm4gbmV3IFpvZFN0cmluZyh7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICBjaGVja3M6IFtcbiAgICAgICAgICAgICAgICAuLi50aGlzLl9kZWYuY2hlY2tzLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAga2luZDogXCJ0b1VwcGVyQ2FzZVwiXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgXVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZ2V0IGlzRGF0ZXRpbWUoKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuX2RlZi5jaGVja3MuZmluZCgoY2gpPT5jaC5raW5kID09PSBcImRhdGV0aW1lXCIpO1xuICAgIH1cbiAgICBnZXQgaXNEYXRlKCkge1xuICAgICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKT0+Y2gua2luZCA9PT0gXCJkYXRlXCIpO1xuICAgIH1cbiAgICBnZXQgaXNUaW1lKCkge1xuICAgICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKT0+Y2gua2luZCA9PT0gXCJ0aW1lXCIpO1xuICAgIH1cbiAgICBnZXQgaXNEdXJhdGlvbigpIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCk9PmNoLmtpbmQgPT09IFwiZHVyYXRpb25cIik7XG4gICAgfVxuICAgIGdldCBpc0VtYWlsKCkge1xuICAgICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKT0+Y2gua2luZCA9PT0gXCJlbWFpbFwiKTtcbiAgICB9XG4gICAgZ2V0IGlzVVJMKCkge1xuICAgICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKT0+Y2gua2luZCA9PT0gXCJ1cmxcIik7XG4gICAgfVxuICAgIGdldCBpc0Vtb2ppKCkge1xuICAgICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKT0+Y2gua2luZCA9PT0gXCJlbW9qaVwiKTtcbiAgICB9XG4gICAgZ2V0IGlzVVVJRCgpIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCk9PmNoLmtpbmQgPT09IFwidXVpZFwiKTtcbiAgICB9XG4gICAgZ2V0IGlzTkFOT0lEKCkge1xuICAgICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKT0+Y2gua2luZCA9PT0gXCJuYW5vaWRcIik7XG4gICAgfVxuICAgIGdldCBpc0NVSUQoKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuX2RlZi5jaGVja3MuZmluZCgoY2gpPT5jaC5raW5kID09PSBcImN1aWRcIik7XG4gICAgfVxuICAgIGdldCBpc0NVSUQyKCkge1xuICAgICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKT0+Y2gua2luZCA9PT0gXCJjdWlkMlwiKTtcbiAgICB9XG4gICAgZ2V0IGlzVUxJRCgpIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCk9PmNoLmtpbmQgPT09IFwidWxpZFwiKTtcbiAgICB9XG4gICAgZ2V0IGlzSVAoKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuX2RlZi5jaGVja3MuZmluZCgoY2gpPT5jaC5raW5kID09PSBcImlwXCIpO1xuICAgIH1cbiAgICBnZXQgaXNDSURSKCkge1xuICAgICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKT0+Y2gua2luZCA9PT0gXCJjaWRyXCIpO1xuICAgIH1cbiAgICBnZXQgaXNCYXNlNjQoKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuX2RlZi5jaGVja3MuZmluZCgoY2gpPT5jaC5raW5kID09PSBcImJhc2U2NFwiKTtcbiAgICB9XG4gICAgZ2V0IGlzQmFzZTY0dXJsKCkge1xuICAgICAgICAvLyBiYXNlNjR1cmwgZW5jb2RpbmcgaXMgYSBtb2RpZmljYXRpb24gb2YgYmFzZTY0IHRoYXQgY2FuIHNhZmVseSBiZSB1c2VkIGluIFVSTHMgYW5kIGZpbGVuYW1lc1xuICAgICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKT0+Y2gua2luZCA9PT0gXCJiYXNlNjR1cmxcIik7XG4gICAgfVxuICAgIGdldCBtaW5MZW5ndGgoKSB7XG4gICAgICAgIGxldCBtaW4gPSBudWxsO1xuICAgICAgICBmb3IgKGNvbnN0IGNoIG9mIHRoaXMuX2RlZi5jaGVja3Mpe1xuICAgICAgICAgICAgaWYgKGNoLmtpbmQgPT09IFwibWluXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAobWluID09PSBudWxsIHx8IGNoLnZhbHVlID4gbWluKSBtaW4gPSBjaC52YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWluO1xuICAgIH1cbiAgICBnZXQgbWF4TGVuZ3RoKCkge1xuICAgICAgICBsZXQgbWF4ID0gbnVsbDtcbiAgICAgICAgZm9yIChjb25zdCBjaCBvZiB0aGlzLl9kZWYuY2hlY2tzKXtcbiAgICAgICAgICAgIGlmIChjaC5raW5kID09PSBcIm1heFwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKG1heCA9PT0gbnVsbCB8fCBjaC52YWx1ZSA8IG1heCkgbWF4ID0gY2gudmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1heDtcbiAgICB9XG59XG5ab2RTdHJpbmcuY3JlYXRlID0gKHBhcmFtcyk9PntcbiAgICByZXR1cm4gbmV3IFpvZFN0cmluZyh7XG4gICAgICAgIGNoZWNrczogW10sXG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kU3RyaW5nLFxuICAgICAgICBjb2VyY2U6IHBhcmFtcz8uY29lcmNlID8/IGZhbHNlLFxuICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn07XG4vLyBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8zOTY2NDg0L3doeS1kb2VzLW1vZHVsdXMtb3BlcmF0b3ItcmV0dXJuLWZyYWN0aW9uYWwtbnVtYmVyLWluLWphdmFzY3JpcHQvMzE3MTEwMzQjMzE3MTEwMzRcbmZ1bmN0aW9uIGZsb2F0U2FmZVJlbWFpbmRlcih2YWwsIHN0ZXApIHtcbiAgICBjb25zdCB2YWxEZWNDb3VudCA9ICh2YWwudG9TdHJpbmcoKS5zcGxpdChcIi5cIilbMV0gfHwgXCJcIikubGVuZ3RoO1xuICAgIGNvbnN0IHN0ZXBEZWNDb3VudCA9IChzdGVwLnRvU3RyaW5nKCkuc3BsaXQoXCIuXCIpWzFdIHx8IFwiXCIpLmxlbmd0aDtcbiAgICBjb25zdCBkZWNDb3VudCA9IHZhbERlY0NvdW50ID4gc3RlcERlY0NvdW50ID8gdmFsRGVjQ291bnQgOiBzdGVwRGVjQ291bnQ7XG4gICAgY29uc3QgdmFsSW50ID0gTnVtYmVyLnBhcnNlSW50KHZhbC50b0ZpeGVkKGRlY0NvdW50KS5yZXBsYWNlKFwiLlwiLCBcIlwiKSk7XG4gICAgY29uc3Qgc3RlcEludCA9IE51bWJlci5wYXJzZUludChzdGVwLnRvRml4ZWQoZGVjQ291bnQpLnJlcGxhY2UoXCIuXCIsIFwiXCIpKTtcbiAgICByZXR1cm4gdmFsSW50ICUgc3RlcEludCAvIDEwICoqIGRlY0NvdW50O1xufVxuZXhwb3J0IGNsYXNzIFpvZE51bWJlciBleHRlbmRzIFpvZFR5cGUge1xuICAgIGNvbnN0cnVjdG9yKCl7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubWluID0gdGhpcy5ndGU7XG4gICAgICAgIHRoaXMubWF4ID0gdGhpcy5sdGU7XG4gICAgICAgIHRoaXMuc3RlcCA9IHRoaXMubXVsdGlwbGVPZjtcbiAgICB9XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGlmICh0aGlzLl9kZWYuY29lcmNlKSB7XG4gICAgICAgICAgICBpbnB1dC5kYXRhID0gTnVtYmVyKGlucHV0LmRhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHBhcnNlZFR5cGUgPSB0aGlzLl9nZXRUeXBlKGlucHV0KTtcbiAgICAgICAgaWYgKHBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUubnVtYmVyKSB7XG4gICAgICAgICAgICBjb25zdCBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7XG4gICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLm51bWJlcixcbiAgICAgICAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGN0eCA9IHVuZGVmaW5lZDtcbiAgICAgICAgY29uc3Qgc3RhdHVzID0gbmV3IFBhcnNlU3RhdHVzKCk7XG4gICAgICAgIGZvciAoY29uc3QgY2hlY2sgb2YgdGhpcy5fZGVmLmNoZWNrcyl7XG4gICAgICAgICAgICBpZiAoY2hlY2sua2luZCA9PT0gXCJpbnRcIikge1xuICAgICAgICAgICAgICAgIGlmICghdXRpbC5pc0ludGVnZXIoaW5wdXQuZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBcImludGVnZXJcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlY2VpdmVkOiBcImZsb2F0XCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwibWluXCIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB0b29TbWFsbCA9IGNoZWNrLmluY2x1c2l2ZSA/IGlucHV0LmRhdGEgPCBjaGVjay52YWx1ZSA6IGlucHV0LmRhdGEgPD0gY2hlY2sudmFsdWU7XG4gICAgICAgICAgICAgICAgaWYgKHRvb1NtYWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS50b29fc21hbGwsXG4gICAgICAgICAgICAgICAgICAgICAgICBtaW5pbXVtOiBjaGVjay52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IFwibnVtYmVyXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmNsdXNpdmU6IGNoZWNrLmluY2x1c2l2ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4YWN0OiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJtYXhcIikge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRvb0JpZyA9IGNoZWNrLmluY2x1c2l2ZSA/IGlucHV0LmRhdGEgPiBjaGVjay52YWx1ZSA6IGlucHV0LmRhdGEgPj0gY2hlY2sudmFsdWU7XG4gICAgICAgICAgICAgICAgaWYgKHRvb0JpZykge1xuICAgICAgICAgICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX2JpZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1heGltdW06IGNoZWNrLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJudW1iZXJcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGluY2x1c2l2ZTogY2hlY2suaW5jbHVzaXZlLFxuICAgICAgICAgICAgICAgICAgICAgICAgZXhhY3Q6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSBcIm11bHRpcGxlT2ZcIikge1xuICAgICAgICAgICAgICAgIGlmIChmbG9hdFNhZmVSZW1haW5kZXIoaW5wdXQuZGF0YSwgY2hlY2sudmFsdWUpICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5ub3RfbXVsdGlwbGVfb2YsXG4gICAgICAgICAgICAgICAgICAgICAgICBtdWx0aXBsZU9mOiBjaGVjay52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJmaW5pdGVcIikge1xuICAgICAgICAgICAgICAgIGlmICghTnVtYmVyLmlzRmluaXRlKGlucHV0LmRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5ub3RfZmluaXRlLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB1dGlsLmFzc2VydE5ldmVyKGNoZWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3RhdHVzOiBzdGF0dXMudmFsdWUsXG4gICAgICAgICAgICB2YWx1ZTogaW5wdXQuZGF0YVxuICAgICAgICB9O1xuICAgIH1cbiAgICBndGUodmFsdWUsIG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2V0TGltaXQoXCJtaW5cIiwgdmFsdWUsIHRydWUsIGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKSk7XG4gICAgfVxuICAgIGd0KHZhbHVlLCBtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNldExpbWl0KFwibWluXCIsIHZhbHVlLCBmYWxzZSwgZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpKTtcbiAgICB9XG4gICAgbHRlKHZhbHVlLCBtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNldExpbWl0KFwibWF4XCIsIHZhbHVlLCB0cnVlLCBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkpO1xuICAgIH1cbiAgICBsdCh2YWx1ZSwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5zZXRMaW1pdChcIm1heFwiLCB2YWx1ZSwgZmFsc2UsIGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKSk7XG4gICAgfVxuICAgIHNldExpbWl0KGtpbmQsIHZhbHVlLCBpbmNsdXNpdmUsIG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBab2ROdW1iZXIoe1xuICAgICAgICAgICAgLi4udGhpcy5fZGVmLFxuICAgICAgICAgICAgY2hlY2tzOiBbXG4gICAgICAgICAgICAgICAgLi4udGhpcy5fZGVmLmNoZWNrcyxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGtpbmQsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBpbmNsdXNpdmUsXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIF9hZGRDaGVjayhjaGVjaykge1xuICAgICAgICByZXR1cm4gbmV3IFpvZE51bWJlcih7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICBjaGVja3M6IFtcbiAgICAgICAgICAgICAgICAuLi50aGlzLl9kZWYuY2hlY2tzLFxuICAgICAgICAgICAgICAgIGNoZWNrXG4gICAgICAgICAgICBdXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBpbnQobWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJpbnRcIixcbiAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgcG9zaXRpdmUobWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJtaW5cIixcbiAgICAgICAgICAgIHZhbHVlOiAwLFxuICAgICAgICAgICAgaW5jbHVzaXZlOiBmYWxzZSxcbiAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgbmVnYXRpdmUobWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJtYXhcIixcbiAgICAgICAgICAgIHZhbHVlOiAwLFxuICAgICAgICAgICAgaW5jbHVzaXZlOiBmYWxzZSxcbiAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgbm9ucG9zaXRpdmUobWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJtYXhcIixcbiAgICAgICAgICAgIHZhbHVlOiAwLFxuICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBub25uZWdhdGl2ZShtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcIm1pblwiLFxuICAgICAgICAgICAgdmFsdWU6IDAsXG4gICAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsXG4gICAgICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIG11bHRpcGxlT2YodmFsdWUsIG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgIGtpbmQ6IFwibXVsdGlwbGVPZlwiLFxuICAgICAgICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBmaW5pdGUobWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJmaW5pdGVcIixcbiAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgc2FmZShtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcIm1pblwiLFxuICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgdmFsdWU6IE51bWJlci5NSU5fU0FGRV9JTlRFR0VSLFxuICAgICAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpXG4gICAgICAgIH0pLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcIm1heFwiLFxuICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgdmFsdWU6IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSLFxuICAgICAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBnZXQgbWluVmFsdWUoKSB7XG4gICAgICAgIGxldCBtaW4gPSBudWxsO1xuICAgICAgICBmb3IgKGNvbnN0IGNoIG9mIHRoaXMuX2RlZi5jaGVja3Mpe1xuICAgICAgICAgICAgaWYgKGNoLmtpbmQgPT09IFwibWluXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAobWluID09PSBudWxsIHx8IGNoLnZhbHVlID4gbWluKSBtaW4gPSBjaC52YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWluO1xuICAgIH1cbiAgICBnZXQgbWF4VmFsdWUoKSB7XG4gICAgICAgIGxldCBtYXggPSBudWxsO1xuICAgICAgICBmb3IgKGNvbnN0IGNoIG9mIHRoaXMuX2RlZi5jaGVja3Mpe1xuICAgICAgICAgICAgaWYgKGNoLmtpbmQgPT09IFwibWF4XCIpIHtcbiAgICAgICAgICAgICAgICBpZiAobWF4ID09PSBudWxsIHx8IGNoLnZhbHVlIDwgbWF4KSBtYXggPSBjaC52YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWF4O1xuICAgIH1cbiAgICBnZXQgaXNJbnQoKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuX2RlZi5jaGVja3MuZmluZCgoY2gpPT5jaC5raW5kID09PSBcImludFwiIHx8IGNoLmtpbmQgPT09IFwibXVsdGlwbGVPZlwiICYmIHV0aWwuaXNJbnRlZ2VyKGNoLnZhbHVlKSk7XG4gICAgfVxuICAgIGdldCBpc0Zpbml0ZSgpIHtcbiAgICAgICAgbGV0IG1heCA9IG51bGw7XG4gICAgICAgIGxldCBtaW4gPSBudWxsO1xuICAgICAgICBmb3IgKGNvbnN0IGNoIG9mIHRoaXMuX2RlZi5jaGVja3Mpe1xuICAgICAgICAgICAgaWYgKGNoLmtpbmQgPT09IFwiZmluaXRlXCIgfHwgY2gua2luZCA9PT0gXCJpbnRcIiB8fCBjaC5raW5kID09PSBcIm11bHRpcGxlT2ZcIikge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChjaC5raW5kID09PSBcIm1pblwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKG1pbiA9PT0gbnVsbCB8fCBjaC52YWx1ZSA+IG1pbikgbWluID0gY2gudmFsdWU7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNoLmtpbmQgPT09IFwibWF4XCIpIHtcbiAgICAgICAgICAgICAgICBpZiAobWF4ID09PSBudWxsIHx8IGNoLnZhbHVlIDwgbWF4KSBtYXggPSBjaC52YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gTnVtYmVyLmlzRmluaXRlKG1pbikgJiYgTnVtYmVyLmlzRmluaXRlKG1heCk7XG4gICAgfVxufVxuWm9kTnVtYmVyLmNyZWF0ZSA9IChwYXJhbXMpPT57XG4gICAgcmV0dXJuIG5ldyBab2ROdW1iZXIoe1xuICAgICAgICBjaGVja3M6IFtdLFxuICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE51bWJlcixcbiAgICAgICAgY29lcmNlOiBwYXJhbXM/LmNvZXJjZSB8fCBmYWxzZSxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59O1xuZXhwb3J0IGNsYXNzIFpvZEJpZ0ludCBleHRlbmRzIFpvZFR5cGUge1xuICAgIGNvbnN0cnVjdG9yKCl7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubWluID0gdGhpcy5ndGU7XG4gICAgICAgIHRoaXMubWF4ID0gdGhpcy5sdGU7XG4gICAgfVxuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBpZiAodGhpcy5fZGVmLmNvZXJjZSkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBpbnB1dC5kYXRhID0gQmlnSW50KGlucHV0LmRhdGEpO1xuICAgICAgICAgICAgfSBjYXRjaCAge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRJbnZhbGlkSW5wdXQoaW5wdXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHBhcnNlZFR5cGUgPSB0aGlzLl9nZXRUeXBlKGlucHV0KTtcbiAgICAgICAgaWYgKHBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUuYmlnaW50KSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZ2V0SW52YWxpZElucHV0KGlucHV0KTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgY3R4ID0gdW5kZWZpbmVkO1xuICAgICAgICBjb25zdCBzdGF0dXMgPSBuZXcgUGFyc2VTdGF0dXMoKTtcbiAgICAgICAgZm9yIChjb25zdCBjaGVjayBvZiB0aGlzLl9kZWYuY2hlY2tzKXtcbiAgICAgICAgICAgIGlmIChjaGVjay5raW5kID09PSBcIm1pblwiKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdG9vU21hbGwgPSBjaGVjay5pbmNsdXNpdmUgPyBpbnB1dC5kYXRhIDwgY2hlY2sudmFsdWUgOiBpbnB1dC5kYXRhIDw9IGNoZWNrLnZhbHVlO1xuICAgICAgICAgICAgICAgIGlmICh0b29TbWFsbCkge1xuICAgICAgICAgICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX3NtYWxsLFxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJiaWdpbnRcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIG1pbmltdW06IGNoZWNrLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgaW5jbHVzaXZlOiBjaGVjay5pbmNsdXNpdmUsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwibWF4XCIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB0b29CaWcgPSBjaGVjay5pbmNsdXNpdmUgPyBpbnB1dC5kYXRhID4gY2hlY2sudmFsdWUgOiBpbnB1dC5kYXRhID49IGNoZWNrLnZhbHVlO1xuICAgICAgICAgICAgICAgIGlmICh0b29CaWcpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLnRvb19iaWcsXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiBcImJpZ2ludFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWF4aW11bTogY2hlY2sudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmNsdXNpdmU6IGNoZWNrLmluY2x1c2l2ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJtdWx0aXBsZU9mXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAoaW5wdXQuZGF0YSAlIGNoZWNrLnZhbHVlICE9PSBCaWdJbnQoMCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLm5vdF9tdWx0aXBsZV9vZixcbiAgICAgICAgICAgICAgICAgICAgICAgIG11bHRpcGxlT2Y6IGNoZWNrLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB1dGlsLmFzc2VydE5ldmVyKGNoZWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3RhdHVzOiBzdGF0dXMudmFsdWUsXG4gICAgICAgICAgICB2YWx1ZTogaW5wdXQuZGF0YVxuICAgICAgICB9O1xuICAgIH1cbiAgICBfZ2V0SW52YWxpZElucHV0KGlucHV0KSB7XG4gICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTtcbiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLFxuICAgICAgICAgICAgZXhwZWN0ZWQ6IFpvZFBhcnNlZFR5cGUuYmlnaW50LFxuICAgICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICB9XG4gICAgZ3RlKHZhbHVlLCBtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNldExpbWl0KFwibWluXCIsIHZhbHVlLCB0cnVlLCBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkpO1xuICAgIH1cbiAgICBndCh2YWx1ZSwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5zZXRMaW1pdChcIm1pblwiLCB2YWx1ZSwgZmFsc2UsIGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKSk7XG4gICAgfVxuICAgIGx0ZSh2YWx1ZSwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5zZXRMaW1pdChcIm1heFwiLCB2YWx1ZSwgdHJ1ZSwgZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpKTtcbiAgICB9XG4gICAgbHQodmFsdWUsIG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2V0TGltaXQoXCJtYXhcIiwgdmFsdWUsIGZhbHNlLCBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkpO1xuICAgIH1cbiAgICBzZXRMaW1pdChraW5kLCB2YWx1ZSwgaW5jbHVzaXZlLCBtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiBuZXcgWm9kQmlnSW50KHtcbiAgICAgICAgICAgIC4uLnRoaXMuX2RlZixcbiAgICAgICAgICAgIGNoZWNrczogW1xuICAgICAgICAgICAgICAgIC4uLnRoaXMuX2RlZi5jaGVja3MsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBraW5kLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgaW5jbHVzaXZlLFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSlcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBfYWRkQ2hlY2soY2hlY2spIHtcbiAgICAgICAgcmV0dXJuIG5ldyBab2RCaWdJbnQoe1xuICAgICAgICAgICAgLi4udGhpcy5fZGVmLFxuICAgICAgICAgICAgY2hlY2tzOiBbXG4gICAgICAgICAgICAgICAgLi4udGhpcy5fZGVmLmNoZWNrcyxcbiAgICAgICAgICAgICAgICBjaGVja1xuICAgICAgICAgICAgXVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgcG9zaXRpdmUobWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJtaW5cIixcbiAgICAgICAgICAgIHZhbHVlOiBCaWdJbnQoMCksXG4gICAgICAgICAgICBpbmNsdXNpdmU6IGZhbHNlLFxuICAgICAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBuZWdhdGl2ZShtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcIm1heFwiLFxuICAgICAgICAgICAgdmFsdWU6IEJpZ0ludCgwKSxcbiAgICAgICAgICAgIGluY2x1c2l2ZTogZmFsc2UsXG4gICAgICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIG5vbnBvc2l0aXZlKG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgIGtpbmQ6IFwibWF4XCIsXG4gICAgICAgICAgICB2YWx1ZTogQmlnSW50KDApLFxuICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBub25uZWdhdGl2ZShtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcIm1pblwiLFxuICAgICAgICAgICAgdmFsdWU6IEJpZ0ludCgwKSxcbiAgICAgICAgICAgIGluY2x1c2l2ZTogdHJ1ZSxcbiAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgbXVsdGlwbGVPZih2YWx1ZSwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJtdWx0aXBsZU9mXCIsXG4gICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZ2V0IG1pblZhbHVlKCkge1xuICAgICAgICBsZXQgbWluID0gbnVsbDtcbiAgICAgICAgZm9yIChjb25zdCBjaCBvZiB0aGlzLl9kZWYuY2hlY2tzKXtcbiAgICAgICAgICAgIGlmIChjaC5raW5kID09PSBcIm1pblwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKG1pbiA9PT0gbnVsbCB8fCBjaC52YWx1ZSA+IG1pbikgbWluID0gY2gudmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1pbjtcbiAgICB9XG4gICAgZ2V0IG1heFZhbHVlKCkge1xuICAgICAgICBsZXQgbWF4ID0gbnVsbDtcbiAgICAgICAgZm9yIChjb25zdCBjaCBvZiB0aGlzLl9kZWYuY2hlY2tzKXtcbiAgICAgICAgICAgIGlmIChjaC5raW5kID09PSBcIm1heFwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKG1heCA9PT0gbnVsbCB8fCBjaC52YWx1ZSA8IG1heCkgbWF4ID0gY2gudmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1heDtcbiAgICB9XG59XG5ab2RCaWdJbnQuY3JlYXRlID0gKHBhcmFtcyk9PntcbiAgICByZXR1cm4gbmV3IFpvZEJpZ0ludCh7XG4gICAgICAgIGNoZWNrczogW10sXG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kQmlnSW50LFxuICAgICAgICBjb2VyY2U6IHBhcmFtcz8uY29lcmNlID8/IGZhbHNlLFxuICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn07XG5leHBvcnQgY2xhc3MgWm9kQm9vbGVhbiBleHRlbmRzIFpvZFR5cGUge1xuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBpZiAodGhpcy5fZGVmLmNvZXJjZSkge1xuICAgICAgICAgICAgaW5wdXQuZGF0YSA9IEJvb2xlYW4oaW5wdXQuZGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcGFyc2VkVHlwZSA9IHRoaXMuX2dldFR5cGUoaW5wdXQpO1xuICAgICAgICBpZiAocGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS5ib29sZWFuKSB7XG4gICAgICAgICAgICBjb25zdCBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7XG4gICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLmJvb2xlYW4sXG4gICAgICAgICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBPSyhpbnB1dC5kYXRhKTtcbiAgICB9XG59XG5ab2RCb29sZWFuLmNyZWF0ZSA9IChwYXJhbXMpPT57XG4gICAgcmV0dXJuIG5ldyBab2RCb29sZWFuKHtcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RCb29sZWFuLFxuICAgICAgICBjb2VyY2U6IHBhcmFtcz8uY29lcmNlIHx8IGZhbHNlLFxuICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn07XG5leHBvcnQgY2xhc3MgWm9kRGF0ZSBleHRlbmRzIFpvZFR5cGUge1xuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBpZiAodGhpcy5fZGVmLmNvZXJjZSkge1xuICAgICAgICAgICAgaW5wdXQuZGF0YSA9IG5ldyBEYXRlKGlucHV0LmRhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHBhcnNlZFR5cGUgPSB0aGlzLl9nZXRUeXBlKGlucHV0KTtcbiAgICAgICAgaWYgKHBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUuZGF0ZSkge1xuICAgICAgICAgICAgY29uc3QgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQpO1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSxcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5kYXRlLFxuICAgICAgICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoTnVtYmVyLmlzTmFOKGlucHV0LmRhdGEuZ2V0VGltZSgpKSkge1xuICAgICAgICAgICAgY29uc3QgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQpO1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfZGF0ZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzdGF0dXMgPSBuZXcgUGFyc2VTdGF0dXMoKTtcbiAgICAgICAgbGV0IGN0eCA9IHVuZGVmaW5lZDtcbiAgICAgICAgZm9yIChjb25zdCBjaGVjayBvZiB0aGlzLl9kZWYuY2hlY2tzKXtcbiAgICAgICAgICAgIGlmIChjaGVjay5raW5kID09PSBcIm1pblwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKGlucHV0LmRhdGEuZ2V0VGltZSgpIDwgY2hlY2sudmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLnRvb19zbWFsbCxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBleGFjdDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICBtaW5pbXVtOiBjaGVjay52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IFwiZGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwibWF4XCIpIHtcbiAgICAgICAgICAgICAgICBpZiAoaW5wdXQuZGF0YS5nZXRUaW1lKCkgPiBjaGVjay52YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX2JpZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBleGFjdDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICBtYXhpbXVtOiBjaGVjay52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IFwiZGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHV0aWwuYXNzZXJ0TmV2ZXIoY2hlY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdGF0dXM6IHN0YXR1cy52YWx1ZSxcbiAgICAgICAgICAgIHZhbHVlOiBuZXcgRGF0ZShpbnB1dC5kYXRhLmdldFRpbWUoKSlcbiAgICAgICAgfTtcbiAgICB9XG4gICAgX2FkZENoZWNrKGNoZWNrKSB7XG4gICAgICAgIHJldHVybiBuZXcgWm9kRGF0ZSh7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICBjaGVja3M6IFtcbiAgICAgICAgICAgICAgICAuLi50aGlzLl9kZWYuY2hlY2tzLFxuICAgICAgICAgICAgICAgIGNoZWNrXG4gICAgICAgICAgICBdXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBtaW4obWluRGF0ZSwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJtaW5cIixcbiAgICAgICAgICAgIHZhbHVlOiBtaW5EYXRlLmdldFRpbWUoKSxcbiAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgbWF4KG1heERhdGUsIG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgIGtpbmQ6IFwibWF4XCIsXG4gICAgICAgICAgICB2YWx1ZTogbWF4RGF0ZS5nZXRUaW1lKCksXG4gICAgICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGdldCBtaW5EYXRlKCkge1xuICAgICAgICBsZXQgbWluID0gbnVsbDtcbiAgICAgICAgZm9yIChjb25zdCBjaCBvZiB0aGlzLl9kZWYuY2hlY2tzKXtcbiAgICAgICAgICAgIGlmIChjaC5raW5kID09PSBcIm1pblwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKG1pbiA9PT0gbnVsbCB8fCBjaC52YWx1ZSA+IG1pbikgbWluID0gY2gudmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1pbiAhPSBudWxsID8gbmV3IERhdGUobWluKSA6IG51bGw7XG4gICAgfVxuICAgIGdldCBtYXhEYXRlKCkge1xuICAgICAgICBsZXQgbWF4ID0gbnVsbDtcbiAgICAgICAgZm9yIChjb25zdCBjaCBvZiB0aGlzLl9kZWYuY2hlY2tzKXtcbiAgICAgICAgICAgIGlmIChjaC5raW5kID09PSBcIm1heFwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKG1heCA9PT0gbnVsbCB8fCBjaC52YWx1ZSA8IG1heCkgbWF4ID0gY2gudmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1heCAhPSBudWxsID8gbmV3IERhdGUobWF4KSA6IG51bGw7XG4gICAgfVxufVxuWm9kRGF0ZS5jcmVhdGUgPSAocGFyYW1zKT0+e1xuICAgIHJldHVybiBuZXcgWm9kRGF0ZSh7XG4gICAgICAgIGNoZWNrczogW10sXG4gICAgICAgIGNvZXJjZTogcGFyYW1zPy5jb2VyY2UgfHwgZmFsc2UsXG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kRGF0ZSxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59O1xuZXhwb3J0IGNsYXNzIFpvZFN5bWJvbCBleHRlbmRzIFpvZFR5cGUge1xuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBjb25zdCBwYXJzZWRUeXBlID0gdGhpcy5fZ2V0VHlwZShpbnB1dCk7XG4gICAgICAgIGlmIChwYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLnN5bWJvbCkge1xuICAgICAgICAgICAgY29uc3QgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQpO1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSxcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5zeW1ib2wsXG4gICAgICAgICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBPSyhpbnB1dC5kYXRhKTtcbiAgICB9XG59XG5ab2RTeW1ib2wuY3JlYXRlID0gKHBhcmFtcyk9PntcbiAgICByZXR1cm4gbmV3IFpvZFN5bWJvbCh7XG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kU3ltYm9sLFxuICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn07XG5leHBvcnQgY2xhc3MgWm9kVW5kZWZpbmVkIGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHBhcnNlZFR5cGUgPSB0aGlzLl9nZXRUeXBlKGlucHV0KTtcbiAgICAgICAgaWYgKHBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUudW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBjb25zdCBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7XG4gICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLnVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIE9LKGlucHV0LmRhdGEpO1xuICAgIH1cbn1cblpvZFVuZGVmaW5lZC5jcmVhdGUgPSAocGFyYW1zKT0+e1xuICAgIHJldHVybiBuZXcgWm9kVW5kZWZpbmVkKHtcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RVbmRlZmluZWQsXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufTtcbmV4cG9ydCBjbGFzcyBab2ROdWxsIGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHBhcnNlZFR5cGUgPSB0aGlzLl9nZXRUeXBlKGlucHV0KTtcbiAgICAgICAgaWYgKHBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUubnVsbCkge1xuICAgICAgICAgICAgY29uc3QgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQpO1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSxcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5udWxsLFxuICAgICAgICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gT0soaW5wdXQuZGF0YSk7XG4gICAgfVxufVxuWm9kTnVsbC5jcmVhdGUgPSAocGFyYW1zKT0+e1xuICAgIHJldHVybiBuZXcgWm9kTnVsbCh7XG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kTnVsbCxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59O1xuZXhwb3J0IGNsYXNzIFpvZEFueSBleHRlbmRzIFpvZFR5cGUge1xuICAgIGNvbnN0cnVjdG9yKCl7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIC8vIHRvIHByZXZlbnQgaW5zdGFuY2VzIG9mIG90aGVyIGNsYXNzZXMgZnJvbSBleHRlbmRpbmcgWm9kQW55LiB0aGlzIGNhdXNlcyBpc3N1ZXMgd2l0aCBjYXRjaGFsbCBpbiBab2RPYmplY3QuXG4gICAgICAgIHRoaXMuX2FueSA9IHRydWU7XG4gICAgfVxuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICByZXR1cm4gT0soaW5wdXQuZGF0YSk7XG4gICAgfVxufVxuWm9kQW55LmNyZWF0ZSA9IChwYXJhbXMpPT57XG4gICAgcmV0dXJuIG5ldyBab2RBbnkoe1xuICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEFueSxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59O1xuZXhwb3J0IGNsYXNzIFpvZFVua25vd24gZXh0ZW5kcyBab2RUeXBlIHtcbiAgICBjb25zdHJ1Y3Rvcigpe1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICAvLyByZXF1aXJlZFxuICAgICAgICB0aGlzLl91bmtub3duID0gdHJ1ZTtcbiAgICB9XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIHJldHVybiBPSyhpbnB1dC5kYXRhKTtcbiAgICB9XG59XG5ab2RVbmtub3duLmNyZWF0ZSA9IChwYXJhbXMpPT57XG4gICAgcmV0dXJuIG5ldyBab2RVbmtub3duKHtcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RVbmtub3duLFxuICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn07XG5leHBvcnQgY2xhc3MgWm9kTmV2ZXIgZXh0ZW5kcyBab2RUeXBlIHtcbiAgICBfcGFyc2UoaW5wdXQpIHtcbiAgICAgICAgY29uc3QgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQpO1xuICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3R5cGUsXG4gICAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5uZXZlcixcbiAgICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgfVxufVxuWm9kTmV2ZXIuY3JlYXRlID0gKHBhcmFtcyk9PntcbiAgICByZXR1cm4gbmV3IFpvZE5ldmVyKHtcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2ROZXZlcixcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59O1xuZXhwb3J0IGNsYXNzIFpvZFZvaWQgZXh0ZW5kcyBab2RUeXBlIHtcbiAgICBfcGFyc2UoaW5wdXQpIHtcbiAgICAgICAgY29uc3QgcGFyc2VkVHlwZSA9IHRoaXMuX2dldFR5cGUoaW5wdXQpO1xuICAgICAgICBpZiAocGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS51bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTtcbiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3R5cGUsXG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IFpvZFBhcnNlZFR5cGUudm9pZCxcbiAgICAgICAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIE9LKGlucHV0LmRhdGEpO1xuICAgIH1cbn1cblpvZFZvaWQuY3JlYXRlID0gKHBhcmFtcyk9PntcbiAgICByZXR1cm4gbmV3IFpvZFZvaWQoe1xuICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZFZvaWQsXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufTtcbmV4cG9ydCBjbGFzcyBab2RBcnJheSBleHRlbmRzIFpvZFR5cGUge1xuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBjb25zdCB7IGN0eCwgc3RhdHVzIH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpO1xuICAgICAgICBjb25zdCBkZWYgPSB0aGlzLl9kZWY7XG4gICAgICAgIGlmIChjdHgucGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS5hcnJheSkge1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSxcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5hcnJheSxcbiAgICAgICAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRlZi5leGFjdExlbmd0aCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgY29uc3QgdG9vQmlnID0gY3R4LmRhdGEubGVuZ3RoID4gZGVmLmV4YWN0TGVuZ3RoLnZhbHVlO1xuICAgICAgICAgICAgY29uc3QgdG9vU21hbGwgPSBjdHguZGF0YS5sZW5ndGggPCBkZWYuZXhhY3RMZW5ndGgudmFsdWU7XG4gICAgICAgICAgICBpZiAodG9vQmlnIHx8IHRvb1NtYWxsKSB7XG4gICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgIGNvZGU6IHRvb0JpZyA/IFpvZElzc3VlQ29kZS50b29fYmlnIDogWm9kSXNzdWVDb2RlLnRvb19zbWFsbCxcbiAgICAgICAgICAgICAgICAgICAgbWluaW11bTogdG9vU21hbGwgPyBkZWYuZXhhY3RMZW5ndGgudmFsdWUgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgIG1heGltdW06IHRvb0JpZyA/IGRlZi5leGFjdExlbmd0aC52YWx1ZSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJhcnJheVwiLFxuICAgICAgICAgICAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGV4YWN0OiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBkZWYuZXhhY3RMZW5ndGgubWVzc2FnZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChkZWYubWluTGVuZ3RoICE9PSBudWxsKSB7XG4gICAgICAgICAgICBpZiAoY3R4LmRhdGEubGVuZ3RoIDwgZGVmLm1pbkxlbmd0aC52YWx1ZSkge1xuICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX3NtYWxsLFxuICAgICAgICAgICAgICAgICAgICBtaW5pbXVtOiBkZWYubWluTGVuZ3RoLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiBcImFycmF5XCIsXG4gICAgICAgICAgICAgICAgICAgIGluY2x1c2l2ZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgZXhhY3Q6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBkZWYubWluTGVuZ3RoLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoZGVmLm1heExlbmd0aCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKGN0eC5kYXRhLmxlbmd0aCA+IGRlZi5tYXhMZW5ndGgudmFsdWUpIHtcbiAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLnRvb19iaWcsXG4gICAgICAgICAgICAgICAgICAgIG1heGltdW06IGRlZi5tYXhMZW5ndGgudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IFwiYXJyYXlcIixcbiAgICAgICAgICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBleGFjdDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGRlZi5tYXhMZW5ndGgubWVzc2FnZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChjdHguY29tbW9uLmFzeW5jKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoW1xuICAgICAgICAgICAgICAgIC4uLmN0eC5kYXRhXG4gICAgICAgICAgICBdLm1hcCgoaXRlbSwgaSk9PntcbiAgICAgICAgICAgICAgICByZXR1cm4gZGVmLnR5cGUuX3BhcnNlQXN5bmMobmV3IFBhcnNlSW5wdXRMYXp5UGF0aChjdHgsIGl0ZW0sIGN0eC5wYXRoLCBpKSk7XG4gICAgICAgICAgICB9KSkudGhlbigocmVzdWx0KT0+e1xuICAgICAgICAgICAgICAgIHJldHVybiBQYXJzZVN0YXR1cy5tZXJnZUFycmF5KHN0YXR1cywgcmVzdWx0KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IFtcbiAgICAgICAgICAgIC4uLmN0eC5kYXRhXG4gICAgICAgIF0ubWFwKChpdGVtLCBpKT0+e1xuICAgICAgICAgICAgcmV0dXJuIGRlZi50eXBlLl9wYXJzZVN5bmMobmV3IFBhcnNlSW5wdXRMYXp5UGF0aChjdHgsIGl0ZW0sIGN0eC5wYXRoLCBpKSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gUGFyc2VTdGF0dXMubWVyZ2VBcnJheShzdGF0dXMsIHJlc3VsdCk7XG4gICAgfVxuICAgIGdldCBlbGVtZW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmLnR5cGU7XG4gICAgfVxuICAgIG1pbihtaW5MZW5ndGgsIG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBab2RBcnJheSh7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICBtaW5MZW5ndGg6IHtcbiAgICAgICAgICAgICAgICB2YWx1ZTogbWluTGVuZ3RoLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgbWF4KG1heExlbmd0aCwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gbmV3IFpvZEFycmF5KHtcbiAgICAgICAgICAgIC4uLnRoaXMuX2RlZixcbiAgICAgICAgICAgIG1heExlbmd0aDoge1xuICAgICAgICAgICAgICAgIHZhbHVlOiBtYXhMZW5ndGgsXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBsZW5ndGgobGVuLCBtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiBuZXcgWm9kQXJyYXkoe1xuICAgICAgICAgICAgLi4udGhpcy5fZGVmLFxuICAgICAgICAgICAgZXhhY3RMZW5ndGg6IHtcbiAgICAgICAgICAgICAgICB2YWx1ZTogbGVuLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgbm9uZW1wdHkobWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5taW4oMSwgbWVzc2FnZSk7XG4gICAgfVxufVxuWm9kQXJyYXkuY3JlYXRlID0gKHNjaGVtYSwgcGFyYW1zKT0+e1xuICAgIHJldHVybiBuZXcgWm9kQXJyYXkoe1xuICAgICAgICB0eXBlOiBzY2hlbWEsXG4gICAgICAgIG1pbkxlbmd0aDogbnVsbCxcbiAgICAgICAgbWF4TGVuZ3RoOiBudWxsLFxuICAgICAgICBleGFjdExlbmd0aDogbnVsbCxcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RBcnJheSxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59O1xuZnVuY3Rpb24gZGVlcFBhcnRpYWxpZnkoc2NoZW1hKSB7XG4gICAgaWYgKHNjaGVtYSBpbnN0YW5jZW9mIFpvZE9iamVjdCkge1xuICAgICAgICBjb25zdCBuZXdTaGFwZSA9IHt9O1xuICAgICAgICBmb3IoY29uc3Qga2V5IGluIHNjaGVtYS5zaGFwZSl7XG4gICAgICAgICAgICBjb25zdCBmaWVsZFNjaGVtYSA9IHNjaGVtYS5zaGFwZVtrZXldO1xuICAgICAgICAgICAgbmV3U2hhcGVba2V5XSA9IFpvZE9wdGlvbmFsLmNyZWF0ZShkZWVwUGFydGlhbGlmeShmaWVsZFNjaGVtYSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHtcbiAgICAgICAgICAgIC4uLnNjaGVtYS5fZGVmLFxuICAgICAgICAgICAgc2hhcGU6ICgpPT5uZXdTaGFwZVxuICAgICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHNjaGVtYSBpbnN0YW5jZW9mIFpvZEFycmF5KSB7XG4gICAgICAgIHJldHVybiBuZXcgWm9kQXJyYXkoe1xuICAgICAgICAgICAgLi4uc2NoZW1hLl9kZWYsXG4gICAgICAgICAgICB0eXBlOiBkZWVwUGFydGlhbGlmeShzY2hlbWEuZWxlbWVudClcbiAgICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChzY2hlbWEgaW5zdGFuY2VvZiBab2RPcHRpb25hbCkge1xuICAgICAgICByZXR1cm4gWm9kT3B0aW9uYWwuY3JlYXRlKGRlZXBQYXJ0aWFsaWZ5KHNjaGVtYS51bndyYXAoKSkpO1xuICAgIH0gZWxzZSBpZiAoc2NoZW1hIGluc3RhbmNlb2YgWm9kTnVsbGFibGUpIHtcbiAgICAgICAgcmV0dXJuIFpvZE51bGxhYmxlLmNyZWF0ZShkZWVwUGFydGlhbGlmeShzY2hlbWEudW53cmFwKCkpKTtcbiAgICB9IGVsc2UgaWYgKHNjaGVtYSBpbnN0YW5jZW9mIFpvZFR1cGxlKSB7XG4gICAgICAgIHJldHVybiBab2RUdXBsZS5jcmVhdGUoc2NoZW1hLml0ZW1zLm1hcCgoaXRlbSk9PmRlZXBQYXJ0aWFsaWZ5KGl0ZW0pKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHNjaGVtYTtcbiAgICB9XG59XG5leHBvcnQgY2xhc3MgWm9kT2JqZWN0IGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgY29uc3RydWN0b3IoKXtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5fY2FjaGVkID0gbnVsbDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBkZXByZWNhdGVkIEluIG1vc3QgY2FzZXMsIHRoaXMgaXMgbm8gbG9uZ2VyIG5lZWRlZCAtIHVua25vd24gcHJvcGVydGllcyBhcmUgbm93IHNpbGVudGx5IHN0cmlwcGVkLlxuICAgICAgICAgKiBJZiB5b3Ugd2FudCB0byBwYXNzIHRocm91Z2ggdW5rbm93biBwcm9wZXJ0aWVzLCB1c2UgYC5wYXNzdGhyb3VnaCgpYCBpbnN0ZWFkLlxuICAgICAgICAgKi8gdGhpcy5ub25zdHJpY3QgPSB0aGlzLnBhc3N0aHJvdWdoO1xuICAgICAgICAvLyBleHRlbmQ8XG4gICAgICAgIC8vICAgQXVnbWVudGF0aW9uIGV4dGVuZHMgWm9kUmF3U2hhcGUsXG4gICAgICAgIC8vICAgTmV3T3V0cHV0IGV4dGVuZHMgdXRpbC5mbGF0dGVuPHtcbiAgICAgICAgLy8gICAgIFtrIGluIGtleW9mIEF1Z21lbnRhdGlvbiB8IGtleW9mIE91dHB1dF06IGsgZXh0ZW5kcyBrZXlvZiBBdWdtZW50YXRpb25cbiAgICAgICAgLy8gICAgICAgPyBBdWdtZW50YXRpb25ba11bXCJfb3V0cHV0XCJdXG4gICAgICAgIC8vICAgICAgIDogayBleHRlbmRzIGtleW9mIE91dHB1dFxuICAgICAgICAvLyAgICAgICA/IE91dHB1dFtrXVxuICAgICAgICAvLyAgICAgICA6IG5ldmVyO1xuICAgICAgICAvLyAgIH0+LFxuICAgICAgICAvLyAgIE5ld0lucHV0IGV4dGVuZHMgdXRpbC5mbGF0dGVuPHtcbiAgICAgICAgLy8gICAgIFtrIGluIGtleW9mIEF1Z21lbnRhdGlvbiB8IGtleW9mIElucHV0XTogayBleHRlbmRzIGtleW9mIEF1Z21lbnRhdGlvblxuICAgICAgICAvLyAgICAgICA/IEF1Z21lbnRhdGlvbltrXVtcIl9pbnB1dFwiXVxuICAgICAgICAvLyAgICAgICA6IGsgZXh0ZW5kcyBrZXlvZiBJbnB1dFxuICAgICAgICAvLyAgICAgICA/IElucHV0W2tdXG4gICAgICAgIC8vICAgICAgIDogbmV2ZXI7XG4gICAgICAgIC8vICAgfT5cbiAgICAgICAgLy8gPihcbiAgICAgICAgLy8gICBhdWdtZW50YXRpb246IEF1Z21lbnRhdGlvblxuICAgICAgICAvLyApOiBab2RPYmplY3Q8XG4gICAgICAgIC8vICAgZXh0ZW5kU2hhcGU8VCwgQXVnbWVudGF0aW9uPixcbiAgICAgICAgLy8gICBVbmtub3duS2V5cyxcbiAgICAgICAgLy8gICBDYXRjaGFsbCxcbiAgICAgICAgLy8gICBOZXdPdXRwdXQsXG4gICAgICAgIC8vICAgTmV3SW5wdXRcbiAgICAgICAgLy8gPiB7XG4gICAgICAgIC8vICAgcmV0dXJuIG5ldyBab2RPYmplY3Qoe1xuICAgICAgICAvLyAgICAgLi4udGhpcy5fZGVmLFxuICAgICAgICAvLyAgICAgc2hhcGU6ICgpID0+ICh7XG4gICAgICAgIC8vICAgICAgIC4uLnRoaXMuX2RlZi5zaGFwZSgpLFxuICAgICAgICAvLyAgICAgICAuLi5hdWdtZW50YXRpb24sXG4gICAgICAgIC8vICAgICB9KSxcbiAgICAgICAgLy8gICB9KSBhcyBhbnk7XG4gICAgICAgIC8vIH1cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBkZXByZWNhdGVkIFVzZSBgLmV4dGVuZGAgaW5zdGVhZFxuICAgICAgICAgKiAgKi8gdGhpcy5hdWdtZW50ID0gdGhpcy5leHRlbmQ7XG4gICAgfVxuICAgIF9nZXRDYWNoZWQoKSB7XG4gICAgICAgIGlmICh0aGlzLl9jYWNoZWQgIT09IG51bGwpIHJldHVybiB0aGlzLl9jYWNoZWQ7XG4gICAgICAgIGNvbnN0IHNoYXBlID0gdGhpcy5fZGVmLnNoYXBlKCk7XG4gICAgICAgIGNvbnN0IGtleXMgPSB1dGlsLm9iamVjdEtleXMoc2hhcGUpO1xuICAgICAgICB0aGlzLl9jYWNoZWQgPSB7XG4gICAgICAgICAgICBzaGFwZSxcbiAgICAgICAgICAgIGtleXNcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlZDtcbiAgICB9XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHBhcnNlZFR5cGUgPSB0aGlzLl9nZXRUeXBlKGlucHV0KTtcbiAgICAgICAgaWYgKHBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUub2JqZWN0KSB7XG4gICAgICAgICAgICBjb25zdCBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7XG4gICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLm9iamVjdCxcbiAgICAgICAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgeyBzdGF0dXMsIGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTtcbiAgICAgICAgY29uc3QgeyBzaGFwZSwga2V5czogc2hhcGVLZXlzIH0gPSB0aGlzLl9nZXRDYWNoZWQoKTtcbiAgICAgICAgY29uc3QgZXh0cmFLZXlzID0gW107XG4gICAgICAgIGlmICghKHRoaXMuX2RlZi5jYXRjaGFsbCBpbnN0YW5jZW9mIFpvZE5ldmVyICYmIHRoaXMuX2RlZi51bmtub3duS2V5cyA9PT0gXCJzdHJpcFwiKSkge1xuICAgICAgICAgICAgZm9yKGNvbnN0IGtleSBpbiBjdHguZGF0YSl7XG4gICAgICAgICAgICAgICAgaWYgKCFzaGFwZUtleXMuaW5jbHVkZXMoa2V5KSkge1xuICAgICAgICAgICAgICAgICAgICBleHRyYUtleXMucHVzaChrZXkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwYWlycyA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBzaGFwZUtleXMpe1xuICAgICAgICAgICAgY29uc3Qga2V5VmFsaWRhdG9yID0gc2hhcGVba2V5XTtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gY3R4LmRhdGFba2V5XTtcbiAgICAgICAgICAgIHBhaXJzLnB1c2goe1xuICAgICAgICAgICAgICAgIGtleToge1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXM6IFwidmFsaWRcIixcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGtleVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdmFsdWU6IGtleVZhbGlkYXRvci5fcGFyc2UobmV3IFBhcnNlSW5wdXRMYXp5UGF0aChjdHgsIHZhbHVlLCBjdHgucGF0aCwga2V5KSksXG4gICAgICAgICAgICAgICAgYWx3YXlzU2V0OiBrZXkgaW4gY3R4LmRhdGFcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9kZWYuY2F0Y2hhbGwgaW5zdGFuY2VvZiBab2ROZXZlcikge1xuICAgICAgICAgICAgY29uc3QgdW5rbm93bktleXMgPSB0aGlzLl9kZWYudW5rbm93bktleXM7XG4gICAgICAgICAgICBpZiAodW5rbm93bktleXMgPT09IFwicGFzc3Rocm91Z2hcIikge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IG9mIGV4dHJhS2V5cyl7XG4gICAgICAgICAgICAgICAgICAgIHBhaXJzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAga2V5OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzOiBcInZhbGlkXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGtleVxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzOiBcInZhbGlkXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGN0eC5kYXRhW2tleV1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmICh1bmtub3duS2V5cyA9PT0gXCJzdHJpY3RcIikge1xuICAgICAgICAgICAgICAgIGlmIChleHRyYUtleXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS51bnJlY29nbml6ZWRfa2V5cyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleXM6IGV4dHJhS2V5c1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmICh1bmtub3duS2V5cyA9PT0gXCJzdHJpcFwiKSB7fSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludGVybmFsIFpvZE9iamVjdCBlcnJvcjogaW52YWxpZCB1bmtub3duS2V5cyB2YWx1ZS5gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIHJ1biBjYXRjaGFsbCB2YWxpZGF0aW9uXG4gICAgICAgICAgICBjb25zdCBjYXRjaGFsbCA9IHRoaXMuX2RlZi5jYXRjaGFsbDtcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IG9mIGV4dHJhS2V5cyl7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBjdHguZGF0YVtrZXldO1xuICAgICAgICAgICAgICAgIHBhaXJzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBrZXk6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1czogXCJ2YWxpZFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGtleVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogY2F0Y2hhbGwuX3BhcnNlKG5ldyBQYXJzZUlucHV0TGF6eVBhdGgoY3R4LCB2YWx1ZSwgY3R4LnBhdGgsIGtleSkgLy8sIGN0eC5jaGlsZChrZXkpLCB2YWx1ZSwgZ2V0UGFyc2VkVHlwZSh2YWx1ZSlcbiAgICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgICAgYWx3YXlzU2V0OiBrZXkgaW4gY3R4LmRhdGFcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoY3R4LmNvbW1vbi5hc3luYykge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpLnRoZW4oYXN5bmMgKCk9PntcbiAgICAgICAgICAgICAgICBjb25zdCBzeW5jUGFpcnMgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHBhaXIgb2YgcGFpcnMpe1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBrZXkgPSBhd2FpdCBwYWlyLmtleTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBhd2FpdCBwYWlyLnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICBzeW5jUGFpcnMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGFsd2F5c1NldDogcGFpci5hbHdheXNTZXRcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBzeW5jUGFpcnM7XG4gICAgICAgICAgICB9KS50aGVuKChzeW5jUGFpcnMpPT57XG4gICAgICAgICAgICAgICAgcmV0dXJuIFBhcnNlU3RhdHVzLm1lcmdlT2JqZWN0U3luYyhzdGF0dXMsIHN5bmNQYWlycyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBQYXJzZVN0YXR1cy5tZXJnZU9iamVjdFN5bmMoc3RhdHVzLCBwYWlycyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IHNoYXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmLnNoYXBlKCk7XG4gICAgfVxuICAgIHN0cmljdChtZXNzYWdlKSB7XG4gICAgICAgIGVycm9yVXRpbC5lcnJUb09iajtcbiAgICAgICAgcmV0dXJuIG5ldyBab2RPYmplY3Qoe1xuICAgICAgICAgICAgLi4udGhpcy5fZGVmLFxuICAgICAgICAgICAgdW5rbm93bktleXM6IFwic3RyaWN0XCIsXG4gICAgICAgICAgICAuLi5tZXNzYWdlICE9PSB1bmRlZmluZWQgPyB7XG4gICAgICAgICAgICAgICAgZXJyb3JNYXA6IChpc3N1ZSwgY3R4KT0+e1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWZhdWx0RXJyb3IgPSB0aGlzLl9kZWYuZXJyb3JNYXA/Lihpc3N1ZSwgY3R4KS5tZXNzYWdlID8/IGN0eC5kZWZhdWx0RXJyb3I7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc3N1ZS5jb2RlID09PSBcInVucmVjb2duaXplZF9rZXlzXCIpIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSkubWVzc2FnZSA/PyBkZWZhdWx0RXJyb3JcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGRlZmF1bHRFcnJvclxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gOiB7fVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgc3RyaXAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHtcbiAgICAgICAgICAgIC4uLnRoaXMuX2RlZixcbiAgICAgICAgICAgIHVua25vd25LZXlzOiBcInN0cmlwXCJcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHBhc3N0aHJvdWdoKCkge1xuICAgICAgICByZXR1cm4gbmV3IFpvZE9iamVjdCh7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICB1bmtub3duS2V5czogXCJwYXNzdGhyb3VnaFwiXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvLyBjb25zdCBBdWdtZW50RmFjdG9yeSA9XG4gICAgLy8gICA8RGVmIGV4dGVuZHMgWm9kT2JqZWN0RGVmPihkZWY6IERlZikgPT5cbiAgICAvLyAgIDxBdWdtZW50YXRpb24gZXh0ZW5kcyBab2RSYXdTaGFwZT4oXG4gICAgLy8gICAgIGF1Z21lbnRhdGlvbjogQXVnbWVudGF0aW9uXG4gICAgLy8gICApOiBab2RPYmplY3Q8XG4gICAgLy8gICAgIGV4dGVuZFNoYXBlPFJldHVyblR5cGU8RGVmW1wic2hhcGVcIl0+LCBBdWdtZW50YXRpb24+LFxuICAgIC8vICAgICBEZWZbXCJ1bmtub3duS2V5c1wiXSxcbiAgICAvLyAgICAgRGVmW1wiY2F0Y2hhbGxcIl1cbiAgICAvLyAgID4gPT4ge1xuICAgIC8vICAgICByZXR1cm4gbmV3IFpvZE9iamVjdCh7XG4gICAgLy8gICAgICAgLi4uZGVmLFxuICAgIC8vICAgICAgIHNoYXBlOiAoKSA9PiAoe1xuICAgIC8vICAgICAgICAgLi4uZGVmLnNoYXBlKCksXG4gICAgLy8gICAgICAgICAuLi5hdWdtZW50YXRpb24sXG4gICAgLy8gICAgICAgfSksXG4gICAgLy8gICAgIH0pIGFzIGFueTtcbiAgICAvLyAgIH07XG4gICAgZXh0ZW5kKGF1Z21lbnRhdGlvbikge1xuICAgICAgICByZXR1cm4gbmV3IFpvZE9iamVjdCh7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICBzaGFwZTogKCk9Pih7XG4gICAgICAgICAgICAgICAgICAgIC4uLnRoaXMuX2RlZi5zaGFwZSgpLFxuICAgICAgICAgICAgICAgICAgICAuLi5hdWdtZW50YXRpb25cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUHJpb3IgdG8gem9kQDEuMC4xMiB0aGVyZSB3YXMgYSBidWcgaW4gdGhlXG4gICAgICogaW5mZXJyZWQgdHlwZSBvZiBtZXJnZWQgb2JqZWN0cy4gUGxlYXNlXG4gICAgICogdXBncmFkZSBpZiB5b3UgYXJlIGV4cGVyaWVuY2luZyBpc3N1ZXMuXG4gICAgICovIG1lcmdlKG1lcmdpbmcpIHtcbiAgICAgICAgY29uc3QgbWVyZ2VkID0gbmV3IFpvZE9iamVjdCh7XG4gICAgICAgICAgICB1bmtub3duS2V5czogbWVyZ2luZy5fZGVmLnVua25vd25LZXlzLFxuICAgICAgICAgICAgY2F0Y2hhbGw6IG1lcmdpbmcuX2RlZi5jYXRjaGFsbCxcbiAgICAgICAgICAgIHNoYXBlOiAoKT0+KHtcbiAgICAgICAgICAgICAgICAgICAgLi4udGhpcy5fZGVmLnNoYXBlKCksXG4gICAgICAgICAgICAgICAgICAgIC4uLm1lcmdpbmcuX2RlZi5zaGFwZSgpXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE9iamVjdFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG1lcmdlZDtcbiAgICB9XG4gICAgLy8gbWVyZ2U8XG4gICAgLy8gICBJbmNvbWluZyBleHRlbmRzIEFueVpvZE9iamVjdCxcbiAgICAvLyAgIEF1Z21lbnRhdGlvbiBleHRlbmRzIEluY29taW5nW1wic2hhcGVcIl0sXG4gICAgLy8gICBOZXdPdXRwdXQgZXh0ZW5kcyB7XG4gICAgLy8gICAgIFtrIGluIGtleW9mIEF1Z21lbnRhdGlvbiB8IGtleW9mIE91dHB1dF06IGsgZXh0ZW5kcyBrZXlvZiBBdWdtZW50YXRpb25cbiAgICAvLyAgICAgICA/IEF1Z21lbnRhdGlvbltrXVtcIl9vdXRwdXRcIl1cbiAgICAvLyAgICAgICA6IGsgZXh0ZW5kcyBrZXlvZiBPdXRwdXRcbiAgICAvLyAgICAgICA/IE91dHB1dFtrXVxuICAgIC8vICAgICAgIDogbmV2ZXI7XG4gICAgLy8gICB9LFxuICAgIC8vICAgTmV3SW5wdXQgZXh0ZW5kcyB7XG4gICAgLy8gICAgIFtrIGluIGtleW9mIEF1Z21lbnRhdGlvbiB8IGtleW9mIElucHV0XTogayBleHRlbmRzIGtleW9mIEF1Z21lbnRhdGlvblxuICAgIC8vICAgICAgID8gQXVnbWVudGF0aW9uW2tdW1wiX2lucHV0XCJdXG4gICAgLy8gICAgICAgOiBrIGV4dGVuZHMga2V5b2YgSW5wdXRcbiAgICAvLyAgICAgICA/IElucHV0W2tdXG4gICAgLy8gICAgICAgOiBuZXZlcjtcbiAgICAvLyAgIH1cbiAgICAvLyA+KFxuICAgIC8vICAgbWVyZ2luZzogSW5jb21pbmdcbiAgICAvLyApOiBab2RPYmplY3Q8XG4gICAgLy8gICBleHRlbmRTaGFwZTxULCBSZXR1cm5UeXBlPEluY29taW5nW1wiX2RlZlwiXVtcInNoYXBlXCJdPj4sXG4gICAgLy8gICBJbmNvbWluZ1tcIl9kZWZcIl1bXCJ1bmtub3duS2V5c1wiXSxcbiAgICAvLyAgIEluY29taW5nW1wiX2RlZlwiXVtcImNhdGNoYWxsXCJdLFxuICAgIC8vICAgTmV3T3V0cHV0LFxuICAgIC8vICAgTmV3SW5wdXRcbiAgICAvLyA+IHtcbiAgICAvLyAgIGNvbnN0IG1lcmdlZDogYW55ID0gbmV3IFpvZE9iamVjdCh7XG4gICAgLy8gICAgIHVua25vd25LZXlzOiBtZXJnaW5nLl9kZWYudW5rbm93bktleXMsXG4gICAgLy8gICAgIGNhdGNoYWxsOiBtZXJnaW5nLl9kZWYuY2F0Y2hhbGwsXG4gICAgLy8gICAgIHNoYXBlOiAoKSA9PlxuICAgIC8vICAgICAgIG9iamVjdFV0aWwubWVyZ2VTaGFwZXModGhpcy5fZGVmLnNoYXBlKCksIG1lcmdpbmcuX2RlZi5zaGFwZSgpKSxcbiAgICAvLyAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RPYmplY3QsXG4gICAgLy8gICB9KSBhcyBhbnk7XG4gICAgLy8gICByZXR1cm4gbWVyZ2VkO1xuICAgIC8vIH1cbiAgICBzZXRLZXkoa2V5LCBzY2hlbWEpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXVnbWVudCh7XG4gICAgICAgICAgICBba2V5XTogc2NoZW1hXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvLyBtZXJnZTxJbmNvbWluZyBleHRlbmRzIEFueVpvZE9iamVjdD4oXG4gICAgLy8gICBtZXJnaW5nOiBJbmNvbWluZ1xuICAgIC8vICk6IC8vWm9kT2JqZWN0PFQgJiBJbmNvbWluZ1tcIl9zaGFwZVwiXSwgVW5rbm93bktleXMsIENhdGNoYWxsPiA9IChtZXJnaW5nKSA9PiB7XG4gICAgLy8gWm9kT2JqZWN0PFxuICAgIC8vICAgZXh0ZW5kU2hhcGU8VCwgUmV0dXJuVHlwZTxJbmNvbWluZ1tcIl9kZWZcIl1bXCJzaGFwZVwiXT4+LFxuICAgIC8vICAgSW5jb21pbmdbXCJfZGVmXCJdW1widW5rbm93bktleXNcIl0sXG4gICAgLy8gICBJbmNvbWluZ1tcIl9kZWZcIl1bXCJjYXRjaGFsbFwiXVxuICAgIC8vID4ge1xuICAgIC8vICAgLy8gY29uc3QgbWVyZ2VkU2hhcGUgPSBvYmplY3RVdGlsLm1lcmdlU2hhcGVzKFxuICAgIC8vICAgLy8gICB0aGlzLl9kZWYuc2hhcGUoKSxcbiAgICAvLyAgIC8vICAgbWVyZ2luZy5fZGVmLnNoYXBlKClcbiAgICAvLyAgIC8vICk7XG4gICAgLy8gICBjb25zdCBtZXJnZWQ6IGFueSA9IG5ldyBab2RPYmplY3Qoe1xuICAgIC8vICAgICB1bmtub3duS2V5czogbWVyZ2luZy5fZGVmLnVua25vd25LZXlzLFxuICAgIC8vICAgICBjYXRjaGFsbDogbWVyZ2luZy5fZGVmLmNhdGNoYWxsLFxuICAgIC8vICAgICBzaGFwZTogKCkgPT5cbiAgICAvLyAgICAgICBvYmplY3RVdGlsLm1lcmdlU2hhcGVzKHRoaXMuX2RlZi5zaGFwZSgpLCBtZXJnaW5nLl9kZWYuc2hhcGUoKSksXG4gICAgLy8gICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kT2JqZWN0LFxuICAgIC8vICAgfSkgYXMgYW55O1xuICAgIC8vICAgcmV0dXJuIG1lcmdlZDtcbiAgICAvLyB9XG4gICAgY2F0Y2hhbGwoaW5kZXgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBab2RPYmplY3Qoe1xuICAgICAgICAgICAgLi4udGhpcy5fZGVmLFxuICAgICAgICAgICAgY2F0Y2hhbGw6IGluZGV4XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBwaWNrKG1hc2spIHtcbiAgICAgICAgY29uc3Qgc2hhcGUgPSB7fTtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgdXRpbC5vYmplY3RLZXlzKG1hc2spKXtcbiAgICAgICAgICAgIGlmIChtYXNrW2tleV0gJiYgdGhpcy5zaGFwZVtrZXldKSB7XG4gICAgICAgICAgICAgICAgc2hhcGVba2V5XSA9IHRoaXMuc2hhcGVba2V5XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFpvZE9iamVjdCh7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICBzaGFwZTogKCk9PnNoYXBlXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBvbWl0KG1hc2spIHtcbiAgICAgICAgY29uc3Qgc2hhcGUgPSB7fTtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgdXRpbC5vYmplY3RLZXlzKHRoaXMuc2hhcGUpKXtcbiAgICAgICAgICAgIGlmICghbWFza1trZXldKSB7XG4gICAgICAgICAgICAgICAgc2hhcGVba2V5XSA9IHRoaXMuc2hhcGVba2V5XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFpvZE9iamVjdCh7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICBzaGFwZTogKCk9PnNoYXBlXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBAZGVwcmVjYXRlZFxuICAgICAqLyBkZWVwUGFydGlhbCgpIHtcbiAgICAgICAgcmV0dXJuIGRlZXBQYXJ0aWFsaWZ5KHRoaXMpO1xuICAgIH1cbiAgICBwYXJ0aWFsKG1hc2spIHtcbiAgICAgICAgY29uc3QgbmV3U2hhcGUgPSB7fTtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgdXRpbC5vYmplY3RLZXlzKHRoaXMuc2hhcGUpKXtcbiAgICAgICAgICAgIGNvbnN0IGZpZWxkU2NoZW1hID0gdGhpcy5zaGFwZVtrZXldO1xuICAgICAgICAgICAgaWYgKG1hc2sgJiYgIW1hc2tba2V5XSkge1xuICAgICAgICAgICAgICAgIG5ld1NoYXBlW2tleV0gPSBmaWVsZFNjaGVtYTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbmV3U2hhcGVba2V5XSA9IGZpZWxkU2NoZW1hLm9wdGlvbmFsKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBab2RPYmplY3Qoe1xuICAgICAgICAgICAgLi4udGhpcy5fZGVmLFxuICAgICAgICAgICAgc2hhcGU6ICgpPT5uZXdTaGFwZVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmVxdWlyZWQobWFzaykge1xuICAgICAgICBjb25zdCBuZXdTaGFwZSA9IHt9O1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiB1dGlsLm9iamVjdEtleXModGhpcy5zaGFwZSkpe1xuICAgICAgICAgICAgaWYgKG1hc2sgJiYgIW1hc2tba2V5XSkge1xuICAgICAgICAgICAgICAgIG5ld1NoYXBlW2tleV0gPSB0aGlzLnNoYXBlW2tleV07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IGZpZWxkU2NoZW1hID0gdGhpcy5zaGFwZVtrZXldO1xuICAgICAgICAgICAgICAgIGxldCBuZXdGaWVsZCA9IGZpZWxkU2NoZW1hO1xuICAgICAgICAgICAgICAgIHdoaWxlKG5ld0ZpZWxkIGluc3RhbmNlb2YgWm9kT3B0aW9uYWwpe1xuICAgICAgICAgICAgICAgICAgICBuZXdGaWVsZCA9IG5ld0ZpZWxkLl9kZWYuaW5uZXJUeXBlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBuZXdTaGFwZVtrZXldID0gbmV3RmllbGQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBab2RPYmplY3Qoe1xuICAgICAgICAgICAgLi4udGhpcy5fZGVmLFxuICAgICAgICAgICAgc2hhcGU6ICgpPT5uZXdTaGFwZVxuICAgICAgICB9KTtcbiAgICB9XG4gICAga2V5b2YoKSB7XG4gICAgICAgIHJldHVybiBjcmVhdGVab2RFbnVtKHV0aWwub2JqZWN0S2V5cyh0aGlzLnNoYXBlKSk7XG4gICAgfVxufVxuWm9kT2JqZWN0LmNyZWF0ZSA9IChzaGFwZSwgcGFyYW1zKT0+e1xuICAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHtcbiAgICAgICAgc2hhcGU6ICgpPT5zaGFwZSxcbiAgICAgICAgdW5rbm93bktleXM6IFwic3RyaXBcIixcbiAgICAgICAgY2F0Y2hhbGw6IFpvZE5ldmVyLmNyZWF0ZSgpLFxuICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE9iamVjdCxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59O1xuWm9kT2JqZWN0LnN0cmljdENyZWF0ZSA9IChzaGFwZSwgcGFyYW1zKT0+e1xuICAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHtcbiAgICAgICAgc2hhcGU6ICgpPT5zaGFwZSxcbiAgICAgICAgdW5rbm93bktleXM6IFwic3RyaWN0XCIsXG4gICAgICAgIGNhdGNoYWxsOiBab2ROZXZlci5jcmVhdGUoKSxcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RPYmplY3QsXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufTtcblpvZE9iamVjdC5sYXp5Y3JlYXRlID0gKHNoYXBlLCBwYXJhbXMpPT57XG4gICAgcmV0dXJuIG5ldyBab2RPYmplY3Qoe1xuICAgICAgICBzaGFwZSxcbiAgICAgICAgdW5rbm93bktleXM6IFwic3RyaXBcIixcbiAgICAgICAgY2F0Y2hhbGw6IFpvZE5ldmVyLmNyZWF0ZSgpLFxuICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE9iamVjdCxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59O1xuZXhwb3J0IGNsYXNzIFpvZFVuaW9uIGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5fZGVmLm9wdGlvbnM7XG4gICAgICAgIGZ1bmN0aW9uIGhhbmRsZVJlc3VsdHMocmVzdWx0cykge1xuICAgICAgICAgICAgLy8gcmV0dXJuIGZpcnN0IGlzc3VlLWZyZWUgdmFsaWRhdGlvbiBpZiBpdCBleGlzdHNcbiAgICAgICAgICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIHJlc3VsdHMpe1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQucmVzdWx0LnN0YXR1cyA9PT0gXCJ2YWxpZFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQucmVzdWx0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIHJlc3VsdHMpe1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQucmVzdWx0LnN0YXR1cyA9PT0gXCJkaXJ0eVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGFkZCBpc3N1ZXMgZnJvbSBkaXJ0eSBvcHRpb25cbiAgICAgICAgICAgICAgICAgICAgY3R4LmNvbW1vbi5pc3N1ZXMucHVzaCguLi5yZXN1bHQuY3R4LmNvbW1vbi5pc3N1ZXMpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0LnJlc3VsdDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyByZXR1cm4gaW52YWxpZFxuICAgICAgICAgICAgY29uc3QgdW5pb25FcnJvcnMgPSByZXN1bHRzLm1hcCgocmVzdWx0KT0+bmV3IFpvZEVycm9yKHJlc3VsdC5jdHguY29tbW9uLmlzc3VlcykpO1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdW5pb24sXG4gICAgICAgICAgICAgICAgdW5pb25FcnJvcnNcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChvcHRpb25zLm1hcChhc3luYyAob3B0aW9uKT0+e1xuICAgICAgICAgICAgICAgIGNvbnN0IGNoaWxkQ3R4ID0ge1xuICAgICAgICAgICAgICAgICAgICAuLi5jdHgsXG4gICAgICAgICAgICAgICAgICAgIGNvbW1vbjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgLi4uY3R4LmNvbW1vbixcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzc3VlczogW11cbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgcGFyZW50OiBudWxsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQ6IGF3YWl0IG9wdGlvbi5fcGFyc2VBc3luYyh7XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhOiBjdHguZGF0YSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50OiBjaGlsZEN0eFxuICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgY3R4OiBjaGlsZEN0eFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9KSkudGhlbihoYW5kbGVSZXN1bHRzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxldCBkaXJ0eSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGNvbnN0IGlzc3VlcyA9IFtdO1xuICAgICAgICAgICAgZm9yIChjb25zdCBvcHRpb24gb2Ygb3B0aW9ucyl7XG4gICAgICAgICAgICAgICAgY29uc3QgY2hpbGRDdHggPSB7XG4gICAgICAgICAgICAgICAgICAgIC4uLmN0eCxcbiAgICAgICAgICAgICAgICAgICAgY29tbW9uOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAuLi5jdHguY29tbW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgaXNzdWVzOiBbXVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IG51bGxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IG9wdGlvbi5fcGFyc2VTeW5jKHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YTogY3R4LmRhdGEsXG4gICAgICAgICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IGNoaWxkQ3R4XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5zdGF0dXMgPT09IFwidmFsaWRcIikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocmVzdWx0LnN0YXR1cyA9PT0gXCJkaXJ0eVwiICYmICFkaXJ0eSkge1xuICAgICAgICAgICAgICAgICAgICBkaXJ0eSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGN0eDogY2hpbGRDdHhcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGNoaWxkQ3R4LmNvbW1vbi5pc3N1ZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIGlzc3Vlcy5wdXNoKGNoaWxkQ3R4LmNvbW1vbi5pc3N1ZXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChkaXJ0eSkge1xuICAgICAgICAgICAgICAgIGN0eC5jb21tb24uaXNzdWVzLnB1c2goLi4uZGlydHkuY3R4LmNvbW1vbi5pc3N1ZXMpO1xuICAgICAgICAgICAgICAgIHJldHVybiBkaXJ0eS5yZXN1bHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCB1bmlvbkVycm9ycyA9IGlzc3Vlcy5tYXAoKGlzc3Vlcyk9Pm5ldyBab2RFcnJvcihpc3N1ZXMpKTtcbiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3VuaW9uLFxuICAgICAgICAgICAgICAgIHVuaW9uRXJyb3JzXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICB9XG4gICAgfVxuICAgIGdldCBvcHRpb25zKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmLm9wdGlvbnM7XG4gICAgfVxufVxuWm9kVW5pb24uY3JlYXRlID0gKHR5cGVzLCBwYXJhbXMpPT57XG4gICAgcmV0dXJuIG5ldyBab2RVbmlvbih7XG4gICAgICAgIG9wdGlvbnM6IHR5cGVzLFxuICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZFVuaW9uLFxuICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn07XG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vLy8vLy8vLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLy8vLy8vLy8vXG4vLy8vLy8vLy8vICAgICAgWm9kRGlzY3JpbWluYXRlZFVuaW9uICAgICAgLy8vLy8vLy8vL1xuLy8vLy8vLy8vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vLy8vLy8vLy9cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuY29uc3QgZ2V0RGlzY3JpbWluYXRvciA9ICh0eXBlKT0+e1xuICAgIGlmICh0eXBlIGluc3RhbmNlb2YgWm9kTGF6eSkge1xuICAgICAgICByZXR1cm4gZ2V0RGlzY3JpbWluYXRvcih0eXBlLnNjaGVtYSk7XG4gICAgfSBlbHNlIGlmICh0eXBlIGluc3RhbmNlb2YgWm9kRWZmZWN0cykge1xuICAgICAgICByZXR1cm4gZ2V0RGlzY3JpbWluYXRvcih0eXBlLmlubmVyVHlwZSgpKTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgaW5zdGFuY2VvZiBab2RMaXRlcmFsKSB7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICB0eXBlLnZhbHVlXG4gICAgICAgIF07XG4gICAgfSBlbHNlIGlmICh0eXBlIGluc3RhbmNlb2YgWm9kRW51bSkge1xuICAgICAgICByZXR1cm4gdHlwZS5vcHRpb25zO1xuICAgIH0gZWxzZSBpZiAodHlwZSBpbnN0YW5jZW9mIFpvZE5hdGl2ZUVudW0pIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGJhbi9iYW5cbiAgICAgICAgcmV0dXJuIHV0aWwub2JqZWN0VmFsdWVzKHR5cGUuZW51bSk7XG4gICAgfSBlbHNlIGlmICh0eXBlIGluc3RhbmNlb2YgWm9kRGVmYXVsdCkge1xuICAgICAgICByZXR1cm4gZ2V0RGlzY3JpbWluYXRvcih0eXBlLl9kZWYuaW5uZXJUeXBlKTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgaW5zdGFuY2VvZiBab2RVbmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIHVuZGVmaW5lZFxuICAgICAgICBdO1xuICAgIH0gZWxzZSBpZiAodHlwZSBpbnN0YW5jZW9mIFpvZE51bGwpIHtcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIG51bGxcbiAgICAgICAgXTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgaW5zdGFuY2VvZiBab2RPcHRpb25hbCkge1xuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgLi4uZ2V0RGlzY3JpbWluYXRvcih0eXBlLnVud3JhcCgpKVxuICAgICAgICBdO1xuICAgIH0gZWxzZSBpZiAodHlwZSBpbnN0YW5jZW9mIFpvZE51bGxhYmxlKSB7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgLi4uZ2V0RGlzY3JpbWluYXRvcih0eXBlLnVud3JhcCgpKVxuICAgICAgICBdO1xuICAgIH0gZWxzZSBpZiAodHlwZSBpbnN0YW5jZW9mIFpvZEJyYW5kZWQpIHtcbiAgICAgICAgcmV0dXJuIGdldERpc2NyaW1pbmF0b3IodHlwZS51bndyYXAoKSk7XG4gICAgfSBlbHNlIGlmICh0eXBlIGluc3RhbmNlb2YgWm9kUmVhZG9ubHkpIHtcbiAgICAgICAgcmV0dXJuIGdldERpc2NyaW1pbmF0b3IodHlwZS51bndyYXAoKSk7XG4gICAgfSBlbHNlIGlmICh0eXBlIGluc3RhbmNlb2YgWm9kQ2F0Y2gpIHtcbiAgICAgICAgcmV0dXJuIGdldERpc2NyaW1pbmF0b3IodHlwZS5fZGVmLmlubmVyVHlwZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbn07XG5leHBvcnQgY2xhc3MgWm9kRGlzY3JpbWluYXRlZFVuaW9uIGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpO1xuICAgICAgICBpZiAoY3R4LnBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUub2JqZWN0KSB7XG4gICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLm9iamVjdCxcbiAgICAgICAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZGlzY3JpbWluYXRvciA9IHRoaXMuZGlzY3JpbWluYXRvcjtcbiAgICAgICAgY29uc3QgZGlzY3JpbWluYXRvclZhbHVlID0gY3R4LmRhdGFbZGlzY3JpbWluYXRvcl07XG4gICAgICAgIGNvbnN0IG9wdGlvbiA9IHRoaXMub3B0aW9uc01hcC5nZXQoZGlzY3JpbWluYXRvclZhbHVlKTtcbiAgICAgICAgaWYgKCFvcHRpb24pIHtcbiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3VuaW9uX2Rpc2NyaW1pbmF0b3IsXG4gICAgICAgICAgICAgICAgb3B0aW9uczogQXJyYXkuZnJvbSh0aGlzLm9wdGlvbnNNYXAua2V5cygpKSxcbiAgICAgICAgICAgICAgICBwYXRoOiBbXG4gICAgICAgICAgICAgICAgICAgIGRpc2NyaW1pbmF0b3JcbiAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjdHguY29tbW9uLmFzeW5jKSB7XG4gICAgICAgICAgICByZXR1cm4gb3B0aW9uLl9wYXJzZUFzeW5jKHtcbiAgICAgICAgICAgICAgICBkYXRhOiBjdHguZGF0YSxcbiAgICAgICAgICAgICAgICBwYXRoOiBjdHgucGF0aCxcbiAgICAgICAgICAgICAgICBwYXJlbnQ6IGN0eFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gb3B0aW9uLl9wYXJzZVN5bmMoe1xuICAgICAgICAgICAgICAgIGRhdGE6IGN0eC5kYXRhLFxuICAgICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgICAgIHBhcmVudDogY3R4XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgZGlzY3JpbWluYXRvcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi5kaXNjcmltaW5hdG9yO1xuICAgIH1cbiAgICBnZXQgb3B0aW9ucygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi5vcHRpb25zO1xuICAgIH1cbiAgICBnZXQgb3B0aW9uc01hcCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi5vcHRpb25zTWFwO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgY29uc3RydWN0b3Igb2YgdGhlIGRpc2NyaW1pbmF0ZWQgdW5pb24gc2NoZW1hLiBJdHMgYmVoYXZpb3VyIGlzIHZlcnkgc2ltaWxhciB0byB0aGF0IG9mIHRoZSBub3JtYWwgei51bmlvbigpIGNvbnN0cnVjdG9yLlxuICAgICAqIEhvd2V2ZXIsIGl0IG9ubHkgYWxsb3dzIGEgdW5pb24gb2Ygb2JqZWN0cywgYWxsIG9mIHdoaWNoIG5lZWQgdG8gc2hhcmUgYSBkaXNjcmltaW5hdG9yIHByb3BlcnR5LiBUaGlzIHByb3BlcnR5IG11c3RcbiAgICAgKiBoYXZlIGEgZGlmZmVyZW50IHZhbHVlIGZvciBlYWNoIG9iamVjdCBpbiB0aGUgdW5pb24uXG4gICAgICogQHBhcmFtIGRpc2NyaW1pbmF0b3IgdGhlIG5hbWUgb2YgdGhlIGRpc2NyaW1pbmF0b3IgcHJvcGVydHlcbiAgICAgKiBAcGFyYW0gdHlwZXMgYW4gYXJyYXkgb2Ygb2JqZWN0IHNjaGVtYXNcbiAgICAgKiBAcGFyYW0gcGFyYW1zXG4gICAgICovIHN0YXRpYyBjcmVhdGUoZGlzY3JpbWluYXRvciwgb3B0aW9ucywgcGFyYW1zKSB7XG4gICAgICAgIC8vIEdldCBhbGwgdGhlIHZhbGlkIGRpc2NyaW1pbmF0b3IgdmFsdWVzXG4gICAgICAgIGNvbnN0IG9wdGlvbnNNYXAgPSBuZXcgTWFwKCk7XG4gICAgICAgIC8vIHRyeSB7XG4gICAgICAgIGZvciAoY29uc3QgdHlwZSBvZiBvcHRpb25zKXtcbiAgICAgICAgICAgIGNvbnN0IGRpc2NyaW1pbmF0b3JWYWx1ZXMgPSBnZXREaXNjcmltaW5hdG9yKHR5cGUuc2hhcGVbZGlzY3JpbWluYXRvcl0pO1xuICAgICAgICAgICAgaWYgKCFkaXNjcmltaW5hdG9yVmFsdWVzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQSBkaXNjcmltaW5hdG9yIHZhbHVlIGZvciBrZXkgXFxgJHtkaXNjcmltaW5hdG9yfVxcYCBjb3VsZCBub3QgYmUgZXh0cmFjdGVkIGZyb20gYWxsIHNjaGVtYSBvcHRpb25zYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHZhbHVlIG9mIGRpc2NyaW1pbmF0b3JWYWx1ZXMpe1xuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zTWFwLmhhcyh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBEaXNjcmltaW5hdG9yIHByb3BlcnR5ICR7U3RyaW5nKGRpc2NyaW1pbmF0b3IpfSBoYXMgZHVwbGljYXRlIHZhbHVlICR7U3RyaW5nKHZhbHVlKX1gKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgb3B0aW9uc01hcC5zZXQodmFsdWUsIHR5cGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgWm9kRGlzY3JpbWluYXRlZFVuaW9uKHtcbiAgICAgICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kRGlzY3JpbWluYXRlZFVuaW9uLFxuICAgICAgICAgICAgZGlzY3JpbWluYXRvcixcbiAgICAgICAgICAgIG9wdGlvbnMsXG4gICAgICAgICAgICBvcHRpb25zTWFwLFxuICAgICAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgICAgIH0pO1xuICAgIH1cbn1cbmZ1bmN0aW9uIG1lcmdlVmFsdWVzKGEsIGIpIHtcbiAgICBjb25zdCBhVHlwZSA9IGdldFBhcnNlZFR5cGUoYSk7XG4gICAgY29uc3QgYlR5cGUgPSBnZXRQYXJzZWRUeXBlKGIpO1xuICAgIGlmIChhID09PSBiKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWxpZDogdHJ1ZSxcbiAgICAgICAgICAgIGRhdGE6IGFcbiAgICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKGFUeXBlID09PSBab2RQYXJzZWRUeXBlLm9iamVjdCAmJiBiVHlwZSA9PT0gWm9kUGFyc2VkVHlwZS5vYmplY3QpIHtcbiAgICAgICAgY29uc3QgYktleXMgPSB1dGlsLm9iamVjdEtleXMoYik7XG4gICAgICAgIGNvbnN0IHNoYXJlZEtleXMgPSB1dGlsLm9iamVjdEtleXMoYSkuZmlsdGVyKChrZXkpPT5iS2V5cy5pbmRleE9mKGtleSkgIT09IC0xKTtcbiAgICAgICAgY29uc3QgbmV3T2JqID0ge1xuICAgICAgICAgICAgLi4uYSxcbiAgICAgICAgICAgIC4uLmJcbiAgICAgICAgfTtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2Ygc2hhcmVkS2V5cyl7XG4gICAgICAgICAgICBjb25zdCBzaGFyZWRWYWx1ZSA9IG1lcmdlVmFsdWVzKGFba2V5XSwgYltrZXldKTtcbiAgICAgICAgICAgIGlmICghc2hhcmVkVmFsdWUudmFsaWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICB2YWxpZDogZmFsc2VcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbmV3T2JqW2tleV0gPSBzaGFyZWRWYWx1ZS5kYXRhO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWxpZDogdHJ1ZSxcbiAgICAgICAgICAgIGRhdGE6IG5ld09ialxuICAgICAgICB9O1xuICAgIH0gZWxzZSBpZiAoYVR5cGUgPT09IFpvZFBhcnNlZFR5cGUuYXJyYXkgJiYgYlR5cGUgPT09IFpvZFBhcnNlZFR5cGUuYXJyYXkpIHtcbiAgICAgICAgaWYgKGEubGVuZ3RoICE9PSBiLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICB2YWxpZDogZmFsc2VcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmV3QXJyYXkgPSBbXTtcbiAgICAgICAgZm9yKGxldCBpbmRleCA9IDA7IGluZGV4IDwgYS5sZW5ndGg7IGluZGV4Kyspe1xuICAgICAgICAgICAgY29uc3QgaXRlbUEgPSBhW2luZGV4XTtcbiAgICAgICAgICAgIGNvbnN0IGl0ZW1CID0gYltpbmRleF07XG4gICAgICAgICAgICBjb25zdCBzaGFyZWRWYWx1ZSA9IG1lcmdlVmFsdWVzKGl0ZW1BLCBpdGVtQik7XG4gICAgICAgICAgICBpZiAoIXNoYXJlZFZhbHVlLnZhbGlkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsaWQ6IGZhbHNlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG5ld0FycmF5LnB1c2goc2hhcmVkVmFsdWUuZGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHZhbGlkOiB0cnVlLFxuICAgICAgICAgICAgZGF0YTogbmV3QXJyYXlcbiAgICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKGFUeXBlID09PSBab2RQYXJzZWRUeXBlLmRhdGUgJiYgYlR5cGUgPT09IFpvZFBhcnNlZFR5cGUuZGF0ZSAmJiArYSA9PT0gK2IpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHZhbGlkOiB0cnVlLFxuICAgICAgICAgICAgZGF0YTogYVxuICAgICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWxpZDogZmFsc2VcbiAgICAgICAgfTtcbiAgICB9XG59XG5leHBvcnQgY2xhc3MgWm9kSW50ZXJzZWN0aW9uIGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHsgc3RhdHVzLCBjdHggfSA9IHRoaXMuX3Byb2Nlc3NJbnB1dFBhcmFtcyhpbnB1dCk7XG4gICAgICAgIGNvbnN0IGhhbmRsZVBhcnNlZCA9IChwYXJzZWRMZWZ0LCBwYXJzZWRSaWdodCk9PntcbiAgICAgICAgICAgIGlmIChpc0Fib3J0ZWQocGFyc2VkTGVmdCkgfHwgaXNBYm9ydGVkKHBhcnNlZFJpZ2h0KSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgbWVyZ2VkID0gbWVyZ2VWYWx1ZXMocGFyc2VkTGVmdC52YWx1ZSwgcGFyc2VkUmlnaHQudmFsdWUpO1xuICAgICAgICAgICAgaWYgKCFtZXJnZWQudmFsaWQpIHtcbiAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfaW50ZXJzZWN0aW9uX3R5cGVzXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNEaXJ0eShwYXJzZWRMZWZ0KSB8fCBpc0RpcnR5KHBhcnNlZFJpZ2h0KSkge1xuICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBzdGF0dXM6IHN0YXR1cy52YWx1ZSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogbWVyZ2VkLmRhdGFcbiAgICAgICAgICAgIH07XG4gICAgICAgIH07XG4gICAgICAgIGlmIChjdHguY29tbW9uLmFzeW5jKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoW1xuICAgICAgICAgICAgICAgIHRoaXMuX2RlZi5sZWZ0Ll9wYXJzZUFzeW5jKHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YTogY3R4LmRhdGEsXG4gICAgICAgICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IGN0eFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIHRoaXMuX2RlZi5yaWdodC5fcGFyc2VBc3luYyh7XG4gICAgICAgICAgICAgICAgICAgIGRhdGE6IGN0eC5kYXRhLFxuICAgICAgICAgICAgICAgICAgICBwYXRoOiBjdHgucGF0aCxcbiAgICAgICAgICAgICAgICAgICAgcGFyZW50OiBjdHhcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgXSkudGhlbigoW2xlZnQsIHJpZ2h0XSk9PmhhbmRsZVBhcnNlZChsZWZ0LCByaWdodCkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGhhbmRsZVBhcnNlZCh0aGlzLl9kZWYubGVmdC5fcGFyc2VTeW5jKHtcbiAgICAgICAgICAgICAgICBkYXRhOiBjdHguZGF0YSxcbiAgICAgICAgICAgICAgICBwYXRoOiBjdHgucGF0aCxcbiAgICAgICAgICAgICAgICBwYXJlbnQ6IGN0eFxuICAgICAgICAgICAgfSksIHRoaXMuX2RlZi5yaWdodC5fcGFyc2VTeW5jKHtcbiAgICAgICAgICAgICAgICBkYXRhOiBjdHguZGF0YSxcbiAgICAgICAgICAgICAgICBwYXRoOiBjdHgucGF0aCxcbiAgICAgICAgICAgICAgICBwYXJlbnQ6IGN0eFxuICAgICAgICAgICAgfSkpO1xuICAgICAgICB9XG4gICAgfVxufVxuWm9kSW50ZXJzZWN0aW9uLmNyZWF0ZSA9IChsZWZ0LCByaWdodCwgcGFyYW1zKT0+e1xuICAgIHJldHVybiBuZXcgWm9kSW50ZXJzZWN0aW9uKHtcbiAgICAgICAgbGVmdDogbGVmdCxcbiAgICAgICAgcmlnaHQ6IHJpZ2h0LFxuICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEludGVyc2VjdGlvbixcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59O1xuLy8gdHlwZSBab2RUdXBsZUl0ZW1zID0gW1pvZFR5cGVBbnksIC4uLlpvZFR5cGVBbnlbXV07XG5leHBvcnQgY2xhc3MgWm9kVHVwbGUgZXh0ZW5kcyBab2RUeXBlIHtcbiAgICBfcGFyc2UoaW5wdXQpIHtcbiAgICAgICAgY29uc3QgeyBzdGF0dXMsIGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTtcbiAgICAgICAgaWYgKGN0eC5wYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLmFycmF5KSB7XG4gICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLmFycmF5LFxuICAgICAgICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY3R4LmRhdGEubGVuZ3RoIDwgdGhpcy5fZGVmLml0ZW1zLmxlbmd0aCkge1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLnRvb19zbWFsbCxcbiAgICAgICAgICAgICAgICBtaW5pbXVtOiB0aGlzLl9kZWYuaXRlbXMubGVuZ3RoLFxuICAgICAgICAgICAgICAgIGluY2x1c2l2ZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBleGFjdDogZmFsc2UsXG4gICAgICAgICAgICAgICAgdHlwZTogXCJhcnJheVwiXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlc3QgPSB0aGlzLl9kZWYucmVzdDtcbiAgICAgICAgaWYgKCFyZXN0ICYmIGN0eC5kYXRhLmxlbmd0aCA+IHRoaXMuX2RlZi5pdGVtcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS50b29fYmlnLFxuICAgICAgICAgICAgICAgIG1heGltdW06IHRoaXMuX2RlZi5pdGVtcy5sZW5ndGgsXG4gICAgICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgICAgIGV4YWN0OiBmYWxzZSxcbiAgICAgICAgICAgICAgICB0eXBlOiBcImFycmF5XCJcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaXRlbXMgPSBbXG4gICAgICAgICAgICAuLi5jdHguZGF0YVxuICAgICAgICBdLm1hcCgoaXRlbSwgaXRlbUluZGV4KT0+e1xuICAgICAgICAgICAgY29uc3Qgc2NoZW1hID0gdGhpcy5fZGVmLml0ZW1zW2l0ZW1JbmRleF0gfHwgdGhpcy5fZGVmLnJlc3Q7XG4gICAgICAgICAgICBpZiAoIXNjaGVtYSkgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICByZXR1cm4gc2NoZW1hLl9wYXJzZShuZXcgUGFyc2VJbnB1dExhenlQYXRoKGN0eCwgaXRlbSwgY3R4LnBhdGgsIGl0ZW1JbmRleCkpO1xuICAgICAgICB9KS5maWx0ZXIoKHgpPT4hIXgpOyAvLyBmaWx0ZXIgbnVsbHNcbiAgICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChpdGVtcykudGhlbigocmVzdWx0cyk9PntcbiAgICAgICAgICAgICAgICByZXR1cm4gUGFyc2VTdGF0dXMubWVyZ2VBcnJheShzdGF0dXMsIHJlc3VsdHMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gUGFyc2VTdGF0dXMubWVyZ2VBcnJheShzdGF0dXMsIGl0ZW1zKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgaXRlbXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYuaXRlbXM7XG4gICAgfVxuICAgIHJlc3QocmVzdCkge1xuICAgICAgICByZXR1cm4gbmV3IFpvZFR1cGxlKHtcbiAgICAgICAgICAgIC4uLnRoaXMuX2RlZixcbiAgICAgICAgICAgIHJlc3RcbiAgICAgICAgfSk7XG4gICAgfVxufVxuWm9kVHVwbGUuY3JlYXRlID0gKHNjaGVtYXMsIHBhcmFtcyk9PntcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoc2NoZW1hcykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiWW91IG11c3QgcGFzcyBhbiBhcnJheSBvZiBzY2hlbWFzIHRvIHoudHVwbGUoWyAuLi4gXSlcIik7XG4gICAgfVxuICAgIHJldHVybiBuZXcgWm9kVHVwbGUoe1xuICAgICAgICBpdGVtczogc2NoZW1hcyxcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RUdXBsZSxcbiAgICAgICAgcmVzdDogbnVsbCxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59O1xuZXhwb3J0IGNsYXNzIFpvZFJlY29yZCBleHRlbmRzIFpvZFR5cGUge1xuICAgIGdldCBrZXlTY2hlbWEoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYua2V5VHlwZTtcbiAgICB9XG4gICAgZ2V0IHZhbHVlU2NoZW1hKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmLnZhbHVlVHlwZTtcbiAgICB9XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHsgc3RhdHVzLCBjdHggfSA9IHRoaXMuX3Byb2Nlc3NJbnB1dFBhcmFtcyhpbnB1dCk7XG4gICAgICAgIGlmIChjdHgucGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS5vYmplY3QpIHtcbiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3R5cGUsXG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IFpvZFBhcnNlZFR5cGUub2JqZWN0LFxuICAgICAgICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwYWlycyA9IFtdO1xuICAgICAgICBjb25zdCBrZXlUeXBlID0gdGhpcy5fZGVmLmtleVR5cGU7XG4gICAgICAgIGNvbnN0IHZhbHVlVHlwZSA9IHRoaXMuX2RlZi52YWx1ZVR5cGU7XG4gICAgICAgIGZvcihjb25zdCBrZXkgaW4gY3R4LmRhdGEpe1xuICAgICAgICAgICAgcGFpcnMucHVzaCh7XG4gICAgICAgICAgICAgICAga2V5OiBrZXlUeXBlLl9wYXJzZShuZXcgUGFyc2VJbnB1dExhenlQYXRoKGN0eCwga2V5LCBjdHgucGF0aCwga2V5KSksXG4gICAgICAgICAgICAgICAgdmFsdWU6IHZhbHVlVHlwZS5fcGFyc2UobmV3IFBhcnNlSW5wdXRMYXp5UGF0aChjdHgsIGN0eC5kYXRhW2tleV0sIGN0eC5wYXRoLCBrZXkpKSxcbiAgICAgICAgICAgICAgICBhbHdheXNTZXQ6IGtleSBpbiBjdHguZGF0YVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMpIHtcbiAgICAgICAgICAgIHJldHVybiBQYXJzZVN0YXR1cy5tZXJnZU9iamVjdEFzeW5jKHN0YXR1cywgcGFpcnMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIFBhcnNlU3RhdHVzLm1lcmdlT2JqZWN0U3luYyhzdGF0dXMsIHBhaXJzKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgZWxlbWVudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi52YWx1ZVR5cGU7XG4gICAgfVxuICAgIHN0YXRpYyBjcmVhdGUoZmlyc3QsIHNlY29uZCwgdGhpcmQpIHtcbiAgICAgICAgaWYgKHNlY29uZCBpbnN0YW5jZW9mIFpvZFR5cGUpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgWm9kUmVjb3JkKHtcbiAgICAgICAgICAgICAgICBrZXlUeXBlOiBmaXJzdCxcbiAgICAgICAgICAgICAgICB2YWx1ZVR5cGU6IHNlY29uZCxcbiAgICAgICAgICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZFJlY29yZCxcbiAgICAgICAgICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHRoaXJkKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBab2RSZWNvcmQoe1xuICAgICAgICAgICAga2V5VHlwZTogWm9kU3RyaW5nLmNyZWF0ZSgpLFxuICAgICAgICAgICAgdmFsdWVUeXBlOiBmaXJzdCxcbiAgICAgICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kUmVjb3JkLFxuICAgICAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhzZWNvbmQpXG4gICAgICAgIH0pO1xuICAgIH1cbn1cbmV4cG9ydCBjbGFzcyBab2RNYXAgZXh0ZW5kcyBab2RUeXBlIHtcbiAgICBnZXQga2V5U2NoZW1hKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmLmtleVR5cGU7XG4gICAgfVxuICAgIGdldCB2YWx1ZVNjaGVtYSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi52YWx1ZVR5cGU7XG4gICAgfVxuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBjb25zdCB7IHN0YXR1cywgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpO1xuICAgICAgICBpZiAoY3R4LnBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUubWFwKSB7XG4gICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLm1hcCxcbiAgICAgICAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qga2V5VHlwZSA9IHRoaXMuX2RlZi5rZXlUeXBlO1xuICAgICAgICBjb25zdCB2YWx1ZVR5cGUgPSB0aGlzLl9kZWYudmFsdWVUeXBlO1xuICAgICAgICBjb25zdCBwYWlycyA9IFtcbiAgICAgICAgICAgIC4uLmN0eC5kYXRhLmVudHJpZXMoKVxuICAgICAgICBdLm1hcCgoW2tleSwgdmFsdWVdLCBpbmRleCk9PntcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAga2V5OiBrZXlUeXBlLl9wYXJzZShuZXcgUGFyc2VJbnB1dExhenlQYXRoKGN0eCwga2V5LCBjdHgucGF0aCwgW1xuICAgICAgICAgICAgICAgICAgICBpbmRleCxcbiAgICAgICAgICAgICAgICAgICAgXCJrZXlcIlxuICAgICAgICAgICAgICAgIF0pKSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogdmFsdWVUeXBlLl9wYXJzZShuZXcgUGFyc2VJbnB1dExhenlQYXRoKGN0eCwgdmFsdWUsIGN0eC5wYXRoLCBbXG4gICAgICAgICAgICAgICAgICAgIGluZGV4LFxuICAgICAgICAgICAgICAgICAgICBcInZhbHVlXCJcbiAgICAgICAgICAgICAgICBdKSlcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoY3R4LmNvbW1vbi5hc3luYykge1xuICAgICAgICAgICAgY29uc3QgZmluYWxNYXAgPSBuZXcgTWFwKCk7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCkudGhlbihhc3luYyAoKT0+e1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgcGFpciBvZiBwYWlycyl7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGtleSA9IGF3YWl0IHBhaXIua2V5O1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGF3YWl0IHBhaXIudmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChrZXkuc3RhdHVzID09PSBcImFib3J0ZWRcIiB8fCB2YWx1ZS5zdGF0dXMgPT09IFwiYWJvcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoa2V5LnN0YXR1cyA9PT0gXCJkaXJ0eVwiIHx8IHZhbHVlLnN0YXR1cyA9PT0gXCJkaXJ0eVwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBmaW5hbE1hcC5zZXQoa2V5LnZhbHVlLCB2YWx1ZS52YWx1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1czogc3RhdHVzLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogZmluYWxNYXBcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBmaW5hbE1hcCA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgcGFpciBvZiBwYWlycyl7XG4gICAgICAgICAgICAgICAgY29uc3Qga2V5ID0gcGFpci5rZXk7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBwYWlyLnZhbHVlO1xuICAgICAgICAgICAgICAgIGlmIChrZXkuc3RhdHVzID09PSBcImFib3J0ZWRcIiB8fCB2YWx1ZS5zdGF0dXMgPT09IFwiYWJvcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoa2V5LnN0YXR1cyA9PT0gXCJkaXJ0eVwiIHx8IHZhbHVlLnN0YXR1cyA9PT0gXCJkaXJ0eVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBmaW5hbE1hcC5zZXQoa2V5LnZhbHVlLCB2YWx1ZS52YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHN0YXR1czogc3RhdHVzLnZhbHVlLFxuICAgICAgICAgICAgICAgIHZhbHVlOiBmaW5hbE1hcFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgIH1cbn1cblpvZE1hcC5jcmVhdGUgPSAoa2V5VHlwZSwgdmFsdWVUeXBlLCBwYXJhbXMpPT57XG4gICAgcmV0dXJuIG5ldyBab2RNYXAoe1xuICAgICAgICB2YWx1ZVR5cGUsXG4gICAgICAgIGtleVR5cGUsXG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kTWFwLFxuICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn07XG5leHBvcnQgY2xhc3MgWm9kU2V0IGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHsgc3RhdHVzLCBjdHggfSA9IHRoaXMuX3Byb2Nlc3NJbnB1dFBhcmFtcyhpbnB1dCk7XG4gICAgICAgIGlmIChjdHgucGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS5zZXQpIHtcbiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3R5cGUsXG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IFpvZFBhcnNlZFR5cGUuc2V0LFxuICAgICAgICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBkZWYgPSB0aGlzLl9kZWY7XG4gICAgICAgIGlmIChkZWYubWluU2l6ZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKGN0eC5kYXRhLnNpemUgPCBkZWYubWluU2l6ZS52YWx1ZSkge1xuICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX3NtYWxsLFxuICAgICAgICAgICAgICAgICAgICBtaW5pbXVtOiBkZWYubWluU2l6ZS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJzZXRcIixcbiAgICAgICAgICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBleGFjdDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGRlZi5taW5TaXplLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoZGVmLm1heFNpemUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGlmIChjdHguZGF0YS5zaXplID4gZGVmLm1heFNpemUudmFsdWUpIHtcbiAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLnRvb19iaWcsXG4gICAgICAgICAgICAgICAgICAgIG1heGltdW06IGRlZi5tYXhTaXplLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiBcInNldFwiLFxuICAgICAgICAgICAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGV4YWN0OiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogZGVmLm1heFNpemUubWVzc2FnZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHZhbHVlVHlwZSA9IHRoaXMuX2RlZi52YWx1ZVR5cGU7XG4gICAgICAgIGZ1bmN0aW9uIGZpbmFsaXplU2V0KGVsZW1lbnRzKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJzZWRTZXQgPSBuZXcgU2V0KCk7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgZWxlbWVudHMpe1xuICAgICAgICAgICAgICAgIGlmIChlbGVtZW50LnN0YXR1cyA9PT0gXCJhYm9ydGVkXCIpIHJldHVybiBJTlZBTElEO1xuICAgICAgICAgICAgICAgIGlmIChlbGVtZW50LnN0YXR1cyA9PT0gXCJkaXJ0eVwiKSBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICBwYXJzZWRTZXQuYWRkKGVsZW1lbnQudmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBzdGF0dXM6IHN0YXR1cy52YWx1ZSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogcGFyc2VkU2V0XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGVsZW1lbnRzID0gW1xuICAgICAgICAgICAgLi4uY3R4LmRhdGEudmFsdWVzKClcbiAgICAgICAgXS5tYXAoKGl0ZW0sIGkpPT52YWx1ZVR5cGUuX3BhcnNlKG5ldyBQYXJzZUlucHV0TGF6eVBhdGgoY3R4LCBpdGVtLCBjdHgucGF0aCwgaSkpKTtcbiAgICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChlbGVtZW50cykudGhlbigoZWxlbWVudHMpPT5maW5hbGl6ZVNldChlbGVtZW50cykpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGZpbmFsaXplU2V0KGVsZW1lbnRzKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBtaW4obWluU2l6ZSwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gbmV3IFpvZFNldCh7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICBtaW5TaXplOiB7XG4gICAgICAgICAgICAgICAgdmFsdWU6IG1pblNpemUsXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBtYXgobWF4U2l6ZSwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gbmV3IFpvZFNldCh7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICBtYXhTaXplOiB7XG4gICAgICAgICAgICAgICAgdmFsdWU6IG1heFNpemUsXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBzaXplKHNpemUsIG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWluKHNpemUsIG1lc3NhZ2UpLm1heChzaXplLCBtZXNzYWdlKTtcbiAgICB9XG4gICAgbm9uZW1wdHkobWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5taW4oMSwgbWVzc2FnZSk7XG4gICAgfVxufVxuWm9kU2V0LmNyZWF0ZSA9ICh2YWx1ZVR5cGUsIHBhcmFtcyk9PntcbiAgICByZXR1cm4gbmV3IFpvZFNldCh7XG4gICAgICAgIHZhbHVlVHlwZSxcbiAgICAgICAgbWluU2l6ZTogbnVsbCxcbiAgICAgICAgbWF4U2l6ZTogbnVsbCxcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RTZXQsXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufTtcbmV4cG9ydCBjbGFzcyBab2RGdW5jdGlvbiBleHRlbmRzIFpvZFR5cGUge1xuICAgIGNvbnN0cnVjdG9yKCl7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMudmFsaWRhdGUgPSB0aGlzLmltcGxlbWVudDtcbiAgICB9XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpO1xuICAgICAgICBpZiAoY3R4LnBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUuZnVuY3Rpb24pIHtcbiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3R5cGUsXG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IFpvZFBhcnNlZFR5cGUuZnVuY3Rpb24sXG4gICAgICAgICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIG1ha2VBcmdzSXNzdWUoYXJncywgZXJyb3IpIHtcbiAgICAgICAgICAgIHJldHVybiBtYWtlSXNzdWUoe1xuICAgICAgICAgICAgICAgIGRhdGE6IGFyZ3MsXG4gICAgICAgICAgICAgICAgcGF0aDogY3R4LnBhdGgsXG4gICAgICAgICAgICAgICAgZXJyb3JNYXBzOiBbXG4gICAgICAgICAgICAgICAgICAgIGN0eC5jb21tb24uY29udGV4dHVhbEVycm9yTWFwLFxuICAgICAgICAgICAgICAgICAgICBjdHguc2NoZW1hRXJyb3JNYXAsXG4gICAgICAgICAgICAgICAgICAgIGdldEVycm9yTWFwKCksXG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHRFcnJvck1hcFxuICAgICAgICAgICAgICAgIF0uZmlsdGVyKCh4KT0+ISF4KSxcbiAgICAgICAgICAgICAgICBpc3N1ZURhdGE6IHtcbiAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfYXJndW1lbnRzLFxuICAgICAgICAgICAgICAgICAgICBhcmd1bWVudHNFcnJvcjogZXJyb3JcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBtYWtlUmV0dXJuc0lzc3VlKHJldHVybnMsIGVycm9yKSB7XG4gICAgICAgICAgICByZXR1cm4gbWFrZUlzc3VlKHtcbiAgICAgICAgICAgICAgICBkYXRhOiByZXR1cm5zLFxuICAgICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgICAgIGVycm9yTWFwczogW1xuICAgICAgICAgICAgICAgICAgICBjdHguY29tbW9uLmNvbnRleHR1YWxFcnJvck1hcCxcbiAgICAgICAgICAgICAgICAgICAgY3R4LnNjaGVtYUVycm9yTWFwLFxuICAgICAgICAgICAgICAgICAgICBnZXRFcnJvck1hcCgpLFxuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0RXJyb3JNYXBcbiAgICAgICAgICAgICAgICBdLmZpbHRlcigoeCk9PiEheCksXG4gICAgICAgICAgICAgICAgaXNzdWVEYXRhOiB7XG4gICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3JldHVybl90eXBlLFxuICAgICAgICAgICAgICAgICAgICByZXR1cm5UeXBlRXJyb3I6IGVycm9yXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgICAgZXJyb3JNYXA6IGN0eC5jb21tb24uY29udGV4dHVhbEVycm9yTWFwXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGZuID0gY3R4LmRhdGE7XG4gICAgICAgIGlmICh0aGlzLl9kZWYucmV0dXJucyBpbnN0YW5jZW9mIFpvZFByb21pc2UpIHtcbiAgICAgICAgICAgIC8vIFdvdWxkIGxvdmUgYSB3YXkgdG8gYXZvaWQgZGlzYWJsaW5nIHRoaXMgcnVsZSwgYnV0IHdlIG5lZWRcbiAgICAgICAgICAgIC8vIGFuIGFsaWFzICh1c2luZyBhbiBhcnJvdyBmdW5jdGlvbiB3YXMgd2hhdCBjYXVzZWQgMjY1MSkuXG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXRoaXMtYWxpYXNcbiAgICAgICAgICAgIGNvbnN0IG1lID0gdGhpcztcbiAgICAgICAgICAgIHJldHVybiBPSyhhc3luYyBmdW5jdGlvbiguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgWm9kRXJyb3IoW10pO1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcnNlZEFyZ3MgPSBhd2FpdCBtZS5fZGVmLmFyZ3MucGFyc2VBc3luYyhhcmdzLCBwYXJhbXMpLmNhdGNoKChlKT0+e1xuICAgICAgICAgICAgICAgICAgICBlcnJvci5hZGRJc3N1ZShtYWtlQXJnc0lzc3VlKGFyZ3MsIGUpKTtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgUmVmbGVjdC5hcHBseShmbiwgdGhpcywgcGFyc2VkQXJncyk7XG4gICAgICAgICAgICAgICAgY29uc3QgcGFyc2VkUmV0dXJucyA9IGF3YWl0IG1lLl9kZWYucmV0dXJucy5fZGVmLnR5cGUucGFyc2VBc3luYyhyZXN1bHQsIHBhcmFtcykuY2F0Y2goKGUpPT57XG4gICAgICAgICAgICAgICAgICAgIGVycm9yLmFkZElzc3VlKG1ha2VSZXR1cm5zSXNzdWUocmVzdWx0LCBlKSk7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZWRSZXR1cm5zO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBXb3VsZCBsb3ZlIGEgd2F5IHRvIGF2b2lkIGRpc2FibGluZyB0aGlzIHJ1bGUsIGJ1dCB3ZSBuZWVkXG4gICAgICAgICAgICAvLyBhbiBhbGlhcyAodXNpbmcgYW4gYXJyb3cgZnVuY3Rpb24gd2FzIHdoYXQgY2F1c2VkIDI2NTEpLlxuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby10aGlzLWFsaWFzXG4gICAgICAgICAgICBjb25zdCBtZSA9IHRoaXM7XG4gICAgICAgICAgICByZXR1cm4gT0soZnVuY3Rpb24oLi4uYXJncykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcnNlZEFyZ3MgPSBtZS5fZGVmLmFyZ3Muc2FmZVBhcnNlKGFyZ3MsIHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgaWYgKCFwYXJzZWRBcmdzLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFpvZEVycm9yKFtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1ha2VBcmdzSXNzdWUoYXJncywgcGFyc2VkQXJncy5lcnJvcilcbiAgICAgICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IFJlZmxlY3QuYXBwbHkoZm4sIHRoaXMsIHBhcnNlZEFyZ3MuZGF0YSk7XG4gICAgICAgICAgICAgICAgY29uc3QgcGFyc2VkUmV0dXJucyA9IG1lLl9kZWYucmV0dXJucy5zYWZlUGFyc2UocmVzdWx0LCBwYXJhbXMpO1xuICAgICAgICAgICAgICAgIGlmICghcGFyc2VkUmV0dXJucy5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBab2RFcnJvcihbXG4gICAgICAgICAgICAgICAgICAgICAgICBtYWtlUmV0dXJuc0lzc3VlKHJlc3VsdCwgcGFyc2VkUmV0dXJucy5lcnJvcilcbiAgICAgICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZWRSZXR1cm5zLmRhdGE7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBwYXJhbWV0ZXJzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmLmFyZ3M7XG4gICAgfVxuICAgIHJldHVyblR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYucmV0dXJucztcbiAgICB9XG4gICAgYXJncyguLi5pdGVtcykge1xuICAgICAgICByZXR1cm4gbmV3IFpvZEZ1bmN0aW9uKHtcbiAgICAgICAgICAgIC4uLnRoaXMuX2RlZixcbiAgICAgICAgICAgIGFyZ3M6IFpvZFR1cGxlLmNyZWF0ZShpdGVtcykucmVzdChab2RVbmtub3duLmNyZWF0ZSgpKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJucyhyZXR1cm5UeXBlKSB7XG4gICAgICAgIHJldHVybiBuZXcgWm9kRnVuY3Rpb24oe1xuICAgICAgICAgICAgLi4udGhpcy5fZGVmLFxuICAgICAgICAgICAgcmV0dXJuczogcmV0dXJuVHlwZVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgaW1wbGVtZW50KGZ1bmMpIHtcbiAgICAgICAgY29uc3QgdmFsaWRhdGVkRnVuYyA9IHRoaXMucGFyc2UoZnVuYyk7XG4gICAgICAgIHJldHVybiB2YWxpZGF0ZWRGdW5jO1xuICAgIH1cbiAgICBzdHJpY3RJbXBsZW1lbnQoZnVuYykge1xuICAgICAgICBjb25zdCB2YWxpZGF0ZWRGdW5jID0gdGhpcy5wYXJzZShmdW5jKTtcbiAgICAgICAgcmV0dXJuIHZhbGlkYXRlZEZ1bmM7XG4gICAgfVxuICAgIHN0YXRpYyBjcmVhdGUoYXJncywgcmV0dXJucywgcGFyYW1zKSB7XG4gICAgICAgIHJldHVybiBuZXcgWm9kRnVuY3Rpb24oe1xuICAgICAgICAgICAgYXJnczogYXJncyA/IGFyZ3MgOiBab2RUdXBsZS5jcmVhdGUoW10pLnJlc3QoWm9kVW5rbm93bi5jcmVhdGUoKSksXG4gICAgICAgICAgICByZXR1cm5zOiByZXR1cm5zIHx8IFpvZFVua25vd24uY3JlYXRlKCksXG4gICAgICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEZ1bmN0aW9uLFxuICAgICAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgICAgIH0pO1xuICAgIH1cbn1cbmV4cG9ydCBjbGFzcyBab2RMYXp5IGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgZ2V0IHNjaGVtYSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi5nZXR0ZXIoKTtcbiAgICB9XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpO1xuICAgICAgICBjb25zdCBsYXp5U2NoZW1hID0gdGhpcy5fZGVmLmdldHRlcigpO1xuICAgICAgICByZXR1cm4gbGF6eVNjaGVtYS5fcGFyc2Uoe1xuICAgICAgICAgICAgZGF0YTogY3R4LmRhdGEsXG4gICAgICAgICAgICBwYXRoOiBjdHgucGF0aCxcbiAgICAgICAgICAgIHBhcmVudDogY3R4XG4gICAgICAgIH0pO1xuICAgIH1cbn1cblpvZExhenkuY3JlYXRlID0gKGdldHRlciwgcGFyYW1zKT0+e1xuICAgIHJldHVybiBuZXcgWm9kTGF6eSh7XG4gICAgICAgIGdldHRlcjogZ2V0dGVyLFxuICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZExhenksXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufTtcbmV4cG9ydCBjbGFzcyBab2RMaXRlcmFsIGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGlmIChpbnB1dC5kYXRhICE9PSB0aGlzLl9kZWYudmFsdWUpIHtcbiAgICAgICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTtcbiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgIHJlY2VpdmVkOiBjdHguZGF0YSxcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9saXRlcmFsLFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiB0aGlzLl9kZWYudmFsdWVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN0YXR1czogXCJ2YWxpZFwiLFxuICAgICAgICAgICAgdmFsdWU6IGlucHV0LmRhdGFcbiAgICAgICAgfTtcbiAgICB9XG4gICAgZ2V0IHZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmLnZhbHVlO1xuICAgIH1cbn1cblpvZExpdGVyYWwuY3JlYXRlID0gKHZhbHVlLCBwYXJhbXMpPT57XG4gICAgcmV0dXJuIG5ldyBab2RMaXRlcmFsKHtcbiAgICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZExpdGVyYWwsXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufTtcbmZ1bmN0aW9uIGNyZWF0ZVpvZEVudW0odmFsdWVzLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gbmV3IFpvZEVudW0oe1xuICAgICAgICB2YWx1ZXMsXG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kRW51bSxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59XG5leHBvcnQgY2xhc3MgWm9kRW51bSBleHRlbmRzIFpvZFR5cGUge1xuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBpZiAodHlwZW9mIGlucHV0LmRhdGEgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTtcbiAgICAgICAgICAgIGNvbnN0IGV4cGVjdGVkVmFsdWVzID0gdGhpcy5fZGVmLnZhbHVlcztcbiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiB1dGlsLmpvaW5WYWx1ZXMoZXhwZWN0ZWRWYWx1ZXMpLFxuICAgICAgICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZSxcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5fY2FjaGUpIHtcbiAgICAgICAgICAgIHRoaXMuX2NhY2hlID0gbmV3IFNldCh0aGlzLl9kZWYudmFsdWVzKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMuX2NhY2hlLmhhcyhpbnB1dC5kYXRhKSkge1xuICAgICAgICAgICAgY29uc3QgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQpO1xuICAgICAgICAgICAgY29uc3QgZXhwZWN0ZWRWYWx1ZXMgPSB0aGlzLl9kZWYudmFsdWVzO1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5kYXRhLFxuICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX2VudW1fdmFsdWUsXG4gICAgICAgICAgICAgICAgb3B0aW9uczogZXhwZWN0ZWRWYWx1ZXNcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIE9LKGlucHV0LmRhdGEpO1xuICAgIH1cbiAgICBnZXQgb3B0aW9ucygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi52YWx1ZXM7XG4gICAgfVxuICAgIGdldCBlbnVtKCkge1xuICAgICAgICBjb25zdCBlbnVtVmFsdWVzID0ge307XG4gICAgICAgIGZvciAoY29uc3QgdmFsIG9mIHRoaXMuX2RlZi52YWx1ZXMpe1xuICAgICAgICAgICAgZW51bVZhbHVlc1t2YWxdID0gdmFsO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBlbnVtVmFsdWVzO1xuICAgIH1cbiAgICBnZXQgVmFsdWVzKCkge1xuICAgICAgICBjb25zdCBlbnVtVmFsdWVzID0ge307XG4gICAgICAgIGZvciAoY29uc3QgdmFsIG9mIHRoaXMuX2RlZi52YWx1ZXMpe1xuICAgICAgICAgICAgZW51bVZhbHVlc1t2YWxdID0gdmFsO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBlbnVtVmFsdWVzO1xuICAgIH1cbiAgICBnZXQgRW51bSgpIHtcbiAgICAgICAgY29uc3QgZW51bVZhbHVlcyA9IHt9O1xuICAgICAgICBmb3IgKGNvbnN0IHZhbCBvZiB0aGlzLl9kZWYudmFsdWVzKXtcbiAgICAgICAgICAgIGVudW1WYWx1ZXNbdmFsXSA9IHZhbDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZW51bVZhbHVlcztcbiAgICB9XG4gICAgZXh0cmFjdCh2YWx1ZXMsIG5ld0RlZiA9IHRoaXMuX2RlZikge1xuICAgICAgICByZXR1cm4gWm9kRW51bS5jcmVhdGUodmFsdWVzLCB7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICAuLi5uZXdEZWZcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGV4Y2x1ZGUodmFsdWVzLCBuZXdEZWYgPSB0aGlzLl9kZWYpIHtcbiAgICAgICAgcmV0dXJuIFpvZEVudW0uY3JlYXRlKHRoaXMub3B0aW9ucy5maWx0ZXIoKG9wdCk9PiF2YWx1ZXMuaW5jbHVkZXMob3B0KSksIHtcbiAgICAgICAgICAgIC4uLnRoaXMuX2RlZixcbiAgICAgICAgICAgIC4uLm5ld0RlZlxuICAgICAgICB9KTtcbiAgICB9XG59XG5ab2RFbnVtLmNyZWF0ZSA9IGNyZWF0ZVpvZEVudW07XG5leHBvcnQgY2xhc3MgWm9kTmF0aXZlRW51bSBleHRlbmRzIFpvZFR5cGUge1xuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBjb25zdCBuYXRpdmVFbnVtVmFsdWVzID0gdXRpbC5nZXRWYWxpZEVudW1WYWx1ZXModGhpcy5fZGVmLnZhbHVlcyk7XG4gICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTtcbiAgICAgICAgaWYgKGN0eC5wYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLnN0cmluZyAmJiBjdHgucGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS5udW1iZXIpIHtcbiAgICAgICAgICAgIGNvbnN0IGV4cGVjdGVkVmFsdWVzID0gdXRpbC5vYmplY3RWYWx1ZXMobmF0aXZlRW51bVZhbHVlcyk7XG4gICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogdXRpbC5qb2luVmFsdWVzKGV4cGVjdGVkVmFsdWVzKSxcbiAgICAgICAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGUsXG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMuX2NhY2hlKSB7XG4gICAgICAgICAgICB0aGlzLl9jYWNoZSA9IG5ldyBTZXQodXRpbC5nZXRWYWxpZEVudW1WYWx1ZXModGhpcy5fZGVmLnZhbHVlcykpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5fY2FjaGUuaGFzKGlucHV0LmRhdGEpKSB7XG4gICAgICAgICAgICBjb25zdCBleHBlY3RlZFZhbHVlcyA9IHV0aWwub2JqZWN0VmFsdWVzKG5hdGl2ZUVudW1WYWx1ZXMpO1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5kYXRhLFxuICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX2VudW1fdmFsdWUsXG4gICAgICAgICAgICAgICAgb3B0aW9uczogZXhwZWN0ZWRWYWx1ZXNcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIE9LKGlucHV0LmRhdGEpO1xuICAgIH1cbiAgICBnZXQgZW51bSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi52YWx1ZXM7XG4gICAgfVxufVxuWm9kTmF0aXZlRW51bS5jcmVhdGUgPSAodmFsdWVzLCBwYXJhbXMpPT57XG4gICAgcmV0dXJuIG5ldyBab2ROYXRpdmVFbnVtKHtcbiAgICAgICAgdmFsdWVzOiB2YWx1ZXMsXG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kTmF0aXZlRW51bSxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59O1xuZXhwb3J0IGNsYXNzIFpvZFByb21pc2UgZXh0ZW5kcyBab2RUeXBlIHtcbiAgICB1bndyYXAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYudHlwZTtcbiAgICB9XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpO1xuICAgICAgICBpZiAoY3R4LnBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUucHJvbWlzZSAmJiBjdHguY29tbW9uLmFzeW5jID09PSBmYWxzZSkge1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSxcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5wcm9taXNlLFxuICAgICAgICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwcm9taXNpZmllZCA9IGN0eC5wYXJzZWRUeXBlID09PSBab2RQYXJzZWRUeXBlLnByb21pc2UgPyBjdHguZGF0YSA6IFByb21pc2UucmVzb2x2ZShjdHguZGF0YSk7XG4gICAgICAgIHJldHVybiBPSyhwcm9taXNpZmllZC50aGVuKChkYXRhKT0+e1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi50eXBlLnBhcnNlQXN5bmMoZGF0YSwge1xuICAgICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgICAgIGVycm9yTWFwOiBjdHguY29tbW9uLmNvbnRleHR1YWxFcnJvck1hcFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pKTtcbiAgICB9XG59XG5ab2RQcm9taXNlLmNyZWF0ZSA9IChzY2hlbWEsIHBhcmFtcyk9PntcbiAgICByZXR1cm4gbmV3IFpvZFByb21pc2Uoe1xuICAgICAgICB0eXBlOiBzY2hlbWEsXG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kUHJvbWlzZSxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59O1xuZXhwb3J0IGNsYXNzIFpvZEVmZmVjdHMgZXh0ZW5kcyBab2RUeXBlIHtcbiAgICBpbm5lclR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYuc2NoZW1hO1xuICAgIH1cbiAgICBzb3VyY2VUeXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmLnNjaGVtYS5fZGVmLnR5cGVOYW1lID09PSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kRWZmZWN0cyA/IHRoaXMuX2RlZi5zY2hlbWEuc291cmNlVHlwZSgpIDogdGhpcy5fZGVmLnNjaGVtYTtcbiAgICB9XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHsgc3RhdHVzLCBjdHggfSA9IHRoaXMuX3Byb2Nlc3NJbnB1dFBhcmFtcyhpbnB1dCk7XG4gICAgICAgIGNvbnN0IGVmZmVjdCA9IHRoaXMuX2RlZi5lZmZlY3QgfHwgbnVsbDtcbiAgICAgICAgY29uc3QgY2hlY2tDdHggPSB7XG4gICAgICAgICAgICBhZGRJc3N1ZTogKGFyZyk9PntcbiAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIGFyZyk7XG4gICAgICAgICAgICAgICAgaWYgKGFyZy5mYXRhbCkge1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuYWJvcnQoKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHBhdGggKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBjdHgucGF0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgY2hlY2tDdHguYWRkSXNzdWUgPSBjaGVja0N0eC5hZGRJc3N1ZS5iaW5kKGNoZWNrQ3R4KTtcbiAgICAgICAgaWYgKGVmZmVjdC50eXBlID09PSBcInByZXByb2Nlc3NcIikge1xuICAgICAgICAgICAgY29uc3QgcHJvY2Vzc2VkID0gZWZmZWN0LnRyYW5zZm9ybShjdHguZGF0YSwgY2hlY2tDdHgpO1xuICAgICAgICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHByb2Nlc3NlZCkudGhlbihhc3luYyAocHJvY2Vzc2VkKT0+e1xuICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdHVzLnZhbHVlID09PSBcImFib3J0ZWRcIikgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuX2RlZi5zY2hlbWEuX3BhcnNlQXN5bmMoe1xuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YTogcHJvY2Vzc2VkLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGF0aDogY3R4LnBhdGgsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IGN0eFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5zdGF0dXMgPT09IFwiYWJvcnRlZFwiKSByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5zdGF0dXMgPT09IFwiZGlydHlcIikgcmV0dXJuIERJUlRZKHJlc3VsdC52YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMudmFsdWUgPT09IFwiZGlydHlcIikgcmV0dXJuIERJUlRZKHJlc3VsdC52YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChzdGF0dXMudmFsdWUgPT09IFwiYWJvcnRlZFwiKSByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSB0aGlzLl9kZWYuc2NoZW1hLl9wYXJzZVN5bmMoe1xuICAgICAgICAgICAgICAgICAgICBkYXRhOiBwcm9jZXNzZWQsXG4gICAgICAgICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IGN0eFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQuc3RhdHVzID09PSBcImFib3J0ZWRcIikgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5zdGF0dXMgPT09IFwiZGlydHlcIikgcmV0dXJuIERJUlRZKHJlc3VsdC52YWx1ZSk7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXR1cy52YWx1ZSA9PT0gXCJkaXJ0eVwiKSByZXR1cm4gRElSVFkocmVzdWx0LnZhbHVlKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChlZmZlY3QudHlwZSA9PT0gXCJyZWZpbmVtZW50XCIpIHtcbiAgICAgICAgICAgIGNvbnN0IGV4ZWN1dGVSZWZpbmVtZW50ID0gKGFjYyk9PntcbiAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSBlZmZlY3QucmVmaW5lbWVudChhY2MsIGNoZWNrQ3R4KTtcbiAgICAgICAgICAgICAgICBpZiAoY3R4LmNvbW1vbi5hc3luYykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkFzeW5jIHJlZmluZW1lbnQgZW5jb3VudGVyZWQgZHVyaW5nIHN5bmNocm9ub3VzIHBhcnNlIG9wZXJhdGlvbi4gVXNlIC5wYXJzZUFzeW5jIGluc3RlYWQuXCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmIChjdHguY29tbW9uLmFzeW5jID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGlubmVyID0gdGhpcy5fZGVmLnNjaGVtYS5fcGFyc2VTeW5jKHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YTogY3R4LmRhdGEsXG4gICAgICAgICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IGN0eFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGlmIChpbm5lci5zdGF0dXMgPT09IFwiYWJvcnRlZFwiKSByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgICAgICAgICBpZiAoaW5uZXIuc3RhdHVzID09PSBcImRpcnR5XCIpIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIC8vIHJldHVybiB2YWx1ZSBpcyBpZ25vcmVkXG4gICAgICAgICAgICAgICAgZXhlY3V0ZVJlZmluZW1lbnQoaW5uZXIudmFsdWUpO1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1czogc3RhdHVzLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogaW5uZXIudmFsdWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fZGVmLnNjaGVtYS5fcGFyc2VBc3luYyh7XG4gICAgICAgICAgICAgICAgICAgIGRhdGE6IGN0eC5kYXRhLFxuICAgICAgICAgICAgICAgICAgICBwYXRoOiBjdHgucGF0aCxcbiAgICAgICAgICAgICAgICAgICAgcGFyZW50OiBjdHhcbiAgICAgICAgICAgICAgICB9KS50aGVuKChpbm5lcik9PntcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlubmVyLnN0YXR1cyA9PT0gXCJhYm9ydGVkXCIpIHJldHVybiBJTlZBTElEO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaW5uZXIuc3RhdHVzID09PSBcImRpcnR5XCIpIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXhlY3V0ZVJlZmluZW1lbnQoaW5uZXIudmFsdWUpLnRoZW4oKCk9PntcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzOiBzdGF0dXMudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGlubmVyLnZhbHVlXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoZWZmZWN0LnR5cGUgPT09IFwidHJhbnNmb3JtXCIpIHtcbiAgICAgICAgICAgIGlmIChjdHguY29tbW9uLmFzeW5jID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGJhc2UgPSB0aGlzLl9kZWYuc2NoZW1hLl9wYXJzZVN5bmMoe1xuICAgICAgICAgICAgICAgICAgICBkYXRhOiBjdHguZGF0YSxcbiAgICAgICAgICAgICAgICAgICAgcGF0aDogY3R4LnBhdGgsXG4gICAgICAgICAgICAgICAgICAgIHBhcmVudDogY3R4XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgaWYgKCFpc1ZhbGlkKGJhc2UpKSByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSBlZmZlY3QudHJhbnNmb3JtKGJhc2UudmFsdWUsIGNoZWNrQ3R4KTtcbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEFzeW5jaHJvbm91cyB0cmFuc2Zvcm0gZW5jb3VudGVyZWQgZHVyaW5nIHN5bmNocm9ub3VzIHBhcnNlIG9wZXJhdGlvbi4gVXNlIC5wYXJzZUFzeW5jIGluc3RlYWQuYCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1czogc3RhdHVzLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogcmVzdWx0XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi5zY2hlbWEuX3BhcnNlQXN5bmMoe1xuICAgICAgICAgICAgICAgICAgICBkYXRhOiBjdHguZGF0YSxcbiAgICAgICAgICAgICAgICAgICAgcGF0aDogY3R4LnBhdGgsXG4gICAgICAgICAgICAgICAgICAgIHBhcmVudDogY3R4XG4gICAgICAgICAgICAgICAgfSkudGhlbigoYmFzZSk9PntcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc1ZhbGlkKGJhc2UpKSByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShlZmZlY3QudHJhbnNmb3JtKGJhc2UudmFsdWUsIGNoZWNrQ3R4KSkudGhlbigocmVzdWx0KT0+KHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXM6IHN0YXR1cy52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogcmVzdWx0XG4gICAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdXRpbC5hc3NlcnROZXZlcihlZmZlY3QpO1xuICAgIH1cbn1cblpvZEVmZmVjdHMuY3JlYXRlID0gKHNjaGVtYSwgZWZmZWN0LCBwYXJhbXMpPT57XG4gICAgcmV0dXJuIG5ldyBab2RFZmZlY3RzKHtcbiAgICAgICAgc2NoZW1hLFxuICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEVmZmVjdHMsXG4gICAgICAgIGVmZmVjdCxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59O1xuWm9kRWZmZWN0cy5jcmVhdGVXaXRoUHJlcHJvY2VzcyA9IChwcmVwcm9jZXNzLCBzY2hlbWEsIHBhcmFtcyk9PntcbiAgICByZXR1cm4gbmV3IFpvZEVmZmVjdHMoe1xuICAgICAgICBzY2hlbWEsXG4gICAgICAgIGVmZmVjdDoge1xuICAgICAgICAgICAgdHlwZTogXCJwcmVwcm9jZXNzXCIsXG4gICAgICAgICAgICB0cmFuc2Zvcm06IHByZXByb2Nlc3NcbiAgICAgICAgfSxcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RFZmZlY3RzLFxuICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn07XG5leHBvcnQgeyBab2RFZmZlY3RzIGFzIFpvZFRyYW5zZm9ybWVyIH07XG5leHBvcnQgY2xhc3MgWm9kT3B0aW9uYWwgZXh0ZW5kcyBab2RUeXBlIHtcbiAgICBfcGFyc2UoaW5wdXQpIHtcbiAgICAgICAgY29uc3QgcGFyc2VkVHlwZSA9IHRoaXMuX2dldFR5cGUoaW5wdXQpO1xuICAgICAgICBpZiAocGFyc2VkVHlwZSA9PT0gWm9kUGFyc2VkVHlwZS51bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBPSyh1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYuaW5uZXJUeXBlLl9wYXJzZShpbnB1dCk7XG4gICAgfVxuICAgIHVud3JhcCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi5pbm5lclR5cGU7XG4gICAgfVxufVxuWm9kT3B0aW9uYWwuY3JlYXRlID0gKHR5cGUsIHBhcmFtcyk9PntcbiAgICByZXR1cm4gbmV3IFpvZE9wdGlvbmFsKHtcbiAgICAgICAgaW5uZXJUeXBlOiB0eXBlLFxuICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE9wdGlvbmFsLFxuICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcylcbiAgICB9KTtcbn07XG5leHBvcnQgY2xhc3MgWm9kTnVsbGFibGUgZXh0ZW5kcyBab2RUeXBlIHtcbiAgICBfcGFyc2UoaW5wdXQpIHtcbiAgICAgICAgY29uc3QgcGFyc2VkVHlwZSA9IHRoaXMuX2dldFR5cGUoaW5wdXQpO1xuICAgICAgICBpZiAocGFyc2VkVHlwZSA9PT0gWm9kUGFyc2VkVHlwZS5udWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gT0sobnVsbCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi5pbm5lclR5cGUuX3BhcnNlKGlucHV0KTtcbiAgICB9XG4gICAgdW53cmFwKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmLmlubmVyVHlwZTtcbiAgICB9XG59XG5ab2ROdWxsYWJsZS5jcmVhdGUgPSAodHlwZSwgcGFyYW1zKT0+e1xuICAgIHJldHVybiBuZXcgWm9kTnVsbGFibGUoe1xuICAgICAgICBpbm5lclR5cGU6IHR5cGUsXG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kTnVsbGFibGUsXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufTtcbmV4cG9ydCBjbGFzcyBab2REZWZhdWx0IGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpO1xuICAgICAgICBsZXQgZGF0YSA9IGN0eC5kYXRhO1xuICAgICAgICBpZiAoY3R4LnBhcnNlZFR5cGUgPT09IFpvZFBhcnNlZFR5cGUudW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBkYXRhID0gdGhpcy5fZGVmLmRlZmF1bHRWYWx1ZSgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYuaW5uZXJUeXBlLl9wYXJzZSh7XG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgcGF0aDogY3R4LnBhdGgsXG4gICAgICAgICAgICBwYXJlbnQ6IGN0eFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmVtb3ZlRGVmYXVsdCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi5pbm5lclR5cGU7XG4gICAgfVxufVxuWm9kRGVmYXVsdC5jcmVhdGUgPSAodHlwZSwgcGFyYW1zKT0+e1xuICAgIHJldHVybiBuZXcgWm9kRGVmYXVsdCh7XG4gICAgICAgIGlubmVyVHlwZTogdHlwZSxcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2REZWZhdWx0LFxuICAgICAgICBkZWZhdWx0VmFsdWU6IHR5cGVvZiBwYXJhbXMuZGVmYXVsdCA9PT0gXCJmdW5jdGlvblwiID8gcGFyYW1zLmRlZmF1bHQgOiAoKT0+cGFyYW1zLmRlZmF1bHQsXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufTtcbmV4cG9ydCBjbGFzcyBab2RDYXRjaCBleHRlbmRzIFpvZFR5cGUge1xuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBjb25zdCB7IGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTtcbiAgICAgICAgLy8gbmV3Q3R4IGlzIHVzZWQgdG8gbm90IGNvbGxlY3QgaXNzdWVzIGZyb20gaW5uZXIgdHlwZXMgaW4gY3R4XG4gICAgICAgIGNvbnN0IG5ld0N0eCA9IHtcbiAgICAgICAgICAgIC4uLmN0eCxcbiAgICAgICAgICAgIGNvbW1vbjoge1xuICAgICAgICAgICAgICAgIC4uLmN0eC5jb21tb24sXG4gICAgICAgICAgICAgICAgaXNzdWVzOiBbXVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCByZXN1bHQgPSB0aGlzLl9kZWYuaW5uZXJUeXBlLl9wYXJzZSh7XG4gICAgICAgICAgICBkYXRhOiBuZXdDdHguZGF0YSxcbiAgICAgICAgICAgIHBhdGg6IG5ld0N0eC5wYXRoLFxuICAgICAgICAgICAgcGFyZW50OiB7XG4gICAgICAgICAgICAgICAgLi4ubmV3Q3R4XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoaXNBc3luYyhyZXN1bHQpKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0LnRoZW4oKHJlc3VsdCk9PntcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXM6IFwidmFsaWRcIixcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHJlc3VsdC5zdGF0dXMgPT09IFwidmFsaWRcIiA/IHJlc3VsdC52YWx1ZSA6IHRoaXMuX2RlZi5jYXRjaFZhbHVlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldCBlcnJvciAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBab2RFcnJvcihuZXdDdHguY29tbW9uLmlzc3Vlcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQ6IG5ld0N0eC5kYXRhXG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBzdGF0dXM6IFwidmFsaWRcIixcbiAgICAgICAgICAgICAgICB2YWx1ZTogcmVzdWx0LnN0YXR1cyA9PT0gXCJ2YWxpZFwiID8gcmVzdWx0LnZhbHVlIDogdGhpcy5fZGVmLmNhdGNoVmFsdWUoe1xuICAgICAgICAgICAgICAgICAgICBnZXQgZXJyb3IgKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBab2RFcnJvcihuZXdDdHguY29tbW9uLmlzc3Vlcyk7XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGlucHV0OiBuZXdDdHguZGF0YVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfVxuICAgIHJlbW92ZUNhdGNoKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmLmlubmVyVHlwZTtcbiAgICB9XG59XG5ab2RDYXRjaC5jcmVhdGUgPSAodHlwZSwgcGFyYW1zKT0+e1xuICAgIHJldHVybiBuZXcgWm9kQ2F0Y2goe1xuICAgICAgICBpbm5lclR5cGU6IHR5cGUsXG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kQ2F0Y2gsXG4gICAgICAgIGNhdGNoVmFsdWU6IHR5cGVvZiBwYXJhbXMuY2F0Y2ggPT09IFwiZnVuY3Rpb25cIiA/IHBhcmFtcy5jYXRjaCA6ICgpPT5wYXJhbXMuY2F0Y2gsXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufTtcbmV4cG9ydCBjbGFzcyBab2ROYU4gZXh0ZW5kcyBab2RUeXBlIHtcbiAgICBfcGFyc2UoaW5wdXQpIHtcbiAgICAgICAgY29uc3QgcGFyc2VkVHlwZSA9IHRoaXMuX2dldFR5cGUoaW5wdXQpO1xuICAgICAgICBpZiAocGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS5uYW4pIHtcbiAgICAgICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTtcbiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3R5cGUsXG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IFpvZFBhcnNlZFR5cGUubmFuLFxuICAgICAgICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3RhdHVzOiBcInZhbGlkXCIsXG4gICAgICAgICAgICB2YWx1ZTogaW5wdXQuZGF0YVxuICAgICAgICB9O1xuICAgIH1cbn1cblpvZE5hTi5jcmVhdGUgPSAocGFyYW1zKT0+e1xuICAgIHJldHVybiBuZXcgWm9kTmFOKHtcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2ROYU4sXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKVxuICAgIH0pO1xufTtcbmV4cG9ydCBjb25zdCBCUkFORCA9IFN5bWJvbChcInpvZF9icmFuZFwiKTtcbmV4cG9ydCBjbGFzcyBab2RCcmFuZGVkIGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpO1xuICAgICAgICBjb25zdCBkYXRhID0gY3R4LmRhdGE7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYudHlwZS5fcGFyc2Uoe1xuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgcGFyZW50OiBjdHhcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHVud3JhcCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi50eXBlO1xuICAgIH1cbn1cbmV4cG9ydCBjbGFzcyBab2RQaXBlbGluZSBleHRlbmRzIFpvZFR5cGUge1xuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBjb25zdCB7IHN0YXR1cywgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpO1xuICAgICAgICBpZiAoY3R4LmNvbW1vbi5hc3luYykge1xuICAgICAgICAgICAgY29uc3QgaGFuZGxlQXN5bmMgPSBhc3luYyAoKT0+e1xuICAgICAgICAgICAgICAgIGNvbnN0IGluUmVzdWx0ID0gYXdhaXQgdGhpcy5fZGVmLmluLl9wYXJzZUFzeW5jKHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YTogY3R4LmRhdGEsXG4gICAgICAgICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IGN0eFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGlmIChpblJlc3VsdC5zdGF0dXMgPT09IFwiYWJvcnRlZFwiKSByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgICAgICAgICBpZiAoaW5SZXN1bHQuc3RhdHVzID09PSBcImRpcnR5XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBESVJUWShpblJlc3VsdC52YWx1ZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi5vdXQuX3BhcnNlQXN5bmMoe1xuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YTogaW5SZXN1bHQudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXRoOiBjdHgucGF0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudDogY3R4XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICByZXR1cm4gaGFuZGxlQXN5bmMoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGluUmVzdWx0ID0gdGhpcy5fZGVmLmluLl9wYXJzZVN5bmMoe1xuICAgICAgICAgICAgICAgIGRhdGE6IGN0eC5kYXRhLFxuICAgICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgICAgIHBhcmVudDogY3R4XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmIChpblJlc3VsdC5zdGF0dXMgPT09IFwiYWJvcnRlZFwiKSByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgICAgIGlmIChpblJlc3VsdC5zdGF0dXMgPT09IFwiZGlydHlcIikge1xuICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1czogXCJkaXJ0eVwiLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogaW5SZXN1bHQudmFsdWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fZGVmLm91dC5fcGFyc2VTeW5jKHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YTogaW5SZXN1bHQudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IGN0eFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHN0YXRpYyBjcmVhdGUoYSwgYikge1xuICAgICAgICByZXR1cm4gbmV3IFpvZFBpcGVsaW5lKHtcbiAgICAgICAgICAgIGluOiBhLFxuICAgICAgICAgICAgb3V0OiBiLFxuICAgICAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RQaXBlbGluZVxuICAgICAgICB9KTtcbiAgICB9XG59XG5leHBvcnQgY2xhc3MgWm9kUmVhZG9ubHkgZXh0ZW5kcyBab2RUeXBlIHtcbiAgICBfcGFyc2UoaW5wdXQpIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5fZGVmLmlubmVyVHlwZS5fcGFyc2UoaW5wdXQpO1xuICAgICAgICBjb25zdCBmcmVlemUgPSAoZGF0YSk9PntcbiAgICAgICAgICAgIGlmIChpc1ZhbGlkKGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgZGF0YS52YWx1ZSA9IE9iamVjdC5mcmVlemUoZGF0YS52YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZGF0YTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIGlzQXN5bmMocmVzdWx0KSA/IHJlc3VsdC50aGVuKChkYXRhKT0+ZnJlZXplKGRhdGEpKSA6IGZyZWV6ZShyZXN1bHQpO1xuICAgIH1cbiAgICB1bndyYXAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYuaW5uZXJUeXBlO1xuICAgIH1cbn1cblpvZFJlYWRvbmx5LmNyZWF0ZSA9ICh0eXBlLCBwYXJhbXMpPT57XG4gICAgcmV0dXJuIG5ldyBab2RSZWFkb25seSh7XG4gICAgICAgIGlubmVyVHlwZTogdHlwZSxcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RSZWFkb25seSxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpXG4gICAgfSk7XG59O1xuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8vLy8vLy8vLyAgICAgICAgICAgICAgICAgICAgLy8vLy8vLy8vL1xuLy8vLy8vLy8vLyAgICAgIHouY3VzdG9tICAgICAgLy8vLy8vLy8vL1xuLy8vLy8vLy8vLyAgICAgICAgICAgICAgICAgICAgLy8vLy8vLy8vL1xuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuZnVuY3Rpb24gY2xlYW5QYXJhbXMocGFyYW1zLCBkYXRhKSB7XG4gICAgY29uc3QgcCA9IHR5cGVvZiBwYXJhbXMgPT09IFwiZnVuY3Rpb25cIiA/IHBhcmFtcyhkYXRhKSA6IHR5cGVvZiBwYXJhbXMgPT09IFwic3RyaW5nXCIgPyB7XG4gICAgICAgIG1lc3NhZ2U6IHBhcmFtc1xuICAgIH0gOiBwYXJhbXM7XG4gICAgY29uc3QgcDIgPSB0eXBlb2YgcCA9PT0gXCJzdHJpbmdcIiA/IHtcbiAgICAgICAgbWVzc2FnZTogcFxuICAgIH0gOiBwO1xuICAgIHJldHVybiBwMjtcbn1cbmV4cG9ydCBmdW5jdGlvbiBjdXN0b20oY2hlY2ssIF9wYXJhbXMgPSB7fSwgLyoqXG4gKiBAZGVwcmVjYXRlZFxuICpcbiAqIFBhc3MgYGZhdGFsYCBpbnRvIHRoZSBwYXJhbXMgb2JqZWN0IGluc3RlYWQ6XG4gKlxuICogYGBgdHNcbiAqIHouc3RyaW5nKCkuY3VzdG9tKCh2YWwpID0+IHZhbC5sZW5ndGggPiA1LCB7IGZhdGFsOiBmYWxzZSB9KVxuICogYGBgXG4gKlxuICovIGZhdGFsKSB7XG4gICAgaWYgKGNoZWNrKSByZXR1cm4gWm9kQW55LmNyZWF0ZSgpLnN1cGVyUmVmaW5lKChkYXRhLCBjdHgpPT57XG4gICAgICAgIGNvbnN0IHIgPSBjaGVjayhkYXRhKTtcbiAgICAgICAgaWYgKHIgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm4gci50aGVuKChyKT0+e1xuICAgICAgICAgICAgICAgIGlmICghcikge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXJhbXMgPSBjbGVhblBhcmFtcyhfcGFyYW1zLCBkYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgX2ZhdGFsID0gcGFyYW1zLmZhdGFsID8/IGZhdGFsID8/IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGN0eC5hZGRJc3N1ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBcImN1c3RvbVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgLi4ucGFyYW1zLFxuICAgICAgICAgICAgICAgICAgICAgICAgZmF0YWw6IF9mYXRhbFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXIpIHtcbiAgICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IGNsZWFuUGFyYW1zKF9wYXJhbXMsIGRhdGEpO1xuICAgICAgICAgICAgY29uc3QgX2ZhdGFsID0gcGFyYW1zLmZhdGFsID8/IGZhdGFsID8/IHRydWU7XG4gICAgICAgICAgICBjdHguYWRkSXNzdWUoe1xuICAgICAgICAgICAgICAgIGNvZGU6IFwiY3VzdG9tXCIsXG4gICAgICAgICAgICAgICAgLi4ucGFyYW1zLFxuICAgICAgICAgICAgICAgIGZhdGFsOiBfZmF0YWxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICB9KTtcbiAgICByZXR1cm4gWm9kQW55LmNyZWF0ZSgpO1xufVxuZXhwb3J0IHsgWm9kVHlwZSBhcyBTY2hlbWEsIFpvZFR5cGUgYXMgWm9kU2NoZW1hIH07XG5leHBvcnQgY29uc3QgbGF0ZSA9IHtcbiAgICBvYmplY3Q6IFpvZE9iamVjdC5sYXp5Y3JlYXRlXG59O1xuZXhwb3J0IHZhciBab2RGaXJzdFBhcnR5VHlwZUtpbmQ7XG4oZnVuY3Rpb24oWm9kRmlyc3RQYXJ0eVR5cGVLaW5kKSB7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kU3RyaW5nXCJdID0gXCJab2RTdHJpbmdcIjtcbiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmRbXCJab2ROdW1iZXJcIl0gPSBcIlpvZE51bWJlclwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZE5hTlwiXSA9IFwiWm9kTmFOXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kQmlnSW50XCJdID0gXCJab2RCaWdJbnRcIjtcbiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmRbXCJab2RCb29sZWFuXCJdID0gXCJab2RCb29sZWFuXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kRGF0ZVwiXSA9IFwiWm9kRGF0ZVwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZFN5bWJvbFwiXSA9IFwiWm9kU3ltYm9sXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kVW5kZWZpbmVkXCJdID0gXCJab2RVbmRlZmluZWRcIjtcbiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmRbXCJab2ROdWxsXCJdID0gXCJab2ROdWxsXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kQW55XCJdID0gXCJab2RBbnlcIjtcbiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmRbXCJab2RVbmtub3duXCJdID0gXCJab2RVbmtub3duXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kTmV2ZXJcIl0gPSBcIlpvZE5ldmVyXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kVm9pZFwiXSA9IFwiWm9kVm9pZFwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZEFycmF5XCJdID0gXCJab2RBcnJheVwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZE9iamVjdFwiXSA9IFwiWm9kT2JqZWN0XCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kVW5pb25cIl0gPSBcIlpvZFVuaW9uXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kRGlzY3JpbWluYXRlZFVuaW9uXCJdID0gXCJab2REaXNjcmltaW5hdGVkVW5pb25cIjtcbiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmRbXCJab2RJbnRlcnNlY3Rpb25cIl0gPSBcIlpvZEludGVyc2VjdGlvblwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZFR1cGxlXCJdID0gXCJab2RUdXBsZVwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZFJlY29yZFwiXSA9IFwiWm9kUmVjb3JkXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kTWFwXCJdID0gXCJab2RNYXBcIjtcbiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmRbXCJab2RTZXRcIl0gPSBcIlpvZFNldFwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZEZ1bmN0aW9uXCJdID0gXCJab2RGdW5jdGlvblwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZExhenlcIl0gPSBcIlpvZExhenlcIjtcbiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmRbXCJab2RMaXRlcmFsXCJdID0gXCJab2RMaXRlcmFsXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kRW51bVwiXSA9IFwiWm9kRW51bVwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZEVmZmVjdHNcIl0gPSBcIlpvZEVmZmVjdHNcIjtcbiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmRbXCJab2ROYXRpdmVFbnVtXCJdID0gXCJab2ROYXRpdmVFbnVtXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kT3B0aW9uYWxcIl0gPSBcIlpvZE9wdGlvbmFsXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kTnVsbGFibGVcIl0gPSBcIlpvZE51bGxhYmxlXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kRGVmYXVsdFwiXSA9IFwiWm9kRGVmYXVsdFwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZENhdGNoXCJdID0gXCJab2RDYXRjaFwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZFByb21pc2VcIl0gPSBcIlpvZFByb21pc2VcIjtcbiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmRbXCJab2RCcmFuZGVkXCJdID0gXCJab2RCcmFuZGVkXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kUGlwZWxpbmVcIl0gPSBcIlpvZFBpcGVsaW5lXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kUmVhZG9ubHlcIl0gPSBcIlpvZFJlYWRvbmx5XCI7XG59KShab2RGaXJzdFBhcnR5VHlwZUtpbmQgfHwgKFpvZEZpcnN0UGFydHlUeXBlS2luZCA9IHt9KSk7XG4vLyByZXF1aXJlcyBUUyA0LjQrXG5jbGFzcyBDbGFzcyB7XG4gICAgY29uc3RydWN0b3IoLi4uXyl7fVxufVxuY29uc3QgaW5zdGFuY2VPZlR5cGUgPSAoLy8gY29uc3QgaW5zdGFuY2VPZlR5cGUgPSA8VCBleHRlbmRzIG5ldyAoLi4uYXJnczogYW55W10pID0+IGFueT4oXG5jbHMsIHBhcmFtcyA9IHtcbiAgICBtZXNzYWdlOiBgSW5wdXQgbm90IGluc3RhbmNlIG9mICR7Y2xzLm5hbWV9YFxufSk9PmN1c3RvbSgoZGF0YSk9PmRhdGEgaW5zdGFuY2VvZiBjbHMsIHBhcmFtcyk7XG5jb25zdCBzdHJpbmdUeXBlID0gWm9kU3RyaW5nLmNyZWF0ZTtcbmNvbnN0IG51bWJlclR5cGUgPSBab2ROdW1iZXIuY3JlYXRlO1xuY29uc3QgbmFuVHlwZSA9IFpvZE5hTi5jcmVhdGU7XG5jb25zdCBiaWdJbnRUeXBlID0gWm9kQmlnSW50LmNyZWF0ZTtcbmNvbnN0IGJvb2xlYW5UeXBlID0gWm9kQm9vbGVhbi5jcmVhdGU7XG5jb25zdCBkYXRlVHlwZSA9IFpvZERhdGUuY3JlYXRlO1xuY29uc3Qgc3ltYm9sVHlwZSA9IFpvZFN5bWJvbC5jcmVhdGU7XG5jb25zdCB1bmRlZmluZWRUeXBlID0gWm9kVW5kZWZpbmVkLmNyZWF0ZTtcbmNvbnN0IG51bGxUeXBlID0gWm9kTnVsbC5jcmVhdGU7XG5jb25zdCBhbnlUeXBlID0gWm9kQW55LmNyZWF0ZTtcbmNvbnN0IHVua25vd25UeXBlID0gWm9kVW5rbm93bi5jcmVhdGU7XG5jb25zdCBuZXZlclR5cGUgPSBab2ROZXZlci5jcmVhdGU7XG5jb25zdCB2b2lkVHlwZSA9IFpvZFZvaWQuY3JlYXRlO1xuY29uc3QgYXJyYXlUeXBlID0gWm9kQXJyYXkuY3JlYXRlO1xuY29uc3Qgb2JqZWN0VHlwZSA9IFpvZE9iamVjdC5jcmVhdGU7XG5jb25zdCBzdHJpY3RPYmplY3RUeXBlID0gWm9kT2JqZWN0LnN0cmljdENyZWF0ZTtcbmNvbnN0IHVuaW9uVHlwZSA9IFpvZFVuaW9uLmNyZWF0ZTtcbmNvbnN0IGRpc2NyaW1pbmF0ZWRVbmlvblR5cGUgPSBab2REaXNjcmltaW5hdGVkVW5pb24uY3JlYXRlO1xuY29uc3QgaW50ZXJzZWN0aW9uVHlwZSA9IFpvZEludGVyc2VjdGlvbi5jcmVhdGU7XG5jb25zdCB0dXBsZVR5cGUgPSBab2RUdXBsZS5jcmVhdGU7XG5jb25zdCByZWNvcmRUeXBlID0gWm9kUmVjb3JkLmNyZWF0ZTtcbmNvbnN0IG1hcFR5cGUgPSBab2RNYXAuY3JlYXRlO1xuY29uc3Qgc2V0VHlwZSA9IFpvZFNldC5jcmVhdGU7XG5jb25zdCBmdW5jdGlvblR5cGUgPSBab2RGdW5jdGlvbi5jcmVhdGU7XG5jb25zdCBsYXp5VHlwZSA9IFpvZExhenkuY3JlYXRlO1xuY29uc3QgbGl0ZXJhbFR5cGUgPSBab2RMaXRlcmFsLmNyZWF0ZTtcbmNvbnN0IGVudW1UeXBlID0gWm9kRW51bS5jcmVhdGU7XG5jb25zdCBuYXRpdmVFbnVtVHlwZSA9IFpvZE5hdGl2ZUVudW0uY3JlYXRlO1xuY29uc3QgcHJvbWlzZVR5cGUgPSBab2RQcm9taXNlLmNyZWF0ZTtcbmNvbnN0IGVmZmVjdHNUeXBlID0gWm9kRWZmZWN0cy5jcmVhdGU7XG5jb25zdCBvcHRpb25hbFR5cGUgPSBab2RPcHRpb25hbC5jcmVhdGU7XG5jb25zdCBudWxsYWJsZVR5cGUgPSBab2ROdWxsYWJsZS5jcmVhdGU7XG5jb25zdCBwcmVwcm9jZXNzVHlwZSA9IFpvZEVmZmVjdHMuY3JlYXRlV2l0aFByZXByb2Nlc3M7XG5jb25zdCBwaXBlbGluZVR5cGUgPSBab2RQaXBlbGluZS5jcmVhdGU7XG5jb25zdCBvc3RyaW5nID0gKCk9PnN0cmluZ1R5cGUoKS5vcHRpb25hbCgpO1xuY29uc3Qgb251bWJlciA9ICgpPT5udW1iZXJUeXBlKCkub3B0aW9uYWwoKTtcbmNvbnN0IG9ib29sZWFuID0gKCk9PmJvb2xlYW5UeXBlKCkub3B0aW9uYWwoKTtcbmV4cG9ydCBjb25zdCBjb2VyY2UgPSB7XG4gICAgc3RyaW5nOiAoYXJnKT0+Wm9kU3RyaW5nLmNyZWF0ZSh7XG4gICAgICAgICAgICAuLi5hcmcsXG4gICAgICAgICAgICBjb2VyY2U6IHRydWVcbiAgICAgICAgfSksXG4gICAgbnVtYmVyOiAoYXJnKT0+Wm9kTnVtYmVyLmNyZWF0ZSh7XG4gICAgICAgICAgICAuLi5hcmcsXG4gICAgICAgICAgICBjb2VyY2U6IHRydWVcbiAgICAgICAgfSksXG4gICAgYm9vbGVhbjogKGFyZyk9PlpvZEJvb2xlYW4uY3JlYXRlKHtcbiAgICAgICAgICAgIC4uLmFyZyxcbiAgICAgICAgICAgIGNvZXJjZTogdHJ1ZVxuICAgICAgICB9KSxcbiAgICBiaWdpbnQ6IChhcmcpPT5ab2RCaWdJbnQuY3JlYXRlKHtcbiAgICAgICAgICAgIC4uLmFyZyxcbiAgICAgICAgICAgIGNvZXJjZTogdHJ1ZVxuICAgICAgICB9KSxcbiAgICBkYXRlOiAoYXJnKT0+Wm9kRGF0ZS5jcmVhdGUoe1xuICAgICAgICAgICAgLi4uYXJnLFxuICAgICAgICAgICAgY29lcmNlOiB0cnVlXG4gICAgICAgIH0pXG59O1xuZXhwb3J0IHsgYW55VHlwZSBhcyBhbnksIGFycmF5VHlwZSBhcyBhcnJheSwgYmlnSW50VHlwZSBhcyBiaWdpbnQsIGJvb2xlYW5UeXBlIGFzIGJvb2xlYW4sIGRhdGVUeXBlIGFzIGRhdGUsIGRpc2NyaW1pbmF0ZWRVbmlvblR5cGUgYXMgZGlzY3JpbWluYXRlZFVuaW9uLCBlZmZlY3RzVHlwZSBhcyBlZmZlY3QsIGVudW1UeXBlIGFzIGVudW0sIGZ1bmN0aW9uVHlwZSBhcyBmdW5jdGlvbiwgaW5zdGFuY2VPZlR5cGUgYXMgaW5zdGFuY2VvZiwgaW50ZXJzZWN0aW9uVHlwZSBhcyBpbnRlcnNlY3Rpb24sIGxhenlUeXBlIGFzIGxhenksIGxpdGVyYWxUeXBlIGFzIGxpdGVyYWwsIG1hcFR5cGUgYXMgbWFwLCBuYW5UeXBlIGFzIG5hbiwgbmF0aXZlRW51bVR5cGUgYXMgbmF0aXZlRW51bSwgbmV2ZXJUeXBlIGFzIG5ldmVyLCBudWxsVHlwZSBhcyBudWxsLCBudWxsYWJsZVR5cGUgYXMgbnVsbGFibGUsIG51bWJlclR5cGUgYXMgbnVtYmVyLCBvYmplY3RUeXBlIGFzIG9iamVjdCwgb2Jvb2xlYW4sIG9udW1iZXIsIG9wdGlvbmFsVHlwZSBhcyBvcHRpb25hbCwgb3N0cmluZywgcGlwZWxpbmVUeXBlIGFzIHBpcGVsaW5lLCBwcmVwcm9jZXNzVHlwZSBhcyBwcmVwcm9jZXNzLCBwcm9taXNlVHlwZSBhcyBwcm9taXNlLCByZWNvcmRUeXBlIGFzIHJlY29yZCwgc2V0VHlwZSBhcyBzZXQsIHN0cmljdE9iamVjdFR5cGUgYXMgc3RyaWN0T2JqZWN0LCBzdHJpbmdUeXBlIGFzIHN0cmluZywgc3ltYm9sVHlwZSBhcyBzeW1ib2wsIGVmZmVjdHNUeXBlIGFzIHRyYW5zZm9ybWVyLCB0dXBsZVR5cGUgYXMgdHVwbGUsIHVuZGVmaW5lZFR5cGUgYXMgdW5kZWZpbmVkLCB1bmlvblR5cGUgYXMgdW5pb24sIHVua25vd25UeXBlIGFzIHVua25vd24sIHZvaWRUeXBlIGFzIHZvaWQgfTtcbmV4cG9ydCBjb25zdCBORVZFUiA9IElOVkFMSUQ7XG4iLCAiZXhwb3J0IGZ1bmN0aW9uIGNvbWJpbmVIZWFkZXJzKFxuICAuLi5oZWFkZXJzOiBBcnJheTxSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+IHwgdW5kZWZpbmVkPlxuKTogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gIHJldHVybiBoZWFkZXJzLnJlZHVjZShcbiAgICAoY29tYmluZWRIZWFkZXJzLCBjdXJyZW50SGVhZGVycykgPT4gKHtcbiAgICAgIC4uLmNvbWJpbmVkSGVhZGVycyxcbiAgICAgIC4uLihjdXJyZW50SGVhZGVycyA/PyB7fSksXG4gICAgfSksXG4gICAge30sXG4gICkgYXMgUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPjtcbn1cbiIsICIvKipcbiAqIENvbnZlcnRzIGFuIEFzeW5jSXRlcmF0b3IgdG8gYSBSZWFkYWJsZVN0cmVhbS5cbiAqXG4gKiBAdGVtcGxhdGUgVCAtIFRoZSB0eXBlIG9mIGVsZW1lbnRzIHByb2R1Y2VkIGJ5IHRoZSBBc3luY0l0ZXJhdG9yLlxuICogQHBhcmFtIHsgPFQ+fSBpdGVyYXRvciAtIFRoZSBBc3luY0l0ZXJhdG9yIHRvIGNvbnZlcnQuXG4gKiBAcmV0dXJucyB7UmVhZGFibGVTdHJlYW08VD59IC0gQSBSZWFkYWJsZVN0cmVhbSB0aGF0IHByb3ZpZGVzIHRoZSBzYW1lIGRhdGEgYXMgdGhlIEFzeW5jSXRlcmF0b3IuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb252ZXJ0QXN5bmNJdGVyYXRvclRvUmVhZGFibGVTdHJlYW08VD4oXG4gIGl0ZXJhdG9yOiBBc3luY0l0ZXJhdG9yPFQ+LFxuKTogUmVhZGFibGVTdHJlYW08VD4ge1xuICByZXR1cm4gbmV3IFJlYWRhYmxlU3RyZWFtPFQ+KHtcbiAgICAvKipcbiAgICAgKiBDYWxsZWQgd2hlbiB0aGUgY29uc3VtZXIgd2FudHMgdG8gcHVsbCBtb3JlIGRhdGEgZnJvbSB0aGUgc3RyZWFtLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyPFQ+fSBjb250cm9sbGVyIC0gVGhlIGNvbnRyb2xsZXIgdG8gZW5xdWV1ZSBkYXRhIGludG8gdGhlIHN0cmVhbS5cbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICAgKi9cbiAgICBhc3luYyBwdWxsKGNvbnRyb2xsZXIpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHsgdmFsdWUsIGRvbmUgfSA9IGF3YWl0IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICBjb250cm9sbGVyLmNsb3NlKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgY29udHJvbGxlci5lcnJvcihlcnJvcik7XG4gICAgICB9XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBDYWxsZWQgd2hlbiB0aGUgY29uc3VtZXIgY2FuY2VscyB0aGUgc3RyZWFtLlxuICAgICAqL1xuICAgIGNhbmNlbCgpIHt9LFxuICB9KTtcbn1cbiIsICIvKipcbiAqIENyZWF0ZXMgYSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgYWZ0ZXIgYSBzcGVjaWZpZWQgZGVsYXlcbiAqIEBwYXJhbSBkZWxheUluTXMgLSBUaGUgZGVsYXkgZHVyYXRpb24gaW4gbWlsbGlzZWNvbmRzLiBJZiBudWxsIG9yIHVuZGVmaW5lZCwgcmVzb2x2ZXMgaW1tZWRpYXRlbHkuXG4gKiBAcGFyYW0gc2lnbmFsIC0gT3B0aW9uYWwgQWJvcnRTaWduYWwgdG8gY2FuY2VsIHRoZSBkZWxheVxuICogQHJldHVybnMgQSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgYWZ0ZXIgdGhlIHNwZWNpZmllZCBkZWxheVxuICogQHRocm93cyB7RE9NRXhjZXB0aW9ufSBXaGVuIHRoZSBzaWduYWwgaXMgYWJvcnRlZFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZGVsYXkoXG4gIGRlbGF5SW5Ncz86IG51bWJlciB8IG51bGwsXG4gIG9wdGlvbnM/OiB7XG4gICAgYWJvcnRTaWduYWw/OiBBYm9ydFNpZ25hbDtcbiAgfSxcbik6IFByb21pc2U8dm9pZD4ge1xuICBpZiAoZGVsYXlJbk1zID09IG51bGwpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICBjb25zdCBzaWduYWwgPSBvcHRpb25zPy5hYm9ydFNpZ25hbDtcblxuICByZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGlmIChzaWduYWw/LmFib3J0ZWQpIHtcbiAgICAgIHJlamVjdChjcmVhdGVBYm9ydEVycm9yKCkpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgY2xlYW51cCgpO1xuICAgICAgcmVzb2x2ZSgpO1xuICAgIH0sIGRlbGF5SW5Ncyk7XG5cbiAgICBjb25zdCBjbGVhbnVwID0gKCkgPT4ge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZCk7XG4gICAgICBzaWduYWw/LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2Fib3J0Jywgb25BYm9ydCk7XG4gICAgfTtcblxuICAgIGNvbnN0IG9uQWJvcnQgPSAoKSA9PiB7XG4gICAgICBjbGVhbnVwKCk7XG4gICAgICByZWplY3QoY3JlYXRlQWJvcnRFcnJvcigpKTtcbiAgICB9O1xuXG4gICAgc2lnbmFsPy5hZGRFdmVudExpc3RlbmVyKCdhYm9ydCcsIG9uQWJvcnQpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlQWJvcnRFcnJvcigpOiBET01FeGNlcHRpb24ge1xuICByZXR1cm4gbmV3IERPTUV4Y2VwdGlvbignRGVsYXkgd2FzIGFib3J0ZWQnLCAnQWJvcnRFcnJvcicpO1xufVxuIiwgIi8qKlxuRXh0cmFjdHMgdGhlIGhlYWRlcnMgZnJvbSBhIHJlc3BvbnNlIG9iamVjdCBhbmQgcmV0dXJucyB0aGVtIGFzIGEga2V5LXZhbHVlIG9iamVjdC5cblxuQHBhcmFtIHJlc3BvbnNlIC0gVGhlIHJlc3BvbnNlIG9iamVjdCB0byBleHRyYWN0IGhlYWRlcnMgZnJvbS5cbkByZXR1cm5zIFRoZSBoZWFkZXJzIGFzIGEga2V5LXZhbHVlIG9iamVjdC5cbiovXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdFJlc3BvbnNlSGVhZGVycyhyZXNwb25zZTogUmVzcG9uc2UpIHtcbiAgcmV0dXJuIE9iamVjdC5mcm9tRW50cmllczxzdHJpbmc+KFsuLi5yZXNwb25zZS5oZWFkZXJzXSk7XG59XG4iLCAiaW1wb3J0IHsgSW52YWxpZEFyZ3VtZW50RXJyb3IgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcblxuLyoqXG5DcmVhdGVzIGFuIElEIGdlbmVyYXRvci5cblRoZSB0b3RhbCBsZW5ndGggb2YgdGhlIElEIGlzIHRoZSBzdW0gb2YgdGhlIHByZWZpeCwgc2VwYXJhdG9yLCBhbmQgcmFuZG9tIHBhcnQgbGVuZ3RoLlxuTm90IGNyeXB0b2dyYXBoaWNhbGx5IHNlY3VyZS5cblxuQHBhcmFtIGFscGhhYmV0IC0gVGhlIGFscGhhYmV0IHRvIHVzZSBmb3IgdGhlIElELiBEZWZhdWx0OiAnMDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXonLlxuQHBhcmFtIHByZWZpeCAtIFRoZSBwcmVmaXggb2YgdGhlIElEIHRvIGdlbmVyYXRlLiBPcHRpb25hbC5cbkBwYXJhbSBzZXBhcmF0b3IgLSBUaGUgc2VwYXJhdG9yIGJldHdlZW4gdGhlIHByZWZpeCBhbmQgdGhlIHJhbmRvbSBwYXJ0IG9mIHRoZSBJRC4gRGVmYXVsdDogJy0nLlxuQHBhcmFtIHNpemUgLSBUaGUgc2l6ZSBvZiB0aGUgcmFuZG9tIHBhcnQgb2YgdGhlIElEIHRvIGdlbmVyYXRlLiBEZWZhdWx0OiAxNi5cbiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUlkR2VuZXJhdG9yID0gKHtcbiAgcHJlZml4LFxuICBzaXplID0gMTYsXG4gIGFscGhhYmV0ID0gJzAxMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6JyxcbiAgc2VwYXJhdG9yID0gJy0nLFxufToge1xuICBwcmVmaXg/OiBzdHJpbmc7XG4gIHNlcGFyYXRvcj86IHN0cmluZztcbiAgc2l6ZT86IG51bWJlcjtcbiAgYWxwaGFiZXQ/OiBzdHJpbmc7XG59ID0ge30pOiBJZEdlbmVyYXRvciA9PiB7XG4gIGNvbnN0IGdlbmVyYXRvciA9ICgpID0+IHtcbiAgICBjb25zdCBhbHBoYWJldExlbmd0aCA9IGFscGhhYmV0Lmxlbmd0aDtcbiAgICBjb25zdCBjaGFycyA9IG5ldyBBcnJheShzaXplKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNpemU7IGkrKykge1xuICAgICAgY2hhcnNbaV0gPSBhbHBoYWJldFsoTWF0aC5yYW5kb20oKSAqIGFscGhhYmV0TGVuZ3RoKSB8IDBdO1xuICAgIH1cbiAgICByZXR1cm4gY2hhcnMuam9pbignJyk7XG4gIH07XG5cbiAgaWYgKHByZWZpeCA9PSBudWxsKSB7XG4gICAgcmV0dXJuIGdlbmVyYXRvcjtcbiAgfVxuXG4gIC8vIGNoZWNrIHRoYXQgdGhlIHByZWZpeCBpcyBub3QgcGFydCBvZiB0aGUgYWxwaGFiZXQgKG90aGVyd2lzZSBwcmVmaXggY2hlY2tpbmcgY2FuIGZhaWwgcmFuZG9tbHkpXG4gIGlmIChhbHBoYWJldC5pbmNsdWRlcyhzZXBhcmF0b3IpKSB7XG4gICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEVycm9yKHtcbiAgICAgIGFyZ3VtZW50OiAnc2VwYXJhdG9yJyxcbiAgICAgIG1lc3NhZ2U6IGBUaGUgc2VwYXJhdG9yIFwiJHtzZXBhcmF0b3J9XCIgbXVzdCBub3QgYmUgcGFydCBvZiB0aGUgYWxwaGFiZXQgXCIke2FscGhhYmV0fVwiLmAsXG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gKCkgPT4gYCR7cHJlZml4fSR7c2VwYXJhdG9yfSR7Z2VuZXJhdG9yKCl9YDtcbn07XG5cbi8qKlxuQSBmdW5jdGlvbiB0aGF0IGdlbmVyYXRlcyBhbiBJRC5cbiAqL1xuZXhwb3J0IHR5cGUgSWRHZW5lcmF0b3IgPSAoKSA9PiBzdHJpbmc7XG5cbi8qKlxuR2VuZXJhdGVzIGEgMTYtY2hhcmFjdGVyIHJhbmRvbSBzdHJpbmcgdG8gdXNlIGZvciBJRHMuXG5Ob3QgY3J5cHRvZ3JhcGhpY2FsbHkgc2VjdXJlLlxuICovXG5leHBvcnQgY29uc3QgZ2VuZXJhdGVJZCA9IGNyZWF0ZUlkR2VuZXJhdG9yKCk7XG4iLCAiZXhwb3J0IGZ1bmN0aW9uIGdldEVycm9yTWVzc2FnZShlcnJvcjogdW5rbm93biB8IHVuZGVmaW5lZCkge1xuICBpZiAoZXJyb3IgPT0gbnVsbCkge1xuICAgIHJldHVybiAndW5rbm93biBlcnJvcic7XG4gIH1cblxuICBpZiAodHlwZW9mIGVycm9yID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBlcnJvcjtcbiAgfVxuXG4gIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgcmV0dXJuIGVycm9yLm1lc3NhZ2U7XG4gIH1cblxuICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoZXJyb3IpO1xufVxuIiwgImltcG9ydCB7IEFQSUNhbGxFcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgZXh0cmFjdFJlc3BvbnNlSGVhZGVycyB9IGZyb20gJy4vZXh0cmFjdC1yZXNwb25zZS1oZWFkZXJzJztcbmltcG9ydCB7IEZldGNoRnVuY3Rpb24gfSBmcm9tICcuL2ZldGNoLWZ1bmN0aW9uJztcbmltcG9ydCB7IGhhbmRsZUZldGNoRXJyb3IgfSBmcm9tICcuL2hhbmRsZS1mZXRjaC1lcnJvcic7XG5pbXBvcnQgeyBpc0Fib3J0RXJyb3IgfSBmcm9tICcuL2lzLWFib3J0LWVycm9yJztcbmltcG9ydCB7IFJlc3BvbnNlSGFuZGxlciB9IGZyb20gJy4vcmVzcG9uc2UtaGFuZGxlcic7XG5pbXBvcnQgeyBnZXRSdW50aW1lRW52aXJvbm1lbnRVc2VyQWdlbnQgfSBmcm9tICcuL2dldC1ydW50aW1lLWVudmlyb25tZW50LXVzZXItYWdlbnQnO1xuaW1wb3J0IHsgd2l0aFVzZXJBZ2VudFN1ZmZpeCB9IGZyb20gJy4vd2l0aC11c2VyLWFnZW50LXN1ZmZpeCc7XG5pbXBvcnQgeyBWRVJTSU9OIH0gZnJvbSAnLi92ZXJzaW9uJztcblxuLy8gdXNlIGZ1bmN0aW9uIHRvIGFsbG93IGZvciBtb2NraW5nIGluIHRlc3RzOlxuY29uc3QgZ2V0T3JpZ2luYWxGZXRjaCA9ICgpID0+IGdsb2JhbFRoaXMuZmV0Y2g7XG5cbmV4cG9ydCBjb25zdCBnZXRGcm9tQXBpID0gYXN5bmMgPFQ+KHtcbiAgdXJsLFxuICBoZWFkZXJzID0ge30sXG4gIHN1Y2Nlc3NmdWxSZXNwb25zZUhhbmRsZXIsXG4gIGZhaWxlZFJlc3BvbnNlSGFuZGxlcixcbiAgYWJvcnRTaWduYWwsXG4gIGZldGNoID0gZ2V0T3JpZ2luYWxGZXRjaCgpLFxufToge1xuICB1cmw6IHN0cmluZztcbiAgaGVhZGVycz86IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD47XG4gIGZhaWxlZFJlc3BvbnNlSGFuZGxlcjogUmVzcG9uc2VIYW5kbGVyPEVycm9yPjtcbiAgc3VjY2Vzc2Z1bFJlc3BvbnNlSGFuZGxlcjogUmVzcG9uc2VIYW5kbGVyPFQ+O1xuICBhYm9ydFNpZ25hbD86IEFib3J0U2lnbmFsO1xuICBmZXRjaD86IEZldGNoRnVuY3Rpb247XG59KSA9PiB7XG4gIHRyeSB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh1cmwsIHtcbiAgICAgIG1ldGhvZDogJ0dFVCcsXG4gICAgICBoZWFkZXJzOiB3aXRoVXNlckFnZW50U3VmZml4KFxuICAgICAgICBoZWFkZXJzLFxuICAgICAgICBgYWktc2RrL3Byb3ZpZGVyLXV0aWxzLyR7VkVSU0lPTn1gLFxuICAgICAgICBnZXRSdW50aW1lRW52aXJvbm1lbnRVc2VyQWdlbnQoKSxcbiAgICAgICksXG4gICAgICBzaWduYWw6IGFib3J0U2lnbmFsLFxuICAgIH0pO1xuXG4gICAgY29uc3QgcmVzcG9uc2VIZWFkZXJzID0gZXh0cmFjdFJlc3BvbnNlSGVhZGVycyhyZXNwb25zZSk7XG5cbiAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICBsZXQgZXJyb3JJbmZvcm1hdGlvbjoge1xuICAgICAgICB2YWx1ZTogRXJyb3I7XG4gICAgICAgIHJlc3BvbnNlSGVhZGVycz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gfCB1bmRlZmluZWQ7XG4gICAgICB9O1xuXG4gICAgICB0cnkge1xuICAgICAgICBlcnJvckluZm9ybWF0aW9uID0gYXdhaXQgZmFpbGVkUmVzcG9uc2VIYW5kbGVyKHtcbiAgICAgICAgICByZXNwb25zZSxcbiAgICAgICAgICB1cmwsXG4gICAgICAgICAgcmVxdWVzdEJvZHlWYWx1ZXM6IHt9LFxuICAgICAgICB9KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGlmIChpc0Fib3J0RXJyb3IoZXJyb3IpIHx8IEFQSUNhbGxFcnJvci5pc0luc3RhbmNlKGVycm9yKSkge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhyb3cgbmV3IEFQSUNhbGxFcnJvcih7XG4gICAgICAgICAgbWVzc2FnZTogJ0ZhaWxlZCB0byBwcm9jZXNzIGVycm9yIHJlc3BvbnNlJyxcbiAgICAgICAgICBjYXVzZTogZXJyb3IsXG4gICAgICAgICAgc3RhdHVzQ29kZTogcmVzcG9uc2Uuc3RhdHVzLFxuICAgICAgICAgIHVybCxcbiAgICAgICAgICByZXNwb25zZUhlYWRlcnMsXG4gICAgICAgICAgcmVxdWVzdEJvZHlWYWx1ZXM6IHt9LFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgdGhyb3cgZXJyb3JJbmZvcm1hdGlvbi52YWx1ZTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IHN1Y2Nlc3NmdWxSZXNwb25zZUhhbmRsZXIoe1xuICAgICAgICByZXNwb25zZSxcbiAgICAgICAgdXJsLFxuICAgICAgICByZXF1ZXN0Qm9keVZhbHVlczoge30sXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgaWYgKGlzQWJvcnRFcnJvcihlcnJvcikgfHwgQVBJQ2FsbEVycm9yLmlzSW5zdGFuY2UoZXJyb3IpKSB7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdGhyb3cgbmV3IEFQSUNhbGxFcnJvcih7XG4gICAgICAgIG1lc3NhZ2U6ICdGYWlsZWQgdG8gcHJvY2VzcyBzdWNjZXNzZnVsIHJlc3BvbnNlJyxcbiAgICAgICAgY2F1c2U6IGVycm9yLFxuICAgICAgICBzdGF0dXNDb2RlOiByZXNwb25zZS5zdGF0dXMsXG4gICAgICAgIHVybCxcbiAgICAgICAgcmVzcG9uc2VIZWFkZXJzLFxuICAgICAgICByZXF1ZXN0Qm9keVZhbHVlczoge30sXG4gICAgICB9KTtcbiAgICB9XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgdGhyb3cgaGFuZGxlRmV0Y2hFcnJvcih7IGVycm9yLCB1cmwsIHJlcXVlc3RCb2R5VmFsdWVzOiB7fSB9KTtcbiAgfVxufTtcbiIsICJpbXBvcnQgeyBBUElDYWxsRXJyb3IgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcbmltcG9ydCB7IGlzQWJvcnRFcnJvciB9IGZyb20gJy4vaXMtYWJvcnQtZXJyb3InO1xuXG5jb25zdCBGRVRDSF9GQUlMRURfRVJST1JfTUVTU0FHRVMgPSBbJ2ZldGNoIGZhaWxlZCcsICdmYWlsZWQgdG8gZmV0Y2gnXTtcblxuZXhwb3J0IGZ1bmN0aW9uIGhhbmRsZUZldGNoRXJyb3Ioe1xuICBlcnJvcixcbiAgdXJsLFxuICByZXF1ZXN0Qm9keVZhbHVlcyxcbn06IHtcbiAgZXJyb3I6IHVua25vd247XG4gIHVybDogc3RyaW5nO1xuICByZXF1ZXN0Qm9keVZhbHVlczogdW5rbm93bjtcbn0pIHtcbiAgaWYgKGlzQWJvcnRFcnJvcihlcnJvcikpIHtcbiAgICByZXR1cm4gZXJyb3I7XG4gIH1cblxuICAvLyB1bndyYXAgb3JpZ2luYWwgZXJyb3Igd2hlbiBmZXRjaCBmYWlsZWQgKGZvciBlYXNpZXIgZGVidWdnaW5nKTpcbiAgaWYgKFxuICAgIGVycm9yIGluc3RhbmNlb2YgVHlwZUVycm9yICYmXG4gICAgRkVUQ0hfRkFJTEVEX0VSUk9SX01FU1NBR0VTLmluY2x1ZGVzKGVycm9yLm1lc3NhZ2UudG9Mb3dlckNhc2UoKSlcbiAgKSB7XG4gICAgY29uc3QgY2F1c2UgPSAoZXJyb3IgYXMgYW55KS5jYXVzZTtcblxuICAgIGlmIChjYXVzZSAhPSBudWxsKSB7XG4gICAgICAvLyBGYWlsZWQgdG8gY29ubmVjdCB0byBzZXJ2ZXI6XG4gICAgICByZXR1cm4gbmV3IEFQSUNhbGxFcnJvcih7XG4gICAgICAgIG1lc3NhZ2U6IGBDYW5ub3QgY29ubmVjdCB0byBBUEk6ICR7Y2F1c2UubWVzc2FnZX1gLFxuICAgICAgICBjYXVzZSxcbiAgICAgICAgdXJsLFxuICAgICAgICByZXF1ZXN0Qm9keVZhbHVlcyxcbiAgICAgICAgaXNSZXRyeWFibGU6IHRydWUsIC8vIHJldHJ5IHdoZW4gbmV0d29yayBlcnJvclxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGVycm9yO1xufVxuIiwgImV4cG9ydCBmdW5jdGlvbiBpc0Fib3J0RXJyb3IoZXJyb3I6IHVua25vd24pOiBlcnJvciBpcyBFcnJvciB7XG4gIHJldHVybiAoXG4gICAgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IgfHwgZXJyb3IgaW5zdGFuY2VvZiBET01FeGNlcHRpb24pICYmXG4gICAgKGVycm9yLm5hbWUgPT09ICdBYm9ydEVycm9yJyB8fFxuICAgICAgZXJyb3IubmFtZSA9PT0gJ1Jlc3BvbnNlQWJvcnRlZCcgfHwgLy8gTmV4dC5qc1xuICAgICAgZXJyb3IubmFtZSA9PT0gJ1RpbWVvdXRFcnJvcicpXG4gICk7XG59XG4iLCAiZXhwb3J0IGZ1bmN0aW9uIGdldFJ1bnRpbWVFbnZpcm9ubWVudFVzZXJBZ2VudChcbiAgZ2xvYmFsVGhpc0FueTogYW55ID0gZ2xvYmFsVGhpcyBhcyBhbnksXG4pOiBzdHJpbmcge1xuICAvLyBCcm93c2Vyc1xuICBpZiAoZ2xvYmFsVGhpc0FueS53aW5kb3cpIHtcbiAgICByZXR1cm4gYHJ1bnRpbWUvYnJvd3NlcmA7XG4gIH1cblxuICAvLyBDbG91ZGZsYXJlIFdvcmtlcnMgLyBEZW5vIC8gQnVuIC8gTm9kZS5qcyA+PSAyMS4xXG4gIGlmIChnbG9iYWxUaGlzQW55Lm5hdmlnYXRvcj8udXNlckFnZW50KSB7XG4gICAgcmV0dXJuIGBydW50aW1lLyR7Z2xvYmFsVGhpc0FueS5uYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCl9YDtcbiAgfVxuXG4gIC8vIE5vZGVzLmpzIDwgMjEuMVxuICBpZiAoZ2xvYmFsVGhpc0FueS5wcm9jZXNzPy52ZXJzaW9ucz8ubm9kZSkge1xuICAgIHJldHVybiBgcnVudGltZS9ub2RlLmpzLyR7Z2xvYmFsVGhpc0FueS5wcm9jZXNzLnZlcnNpb24uc3Vic3RyaW5nKDApfWA7XG4gIH1cblxuICBpZiAoZ2xvYmFsVGhpc0FueS5FZGdlUnVudGltZSkge1xuICAgIHJldHVybiBgcnVudGltZS92ZXJjZWwtZWRnZWA7XG4gIH1cblxuICByZXR1cm4gJ3J1bnRpbWUvdW5rbm93bic7XG59XG4iLCAiLyoqXG4gKiBSZW1vdmVzIGVudHJpZXMgZnJvbSBhIHJlY29yZCB3aGVyZSB0aGUgdmFsdWUgaXMgbnVsbCBvciB1bmRlZmluZWQuXG4gKiBAcGFyYW0gcmVjb3JkIC0gVGhlIGlucHV0IG9iamVjdCB3aG9zZSBlbnRyaWVzIG1heSBiZSBudWxsIG9yIHVuZGVmaW5lZC5cbiAqIEByZXR1cm5zIEEgbmV3IG9iamVjdCBjb250YWluaW5nIG9ubHkgZW50cmllcyB3aXRoIG5vbi1udWxsIGFuZCBub24tdW5kZWZpbmVkIHZhbHVlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZVVuZGVmaW5lZEVudHJpZXM8VD4oXG4gIHJlY29yZDogUmVjb3JkPHN0cmluZywgVCB8IHVuZGVmaW5lZD4sXG4pOiBSZWNvcmQ8c3RyaW5nLCBUPiB7XG4gIHJldHVybiBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgT2JqZWN0LmVudHJpZXMocmVjb3JkKS5maWx0ZXIoKFtfa2V5LCB2YWx1ZV0pID0+IHZhbHVlICE9IG51bGwpLFxuICApIGFzIFJlY29yZDxzdHJpbmcsIFQ+O1xufVxuIiwgImltcG9ydCB7IHJlbW92ZVVuZGVmaW5lZEVudHJpZXMgfSBmcm9tICcuL3JlbW92ZS11bmRlZmluZWQtZW50cmllcyc7XG5cbi8qKlxuICogQXBwZW5kcyBzdWZmaXggcGFydHMgdG8gdGhlIGB1c2VyLWFnZW50YCBoZWFkZXIuXG4gKiBJZiBhIGB1c2VyLWFnZW50YCBoZWFkZXIgYWxyZWFkeSBleGlzdHMsIHRoZSBzdWZmaXggcGFydHMgYXJlIGFwcGVuZGVkIHRvIGl0LlxuICogSWYgbm8gYHVzZXItYWdlbnRgIGhlYWRlciBleGlzdHMsIGEgbmV3IG9uZSBpcyBjcmVhdGVkIHdpdGggdGhlIHN1ZmZpeCBwYXJ0cy5cbiAqIEF1dG9tYXRpY2FsbHkgcmVtb3ZlcyB1bmRlZmluZWQgZW50cmllcyBmcm9tIHRoZSBoZWFkZXJzLlxuICpcbiAqIEBwYXJhbSBoZWFkZXJzIC0gVGhlIG9yaWdpbmFsIGhlYWRlcnMuXG4gKiBAcGFyYW0gdXNlckFnZW50U3VmZml4UGFydHMgLSBUaGUgcGFydHMgdG8gYXBwZW5kIHRvIHRoZSBgdXNlci1hZ2VudGAgaGVhZGVyLlxuICogQHJldHVybnMgVGhlIG5ldyBoZWFkZXJzIHdpdGggdGhlIGB1c2VyLWFnZW50YCBoZWFkZXIgc2V0IG9yIHVwZGF0ZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3aXRoVXNlckFnZW50U3VmZml4KFxuICBoZWFkZXJzOiBIZWFkZXJzSW5pdCB8IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD4gfCB1bmRlZmluZWQsXG4gIC4uLnVzZXJBZ2VudFN1ZmZpeFBhcnRzOiBzdHJpbmdbXVxuKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG4gIGNvbnN0IGNsZWFuZWRIZWFkZXJzID0gcmVtb3ZlVW5kZWZpbmVkRW50cmllcyhcbiAgICAoaGVhZGVycyBhcyBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+KSA/PyB7fSxcbiAgKTtcbiAgY29uc3Qgbm9ybWFsaXplZEhlYWRlcnMgPSBuZXcgSGVhZGVycyhjbGVhbmVkSGVhZGVycyk7XG5cbiAgY29uc3QgY3VycmVudFVzZXJBZ2VudEhlYWRlciA9IG5vcm1hbGl6ZWRIZWFkZXJzLmdldCgndXNlci1hZ2VudCcpIHx8ICcnO1xuXG4gIG5vcm1hbGl6ZWRIZWFkZXJzLnNldChcbiAgICAndXNlci1hZ2VudCcsXG4gICAgW2N1cnJlbnRVc2VyQWdlbnRIZWFkZXIsIC4uLnVzZXJBZ2VudFN1ZmZpeFBhcnRzXS5maWx0ZXIoQm9vbGVhbikuam9pbignICcpLFxuICApO1xuXG4gIHJldHVybiBPYmplY3QuZnJvbUVudHJpZXMobm9ybWFsaXplZEhlYWRlcnMpO1xufVxuIiwgIi8vIFZlcnNpb24gc3RyaW5nIG9mIHRoaXMgcGFja2FnZSBpbmplY3RlZCBhdCBidWlsZCB0aW1lLlxuZGVjbGFyZSBjb25zdCBfX1BBQ0tBR0VfVkVSU0lPTl9fOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5leHBvcnQgY29uc3QgVkVSU0lPTjogc3RyaW5nID1cbiAgdHlwZW9mIF9fUEFDS0FHRV9WRVJTSU9OX18gIT09ICd1bmRlZmluZWQnXG4gICAgPyBfX1BBQ0tBR0VfVkVSU0lPTl9fXG4gICAgOiAnMC4wLjAtdGVzdCc7XG4iLCAiaW1wb3J0IHtcbiAgSlNPTlNjaGVtYTcsXG4gIExhbmd1YWdlTW9kZWxWMk1lc3NhZ2UsXG4gIExhbmd1YWdlTW9kZWxWMlByb21wdCxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5cbmNvbnN0IERFRkFVTFRfU0NIRU1BX1BSRUZJWCA9ICdKU09OIHNjaGVtYTonO1xuY29uc3QgREVGQVVMVF9TQ0hFTUFfU1VGRklYID1cbiAgJ1lvdSBNVVNUIGFuc3dlciB3aXRoIGEgSlNPTiBvYmplY3QgdGhhdCBtYXRjaGVzIHRoZSBKU09OIHNjaGVtYSBhYm92ZS4nO1xuY29uc3QgREVGQVVMVF9HRU5FUklDX1NVRkZJWCA9ICdZb3UgTVVTVCBhbnN3ZXIgd2l0aCBKU09OLic7XG5cbmV4cG9ydCBmdW5jdGlvbiBpbmplY3RKc29uSW5zdHJ1Y3Rpb24oe1xuICBwcm9tcHQsXG4gIHNjaGVtYSxcbiAgc2NoZW1hUHJlZml4ID0gc2NoZW1hICE9IG51bGwgPyBERUZBVUxUX1NDSEVNQV9QUkVGSVggOiB1bmRlZmluZWQsXG4gIHNjaGVtYVN1ZmZpeCA9IHNjaGVtYSAhPSBudWxsXG4gICAgPyBERUZBVUxUX1NDSEVNQV9TVUZGSVhcbiAgICA6IERFRkFVTFRfR0VORVJJQ19TVUZGSVgsXG59OiB7XG4gIHByb21wdD86IHN0cmluZztcbiAgc2NoZW1hPzogSlNPTlNjaGVtYTc7XG4gIHNjaGVtYVByZWZpeD86IHN0cmluZztcbiAgc2NoZW1hU3VmZml4Pzogc3RyaW5nO1xufSk6IHN0cmluZyB7XG4gIHJldHVybiBbXG4gICAgcHJvbXB0ICE9IG51bGwgJiYgcHJvbXB0Lmxlbmd0aCA+IDAgPyBwcm9tcHQgOiB1bmRlZmluZWQsXG4gICAgcHJvbXB0ICE9IG51bGwgJiYgcHJvbXB0Lmxlbmd0aCA+IDAgPyAnJyA6IHVuZGVmaW5lZCwgLy8gYWRkIGEgbmV3bGluZSBpZiBwcm9tcHQgaXMgbm90IG51bGxcbiAgICBzY2hlbWFQcmVmaXgsXG4gICAgc2NoZW1hICE9IG51bGwgPyBKU09OLnN0cmluZ2lmeShzY2hlbWEpIDogdW5kZWZpbmVkLFxuICAgIHNjaGVtYVN1ZmZpeCxcbiAgXVxuICAgIC5maWx0ZXIobGluZSA9PiBsaW5lICE9IG51bGwpXG4gICAgLmpvaW4oJ1xcbicpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaW5qZWN0SnNvbkluc3RydWN0aW9uSW50b01lc3NhZ2VzKHtcbiAgbWVzc2FnZXMsXG4gIHNjaGVtYSxcbiAgc2NoZW1hUHJlZml4LFxuICBzY2hlbWFTdWZmaXgsXG59OiB7XG4gIG1lc3NhZ2VzOiBMYW5ndWFnZU1vZGVsVjJQcm9tcHQ7XG4gIHNjaGVtYT86IEpTT05TY2hlbWE3O1xuICBzY2hlbWFQcmVmaXg/OiBzdHJpbmc7XG4gIHNjaGVtYVN1ZmZpeD86IHN0cmluZztcbn0pOiBMYW5ndWFnZU1vZGVsVjJQcm9tcHQge1xuICBjb25zdCBzeXN0ZW1NZXNzYWdlOiBMYW5ndWFnZU1vZGVsVjJNZXNzYWdlID1cbiAgICBtZXNzYWdlc1swXT8ucm9sZSA9PT0gJ3N5c3RlbSdcbiAgICAgID8geyAuLi5tZXNzYWdlc1swXSB9XG4gICAgICA6IHsgcm9sZTogJ3N5c3RlbScsIGNvbnRlbnQ6ICcnIH07XG5cbiAgc3lzdGVtTWVzc2FnZS5jb250ZW50ID0gaW5qZWN0SnNvbkluc3RydWN0aW9uKHtcbiAgICBwcm9tcHQ6IHN5c3RlbU1lc3NhZ2UuY29udGVudCxcbiAgICBzY2hlbWEsXG4gICAgc2NoZW1hUHJlZml4LFxuICAgIHNjaGVtYVN1ZmZpeCxcbiAgfSk7XG5cbiAgcmV0dXJuIFtcbiAgICBzeXN0ZW1NZXNzYWdlLFxuICAgIC4uLihtZXNzYWdlc1swXT8ucm9sZSA9PT0gJ3N5c3RlbScgPyBtZXNzYWdlcy5zbGljZSgxKSA6IG1lc3NhZ2VzKSxcbiAgXTtcbn1cbiIsICIvKipcbiAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gVVJMIGlzIHN1cHBvcnRlZCBuYXRpdmVseSBieSB0aGUgbW9kZWwuXG4gKlxuICogQHBhcmFtIG1lZGlhVHlwZSAtIFRoZSBtZWRpYSB0eXBlIG9mIHRoZSBVUkwuIENhc2Utc2Vuc2l0aXZlLlxuICogQHBhcmFtIHVybCAtIFRoZSBVUkwgdG8gY2hlY2suXG4gKiBAcGFyYW0gc3VwcG9ydGVkVXJscyAtIEEgcmVjb3JkIHdoZXJlIGtleXMgYXJlIGNhc2Utc2Vuc2l0aXZlIG1lZGlhIHR5cGVzIChvciAnKicpXG4gKiAgICAgICAgICAgICAgICAgICAgICAgIGFuZCB2YWx1ZXMgYXJlIGFycmF5cyBvZiBSZWdFeHAgcGF0dGVybnMgZm9yIFVSTHMuXG4gKlxuICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBVUkwgbWF0Y2hlcyBhIHBhdHRlcm4gdW5kZXIgdGhlIHNwZWNpZmljIG1lZGlhIHR5cGVcbiAqICAgICAgICAgIG9yIHRoZSB3aWxkY2FyZCAnKicsIGBmYWxzZWAgb3RoZXJ3aXNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNVcmxTdXBwb3J0ZWQoe1xuICBtZWRpYVR5cGUsXG4gIHVybCxcbiAgc3VwcG9ydGVkVXJscyxcbn06IHtcbiAgbWVkaWFUeXBlOiBzdHJpbmc7XG4gIHVybDogc3RyaW5nO1xuICBzdXBwb3J0ZWRVcmxzOiBSZWNvcmQ8c3RyaW5nLCBSZWdFeHBbXT47XG59KTogYm9vbGVhbiB7XG4gIC8vIHN0YW5kYXJkaXplIG1lZGlhIHR5cGUgYW5kIHVybCB0byBsb3dlciBjYXNlXG4gIHVybCA9IHVybC50b0xvd2VyQ2FzZSgpO1xuICBtZWRpYVR5cGUgPSBtZWRpYVR5cGUudG9Mb3dlckNhc2UoKTtcblxuICByZXR1cm4gKFxuICAgIE9iamVjdC5lbnRyaWVzKHN1cHBvcnRlZFVybHMpXG4gICAgICAvLyBzdGFuZGFyZGl6ZSBzdXBwb3J0ZWQgdXJsIG1hcCBpbnRvIGxvd2VyY2FzZSBwcmVmaXhlczpcbiAgICAgIC5tYXAoKFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgICBjb25zdCBtZWRpYVR5cGUgPSBrZXkudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgcmV0dXJuIG1lZGlhVHlwZSA9PT0gJyonIHx8IG1lZGlhVHlwZSA9PT0gJyovKidcbiAgICAgICAgICA/IHsgbWVkaWFUeXBlUHJlZml4OiAnJywgcmVnZXhlczogdmFsdWUgfVxuICAgICAgICAgIDogeyBtZWRpYVR5cGVQcmVmaXg6IG1lZGlhVHlwZS5yZXBsYWNlKC9cXCovLCAnJyksIHJlZ2V4ZXM6IHZhbHVlIH07XG4gICAgICB9KVxuICAgICAgLy8gZ2F0aGVyIGFsbCByZWdleHAgcGF0dGVybiBmcm9tIG1hdGNoZWQgbWVkaWEgdHlwZSBwcmVmaXhlczpcbiAgICAgIC5maWx0ZXIoKHsgbWVkaWFUeXBlUHJlZml4IH0pID0+IG1lZGlhVHlwZS5zdGFydHNXaXRoKG1lZGlhVHlwZVByZWZpeCkpXG4gICAgICAuZmxhdE1hcCgoeyByZWdleGVzIH0pID0+IHJlZ2V4ZXMpXG4gICAgICAvLyBjaGVjayBpZiBhbnkgcGF0dGVybiBtYXRjaGVzIHRoZSB1cmw6XG4gICAgICAuc29tZShwYXR0ZXJuID0+IHBhdHRlcm4udGVzdCh1cmwpKVxuICApO1xufVxuIiwgImltcG9ydCB7IExvYWRBUElLZXlFcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuXG5leHBvcnQgZnVuY3Rpb24gbG9hZEFwaUtleSh7XG4gIGFwaUtleSxcbiAgZW52aXJvbm1lbnRWYXJpYWJsZU5hbWUsXG4gIGFwaUtleVBhcmFtZXRlck5hbWUgPSAnYXBpS2V5JyxcbiAgZGVzY3JpcHRpb24sXG59OiB7XG4gIGFwaUtleTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBlbnZpcm9ubWVudFZhcmlhYmxlTmFtZTogc3RyaW5nO1xuICBhcGlLZXlQYXJhbWV0ZXJOYW1lPzogc3RyaW5nO1xuICBkZXNjcmlwdGlvbjogc3RyaW5nO1xufSk6IHN0cmluZyB7XG4gIGlmICh0eXBlb2YgYXBpS2V5ID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBhcGlLZXk7XG4gIH1cblxuICBpZiAoYXBpS2V5ICE9IG51bGwpIHtcbiAgICB0aHJvdyBuZXcgTG9hZEFQSUtleUVycm9yKHtcbiAgICAgIG1lc3NhZ2U6IGAke2Rlc2NyaXB0aW9ufSBBUEkga2V5IG11c3QgYmUgYSBzdHJpbmcuYCxcbiAgICB9KTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgcHJvY2VzcyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB0aHJvdyBuZXcgTG9hZEFQSUtleUVycm9yKHtcbiAgICAgIG1lc3NhZ2U6IGAke2Rlc2NyaXB0aW9ufSBBUEkga2V5IGlzIG1pc3NpbmcuIFBhc3MgaXQgdXNpbmcgdGhlICcke2FwaUtleVBhcmFtZXRlck5hbWV9JyBwYXJhbWV0ZXIuIEVudmlyb25tZW50IHZhcmlhYmxlcyBpcyBub3Qgc3VwcG9ydGVkIGluIHRoaXMgZW52aXJvbm1lbnQuYCxcbiAgICB9KTtcbiAgfVxuXG4gIGFwaUtleSA9IHByb2Nlc3MuZW52W2Vudmlyb25tZW50VmFyaWFibGVOYW1lXTtcblxuICBpZiAoYXBpS2V5ID09IG51bGwpIHtcbiAgICB0aHJvdyBuZXcgTG9hZEFQSUtleUVycm9yKHtcbiAgICAgIG1lc3NhZ2U6IGAke2Rlc2NyaXB0aW9ufSBBUEkga2V5IGlzIG1pc3NpbmcuIFBhc3MgaXQgdXNpbmcgdGhlICcke2FwaUtleVBhcmFtZXRlck5hbWV9JyBwYXJhbWV0ZXIgb3IgdGhlICR7ZW52aXJvbm1lbnRWYXJpYWJsZU5hbWV9IGVudmlyb25tZW50IHZhcmlhYmxlLmAsXG4gICAgfSk7XG4gIH1cblxuICBpZiAodHlwZW9mIGFwaUtleSAhPT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgTG9hZEFQSUtleUVycm9yKHtcbiAgICAgIG1lc3NhZ2U6IGAke2Rlc2NyaXB0aW9ufSBBUEkga2V5IG11c3QgYmUgYSBzdHJpbmcuIFRoZSB2YWx1ZSBvZiB0aGUgJHtlbnZpcm9ubWVudFZhcmlhYmxlTmFtZX0gZW52aXJvbm1lbnQgdmFyaWFibGUgaXMgbm90IGEgc3RyaW5nLmAsXG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gYXBpS2V5O1xufVxuIiwgIi8qKlxuICogTG9hZHMgYW4gb3B0aW9uYWwgYHN0cmluZ2Agc2V0dGluZyBmcm9tIHRoZSBlbnZpcm9ubWVudCBvciBhIHBhcmFtZXRlci5cbiAqXG4gKiBAcGFyYW0gc2V0dGluZ1ZhbHVlIC0gVGhlIHNldHRpbmcgdmFsdWUuXG4gKiBAcGFyYW0gZW52aXJvbm1lbnRWYXJpYWJsZU5hbWUgLSBUaGUgZW52aXJvbm1lbnQgdmFyaWFibGUgbmFtZS5cbiAqIEByZXR1cm5zIFRoZSBzZXR0aW5nIHZhbHVlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbG9hZE9wdGlvbmFsU2V0dGluZyh7XG4gIHNldHRpbmdWYWx1ZSxcbiAgZW52aXJvbm1lbnRWYXJpYWJsZU5hbWUsXG59OiB7XG4gIHNldHRpbmdWYWx1ZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBlbnZpcm9ubWVudFZhcmlhYmxlTmFtZTogc3RyaW5nO1xufSk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGlmICh0eXBlb2Ygc2V0dGluZ1ZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBzZXR0aW5nVmFsdWU7XG4gIH1cblxuICBpZiAoc2V0dGluZ1ZhbHVlICE9IG51bGwgfHwgdHlwZW9mIHByb2Nlc3MgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHNldHRpbmdWYWx1ZSA9IHByb2Nlc3MuZW52W2Vudmlyb25tZW50VmFyaWFibGVOYW1lXTtcblxuICBpZiAoc2V0dGluZ1ZhbHVlID09IG51bGwgfHwgdHlwZW9mIHNldHRpbmdWYWx1ZSAhPT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgcmV0dXJuIHNldHRpbmdWYWx1ZTtcbn1cbiIsICJpbXBvcnQgeyBMb2FkU2V0dGluZ0Vycm9yIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5cbi8qKlxuICogTG9hZHMgYSBgc3RyaW5nYCBzZXR0aW5nIGZyb20gdGhlIGVudmlyb25tZW50IG9yIGEgcGFyYW1ldGVyLlxuICpcbiAqIEBwYXJhbSBzZXR0aW5nVmFsdWUgLSBUaGUgc2V0dGluZyB2YWx1ZS5cbiAqIEBwYXJhbSBlbnZpcm9ubWVudFZhcmlhYmxlTmFtZSAtIFRoZSBlbnZpcm9ubWVudCB2YXJpYWJsZSBuYW1lLlxuICogQHBhcmFtIHNldHRpbmdOYW1lIC0gVGhlIHNldHRpbmcgbmFtZS5cbiAqIEBwYXJhbSBkZXNjcmlwdGlvbiAtIFRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgc2V0dGluZy5cbiAqIEByZXR1cm5zIFRoZSBzZXR0aW5nIHZhbHVlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbG9hZFNldHRpbmcoe1xuICBzZXR0aW5nVmFsdWUsXG4gIGVudmlyb25tZW50VmFyaWFibGVOYW1lLFxuICBzZXR0aW5nTmFtZSxcbiAgZGVzY3JpcHRpb24sXG59OiB7XG4gIHNldHRpbmdWYWx1ZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBlbnZpcm9ubWVudFZhcmlhYmxlTmFtZTogc3RyaW5nO1xuICBzZXR0aW5nTmFtZTogc3RyaW5nO1xuICBkZXNjcmlwdGlvbjogc3RyaW5nO1xufSk6IHN0cmluZyB7XG4gIGlmICh0eXBlb2Ygc2V0dGluZ1ZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBzZXR0aW5nVmFsdWU7XG4gIH1cblxuICBpZiAoc2V0dGluZ1ZhbHVlICE9IG51bGwpIHtcbiAgICB0aHJvdyBuZXcgTG9hZFNldHRpbmdFcnJvcih7XG4gICAgICBtZXNzYWdlOiBgJHtkZXNjcmlwdGlvbn0gc2V0dGluZyBtdXN0IGJlIGEgc3RyaW5nLmAsXG4gICAgfSk7XG4gIH1cblxuICBpZiAodHlwZW9mIHByb2Nlc3MgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgdGhyb3cgbmV3IExvYWRTZXR0aW5nRXJyb3Ioe1xuICAgICAgbWVzc2FnZTpcbiAgICAgICAgYCR7ZGVzY3JpcHRpb259IHNldHRpbmcgaXMgbWlzc2luZy4gYCArXG4gICAgICAgIGBQYXNzIGl0IHVzaW5nIHRoZSAnJHtzZXR0aW5nTmFtZX0nIHBhcmFtZXRlci4gYCArXG4gICAgICAgIGBFbnZpcm9ubWVudCB2YXJpYWJsZXMgaXMgbm90IHN1cHBvcnRlZCBpbiB0aGlzIGVudmlyb25tZW50LmAsXG4gICAgfSk7XG4gIH1cblxuICBzZXR0aW5nVmFsdWUgPSBwcm9jZXNzLmVudltlbnZpcm9ubWVudFZhcmlhYmxlTmFtZV07XG5cbiAgaWYgKHNldHRpbmdWYWx1ZSA9PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IExvYWRTZXR0aW5nRXJyb3Ioe1xuICAgICAgbWVzc2FnZTpcbiAgICAgICAgYCR7ZGVzY3JpcHRpb259IHNldHRpbmcgaXMgbWlzc2luZy4gYCArXG4gICAgICAgIGBQYXNzIGl0IHVzaW5nIHRoZSAnJHtzZXR0aW5nTmFtZX0nIHBhcmFtZXRlciBgICtcbiAgICAgICAgYG9yIHRoZSAke2Vudmlyb25tZW50VmFyaWFibGVOYW1lfSBlbnZpcm9ubWVudCB2YXJpYWJsZS5gLFxuICAgIH0pO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBzZXR0aW5nVmFsdWUgIT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IExvYWRTZXR0aW5nRXJyb3Ioe1xuICAgICAgbWVzc2FnZTpcbiAgICAgICAgYCR7ZGVzY3JpcHRpb259IHNldHRpbmcgbXVzdCBiZSBhIHN0cmluZy4gYCArXG4gICAgICAgIGBUaGUgdmFsdWUgb2YgdGhlICR7ZW52aXJvbm1lbnRWYXJpYWJsZU5hbWV9IGVudmlyb25tZW50IHZhcmlhYmxlIGlzIG5vdCBhIHN0cmluZy5gLFxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHNldHRpbmdWYWx1ZTtcbn1cbiIsICIvKipcbiAqIE1hcHMgYSBtZWRpYSB0eXBlIHRvIGl0cyBjb3JyZXNwb25kaW5nIGZpbGUgZXh0ZW5zaW9uLlxuICogSXQgd2FzIG9yaWdpbmFsbHkgaW50cm9kdWNlZCB0byBzZXQgYSBmaWxlbmFtZSBmb3IgYXVkaW8gZmlsZSB1cGxvYWRzXG4gKiBpbiBodHRwczovL2dpdGh1Yi5jb20vdmVyY2VsL2FpL3B1bGwvODE1OS5cbiAqXG4gKiBAcGFyYW0gbWVkaWFUeXBlIFRoZSBtZWRpYSB0eXBlIHRvIG1hcC5cbiAqIEByZXR1cm5zIFRoZSBjb3JyZXNwb25kaW5nIGZpbGUgZXh0ZW5zaW9uXG4gKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUVFAvR3VpZGVzL01JTUVfdHlwZXMvQ29tbW9uX3R5cGVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtZWRpYVR5cGVUb0V4dGVuc2lvbihtZWRpYVR5cGU6IHN0cmluZykge1xuICBjb25zdCBbX3R5cGUsIHN1YnR5cGUgPSAnJ10gPSBtZWRpYVR5cGUudG9Mb3dlckNhc2UoKS5zcGxpdCgnLycpO1xuXG4gIHJldHVybiAoXG4gICAge1xuICAgICAgbXBlZzogJ21wMycsXG4gICAgICAneC13YXYnOiAnd2F2JyxcbiAgICAgIG9wdXM6ICdvZ2cnLFxuICAgICAgbXA0OiAnbTRhJyxcbiAgICAgICd4LW00YSc6ICdtNGEnLFxuICAgIH1bc3VidHlwZV0gPz8gc3VidHlwZVxuICApO1xufVxuIiwgImltcG9ydCB7XG4gIEpTT05QYXJzZUVycm9yLFxuICBKU09OVmFsdWUsXG4gIFR5cGVWYWxpZGF0aW9uRXJyb3IsXG59IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgc2VjdXJlSnNvblBhcnNlIH0gZnJvbSAnLi9zZWN1cmUtanNvbi1wYXJzZSc7XG5pbXBvcnQgeyBzYWZlVmFsaWRhdGVUeXBlcywgdmFsaWRhdGVUeXBlcyB9IGZyb20gJy4vdmFsaWRhdGUtdHlwZXMnO1xuaW1wb3J0IHsgRmxleGlibGVWYWxpZGF0b3IsIFZhbGlkYXRvciB9IGZyb20gJy4vdmFsaWRhdG9yJztcblxuLyoqXG4gKiBQYXJzZXMgYSBKU09OIHN0cmluZyBpbnRvIGFuIHVua25vd24gb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB0ZXh0IC0gVGhlIEpTT04gc3RyaW5nIHRvIHBhcnNlLlxuICogQHJldHVybnMge0pTT05WYWx1ZX0gLSBUaGUgcGFyc2VkIEpTT04gb2JqZWN0LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcGFyc2VKU09OKG9wdGlvbnM6IHtcbiAgdGV4dDogc3RyaW5nO1xuICBzY2hlbWE/OiB1bmRlZmluZWQ7XG59KTogUHJvbWlzZTxKU09OVmFsdWU+O1xuLyoqXG4gKiBQYXJzZXMgYSBKU09OIHN0cmluZyBpbnRvIGEgc3Ryb25nbHktdHlwZWQgb2JqZWN0IHVzaW5nIHRoZSBwcm92aWRlZCBzY2hlbWEuXG4gKlxuICogQHRlbXBsYXRlIFQgLSBUaGUgdHlwZSBvZiB0aGUgb2JqZWN0IHRvIHBhcnNlIHRoZSBKU09OIGludG8uXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIFRoZSBKU09OIHN0cmluZyB0byBwYXJzZS5cbiAqIEBwYXJhbSB7VmFsaWRhdG9yPFQ+fSBzY2hlbWEgLSBUaGUgc2NoZW1hIHRvIHVzZSBmb3IgcGFyc2luZyB0aGUgSlNPTi5cbiAqIEByZXR1cm5zIHtQcm9taXNlPFQ+fSAtIFRoZSBwYXJzZWQgb2JqZWN0LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcGFyc2VKU09OPFQ+KG9wdGlvbnM6IHtcbiAgdGV4dDogc3RyaW5nO1xuICBzY2hlbWE6IEZsZXhpYmxlVmFsaWRhdG9yPFQ+O1xufSk6IFByb21pc2U8VD47XG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcGFyc2VKU09OPFQ+KHtcbiAgdGV4dCxcbiAgc2NoZW1hLFxufToge1xuICB0ZXh0OiBzdHJpbmc7XG4gIHNjaGVtYT86IEZsZXhpYmxlVmFsaWRhdG9yPFQ+O1xufSk6IFByb21pc2U8VD4ge1xuICB0cnkge1xuICAgIGNvbnN0IHZhbHVlID0gc2VjdXJlSnNvblBhcnNlKHRleHQpO1xuXG4gICAgaWYgKHNjaGVtYSA9PSBudWxsKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbGlkYXRlVHlwZXM8VD4oeyB2YWx1ZSwgc2NoZW1hIH0pO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmIChcbiAgICAgIEpTT05QYXJzZUVycm9yLmlzSW5zdGFuY2UoZXJyb3IpIHx8XG4gICAgICBUeXBlVmFsaWRhdGlvbkVycm9yLmlzSW5zdGFuY2UoZXJyb3IpXG4gICAgKSB7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgSlNPTlBhcnNlRXJyb3IoeyB0ZXh0LCBjYXVzZTogZXJyb3IgfSk7XG4gIH1cbn1cblxuZXhwb3J0IHR5cGUgUGFyc2VSZXN1bHQ8VD4gPVxuICB8IHsgc3VjY2VzczogdHJ1ZTsgdmFsdWU6IFQ7IHJhd1ZhbHVlOiB1bmtub3duIH1cbiAgfCB7XG4gICAgICBzdWNjZXNzOiBmYWxzZTtcbiAgICAgIGVycm9yOiBKU09OUGFyc2VFcnJvciB8IFR5cGVWYWxpZGF0aW9uRXJyb3I7XG4gICAgICByYXdWYWx1ZTogdW5rbm93bjtcbiAgICB9O1xuXG4vKipcbiAqIFNhZmVseSBwYXJzZXMgYSBKU09OIHN0cmluZyBhbmQgcmV0dXJucyB0aGUgcmVzdWx0IGFzIGFuIG9iamVjdCBvZiB0eXBlIGB1bmtub3duYC5cbiAqXG4gKiBAcGFyYW0gdGV4dCAtIFRoZSBKU09OIHN0cmluZyB0byBwYXJzZS5cbiAqIEByZXR1cm5zIHtQcm9taXNlPG9iamVjdD59IEVpdGhlciBhbiBvYmplY3Qgd2l0aCBgc3VjY2VzczogdHJ1ZWAgYW5kIHRoZSBwYXJzZWQgZGF0YSwgb3IgYW4gb2JqZWN0IHdpdGggYHN1Y2Nlc3M6IGZhbHNlYCBhbmQgdGhlIGVycm9yIHRoYXQgb2NjdXJyZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzYWZlUGFyc2VKU09OKG9wdGlvbnM6IHtcbiAgdGV4dDogc3RyaW5nO1xuICBzY2hlbWE/OiB1bmRlZmluZWQ7XG59KTogUHJvbWlzZTxQYXJzZVJlc3VsdDxKU09OVmFsdWU+Pjtcbi8qKlxuICogU2FmZWx5IHBhcnNlcyBhIEpTT04gc3RyaW5nIGludG8gYSBzdHJvbmdseS10eXBlZCBvYmplY3QsIHVzaW5nIGEgcHJvdmlkZWQgc2NoZW1hIHRvIHZhbGlkYXRlIHRoZSBvYmplY3QuXG4gKlxuICogQHRlbXBsYXRlIFQgLSBUaGUgdHlwZSBvZiB0aGUgb2JqZWN0IHRvIHBhcnNlIHRoZSBKU09OIGludG8uXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIFRoZSBKU09OIHN0cmluZyB0byBwYXJzZS5cbiAqIEBwYXJhbSB7VmFsaWRhdG9yPFQ+fSBzY2hlbWEgLSBUaGUgc2NoZW1hIHRvIHVzZSBmb3IgcGFyc2luZyB0aGUgSlNPTi5cbiAqIEByZXR1cm5zIEFuIG9iamVjdCB3aXRoIGVpdGhlciBhIGBzdWNjZXNzYCBmbGFnIGFuZCB0aGUgcGFyc2VkIGFuZCB0eXBlZCBkYXRhLCBvciBhIGBzdWNjZXNzYCBmbGFnIGFuZCBhbiBlcnJvciBvYmplY3QuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzYWZlUGFyc2VKU09OPFQ+KG9wdGlvbnM6IHtcbiAgdGV4dDogc3RyaW5nO1xuICBzY2hlbWE6IEZsZXhpYmxlVmFsaWRhdG9yPFQ+O1xufSk6IFByb21pc2U8UGFyc2VSZXN1bHQ8VD4+O1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNhZmVQYXJzZUpTT048VD4oe1xuICB0ZXh0LFxuICBzY2hlbWEsXG59OiB7XG4gIHRleHQ6IHN0cmluZztcbiAgc2NoZW1hPzogRmxleGlibGVWYWxpZGF0b3I8VD47XG59KTogUHJvbWlzZTxQYXJzZVJlc3VsdDxUPj4ge1xuICB0cnkge1xuICAgIGNvbnN0IHZhbHVlID0gc2VjdXJlSnNvblBhcnNlKHRleHQpO1xuXG4gICAgaWYgKHNjaGVtYSA9PSBudWxsKSB7XG4gICAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlLCB2YWx1ZTogdmFsdWUgYXMgVCwgcmF3VmFsdWU6IHZhbHVlIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHNhZmVWYWxpZGF0ZVR5cGVzPFQ+KHsgdmFsdWUsIHNjaGVtYSB9KTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICBlcnJvcjogSlNPTlBhcnNlRXJyb3IuaXNJbnN0YW5jZShlcnJvcilcbiAgICAgICAgPyBlcnJvclxuICAgICAgICA6IG5ldyBKU09OUGFyc2VFcnJvcih7IHRleHQsIGNhdXNlOiBlcnJvciB9KSxcbiAgICAgIHJhd1ZhbHVlOiB1bmRlZmluZWQsXG4gICAgfTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNQYXJzYWJsZUpzb24oaW5wdXQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICB0cnkge1xuICAgIHNlY3VyZUpzb25QYXJzZShpbnB1dCk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuIiwgIi8vIExpY2Vuc2VkIHVuZGVyIEJTRC0zLUNsYXVzZSAodGhpcyBmaWxlIG9ubHkpXG4vLyBDb2RlIGFkYXB0ZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vZmFzdGlmeS9zZWN1cmUtanNvbi1wYXJzZS9ibG9iLzc4M2ZjYjFiNTQzNDcwOTQ2Njc1OTg0N2NlYzk3NDM4MTkzOTY3M2EvaW5kZXguanNcbi8vXG4vLyBDb3B5cmlnaHQgKGMpIFZlcmNlbCwgSW5jLiAoaHR0cHM6Ly92ZXJjZWwuY29tKVxuLy8gQ29weXJpZ2h0IChjKSAyMDE5IFRoZSBGYXN0aWZ5IFRlYW1cbi8vIENvcHlyaWdodCAoYykgMjAxOSwgU2lkZXdheSBJbmMsIGFuZCBwcm9qZWN0IGNvbnRyaWJ1dG9yc1xuLy8gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vXG4vLyBUaGUgY29tcGxldGUgbGlzdCBvZiBjb250cmlidXRvcnMgY2FuIGJlIGZvdW5kIGF0OlxuLy8gLSBodHRwczovL2dpdGh1Yi5jb20vaGFwaWpzL2JvdXJuZS9ncmFwaHMvY29udHJpYnV0b3JzXG4vLyAtIGh0dHBzOi8vZ2l0aHViLmNvbS9mYXN0aWZ5L3NlY3VyZS1qc29uLXBhcnNlL2dyYXBocy9jb250cmlidXRvcnNcbi8vIC0gaHR0cHM6Ly9naXRodWIuY29tL3ZlcmNlbC9haS9jb21taXRzL21haW4vcGFja2FnZXMvcHJvdmlkZXItdXRpbHMvc3JjL3NlY3VyZS1wYXJzZS1qc29uLnRzXG4vL1xuLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuLy9cbi8vIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbi8vXG4vLyAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXG4vL1xuLy8gMy4gTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgY29weXJpZ2h0IGhvbGRlciBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuLy9cbi8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cblxuY29uc3Qgc3VzcGVjdFByb3RvUnggPSAvXCJfX3Byb3RvX19cIlxccyo6LztcbmNvbnN0IHN1c3BlY3RDb25zdHJ1Y3RvclJ4ID0gL1wiY29uc3RydWN0b3JcIlxccyo6LztcblxuZnVuY3Rpb24gX3BhcnNlKHRleHQ6IHN0cmluZykge1xuICAvLyBQYXJzZSBub3JtYWxseVxuICBjb25zdCBvYmogPSBKU09OLnBhcnNlKHRleHQpO1xuXG4gIC8vIElnbm9yZSBudWxsIGFuZCBub24tb2JqZWN0c1xuICBpZiAob2JqID09PSBudWxsIHx8IHR5cGVvZiBvYmogIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIG9iajtcbiAgfVxuXG4gIGlmIChcbiAgICBzdXNwZWN0UHJvdG9SeC50ZXN0KHRleHQpID09PSBmYWxzZSAmJlxuICAgIHN1c3BlY3RDb25zdHJ1Y3RvclJ4LnRlc3QodGV4dCkgPT09IGZhbHNlXG4gICkge1xuICAgIHJldHVybiBvYmo7XG4gIH1cblxuICAvLyBTY2FuIHJlc3VsdCBmb3IgcHJvdG8ga2V5c1xuICByZXR1cm4gZmlsdGVyKG9iaik7XG59XG5cbmZ1bmN0aW9uIGZpbHRlcihvYmo6IGFueSkge1xuICBsZXQgbmV4dCA9IFtvYmpdO1xuXG4gIHdoaWxlIChuZXh0Lmxlbmd0aCkge1xuICAgIGNvbnN0IG5vZGVzID0gbmV4dDtcbiAgICBuZXh0ID0gW107XG5cbiAgICBmb3IgKGNvbnN0IG5vZGUgb2Ygbm9kZXMpIHtcbiAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobm9kZSwgJ19fcHJvdG9fXycpKSB7XG4gICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcignT2JqZWN0IGNvbnRhaW5zIGZvcmJpZGRlbiBwcm90b3R5cGUgcHJvcGVydHknKTtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobm9kZSwgJ2NvbnN0cnVjdG9yJykgJiZcbiAgICAgICAgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG5vZGUuY29uc3RydWN0b3IsICdwcm90b3R5cGUnKVxuICAgICAgKSB7XG4gICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcignT2JqZWN0IGNvbnRhaW5zIGZvcmJpZGRlbiBwcm90b3R5cGUgcHJvcGVydHknKTtcbiAgICAgIH1cblxuICAgICAgZm9yIChjb25zdCBrZXkgaW4gbm9kZSkge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IG5vZGVba2V5XTtcbiAgICAgICAgaWYgKHZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICBuZXh0LnB1c2godmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBvYmo7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZWN1cmVKc29uUGFyc2UodGV4dDogc3RyaW5nKSB7XG4gIC8vIFBlcmZvcm1hbmNlIG9wdGltaXphdGlvbiwgc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9mYXN0aWZ5L3NlY3VyZS1qc29uLXBhcnNlL3B1bGwvOTBcbiAgY29uc3QgeyBzdGFja1RyYWNlTGltaXQgfSA9IEVycm9yO1xuICBFcnJvci5zdGFja1RyYWNlTGltaXQgPSAwO1xuICB0cnkge1xuICAgIHJldHVybiBfcGFyc2UodGV4dCk7XG4gIH0gZmluYWxseSB7XG4gICAgRXJyb3Iuc3RhY2tUcmFjZUxpbWl0ID0gc3RhY2tUcmFjZUxpbWl0O1xuICB9XG59XG4iLCAiaW1wb3J0IHsgVHlwZVZhbGlkYXRpb25FcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgRmxleGlibGVWYWxpZGF0b3IsIGFzVmFsaWRhdG9yIH0gZnJvbSAnLi92YWxpZGF0b3InO1xuXG4vKipcbiAqIFZhbGlkYXRlcyB0aGUgdHlwZXMgb2YgYW4gdW5rbm93biBvYmplY3QgdXNpbmcgYSBzY2hlbWEgYW5kXG4gKiByZXR1cm4gYSBzdHJvbmdseS10eXBlZCBvYmplY3QuXG4gKlxuICogQHRlbXBsYXRlIFQgLSBUaGUgdHlwZSBvZiB0aGUgb2JqZWN0IHRvIHZhbGlkYXRlLlxuICogQHBhcmFtIHtzdHJpbmd9IG9wdGlvbnMudmFsdWUgLSBUaGUgb2JqZWN0IHRvIHZhbGlkYXRlLlxuICogQHBhcmFtIHtWYWxpZGF0b3I8VD59IG9wdGlvbnMuc2NoZW1hIC0gVGhlIHNjaGVtYSB0byB1c2UgZm9yIHZhbGlkYXRpbmcgdGhlIEpTT04uXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxUPn0gLSBUaGUgdHlwZWQgb2JqZWN0LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gdmFsaWRhdGVUeXBlczxPQkpFQ1Q+KHtcbiAgdmFsdWUsXG4gIHNjaGVtYSxcbn06IHtcbiAgdmFsdWU6IHVua25vd247XG4gIHNjaGVtYTogRmxleGlibGVWYWxpZGF0b3I8T0JKRUNUPjtcbn0pOiBQcm9taXNlPE9CSkVDVD4ge1xuICBjb25zdCByZXN1bHQgPSBhd2FpdCBzYWZlVmFsaWRhdGVUeXBlcyh7IHZhbHVlLCBzY2hlbWEgfSk7XG5cbiAgaWYgKCFyZXN1bHQuc3VjY2Vzcykge1xuICAgIHRocm93IFR5cGVWYWxpZGF0aW9uRXJyb3Iud3JhcCh7IHZhbHVlLCBjYXVzZTogcmVzdWx0LmVycm9yIH0pO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdC52YWx1ZTtcbn1cblxuLyoqXG4gKiBTYWZlbHkgdmFsaWRhdGVzIHRoZSB0eXBlcyBvZiBhbiB1bmtub3duIG9iamVjdCB1c2luZyBhIHNjaGVtYSBhbmRcbiAqIHJldHVybiBhIHN0cm9uZ2x5LXR5cGVkIG9iamVjdC5cbiAqXG4gKiBAdGVtcGxhdGUgVCAtIFRoZSB0eXBlIG9mIHRoZSBvYmplY3QgdG8gdmFsaWRhdGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gb3B0aW9ucy52YWx1ZSAtIFRoZSBKU09OIG9iamVjdCB0byB2YWxpZGF0ZS5cbiAqIEBwYXJhbSB7VmFsaWRhdG9yPFQ+fSBvcHRpb25zLnNjaGVtYSAtIFRoZSBzY2hlbWEgdG8gdXNlIGZvciB2YWxpZGF0aW5nIHRoZSBKU09OLlxuICogQHJldHVybnMgQW4gb2JqZWN0IHdpdGggZWl0aGVyIGEgYHN1Y2Nlc3NgIGZsYWcgYW5kIHRoZSBwYXJzZWQgYW5kIHR5cGVkIGRhdGEsIG9yIGEgYHN1Y2Nlc3NgIGZsYWcgYW5kIGFuIGVycm9yIG9iamVjdC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNhZmVWYWxpZGF0ZVR5cGVzPE9CSkVDVD4oe1xuICB2YWx1ZSxcbiAgc2NoZW1hLFxufToge1xuICB2YWx1ZTogdW5rbm93bjtcbiAgc2NoZW1hOiBGbGV4aWJsZVZhbGlkYXRvcjxPQkpFQ1Q+O1xufSk6IFByb21pc2U8XG4gIHwge1xuICAgICAgc3VjY2VzczogdHJ1ZTtcbiAgICAgIHZhbHVlOiBPQkpFQ1Q7XG4gICAgICByYXdWYWx1ZTogdW5rbm93bjtcbiAgICB9XG4gIHwge1xuICAgICAgc3VjY2VzczogZmFsc2U7XG4gICAgICBlcnJvcjogVHlwZVZhbGlkYXRpb25FcnJvcjtcbiAgICAgIHJhd1ZhbHVlOiB1bmtub3duO1xuICAgIH1cbj4ge1xuICBjb25zdCB2YWxpZGF0b3IgPSBhc1ZhbGlkYXRvcihzY2hlbWEpO1xuXG4gIHRyeSB7XG4gICAgaWYgKHZhbGlkYXRvci52YWxpZGF0ZSA9PSBudWxsKSB7XG4gICAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlLCB2YWx1ZTogdmFsdWUgYXMgT0JKRUNULCByYXdWYWx1ZTogdmFsdWUgfTtcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB2YWxpZGF0b3IudmFsaWRhdGUodmFsdWUpO1xuXG4gICAgaWYgKHJlc3VsdC5zdWNjZXNzKSB7XG4gICAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlLCB2YWx1ZTogcmVzdWx0LnZhbHVlLCByYXdWYWx1ZTogdmFsdWUgfTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICBlcnJvcjogVHlwZVZhbGlkYXRpb25FcnJvci53cmFwKHsgdmFsdWUsIGNhdXNlOiByZXN1bHQuZXJyb3IgfSksXG4gICAgICByYXdWYWx1ZTogdmFsdWUsXG4gICAgfTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICBlcnJvcjogVHlwZVZhbGlkYXRpb25FcnJvci53cmFwKHsgdmFsdWUsIGNhdXNlOiBlcnJvciB9KSxcbiAgICAgIHJhd1ZhbHVlOiB2YWx1ZSxcbiAgICB9O1xuICB9XG59XG4iLCAiaW1wb3J0IHsgVHlwZVZhbGlkYXRpb25FcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgU3RhbmRhcmRTY2hlbWFWMSB9IGZyb20gJ0BzdGFuZGFyZC1zY2hlbWEvc3BlYyc7XG5cbi8qKlxuICogVXNlZCB0byBtYXJrIHZhbGlkYXRvciBmdW5jdGlvbnMgc28gd2UgY2FuIHN1cHBvcnQgYm90aCBab2QgYW5kIGN1c3RvbSBzY2hlbWFzLlxuICovXG5leHBvcnQgY29uc3QgdmFsaWRhdG9yU3ltYm9sID0gU3ltYm9sLmZvcigndmVyY2VsLmFpLnZhbGlkYXRvcicpO1xuXG5leHBvcnQgdHlwZSBWYWxpZGF0aW9uUmVzdWx0PE9CSkVDVD4gPVxuICB8IHsgc3VjY2VzczogdHJ1ZTsgdmFsdWU6IE9CSkVDVCB9XG4gIHwgeyBzdWNjZXNzOiBmYWxzZTsgZXJyb3I6IEVycm9yIH07XG5cbmV4cG9ydCB0eXBlIFZhbGlkYXRvcjxPQkpFQ1QgPSB1bmtub3duPiA9IHtcbiAgLyoqXG4gICAqIFVzZWQgdG8gbWFyayB2YWxpZGF0b3IgZnVuY3Rpb25zIHNvIHdlIGNhbiBzdXBwb3J0IGJvdGggWm9kIGFuZCBjdXN0b20gc2NoZW1hcy5cbiAgICovXG4gIFt2YWxpZGF0b3JTeW1ib2xdOiB0cnVlO1xuXG4gIC8qKlxuICAgKiBPcHRpb25hbC4gVmFsaWRhdGVzIHRoYXQgdGhlIHN0cnVjdHVyZSBvZiBhIHZhbHVlIG1hdGNoZXMgdGhpcyBzY2hlbWEsXG4gICAqIGFuZCByZXR1cm5zIGEgdHlwZWQgdmVyc2lvbiBvZiB0aGUgdmFsdWUgaWYgaXQgZG9lcy5cbiAgICovXG4gIHJlYWRvbmx5IHZhbGlkYXRlPzogKFxuICAgIHZhbHVlOiB1bmtub3duLFxuICApID0+IFZhbGlkYXRpb25SZXN1bHQ8T0JKRUNUPiB8IFByb21pc2VMaWtlPFZhbGlkYXRpb25SZXN1bHQ8T0JKRUNUPj47XG59O1xuXG4vKipcbiAqIENyZWF0ZSBhIHZhbGlkYXRvci5cbiAqXG4gKiBAcGFyYW0gdmFsaWRhdGUgQSB2YWxpZGF0aW9uIGZ1bmN0aW9uIGZvciB0aGUgc2NoZW1hLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdG9yPE9CSkVDVD4oXG4gIHZhbGlkYXRlPzpcbiAgICB8IHVuZGVmaW5lZFxuICAgIHwgKChcbiAgICAgICAgdmFsdWU6IHVua25vd24sXG4gICAgICApID0+IFZhbGlkYXRpb25SZXN1bHQ8T0JKRUNUPiB8IFByb21pc2VMaWtlPFZhbGlkYXRpb25SZXN1bHQ8T0JKRUNUPj4pLFxuKTogVmFsaWRhdG9yPE9CSkVDVD4ge1xuICByZXR1cm4geyBbdmFsaWRhdG9yU3ltYm9sXTogdHJ1ZSwgdmFsaWRhdGUgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzVmFsaWRhdG9yKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgVmFsaWRhdG9yIHtcbiAgcmV0dXJuIChcbiAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXG4gICAgdmFsdWUgIT09IG51bGwgJiZcbiAgICB2YWxpZGF0b3JTeW1ib2wgaW4gdmFsdWUgJiZcbiAgICB2YWx1ZVt2YWxpZGF0b3JTeW1ib2xdID09PSB0cnVlICYmXG4gICAgJ3ZhbGlkYXRlJyBpbiB2YWx1ZVxuICApO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSB2YWxpZGF0b3Igd2l0aCBkZWZlcnJlZCBjcmVhdGlvbi5cbiAqIFRoaXMgaXMgaW1wb3J0YW50IHRvIHJlZHVjZSB0aGUgc3RhcnR1cCB0aW1lIG9mIHRoZSBsaWJyYXJ5XG4gKiBhbmQgdG8gYXZvaWQgaW5pdGlhbGl6aW5nIHVudXNlZCB2YWxpZGF0b3JzLlxuICpcbiAqIEBwYXJhbSBjcmVhdGVWYWxpZGF0b3IgQSBmdW5jdGlvbiB0aGF0IGNyZWF0ZXMgYSB2YWxpZGF0b3IuXG4gKiBAcmV0dXJucyBBIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBhIHZhbGlkYXRvci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxhenlWYWxpZGF0b3I8T0JKRUNUPihcbiAgY3JlYXRlVmFsaWRhdG9yOiAoKSA9PiBWYWxpZGF0b3I8T0JKRUNUPixcbik6IExhenlWYWxpZGF0b3I8T0JKRUNUPiB7XG4gIC8vIGNhY2hlIHRoZSB2YWxpZGF0b3IgdG8gYXZvaWQgaW5pdGlhbGl6aW5nIGl0IG11bHRpcGxlIHRpbWVzXG4gIGxldCB2YWxpZGF0b3I6IFZhbGlkYXRvcjxPQkpFQ1Q+IHwgdW5kZWZpbmVkO1xuICByZXR1cm4gKCkgPT4ge1xuICAgIGlmICh2YWxpZGF0b3IgPT0gbnVsbCkge1xuICAgICAgdmFsaWRhdG9yID0gY3JlYXRlVmFsaWRhdG9yKCk7XG4gICAgfVxuICAgIHJldHVybiB2YWxpZGF0b3I7XG4gIH07XG59XG5cbmV4cG9ydCB0eXBlIExhenlWYWxpZGF0b3I8T0JKRUNUPiA9ICgpID0+IFZhbGlkYXRvcjxPQkpFQ1Q+O1xuXG5leHBvcnQgdHlwZSBGbGV4aWJsZVZhbGlkYXRvcjxPQkpFQ1Q+ID1cbiAgfCBWYWxpZGF0b3I8T0JKRUNUPlxuICB8IExhenlWYWxpZGF0b3I8T0JKRUNUPlxuICB8IFN0YW5kYXJkU2NoZW1hVjE8dW5rbm93biwgT0JKRUNUPjtcblxuZXhwb3J0IHR5cGUgSW5mZXJWYWxpZGF0b3I8U0NIRU1BPiA9XG4gIFNDSEVNQSBleHRlbmRzIFN0YW5kYXJkU2NoZW1hVjE8dW5rbm93biwgaW5mZXIgVD5cbiAgICA/IFRcbiAgICA6IFNDSEVNQSBleHRlbmRzIExhenlWYWxpZGF0b3I8aW5mZXIgVD5cbiAgICAgID8gVFxuICAgICAgOiBTQ0hFTUEgZXh0ZW5kcyBWYWxpZGF0b3I8aW5mZXIgVD5cbiAgICAgICAgPyBUXG4gICAgICAgIDogbmV2ZXI7XG5cbmV4cG9ydCBmdW5jdGlvbiBhc1ZhbGlkYXRvcjxPQkpFQ1Q+KFxuICB2YWx1ZTogRmxleGlibGVWYWxpZGF0b3I8T0JKRUNUPixcbik6IFZhbGlkYXRvcjxPQkpFQ1Q+IHtcbiAgcmV0dXJuIGlzVmFsaWRhdG9yKHZhbHVlKVxuICAgID8gdmFsdWVcbiAgICA6IHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJ1xuICAgICAgPyB2YWx1ZSgpXG4gICAgICA6IHN0YW5kYXJkU2NoZW1hVmFsaWRhdG9yKHZhbHVlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHN0YW5kYXJkU2NoZW1hVmFsaWRhdG9yPE9CSkVDVD4oXG4gIHN0YW5kYXJkU2NoZW1hOiBTdGFuZGFyZFNjaGVtYVYxPHVua25vd24sIE9CSkVDVD4sXG4pOiBWYWxpZGF0b3I8T0JKRUNUPiB7XG4gIHJldHVybiB2YWxpZGF0b3IoYXN5bmMgdmFsdWUgPT4ge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHN0YW5kYXJkU2NoZW1hWyd+c3RhbmRhcmQnXS52YWxpZGF0ZSh2YWx1ZSk7XG5cbiAgICByZXR1cm4gcmVzdWx0Lmlzc3VlcyA9PSBudWxsXG4gICAgICA/IHsgc3VjY2VzczogdHJ1ZSwgdmFsdWU6IHJlc3VsdC52YWx1ZSB9XG4gICAgICA6IHtcbiAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICBlcnJvcjogbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3Ioe1xuICAgICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgICBjYXVzZTogcmVzdWx0Lmlzc3VlcyxcbiAgICAgICAgICB9KSxcbiAgICAgICAgfTtcbiAgfSk7XG59XG4iLCAiaW1wb3J0IHtcbiAgRXZlbnRTb3VyY2VNZXNzYWdlLFxuICBFdmVudFNvdXJjZVBhcnNlclN0cmVhbSxcbn0gZnJvbSAnZXZlbnRzb3VyY2UtcGFyc2VyL3N0cmVhbSc7XG5pbXBvcnQgeyBQYXJzZVJlc3VsdCwgc2FmZVBhcnNlSlNPTiB9IGZyb20gJy4vcGFyc2UtanNvbic7XG5pbXBvcnQgeyBGbGV4aWJsZVZhbGlkYXRvciB9IGZyb20gJy4vdmFsaWRhdG9yJztcblxuLyoqXG4gKiBQYXJzZXMgYSBKU09OIGV2ZW50IHN0cmVhbSBpbnRvIGEgc3RyZWFtIG9mIHBhcnNlZCBKU09OIG9iamVjdHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUpzb25FdmVudFN0cmVhbTxUPih7XG4gIHN0cmVhbSxcbiAgc2NoZW1hLFxufToge1xuICBzdHJlYW06IFJlYWRhYmxlU3RyZWFtPFVpbnQ4QXJyYXk+O1xuICBzY2hlbWE6IEZsZXhpYmxlVmFsaWRhdG9yPFQ+O1xufSk6IFJlYWRhYmxlU3RyZWFtPFBhcnNlUmVzdWx0PFQ+PiB7XG4gIHJldHVybiBzdHJlYW1cbiAgICAucGlwZVRocm91Z2gobmV3IFRleHREZWNvZGVyU3RyZWFtKCkpXG4gICAgLnBpcGVUaHJvdWdoKG5ldyBFdmVudFNvdXJjZVBhcnNlclN0cmVhbSgpKVxuICAgIC5waXBlVGhyb3VnaChcbiAgICAgIG5ldyBUcmFuc2Zvcm1TdHJlYW08RXZlbnRTb3VyY2VNZXNzYWdlLCBQYXJzZVJlc3VsdDxUPj4oe1xuICAgICAgICBhc3luYyB0cmFuc2Zvcm0oeyBkYXRhIH0sIGNvbnRyb2xsZXIpIHtcbiAgICAgICAgICAvLyBpZ25vcmUgdGhlICdET05FJyBldmVudCB0aGF0IGUuZy4gT3BlbkFJIHNlbmRzOlxuICAgICAgICAgIGlmIChkYXRhID09PSAnW0RPTkVdJykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShhd2FpdCBzYWZlUGFyc2VKU09OKHsgdGV4dDogZGF0YSwgc2NoZW1hIH0pKTtcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgICk7XG59XG4iLCAiaW1wb3J0IHsgSW52YWxpZEFyZ3VtZW50RXJyb3IgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcbmltcG9ydCB7IHNhZmVWYWxpZGF0ZVR5cGVzIH0gZnJvbSAnLi92YWxpZGF0ZS10eXBlcyc7XG5pbXBvcnQgeyBGbGV4aWJsZVZhbGlkYXRvciB9IGZyb20gJy4vdmFsaWRhdG9yJztcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHBhcnNlUHJvdmlkZXJPcHRpb25zPE9QVElPTlM+KHtcbiAgcHJvdmlkZXIsXG4gIHByb3ZpZGVyT3B0aW9ucyxcbiAgc2NoZW1hLFxufToge1xuICBwcm92aWRlcjogc3RyaW5nO1xuICBwcm92aWRlck9wdGlvbnM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgdW5kZWZpbmVkO1xuICBzY2hlbWE6IEZsZXhpYmxlVmFsaWRhdG9yPE9QVElPTlM+O1xufSk6IFByb21pc2U8T1BUSU9OUyB8IHVuZGVmaW5lZD4ge1xuICBpZiAocHJvdmlkZXJPcHRpb25zPy5bcHJvdmlkZXJdID09IG51bGwpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgY29uc3QgcGFyc2VkUHJvdmlkZXJPcHRpb25zID0gYXdhaXQgc2FmZVZhbGlkYXRlVHlwZXM8T1BUSU9OUyB8IHVuZGVmaW5lZD4oe1xuICAgIHZhbHVlOiBwcm92aWRlck9wdGlvbnNbcHJvdmlkZXJdLFxuICAgIHNjaGVtYSxcbiAgfSk7XG5cbiAgaWYgKCFwYXJzZWRQcm92aWRlck9wdGlvbnMuc3VjY2Vzcykge1xuICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFcnJvcih7XG4gICAgICBhcmd1bWVudDogJ3Byb3ZpZGVyT3B0aW9ucycsXG4gICAgICBtZXNzYWdlOiBgaW52YWxpZCAke3Byb3ZpZGVyfSBwcm92aWRlciBvcHRpb25zYCxcbiAgICAgIGNhdXNlOiBwYXJzZWRQcm92aWRlck9wdGlvbnMuZXJyb3IsXG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gcGFyc2VkUHJvdmlkZXJPcHRpb25zLnZhbHVlO1xufVxuIiwgImltcG9ydCB7IEFQSUNhbGxFcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgZXh0cmFjdFJlc3BvbnNlSGVhZGVycyB9IGZyb20gJy4vZXh0cmFjdC1yZXNwb25zZS1oZWFkZXJzJztcbmltcG9ydCB7IEZldGNoRnVuY3Rpb24gfSBmcm9tICcuL2ZldGNoLWZ1bmN0aW9uJztcbmltcG9ydCB7IGhhbmRsZUZldGNoRXJyb3IgfSBmcm9tICcuL2hhbmRsZS1mZXRjaC1lcnJvcic7XG5pbXBvcnQgeyBpc0Fib3J0RXJyb3IgfSBmcm9tICcuL2lzLWFib3J0LWVycm9yJztcbmltcG9ydCB7IFJlc3BvbnNlSGFuZGxlciB9IGZyb20gJy4vcmVzcG9uc2UtaGFuZGxlcic7XG5pbXBvcnQgeyBnZXRSdW50aW1lRW52aXJvbm1lbnRVc2VyQWdlbnQgfSBmcm9tICcuL2dldC1ydW50aW1lLWVudmlyb25tZW50LXVzZXItYWdlbnQnO1xuaW1wb3J0IHsgd2l0aFVzZXJBZ2VudFN1ZmZpeCB9IGZyb20gJy4vd2l0aC11c2VyLWFnZW50LXN1ZmZpeCc7XG5pbXBvcnQgeyBWRVJTSU9OIH0gZnJvbSAnLi92ZXJzaW9uJztcblxuLy8gdXNlIGZ1bmN0aW9uIHRvIGFsbG93IGZvciBtb2NraW5nIGluIHRlc3RzOlxuY29uc3QgZ2V0T3JpZ2luYWxGZXRjaCA9ICgpID0+IGdsb2JhbFRoaXMuZmV0Y2g7XG5cbmV4cG9ydCBjb25zdCBwb3N0SnNvblRvQXBpID0gYXN5bmMgPFQ+KHtcbiAgdXJsLFxuICBoZWFkZXJzLFxuICBib2R5LFxuICBmYWlsZWRSZXNwb25zZUhhbmRsZXIsXG4gIHN1Y2Nlc3NmdWxSZXNwb25zZUhhbmRsZXIsXG4gIGFib3J0U2lnbmFsLFxuICBmZXRjaCxcbn06IHtcbiAgdXJsOiBzdHJpbmc7XG4gIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+O1xuICBib2R5OiB1bmtub3duO1xuICBmYWlsZWRSZXNwb25zZUhhbmRsZXI6IFJlc3BvbnNlSGFuZGxlcjxBUElDYWxsRXJyb3I+O1xuICBzdWNjZXNzZnVsUmVzcG9uc2VIYW5kbGVyOiBSZXNwb25zZUhhbmRsZXI8VD47XG4gIGFib3J0U2lnbmFsPzogQWJvcnRTaWduYWw7XG4gIGZldGNoPzogRmV0Y2hGdW5jdGlvbjtcbn0pID0+XG4gIHBvc3RUb0FwaSh7XG4gICAgdXJsLFxuICAgIGhlYWRlcnM6IHtcbiAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAuLi5oZWFkZXJzLFxuICAgIH0sXG4gICAgYm9keToge1xuICAgICAgY29udGVudDogSlNPTi5zdHJpbmdpZnkoYm9keSksXG4gICAgICB2YWx1ZXM6IGJvZHksXG4gICAgfSxcbiAgICBmYWlsZWRSZXNwb25zZUhhbmRsZXIsXG4gICAgc3VjY2Vzc2Z1bFJlc3BvbnNlSGFuZGxlcixcbiAgICBhYm9ydFNpZ25hbCxcbiAgICBmZXRjaCxcbiAgfSk7XG5cbmV4cG9ydCBjb25zdCBwb3N0Rm9ybURhdGFUb0FwaSA9IGFzeW5jIDxUPih7XG4gIHVybCxcbiAgaGVhZGVycyxcbiAgZm9ybURhdGEsXG4gIGZhaWxlZFJlc3BvbnNlSGFuZGxlcixcbiAgc3VjY2Vzc2Z1bFJlc3BvbnNlSGFuZGxlcixcbiAgYWJvcnRTaWduYWwsXG4gIGZldGNoLFxufToge1xuICB1cmw6IHN0cmluZztcbiAgaGVhZGVycz86IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD47XG4gIGZvcm1EYXRhOiBGb3JtRGF0YTtcbiAgZmFpbGVkUmVzcG9uc2VIYW5kbGVyOiBSZXNwb25zZUhhbmRsZXI8QVBJQ2FsbEVycm9yPjtcbiAgc3VjY2Vzc2Z1bFJlc3BvbnNlSGFuZGxlcjogUmVzcG9uc2VIYW5kbGVyPFQ+O1xuICBhYm9ydFNpZ25hbD86IEFib3J0U2lnbmFsO1xuICBmZXRjaD86IEZldGNoRnVuY3Rpb247XG59KSA9PlxuICBwb3N0VG9BcGkoe1xuICAgIHVybCxcbiAgICBoZWFkZXJzLFxuICAgIGJvZHk6IHtcbiAgICAgIGNvbnRlbnQ6IGZvcm1EYXRhLFxuICAgICAgdmFsdWVzOiBPYmplY3QuZnJvbUVudHJpZXMoKGZvcm1EYXRhIGFzIGFueSkuZW50cmllcygpKSxcbiAgICB9LFxuICAgIGZhaWxlZFJlc3BvbnNlSGFuZGxlcixcbiAgICBzdWNjZXNzZnVsUmVzcG9uc2VIYW5kbGVyLFxuICAgIGFib3J0U2lnbmFsLFxuICAgIGZldGNoLFxuICB9KTtcblxuZXhwb3J0IGNvbnN0IHBvc3RUb0FwaSA9IGFzeW5jIDxUPih7XG4gIHVybCxcbiAgaGVhZGVycyA9IHt9LFxuICBib2R5LFxuICBzdWNjZXNzZnVsUmVzcG9uc2VIYW5kbGVyLFxuICBmYWlsZWRSZXNwb25zZUhhbmRsZXIsXG4gIGFib3J0U2lnbmFsLFxuICBmZXRjaCA9IGdldE9yaWdpbmFsRmV0Y2goKSxcbn06IHtcbiAgdXJsOiBzdHJpbmc7XG4gIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+O1xuICBib2R5OiB7XG4gICAgY29udGVudDogc3RyaW5nIHwgRm9ybURhdGEgfCBVaW50OEFycmF5O1xuICAgIHZhbHVlczogdW5rbm93bjtcbiAgfTtcbiAgZmFpbGVkUmVzcG9uc2VIYW5kbGVyOiBSZXNwb25zZUhhbmRsZXI8RXJyb3I+O1xuICBzdWNjZXNzZnVsUmVzcG9uc2VIYW5kbGVyOiBSZXNwb25zZUhhbmRsZXI8VD47XG4gIGFib3J0U2lnbmFsPzogQWJvcnRTaWduYWw7XG4gIGZldGNoPzogRmV0Y2hGdW5jdGlvbjtcbn0pID0+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHVybCwge1xuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBoZWFkZXJzOiB3aXRoVXNlckFnZW50U3VmZml4KFxuICAgICAgICBoZWFkZXJzLFxuICAgICAgICBgYWktc2RrL3Byb3ZpZGVyLXV0aWxzLyR7VkVSU0lPTn1gLFxuICAgICAgICBnZXRSdW50aW1lRW52aXJvbm1lbnRVc2VyQWdlbnQoKSxcbiAgICAgICksXG4gICAgICBib2R5OiBib2R5LmNvbnRlbnQsXG4gICAgICBzaWduYWw6IGFib3J0U2lnbmFsLFxuICAgIH0pO1xuXG4gICAgY29uc3QgcmVzcG9uc2VIZWFkZXJzID0gZXh0cmFjdFJlc3BvbnNlSGVhZGVycyhyZXNwb25zZSk7XG5cbiAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICBsZXQgZXJyb3JJbmZvcm1hdGlvbjoge1xuICAgICAgICB2YWx1ZTogRXJyb3I7XG4gICAgICAgIHJlc3BvbnNlSGVhZGVycz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gfCB1bmRlZmluZWQ7XG4gICAgICB9O1xuXG4gICAgICB0cnkge1xuICAgICAgICBlcnJvckluZm9ybWF0aW9uID0gYXdhaXQgZmFpbGVkUmVzcG9uc2VIYW5kbGVyKHtcbiAgICAgICAgICByZXNwb25zZSxcbiAgICAgICAgICB1cmwsXG4gICAgICAgICAgcmVxdWVzdEJvZHlWYWx1ZXM6IGJvZHkudmFsdWVzLFxuICAgICAgICB9KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGlmIChpc0Fib3J0RXJyb3IoZXJyb3IpIHx8IEFQSUNhbGxFcnJvci5pc0luc3RhbmNlKGVycm9yKSkge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhyb3cgbmV3IEFQSUNhbGxFcnJvcih7XG4gICAgICAgICAgbWVzc2FnZTogJ0ZhaWxlZCB0byBwcm9jZXNzIGVycm9yIHJlc3BvbnNlJyxcbiAgICAgICAgICBjYXVzZTogZXJyb3IsXG4gICAgICAgICAgc3RhdHVzQ29kZTogcmVzcG9uc2Uuc3RhdHVzLFxuICAgICAgICAgIHVybCxcbiAgICAgICAgICByZXNwb25zZUhlYWRlcnMsXG4gICAgICAgICAgcmVxdWVzdEJvZHlWYWx1ZXM6IGJvZHkudmFsdWVzLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgdGhyb3cgZXJyb3JJbmZvcm1hdGlvbi52YWx1ZTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IHN1Y2Nlc3NmdWxSZXNwb25zZUhhbmRsZXIoe1xuICAgICAgICByZXNwb25zZSxcbiAgICAgICAgdXJsLFxuICAgICAgICByZXF1ZXN0Qm9keVZhbHVlczogYm9keS52YWx1ZXMsXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgaWYgKGlzQWJvcnRFcnJvcihlcnJvcikgfHwgQVBJQ2FsbEVycm9yLmlzSW5zdGFuY2UoZXJyb3IpKSB7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdGhyb3cgbmV3IEFQSUNhbGxFcnJvcih7XG4gICAgICAgIG1lc3NhZ2U6ICdGYWlsZWQgdG8gcHJvY2VzcyBzdWNjZXNzZnVsIHJlc3BvbnNlJyxcbiAgICAgICAgY2F1c2U6IGVycm9yLFxuICAgICAgICBzdGF0dXNDb2RlOiByZXNwb25zZS5zdGF0dXMsXG4gICAgICAgIHVybCxcbiAgICAgICAgcmVzcG9uc2VIZWFkZXJzLFxuICAgICAgICByZXF1ZXN0Qm9keVZhbHVlczogYm9keS52YWx1ZXMsXG4gICAgICB9KTtcbiAgICB9XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgdGhyb3cgaGFuZGxlRmV0Y2hFcnJvcih7IGVycm9yLCB1cmwsIHJlcXVlc3RCb2R5VmFsdWVzOiBib2R5LnZhbHVlcyB9KTtcbiAgfVxufTtcbiIsICJpbXBvcnQgeyBKU09OVmFsdWUsIExhbmd1YWdlTW9kZWxWMlRvb2xSZXN1bHRQYXJ0IH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQgeyBGbGV4aWJsZVNjaGVtYSB9IGZyb20gJy4uL3NjaGVtYSc7XG5pbXBvcnQgeyBNb2RlbE1lc3NhZ2UgfSBmcm9tICcuL21vZGVsLW1lc3NhZ2UnO1xuaW1wb3J0IHsgUHJvdmlkZXJPcHRpb25zIH0gZnJvbSAnLi9wcm92aWRlci1vcHRpb25zJztcblxuLyoqXG4gKiBBZGRpdGlvbmFsIG9wdGlvbnMgdGhhdCBhcmUgc2VudCBpbnRvIGVhY2ggdG9vbCBjYWxsLlxuICovXG4vLyBUT0RPIEFJIFNESyA2OiByZW5hbWUgdG8gVG9vbEV4ZWN1dGlvbk9wdGlvbnNcbmV4cG9ydCBpbnRlcmZhY2UgVG9vbENhbGxPcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSBJRCBvZiB0aGUgdG9vbCBjYWxsLiBZb3UgY2FuIHVzZSBpdCBlLmcuIHdoZW4gc2VuZGluZyB0b29sLWNhbGwgcmVsYXRlZCBpbmZvcm1hdGlvbiB3aXRoIHN0cmVhbSBkYXRhLlxuICAgKi9cbiAgdG9vbENhbGxJZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBNZXNzYWdlcyB0aGF0IHdlcmUgc2VudCB0byB0aGUgbGFuZ3VhZ2UgbW9kZWwgdG8gaW5pdGlhdGUgdGhlIHJlc3BvbnNlIHRoYXQgY29udGFpbmVkIHRoZSB0b29sIGNhbGwuXG4gICAqIFRoZSBtZXNzYWdlcyAqKmRvIG5vdCoqIGluY2x1ZGUgdGhlIHN5c3RlbSBwcm9tcHQgbm9yIHRoZSBhc3Npc3RhbnQgcmVzcG9uc2UgdGhhdCBjb250YWluZWQgdGhlIHRvb2wgY2FsbC5cbiAgICovXG4gIG1lc3NhZ2VzOiBNb2RlbE1lc3NhZ2VbXTtcblxuICAvKipcbiAgICogQW4gb3B0aW9uYWwgYWJvcnQgc2lnbmFsIHRoYXQgaW5kaWNhdGVzIHRoYXQgdGhlIG92ZXJhbGwgb3BlcmF0aW9uIHNob3VsZCBiZSBhYm9ydGVkLlxuICAgKi9cbiAgYWJvcnRTaWduYWw/OiBBYm9ydFNpZ25hbDtcblxuICAvKipcbiAgICogQWRkaXRpb25hbCBjb250ZXh0LlxuICAgKlxuICAgKiBFeHBlcmltZW50YWwgKGNhbiBicmVhayBpbiBwYXRjaCByZWxlYXNlcykuXG4gICAqL1xuICBleHBlcmltZW50YWxfY29udGV4dD86IHVua25vd247XG59XG5cbmV4cG9ydCB0eXBlIFRvb2xFeGVjdXRlRnVuY3Rpb248SU5QVVQsIE9VVFBVVD4gPSAoXG4gIGlucHV0OiBJTlBVVCxcbiAgb3B0aW9uczogVG9vbENhbGxPcHRpb25zLFxuKSA9PiBBc3luY0l0ZXJhYmxlPE9VVFBVVD4gfCBQcm9taXNlTGlrZTxPVVRQVVQ+IHwgT1VUUFVUO1xuXG4vLyAwIGV4dGVuZHMgMSAmIE4gY2hlY2tzIGZvciBhbnlcbi8vIFtOXSBleHRlbmRzIFtuZXZlcl0gY2hlY2tzIGZvciBuZXZlclxudHlwZSBOZXZlck9wdGlvbmFsPE4sIFQ+ID0gMCBleHRlbmRzIDEgJiBOXG4gID8gUGFydGlhbDxUPlxuICA6IFtOXSBleHRlbmRzIFtuZXZlcl1cbiAgICA/IFBhcnRpYWw8UmVjb3JkPGtleW9mIFQsIHVuZGVmaW5lZD4+XG4gICAgOiBUO1xuXG50eXBlIFRvb2xPdXRwdXRQcm9wZXJ0aWVzPElOUFVULCBPVVRQVVQ+ID0gTmV2ZXJPcHRpb25hbDxcbiAgT1VUUFVULFxuICB8IHtcbiAgICAgIC8qKlxuQW4gYXN5bmMgZnVuY3Rpb24gdGhhdCBpcyBjYWxsZWQgd2l0aCB0aGUgYXJndW1lbnRzIGZyb20gdGhlIHRvb2wgY2FsbCBhbmQgcHJvZHVjZXMgYSByZXN1bHQuXG5JZiBub3QgcHJvdmlkZWQsIHRoZSB0b29sIHdpbGwgbm90IGJlIGV4ZWN1dGVkIGF1dG9tYXRpY2FsbHkuXG5cbkBhcmdzIGlzIHRoZSBpbnB1dCBvZiB0aGUgdG9vbCBjYWxsLlxuQG9wdGlvbnMuYWJvcnRTaWduYWwgaXMgYSBzaWduYWwgdGhhdCBjYW4gYmUgdXNlZCB0byBhYm9ydCB0aGUgdG9vbCBjYWxsLlxuICAgICovXG4gICAgICBleGVjdXRlOiBUb29sRXhlY3V0ZUZ1bmN0aW9uPElOUFVULCBPVVRQVVQ+O1xuXG4gICAgICBvdXRwdXRTY2hlbWE/OiBGbGV4aWJsZVNjaGVtYTxPVVRQVVQ+O1xuICAgIH1cbiAgfCB7XG4gICAgICBvdXRwdXRTY2hlbWE6IEZsZXhpYmxlU2NoZW1hPE9VVFBVVD47XG5cbiAgICAgIGV4ZWN1dGU/OiBuZXZlcjtcbiAgICB9XG4+O1xuXG4vKipcbkEgdG9vbCBjb250YWlucyB0aGUgZGVzY3JpcHRpb24gYW5kIHRoZSBzY2hlbWEgb2YgdGhlIGlucHV0IHRoYXQgdGhlIHRvb2wgZXhwZWN0cy5cblRoaXMgZW5hYmxlcyB0aGUgbGFuZ3VhZ2UgbW9kZWwgdG8gZ2VuZXJhdGUgdGhlIGlucHV0LlxuXG5UaGUgdG9vbCBjYW4gYWxzbyBjb250YWluIGFuIG9wdGlvbmFsIGV4ZWN1dGUgZnVuY3Rpb24gZm9yIHRoZSBhY3R1YWwgZXhlY3V0aW9uIGZ1bmN0aW9uIG9mIHRoZSB0b29sLlxuICovXG5leHBvcnQgdHlwZSBUb29sPFxuICBJTlBVVCBleHRlbmRzIEpTT05WYWx1ZSB8IHVua25vd24gfCBuZXZlciA9IGFueSxcbiAgT1VUUFVUIGV4dGVuZHMgSlNPTlZhbHVlIHwgdW5rbm93biB8IG5ldmVyID0gYW55LFxuPiA9IHtcbiAgLyoqXG5BbiBvcHRpb25hbCBkZXNjcmlwdGlvbiBvZiB3aGF0IHRoZSB0b29sIGRvZXMuXG5XaWxsIGJlIHVzZWQgYnkgdGhlIGxhbmd1YWdlIG1vZGVsIHRvIGRlY2lkZSB3aGV0aGVyIHRvIHVzZSB0aGUgdG9vbC5cbk5vdCB1c2VkIGZvciBwcm92aWRlci1kZWZpbmVkIHRvb2xzLlxuICAgKi9cbiAgZGVzY3JpcHRpb24/OiBzdHJpbmc7XG5cbiAgLyoqXG5BZGRpdGlvbmFsIHByb3ZpZGVyLXNwZWNpZmljIG1ldGFkYXRhLiBUaGV5IGFyZSBwYXNzZWQgdGhyb3VnaFxudG8gdGhlIHByb3ZpZGVyIGZyb20gdGhlIEFJIFNESyBhbmQgZW5hYmxlIHByb3ZpZGVyLXNwZWNpZmljXG5mdW5jdGlvbmFsaXR5IHRoYXQgY2FuIGJlIGZ1bGx5IGVuY2Fwc3VsYXRlZCBpbiB0aGUgcHJvdmlkZXIuXG4gICAqL1xuICBwcm92aWRlck9wdGlvbnM/OiBQcm92aWRlck9wdGlvbnM7XG5cbiAgLyoqXG5UaGUgc2NoZW1hIG9mIHRoZSBpbnB1dCB0aGF0IHRoZSB0b29sIGV4cGVjdHMuIFRoZSBsYW5ndWFnZSBtb2RlbCB3aWxsIHVzZSB0aGlzIHRvIGdlbmVyYXRlIHRoZSBpbnB1dC5cbkl0IGlzIGFsc28gdXNlZCB0byB2YWxpZGF0ZSB0aGUgb3V0cHV0IG9mIHRoZSBsYW5ndWFnZSBtb2RlbC5cblVzZSBkZXNjcmlwdGlvbnMgdG8gbWFrZSB0aGUgaW5wdXQgdW5kZXJzdGFuZGFibGUgZm9yIHRoZSBsYW5ndWFnZSBtb2RlbC5cbiAgICovXG4gIGlucHV0U2NoZW1hOiBGbGV4aWJsZVNjaGVtYTxJTlBVVD47XG5cbiAgLyoqXG4gICAqIE9wdGlvbmFsIGZ1bmN0aW9uIHRoYXQgaXMgY2FsbGVkIHdoZW4gdGhlIGFyZ3VtZW50IHN0cmVhbWluZyBzdGFydHMuXG4gICAqIE9ubHkgY2FsbGVkIHdoZW4gdGhlIHRvb2wgaXMgdXNlZCBpbiBhIHN0cmVhbWluZyBjb250ZXh0LlxuICAgKi9cbiAgb25JbnB1dFN0YXJ0PzogKG9wdGlvbnM6IFRvb2xDYWxsT3B0aW9ucykgPT4gdm9pZCB8IFByb21pc2VMaWtlPHZvaWQ+O1xuXG4gIC8qKlxuICAgKiBPcHRpb25hbCBmdW5jdGlvbiB0aGF0IGlzIGNhbGxlZCB3aGVuIGFuIGFyZ3VtZW50IHN0cmVhbWluZyBkZWx0YSBpcyBhdmFpbGFibGUuXG4gICAqIE9ubHkgY2FsbGVkIHdoZW4gdGhlIHRvb2wgaXMgdXNlZCBpbiBhIHN0cmVhbWluZyBjb250ZXh0LlxuICAgKi9cbiAgb25JbnB1dERlbHRhPzogKFxuICAgIG9wdGlvbnM6IHsgaW5wdXRUZXh0RGVsdGE6IHN0cmluZyB9ICYgVG9vbENhbGxPcHRpb25zLFxuICApID0+IHZvaWQgfCBQcm9taXNlTGlrZTx2b2lkPjtcblxuICAvKipcbiAgICogT3B0aW9uYWwgZnVuY3Rpb24gdGhhdCBpcyBjYWxsZWQgd2hlbiBhIHRvb2wgY2FsbCBjYW4gYmUgc3RhcnRlZCxcbiAgICogZXZlbiBpZiB0aGUgZXhlY3V0ZSBmdW5jdGlvbiBpcyBub3QgcHJvdmlkZWQuXG4gICAqL1xuICBvbklucHV0QXZhaWxhYmxlPzogKFxuICAgIG9wdGlvbnM6IHtcbiAgICAgIGlucHV0OiBbSU5QVVRdIGV4dGVuZHMgW25ldmVyXSA/IHVuZGVmaW5lZCA6IElOUFVUO1xuICAgIH0gJiBUb29sQ2FsbE9wdGlvbnMsXG4gICkgPT4gdm9pZCB8IFByb21pc2VMaWtlPHZvaWQ+O1xufSAmIFRvb2xPdXRwdXRQcm9wZXJ0aWVzPElOUFVULCBPVVRQVVQ+ICYge1xuICAgIC8qKlxuT3B0aW9uYWwgY29udmVyc2lvbiBmdW5jdGlvbiB0aGF0IG1hcHMgdGhlIHRvb2wgcmVzdWx0IHRvIGFuIG91dHB1dCB0aGF0IGNhbiBiZSB1c2VkIGJ5IHRoZSBsYW5ndWFnZSBtb2RlbC5cblxuSWYgbm90IHByb3ZpZGVkLCB0aGUgdG9vbCByZXN1bHQgd2lsbCBiZSBzZW50IGFzIGEgSlNPTiBvYmplY3QuXG4gICovXG4gICAgdG9Nb2RlbE91dHB1dD86IChcbiAgICAgIG91dHB1dDogMCBleHRlbmRzIDEgJiBPVVRQVVRcbiAgICAgICAgPyBhbnlcbiAgICAgICAgOiBbT1VUUFVUXSBleHRlbmRzIFtuZXZlcl1cbiAgICAgICAgICA/IGFueVxuICAgICAgICAgIDogTm9JbmZlcjxPVVRQVVQ+LFxuICAgICkgPT4gTGFuZ3VhZ2VNb2RlbFYyVG9vbFJlc3VsdFBhcnRbJ291dHB1dCddO1xuICB9ICYgKFxuICAgIHwge1xuICAgICAgICAvKipcblRvb2wgd2l0aCB1c2VyLWRlZmluZWQgaW5wdXQgYW5kIG91dHB1dCBzY2hlbWFzLlxuICAgICAqL1xuICAgICAgICB0eXBlPzogdW5kZWZpbmVkIHwgJ2Z1bmN0aW9uJztcbiAgICAgIH1cbiAgICB8IHtcbiAgICAgICAgLyoqXG5Ub29sIHRoYXQgaXMgZGVmaW5lZCBhdCBydW50aW1lIChlLmcuIGFuIE1DUCB0b29sKS5cblRoZSB0eXBlcyBvZiBpbnB1dCBhbmQgb3V0cHV0IGFyZSBub3Qga25vd24gYXQgZGV2ZWxvcG1lbnQgdGltZS5cbiAgICAgICAqL1xuICAgICAgICB0eXBlOiAnZHluYW1pYyc7XG4gICAgICB9XG4gICAgfCB7XG4gICAgICAgIC8qKlxuVG9vbCB3aXRoIHByb3ZpZGVyLWRlZmluZWQgaW5wdXQgYW5kIG91dHB1dCBzY2hlbWFzLlxuICAgICAqL1xuICAgICAgICB0eXBlOiAncHJvdmlkZXItZGVmaW5lZCc7XG5cbiAgICAgICAgLyoqXG5UaGUgSUQgb2YgdGhlIHRvb2wuIFNob3VsZCBmb2xsb3cgdGhlIGZvcm1hdCBgPHByb3ZpZGVyLW5hbWU+Ljx1bmlxdWUtdG9vbC1uYW1lPmAuXG4gICAqL1xuICAgICAgICBpZDogYCR7c3RyaW5nfS4ke3N0cmluZ31gO1xuXG4gICAgICAgIC8qKlxuVGhlIG5hbWUgb2YgdGhlIHRvb2wgdGhhdCB0aGUgdXNlciBtdXN0IHVzZSBpbiB0aGUgdG9vbCBzZXQuXG4gKi9cbiAgICAgICAgbmFtZTogc3RyaW5nO1xuXG4gICAgICAgIC8qKlxuVGhlIGFyZ3VtZW50cyBmb3IgY29uZmlndXJpbmcgdGhlIHRvb2wuIE11c3QgbWF0Y2ggdGhlIGV4cGVjdGVkIGFyZ3VtZW50cyBkZWZpbmVkIGJ5IHRoZSBwcm92aWRlciBmb3IgdGhpcyB0b29sLlxuICAgICAqL1xuICAgICAgICBhcmdzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICAgIH1cbiAgKTtcblxuLyoqXG4gKiBJbmZlciB0aGUgaW5wdXQgdHlwZSBvZiBhIHRvb2wuXG4gKi9cbmV4cG9ydCB0eXBlIEluZmVyVG9vbElucHV0PFRPT0wgZXh0ZW5kcyBUb29sPiA9XG4gIFRPT0wgZXh0ZW5kcyBUb29sPGluZmVyIElOUFVULCBhbnk+ID8gSU5QVVQgOiBuZXZlcjtcblxuLyoqXG4gKiBJbmZlciB0aGUgb3V0cHV0IHR5cGUgb2YgYSB0b29sLlxuICovXG5leHBvcnQgdHlwZSBJbmZlclRvb2xPdXRwdXQ8VE9PTCBleHRlbmRzIFRvb2w+ID1cbiAgVE9PTCBleHRlbmRzIFRvb2w8YW55LCBpbmZlciBPVVRQVVQ+ID8gT1VUUFVUIDogbmV2ZXI7XG5cbi8qKlxuSGVscGVyIGZ1bmN0aW9uIGZvciBpbmZlcnJpbmcgdGhlIGV4ZWN1dGUgYXJncyBvZiBhIHRvb2wuXG4gKi9cbi8vIE5vdGU6IG92ZXJsb2FkIG9yZGVyIGlzIGltcG9ydGFudCBmb3IgYXV0by1jb21wbGV0aW9uXG5leHBvcnQgZnVuY3Rpb24gdG9vbDxJTlBVVCwgT1VUUFVUPihcbiAgdG9vbDogVG9vbDxJTlBVVCwgT1VUUFVUPixcbik6IFRvb2w8SU5QVVQsIE9VVFBVVD47XG5leHBvcnQgZnVuY3Rpb24gdG9vbDxJTlBVVD4odG9vbDogVG9vbDxJTlBVVCwgbmV2ZXI+KTogVG9vbDxJTlBVVCwgbmV2ZXI+O1xuZXhwb3J0IGZ1bmN0aW9uIHRvb2w8T1VUUFVUPih0b29sOiBUb29sPG5ldmVyLCBPVVRQVVQ+KTogVG9vbDxuZXZlciwgT1VUUFVUPjtcbmV4cG9ydCBmdW5jdGlvbiB0b29sKHRvb2w6IFRvb2w8bmV2ZXIsIG5ldmVyPik6IFRvb2w8bmV2ZXIsIG5ldmVyPjtcbmV4cG9ydCBmdW5jdGlvbiB0b29sKHRvb2w6IGFueSk6IGFueSB7XG4gIHJldHVybiB0b29sO1xufVxuXG4vKipcbkhlbHBlciBmdW5jdGlvbiBmb3IgZGVmaW5pbmcgYSBkeW5hbWljIHRvb2wuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkeW5hbWljVG9vbCh0b29sOiB7XG4gIGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuICBwcm92aWRlck9wdGlvbnM/OiBQcm92aWRlck9wdGlvbnM7XG4gIGlucHV0U2NoZW1hOiBGbGV4aWJsZVNjaGVtYTx1bmtub3duPjtcbiAgZXhlY3V0ZTogVG9vbEV4ZWN1dGVGdW5jdGlvbjx1bmtub3duLCB1bmtub3duPjtcbiAgdG9Nb2RlbE91dHB1dD86IChvdXRwdXQ6IHVua25vd24pID0+IExhbmd1YWdlTW9kZWxWMlRvb2xSZXN1bHRQYXJ0WydvdXRwdXQnXTtcbn0pOiBUb29sPHVua25vd24sIHVua25vd24+ICYge1xuICB0eXBlOiAnZHluYW1pYyc7XG59IHtcbiAgcmV0dXJuIHsgLi4udG9vbCwgdHlwZTogJ2R5bmFtaWMnIH07XG59XG4iLCAiaW1wb3J0IHsgdG9vbCwgVG9vbCwgVG9vbEV4ZWN1dGVGdW5jdGlvbiB9IGZyb20gJy4vdHlwZXMvdG9vbCc7XG5pbXBvcnQgeyBGbGV4aWJsZVNjaGVtYSB9IGZyb20gJy4vc2NoZW1hJztcblxuZXhwb3J0IHR5cGUgUHJvdmlkZXJEZWZpbmVkVG9vbEZhY3Rvcnk8SU5QVVQsIEFSR1MgZXh0ZW5kcyBvYmplY3Q+ID0gPE9VVFBVVD4oXG4gIG9wdGlvbnM6IEFSR1MgJiB7XG4gICAgZXhlY3V0ZT86IFRvb2xFeGVjdXRlRnVuY3Rpb248SU5QVVQsIE9VVFBVVD47XG4gICAgdG9Nb2RlbE91dHB1dD86IFRvb2w8SU5QVVQsIE9VVFBVVD5bJ3RvTW9kZWxPdXRwdXQnXTtcbiAgICBvbklucHV0U3RhcnQ/OiBUb29sPElOUFVULCBPVVRQVVQ+WydvbklucHV0U3RhcnQnXTtcbiAgICBvbklucHV0RGVsdGE/OiBUb29sPElOUFVULCBPVVRQVVQ+WydvbklucHV0RGVsdGEnXTtcbiAgICBvbklucHV0QXZhaWxhYmxlPzogVG9vbDxJTlBVVCwgT1VUUFVUPlsnb25JbnB1dEF2YWlsYWJsZSddO1xuICB9LFxuKSA9PiBUb29sPElOUFVULCBPVVRQVVQ+O1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUHJvdmlkZXJEZWZpbmVkVG9vbEZhY3Rvcnk8SU5QVVQsIEFSR1MgZXh0ZW5kcyBvYmplY3Q+KHtcbiAgaWQsXG4gIG5hbWUsXG4gIGlucHV0U2NoZW1hLFxufToge1xuICBpZDogYCR7c3RyaW5nfS4ke3N0cmluZ31gO1xuICBuYW1lOiBzdHJpbmc7XG4gIGlucHV0U2NoZW1hOiBGbGV4aWJsZVNjaGVtYTxJTlBVVD47XG59KTogUHJvdmlkZXJEZWZpbmVkVG9vbEZhY3Rvcnk8SU5QVVQsIEFSR1M+IHtcbiAgcmV0dXJuIDxPVVRQVVQ+KHtcbiAgICBleGVjdXRlLFxuICAgIG91dHB1dFNjaGVtYSxcbiAgICB0b01vZGVsT3V0cHV0LFxuICAgIG9uSW5wdXRTdGFydCxcbiAgICBvbklucHV0RGVsdGEsXG4gICAgb25JbnB1dEF2YWlsYWJsZSxcbiAgICAuLi5hcmdzXG4gIH06IEFSR1MgJiB7XG4gICAgZXhlY3V0ZT86IFRvb2xFeGVjdXRlRnVuY3Rpb248SU5QVVQsIE9VVFBVVD47XG4gICAgb3V0cHV0U2NoZW1hPzogRmxleGlibGVTY2hlbWE8T1VUUFVUPjtcbiAgICB0b01vZGVsT3V0cHV0PzogVG9vbDxJTlBVVCwgT1VUUFVUPlsndG9Nb2RlbE91dHB1dCddO1xuICAgIG9uSW5wdXRTdGFydD86IFRvb2w8SU5QVVQsIE9VVFBVVD5bJ29uSW5wdXRTdGFydCddO1xuICAgIG9uSW5wdXREZWx0YT86IFRvb2w8SU5QVVQsIE9VVFBVVD5bJ29uSW5wdXREZWx0YSddO1xuICAgIG9uSW5wdXRBdmFpbGFibGU/OiBUb29sPElOUFVULCBPVVRQVVQ+WydvbklucHV0QXZhaWxhYmxlJ107XG4gIH0pOiBUb29sPElOUFVULCBPVVRQVVQ+ID0+XG4gICAgdG9vbCh7XG4gICAgICB0eXBlOiAncHJvdmlkZXItZGVmaW5lZCcsXG4gICAgICBpZCxcbiAgICAgIG5hbWUsXG4gICAgICBhcmdzLFxuICAgICAgaW5wdXRTY2hlbWEsXG4gICAgICBvdXRwdXRTY2hlbWEsXG4gICAgICBleGVjdXRlLFxuICAgICAgdG9Nb2RlbE91dHB1dCxcbiAgICAgIG9uSW5wdXRTdGFydCxcbiAgICAgIG9uSW5wdXREZWx0YSxcbiAgICAgIG9uSW5wdXRBdmFpbGFibGUsXG4gICAgfSk7XG59XG5cbmV4cG9ydCB0eXBlIFByb3ZpZGVyRGVmaW5lZFRvb2xGYWN0b3J5V2l0aE91dHB1dFNjaGVtYTxcbiAgSU5QVVQsXG4gIE9VVFBVVCxcbiAgQVJHUyBleHRlbmRzIG9iamVjdCxcbj4gPSAoXG4gIG9wdGlvbnM6IEFSR1MgJiB7XG4gICAgZXhlY3V0ZT86IFRvb2xFeGVjdXRlRnVuY3Rpb248SU5QVVQsIE9VVFBVVD47XG4gICAgdG9Nb2RlbE91dHB1dD86IFRvb2w8SU5QVVQsIE9VVFBVVD5bJ3RvTW9kZWxPdXRwdXQnXTtcbiAgICBvbklucHV0U3RhcnQ/OiBUb29sPElOUFVULCBPVVRQVVQ+WydvbklucHV0U3RhcnQnXTtcbiAgICBvbklucHV0RGVsdGE/OiBUb29sPElOUFVULCBPVVRQVVQ+WydvbklucHV0RGVsdGEnXTtcbiAgICBvbklucHV0QXZhaWxhYmxlPzogVG9vbDxJTlBVVCwgT1VUUFVUPlsnb25JbnB1dEF2YWlsYWJsZSddO1xuICB9LFxuKSA9PiBUb29sPElOUFVULCBPVVRQVVQ+O1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUHJvdmlkZXJEZWZpbmVkVG9vbEZhY3RvcnlXaXRoT3V0cHV0U2NoZW1hPFxuICBJTlBVVCxcbiAgT1VUUFVULFxuICBBUkdTIGV4dGVuZHMgb2JqZWN0LFxuPih7XG4gIGlkLFxuICBuYW1lLFxuICBpbnB1dFNjaGVtYSxcbiAgb3V0cHV0U2NoZW1hLFxufToge1xuICBpZDogYCR7c3RyaW5nfS4ke3N0cmluZ31gO1xuICBuYW1lOiBzdHJpbmc7XG4gIGlucHV0U2NoZW1hOiBGbGV4aWJsZVNjaGVtYTxJTlBVVD47XG4gIG91dHB1dFNjaGVtYTogRmxleGlibGVTY2hlbWE8T1VUUFVUPjtcbn0pOiBQcm92aWRlckRlZmluZWRUb29sRmFjdG9yeVdpdGhPdXRwdXRTY2hlbWE8SU5QVVQsIE9VVFBVVCwgQVJHUz4ge1xuICByZXR1cm4gKHtcbiAgICBleGVjdXRlLFxuICAgIHRvTW9kZWxPdXRwdXQsXG4gICAgb25JbnB1dFN0YXJ0LFxuICAgIG9uSW5wdXREZWx0YSxcbiAgICBvbklucHV0QXZhaWxhYmxlLFxuICAgIC4uLmFyZ3NcbiAgfTogQVJHUyAmIHtcbiAgICBleGVjdXRlPzogVG9vbEV4ZWN1dGVGdW5jdGlvbjxJTlBVVCwgT1VUUFVUPjtcbiAgICB0b01vZGVsT3V0cHV0PzogVG9vbDxJTlBVVCwgT1VUUFVUPlsndG9Nb2RlbE91dHB1dCddO1xuICAgIG9uSW5wdXRTdGFydD86IFRvb2w8SU5QVVQsIE9VVFBVVD5bJ29uSW5wdXRTdGFydCddO1xuICAgIG9uSW5wdXREZWx0YT86IFRvb2w8SU5QVVQsIE9VVFBVVD5bJ29uSW5wdXREZWx0YSddO1xuICAgIG9uSW5wdXRBdmFpbGFibGU/OiBUb29sPElOUFVULCBPVVRQVVQ+WydvbklucHV0QXZhaWxhYmxlJ107XG4gIH0pOiBUb29sPElOUFVULCBPVVRQVVQ+ID0+XG4gICAgdG9vbCh7XG4gICAgICB0eXBlOiAncHJvdmlkZXItZGVmaW5lZCcsXG4gICAgICBpZCxcbiAgICAgIG5hbWUsXG4gICAgICBhcmdzLFxuICAgICAgaW5wdXRTY2hlbWEsXG4gICAgICBvdXRwdXRTY2hlbWEsXG4gICAgICBleGVjdXRlLFxuICAgICAgdG9Nb2RlbE91dHB1dCxcbiAgICAgIG9uSW5wdXRTdGFydCxcbiAgICAgIG9uSW5wdXREZWx0YSxcbiAgICAgIG9uSW5wdXRBdmFpbGFibGUsXG4gICAgfSk7XG59XG4iLCAiZXhwb3J0IHR5cGUgUmVzb2x2YWJsZTxUPiA9XG4gIHwgVCAvLyBSYXcgdmFsdWVcbiAgfCBQcm9taXNlPFQ+IC8vIFByb21pc2Ugb2YgdmFsdWVcbiAgfCAoKCkgPT4gVCkgLy8gRnVuY3Rpb24gcmV0dXJuaW5nIHZhbHVlXG4gIHwgKCgpID0+IFByb21pc2U8VD4pOyAvLyBGdW5jdGlvbiByZXR1cm5pbmcgcHJvbWlzZSBvZiB2YWx1ZVxuXG4vKipcbiAqIFJlc29sdmVzIGEgdmFsdWUgdGhhdCBjb3VsZCBiZSBhIHJhdyB2YWx1ZSwgYSBQcm9taXNlLCBhIGZ1bmN0aW9uIHJldHVybmluZyBhIHZhbHVlLFxuICogb3IgYSBmdW5jdGlvbiByZXR1cm5pbmcgYSBQcm9taXNlLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZTxUPih2YWx1ZTogUmVzb2x2YWJsZTxUPik6IFByb21pc2U8VD4ge1xuICAvLyBJZiBpdCdzIGEgZnVuY3Rpb24sIGNhbGwgaXQgdG8gZ2V0IHRoZSB2YWx1ZS9wcm9taXNlXG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICB2YWx1ZSA9ICh2YWx1ZSBhcyBGdW5jdGlvbikoKTtcbiAgfVxuXG4gIC8vIE90aGVyd2lzZSBqdXN0IHJlc29sdmUgd2hhdGV2ZXIgd2UgZ290ICh2YWx1ZSBvciBwcm9taXNlKVxuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHZhbHVlIGFzIFQpO1xufVxuIiwgImltcG9ydCB7IEFQSUNhbGxFcnJvciwgRW1wdHlSZXNwb25zZUJvZHlFcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgWm9kVHlwZSB9IGZyb20gJ3pvZC92NCc7XG5pbXBvcnQgeyBleHRyYWN0UmVzcG9uc2VIZWFkZXJzIH0gZnJvbSAnLi9leHRyYWN0LXJlc3BvbnNlLWhlYWRlcnMnO1xuaW1wb3J0IHsgcGFyc2VKU09OLCBQYXJzZVJlc3VsdCwgc2FmZVBhcnNlSlNPTiB9IGZyb20gJy4vcGFyc2UtanNvbic7XG5pbXBvcnQgeyBwYXJzZUpzb25FdmVudFN0cmVhbSB9IGZyb20gJy4vcGFyc2UtanNvbi1ldmVudC1zdHJlYW0nO1xuaW1wb3J0IHsgRmxleGlibGVWYWxpZGF0b3IgfSBmcm9tICcuL3ZhbGlkYXRvcic7XG5cbmV4cG9ydCB0eXBlIFJlc3BvbnNlSGFuZGxlcjxSRVRVUk5fVFlQRT4gPSAob3B0aW9uczoge1xuICB1cmw6IHN0cmluZztcbiAgcmVxdWVzdEJvZHlWYWx1ZXM6IHVua25vd247XG4gIHJlc3BvbnNlOiBSZXNwb25zZTtcbn0pID0+IFByb21pc2VMaWtlPHtcbiAgdmFsdWU6IFJFVFVSTl9UWVBFO1xuICByYXdWYWx1ZT86IHVua25vd247XG4gIHJlc3BvbnNlSGVhZGVycz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG59PjtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZUpzb25FcnJvclJlc3BvbnNlSGFuZGxlciA9XG4gIDxUPih7XG4gICAgZXJyb3JTY2hlbWEsXG4gICAgZXJyb3JUb01lc3NhZ2UsXG4gICAgaXNSZXRyeWFibGUsXG4gIH06IHtcbiAgICBlcnJvclNjaGVtYTogRmxleGlibGVWYWxpZGF0b3I8VD47XG4gICAgZXJyb3JUb01lc3NhZ2U6IChlcnJvcjogVCkgPT4gc3RyaW5nO1xuICAgIGlzUmV0cnlhYmxlPzogKHJlc3BvbnNlOiBSZXNwb25zZSwgZXJyb3I/OiBUKSA9PiBib29sZWFuO1xuICB9KTogUmVzcG9uc2VIYW5kbGVyPEFQSUNhbGxFcnJvcj4gPT5cbiAgYXN5bmMgKHsgcmVzcG9uc2UsIHVybCwgcmVxdWVzdEJvZHlWYWx1ZXMgfSkgPT4ge1xuICAgIGNvbnN0IHJlc3BvbnNlQm9keSA9IGF3YWl0IHJlc3BvbnNlLnRleHQoKTtcbiAgICBjb25zdCByZXNwb25zZUhlYWRlcnMgPSBleHRyYWN0UmVzcG9uc2VIZWFkZXJzKHJlc3BvbnNlKTtcblxuICAgIC8vIFNvbWUgcHJvdmlkZXJzIHJldHVybiBhbiBlbXB0eSByZXNwb25zZSBib2R5IGZvciBzb21lIGVycm9yczpcbiAgICBpZiAocmVzcG9uc2VCb2R5LnRyaW0oKSA9PT0gJycpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHJlc3BvbnNlSGVhZGVycyxcbiAgICAgICAgdmFsdWU6IG5ldyBBUElDYWxsRXJyb3Ioe1xuICAgICAgICAgIG1lc3NhZ2U6IHJlc3BvbnNlLnN0YXR1c1RleHQsXG4gICAgICAgICAgdXJsLFxuICAgICAgICAgIHJlcXVlc3RCb2R5VmFsdWVzLFxuICAgICAgICAgIHN0YXR1c0NvZGU6IHJlc3BvbnNlLnN0YXR1cyxcbiAgICAgICAgICByZXNwb25zZUhlYWRlcnMsXG4gICAgICAgICAgcmVzcG9uc2VCb2R5LFxuICAgICAgICAgIGlzUmV0cnlhYmxlOiBpc1JldHJ5YWJsZT8uKHJlc3BvbnNlKSxcbiAgICAgICAgfSksXG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIHJlc2lsaWVudCBwYXJzaW5nIGluIGNhc2UgdGhlIHJlc3BvbnNlIGlzIG5vdCBKU09OIG9yIGRvZXMgbm90IG1hdGNoIHRoZSBzY2hlbWE6XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBhcnNlZEVycm9yID0gYXdhaXQgcGFyc2VKU09OKHtcbiAgICAgICAgdGV4dDogcmVzcG9uc2VCb2R5LFxuICAgICAgICBzY2hlbWE6IGVycm9yU2NoZW1hLFxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHJlc3BvbnNlSGVhZGVycyxcbiAgICAgICAgdmFsdWU6IG5ldyBBUElDYWxsRXJyb3Ioe1xuICAgICAgICAgIG1lc3NhZ2U6IGVycm9yVG9NZXNzYWdlKHBhcnNlZEVycm9yKSxcbiAgICAgICAgICB1cmwsXG4gICAgICAgICAgcmVxdWVzdEJvZHlWYWx1ZXMsXG4gICAgICAgICAgc3RhdHVzQ29kZTogcmVzcG9uc2Uuc3RhdHVzLFxuICAgICAgICAgIHJlc3BvbnNlSGVhZGVycyxcbiAgICAgICAgICByZXNwb25zZUJvZHksXG4gICAgICAgICAgZGF0YTogcGFyc2VkRXJyb3IsXG4gICAgICAgICAgaXNSZXRyeWFibGU6IGlzUmV0cnlhYmxlPy4ocmVzcG9uc2UsIHBhcnNlZEVycm9yKSxcbiAgICAgICAgfSksXG4gICAgICB9O1xuICAgIH0gY2F0Y2ggKHBhcnNlRXJyb3IpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHJlc3BvbnNlSGVhZGVycyxcbiAgICAgICAgdmFsdWU6IG5ldyBBUElDYWxsRXJyb3Ioe1xuICAgICAgICAgIG1lc3NhZ2U6IHJlc3BvbnNlLnN0YXR1c1RleHQsXG4gICAgICAgICAgdXJsLFxuICAgICAgICAgIHJlcXVlc3RCb2R5VmFsdWVzLFxuICAgICAgICAgIHN0YXR1c0NvZGU6IHJlc3BvbnNlLnN0YXR1cyxcbiAgICAgICAgICByZXNwb25zZUhlYWRlcnMsXG4gICAgICAgICAgcmVzcG9uc2VCb2R5LFxuICAgICAgICAgIGlzUmV0cnlhYmxlOiBpc1JldHJ5YWJsZT8uKHJlc3BvbnNlKSxcbiAgICAgICAgfSksXG4gICAgICB9O1xuICAgIH1cbiAgfTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZUV2ZW50U291cmNlUmVzcG9uc2VIYW5kbGVyID1cbiAgPFQ+KFxuICAgIGNodW5rU2NoZW1hOiBGbGV4aWJsZVZhbGlkYXRvcjxUPixcbiAgKTogUmVzcG9uc2VIYW5kbGVyPFJlYWRhYmxlU3RyZWFtPFBhcnNlUmVzdWx0PFQ+Pj4gPT5cbiAgYXN5bmMgKHsgcmVzcG9uc2UgfTogeyByZXNwb25zZTogUmVzcG9uc2UgfSkgPT4ge1xuICAgIGNvbnN0IHJlc3BvbnNlSGVhZGVycyA9IGV4dHJhY3RSZXNwb25zZUhlYWRlcnMocmVzcG9uc2UpO1xuXG4gICAgaWYgKHJlc3BvbnNlLmJvZHkgPT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVtcHR5UmVzcG9uc2VCb2R5RXJyb3Ioe30pO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICByZXNwb25zZUhlYWRlcnMsXG4gICAgICB2YWx1ZTogcGFyc2VKc29uRXZlbnRTdHJlYW0oe1xuICAgICAgICBzdHJlYW06IHJlc3BvbnNlLmJvZHksXG4gICAgICAgIHNjaGVtYTogY2h1bmtTY2hlbWEsXG4gICAgICB9KSxcbiAgICB9O1xuICB9O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlSnNvblN0cmVhbVJlc3BvbnNlSGFuZGxlciA9XG4gIDxUPihcbiAgICBjaHVua1NjaGVtYTogWm9kVHlwZTxUPixcbiAgKTogUmVzcG9uc2VIYW5kbGVyPFJlYWRhYmxlU3RyZWFtPFBhcnNlUmVzdWx0PFQ+Pj4gPT5cbiAgYXN5bmMgKHsgcmVzcG9uc2UgfTogeyByZXNwb25zZTogUmVzcG9uc2UgfSkgPT4ge1xuICAgIGNvbnN0IHJlc3BvbnNlSGVhZGVycyA9IGV4dHJhY3RSZXNwb25zZUhlYWRlcnMocmVzcG9uc2UpO1xuXG4gICAgaWYgKHJlc3BvbnNlLmJvZHkgPT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVtcHR5UmVzcG9uc2VCb2R5RXJyb3Ioe30pO1xuICAgIH1cblxuICAgIGxldCBidWZmZXIgPSAnJztcblxuICAgIHJldHVybiB7XG4gICAgICByZXNwb25zZUhlYWRlcnMsXG4gICAgICB2YWx1ZTogcmVzcG9uc2UuYm9keS5waXBlVGhyb3VnaChuZXcgVGV4dERlY29kZXJTdHJlYW0oKSkucGlwZVRocm91Z2goXG4gICAgICAgIG5ldyBUcmFuc2Zvcm1TdHJlYW08c3RyaW5nLCBQYXJzZVJlc3VsdDxUPj4oe1xuICAgICAgICAgIGFzeW5jIHRyYW5zZm9ybShjaHVua1RleHQsIGNvbnRyb2xsZXIpIHtcbiAgICAgICAgICAgIGlmIChjaHVua1RleHQuZW5kc1dpdGgoJ1xcbicpKSB7XG4gICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShcbiAgICAgICAgICAgICAgICBhd2FpdCBzYWZlUGFyc2VKU09OKHtcbiAgICAgICAgICAgICAgICAgIHRleHQ6IGJ1ZmZlciArIGNodW5rVGV4dCxcbiAgICAgICAgICAgICAgICAgIHNjaGVtYTogY2h1bmtTY2hlbWEsXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIGJ1ZmZlciA9ICcnO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgYnVmZmVyICs9IGNodW5rVGV4dDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgICksXG4gICAgfTtcbiAgfTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZUpzb25SZXNwb25zZUhhbmRsZXIgPVxuICA8VD4ocmVzcG9uc2VTY2hlbWE6IEZsZXhpYmxlVmFsaWRhdG9yPFQ+KTogUmVzcG9uc2VIYW5kbGVyPFQ+ID0+XG4gIGFzeW5jICh7IHJlc3BvbnNlLCB1cmwsIHJlcXVlc3RCb2R5VmFsdWVzIH0pID0+IHtcbiAgICBjb25zdCByZXNwb25zZUJvZHkgPSBhd2FpdCByZXNwb25zZS50ZXh0KCk7XG5cbiAgICBjb25zdCBwYXJzZWRSZXN1bHQgPSBhd2FpdCBzYWZlUGFyc2VKU09OKHtcbiAgICAgIHRleHQ6IHJlc3BvbnNlQm9keSxcbiAgICAgIHNjaGVtYTogcmVzcG9uc2VTY2hlbWEsXG4gICAgfSk7XG5cbiAgICBjb25zdCByZXNwb25zZUhlYWRlcnMgPSBleHRyYWN0UmVzcG9uc2VIZWFkZXJzKHJlc3BvbnNlKTtcblxuICAgIGlmICghcGFyc2VkUmVzdWx0LnN1Y2Nlc3MpIHtcbiAgICAgIHRocm93IG5ldyBBUElDYWxsRXJyb3Ioe1xuICAgICAgICBtZXNzYWdlOiAnSW52YWxpZCBKU09OIHJlc3BvbnNlJyxcbiAgICAgICAgY2F1c2U6IHBhcnNlZFJlc3VsdC5lcnJvcixcbiAgICAgICAgc3RhdHVzQ29kZTogcmVzcG9uc2Uuc3RhdHVzLFxuICAgICAgICByZXNwb25zZUhlYWRlcnMsXG4gICAgICAgIHJlc3BvbnNlQm9keSxcbiAgICAgICAgdXJsLFxuICAgICAgICByZXF1ZXN0Qm9keVZhbHVlcyxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICByZXNwb25zZUhlYWRlcnMsXG4gICAgICB2YWx1ZTogcGFyc2VkUmVzdWx0LnZhbHVlLFxuICAgICAgcmF3VmFsdWU6IHBhcnNlZFJlc3VsdC5yYXdWYWx1ZSxcbiAgICB9O1xuICB9O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlQmluYXJ5UmVzcG9uc2VIYW5kbGVyID1cbiAgKCk6IFJlc3BvbnNlSGFuZGxlcjxVaW50OEFycmF5PiA9PlxuICBhc3luYyAoeyByZXNwb25zZSwgdXJsLCByZXF1ZXN0Qm9keVZhbHVlcyB9KSA9PiB7XG4gICAgY29uc3QgcmVzcG9uc2VIZWFkZXJzID0gZXh0cmFjdFJlc3BvbnNlSGVhZGVycyhyZXNwb25zZSk7XG5cbiAgICBpZiAoIXJlc3BvbnNlLmJvZHkpIHtcbiAgICAgIHRocm93IG5ldyBBUElDYWxsRXJyb3Ioe1xuICAgICAgICBtZXNzYWdlOiAnUmVzcG9uc2UgYm9keSBpcyBlbXB0eScsXG4gICAgICAgIHVybCxcbiAgICAgICAgcmVxdWVzdEJvZHlWYWx1ZXMsXG4gICAgICAgIHN0YXR1c0NvZGU6IHJlc3BvbnNlLnN0YXR1cyxcbiAgICAgICAgcmVzcG9uc2VIZWFkZXJzLFxuICAgICAgICByZXNwb25zZUJvZHk6IHVuZGVmaW5lZCxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBidWZmZXIgPSBhd2FpdCByZXNwb25zZS5hcnJheUJ1ZmZlcigpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcmVzcG9uc2VIZWFkZXJzLFxuICAgICAgICB2YWx1ZTogbmV3IFVpbnQ4QXJyYXkoYnVmZmVyKSxcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRocm93IG5ldyBBUElDYWxsRXJyb3Ioe1xuICAgICAgICBtZXNzYWdlOiAnRmFpbGVkIHRvIHJlYWQgcmVzcG9uc2UgYXMgYXJyYXkgYnVmZmVyJyxcbiAgICAgICAgdXJsLFxuICAgICAgICByZXF1ZXN0Qm9keVZhbHVlcyxcbiAgICAgICAgc3RhdHVzQ29kZTogcmVzcG9uc2Uuc3RhdHVzLFxuICAgICAgICByZXNwb25zZUhlYWRlcnMsXG4gICAgICAgIHJlc3BvbnNlQm9keTogdW5kZWZpbmVkLFxuICAgICAgICBjYXVzZTogZXJyb3IsXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVTdGF0dXNDb2RlRXJyb3JSZXNwb25zZUhhbmRsZXIgPVxuICAoKTogUmVzcG9uc2VIYW5kbGVyPEFQSUNhbGxFcnJvcj4gPT5cbiAgYXN5bmMgKHsgcmVzcG9uc2UsIHVybCwgcmVxdWVzdEJvZHlWYWx1ZXMgfSkgPT4ge1xuICAgIGNvbnN0IHJlc3BvbnNlSGVhZGVycyA9IGV4dHJhY3RSZXNwb25zZUhlYWRlcnMocmVzcG9uc2UpO1xuICAgIGNvbnN0IHJlc3BvbnNlQm9keSA9IGF3YWl0IHJlc3BvbnNlLnRleHQoKTtcblxuICAgIHJldHVybiB7XG4gICAgICByZXNwb25zZUhlYWRlcnMsXG4gICAgICB2YWx1ZTogbmV3IEFQSUNhbGxFcnJvcih7XG4gICAgICAgIG1lc3NhZ2U6IHJlc3BvbnNlLnN0YXR1c1RleHQsXG4gICAgICAgIHVybCxcbiAgICAgICAgcmVxdWVzdEJvZHlWYWx1ZXM6IHJlcXVlc3RCb2R5VmFsdWVzIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICAgICAgICBzdGF0dXNDb2RlOiByZXNwb25zZS5zdGF0dXMsXG4gICAgICAgIHJlc3BvbnNlSGVhZGVycyxcbiAgICAgICAgcmVzcG9uc2VCb2R5LFxuICAgICAgfSksXG4gICAgfTtcbiAgfTtcbiIsICJpbXBvcnQgeyBKU09OU2NoZW1hNyB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0ICogYXMgejMgZnJvbSAnem9kL3YzJztcbmltcG9ydCAqIGFzIHo0IGZyb20gJ3pvZC92NCc7XG5pbXBvcnQgem9kVG9Kc29uU2NoZW1hIGZyb20gJy4vem9kLXRvLWpzb24tc2NoZW1hJztcbmltcG9ydCB7IGpzb25TY2hlbWEsIFNjaGVtYSB9IGZyb20gJy4vc2NoZW1hJztcblxuZXhwb3J0IGZ1bmN0aW9uIHpvZDNTY2hlbWE8T0JKRUNUPihcbiAgem9kU2NoZW1hOiB6My5TY2hlbWE8T0JKRUNULCB6My5ab2RUeXBlRGVmLCBhbnk+LFxuICBvcHRpb25zPzoge1xuICAgIC8qKlxuICAgICAqIEVuYWJsZXMgc3VwcG9ydCBmb3IgcmVmZXJlbmNlcyBpbiB0aGUgc2NoZW1hLlxuICAgICAqIFRoaXMgaXMgcmVxdWlyZWQgZm9yIHJlY3Vyc2l2ZSBzY2hlbWFzLCBlLmcuIHdpdGggYHoubGF6eWAuXG4gICAgICogSG93ZXZlciwgbm90IGFsbCBsYW5ndWFnZSBtb2RlbHMgYW5kIHByb3ZpZGVycyBzdXBwb3J0IHN1Y2ggcmVmZXJlbmNlcy5cbiAgICAgKiBEZWZhdWx0cyB0byBgZmFsc2VgLlxuICAgICAqL1xuICAgIHVzZVJlZmVyZW5jZXM/OiBib29sZWFuO1xuICB9LFxuKTogU2NoZW1hPE9CSkVDVD4ge1xuICAvLyBkZWZhdWx0IHRvIG5vIHJlZmVyZW5jZXMgKHRvIHN1cHBvcnQgb3BlbmFwaSBjb252ZXJzaW9uIGZvciBnb29nbGUpXG4gIGNvbnN0IHVzZVJlZmVyZW5jZXMgPSBvcHRpb25zPy51c2VSZWZlcmVuY2VzID8/IGZhbHNlO1xuXG4gIHJldHVybiBqc29uU2NoZW1hKFxuICAgIC8vIGRlZmVyIGpzb24gc2NoZW1hIGNyZWF0aW9uIHRvIGF2b2lkIHVubmVjZXNzYXJ5IGNvbXB1dGF0aW9uIHdoZW4gb25seSB2YWxpZGF0aW9uIGlzIG5lZWRlZFxuICAgICgpID0+XG4gICAgICB6b2RUb0pzb25TY2hlbWEoem9kU2NoZW1hLCB7XG4gICAgICAgICRyZWZTdHJhdGVneTogdXNlUmVmZXJlbmNlcyA/ICdyb290JyA6ICdub25lJyxcbiAgICAgIH0pIGFzIEpTT05TY2hlbWE3LFxuICAgIHtcbiAgICAgIHZhbGlkYXRlOiBhc3luYyB2YWx1ZSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHpvZFNjaGVtYS5zYWZlUGFyc2VBc3luYyh2YWx1ZSk7XG4gICAgICAgIHJldHVybiByZXN1bHQuc3VjY2Vzc1xuICAgICAgICAgID8geyBzdWNjZXNzOiB0cnVlLCB2YWx1ZTogcmVzdWx0LmRhdGEgfVxuICAgICAgICAgIDogeyBzdWNjZXNzOiBmYWxzZSwgZXJyb3I6IHJlc3VsdC5lcnJvciB9O1xuICAgICAgfSxcbiAgICB9LFxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gem9kNFNjaGVtYTxPQkpFQ1Q+KFxuICB6b2RTY2hlbWE6IHo0LmNvcmUuJFpvZFR5cGU8T0JKRUNULCBhbnk+LFxuICBvcHRpb25zPzoge1xuICAgIC8qKlxuICAgICAqIEVuYWJsZXMgc3VwcG9ydCBmb3IgcmVmZXJlbmNlcyBpbiB0aGUgc2NoZW1hLlxuICAgICAqIFRoaXMgaXMgcmVxdWlyZWQgZm9yIHJlY3Vyc2l2ZSBzY2hlbWFzLCBlLmcuIHdpdGggYHoubGF6eWAuXG4gICAgICogSG93ZXZlciwgbm90IGFsbCBsYW5ndWFnZSBtb2RlbHMgYW5kIHByb3ZpZGVycyBzdXBwb3J0IHN1Y2ggcmVmZXJlbmNlcy5cbiAgICAgKiBEZWZhdWx0cyB0byBgZmFsc2VgLlxuICAgICAqL1xuICAgIHVzZVJlZmVyZW5jZXM/OiBib29sZWFuO1xuICB9LFxuKTogU2NoZW1hPE9CSkVDVD4ge1xuICAvLyBkZWZhdWx0IHRvIG5vIHJlZmVyZW5jZXMgKHRvIHN1cHBvcnQgb3BlbmFwaSBjb252ZXJzaW9uIGZvciBnb29nbGUpXG4gIGNvbnN0IHVzZVJlZmVyZW5jZXMgPSBvcHRpb25zPy51c2VSZWZlcmVuY2VzID8/IGZhbHNlO1xuXG4gIHJldHVybiBqc29uU2NoZW1hKFxuICAgIC8vIGRlZmVyIGpzb24gc2NoZW1hIGNyZWF0aW9uIHRvIGF2b2lkIHVubmVjZXNzYXJ5IGNvbXB1dGF0aW9uIHdoZW4gb25seSB2YWxpZGF0aW9uIGlzIG5lZWRlZFxuICAgICgpID0+XG4gICAgICB6NC50b0pTT05TY2hlbWEoem9kU2NoZW1hLCB7XG4gICAgICAgIHRhcmdldDogJ2RyYWZ0LTcnLFxuICAgICAgICBpbzogJ291dHB1dCcsXG4gICAgICAgIHJldXNlZDogdXNlUmVmZXJlbmNlcyA/ICdyZWYnIDogJ2lubGluZScsXG4gICAgICB9KSBhcyBKU09OU2NoZW1hNyxcbiAgICB7XG4gICAgICB2YWxpZGF0ZTogYXN5bmMgdmFsdWUgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB6NC5zYWZlUGFyc2VBc3luYyh6b2RTY2hlbWEsIHZhbHVlKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdC5zdWNjZXNzXG4gICAgICAgICAgPyB7IHN1Y2Nlc3M6IHRydWUsIHZhbHVlOiByZXN1bHQuZGF0YSB9XG4gICAgICAgICAgOiB7IHN1Y2Nlc3M6IGZhbHNlLCBlcnJvcjogcmVzdWx0LmVycm9yIH07XG4gICAgICB9LFxuICAgIH0sXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1pvZDRTY2hlbWEoXG4gIHpvZFNjaGVtYTogejQuY29yZS4kWm9kVHlwZTxhbnksIGFueT4gfCB6My5TY2hlbWE8YW55LCB6My5ab2RUeXBlRGVmLCBhbnk+LFxuKTogem9kU2NoZW1hIGlzIHo0LmNvcmUuJFpvZFR5cGU8YW55LCBhbnk+IHtcbiAgLy8gaHR0cHM6Ly96b2QuZGV2L2xpYnJhcnktYXV0aG9ycz9pZD1ob3ctdG8tc3VwcG9ydC16b2QtMy1hbmQtem9kLTQtc2ltdWx0YW5lb3VzbHlcbiAgcmV0dXJuICdfem9kJyBpbiB6b2RTY2hlbWE7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB6b2RTY2hlbWE8T0JKRUNUPihcbiAgem9kU2NoZW1hOlxuICAgIHwgejQuY29yZS4kWm9kVHlwZTxPQkpFQ1QsIGFueT5cbiAgICB8IHozLlNjaGVtYTxPQkpFQ1QsIHozLlpvZFR5cGVEZWYsIGFueT4sXG4gIG9wdGlvbnM/OiB7XG4gICAgLyoqXG4gICAgICogRW5hYmxlcyBzdXBwb3J0IGZvciByZWZlcmVuY2VzIGluIHRoZSBzY2hlbWEuXG4gICAgICogVGhpcyBpcyByZXF1aXJlZCBmb3IgcmVjdXJzaXZlIHNjaGVtYXMsIGUuZy4gd2l0aCBgei5sYXp5YC5cbiAgICAgKiBIb3dldmVyLCBub3QgYWxsIGxhbmd1YWdlIG1vZGVscyBhbmQgcHJvdmlkZXJzIHN1cHBvcnQgc3VjaCByZWZlcmVuY2VzLlxuICAgICAqIERlZmF1bHRzIHRvIGBmYWxzZWAuXG4gICAgICovXG4gICAgdXNlUmVmZXJlbmNlcz86IGJvb2xlYW47XG4gIH0sXG4pOiBTY2hlbWE8T0JKRUNUPiB7XG4gIGlmIChpc1pvZDRTY2hlbWEoem9kU2NoZW1hKSkge1xuICAgIHJldHVybiB6b2Q0U2NoZW1hKHpvZFNjaGVtYSwgb3B0aW9ucyk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHpvZDNTY2hlbWEoem9kU2NoZW1hLCBvcHRpb25zKTtcbiAgfVxufVxuIiwgImV4cG9ydCBjb25zdCBnZXRSZWxhdGl2ZVBhdGggPSAocGF0aEE6IHN0cmluZ1tdLCBwYXRoQjogc3RyaW5nW10pID0+IHtcbiAgbGV0IGkgPSAwO1xuICBmb3IgKDsgaSA8IHBhdGhBLmxlbmd0aCAmJiBpIDwgcGF0aEIubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAocGF0aEFbaV0gIT09IHBhdGhCW2ldKSBicmVhaztcbiAgfVxuICByZXR1cm4gWyhwYXRoQS5sZW5ndGggLSBpKS50b1N0cmluZygpLCAuLi5wYXRoQi5zbGljZShpKV0uam9pbignLycpO1xufTtcbiIsICJpbXBvcnQgeyBab2RTY2hlbWEsIFpvZFR5cGVEZWYgfSBmcm9tICd6b2QvdjMnO1xuaW1wb3J0IHsgUmVmcywgU2VlbiB9IGZyb20gJy4vcmVmcyc7XG5pbXBvcnQgeyBKc29uU2NoZW1hN1R5cGUgfSBmcm9tICcuL3BhcnNlLXR5cGVzJztcblxuZXhwb3J0IHR5cGUgRGF0ZVN0cmF0ZWd5ID1cbiAgfCAnZm9ybWF0OmRhdGUtdGltZSdcbiAgfCAnZm9ybWF0OmRhdGUnXG4gIHwgJ3N0cmluZydcbiAgfCAnaW50ZWdlcic7XG5cbmV4cG9ydCBjb25zdCBpZ25vcmVPdmVycmlkZSA9IFN5bWJvbChcbiAgJ0xldCB6b2RUb0pzb25TY2hlbWEgZGVjaWRlIG9uIHdoaWNoIHBhcnNlciB0byB1c2UnLFxuKTtcblxuZXhwb3J0IHR5cGUgT3ZlcnJpZGVDYWxsYmFjayA9IChcbiAgZGVmOiBab2RUeXBlRGVmLFxuICByZWZzOiBSZWZzLFxuICBzZWVuOiBTZWVuIHwgdW5kZWZpbmVkLFxuICBmb3JjZVJlc29sdXRpb24/OiBib29sZWFuLFxuKSA9PiBKc29uU2NoZW1hN1R5cGUgfCB1bmRlZmluZWQgfCB0eXBlb2YgaWdub3JlT3ZlcnJpZGU7XG5cbmV4cG9ydCB0eXBlIFBvc3RQcm9jZXNzQ2FsbGJhY2sgPSAoXG4gIGpzb25TY2hlbWE6IEpzb25TY2hlbWE3VHlwZSB8IHVuZGVmaW5lZCxcbiAgZGVmOiBab2RUeXBlRGVmLFxuICByZWZzOiBSZWZzLFxuKSA9PiBKc29uU2NoZW1hN1R5cGUgfCB1bmRlZmluZWQ7XG5cbmV4cG9ydCBjb25zdCBqc29uRGVzY3JpcHRpb246IFBvc3RQcm9jZXNzQ2FsbGJhY2sgPSAoanNvblNjaGVtYSwgZGVmKSA9PiB7XG4gIGlmIChkZWYuZGVzY3JpcHRpb24pIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uanNvblNjaGVtYSxcbiAgICAgICAgLi4uSlNPTi5wYXJzZShkZWYuZGVzY3JpcHRpb24pLFxuICAgICAgfTtcbiAgICB9IGNhdGNoIHt9XG4gIH1cblxuICByZXR1cm4ganNvblNjaGVtYTtcbn07XG5cbmV4cG9ydCB0eXBlIE9wdGlvbnMgPSB7XG4gIG5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgJHJlZlN0cmF0ZWd5OiAncm9vdCcgfCAncmVsYXRpdmUnIHwgJ25vbmUnIHwgJ3NlZW4nO1xuICBiYXNlUGF0aDogc3RyaW5nW107XG4gIGVmZmVjdFN0cmF0ZWd5OiAnaW5wdXQnIHwgJ2FueSc7XG4gIHBpcGVTdHJhdGVneTogJ2lucHV0JyB8ICdvdXRwdXQnIHwgJ2FsbCc7XG4gIGRhdGVTdHJhdGVneTogRGF0ZVN0cmF0ZWd5IHwgRGF0ZVN0cmF0ZWd5W107XG4gIG1hcFN0cmF0ZWd5OiAnZW50cmllcycgfCAncmVjb3JkJztcbiAgcmVtb3ZlQWRkaXRpb25hbFN0cmF0ZWd5OiAncGFzc3Rocm91Z2gnIHwgJ3N0cmljdCc7XG4gIGFsbG93ZWRBZGRpdGlvbmFsUHJvcGVydGllczogdHJ1ZSB8IHVuZGVmaW5lZDtcbiAgcmVqZWN0ZWRBZGRpdGlvbmFsUHJvcGVydGllczogZmFsc2UgfCB1bmRlZmluZWQ7XG4gIHN0cmljdFVuaW9uczogYm9vbGVhbjtcbiAgZGVmaW5pdGlvblBhdGg6IHN0cmluZztcbiAgZGVmaW5pdGlvbnM6IFJlY29yZDxzdHJpbmcsIFpvZFNjaGVtYT47XG4gIGVycm9yTWVzc2FnZXM6IGJvb2xlYW47XG4gIHBhdHRlcm5TdHJhdGVneTogJ2VzY2FwZScgfCAncHJlc2VydmUnO1xuICBhcHBseVJlZ2V4RmxhZ3M6IGJvb2xlYW47XG4gIGVtYWlsU3RyYXRlZ3k6ICdmb3JtYXQ6ZW1haWwnIHwgJ2Zvcm1hdDppZG4tZW1haWwnIHwgJ3BhdHRlcm46em9kJztcbiAgYmFzZTY0U3RyYXRlZ3k6ICdmb3JtYXQ6YmluYXJ5JyB8ICdjb250ZW50RW5jb2Rpbmc6YmFzZTY0JyB8ICdwYXR0ZXJuOnpvZCc7XG4gIG5hbWVTdHJhdGVneTogJ3JlZicgfCAndGl0bGUnO1xuICBvdmVycmlkZT86IE92ZXJyaWRlQ2FsbGJhY2s7XG4gIHBvc3RQcm9jZXNzPzogUG9zdFByb2Nlc3NDYWxsYmFjaztcbn07XG5cbmV4cG9ydCBjb25zdCBkZWZhdWx0T3B0aW9uczogT3B0aW9ucyA9IHtcbiAgbmFtZTogdW5kZWZpbmVkLFxuICAkcmVmU3RyYXRlZ3k6ICdyb290JyxcbiAgYmFzZVBhdGg6IFsnIyddLFxuICBlZmZlY3RTdHJhdGVneTogJ2lucHV0JyxcbiAgcGlwZVN0cmF0ZWd5OiAnYWxsJyxcbiAgZGF0ZVN0cmF0ZWd5OiAnZm9ybWF0OmRhdGUtdGltZScsXG4gIG1hcFN0cmF0ZWd5OiAnZW50cmllcycsXG4gIHJlbW92ZUFkZGl0aW9uYWxTdHJhdGVneTogJ3Bhc3N0aHJvdWdoJyxcbiAgYWxsb3dlZEFkZGl0aW9uYWxQcm9wZXJ0aWVzOiB0cnVlLFxuICByZWplY3RlZEFkZGl0aW9uYWxQcm9wZXJ0aWVzOiBmYWxzZSxcbiAgZGVmaW5pdGlvblBhdGg6ICdkZWZpbml0aW9ucycsXG4gIHN0cmljdFVuaW9uczogZmFsc2UsXG4gIGRlZmluaXRpb25zOiB7fSxcbiAgZXJyb3JNZXNzYWdlczogZmFsc2UsXG4gIHBhdHRlcm5TdHJhdGVneTogJ2VzY2FwZScsXG4gIGFwcGx5UmVnZXhGbGFnczogZmFsc2UsXG4gIGVtYWlsU3RyYXRlZ3k6ICdmb3JtYXQ6ZW1haWwnLFxuICBiYXNlNjRTdHJhdGVneTogJ2NvbnRlbnRFbmNvZGluZzpiYXNlNjQnLFxuICBuYW1lU3RyYXRlZ3k6ICdyZWYnLFxufTtcblxuZXhwb3J0IGNvbnN0IGdldERlZmF1bHRPcHRpb25zID0gKFxuICBvcHRpb25zOiBQYXJ0aWFsPE9wdGlvbnM+IHwgc3RyaW5nIHwgdW5kZWZpbmVkLFxuKSA9PlxuICAodHlwZW9mIG9wdGlvbnMgPT09ICdzdHJpbmcnXG4gICAgPyB7XG4gICAgICAgIC4uLmRlZmF1bHRPcHRpb25zLFxuICAgICAgICBuYW1lOiBvcHRpb25zLFxuICAgICAgfVxuICAgIDoge1xuICAgICAgICAuLi5kZWZhdWx0T3B0aW9ucyxcbiAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgIH0pIGFzIE9wdGlvbnM7XG4iLCAiaW1wb3J0IHsgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kIH0gZnJvbSAnem9kL3YzJztcbmltcG9ydCB7IHBhcnNlQW55RGVmIH0gZnJvbSAnLi9wYXJzZXJzL2FueSc7XG5pbXBvcnQgeyBwYXJzZUFycmF5RGVmIH0gZnJvbSAnLi9wYXJzZXJzL2FycmF5JztcbmltcG9ydCB7IHBhcnNlQmlnaW50RGVmIH0gZnJvbSAnLi9wYXJzZXJzL2JpZ2ludCc7XG5pbXBvcnQgeyBwYXJzZUJvb2xlYW5EZWYgfSBmcm9tICcuL3BhcnNlcnMvYm9vbGVhbic7XG5pbXBvcnQgeyBwYXJzZUJyYW5kZWREZWYgfSBmcm9tICcuL3BhcnNlcnMvYnJhbmRlZCc7XG5pbXBvcnQgeyBwYXJzZUNhdGNoRGVmIH0gZnJvbSAnLi9wYXJzZXJzL2NhdGNoJztcbmltcG9ydCB7IHBhcnNlRGF0ZURlZiB9IGZyb20gJy4vcGFyc2Vycy9kYXRlJztcbmltcG9ydCB7IHBhcnNlRGVmYXVsdERlZiB9IGZyb20gJy4vcGFyc2Vycy9kZWZhdWx0JztcbmltcG9ydCB7IHBhcnNlRWZmZWN0c0RlZiB9IGZyb20gJy4vcGFyc2Vycy9lZmZlY3RzJztcbmltcG9ydCB7IHBhcnNlRW51bURlZiB9IGZyb20gJy4vcGFyc2Vycy9lbnVtJztcbmltcG9ydCB7IHBhcnNlSW50ZXJzZWN0aW9uRGVmIH0gZnJvbSAnLi9wYXJzZXJzL2ludGVyc2VjdGlvbic7XG5pbXBvcnQgeyBwYXJzZUxpdGVyYWxEZWYgfSBmcm9tICcuL3BhcnNlcnMvbGl0ZXJhbCc7XG5pbXBvcnQgeyBwYXJzZU1hcERlZiB9IGZyb20gJy4vcGFyc2Vycy9tYXAnO1xuaW1wb3J0IHsgcGFyc2VOYXRpdmVFbnVtRGVmIH0gZnJvbSAnLi9wYXJzZXJzL25hdGl2ZS1lbnVtJztcbmltcG9ydCB7IHBhcnNlTmV2ZXJEZWYgfSBmcm9tICcuL3BhcnNlcnMvbmV2ZXInO1xuaW1wb3J0IHsgcGFyc2VOdWxsRGVmIH0gZnJvbSAnLi9wYXJzZXJzL251bGwnO1xuaW1wb3J0IHsgcGFyc2VOdWxsYWJsZURlZiB9IGZyb20gJy4vcGFyc2Vycy9udWxsYWJsZSc7XG5pbXBvcnQgeyBwYXJzZU51bWJlckRlZiB9IGZyb20gJy4vcGFyc2Vycy9udW1iZXInO1xuaW1wb3J0IHsgcGFyc2VPYmplY3REZWYgfSBmcm9tICcuL3BhcnNlcnMvb2JqZWN0JztcbmltcG9ydCB7IHBhcnNlT3B0aW9uYWxEZWYgfSBmcm9tICcuL3BhcnNlcnMvb3B0aW9uYWwnO1xuaW1wb3J0IHsgcGFyc2VQaXBlbGluZURlZiB9IGZyb20gJy4vcGFyc2Vycy9waXBlbGluZSc7XG5pbXBvcnQgeyBwYXJzZVByb21pc2VEZWYgfSBmcm9tICcuL3BhcnNlcnMvcHJvbWlzZSc7XG5pbXBvcnQgeyBwYXJzZVJlY29yZERlZiB9IGZyb20gJy4vcGFyc2Vycy9yZWNvcmQnO1xuaW1wb3J0IHsgcGFyc2VTZXREZWYgfSBmcm9tICcuL3BhcnNlcnMvc2V0JztcbmltcG9ydCB7IHBhcnNlU3RyaW5nRGVmIH0gZnJvbSAnLi9wYXJzZXJzL3N0cmluZyc7XG5pbXBvcnQgeyBwYXJzZVR1cGxlRGVmIH0gZnJvbSAnLi9wYXJzZXJzL3R1cGxlJztcbmltcG9ydCB7IHBhcnNlVW5kZWZpbmVkRGVmIH0gZnJvbSAnLi9wYXJzZXJzL3VuZGVmaW5lZCc7XG5pbXBvcnQgeyBwYXJzZVVuaW9uRGVmIH0gZnJvbSAnLi9wYXJzZXJzL3VuaW9uJztcbmltcG9ydCB7IHBhcnNlVW5rbm93bkRlZiB9IGZyb20gJy4vcGFyc2Vycy91bmtub3duJztcbmltcG9ydCB7IFJlZnMgfSBmcm9tICcuL3JlZnMnO1xuaW1wb3J0IHsgcGFyc2VSZWFkb25seURlZiB9IGZyb20gJy4vcGFyc2Vycy9yZWFkb25seSc7XG5pbXBvcnQgeyBKc29uU2NoZW1hN1R5cGUgfSBmcm9tICcuL3BhcnNlLXR5cGVzJztcblxuZXhwb3J0IHR5cGUgSW5uZXJEZWZHZXR0ZXIgPSAoKSA9PiBhbnk7XG5cbmV4cG9ydCBjb25zdCBzZWxlY3RQYXJzZXIgPSAoXG4gIGRlZjogYW55LFxuICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLFxuICByZWZzOiBSZWZzLFxuKTogSnNvblNjaGVtYTdUeXBlIHwgdW5kZWZpbmVkIHwgSW5uZXJEZWZHZXR0ZXIgPT4ge1xuICBzd2l0Y2ggKHR5cGVOYW1lKSB7XG4gICAgY2FzZSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kU3RyaW5nOlxuICAgICAgcmV0dXJuIHBhcnNlU3RyaW5nRGVmKGRlZiwgcmVmcyk7XG4gICAgY2FzZSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kTnVtYmVyOlxuICAgICAgcmV0dXJuIHBhcnNlTnVtYmVyRGVmKGRlZik7XG4gICAgY2FzZSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kT2JqZWN0OlxuICAgICAgcmV0dXJuIHBhcnNlT2JqZWN0RGVmKGRlZiwgcmVmcyk7XG4gICAgY2FzZSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kQmlnSW50OlxuICAgICAgcmV0dXJuIHBhcnNlQmlnaW50RGVmKGRlZik7XG4gICAgY2FzZSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kQm9vbGVhbjpcbiAgICAgIHJldHVybiBwYXJzZUJvb2xlYW5EZWYoKTtcbiAgICBjYXNlIFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2REYXRlOlxuICAgICAgcmV0dXJuIHBhcnNlRGF0ZURlZihkZWYsIHJlZnMpO1xuICAgIGNhc2UgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZFVuZGVmaW5lZDpcbiAgICAgIHJldHVybiBwYXJzZVVuZGVmaW5lZERlZigpO1xuICAgIGNhc2UgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE51bGw6XG4gICAgICByZXR1cm4gcGFyc2VOdWxsRGVmKCk7XG4gICAgY2FzZSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kQXJyYXk6XG4gICAgICByZXR1cm4gcGFyc2VBcnJheURlZihkZWYsIHJlZnMpO1xuICAgIGNhc2UgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZFVuaW9uOlxuICAgIGNhc2UgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZERpc2NyaW1pbmF0ZWRVbmlvbjpcbiAgICAgIHJldHVybiBwYXJzZVVuaW9uRGVmKGRlZiwgcmVmcyk7XG4gICAgY2FzZSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kSW50ZXJzZWN0aW9uOlxuICAgICAgcmV0dXJuIHBhcnNlSW50ZXJzZWN0aW9uRGVmKGRlZiwgcmVmcyk7XG4gICAgY2FzZSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kVHVwbGU6XG4gICAgICByZXR1cm4gcGFyc2VUdXBsZURlZihkZWYsIHJlZnMpO1xuICAgIGNhc2UgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZFJlY29yZDpcbiAgICAgIHJldHVybiBwYXJzZVJlY29yZERlZihkZWYsIHJlZnMpO1xuICAgIGNhc2UgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZExpdGVyYWw6XG4gICAgICByZXR1cm4gcGFyc2VMaXRlcmFsRGVmKGRlZik7XG4gICAgY2FzZSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kRW51bTpcbiAgICAgIHJldHVybiBwYXJzZUVudW1EZWYoZGVmKTtcbiAgICBjYXNlIFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2ROYXRpdmVFbnVtOlxuICAgICAgcmV0dXJuIHBhcnNlTmF0aXZlRW51bURlZihkZWYpO1xuICAgIGNhc2UgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE51bGxhYmxlOlxuICAgICAgcmV0dXJuIHBhcnNlTnVsbGFibGVEZWYoZGVmLCByZWZzKTtcbiAgICBjYXNlIFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RPcHRpb25hbDpcbiAgICAgIHJldHVybiBwYXJzZU9wdGlvbmFsRGVmKGRlZiwgcmVmcyk7XG4gICAgY2FzZSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kTWFwOlxuICAgICAgcmV0dXJuIHBhcnNlTWFwRGVmKGRlZiwgcmVmcyk7XG4gICAgY2FzZSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kU2V0OlxuICAgICAgcmV0dXJuIHBhcnNlU2V0RGVmKGRlZiwgcmVmcyk7XG4gICAgY2FzZSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kTGF6eTpcbiAgICAgIHJldHVybiAoKSA9PiAoZGVmIGFzIGFueSkuZ2V0dGVyKCkuX2RlZjtcbiAgICBjYXNlIFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RQcm9taXNlOlxuICAgICAgcmV0dXJuIHBhcnNlUHJvbWlzZURlZihkZWYsIHJlZnMpO1xuICAgIGNhc2UgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE5hTjpcbiAgICBjYXNlIFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2ROZXZlcjpcbiAgICAgIHJldHVybiBwYXJzZU5ldmVyRGVmKCk7XG4gICAgY2FzZSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kRWZmZWN0czpcbiAgICAgIHJldHVybiBwYXJzZUVmZmVjdHNEZWYoZGVmLCByZWZzKTtcbiAgICBjYXNlIFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RBbnk6XG4gICAgICByZXR1cm4gcGFyc2VBbnlEZWYoKTtcbiAgICBjYXNlIFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RVbmtub3duOlxuICAgICAgcmV0dXJuIHBhcnNlVW5rbm93bkRlZigpO1xuICAgIGNhc2UgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZERlZmF1bHQ6XG4gICAgICByZXR1cm4gcGFyc2VEZWZhdWx0RGVmKGRlZiwgcmVmcyk7XG4gICAgY2FzZSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kQnJhbmRlZDpcbiAgICAgIHJldHVybiBwYXJzZUJyYW5kZWREZWYoZGVmLCByZWZzKTtcbiAgICBjYXNlIFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RSZWFkb25seTpcbiAgICAgIHJldHVybiBwYXJzZVJlYWRvbmx5RGVmKGRlZiwgcmVmcyk7XG4gICAgY2FzZSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kQ2F0Y2g6XG4gICAgICByZXR1cm4gcGFyc2VDYXRjaERlZihkZWYsIHJlZnMpO1xuICAgIGNhc2UgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZFBpcGVsaW5lOlxuICAgICAgcmV0dXJuIHBhcnNlUGlwZWxpbmVEZWYoZGVmLCByZWZzKTtcbiAgICBjYXNlIFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RGdW5jdGlvbjpcbiAgICBjYXNlIFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RWb2lkOlxuICAgIGNhc2UgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZFN5bWJvbDpcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgZGVmYXVsdDpcbiAgICAgIC8qIGM4IGlnbm9yZSBuZXh0ICovXG4gICAgICByZXR1cm4gKChfOiBuZXZlcikgPT4gdW5kZWZpbmVkKSh0eXBlTmFtZSk7XG4gIH1cbn07XG4iLCAiZXhwb3J0IHR5cGUgSnNvblNjaGVtYTdBbnlUeXBlID0geyAkcmVmPzogc3RyaW5nIH07XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUFueURlZigpOiBKc29uU2NoZW1hN0FueVR5cGUge1xuICByZXR1cm4ge307XG59XG4iLCAiaW1wb3J0IHsgWm9kQXJyYXlEZWYsIFpvZEZpcnN0UGFydHlUeXBlS2luZCB9IGZyb20gJ3pvZC92Myc7XG5pbXBvcnQgeyBwYXJzZURlZiB9IGZyb20gJy4uL3BhcnNlLWRlZic7XG5pbXBvcnQgeyBKc29uU2NoZW1hN1R5cGUgfSBmcm9tICcuLi9wYXJzZS10eXBlcyc7XG5pbXBvcnQgeyBSZWZzIH0gZnJvbSAnLi4vcmVmcyc7XG5cbmV4cG9ydCB0eXBlIEpzb25TY2hlbWE3QXJyYXlUeXBlID0ge1xuICB0eXBlOiAnYXJyYXknO1xuICBpdGVtcz86IEpzb25TY2hlbWE3VHlwZTtcbiAgbWluSXRlbXM/OiBudW1iZXI7XG4gIG1heEl0ZW1zPzogbnVtYmVyO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlQXJyYXlEZWYoZGVmOiBab2RBcnJheURlZiwgcmVmczogUmVmcykge1xuICBjb25zdCByZXM6IEpzb25TY2hlbWE3QXJyYXlUeXBlID0ge1xuICAgIHR5cGU6ICdhcnJheScsXG4gIH07XG4gIGlmIChcbiAgICBkZWYudHlwZT8uX2RlZiAmJlxuICAgIGRlZi50eXBlPy5fZGVmPy50eXBlTmFtZSAhPT0gWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEFueVxuICApIHtcbiAgICByZXMuaXRlbXMgPSBwYXJzZURlZihkZWYudHlwZS5fZGVmLCB7XG4gICAgICAuLi5yZWZzLFxuICAgICAgY3VycmVudFBhdGg6IFsuLi5yZWZzLmN1cnJlbnRQYXRoLCAnaXRlbXMnXSxcbiAgICB9KTtcbiAgfVxuXG4gIGlmIChkZWYubWluTGVuZ3RoKSB7XG4gICAgcmVzLm1pbkl0ZW1zID0gZGVmLm1pbkxlbmd0aC52YWx1ZTtcbiAgfVxuICBpZiAoZGVmLm1heExlbmd0aCkge1xuICAgIHJlcy5tYXhJdGVtcyA9IGRlZi5tYXhMZW5ndGgudmFsdWU7XG4gIH1cbiAgaWYgKGRlZi5leGFjdExlbmd0aCkge1xuICAgIHJlcy5taW5JdGVtcyA9IGRlZi5leGFjdExlbmd0aC52YWx1ZTtcbiAgICByZXMubWF4SXRlbXMgPSBkZWYuZXhhY3RMZW5ndGgudmFsdWU7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cbiIsICJpbXBvcnQgeyBab2RCaWdJbnREZWYgfSBmcm9tICd6b2QvdjMnO1xuXG5leHBvcnQgdHlwZSBKc29uU2NoZW1hN0JpZ2ludFR5cGUgPSB7XG4gIHR5cGU6ICdpbnRlZ2VyJztcbiAgZm9ybWF0OiAnaW50NjQnO1xuICBtaW5pbXVtPzogQmlnSW50O1xuICBleGNsdXNpdmVNaW5pbXVtPzogQmlnSW50O1xuICBtYXhpbXVtPzogQmlnSW50O1xuICBleGNsdXNpdmVNYXhpbXVtPzogQmlnSW50O1xuICBtdWx0aXBsZU9mPzogQmlnSW50O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlQmlnaW50RGVmKGRlZjogWm9kQmlnSW50RGVmKTogSnNvblNjaGVtYTdCaWdpbnRUeXBlIHtcbiAgY29uc3QgcmVzOiBKc29uU2NoZW1hN0JpZ2ludFR5cGUgPSB7XG4gICAgdHlwZTogJ2ludGVnZXInLFxuICAgIGZvcm1hdDogJ2ludDY0JyxcbiAgfTtcblxuICBpZiAoIWRlZi5jaGVja3MpIHJldHVybiByZXM7XG5cbiAgZm9yIChjb25zdCBjaGVjayBvZiBkZWYuY2hlY2tzKSB7XG4gICAgc3dpdGNoIChjaGVjay5raW5kKSB7XG4gICAgICBjYXNlICdtaW4nOlxuICAgICAgICBpZiAoY2hlY2suaW5jbHVzaXZlKSB7XG4gICAgICAgICAgcmVzLm1pbmltdW0gPSBjaGVjay52YWx1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXMuZXhjbHVzaXZlTWluaW11bSA9IGNoZWNrLnZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbWF4JzpcbiAgICAgICAgaWYgKGNoZWNrLmluY2x1c2l2ZSkge1xuICAgICAgICAgIHJlcy5tYXhpbXVtID0gY2hlY2sudmFsdWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzLmV4Y2x1c2l2ZU1heGltdW0gPSBjaGVjay52YWx1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbXVsdGlwbGVPZic6XG4gICAgICAgIHJlcy5tdWx0aXBsZU9mID0gY2hlY2sudmFsdWU7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzO1xufVxuIiwgImV4cG9ydCB0eXBlIEpzb25TY2hlbWE3Qm9vbGVhblR5cGUgPSB7XG4gIHR5cGU6ICdib29sZWFuJztcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUJvb2xlYW5EZWYoKTogSnNvblNjaGVtYTdCb29sZWFuVHlwZSB7XG4gIHJldHVybiB7IHR5cGU6ICdib29sZWFuJyB9O1xufVxuIiwgImltcG9ydCB7IFpvZEJyYW5kZWREZWYgfSBmcm9tICd6b2QvdjMnO1xuaW1wb3J0IHsgcGFyc2VEZWYgfSBmcm9tICcuLi9wYXJzZS1kZWYnO1xuaW1wb3J0IHsgUmVmcyB9IGZyb20gJy4uL3JlZnMnO1xuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VCcmFuZGVkRGVmKF9kZWY6IFpvZEJyYW5kZWREZWY8YW55PiwgcmVmczogUmVmcykge1xuICByZXR1cm4gcGFyc2VEZWYoX2RlZi50eXBlLl9kZWYsIHJlZnMpO1xufVxuIiwgImltcG9ydCB7IFpvZENhdGNoRGVmIH0gZnJvbSAnem9kL3YzJztcbmltcG9ydCB7IHBhcnNlRGVmIH0gZnJvbSAnLi4vcGFyc2UtZGVmJztcbmltcG9ydCB7IFJlZnMgfSBmcm9tICcuLi9yZWZzJztcblxuZXhwb3J0IGNvbnN0IHBhcnNlQ2F0Y2hEZWYgPSAoZGVmOiBab2RDYXRjaERlZjxhbnk+LCByZWZzOiBSZWZzKSA9PiB7XG4gIHJldHVybiBwYXJzZURlZihkZWYuaW5uZXJUeXBlLl9kZWYsIHJlZnMpO1xufTtcbiIsICJpbXBvcnQgeyBab2REYXRlRGVmIH0gZnJvbSAnem9kL3YzJztcbmltcG9ydCB7IFJlZnMgfSBmcm9tICcuLi9yZWZzJztcbmltcG9ydCB7IERhdGVTdHJhdGVneSB9IGZyb20gJy4uL29wdGlvbnMnO1xuXG5leHBvcnQgdHlwZSBKc29uU2NoZW1hN0RhdGVUeXBlID1cbiAgfCB7XG4gICAgICB0eXBlOiAnaW50ZWdlcicgfCAnc3RyaW5nJztcbiAgICAgIGZvcm1hdDogJ3VuaXgtdGltZScgfCAnZGF0ZS10aW1lJyB8ICdkYXRlJztcbiAgICAgIG1pbmltdW0/OiBudW1iZXI7XG4gICAgICBtYXhpbXVtPzogbnVtYmVyO1xuICAgIH1cbiAgfCB7XG4gICAgICBhbnlPZjogSnNvblNjaGVtYTdEYXRlVHlwZVtdO1xuICAgIH07XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZURhdGVEZWYoXG4gIGRlZjogWm9kRGF0ZURlZixcbiAgcmVmczogUmVmcyxcbiAgb3ZlcnJpZGVEYXRlU3RyYXRlZ3k/OiBEYXRlU3RyYXRlZ3ksXG4pOiBKc29uU2NoZW1hN0RhdGVUeXBlIHtcbiAgY29uc3Qgc3RyYXRlZ3kgPSBvdmVycmlkZURhdGVTdHJhdGVneSA/PyByZWZzLmRhdGVTdHJhdGVneTtcblxuICBpZiAoQXJyYXkuaXNBcnJheShzdHJhdGVneSkpIHtcbiAgICByZXR1cm4ge1xuICAgICAgYW55T2Y6IHN0cmF0ZWd5Lm1hcCgoaXRlbSwgaSkgPT4gcGFyc2VEYXRlRGVmKGRlZiwgcmVmcywgaXRlbSkpLFxuICAgIH07XG4gIH1cblxuICBzd2l0Y2ggKHN0cmF0ZWd5KSB7XG4gICAgY2FzZSAnc3RyaW5nJzpcbiAgICBjYXNlICdmb3JtYXQ6ZGF0ZS10aW1lJzpcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICBmb3JtYXQ6ICdkYXRlLXRpbWUnLFxuICAgICAgfTtcbiAgICBjYXNlICdmb3JtYXQ6ZGF0ZSc6XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgZm9ybWF0OiAnZGF0ZScsXG4gICAgICB9O1xuICAgIGNhc2UgJ2ludGVnZXInOlxuICAgICAgcmV0dXJuIGludGVnZXJEYXRlUGFyc2VyKGRlZik7XG4gIH1cbn1cblxuY29uc3QgaW50ZWdlckRhdGVQYXJzZXIgPSAoZGVmOiBab2REYXRlRGVmKSA9PiB7XG4gIGNvbnN0IHJlczogSnNvblNjaGVtYTdEYXRlVHlwZSA9IHtcbiAgICB0eXBlOiAnaW50ZWdlcicsXG4gICAgZm9ybWF0OiAndW5peC10aW1lJyxcbiAgfTtcblxuICBmb3IgKGNvbnN0IGNoZWNrIG9mIGRlZi5jaGVja3MpIHtcbiAgICBzd2l0Y2ggKGNoZWNrLmtpbmQpIHtcbiAgICAgIGNhc2UgJ21pbic6XG4gICAgICAgIHJlcy5taW5pbXVtID0gY2hlY2sudmFsdWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbWF4JzpcbiAgICAgICAgcmVzLm1heGltdW0gPSBjaGVjay52YWx1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlcztcbn07XG4iLCAiaW1wb3J0IHsgWm9kRGVmYXVsdERlZiB9IGZyb20gJ3pvZC92Myc7XG5pbXBvcnQgeyBwYXJzZURlZiB9IGZyb20gJy4uL3BhcnNlLWRlZic7XG5pbXBvcnQgeyBKc29uU2NoZW1hN1R5cGUgfSBmcm9tICcuLi9wYXJzZS10eXBlcyc7XG5pbXBvcnQgeyBSZWZzIH0gZnJvbSAnLi4vcmVmcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZURlZmF1bHREZWYoXG4gIF9kZWY6IFpvZERlZmF1bHREZWYsXG4gIHJlZnM6IFJlZnMsXG4pOiBKc29uU2NoZW1hN1R5cGUgJiB7IGRlZmF1bHQ6IGFueSB9IHtcbiAgcmV0dXJuIHtcbiAgICAuLi5wYXJzZURlZihfZGVmLmlubmVyVHlwZS5fZGVmLCByZWZzKSxcbiAgICBkZWZhdWx0OiBfZGVmLmRlZmF1bHRWYWx1ZSgpLFxuICB9O1xufVxuIiwgImltcG9ydCB7IFpvZEVmZmVjdHNEZWYgfSBmcm9tICd6b2QvdjMnO1xuaW1wb3J0IHsgcGFyc2VEZWYgfSBmcm9tICcuLi9wYXJzZS1kZWYnO1xuaW1wb3J0IHsgSnNvblNjaGVtYTdUeXBlIH0gZnJvbSAnLi4vcGFyc2UtdHlwZXMnO1xuaW1wb3J0IHsgUmVmcyB9IGZyb20gJy4uL3JlZnMnO1xuaW1wb3J0IHsgcGFyc2VBbnlEZWYgfSBmcm9tICcuL2FueSc7XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUVmZmVjdHNEZWYoXG4gIF9kZWY6IFpvZEVmZmVjdHNEZWYsXG4gIHJlZnM6IFJlZnMsXG4pOiBKc29uU2NoZW1hN1R5cGUgfCB1bmRlZmluZWQge1xuICByZXR1cm4gcmVmcy5lZmZlY3RTdHJhdGVneSA9PT0gJ2lucHV0J1xuICAgID8gcGFyc2VEZWYoX2RlZi5zY2hlbWEuX2RlZiwgcmVmcylcbiAgICA6IHBhcnNlQW55RGVmKCk7XG59XG4iLCAiaW1wb3J0IHsgWm9kRW51bURlZiB9IGZyb20gJ3pvZC92Myc7XG5cbmV4cG9ydCB0eXBlIEpzb25TY2hlbWE3RW51bVR5cGUgPSB7XG4gIHR5cGU6ICdzdHJpbmcnO1xuICBlbnVtOiBzdHJpbmdbXTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUVudW1EZWYoZGVmOiBab2RFbnVtRGVmKTogSnNvblNjaGVtYTdFbnVtVHlwZSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogJ3N0cmluZycsXG4gICAgZW51bTogQXJyYXkuZnJvbShkZWYudmFsdWVzKSxcbiAgfTtcbn1cbiIsICJpbXBvcnQgeyBab2RJbnRlcnNlY3Rpb25EZWYgfSBmcm9tICd6b2QvdjMnO1xuaW1wb3J0IHsgcGFyc2VEZWYgfSBmcm9tICcuLi9wYXJzZS1kZWYnO1xuaW1wb3J0IHsgSnNvblNjaGVtYTdUeXBlIH0gZnJvbSAnLi4vcGFyc2UtdHlwZXMnO1xuaW1wb3J0IHsgUmVmcyB9IGZyb20gJy4uL3JlZnMnO1xuaW1wb3J0IHsgSnNvblNjaGVtYTdTdHJpbmdUeXBlIH0gZnJvbSAnLi9zdHJpbmcnO1xuXG5leHBvcnQgdHlwZSBKc29uU2NoZW1hN0FsbE9mVHlwZSA9IHtcbiAgYWxsT2Y6IEpzb25TY2hlbWE3VHlwZVtdO1xuICB1bmV2YWx1YXRlZFByb3BlcnRpZXM/OiBib29sZWFuO1xufTtcblxuY29uc3QgaXNKc29uU2NoZW1hN0FsbE9mVHlwZSA9IChcbiAgdHlwZTogSnNvblNjaGVtYTdUeXBlIHwgSnNvblNjaGVtYTdTdHJpbmdUeXBlLFxuKTogdHlwZSBpcyBKc29uU2NoZW1hN0FsbE9mVHlwZSA9PiB7XG4gIGlmICgndHlwZScgaW4gdHlwZSAmJiB0eXBlLnR5cGUgPT09ICdzdHJpbmcnKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiAnYWxsT2YnIGluIHR5cGU7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VJbnRlcnNlY3Rpb25EZWYoXG4gIGRlZjogWm9kSW50ZXJzZWN0aW9uRGVmLFxuICByZWZzOiBSZWZzLFxuKTogSnNvblNjaGVtYTdBbGxPZlR5cGUgfCBKc29uU2NoZW1hN1R5cGUgfCB1bmRlZmluZWQge1xuICBjb25zdCBhbGxPZiA9IFtcbiAgICBwYXJzZURlZihkZWYubGVmdC5fZGVmLCB7XG4gICAgICAuLi5yZWZzLFxuICAgICAgY3VycmVudFBhdGg6IFsuLi5yZWZzLmN1cnJlbnRQYXRoLCAnYWxsT2YnLCAnMCddLFxuICAgIH0pLFxuICAgIHBhcnNlRGVmKGRlZi5yaWdodC5fZGVmLCB7XG4gICAgICAuLi5yZWZzLFxuICAgICAgY3VycmVudFBhdGg6IFsuLi5yZWZzLmN1cnJlbnRQYXRoLCAnYWxsT2YnLCAnMSddLFxuICAgIH0pLFxuICBdLmZpbHRlcigoeCk6IHggaXMgSnNvblNjaGVtYTdUeXBlID0+ICEheCk7XG5cbiAgY29uc3QgbWVyZ2VkQWxsT2Y6IEpzb25TY2hlbWE3VHlwZVtdID0gW107XG4gIC8vIElmIGVpdGhlciBvZiB0aGUgc2NoZW1hcyBpcyBhbiBhbGxPZiwgbWVyZ2UgdGhlbSBpbnRvIGEgc2luZ2xlIGFsbE9mXG4gIGFsbE9mLmZvckVhY2goc2NoZW1hID0+IHtcbiAgICBpZiAoaXNKc29uU2NoZW1hN0FsbE9mVHlwZShzY2hlbWEpKSB7XG4gICAgICBtZXJnZWRBbGxPZi5wdXNoKC4uLnNjaGVtYS5hbGxPZik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxldCBuZXN0ZWRTY2hlbWE6IEpzb25TY2hlbWE3VHlwZSA9IHNjaGVtYTtcbiAgICAgIGlmIChcbiAgICAgICAgJ2FkZGl0aW9uYWxQcm9wZXJ0aWVzJyBpbiBzY2hlbWEgJiZcbiAgICAgICAgc2NoZW1hLmFkZGl0aW9uYWxQcm9wZXJ0aWVzID09PSBmYWxzZVxuICAgICAgKSB7XG4gICAgICAgIGNvbnN0IHsgYWRkaXRpb25hbFByb3BlcnRpZXMsIC4uLnJlc3QgfSA9IHNjaGVtYTtcbiAgICAgICAgbmVzdGVkU2NoZW1hID0gcmVzdDtcbiAgICAgIH1cbiAgICAgIG1lcmdlZEFsbE9mLnB1c2gobmVzdGVkU2NoZW1hKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gbWVyZ2VkQWxsT2YubGVuZ3RoID8geyBhbGxPZjogbWVyZ2VkQWxsT2YgfSA6IHVuZGVmaW5lZDtcbn1cbiIsICJpbXBvcnQgeyBab2RMaXRlcmFsRGVmIH0gZnJvbSAnem9kL3YzJztcblxuZXhwb3J0IHR5cGUgSnNvblNjaGVtYTdMaXRlcmFsVHlwZSA9XG4gIHwge1xuICAgICAgdHlwZTogJ3N0cmluZycgfCAnbnVtYmVyJyB8ICdpbnRlZ2VyJyB8ICdib29sZWFuJztcbiAgICAgIGNvbnN0OiBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuO1xuICAgIH1cbiAgfCB7XG4gICAgICB0eXBlOiAnb2JqZWN0JyB8ICdhcnJheSc7XG4gICAgfTtcblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlTGl0ZXJhbERlZihkZWY6IFpvZExpdGVyYWxEZWYpOiBKc29uU2NoZW1hN0xpdGVyYWxUeXBlIHtcbiAgY29uc3QgcGFyc2VkVHlwZSA9IHR5cGVvZiBkZWYudmFsdWU7XG4gIGlmIChcbiAgICBwYXJzZWRUeXBlICE9PSAnYmlnaW50JyAmJlxuICAgIHBhcnNlZFR5cGUgIT09ICdudW1iZXInICYmXG4gICAgcGFyc2VkVHlwZSAhPT0gJ2Jvb2xlYW4nICYmXG4gICAgcGFyc2VkVHlwZSAhPT0gJ3N0cmluZydcbiAgKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IEFycmF5LmlzQXJyYXkoZGVmLnZhbHVlKSA/ICdhcnJheScgOiAnb2JqZWN0JyxcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBwYXJzZWRUeXBlID09PSAnYmlnaW50JyA/ICdpbnRlZ2VyJyA6IHBhcnNlZFR5cGUsXG4gICAgY29uc3Q6IGRlZi52YWx1ZSxcbiAgfTtcbn1cbiIsICJpbXBvcnQge1xuICBab2RGaXJzdFBhcnR5VHlwZUtpbmQsXG4gIFpvZE1hcERlZixcbiAgWm9kUmVjb3JkRGVmLFxuICBab2RUeXBlQW55LFxufSBmcm9tICd6b2QvdjMnO1xuaW1wb3J0IHsgcGFyc2VEZWYgfSBmcm9tICcuLi9wYXJzZS1kZWYnO1xuaW1wb3J0IHsgSnNvblNjaGVtYTdUeXBlIH0gZnJvbSAnLi4vcGFyc2UtdHlwZXMnO1xuaW1wb3J0IHsgUmVmcyB9IGZyb20gJy4uL3JlZnMnO1xuaW1wb3J0IHsgcGFyc2VCcmFuZGVkRGVmIH0gZnJvbSAnLi9icmFuZGVkJztcbmltcG9ydCB7IEpzb25TY2hlbWE3RW51bVR5cGUgfSBmcm9tICcuL2VudW0nO1xuaW1wb3J0IHsgSnNvblNjaGVtYTdTdHJpbmdUeXBlLCBwYXJzZVN0cmluZ0RlZiB9IGZyb20gJy4vc3RyaW5nJztcblxudHlwZSBKc29uU2NoZW1hN1JlY29yZFByb3BlcnR5TmFtZXNUeXBlID1cbiAgfCBPbWl0PEpzb25TY2hlbWE3U3RyaW5nVHlwZSwgJ3R5cGUnPlxuICB8IE9taXQ8SnNvblNjaGVtYTdFbnVtVHlwZSwgJ3R5cGUnPjtcblxuZXhwb3J0IHR5cGUgSnNvblNjaGVtYTdSZWNvcmRUeXBlID0ge1xuICB0eXBlOiAnb2JqZWN0JztcbiAgYWRkaXRpb25hbFByb3BlcnRpZXM/OiBKc29uU2NoZW1hN1R5cGUgfCB0cnVlO1xuICBwcm9wZXJ0eU5hbWVzPzogSnNvblNjaGVtYTdSZWNvcmRQcm9wZXJ0eU5hbWVzVHlwZTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVJlY29yZERlZihcbiAgZGVmOiBab2RSZWNvcmREZWY8Wm9kVHlwZUFueSwgWm9kVHlwZUFueT4gfCBab2RNYXBEZWYsXG4gIHJlZnM6IFJlZnMsXG4pOiBKc29uU2NoZW1hN1JlY29yZFR5cGUge1xuICBjb25zdCBzY2hlbWE6IEpzb25TY2hlbWE3UmVjb3JkVHlwZSA9IHtcbiAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICBhZGRpdGlvbmFsUHJvcGVydGllczpcbiAgICAgIHBhcnNlRGVmKGRlZi52YWx1ZVR5cGUuX2RlZiwge1xuICAgICAgICAuLi5yZWZzLFxuICAgICAgICBjdXJyZW50UGF0aDogWy4uLnJlZnMuY3VycmVudFBhdGgsICdhZGRpdGlvbmFsUHJvcGVydGllcyddLFxuICAgICAgfSkgPz8gcmVmcy5hbGxvd2VkQWRkaXRpb25hbFByb3BlcnRpZXMsXG4gIH07XG5cbiAgaWYgKFxuICAgIGRlZi5rZXlUeXBlPy5fZGVmLnR5cGVOYW1lID09PSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kU3RyaW5nICYmXG4gICAgZGVmLmtleVR5cGUuX2RlZi5jaGVja3M/Lmxlbmd0aFxuICApIHtcbiAgICBjb25zdCB7IHR5cGUsIC4uLmtleVR5cGUgfSA9IHBhcnNlU3RyaW5nRGVmKGRlZi5rZXlUeXBlLl9kZWYsIHJlZnMpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnNjaGVtYSxcbiAgICAgIHByb3BlcnR5TmFtZXM6IGtleVR5cGUsXG4gICAgfTtcbiAgfSBlbHNlIGlmIChkZWYua2V5VHlwZT8uX2RlZi50eXBlTmFtZSA9PT0gWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEVudW0pIHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4uc2NoZW1hLFxuICAgICAgcHJvcGVydHlOYW1lczoge1xuICAgICAgICBlbnVtOiBkZWYua2V5VHlwZS5fZGVmLnZhbHVlcyxcbiAgICAgIH0sXG4gICAgfTtcbiAgfSBlbHNlIGlmIChcbiAgICBkZWYua2V5VHlwZT8uX2RlZi50eXBlTmFtZSA9PT0gWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEJyYW5kZWQgJiZcbiAgICBkZWYua2V5VHlwZS5fZGVmLnR5cGUuX2RlZi50eXBlTmFtZSA9PT0gWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZFN0cmluZyAmJlxuICAgIGRlZi5rZXlUeXBlLl9kZWYudHlwZS5fZGVmLmNoZWNrcz8ubGVuZ3RoXG4gICkge1xuICAgIGNvbnN0IHsgdHlwZSwgLi4ua2V5VHlwZSB9ID0gcGFyc2VCcmFuZGVkRGVmKFxuICAgICAgZGVmLmtleVR5cGUuX2RlZixcbiAgICAgIHJlZnMsXG4gICAgKSBhcyBKc29uU2NoZW1hN1N0cmluZ1R5cGU7XG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4uc2NoZW1hLFxuICAgICAgcHJvcGVydHlOYW1lczoga2V5VHlwZSxcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHNjaGVtYTtcbn1cbiIsICJpbXBvcnQgeyBab2RTdHJpbmdEZWYgfSBmcm9tICd6b2QvdjMnO1xuaW1wb3J0IHsgUmVmcyB9IGZyb20gJy4uL3JlZnMnO1xuXG5sZXQgZW1vamlSZWdleDogUmVnRXhwIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuXG4vKipcbiAqIEdlbmVyYXRlZCBmcm9tIHRoZSByZWd1bGFyIGV4cHJlc3Npb25zIGZvdW5kIGhlcmUgYXMgb2YgMjAyNC0wNS0yMjpcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9jb2xpbmhhY2tzL3pvZC9ibG9iL21hc3Rlci9zcmMvdHlwZXMudHMuXG4gKlxuICogRXhwcmVzc2lvbnMgd2l0aCAvaSBmbGFnIGhhdmUgYmVlbiBjaGFuZ2VkIGFjY29yZGluZ2x5LlxuICovXG5leHBvcnQgY29uc3Qgem9kUGF0dGVybnMgPSB7XG4gIC8qKlxuICAgKiBgY2Agd2FzIGNoYW5nZWQgdG8gYFtjQ11gIHRvIHJlcGxpY2F0ZSAvaSBmbGFnXG4gICAqL1xuICBjdWlkOiAvXltjQ11bXlxccy1dezgsfSQvLFxuICBjdWlkMjogL15bMC05YS16XSskLyxcbiAgdWxpZDogL15bMC05QS1ISktNTlAtVFYtWl17MjZ9JC8sXG4gIC8qKlxuICAgKiBgYS16YCB3YXMgYWRkZWQgdG8gcmVwbGljYXRlIC9pIGZsYWdcbiAgICovXG4gIGVtYWlsOlxuICAgIC9eKD8hXFwuKSg/IS4qXFwuXFwuKShbYS16QS1aMC05XycrXFwtXFwuXSopW2EtekEtWjAtOV8rLV1AKFthLXpBLVowLTldW2EtekEtWjAtOVxcLV0qXFwuKStbYS16QS1aXXsyLH0kLyxcbiAgLyoqXG4gICAqIENvbnN0cnVjdGVkIGEgdmFsaWQgVW5pY29kZSBSZWdFeHBcbiAgICpcbiAgICogTGF6aWx5IGluc3RhbnRpYXRlIHNpbmNlIHRoaXMgdHlwZSBvZiByZWdleCBpc24ndCBzdXBwb3J0ZWRcbiAgICogaW4gYWxsIGVudnMgKGUuZy4gUmVhY3QgTmF0aXZlKS5cbiAgICpcbiAgICogU2VlOlxuICAgKiBodHRwczovL2dpdGh1Yi5jb20vY29saW5oYWNrcy96b2QvaXNzdWVzLzI0MzNcbiAgICogRml4IGluIFpvZDpcbiAgICogaHR0cHM6Ly9naXRodWIuY29tL2NvbGluaGFja3Mvem9kL2NvbW1pdC85MzQwZmQ1MWU0ODU3NmE3NWFkYzkxOWJmZjY1ZGJjNGE1ZDRjOTliXG4gICAqL1xuICBlbW9qaTogKCkgPT4ge1xuICAgIGlmIChlbW9qaVJlZ2V4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGVtb2ppUmVnZXggPSBSZWdFeHAoXG4gICAgICAgICdeKFxcXFxwe0V4dGVuZGVkX1BpY3RvZ3JhcGhpY318XFxcXHB7RW1vamlfQ29tcG9uZW50fSkrJCcsXG4gICAgICAgICd1JyxcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBlbW9qaVJlZ2V4O1xuICB9LFxuICAvKipcbiAgICogVW51c2VkXG4gICAqL1xuICB1dWlkOiAvXlswLTlhLWZBLUZdezh9XFxiLVswLTlhLWZBLUZdezR9XFxiLVswLTlhLWZBLUZdezR9XFxiLVswLTlhLWZBLUZdezR9XFxiLVswLTlhLWZBLUZdezEyfSQvLFxuICAvKipcbiAgICogVW51c2VkXG4gICAqL1xuICBpcHY0OiAvXig/Oig/OjI1WzAtNV18MlswLTRdWzAtOV18MVswLTldWzAtOV18WzEtOV1bMC05XXxbMC05XSlcXC4pezN9KD86MjVbMC01XXwyWzAtNF1bMC05XXwxWzAtOV1bMC05XXxbMS05XVswLTldfFswLTldKSQvLFxuICBpcHY0Q2lkcjpcbiAgICAvXig/Oig/OjI1WzAtNV18MlswLTRdWzAtOV18MVswLTldWzAtOV18WzEtOV1bMC05XXxbMC05XSlcXC4pezN9KD86MjVbMC01XXwyWzAtNF1bMC05XXwxWzAtOV1bMC05XXxbMS05XVswLTldfFswLTldKVxcLygzWzAtMl18WzEyXT9bMC05XSkkLyxcbiAgLyoqXG4gICAqIFVudXNlZFxuICAgKi9cbiAgaXB2NjogL14oKFthLWYwLTldezEsNH06KXs3fXw6OihbYS1mMC05XXsxLDR9Oil7MCw2fXwoW2EtZjAtOV17MSw0fTopezF9OihbYS1mMC05XXsxLDR9Oil7MCw1fXwoW2EtZjAtOV17MSw0fTopezJ9OihbYS1mMC05XXsxLDR9Oil7MCw0fXwoW2EtZjAtOV17MSw0fTopezN9OihbYS1mMC05XXsxLDR9Oil7MCwzfXwoW2EtZjAtOV17MSw0fTopezR9OihbYS1mMC05XXsxLDR9Oil7MCwyfXwoW2EtZjAtOV17MSw0fTopezV9OihbYS1mMC05XXsxLDR9Oil7MCwxfSkoW2EtZjAtOV17MSw0fXwoKCgyNVswLTVdKXwoMlswLTRdWzAtOV0pfCgxWzAtOV17Mn0pfChbMC05XXsxLDJ9KSlcXC4pezN9KCgyNVswLTVdKXwoMlswLTRdWzAtOV0pfCgxWzAtOV17Mn0pfChbMC05XXsxLDJ9KSkpJC8sXG4gIGlwdjZDaWRyOlxuICAgIC9eKChbMC05YS1mQS1GXXsxLDR9Oil7Nyw3fVswLTlhLWZBLUZdezEsNH18KFswLTlhLWZBLUZdezEsNH06KXsxLDd9OnwoWzAtOWEtZkEtRl17MSw0fTopezEsNn06WzAtOWEtZkEtRl17MSw0fXwoWzAtOWEtZkEtRl17MSw0fTopezEsNX0oOlswLTlhLWZBLUZdezEsNH0pezEsMn18KFswLTlhLWZBLUZdezEsNH06KXsxLDR9KDpbMC05YS1mQS1GXXsxLDR9KXsxLDN9fChbMC05YS1mQS1GXXsxLDR9Oil7MSwzfSg6WzAtOWEtZkEtRl17MSw0fSl7MSw0fXwoWzAtOWEtZkEtRl17MSw0fTopezEsMn0oOlswLTlhLWZBLUZdezEsNH0pezEsNX18WzAtOWEtZkEtRl17MSw0fTooKDpbMC05YS1mQS1GXXsxLDR9KXsxLDZ9KXw6KCg6WzAtOWEtZkEtRl17MSw0fSl7MSw3fXw6KXxmZTgwOig6WzAtOWEtZkEtRl17MCw0fSl7MCw0fSVbMC05YS16QS1aXXsxLH18OjooZmZmZig6MHsxLDR9KXswLDF9Oil7MCwxfSgoMjVbMC01XXwoMlswLTRdfDF7MCwxfVswLTldKXswLDF9WzAtOV0pXFwuKXszLDN9KDI1WzAtNV18KDJbMC00XXwxezAsMX1bMC05XSl7MCwxfVswLTldKXwoWzAtOWEtZkEtRl17MSw0fTopezEsNH06KCgyNVswLTVdfCgyWzAtNF18MXswLDF9WzAtOV0pezAsMX1bMC05XSlcXC4pezMsM30oMjVbMC01XXwoMlswLTRdfDF7MCwxfVswLTldKXswLDF9WzAtOV0pKVxcLygxMlswLThdfDFbMDFdWzAtOV18WzEtOV0/WzAtOV0pJC8sXG4gIGJhc2U2NDogL14oWzAtOWEtekEtWisvXXs0fSkqKChbMC05YS16QS1aKy9dezJ9PT0pfChbMC05YS16QS1aKy9dezN9PSkpPyQvLFxuICBiYXNlNjR1cmw6XG4gICAgL14oWzAtOWEtekEtWi1fXXs0fSkqKChbMC05YS16QS1aLV9dezJ9KD09KT8pfChbMC05YS16QS1aLV9dezN9KD0pPykpPyQvLFxuICBuYW5vaWQ6IC9eW2EtekEtWjAtOV8tXXsyMX0kLyxcbiAgand0OiAvXltBLVphLXowLTktX10rXFwuW0EtWmEtejAtOS1fXStcXC5bQS1aYS16MC05LV9dKiQvLFxufSBhcyBjb25zdDtcblxuZXhwb3J0IHR5cGUgSnNvblNjaGVtYTdTdHJpbmdUeXBlID0ge1xuICB0eXBlOiAnc3RyaW5nJztcbiAgbWluTGVuZ3RoPzogbnVtYmVyO1xuICBtYXhMZW5ndGg/OiBudW1iZXI7XG4gIGZvcm1hdD86XG4gICAgfCAnZW1haWwnXG4gICAgfCAnaWRuLWVtYWlsJ1xuICAgIHwgJ3VyaSdcbiAgICB8ICd1dWlkJ1xuICAgIHwgJ2RhdGUtdGltZSdcbiAgICB8ICdpcHY0J1xuICAgIHwgJ2lwdjYnXG4gICAgfCAnZGF0ZSdcbiAgICB8ICd0aW1lJ1xuICAgIHwgJ2R1cmF0aW9uJztcbiAgcGF0dGVybj86IHN0cmluZztcbiAgYWxsT2Y/OiB7XG4gICAgcGF0dGVybjogc3RyaW5nO1xuICB9W107XG4gIGFueU9mPzoge1xuICAgIGZvcm1hdDogc3RyaW5nO1xuICB9W107XG4gIGNvbnRlbnRFbmNvZGluZz86IHN0cmluZztcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVN0cmluZ0RlZihcbiAgZGVmOiBab2RTdHJpbmdEZWYsXG4gIHJlZnM6IFJlZnMsXG4pOiBKc29uU2NoZW1hN1N0cmluZ1R5cGUge1xuICBjb25zdCByZXM6IEpzb25TY2hlbWE3U3RyaW5nVHlwZSA9IHtcbiAgICB0eXBlOiAnc3RyaW5nJyxcbiAgfTtcblxuICBpZiAoZGVmLmNoZWNrcykge1xuICAgIGZvciAoY29uc3QgY2hlY2sgb2YgZGVmLmNoZWNrcykge1xuICAgICAgc3dpdGNoIChjaGVjay5raW5kKSB7XG4gICAgICAgIGNhc2UgJ21pbic6XG4gICAgICAgICAgcmVzLm1pbkxlbmd0aCA9XG4gICAgICAgICAgICB0eXBlb2YgcmVzLm1pbkxlbmd0aCA9PT0gJ251bWJlcidcbiAgICAgICAgICAgICAgPyBNYXRoLm1heChyZXMubWluTGVuZ3RoLCBjaGVjay52YWx1ZSlcbiAgICAgICAgICAgICAgOiBjaGVjay52YWx1ZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnbWF4JzpcbiAgICAgICAgICByZXMubWF4TGVuZ3RoID1cbiAgICAgICAgICAgIHR5cGVvZiByZXMubWF4TGVuZ3RoID09PSAnbnVtYmVyJ1xuICAgICAgICAgICAgICA/IE1hdGgubWluKHJlcy5tYXhMZW5ndGgsIGNoZWNrLnZhbHVlKVxuICAgICAgICAgICAgICA6IGNoZWNrLnZhbHVlO1xuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2VtYWlsJzpcbiAgICAgICAgICBzd2l0Y2ggKHJlZnMuZW1haWxTdHJhdGVneSkge1xuICAgICAgICAgICAgY2FzZSAnZm9ybWF0OmVtYWlsJzpcbiAgICAgICAgICAgICAgYWRkRm9ybWF0KHJlcywgJ2VtYWlsJywgY2hlY2subWVzc2FnZSwgcmVmcyk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnZm9ybWF0Omlkbi1lbWFpbCc6XG4gICAgICAgICAgICAgIGFkZEZvcm1hdChyZXMsICdpZG4tZW1haWwnLCBjaGVjay5tZXNzYWdlLCByZWZzKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdwYXR0ZXJuOnpvZCc6XG4gICAgICAgICAgICAgIGFkZFBhdHRlcm4ocmVzLCB6b2RQYXR0ZXJucy5lbWFpbCwgY2hlY2subWVzc2FnZSwgcmVmcyk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICd1cmwnOlxuICAgICAgICAgIGFkZEZvcm1hdChyZXMsICd1cmknLCBjaGVjay5tZXNzYWdlLCByZWZzKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAndXVpZCc6XG4gICAgICAgICAgYWRkRm9ybWF0KHJlcywgJ3V1aWQnLCBjaGVjay5tZXNzYWdlLCByZWZzKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAncmVnZXgnOlxuICAgICAgICAgIGFkZFBhdHRlcm4ocmVzLCBjaGVjay5yZWdleCwgY2hlY2subWVzc2FnZSwgcmVmcyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2N1aWQnOlxuICAgICAgICAgIGFkZFBhdHRlcm4ocmVzLCB6b2RQYXR0ZXJucy5jdWlkLCBjaGVjay5tZXNzYWdlLCByZWZzKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnY3VpZDInOlxuICAgICAgICAgIGFkZFBhdHRlcm4ocmVzLCB6b2RQYXR0ZXJucy5jdWlkMiwgY2hlY2subWVzc2FnZSwgcmVmcyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3N0YXJ0c1dpdGgnOlxuICAgICAgICAgIGFkZFBhdHRlcm4oXG4gICAgICAgICAgICByZXMsXG4gICAgICAgICAgICBSZWdFeHAoYF4ke2VzY2FwZUxpdGVyYWxDaGVja1ZhbHVlKGNoZWNrLnZhbHVlLCByZWZzKX1gKSxcbiAgICAgICAgICAgIGNoZWNrLm1lc3NhZ2UsXG4gICAgICAgICAgICByZWZzLFxuICAgICAgICAgICk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2VuZHNXaXRoJzpcbiAgICAgICAgICBhZGRQYXR0ZXJuKFxuICAgICAgICAgICAgcmVzLFxuICAgICAgICAgICAgUmVnRXhwKGAke2VzY2FwZUxpdGVyYWxDaGVja1ZhbHVlKGNoZWNrLnZhbHVlLCByZWZzKX0kYCksXG4gICAgICAgICAgICBjaGVjay5tZXNzYWdlLFxuICAgICAgICAgICAgcmVmcyxcbiAgICAgICAgICApO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdkYXRldGltZSc6XG4gICAgICAgICAgYWRkRm9ybWF0KHJlcywgJ2RhdGUtdGltZScsIGNoZWNrLm1lc3NhZ2UsIHJlZnMpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdkYXRlJzpcbiAgICAgICAgICBhZGRGb3JtYXQocmVzLCAnZGF0ZScsIGNoZWNrLm1lc3NhZ2UsIHJlZnMpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICd0aW1lJzpcbiAgICAgICAgICBhZGRGb3JtYXQocmVzLCAndGltZScsIGNoZWNrLm1lc3NhZ2UsIHJlZnMpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdkdXJhdGlvbic6XG4gICAgICAgICAgYWRkRm9ybWF0KHJlcywgJ2R1cmF0aW9uJywgY2hlY2subWVzc2FnZSwgcmVmcyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2xlbmd0aCc6XG4gICAgICAgICAgcmVzLm1pbkxlbmd0aCA9XG4gICAgICAgICAgICB0eXBlb2YgcmVzLm1pbkxlbmd0aCA9PT0gJ251bWJlcidcbiAgICAgICAgICAgICAgPyBNYXRoLm1heChyZXMubWluTGVuZ3RoLCBjaGVjay52YWx1ZSlcbiAgICAgICAgICAgICAgOiBjaGVjay52YWx1ZTtcbiAgICAgICAgICByZXMubWF4TGVuZ3RoID1cbiAgICAgICAgICAgIHR5cGVvZiByZXMubWF4TGVuZ3RoID09PSAnbnVtYmVyJ1xuICAgICAgICAgICAgICA/IE1hdGgubWluKHJlcy5tYXhMZW5ndGgsIGNoZWNrLnZhbHVlKVxuICAgICAgICAgICAgICA6IGNoZWNrLnZhbHVlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdpbmNsdWRlcyc6IHtcbiAgICAgICAgICBhZGRQYXR0ZXJuKFxuICAgICAgICAgICAgcmVzLFxuICAgICAgICAgICAgUmVnRXhwKGVzY2FwZUxpdGVyYWxDaGVja1ZhbHVlKGNoZWNrLnZhbHVlLCByZWZzKSksXG4gICAgICAgICAgICBjaGVjay5tZXNzYWdlLFxuICAgICAgICAgICAgcmVmcyxcbiAgICAgICAgICApO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgJ2lwJzoge1xuICAgICAgICAgIGlmIChjaGVjay52ZXJzaW9uICE9PSAndjYnKSB7XG4gICAgICAgICAgICBhZGRGb3JtYXQocmVzLCAnaXB2NCcsIGNoZWNrLm1lc3NhZ2UsIHJlZnMpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoY2hlY2sudmVyc2lvbiAhPT0gJ3Y0Jykge1xuICAgICAgICAgICAgYWRkRm9ybWF0KHJlcywgJ2lwdjYnLCBjaGVjay5tZXNzYWdlLCByZWZzKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAnYmFzZTY0dXJsJzpcbiAgICAgICAgICBhZGRQYXR0ZXJuKHJlcywgem9kUGF0dGVybnMuYmFzZTY0dXJsLCBjaGVjay5tZXNzYWdlLCByZWZzKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnand0JzpcbiAgICAgICAgICBhZGRQYXR0ZXJuKHJlcywgem9kUGF0dGVybnMuand0LCBjaGVjay5tZXNzYWdlLCByZWZzKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnY2lkcic6IHtcbiAgICAgICAgICBpZiAoY2hlY2sudmVyc2lvbiAhPT0gJ3Y2Jykge1xuICAgICAgICAgICAgYWRkUGF0dGVybihyZXMsIHpvZFBhdHRlcm5zLmlwdjRDaWRyLCBjaGVjay5tZXNzYWdlLCByZWZzKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGNoZWNrLnZlcnNpb24gIT09ICd2NCcpIHtcbiAgICAgICAgICAgIGFkZFBhdHRlcm4ocmVzLCB6b2RQYXR0ZXJucy5pcHY2Q2lkciwgY2hlY2subWVzc2FnZSwgcmVmcyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgJ2Vtb2ppJzpcbiAgICAgICAgICBhZGRQYXR0ZXJuKHJlcywgem9kUGF0dGVybnMuZW1vamkoKSwgY2hlY2subWVzc2FnZSwgcmVmcyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3VsaWQnOiB7XG4gICAgICAgICAgYWRkUGF0dGVybihyZXMsIHpvZFBhdHRlcm5zLnVsaWQsIGNoZWNrLm1lc3NhZ2UsIHJlZnMpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgJ2Jhc2U2NCc6IHtcbiAgICAgICAgICBzd2l0Y2ggKHJlZnMuYmFzZTY0U3RyYXRlZ3kpIHtcbiAgICAgICAgICAgIGNhc2UgJ2Zvcm1hdDpiaW5hcnknOiB7XG4gICAgICAgICAgICAgIGFkZEZvcm1hdChyZXMsICdiaW5hcnknIGFzIGFueSwgY2hlY2subWVzc2FnZSwgcmVmcyk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYXNlICdjb250ZW50RW5jb2Rpbmc6YmFzZTY0Jzoge1xuICAgICAgICAgICAgICByZXMuY29udGVudEVuY29kaW5nID0gJ2Jhc2U2NCc7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYXNlICdwYXR0ZXJuOnpvZCc6IHtcbiAgICAgICAgICAgICAgYWRkUGF0dGVybihyZXMsIHpvZFBhdHRlcm5zLmJhc2U2NCwgY2hlY2subWVzc2FnZSwgcmVmcyk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlICduYW5vaWQnOiB7XG4gICAgICAgICAgYWRkUGF0dGVybihyZXMsIHpvZFBhdHRlcm5zLm5hbm9pZCwgY2hlY2subWVzc2FnZSwgcmVmcyk7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAndG9Mb3dlckNhc2UnOlxuICAgICAgICBjYXNlICd0b1VwcGVyQ2FzZSc6XG4gICAgICAgIGNhc2UgJ3RyaW0nOlxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIC8qIGM4IGlnbm9yZSBuZXh0ICovXG4gICAgICAgICAgKChfOiBuZXZlcikgPT4ge30pKGNoZWNrKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzO1xufVxuXG5mdW5jdGlvbiBlc2NhcGVMaXRlcmFsQ2hlY2tWYWx1ZShsaXRlcmFsOiBzdHJpbmcsIHJlZnM6IFJlZnMpOiBzdHJpbmcge1xuICByZXR1cm4gcmVmcy5wYXR0ZXJuU3RyYXRlZ3kgPT09ICdlc2NhcGUnXG4gICAgPyBlc2NhcGVOb25BbHBoYU51bWVyaWMobGl0ZXJhbClcbiAgICA6IGxpdGVyYWw7XG59XG5cbmNvbnN0IEFMUEhBX05VTUVSSUMgPSBuZXcgU2V0KFxuICAnQUJDREVGR0hJSktMTU5PUFFSU1RVVlhZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ4eXowMTIzNDU2Nzg5Jyxcbik7XG5cbmZ1bmN0aW9uIGVzY2FwZU5vbkFscGhhTnVtZXJpYyhzb3VyY2U6IHN0cmluZykge1xuICBsZXQgcmVzdWx0ID0gJyc7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzb3VyY2UubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoIUFMUEhBX05VTUVSSUMuaGFzKHNvdXJjZVtpXSkpIHtcbiAgICAgIHJlc3VsdCArPSAnXFxcXCc7XG4gICAgfVxuXG4gICAgcmVzdWx0ICs9IHNvdXJjZVtpXTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8vIEFkZHMgYSBcImZvcm1hdFwiIGtleXdvcmQgdG8gdGhlIHNjaGVtYS4gSWYgYSBmb3JtYXQgZXhpc3RzLCBib3RoIGZvcm1hdHMgd2lsbCBiZSBqb2luZWQgaW4gYW4gYWxsT2Ytbm9kZSwgYWxvbmcgd2l0aCBzdWJzZXF1ZW50IG9uZXMuXG5mdW5jdGlvbiBhZGRGb3JtYXQoXG4gIHNjaGVtYTogSnNvblNjaGVtYTdTdHJpbmdUeXBlLFxuICB2YWx1ZTogUmVxdWlyZWQ8SnNvblNjaGVtYTdTdHJpbmdUeXBlPlsnZm9ybWF0J10sXG4gIG1lc3NhZ2U6IHN0cmluZyB8IHVuZGVmaW5lZCxcbiAgcmVmczogUmVmcyxcbikge1xuICBpZiAoc2NoZW1hLmZvcm1hdCB8fCBzY2hlbWEuYW55T2Y/LnNvbWUoeCA9PiB4LmZvcm1hdCkpIHtcbiAgICBpZiAoIXNjaGVtYS5hbnlPZikge1xuICAgICAgc2NoZW1hLmFueU9mID0gW107XG4gICAgfVxuXG4gICAgaWYgKHNjaGVtYS5mb3JtYXQpIHtcbiAgICAgIHNjaGVtYS5hbnlPZiEucHVzaCh7XG4gICAgICAgIGZvcm1hdDogc2NoZW1hLmZvcm1hdCxcbiAgICAgIH0pO1xuICAgICAgZGVsZXRlIHNjaGVtYS5mb3JtYXQ7XG4gICAgfVxuXG4gICAgc2NoZW1hLmFueU9mIS5wdXNoKHtcbiAgICAgIGZvcm1hdDogdmFsdWUsXG4gICAgICAuLi4obWVzc2FnZSAmJlxuICAgICAgICByZWZzLmVycm9yTWVzc2FnZXMgJiYgeyBlcnJvck1lc3NhZ2U6IHsgZm9ybWF0OiBtZXNzYWdlIH0gfSksXG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgc2NoZW1hLmZvcm1hdCA9IHZhbHVlO1xuICB9XG59XG5cbi8vIEFkZHMgYSBcInBhdHRlcm5cIiBrZXl3b3JkIHRvIHRoZSBzY2hlbWEuIElmIGEgcGF0dGVybiBleGlzdHMsIGJvdGggcGF0dGVybnMgd2lsbCBiZSBqb2luZWQgaW4gYW4gYWxsT2Ytbm9kZSwgYWxvbmcgd2l0aCBzdWJzZXF1ZW50IG9uZXMuXG5mdW5jdGlvbiBhZGRQYXR0ZXJuKFxuICBzY2hlbWE6IEpzb25TY2hlbWE3U3RyaW5nVHlwZSxcbiAgcmVnZXg6IFJlZ0V4cCxcbiAgbWVzc2FnZTogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICByZWZzOiBSZWZzLFxuKSB7XG4gIGlmIChzY2hlbWEucGF0dGVybiB8fCBzY2hlbWEuYWxsT2Y/LnNvbWUoeCA9PiB4LnBhdHRlcm4pKSB7XG4gICAgaWYgKCFzY2hlbWEuYWxsT2YpIHtcbiAgICAgIHNjaGVtYS5hbGxPZiA9IFtdO1xuICAgIH1cblxuICAgIGlmIChzY2hlbWEucGF0dGVybikge1xuICAgICAgc2NoZW1hLmFsbE9mIS5wdXNoKHtcbiAgICAgICAgcGF0dGVybjogc2NoZW1hLnBhdHRlcm4sXG4gICAgICB9KTtcbiAgICAgIGRlbGV0ZSBzY2hlbWEucGF0dGVybjtcbiAgICB9XG5cbiAgICBzY2hlbWEuYWxsT2YhLnB1c2goe1xuICAgICAgcGF0dGVybjogc3RyaW5naWZ5UmVnRXhwV2l0aEZsYWdzKHJlZ2V4LCByZWZzKSxcbiAgICAgIC4uLihtZXNzYWdlICYmXG4gICAgICAgIHJlZnMuZXJyb3JNZXNzYWdlcyAmJiB7IGVycm9yTWVzc2FnZTogeyBwYXR0ZXJuOiBtZXNzYWdlIH0gfSksXG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgc2NoZW1hLnBhdHRlcm4gPSBzdHJpbmdpZnlSZWdFeHBXaXRoRmxhZ3MocmVnZXgsIHJlZnMpO1xuICB9XG59XG5cbi8vIE11dGF0ZSB6LnN0cmluZy5yZWdleCgpIGluIGEgYmVzdCBhdHRlbXB0IHRvIGFjY29tbW9kYXRlIGZvciByZWdleCBmbGFncyB3aGVuIGFwcGx5UmVnZXhGbGFncyBpcyB0cnVlXG5mdW5jdGlvbiBzdHJpbmdpZnlSZWdFeHBXaXRoRmxhZ3MocmVnZXg6IFJlZ0V4cCwgcmVmczogUmVmcyk6IHN0cmluZyB7XG4gIGlmICghcmVmcy5hcHBseVJlZ2V4RmxhZ3MgfHwgIXJlZ2V4LmZsYWdzKSB7XG4gICAgcmV0dXJuIHJlZ2V4LnNvdXJjZTtcbiAgfVxuXG4gIC8vIEN1cnJlbnRseSBoYW5kbGVkIGZsYWdzXG4gIGNvbnN0IGZsYWdzID0ge1xuICAgIGk6IHJlZ2V4LmZsYWdzLmluY2x1ZGVzKCdpJyksIC8vIENhc2UtaW5zZW5zaXRpdmVcbiAgICBtOiByZWdleC5mbGFncy5pbmNsdWRlcygnbScpLCAvLyBgXmAgYW5kIGAkYCBtYXRjaGVzIGFkamFjZW50IHRvIG5ld2xpbmUgY2hhcmFjdGVyc1xuICAgIHM6IHJlZ2V4LmZsYWdzLmluY2x1ZGVzKCdzJyksIC8vIGAuYCBtYXRjaGVzIG5ld2xpbmVzXG4gIH07XG5cbiAgLy8gVGhlIGdlbmVyYWwgcHJpbmNpcGxlIGhlcmUgaXMgdG8gc3RlcCB0aHJvdWdoIGVhY2ggY2hhcmFjdGVyLCBvbmUgYXQgYSB0aW1lLCBhcHBseWluZyBtdXRhdGlvbnMgYXMgZmxhZ3MgcmVxdWlyZS4gV2Uga2VlcCB0cmFjayB3aGVuIHRoZSBjdXJyZW50IGNoYXJhY3RlciBpcyBlc2NhcGVkLCBhbmQgd2hlbiBpdCdzIGluc2lkZSBhIGdyb3VwIC9saWtlIFt0aGlzXS8gb3IgKGFsc28pIGEgcmFuZ2UgbGlrZSAvW2Etel0vLiBUaGUgZm9sbG93aW5nIGlzIGZhaXJseSBicml0dGxlIGltcGVyYXRpdmUgY29kZTsgZWRpdCBhdCB5b3VyIHBlcmlsIVxuICBjb25zdCBzb3VyY2UgPSBmbGFncy5pID8gcmVnZXguc291cmNlLnRvTG93ZXJDYXNlKCkgOiByZWdleC5zb3VyY2U7XG4gIGxldCBwYXR0ZXJuID0gJyc7XG4gIGxldCBpc0VzY2FwZWQgPSBmYWxzZTtcbiAgbGV0IGluQ2hhckdyb3VwID0gZmFsc2U7XG4gIGxldCBpbkNoYXJSYW5nZSA9IGZhbHNlO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc291cmNlLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGlzRXNjYXBlZCkge1xuICAgICAgcGF0dGVybiArPSBzb3VyY2VbaV07XG4gICAgICBpc0VzY2FwZWQgPSBmYWxzZTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChmbGFncy5pKSB7XG4gICAgICBpZiAoaW5DaGFyR3JvdXApIHtcbiAgICAgICAgaWYgKHNvdXJjZVtpXS5tYXRjaCgvW2Etel0vKSkge1xuICAgICAgICAgIGlmIChpbkNoYXJSYW5nZSkge1xuICAgICAgICAgICAgcGF0dGVybiArPSBzb3VyY2VbaV07XG4gICAgICAgICAgICBwYXR0ZXJuICs9IGAke3NvdXJjZVtpIC0gMl19LSR7c291cmNlW2ldfWAudG9VcHBlckNhc2UoKTtcbiAgICAgICAgICAgIGluQ2hhclJhbmdlID0gZmFsc2U7XG4gICAgICAgICAgfSBlbHNlIGlmIChzb3VyY2VbaSArIDFdID09PSAnLScgJiYgc291cmNlW2kgKyAyXT8ubWF0Y2goL1thLXpdLykpIHtcbiAgICAgICAgICAgIHBhdHRlcm4gKz0gc291cmNlW2ldO1xuICAgICAgICAgICAgaW5DaGFyUmFuZ2UgPSB0cnVlO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwYXR0ZXJuICs9IGAke3NvdXJjZVtpXX0ke3NvdXJjZVtpXS50b1VwcGVyQ2FzZSgpfWA7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHNvdXJjZVtpXS5tYXRjaCgvW2Etel0vKSkge1xuICAgICAgICBwYXR0ZXJuICs9IGBbJHtzb3VyY2VbaV19JHtzb3VyY2VbaV0udG9VcHBlckNhc2UoKX1dYDtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGZsYWdzLm0pIHtcbiAgICAgIGlmIChzb3VyY2VbaV0gPT09ICdeJykge1xuICAgICAgICBwYXR0ZXJuICs9IGAoXnwoPzw9W1xcclxcbl0pKWA7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfSBlbHNlIGlmIChzb3VyY2VbaV0gPT09ICckJykge1xuICAgICAgICBwYXR0ZXJuICs9IGAoJHwoPz1bXFxyXFxuXSkpYDtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGZsYWdzLnMgJiYgc291cmNlW2ldID09PSAnLicpIHtcbiAgICAgIHBhdHRlcm4gKz0gaW5DaGFyR3JvdXAgPyBgJHtzb3VyY2VbaV19XFxyXFxuYCA6IGBbJHtzb3VyY2VbaV19XFxyXFxuXWA7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBwYXR0ZXJuICs9IHNvdXJjZVtpXTtcbiAgICBpZiAoc291cmNlW2ldID09PSAnXFxcXCcpIHtcbiAgICAgIGlzRXNjYXBlZCA9IHRydWU7XG4gICAgfSBlbHNlIGlmIChpbkNoYXJHcm91cCAmJiBzb3VyY2VbaV0gPT09ICddJykge1xuICAgICAgaW5DaGFyR3JvdXAgPSBmYWxzZTtcbiAgICB9IGVsc2UgaWYgKCFpbkNoYXJHcm91cCAmJiBzb3VyY2VbaV0gPT09ICdbJykge1xuICAgICAgaW5DaGFyR3JvdXAgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHRyeSB7XG4gICAgbmV3IFJlZ0V4cChwYXR0ZXJuKTtcbiAgfSBjYXRjaCB7XG4gICAgY29uc29sZS53YXJuKFxuICAgICAgYENvdWxkIG5vdCBjb252ZXJ0IHJlZ2V4IHBhdHRlcm4gYXQgJHtyZWZzLmN1cnJlbnRQYXRoLmpvaW4oXG4gICAgICAgICcvJyxcbiAgICAgICl9IHRvIGEgZmxhZy1pbmRlcGVuZGVudCBmb3JtISBGYWxsaW5nIGJhY2sgdG8gdGhlIGZsYWctaWdub3JhbnQgc291cmNlYCxcbiAgICApO1xuICAgIHJldHVybiByZWdleC5zb3VyY2U7XG4gIH1cblxuICByZXR1cm4gcGF0dGVybjtcbn1cbiIsICJpbXBvcnQgeyBab2RNYXBEZWYgfSBmcm9tICd6b2QvdjMnO1xuaW1wb3J0IHsgcGFyc2VEZWYgfSBmcm9tICcuLi9wYXJzZS1kZWYnO1xuaW1wb3J0IHsgSnNvblNjaGVtYTdUeXBlIH0gZnJvbSAnLi4vcGFyc2UtdHlwZXMnO1xuaW1wb3J0IHsgUmVmcyB9IGZyb20gJy4uL3JlZnMnO1xuaW1wb3J0IHsgcGFyc2VBbnlEZWYgfSBmcm9tICcuL2FueSc7XG5pbXBvcnQgeyBKc29uU2NoZW1hN1JlY29yZFR5cGUsIHBhcnNlUmVjb3JkRGVmIH0gZnJvbSAnLi9yZWNvcmQnO1xuXG5leHBvcnQgdHlwZSBKc29uU2NoZW1hN01hcFR5cGUgPSB7XG4gIHR5cGU6ICdhcnJheSc7XG4gIG1heEl0ZW1zOiAxMjU7XG4gIGl0ZW1zOiB7XG4gICAgdHlwZTogJ2FycmF5JztcbiAgICBpdGVtczogW0pzb25TY2hlbWE3VHlwZSwgSnNvblNjaGVtYTdUeXBlXTtcbiAgICBtaW5JdGVtczogMjtcbiAgICBtYXhJdGVtczogMjtcbiAgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZU1hcERlZihcbiAgZGVmOiBab2RNYXBEZWYsXG4gIHJlZnM6IFJlZnMsXG4pOiBKc29uU2NoZW1hN01hcFR5cGUgfCBKc29uU2NoZW1hN1JlY29yZFR5cGUge1xuICBpZiAocmVmcy5tYXBTdHJhdGVneSA9PT0gJ3JlY29yZCcpIHtcbiAgICByZXR1cm4gcGFyc2VSZWNvcmREZWYoZGVmLCByZWZzKTtcbiAgfVxuXG4gIGNvbnN0IGtleXMgPVxuICAgIHBhcnNlRGVmKGRlZi5rZXlUeXBlLl9kZWYsIHtcbiAgICAgIC4uLnJlZnMsXG4gICAgICBjdXJyZW50UGF0aDogWy4uLnJlZnMuY3VycmVudFBhdGgsICdpdGVtcycsICdpdGVtcycsICcwJ10sXG4gICAgfSkgfHwgcGFyc2VBbnlEZWYoKTtcbiAgY29uc3QgdmFsdWVzID1cbiAgICBwYXJzZURlZihkZWYudmFsdWVUeXBlLl9kZWYsIHtcbiAgICAgIC4uLnJlZnMsXG4gICAgICBjdXJyZW50UGF0aDogWy4uLnJlZnMuY3VycmVudFBhdGgsICdpdGVtcycsICdpdGVtcycsICcxJ10sXG4gICAgfSkgfHwgcGFyc2VBbnlEZWYoKTtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAnYXJyYXknLFxuICAgIG1heEl0ZW1zOiAxMjUsXG4gICAgaXRlbXM6IHtcbiAgICAgIHR5cGU6ICdhcnJheScsXG4gICAgICBpdGVtczogW2tleXMsIHZhbHVlc10sXG4gICAgICBtaW5JdGVtczogMixcbiAgICAgIG1heEl0ZW1zOiAyLFxuICAgIH0sXG4gIH07XG59XG4iLCAiaW1wb3J0IHsgWm9kTmF0aXZlRW51bURlZiB9IGZyb20gJ3pvZC92Myc7XG5cbmV4cG9ydCB0eXBlIEpzb25TY2hlbWE3TmF0aXZlRW51bVR5cGUgPSB7XG4gIHR5cGU6ICdzdHJpbmcnIHwgJ251bWJlcicgfCBbJ3N0cmluZycsICdudW1iZXInXTtcbiAgZW51bTogKHN0cmluZyB8IG51bWJlcilbXTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZU5hdGl2ZUVudW1EZWYoXG4gIGRlZjogWm9kTmF0aXZlRW51bURlZixcbik6IEpzb25TY2hlbWE3TmF0aXZlRW51bVR5cGUge1xuICBjb25zdCBvYmplY3QgPSBkZWYudmFsdWVzO1xuICBjb25zdCBhY3R1YWxLZXlzID0gT2JqZWN0LmtleXMoZGVmLnZhbHVlcykuZmlsdGVyKChrZXk6IHN0cmluZykgPT4ge1xuICAgIHJldHVybiB0eXBlb2Ygb2JqZWN0W29iamVjdFtrZXldXSAhPT0gJ251bWJlcic7XG4gIH0pO1xuXG4gIGNvbnN0IGFjdHVhbFZhbHVlcyA9IGFjdHVhbEtleXMubWFwKChrZXk6IHN0cmluZykgPT4gb2JqZWN0W2tleV0pO1xuXG4gIGNvbnN0IHBhcnNlZFR5cGVzID0gQXJyYXkuZnJvbShcbiAgICBuZXcgU2V0KGFjdHVhbFZhbHVlcy5tYXAoKHZhbHVlczogc3RyaW5nIHwgbnVtYmVyKSA9PiB0eXBlb2YgdmFsdWVzKSksXG4gICk7XG5cbiAgcmV0dXJuIHtcbiAgICB0eXBlOlxuICAgICAgcGFyc2VkVHlwZXMubGVuZ3RoID09PSAxXG4gICAgICAgID8gcGFyc2VkVHlwZXNbMF0gPT09ICdzdHJpbmcnXG4gICAgICAgICAgPyAnc3RyaW5nJ1xuICAgICAgICAgIDogJ251bWJlcidcbiAgICAgICAgOiBbJ3N0cmluZycsICdudW1iZXInXSxcbiAgICBlbnVtOiBhY3R1YWxWYWx1ZXMsXG4gIH07XG59XG4iLCAiaW1wb3J0IHsgSnNvblNjaGVtYTdBbnlUeXBlLCBwYXJzZUFueURlZiB9IGZyb20gJy4vYW55JztcblxuZXhwb3J0IHR5cGUgSnNvblNjaGVtYTdOZXZlclR5cGUgPSB7XG4gIG5vdDogSnNvblNjaGVtYTdBbnlUeXBlO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlTmV2ZXJEZWYoKTogSnNvblNjaGVtYTdOZXZlclR5cGUgfCB1bmRlZmluZWQge1xuICByZXR1cm4geyBub3Q6IHBhcnNlQW55RGVmKCkgfTtcbn1cbiIsICJleHBvcnQgdHlwZSBKc29uU2NoZW1hN051bGxUeXBlID0ge1xuICB0eXBlOiAnbnVsbCc7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VOdWxsRGVmKCk6IEpzb25TY2hlbWE3TnVsbFR5cGUge1xuICByZXR1cm4ge1xuICAgIHR5cGU6ICdudWxsJyxcbiAgfTtcbn1cbiIsICJpbXBvcnQge1xuICBab2REaXNjcmltaW5hdGVkVW5pb25EZWYsXG4gIFpvZExpdGVyYWxEZWYsXG4gIFpvZFR5cGVBbnksXG4gIFpvZFVuaW9uRGVmLFxufSBmcm9tICd6b2QvdjMnO1xuaW1wb3J0IHsgcGFyc2VEZWYgfSBmcm9tICcuLi9wYXJzZS1kZWYnO1xuaW1wb3J0IHsgSnNvblNjaGVtYTdUeXBlIH0gZnJvbSAnLi4vcGFyc2UtdHlwZXMnO1xuaW1wb3J0IHsgUmVmcyB9IGZyb20gJy4uL3JlZnMnO1xuXG5leHBvcnQgY29uc3QgcHJpbWl0aXZlTWFwcGluZ3MgPSB7XG4gIFpvZFN0cmluZzogJ3N0cmluZycsXG4gIFpvZE51bWJlcjogJ251bWJlcicsXG4gIFpvZEJpZ0ludDogJ2ludGVnZXInLFxuICBab2RCb29sZWFuOiAnYm9vbGVhbicsXG4gIFpvZE51bGw6ICdudWxsJyxcbn0gYXMgY29uc3Q7XG50eXBlIFpvZFByaW1pdGl2ZSA9IGtleW9mIHR5cGVvZiBwcmltaXRpdmVNYXBwaW5ncztcbnR5cGUgSnNvblNjaGVtYTdQcmltaXRpdmUgPVxuICAodHlwZW9mIHByaW1pdGl2ZU1hcHBpbmdzKVtrZXlvZiB0eXBlb2YgcHJpbWl0aXZlTWFwcGluZ3NdO1xuXG5leHBvcnQgdHlwZSBKc29uU2NoZW1hN1VuaW9uVHlwZSA9XG4gIHwgSnNvblNjaGVtYTdQcmltaXRpdmVVbmlvblR5cGVcbiAgfCBKc29uU2NoZW1hN0FueU9mVHlwZTtcblxudHlwZSBKc29uU2NoZW1hN1ByaW1pdGl2ZVVuaW9uVHlwZSA9XG4gIHwge1xuICAgICAgdHlwZTogSnNvblNjaGVtYTdQcmltaXRpdmUgfCBKc29uU2NoZW1hN1ByaW1pdGl2ZVtdO1xuICAgIH1cbiAgfCB7XG4gICAgICB0eXBlOiBKc29uU2NoZW1hN1ByaW1pdGl2ZSB8IEpzb25TY2hlbWE3UHJpbWl0aXZlW107XG4gICAgICBlbnVtOiAoc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50IHwgYm9vbGVhbiB8IG51bGwpW107XG4gICAgfTtcblxudHlwZSBKc29uU2NoZW1hN0FueU9mVHlwZSA9IHtcbiAgYW55T2Y6IEpzb25TY2hlbWE3VHlwZVtdO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlVW5pb25EZWYoXG4gIGRlZjogWm9kVW5pb25EZWYgfCBab2REaXNjcmltaW5hdGVkVW5pb25EZWY8YW55LCBhbnk+LFxuICByZWZzOiBSZWZzLFxuKTogSnNvblNjaGVtYTdQcmltaXRpdmVVbmlvblR5cGUgfCBKc29uU2NoZW1hN0FueU9mVHlwZSB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IG9wdGlvbnM6IHJlYWRvbmx5IFpvZFR5cGVBbnlbXSA9XG4gICAgZGVmLm9wdGlvbnMgaW5zdGFuY2VvZiBNYXAgPyBBcnJheS5mcm9tKGRlZi5vcHRpb25zLnZhbHVlcygpKSA6IGRlZi5vcHRpb25zO1xuXG4gIC8vIFRoaXMgYmxvY2tzIHRyaWVzIHRvIGxvb2sgYWhlYWQgYSBiaXQgdG8gcHJvZHVjZSBuaWNlciBsb29raW5nIHNjaGVtYXMgd2l0aCB0eXBlIGFycmF5IGluc3RlYWQgb2YgYW55T2YuXG4gIGlmIChcbiAgICBvcHRpb25zLmV2ZXJ5KFxuICAgICAgeCA9PlxuICAgICAgICB4Ll9kZWYudHlwZU5hbWUgaW4gcHJpbWl0aXZlTWFwcGluZ3MgJiZcbiAgICAgICAgKCF4Ll9kZWYuY2hlY2tzIHx8ICF4Ll9kZWYuY2hlY2tzLmxlbmd0aCksXG4gICAgKVxuICApIHtcbiAgICAvLyBhbGwgdHlwZXMgaW4gdW5pb24gYXJlIHByaW1pdGl2ZSBhbmQgbGFjayBjaGVja3MsIHNvIG1pZ2h0IGFzIHdlbGwgc3F1YXNoIGludG8ge3R5cGU6IFsuLi5dfVxuXG4gICAgY29uc3QgdHlwZXMgPSBvcHRpb25zLnJlZHVjZSgodHlwZXM6IEpzb25TY2hlbWE3UHJpbWl0aXZlW10sIHgpID0+IHtcbiAgICAgIGNvbnN0IHR5cGUgPSBwcmltaXRpdmVNYXBwaW5nc1t4Ll9kZWYudHlwZU5hbWUgYXMgWm9kUHJpbWl0aXZlXTsgLy9DYW4gYmUgc2FmZWx5IGNhc3RlZCBkdWUgdG8gcm93IDQzXG4gICAgICByZXR1cm4gdHlwZSAmJiAhdHlwZXMuaW5jbHVkZXModHlwZSkgPyBbLi4udHlwZXMsIHR5cGVdIDogdHlwZXM7XG4gICAgfSwgW10pO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IHR5cGVzLmxlbmd0aCA+IDEgPyB0eXBlcyA6IHR5cGVzWzBdLFxuICAgIH07XG4gIH0gZWxzZSBpZiAoXG4gICAgb3B0aW9ucy5ldmVyeSh4ID0+IHguX2RlZi50eXBlTmFtZSA9PT0gJ1pvZExpdGVyYWwnICYmICF4LmRlc2NyaXB0aW9uKVxuICApIHtcbiAgICAvLyBhbGwgb3B0aW9ucyBsaXRlcmFsc1xuXG4gICAgY29uc3QgdHlwZXMgPSBvcHRpb25zLnJlZHVjZShcbiAgICAgIChhY2M6IEpzb25TY2hlbWE3UHJpbWl0aXZlW10sIHg6IHsgX2RlZjogWm9kTGl0ZXJhbERlZiB9KSA9PiB7XG4gICAgICAgIGNvbnN0IHR5cGUgPSB0eXBlb2YgeC5fZGVmLnZhbHVlO1xuICAgICAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgICAgIGNhc2UgJ251bWJlcic6XG4gICAgICAgICAgY2FzZSAnYm9vbGVhbic6XG4gICAgICAgICAgICByZXR1cm4gWy4uLmFjYywgdHlwZV07XG4gICAgICAgICAgY2FzZSAnYmlnaW50JzpcbiAgICAgICAgICAgIHJldHVybiBbLi4uYWNjLCAnaW50ZWdlcicgYXMgY29uc3RdO1xuICAgICAgICAgIGNhc2UgJ29iamVjdCc6XG4gICAgICAgICAgICBpZiAoeC5fZGVmLnZhbHVlID09PSBudWxsKSByZXR1cm4gWy4uLmFjYywgJ251bGwnIGFzIGNvbnN0XTtcbiAgICAgICAgICBjYXNlICdzeW1ib2wnOlxuICAgICAgICAgIGNhc2UgJ3VuZGVmaW5lZCc6XG4gICAgICAgICAgY2FzZSAnZnVuY3Rpb24nOlxuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgW10sXG4gICAgKTtcblxuICAgIGlmICh0eXBlcy5sZW5ndGggPT09IG9wdGlvbnMubGVuZ3RoKSB7XG4gICAgICAvLyBhbGwgdGhlIGxpdGVyYWxzIGFyZSBwcmltaXRpdmUsIGFzIGZhciBhcyBudWxsIGNhbiBiZSBjb25zaWRlcmVkIHByaW1pdGl2ZVxuXG4gICAgICBjb25zdCB1bmlxdWVUeXBlcyA9IHR5cGVzLmZpbHRlcigoeCwgaSwgYSkgPT4gYS5pbmRleE9mKHgpID09PSBpKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6IHVuaXF1ZVR5cGVzLmxlbmd0aCA+IDEgPyB1bmlxdWVUeXBlcyA6IHVuaXF1ZVR5cGVzWzBdLFxuICAgICAgICBlbnVtOiBvcHRpb25zLnJlZHVjZShcbiAgICAgICAgICAoYWNjLCB4KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gYWNjLmluY2x1ZGVzKHguX2RlZi52YWx1ZSkgPyBhY2MgOiBbLi4uYWNjLCB4Ll9kZWYudmFsdWVdO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgW10gYXMgKHN0cmluZyB8IG51bWJlciB8IGJpZ2ludCB8IGJvb2xlYW4gfCBudWxsKVtdLFxuICAgICAgICApLFxuICAgICAgfTtcbiAgICB9XG4gIH0gZWxzZSBpZiAob3B0aW9ucy5ldmVyeSh4ID0+IHguX2RlZi50eXBlTmFtZSA9PT0gJ1pvZEVudW0nKSkge1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIGVudW06IG9wdGlvbnMucmVkdWNlKFxuICAgICAgICAoYWNjOiBzdHJpbmdbXSwgeCkgPT4gW1xuICAgICAgICAgIC4uLmFjYyxcbiAgICAgICAgICAuLi54Ll9kZWYudmFsdWVzLmZpbHRlcigoeDogc3RyaW5nKSA9PiAhYWNjLmluY2x1ZGVzKHgpKSxcbiAgICAgICAgXSxcbiAgICAgICAgW10sXG4gICAgICApLFxuICAgIH07XG4gIH1cblxuICByZXR1cm4gYXNBbnlPZihkZWYsIHJlZnMpO1xufVxuXG5jb25zdCBhc0FueU9mID0gKFxuICBkZWY6IFpvZFVuaW9uRGVmIHwgWm9kRGlzY3JpbWluYXRlZFVuaW9uRGVmPGFueSwgYW55PixcbiAgcmVmczogUmVmcyxcbik6IEpzb25TY2hlbWE3UHJpbWl0aXZlVW5pb25UeXBlIHwgSnNvblNjaGVtYTdBbnlPZlR5cGUgfCB1bmRlZmluZWQgPT4ge1xuICBjb25zdCBhbnlPZiA9IChcbiAgICAoZGVmLm9wdGlvbnMgaW5zdGFuY2VvZiBNYXBcbiAgICAgID8gQXJyYXkuZnJvbShkZWYub3B0aW9ucy52YWx1ZXMoKSlcbiAgICAgIDogZGVmLm9wdGlvbnMpIGFzIGFueVtdXG4gIClcbiAgICAubWFwKCh4LCBpKSA9PlxuICAgICAgcGFyc2VEZWYoeC5fZGVmLCB7XG4gICAgICAgIC4uLnJlZnMsXG4gICAgICAgIGN1cnJlbnRQYXRoOiBbLi4ucmVmcy5jdXJyZW50UGF0aCwgJ2FueU9mJywgYCR7aX1gXSxcbiAgICAgIH0pLFxuICAgIClcbiAgICAuZmlsdGVyKFxuICAgICAgKHgpOiB4IGlzIEpzb25TY2hlbWE3VHlwZSA9PlxuICAgICAgICAhIXggJiZcbiAgICAgICAgKCFyZWZzLnN0cmljdFVuaW9ucyB8fFxuICAgICAgICAgICh0eXBlb2YgeCA9PT0gJ29iamVjdCcgJiYgT2JqZWN0LmtleXMoeCkubGVuZ3RoID4gMCkpLFxuICAgICk7XG5cbiAgcmV0dXJuIGFueU9mLmxlbmd0aCA/IHsgYW55T2YgfSA6IHVuZGVmaW5lZDtcbn07XG4iLCAiaW1wb3J0IHsgWm9kTnVsbGFibGVEZWYgfSBmcm9tICd6b2QvdjMnO1xuaW1wb3J0IHsgcGFyc2VEZWYgfSBmcm9tICcuLi9wYXJzZS1kZWYnO1xuaW1wb3J0IHsgSnNvblNjaGVtYTdUeXBlIH0gZnJvbSAnLi4vcGFyc2UtdHlwZXMnO1xuaW1wb3J0IHsgUmVmcyB9IGZyb20gJy4uL3JlZnMnO1xuaW1wb3J0IHsgSnNvblNjaGVtYTdOdWxsVHlwZSB9IGZyb20gJy4vbnVsbCc7XG5pbXBvcnQgeyBwcmltaXRpdmVNYXBwaW5ncyB9IGZyb20gJy4vdW5pb24nO1xuXG5leHBvcnQgdHlwZSBKc29uU2NoZW1hN051bGxhYmxlVHlwZSA9XG4gIHwge1xuICAgICAgYW55T2Y6IFtKc29uU2NoZW1hN1R5cGUsIEpzb25TY2hlbWE3TnVsbFR5cGVdO1xuICAgIH1cbiAgfCB7XG4gICAgICB0eXBlOiBbc3RyaW5nLCAnbnVsbCddO1xuICAgIH07XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZU51bGxhYmxlRGVmKFxuICBkZWY6IFpvZE51bGxhYmxlRGVmLFxuICByZWZzOiBSZWZzLFxuKTogSnNvblNjaGVtYTdOdWxsYWJsZVR5cGUgfCB1bmRlZmluZWQge1xuICBpZiAoXG4gICAgWydab2RTdHJpbmcnLCAnWm9kTnVtYmVyJywgJ1pvZEJpZ0ludCcsICdab2RCb29sZWFuJywgJ1pvZE51bGwnXS5pbmNsdWRlcyhcbiAgICAgIGRlZi5pbm5lclR5cGUuX2RlZi50eXBlTmFtZSxcbiAgICApICYmXG4gICAgKCFkZWYuaW5uZXJUeXBlLl9kZWYuY2hlY2tzIHx8ICFkZWYuaW5uZXJUeXBlLl9kZWYuY2hlY2tzLmxlbmd0aClcbiAgKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IFtcbiAgICAgICAgcHJpbWl0aXZlTWFwcGluZ3NbXG4gICAgICAgICAgZGVmLmlubmVyVHlwZS5fZGVmLnR5cGVOYW1lIGFzIGtleW9mIHR5cGVvZiBwcmltaXRpdmVNYXBwaW5nc1xuICAgICAgICBdLFxuICAgICAgICAnbnVsbCcsXG4gICAgICBdLFxuICAgIH07XG4gIH1cblxuICBjb25zdCBiYXNlID0gcGFyc2VEZWYoZGVmLmlubmVyVHlwZS5fZGVmLCB7XG4gICAgLi4ucmVmcyxcbiAgICBjdXJyZW50UGF0aDogWy4uLnJlZnMuY3VycmVudFBhdGgsICdhbnlPZicsICcwJ10sXG4gIH0pO1xuXG4gIHJldHVybiBiYXNlICYmIHsgYW55T2Y6IFtiYXNlLCB7IHR5cGU6ICdudWxsJyB9XSB9O1xufVxuIiwgImltcG9ydCB7IFpvZE51bWJlckRlZiB9IGZyb20gJ3pvZC92Myc7XG5cbmV4cG9ydCB0eXBlIEpzb25TY2hlbWE3TnVtYmVyVHlwZSA9IHtcbiAgdHlwZTogJ251bWJlcicgfCAnaW50ZWdlcic7XG4gIG1pbmltdW0/OiBudW1iZXI7XG4gIGV4Y2x1c2l2ZU1pbmltdW0/OiBudW1iZXI7XG4gIG1heGltdW0/OiBudW1iZXI7XG4gIGV4Y2x1c2l2ZU1heGltdW0/OiBudW1iZXI7XG4gIG11bHRpcGxlT2Y/OiBudW1iZXI7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VOdW1iZXJEZWYoZGVmOiBab2ROdW1iZXJEZWYpOiBKc29uU2NoZW1hN051bWJlclR5cGUge1xuICBjb25zdCByZXM6IEpzb25TY2hlbWE3TnVtYmVyVHlwZSA9IHtcbiAgICB0eXBlOiAnbnVtYmVyJyxcbiAgfTtcblxuICBpZiAoIWRlZi5jaGVja3MpIHJldHVybiByZXM7XG5cbiAgZm9yIChjb25zdCBjaGVjayBvZiBkZWYuY2hlY2tzKSB7XG4gICAgc3dpdGNoIChjaGVjay5raW5kKSB7XG4gICAgICBjYXNlICdpbnQnOlxuICAgICAgICByZXMudHlwZSA9ICdpbnRlZ2VyJztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdtaW4nOlxuICAgICAgICBpZiAoY2hlY2suaW5jbHVzaXZlKSB7XG4gICAgICAgICAgcmVzLm1pbmltdW0gPSBjaGVjay52YWx1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXMuZXhjbHVzaXZlTWluaW11bSA9IGNoZWNrLnZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbWF4JzpcbiAgICAgICAgaWYgKGNoZWNrLmluY2x1c2l2ZSkge1xuICAgICAgICAgIHJlcy5tYXhpbXVtID0gY2hlY2sudmFsdWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzLmV4Y2x1c2l2ZU1heGltdW0gPSBjaGVjay52YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ211bHRpcGxlT2YnOlxuICAgICAgICByZXMubXVsdGlwbGVPZiA9IGNoZWNrLnZhbHVlO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cbiIsICJpbXBvcnQgeyBab2RPYmplY3REZWYsIFpvZFR5cGVBbnkgfSBmcm9tICd6b2QvdjMnO1xuaW1wb3J0IHsgcGFyc2VEZWYgfSBmcm9tICcuLi9wYXJzZS1kZWYnO1xuaW1wb3J0IHsgSnNvblNjaGVtYTdUeXBlIH0gZnJvbSAnLi4vcGFyc2UtdHlwZXMnO1xuaW1wb3J0IHsgUmVmcyB9IGZyb20gJy4uL3JlZnMnO1xuXG5leHBvcnQgdHlwZSBKc29uU2NoZW1hN09iamVjdFR5cGUgPSB7XG4gIHR5cGU6ICdvYmplY3QnO1xuICBwcm9wZXJ0aWVzOiBSZWNvcmQ8c3RyaW5nLCBKc29uU2NoZW1hN1R5cGU+O1xuICBhZGRpdGlvbmFsUHJvcGVydGllcz86IGJvb2xlYW4gfCBKc29uU2NoZW1hN1R5cGU7XG4gIHJlcXVpcmVkPzogc3RyaW5nW107XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VPYmplY3REZWYoZGVmOiBab2RPYmplY3REZWYsIHJlZnM6IFJlZnMpIHtcbiAgY29uc3QgcmVzdWx0OiBKc29uU2NoZW1hN09iamVjdFR5cGUgPSB7XG4gICAgdHlwZTogJ29iamVjdCcsXG4gICAgcHJvcGVydGllczoge30sXG4gIH07XG5cbiAgY29uc3QgcmVxdWlyZWQ6IHN0cmluZ1tdID0gW107XG5cbiAgY29uc3Qgc2hhcGUgPSBkZWYuc2hhcGUoKTtcblxuICBmb3IgKGNvbnN0IHByb3BOYW1lIGluIHNoYXBlKSB7XG4gICAgbGV0IHByb3BEZWYgPSBzaGFwZVtwcm9wTmFtZV07XG5cbiAgICBpZiAocHJvcERlZiA9PT0gdW5kZWZpbmVkIHx8IHByb3BEZWYuX2RlZiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBwcm9wT3B0aW9uYWwgPSBzYWZlSXNPcHRpb25hbChwcm9wRGVmKTtcblxuICAgIGNvbnN0IHBhcnNlZERlZiA9IHBhcnNlRGVmKHByb3BEZWYuX2RlZiwge1xuICAgICAgLi4ucmVmcyxcbiAgICAgIGN1cnJlbnRQYXRoOiBbLi4ucmVmcy5jdXJyZW50UGF0aCwgJ3Byb3BlcnRpZXMnLCBwcm9wTmFtZV0sXG4gICAgICBwcm9wZXJ0eVBhdGg6IFsuLi5yZWZzLmN1cnJlbnRQYXRoLCAncHJvcGVydGllcycsIHByb3BOYW1lXSxcbiAgICB9KTtcblxuICAgIGlmIChwYXJzZWREZWYgPT09IHVuZGVmaW5lZCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgcmVzdWx0LnByb3BlcnRpZXNbcHJvcE5hbWVdID0gcGFyc2VkRGVmO1xuXG4gICAgaWYgKCFwcm9wT3B0aW9uYWwpIHtcbiAgICAgIHJlcXVpcmVkLnB1c2gocHJvcE5hbWUpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChyZXF1aXJlZC5sZW5ndGgpIHtcbiAgICByZXN1bHQucmVxdWlyZWQgPSByZXF1aXJlZDtcbiAgfVxuXG4gIGNvbnN0IGFkZGl0aW9uYWxQcm9wZXJ0aWVzID0gZGVjaWRlQWRkaXRpb25hbFByb3BlcnRpZXMoZGVmLCByZWZzKTtcblxuICBpZiAoYWRkaXRpb25hbFByb3BlcnRpZXMgIT09IHVuZGVmaW5lZCkge1xuICAgIHJlc3VsdC5hZGRpdGlvbmFsUHJvcGVydGllcyA9IGFkZGl0aW9uYWxQcm9wZXJ0aWVzO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gZGVjaWRlQWRkaXRpb25hbFByb3BlcnRpZXMoZGVmOiBab2RPYmplY3REZWYsIHJlZnM6IFJlZnMpIHtcbiAgaWYgKGRlZi5jYXRjaGFsbC5fZGVmLnR5cGVOYW1lICE9PSAnWm9kTmV2ZXInKSB7XG4gICAgcmV0dXJuIHBhcnNlRGVmKGRlZi5jYXRjaGFsbC5fZGVmLCB7XG4gICAgICAuLi5yZWZzLFxuICAgICAgY3VycmVudFBhdGg6IFsuLi5yZWZzLmN1cnJlbnRQYXRoLCAnYWRkaXRpb25hbFByb3BlcnRpZXMnXSxcbiAgICB9KTtcbiAgfVxuXG4gIHN3aXRjaCAoZGVmLnVua25vd25LZXlzKSB7XG4gICAgY2FzZSAncGFzc3Rocm91Z2gnOlxuICAgICAgcmV0dXJuIHJlZnMuYWxsb3dlZEFkZGl0aW9uYWxQcm9wZXJ0aWVzO1xuICAgIGNhc2UgJ3N0cmljdCc6XG4gICAgICByZXR1cm4gcmVmcy5yZWplY3RlZEFkZGl0aW9uYWxQcm9wZXJ0aWVzO1xuICAgIGNhc2UgJ3N0cmlwJzpcbiAgICAgIHJldHVybiByZWZzLnJlbW92ZUFkZGl0aW9uYWxTdHJhdGVneSA9PT0gJ3N0cmljdCdcbiAgICAgICAgPyByZWZzLmFsbG93ZWRBZGRpdGlvbmFsUHJvcGVydGllc1xuICAgICAgICA6IHJlZnMucmVqZWN0ZWRBZGRpdGlvbmFsUHJvcGVydGllcztcbiAgfVxufVxuXG5mdW5jdGlvbiBzYWZlSXNPcHRpb25hbChzY2hlbWE6IFpvZFR5cGVBbnkpOiBib29sZWFuIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gc2NoZW1hLmlzT3B0aW9uYWwoKTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBab2RPcHRpb25hbERlZiB9IGZyb20gJ3pvZC92Myc7XG5pbXBvcnQgeyBwYXJzZURlZiB9IGZyb20gJy4uL3BhcnNlLWRlZic7XG5pbXBvcnQgeyBKc29uU2NoZW1hN1R5cGUgfSBmcm9tICcuLi9wYXJzZS10eXBlcyc7XG5pbXBvcnQgeyBSZWZzIH0gZnJvbSAnLi4vcmVmcyc7XG5pbXBvcnQgeyBwYXJzZUFueURlZiB9IGZyb20gJy4vYW55JztcblxuZXhwb3J0IGNvbnN0IHBhcnNlT3B0aW9uYWxEZWYgPSAoXG4gIGRlZjogWm9kT3B0aW9uYWxEZWYsXG4gIHJlZnM6IFJlZnMsXG4pOiBKc29uU2NoZW1hN1R5cGUgfCB1bmRlZmluZWQgPT4ge1xuICBpZiAocmVmcy5jdXJyZW50UGF0aC50b1N0cmluZygpID09PSByZWZzLnByb3BlcnR5UGF0aD8udG9TdHJpbmcoKSkge1xuICAgIHJldHVybiBwYXJzZURlZihkZWYuaW5uZXJUeXBlLl9kZWYsIHJlZnMpO1xuICB9XG5cbiAgY29uc3QgaW5uZXJTY2hlbWEgPSBwYXJzZURlZihkZWYuaW5uZXJUeXBlLl9kZWYsIHtcbiAgICAuLi5yZWZzLFxuICAgIGN1cnJlbnRQYXRoOiBbLi4ucmVmcy5jdXJyZW50UGF0aCwgJ2FueU9mJywgJzEnXSxcbiAgfSk7XG5cbiAgcmV0dXJuIGlubmVyU2NoZW1hXG4gICAgPyB7IGFueU9mOiBbeyBub3Q6IHBhcnNlQW55RGVmKCkgfSwgaW5uZXJTY2hlbWFdIH1cbiAgICA6IHBhcnNlQW55RGVmKCk7XG59O1xuIiwgImltcG9ydCB7IFpvZFBpcGVsaW5lRGVmIH0gZnJvbSAnem9kL3YzJztcbmltcG9ydCB7IHBhcnNlRGVmIH0gZnJvbSAnLi4vcGFyc2UtZGVmJztcbmltcG9ydCB7IEpzb25TY2hlbWE3VHlwZSB9IGZyb20gJy4uL3BhcnNlLXR5cGVzJztcbmltcG9ydCB7IFJlZnMgfSBmcm9tICcuLi9yZWZzJztcbmltcG9ydCB7IEpzb25TY2hlbWE3QWxsT2ZUeXBlIH0gZnJvbSAnLi9pbnRlcnNlY3Rpb24nO1xuXG5leHBvcnQgY29uc3QgcGFyc2VQaXBlbGluZURlZiA9IChcbiAgZGVmOiBab2RQaXBlbGluZURlZjxhbnksIGFueT4sXG4gIHJlZnM6IFJlZnMsXG4pOiBKc29uU2NoZW1hN0FsbE9mVHlwZSB8IEpzb25TY2hlbWE3VHlwZSB8IHVuZGVmaW5lZCA9PiB7XG4gIGlmIChyZWZzLnBpcGVTdHJhdGVneSA9PT0gJ2lucHV0Jykge1xuICAgIHJldHVybiBwYXJzZURlZihkZWYuaW4uX2RlZiwgcmVmcyk7XG4gIH0gZWxzZSBpZiAocmVmcy5waXBlU3RyYXRlZ3kgPT09ICdvdXRwdXQnKSB7XG4gICAgcmV0dXJuIHBhcnNlRGVmKGRlZi5vdXQuX2RlZiwgcmVmcyk7XG4gIH1cblxuICBjb25zdCBhID0gcGFyc2VEZWYoZGVmLmluLl9kZWYsIHtcbiAgICAuLi5yZWZzLFxuICAgIGN1cnJlbnRQYXRoOiBbLi4ucmVmcy5jdXJyZW50UGF0aCwgJ2FsbE9mJywgJzAnXSxcbiAgfSk7XG4gIGNvbnN0IGIgPSBwYXJzZURlZihkZWYub3V0Ll9kZWYsIHtcbiAgICAuLi5yZWZzLFxuICAgIGN1cnJlbnRQYXRoOiBbLi4ucmVmcy5jdXJyZW50UGF0aCwgJ2FsbE9mJywgYSA/ICcxJyA6ICcwJ10sXG4gIH0pO1xuXG4gIHJldHVybiB7XG4gICAgYWxsT2Y6IFthLCBiXS5maWx0ZXIoKHgpOiB4IGlzIEpzb25TY2hlbWE3VHlwZSA9PiB4ICE9PSB1bmRlZmluZWQpLFxuICB9O1xufTtcbiIsICJpbXBvcnQgeyBab2RQcm9taXNlRGVmIH0gZnJvbSAnem9kL3YzJztcbmltcG9ydCB7IHBhcnNlRGVmIH0gZnJvbSAnLi4vcGFyc2UtZGVmJztcbmltcG9ydCB7IEpzb25TY2hlbWE3VHlwZSB9IGZyb20gJy4uL3BhcnNlLXR5cGVzJztcbmltcG9ydCB7IFJlZnMgfSBmcm9tICcuLi9yZWZzJztcblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlUHJvbWlzZURlZihcbiAgZGVmOiBab2RQcm9taXNlRGVmLFxuICByZWZzOiBSZWZzLFxuKTogSnNvblNjaGVtYTdUeXBlIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIHBhcnNlRGVmKGRlZi50eXBlLl9kZWYsIHJlZnMpO1xufVxuIiwgImltcG9ydCB7IFpvZFNldERlZiB9IGZyb20gJ3pvZC92Myc7XG5pbXBvcnQgeyBwYXJzZURlZiB9IGZyb20gJy4uL3BhcnNlLWRlZic7XG5pbXBvcnQgeyBKc29uU2NoZW1hN1R5cGUgfSBmcm9tICcuLi9wYXJzZS10eXBlcyc7XG5pbXBvcnQgeyBSZWZzIH0gZnJvbSAnLi4vcmVmcyc7XG5cbmV4cG9ydCB0eXBlIEpzb25TY2hlbWE3U2V0VHlwZSA9IHtcbiAgdHlwZTogJ2FycmF5JztcbiAgdW5pcXVlSXRlbXM6IHRydWU7XG4gIGl0ZW1zPzogSnNvblNjaGVtYTdUeXBlO1xuICBtaW5JdGVtcz86IG51bWJlcjtcbiAgbWF4SXRlbXM/OiBudW1iZXI7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VTZXREZWYoZGVmOiBab2RTZXREZWYsIHJlZnM6IFJlZnMpOiBKc29uU2NoZW1hN1NldFR5cGUge1xuICBjb25zdCBpdGVtcyA9IHBhcnNlRGVmKGRlZi52YWx1ZVR5cGUuX2RlZiwge1xuICAgIC4uLnJlZnMsXG4gICAgY3VycmVudFBhdGg6IFsuLi5yZWZzLmN1cnJlbnRQYXRoLCAnaXRlbXMnXSxcbiAgfSk7XG5cbiAgY29uc3Qgc2NoZW1hOiBKc29uU2NoZW1hN1NldFR5cGUgPSB7XG4gICAgdHlwZTogJ2FycmF5JyxcbiAgICB1bmlxdWVJdGVtczogdHJ1ZSxcbiAgICBpdGVtcyxcbiAgfTtcblxuICBpZiAoZGVmLm1pblNpemUpIHtcbiAgICBzY2hlbWEubWluSXRlbXMgPSBkZWYubWluU2l6ZS52YWx1ZTtcbiAgfVxuXG4gIGlmIChkZWYubWF4U2l6ZSkge1xuICAgIHNjaGVtYS5tYXhJdGVtcyA9IGRlZi5tYXhTaXplLnZhbHVlO1xuICB9XG5cbiAgcmV0dXJuIHNjaGVtYTtcbn1cbiIsICJpbXBvcnQgeyBab2RUdXBsZURlZiwgWm9kVHVwbGVJdGVtcywgWm9kVHlwZUFueSB9IGZyb20gJ3pvZC92Myc7XG5pbXBvcnQgeyBwYXJzZURlZiB9IGZyb20gJy4uL3BhcnNlLWRlZic7XG5pbXBvcnQgeyBKc29uU2NoZW1hN1R5cGUgfSBmcm9tICcuLi9wYXJzZS10eXBlcyc7XG5pbXBvcnQgeyBSZWZzIH0gZnJvbSAnLi4vcmVmcyc7XG5cbmV4cG9ydCB0eXBlIEpzb25TY2hlbWE3VHVwbGVUeXBlID0ge1xuICB0eXBlOiAnYXJyYXknO1xuICBtaW5JdGVtczogbnVtYmVyO1xuICBpdGVtczogSnNvblNjaGVtYTdUeXBlW107XG59ICYgKFxuICB8IHtcbiAgICAgIG1heEl0ZW1zOiBudW1iZXI7XG4gICAgfVxuICB8IHtcbiAgICAgIGFkZGl0aW9uYWxJdGVtcz86IEpzb25TY2hlbWE3VHlwZTtcbiAgICB9XG4pO1xuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VUdXBsZURlZihcbiAgZGVmOiBab2RUdXBsZURlZjxab2RUdXBsZUl0ZW1zIHwgW10sIFpvZFR5cGVBbnkgfCBudWxsPixcbiAgcmVmczogUmVmcyxcbik6IEpzb25TY2hlbWE3VHVwbGVUeXBlIHtcbiAgaWYgKGRlZi5yZXN0KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdhcnJheScsXG4gICAgICBtaW5JdGVtczogZGVmLml0ZW1zLmxlbmd0aCxcbiAgICAgIGl0ZW1zOiBkZWYuaXRlbXNcbiAgICAgICAgLm1hcCgoeCwgaSkgPT5cbiAgICAgICAgICBwYXJzZURlZih4Ll9kZWYsIHtcbiAgICAgICAgICAgIC4uLnJlZnMsXG4gICAgICAgICAgICBjdXJyZW50UGF0aDogWy4uLnJlZnMuY3VycmVudFBhdGgsICdpdGVtcycsIGAke2l9YF0sXG4gICAgICAgICAgfSksXG4gICAgICAgIClcbiAgICAgICAgLnJlZHVjZShcbiAgICAgICAgICAoYWNjOiBKc29uU2NoZW1hN1R5cGVbXSwgeCkgPT4gKHggPT09IHVuZGVmaW5lZCA/IGFjYyA6IFsuLi5hY2MsIHhdKSxcbiAgICAgICAgICBbXSxcbiAgICAgICAgKSxcbiAgICAgIGFkZGl0aW9uYWxJdGVtczogcGFyc2VEZWYoZGVmLnJlc3QuX2RlZiwge1xuICAgICAgICAuLi5yZWZzLFxuICAgICAgICBjdXJyZW50UGF0aDogWy4uLnJlZnMuY3VycmVudFBhdGgsICdhZGRpdGlvbmFsSXRlbXMnXSxcbiAgICAgIH0pLFxuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdhcnJheScsXG4gICAgICBtaW5JdGVtczogZGVmLml0ZW1zLmxlbmd0aCxcbiAgICAgIG1heEl0ZW1zOiBkZWYuaXRlbXMubGVuZ3RoLFxuICAgICAgaXRlbXM6IGRlZi5pdGVtc1xuICAgICAgICAubWFwKCh4LCBpKSA9PlxuICAgICAgICAgIHBhcnNlRGVmKHguX2RlZiwge1xuICAgICAgICAgICAgLi4ucmVmcyxcbiAgICAgICAgICAgIGN1cnJlbnRQYXRoOiBbLi4ucmVmcy5jdXJyZW50UGF0aCwgJ2l0ZW1zJywgYCR7aX1gXSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKVxuICAgICAgICAucmVkdWNlKFxuICAgICAgICAgIChhY2M6IEpzb25TY2hlbWE3VHlwZVtdLCB4KSA9PiAoeCA9PT0gdW5kZWZpbmVkID8gYWNjIDogWy4uLmFjYywgeF0pLFxuICAgICAgICAgIFtdLFxuICAgICAgICApLFxuICAgIH07XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBKc29uU2NoZW1hN0FueVR5cGUsIHBhcnNlQW55RGVmIH0gZnJvbSAnLi9hbnknO1xuXG5leHBvcnQgdHlwZSBKc29uU2NoZW1hN1VuZGVmaW5lZFR5cGUgPSB7XG4gIG5vdDogSnNvblNjaGVtYTdBbnlUeXBlO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlVW5kZWZpbmVkRGVmKCk6IEpzb25TY2hlbWE3VW5kZWZpbmVkVHlwZSB7XG4gIHJldHVybiB7XG4gICAgbm90OiBwYXJzZUFueURlZigpLFxuICB9O1xufVxuIiwgImltcG9ydCB7IEpzb25TY2hlbWE3QW55VHlwZSwgcGFyc2VBbnlEZWYgfSBmcm9tICcuL2FueSc7XG5cbmV4cG9ydCB0eXBlIEpzb25TY2hlbWE3VW5rbm93blR5cGUgPSBKc29uU2NoZW1hN0FueVR5cGU7XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVVua25vd25EZWYoKTogSnNvblNjaGVtYTdVbmtub3duVHlwZSB7XG4gIHJldHVybiBwYXJzZUFueURlZigpO1xufVxuIiwgImltcG9ydCB7IFpvZFJlYWRvbmx5RGVmIH0gZnJvbSAnem9kL3YzJztcbmltcG9ydCB7IHBhcnNlRGVmIH0gZnJvbSAnLi4vcGFyc2UtZGVmJztcbmltcG9ydCB7IFJlZnMgfSBmcm9tICcuLi9yZWZzJztcblxuZXhwb3J0IGNvbnN0IHBhcnNlUmVhZG9ubHlEZWYgPSAoZGVmOiBab2RSZWFkb25seURlZjxhbnk+LCByZWZzOiBSZWZzKSA9PiB7XG4gIHJldHVybiBwYXJzZURlZihkZWYuaW5uZXJUeXBlLl9kZWYsIHJlZnMpO1xufTtcbiIsICJpbXBvcnQgeyBab2RUeXBlRGVmIH0gZnJvbSAnem9kL3YzJztcbmltcG9ydCB7IFJlZnMsIFNlZW4gfSBmcm9tICcuL3JlZnMnO1xuaW1wb3J0IHsgaWdub3JlT3ZlcnJpZGUgfSBmcm9tICcuL29wdGlvbnMnO1xuaW1wb3J0IHsgSnNvblNjaGVtYTdUeXBlIH0gZnJvbSAnLi9wYXJzZS10eXBlcyc7XG5pbXBvcnQgeyBzZWxlY3RQYXJzZXIgfSBmcm9tICcuL3NlbGVjdC1wYXJzZXInO1xuaW1wb3J0IHsgZ2V0UmVsYXRpdmVQYXRoIH0gZnJvbSAnLi9nZXQtcmVsYXRpdmUtcGF0aCc7XG5pbXBvcnQgeyBwYXJzZUFueURlZiB9IGZyb20gJy4vcGFyc2Vycy9hbnknO1xuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VEZWYoXG4gIGRlZjogWm9kVHlwZURlZixcbiAgcmVmczogUmVmcyxcbiAgZm9yY2VSZXNvbHV0aW9uID0gZmFsc2UsIC8vIEZvcmNlcyBhIG5ldyBzY2hlbWEgdG8gYmUgaW5zdGFudGlhdGVkIGV2ZW4gdGhvdWdoIGl0cyBkZWYgaGFzIGJlZW4gc2Vlbi4gVXNlZCBmb3IgaW1wcm92aW5nIHJlZnMgaW4gZGVmaW5pdGlvbnMuIFNlZSBodHRwczovL2dpdGh1Yi5jb20vU3RlZmFuVGVyZGVsbC96b2QtdG8tanNvbi1zY2hlbWEvcHVsbC82MS5cbik6IEpzb25TY2hlbWE3VHlwZSB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHNlZW5JdGVtID0gcmVmcy5zZWVuLmdldChkZWYpO1xuXG4gIGlmIChyZWZzLm92ZXJyaWRlKSB7XG4gICAgY29uc3Qgb3ZlcnJpZGVSZXN1bHQgPSByZWZzLm92ZXJyaWRlPy4oXG4gICAgICBkZWYsXG4gICAgICByZWZzLFxuICAgICAgc2Vlbkl0ZW0sXG4gICAgICBmb3JjZVJlc29sdXRpb24sXG4gICAgKTtcblxuICAgIGlmIChvdmVycmlkZVJlc3VsdCAhPT0gaWdub3JlT3ZlcnJpZGUpIHtcbiAgICAgIHJldHVybiBvdmVycmlkZVJlc3VsdDtcbiAgICB9XG4gIH1cblxuICBpZiAoc2Vlbkl0ZW0gJiYgIWZvcmNlUmVzb2x1dGlvbikge1xuICAgIGNvbnN0IHNlZW5TY2hlbWEgPSBnZXQkcmVmKHNlZW5JdGVtLCByZWZzKTtcblxuICAgIGlmIChzZWVuU2NoZW1hICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBzZWVuU2NoZW1hO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IG5ld0l0ZW06IFNlZW4gPSB7IGRlZiwgcGF0aDogcmVmcy5jdXJyZW50UGF0aCwganNvblNjaGVtYTogdW5kZWZpbmVkIH07XG5cbiAgcmVmcy5zZWVuLnNldChkZWYsIG5ld0l0ZW0pO1xuXG4gIGNvbnN0IGpzb25TY2hlbWFPckdldHRlciA9IHNlbGVjdFBhcnNlcihkZWYsIChkZWYgYXMgYW55KS50eXBlTmFtZSwgcmVmcyk7XG5cbiAgLy8gSWYgdGhlIHJldHVybiB3YXMgYSBmdW5jdGlvbiwgdGhlbiB0aGUgaW5uZXIgZGVmaW5pdGlvbiBuZWVkcyB0byBiZSBleHRyYWN0ZWQgYmVmb3JlIGEgY2FsbCB0byBwYXJzZURlZiAocmVjdXJzaXZlKVxuICBjb25zdCBqc29uU2NoZW1hID1cbiAgICB0eXBlb2YganNvblNjaGVtYU9yR2V0dGVyID09PSAnZnVuY3Rpb24nXG4gICAgICA/IHBhcnNlRGVmKGpzb25TY2hlbWFPckdldHRlcigpLCByZWZzKVxuICAgICAgOiBqc29uU2NoZW1hT3JHZXR0ZXI7XG5cbiAgaWYgKGpzb25TY2hlbWEpIHtcbiAgICBhZGRNZXRhKGRlZiwgcmVmcywganNvblNjaGVtYSk7XG4gIH1cblxuICBpZiAocmVmcy5wb3N0UHJvY2Vzcykge1xuICAgIGNvbnN0IHBvc3RQcm9jZXNzUmVzdWx0ID0gcmVmcy5wb3N0UHJvY2Vzcyhqc29uU2NoZW1hLCBkZWYsIHJlZnMpO1xuXG4gICAgbmV3SXRlbS5qc29uU2NoZW1hID0ganNvblNjaGVtYTtcblxuICAgIHJldHVybiBwb3N0UHJvY2Vzc1Jlc3VsdDtcbiAgfVxuXG4gIG5ld0l0ZW0uanNvblNjaGVtYSA9IGpzb25TY2hlbWE7XG5cbiAgcmV0dXJuIGpzb25TY2hlbWE7XG59XG5cbmNvbnN0IGdldCRyZWYgPSAoXG4gIGl0ZW06IFNlZW4sXG4gIHJlZnM6IFJlZnMsXG4pOlxuICB8IHtcbiAgICAgICRyZWY6IHN0cmluZztcbiAgICB9XG4gIHwge31cbiAgfCB1bmRlZmluZWQgPT4ge1xuICBzd2l0Y2ggKHJlZnMuJHJlZlN0cmF0ZWd5KSB7XG4gICAgY2FzZSAncm9vdCc6XG4gICAgICByZXR1cm4geyAkcmVmOiBpdGVtLnBhdGguam9pbignLycpIH07XG4gICAgY2FzZSAncmVsYXRpdmUnOlxuICAgICAgcmV0dXJuIHsgJHJlZjogZ2V0UmVsYXRpdmVQYXRoKHJlZnMuY3VycmVudFBhdGgsIGl0ZW0ucGF0aCkgfTtcbiAgICBjYXNlICdub25lJzpcbiAgICBjYXNlICdzZWVuJzoge1xuICAgICAgaWYgKFxuICAgICAgICBpdGVtLnBhdGgubGVuZ3RoIDwgcmVmcy5jdXJyZW50UGF0aC5sZW5ndGggJiZcbiAgICAgICAgaXRlbS5wYXRoLmV2ZXJ5KCh2YWx1ZSwgaW5kZXgpID0+IHJlZnMuY3VycmVudFBhdGhbaW5kZXhdID09PSB2YWx1ZSlcbiAgICAgICkge1xuICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgYFJlY3Vyc2l2ZSByZWZlcmVuY2UgZGV0ZWN0ZWQgYXQgJHtyZWZzLmN1cnJlbnRQYXRoLmpvaW4oXG4gICAgICAgICAgICAnLycsXG4gICAgICAgICAgKX0hIERlZmF1bHRpbmcgdG8gYW55YCxcbiAgICAgICAgKTtcblxuICAgICAgICByZXR1cm4gcGFyc2VBbnlEZWYoKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlZnMuJHJlZlN0cmF0ZWd5ID09PSAnc2VlbicgPyBwYXJzZUFueURlZigpIDogdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxufTtcblxuY29uc3QgYWRkTWV0YSA9IChcbiAgZGVmOiBab2RUeXBlRGVmLFxuICByZWZzOiBSZWZzLFxuICBqc29uU2NoZW1hOiBKc29uU2NoZW1hN1R5cGUsXG4pOiBKc29uU2NoZW1hN1R5cGUgPT4ge1xuICBpZiAoZGVmLmRlc2NyaXB0aW9uKSB7XG4gICAganNvblNjaGVtYS5kZXNjcmlwdGlvbiA9IGRlZi5kZXNjcmlwdGlvbjtcbiAgfVxuICByZXR1cm4ganNvblNjaGVtYTtcbn07XG4iLCAiaW1wb3J0IHsgWm9kVHlwZURlZiB9IGZyb20gJ3pvZC92Myc7XG5pbXBvcnQgeyBnZXREZWZhdWx0T3B0aW9ucywgT3B0aW9ucyB9IGZyb20gJy4vb3B0aW9ucyc7XG5pbXBvcnQgeyBKc29uU2NoZW1hN1R5cGUgfSBmcm9tICcuL3BhcnNlLXR5cGVzJztcblxuZXhwb3J0IHR5cGUgUmVmcyA9IHtcbiAgc2VlbjogTWFwPFpvZFR5cGVEZWYsIFNlZW4+O1xuICBjdXJyZW50UGF0aDogc3RyaW5nW107XG4gIHByb3BlcnR5UGF0aDogc3RyaW5nW10gfCB1bmRlZmluZWQ7XG59ICYgT3B0aW9ucztcblxuZXhwb3J0IHR5cGUgU2VlbiA9IHtcbiAgZGVmOiBab2RUeXBlRGVmO1xuICBwYXRoOiBzdHJpbmdbXTtcbiAganNvblNjaGVtYTogSnNvblNjaGVtYTdUeXBlIHwgdW5kZWZpbmVkO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldFJlZnMgPSAob3B0aW9ucz86IHN0cmluZyB8IFBhcnRpYWw8T3B0aW9ucz4pOiBSZWZzID0+IHtcbiAgY29uc3QgX29wdGlvbnMgPSBnZXREZWZhdWx0T3B0aW9ucyhvcHRpb25zKTtcbiAgY29uc3QgY3VycmVudFBhdGggPVxuICAgIF9vcHRpb25zLm5hbWUgIT09IHVuZGVmaW5lZFxuICAgICAgPyBbLi4uX29wdGlvbnMuYmFzZVBhdGgsIF9vcHRpb25zLmRlZmluaXRpb25QYXRoLCBfb3B0aW9ucy5uYW1lXVxuICAgICAgOiBfb3B0aW9ucy5iYXNlUGF0aDtcbiAgcmV0dXJuIHtcbiAgICAuLi5fb3B0aW9ucyxcbiAgICBjdXJyZW50UGF0aDogY3VycmVudFBhdGgsXG4gICAgcHJvcGVydHlQYXRoOiB1bmRlZmluZWQsXG4gICAgc2VlbjogbmV3IE1hcChcbiAgICAgIE9iamVjdC5lbnRyaWVzKF9vcHRpb25zLmRlZmluaXRpb25zKS5tYXAoKFtuYW1lLCBkZWZdKSA9PiBbXG4gICAgICAgIGRlZi5fZGVmLFxuICAgICAgICB7XG4gICAgICAgICAgZGVmOiBkZWYuX2RlZixcbiAgICAgICAgICBwYXRoOiBbLi4uX29wdGlvbnMuYmFzZVBhdGgsIF9vcHRpb25zLmRlZmluaXRpb25QYXRoLCBuYW1lXSxcbiAgICAgICAgICAvLyBSZXNvbHV0aW9uIG9mIHJlZmVyZW5jZXMgd2lsbCBiZSBmb3JjZWQgZXZlbiB0aG91Z2ggc2Vlbiwgc28gaXQncyBvayB0aGF0IHRoZSBzY2hlbWEgaXMgdW5kZWZpbmVkIGhlcmUgZm9yIG5vdy5cbiAgICAgICAgICBqc29uU2NoZW1hOiB1bmRlZmluZWQsXG4gICAgICAgIH0sXG4gICAgICBdKSxcbiAgICApLFxuICB9O1xufTtcbiIsICJpbXBvcnQgeyBab2RTY2hlbWEgfSBmcm9tICd6b2QvdjMnO1xuaW1wb3J0IHsgT3B0aW9ucyB9IGZyb20gJy4vb3B0aW9ucyc7XG5pbXBvcnQgeyBwYXJzZURlZiB9IGZyb20gJy4vcGFyc2UtZGVmJztcbmltcG9ydCB7IEpzb25TY2hlbWE3VHlwZSB9IGZyb20gJy4vcGFyc2UtdHlwZXMnO1xuaW1wb3J0IHsgZ2V0UmVmcyB9IGZyb20gJy4vcmVmcyc7XG5pbXBvcnQgeyBwYXJzZUFueURlZiB9IGZyb20gJy4vcGFyc2Vycy9hbnknO1xuXG5jb25zdCB6b2RUb0pzb25TY2hlbWEgPSAoXG4gIHNjaGVtYTogWm9kU2NoZW1hPGFueT4sXG4gIG9wdGlvbnM/OiBQYXJ0aWFsPE9wdGlvbnM+IHwgc3RyaW5nLFxuKTogSnNvblNjaGVtYTdUeXBlICYge1xuICAkc2NoZW1hPzogc3RyaW5nO1xuICBkZWZpbml0aW9ucz86IHtcbiAgICBba2V5OiBzdHJpbmddOiBKc29uU2NoZW1hN1R5cGU7XG4gIH07XG59ID0+IHtcbiAgY29uc3QgcmVmcyA9IGdldFJlZnMob3B0aW9ucyk7XG5cbiAgbGV0IGRlZmluaXRpb25zID1cbiAgICB0eXBlb2Ygb3B0aW9ucyA9PT0gJ29iamVjdCcgJiYgb3B0aW9ucy5kZWZpbml0aW9uc1xuICAgICAgPyBPYmplY3QuZW50cmllcyhvcHRpb25zLmRlZmluaXRpb25zKS5yZWR1Y2UoXG4gICAgICAgICAgKGFjYzogeyBba2V5OiBzdHJpbmddOiBKc29uU2NoZW1hN1R5cGUgfSwgW25hbWUsIHNjaGVtYV0pID0+ICh7XG4gICAgICAgICAgICAuLi5hY2MsXG4gICAgICAgICAgICBbbmFtZV06XG4gICAgICAgICAgICAgIHBhcnNlRGVmKFxuICAgICAgICAgICAgICAgIHNjaGVtYS5fZGVmLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIC4uLnJlZnMsXG4gICAgICAgICAgICAgICAgICBjdXJyZW50UGF0aDogWy4uLnJlZnMuYmFzZVBhdGgsIHJlZnMuZGVmaW5pdGlvblBhdGgsIG5hbWVdLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdHJ1ZSxcbiAgICAgICAgICAgICAgKSA/PyBwYXJzZUFueURlZigpLFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIHt9LFxuICAgICAgICApXG4gICAgICA6IHVuZGVmaW5lZDtcblxuICBjb25zdCBuYW1lID1cbiAgICB0eXBlb2Ygb3B0aW9ucyA9PT0gJ3N0cmluZydcbiAgICAgID8gb3B0aW9uc1xuICAgICAgOiBvcHRpb25zPy5uYW1lU3RyYXRlZ3kgPT09ICd0aXRsZSdcbiAgICAgICAgPyB1bmRlZmluZWRcbiAgICAgICAgOiBvcHRpb25zPy5uYW1lO1xuXG4gIGNvbnN0IG1haW4gPVxuICAgIHBhcnNlRGVmKFxuICAgICAgc2NoZW1hLl9kZWYsXG4gICAgICBuYW1lID09PSB1bmRlZmluZWRcbiAgICAgICAgPyByZWZzXG4gICAgICAgIDoge1xuICAgICAgICAgICAgLi4ucmVmcyxcbiAgICAgICAgICAgIGN1cnJlbnRQYXRoOiBbLi4ucmVmcy5iYXNlUGF0aCwgcmVmcy5kZWZpbml0aW9uUGF0aCwgbmFtZV0sXG4gICAgICAgICAgfSxcbiAgICAgIGZhbHNlLFxuICAgICkgPz8gKHBhcnNlQW55RGVmKCkgYXMgSnNvblNjaGVtYTdUeXBlKTtcblxuICBjb25zdCB0aXRsZSA9XG4gICAgdHlwZW9mIG9wdGlvbnMgPT09ICdvYmplY3QnICYmXG4gICAgb3B0aW9ucy5uYW1lICE9PSB1bmRlZmluZWQgJiZcbiAgICBvcHRpb25zLm5hbWVTdHJhdGVneSA9PT0gJ3RpdGxlJ1xuICAgICAgPyBvcHRpb25zLm5hbWVcbiAgICAgIDogdW5kZWZpbmVkO1xuXG4gIGlmICh0aXRsZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgbWFpbi50aXRsZSA9IHRpdGxlO1xuICB9XG5cbiAgY29uc3QgY29tYmluZWQ6IFJldHVyblR5cGU8dHlwZW9mIHpvZFRvSnNvblNjaGVtYT4gPVxuICAgIG5hbWUgPT09IHVuZGVmaW5lZFxuICAgICAgPyBkZWZpbml0aW9uc1xuICAgICAgICA/IHtcbiAgICAgICAgICAgIC4uLm1haW4sXG4gICAgICAgICAgICBbcmVmcy5kZWZpbml0aW9uUGF0aF06IGRlZmluaXRpb25zLFxuICAgICAgICAgIH1cbiAgICAgICAgOiBtYWluXG4gICAgICA6IHtcbiAgICAgICAgICAkcmVmOiBbXG4gICAgICAgICAgICAuLi4ocmVmcy4kcmVmU3RyYXRlZ3kgPT09ICdyZWxhdGl2ZScgPyBbXSA6IHJlZnMuYmFzZVBhdGgpLFxuICAgICAgICAgICAgcmVmcy5kZWZpbml0aW9uUGF0aCxcbiAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgXS5qb2luKCcvJyksXG4gICAgICAgICAgW3JlZnMuZGVmaW5pdGlvblBhdGhdOiB7XG4gICAgICAgICAgICAuLi5kZWZpbml0aW9ucyxcbiAgICAgICAgICAgIFtuYW1lXTogbWFpbixcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuXG4gIGNvbWJpbmVkLiRzY2hlbWEgPSAnaHR0cDovL2pzb24tc2NoZW1hLm9yZy9kcmFmdC0wNy9zY2hlbWEjJztcblxuICByZXR1cm4gY29tYmluZWQ7XG59O1xuXG5leHBvcnQgeyB6b2RUb0pzb25TY2hlbWEgfTtcbiIsICJleHBvcnQgKiBmcm9tICcuL2dldC1yZWxhdGl2ZS1wYXRoJztcbmV4cG9ydCAqIGZyb20gJy4vb3B0aW9ucyc7XG5leHBvcnQgKiBmcm9tICcuL3BhcnNlLWRlZic7XG5leHBvcnQgKiBmcm9tICcuL3BhcnNlLXR5cGVzJztcbmV4cG9ydCAqIGZyb20gJy4vcGFyc2Vycy9hbnknO1xuZXhwb3J0ICogZnJvbSAnLi9wYXJzZXJzL2FycmF5JztcbmV4cG9ydCAqIGZyb20gJy4vcGFyc2Vycy9iaWdpbnQnO1xuZXhwb3J0ICogZnJvbSAnLi9wYXJzZXJzL2Jvb2xlYW4nO1xuZXhwb3J0ICogZnJvbSAnLi9wYXJzZXJzL2JyYW5kZWQnO1xuZXhwb3J0ICogZnJvbSAnLi9wYXJzZXJzL2NhdGNoJztcbmV4cG9ydCAqIGZyb20gJy4vcGFyc2Vycy9kYXRlJztcbmV4cG9ydCAqIGZyb20gJy4vcGFyc2Vycy9kZWZhdWx0JztcbmV4cG9ydCAqIGZyb20gJy4vcGFyc2Vycy9lZmZlY3RzJztcbmV4cG9ydCAqIGZyb20gJy4vcGFyc2Vycy9lbnVtJztcbmV4cG9ydCAqIGZyb20gJy4vcGFyc2Vycy9pbnRlcnNlY3Rpb24nO1xuZXhwb3J0ICogZnJvbSAnLi9wYXJzZXJzL2xpdGVyYWwnO1xuZXhwb3J0ICogZnJvbSAnLi9wYXJzZXJzL21hcCc7XG5leHBvcnQgKiBmcm9tICcuL3BhcnNlcnMvbmF0aXZlLWVudW0nO1xuZXhwb3J0ICogZnJvbSAnLi9wYXJzZXJzL25ldmVyJztcbmV4cG9ydCAqIGZyb20gJy4vcGFyc2Vycy9udWxsJztcbmV4cG9ydCAqIGZyb20gJy4vcGFyc2Vycy9udWxsYWJsZSc7XG5leHBvcnQgKiBmcm9tICcuL3BhcnNlcnMvbnVtYmVyJztcbmV4cG9ydCAqIGZyb20gJy4vcGFyc2Vycy9vYmplY3QnO1xuZXhwb3J0ICogZnJvbSAnLi9wYXJzZXJzL29wdGlvbmFsJztcbmV4cG9ydCAqIGZyb20gJy4vcGFyc2Vycy9waXBlbGluZSc7XG5leHBvcnQgKiBmcm9tICcuL3BhcnNlcnMvcHJvbWlzZSc7XG5leHBvcnQgKiBmcm9tICcuL3BhcnNlcnMvcmVhZG9ubHknO1xuZXhwb3J0ICogZnJvbSAnLi9wYXJzZXJzL3JlY29yZCc7XG5leHBvcnQgKiBmcm9tICcuL3BhcnNlcnMvc2V0JztcbmV4cG9ydCAqIGZyb20gJy4vcGFyc2Vycy9zdHJpbmcnO1xuZXhwb3J0ICogZnJvbSAnLi9wYXJzZXJzL3R1cGxlJztcbmV4cG9ydCAqIGZyb20gJy4vcGFyc2Vycy91bmRlZmluZWQnO1xuZXhwb3J0ICogZnJvbSAnLi9wYXJzZXJzL3VuaW9uJztcbmV4cG9ydCAqIGZyb20gJy4vcGFyc2Vycy91bmtub3duJztcbmV4cG9ydCAqIGZyb20gJy4vcmVmcyc7XG5leHBvcnQgKiBmcm9tICcuL3NlbGVjdC1wYXJzZXInO1xuZXhwb3J0ICogZnJvbSAnLi96b2QtdG8tanNvbi1zY2hlbWEnO1xuaW1wb3J0IHsgem9kVG9Kc29uU2NoZW1hIH0gZnJvbSAnLi96b2QtdG8tanNvbi1zY2hlbWEnO1xuZXhwb3J0IGRlZmF1bHQgem9kVG9Kc29uU2NoZW1hO1xuIiwgImltcG9ydCB7IEpTT05TY2hlbWE3IH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQgKiBhcyB6MyBmcm9tICd6b2QvdjMnO1xuaW1wb3J0ICogYXMgejQgZnJvbSAnem9kL3Y0JztcbmltcG9ydCB7IFZhbGlkYXRvciwgdmFsaWRhdG9yU3ltYm9sLCB0eXBlIFZhbGlkYXRpb25SZXN1bHQgfSBmcm9tICcuL3ZhbGlkYXRvcic7XG5pbXBvcnQgeyB6b2RTY2hlbWEgfSBmcm9tICcuL3pvZC1zY2hlbWEnO1xuXG4vKipcbiAqIFVzZWQgdG8gbWFyayBzY2hlbWFzIHNvIHdlIGNhbiBzdXBwb3J0IGJvdGggWm9kIGFuZCBjdXN0b20gc2NoZW1hcy5cbiAqL1xuY29uc3Qgc2NoZW1hU3ltYm9sID0gU3ltYm9sLmZvcigndmVyY2VsLmFpLnNjaGVtYScpO1xuXG5leHBvcnQgdHlwZSBTY2hlbWE8T0JKRUNUID0gdW5rbm93bj4gPSBWYWxpZGF0b3I8T0JKRUNUPiAmIHtcbiAgLyoqXG4gICAqIFVzZWQgdG8gbWFyayBzY2hlbWFzIHNvIHdlIGNhbiBzdXBwb3J0IGJvdGggWm9kIGFuZCBjdXN0b20gc2NoZW1hcy5cbiAgICovXG4gIFtzY2hlbWFTeW1ib2xdOiB0cnVlO1xuXG4gIC8qKlxuICAgKiBTY2hlbWEgdHlwZSBmb3IgaW5mZXJlbmNlLlxuICAgKi9cbiAgX3R5cGU6IE9CSkVDVDtcblxuICAvKipcbiAgICogVGhlIEpTT04gU2NoZW1hIGZvciB0aGUgc2NoZW1hLiBJdCBpcyBwYXNzZWQgdG8gdGhlIHByb3ZpZGVycy5cbiAgICovXG4gIHJlYWRvbmx5IGpzb25TY2hlbWE6IEpTT05TY2hlbWE3O1xufTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgc2NoZW1hIHdpdGggZGVmZXJyZWQgY3JlYXRpb24uXG4gKiBUaGlzIGlzIGltcG9ydGFudCB0byByZWR1Y2UgdGhlIHN0YXJ0dXAgdGltZSBvZiB0aGUgbGlicmFyeVxuICogYW5kIHRvIGF2b2lkIGluaXRpYWxpemluZyB1bnVzZWQgdmFsaWRhdG9ycy5cbiAqXG4gKiBAcGFyYW0gY3JlYXRlVmFsaWRhdG9yIEEgZnVuY3Rpb24gdGhhdCBjcmVhdGVzIGEgc2NoZW1hLlxuICogQHJldHVybnMgQSBmdW5jdGlvbiB0aGF0IHJldHVybnMgYSBzY2hlbWEuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsYXp5U2NoZW1hPFNDSEVNQT4oXG4gIGNyZWF0ZVNjaGVtYTogKCkgPT4gU2NoZW1hPFNDSEVNQT4sXG4pOiBMYXp5U2NoZW1hPFNDSEVNQT4ge1xuICAvLyBjYWNoZSB0aGUgdmFsaWRhdG9yIHRvIGF2b2lkIGluaXRpYWxpemluZyBpdCBtdWx0aXBsZSB0aW1lc1xuICBsZXQgc2NoZW1hOiBTY2hlbWE8U0NIRU1BPiB8IHVuZGVmaW5lZDtcbiAgcmV0dXJuICgpID0+IHtcbiAgICBpZiAoc2NoZW1hID09IG51bGwpIHtcbiAgICAgIHNjaGVtYSA9IGNyZWF0ZVNjaGVtYSgpO1xuICAgIH1cbiAgICByZXR1cm4gc2NoZW1hO1xuICB9O1xufVxuXG5leHBvcnQgdHlwZSBMYXp5U2NoZW1hPFNDSEVNQT4gPSAoKSA9PiBTY2hlbWE8U0NIRU1BPjtcblxuLy8gTm90ZTogWm9kIHR5cGVzIGhlcmUgZXhhY3RseSBtYXRjaCB0aGUgdHlwZXMgaW4gem9kLXNjaGVtYS50c1xuLy8gdG8gcHJldmVudCB0eXBlIGVycm9ycyB3aGVuIHVzaW5nIHpvZCBzY2hlbWFzIHdpdGggZmxleGlibGUgc2NoZW1hcy5cbmV4cG9ydCB0eXBlIEZsZXhpYmxlU2NoZW1hPFNDSEVNQT4gPVxuICB8IHo0LmNvcmUuJFpvZFR5cGU8U0NIRU1BLCBhbnk+XG4gIHwgejMuU2NoZW1hPFNDSEVNQSwgejMuWm9kVHlwZURlZiwgYW55PlxuICB8IFNjaGVtYTxTQ0hFTUE+XG4gIHwgTGF6eVNjaGVtYTxTQ0hFTUE+O1xuXG5leHBvcnQgdHlwZSBJbmZlclNjaGVtYTxTQ0hFTUE+ID0gU0NIRU1BIGV4dGVuZHMgejMuU2NoZW1hXG4gID8gejMuaW5mZXI8U0NIRU1BPlxuICA6IFNDSEVNQSBleHRlbmRzIHo0LmNvcmUuJFpvZFR5cGVcbiAgICA/IHo0LmluZmVyPFNDSEVNQT5cbiAgICA6IFNDSEVNQSBleHRlbmRzIExhenlTY2hlbWE8aW5mZXIgVD5cbiAgICAgID8gVFxuICAgICAgOiBTQ0hFTUEgZXh0ZW5kcyBTY2hlbWE8aW5mZXIgVD5cbiAgICAgICAgPyBUXG4gICAgICAgIDogbmV2ZXI7XG5cbi8qKlxuICogQ3JlYXRlIGEgc2NoZW1hIHVzaW5nIGEgSlNPTiBTY2hlbWEuXG4gKlxuICogQHBhcmFtIGpzb25TY2hlbWEgVGhlIEpTT04gU2NoZW1hIGZvciB0aGUgc2NoZW1hLlxuICogQHBhcmFtIG9wdGlvbnMudmFsaWRhdGUgT3B0aW9uYWwuIEEgdmFsaWRhdGlvbiBmdW5jdGlvbiBmb3IgdGhlIHNjaGVtYS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGpzb25TY2hlbWE8T0JKRUNUID0gdW5rbm93bj4oXG4gIGpzb25TY2hlbWE6IEpTT05TY2hlbWE3IHwgKCgpID0+IEpTT05TY2hlbWE3KSxcbiAge1xuICAgIHZhbGlkYXRlLFxuICB9OiB7XG4gICAgdmFsaWRhdGU/OiAoXG4gICAgICB2YWx1ZTogdW5rbm93bixcbiAgICApID0+IFZhbGlkYXRpb25SZXN1bHQ8T0JKRUNUPiB8IFByb21pc2VMaWtlPFZhbGlkYXRpb25SZXN1bHQ8T0JKRUNUPj47XG4gIH0gPSB7fSxcbik6IFNjaGVtYTxPQkpFQ1Q+IHtcbiAgcmV0dXJuIHtcbiAgICBbc2NoZW1hU3ltYm9sXTogdHJ1ZSxcbiAgICBfdHlwZTogdW5kZWZpbmVkIGFzIE9CSkVDVCwgLy8gc2hvdWxkIG5ldmVyIGJlIHVzZWQgZGlyZWN0bHlcbiAgICBbdmFsaWRhdG9yU3ltYm9sXTogdHJ1ZSxcbiAgICBnZXQganNvblNjaGVtYSgpIHtcbiAgICAgIGlmICh0eXBlb2YganNvblNjaGVtYSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBqc29uU2NoZW1hID0ganNvblNjaGVtYSgpOyAvLyBjYWNoZSB0aGUgZnVuY3Rpb24gcmVzdWx0c1xuICAgICAgfVxuICAgICAgcmV0dXJuIGpzb25TY2hlbWE7XG4gICAgfSxcbiAgICB2YWxpZGF0ZSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gaXNTY2hlbWEodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBTY2hlbWEge1xuICByZXR1cm4gKFxuICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiZcbiAgICB2YWx1ZSAhPT0gbnVsbCAmJlxuICAgIHNjaGVtYVN5bWJvbCBpbiB2YWx1ZSAmJlxuICAgIHZhbHVlW3NjaGVtYVN5bWJvbF0gPT09IHRydWUgJiZcbiAgICAnanNvblNjaGVtYScgaW4gdmFsdWUgJiZcbiAgICAndmFsaWRhdGUnIGluIHZhbHVlXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhc1NjaGVtYTxPQkpFQ1Q+KFxuICBzY2hlbWE6IEZsZXhpYmxlU2NoZW1hPE9CSkVDVD4gfCB1bmRlZmluZWQsXG4pOiBTY2hlbWE8T0JKRUNUPiB7XG4gIHJldHVybiBzY2hlbWEgPT0gbnVsbFxuICAgID8ganNvblNjaGVtYSh7XG4gICAgICAgIHByb3BlcnRpZXM6IHt9LFxuICAgICAgICBhZGRpdGlvbmFsUHJvcGVydGllczogZmFsc2UsXG4gICAgICB9KVxuICAgIDogaXNTY2hlbWEoc2NoZW1hKVxuICAgICAgPyBzY2hlbWFcbiAgICAgIDogdHlwZW9mIHNjaGVtYSA9PT0gJ2Z1bmN0aW9uJ1xuICAgICAgICA/IHNjaGVtYSgpXG4gICAgICAgIDogem9kU2NoZW1hKHNjaGVtYSk7XG59XG4iLCAiLy8gYnRvYSBhbmQgYXRvYiBuZWVkIHRvIGJlIGludm9rZWQgYXMgYSBmdW5jdGlvbiBjYWxsLCBub3QgYXMgYSBtZXRob2QgY2FsbC5cbi8vIE90aGVyd2lzZSBDbG91ZEZsYXJlIHdpbGwgdGhyb3cgYVxuLy8gXCJUeXBlRXJyb3I6IElsbGVnYWwgaW52b2NhdGlvbjogZnVuY3Rpb24gY2FsbGVkIHdpdGggaW5jb3JyZWN0IHRoaXMgcmVmZXJlbmNlXCJcbmNvbnN0IHsgYnRvYSwgYXRvYiB9ID0gZ2xvYmFsVGhpcztcblxuZXhwb3J0IGZ1bmN0aW9uIGNvbnZlcnRCYXNlNjRUb1VpbnQ4QXJyYXkoYmFzZTY0U3RyaW5nOiBzdHJpbmcpIHtcbiAgY29uc3QgYmFzZTY0VXJsID0gYmFzZTY0U3RyaW5nLnJlcGxhY2UoLy0vZywgJysnKS5yZXBsYWNlKC9fL2csICcvJyk7XG4gIGNvbnN0IGxhdGluMXN0cmluZyA9IGF0b2IoYmFzZTY0VXJsKTtcbiAgcmV0dXJuIFVpbnQ4QXJyYXkuZnJvbShsYXRpbjFzdHJpbmcsIGJ5dGUgPT4gYnl0ZS5jb2RlUG9pbnRBdCgwKSEpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY29udmVydFVpbnQ4QXJyYXlUb0Jhc2U2NChhcnJheTogVWludDhBcnJheSk6IHN0cmluZyB7XG4gIGxldCBsYXRpbjFzdHJpbmcgPSAnJztcblxuICAvLyBOb3RlOiByZWd1bGFyIGZvciBsb29wIHRvIHN1cHBvcnQgb2xkZXIgSmF2YVNjcmlwdCB2ZXJzaW9ucyB0aGF0XG4gIC8vIGRvIG5vdCBzdXBwb3J0IGZvci4ub2Ygb24gVWludDhBcnJheVxuICBmb3IgKGxldCBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgbGF0aW4xc3RyaW5nICs9IFN0cmluZy5mcm9tQ29kZVBvaW50KGFycmF5W2ldKTtcbiAgfVxuXG4gIHJldHVybiBidG9hKGxhdGluMXN0cmluZyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb252ZXJ0VG9CYXNlNjQodmFsdWU6IHN0cmluZyB8IFVpbnQ4QXJyYXkpOiBzdHJpbmcge1xuICByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBVaW50OEFycmF5ID8gY29udmVydFVpbnQ4QXJyYXlUb0Jhc2U2NCh2YWx1ZSkgOiB2YWx1ZTtcbn1cbiIsICJleHBvcnQgZnVuY3Rpb24gd2l0aG91dFRyYWlsaW5nU2xhc2godXJsOiBzdHJpbmcgfCB1bmRlZmluZWQpIHtcbiAgcmV0dXJuIHVybD8ucmVwbGFjZSgvXFwvJC8sICcnKTtcbn1cbiIsICJleHBvcnQgZnVuY3Rpb24gaXNBc3luY0l0ZXJhYmxlPFQgPSBhbnk+KG9iajogYW55KTogb2JqIGlzIEFzeW5jSXRlcmFibGU8VD4ge1xuICByZXR1cm4gb2JqICE9IG51bGwgJiYgdHlwZW9mIG9ialtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPT09ICdmdW5jdGlvbic7XG59XG4iLCAiaW1wb3J0IHsgVG9vbCwgVG9vbENhbGxPcHRpb25zLCBUb29sRXhlY3V0ZUZ1bmN0aW9uIH0gZnJvbSAnLi90b29sJztcbmltcG9ydCB7IGlzQXN5bmNJdGVyYWJsZSB9IGZyb20gJy4uL2lzLWFzeW5jLWl0ZXJhYmxlJztcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uKiBleGVjdXRlVG9vbDxJTlBVVCwgT1VUUFVUPih7XG4gIGV4ZWN1dGUsXG4gIGlucHV0LFxuICBvcHRpb25zLFxufToge1xuICBleGVjdXRlOiBUb29sRXhlY3V0ZUZ1bmN0aW9uPElOUFVULCBPVVRQVVQ+O1xuICBpbnB1dDogSU5QVVQ7XG4gIG9wdGlvbnM6IFRvb2xDYWxsT3B0aW9ucztcbn0pOiBBc3luY0dlbmVyYXRvcjxcbiAgeyB0eXBlOiAncHJlbGltaW5hcnknOyBvdXRwdXQ6IE9VVFBVVCB9IHwgeyB0eXBlOiAnZmluYWwnOyBvdXRwdXQ6IE9VVFBVVCB9XG4+IHtcbiAgY29uc3QgcmVzdWx0ID0gZXhlY3V0ZShpbnB1dCwgb3B0aW9ucyk7XG5cbiAgaWYgKGlzQXN5bmNJdGVyYWJsZShyZXN1bHQpKSB7XG4gICAgbGV0IGxhc3RPdXRwdXQ6IE9VVFBVVCB8IHVuZGVmaW5lZDtcbiAgICBmb3IgYXdhaXQgKGNvbnN0IG91dHB1dCBvZiByZXN1bHQpIHtcbiAgICAgIGxhc3RPdXRwdXQgPSBvdXRwdXQ7XG4gICAgICB5aWVsZCB7IHR5cGU6ICdwcmVsaW1pbmFyeScsIG91dHB1dCB9O1xuICAgIH1cbiAgICB5aWVsZCB7IHR5cGU6ICdmaW5hbCcsIG91dHB1dDogbGFzdE91dHB1dCEgfTtcbiAgfSBlbHNlIHtcbiAgICB5aWVsZCB7IHR5cGU6ICdmaW5hbCcsIG91dHB1dDogYXdhaXQgcmVzdWx0IH07XG4gIH1cbn1cbiIsICJleHBvcnQgKiBmcm9tICcuL2NvbWJpbmUtaGVhZGVycyc7XG5leHBvcnQgeyBjb252ZXJ0QXN5bmNJdGVyYXRvclRvUmVhZGFibGVTdHJlYW0gfSBmcm9tICcuL2NvbnZlcnQtYXN5bmMtaXRlcmF0b3ItdG8tcmVhZGFibGUtc3RyZWFtJztcbmV4cG9ydCAqIGZyb20gJy4vZGVsYXknO1xuZXhwb3J0ICogZnJvbSAnLi9leHRyYWN0LXJlc3BvbnNlLWhlYWRlcnMnO1xuZXhwb3J0ICogZnJvbSAnLi9mZXRjaC1mdW5jdGlvbic7XG5leHBvcnQgeyBjcmVhdGVJZEdlbmVyYXRvciwgZ2VuZXJhdGVJZCwgdHlwZSBJZEdlbmVyYXRvciB9IGZyb20gJy4vZ2VuZXJhdGUtaWQnO1xuZXhwb3J0ICogZnJvbSAnLi9nZXQtZXJyb3ItbWVzc2FnZSc7XG5leHBvcnQgKiBmcm9tICcuL2dldC1mcm9tLWFwaSc7XG5leHBvcnQgeyBnZXRSdW50aW1lRW52aXJvbm1lbnRVc2VyQWdlbnQgfSBmcm9tICcuL2dldC1ydW50aW1lLWVudmlyb25tZW50LXVzZXItYWdlbnQnO1xuZXhwb3J0IHsgaW5qZWN0SnNvbkluc3RydWN0aW9uSW50b01lc3NhZ2VzIH0gZnJvbSAnLi9pbmplY3QtanNvbi1pbnN0cnVjdGlvbic7XG5leHBvcnQgKiBmcm9tICcuL2lzLWFib3J0LWVycm9yJztcbmV4cG9ydCB7IGlzVXJsU3VwcG9ydGVkIH0gZnJvbSAnLi9pcy11cmwtc3VwcG9ydGVkJztcbmV4cG9ydCAqIGZyb20gJy4vbG9hZC1hcGkta2V5JztcbmV4cG9ydCB7IGxvYWRPcHRpb25hbFNldHRpbmcgfSBmcm9tICcuL2xvYWQtb3B0aW9uYWwtc2V0dGluZyc7XG5leHBvcnQgeyBsb2FkU2V0dGluZyB9IGZyb20gJy4vbG9hZC1zZXR0aW5nJztcbmV4cG9ydCB7IG1lZGlhVHlwZVRvRXh0ZW5zaW9uIH0gZnJvbSAnLi9tZWRpYS10eXBlLXRvLWV4dGVuc2lvbic7XG5leHBvcnQgKiBmcm9tICcuL3BhcnNlLWpzb24nO1xuZXhwb3J0IHsgcGFyc2VKc29uRXZlbnRTdHJlYW0gfSBmcm9tICcuL3BhcnNlLWpzb24tZXZlbnQtc3RyZWFtJztcbmV4cG9ydCB7IHBhcnNlUHJvdmlkZXJPcHRpb25zIH0gZnJvbSAnLi9wYXJzZS1wcm92aWRlci1vcHRpb25zJztcbmV4cG9ydCAqIGZyb20gJy4vcG9zdC10by1hcGknO1xuZXhwb3J0IHtcbiAgY3JlYXRlUHJvdmlkZXJEZWZpbmVkVG9vbEZhY3RvcnksXG4gIGNyZWF0ZVByb3ZpZGVyRGVmaW5lZFRvb2xGYWN0b3J5V2l0aE91dHB1dFNjaGVtYSxcbiAgdHlwZSBQcm92aWRlckRlZmluZWRUb29sRmFjdG9yeSxcbiAgdHlwZSBQcm92aWRlckRlZmluZWRUb29sRmFjdG9yeVdpdGhPdXRwdXRTY2hlbWEsXG59IGZyb20gJy4vcHJvdmlkZXItZGVmaW5lZC10b29sLWZhY3RvcnknO1xuZXhwb3J0ICogZnJvbSAnLi9yZW1vdmUtdW5kZWZpbmVkLWVudHJpZXMnO1xuZXhwb3J0ICogZnJvbSAnLi9yZXNvbHZlJztcbmV4cG9ydCAqIGZyb20gJy4vcmVzcG9uc2UtaGFuZGxlcic7XG5leHBvcnQge1xuICBhc1NjaGVtYSxcbiAganNvblNjaGVtYSxcbiAgbGF6eVNjaGVtYSxcbiAgdHlwZSBGbGV4aWJsZVNjaGVtYSxcbiAgdHlwZSBJbmZlclNjaGVtYSxcbiAgdHlwZSBMYXp5U2NoZW1hLFxuICB0eXBlIFNjaGVtYSxcbn0gZnJvbSAnLi9zY2hlbWEnO1xuZXhwb3J0ICogZnJvbSAnLi91aW50OC11dGlscyc7XG5leHBvcnQgKiBmcm9tICcuL3ZhbGlkYXRlLXR5cGVzJztcbmV4cG9ydCB7XG4gIGFzVmFsaWRhdG9yLFxuICBpc1ZhbGlkYXRvcixcbiAgbGF6eVZhbGlkYXRvcixcbiAgc3RhbmRhcmRTY2hlbWFWYWxpZGF0b3IsXG4gIHZhbGlkYXRvcixcbiAgdHlwZSBGbGV4aWJsZVZhbGlkYXRvcixcbiAgdHlwZSBJbmZlclZhbGlkYXRvcixcbiAgdHlwZSBMYXp5VmFsaWRhdG9yLFxuICB0eXBlIFZhbGlkYXRpb25SZXN1bHQsXG4gIHR5cGUgVmFsaWRhdG9yLFxufSBmcm9tICcuL3ZhbGlkYXRvcic7XG5leHBvcnQgeyBWRVJTSU9OIH0gZnJvbSAnLi92ZXJzaW9uJztcbmV4cG9ydCB7IHdpdGhVc2VyQWdlbnRTdWZmaXggfSBmcm9tICcuL3dpdGgtdXNlci1hZ2VudC1zdWZmaXgnO1xuZXhwb3J0ICogZnJvbSAnLi93aXRob3V0LXRyYWlsaW5nLXNsYXNoJztcbmV4cG9ydCB7IHpvZFNjaGVtYSB9IGZyb20gJy4vem9kLXNjaGVtYSc7XG5cbi8vIGZvbGRlciByZS1leHBvcnRzXG5leHBvcnQgKiBmcm9tICcuL3R5cGVzJztcblxuLy8gZXh0ZXJuYWwgcmUtZXhwb3J0c1xuZXhwb3J0ICogZnJvbSAnQHN0YW5kYXJkLXNjaGVtYS9zcGVjJztcbmV4cG9ydCB7XG4gIEV2ZW50U291cmNlUGFyc2VyU3RyZWFtLFxuICB0eXBlIEV2ZW50U291cmNlTWVzc2FnZSxcbn0gZnJvbSAnZXZlbnRzb3VyY2UtcGFyc2VyL3N0cmVhbSc7XG4iLCAiaW1wb3J0IHsgTm9TdWNoTW9kZWxFcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHtcbiAgbG9hZE9wdGlvbmFsU2V0dGluZyxcbiAgd2l0aG91dFRyYWlsaW5nU2xhc2gsXG4gIHR5cGUgRmV0Y2hGdW5jdGlvbixcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyBhc0dhdGV3YXlFcnJvciwgR2F0ZXdheUF1dGhlbnRpY2F0aW9uRXJyb3IgfSBmcm9tICcuL2Vycm9ycyc7XG5pbXBvcnQge1xuICBHQVRFV0FZX0FVVEhfTUVUSE9EX0hFQURFUixcbiAgcGFyc2VBdXRoTWV0aG9kLFxufSBmcm9tICcuL2Vycm9ycy9wYXJzZS1hdXRoLW1ldGhvZCc7XG5pbXBvcnQge1xuICBHYXRld2F5RmV0Y2hNZXRhZGF0YSxcbiAgdHlwZSBHYXRld2F5RmV0Y2hNZXRhZGF0YVJlc3BvbnNlLFxuICB0eXBlIEdhdGV3YXlDcmVkaXRzUmVzcG9uc2UsXG59IGZyb20gJy4vZ2F0ZXdheS1mZXRjaC1tZXRhZGF0YSc7XG5pbXBvcnQgeyBHYXRld2F5TGFuZ3VhZ2VNb2RlbCB9IGZyb20gJy4vZ2F0ZXdheS1sYW5ndWFnZS1tb2RlbCc7XG5pbXBvcnQgeyBHYXRld2F5RW1iZWRkaW5nTW9kZWwgfSBmcm9tICcuL2dhdGV3YXktZW1iZWRkaW5nLW1vZGVsJztcbmltcG9ydCB0eXBlIHsgR2F0ZXdheUVtYmVkZGluZ01vZGVsSWQgfSBmcm9tICcuL2dhdGV3YXktZW1iZWRkaW5nLW1vZGVsLXNldHRpbmdzJztcbmltcG9ydCB7IGdldFZlcmNlbE9pZGNUb2tlbiwgZ2V0VmVyY2VsUmVxdWVzdElkIH0gZnJvbSAnLi92ZXJjZWwtZW52aXJvbm1lbnQnO1xuaW1wb3J0IHR5cGUgeyBHYXRld2F5TW9kZWxJZCB9IGZyb20gJy4vZ2F0ZXdheS1sYW5ndWFnZS1tb2RlbC1zZXR0aW5ncyc7XG5pbXBvcnQgdHlwZSB7XG4gIExhbmd1YWdlTW9kZWxWMixcbiAgRW1iZWRkaW5nTW9kZWxWMixcbiAgUHJvdmlkZXJWMixcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQgeyB3aXRoVXNlckFnZW50U3VmZml4IH0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyBWRVJTSU9OIH0gZnJvbSAnLi92ZXJzaW9uJztcblxuZXhwb3J0IGludGVyZmFjZSBHYXRld2F5UHJvdmlkZXIgZXh0ZW5kcyBQcm92aWRlclYyIHtcbiAgKG1vZGVsSWQ6IEdhdGV3YXlNb2RlbElkKTogTGFuZ3VhZ2VNb2RlbFYyO1xuXG4gIC8qKlxuQ3JlYXRlcyBhIG1vZGVsIGZvciB0ZXh0IGdlbmVyYXRpb24uXG4qL1xuICBsYW5ndWFnZU1vZGVsKG1vZGVsSWQ6IEdhdGV3YXlNb2RlbElkKTogTGFuZ3VhZ2VNb2RlbFYyO1xuXG4gIC8qKlxuUmV0dXJucyBhdmFpbGFibGUgcHJvdmlkZXJzIGFuZCBtb2RlbHMgZm9yIHVzZSB3aXRoIHRoZSByZW1vdGUgcHJvdmlkZXIuXG4gKi9cbiAgZ2V0QXZhaWxhYmxlTW9kZWxzKCk6IFByb21pc2U8R2F0ZXdheUZldGNoTWV0YWRhdGFSZXNwb25zZT47XG5cbiAgLyoqXG5SZXR1cm5zIGNyZWRpdCBpbmZvcm1hdGlvbiBmb3IgdGhlIGF1dGhlbnRpY2F0ZWQgdXNlci5cbiAqL1xuICBnZXRDcmVkaXRzKCk6IFByb21pc2U8R2F0ZXdheUNyZWRpdHNSZXNwb25zZT47XG5cbiAgLyoqXG5DcmVhdGVzIGEgbW9kZWwgZm9yIGdlbmVyYXRpbmcgdGV4dCBlbWJlZGRpbmdzLlxuKi9cbiAgdGV4dEVtYmVkZGluZ01vZGVsKFxuICAgIG1vZGVsSWQ6IEdhdGV3YXlFbWJlZGRpbmdNb2RlbElkLFxuICApOiBFbWJlZGRpbmdNb2RlbFYyPHN0cmluZz47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2F0ZXdheVByb3ZpZGVyU2V0dGluZ3Mge1xuICAvKipcblRoZSBiYXNlIFVSTCBwcmVmaXggZm9yIEFQSSBjYWxscy4gRGVmYXVsdHMgdG8gYGh0dHBzOi8vYWktZ2F0ZXdheS52ZXJjZWwuc2gvdjEvYWlgLlxuICAgKi9cbiAgYmFzZVVSTD86IHN0cmluZztcblxuICAvKipcbkFQSSBrZXkgdGhhdCBpcyBiZWluZyBzZW50IHVzaW5nIHRoZSBgQXV0aG9yaXphdGlvbmAgaGVhZGVyLlxuICAgKi9cbiAgYXBpS2V5Pzogc3RyaW5nO1xuXG4gIC8qKlxuQ3VzdG9tIGhlYWRlcnMgdG8gaW5jbHVkZSBpbiB0aGUgcmVxdWVzdHMuXG4gICAgICovXG4gIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuXG4gIC8qKlxuQ3VzdG9tIGZldGNoIGltcGxlbWVudGF0aW9uLiBZb3UgY2FuIHVzZSBpdCBhcyBhIG1pZGRsZXdhcmUgdG8gaW50ZXJjZXB0IHJlcXVlc3RzLFxub3IgdG8gcHJvdmlkZSBhIGN1c3RvbSBmZXRjaCBpbXBsZW1lbnRhdGlvbiBmb3IgZS5nLiB0ZXN0aW5nLlxuICAgICovXG4gIGZldGNoPzogRmV0Y2hGdW5jdGlvbjtcblxuICAvKipcbkhvdyBmcmVxdWVudGx5IHRvIHJlZnJlc2ggdGhlIG1ldGFkYXRhIGNhY2hlIGluIG1pbGxpc2Vjb25kcy5cbiAgICovXG4gIG1ldGFkYXRhQ2FjaGVSZWZyZXNoTWlsbGlzPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBAaW50ZXJuYWwgRm9yIHRlc3RpbmcgcHVycG9zZXMgb25seVxuICAgKi9cbiAgX2ludGVybmFsPzoge1xuICAgIGN1cnJlbnREYXRlPzogKCkgPT4gRGF0ZTtcbiAgfTtcbn1cblxuY29uc3QgQUlfR0FURVdBWV9QUk9UT0NPTF9WRVJTSU9OID0gJzAuMC4xJztcblxuLyoqXG5DcmVhdGUgYSByZW1vdGUgcHJvdmlkZXIgaW5zdGFuY2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVHYXRld2F5UHJvdmlkZXIoXG4gIG9wdGlvbnM6IEdhdGV3YXlQcm92aWRlclNldHRpbmdzID0ge30sXG4pOiBHYXRld2F5UHJvdmlkZXIge1xuICBsZXQgcGVuZGluZ01ldGFkYXRhOiBQcm9taXNlPEdhdGV3YXlGZXRjaE1ldGFkYXRhUmVzcG9uc2U+IHwgbnVsbCA9IG51bGw7XG4gIGxldCBtZXRhZGF0YUNhY2hlOiBHYXRld2F5RmV0Y2hNZXRhZGF0YVJlc3BvbnNlIHwgbnVsbCA9IG51bGw7XG4gIGNvbnN0IGNhY2hlUmVmcmVzaE1pbGxpcyA9XG4gICAgb3B0aW9ucy5tZXRhZGF0YUNhY2hlUmVmcmVzaE1pbGxpcyA/PyAxMDAwICogNjAgKiA1O1xuICBsZXQgbGFzdEZldGNoVGltZSA9IDA7XG5cbiAgY29uc3QgYmFzZVVSTCA9XG4gICAgd2l0aG91dFRyYWlsaW5nU2xhc2gob3B0aW9ucy5iYXNlVVJMKSA/P1xuICAgICdodHRwczovL2FpLWdhdGV3YXkudmVyY2VsLnNoL3YxL2FpJztcblxuICBjb25zdCBnZXRIZWFkZXJzID0gYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGF1dGggPSBhd2FpdCBnZXRHYXRld2F5QXV0aFRva2VuKG9wdGlvbnMpO1xuICAgIGlmIChhdXRoKSB7XG4gICAgICByZXR1cm4gd2l0aFVzZXJBZ2VudFN1ZmZpeChcbiAgICAgICAge1xuICAgICAgICAgIEF1dGhvcml6YXRpb246IGBCZWFyZXIgJHthdXRoLnRva2VufWAsXG4gICAgICAgICAgJ2FpLWdhdGV3YXktcHJvdG9jb2wtdmVyc2lvbic6IEFJX0dBVEVXQVlfUFJPVE9DT0xfVkVSU0lPTixcbiAgICAgICAgICBbR0FURVdBWV9BVVRIX01FVEhPRF9IRUFERVJdOiBhdXRoLmF1dGhNZXRob2QsXG4gICAgICAgICAgLi4ub3B0aW9ucy5oZWFkZXJzLFxuICAgICAgICB9LFxuICAgICAgICBgYWktc2RrL2dhdGV3YXkvJHtWRVJTSU9OfWAsXG4gICAgICApO1xuICAgIH1cblxuICAgIHRocm93IEdhdGV3YXlBdXRoZW50aWNhdGlvbkVycm9yLmNyZWF0ZUNvbnRleHR1YWxFcnJvcih7XG4gICAgICBhcGlLZXlQcm92aWRlZDogZmFsc2UsXG4gICAgICBvaWRjVG9rZW5Qcm92aWRlZDogZmFsc2UsXG4gICAgICBzdGF0dXNDb2RlOiA0MDEsXG4gICAgfSk7XG4gIH07XG5cbiAgY29uc3QgY3JlYXRlTzExeUhlYWRlcnMgPSAoKSA9PiB7XG4gICAgY29uc3QgZGVwbG95bWVudElkID0gbG9hZE9wdGlvbmFsU2V0dGluZyh7XG4gICAgICBzZXR0aW5nVmFsdWU6IHVuZGVmaW5lZCxcbiAgICAgIGVudmlyb25tZW50VmFyaWFibGVOYW1lOiAnVkVSQ0VMX0RFUExPWU1FTlRfSUQnLFxuICAgIH0pO1xuICAgIGNvbnN0IGVudmlyb25tZW50ID0gbG9hZE9wdGlvbmFsU2V0dGluZyh7XG4gICAgICBzZXR0aW5nVmFsdWU6IHVuZGVmaW5lZCxcbiAgICAgIGVudmlyb25tZW50VmFyaWFibGVOYW1lOiAnVkVSQ0VMX0VOVicsXG4gICAgfSk7XG4gICAgY29uc3QgcmVnaW9uID0gbG9hZE9wdGlvbmFsU2V0dGluZyh7XG4gICAgICBzZXR0aW5nVmFsdWU6IHVuZGVmaW5lZCxcbiAgICAgIGVudmlyb25tZW50VmFyaWFibGVOYW1lOiAnVkVSQ0VMX1JFR0lPTicsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcmVxdWVzdElkID0gYXdhaXQgZ2V0VmVyY2VsUmVxdWVzdElkKCk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi4oZGVwbG95bWVudElkICYmIHsgJ2FpLW8xMXktZGVwbG95bWVudC1pZCc6IGRlcGxveW1lbnRJZCB9KSxcbiAgICAgICAgLi4uKGVudmlyb25tZW50ICYmIHsgJ2FpLW8xMXktZW52aXJvbm1lbnQnOiBlbnZpcm9ubWVudCB9KSxcbiAgICAgICAgLi4uKHJlZ2lvbiAmJiB7ICdhaS1vMTF5LXJlZ2lvbic6IHJlZ2lvbiB9KSxcbiAgICAgICAgLi4uKHJlcXVlc3RJZCAmJiB7ICdhaS1vMTF5LXJlcXVlc3QtaWQnOiByZXF1ZXN0SWQgfSksXG4gICAgICB9O1xuICAgIH07XG4gIH07XG5cbiAgY29uc3QgY3JlYXRlTGFuZ3VhZ2VNb2RlbCA9IChtb2RlbElkOiBHYXRld2F5TW9kZWxJZCkgPT4ge1xuICAgIHJldHVybiBuZXcgR2F0ZXdheUxhbmd1YWdlTW9kZWwobW9kZWxJZCwge1xuICAgICAgcHJvdmlkZXI6ICdnYXRld2F5JyxcbiAgICAgIGJhc2VVUkwsXG4gICAgICBoZWFkZXJzOiBnZXRIZWFkZXJzLFxuICAgICAgZmV0Y2g6IG9wdGlvbnMuZmV0Y2gsXG4gICAgICBvMTF5SGVhZGVyczogY3JlYXRlTzExeUhlYWRlcnMoKSxcbiAgICB9KTtcbiAgfTtcblxuICBjb25zdCBnZXRBdmFpbGFibGVNb2RlbHMgPSBhc3luYyAoKSA9PiB7XG4gICAgY29uc3Qgbm93ID0gb3B0aW9ucy5faW50ZXJuYWw/LmN1cnJlbnREYXRlPy4oKS5nZXRUaW1lKCkgPz8gRGF0ZS5ub3coKTtcbiAgICBpZiAoIXBlbmRpbmdNZXRhZGF0YSB8fCBub3cgLSBsYXN0RmV0Y2hUaW1lID4gY2FjaGVSZWZyZXNoTWlsbGlzKSB7XG4gICAgICBsYXN0RmV0Y2hUaW1lID0gbm93O1xuXG4gICAgICBwZW5kaW5nTWV0YWRhdGEgPSBuZXcgR2F0ZXdheUZldGNoTWV0YWRhdGEoe1xuICAgICAgICBiYXNlVVJMLFxuICAgICAgICBoZWFkZXJzOiBnZXRIZWFkZXJzLFxuICAgICAgICBmZXRjaDogb3B0aW9ucy5mZXRjaCxcbiAgICAgIH0pXG4gICAgICAgIC5nZXRBdmFpbGFibGVNb2RlbHMoKVxuICAgICAgICAudGhlbihtZXRhZGF0YSA9PiB7XG4gICAgICAgICAgbWV0YWRhdGFDYWNoZSA9IG1ldGFkYXRhO1xuICAgICAgICAgIHJldHVybiBtZXRhZGF0YTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGFzeW5jIChlcnJvcjogdW5rbm93bikgPT4ge1xuICAgICAgICAgIHRocm93IGF3YWl0IGFzR2F0ZXdheUVycm9yKFxuICAgICAgICAgICAgZXJyb3IsXG4gICAgICAgICAgICBhd2FpdCBwYXJzZUF1dGhNZXRob2QoYXdhaXQgZ2V0SGVhZGVycygpKSxcbiAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gbWV0YWRhdGFDYWNoZSA/IFByb21pc2UucmVzb2x2ZShtZXRhZGF0YUNhY2hlKSA6IHBlbmRpbmdNZXRhZGF0YTtcbiAgfTtcblxuICBjb25zdCBnZXRDcmVkaXRzID0gYXN5bmMgKCkgPT4ge1xuICAgIHJldHVybiBuZXcgR2F0ZXdheUZldGNoTWV0YWRhdGEoe1xuICAgICAgYmFzZVVSTCxcbiAgICAgIGhlYWRlcnM6IGdldEhlYWRlcnMsXG4gICAgICBmZXRjaDogb3B0aW9ucy5mZXRjaCxcbiAgICB9KVxuICAgICAgLmdldENyZWRpdHMoKVxuICAgICAgLmNhdGNoKGFzeW5jIChlcnJvcjogdW5rbm93bikgPT4ge1xuICAgICAgICB0aHJvdyBhd2FpdCBhc0dhdGV3YXlFcnJvcihcbiAgICAgICAgICBlcnJvcixcbiAgICAgICAgICBhd2FpdCBwYXJzZUF1dGhNZXRob2QoYXdhaXQgZ2V0SGVhZGVycygpKSxcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICB9O1xuXG4gIGNvbnN0IHByb3ZpZGVyID0gZnVuY3Rpb24gKG1vZGVsSWQ6IEdhdGV3YXlNb2RlbElkKSB7XG4gICAgaWYgKG5ldy50YXJnZXQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ1RoZSBHYXRld2F5IFByb3ZpZGVyIG1vZGVsIGZ1bmN0aW9uIGNhbm5vdCBiZSBjYWxsZWQgd2l0aCB0aGUgbmV3IGtleXdvcmQuJyxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNyZWF0ZUxhbmd1YWdlTW9kZWwobW9kZWxJZCk7XG4gIH07XG5cbiAgcHJvdmlkZXIuZ2V0QXZhaWxhYmxlTW9kZWxzID0gZ2V0QXZhaWxhYmxlTW9kZWxzO1xuICBwcm92aWRlci5nZXRDcmVkaXRzID0gZ2V0Q3JlZGl0cztcbiAgcHJvdmlkZXIuaW1hZ2VNb2RlbCA9IChtb2RlbElkOiBzdHJpbmcpID0+IHtcbiAgICB0aHJvdyBuZXcgTm9TdWNoTW9kZWxFcnJvcih7IG1vZGVsSWQsIG1vZGVsVHlwZTogJ2ltYWdlTW9kZWwnIH0pO1xuICB9O1xuICBwcm92aWRlci5sYW5ndWFnZU1vZGVsID0gY3JlYXRlTGFuZ3VhZ2VNb2RlbDtcbiAgcHJvdmlkZXIudGV4dEVtYmVkZGluZ01vZGVsID0gKG1vZGVsSWQ6IEdhdGV3YXlFbWJlZGRpbmdNb2RlbElkKSA9PiB7XG4gICAgcmV0dXJuIG5ldyBHYXRld2F5RW1iZWRkaW5nTW9kZWwobW9kZWxJZCwge1xuICAgICAgcHJvdmlkZXI6ICdnYXRld2F5JyxcbiAgICAgIGJhc2VVUkwsXG4gICAgICBoZWFkZXJzOiBnZXRIZWFkZXJzLFxuICAgICAgZmV0Y2g6IG9wdGlvbnMuZmV0Y2gsXG4gICAgICBvMTF5SGVhZGVyczogY3JlYXRlTzExeUhlYWRlcnMoKSxcbiAgICB9KTtcbiAgfTtcblxuICByZXR1cm4gcHJvdmlkZXI7XG59XG5cbmV4cG9ydCBjb25zdCBnYXRld2F5ID0gY3JlYXRlR2F0ZXdheVByb3ZpZGVyKCk7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRHYXRld2F5QXV0aFRva2VuKFxuICBvcHRpb25zOiBHYXRld2F5UHJvdmlkZXJTZXR0aW5ncyxcbik6IFByb21pc2U8e1xuICB0b2tlbjogc3RyaW5nO1xuICBhdXRoTWV0aG9kOiAnYXBpLWtleScgfCAnb2lkYyc7XG59IHwgbnVsbD4ge1xuICBjb25zdCBhcGlLZXkgPSBsb2FkT3B0aW9uYWxTZXR0aW5nKHtcbiAgICBzZXR0aW5nVmFsdWU6IG9wdGlvbnMuYXBpS2V5LFxuICAgIGVudmlyb25tZW50VmFyaWFibGVOYW1lOiAnQUlfR0FURVdBWV9BUElfS0VZJyxcbiAgfSk7XG5cbiAgaWYgKGFwaUtleSkge1xuICAgIHJldHVybiB7XG4gICAgICB0b2tlbjogYXBpS2V5LFxuICAgICAgYXV0aE1ldGhvZDogJ2FwaS1rZXknLFxuICAgIH07XG4gIH1cblxuICB0cnkge1xuICAgIGNvbnN0IG9pZGNUb2tlbiA9IGF3YWl0IGdldFZlcmNlbE9pZGNUb2tlbigpO1xuICAgIHJldHVybiB7XG4gICAgICB0b2tlbjogb2lkY1Rva2VuLFxuICAgICAgYXV0aE1ldGhvZDogJ29pZGMnLFxuICAgIH07XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBudWxsO1xuICB9XG59XG4iLCAiaW1wb3J0IHsgQVBJQ2FsbEVycm9yIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQgeyBleHRyYWN0QXBpQ2FsbFJlc3BvbnNlLCBHYXRld2F5RXJyb3IgfSBmcm9tICcuJztcbmltcG9ydCB7IGNyZWF0ZUdhdGV3YXlFcnJvckZyb21SZXNwb25zZSB9IGZyb20gJy4vY3JlYXRlLWdhdGV3YXktZXJyb3InO1xuXG5leHBvcnQgZnVuY3Rpb24gYXNHYXRld2F5RXJyb3IoXG4gIGVycm9yOiB1bmtub3duLFxuICBhdXRoTWV0aG9kPzogJ2FwaS1rZXknIHwgJ29pZGMnLFxuKSB7XG4gIGlmIChHYXRld2F5RXJyb3IuaXNJbnN0YW5jZShlcnJvcikpIHtcbiAgICByZXR1cm4gZXJyb3I7XG4gIH1cblxuICBpZiAoQVBJQ2FsbEVycm9yLmlzSW5zdGFuY2UoZXJyb3IpKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUdhdGV3YXlFcnJvckZyb21SZXNwb25zZSh7XG4gICAgICByZXNwb25zZTogZXh0cmFjdEFwaUNhbGxSZXNwb25zZShlcnJvciksXG4gICAgICBzdGF0dXNDb2RlOiBlcnJvci5zdGF0dXNDb2RlID8/IDUwMCxcbiAgICAgIGRlZmF1bHRNZXNzYWdlOiAnR2F0ZXdheSByZXF1ZXN0IGZhaWxlZCcsXG4gICAgICBjYXVzZTogZXJyb3IsXG4gICAgICBhdXRoTWV0aG9kLFxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIGNyZWF0ZUdhdGV3YXlFcnJvckZyb21SZXNwb25zZSh7XG4gICAgcmVzcG9uc2U6IHt9LFxuICAgIHN0YXR1c0NvZGU6IDUwMCxcbiAgICBkZWZhdWx0TWVzc2FnZTpcbiAgICAgIGVycm9yIGluc3RhbmNlb2YgRXJyb3JcbiAgICAgICAgPyBgR2F0ZXdheSByZXF1ZXN0IGZhaWxlZDogJHtlcnJvci5tZXNzYWdlfWBcbiAgICAgICAgOiAnVW5rbm93biBHYXRld2F5IGVycm9yJyxcbiAgICBjYXVzZTogZXJyb3IsXG4gICAgYXV0aE1ldGhvZCxcbiAgfSk7XG59XG4iLCAiaW1wb3J0IHsgeiB9IGZyb20gJ3pvZC92NCc7XG5pbXBvcnQgdHlwZSB7IEdhdGV3YXlFcnJvciB9IGZyb20gJy4vZ2F0ZXdheS1lcnJvcic7XG5pbXBvcnQgeyBHYXRld2F5QXV0aGVudGljYXRpb25FcnJvciB9IGZyb20gJy4vZ2F0ZXdheS1hdXRoZW50aWNhdGlvbi1lcnJvcic7XG5pbXBvcnQgeyBHYXRld2F5SW52YWxpZFJlcXVlc3RFcnJvciB9IGZyb20gJy4vZ2F0ZXdheS1pbnZhbGlkLXJlcXVlc3QtZXJyb3InO1xuaW1wb3J0IHsgR2F0ZXdheVJhdGVMaW1pdEVycm9yIH0gZnJvbSAnLi9nYXRld2F5LXJhdGUtbGltaXQtZXJyb3InO1xuaW1wb3J0IHtcbiAgR2F0ZXdheU1vZGVsTm90Rm91bmRFcnJvcixcbiAgbW9kZWxOb3RGb3VuZFBhcmFtU2NoZW1hLFxufSBmcm9tICcuL2dhdGV3YXktbW9kZWwtbm90LWZvdW5kLWVycm9yJztcbmltcG9ydCB7IEdhdGV3YXlJbnRlcm5hbFNlcnZlckVycm9yIH0gZnJvbSAnLi9nYXRld2F5LWludGVybmFsLXNlcnZlci1lcnJvcic7XG5pbXBvcnQgeyBHYXRld2F5UmVzcG9uc2VFcnJvciB9IGZyb20gJy4vZ2F0ZXdheS1yZXNwb25zZS1lcnJvcic7XG5pbXBvcnQge1xuICBJbmZlclZhbGlkYXRvcixcbiAgbGF6eVZhbGlkYXRvcixcbiAgc2FmZVZhbGlkYXRlVHlwZXMsXG4gIHZhbGlkYXRlVHlwZXMsXG4gIHpvZFNjaGVtYSxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjcmVhdGVHYXRld2F5RXJyb3JGcm9tUmVzcG9uc2Uoe1xuICByZXNwb25zZSxcbiAgc3RhdHVzQ29kZSxcbiAgZGVmYXVsdE1lc3NhZ2UgPSAnR2F0ZXdheSByZXF1ZXN0IGZhaWxlZCcsXG4gIGNhdXNlLFxuICBhdXRoTWV0aG9kLFxufToge1xuICByZXNwb25zZTogdW5rbm93bjtcbiAgc3RhdHVzQ29kZTogbnVtYmVyO1xuICBkZWZhdWx0TWVzc2FnZT86IHN0cmluZztcbiAgY2F1c2U/OiB1bmtub3duO1xuICBhdXRoTWV0aG9kPzogJ2FwaS1rZXknIHwgJ29pZGMnO1xufSk6IFByb21pc2U8R2F0ZXdheUVycm9yPiB7XG4gIGNvbnN0IHBhcnNlUmVzdWx0ID0gYXdhaXQgc2FmZVZhbGlkYXRlVHlwZXMoe1xuICAgIHZhbHVlOiByZXNwb25zZSxcbiAgICBzY2hlbWE6IGdhdGV3YXlFcnJvclJlc3BvbnNlU2NoZW1hLFxuICB9KTtcblxuICBpZiAoIXBhcnNlUmVzdWx0LnN1Y2Nlc3MpIHtcbiAgICByZXR1cm4gbmV3IEdhdGV3YXlSZXNwb25zZUVycm9yKHtcbiAgICAgIG1lc3NhZ2U6IGBJbnZhbGlkIGVycm9yIHJlc3BvbnNlIGZvcm1hdDogJHtkZWZhdWx0TWVzc2FnZX1gLFxuICAgICAgc3RhdHVzQ29kZSxcbiAgICAgIHJlc3BvbnNlLFxuICAgICAgdmFsaWRhdGlvbkVycm9yOiBwYXJzZVJlc3VsdC5lcnJvcixcbiAgICAgIGNhdXNlLFxuICAgIH0pO1xuICB9XG5cbiAgY29uc3QgdmFsaWRhdGVkUmVzcG9uc2U6IEdhdGV3YXlFcnJvclJlc3BvbnNlID0gcGFyc2VSZXN1bHQudmFsdWU7XG4gIGNvbnN0IGVycm9yVHlwZSA9IHZhbGlkYXRlZFJlc3BvbnNlLmVycm9yLnR5cGU7XG4gIGNvbnN0IG1lc3NhZ2UgPSB2YWxpZGF0ZWRSZXNwb25zZS5lcnJvci5tZXNzYWdlO1xuXG4gIHN3aXRjaCAoZXJyb3JUeXBlKSB7XG4gICAgY2FzZSAnYXV0aGVudGljYXRpb25fZXJyb3InOlxuICAgICAgcmV0dXJuIEdhdGV3YXlBdXRoZW50aWNhdGlvbkVycm9yLmNyZWF0ZUNvbnRleHR1YWxFcnJvcih7XG4gICAgICAgIGFwaUtleVByb3ZpZGVkOiBhdXRoTWV0aG9kID09PSAnYXBpLWtleScsXG4gICAgICAgIG9pZGNUb2tlblByb3ZpZGVkOiBhdXRoTWV0aG9kID09PSAnb2lkYycsXG4gICAgICAgIHN0YXR1c0NvZGUsXG4gICAgICAgIGNhdXNlLFxuICAgICAgfSk7XG4gICAgY2FzZSAnaW52YWxpZF9yZXF1ZXN0X2Vycm9yJzpcbiAgICAgIHJldHVybiBuZXcgR2F0ZXdheUludmFsaWRSZXF1ZXN0RXJyb3IoeyBtZXNzYWdlLCBzdGF0dXNDb2RlLCBjYXVzZSB9KTtcbiAgICBjYXNlICdyYXRlX2xpbWl0X2V4Y2VlZGVkJzpcbiAgICAgIHJldHVybiBuZXcgR2F0ZXdheVJhdGVMaW1pdEVycm9yKHsgbWVzc2FnZSwgc3RhdHVzQ29kZSwgY2F1c2UgfSk7XG4gICAgY2FzZSAnbW9kZWxfbm90X2ZvdW5kJzoge1xuICAgICAgY29uc3QgbW9kZWxSZXN1bHQgPSBhd2FpdCBzYWZlVmFsaWRhdGVUeXBlcyh7XG4gICAgICAgIHZhbHVlOiB2YWxpZGF0ZWRSZXNwb25zZS5lcnJvci5wYXJhbSxcbiAgICAgICAgc2NoZW1hOiBtb2RlbE5vdEZvdW5kUGFyYW1TY2hlbWEsXG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIG5ldyBHYXRld2F5TW9kZWxOb3RGb3VuZEVycm9yKHtcbiAgICAgICAgbWVzc2FnZSxcbiAgICAgICAgc3RhdHVzQ29kZSxcbiAgICAgICAgbW9kZWxJZDogbW9kZWxSZXN1bHQuc3VjY2VzcyA/IG1vZGVsUmVzdWx0LnZhbHVlLm1vZGVsSWQgOiB1bmRlZmluZWQsXG4gICAgICAgIGNhdXNlLFxuICAgICAgfSk7XG4gICAgfVxuICAgIGNhc2UgJ2ludGVybmFsX3NlcnZlcl9lcnJvcic6XG4gICAgICByZXR1cm4gbmV3IEdhdGV3YXlJbnRlcm5hbFNlcnZlckVycm9yKHsgbWVzc2FnZSwgc3RhdHVzQ29kZSwgY2F1c2UgfSk7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBuZXcgR2F0ZXdheUludGVybmFsU2VydmVyRXJyb3IoeyBtZXNzYWdlLCBzdGF0dXNDb2RlLCBjYXVzZSB9KTtcbiAgfVxufVxuXG5jb25zdCBnYXRld2F5RXJyb3JSZXNwb25zZVNjaGVtYSA9IGxhenlWYWxpZGF0b3IoKCkgPT5cbiAgem9kU2NoZW1hKFxuICAgIHoub2JqZWN0KHtcbiAgICAgIGVycm9yOiB6Lm9iamVjdCh7XG4gICAgICAgIG1lc3NhZ2U6IHouc3RyaW5nKCksXG4gICAgICAgIHR5cGU6IHouc3RyaW5nKCkubnVsbGlzaCgpLFxuICAgICAgICBwYXJhbTogei51bmtub3duKCkubnVsbGlzaCgpLFxuICAgICAgICBjb2RlOiB6LnVuaW9uKFt6LnN0cmluZygpLCB6Lm51bWJlcigpXSkubnVsbGlzaCgpLFxuICAgICAgfSksXG4gICAgfSksXG4gICksXG4pO1xuXG5leHBvcnQgdHlwZSBHYXRld2F5RXJyb3JSZXNwb25zZSA9IEluZmVyVmFsaWRhdG9yPFxuICB0eXBlb2YgZ2F0ZXdheUVycm9yUmVzcG9uc2VTY2hlbWFcbj47XG4iLCAiY29uc3QgbWFya2VyID0gJ3ZlcmNlbC5haS5nYXRld2F5LmVycm9yJztcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEdhdGV3YXlFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7IC8vIHVzZWQgaW4gaXNJbnN0YW5jZVxuXG4gIGFic3RyYWN0IHJlYWRvbmx5IG5hbWU6IHN0cmluZztcbiAgYWJzdHJhY3QgcmVhZG9ubHkgdHlwZTogc3RyaW5nO1xuICByZWFkb25seSBzdGF0dXNDb2RlOiBudW1iZXI7XG4gIHJlYWRvbmx5IGNhdXNlPzogdW5rbm93bjtcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgbWVzc2FnZSxcbiAgICBzdGF0dXNDb2RlID0gNTAwLFxuICAgIGNhdXNlLFxuICB9OiB7XG4gICAgbWVzc2FnZTogc3RyaW5nO1xuICAgIHN0YXR1c0NvZGU/OiBudW1iZXI7XG4gICAgY2F1c2U/OiB1bmtub3duO1xuICB9KSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gICAgdGhpcy5zdGF0dXNDb2RlID0gc3RhdHVzQ29kZTtcbiAgICB0aGlzLmNhdXNlID0gY2F1c2U7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBlcnJvciBpcyBhIEdhdGV3YXkgRXJyb3IuXG4gICAqIEBwYXJhbSB7dW5rbm93bn0gZXJyb3IgLSBUaGUgZXJyb3IgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSBlcnJvciBpcyBhIEdhdGV3YXkgRXJyb3IsIGZhbHNlIG90aGVyd2lzZS5cbiAgICovXG4gIHN0YXRpYyBpc0luc3RhbmNlKGVycm9yOiB1bmtub3duKTogZXJyb3IgaXMgR2F0ZXdheUVycm9yIHtcbiAgICByZXR1cm4gR2F0ZXdheUVycm9yLmhhc01hcmtlcihlcnJvcik7XG4gIH1cblxuICBzdGF0aWMgaGFzTWFya2VyKGVycm9yOiB1bmtub3duKTogZXJyb3IgaXMgR2F0ZXdheUVycm9yIHtcbiAgICByZXR1cm4gKFxuICAgICAgdHlwZW9mIGVycm9yID09PSAnb2JqZWN0JyAmJlxuICAgICAgZXJyb3IgIT09IG51bGwgJiZcbiAgICAgIHN5bWJvbCBpbiBlcnJvciAmJlxuICAgICAgKGVycm9yIGFzIGFueSlbc3ltYm9sXSA9PT0gdHJ1ZVxuICAgICk7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBHYXRld2F5RXJyb3IgfSBmcm9tICcuL2dhdGV3YXktZXJyb3InO1xuXG5jb25zdCBuYW1lID0gJ0dhdGV3YXlBdXRoZW50aWNhdGlvbkVycm9yJztcbmNvbnN0IG1hcmtlciA9IGB2ZXJjZWwuYWkuZ2F0ZXdheS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuLyoqXG4gKiBBdXRoZW50aWNhdGlvbiBmYWlsZWQgLSBpbnZhbGlkIEFQSSBrZXkgb3IgT0lEQyB0b2tlblxuICovXG5leHBvcnQgY2xhc3MgR2F0ZXdheUF1dGhlbnRpY2F0aW9uRXJyb3IgZXh0ZW5kcyBHYXRld2F5RXJyb3Ige1xuICBwcml2YXRlIHJlYWRvbmx5IFtzeW1ib2xdID0gdHJ1ZTsgLy8gdXNlZCBpbiBpc0luc3RhbmNlXG5cbiAgcmVhZG9ubHkgbmFtZSA9IG5hbWU7XG4gIHJlYWRvbmx5IHR5cGUgPSAnYXV0aGVudGljYXRpb25fZXJyb3InO1xuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICBtZXNzYWdlID0gJ0F1dGhlbnRpY2F0aW9uIGZhaWxlZCcsXG4gICAgc3RhdHVzQ29kZSA9IDQwMSxcbiAgICBjYXVzZSxcbiAgfToge1xuICAgIG1lc3NhZ2U/OiBzdHJpbmc7XG4gICAgc3RhdHVzQ29kZT86IG51bWJlcjtcbiAgICBjYXVzZT86IHVua25vd247XG4gIH0gPSB7fSkge1xuICAgIHN1cGVyKHsgbWVzc2FnZSwgc3RhdHVzQ29kZSwgY2F1c2UgfSk7XG4gIH1cblxuICBzdGF0aWMgaXNJbnN0YW5jZShlcnJvcjogdW5rbm93bik6IGVycm9yIGlzIEdhdGV3YXlBdXRoZW50aWNhdGlvbkVycm9yIHtcbiAgICByZXR1cm4gR2F0ZXdheUVycm9yLmhhc01hcmtlcihlcnJvcikgJiYgc3ltYm9sIGluIGVycm9yO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBjb250ZXh0dWFsIGVycm9yIG1lc3NhZ2Ugd2hlbiBhdXRoZW50aWNhdGlvbiBmYWlsc1xuICAgKi9cbiAgc3RhdGljIGNyZWF0ZUNvbnRleHR1YWxFcnJvcih7XG4gICAgYXBpS2V5UHJvdmlkZWQsXG4gICAgb2lkY1Rva2VuUHJvdmlkZWQsXG4gICAgbWVzc2FnZSA9ICdBdXRoZW50aWNhdGlvbiBmYWlsZWQnLFxuICAgIHN0YXR1c0NvZGUgPSA0MDEsXG4gICAgY2F1c2UsXG4gIH06IHtcbiAgICBhcGlLZXlQcm92aWRlZDogYm9vbGVhbjtcbiAgICBvaWRjVG9rZW5Qcm92aWRlZDogYm9vbGVhbjtcbiAgICBtZXNzYWdlPzogc3RyaW5nO1xuICAgIHN0YXR1c0NvZGU/OiBudW1iZXI7XG4gICAgY2F1c2U/OiB1bmtub3duO1xuICB9KTogR2F0ZXdheUF1dGhlbnRpY2F0aW9uRXJyb3Ige1xuICAgIGxldCBjb250ZXh0dWFsTWVzc2FnZTogc3RyaW5nO1xuXG4gICAgaWYgKGFwaUtleVByb3ZpZGVkKSB7XG4gICAgICBjb250ZXh0dWFsTWVzc2FnZSA9IGBBSSBHYXRld2F5IGF1dGhlbnRpY2F0aW9uIGZhaWxlZDogSW52YWxpZCBBUEkga2V5LlxuXG5DcmVhdGUgYSBuZXcgQVBJIGtleTogaHR0cHM6Ly92ZXJjZWwuY29tL2Q/dG89JTJGJTVCdGVhbSU1RCUyRiU3RSUyRmFpJTJGYXBpLWtleXNcblxuUHJvdmlkZSB2aWEgJ2FwaUtleScgb3B0aW9uIG9yICdBSV9HQVRFV0FZX0FQSV9LRVknIGVudmlyb25tZW50IHZhcmlhYmxlLmA7XG4gICAgfSBlbHNlIGlmIChvaWRjVG9rZW5Qcm92aWRlZCkge1xuICAgICAgY29udGV4dHVhbE1lc3NhZ2UgPSBgQUkgR2F0ZXdheSBhdXRoZW50aWNhdGlvbiBmYWlsZWQ6IEludmFsaWQgT0lEQyB0b2tlbi5cblxuUnVuICducHggdmVyY2VsIGxpbmsnIHRvIGxpbmsgeW91ciBwcm9qZWN0LCB0aGVuICd2YyBlbnYgcHVsbCcgdG8gZmV0Y2ggdGhlIHRva2VuLlxuXG5BbHRlcm5hdGl2ZWx5LCB1c2UgYW4gQVBJIGtleTogaHR0cHM6Ly92ZXJjZWwuY29tL2Q/dG89JTJGJTVCdGVhbSU1RCUyRiU3RSUyRmFpJTJGYXBpLWtleXNgO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb250ZXh0dWFsTWVzc2FnZSA9IGBBSSBHYXRld2F5IGF1dGhlbnRpY2F0aW9uIGZhaWxlZDogTm8gYXV0aGVudGljYXRpb24gcHJvdmlkZWQuXG5cbk9wdGlvbiAxIC0gQVBJIGtleTpcbkNyZWF0ZSBhbiBBUEkga2V5OiBodHRwczovL3ZlcmNlbC5jb20vZD90bz0lMkYlNUJ0ZWFtJTVEJTJGJTdFJTJGYWklMkZhcGkta2V5c1xuUHJvdmlkZSB2aWEgJ2FwaUtleScgb3B0aW9uIG9yICdBSV9HQVRFV0FZX0FQSV9LRVknIGVudmlyb25tZW50IHZhcmlhYmxlLlxuXG5PcHRpb24gMiAtIE9JREMgdG9rZW46XG5SdW4gJ25weCB2ZXJjZWwgbGluaycgdG8gbGluayB5b3VyIHByb2plY3QsIHRoZW4gJ3ZjIGVudiBwdWxsJyB0byBmZXRjaCB0aGUgdG9rZW4uYDtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IEdhdGV3YXlBdXRoZW50aWNhdGlvbkVycm9yKHtcbiAgICAgIG1lc3NhZ2U6IGNvbnRleHR1YWxNZXNzYWdlLFxuICAgICAgc3RhdHVzQ29kZSxcbiAgICAgIGNhdXNlLFxuICAgIH0pO1xuICB9XG59XG4iLCAiaW1wb3J0IHsgR2F0ZXdheUVycm9yIH0gZnJvbSAnLi9nYXRld2F5LWVycm9yJztcblxuY29uc3QgbmFtZSA9ICdHYXRld2F5SW52YWxpZFJlcXVlc3RFcnJvcic7XG5jb25zdCBtYXJrZXIgPSBgdmVyY2VsLmFpLmdhdGV3YXkuZXJyb3IuJHtuYW1lfWA7XG5jb25zdCBzeW1ib2wgPSBTeW1ib2wuZm9yKG1hcmtlcik7XG5cbi8qKlxuICogSW52YWxpZCByZXF1ZXN0IC0gbWlzc2luZyBoZWFkZXJzLCBtYWxmb3JtZWQgZGF0YSwgZXRjLlxuICovXG5leHBvcnQgY2xhc3MgR2F0ZXdheUludmFsaWRSZXF1ZXN0RXJyb3IgZXh0ZW5kcyBHYXRld2F5RXJyb3Ige1xuICBwcml2YXRlIHJlYWRvbmx5IFtzeW1ib2xdID0gdHJ1ZTsgLy8gdXNlZCBpbiBpc0luc3RhbmNlXG5cbiAgcmVhZG9ubHkgbmFtZSA9IG5hbWU7XG4gIHJlYWRvbmx5IHR5cGUgPSAnaW52YWxpZF9yZXF1ZXN0X2Vycm9yJztcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgbWVzc2FnZSA9ICdJbnZhbGlkIHJlcXVlc3QnLFxuICAgIHN0YXR1c0NvZGUgPSA0MDAsXG4gICAgY2F1c2UsXG4gIH06IHtcbiAgICBtZXNzYWdlPzogc3RyaW5nO1xuICAgIHN0YXR1c0NvZGU/OiBudW1iZXI7XG4gICAgY2F1c2U/OiB1bmtub3duO1xuICB9ID0ge30pIHtcbiAgICBzdXBlcih7IG1lc3NhZ2UsIHN0YXR1c0NvZGUsIGNhdXNlIH0pO1xuICB9XG5cbiAgc3RhdGljIGlzSW5zdGFuY2UoZXJyb3I6IHVua25vd24pOiBlcnJvciBpcyBHYXRld2F5SW52YWxpZFJlcXVlc3RFcnJvciB7XG4gICAgcmV0dXJuIEdhdGV3YXlFcnJvci5oYXNNYXJrZXIoZXJyb3IpICYmIHN5bWJvbCBpbiBlcnJvcjtcbiAgfVxufVxuIiwgImltcG9ydCB7IEdhdGV3YXlFcnJvciB9IGZyb20gJy4vZ2F0ZXdheS1lcnJvcic7XG5cbmNvbnN0IG5hbWUgPSAnR2F0ZXdheVJhdGVMaW1pdEVycm9yJztcbmNvbnN0IG1hcmtlciA9IGB2ZXJjZWwuYWkuZ2F0ZXdheS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuLyoqXG4gKiBSYXRlIGxpbWl0IGV4Y2VlZGVkLlxuICovXG5leHBvcnQgY2xhc3MgR2F0ZXdheVJhdGVMaW1pdEVycm9yIGV4dGVuZHMgR2F0ZXdheUVycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7IC8vIHVzZWQgaW4gaXNJbnN0YW5jZVxuXG4gIHJlYWRvbmx5IG5hbWUgPSBuYW1lO1xuICByZWFkb25seSB0eXBlID0gJ3JhdGVfbGltaXRfZXhjZWVkZWQnO1xuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICBtZXNzYWdlID0gJ1JhdGUgbGltaXQgZXhjZWVkZWQnLFxuICAgIHN0YXR1c0NvZGUgPSA0MjksXG4gICAgY2F1c2UsXG4gIH06IHtcbiAgICBtZXNzYWdlPzogc3RyaW5nO1xuICAgIHN0YXR1c0NvZGU/OiBudW1iZXI7XG4gICAgY2F1c2U/OiB1bmtub3duO1xuICB9ID0ge30pIHtcbiAgICBzdXBlcih7IG1lc3NhZ2UsIHN0YXR1c0NvZGUsIGNhdXNlIH0pO1xuICB9XG5cbiAgc3RhdGljIGlzSW5zdGFuY2UoZXJyb3I6IHVua25vd24pOiBlcnJvciBpcyBHYXRld2F5UmF0ZUxpbWl0RXJyb3Ige1xuICAgIHJldHVybiBHYXRld2F5RXJyb3IuaGFzTWFya2VyKGVycm9yKSAmJiBzeW1ib2wgaW4gZXJyb3I7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyB6IH0gZnJvbSAnem9kL3Y0JztcbmltcG9ydCB7IEdhdGV3YXlFcnJvciB9IGZyb20gJy4vZ2F0ZXdheS1lcnJvcic7XG5pbXBvcnQgeyBsYXp5VmFsaWRhdG9yLCB6b2RTY2hlbWEgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyLXV0aWxzJztcblxuY29uc3QgbmFtZSA9ICdHYXRld2F5TW9kZWxOb3RGb3VuZEVycm9yJztcbmNvbnN0IG1hcmtlciA9IGB2ZXJjZWwuYWkuZ2F0ZXdheS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuZXhwb3J0IGNvbnN0IG1vZGVsTm90Rm91bmRQYXJhbVNjaGVtYSA9IGxhenlWYWxpZGF0b3IoKCkgPT5cbiAgem9kU2NoZW1hKFxuICAgIHoub2JqZWN0KHtcbiAgICAgIG1vZGVsSWQ6IHouc3RyaW5nKCksXG4gICAgfSksXG4gICksXG4pO1xuXG4vKipcbiAqIE1vZGVsIG5vdCBmb3VuZCBvciBub3QgYXZhaWxhYmxlXG4gKi9cbmV4cG9ydCBjbGFzcyBHYXRld2F5TW9kZWxOb3RGb3VuZEVycm9yIGV4dGVuZHMgR2F0ZXdheUVycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7IC8vIHVzZWQgaW4gaXNJbnN0YW5jZVxuXG4gIHJlYWRvbmx5IG5hbWUgPSBuYW1lO1xuICByZWFkb25seSB0eXBlID0gJ21vZGVsX25vdF9mb3VuZCc7XG4gIHJlYWRvbmx5IG1vZGVsSWQ/OiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIG1lc3NhZ2UgPSAnTW9kZWwgbm90IGZvdW5kJyxcbiAgICBzdGF0dXNDb2RlID0gNDA0LFxuICAgIG1vZGVsSWQsXG4gICAgY2F1c2UsXG4gIH06IHtcbiAgICBtZXNzYWdlPzogc3RyaW5nO1xuICAgIHN0YXR1c0NvZGU/OiBudW1iZXI7XG4gICAgbW9kZWxJZD86IHN0cmluZztcbiAgICBjYXVzZT86IHVua25vd247XG4gIH0gPSB7fSkge1xuICAgIHN1cGVyKHsgbWVzc2FnZSwgc3RhdHVzQ29kZSwgY2F1c2UgfSk7XG4gICAgdGhpcy5tb2RlbElkID0gbW9kZWxJZDtcbiAgfVxuXG4gIHN0YXRpYyBpc0luc3RhbmNlKGVycm9yOiB1bmtub3duKTogZXJyb3IgaXMgR2F0ZXdheU1vZGVsTm90Rm91bmRFcnJvciB7XG4gICAgcmV0dXJuIEdhdGV3YXlFcnJvci5oYXNNYXJrZXIoZXJyb3IpICYmIHN5bWJvbCBpbiBlcnJvcjtcbiAgfVxufVxuIiwgImltcG9ydCB7IEdhdGV3YXlFcnJvciB9IGZyb20gJy4vZ2F0ZXdheS1lcnJvcic7XG5cbmNvbnN0IG5hbWUgPSAnR2F0ZXdheUludGVybmFsU2VydmVyRXJyb3InO1xuY29uc3QgbWFya2VyID0gYHZlcmNlbC5haS5nYXRld2F5LmVycm9yLiR7bmFtZX1gO1xuY29uc3Qgc3ltYm9sID0gU3ltYm9sLmZvcihtYXJrZXIpO1xuXG4vKipcbiAqIEludGVybmFsIHNlcnZlciBlcnJvciBmcm9tIHRoZSBHYXRld2F5XG4gKi9cbmV4cG9ydCBjbGFzcyBHYXRld2F5SW50ZXJuYWxTZXJ2ZXJFcnJvciBleHRlbmRzIEdhdGV3YXlFcnJvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgW3N5bWJvbF0gPSB0cnVlOyAvLyB1c2VkIGluIGlzSW5zdGFuY2VcblxuICByZWFkb25seSBuYW1lID0gbmFtZTtcbiAgcmVhZG9ubHkgdHlwZSA9ICdpbnRlcm5hbF9zZXJ2ZXJfZXJyb3InO1xuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICBtZXNzYWdlID0gJ0ludGVybmFsIHNlcnZlciBlcnJvcicsXG4gICAgc3RhdHVzQ29kZSA9IDUwMCxcbiAgICBjYXVzZSxcbiAgfToge1xuICAgIG1lc3NhZ2U/OiBzdHJpbmc7XG4gICAgc3RhdHVzQ29kZT86IG51bWJlcjtcbiAgICBjYXVzZT86IHVua25vd247XG4gIH0gPSB7fSkge1xuICAgIHN1cGVyKHsgbWVzc2FnZSwgc3RhdHVzQ29kZSwgY2F1c2UgfSk7XG4gIH1cblxuICBzdGF0aWMgaXNJbnN0YW5jZShlcnJvcjogdW5rbm93bik6IGVycm9yIGlzIEdhdGV3YXlJbnRlcm5hbFNlcnZlckVycm9yIHtcbiAgICByZXR1cm4gR2F0ZXdheUVycm9yLmhhc01hcmtlcihlcnJvcikgJiYgc3ltYm9sIGluIGVycm9yO1xuICB9XG59XG4iLCAiaW1wb3J0IHsgVHlwZVZhbGlkYXRpb25FcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgR2F0ZXdheUVycm9yIH0gZnJvbSAnLi9nYXRld2F5LWVycm9yJztcblxuY29uc3QgbmFtZSA9ICdHYXRld2F5UmVzcG9uc2VFcnJvcic7XG5jb25zdCBtYXJrZXIgPSBgdmVyY2VsLmFpLmdhdGV3YXkuZXJyb3IuJHtuYW1lfWA7XG5jb25zdCBzeW1ib2wgPSBTeW1ib2wuZm9yKG1hcmtlcik7XG5cbi8qKlxuICogR2F0ZXdheSByZXNwb25zZSBwYXJzaW5nIGVycm9yXG4gKi9cbmV4cG9ydCBjbGFzcyBHYXRld2F5UmVzcG9uc2VFcnJvciBleHRlbmRzIEdhdGV3YXlFcnJvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgW3N5bWJvbF0gPSB0cnVlOyAvLyB1c2VkIGluIGlzSW5zdGFuY2VcblxuICByZWFkb25seSBuYW1lID0gbmFtZTtcbiAgcmVhZG9ubHkgdHlwZSA9ICdyZXNwb25zZV9lcnJvcic7XG4gIHJlYWRvbmx5IHJlc3BvbnNlPzogdW5rbm93bjtcbiAgcmVhZG9ubHkgdmFsaWRhdGlvbkVycm9yPzogVHlwZVZhbGlkYXRpb25FcnJvcjtcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgbWVzc2FnZSA9ICdJbnZhbGlkIHJlc3BvbnNlIGZyb20gR2F0ZXdheScsXG4gICAgc3RhdHVzQ29kZSA9IDUwMixcbiAgICByZXNwb25zZSxcbiAgICB2YWxpZGF0aW9uRXJyb3IsXG4gICAgY2F1c2UsXG4gIH06IHtcbiAgICBtZXNzYWdlPzogc3RyaW5nO1xuICAgIHN0YXR1c0NvZGU/OiBudW1iZXI7XG4gICAgcmVzcG9uc2U/OiB1bmtub3duO1xuICAgIHZhbGlkYXRpb25FcnJvcj86IFR5cGVWYWxpZGF0aW9uRXJyb3I7XG4gICAgY2F1c2U/OiB1bmtub3duO1xuICB9ID0ge30pIHtcbiAgICBzdXBlcih7IG1lc3NhZ2UsIHN0YXR1c0NvZGUsIGNhdXNlIH0pO1xuICAgIHRoaXMucmVzcG9uc2UgPSByZXNwb25zZTtcbiAgICB0aGlzLnZhbGlkYXRpb25FcnJvciA9IHZhbGlkYXRpb25FcnJvcjtcbiAgfVxuXG4gIHN0YXRpYyBpc0luc3RhbmNlKGVycm9yOiB1bmtub3duKTogZXJyb3IgaXMgR2F0ZXdheVJlc3BvbnNlRXJyb3Ige1xuICAgIHJldHVybiBHYXRld2F5RXJyb3IuaGFzTWFya2VyKGVycm9yKSAmJiBzeW1ib2wgaW4gZXJyb3I7XG4gIH1cbn1cbiIsICJpbXBvcnQgdHlwZSB7IEFQSUNhbGxFcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdEFwaUNhbGxSZXNwb25zZShlcnJvcjogQVBJQ2FsbEVycm9yKTogdW5rbm93biB7XG4gIGlmIChlcnJvci5kYXRhICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gZXJyb3IuZGF0YTtcbiAgfVxuICBpZiAoZXJyb3IucmVzcG9uc2VCb2R5ICE9IG51bGwpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIEpTT04ucGFyc2UoZXJyb3IucmVzcG9uc2VCb2R5KTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBlcnJvci5yZXNwb25zZUJvZHk7XG4gICAgfVxuICB9XG4gIHJldHVybiB7fTtcbn1cbiIsICJpbXBvcnQgeyB6IH0gZnJvbSAnem9kL3Y0JztcbmltcG9ydCB7XG4gIGxhenlWYWxpZGF0b3IsXG4gIHNhZmVWYWxpZGF0ZVR5cGVzLFxuICB6b2RTY2hlbWEsXG59IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXItdXRpbHMnO1xuXG5leHBvcnQgY29uc3QgR0FURVdBWV9BVVRIX01FVEhPRF9IRUFERVIgPSAnYWktZ2F0ZXdheS1hdXRoLW1ldGhvZCcgYXMgY29uc3Q7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwYXJzZUF1dGhNZXRob2QoXG4gIGhlYWRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD4sXG4pIHtcbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc2FmZVZhbGlkYXRlVHlwZXMoe1xuICAgIHZhbHVlOiBoZWFkZXJzW0dBVEVXQVlfQVVUSF9NRVRIT0RfSEVBREVSXSxcbiAgICBzY2hlbWE6IGdhdGV3YXlBdXRoTWV0aG9kU2NoZW1hLFxuICB9KTtcblxuICByZXR1cm4gcmVzdWx0LnN1Y2Nlc3MgPyByZXN1bHQudmFsdWUgOiB1bmRlZmluZWQ7XG59XG5cbmNvbnN0IGdhdGV3YXlBdXRoTWV0aG9kU2NoZW1hID0gbGF6eVZhbGlkYXRvcigoKSA9PlxuICB6b2RTY2hlbWEoei51bmlvbihbei5saXRlcmFsKCdhcGkta2V5JyksIHoubGl0ZXJhbCgnb2lkYycpXSkpLFxuKTtcbiIsICJpbXBvcnQge1xuICBjcmVhdGVKc29uRXJyb3JSZXNwb25zZUhhbmRsZXIsXG4gIGNyZWF0ZUpzb25SZXNwb25zZUhhbmRsZXIsXG4gIGdldEZyb21BcGksXG4gIGxhenlWYWxpZGF0b3IsXG4gIHJlc29sdmUsXG4gIHpvZFNjaGVtYSxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyB6IH0gZnJvbSAnem9kL3Y0JztcbmltcG9ydCB7IGFzR2F0ZXdheUVycm9yIH0gZnJvbSAnLi9lcnJvcnMnO1xuaW1wb3J0IHR5cGUgeyBHYXRld2F5Q29uZmlnIH0gZnJvbSAnLi9nYXRld2F5LWNvbmZpZyc7XG5pbXBvcnQgdHlwZSB7IEdhdGV3YXlMYW5ndWFnZU1vZGVsRW50cnkgfSBmcm9tICcuL2dhdGV3YXktbW9kZWwtZW50cnknO1xuXG50eXBlIEdhdGV3YXlGZXRjaE1ldGFkYXRhQ29uZmlnID0gR2F0ZXdheUNvbmZpZztcblxuZXhwb3J0IGludGVyZmFjZSBHYXRld2F5RmV0Y2hNZXRhZGF0YVJlc3BvbnNlIHtcbiAgbW9kZWxzOiBHYXRld2F5TGFuZ3VhZ2VNb2RlbEVudHJ5W107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2F0ZXdheUNyZWRpdHNSZXNwb25zZSB7XG4gIC8qKiBUaGUgcmVtYWluaW5nIGdhdGV3YXkgY3JlZGl0IGJhbGFuY2UgYXZhaWxhYmxlIGZvciBBUEkgdXNhZ2UgKi9cbiAgYmFsYW5jZTogc3RyaW5nO1xuICAvKiogVGhlIHRvdGFsIGFtb3VudCBvZiBnYXRld2F5IGNyZWRpdHMgdGhhdCBoYXZlIGJlZW4gY29uc3VtZWQgKi9cbiAgdG90YWxVc2VkOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBHYXRld2F5RmV0Y2hNZXRhZGF0YSB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgY29uZmlnOiBHYXRld2F5RmV0Y2hNZXRhZGF0YUNvbmZpZykge31cblxuICBhc3luYyBnZXRBdmFpbGFibGVNb2RlbHMoKTogUHJvbWlzZTxHYXRld2F5RmV0Y2hNZXRhZGF0YVJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHsgdmFsdWUgfSA9IGF3YWl0IGdldEZyb21BcGkoe1xuICAgICAgICB1cmw6IGAke3RoaXMuY29uZmlnLmJhc2VVUkx9L2NvbmZpZ2AsXG4gICAgICAgIGhlYWRlcnM6IGF3YWl0IHJlc29sdmUodGhpcy5jb25maWcuaGVhZGVycygpKSxcbiAgICAgICAgc3VjY2Vzc2Z1bFJlc3BvbnNlSGFuZGxlcjogY3JlYXRlSnNvblJlc3BvbnNlSGFuZGxlcihcbiAgICAgICAgICBnYXRld2F5QXZhaWxhYmxlTW9kZWxzUmVzcG9uc2VTY2hlbWEsXG4gICAgICAgICksXG4gICAgICAgIGZhaWxlZFJlc3BvbnNlSGFuZGxlcjogY3JlYXRlSnNvbkVycm9yUmVzcG9uc2VIYW5kbGVyKHtcbiAgICAgICAgICBlcnJvclNjaGVtYTogei5hbnkoKSxcbiAgICAgICAgICBlcnJvclRvTWVzc2FnZTogZGF0YSA9PiBkYXRhLFxuICAgICAgICB9KSxcbiAgICAgICAgZmV0Y2g6IHRoaXMuY29uZmlnLmZldGNoLFxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgYXdhaXQgYXNHYXRld2F5RXJyb3IoZXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGdldENyZWRpdHMoKTogUHJvbWlzZTxHYXRld2F5Q3JlZGl0c1Jlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGJhc2VVcmwgPSBuZXcgVVJMKHRoaXMuY29uZmlnLmJhc2VVUkwpO1xuXG4gICAgICBjb25zdCB7IHZhbHVlIH0gPSBhd2FpdCBnZXRGcm9tQXBpKHtcbiAgICAgICAgdXJsOiBgJHtiYXNlVXJsLm9yaWdpbn0vdjEvY3JlZGl0c2AsXG4gICAgICAgIGhlYWRlcnM6IGF3YWl0IHJlc29sdmUodGhpcy5jb25maWcuaGVhZGVycygpKSxcbiAgICAgICAgc3VjY2Vzc2Z1bFJlc3BvbnNlSGFuZGxlcjogY3JlYXRlSnNvblJlc3BvbnNlSGFuZGxlcihcbiAgICAgICAgICBnYXRld2F5Q3JlZGl0c1Jlc3BvbnNlU2NoZW1hLFxuICAgICAgICApLFxuICAgICAgICBmYWlsZWRSZXNwb25zZUhhbmRsZXI6IGNyZWF0ZUpzb25FcnJvclJlc3BvbnNlSGFuZGxlcih7XG4gICAgICAgICAgZXJyb3JTY2hlbWE6IHouYW55KCksXG4gICAgICAgICAgZXJyb3JUb01lc3NhZ2U6IGRhdGEgPT4gZGF0YSxcbiAgICAgICAgfSksXG4gICAgICAgIGZldGNoOiB0aGlzLmNvbmZpZy5mZXRjaCxcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRocm93IGF3YWl0IGFzR2F0ZXdheUVycm9yKGVycm9yKTtcbiAgICB9XG4gIH1cbn1cblxuY29uc3QgZ2F0ZXdheUF2YWlsYWJsZU1vZGVsc1Jlc3BvbnNlU2NoZW1hID0gbGF6eVZhbGlkYXRvcigoKSA9PlxuICB6b2RTY2hlbWEoXG4gICAgei5vYmplY3Qoe1xuICAgICAgbW9kZWxzOiB6LmFycmF5KFxuICAgICAgICB6Lm9iamVjdCh7XG4gICAgICAgICAgaWQ6IHouc3RyaW5nKCksXG4gICAgICAgICAgbmFtZTogei5zdHJpbmcoKSxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogei5zdHJpbmcoKS5udWxsaXNoKCksXG4gICAgICAgICAgcHJpY2luZzogelxuICAgICAgICAgICAgLm9iamVjdCh7XG4gICAgICAgICAgICAgIGlucHV0OiB6LnN0cmluZygpLFxuICAgICAgICAgICAgICBvdXRwdXQ6IHouc3RyaW5nKCksXG4gICAgICAgICAgICAgIGlucHV0X2NhY2hlX3JlYWQ6IHouc3RyaW5nKCkubnVsbGlzaCgpLFxuICAgICAgICAgICAgICBpbnB1dF9jYWNoZV93cml0ZTogei5zdHJpbmcoKS5udWxsaXNoKCksXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLnRyYW5zZm9ybShcbiAgICAgICAgICAgICAgKHsgaW5wdXQsIG91dHB1dCwgaW5wdXRfY2FjaGVfcmVhZCwgaW5wdXRfY2FjaGVfd3JpdGUgfSkgPT4gKHtcbiAgICAgICAgICAgICAgICBpbnB1dCxcbiAgICAgICAgICAgICAgICBvdXRwdXQsXG4gICAgICAgICAgICAgICAgLi4uKGlucHV0X2NhY2hlX3JlYWRcbiAgICAgICAgICAgICAgICAgID8geyBjYWNoZWRJbnB1dFRva2VuczogaW5wdXRfY2FjaGVfcmVhZCB9XG4gICAgICAgICAgICAgICAgICA6IHt9KSxcbiAgICAgICAgICAgICAgICAuLi4oaW5wdXRfY2FjaGVfd3JpdGVcbiAgICAgICAgICAgICAgICAgID8geyBjYWNoZUNyZWF0aW9uSW5wdXRUb2tlbnM6IGlucHV0X2NhY2hlX3dyaXRlIH1cbiAgICAgICAgICAgICAgICAgIDoge30pLFxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIC5udWxsaXNoKCksXG4gICAgICAgICAgc3BlY2lmaWNhdGlvbjogei5vYmplY3Qoe1xuICAgICAgICAgICAgc3BlY2lmaWNhdGlvblZlcnNpb246IHoubGl0ZXJhbCgndjInKSxcbiAgICAgICAgICAgIHByb3ZpZGVyOiB6LnN0cmluZygpLFxuICAgICAgICAgICAgbW9kZWxJZDogei5zdHJpbmcoKSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBtb2RlbFR5cGU6IHouZW51bShbJ2xhbmd1YWdlJywgJ2VtYmVkZGluZycsICdpbWFnZSddKS5udWxsaXNoKCksXG4gICAgICAgIH0pLFxuICAgICAgKSxcbiAgICB9KSxcbiAgKSxcbik7XG5cbmNvbnN0IGdhdGV3YXlDcmVkaXRzUmVzcG9uc2VTY2hlbWEgPSBsYXp5VmFsaWRhdG9yKCgpID0+XG4gIHpvZFNjaGVtYShcbiAgICB6XG4gICAgICAub2JqZWN0KHtcbiAgICAgICAgYmFsYW5jZTogei5zdHJpbmcoKSxcbiAgICAgICAgdG90YWxfdXNlZDogei5zdHJpbmcoKSxcbiAgICAgIH0pXG4gICAgICAudHJhbnNmb3JtKCh7IGJhbGFuY2UsIHRvdGFsX3VzZWQgfSkgPT4gKHtcbiAgICAgICAgYmFsYW5jZSxcbiAgICAgICAgdG90YWxVc2VkOiB0b3RhbF91c2VkLFxuICAgICAgfSkpLFxuICApLFxuKTtcbiIsICJpbXBvcnQgdHlwZSB7XG4gIExhbmd1YWdlTW9kZWxWMixcbiAgTGFuZ3VhZ2VNb2RlbFYyQ2FsbE9wdGlvbnMsXG4gIExhbmd1YWdlTW9kZWxWMkNhbGxXYXJuaW5nLFxuICBMYW5ndWFnZU1vZGVsVjJGaWxlUGFydCxcbiAgTGFuZ3VhZ2VNb2RlbFYyU3RyZWFtUGFydCxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQge1xuICBjb21iaW5lSGVhZGVycyxcbiAgY3JlYXRlRXZlbnRTb3VyY2VSZXNwb25zZUhhbmRsZXIsXG4gIGNyZWF0ZUpzb25FcnJvclJlc3BvbnNlSGFuZGxlcixcbiAgY3JlYXRlSnNvblJlc3BvbnNlSGFuZGxlcixcbiAgcG9zdEpzb25Ub0FwaSxcbiAgcmVzb2x2ZSxcbiAgdHlwZSBQYXJzZVJlc3VsdCxcbiAgdHlwZSBSZXNvbHZhYmxlLFxufSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyLXV0aWxzJztcbmltcG9ydCB7IHogfSBmcm9tICd6b2QvdjQnO1xuaW1wb3J0IHR5cGUgeyBHYXRld2F5Q29uZmlnIH0gZnJvbSAnLi9nYXRld2F5LWNvbmZpZyc7XG5pbXBvcnQgdHlwZSB7IEdhdGV3YXlNb2RlbElkIH0gZnJvbSAnLi9nYXRld2F5LWxhbmd1YWdlLW1vZGVsLXNldHRpbmdzJztcbmltcG9ydCB7IGFzR2F0ZXdheUVycm9yIH0gZnJvbSAnLi9lcnJvcnMnO1xuaW1wb3J0IHsgcGFyc2VBdXRoTWV0aG9kIH0gZnJvbSAnLi9lcnJvcnMvcGFyc2UtYXV0aC1tZXRob2QnO1xuXG50eXBlIEdhdGV3YXlDaGF0Q29uZmlnID0gR2F0ZXdheUNvbmZpZyAmIHtcbiAgcHJvdmlkZXI6IHN0cmluZztcbiAgbzExeUhlYWRlcnM6IFJlc29sdmFibGU8UmVjb3JkPHN0cmluZywgc3RyaW5nPj47XG59O1xuXG5leHBvcnQgY2xhc3MgR2F0ZXdheUxhbmd1YWdlTW9kZWwgaW1wbGVtZW50cyBMYW5ndWFnZU1vZGVsVjIge1xuICByZWFkb25seSBzcGVjaWZpY2F0aW9uVmVyc2lvbiA9ICd2Mic7XG4gIHJlYWRvbmx5IHN1cHBvcnRlZFVybHMgPSB7ICcqLyonOiBbLy4qL10gfTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICByZWFkb25seSBtb2RlbElkOiBHYXRld2F5TW9kZWxJZCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNvbmZpZzogR2F0ZXdheUNoYXRDb25maWcsXG4gICkge31cblxuICBnZXQgcHJvdmlkZXIoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5jb25maWcucHJvdmlkZXI7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGdldEFyZ3Mob3B0aW9uczogUGFyYW1ldGVyczxMYW5ndWFnZU1vZGVsVjJbJ2RvR2VuZXJhdGUnXT5bMF0pIHtcbiAgICBjb25zdCB7IGFib3J0U2lnbmFsOiBfYWJvcnRTaWduYWwsIC4uLm9wdGlvbnNXaXRob3V0U2lnbmFsIH0gPSBvcHRpb25zO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGFyZ3M6IHRoaXMubWF5YmVFbmNvZGVGaWxlUGFydHMob3B0aW9uc1dpdGhvdXRTaWduYWwpLFxuICAgICAgd2FybmluZ3M6IFtdLFxuICAgIH07XG4gIH1cblxuICBhc3luYyBkb0dlbmVyYXRlKFxuICAgIG9wdGlvbnM6IFBhcmFtZXRlcnM8TGFuZ3VhZ2VNb2RlbFYyWydkb0dlbmVyYXRlJ10+WzBdLFxuICApOiBQcm9taXNlPEF3YWl0ZWQ8UmV0dXJuVHlwZTxMYW5ndWFnZU1vZGVsVjJbJ2RvR2VuZXJhdGUnXT4+PiB7XG4gICAgY29uc3QgeyBhcmdzLCB3YXJuaW5ncyB9ID0gYXdhaXQgdGhpcy5nZXRBcmdzKG9wdGlvbnMpO1xuICAgIGNvbnN0IHsgYWJvcnRTaWduYWwgfSA9IG9wdGlvbnM7XG5cbiAgICBjb25zdCByZXNvbHZlZEhlYWRlcnMgPSBhd2FpdCByZXNvbHZlKHRoaXMuY29uZmlnLmhlYWRlcnMoKSk7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3Qge1xuICAgICAgICByZXNwb25zZUhlYWRlcnMsXG4gICAgICAgIHZhbHVlOiByZXNwb25zZUJvZHksXG4gICAgICAgIHJhd1ZhbHVlOiByYXdSZXNwb25zZSxcbiAgICAgIH0gPSBhd2FpdCBwb3N0SnNvblRvQXBpKHtcbiAgICAgICAgdXJsOiB0aGlzLmdldFVybCgpLFxuICAgICAgICBoZWFkZXJzOiBjb21iaW5lSGVhZGVycyhcbiAgICAgICAgICByZXNvbHZlZEhlYWRlcnMsXG4gICAgICAgICAgb3B0aW9ucy5oZWFkZXJzLFxuICAgICAgICAgIHRoaXMuZ2V0TW9kZWxDb25maWdIZWFkZXJzKHRoaXMubW9kZWxJZCwgZmFsc2UpLFxuICAgICAgICAgIGF3YWl0IHJlc29sdmUodGhpcy5jb25maWcubzExeUhlYWRlcnMpLFxuICAgICAgICApLFxuICAgICAgICBib2R5OiBhcmdzLFxuICAgICAgICBzdWNjZXNzZnVsUmVzcG9uc2VIYW5kbGVyOiBjcmVhdGVKc29uUmVzcG9uc2VIYW5kbGVyKHouYW55KCkpLFxuICAgICAgICBmYWlsZWRSZXNwb25zZUhhbmRsZXI6IGNyZWF0ZUpzb25FcnJvclJlc3BvbnNlSGFuZGxlcih7XG4gICAgICAgICAgZXJyb3JTY2hlbWE6IHouYW55KCksXG4gICAgICAgICAgZXJyb3JUb01lc3NhZ2U6IGRhdGEgPT4gZGF0YSxcbiAgICAgICAgfSksXG4gICAgICAgIC4uLihhYm9ydFNpZ25hbCAmJiB7IGFib3J0U2lnbmFsIH0pLFxuICAgICAgICBmZXRjaDogdGhpcy5jb25maWcuZmV0Y2gsXG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ucmVzcG9uc2VCb2R5LFxuICAgICAgICByZXF1ZXN0OiB7IGJvZHk6IGFyZ3MgfSxcbiAgICAgICAgcmVzcG9uc2U6IHsgaGVhZGVyczogcmVzcG9uc2VIZWFkZXJzLCBib2R5OiByYXdSZXNwb25zZSB9LFxuICAgICAgICB3YXJuaW5ncyxcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRocm93IGF3YWl0IGFzR2F0ZXdheUVycm9yKGVycm9yLCBhd2FpdCBwYXJzZUF1dGhNZXRob2QocmVzb2x2ZWRIZWFkZXJzKSk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZG9TdHJlYW0oXG4gICAgb3B0aW9uczogUGFyYW1ldGVyczxMYW5ndWFnZU1vZGVsVjJbJ2RvU3RyZWFtJ10+WzBdLFxuICApOiBQcm9taXNlPEF3YWl0ZWQ8UmV0dXJuVHlwZTxMYW5ndWFnZU1vZGVsVjJbJ2RvU3RyZWFtJ10+Pj4ge1xuICAgIGNvbnN0IHsgYXJncywgd2FybmluZ3MgfSA9IGF3YWl0IHRoaXMuZ2V0QXJncyhvcHRpb25zKTtcbiAgICBjb25zdCB7IGFib3J0U2lnbmFsIH0gPSBvcHRpb25zO1xuXG4gICAgY29uc3QgcmVzb2x2ZWRIZWFkZXJzID0gYXdhaXQgcmVzb2x2ZSh0aGlzLmNvbmZpZy5oZWFkZXJzKCkpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHsgdmFsdWU6IHJlc3BvbnNlLCByZXNwb25zZUhlYWRlcnMgfSA9IGF3YWl0IHBvc3RKc29uVG9BcGkoe1xuICAgICAgICB1cmw6IHRoaXMuZ2V0VXJsKCksXG4gICAgICAgIGhlYWRlcnM6IGNvbWJpbmVIZWFkZXJzKFxuICAgICAgICAgIHJlc29sdmVkSGVhZGVycyxcbiAgICAgICAgICBvcHRpb25zLmhlYWRlcnMsXG4gICAgICAgICAgdGhpcy5nZXRNb2RlbENvbmZpZ0hlYWRlcnModGhpcy5tb2RlbElkLCB0cnVlKSxcbiAgICAgICAgICBhd2FpdCByZXNvbHZlKHRoaXMuY29uZmlnLm8xMXlIZWFkZXJzKSxcbiAgICAgICAgKSxcbiAgICAgICAgYm9keTogYXJncyxcbiAgICAgICAgc3VjY2Vzc2Z1bFJlc3BvbnNlSGFuZGxlcjogY3JlYXRlRXZlbnRTb3VyY2VSZXNwb25zZUhhbmRsZXIoei5hbnkoKSksXG4gICAgICAgIGZhaWxlZFJlc3BvbnNlSGFuZGxlcjogY3JlYXRlSnNvbkVycm9yUmVzcG9uc2VIYW5kbGVyKHtcbiAgICAgICAgICBlcnJvclNjaGVtYTogei5hbnkoKSxcbiAgICAgICAgICBlcnJvclRvTWVzc2FnZTogZGF0YSA9PiBkYXRhLFxuICAgICAgICB9KSxcbiAgICAgICAgLi4uKGFib3J0U2lnbmFsICYmIHsgYWJvcnRTaWduYWwgfSksXG4gICAgICAgIGZldGNoOiB0aGlzLmNvbmZpZy5mZXRjaCxcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBzdHJlYW06IHJlc3BvbnNlLnBpcGVUaHJvdWdoKFxuICAgICAgICAgIG5ldyBUcmFuc2Zvcm1TdHJlYW08XG4gICAgICAgICAgICBQYXJzZVJlc3VsdDxMYW5ndWFnZU1vZGVsVjJTdHJlYW1QYXJ0PixcbiAgICAgICAgICAgIExhbmd1YWdlTW9kZWxWMlN0cmVhbVBhcnRcbiAgICAgICAgICA+KHtcbiAgICAgICAgICAgIHN0YXJ0KGNvbnRyb2xsZXIpIHtcbiAgICAgICAgICAgICAgaWYgKHdhcm5pbmdzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoeyB0eXBlOiAnc3RyZWFtLXN0YXJ0Jywgd2FybmluZ3MgfSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0cmFuc2Zvcm0oY2h1bmssIGNvbnRyb2xsZXIpIHtcbiAgICAgICAgICAgICAgaWYgKGNodW5rLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW1QYXJ0ID0gY2h1bmsudmFsdWU7XG5cbiAgICAgICAgICAgICAgICAvLyBIYW5kbGUgcmF3IGNodW5rczogaWYgdGhpcyBpcyBhIHJhdyBjaHVuayBmcm9tIHRoZSBnYXRld2F5IEFQSSxcbiAgICAgICAgICAgICAgICAvLyBvbmx5IGVtaXQgaXQgaWYgaW5jbHVkZVJhd0NodW5rcyBpcyB0cnVlXG4gICAgICAgICAgICAgICAgaWYgKHN0cmVhbVBhcnQudHlwZSA9PT0gJ3JhdycgJiYgIW9wdGlvbnMuaW5jbHVkZVJhd0NodW5rcykge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuOyAvLyBTa2lwIHJhdyBjaHVua3MgaWYgbm90IHJlcXVlc3RlZFxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgIHN0cmVhbVBhcnQudHlwZSA9PT0gJ3Jlc3BvbnNlLW1ldGFkYXRhJyAmJlxuICAgICAgICAgICAgICAgICAgc3RyZWFtUGFydC50aW1lc3RhbXAgJiZcbiAgICAgICAgICAgICAgICAgIHR5cGVvZiBzdHJlYW1QYXJ0LnRpbWVzdGFtcCA9PT0gJ3N0cmluZydcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgIHN0cmVhbVBhcnQudGltZXN0YW1wID0gbmV3IERhdGUoc3RyZWFtUGFydC50aW1lc3RhbXApO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShzdHJlYW1QYXJ0KTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVycm9yKFxuICAgICAgICAgICAgICAgICAgKGNodW5rIGFzIHsgc3VjY2VzczogZmFsc2U7IGVycm9yOiB1bmtub3duIH0pLmVycm9yLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSksXG4gICAgICAgICksXG4gICAgICAgIHJlcXVlc3Q6IHsgYm9keTogYXJncyB9LFxuICAgICAgICByZXNwb25zZTogeyBoZWFkZXJzOiByZXNwb25zZUhlYWRlcnMgfSxcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRocm93IGF3YWl0IGFzR2F0ZXdheUVycm9yKGVycm9yLCBhd2FpdCBwYXJzZUF1dGhNZXRob2QocmVzb2x2ZWRIZWFkZXJzKSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBpc0ZpbGVQYXJ0KHBhcnQ6IHVua25vd24pIHtcbiAgICByZXR1cm4gKFxuICAgICAgcGFydCAmJiB0eXBlb2YgcGFydCA9PT0gJ29iamVjdCcgJiYgJ3R5cGUnIGluIHBhcnQgJiYgcGFydC50eXBlID09PSAnZmlsZSdcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEVuY29kZXMgZmlsZSBwYXJ0cyBpbiB0aGUgcHJvbXB0IHRvIGJhc2U2NC4gTXV0YXRlcyB0aGUgcGFzc2VkIG9wdGlvbnNcbiAgICogaW5zdGFuY2UgZGlyZWN0bHkgdG8gYXZvaWQgY29weWluZyB0aGUgZmlsZSBkYXRhLlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIFRoZSBvcHRpb25zIHRvIGVuY29kZS5cbiAgICogQHJldHVybnMgVGhlIG9wdGlvbnMgd2l0aCB0aGUgZmlsZSBwYXJ0cyBlbmNvZGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBtYXliZUVuY29kZUZpbGVQYXJ0cyhvcHRpb25zOiBMYW5ndWFnZU1vZGVsVjJDYWxsT3B0aW9ucykge1xuICAgIGZvciAoY29uc3QgbWVzc2FnZSBvZiBvcHRpb25zLnByb21wdCkge1xuICAgICAgZm9yIChjb25zdCBwYXJ0IG9mIG1lc3NhZ2UuY29udGVudCkge1xuICAgICAgICBpZiAodGhpcy5pc0ZpbGVQYXJ0KHBhcnQpKSB7XG4gICAgICAgICAgY29uc3QgZmlsZVBhcnQgPSBwYXJ0IGFzIExhbmd1YWdlTW9kZWxWMkZpbGVQYXJ0O1xuICAgICAgICAgIC8vIElmIHRoZSBmaWxlIHBhcnQgaXMgYSBVUkwgaXQgd2lsbCBnZXQgY2xlYW5seSBjb252ZXJ0ZWQgdG8gYSBzdHJpbmcuXG4gICAgICAgICAgLy8gSWYgaXQncyBhIGJpbmFyeSBmaWxlIGF0dGFjaG1lbnQgd2UgY29udmVydCBpdCB0byBhIGRhdGEgdXJsLlxuICAgICAgICAgIC8vIEluIGVpdGhlciBjYXNlLCBzZXJ2ZXItc2lkZSB3ZSBzaG91bGQgb25seSBldmVyIHNlZSBVUkxzIGFzIHN0cmluZ3MuXG4gICAgICAgICAgaWYgKGZpbGVQYXJ0LmRhdGEgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XG4gICAgICAgICAgICBjb25zdCBidWZmZXIgPSBVaW50OEFycmF5LmZyb20oZmlsZVBhcnQuZGF0YSk7XG4gICAgICAgICAgICBjb25zdCBiYXNlNjREYXRhID0gQnVmZmVyLmZyb20oYnVmZmVyKS50b1N0cmluZygnYmFzZTY0Jyk7XG4gICAgICAgICAgICBmaWxlUGFydC5kYXRhID0gbmV3IFVSTChcbiAgICAgICAgICAgICAgYGRhdGE6JHtmaWxlUGFydC5tZWRpYVR5cGUgfHwgJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSd9O2Jhc2U2NCwke2Jhc2U2NERhdGF9YCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvcHRpb25zO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRVcmwoKSB7XG4gICAgcmV0dXJuIGAke3RoaXMuY29uZmlnLmJhc2VVUkx9L2xhbmd1YWdlLW1vZGVsYDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0TW9kZWxDb25maWdIZWFkZXJzKG1vZGVsSWQ6IHN0cmluZywgc3RyZWFtaW5nOiBib29sZWFuKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICdhaS1sYW5ndWFnZS1tb2RlbC1zcGVjaWZpY2F0aW9uLXZlcnNpb24nOiAnMicsXG4gICAgICAnYWktbGFuZ3VhZ2UtbW9kZWwtaWQnOiBtb2RlbElkLFxuICAgICAgJ2FpLWxhbmd1YWdlLW1vZGVsLXN0cmVhbWluZyc6IFN0cmluZyhzdHJlYW1pbmcpLFxuICAgIH07XG4gIH1cbn1cbiIsICJpbXBvcnQgdHlwZSB7XG4gIEVtYmVkZGluZ01vZGVsVjIsXG4gIFNoYXJlZFYyUHJvdmlkZXJNZXRhZGF0YSxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQge1xuICBjb21iaW5lSGVhZGVycyxcbiAgY3JlYXRlSnNvbkVycm9yUmVzcG9uc2VIYW5kbGVyLFxuICBjcmVhdGVKc29uUmVzcG9uc2VIYW5kbGVyLFxuICBsYXp5VmFsaWRhdG9yLFxuICBwb3N0SnNvblRvQXBpLFxuICByZXNvbHZlLFxuICB6b2RTY2hlbWEsXG4gIHR5cGUgUmVzb2x2YWJsZSxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyB6IH0gZnJvbSAnem9kL3Y0JztcbmltcG9ydCB7IGFzR2F0ZXdheUVycm9yIH0gZnJvbSAnLi9lcnJvcnMnO1xuaW1wb3J0IHsgcGFyc2VBdXRoTWV0aG9kIH0gZnJvbSAnLi9lcnJvcnMvcGFyc2UtYXV0aC1tZXRob2QnO1xuaW1wb3J0IHR5cGUgeyBHYXRld2F5Q29uZmlnIH0gZnJvbSAnLi9nYXRld2F5LWNvbmZpZyc7XG5cbmV4cG9ydCBjbGFzcyBHYXRld2F5RW1iZWRkaW5nTW9kZWwgaW1wbGVtZW50cyBFbWJlZGRpbmdNb2RlbFYyPHN0cmluZz4ge1xuICByZWFkb25seSBzcGVjaWZpY2F0aW9uVmVyc2lvbiA9ICd2Mic7XG4gIHJlYWRvbmx5IG1heEVtYmVkZGluZ3NQZXJDYWxsID0gMjA0ODtcbiAgcmVhZG9ubHkgc3VwcG9ydHNQYXJhbGxlbENhbGxzID0gdHJ1ZTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICByZWFkb25seSBtb2RlbElkOiBzdHJpbmcsXG4gICAgcHJpdmF0ZSByZWFkb25seSBjb25maWc6IEdhdGV3YXlDb25maWcgJiB7XG4gICAgICBwcm92aWRlcjogc3RyaW5nO1xuICAgICAgbzExeUhlYWRlcnM6IFJlc29sdmFibGU8UmVjb3JkPHN0cmluZywgc3RyaW5nPj47XG4gICAgfSxcbiAgKSB7fVxuXG4gIGdldCBwcm92aWRlcigpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmNvbmZpZy5wcm92aWRlcjtcbiAgfVxuXG4gIGFzeW5jIGRvRW1iZWQoe1xuICAgIHZhbHVlcyxcbiAgICBoZWFkZXJzLFxuICAgIGFib3J0U2lnbmFsLFxuICAgIHByb3ZpZGVyT3B0aW9ucyxcbiAgfTogUGFyYW1ldGVyczxFbWJlZGRpbmdNb2RlbFYyPHN0cmluZz5bJ2RvRW1iZWQnXT5bMF0pOiBQcm9taXNlPFxuICAgIEF3YWl0ZWQ8UmV0dXJuVHlwZTxFbWJlZGRpbmdNb2RlbFYyPHN0cmluZz5bJ2RvRW1iZWQnXT4+XG4gID4ge1xuICAgIGNvbnN0IHJlc29sdmVkSGVhZGVycyA9IGF3YWl0IHJlc29sdmUodGhpcy5jb25maWcuaGVhZGVycygpKTtcbiAgICB0cnkge1xuICAgICAgY29uc3Qge1xuICAgICAgICByZXNwb25zZUhlYWRlcnMsXG4gICAgICAgIHZhbHVlOiByZXNwb25zZUJvZHksXG4gICAgICAgIHJhd1ZhbHVlLFxuICAgICAgfSA9IGF3YWl0IHBvc3RKc29uVG9BcGkoe1xuICAgICAgICB1cmw6IHRoaXMuZ2V0VXJsKCksXG4gICAgICAgIGhlYWRlcnM6IGNvbWJpbmVIZWFkZXJzKFxuICAgICAgICAgIHJlc29sdmVkSGVhZGVycyxcbiAgICAgICAgICBoZWFkZXJzID8/IHt9LFxuICAgICAgICAgIHRoaXMuZ2V0TW9kZWxDb25maWdIZWFkZXJzKCksXG4gICAgICAgICAgYXdhaXQgcmVzb2x2ZSh0aGlzLmNvbmZpZy5vMTF5SGVhZGVycyksXG4gICAgICAgICksXG4gICAgICAgIGJvZHk6IHtcbiAgICAgICAgICBpbnB1dDogdmFsdWVzLmxlbmd0aCA9PT0gMSA/IHZhbHVlc1swXSA6IHZhbHVlcyxcbiAgICAgICAgICAuLi4ocHJvdmlkZXJPcHRpb25zID8geyBwcm92aWRlck9wdGlvbnMgfSA6IHt9KSxcbiAgICAgICAgfSxcbiAgICAgICAgc3VjY2Vzc2Z1bFJlc3BvbnNlSGFuZGxlcjogY3JlYXRlSnNvblJlc3BvbnNlSGFuZGxlcihcbiAgICAgICAgICBnYXRld2F5RW1iZWRkaW5nUmVzcG9uc2VTY2hlbWEsXG4gICAgICAgICksXG4gICAgICAgIGZhaWxlZFJlc3BvbnNlSGFuZGxlcjogY3JlYXRlSnNvbkVycm9yUmVzcG9uc2VIYW5kbGVyKHtcbiAgICAgICAgICBlcnJvclNjaGVtYTogei5hbnkoKSxcbiAgICAgICAgICBlcnJvclRvTWVzc2FnZTogZGF0YSA9PiBkYXRhLFxuICAgICAgICB9KSxcbiAgICAgICAgLi4uKGFib3J0U2lnbmFsICYmIHsgYWJvcnRTaWduYWwgfSksXG4gICAgICAgIGZldGNoOiB0aGlzLmNvbmZpZy5mZXRjaCxcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBlbWJlZGRpbmdzOiByZXNwb25zZUJvZHkuZW1iZWRkaW5ncyxcbiAgICAgICAgdXNhZ2U6IHJlc3BvbnNlQm9keS51c2FnZSA/PyB1bmRlZmluZWQsXG4gICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6XG4gICAgICAgICAgcmVzcG9uc2VCb2R5LnByb3ZpZGVyTWV0YWRhdGEgYXMgdW5rbm93biBhcyBTaGFyZWRWMlByb3ZpZGVyTWV0YWRhdGEsXG4gICAgICAgIHJlc3BvbnNlOiB7IGhlYWRlcnM6IHJlc3BvbnNlSGVhZGVycywgYm9keTogcmF3VmFsdWUgfSxcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRocm93IGF3YWl0IGFzR2F0ZXdheUVycm9yKGVycm9yLCBhd2FpdCBwYXJzZUF1dGhNZXRob2QocmVzb2x2ZWRIZWFkZXJzKSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRVcmwoKSB7XG4gICAgcmV0dXJuIGAke3RoaXMuY29uZmlnLmJhc2VVUkx9L2VtYmVkZGluZy1tb2RlbGA7XG4gIH1cblxuICBwcml2YXRlIGdldE1vZGVsQ29uZmlnSGVhZGVycygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgJ2FpLWVtYmVkZGluZy1tb2RlbC1zcGVjaWZpY2F0aW9uLXZlcnNpb24nOiAnMicsXG4gICAgICAnYWktbW9kZWwtaWQnOiB0aGlzLm1vZGVsSWQsXG4gICAgfTtcbiAgfVxufVxuXG5jb25zdCBnYXRld2F5RW1iZWRkaW5nUmVzcG9uc2VTY2hlbWEgPSBsYXp5VmFsaWRhdG9yKCgpID0+XG4gIHpvZFNjaGVtYShcbiAgICB6Lm9iamVjdCh7XG4gICAgICBlbWJlZGRpbmdzOiB6LmFycmF5KHouYXJyYXkoei5udW1iZXIoKSkpLFxuICAgICAgdXNhZ2U6IHoub2JqZWN0KHsgdG9rZW5zOiB6Lm51bWJlcigpIH0pLm51bGxpc2goKSxcbiAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHpcbiAgICAgICAgLnJlY29yZCh6LnN0cmluZygpLCB6LnJlY29yZCh6LnN0cmluZygpLCB6LnVua25vd24oKSkpXG4gICAgICAgIC5vcHRpb25hbCgpLFxuICAgIH0pLFxuICApLFxuKTtcbiIsICJpbXBvcnQgeyBnZXRDb250ZXh0IH0gZnJvbSAnQHZlcmNlbC9vaWRjJztcbmV4cG9ydCB7IGdldFZlcmNlbE9pZGNUb2tlbiB9IGZyb20gJ0B2ZXJjZWwvb2lkYyc7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRWZXJjZWxSZXF1ZXN0SWQoKTogUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgcmV0dXJuIGdldENvbnRleHQoKS5oZWFkZXJzPy5bJ3gtdmVyY2VsLWlkJ107XG59XG4iLCAiLy8gVmVyc2lvbiBzdHJpbmcgb2YgdGhpcyBwYWNrYWdlIGluamVjdGVkIGF0IGJ1aWxkIHRpbWUuXG5kZWNsYXJlIGNvbnN0IF9fUEFDS0FHRV9WRVJTSU9OX186IHN0cmluZyB8IHVuZGVmaW5lZDtcbmV4cG9ydCBjb25zdCBWRVJTSU9OOiBzdHJpbmcgPVxuICB0eXBlb2YgX19QQUNLQUdFX1ZFUlNJT05fXyAhPT0gJ3VuZGVmaW5lZCdcbiAgICA/IF9fUEFDS0FHRV9WRVJTSU9OX19cbiAgICA6ICcwLjAuMC10ZXN0JztcbiIsICIvLyByZS1leHBvcnRzOlxuZXhwb3J0IHsgZ2F0ZXdheSwgY3JlYXRlR2F0ZXdheSB9IGZyb20gJ0BhaS1zZGsvZ2F0ZXdheSc7XG5leHBvcnQge1xuICBhc1NjaGVtYSxcbiAgY3JlYXRlSWRHZW5lcmF0b3IsXG4gIGR5bmFtaWNUb29sLFxuICBnZW5lcmF0ZUlkLFxuICBqc29uU2NoZW1hLFxuICBwYXJzZUpzb25FdmVudFN0cmVhbSxcbiAgdG9vbCxcbiAgem9kU2NoZW1hLFxuICB0eXBlIElkR2VuZXJhdG9yLFxuICB0eXBlIEluZmVyVG9vbElucHV0LFxuICB0eXBlIEluZmVyVG9vbE91dHB1dCxcbiAgdHlwZSBTY2hlbWEsXG4gIHR5cGUgVG9vbCxcbiAgdHlwZSBUb29sQ2FsbE9wdGlvbnMsXG4gIHR5cGUgVG9vbEV4ZWN1dGVGdW5jdGlvbixcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5cbi8vIGRpcmVjdG9yeSBleHBvcnRzXG5leHBvcnQgKiBmcm9tICcuL2FnZW50JztcbmV4cG9ydCAqIGZyb20gJy4vZW1iZWQnO1xuZXhwb3J0ICogZnJvbSAnLi9lcnJvcic7XG5leHBvcnQgKiBmcm9tICcuL2dlbmVyYXRlLWltYWdlJztcbmV4cG9ydCAqIGZyb20gJy4vZ2VuZXJhdGUtb2JqZWN0JztcbmV4cG9ydCAqIGZyb20gJy4vZ2VuZXJhdGUtc3BlZWNoJztcbmV4cG9ydCAqIGZyb20gJy4vZ2VuZXJhdGUtdGV4dCc7XG5leHBvcnQgKiBmcm9tICcuL2xvZ2dlcic7XG5leHBvcnQgKiBmcm9tICcuL21pZGRsZXdhcmUnO1xuZXhwb3J0ICogZnJvbSAnLi9wcm9tcHQnO1xuZXhwb3J0ICogZnJvbSAnLi9yZWdpc3RyeSc7XG5leHBvcnQgKiBmcm9tICcuL3RleHQtc3RyZWFtJztcbmV4cG9ydCAqIGZyb20gJy4vdG9vbCc7XG5leHBvcnQgKiBmcm9tICcuL3RyYW5zY3JpYmUnO1xuZXhwb3J0ICogZnJvbSAnLi90eXBlcyc7XG5leHBvcnQgKiBmcm9tICcuL3VpJztcbmV4cG9ydCAqIGZyb20gJy4vdWktbWVzc2FnZS1zdHJlYW0nO1xuZXhwb3J0ICogZnJvbSAnLi91dGlsJztcblxuLy8gdGVsZW1ldHJ5IHR5cGVzOlxuZXhwb3J0IHR5cGUgeyBUZWxlbWV0cnlTZXR0aW5ncyB9IGZyb20gJy4vdGVsZW1ldHJ5L3RlbGVtZXRyeS1zZXR0aW5ncyc7XG5cbi8vIGltcG9ydCBnbG9iYWxzXG5pbXBvcnQgJy4vZ2xvYmFsJztcbiIsICJpbXBvcnQge1xuICBMYW5ndWFnZU1vZGVsVjIsXG4gIExhbmd1YWdlTW9kZWxWMkNvbnRlbnQsXG4gIExhbmd1YWdlTW9kZWxWMlRvb2xDYWxsLFxufSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcbmltcG9ydCB7XG4gIGNyZWF0ZUlkR2VuZXJhdG9yLFxuICBleGVjdXRlVG9vbCxcbiAgZ2V0RXJyb3JNZXNzYWdlLFxuICBJZEdlbmVyYXRvcixcbiAgUHJvdmlkZXJPcHRpb25zLFxuICB3aXRoVXNlckFnZW50U3VmZml4LFxufSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyLXV0aWxzJztcbmltcG9ydCB7IFRyYWNlciB9IGZyb20gJ0BvcGVudGVsZW1ldHJ5L2FwaSc7XG5pbXBvcnQgeyBOb091dHB1dFNwZWNpZmllZEVycm9yIH0gZnJvbSAnLi4vZXJyb3Ivbm8tb3V0cHV0LXNwZWNpZmllZC1lcnJvcic7XG5pbXBvcnQgeyBsb2dXYXJuaW5ncyB9IGZyb20gJy4uL2xvZ2dlci9sb2ctd2FybmluZ3MnO1xuaW1wb3J0IHsgcmVzb2x2ZUxhbmd1YWdlTW9kZWwgfSBmcm9tICcuLi9tb2RlbC9yZXNvbHZlLW1vZGVsJztcbmltcG9ydCB7IE1vZGVsTWVzc2FnZSB9IGZyb20gJy4uL3Byb21wdCc7XG5pbXBvcnQgeyBDYWxsU2V0dGluZ3MgfSBmcm9tICcuLi9wcm9tcHQvY2FsbC1zZXR0aW5ncyc7XG5pbXBvcnQgeyBjb252ZXJ0VG9MYW5ndWFnZU1vZGVsUHJvbXB0IH0gZnJvbSAnLi4vcHJvbXB0L2NvbnZlcnQtdG8tbGFuZ3VhZ2UtbW9kZWwtcHJvbXB0JztcbmltcG9ydCB7IHByZXBhcmVDYWxsU2V0dGluZ3MgfSBmcm9tICcuLi9wcm9tcHQvcHJlcGFyZS1jYWxsLXNldHRpbmdzJztcbmltcG9ydCB7IHByZXBhcmVUb29sc0FuZFRvb2xDaG9pY2UgfSBmcm9tICcuLi9wcm9tcHQvcHJlcGFyZS10b29scy1hbmQtdG9vbC1jaG9pY2UnO1xuaW1wb3J0IHsgUHJvbXB0IH0gZnJvbSAnLi4vcHJvbXB0L3Byb21wdCc7XG5pbXBvcnQgeyBzdGFuZGFyZGl6ZVByb21wdCB9IGZyb20gJy4uL3Byb21wdC9zdGFuZGFyZGl6ZS1wcm9tcHQnO1xuaW1wb3J0IHsgd3JhcEdhdGV3YXlFcnJvciB9IGZyb20gJy4uL3Byb21wdC93cmFwLWdhdGV3YXktZXJyb3InO1xuaW1wb3J0IHsgYXNzZW1ibGVPcGVyYXRpb25OYW1lIH0gZnJvbSAnLi4vdGVsZW1ldHJ5L2Fzc2VtYmxlLW9wZXJhdGlvbi1uYW1lJztcbmltcG9ydCB7IGdldEJhc2VUZWxlbWV0cnlBdHRyaWJ1dGVzIH0gZnJvbSAnLi4vdGVsZW1ldHJ5L2dldC1iYXNlLXRlbGVtZXRyeS1hdHRyaWJ1dGVzJztcbmltcG9ydCB7IGdldFRyYWNlciB9IGZyb20gJy4uL3RlbGVtZXRyeS9nZXQtdHJhY2VyJztcbmltcG9ydCB7IHJlY29yZEVycm9yT25TcGFuLCByZWNvcmRTcGFuIH0gZnJvbSAnLi4vdGVsZW1ldHJ5L3JlY29yZC1zcGFuJztcbmltcG9ydCB7IHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMgfSBmcm9tICcuLi90ZWxlbWV0cnkvc2VsZWN0LXRlbGVtZXRyeS1hdHRyaWJ1dGVzJztcbmltcG9ydCB7IHN0cmluZ2lmeUZvclRlbGVtZXRyeSB9IGZyb20gJy4uL3RlbGVtZXRyeS9zdHJpbmdpZnktZm9yLXRlbGVtZXRyeSc7XG5pbXBvcnQgeyBUZWxlbWV0cnlTZXR0aW5ncyB9IGZyb20gJy4uL3RlbGVtZXRyeS90ZWxlbWV0cnktc2V0dGluZ3MnO1xuaW1wb3J0IHsgTGFuZ3VhZ2VNb2RlbCwgVG9vbENob2ljZSB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IGFkZExhbmd1YWdlTW9kZWxVc2FnZSwgTGFuZ3VhZ2VNb2RlbFVzYWdlIH0gZnJvbSAnLi4vdHlwZXMvdXNhZ2UnO1xuaW1wb3J0IHsgYXNBcnJheSB9IGZyb20gJy4uL3V0aWwvYXMtYXJyYXknO1xuaW1wb3J0IHsgRG93bmxvYWRGdW5jdGlvbiB9IGZyb20gJy4uL3V0aWwvZG93bmxvYWQvZG93bmxvYWQtZnVuY3Rpb24nO1xuaW1wb3J0IHsgcHJlcGFyZVJldHJpZXMgfSBmcm9tICcuLi91dGlsL3ByZXBhcmUtcmV0cmllcyc7XG5pbXBvcnQgeyBDb250ZW50UGFydCB9IGZyb20gJy4vY29udGVudC1wYXJ0JztcbmltcG9ydCB7IGV4dHJhY3RUZXh0Q29udGVudCB9IGZyb20gJy4vZXh0cmFjdC10ZXh0LWNvbnRlbnQnO1xuaW1wb3J0IHsgR2VuZXJhdGVUZXh0UmVzdWx0IH0gZnJvbSAnLi9nZW5lcmF0ZS10ZXh0LXJlc3VsdCc7XG5pbXBvcnQgeyBEZWZhdWx0R2VuZXJhdGVkRmlsZSB9IGZyb20gJy4vZ2VuZXJhdGVkLWZpbGUnO1xuaW1wb3J0IHsgT3V0cHV0IH0gZnJvbSAnLi9vdXRwdXQnO1xuaW1wb3J0IHsgcGFyc2VUb29sQ2FsbCB9IGZyb20gJy4vcGFyc2UtdG9vbC1jYWxsJztcbmltcG9ydCB7IFByZXBhcmVTdGVwRnVuY3Rpb24gfSBmcm9tICcuL3ByZXBhcmUtc3RlcCc7XG5pbXBvcnQgeyBSZXNwb25zZU1lc3NhZ2UgfSBmcm9tICcuL3Jlc3BvbnNlLW1lc3NhZ2UnO1xuaW1wb3J0IHsgRGVmYXVsdFN0ZXBSZXN1bHQsIFN0ZXBSZXN1bHQgfSBmcm9tICcuL3N0ZXAtcmVzdWx0JztcbmltcG9ydCB7XG4gIGlzU3RvcENvbmRpdGlvbk1ldCxcbiAgc3RlcENvdW50SXMsXG4gIFN0b3BDb25kaXRpb24sXG59IGZyb20gJy4vc3RvcC1jb25kaXRpb24nO1xuaW1wb3J0IHsgdG9SZXNwb25zZU1lc3NhZ2VzIH0gZnJvbSAnLi90by1yZXNwb25zZS1tZXNzYWdlcyc7XG5pbXBvcnQgeyBUeXBlZFRvb2xDYWxsIH0gZnJvbSAnLi90b29sLWNhbGwnO1xuaW1wb3J0IHsgVG9vbENhbGxSZXBhaXJGdW5jdGlvbiB9IGZyb20gJy4vdG9vbC1jYWxsLXJlcGFpci1mdW5jdGlvbic7XG5pbXBvcnQgeyBUeXBlZFRvb2xFcnJvciB9IGZyb20gJy4vdG9vbC1lcnJvcic7XG5pbXBvcnQgeyBUb29sT3V0cHV0IH0gZnJvbSAnLi90b29sLW91dHB1dCc7XG5pbXBvcnQgeyBUeXBlZFRvb2xSZXN1bHQgfSBmcm9tICcuL3Rvb2wtcmVzdWx0JztcbmltcG9ydCB7IFRvb2xTZXQgfSBmcm9tICcuL3Rvb2wtc2V0JztcbmltcG9ydCB7IFZFUlNJT04gfSBmcm9tICcuLi92ZXJzaW9uJztcblxuY29uc3Qgb3JpZ2luYWxHZW5lcmF0ZUlkID0gY3JlYXRlSWRHZW5lcmF0b3Ioe1xuICBwcmVmaXg6ICdhaXR4dCcsXG4gIHNpemU6IDI0LFxufSk7XG5cbi8qKlxuQ2FsbGJhY2sgdGhhdCBpcyBzZXQgdXNpbmcgdGhlIGBvblN0ZXBGaW5pc2hgIG9wdGlvbi5cblxuQHBhcmFtIHN0ZXBSZXN1bHQgLSBUaGUgcmVzdWx0IG9mIHRoZSBzdGVwLlxuICovXG5leHBvcnQgdHlwZSBHZW5lcmF0ZVRleHRPblN0ZXBGaW5pc2hDYWxsYmFjazxUT09MUyBleHRlbmRzIFRvb2xTZXQ+ID0gKFxuICBzdGVwUmVzdWx0OiBTdGVwUmVzdWx0PFRPT0xTPixcbikgPT4gUHJvbWlzZTx2b2lkPiB8IHZvaWQ7XG5cbi8qKlxuR2VuZXJhdGUgYSB0ZXh0IGFuZCBjYWxsIHRvb2xzIGZvciBhIGdpdmVuIHByb21wdCB1c2luZyBhIGxhbmd1YWdlIG1vZGVsLlxuXG5UaGlzIGZ1bmN0aW9uIGRvZXMgbm90IHN0cmVhbSB0aGUgb3V0cHV0LiBJZiB5b3Ugd2FudCB0byBzdHJlYW0gdGhlIG91dHB1dCwgdXNlIGBzdHJlYW1UZXh0YCBpbnN0ZWFkLlxuXG5AcGFyYW0gbW9kZWwgLSBUaGUgbGFuZ3VhZ2UgbW9kZWwgdG8gdXNlLlxuXG5AcGFyYW0gdG9vbHMgLSBUb29scyB0aGF0IGFyZSBhY2Nlc3NpYmxlIHRvIGFuZCBjYW4gYmUgY2FsbGVkIGJ5IHRoZSBtb2RlbC4gVGhlIG1vZGVsIG5lZWRzIHRvIHN1cHBvcnQgY2FsbGluZyB0b29scy5cbkBwYXJhbSB0b29sQ2hvaWNlIC0gVGhlIHRvb2wgY2hvaWNlIHN0cmF0ZWd5LiBEZWZhdWx0OiAnYXV0bycuXG5cbkBwYXJhbSBzeXN0ZW0gLSBBIHN5c3RlbSBtZXNzYWdlIHRoYXQgd2lsbCBiZSBwYXJ0IG9mIHRoZSBwcm9tcHQuXG5AcGFyYW0gcHJvbXB0IC0gQSBzaW1wbGUgdGV4dCBwcm9tcHQuIFlvdSBjYW4gZWl0aGVyIHVzZSBgcHJvbXB0YCBvciBgbWVzc2FnZXNgIGJ1dCBub3QgYm90aC5cbkBwYXJhbSBtZXNzYWdlcyAtIEEgbGlzdCBvZiBtZXNzYWdlcy4gWW91IGNhbiBlaXRoZXIgdXNlIGBwcm9tcHRgIG9yIGBtZXNzYWdlc2AgYnV0IG5vdCBib3RoLlxuXG5AcGFyYW0gbWF4T3V0cHV0VG9rZW5zIC0gTWF4aW11bSBudW1iZXIgb2YgdG9rZW5zIHRvIGdlbmVyYXRlLlxuQHBhcmFtIHRlbXBlcmF0dXJlIC0gVGVtcGVyYXR1cmUgc2V0dGluZy5cblRoZSB2YWx1ZSBpcyBwYXNzZWQgdGhyb3VnaCB0byB0aGUgcHJvdmlkZXIuIFRoZSByYW5nZSBkZXBlbmRzIG9uIHRoZSBwcm92aWRlciBhbmQgbW9kZWwuXG5JdCBpcyByZWNvbW1lbmRlZCB0byBzZXQgZWl0aGVyIGB0ZW1wZXJhdHVyZWAgb3IgYHRvcFBgLCBidXQgbm90IGJvdGguXG5AcGFyYW0gdG9wUCAtIE51Y2xldXMgc2FtcGxpbmcuXG5UaGUgdmFsdWUgaXMgcGFzc2VkIHRocm91Z2ggdG8gdGhlIHByb3ZpZGVyLiBUaGUgcmFuZ2UgZGVwZW5kcyBvbiB0aGUgcHJvdmlkZXIgYW5kIG1vZGVsLlxuSXQgaXMgcmVjb21tZW5kZWQgdG8gc2V0IGVpdGhlciBgdGVtcGVyYXR1cmVgIG9yIGB0b3BQYCwgYnV0IG5vdCBib3RoLlxuQHBhcmFtIHRvcEsgLSBPbmx5IHNhbXBsZSBmcm9tIHRoZSB0b3AgSyBvcHRpb25zIGZvciBlYWNoIHN1YnNlcXVlbnQgdG9rZW4uXG5Vc2VkIHRvIHJlbW92ZSBcImxvbmcgdGFpbFwiIGxvdyBwcm9iYWJpbGl0eSByZXNwb25zZXMuXG5SZWNvbW1lbmRlZCBmb3IgYWR2YW5jZWQgdXNlIGNhc2VzIG9ubHkuIFlvdSB1c3VhbGx5IG9ubHkgbmVlZCB0byB1c2UgdGVtcGVyYXR1cmUuXG5AcGFyYW0gcHJlc2VuY2VQZW5hbHR5IC0gUHJlc2VuY2UgcGVuYWx0eSBzZXR0aW5nLlxuSXQgYWZmZWN0cyB0aGUgbGlrZWxpaG9vZCBvZiB0aGUgbW9kZWwgdG8gcmVwZWF0IGluZm9ybWF0aW9uIHRoYXQgaXMgYWxyZWFkeSBpbiB0aGUgcHJvbXB0LlxuVGhlIHZhbHVlIGlzIHBhc3NlZCB0aHJvdWdoIHRvIHRoZSBwcm92aWRlci4gVGhlIHJhbmdlIGRlcGVuZHMgb24gdGhlIHByb3ZpZGVyIGFuZCBtb2RlbC5cbkBwYXJhbSBmcmVxdWVuY3lQZW5hbHR5IC0gRnJlcXVlbmN5IHBlbmFsdHkgc2V0dGluZy5cbkl0IGFmZmVjdHMgdGhlIGxpa2VsaWhvb2Qgb2YgdGhlIG1vZGVsIHRvIHJlcGVhdGVkbHkgdXNlIHRoZSBzYW1lIHdvcmRzIG9yIHBocmFzZXMuXG5UaGUgdmFsdWUgaXMgcGFzc2VkIHRocm91Z2ggdG8gdGhlIHByb3ZpZGVyLiBUaGUgcmFuZ2UgZGVwZW5kcyBvbiB0aGUgcHJvdmlkZXIgYW5kIG1vZGVsLlxuQHBhcmFtIHN0b3BTZXF1ZW5jZXMgLSBTdG9wIHNlcXVlbmNlcy5cbklmIHNldCwgdGhlIG1vZGVsIHdpbGwgc3RvcCBnZW5lcmF0aW5nIHRleHQgd2hlbiBvbmUgb2YgdGhlIHN0b3Agc2VxdWVuY2VzIGlzIGdlbmVyYXRlZC5cbkBwYXJhbSBzZWVkIC0gVGhlIHNlZWQgKGludGVnZXIpIHRvIHVzZSBmb3IgcmFuZG9tIHNhbXBsaW5nLlxuSWYgc2V0IGFuZCBzdXBwb3J0ZWQgYnkgdGhlIG1vZGVsLCBjYWxscyB3aWxsIGdlbmVyYXRlIGRldGVybWluaXN0aWMgcmVzdWx0cy5cblxuQHBhcmFtIG1heFJldHJpZXMgLSBNYXhpbXVtIG51bWJlciBvZiByZXRyaWVzLiBTZXQgdG8gMCB0byBkaXNhYmxlIHJldHJpZXMuIERlZmF1bHQ6IDIuXG5AcGFyYW0gYWJvcnRTaWduYWwgLSBBbiBvcHRpb25hbCBhYm9ydCBzaWduYWwgdGhhdCBjYW4gYmUgdXNlZCB0byBjYW5jZWwgdGhlIGNhbGwuXG5AcGFyYW0gaGVhZGVycyAtIEFkZGl0aW9uYWwgSFRUUCBoZWFkZXJzIHRvIGJlIHNlbnQgd2l0aCB0aGUgcmVxdWVzdC4gT25seSBhcHBsaWNhYmxlIGZvciBIVFRQLWJhc2VkIHByb3ZpZGVycy5cblxuQHBhcmFtIGV4cGVyaW1lbnRhbF9nZW5lcmF0ZU1lc3NhZ2VJZCAtIEdlbmVyYXRlIGEgdW5pcXVlIElEIGZvciBlYWNoIG1lc3NhZ2UuXG5cbkBwYXJhbSBvblN0ZXBGaW5pc2ggLSBDYWxsYmFjayB0aGF0IGlzIGNhbGxlZCB3aGVuIGVhY2ggc3RlcCAoTExNIGNhbGwpIGlzIGZpbmlzaGVkLCBpbmNsdWRpbmcgaW50ZXJtZWRpYXRlIHN0ZXBzLlxuXG5AcmV0dXJuc1xuQSByZXN1bHQgb2JqZWN0IHRoYXQgY29udGFpbnMgdGhlIGdlbmVyYXRlZCB0ZXh0LCB0aGUgcmVzdWx0cyBvZiB0aGUgdG9vbCBjYWxscywgYW5kIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24uXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZW5lcmF0ZVRleHQ8XG4gIFRPT0xTIGV4dGVuZHMgVG9vbFNldCxcbiAgT1VUUFVUID0gbmV2ZXIsXG4gIE9VVFBVVF9QQVJUSUFMID0gbmV2ZXIsXG4+KHtcbiAgbW9kZWw6IG1vZGVsQXJnLFxuICB0b29scyxcbiAgdG9vbENob2ljZSxcbiAgc3lzdGVtLFxuICBwcm9tcHQsXG4gIG1lc3NhZ2VzLFxuICBtYXhSZXRyaWVzOiBtYXhSZXRyaWVzQXJnLFxuICBhYm9ydFNpZ25hbCxcbiAgaGVhZGVycyxcbiAgc3RvcFdoZW4gPSBzdGVwQ291bnRJcygxKSxcbiAgZXhwZXJpbWVudGFsX291dHB1dDogb3V0cHV0LFxuICBleHBlcmltZW50YWxfdGVsZW1ldHJ5OiB0ZWxlbWV0cnksXG4gIHByb3ZpZGVyT3B0aW9ucyxcbiAgZXhwZXJpbWVudGFsX2FjdGl2ZVRvb2xzLFxuICBhY3RpdmVUb29scyA9IGV4cGVyaW1lbnRhbF9hY3RpdmVUb29scyxcbiAgZXhwZXJpbWVudGFsX3ByZXBhcmVTdGVwLFxuICBwcmVwYXJlU3RlcCA9IGV4cGVyaW1lbnRhbF9wcmVwYXJlU3RlcCxcbiAgZXhwZXJpbWVudGFsX3JlcGFpclRvb2xDYWxsOiByZXBhaXJUb29sQ2FsbCxcbiAgZXhwZXJpbWVudGFsX2Rvd25sb2FkOiBkb3dubG9hZCxcbiAgZXhwZXJpbWVudGFsX2NvbnRleHQsXG4gIF9pbnRlcm5hbDoge1xuICAgIGdlbmVyYXRlSWQgPSBvcmlnaW5hbEdlbmVyYXRlSWQsXG4gICAgY3VycmVudERhdGUgPSAoKSA9PiBuZXcgRGF0ZSgpLFxuICB9ID0ge30sXG4gIG9uU3RlcEZpbmlzaCxcbiAgLi4uc2V0dGluZ3Ncbn06IENhbGxTZXR0aW5ncyAmXG4gIFByb21wdCAmIHtcbiAgICAvKipcblRoZSBsYW5ndWFnZSBtb2RlbCB0byB1c2UuXG4gICAgICovXG4gICAgbW9kZWw6IExhbmd1YWdlTW9kZWw7XG5cbiAgICAvKipcblRoZSB0b29scyB0aGF0IHRoZSBtb2RlbCBjYW4gY2FsbC4gVGhlIG1vZGVsIG5lZWRzIHRvIHN1cHBvcnQgY2FsbGluZyB0b29scy5cbiovXG4gICAgdG9vbHM/OiBUT09MUztcblxuICAgIC8qKlxuVGhlIHRvb2wgY2hvaWNlIHN0cmF0ZWd5LiBEZWZhdWx0OiAnYXV0bycuXG4gICAgICovXG4gICAgdG9vbENob2ljZT86IFRvb2xDaG9pY2U8Tm9JbmZlcjxUT09MUz4+O1xuXG4gICAgLyoqXG5Db25kaXRpb24gZm9yIHN0b3BwaW5nIHRoZSBnZW5lcmF0aW9uIHdoZW4gdGhlcmUgYXJlIHRvb2wgcmVzdWx0cyBpbiB0aGUgbGFzdCBzdGVwLlxuV2hlbiB0aGUgY29uZGl0aW9uIGlzIGFuIGFycmF5LCBhbnkgb2YgdGhlIGNvbmRpdGlvbnMgY2FuIGJlIG1ldCB0byBzdG9wIHRoZSBnZW5lcmF0aW9uLlxuXG5AZGVmYXVsdCBzdGVwQ291bnRJcygxKVxuICAgICAqL1xuICAgIHN0b3BXaGVuPzpcbiAgICAgIHwgU3RvcENvbmRpdGlvbjxOb0luZmVyPFRPT0xTPj5cbiAgICAgIHwgQXJyYXk8U3RvcENvbmRpdGlvbjxOb0luZmVyPFRPT0xTPj4+O1xuXG4gICAgLyoqXG5PcHRpb25hbCB0ZWxlbWV0cnkgY29uZmlndXJhdGlvbiAoZXhwZXJpbWVudGFsKS5cbiAgICAgKi9cbiAgICBleHBlcmltZW50YWxfdGVsZW1ldHJ5PzogVGVsZW1ldHJ5U2V0dGluZ3M7XG5cbiAgICAvKipcbkFkZGl0aW9uYWwgcHJvdmlkZXItc3BlY2lmaWMgb3B0aW9ucy4gVGhleSBhcmUgcGFzc2VkIHRocm91Z2hcbnRvIHRoZSBwcm92aWRlciBmcm9tIHRoZSBBSSBTREsgYW5kIGVuYWJsZSBwcm92aWRlci1zcGVjaWZpY1xuZnVuY3Rpb25hbGl0eSB0aGF0IGNhbiBiZSBmdWxseSBlbmNhcHN1bGF0ZWQgaW4gdGhlIHByb3ZpZGVyLlxuICovXG4gICAgcHJvdmlkZXJPcHRpb25zPzogUHJvdmlkZXJPcHRpb25zO1xuXG4gICAgLyoqXG4gICAgICogQGRlcHJlY2F0ZWQgVXNlIGBhY3RpdmVUb29sc2AgaW5zdGVhZC5cbiAgICAgKi9cbiAgICBleHBlcmltZW50YWxfYWN0aXZlVG9vbHM/OiBBcnJheTxrZXlvZiBOb0luZmVyPFRPT0xTPj47XG5cbiAgICAvKipcbkxpbWl0cyB0aGUgdG9vbHMgdGhhdCBhcmUgYXZhaWxhYmxlIGZvciB0aGUgbW9kZWwgdG8gY2FsbCB3aXRob3V0XG5jaGFuZ2luZyB0aGUgdG9vbCBjYWxsIGFuZCByZXN1bHQgdHlwZXMgaW4gdGhlIHJlc3VsdC5cbiAgICAgKi9cbiAgICBhY3RpdmVUb29scz86IEFycmF5PGtleW9mIE5vSW5mZXI8VE9PTFM+PjtcblxuICAgIC8qKlxuT3B0aW9uYWwgc3BlY2lmaWNhdGlvbiBmb3IgcGFyc2luZyBzdHJ1Y3R1cmVkIG91dHB1dHMgZnJvbSB0aGUgTExNIHJlc3BvbnNlLlxuICAgICAqL1xuICAgIGV4cGVyaW1lbnRhbF9vdXRwdXQ/OiBPdXRwdXQ8T1VUUFVULCBPVVRQVVRfUEFSVElBTD47XG5cbiAgICAvKipcbkN1c3RvbSBkb3dubG9hZCBmdW5jdGlvbiB0byB1c2UgZm9yIFVSTHMuXG5cbkJ5IGRlZmF1bHQsIGZpbGVzIGFyZSBkb3dubG9hZGVkIGlmIHRoZSBtb2RlbCBkb2VzIG5vdCBzdXBwb3J0IHRoZSBVUkwgZm9yIHRoZSBnaXZlbiBtZWRpYSB0eXBlLlxuICAgICAqL1xuICAgIGV4cGVyaW1lbnRhbF9kb3dubG9hZD86IERvd25sb2FkRnVuY3Rpb24gfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBAZGVwcmVjYXRlZCBVc2UgYHByZXBhcmVTdGVwYCBpbnN0ZWFkLlxuICAgICAqL1xuICAgIGV4cGVyaW1lbnRhbF9wcmVwYXJlU3RlcD86IFByZXBhcmVTdGVwRnVuY3Rpb248Tm9JbmZlcjxUT09MUz4+O1xuXG4gICAgLyoqXG5PcHRpb25hbCBmdW5jdGlvbiB0aGF0IHlvdSBjYW4gdXNlIHRvIHByb3ZpZGUgZGlmZmVyZW50IHNldHRpbmdzIGZvciBhIHN0ZXAuXG4gICAgKi9cbiAgICBwcmVwYXJlU3RlcD86IFByZXBhcmVTdGVwRnVuY3Rpb248Tm9JbmZlcjxUT09MUz4+O1xuXG4gICAgLyoqXG5BIGZ1bmN0aW9uIHRoYXQgYXR0ZW1wdHMgdG8gcmVwYWlyIGEgdG9vbCBjYWxsIHRoYXQgZmFpbGVkIHRvIHBhcnNlLlxuICAgICAqL1xuICAgIGV4cGVyaW1lbnRhbF9yZXBhaXJUb29sQ2FsbD86IFRvb2xDYWxsUmVwYWlyRnVuY3Rpb248Tm9JbmZlcjxUT09MUz4+O1xuXG4gICAgLyoqXG4gICAgQ2FsbGJhY2sgdGhhdCBpcyBjYWxsZWQgd2hlbiBlYWNoIHN0ZXAgKExMTSBjYWxsKSBpcyBmaW5pc2hlZCwgaW5jbHVkaW5nIGludGVybWVkaWF0ZSBzdGVwcy5cbiAgICAqL1xuICAgIG9uU3RlcEZpbmlzaD86IEdlbmVyYXRlVGV4dE9uU3RlcEZpbmlzaENhbGxiYWNrPE5vSW5mZXI8VE9PTFM+PjtcblxuICAgIC8qKlxuICAgICAqIENvbnRleHQgdGhhdCBpcyBwYXNzZWQgaW50byB0b29sIGV4ZWN1dGlvbi5cbiAgICAgKlxuICAgICAqIEV4cGVyaW1lbnRhbCAoY2FuIGJyZWFrIGluIHBhdGNoIHJlbGVhc2VzKS5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0IHVuZGVmaW5lZFxuICAgICAqL1xuICAgIGV4cGVyaW1lbnRhbF9jb250ZXh0PzogdW5rbm93bjtcblxuICAgIC8qKlxuICAgICAqIEludGVybmFsLiBGb3IgdGVzdCB1c2Ugb25seS4gTWF5IGNoYW5nZSB3aXRob3V0IG5vdGljZS5cbiAgICAgKi9cbiAgICBfaW50ZXJuYWw/OiB7XG4gICAgICBnZW5lcmF0ZUlkPzogSWRHZW5lcmF0b3I7XG4gICAgICBjdXJyZW50RGF0ZT86ICgpID0+IERhdGU7XG4gICAgfTtcbiAgfSk6IFByb21pc2U8R2VuZXJhdGVUZXh0UmVzdWx0PFRPT0xTLCBPVVRQVVQ+PiB7XG4gIGNvbnN0IG1vZGVsID0gcmVzb2x2ZUxhbmd1YWdlTW9kZWwobW9kZWxBcmcpO1xuICBjb25zdCBzdG9wQ29uZGl0aW9ucyA9IGFzQXJyYXkoc3RvcFdoZW4pO1xuICBjb25zdCB7IG1heFJldHJpZXMsIHJldHJ5IH0gPSBwcmVwYXJlUmV0cmllcyh7XG4gICAgbWF4UmV0cmllczogbWF4UmV0cmllc0FyZyxcbiAgICBhYm9ydFNpZ25hbCxcbiAgfSk7XG5cbiAgY29uc3QgY2FsbFNldHRpbmdzID0gcHJlcGFyZUNhbGxTZXR0aW5ncyhzZXR0aW5ncyk7XG5cbiAgY29uc3QgaGVhZGVyc1dpdGhVc2VyQWdlbnQgPSB3aXRoVXNlckFnZW50U3VmZml4KFxuICAgIGhlYWRlcnMgPz8ge30sXG4gICAgYGFpLyR7VkVSU0lPTn1gLFxuICApO1xuXG4gIGNvbnN0IGJhc2VUZWxlbWV0cnlBdHRyaWJ1dGVzID0gZ2V0QmFzZVRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgIG1vZGVsLFxuICAgIHRlbGVtZXRyeSxcbiAgICBoZWFkZXJzOiBoZWFkZXJzV2l0aFVzZXJBZ2VudCxcbiAgICBzZXR0aW5nczogeyAuLi5jYWxsU2V0dGluZ3MsIG1heFJldHJpZXMgfSxcbiAgfSk7XG5cbiAgY29uc3QgaW5pdGlhbFByb21wdCA9IGF3YWl0IHN0YW5kYXJkaXplUHJvbXB0KHtcbiAgICBzeXN0ZW0sXG4gICAgcHJvbXB0LFxuICAgIG1lc3NhZ2VzLFxuICB9IGFzIFByb21wdCk7XG5cbiAgY29uc3QgdHJhY2VyID0gZ2V0VHJhY2VyKHRlbGVtZXRyeSk7XG5cbiAgdHJ5IHtcbiAgICByZXR1cm4gYXdhaXQgcmVjb3JkU3Bhbih7XG4gICAgICBuYW1lOiAnYWkuZ2VuZXJhdGVUZXh0JyxcbiAgICAgIGF0dHJpYnV0ZXM6IHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgICB0ZWxlbWV0cnksXG4gICAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgICAuLi5hc3NlbWJsZU9wZXJhdGlvbk5hbWUoe1xuICAgICAgICAgICAgb3BlcmF0aW9uSWQ6ICdhaS5nZW5lcmF0ZVRleHQnLFxuICAgICAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIC4uLmJhc2VUZWxlbWV0cnlBdHRyaWJ1dGVzLFxuICAgICAgICAgIC8vIG1vZGVsOlxuICAgICAgICAgICdhaS5tb2RlbC5wcm92aWRlcic6IG1vZGVsLnByb3ZpZGVyLFxuICAgICAgICAgICdhaS5tb2RlbC5pZCc6IG1vZGVsLm1vZGVsSWQsXG4gICAgICAgICAgLy8gc3BlY2lmaWMgc2V0dGluZ3MgdGhhdCBvbmx5IG1ha2Ugc2Vuc2Ugb24gdGhlIG91dGVyIGxldmVsOlxuICAgICAgICAgICdhaS5wcm9tcHQnOiB7XG4gICAgICAgICAgICBpbnB1dDogKCkgPT4gSlNPTi5zdHJpbmdpZnkoeyBzeXN0ZW0sIHByb21wdCwgbWVzc2FnZXMgfSksXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgICAgdHJhY2VyLFxuICAgICAgZm46IGFzeW5jIHNwYW4gPT4ge1xuICAgICAgICBjb25zdCBjYWxsU2V0dGluZ3MgPSBwcmVwYXJlQ2FsbFNldHRpbmdzKHNldHRpbmdzKTtcblxuICAgICAgICBsZXQgY3VycmVudE1vZGVsUmVzcG9uc2U6IEF3YWl0ZWQ8XG4gICAgICAgICAgUmV0dXJuVHlwZTxMYW5ndWFnZU1vZGVsVjJbJ2RvR2VuZXJhdGUnXT5cbiAgICAgICAgPiAmIHsgcmVzcG9uc2U6IHsgaWQ6IHN0cmluZzsgdGltZXN0YW1wOiBEYXRlOyBtb2RlbElkOiBzdHJpbmcgfSB9O1xuICAgICAgICBsZXQgY2xpZW50VG9vbENhbGxzOiBBcnJheTxUeXBlZFRvb2xDYWxsPFRPT0xTPj4gPSBbXTtcbiAgICAgICAgbGV0IGNsaWVudFRvb2xPdXRwdXRzOiBBcnJheTxUb29sT3V0cHV0PFRPT0xTPj4gPSBbXTtcbiAgICAgICAgY29uc3QgcmVzcG9uc2VNZXNzYWdlczogQXJyYXk8UmVzcG9uc2VNZXNzYWdlPiA9IFtdO1xuICAgICAgICBjb25zdCBzdGVwczogR2VuZXJhdGVUZXh0UmVzdWx0PFRPT0xTLCBPVVRQVVQ+WydzdGVwcyddID0gW107XG5cbiAgICAgICAgZG8ge1xuICAgICAgICAgIGNvbnN0IHN0ZXBJbnB1dE1lc3NhZ2VzID0gW1xuICAgICAgICAgICAgLi4uaW5pdGlhbFByb21wdC5tZXNzYWdlcyxcbiAgICAgICAgICAgIC4uLnJlc3BvbnNlTWVzc2FnZXMsXG4gICAgICAgICAgXTtcblxuICAgICAgICAgIGNvbnN0IHByZXBhcmVTdGVwUmVzdWx0ID0gYXdhaXQgcHJlcGFyZVN0ZXA/Lih7XG4gICAgICAgICAgICBtb2RlbCxcbiAgICAgICAgICAgIHN0ZXBzLFxuICAgICAgICAgICAgc3RlcE51bWJlcjogc3RlcHMubGVuZ3RoLFxuICAgICAgICAgICAgbWVzc2FnZXM6IHN0ZXBJbnB1dE1lc3NhZ2VzLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY29uc3Qgc3RlcE1vZGVsID0gcmVzb2x2ZUxhbmd1YWdlTW9kZWwoXG4gICAgICAgICAgICBwcmVwYXJlU3RlcFJlc3VsdD8ubW9kZWwgPz8gbW9kZWwsXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGNvbnN0IHByb21wdE1lc3NhZ2VzID0gYXdhaXQgY29udmVydFRvTGFuZ3VhZ2VNb2RlbFByb21wdCh7XG4gICAgICAgICAgICBwcm9tcHQ6IHtcbiAgICAgICAgICAgICAgc3lzdGVtOiBwcmVwYXJlU3RlcFJlc3VsdD8uc3lzdGVtID8/IGluaXRpYWxQcm9tcHQuc3lzdGVtLFxuICAgICAgICAgICAgICBtZXNzYWdlczogcHJlcGFyZVN0ZXBSZXN1bHQ/Lm1lc3NhZ2VzID8/IHN0ZXBJbnB1dE1lc3NhZ2VzLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHN1cHBvcnRlZFVybHM6IGF3YWl0IHN0ZXBNb2RlbC5zdXBwb3J0ZWRVcmxzLFxuICAgICAgICAgICAgZG93bmxvYWQsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCB7IHRvb2xDaG9pY2U6IHN0ZXBUb29sQ2hvaWNlLCB0b29sczogc3RlcFRvb2xzIH0gPVxuICAgICAgICAgICAgcHJlcGFyZVRvb2xzQW5kVG9vbENob2ljZSh7XG4gICAgICAgICAgICAgIHRvb2xzLFxuICAgICAgICAgICAgICB0b29sQ2hvaWNlOiBwcmVwYXJlU3RlcFJlc3VsdD8udG9vbENob2ljZSA/PyB0b29sQ2hvaWNlLFxuICAgICAgICAgICAgICBhY3RpdmVUb29sczogcHJlcGFyZVN0ZXBSZXN1bHQ/LmFjdGl2ZVRvb2xzID8/IGFjdGl2ZVRvb2xzLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjdXJyZW50TW9kZWxSZXNwb25zZSA9IGF3YWl0IHJldHJ5KCgpID0+XG4gICAgICAgICAgICByZWNvcmRTcGFuKHtcbiAgICAgICAgICAgICAgbmFtZTogJ2FpLmdlbmVyYXRlVGV4dC5kb0dlbmVyYXRlJyxcbiAgICAgICAgICAgICAgYXR0cmlidXRlczogc2VsZWN0VGVsZW1ldHJ5QXR0cmlidXRlcyh7XG4gICAgICAgICAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgICAgICAgICAgIC4uLmFzc2VtYmxlT3BlcmF0aW9uTmFtZSh7XG4gICAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbklkOiAnYWkuZ2VuZXJhdGVUZXh0LmRvR2VuZXJhdGUnLFxuICAgICAgICAgICAgICAgICAgICB0ZWxlbWV0cnksXG4gICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgIC4uLmJhc2VUZWxlbWV0cnlBdHRyaWJ1dGVzLFxuICAgICAgICAgICAgICAgICAgLy8gbW9kZWw6XG4gICAgICAgICAgICAgICAgICAnYWkubW9kZWwucHJvdmlkZXInOiBzdGVwTW9kZWwucHJvdmlkZXIsXG4gICAgICAgICAgICAgICAgICAnYWkubW9kZWwuaWQnOiBzdGVwTW9kZWwubW9kZWxJZCxcbiAgICAgICAgICAgICAgICAgIC8vIHByb21wdDpcbiAgICAgICAgICAgICAgICAgICdhaS5wcm9tcHQubWVzc2FnZXMnOiB7XG4gICAgICAgICAgICAgICAgICAgIGlucHV0OiAoKSA9PiBzdHJpbmdpZnlGb3JUZWxlbWV0cnkocHJvbXB0TWVzc2FnZXMpLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICdhaS5wcm9tcHQudG9vbHMnOiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGNvbnZlcnQgdGhlIGxhbmd1YWdlIG1vZGVsIGxldmVsIHRvb2xzOlxuICAgICAgICAgICAgICAgICAgICBpbnB1dDogKCkgPT4gc3RlcFRvb2xzPy5tYXAodG9vbCA9PiBKU09OLnN0cmluZ2lmeSh0b29sKSksXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgJ2FpLnByb21wdC50b29sQ2hvaWNlJzoge1xuICAgICAgICAgICAgICAgICAgICBpbnB1dDogKCkgPT5cbiAgICAgICAgICAgICAgICAgICAgICBzdGVwVG9vbENob2ljZSAhPSBudWxsXG4gICAgICAgICAgICAgICAgICAgICAgICA/IEpTT04uc3RyaW5naWZ5KHN0ZXBUb29sQ2hvaWNlKVxuICAgICAgICAgICAgICAgICAgICAgICAgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAgICAgICAvLyBzdGFuZGFyZGl6ZWQgZ2VuLWFpIGxsbSBzcGFuIGF0dHJpYnV0ZXM6XG4gICAgICAgICAgICAgICAgICAnZ2VuX2FpLnN5c3RlbSc6IHN0ZXBNb2RlbC5wcm92aWRlcixcbiAgICAgICAgICAgICAgICAgICdnZW5fYWkucmVxdWVzdC5tb2RlbCc6IHN0ZXBNb2RlbC5tb2RlbElkLFxuICAgICAgICAgICAgICAgICAgJ2dlbl9haS5yZXF1ZXN0LmZyZXF1ZW5jeV9wZW5hbHR5Jzogc2V0dGluZ3MuZnJlcXVlbmN5UGVuYWx0eSxcbiAgICAgICAgICAgICAgICAgICdnZW5fYWkucmVxdWVzdC5tYXhfdG9rZW5zJzogc2V0dGluZ3MubWF4T3V0cHV0VG9rZW5zLFxuICAgICAgICAgICAgICAgICAgJ2dlbl9haS5yZXF1ZXN0LnByZXNlbmNlX3BlbmFsdHknOiBzZXR0aW5ncy5wcmVzZW5jZVBlbmFsdHksXG4gICAgICAgICAgICAgICAgICAnZ2VuX2FpLnJlcXVlc3Quc3RvcF9zZXF1ZW5jZXMnOiBzZXR0aW5ncy5zdG9wU2VxdWVuY2VzLFxuICAgICAgICAgICAgICAgICAgJ2dlbl9haS5yZXF1ZXN0LnRlbXBlcmF0dXJlJzpcbiAgICAgICAgICAgICAgICAgICAgc2V0dGluZ3MudGVtcGVyYXR1cmUgPz8gdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgICAgJ2dlbl9haS5yZXF1ZXN0LnRvcF9rJzogc2V0dGluZ3MudG9wSyxcbiAgICAgICAgICAgICAgICAgICdnZW5fYWkucmVxdWVzdC50b3BfcCc6IHNldHRpbmdzLnRvcFAsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIHRyYWNlcixcbiAgICAgICAgICAgICAgZm46IGFzeW5jIHNwYW4gPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHN0ZXBNb2RlbC5kb0dlbmVyYXRlKHtcbiAgICAgICAgICAgICAgICAgIC4uLmNhbGxTZXR0aW5ncyxcbiAgICAgICAgICAgICAgICAgIHRvb2xzOiBzdGVwVG9vbHMsXG4gICAgICAgICAgICAgICAgICB0b29sQ2hvaWNlOiBzdGVwVG9vbENob2ljZSxcbiAgICAgICAgICAgICAgICAgIHJlc3BvbnNlRm9ybWF0OiBvdXRwdXQ/LnJlc3BvbnNlRm9ybWF0LFxuICAgICAgICAgICAgICAgICAgcHJvbXB0OiBwcm9tcHRNZXNzYWdlcyxcbiAgICAgICAgICAgICAgICAgIHByb3ZpZGVyT3B0aW9ucyxcbiAgICAgICAgICAgICAgICAgIGFib3J0U2lnbmFsLFxuICAgICAgICAgICAgICAgICAgaGVhZGVyczogaGVhZGVyc1dpdGhVc2VyQWdlbnQsXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAvLyBGaWxsIGluIGRlZmF1bHQgdmFsdWVzOlxuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlRGF0YSA9IHtcbiAgICAgICAgICAgICAgICAgIGlkOiByZXN1bHQucmVzcG9uc2U/LmlkID8/IGdlbmVyYXRlSWQoKSxcbiAgICAgICAgICAgICAgICAgIHRpbWVzdGFtcDogcmVzdWx0LnJlc3BvbnNlPy50aW1lc3RhbXAgPz8gY3VycmVudERhdGUoKSxcbiAgICAgICAgICAgICAgICAgIG1vZGVsSWQ6IHJlc3VsdC5yZXNwb25zZT8ubW9kZWxJZCA/PyBzdGVwTW9kZWwubW9kZWxJZCxcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHJlc3VsdC5yZXNwb25zZT8uaGVhZGVycyxcbiAgICAgICAgICAgICAgICAgIGJvZHk6IHJlc3VsdC5yZXNwb25zZT8uYm9keSxcbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgLy8gQWRkIHJlc3BvbnNlIGluZm9ybWF0aW9uIHRvIHRoZSBzcGFuOlxuICAgICAgICAgICAgICAgIHNwYW4uc2V0QXR0cmlidXRlcyhcbiAgICAgICAgICAgICAgICAgIHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgICAgICAgICB0ZWxlbWV0cnksXG4gICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAnYWkucmVzcG9uc2UuZmluaXNoUmVhc29uJzogcmVzdWx0LmZpbmlzaFJlYXNvbixcbiAgICAgICAgICAgICAgICAgICAgICAnYWkucmVzcG9uc2UudGV4dCc6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dDogKCkgPT4gZXh0cmFjdFRleHRDb250ZW50KHJlc3VsdC5jb250ZW50KSxcbiAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICdhaS5yZXNwb25zZS50b29sQ2FsbHMnOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQ6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdG9vbENhbGxzID0gYXNUb29sQ2FsbHMocmVzdWx0LmNvbnRlbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdG9vbENhbGxzID09IG51bGxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogSlNPTi5zdHJpbmdpZnkodG9vbENhbGxzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAnYWkucmVzcG9uc2UuaWQnOiByZXNwb25zZURhdGEuaWQsXG4gICAgICAgICAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLm1vZGVsJzogcmVzcG9uc2VEYXRhLm1vZGVsSWQsXG4gICAgICAgICAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLnRpbWVzdGFtcCc6XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZURhdGEudGltZXN0YW1wLnRvSVNPU3RyaW5nKCksXG4gICAgICAgICAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLnByb3ZpZGVyTWV0YWRhdGEnOiBKU09OLnN0cmluZ2lmeShcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wcm92aWRlck1ldGFkYXRhLFxuICAgICAgICAgICAgICAgICAgICAgICksXG5cbiAgICAgICAgICAgICAgICAgICAgICAvLyBUT0RPIHJlbmFtZSB0ZWxlbWV0cnkgYXR0cmlidXRlcyB0byBpbnB1dFRva2VucyBhbmQgb3V0cHV0VG9rZW5zXG4gICAgICAgICAgICAgICAgICAgICAgJ2FpLnVzYWdlLnByb21wdFRva2Vucyc6IHJlc3VsdC51c2FnZS5pbnB1dFRva2VucyxcbiAgICAgICAgICAgICAgICAgICAgICAnYWkudXNhZ2UuY29tcGxldGlvblRva2Vucyc6IHJlc3VsdC51c2FnZS5vdXRwdXRUb2tlbnMsXG5cbiAgICAgICAgICAgICAgICAgICAgICAvLyBzdGFuZGFyZGl6ZWQgZ2VuLWFpIGxsbSBzcGFuIGF0dHJpYnV0ZXM6XG4gICAgICAgICAgICAgICAgICAgICAgJ2dlbl9haS5yZXNwb25zZS5maW5pc2hfcmVhc29ucyc6IFtyZXN1bHQuZmluaXNoUmVhc29uXSxcbiAgICAgICAgICAgICAgICAgICAgICAnZ2VuX2FpLnJlc3BvbnNlLmlkJzogcmVzcG9uc2VEYXRhLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICdnZW5fYWkucmVzcG9uc2UubW9kZWwnOiByZXNwb25zZURhdGEubW9kZWxJZCxcbiAgICAgICAgICAgICAgICAgICAgICAnZ2VuX2FpLnVzYWdlLmlucHV0X3Rva2Vucyc6IHJlc3VsdC51c2FnZS5pbnB1dFRva2VucyxcbiAgICAgICAgICAgICAgICAgICAgICAnZ2VuX2FpLnVzYWdlLm91dHB1dF90b2tlbnMnOiByZXN1bHQudXNhZ2Uub3V0cHV0VG9rZW5zLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiB7IC4uLnJlc3VsdCwgcmVzcG9uc2U6IHJlc3BvbnNlRGF0YSB9O1xuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIC8vIHBhcnNlIHRvb2wgY2FsbHM6XG4gICAgICAgICAgY29uc3Qgc3RlcFRvb2xDYWxsczogVHlwZWRUb29sQ2FsbDxUT09MUz5bXSA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICAgICAgY3VycmVudE1vZGVsUmVzcG9uc2UuY29udGVudFxuICAgICAgICAgICAgICAuZmlsdGVyKFxuICAgICAgICAgICAgICAgIChwYXJ0KTogcGFydCBpcyBMYW5ndWFnZU1vZGVsVjJUb29sQ2FsbCA9PlxuICAgICAgICAgICAgICAgICAgcGFydC50eXBlID09PSAndG9vbC1jYWxsJyxcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAubWFwKHRvb2xDYWxsID0+XG4gICAgICAgICAgICAgICAgcGFyc2VUb29sQ2FsbCh7XG4gICAgICAgICAgICAgICAgICB0b29sQ2FsbCxcbiAgICAgICAgICAgICAgICAgIHRvb2xzLFxuICAgICAgICAgICAgICAgICAgcmVwYWlyVG9vbENhbGwsXG4gICAgICAgICAgICAgICAgICBzeXN0ZW0sXG4gICAgICAgICAgICAgICAgICBtZXNzYWdlczogc3RlcElucHV0TWVzc2FnZXMsXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIC8vIG5vdGlmeSB0aGUgdG9vbHMgdGhhdCB0aGUgdG9vbCBjYWxscyBhcmUgYXZhaWxhYmxlOlxuICAgICAgICAgIGZvciAoY29uc3QgdG9vbENhbGwgb2Ygc3RlcFRvb2xDYWxscykge1xuICAgICAgICAgICAgaWYgKHRvb2xDYWxsLmludmFsaWQpIHtcbiAgICAgICAgICAgICAgY29udGludWU7IC8vIGlnbm9yZSBpbnZhbGlkIHRvb2wgY2FsbHNcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgdG9vbCA9IHRvb2xzIVt0b29sQ2FsbC50b29sTmFtZV07XG4gICAgICAgICAgICBpZiAodG9vbD8ub25JbnB1dEF2YWlsYWJsZSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgIGF3YWl0IHRvb2wub25JbnB1dEF2YWlsYWJsZSh7XG4gICAgICAgICAgICAgICAgaW5wdXQ6IHRvb2xDYWxsLmlucHV0LFxuICAgICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IHRvb2xDYWxsLnRvb2xDYWxsSWQsXG4gICAgICAgICAgICAgICAgbWVzc2FnZXM6IHN0ZXBJbnB1dE1lc3NhZ2VzLFxuICAgICAgICAgICAgICAgIGFib3J0U2lnbmFsLFxuICAgICAgICAgICAgICAgIGV4cGVyaW1lbnRhbF9jb250ZXh0LFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBpbnNlcnQgZXJyb3IgdG9vbCBvdXRwdXRzIGZvciBpbnZhbGlkIHRvb2wgY2FsbHM6XG4gICAgICAgICAgLy8gVE9ETyBBSSBTREsgNjogaW52YWxpZCBpbnB1dHMgc2hvdWxkIG5vdCByZXF1aXJlIG91dHB1dCBwYXJ0c1xuICAgICAgICAgIGNvbnN0IGludmFsaWRUb29sQ2FsbHMgPSBzdGVwVG9vbENhbGxzLmZpbHRlcihcbiAgICAgICAgICAgIHRvb2xDYWxsID0+IHRvb2xDYWxsLmludmFsaWQgJiYgdG9vbENhbGwuZHluYW1pYyxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgY2xpZW50VG9vbE91dHB1dHMgPSBbXTtcblxuICAgICAgICAgIGZvciAoY29uc3QgdG9vbENhbGwgb2YgaW52YWxpZFRvb2xDYWxscykge1xuICAgICAgICAgICAgY2xpZW50VG9vbE91dHB1dHMucHVzaCh7XG4gICAgICAgICAgICAgIHR5cGU6ICd0b29sLWVycm9yJyxcbiAgICAgICAgICAgICAgdG9vbENhbGxJZDogdG9vbENhbGwudG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgdG9vbE5hbWU6IHRvb2xDYWxsLnRvb2xOYW1lLFxuICAgICAgICAgICAgICBpbnB1dDogdG9vbENhbGwuaW5wdXQsXG4gICAgICAgICAgICAgIGVycm9yOiBnZXRFcnJvck1lc3NhZ2UodG9vbENhbGwuZXJyb3IhKSxcbiAgICAgICAgICAgICAgZHluYW1pYzogdHJ1ZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIGV4ZWN1dGUgY2xpZW50IHRvb2wgY2FsbHM6XG4gICAgICAgICAgY2xpZW50VG9vbENhbGxzID0gc3RlcFRvb2xDYWxscy5maWx0ZXIoXG4gICAgICAgICAgICB0b29sQ2FsbCA9PiAhdG9vbENhbGwucHJvdmlkZXJFeGVjdXRlZCxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgaWYgKHRvb2xzICE9IG51bGwpIHtcbiAgICAgICAgICAgIGNsaWVudFRvb2xPdXRwdXRzLnB1c2goXG4gICAgICAgICAgICAgIC4uLihhd2FpdCBleGVjdXRlVG9vbHMoe1xuICAgICAgICAgICAgICAgIHRvb2xDYWxsczogY2xpZW50VG9vbENhbGxzLmZpbHRlcihcbiAgICAgICAgICAgICAgICAgIHRvb2xDYWxsID0+ICF0b29sQ2FsbC5pbnZhbGlkLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgdG9vbHMsXG4gICAgICAgICAgICAgICAgdHJhY2VyLFxuICAgICAgICAgICAgICAgIHRlbGVtZXRyeSxcbiAgICAgICAgICAgICAgICBtZXNzYWdlczogc3RlcElucHV0TWVzc2FnZXMsXG4gICAgICAgICAgICAgICAgYWJvcnRTaWduYWwsXG4gICAgICAgICAgICAgICAgZXhwZXJpbWVudGFsX2NvbnRleHQsXG4gICAgICAgICAgICAgIH0pKSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gY29udGVudDpcbiAgICAgICAgICBjb25zdCBzdGVwQ29udGVudCA9IGFzQ29udGVudCh7XG4gICAgICAgICAgICBjb250ZW50OiBjdXJyZW50TW9kZWxSZXNwb25zZS5jb250ZW50LFxuICAgICAgICAgICAgdG9vbENhbGxzOiBzdGVwVG9vbENhbGxzLFxuICAgICAgICAgICAgdG9vbE91dHB1dHM6IGNsaWVudFRvb2xPdXRwdXRzLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgLy8gYXBwZW5kIHRvIG1lc3NhZ2VzIGZvciBwb3RlbnRpYWwgbmV4dCBzdGVwOlxuICAgICAgICAgIHJlc3BvbnNlTWVzc2FnZXMucHVzaChcbiAgICAgICAgICAgIC4uLnRvUmVzcG9uc2VNZXNzYWdlcyh7XG4gICAgICAgICAgICAgIGNvbnRlbnQ6IHN0ZXBDb250ZW50LFxuICAgICAgICAgICAgICB0b29scyxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICAvLyBBZGQgc3RlcCBpbmZvcm1hdGlvbiAoYWZ0ZXIgcmVzcG9uc2UgbWVzc2FnZXMgYXJlIHVwZGF0ZWQpOlxuICAgICAgICAgIGNvbnN0IGN1cnJlbnRTdGVwUmVzdWx0OiBTdGVwUmVzdWx0PFRPT0xTPiA9IG5ldyBEZWZhdWx0U3RlcFJlc3VsdCh7XG4gICAgICAgICAgICBjb250ZW50OiBzdGVwQ29udGVudCxcbiAgICAgICAgICAgIGZpbmlzaFJlYXNvbjogY3VycmVudE1vZGVsUmVzcG9uc2UuZmluaXNoUmVhc29uLFxuICAgICAgICAgICAgdXNhZ2U6IGN1cnJlbnRNb2RlbFJlc3BvbnNlLnVzYWdlLFxuICAgICAgICAgICAgd2FybmluZ3M6IGN1cnJlbnRNb2RlbFJlc3BvbnNlLndhcm5pbmdzLFxuICAgICAgICAgICAgcHJvdmlkZXJNZXRhZGF0YTogY3VycmVudE1vZGVsUmVzcG9uc2UucHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgICAgIHJlcXVlc3Q6IGN1cnJlbnRNb2RlbFJlc3BvbnNlLnJlcXVlc3QgPz8ge30sXG4gICAgICAgICAgICByZXNwb25zZToge1xuICAgICAgICAgICAgICAuLi5jdXJyZW50TW9kZWxSZXNwb25zZS5yZXNwb25zZSxcbiAgICAgICAgICAgICAgLy8gZGVlcCBjbG9uZSBtc2dzIHRvIGF2b2lkIG11dGF0aW5nIHBhc3QgbWVzc2FnZXMgaW4gbXVsdGktc3RlcDpcbiAgICAgICAgICAgICAgbWVzc2FnZXM6IHN0cnVjdHVyZWRDbG9uZShyZXNwb25zZU1lc3NhZ2VzKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBsb2dXYXJuaW5ncyhjdXJyZW50TW9kZWxSZXNwb25zZS53YXJuaW5ncyA/PyBbXSk7XG5cbiAgICAgICAgICBzdGVwcy5wdXNoKGN1cnJlbnRTdGVwUmVzdWx0KTtcbiAgICAgICAgICBhd2FpdCBvblN0ZXBGaW5pc2g/LihjdXJyZW50U3RlcFJlc3VsdCk7XG4gICAgICAgIH0gd2hpbGUgKFxuICAgICAgICAgIC8vIHRoZXJlIGFyZSB0b29sIGNhbGxzOlxuICAgICAgICAgIGNsaWVudFRvb2xDYWxscy5sZW5ndGggPiAwICYmXG4gICAgICAgICAgLy8gYWxsIGN1cnJlbnQgdG9vbCBjYWxscyBoYXZlIG91dHB1dHMgKGluY2wuIGV4ZWN1dGlvbiBlcnJvcnMpOlxuICAgICAgICAgIGNsaWVudFRvb2xPdXRwdXRzLmxlbmd0aCA9PT0gY2xpZW50VG9vbENhbGxzLmxlbmd0aCAmJlxuICAgICAgICAgIC8vIGNvbnRpbnVlIHVudGlsIGEgc3RvcCBjb25kaXRpb24gaXMgbWV0OlxuICAgICAgICAgICEoYXdhaXQgaXNTdG9wQ29uZGl0aW9uTWV0KHsgc3RvcENvbmRpdGlvbnMsIHN0ZXBzIH0pKVxuICAgICAgICApO1xuXG4gICAgICAgIC8vIEFkZCByZXNwb25zZSBpbmZvcm1hdGlvbiB0byB0aGUgc3BhbjpcbiAgICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGVzKFxuICAgICAgICAgIHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAgICAgICAnYWkucmVzcG9uc2UuZmluaXNoUmVhc29uJzogY3VycmVudE1vZGVsUmVzcG9uc2UuZmluaXNoUmVhc29uLFxuICAgICAgICAgICAgICAnYWkucmVzcG9uc2UudGV4dCc6IHtcbiAgICAgICAgICAgICAgICBvdXRwdXQ6ICgpID0+IGV4dHJhY3RUZXh0Q29udGVudChjdXJyZW50TW9kZWxSZXNwb25zZS5jb250ZW50KSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLnRvb2xDYWxscyc6IHtcbiAgICAgICAgICAgICAgICBvdXRwdXQ6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHRvb2xDYWxscyA9IGFzVG9vbENhbGxzKGN1cnJlbnRNb2RlbFJlc3BvbnNlLmNvbnRlbnQpO1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIHRvb2xDYWxscyA9PSBudWxsXG4gICAgICAgICAgICAgICAgICAgID8gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgIDogSlNPTi5zdHJpbmdpZnkodG9vbENhbGxzKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAnYWkucmVzcG9uc2UucHJvdmlkZXJNZXRhZGF0YSc6IEpTT04uc3RyaW5naWZ5KFxuICAgICAgICAgICAgICAgIGN1cnJlbnRNb2RlbFJlc3BvbnNlLnByb3ZpZGVyTWV0YWRhdGEsXG4gICAgICAgICAgICAgICksXG5cbiAgICAgICAgICAgICAgLy8gVE9ETyByZW5hbWUgdGVsZW1ldHJ5IGF0dHJpYnV0ZXMgdG8gaW5wdXRUb2tlbnMgYW5kIG91dHB1dFRva2Vuc1xuICAgICAgICAgICAgICAnYWkudXNhZ2UucHJvbXB0VG9rZW5zJzogY3VycmVudE1vZGVsUmVzcG9uc2UudXNhZ2UuaW5wdXRUb2tlbnMsXG4gICAgICAgICAgICAgICdhaS51c2FnZS5jb21wbGV0aW9uVG9rZW5zJzpcbiAgICAgICAgICAgICAgICBjdXJyZW50TW9kZWxSZXNwb25zZS51c2FnZS5vdXRwdXRUb2tlbnMsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IGxhc3RTdGVwID0gc3RlcHNbc3RlcHMubGVuZ3RoIC0gMV07XG5cbiAgICAgICAgLy8gcGFyc2Ugb3V0cHV0IG9ubHkgaWYgdGhlIGxhc3Qgc3RlcCB3YXMgZmluaXNoZWQgd2l0aCBcInN0b3BcIjpcbiAgICAgICAgbGV0IHJlc29sdmVkT3V0cHV0O1xuICAgICAgICBpZiAobGFzdFN0ZXAuZmluaXNoUmVhc29uID09PSAnc3RvcCcpIHtcbiAgICAgICAgICByZXNvbHZlZE91dHB1dCA9IGF3YWl0IG91dHB1dD8ucGFyc2VPdXRwdXQoXG4gICAgICAgICAgICB7IHRleHQ6IGxhc3RTdGVwLnRleHQgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgcmVzcG9uc2U6IGxhc3RTdGVwLnJlc3BvbnNlLFxuICAgICAgICAgICAgICB1c2FnZTogbGFzdFN0ZXAudXNhZ2UsXG4gICAgICAgICAgICAgIGZpbmlzaFJlYXNvbjogbGFzdFN0ZXAuZmluaXNoUmVhc29uLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBEZWZhdWx0R2VuZXJhdGVUZXh0UmVzdWx0KHtcbiAgICAgICAgICBzdGVwcyxcbiAgICAgICAgICByZXNvbHZlZE91dHB1dCxcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgIH0pO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHRocm93IHdyYXBHYXRld2F5RXJyb3IoZXJyb3IpO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGV4ZWN1dGVUb29sczxUT09MUyBleHRlbmRzIFRvb2xTZXQ+KHtcbiAgdG9vbENhbGxzLFxuICB0b29scyxcbiAgdHJhY2VyLFxuICB0ZWxlbWV0cnksXG4gIG1lc3NhZ2VzLFxuICBhYm9ydFNpZ25hbCxcbiAgZXhwZXJpbWVudGFsX2NvbnRleHQsXG59OiB7XG4gIHRvb2xDYWxsczogQXJyYXk8VHlwZWRUb29sQ2FsbDxUT09MUz4+O1xuICB0b29sczogVE9PTFM7XG4gIHRyYWNlcjogVHJhY2VyO1xuICB0ZWxlbWV0cnk6IFRlbGVtZXRyeVNldHRpbmdzIHwgdW5kZWZpbmVkO1xuICBtZXNzYWdlczogTW9kZWxNZXNzYWdlW107XG4gIGFib3J0U2lnbmFsOiBBYm9ydFNpZ25hbCB8IHVuZGVmaW5lZDtcbiAgZXhwZXJpbWVudGFsX2NvbnRleHQ6IHVua25vd247XG59KTogUHJvbWlzZTxBcnJheTxUb29sT3V0cHV0PFRPT0xTPj4+IHtcbiAgY29uc3QgdG9vbE91dHB1dHMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICB0b29sQ2FsbHMubWFwKGFzeW5jICh7IHRvb2xDYWxsSWQsIHRvb2xOYW1lLCBpbnB1dCB9KSA9PiB7XG4gICAgICBjb25zdCB0b29sID0gdG9vbHNbdG9vbE5hbWVdO1xuXG4gICAgICBpZiAodG9vbD8uZXhlY3V0ZSA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZWNvcmRTcGFuKHtcbiAgICAgICAgbmFtZTogJ2FpLnRvb2xDYWxsJyxcbiAgICAgICAgYXR0cmlidXRlczogc2VsZWN0VGVsZW1ldHJ5QXR0cmlidXRlcyh7XG4gICAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgICAgIC4uLmFzc2VtYmxlT3BlcmF0aW9uTmFtZSh7XG4gICAgICAgICAgICAgIG9wZXJhdGlvbklkOiAnYWkudG9vbENhbGwnLFxuICAgICAgICAgICAgICB0ZWxlbWV0cnksXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICdhaS50b29sQ2FsbC5uYW1lJzogdG9vbE5hbWUsXG4gICAgICAgICAgICAnYWkudG9vbENhbGwuaWQnOiB0b29sQ2FsbElkLFxuICAgICAgICAgICAgJ2FpLnRvb2xDYWxsLmFyZ3MnOiB7XG4gICAgICAgICAgICAgIG91dHB1dDogKCkgPT4gSlNPTi5zdHJpbmdpZnkoaW5wdXQpLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgICAgdHJhY2VyLFxuICAgICAgICBmbjogYXN5bmMgc3BhbiA9PiB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHN0cmVhbSA9IGV4ZWN1dGVUb29sKHtcbiAgICAgICAgICAgICAgZXhlY3V0ZTogdG9vbC5leGVjdXRlIS5iaW5kKHRvb2wpLFxuICAgICAgICAgICAgICBpbnB1dCxcbiAgICAgICAgICAgICAgb3B0aW9uczoge1xuICAgICAgICAgICAgICAgIHRvb2xDYWxsSWQsXG4gICAgICAgICAgICAgICAgbWVzc2FnZXMsXG4gICAgICAgICAgICAgICAgYWJvcnRTaWduYWwsXG4gICAgICAgICAgICAgICAgZXhwZXJpbWVudGFsX2NvbnRleHQsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgbGV0IG91dHB1dDogdW5rbm93bjtcbiAgICAgICAgICAgIGZvciBhd2FpdCAoY29uc3QgcGFydCBvZiBzdHJlYW0pIHtcbiAgICAgICAgICAgICAgaWYgKHBhcnQudHlwZSA9PT0gJ2ZpbmFsJykge1xuICAgICAgICAgICAgICAgIG91dHB1dCA9IHBhcnQub3V0cHV0O1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBzcGFuLnNldEF0dHJpYnV0ZXMoXG4gICAgICAgICAgICAgICAgc2VsZWN0VGVsZW1ldHJ5QXR0cmlidXRlcyh7XG4gICAgICAgICAgICAgICAgICB0ZWxlbWV0cnksXG4gICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgICAgICAgICAgICdhaS50b29sQ2FsbC5yZXN1bHQnOiB7XG4gICAgICAgICAgICAgICAgICAgICAgb3V0cHV0OiAoKSA9PiBKU09OLnN0cmluZ2lmeShvdXRwdXQpLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGlnbm9yZWQpIHtcbiAgICAgICAgICAgICAgLy8gSlNPTiBzdHJpbmdpZnkgbWlnaHQgZmFpbCBpZiB0aGUgcmVzdWx0IGlzIG5vdCBzZXJpYWxpemFibGUsXG4gICAgICAgICAgICAgIC8vIGluIHdoaWNoIGNhc2Ugd2UganVzdCBpZ25vcmUgaXQuIEluIHRoZSBmdXR1cmUgd2UgbWlnaHQgd2FudCB0b1xuICAgICAgICAgICAgICAvLyBhZGQgYW4gb3B0aW9uYWwgc2VyaWFsaXplIG1ldGhvZCB0byB0aGUgdG9vbCBpbnRlcmZhY2UgYW5kIHdhcm5cbiAgICAgICAgICAgICAgLy8gaWYgdGhlIHJlc3VsdCBpcyBub3Qgc2VyaWFsaXphYmxlLlxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICB0eXBlOiAndG9vbC1yZXN1bHQnLFxuICAgICAgICAgICAgICB0b29sQ2FsbElkLFxuICAgICAgICAgICAgICB0b29sTmFtZSxcbiAgICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICAgIG91dHB1dCxcbiAgICAgICAgICAgICAgZHluYW1pYzogdG9vbC50eXBlID09PSAnZHluYW1pYycsXG4gICAgICAgICAgICB9IGFzIFR5cGVkVG9vbFJlc3VsdDxUT09MUz47XG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIHJlY29yZEVycm9yT25TcGFuKHNwYW4sIGVycm9yKTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIHR5cGU6ICd0b29sLWVycm9yJyxcbiAgICAgICAgICAgICAgdG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgdG9vbE5hbWUsXG4gICAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgICBlcnJvcixcbiAgICAgICAgICAgICAgZHluYW1pYzogdG9vbC50eXBlID09PSAnZHluYW1pYycsXG4gICAgICAgICAgICB9IGFzIFR5cGVkVG9vbEVycm9yPFRPT0xTPjtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KSxcbiAgKTtcblxuICByZXR1cm4gdG9vbE91dHB1dHMuZmlsdGVyKFxuICAgIChvdXRwdXQpOiBvdXRwdXQgaXMgTm9uTnVsbGFibGU8dHlwZW9mIG91dHB1dD4gPT4gb3V0cHV0ICE9IG51bGwsXG4gICk7XG59XG5cbmNsYXNzIERlZmF1bHRHZW5lcmF0ZVRleHRSZXN1bHQ8VE9PTFMgZXh0ZW5kcyBUb29sU2V0LCBPVVRQVVQ+XG4gIGltcGxlbWVudHMgR2VuZXJhdGVUZXh0UmVzdWx0PFRPT0xTLCBPVVRQVVQ+XG57XG4gIHJlYWRvbmx5IHN0ZXBzOiBHZW5lcmF0ZVRleHRSZXN1bHQ8VE9PTFMsIE9VVFBVVD5bJ3N0ZXBzJ107XG5cbiAgcHJpdmF0ZSByZWFkb25seSByZXNvbHZlZE91dHB1dDogT1VUUFVUO1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IHtcbiAgICBzdGVwczogR2VuZXJhdGVUZXh0UmVzdWx0PFRPT0xTLCBPVVRQVVQ+WydzdGVwcyddO1xuICAgIHJlc29sdmVkT3V0cHV0OiBPVVRQVVQ7XG4gIH0pIHtcbiAgICB0aGlzLnN0ZXBzID0gb3B0aW9ucy5zdGVwcztcbiAgICB0aGlzLnJlc29sdmVkT3V0cHV0ID0gb3B0aW9ucy5yZXNvbHZlZE91dHB1dDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0IGZpbmFsU3RlcCgpIHtcbiAgICByZXR1cm4gdGhpcy5zdGVwc1t0aGlzLnN0ZXBzLmxlbmd0aCAtIDFdO1xuICB9XG5cbiAgZ2V0IGNvbnRlbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmluYWxTdGVwLmNvbnRlbnQ7XG4gIH1cblxuICBnZXQgdGV4dCgpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAudGV4dDtcbiAgfVxuXG4gIGdldCBmaWxlcygpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAuZmlsZXM7XG4gIH1cblxuICBnZXQgcmVhc29uaW5nVGV4dCgpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAucmVhc29uaW5nVGV4dDtcbiAgfVxuXG4gIGdldCByZWFzb25pbmcoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmluYWxTdGVwLnJlYXNvbmluZztcbiAgfVxuXG4gIGdldCB0b29sQ2FsbHMoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmluYWxTdGVwLnRvb2xDYWxscztcbiAgfVxuXG4gIGdldCBzdGF0aWNUb29sQ2FsbHMoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmluYWxTdGVwLnN0YXRpY1Rvb2xDYWxscztcbiAgfVxuXG4gIGdldCBkeW5hbWljVG9vbENhbGxzKCkge1xuICAgIHJldHVybiB0aGlzLmZpbmFsU3RlcC5keW5hbWljVG9vbENhbGxzO1xuICB9XG5cbiAgZ2V0IHRvb2xSZXN1bHRzKCkge1xuICAgIHJldHVybiB0aGlzLmZpbmFsU3RlcC50b29sUmVzdWx0cztcbiAgfVxuXG4gIGdldCBzdGF0aWNUb29sUmVzdWx0cygpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAuc3RhdGljVG9vbFJlc3VsdHM7XG4gIH1cblxuICBnZXQgZHluYW1pY1Rvb2xSZXN1bHRzKCkge1xuICAgIHJldHVybiB0aGlzLmZpbmFsU3RlcC5keW5hbWljVG9vbFJlc3VsdHM7XG4gIH1cblxuICBnZXQgc291cmNlcygpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAuc291cmNlcztcbiAgfVxuXG4gIGdldCBmaW5pc2hSZWFzb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuZmluYWxTdGVwLmZpbmlzaFJlYXNvbjtcbiAgfVxuXG4gIGdldCB3YXJuaW5ncygpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAud2FybmluZ3M7XG4gIH1cblxuICBnZXQgcHJvdmlkZXJNZXRhZGF0YSgpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAucHJvdmlkZXJNZXRhZGF0YTtcbiAgfVxuXG4gIGdldCByZXNwb25zZSgpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAucmVzcG9uc2U7XG4gIH1cblxuICBnZXQgcmVxdWVzdCgpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAucmVxdWVzdDtcbiAgfVxuXG4gIGdldCB1c2FnZSgpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAudXNhZ2U7XG4gIH1cblxuICBnZXQgdG90YWxVc2FnZSgpIHtcbiAgICByZXR1cm4gdGhpcy5zdGVwcy5yZWR1Y2UoXG4gICAgICAodG90YWxVc2FnZSwgc3RlcCkgPT4ge1xuICAgICAgICByZXR1cm4gYWRkTGFuZ3VhZ2VNb2RlbFVzYWdlKHRvdGFsVXNhZ2UsIHN0ZXAudXNhZ2UpO1xuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgaW5wdXRUb2tlbnM6IHVuZGVmaW5lZCxcbiAgICAgICAgb3V0cHV0VG9rZW5zOiB1bmRlZmluZWQsXG4gICAgICAgIHRvdGFsVG9rZW5zOiB1bmRlZmluZWQsXG4gICAgICAgIHJlYXNvbmluZ1Rva2VuczogdW5kZWZpbmVkLFxuICAgICAgICBjYWNoZWRJbnB1dFRva2VuczogdW5kZWZpbmVkLFxuICAgICAgfSBhcyBMYW5ndWFnZU1vZGVsVXNhZ2UsXG4gICAgKTtcbiAgfVxuXG4gIGdldCBleHBlcmltZW50YWxfb3V0cHV0KCkge1xuICAgIGlmICh0aGlzLnJlc29sdmVkT3V0cHV0ID09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBOb091dHB1dFNwZWNpZmllZEVycm9yKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMucmVzb2x2ZWRPdXRwdXQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gYXNUb29sQ2FsbHMoY29udGVudDogQXJyYXk8TGFuZ3VhZ2VNb2RlbFYyQ29udGVudD4pIHtcbiAgY29uc3QgcGFydHMgPSBjb250ZW50LmZpbHRlcihcbiAgICAocGFydCk6IHBhcnQgaXMgTGFuZ3VhZ2VNb2RlbFYyVG9vbENhbGwgPT4gcGFydC50eXBlID09PSAndG9vbC1jYWxsJyxcbiAgKTtcblxuICBpZiAocGFydHMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHJldHVybiBwYXJ0cy5tYXAodG9vbENhbGwgPT4gKHtcbiAgICB0b29sQ2FsbElkOiB0b29sQ2FsbC50b29sQ2FsbElkLFxuICAgIHRvb2xOYW1lOiB0b29sQ2FsbC50b29sTmFtZSxcbiAgICBpbnB1dDogdG9vbENhbGwuaW5wdXQsXG4gIH0pKTtcbn1cblxuZnVuY3Rpb24gYXNDb250ZW50PFRPT0xTIGV4dGVuZHMgVG9vbFNldD4oe1xuICBjb250ZW50LFxuICB0b29sQ2FsbHMsXG4gIHRvb2xPdXRwdXRzLFxufToge1xuICBjb250ZW50OiBBcnJheTxMYW5ndWFnZU1vZGVsVjJDb250ZW50PjtcbiAgdG9vbENhbGxzOiBBcnJheTxUeXBlZFRvb2xDYWxsPFRPT0xTPj47XG4gIHRvb2xPdXRwdXRzOiBBcnJheTxUb29sT3V0cHV0PFRPT0xTPj47XG59KTogQXJyYXk8Q29udGVudFBhcnQ8VE9PTFM+PiB7XG4gIHJldHVybiBbXG4gICAgLi4uY29udGVudC5tYXAocGFydCA9PiB7XG4gICAgICBzd2l0Y2ggKHBhcnQudHlwZSkge1xuICAgICAgICBjYXNlICd0ZXh0JzpcbiAgICAgICAgY2FzZSAncmVhc29uaW5nJzpcbiAgICAgICAgY2FzZSAnc291cmNlJzpcbiAgICAgICAgICByZXR1cm4gcGFydDtcblxuICAgICAgICBjYXNlICdmaWxlJzoge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiAnZmlsZScgYXMgY29uc3QsXG4gICAgICAgICAgICBmaWxlOiBuZXcgRGVmYXVsdEdlbmVyYXRlZEZpbGUocGFydCksXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNhc2UgJ3Rvb2wtY2FsbCc6IHtcbiAgICAgICAgICByZXR1cm4gdG9vbENhbGxzLmZpbmQoXG4gICAgICAgICAgICB0b29sQ2FsbCA9PiB0b29sQ2FsbC50b29sQ2FsbElkID09PSBwYXJ0LnRvb2xDYWxsSWQsXG4gICAgICAgICAgKSE7XG4gICAgICAgIH1cblxuICAgICAgICBjYXNlICd0b29sLXJlc3VsdCc6IHtcbiAgICAgICAgICBjb25zdCB0b29sQ2FsbCA9IHRvb2xDYWxscy5maW5kKFxuICAgICAgICAgICAgdG9vbENhbGwgPT4gdG9vbENhbGwudG9vbENhbGxJZCA9PT0gcGFydC50b29sQ2FsbElkLFxuICAgICAgICAgICkhO1xuXG4gICAgICAgICAgaWYgKHRvb2xDYWxsID09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVG9vbCBjYWxsICR7cGFydC50b29sQ2FsbElkfSBub3QgZm91bmQuYCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHBhcnQuaXNFcnJvcikge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgdHlwZTogJ3Rvb2wtZXJyb3InIGFzIGNvbnN0LFxuICAgICAgICAgICAgICB0b29sQ2FsbElkOiBwYXJ0LnRvb2xDYWxsSWQsXG4gICAgICAgICAgICAgIHRvb2xOYW1lOiBwYXJ0LnRvb2xOYW1lIGFzIGtleW9mIFRPT0xTICYgc3RyaW5nLFxuICAgICAgICAgICAgICBpbnB1dDogdG9vbENhbGwuaW5wdXQsXG4gICAgICAgICAgICAgIGVycm9yOiBwYXJ0LnJlc3VsdCxcbiAgICAgICAgICAgICAgcHJvdmlkZXJFeGVjdXRlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgZHluYW1pYzogdG9vbENhbGwuZHluYW1pYyxcbiAgICAgICAgICAgIH0gYXMgVHlwZWRUb29sRXJyb3I8VE9PTFM+O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiAndG9vbC1yZXN1bHQnIGFzIGNvbnN0LFxuICAgICAgICAgICAgdG9vbENhbGxJZDogcGFydC50b29sQ2FsbElkLFxuICAgICAgICAgICAgdG9vbE5hbWU6IHBhcnQudG9vbE5hbWUgYXMga2V5b2YgVE9PTFMgJiBzdHJpbmcsXG4gICAgICAgICAgICBpbnB1dDogdG9vbENhbGwuaW5wdXQsXG4gICAgICAgICAgICBvdXRwdXQ6IHBhcnQucmVzdWx0LFxuICAgICAgICAgICAgcHJvdmlkZXJFeGVjdXRlZDogdHJ1ZSxcbiAgICAgICAgICAgIGR5bmFtaWM6IHRvb2xDYWxsLmR5bmFtaWMsXG4gICAgICAgICAgfSBhcyBUeXBlZFRvb2xSZXN1bHQ8VE9PTFM+O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSksXG4gICAgLi4udG9vbE91dHB1dHMsXG4gIF07XG59XG4iLCAiaW1wb3J0IHsgQUlTREtFcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuXG5jb25zdCBuYW1lID0gJ0FJX05vT3V0cHV0U3BlY2lmaWVkRXJyb3InO1xuY29uc3QgbWFya2VyID0gYHZlcmNlbC5haS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuLyoqXG5UaHJvd24gd2hlbiBubyBvdXRwdXQgdHlwZSBpcyBzcGVjaWZpZWQgYW5kIG91dHB1dC1yZWxhdGVkIG1ldGhvZHMgYXJlIGNhbGxlZC5cbiAqL1xuZXhwb3J0IGNsYXNzIE5vT3V0cHV0U3BlY2lmaWVkRXJyb3IgZXh0ZW5kcyBBSVNES0Vycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7IC8vIHVzZWQgaW4gaXNJbnN0YW5jZVxuXG4gIGNvbnN0cnVjdG9yKHsgbWVzc2FnZSA9ICdObyBvdXRwdXQgc3BlY2lmaWVkLicgfTogeyBtZXNzYWdlPzogc3RyaW5nIH0gPSB7fSkge1xuICAgIHN1cGVyKHsgbmFtZSwgbWVzc2FnZSB9KTtcbiAgfVxuXG4gIHN0YXRpYyBpc0luc3RhbmNlKGVycm9yOiB1bmtub3duKTogZXJyb3IgaXMgTm9PdXRwdXRTcGVjaWZpZWRFcnJvciB7XG4gICAgcmV0dXJuIEFJU0RLRXJyb3IuaGFzTWFya2VyKGVycm9yLCBtYXJrZXIpO1xuICB9XG59XG4iLCAiaW1wb3J0IHtcbiAgSW1hZ2VNb2RlbFYyQ2FsbFdhcm5pbmcsXG4gIExhbmd1YWdlTW9kZWxWMkNhbGxXYXJuaW5nLFxuICBTcGVlY2hNb2RlbFYyQ2FsbFdhcm5pbmcsXG4gIFRyYW5zY3JpcHRpb25Nb2RlbFYyQ2FsbFdhcm5pbmcsXG59IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuXG5leHBvcnQgdHlwZSBXYXJuaW5nID1cbiAgfCBMYW5ndWFnZU1vZGVsVjJDYWxsV2FybmluZ1xuICB8IEltYWdlTW9kZWxWMkNhbGxXYXJuaW5nXG4gIHwgU3BlZWNoTW9kZWxWMkNhbGxXYXJuaW5nXG4gIHwgVHJhbnNjcmlwdGlvbk1vZGVsVjJDYWxsV2FybmluZztcblxuZXhwb3J0IHR5cGUgTG9nV2FybmluZ3NGdW5jdGlvbiA9ICh3YXJuaW5nczogV2FybmluZ1tdKSA9PiB2b2lkO1xuXG4vKipcbiAqIEZvcm1hdHMgYSB3YXJuaW5nIG9iamVjdCBpbnRvIGEgaHVtYW4tcmVhZGFibGUgc3RyaW5nIHdpdGggY2xlYXIgQUkgU0RLIGJyYW5kaW5nXG4gKi9cbmZ1bmN0aW9uIGZvcm1hdFdhcm5pbmcod2FybmluZzogV2FybmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHByZWZpeCA9ICdBSSBTREsgV2FybmluZzonO1xuXG4gIHN3aXRjaCAod2FybmluZy50eXBlKSB7XG4gICAgY2FzZSAndW5zdXBwb3J0ZWQtc2V0dGluZyc6IHtcbiAgICAgIGxldCBtZXNzYWdlID0gYCR7cHJlZml4fSBUaGUgXCIke3dhcm5pbmcuc2V0dGluZ31cIiBzZXR0aW5nIGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhpcyBtb2RlbGA7XG4gICAgICBpZiAod2FybmluZy5kZXRhaWxzKSB7XG4gICAgICAgIG1lc3NhZ2UgKz0gYCAtICR7d2FybmluZy5kZXRhaWxzfWA7XG4gICAgICB9XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9XG5cbiAgICBjYXNlICd1bnN1cHBvcnRlZC10b29sJzoge1xuICAgICAgY29uc3QgdG9vbE5hbWUgPVxuICAgICAgICAnbmFtZScgaW4gd2FybmluZy50b29sID8gd2FybmluZy50b29sLm5hbWUgOiAndW5rbm93biB0b29sJztcbiAgICAgIGxldCBtZXNzYWdlID0gYCR7cHJlZml4fSBUaGUgdG9vbCBcIiR7dG9vbE5hbWV9XCIgaXMgbm90IHN1cHBvcnRlZCBieSB0aGlzIG1vZGVsYDtcbiAgICAgIGlmICh3YXJuaW5nLmRldGFpbHMpIHtcbiAgICAgICAgbWVzc2FnZSArPSBgIC0gJHt3YXJuaW5nLmRldGFpbHN9YDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH1cblxuICAgIGNhc2UgJ290aGVyJzoge1xuICAgICAgcmV0dXJuIGAke3ByZWZpeH0gJHt3YXJuaW5nLm1lc3NhZ2V9YDtcbiAgICB9XG5cbiAgICBkZWZhdWx0OiB7XG4gICAgICAvLyBGYWxsYmFjayBmb3IgYW55IHVua25vd24gd2FybmluZyB0eXBlc1xuICAgICAgcmV0dXJuIGAke3ByZWZpeH0gJHtKU09OLnN0cmluZ2lmeSh3YXJuaW5nLCBudWxsLCAyKX1gO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgRklSU1RfV0FSTklOR19JTkZPX01FU1NBR0UgPVxuICAnQUkgU0RLIFdhcm5pbmcgU3lzdGVtOiBUbyB0dXJuIG9mZiB3YXJuaW5nIGxvZ2dpbmcsIHNldCB0aGUgQUlfU0RLX0xPR19XQVJOSU5HUyBnbG9iYWwgdG8gZmFsc2UuJztcblxubGV0IGhhc0xvZ2dlZEJlZm9yZSA9IGZhbHNlO1xuXG5leHBvcnQgY29uc3QgbG9nV2FybmluZ3M6IExvZ1dhcm5pbmdzRnVuY3Rpb24gPSB3YXJuaW5ncyA9PiB7XG4gIC8vIGlmIHRoZSB3YXJuaW5ncyBhcnJheSBpcyBlbXB0eSwgZG8gbm90aGluZ1xuICBpZiAod2FybmluZ3MubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgbG9nZ2VyID0gZ2xvYmFsVGhpcy5BSV9TREtfTE9HX1dBUk5JTkdTO1xuXG4gIC8vIGlmIHRoZSBsb2dnZXIgaXMgc2V0IHRvIGZhbHNlLCBkbyBub3RoaW5nXG4gIGlmIChsb2dnZXIgPT09IGZhbHNlKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gdXNlIHRoZSBwcm92aWRlZCBsb2dnZXIgaWYgaXQgaXMgYSBmdW5jdGlvblxuICBpZiAodHlwZW9mIGxvZ2dlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGxvZ2dlcih3YXJuaW5ncyk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gZGlzcGxheSBpbmZvcm1hdGlvbiBub3RlIG9uIGZpcnN0IGNhbGxcbiAgaWYgKCFoYXNMb2dnZWRCZWZvcmUpIHtcbiAgICBoYXNMb2dnZWRCZWZvcmUgPSB0cnVlO1xuICAgIGNvbnNvbGUuaW5mbyhGSVJTVF9XQVJOSU5HX0lORk9fTUVTU0FHRSk7XG4gIH1cblxuICAvLyBkZWZhdWx0IGJlaGF2aW9yOiBsb2cgd2FybmluZ3MgdG8gdGhlIGNvbnNvbGVcbiAgZm9yIChjb25zdCB3YXJuaW5nIG9mIHdhcm5pbmdzKSB7XG4gICAgY29uc29sZS53YXJuKGZvcm1hdFdhcm5pbmcod2FybmluZykpO1xuICB9XG59O1xuXG4vLyBSZXNldCBmdW5jdGlvbiBmb3IgdGVzdGluZyBwdXJwb3Nlc1xuZXhwb3J0IGNvbnN0IHJlc2V0TG9nV2FybmluZ3NTdGF0ZSA9ICgpID0+IHtcbiAgaGFzTG9nZ2VkQmVmb3JlID0gZmFsc2U7XG59O1xuIiwgImltcG9ydCB7IGdhdGV3YXkgfSBmcm9tICdAYWktc2RrL2dhdGV3YXknO1xuaW1wb3J0IHtcbiAgRW1iZWRkaW5nTW9kZWxWMixcbiAgTGFuZ3VhZ2VNb2RlbFYyLFxuICBQcm92aWRlclYyLFxufSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcbmltcG9ydCB7IFVuc3VwcG9ydGVkTW9kZWxWZXJzaW9uRXJyb3IgfSBmcm9tICcuLi9lcnJvcic7XG5pbXBvcnQgeyBFbWJlZGRpbmdNb2RlbCB9IGZyb20gJy4uL3R5cGVzL2VtYmVkZGluZy1tb2RlbCc7XG5pbXBvcnQgeyBMYW5ndWFnZU1vZGVsIH0gZnJvbSAnLi4vdHlwZXMvbGFuZ3VhZ2UtbW9kZWwnO1xuXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZUxhbmd1YWdlTW9kZWwobW9kZWw6IExhbmd1YWdlTW9kZWwpOiBMYW5ndWFnZU1vZGVsVjIge1xuICBpZiAodHlwZW9mIG1vZGVsICE9PSAnc3RyaW5nJykge1xuICAgIGlmIChtb2RlbC5zcGVjaWZpY2F0aW9uVmVyc2lvbiAhPT0gJ3YyJykge1xuICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkTW9kZWxWZXJzaW9uRXJyb3Ioe1xuICAgICAgICB2ZXJzaW9uOiBtb2RlbC5zcGVjaWZpY2F0aW9uVmVyc2lvbixcbiAgICAgICAgcHJvdmlkZXI6IG1vZGVsLnByb3ZpZGVyLFxuICAgICAgICBtb2RlbElkOiBtb2RlbC5tb2RlbElkLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1vZGVsO1xuICB9XG5cbiAgcmV0dXJuIGdldEdsb2JhbFByb3ZpZGVyKCkubGFuZ3VhZ2VNb2RlbChtb2RlbCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlRW1iZWRkaW5nTW9kZWw8VkFMVUUgPSBzdHJpbmc+KFxuICBtb2RlbDogRW1iZWRkaW5nTW9kZWw8VkFMVUU+LFxuKTogRW1iZWRkaW5nTW9kZWxWMjxWQUxVRT4ge1xuICBpZiAodHlwZW9mIG1vZGVsICE9PSAnc3RyaW5nJykge1xuICAgIGlmIChtb2RlbC5zcGVjaWZpY2F0aW9uVmVyc2lvbiAhPT0gJ3YyJykge1xuICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkTW9kZWxWZXJzaW9uRXJyb3Ioe1xuICAgICAgICB2ZXJzaW9uOiBtb2RlbC5zcGVjaWZpY2F0aW9uVmVyc2lvbixcbiAgICAgICAgcHJvdmlkZXI6IG1vZGVsLnByb3ZpZGVyLFxuICAgICAgICBtb2RlbElkOiBtb2RlbC5tb2RlbElkLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1vZGVsO1xuICB9XG5cbiAgLy8gVE9ETyBBSSBTREsgNjogZmlndXJlIG91dCBob3cgdG8gY2xlYW5seSBzdXBwb3J0IGRpZmZlcmVudCBnZW5lcmljIHR5cGVzXG4gIHJldHVybiBnZXRHbG9iYWxQcm92aWRlcigpLnRleHRFbWJlZGRpbmdNb2RlbChcbiAgICBtb2RlbCxcbiAgKSBhcyBFbWJlZGRpbmdNb2RlbFYyPFZBTFVFPjtcbn1cblxuZnVuY3Rpb24gZ2V0R2xvYmFsUHJvdmlkZXIoKTogUHJvdmlkZXJWMiB7XG4gIHJldHVybiBnbG9iYWxUaGlzLkFJX1NES19ERUZBVUxUX1BST1ZJREVSID8/IGdhdGV3YXk7XG59XG4iLCAiZXhwb3J0IHtcbiAgQUlTREtFcnJvcixcbiAgQVBJQ2FsbEVycm9yLFxuICBFbXB0eVJlc3BvbnNlQm9keUVycm9yLFxuICBJbnZhbGlkUHJvbXB0RXJyb3IsXG4gIEludmFsaWRSZXNwb25zZURhdGFFcnJvcixcbiAgSlNPTlBhcnNlRXJyb3IsXG4gIExvYWRBUElLZXlFcnJvcixcbiAgTG9hZFNldHRpbmdFcnJvcixcbiAgTm9Db250ZW50R2VuZXJhdGVkRXJyb3IsXG4gIE5vU3VjaE1vZGVsRXJyb3IsXG4gIFRvb01hbnlFbWJlZGRpbmdWYWx1ZXNGb3JDYWxsRXJyb3IsXG4gIFR5cGVWYWxpZGF0aW9uRXJyb3IsXG4gIFVuc3VwcG9ydGVkRnVuY3Rpb25hbGl0eUVycm9yLFxufSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcblxuZXhwb3J0IHsgSW52YWxpZEFyZ3VtZW50RXJyb3IgfSBmcm9tICcuL2ludmFsaWQtYXJndW1lbnQtZXJyb3InO1xuZXhwb3J0IHsgSW52YWxpZFN0cmVhbVBhcnRFcnJvciB9IGZyb20gJy4vaW52YWxpZC1zdHJlYW0tcGFydC1lcnJvcic7XG5leHBvcnQgeyBJbnZhbGlkVG9vbElucHV0RXJyb3IgfSBmcm9tICcuL2ludmFsaWQtdG9vbC1pbnB1dC1lcnJvcic7XG5leHBvcnQgeyBNQ1BDbGllbnRFcnJvciB9IGZyb20gJy4vbWNwLWNsaWVudC1lcnJvcic7XG5leHBvcnQgeyBOb0ltYWdlR2VuZXJhdGVkRXJyb3IgfSBmcm9tICcuL25vLWltYWdlLWdlbmVyYXRlZC1lcnJvcic7XG5leHBvcnQgeyBOb09iamVjdEdlbmVyYXRlZEVycm9yIH0gZnJvbSAnLi9uby1vYmplY3QtZ2VuZXJhdGVkLWVycm9yJztcbmV4cG9ydCB7IE5vT3V0cHV0R2VuZXJhdGVkRXJyb3IgfSBmcm9tICcuL25vLW91dHB1dC1nZW5lcmF0ZWQtZXJyb3InO1xuZXhwb3J0IHsgTm9PdXRwdXRTcGVjaWZpZWRFcnJvciB9IGZyb20gJy4vbm8tb3V0cHV0LXNwZWNpZmllZC1lcnJvcic7XG5leHBvcnQgeyBOb1NwZWVjaEdlbmVyYXRlZEVycm9yIH0gZnJvbSAnLi9uby1zcGVlY2gtZ2VuZXJhdGVkLWVycm9yJztcbmV4cG9ydCB7IE5vU3VjaFRvb2xFcnJvciB9IGZyb20gJy4vbm8tc3VjaC10b29sLWVycm9yJztcbmV4cG9ydCB7IFRvb2xDYWxsUmVwYWlyRXJyb3IgfSBmcm9tICcuL3Rvb2wtY2FsbC1yZXBhaXItZXJyb3InO1xuZXhwb3J0IHsgVW5zdXBwb3J0ZWRNb2RlbFZlcnNpb25FcnJvciB9IGZyb20gJy4vdW5zdXBwb3J0ZWQtbW9kZWwtdmVyc2lvbi1lcnJvcic7XG5cbmV4cG9ydCB7IEludmFsaWREYXRhQ29udGVudEVycm9yIH0gZnJvbSAnLi4vcHJvbXB0L2ludmFsaWQtZGF0YS1jb250ZW50LWVycm9yJztcbmV4cG9ydCB7IEludmFsaWRNZXNzYWdlUm9sZUVycm9yIH0gZnJvbSAnLi4vcHJvbXB0L2ludmFsaWQtbWVzc2FnZS1yb2xlLWVycm9yJztcbmV4cG9ydCB7IE1lc3NhZ2VDb252ZXJzaW9uRXJyb3IgfSBmcm9tICcuLi9wcm9tcHQvbWVzc2FnZS1jb252ZXJzaW9uLWVycm9yJztcbmV4cG9ydCB7IERvd25sb2FkRXJyb3IgfSBmcm9tICcuLi91dGlsL2Rvd25sb2FkL2Rvd25sb2FkLWVycm9yJztcbmV4cG9ydCB7IFJldHJ5RXJyb3IgfSBmcm9tICcuLi91dGlsL3JldHJ5LWVycm9yJztcbiIsICJpbXBvcnQgeyBBSVNES0Vycm9yIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5cbmNvbnN0IG5hbWUgPSAnQUlfSW52YWxpZEFyZ3VtZW50RXJyb3InO1xuY29uc3QgbWFya2VyID0gYHZlcmNlbC5haS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuZXhwb3J0IGNsYXNzIEludmFsaWRBcmd1bWVudEVycm9yIGV4dGVuZHMgQUlTREtFcnJvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgW3N5bWJvbF0gPSB0cnVlOyAvLyB1c2VkIGluIGlzSW5zdGFuY2VcblxuICByZWFkb25seSBwYXJhbWV0ZXI6IHN0cmluZztcbiAgcmVhZG9ubHkgdmFsdWU6IHVua25vd247XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIHBhcmFtZXRlcixcbiAgICB2YWx1ZSxcbiAgICBtZXNzYWdlLFxuICB9OiB7XG4gICAgcGFyYW1ldGVyOiBzdHJpbmc7XG4gICAgdmFsdWU6IHVua25vd247XG4gICAgbWVzc2FnZTogc3RyaW5nO1xuICB9KSB7XG4gICAgc3VwZXIoe1xuICAgICAgbmFtZSxcbiAgICAgIG1lc3NhZ2U6IGBJbnZhbGlkIGFyZ3VtZW50IGZvciBwYXJhbWV0ZXIgJHtwYXJhbWV0ZXJ9OiAke21lc3NhZ2V9YCxcbiAgICB9KTtcblxuICAgIHRoaXMucGFyYW1ldGVyID0gcGFyYW1ldGVyO1xuICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgfVxuXG4gIHN0YXRpYyBpc0luc3RhbmNlKGVycm9yOiB1bmtub3duKTogZXJyb3IgaXMgSW52YWxpZEFyZ3VtZW50RXJyb3Ige1xuICAgIHJldHVybiBBSVNES0Vycm9yLmhhc01hcmtlcihlcnJvciwgbWFya2VyKTtcbiAgfVxufVxuIiwgImltcG9ydCB7IEFJU0RLRXJyb3IgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcbmltcG9ydCB7IFNpbmdsZVJlcXVlc3RUZXh0U3RyZWFtUGFydCB9IGZyb20gJy4uL2dlbmVyYXRlLXRleHQvcnVuLXRvb2xzLXRyYW5zZm9ybWF0aW9uJztcblxuY29uc3QgbmFtZSA9ICdBSV9JbnZhbGlkU3RyZWFtUGFydEVycm9yJztcbmNvbnN0IG1hcmtlciA9IGB2ZXJjZWwuYWkuZXJyb3IuJHtuYW1lfWA7XG5jb25zdCBzeW1ib2wgPSBTeW1ib2wuZm9yKG1hcmtlcik7XG5cbmV4cG9ydCBjbGFzcyBJbnZhbGlkU3RyZWFtUGFydEVycm9yIGV4dGVuZHMgQUlTREtFcnJvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgW3N5bWJvbF0gPSB0cnVlOyAvLyB1c2VkIGluIGlzSW5zdGFuY2VcblxuICByZWFkb25seSBjaHVuazogU2luZ2xlUmVxdWVzdFRleHRTdHJlYW1QYXJ0PGFueT47XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIGNodW5rLFxuICAgIG1lc3NhZ2UsXG4gIH06IHtcbiAgICBjaHVuazogU2luZ2xlUmVxdWVzdFRleHRTdHJlYW1QYXJ0PGFueT47XG4gICAgbWVzc2FnZTogc3RyaW5nO1xuICB9KSB7XG4gICAgc3VwZXIoeyBuYW1lLCBtZXNzYWdlIH0pO1xuXG4gICAgdGhpcy5jaHVuayA9IGNodW5rO1xuICB9XG5cbiAgc3RhdGljIGlzSW5zdGFuY2UoZXJyb3I6IHVua25vd24pOiBlcnJvciBpcyBJbnZhbGlkU3RyZWFtUGFydEVycm9yIHtcbiAgICByZXR1cm4gQUlTREtFcnJvci5oYXNNYXJrZXIoZXJyb3IsIG1hcmtlcik7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBBSVNES0Vycm9yLCBnZXRFcnJvck1lc3NhZ2UgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcblxuY29uc3QgbmFtZSA9ICdBSV9JbnZhbGlkVG9vbElucHV0RXJyb3InO1xuY29uc3QgbWFya2VyID0gYHZlcmNlbC5haS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuZXhwb3J0IGNsYXNzIEludmFsaWRUb29sSW5wdXRFcnJvciBleHRlbmRzIEFJU0RLRXJyb3Ige1xuICBwcml2YXRlIHJlYWRvbmx5IFtzeW1ib2xdID0gdHJ1ZTsgLy8gdXNlZCBpbiBpc0luc3RhbmNlXG5cbiAgcmVhZG9ubHkgdG9vbE5hbWU6IHN0cmluZztcbiAgcmVhZG9ubHkgdG9vbElucHV0OiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIHRvb2xJbnB1dCxcbiAgICB0b29sTmFtZSxcbiAgICBjYXVzZSxcbiAgICBtZXNzYWdlID0gYEludmFsaWQgaW5wdXQgZm9yIHRvb2wgJHt0b29sTmFtZX06ICR7Z2V0RXJyb3JNZXNzYWdlKGNhdXNlKX1gLFxuICB9OiB7XG4gICAgbWVzc2FnZT86IHN0cmluZztcbiAgICB0b29sSW5wdXQ6IHN0cmluZztcbiAgICB0b29sTmFtZTogc3RyaW5nO1xuICAgIGNhdXNlOiB1bmtub3duO1xuICB9KSB7XG4gICAgc3VwZXIoeyBuYW1lLCBtZXNzYWdlLCBjYXVzZSB9KTtcblxuICAgIHRoaXMudG9vbElucHV0ID0gdG9vbElucHV0O1xuICAgIHRoaXMudG9vbE5hbWUgPSB0b29sTmFtZTtcbiAgfVxuXG4gIHN0YXRpYyBpc0luc3RhbmNlKGVycm9yOiB1bmtub3duKTogZXJyb3IgaXMgSW52YWxpZFRvb2xJbnB1dEVycm9yIHtcbiAgICByZXR1cm4gQUlTREtFcnJvci5oYXNNYXJrZXIoZXJyb3IsIG1hcmtlcik7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBBSVNES0Vycm9yIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5cbmNvbnN0IG5hbWUgPSAnQUlfTUNQQ2xpZW50RXJyb3InO1xuY29uc3QgbWFya2VyID0gYHZlcmNlbC5haS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuLyoqXG4gKiBBbiBlcnJvciBvY2N1cnJlZCB3aXRoIHRoZSBNQ1AgY2xpZW50LlxuICovXG5leHBvcnQgY2xhc3MgTUNQQ2xpZW50RXJyb3IgZXh0ZW5kcyBBSVNES0Vycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7XG4gIHJlYWRvbmx5IGRhdGE/OiB1bmtub3duO1xuICByZWFkb25seSBjb2RlPzogbnVtYmVyO1xuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICBuYW1lID0gJ01DUENsaWVudEVycm9yJyxcbiAgICBtZXNzYWdlLFxuICAgIGNhdXNlLFxuICAgIGRhdGEsXG4gICAgY29kZSxcbiAgfToge1xuICAgIG5hbWU/OiBzdHJpbmc7XG4gICAgbWVzc2FnZTogc3RyaW5nO1xuICAgIGNhdXNlPzogdW5rbm93bjtcbiAgICBkYXRhPzogdW5rbm93bjtcbiAgICBjb2RlPzogbnVtYmVyO1xuICB9KSB7XG4gICAgc3VwZXIoeyBuYW1lLCBtZXNzYWdlLCBjYXVzZSB9KTtcbiAgICB0aGlzLmRhdGEgPSBkYXRhO1xuICAgIHRoaXMuY29kZSA9IGNvZGU7XG4gIH1cblxuICBzdGF0aWMgaXNJbnN0YW5jZShlcnJvcjogdW5rbm93bik6IGVycm9yIGlzIE1DUENsaWVudEVycm9yIHtcbiAgICByZXR1cm4gQUlTREtFcnJvci5oYXNNYXJrZXIoZXJyb3IsIG1hcmtlcik7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBBSVNES0Vycm9yIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQgeyBJbWFnZU1vZGVsUmVzcG9uc2VNZXRhZGF0YSB9IGZyb20gJy4uL3R5cGVzL2ltYWdlLW1vZGVsLXJlc3BvbnNlLW1ldGFkYXRhJztcblxuY29uc3QgbmFtZSA9ICdBSV9Ob0ltYWdlR2VuZXJhdGVkRXJyb3InO1xuY29uc3QgbWFya2VyID0gYHZlcmNlbC5haS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuLyoqXG5UaHJvd24gd2hlbiBubyBpbWFnZSBjb3VsZCBiZSBnZW5lcmF0ZWQuIFRoaXMgY2FuIGhhdmUgbXVsdGlwbGUgY2F1c2VzOlxuXG4tIFRoZSBtb2RlbCBmYWlsZWQgdG8gZ2VuZXJhdGUgYSByZXNwb25zZS5cbi0gVGhlIG1vZGVsIGdlbmVyYXRlZCBhIHJlc3BvbnNlIHRoYXQgY291bGQgbm90IGJlIHBhcnNlZC5cbiAqL1xuZXhwb3J0IGNsYXNzIE5vSW1hZ2VHZW5lcmF0ZWRFcnJvciBleHRlbmRzIEFJU0RLRXJyb3Ige1xuICBwcml2YXRlIHJlYWRvbmx5IFtzeW1ib2xdID0gdHJ1ZTsgLy8gdXNlZCBpbiBpc0luc3RhbmNlXG5cbiAgLyoqXG5UaGUgcmVzcG9uc2UgbWV0YWRhdGEgZm9yIGVhY2ggY2FsbC5cbiAgICovXG4gIHJlYWRvbmx5IHJlc3BvbnNlczogQXJyYXk8SW1hZ2VNb2RlbFJlc3BvbnNlTWV0YWRhdGE+IHwgdW5kZWZpbmVkO1xuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICBtZXNzYWdlID0gJ05vIGltYWdlIGdlbmVyYXRlZC4nLFxuICAgIGNhdXNlLFxuICAgIHJlc3BvbnNlcyxcbiAgfToge1xuICAgIG1lc3NhZ2U/OiBzdHJpbmc7XG4gICAgY2F1c2U/OiBFcnJvcjtcbiAgICByZXNwb25zZXM/OiBBcnJheTxJbWFnZU1vZGVsUmVzcG9uc2VNZXRhZGF0YT47XG4gIH0pIHtcbiAgICBzdXBlcih7IG5hbWUsIG1lc3NhZ2UsIGNhdXNlIH0pO1xuXG4gICAgdGhpcy5yZXNwb25zZXMgPSByZXNwb25zZXM7XG4gIH1cblxuICBzdGF0aWMgaXNJbnN0YW5jZShlcnJvcjogdW5rbm93bik6IGVycm9yIGlzIE5vSW1hZ2VHZW5lcmF0ZWRFcnJvciB7XG4gICAgcmV0dXJuIEFJU0RLRXJyb3IuaGFzTWFya2VyKGVycm9yLCBtYXJrZXIpO1xuICB9XG59XG4iLCAiaW1wb3J0IHsgQUlTREtFcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgRmluaXNoUmVhc29uIH0gZnJvbSAnLi4vdHlwZXMvbGFuZ3VhZ2UtbW9kZWwnO1xuaW1wb3J0IHsgTGFuZ3VhZ2VNb2RlbFJlc3BvbnNlTWV0YWRhdGEgfSBmcm9tICcuLi90eXBlcy9sYW5ndWFnZS1tb2RlbC1yZXNwb25zZS1tZXRhZGF0YSc7XG5pbXBvcnQgeyBMYW5ndWFnZU1vZGVsVXNhZ2UgfSBmcm9tICcuLi90eXBlcy91c2FnZSc7XG5cbmNvbnN0IG5hbWUgPSAnQUlfTm9PYmplY3RHZW5lcmF0ZWRFcnJvcic7XG5jb25zdCBtYXJrZXIgPSBgdmVyY2VsLmFpLmVycm9yLiR7bmFtZX1gO1xuY29uc3Qgc3ltYm9sID0gU3ltYm9sLmZvcihtYXJrZXIpO1xuXG4vKipcblRocm93biB3aGVuIG5vIG9iamVjdCBjb3VsZCBiZSBnZW5lcmF0ZWQuIFRoaXMgY2FuIGhhdmUgc2V2ZXJhbCBjYXVzZXM6XG5cbi0gVGhlIG1vZGVsIGZhaWxlZCB0byBnZW5lcmF0ZSBhIHJlc3BvbnNlLlxuLSBUaGUgbW9kZWwgZ2VuZXJhdGVkIGEgcmVzcG9uc2UgdGhhdCBjb3VsZCBub3QgYmUgcGFyc2VkLlxuLSBUaGUgbW9kZWwgZ2VuZXJhdGVkIGEgcmVzcG9uc2UgdGhhdCBjb3VsZCBub3QgYmUgdmFsaWRhdGVkIGFnYWluc3QgdGhlIHNjaGVtYS5cblxuVGhlIGVycm9yIGNvbnRhaW5zIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczpcblxuLSBgdGV4dGA6IFRoZSB0ZXh0IHRoYXQgd2FzIGdlbmVyYXRlZCBieSB0aGUgbW9kZWwuIFRoaXMgY2FuIGJlIHRoZSByYXcgdGV4dCBvciB0aGUgdG9vbCBjYWxsIHRleHQsIGRlcGVuZGluZyBvbiB0aGUgbW9kZWwuXG4gKi9cbmV4cG9ydCBjbGFzcyBOb09iamVjdEdlbmVyYXRlZEVycm9yIGV4dGVuZHMgQUlTREtFcnJvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgW3N5bWJvbF0gPSB0cnVlOyAvLyB1c2VkIGluIGlzSW5zdGFuY2VcblxuICAvKipcbiAgVGhlIHRleHQgdGhhdCB3YXMgZ2VuZXJhdGVkIGJ5IHRoZSBtb2RlbC4gVGhpcyBjYW4gYmUgdGhlIHJhdyB0ZXh0IG9yIHRoZSB0b29sIGNhbGwgdGV4dCwgZGVwZW5kaW5nIG9uIHRoZSBtb2RlbC5cbiAgICovXG4gIHJlYWRvbmx5IHRleHQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgVGhlIHJlc3BvbnNlIG1ldGFkYXRhLlxuICAgKi9cbiAgcmVhZG9ubHkgcmVzcG9uc2U6IExhbmd1YWdlTW9kZWxSZXNwb25zZU1ldGFkYXRhIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICBUaGUgdXNhZ2Ugb2YgdGhlIG1vZGVsLlxuICAgKi9cbiAgcmVhZG9ubHkgdXNhZ2U6IExhbmd1YWdlTW9kZWxVc2FnZSB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgUmVhc29uIHdoeSB0aGUgbW9kZWwgZmluaXNoZWQgZ2VuZXJhdGluZyBhIHJlc3BvbnNlLlxuICAgKi9cbiAgcmVhZG9ubHkgZmluaXNoUmVhc29uOiBGaW5pc2hSZWFzb24gfCB1bmRlZmluZWQ7XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIG1lc3NhZ2UgPSAnTm8gb2JqZWN0IGdlbmVyYXRlZC4nLFxuICAgIGNhdXNlLFxuICAgIHRleHQsXG4gICAgcmVzcG9uc2UsXG4gICAgdXNhZ2UsXG4gICAgZmluaXNoUmVhc29uLFxuICB9OiB7XG4gICAgbWVzc2FnZT86IHN0cmluZztcbiAgICBjYXVzZT86IEVycm9yO1xuICAgIHRleHQ/OiBzdHJpbmc7XG4gICAgcmVzcG9uc2U6IExhbmd1YWdlTW9kZWxSZXNwb25zZU1ldGFkYXRhO1xuICAgIHVzYWdlOiBMYW5ndWFnZU1vZGVsVXNhZ2U7XG4gICAgZmluaXNoUmVhc29uOiBGaW5pc2hSZWFzb247XG4gIH0pIHtcbiAgICBzdXBlcih7IG5hbWUsIG1lc3NhZ2UsIGNhdXNlIH0pO1xuXG4gICAgdGhpcy50ZXh0ID0gdGV4dDtcbiAgICB0aGlzLnJlc3BvbnNlID0gcmVzcG9uc2U7XG4gICAgdGhpcy51c2FnZSA9IHVzYWdlO1xuICAgIHRoaXMuZmluaXNoUmVhc29uID0gZmluaXNoUmVhc29uO1xuICB9XG5cbiAgc3RhdGljIGlzSW5zdGFuY2UoZXJyb3I6IHVua25vd24pOiBlcnJvciBpcyBOb09iamVjdEdlbmVyYXRlZEVycm9yIHtcbiAgICByZXR1cm4gQUlTREtFcnJvci5oYXNNYXJrZXIoZXJyb3IsIG1hcmtlcik7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBBSVNES0Vycm9yIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5cbmNvbnN0IG5hbWUgPSAnQUlfTm9PdXRwdXRHZW5lcmF0ZWRFcnJvcic7XG5jb25zdCBtYXJrZXIgPSBgdmVyY2VsLmFpLmVycm9yLiR7bmFtZX1gO1xuY29uc3Qgc3ltYm9sID0gU3ltYm9sLmZvcihtYXJrZXIpO1xuXG4vKipcblRocm93biB3aGVuIG5vIExMTSBvdXRwdXQgd2FzIGdlbmVyYXRlZCwgZS5nLiBiZWNhdXNlIG9mIGVycm9ycy5cbiAqL1xuZXhwb3J0IGNsYXNzIE5vT3V0cHV0R2VuZXJhdGVkRXJyb3IgZXh0ZW5kcyBBSVNES0Vycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7IC8vIHVzZWQgaW4gaXNJbnN0YW5jZVxuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICBtZXNzYWdlID0gJ05vIG91dHB1dCBnZW5lcmF0ZWQuJyxcbiAgICBjYXVzZSxcbiAgfToge1xuICAgIG1lc3NhZ2U/OiBzdHJpbmc7XG4gICAgY2F1c2U/OiBFcnJvcjtcbiAgfSA9IHt9KSB7XG4gICAgc3VwZXIoeyBuYW1lLCBtZXNzYWdlLCBjYXVzZSB9KTtcbiAgfVxuXG4gIHN0YXRpYyBpc0luc3RhbmNlKGVycm9yOiB1bmtub3duKTogZXJyb3IgaXMgTm9PdXRwdXRHZW5lcmF0ZWRFcnJvciB7XG4gICAgcmV0dXJuIEFJU0RLRXJyb3IuaGFzTWFya2VyKGVycm9yLCBtYXJrZXIpO1xuICB9XG59XG4iLCAiaW1wb3J0IHsgQUlTREtFcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgU3BlZWNoTW9kZWxSZXNwb25zZU1ldGFkYXRhIH0gZnJvbSAnLi4vdHlwZXMvc3BlZWNoLW1vZGVsLXJlc3BvbnNlLW1ldGFkYXRhJztcblxuLyoqXG5FcnJvciB0aGF0IGlzIHRocm93biB3aGVuIG5vIHNwZWVjaCBhdWRpbyB3YXMgZ2VuZXJhdGVkLlxuICovXG5leHBvcnQgY2xhc3MgTm9TcGVlY2hHZW5lcmF0ZWRFcnJvciBleHRlbmRzIEFJU0RLRXJyb3Ige1xuICByZWFkb25seSByZXNwb25zZXM6IEFycmF5PFNwZWVjaE1vZGVsUmVzcG9uc2VNZXRhZGF0YT47XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczogeyByZXNwb25zZXM6IEFycmF5PFNwZWVjaE1vZGVsUmVzcG9uc2VNZXRhZGF0YT4gfSkge1xuICAgIHN1cGVyKHtcbiAgICAgIG5hbWU6ICdBSV9Ob1NwZWVjaEdlbmVyYXRlZEVycm9yJyxcbiAgICAgIG1lc3NhZ2U6ICdObyBzcGVlY2ggYXVkaW8gZ2VuZXJhdGVkLicsXG4gICAgfSk7XG5cbiAgICB0aGlzLnJlc3BvbnNlcyA9IG9wdGlvbnMucmVzcG9uc2VzO1xuICB9XG59XG4iLCAiaW1wb3J0IHsgQUlTREtFcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuXG5jb25zdCBuYW1lID0gJ0FJX05vU3VjaFRvb2xFcnJvcic7XG5jb25zdCBtYXJrZXIgPSBgdmVyY2VsLmFpLmVycm9yLiR7bmFtZX1gO1xuY29uc3Qgc3ltYm9sID0gU3ltYm9sLmZvcihtYXJrZXIpO1xuXG5leHBvcnQgY2xhc3MgTm9TdWNoVG9vbEVycm9yIGV4dGVuZHMgQUlTREtFcnJvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgW3N5bWJvbF0gPSB0cnVlOyAvLyB1c2VkIGluIGlzSW5zdGFuY2VcblxuICByZWFkb25seSB0b29sTmFtZTogc3RyaW5nO1xuICByZWFkb25seSBhdmFpbGFibGVUb29sczogc3RyaW5nW10gfCB1bmRlZmluZWQ7XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIHRvb2xOYW1lLFxuICAgIGF2YWlsYWJsZVRvb2xzID0gdW5kZWZpbmVkLFxuICAgIG1lc3NhZ2UgPSBgTW9kZWwgdHJpZWQgdG8gY2FsbCB1bmF2YWlsYWJsZSB0b29sICcke3Rvb2xOYW1lfScuICR7XG4gICAgICBhdmFpbGFibGVUb29scyA9PT0gdW5kZWZpbmVkXG4gICAgICAgID8gJ05vIHRvb2xzIGFyZSBhdmFpbGFibGUuJ1xuICAgICAgICA6IGBBdmFpbGFibGUgdG9vbHM6ICR7YXZhaWxhYmxlVG9vbHMuam9pbignLCAnKX0uYFxuICAgIH1gLFxuICB9OiB7XG4gICAgdG9vbE5hbWU6IHN0cmluZztcbiAgICBhdmFpbGFibGVUb29scz86IHN0cmluZ1tdIHwgdW5kZWZpbmVkO1xuICAgIG1lc3NhZ2U/OiBzdHJpbmc7XG4gIH0pIHtcbiAgICBzdXBlcih7IG5hbWUsIG1lc3NhZ2UgfSk7XG5cbiAgICB0aGlzLnRvb2xOYW1lID0gdG9vbE5hbWU7XG4gICAgdGhpcy5hdmFpbGFibGVUb29scyA9IGF2YWlsYWJsZVRvb2xzO1xuICB9XG5cbiAgc3RhdGljIGlzSW5zdGFuY2UoZXJyb3I6IHVua25vd24pOiBlcnJvciBpcyBOb1N1Y2hUb29sRXJyb3Ige1xuICAgIHJldHVybiBBSVNES0Vycm9yLmhhc01hcmtlcihlcnJvciwgbWFya2VyKTtcbiAgfVxufVxuIiwgImltcG9ydCB7IEFJU0RLRXJyb3IsIGdldEVycm9yTWVzc2FnZSB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgSW52YWxpZFRvb2xJbnB1dEVycm9yIH0gZnJvbSAnLi9pbnZhbGlkLXRvb2wtaW5wdXQtZXJyb3InO1xuaW1wb3J0IHsgTm9TdWNoVG9vbEVycm9yIH0gZnJvbSAnLi9uby1zdWNoLXRvb2wtZXJyb3InO1xuXG5jb25zdCBuYW1lID0gJ0FJX1Rvb2xDYWxsUmVwYWlyRXJyb3InO1xuY29uc3QgbWFya2VyID0gYHZlcmNlbC5haS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuZXhwb3J0IGNsYXNzIFRvb2xDYWxsUmVwYWlyRXJyb3IgZXh0ZW5kcyBBSVNES0Vycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7IC8vIHVzZWQgaW4gaXNJbnN0YW5jZVxuXG4gIHJlYWRvbmx5IG9yaWdpbmFsRXJyb3I6IE5vU3VjaFRvb2xFcnJvciB8IEludmFsaWRUb29sSW5wdXRFcnJvcjtcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgY2F1c2UsXG4gICAgb3JpZ2luYWxFcnJvcixcbiAgICBtZXNzYWdlID0gYEVycm9yIHJlcGFpcmluZyB0b29sIGNhbGw6ICR7Z2V0RXJyb3JNZXNzYWdlKGNhdXNlKX1gLFxuICB9OiB7XG4gICAgbWVzc2FnZT86IHN0cmluZztcbiAgICBjYXVzZTogdW5rbm93bjtcbiAgICBvcmlnaW5hbEVycm9yOiBOb1N1Y2hUb29sRXJyb3IgfCBJbnZhbGlkVG9vbElucHV0RXJyb3I7XG4gIH0pIHtcbiAgICBzdXBlcih7IG5hbWUsIG1lc3NhZ2UsIGNhdXNlIH0pO1xuICAgIHRoaXMub3JpZ2luYWxFcnJvciA9IG9yaWdpbmFsRXJyb3I7XG4gIH1cblxuICBzdGF0aWMgaXNJbnN0YW5jZShlcnJvcjogdW5rbm93bik6IGVycm9yIGlzIFRvb2xDYWxsUmVwYWlyRXJyb3Ige1xuICAgIHJldHVybiBBSVNES0Vycm9yLmhhc01hcmtlcihlcnJvciwgbWFya2VyKTtcbiAgfVxufVxuIiwgImltcG9ydCB7IEFJU0RLRXJyb3IgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcblxuLyoqXG5FcnJvciB0aGF0IGlzIHRocm93biB3aGVuIGEgbW9kZWwgd2l0aCBhbiB1bnN1cHBvcnRlZCB2ZXJzaW9uIGlzIHVzZWQuXG4gKi9cbmV4cG9ydCBjbGFzcyBVbnN1cHBvcnRlZE1vZGVsVmVyc2lvbkVycm9yIGV4dGVuZHMgQUlTREtFcnJvciB7XG4gIHJlYWRvbmx5IHZlcnNpb246IHN0cmluZztcbiAgcmVhZG9ubHkgcHJvdmlkZXI6IHN0cmluZztcbiAgcmVhZG9ubHkgbW9kZWxJZDogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IHsgdmVyc2lvbjogc3RyaW5nOyBwcm92aWRlcjogc3RyaW5nOyBtb2RlbElkOiBzdHJpbmcgfSkge1xuICAgIHN1cGVyKHtcbiAgICAgIG5hbWU6ICdBSV9VbnN1cHBvcnRlZE1vZGVsVmVyc2lvbkVycm9yJyxcbiAgICAgIG1lc3NhZ2U6XG4gICAgICAgIGBVbnN1cHBvcnRlZCBtb2RlbCB2ZXJzaW9uICR7b3B0aW9ucy52ZXJzaW9ufSBmb3IgcHJvdmlkZXIgXCIke29wdGlvbnMucHJvdmlkZXJ9XCIgYW5kIG1vZGVsIFwiJHtvcHRpb25zLm1vZGVsSWR9XCIuIGAgK1xuICAgICAgICBgQUkgU0RLIDUgb25seSBzdXBwb3J0cyBtb2RlbHMgdGhhdCBpbXBsZW1lbnQgc3BlY2lmaWNhdGlvbiB2ZXJzaW9uIFwidjJcIi5gLFxuICAgIH0pO1xuXG4gICAgdGhpcy52ZXJzaW9uID0gb3B0aW9ucy52ZXJzaW9uO1xuICAgIHRoaXMucHJvdmlkZXIgPSBvcHRpb25zLnByb3ZpZGVyO1xuICAgIHRoaXMubW9kZWxJZCA9IG9wdGlvbnMubW9kZWxJZDtcbiAgfVxufVxuIiwgImltcG9ydCB7IEFJU0RLRXJyb3IgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcblxuY29uc3QgbmFtZSA9ICdBSV9JbnZhbGlkRGF0YUNvbnRlbnRFcnJvcic7XG5jb25zdCBtYXJrZXIgPSBgdmVyY2VsLmFpLmVycm9yLiR7bmFtZX1gO1xuY29uc3Qgc3ltYm9sID0gU3ltYm9sLmZvcihtYXJrZXIpO1xuXG5leHBvcnQgY2xhc3MgSW52YWxpZERhdGFDb250ZW50RXJyb3IgZXh0ZW5kcyBBSVNES0Vycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7IC8vIHVzZWQgaW4gaXNJbnN0YW5jZVxuXG4gIHJlYWRvbmx5IGNvbnRlbnQ6IHVua25vd247XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIGNvbnRlbnQsXG4gICAgY2F1c2UsXG4gICAgbWVzc2FnZSA9IGBJbnZhbGlkIGRhdGEgY29udGVudC4gRXhwZWN0ZWQgYSBiYXNlNjQgc3RyaW5nLCBVaW50OEFycmF5LCBBcnJheUJ1ZmZlciwgb3IgQnVmZmVyLCBidXQgZ290ICR7dHlwZW9mIGNvbnRlbnR9LmAsXG4gIH06IHtcbiAgICBjb250ZW50OiB1bmtub3duO1xuICAgIGNhdXNlPzogdW5rbm93bjtcbiAgICBtZXNzYWdlPzogc3RyaW5nO1xuICB9KSB7XG4gICAgc3VwZXIoeyBuYW1lLCBtZXNzYWdlLCBjYXVzZSB9KTtcblxuICAgIHRoaXMuY29udGVudCA9IGNvbnRlbnQ7XG4gIH1cblxuICBzdGF0aWMgaXNJbnN0YW5jZShlcnJvcjogdW5rbm93bik6IGVycm9yIGlzIEludmFsaWREYXRhQ29udGVudEVycm9yIHtcbiAgICByZXR1cm4gQUlTREtFcnJvci5oYXNNYXJrZXIoZXJyb3IsIG1hcmtlcik7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBBSVNES0Vycm9yIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5cbmNvbnN0IG5hbWUgPSAnQUlfSW52YWxpZE1lc3NhZ2VSb2xlRXJyb3InO1xuY29uc3QgbWFya2VyID0gYHZlcmNlbC5haS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuZXhwb3J0IGNsYXNzIEludmFsaWRNZXNzYWdlUm9sZUVycm9yIGV4dGVuZHMgQUlTREtFcnJvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgW3N5bWJvbF0gPSB0cnVlOyAvLyB1c2VkIGluIGlzSW5zdGFuY2VcblxuICByZWFkb25seSByb2xlOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIHJvbGUsXG4gICAgbWVzc2FnZSA9IGBJbnZhbGlkIG1lc3NhZ2Ugcm9sZTogJyR7cm9sZX0nLiBNdXN0IGJlIG9uZSBvZjogXCJzeXN0ZW1cIiwgXCJ1c2VyXCIsIFwiYXNzaXN0YW50XCIsIFwidG9vbFwiLmAsXG4gIH06IHtcbiAgICByb2xlOiBzdHJpbmc7XG4gICAgbWVzc2FnZT86IHN0cmluZztcbiAgfSkge1xuICAgIHN1cGVyKHsgbmFtZSwgbWVzc2FnZSB9KTtcblxuICAgIHRoaXMucm9sZSA9IHJvbGU7XG4gIH1cblxuICBzdGF0aWMgaXNJbnN0YW5jZShlcnJvcjogdW5rbm93bik6IGVycm9yIGlzIEludmFsaWRNZXNzYWdlUm9sZUVycm9yIHtcbiAgICByZXR1cm4gQUlTREtFcnJvci5oYXNNYXJrZXIoZXJyb3IsIG1hcmtlcik7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBBSVNES0Vycm9yIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQgeyBVSU1lc3NhZ2UgfSBmcm9tICcuLi91aS91aS1tZXNzYWdlcyc7XG5cbmNvbnN0IG5hbWUgPSAnQUlfTWVzc2FnZUNvbnZlcnNpb25FcnJvcic7XG5jb25zdCBtYXJrZXIgPSBgdmVyY2VsLmFpLmVycm9yLiR7bmFtZX1gO1xuY29uc3Qgc3ltYm9sID0gU3ltYm9sLmZvcihtYXJrZXIpO1xuXG5leHBvcnQgY2xhc3MgTWVzc2FnZUNvbnZlcnNpb25FcnJvciBleHRlbmRzIEFJU0RLRXJyb3Ige1xuICBwcml2YXRlIHJlYWRvbmx5IFtzeW1ib2xdID0gdHJ1ZTsgLy8gdXNlZCBpbiBpc0luc3RhbmNlXG5cbiAgcmVhZG9ubHkgb3JpZ2luYWxNZXNzYWdlOiBPbWl0PFVJTWVzc2FnZSwgJ2lkJz47XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIG9yaWdpbmFsTWVzc2FnZSxcbiAgICBtZXNzYWdlLFxuICB9OiB7XG4gICAgb3JpZ2luYWxNZXNzYWdlOiBPbWl0PFVJTWVzc2FnZSwgJ2lkJz47XG4gICAgbWVzc2FnZTogc3RyaW5nO1xuICB9KSB7XG4gICAgc3VwZXIoeyBuYW1lLCBtZXNzYWdlIH0pO1xuXG4gICAgdGhpcy5vcmlnaW5hbE1lc3NhZ2UgPSBvcmlnaW5hbE1lc3NhZ2U7XG4gIH1cblxuICBzdGF0aWMgaXNJbnN0YW5jZShlcnJvcjogdW5rbm93bik6IGVycm9yIGlzIE1lc3NhZ2VDb252ZXJzaW9uRXJyb3Ige1xuICAgIHJldHVybiBBSVNES0Vycm9yLmhhc01hcmtlcihlcnJvciwgbWFya2VyKTtcbiAgfVxufVxuIiwgImltcG9ydCB7IEFJU0RLRXJyb3IgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcblxuY29uc3QgbmFtZSA9ICdBSV9Eb3dubG9hZEVycm9yJztcbmNvbnN0IG1hcmtlciA9IGB2ZXJjZWwuYWkuZXJyb3IuJHtuYW1lfWA7XG5jb25zdCBzeW1ib2wgPSBTeW1ib2wuZm9yKG1hcmtlcik7XG5cbmV4cG9ydCBjbGFzcyBEb3dubG9hZEVycm9yIGV4dGVuZHMgQUlTREtFcnJvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgW3N5bWJvbF0gPSB0cnVlOyAvLyB1c2VkIGluIGlzSW5zdGFuY2VcblxuICByZWFkb25seSB1cmw6IHN0cmluZztcbiAgcmVhZG9ubHkgc3RhdHVzQ29kZT86IG51bWJlcjtcbiAgcmVhZG9ubHkgc3RhdHVzVGV4dD86IHN0cmluZztcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgdXJsLFxuICAgIHN0YXR1c0NvZGUsXG4gICAgc3RhdHVzVGV4dCxcbiAgICBjYXVzZSxcbiAgICBtZXNzYWdlID0gY2F1c2UgPT0gbnVsbFxuICAgICAgPyBgRmFpbGVkIHRvIGRvd25sb2FkICR7dXJsfTogJHtzdGF0dXNDb2RlfSAke3N0YXR1c1RleHR9YFxuICAgICAgOiBgRmFpbGVkIHRvIGRvd25sb2FkICR7dXJsfTogJHtjYXVzZX1gLFxuICB9OiB7XG4gICAgdXJsOiBzdHJpbmc7XG4gICAgc3RhdHVzQ29kZT86IG51bWJlcjtcbiAgICBzdGF0dXNUZXh0Pzogc3RyaW5nO1xuICAgIG1lc3NhZ2U/OiBzdHJpbmc7XG4gICAgY2F1c2U/OiB1bmtub3duO1xuICB9KSB7XG4gICAgc3VwZXIoeyBuYW1lLCBtZXNzYWdlLCBjYXVzZSB9KTtcblxuICAgIHRoaXMudXJsID0gdXJsO1xuICAgIHRoaXMuc3RhdHVzQ29kZSA9IHN0YXR1c0NvZGU7XG4gICAgdGhpcy5zdGF0dXNUZXh0ID0gc3RhdHVzVGV4dDtcbiAgfVxuXG4gIHN0YXRpYyBpc0luc3RhbmNlKGVycm9yOiB1bmtub3duKTogZXJyb3IgaXMgRG93bmxvYWRFcnJvciB7XG4gICAgcmV0dXJuIEFJU0RLRXJyb3IuaGFzTWFya2VyKGVycm9yLCBtYXJrZXIpO1xuICB9XG59XG4iLCAiaW1wb3J0IHsgQUlTREtFcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuXG5jb25zdCBuYW1lID0gJ0FJX1JldHJ5RXJyb3InO1xuY29uc3QgbWFya2VyID0gYHZlcmNlbC5haS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuZXhwb3J0IHR5cGUgUmV0cnlFcnJvclJlYXNvbiA9XG4gIHwgJ21heFJldHJpZXNFeGNlZWRlZCdcbiAgfCAnZXJyb3JOb3RSZXRyeWFibGUnXG4gIHwgJ2Fib3J0JztcblxuZXhwb3J0IGNsYXNzIFJldHJ5RXJyb3IgZXh0ZW5kcyBBSVNES0Vycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7IC8vIHVzZWQgaW4gaXNJbnN0YW5jZVxuXG4gIC8vIG5vdGU6IHByb3BlcnR5IG9yZGVyIGRldGVybWluZXMgZGVidWdnaW5nIG91dHB1dFxuICByZWFkb25seSByZWFzb246IFJldHJ5RXJyb3JSZWFzb247XG4gIHJlYWRvbmx5IGxhc3RFcnJvcjogdW5rbm93bjtcbiAgcmVhZG9ubHkgZXJyb3JzOiBBcnJheTx1bmtub3duPjtcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgbWVzc2FnZSxcbiAgICByZWFzb24sXG4gICAgZXJyb3JzLFxuICB9OiB7XG4gICAgbWVzc2FnZTogc3RyaW5nO1xuICAgIHJlYXNvbjogUmV0cnlFcnJvclJlYXNvbjtcbiAgICBlcnJvcnM6IEFycmF5PHVua25vd24+O1xuICB9KSB7XG4gICAgc3VwZXIoeyBuYW1lLCBtZXNzYWdlIH0pO1xuXG4gICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgdGhpcy5lcnJvcnMgPSBlcnJvcnM7XG5cbiAgICAvLyBzZXBhcmF0ZSBvdXIgbGFzdCBlcnJvciB0byBtYWtlIGRlYnVnZ2luZyB2aWEgbG9nIGVhc2llcjpcbiAgICB0aGlzLmxhc3RFcnJvciA9IGVycm9yc1tlcnJvcnMubGVuZ3RoIC0gMV07XG4gIH1cblxuICBzdGF0aWMgaXNJbnN0YW5jZShlcnJvcjogdW5rbm93bik6IGVycm9yIGlzIFJldHJ5RXJyb3Ige1xuICAgIHJldHVybiBBSVNES0Vycm9yLmhhc01hcmtlcihlcnJvciwgbWFya2VyKTtcbiAgfVxufVxuIiwgImltcG9ydCB7XG4gIExhbmd1YWdlTW9kZWxWMkZpbGVQYXJ0LFxuICBMYW5ndWFnZU1vZGVsVjJNZXNzYWdlLFxuICBMYW5ndWFnZU1vZGVsVjJQcm9tcHQsXG4gIExhbmd1YWdlTW9kZWxWMlRleHRQYXJ0LFxufSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcbmltcG9ydCB7XG4gIERhdGFDb250ZW50LFxuICBGaWxlUGFydCxcbiAgSW1hZ2VQYXJ0LFxuICBpc1VybFN1cHBvcnRlZCxcbiAgTW9kZWxNZXNzYWdlLFxuICBUZXh0UGFydCxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQge1xuICBkZXRlY3RNZWRpYVR5cGUsXG4gIGltYWdlTWVkaWFUeXBlU2lnbmF0dXJlcyxcbn0gZnJvbSAnLi4vdXRpbC9kZXRlY3QtbWVkaWEtdHlwZSc7XG5pbXBvcnQge1xuICBjcmVhdGVEZWZhdWx0RG93bmxvYWRGdW5jdGlvbixcbiAgRG93bmxvYWRGdW5jdGlvbixcbn0gZnJvbSAnLi4vdXRpbC9kb3dubG9hZC9kb3dubG9hZC1mdW5jdGlvbic7XG5pbXBvcnQgeyBjb252ZXJ0VG9MYW5ndWFnZU1vZGVsVjJEYXRhQ29udGVudCB9IGZyb20gJy4vZGF0YS1jb250ZW50JztcbmltcG9ydCB7IEludmFsaWRNZXNzYWdlUm9sZUVycm9yIH0gZnJvbSAnLi9pbnZhbGlkLW1lc3NhZ2Utcm9sZS1lcnJvcic7XG5pbXBvcnQgeyBTdGFuZGFyZGl6ZWRQcm9tcHQgfSBmcm9tICcuL3N0YW5kYXJkaXplLXByb21wdCc7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjb252ZXJ0VG9MYW5ndWFnZU1vZGVsUHJvbXB0KHtcbiAgcHJvbXB0LFxuICBzdXBwb3J0ZWRVcmxzLFxuICBkb3dubG9hZCA9IGNyZWF0ZURlZmF1bHREb3dubG9hZEZ1bmN0aW9uKCksXG59OiB7XG4gIHByb21wdDogU3RhbmRhcmRpemVkUHJvbXB0O1xuICBzdXBwb3J0ZWRVcmxzOiBSZWNvcmQ8c3RyaW5nLCBSZWdFeHBbXT47XG4gIGRvd25sb2FkOiBEb3dubG9hZEZ1bmN0aW9uIHwgdW5kZWZpbmVkO1xufSk6IFByb21pc2U8TGFuZ3VhZ2VNb2RlbFYyUHJvbXB0PiB7XG4gIGNvbnN0IGRvd25sb2FkZWRBc3NldHMgPSBhd2FpdCBkb3dubG9hZEFzc2V0cyhcbiAgICBwcm9tcHQubWVzc2FnZXMsXG4gICAgZG93bmxvYWQsXG4gICAgc3VwcG9ydGVkVXJscyxcbiAgKTtcblxuICByZXR1cm4gW1xuICAgIC4uLihwcm9tcHQuc3lzdGVtICE9IG51bGxcbiAgICAgID8gW3sgcm9sZTogJ3N5c3RlbScgYXMgY29uc3QsIGNvbnRlbnQ6IHByb21wdC5zeXN0ZW0gfV1cbiAgICAgIDogW10pLFxuICAgIC4uLnByb21wdC5tZXNzYWdlcy5tYXAobWVzc2FnZSA9PlxuICAgICAgY29udmVydFRvTGFuZ3VhZ2VNb2RlbE1lc3NhZ2UoeyBtZXNzYWdlLCBkb3dubG9hZGVkQXNzZXRzIH0pLFxuICAgICksXG4gIF07XG59XG5cbi8qKlxuICogQ29udmVydCBhIE1vZGVsTWVzc2FnZSB0byBhIExhbmd1YWdlTW9kZWxWMk1lc3NhZ2UuXG4gKlxuICogQHBhcmFtIG1lc3NhZ2UgVGhlIE1vZGVsTWVzc2FnZSB0byBjb252ZXJ0LlxuICogQHBhcmFtIGRvd25sb2FkZWRBc3NldHMgQSBtYXAgb2YgVVJMcyB0byB0aGVpciBkb3dubG9hZGVkIGRhdGEuIE9ubHlcbiAqICAgYXZhaWxhYmxlIGlmIHRoZSBtb2RlbCBkb2VzIG5vdCBzdXBwb3J0IFVSTHMsIG51bGwgb3RoZXJ3aXNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY29udmVydFRvTGFuZ3VhZ2VNb2RlbE1lc3NhZ2Uoe1xuICBtZXNzYWdlLFxuICBkb3dubG9hZGVkQXNzZXRzLFxufToge1xuICBtZXNzYWdlOiBNb2RlbE1lc3NhZ2U7XG4gIGRvd25sb2FkZWRBc3NldHM6IFJlY29yZDxcbiAgICBzdHJpbmcsXG4gICAgeyBtZWRpYVR5cGU6IHN0cmluZyB8IHVuZGVmaW5lZDsgZGF0YTogVWludDhBcnJheSB9XG4gID47XG59KTogTGFuZ3VhZ2VNb2RlbFYyTWVzc2FnZSB7XG4gIGNvbnN0IHJvbGUgPSBtZXNzYWdlLnJvbGU7XG4gIHN3aXRjaCAocm9sZSkge1xuICAgIGNhc2UgJ3N5c3RlbSc6IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHJvbGU6ICdzeXN0ZW0nLFxuICAgICAgICBjb250ZW50OiBtZXNzYWdlLmNvbnRlbnQsXG4gICAgICAgIHByb3ZpZGVyT3B0aW9uczogbWVzc2FnZS5wcm92aWRlck9wdGlvbnMsXG4gICAgICB9O1xuICAgIH1cblxuICAgIGNhc2UgJ3VzZXInOiB7XG4gICAgICBpZiAodHlwZW9mIG1lc3NhZ2UuY29udGVudCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICByb2xlOiAndXNlcicsXG4gICAgICAgICAgY29udGVudDogW3sgdHlwZTogJ3RleHQnLCB0ZXh0OiBtZXNzYWdlLmNvbnRlbnQgfV0sXG4gICAgICAgICAgcHJvdmlkZXJPcHRpb25zOiBtZXNzYWdlLnByb3ZpZGVyT3B0aW9ucyxcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcm9sZTogJ3VzZXInLFxuICAgICAgICBjb250ZW50OiBtZXNzYWdlLmNvbnRlbnRcbiAgICAgICAgICAubWFwKHBhcnQgPT4gY29udmVydFBhcnRUb0xhbmd1YWdlTW9kZWxQYXJ0KHBhcnQsIGRvd25sb2FkZWRBc3NldHMpKVxuICAgICAgICAgIC8vIHJlbW92ZSBlbXB0eSB0ZXh0IHBhcnRzOlxuICAgICAgICAgIC5maWx0ZXIocGFydCA9PiBwYXJ0LnR5cGUgIT09ICd0ZXh0JyB8fCBwYXJ0LnRleHQgIT09ICcnKSxcbiAgICAgICAgcHJvdmlkZXJPcHRpb25zOiBtZXNzYWdlLnByb3ZpZGVyT3B0aW9ucyxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY2FzZSAnYXNzaXN0YW50Jzoge1xuICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLmNvbnRlbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcm9sZTogJ2Fzc2lzdGFudCcsXG4gICAgICAgICAgY29udGVudDogW3sgdHlwZTogJ3RleHQnLCB0ZXh0OiBtZXNzYWdlLmNvbnRlbnQgfV0sXG4gICAgICAgICAgcHJvdmlkZXJPcHRpb25zOiBtZXNzYWdlLnByb3ZpZGVyT3B0aW9ucyxcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcm9sZTogJ2Fzc2lzdGFudCcsXG4gICAgICAgIGNvbnRlbnQ6IG1lc3NhZ2UuY29udGVudFxuICAgICAgICAgIC5maWx0ZXIoXG4gICAgICAgICAgICAvLyByZW1vdmUgZW1wdHkgdGV4dCBwYXJ0cyAobm8gdGV4dCwgYW5kIG5vIHByb3ZpZGVyIG9wdGlvbnMpOlxuICAgICAgICAgICAgcGFydCA9PlxuICAgICAgICAgICAgICBwYXJ0LnR5cGUgIT09ICd0ZXh0JyB8fFxuICAgICAgICAgICAgICBwYXJ0LnRleHQgIT09ICcnIHx8XG4gICAgICAgICAgICAgIHBhcnQucHJvdmlkZXJPcHRpb25zICE9IG51bGwsXG4gICAgICAgICAgKVxuICAgICAgICAgIC5tYXAocGFydCA9PiB7XG4gICAgICAgICAgICBjb25zdCBwcm92aWRlck9wdGlvbnMgPSBwYXJ0LnByb3ZpZGVyT3B0aW9ucztcblxuICAgICAgICAgICAgc3dpdGNoIChwYXJ0LnR5cGUpIHtcbiAgICAgICAgICAgICAgY2FzZSAnZmlsZSc6IHtcbiAgICAgICAgICAgICAgICBjb25zdCB7IGRhdGEsIG1lZGlhVHlwZSB9ID0gY29udmVydFRvTGFuZ3VhZ2VNb2RlbFYyRGF0YUNvbnRlbnQoXG4gICAgICAgICAgICAgICAgICBwYXJ0LmRhdGEsXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgdHlwZTogJ2ZpbGUnLFxuICAgICAgICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgICAgICAgIGZpbGVuYW1lOiBwYXJ0LmZpbGVuYW1lLFxuICAgICAgICAgICAgICAgICAgbWVkaWFUeXBlOiBtZWRpYVR5cGUgPz8gcGFydC5tZWRpYVR5cGUsXG4gICAgICAgICAgICAgICAgICBwcm92aWRlck9wdGlvbnMsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBjYXNlICdyZWFzb25pbmcnOiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgIHR5cGU6ICdyZWFzb25pbmcnLFxuICAgICAgICAgICAgICAgICAgdGV4dDogcGFydC50ZXh0LFxuICAgICAgICAgICAgICAgICAgcHJvdmlkZXJPcHRpb25zLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgY2FzZSAndGV4dCc6IHtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgdHlwZTogJ3RleHQnIGFzIGNvbnN0LFxuICAgICAgICAgICAgICAgICAgdGV4dDogcGFydC50ZXh0LFxuICAgICAgICAgICAgICAgICAgcHJvdmlkZXJPcHRpb25zLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgY2FzZSAndG9vbC1jYWxsJzoge1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICB0eXBlOiAndG9vbC1jYWxsJyBhcyBjb25zdCxcbiAgICAgICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IHBhcnQudG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgICAgIHRvb2xOYW1lOiBwYXJ0LnRvb2xOYW1lLFxuICAgICAgICAgICAgICAgICAgaW5wdXQ6IHBhcnQuaW5wdXQsXG4gICAgICAgICAgICAgICAgICBwcm92aWRlckV4ZWN1dGVkOiBwYXJ0LnByb3ZpZGVyRXhlY3V0ZWQsXG4gICAgICAgICAgICAgICAgICBwcm92aWRlck9wdGlvbnMsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBjYXNlICd0b29sLXJlc3VsdCc6IHtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgdHlwZTogJ3Rvb2wtcmVzdWx0JyBhcyBjb25zdCxcbiAgICAgICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IHBhcnQudG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgICAgIHRvb2xOYW1lOiBwYXJ0LnRvb2xOYW1lLFxuICAgICAgICAgICAgICAgICAgb3V0cHV0OiBwYXJ0Lm91dHB1dCxcbiAgICAgICAgICAgICAgICAgIHByb3ZpZGVyT3B0aW9ucyxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSksXG4gICAgICAgIHByb3ZpZGVyT3B0aW9uczogbWVzc2FnZS5wcm92aWRlck9wdGlvbnMsXG4gICAgICB9O1xuICAgIH1cblxuICAgIGNhc2UgJ3Rvb2wnOiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICByb2xlOiAndG9vbCcsXG4gICAgICAgIGNvbnRlbnQ6IG1lc3NhZ2UuY29udGVudC5tYXAocGFydCA9PiAoe1xuICAgICAgICAgIHR5cGU6ICd0b29sLXJlc3VsdCcgYXMgY29uc3QsXG4gICAgICAgICAgdG9vbENhbGxJZDogcGFydC50b29sQ2FsbElkLFxuICAgICAgICAgIHRvb2xOYW1lOiBwYXJ0LnRvb2xOYW1lLFxuICAgICAgICAgIG91dHB1dDogcGFydC5vdXRwdXQsXG4gICAgICAgICAgcHJvdmlkZXJPcHRpb25zOiBwYXJ0LnByb3ZpZGVyT3B0aW9ucyxcbiAgICAgICAgfSkpLFxuICAgICAgICBwcm92aWRlck9wdGlvbnM6IG1lc3NhZ2UucHJvdmlkZXJPcHRpb25zLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBkZWZhdWx0OiB7XG4gICAgICBjb25zdCBfZXhoYXVzdGl2ZUNoZWNrOiBuZXZlciA9IHJvbGU7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZE1lc3NhZ2VSb2xlRXJyb3IoeyByb2xlOiBfZXhoYXVzdGl2ZUNoZWNrIH0pO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIERvd25sb2FkcyBpbWFnZXMgYW5kIGZpbGVzIGZyb20gVVJMcyBpbiB0aGUgbWVzc2FnZXMuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGRvd25sb2FkQXNzZXRzKFxuICBtZXNzYWdlczogTW9kZWxNZXNzYWdlW10sXG4gIGRvd25sb2FkOiBEb3dubG9hZEZ1bmN0aW9uLFxuICBzdXBwb3J0ZWRVcmxzOiBSZWNvcmQ8c3RyaW5nLCBSZWdFeHBbXT4sXG4pOiBQcm9taXNlPFxuICBSZWNvcmQ8c3RyaW5nLCB7IG1lZGlhVHlwZTogc3RyaW5nIHwgdW5kZWZpbmVkOyBkYXRhOiBVaW50OEFycmF5IH0+XG4+IHtcbiAgY29uc3QgcGxhbm5lZERvd25sb2FkcyA9IG1lc3NhZ2VzXG4gICAgLmZpbHRlcihtZXNzYWdlID0+IG1lc3NhZ2Uucm9sZSA9PT0gJ3VzZXInKVxuICAgIC5tYXAobWVzc2FnZSA9PiBtZXNzYWdlLmNvbnRlbnQpXG4gICAgLmZpbHRlcigoY29udGVudCk6IGNvbnRlbnQgaXMgQXJyYXk8VGV4dFBhcnQgfCBJbWFnZVBhcnQgfCBGaWxlUGFydD4gPT5cbiAgICAgIEFycmF5LmlzQXJyYXkoY29udGVudCksXG4gICAgKVxuICAgIC5mbGF0KClcbiAgICAuZmlsdGVyKFxuICAgICAgKHBhcnQpOiBwYXJ0IGlzIEltYWdlUGFydCB8IEZpbGVQYXJ0ID0+XG4gICAgICAgIHBhcnQudHlwZSA9PT0gJ2ltYWdlJyB8fCBwYXJ0LnR5cGUgPT09ICdmaWxlJyxcbiAgICApXG4gICAgLm1hcChwYXJ0ID0+IHtcbiAgICAgIGNvbnN0IG1lZGlhVHlwZSA9XG4gICAgICAgIHBhcnQubWVkaWFUeXBlID8/IChwYXJ0LnR5cGUgPT09ICdpbWFnZScgPyAnaW1hZ2UvKicgOiB1bmRlZmluZWQpO1xuXG4gICAgICBsZXQgZGF0YSA9IHBhcnQudHlwZSA9PT0gJ2ltYWdlJyA/IHBhcnQuaW1hZ2UgOiBwYXJ0LmRhdGE7XG4gICAgICBpZiAodHlwZW9mIGRhdGEgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgZGF0YSA9IG5ldyBVUkwoZGF0YSk7XG4gICAgICAgIH0gY2F0Y2ggKGlnbm9yZWQpIHt9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7IG1lZGlhVHlwZSwgZGF0YSB9O1xuICAgIH0pXG5cbiAgICAuZmlsdGVyKFxuICAgICAgKHBhcnQpOiBwYXJ0IGlzIHsgbWVkaWFUeXBlOiBzdHJpbmcgfCB1bmRlZmluZWQ7IGRhdGE6IFVSTCB9ID0+XG4gICAgICAgIHBhcnQuZGF0YSBpbnN0YW5jZW9mIFVSTCxcbiAgICApXG4gICAgLm1hcChwYXJ0ID0+ICh7XG4gICAgICB1cmw6IHBhcnQuZGF0YSxcbiAgICAgIGlzVXJsU3VwcG9ydGVkQnlNb2RlbDpcbiAgICAgICAgcGFydC5tZWRpYVR5cGUgIT0gbnVsbCAmJlxuICAgICAgICBpc1VybFN1cHBvcnRlZCh7XG4gICAgICAgICAgdXJsOiBwYXJ0LmRhdGEudG9TdHJpbmcoKSxcbiAgICAgICAgICBtZWRpYVR5cGU6IHBhcnQubWVkaWFUeXBlLFxuICAgICAgICAgIHN1cHBvcnRlZFVybHMsXG4gICAgICAgIH0pLFxuICAgIH0pKTtcblxuICAvLyBkb3dubG9hZCBpbiBwYXJhbGxlbDpcbiAgY29uc3QgZG93bmxvYWRlZEZpbGVzID0gYXdhaXQgZG93bmxvYWQocGxhbm5lZERvd25sb2Fkcyk7XG5cbiAgcmV0dXJuIE9iamVjdC5mcm9tRW50cmllcyhcbiAgICBkb3dubG9hZGVkRmlsZXNcbiAgICAgIC5tYXAoKGZpbGUsIGluZGV4KSA9PlxuICAgICAgICBmaWxlID09IG51bGxcbiAgICAgICAgICA/IG51bGxcbiAgICAgICAgICA6IFtcbiAgICAgICAgICAgICAgcGxhbm5lZERvd25sb2Fkc1tpbmRleF0udXJsLnRvU3RyaW5nKCksXG4gICAgICAgICAgICAgIHsgZGF0YTogZmlsZS5kYXRhLCBtZWRpYVR5cGU6IGZpbGUubWVkaWFUeXBlIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgKVxuICAgICAgLmZpbHRlcihmaWxlID0+IGZpbGUgIT0gbnVsbCksXG4gICk7XG59XG5cbi8qKlxuICogQ29udmVydCBwYXJ0IG9mIGEgbWVzc2FnZSB0byBhIExhbmd1YWdlTW9kZWxWMlBhcnQuXG4gKiBAcGFyYW0gcGFydCBUaGUgcGFydCB0byBjb252ZXJ0LlxuICogQHBhcmFtIGRvd25sb2FkZWRBc3NldHMgQSBtYXAgb2YgVVJMcyB0byB0aGVpciBkb3dubG9hZGVkIGRhdGEuIE9ubHlcbiAqICBhdmFpbGFibGUgaWYgdGhlIG1vZGVsIGRvZXMgbm90IHN1cHBvcnQgVVJMcywgbnVsbCBvdGhlcndpc2UuXG4gKlxuICogQHJldHVybnMgVGhlIGNvbnZlcnRlZCBwYXJ0LlxuICovXG5mdW5jdGlvbiBjb252ZXJ0UGFydFRvTGFuZ3VhZ2VNb2RlbFBhcnQoXG4gIHBhcnQ6IFRleHRQYXJ0IHwgSW1hZ2VQYXJ0IHwgRmlsZVBhcnQsXG4gIGRvd25sb2FkZWRBc3NldHM6IFJlY29yZDxcbiAgICBzdHJpbmcsXG4gICAgeyBtZWRpYVR5cGU6IHN0cmluZyB8IHVuZGVmaW5lZDsgZGF0YTogVWludDhBcnJheSB9XG4gID4sXG4pOiBMYW5ndWFnZU1vZGVsVjJUZXh0UGFydCB8IExhbmd1YWdlTW9kZWxWMkZpbGVQYXJ0IHtcbiAgaWYgKHBhcnQudHlwZSA9PT0gJ3RleHQnKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgIHRleHQ6IHBhcnQudGV4dCxcbiAgICAgIHByb3ZpZGVyT3B0aW9uczogcGFydC5wcm92aWRlck9wdGlvbnMsXG4gICAgfTtcbiAgfVxuXG4gIGxldCBvcmlnaW5hbERhdGE6IERhdGFDb250ZW50IHwgVVJMO1xuICBjb25zdCB0eXBlID0gcGFydC50eXBlO1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICdpbWFnZSc6XG4gICAgICBvcmlnaW5hbERhdGEgPSBwYXJ0LmltYWdlO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnZmlsZSc6XG4gICAgICBvcmlnaW5hbERhdGEgPSBwYXJ0LmRhdGE7XG5cbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIHBhcnQgdHlwZTogJHt0eXBlfWApO1xuICB9XG5cbiAgY29uc3QgeyBkYXRhOiBjb252ZXJ0ZWREYXRhLCBtZWRpYVR5cGU6IGNvbnZlcnRlZE1lZGlhVHlwZSB9ID1cbiAgICBjb252ZXJ0VG9MYW5ndWFnZU1vZGVsVjJEYXRhQ29udGVudChvcmlnaW5hbERhdGEpO1xuXG4gIGxldCBtZWRpYVR5cGU6IHN0cmluZyB8IHVuZGVmaW5lZCA9IGNvbnZlcnRlZE1lZGlhVHlwZSA/PyBwYXJ0Lm1lZGlhVHlwZTtcbiAgbGV0IGRhdGE6IFVpbnQ4QXJyYXkgfCBzdHJpbmcgfCBVUkwgPSBjb252ZXJ0ZWREYXRhOyAvLyBiaW5hcnkgfCBiYXNlNjQgfCB1cmxcblxuICAvLyBJZiB0aGUgY29udGVudCBpcyBhIFVSTCwgd2UgY2hlY2sgaWYgaXQgd2FzIGRvd25sb2FkZWQ6XG4gIGlmIChkYXRhIGluc3RhbmNlb2YgVVJMKSB7XG4gICAgY29uc3QgZG93bmxvYWRlZEZpbGUgPSBkb3dubG9hZGVkQXNzZXRzW2RhdGEudG9TdHJpbmcoKV07XG4gICAgaWYgKGRvd25sb2FkZWRGaWxlKSB7XG4gICAgICBkYXRhID0gZG93bmxvYWRlZEZpbGUuZGF0YTtcbiAgICAgIG1lZGlhVHlwZSA/Pz0gZG93bmxvYWRlZEZpbGUubWVkaWFUeXBlO1xuICAgIH1cbiAgfVxuXG4gIC8vIE5vdyB0aGF0IHdlIGhhdmUgdGhlIG5vcm1hbGl6ZWQgZGF0YSBlaXRoZXIgYXMgYSBVUkwgb3IgYSBVaW50OEFycmF5LFxuICAvLyB3ZSBjYW4gY3JlYXRlIHRoZSBMYW5ndWFnZU1vZGVsVjJQYXJ0LlxuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICdpbWFnZSc6IHtcbiAgICAgIC8vIFdoZW4gcG9zc2libGUsIHRyeSB0byBkZXRlY3QgdGhlIG1lZGlhIHR5cGUgYXV0b21hdGljYWxseVxuICAgICAgLy8gdG8gZGVhbCB3aXRoIGluY29ycmVjdCBtZWRpYSB0eXBlIGlucHV0cy5cbiAgICAgIC8vIFdoZW4gZGV0ZWN0aW9uIGZhaWxzLCB1c2UgcHJvdmlkZWQgbWVkaWEgdHlwZS5cbiAgICAgIGlmIChkYXRhIGluc3RhbmNlb2YgVWludDhBcnJheSB8fCB0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgbWVkaWFUeXBlID1cbiAgICAgICAgICBkZXRlY3RNZWRpYVR5cGUoeyBkYXRhLCBzaWduYXR1cmVzOiBpbWFnZU1lZGlhVHlwZVNpZ25hdHVyZXMgfSkgPz9cbiAgICAgICAgICBtZWRpYVR5cGU7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6ICdmaWxlJyxcbiAgICAgICAgbWVkaWFUeXBlOiBtZWRpYVR5cGUgPz8gJ2ltYWdlLyonLCAvLyBhbnkgaW1hZ2VcbiAgICAgICAgZmlsZW5hbWU6IHVuZGVmaW5lZCxcbiAgICAgICAgZGF0YSxcbiAgICAgICAgcHJvdmlkZXJPcHRpb25zOiBwYXJ0LnByb3ZpZGVyT3B0aW9ucyxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY2FzZSAnZmlsZSc6IHtcbiAgICAgIC8vIFdlIG11c3QgaGF2ZSBhIG1lZGlhVHlwZSBmb3IgZmlsZXMsIGlmIG5vdCwgdGhyb3cgYW4gZXJyb3IuXG4gICAgICBpZiAobWVkaWFUeXBlID09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBNZWRpYSB0eXBlIGlzIG1pc3NpbmcgZm9yIGZpbGUgcGFydGApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiAnZmlsZScsXG4gICAgICAgIG1lZGlhVHlwZSxcbiAgICAgICAgZmlsZW5hbWU6IHBhcnQuZmlsZW5hbWUsXG4gICAgICAgIGRhdGEsXG4gICAgICAgIHByb3ZpZGVyT3B0aW9uczogcGFydC5wcm92aWRlck9wdGlvbnMsXG4gICAgICB9O1xuICAgIH1cbiAgfVxufVxuIiwgImltcG9ydCB7IGNvbnZlcnRCYXNlNjRUb1VpbnQ4QXJyYXkgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyLXV0aWxzJztcblxuZXhwb3J0IGNvbnN0IGltYWdlTWVkaWFUeXBlU2lnbmF0dXJlcyA9IFtcbiAge1xuICAgIG1lZGlhVHlwZTogJ2ltYWdlL2dpZicgYXMgY29uc3QsXG4gICAgYnl0ZXNQcmVmaXg6IFsweDQ3LCAweDQ5LCAweDQ2XSwgLy8gR0lGXG4gIH0sXG4gIHtcbiAgICBtZWRpYVR5cGU6ICdpbWFnZS9wbmcnIGFzIGNvbnN0LFxuICAgIGJ5dGVzUHJlZml4OiBbMHg4OSwgMHg1MCwgMHg0ZSwgMHg0N10sIC8vIFBOR1xuICB9LFxuICB7XG4gICAgbWVkaWFUeXBlOiAnaW1hZ2UvanBlZycgYXMgY29uc3QsXG4gICAgYnl0ZXNQcmVmaXg6IFsweGZmLCAweGQ4XSwgLy8gSlBFR1xuICB9LFxuICB7XG4gICAgbWVkaWFUeXBlOiAnaW1hZ2Uvd2VicCcgYXMgY29uc3QsXG4gICAgYnl0ZXNQcmVmaXg6IFtcbiAgICAgIDB4NTIsXG4gICAgICAweDQ5LFxuICAgICAgMHg0NixcbiAgICAgIDB4NDYsIC8vIFwiUklGRlwiXG4gICAgICBudWxsLFxuICAgICAgbnVsbCxcbiAgICAgIG51bGwsXG4gICAgICBudWxsLCAvLyBmaWxlIHNpemUgKHZhcmlhYmxlKVxuICAgICAgMHg1NyxcbiAgICAgIDB4NDUsXG4gICAgICAweDQyLFxuICAgICAgMHg1MCwgLy8gXCJXRUJQXCJcbiAgICBdLFxuICB9LFxuICB7XG4gICAgbWVkaWFUeXBlOiAnaW1hZ2UvYm1wJyBhcyBjb25zdCxcbiAgICBieXRlc1ByZWZpeDogWzB4NDIsIDB4NGRdLFxuICB9LFxuICB7XG4gICAgbWVkaWFUeXBlOiAnaW1hZ2UvdGlmZicgYXMgY29uc3QsXG4gICAgYnl0ZXNQcmVmaXg6IFsweDQ5LCAweDQ5LCAweDJhLCAweDAwXSxcbiAgfSxcbiAge1xuICAgIG1lZGlhVHlwZTogJ2ltYWdlL3RpZmYnIGFzIGNvbnN0LFxuICAgIGJ5dGVzUHJlZml4OiBbMHg0ZCwgMHg0ZCwgMHgwMCwgMHgyYV0sXG4gIH0sXG4gIHtcbiAgICBtZWRpYVR5cGU6ICdpbWFnZS9hdmlmJyBhcyBjb25zdCxcbiAgICBieXRlc1ByZWZpeDogW1xuICAgICAgMHgwMCwgMHgwMCwgMHgwMCwgMHgyMCwgMHg2NiwgMHg3NCwgMHg3OSwgMHg3MCwgMHg2MSwgMHg3NiwgMHg2OSwgMHg2NixcbiAgICBdLFxuICB9LFxuICB7XG4gICAgbWVkaWFUeXBlOiAnaW1hZ2UvaGVpYycgYXMgY29uc3QsXG4gICAgYnl0ZXNQcmVmaXg6IFtcbiAgICAgIDB4MDAsIDB4MDAsIDB4MDAsIDB4MjAsIDB4NjYsIDB4NzQsIDB4NzksIDB4NzAsIDB4NjgsIDB4NjUsIDB4NjksIDB4NjMsXG4gICAgXSxcbiAgfSxcbl0gYXMgY29uc3Q7XG5cbmV4cG9ydCBjb25zdCBhdWRpb01lZGlhVHlwZVNpZ25hdHVyZXMgPSBbXG4gIHtcbiAgICBtZWRpYVR5cGU6ICdhdWRpby9tcGVnJyBhcyBjb25zdCxcbiAgICBieXRlc1ByZWZpeDogWzB4ZmYsIDB4ZmJdLFxuICB9LFxuICB7XG4gICAgbWVkaWFUeXBlOiAnYXVkaW8vbXBlZycgYXMgY29uc3QsXG4gICAgYnl0ZXNQcmVmaXg6IFsweGZmLCAweGZhXSxcbiAgfSxcbiAge1xuICAgIG1lZGlhVHlwZTogJ2F1ZGlvL21wZWcnIGFzIGNvbnN0LFxuICAgIGJ5dGVzUHJlZml4OiBbMHhmZiwgMHhmM10sXG4gIH0sXG4gIHtcbiAgICBtZWRpYVR5cGU6ICdhdWRpby9tcGVnJyBhcyBjb25zdCxcbiAgICBieXRlc1ByZWZpeDogWzB4ZmYsIDB4ZjJdLFxuICB9LFxuICB7XG4gICAgbWVkaWFUeXBlOiAnYXVkaW8vbXBlZycgYXMgY29uc3QsXG4gICAgYnl0ZXNQcmVmaXg6IFsweGZmLCAweGUzXSxcbiAgfSxcbiAge1xuICAgIG1lZGlhVHlwZTogJ2F1ZGlvL21wZWcnIGFzIGNvbnN0LFxuICAgIGJ5dGVzUHJlZml4OiBbMHhmZiwgMHhlMl0sXG4gIH0sXG4gIHtcbiAgICBtZWRpYVR5cGU6ICdhdWRpby93YXYnIGFzIGNvbnN0LFxuICAgIGJ5dGVzUHJlZml4OiBbXG4gICAgICAweDUyLCAvLyBSXG4gICAgICAweDQ5LCAvLyBJXG4gICAgICAweDQ2LCAvLyBGXG4gICAgICAweDQ2LCAvLyBGXG4gICAgICBudWxsLFxuICAgICAgbnVsbCxcbiAgICAgIG51bGwsXG4gICAgICBudWxsLFxuICAgICAgMHg1NywgLy8gV1xuICAgICAgMHg0MSwgLy8gQVxuICAgICAgMHg1NiwgLy8gVlxuICAgICAgMHg0NSwgLy8gRVxuICAgIF0sXG4gIH0sXG4gIHtcbiAgICBtZWRpYVR5cGU6ICdhdWRpby9vZ2cnIGFzIGNvbnN0LFxuICAgIGJ5dGVzUHJlZml4OiBbMHg0ZiwgMHg2NywgMHg2NywgMHg1M10sXG4gIH0sXG4gIHtcbiAgICBtZWRpYVR5cGU6ICdhdWRpby9mbGFjJyBhcyBjb25zdCxcbiAgICBieXRlc1ByZWZpeDogWzB4NjYsIDB4NGMsIDB4NjEsIDB4NDNdLFxuICB9LFxuICB7XG4gICAgbWVkaWFUeXBlOiAnYXVkaW8vYWFjJyBhcyBjb25zdCxcbiAgICBieXRlc1ByZWZpeDogWzB4NDAsIDB4MTUsIDB4MDAsIDB4MDBdLFxuICB9LFxuICB7XG4gICAgbWVkaWFUeXBlOiAnYXVkaW8vbXA0JyBhcyBjb25zdCxcbiAgICBieXRlc1ByZWZpeDogWzB4NjYsIDB4NzQsIDB4NzksIDB4NzBdLFxuICB9LFxuICB7XG4gICAgbWVkaWFUeXBlOiAnYXVkaW8vd2VibScsXG4gICAgYnl0ZXNQcmVmaXg6IFsweDFhLCAweDQ1LCAweGRmLCAweGEzXSxcbiAgfSxcbl0gYXMgY29uc3Q7XG5cbmNvbnN0IHN0cmlwSUQzID0gKGRhdGE6IFVpbnQ4QXJyYXkgfCBzdHJpbmcpID0+IHtcbiAgY29uc3QgYnl0ZXMgPVxuICAgIHR5cGVvZiBkYXRhID09PSAnc3RyaW5nJyA/IGNvbnZlcnRCYXNlNjRUb1VpbnQ4QXJyYXkoZGF0YSkgOiBkYXRhO1xuICBjb25zdCBpZDNTaXplID1cbiAgICAoKGJ5dGVzWzZdICYgMHg3ZikgPDwgMjEpIHxcbiAgICAoKGJ5dGVzWzddICYgMHg3ZikgPDwgMTQpIHxcbiAgICAoKGJ5dGVzWzhdICYgMHg3ZikgPDwgNykgfFxuICAgIChieXRlc1s5XSAmIDB4N2YpO1xuXG4gIC8vIFRoZSByYXcgTVAzIHN0YXJ0cyBoZXJlXG4gIHJldHVybiBieXRlcy5zbGljZShpZDNTaXplICsgMTApO1xufTtcblxuZnVuY3Rpb24gc3RyaXBJRDNUYWdzSWZQcmVzZW50KGRhdGE6IFVpbnQ4QXJyYXkgfCBzdHJpbmcpOiBVaW50OEFycmF5IHwgc3RyaW5nIHtcbiAgY29uc3QgaGFzSWQzID1cbiAgICAodHlwZW9mIGRhdGEgPT09ICdzdHJpbmcnICYmIGRhdGEuc3RhcnRzV2l0aCgnU1VReicpKSB8fFxuICAgICh0eXBlb2YgZGF0YSAhPT0gJ3N0cmluZycgJiZcbiAgICAgIGRhdGEubGVuZ3RoID4gMTAgJiZcbiAgICAgIGRhdGFbMF0gPT09IDB4NDkgJiYgLy8gJ0knXG4gICAgICBkYXRhWzFdID09PSAweDQ0ICYmIC8vICdEJ1xuICAgICAgZGF0YVsyXSA9PT0gMHgzMyk7IC8vICczJ1xuXG4gIHJldHVybiBoYXNJZDMgPyBzdHJpcElEMyhkYXRhKSA6IGRhdGE7XG59XG5cbi8qKlxuICogRGV0ZWN0IHRoZSBtZWRpYSBJQU5BIG1lZGlhIHR5cGUgb2YgYSBmaWxlIHVzaW5nIGEgbGlzdCBvZiBzaWduYXR1cmVzLlxuICpcbiAqIEBwYXJhbSBkYXRhIC0gVGhlIGZpbGUgZGF0YS5cbiAqIEBwYXJhbSBzaWduYXR1cmVzIC0gVGhlIHNpZ25hdHVyZXMgdG8gdXNlIGZvciBkZXRlY3Rpb24uXG4gKiBAcmV0dXJucyBUaGUgbWVkaWEgdHlwZSBvZiB0aGUgZmlsZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRldGVjdE1lZGlhVHlwZSh7XG4gIGRhdGEsXG4gIHNpZ25hdHVyZXMsXG59OiB7XG4gIGRhdGE6IFVpbnQ4QXJyYXkgfCBzdHJpbmc7XG4gIHNpZ25hdHVyZXM6IHR5cGVvZiBhdWRpb01lZGlhVHlwZVNpZ25hdHVyZXMgfCB0eXBlb2YgaW1hZ2VNZWRpYVR5cGVTaWduYXR1cmVzO1xufSk6ICh0eXBlb2Ygc2lnbmF0dXJlcylbbnVtYmVyXVsnbWVkaWFUeXBlJ10gfCB1bmRlZmluZWQge1xuICBjb25zdCBwcm9jZXNzZWREYXRhID0gc3RyaXBJRDNUYWdzSWZQcmVzZW50KGRhdGEpO1xuXG4gIC8vIENvbnZlcnQgdGhlIGZpcnN0IH4xOCBieXRlcyAoMjQgYmFzZTY0IGNoYXJzKSBmb3IgY29uc2lzdGVudCBkZXRlY3Rpb24gbG9naWM6XG4gIGNvbnN0IGJ5dGVzID1cbiAgICB0eXBlb2YgcHJvY2Vzc2VkRGF0YSA9PT0gJ3N0cmluZydcbiAgICAgID8gY29udmVydEJhc2U2NFRvVWludDhBcnJheShcbiAgICAgICAgICBwcm9jZXNzZWREYXRhLnN1YnN0cmluZygwLCBNYXRoLm1pbihwcm9jZXNzZWREYXRhLmxlbmd0aCwgMjQpKSxcbiAgICAgICAgKVxuICAgICAgOiBwcm9jZXNzZWREYXRhO1xuXG4gIGZvciAoY29uc3Qgc2lnbmF0dXJlIG9mIHNpZ25hdHVyZXMpIHtcbiAgICBpZiAoXG4gICAgICBieXRlcy5sZW5ndGggPj0gc2lnbmF0dXJlLmJ5dGVzUHJlZml4Lmxlbmd0aCAmJlxuICAgICAgc2lnbmF0dXJlLmJ5dGVzUHJlZml4LmV2ZXJ5KFxuICAgICAgICAoYnl0ZSwgaW5kZXgpID0+IGJ5dGUgPT09IG51bGwgfHwgYnl0ZXNbaW5kZXhdID09PSBieXRlLFxuICAgICAgKVxuICAgICkge1xuICAgICAgcmV0dXJuIHNpZ25hdHVyZS5tZWRpYVR5cGU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cbiIsICJpbXBvcnQgeyBEb3dubG9hZEVycm9yIH0gZnJvbSAnLi9kb3dubG9hZC1lcnJvcic7XG5pbXBvcnQge1xuICB3aXRoVXNlckFnZW50U3VmZml4LFxuICBnZXRSdW50aW1lRW52aXJvbm1lbnRVc2VyQWdlbnQsXG59IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXItdXRpbHMnO1xuaW1wb3J0IHsgVkVSU0lPTiB9IGZyb20gJy4uLy4uL3ZlcnNpb24nO1xuXG4vKipcbiAqIERvd25sb2FkIGEgZmlsZSBmcm9tIGEgVVJMLlxuICpcbiAqIEBwYXJhbSB1cmwgLSBUaGUgVVJMIHRvIGRvd25sb2FkIGZyb20uXG4gKiBAcmV0dXJucyBUaGUgZG93bmxvYWRlZCBkYXRhIGFuZCBtZWRpYSB0eXBlLlxuICpcbiAqIEB0aHJvd3MgRG93bmxvYWRFcnJvciBpZiB0aGUgZG93bmxvYWQgZmFpbHMuXG4gKi9cbmV4cG9ydCBjb25zdCBkb3dubG9hZCA9IGFzeW5jICh7IHVybCB9OiB7IHVybDogVVJMIH0pID0+IHtcbiAgY29uc3QgdXJsVGV4dCA9IHVybC50b1N0cmluZygpO1xuICB0cnkge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godXJsVGV4dCwge1xuICAgICAgaGVhZGVyczogd2l0aFVzZXJBZ2VudFN1ZmZpeChcbiAgICAgICAge30sXG4gICAgICAgIGBhaS1zZGsvJHtWRVJTSU9OfWAsXG4gICAgICAgIGdldFJ1bnRpbWVFbnZpcm9ubWVudFVzZXJBZ2VudCgpLFxuICAgICAgKSxcbiAgICB9KTtcblxuICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgIHRocm93IG5ldyBEb3dubG9hZEVycm9yKHtcbiAgICAgICAgdXJsOiB1cmxUZXh0LFxuICAgICAgICBzdGF0dXNDb2RlOiByZXNwb25zZS5zdGF0dXMsXG4gICAgICAgIHN0YXR1c1RleHQ6IHJlc3BvbnNlLnN0YXR1c1RleHQsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgZGF0YTogbmV3IFVpbnQ4QXJyYXkoYXdhaXQgcmVzcG9uc2UuYXJyYXlCdWZmZXIoKSksXG4gICAgICBtZWRpYVR5cGU6IHJlc3BvbnNlLmhlYWRlcnMuZ2V0KCdjb250ZW50LXR5cGUnKSA/PyB1bmRlZmluZWQsXG4gICAgfTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoRG93bmxvYWRFcnJvci5pc0luc3RhbmNlKGVycm9yKSkge1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IERvd25sb2FkRXJyb3IoeyB1cmw6IHVybFRleHQsIGNhdXNlOiBlcnJvciB9KTtcbiAgfVxufTtcbiIsICJkZWNsYXJlIGNvbnN0IF9fUEFDS0FHRV9WRVJTSU9OX186IHN0cmluZyB8IHVuZGVmaW5lZDtcbmV4cG9ydCBjb25zdCBWRVJTSU9OOiBzdHJpbmcgPVxuICB0eXBlb2YgX19QQUNLQUdFX1ZFUlNJT05fXyAhPT0gJ3VuZGVmaW5lZCdcbiAgICA/IF9fUEFDS0FHRV9WRVJTSU9OX19cbiAgICA6ICcwLjAuMC10ZXN0JztcbiIsICJpbXBvcnQgeyBkb3dubG9hZCBhcyBvcmlnaW5hbERvd25sb2FkIH0gZnJvbSAnLi9kb3dubG9hZCc7XG5cbi8qKlxuICogRXhwZXJpbWVudGFsLiBDYW4gY2hhbmdlIGluIHBhdGNoIHZlcnNpb25zIHdpdGhvdXQgd2FybmluZy5cbiAqXG4gKiBEb3dubG9hZCBmdW5jdGlvbi4gQ2FsbGVkIHdpdGggdGhlIGFycmF5IG9mIFVSTHMgYW5kIGEgYm9vbGVhbiBpbmRpY2F0aW5nXG4gKiB3aGV0aGVyIHRoZSBVUkwgaXMgc3VwcG9ydGVkIGJ5IHRoZSBtb2RlbC5cbiAqXG4gKiBUaGUgZG93bmxvYWQgZnVuY3Rpb24gY2FuIGRlY2lkZSBmb3IgZWFjaCBVUkw6XG4gKiAtIHRvIHJldHVybiBudWxsICh3aGljaCBtZWFucyB0aGF0IHRoZSBVUkwgc2hvdWxkIGJlIHBhc3NlZCB0byB0aGUgbW9kZWwpXG4gKiAtIHRvIGRvd25sb2FkIHRoZSBhc3NldCBhbmQgcmV0dXJuIHRoZSBkYXRhIChpbmNsLiByZXRyaWVzLCBhdXRoZW50aWNhdGlvbiwgZXRjLilcbiAqXG4gKiBTaG91bGQgdGhyb3cgRG93bmxvYWRFcnJvciBpZiB0aGUgZG93bmxvYWQgZmFpbHMuXG4gKlxuICogU2hvdWxkIHJldHVybiBhbiBhcnJheSBvZiBvYmplY3RzIHNvcnRlZCBieSB0aGUgb3JkZXIgb2YgdGhlIHJlcXVlc3RlZCBkb3dubG9hZHMuXG4gKiBGb3IgZWFjaCBvYmplY3QsIHRoZSBkYXRhIHNob3VsZCBiZSBhIFVpbnQ4QXJyYXkgaWYgdGhlIFVSTCB3YXMgZG93bmxvYWRlZC5cbiAqIEZvciBlYWNoIG9iamVjdCwgdGhlIG1lZGlhVHlwZSBzaG91bGQgYmUgdGhlIG1lZGlhIHR5cGUgb2YgdGhlIGRvd25sb2FkZWQgYXNzZXQuXG4gKiBGb3IgZWFjaCBvYmplY3QsIHRoZSBkYXRhIHNob3VsZCBiZSBudWxsIGlmIHRoZSBVUkwgc2hvdWxkIGJlIHBhc3NlZCB0aHJvdWdoIGFzIGlzLlxuICovXG5leHBvcnQgdHlwZSBEb3dubG9hZEZ1bmN0aW9uID0gKFxuICBvcHRpb25zOiBBcnJheTx7XG4gICAgdXJsOiBVUkw7XG4gICAgaXNVcmxTdXBwb3J0ZWRCeU1vZGVsOiBib29sZWFuO1xuICB9PixcbikgPT4gUHJvbWlzZUxpa2U8XG4gIEFycmF5PHtcbiAgICBkYXRhOiBVaW50OEFycmF5O1xuICAgIG1lZGlhVHlwZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICB9IHwgbnVsbD5cbj47XG5cbi8qKlxuICogRGVmYXVsdCBkb3dubG9hZCBmdW5jdGlvbi5cbiAqIERvd25sb2FkcyB0aGUgZmlsZSBpZiBpdCBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBtb2RlbC5cbiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZURlZmF1bHREb3dubG9hZEZ1bmN0aW9uID1cbiAgKGRvd25sb2FkOiB0eXBlb2Ygb3JpZ2luYWxEb3dubG9hZCA9IG9yaWdpbmFsRG93bmxvYWQpOiBEb3dubG9hZEZ1bmN0aW9uID0+XG4gIHJlcXVlc3RlZERvd25sb2FkcyA9PlxuICAgIFByb21pc2UuYWxsKFxuICAgICAgcmVxdWVzdGVkRG93bmxvYWRzLm1hcChhc3luYyByZXF1ZXN0ZWREb3dubG9hZCA9PlxuICAgICAgICByZXF1ZXN0ZWREb3dubG9hZC5pc1VybFN1cHBvcnRlZEJ5TW9kZWxcbiAgICAgICAgICA/IG51bGxcbiAgICAgICAgICA6IGRvd25sb2FkKHJlcXVlc3RlZERvd25sb2FkKSxcbiAgICAgICksXG4gICAgKTtcbiIsICJpbXBvcnQgeyBBSVNES0Vycm9yLCBMYW5ndWFnZU1vZGVsVjJEYXRhQ29udGVudCB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHtcbiAgY29udmVydEJhc2U2NFRvVWludDhBcnJheSxcbiAgY29udmVydFVpbnQ4QXJyYXlUb0Jhc2U2NCxcbiAgRGF0YUNvbnRlbnQsXG59IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXItdXRpbHMnO1xuaW1wb3J0IHsgeiB9IGZyb20gJ3pvZC92NCc7XG5pbXBvcnQgeyBJbnZhbGlkRGF0YUNvbnRlbnRFcnJvciB9IGZyb20gJy4vaW52YWxpZC1kYXRhLWNvbnRlbnQtZXJyb3InO1xuaW1wb3J0IHsgc3BsaXREYXRhVXJsIH0gZnJvbSAnLi9zcGxpdC1kYXRhLXVybCc7XG5cbi8qKlxuQGludGVybmFsXG4gKi9cbmV4cG9ydCBjb25zdCBkYXRhQ29udGVudFNjaGVtYTogei5ab2RUeXBlPERhdGFDb250ZW50PiA9IHoudW5pb24oW1xuICB6LnN0cmluZygpLFxuICB6Lmluc3RhbmNlb2YoVWludDhBcnJheSksXG4gIHouaW5zdGFuY2VvZihBcnJheUJ1ZmZlciksXG4gIHouY3VzdG9tPEJ1ZmZlcj4oXG4gICAgLy8gQnVmZmVyIG1pZ2h0IG5vdCBiZSBhdmFpbGFibGUgaW4gc29tZSBlbnZpcm9ubWVudHMgc3VjaCBhcyBDbG91ZEZsYXJlOlxuICAgICh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIEJ1ZmZlciA9PlxuICAgICAgZ2xvYmFsVGhpcy5CdWZmZXI/LmlzQnVmZmVyKHZhbHVlKSA/PyBmYWxzZSxcbiAgICB7IG1lc3NhZ2U6ICdNdXN0IGJlIGEgQnVmZmVyJyB9LFxuICApLFxuXSk7XG5cbmV4cG9ydCBmdW5jdGlvbiBjb252ZXJ0VG9MYW5ndWFnZU1vZGVsVjJEYXRhQ29udGVudChcbiAgY29udGVudDogRGF0YUNvbnRlbnQgfCBVUkwsXG4pOiB7XG4gIGRhdGE6IExhbmd1YWdlTW9kZWxWMkRhdGFDb250ZW50O1xuICBtZWRpYVR5cGU6IHN0cmluZyB8IHVuZGVmaW5lZDtcbn0ge1xuICAvLyBCdWZmZXIgJiBVaW50OEFycmF5OlxuICBpZiAoY29udGVudCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHtcbiAgICByZXR1cm4geyBkYXRhOiBjb250ZW50LCBtZWRpYVR5cGU6IHVuZGVmaW5lZCB9O1xuICB9XG5cbiAgLy8gQXJyYXlCdWZmZXIgbmVlZHMgY29udmVyc2lvbiB0byBVaW50OEFycmF5IChsaWdodHdlaWdodCk6XG4gIGlmIChjb250ZW50IGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICByZXR1cm4geyBkYXRhOiBuZXcgVWludDhBcnJheShjb250ZW50KSwgbWVkaWFUeXBlOiB1bmRlZmluZWQgfTtcbiAgfVxuXG4gIC8vIEF0dGVtcHQgdG8gY3JlYXRlIGEgVVJMIGZyb20gdGhlIGRhdGEuIElmIGl0IGZhaWxzLCB3ZSBjYW4gYXNzdW1lIHRoZSBkYXRhXG4gIC8vIGlzIG5vdCBhIFVSTCBhbmQgbGlrZWx5IHNvbWUgb3RoZXIgc29ydCBvZiBkYXRhLlxuICBpZiAodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnRlbnQgPSBuZXcgVVJMKGNvbnRlbnQpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBpZ25vcmVkXG4gICAgfVxuICB9XG5cbiAgLy8gRXh0cmFjdCBkYXRhIGZyb20gZGF0YSBVUkw6XG4gIGlmIChjb250ZW50IGluc3RhbmNlb2YgVVJMICYmIGNvbnRlbnQucHJvdG9jb2wgPT09ICdkYXRhOicpIHtcbiAgICBjb25zdCB7IG1lZGlhVHlwZTogZGF0YVVybE1lZGlhVHlwZSwgYmFzZTY0Q29udGVudCB9ID0gc3BsaXREYXRhVXJsKFxuICAgICAgY29udGVudC50b1N0cmluZygpLFxuICAgICk7XG5cbiAgICBpZiAoZGF0YVVybE1lZGlhVHlwZSA9PSBudWxsIHx8IGJhc2U2NENvbnRlbnQgPT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEFJU0RLRXJyb3Ioe1xuICAgICAgICBuYW1lOiAnSW52YWxpZERhdGFDb250ZW50RXJyb3InLFxuICAgICAgICBtZXNzYWdlOiBgSW52YWxpZCBkYXRhIFVSTCBmb3JtYXQgaW4gY29udGVudCAke2NvbnRlbnQudG9TdHJpbmcoKX1gLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgZGF0YTogYmFzZTY0Q29udGVudCwgbWVkaWFUeXBlOiBkYXRhVXJsTWVkaWFUeXBlIH07XG4gIH1cblxuICByZXR1cm4geyBkYXRhOiBjb250ZW50LCBtZWRpYVR5cGU6IHVuZGVmaW5lZCB9O1xufVxuXG4vKipcbkNvbnZlcnRzIGRhdGEgY29udGVudCB0byBhIGJhc2U2NC1lbmNvZGVkIHN0cmluZy5cblxuQHBhcmFtIGNvbnRlbnQgLSBEYXRhIGNvbnRlbnQgdG8gY29udmVydC5cbkByZXR1cm5zIEJhc2U2NC1lbmNvZGVkIHN0cmluZy5cbiovXG5leHBvcnQgZnVuY3Rpb24gY29udmVydERhdGFDb250ZW50VG9CYXNlNjRTdHJpbmcoY29udGVudDogRGF0YUNvbnRlbnQpOiBzdHJpbmcge1xuICBpZiAodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGNvbnRlbnQ7XG4gIH1cblxuICBpZiAoY29udGVudCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgcmV0dXJuIGNvbnZlcnRVaW50OEFycmF5VG9CYXNlNjQobmV3IFVpbnQ4QXJyYXkoY29udGVudCkpO1xuICB9XG5cbiAgcmV0dXJuIGNvbnZlcnRVaW50OEFycmF5VG9CYXNlNjQoY29udGVudCk7XG59XG5cbi8qKlxuQ29udmVydHMgZGF0YSBjb250ZW50IHRvIGEgVWludDhBcnJheS5cblxuQHBhcmFtIGNvbnRlbnQgLSBEYXRhIGNvbnRlbnQgdG8gY29udmVydC5cbkByZXR1cm5zIFVpbnQ4QXJyYXkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb252ZXJ0RGF0YUNvbnRlbnRUb1VpbnQ4QXJyYXkoXG4gIGNvbnRlbnQ6IERhdGFDb250ZW50LFxuKTogVWludDhBcnJheSB7XG4gIGlmIChjb250ZW50IGluc3RhbmNlb2YgVWludDhBcnJheSkge1xuICAgIHJldHVybiBjb250ZW50O1xuICB9XG5cbiAgaWYgKHR5cGVvZiBjb250ZW50ID09PSAnc3RyaW5nJykge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gY29udmVydEJhc2U2NFRvVWludDhBcnJheShjb250ZW50KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWREYXRhQ29udGVudEVycm9yKHtcbiAgICAgICAgbWVzc2FnZTpcbiAgICAgICAgICAnSW52YWxpZCBkYXRhIGNvbnRlbnQuIENvbnRlbnQgc3RyaW5nIGlzIG5vdCBhIGJhc2U2NC1lbmNvZGVkIG1lZGlhLicsXG4gICAgICAgIGNvbnRlbnQsXG4gICAgICAgIGNhdXNlOiBlcnJvcixcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGlmIChjb250ZW50IGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoY29udGVudCk7XG4gIH1cblxuICB0aHJvdyBuZXcgSW52YWxpZERhdGFDb250ZW50RXJyb3IoeyBjb250ZW50IH0pO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIGEgVWludDhBcnJheSB0byBhIHN0cmluZyBvZiB0ZXh0LlxuICpcbiAqIEBwYXJhbSB1aW50OEFycmF5IC0gVGhlIFVpbnQ4QXJyYXkgdG8gY29udmVydC5cbiAqIEByZXR1cm5zIFRoZSBjb252ZXJ0ZWQgc3RyaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY29udmVydFVpbnQ4QXJyYXlUb1RleHQodWludDhBcnJheTogVWludDhBcnJheSk6IHN0cmluZyB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIG5ldyBUZXh0RGVjb2RlcigpLmRlY29kZSh1aW50OEFycmF5KTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0Vycm9yIGRlY29kaW5nIFVpbnQ4QXJyYXkgdG8gdGV4dCcpO1xuICB9XG59XG4iLCAiZXhwb3J0IGZ1bmN0aW9uIHNwbGl0RGF0YVVybChkYXRhVXJsOiBzdHJpbmcpOiB7XG4gIG1lZGlhVHlwZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBiYXNlNjRDb250ZW50OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG59IHtcbiAgdHJ5IHtcbiAgICBjb25zdCBbaGVhZGVyLCBiYXNlNjRDb250ZW50XSA9IGRhdGFVcmwuc3BsaXQoJywnKTtcbiAgICByZXR1cm4ge1xuICAgICAgbWVkaWFUeXBlOiBoZWFkZXIuc3BsaXQoJzsnKVswXS5zcGxpdCgnOicpWzFdLFxuICAgICAgYmFzZTY0Q29udGVudCxcbiAgICB9O1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiB7XG4gICAgICBtZWRpYVR5cGU6IHVuZGVmaW5lZCxcbiAgICAgIGJhc2U2NENvbnRlbnQ6IHVuZGVmaW5lZCxcbiAgICB9O1xuICB9XG59XG4iLCAiaW1wb3J0IHsgSW52YWxpZEFyZ3VtZW50RXJyb3IgfSBmcm9tICcuLi9lcnJvci9pbnZhbGlkLWFyZ3VtZW50LWVycm9yJztcbmltcG9ydCB7IENhbGxTZXR0aW5ncyB9IGZyb20gJy4vY2FsbC1zZXR0aW5ncyc7XG5cbi8qKlxuICogVmFsaWRhdGVzIGNhbGwgc2V0dGluZ3MgYW5kIHJldHVybnMgYSBuZXcgb2JqZWN0IHdpdGggbGltaXRlZCB2YWx1ZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcmVwYXJlQ2FsbFNldHRpbmdzKHtcbiAgbWF4T3V0cHV0VG9rZW5zLFxuICB0ZW1wZXJhdHVyZSxcbiAgdG9wUCxcbiAgdG9wSyxcbiAgcHJlc2VuY2VQZW5hbHR5LFxuICBmcmVxdWVuY3lQZW5hbHR5LFxuICBzZWVkLFxuICBzdG9wU2VxdWVuY2VzLFxufTogT21pdDxDYWxsU2V0dGluZ3MsICdhYm9ydFNpZ25hbCcgfCAnaGVhZGVycycgfCAnbWF4UmV0cmllcyc+KTogT21pdDxcbiAgQ2FsbFNldHRpbmdzLFxuICAnYWJvcnRTaWduYWwnIHwgJ2hlYWRlcnMnIHwgJ21heFJldHJpZXMnXG4+IHtcbiAgaWYgKG1heE91dHB1dFRva2VucyAhPSBudWxsKSB7XG4gICAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKG1heE91dHB1dFRva2VucykpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFcnJvcih7XG4gICAgICAgIHBhcmFtZXRlcjogJ21heE91dHB1dFRva2VucycsXG4gICAgICAgIHZhbHVlOiBtYXhPdXRwdXRUb2tlbnMsXG4gICAgICAgIG1lc3NhZ2U6ICdtYXhPdXRwdXRUb2tlbnMgbXVzdCBiZSBhbiBpbnRlZ2VyJyxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChtYXhPdXRwdXRUb2tlbnMgPCAxKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3Ioe1xuICAgICAgICBwYXJhbWV0ZXI6ICdtYXhPdXRwdXRUb2tlbnMnLFxuICAgICAgICB2YWx1ZTogbWF4T3V0cHV0VG9rZW5zLFxuICAgICAgICBtZXNzYWdlOiAnbWF4T3V0cHV0VG9rZW5zIG11c3QgYmUgPj0gMScsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBpZiAodGVtcGVyYXR1cmUgIT0gbnVsbCkge1xuICAgIGlmICh0eXBlb2YgdGVtcGVyYXR1cmUgIT09ICdudW1iZXInKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3Ioe1xuICAgICAgICBwYXJhbWV0ZXI6ICd0ZW1wZXJhdHVyZScsXG4gICAgICAgIHZhbHVlOiB0ZW1wZXJhdHVyZSxcbiAgICAgICAgbWVzc2FnZTogJ3RlbXBlcmF0dXJlIG11c3QgYmUgYSBudW1iZXInLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHRvcFAgIT0gbnVsbCkge1xuICAgIGlmICh0eXBlb2YgdG9wUCAhPT0gJ251bWJlcicpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFcnJvcih7XG4gICAgICAgIHBhcmFtZXRlcjogJ3RvcFAnLFxuICAgICAgICB2YWx1ZTogdG9wUCxcbiAgICAgICAgbWVzc2FnZTogJ3RvcFAgbXVzdCBiZSBhIG51bWJlcicsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBpZiAodG9wSyAhPSBudWxsKSB7XG4gICAgaWYgKHR5cGVvZiB0b3BLICE9PSAnbnVtYmVyJykge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEVycm9yKHtcbiAgICAgICAgcGFyYW1ldGVyOiAndG9wSycsXG4gICAgICAgIHZhbHVlOiB0b3BLLFxuICAgICAgICBtZXNzYWdlOiAndG9wSyBtdXN0IGJlIGEgbnVtYmVyJyxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGlmIChwcmVzZW5jZVBlbmFsdHkgIT0gbnVsbCkge1xuICAgIGlmICh0eXBlb2YgcHJlc2VuY2VQZW5hbHR5ICE9PSAnbnVtYmVyJykge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEVycm9yKHtcbiAgICAgICAgcGFyYW1ldGVyOiAncHJlc2VuY2VQZW5hbHR5JyxcbiAgICAgICAgdmFsdWU6IHByZXNlbmNlUGVuYWx0eSxcbiAgICAgICAgbWVzc2FnZTogJ3ByZXNlbmNlUGVuYWx0eSBtdXN0IGJlIGEgbnVtYmVyJyxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGlmIChmcmVxdWVuY3lQZW5hbHR5ICE9IG51bGwpIHtcbiAgICBpZiAodHlwZW9mIGZyZXF1ZW5jeVBlbmFsdHkgIT09ICdudW1iZXInKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3Ioe1xuICAgICAgICBwYXJhbWV0ZXI6ICdmcmVxdWVuY3lQZW5hbHR5JyxcbiAgICAgICAgdmFsdWU6IGZyZXF1ZW5jeVBlbmFsdHksXG4gICAgICAgIG1lc3NhZ2U6ICdmcmVxdWVuY3lQZW5hbHR5IG11c3QgYmUgYSBudW1iZXInLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHNlZWQgIT0gbnVsbCkge1xuICAgIGlmICghTnVtYmVyLmlzSW50ZWdlcihzZWVkKSkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEVycm9yKHtcbiAgICAgICAgcGFyYW1ldGVyOiAnc2VlZCcsXG4gICAgICAgIHZhbHVlOiBzZWVkLFxuICAgICAgICBtZXNzYWdlOiAnc2VlZCBtdXN0IGJlIGFuIGludGVnZXInLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBtYXhPdXRwdXRUb2tlbnMsXG4gICAgdGVtcGVyYXR1cmUsXG4gICAgdG9wUCxcbiAgICB0b3BLLFxuICAgIHByZXNlbmNlUGVuYWx0eSxcbiAgICBmcmVxdWVuY3lQZW5hbHR5LFxuICAgIHN0b3BTZXF1ZW5jZXMsXG4gICAgc2VlZCxcbiAgfTtcbn1cbiIsICJpbXBvcnQge1xuICBMYW5ndWFnZU1vZGVsVjJGdW5jdGlvblRvb2wsXG4gIExhbmd1YWdlTW9kZWxWMlByb3ZpZGVyRGVmaW5lZFRvb2wsXG4gIExhbmd1YWdlTW9kZWxWMlRvb2xDaG9pY2UsXG59IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgYXNTY2hlbWEgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyLXV0aWxzJztcbmltcG9ydCB7IGlzTm9uRW1wdHlPYmplY3QgfSBmcm9tICcuLi91dGlsL2lzLW5vbi1lbXB0eS1vYmplY3QnO1xuaW1wb3J0IHsgVG9vbFNldCB9IGZyb20gJy4uL2dlbmVyYXRlLXRleHQnO1xuaW1wb3J0IHsgVG9vbENob2ljZSB9IGZyb20gJy4uL3R5cGVzL2xhbmd1YWdlLW1vZGVsJztcblxuZXhwb3J0IGZ1bmN0aW9uIHByZXBhcmVUb29sc0FuZFRvb2xDaG9pY2U8VE9PTFMgZXh0ZW5kcyBUb29sU2V0Pih7XG4gIHRvb2xzLFxuICB0b29sQ2hvaWNlLFxuICBhY3RpdmVUb29scyxcbn06IHtcbiAgdG9vbHM6IFRPT0xTIHwgdW5kZWZpbmVkO1xuICB0b29sQ2hvaWNlOiBUb29sQ2hvaWNlPFRPT0xTPiB8IHVuZGVmaW5lZDtcbiAgYWN0aXZlVG9vbHM6IEFycmF5PGtleW9mIFRPT0xTPiB8IHVuZGVmaW5lZDtcbn0pOiB7XG4gIHRvb2xzOlxuICAgIHwgQXJyYXk8TGFuZ3VhZ2VNb2RlbFYyRnVuY3Rpb25Ub29sIHwgTGFuZ3VhZ2VNb2RlbFYyUHJvdmlkZXJEZWZpbmVkVG9vbD5cbiAgICB8IHVuZGVmaW5lZDtcbiAgdG9vbENob2ljZTogTGFuZ3VhZ2VNb2RlbFYyVG9vbENob2ljZSB8IHVuZGVmaW5lZDtcbn0ge1xuICBpZiAoIWlzTm9uRW1wdHlPYmplY3QodG9vbHMpKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHRvb2xzOiB1bmRlZmluZWQsXG4gICAgICB0b29sQ2hvaWNlOiB1bmRlZmluZWQsXG4gICAgfTtcbiAgfVxuXG4gIC8vIHdoZW4gYWN0aXZlVG9vbHMgaXMgcHJvdmlkZWQsIHdlIG9ubHkgaW5jbHVkZSB0aGUgdG9vbHMgdGhhdCBhcmUgaW4gdGhlIGxpc3Q6XG4gIGNvbnN0IGZpbHRlcmVkVG9vbHMgPVxuICAgIGFjdGl2ZVRvb2xzICE9IG51bGxcbiAgICAgID8gT2JqZWN0LmVudHJpZXModG9vbHMpLmZpbHRlcigoW25hbWVdKSA9PlxuICAgICAgICAgIGFjdGl2ZVRvb2xzLmluY2x1ZGVzKG5hbWUgYXMga2V5b2YgVE9PTFMpLFxuICAgICAgICApXG4gICAgICA6IE9iamVjdC5lbnRyaWVzKHRvb2xzKTtcblxuICByZXR1cm4ge1xuICAgIHRvb2xzOiBmaWx0ZXJlZFRvb2xzLm1hcCgoW25hbWUsIHRvb2xdKSA9PiB7XG4gICAgICBjb25zdCB0b29sVHlwZSA9IHRvb2wudHlwZTtcbiAgICAgIHN3aXRjaCAodG9vbFR5cGUpIHtcbiAgICAgICAgY2FzZSB1bmRlZmluZWQ6XG4gICAgICAgIGNhc2UgJ2R5bmFtaWMnOlxuICAgICAgICBjYXNlICdmdW5jdGlvbic6XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6ICdmdW5jdGlvbicgYXMgY29uc3QsXG4gICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IHRvb2wuZGVzY3JpcHRpb24sXG4gICAgICAgICAgICBpbnB1dFNjaGVtYTogYXNTY2hlbWEodG9vbC5pbnB1dFNjaGVtYSkuanNvblNjaGVtYSxcbiAgICAgICAgICAgIHByb3ZpZGVyT3B0aW9uczogdG9vbC5wcm92aWRlck9wdGlvbnMsXG4gICAgICAgICAgfTtcbiAgICAgICAgY2FzZSAncHJvdmlkZXItZGVmaW5lZCc6XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6ICdwcm92aWRlci1kZWZpbmVkJyBhcyBjb25zdCxcbiAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICBpZDogdG9vbC5pZCxcbiAgICAgICAgICAgIGFyZ3M6IHRvb2wuYXJncyxcbiAgICAgICAgICB9O1xuICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgY29uc3QgZXhoYXVzdGl2ZUNoZWNrOiBuZXZlciA9IHRvb2xUeXBlO1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgdG9vbCB0eXBlOiAke2V4aGF1c3RpdmVDaGVja31gKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pLFxuICAgIHRvb2xDaG9pY2U6XG4gICAgICB0b29sQ2hvaWNlID09IG51bGxcbiAgICAgICAgPyB7IHR5cGU6ICdhdXRvJyB9XG4gICAgICAgIDogdHlwZW9mIHRvb2xDaG9pY2UgPT09ICdzdHJpbmcnXG4gICAgICAgICAgPyB7IHR5cGU6IHRvb2xDaG9pY2UgfVxuICAgICAgICAgIDogeyB0eXBlOiAndG9vbCcgYXMgY29uc3QsIHRvb2xOYW1lOiB0b29sQ2hvaWNlLnRvb2xOYW1lIGFzIHN0cmluZyB9LFxuICB9O1xufVxuIiwgImV4cG9ydCBmdW5jdGlvbiBpc05vbkVtcHR5T2JqZWN0KFxuICBvYmplY3Q6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgdW5kZWZpbmVkIHwgbnVsbCxcbik6IG9iamVjdCBpcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gIHJldHVybiBvYmplY3QgIT0gbnVsbCAmJiBPYmplY3Qua2V5cyhvYmplY3QpLmxlbmd0aCA+IDA7XG59XG4iLCAiaW1wb3J0IHsgSW52YWxpZFByb21wdEVycm9yIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQgeyBNb2RlbE1lc3NhZ2UsIHNhZmVWYWxpZGF0ZVR5cGVzIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyB6IH0gZnJvbSAnem9kL3Y0JztcbmltcG9ydCB7IG1vZGVsTWVzc2FnZVNjaGVtYSB9IGZyb20gJy4vbWVzc2FnZSc7XG5pbXBvcnQgeyBQcm9tcHQgfSBmcm9tICcuL3Byb21wdCc7XG5cbmV4cG9ydCB0eXBlIFN0YW5kYXJkaXplZFByb21wdCA9IHtcbiAgLyoqXG4gICAqIFN5c3RlbSBtZXNzYWdlLlxuICAgKi9cbiAgc3lzdGVtPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBNZXNzYWdlcy5cbiAgICovXG4gIG1lc3NhZ2VzOiBNb2RlbE1lc3NhZ2VbXTtcbn07XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzdGFuZGFyZGl6ZVByb21wdChcbiAgcHJvbXB0OiBQcm9tcHQsXG4pOiBQcm9taXNlPFN0YW5kYXJkaXplZFByb21wdD4ge1xuICBpZiAocHJvbXB0LnByb21wdCA9PSBudWxsICYmIHByb21wdC5tZXNzYWdlcyA9PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IEludmFsaWRQcm9tcHRFcnJvcih7XG4gICAgICBwcm9tcHQsXG4gICAgICBtZXNzYWdlOiAncHJvbXB0IG9yIG1lc3NhZ2VzIG11c3QgYmUgZGVmaW5lZCcsXG4gICAgfSk7XG4gIH1cblxuICBpZiAocHJvbXB0LnByb21wdCAhPSBudWxsICYmIHByb21wdC5tZXNzYWdlcyAhPSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IEludmFsaWRQcm9tcHRFcnJvcih7XG4gICAgICBwcm9tcHQsXG4gICAgICBtZXNzYWdlOiAncHJvbXB0IGFuZCBtZXNzYWdlcyBjYW5ub3QgYmUgZGVmaW5lZCBhdCB0aGUgc2FtZSB0aW1lJyxcbiAgICB9KTtcbiAgfVxuXG4gIC8vIHZhbGlkYXRlIHRoYXQgc3lzdGVtIGlzIGEgc3RyaW5nXG4gIGlmIChwcm9tcHQuc3lzdGVtICE9IG51bGwgJiYgdHlwZW9mIHByb21wdC5zeXN0ZW0gIT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IEludmFsaWRQcm9tcHRFcnJvcih7XG4gICAgICBwcm9tcHQsXG4gICAgICBtZXNzYWdlOiAnc3lzdGVtIG11c3QgYmUgYSBzdHJpbmcnLFxuICAgIH0pO1xuICB9XG5cbiAgbGV0IG1lc3NhZ2VzOiBNb2RlbE1lc3NhZ2VbXTtcblxuICBpZiAocHJvbXB0LnByb21wdCAhPSBudWxsICYmIHR5cGVvZiBwcm9tcHQucHJvbXB0ID09PSAnc3RyaW5nJykge1xuICAgIG1lc3NhZ2VzID0gW3sgcm9sZTogJ3VzZXInLCBjb250ZW50OiBwcm9tcHQucHJvbXB0IH1dO1xuICB9IGVsc2UgaWYgKHByb21wdC5wcm9tcHQgIT0gbnVsbCAmJiBBcnJheS5pc0FycmF5KHByb21wdC5wcm9tcHQpKSB7XG4gICAgbWVzc2FnZXMgPSBwcm9tcHQucHJvbXB0O1xuICB9IGVsc2UgaWYgKHByb21wdC5tZXNzYWdlcyAhPSBudWxsKSB7XG4gICAgbWVzc2FnZXMgPSBwcm9tcHQubWVzc2FnZXM7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEludmFsaWRQcm9tcHRFcnJvcih7XG4gICAgICBwcm9tcHQsXG4gICAgICBtZXNzYWdlOiAncHJvbXB0IG9yIG1lc3NhZ2VzIG11c3QgYmUgZGVmaW5lZCcsXG4gICAgfSk7XG4gIH1cblxuICBpZiAobWVzc2FnZXMubGVuZ3RoID09PSAwKSB7XG4gICAgdGhyb3cgbmV3IEludmFsaWRQcm9tcHRFcnJvcih7XG4gICAgICBwcm9tcHQsXG4gICAgICBtZXNzYWdlOiAnbWVzc2FnZXMgbXVzdCBub3QgYmUgZW1wdHknLFxuICAgIH0pO1xuICB9XG5cbiAgY29uc3QgdmFsaWRhdGlvblJlc3VsdCA9IGF3YWl0IHNhZmVWYWxpZGF0ZVR5cGVzKHtcbiAgICB2YWx1ZTogbWVzc2FnZXMsXG4gICAgc2NoZW1hOiB6LmFycmF5KG1vZGVsTWVzc2FnZVNjaGVtYSksXG4gIH0pO1xuXG4gIGlmICghdmFsaWRhdGlvblJlc3VsdC5zdWNjZXNzKSB7XG4gICAgdGhyb3cgbmV3IEludmFsaWRQcm9tcHRFcnJvcih7XG4gICAgICBwcm9tcHQsXG4gICAgICBtZXNzYWdlOlxuICAgICAgICAnVGhlIG1lc3NhZ2VzIG11c3QgYmUgYSBNb2RlbE1lc3NhZ2VbXS4gJyArXG4gICAgICAgICdJZiB5b3UgaGF2ZSBwYXNzZWQgYSBVSU1lc3NhZ2VbXSwgeW91IGNhbiB1c2UgY29udmVydFRvTW9kZWxNZXNzYWdlcyB0byBjb252ZXJ0IHRoZW0uJyxcbiAgICAgIGNhdXNlOiB2YWxpZGF0aW9uUmVzdWx0LmVycm9yLFxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBtZXNzYWdlcyxcbiAgICBzeXN0ZW06IHByb21wdC5zeXN0ZW0sXG4gIH07XG59XG4iLCAiaW1wb3J0IHtcbiAgQXNzaXN0YW50TW9kZWxNZXNzYWdlLFxuICBNb2RlbE1lc3NhZ2UsXG4gIFN5c3RlbU1vZGVsTWVzc2FnZSxcbiAgVG9vbE1vZGVsTWVzc2FnZSxcbiAgVXNlck1vZGVsTWVzc2FnZSxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyB6IH0gZnJvbSAnem9kL3Y0JztcbmltcG9ydCB7IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEgfSBmcm9tICcuLi90eXBlcy9wcm92aWRlci1tZXRhZGF0YSc7XG5pbXBvcnQge1xuICBmaWxlUGFydFNjaGVtYSxcbiAgaW1hZ2VQYXJ0U2NoZW1hLFxuICByZWFzb25pbmdQYXJ0U2NoZW1hLFxuICB0ZXh0UGFydFNjaGVtYSxcbiAgdG9vbENhbGxQYXJ0U2NoZW1hLFxuICB0b29sUmVzdWx0UGFydFNjaGVtYSxcbn0gZnJvbSAnLi9jb250ZW50LXBhcnQnO1xuXG4vKipcbkBkZXByZWNhdGVkIFVzZSBgU3lzdGVtTW9kZWxNZXNzYWdlYCBpbnN0ZWFkLlxuICovXG4vLyBUT0RPIHJlbW92ZSBpbiBBSSBTREsgNlxuZXhwb3J0IHR5cGUgQ29yZVN5c3RlbU1lc3NhZ2UgPSBTeXN0ZW1Nb2RlbE1lc3NhZ2U7XG5cbmV4cG9ydCBjb25zdCBzeXN0ZW1Nb2RlbE1lc3NhZ2VTY2hlbWE6IHouWm9kVHlwZTxTeXN0ZW1Nb2RlbE1lc3NhZ2U+ID0gei5vYmplY3QoXG4gIHtcbiAgICByb2xlOiB6LmxpdGVyYWwoJ3N5c3RlbScpLFxuICAgIGNvbnRlbnQ6IHouc3RyaW5nKCksXG4gICAgcHJvdmlkZXJPcHRpb25zOiBwcm92aWRlck1ldGFkYXRhU2NoZW1hLm9wdGlvbmFsKCksXG4gIH0sXG4pO1xuXG4vKipcbkBkZXByZWNhdGVkIFVzZSBgc3lzdGVtTW9kZWxNZXNzYWdlU2NoZW1hYCBpbnN0ZWFkLlxuICovXG4vLyBUT0RPIHJlbW92ZSBpbiBBSSBTREsgNlxuZXhwb3J0IGNvbnN0IGNvcmVTeXN0ZW1NZXNzYWdlU2NoZW1hID0gc3lzdGVtTW9kZWxNZXNzYWdlU2NoZW1hO1xuXG4vKipcbkBkZXByZWNhdGVkIFVzZSBgVXNlck1vZGVsTWVzc2FnZWAgaW5zdGVhZC5cbiAqL1xuLy8gVE9ETyByZW1vdmUgaW4gQUkgU0RLIDZcbmV4cG9ydCB0eXBlIENvcmVVc2VyTWVzc2FnZSA9IFVzZXJNb2RlbE1lc3NhZ2U7XG5cbmV4cG9ydCBjb25zdCB1c2VyTW9kZWxNZXNzYWdlU2NoZW1hOiB6LlpvZFR5cGU8VXNlck1vZGVsTWVzc2FnZT4gPSB6Lm9iamVjdCh7XG4gIHJvbGU6IHoubGl0ZXJhbCgndXNlcicpLFxuICBjb250ZW50OiB6LnVuaW9uKFtcbiAgICB6LnN0cmluZygpLFxuICAgIHouYXJyYXkoei51bmlvbihbdGV4dFBhcnRTY2hlbWEsIGltYWdlUGFydFNjaGVtYSwgZmlsZVBhcnRTY2hlbWFdKSksXG4gIF0pLFxuICBwcm92aWRlck9wdGlvbnM6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbn0pO1xuXG4vKipcbkBkZXByZWNhdGVkIFVzZSBgdXNlck1vZGVsTWVzc2FnZVNjaGVtYWAgaW5zdGVhZC5cbiAqL1xuLy8gVE9ETyByZW1vdmUgaW4gQUkgU0RLIDZcbmV4cG9ydCBjb25zdCBjb3JlVXNlck1lc3NhZ2VTY2hlbWEgPSB1c2VyTW9kZWxNZXNzYWdlU2NoZW1hO1xuXG4vKipcbkBkZXByZWNhdGVkIFVzZSBgQXNzaXN0YW50TW9kZWxNZXNzYWdlYCBpbnN0ZWFkLlxuICovXG4vLyBUT0RPIHJlbW92ZSBpbiBBSSBTREsgNlxuZXhwb3J0IHR5cGUgQ29yZUFzc2lzdGFudE1lc3NhZ2UgPSBBc3Npc3RhbnRNb2RlbE1lc3NhZ2U7XG5cbmV4cG9ydCBjb25zdCBhc3Npc3RhbnRNb2RlbE1lc3NhZ2VTY2hlbWE6IHouWm9kVHlwZTxBc3Npc3RhbnRNb2RlbE1lc3NhZ2U+ID1cbiAgei5vYmplY3Qoe1xuICAgIHJvbGU6IHoubGl0ZXJhbCgnYXNzaXN0YW50JyksXG4gICAgY29udGVudDogei51bmlvbihbXG4gICAgICB6LnN0cmluZygpLFxuICAgICAgei5hcnJheShcbiAgICAgICAgei51bmlvbihbXG4gICAgICAgICAgdGV4dFBhcnRTY2hlbWEsXG4gICAgICAgICAgZmlsZVBhcnRTY2hlbWEsXG4gICAgICAgICAgcmVhc29uaW5nUGFydFNjaGVtYSxcbiAgICAgICAgICB0b29sQ2FsbFBhcnRTY2hlbWEsXG4gICAgICAgICAgdG9vbFJlc3VsdFBhcnRTY2hlbWEsXG4gICAgICAgIF0pLFxuICAgICAgKSxcbiAgICBdKSxcbiAgICBwcm92aWRlck9wdGlvbnM6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbiAgfSk7XG5cbi8qKlxuQGRlcHJlY2F0ZWQgVXNlIGBhc3Npc3RhbnRNb2RlbE1lc3NhZ2VTY2hlbWFgIGluc3RlYWQuXG4gKi9cbi8vIFRPRE8gcmVtb3ZlIGluIEFJIFNESyA2XG5leHBvcnQgY29uc3QgY29yZUFzc2lzdGFudE1lc3NhZ2VTY2hlbWEgPSBhc3Npc3RhbnRNb2RlbE1lc3NhZ2VTY2hlbWE7XG5cbi8qKlxuQGRlcHJlY2F0ZWQgVXNlIGBUb29sTW9kZWxNZXNzYWdlYCBpbnN0ZWFkLlxuICovXG4vLyBUT0RPIHJlbW92ZSBpbiBBSSBTREsgNlxuZXhwb3J0IHR5cGUgQ29yZVRvb2xNZXNzYWdlID0gVG9vbE1vZGVsTWVzc2FnZTtcblxuZXhwb3J0IGNvbnN0IHRvb2xNb2RlbE1lc3NhZ2VTY2hlbWE6IHouWm9kVHlwZTxUb29sTW9kZWxNZXNzYWdlPiA9IHoub2JqZWN0KHtcbiAgcm9sZTogei5saXRlcmFsKCd0b29sJyksXG4gIGNvbnRlbnQ6IHouYXJyYXkodG9vbFJlc3VsdFBhcnRTY2hlbWEpLFxuICBwcm92aWRlck9wdGlvbnM6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbn0pO1xuXG4vKipcbkBkZXByZWNhdGVkIFVzZSBgdG9vbE1vZGVsTWVzc2FnZVNjaGVtYWAgaW5zdGVhZC5cbiAqL1xuLy8gVE9ETyByZW1vdmUgaW4gQUkgU0RLIDZcbmV4cG9ydCBjb25zdCBjb3JlVG9vbE1lc3NhZ2VTY2hlbWEgPSB0b29sTW9kZWxNZXNzYWdlU2NoZW1hO1xuXG4vKipcbkBkZXByZWNhdGVkIFVzZSBgTW9kZWxNZXNzYWdlYCBpbnN0ZWFkLlxuICAgKi9cbi8vIFRPRE8gcmVtb3ZlIGluIEFJIFNESyA2XG5leHBvcnQgdHlwZSBDb3JlTWVzc2FnZSA9IE1vZGVsTWVzc2FnZTtcblxuZXhwb3J0IGNvbnN0IG1vZGVsTWVzc2FnZVNjaGVtYTogei5ab2RUeXBlPE1vZGVsTWVzc2FnZT4gPSB6LnVuaW9uKFtcbiAgc3lzdGVtTW9kZWxNZXNzYWdlU2NoZW1hLFxuICB1c2VyTW9kZWxNZXNzYWdlU2NoZW1hLFxuICBhc3Npc3RhbnRNb2RlbE1lc3NhZ2VTY2hlbWEsXG4gIHRvb2xNb2RlbE1lc3NhZ2VTY2hlbWEsXG5dKTtcblxuLyoqXG5AZGVwcmVjYXRlZCBVc2UgYG1vZGVsTWVzc2FnZVNjaGVtYWAgaW5zdGVhZC5cbiAqL1xuLy8gVE9ETyByZW1vdmUgaW4gQUkgU0RLIDZcbmV4cG9ydCBjb25zdCBjb3JlTWVzc2FnZVNjaGVtYTogei5ab2RUeXBlPENvcmVNZXNzYWdlPiA9IG1vZGVsTWVzc2FnZVNjaGVtYTtcbiIsICJpbXBvcnQgeyBTaGFyZWRWMlByb3ZpZGVyTWV0YWRhdGEgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcbmltcG9ydCB7IHogfSBmcm9tICd6b2QvdjQnO1xuaW1wb3J0IHsganNvblZhbHVlU2NoZW1hIH0gZnJvbSAnLi9qc29uLXZhbHVlJztcblxuLyoqXG5BZGRpdGlvbmFsIHByb3ZpZGVyLXNwZWNpZmljIG1ldGFkYXRhIHRoYXQgaXMgcmV0dXJuZWQgZnJvbSB0aGUgcHJvdmlkZXIuXG5cblRoaXMgaXMgbmVlZGVkIHRvIGVuYWJsZSBwcm92aWRlci1zcGVjaWZpYyBmdW5jdGlvbmFsaXR5IHRoYXQgY2FuIGJlXG5mdWxseSBlbmNhcHN1bGF0ZWQgaW4gdGhlIHByb3ZpZGVyLlxuICovXG5leHBvcnQgdHlwZSBQcm92aWRlck1ldGFkYXRhID0gU2hhcmVkVjJQcm92aWRlck1ldGFkYXRhO1xuXG5leHBvcnQgY29uc3QgcHJvdmlkZXJNZXRhZGF0YVNjaGVtYTogei5ab2RUeXBlPFByb3ZpZGVyTWV0YWRhdGE+ID0gei5yZWNvcmQoXG4gIHouc3RyaW5nKCksXG4gIHoucmVjb3JkKHouc3RyaW5nKCksIGpzb25WYWx1ZVNjaGVtYSksXG4pO1xuIiwgImltcG9ydCB7IEpTT05WYWx1ZSBhcyBPcmlnaW5hbEpTT05WYWx1ZSB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgeiB9IGZyb20gJ3pvZC92NCc7XG5cbmV4cG9ydCBjb25zdCBqc29uVmFsdWVTY2hlbWE6IHouWm9kVHlwZTxKU09OVmFsdWU+ID0gei5sYXp5KCgpID0+XG4gIHoudW5pb24oW1xuICAgIHoubnVsbCgpLFxuICAgIHouc3RyaW5nKCksXG4gICAgei5udW1iZXIoKSxcbiAgICB6LmJvb2xlYW4oKSxcbiAgICB6LnJlY29yZCh6LnN0cmluZygpLCBqc29uVmFsdWVTY2hlbWEpLFxuICAgIHouYXJyYXkoanNvblZhbHVlU2NoZW1hKSxcbiAgXSksXG4pO1xuXG5leHBvcnQgdHlwZSBKU09OVmFsdWUgPSBPcmlnaW5hbEpTT05WYWx1ZTtcbiIsICJpbXBvcnQgeyBMYW5ndWFnZU1vZGVsVjJUb29sUmVzdWx0T3V0cHV0IH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQge1xuICBGaWxlUGFydCxcbiAgSW1hZ2VQYXJ0LFxuICBQcm92aWRlck9wdGlvbnMsXG4gIFJlYXNvbmluZ1BhcnQsXG4gIFRleHRQYXJ0LFxuICBUb29sUmVzdWx0UGFydCxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyB6IH0gZnJvbSAnem9kL3Y0JztcbmltcG9ydCB7IGpzb25WYWx1ZVNjaGVtYSB9IGZyb20gJy4uL3R5cGVzL2pzb24tdmFsdWUnO1xuaW1wb3J0IHsgcHJvdmlkZXJNZXRhZGF0YVNjaGVtYSB9IGZyb20gJy4uL3R5cGVzL3Byb3ZpZGVyLW1ldGFkYXRhJztcbmltcG9ydCB7IGRhdGFDb250ZW50U2NoZW1hIH0gZnJvbSAnLi9kYXRhLWNvbnRlbnQnO1xuXG4vKipcbkBpbnRlcm5hbFxuICovXG5leHBvcnQgY29uc3QgdGV4dFBhcnRTY2hlbWE6IHouWm9kVHlwZTxUZXh0UGFydD4gPSB6Lm9iamVjdCh7XG4gIHR5cGU6IHoubGl0ZXJhbCgndGV4dCcpLFxuICB0ZXh0OiB6LnN0cmluZygpLFxuICBwcm92aWRlck9wdGlvbnM6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbn0pO1xuXG4vKipcbkBpbnRlcm5hbFxuICovXG5leHBvcnQgY29uc3QgaW1hZ2VQYXJ0U2NoZW1hOiB6LlpvZFR5cGU8SW1hZ2VQYXJ0PiA9IHoub2JqZWN0KHtcbiAgdHlwZTogei5saXRlcmFsKCdpbWFnZScpLFxuICBpbWFnZTogei51bmlvbihbZGF0YUNvbnRlbnRTY2hlbWEsIHouaW5zdGFuY2VvZihVUkwpXSksXG4gIG1lZGlhVHlwZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICBwcm92aWRlck9wdGlvbnM6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbn0pO1xuXG4vKipcbkBpbnRlcm5hbFxuICovXG5leHBvcnQgY29uc3QgZmlsZVBhcnRTY2hlbWE6IHouWm9kVHlwZTxGaWxlUGFydD4gPSB6Lm9iamVjdCh7XG4gIHR5cGU6IHoubGl0ZXJhbCgnZmlsZScpLFxuICBkYXRhOiB6LnVuaW9uKFtkYXRhQ29udGVudFNjaGVtYSwgei5pbnN0YW5jZW9mKFVSTCldKSxcbiAgZmlsZW5hbWU6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgbWVkaWFUeXBlOiB6LnN0cmluZygpLFxuICBwcm92aWRlck9wdGlvbnM6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbn0pO1xuXG4vKipcbkBpbnRlcm5hbFxuICovXG5leHBvcnQgY29uc3QgcmVhc29uaW5nUGFydFNjaGVtYTogei5ab2RUeXBlPFJlYXNvbmluZ1BhcnQ+ID0gei5vYmplY3Qoe1xuICB0eXBlOiB6LmxpdGVyYWwoJ3JlYXNvbmluZycpLFxuICB0ZXh0OiB6LnN0cmluZygpLFxuICBwcm92aWRlck9wdGlvbnM6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbn0pO1xuXG4vKipcblRvb2wgY2FsbCBjb250ZW50IHBhcnQgb2YgYSBwcm9tcHQuIEl0IGNvbnRhaW5zIGEgdG9vbCBjYWxsICh1c3VhbGx5IGdlbmVyYXRlZCBieSB0aGUgQUkgbW9kZWwpLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRvb2xDYWxsUGFydCB7XG4gIHR5cGU6ICd0b29sLWNhbGwnO1xuXG4gIC8qKlxuSUQgb2YgdGhlIHRvb2wgY2FsbC4gVGhpcyBJRCBpcyB1c2VkIHRvIG1hdGNoIHRoZSB0b29sIGNhbGwgd2l0aCB0aGUgdG9vbCByZXN1bHQuXG4gKi9cbiAgdG9vbENhbGxJZDogc3RyaW5nO1xuXG4gIC8qKlxuTmFtZSBvZiB0aGUgdG9vbCB0aGF0IGlzIGJlaW5nIGNhbGxlZC5cbiAqL1xuICB0b29sTmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuQXJndW1lbnRzIG9mIHRoZSB0b29sIGNhbGwuIFRoaXMgaXMgYSBKU09OLXNlcmlhbGl6YWJsZSBvYmplY3QgdGhhdCBtYXRjaGVzIHRoZSB0b29sJ3MgaW5wdXQgc2NoZW1hLlxuICAgKi9cbiAgaW5wdXQ6IHVua25vd247XG5cbiAgLyoqXG5BZGRpdGlvbmFsIHByb3ZpZGVyLXNwZWNpZmljIG1ldGFkYXRhLiBUaGV5IGFyZSBwYXNzZWQgdGhyb3VnaFxudG8gdGhlIHByb3ZpZGVyIGZyb20gdGhlIEFJIFNESyBhbmQgZW5hYmxlIHByb3ZpZGVyLXNwZWNpZmljXG5mdW5jdGlvbmFsaXR5IHRoYXQgY2FuIGJlIGZ1bGx5IGVuY2Fwc3VsYXRlZCBpbiB0aGUgcHJvdmlkZXIuXG4gKi9cbiAgcHJvdmlkZXJPcHRpb25zPzogUHJvdmlkZXJPcHRpb25zO1xufVxuXG4vKipcbkBpbnRlcm5hbFxuICovXG5leHBvcnQgY29uc3QgdG9vbENhbGxQYXJ0U2NoZW1hOiB6LlpvZFR5cGU8VG9vbENhbGxQYXJ0PiA9IHoub2JqZWN0KHtcbiAgdHlwZTogei5saXRlcmFsKCd0b29sLWNhbGwnKSxcbiAgdG9vbENhbGxJZDogei5zdHJpbmcoKSxcbiAgdG9vbE5hbWU6IHouc3RyaW5nKCksXG4gIGlucHV0OiB6LnVua25vd24oKSxcbiAgcHJvdmlkZXJPcHRpb25zOiBwcm92aWRlck1ldGFkYXRhU2NoZW1hLm9wdGlvbmFsKCksXG4gIHByb3ZpZGVyRXhlY3V0ZWQ6IHouYm9vbGVhbigpLm9wdGlvbmFsKCksXG59KSBhcyB6LlpvZFR5cGU8VG9vbENhbGxQYXJ0PjsgLy8gbmVjZXNzYXJ5IGJjIGlucHV0IGlzIG9wdGlvbmFsIG9uIFpvZCB0eXBlXG5cbi8qKlxuQGludGVybmFsXG4gKi9cbmV4cG9ydCBjb25zdCBvdXRwdXRTY2hlbWE6IHouWm9kVHlwZTxMYW5ndWFnZU1vZGVsVjJUb29sUmVzdWx0T3V0cHV0PiA9XG4gIHouZGlzY3JpbWluYXRlZFVuaW9uKCd0eXBlJywgW1xuICAgIHoub2JqZWN0KHtcbiAgICAgIHR5cGU6IHoubGl0ZXJhbCgndGV4dCcpLFxuICAgICAgdmFsdWU6IHouc3RyaW5nKCksXG4gICAgfSksXG4gICAgei5vYmplY3Qoe1xuICAgICAgdHlwZTogei5saXRlcmFsKCdqc29uJyksXG4gICAgICB2YWx1ZToganNvblZhbHVlU2NoZW1hLFxuICAgIH0pLFxuICAgIHoub2JqZWN0KHtcbiAgICAgIHR5cGU6IHoubGl0ZXJhbCgnZXJyb3ItdGV4dCcpLFxuICAgICAgdmFsdWU6IHouc3RyaW5nKCksXG4gICAgfSksXG4gICAgei5vYmplY3Qoe1xuICAgICAgdHlwZTogei5saXRlcmFsKCdlcnJvci1qc29uJyksXG4gICAgICB2YWx1ZToganNvblZhbHVlU2NoZW1hLFxuICAgIH0pLFxuICAgIHoub2JqZWN0KHtcbiAgICAgIHR5cGU6IHoubGl0ZXJhbCgnY29udGVudCcpLFxuICAgICAgdmFsdWU6IHouYXJyYXkoXG4gICAgICAgIHoudW5pb24oW1xuICAgICAgICAgIHoub2JqZWN0KHtcbiAgICAgICAgICAgIHR5cGU6IHoubGl0ZXJhbCgndGV4dCcpLFxuICAgICAgICAgICAgdGV4dDogei5zdHJpbmcoKSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICB6Lm9iamVjdCh7XG4gICAgICAgICAgICB0eXBlOiB6LmxpdGVyYWwoJ21lZGlhJyksXG4gICAgICAgICAgICBkYXRhOiB6LnN0cmluZygpLFxuICAgICAgICAgICAgbWVkaWFUeXBlOiB6LnN0cmluZygpLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdKSxcbiAgICAgICksXG4gICAgfSksXG4gIF0pO1xuXG4vKipcbkBpbnRlcm5hbFxuICovXG5leHBvcnQgY29uc3QgdG9vbFJlc3VsdFBhcnRTY2hlbWE6IHouWm9kVHlwZTxUb29sUmVzdWx0UGFydD4gPSB6Lm9iamVjdCh7XG4gIHR5cGU6IHoubGl0ZXJhbCgndG9vbC1yZXN1bHQnKSxcbiAgdG9vbENhbGxJZDogei5zdHJpbmcoKSxcbiAgdG9vbE5hbWU6IHouc3RyaW5nKCksXG4gIG91dHB1dDogb3V0cHV0U2NoZW1hLFxuICBwcm92aWRlck9wdGlvbnM6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbn0pIGFzIHouWm9kVHlwZTxUb29sUmVzdWx0UGFydD47IC8vIG5lY2Vzc2FyeSBiYyByZXN1bHQgaXMgb3B0aW9uYWwgb24gWm9kIHR5cGVcbiIsICJpbXBvcnQge1xuICBHYXRld2F5QXV0aGVudGljYXRpb25FcnJvcixcbiAgR2F0ZXdheU1vZGVsTm90Rm91bmRFcnJvcixcbn0gZnJvbSAnQGFpLXNkay9nYXRld2F5JztcbmltcG9ydCB7IEFJU0RLRXJyb3IgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcblxuZXhwb3J0IGZ1bmN0aW9uIHdyYXBHYXRld2F5RXJyb3IoZXJyb3I6IHVua25vd24pOiB1bmtub3duIHtcbiAgaWYgKFxuICAgIEdhdGV3YXlBdXRoZW50aWNhdGlvbkVycm9yLmlzSW5zdGFuY2UoZXJyb3IpIHx8XG4gICAgR2F0ZXdheU1vZGVsTm90Rm91bmRFcnJvci5pc0luc3RhbmNlKGVycm9yKVxuICApIHtcbiAgICByZXR1cm4gbmV3IEFJU0RLRXJyb3Ioe1xuICAgICAgbmFtZTogJ0dhdGV3YXlFcnJvcicsXG4gICAgICBtZXNzYWdlOlxuICAgICAgICAnVmVyY2VsIEFJIEdhdGV3YXkgYWNjZXNzIGZhaWxlZC4gJyArXG4gICAgICAgICdJZiB5b3Ugd2FudCB0byB1c2UgQUkgU0RLIHByb3ZpZGVycyBkaXJlY3RseSwgdXNlIHRoZSBwcm92aWRlcnMsIGUuZy4gQGFpLXNkay9vcGVuYWksICcgK1xuICAgICAgICAnb3IgcmVnaXN0ZXIgYSBkaWZmZXJlbnQgZ2xvYmFsIGRlZmF1bHQgcHJvdmlkZXIuJyxcbiAgICAgIGNhdXNlOiBlcnJvcixcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBlcnJvcjtcbn1cbiIsICJpbXBvcnQgeyBUZWxlbWV0cnlTZXR0aW5ncyB9IGZyb20gJy4vdGVsZW1ldHJ5LXNldHRpbmdzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGFzc2VtYmxlT3BlcmF0aW9uTmFtZSh7XG4gIG9wZXJhdGlvbklkLFxuICB0ZWxlbWV0cnksXG59OiB7XG4gIG9wZXJhdGlvbklkOiBzdHJpbmc7XG4gIHRlbGVtZXRyeT86IFRlbGVtZXRyeVNldHRpbmdzO1xufSkge1xuICByZXR1cm4ge1xuICAgIC8vIHN0YW5kYXJkaXplZCBvcGVyYXRpb24gYW5kIHJlc291cmNlIG5hbWU6XG4gICAgJ29wZXJhdGlvbi5uYW1lJzogYCR7b3BlcmF0aW9uSWR9JHtcbiAgICAgIHRlbGVtZXRyeT8uZnVuY3Rpb25JZCAhPSBudWxsID8gYCAke3RlbGVtZXRyeS5mdW5jdGlvbklkfWAgOiAnJ1xuICAgIH1gLFxuICAgICdyZXNvdXJjZS5uYW1lJzogdGVsZW1ldHJ5Py5mdW5jdGlvbklkLFxuXG4gICAgLy8gZGV0YWlsZWQsIEFJIFNESyBzcGVjaWZpYyBkYXRhOlxuICAgICdhaS5vcGVyYXRpb25JZCc6IG9wZXJhdGlvbklkLFxuICAgICdhaS50ZWxlbWV0cnkuZnVuY3Rpb25JZCc6IHRlbGVtZXRyeT8uZnVuY3Rpb25JZCxcbiAgfTtcbn1cbiIsICJpbXBvcnQgeyBBdHRyaWJ1dGVzIH0gZnJvbSAnQG9wZW50ZWxlbWV0cnkvYXBpJztcbmltcG9ydCB7IENhbGxTZXR0aW5ncyB9IGZyb20gJy4uL3Byb21wdC9jYWxsLXNldHRpbmdzJztcbmltcG9ydCB7IFRlbGVtZXRyeVNldHRpbmdzIH0gZnJvbSAnLi90ZWxlbWV0cnktc2V0dGluZ3MnO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QmFzZVRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICBtb2RlbCxcbiAgc2V0dGluZ3MsXG4gIHRlbGVtZXRyeSxcbiAgaGVhZGVycyxcbn06IHtcbiAgbW9kZWw6IHsgbW9kZWxJZDogc3RyaW5nOyBwcm92aWRlcjogc3RyaW5nIH07XG4gIHNldHRpbmdzOiBPbWl0PENhbGxTZXR0aW5ncywgJ2Fib3J0U2lnbmFsJyB8ICdoZWFkZXJzJyB8ICd0ZW1wZXJhdHVyZSc+O1xuICB0ZWxlbWV0cnk6IFRlbGVtZXRyeVNldHRpbmdzIHwgdW5kZWZpbmVkO1xuICBoZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+IHwgdW5kZWZpbmVkO1xufSk6IEF0dHJpYnV0ZXMge1xuICByZXR1cm4ge1xuICAgICdhaS5tb2RlbC5wcm92aWRlcic6IG1vZGVsLnByb3ZpZGVyLFxuICAgICdhaS5tb2RlbC5pZCc6IG1vZGVsLm1vZGVsSWQsXG5cbiAgICAvLyBzZXR0aW5nczpcbiAgICAuLi5PYmplY3QuZW50cmllcyhzZXR0aW5ncykucmVkdWNlKChhdHRyaWJ1dGVzLCBba2V5LCB2YWx1ZV0pID0+IHtcbiAgICAgIGF0dHJpYnV0ZXNbYGFpLnNldHRpbmdzLiR7a2V5fWBdID0gdmFsdWU7XG4gICAgICByZXR1cm4gYXR0cmlidXRlcztcbiAgICB9LCB7fSBhcyBBdHRyaWJ1dGVzKSxcblxuICAgIC8vIGFkZCBtZXRhZGF0YSBhcyBhdHRyaWJ1dGVzOlxuICAgIC4uLk9iamVjdC5lbnRyaWVzKHRlbGVtZXRyeT8ubWV0YWRhdGEgPz8ge30pLnJlZHVjZShcbiAgICAgIChhdHRyaWJ1dGVzLCBba2V5LCB2YWx1ZV0pID0+IHtcbiAgICAgICAgYXR0cmlidXRlc1tgYWkudGVsZW1ldHJ5Lm1ldGFkYXRhLiR7a2V5fWBdID0gdmFsdWU7XG4gICAgICAgIHJldHVybiBhdHRyaWJ1dGVzO1xuICAgICAgfSxcbiAgICAgIHt9IGFzIEF0dHJpYnV0ZXMsXG4gICAgKSxcblxuICAgIC8vIHJlcXVlc3QgaGVhZGVyc1xuICAgIC4uLk9iamVjdC5lbnRyaWVzKGhlYWRlcnMgPz8ge30pLnJlZHVjZSgoYXR0cmlidXRlcywgW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBhdHRyaWJ1dGVzW2BhaS5yZXF1ZXN0LmhlYWRlcnMuJHtrZXl9YF0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhdHRyaWJ1dGVzO1xuICAgIH0sIHt9IGFzIEF0dHJpYnV0ZXMpLFxuICB9O1xufVxuIiwgImltcG9ydCB7IFRyYWNlciwgdHJhY2UgfSBmcm9tICdAb3BlbnRlbGVtZXRyeS9hcGknO1xuaW1wb3J0IHsgbm9vcFRyYWNlciB9IGZyb20gJy4vbm9vcC10cmFjZXInO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VHJhY2VyKHtcbiAgaXNFbmFibGVkID0gZmFsc2UsXG4gIHRyYWNlcixcbn06IHtcbiAgaXNFbmFibGVkPzogYm9vbGVhbjtcbiAgdHJhY2VyPzogVHJhY2VyO1xufSA9IHt9KTogVHJhY2VyIHtcbiAgaWYgKCFpc0VuYWJsZWQpIHtcbiAgICByZXR1cm4gbm9vcFRyYWNlcjtcbiAgfVxuXG4gIGlmICh0cmFjZXIpIHtcbiAgICByZXR1cm4gdHJhY2VyO1xuICB9XG5cbiAgcmV0dXJuIHRyYWNlLmdldFRyYWNlcignYWknKTtcbn1cbiIsICJpbXBvcnQgeyBTcGFuLCBTcGFuQ29udGV4dCwgVHJhY2VyIH0gZnJvbSAnQG9wZW50ZWxlbWV0cnkvYXBpJztcblxuLyoqXG4gKiBUcmFjZXIgaW1wbGVtZW50YXRpb24gdGhhdCBkb2VzIG5vdGhpbmcgKG51bGwgb2JqZWN0KS5cbiAqL1xuZXhwb3J0IGNvbnN0IG5vb3BUcmFjZXI6IFRyYWNlciA9IHtcbiAgc3RhcnRTcGFuKCk6IFNwYW4ge1xuICAgIHJldHVybiBub29wU3BhbjtcbiAgfSxcblxuICBzdGFydEFjdGl2ZVNwYW48RiBleHRlbmRzIChzcGFuOiBTcGFuKSA9PiB1bmtub3duPihcbiAgICBuYW1lOiB1bmtub3duLFxuICAgIGFyZzE6IHVua25vd24sXG4gICAgYXJnMj86IHVua25vd24sXG4gICAgYXJnMz86IEYsXG4gICk6IFJldHVyblR5cGU8YW55PiB7XG4gICAgaWYgKHR5cGVvZiBhcmcxID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gYXJnMShub29wU3Bhbik7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgYXJnMiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIGFyZzIobm9vcFNwYW4pO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGFyZzMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiBhcmczKG5vb3BTcGFuKTtcbiAgICB9XG4gIH0sXG59O1xuXG5jb25zdCBub29wU3BhbjogU3BhbiA9IHtcbiAgc3BhbkNvbnRleHQoKSB7XG4gICAgcmV0dXJuIG5vb3BTcGFuQ29udGV4dDtcbiAgfSxcbiAgc2V0QXR0cmlidXRlKCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9LFxuICBzZXRBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9LFxuICBhZGRFdmVudCgpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfSxcbiAgYWRkTGluaygpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfSxcbiAgYWRkTGlua3MoKSB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG4gIHNldFN0YXR1cygpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfSxcbiAgdXBkYXRlTmFtZSgpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfSxcbiAgZW5kKCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9LFxuICBpc1JlY29yZGluZygpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH0sXG4gIHJlY29yZEV4Y2VwdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfSxcbn07XG5cbmNvbnN0IG5vb3BTcGFuQ29udGV4dDogU3BhbkNvbnRleHQgPSB7XG4gIHRyYWNlSWQ6ICcnLFxuICBzcGFuSWQ6ICcnLFxuICB0cmFjZUZsYWdzOiAwLFxufTtcbiIsICJpbXBvcnQgeyBBdHRyaWJ1dGVzLCBTcGFuLCBUcmFjZXIsIFNwYW5TdGF0dXNDb2RlIH0gZnJvbSAnQG9wZW50ZWxlbWV0cnkvYXBpJztcblxuZXhwb3J0IGZ1bmN0aW9uIHJlY29yZFNwYW48VD4oe1xuICBuYW1lLFxuICB0cmFjZXIsXG4gIGF0dHJpYnV0ZXMsXG4gIGZuLFxuICBlbmRXaGVuRG9uZSA9IHRydWUsXG59OiB7XG4gIG5hbWU6IHN0cmluZztcbiAgdHJhY2VyOiBUcmFjZXI7XG4gIGF0dHJpYnV0ZXM6IEF0dHJpYnV0ZXM7XG4gIGZuOiAoc3BhbjogU3BhbikgPT4gUHJvbWlzZTxUPjtcbiAgZW5kV2hlbkRvbmU/OiBib29sZWFuO1xufSkge1xuICByZXR1cm4gdHJhY2VyLnN0YXJ0QWN0aXZlU3BhbihuYW1lLCB7IGF0dHJpYnV0ZXMgfSwgYXN5bmMgc3BhbiA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGZuKHNwYW4pO1xuXG4gICAgICBpZiAoZW5kV2hlbkRvbmUpIHtcbiAgICAgICAgc3Bhbi5lbmQoKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmVjb3JkRXJyb3JPblNwYW4oc3BhbiwgZXJyb3IpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgLy8gYWx3YXlzIHN0b3AgdGhlIHNwYW4gd2hlbiB0aGVyZSBpcyBhbiBlcnJvcjpcbiAgICAgICAgc3Bhbi5lbmQoKTtcbiAgICAgIH1cblxuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9KTtcbn1cblxuLyoqXG4gKiBSZWNvcmQgYW4gZXJyb3Igb24gYSBzcGFuLiBJZiB0aGUgZXJyb3IgaXMgYW4gaW5zdGFuY2Ugb2YgRXJyb3IsIGFuIGV4Y2VwdGlvbiBldmVudCB3aWxsIGJlIHJlY29yZGVkIG9uIHRoZSBzcGFuLCBvdGhlcndpc2VcbiAqIHRoZSBzcGFuIHdpbGwgYmUgc2V0IHRvIGFuIGVycm9yIHN0YXR1cy5cbiAqXG4gKiBAcGFyYW0gc3BhbiAtIFRoZSBzcGFuIHRvIHJlY29yZCB0aGUgZXJyb3Igb24uXG4gKiBAcGFyYW0gZXJyb3IgLSBUaGUgZXJyb3IgdG8gcmVjb3JkIG9uIHRoZSBzcGFuLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVjb3JkRXJyb3JPblNwYW4oc3BhbjogU3BhbiwgZXJyb3I6IHVua25vd24pIHtcbiAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICBzcGFuLnJlY29yZEV4Y2VwdGlvbih7XG4gICAgICBuYW1lOiBlcnJvci5uYW1lLFxuICAgICAgbWVzc2FnZTogZXJyb3IubWVzc2FnZSxcbiAgICAgIHN0YWNrOiBlcnJvci5zdGFjayxcbiAgICB9KTtcbiAgICBzcGFuLnNldFN0YXR1cyh7XG4gICAgICBjb2RlOiBTcGFuU3RhdHVzQ29kZS5FUlJPUixcbiAgICAgIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UsXG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgc3Bhbi5zZXRTdGF0dXMoeyBjb2RlOiBTcGFuU3RhdHVzQ29kZS5FUlJPUiB9KTtcbiAgfVxufVxuIiwgImltcG9ydCB0eXBlIHsgQXR0cmlidXRlcywgQXR0cmlidXRlVmFsdWUgfSBmcm9tICdAb3BlbnRlbGVtZXRyeS9hcGknO1xuaW1wb3J0IHR5cGUgeyBUZWxlbWV0cnlTZXR0aW5ncyB9IGZyb20gJy4vdGVsZW1ldHJ5LXNldHRpbmdzJztcblxuZXhwb3J0IGZ1bmN0aW9uIHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICB0ZWxlbWV0cnksXG4gIGF0dHJpYnV0ZXMsXG59OiB7XG4gIHRlbGVtZXRyeT86IFRlbGVtZXRyeVNldHRpbmdzO1xuICBhdHRyaWJ1dGVzOiB7XG4gICAgW2F0dHJpYnV0ZUtleTogc3RyaW5nXTpcbiAgICAgIHwgQXR0cmlidXRlVmFsdWVcbiAgICAgIHwgeyBpbnB1dDogKCkgPT4gQXR0cmlidXRlVmFsdWUgfCB1bmRlZmluZWQgfVxuICAgICAgfCB7IG91dHB1dDogKCkgPT4gQXR0cmlidXRlVmFsdWUgfCB1bmRlZmluZWQgfVxuICAgICAgfCB1bmRlZmluZWQ7XG4gIH07XG59KTogQXR0cmlidXRlcyB7XG4gIC8vIHdoZW4gdGVsZW1ldHJ5IGlzIGRpc2FibGVkLCByZXR1cm4gYW4gZW1wdHkgb2JqZWN0IHRvIGF2b2lkIHNlcmlhbGl6YXRpb24gb3ZlcmhlYWQ6XG4gIGlmICh0ZWxlbWV0cnk/LmlzRW5hYmxlZCAhPT0gdHJ1ZSkge1xuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIHJldHVybiBPYmplY3QuZW50cmllcyhhdHRyaWJ1dGVzKS5yZWR1Y2UoKGF0dHJpYnV0ZXMsIFtrZXksIHZhbHVlXSkgPT4ge1xuICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgICByZXR1cm4gYXR0cmlidXRlcztcbiAgICB9XG5cbiAgICAvLyBpbnB1dCB2YWx1ZSwgY2hlY2sgaWYgaXQgc2hvdWxkIGJlIHJlY29yZGVkOlxuICAgIGlmIChcbiAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiZcbiAgICAgICdpbnB1dCcgaW4gdmFsdWUgJiZcbiAgICAgIHR5cGVvZiB2YWx1ZS5pbnB1dCA9PT0gJ2Z1bmN0aW9uJ1xuICAgICkge1xuICAgICAgLy8gZGVmYXVsdCB0byB0cnVlOlxuICAgICAgaWYgKHRlbGVtZXRyeT8ucmVjb3JkSW5wdXRzID09PSBmYWxzZSkge1xuICAgICAgICByZXR1cm4gYXR0cmlidXRlcztcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVzdWx0ID0gdmFsdWUuaW5wdXQoKTtcblxuICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gYXR0cmlidXRlcyA6IHsgLi4uYXR0cmlidXRlcywgW2tleV06IHJlc3VsdCB9O1xuICAgIH1cblxuICAgIC8vIG91dHB1dCB2YWx1ZSwgY2hlY2sgaWYgaXQgc2hvdWxkIGJlIHJlY29yZGVkOlxuICAgIGlmIChcbiAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiZcbiAgICAgICdvdXRwdXQnIGluIHZhbHVlICYmXG4gICAgICB0eXBlb2YgdmFsdWUub3V0cHV0ID09PSAnZnVuY3Rpb24nXG4gICAgKSB7XG4gICAgICAvLyBkZWZhdWx0IHRvIHRydWU6XG4gICAgICBpZiAodGVsZW1ldHJ5Py5yZWNvcmRPdXRwdXRzID09PSBmYWxzZSkge1xuICAgICAgICByZXR1cm4gYXR0cmlidXRlcztcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVzdWx0ID0gdmFsdWUub3V0cHV0KCk7XG5cbiAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IGF0dHJpYnV0ZXMgOiB7IC4uLmF0dHJpYnV0ZXMsIFtrZXldOiByZXN1bHQgfTtcbiAgICB9XG5cbiAgICAvLyB2YWx1ZSBpcyBhbiBhdHRyaWJ1dGUgdmFsdWUgYWxyZWFkeTpcbiAgICByZXR1cm4geyAuLi5hdHRyaWJ1dGVzLCBba2V5XTogdmFsdWUgfTtcbiAgfSwge30pO1xufVxuIiwgImltcG9ydCB7XG4gIExhbmd1YWdlTW9kZWxWMk1lc3NhZ2UsXG4gIExhbmd1YWdlTW9kZWxWMlByb21wdCxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQgeyBjb252ZXJ0RGF0YUNvbnRlbnRUb0Jhc2U2NFN0cmluZyB9IGZyb20gJy4uL3Byb21wdC9kYXRhLWNvbnRlbnQnO1xuXG4vKipcbiAqIEhlbHBlciB1dGlsaXR5IHRvIHNlcmlhbGl6ZSBwcm9tcHQgY29udGVudCBmb3IgT3BlblRlbGVtZXRyeSB0cmFjaW5nLlxuICogSXQgaXMgaW5pdGlhbGx5IGNyZWF0ZWQgYmVjYXVzZSBub3JtYWxpemVkIExhbmd1YWdlTW9kZWxWMVByb21wdCBjYXJyaWVzXG4gKiBpbWFnZXMgYXMgVWludDhBcnJheXMsIG9uIHdoaWNoIEpTT04uc3RyaW5naWZ5IGFjdHMgd2VpcmRseSwgY29udmVydGluZ1xuICogdGhlbSB0byBvYmplY3RzIHdpdGggc3RyaW5naWZpZWQgaW5kaWNlcyBhcyBrZXlzLCBlLmcuIHtcIjBcIjogNDIsIFwiMVwiOiA2OSB9LlxuICovXG5leHBvcnQgZnVuY3Rpb24gc3RyaW5naWZ5Rm9yVGVsZW1ldHJ5KHByb21wdDogTGFuZ3VhZ2VNb2RlbFYyUHJvbXB0KTogc3RyaW5nIHtcbiAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KFxuICAgIHByb21wdC5tYXAoKG1lc3NhZ2U6IExhbmd1YWdlTW9kZWxWMk1lc3NhZ2UpID0+ICh7XG4gICAgICAuLi5tZXNzYWdlLFxuICAgICAgY29udGVudDpcbiAgICAgICAgdHlwZW9mIG1lc3NhZ2UuY29udGVudCA9PT0gJ3N0cmluZydcbiAgICAgICAgICA/IG1lc3NhZ2UuY29udGVudFxuICAgICAgICAgIDogbWVzc2FnZS5jb250ZW50Lm1hcChwYXJ0ID0+XG4gICAgICAgICAgICAgIHBhcnQudHlwZSA9PT0gJ2ZpbGUnXG4gICAgICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgICAgIC4uLnBhcnQsXG4gICAgICAgICAgICAgICAgICAgIGRhdGE6XG4gICAgICAgICAgICAgICAgICAgICAgcGFydC5kYXRhIGluc3RhbmNlb2YgVWludDhBcnJheVxuICAgICAgICAgICAgICAgICAgICAgICAgPyBjb252ZXJ0RGF0YUNvbnRlbnRUb0Jhc2U2NFN0cmluZyhwYXJ0LmRhdGEpXG4gICAgICAgICAgICAgICAgICAgICAgICA6IHBhcnQuZGF0YSxcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA6IHBhcnQsXG4gICAgICAgICAgICApLFxuICAgIH0pKSxcbiAgKTtcbn1cbiIsICJpbXBvcnQgeyBMYW5ndWFnZU1vZGVsVjJVc2FnZSB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuXG4vKipcblJlcHJlc2VudHMgdGhlIG51bWJlciBvZiB0b2tlbnMgdXNlZCBpbiBhIHByb21wdCBhbmQgY29tcGxldGlvbi5cbiAqL1xuZXhwb3J0IHR5cGUgTGFuZ3VhZ2VNb2RlbFVzYWdlID0gTGFuZ3VhZ2VNb2RlbFYyVXNhZ2U7XG5cbi8qKlxuUmVwcmVzZW50cyB0aGUgbnVtYmVyIG9mIHRva2VucyB1c2VkIGluIGFuIGVtYmVkZGluZy5cbiAqL1xuLy8gVE9ETyByZXBsYWNlIHdpdGggRW1iZWRkaW5nTW9kZWxWMlVzYWdlXG5leHBvcnQgdHlwZSBFbWJlZGRpbmdNb2RlbFVzYWdlID0ge1xuICAvKipcblRoZSBudW1iZXIgb2YgdG9rZW5zIHVzZWQgaW4gdGhlIGVtYmVkZGluZy5cbiAgICovXG4gIHRva2VuczogbnVtYmVyO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGFkZExhbmd1YWdlTW9kZWxVc2FnZShcbiAgdXNhZ2UxOiBMYW5ndWFnZU1vZGVsVXNhZ2UsXG4gIHVzYWdlMjogTGFuZ3VhZ2VNb2RlbFVzYWdlLFxuKTogTGFuZ3VhZ2VNb2RlbFVzYWdlIHtcbiAgcmV0dXJuIHtcbiAgICBpbnB1dFRva2VuczogYWRkVG9rZW5Db3VudHModXNhZ2UxLmlucHV0VG9rZW5zLCB1c2FnZTIuaW5wdXRUb2tlbnMpLFxuICAgIG91dHB1dFRva2VuczogYWRkVG9rZW5Db3VudHModXNhZ2UxLm91dHB1dFRva2VucywgdXNhZ2UyLm91dHB1dFRva2VucyksXG4gICAgdG90YWxUb2tlbnM6IGFkZFRva2VuQ291bnRzKHVzYWdlMS50b3RhbFRva2VucywgdXNhZ2UyLnRvdGFsVG9rZW5zKSxcbiAgICByZWFzb25pbmdUb2tlbnM6IGFkZFRva2VuQ291bnRzKFxuICAgICAgdXNhZ2UxLnJlYXNvbmluZ1Rva2VucyxcbiAgICAgIHVzYWdlMi5yZWFzb25pbmdUb2tlbnMsXG4gICAgKSxcbiAgICBjYWNoZWRJbnB1dFRva2VuczogYWRkVG9rZW5Db3VudHMoXG4gICAgICB1c2FnZTEuY2FjaGVkSW5wdXRUb2tlbnMsXG4gICAgICB1c2FnZTIuY2FjaGVkSW5wdXRUb2tlbnMsXG4gICAgKSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gYWRkVG9rZW5Db3VudHMoXG4gIHRva2VuQ291bnQxOiBudW1iZXIgfCB1bmRlZmluZWQsXG4gIHRva2VuQ291bnQyOiBudW1iZXIgfCB1bmRlZmluZWQsXG4pOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICByZXR1cm4gdG9rZW5Db3VudDEgPT0gbnVsbCAmJiB0b2tlbkNvdW50MiA9PSBudWxsXG4gICAgPyB1bmRlZmluZWRcbiAgICA6ICh0b2tlbkNvdW50MSA/PyAwKSArICh0b2tlbkNvdW50MiA/PyAwKTtcbn1cbiIsICJleHBvcnQgZnVuY3Rpb24gYXNBcnJheTxUPih2YWx1ZTogVCB8IFRbXSB8IHVuZGVmaW5lZCk6IFRbXSB7XG4gIHJldHVybiB2YWx1ZSA9PT0gdW5kZWZpbmVkID8gW10gOiBBcnJheS5pc0FycmF5KHZhbHVlKSA/IHZhbHVlIDogW3ZhbHVlXTtcbn1cbiIsICJpbXBvcnQgeyBBUElDYWxsRXJyb3IgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcbmltcG9ydCB7IGRlbGF5LCBnZXRFcnJvck1lc3NhZ2UsIGlzQWJvcnRFcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXItdXRpbHMnO1xuaW1wb3J0IHsgUmV0cnlFcnJvciB9IGZyb20gJy4vcmV0cnktZXJyb3InO1xuXG5leHBvcnQgdHlwZSBSZXRyeUZ1bmN0aW9uID0gPE9VVFBVVD4oXG4gIGZuOiAoKSA9PiBQcm9taXNlTGlrZTxPVVRQVVQ+LFxuKSA9PiBQcm9taXNlTGlrZTxPVVRQVVQ+O1xuXG5mdW5jdGlvbiBnZXRSZXRyeURlbGF5SW5Ncyh7XG4gIGVycm9yLFxuICBleHBvbmVudGlhbEJhY2tvZmZEZWxheSxcbn06IHtcbiAgZXJyb3I6IEFQSUNhbGxFcnJvcjtcbiAgZXhwb25lbnRpYWxCYWNrb2ZmRGVsYXk6IG51bWJlcjtcbn0pOiBudW1iZXIge1xuICBjb25zdCBoZWFkZXJzID0gZXJyb3IucmVzcG9uc2VIZWFkZXJzO1xuXG4gIGlmICghaGVhZGVycykgcmV0dXJuIGV4cG9uZW50aWFsQmFja29mZkRlbGF5O1xuXG4gIGxldCBtczogbnVtYmVyIHwgdW5kZWZpbmVkO1xuXG4gIC8vIHJldHJ5LW1zIGlzIG1vcmUgcHJlY2lzZSB0aGFuIHJldHJ5LWFmdGVyIGFuZCB1c2VkIGJ5IGUuZy4gT3BlbkFJXG4gIGNvbnN0IHJldHJ5QWZ0ZXJNcyA9IGhlYWRlcnNbJ3JldHJ5LWFmdGVyLW1zJ107XG4gIGlmIChyZXRyeUFmdGVyTXMpIHtcbiAgICBjb25zdCB0aW1lb3V0TXMgPSBwYXJzZUZsb2F0KHJldHJ5QWZ0ZXJNcyk7XG4gICAgaWYgKCFOdW1iZXIuaXNOYU4odGltZW91dE1zKSkge1xuICAgICAgbXMgPSB0aW1lb3V0TXM7XG4gICAgfVxuICB9XG5cbiAgLy8gQWJvdXQgdGhlIFJldHJ5LUFmdGVyIGhlYWRlcjogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRUUC9IZWFkZXJzL1JldHJ5LUFmdGVyXG4gIGNvbnN0IHJldHJ5QWZ0ZXIgPSBoZWFkZXJzWydyZXRyeS1hZnRlciddO1xuICBpZiAocmV0cnlBZnRlciAmJiBtcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgY29uc3QgdGltZW91dFNlY29uZHMgPSBwYXJzZUZsb2F0KHJldHJ5QWZ0ZXIpO1xuICAgIGlmICghTnVtYmVyLmlzTmFOKHRpbWVvdXRTZWNvbmRzKSkge1xuICAgICAgbXMgPSB0aW1lb3V0U2Vjb25kcyAqIDEwMDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIG1zID0gRGF0ZS5wYXJzZShyZXRyeUFmdGVyKSAtIERhdGUubm93KCk7XG4gICAgfVxuICB9XG5cbiAgLy8gY2hlY2sgdGhhdCB0aGUgZGVsYXkgaXMgcmVhc29uYWJsZTpcbiAgaWYgKFxuICAgIG1zICE9IG51bGwgJiZcbiAgICAhTnVtYmVyLmlzTmFOKG1zKSAmJlxuICAgIDAgPD0gbXMgJiZcbiAgICAobXMgPCA2MCAqIDEwMDAgfHwgbXMgPCBleHBvbmVudGlhbEJhY2tvZmZEZWxheSlcbiAgKSB7XG4gICAgcmV0dXJuIG1zO1xuICB9XG5cbiAgcmV0dXJuIGV4cG9uZW50aWFsQmFja29mZkRlbGF5O1xufVxuXG4vKipcblRoZSBgcmV0cnlXaXRoRXhwb25lbnRpYWxCYWNrb2ZmUmVzcGVjdGluZ1JldHJ5SGVhZGVyc2Agc3RyYXRlZ3kgcmV0cmllcyBhIGZhaWxlZCBBUEkgY2FsbCB3aXRoIGFuIGV4cG9uZW50aWFsIGJhY2tvZmYsXG53aGlsZSByZXNwZWN0aW5nIHJhdGUgbGltaXQgaGVhZGVycyAocmV0cnktYWZ0ZXItbXMgYW5kIHJldHJ5LWFmdGVyKSBpZiB0aGV5IGFyZSBwcm92aWRlZCBhbmQgcmVhc29uYWJsZSAoMC02MCBzZWNvbmRzKS5cbllvdSBjYW4gY29uZmlndXJlIHRoZSBtYXhpbXVtIG51bWJlciBvZiByZXRyaWVzLCB0aGUgaW5pdGlhbCBkZWxheSwgYW5kIHRoZSBiYWNrb2ZmIGZhY3Rvci5cbiAqL1xuZXhwb3J0IGNvbnN0IHJldHJ5V2l0aEV4cG9uZW50aWFsQmFja29mZlJlc3BlY3RpbmdSZXRyeUhlYWRlcnMgPVxuICAoe1xuICAgIG1heFJldHJpZXMgPSAyLFxuICAgIGluaXRpYWxEZWxheUluTXMgPSAyMDAwLFxuICAgIGJhY2tvZmZGYWN0b3IgPSAyLFxuICAgIGFib3J0U2lnbmFsLFxuICB9OiB7XG4gICAgbWF4UmV0cmllcz86IG51bWJlcjtcbiAgICBpbml0aWFsRGVsYXlJbk1zPzogbnVtYmVyO1xuICAgIGJhY2tvZmZGYWN0b3I/OiBudW1iZXI7XG4gICAgYWJvcnRTaWduYWw/OiBBYm9ydFNpZ25hbDtcbiAgfSA9IHt9KTogUmV0cnlGdW5jdGlvbiA9PlxuICBhc3luYyA8T1VUUFVUPihmOiAoKSA9PiBQcm9taXNlTGlrZTxPVVRQVVQ+KSA9PlxuICAgIF9yZXRyeVdpdGhFeHBvbmVudGlhbEJhY2tvZmYoZiwge1xuICAgICAgbWF4UmV0cmllcyxcbiAgICAgIGRlbGF5SW5NczogaW5pdGlhbERlbGF5SW5NcyxcbiAgICAgIGJhY2tvZmZGYWN0b3IsXG4gICAgICBhYm9ydFNpZ25hbCxcbiAgICB9KTtcblxuYXN5bmMgZnVuY3Rpb24gX3JldHJ5V2l0aEV4cG9uZW50aWFsQmFja29mZjxPVVRQVVQ+KFxuICBmOiAoKSA9PiBQcm9taXNlTGlrZTxPVVRQVVQ+LFxuICB7XG4gICAgbWF4UmV0cmllcyxcbiAgICBkZWxheUluTXMsXG4gICAgYmFja29mZkZhY3RvcixcbiAgICBhYm9ydFNpZ25hbCxcbiAgfToge1xuICAgIG1heFJldHJpZXM6IG51bWJlcjtcbiAgICBkZWxheUluTXM6IG51bWJlcjtcbiAgICBiYWNrb2ZmRmFjdG9yOiBudW1iZXI7XG4gICAgYWJvcnRTaWduYWw6IEFib3J0U2lnbmFsIHwgdW5kZWZpbmVkO1xuICB9LFxuICBlcnJvcnM6IHVua25vd25bXSA9IFtdLFxuKTogUHJvbWlzZTxPVVRQVVQ+IHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gYXdhaXQgZigpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmIChpc0Fib3J0RXJyb3IoZXJyb3IpKSB7XG4gICAgICB0aHJvdyBlcnJvcjsgLy8gZG9uJ3QgcmV0cnkgd2hlbiB0aGUgcmVxdWVzdCB3YXMgYWJvcnRlZFxuICAgIH1cblxuICAgIGlmIChtYXhSZXRyaWVzID09PSAwKSB7XG4gICAgICB0aHJvdyBlcnJvcjsgLy8gZG9uJ3Qgd3JhcCB0aGUgZXJyb3Igd2hlbiByZXRyaWVzIGFyZSBkaXNhYmxlZFxuICAgIH1cblxuICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGdldEVycm9yTWVzc2FnZShlcnJvcik7XG4gICAgY29uc3QgbmV3RXJyb3JzID0gWy4uLmVycm9ycywgZXJyb3JdO1xuICAgIGNvbnN0IHRyeU51bWJlciA9IG5ld0Vycm9ycy5sZW5ndGg7XG5cbiAgICBpZiAodHJ5TnVtYmVyID4gbWF4UmV0cmllcykge1xuICAgICAgdGhyb3cgbmV3IFJldHJ5RXJyb3Ioe1xuICAgICAgICBtZXNzYWdlOiBgRmFpbGVkIGFmdGVyICR7dHJ5TnVtYmVyfSBhdHRlbXB0cy4gTGFzdCBlcnJvcjogJHtlcnJvck1lc3NhZ2V9YCxcbiAgICAgICAgcmVhc29uOiAnbWF4UmV0cmllc0V4Y2VlZGVkJyxcbiAgICAgICAgZXJyb3JzOiBuZXdFcnJvcnMsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICBlcnJvciBpbnN0YW5jZW9mIEVycm9yICYmXG4gICAgICBBUElDYWxsRXJyb3IuaXNJbnN0YW5jZShlcnJvcikgJiZcbiAgICAgIGVycm9yLmlzUmV0cnlhYmxlID09PSB0cnVlICYmXG4gICAgICB0cnlOdW1iZXIgPD0gbWF4UmV0cmllc1xuICAgICkge1xuICAgICAgYXdhaXQgZGVsYXkoXG4gICAgICAgIGdldFJldHJ5RGVsYXlJbk1zKHtcbiAgICAgICAgICBlcnJvcixcbiAgICAgICAgICBleHBvbmVudGlhbEJhY2tvZmZEZWxheTogZGVsYXlJbk1zLFxuICAgICAgICB9KSxcbiAgICAgICAgeyBhYm9ydFNpZ25hbCB9LFxuICAgICAgKTtcblxuICAgICAgcmV0dXJuIF9yZXRyeVdpdGhFeHBvbmVudGlhbEJhY2tvZmYoXG4gICAgICAgIGYsXG4gICAgICAgIHtcbiAgICAgICAgICBtYXhSZXRyaWVzLFxuICAgICAgICAgIGRlbGF5SW5NczogYmFja29mZkZhY3RvciAqIGRlbGF5SW5NcyxcbiAgICAgICAgICBiYWNrb2ZmRmFjdG9yLFxuICAgICAgICAgIGFib3J0U2lnbmFsLFxuICAgICAgICB9LFxuICAgICAgICBuZXdFcnJvcnMsXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICh0cnlOdW1iZXIgPT09IDEpIHtcbiAgICAgIHRocm93IGVycm9yOyAvLyBkb24ndCB3cmFwIHRoZSBlcnJvciB3aGVuIGEgbm9uLXJldHJ5YWJsZSBlcnJvciBvY2N1cnMgb24gdGhlIGZpcnN0IHRyeVxuICAgIH1cblxuICAgIHRocm93IG5ldyBSZXRyeUVycm9yKHtcbiAgICAgIG1lc3NhZ2U6IGBGYWlsZWQgYWZ0ZXIgJHt0cnlOdW1iZXJ9IGF0dGVtcHRzIHdpdGggbm9uLXJldHJ5YWJsZSBlcnJvcjogJyR7ZXJyb3JNZXNzYWdlfSdgLFxuICAgICAgcmVhc29uOiAnZXJyb3JOb3RSZXRyeWFibGUnLFxuICAgICAgZXJyb3JzOiBuZXdFcnJvcnMsXG4gICAgfSk7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBJbnZhbGlkQXJndW1lbnRFcnJvciB9IGZyb20gJy4uL2Vycm9yL2ludmFsaWQtYXJndW1lbnQtZXJyb3InO1xuaW1wb3J0IHtcbiAgUmV0cnlGdW5jdGlvbixcbiAgcmV0cnlXaXRoRXhwb25lbnRpYWxCYWNrb2ZmUmVzcGVjdGluZ1JldHJ5SGVhZGVycyxcbn0gZnJvbSAnLi4vdXRpbC9yZXRyeS13aXRoLWV4cG9uZW50aWFsLWJhY2tvZmYnO1xuXG4vKipcbiAqIFZhbGlkYXRlIGFuZCBwcmVwYXJlIHJldHJpZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcmVwYXJlUmV0cmllcyh7XG4gIG1heFJldHJpZXMsXG4gIGFib3J0U2lnbmFsLFxufToge1xuICBtYXhSZXRyaWVzOiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gIGFib3J0U2lnbmFsOiBBYm9ydFNpZ25hbCB8IHVuZGVmaW5lZDtcbn0pOiB7XG4gIG1heFJldHJpZXM6IG51bWJlcjtcbiAgcmV0cnk6IFJldHJ5RnVuY3Rpb247XG59IHtcbiAgaWYgKG1heFJldHJpZXMgIT0gbnVsbCkge1xuICAgIGlmICghTnVtYmVyLmlzSW50ZWdlcihtYXhSZXRyaWVzKSkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEVycm9yKHtcbiAgICAgICAgcGFyYW1ldGVyOiAnbWF4UmV0cmllcycsXG4gICAgICAgIHZhbHVlOiBtYXhSZXRyaWVzLFxuICAgICAgICBtZXNzYWdlOiAnbWF4UmV0cmllcyBtdXN0IGJlIGFuIGludGVnZXInLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKG1heFJldHJpZXMgPCAwKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3Ioe1xuICAgICAgICBwYXJhbWV0ZXI6ICdtYXhSZXRyaWVzJyxcbiAgICAgICAgdmFsdWU6IG1heFJldHJpZXMsXG4gICAgICAgIG1lc3NhZ2U6ICdtYXhSZXRyaWVzIG11c3QgYmUgPj0gMCcsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBtYXhSZXRyaWVzUmVzdWx0ID0gbWF4UmV0cmllcyA/PyAyO1xuXG4gIHJldHVybiB7XG4gICAgbWF4UmV0cmllczogbWF4UmV0cmllc1Jlc3VsdCxcbiAgICByZXRyeTogcmV0cnlXaXRoRXhwb25lbnRpYWxCYWNrb2ZmUmVzcGVjdGluZ1JldHJ5SGVhZGVycyh7XG4gICAgICBtYXhSZXRyaWVzOiBtYXhSZXRyaWVzUmVzdWx0LFxuICAgICAgYWJvcnRTaWduYWwsXG4gICAgfSksXG4gIH07XG59XG4iLCAiaW1wb3J0IHsgTGFuZ3VhZ2VNb2RlbFYyQ29udGVudCwgTGFuZ3VhZ2VNb2RlbFYyVGV4dCB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdFRleHRDb250ZW50KFxuICBjb250ZW50OiBMYW5ndWFnZU1vZGVsVjJDb250ZW50W10sXG4pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCBwYXJ0cyA9IGNvbnRlbnQuZmlsdGVyKFxuICAgIChjb250ZW50KTogY29udGVudCBpcyBMYW5ndWFnZU1vZGVsVjJUZXh0ID0+IGNvbnRlbnQudHlwZSA9PT0gJ3RleHQnLFxuICApO1xuXG4gIGlmIChwYXJ0cy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgcmV0dXJuIHBhcnRzLm1hcChjb250ZW50ID0+IGNvbnRlbnQudGV4dCkuam9pbignJyk7XG59XG4iLCAiaW1wb3J0IHtcbiAgY29udmVydEJhc2U2NFRvVWludDhBcnJheSxcbiAgY29udmVydFVpbnQ4QXJyYXlUb0Jhc2U2NCxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5cbi8qKlxuICogQSBnZW5lcmF0ZWQgZmlsZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBHZW5lcmF0ZWRGaWxlIHtcbiAgLyoqXG5GaWxlIGFzIGEgYmFzZTY0IGVuY29kZWQgc3RyaW5nLlxuICAgICAqL1xuICByZWFkb25seSBiYXNlNjQ6IHN0cmluZztcblxuICAvKipcbkZpbGUgYXMgYSBVaW50OEFycmF5LlxuICAgICAqL1xuICByZWFkb25seSB1aW50OEFycmF5OiBVaW50OEFycmF5O1xuXG4gIC8qKlxuVGhlIElBTkEgbWVkaWEgdHlwZSBvZiB0aGUgZmlsZS5cblxuQHNlZSBodHRwczovL3d3dy5pYW5hLm9yZy9hc3NpZ25tZW50cy9tZWRpYS10eXBlcy9tZWRpYS10eXBlcy54aHRtbFxuICAgKi9cbiAgcmVhZG9ubHkgbWVkaWFUeXBlOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBEZWZhdWx0R2VuZXJhdGVkRmlsZSBpbXBsZW1lbnRzIEdlbmVyYXRlZEZpbGUge1xuICBwcml2YXRlIGJhc2U2NERhdGE6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSB1aW50OEFycmF5RGF0YTogVWludDhBcnJheSB8IHVuZGVmaW5lZDtcblxuICByZWFkb25seSBtZWRpYVR5cGU6IHN0cmluZztcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgZGF0YSxcbiAgICBtZWRpYVR5cGUsXG4gIH06IHtcbiAgICBkYXRhOiBzdHJpbmcgfCBVaW50OEFycmF5O1xuICAgIG1lZGlhVHlwZTogc3RyaW5nO1xuICB9KSB7XG4gICAgY29uc3QgaXNVaW50OEFycmF5ID0gZGF0YSBpbnN0YW5jZW9mIFVpbnQ4QXJyYXk7XG4gICAgdGhpcy5iYXNlNjREYXRhID0gaXNVaW50OEFycmF5ID8gdW5kZWZpbmVkIDogZGF0YTtcbiAgICB0aGlzLnVpbnQ4QXJyYXlEYXRhID0gaXNVaW50OEFycmF5ID8gZGF0YSA6IHVuZGVmaW5lZDtcbiAgICB0aGlzLm1lZGlhVHlwZSA9IG1lZGlhVHlwZTtcbiAgfVxuXG4gIC8vIGxhenkgY29udmVyc2lvbiB3aXRoIGNhY2hpbmcgdG8gYXZvaWQgdW5uZWNlc3NhcnkgY29udmVyc2lvbiBvdmVyaGVhZDpcbiAgZ2V0IGJhc2U2NCgpIHtcbiAgICBpZiAodGhpcy5iYXNlNjREYXRhID09IG51bGwpIHtcbiAgICAgIHRoaXMuYmFzZTY0RGF0YSA9IGNvbnZlcnRVaW50OEFycmF5VG9CYXNlNjQodGhpcy51aW50OEFycmF5RGF0YSEpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5iYXNlNjREYXRhO1xuICB9XG5cbiAgLy8gbGF6eSBjb252ZXJzaW9uIHdpdGggY2FjaGluZyB0byBhdm9pZCB1bm5lY2Vzc2FyeSBjb252ZXJzaW9uIG92ZXJoZWFkOlxuICBnZXQgdWludDhBcnJheSgpIHtcbiAgICBpZiAodGhpcy51aW50OEFycmF5RGF0YSA9PSBudWxsKSB7XG4gICAgICB0aGlzLnVpbnQ4QXJyYXlEYXRhID0gY29udmVydEJhc2U2NFRvVWludDhBcnJheSh0aGlzLmJhc2U2NERhdGEhKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudWludDhBcnJheURhdGE7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIERlZmF1bHRHZW5lcmF0ZWRGaWxlV2l0aFR5cGUgZXh0ZW5kcyBEZWZhdWx0R2VuZXJhdGVkRmlsZSB7XG4gIHJlYWRvbmx5IHR5cGUgPSAnZmlsZSc7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczogeyBkYXRhOiBzdHJpbmcgfCBVaW50OEFycmF5OyBtZWRpYVR5cGU6IHN0cmluZyB9KSB7XG4gICAgc3VwZXIob3B0aW9ucyk7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBMYW5ndWFnZU1vZGVsVjJUb29sQ2FsbCB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHtcbiAgYXNTY2hlbWEsXG4gIE1vZGVsTWVzc2FnZSxcbiAgc2FmZVBhcnNlSlNPTixcbiAgc2FmZVZhbGlkYXRlVHlwZXMsXG59IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXItdXRpbHMnO1xuaW1wb3J0IHsgSW52YWxpZFRvb2xJbnB1dEVycm9yIH0gZnJvbSAnLi4vZXJyb3IvaW52YWxpZC10b29sLWlucHV0LWVycm9yJztcbmltcG9ydCB7IE5vU3VjaFRvb2xFcnJvciB9IGZyb20gJy4uL2Vycm9yL25vLXN1Y2gtdG9vbC1lcnJvcic7XG5pbXBvcnQgeyBUb29sQ2FsbFJlcGFpckVycm9yIH0gZnJvbSAnLi4vZXJyb3IvdG9vbC1jYWxsLXJlcGFpci1lcnJvcic7XG5pbXBvcnQgeyBUeXBlZFRvb2xDYWxsIH0gZnJvbSAnLi90b29sLWNhbGwnO1xuaW1wb3J0IHsgVG9vbENhbGxSZXBhaXJGdW5jdGlvbiB9IGZyb20gJy4vdG9vbC1jYWxsLXJlcGFpci1mdW5jdGlvbic7XG5pbXBvcnQgeyBUb29sU2V0IH0gZnJvbSAnLi90b29sLXNldCc7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwYXJzZVRvb2xDYWxsPFRPT0xTIGV4dGVuZHMgVG9vbFNldD4oe1xuICB0b29sQ2FsbCxcbiAgdG9vbHMsXG4gIHJlcGFpclRvb2xDYWxsLFxuICBzeXN0ZW0sXG4gIG1lc3NhZ2VzLFxufToge1xuICB0b29sQ2FsbDogTGFuZ3VhZ2VNb2RlbFYyVG9vbENhbGw7XG4gIHRvb2xzOiBUT09MUyB8IHVuZGVmaW5lZDtcbiAgcmVwYWlyVG9vbENhbGw6IFRvb2xDYWxsUmVwYWlyRnVuY3Rpb248VE9PTFM+IHwgdW5kZWZpbmVkO1xuICBzeXN0ZW06IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgbWVzc2FnZXM6IE1vZGVsTWVzc2FnZVtdO1xufSk6IFByb21pc2U8VHlwZWRUb29sQ2FsbDxUT09MUz4+IHtcbiAgdHJ5IHtcbiAgICBpZiAodG9vbHMgPT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IE5vU3VjaFRvb2xFcnJvcih7IHRvb2xOYW1lOiB0b29sQ2FsbC50b29sTmFtZSB9KTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IGRvUGFyc2VUb29sQ2FsbCh7IHRvb2xDYWxsLCB0b29scyB9KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKFxuICAgICAgICByZXBhaXJUb29sQ2FsbCA9PSBudWxsIHx8XG4gICAgICAgICEoXG4gICAgICAgICAgTm9TdWNoVG9vbEVycm9yLmlzSW5zdGFuY2UoZXJyb3IpIHx8XG4gICAgICAgICAgSW52YWxpZFRvb2xJbnB1dEVycm9yLmlzSW5zdGFuY2UoZXJyb3IpXG4gICAgICAgIClcbiAgICAgICkge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cblxuICAgICAgbGV0IHJlcGFpcmVkVG9vbENhbGw6IExhbmd1YWdlTW9kZWxWMlRvb2xDYWxsIHwgbnVsbCA9IG51bGw7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJlcGFpcmVkVG9vbENhbGwgPSBhd2FpdCByZXBhaXJUb29sQ2FsbCh7XG4gICAgICAgICAgdG9vbENhbGwsXG4gICAgICAgICAgdG9vbHMsXG4gICAgICAgICAgaW5wdXRTY2hlbWE6ICh7IHRvb2xOYW1lIH0pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgaW5wdXRTY2hlbWEgfSA9IHRvb2xzW3Rvb2xOYW1lXTtcbiAgICAgICAgICAgIHJldHVybiBhc1NjaGVtYShpbnB1dFNjaGVtYSkuanNvblNjaGVtYTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIHN5c3RlbSxcbiAgICAgICAgICBtZXNzYWdlcyxcbiAgICAgICAgICBlcnJvcixcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChyZXBhaXJFcnJvcikge1xuICAgICAgICB0aHJvdyBuZXcgVG9vbENhbGxSZXBhaXJFcnJvcih7XG4gICAgICAgICAgY2F1c2U6IHJlcGFpckVycm9yLFxuICAgICAgICAgIG9yaWdpbmFsRXJyb3I6IGVycm9yLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgLy8gbm8gcmVwYWlyZWQgdG9vbCBjYWxsIHJldHVybmVkXG4gICAgICBpZiAocmVwYWlyZWRUb29sQ2FsbCA9PSBudWxsKSB7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gYXdhaXQgZG9QYXJzZVRvb2xDYWxsKHsgdG9vbENhbGw6IHJlcGFpcmVkVG9vbENhbGwsIHRvb2xzIH0pO1xuICAgIH1cbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAvLyB1c2UgcGFyc2VkIGlucHV0IHdoZW4gcG9zc2libGVcbiAgICBjb25zdCBwYXJzZWRJbnB1dCA9IGF3YWl0IHNhZmVQYXJzZUpTT04oeyB0ZXh0OiB0b29sQ2FsbC5pbnB1dCB9KTtcbiAgICBjb25zdCBpbnB1dCA9IHBhcnNlZElucHV0LnN1Y2Nlc3MgPyBwYXJzZWRJbnB1dC52YWx1ZSA6IHRvb2xDYWxsLmlucHV0O1xuXG4gICAgLy8gVE9ETyBBSSBTREsgNjogc3BlY2lhbCBpbnZhbGlkIHRvb2wgY2FsbCBwYXJ0c1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiAndG9vbC1jYWxsJyxcbiAgICAgIHRvb2xDYWxsSWQ6IHRvb2xDYWxsLnRvb2xDYWxsSWQsXG4gICAgICB0b29sTmFtZTogdG9vbENhbGwudG9vbE5hbWUsXG4gICAgICBpbnB1dCxcbiAgICAgIGR5bmFtaWM6IHRydWUsXG4gICAgICBpbnZhbGlkOiB0cnVlLFxuICAgICAgZXJyb3IsXG4gICAgfTtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBkb1BhcnNlVG9vbENhbGw8VE9PTFMgZXh0ZW5kcyBUb29sU2V0Pih7XG4gIHRvb2xDYWxsLFxuICB0b29scyxcbn06IHtcbiAgdG9vbENhbGw6IExhbmd1YWdlTW9kZWxWMlRvb2xDYWxsO1xuICB0b29sczogVE9PTFM7XG59KTogUHJvbWlzZTxUeXBlZFRvb2xDYWxsPFRPT0xTPj4ge1xuICBjb25zdCB0b29sTmFtZSA9IHRvb2xDYWxsLnRvb2xOYW1lIGFzIGtleW9mIFRPT0xTICYgc3RyaW5nO1xuXG4gIGNvbnN0IHRvb2wgPSB0b29sc1t0b29sTmFtZV07XG5cbiAgaWYgKHRvb2wgPT0gbnVsbCkge1xuICAgIHRocm93IG5ldyBOb1N1Y2hUb29sRXJyb3Ioe1xuICAgICAgdG9vbE5hbWU6IHRvb2xDYWxsLnRvb2xOYW1lLFxuICAgICAgYXZhaWxhYmxlVG9vbHM6IE9iamVjdC5rZXlzKHRvb2xzKSxcbiAgICB9KTtcbiAgfVxuXG4gIGNvbnN0IHNjaGVtYSA9IGFzU2NoZW1hKHRvb2wuaW5wdXRTY2hlbWEpO1xuXG4gIC8vIHdoZW4gdGhlIHRvb2wgY2FsbCBoYXMgbm8gYXJndW1lbnRzLCB3ZSB0cnkgcGFzc2luZyBhbiBlbXB0eSBvYmplY3QgdG8gdGhlIHNjaGVtYVxuICAvLyAobWFueSBMTE1zIGdlbmVyYXRlIGVtcHR5IHN0cmluZ3MgZm9yIHRvb2wgY2FsbHMgd2l0aCBubyBhcmd1bWVudHMpXG4gIGNvbnN0IHBhcnNlUmVzdWx0ID1cbiAgICB0b29sQ2FsbC5pbnB1dC50cmltKCkgPT09ICcnXG4gICAgICA/IGF3YWl0IHNhZmVWYWxpZGF0ZVR5cGVzKHsgdmFsdWU6IHt9LCBzY2hlbWEgfSlcbiAgICAgIDogYXdhaXQgc2FmZVBhcnNlSlNPTih7IHRleHQ6IHRvb2xDYWxsLmlucHV0LCBzY2hlbWEgfSk7XG5cbiAgaWYgKHBhcnNlUmVzdWx0LnN1Y2Nlc3MgPT09IGZhbHNlKSB7XG4gICAgdGhyb3cgbmV3IEludmFsaWRUb29sSW5wdXRFcnJvcih7XG4gICAgICB0b29sTmFtZSxcbiAgICAgIHRvb2xJbnB1dDogdG9vbENhbGwuaW5wdXQsXG4gICAgICBjYXVzZTogcGFyc2VSZXN1bHQuZXJyb3IsXG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gdG9vbC50eXBlID09PSAnZHluYW1pYydcbiAgICA/IHtcbiAgICAgICAgdHlwZTogJ3Rvb2wtY2FsbCcsXG4gICAgICAgIHRvb2xDYWxsSWQ6IHRvb2xDYWxsLnRvb2xDYWxsSWQsXG4gICAgICAgIHRvb2xOYW1lOiB0b29sQ2FsbC50b29sTmFtZSxcbiAgICAgICAgaW5wdXQ6IHBhcnNlUmVzdWx0LnZhbHVlLFxuICAgICAgICBwcm92aWRlckV4ZWN1dGVkOiB0b29sQ2FsbC5wcm92aWRlckV4ZWN1dGVkLFxuICAgICAgICBwcm92aWRlck1ldGFkYXRhOiB0b29sQ2FsbC5wcm92aWRlck1ldGFkYXRhLFxuICAgICAgICBkeW5hbWljOiB0cnVlLFxuICAgICAgfVxuICAgIDoge1xuICAgICAgICB0eXBlOiAndG9vbC1jYWxsJyxcbiAgICAgICAgdG9vbENhbGxJZDogdG9vbENhbGwudG9vbENhbGxJZCxcbiAgICAgICAgdG9vbE5hbWUsXG4gICAgICAgIGlucHV0OiBwYXJzZVJlc3VsdC52YWx1ZSxcbiAgICAgICAgcHJvdmlkZXJFeGVjdXRlZDogdG9vbENhbGwucHJvdmlkZXJFeGVjdXRlZCxcbiAgICAgICAgcHJvdmlkZXJNZXRhZGF0YTogdG9vbENhbGwucHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgIH07XG59XG4iLCAiaW1wb3J0IHsgUmVhc29uaW5nUGFydCB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXItdXRpbHMnO1xuaW1wb3J0IHtcbiAgQ2FsbFdhcm5pbmcsXG4gIEZpbmlzaFJlYXNvbixcbiAgTGFuZ3VhZ2VNb2RlbFJlcXVlc3RNZXRhZGF0YSxcbiAgTGFuZ3VhZ2VNb2RlbFJlc3BvbnNlTWV0YWRhdGEsXG4gIFByb3ZpZGVyTWV0YWRhdGEsXG59IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gJy4uL3R5cGVzL2xhbmd1YWdlLW1vZGVsJztcbmltcG9ydCB7IExhbmd1YWdlTW9kZWxVc2FnZSB9IGZyb20gJy4uL3R5cGVzL3VzYWdlJztcbmltcG9ydCB7IENvbnRlbnRQYXJ0IH0gZnJvbSAnLi9jb250ZW50LXBhcnQnO1xuaW1wb3J0IHsgR2VuZXJhdGVkRmlsZSB9IGZyb20gJy4vZ2VuZXJhdGVkLWZpbGUnO1xuaW1wb3J0IHsgUmVzcG9uc2VNZXNzYWdlIH0gZnJvbSAnLi9yZXNwb25zZS1tZXNzYWdlJztcbmltcG9ydCB7IER5bmFtaWNUb29sQ2FsbCwgU3RhdGljVG9vbENhbGwsIFR5cGVkVG9vbENhbGwgfSBmcm9tICcuL3Rvb2wtY2FsbCc7XG5pbXBvcnQge1xuICBEeW5hbWljVG9vbFJlc3VsdCxcbiAgU3RhdGljVG9vbFJlc3VsdCxcbiAgVHlwZWRUb29sUmVzdWx0LFxufSBmcm9tICcuL3Rvb2wtcmVzdWx0JztcbmltcG9ydCB7IFRvb2xTZXQgfSBmcm9tICcuL3Rvb2wtc2V0JztcblxuLyoqXG4gKiBUaGUgcmVzdWx0IG9mIGEgc2luZ2xlIHN0ZXAgaW4gdGhlIGdlbmVyYXRpb24gcHJvY2Vzcy5cbiAqL1xuZXhwb3J0IHR5cGUgU3RlcFJlc3VsdDxUT09MUyBleHRlbmRzIFRvb2xTZXQ+ID0ge1xuICAvKipcblRoZSBjb250ZW50IHRoYXQgd2FzIGdlbmVyYXRlZCBpbiB0aGUgbGFzdCBzdGVwLlxuICAgKi9cbiAgcmVhZG9ubHkgY29udGVudDogQXJyYXk8Q29udGVudFBhcnQ8VE9PTFM+PjtcblxuICAvKipcblRoZSBnZW5lcmF0ZWQgdGV4dC5cbiovXG4gIHJlYWRvbmx5IHRleHQ6IHN0cmluZztcblxuICAvKipcblRoZSByZWFzb25pbmcgdGhhdCB3YXMgZ2VuZXJhdGVkIGR1cmluZyB0aGUgZ2VuZXJhdGlvbi5cbiovXG4gIHJlYWRvbmx5IHJlYXNvbmluZzogQXJyYXk8UmVhc29uaW5nUGFydD47XG5cbiAgLyoqXG5UaGUgcmVhc29uaW5nIHRleHQgdGhhdCB3YXMgZ2VuZXJhdGVkIGR1cmluZyB0aGUgZ2VuZXJhdGlvbi5cbiovXG4gIHJlYWRvbmx5IHJlYXNvbmluZ1RleHQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAvKipcblRoZSBmaWxlcyB0aGF0IHdlcmUgZ2VuZXJhdGVkIGR1cmluZyB0aGUgZ2VuZXJhdGlvbi5cbiovXG4gIHJlYWRvbmx5IGZpbGVzOiBBcnJheTxHZW5lcmF0ZWRGaWxlPjtcblxuICAvKipcblRoZSBzb3VyY2VzIHRoYXQgd2VyZSB1c2VkIHRvIGdlbmVyYXRlIHRoZSB0ZXh0LlxuKi9cbiAgcmVhZG9ubHkgc291cmNlczogQXJyYXk8U291cmNlPjtcblxuICAvKipcblRoZSB0b29sIGNhbGxzIHRoYXQgd2VyZSBtYWRlIGR1cmluZyB0aGUgZ2VuZXJhdGlvbi5cbiovXG4gIHJlYWRvbmx5IHRvb2xDYWxsczogQXJyYXk8VHlwZWRUb29sQ2FsbDxUT09MUz4+O1xuXG4gIC8qKlxuVGhlIHN0YXRpYyB0b29sIGNhbGxzIHRoYXQgd2VyZSBtYWRlIGluIHRoZSBsYXN0IHN0ZXAuXG4qL1xuICByZWFkb25seSBzdGF0aWNUb29sQ2FsbHM6IEFycmF5PFN0YXRpY1Rvb2xDYWxsPFRPT0xTPj47XG5cbiAgLyoqXG5UaGUgZHluYW1pYyB0b29sIGNhbGxzIHRoYXQgd2VyZSBtYWRlIGluIHRoZSBsYXN0IHN0ZXAuXG4qL1xuICByZWFkb25seSBkeW5hbWljVG9vbENhbGxzOiBBcnJheTxEeW5hbWljVG9vbENhbGw+O1xuXG4gIC8qKlxuVGhlIHJlc3VsdHMgb2YgdGhlIHRvb2wgY2FsbHMuXG4qL1xuICByZWFkb25seSB0b29sUmVzdWx0czogQXJyYXk8VHlwZWRUb29sUmVzdWx0PFRPT0xTPj47XG5cbiAgLyoqXG5UaGUgc3RhdGljIHRvb2wgcmVzdWx0cyB0aGF0IHdlcmUgbWFkZSBpbiB0aGUgbGFzdCBzdGVwLlxuKi9cbiAgcmVhZG9ubHkgc3RhdGljVG9vbFJlc3VsdHM6IEFycmF5PFN0YXRpY1Rvb2xSZXN1bHQ8VE9PTFM+PjtcblxuICAvKipcblRoZSBkeW5hbWljIHRvb2wgcmVzdWx0cyB0aGF0IHdlcmUgbWFkZSBpbiB0aGUgbGFzdCBzdGVwLlxuKi9cbiAgcmVhZG9ubHkgZHluYW1pY1Rvb2xSZXN1bHRzOiBBcnJheTxEeW5hbWljVG9vbFJlc3VsdD47XG5cbiAgLyoqXG5UaGUgcmVhc29uIHdoeSB0aGUgZ2VuZXJhdGlvbiBmaW5pc2hlZC5cbiovXG4gIHJlYWRvbmx5IGZpbmlzaFJlYXNvbjogRmluaXNoUmVhc29uO1xuXG4gIC8qKlxuVGhlIHRva2VuIHVzYWdlIG9mIHRoZSBnZW5lcmF0ZWQgdGV4dC5cbiovXG4gIHJlYWRvbmx5IHVzYWdlOiBMYW5ndWFnZU1vZGVsVXNhZ2U7XG5cbiAgLyoqXG5XYXJuaW5ncyBmcm9tIHRoZSBtb2RlbCBwcm92aWRlciAoZS5nLiB1bnN1cHBvcnRlZCBzZXR0aW5ncykuXG4qL1xuICByZWFkb25seSB3YXJuaW5nczogQ2FsbFdhcm5pbmdbXSB8IHVuZGVmaW5lZDtcblxuICAvKipcbkFkZGl0aW9uYWwgcmVxdWVzdCBpbmZvcm1hdGlvbi5cbiAgICovXG4gIHJlYWRvbmx5IHJlcXVlc3Q6IExhbmd1YWdlTW9kZWxSZXF1ZXN0TWV0YWRhdGE7XG5cbiAgLyoqXG5BZGRpdGlvbmFsIHJlc3BvbnNlIGluZm9ybWF0aW9uLlxuKi9cbiAgcmVhZG9ubHkgcmVzcG9uc2U6IExhbmd1YWdlTW9kZWxSZXNwb25zZU1ldGFkYXRhICYge1xuICAgIC8qKlxuVGhlIHJlc3BvbnNlIG1lc3NhZ2VzIHRoYXQgd2VyZSBnZW5lcmF0ZWQgZHVyaW5nIHRoZSBjYWxsLlxuUmVzcG9uc2UgbWVzc2FnZXMgY2FuIGJlIGVpdGhlciBhc3Npc3RhbnQgbWVzc2FnZXMgb3IgdG9vbCBtZXNzYWdlcy5cblRoZXkgY29udGFpbiBhIGdlbmVyYXRlZCBpZC5cbiovXG4gICAgcmVhZG9ubHkgbWVzc2FnZXM6IEFycmF5PFJlc3BvbnNlTWVzc2FnZT47XG5cbiAgICAvKipcblJlc3BvbnNlIGJvZHkgKGF2YWlsYWJsZSBvbmx5IGZvciBwcm92aWRlcnMgdGhhdCB1c2UgSFRUUCByZXF1ZXN0cykuXG4gICAgICovXG4gICAgYm9keT86IHVua25vd247XG4gIH07XG5cbiAgLyoqXG5BZGRpdGlvbmFsIHByb3ZpZGVyLXNwZWNpZmljIG1ldGFkYXRhLiBUaGV5IGFyZSBwYXNzZWQgdGhyb3VnaFxuZnJvbSB0aGUgcHJvdmlkZXIgdG8gdGhlIEFJIFNESyBhbmQgZW5hYmxlIHByb3ZpZGVyLXNwZWNpZmljXG5yZXN1bHRzIHRoYXQgY2FuIGJlIGZ1bGx5IGVuY2Fwc3VsYXRlZCBpbiB0aGUgcHJvdmlkZXIuXG4gICAqL1xuICByZWFkb25seSBwcm92aWRlck1ldGFkYXRhOiBQcm92aWRlck1ldGFkYXRhIHwgdW5kZWZpbmVkO1xufTtcblxuZXhwb3J0IGNsYXNzIERlZmF1bHRTdGVwUmVzdWx0PFRPT0xTIGV4dGVuZHMgVG9vbFNldD5cbiAgaW1wbGVtZW50cyBTdGVwUmVzdWx0PFRPT0xTPlxue1xuICByZWFkb25seSBjb250ZW50OiBTdGVwUmVzdWx0PFRPT0xTPlsnY29udGVudCddO1xuICByZWFkb25seSBmaW5pc2hSZWFzb246IFN0ZXBSZXN1bHQ8VE9PTFM+WydmaW5pc2hSZWFzb24nXTtcbiAgcmVhZG9ubHkgdXNhZ2U6IFN0ZXBSZXN1bHQ8VE9PTFM+Wyd1c2FnZSddO1xuICByZWFkb25seSB3YXJuaW5nczogU3RlcFJlc3VsdDxUT09MUz5bJ3dhcm5pbmdzJ107XG4gIHJlYWRvbmx5IHJlcXVlc3Q6IFN0ZXBSZXN1bHQ8VE9PTFM+WydyZXF1ZXN0J107XG4gIHJlYWRvbmx5IHJlc3BvbnNlOiBTdGVwUmVzdWx0PFRPT0xTPlsncmVzcG9uc2UnXTtcbiAgcmVhZG9ubHkgcHJvdmlkZXJNZXRhZGF0YTogU3RlcFJlc3VsdDxUT09MUz5bJ3Byb3ZpZGVyTWV0YWRhdGEnXTtcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgY29udGVudCxcbiAgICBmaW5pc2hSZWFzb24sXG4gICAgdXNhZ2UsXG4gICAgd2FybmluZ3MsXG4gICAgcmVxdWVzdCxcbiAgICByZXNwb25zZSxcbiAgICBwcm92aWRlck1ldGFkYXRhLFxuICB9OiB7XG4gICAgY29udGVudDogU3RlcFJlc3VsdDxUT09MUz5bJ2NvbnRlbnQnXTtcbiAgICBmaW5pc2hSZWFzb246IFN0ZXBSZXN1bHQ8VE9PTFM+WydmaW5pc2hSZWFzb24nXTtcbiAgICB1c2FnZTogU3RlcFJlc3VsdDxUT09MUz5bJ3VzYWdlJ107XG4gICAgd2FybmluZ3M6IFN0ZXBSZXN1bHQ8VE9PTFM+Wyd3YXJuaW5ncyddO1xuICAgIHJlcXVlc3Q6IFN0ZXBSZXN1bHQ8VE9PTFM+WydyZXF1ZXN0J107XG4gICAgcmVzcG9uc2U6IFN0ZXBSZXN1bHQ8VE9PTFM+WydyZXNwb25zZSddO1xuICAgIHByb3ZpZGVyTWV0YWRhdGE6IFN0ZXBSZXN1bHQ8VE9PTFM+Wydwcm92aWRlck1ldGFkYXRhJ107XG4gIH0pIHtcbiAgICB0aGlzLmNvbnRlbnQgPSBjb250ZW50O1xuICAgIHRoaXMuZmluaXNoUmVhc29uID0gZmluaXNoUmVhc29uO1xuICAgIHRoaXMudXNhZ2UgPSB1c2FnZTtcbiAgICB0aGlzLndhcm5pbmdzID0gd2FybmluZ3M7XG4gICAgdGhpcy5yZXF1ZXN0ID0gcmVxdWVzdDtcbiAgICB0aGlzLnJlc3BvbnNlID0gcmVzcG9uc2U7XG4gICAgdGhpcy5wcm92aWRlck1ldGFkYXRhID0gcHJvdmlkZXJNZXRhZGF0YTtcbiAgfVxuXG4gIGdldCB0ZXh0KCkge1xuICAgIHJldHVybiB0aGlzLmNvbnRlbnRcbiAgICAgIC5maWx0ZXIocGFydCA9PiBwYXJ0LnR5cGUgPT09ICd0ZXh0JylcbiAgICAgIC5tYXAocGFydCA9PiBwYXJ0LnRleHQpXG4gICAgICAuam9pbignJyk7XG4gIH1cblxuICBnZXQgcmVhc29uaW5nKCkge1xuICAgIHJldHVybiB0aGlzLmNvbnRlbnQuZmlsdGVyKHBhcnQgPT4gcGFydC50eXBlID09PSAncmVhc29uaW5nJyk7XG4gIH1cblxuICBnZXQgcmVhc29uaW5nVGV4dCgpIHtcbiAgICByZXR1cm4gdGhpcy5yZWFzb25pbmcubGVuZ3RoID09PSAwXG4gICAgICA/IHVuZGVmaW5lZFxuICAgICAgOiB0aGlzLnJlYXNvbmluZy5tYXAocGFydCA9PiBwYXJ0LnRleHQpLmpvaW4oJycpO1xuICB9XG5cbiAgZ2V0IGZpbGVzKCkge1xuICAgIHJldHVybiB0aGlzLmNvbnRlbnRcbiAgICAgIC5maWx0ZXIocGFydCA9PiBwYXJ0LnR5cGUgPT09ICdmaWxlJylcbiAgICAgIC5tYXAocGFydCA9PiBwYXJ0LmZpbGUpO1xuICB9XG5cbiAgZ2V0IHNvdXJjZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMuY29udGVudC5maWx0ZXIocGFydCA9PiBwYXJ0LnR5cGUgPT09ICdzb3VyY2UnKTtcbiAgfVxuXG4gIGdldCB0b29sQ2FsbHMoKSB7XG4gICAgcmV0dXJuIHRoaXMuY29udGVudC5maWx0ZXIocGFydCA9PiBwYXJ0LnR5cGUgPT09ICd0b29sLWNhbGwnKTtcbiAgfVxuXG4gIGdldCBzdGF0aWNUb29sQ2FsbHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG9vbENhbGxzLmZpbHRlcihcbiAgICAgICh0b29sQ2FsbCk6IHRvb2xDYWxsIGlzIFN0YXRpY1Rvb2xDYWxsPFRPT0xTPiA9PlxuICAgICAgICB0b29sQ2FsbC5keW5hbWljICE9PSB0cnVlLFxuICAgICk7XG4gIH1cblxuICBnZXQgZHluYW1pY1Rvb2xDYWxscygpIHtcbiAgICByZXR1cm4gdGhpcy50b29sQ2FsbHMuZmlsdGVyKFxuICAgICAgKHRvb2xDYWxsKTogdG9vbENhbGwgaXMgRHluYW1pY1Rvb2xDYWxsID0+IHRvb2xDYWxsLmR5bmFtaWMgPT09IHRydWUsXG4gICAgKTtcbiAgfVxuXG4gIGdldCB0b29sUmVzdWx0cygpIHtcbiAgICByZXR1cm4gdGhpcy5jb250ZW50LmZpbHRlcihwYXJ0ID0+IHBhcnQudHlwZSA9PT0gJ3Rvb2wtcmVzdWx0Jyk7XG4gIH1cblxuICBnZXQgc3RhdGljVG9vbFJlc3VsdHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG9vbFJlc3VsdHMuZmlsdGVyKFxuICAgICAgKHRvb2xSZXN1bHQpOiB0b29sUmVzdWx0IGlzIFN0YXRpY1Rvb2xSZXN1bHQ8VE9PTFM+ID0+XG4gICAgICAgIHRvb2xSZXN1bHQuZHluYW1pYyAhPT0gdHJ1ZSxcbiAgICApO1xuICB9XG5cbiAgZ2V0IGR5bmFtaWNUb29sUmVzdWx0cygpIHtcbiAgICByZXR1cm4gdGhpcy50b29sUmVzdWx0cy5maWx0ZXIoXG4gICAgICAodG9vbFJlc3VsdCk6IHRvb2xSZXN1bHQgaXMgRHluYW1pY1Rvb2xSZXN1bHQgPT5cbiAgICAgICAgdG9vbFJlc3VsdC5keW5hbWljID09PSB0cnVlLFxuICAgICk7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBTdGVwUmVzdWx0IH0gZnJvbSAnLi9zdGVwLXJlc3VsdCc7XG5pbXBvcnQgeyBUb29sU2V0IH0gZnJvbSAnLi90b29sLXNldCc7XG5cbmV4cG9ydCB0eXBlIFN0b3BDb25kaXRpb248VE9PTFMgZXh0ZW5kcyBUb29sU2V0PiA9IChvcHRpb25zOiB7XG4gIHN0ZXBzOiBBcnJheTxTdGVwUmVzdWx0PFRPT0xTPj47XG59KSA9PiBQcm9taXNlTGlrZTxib29sZWFuPiB8IGJvb2xlYW47XG5cbmV4cG9ydCBmdW5jdGlvbiBzdGVwQ291bnRJcyhzdGVwQ291bnQ6IG51bWJlcik6IFN0b3BDb25kaXRpb248YW55PiB7XG4gIHJldHVybiAoeyBzdGVwcyB9KSA9PiBzdGVwcy5sZW5ndGggPT09IHN0ZXBDb3VudDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhhc1Rvb2xDYWxsKHRvb2xOYW1lOiBzdHJpbmcpOiBTdG9wQ29uZGl0aW9uPGFueT4ge1xuICByZXR1cm4gKHsgc3RlcHMgfSkgPT5cbiAgICBzdGVwc1tzdGVwcy5sZW5ndGggLSAxXT8udG9vbENhbGxzPy5zb21lKFxuICAgICAgdG9vbENhbGwgPT4gdG9vbENhbGwudG9vbE5hbWUgPT09IHRvb2xOYW1lLFxuICAgICkgPz8gZmFsc2U7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBpc1N0b3BDb25kaXRpb25NZXQ8VE9PTFMgZXh0ZW5kcyBUb29sU2V0Pih7XG4gIHN0b3BDb25kaXRpb25zLFxuICBzdGVwcyxcbn06IHtcbiAgc3RvcENvbmRpdGlvbnM6IEFycmF5PFN0b3BDb25kaXRpb248VE9PTFM+PjtcbiAgc3RlcHM6IEFycmF5PFN0ZXBSZXN1bHQ8VE9PTFM+Pjtcbn0pOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgcmV0dXJuIChcbiAgICBhd2FpdCBQcm9taXNlLmFsbChzdG9wQ29uZGl0aW9ucy5tYXAoY29uZGl0aW9uID0+IGNvbmRpdGlvbih7IHN0ZXBzIH0pKSlcbiAgKS5zb21lKHJlc3VsdCA9PiByZXN1bHQpO1xufVxuIiwgImltcG9ydCB7XG4gIGdldEVycm9yTWVzc2FnZSxcbiAgSlNPTlZhbHVlLFxuICBMYW5ndWFnZU1vZGVsVjJUb29sUmVzdWx0T3V0cHV0LFxufSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcbmltcG9ydCB7IFRvb2wgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyLXV0aWxzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVRvb2xNb2RlbE91dHB1dCh7XG4gIG91dHB1dCxcbiAgdG9vbCxcbiAgZXJyb3JNb2RlLFxufToge1xuICBvdXRwdXQ6IHVua25vd247XG4gIHRvb2w6IFRvb2wgfCB1bmRlZmluZWQ7XG4gIGVycm9yTW9kZTogJ25vbmUnIHwgJ3RleHQnIHwgJ2pzb24nO1xufSk6IExhbmd1YWdlTW9kZWxWMlRvb2xSZXN1bHRPdXRwdXQge1xuICBpZiAoZXJyb3JNb2RlID09PSAndGV4dCcpIHtcbiAgICByZXR1cm4geyB0eXBlOiAnZXJyb3ItdGV4dCcsIHZhbHVlOiBnZXRFcnJvck1lc3NhZ2Uob3V0cHV0KSB9O1xuICB9IGVsc2UgaWYgKGVycm9yTW9kZSA9PT0gJ2pzb24nKSB7XG4gICAgcmV0dXJuIHsgdHlwZTogJ2Vycm9yLWpzb24nLCB2YWx1ZTogdG9KU09OVmFsdWUob3V0cHV0KSB9O1xuICB9XG5cbiAgaWYgKHRvb2w/LnRvTW9kZWxPdXRwdXQpIHtcbiAgICByZXR1cm4gdG9vbC50b01vZGVsT3V0cHV0KG91dHB1dCk7XG4gIH1cblxuICByZXR1cm4gdHlwZW9mIG91dHB1dCA9PT0gJ3N0cmluZydcbiAgICA/IHsgdHlwZTogJ3RleHQnLCB2YWx1ZTogb3V0cHV0IH1cbiAgICA6IHsgdHlwZTogJ2pzb24nLCB2YWx1ZTogdG9KU09OVmFsdWUob3V0cHV0KSB9O1xufVxuXG5mdW5jdGlvbiB0b0pTT05WYWx1ZSh2YWx1ZTogdW5rbm93bik6IEpTT05WYWx1ZSB7XG4gIHJldHVybiB2YWx1ZSA9PT0gdW5kZWZpbmVkID8gbnVsbCA6ICh2YWx1ZSBhcyBKU09OVmFsdWUpO1xufVxuIiwgImltcG9ydCB7XG4gIEFzc2lzdGFudENvbnRlbnQsXG4gIEFzc2lzdGFudE1vZGVsTWVzc2FnZSxcbiAgVG9vbENvbnRlbnQsXG4gIFRvb2xNb2RlbE1lc3NhZ2UsXG59IGZyb20gJy4uL3Byb21wdCc7XG5pbXBvcnQgeyBjcmVhdGVUb29sTW9kZWxPdXRwdXQgfSBmcm9tICcuLi9wcm9tcHQvY3JlYXRlLXRvb2wtbW9kZWwtb3V0cHV0JztcbmltcG9ydCB7IENvbnRlbnRQYXJ0IH0gZnJvbSAnLi9jb250ZW50LXBhcnQnO1xuaW1wb3J0IHsgVG9vbFNldCB9IGZyb20gJy4vdG9vbC1zZXQnO1xuXG4vKipcbkNvbnZlcnRzIHRoZSByZXN1bHQgb2YgYSBgZ2VuZXJhdGVUZXh0YCBvciBgc3RyZWFtVGV4dGAgY2FsbCB0byBhIGxpc3Qgb2YgcmVzcG9uc2UgbWVzc2FnZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b1Jlc3BvbnNlTWVzc2FnZXM8VE9PTFMgZXh0ZW5kcyBUb29sU2V0Pih7XG4gIGNvbnRlbnQ6IGlucHV0Q29udGVudCxcbiAgdG9vbHMsXG59OiB7XG4gIGNvbnRlbnQ6IEFycmF5PENvbnRlbnRQYXJ0PFRPT0xTPj47XG4gIHRvb2xzOiBUT09MUyB8IHVuZGVmaW5lZDtcbn0pOiBBcnJheTxBc3Npc3RhbnRNb2RlbE1lc3NhZ2UgfCBUb29sTW9kZWxNZXNzYWdlPiB7XG4gIGNvbnN0IHJlc3BvbnNlTWVzc2FnZXM6IEFycmF5PEFzc2lzdGFudE1vZGVsTWVzc2FnZSB8IFRvb2xNb2RlbE1lc3NhZ2U+ID0gW107XG5cbiAgY29uc3QgY29udGVudDogQXNzaXN0YW50Q29udGVudCA9IGlucHV0Q29udGVudFxuICAgIC5maWx0ZXIocGFydCA9PiBwYXJ0LnR5cGUgIT09ICdzb3VyY2UnKVxuICAgIC5maWx0ZXIoXG4gICAgICBwYXJ0ID0+XG4gICAgICAgIChwYXJ0LnR5cGUgIT09ICd0b29sLXJlc3VsdCcgfHwgcGFydC5wcm92aWRlckV4ZWN1dGVkKSAmJlxuICAgICAgICAocGFydC50eXBlICE9PSAndG9vbC1lcnJvcicgfHwgcGFydC5wcm92aWRlckV4ZWN1dGVkKSxcbiAgICApXG4gICAgLmZpbHRlcihwYXJ0ID0+IHBhcnQudHlwZSAhPT0gJ3RleHQnIHx8IHBhcnQudGV4dC5sZW5ndGggPiAwKVxuICAgIC5tYXAocGFydCA9PiB7XG4gICAgICBzd2l0Y2ggKHBhcnQudHlwZSkge1xuICAgICAgICBjYXNlICd0ZXh0JzpcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgICAgICAgdGV4dDogcGFydC50ZXh0LFxuICAgICAgICAgICAgcHJvdmlkZXJPcHRpb25zOiBwYXJ0LnByb3ZpZGVyTWV0YWRhdGEsXG4gICAgICAgICAgfTtcbiAgICAgICAgY2FzZSAncmVhc29uaW5nJzpcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogJ3JlYXNvbmluZycsXG4gICAgICAgICAgICB0ZXh0OiBwYXJ0LnRleHQsXG4gICAgICAgICAgICBwcm92aWRlck9wdGlvbnM6IHBhcnQucHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgICB9O1xuICAgICAgICBjYXNlICdmaWxlJzpcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogJ2ZpbGUnLFxuICAgICAgICAgICAgZGF0YTogcGFydC5maWxlLmJhc2U2NCxcbiAgICAgICAgICAgIG1lZGlhVHlwZTogcGFydC5maWxlLm1lZGlhVHlwZSxcbiAgICAgICAgICAgIHByb3ZpZGVyT3B0aW9uczogcGFydC5wcm92aWRlck1ldGFkYXRhLFxuICAgICAgICAgIH07XG4gICAgICAgIGNhc2UgJ3Rvb2wtY2FsbCc6XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6ICd0b29sLWNhbGwnLFxuICAgICAgICAgICAgdG9vbENhbGxJZDogcGFydC50b29sQ2FsbElkLFxuICAgICAgICAgICAgdG9vbE5hbWU6IHBhcnQudG9vbE5hbWUsXG4gICAgICAgICAgICBpbnB1dDogcGFydC5pbnB1dCxcbiAgICAgICAgICAgIHByb3ZpZGVyRXhlY3V0ZWQ6IHBhcnQucHJvdmlkZXJFeGVjdXRlZCxcbiAgICAgICAgICAgIHByb3ZpZGVyT3B0aW9uczogcGFydC5wcm92aWRlck1ldGFkYXRhLFxuICAgICAgICAgIH07XG4gICAgICAgIGNhc2UgJ3Rvb2wtcmVzdWx0JzpcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogJ3Rvb2wtcmVzdWx0JyxcbiAgICAgICAgICAgIHRvb2xDYWxsSWQ6IHBhcnQudG9vbENhbGxJZCxcbiAgICAgICAgICAgIHRvb2xOYW1lOiBwYXJ0LnRvb2xOYW1lLFxuICAgICAgICAgICAgb3V0cHV0OiBjcmVhdGVUb29sTW9kZWxPdXRwdXQoe1xuICAgICAgICAgICAgICB0b29sOiB0b29scz8uW3BhcnQudG9vbE5hbWVdLFxuICAgICAgICAgICAgICBvdXRwdXQ6IHBhcnQub3V0cHV0LFxuICAgICAgICAgICAgICBlcnJvck1vZGU6ICdub25lJyxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgcHJvdmlkZXJFeGVjdXRlZDogdHJ1ZSxcbiAgICAgICAgICAgIHByb3ZpZGVyT3B0aW9uczogcGFydC5wcm92aWRlck1ldGFkYXRhLFxuICAgICAgICAgIH07XG4gICAgICAgIGNhc2UgJ3Rvb2wtZXJyb3InOlxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiAndG9vbC1yZXN1bHQnLFxuICAgICAgICAgICAgdG9vbENhbGxJZDogcGFydC50b29sQ2FsbElkLFxuICAgICAgICAgICAgdG9vbE5hbWU6IHBhcnQudG9vbE5hbWUsXG4gICAgICAgICAgICBvdXRwdXQ6IGNyZWF0ZVRvb2xNb2RlbE91dHB1dCh7XG4gICAgICAgICAgICAgIHRvb2w6IHRvb2xzPy5bcGFydC50b29sTmFtZV0sXG4gICAgICAgICAgICAgIG91dHB1dDogcGFydC5lcnJvcixcbiAgICAgICAgICAgICAgZXJyb3JNb2RlOiAnanNvbicsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIHByb3ZpZGVyT3B0aW9uczogcGFydC5wcm92aWRlck1ldGFkYXRhLFxuICAgICAgICAgIH07XG4gICAgICB9XG4gICAgfSk7XG5cbiAgaWYgKGNvbnRlbnQubGVuZ3RoID4gMCkge1xuICAgIHJlc3BvbnNlTWVzc2FnZXMucHVzaCh7XG4gICAgICByb2xlOiAnYXNzaXN0YW50JyxcbiAgICAgIGNvbnRlbnQsXG4gICAgfSk7XG4gIH1cblxuICBjb25zdCB0b29sUmVzdWx0Q29udGVudDogVG9vbENvbnRlbnQgPSBpbnB1dENvbnRlbnRcbiAgICAuZmlsdGVyKHBhcnQgPT4gcGFydC50eXBlID09PSAndG9vbC1yZXN1bHQnIHx8IHBhcnQudHlwZSA9PT0gJ3Rvb2wtZXJyb3InKVxuICAgIC5maWx0ZXIocGFydCA9PiAhcGFydC5wcm92aWRlckV4ZWN1dGVkKVxuICAgIC5tYXAodG9vbFJlc3VsdCA9PiAoe1xuICAgICAgdHlwZTogJ3Rvb2wtcmVzdWx0JyxcbiAgICAgIHRvb2xDYWxsSWQ6IHRvb2xSZXN1bHQudG9vbENhbGxJZCxcbiAgICAgIHRvb2xOYW1lOiB0b29sUmVzdWx0LnRvb2xOYW1lLFxuICAgICAgb3V0cHV0OiBjcmVhdGVUb29sTW9kZWxPdXRwdXQoe1xuICAgICAgICB0b29sOiB0b29scz8uW3Rvb2xSZXN1bHQudG9vbE5hbWVdLFxuICAgICAgICBvdXRwdXQ6XG4gICAgICAgICAgdG9vbFJlc3VsdC50eXBlID09PSAndG9vbC1yZXN1bHQnXG4gICAgICAgICAgICA/IHRvb2xSZXN1bHQub3V0cHV0XG4gICAgICAgICAgICA6IHRvb2xSZXN1bHQuZXJyb3IsXG4gICAgICAgIGVycm9yTW9kZTogdG9vbFJlc3VsdC50eXBlID09PSAndG9vbC1lcnJvcicgPyAndGV4dCcgOiAnbm9uZScsXG4gICAgICB9KSxcbiAgICB9KSk7XG5cbiAgaWYgKHRvb2xSZXN1bHRDb250ZW50Lmxlbmd0aCA+IDApIHtcbiAgICByZXNwb25zZU1lc3NhZ2VzLnB1c2goe1xuICAgICAgcm9sZTogJ3Rvb2wnLFxuICAgICAgY29udGVudDogdG9vbFJlc3VsdENvbnRlbnQsXG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gcmVzcG9uc2VNZXNzYWdlcztcbn1cbiIsICJpbXBvcnQge1xuICBnZXRFcnJvck1lc3NhZ2UsXG4gIExhbmd1YWdlTW9kZWxWMixcbiAgTGFuZ3VhZ2VNb2RlbFYyQ2FsbFdhcm5pbmcsXG59IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHtcbiAgY3JlYXRlSWRHZW5lcmF0b3IsXG4gIElkR2VuZXJhdG9yLFxuICBpc0Fib3J0RXJyb3IsXG4gIFByb3ZpZGVyT3B0aW9ucyxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyBTcGFuIH0gZnJvbSAnQG9wZW50ZWxlbWV0cnkvYXBpJztcbmltcG9ydCB7IFNlcnZlclJlc3BvbnNlIH0gZnJvbSAnbm9kZTpodHRwJztcbmltcG9ydCB7IE5vT3V0cHV0R2VuZXJhdGVkRXJyb3IgfSBmcm9tICcuLi9lcnJvcic7XG5pbXBvcnQgeyBOb091dHB1dFNwZWNpZmllZEVycm9yIH0gZnJvbSAnLi4vZXJyb3Ivbm8tb3V0cHV0LXNwZWNpZmllZC1lcnJvcic7XG5pbXBvcnQgeyBsb2dXYXJuaW5ncyB9IGZyb20gJy4uL2xvZ2dlci9sb2ctd2FybmluZ3MnO1xuaW1wb3J0IHsgcmVzb2x2ZUxhbmd1YWdlTW9kZWwgfSBmcm9tICcuLi9tb2RlbC9yZXNvbHZlLW1vZGVsJztcbmltcG9ydCB7IENhbGxTZXR0aW5ncyB9IGZyb20gJy4uL3Byb21wdC9jYWxsLXNldHRpbmdzJztcbmltcG9ydCB7IGNvbnZlcnRUb0xhbmd1YWdlTW9kZWxQcm9tcHQgfSBmcm9tICcuLi9wcm9tcHQvY29udmVydC10by1sYW5ndWFnZS1tb2RlbC1wcm9tcHQnO1xuaW1wb3J0IHsgcHJlcGFyZUNhbGxTZXR0aW5ncyB9IGZyb20gJy4uL3Byb21wdC9wcmVwYXJlLWNhbGwtc2V0dGluZ3MnO1xuaW1wb3J0IHsgcHJlcGFyZVRvb2xzQW5kVG9vbENob2ljZSB9IGZyb20gJy4uL3Byb21wdC9wcmVwYXJlLXRvb2xzLWFuZC10b29sLWNob2ljZSc7XG5pbXBvcnQgeyBQcm9tcHQgfSBmcm9tICcuLi9wcm9tcHQvcHJvbXB0JztcbmltcG9ydCB7IHN0YW5kYXJkaXplUHJvbXB0IH0gZnJvbSAnLi4vcHJvbXB0L3N0YW5kYXJkaXplLXByb21wdCc7XG5pbXBvcnQgeyB3cmFwR2F0ZXdheUVycm9yIH0gZnJvbSAnLi4vcHJvbXB0L3dyYXAtZ2F0ZXdheS1lcnJvcic7XG5pbXBvcnQgeyBhc3NlbWJsZU9wZXJhdGlvbk5hbWUgfSBmcm9tICcuLi90ZWxlbWV0cnkvYXNzZW1ibGUtb3BlcmF0aW9uLW5hbWUnO1xuaW1wb3J0IHsgZ2V0QmFzZVRlbGVtZXRyeUF0dHJpYnV0ZXMgfSBmcm9tICcuLi90ZWxlbWV0cnkvZ2V0LWJhc2UtdGVsZW1ldHJ5LWF0dHJpYnV0ZXMnO1xuaW1wb3J0IHsgZ2V0VHJhY2VyIH0gZnJvbSAnLi4vdGVsZW1ldHJ5L2dldC10cmFjZXInO1xuaW1wb3J0IHsgcmVjb3JkU3BhbiB9IGZyb20gJy4uL3RlbGVtZXRyeS9yZWNvcmQtc3Bhbic7XG5pbXBvcnQgeyBzZWxlY3RUZWxlbWV0cnlBdHRyaWJ1dGVzIH0gZnJvbSAnLi4vdGVsZW1ldHJ5L3NlbGVjdC10ZWxlbWV0cnktYXR0cmlidXRlcyc7XG5pbXBvcnQgeyBzdHJpbmdpZnlGb3JUZWxlbWV0cnkgfSBmcm9tICcuLi90ZWxlbWV0cnkvc3RyaW5naWZ5LWZvci10ZWxlbWV0cnknO1xuaW1wb3J0IHsgVGVsZW1ldHJ5U2V0dGluZ3MgfSBmcm9tICcuLi90ZWxlbWV0cnkvdGVsZW1ldHJ5LXNldHRpbmdzJztcbmltcG9ydCB7IGNyZWF0ZVRleHRTdHJlYW1SZXNwb25zZSB9IGZyb20gJy4uL3RleHQtc3RyZWFtL2NyZWF0ZS10ZXh0LXN0cmVhbS1yZXNwb25zZSc7XG5pbXBvcnQgeyBwaXBlVGV4dFN0cmVhbVRvUmVzcG9uc2UgfSBmcm9tICcuLi90ZXh0LXN0cmVhbS9waXBlLXRleHQtc3RyZWFtLXRvLXJlc3BvbnNlJztcbmltcG9ydCB7IExhbmd1YWdlTW9kZWxSZXF1ZXN0TWV0YWRhdGEgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQge1xuICBDYWxsV2FybmluZyxcbiAgRmluaXNoUmVhc29uLFxuICBMYW5ndWFnZU1vZGVsLFxuICBUb29sQ2hvaWNlLFxufSBmcm9tICcuLi90eXBlcy9sYW5ndWFnZS1tb2RlbCc7XG5pbXBvcnQgeyBQcm92aWRlck1ldGFkYXRhIH0gZnJvbSAnLi4vdHlwZXMvcHJvdmlkZXItbWV0YWRhdGEnO1xuaW1wb3J0IHsgYWRkTGFuZ3VhZ2VNb2RlbFVzYWdlLCBMYW5ndWFnZU1vZGVsVXNhZ2UgfSBmcm9tICcuLi90eXBlcy91c2FnZSc7XG5pbXBvcnQgeyBVSU1lc3NhZ2UgfSBmcm9tICcuLi91aSc7XG5pbXBvcnQgeyBjcmVhdGVVSU1lc3NhZ2VTdHJlYW1SZXNwb25zZSB9IGZyb20gJy4uL3VpLW1lc3NhZ2Utc3RyZWFtL2NyZWF0ZS11aS1tZXNzYWdlLXN0cmVhbS1yZXNwb25zZSc7XG5pbXBvcnQgeyBnZXRSZXNwb25zZVVJTWVzc2FnZUlkIH0gZnJvbSAnLi4vdWktbWVzc2FnZS1zdHJlYW0vZ2V0LXJlc3BvbnNlLXVpLW1lc3NhZ2UtaWQnO1xuaW1wb3J0IHsgaGFuZGxlVUlNZXNzYWdlU3RyZWFtRmluaXNoIH0gZnJvbSAnLi4vdWktbWVzc2FnZS1zdHJlYW0vaGFuZGxlLXVpLW1lc3NhZ2Utc3RyZWFtLWZpbmlzaCc7XG5pbXBvcnQgeyBwaXBlVUlNZXNzYWdlU3RyZWFtVG9SZXNwb25zZSB9IGZyb20gJy4uL3VpLW1lc3NhZ2Utc3RyZWFtL3BpcGUtdWktbWVzc2FnZS1zdHJlYW0tdG8tcmVzcG9uc2UnO1xuaW1wb3J0IHtcbiAgSW5mZXJVSU1lc3NhZ2VDaHVuayxcbiAgVUlNZXNzYWdlQ2h1bmssXG59IGZyb20gJy4uL3VpLW1lc3NhZ2Utc3RyZWFtL3VpLW1lc3NhZ2UtY2h1bmtzJztcbmltcG9ydCB7IFVJTWVzc2FnZVN0cmVhbVJlc3BvbnNlSW5pdCB9IGZyb20gJy4uL3VpLW1lc3NhZ2Utc3RyZWFtL3VpLW1lc3NhZ2Utc3RyZWFtLXJlc3BvbnNlLWluaXQnO1xuaW1wb3J0IHsgSW5mZXJVSU1lc3NhZ2VEYXRhLCBJbmZlclVJTWVzc2FnZU1ldGFkYXRhIH0gZnJvbSAnLi4vdWkvdWktbWVzc2FnZXMnO1xuaW1wb3J0IHsgYXNBcnJheSB9IGZyb20gJy4uL3V0aWwvYXMtYXJyYXknO1xuaW1wb3J0IHtcbiAgQXN5bmNJdGVyYWJsZVN0cmVhbSxcbiAgY3JlYXRlQXN5bmNJdGVyYWJsZVN0cmVhbSxcbn0gZnJvbSAnLi4vdXRpbC9hc3luYy1pdGVyYWJsZS1zdHJlYW0nO1xuaW1wb3J0IHsgY29uc3VtZVN0cmVhbSB9IGZyb20gJy4uL3V0aWwvY29uc3VtZS1zdHJlYW0nO1xuaW1wb3J0IHsgY3JlYXRlU3RpdGNoYWJsZVN0cmVhbSB9IGZyb20gJy4uL3V0aWwvY3JlYXRlLXN0aXRjaGFibGUtc3RyZWFtJztcbmltcG9ydCB7IERlbGF5ZWRQcm9taXNlIH0gZnJvbSAnLi4vdXRpbC9kZWxheWVkLXByb21pc2UnO1xuaW1wb3J0IHsgRG93bmxvYWRGdW5jdGlvbiB9IGZyb20gJy4uL3V0aWwvZG93bmxvYWQvZG93bmxvYWQtZnVuY3Rpb24nO1xuaW1wb3J0IHsgbm93IGFzIG9yaWdpbmFsTm93IH0gZnJvbSAnLi4vdXRpbC9ub3cnO1xuaW1wb3J0IHsgcHJlcGFyZVJldHJpZXMgfSBmcm9tICcuLi91dGlsL3ByZXBhcmUtcmV0cmllcyc7XG5pbXBvcnQgeyBDb250ZW50UGFydCB9IGZyb20gJy4vY29udGVudC1wYXJ0JztcbmltcG9ydCB7IE91dHB1dCB9IGZyb20gJy4vb3V0cHV0JztcbmltcG9ydCB7IFByZXBhcmVTdGVwRnVuY3Rpb24gfSBmcm9tICcuL3ByZXBhcmUtc3RlcCc7XG5pbXBvcnQgeyBSZXNwb25zZU1lc3NhZ2UgfSBmcm9tICcuL3Jlc3BvbnNlLW1lc3NhZ2UnO1xuaW1wb3J0IHtcbiAgcnVuVG9vbHNUcmFuc2Zvcm1hdGlvbixcbiAgU2luZ2xlUmVxdWVzdFRleHRTdHJlYW1QYXJ0LFxufSBmcm9tICcuL3J1bi10b29scy10cmFuc2Zvcm1hdGlvbic7XG5pbXBvcnQgeyBEZWZhdWx0U3RlcFJlc3VsdCwgU3RlcFJlc3VsdCB9IGZyb20gJy4vc3RlcC1yZXN1bHQnO1xuaW1wb3J0IHtcbiAgaXNTdG9wQ29uZGl0aW9uTWV0LFxuICBzdGVwQ291bnRJcyxcbiAgU3RvcENvbmRpdGlvbixcbn0gZnJvbSAnLi9zdG9wLWNvbmRpdGlvbic7XG5pbXBvcnQge1xuICBDb25zdW1lU3RyZWFtT3B0aW9ucyxcbiAgU3RyZWFtVGV4dFJlc3VsdCxcbiAgVGV4dFN0cmVhbVBhcnQsXG4gIFVJTWVzc2FnZVN0cmVhbU9wdGlvbnMsXG59IGZyb20gJy4vc3RyZWFtLXRleHQtcmVzdWx0JztcbmltcG9ydCB7IHRvUmVzcG9uc2VNZXNzYWdlcyB9IGZyb20gJy4vdG8tcmVzcG9uc2UtbWVzc2FnZXMnO1xuaW1wb3J0IHsgVHlwZWRUb29sQ2FsbCB9IGZyb20gJy4vdG9vbC1jYWxsJztcbmltcG9ydCB7IFRvb2xDYWxsUmVwYWlyRnVuY3Rpb24gfSBmcm9tICcuL3Rvb2wtY2FsbC1yZXBhaXItZnVuY3Rpb24nO1xuaW1wb3J0IHsgVG9vbE91dHB1dCB9IGZyb20gJy4vdG9vbC1vdXRwdXQnO1xuaW1wb3J0IHsgVG9vbFNldCB9IGZyb20gJy4vdG9vbC1zZXQnO1xuXG5jb25zdCBvcmlnaW5hbEdlbmVyYXRlSWQgPSBjcmVhdGVJZEdlbmVyYXRvcih7XG4gIHByZWZpeDogJ2FpdHh0JyxcbiAgc2l6ZTogMjQsXG59KTtcblxuLyoqXG5BIHRyYW5zZm9ybWF0aW9uIHRoYXQgaXMgYXBwbGllZCB0byB0aGUgc3RyZWFtLlxuXG5AcGFyYW0gc3RvcFN0cmVhbSAtIEEgZnVuY3Rpb24gdGhhdCBzdG9wcyB0aGUgc291cmNlIHN0cmVhbS5cbkBwYXJhbSB0b29scyAtIFRoZSB0b29scyB0aGF0IGFyZSBhY2Nlc3NpYmxlIHRvIGFuZCBjYW4gYmUgY2FsbGVkIGJ5IHRoZSBtb2RlbC4gVGhlIG1vZGVsIG5lZWRzIHRvIHN1cHBvcnQgY2FsbGluZyB0b29scy5cbiAqL1xuZXhwb3J0IHR5cGUgU3RyZWFtVGV4dFRyYW5zZm9ybTxUT09MUyBleHRlbmRzIFRvb2xTZXQ+ID0gKG9wdGlvbnM6IHtcbiAgdG9vbHM6IFRPT0xTOyAvLyBmb3IgdHlwZSBpbmZlcmVuY2VcbiAgc3RvcFN0cmVhbTogKCkgPT4gdm9pZDtcbn0pID0+IFRyYW5zZm9ybVN0cmVhbTxUZXh0U3RyZWFtUGFydDxUT09MUz4sIFRleHRTdHJlYW1QYXJ0PFRPT0xTPj47XG5cbi8qKlxuQ2FsbGJhY2sgdGhhdCBpcyBzZXQgdXNpbmcgdGhlIGBvbkVycm9yYCBvcHRpb24uXG5cbkBwYXJhbSBldmVudCAtIFRoZSBldmVudCB0aGF0IGlzIHBhc3NlZCB0byB0aGUgY2FsbGJhY2suXG4gKi9cbmV4cG9ydCB0eXBlIFN0cmVhbVRleHRPbkVycm9yQ2FsbGJhY2sgPSAoZXZlbnQ6IHtcbiAgZXJyb3I6IHVua25vd247XG59KSA9PiBQcm9taXNlTGlrZTx2b2lkPiB8IHZvaWQ7XG5cbi8qKlxuQ2FsbGJhY2sgdGhhdCBpcyBzZXQgdXNpbmcgdGhlIGBvblN0ZXBGaW5pc2hgIG9wdGlvbi5cblxuQHBhcmFtIHN0ZXBSZXN1bHQgLSBUaGUgcmVzdWx0IG9mIHRoZSBzdGVwLlxuICovXG5leHBvcnQgdHlwZSBTdHJlYW1UZXh0T25TdGVwRmluaXNoQ2FsbGJhY2s8VE9PTFMgZXh0ZW5kcyBUb29sU2V0PiA9IChcbiAgc3RlcFJlc3VsdDogU3RlcFJlc3VsdDxUT09MUz4sXG4pID0+IFByb21pc2VMaWtlPHZvaWQ+IHwgdm9pZDtcblxuLyoqXG5DYWxsYmFjayB0aGF0IGlzIHNldCB1c2luZyB0aGUgYG9uQ2h1bmtgIG9wdGlvbi5cblxuQHBhcmFtIGV2ZW50IC0gVGhlIGV2ZW50IHRoYXQgaXMgcGFzc2VkIHRvIHRoZSBjYWxsYmFjay5cbiAqL1xuZXhwb3J0IHR5cGUgU3RyZWFtVGV4dE9uQ2h1bmtDYWxsYmFjazxUT09MUyBleHRlbmRzIFRvb2xTZXQ+ID0gKGV2ZW50OiB7XG4gIGNodW5rOiBFeHRyYWN0PFxuICAgIFRleHRTdHJlYW1QYXJ0PFRPT0xTPixcbiAgICB7XG4gICAgICB0eXBlOlxuICAgICAgICB8ICd0ZXh0LWRlbHRhJ1xuICAgICAgICB8ICdyZWFzb25pbmctZGVsdGEnXG4gICAgICAgIHwgJ3NvdXJjZSdcbiAgICAgICAgfCAndG9vbC1jYWxsJ1xuICAgICAgICB8ICd0b29sLWlucHV0LXN0YXJ0J1xuICAgICAgICB8ICd0b29sLWlucHV0LWRlbHRhJ1xuICAgICAgICB8ICd0b29sLXJlc3VsdCdcbiAgICAgICAgfCAncmF3JztcbiAgICB9XG4gID47XG59KSA9PiBQcm9taXNlTGlrZTx2b2lkPiB8IHZvaWQ7XG5cbi8qKlxuQ2FsbGJhY2sgdGhhdCBpcyBzZXQgdXNpbmcgdGhlIGBvbkZpbmlzaGAgb3B0aW9uLlxuXG5AcGFyYW0gZXZlbnQgLSBUaGUgZXZlbnQgdGhhdCBpcyBwYXNzZWQgdG8gdGhlIGNhbGxiYWNrLlxuICovXG5leHBvcnQgdHlwZSBTdHJlYW1UZXh0T25GaW5pc2hDYWxsYmFjazxUT09MUyBleHRlbmRzIFRvb2xTZXQ+ID0gKFxuICBldmVudDogU3RlcFJlc3VsdDxUT09MUz4gJiB7XG4gICAgLyoqXG5EZXRhaWxzIGZvciBhbGwgc3RlcHMuXG4gICAqL1xuICAgIHJlYWRvbmx5IHN0ZXBzOiBTdGVwUmVzdWx0PFRPT0xTPltdO1xuXG4gICAgLyoqXG5Ub3RhbCB1c2FnZSBmb3IgYWxsIHN0ZXBzLiBUaGlzIGlzIHRoZSBzdW0gb2YgdGhlIHVzYWdlIG9mIGFsbCBzdGVwcy5cbiAgICAgKi9cbiAgICByZWFkb25seSB0b3RhbFVzYWdlOiBMYW5ndWFnZU1vZGVsVXNhZ2U7XG4gIH0sXG4pID0+IFByb21pc2VMaWtlPHZvaWQ+IHwgdm9pZDtcblxuLyoqXG5DYWxsYmFjayB0aGF0IGlzIHNldCB1c2luZyB0aGUgYG9uQWJvcnRgIG9wdGlvbi5cblxuQHBhcmFtIGV2ZW50IC0gVGhlIGV2ZW50IHRoYXQgaXMgcGFzc2VkIHRvIHRoZSBjYWxsYmFjay5cbiAqL1xuZXhwb3J0IHR5cGUgU3RyZWFtVGV4dE9uQWJvcnRDYWxsYmFjazxUT09MUyBleHRlbmRzIFRvb2xTZXQ+ID0gKGV2ZW50OiB7XG4gIC8qKlxuRGV0YWlscyBmb3IgYWxsIHByZXZpb3VzbHkgZmluaXNoZWQgc3RlcHMuXG4gICAqL1xuICByZWFkb25seSBzdGVwczogU3RlcFJlc3VsdDxUT09MUz5bXTtcbn0pID0+IFByb21pc2VMaWtlPHZvaWQ+IHwgdm9pZDtcblxuLyoqXG5HZW5lcmF0ZSBhIHRleHQgYW5kIGNhbGwgdG9vbHMgZm9yIGEgZ2l2ZW4gcHJvbXB0IHVzaW5nIGEgbGFuZ3VhZ2UgbW9kZWwuXG5cblRoaXMgZnVuY3Rpb24gc3RyZWFtcyB0aGUgb3V0cHV0LiBJZiB5b3UgZG8gbm90IHdhbnQgdG8gc3RyZWFtIHRoZSBvdXRwdXQsIHVzZSBgZ2VuZXJhdGVUZXh0YCBpbnN0ZWFkLlxuXG5AcGFyYW0gbW9kZWwgLSBUaGUgbGFuZ3VhZ2UgbW9kZWwgdG8gdXNlLlxuQHBhcmFtIHRvb2xzIC0gVG9vbHMgdGhhdCBhcmUgYWNjZXNzaWJsZSB0byBhbmQgY2FuIGJlIGNhbGxlZCBieSB0aGUgbW9kZWwuIFRoZSBtb2RlbCBuZWVkcyB0byBzdXBwb3J0IGNhbGxpbmcgdG9vbHMuXG5cbkBwYXJhbSBzeXN0ZW0gLSBBIHN5c3RlbSBtZXNzYWdlIHRoYXQgd2lsbCBiZSBwYXJ0IG9mIHRoZSBwcm9tcHQuXG5AcGFyYW0gcHJvbXB0IC0gQSBzaW1wbGUgdGV4dCBwcm9tcHQuIFlvdSBjYW4gZWl0aGVyIHVzZSBgcHJvbXB0YCBvciBgbWVzc2FnZXNgIGJ1dCBub3QgYm90aC5cbkBwYXJhbSBtZXNzYWdlcyAtIEEgbGlzdCBvZiBtZXNzYWdlcy4gWW91IGNhbiBlaXRoZXIgdXNlIGBwcm9tcHRgIG9yIGBtZXNzYWdlc2AgYnV0IG5vdCBib3RoLlxuXG5AcGFyYW0gbWF4T3V0cHV0VG9rZW5zIC0gTWF4aW11bSBudW1iZXIgb2YgdG9rZW5zIHRvIGdlbmVyYXRlLlxuQHBhcmFtIHRlbXBlcmF0dXJlIC0gVGVtcGVyYXR1cmUgc2V0dGluZy5cblRoZSB2YWx1ZSBpcyBwYXNzZWQgdGhyb3VnaCB0byB0aGUgcHJvdmlkZXIuIFRoZSByYW5nZSBkZXBlbmRzIG9uIHRoZSBwcm92aWRlciBhbmQgbW9kZWwuXG5JdCBpcyByZWNvbW1lbmRlZCB0byBzZXQgZWl0aGVyIGB0ZW1wZXJhdHVyZWAgb3IgYHRvcFBgLCBidXQgbm90IGJvdGguXG5AcGFyYW0gdG9wUCAtIE51Y2xldXMgc2FtcGxpbmcuXG5UaGUgdmFsdWUgaXMgcGFzc2VkIHRocm91Z2ggdG8gdGhlIHByb3ZpZGVyLiBUaGUgcmFuZ2UgZGVwZW5kcyBvbiB0aGUgcHJvdmlkZXIgYW5kIG1vZGVsLlxuSXQgaXMgcmVjb21tZW5kZWQgdG8gc2V0IGVpdGhlciBgdGVtcGVyYXR1cmVgIG9yIGB0b3BQYCwgYnV0IG5vdCBib3RoLlxuQHBhcmFtIHRvcEsgLSBPbmx5IHNhbXBsZSBmcm9tIHRoZSB0b3AgSyBvcHRpb25zIGZvciBlYWNoIHN1YnNlcXVlbnQgdG9rZW4uXG5Vc2VkIHRvIHJlbW92ZSBcImxvbmcgdGFpbFwiIGxvdyBwcm9iYWJpbGl0eSByZXNwb25zZXMuXG5SZWNvbW1lbmRlZCBmb3IgYWR2YW5jZWQgdXNlIGNhc2VzIG9ubHkuIFlvdSB1c3VhbGx5IG9ubHkgbmVlZCB0byB1c2UgdGVtcGVyYXR1cmUuXG5AcGFyYW0gcHJlc2VuY2VQZW5hbHR5IC0gUHJlc2VuY2UgcGVuYWx0eSBzZXR0aW5nLlxuSXQgYWZmZWN0cyB0aGUgbGlrZWxpaG9vZCBvZiB0aGUgbW9kZWwgdG8gcmVwZWF0IGluZm9ybWF0aW9uIHRoYXQgaXMgYWxyZWFkeSBpbiB0aGUgcHJvbXB0LlxuVGhlIHZhbHVlIGlzIHBhc3NlZCB0aHJvdWdoIHRvIHRoZSBwcm92aWRlci4gVGhlIHJhbmdlIGRlcGVuZHMgb24gdGhlIHByb3ZpZGVyIGFuZCBtb2RlbC5cbkBwYXJhbSBmcmVxdWVuY3lQZW5hbHR5IC0gRnJlcXVlbmN5IHBlbmFsdHkgc2V0dGluZy5cbkl0IGFmZmVjdHMgdGhlIGxpa2VsaWhvb2Qgb2YgdGhlIG1vZGVsIHRvIHJlcGVhdGVkbHkgdXNlIHRoZSBzYW1lIHdvcmRzIG9yIHBocmFzZXMuXG5UaGUgdmFsdWUgaXMgcGFzc2VkIHRocm91Z2ggdG8gdGhlIHByb3ZpZGVyLiBUaGUgcmFuZ2UgZGVwZW5kcyBvbiB0aGUgcHJvdmlkZXIgYW5kIG1vZGVsLlxuQHBhcmFtIHN0b3BTZXF1ZW5jZXMgLSBTdG9wIHNlcXVlbmNlcy5cbklmIHNldCwgdGhlIG1vZGVsIHdpbGwgc3RvcCBnZW5lcmF0aW5nIHRleHQgd2hlbiBvbmUgb2YgdGhlIHN0b3Agc2VxdWVuY2VzIGlzIGdlbmVyYXRlZC5cbkBwYXJhbSBzZWVkIC0gVGhlIHNlZWQgKGludGVnZXIpIHRvIHVzZSBmb3IgcmFuZG9tIHNhbXBsaW5nLlxuSWYgc2V0IGFuZCBzdXBwb3J0ZWQgYnkgdGhlIG1vZGVsLCBjYWxscyB3aWxsIGdlbmVyYXRlIGRldGVybWluaXN0aWMgcmVzdWx0cy5cblxuQHBhcmFtIG1heFJldHJpZXMgLSBNYXhpbXVtIG51bWJlciBvZiByZXRyaWVzLiBTZXQgdG8gMCB0byBkaXNhYmxlIHJldHJpZXMuIERlZmF1bHQ6IDIuXG5AcGFyYW0gYWJvcnRTaWduYWwgLSBBbiBvcHRpb25hbCBhYm9ydCBzaWduYWwgdGhhdCBjYW4gYmUgdXNlZCB0byBjYW5jZWwgdGhlIGNhbGwuXG5AcGFyYW0gaGVhZGVycyAtIEFkZGl0aW9uYWwgSFRUUCBoZWFkZXJzIHRvIGJlIHNlbnQgd2l0aCB0aGUgcmVxdWVzdC4gT25seSBhcHBsaWNhYmxlIGZvciBIVFRQLWJhc2VkIHByb3ZpZGVycy5cblxuQHBhcmFtIG1heFN0ZXBzIC0gTWF4aW11bSBudW1iZXIgb2Ygc2VxdWVudGlhbCBMTE0gY2FsbHMgKHN0ZXBzKSwgZS5nLiB3aGVuIHlvdSB1c2UgdG9vbCBjYWxscy5cblxuQHBhcmFtIG9uQ2h1bmsgLSBDYWxsYmFjayB0aGF0IGlzIGNhbGxlZCBmb3IgZWFjaCBjaHVuayBvZiB0aGUgc3RyZWFtLiBUaGUgc3RyZWFtIHByb2Nlc3Npbmcgd2lsbCBwYXVzZSB1bnRpbCB0aGUgY2FsbGJhY2sgcHJvbWlzZSBpcyByZXNvbHZlZC5cbkBwYXJhbSBvbkVycm9yIC0gQ2FsbGJhY2sgdGhhdCBpcyBjYWxsZWQgd2hlbiBhbiBlcnJvciBvY2N1cnMgZHVyaW5nIHN0cmVhbWluZy4gWW91IGNhbiB1c2UgaXQgdG8gbG9nIGVycm9ycy5cbkBwYXJhbSBvblN0ZXBGaW5pc2ggLSBDYWxsYmFjayB0aGF0IGlzIGNhbGxlZCB3aGVuIGVhY2ggc3RlcCAoTExNIGNhbGwpIGlzIGZpbmlzaGVkLCBpbmNsdWRpbmcgaW50ZXJtZWRpYXRlIHN0ZXBzLlxuQHBhcmFtIG9uRmluaXNoIC0gQ2FsbGJhY2sgdGhhdCBpcyBjYWxsZWQgd2hlbiB0aGUgTExNIHJlc3BvbnNlIGFuZCBhbGwgcmVxdWVzdCB0b29sIGV4ZWN1dGlvbnNcbihmb3IgdG9vbHMgdGhhdCBoYXZlIGFuIGBleGVjdXRlYCBmdW5jdGlvbikgYXJlIGZpbmlzaGVkLlxuXG5AcmV0dXJuXG5BIHJlc3VsdCBvYmplY3QgZm9yIGFjY2Vzc2luZyBkaWZmZXJlbnQgc3RyZWFtIHR5cGVzIGFuZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc3RyZWFtVGV4dDxcbiAgVE9PTFMgZXh0ZW5kcyBUb29sU2V0LFxuICBPVVRQVVQgPSBuZXZlcixcbiAgUEFSVElBTF9PVVRQVVQgPSBuZXZlcixcbj4oe1xuICBtb2RlbCxcbiAgdG9vbHMsXG4gIHRvb2xDaG9pY2UsXG4gIHN5c3RlbSxcbiAgcHJvbXB0LFxuICBtZXNzYWdlcyxcbiAgbWF4UmV0cmllcyxcbiAgYWJvcnRTaWduYWwsXG4gIGhlYWRlcnMsXG4gIHN0b3BXaGVuID0gc3RlcENvdW50SXMoMSksXG4gIGV4cGVyaW1lbnRhbF9vdXRwdXQ6IG91dHB1dCxcbiAgZXhwZXJpbWVudGFsX3RlbGVtZXRyeTogdGVsZW1ldHJ5LFxuICBwcmVwYXJlU3RlcCxcbiAgcHJvdmlkZXJPcHRpb25zLFxuICBleHBlcmltZW50YWxfYWN0aXZlVG9vbHMsXG4gIGFjdGl2ZVRvb2xzID0gZXhwZXJpbWVudGFsX2FjdGl2ZVRvb2xzLFxuICBleHBlcmltZW50YWxfcmVwYWlyVG9vbENhbGw6IHJlcGFpclRvb2xDYWxsLFxuICBleHBlcmltZW50YWxfdHJhbnNmb3JtOiB0cmFuc2Zvcm0sXG4gIGV4cGVyaW1lbnRhbF9kb3dubG9hZDogZG93bmxvYWQsXG4gIGluY2x1ZGVSYXdDaHVua3MgPSBmYWxzZSxcbiAgb25DaHVuayxcbiAgb25FcnJvciA9ICh7IGVycm9yIH0pID0+IHtcbiAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgfSxcbiAgb25GaW5pc2gsXG4gIG9uQWJvcnQsXG4gIG9uU3RlcEZpbmlzaCxcbiAgZXhwZXJpbWVudGFsX2NvbnRleHQsXG4gIF9pbnRlcm5hbDoge1xuICAgIG5vdyA9IG9yaWdpbmFsTm93LFxuICAgIGdlbmVyYXRlSWQgPSBvcmlnaW5hbEdlbmVyYXRlSWQsXG4gICAgY3VycmVudERhdGUgPSAoKSA9PiBuZXcgRGF0ZSgpLFxuICB9ID0ge30sXG4gIC4uLnNldHRpbmdzXG59OiBDYWxsU2V0dGluZ3MgJlxuICBQcm9tcHQgJiB7XG4gICAgLyoqXG5UaGUgbGFuZ3VhZ2UgbW9kZWwgdG8gdXNlLlxuICAgICAqL1xuICAgIG1vZGVsOiBMYW5ndWFnZU1vZGVsO1xuXG4gICAgLyoqXG5UaGUgdG9vbHMgdGhhdCB0aGUgbW9kZWwgY2FuIGNhbGwuIFRoZSBtb2RlbCBuZWVkcyB0byBzdXBwb3J0IGNhbGxpbmcgdG9vbHMuXG4gICAgKi9cbiAgICB0b29scz86IFRPT0xTO1xuXG4gICAgLyoqXG5UaGUgdG9vbCBjaG9pY2Ugc3RyYXRlZ3kuIERlZmF1bHQ6ICdhdXRvJy5cbiAgICAgKi9cbiAgICB0b29sQ2hvaWNlPzogVG9vbENob2ljZTxUT09MUz47XG5cbiAgICAvKipcbkNvbmRpdGlvbiBmb3Igc3RvcHBpbmcgdGhlIGdlbmVyYXRpb24gd2hlbiB0aGVyZSBhcmUgdG9vbCByZXN1bHRzIGluIHRoZSBsYXN0IHN0ZXAuXG5XaGVuIHRoZSBjb25kaXRpb24gaXMgYW4gYXJyYXksIGFueSBvZiB0aGUgY29uZGl0aW9ucyBjYW4gYmUgbWV0IHRvIHN0b3AgdGhlIGdlbmVyYXRpb24uXG5cbkBkZWZhdWx0IHN0ZXBDb3VudElzKDEpXG4gICAgICovXG4gICAgc3RvcFdoZW4/OlxuICAgICAgfCBTdG9wQ29uZGl0aW9uPE5vSW5mZXI8VE9PTFM+PlxuICAgICAgfCBBcnJheTxTdG9wQ29uZGl0aW9uPE5vSW5mZXI8VE9PTFM+Pj47XG5cbiAgICAvKipcbk9wdGlvbmFsIHRlbGVtZXRyeSBjb25maWd1cmF0aW9uIChleHBlcmltZW50YWwpLlxuICAgICAqL1xuICAgIGV4cGVyaW1lbnRhbF90ZWxlbWV0cnk/OiBUZWxlbWV0cnlTZXR0aW5ncztcblxuICAgIC8qKlxuQWRkaXRpb25hbCBwcm92aWRlci1zcGVjaWZpYyBvcHRpb25zLiBUaGV5IGFyZSBwYXNzZWQgdGhyb3VnaFxudG8gdGhlIHByb3ZpZGVyIGZyb20gdGhlIEFJIFNESyBhbmQgZW5hYmxlIHByb3ZpZGVyLXNwZWNpZmljXG5mdW5jdGlvbmFsaXR5IHRoYXQgY2FuIGJlIGZ1bGx5IGVuY2Fwc3VsYXRlZCBpbiB0aGUgcHJvdmlkZXIuXG4gKi9cbiAgICBwcm92aWRlck9wdGlvbnM/OiBQcm92aWRlck9wdGlvbnM7XG5cbiAgICAvKipcbiAgICAgKiBAZGVwcmVjYXRlZCBVc2UgYGFjdGl2ZVRvb2xzYCBpbnN0ZWFkLlxuICAgICAqL1xuICAgIGV4cGVyaW1lbnRhbF9hY3RpdmVUb29scz86IEFycmF5PGtleW9mIE5vSW5mZXI8VE9PTFM+PjtcblxuICAgIC8qKlxuICAgTGltaXRzIHRoZSB0b29scyB0aGF0IGFyZSBhdmFpbGFibGUgZm9yIHRoZSBtb2RlbCB0byBjYWxsIHdpdGhvdXRcbiAgIGNoYW5naW5nIHRoZSB0b29sIGNhbGwgYW5kIHJlc3VsdCB0eXBlcyBpbiB0aGUgcmVzdWx0LlxuICAgICAgICAqL1xuICAgIGFjdGl2ZVRvb2xzPzogQXJyYXk8a2V5b2YgTm9JbmZlcjxUT09MUz4+O1xuXG4gICAgLyoqXG5PcHRpb25hbCBzcGVjaWZpY2F0aW9uIGZvciBwYXJzaW5nIHN0cnVjdHVyZWQgb3V0cHV0cyBmcm9tIHRoZSBMTE0gcmVzcG9uc2UuXG4gICAgICovXG4gICAgZXhwZXJpbWVudGFsX291dHB1dD86IE91dHB1dDxPVVRQVVQsIFBBUlRJQUxfT1VUUFVUPjtcblxuICAgIC8qKlxuT3B0aW9uYWwgZnVuY3Rpb24gdGhhdCB5b3UgY2FuIHVzZSB0byBwcm92aWRlIGRpZmZlcmVudCBzZXR0aW5ncyBmb3IgYSBzdGVwLlxuXG5AcGFyYW0gb3B0aW9ucyAtIFRoZSBvcHRpb25zIGZvciB0aGUgc3RlcC5cbkBwYXJhbSBvcHRpb25zLnN0ZXBzIC0gVGhlIHN0ZXBzIHRoYXQgaGF2ZSBiZWVuIGV4ZWN1dGVkIHNvIGZhci5cbkBwYXJhbSBvcHRpb25zLnN0ZXBOdW1iZXIgLSBUaGUgbnVtYmVyIG9mIHRoZSBzdGVwIHRoYXQgaXMgYmVpbmcgZXhlY3V0ZWQuXG5AcGFyYW0gb3B0aW9ucy5tb2RlbCAtIFRoZSBtb2RlbCB0aGF0IGlzIGJlaW5nIHVzZWQuXG5cbkByZXR1cm5zIEFuIG9iamVjdCB0aGF0IGNvbnRhaW5zIHRoZSBzZXR0aW5ncyBmb3IgdGhlIHN0ZXAuXG5JZiB5b3UgcmV0dXJuIHVuZGVmaW5lZCAob3IgZm9yIHVuZGVmaW5lZCBzZXR0aW5ncyksIHRoZSBzZXR0aW5ncyBmcm9tIHRoZSBvdXRlciBsZXZlbCB3aWxsIGJlIHVzZWQuXG4gICAgKi9cbiAgICBwcmVwYXJlU3RlcD86IFByZXBhcmVTdGVwRnVuY3Rpb248Tm9JbmZlcjxUT09MUz4+O1xuXG4gICAgLyoqXG5BIGZ1bmN0aW9uIHRoYXQgYXR0ZW1wdHMgdG8gcmVwYWlyIGEgdG9vbCBjYWxsIHRoYXQgZmFpbGVkIHRvIHBhcnNlLlxuICAgICAqL1xuICAgIGV4cGVyaW1lbnRhbF9yZXBhaXJUb29sQ2FsbD86IFRvb2xDYWxsUmVwYWlyRnVuY3Rpb248VE9PTFM+O1xuXG4gICAgLyoqXG5PcHRpb25hbCBzdHJlYW0gdHJhbnNmb3JtYXRpb25zLlxuVGhleSBhcmUgYXBwbGllZCBpbiB0aGUgb3JkZXIgdGhleSBhcmUgcHJvdmlkZWQuXG5UaGUgc3RyZWFtIHRyYW5zZm9ybWF0aW9ucyBtdXN0IG1haW50YWluIHRoZSBzdHJlYW0gc3RydWN0dXJlIGZvciBzdHJlYW1UZXh0IHRvIHdvcmsgY29ycmVjdGx5LlxuICAgICAqL1xuICAgIGV4cGVyaW1lbnRhbF90cmFuc2Zvcm0/OlxuICAgICAgfCBTdHJlYW1UZXh0VHJhbnNmb3JtPFRPT0xTPlxuICAgICAgfCBBcnJheTxTdHJlYW1UZXh0VHJhbnNmb3JtPFRPT0xTPj47XG5cbiAgICAvKipcbkN1c3RvbSBkb3dubG9hZCBmdW5jdGlvbiB0byB1c2UgZm9yIFVSTHMuXG5cbkJ5IGRlZmF1bHQsIGZpbGVzIGFyZSBkb3dubG9hZGVkIGlmIHRoZSBtb2RlbCBkb2VzIG5vdCBzdXBwb3J0IHRoZSBVUkwgZm9yIHRoZSBnaXZlbiBtZWRpYSB0eXBlLlxuICAgICAqL1xuICAgIGV4cGVyaW1lbnRhbF9kb3dubG9hZD86IERvd25sb2FkRnVuY3Rpb24gfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbldoZXRoZXIgdG8gaW5jbHVkZSByYXcgY2h1bmtzIGZyb20gdGhlIHByb3ZpZGVyIGluIHRoZSBzdHJlYW0uXG5XaGVuIGVuYWJsZWQsIHlvdSB3aWxsIHJlY2VpdmUgcmF3IGNodW5rcyB3aXRoIHR5cGUgJ3JhdycgdGhhdCBjb250YWluIHRoZSB1bnByb2Nlc3NlZCBkYXRhIGZyb20gdGhlIHByb3ZpZGVyLlxuVGhpcyBhbGxvd3MgYWNjZXNzIHRvIGN1dHRpbmctZWRnZSBwcm92aWRlciBmZWF0dXJlcyBub3QgeWV0IHdyYXBwZWQgYnkgdGhlIEFJIFNESy5cbkRlZmF1bHRzIHRvIGZhbHNlLlxuICAgICAqL1xuICAgIGluY2x1ZGVSYXdDaHVua3M/OiBib29sZWFuO1xuXG4gICAgLyoqXG5DYWxsYmFjayB0aGF0IGlzIGNhbGxlZCBmb3IgZWFjaCBjaHVuayBvZiB0aGUgc3RyZWFtLlxuVGhlIHN0cmVhbSBwcm9jZXNzaW5nIHdpbGwgcGF1c2UgdW50aWwgdGhlIGNhbGxiYWNrIHByb21pc2UgaXMgcmVzb2x2ZWQuXG4gICAgICovXG4gICAgb25DaHVuaz86IFN0cmVhbVRleHRPbkNodW5rQ2FsbGJhY2s8VE9PTFM+O1xuXG4gICAgLyoqXG5DYWxsYmFjayB0aGF0IGlzIGludm9rZWQgd2hlbiBhbiBlcnJvciBvY2N1cnMgZHVyaW5nIHN0cmVhbWluZy5cbllvdSBjYW4gdXNlIGl0IHRvIGxvZyBlcnJvcnMuXG5UaGUgc3RyZWFtIHByb2Nlc3Npbmcgd2lsbCBwYXVzZSB1bnRpbCB0aGUgY2FsbGJhY2sgcHJvbWlzZSBpcyByZXNvbHZlZC5cbiAgICAgKi9cbiAgICBvbkVycm9yPzogU3RyZWFtVGV4dE9uRXJyb3JDYWxsYmFjaztcblxuICAgIC8qKlxuQ2FsbGJhY2sgdGhhdCBpcyBjYWxsZWQgd2hlbiB0aGUgTExNIHJlc3BvbnNlIGFuZCBhbGwgcmVxdWVzdCB0b29sIGV4ZWN1dGlvbnNcbihmb3IgdG9vbHMgdGhhdCBoYXZlIGFuIGBleGVjdXRlYCBmdW5jdGlvbikgYXJlIGZpbmlzaGVkLlxuXG5UaGUgdXNhZ2UgaXMgdGhlIGNvbWJpbmVkIHVzYWdlIG9mIGFsbCBzdGVwcy5cbiAgICAgKi9cbiAgICBvbkZpbmlzaD86IFN0cmVhbVRleHRPbkZpbmlzaENhbGxiYWNrPFRPT0xTPjtcblxuICAgIG9uQWJvcnQ/OiBTdHJlYW1UZXh0T25BYm9ydENhbGxiYWNrPFRPT0xTPjtcblxuICAgIC8qKlxuQ2FsbGJhY2sgdGhhdCBpcyBjYWxsZWQgd2hlbiBlYWNoIHN0ZXAgKExMTSBjYWxsKSBpcyBmaW5pc2hlZCwgaW5jbHVkaW5nIGludGVybWVkaWF0ZSBzdGVwcy5cbiAgICAqL1xuICAgIG9uU3RlcEZpbmlzaD86IFN0cmVhbVRleHRPblN0ZXBGaW5pc2hDYWxsYmFjazxUT09MUz47XG5cbiAgICAvKipcbiAgICAgKiBDb250ZXh0IHRoYXQgaXMgcGFzc2VkIGludG8gdG9vbCBleGVjdXRpb24uXG4gICAgICpcbiAgICAgKiBFeHBlcmltZW50YWwgKGNhbiBicmVhayBpbiBwYXRjaCByZWxlYXNlcykuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdCB1bmRlZmluZWRcbiAgICAgKi9cbiAgICBleHBlcmltZW50YWxfY29udGV4dD86IHVua25vd247XG5cbiAgICAvKipcbkludGVybmFsLiBGb3IgdGVzdCB1c2Ugb25seS4gTWF5IGNoYW5nZSB3aXRob3V0IG5vdGljZS5cbiAgICAgKi9cbiAgICBfaW50ZXJuYWw/OiB7XG4gICAgICBub3c/OiAoKSA9PiBudW1iZXI7XG4gICAgICBnZW5lcmF0ZUlkPzogSWRHZW5lcmF0b3I7XG4gICAgICBjdXJyZW50RGF0ZT86ICgpID0+IERhdGU7XG4gICAgfTtcbiAgfSk6IFN0cmVhbVRleHRSZXN1bHQ8VE9PTFMsIFBBUlRJQUxfT1VUUFVUPiB7XG4gIHJldHVybiBuZXcgRGVmYXVsdFN0cmVhbVRleHRSZXN1bHQ8VE9PTFMsIE9VVFBVVCwgUEFSVElBTF9PVVRQVVQ+KHtcbiAgICBtb2RlbDogcmVzb2x2ZUxhbmd1YWdlTW9kZWwobW9kZWwpLFxuICAgIHRlbGVtZXRyeSxcbiAgICBoZWFkZXJzLFxuICAgIHNldHRpbmdzLFxuICAgIG1heFJldHJpZXMsXG4gICAgYWJvcnRTaWduYWwsXG4gICAgc3lzdGVtLFxuICAgIHByb21wdCxcbiAgICBtZXNzYWdlcyxcbiAgICB0b29scyxcbiAgICB0b29sQ2hvaWNlLFxuICAgIHRyYW5zZm9ybXM6IGFzQXJyYXkodHJhbnNmb3JtKSxcbiAgICBhY3RpdmVUb29scyxcbiAgICByZXBhaXJUb29sQ2FsbCxcbiAgICBzdG9wQ29uZGl0aW9uczogYXNBcnJheShzdG9wV2hlbiksXG4gICAgb3V0cHV0LFxuICAgIHByb3ZpZGVyT3B0aW9ucyxcbiAgICBwcmVwYXJlU3RlcCxcbiAgICBpbmNsdWRlUmF3Q2h1bmtzLFxuICAgIG9uQ2h1bmssXG4gICAgb25FcnJvcixcbiAgICBvbkZpbmlzaCxcbiAgICBvbkFib3J0LFxuICAgIG9uU3RlcEZpbmlzaCxcbiAgICBub3csXG4gICAgY3VycmVudERhdGUsXG4gICAgZ2VuZXJhdGVJZCxcbiAgICBleHBlcmltZW50YWxfY29udGV4dCxcbiAgICBkb3dubG9hZCxcbiAgfSk7XG59XG5cbnR5cGUgRW5yaWNoZWRTdHJlYW1QYXJ0PFRPT0xTIGV4dGVuZHMgVG9vbFNldCwgUEFSVElBTF9PVVRQVVQ+ID0ge1xuICBwYXJ0OiBUZXh0U3RyZWFtUGFydDxUT09MUz47XG4gIHBhcnRpYWxPdXRwdXQ6IFBBUlRJQUxfT1VUUFVUIHwgdW5kZWZpbmVkO1xufTtcblxuZnVuY3Rpb24gY3JlYXRlT3V0cHV0VHJhbnNmb3JtU3RyZWFtPFxuICBUT09MUyBleHRlbmRzIFRvb2xTZXQsXG4gIE9VVFBVVCxcbiAgUEFSVElBTF9PVVRQVVQsXG4+KFxuICBvdXRwdXQ6IE91dHB1dDxPVVRQVVQsIFBBUlRJQUxfT1VUUFVUPiB8IHVuZGVmaW5lZCxcbik6IFRyYW5zZm9ybVN0cmVhbTxcbiAgVGV4dFN0cmVhbVBhcnQ8VE9PTFM+LFxuICBFbnJpY2hlZFN0cmVhbVBhcnQ8VE9PTFMsIFBBUlRJQUxfT1VUUFVUPlxuPiB7XG4gIGlmICghb3V0cHV0KSB7XG4gICAgcmV0dXJuIG5ldyBUcmFuc2Zvcm1TdHJlYW08XG4gICAgICBUZXh0U3RyZWFtUGFydDxUT09MUz4sXG4gICAgICBFbnJpY2hlZFN0cmVhbVBhcnQ8VE9PTFMsIFBBUlRJQUxfT1VUUFVUPlxuICAgID4oe1xuICAgICAgdHJhbnNmb3JtKGNodW5rLCBjb250cm9sbGVyKSB7XG4gICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7IHBhcnQ6IGNodW5rLCBwYXJ0aWFsT3V0cHV0OiB1bmRlZmluZWQgfSk7XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgbGV0IGZpcnN0VGV4dENodW5rSWQ6IHN0cmluZyB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgbGV0IHRleHQgPSAnJztcbiAgbGV0IHRleHRDaHVuayA9ICcnO1xuICBsZXQgbGFzdFB1Ymxpc2hlZEpzb24gPSAnJztcblxuICBmdW5jdGlvbiBwdWJsaXNoVGV4dENodW5rKHtcbiAgICBjb250cm9sbGVyLFxuICAgIHBhcnRpYWxPdXRwdXQgPSB1bmRlZmluZWQsXG4gIH06IHtcbiAgICBjb250cm9sbGVyOiBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlcjxcbiAgICAgIEVucmljaGVkU3RyZWFtUGFydDxUT09MUywgUEFSVElBTF9PVVRQVVQ+XG4gICAgPjtcbiAgICBwYXJ0aWFsT3V0cHV0PzogUEFSVElBTF9PVVRQVVQ7XG4gIH0pIHtcbiAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgcGFydDoge1xuICAgICAgICB0eXBlOiAndGV4dC1kZWx0YScsXG4gICAgICAgIGlkOiBmaXJzdFRleHRDaHVua0lkISxcbiAgICAgICAgdGV4dDogdGV4dENodW5rLFxuICAgICAgfSxcbiAgICAgIHBhcnRpYWxPdXRwdXQsXG4gICAgfSk7XG4gICAgdGV4dENodW5rID0gJyc7XG4gIH1cblxuICByZXR1cm4gbmV3IFRyYW5zZm9ybVN0cmVhbTxcbiAgICBUZXh0U3RyZWFtUGFydDxUT09MUz4sXG4gICAgRW5yaWNoZWRTdHJlYW1QYXJ0PFRPT0xTLCBQQVJUSUFMX09VVFBVVD5cbiAgPih7XG4gICAgYXN5bmMgdHJhbnNmb3JtKGNodW5rLCBjb250cm9sbGVyKSB7XG4gICAgICAvLyBlbnN1cmUgdGhhdCB3ZSBwdWJsaXNoIHRoZSBsYXN0IHRleHQgY2h1bmsgYmVmb3JlIHRoZSBzdGVwIGZpbmlzaDpcbiAgICAgIGlmIChjaHVuay50eXBlID09PSAnZmluaXNoLXN0ZXAnICYmIHRleHRDaHVuay5sZW5ndGggPiAwKSB7XG4gICAgICAgIHB1Ymxpc2hUZXh0Q2h1bmsoeyBjb250cm9sbGVyIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIGNodW5rLnR5cGUgIT09ICd0ZXh0LWRlbHRhJyAmJlxuICAgICAgICBjaHVuay50eXBlICE9PSAndGV4dC1zdGFydCcgJiZcbiAgICAgICAgY2h1bmsudHlwZSAhPT0gJ3RleHQtZW5kJ1xuICAgICAgKSB7XG4gICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7IHBhcnQ6IGNodW5rLCBwYXJ0aWFsT3V0cHV0OiB1bmRlZmluZWQgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gd2UgaGF2ZSB0byBwaWNrIGEgdGV4dCBjaHVuayB3aGljaCBjb250YWlucyB0aGUganNvbiB0ZXh0XG4gICAgICAvLyBzaW5jZSB3ZSBhcmUgc3RyZWFtaW5nLCB3ZSBoYXZlIHRvIHBpY2sgdGhlIGZpcnN0IHRleHQgY2h1bmtcbiAgICAgIGlmIChmaXJzdFRleHRDaHVua0lkID09IG51bGwpIHtcbiAgICAgICAgZmlyc3RUZXh0Q2h1bmtJZCA9IGNodW5rLmlkO1xuICAgICAgfSBlbHNlIGlmIChjaHVuay5pZCAhPT0gZmlyc3RUZXh0Q2h1bmtJZCkge1xuICAgICAgICBjb250cm9sbGVyLmVucXVldWUoeyBwYXJ0OiBjaHVuaywgcGFydGlhbE91dHB1dDogdW5kZWZpbmVkIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChjaHVuay50eXBlID09PSAndGV4dC1zdGFydCcpIHtcbiAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHsgcGFydDogY2h1bmssIHBhcnRpYWxPdXRwdXQ6IHVuZGVmaW5lZCB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoY2h1bmsudHlwZSA9PT0gJ3RleHQtZW5kJykge1xuICAgICAgICBpZiAodGV4dENodW5rLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBwdWJsaXNoVGV4dENodW5rKHsgY29udHJvbGxlciB9KTtcbiAgICAgICAgfVxuICAgICAgICBjb250cm9sbGVyLmVucXVldWUoeyBwYXJ0OiBjaHVuaywgcGFydGlhbE91dHB1dDogdW5kZWZpbmVkIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRleHQgKz0gY2h1bmsudGV4dDtcbiAgICAgIHRleHRDaHVuayArPSBjaHVuay50ZXh0O1xuXG4gICAgICAvLyBvbmx5IHB1Ymxpc2ggaWYgcGFydGlhbCBqc29uIGNhbiBiZSBwYXJzZWQ6XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBvdXRwdXQucGFyc2VQYXJ0aWFsKHsgdGV4dCB9KTtcbiAgICAgIGlmIChyZXN1bHQgIT0gbnVsbCkge1xuICAgICAgICAvLyBvbmx5IHNlbmQgbmV3IGpzb24gaWYgaXQgaGFzIGNoYW5nZWQ6XG4gICAgICAgIGNvbnN0IGN1cnJlbnRKc29uID0gSlNPTi5zdHJpbmdpZnkocmVzdWx0LnBhcnRpYWwpO1xuICAgICAgICBpZiAoY3VycmVudEpzb24gIT09IGxhc3RQdWJsaXNoZWRKc29uKSB7XG4gICAgICAgICAgcHVibGlzaFRleHRDaHVuayh7IGNvbnRyb2xsZXIsIHBhcnRpYWxPdXRwdXQ6IHJlc3VsdC5wYXJ0aWFsIH0pO1xuICAgICAgICAgIGxhc3RQdWJsaXNoZWRKc29uID0gY3VycmVudEpzb247XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuICB9KTtcbn1cblxuY2xhc3MgRGVmYXVsdFN0cmVhbVRleHRSZXN1bHQ8VE9PTFMgZXh0ZW5kcyBUb29sU2V0LCBPVVRQVVQsIFBBUlRJQUxfT1VUUFVUPlxuICBpbXBsZW1lbnRzIFN0cmVhbVRleHRSZXN1bHQ8VE9PTFMsIFBBUlRJQUxfT1VUUFVUPlxue1xuICBwcml2YXRlIHJlYWRvbmx5IF90b3RhbFVzYWdlID0gbmV3IERlbGF5ZWRQcm9taXNlPFxuICAgIEF3YWl0ZWQ8U3RyZWFtVGV4dFJlc3VsdDxUT09MUywgUEFSVElBTF9PVVRQVVQ+Wyd1c2FnZSddPlxuICA+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2ZpbmlzaFJlYXNvbiA9IG5ldyBEZWxheWVkUHJvbWlzZTxcbiAgICBBd2FpdGVkPFN0cmVhbVRleHRSZXN1bHQ8VE9PTFMsIFBBUlRJQUxfT1VUUFVUPlsnZmluaXNoUmVhc29uJ10+XG4gID4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfc3RlcHMgPSBuZXcgRGVsYXllZFByb21pc2U8XG4gICAgQXdhaXRlZDxTdHJlYW1UZXh0UmVzdWx0PFRPT0xTLCBQQVJUSUFMX09VVFBVVD5bJ3N0ZXBzJ10+XG4gID4oKTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGFkZFN0cmVhbTogKFxuICAgIHN0cmVhbTogUmVhZGFibGVTdHJlYW08VGV4dFN0cmVhbVBhcnQ8VE9PTFM+PixcbiAgKSA9PiB2b2lkO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgY2xvc2VTdHJlYW06ICgpID0+IHZvaWQ7XG5cbiAgcHJpdmF0ZSBiYXNlU3RyZWFtOiBSZWFkYWJsZVN0cmVhbTxFbnJpY2hlZFN0cmVhbVBhcnQ8VE9PTFMsIFBBUlRJQUxfT1VUUFVUPj47XG5cbiAgcHJpdmF0ZSBvdXRwdXQ6IE91dHB1dDxPVVRQVVQsIFBBUlRJQUxfT1VUUFVUPiB8IHVuZGVmaW5lZDtcblxuICBwcml2YXRlIGluY2x1ZGVSYXdDaHVua3M6IGJvb2xlYW47XG5cbiAgcHJpdmF0ZSB0b29sczogVE9PTFMgfCB1bmRlZmluZWQ7XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIG1vZGVsLFxuICAgIHRlbGVtZXRyeSxcbiAgICBoZWFkZXJzLFxuICAgIHNldHRpbmdzLFxuICAgIG1heFJldHJpZXM6IG1heFJldHJpZXNBcmcsXG4gICAgYWJvcnRTaWduYWwsXG4gICAgc3lzdGVtLFxuICAgIHByb21wdCxcbiAgICBtZXNzYWdlcyxcbiAgICB0b29scyxcbiAgICB0b29sQ2hvaWNlLFxuICAgIHRyYW5zZm9ybXMsXG4gICAgYWN0aXZlVG9vbHMsXG4gICAgcmVwYWlyVG9vbENhbGwsXG4gICAgc3RvcENvbmRpdGlvbnMsXG4gICAgb3V0cHV0LFxuICAgIHByb3ZpZGVyT3B0aW9ucyxcbiAgICBwcmVwYXJlU3RlcCxcbiAgICBpbmNsdWRlUmF3Q2h1bmtzLFxuICAgIG5vdyxcbiAgICBjdXJyZW50RGF0ZSxcbiAgICBnZW5lcmF0ZUlkLFxuICAgIG9uQ2h1bmssXG4gICAgb25FcnJvcixcbiAgICBvbkZpbmlzaCxcbiAgICBvbkFib3J0LFxuICAgIG9uU3RlcEZpbmlzaCxcbiAgICBleHBlcmltZW50YWxfY29udGV4dCxcbiAgICBkb3dubG9hZCxcbiAgfToge1xuICAgIG1vZGVsOiBMYW5ndWFnZU1vZGVsVjI7XG4gICAgdGVsZW1ldHJ5OiBUZWxlbWV0cnlTZXR0aW5ncyB8IHVuZGVmaW5lZDtcbiAgICBoZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+IHwgdW5kZWZpbmVkO1xuICAgIHNldHRpbmdzOiBPbWl0PENhbGxTZXR0aW5ncywgJ2Fib3J0U2lnbmFsJyB8ICdoZWFkZXJzJz47XG4gICAgbWF4UmV0cmllczogbnVtYmVyIHwgdW5kZWZpbmVkO1xuICAgIGFib3J0U2lnbmFsOiBBYm9ydFNpZ25hbCB8IHVuZGVmaW5lZDtcbiAgICBzeXN0ZW06IFByb21wdFsnc3lzdGVtJ107XG4gICAgcHJvbXB0OiBQcm9tcHRbJ3Byb21wdCddO1xuICAgIG1lc3NhZ2VzOiBQcm9tcHRbJ21lc3NhZ2VzJ107XG4gICAgdG9vbHM6IFRPT0xTIHwgdW5kZWZpbmVkO1xuICAgIHRvb2xDaG9pY2U6IFRvb2xDaG9pY2U8VE9PTFM+IHwgdW5kZWZpbmVkO1xuICAgIHRyYW5zZm9ybXM6IEFycmF5PFN0cmVhbVRleHRUcmFuc2Zvcm08VE9PTFM+PjtcbiAgICBhY3RpdmVUb29sczogQXJyYXk8a2V5b2YgVE9PTFM+IHwgdW5kZWZpbmVkO1xuICAgIHJlcGFpclRvb2xDYWxsOiBUb29sQ2FsbFJlcGFpckZ1bmN0aW9uPFRPT0xTPiB8IHVuZGVmaW5lZDtcbiAgICBzdG9wQ29uZGl0aW9uczogQXJyYXk8U3RvcENvbmRpdGlvbjxOb0luZmVyPFRPT0xTPj4+O1xuICAgIG91dHB1dDogT3V0cHV0PE9VVFBVVCwgUEFSVElBTF9PVVRQVVQ+IHwgdW5kZWZpbmVkO1xuICAgIHByb3ZpZGVyT3B0aW9uczogUHJvdmlkZXJPcHRpb25zIHwgdW5kZWZpbmVkO1xuICAgIHByZXBhcmVTdGVwOiBQcmVwYXJlU3RlcEZ1bmN0aW9uPE5vSW5mZXI8VE9PTFM+PiB8IHVuZGVmaW5lZDtcbiAgICBpbmNsdWRlUmF3Q2h1bmtzOiBib29sZWFuO1xuICAgIG5vdzogKCkgPT4gbnVtYmVyO1xuICAgIGN1cnJlbnREYXRlOiAoKSA9PiBEYXRlO1xuICAgIGdlbmVyYXRlSWQ6ICgpID0+IHN0cmluZztcbiAgICBleHBlcmltZW50YWxfY29udGV4dDogdW5rbm93bjtcbiAgICBkb3dubG9hZDogRG93bmxvYWRGdW5jdGlvbiB8IHVuZGVmaW5lZDtcblxuICAgIC8vIGNhbGxiYWNrczpcbiAgICBvbkNodW5rOiB1bmRlZmluZWQgfCBTdHJlYW1UZXh0T25DaHVua0NhbGxiYWNrPFRPT0xTPjtcbiAgICBvbkVycm9yOiBTdHJlYW1UZXh0T25FcnJvckNhbGxiYWNrO1xuICAgIG9uRmluaXNoOiB1bmRlZmluZWQgfCBTdHJlYW1UZXh0T25GaW5pc2hDYWxsYmFjazxUT09MUz47XG4gICAgb25BYm9ydDogdW5kZWZpbmVkIHwgU3RyZWFtVGV4dE9uQWJvcnRDYWxsYmFjazxUT09MUz47XG4gICAgb25TdGVwRmluaXNoOiB1bmRlZmluZWQgfCBTdHJlYW1UZXh0T25TdGVwRmluaXNoQ2FsbGJhY2s8VE9PTFM+O1xuICB9KSB7XG4gICAgdGhpcy5vdXRwdXQgPSBvdXRwdXQ7XG4gICAgdGhpcy5pbmNsdWRlUmF3Q2h1bmtzID0gaW5jbHVkZVJhd0NodW5rcztcbiAgICB0aGlzLnRvb2xzID0gdG9vbHM7XG5cbiAgICAvLyBwcm9taXNlIHRvIGVuc3VyZSB0aGF0IHRoZSBzdGVwIGhhcyBiZWVuIGZ1bGx5IHByb2Nlc3NlZCBieSB0aGUgZXZlbnQgcHJvY2Vzc29yXG4gICAgLy8gYmVmb3JlIGEgbmV3IHN0ZXAgaXMgc3RhcnRlZC4gVGhpcyBpcyByZXF1aXJlZCBiZWNhdXNlIHRoZSBjb250aW51YXRpb24gY29uZGl0aW9uXG4gICAgLy8gbmVlZHMgdGhlIHVwZGF0ZWQgc3RlcHMgdG8gZGV0ZXJtaW5lIGlmIGFub3RoZXIgc3RlcCBpcyBuZWVkZWQuXG4gICAgbGV0IHN0ZXBGaW5pc2ghOiBEZWxheWVkUHJvbWlzZTx2b2lkPjtcblxuICAgIGxldCByZWNvcmRlZENvbnRlbnQ6IEFycmF5PENvbnRlbnRQYXJ0PFRPT0xTPj4gPSBbXTtcbiAgICBjb25zdCByZWNvcmRlZFJlc3BvbnNlTWVzc2FnZXM6IEFycmF5PFJlc3BvbnNlTWVzc2FnZT4gPSBbXTtcbiAgICBsZXQgcmVjb3JkZWRGaW5pc2hSZWFzb246IEZpbmlzaFJlYXNvbiB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICBsZXQgcmVjb3JkZWRUb3RhbFVzYWdlOiBMYW5ndWFnZU1vZGVsVXNhZ2UgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgbGV0IHJlY29yZGVkUmVxdWVzdDogTGFuZ3VhZ2VNb2RlbFJlcXVlc3RNZXRhZGF0YSA9IHt9O1xuICAgIGxldCByZWNvcmRlZFdhcm5pbmdzOiBBcnJheTxDYWxsV2FybmluZz4gPSBbXTtcbiAgICBjb25zdCByZWNvcmRlZFN0ZXBzOiBTdGVwUmVzdWx0PFRPT0xTPltdID0gW107XG5cbiAgICBsZXQgcm9vdFNwYW4hOiBTcGFuO1xuXG4gICAgbGV0IGFjdGl2ZVRleHRDb250ZW50OiBSZWNvcmQ8XG4gICAgICBzdHJpbmcsXG4gICAgICB7XG4gICAgICAgIHR5cGU6ICd0ZXh0JztcbiAgICAgICAgdGV4dDogc3RyaW5nO1xuICAgICAgICBwcm92aWRlck1ldGFkYXRhOiBQcm92aWRlck1ldGFkYXRhIHwgdW5kZWZpbmVkO1xuICAgICAgfVxuICAgID4gPSB7fTtcblxuICAgIGxldCBhY3RpdmVSZWFzb25pbmdDb250ZW50OiBSZWNvcmQ8XG4gICAgICBzdHJpbmcsXG4gICAgICB7XG4gICAgICAgIHR5cGU6ICdyZWFzb25pbmcnO1xuICAgICAgICB0ZXh0OiBzdHJpbmc7XG4gICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IFByb3ZpZGVyTWV0YWRhdGEgfCB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgPiA9IHt9O1xuXG4gICAgY29uc3QgZXZlbnRQcm9jZXNzb3IgPSBuZXcgVHJhbnNmb3JtU3RyZWFtPFxuICAgICAgRW5yaWNoZWRTdHJlYW1QYXJ0PFRPT0xTLCBQQVJUSUFMX09VVFBVVD4sXG4gICAgICBFbnJpY2hlZFN0cmVhbVBhcnQ8VE9PTFMsIFBBUlRJQUxfT1VUUFVUPlxuICAgID4oe1xuICAgICAgYXN5bmMgdHJhbnNmb3JtKGNodW5rLCBjb250cm9sbGVyKSB7XG4gICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShjaHVuayk7IC8vIGZvcndhcmQgdGhlIGNodW5rIHRvIHRoZSBuZXh0IHN0cmVhbVxuXG4gICAgICAgIGNvbnN0IHsgcGFydCB9ID0gY2h1bms7XG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgIHBhcnQudHlwZSA9PT0gJ3RleHQtZGVsdGEnIHx8XG4gICAgICAgICAgcGFydC50eXBlID09PSAncmVhc29uaW5nLWRlbHRhJyB8fFxuICAgICAgICAgIHBhcnQudHlwZSA9PT0gJ3NvdXJjZScgfHxcbiAgICAgICAgICBwYXJ0LnR5cGUgPT09ICd0b29sLWNhbGwnIHx8XG4gICAgICAgICAgcGFydC50eXBlID09PSAndG9vbC1yZXN1bHQnIHx8XG4gICAgICAgICAgcGFydC50eXBlID09PSAndG9vbC1pbnB1dC1zdGFydCcgfHxcbiAgICAgICAgICBwYXJ0LnR5cGUgPT09ICd0b29sLWlucHV0LWRlbHRhJyB8fFxuICAgICAgICAgIHBhcnQudHlwZSA9PT0gJ3JhdydcbiAgICAgICAgKSB7XG4gICAgICAgICAgYXdhaXQgb25DaHVuaz8uKHsgY2h1bms6IHBhcnQgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocGFydC50eXBlID09PSAnZXJyb3InKSB7XG4gICAgICAgICAgYXdhaXQgb25FcnJvcih7IGVycm9yOiB3cmFwR2F0ZXdheUVycm9yKHBhcnQuZXJyb3IpIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBhcnQudHlwZSA9PT0gJ3RleHQtc3RhcnQnKSB7XG4gICAgICAgICAgYWN0aXZlVGV4dENvbnRlbnRbcGFydC5pZF0gPSB7XG4gICAgICAgICAgICB0eXBlOiAndGV4dCcsXG4gICAgICAgICAgICB0ZXh0OiAnJyxcbiAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHBhcnQucHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgcmVjb3JkZWRDb250ZW50LnB1c2goYWN0aXZlVGV4dENvbnRlbnRbcGFydC5pZF0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBhcnQudHlwZSA9PT0gJ3RleHQtZGVsdGEnKSB7XG4gICAgICAgICAgY29uc3QgYWN0aXZlVGV4dCA9IGFjdGl2ZVRleHRDb250ZW50W3BhcnQuaWRdO1xuXG4gICAgICAgICAgaWYgKGFjdGl2ZVRleHQgPT0gbnVsbCkge1xuICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHtcbiAgICAgICAgICAgICAgcGFydDoge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdlcnJvcicsXG4gICAgICAgICAgICAgICAgZXJyb3I6IGB0ZXh0IHBhcnQgJHtwYXJ0LmlkfSBub3QgZm91bmRgLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBwYXJ0aWFsT3V0cHV0OiB1bmRlZmluZWQsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBhY3RpdmVUZXh0LnRleHQgKz0gcGFydC50ZXh0O1xuICAgICAgICAgIGFjdGl2ZVRleHQucHJvdmlkZXJNZXRhZGF0YSA9XG4gICAgICAgICAgICBwYXJ0LnByb3ZpZGVyTWV0YWRhdGEgPz8gYWN0aXZlVGV4dC5wcm92aWRlck1ldGFkYXRhO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBhcnQudHlwZSA9PT0gJ3RleHQtZW5kJykge1xuICAgICAgICAgIGNvbnN0IGFjdGl2ZVRleHQgPSBhY3RpdmVUZXh0Q29udGVudFtwYXJ0LmlkXTtcblxuICAgICAgICAgIGlmIChhY3RpdmVUZXh0ID09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgIHBhcnQ6IHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnZXJyb3InLFxuICAgICAgICAgICAgICAgIGVycm9yOiBgdGV4dCBwYXJ0ICR7cGFydC5pZH0gbm90IGZvdW5kYCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgcGFydGlhbE91dHB1dDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYWN0aXZlVGV4dC5wcm92aWRlck1ldGFkYXRhID1cbiAgICAgICAgICAgIHBhcnQucHJvdmlkZXJNZXRhZGF0YSA/PyBhY3RpdmVUZXh0LnByb3ZpZGVyTWV0YWRhdGE7XG5cbiAgICAgICAgICBkZWxldGUgYWN0aXZlVGV4dENvbnRlbnRbcGFydC5pZF07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocGFydC50eXBlID09PSAncmVhc29uaW5nLXN0YXJ0Jykge1xuICAgICAgICAgIGFjdGl2ZVJlYXNvbmluZ0NvbnRlbnRbcGFydC5pZF0gPSB7XG4gICAgICAgICAgICB0eXBlOiAncmVhc29uaW5nJyxcbiAgICAgICAgICAgIHRleHQ6ICcnLFxuICAgICAgICAgICAgcHJvdmlkZXJNZXRhZGF0YTogcGFydC5wcm92aWRlck1ldGFkYXRhLFxuICAgICAgICAgIH07XG5cbiAgICAgICAgICByZWNvcmRlZENvbnRlbnQucHVzaChhY3RpdmVSZWFzb25pbmdDb250ZW50W3BhcnQuaWRdKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXJ0LnR5cGUgPT09ICdyZWFzb25pbmctZGVsdGEnKSB7XG4gICAgICAgICAgY29uc3QgYWN0aXZlUmVhc29uaW5nID0gYWN0aXZlUmVhc29uaW5nQ29udGVudFtwYXJ0LmlkXTtcblxuICAgICAgICAgIGlmIChhY3RpdmVSZWFzb25pbmcgPT0gbnVsbCkge1xuICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHtcbiAgICAgICAgICAgICAgcGFydDoge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdlcnJvcicsXG4gICAgICAgICAgICAgICAgZXJyb3I6IGByZWFzb25pbmcgcGFydCAke3BhcnQuaWR9IG5vdCBmb3VuZGAsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHBhcnRpYWxPdXRwdXQ6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGFjdGl2ZVJlYXNvbmluZy50ZXh0ICs9IHBhcnQudGV4dDtcbiAgICAgICAgICBhY3RpdmVSZWFzb25pbmcucHJvdmlkZXJNZXRhZGF0YSA9XG4gICAgICAgICAgICBwYXJ0LnByb3ZpZGVyTWV0YWRhdGEgPz8gYWN0aXZlUmVhc29uaW5nLnByb3ZpZGVyTWV0YWRhdGE7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocGFydC50eXBlID09PSAncmVhc29uaW5nLWVuZCcpIHtcbiAgICAgICAgICBjb25zdCBhY3RpdmVSZWFzb25pbmcgPSBhY3RpdmVSZWFzb25pbmdDb250ZW50W3BhcnQuaWRdO1xuXG4gICAgICAgICAgaWYgKGFjdGl2ZVJlYXNvbmluZyA9PSBudWxsKSB7XG4gICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgICBwYXJ0OiB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ2Vycm9yJyxcbiAgICAgICAgICAgICAgICBlcnJvcjogYHJlYXNvbmluZyBwYXJ0ICR7cGFydC5pZH0gbm90IGZvdW5kYCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgcGFydGlhbE91dHB1dDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYWN0aXZlUmVhc29uaW5nLnByb3ZpZGVyTWV0YWRhdGEgPVxuICAgICAgICAgICAgcGFydC5wcm92aWRlck1ldGFkYXRhID8/IGFjdGl2ZVJlYXNvbmluZy5wcm92aWRlck1ldGFkYXRhO1xuXG4gICAgICAgICAgZGVsZXRlIGFjdGl2ZVJlYXNvbmluZ0NvbnRlbnRbcGFydC5pZF07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocGFydC50eXBlID09PSAnZmlsZScpIHtcbiAgICAgICAgICByZWNvcmRlZENvbnRlbnQucHVzaCh7IHR5cGU6ICdmaWxlJywgZmlsZTogcGFydC5maWxlIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBhcnQudHlwZSA9PT0gJ3NvdXJjZScpIHtcbiAgICAgICAgICByZWNvcmRlZENvbnRlbnQucHVzaChwYXJ0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXJ0LnR5cGUgPT09ICd0b29sLWNhbGwnKSB7XG4gICAgICAgICAgcmVjb3JkZWRDb250ZW50LnB1c2gocGFydCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocGFydC50eXBlID09PSAndG9vbC1yZXN1bHQnICYmICFwYXJ0LnByZWxpbWluYXJ5KSB7XG4gICAgICAgICAgcmVjb3JkZWRDb250ZW50LnB1c2gocGFydCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocGFydC50eXBlID09PSAndG9vbC1lcnJvcicpIHtcbiAgICAgICAgICByZWNvcmRlZENvbnRlbnQucHVzaChwYXJ0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXJ0LnR5cGUgPT09ICdzdGFydC1zdGVwJykge1xuICAgICAgICAgIHJlY29yZGVkUmVxdWVzdCA9IHBhcnQucmVxdWVzdDtcbiAgICAgICAgICByZWNvcmRlZFdhcm5pbmdzID0gcGFydC53YXJuaW5ncztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXJ0LnR5cGUgPT09ICdmaW5pc2gtc3RlcCcpIHtcbiAgICAgICAgICBjb25zdCBzdGVwTWVzc2FnZXMgPSB0b1Jlc3BvbnNlTWVzc2FnZXMoe1xuICAgICAgICAgICAgY29udGVudDogcmVjb3JkZWRDb250ZW50LFxuICAgICAgICAgICAgdG9vbHMsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICAvLyBBZGQgc3RlcCBpbmZvcm1hdGlvbiAoYWZ0ZXIgcmVzcG9uc2UgbWVzc2FnZXMgYXJlIHVwZGF0ZWQpOlxuICAgICAgICAgIGNvbnN0IGN1cnJlbnRTdGVwUmVzdWx0OiBTdGVwUmVzdWx0PFRPT0xTPiA9IG5ldyBEZWZhdWx0U3RlcFJlc3VsdCh7XG4gICAgICAgICAgICBjb250ZW50OiByZWNvcmRlZENvbnRlbnQsXG4gICAgICAgICAgICBmaW5pc2hSZWFzb246IHBhcnQuZmluaXNoUmVhc29uLFxuICAgICAgICAgICAgdXNhZ2U6IHBhcnQudXNhZ2UsXG4gICAgICAgICAgICB3YXJuaW5nczogcmVjb3JkZWRXYXJuaW5ncyxcbiAgICAgICAgICAgIHJlcXVlc3Q6IHJlY29yZGVkUmVxdWVzdCxcbiAgICAgICAgICAgIHJlc3BvbnNlOiB7XG4gICAgICAgICAgICAgIC4uLnBhcnQucmVzcG9uc2UsXG4gICAgICAgICAgICAgIG1lc3NhZ2VzOiBbLi4ucmVjb3JkZWRSZXNwb25zZU1lc3NhZ2VzLCAuLi5zdGVwTWVzc2FnZXNdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHBhcnQucHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGF3YWl0IG9uU3RlcEZpbmlzaD8uKGN1cnJlbnRTdGVwUmVzdWx0KTtcblxuICAgICAgICAgIGxvZ1dhcm5pbmdzKHJlY29yZGVkV2FybmluZ3MpO1xuXG4gICAgICAgICAgcmVjb3JkZWRTdGVwcy5wdXNoKGN1cnJlbnRTdGVwUmVzdWx0KTtcblxuICAgICAgICAgIHJlY29yZGVkQ29udGVudCA9IFtdO1xuICAgICAgICAgIGFjdGl2ZVJlYXNvbmluZ0NvbnRlbnQgPSB7fTtcbiAgICAgICAgICBhY3RpdmVUZXh0Q29udGVudCA9IHt9O1xuXG4gICAgICAgICAgcmVjb3JkZWRSZXNwb25zZU1lc3NhZ2VzLnB1c2goLi4uc3RlcE1lc3NhZ2VzKTtcblxuICAgICAgICAgIC8vIHJlc29sdmUgdGhlIHByb21pc2UgdG8gc2lnbmFsIHRoYXQgdGhlIHN0ZXAgaGFzIGJlZW4gZnVsbHkgcHJvY2Vzc2VkXG4gICAgICAgICAgLy8gYnkgdGhlIGV2ZW50IHByb2Nlc3NvcjpcbiAgICAgICAgICBzdGVwRmluaXNoLnJlc29sdmUoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXJ0LnR5cGUgPT09ICdmaW5pc2gnKSB7XG4gICAgICAgICAgcmVjb3JkZWRUb3RhbFVzYWdlID0gcGFydC50b3RhbFVzYWdlO1xuICAgICAgICAgIHJlY29yZGVkRmluaXNoUmVhc29uID0gcGFydC5maW5pc2hSZWFzb247XG4gICAgICAgIH1cbiAgICAgIH0sXG5cbiAgICAgIGFzeW5jIGZsdXNoKGNvbnRyb2xsZXIpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBpZiAocmVjb3JkZWRTdGVwcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IE5vT3V0cHV0R2VuZXJhdGVkRXJyb3Ioe1xuICAgICAgICAgICAgICBtZXNzYWdlOiAnTm8gb3V0cHV0IGdlbmVyYXRlZC4gQ2hlY2sgdGhlIHN0cmVhbSBmb3IgZXJyb3JzLicsXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgc2VsZi5fZmluaXNoUmVhc29uLnJlamVjdChlcnJvcik7XG4gICAgICAgICAgICBzZWxmLl90b3RhbFVzYWdlLnJlamVjdChlcnJvcik7XG4gICAgICAgICAgICBzZWxmLl9zdGVwcy5yZWplY3QoZXJyb3IpO1xuXG4gICAgICAgICAgICByZXR1cm47IC8vIG5vIHN0ZXBzIHJlY29yZGVkIChlLmcuIGluIGVycm9yIHNjZW5hcmlvKVxuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIGRlcml2ZWQ6XG4gICAgICAgICAgY29uc3QgZmluaXNoUmVhc29uID0gcmVjb3JkZWRGaW5pc2hSZWFzb24gPz8gJ3Vua25vd24nO1xuICAgICAgICAgIGNvbnN0IHRvdGFsVXNhZ2UgPSByZWNvcmRlZFRvdGFsVXNhZ2UgPz8ge1xuICAgICAgICAgICAgaW5wdXRUb2tlbnM6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIG91dHB1dFRva2VuczogdW5kZWZpbmVkLFxuICAgICAgICAgICAgdG90YWxUb2tlbnM6IHVuZGVmaW5lZCxcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgLy8gZnJvbSBmaW5pc2g6XG4gICAgICAgICAgc2VsZi5fZmluaXNoUmVhc29uLnJlc29sdmUoZmluaXNoUmVhc29uKTtcbiAgICAgICAgICBzZWxmLl90b3RhbFVzYWdlLnJlc29sdmUodG90YWxVc2FnZSk7XG5cbiAgICAgICAgICAvLyBhZ2dyZWdhdGUgcmVzdWx0czpcbiAgICAgICAgICBzZWxmLl9zdGVwcy5yZXNvbHZlKHJlY29yZGVkU3RlcHMpO1xuXG4gICAgICAgICAgLy8gY2FsbCBvbkZpbmlzaCBjYWxsYmFjazpcbiAgICAgICAgICBjb25zdCBmaW5hbFN0ZXAgPSByZWNvcmRlZFN0ZXBzW3JlY29yZGVkU3RlcHMubGVuZ3RoIC0gMV07XG4gICAgICAgICAgYXdhaXQgb25GaW5pc2g/Lih7XG4gICAgICAgICAgICBmaW5pc2hSZWFzb24sXG4gICAgICAgICAgICB0b3RhbFVzYWdlLFxuICAgICAgICAgICAgdXNhZ2U6IGZpbmFsU3RlcC51c2FnZSxcbiAgICAgICAgICAgIGNvbnRlbnQ6IGZpbmFsU3RlcC5jb250ZW50LFxuICAgICAgICAgICAgdGV4dDogZmluYWxTdGVwLnRleHQsXG4gICAgICAgICAgICByZWFzb25pbmdUZXh0OiBmaW5hbFN0ZXAucmVhc29uaW5nVGV4dCxcbiAgICAgICAgICAgIHJlYXNvbmluZzogZmluYWxTdGVwLnJlYXNvbmluZyxcbiAgICAgICAgICAgIGZpbGVzOiBmaW5hbFN0ZXAuZmlsZXMsXG4gICAgICAgICAgICBzb3VyY2VzOiBmaW5hbFN0ZXAuc291cmNlcyxcbiAgICAgICAgICAgIHRvb2xDYWxsczogZmluYWxTdGVwLnRvb2xDYWxscyxcbiAgICAgICAgICAgIHN0YXRpY1Rvb2xDYWxsczogZmluYWxTdGVwLnN0YXRpY1Rvb2xDYWxscyxcbiAgICAgICAgICAgIGR5bmFtaWNUb29sQ2FsbHM6IGZpbmFsU3RlcC5keW5hbWljVG9vbENhbGxzLFxuICAgICAgICAgICAgdG9vbFJlc3VsdHM6IGZpbmFsU3RlcC50b29sUmVzdWx0cyxcbiAgICAgICAgICAgIHN0YXRpY1Rvb2xSZXN1bHRzOiBmaW5hbFN0ZXAuc3RhdGljVG9vbFJlc3VsdHMsXG4gICAgICAgICAgICBkeW5hbWljVG9vbFJlc3VsdHM6IGZpbmFsU3RlcC5keW5hbWljVG9vbFJlc3VsdHMsXG4gICAgICAgICAgICByZXF1ZXN0OiBmaW5hbFN0ZXAucmVxdWVzdCxcbiAgICAgICAgICAgIHJlc3BvbnNlOiBmaW5hbFN0ZXAucmVzcG9uc2UsXG4gICAgICAgICAgICB3YXJuaW5nczogZmluYWxTdGVwLndhcm5pbmdzLFxuICAgICAgICAgICAgcHJvdmlkZXJNZXRhZGF0YTogZmluYWxTdGVwLnByb3ZpZGVyTWV0YWRhdGEsXG4gICAgICAgICAgICBzdGVwczogcmVjb3JkZWRTdGVwcyxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIC8vIEFkZCByZXNwb25zZSBpbmZvcm1hdGlvbiB0byB0aGUgcm9vdCBzcGFuOlxuICAgICAgICAgIHJvb3RTcGFuLnNldEF0dHJpYnV0ZXMoXG4gICAgICAgICAgICBzZWxlY3RUZWxlbWV0cnlBdHRyaWJ1dGVzKHtcbiAgICAgICAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLmZpbmlzaFJlYXNvbic6IGZpbmlzaFJlYXNvbixcbiAgICAgICAgICAgICAgICAnYWkucmVzcG9uc2UudGV4dCc6IHsgb3V0cHV0OiAoKSA9PiBmaW5hbFN0ZXAudGV4dCB9LFxuICAgICAgICAgICAgICAgICdhaS5yZXNwb25zZS50b29sQ2FsbHMnOiB7XG4gICAgICAgICAgICAgICAgICBvdXRwdXQ6ICgpID0+XG4gICAgICAgICAgICAgICAgICAgIGZpbmFsU3RlcC50b29sQ2FsbHM/Lmxlbmd0aFxuICAgICAgICAgICAgICAgICAgICAgID8gSlNPTi5zdHJpbmdpZnkoZmluYWxTdGVwLnRvb2xDYWxscylcbiAgICAgICAgICAgICAgICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICdhaS5yZXNwb25zZS5wcm92aWRlck1ldGFkYXRhJzogSlNPTi5zdHJpbmdpZnkoXG4gICAgICAgICAgICAgICAgICBmaW5hbFN0ZXAucHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgICAgICAgICApLFxuXG4gICAgICAgICAgICAgICAgJ2FpLnVzYWdlLmlucHV0VG9rZW5zJzogdG90YWxVc2FnZS5pbnB1dFRva2VucyxcbiAgICAgICAgICAgICAgICAnYWkudXNhZ2Uub3V0cHV0VG9rZW5zJzogdG90YWxVc2FnZS5vdXRwdXRUb2tlbnMsXG4gICAgICAgICAgICAgICAgJ2FpLnVzYWdlLnRvdGFsVG9rZW5zJzogdG90YWxVc2FnZS50b3RhbFRva2VucyxcbiAgICAgICAgICAgICAgICAnYWkudXNhZ2UucmVhc29uaW5nVG9rZW5zJzogdG90YWxVc2FnZS5yZWFzb25pbmdUb2tlbnMsXG4gICAgICAgICAgICAgICAgJ2FpLnVzYWdlLmNhY2hlZElucHV0VG9rZW5zJzogdG90YWxVc2FnZS5jYWNoZWRJbnB1dFRva2VucyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgY29udHJvbGxlci5lcnJvcihlcnJvcik7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgcm9vdFNwYW4uZW5kKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICAvLyBpbml0aWFsaXplIHRoZSBzdGl0Y2hhYmxlIHN0cmVhbSBhbmQgdGhlIHRyYW5zZm9ybWVkIHN0cmVhbTpcbiAgICBjb25zdCBzdGl0Y2hhYmxlU3RyZWFtID0gY3JlYXRlU3RpdGNoYWJsZVN0cmVhbTxUZXh0U3RyZWFtUGFydDxUT09MUz4+KCk7XG4gICAgdGhpcy5hZGRTdHJlYW0gPSBzdGl0Y2hhYmxlU3RyZWFtLmFkZFN0cmVhbTtcbiAgICB0aGlzLmNsb3NlU3RyZWFtID0gc3RpdGNoYWJsZVN0cmVhbS5jbG9zZTtcblxuICAgIC8vIHJlc2lsaWVudCBzdHJlYW0gdGhhdCBoYW5kbGVzIGFib3J0IHNpZ25hbHMgYW5kIGVycm9yczpcbiAgICBjb25zdCByZWFkZXIgPSBzdGl0Y2hhYmxlU3RyZWFtLnN0cmVhbS5nZXRSZWFkZXIoKTtcbiAgICBsZXQgc3RyZWFtID0gbmV3IFJlYWRhYmxlU3RyZWFtPFRleHRTdHJlYW1QYXJ0PFRPT0xTPj4oe1xuICAgICAgYXN5bmMgc3RhcnQoY29udHJvbGxlcikge1xuICAgICAgICAvLyBzZW5kIHN0YXJ0IGV2ZW50OlxuICAgICAgICBjb250cm9sbGVyLmVucXVldWUoeyB0eXBlOiAnc3RhcnQnIH0pO1xuICAgICAgfSxcblxuICAgICAgYXN5bmMgcHVsbChjb250cm9sbGVyKSB7XG4gICAgICAgIC8vIGFib3J0IGhhbmRsaW5nOlxuICAgICAgICBmdW5jdGlvbiBhYm9ydCgpIHtcbiAgICAgICAgICBvbkFib3J0Py4oeyBzdGVwczogcmVjb3JkZWRTdGVwcyB9KTtcbiAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoeyB0eXBlOiAnYWJvcnQnIH0pO1xuICAgICAgICAgIGNvbnRyb2xsZXIuY2xvc2UoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgeyBkb25lLCB2YWx1ZSB9ID0gYXdhaXQgcmVhZGVyLnJlYWQoKTtcblxuICAgICAgICAgIGlmIChkb25lKSB7XG4gICAgICAgICAgICBjb250cm9sbGVyLmNsb3NlKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGFib3J0U2lnbmFsPy5hYm9ydGVkKSB7XG4gICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh2YWx1ZSk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgaWYgKGlzQWJvcnRFcnJvcihlcnJvcikgJiYgYWJvcnRTaWduYWw/LmFib3J0ZWQpIHtcbiAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnRyb2xsZXIuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSxcblxuICAgICAgY2FuY2VsKHJlYXNvbikge1xuICAgICAgICByZXR1cm4gc3RpdGNoYWJsZVN0cmVhbS5zdHJlYW0uY2FuY2VsKHJlYXNvbik7XG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgLy8gdHJhbnNmb3JtIHRoZSBzdHJlYW0gYmVmb3JlIG91dHB1dCBwYXJzaW5nXG4gICAgLy8gdG8gZW5hYmxlIHJlcGxhY2VtZW50IG9mIHN0cmVhbSBzZWdtZW50czpcbiAgICBmb3IgKGNvbnN0IHRyYW5zZm9ybSBvZiB0cmFuc2Zvcm1zKSB7XG4gICAgICBzdHJlYW0gPSBzdHJlYW0ucGlwZVRocm91Z2goXG4gICAgICAgIHRyYW5zZm9ybSh7XG4gICAgICAgICAgdG9vbHM6IHRvb2xzIGFzIFRPT0xTLFxuICAgICAgICAgIHN0b3BTdHJlYW0oKSB7XG4gICAgICAgICAgICBzdGl0Y2hhYmxlU3RyZWFtLnRlcm1pbmF0ZSgpO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICB0aGlzLmJhc2VTdHJlYW0gPSBzdHJlYW1cbiAgICAgIC5waXBlVGhyb3VnaChjcmVhdGVPdXRwdXRUcmFuc2Zvcm1TdHJlYW0ob3V0cHV0KSlcbiAgICAgIC5waXBlVGhyb3VnaChldmVudFByb2Nlc3Nvcik7XG5cbiAgICBjb25zdCB7IG1heFJldHJpZXMsIHJldHJ5IH0gPSBwcmVwYXJlUmV0cmllcyh7XG4gICAgICBtYXhSZXRyaWVzOiBtYXhSZXRyaWVzQXJnLFxuICAgICAgYWJvcnRTaWduYWwsXG4gICAgfSk7XG5cbiAgICBjb25zdCB0cmFjZXIgPSBnZXRUcmFjZXIodGVsZW1ldHJ5KTtcblxuICAgIGNvbnN0IGNhbGxTZXR0aW5ncyA9IHByZXBhcmVDYWxsU2V0dGluZ3Moc2V0dGluZ3MpO1xuXG4gICAgY29uc3QgYmFzZVRlbGVtZXRyeUF0dHJpYnV0ZXMgPSBnZXRCYXNlVGVsZW1ldHJ5QXR0cmlidXRlcyh7XG4gICAgICBtb2RlbCxcbiAgICAgIHRlbGVtZXRyeSxcbiAgICAgIGhlYWRlcnMsXG4gICAgICBzZXR0aW5nczogeyAuLi5jYWxsU2V0dGluZ3MsIG1heFJldHJpZXMgfSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgcmVjb3JkU3Bhbih7XG4gICAgICBuYW1lOiAnYWkuc3RyZWFtVGV4dCcsXG4gICAgICBhdHRyaWJ1dGVzOiBzZWxlY3RUZWxlbWV0cnlBdHRyaWJ1dGVzKHtcbiAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgLi4uYXNzZW1ibGVPcGVyYXRpb25OYW1lKHsgb3BlcmF0aW9uSWQ6ICdhaS5zdHJlYW1UZXh0JywgdGVsZW1ldHJ5IH0pLFxuICAgICAgICAgIC4uLmJhc2VUZWxlbWV0cnlBdHRyaWJ1dGVzLFxuICAgICAgICAgIC8vIHNwZWNpZmljIHNldHRpbmdzIHRoYXQgb25seSBtYWtlIHNlbnNlIG9uIHRoZSBvdXRlciBsZXZlbDpcbiAgICAgICAgICAnYWkucHJvbXB0Jzoge1xuICAgICAgICAgICAgaW5wdXQ6ICgpID0+IEpTT04uc3RyaW5naWZ5KHsgc3lzdGVtLCBwcm9tcHQsIG1lc3NhZ2VzIH0pLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KSxcbiAgICAgIHRyYWNlcixcbiAgICAgIGVuZFdoZW5Eb25lOiBmYWxzZSxcbiAgICAgIGZuOiBhc3luYyByb290U3BhbkFyZyA9PiB7XG4gICAgICAgIHJvb3RTcGFuID0gcm9vdFNwYW5Bcmc7XG5cbiAgICAgICAgYXN5bmMgZnVuY3Rpb24gc3RyZWFtU3RlcCh7XG4gICAgICAgICAgY3VycmVudFN0ZXAsXG4gICAgICAgICAgcmVzcG9uc2VNZXNzYWdlcyxcbiAgICAgICAgICB1c2FnZSxcbiAgICAgICAgfToge1xuICAgICAgICAgIGN1cnJlbnRTdGVwOiBudW1iZXI7XG4gICAgICAgICAgcmVzcG9uc2VNZXNzYWdlczogQXJyYXk8UmVzcG9uc2VNZXNzYWdlPjtcbiAgICAgICAgICB1c2FnZTogTGFuZ3VhZ2VNb2RlbFVzYWdlO1xuICAgICAgICB9KSB7XG4gICAgICAgICAgY29uc3QgaW5jbHVkZVJhd0NodW5rcyA9IHNlbGYuaW5jbHVkZVJhd0NodW5rcztcblxuICAgICAgICAgIHN0ZXBGaW5pc2ggPSBuZXcgRGVsYXllZFByb21pc2U8dm9pZD4oKTtcblxuICAgICAgICAgIGNvbnN0IGluaXRpYWxQcm9tcHQgPSBhd2FpdCBzdGFuZGFyZGl6ZVByb21wdCh7XG4gICAgICAgICAgICBzeXN0ZW0sXG4gICAgICAgICAgICBwcm9tcHQsXG4gICAgICAgICAgICBtZXNzYWdlcyxcbiAgICAgICAgICB9IGFzIFByb21wdCk7XG5cbiAgICAgICAgICBjb25zdCBzdGVwSW5wdXRNZXNzYWdlcyA9IFtcbiAgICAgICAgICAgIC4uLmluaXRpYWxQcm9tcHQubWVzc2FnZXMsXG4gICAgICAgICAgICAuLi5yZXNwb25zZU1lc3NhZ2VzLFxuICAgICAgICAgIF07XG5cbiAgICAgICAgICBjb25zdCBwcmVwYXJlU3RlcFJlc3VsdCA9IGF3YWl0IHByZXBhcmVTdGVwPy4oe1xuICAgICAgICAgICAgbW9kZWwsXG4gICAgICAgICAgICBzdGVwczogcmVjb3JkZWRTdGVwcyxcbiAgICAgICAgICAgIHN0ZXBOdW1iZXI6IHJlY29yZGVkU3RlcHMubGVuZ3RoLFxuICAgICAgICAgICAgbWVzc2FnZXM6IHN0ZXBJbnB1dE1lc3NhZ2VzLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY29uc3Qgc3RlcE1vZGVsID0gcmVzb2x2ZUxhbmd1YWdlTW9kZWwoXG4gICAgICAgICAgICBwcmVwYXJlU3RlcFJlc3VsdD8ubW9kZWwgPz8gbW9kZWwsXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGNvbnN0IHByb21wdE1lc3NhZ2VzID0gYXdhaXQgY29udmVydFRvTGFuZ3VhZ2VNb2RlbFByb21wdCh7XG4gICAgICAgICAgICBwcm9tcHQ6IHtcbiAgICAgICAgICAgICAgc3lzdGVtOiBwcmVwYXJlU3RlcFJlc3VsdD8uc3lzdGVtID8/IGluaXRpYWxQcm9tcHQuc3lzdGVtLFxuICAgICAgICAgICAgICBtZXNzYWdlczogcHJlcGFyZVN0ZXBSZXN1bHQ/Lm1lc3NhZ2VzID8/IHN0ZXBJbnB1dE1lc3NhZ2VzLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHN1cHBvcnRlZFVybHM6IGF3YWl0IHN0ZXBNb2RlbC5zdXBwb3J0ZWRVcmxzLFxuICAgICAgICAgICAgZG93bmxvYWQsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCB7IHRvb2xDaG9pY2U6IHN0ZXBUb29sQ2hvaWNlLCB0b29sczogc3RlcFRvb2xzIH0gPVxuICAgICAgICAgICAgcHJlcGFyZVRvb2xzQW5kVG9vbENob2ljZSh7XG4gICAgICAgICAgICAgIHRvb2xzLFxuICAgICAgICAgICAgICB0b29sQ2hvaWNlOiBwcmVwYXJlU3RlcFJlc3VsdD8udG9vbENob2ljZSA/PyB0b29sQ2hvaWNlLFxuICAgICAgICAgICAgICBhY3RpdmVUb29sczogcHJlcGFyZVN0ZXBSZXN1bHQ/LmFjdGl2ZVRvb2xzID8/IGFjdGl2ZVRvb2xzLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICByZXN1bHQ6IHsgc3RyZWFtLCByZXNwb25zZSwgcmVxdWVzdCB9LFxuICAgICAgICAgICAgZG9TdHJlYW1TcGFuLFxuICAgICAgICAgICAgc3RhcnRUaW1lc3RhbXBNcyxcbiAgICAgICAgICB9ID0gYXdhaXQgcmV0cnkoKCkgPT5cbiAgICAgICAgICAgIHJlY29yZFNwYW4oe1xuICAgICAgICAgICAgICBuYW1lOiAnYWkuc3RyZWFtVGV4dC5kb1N0cmVhbScsXG4gICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgICAgIHRlbGVtZXRyeSxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgICAgICAgICAuLi5hc3NlbWJsZU9wZXJhdGlvbk5hbWUoe1xuICAgICAgICAgICAgICAgICAgICBvcGVyYXRpb25JZDogJ2FpLnN0cmVhbVRleHQuZG9TdHJlYW0nLFxuICAgICAgICAgICAgICAgICAgICB0ZWxlbWV0cnksXG4gICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgIC4uLmJhc2VUZWxlbWV0cnlBdHRyaWJ1dGVzLFxuICAgICAgICAgICAgICAgICAgLy8gbW9kZWw6XG4gICAgICAgICAgICAgICAgICAnYWkubW9kZWwucHJvdmlkZXInOiBzdGVwTW9kZWwucHJvdmlkZXIsXG4gICAgICAgICAgICAgICAgICAnYWkubW9kZWwuaWQnOiBzdGVwTW9kZWwubW9kZWxJZCxcbiAgICAgICAgICAgICAgICAgIC8vIHByb21wdDpcbiAgICAgICAgICAgICAgICAgICdhaS5wcm9tcHQubWVzc2FnZXMnOiB7XG4gICAgICAgICAgICAgICAgICAgIGlucHV0OiAoKSA9PiBzdHJpbmdpZnlGb3JUZWxlbWV0cnkocHJvbXB0TWVzc2FnZXMpLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICdhaS5wcm9tcHQudG9vbHMnOiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGNvbnZlcnQgdGhlIGxhbmd1YWdlIG1vZGVsIGxldmVsIHRvb2xzOlxuICAgICAgICAgICAgICAgICAgICBpbnB1dDogKCkgPT4gc3RlcFRvb2xzPy5tYXAodG9vbCA9PiBKU09OLnN0cmluZ2lmeSh0b29sKSksXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgJ2FpLnByb21wdC50b29sQ2hvaWNlJzoge1xuICAgICAgICAgICAgICAgICAgICBpbnB1dDogKCkgPT5cbiAgICAgICAgICAgICAgICAgICAgICBzdGVwVG9vbENob2ljZSAhPSBudWxsXG4gICAgICAgICAgICAgICAgICAgICAgICA/IEpTT04uc3RyaW5naWZ5KHN0ZXBUb29sQ2hvaWNlKVxuICAgICAgICAgICAgICAgICAgICAgICAgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAgICAgICAvLyBzdGFuZGFyZGl6ZWQgZ2VuLWFpIGxsbSBzcGFuIGF0dHJpYnV0ZXM6XG4gICAgICAgICAgICAgICAgICAnZ2VuX2FpLnN5c3RlbSc6IHN0ZXBNb2RlbC5wcm92aWRlcixcbiAgICAgICAgICAgICAgICAgICdnZW5fYWkucmVxdWVzdC5tb2RlbCc6IHN0ZXBNb2RlbC5tb2RlbElkLFxuICAgICAgICAgICAgICAgICAgJ2dlbl9haS5yZXF1ZXN0LmZyZXF1ZW5jeV9wZW5hbHR5JzpcbiAgICAgICAgICAgICAgICAgICAgY2FsbFNldHRpbmdzLmZyZXF1ZW5jeVBlbmFsdHksXG4gICAgICAgICAgICAgICAgICAnZ2VuX2FpLnJlcXVlc3QubWF4X3Rva2Vucyc6IGNhbGxTZXR0aW5ncy5tYXhPdXRwdXRUb2tlbnMsXG4gICAgICAgICAgICAgICAgICAnZ2VuX2FpLnJlcXVlc3QucHJlc2VuY2VfcGVuYWx0eSc6XG4gICAgICAgICAgICAgICAgICAgIGNhbGxTZXR0aW5ncy5wcmVzZW5jZVBlbmFsdHksXG4gICAgICAgICAgICAgICAgICAnZ2VuX2FpLnJlcXVlc3Quc3RvcF9zZXF1ZW5jZXMnOiBjYWxsU2V0dGluZ3Muc3RvcFNlcXVlbmNlcyxcbiAgICAgICAgICAgICAgICAgICdnZW5fYWkucmVxdWVzdC50ZW1wZXJhdHVyZSc6IGNhbGxTZXR0aW5ncy50ZW1wZXJhdHVyZSxcbiAgICAgICAgICAgICAgICAgICdnZW5fYWkucmVxdWVzdC50b3Bfayc6IGNhbGxTZXR0aW5ncy50b3BLLFxuICAgICAgICAgICAgICAgICAgJ2dlbl9haS5yZXF1ZXN0LnRvcF9wJzogY2FsbFNldHRpbmdzLnRvcFAsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIHRyYWNlcixcbiAgICAgICAgICAgICAgZW5kV2hlbkRvbmU6IGZhbHNlLFxuICAgICAgICAgICAgICBmbjogYXN5bmMgZG9TdHJlYW1TcGFuID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgc3RhcnRUaW1lc3RhbXBNczogbm93KCksIC8vIGdldCBiZWZvcmUgdGhlIGNhbGxcbiAgICAgICAgICAgICAgICAgIGRvU3RyZWFtU3BhbixcbiAgICAgICAgICAgICAgICAgIHJlc3VsdDogYXdhaXQgc3RlcE1vZGVsLmRvU3RyZWFtKHtcbiAgICAgICAgICAgICAgICAgICAgLi4uY2FsbFNldHRpbmdzLFxuICAgICAgICAgICAgICAgICAgICB0b29sczogc3RlcFRvb2xzLFxuICAgICAgICAgICAgICAgICAgICB0b29sQ2hvaWNlOiBzdGVwVG9vbENob2ljZSxcbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2VGb3JtYXQ6IG91dHB1dD8ucmVzcG9uc2VGb3JtYXQsXG4gICAgICAgICAgICAgICAgICAgIHByb21wdDogcHJvbXB0TWVzc2FnZXMsXG4gICAgICAgICAgICAgICAgICAgIHByb3ZpZGVyT3B0aW9ucyxcbiAgICAgICAgICAgICAgICAgICAgYWJvcnRTaWduYWwsXG4gICAgICAgICAgICAgICAgICAgIGhlYWRlcnMsXG4gICAgICAgICAgICAgICAgICAgIGluY2x1ZGVSYXdDaHVua3MsXG4gICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGNvbnN0IHN0cmVhbVdpdGhUb29sUmVzdWx0cyA9IHJ1blRvb2xzVHJhbnNmb3JtYXRpb24oe1xuICAgICAgICAgICAgdG9vbHMsXG4gICAgICAgICAgICBnZW5lcmF0b3JTdHJlYW06IHN0cmVhbSxcbiAgICAgICAgICAgIHRyYWNlcixcbiAgICAgICAgICAgIHRlbGVtZXRyeSxcbiAgICAgICAgICAgIHN5c3RlbSxcbiAgICAgICAgICAgIG1lc3NhZ2VzOiBzdGVwSW5wdXRNZXNzYWdlcyxcbiAgICAgICAgICAgIHJlcGFpclRvb2xDYWxsLFxuICAgICAgICAgICAgYWJvcnRTaWduYWwsXG4gICAgICAgICAgICBleHBlcmltZW50YWxfY29udGV4dCxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNvbnN0IHN0ZXBSZXF1ZXN0ID0gcmVxdWVzdCA/PyB7fTtcbiAgICAgICAgICBjb25zdCBzdGVwVG9vbENhbGxzOiBUeXBlZFRvb2xDYWxsPFRPT0xTPltdID0gW107XG4gICAgICAgICAgY29uc3Qgc3RlcFRvb2xPdXRwdXRzOiBUb29sT3V0cHV0PFRPT0xTPltdID0gW107XG4gICAgICAgICAgbGV0IHdhcm5pbmdzOiBMYW5ndWFnZU1vZGVsVjJDYWxsV2FybmluZ1tdIHwgdW5kZWZpbmVkO1xuXG4gICAgICAgICAgY29uc3QgYWN0aXZlVG9vbENhbGxUb29sTmFtZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcblxuICAgICAgICAgIGxldCBzdGVwRmluaXNoUmVhc29uOiBGaW5pc2hSZWFzb24gPSAndW5rbm93bic7XG4gICAgICAgICAgbGV0IHN0ZXBVc2FnZTogTGFuZ3VhZ2VNb2RlbFVzYWdlID0ge1xuICAgICAgICAgICAgaW5wdXRUb2tlbnM6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIG91dHB1dFRva2VuczogdW5kZWZpbmVkLFxuICAgICAgICAgICAgdG90YWxUb2tlbnM6IHVuZGVmaW5lZCxcbiAgICAgICAgICB9O1xuICAgICAgICAgIGxldCBzdGVwUHJvdmlkZXJNZXRhZGF0YTogUHJvdmlkZXJNZXRhZGF0YSB8IHVuZGVmaW5lZDtcbiAgICAgICAgICBsZXQgc3RlcEZpcnN0Q2h1bmsgPSB0cnVlO1xuICAgICAgICAgIGxldCBzdGVwUmVzcG9uc2U6IHsgaWQ6IHN0cmluZzsgdGltZXN0YW1wOiBEYXRlOyBtb2RlbElkOiBzdHJpbmcgfSA9IHtcbiAgICAgICAgICAgIGlkOiBnZW5lcmF0ZUlkKCksXG4gICAgICAgICAgICB0aW1lc3RhbXA6IGN1cnJlbnREYXRlKCksXG4gICAgICAgICAgICBtb2RlbElkOiBtb2RlbC5tb2RlbElkLFxuICAgICAgICAgIH07XG5cbiAgICAgICAgICAvLyByYXcgdGV4dCBhcyBpdCBjb21lcyBmcm9tIHRoZSBwcm92aWRlci4gcmVjb3JkZWQgZm9yIHRlbGVtZXRyeS5cbiAgICAgICAgICBsZXQgYWN0aXZlVGV4dCA9ICcnO1xuXG4gICAgICAgICAgc2VsZi5hZGRTdHJlYW0oXG4gICAgICAgICAgICBzdHJlYW1XaXRoVG9vbFJlc3VsdHMucGlwZVRocm91Z2goXG4gICAgICAgICAgICAgIG5ldyBUcmFuc2Zvcm1TdHJlYW08XG4gICAgICAgICAgICAgICAgU2luZ2xlUmVxdWVzdFRleHRTdHJlYW1QYXJ0PFRPT0xTPixcbiAgICAgICAgICAgICAgICBUZXh0U3RyZWFtUGFydDxUT09MUz5cbiAgICAgICAgICAgICAgPih7XG4gICAgICAgICAgICAgICAgYXN5bmMgdHJhbnNmb3JtKGNodW5rLCBjb250cm9sbGVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgICAgICAgICAgICBpZiAoY2h1bmsudHlwZSA9PT0gJ3N0cmVhbS1zdGFydCcpIHtcbiAgICAgICAgICAgICAgICAgICAgd2FybmluZ3MgPSBjaHVuay53YXJuaW5ncztcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOyAvLyBzdHJlYW0gc3RhcnQgY2h1bmtzIGFyZSBzZW50IGltbWVkaWF0ZWx5IGFuZCBkbyBub3QgY291bnQgYXMgZmlyc3QgY2h1bmtcbiAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgaWYgKHN0ZXBGaXJzdENodW5rKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFRlbGVtZXRyeSBmb3IgZmlyc3QgY2h1bms6XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG1zVG9GaXJzdENodW5rID0gbm93KCkgLSBzdGFydFRpbWVzdGFtcE1zO1xuXG4gICAgICAgICAgICAgICAgICAgIHN0ZXBGaXJzdENodW5rID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICAgICAgZG9TdHJlYW1TcGFuLmFkZEV2ZW50KCdhaS5zdHJlYW0uZmlyc3RDaHVuaycsIHtcbiAgICAgICAgICAgICAgICAgICAgICAnYWkucmVzcG9uc2UubXNUb0ZpcnN0Q2h1bmsnOiBtc1RvRmlyc3RDaHVuayxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgZG9TdHJlYW1TcGFuLnNldEF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgICAgICAgICAgICdhaS5yZXNwb25zZS5tc1RvRmlyc3RDaHVuayc6IG1zVG9GaXJzdENodW5rLFxuICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBTdGVwIHN0YXJ0OlxuICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdzdGFydC1zdGVwJyxcbiAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0OiBzdGVwUmVxdWVzdCxcbiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nczogd2FybmluZ3MgPz8gW10sXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICBjb25zdCBjaHVua1R5cGUgPSBjaHVuay50eXBlO1xuICAgICAgICAgICAgICAgICAgc3dpdGNoIChjaHVua1R5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAndGV4dC1zdGFydCc6XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3RleHQtZW5kJzoge1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShjaHVuayk7XG4gICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjYXNlICd0ZXh0LWRlbHRhJzoge1xuICAgICAgICAgICAgICAgICAgICAgIGlmIChjaHVuay5kZWx0YS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAndGV4dC1kZWx0YScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlkOiBjaHVuay5pZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dDogY2h1bmsuZGVsdGEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IGNodW5rLnByb3ZpZGVyTWV0YWRhdGEsXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFjdGl2ZVRleHQgKz0gY2h1bmsuZGVsdGE7XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgY2FzZSAncmVhc29uaW5nLXN0YXJ0JzpcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAncmVhc29uaW5nLWVuZCc6IHtcbiAgICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoY2h1bmspO1xuICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgY2FzZSAncmVhc29uaW5nLWRlbHRhJzoge1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAncmVhc29uaW5nLWRlbHRhJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlkOiBjaHVuay5pZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHQ6IGNodW5rLmRlbHRhLFxuICAgICAgICAgICAgICAgICAgICAgICAgcHJvdmlkZXJNZXRhZGF0YTogY2h1bmsucHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3Rvb2wtY2FsbCc6IHtcbiAgICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoY2h1bmspO1xuICAgICAgICAgICAgICAgICAgICAgIC8vIHN0b3JlIHRvb2wgY2FsbHMgZm9yIG9uRmluaXNoIGNhbGxiYWNrIGFuZCB0b29sQ2FsbHMgcHJvbWlzZTpcbiAgICAgICAgICAgICAgICAgICAgICBzdGVwVG9vbENhbGxzLnB1c2goY2h1bmspO1xuICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgY2FzZSAndG9vbC1yZXN1bHQnOiB7XG4gICAgICAgICAgICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKGNodW5rKTtcblxuICAgICAgICAgICAgICAgICAgICAgIGlmICghY2h1bmsucHJlbGltaW5hcnkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0ZXBUb29sT3V0cHV0cy5wdXNoKGNodW5rKTtcbiAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3Rvb2wtZXJyb3InOiB7XG4gICAgICAgICAgICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKGNodW5rKTtcbiAgICAgICAgICAgICAgICAgICAgICBzdGVwVG9vbE91dHB1dHMucHVzaChjaHVuayk7XG4gICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjYXNlICdyZXNwb25zZS1tZXRhZGF0YSc6IHtcbiAgICAgICAgICAgICAgICAgICAgICBzdGVwUmVzcG9uc2UgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZDogY2h1bmsuaWQgPz8gc3RlcFJlc3BvbnNlLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGltZXN0YW1wOiBjaHVuay50aW1lc3RhbXAgPz8gc3RlcFJlc3BvbnNlLnRpbWVzdGFtcCxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1vZGVsSWQ6IGNodW5rLm1vZGVsSWQgPz8gc3RlcFJlc3BvbnNlLm1vZGVsSWQsXG4gICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2ZpbmlzaCc6IHtcbiAgICAgICAgICAgICAgICAgICAgICAvLyBOb3RlOiB0b29sIGV4ZWN1dGlvbnMgbWlnaHQgbm90IGJlIGZpbmlzaGVkIHlldCB3aGVuIHRoZSBmaW5pc2ggZXZlbnQgaXMgZW1pdHRlZC5cbiAgICAgICAgICAgICAgICAgICAgICAvLyBzdG9yZSB1c2FnZSBhbmQgZmluaXNoIHJlYXNvbiBmb3IgcHJvbWlzZXMgYW5kIG9uRmluaXNoIGNhbGxiYWNrOlxuICAgICAgICAgICAgICAgICAgICAgIHN0ZXBVc2FnZSA9IGNodW5rLnVzYWdlO1xuICAgICAgICAgICAgICAgICAgICAgIHN0ZXBGaW5pc2hSZWFzb24gPSBjaHVuay5maW5pc2hSZWFzb247XG4gICAgICAgICAgICAgICAgICAgICAgc3RlcFByb3ZpZGVyTWV0YWRhdGEgPSBjaHVuay5wcm92aWRlck1ldGFkYXRhO1xuXG4gICAgICAgICAgICAgICAgICAgICAgLy8gVGVsZW1ldHJ5IGZvciBmaW5pc2ggZXZlbnQgdGltaW5nXG4gICAgICAgICAgICAgICAgICAgICAgLy8gKHNpbmNlIHRvb2wgZXhlY3V0aW9ucyBjYW4gdGFrZSBsb25nZXIgYW5kIGRpc3RvcnQgY2FsY3VsYXRpb25zKVxuICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1zVG9GaW5pc2ggPSBub3coKSAtIHN0YXJ0VGltZXN0YW1wTXM7XG4gICAgICAgICAgICAgICAgICAgICAgZG9TdHJlYW1TcGFuLmFkZEV2ZW50KCdhaS5zdHJlYW0uZmluaXNoJyk7XG4gICAgICAgICAgICAgICAgICAgICAgZG9TdHJlYW1TcGFuLnNldEF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLm1zVG9GaW5pc2gnOiBtc1RvRmluaXNoLFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLmF2Z091dHB1dFRva2Vuc1BlclNlY29uZCc6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICgxMDAwICogKHN0ZXBVc2FnZS5vdXRwdXRUb2tlbnMgPz8gMCkpIC8gbXNUb0ZpbmlzaCxcbiAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnZmlsZSc6IHtcbiAgICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoY2h1bmspO1xuICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnc291cmNlJzoge1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShjaHVuayk7XG4gICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjYXNlICd0b29sLWlucHV0LXN0YXJ0Jzoge1xuICAgICAgICAgICAgICAgICAgICAgIGFjdGl2ZVRvb2xDYWxsVG9vbE5hbWVzW2NodW5rLmlkXSA9IGNodW5rLnRvb2xOYW1lO1xuXG4gICAgICAgICAgICAgICAgICAgICAgY29uc3QgdG9vbCA9IHRvb2xzPy5bY2h1bmsudG9vbE5hbWVdO1xuICAgICAgICAgICAgICAgICAgICAgIGlmICh0b29sPy5vbklucHV0U3RhcnQgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgdG9vbC5vbklucHV0U3RhcnQoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICB0b29sQ2FsbElkOiBjaHVuay5pZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZXM6IHN0ZXBJbnB1dE1lc3NhZ2VzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBhYm9ydFNpZ25hbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwZXJpbWVudGFsX2NvbnRleHQsXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgICAgICAgICAgICAgLi4uY2h1bmssXG4gICAgICAgICAgICAgICAgICAgICAgICBkeW5hbWljOiB0b29sPy50eXBlID09PSAnZHluYW1pYycsXG4gICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjYXNlICd0b29sLWlucHV0LWVuZCc6IHtcbiAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgYWN0aXZlVG9vbENhbGxUb29sTmFtZXNbY2h1bmsuaWRdO1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShjaHVuayk7XG4gICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjYXNlICd0b29sLWlucHV0LWRlbHRhJzoge1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRvb2xOYW1lID0gYWN0aXZlVG9vbENhbGxUb29sTmFtZXNbY2h1bmsuaWRdO1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRvb2wgPSB0b29scz8uW3Rvb2xOYW1lXTtcblxuICAgICAgICAgICAgICAgICAgICAgIGlmICh0b29sPy5vbklucHV0RGVsdGEgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgdG9vbC5vbklucHV0RGVsdGEoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dFRleHREZWx0YTogY2h1bmsuZGVsdGEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IGNodW5rLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlczogc3RlcElucHV0TWVzc2FnZXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0U2lnbmFsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBleHBlcmltZW50YWxfY29udGV4dCxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShjaHVuayk7XG4gICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjYXNlICdlcnJvcic6IHtcbiAgICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoY2h1bmspO1xuICAgICAgICAgICAgICAgICAgICAgIHN0ZXBGaW5pc2hSZWFzb24gPSAnZXJyb3InO1xuICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgY2FzZSAncmF3Jzoge1xuICAgICAgICAgICAgICAgICAgICAgIGlmIChpbmNsdWRlUmF3Q2h1bmtzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoY2h1bmspO1xuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBleGhhdXN0aXZlQ2hlY2s6IG5ldmVyID0gY2h1bmtUeXBlO1xuICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBjaHVuayB0eXBlOiAke2V4aGF1c3RpdmVDaGVja31gKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgICAgICAvLyBpbnZva2Ugb25GaW5pc2ggY2FsbGJhY2sgYW5kIHJlc29sdmUgdG9vbFJlc3VsdHMgcHJvbWlzZSB3aGVuIHRoZSBzdHJlYW0gaXMgYWJvdXQgdG8gY2xvc2U6XG4gICAgICAgICAgICAgICAgYXN5bmMgZmx1c2goY29udHJvbGxlcikge1xuICAgICAgICAgICAgICAgICAgY29uc3Qgc3RlcFRvb2xDYWxsc0pzb24gPVxuICAgICAgICAgICAgICAgICAgICBzdGVwVG9vbENhbGxzLmxlbmd0aCA+IDBcbiAgICAgICAgICAgICAgICAgICAgICA/IEpTT04uc3RyaW5naWZ5KHN0ZXBUb29sQ2FsbHMpXG4gICAgICAgICAgICAgICAgICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgICAgICAgICAgIC8vIHJlY29yZCB0ZWxlbWV0cnkgaW5mb3JtYXRpb24gZmlyc3QgdG8gZW5zdXJlIGJlc3QgZWZmb3J0IHRpbWluZ1xuICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgZG9TdHJlYW1TcGFuLnNldEF0dHJpYnV0ZXMoXG4gICAgICAgICAgICAgICAgICAgICAgc2VsZWN0VGVsZW1ldHJ5QXR0cmlidXRlcyh7XG4gICAgICAgICAgICAgICAgICAgICAgICB0ZWxlbWV0cnksXG4gICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICdhaS5yZXNwb25zZS5maW5pc2hSZWFzb24nOiBzdGVwRmluaXNoUmVhc29uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAnYWkucmVzcG9uc2UudGV4dCc6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQ6ICgpID0+IGFjdGl2ZVRleHQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICdhaS5yZXNwb25zZS50b29sQ2FsbHMnOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0OiAoKSA9PiBzdGVwVG9vbENhbGxzSnNvbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLmlkJzogc3RlcFJlc3BvbnNlLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAnYWkucmVzcG9uc2UubW9kZWwnOiBzdGVwUmVzcG9uc2UubW9kZWxJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLnRpbWVzdGFtcCc6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcFJlc3BvbnNlLnRpbWVzdGFtcC50b0lTT1N0cmluZygpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAnYWkucmVzcG9uc2UucHJvdmlkZXJNZXRhZGF0YSc6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkoc3RlcFByb3ZpZGVyTWV0YWRhdGEpLFxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICdhaS51c2FnZS5pbnB1dFRva2Vucyc6IHN0ZXBVc2FnZS5pbnB1dFRva2VucyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgJ2FpLnVzYWdlLm91dHB1dFRva2Vucyc6IHN0ZXBVc2FnZS5vdXRwdXRUb2tlbnMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICdhaS51c2FnZS50b3RhbFRva2Vucyc6IHN0ZXBVc2FnZS50b3RhbFRva2VucyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgJ2FpLnVzYWdlLnJlYXNvbmluZ1Rva2Vucyc6IHN0ZXBVc2FnZS5yZWFzb25pbmdUb2tlbnMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICdhaS51c2FnZS5jYWNoZWRJbnB1dFRva2Vucyc6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcFVzYWdlLmNhY2hlZElucHV0VG9rZW5zLFxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHN0YW5kYXJkaXplZCBnZW4tYWkgbGxtIHNwYW4gYXR0cmlidXRlczpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgJ2dlbl9haS5yZXNwb25zZS5maW5pc2hfcmVhc29ucyc6IFtzdGVwRmluaXNoUmVhc29uXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgJ2dlbl9haS5yZXNwb25zZS5pZCc6IHN0ZXBSZXNwb25zZS5pZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgJ2dlbl9haS5yZXNwb25zZS5tb2RlbCc6IHN0ZXBSZXNwb25zZS5tb2RlbElkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAnZ2VuX2FpLnVzYWdlLmlucHV0X3Rva2Vucyc6IHN0ZXBVc2FnZS5pbnB1dFRva2VucyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgJ2dlbl9haS51c2FnZS5vdXRwdXRfdG9rZW5zJzogc3RlcFVzYWdlLm91dHB1dFRva2VucyxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAvLyBpZ25vcmUgZXJyb3Igc2V0dGluZyB0ZWxlbWV0cnkgYXR0cmlidXRlc1xuICAgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gZmluaXNoIGRvU3RyZWFtU3BhbiBiZWZvcmUgb3RoZXIgb3BlcmF0aW9ucyBmb3IgY29ycmVjdCB0aW1pbmc6XG4gICAgICAgICAgICAgICAgICAgIGRvU3RyZWFtU3Bhbi5lbmQoKTtcbiAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2ZpbmlzaC1zdGVwJyxcbiAgICAgICAgICAgICAgICAgICAgZmluaXNoUmVhc29uOiBzdGVwRmluaXNoUmVhc29uLFxuICAgICAgICAgICAgICAgICAgICB1c2FnZTogc3RlcFVzYWdlLFxuICAgICAgICAgICAgICAgICAgICBwcm92aWRlck1ldGFkYXRhOiBzdGVwUHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2U6IHtcbiAgICAgICAgICAgICAgICAgICAgICAuLi5zdGVwUmVzcG9uc2UsXG4gICAgICAgICAgICAgICAgICAgICAgaGVhZGVyczogcmVzcG9uc2U/LmhlYWRlcnMsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgY29uc3QgY29tYmluZWRVc2FnZSA9IGFkZExhbmd1YWdlTW9kZWxVc2FnZSh1c2FnZSwgc3RlcFVzYWdlKTtcblxuICAgICAgICAgICAgICAgICAgLy8gd2FpdCBmb3IgdGhlIHN0ZXAgdG8gYmUgZnVsbHkgcHJvY2Vzc2VkIGJ5IHRoZSBldmVudCBwcm9jZXNzb3JcbiAgICAgICAgICAgICAgICAgIC8vIHRvIGVuc3VyZSB0aGF0IHRoZSByZWNvcmRlZCBzdGVwcyBhcmUgY29tcGxldGU6XG4gICAgICAgICAgICAgICAgICBhd2FpdCBzdGVwRmluaXNoLnByb21pc2U7XG5cbiAgICAgICAgICAgICAgICAgIGNvbnN0IGNsaWVudFRvb2xDYWxscyA9IHN0ZXBUb29sQ2FsbHMuZmlsdGVyKFxuICAgICAgICAgICAgICAgICAgICB0b29sQ2FsbCA9PiB0b29sQ2FsbC5wcm92aWRlckV4ZWN1dGVkICE9PSB0cnVlLFxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGNsaWVudFRvb2xPdXRwdXRzID0gc3RlcFRvb2xPdXRwdXRzLmZpbHRlcihcbiAgICAgICAgICAgICAgICAgICAgdG9vbE91dHB1dCA9PiB0b29sT3V0cHV0LnByb3ZpZGVyRXhlY3V0ZWQgIT09IHRydWUsXG4gICAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgIGNsaWVudFRvb2xDYWxscy5sZW5ndGggPiAwICYmXG4gICAgICAgICAgICAgICAgICAgIC8vIGFsbCBjdXJyZW50IHRvb2wgY2FsbHMgaGF2ZSBvdXRwdXRzIChpbmNsLiBleGVjdXRpb24gZXJyb3JzKTpcbiAgICAgICAgICAgICAgICAgICAgY2xpZW50VG9vbE91dHB1dHMubGVuZ3RoID09PSBjbGllbnRUb29sQ2FsbHMubGVuZ3RoICYmXG4gICAgICAgICAgICAgICAgICAgIC8vIGNvbnRpbnVlIHVudGlsIGEgc3RvcCBjb25kaXRpb24gaXMgbWV0OlxuICAgICAgICAgICAgICAgICAgICAhKGF3YWl0IGlzU3RvcENvbmRpdGlvbk1ldCh7XG4gICAgICAgICAgICAgICAgICAgICAgc3RvcENvbmRpdGlvbnMsXG4gICAgICAgICAgICAgICAgICAgICAgc3RlcHM6IHJlY29yZGVkU3RlcHMsXG4gICAgICAgICAgICAgICAgICAgIH0pKVxuICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGFwcGVuZCB0byBtZXNzYWdlcyBmb3IgdGhlIG5leHQgc3RlcDpcbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2VNZXNzYWdlcy5wdXNoKFxuICAgICAgICAgICAgICAgICAgICAgIC4uLnRvUmVzcG9uc2VNZXNzYWdlcyh7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50OlxuICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB1c2UgdHJhbnNmb3JtZWQgY29udGVudCB0byBjcmVhdGUgdGhlIG1lc3NhZ2VzIGZvciB0aGUgbmV4dCBzdGVwOlxuICAgICAgICAgICAgICAgICAgICAgICAgICByZWNvcmRlZFN0ZXBzW3JlY29yZGVkU3RlcHMubGVuZ3RoIC0gMV0uY29udGVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvb2xzLFxuICAgICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgYXdhaXQgc3RyZWFtU3RlcCh7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50U3RlcDogY3VycmVudFN0ZXAgKyAxLFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2VNZXNzYWdlcyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHVzYWdlOiBjb21iaW5lZFVzYWdlLFxuICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnZXJyb3InLFxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IsXG4gICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICBzZWxmLmNsb3NlU3RyZWFtKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2ZpbmlzaCcsXG4gICAgICAgICAgICAgICAgICAgICAgZmluaXNoUmVhc29uOiBzdGVwRmluaXNoUmVhc29uLFxuICAgICAgICAgICAgICAgICAgICAgIHRvdGFsVXNhZ2U6IGNvbWJpbmVkVXNhZ2UsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuY2xvc2VTdHJlYW0oKTsgLy8gY2xvc2UgdGhlIHN0aXRjaGFibGUgc3RyZWFtXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICApLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBhZGQgdGhlIGluaXRpYWwgc3RyZWFtIHRvIHRoZSBzdGl0Y2hhYmxlIHN0cmVhbVxuICAgICAgICBhd2FpdCBzdHJlYW1TdGVwKHtcbiAgICAgICAgICBjdXJyZW50U3RlcDogMCxcbiAgICAgICAgICByZXNwb25zZU1lc3NhZ2VzOiBbXSxcbiAgICAgICAgICB1c2FnZToge1xuICAgICAgICAgICAgaW5wdXRUb2tlbnM6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIG91dHB1dFRva2VuczogdW5kZWZpbmVkLFxuICAgICAgICAgICAgdG90YWxUb2tlbnM6IHVuZGVmaW5lZCxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgfSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgLy8gYWRkIGFuIGVycm9yIHN0cmVhbSBwYXJ0IGFuZCBjbG9zZSB0aGUgc3RyZWFtczpcbiAgICAgIHNlbGYuYWRkU3RyZWFtKFxuICAgICAgICBuZXcgUmVhZGFibGVTdHJlYW0oe1xuICAgICAgICAgIHN0YXJ0KGNvbnRyb2xsZXIpIHtcbiAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7IHR5cGU6ICdlcnJvcicsIGVycm9yIH0pO1xuICAgICAgICAgICAgY29udHJvbGxlci5jbG9zZSgpO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICAgIHNlbGYuY2xvc2VTdHJlYW0oKTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldCBzdGVwcygpIHtcbiAgICAvLyB3aGVuIGFueSBvZiB0aGUgcHJvbWlzZXMgYXJlIGFjY2Vzc2VkLCB0aGUgc3RyZWFtIGlzIGNvbnN1bWVkXG4gICAgLy8gc28gaXQgcmVzb2x2ZXMgd2l0aG91dCBuZWVkaW5nIHRvIGNvbnN1bWUgdGhlIHN0cmVhbSBzZXBhcmF0ZWx5XG4gICAgdGhpcy5jb25zdW1lU3RyZWFtKCk7XG5cbiAgICByZXR1cm4gdGhpcy5fc3RlcHMucHJvbWlzZTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0IGZpbmFsU3RlcCgpIHtcbiAgICByZXR1cm4gdGhpcy5zdGVwcy50aGVuKHN0ZXBzID0+IHN0ZXBzW3N0ZXBzLmxlbmd0aCAtIDFdKTtcbiAgfVxuXG4gIGdldCBjb250ZW50KCkge1xuICAgIHJldHVybiB0aGlzLmZpbmFsU3RlcC50aGVuKHN0ZXAgPT4gc3RlcC5jb250ZW50KTtcbiAgfVxuXG4gIGdldCB3YXJuaW5ncygpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAudGhlbihzdGVwID0+IHN0ZXAud2FybmluZ3MpO1xuICB9XG5cbiAgZ2V0IHByb3ZpZGVyTWV0YWRhdGEoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmluYWxTdGVwLnRoZW4oc3RlcCA9PiBzdGVwLnByb3ZpZGVyTWV0YWRhdGEpO1xuICB9XG5cbiAgZ2V0IHRleHQoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmluYWxTdGVwLnRoZW4oc3RlcCA9PiBzdGVwLnRleHQpO1xuICB9XG5cbiAgZ2V0IHJlYXNvbmluZ1RleHQoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmluYWxTdGVwLnRoZW4oc3RlcCA9PiBzdGVwLnJlYXNvbmluZ1RleHQpO1xuICB9XG5cbiAgZ2V0IHJlYXNvbmluZygpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAudGhlbihzdGVwID0+IHN0ZXAucmVhc29uaW5nKTtcbiAgfVxuXG4gIGdldCBzb3VyY2VzKCkge1xuICAgIHJldHVybiB0aGlzLmZpbmFsU3RlcC50aGVuKHN0ZXAgPT4gc3RlcC5zb3VyY2VzKTtcbiAgfVxuXG4gIGdldCBmaWxlcygpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAudGhlbihzdGVwID0+IHN0ZXAuZmlsZXMpO1xuICB9XG5cbiAgZ2V0IHRvb2xDYWxscygpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAudGhlbihzdGVwID0+IHN0ZXAudG9vbENhbGxzKTtcbiAgfVxuXG4gIGdldCBzdGF0aWNUb29sQ2FsbHMoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmluYWxTdGVwLnRoZW4oc3RlcCA9PiBzdGVwLnN0YXRpY1Rvb2xDYWxscyk7XG4gIH1cblxuICBnZXQgZHluYW1pY1Rvb2xDYWxscygpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAudGhlbihzdGVwID0+IHN0ZXAuZHluYW1pY1Rvb2xDYWxscyk7XG4gIH1cblxuICBnZXQgdG9vbFJlc3VsdHMoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmluYWxTdGVwLnRoZW4oc3RlcCA9PiBzdGVwLnRvb2xSZXN1bHRzKTtcbiAgfVxuXG4gIGdldCBzdGF0aWNUb29sUmVzdWx0cygpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAudGhlbihzdGVwID0+IHN0ZXAuc3RhdGljVG9vbFJlc3VsdHMpO1xuICB9XG5cbiAgZ2V0IGR5bmFtaWNUb29sUmVzdWx0cygpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAudGhlbihzdGVwID0+IHN0ZXAuZHluYW1pY1Rvb2xSZXN1bHRzKTtcbiAgfVxuXG4gIGdldCB1c2FnZSgpIHtcbiAgICByZXR1cm4gdGhpcy5maW5hbFN0ZXAudGhlbihzdGVwID0+IHN0ZXAudXNhZ2UpO1xuICB9XG5cbiAgZ2V0IHJlcXVlc3QoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmluYWxTdGVwLnRoZW4oc3RlcCA9PiBzdGVwLnJlcXVlc3QpO1xuICB9XG5cbiAgZ2V0IHJlc3BvbnNlKCkge1xuICAgIHJldHVybiB0aGlzLmZpbmFsU3RlcC50aGVuKHN0ZXAgPT4gc3RlcC5yZXNwb25zZSk7XG4gIH1cblxuICBnZXQgdG90YWxVc2FnZSgpIHtcbiAgICAvLyB3aGVuIGFueSBvZiB0aGUgcHJvbWlzZXMgYXJlIGFjY2Vzc2VkLCB0aGUgc3RyZWFtIGlzIGNvbnN1bWVkXG4gICAgLy8gc28gaXQgcmVzb2x2ZXMgd2l0aG91dCBuZWVkaW5nIHRvIGNvbnN1bWUgdGhlIHN0cmVhbSBzZXBhcmF0ZWx5XG4gICAgdGhpcy5jb25zdW1lU3RyZWFtKCk7XG5cbiAgICByZXR1cm4gdGhpcy5fdG90YWxVc2FnZS5wcm9taXNlO1xuICB9XG5cbiAgZ2V0IGZpbmlzaFJlYXNvbigpIHtcbiAgICAvLyB3aGVuIGFueSBvZiB0aGUgcHJvbWlzZXMgYXJlIGFjY2Vzc2VkLCB0aGUgc3RyZWFtIGlzIGNvbnN1bWVkXG4gICAgLy8gc28gaXQgcmVzb2x2ZXMgd2l0aG91dCBuZWVkaW5nIHRvIGNvbnN1bWUgdGhlIHN0cmVhbSBzZXBhcmF0ZWx5XG4gICAgdGhpcy5jb25zdW1lU3RyZWFtKCk7XG5cbiAgICByZXR1cm4gdGhpcy5fZmluaXNoUmVhc29uLnByb21pc2U7XG4gIH1cblxuICAvKipcblNwbGl0IG91dCBhIG5ldyBzdHJlYW0gZnJvbSB0aGUgb3JpZ2luYWwgc3RyZWFtLlxuVGhlIG9yaWdpbmFsIHN0cmVhbSBpcyByZXBsYWNlZCB0byBhbGxvdyBmb3IgZnVydGhlciBzcGxpdHRpbmcsXG5zaW5jZSB3ZSBkbyBub3Qga25vdyBob3cgbWFueSB0aW1lcyB0aGUgc3RyZWFtIHdpbGwgYmUgc3BsaXQuXG5cbk5vdGU6IHRoaXMgbGVhZHMgdG8gYnVmZmVyaW5nIHRoZSBzdHJlYW0gY29udGVudCBvbiB0aGUgc2VydmVyLlxuSG93ZXZlciwgdGhlIExMTSByZXN1bHRzIGFyZSBleHBlY3RlZCB0byBiZSBzbWFsbCBlbm91Z2ggdG8gbm90IGNhdXNlIGlzc3Vlcy5cbiAgICovXG4gIHByaXZhdGUgdGVlU3RyZWFtKCkge1xuICAgIGNvbnN0IFtzdHJlYW0xLCBzdHJlYW0yXSA9IHRoaXMuYmFzZVN0cmVhbS50ZWUoKTtcbiAgICB0aGlzLmJhc2VTdHJlYW0gPSBzdHJlYW0yO1xuICAgIHJldHVybiBzdHJlYW0xO1xuICB9XG5cbiAgZ2V0IHRleHRTdHJlYW0oKTogQXN5bmNJdGVyYWJsZVN0cmVhbTxzdHJpbmc+IHtcbiAgICByZXR1cm4gY3JlYXRlQXN5bmNJdGVyYWJsZVN0cmVhbShcbiAgICAgIHRoaXMudGVlU3RyZWFtKCkucGlwZVRocm91Z2goXG4gICAgICAgIG5ldyBUcmFuc2Zvcm1TdHJlYW08RW5yaWNoZWRTdHJlYW1QYXJ0PFRPT0xTLCBQQVJUSUFMX09VVFBVVD4sIHN0cmluZz4oe1xuICAgICAgICAgIHRyYW5zZm9ybSh7IHBhcnQgfSwgY29udHJvbGxlcikge1xuICAgICAgICAgICAgaWYgKHBhcnQudHlwZSA9PT0gJ3RleHQtZGVsdGEnKSB7XG4gICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShwYXJ0LnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgKSxcbiAgICApO1xuICB9XG5cbiAgZ2V0IGZ1bGxTdHJlYW0oKTogQXN5bmNJdGVyYWJsZVN0cmVhbTxUZXh0U3RyZWFtUGFydDxUT09MUz4+IHtcbiAgICByZXR1cm4gY3JlYXRlQXN5bmNJdGVyYWJsZVN0cmVhbShcbiAgICAgIHRoaXMudGVlU3RyZWFtKCkucGlwZVRocm91Z2goXG4gICAgICAgIG5ldyBUcmFuc2Zvcm1TdHJlYW08XG4gICAgICAgICAgRW5yaWNoZWRTdHJlYW1QYXJ0PFRPT0xTLCBQQVJUSUFMX09VVFBVVD4sXG4gICAgICAgICAgVGV4dFN0cmVhbVBhcnQ8VE9PTFM+XG4gICAgICAgID4oe1xuICAgICAgICAgIHRyYW5zZm9ybSh7IHBhcnQgfSwgY29udHJvbGxlcikge1xuICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHBhcnQpO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgKSxcbiAgICApO1xuICB9XG5cbiAgYXN5bmMgY29uc3VtZVN0cmVhbShvcHRpb25zPzogQ29uc3VtZVN0cmVhbU9wdGlvbnMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgY29uc3VtZVN0cmVhbSh7XG4gICAgICAgIHN0cmVhbTogdGhpcy5mdWxsU3RyZWFtLFxuICAgICAgICBvbkVycm9yOiBvcHRpb25zPy5vbkVycm9yLFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIG9wdGlvbnM/Lm9uRXJyb3I/LihlcnJvcik7XG4gICAgfVxuICB9XG5cbiAgZ2V0IGV4cGVyaW1lbnRhbF9wYXJ0aWFsT3V0cHV0U3RyZWFtKCk6IEFzeW5jSXRlcmFibGVTdHJlYW08UEFSVElBTF9PVVRQVVQ+IHtcbiAgICBpZiAodGhpcy5vdXRwdXQgPT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IE5vT3V0cHV0U3BlY2lmaWVkRXJyb3IoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY3JlYXRlQXN5bmNJdGVyYWJsZVN0cmVhbShcbiAgICAgIHRoaXMudGVlU3RyZWFtKCkucGlwZVRocm91Z2goXG4gICAgICAgIG5ldyBUcmFuc2Zvcm1TdHJlYW08XG4gICAgICAgICAgRW5yaWNoZWRTdHJlYW1QYXJ0PFRPT0xTLCBQQVJUSUFMX09VVFBVVD4sXG4gICAgICAgICAgUEFSVElBTF9PVVRQVVRcbiAgICAgICAgPih7XG4gICAgICAgICAgdHJhbnNmb3JtKHsgcGFydGlhbE91dHB1dCB9LCBjb250cm9sbGVyKSB7XG4gICAgICAgICAgICBpZiAocGFydGlhbE91dHB1dCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShwYXJ0aWFsT3V0cHV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgICksXG4gICAgKTtcbiAgfVxuXG4gIHRvVUlNZXNzYWdlU3RyZWFtPFVJX01FU1NBR0UgZXh0ZW5kcyBVSU1lc3NhZ2U+KHtcbiAgICBvcmlnaW5hbE1lc3NhZ2VzLFxuICAgIGdlbmVyYXRlTWVzc2FnZUlkLFxuICAgIG9uRmluaXNoLFxuICAgIG1lc3NhZ2VNZXRhZGF0YSxcbiAgICBzZW5kUmVhc29uaW5nID0gdHJ1ZSxcbiAgICBzZW5kU291cmNlcyA9IGZhbHNlLFxuICAgIHNlbmRTdGFydCA9IHRydWUsXG4gICAgc2VuZEZpbmlzaCA9IHRydWUsXG4gICAgb25FcnJvciA9IGdldEVycm9yTWVzc2FnZSxcbiAgfTogVUlNZXNzYWdlU3RyZWFtT3B0aW9uczxVSV9NRVNTQUdFPiA9IHt9KTogQXN5bmNJdGVyYWJsZVN0cmVhbTxcbiAgICBJbmZlclVJTWVzc2FnZUNodW5rPFVJX01FU1NBR0U+XG4gID4ge1xuICAgIGNvbnN0IHJlc3BvbnNlTWVzc2FnZUlkID1cbiAgICAgIGdlbmVyYXRlTWVzc2FnZUlkICE9IG51bGxcbiAgICAgICAgPyBnZXRSZXNwb25zZVVJTWVzc2FnZUlkKHtcbiAgICAgICAgICAgIG9yaWdpbmFsTWVzc2FnZXMsXG4gICAgICAgICAgICByZXNwb25zZU1lc3NhZ2VJZDogZ2VuZXJhdGVNZXNzYWdlSWQsXG4gICAgICAgICAgfSlcbiAgICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICBjb25zdCB0b29sTmFtZXNCeUNhbGxJZDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuXG4gICAgY29uc3QgaXNEeW5hbWljID0gKHRvb2xDYWxsSWQ6IHN0cmluZykgPT4ge1xuICAgICAgY29uc3QgdG9vbE5hbWUgPSB0b29sTmFtZXNCeUNhbGxJZFt0b29sQ2FsbElkXTtcbiAgICAgIGNvbnN0IGR5bmFtaWMgPSB0aGlzLnRvb2xzPy5bdG9vbE5hbWVdPy50eXBlID09PSAnZHluYW1pYyc7XG4gICAgICByZXR1cm4gZHluYW1pYyA/IHRydWUgOiB1bmRlZmluZWQ7IC8vIG9ubHkgc2VuZCB3aGVuIGR5bmFtaWMgdG8gcmVkdWNlIGRhdGEgdHJhbnNmZXJcbiAgICB9O1xuXG4gICAgY29uc3QgYmFzZVN0cmVhbSA9IHRoaXMuZnVsbFN0cmVhbS5waXBlVGhyb3VnaChcbiAgICAgIG5ldyBUcmFuc2Zvcm1TdHJlYW08XG4gICAgICAgIFRleHRTdHJlYW1QYXJ0PFRPT0xTPixcbiAgICAgICAgVUlNZXNzYWdlQ2h1bms8XG4gICAgICAgICAgSW5mZXJVSU1lc3NhZ2VNZXRhZGF0YTxVSV9NRVNTQUdFPixcbiAgICAgICAgICBJbmZlclVJTWVzc2FnZURhdGE8VUlfTUVTU0FHRT5cbiAgICAgICAgPlxuICAgICAgPih7XG4gICAgICAgIHRyYW5zZm9ybTogYXN5bmMgKHBhcnQsIGNvbnRyb2xsZXIpID0+IHtcbiAgICAgICAgICBjb25zdCBtZXNzYWdlTWV0YWRhdGFWYWx1ZSA9IG1lc3NhZ2VNZXRhZGF0YT8uKHsgcGFydCB9KTtcblxuICAgICAgICAgIGNvbnN0IHBhcnRUeXBlID0gcGFydC50eXBlO1xuICAgICAgICAgIHN3aXRjaCAocGFydFR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgJ3RleHQtc3RhcnQnOiB7XG4gICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgICAgdHlwZTogJ3RleHQtc3RhcnQnLFxuICAgICAgICAgICAgICAgIGlkOiBwYXJ0LmlkLFxuICAgICAgICAgICAgICAgIC4uLihwYXJ0LnByb3ZpZGVyTWV0YWRhdGEgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgPyB7IHByb3ZpZGVyTWV0YWRhdGE6IHBhcnQucHJvdmlkZXJNZXRhZGF0YSB9XG4gICAgICAgICAgICAgICAgICA6IHt9KSxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYXNlICd0ZXh0LWRlbHRhJzoge1xuICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgICAgIHR5cGU6ICd0ZXh0LWRlbHRhJyxcbiAgICAgICAgICAgICAgICBpZDogcGFydC5pZCxcbiAgICAgICAgICAgICAgICBkZWx0YTogcGFydC50ZXh0LFxuICAgICAgICAgICAgICAgIC4uLihwYXJ0LnByb3ZpZGVyTWV0YWRhdGEgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgPyB7IHByb3ZpZGVyTWV0YWRhdGE6IHBhcnQucHJvdmlkZXJNZXRhZGF0YSB9XG4gICAgICAgICAgICAgICAgICA6IHt9KSxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYXNlICd0ZXh0LWVuZCc6IHtcbiAgICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHtcbiAgICAgICAgICAgICAgICB0eXBlOiAndGV4dC1lbmQnLFxuICAgICAgICAgICAgICAgIGlkOiBwYXJ0LmlkLFxuICAgICAgICAgICAgICAgIC4uLihwYXJ0LnByb3ZpZGVyTWV0YWRhdGEgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgPyB7IHByb3ZpZGVyTWV0YWRhdGE6IHBhcnQucHJvdmlkZXJNZXRhZGF0YSB9XG4gICAgICAgICAgICAgICAgICA6IHt9KSxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYXNlICdyZWFzb25pbmctc3RhcnQnOiB7XG4gICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgICAgdHlwZTogJ3JlYXNvbmluZy1zdGFydCcsXG4gICAgICAgICAgICAgICAgaWQ6IHBhcnQuaWQsXG4gICAgICAgICAgICAgICAgLi4uKHBhcnQucHJvdmlkZXJNZXRhZGF0YSAhPSBudWxsXG4gICAgICAgICAgICAgICAgICA/IHsgcHJvdmlkZXJNZXRhZGF0YTogcGFydC5wcm92aWRlck1ldGFkYXRhIH1cbiAgICAgICAgICAgICAgICAgIDoge30pLFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgJ3JlYXNvbmluZy1kZWx0YSc6IHtcbiAgICAgICAgICAgICAgaWYgKHNlbmRSZWFzb25pbmcpIHtcbiAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgICAgICAgdHlwZTogJ3JlYXNvbmluZy1kZWx0YScsXG4gICAgICAgICAgICAgICAgICBpZDogcGFydC5pZCxcbiAgICAgICAgICAgICAgICAgIGRlbHRhOiBwYXJ0LnRleHQsXG4gICAgICAgICAgICAgICAgICAuLi4ocGFydC5wcm92aWRlck1ldGFkYXRhICE9IG51bGxcbiAgICAgICAgICAgICAgICAgICAgPyB7IHByb3ZpZGVyTWV0YWRhdGE6IHBhcnQucHJvdmlkZXJNZXRhZGF0YSB9XG4gICAgICAgICAgICAgICAgICAgIDoge30pLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYXNlICdyZWFzb25pbmctZW5kJzoge1xuICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgICAgIHR5cGU6ICdyZWFzb25pbmctZW5kJyxcbiAgICAgICAgICAgICAgICBpZDogcGFydC5pZCxcbiAgICAgICAgICAgICAgICAuLi4ocGFydC5wcm92aWRlck1ldGFkYXRhICE9IG51bGxcbiAgICAgICAgICAgICAgICAgID8geyBwcm92aWRlck1ldGFkYXRhOiBwYXJ0LnByb3ZpZGVyTWV0YWRhdGEgfVxuICAgICAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSAnZmlsZSc6IHtcbiAgICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnZmlsZScsXG4gICAgICAgICAgICAgICAgbWVkaWFUeXBlOiBwYXJ0LmZpbGUubWVkaWFUeXBlLFxuICAgICAgICAgICAgICAgIHVybDogYGRhdGE6JHtwYXJ0LmZpbGUubWVkaWFUeXBlfTtiYXNlNjQsJHtwYXJ0LmZpbGUuYmFzZTY0fWAsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSAnc291cmNlJzoge1xuICAgICAgICAgICAgICBpZiAoc2VuZFNvdXJjZXMgJiYgcGFydC5zb3VyY2VUeXBlID09PSAndXJsJykge1xuICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgICAgICB0eXBlOiAnc291cmNlLXVybCcsXG4gICAgICAgICAgICAgICAgICBzb3VyY2VJZDogcGFydC5pZCxcbiAgICAgICAgICAgICAgICAgIHVybDogcGFydC51cmwsXG4gICAgICAgICAgICAgICAgICB0aXRsZTogcGFydC50aXRsZSxcbiAgICAgICAgICAgICAgICAgIC4uLihwYXJ0LnByb3ZpZGVyTWV0YWRhdGEgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgICA/IHsgcHJvdmlkZXJNZXRhZGF0YTogcGFydC5wcm92aWRlck1ldGFkYXRhIH1cbiAgICAgICAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBpZiAoc2VuZFNvdXJjZXMgJiYgcGFydC5zb3VyY2VUeXBlID09PSAnZG9jdW1lbnQnKSB7XG4gICAgICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHtcbiAgICAgICAgICAgICAgICAgIHR5cGU6ICdzb3VyY2UtZG9jdW1lbnQnLFxuICAgICAgICAgICAgICAgICAgc291cmNlSWQ6IHBhcnQuaWQsXG4gICAgICAgICAgICAgICAgICBtZWRpYVR5cGU6IHBhcnQubWVkaWFUeXBlLFxuICAgICAgICAgICAgICAgICAgdGl0bGU6IHBhcnQudGl0bGUsXG4gICAgICAgICAgICAgICAgICBmaWxlbmFtZTogcGFydC5maWxlbmFtZSxcbiAgICAgICAgICAgICAgICAgIC4uLihwYXJ0LnByb3ZpZGVyTWV0YWRhdGEgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgICA/IHsgcHJvdmlkZXJNZXRhZGF0YTogcGFydC5wcm92aWRlck1ldGFkYXRhIH1cbiAgICAgICAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgJ3Rvb2wtaW5wdXQtc3RhcnQnOiB7XG4gICAgICAgICAgICAgIHRvb2xOYW1lc0J5Q2FsbElkW3BhcnQuaWRdID0gcGFydC50b29sTmFtZTtcbiAgICAgICAgICAgICAgY29uc3QgZHluYW1pYyA9IGlzRHluYW1pYyhwYXJ0LmlkKTtcblxuICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgICAgIHR5cGU6ICd0b29sLWlucHV0LXN0YXJ0JyxcbiAgICAgICAgICAgICAgICB0b29sQ2FsbElkOiBwYXJ0LmlkLFxuICAgICAgICAgICAgICAgIHRvb2xOYW1lOiBwYXJ0LnRvb2xOYW1lLFxuICAgICAgICAgICAgICAgIC4uLihwYXJ0LnByb3ZpZGVyRXhlY3V0ZWQgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgPyB7IHByb3ZpZGVyRXhlY3V0ZWQ6IHBhcnQucHJvdmlkZXJFeGVjdXRlZCB9XG4gICAgICAgICAgICAgICAgICA6IHt9KSxcbiAgICAgICAgICAgICAgICAuLi4oZHluYW1pYyAhPSBudWxsID8geyBkeW5hbWljIH0gOiB7fSksXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSAndG9vbC1pbnB1dC1kZWx0YSc6IHtcbiAgICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHtcbiAgICAgICAgICAgICAgICB0eXBlOiAndG9vbC1pbnB1dC1kZWx0YScsXG4gICAgICAgICAgICAgICAgdG9vbENhbGxJZDogcGFydC5pZCxcbiAgICAgICAgICAgICAgICBpbnB1dFRleHREZWx0YTogcGFydC5kZWx0YSxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYXNlICd0b29sLWNhbGwnOiB7XG4gICAgICAgICAgICAgIHRvb2xOYW1lc0J5Q2FsbElkW3BhcnQudG9vbENhbGxJZF0gPSBwYXJ0LnRvb2xOYW1lO1xuICAgICAgICAgICAgICBjb25zdCBkeW5hbWljID0gaXNEeW5hbWljKHBhcnQudG9vbENhbGxJZCk7XG5cbiAgICAgICAgICAgICAgaWYgKHBhcnQuaW52YWxpZCkge1xuICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgICAgICB0eXBlOiAndG9vbC1pbnB1dC1lcnJvcicsXG4gICAgICAgICAgICAgICAgICB0b29sQ2FsbElkOiBwYXJ0LnRvb2xDYWxsSWQsXG4gICAgICAgICAgICAgICAgICB0b29sTmFtZTogcGFydC50b29sTmFtZSxcbiAgICAgICAgICAgICAgICAgIGlucHV0OiBwYXJ0LmlucHV0LFxuICAgICAgICAgICAgICAgICAgLi4uKHBhcnQucHJvdmlkZXJFeGVjdXRlZCAhPSBudWxsXG4gICAgICAgICAgICAgICAgICAgID8geyBwcm92aWRlckV4ZWN1dGVkOiBwYXJ0LnByb3ZpZGVyRXhlY3V0ZWQgfVxuICAgICAgICAgICAgICAgICAgICA6IHt9KSxcbiAgICAgICAgICAgICAgICAgIC4uLihwYXJ0LnByb3ZpZGVyTWV0YWRhdGEgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgICA/IHsgcHJvdmlkZXJNZXRhZGF0YTogcGFydC5wcm92aWRlck1ldGFkYXRhIH1cbiAgICAgICAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgICAgICAgICAuLi4oZHluYW1pYyAhPSBudWxsID8geyBkeW5hbWljIH0gOiB7fSksXG4gICAgICAgICAgICAgICAgICBlcnJvclRleHQ6IG9uRXJyb3IocGFydC5lcnJvciksXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHtcbiAgICAgICAgICAgICAgICAgIHR5cGU6ICd0b29sLWlucHV0LWF2YWlsYWJsZScsXG4gICAgICAgICAgICAgICAgICB0b29sQ2FsbElkOiBwYXJ0LnRvb2xDYWxsSWQsXG4gICAgICAgICAgICAgICAgICB0b29sTmFtZTogcGFydC50b29sTmFtZSxcbiAgICAgICAgICAgICAgICAgIGlucHV0OiBwYXJ0LmlucHV0LFxuICAgICAgICAgICAgICAgICAgLi4uKHBhcnQucHJvdmlkZXJFeGVjdXRlZCAhPSBudWxsXG4gICAgICAgICAgICAgICAgICAgID8geyBwcm92aWRlckV4ZWN1dGVkOiBwYXJ0LnByb3ZpZGVyRXhlY3V0ZWQgfVxuICAgICAgICAgICAgICAgICAgICA6IHt9KSxcbiAgICAgICAgICAgICAgICAgIC4uLihwYXJ0LnByb3ZpZGVyTWV0YWRhdGEgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgICA/IHsgcHJvdmlkZXJNZXRhZGF0YTogcGFydC5wcm92aWRlck1ldGFkYXRhIH1cbiAgICAgICAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgICAgICAgICAuLi4oZHluYW1pYyAhPSBudWxsID8geyBkeW5hbWljIH0gOiB7fSksXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSAndG9vbC1yZXN1bHQnOiB7XG4gICAgICAgICAgICAgIGNvbnN0IGR5bmFtaWMgPSBpc0R5bmFtaWMocGFydC50b29sQ2FsbElkKTtcblxuICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgICAgIHR5cGU6ICd0b29sLW91dHB1dC1hdmFpbGFibGUnLFxuICAgICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IHBhcnQudG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgICBvdXRwdXQ6IHBhcnQub3V0cHV0LFxuICAgICAgICAgICAgICAgIC4uLihwYXJ0LnByb3ZpZGVyRXhlY3V0ZWQgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgPyB7IHByb3ZpZGVyRXhlY3V0ZWQ6IHBhcnQucHJvdmlkZXJFeGVjdXRlZCB9XG4gICAgICAgICAgICAgICAgICA6IHt9KSxcbiAgICAgICAgICAgICAgICAuLi4ocGFydC5wcmVsaW1pbmFyeSAhPSBudWxsXG4gICAgICAgICAgICAgICAgICA/IHsgcHJlbGltaW5hcnk6IHBhcnQucHJlbGltaW5hcnkgfVxuICAgICAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgICAgICAgLi4uKGR5bmFtaWMgIT0gbnVsbCA/IHsgZHluYW1pYyB9IDoge30pLFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgJ3Rvb2wtZXJyb3InOiB7XG4gICAgICAgICAgICAgIGNvbnN0IGR5bmFtaWMgPSBpc0R5bmFtaWMocGFydC50b29sQ2FsbElkKTtcblxuICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgICAgIHR5cGU6ICd0b29sLW91dHB1dC1lcnJvcicsXG4gICAgICAgICAgICAgICAgdG9vbENhbGxJZDogcGFydC50b29sQ2FsbElkLFxuICAgICAgICAgICAgICAgIGVycm9yVGV4dDogb25FcnJvcihwYXJ0LmVycm9yKSxcbiAgICAgICAgICAgICAgICAuLi4ocGFydC5wcm92aWRlckV4ZWN1dGVkICE9IG51bGxcbiAgICAgICAgICAgICAgICAgID8geyBwcm92aWRlckV4ZWN1dGVkOiBwYXJ0LnByb3ZpZGVyRXhlY3V0ZWQgfVxuICAgICAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgICAgICAgLi4uKGR5bmFtaWMgIT0gbnVsbCA/IHsgZHluYW1pYyB9IDoge30pLFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgJ2Vycm9yJzoge1xuICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgICAgIHR5cGU6ICdlcnJvcicsXG4gICAgICAgICAgICAgICAgZXJyb3JUZXh0OiBvbkVycm9yKHBhcnQuZXJyb3IpLFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgJ3N0YXJ0LXN0ZXAnOiB7XG4gICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7IHR5cGU6ICdzdGFydC1zdGVwJyB9KTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgJ2ZpbmlzaC1zdGVwJzoge1xuICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoeyB0eXBlOiAnZmluaXNoLXN0ZXAnIH0pO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSAnc3RhcnQnOiB7XG4gICAgICAgICAgICAgIGlmIChzZW5kU3RhcnQpIHtcbiAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgICAgICAgdHlwZTogJ3N0YXJ0JyxcbiAgICAgICAgICAgICAgICAgIC4uLihtZXNzYWdlTWV0YWRhdGFWYWx1ZSAhPSBudWxsXG4gICAgICAgICAgICAgICAgICAgID8geyBtZXNzYWdlTWV0YWRhdGE6IG1lc3NhZ2VNZXRhZGF0YVZhbHVlIH1cbiAgICAgICAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgICAgICAgICAuLi4ocmVzcG9uc2VNZXNzYWdlSWQgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgICA/IHsgbWVzc2FnZUlkOiByZXNwb25zZU1lc3NhZ2VJZCB9XG4gICAgICAgICAgICAgICAgICAgIDoge30pLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYXNlICdmaW5pc2gnOiB7XG4gICAgICAgICAgICAgIGlmIChzZW5kRmluaXNoKSB7XG4gICAgICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHtcbiAgICAgICAgICAgICAgICAgIHR5cGU6ICdmaW5pc2gnLFxuICAgICAgICAgICAgICAgICAgLi4uKG1lc3NhZ2VNZXRhZGF0YVZhbHVlICE9IG51bGxcbiAgICAgICAgICAgICAgICAgICAgPyB7IG1lc3NhZ2VNZXRhZGF0YTogbWVzc2FnZU1ldGFkYXRhVmFsdWUgfVxuICAgICAgICAgICAgICAgICAgICA6IHt9KSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSAnYWJvcnQnOiB7XG4gICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShwYXJ0KTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgJ3Rvb2wtaW5wdXQtZW5kJzoge1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSAncmF3Jzoge1xuICAgICAgICAgICAgICAvLyBSYXcgY2h1bmtzIGFyZSBub3QgaW5jbHVkZWQgaW4gVUkgbWVzc2FnZSBzdHJlYW1zXG4gICAgICAgICAgICAgIC8vIGFzIHRoZXkgY29udGFpbiBwcm92aWRlci1zcGVjaWZpYyBkYXRhIGZvciBkZXZlbG9wZXIgdXNlXG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgIGNvbnN0IGV4aGF1c3RpdmVDaGVjazogbmV2ZXIgPSBwYXJ0VHlwZTtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGNodW5rIHR5cGU6ICR7ZXhoYXVzdGl2ZUNoZWNrfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIHN0YXJ0IGFuZCBmaW5pc2ggZXZlbnRzIGFscmVhZHkgaGF2ZSBtZXRhZGF0YVxuICAgICAgICAgIC8vIHNvIHdlIG9ubHkgbmVlZCB0byBzZW5kIG1ldGFkYXRhIGZvciBvdGhlciBwYXJ0c1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIG1lc3NhZ2VNZXRhZGF0YVZhbHVlICE9IG51bGwgJiZcbiAgICAgICAgICAgIHBhcnRUeXBlICE9PSAnc3RhcnQnICYmXG4gICAgICAgICAgICBwYXJ0VHlwZSAhPT0gJ2ZpbmlzaCdcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgIHR5cGU6ICdtZXNzYWdlLW1ldGFkYXRhJyxcbiAgICAgICAgICAgICAgbWVzc2FnZU1ldGFkYXRhOiBtZXNzYWdlTWV0YWRhdGFWYWx1ZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICByZXR1cm4gY3JlYXRlQXN5bmNJdGVyYWJsZVN0cmVhbShcbiAgICAgIGhhbmRsZVVJTWVzc2FnZVN0cmVhbUZpbmlzaDxVSV9NRVNTQUdFPih7XG4gICAgICAgIHN0cmVhbTogYmFzZVN0cmVhbSxcbiAgICAgICAgbWVzc2FnZUlkOiByZXNwb25zZU1lc3NhZ2VJZCA/PyBnZW5lcmF0ZU1lc3NhZ2VJZD8uKCksXG4gICAgICAgIG9yaWdpbmFsTWVzc2FnZXMsXG4gICAgICAgIG9uRmluaXNoLFxuICAgICAgICBvbkVycm9yLFxuICAgICAgfSksXG4gICAgKTtcbiAgfVxuXG4gIHBpcGVVSU1lc3NhZ2VTdHJlYW1Ub1Jlc3BvbnNlPFVJX01FU1NBR0UgZXh0ZW5kcyBVSU1lc3NhZ2U+KFxuICAgIHJlc3BvbnNlOiBTZXJ2ZXJSZXNwb25zZSxcbiAgICB7XG4gICAgICBvcmlnaW5hbE1lc3NhZ2VzLFxuICAgICAgZ2VuZXJhdGVNZXNzYWdlSWQsXG4gICAgICBvbkZpbmlzaCxcbiAgICAgIG1lc3NhZ2VNZXRhZGF0YSxcbiAgICAgIHNlbmRSZWFzb25pbmcsXG4gICAgICBzZW5kU291cmNlcyxcbiAgICAgIHNlbmRGaW5pc2gsXG4gICAgICBzZW5kU3RhcnQsXG4gICAgICBvbkVycm9yLFxuICAgICAgLi4uaW5pdFxuICAgIH06IFVJTWVzc2FnZVN0cmVhbVJlc3BvbnNlSW5pdCAmIFVJTWVzc2FnZVN0cmVhbU9wdGlvbnM8VUlfTUVTU0FHRT4gPSB7fSxcbiAgKSB7XG4gICAgcGlwZVVJTWVzc2FnZVN0cmVhbVRvUmVzcG9uc2Uoe1xuICAgICAgcmVzcG9uc2UsXG4gICAgICBzdHJlYW06IHRoaXMudG9VSU1lc3NhZ2VTdHJlYW0oe1xuICAgICAgICBvcmlnaW5hbE1lc3NhZ2VzLFxuICAgICAgICBnZW5lcmF0ZU1lc3NhZ2VJZCxcbiAgICAgICAgb25GaW5pc2gsXG4gICAgICAgIG1lc3NhZ2VNZXRhZGF0YSxcbiAgICAgICAgc2VuZFJlYXNvbmluZyxcbiAgICAgICAgc2VuZFNvdXJjZXMsXG4gICAgICAgIHNlbmRGaW5pc2gsXG4gICAgICAgIHNlbmRTdGFydCxcbiAgICAgICAgb25FcnJvcixcbiAgICAgIH0pLFxuICAgICAgLi4uaW5pdCxcbiAgICB9KTtcbiAgfVxuXG4gIHBpcGVUZXh0U3RyZWFtVG9SZXNwb25zZShyZXNwb25zZTogU2VydmVyUmVzcG9uc2UsIGluaXQ/OiBSZXNwb25zZUluaXQpIHtcbiAgICBwaXBlVGV4dFN0cmVhbVRvUmVzcG9uc2Uoe1xuICAgICAgcmVzcG9uc2UsXG4gICAgICB0ZXh0U3RyZWFtOiB0aGlzLnRleHRTdHJlYW0sXG4gICAgICAuLi5pbml0LFxuICAgIH0pO1xuICB9XG5cbiAgdG9VSU1lc3NhZ2VTdHJlYW1SZXNwb25zZTxVSV9NRVNTQUdFIGV4dGVuZHMgVUlNZXNzYWdlPih7XG4gICAgb3JpZ2luYWxNZXNzYWdlcyxcbiAgICBnZW5lcmF0ZU1lc3NhZ2VJZCxcbiAgICBvbkZpbmlzaCxcbiAgICBtZXNzYWdlTWV0YWRhdGEsXG4gICAgc2VuZFJlYXNvbmluZyxcbiAgICBzZW5kU291cmNlcyxcbiAgICBzZW5kRmluaXNoLFxuICAgIHNlbmRTdGFydCxcbiAgICBvbkVycm9yLFxuICAgIC4uLmluaXRcbiAgfTogVUlNZXNzYWdlU3RyZWFtUmVzcG9uc2VJbml0ICZcbiAgICBVSU1lc3NhZ2VTdHJlYW1PcHRpb25zPFVJX01FU1NBR0U+ID0ge30pOiBSZXNwb25zZSB7XG4gICAgcmV0dXJuIGNyZWF0ZVVJTWVzc2FnZVN0cmVhbVJlc3BvbnNlKHtcbiAgICAgIHN0cmVhbTogdGhpcy50b1VJTWVzc2FnZVN0cmVhbSh7XG4gICAgICAgIG9yaWdpbmFsTWVzc2FnZXMsXG4gICAgICAgIGdlbmVyYXRlTWVzc2FnZUlkLFxuICAgICAgICBvbkZpbmlzaCxcbiAgICAgICAgbWVzc2FnZU1ldGFkYXRhLFxuICAgICAgICBzZW5kUmVhc29uaW5nLFxuICAgICAgICBzZW5kU291cmNlcyxcbiAgICAgICAgc2VuZEZpbmlzaCxcbiAgICAgICAgc2VuZFN0YXJ0LFxuICAgICAgICBvbkVycm9yLFxuICAgICAgfSksXG4gICAgICAuLi5pbml0LFxuICAgIH0pO1xuICB9XG5cbiAgdG9UZXh0U3RyZWFtUmVzcG9uc2UoaW5pdD86IFJlc3BvbnNlSW5pdCk6IFJlc3BvbnNlIHtcbiAgICByZXR1cm4gY3JlYXRlVGV4dFN0cmVhbVJlc3BvbnNlKHtcbiAgICAgIHRleHRTdHJlYW06IHRoaXMudGV4dFN0cmVhbSxcbiAgICAgIC4uLmluaXQsXG4gICAgfSk7XG4gIH1cbn1cbiIsICJleHBvcnQgZnVuY3Rpb24gcHJlcGFyZUhlYWRlcnMoXG4gIGhlYWRlcnM6IEhlYWRlcnNJbml0IHwgdW5kZWZpbmVkLFxuICBkZWZhdWx0SGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPixcbik6IEhlYWRlcnMge1xuICBjb25zdCByZXNwb25zZUhlYWRlcnMgPSBuZXcgSGVhZGVycyhoZWFkZXJzID8/IHt9KTtcblxuICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhkZWZhdWx0SGVhZGVycykpIHtcbiAgICBpZiAoIXJlc3BvbnNlSGVhZGVycy5oYXMoa2V5KSkge1xuICAgICAgcmVzcG9uc2VIZWFkZXJzLnNldChrZXksIHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzcG9uc2VIZWFkZXJzO1xufVxuIiwgImltcG9ydCB7IHByZXBhcmVIZWFkZXJzIH0gZnJvbSAnLi4vdXRpbC9wcmVwYXJlLWhlYWRlcnMnO1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlVGV4dFN0cmVhbVJlc3BvbnNlKHtcbiAgc3RhdHVzLFxuICBzdGF0dXNUZXh0LFxuICBoZWFkZXJzLFxuICB0ZXh0U3RyZWFtLFxufTogUmVzcG9uc2VJbml0ICYge1xuICB0ZXh0U3RyZWFtOiBSZWFkYWJsZVN0cmVhbTxzdHJpbmc+O1xufSk6IFJlc3BvbnNlIHtcbiAgcmV0dXJuIG5ldyBSZXNwb25zZSh0ZXh0U3RyZWFtLnBpcGVUaHJvdWdoKG5ldyBUZXh0RW5jb2RlclN0cmVhbSgpKSwge1xuICAgIHN0YXR1czogc3RhdHVzID8/IDIwMCxcbiAgICBzdGF0dXNUZXh0LFxuICAgIGhlYWRlcnM6IHByZXBhcmVIZWFkZXJzKGhlYWRlcnMsIHtcbiAgICAgICdjb250ZW50LXR5cGUnOiAndGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCcsXG4gICAgfSksXG4gIH0pO1xufVxuIiwgImltcG9ydCB7IFNlcnZlclJlc3BvbnNlIH0gZnJvbSAnbm9kZTpodHRwJztcblxuLyoqXG4gKiBXcml0ZXMgdGhlIGNvbnRlbnQgb2YgYSBzdHJlYW0gdG8gYSBzZXJ2ZXIgcmVzcG9uc2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3cml0ZVRvU2VydmVyUmVzcG9uc2Uoe1xuICByZXNwb25zZSxcbiAgc3RhdHVzLFxuICBzdGF0dXNUZXh0LFxuICBoZWFkZXJzLFxuICBzdHJlYW0sXG59OiB7XG4gIHJlc3BvbnNlOiBTZXJ2ZXJSZXNwb25zZTtcbiAgc3RhdHVzPzogbnVtYmVyO1xuICBzdGF0dXNUZXh0Pzogc3RyaW5nO1xuICBoZWFkZXJzPzogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgbnVtYmVyIHwgc3RyaW5nW10+O1xuICBzdHJlYW06IFJlYWRhYmxlU3RyZWFtPFVpbnQ4QXJyYXk+O1xufSk6IHZvaWQge1xuICByZXNwb25zZS53cml0ZUhlYWQoc3RhdHVzID8/IDIwMCwgc3RhdHVzVGV4dCwgaGVhZGVycyk7XG5cbiAgY29uc3QgcmVhZGVyID0gc3RyZWFtLmdldFJlYWRlcigpO1xuICBjb25zdCByZWFkID0gYXN5bmMgKCkgPT4ge1xuICAgIHRyeSB7XG4gICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICBjb25zdCB7IGRvbmUsIHZhbHVlIH0gPSBhd2FpdCByZWFkZXIucmVhZCgpO1xuICAgICAgICBpZiAoZG9uZSkgYnJlYWs7XG5cbiAgICAgICAgLy8gUmVzcGVjdCBiYWNrcHJlc3N1cmU6IGlmIHdyaXRlKCkgcmV0dXJucyBmYWxzZSwgd2FpdCBmb3IgJ2RyYWluJyBldmVudFxuICAgICAgICBjb25zdCBjYW5Db250aW51ZSA9IHJlc3BvbnNlLndyaXRlKHZhbHVlKTtcbiAgICAgICAgaWYgKCFjYW5Db250aW51ZSkge1xuICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KHJlc29sdmUgPT4ge1xuICAgICAgICAgICAgcmVzcG9uc2Uub25jZSgnZHJhaW4nLCByZXNvbHZlKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgcmVzcG9uc2UuZW5kKCk7XG4gICAgfVxuICB9O1xuXG4gIHJlYWQoKTtcbn1cbiIsICJpbXBvcnQgeyBTZXJ2ZXJSZXNwb25zZSB9IGZyb20gJ25vZGU6aHR0cCc7XG5pbXBvcnQgeyBwcmVwYXJlSGVhZGVycyB9IGZyb20gJy4uL3V0aWwvcHJlcGFyZS1oZWFkZXJzJztcbmltcG9ydCB7IHdyaXRlVG9TZXJ2ZXJSZXNwb25zZSB9IGZyb20gJy4uL3V0aWwvd3JpdGUtdG8tc2VydmVyLXJlc3BvbnNlJztcblxuZXhwb3J0IGZ1bmN0aW9uIHBpcGVUZXh0U3RyZWFtVG9SZXNwb25zZSh7XG4gIHJlc3BvbnNlLFxuICBzdGF0dXMsXG4gIHN0YXR1c1RleHQsXG4gIGhlYWRlcnMsXG4gIHRleHRTdHJlYW0sXG59OiB7XG4gIHJlc3BvbnNlOiBTZXJ2ZXJSZXNwb25zZTtcbiAgdGV4dFN0cmVhbTogUmVhZGFibGVTdHJlYW08c3RyaW5nPjtcbn0gJiBSZXNwb25zZUluaXQpOiB2b2lkIHtcbiAgd3JpdGVUb1NlcnZlclJlc3BvbnNlKHtcbiAgICByZXNwb25zZSxcbiAgICBzdGF0dXMsXG4gICAgc3RhdHVzVGV4dCxcbiAgICBoZWFkZXJzOiBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICBwcmVwYXJlSGVhZGVycyhoZWFkZXJzLCB7XG4gICAgICAgICdjb250ZW50LXR5cGUnOiAndGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCcsXG4gICAgICB9KS5lbnRyaWVzKCksXG4gICAgKSxcbiAgICBzdHJlYW06IHRleHRTdHJlYW0ucGlwZVRocm91Z2gobmV3IFRleHRFbmNvZGVyU3RyZWFtKCkpLFxuICB9KTtcbn1cbiIsICJleHBvcnQgY2xhc3MgSnNvblRvU3NlVHJhbnNmb3JtU3RyZWFtIGV4dGVuZHMgVHJhbnNmb3JtU3RyZWFtPHVua25vd24sIHN0cmluZz4ge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcih7XG4gICAgICB0cmFuc2Zvcm0ocGFydCwgY29udHJvbGxlcikge1xuICAgICAgICBjb250cm9sbGVyLmVucXVldWUoYGRhdGE6ICR7SlNPTi5zdHJpbmdpZnkocGFydCl9XFxuXFxuYCk7XG4gICAgICB9LFxuICAgICAgZmx1c2goY29udHJvbGxlcikge1xuICAgICAgICBjb250cm9sbGVyLmVucXVldWUoJ2RhdGE6IFtET05FXVxcblxcbicpO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxufVxuIiwgImV4cG9ydCBjb25zdCBVSV9NRVNTQUdFX1NUUkVBTV9IRUFERVJTID0ge1xuICAnY29udGVudC10eXBlJzogJ3RleHQvZXZlbnQtc3RyZWFtJyxcbiAgJ2NhY2hlLWNvbnRyb2wnOiAnbm8tY2FjaGUnLFxuICBjb25uZWN0aW9uOiAna2VlcC1hbGl2ZScsXG4gICd4LXZlcmNlbC1haS11aS1tZXNzYWdlLXN0cmVhbSc6ICd2MScsXG4gICd4LWFjY2VsLWJ1ZmZlcmluZyc6ICdubycsIC8vIGRpc2FibGUgbmdpbnggYnVmZmVyaW5nXG59O1xuIiwgImltcG9ydCB7IHByZXBhcmVIZWFkZXJzIH0gZnJvbSAnLi4vdXRpbC9wcmVwYXJlLWhlYWRlcnMnO1xuaW1wb3J0IHsgSnNvblRvU3NlVHJhbnNmb3JtU3RyZWFtIH0gZnJvbSAnLi9qc29uLXRvLXNzZS10cmFuc2Zvcm0tc3RyZWFtJztcbmltcG9ydCB7IFVJX01FU1NBR0VfU1RSRUFNX0hFQURFUlMgfSBmcm9tICcuL3VpLW1lc3NhZ2Utc3RyZWFtLWhlYWRlcnMnO1xuaW1wb3J0IHsgVUlNZXNzYWdlQ2h1bmsgfSBmcm9tICcuL3VpLW1lc3NhZ2UtY2h1bmtzJztcbmltcG9ydCB7IFVJTWVzc2FnZVN0cmVhbVJlc3BvbnNlSW5pdCB9IGZyb20gJy4vdWktbWVzc2FnZS1zdHJlYW0tcmVzcG9uc2UtaW5pdCc7XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVVSU1lc3NhZ2VTdHJlYW1SZXNwb25zZSh7XG4gIHN0YXR1cyxcbiAgc3RhdHVzVGV4dCxcbiAgaGVhZGVycyxcbiAgc3RyZWFtLFxuICBjb25zdW1lU3NlU3RyZWFtLFxufTogVUlNZXNzYWdlU3RyZWFtUmVzcG9uc2VJbml0ICYge1xuICBzdHJlYW06IFJlYWRhYmxlU3RyZWFtPFVJTWVzc2FnZUNodW5rPjtcbn0pOiBSZXNwb25zZSB7XG4gIGxldCBzc2VTdHJlYW0gPSBzdHJlYW0ucGlwZVRocm91Z2gobmV3IEpzb25Ub1NzZVRyYW5zZm9ybVN0cmVhbSgpKTtcblxuICAvLyB3aGVuIHRoZSBjb25zdW1lU3NlU3RyZWFtIGlzIHByb3ZpZGVkLCB3ZSBuZWVkIHRvIHRlZSB0aGUgc3RyZWFtXG4gIC8vIGFuZCBzZW5kIHRoZSBzZWNvbmQgcGFydCB0byB0aGUgY29uc3VtZVNzZVN0cmVhbSBmdW5jdGlvblxuICAvLyBzbyB0aGF0IGl0IGNhbiBiZSBjb25zdW1lZCBieSB0aGUgY2xpZW50IGluZGVwZW5kZW50bHlcbiAgaWYgKGNvbnN1bWVTc2VTdHJlYW0pIHtcbiAgICBjb25zdCBbc3RyZWFtMSwgc3RyZWFtMl0gPSBzc2VTdHJlYW0udGVlKCk7XG4gICAgc3NlU3RyZWFtID0gc3RyZWFtMTtcbiAgICBjb25zdW1lU3NlU3RyZWFtKHsgc3RyZWFtOiBzdHJlYW0yIH0pOyAvLyBubyBhd2FpdCAoZG8gbm90IGJsb2NrIHRoZSByZXNwb25zZSlcbiAgfVxuXG4gIHJldHVybiBuZXcgUmVzcG9uc2Uoc3NlU3RyZWFtLnBpcGVUaHJvdWdoKG5ldyBUZXh0RW5jb2RlclN0cmVhbSgpKSwge1xuICAgIHN0YXR1cyxcbiAgICBzdGF0dXNUZXh0LFxuICAgIGhlYWRlcnM6IHByZXBhcmVIZWFkZXJzKGhlYWRlcnMsIFVJX01FU1NBR0VfU1RSRUFNX0hFQURFUlMpLFxuICB9KTtcbn1cbiIsICJpbXBvcnQgeyBJZEdlbmVyYXRvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXItdXRpbHMnO1xuaW1wb3J0IHsgVUlNZXNzYWdlIH0gZnJvbSAnLi4vdWkvdWktbWVzc2FnZXMnO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UmVzcG9uc2VVSU1lc3NhZ2VJZCh7XG4gIG9yaWdpbmFsTWVzc2FnZXMsXG4gIHJlc3BvbnNlTWVzc2FnZUlkLFxufToge1xuICBvcmlnaW5hbE1lc3NhZ2VzOiBVSU1lc3NhZ2VbXSB8IHVuZGVmaW5lZDtcbiAgcmVzcG9uc2VNZXNzYWdlSWQ6IHN0cmluZyB8IElkR2VuZXJhdG9yO1xufSkge1xuICAvLyB3aGVuIHRoZXJlIGFyZSBubyBvcmlnaW5hbCBtZXNzYWdlcyAoaS5lLiBubyBwZXJzaXN0ZW5jZSksXG4gIC8vIHRoZSBhc3Npc3RhbnQgbWVzc2FnZSBpZCBnZW5lcmF0aW9uIGlzIGhhbmRsZWQgb24gdGhlIGNsaWVudCBzaWRlLlxuICBpZiAob3JpZ2luYWxNZXNzYWdlcyA9PSBudWxsKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGNvbnN0IGxhc3RNZXNzYWdlID0gb3JpZ2luYWxNZXNzYWdlc1tvcmlnaW5hbE1lc3NhZ2VzLmxlbmd0aCAtIDFdO1xuXG4gIHJldHVybiBsYXN0TWVzc2FnZT8ucm9sZSA9PT0gJ2Fzc2lzdGFudCdcbiAgICA/IGxhc3RNZXNzYWdlLmlkXG4gICAgOiB0eXBlb2YgcmVzcG9uc2VNZXNzYWdlSWQgPT09ICdmdW5jdGlvbidcbiAgICAgID8gcmVzcG9uc2VNZXNzYWdlSWQoKVxuICAgICAgOiByZXNwb25zZU1lc3NhZ2VJZDtcbn1cbiIsICJpbXBvcnQge1xuICBTdGFuZGFyZFNjaGVtYVYxLFxuICB2YWxpZGF0ZVR5cGVzLFxuICBWYWxpZGF0b3IsXG59IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXItdXRpbHMnO1xuaW1wb3J0IHsgUHJvdmlkZXJNZXRhZGF0YSB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7XG4gIERhdGFVSU1lc3NhZ2VDaHVuayxcbiAgSW5mZXJVSU1lc3NhZ2VDaHVuayxcbiAgaXNEYXRhVUlNZXNzYWdlQ2h1bmssXG4gIFVJTWVzc2FnZUNodW5rLFxufSBmcm9tICcuLi91aS1tZXNzYWdlLXN0cmVhbS91aS1tZXNzYWdlLWNodW5rcyc7XG5pbXBvcnQgeyBFcnJvckhhbmRsZXIgfSBmcm9tICcuLi91dGlsL2Vycm9yLWhhbmRsZXInO1xuaW1wb3J0IHsgbWVyZ2VPYmplY3RzIH0gZnJvbSAnLi4vdXRpbC9tZXJnZS1vYmplY3RzJztcbmltcG9ydCB7IHBhcnNlUGFydGlhbEpzb24gfSBmcm9tICcuLi91dGlsL3BhcnNlLXBhcnRpYWwtanNvbic7XG5pbXBvcnQgeyBVSURhdGFUeXBlc1RvU2NoZW1hcyB9IGZyb20gJy4vY2hhdCc7XG5pbXBvcnQge1xuICBEYXRhVUlQYXJ0LFxuICBEeW5hbWljVG9vbFVJUGFydCxcbiAgZ2V0VG9vbE5hbWUsXG4gIEluZmVyVUlNZXNzYWdlRGF0YSxcbiAgSW5mZXJVSU1lc3NhZ2VNZXRhZGF0YSxcbiAgSW5mZXJVSU1lc3NhZ2VUb29sQ2FsbCxcbiAgSW5mZXJVSU1lc3NhZ2VUb29scyxcbiAgaXNUb29sVUlQYXJ0LFxuICBSZWFzb25pbmdVSVBhcnQsXG4gIFRleHRVSVBhcnQsXG4gIFRvb2xVSVBhcnQsXG4gIFVJTWVzc2FnZSxcbiAgVUlNZXNzYWdlUGFydCxcbn0gZnJvbSAnLi91aS1tZXNzYWdlcyc7XG5cbmV4cG9ydCB0eXBlIFN0cmVhbWluZ1VJTWVzc2FnZVN0YXRlPFVJX01FU1NBR0UgZXh0ZW5kcyBVSU1lc3NhZ2U+ID0ge1xuICBtZXNzYWdlOiBVSV9NRVNTQUdFO1xuICBhY3RpdmVUZXh0UGFydHM6IFJlY29yZDxzdHJpbmcsIFRleHRVSVBhcnQ+O1xuICBhY3RpdmVSZWFzb25pbmdQYXJ0czogUmVjb3JkPHN0cmluZywgUmVhc29uaW5nVUlQYXJ0PjtcbiAgcGFydGlhbFRvb2xDYWxsczogUmVjb3JkPFxuICAgIHN0cmluZyxcbiAgICB7IHRleHQ6IHN0cmluZzsgaW5kZXg6IG51bWJlcjsgdG9vbE5hbWU6IHN0cmluZzsgZHluYW1pYz86IGJvb2xlYW4gfVxuICA+O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVN0cmVhbWluZ1VJTWVzc2FnZVN0YXRlPFVJX01FU1NBR0UgZXh0ZW5kcyBVSU1lc3NhZ2U+KHtcbiAgbGFzdE1lc3NhZ2UsXG4gIG1lc3NhZ2VJZCxcbn06IHtcbiAgbGFzdE1lc3NhZ2U6IFVJX01FU1NBR0UgfCB1bmRlZmluZWQ7XG4gIG1lc3NhZ2VJZDogc3RyaW5nO1xufSk6IFN0cmVhbWluZ1VJTWVzc2FnZVN0YXRlPFVJX01FU1NBR0U+IHtcbiAgcmV0dXJuIHtcbiAgICBtZXNzYWdlOlxuICAgICAgbGFzdE1lc3NhZ2U/LnJvbGUgPT09ICdhc3Npc3RhbnQnXG4gICAgICAgID8gbGFzdE1lc3NhZ2VcbiAgICAgICAgOiAoe1xuICAgICAgICAgICAgaWQ6IG1lc3NhZ2VJZCxcbiAgICAgICAgICAgIG1ldGFkYXRhOiB1bmRlZmluZWQsXG4gICAgICAgICAgICByb2xlOiAnYXNzaXN0YW50JyxcbiAgICAgICAgICAgIHBhcnRzOiBbXSBhcyBVSU1lc3NhZ2VQYXJ0PFxuICAgICAgICAgICAgICBJbmZlclVJTWVzc2FnZURhdGE8VUlfTUVTU0FHRT4sXG4gICAgICAgICAgICAgIEluZmVyVUlNZXNzYWdlVG9vbHM8VUlfTUVTU0FHRT5cbiAgICAgICAgICAgID5bXSxcbiAgICAgICAgICB9IGFzIFVJX01FU1NBR0UpLFxuICAgIGFjdGl2ZVRleHRQYXJ0czoge30sXG4gICAgYWN0aXZlUmVhc29uaW5nUGFydHM6IHt9LFxuICAgIHBhcnRpYWxUb29sQ2FsbHM6IHt9LFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcHJvY2Vzc1VJTWVzc2FnZVN0cmVhbTxVSV9NRVNTQUdFIGV4dGVuZHMgVUlNZXNzYWdlPih7XG4gIHN0cmVhbSxcbiAgbWVzc2FnZU1ldGFkYXRhU2NoZW1hLFxuICBkYXRhUGFydFNjaGVtYXMsXG4gIHJ1blVwZGF0ZU1lc3NhZ2VKb2IsXG4gIG9uRXJyb3IsXG4gIG9uVG9vbENhbGwsXG4gIG9uRGF0YSxcbn06IHtcbiAgLy8gaW5wdXQgc3RyZWFtIGlzIG5vdCBmdWxseSB0eXBlZCB5ZXQ6XG4gIHN0cmVhbTogUmVhZGFibGVTdHJlYW08VUlNZXNzYWdlQ2h1bms+O1xuICBtZXNzYWdlTWV0YWRhdGFTY2hlbWE/OlxuICAgIHwgVmFsaWRhdG9yPEluZmVyVUlNZXNzYWdlTWV0YWRhdGE8VUlfTUVTU0FHRT4+XG4gICAgfCBTdGFuZGFyZFNjaGVtYVYxPEluZmVyVUlNZXNzYWdlTWV0YWRhdGE8VUlfTUVTU0FHRT4+O1xuICBkYXRhUGFydFNjaGVtYXM/OiBVSURhdGFUeXBlc1RvU2NoZW1hczxJbmZlclVJTWVzc2FnZURhdGE8VUlfTUVTU0FHRT4+O1xuICBvblRvb2xDYWxsPzogKG9wdGlvbnM6IHtcbiAgICB0b29sQ2FsbDogSW5mZXJVSU1lc3NhZ2VUb29sQ2FsbDxVSV9NRVNTQUdFPjtcbiAgfSkgPT4gdm9pZCB8IFByb21pc2VMaWtlPHZvaWQ+O1xuICBvbkRhdGE/OiAoZGF0YVBhcnQ6IERhdGFVSVBhcnQ8SW5mZXJVSU1lc3NhZ2VEYXRhPFVJX01FU1NBR0U+PikgPT4gdm9pZDtcbiAgcnVuVXBkYXRlTWVzc2FnZUpvYjogKFxuICAgIGpvYjogKG9wdGlvbnM6IHtcbiAgICAgIHN0YXRlOiBTdHJlYW1pbmdVSU1lc3NhZ2VTdGF0ZTxVSV9NRVNTQUdFPjtcbiAgICAgIHdyaXRlOiAoKSA9PiB2b2lkO1xuICAgIH0pID0+IFByb21pc2U8dm9pZD4sXG4gICkgPT4gUHJvbWlzZTx2b2lkPjtcbiAgb25FcnJvcjogRXJyb3JIYW5kbGVyO1xufSk6IFJlYWRhYmxlU3RyZWFtPEluZmVyVUlNZXNzYWdlQ2h1bms8VUlfTUVTU0FHRT4+IHtcbiAgcmV0dXJuIHN0cmVhbS5waXBlVGhyb3VnaChcbiAgICBuZXcgVHJhbnNmb3JtU3RyZWFtPFVJTWVzc2FnZUNodW5rLCBJbmZlclVJTWVzc2FnZUNodW5rPFVJX01FU1NBR0U+Pih7XG4gICAgICBhc3luYyB0cmFuc2Zvcm0oY2h1bmssIGNvbnRyb2xsZXIpIHtcbiAgICAgICAgYXdhaXQgcnVuVXBkYXRlTWVzc2FnZUpvYihhc3luYyAoeyBzdGF0ZSwgd3JpdGUgfSkgPT4ge1xuICAgICAgICAgIGZ1bmN0aW9uIGdldFRvb2xJbnZvY2F0aW9uKHRvb2xDYWxsSWQ6IHN0cmluZykge1xuICAgICAgICAgICAgY29uc3QgdG9vbEludm9jYXRpb25zID0gc3RhdGUubWVzc2FnZS5wYXJ0cy5maWx0ZXIoaXNUb29sVUlQYXJ0KTtcblxuICAgICAgICAgICAgY29uc3QgdG9vbEludm9jYXRpb24gPSB0b29sSW52b2NhdGlvbnMuZmluZChcbiAgICAgICAgICAgICAgaW52b2NhdGlvbiA9PiBpbnZvY2F0aW9uLnRvb2xDYWxsSWQgPT09IHRvb2xDYWxsSWQsXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBpZiAodG9vbEludm9jYXRpb24gPT0gbnVsbCkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgJ3Rvb2wtb3V0cHV0LWVycm9yIG11c3QgYmUgcHJlY2VkZWQgYnkgYSB0b29sLWlucHV0LWF2YWlsYWJsZScsXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0b29sSW52b2NhdGlvbjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBmdW5jdGlvbiBnZXREeW5hbWljVG9vbEludm9jYXRpb24odG9vbENhbGxJZDogc3RyaW5nKSB7XG4gICAgICAgICAgICBjb25zdCB0b29sSW52b2NhdGlvbnMgPSBzdGF0ZS5tZXNzYWdlLnBhcnRzLmZpbHRlcihcbiAgICAgICAgICAgICAgcGFydCA9PiBwYXJ0LnR5cGUgPT09ICdkeW5hbWljLXRvb2wnLFxuICAgICAgICAgICAgKSBhcyBEeW5hbWljVG9vbFVJUGFydFtdO1xuXG4gICAgICAgICAgICBjb25zdCB0b29sSW52b2NhdGlvbiA9IHRvb2xJbnZvY2F0aW9ucy5maW5kKFxuICAgICAgICAgICAgICBpbnZvY2F0aW9uID0+IGludm9jYXRpb24udG9vbENhbGxJZCA9PT0gdG9vbENhbGxJZCxcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGlmICh0b29sSW52b2NhdGlvbiA9PSBudWxsKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICAndG9vbC1vdXRwdXQtZXJyb3IgbXVzdCBiZSBwcmVjZWRlZCBieSBhIHRvb2wtaW5wdXQtYXZhaWxhYmxlJyxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHRvb2xJbnZvY2F0aW9uO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGZ1bmN0aW9uIHVwZGF0ZVRvb2xQYXJ0KFxuICAgICAgICAgICAgb3B0aW9uczoge1xuICAgICAgICAgICAgICB0b29sTmFtZToga2V5b2YgSW5mZXJVSU1lc3NhZ2VUb29sczxVSV9NRVNTQUdFPiAmIHN0cmluZztcbiAgICAgICAgICAgICAgdG9vbENhbGxJZDogc3RyaW5nO1xuICAgICAgICAgICAgICBwcm92aWRlckV4ZWN1dGVkPzogYm9vbGVhbjtcbiAgICAgICAgICAgIH0gJiAoXG4gICAgICAgICAgICAgIHwge1xuICAgICAgICAgICAgICAgICAgc3RhdGU6ICdpbnB1dC1zdHJlYW1pbmcnO1xuICAgICAgICAgICAgICAgICAgaW5wdXQ6IHVua25vd247XG4gICAgICAgICAgICAgICAgICBwcm92aWRlckV4ZWN1dGVkPzogYm9vbGVhbjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHwge1xuICAgICAgICAgICAgICAgICAgc3RhdGU6ICdpbnB1dC1hdmFpbGFibGUnO1xuICAgICAgICAgICAgICAgICAgaW5wdXQ6IHVua25vd247XG4gICAgICAgICAgICAgICAgICBwcm92aWRlckV4ZWN1dGVkPzogYm9vbGVhbjtcbiAgICAgICAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE/OiBQcm92aWRlck1ldGFkYXRhO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfCB7XG4gICAgICAgICAgICAgICAgICBzdGF0ZTogJ291dHB1dC1hdmFpbGFibGUnO1xuICAgICAgICAgICAgICAgICAgaW5wdXQ6IHVua25vd247XG4gICAgICAgICAgICAgICAgICBvdXRwdXQ6IHVua25vd247XG4gICAgICAgICAgICAgICAgICBwcm92aWRlckV4ZWN1dGVkPzogYm9vbGVhbjtcbiAgICAgICAgICAgICAgICAgIHByZWxpbWluYXJ5PzogYm9vbGVhbjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHwge1xuICAgICAgICAgICAgICAgICAgc3RhdGU6ICdvdXRwdXQtZXJyb3InO1xuICAgICAgICAgICAgICAgICAgaW5wdXQ6IHVua25vd247XG4gICAgICAgICAgICAgICAgICByYXdJbnB1dD86IHVua25vd247XG4gICAgICAgICAgICAgICAgICBlcnJvclRleHQ6IHN0cmluZztcbiAgICAgICAgICAgICAgICAgIHByb3ZpZGVyRXhlY3V0ZWQ/OiBib29sZWFuO1xuICAgICAgICAgICAgICAgICAgcHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKSxcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIGNvbnN0IHBhcnQgPSBzdGF0ZS5tZXNzYWdlLnBhcnRzLmZpbmQoXG4gICAgICAgICAgICAgIHBhcnQgPT5cbiAgICAgICAgICAgICAgICBpc1Rvb2xVSVBhcnQocGFydCkgJiYgcGFydC50b29sQ2FsbElkID09PSBvcHRpb25zLnRvb2xDYWxsSWQsXG4gICAgICAgICAgICApIGFzIFRvb2xVSVBhcnQ8SW5mZXJVSU1lc3NhZ2VUb29sczxVSV9NRVNTQUdFPj4gfCB1bmRlZmluZWQ7XG5cbiAgICAgICAgICAgIGNvbnN0IGFueU9wdGlvbnMgPSBvcHRpb25zIGFzIGFueTtcbiAgICAgICAgICAgIGNvbnN0IGFueVBhcnQgPSBwYXJ0IGFzIGFueTtcblxuICAgICAgICAgICAgaWYgKHBhcnQgIT0gbnVsbCkge1xuICAgICAgICAgICAgICBwYXJ0LnN0YXRlID0gb3B0aW9ucy5zdGF0ZTtcbiAgICAgICAgICAgICAgYW55UGFydC5pbnB1dCA9IGFueU9wdGlvbnMuaW5wdXQ7XG4gICAgICAgICAgICAgIGFueVBhcnQub3V0cHV0ID0gYW55T3B0aW9ucy5vdXRwdXQ7XG4gICAgICAgICAgICAgIGFueVBhcnQuZXJyb3JUZXh0ID0gYW55T3B0aW9ucy5lcnJvclRleHQ7XG4gICAgICAgICAgICAgIGFueVBhcnQucmF3SW5wdXQgPSBhbnlPcHRpb25zLnJhd0lucHV0O1xuICAgICAgICAgICAgICBhbnlQYXJ0LnByZWxpbWluYXJ5ID0gYW55T3B0aW9ucy5wcmVsaW1pbmFyeTtcblxuICAgICAgICAgICAgICAvLyBvbmNlIHByb3ZpZGVyRXhlY3V0ZWQgaXMgc2V0LCBpdCBzdGF5cyBmb3Igc3RyZWFtaW5nXG4gICAgICAgICAgICAgIGFueVBhcnQucHJvdmlkZXJFeGVjdXRlZCA9XG4gICAgICAgICAgICAgICAgYW55T3B0aW9ucy5wcm92aWRlckV4ZWN1dGVkID8/IHBhcnQucHJvdmlkZXJFeGVjdXRlZDtcblxuICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgYW55T3B0aW9ucy5wcm92aWRlck1ldGFkYXRhICE9IG51bGwgJiZcbiAgICAgICAgICAgICAgICBwYXJ0LnN0YXRlID09PSAnaW5wdXQtYXZhaWxhYmxlJ1xuICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICBwYXJ0LmNhbGxQcm92aWRlck1ldGFkYXRhID0gYW55T3B0aW9ucy5wcm92aWRlck1ldGFkYXRhO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBzdGF0ZS5tZXNzYWdlLnBhcnRzLnB1c2goe1xuICAgICAgICAgICAgICAgIHR5cGU6IGB0b29sLSR7b3B0aW9ucy50b29sTmFtZX1gLFxuICAgICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IG9wdGlvbnMudG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgICBzdGF0ZTogb3B0aW9ucy5zdGF0ZSxcbiAgICAgICAgICAgICAgICBpbnB1dDogYW55T3B0aW9ucy5pbnB1dCxcbiAgICAgICAgICAgICAgICBvdXRwdXQ6IGFueU9wdGlvbnMub3V0cHV0LFxuICAgICAgICAgICAgICAgIHJhd0lucHV0OiBhbnlPcHRpb25zLnJhd0lucHV0LFxuICAgICAgICAgICAgICAgIGVycm9yVGV4dDogYW55T3B0aW9ucy5lcnJvclRleHQsXG4gICAgICAgICAgICAgICAgcHJvdmlkZXJFeGVjdXRlZDogYW55T3B0aW9ucy5wcm92aWRlckV4ZWN1dGVkLFxuICAgICAgICAgICAgICAgIHByZWxpbWluYXJ5OiBhbnlPcHRpb25zLnByZWxpbWluYXJ5LFxuICAgICAgICAgICAgICAgIC4uLihhbnlPcHRpb25zLnByb3ZpZGVyTWV0YWRhdGEgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgPyB7IGNhbGxQcm92aWRlck1ldGFkYXRhOiBhbnlPcHRpb25zLnByb3ZpZGVyTWV0YWRhdGEgfVxuICAgICAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgICAgIH0gYXMgVG9vbFVJUGFydDxJbmZlclVJTWVzc2FnZVRvb2xzPFVJX01FU1NBR0U+Pik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZnVuY3Rpb24gdXBkYXRlRHluYW1pY1Rvb2xQYXJ0KFxuICAgICAgICAgICAgb3B0aW9uczoge1xuICAgICAgICAgICAgICB0b29sTmFtZToga2V5b2YgSW5mZXJVSU1lc3NhZ2VUb29sczxVSV9NRVNTQUdFPiAmIHN0cmluZztcbiAgICAgICAgICAgICAgdG9vbENhbGxJZDogc3RyaW5nO1xuICAgICAgICAgICAgICBwcm92aWRlckV4ZWN1dGVkPzogYm9vbGVhbjtcbiAgICAgICAgICAgIH0gJiAoXG4gICAgICAgICAgICAgIHwge1xuICAgICAgICAgICAgICAgICAgc3RhdGU6ICdpbnB1dC1zdHJlYW1pbmcnO1xuICAgICAgICAgICAgICAgICAgaW5wdXQ6IHVua25vd247XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB8IHtcbiAgICAgICAgICAgICAgICAgIHN0YXRlOiAnaW5wdXQtYXZhaWxhYmxlJztcbiAgICAgICAgICAgICAgICAgIGlucHV0OiB1bmtub3duO1xuICAgICAgICAgICAgICAgICAgcHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB8IHtcbiAgICAgICAgICAgICAgICAgIHN0YXRlOiAnb3V0cHV0LWF2YWlsYWJsZSc7XG4gICAgICAgICAgICAgICAgICBpbnB1dDogdW5rbm93bjtcbiAgICAgICAgICAgICAgICAgIG91dHB1dDogdW5rbm93bjtcbiAgICAgICAgICAgICAgICAgIHByZWxpbWluYXJ5OiBib29sZWFuIHwgdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfCB7XG4gICAgICAgICAgICAgICAgICBzdGF0ZTogJ291dHB1dC1lcnJvcic7XG4gICAgICAgICAgICAgICAgICBpbnB1dDogdW5rbm93bjtcbiAgICAgICAgICAgICAgICAgIGVycm9yVGV4dDogc3RyaW5nO1xuICAgICAgICAgICAgICAgICAgcHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKSxcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIGNvbnN0IHBhcnQgPSBzdGF0ZS5tZXNzYWdlLnBhcnRzLmZpbmQoXG4gICAgICAgICAgICAgIHBhcnQgPT5cbiAgICAgICAgICAgICAgICBwYXJ0LnR5cGUgPT09ICdkeW5hbWljLXRvb2wnICYmXG4gICAgICAgICAgICAgICAgcGFydC50b29sQ2FsbElkID09PSBvcHRpb25zLnRvb2xDYWxsSWQsXG4gICAgICAgICAgICApIGFzIER5bmFtaWNUb29sVUlQYXJ0IHwgdW5kZWZpbmVkO1xuXG4gICAgICAgICAgICBjb25zdCBhbnlPcHRpb25zID0gb3B0aW9ucyBhcyBhbnk7XG4gICAgICAgICAgICBjb25zdCBhbnlQYXJ0ID0gcGFydCBhcyBhbnk7XG5cbiAgICAgICAgICAgIGlmIChwYXJ0ICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgcGFydC5zdGF0ZSA9IG9wdGlvbnMuc3RhdGU7XG4gICAgICAgICAgICAgIGFueVBhcnQudG9vbE5hbWUgPSBvcHRpb25zLnRvb2xOYW1lO1xuICAgICAgICAgICAgICBhbnlQYXJ0LmlucHV0ID0gYW55T3B0aW9ucy5pbnB1dDtcbiAgICAgICAgICAgICAgYW55UGFydC5vdXRwdXQgPSBhbnlPcHRpb25zLm91dHB1dDtcbiAgICAgICAgICAgICAgYW55UGFydC5lcnJvclRleHQgPSBhbnlPcHRpb25zLmVycm9yVGV4dDtcbiAgICAgICAgICAgICAgYW55UGFydC5yYXdJbnB1dCA9IGFueU9wdGlvbnMucmF3SW5wdXQgPz8gYW55UGFydC5yYXdJbnB1dDtcbiAgICAgICAgICAgICAgYW55UGFydC5wcmVsaW1pbmFyeSA9IGFueU9wdGlvbnMucHJlbGltaW5hcnk7XG5cbiAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIGFueU9wdGlvbnMucHJvdmlkZXJNZXRhZGF0YSAhPSBudWxsICYmXG4gICAgICAgICAgICAgICAgcGFydC5zdGF0ZSA9PT0gJ2lucHV0LWF2YWlsYWJsZSdcbiAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgcGFydC5jYWxsUHJvdmlkZXJNZXRhZGF0YSA9IGFueU9wdGlvbnMucHJvdmlkZXJNZXRhZGF0YTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgc3RhdGUubWVzc2FnZS5wYXJ0cy5wdXNoKHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnZHluYW1pYy10b29sJyxcbiAgICAgICAgICAgICAgICB0b29sTmFtZTogb3B0aW9ucy50b29sTmFtZSxcbiAgICAgICAgICAgICAgICB0b29sQ2FsbElkOiBvcHRpb25zLnRvb2xDYWxsSWQsXG4gICAgICAgICAgICAgICAgc3RhdGU6IG9wdGlvbnMuc3RhdGUsXG4gICAgICAgICAgICAgICAgaW5wdXQ6IGFueU9wdGlvbnMuaW5wdXQsXG4gICAgICAgICAgICAgICAgb3V0cHV0OiBhbnlPcHRpb25zLm91dHB1dCxcbiAgICAgICAgICAgICAgICBlcnJvclRleHQ6IGFueU9wdGlvbnMuZXJyb3JUZXh0LFxuICAgICAgICAgICAgICAgIHByZWxpbWluYXJ5OiBhbnlPcHRpb25zLnByZWxpbWluYXJ5LFxuICAgICAgICAgICAgICAgIC4uLihhbnlPcHRpb25zLnByb3ZpZGVyTWV0YWRhdGEgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgPyB7IGNhbGxQcm92aWRlck1ldGFkYXRhOiBhbnlPcHRpb25zLnByb3ZpZGVyTWV0YWRhdGEgfVxuICAgICAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgICAgIH0gYXMgRHluYW1pY1Rvb2xVSVBhcnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGFzeW5jIGZ1bmN0aW9uIHVwZGF0ZU1lc3NhZ2VNZXRhZGF0YShtZXRhZGF0YTogdW5rbm93bikge1xuICAgICAgICAgICAgaWYgKG1ldGFkYXRhICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgY29uc3QgbWVyZ2VkTWV0YWRhdGEgPVxuICAgICAgICAgICAgICAgIHN0YXRlLm1lc3NhZ2UubWV0YWRhdGEgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgPyBtZXJnZU9iamVjdHMoc3RhdGUubWVzc2FnZS5tZXRhZGF0YSwgbWV0YWRhdGEpXG4gICAgICAgICAgICAgICAgICA6IG1ldGFkYXRhO1xuXG4gICAgICAgICAgICAgIGlmIChtZXNzYWdlTWV0YWRhdGFTY2hlbWEgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHZhbGlkYXRlVHlwZXMoe1xuICAgICAgICAgICAgICAgICAgdmFsdWU6IG1lcmdlZE1ldGFkYXRhLFxuICAgICAgICAgICAgICAgICAgc2NoZW1hOiBtZXNzYWdlTWV0YWRhdGFTY2hlbWEsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBzdGF0ZS5tZXNzYWdlLm1ldGFkYXRhID1cbiAgICAgICAgICAgICAgICBtZXJnZWRNZXRhZGF0YSBhcyBJbmZlclVJTWVzc2FnZU1ldGFkYXRhPFVJX01FU1NBR0U+O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHN3aXRjaCAoY2h1bmsudHlwZSkge1xuICAgICAgICAgICAgY2FzZSAndGV4dC1zdGFydCc6IHtcbiAgICAgICAgICAgICAgY29uc3QgdGV4dFBhcnQ6IFRleHRVSVBhcnQgPSB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgICAgICAgICAgIHRleHQ6ICcnLFxuICAgICAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IGNodW5rLnByb3ZpZGVyTWV0YWRhdGEsXG4gICAgICAgICAgICAgICAgc3RhdGU6ICdzdHJlYW1pbmcnLFxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICBzdGF0ZS5hY3RpdmVUZXh0UGFydHNbY2h1bmsuaWRdID0gdGV4dFBhcnQ7XG4gICAgICAgICAgICAgIHN0YXRlLm1lc3NhZ2UucGFydHMucHVzaCh0ZXh0UGFydCk7XG4gICAgICAgICAgICAgIHdyaXRlKCk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYXNlICd0ZXh0LWRlbHRhJzoge1xuICAgICAgICAgICAgICBjb25zdCB0ZXh0UGFydCA9IHN0YXRlLmFjdGl2ZVRleHRQYXJ0c1tjaHVuay5pZF07XG4gICAgICAgICAgICAgIHRleHRQYXJ0LnRleHQgKz0gY2h1bmsuZGVsdGE7XG4gICAgICAgICAgICAgIHRleHRQYXJ0LnByb3ZpZGVyTWV0YWRhdGEgPVxuICAgICAgICAgICAgICAgIGNodW5rLnByb3ZpZGVyTWV0YWRhdGEgPz8gdGV4dFBhcnQucHJvdmlkZXJNZXRhZGF0YTtcbiAgICAgICAgICAgICAgd3JpdGUoKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgJ3RleHQtZW5kJzoge1xuICAgICAgICAgICAgICBjb25zdCB0ZXh0UGFydCA9IHN0YXRlLmFjdGl2ZVRleHRQYXJ0c1tjaHVuay5pZF07XG4gICAgICAgICAgICAgIHRleHRQYXJ0LnN0YXRlID0gJ2RvbmUnO1xuICAgICAgICAgICAgICB0ZXh0UGFydC5wcm92aWRlck1ldGFkYXRhID1cbiAgICAgICAgICAgICAgICBjaHVuay5wcm92aWRlck1ldGFkYXRhID8/IHRleHRQYXJ0LnByb3ZpZGVyTWV0YWRhdGE7XG4gICAgICAgICAgICAgIGRlbGV0ZSBzdGF0ZS5hY3RpdmVUZXh0UGFydHNbY2h1bmsuaWRdO1xuICAgICAgICAgICAgICB3cml0ZSgpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSAncmVhc29uaW5nLXN0YXJ0Jzoge1xuICAgICAgICAgICAgICBjb25zdCByZWFzb25pbmdQYXJ0OiBSZWFzb25pbmdVSVBhcnQgPSB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ3JlYXNvbmluZycsXG4gICAgICAgICAgICAgICAgdGV4dDogJycsXG4gICAgICAgICAgICAgICAgcHJvdmlkZXJNZXRhZGF0YTogY2h1bmsucHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgICAgICAgICBzdGF0ZTogJ3N0cmVhbWluZycsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgIHN0YXRlLmFjdGl2ZVJlYXNvbmluZ1BhcnRzW2NodW5rLmlkXSA9IHJlYXNvbmluZ1BhcnQ7XG4gICAgICAgICAgICAgIHN0YXRlLm1lc3NhZ2UucGFydHMucHVzaChyZWFzb25pbmdQYXJ0KTtcbiAgICAgICAgICAgICAgd3JpdGUoKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgJ3JlYXNvbmluZy1kZWx0YSc6IHtcbiAgICAgICAgICAgICAgY29uc3QgcmVhc29uaW5nUGFydCA9IHN0YXRlLmFjdGl2ZVJlYXNvbmluZ1BhcnRzW2NodW5rLmlkXTtcbiAgICAgICAgICAgICAgcmVhc29uaW5nUGFydC50ZXh0ICs9IGNodW5rLmRlbHRhO1xuICAgICAgICAgICAgICByZWFzb25pbmdQYXJ0LnByb3ZpZGVyTWV0YWRhdGEgPVxuICAgICAgICAgICAgICAgIGNodW5rLnByb3ZpZGVyTWV0YWRhdGEgPz8gcmVhc29uaW5nUGFydC5wcm92aWRlck1ldGFkYXRhO1xuICAgICAgICAgICAgICB3cml0ZSgpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSAncmVhc29uaW5nLWVuZCc6IHtcbiAgICAgICAgICAgICAgY29uc3QgcmVhc29uaW5nUGFydCA9IHN0YXRlLmFjdGl2ZVJlYXNvbmluZ1BhcnRzW2NodW5rLmlkXTtcbiAgICAgICAgICAgICAgcmVhc29uaW5nUGFydC5wcm92aWRlck1ldGFkYXRhID1cbiAgICAgICAgICAgICAgICBjaHVuay5wcm92aWRlck1ldGFkYXRhID8/IHJlYXNvbmluZ1BhcnQucHJvdmlkZXJNZXRhZGF0YTtcbiAgICAgICAgICAgICAgcmVhc29uaW5nUGFydC5zdGF0ZSA9ICdkb25lJztcbiAgICAgICAgICAgICAgZGVsZXRlIHN0YXRlLmFjdGl2ZVJlYXNvbmluZ1BhcnRzW2NodW5rLmlkXTtcblxuICAgICAgICAgICAgICB3cml0ZSgpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSAnZmlsZSc6IHtcbiAgICAgICAgICAgICAgc3RhdGUubWVzc2FnZS5wYXJ0cy5wdXNoKHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnZmlsZScsXG4gICAgICAgICAgICAgICAgbWVkaWFUeXBlOiBjaHVuay5tZWRpYVR5cGUsXG4gICAgICAgICAgICAgICAgdXJsOiBjaHVuay51cmwsXG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIHdyaXRlKCk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYXNlICdzb3VyY2UtdXJsJzoge1xuICAgICAgICAgICAgICBzdGF0ZS5tZXNzYWdlLnBhcnRzLnB1c2goe1xuICAgICAgICAgICAgICAgIHR5cGU6ICdzb3VyY2UtdXJsJyxcbiAgICAgICAgICAgICAgICBzb3VyY2VJZDogY2h1bmsuc291cmNlSWQsXG4gICAgICAgICAgICAgICAgdXJsOiBjaHVuay51cmwsXG4gICAgICAgICAgICAgICAgdGl0bGU6IGNodW5rLnRpdGxlLFxuICAgICAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IGNodW5rLnByb3ZpZGVyTWV0YWRhdGEsXG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIHdyaXRlKCk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYXNlICdzb3VyY2UtZG9jdW1lbnQnOiB7XG4gICAgICAgICAgICAgIHN0YXRlLm1lc3NhZ2UucGFydHMucHVzaCh7XG4gICAgICAgICAgICAgICAgdHlwZTogJ3NvdXJjZS1kb2N1bWVudCcsXG4gICAgICAgICAgICAgICAgc291cmNlSWQ6IGNodW5rLnNvdXJjZUlkLFxuICAgICAgICAgICAgICAgIG1lZGlhVHlwZTogY2h1bmsubWVkaWFUeXBlLFxuICAgICAgICAgICAgICAgIHRpdGxlOiBjaHVuay50aXRsZSxcbiAgICAgICAgICAgICAgICBmaWxlbmFtZTogY2h1bmsuZmlsZW5hbWUsXG4gICAgICAgICAgICAgICAgcHJvdmlkZXJNZXRhZGF0YTogY2h1bmsucHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgd3JpdGUoKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgJ3Rvb2wtaW5wdXQtc3RhcnQnOiB7XG4gICAgICAgICAgICAgIGNvbnN0IHRvb2xJbnZvY2F0aW9ucyA9IHN0YXRlLm1lc3NhZ2UucGFydHMuZmlsdGVyKGlzVG9vbFVJUGFydCk7XG5cbiAgICAgICAgICAgICAgLy8gYWRkIHRoZSBwYXJ0aWFsIHRvb2wgY2FsbCB0byB0aGUgbWFwXG4gICAgICAgICAgICAgIHN0YXRlLnBhcnRpYWxUb29sQ2FsbHNbY2h1bmsudG9vbENhbGxJZF0gPSB7XG4gICAgICAgICAgICAgICAgdGV4dDogJycsXG4gICAgICAgICAgICAgICAgdG9vbE5hbWU6IGNodW5rLnRvb2xOYW1lLFxuICAgICAgICAgICAgICAgIGluZGV4OiB0b29sSW52b2NhdGlvbnMubGVuZ3RoLFxuICAgICAgICAgICAgICAgIGR5bmFtaWM6IGNodW5rLmR5bmFtaWMsXG4gICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgaWYgKGNodW5rLmR5bmFtaWMpIHtcbiAgICAgICAgICAgICAgICB1cGRhdGVEeW5hbWljVG9vbFBhcnQoe1xuICAgICAgICAgICAgICAgICAgdG9vbENhbGxJZDogY2h1bmsudG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgICAgIHRvb2xOYW1lOiBjaHVuay50b29sTmFtZSxcbiAgICAgICAgICAgICAgICAgIHN0YXRlOiAnaW5wdXQtc3RyZWFtaW5nJyxcbiAgICAgICAgICAgICAgICAgIGlucHV0OiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdXBkYXRlVG9vbFBhcnQoe1xuICAgICAgICAgICAgICAgICAgdG9vbENhbGxJZDogY2h1bmsudG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgICAgIHRvb2xOYW1lOiBjaHVuay50b29sTmFtZSxcbiAgICAgICAgICAgICAgICAgIHN0YXRlOiAnaW5wdXQtc3RyZWFtaW5nJyxcbiAgICAgICAgICAgICAgICAgIGlucHV0OiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICBwcm92aWRlckV4ZWN1dGVkOiBjaHVuay5wcm92aWRlckV4ZWN1dGVkLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgd3JpdGUoKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgJ3Rvb2wtaW5wdXQtZGVsdGEnOiB7XG4gICAgICAgICAgICAgIGNvbnN0IHBhcnRpYWxUb29sQ2FsbCA9IHN0YXRlLnBhcnRpYWxUb29sQ2FsbHNbY2h1bmsudG9vbENhbGxJZF07XG5cbiAgICAgICAgICAgICAgcGFydGlhbFRvb2xDYWxsLnRleHQgKz0gY2h1bmsuaW5wdXRUZXh0RGVsdGE7XG5cbiAgICAgICAgICAgICAgY29uc3QgeyB2YWx1ZTogcGFydGlhbEFyZ3MgfSA9IGF3YWl0IHBhcnNlUGFydGlhbEpzb24oXG4gICAgICAgICAgICAgICAgcGFydGlhbFRvb2xDYWxsLnRleHQsXG4gICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgaWYgKHBhcnRpYWxUb29sQ2FsbC5keW5hbWljKSB7XG4gICAgICAgICAgICAgICAgdXBkYXRlRHluYW1pY1Rvb2xQYXJ0KHtcbiAgICAgICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IGNodW5rLnRvb2xDYWxsSWQsXG4gICAgICAgICAgICAgICAgICB0b29sTmFtZTogcGFydGlhbFRvb2xDYWxsLnRvb2xOYW1lLFxuICAgICAgICAgICAgICAgICAgc3RhdGU6ICdpbnB1dC1zdHJlYW1pbmcnLFxuICAgICAgICAgICAgICAgICAgaW5wdXQ6IHBhcnRpYWxBcmdzLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHVwZGF0ZVRvb2xQYXJ0KHtcbiAgICAgICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IGNodW5rLnRvb2xDYWxsSWQsXG4gICAgICAgICAgICAgICAgICB0b29sTmFtZTogcGFydGlhbFRvb2xDYWxsLnRvb2xOYW1lLFxuICAgICAgICAgICAgICAgICAgc3RhdGU6ICdpbnB1dC1zdHJlYW1pbmcnLFxuICAgICAgICAgICAgICAgICAgaW5wdXQ6IHBhcnRpYWxBcmdzLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgd3JpdGUoKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgJ3Rvb2wtaW5wdXQtYXZhaWxhYmxlJzoge1xuICAgICAgICAgICAgICBpZiAoY2h1bmsuZHluYW1pYykge1xuICAgICAgICAgICAgICAgIHVwZGF0ZUR5bmFtaWNUb29sUGFydCh7XG4gICAgICAgICAgICAgICAgICB0b29sQ2FsbElkOiBjaHVuay50b29sQ2FsbElkLFxuICAgICAgICAgICAgICAgICAgdG9vbE5hbWU6IGNodW5rLnRvb2xOYW1lLFxuICAgICAgICAgICAgICAgICAgc3RhdGU6ICdpbnB1dC1hdmFpbGFibGUnLFxuICAgICAgICAgICAgICAgICAgaW5wdXQ6IGNodW5rLmlucHV0LFxuICAgICAgICAgICAgICAgICAgcHJvdmlkZXJNZXRhZGF0YTogY2h1bmsucHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB1cGRhdGVUb29sUGFydCh7XG4gICAgICAgICAgICAgICAgICB0b29sQ2FsbElkOiBjaHVuay50b29sQ2FsbElkLFxuICAgICAgICAgICAgICAgICAgdG9vbE5hbWU6IGNodW5rLnRvb2xOYW1lLFxuICAgICAgICAgICAgICAgICAgc3RhdGU6ICdpbnB1dC1hdmFpbGFibGUnLFxuICAgICAgICAgICAgICAgICAgaW5wdXQ6IGNodW5rLmlucHV0LFxuICAgICAgICAgICAgICAgICAgcHJvdmlkZXJFeGVjdXRlZDogY2h1bmsucHJvdmlkZXJFeGVjdXRlZCxcbiAgICAgICAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IGNodW5rLnByb3ZpZGVyTWV0YWRhdGEsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICB3cml0ZSgpO1xuXG4gICAgICAgICAgICAgIC8vIGludm9rZSB0aGUgb25Ub29sQ2FsbCBjYWxsYmFjayBpZiBpdCBleGlzdHMuIFRoaXMgaXMgYmxvY2tpbmcuXG4gICAgICAgICAgICAgIC8vIEluIHRoZSBmdXR1cmUgd2Ugc2hvdWxkIG1ha2UgdGhpcyBub24tYmxvY2tpbmcsIHdoaWNoXG4gICAgICAgICAgICAgIC8vIHJlcXVpcmVzIGFkZGl0aW9uYWwgc3RhdGUgbWFuYWdlbWVudCBmb3IgZXJyb3IgaGFuZGxpbmcgZXRjLlxuICAgICAgICAgICAgICAvLyBTa2lwIGNhbGxpbmcgb25Ub29sQ2FsbCBmb3IgcHJvdmlkZXItZXhlY3V0ZWQgdG9vbHMgc2luY2UgdGhleSBhcmUgYWxyZWFkeSBleGVjdXRlZFxuICAgICAgICAgICAgICBpZiAob25Ub29sQ2FsbCAmJiAhY2h1bmsucHJvdmlkZXJFeGVjdXRlZCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IG9uVG9vbENhbGwoe1xuICAgICAgICAgICAgICAgICAgdG9vbENhbGw6IGNodW5rIGFzIEluZmVyVUlNZXNzYWdlVG9vbENhbGw8VUlfTUVTU0FHRT4sXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgJ3Rvb2wtaW5wdXQtZXJyb3InOiB7XG4gICAgICAgICAgICAgIGlmIChjaHVuay5keW5hbWljKSB7XG4gICAgICAgICAgICAgICAgdXBkYXRlRHluYW1pY1Rvb2xQYXJ0KHtcbiAgICAgICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IGNodW5rLnRvb2xDYWxsSWQsXG4gICAgICAgICAgICAgICAgICB0b29sTmFtZTogY2h1bmsudG9vbE5hbWUsXG4gICAgICAgICAgICAgICAgICBzdGF0ZTogJ291dHB1dC1lcnJvcicsXG4gICAgICAgICAgICAgICAgICBpbnB1dDogY2h1bmsuaW5wdXQsXG4gICAgICAgICAgICAgICAgICBlcnJvclRleHQ6IGNodW5rLmVycm9yVGV4dCxcbiAgICAgICAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IGNodW5rLnByb3ZpZGVyTWV0YWRhdGEsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdXBkYXRlVG9vbFBhcnQoe1xuICAgICAgICAgICAgICAgICAgdG9vbENhbGxJZDogY2h1bmsudG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgICAgIHRvb2xOYW1lOiBjaHVuay50b29sTmFtZSxcbiAgICAgICAgICAgICAgICAgIHN0YXRlOiAnb3V0cHV0LWVycm9yJyxcbiAgICAgICAgICAgICAgICAgIGlucHV0OiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICByYXdJbnB1dDogY2h1bmsuaW5wdXQsXG4gICAgICAgICAgICAgICAgICBlcnJvclRleHQ6IGNodW5rLmVycm9yVGV4dCxcbiAgICAgICAgICAgICAgICAgIHByb3ZpZGVyRXhlY3V0ZWQ6IGNodW5rLnByb3ZpZGVyRXhlY3V0ZWQsXG4gICAgICAgICAgICAgICAgICBwcm92aWRlck1ldGFkYXRhOiBjaHVuay5wcm92aWRlck1ldGFkYXRhLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgd3JpdGUoKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgJ3Rvb2wtb3V0cHV0LWF2YWlsYWJsZSc6IHtcbiAgICAgICAgICAgICAgaWYgKGNodW5rLmR5bmFtaWMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB0b29sSW52b2NhdGlvbiA9IGdldER5bmFtaWNUb29sSW52b2NhdGlvbihcbiAgICAgICAgICAgICAgICAgIGNodW5rLnRvb2xDYWxsSWQsXG4gICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgIHVwZGF0ZUR5bmFtaWNUb29sUGFydCh7XG4gICAgICAgICAgICAgICAgICB0b29sQ2FsbElkOiBjaHVuay50b29sQ2FsbElkLFxuICAgICAgICAgICAgICAgICAgdG9vbE5hbWU6IHRvb2xJbnZvY2F0aW9uLnRvb2xOYW1lLFxuICAgICAgICAgICAgICAgICAgc3RhdGU6ICdvdXRwdXQtYXZhaWxhYmxlJyxcbiAgICAgICAgICAgICAgICAgIGlucHV0OiAodG9vbEludm9jYXRpb24gYXMgYW55KS5pbnB1dCxcbiAgICAgICAgICAgICAgICAgIG91dHB1dDogY2h1bmsub3V0cHV0LFxuICAgICAgICAgICAgICAgICAgcHJlbGltaW5hcnk6IGNodW5rLnByZWxpbWluYXJ5LFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRvb2xJbnZvY2F0aW9uID0gZ2V0VG9vbEludm9jYXRpb24oY2h1bmsudG9vbENhbGxJZCk7XG5cbiAgICAgICAgICAgICAgICB1cGRhdGVUb29sUGFydCh7XG4gICAgICAgICAgICAgICAgICB0b29sQ2FsbElkOiBjaHVuay50b29sQ2FsbElkLFxuICAgICAgICAgICAgICAgICAgdG9vbE5hbWU6IGdldFRvb2xOYW1lKHRvb2xJbnZvY2F0aW9uKSxcbiAgICAgICAgICAgICAgICAgIHN0YXRlOiAnb3V0cHV0LWF2YWlsYWJsZScsXG4gICAgICAgICAgICAgICAgICBpbnB1dDogKHRvb2xJbnZvY2F0aW9uIGFzIGFueSkuaW5wdXQsXG4gICAgICAgICAgICAgICAgICBvdXRwdXQ6IGNodW5rLm91dHB1dCxcbiAgICAgICAgICAgICAgICAgIHByb3ZpZGVyRXhlY3V0ZWQ6IGNodW5rLnByb3ZpZGVyRXhlY3V0ZWQsXG4gICAgICAgICAgICAgICAgICBwcmVsaW1pbmFyeTogY2h1bmsucHJlbGltaW5hcnksXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICB3cml0ZSgpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSAndG9vbC1vdXRwdXQtZXJyb3InOiB7XG4gICAgICAgICAgICAgIGlmIChjaHVuay5keW5hbWljKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdG9vbEludm9jYXRpb24gPSBnZXREeW5hbWljVG9vbEludm9jYXRpb24oXG4gICAgICAgICAgICAgICAgICBjaHVuay50b29sQ2FsbElkLFxuICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgICB1cGRhdGVEeW5hbWljVG9vbFBhcnQoe1xuICAgICAgICAgICAgICAgICAgdG9vbENhbGxJZDogY2h1bmsudG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgICAgIHRvb2xOYW1lOiB0b29sSW52b2NhdGlvbi50b29sTmFtZSxcbiAgICAgICAgICAgICAgICAgIHN0YXRlOiAnb3V0cHV0LWVycm9yJyxcbiAgICAgICAgICAgICAgICAgIGlucHV0OiAodG9vbEludm9jYXRpb24gYXMgYW55KS5pbnB1dCxcbiAgICAgICAgICAgICAgICAgIGVycm9yVGV4dDogY2h1bmsuZXJyb3JUZXh0LFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRvb2xJbnZvY2F0aW9uID0gZ2V0VG9vbEludm9jYXRpb24oY2h1bmsudG9vbENhbGxJZCk7XG5cbiAgICAgICAgICAgICAgICB1cGRhdGVUb29sUGFydCh7XG4gICAgICAgICAgICAgICAgICB0b29sQ2FsbElkOiBjaHVuay50b29sQ2FsbElkLFxuICAgICAgICAgICAgICAgICAgdG9vbE5hbWU6IGdldFRvb2xOYW1lKHRvb2xJbnZvY2F0aW9uKSxcbiAgICAgICAgICAgICAgICAgIHN0YXRlOiAnb3V0cHV0LWVycm9yJyxcbiAgICAgICAgICAgICAgICAgIGlucHV0OiAodG9vbEludm9jYXRpb24gYXMgYW55KS5pbnB1dCxcbiAgICAgICAgICAgICAgICAgIHJhd0lucHV0OiAodG9vbEludm9jYXRpb24gYXMgYW55KS5yYXdJbnB1dCxcbiAgICAgICAgICAgICAgICAgIGVycm9yVGV4dDogY2h1bmsuZXJyb3JUZXh0LFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgd3JpdGUoKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNhc2UgJ3N0YXJ0LXN0ZXAnOiB7XG4gICAgICAgICAgICAgIC8vIGFkZCBhIHN0ZXAgYm91bmRhcnkgcGFydCB0byB0aGUgbWVzc2FnZVxuICAgICAgICAgICAgICBzdGF0ZS5tZXNzYWdlLnBhcnRzLnB1c2goeyB0eXBlOiAnc3RlcC1zdGFydCcgfSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYXNlICdmaW5pc2gtc3RlcCc6IHtcbiAgICAgICAgICAgICAgLy8gcmVzZXQgdGhlIGN1cnJlbnQgdGV4dCBhbmQgcmVhc29uaW5nIHBhcnRzXG4gICAgICAgICAgICAgIHN0YXRlLmFjdGl2ZVRleHRQYXJ0cyA9IHt9O1xuICAgICAgICAgICAgICBzdGF0ZS5hY3RpdmVSZWFzb25pbmdQYXJ0cyA9IHt9O1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSAnc3RhcnQnOiB7XG4gICAgICAgICAgICAgIGlmIChjaHVuay5tZXNzYWdlSWQgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHN0YXRlLm1lc3NhZ2UuaWQgPSBjaHVuay5tZXNzYWdlSWQ7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBhd2FpdCB1cGRhdGVNZXNzYWdlTWV0YWRhdGEoY2h1bmsubWVzc2FnZU1ldGFkYXRhKTtcblxuICAgICAgICAgICAgICBpZiAoY2h1bmsubWVzc2FnZUlkICE9IG51bGwgfHwgY2h1bmsubWVzc2FnZU1ldGFkYXRhICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICB3cml0ZSgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYXNlICdmaW5pc2gnOiB7XG4gICAgICAgICAgICAgIGF3YWl0IHVwZGF0ZU1lc3NhZ2VNZXRhZGF0YShjaHVuay5tZXNzYWdlTWV0YWRhdGEpO1xuICAgICAgICAgICAgICBpZiAoY2h1bmsubWVzc2FnZU1ldGFkYXRhICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICB3cml0ZSgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYXNlICdtZXNzYWdlLW1ldGFkYXRhJzoge1xuICAgICAgICAgICAgICBhd2FpdCB1cGRhdGVNZXNzYWdlTWV0YWRhdGEoY2h1bmsubWVzc2FnZU1ldGFkYXRhKTtcbiAgICAgICAgICAgICAgaWYgKGNodW5rLm1lc3NhZ2VNZXRhZGF0YSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgd3JpdGUoKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSAnZXJyb3InOiB7XG4gICAgICAgICAgICAgIG9uRXJyb3I/LihuZXcgRXJyb3IoY2h1bmsuZXJyb3JUZXh0KSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgIGlmIChpc0RhdGFVSU1lc3NhZ2VDaHVuayhjaHVuaykpIHtcbiAgICAgICAgICAgICAgICAvLyB2YWxpZGF0ZSBkYXRhIGNodW5rIGlmIGRhdGFQYXJ0U2NoZW1hcyBpcyBwcm92aWRlZFxuICAgICAgICAgICAgICAgIGlmIChkYXRhUGFydFNjaGVtYXM/LltjaHVuay50eXBlXSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICBhd2FpdCB2YWxpZGF0ZVR5cGVzKHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGNodW5rLmRhdGEsXG4gICAgICAgICAgICAgICAgICAgIHNjaGVtYTogZGF0YVBhcnRTY2hlbWFzW2NodW5rLnR5cGVdLFxuICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gY2FzdCwgdmFsaWRhdGlvbiBpcyBkb25lIGFib3ZlXG4gICAgICAgICAgICAgICAgY29uc3QgZGF0YUNodW5rID0gY2h1bmsgYXMgRGF0YVVJTWVzc2FnZUNodW5rPFxuICAgICAgICAgICAgICAgICAgSW5mZXJVSU1lc3NhZ2VEYXRhPFVJX01FU1NBR0U+XG4gICAgICAgICAgICAgICAgPjtcblxuICAgICAgICAgICAgICAgIC8vIHRyYW5zaWVudCBwYXJ0cyBhcmUgbm90IGFkZGVkIHRvIHRoZSBtZXNzYWdlIHN0YXRlXG4gICAgICAgICAgICAgICAgaWYgKGRhdGFDaHVuay50cmFuc2llbnQpIHtcbiAgICAgICAgICAgICAgICAgIG9uRGF0YT8uKGRhdGFDaHVuayk7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCBleGlzdGluZ1VJUGFydCA9XG4gICAgICAgICAgICAgICAgICBkYXRhQ2h1bmsuaWQgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgICA/IChzdGF0ZS5tZXNzYWdlLnBhcnRzLmZpbmQoXG4gICAgICAgICAgICAgICAgICAgICAgICBjaHVua0FyZyA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhQ2h1bmsudHlwZSA9PT0gY2h1bmtBcmcudHlwZSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhQ2h1bmsuaWQgPT09IGNodW5rQXJnLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICkgYXNcbiAgICAgICAgICAgICAgICAgICAgICAgIHwgRGF0YVVJUGFydDxJbmZlclVJTWVzc2FnZURhdGE8VUlfTUVTU0FHRT4+XG4gICAgICAgICAgICAgICAgICAgICAgICB8IHVuZGVmaW5lZClcbiAgICAgICAgICAgICAgICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgICAgICAgICBpZiAoZXhpc3RpbmdVSVBhcnQgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgZXhpc3RpbmdVSVBhcnQuZGF0YSA9IGRhdGFDaHVuay5kYXRhO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBzdGF0ZS5tZXNzYWdlLnBhcnRzLnB1c2goZGF0YUNodW5rKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBvbkRhdGE/LihkYXRhQ2h1bmspO1xuXG4gICAgICAgICAgICAgICAgd3JpdGUoKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShjaHVuayBhcyBJbmZlclVJTWVzc2FnZUNodW5rPFVJX01FU1NBR0U+KTtcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgIH0pLFxuICApO1xufVxuIiwgImltcG9ydCB7IHogfSBmcm9tICd6b2QvdjQnO1xuaW1wb3J0IHtcbiAgUHJvdmlkZXJNZXRhZGF0YSxcbiAgcHJvdmlkZXJNZXRhZGF0YVNjaGVtYSxcbn0gZnJvbSAnLi4vdHlwZXMvcHJvdmlkZXItbWV0YWRhdGEnO1xuaW1wb3J0IHtcbiAgSW5mZXJVSU1lc3NhZ2VEYXRhLFxuICBJbmZlclVJTWVzc2FnZU1ldGFkYXRhLFxuICBVSURhdGFUeXBlcyxcbiAgVUlNZXNzYWdlLFxufSBmcm9tICcuLi91aS91aS1tZXNzYWdlcyc7XG5pbXBvcnQgeyBWYWx1ZU9mIH0gZnJvbSAnLi4vdXRpbC92YWx1ZS1vZic7XG5pbXBvcnQgeyBsYXp5VmFsaWRhdG9yLCB6b2RTY2hlbWEgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyLXV0aWxzJztcblxuZXhwb3J0IGNvbnN0IHVpTWVzc2FnZUNodW5rU2NoZW1hID0gbGF6eVZhbGlkYXRvcigoKSA9PlxuICB6b2RTY2hlbWEoXG4gICAgei51bmlvbihbXG4gICAgICB6LnN0cmljdE9iamVjdCh7XG4gICAgICAgIHR5cGU6IHoubGl0ZXJhbCgndGV4dC1zdGFydCcpLFxuICAgICAgICBpZDogei5zdHJpbmcoKSxcbiAgICAgICAgcHJvdmlkZXJNZXRhZGF0YTogcHJvdmlkZXJNZXRhZGF0YVNjaGVtYS5vcHRpb25hbCgpLFxuICAgICAgfSksXG4gICAgICB6LnN0cmljdE9iamVjdCh7XG4gICAgICAgIHR5cGU6IHoubGl0ZXJhbCgndGV4dC1kZWx0YScpLFxuICAgICAgICBpZDogei5zdHJpbmcoKSxcbiAgICAgICAgZGVsdGE6IHouc3RyaW5nKCksXG4gICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbiAgICAgIH0pLFxuICAgICAgei5zdHJpY3RPYmplY3Qoe1xuICAgICAgICB0eXBlOiB6LmxpdGVyYWwoJ3RleHQtZW5kJyksXG4gICAgICAgIGlkOiB6LnN0cmluZygpLFxuICAgICAgICBwcm92aWRlck1ldGFkYXRhOiBwcm92aWRlck1ldGFkYXRhU2NoZW1hLm9wdGlvbmFsKCksXG4gICAgICB9KSxcbiAgICAgIHouc3RyaWN0T2JqZWN0KHtcbiAgICAgICAgdHlwZTogei5saXRlcmFsKCdlcnJvcicpLFxuICAgICAgICBlcnJvclRleHQ6IHouc3RyaW5nKCksXG4gICAgICB9KSxcbiAgICAgIHouc3RyaWN0T2JqZWN0KHtcbiAgICAgICAgdHlwZTogei5saXRlcmFsKCd0b29sLWlucHV0LXN0YXJ0JyksXG4gICAgICAgIHRvb2xDYWxsSWQ6IHouc3RyaW5nKCksXG4gICAgICAgIHRvb2xOYW1lOiB6LnN0cmluZygpLFxuICAgICAgICBwcm92aWRlckV4ZWN1dGVkOiB6LmJvb2xlYW4oKS5vcHRpb25hbCgpLFxuICAgICAgICBkeW5hbWljOiB6LmJvb2xlYW4oKS5vcHRpb25hbCgpLFxuICAgICAgfSksXG4gICAgICB6LnN0cmljdE9iamVjdCh7XG4gICAgICAgIHR5cGU6IHoubGl0ZXJhbCgndG9vbC1pbnB1dC1kZWx0YScpLFxuICAgICAgICB0b29sQ2FsbElkOiB6LnN0cmluZygpLFxuICAgICAgICBpbnB1dFRleHREZWx0YTogei5zdHJpbmcoKSxcbiAgICAgIH0pLFxuICAgICAgei5zdHJpY3RPYmplY3Qoe1xuICAgICAgICB0eXBlOiB6LmxpdGVyYWwoJ3Rvb2wtaW5wdXQtYXZhaWxhYmxlJyksXG4gICAgICAgIHRvb2xDYWxsSWQ6IHouc3RyaW5nKCksXG4gICAgICAgIHRvb2xOYW1lOiB6LnN0cmluZygpLFxuICAgICAgICBpbnB1dDogei51bmtub3duKCksXG4gICAgICAgIHByb3ZpZGVyRXhlY3V0ZWQ6IHouYm9vbGVhbigpLm9wdGlvbmFsKCksXG4gICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbiAgICAgICAgZHluYW1pYzogei5ib29sZWFuKCkub3B0aW9uYWwoKSxcbiAgICAgIH0pLFxuICAgICAgei5zdHJpY3RPYmplY3Qoe1xuICAgICAgICB0eXBlOiB6LmxpdGVyYWwoJ3Rvb2wtaW5wdXQtZXJyb3InKSxcbiAgICAgICAgdG9vbENhbGxJZDogei5zdHJpbmcoKSxcbiAgICAgICAgdG9vbE5hbWU6IHouc3RyaW5nKCksXG4gICAgICAgIGlucHV0OiB6LnVua25vd24oKSxcbiAgICAgICAgcHJvdmlkZXJFeGVjdXRlZDogei5ib29sZWFuKCkub3B0aW9uYWwoKSxcbiAgICAgICAgcHJvdmlkZXJNZXRhZGF0YTogcHJvdmlkZXJNZXRhZGF0YVNjaGVtYS5vcHRpb25hbCgpLFxuICAgICAgICBkeW5hbWljOiB6LmJvb2xlYW4oKS5vcHRpb25hbCgpLFxuICAgICAgICBlcnJvclRleHQ6IHouc3RyaW5nKCksXG4gICAgICB9KSxcbiAgICAgIHouc3RyaWN0T2JqZWN0KHtcbiAgICAgICAgdHlwZTogei5saXRlcmFsKCd0b29sLW91dHB1dC1hdmFpbGFibGUnKSxcbiAgICAgICAgdG9vbENhbGxJZDogei5zdHJpbmcoKSxcbiAgICAgICAgb3V0cHV0OiB6LnVua25vd24oKSxcbiAgICAgICAgcHJvdmlkZXJFeGVjdXRlZDogei5ib29sZWFuKCkub3B0aW9uYWwoKSxcbiAgICAgICAgZHluYW1pYzogei5ib29sZWFuKCkub3B0aW9uYWwoKSxcbiAgICAgICAgcHJlbGltaW5hcnk6IHouYm9vbGVhbigpLm9wdGlvbmFsKCksXG4gICAgICB9KSxcbiAgICAgIHouc3RyaWN0T2JqZWN0KHtcbiAgICAgICAgdHlwZTogei5saXRlcmFsKCd0b29sLW91dHB1dC1lcnJvcicpLFxuICAgICAgICB0b29sQ2FsbElkOiB6LnN0cmluZygpLFxuICAgICAgICBlcnJvclRleHQ6IHouc3RyaW5nKCksXG4gICAgICAgIHByb3ZpZGVyRXhlY3V0ZWQ6IHouYm9vbGVhbigpLm9wdGlvbmFsKCksXG4gICAgICAgIGR5bmFtaWM6IHouYm9vbGVhbigpLm9wdGlvbmFsKCksXG4gICAgICB9KSxcbiAgICAgIHouc3RyaWN0T2JqZWN0KHtcbiAgICAgICAgdHlwZTogei5saXRlcmFsKCdyZWFzb25pbmctc3RhcnQnKSxcbiAgICAgICAgaWQ6IHouc3RyaW5nKCksXG4gICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbiAgICAgIH0pLFxuICAgICAgei5zdHJpY3RPYmplY3Qoe1xuICAgICAgICB0eXBlOiB6LmxpdGVyYWwoJ3JlYXNvbmluZy1kZWx0YScpLFxuICAgICAgICBpZDogei5zdHJpbmcoKSxcbiAgICAgICAgZGVsdGE6IHouc3RyaW5nKCksXG4gICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbiAgICAgIH0pLFxuICAgICAgei5zdHJpY3RPYmplY3Qoe1xuICAgICAgICB0eXBlOiB6LmxpdGVyYWwoJ3JlYXNvbmluZy1lbmQnKSxcbiAgICAgICAgaWQ6IHouc3RyaW5nKCksXG4gICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbiAgICAgIH0pLFxuICAgICAgei5zdHJpY3RPYmplY3Qoe1xuICAgICAgICB0eXBlOiB6LmxpdGVyYWwoJ3NvdXJjZS11cmwnKSxcbiAgICAgICAgc291cmNlSWQ6IHouc3RyaW5nKCksXG4gICAgICAgIHVybDogei5zdHJpbmcoKSxcbiAgICAgICAgdGl0bGU6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgICAgICAgcHJvdmlkZXJNZXRhZGF0YTogcHJvdmlkZXJNZXRhZGF0YVNjaGVtYS5vcHRpb25hbCgpLFxuICAgICAgfSksXG4gICAgICB6LnN0cmljdE9iamVjdCh7XG4gICAgICAgIHR5cGU6IHoubGl0ZXJhbCgnc291cmNlLWRvY3VtZW50JyksXG4gICAgICAgIHNvdXJjZUlkOiB6LnN0cmluZygpLFxuICAgICAgICBtZWRpYVR5cGU6IHouc3RyaW5nKCksXG4gICAgICAgIHRpdGxlOiB6LnN0cmluZygpLFxuICAgICAgICBmaWxlbmFtZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICAgICAgICBwcm92aWRlck1ldGFkYXRhOiBwcm92aWRlck1ldGFkYXRhU2NoZW1hLm9wdGlvbmFsKCksXG4gICAgICB9KSxcbiAgICAgIHouc3RyaWN0T2JqZWN0KHtcbiAgICAgICAgdHlwZTogei5saXRlcmFsKCdmaWxlJyksXG4gICAgICAgIHVybDogei5zdHJpbmcoKSxcbiAgICAgICAgbWVkaWFUeXBlOiB6LnN0cmluZygpLFxuICAgICAgICBwcm92aWRlck1ldGFkYXRhOiBwcm92aWRlck1ldGFkYXRhU2NoZW1hLm9wdGlvbmFsKCksXG4gICAgICB9KSxcbiAgICAgIHouc3RyaWN0T2JqZWN0KHtcbiAgICAgICAgdHlwZTogei5jdXN0b208YGRhdGEtJHtzdHJpbmd9YD4oXG4gICAgICAgICAgKHZhbHVlKTogdmFsdWUgaXMgYGRhdGEtJHtzdHJpbmd9YCA9PlxuICAgICAgICAgICAgdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyAmJiB2YWx1ZS5zdGFydHNXaXRoKCdkYXRhLScpLFxuICAgICAgICAgIHsgbWVzc2FnZTogJ1R5cGUgbXVzdCBzdGFydCB3aXRoIFwiZGF0YS1cIicgfSxcbiAgICAgICAgKSxcbiAgICAgICAgaWQ6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgICAgICAgZGF0YTogei51bmtub3duKCksXG4gICAgICAgIHRyYW5zaWVudDogei5ib29sZWFuKCkub3B0aW9uYWwoKSxcbiAgICAgIH0pLFxuICAgICAgei5zdHJpY3RPYmplY3Qoe1xuICAgICAgICB0eXBlOiB6LmxpdGVyYWwoJ3N0YXJ0LXN0ZXAnKSxcbiAgICAgIH0pLFxuICAgICAgei5zdHJpY3RPYmplY3Qoe1xuICAgICAgICB0eXBlOiB6LmxpdGVyYWwoJ2ZpbmlzaC1zdGVwJyksXG4gICAgICB9KSxcbiAgICAgIHouc3RyaWN0T2JqZWN0KHtcbiAgICAgICAgdHlwZTogei5saXRlcmFsKCdzdGFydCcpLFxuICAgICAgICBtZXNzYWdlSWQ6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgICAgICAgbWVzc2FnZU1ldGFkYXRhOiB6LnVua25vd24oKS5vcHRpb25hbCgpLFxuICAgICAgfSksXG4gICAgICB6LnN0cmljdE9iamVjdCh7XG4gICAgICAgIHR5cGU6IHoubGl0ZXJhbCgnZmluaXNoJyksXG4gICAgICAgIG1lc3NhZ2VNZXRhZGF0YTogei51bmtub3duKCkub3B0aW9uYWwoKSxcbiAgICAgIH0pLFxuICAgICAgei5zdHJpY3RPYmplY3Qoe1xuICAgICAgICB0eXBlOiB6LmxpdGVyYWwoJ2Fib3J0JyksXG4gICAgICB9KSxcbiAgICAgIHouc3RyaWN0T2JqZWN0KHtcbiAgICAgICAgdHlwZTogei5saXRlcmFsKCdtZXNzYWdlLW1ldGFkYXRhJyksXG4gICAgICAgIG1lc3NhZ2VNZXRhZGF0YTogei51bmtub3duKCksXG4gICAgICB9KSxcbiAgICBdKSxcbiAgKSxcbik7XG5cbmV4cG9ydCB0eXBlIERhdGFVSU1lc3NhZ2VDaHVuazxEQVRBX1RZUEVTIGV4dGVuZHMgVUlEYXRhVHlwZXM+ID0gVmFsdWVPZjx7XG4gIFtOQU1FIGluIGtleW9mIERBVEFfVFlQRVMgJiBzdHJpbmddOiB7XG4gICAgdHlwZTogYGRhdGEtJHtOQU1FfWA7XG4gICAgaWQ/OiBzdHJpbmc7XG4gICAgZGF0YTogREFUQV9UWVBFU1tOQU1FXTtcbiAgICB0cmFuc2llbnQ/OiBib29sZWFuO1xuICB9O1xufT47XG5cbmV4cG9ydCB0eXBlIFVJTWVzc2FnZUNodW5rPFxuICBNRVRBREFUQSA9IHVua25vd24sXG4gIERBVEFfVFlQRVMgZXh0ZW5kcyBVSURhdGFUeXBlcyA9IFVJRGF0YVR5cGVzLFxuPiA9XG4gIHwge1xuICAgICAgdHlwZTogJ3RleHQtc3RhcnQnO1xuICAgICAgaWQ6IHN0cmluZztcbiAgICAgIHByb3ZpZGVyTWV0YWRhdGE/OiBQcm92aWRlck1ldGFkYXRhO1xuICAgIH1cbiAgfCB7XG4gICAgICB0eXBlOiAndGV4dC1kZWx0YSc7XG4gICAgICBkZWx0YTogc3RyaW5nO1xuICAgICAgaWQ6IHN0cmluZztcbiAgICAgIHByb3ZpZGVyTWV0YWRhdGE/OiBQcm92aWRlck1ldGFkYXRhO1xuICAgIH1cbiAgfCB7XG4gICAgICB0eXBlOiAndGV4dC1lbmQnO1xuICAgICAgaWQ6IHN0cmluZztcbiAgICAgIHByb3ZpZGVyTWV0YWRhdGE/OiBQcm92aWRlck1ldGFkYXRhO1xuICAgIH1cbiAgfCB7XG4gICAgICB0eXBlOiAncmVhc29uaW5nLXN0YXJ0JztcbiAgICAgIGlkOiBzdHJpbmc7XG4gICAgICBwcm92aWRlck1ldGFkYXRhPzogUHJvdmlkZXJNZXRhZGF0YTtcbiAgICB9XG4gIHwge1xuICAgICAgdHlwZTogJ3JlYXNvbmluZy1kZWx0YSc7XG4gICAgICBpZDogc3RyaW5nO1xuICAgICAgZGVsdGE6IHN0cmluZztcbiAgICAgIHByb3ZpZGVyTWV0YWRhdGE/OiBQcm92aWRlck1ldGFkYXRhO1xuICAgIH1cbiAgfCB7XG4gICAgICB0eXBlOiAncmVhc29uaW5nLWVuZCc7XG4gICAgICBpZDogc3RyaW5nO1xuICAgICAgcHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG4gICAgfVxuICB8IHtcbiAgICAgIHR5cGU6ICdlcnJvcic7XG4gICAgICBlcnJvclRleHQ6IHN0cmluZztcbiAgICB9XG4gIHwge1xuICAgICAgdHlwZTogJ3Rvb2wtaW5wdXQtYXZhaWxhYmxlJztcbiAgICAgIHRvb2xDYWxsSWQ6IHN0cmluZztcbiAgICAgIHRvb2xOYW1lOiBzdHJpbmc7XG4gICAgICBpbnB1dDogdW5rbm93bjtcbiAgICAgIHByb3ZpZGVyRXhlY3V0ZWQ/OiBib29sZWFuO1xuICAgICAgcHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG4gICAgICBkeW5hbWljPzogYm9vbGVhbjtcbiAgICB9XG4gIHwge1xuICAgICAgdHlwZTogJ3Rvb2wtaW5wdXQtZXJyb3InO1xuICAgICAgdG9vbENhbGxJZDogc3RyaW5nO1xuICAgICAgdG9vbE5hbWU6IHN0cmluZztcbiAgICAgIGlucHV0OiB1bmtub3duO1xuICAgICAgcHJvdmlkZXJFeGVjdXRlZD86IGJvb2xlYW47XG4gICAgICBwcm92aWRlck1ldGFkYXRhPzogUHJvdmlkZXJNZXRhZGF0YTtcbiAgICAgIGR5bmFtaWM/OiBib29sZWFuO1xuICAgICAgZXJyb3JUZXh0OiBzdHJpbmc7XG4gICAgfVxuICB8IHtcbiAgICAgIHR5cGU6ICd0b29sLW91dHB1dC1hdmFpbGFibGUnO1xuICAgICAgdG9vbENhbGxJZDogc3RyaW5nO1xuICAgICAgb3V0cHV0OiB1bmtub3duO1xuICAgICAgcHJvdmlkZXJFeGVjdXRlZD86IGJvb2xlYW47XG4gICAgICBkeW5hbWljPzogYm9vbGVhbjtcbiAgICAgIHByZWxpbWluYXJ5PzogYm9vbGVhbjtcbiAgICB9XG4gIHwge1xuICAgICAgdHlwZTogJ3Rvb2wtb3V0cHV0LWVycm9yJztcbiAgICAgIHRvb2xDYWxsSWQ6IHN0cmluZztcbiAgICAgIGVycm9yVGV4dDogc3RyaW5nO1xuICAgICAgcHJvdmlkZXJFeGVjdXRlZD86IGJvb2xlYW47XG4gICAgICBkeW5hbWljPzogYm9vbGVhbjtcbiAgICB9XG4gIHwge1xuICAgICAgdHlwZTogJ3Rvb2wtaW5wdXQtc3RhcnQnO1xuICAgICAgdG9vbENhbGxJZDogc3RyaW5nO1xuICAgICAgdG9vbE5hbWU6IHN0cmluZztcbiAgICAgIHByb3ZpZGVyRXhlY3V0ZWQ/OiBib29sZWFuO1xuICAgICAgZHluYW1pYz86IGJvb2xlYW47XG4gICAgfVxuICB8IHtcbiAgICAgIHR5cGU6ICd0b29sLWlucHV0LWRlbHRhJztcbiAgICAgIHRvb2xDYWxsSWQ6IHN0cmluZztcbiAgICAgIGlucHV0VGV4dERlbHRhOiBzdHJpbmc7XG4gICAgfVxuICB8IHtcbiAgICAgIHR5cGU6ICdzb3VyY2UtdXJsJztcbiAgICAgIHNvdXJjZUlkOiBzdHJpbmc7XG4gICAgICB1cmw6IHN0cmluZztcbiAgICAgIHRpdGxlPzogc3RyaW5nO1xuICAgICAgcHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG4gICAgfVxuICB8IHtcbiAgICAgIHR5cGU6ICdzb3VyY2UtZG9jdW1lbnQnO1xuICAgICAgc291cmNlSWQ6IHN0cmluZztcbiAgICAgIG1lZGlhVHlwZTogc3RyaW5nO1xuICAgICAgdGl0bGU6IHN0cmluZztcbiAgICAgIGZpbGVuYW1lPzogc3RyaW5nO1xuICAgICAgcHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG4gICAgfVxuICB8IHtcbiAgICAgIHR5cGU6ICdmaWxlJztcbiAgICAgIHVybDogc3RyaW5nO1xuICAgICAgbWVkaWFUeXBlOiBzdHJpbmc7XG4gICAgICBwcm92aWRlck1ldGFkYXRhPzogUHJvdmlkZXJNZXRhZGF0YTtcbiAgICB9XG4gIHwgRGF0YVVJTWVzc2FnZUNodW5rPERBVEFfVFlQRVM+XG4gIHwge1xuICAgICAgdHlwZTogJ3N0YXJ0LXN0ZXAnO1xuICAgIH1cbiAgfCB7XG4gICAgICB0eXBlOiAnZmluaXNoLXN0ZXAnO1xuICAgIH1cbiAgfCB7XG4gICAgICB0eXBlOiAnc3RhcnQnO1xuICAgICAgbWVzc2FnZUlkPzogc3RyaW5nO1xuICAgICAgbWVzc2FnZU1ldGFkYXRhPzogTUVUQURBVEE7XG4gICAgfVxuICB8IHtcbiAgICAgIHR5cGU6ICdmaW5pc2gnO1xuICAgICAgbWVzc2FnZU1ldGFkYXRhPzogTUVUQURBVEE7XG4gICAgfVxuICB8IHtcbiAgICAgIHR5cGU6ICdhYm9ydCc7XG4gICAgfVxuICB8IHtcbiAgICAgIHR5cGU6ICdtZXNzYWdlLW1ldGFkYXRhJztcbiAgICAgIG1lc3NhZ2VNZXRhZGF0YTogTUVUQURBVEE7XG4gICAgfTtcblxuZXhwb3J0IGZ1bmN0aW9uIGlzRGF0YVVJTWVzc2FnZUNodW5rKFxuICBjaHVuazogVUlNZXNzYWdlQ2h1bmssXG4pOiBjaHVuayBpcyBEYXRhVUlNZXNzYWdlQ2h1bms8VUlEYXRhVHlwZXM+IHtcbiAgcmV0dXJuIGNodW5rLnR5cGUuc3RhcnRzV2l0aCgnZGF0YS0nKTtcbn1cblxuZXhwb3J0IHR5cGUgSW5mZXJVSU1lc3NhZ2VDaHVuazxUIGV4dGVuZHMgVUlNZXNzYWdlPiA9IFVJTWVzc2FnZUNodW5rPFxuICBJbmZlclVJTWVzc2FnZU1ldGFkYXRhPFQ+LFxuICBJbmZlclVJTWVzc2FnZURhdGE8VD5cbj47XG4iLCAiLyoqXG4gKiBEZWVwbHkgbWVyZ2VzIHR3byBvYmplY3RzIHRvZ2V0aGVyLlxuICogLSBQcm9wZXJ0aWVzIGZyb20gdGhlIGBvdmVycmlkZXNgIG9iamVjdCBvdmVycmlkZSB0aG9zZSBpbiB0aGUgYGJhc2VgIG9iamVjdCB3aXRoIHRoZSBzYW1lIGtleS5cbiAqIC0gRm9yIG5lc3RlZCBvYmplY3RzLCB0aGUgbWVyZ2UgaXMgcGVyZm9ybWVkIHJlY3Vyc2l2ZWx5IChkZWVwIG1lcmdlKS5cbiAqIC0gQXJyYXlzIGFyZSByZXBsYWNlZCwgbm90IG1lcmdlZC5cbiAqIC0gUHJpbWl0aXZlIHZhbHVlcyBhcmUgcmVwbGFjZWQuXG4gKiAtIElmIGJvdGggYGJhc2VgIGFuZCBgb3ZlcnJpZGVzYCBhcmUgdW5kZWZpbmVkLCByZXR1cm5zIHVuZGVmaW5lZC5cbiAqIC0gSWYgb25lIG9mIGBiYXNlYCBvciBgb3ZlcnJpZGVzYCBpcyB1bmRlZmluZWQsIHJldHVybnMgdGhlIG90aGVyLlxuICpcbiAqIEBwYXJhbSBiYXNlIFRoZSB0YXJnZXQgb2JqZWN0IHRvIG1lcmdlIGludG9cbiAqIEBwYXJhbSBvdmVycmlkZXMgVGhlIHNvdXJjZSBvYmplY3QgdG8gbWVyZ2UgZnJvbVxuICogQHJldHVybnMgQSBuZXcgb2JqZWN0IHdpdGggdGhlIG1lcmdlZCBwcm9wZXJ0aWVzLCBvciB1bmRlZmluZWQgaWYgYm90aCBpbnB1dHMgYXJlIHVuZGVmaW5lZFxuICovXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VPYmplY3RzPFQgZXh0ZW5kcyBvYmplY3QsIFUgZXh0ZW5kcyBvYmplY3Q+KFxuICBiYXNlOiBUIHwgdW5kZWZpbmVkLFxuICBvdmVycmlkZXM6IFUgfCB1bmRlZmluZWQsXG4pOiAoVCAmIFUpIHwgVCB8IFUgfCB1bmRlZmluZWQge1xuICAvLyBJZiBib3RoIGlucHV0cyBhcmUgdW5kZWZpbmVkLCByZXR1cm4gdW5kZWZpbmVkXG4gIGlmIChiYXNlID09PSB1bmRlZmluZWQgJiYgb3ZlcnJpZGVzID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgLy8gSWYgdGFyZ2V0IGlzIHVuZGVmaW5lZCwgcmV0dXJuIHNvdXJjZVxuICBpZiAoYmFzZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIG92ZXJyaWRlcztcbiAgfVxuXG4gIC8vIElmIHNvdXJjZSBpcyB1bmRlZmluZWQsIHJldHVybiB0YXJnZXRcbiAgaWYgKG92ZXJyaWRlcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGJhc2U7XG4gIH1cblxuICAvLyBDcmVhdGUgYSBuZXcgb2JqZWN0IHRvIGF2b2lkIG11dGF0aW5nIHRoZSBpbnB1dHNcbiAgY29uc3QgcmVzdWx0ID0geyAuLi5iYXNlIH0gYXMgVCAmIFU7XG5cbiAgLy8gSXRlcmF0ZSB0aHJvdWdoIGFsbCBrZXlzIGluIHRoZSBzb3VyY2Ugb2JqZWN0XG4gIGZvciAoY29uc3Qga2V5IGluIG92ZXJyaWRlcykge1xuICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob3ZlcnJpZGVzLCBrZXkpKSB7XG4gICAgICBjb25zdCBvdmVycmlkZXNWYWx1ZSA9IG92ZXJyaWRlc1trZXldO1xuXG4gICAgICAvLyBTa2lwIGlmIHRoZSBvdmVycmlkZXMgdmFsdWUgaXMgdW5kZWZpbmVkXG4gICAgICBpZiAob3ZlcnJpZGVzVmFsdWUgPT09IHVuZGVmaW5lZCkgY29udGludWU7XG5cbiAgICAgIC8vIEdldCB0aGUgYmFzZSB2YWx1ZSBpZiBpdCBleGlzdHNcbiAgICAgIGNvbnN0IGJhc2VWYWx1ZSA9XG4gICAgICAgIGtleSBpbiBiYXNlID8gYmFzZVtrZXkgYXMgdW5rbm93biBhcyBrZXlvZiBUXSA6IHVuZGVmaW5lZDtcblxuICAgICAgLy8gQ2hlY2sgaWYgYm90aCB2YWx1ZXMgYXJlIG9iamVjdHMgdGhhdCBjYW4gYmUgZGVlcGx5IG1lcmdlZFxuICAgICAgY29uc3QgaXNTb3VyY2VPYmplY3QgPVxuICAgICAgICBvdmVycmlkZXNWYWx1ZSAhPT0gbnVsbCAmJlxuICAgICAgICB0eXBlb2Ygb3ZlcnJpZGVzVmFsdWUgPT09ICdvYmplY3QnICYmXG4gICAgICAgICFBcnJheS5pc0FycmF5KG92ZXJyaWRlc1ZhbHVlKSAmJlxuICAgICAgICAhKG92ZXJyaWRlc1ZhbHVlIGluc3RhbmNlb2YgRGF0ZSkgJiZcbiAgICAgICAgIShvdmVycmlkZXNWYWx1ZSBpbnN0YW5jZW9mIFJlZ0V4cCk7XG5cbiAgICAgIGNvbnN0IGlzVGFyZ2V0T2JqZWN0ID1cbiAgICAgICAgYmFzZVZhbHVlICE9PSBudWxsICYmXG4gICAgICAgIGJhc2VWYWx1ZSAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAgIHR5cGVvZiBiYXNlVmFsdWUgPT09ICdvYmplY3QnICYmXG4gICAgICAgICFBcnJheS5pc0FycmF5KGJhc2VWYWx1ZSkgJiZcbiAgICAgICAgIShiYXNlVmFsdWUgaW5zdGFuY2VvZiBEYXRlKSAmJlxuICAgICAgICAhKGJhc2VWYWx1ZSBpbnN0YW5jZW9mIFJlZ0V4cCk7XG5cbiAgICAgIC8vIElmIGJvdGggdmFsdWVzIGFyZSBtZXJnZWFibGUgb2JqZWN0cywgbWVyZ2UgdGhlbSByZWN1cnNpdmVseVxuICAgICAgaWYgKGlzU291cmNlT2JqZWN0ICYmIGlzVGFyZ2V0T2JqZWN0KSB7XG4gICAgICAgIHJlc3VsdFtrZXkgYXMga2V5b2YgKFQgJiBVKV0gPSBtZXJnZU9iamVjdHMoXG4gICAgICAgICAgYmFzZVZhbHVlIGFzIG9iamVjdCxcbiAgICAgICAgICBvdmVycmlkZXNWYWx1ZSBhcyBvYmplY3QsXG4gICAgICAgICkgYXMgYW55O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gRm9yIHByaW1pdGl2ZXMsIGFycmF5cywgb3Igd2hlbiBvbmUgdmFsdWUgaXMgbm90IGEgbWVyZ2VhYmxlIG9iamVjdCxcbiAgICAgICAgLy8gc2ltcGx5IG92ZXJyaWRlIHdpdGggdGhlIHNvdXJjZSB2YWx1ZVxuICAgICAgICByZXN1bHRba2V5IGFzIGtleW9mIChUICYgVSldID0gb3ZlcnJpZGVzVmFsdWUgYXMgYW55O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG4iLCAiaW1wb3J0IHsgSlNPTlZhbHVlIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQgeyBzYWZlUGFyc2VKU09OIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyBmaXhKc29uIH0gZnJvbSAnLi9maXgtanNvbic7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwYXJzZVBhcnRpYWxKc29uKGpzb25UZXh0OiBzdHJpbmcgfCB1bmRlZmluZWQpOiBQcm9taXNlPHtcbiAgdmFsdWU6IEpTT05WYWx1ZSB8IHVuZGVmaW5lZDtcbiAgc3RhdGU6XG4gICAgfCAndW5kZWZpbmVkLWlucHV0J1xuICAgIHwgJ3N1Y2Nlc3NmdWwtcGFyc2UnXG4gICAgfCAncmVwYWlyZWQtcGFyc2UnXG4gICAgfCAnZmFpbGVkLXBhcnNlJztcbn0+IHtcbiAgaWYgKGpzb25UZXh0ID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4geyB2YWx1ZTogdW5kZWZpbmVkLCBzdGF0ZTogJ3VuZGVmaW5lZC1pbnB1dCcgfTtcbiAgfVxuXG4gIGxldCByZXN1bHQgPSBhd2FpdCBzYWZlUGFyc2VKU09OKHsgdGV4dDoganNvblRleHQgfSk7XG5cbiAgaWYgKHJlc3VsdC5zdWNjZXNzKSB7XG4gICAgcmV0dXJuIHsgdmFsdWU6IHJlc3VsdC52YWx1ZSwgc3RhdGU6ICdzdWNjZXNzZnVsLXBhcnNlJyB9O1xuICB9XG5cbiAgcmVzdWx0ID0gYXdhaXQgc2FmZVBhcnNlSlNPTih7IHRleHQ6IGZpeEpzb24oanNvblRleHQpIH0pO1xuXG4gIGlmIChyZXN1bHQuc3VjY2Vzcykge1xuICAgIHJldHVybiB7IHZhbHVlOiByZXN1bHQudmFsdWUsIHN0YXRlOiAncmVwYWlyZWQtcGFyc2UnIH07XG4gIH1cblxuICByZXR1cm4geyB2YWx1ZTogdW5kZWZpbmVkLCBzdGF0ZTogJ2ZhaWxlZC1wYXJzZScgfTtcbn1cbiIsICJ0eXBlIFN0YXRlID1cbiAgfCAnUk9PVCdcbiAgfCAnRklOSVNIJ1xuICB8ICdJTlNJREVfU1RSSU5HJ1xuICB8ICdJTlNJREVfU1RSSU5HX0VTQ0FQRSdcbiAgfCAnSU5TSURFX0xJVEVSQUwnXG4gIHwgJ0lOU0lERV9OVU1CRVInXG4gIHwgJ0lOU0lERV9PQkpFQ1RfU1RBUlQnXG4gIHwgJ0lOU0lERV9PQkpFQ1RfS0VZJ1xuICB8ICdJTlNJREVfT0JKRUNUX0FGVEVSX0tFWSdcbiAgfCAnSU5TSURFX09CSkVDVF9CRUZPUkVfVkFMVUUnXG4gIHwgJ0lOU0lERV9PQkpFQ1RfQUZURVJfVkFMVUUnXG4gIHwgJ0lOU0lERV9PQkpFQ1RfQUZURVJfQ09NTUEnXG4gIHwgJ0lOU0lERV9BUlJBWV9TVEFSVCdcbiAgfCAnSU5TSURFX0FSUkFZX0FGVEVSX1ZBTFVFJ1xuICB8ICdJTlNJREVfQVJSQVlfQUZURVJfQ09NTUEnO1xuXG4vLyBJbXBsZW1lbnRlZCBhcyBhIHNjYW5uZXIgd2l0aCBhZGRpdGlvbmFsIGZpeGluZ1xuLy8gdGhhdCBwZXJmb3JtcyBhIHNpbmdsZSBsaW5lYXIgdGltZSBzY2FuIHBhc3Mgb3ZlciB0aGUgcGFydGlhbCBKU09OLlxuLy9cbi8vIFRoZSBzdGF0ZXMgc2hvdWxkIGlkZWFsbHkgbWF0Y2ggcmVsZXZhbnQgc3RhdGVzIGZyb20gdGhlIEpTT04gc3BlYzpcbi8vIGh0dHBzOi8vd3d3Lmpzb24ub3JnL2pzb24tZW4uaHRtbFxuLy9cbi8vIFBsZWFzZSBub3RlIHRoYXQgaW52YWxpZCBKU09OIGlzIG5vdCBjb25zaWRlcmVkL2NvdmVyZWQsIGJlY2F1c2UgaXRcbi8vIGlzIGFzc3VtZWQgdGhhdCB0aGUgcmVzdWx0aW5nIEpTT04gd2lsbCBiZSBwcm9jZXNzZWQgYnkgYSBzdGFuZGFyZFxuLy8gSlNPTiBwYXJzZXIgdGhhdCB3aWxsIGRldGVjdCBhbnkgaW52YWxpZCBKU09OLlxuZXhwb3J0IGZ1bmN0aW9uIGZpeEpzb24oaW5wdXQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHN0YWNrOiBTdGF0ZVtdID0gWydST09UJ107XG4gIGxldCBsYXN0VmFsaWRJbmRleCA9IC0xO1xuICBsZXQgbGl0ZXJhbFN0YXJ0OiBudW1iZXIgfCBudWxsID0gbnVsbDtcblxuICBmdW5jdGlvbiBwcm9jZXNzVmFsdWVTdGFydChjaGFyOiBzdHJpbmcsIGk6IG51bWJlciwgc3dhcFN0YXRlOiBTdGF0ZSkge1xuICAgIHtcbiAgICAgIHN3aXRjaCAoY2hhcikge1xuICAgICAgICBjYXNlICdcIic6IHtcbiAgICAgICAgICBsYXN0VmFsaWRJbmRleCA9IGk7XG4gICAgICAgICAgc3RhY2sucG9wKCk7XG4gICAgICAgICAgc3RhY2sucHVzaChzd2FwU3RhdGUpO1xuICAgICAgICAgIHN0YWNrLnB1c2goJ0lOU0lERV9TVFJJTkcnKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGNhc2UgJ2YnOlxuICAgICAgICBjYXNlICd0JzpcbiAgICAgICAgY2FzZSAnbic6IHtcbiAgICAgICAgICBsYXN0VmFsaWRJbmRleCA9IGk7XG4gICAgICAgICAgbGl0ZXJhbFN0YXJ0ID0gaTtcbiAgICAgICAgICBzdGFjay5wb3AoKTtcbiAgICAgICAgICBzdGFjay5wdXNoKHN3YXBTdGF0ZSk7XG4gICAgICAgICAgc3RhY2sucHVzaCgnSU5TSURFX0xJVEVSQUwnKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGNhc2UgJy0nOiB7XG4gICAgICAgICAgc3RhY2sucG9wKCk7XG4gICAgICAgICAgc3RhY2sucHVzaChzd2FwU3RhdGUpO1xuICAgICAgICAgIHN0YWNrLnB1c2goJ0lOU0lERV9OVU1CRVInKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlICcwJzpcbiAgICAgICAgY2FzZSAnMSc6XG4gICAgICAgIGNhc2UgJzInOlxuICAgICAgICBjYXNlICczJzpcbiAgICAgICAgY2FzZSAnNCc6XG4gICAgICAgIGNhc2UgJzUnOlxuICAgICAgICBjYXNlICc2JzpcbiAgICAgICAgY2FzZSAnNyc6XG4gICAgICAgIGNhc2UgJzgnOlxuICAgICAgICBjYXNlICc5Jzoge1xuICAgICAgICAgIGxhc3RWYWxpZEluZGV4ID0gaTtcbiAgICAgICAgICBzdGFjay5wb3AoKTtcbiAgICAgICAgICBzdGFjay5wdXNoKHN3YXBTdGF0ZSk7XG4gICAgICAgICAgc3RhY2sucHVzaCgnSU5TSURFX05VTUJFUicpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgY2FzZSAneyc6IHtcbiAgICAgICAgICBsYXN0VmFsaWRJbmRleCA9IGk7XG4gICAgICAgICAgc3RhY2sucG9wKCk7XG4gICAgICAgICAgc3RhY2sucHVzaChzd2FwU3RhdGUpO1xuICAgICAgICAgIHN0YWNrLnB1c2goJ0lOU0lERV9PQkpFQ1RfU1RBUlQnKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGNhc2UgJ1snOiB7XG4gICAgICAgICAgbGFzdFZhbGlkSW5kZXggPSBpO1xuICAgICAgICAgIHN0YWNrLnBvcCgpO1xuICAgICAgICAgIHN0YWNrLnB1c2goc3dhcFN0YXRlKTtcbiAgICAgICAgICBzdGFjay5wdXNoKCdJTlNJREVfQVJSQVlfU1RBUlQnKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHByb2Nlc3NBZnRlck9iamVjdFZhbHVlKGNoYXI6IHN0cmluZywgaTogbnVtYmVyKSB7XG4gICAgc3dpdGNoIChjaGFyKSB7XG4gICAgICBjYXNlICcsJzoge1xuICAgICAgICBzdGFjay5wb3AoKTtcbiAgICAgICAgc3RhY2sucHVzaCgnSU5TSURFX09CSkVDVF9BRlRFUl9DT01NQScpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ30nOiB7XG4gICAgICAgIGxhc3RWYWxpZEluZGV4ID0gaTtcbiAgICAgICAgc3RhY2sucG9wKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHByb2Nlc3NBZnRlckFycmF5VmFsdWUoY2hhcjogc3RyaW5nLCBpOiBudW1iZXIpIHtcbiAgICBzd2l0Y2ggKGNoYXIpIHtcbiAgICAgIGNhc2UgJywnOiB7XG4gICAgICAgIHN0YWNrLnBvcCgpO1xuICAgICAgICBzdGFjay5wdXNoKCdJTlNJREVfQVJSQVlfQUZURVJfQ09NTUEnKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICddJzoge1xuICAgICAgICBsYXN0VmFsaWRJbmRleCA9IGk7XG4gICAgICAgIHN0YWNrLnBvcCgpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGlucHV0Lmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgY2hhciA9IGlucHV0W2ldO1xuICAgIGNvbnN0IGN1cnJlbnRTdGF0ZSA9IHN0YWNrW3N0YWNrLmxlbmd0aCAtIDFdO1xuXG4gICAgc3dpdGNoIChjdXJyZW50U3RhdGUpIHtcbiAgICAgIGNhc2UgJ1JPT1QnOlxuICAgICAgICBwcm9jZXNzVmFsdWVTdGFydChjaGFyLCBpLCAnRklOSVNIJyk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdJTlNJREVfT0JKRUNUX1NUQVJUJzoge1xuICAgICAgICBzd2l0Y2ggKGNoYXIpIHtcbiAgICAgICAgICBjYXNlICdcIic6IHtcbiAgICAgICAgICAgIHN0YWNrLnBvcCgpO1xuICAgICAgICAgICAgc3RhY2sucHVzaCgnSU5TSURFX09CSkVDVF9LRVknKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlICd9Jzoge1xuICAgICAgICAgICAgbGFzdFZhbGlkSW5kZXggPSBpO1xuICAgICAgICAgICAgc3RhY2sucG9wKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGNhc2UgJ0lOU0lERV9PQkpFQ1RfQUZURVJfQ09NTUEnOiB7XG4gICAgICAgIHN3aXRjaCAoY2hhcikge1xuICAgICAgICAgIGNhc2UgJ1wiJzoge1xuICAgICAgICAgICAgc3RhY2sucG9wKCk7XG4gICAgICAgICAgICBzdGFjay5wdXNoKCdJTlNJREVfT0JKRUNUX0tFWScpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBjYXNlICdJTlNJREVfT0JKRUNUX0tFWSc6IHtcbiAgICAgICAgc3dpdGNoIChjaGFyKSB7XG4gICAgICAgICAgY2FzZSAnXCInOiB7XG4gICAgICAgICAgICBzdGFjay5wb3AoKTtcbiAgICAgICAgICAgIHN0YWNrLnB1c2goJ0lOU0lERV9PQkpFQ1RfQUZURVJfS0VZJyk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGNhc2UgJ0lOU0lERV9PQkpFQ1RfQUZURVJfS0VZJzoge1xuICAgICAgICBzd2l0Y2ggKGNoYXIpIHtcbiAgICAgICAgICBjYXNlICc6Jzoge1xuICAgICAgICAgICAgc3RhY2sucG9wKCk7XG4gICAgICAgICAgICBzdGFjay5wdXNoKCdJTlNJREVfT0JKRUNUX0JFRk9SRV9WQUxVRScpO1xuXG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGNhc2UgJ0lOU0lERV9PQkpFQ1RfQkVGT1JFX1ZBTFVFJzoge1xuICAgICAgICBwcm9jZXNzVmFsdWVTdGFydChjaGFyLCBpLCAnSU5TSURFX09CSkVDVF9BRlRFUl9WQUxVRScpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgY2FzZSAnSU5TSURFX09CSkVDVF9BRlRFUl9WQUxVRSc6IHtcbiAgICAgICAgcHJvY2Vzc0FmdGVyT2JqZWN0VmFsdWUoY2hhciwgaSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBjYXNlICdJTlNJREVfU1RSSU5HJzoge1xuICAgICAgICBzd2l0Y2ggKGNoYXIpIHtcbiAgICAgICAgICBjYXNlICdcIic6IHtcbiAgICAgICAgICAgIHN0YWNrLnBvcCgpO1xuICAgICAgICAgICAgbGFzdFZhbGlkSW5kZXggPSBpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY2FzZSAnXFxcXCc6IHtcbiAgICAgICAgICAgIHN0YWNrLnB1c2goJ0lOU0lERV9TVFJJTkdfRVNDQVBFJyk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICBsYXN0VmFsaWRJbmRleCA9IGk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGNhc2UgJ0lOU0lERV9BUlJBWV9TVEFSVCc6IHtcbiAgICAgICAgc3dpdGNoIChjaGFyKSB7XG4gICAgICAgICAgY2FzZSAnXSc6IHtcbiAgICAgICAgICAgIGxhc3RWYWxpZEluZGV4ID0gaTtcbiAgICAgICAgICAgIHN0YWNrLnBvcCgpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgbGFzdFZhbGlkSW5kZXggPSBpO1xuICAgICAgICAgICAgcHJvY2Vzc1ZhbHVlU3RhcnQoY2hhciwgaSwgJ0lOU0lERV9BUlJBWV9BRlRFUl9WQUxVRScpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBjYXNlICdJTlNJREVfQVJSQVlfQUZURVJfVkFMVUUnOiB7XG4gICAgICAgIHN3aXRjaCAoY2hhcikge1xuICAgICAgICAgIGNhc2UgJywnOiB7XG4gICAgICAgICAgICBzdGFjay5wb3AoKTtcbiAgICAgICAgICAgIHN0YWNrLnB1c2goJ0lOU0lERV9BUlJBWV9BRlRFUl9DT01NQScpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY2FzZSAnXSc6IHtcbiAgICAgICAgICAgIGxhc3RWYWxpZEluZGV4ID0gaTtcbiAgICAgICAgICAgIHN0YWNrLnBvcCgpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgbGFzdFZhbGlkSW5kZXggPSBpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGNhc2UgJ0lOU0lERV9BUlJBWV9BRlRFUl9DT01NQSc6IHtcbiAgICAgICAgcHJvY2Vzc1ZhbHVlU3RhcnQoY2hhciwgaSwgJ0lOU0lERV9BUlJBWV9BRlRFUl9WQUxVRScpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgY2FzZSAnSU5TSURFX1NUUklOR19FU0NBUEUnOiB7XG4gICAgICAgIHN0YWNrLnBvcCgpO1xuICAgICAgICBsYXN0VmFsaWRJbmRleCA9IGk7XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGNhc2UgJ0lOU0lERV9OVU1CRVInOiB7XG4gICAgICAgIHN3aXRjaCAoY2hhcikge1xuICAgICAgICAgIGNhc2UgJzAnOlxuICAgICAgICAgIGNhc2UgJzEnOlxuICAgICAgICAgIGNhc2UgJzInOlxuICAgICAgICAgIGNhc2UgJzMnOlxuICAgICAgICAgIGNhc2UgJzQnOlxuICAgICAgICAgIGNhc2UgJzUnOlxuICAgICAgICAgIGNhc2UgJzYnOlxuICAgICAgICAgIGNhc2UgJzcnOlxuICAgICAgICAgIGNhc2UgJzgnOlxuICAgICAgICAgIGNhc2UgJzknOiB7XG4gICAgICAgICAgICBsYXN0VmFsaWRJbmRleCA9IGk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjYXNlICdlJzpcbiAgICAgICAgICBjYXNlICdFJzpcbiAgICAgICAgICBjYXNlICctJzpcbiAgICAgICAgICBjYXNlICcuJzoge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY2FzZSAnLCc6IHtcbiAgICAgICAgICAgIHN0YWNrLnBvcCgpO1xuXG4gICAgICAgICAgICBpZiAoc3RhY2tbc3RhY2subGVuZ3RoIC0gMV0gPT09ICdJTlNJREVfQVJSQVlfQUZURVJfVkFMVUUnKSB7XG4gICAgICAgICAgICAgIHByb2Nlc3NBZnRlckFycmF5VmFsdWUoY2hhciwgaSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChzdGFja1tzdGFjay5sZW5ndGggLSAxXSA9PT0gJ0lOU0lERV9PQkpFQ1RfQUZURVJfVkFMVUUnKSB7XG4gICAgICAgICAgICAgIHByb2Nlc3NBZnRlck9iamVjdFZhbHVlKGNoYXIsIGkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjYXNlICd9Jzoge1xuICAgICAgICAgICAgc3RhY2sucG9wKCk7XG5cbiAgICAgICAgICAgIGlmIChzdGFja1tzdGFjay5sZW5ndGggLSAxXSA9PT0gJ0lOU0lERV9PQkpFQ1RfQUZURVJfVkFMVUUnKSB7XG4gICAgICAgICAgICAgIHByb2Nlc3NBZnRlck9iamVjdFZhbHVlKGNoYXIsIGkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjYXNlICddJzoge1xuICAgICAgICAgICAgc3RhY2sucG9wKCk7XG5cbiAgICAgICAgICAgIGlmIChzdGFja1tzdGFjay5sZW5ndGggLSAxXSA9PT0gJ0lOU0lERV9BUlJBWV9BRlRFUl9WQUxVRScpIHtcbiAgICAgICAgICAgICAgcHJvY2Vzc0FmdGVyQXJyYXlWYWx1ZShjaGFyLCBpKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgc3RhY2sucG9wKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgY2FzZSAnSU5TSURFX0xJVEVSQUwnOiB7XG4gICAgICAgIGNvbnN0IHBhcnRpYWxMaXRlcmFsID0gaW5wdXQuc3Vic3RyaW5nKGxpdGVyYWxTdGFydCEsIGkgKyAxKTtcblxuICAgICAgICBpZiAoXG4gICAgICAgICAgISdmYWxzZScuc3RhcnRzV2l0aChwYXJ0aWFsTGl0ZXJhbCkgJiZcbiAgICAgICAgICAhJ3RydWUnLnN0YXJ0c1dpdGgocGFydGlhbExpdGVyYWwpICYmXG4gICAgICAgICAgISdudWxsJy5zdGFydHNXaXRoKHBhcnRpYWxMaXRlcmFsKVxuICAgICAgICApIHtcbiAgICAgICAgICBzdGFjay5wb3AoKTtcblxuICAgICAgICAgIGlmIChzdGFja1tzdGFjay5sZW5ndGggLSAxXSA9PT0gJ0lOU0lERV9PQkpFQ1RfQUZURVJfVkFMVUUnKSB7XG4gICAgICAgICAgICBwcm9jZXNzQWZ0ZXJPYmplY3RWYWx1ZShjaGFyLCBpKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHN0YWNrW3N0YWNrLmxlbmd0aCAtIDFdID09PSAnSU5TSURFX0FSUkFZX0FGVEVSX1ZBTFVFJykge1xuICAgICAgICAgICAgcHJvY2Vzc0FmdGVyQXJyYXlWYWx1ZShjaGFyLCBpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbGFzdFZhbGlkSW5kZXggPSBpO1xuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgbGV0IHJlc3VsdCA9IGlucHV0LnNsaWNlKDAsIGxhc3RWYWxpZEluZGV4ICsgMSk7XG5cbiAgZm9yIChsZXQgaSA9IHN0YWNrLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgY29uc3Qgc3RhdGUgPSBzdGFja1tpXTtcblxuICAgIHN3aXRjaCAoc3RhdGUpIHtcbiAgICAgIGNhc2UgJ0lOU0lERV9TVFJJTkcnOiB7XG4gICAgICAgIHJlc3VsdCArPSAnXCInO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgY2FzZSAnSU5TSURFX09CSkVDVF9LRVknOlxuICAgICAgY2FzZSAnSU5TSURFX09CSkVDVF9BRlRFUl9LRVknOlxuICAgICAgY2FzZSAnSU5TSURFX09CSkVDVF9BRlRFUl9DT01NQSc6XG4gICAgICBjYXNlICdJTlNJREVfT0JKRUNUX1NUQVJUJzpcbiAgICAgIGNhc2UgJ0lOU0lERV9PQkpFQ1RfQkVGT1JFX1ZBTFVFJzpcbiAgICAgIGNhc2UgJ0lOU0lERV9PQkpFQ1RfQUZURVJfVkFMVUUnOiB7XG4gICAgICAgIHJlc3VsdCArPSAnfSc7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBjYXNlICdJTlNJREVfQVJSQVlfU1RBUlQnOlxuICAgICAgY2FzZSAnSU5TSURFX0FSUkFZX0FGVEVSX0NPTU1BJzpcbiAgICAgIGNhc2UgJ0lOU0lERV9BUlJBWV9BRlRFUl9WQUxVRSc6IHtcbiAgICAgICAgcmVzdWx0ICs9ICddJztcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGNhc2UgJ0lOU0lERV9MSVRFUkFMJzoge1xuICAgICAgICBjb25zdCBwYXJ0aWFsTGl0ZXJhbCA9IGlucHV0LnN1YnN0cmluZyhsaXRlcmFsU3RhcnQhLCBpbnB1dC5sZW5ndGgpO1xuXG4gICAgICAgIGlmICgndHJ1ZScuc3RhcnRzV2l0aChwYXJ0aWFsTGl0ZXJhbCkpIHtcbiAgICAgICAgICByZXN1bHQgKz0gJ3RydWUnLnNsaWNlKHBhcnRpYWxMaXRlcmFsLmxlbmd0aCk7XG4gICAgICAgIH0gZWxzZSBpZiAoJ2ZhbHNlJy5zdGFydHNXaXRoKHBhcnRpYWxMaXRlcmFsKSkge1xuICAgICAgICAgIHJlc3VsdCArPSAnZmFsc2UnLnNsaWNlKHBhcnRpYWxMaXRlcmFsLmxlbmd0aCk7XG4gICAgICAgIH0gZWxzZSBpZiAoJ251bGwnLnN0YXJ0c1dpdGgocGFydGlhbExpdGVyYWwpKSB7XG4gICAgICAgICAgcmVzdWx0ICs9ICdudWxsJy5zbGljZShwYXJ0aWFsTGl0ZXJhbC5sZW5ndGgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cbiIsICJpbXBvcnQge1xuICBJbmZlclRvb2xJbnB1dCxcbiAgSW5mZXJUb29sT3V0cHV0LFxuICBUb29sLFxuICBUb29sQ2FsbCxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyBUb29sU2V0IH0gZnJvbSAnLi4vZ2VuZXJhdGUtdGV4dCc7XG5pbXBvcnQgeyBQcm92aWRlck1ldGFkYXRhIH0gZnJvbSAnLi4vdHlwZXMvcHJvdmlkZXItbWV0YWRhdGEnO1xuaW1wb3J0IHsgRGVlcFBhcnRpYWwgfSBmcm9tICcuLi91dGlsL2RlZXAtcGFydGlhbCc7XG5pbXBvcnQgeyBWYWx1ZU9mIH0gZnJvbSAnLi4vdXRpbC92YWx1ZS1vZic7XG5cbi8qKlxuVGhlIGRhdGEgdHlwZXMgdGhhdCBjYW4gYmUgdXNlZCBpbiB0aGUgVUkgbWVzc2FnZSBmb3IgdGhlIFVJIG1lc3NhZ2UgZGF0YSBwYXJ0cy5cbiAqL1xuZXhwb3J0IHR5cGUgVUlEYXRhVHlwZXMgPSBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcblxuZXhwb3J0IHR5cGUgVUlUb29sID0ge1xuICBpbnB1dDogdW5rbm93bjtcbiAgb3V0cHV0OiB1bmtub3duIHwgdW5kZWZpbmVkO1xufTtcblxuLyoqXG4gKiBJbmZlciB0aGUgaW5wdXQgYW5kIG91dHB1dCB0eXBlcyBvZiBhIHRvb2wgc28gaXQgY2FuIGJlIHVzZWQgYXMgYSBVSSB0b29sLlxuICovXG5leHBvcnQgdHlwZSBJbmZlclVJVG9vbDxUT09MIGV4dGVuZHMgVG9vbD4gPSB7XG4gIGlucHV0OiBJbmZlclRvb2xJbnB1dDxUT09MPjtcbiAgb3V0cHV0OiBJbmZlclRvb2xPdXRwdXQ8VE9PTD47XG59O1xuXG4vKipcbiAqIEluZmVyIHRoZSBpbnB1dCBhbmQgb3V0cHV0IHR5cGVzIG9mIGEgdG9vbCBzZXQgc28gaXQgY2FuIGJlIHVzZWQgYXMgYSBVSSB0b29sIHNldC5cbiAqL1xuZXhwb3J0IHR5cGUgSW5mZXJVSVRvb2xzPFRPT0xTIGV4dGVuZHMgVG9vbFNldD4gPSB7XG4gIFtOQU1FIGluIGtleW9mIFRPT0xTICYgc3RyaW5nXTogSW5mZXJVSVRvb2w8VE9PTFNbTkFNRV0+O1xufTtcblxuZXhwb3J0IHR5cGUgVUlUb29scyA9IFJlY29yZDxzdHJpbmcsIFVJVG9vbD47XG5cbi8qKlxuQUkgU0RLIFVJIE1lc3NhZ2VzLiBUaGV5IGFyZSB1c2VkIGluIHRoZSBjbGllbnQgYW5kIHRvIGNvbW11bmljYXRlIGJldHdlZW4gdGhlIGZyb250ZW5kIGFuZCB0aGUgQVBJIHJvdXRlcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBVSU1lc3NhZ2U8XG4gIE1FVEFEQVRBID0gdW5rbm93bixcbiAgREFUQV9QQVJUUyBleHRlbmRzIFVJRGF0YVR5cGVzID0gVUlEYXRhVHlwZXMsXG4gIFRPT0xTIGV4dGVuZHMgVUlUb29scyA9IFVJVG9vbHMsXG4+IHtcbiAgLyoqXG5BIHVuaXF1ZSBpZGVudGlmaWVyIGZvciB0aGUgbWVzc2FnZS5cbiAgICovXG4gIGlkOiBzdHJpbmc7XG5cbiAgLyoqXG5UaGUgcm9sZSBvZiB0aGUgbWVzc2FnZS5cbiAgICovXG4gIHJvbGU6ICdzeXN0ZW0nIHwgJ3VzZXInIHwgJ2Fzc2lzdGFudCc7XG5cbiAgLyoqXG5UaGUgbWV0YWRhdGEgb2YgdGhlIG1lc3NhZ2UuXG4gICAqL1xuICBtZXRhZGF0YT86IE1FVEFEQVRBO1xuXG4gIC8qKlxuVGhlIHBhcnRzIG9mIHRoZSBtZXNzYWdlLiBVc2UgdGhpcyBmb3IgcmVuZGVyaW5nIHRoZSBtZXNzYWdlIGluIHRoZSBVSS5cblxuU3lzdGVtIG1lc3NhZ2VzIHNob3VsZCBiZSBhdm9pZGVkIChzZXQgdGhlIHN5c3RlbSBwcm9tcHQgb24gdGhlIHNlcnZlciBpbnN0ZWFkKS5cblRoZXkgY2FuIGhhdmUgdGV4dCBwYXJ0cy5cblxuVXNlciBtZXNzYWdlcyBjYW4gaGF2ZSB0ZXh0IHBhcnRzIGFuZCBmaWxlIHBhcnRzLlxuXG5Bc3Npc3RhbnQgbWVzc2FnZXMgY2FuIGhhdmUgdGV4dCwgcmVhc29uaW5nLCB0b29sIGludm9jYXRpb24sIGFuZCBmaWxlIHBhcnRzLlxuICAgKi9cbiAgcGFydHM6IEFycmF5PFVJTWVzc2FnZVBhcnQ8REFUQV9QQVJUUywgVE9PTFM+Pjtcbn1cblxuZXhwb3J0IHR5cGUgVUlNZXNzYWdlUGFydDxcbiAgREFUQV9UWVBFUyBleHRlbmRzIFVJRGF0YVR5cGVzLFxuICBUT09MUyBleHRlbmRzIFVJVG9vbHMsXG4+ID1cbiAgfCBUZXh0VUlQYXJ0XG4gIHwgUmVhc29uaW5nVUlQYXJ0XG4gIHwgVG9vbFVJUGFydDxUT09MUz5cbiAgfCBEeW5hbWljVG9vbFVJUGFydFxuICB8IFNvdXJjZVVybFVJUGFydFxuICB8IFNvdXJjZURvY3VtZW50VUlQYXJ0XG4gIHwgRmlsZVVJUGFydFxuICB8IERhdGFVSVBhcnQ8REFUQV9UWVBFUz5cbiAgfCBTdGVwU3RhcnRVSVBhcnQ7XG5cbi8qKlxuICogQSB0ZXh0IHBhcnQgb2YgYSBtZXNzYWdlLlxuICovXG5leHBvcnQgdHlwZSBUZXh0VUlQYXJ0ID0ge1xuICB0eXBlOiAndGV4dCc7XG5cbiAgLyoqXG4gICAqIFRoZSB0ZXh0IGNvbnRlbnQuXG4gICAqL1xuICB0ZXh0OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBzdGF0ZSBvZiB0aGUgdGV4dCBwYXJ0LlxuICAgKi9cbiAgc3RhdGU/OiAnc3RyZWFtaW5nJyB8ICdkb25lJztcblxuICAvKipcbiAgICogVGhlIHByb3ZpZGVyIG1ldGFkYXRhLlxuICAgKi9cbiAgcHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG59O1xuXG4vKipcbiAqIEEgcmVhc29uaW5nIHBhcnQgb2YgYSBtZXNzYWdlLlxuICovXG5leHBvcnQgdHlwZSBSZWFzb25pbmdVSVBhcnQgPSB7XG4gIHR5cGU6ICdyZWFzb25pbmcnO1xuXG4gIC8qKlxuICAgKiBUaGUgcmVhc29uaW5nIHRleHQuXG4gICAqL1xuICB0ZXh0OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBzdGF0ZSBvZiB0aGUgcmVhc29uaW5nIHBhcnQuXG4gICAqL1xuICBzdGF0ZT86ICdzdHJlYW1pbmcnIHwgJ2RvbmUnO1xuXG4gIC8qKlxuICAgKiBUaGUgcHJvdmlkZXIgbWV0YWRhdGEuXG4gICAqL1xuICBwcm92aWRlck1ldGFkYXRhPzogUHJvdmlkZXJNZXRhZGF0YTtcbn07XG5cbi8qKlxuICogQSBzb3VyY2UgcGFydCBvZiBhIG1lc3NhZ2UuXG4gKi9cbmV4cG9ydCB0eXBlIFNvdXJjZVVybFVJUGFydCA9IHtcbiAgdHlwZTogJ3NvdXJjZS11cmwnO1xuICBzb3VyY2VJZDogc3RyaW5nO1xuICB1cmw6IHN0cmluZztcbiAgdGl0bGU/OiBzdHJpbmc7XG4gIHByb3ZpZGVyTWV0YWRhdGE/OiBQcm92aWRlck1ldGFkYXRhO1xufTtcblxuLyoqXG4gKiBBIGRvY3VtZW50IHNvdXJjZSBwYXJ0IG9mIGEgbWVzc2FnZS5cbiAqL1xuZXhwb3J0IHR5cGUgU291cmNlRG9jdW1lbnRVSVBhcnQgPSB7XG4gIHR5cGU6ICdzb3VyY2UtZG9jdW1lbnQnO1xuICBzb3VyY2VJZDogc3RyaW5nO1xuICBtZWRpYVR5cGU6IHN0cmluZztcbiAgdGl0bGU6IHN0cmluZztcbiAgZmlsZW5hbWU/OiBzdHJpbmc7XG4gIHByb3ZpZGVyTWV0YWRhdGE/OiBQcm92aWRlck1ldGFkYXRhO1xufTtcblxuLyoqXG4gKiBBIGZpbGUgcGFydCBvZiBhIG1lc3NhZ2UuXG4gKi9cbmV4cG9ydCB0eXBlIEZpbGVVSVBhcnQgPSB7XG4gIHR5cGU6ICdmaWxlJztcblxuICAvKipcbiAgICogSUFOQSBtZWRpYSB0eXBlIG9mIHRoZSBmaWxlLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vd3d3LmlhbmEub3JnL2Fzc2lnbm1lbnRzL21lZGlhLXR5cGVzL21lZGlhLXR5cGVzLnhodG1sXG4gICAqL1xuICBtZWRpYVR5cGU6IHN0cmluZztcblxuICAvKipcbiAgICogT3B0aW9uYWwgZmlsZW5hbWUgb2YgdGhlIGZpbGUuXG4gICAqL1xuICBmaWxlbmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIFVSTCBvZiB0aGUgZmlsZS5cbiAgICogSXQgY2FuIGVpdGhlciBiZSBhIFVSTCB0byBhIGhvc3RlZCBmaWxlIG9yIGEgW0RhdGEgVVJMXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVFRQL0Jhc2ljc19vZl9IVFRQL0RhdGFfVVJMcykuXG4gICAqL1xuICB1cmw6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHByb3ZpZGVyIG1ldGFkYXRhLlxuICAgKi9cbiAgcHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG59O1xuXG4vKipcbiAqIEEgc3RlcCBib3VuZGFyeSBwYXJ0IG9mIGEgbWVzc2FnZS5cbiAqL1xuZXhwb3J0IHR5cGUgU3RlcFN0YXJ0VUlQYXJ0ID0ge1xuICB0eXBlOiAnc3RlcC1zdGFydCc7XG59O1xuXG5leHBvcnQgdHlwZSBEYXRhVUlQYXJ0PERBVEFfVFlQRVMgZXh0ZW5kcyBVSURhdGFUeXBlcz4gPSBWYWx1ZU9mPHtcbiAgW05BTUUgaW4ga2V5b2YgREFUQV9UWVBFUyAmIHN0cmluZ106IHtcbiAgICB0eXBlOiBgZGF0YS0ke05BTUV9YDtcbiAgICBpZD86IHN0cmluZztcbiAgICBkYXRhOiBEQVRBX1RZUEVTW05BTUVdO1xuICB9O1xufT47XG5cbnR5cGUgYXNVSVRvb2w8VE9PTCBleHRlbmRzIFVJVG9vbCB8IFRvb2w+ID0gVE9PTCBleHRlbmRzIFRvb2xcbiAgPyBJbmZlclVJVG9vbDxUT09MPlxuICA6IFRPT0w7XG5cbi8qKlxuICogQ2hlY2sgaWYgYSBtZXNzYWdlIHBhcnQgaXMgYSBkYXRhIHBhcnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0RhdGFVSVBhcnQ8REFUQV9UWVBFUyBleHRlbmRzIFVJRGF0YVR5cGVzPihcbiAgcGFydDogVUlNZXNzYWdlUGFydDxEQVRBX1RZUEVTLCBVSVRvb2xzPixcbik6IHBhcnQgaXMgRGF0YVVJUGFydDxEQVRBX1RZUEVTPiB7XG4gIHJldHVybiBwYXJ0LnR5cGUuc3RhcnRzV2l0aCgnZGF0YS0nKTtcbn1cblxuLyoqXG4gKiBBIFVJIHRvb2wgaW52b2NhdGlvbiBjb250YWlucyBhbGwgdGhlIGluZm9ybWF0aW9uIG5lZWRlZCB0byByZW5kZXIgYSB0b29sIGludm9jYXRpb24gaW4gdGhlIFVJLlxuICogSXQgY2FuIGJlIGRlcml2ZWQgZnJvbSBhIHRvb2wgd2l0aG91dCBrbm93aW5nIHRoZSB0b29sIG5hbWUsIGFuZCBjYW4gYmUgdXNlZCB0byBkZWZpbmVcbiAqIFVJIGNvbXBvbmVudHMgZm9yIHRoZSB0b29sLlxuICovXG5leHBvcnQgdHlwZSBVSVRvb2xJbnZvY2F0aW9uPFRPT0wgZXh0ZW5kcyBVSVRvb2wgfCBUb29sPiA9IHtcbiAgdG9vbENhbGxJZDogc3RyaW5nO1xufSAmIChcbiAgfCB7XG4gICAgICBzdGF0ZTogJ2lucHV0LXN0cmVhbWluZyc7XG4gICAgICBpbnB1dDogRGVlcFBhcnRpYWw8YXNVSVRvb2w8VE9PTD5bJ2lucHV0J10+IHwgdW5kZWZpbmVkO1xuICAgICAgcHJvdmlkZXJFeGVjdXRlZD86IGJvb2xlYW47XG4gICAgICBvdXRwdXQ/OiBuZXZlcjtcbiAgICAgIGVycm9yVGV4dD86IG5ldmVyO1xuICAgIH1cbiAgfCB7XG4gICAgICBzdGF0ZTogJ2lucHV0LWF2YWlsYWJsZSc7XG4gICAgICBpbnB1dDogYXNVSVRvb2w8VE9PTD5bJ2lucHV0J107XG4gICAgICBwcm92aWRlckV4ZWN1dGVkPzogYm9vbGVhbjtcbiAgICAgIG91dHB1dD86IG5ldmVyO1xuICAgICAgZXJyb3JUZXh0PzogbmV2ZXI7XG4gICAgICBjYWxsUHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG4gICAgfVxuICB8IHtcbiAgICAgIHN0YXRlOiAnb3V0cHV0LWF2YWlsYWJsZSc7XG4gICAgICBpbnB1dDogYXNVSVRvb2w8VE9PTD5bJ2lucHV0J107XG4gICAgICBvdXRwdXQ6IGFzVUlUb29sPFRPT0w+WydvdXRwdXQnXTtcbiAgICAgIGVycm9yVGV4dD86IG5ldmVyO1xuICAgICAgcHJvdmlkZXJFeGVjdXRlZD86IGJvb2xlYW47XG4gICAgICBjYWxsUHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG4gICAgICBwcmVsaW1pbmFyeT86IGJvb2xlYW47XG4gICAgfVxuICB8IHtcbiAgICAgIHN0YXRlOiAnb3V0cHV0LWVycm9yJzsgLy8gVE9ETyBBSSBTREsgNjogY2hhbmdlIHRvICdlcnJvcicgc3RhdGVcbiAgICAgIGlucHV0OiBhc1VJVG9vbDxUT09MPlsnaW5wdXQnXSB8IHVuZGVmaW5lZDtcbiAgICAgIHJhd0lucHV0PzogdW5rbm93bjsgLy8gVE9ETyBBSSBTREsgNjogcmVtb3ZlIHRoaXMgZmllbGQsIGlucHV0IHNob3VsZCBiZSB1bmtub3duXG4gICAgICBvdXRwdXQ/OiBuZXZlcjtcbiAgICAgIGVycm9yVGV4dDogc3RyaW5nO1xuICAgICAgcHJvdmlkZXJFeGVjdXRlZD86IGJvb2xlYW47XG4gICAgICBjYWxsUHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG4gICAgfVxuKTtcblxuZXhwb3J0IHR5cGUgVG9vbFVJUGFydDxUT09MUyBleHRlbmRzIFVJVG9vbHMgPSBVSVRvb2xzPiA9IFZhbHVlT2Y8e1xuICBbTkFNRSBpbiBrZXlvZiBUT09MUyAmIHN0cmluZ106IHtcbiAgICB0eXBlOiBgdG9vbC0ke05BTUV9YDtcbiAgfSAmIFVJVG9vbEludm9jYXRpb248VE9PTFNbTkFNRV0+O1xufT47XG5cbmV4cG9ydCB0eXBlIER5bmFtaWNUb29sVUlQYXJ0ID0ge1xuICB0eXBlOiAnZHluYW1pYy10b29sJztcbiAgdG9vbE5hbWU6IHN0cmluZztcbiAgdG9vbENhbGxJZDogc3RyaW5nO1xufSAmIChcbiAgfCB7XG4gICAgICBzdGF0ZTogJ2lucHV0LXN0cmVhbWluZyc7XG4gICAgICBpbnB1dDogdW5rbm93biB8IHVuZGVmaW5lZDtcbiAgICAgIG91dHB1dD86IG5ldmVyO1xuICAgICAgZXJyb3JUZXh0PzogbmV2ZXI7XG4gICAgfVxuICB8IHtcbiAgICAgIHN0YXRlOiAnaW5wdXQtYXZhaWxhYmxlJztcbiAgICAgIGlucHV0OiB1bmtub3duO1xuICAgICAgb3V0cHV0PzogbmV2ZXI7XG4gICAgICBlcnJvclRleHQ/OiBuZXZlcjtcbiAgICAgIGNhbGxQcm92aWRlck1ldGFkYXRhPzogUHJvdmlkZXJNZXRhZGF0YTtcbiAgICB9XG4gIHwge1xuICAgICAgc3RhdGU6ICdvdXRwdXQtYXZhaWxhYmxlJztcbiAgICAgIGlucHV0OiB1bmtub3duO1xuICAgICAgb3V0cHV0OiB1bmtub3duO1xuICAgICAgZXJyb3JUZXh0PzogbmV2ZXI7XG4gICAgICBjYWxsUHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG4gICAgICBwcmVsaW1pbmFyeT86IGJvb2xlYW47XG4gICAgfVxuICB8IHtcbiAgICAgIHN0YXRlOiAnb3V0cHV0LWVycm9yJzsgLy8gVE9ETyBBSSBTREsgNjogY2hhbmdlIHRvICdlcnJvcicgc3RhdGVcbiAgICAgIGlucHV0OiB1bmtub3duO1xuICAgICAgb3V0cHV0PzogbmV2ZXI7XG4gICAgICBlcnJvclRleHQ6IHN0cmluZztcbiAgICAgIGNhbGxQcm92aWRlck1ldGFkYXRhPzogUHJvdmlkZXJNZXRhZGF0YTtcbiAgICB9XG4pO1xuXG5leHBvcnQgZnVuY3Rpb24gaXNUb29sVUlQYXJ0PFRPT0xTIGV4dGVuZHMgVUlUb29scz4oXG4gIHBhcnQ6IFVJTWVzc2FnZVBhcnQ8VUlEYXRhVHlwZXMsIFRPT0xTPixcbik6IHBhcnQgaXMgVG9vbFVJUGFydDxUT09MUz4ge1xuICByZXR1cm4gcGFydC50eXBlLnN0YXJ0c1dpdGgoJ3Rvb2wtJyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0R5bmFtaWNUb29sVUlQYXJ0KFxuICBwYXJ0OiBVSU1lc3NhZ2VQYXJ0PFVJRGF0YVR5cGVzLCBVSVRvb2xzPixcbik6IHBhcnQgaXMgRHluYW1pY1Rvb2xVSVBhcnQge1xuICByZXR1cm4gcGFydC50eXBlID09PSAnZHluYW1pYy10b29sJztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzVG9vbE9yRHluYW1pY1Rvb2xVSVBhcnQ8VE9PTFMgZXh0ZW5kcyBVSVRvb2xzPihcbiAgcGFydDogVUlNZXNzYWdlUGFydDxVSURhdGFUeXBlcywgVE9PTFM+LFxuKTogcGFydCBpcyBUb29sVUlQYXJ0PFRPT0xTPiB8IER5bmFtaWNUb29sVUlQYXJ0IHtcbiAgcmV0dXJuIGlzVG9vbFVJUGFydChwYXJ0KSB8fCBpc0R5bmFtaWNUb29sVUlQYXJ0KHBhcnQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VG9vbE5hbWU8VE9PTFMgZXh0ZW5kcyBVSVRvb2xzPihcbiAgcGFydDogVG9vbFVJUGFydDxUT09MUz4sXG4pOiBrZXlvZiBUT09MUyB7XG4gIHJldHVybiBwYXJ0LnR5cGUuc3BsaXQoJy0nKS5zbGljZSgxKS5qb2luKCctJykgYXMga2V5b2YgVE9PTFM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRUb29sT3JEeW5hbWljVG9vbE5hbWUoXG4gIHBhcnQ6IFRvb2xVSVBhcnQ8VUlUb29scz4gfCBEeW5hbWljVG9vbFVJUGFydCxcbik6IHN0cmluZyB7XG4gIHJldHVybiBpc0R5bmFtaWNUb29sVUlQYXJ0KHBhcnQpID8gcGFydC50b29sTmFtZSA6IGdldFRvb2xOYW1lKHBhcnQpO1xufVxuXG5leHBvcnQgdHlwZSBJbmZlclVJTWVzc2FnZU1ldGFkYXRhPFQgZXh0ZW5kcyBVSU1lc3NhZ2U+ID1cbiAgVCBleHRlbmRzIFVJTWVzc2FnZTxpbmZlciBNRVRBREFUQT4gPyBNRVRBREFUQSA6IHVua25vd247XG5cbmV4cG9ydCB0eXBlIEluZmVyVUlNZXNzYWdlRGF0YTxUIGV4dGVuZHMgVUlNZXNzYWdlPiA9XG4gIFQgZXh0ZW5kcyBVSU1lc3NhZ2U8dW5rbm93biwgaW5mZXIgREFUQV9UWVBFUz4gPyBEQVRBX1RZUEVTIDogVUlEYXRhVHlwZXM7XG5cbmV4cG9ydCB0eXBlIEluZmVyVUlNZXNzYWdlVG9vbHM8VCBleHRlbmRzIFVJTWVzc2FnZT4gPVxuICBUIGV4dGVuZHMgVUlNZXNzYWdlPHVua25vd24sIFVJRGF0YVR5cGVzLCBpbmZlciBUT09MUz4gPyBUT09MUyA6IFVJVG9vbHM7XG5cbmV4cG9ydCB0eXBlIEluZmVyVUlNZXNzYWdlVG9vbE91dHB1dHM8VUlfTUVTU0FHRSBleHRlbmRzIFVJTWVzc2FnZT4gPVxuICBJbmZlclVJTWVzc2FnZVRvb2xzPFVJX01FU1NBR0U+W2tleW9mIEluZmVyVUlNZXNzYWdlVG9vbHM8VUlfTUVTU0FHRT5dWydvdXRwdXQnXTtcblxuZXhwb3J0IHR5cGUgSW5mZXJVSU1lc3NhZ2VUb29sQ2FsbDxVSV9NRVNTQUdFIGV4dGVuZHMgVUlNZXNzYWdlPiA9XG4gIHwgVmFsdWVPZjx7XG4gICAgICBbTkFNRSBpbiBrZXlvZiBJbmZlclVJTWVzc2FnZVRvb2xzPFVJX01FU1NBR0U+XTogVG9vbENhbGw8XG4gICAgICAgIE5BTUUgJiBzdHJpbmcsXG4gICAgICAgIEluZmVyVUlNZXNzYWdlVG9vbHM8VUlfTUVTU0FHRT5bTkFNRV0gZXh0ZW5kcyB7IGlucHV0OiBpbmZlciBJTlBVVCB9XG4gICAgICAgICAgPyBJTlBVVFxuICAgICAgICAgIDogbmV2ZXJcbiAgICAgID4gJiB7IGR5bmFtaWM/OiBmYWxzZSB9O1xuICAgIH0+XG4gIHwgKFRvb2xDYWxsPHN0cmluZywgdW5rbm93bj4gJiB7IGR5bmFtaWM6IHRydWUgfSk7XG4iLCAiaW1wb3J0IHtcbiAgY3JlYXRlU3RyZWFtaW5nVUlNZXNzYWdlU3RhdGUsXG4gIHByb2Nlc3NVSU1lc3NhZ2VTdHJlYW0sXG4gIFN0cmVhbWluZ1VJTWVzc2FnZVN0YXRlLFxufSBmcm9tICcuLi91aS9wcm9jZXNzLXVpLW1lc3NhZ2Utc3RyZWFtJztcbmltcG9ydCB7IFVJTWVzc2FnZSB9IGZyb20gJy4uL3VpL3VpLW1lc3NhZ2VzJztcbmltcG9ydCB7IEVycm9ySGFuZGxlciB9IGZyb20gJy4uL3V0aWwvZXJyb3ItaGFuZGxlcic7XG5pbXBvcnQgeyBJbmZlclVJTWVzc2FnZUNodW5rLCBVSU1lc3NhZ2VDaHVuayB9IGZyb20gJy4vdWktbWVzc2FnZS1jaHVua3MnO1xuaW1wb3J0IHsgVUlNZXNzYWdlU3RyZWFtT25GaW5pc2hDYWxsYmFjayB9IGZyb20gJy4vdWktbWVzc2FnZS1zdHJlYW0tb24tZmluaXNoLWNhbGxiYWNrJztcblxuZXhwb3J0IGZ1bmN0aW9uIGhhbmRsZVVJTWVzc2FnZVN0cmVhbUZpbmlzaDxVSV9NRVNTQUdFIGV4dGVuZHMgVUlNZXNzYWdlPih7XG4gIG1lc3NhZ2VJZCxcbiAgb3JpZ2luYWxNZXNzYWdlcyA9IFtdLFxuICBvbkZpbmlzaCxcbiAgb25FcnJvcixcbiAgc3RyZWFtLFxufToge1xuICBzdHJlYW06IFJlYWRhYmxlU3RyZWFtPEluZmVyVUlNZXNzYWdlQ2h1bms8VUlfTUVTU0FHRT4+O1xuXG4gIC8qKlxuICAgKiBUaGUgbWVzc2FnZSBJRCB0byB1c2UgZm9yIHRoZSByZXNwb25zZSBtZXNzYWdlLlxuICAgKiBJZiBub3QgcHJvdmlkZWQsIG5vIGlkIHdpbGwgYmUgc2V0IGZvciB0aGUgcmVzcG9uc2UgbWVzc2FnZS5cbiAgICovXG4gIG1lc3NhZ2VJZD86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIG9yaWdpbmFsIG1lc3NhZ2VzLlxuICAgKi9cbiAgb3JpZ2luYWxNZXNzYWdlcz86IFVJX01FU1NBR0VbXTtcblxuICBvbkVycm9yOiBFcnJvckhhbmRsZXI7XG5cbiAgb25GaW5pc2g/OiBVSU1lc3NhZ2VTdHJlYW1PbkZpbmlzaENhbGxiYWNrPFVJX01FU1NBR0U+O1xufSk6IFJlYWRhYmxlU3RyZWFtPEluZmVyVUlNZXNzYWdlQ2h1bms8VUlfTUVTU0FHRT4+IHtcbiAgLy8gbGFzdCBtZXNzYWdlIGlzIG9ubHkgcmVsZXZhbnQgZm9yIGFzc2lzdGFudCBtZXNzYWdlc1xuICBsZXQgbGFzdE1lc3NhZ2U6IFVJX01FU1NBR0UgfCB1bmRlZmluZWQgPVxuICAgIG9yaWdpbmFsTWVzc2FnZXM/LltvcmlnaW5hbE1lc3NhZ2VzLmxlbmd0aCAtIDFdO1xuICBpZiAobGFzdE1lc3NhZ2U/LnJvbGUgIT09ICdhc3Npc3RhbnQnKSB7XG4gICAgbGFzdE1lc3NhZ2UgPSB1bmRlZmluZWQ7XG4gIH0gZWxzZSB7XG4gICAgLy8gYXBwZW5kaW5nIHRvIHRoZSBsYXN0IG1lc3NhZ2UsIHNvIHdlIG5lZWQgdG8gdXNlIHRoZSBzYW1lIGlkXG4gICAgbWVzc2FnZUlkID0gbGFzdE1lc3NhZ2UuaWQ7XG4gIH1cblxuICBsZXQgaXNBYm9ydGVkID0gZmFsc2U7XG5cbiAgY29uc3QgaWRJbmplY3RlZFN0cmVhbSA9IHN0cmVhbS5waXBlVGhyb3VnaChcbiAgICBuZXcgVHJhbnNmb3JtU3RyZWFtPFxuICAgICAgSW5mZXJVSU1lc3NhZ2VDaHVuazxVSV9NRVNTQUdFPixcbiAgICAgIEluZmVyVUlNZXNzYWdlQ2h1bms8VUlfTUVTU0FHRT5cbiAgICA+KHtcbiAgICAgIHRyYW5zZm9ybShjaHVuaywgY29udHJvbGxlcikge1xuICAgICAgICAvLyB3aGVuIHRoZXJlIGlzIG5vIG1lc3NhZ2VJZCBpbiB0aGUgc3RhcnQgY2h1bmssXG4gICAgICAgIC8vIGJ1dCB0aGUgdXNlciBjaGVja2VkIGZvciBwZXJzaXN0ZW5jZSxcbiAgICAgICAgLy8gaW5qZWN0IHRoZSBtZXNzYWdlSWQgaW50byB0aGUgY2h1bmtcbiAgICAgICAgaWYgKGNodW5rLnR5cGUgPT09ICdzdGFydCcpIHtcbiAgICAgICAgICBjb25zdCBzdGFydENodW5rID0gY2h1bmsgYXMgVUlNZXNzYWdlQ2h1bmsgJiB7IHR5cGU6ICdzdGFydCcgfTtcbiAgICAgICAgICBpZiAoc3RhcnRDaHVuay5tZXNzYWdlSWQgPT0gbnVsbCAmJiBtZXNzYWdlSWQgIT0gbnVsbCkge1xuICAgICAgICAgICAgc3RhcnRDaHVuay5tZXNzYWdlSWQgPSBtZXNzYWdlSWQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNodW5rLnR5cGUgPT09ICdhYm9ydCcpIHtcbiAgICAgICAgICBpc0Fib3J0ZWQgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKGNodW5rKTtcbiAgICAgIH0sXG4gICAgfSksXG4gICk7XG5cbiAgaWYgKG9uRmluaXNoID09IG51bGwpIHtcbiAgICByZXR1cm4gaWRJbmplY3RlZFN0cmVhbTtcbiAgfVxuXG4gIGNvbnN0IHN0YXRlID0gY3JlYXRlU3RyZWFtaW5nVUlNZXNzYWdlU3RhdGU8VUlfTUVTU0FHRT4oe1xuICAgIGxhc3RNZXNzYWdlOiBsYXN0TWVzc2FnZVxuICAgICAgPyAoc3RydWN0dXJlZENsb25lKGxhc3RNZXNzYWdlKSBhcyBVSV9NRVNTQUdFKVxuICAgICAgOiB1bmRlZmluZWQsXG4gICAgbWVzc2FnZUlkOiBtZXNzYWdlSWQgPz8gJycsIC8vIHdpbGwgYmUgb3ZlcnJpZGRlbiBieSB0aGUgc3RyZWFtXG4gIH0pO1xuXG4gIGNvbnN0IHJ1blVwZGF0ZU1lc3NhZ2VKb2IgPSBhc3luYyAoXG4gICAgam9iOiAob3B0aW9uczoge1xuICAgICAgc3RhdGU6IFN0cmVhbWluZ1VJTWVzc2FnZVN0YXRlPFVJX01FU1NBR0U+O1xuICAgICAgd3JpdGU6ICgpID0+IHZvaWQ7XG4gICAgfSkgPT4gUHJvbWlzZTx2b2lkPixcbiAgKSA9PiB7XG4gICAgYXdhaXQgam9iKHsgc3RhdGUsIHdyaXRlOiAoKSA9PiB7fSB9KTtcbiAgfTtcblxuICBsZXQgZmluaXNoQ2FsbGVkID0gZmFsc2U7XG5cbiAgY29uc3QgY2FsbE9uRmluaXNoID0gYXN5bmMgKCkgPT4ge1xuICAgIGlmIChmaW5pc2hDYWxsZWQgfHwgIW9uRmluaXNoKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGZpbmlzaENhbGxlZCA9IHRydWU7XG5cbiAgICBjb25zdCBpc0NvbnRpbnVhdGlvbiA9IHN0YXRlLm1lc3NhZ2UuaWQgPT09IGxhc3RNZXNzYWdlPy5pZDtcbiAgICBhd2FpdCBvbkZpbmlzaCh7XG4gICAgICBpc0Fib3J0ZWQsXG4gICAgICBpc0NvbnRpbnVhdGlvbixcbiAgICAgIHJlc3BvbnNlTWVzc2FnZTogc3RhdGUubWVzc2FnZSBhcyBVSV9NRVNTQUdFLFxuICAgICAgbWVzc2FnZXM6IFtcbiAgICAgICAgLi4uKGlzQ29udGludWF0aW9uID8gb3JpZ2luYWxNZXNzYWdlcy5zbGljZSgwLCAtMSkgOiBvcmlnaW5hbE1lc3NhZ2VzKSxcbiAgICAgICAgc3RhdGUubWVzc2FnZSxcbiAgICAgIF0gYXMgVUlfTUVTU0FHRVtdLFxuICAgIH0pO1xuICB9O1xuXG4gIHJldHVybiBwcm9jZXNzVUlNZXNzYWdlU3RyZWFtPFVJX01FU1NBR0U+KHtcbiAgICBzdHJlYW06IGlkSW5qZWN0ZWRTdHJlYW0sXG4gICAgcnVuVXBkYXRlTWVzc2FnZUpvYixcbiAgICBvbkVycm9yLFxuICB9KS5waXBlVGhyb3VnaChcbiAgICBuZXcgVHJhbnNmb3JtU3RyZWFtPFxuICAgICAgSW5mZXJVSU1lc3NhZ2VDaHVuazxVSV9NRVNTQUdFPixcbiAgICAgIEluZmVyVUlNZXNzYWdlQ2h1bms8VUlfTUVTU0FHRT5cbiAgICA+KHtcbiAgICAgIHRyYW5zZm9ybShjaHVuaywgY29udHJvbGxlcikge1xuICAgICAgICBjb250cm9sbGVyLmVucXVldWUoY2h1bmspO1xuICAgICAgfSxcbiAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgY2FuY2VsIGlzIHN0aWxsIG5ldyBhbmQgbWlzc2luZyBmcm9tIHR5cGVzIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9UcmFuc2Zvcm1TdHJlYW0jYnJvd3Nlcl9jb21wYXRpYmlsaXR5XG4gICAgICBhc3luYyBjYW5jZWwoKSB7XG4gICAgICAgIGF3YWl0IGNhbGxPbkZpbmlzaCgpO1xuICAgICAgfSxcblxuICAgICAgYXN5bmMgZmx1c2goKSB7XG4gICAgICAgIGF3YWl0IGNhbGxPbkZpbmlzaCgpO1xuICAgICAgfSxcbiAgICB9KSxcbiAgKTtcbn1cbiIsICJpbXBvcnQgeyBTZXJ2ZXJSZXNwb25zZSB9IGZyb20gJ25vZGU6aHR0cCc7XG5pbXBvcnQgeyBwcmVwYXJlSGVhZGVycyB9IGZyb20gJy4uL3V0aWwvcHJlcGFyZS1oZWFkZXJzJztcbmltcG9ydCB7IHdyaXRlVG9TZXJ2ZXJSZXNwb25zZSB9IGZyb20gJy4uL3V0aWwvd3JpdGUtdG8tc2VydmVyLXJlc3BvbnNlJztcbmltcG9ydCB7IEpzb25Ub1NzZVRyYW5zZm9ybVN0cmVhbSB9IGZyb20gJy4vanNvbi10by1zc2UtdHJhbnNmb3JtLXN0cmVhbSc7XG5pbXBvcnQgeyBVSV9NRVNTQUdFX1NUUkVBTV9IRUFERVJTIH0gZnJvbSAnLi91aS1tZXNzYWdlLXN0cmVhbS1oZWFkZXJzJztcbmltcG9ydCB7IFVJTWVzc2FnZUNodW5rIH0gZnJvbSAnLi91aS1tZXNzYWdlLWNodW5rcyc7XG5pbXBvcnQgeyBVSU1lc3NhZ2VTdHJlYW1SZXNwb25zZUluaXQgfSBmcm9tICcuL3VpLW1lc3NhZ2Utc3RyZWFtLXJlc3BvbnNlLWluaXQnO1xuXG5leHBvcnQgZnVuY3Rpb24gcGlwZVVJTWVzc2FnZVN0cmVhbVRvUmVzcG9uc2Uoe1xuICByZXNwb25zZSxcbiAgc3RhdHVzLFxuICBzdGF0dXNUZXh0LFxuICBoZWFkZXJzLFxuICBzdHJlYW0sXG4gIGNvbnN1bWVTc2VTdHJlYW0sXG59OiB7XG4gIHJlc3BvbnNlOiBTZXJ2ZXJSZXNwb25zZTtcbiAgc3RyZWFtOiBSZWFkYWJsZVN0cmVhbTxVSU1lc3NhZ2VDaHVuaz47XG59ICYgVUlNZXNzYWdlU3RyZWFtUmVzcG9uc2VJbml0KTogdm9pZCB7XG4gIGxldCBzc2VTdHJlYW0gPSBzdHJlYW0ucGlwZVRocm91Z2gobmV3IEpzb25Ub1NzZVRyYW5zZm9ybVN0cmVhbSgpKTtcblxuICAvLyB3aGVuIHRoZSBjb25zdW1lU3NlU3RyZWFtIGlzIHByb3ZpZGVkLCB3ZSBuZWVkIHRvIHRlZSB0aGUgc3RyZWFtXG4gIC8vIGFuZCBzZW5kIHRoZSBzZWNvbmQgcGFydCB0byB0aGUgY29uc3VtZVNzZVN0cmVhbSBmdW5jdGlvblxuICAvLyBzbyB0aGF0IGl0IGNhbiBiZSBjb25zdW1lZCBieSB0aGUgY2xpZW50IGluZGVwZW5kZW50bHlcbiAgaWYgKGNvbnN1bWVTc2VTdHJlYW0pIHtcbiAgICBjb25zdCBbc3RyZWFtMSwgc3RyZWFtMl0gPSBzc2VTdHJlYW0udGVlKCk7XG4gICAgc3NlU3RyZWFtID0gc3RyZWFtMTtcbiAgICBjb25zdW1lU3NlU3RyZWFtKHsgc3RyZWFtOiBzdHJlYW0yIH0pOyAvLyBubyBhd2FpdCAoZG8gbm90IGJsb2NrIHRoZSByZXNwb25zZSlcbiAgfVxuXG4gIHdyaXRlVG9TZXJ2ZXJSZXNwb25zZSh7XG4gICAgcmVzcG9uc2UsXG4gICAgc3RhdHVzLFxuICAgIHN0YXR1c1RleHQsXG4gICAgaGVhZGVyczogT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgcHJlcGFyZUhlYWRlcnMoaGVhZGVycywgVUlfTUVTU0FHRV9TVFJFQU1fSEVBREVSUykuZW50cmllcygpLFxuICAgICksXG4gICAgc3RyZWFtOiBzc2VTdHJlYW0ucGlwZVRocm91Z2gobmV3IFRleHRFbmNvZGVyU3RyZWFtKCkpLFxuICB9KTtcbn1cbiIsICIvKipcbiAqIEEgdHlwZSB0aGF0IGNvbWJpbmVzIEFzeW5jSXRlcmFibGUgYW5kIFJlYWRhYmxlU3RyZWFtLlxuICogVGhpcyBhbGxvd3MgYSBSZWFkYWJsZVN0cmVhbSB0byBiZSBjb25zdW1lZCB1c2luZyBmb3ItYXdhaXQtb2Ygc3ludGF4LlxuICovXG5leHBvcnQgdHlwZSBBc3luY0l0ZXJhYmxlU3RyZWFtPFQ+ID0gQXN5bmNJdGVyYWJsZTxUPiAmIFJlYWRhYmxlU3RyZWFtPFQ+O1xuXG4vKipcbiAqIFdyYXBzIGEgUmVhZGFibGVTdHJlYW0gYW5kIHJldHVybnMgYW4gb2JqZWN0IHRoYXQgaXMgYm90aCBhIFJlYWRhYmxlU3RyZWFtIGFuZCBhbiBBc3luY0l0ZXJhYmxlLlxuICogVGhpcyBlbmFibGVzIGNvbnN1bXB0aW9uIG9mIHRoZSBzdHJlYW0gdXNpbmcgZm9yLWF3YWl0LW9mLCB3aXRoIHByb3BlciByZXNvdXJjZSBjbGVhbnVwIG9uIGVhcmx5IGV4aXQgb3IgZXJyb3IuXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHR5cGUgb2YgdGhlIHN0cmVhbSdzIGNodW5rcy5cbiAqIEBwYXJhbSBzb3VyY2UgVGhlIHNvdXJjZSBSZWFkYWJsZVN0cmVhbSB0byB3cmFwLlxuICogQHJldHVybnMgQW4gQXN5bmNJdGVyYWJsZVN0cmVhbSB0aGF0IGNhbiBiZSB1c2VkIGFzIGJvdGggYSBSZWFkYWJsZVN0cmVhbSBhbmQgYW4gQXN5bmNJdGVyYWJsZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUFzeW5jSXRlcmFibGVTdHJlYW08VD4oXG4gIHNvdXJjZTogUmVhZGFibGVTdHJlYW08VD4sXG4pOiBBc3luY0l0ZXJhYmxlU3RyZWFtPFQ+IHtcbiAgLy8gUGlwZSB0aHJvdWdoIGEgVHJhbnNmb3JtU3RyZWFtIHRvIGVuc3VyZSBhIGZyZXNoLCB1bmxvY2tlZCBzdHJlYW0uXG4gIGNvbnN0IHN0cmVhbSA9IHNvdXJjZS5waXBlVGhyb3VnaChuZXcgVHJhbnNmb3JtU3RyZWFtPFQsIFQ+KCkpO1xuXG4gIC8qKlxuICAgKiBJbXBsZW1lbnRzIHRoZSBhc3luYyBpdGVyYXRvciBwcm90b2NvbCBmb3IgdGhlIHN0cmVhbS5cbiAgICogRW5zdXJlcyBwcm9wZXIgY2xlYW51cCAoY2FuY2VsbGluZyBhbmQgcmVsZWFzaW5nIHRoZSByZWFkZXIpIG9uIGNvbXBsZXRpb24sIGVhcmx5IGV4aXQsIG9yIGVycm9yLlxuICAgKi9cbiAgKHN0cmVhbSBhcyBBc3luY0l0ZXJhYmxlU3RyZWFtPFQ+KVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoXG4gICAgdGhpczogUmVhZGFibGVTdHJlYW08VD4sXG4gICk6IEFzeW5jSXRlcmF0b3I8VD4ge1xuICAgIGNvbnN0IHJlYWRlciA9IHRoaXMuZ2V0UmVhZGVyKCk7XG5cbiAgICBsZXQgZmluaXNoZWQgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIENsZWFucyB1cCB0aGUgcmVhZGVyIGJ5IGNhbmNlbGxpbmcgYW5kIHJlbGVhc2luZyB0aGUgbG9jay5cbiAgICAgKi9cbiAgICBhc3luYyBmdW5jdGlvbiBjbGVhbnVwKGNhbmNlbFN0cmVhbTogYm9vbGVhbikge1xuICAgICAgZmluaXNoZWQgPSB0cnVlO1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKGNhbmNlbFN0cmVhbSkge1xuICAgICAgICAgIGF3YWl0IHJlYWRlci5jYW5jZWw/LigpO1xuICAgICAgICB9XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHJlYWRlci5yZWxlYXNlTG9jaygpO1xuICAgICAgICB9IGNhdGNoIHt9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIC8qKlxuICAgICAgICogUmVhZHMgdGhlIG5leHQgY2h1bmsgZnJvbSB0aGUgc3RyZWFtLlxuICAgICAgICogQHJldHVybnMgQSBwcm9taXNlIHJlc29sdmluZyB0byB0aGUgbmV4dCBJdGVyYXRvclJlc3VsdC5cbiAgICAgICAqL1xuICAgICAgYXN5bmMgbmV4dCgpOiBQcm9taXNlPEl0ZXJhdG9yUmVzdWx0PFQ+PiB7XG4gICAgICAgIGlmIChmaW5pc2hlZCkge1xuICAgICAgICAgIHJldHVybiB7IGRvbmU6IHRydWUsIHZhbHVlOiB1bmRlZmluZWQgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHsgZG9uZSwgdmFsdWUgfSA9IGF3YWl0IHJlYWRlci5yZWFkKCk7XG5cbiAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICBhd2FpdCBjbGVhbnVwKHRydWUpO1xuICAgICAgICAgIHJldHVybiB7IGRvbmU6IHRydWUsIHZhbHVlOiB1bmRlZmluZWQgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7IGRvbmU6IGZhbHNlLCB2YWx1ZSB9O1xuICAgICAgfSxcblxuICAgICAgLyoqXG4gICAgICAgKiBDYWxsZWQgb24gZWFybHkgZXhpdCAoZS5nLiwgYnJlYWsgZnJvbSBmb3ItYXdhaXQpLlxuICAgICAgICogRW5zdXJlcyB0aGUgc3RyZWFtIGlzIGNhbmNlbGxlZCBhbmQgcmVzb3VyY2VzIGFyZSByZWxlYXNlZC5cbiAgICAgICAqIEByZXR1cm5zIEEgcHJvbWlzZSByZXNvbHZpbmcgdG8gYSBjb21wbGV0ZWQgSXRlcmF0b3JSZXN1bHQuXG4gICAgICAgKi9cbiAgICAgIGFzeW5jIHJldHVybigpOiBQcm9taXNlPEl0ZXJhdG9yUmVzdWx0PFQ+PiB7XG4gICAgICAgIGF3YWl0IGNsZWFudXAodHJ1ZSk7XG4gICAgICAgIHJldHVybiB7IGRvbmU6IHRydWUsIHZhbHVlOiB1bmRlZmluZWQgfTtcbiAgICAgIH0sXG5cbiAgICAgIC8qKlxuICAgICAgICogQ2FsbGVkIG9uIGVhcmx5IGV4aXQgd2l0aCBlcnJvci5cbiAgICAgICAqIEVuc3VyZXMgdGhlIHN0cmVhbSBpcyBjYW5jZWxsZWQgYW5kIHJlc291cmNlcyBhcmUgcmVsZWFzZWQsIHRoZW4gcmV0aHJvd3MgdGhlIGVycm9yLlxuICAgICAgICogQHBhcmFtIGVyciBUaGUgZXJyb3IgdG8gdGhyb3cuXG4gICAgICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZWplY3RzIHdpdGggdGhlIHByb3ZpZGVkIGVycm9yLlxuICAgICAgICovXG4gICAgICBhc3luYyB0aHJvdyhlcnI6IHVua25vd24pOiBQcm9taXNlPEl0ZXJhdG9yUmVzdWx0PFQ+PiB7XG4gICAgICAgIGF3YWl0IGNsZWFudXAodHJ1ZSk7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH0sXG4gICAgfTtcbiAgfTtcblxuICByZXR1cm4gc3RyZWFtIGFzIEFzeW5jSXRlcmFibGVTdHJlYW08VD47XG59XG4iLCAiLyoqXG4gKiBDb25zdW1lcyBhIFJlYWRhYmxlU3RyZWFtIHVudGlsIGl0J3MgZnVsbHkgcmVhZC5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIHJlYWRzIHRoZSBzdHJlYW0gY2h1bmsgYnkgY2h1bmsgdW50aWwgdGhlIHN0cmVhbSBpcyBleGhhdXN0ZWQuXG4gKiBJdCBkb2Vzbid0IHByb2Nlc3Mgb3IgcmV0dXJuIHRoZSBkYXRhIGZyb20gdGhlIHN0cmVhbTsgaXQgc2ltcGx5IGVuc3VyZXNcbiAqIHRoYXQgdGhlIGVudGlyZSBzdHJlYW0gaXMgcmVhZC5cbiAqXG4gKiBAcGFyYW0ge1JlYWRhYmxlU3RyZWFtfSBzdHJlYW0gLSBUaGUgUmVhZGFibGVTdHJlYW0gdG8gYmUgY29uc3VtZWQuXG4gKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgc3RyZWFtIGlzIGZ1bGx5IGNvbnN1bWVkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY29uc3VtZVN0cmVhbSh7XG4gIHN0cmVhbSxcbiAgb25FcnJvcixcbn06IHtcbiAgc3RyZWFtOiBSZWFkYWJsZVN0cmVhbTtcbiAgb25FcnJvcj86IChlcnJvcjogdW5rbm93bikgPT4gdm9pZDtcbn0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgcmVhZGVyID0gc3RyZWFtLmdldFJlYWRlcigpO1xuICB0cnkge1xuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICBjb25zdCB7IGRvbmUgfSA9IGF3YWl0IHJlYWRlci5yZWFkKCk7XG4gICAgICBpZiAoZG9uZSkgYnJlYWs7XG4gICAgfVxuICB9IGNhdGNoIChlcnJvcikge1xuICAgIG9uRXJyb3I/LihlcnJvcik7XG4gIH0gZmluYWxseSB7XG4gICAgcmVhZGVyLnJlbGVhc2VMb2NrKCk7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBFcnJvckhhbmRsZXIgfSBmcm9tICcuL2Vycm9yLWhhbmRsZXInO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBQcm9taXNlIHdpdGggZXh0ZXJuYWxseSBhY2Nlc3NpYmxlIHJlc29sdmUgYW5kIHJlamVjdCBmdW5jdGlvbnMuXG4gKlxuICogQHRlbXBsYXRlIFQgLSBUaGUgdHlwZSBvZiB0aGUgdmFsdWUgdGhhdCB0aGUgUHJvbWlzZSB3aWxsIHJlc29sdmUgdG8uXG4gKiBAcmV0dXJucyBBbiBvYmplY3QgY29udGFpbmluZzpcbiAqICAgLSBwcm9taXNlOiBBIFByb21pc2UgdGhhdCBjYW4gYmUgcmVzb2x2ZWQgb3IgcmVqZWN0ZWQgZXh0ZXJuYWxseS5cbiAqICAgLSByZXNvbHZlOiBBIGZ1bmN0aW9uIHRvIHJlc29sdmUgdGhlIFByb21pc2Ugd2l0aCBhIHZhbHVlIG9mIHR5cGUgVC5cbiAqICAgLSByZWplY3Q6IEEgZnVuY3Rpb24gdG8gcmVqZWN0IHRoZSBQcm9taXNlIHdpdGggYW4gZXJyb3IuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVSZXNvbHZhYmxlUHJvbWlzZTxUID0gYW55PigpOiB7XG4gIHByb21pc2U6IFByb21pc2U8VD47XG4gIHJlc29sdmU6ICh2YWx1ZTogVCkgPT4gdm9pZDtcbiAgcmVqZWN0OiBFcnJvckhhbmRsZXI7XG59IHtcbiAgbGV0IHJlc29sdmU6ICh2YWx1ZTogVCkgPT4gdm9pZDtcbiAgbGV0IHJlamVjdDogRXJyb3JIYW5kbGVyO1xuXG4gIGNvbnN0IHByb21pc2UgPSBuZXcgUHJvbWlzZTxUPigocmVzLCByZWopID0+IHtcbiAgICByZXNvbHZlID0gcmVzO1xuICAgIHJlamVjdCA9IHJlajtcbiAgfSk7XG5cbiAgcmV0dXJuIHtcbiAgICBwcm9taXNlLFxuICAgIHJlc29sdmU6IHJlc29sdmUhLFxuICAgIHJlamVjdDogcmVqZWN0ISxcbiAgfTtcbn1cbiIsICJpbXBvcnQgeyBjcmVhdGVSZXNvbHZhYmxlUHJvbWlzZSB9IGZyb20gJy4vY3JlYXRlLXJlc29sdmFibGUtcHJvbWlzZSc7XG5cbi8qKlxuICogQ3JlYXRlcyBhIHN0aXRjaGFibGUgc3RyZWFtIHRoYXQgY2FuIHBpcGUgb25lIHN0cmVhbSBhdCBhIHRpbWUuXG4gKlxuICogQHRlbXBsYXRlIFQgLSBUaGUgdHlwZSBvZiB2YWx1ZXMgZW1pdHRlZCBieSB0aGUgc3RyZWFtcy5cbiAqIEByZXR1cm5zIHtPYmplY3R9IEFuIG9iamVjdCBjb250YWluaW5nIHRoZSBzdGl0Y2hhYmxlIHN0cmVhbSBhbmQgY29udHJvbCBtZXRob2RzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlU3RpdGNoYWJsZVN0cmVhbTxUPigpOiB7XG4gIHN0cmVhbTogUmVhZGFibGVTdHJlYW08VD47XG4gIGFkZFN0cmVhbTogKGlubmVyU3RyZWFtOiBSZWFkYWJsZVN0cmVhbTxUPikgPT4gdm9pZDtcbiAgY2xvc2U6ICgpID0+IHZvaWQ7XG4gIHRlcm1pbmF0ZTogKCkgPT4gdm9pZDtcbn0ge1xuICBsZXQgaW5uZXJTdHJlYW1SZWFkZXJzOiBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXI8VD5bXSA9IFtdO1xuICBsZXQgY29udHJvbGxlcjogUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcjxUPiB8IG51bGwgPSBudWxsO1xuICBsZXQgaXNDbG9zZWQgPSBmYWxzZTtcbiAgbGV0IHdhaXRGb3JOZXdTdHJlYW0gPSBjcmVhdGVSZXNvbHZhYmxlUHJvbWlzZTx2b2lkPigpO1xuXG4gIGNvbnN0IHRlcm1pbmF0ZSA9ICgpID0+IHtcbiAgICBpc0Nsb3NlZCA9IHRydWU7XG4gICAgd2FpdEZvck5ld1N0cmVhbS5yZXNvbHZlKCk7XG5cbiAgICBpbm5lclN0cmVhbVJlYWRlcnMuZm9yRWFjaChyZWFkZXIgPT4gcmVhZGVyLmNhbmNlbCgpKTtcbiAgICBpbm5lclN0cmVhbVJlYWRlcnMgPSBbXTtcbiAgICBjb250cm9sbGVyPy5jbG9zZSgpO1xuICB9O1xuXG4gIGNvbnN0IHByb2Nlc3NQdWxsID0gYXN5bmMgKCkgPT4ge1xuICAgIC8vIENhc2UgMTogT3V0ZXIgc3RyZWFtIGlzIGNsb3NlZCBhbmQgbm8gbW9yZSBpbm5lciBzdHJlYW1zXG4gICAgaWYgKGlzQ2xvc2VkICYmIGlubmVyU3RyZWFtUmVhZGVycy5sZW5ndGggPT09IDApIHtcbiAgICAgIGNvbnRyb2xsZXI/LmNsb3NlKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gQ2FzZSAyOiBObyBpbm5lciBzdHJlYW1zIGF2YWlsYWJsZSwgYnV0IG91dGVyIHN0cmVhbSBpcyBvcGVuXG4gICAgLy8gd2FpdCBmb3IgYSBuZXcgaW5uZXIgc3RyZWFtIHRvIGJlIGFkZGVkIG9yIHRoZSBvdXRlciBzdHJlYW0gdG8gY2xvc2VcbiAgICBpZiAoaW5uZXJTdHJlYW1SZWFkZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgd2FpdEZvck5ld1N0cmVhbSA9IGNyZWF0ZVJlc29sdmFibGVQcm9taXNlPHZvaWQ+KCk7XG4gICAgICBhd2FpdCB3YWl0Rm9yTmV3U3RyZWFtLnByb21pc2U7XG4gICAgICByZXR1cm4gcHJvY2Vzc1B1bGwoKTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgeyB2YWx1ZSwgZG9uZSB9ID0gYXdhaXQgaW5uZXJTdHJlYW1SZWFkZXJzWzBdLnJlYWQoKTtcblxuICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgLy8gQ2FzZSAzOiBDdXJyZW50IGlubmVyIHN0cmVhbSBpcyBkb25lXG4gICAgICAgIGlubmVyU3RyZWFtUmVhZGVycy5zaGlmdCgpOyAvLyBSZW1vdmUgdGhlIGZpbmlzaGVkIHN0cmVhbVxuXG4gICAgICAgIC8vIENvbnRpbnVlIHB1bGxpbmcgZnJvbSB0aGUgbmV4dCBzdHJlYW0gaWYgYXZhaWxhYmxlXG4gICAgICAgIGlmIChpbm5lclN0cmVhbVJlYWRlcnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGF3YWl0IHByb2Nlc3NQdWxsKCk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNDbG9zZWQpIHtcbiAgICAgICAgICBjb250cm9sbGVyPy5jbG9zZSgpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBDYXNlIDQ6IEN1cnJlbnQgaW5uZXIgc3RyZWFtIHJldHVybnMgYW4gaXRlbVxuICAgICAgICBjb250cm9sbGVyPy5lbnF1ZXVlKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLy8gQ2FzZSA1OiBDdXJyZW50IGlubmVyIHN0cmVhbSB0aHJvd3MgYW4gZXJyb3JcbiAgICAgIGNvbnRyb2xsZXI/LmVycm9yKGVycm9yKTtcbiAgICAgIGlubmVyU3RyZWFtUmVhZGVycy5zaGlmdCgpOyAvLyBSZW1vdmUgdGhlIGVycm9yZWQgc3RyZWFtXG4gICAgICB0ZXJtaW5hdGUoKTsgLy8gd2UgaGF2ZSBlcnJvcmVkLCB0ZXJtaW5hdGUgYWxsIHN0cmVhbXNcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIHtcbiAgICBzdHJlYW06IG5ldyBSZWFkYWJsZVN0cmVhbTxUPih7XG4gICAgICBzdGFydChjb250cm9sbGVyUGFyYW0pIHtcbiAgICAgICAgY29udHJvbGxlciA9IGNvbnRyb2xsZXJQYXJhbTtcbiAgICAgIH0sXG4gICAgICBwdWxsOiBwcm9jZXNzUHVsbCxcbiAgICAgIGFzeW5jIGNhbmNlbCgpIHtcbiAgICAgICAgZm9yIChjb25zdCByZWFkZXIgb2YgaW5uZXJTdHJlYW1SZWFkZXJzKSB7XG4gICAgICAgICAgYXdhaXQgcmVhZGVyLmNhbmNlbCgpO1xuICAgICAgICB9XG4gICAgICAgIGlubmVyU3RyZWFtUmVhZGVycyA9IFtdO1xuICAgICAgICBpc0Nsb3NlZCA9IHRydWU7XG4gICAgICB9LFxuICAgIH0pLFxuICAgIGFkZFN0cmVhbTogKGlubmVyU3RyZWFtOiBSZWFkYWJsZVN0cmVhbTxUPikgPT4ge1xuICAgICAgaWYgKGlzQ2xvc2VkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGFkZCBpbm5lciBzdHJlYW06IG91dGVyIHN0cmVhbSBpcyBjbG9zZWQnKTtcbiAgICAgIH1cblxuICAgICAgaW5uZXJTdHJlYW1SZWFkZXJzLnB1c2goaW5uZXJTdHJlYW0uZ2V0UmVhZGVyKCkpO1xuICAgICAgd2FpdEZvck5ld1N0cmVhbS5yZXNvbHZlKCk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdyYWNlZnVsbHkgY2xvc2UgdGhlIG91dGVyIHN0cmVhbS4gVGhpcyB3aWxsIGxldCB0aGUgaW5uZXIgc3RyZWFtc1xuICAgICAqIGZpbmlzaCBwcm9jZXNzaW5nIGFuZCB0aGVuIGNsb3NlIHRoZSBvdXRlciBzdHJlYW0uXG4gICAgICovXG4gICAgY2xvc2U6ICgpID0+IHtcbiAgICAgIGlzQ2xvc2VkID0gdHJ1ZTtcbiAgICAgIHdhaXRGb3JOZXdTdHJlYW0ucmVzb2x2ZSgpO1xuXG4gICAgICBpZiAoaW5uZXJTdHJlYW1SZWFkZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBjb250cm9sbGVyPy5jbG9zZSgpO1xuICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBJbW1lZGlhdGVseSBjbG9zZSB0aGUgb3V0ZXIgc3RyZWFtLiBUaGlzIHdpbGwgY2FuY2VsIGFsbCBpbm5lciBzdHJlYW1zXG4gICAgICogYW5kIGNsb3NlIHRoZSBvdXRlciBzdHJlYW0uXG4gICAgICovXG4gICAgdGVybWluYXRlLFxuICB9O1xufVxuIiwgIi8qKlxuICogRGVsYXllZCBwcm9taXNlLiBJdCBpcyBvbmx5IGNvbnN0cnVjdGVkIG9uY2UgdGhlIHZhbHVlIGlzIGFjY2Vzc2VkLlxuICogVGhpcyBpcyB1c2VmdWwgdG8gYXZvaWQgdW5oYW5kbGVkIHByb21pc2UgcmVqZWN0aW9ucyB3aGVuIHRoZSBwcm9taXNlIGlzIGNyZWF0ZWRcbiAqIGJ1dCBub3QgYWNjZXNzZWQuXG4gKi9cbmV4cG9ydCBjbGFzcyBEZWxheWVkUHJvbWlzZTxUPiB7XG4gIHByaXZhdGUgc3RhdHVzOlxuICAgIHwgeyB0eXBlOiAncGVuZGluZycgfVxuICAgIHwgeyB0eXBlOiAncmVzb2x2ZWQnOyB2YWx1ZTogVCB9XG4gICAgfCB7IHR5cGU6ICdyZWplY3RlZCc7IGVycm9yOiB1bmtub3duIH0gPSB7IHR5cGU6ICdwZW5kaW5nJyB9O1xuICBwcml2YXRlIF9wcm9taXNlOiBQcm9taXNlPFQ+IHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIF9yZXNvbHZlOiB1bmRlZmluZWQgfCAoKHZhbHVlOiBUKSA9PiB2b2lkKSA9IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSBfcmVqZWN0OiB1bmRlZmluZWQgfCAoKGVycm9yOiB1bmtub3duKSA9PiB2b2lkKSA9IHVuZGVmaW5lZDtcblxuICBnZXQgcHJvbWlzZSgpOiBQcm9taXNlPFQ+IHtcbiAgICBpZiAodGhpcy5fcHJvbWlzZSkge1xuICAgICAgcmV0dXJuIHRoaXMuX3Byb21pc2U7XG4gICAgfVxuXG4gICAgdGhpcy5fcHJvbWlzZSA9IG5ldyBQcm9taXNlPFQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGlmICh0aGlzLnN0YXR1cy50eXBlID09PSAncmVzb2x2ZWQnKSB7XG4gICAgICAgIHJlc29sdmUodGhpcy5zdGF0dXMudmFsdWUpO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLnN0YXR1cy50eXBlID09PSAncmVqZWN0ZWQnKSB7XG4gICAgICAgIHJlamVjdCh0aGlzLnN0YXR1cy5lcnJvcik7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX3Jlc29sdmUgPSByZXNvbHZlO1xuICAgICAgdGhpcy5fcmVqZWN0ID0gcmVqZWN0O1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRoaXMuX3Byb21pc2U7XG4gIH1cblxuICByZXNvbHZlKHZhbHVlOiBUKTogdm9pZCB7XG4gICAgdGhpcy5zdGF0dXMgPSB7IHR5cGU6ICdyZXNvbHZlZCcsIHZhbHVlIH07XG5cbiAgICBpZiAodGhpcy5fcHJvbWlzZSkge1xuICAgICAgdGhpcy5fcmVzb2x2ZT8uKHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICByZWplY3QoZXJyb3I6IHVua25vd24pOiB2b2lkIHtcbiAgICB0aGlzLnN0YXR1cyA9IHsgdHlwZTogJ3JlamVjdGVkJywgZXJyb3IgfTtcblxuICAgIGlmICh0aGlzLl9wcm9taXNlKSB7XG4gICAgICB0aGlzLl9yZWplY3Q/LihlcnJvcik7XG4gICAgfVxuICB9XG59XG4iLCAiLy8gU2hpbSBmb3IgcGVyZm9ybWFuY2Uubm93KCkgdG8gc3VwcG9ydCBlbnZpcm9ubWVudHMgdGhhdCBkb24ndCBoYXZlIGl0OlxuZXhwb3J0IGZ1bmN0aW9uIG5vdygpOiBudW1iZXIge1xuICByZXR1cm4gZ2xvYmFsVGhpcz8ucGVyZm9ybWFuY2U/Lm5vdygpID8/IERhdGUubm93KCk7XG59XG4iLCAiaW1wb3J0IHtcbiAgTGFuZ3VhZ2VNb2RlbFYyQ2FsbFdhcm5pbmcsXG4gIExhbmd1YWdlTW9kZWxWMlN0cmVhbVBhcnQsXG59IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHtcbiAgZXhlY3V0ZVRvb2wsXG4gIGdlbmVyYXRlSWQsXG4gIGdldEVycm9yTWVzc2FnZSxcbiAgTW9kZWxNZXNzYWdlLFxufSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyLXV0aWxzJztcbmltcG9ydCB7IFRyYWNlciB9IGZyb20gJ0BvcGVudGVsZW1ldHJ5L2FwaSc7XG5pbXBvcnQgeyBhc3NlbWJsZU9wZXJhdGlvbk5hbWUgfSBmcm9tICcuLi90ZWxlbWV0cnkvYXNzZW1ibGUtb3BlcmF0aW9uLW5hbWUnO1xuaW1wb3J0IHsgcmVjb3JkRXJyb3JPblNwYW4sIHJlY29yZFNwYW4gfSBmcm9tICcuLi90ZWxlbWV0cnkvcmVjb3JkLXNwYW4nO1xuaW1wb3J0IHsgc2VsZWN0VGVsZW1ldHJ5QXR0cmlidXRlcyB9IGZyb20gJy4uL3RlbGVtZXRyeS9zZWxlY3QtdGVsZW1ldHJ5LWF0dHJpYnV0ZXMnO1xuaW1wb3J0IHsgVGVsZW1ldHJ5U2V0dGluZ3MgfSBmcm9tICcuLi90ZWxlbWV0cnkvdGVsZW1ldHJ5LXNldHRpbmdzJztcbmltcG9ydCB7IEZpbmlzaFJlYXNvbiwgTGFuZ3VhZ2VNb2RlbFVzYWdlLCBQcm92aWRlck1ldGFkYXRhIH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHsgU291cmNlIH0gZnJvbSAnLi4vdHlwZXMvbGFuZ3VhZ2UtbW9kZWwnO1xuaW1wb3J0IHsgRGVmYXVsdEdlbmVyYXRlZEZpbGVXaXRoVHlwZSwgR2VuZXJhdGVkRmlsZSB9IGZyb20gJy4vZ2VuZXJhdGVkLWZpbGUnO1xuaW1wb3J0IHsgcGFyc2VUb29sQ2FsbCB9IGZyb20gJy4vcGFyc2UtdG9vbC1jYWxsJztcbmltcG9ydCB7IFR5cGVkVG9vbENhbGwgfSBmcm9tICcuL3Rvb2wtY2FsbCc7XG5pbXBvcnQgeyBUb29sQ2FsbFJlcGFpckZ1bmN0aW9uIH0gZnJvbSAnLi90b29sLWNhbGwtcmVwYWlyLWZ1bmN0aW9uJztcbmltcG9ydCB7IFR5cGVkVG9vbEVycm9yIH0gZnJvbSAnLi90b29sLWVycm9yJztcbmltcG9ydCB7IFR5cGVkVG9vbFJlc3VsdCB9IGZyb20gJy4vdG9vbC1yZXN1bHQnO1xuaW1wb3J0IHsgVG9vbFNldCB9IGZyb20gJy4vdG9vbC1zZXQnO1xuXG5leHBvcnQgdHlwZSBTaW5nbGVSZXF1ZXN0VGV4dFN0cmVhbVBhcnQ8VE9PTFMgZXh0ZW5kcyBUb29sU2V0PiA9XG4gIC8vIFRleHQgYmxvY2tzOlxuICB8IHtcbiAgICAgIHR5cGU6ICd0ZXh0LXN0YXJ0JztcbiAgICAgIHByb3ZpZGVyTWV0YWRhdGE/OiBQcm92aWRlck1ldGFkYXRhO1xuICAgICAgaWQ6IHN0cmluZztcbiAgICB9XG4gIHwge1xuICAgICAgdHlwZTogJ3RleHQtZGVsdGEnO1xuICAgICAgaWQ6IHN0cmluZztcbiAgICAgIHByb3ZpZGVyTWV0YWRhdGE/OiBQcm92aWRlck1ldGFkYXRhO1xuICAgICAgZGVsdGE6IHN0cmluZztcbiAgICB9XG4gIHwge1xuICAgICAgdHlwZTogJ3RleHQtZW5kJztcbiAgICAgIHByb3ZpZGVyTWV0YWRhdGE/OiBQcm92aWRlck1ldGFkYXRhO1xuICAgICAgaWQ6IHN0cmluZztcbiAgICB9XG5cbiAgLy8gUmVhc29uaW5nIGJsb2NrczpcbiAgfCB7XG4gICAgICB0eXBlOiAncmVhc29uaW5nLXN0YXJ0JztcbiAgICAgIHByb3ZpZGVyTWV0YWRhdGE/OiBQcm92aWRlck1ldGFkYXRhO1xuICAgICAgaWQ6IHN0cmluZztcbiAgICB9XG4gIHwge1xuICAgICAgdHlwZTogJ3JlYXNvbmluZy1kZWx0YSc7XG4gICAgICBpZDogc3RyaW5nO1xuICAgICAgcHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG4gICAgICBkZWx0YTogc3RyaW5nO1xuICAgIH1cbiAgfCB7XG4gICAgICB0eXBlOiAncmVhc29uaW5nLWVuZCc7XG4gICAgICBpZDogc3RyaW5nO1xuICAgICAgcHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG4gICAgfVxuXG4gIC8vIFRvb2wgY2FsbHM6XG4gIHwge1xuICAgICAgdHlwZTogJ3Rvb2wtaW5wdXQtc3RhcnQnO1xuICAgICAgaWQ6IHN0cmluZztcbiAgICAgIHRvb2xOYW1lOiBzdHJpbmc7XG4gICAgICBwcm92aWRlck1ldGFkYXRhPzogUHJvdmlkZXJNZXRhZGF0YTtcbiAgICB9XG4gIHwge1xuICAgICAgdHlwZTogJ3Rvb2wtaW5wdXQtZGVsdGEnO1xuICAgICAgaWQ6IHN0cmluZztcbiAgICAgIGRlbHRhOiBzdHJpbmc7XG4gICAgICBwcm92aWRlck1ldGFkYXRhPzogUHJvdmlkZXJNZXRhZGF0YTtcbiAgICB9XG4gIHwge1xuICAgICAgdHlwZTogJ3Rvb2wtaW5wdXQtZW5kJztcbiAgICAgIGlkOiBzdHJpbmc7XG4gICAgICBwcm92aWRlck1ldGFkYXRhPzogUHJvdmlkZXJNZXRhZGF0YTtcbiAgICB9XG4gIHwgKHsgdHlwZTogJ3NvdXJjZScgfSAmIFNvdXJjZSlcbiAgfCB7IHR5cGU6ICdmaWxlJzsgZmlsZTogR2VuZXJhdGVkRmlsZSB9IC8vIGRpZmZlcmVudCBiZWNhdXNlIG9mIEdlbmVyYXRlZEZpbGUgb2JqZWN0XG4gIHwgKHsgdHlwZTogJ3Rvb2wtY2FsbCcgfSAmIFR5cGVkVG9vbENhbGw8VE9PTFM+KVxuICB8ICh7IHR5cGU6ICd0b29sLXJlc3VsdCcgfSAmIFR5cGVkVG9vbFJlc3VsdDxUT09MUz4pXG4gIHwgKHsgdHlwZTogJ3Rvb2wtZXJyb3InIH0gJiBUeXBlZFRvb2xFcnJvcjxUT09MUz4pXG4gIHwgeyB0eXBlOiAnZmlsZSc7IGZpbGU6IEdlbmVyYXRlZEZpbGUgfSAvLyBkaWZmZXJlbnQgYmVjYXVzZSBvZiBHZW5lcmF0ZWRGaWxlIG9iamVjdFxuICB8IHsgdHlwZTogJ3N0cmVhbS1zdGFydCc7IHdhcm5pbmdzOiBMYW5ndWFnZU1vZGVsVjJDYWxsV2FybmluZ1tdIH1cbiAgfCB7XG4gICAgICB0eXBlOiAncmVzcG9uc2UtbWV0YWRhdGEnO1xuICAgICAgaWQ/OiBzdHJpbmc7XG4gICAgICB0aW1lc3RhbXA/OiBEYXRlO1xuICAgICAgbW9kZWxJZD86IHN0cmluZztcbiAgICB9XG4gIHwge1xuICAgICAgdHlwZTogJ2ZpbmlzaCc7XG4gICAgICBmaW5pc2hSZWFzb246IEZpbmlzaFJlYXNvbjtcbiAgICAgIHVzYWdlOiBMYW5ndWFnZU1vZGVsVXNhZ2U7XG4gICAgICBwcm92aWRlck1ldGFkYXRhPzogUHJvdmlkZXJNZXRhZGF0YTtcbiAgICB9XG4gIHwgeyB0eXBlOiAnZXJyb3InOyBlcnJvcjogdW5rbm93biB9XG4gIHwgeyB0eXBlOiAncmF3JzsgcmF3VmFsdWU6IHVua25vd24gfTtcblxuZXhwb3J0IGZ1bmN0aW9uIHJ1blRvb2xzVHJhbnNmb3JtYXRpb248VE9PTFMgZXh0ZW5kcyBUb29sU2V0Pih7XG4gIHRvb2xzLFxuICBnZW5lcmF0b3JTdHJlYW0sXG4gIHRyYWNlcixcbiAgdGVsZW1ldHJ5LFxuICBzeXN0ZW0sXG4gIG1lc3NhZ2VzLFxuICBhYm9ydFNpZ25hbCxcbiAgcmVwYWlyVG9vbENhbGwsXG4gIGV4cGVyaW1lbnRhbF9jb250ZXh0LFxufToge1xuICB0b29sczogVE9PTFMgfCB1bmRlZmluZWQ7XG4gIGdlbmVyYXRvclN0cmVhbTogUmVhZGFibGVTdHJlYW08TGFuZ3VhZ2VNb2RlbFYyU3RyZWFtUGFydD47XG4gIHRyYWNlcjogVHJhY2VyO1xuICB0ZWxlbWV0cnk6IFRlbGVtZXRyeVNldHRpbmdzIHwgdW5kZWZpbmVkO1xuICBzeXN0ZW06IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgbWVzc2FnZXM6IE1vZGVsTWVzc2FnZVtdO1xuICBhYm9ydFNpZ25hbDogQWJvcnRTaWduYWwgfCB1bmRlZmluZWQ7XG4gIHJlcGFpclRvb2xDYWxsOiBUb29sQ2FsbFJlcGFpckZ1bmN0aW9uPFRPT0xTPiB8IHVuZGVmaW5lZDtcbiAgZXhwZXJpbWVudGFsX2NvbnRleHQ6IHVua25vd247XG59KTogUmVhZGFibGVTdHJlYW08U2luZ2xlUmVxdWVzdFRleHRTdHJlYW1QYXJ0PFRPT0xTPj4ge1xuICAvLyB0b29sIHJlc3VsdHMgc3RyZWFtXG4gIGxldCB0b29sUmVzdWx0c1N0cmVhbUNvbnRyb2xsZXI6IFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXI8XG4gICAgU2luZ2xlUmVxdWVzdFRleHRTdHJlYW1QYXJ0PFRPT0xTPlxuICA+IHwgbnVsbCA9IG51bGw7XG4gIGNvbnN0IHRvb2xSZXN1bHRzU3RyZWFtID0gbmV3IFJlYWRhYmxlU3RyZWFtPFxuICAgIFNpbmdsZVJlcXVlc3RUZXh0U3RyZWFtUGFydDxUT09MUz5cbiAgPih7XG4gICAgc3RhcnQoY29udHJvbGxlcikge1xuICAgICAgdG9vbFJlc3VsdHNTdHJlYW1Db250cm9sbGVyID0gY29udHJvbGxlcjtcbiAgICB9LFxuICB9KTtcblxuICAvLyBrZWVwIHRyYWNrIG9mIG91dHN0YW5kaW5nIHRvb2wgcmVzdWx0cyBmb3Igc3RyZWFtIGNsb3Npbmc6XG4gIGNvbnN0IG91dHN0YW5kaW5nVG9vbFJlc3VsdHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuICAvLyBrZWVwIHRyYWNrIG9mIHRvb2wgaW5wdXRzIGZvciBwcm92aWRlci1zaWRlIHRvb2wgcmVzdWx0c1xuICBjb25zdCB0b29sSW5wdXRzID0gbmV3IE1hcDxzdHJpbmcsIHVua25vd24+KCk7XG5cbiAgbGV0IGNhbkNsb3NlID0gZmFsc2U7XG4gIGxldCBmaW5pc2hDaHVuazpcbiAgICB8IChTaW5nbGVSZXF1ZXN0VGV4dFN0cmVhbVBhcnQ8VE9PTFM+ICYgeyB0eXBlOiAnZmluaXNoJyB9KVxuICAgIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuXG4gIGZ1bmN0aW9uIGF0dGVtcHRDbG9zZSgpIHtcbiAgICAvLyBjbG9zZSB0aGUgdG9vbCByZXN1bHRzIGNvbnRyb2xsZXIgaWYgbm8gbW9yZSBvdXRzdGFuZGluZyB0b29sIGNhbGxzXG4gICAgaWYgKGNhbkNsb3NlICYmIG91dHN0YW5kaW5nVG9vbFJlc3VsdHMuc2l6ZSA9PT0gMCkge1xuICAgICAgLy8gd2UgZGVsYXkgc2VuZGluZyB0aGUgZmluaXNoIGNodW5rIHVudGlsIGFsbCB0b29sIHJlc3VsdHMgKGluY2wuIGRlbGF5ZWQgb25lcylcbiAgICAgIC8vIGFyZSByZWNlaXZlZCB0byBlbnN1cmUgdGhhdCB0aGUgZnJvbnRlbmQgcmVjZWl2ZXMgdG9vbCByZXN1bHRzIGJlZm9yZSBhIG1lc3NhZ2VcbiAgICAgIC8vIGZpbmlzaCBldmVudCBhcnJpdmVzLlxuICAgICAgaWYgKGZpbmlzaENodW5rICE9IG51bGwpIHtcbiAgICAgICAgdG9vbFJlc3VsdHNTdHJlYW1Db250cm9sbGVyIS5lbnF1ZXVlKGZpbmlzaENodW5rKTtcbiAgICAgIH1cblxuICAgICAgdG9vbFJlc3VsdHNTdHJlYW1Db250cm9sbGVyIS5jbG9zZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8vIGZvcndhcmQgc3RyZWFtXG4gIGNvbnN0IGZvcndhcmRTdHJlYW0gPSBuZXcgVHJhbnNmb3JtU3RyZWFtPFxuICAgIExhbmd1YWdlTW9kZWxWMlN0cmVhbVBhcnQsXG4gICAgU2luZ2xlUmVxdWVzdFRleHRTdHJlYW1QYXJ0PFRPT0xTPlxuICA+KHtcbiAgICBhc3luYyB0cmFuc2Zvcm0oXG4gICAgICBjaHVuazogTGFuZ3VhZ2VNb2RlbFYyU3RyZWFtUGFydCxcbiAgICAgIGNvbnRyb2xsZXI6IFRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyPFxuICAgICAgICBTaW5nbGVSZXF1ZXN0VGV4dFN0cmVhbVBhcnQ8VE9PTFM+XG4gICAgICA+LFxuICAgICkge1xuICAgICAgY29uc3QgY2h1bmtUeXBlID0gY2h1bmsudHlwZTtcblxuICAgICAgc3dpdGNoIChjaHVua1R5cGUpIHtcbiAgICAgICAgLy8gZm9yd2FyZDpcbiAgICAgICAgY2FzZSAnc3RyZWFtLXN0YXJ0JzpcbiAgICAgICAgY2FzZSAndGV4dC1zdGFydCc6XG4gICAgICAgIGNhc2UgJ3RleHQtZGVsdGEnOlxuICAgICAgICBjYXNlICd0ZXh0LWVuZCc6XG4gICAgICAgIGNhc2UgJ3JlYXNvbmluZy1zdGFydCc6XG4gICAgICAgIGNhc2UgJ3JlYXNvbmluZy1kZWx0YSc6XG4gICAgICAgIGNhc2UgJ3JlYXNvbmluZy1lbmQnOlxuICAgICAgICBjYXNlICd0b29sLWlucHV0LXN0YXJ0JzpcbiAgICAgICAgY2FzZSAndG9vbC1pbnB1dC1kZWx0YSc6XG4gICAgICAgIGNhc2UgJ3Rvb2wtaW5wdXQtZW5kJzpcbiAgICAgICAgY2FzZSAnc291cmNlJzpcbiAgICAgICAgY2FzZSAncmVzcG9uc2UtbWV0YWRhdGEnOlxuICAgICAgICBjYXNlICdlcnJvcic6XG4gICAgICAgIGNhc2UgJ3Jhdyc6IHtcbiAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoY2h1bmspO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgY2FzZSAnZmlsZSc6IHtcbiAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgdHlwZTogJ2ZpbGUnLFxuICAgICAgICAgICAgZmlsZTogbmV3IERlZmF1bHRHZW5lcmF0ZWRGaWxlV2l0aFR5cGUoe1xuICAgICAgICAgICAgICBkYXRhOiBjaHVuay5kYXRhLFxuICAgICAgICAgICAgICBtZWRpYVR5cGU6IGNodW5rLm1lZGlhVHlwZSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgY2FzZSAnZmluaXNoJzoge1xuICAgICAgICAgIGZpbmlzaENodW5rID0ge1xuICAgICAgICAgICAgdHlwZTogJ2ZpbmlzaCcsXG4gICAgICAgICAgICBmaW5pc2hSZWFzb246IGNodW5rLmZpbmlzaFJlYXNvbixcbiAgICAgICAgICAgIHVzYWdlOiBjaHVuay51c2FnZSxcbiAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IGNodW5rLnByb3ZpZGVyTWV0YWRhdGEsXG4gICAgICAgICAgfTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHByb2Nlc3MgdG9vbCBjYWxsOlxuICAgICAgICBjYXNlICd0b29sLWNhbGwnOiB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHRvb2xDYWxsID0gYXdhaXQgcGFyc2VUb29sQ2FsbCh7XG4gICAgICAgICAgICAgIHRvb2xDYWxsOiBjaHVuayxcbiAgICAgICAgICAgICAgdG9vbHMsXG4gICAgICAgICAgICAgIHJlcGFpclRvb2xDYWxsLFxuICAgICAgICAgICAgICBzeXN0ZW0sXG4gICAgICAgICAgICAgIG1lc3NhZ2VzLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh0b29sQ2FsbCk7XG5cbiAgICAgICAgICAgIC8vIGhhbmRsZSBpbnZhbGlkIHRvb2wgY2FsbHM6XG4gICAgICAgICAgICBpZiAodG9vbENhbGwuaW52YWxpZCkge1xuICAgICAgICAgICAgICB0b29sUmVzdWx0c1N0cmVhbUNvbnRyb2xsZXIhLmVucXVldWUoe1xuICAgICAgICAgICAgICAgIHR5cGU6ICd0b29sLWVycm9yJyxcbiAgICAgICAgICAgICAgICB0b29sQ2FsbElkOiB0b29sQ2FsbC50b29sQ2FsbElkLFxuICAgICAgICAgICAgICAgIHRvb2xOYW1lOiB0b29sQ2FsbC50b29sTmFtZSxcbiAgICAgICAgICAgICAgICBpbnB1dDogdG9vbENhbGwuaW5wdXQsXG4gICAgICAgICAgICAgICAgZXJyb3I6IGdldEVycm9yTWVzc2FnZSh0b29sQ2FsbC5lcnJvciEpLFxuICAgICAgICAgICAgICAgIGR5bmFtaWM6IHRydWUsXG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCB0b29sID0gdG9vbHMhW3Rvb2xDYWxsLnRvb2xOYW1lXTtcblxuICAgICAgICAgICAgdG9vbElucHV0cy5zZXQodG9vbENhbGwudG9vbENhbGxJZCwgdG9vbENhbGwuaW5wdXQpO1xuXG4gICAgICAgICAgICBpZiAodG9vbC5vbklucHV0QXZhaWxhYmxlICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgYXdhaXQgdG9vbC5vbklucHV0QXZhaWxhYmxlKHtcbiAgICAgICAgICAgICAgICBpbnB1dDogdG9vbENhbGwuaW5wdXQsXG4gICAgICAgICAgICAgICAgdG9vbENhbGxJZDogdG9vbENhbGwudG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgICBtZXNzYWdlcyxcbiAgICAgICAgICAgICAgICBhYm9ydFNpZ25hbCxcbiAgICAgICAgICAgICAgICBleHBlcmltZW50YWxfY29udGV4dCxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIE9ubHkgZXhlY3V0ZSB0b29scyB0aGF0IGFyZSBub3QgcHJvdmlkZXItZXhlY3V0ZWQ6XG4gICAgICAgICAgICBpZiAodG9vbC5leGVjdXRlICE9IG51bGwgJiYgdG9vbENhbGwucHJvdmlkZXJFeGVjdXRlZCAhPT0gdHJ1ZSkge1xuICAgICAgICAgICAgICBjb25zdCB0b29sRXhlY3V0aW9uSWQgPSBnZW5lcmF0ZUlkKCk7IC8vIHVzZSBvdXIgb3duIGlkIHRvIGd1YXJhbnRlZSB1bmlxdWVuZXNzXG4gICAgICAgICAgICAgIG91dHN0YW5kaW5nVG9vbFJlc3VsdHMuYWRkKHRvb2xFeGVjdXRpb25JZCk7XG5cbiAgICAgICAgICAgICAgLy8gTm90ZTogd2UgZG9uJ3QgYXdhaXQgdGhlIHRvb2wgZXhlY3V0aW9uIGhlcmUgKGJ5IGxlYXZpbmcgb3V0ICdhd2FpdCcgb24gcmVjb3JkU3BhbiksXG4gICAgICAgICAgICAgIC8vIGJlY2F1c2Ugd2Ugd2FudCB0byBwcm9jZXNzIHRoZSBuZXh0IGNodW5rIGFzIHNvb24gYXMgcG9zc2libGUuXG4gICAgICAgICAgICAgIC8vIFRoaXMgaXMgaW1wb3J0YW50IGZvciB0aGUgY2FzZSB3aGVyZSB0aGUgdG9vbCBleGVjdXRpb24gdGFrZXMgYSBsb25nIHRpbWUuXG4gICAgICAgICAgICAgIHJlY29yZFNwYW4oe1xuICAgICAgICAgICAgICAgIG5hbWU6ICdhaS50b29sQ2FsbCcsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlczogc2VsZWN0VGVsZW1ldHJ5QXR0cmlidXRlcyh7XG4gICAgICAgICAgICAgICAgICB0ZWxlbWV0cnksXG4gICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgICAgICAgICAgIC4uLmFzc2VtYmxlT3BlcmF0aW9uTmFtZSh7XG4gICAgICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uSWQ6ICdhaS50b29sQ2FsbCcsXG4gICAgICAgICAgICAgICAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgJ2FpLnRvb2xDYWxsLm5hbWUnOiB0b29sQ2FsbC50b29sTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgJ2FpLnRvb2xDYWxsLmlkJzogdG9vbENhbGwudG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgICAgICAgJ2FpLnRvb2xDYWxsLmFyZ3MnOiB7XG4gICAgICAgICAgICAgICAgICAgICAgb3V0cHV0OiAoKSA9PiBKU09OLnN0cmluZ2lmeSh0b29sQ2FsbC5pbnB1dCksXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIHRyYWNlcixcbiAgICAgICAgICAgICAgICBmbjogYXN5bmMgc3BhbiA9PiB7XG4gICAgICAgICAgICAgICAgICBsZXQgb3V0cHV0OiB1bmtub3duO1xuXG4gICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBleGVjdXRlVG9vbCh7XG4gICAgICAgICAgICAgICAgICAgICAgZXhlY3V0ZTogdG9vbC5leGVjdXRlIS5iaW5kKHRvb2wpLFxuICAgICAgICAgICAgICAgICAgICAgIGlucHV0OiB0b29sQ2FsbC5pbnB1dCxcbiAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b29sQ2FsbElkOiB0b29sQ2FsbC50b29sQ2FsbElkLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZXMsXG4gICAgICAgICAgICAgICAgICAgICAgICBhYm9ydFNpZ25hbCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVyaW1lbnRhbF9jb250ZXh0LFxuICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgIGZvciBhd2FpdCAoY29uc3QgcGFydCBvZiBzdHJlYW0pIHtcbiAgICAgICAgICAgICAgICAgICAgICB0b29sUmVzdWx0c1N0cmVhbUNvbnRyb2xsZXIhLmVucXVldWUoe1xuICAgICAgICAgICAgICAgICAgICAgICAgLi4udG9vbENhbGwsXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAndG9vbC1yZXN1bHQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0OiBwYXJ0Lm91dHB1dCxcbiAgICAgICAgICAgICAgICAgICAgICAgIC4uLihwYXJ0LnR5cGUgPT09ICdwcmVsaW1pbmFyeScgJiYge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVsaW1pbmFyeTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnQudHlwZSA9PT0gJ2ZpbmFsJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0ID0gcGFydC5vdXRwdXQ7XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICByZWNvcmRFcnJvck9uU3BhbihzcGFuLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIHRvb2xSZXN1bHRzU3RyZWFtQ29udHJvbGxlciEuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgLi4udG9vbENhbGwsXG4gICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3Rvb2wtZXJyb3InLFxuICAgICAgICAgICAgICAgICAgICAgIGVycm9yLFxuICAgICAgICAgICAgICAgICAgICB9IHNhdGlzZmllcyBUeXBlZFRvb2xFcnJvcjxUT09MUz4pO1xuXG4gICAgICAgICAgICAgICAgICAgIG91dHN0YW5kaW5nVG9vbFJlc3VsdHMuZGVsZXRlKHRvb2xFeGVjdXRpb25JZCk7XG4gICAgICAgICAgICAgICAgICAgIGF0dGVtcHRDbG9zZSgpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgIG91dHN0YW5kaW5nVG9vbFJlc3VsdHMuZGVsZXRlKHRvb2xFeGVjdXRpb25JZCk7XG4gICAgICAgICAgICAgICAgICBhdHRlbXB0Q2xvc2UoKTtcblxuICAgICAgICAgICAgICAgICAgLy8gcmVjb3JkIHRlbGVtZXRyeVxuICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGVzKFxuICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgICAgICAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAnYWkudG9vbENhbGwucmVzdWx0Jzoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dDogKCkgPT4gSlNPTi5zdHJpbmdpZnkob3V0cHV0KSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICB9IGNhdGNoIChpZ25vcmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEpTT04gc3RyaW5naWZ5IG1pZ2h0IGZhaWwgaWYgdGhlIHJlc3VsdCBpcyBub3Qgc2VyaWFsaXphYmxlLFxuICAgICAgICAgICAgICAgICAgICAvLyBpbiB3aGljaCBjYXNlIHdlIGp1c3QgaWdub3JlIGl0LiBJbiB0aGUgZnV0dXJlIHdlIG1pZ2h0IHdhbnQgdG9cbiAgICAgICAgICAgICAgICAgICAgLy8gYWRkIGFuIG9wdGlvbmFsIHNlcmlhbGl6ZSBtZXRob2QgdG8gdGhlIHRvb2wgaW50ZXJmYWNlIGFuZCB3YXJuXG4gICAgICAgICAgICAgICAgICAgIC8vIGlmIHRoZSByZXN1bHQgaXMgbm90IHNlcmlhbGl6YWJsZS5cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgdG9vbFJlc3VsdHNTdHJlYW1Db250cm9sbGVyIS5lbnF1ZXVlKHsgdHlwZTogJ2Vycm9yJywgZXJyb3IgfSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBjYXNlICd0b29sLXJlc3VsdCc6IHtcbiAgICAgICAgICBjb25zdCB0b29sTmFtZSA9IGNodW5rLnRvb2xOYW1lIGFzIGtleW9mIFRPT0xTICYgc3RyaW5nO1xuXG4gICAgICAgICAgaWYgKGNodW5rLmlzRXJyb3IpIHtcbiAgICAgICAgICAgIHRvb2xSZXN1bHRzU3RyZWFtQ29udHJvbGxlciEuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgIHR5cGU6ICd0b29sLWVycm9yJyxcbiAgICAgICAgICAgICAgdG9vbENhbGxJZDogY2h1bmsudG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgdG9vbE5hbWUsXG4gICAgICAgICAgICAgIGlucHV0OiB0b29sSW5wdXRzLmdldChjaHVuay50b29sQ2FsbElkKSxcbiAgICAgICAgICAgICAgcHJvdmlkZXJFeGVjdXRlZDogY2h1bmsucHJvdmlkZXJFeGVjdXRlZCxcbiAgICAgICAgICAgICAgZXJyb3I6IGNodW5rLnJlc3VsdCxcbiAgICAgICAgICAgIH0gYXMgVHlwZWRUb29sRXJyb3I8VE9PTFM+KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHtcbiAgICAgICAgICAgICAgdHlwZTogJ3Rvb2wtcmVzdWx0JyxcbiAgICAgICAgICAgICAgdG9vbENhbGxJZDogY2h1bmsudG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgdG9vbE5hbWUsXG4gICAgICAgICAgICAgIGlucHV0OiB0b29sSW5wdXRzLmdldChjaHVuay50b29sQ2FsbElkKSxcbiAgICAgICAgICAgICAgb3V0cHV0OiBjaHVuay5yZXN1bHQsXG4gICAgICAgICAgICAgIHByb3ZpZGVyRXhlY3V0ZWQ6IGNodW5rLnByb3ZpZGVyRXhlY3V0ZWQsXG4gICAgICAgICAgICB9IGFzIFR5cGVkVG9vbFJlc3VsdDxUT09MUz4pO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICBjb25zdCBfZXhoYXVzdGl2ZUNoZWNrOiBuZXZlciA9IGNodW5rVHlwZTtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuaGFuZGxlZCBjaHVuayB0eXBlOiAke19leGhhdXN0aXZlQ2hlY2t9YCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuXG4gICAgZmx1c2goKSB7XG4gICAgICBjYW5DbG9zZSA9IHRydWU7XG4gICAgICBhdHRlbXB0Q2xvc2UoKTtcbiAgICB9LFxuICB9KTtcblxuICAvLyBjb21iaW5lIHRoZSBnZW5lcmF0b3Igc3RyZWFtIGFuZCB0aGUgdG9vbCByZXN1bHRzIHN0cmVhbVxuICByZXR1cm4gbmV3IFJlYWRhYmxlU3RyZWFtPFNpbmdsZVJlcXVlc3RUZXh0U3RyZWFtUGFydDxUT09MUz4+KHtcbiAgICBhc3luYyBzdGFydChjb250cm9sbGVyKSB7XG4gICAgICAvLyBuZWVkIHRvIHdhaXQgZm9yIGJvdGggcGlwZXMgc28gdGhlcmUgYXJlIG5vIGRhbmdsaW5nIHByb21pc2VzIHRoYXRcbiAgICAgIC8vIGNhbiBjYXVzZSB1bmNhdWdodCBwcm9taXNlIHJlamVjdGlvbnMgd2hlbiB0aGUgc3RyZWFtIGlzIGFib3J0ZWRcbiAgICAgIHJldHVybiBQcm9taXNlLmFsbChbXG4gICAgICAgIGdlbmVyYXRvclN0cmVhbS5waXBlVGhyb3VnaChmb3J3YXJkU3RyZWFtKS5waXBlVG8oXG4gICAgICAgICAgbmV3IFdyaXRhYmxlU3RyZWFtKHtcbiAgICAgICAgICAgIHdyaXRlKGNodW5rKSB7XG4gICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShjaHVuayk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY2xvc2UoKSB7XG4gICAgICAgICAgICAgIC8vIHRoZSBnZW5lcmF0b3Igc3RyZWFtIGNvbnRyb2xsZXIgaXMgYXV0b21hdGljYWxseSBjbG9zZWQgd2hlbiBpdCdzIGNvbnN1bWVkXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pLFxuICAgICAgICApLFxuICAgICAgICB0b29sUmVzdWx0c1N0cmVhbS5waXBlVG8oXG4gICAgICAgICAgbmV3IFdyaXRhYmxlU3RyZWFtKHtcbiAgICAgICAgICAgIHdyaXRlKGNodW5rKSB7XG4gICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShjaHVuayk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY2xvc2UoKSB7XG4gICAgICAgICAgICAgIGNvbnRyb2xsZXIuY2xvc2UoKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSksXG4gICAgICAgICksXG4gICAgICBdKTtcbiAgICB9LFxuICB9KTtcbn1cbiIsICJpbXBvcnQge1xuICBBc3Npc3RhbnRDb250ZW50LFxuICBNb2RlbE1lc3NhZ2UsXG4gIFRvb2xSZXN1bHRQYXJ0LFxufSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyLXV0aWxzJztcbmltcG9ydCB7IFRvb2xTZXQgfSBmcm9tICcuLi9nZW5lcmF0ZS10ZXh0L3Rvb2wtc2V0JztcbmltcG9ydCB7IGNyZWF0ZVRvb2xNb2RlbE91dHB1dCB9IGZyb20gJy4uL3Byb21wdC9jcmVhdGUtdG9vbC1tb2RlbC1vdXRwdXQnO1xuaW1wb3J0IHsgTWVzc2FnZUNvbnZlcnNpb25FcnJvciB9IGZyb20gJy4uL3Byb21wdC9tZXNzYWdlLWNvbnZlcnNpb24tZXJyb3InO1xuaW1wb3J0IHtcbiAgRHluYW1pY1Rvb2xVSVBhcnQsXG4gIEZpbGVVSVBhcnQsXG4gIGdldFRvb2xOYW1lLFxuICBpc1Rvb2xPckR5bmFtaWNUb29sVUlQYXJ0LFxuICBpc1Rvb2xVSVBhcnQsXG4gIFJlYXNvbmluZ1VJUGFydCxcbiAgVGV4dFVJUGFydCxcbiAgVG9vbFVJUGFydCxcbiAgVUlNZXNzYWdlLFxuICBVSVRvb2xzLFxufSBmcm9tICcuL3VpLW1lc3NhZ2VzJztcblxuLyoqXG5Db252ZXJ0cyBhbiBhcnJheSBvZiBVSSBtZXNzYWdlcyBmcm9tIHVzZUNoYXQgaW50byBhbiBhcnJheSBvZiBNb2RlbE1lc3NhZ2VzIHRoYXQgY2FuIGJlIHVzZWRcbndpdGggdGhlIEFJIGZ1bmN0aW9ucyAoZS5nLiBgc3RyZWFtVGV4dGAsIGBnZW5lcmF0ZVRleHRgKS5cblxuQHBhcmFtIG1lc3NhZ2VzIC0gVGhlIFVJIG1lc3NhZ2VzIHRvIGNvbnZlcnQuXG5AcGFyYW0gb3B0aW9ucy50b29scyAtIFRoZSB0b29scyB0byB1c2UuXG5AcGFyYW0gb3B0aW9ucy5pZ25vcmVJbmNvbXBsZXRlVG9vbENhbGxzIC0gV2hldGhlciB0byBpZ25vcmUgaW5jb21wbGV0ZSB0b29sIGNhbGxzLiBEZWZhdWx0IGlzIGBmYWxzZWAuXG5cbkByZXR1cm5zIEFuIGFycmF5IG9mIE1vZGVsTWVzc2FnZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb252ZXJ0VG9Nb2RlbE1lc3NhZ2VzKFxuICBtZXNzYWdlczogQXJyYXk8T21pdDxVSU1lc3NhZ2UsICdpZCc+PixcbiAgb3B0aW9ucz86IHtcbiAgICB0b29scz86IFRvb2xTZXQ7XG4gICAgaWdub3JlSW5jb21wbGV0ZVRvb2xDYWxscz86IGJvb2xlYW47XG4gIH0sXG4pOiBNb2RlbE1lc3NhZ2VbXSB7XG4gIGNvbnN0IG1vZGVsTWVzc2FnZXM6IE1vZGVsTWVzc2FnZVtdID0gW107XG5cbiAgaWYgKG9wdGlvbnM/Lmlnbm9yZUluY29tcGxldGVUb29sQ2FsbHMpIHtcbiAgICBtZXNzYWdlcyA9IG1lc3NhZ2VzLm1hcChtZXNzYWdlID0+ICh7XG4gICAgICAuLi5tZXNzYWdlLFxuICAgICAgcGFydHM6IG1lc3NhZ2UucGFydHMuZmlsdGVyKFxuICAgICAgICBwYXJ0ID0+XG4gICAgICAgICAgIWlzVG9vbE9yRHluYW1pY1Rvb2xVSVBhcnQocGFydCkgfHxcbiAgICAgICAgICAocGFydC5zdGF0ZSAhPT0gJ2lucHV0LXN0cmVhbWluZycgJiZcbiAgICAgICAgICAgIHBhcnQuc3RhdGUgIT09ICdpbnB1dC1hdmFpbGFibGUnKSxcbiAgICAgICksXG4gICAgfSkpO1xuICB9XG5cbiAgZm9yIChjb25zdCBtZXNzYWdlIG9mIG1lc3NhZ2VzKSB7XG4gICAgc3dpdGNoIChtZXNzYWdlLnJvbGUpIHtcbiAgICAgIGNhc2UgJ3N5c3RlbSc6IHtcbiAgICAgICAgY29uc3QgdGV4dFBhcnRzID0gbWVzc2FnZS5wYXJ0cy5maWx0ZXIocGFydCA9PiBwYXJ0LnR5cGUgPT09ICd0ZXh0Jyk7XG5cbiAgICAgICAgY29uc3QgcHJvdmlkZXJNZXRhZGF0YSA9IHRleHRQYXJ0cy5yZWR1Y2UoKGFjYywgcGFydCkgPT4ge1xuICAgICAgICAgIGlmIChwYXJ0LnByb3ZpZGVyTWV0YWRhdGEgIT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIHsgLi4uYWNjLCAuLi5wYXJ0LnByb3ZpZGVyTWV0YWRhdGEgfTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgICAgfSwge30pO1xuXG4gICAgICAgIG1vZGVsTWVzc2FnZXMucHVzaCh7XG4gICAgICAgICAgcm9sZTogJ3N5c3RlbScsXG4gICAgICAgICAgY29udGVudDogdGV4dFBhcnRzLm1hcChwYXJ0ID0+IHBhcnQudGV4dCkuam9pbignJyksXG4gICAgICAgICAgLi4uKE9iamVjdC5rZXlzKHByb3ZpZGVyTWV0YWRhdGEpLmxlbmd0aCA+IDBcbiAgICAgICAgICAgID8geyBwcm92aWRlck9wdGlvbnM6IHByb3ZpZGVyTWV0YWRhdGEgfVxuICAgICAgICAgICAgOiB7fSksXG4gICAgICAgIH0pO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgY2FzZSAndXNlcic6IHtcbiAgICAgICAgbW9kZWxNZXNzYWdlcy5wdXNoKHtcbiAgICAgICAgICByb2xlOiAndXNlcicsXG4gICAgICAgICAgY29udGVudDogbWVzc2FnZS5wYXJ0c1xuICAgICAgICAgICAgLmZpbHRlcihcbiAgICAgICAgICAgICAgKHBhcnQpOiBwYXJ0IGlzIFRleHRVSVBhcnQgfCBGaWxlVUlQYXJ0ID0+XG4gICAgICAgICAgICAgICAgcGFydC50eXBlID09PSAndGV4dCcgfHwgcGFydC50eXBlID09PSAnZmlsZScsXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAubWFwKHBhcnQgPT4ge1xuICAgICAgICAgICAgICBzd2l0Y2ggKHBhcnQudHlwZSkge1xuICAgICAgICAgICAgICAgIGNhc2UgJ3RleHQnOlxuICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3RleHQnIGFzIGNvbnN0LFxuICAgICAgICAgICAgICAgICAgICB0ZXh0OiBwYXJ0LnRleHQsXG4gICAgICAgICAgICAgICAgICAgIC4uLihwYXJ0LnByb3ZpZGVyTWV0YWRhdGEgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgICAgID8geyBwcm92aWRlck9wdGlvbnM6IHBhcnQucHJvdmlkZXJNZXRhZGF0YSB9XG4gICAgICAgICAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGNhc2UgJ2ZpbGUnOlxuICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2ZpbGUnIGFzIGNvbnN0LFxuICAgICAgICAgICAgICAgICAgICBtZWRpYVR5cGU6IHBhcnQubWVkaWFUeXBlLFxuICAgICAgICAgICAgICAgICAgICBmaWxlbmFtZTogcGFydC5maWxlbmFtZSxcbiAgICAgICAgICAgICAgICAgICAgZGF0YTogcGFydC51cmwsXG4gICAgICAgICAgICAgICAgICAgIC4uLihwYXJ0LnByb3ZpZGVyTWV0YWRhdGEgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgICAgID8geyBwcm92aWRlck9wdGlvbnM6IHBhcnQucHJvdmlkZXJNZXRhZGF0YSB9XG4gICAgICAgICAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICByZXR1cm4gcGFydDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSksXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBjYXNlICdhc3Npc3RhbnQnOiB7XG4gICAgICAgIGlmIChtZXNzYWdlLnBhcnRzICE9IG51bGwpIHtcbiAgICAgICAgICBsZXQgYmxvY2s6IEFycmF5PFxuICAgICAgICAgICAgfCBUZXh0VUlQYXJ0XG4gICAgICAgICAgICB8IFRvb2xVSVBhcnQ8VUlUb29scz5cbiAgICAgICAgICAgIHwgUmVhc29uaW5nVUlQYXJ0XG4gICAgICAgICAgICB8IEZpbGVVSVBhcnRcbiAgICAgICAgICAgIHwgRHluYW1pY1Rvb2xVSVBhcnRcbiAgICAgICAgICA+ID0gW107XG5cbiAgICAgICAgICBmdW5jdGlvbiBwcm9jZXNzQmxvY2soKSB7XG4gICAgICAgICAgICBpZiAoYmxvY2subGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgY29udGVudDogQXNzaXN0YW50Q29udGVudCA9IFtdO1xuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHBhcnQgb2YgYmxvY2spIHtcbiAgICAgICAgICAgICAgaWYgKHBhcnQudHlwZSA9PT0gJ3RleHQnKSB7XG4gICAgICAgICAgICAgICAgY29udGVudC5wdXNoKHtcbiAgICAgICAgICAgICAgICAgIHR5cGU6ICd0ZXh0JyBhcyBjb25zdCxcbiAgICAgICAgICAgICAgICAgIHRleHQ6IHBhcnQudGV4dCxcbiAgICAgICAgICAgICAgICAgIC4uLihwYXJ0LnByb3ZpZGVyTWV0YWRhdGEgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgICA/IHsgcHJvdmlkZXJPcHRpb25zOiBwYXJ0LnByb3ZpZGVyTWV0YWRhdGEgfVxuICAgICAgICAgICAgICAgICAgICA6IHt9KSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfSBlbHNlIGlmIChwYXJ0LnR5cGUgPT09ICdmaWxlJykge1xuICAgICAgICAgICAgICAgIGNvbnRlbnQucHVzaCh7XG4gICAgICAgICAgICAgICAgICB0eXBlOiAnZmlsZScgYXMgY29uc3QsXG4gICAgICAgICAgICAgICAgICBtZWRpYVR5cGU6IHBhcnQubWVkaWFUeXBlLFxuICAgICAgICAgICAgICAgICAgZmlsZW5hbWU6IHBhcnQuZmlsZW5hbWUsXG4gICAgICAgICAgICAgICAgICBkYXRhOiBwYXJ0LnVybCxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfSBlbHNlIGlmIChwYXJ0LnR5cGUgPT09ICdyZWFzb25pbmcnKSB7XG4gICAgICAgICAgICAgICAgY29udGVudC5wdXNoKHtcbiAgICAgICAgICAgICAgICAgIHR5cGU6ICdyZWFzb25pbmcnIGFzIGNvbnN0LFxuICAgICAgICAgICAgICAgICAgdGV4dDogcGFydC50ZXh0LFxuICAgICAgICAgICAgICAgICAgcHJvdmlkZXJPcHRpb25zOiBwYXJ0LnByb3ZpZGVyTWV0YWRhdGEsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAocGFydC50eXBlID09PSAnZHluYW1pYy10b29sJykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRvb2xOYW1lID0gcGFydC50b29sTmFtZTtcblxuICAgICAgICAgICAgICAgIGlmIChwYXJ0LnN0YXRlICE9PSAnaW5wdXQtc3RyZWFtaW5nJykge1xuICAgICAgICAgICAgICAgICAgY29udGVudC5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3Rvb2wtY2FsbCcgYXMgY29uc3QsXG4gICAgICAgICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IHBhcnQudG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgICAgICAgdG9vbE5hbWUsXG4gICAgICAgICAgICAgICAgICAgIGlucHV0OiBwYXJ0LmlucHV0LFxuICAgICAgICAgICAgICAgICAgICAuLi4ocGFydC5jYWxsUHJvdmlkZXJNZXRhZGF0YSAhPSBudWxsXG4gICAgICAgICAgICAgICAgICAgICAgPyB7IHByb3ZpZGVyT3B0aW9uczogcGFydC5jYWxsUHJvdmlkZXJNZXRhZGF0YSB9XG4gICAgICAgICAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNUb29sVUlQYXJ0KHBhcnQpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdG9vbE5hbWUgPSBnZXRUb29sTmFtZShwYXJ0KTtcblxuICAgICAgICAgICAgICAgIGlmIChwYXJ0LnN0YXRlICE9PSAnaW5wdXQtc3RyZWFtaW5nJykge1xuICAgICAgICAgICAgICAgICAgY29udGVudC5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3Rvb2wtY2FsbCcgYXMgY29uc3QsXG4gICAgICAgICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IHBhcnQudG9vbENhbGxJZCxcbiAgICAgICAgICAgICAgICAgICAgdG9vbE5hbWUsXG4gICAgICAgICAgICAgICAgICAgIGlucHV0OlxuICAgICAgICAgICAgICAgICAgICAgIHBhcnQuc3RhdGUgPT09ICdvdXRwdXQtZXJyb3InXG4gICAgICAgICAgICAgICAgICAgICAgICA/IChwYXJ0LmlucHV0ID8/IHBhcnQucmF3SW5wdXQpXG4gICAgICAgICAgICAgICAgICAgICAgICA6IHBhcnQuaW5wdXQsXG4gICAgICAgICAgICAgICAgICAgIHByb3ZpZGVyRXhlY3V0ZWQ6IHBhcnQucHJvdmlkZXJFeGVjdXRlZCxcbiAgICAgICAgICAgICAgICAgICAgLi4uKHBhcnQuY2FsbFByb3ZpZGVyTWV0YWRhdGEgIT0gbnVsbFxuICAgICAgICAgICAgICAgICAgICAgID8geyBwcm92aWRlck9wdGlvbnM6IHBhcnQuY2FsbFByb3ZpZGVyTWV0YWRhdGEgfVxuICAgICAgICAgICAgICAgICAgICAgIDoge30pLFxuICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgcGFydC5wcm92aWRlckV4ZWN1dGVkID09PSB0cnVlICYmXG4gICAgICAgICAgICAgICAgICAgIChwYXJ0LnN0YXRlID09PSAnb3V0cHV0LWF2YWlsYWJsZScgfHxcbiAgICAgICAgICAgICAgICAgICAgICBwYXJ0LnN0YXRlID09PSAnb3V0cHV0LWVycm9yJylcbiAgICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICBjb250ZW50LnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICd0b29sLXJlc3VsdCcsXG4gICAgICAgICAgICAgICAgICAgICAgdG9vbENhbGxJZDogcGFydC50b29sQ2FsbElkLFxuICAgICAgICAgICAgICAgICAgICAgIHRvb2xOYW1lLFxuICAgICAgICAgICAgICAgICAgICAgIG91dHB1dDogY3JlYXRlVG9vbE1vZGVsT3V0cHV0KHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcGFydC5zdGF0ZSA9PT0gJ291dHB1dC1lcnJvcidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHBhcnQuZXJyb3JUZXh0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBwYXJ0Lm91dHB1dCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvb2w6IG9wdGlvbnM/LnRvb2xzPy5bdG9vbE5hbWVdLFxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNb2RlOlxuICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJ0LnN0YXRlID09PSAnb3V0cHV0LWVycm9yJyA/ICdqc29uJyA6ICdub25lJyxcbiAgICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IF9leGhhdXN0aXZlQ2hlY2s6IG5ldmVyID0gcGFydDtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIHBhcnQ6ICR7X2V4aGF1c3RpdmVDaGVja31gKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBtb2RlbE1lc3NhZ2VzLnB1c2goe1xuICAgICAgICAgICAgICByb2xlOiAnYXNzaXN0YW50JyxcbiAgICAgICAgICAgICAgY29udGVudCxcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyBjaGVjayBpZiB0aGVyZSBhcmUgdG9vbCBpbnZvY2F0aW9ucyB3aXRoIHJlc3VsdHMgaW4gdGhlIGJsb2NrXG4gICAgICAgICAgICBjb25zdCB0b29sUGFydHMgPSBibG9jay5maWx0ZXIoXG4gICAgICAgICAgICAgIHBhcnQgPT5cbiAgICAgICAgICAgICAgICAoaXNUb29sVUlQYXJ0KHBhcnQpICYmIHBhcnQucHJvdmlkZXJFeGVjdXRlZCAhPT0gdHJ1ZSkgfHxcbiAgICAgICAgICAgICAgICBwYXJ0LnR5cGUgPT09ICdkeW5hbWljLXRvb2wnLFxuICAgICAgICAgICAgKSBhcyAoVG9vbFVJUGFydDxVSVRvb2xzPiB8IER5bmFtaWNUb29sVUlQYXJ0KVtdO1xuXG4gICAgICAgICAgICAvLyB0b29sIG1lc3NhZ2Ugd2l0aCB0b29sIHJlc3VsdHNcbiAgICAgICAgICAgIGlmICh0b29sUGFydHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICBtb2RlbE1lc3NhZ2VzLnB1c2goe1xuICAgICAgICAgICAgICAgIHJvbGU6ICd0b29sJyxcbiAgICAgICAgICAgICAgICBjb250ZW50OiB0b29sUGFydHNcbiAgICAgICAgICAgICAgICAgIC5tYXAoKHRvb2xQYXJ0KTogVG9vbFJlc3VsdFBhcnQgfCBudWxsID0+IHtcbiAgICAgICAgICAgICAgICAgICAgc3dpdGNoICh0b29sUGFydC5zdGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ291dHB1dC1lcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgY2FzZSAnb3V0cHV0LWF2YWlsYWJsZSc6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRvb2xOYW1lID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgdG9vbFBhcnQudHlwZSA9PT0gJ2R5bmFtaWMtdG9vbCdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHRvb2xQYXJ0LnRvb2xOYW1lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBnZXRUb29sTmFtZSh0b29sUGFydCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICd0b29sLXJlc3VsdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IHRvb2xQYXJ0LnRvb2xDYWxsSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHRvb2xOYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQ6IGNyZWF0ZVRvb2xNb2RlbE91dHB1dCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0OlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9vbFBhcnQuc3RhdGUgPT09ICdvdXRwdXQtZXJyb3InXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gdG9vbFBhcnQuZXJyb3JUZXh0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogdG9vbFBhcnQub3V0cHV0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvb2w6IG9wdGlvbnM/LnRvb2xzPy5bdG9vbE5hbWVdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTW9kZTpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvb2xQYXJ0LnN0YXRlID09PSAnb3V0cHV0LWVycm9yJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/ICd0ZXh0J1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICdub25lJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAuZmlsdGVyKFxuICAgICAgICAgICAgICAgICAgICAob3V0cHV0KTogb3V0cHV0IGlzIE5vbk51bGxhYmxlPHR5cGVvZiBvdXRwdXQ+ID0+XG4gICAgICAgICAgICAgICAgICAgICAgb3V0cHV0ICE9IG51bGwsXG4gICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gdXBkYXRlcyBmb3IgbmV4dCBibG9ja1xuICAgICAgICAgICAgYmxvY2sgPSBbXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBmb3IgKGNvbnN0IHBhcnQgb2YgbWVzc2FnZS5wYXJ0cykge1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICBwYXJ0LnR5cGUgPT09ICd0ZXh0JyB8fFxuICAgICAgICAgICAgICBwYXJ0LnR5cGUgPT09ICdyZWFzb25pbmcnIHx8XG4gICAgICAgICAgICAgIHBhcnQudHlwZSA9PT0gJ2ZpbGUnIHx8XG4gICAgICAgICAgICAgIHBhcnQudHlwZSA9PT0gJ2R5bmFtaWMtdG9vbCcgfHxcbiAgICAgICAgICAgICAgaXNUb29sVUlQYXJ0KHBhcnQpXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgYmxvY2sucHVzaChwYXJ0KTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocGFydC50eXBlID09PSAnc3RlcC1zdGFydCcpIHtcbiAgICAgICAgICAgICAgcHJvY2Vzc0Jsb2NrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcHJvY2Vzc0Jsb2NrKCk7XG5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBkZWZhdWx0OiB7XG4gICAgICAgIGNvbnN0IF9leGhhdXN0aXZlQ2hlY2s6IG5ldmVyID0gbWVzc2FnZS5yb2xlO1xuICAgICAgICB0aHJvdyBuZXcgTWVzc2FnZUNvbnZlcnNpb25FcnJvcih7XG4gICAgICAgICAgb3JpZ2luYWxNZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgICAgIG1lc3NhZ2U6IGBVbnN1cHBvcnRlZCByb2xlOiAke19leGhhdXN0aXZlQ2hlY2t9YCxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG1vZGVsTWVzc2FnZXM7XG59XG5cbi8qKlxuQGRlcHJlY2F0ZWQgVXNlIGBjb252ZXJ0VG9Nb2RlbE1lc3NhZ2VzYCBpbnN0ZWFkLlxuICovXG4vLyBUT0RPIHJlbW92ZSBpbiBBSSBTREsgNlxuZXhwb3J0IGNvbnN0IGNvbnZlcnRUb0NvcmVNZXNzYWdlcyA9IGNvbnZlcnRUb01vZGVsTWVzc2FnZXM7XG4iLCAiaW1wb3J0IHsgSWRHZW5lcmF0b3IsIFByb3ZpZGVyT3B0aW9ucyB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXItdXRpbHMnO1xuaW1wb3J0IHtcbiAgZ2VuZXJhdGVUZXh0LFxuICBHZW5lcmF0ZVRleHRPblN0ZXBGaW5pc2hDYWxsYmFjayxcbn0gZnJvbSAnLi4vZ2VuZXJhdGUtdGV4dC9nZW5lcmF0ZS10ZXh0JztcbmltcG9ydCB7IEdlbmVyYXRlVGV4dFJlc3VsdCB9IGZyb20gJy4uL2dlbmVyYXRlLXRleHQvZ2VuZXJhdGUtdGV4dC1yZXN1bHQnO1xuaW1wb3J0IHsgT3V0cHV0IH0gZnJvbSAnLi4vZ2VuZXJhdGUtdGV4dC9vdXRwdXQnO1xuaW1wb3J0IHsgUHJlcGFyZVN0ZXBGdW5jdGlvbiB9IGZyb20gJy4uL2dlbmVyYXRlLXRleHQvcHJlcGFyZS1zdGVwJztcbmltcG9ydCB7IFN0b3BDb25kaXRpb24gfSBmcm9tICcuLi9nZW5lcmF0ZS10ZXh0L3N0b3AtY29uZGl0aW9uJztcbmltcG9ydCB7IHN0cmVhbVRleHQgfSBmcm9tICcuLi9nZW5lcmF0ZS10ZXh0L3N0cmVhbS10ZXh0JztcbmltcG9ydCB7IFN0cmVhbVRleHRSZXN1bHQgfSBmcm9tICcuLi9nZW5lcmF0ZS10ZXh0L3N0cmVhbS10ZXh0LXJlc3VsdCc7XG5pbXBvcnQgeyBUb29sQ2FsbFJlcGFpckZ1bmN0aW9uIH0gZnJvbSAnLi4vZ2VuZXJhdGUtdGV4dC90b29sLWNhbGwtcmVwYWlyLWZ1bmN0aW9uJztcbmltcG9ydCB7IFRvb2xTZXQgfSBmcm9tICcuLi9nZW5lcmF0ZS10ZXh0L3Rvb2wtc2V0JztcbmltcG9ydCB7IENhbGxTZXR0aW5ncyB9IGZyb20gJy4uL3Byb21wdC9jYWxsLXNldHRpbmdzJztcbmltcG9ydCB7IFByb21wdCB9IGZyb20gJy4uL3Byb21wdC9wcm9tcHQnO1xuaW1wb3J0IHsgVGVsZW1ldHJ5U2V0dGluZ3MgfSBmcm9tICcuLi90ZWxlbWV0cnkvdGVsZW1ldHJ5LXNldHRpbmdzJztcbmltcG9ydCB7IExhbmd1YWdlTW9kZWwsIFRvb2xDaG9pY2UgfSBmcm9tICcuLi90eXBlcy9sYW5ndWFnZS1tb2RlbCc7XG5pbXBvcnQgeyBQcm92aWRlck1ldGFkYXRhIH0gZnJvbSAnLi4vdHlwZXMvcHJvdmlkZXItbWV0YWRhdGEnO1xuaW1wb3J0IHsgY29udmVydFRvTW9kZWxNZXNzYWdlcyB9IGZyb20gJy4uL3VpL2NvbnZlcnQtdG8tbW9kZWwtbWVzc2FnZXMnO1xuaW1wb3J0IHsgSW5mZXJVSVRvb2xzLCBVSU1lc3NhZ2UgfSBmcm9tICcuLi91aS91aS1tZXNzYWdlcyc7XG5cbmV4cG9ydCB0eXBlIEFnZW50U2V0dGluZ3M8XG4gIFRPT0xTIGV4dGVuZHMgVG9vbFNldCxcbiAgT1VUUFVUID0gbmV2ZXIsXG4gIE9VVFBVVF9QQVJUSUFMID0gbmV2ZXIsXG4+ID0gQ2FsbFNldHRpbmdzICYge1xuICAvKipcbiAgICogVGhlIHN5c3RlbSBwcm9tcHQgdG8gdXNlLlxuICAgKi9cbiAgc3lzdGVtPzogc3RyaW5nO1xuXG4gIC8qKlxuVGhlIGxhbmd1YWdlIG1vZGVsIHRvIHVzZS5cbiAgICovXG4gIG1vZGVsOiBMYW5ndWFnZU1vZGVsO1xuXG4gIC8qKlxuVGhlIHRvb2xzIHRoYXQgdGhlIG1vZGVsIGNhbiBjYWxsLiBUaGUgbW9kZWwgbmVlZHMgdG8gc3VwcG9ydCBjYWxsaW5nIHRvb2xzLlxuKi9cbiAgdG9vbHM/OiBUT09MUztcblxuICAvKipcblRoZSB0b29sIGNob2ljZSBzdHJhdGVneS4gRGVmYXVsdDogJ2F1dG8nLlxuICAgKi9cbiAgdG9vbENob2ljZT86IFRvb2xDaG9pY2U8Tm9JbmZlcjxUT09MUz4+O1xuXG4gIC8qKlxuQ29uZGl0aW9uIGZvciBzdG9wcGluZyB0aGUgZ2VuZXJhdGlvbiB3aGVuIHRoZXJlIGFyZSB0b29sIHJlc3VsdHMgaW4gdGhlIGxhc3Qgc3RlcC5cbldoZW4gdGhlIGNvbmRpdGlvbiBpcyBhbiBhcnJheSwgYW55IG9mIHRoZSBjb25kaXRpb25zIGNhbiBiZSBtZXQgdG8gc3RvcCB0aGUgZ2VuZXJhdGlvbi5cblxuQGRlZmF1bHQgc3RlcENvdW50SXMoMSlcbiAgICovXG4gIHN0b3BXaGVuPzpcbiAgICB8IFN0b3BDb25kaXRpb248Tm9JbmZlcjxUT09MUz4+XG4gICAgfCBBcnJheTxTdG9wQ29uZGl0aW9uPE5vSW5mZXI8VE9PTFM+Pj47XG5cbiAgLyoqXG5PcHRpb25hbCB0ZWxlbWV0cnkgY29uZmlndXJhdGlvbiAoZXhwZXJpbWVudGFsKS5cbiAgICovXG4gIGV4cGVyaW1lbnRhbF90ZWxlbWV0cnk/OiBUZWxlbWV0cnlTZXR0aW5ncztcblxuICAvKipcbkxpbWl0cyB0aGUgdG9vbHMgdGhhdCBhcmUgYXZhaWxhYmxlIGZvciB0aGUgbW9kZWwgdG8gY2FsbCB3aXRob3V0XG5jaGFuZ2luZyB0aGUgdG9vbCBjYWxsIGFuZCByZXN1bHQgdHlwZXMgaW4gdGhlIHJlc3VsdC5cbiAgICovXG4gIGFjdGl2ZVRvb2xzPzogQXJyYXk8a2V5b2YgTm9JbmZlcjxUT09MUz4+O1xuXG4gIC8qKlxuT3B0aW9uYWwgc3BlY2lmaWNhdGlvbiBmb3IgcGFyc2luZyBzdHJ1Y3R1cmVkIG91dHB1dHMgZnJvbSB0aGUgTExNIHJlc3BvbnNlLlxuICAgKi9cbiAgZXhwZXJpbWVudGFsX291dHB1dD86IE91dHB1dDxPVVRQVVQsIE9VVFBVVF9QQVJUSUFMPjtcblxuICAvKipcbiAgICogQGRlcHJlY2F0ZWQgVXNlIGBwcmVwYXJlU3RlcGAgaW5zdGVhZC5cbiAgICovXG4gIGV4cGVyaW1lbnRhbF9wcmVwYXJlU3RlcD86IFByZXBhcmVTdGVwRnVuY3Rpb248Tm9JbmZlcjxUT09MUz4+O1xuXG4gIC8qKlxuT3B0aW9uYWwgZnVuY3Rpb24gdGhhdCB5b3UgY2FuIHVzZSB0byBwcm92aWRlIGRpZmZlcmVudCBzZXR0aW5ncyBmb3IgYSBzdGVwLlxuICAqL1xuICBwcmVwYXJlU3RlcD86IFByZXBhcmVTdGVwRnVuY3Rpb248Tm9JbmZlcjxUT09MUz4+O1xuXG4gIC8qKlxuQSBmdW5jdGlvbiB0aGF0IGF0dGVtcHRzIHRvIHJlcGFpciBhIHRvb2wgY2FsbCB0aGF0IGZhaWxlZCB0byBwYXJzZS5cbiAgICovXG4gIGV4cGVyaW1lbnRhbF9yZXBhaXJUb29sQ2FsbD86IFRvb2xDYWxsUmVwYWlyRnVuY3Rpb248Tm9JbmZlcjxUT09MUz4+O1xuXG4gIC8qKlxuICBDYWxsYmFjayB0aGF0IGlzIGNhbGxlZCB3aGVuIGVhY2ggc3RlcCAoTExNIGNhbGwpIGlzIGZpbmlzaGVkLCBpbmNsdWRpbmcgaW50ZXJtZWRpYXRlIHN0ZXBzLlxuICAqL1xuICBvblN0ZXBGaW5pc2g/OiBHZW5lcmF0ZVRleHRPblN0ZXBGaW5pc2hDYWxsYmFjazxOb0luZmVyPFRPT0xTPj47XG5cbiAgLyoqXG4gICAqIENvbnRleHQgdGhhdCBpcyBwYXNzZWQgaW50byB0b29sIGNhbGxzLlxuICAgKlxuICAgKiBFeHBlcmltZW50YWwgKGNhbiBicmVhayBpbiBwYXRjaCByZWxlYXNlcykuXG4gICAqXG4gICAqIEBkZWZhdWx0IHVuZGVmaW5lZFxuICAgKi9cbiAgZXhwZXJpbWVudGFsX2NvbnRleHQ/OiB1bmtub3duO1xuXG4gIC8qKlxuICAgKiBJbnRlcm5hbC4gRm9yIHRlc3QgdXNlIG9ubHkuIE1heSBjaGFuZ2Ugd2l0aG91dCBub3RpY2UuXG4gICAqL1xuICBfaW50ZXJuYWw/OiB7XG4gICAgZ2VuZXJhdGVJZD86IElkR2VuZXJhdG9yO1xuICAgIGN1cnJlbnREYXRlPzogKCkgPT4gRGF0ZTtcbiAgfTtcbn07XG5cbmV4cG9ydCBjbGFzcyBBZ2VudDxcbiAgVE9PTFMgZXh0ZW5kcyBUb29sU2V0LFxuICBPVVRQVVQgPSBuZXZlcixcbiAgT1VUUFVUX1BBUlRJQUwgPSBuZXZlcixcbj4ge1xuICBwcml2YXRlIHJlYWRvbmx5IHNldHRpbmdzOiBBZ2VudFNldHRpbmdzPFRPT0xTLCBPVVRQVVQsIE9VVFBVVF9QQVJUSUFMPjtcblxuICBjb25zdHJ1Y3RvcihzZXR0aW5nczogQWdlbnRTZXR0aW5nczxUT09MUywgT1VUUFVULCBPVVRQVVRfUEFSVElBTD4pIHtcbiAgICB0aGlzLnNldHRpbmdzID0gc2V0dGluZ3M7XG4gIH1cblxuICBnZXQgdG9vbHMoKTogVE9PTFMge1xuICAgIHJldHVybiB0aGlzLnNldHRpbmdzLnRvb2xzIGFzIFRPT0xTO1xuICB9XG5cbiAgYXN5bmMgZ2VuZXJhdGUoXG4gICAgb3B0aW9uczogUHJvbXB0ICYge1xuICAgICAgLyoqXG5BZGRpdGlvbmFsIHByb3ZpZGVyLXNwZWNpZmljIG1ldGFkYXRhLiBUaGV5IGFyZSBwYXNzZWQgdGhyb3VnaFxuZnJvbSB0aGUgcHJvdmlkZXIgdG8gdGhlIEFJIFNESyBhbmQgZW5hYmxlIHByb3ZpZGVyLXNwZWNpZmljXG5yZXN1bHRzIHRoYXQgY2FuIGJlIGZ1bGx5IGVuY2Fwc3VsYXRlZCBpbiB0aGUgcHJvdmlkZXIuXG4gICAqL1xuICAgICAgcHJvdmlkZXJNZXRhZGF0YT86IFByb3ZpZGVyTWV0YWRhdGE7XG4gICAgICAvKipcbkFkZGl0aW9uYWwgcHJvdmlkZXItc3BlY2lmaWMgbWV0YWRhdGEuIFRoZXkgYXJlIHBhc3NlZCB0aHJvdWdoXG50byB0aGUgcHJvdmlkZXIgZnJvbSB0aGUgQUkgU0RLIGFuZCBlbmFibGUgcHJvdmlkZXItc3BlY2lmaWNcbmZ1bmN0aW9uYWxpdHkgdGhhdCBjYW4gYmUgZnVsbHkgZW5jYXBzdWxhdGVkIGluIHRoZSBwcm92aWRlci5cbiAgICAgICAgICovXG4gICAgICBwcm92aWRlck9wdGlvbnM/OiBQcm92aWRlck9wdGlvbnM7XG4gICAgfSxcbiAgKTogUHJvbWlzZTxHZW5lcmF0ZVRleHRSZXN1bHQ8VE9PTFMsIE9VVFBVVD4+IHtcbiAgICByZXR1cm4gZ2VuZXJhdGVUZXh0KHsgLi4udGhpcy5zZXR0aW5ncywgLi4ub3B0aW9ucyB9KTtcbiAgfVxuXG4gIHN0cmVhbShcbiAgICBvcHRpb25zOiBQcm9tcHQgJiB7XG4gICAgICAvKipcbkFkZGl0aW9uYWwgcHJvdmlkZXItc3BlY2lmaWMgbWV0YWRhdGEuIFRoZXkgYXJlIHBhc3NlZCB0aHJvdWdoXG5mcm9tIHRoZSBwcm92aWRlciB0byB0aGUgQUkgU0RLIGFuZCBlbmFibGUgcHJvdmlkZXItc3BlY2lmaWNcbnJlc3VsdHMgdGhhdCBjYW4gYmUgZnVsbHkgZW5jYXBzdWxhdGVkIGluIHRoZSBwcm92aWRlci5cbiAgICovXG4gICAgICBwcm92aWRlck1ldGFkYXRhPzogUHJvdmlkZXJNZXRhZGF0YTtcbiAgICAgIC8qKlxuQWRkaXRpb25hbCBwcm92aWRlci1zcGVjaWZpYyBtZXRhZGF0YS4gVGhleSBhcmUgcGFzc2VkIHRocm91Z2hcbnRvIHRoZSBwcm92aWRlciBmcm9tIHRoZSBBSSBTREsgYW5kIGVuYWJsZSBwcm92aWRlci1zcGVjaWZpY1xuZnVuY3Rpb25hbGl0eSB0aGF0IGNhbiBiZSBmdWxseSBlbmNhcHN1bGF0ZWQgaW4gdGhlIHByb3ZpZGVyLlxuICAgICAgICAgKi9cbiAgICAgIHByb3ZpZGVyT3B0aW9ucz86IFByb3ZpZGVyT3B0aW9ucztcbiAgICB9LFxuICApOiBTdHJlYW1UZXh0UmVzdWx0PFRPT0xTLCBPVVRQVVRfUEFSVElBTD4ge1xuICAgIHJldHVybiBzdHJlYW1UZXh0KHsgLi4udGhpcy5zZXR0aW5ncywgLi4ub3B0aW9ucyB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgcmVzcG9uc2Ugb2JqZWN0IHRoYXQgc3RyZWFtcyBVSSBtZXNzYWdlcyB0byB0aGUgY2xpZW50LlxuICAgKi9cbiAgcmVzcG9uZChvcHRpb25zOiB7XG4gICAgbWVzc2FnZXM6IFVJTWVzc2FnZTxuZXZlciwgbmV2ZXIsIEluZmVyVUlUb29sczxUT09MUz4+W107XG4gIH0pOiBSZXNwb25zZSB7XG4gICAgcmV0dXJuIHRoaXMuc3RyZWFtKHtcbiAgICAgIHByb21wdDogY29udmVydFRvTW9kZWxNZXNzYWdlcyhvcHRpb25zLm1lc3NhZ2VzKSxcbiAgICB9KS50b1VJTWVzc2FnZVN0cmVhbVJlc3BvbnNlPFxuICAgICAgVUlNZXNzYWdlPG5ldmVyLCBuZXZlciwgSW5mZXJVSVRvb2xzPFRPT0xTPj5cbiAgICA+KCk7XG4gIH1cbn1cblxudHlwZSBJbmZlckFnZW50VG9vbHM8QUdFTlQ+ID1cbiAgQUdFTlQgZXh0ZW5kcyBBZ2VudDxpbmZlciBUT09MUywgYW55LCBhbnk+ID8gVE9PTFMgOiBuZXZlcjtcblxuLyoqXG4gKiBJbmZlciB0aGUgVUkgbWVzc2FnZSB0eXBlIG9mIGFuIGFnZW50LlxuICovXG5leHBvcnQgdHlwZSBJbmZlckFnZW50VUlNZXNzYWdlPEFHRU5UPiA9IFVJTWVzc2FnZTxcbiAgbmV2ZXIsXG4gIG5ldmVyLFxuICBJbmZlclVJVG9vbHM8SW5mZXJBZ2VudFRvb2xzPEFHRU5UPj5cbj47XG4iLCAiaW1wb3J0IHsgUHJvdmlkZXJPcHRpb25zLCB3aXRoVXNlckFnZW50U3VmZml4IH0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyByZXNvbHZlRW1iZWRkaW5nTW9kZWwgfSBmcm9tICcuLi9tb2RlbC9yZXNvbHZlLW1vZGVsJztcbmltcG9ydCB7IGFzc2VtYmxlT3BlcmF0aW9uTmFtZSB9IGZyb20gJy4uL3RlbGVtZXRyeS9hc3NlbWJsZS1vcGVyYXRpb24tbmFtZSc7XG5pbXBvcnQgeyBnZXRCYXNlVGVsZW1ldHJ5QXR0cmlidXRlcyB9IGZyb20gJy4uL3RlbGVtZXRyeS9nZXQtYmFzZS10ZWxlbWV0cnktYXR0cmlidXRlcyc7XG5pbXBvcnQgeyBnZXRUcmFjZXIgfSBmcm9tICcuLi90ZWxlbWV0cnkvZ2V0LXRyYWNlcic7XG5pbXBvcnQgeyByZWNvcmRTcGFuIH0gZnJvbSAnLi4vdGVsZW1ldHJ5L3JlY29yZC1zcGFuJztcbmltcG9ydCB7IHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMgfSBmcm9tICcuLi90ZWxlbWV0cnkvc2VsZWN0LXRlbGVtZXRyeS1hdHRyaWJ1dGVzJztcbmltcG9ydCB7IFRlbGVtZXRyeVNldHRpbmdzIH0gZnJvbSAnLi4vdGVsZW1ldHJ5L3RlbGVtZXRyeS1zZXR0aW5ncyc7XG5pbXBvcnQgeyBFbWJlZGRpbmdNb2RlbCB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IHByZXBhcmVSZXRyaWVzIH0gZnJvbSAnLi4vdXRpbC9wcmVwYXJlLXJldHJpZXMnO1xuaW1wb3J0IHsgRW1iZWRSZXN1bHQgfSBmcm9tICcuL2VtYmVkLXJlc3VsdCc7XG5pbXBvcnQgeyBWRVJTSU9OIH0gZnJvbSAnLi4vdmVyc2lvbic7XG5cbi8qKlxuRW1iZWQgYSB2YWx1ZSB1c2luZyBhbiBlbWJlZGRpbmcgbW9kZWwuIFRoZSB0eXBlIG9mIHRoZSB2YWx1ZSBpcyBkZWZpbmVkIGJ5IHRoZSBlbWJlZGRpbmcgbW9kZWwuXG5cbkBwYXJhbSBtb2RlbCAtIFRoZSBlbWJlZGRpbmcgbW9kZWwgdG8gdXNlLlxuQHBhcmFtIHZhbHVlIC0gVGhlIHZhbHVlIHRoYXQgc2hvdWxkIGJlIGVtYmVkZGVkLlxuXG5AcGFyYW0gbWF4UmV0cmllcyAtIE1heGltdW0gbnVtYmVyIG9mIHJldHJpZXMuIFNldCB0byAwIHRvIGRpc2FibGUgcmV0cmllcy4gRGVmYXVsdDogMi5cbkBwYXJhbSBhYm9ydFNpZ25hbCAtIEFuIG9wdGlvbmFsIGFib3J0IHNpZ25hbCB0aGF0IGNhbiBiZSB1c2VkIHRvIGNhbmNlbCB0aGUgY2FsbC5cbkBwYXJhbSBoZWFkZXJzIC0gQWRkaXRpb25hbCBIVFRQIGhlYWRlcnMgdG8gYmUgc2VudCB3aXRoIHRoZSByZXF1ZXN0LiBPbmx5IGFwcGxpY2FibGUgZm9yIEhUVFAtYmFzZWQgcHJvdmlkZXJzLlxuXG5AcmV0dXJucyBBIHJlc3VsdCBvYmplY3QgdGhhdCBjb250YWlucyB0aGUgZW1iZWRkaW5nLCB0aGUgdmFsdWUsIGFuZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZW1iZWQ8VkFMVUUgPSBzdHJpbmc+KHtcbiAgbW9kZWw6IG1vZGVsQXJnLFxuICB2YWx1ZSxcbiAgcHJvdmlkZXJPcHRpb25zLFxuICBtYXhSZXRyaWVzOiBtYXhSZXRyaWVzQXJnLFxuICBhYm9ydFNpZ25hbCxcbiAgaGVhZGVycyxcbiAgZXhwZXJpbWVudGFsX3RlbGVtZXRyeTogdGVsZW1ldHJ5LFxufToge1xuICAvKipcblRoZSBlbWJlZGRpbmcgbW9kZWwgdG8gdXNlLlxuICAgICAqL1xuICBtb2RlbDogRW1iZWRkaW5nTW9kZWw8VkFMVUU+O1xuXG4gIC8qKlxuVGhlIHZhbHVlIHRoYXQgc2hvdWxkIGJlIGVtYmVkZGVkLlxuICAgKi9cbiAgdmFsdWU6IFZBTFVFO1xuXG4gIC8qKlxuTWF4aW11bSBudW1iZXIgb2YgcmV0cmllcyBwZXIgZW1iZWRkaW5nIG1vZGVsIGNhbGwuIFNldCB0byAwIHRvIGRpc2FibGUgcmV0cmllcy5cblxuQGRlZmF1bHQgMlxuICAgKi9cbiAgbWF4UmV0cmllcz86IG51bWJlcjtcblxuICAvKipcbkFib3J0IHNpZ25hbC5cbiAqL1xuICBhYm9ydFNpZ25hbD86IEFib3J0U2lnbmFsO1xuXG4gIC8qKlxuQWRkaXRpb25hbCBoZWFkZXJzIHRvIGluY2x1ZGUgaW4gdGhlIHJlcXVlc3QuXG5Pbmx5IGFwcGxpY2FibGUgZm9yIEhUVFAtYmFzZWQgcHJvdmlkZXJzLlxuICovXG4gIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuXG4gIC8qKlxuICBBZGRpdGlvbmFsIHByb3ZpZGVyLXNwZWNpZmljIG9wdGlvbnMuIFRoZXkgYXJlIHBhc3NlZCB0aHJvdWdoXG4gIHRvIHRoZSBwcm92aWRlciBmcm9tIHRoZSBBSSBTREsgYW5kIGVuYWJsZSBwcm92aWRlci1zcGVjaWZpY1xuICBmdW5jdGlvbmFsaXR5IHRoYXQgY2FuIGJlIGZ1bGx5IGVuY2Fwc3VsYXRlZCBpbiB0aGUgcHJvdmlkZXIuXG4gICovXG4gIHByb3ZpZGVyT3B0aW9ucz86IFByb3ZpZGVyT3B0aW9ucztcblxuICAvKipcbiAgICogT3B0aW9uYWwgdGVsZW1ldHJ5IGNvbmZpZ3VyYXRpb24gKGV4cGVyaW1lbnRhbCkuXG4gICAqL1xuICBleHBlcmltZW50YWxfdGVsZW1ldHJ5PzogVGVsZW1ldHJ5U2V0dGluZ3M7XG59KTogUHJvbWlzZTxFbWJlZFJlc3VsdDxWQUxVRT4+IHtcbiAgY29uc3QgbW9kZWwgPSByZXNvbHZlRW1iZWRkaW5nTW9kZWw8VkFMVUU+KG1vZGVsQXJnKTtcblxuICBjb25zdCB7IG1heFJldHJpZXMsIHJldHJ5IH0gPSBwcmVwYXJlUmV0cmllcyh7XG4gICAgbWF4UmV0cmllczogbWF4UmV0cmllc0FyZyxcbiAgICBhYm9ydFNpZ25hbCxcbiAgfSk7XG5cbiAgY29uc3QgaGVhZGVyc1dpdGhVc2VyQWdlbnQgPSB3aXRoVXNlckFnZW50U3VmZml4KFxuICAgIGhlYWRlcnMgPz8ge30sXG4gICAgYGFpLyR7VkVSU0lPTn1gLFxuICApO1xuXG4gIGNvbnN0IGJhc2VUZWxlbWV0cnlBdHRyaWJ1dGVzID0gZ2V0QmFzZVRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgIG1vZGVsOiBtb2RlbCxcbiAgICB0ZWxlbWV0cnksXG4gICAgaGVhZGVyczogaGVhZGVyc1dpdGhVc2VyQWdlbnQsXG4gICAgc2V0dGluZ3M6IHsgbWF4UmV0cmllcyB9LFxuICB9KTtcblxuICBjb25zdCB0cmFjZXIgPSBnZXRUcmFjZXIodGVsZW1ldHJ5KTtcblxuICByZXR1cm4gcmVjb3JkU3Bhbih7XG4gICAgbmFtZTogJ2FpLmVtYmVkJyxcbiAgICBhdHRyaWJ1dGVzOiBzZWxlY3RUZWxlbWV0cnlBdHRyaWJ1dGVzKHtcbiAgICAgIHRlbGVtZXRyeSxcbiAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgLi4uYXNzZW1ibGVPcGVyYXRpb25OYW1lKHsgb3BlcmF0aW9uSWQ6ICdhaS5lbWJlZCcsIHRlbGVtZXRyeSB9KSxcbiAgICAgICAgLi4uYmFzZVRlbGVtZXRyeUF0dHJpYnV0ZXMsXG4gICAgICAgICdhaS52YWx1ZSc6IHsgaW5wdXQ6ICgpID0+IEpTT04uc3RyaW5naWZ5KHZhbHVlKSB9LFxuICAgICAgfSxcbiAgICB9KSxcbiAgICB0cmFjZXIsXG4gICAgZm46IGFzeW5jIHNwYW4gPT4ge1xuICAgICAgY29uc3QgeyBlbWJlZGRpbmcsIHVzYWdlLCByZXNwb25zZSwgcHJvdmlkZXJNZXRhZGF0YSB9ID0gYXdhaXQgcmV0cnkoKCkgPT5cbiAgICAgICAgLy8gbmVzdGVkIHNwYW5zIHRvIGFsaWduIHdpdGggdGhlIGVtYmVkTWFueSB0ZWxlbWV0cnkgZGF0YTpcbiAgICAgICAgcmVjb3JkU3Bhbih7XG4gICAgICAgICAgbmFtZTogJ2FpLmVtYmVkLmRvRW1iZWQnLFxuICAgICAgICAgIGF0dHJpYnV0ZXM6IHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAgICAgICAuLi5hc3NlbWJsZU9wZXJhdGlvbk5hbWUoe1xuICAgICAgICAgICAgICAgIG9wZXJhdGlvbklkOiAnYWkuZW1iZWQuZG9FbWJlZCcsXG4gICAgICAgICAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgLi4uYmFzZVRlbGVtZXRyeUF0dHJpYnV0ZXMsXG4gICAgICAgICAgICAgIC8vIHNwZWNpZmljIHNldHRpbmdzIHRoYXQgb25seSBtYWtlIHNlbnNlIG9uIHRoZSBvdXRlciBsZXZlbDpcbiAgICAgICAgICAgICAgJ2FpLnZhbHVlcyc6IHsgaW5wdXQ6ICgpID0+IFtKU09OLnN0cmluZ2lmeSh2YWx1ZSldIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIHRyYWNlcixcbiAgICAgICAgICBmbjogYXN5bmMgZG9FbWJlZFNwYW4gPT4ge1xuICAgICAgICAgICAgY29uc3QgbW9kZWxSZXNwb25zZSA9IGF3YWl0IG1vZGVsLmRvRW1iZWQoe1xuICAgICAgICAgICAgICB2YWx1ZXM6IFt2YWx1ZV0sXG4gICAgICAgICAgICAgIGFib3J0U2lnbmFsLFxuICAgICAgICAgICAgICBoZWFkZXJzOiBoZWFkZXJzV2l0aFVzZXJBZ2VudCxcbiAgICAgICAgICAgICAgcHJvdmlkZXJPcHRpb25zLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGNvbnN0IGVtYmVkZGluZyA9IG1vZGVsUmVzcG9uc2UuZW1iZWRkaW5nc1swXTtcbiAgICAgICAgICAgIGNvbnN0IHVzYWdlID0gbW9kZWxSZXNwb25zZS51c2FnZSA/PyB7IHRva2VuczogTmFOIH07XG5cbiAgICAgICAgICAgIGRvRW1iZWRTcGFuLnNldEF0dHJpYnV0ZXMoXG4gICAgICAgICAgICAgIHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgICAgIHRlbGVtZXRyeSxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgICAgICAgICAnYWkuZW1iZWRkaW5ncyc6IHtcbiAgICAgICAgICAgICAgICAgICAgb3V0cHV0OiAoKSA9PlxuICAgICAgICAgICAgICAgICAgICAgIG1vZGVsUmVzcG9uc2UuZW1iZWRkaW5ncy5tYXAoZW1iZWRkaW5nID0+XG4gICAgICAgICAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeShlbWJlZGRpbmcpLFxuICAgICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgJ2FpLnVzYWdlLnRva2Vucyc6IHVzYWdlLnRva2VucyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIGVtYmVkZGluZyxcbiAgICAgICAgICAgICAgdXNhZ2UsXG4gICAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IG1vZGVsUmVzcG9uc2UucHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgICAgICAgcmVzcG9uc2U6IG1vZGVsUmVzcG9uc2UucmVzcG9uc2UsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGVzKFxuICAgICAgICBzZWxlY3RUZWxlbWV0cnlBdHRyaWJ1dGVzKHtcbiAgICAgICAgICB0ZWxlbWV0cnksXG4gICAgICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAgICAgJ2FpLmVtYmVkZGluZyc6IHsgb3V0cHV0OiAoKSA9PiBKU09OLnN0cmluZ2lmeShlbWJlZGRpbmcpIH0sXG4gICAgICAgICAgICAnYWkudXNhZ2UudG9rZW5zJzogdXNhZ2UudG9rZW5zLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgcmV0dXJuIG5ldyBEZWZhdWx0RW1iZWRSZXN1bHQoe1xuICAgICAgICB2YWx1ZSxcbiAgICAgICAgZW1iZWRkaW5nLFxuICAgICAgICB1c2FnZSxcbiAgICAgICAgcHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgcmVzcG9uc2UsXG4gICAgICB9KTtcbiAgICB9LFxuICB9KTtcbn1cblxuY2xhc3MgRGVmYXVsdEVtYmVkUmVzdWx0PFZBTFVFPiBpbXBsZW1lbnRzIEVtYmVkUmVzdWx0PFZBTFVFPiB7XG4gIHJlYWRvbmx5IHZhbHVlOiBFbWJlZFJlc3VsdDxWQUxVRT5bJ3ZhbHVlJ107XG4gIHJlYWRvbmx5IGVtYmVkZGluZzogRW1iZWRSZXN1bHQ8VkFMVUU+WydlbWJlZGRpbmcnXTtcbiAgcmVhZG9ubHkgdXNhZ2U6IEVtYmVkUmVzdWx0PFZBTFVFPlsndXNhZ2UnXTtcbiAgcmVhZG9ubHkgcHJvdmlkZXJNZXRhZGF0YTogRW1iZWRSZXN1bHQ8VkFMVUU+Wydwcm92aWRlck1ldGFkYXRhJ107XG4gIHJlYWRvbmx5IHJlc3BvbnNlOiBFbWJlZFJlc3VsdDxWQUxVRT5bJ3Jlc3BvbnNlJ107XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczoge1xuICAgIHZhbHVlOiBFbWJlZFJlc3VsdDxWQUxVRT5bJ3ZhbHVlJ107XG4gICAgZW1iZWRkaW5nOiBFbWJlZFJlc3VsdDxWQUxVRT5bJ2VtYmVkZGluZyddO1xuICAgIHVzYWdlOiBFbWJlZFJlc3VsdDxWQUxVRT5bJ3VzYWdlJ107XG4gICAgcHJvdmlkZXJNZXRhZGF0YT86IEVtYmVkUmVzdWx0PFZBTFVFPlsncHJvdmlkZXJNZXRhZGF0YSddO1xuICAgIHJlc3BvbnNlPzogRW1iZWRSZXN1bHQ8VkFMVUU+WydyZXNwb25zZSddO1xuICB9KSB7XG4gICAgdGhpcy52YWx1ZSA9IG9wdGlvbnMudmFsdWU7XG4gICAgdGhpcy5lbWJlZGRpbmcgPSBvcHRpb25zLmVtYmVkZGluZztcbiAgICB0aGlzLnVzYWdlID0gb3B0aW9ucy51c2FnZTtcbiAgICB0aGlzLnByb3ZpZGVyTWV0YWRhdGEgPSBvcHRpb25zLnByb3ZpZGVyTWV0YWRhdGE7XG4gICAgdGhpcy5yZXNwb25zZSA9IG9wdGlvbnMucmVzcG9uc2U7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBQcm92aWRlck9wdGlvbnMsIHdpdGhVc2VyQWdlbnRTdWZmaXggfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyLXV0aWxzJztcbmltcG9ydCB7IHByZXBhcmVSZXRyaWVzIH0gZnJvbSAnLi4vdXRpbC9wcmVwYXJlLXJldHJpZXMnO1xuaW1wb3J0IHsgc3BsaXRBcnJheSB9IGZyb20gJy4uL3V0aWwvc3BsaXQtYXJyYXknO1xuaW1wb3J0IHsgVW5zdXBwb3J0ZWRNb2RlbFZlcnNpb25FcnJvciB9IGZyb20gJy4uL2Vycm9yL3Vuc3VwcG9ydGVkLW1vZGVsLXZlcnNpb24tZXJyb3InO1xuaW1wb3J0IHsgYXNzZW1ibGVPcGVyYXRpb25OYW1lIH0gZnJvbSAnLi4vdGVsZW1ldHJ5L2Fzc2VtYmxlLW9wZXJhdGlvbi1uYW1lJztcbmltcG9ydCB7IGdldEJhc2VUZWxlbWV0cnlBdHRyaWJ1dGVzIH0gZnJvbSAnLi4vdGVsZW1ldHJ5L2dldC1iYXNlLXRlbGVtZXRyeS1hdHRyaWJ1dGVzJztcbmltcG9ydCB7IGdldFRyYWNlciB9IGZyb20gJy4uL3RlbGVtZXRyeS9nZXQtdHJhY2VyJztcbmltcG9ydCB7IHJlY29yZFNwYW4gfSBmcm9tICcuLi90ZWxlbWV0cnkvcmVjb3JkLXNwYW4nO1xuaW1wb3J0IHsgc2VsZWN0VGVsZW1ldHJ5QXR0cmlidXRlcyB9IGZyb20gJy4uL3RlbGVtZXRyeS9zZWxlY3QtdGVsZW1ldHJ5LWF0dHJpYnV0ZXMnO1xuaW1wb3J0IHsgVGVsZW1ldHJ5U2V0dGluZ3MgfSBmcm9tICcuLi90ZWxlbWV0cnkvdGVsZW1ldHJ5LXNldHRpbmdzJztcbmltcG9ydCB7IEVtYmVkZGluZywgRW1iZWRkaW5nTW9kZWwsIFByb3ZpZGVyTWV0YWRhdGEgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgeyByZXNvbHZlRW1iZWRkaW5nTW9kZWwgfSBmcm9tICcuLi9tb2RlbC9yZXNvbHZlLW1vZGVsJztcbmltcG9ydCB7IEVtYmVkTWFueVJlc3VsdCB9IGZyb20gJy4vZW1iZWQtbWFueS1yZXN1bHQnO1xuaW1wb3J0IHsgVkVSU0lPTiB9IGZyb20gJy4uL3ZlcnNpb24nO1xuXG4vKipcbkVtYmVkIHNldmVyYWwgdmFsdWVzIHVzaW5nIGFuIGVtYmVkZGluZyBtb2RlbC4gVGhlIHR5cGUgb2YgdGhlIHZhbHVlIGlzIGRlZmluZWRcbmJ5IHRoZSBlbWJlZGRpbmcgbW9kZWwuXG5cbmBlbWJlZE1hbnlgIGF1dG9tYXRpY2FsbHkgc3BsaXRzIGxhcmdlIHJlcXVlc3RzIGludG8gc21hbGxlciBjaHVua3MgaWYgdGhlIG1vZGVsXG5oYXMgYSBsaW1pdCBvbiBob3cgbWFueSBlbWJlZGRpbmdzIGNhbiBiZSBnZW5lcmF0ZWQgaW4gYSBzaW5nbGUgY2FsbC5cblxuQHBhcmFtIG1vZGVsIC0gVGhlIGVtYmVkZGluZyBtb2RlbCB0byB1c2UuXG5AcGFyYW0gdmFsdWVzIC0gVGhlIHZhbHVlcyB0aGF0IHNob3VsZCBiZSBlbWJlZGRlZC5cblxuQHBhcmFtIG1heFJldHJpZXMgLSBNYXhpbXVtIG51bWJlciBvZiByZXRyaWVzLiBTZXQgdG8gMCB0byBkaXNhYmxlIHJldHJpZXMuIERlZmF1bHQ6IDIuXG5AcGFyYW0gYWJvcnRTaWduYWwgLSBBbiBvcHRpb25hbCBhYm9ydCBzaWduYWwgdGhhdCBjYW4gYmUgdXNlZCB0byBjYW5jZWwgdGhlIGNhbGwuXG5AcGFyYW0gaGVhZGVycyAtIEFkZGl0aW9uYWwgSFRUUCBoZWFkZXJzIHRvIGJlIHNlbnQgd2l0aCB0aGUgcmVxdWVzdC4gT25seSBhcHBsaWNhYmxlIGZvciBIVFRQLWJhc2VkIHByb3ZpZGVycy5cblxuQHJldHVybnMgQSByZXN1bHQgb2JqZWN0IHRoYXQgY29udGFpbnMgdGhlIGVtYmVkZGluZ3MsIHRoZSB2YWx1ZSwgYW5kIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24uXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBlbWJlZE1hbnk8VkFMVUUgPSBzdHJpbmc+KHtcbiAgbW9kZWw6IG1vZGVsQXJnLFxuICB2YWx1ZXMsXG4gIG1heFBhcmFsbGVsQ2FsbHMgPSBJbmZpbml0eSxcbiAgbWF4UmV0cmllczogbWF4UmV0cmllc0FyZyxcbiAgYWJvcnRTaWduYWwsXG4gIGhlYWRlcnMsXG4gIHByb3ZpZGVyT3B0aW9ucyxcbiAgZXhwZXJpbWVudGFsX3RlbGVtZXRyeTogdGVsZW1ldHJ5LFxufToge1xuICAvKipcblRoZSBlbWJlZGRpbmcgbW9kZWwgdG8gdXNlLlxuICAgICAqL1xuICBtb2RlbDogRW1iZWRkaW5nTW9kZWw8VkFMVUU+O1xuXG4gIC8qKlxuVGhlIHZhbHVlcyB0aGF0IHNob3VsZCBiZSBlbWJlZGRlZC5cbiAgICovXG4gIHZhbHVlczogQXJyYXk8VkFMVUU+O1xuXG4gIC8qKlxuTWF4aW11bSBudW1iZXIgb2YgcmV0cmllcyBwZXIgZW1iZWRkaW5nIG1vZGVsIGNhbGwuIFNldCB0byAwIHRvIGRpc2FibGUgcmV0cmllcy5cblxuQGRlZmF1bHQgMlxuICAgKi9cbiAgbWF4UmV0cmllcz86IG51bWJlcjtcblxuICAvKipcbkFib3J0IHNpZ25hbC5cbiAqL1xuICBhYm9ydFNpZ25hbD86IEFib3J0U2lnbmFsO1xuXG4gIC8qKlxuQWRkaXRpb25hbCBoZWFkZXJzIHRvIGluY2x1ZGUgaW4gdGhlIHJlcXVlc3QuXG5Pbmx5IGFwcGxpY2FibGUgZm9yIEhUVFAtYmFzZWQgcHJvdmlkZXJzLlxuICovXG4gIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuXG4gIC8qKlxuICAgKiBPcHRpb25hbCB0ZWxlbWV0cnkgY29uZmlndXJhdGlvbiAoZXhwZXJpbWVudGFsKS5cbiAgICovXG4gIGV4cGVyaW1lbnRhbF90ZWxlbWV0cnk/OiBUZWxlbWV0cnlTZXR0aW5ncztcblxuICAvKipcbiAgQWRkaXRpb25hbCBwcm92aWRlci1zcGVjaWZpYyBvcHRpb25zLiBUaGV5IGFyZSBwYXNzZWQgdGhyb3VnaFxuICB0byB0aGUgcHJvdmlkZXIgZnJvbSB0aGUgQUkgU0RLIGFuZCBlbmFibGUgcHJvdmlkZXItc3BlY2lmaWNcbiAgZnVuY3Rpb25hbGl0eSB0aGF0IGNhbiBiZSBmdWxseSBlbmNhcHN1bGF0ZWQgaW4gdGhlIHByb3ZpZGVyLlxuICAqL1xuICBwcm92aWRlck9wdGlvbnM/OiBQcm92aWRlck9wdGlvbnM7XG5cbiAgLyoqXG4gICAqIE1heGltdW0gbnVtYmVyIG9mIGNvbmN1cnJlbnQgcmVxdWVzdHMuXG4gICAqXG4gICAqIEBkZWZhdWx0IEluZmluaXR5XG4gICAqL1xuICBtYXhQYXJhbGxlbENhbGxzPzogbnVtYmVyO1xufSk6IFByb21pc2U8RW1iZWRNYW55UmVzdWx0PFZBTFVFPj4ge1xuICBjb25zdCBtb2RlbCA9IHJlc29sdmVFbWJlZGRpbmdNb2RlbDxWQUxVRT4obW9kZWxBcmcpO1xuXG4gIGNvbnN0IHsgbWF4UmV0cmllcywgcmV0cnkgfSA9IHByZXBhcmVSZXRyaWVzKHtcbiAgICBtYXhSZXRyaWVzOiBtYXhSZXRyaWVzQXJnLFxuICAgIGFib3J0U2lnbmFsLFxuICB9KTtcblxuICBjb25zdCBoZWFkZXJzV2l0aFVzZXJBZ2VudCA9IHdpdGhVc2VyQWdlbnRTdWZmaXgoXG4gICAgaGVhZGVycyA/PyB7fSxcbiAgICBgYWkvJHtWRVJTSU9OfWAsXG4gICk7XG5cbiAgY29uc3QgYmFzZVRlbGVtZXRyeUF0dHJpYnV0ZXMgPSBnZXRCYXNlVGVsZW1ldHJ5QXR0cmlidXRlcyh7XG4gICAgbW9kZWwsXG4gICAgdGVsZW1ldHJ5LFxuICAgIGhlYWRlcnM6IGhlYWRlcnNXaXRoVXNlckFnZW50LFxuICAgIHNldHRpbmdzOiB7IG1heFJldHJpZXMgfSxcbiAgfSk7XG5cbiAgY29uc3QgdHJhY2VyID0gZ2V0VHJhY2VyKHRlbGVtZXRyeSk7XG5cbiAgcmV0dXJuIHJlY29yZFNwYW4oe1xuICAgIG5hbWU6ICdhaS5lbWJlZE1hbnknLFxuICAgIGF0dHJpYnV0ZXM6IHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgdGVsZW1ldHJ5LFxuICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAuLi5hc3NlbWJsZU9wZXJhdGlvbk5hbWUoeyBvcGVyYXRpb25JZDogJ2FpLmVtYmVkTWFueScsIHRlbGVtZXRyeSB9KSxcbiAgICAgICAgLi4uYmFzZVRlbGVtZXRyeUF0dHJpYnV0ZXMsXG4gICAgICAgIC8vIHNwZWNpZmljIHNldHRpbmdzIHRoYXQgb25seSBtYWtlIHNlbnNlIG9uIHRoZSBvdXRlciBsZXZlbDpcbiAgICAgICAgJ2FpLnZhbHVlcyc6IHtcbiAgICAgICAgICBpbnB1dDogKCkgPT4gdmFsdWVzLm1hcCh2YWx1ZSA9PiBKU09OLnN0cmluZ2lmeSh2YWx1ZSkpLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9KSxcbiAgICB0cmFjZXIsXG4gICAgZm46IGFzeW5jIHNwYW4gPT4ge1xuICAgICAgY29uc3QgW21heEVtYmVkZGluZ3NQZXJDYWxsLCBzdXBwb3J0c1BhcmFsbGVsQ2FsbHNdID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICBtb2RlbC5tYXhFbWJlZGRpbmdzUGVyQ2FsbCxcbiAgICAgICAgbW9kZWwuc3VwcG9ydHNQYXJhbGxlbENhbGxzLFxuICAgICAgXSk7XG5cbiAgICAgIC8vIHRoZSBtb2RlbCBoYXMgbm90IHNwZWNpZmllZCBsaW1pdHMgb25cbiAgICAgIC8vIGhvdyBtYW55IGVtYmVkZGluZ3MgY2FuIGJlIGdlbmVyYXRlZCBpbiBhIHNpbmdsZSBjYWxsXG4gICAgICBpZiAobWF4RW1iZWRkaW5nc1BlckNhbGwgPT0gbnVsbCB8fCBtYXhFbWJlZGRpbmdzUGVyQ2FsbCA9PT0gSW5maW5pdHkpIHtcbiAgICAgICAgY29uc3QgeyBlbWJlZGRpbmdzLCB1c2FnZSwgcmVzcG9uc2UsIHByb3ZpZGVyTWV0YWRhdGEgfSA9IGF3YWl0IHJldHJ5KFxuICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgIC8vIG5lc3RlZCBzcGFucyB0byBhbGlnbiB3aXRoIHRoZSBlbWJlZE1hbnkgdGVsZW1ldHJ5IGRhdGE6XG4gICAgICAgICAgICByZXR1cm4gcmVjb3JkU3Bhbih7XG4gICAgICAgICAgICAgIG5hbWU6ICdhaS5lbWJlZE1hbnkuZG9FbWJlZCcsXG4gICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgICAgIHRlbGVtZXRyeSxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgICAgICAgICAuLi5hc3NlbWJsZU9wZXJhdGlvbk5hbWUoe1xuICAgICAgICAgICAgICAgICAgICBvcGVyYXRpb25JZDogJ2FpLmVtYmVkTWFueS5kb0VtYmVkJyxcbiAgICAgICAgICAgICAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAuLi5iYXNlVGVsZW1ldHJ5QXR0cmlidXRlcyxcbiAgICAgICAgICAgICAgICAgIC8vIHNwZWNpZmljIHNldHRpbmdzIHRoYXQgb25seSBtYWtlIHNlbnNlIG9uIHRoZSBvdXRlciBsZXZlbDpcbiAgICAgICAgICAgICAgICAgICdhaS52YWx1ZXMnOiB7XG4gICAgICAgICAgICAgICAgICAgIGlucHV0OiAoKSA9PiB2YWx1ZXMubWFwKHZhbHVlID0+IEpTT04uc3RyaW5naWZ5KHZhbHVlKSksXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICB0cmFjZXIsXG4gICAgICAgICAgICAgIGZuOiBhc3luYyBkb0VtYmVkU3BhbiA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgbW9kZWxSZXNwb25zZSA9IGF3YWl0IG1vZGVsLmRvRW1iZWQoe1xuICAgICAgICAgICAgICAgICAgdmFsdWVzLFxuICAgICAgICAgICAgICAgICAgYWJvcnRTaWduYWwsXG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiBoZWFkZXJzV2l0aFVzZXJBZ2VudCxcbiAgICAgICAgICAgICAgICAgIHByb3ZpZGVyT3B0aW9ucyxcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IGVtYmVkZGluZ3MgPSBtb2RlbFJlc3BvbnNlLmVtYmVkZGluZ3M7XG4gICAgICAgICAgICAgICAgY29uc3QgdXNhZ2UgPSBtb2RlbFJlc3BvbnNlLnVzYWdlID8/IHsgdG9rZW5zOiBOYU4gfTtcblxuICAgICAgICAgICAgICAgIGRvRW1iZWRTcGFuLnNldEF0dHJpYnV0ZXMoXG4gICAgICAgICAgICAgICAgICBzZWxlY3RUZWxlbWV0cnlBdHRyaWJ1dGVzKHtcbiAgICAgICAgICAgICAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgJ2FpLmVtYmVkZGluZ3MnOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQ6ICgpID0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGVtYmVkZGluZ3MubWFwKGVtYmVkZGluZyA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KGVtYmVkZGluZyksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAnYWkudXNhZ2UudG9rZW5zJzogdXNhZ2UudG9rZW5zLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICBlbWJlZGRpbmdzLFxuICAgICAgICAgICAgICAgICAgdXNhZ2UsXG4gICAgICAgICAgICAgICAgICBwcm92aWRlck1ldGFkYXRhOiBtb2RlbFJlc3BvbnNlLnByb3ZpZGVyTWV0YWRhdGEsXG4gICAgICAgICAgICAgICAgICByZXNwb25zZTogbW9kZWxSZXNwb25zZS5yZXNwb25zZSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcblxuICAgICAgICBzcGFuLnNldEF0dHJpYnV0ZXMoXG4gICAgICAgICAgc2VsZWN0VGVsZW1ldHJ5QXR0cmlidXRlcyh7XG4gICAgICAgICAgICB0ZWxlbWV0cnksXG4gICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgICAgICdhaS5lbWJlZGRpbmdzJzoge1xuICAgICAgICAgICAgICAgIG91dHB1dDogKCkgPT5cbiAgICAgICAgICAgICAgICAgIGVtYmVkZGluZ3MubWFwKGVtYmVkZGluZyA9PiBKU09OLnN0cmluZ2lmeShlbWJlZGRpbmcpKSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgJ2FpLnVzYWdlLnRva2Vucyc6IHVzYWdlLnRva2VucyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBEZWZhdWx0RW1iZWRNYW55UmVzdWx0KHtcbiAgICAgICAgICB2YWx1ZXMsXG4gICAgICAgICAgZW1iZWRkaW5ncyxcbiAgICAgICAgICB1c2FnZSxcbiAgICAgICAgICBwcm92aWRlck1ldGFkYXRhLFxuICAgICAgICAgIHJlc3BvbnNlczogW3Jlc3BvbnNlXSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIC8vIHNwbGl0IHRoZSB2YWx1ZXMgaW50byBjaHVua3MgdGhhdCBhcmUgc21hbGwgZW5vdWdoIGZvciB0aGUgbW9kZWw6XG4gICAgICBjb25zdCB2YWx1ZUNodW5rcyA9IHNwbGl0QXJyYXkodmFsdWVzLCBtYXhFbWJlZGRpbmdzUGVyQ2FsbCk7XG5cbiAgICAgIC8vIHNlcmlhbGx5IGVtYmVkIHRoZSBjaHVua3M6XG4gICAgICBjb25zdCBlbWJlZGRpbmdzOiBBcnJheTxFbWJlZGRpbmc+ID0gW107XG4gICAgICBjb25zdCByZXNwb25zZXM6IEFycmF5PFxuICAgICAgICB8IHtcbiAgICAgICAgICAgIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICAgICAgICAgICAgYm9keT86IHVua25vd247XG4gICAgICAgICAgfVxuICAgICAgICB8IHVuZGVmaW5lZFxuICAgICAgPiA9IFtdO1xuICAgICAgbGV0IHRva2VucyA9IDA7XG4gICAgICBsZXQgcHJvdmlkZXJNZXRhZGF0YTogUHJvdmlkZXJNZXRhZGF0YSB8IHVuZGVmaW5lZDtcblxuICAgICAgY29uc3QgcGFyYWxsZWxDaHVua3MgPSBzcGxpdEFycmF5KFxuICAgICAgICB2YWx1ZUNodW5rcyxcbiAgICAgICAgc3VwcG9ydHNQYXJhbGxlbENhbGxzID8gbWF4UGFyYWxsZWxDYWxscyA6IDEsXG4gICAgICApO1xuXG4gICAgICBmb3IgKGNvbnN0IHBhcmFsbGVsQ2h1bmsgb2YgcGFyYWxsZWxDaHVua3MpIHtcbiAgICAgICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICAgIHBhcmFsbGVsQ2h1bmsubWFwKGNodW5rID0+IHtcbiAgICAgICAgICAgIHJldHVybiByZXRyeSgoKSA9PiB7XG4gICAgICAgICAgICAgIC8vIG5lc3RlZCBzcGFucyB0byBhbGlnbiB3aXRoIHRoZSBlbWJlZE1hbnkgdGVsZW1ldHJ5IGRhdGE6XG4gICAgICAgICAgICAgIHJldHVybiByZWNvcmRTcGFuKHtcbiAgICAgICAgICAgICAgICBuYW1lOiAnYWkuZW1iZWRNYW55LmRvRW1iZWQnLFxuICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICAgICAgICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAgICAgICAgICAgICAuLi5hc3NlbWJsZU9wZXJhdGlvbk5hbWUoe1xuICAgICAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbklkOiAnYWkuZW1iZWRNYW55LmRvRW1iZWQnLFxuICAgICAgICAgICAgICAgICAgICAgIHRlbGVtZXRyeSxcbiAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAgIC4uLmJhc2VUZWxlbWV0cnlBdHRyaWJ1dGVzLFxuICAgICAgICAgICAgICAgICAgICAvLyBzcGVjaWZpYyBzZXR0aW5ncyB0aGF0IG9ubHkgbWFrZSBzZW5zZSBvbiB0aGUgb3V0ZXIgbGV2ZWw6XG4gICAgICAgICAgICAgICAgICAgICdhaS52YWx1ZXMnOiB7XG4gICAgICAgICAgICAgICAgICAgICAgaW5wdXQ6ICgpID0+IGNodW5rLm1hcCh2YWx1ZSA9PiBKU09OLnN0cmluZ2lmeSh2YWx1ZSkpLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICB0cmFjZXIsXG4gICAgICAgICAgICAgICAgZm46IGFzeW5jIGRvRW1iZWRTcGFuID0+IHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IG1vZGVsUmVzcG9uc2UgPSBhd2FpdCBtb2RlbC5kb0VtYmVkKHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWVzOiBjaHVuayxcbiAgICAgICAgICAgICAgICAgICAgYWJvcnRTaWduYWwsXG4gICAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IGhlYWRlcnNXaXRoVXNlckFnZW50LFxuICAgICAgICAgICAgICAgICAgICBwcm92aWRlck9wdGlvbnMsXG4gICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgY29uc3QgZW1iZWRkaW5ncyA9IG1vZGVsUmVzcG9uc2UuZW1iZWRkaW5ncztcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHVzYWdlID0gbW9kZWxSZXNwb25zZS51c2FnZSA/PyB7IHRva2VuczogTmFOIH07XG5cbiAgICAgICAgICAgICAgICAgIGRvRW1iZWRTcGFuLnNldEF0dHJpYnV0ZXMoXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgICAgICAgICAgIHRlbGVtZXRyeSxcbiAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAnYWkuZW1iZWRkaW5ncyc6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0OiAoKSA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVtYmVkZGluZ3MubWFwKGVtYmVkZGluZyA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkoZW1iZWRkaW5nKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICdhaS51c2FnZS50b2tlbnMnOiB1c2FnZS50b2tlbnMsXG4gICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBlbWJlZGRpbmdzLFxuICAgICAgICAgICAgICAgICAgICB1c2FnZSxcbiAgICAgICAgICAgICAgICAgICAgcHJvdmlkZXJNZXRhZGF0YTogbW9kZWxSZXNwb25zZS5wcm92aWRlck1ldGFkYXRhLFxuICAgICAgICAgICAgICAgICAgICByZXNwb25zZTogbW9kZWxSZXNwb25zZS5yZXNwb25zZSxcbiAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcblxuICAgICAgICBmb3IgKGNvbnN0IHJlc3VsdCBvZiByZXN1bHRzKSB7XG4gICAgICAgICAgZW1iZWRkaW5ncy5wdXNoKC4uLnJlc3VsdC5lbWJlZGRpbmdzKTtcbiAgICAgICAgICByZXNwb25zZXMucHVzaChyZXN1bHQucmVzcG9uc2UpO1xuICAgICAgICAgIHRva2VucyArPSByZXN1bHQudXNhZ2UudG9rZW5zO1xuICAgICAgICAgIGlmIChyZXN1bHQucHJvdmlkZXJNZXRhZGF0YSkge1xuICAgICAgICAgICAgaWYgKCFwcm92aWRlck1ldGFkYXRhKSB7XG4gICAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGEgPSB7IC4uLnJlc3VsdC5wcm92aWRlck1ldGFkYXRhIH07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBmb3IgKGNvbnN0IFtwcm92aWRlck5hbWUsIG1ldGFkYXRhXSBvZiBPYmplY3QuZW50cmllcyhcbiAgICAgICAgICAgICAgICByZXN1bHQucHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgICAgICAgKSkge1xuICAgICAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGFbcHJvdmlkZXJOYW1lXSA9IHtcbiAgICAgICAgICAgICAgICAgIC4uLihwcm92aWRlck1ldGFkYXRhW3Byb3ZpZGVyTmFtZV0gPz8ge30pLFxuICAgICAgICAgICAgICAgICAgLi4ubWV0YWRhdGEsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBzcGFuLnNldEF0dHJpYnV0ZXMoXG4gICAgICAgIHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgICAgIHRlbGVtZXRyeSxcbiAgICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgICAnYWkuZW1iZWRkaW5ncyc6IHtcbiAgICAgICAgICAgICAgb3V0cHV0OiAoKSA9PlxuICAgICAgICAgICAgICAgIGVtYmVkZGluZ3MubWFwKGVtYmVkZGluZyA9PiBKU09OLnN0cmluZ2lmeShlbWJlZGRpbmcpKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAnYWkudXNhZ2UudG9rZW5zJzogdG9rZW5zLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgcmV0dXJuIG5ldyBEZWZhdWx0RW1iZWRNYW55UmVzdWx0KHtcbiAgICAgICAgdmFsdWVzLFxuICAgICAgICBlbWJlZGRpbmdzLFxuICAgICAgICB1c2FnZTogeyB0b2tlbnMgfSxcbiAgICAgICAgcHJvdmlkZXJNZXRhZGF0YTogcHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgcmVzcG9uc2VzLFxuICAgICAgfSk7XG4gICAgfSxcbiAgfSk7XG59XG5cbmNsYXNzIERlZmF1bHRFbWJlZE1hbnlSZXN1bHQ8VkFMVUU+IGltcGxlbWVudHMgRW1iZWRNYW55UmVzdWx0PFZBTFVFPiB7XG4gIHJlYWRvbmx5IHZhbHVlczogRW1iZWRNYW55UmVzdWx0PFZBTFVFPlsndmFsdWVzJ107XG4gIHJlYWRvbmx5IGVtYmVkZGluZ3M6IEVtYmVkTWFueVJlc3VsdDxWQUxVRT5bJ2VtYmVkZGluZ3MnXTtcbiAgcmVhZG9ubHkgdXNhZ2U6IEVtYmVkTWFueVJlc3VsdDxWQUxVRT5bJ3VzYWdlJ107XG4gIHJlYWRvbmx5IHByb3ZpZGVyTWV0YWRhdGE6IEVtYmVkTWFueVJlc3VsdDxWQUxVRT5bJ3Byb3ZpZGVyTWV0YWRhdGEnXTtcbiAgcmVhZG9ubHkgcmVzcG9uc2VzOiBFbWJlZE1hbnlSZXN1bHQ8VkFMVUU+WydyZXNwb25zZXMnXTtcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiB7XG4gICAgdmFsdWVzOiBFbWJlZE1hbnlSZXN1bHQ8VkFMVUU+Wyd2YWx1ZXMnXTtcbiAgICBlbWJlZGRpbmdzOiBFbWJlZE1hbnlSZXN1bHQ8VkFMVUU+WydlbWJlZGRpbmdzJ107XG4gICAgdXNhZ2U6IEVtYmVkTWFueVJlc3VsdDxWQUxVRT5bJ3VzYWdlJ107XG4gICAgcHJvdmlkZXJNZXRhZGF0YT86IEVtYmVkTWFueVJlc3VsdDxWQUxVRT5bJ3Byb3ZpZGVyTWV0YWRhdGEnXTtcbiAgICByZXNwb25zZXM/OiBFbWJlZE1hbnlSZXN1bHQ8VkFMVUU+WydyZXNwb25zZXMnXTtcbiAgfSkge1xuICAgIHRoaXMudmFsdWVzID0gb3B0aW9ucy52YWx1ZXM7XG4gICAgdGhpcy5lbWJlZGRpbmdzID0gb3B0aW9ucy5lbWJlZGRpbmdzO1xuICAgIHRoaXMudXNhZ2UgPSBvcHRpb25zLnVzYWdlO1xuICAgIHRoaXMucHJvdmlkZXJNZXRhZGF0YSA9IG9wdGlvbnMucHJvdmlkZXJNZXRhZGF0YTtcbiAgICB0aGlzLnJlc3BvbnNlcyA9IG9wdGlvbnMucmVzcG9uc2VzO1xuICB9XG59XG4iLCAiLyoqXG4gKiBTcGxpdHMgYW4gYXJyYXkgaW50byBjaHVua3Mgb2YgYSBzcGVjaWZpZWQgc2l6ZS5cbiAqXG4gKiBAdGVtcGxhdGUgVCAtIFRoZSB0eXBlIG9mIGVsZW1lbnRzIGluIHRoZSBhcnJheS5cbiAqIEBwYXJhbSB7VFtdfSBhcnJheSAtIFRoZSBhcnJheSB0byBzcGxpdC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBjaHVua1NpemUgLSBUaGUgc2l6ZSBvZiBlYWNoIGNodW5rLlxuICogQHJldHVybnMge1RbXVtdfSAtIEEgbmV3IGFycmF5IGNvbnRhaW5pbmcgdGhlIGNodW5rcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNwbGl0QXJyYXk8VD4oYXJyYXk6IFRbXSwgY2h1bmtTaXplOiBudW1iZXIpOiBUW11bXSB7XG4gIGlmIChjaHVua1NpemUgPD0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignY2h1bmtTaXplIG11c3QgYmUgZ3JlYXRlciB0aGFuIDAnKTtcbiAgfVxuXG4gIGNvbnN0IHJlc3VsdCA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSArPSBjaHVua1NpemUpIHtcbiAgICByZXN1bHQucHVzaChhcnJheS5zbGljZShpLCBpICsgY2h1bmtTaXplKSk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuIiwgImltcG9ydCB7IEltYWdlTW9kZWxWMiwgSW1hZ2VNb2RlbFYyUHJvdmlkZXJNZXRhZGF0YSB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgUHJvdmlkZXJPcHRpb25zLCB3aXRoVXNlckFnZW50U3VmZml4IH0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyBOb0ltYWdlR2VuZXJhdGVkRXJyb3IgfSBmcm9tICcuLi9lcnJvci9uby1pbWFnZS1nZW5lcmF0ZWQtZXJyb3InO1xuaW1wb3J0IHtcbiAgZGV0ZWN0TWVkaWFUeXBlLFxuICBpbWFnZU1lZGlhVHlwZVNpZ25hdHVyZXMsXG59IGZyb20gJy4uL3V0aWwvZGV0ZWN0LW1lZGlhLXR5cGUnO1xuaW1wb3J0IHsgcHJlcGFyZVJldHJpZXMgfSBmcm9tICcuLi91dGlsL3ByZXBhcmUtcmV0cmllcyc7XG5pbXBvcnQgeyBVbnN1cHBvcnRlZE1vZGVsVmVyc2lvbkVycm9yIH0gZnJvbSAnLi4vZXJyb3IvdW5zdXBwb3J0ZWQtbW9kZWwtdmVyc2lvbi1lcnJvcic7XG5pbXBvcnQge1xuICBEZWZhdWx0R2VuZXJhdGVkRmlsZSxcbiAgR2VuZXJhdGVkRmlsZSxcbn0gZnJvbSAnLi4vZ2VuZXJhdGUtdGV4dC9nZW5lcmF0ZWQtZmlsZSc7XG5pbXBvcnQgeyBJbWFnZUdlbmVyYXRpb25XYXJuaW5nIH0gZnJvbSAnLi4vdHlwZXMvaW1hZ2UtbW9kZWwnO1xuaW1wb3J0IHsgSW1hZ2VNb2RlbFJlc3BvbnNlTWV0YWRhdGEgfSBmcm9tICcuLi90eXBlcy9pbWFnZS1tb2RlbC1yZXNwb25zZS1tZXRhZGF0YSc7XG5pbXBvcnQgeyBHZW5lcmF0ZUltYWdlUmVzdWx0IH0gZnJvbSAnLi9nZW5lcmF0ZS1pbWFnZS1yZXN1bHQnO1xuaW1wb3J0IHsgbG9nV2FybmluZ3MgfSBmcm9tICcuLi9sb2dnZXIvbG9nLXdhcm5pbmdzJztcbmltcG9ydCB7IFZFUlNJT04gfSBmcm9tICcuLi92ZXJzaW9uJztcblxuLyoqXG5HZW5lcmF0ZXMgaW1hZ2VzIHVzaW5nIGFuIGltYWdlIG1vZGVsLlxuXG5AcGFyYW0gbW9kZWwgLSBUaGUgaW1hZ2UgbW9kZWwgdG8gdXNlLlxuQHBhcmFtIHByb21wdCAtIFRoZSBwcm9tcHQgdGhhdCBzaG91bGQgYmUgdXNlZCB0byBnZW5lcmF0ZSB0aGUgaW1hZ2UuXG5AcGFyYW0gbiAtIE51bWJlciBvZiBpbWFnZXMgdG8gZ2VuZXJhdGUuIERlZmF1bHQ6IDEuXG5AcGFyYW0gc2l6ZSAtIFNpemUgb2YgdGhlIGltYWdlcyB0byBnZW5lcmF0ZS4gTXVzdCBoYXZlIHRoZSBmb3JtYXQgYHt3aWR0aH14e2hlaWdodH1gLlxuQHBhcmFtIGFzcGVjdFJhdGlvIC0gQXNwZWN0IHJhdGlvIG9mIHRoZSBpbWFnZXMgdG8gZ2VuZXJhdGUuIE11c3QgaGF2ZSB0aGUgZm9ybWF0IGB7d2lkdGh9OntoZWlnaHR9YC5cbkBwYXJhbSBzZWVkIC0gU2VlZCBmb3IgdGhlIGltYWdlIGdlbmVyYXRpb24uXG5AcGFyYW0gcHJvdmlkZXJPcHRpb25zIC0gQWRkaXRpb25hbCBwcm92aWRlci1zcGVjaWZpYyBvcHRpb25zIHRoYXQgYXJlIHBhc3NlZCB0aHJvdWdoIHRvIHRoZSBwcm92aWRlclxuYXMgYm9keSBwYXJhbWV0ZXJzLlxuQHBhcmFtIG1heFJldHJpZXMgLSBNYXhpbXVtIG51bWJlciBvZiByZXRyaWVzLiBTZXQgdG8gMCB0byBkaXNhYmxlIHJldHJpZXMuIERlZmF1bHQ6IDIuXG5AcGFyYW0gYWJvcnRTaWduYWwgLSBBbiBvcHRpb25hbCBhYm9ydCBzaWduYWwgdGhhdCBjYW4gYmUgdXNlZCB0byBjYW5jZWwgdGhlIGNhbGwuXG5AcGFyYW0gaGVhZGVycyAtIEFkZGl0aW9uYWwgSFRUUCBoZWFkZXJzIHRvIGJlIHNlbnQgd2l0aCB0aGUgcmVxdWVzdC4gT25seSBhcHBsaWNhYmxlIGZvciBIVFRQLWJhc2VkIHByb3ZpZGVycy5cblxuQHJldHVybnMgQSByZXN1bHQgb2JqZWN0IHRoYXQgY29udGFpbnMgdGhlIGdlbmVyYXRlZCBpbWFnZXMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZW5lcmF0ZUltYWdlKHtcbiAgbW9kZWwsXG4gIHByb21wdCxcbiAgbiA9IDEsXG4gIG1heEltYWdlc1BlckNhbGwsXG4gIHNpemUsXG4gIGFzcGVjdFJhdGlvLFxuICBzZWVkLFxuICBwcm92aWRlck9wdGlvbnMsXG4gIG1heFJldHJpZXM6IG1heFJldHJpZXNBcmcsXG4gIGFib3J0U2lnbmFsLFxuICBoZWFkZXJzLFxufToge1xuICAvKipcblRoZSBpbWFnZSBtb2RlbCB0byB1c2UuXG4gICAgICovXG4gIG1vZGVsOiBJbWFnZU1vZGVsVjI7XG5cbiAgLyoqXG5UaGUgcHJvbXB0IHRoYXQgc2hvdWxkIGJlIHVzZWQgdG8gZ2VuZXJhdGUgdGhlIGltYWdlLlxuICAgKi9cbiAgcHJvbXB0OiBzdHJpbmc7XG5cbiAgLyoqXG5OdW1iZXIgb2YgaW1hZ2VzIHRvIGdlbmVyYXRlLlxuICAgKi9cbiAgbj86IG51bWJlcjtcblxuICAvKipcbk51bWJlciBvZiBpbWFnZXMgdG8gZ2VuZXJhdGUuXG4gICAqL1xuICBtYXhJbWFnZXNQZXJDYWxsPzogbnVtYmVyO1xuXG4gIC8qKlxuU2l6ZSBvZiB0aGUgaW1hZ2VzIHRvIGdlbmVyYXRlLiBNdXN0IGhhdmUgdGhlIGZvcm1hdCBge3dpZHRofXh7aGVpZ2h0fWAuIElmIG5vdCBwcm92aWRlZCwgdGhlIGRlZmF1bHQgc2l6ZSB3aWxsIGJlIHVzZWQuXG4gICAqL1xuICBzaXplPzogYCR7bnVtYmVyfXgke251bWJlcn1gO1xuXG4gIC8qKlxuQXNwZWN0IHJhdGlvIG9mIHRoZSBpbWFnZXMgdG8gZ2VuZXJhdGUuIE11c3QgaGF2ZSB0aGUgZm9ybWF0IGB7d2lkdGh9OntoZWlnaHR9YC4gSWYgbm90IHByb3ZpZGVkLCB0aGUgZGVmYXVsdCBhc3BlY3QgcmF0aW8gd2lsbCBiZSB1c2VkLlxuICAgKi9cbiAgYXNwZWN0UmF0aW8/OiBgJHtudW1iZXJ9OiR7bnVtYmVyfWA7XG5cbiAgLyoqXG5TZWVkIGZvciB0aGUgaW1hZ2UgZ2VuZXJhdGlvbi4gSWYgbm90IHByb3ZpZGVkLCB0aGUgZGVmYXVsdCBzZWVkIHdpbGwgYmUgdXNlZC5cbiAgICovXG4gIHNlZWQ/OiBudW1iZXI7XG5cbiAgLyoqXG5BZGRpdGlvbmFsIHByb3ZpZGVyLXNwZWNpZmljIG9wdGlvbnMgdGhhdCBhcmUgcGFzc2VkIHRocm91Z2ggdG8gdGhlIHByb3ZpZGVyXG5hcyBib2R5IHBhcmFtZXRlcnMuXG5cblRoZSBvdXRlciByZWNvcmQgaXMga2V5ZWQgYnkgdGhlIHByb3ZpZGVyIG5hbWUsIGFuZCB0aGUgaW5uZXJcbnJlY29yZCBpcyBrZXllZCBieSB0aGUgcHJvdmlkZXItc3BlY2lmaWMgbWV0YWRhdGEga2V5LlxuYGBgdHNcbntcbiAgXCJvcGVuYWlcIjoge1xuICAgIFwic3R5bGVcIjogXCJ2aXZpZFwiXG4gIH1cbn1cbmBgYFxuICAgICAqL1xuICBwcm92aWRlck9wdGlvbnM/OiBQcm92aWRlck9wdGlvbnM7XG5cbiAgLyoqXG5NYXhpbXVtIG51bWJlciBvZiByZXRyaWVzIHBlciBlbWJlZGRpbmcgbW9kZWwgY2FsbC4gU2V0IHRvIDAgdG8gZGlzYWJsZSByZXRyaWVzLlxuXG5AZGVmYXVsdCAyXG4gICAqL1xuICBtYXhSZXRyaWVzPzogbnVtYmVyO1xuXG4gIC8qKlxuQWJvcnQgc2lnbmFsLlxuICovXG4gIGFib3J0U2lnbmFsPzogQWJvcnRTaWduYWw7XG5cbiAgLyoqXG5BZGRpdGlvbmFsIGhlYWRlcnMgdG8gaW5jbHVkZSBpbiB0aGUgcmVxdWVzdC5cbk9ubHkgYXBwbGljYWJsZSBmb3IgSFRUUC1iYXNlZCBwcm92aWRlcnMuXG4gKi9cbiAgaGVhZGVycz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG59KTogUHJvbWlzZTxHZW5lcmF0ZUltYWdlUmVzdWx0PiB7XG4gIGlmIChtb2RlbC5zcGVjaWZpY2F0aW9uVmVyc2lvbiAhPT0gJ3YyJykge1xuICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE1vZGVsVmVyc2lvbkVycm9yKHtcbiAgICAgIHZlcnNpb246IG1vZGVsLnNwZWNpZmljYXRpb25WZXJzaW9uLFxuICAgICAgcHJvdmlkZXI6IG1vZGVsLnByb3ZpZGVyLFxuICAgICAgbW9kZWxJZDogbW9kZWwubW9kZWxJZCxcbiAgICB9KTtcbiAgfVxuXG4gIGNvbnN0IGhlYWRlcnNXaXRoVXNlckFnZW50ID0gd2l0aFVzZXJBZ2VudFN1ZmZpeChcbiAgICBoZWFkZXJzID8/IHt9LFxuICAgIGBhaS8ke1ZFUlNJT059YCxcbiAgKTtcblxuICBjb25zdCB7IHJldHJ5IH0gPSBwcmVwYXJlUmV0cmllcyh7XG4gICAgbWF4UmV0cmllczogbWF4UmV0cmllc0FyZyxcbiAgICBhYm9ydFNpZ25hbCxcbiAgfSk7XG5cbiAgLy8gZGVmYXVsdCB0byAxIGlmIHRoZSBtb2RlbCBoYXMgbm90IHNwZWNpZmllZCBsaW1pdHMgb25cbiAgLy8gaG93IG1hbnkgaW1hZ2VzIGNhbiBiZSBnZW5lcmF0ZWQgaW4gYSBzaW5nbGUgY2FsbFxuICBjb25zdCBtYXhJbWFnZXNQZXJDYWxsV2l0aERlZmF1bHQgPVxuICAgIG1heEltYWdlc1BlckNhbGwgPz8gKGF3YWl0IGludm9rZU1vZGVsTWF4SW1hZ2VzUGVyQ2FsbChtb2RlbCkpID8/IDE7XG5cbiAgLy8gcGFyYWxsZWxpemUgY2FsbHMgdG8gdGhlIG1vZGVsOlxuICBjb25zdCBjYWxsQ291bnQgPSBNYXRoLmNlaWwobiAvIG1heEltYWdlc1BlckNhbGxXaXRoRGVmYXVsdCk7XG4gIGNvbnN0IGNhbGxJbWFnZUNvdW50cyA9IEFycmF5LmZyb20oeyBsZW5ndGg6IGNhbGxDb3VudCB9LCAoXywgaSkgPT4ge1xuICAgIGlmIChpIDwgY2FsbENvdW50IC0gMSkge1xuICAgICAgcmV0dXJuIG1heEltYWdlc1BlckNhbGxXaXRoRGVmYXVsdDtcbiAgICB9XG5cbiAgICBjb25zdCByZW1haW5kZXIgPSBuICUgbWF4SW1hZ2VzUGVyQ2FsbFdpdGhEZWZhdWx0O1xuICAgIHJldHVybiByZW1haW5kZXIgPT09IDAgPyBtYXhJbWFnZXNQZXJDYWxsV2l0aERlZmF1bHQgOiByZW1haW5kZXI7XG4gIH0pO1xuXG4gIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICBjYWxsSW1hZ2VDb3VudHMubWFwKGFzeW5jIGNhbGxJbWFnZUNvdW50ID0+XG4gICAgICByZXRyeSgoKSA9PlxuICAgICAgICBtb2RlbC5kb0dlbmVyYXRlKHtcbiAgICAgICAgICBwcm9tcHQsXG4gICAgICAgICAgbjogY2FsbEltYWdlQ291bnQsXG4gICAgICAgICAgYWJvcnRTaWduYWwsXG4gICAgICAgICAgaGVhZGVyczogaGVhZGVyc1dpdGhVc2VyQWdlbnQsXG4gICAgICAgICAgc2l6ZSxcbiAgICAgICAgICBhc3BlY3RSYXRpbyxcbiAgICAgICAgICBzZWVkLFxuICAgICAgICAgIHByb3ZpZGVyT3B0aW9uczogcHJvdmlkZXJPcHRpb25zID8/IHt9LFxuICAgICAgICB9KSxcbiAgICAgICksXG4gICAgKSxcbiAgKTtcblxuICAvLyBjb2xsZWN0IHJlc3VsdCBpbWFnZXMsIHdhcm5pbmdzLCBhbmQgcmVzcG9uc2UgbWV0YWRhdGFcbiAgY29uc3QgaW1hZ2VzOiBBcnJheTxEZWZhdWx0R2VuZXJhdGVkRmlsZT4gPSBbXTtcbiAgY29uc3Qgd2FybmluZ3M6IEFycmF5PEltYWdlR2VuZXJhdGlvbldhcm5pbmc+ID0gW107XG4gIGNvbnN0IHJlc3BvbnNlczogQXJyYXk8SW1hZ2VNb2RlbFJlc3BvbnNlTWV0YWRhdGE+ID0gW107XG4gIGNvbnN0IHByb3ZpZGVyTWV0YWRhdGE6IEltYWdlTW9kZWxWMlByb3ZpZGVyTWV0YWRhdGEgPSB7fTtcbiAgZm9yIChjb25zdCByZXN1bHQgb2YgcmVzdWx0cykge1xuICAgIGltYWdlcy5wdXNoKFxuICAgICAgLi4ucmVzdWx0LmltYWdlcy5tYXAoXG4gICAgICAgIGltYWdlID0+XG4gICAgICAgICAgbmV3IERlZmF1bHRHZW5lcmF0ZWRGaWxlKHtcbiAgICAgICAgICAgIGRhdGE6IGltYWdlLFxuICAgICAgICAgICAgbWVkaWFUeXBlOlxuICAgICAgICAgICAgICBkZXRlY3RNZWRpYVR5cGUoe1xuICAgICAgICAgICAgICAgIGRhdGE6IGltYWdlLFxuICAgICAgICAgICAgICAgIHNpZ25hdHVyZXM6IGltYWdlTWVkaWFUeXBlU2lnbmF0dXJlcyxcbiAgICAgICAgICAgICAgfSkgPz8gJ2ltYWdlL3BuZycsXG4gICAgICAgICAgfSksXG4gICAgICApLFxuICAgICk7XG4gICAgd2FybmluZ3MucHVzaCguLi5yZXN1bHQud2FybmluZ3MpO1xuXG4gICAgaWYgKHJlc3VsdC5wcm92aWRlck1ldGFkYXRhKSB7XG4gICAgICBmb3IgKGNvbnN0IFtwcm92aWRlck5hbWUsIG1ldGFkYXRhXSBvZiBPYmplY3QuZW50cmllczx7XG4gICAgICAgIGltYWdlczogdW5rbm93bjtcbiAgICAgIH0+KHJlc3VsdC5wcm92aWRlck1ldGFkYXRhKSkge1xuICAgICAgICBwcm92aWRlck1ldGFkYXRhW3Byb3ZpZGVyTmFtZV0gPz89IHsgaW1hZ2VzOiBbXSB9O1xuICAgICAgICBwcm92aWRlck1ldGFkYXRhW3Byb3ZpZGVyTmFtZV0uaW1hZ2VzLnB1c2goXG4gICAgICAgICAgLi4ucmVzdWx0LnByb3ZpZGVyTWV0YWRhdGFbcHJvdmlkZXJOYW1lXS5pbWFnZXMsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmVzcG9uc2VzLnB1c2gocmVzdWx0LnJlc3BvbnNlKTtcbiAgfVxuXG4gIGxvZ1dhcm5pbmdzKHdhcm5pbmdzKTtcblxuICBpZiAoIWltYWdlcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgTm9JbWFnZUdlbmVyYXRlZEVycm9yKHsgcmVzcG9uc2VzIH0pO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBEZWZhdWx0R2VuZXJhdGVJbWFnZVJlc3VsdCh7XG4gICAgaW1hZ2VzLFxuICAgIHdhcm5pbmdzLFxuICAgIHJlc3BvbnNlcyxcbiAgICBwcm92aWRlck1ldGFkYXRhLFxuICB9KTtcbn1cblxuY2xhc3MgRGVmYXVsdEdlbmVyYXRlSW1hZ2VSZXN1bHQgaW1wbGVtZW50cyBHZW5lcmF0ZUltYWdlUmVzdWx0IHtcbiAgcmVhZG9ubHkgaW1hZ2VzOiBBcnJheTxHZW5lcmF0ZWRGaWxlPjtcbiAgcmVhZG9ubHkgd2FybmluZ3M6IEFycmF5PEltYWdlR2VuZXJhdGlvbldhcm5pbmc+O1xuICByZWFkb25seSByZXNwb25zZXM6IEFycmF5PEltYWdlTW9kZWxSZXNwb25zZU1ldGFkYXRhPjtcbiAgcmVhZG9ubHkgcHJvdmlkZXJNZXRhZGF0YTogSW1hZ2VNb2RlbFYyUHJvdmlkZXJNZXRhZGF0YTtcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiB7XG4gICAgaW1hZ2VzOiBBcnJheTxHZW5lcmF0ZWRGaWxlPjtcbiAgICB3YXJuaW5nczogQXJyYXk8SW1hZ2VHZW5lcmF0aW9uV2FybmluZz47XG4gICAgcmVzcG9uc2VzOiBBcnJheTxJbWFnZU1vZGVsUmVzcG9uc2VNZXRhZGF0YT47XG4gICAgcHJvdmlkZXJNZXRhZGF0YTogSW1hZ2VNb2RlbFYyUHJvdmlkZXJNZXRhZGF0YTtcbiAgfSkge1xuICAgIHRoaXMuaW1hZ2VzID0gb3B0aW9ucy5pbWFnZXM7XG4gICAgdGhpcy53YXJuaW5ncyA9IG9wdGlvbnMud2FybmluZ3M7XG4gICAgdGhpcy5yZXNwb25zZXMgPSBvcHRpb25zLnJlc3BvbnNlcztcbiAgICB0aGlzLnByb3ZpZGVyTWV0YWRhdGEgPSBvcHRpb25zLnByb3ZpZGVyTWV0YWRhdGE7XG4gIH1cblxuICBnZXQgaW1hZ2UoKSB7XG4gICAgcmV0dXJuIHRoaXMuaW1hZ2VzWzBdO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGludm9rZU1vZGVsTWF4SW1hZ2VzUGVyQ2FsbChtb2RlbDogSW1hZ2VNb2RlbFYyKSB7XG4gIGNvbnN0IGlzRnVuY3Rpb24gPSBtb2RlbC5tYXhJbWFnZXNQZXJDYWxsIGluc3RhbmNlb2YgRnVuY3Rpb247XG5cbiAgaWYgKCFpc0Z1bmN0aW9uKSB7XG4gICAgcmV0dXJuIG1vZGVsLm1heEltYWdlc1BlckNhbGw7XG4gIH1cblxuICByZXR1cm4gbW9kZWwubWF4SW1hZ2VzUGVyQ2FsbCh7XG4gICAgbW9kZWxJZDogbW9kZWwubW9kZWxJZCxcbiAgfSk7XG59XG4iLCAiaW1wb3J0IHsgSlNPTlZhbHVlIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQge1xuICBjcmVhdGVJZEdlbmVyYXRvcixcbiAgRmxleGlibGVTY2hlbWEsXG4gIEluZmVyU2NoZW1hLFxuICBQcm92aWRlck9wdGlvbnMsXG4gIHdpdGhVc2VyQWdlbnRTdWZmaXgsXG59IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXItdXRpbHMnO1xuaW1wb3J0IHsgTm9PYmplY3RHZW5lcmF0ZWRFcnJvciB9IGZyb20gJy4uL2Vycm9yL25vLW9iamVjdC1nZW5lcmF0ZWQtZXJyb3InO1xuaW1wb3J0IHsgZXh0cmFjdFJlYXNvbmluZ0NvbnRlbnQgfSBmcm9tICcuLi9nZW5lcmF0ZS10ZXh0L2V4dHJhY3QtcmVhc29uaW5nLWNvbnRlbnQnO1xuaW1wb3J0IHsgZXh0cmFjdFRleHRDb250ZW50IH0gZnJvbSAnLi4vZ2VuZXJhdGUtdGV4dC9leHRyYWN0LXRleHQtY29udGVudCc7XG5pbXBvcnQgeyBsb2dXYXJuaW5ncyB9IGZyb20gJy4uL2xvZ2dlci9sb2ctd2FybmluZ3MnO1xuaW1wb3J0IHsgcmVzb2x2ZUxhbmd1YWdlTW9kZWwgfSBmcm9tICcuLi9tb2RlbC9yZXNvbHZlLW1vZGVsJztcbmltcG9ydCB7IENhbGxTZXR0aW5ncyB9IGZyb20gJy4uL3Byb21wdC9jYWxsLXNldHRpbmdzJztcbmltcG9ydCB7IGNvbnZlcnRUb0xhbmd1YWdlTW9kZWxQcm9tcHQgfSBmcm9tICcuLi9wcm9tcHQvY29udmVydC10by1sYW5ndWFnZS1tb2RlbC1wcm9tcHQnO1xuaW1wb3J0IHsgcHJlcGFyZUNhbGxTZXR0aW5ncyB9IGZyb20gJy4uL3Byb21wdC9wcmVwYXJlLWNhbGwtc2V0dGluZ3MnO1xuaW1wb3J0IHsgUHJvbXB0IH0gZnJvbSAnLi4vcHJvbXB0L3Byb21wdCc7XG5pbXBvcnQgeyBzdGFuZGFyZGl6ZVByb21wdCB9IGZyb20gJy4uL3Byb21wdC9zdGFuZGFyZGl6ZS1wcm9tcHQnO1xuaW1wb3J0IHsgd3JhcEdhdGV3YXlFcnJvciB9IGZyb20gJy4uL3Byb21wdC93cmFwLWdhdGV3YXktZXJyb3InO1xuaW1wb3J0IHsgYXNzZW1ibGVPcGVyYXRpb25OYW1lIH0gZnJvbSAnLi4vdGVsZW1ldHJ5L2Fzc2VtYmxlLW9wZXJhdGlvbi1uYW1lJztcbmltcG9ydCB7IGdldEJhc2VUZWxlbWV0cnlBdHRyaWJ1dGVzIH0gZnJvbSAnLi4vdGVsZW1ldHJ5L2dldC1iYXNlLXRlbGVtZXRyeS1hdHRyaWJ1dGVzJztcbmltcG9ydCB7IGdldFRyYWNlciB9IGZyb20gJy4uL3RlbGVtZXRyeS9nZXQtdHJhY2VyJztcbmltcG9ydCB7IHJlY29yZFNwYW4gfSBmcm9tICcuLi90ZWxlbWV0cnkvcmVjb3JkLXNwYW4nO1xuaW1wb3J0IHsgc2VsZWN0VGVsZW1ldHJ5QXR0cmlidXRlcyB9IGZyb20gJy4uL3RlbGVtZXRyeS9zZWxlY3QtdGVsZW1ldHJ5LWF0dHJpYnV0ZXMnO1xuaW1wb3J0IHsgc3RyaW5naWZ5Rm9yVGVsZW1ldHJ5IH0gZnJvbSAnLi4vdGVsZW1ldHJ5L3N0cmluZ2lmeS1mb3ItdGVsZW1ldHJ5JztcbmltcG9ydCB7IFRlbGVtZXRyeVNldHRpbmdzIH0gZnJvbSAnLi4vdGVsZW1ldHJ5L3RlbGVtZXRyeS1zZXR0aW5ncyc7XG5pbXBvcnQge1xuICBDYWxsV2FybmluZyxcbiAgRmluaXNoUmVhc29uLFxuICBMYW5ndWFnZU1vZGVsLFxufSBmcm9tICcuLi90eXBlcy9sYW5ndWFnZS1tb2RlbCc7XG5pbXBvcnQgeyBMYW5ndWFnZU1vZGVsUmVxdWVzdE1ldGFkYXRhIH0gZnJvbSAnLi4vdHlwZXMvbGFuZ3VhZ2UtbW9kZWwtcmVxdWVzdC1tZXRhZGF0YSc7XG5pbXBvcnQgeyBMYW5ndWFnZU1vZGVsUmVzcG9uc2VNZXRhZGF0YSB9IGZyb20gJy4uL3R5cGVzL2xhbmd1YWdlLW1vZGVsLXJlc3BvbnNlLW1ldGFkYXRhJztcbmltcG9ydCB7IFByb3ZpZGVyTWV0YWRhdGEgfSBmcm9tICcuLi90eXBlcy9wcm92aWRlci1tZXRhZGF0YSc7XG5pbXBvcnQgeyBMYW5ndWFnZU1vZGVsVXNhZ2UgfSBmcm9tICcuLi90eXBlcy91c2FnZSc7XG5pbXBvcnQgeyBEb3dubG9hZEZ1bmN0aW9uIH0gZnJvbSAnLi4vdXRpbC9kb3dubG9hZC9kb3dubG9hZC1mdW5jdGlvbic7XG5pbXBvcnQgeyBwcmVwYXJlSGVhZGVycyB9IGZyb20gJy4uL3V0aWwvcHJlcGFyZS1oZWFkZXJzJztcbmltcG9ydCB7IHByZXBhcmVSZXRyaWVzIH0gZnJvbSAnLi4vdXRpbC9wcmVwYXJlLXJldHJpZXMnO1xuaW1wb3J0IHsgVkVSU0lPTiB9IGZyb20gJy4uL3ZlcnNpb24nO1xuaW1wb3J0IHsgR2VuZXJhdGVPYmplY3RSZXN1bHQgfSBmcm9tICcuL2dlbmVyYXRlLW9iamVjdC1yZXN1bHQnO1xuaW1wb3J0IHsgZ2V0T3V0cHV0U3RyYXRlZ3kgfSBmcm9tICcuL291dHB1dC1zdHJhdGVneSc7XG5pbXBvcnQgeyBwYXJzZUFuZFZhbGlkYXRlT2JqZWN0UmVzdWx0V2l0aFJlcGFpciB9IGZyb20gJy4vcGFyc2UtYW5kLXZhbGlkYXRlLW9iamVjdC1yZXN1bHQnO1xuaW1wb3J0IHsgUmVwYWlyVGV4dEZ1bmN0aW9uIH0gZnJvbSAnLi9yZXBhaXItdGV4dCc7XG5pbXBvcnQgeyB2YWxpZGF0ZU9iamVjdEdlbmVyYXRpb25JbnB1dCB9IGZyb20gJy4vdmFsaWRhdGUtb2JqZWN0LWdlbmVyYXRpb24taW5wdXQnO1xuXG5jb25zdCBvcmlnaW5hbEdlbmVyYXRlSWQgPSBjcmVhdGVJZEdlbmVyYXRvcih7IHByZWZpeDogJ2Fpb2JqJywgc2l6ZTogMjQgfSk7XG5cbi8qKlxuR2VuZXJhdGUgYSBzdHJ1Y3R1cmVkLCB0eXBlZCBvYmplY3QgZm9yIGEgZ2l2ZW4gcHJvbXB0IGFuZCBzY2hlbWEgdXNpbmcgYSBsYW5ndWFnZSBtb2RlbC5cblxuVGhpcyBmdW5jdGlvbiBkb2VzIG5vdCBzdHJlYW0gdGhlIG91dHB1dC4gSWYgeW91IHdhbnQgdG8gc3RyZWFtIHRoZSBvdXRwdXQsIHVzZSBgc3RyZWFtT2JqZWN0YCBpbnN0ZWFkLlxuXG5AcGFyYW0gbW9kZWwgLSBUaGUgbGFuZ3VhZ2UgbW9kZWwgdG8gdXNlLlxuQHBhcmFtIHRvb2xzIC0gVG9vbHMgdGhhdCBhcmUgYWNjZXNzaWJsZSB0byBhbmQgY2FuIGJlIGNhbGxlZCBieSB0aGUgbW9kZWwuIFRoZSBtb2RlbCBuZWVkcyB0byBzdXBwb3J0IGNhbGxpbmcgdG9vbHMuXG5cbkBwYXJhbSBzeXN0ZW0gLSBBIHN5c3RlbSBtZXNzYWdlIHRoYXQgd2lsbCBiZSBwYXJ0IG9mIHRoZSBwcm9tcHQuXG5AcGFyYW0gcHJvbXB0IC0gQSBzaW1wbGUgdGV4dCBwcm9tcHQuIFlvdSBjYW4gZWl0aGVyIHVzZSBgcHJvbXB0YCBvciBgbWVzc2FnZXNgIGJ1dCBub3QgYm90aC5cbkBwYXJhbSBtZXNzYWdlcyAtIEEgbGlzdCBvZiBtZXNzYWdlcy4gWW91IGNhbiBlaXRoZXIgdXNlIGBwcm9tcHRgIG9yIGBtZXNzYWdlc2AgYnV0IG5vdCBib3RoLlxuXG5AcGFyYW0gbWF4T3V0cHV0VG9rZW5zIC0gTWF4aW11bSBudW1iZXIgb2YgdG9rZW5zIHRvIGdlbmVyYXRlLlxuQHBhcmFtIHRlbXBlcmF0dXJlIC0gVGVtcGVyYXR1cmUgc2V0dGluZy5cblRoZSB2YWx1ZSBpcyBwYXNzZWQgdGhyb3VnaCB0byB0aGUgcHJvdmlkZXIuIFRoZSByYW5nZSBkZXBlbmRzIG9uIHRoZSBwcm92aWRlciBhbmQgbW9kZWwuXG5JdCBpcyByZWNvbW1lbmRlZCB0byBzZXQgZWl0aGVyIGB0ZW1wZXJhdHVyZWAgb3IgYHRvcFBgLCBidXQgbm90IGJvdGguXG5AcGFyYW0gdG9wUCAtIE51Y2xldXMgc2FtcGxpbmcuXG5UaGUgdmFsdWUgaXMgcGFzc2VkIHRocm91Z2ggdG8gdGhlIHByb3ZpZGVyLiBUaGUgcmFuZ2UgZGVwZW5kcyBvbiB0aGUgcHJvdmlkZXIgYW5kIG1vZGVsLlxuSXQgaXMgcmVjb21tZW5kZWQgdG8gc2V0IGVpdGhlciBgdGVtcGVyYXR1cmVgIG9yIGB0b3BQYCwgYnV0IG5vdCBib3RoLlxuQHBhcmFtIHRvcEsgLSBPbmx5IHNhbXBsZSBmcm9tIHRoZSB0b3AgSyBvcHRpb25zIGZvciBlYWNoIHN1YnNlcXVlbnQgdG9rZW4uXG5Vc2VkIHRvIHJlbW92ZSBcImxvbmcgdGFpbFwiIGxvdyBwcm9iYWJpbGl0eSByZXNwb25zZXMuXG5SZWNvbW1lbmRlZCBmb3IgYWR2YW5jZWQgdXNlIGNhc2VzIG9ubHkuIFlvdSB1c3VhbGx5IG9ubHkgbmVlZCB0byB1c2UgdGVtcGVyYXR1cmUuXG5AcGFyYW0gcHJlc2VuY2VQZW5hbHR5IC0gUHJlc2VuY2UgcGVuYWx0eSBzZXR0aW5nLlxuSXQgYWZmZWN0cyB0aGUgbGlrZWxpaG9vZCBvZiB0aGUgbW9kZWwgdG8gcmVwZWF0IGluZm9ybWF0aW9uIHRoYXQgaXMgYWxyZWFkeSBpbiB0aGUgcHJvbXB0LlxuVGhlIHZhbHVlIGlzIHBhc3NlZCB0aHJvdWdoIHRvIHRoZSBwcm92aWRlci4gVGhlIHJhbmdlIGRlcGVuZHMgb24gdGhlIHByb3ZpZGVyIGFuZCBtb2RlbC5cbkBwYXJhbSBmcmVxdWVuY3lQZW5hbHR5IC0gRnJlcXVlbmN5IHBlbmFsdHkgc2V0dGluZy5cbkl0IGFmZmVjdHMgdGhlIGxpa2VsaWhvb2Qgb2YgdGhlIG1vZGVsIHRvIHJlcGVhdGVkbHkgdXNlIHRoZSBzYW1lIHdvcmRzIG9yIHBocmFzZXMuXG5UaGUgdmFsdWUgaXMgcGFzc2VkIHRocm91Z2ggdG8gdGhlIHByb3ZpZGVyLiBUaGUgcmFuZ2UgZGVwZW5kcyBvbiB0aGUgcHJvdmlkZXIgYW5kIG1vZGVsLlxuQHBhcmFtIHN0b3BTZXF1ZW5jZXMgLSBTdG9wIHNlcXVlbmNlcy5cbklmIHNldCwgdGhlIG1vZGVsIHdpbGwgc3RvcCBnZW5lcmF0aW5nIHRleHQgd2hlbiBvbmUgb2YgdGhlIHN0b3Agc2VxdWVuY2VzIGlzIGdlbmVyYXRlZC5cbkBwYXJhbSBzZWVkIC0gVGhlIHNlZWQgKGludGVnZXIpIHRvIHVzZSBmb3IgcmFuZG9tIHNhbXBsaW5nLlxuSWYgc2V0IGFuZCBzdXBwb3J0ZWQgYnkgdGhlIG1vZGVsLCBjYWxscyB3aWxsIGdlbmVyYXRlIGRldGVybWluaXN0aWMgcmVzdWx0cy5cblxuQHBhcmFtIG1heFJldHJpZXMgLSBNYXhpbXVtIG51bWJlciBvZiByZXRyaWVzLiBTZXQgdG8gMCB0byBkaXNhYmxlIHJldHJpZXMuIERlZmF1bHQ6IDIuXG5AcGFyYW0gYWJvcnRTaWduYWwgLSBBbiBvcHRpb25hbCBhYm9ydCBzaWduYWwgdGhhdCBjYW4gYmUgdXNlZCB0byBjYW5jZWwgdGhlIGNhbGwuXG5AcGFyYW0gaGVhZGVycyAtIEFkZGl0aW9uYWwgSFRUUCBoZWFkZXJzIHRvIGJlIHNlbnQgd2l0aCB0aGUgcmVxdWVzdC4gT25seSBhcHBsaWNhYmxlIGZvciBIVFRQLWJhc2VkIHByb3ZpZGVycy5cblxuQHBhcmFtIHNjaGVtYSAtIFRoZSBzY2hlbWEgb2YgdGhlIG9iamVjdCB0aGF0IHRoZSBtb2RlbCBzaG91bGQgZ2VuZXJhdGUuXG5AcGFyYW0gc2NoZW1hTmFtZSAtIE9wdGlvbmFsIG5hbWUgb2YgdGhlIG91dHB1dCB0aGF0IHNob3VsZCBiZSBnZW5lcmF0ZWQuXG5Vc2VkIGJ5IHNvbWUgcHJvdmlkZXJzIGZvciBhZGRpdGlvbmFsIExMTSBndWlkYW5jZSwgZS5nLlxudmlhIHRvb2wgb3Igc2NoZW1hIG5hbWUuXG5AcGFyYW0gc2NoZW1hRGVzY3JpcHRpb24gLSBPcHRpb25hbCBkZXNjcmlwdGlvbiBvZiB0aGUgb3V0cHV0IHRoYXQgc2hvdWxkIGJlIGdlbmVyYXRlZC5cblVzZWQgYnkgc29tZSBwcm92aWRlcnMgZm9yIGFkZGl0aW9uYWwgTExNIGd1aWRhbmNlLCBlLmcuXG52aWEgdG9vbCBvciBzY2hlbWEgZGVzY3JpcHRpb24uXG5cbkBwYXJhbSBvdXRwdXQgLSBUaGUgdHlwZSBvZiB0aGUgb3V0cHV0LlxuXG4tICdvYmplY3QnOiBUaGUgb3V0cHV0IGlzIGFuIG9iamVjdC5cbi0gJ2FycmF5JzogVGhlIG91dHB1dCBpcyBhbiBhcnJheS5cbi0gJ2VudW0nOiBUaGUgb3V0cHV0IGlzIGFuIGVudW0uXG4tICduby1zY2hlbWEnOiBUaGUgb3V0cHV0IGlzIG5vdCBhIHNjaGVtYS5cblxuQHBhcmFtIGV4cGVyaW1lbnRhbF9yZXBhaXJUZXh0IC0gQSBmdW5jdGlvbiB0aGF0IGF0dGVtcHRzIHRvIHJlcGFpciB0aGUgcmF3IG91dHB1dCBvZiB0aGUgbW9kZWxcbnRvIGVuYWJsZSBKU09OIHBhcnNpbmcuXG5cbkBwYXJhbSBleHBlcmltZW50YWxfdGVsZW1ldHJ5IC0gT3B0aW9uYWwgdGVsZW1ldHJ5IGNvbmZpZ3VyYXRpb24gKGV4cGVyaW1lbnRhbCkuXG5cbkBwYXJhbSBwcm92aWRlck9wdGlvbnMgLSBBZGRpdGlvbmFsIHByb3ZpZGVyLXNwZWNpZmljIG9wdGlvbnMuIFRoZXkgYXJlIHBhc3NlZCB0aHJvdWdoXG50byB0aGUgcHJvdmlkZXIgZnJvbSB0aGUgQUkgU0RLIGFuZCBlbmFibGUgcHJvdmlkZXItc3BlY2lmaWNcbmZ1bmN0aW9uYWxpdHkgdGhhdCBjYW4gYmUgZnVsbHkgZW5jYXBzdWxhdGVkIGluIHRoZSBwcm92aWRlci5cblxuQHJldHVybnNcbkEgcmVzdWx0IG9iamVjdCB0aGF0IGNvbnRhaW5zIHRoZSBnZW5lcmF0ZWQgb2JqZWN0LCB0aGUgZmluaXNoIHJlYXNvbiwgdGhlIHRva2VuIHVzYWdlLCBhbmQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbi5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlT2JqZWN0PFxuICBTQ0hFTUEgZXh0ZW5kcyBGbGV4aWJsZVNjaGVtYTx1bmtub3duPiA9IEZsZXhpYmxlU2NoZW1hPEpTT05WYWx1ZT4sXG4gIE9VVFBVVCBleHRlbmRzXG4gICAgfCAnb2JqZWN0J1xuICAgIHwgJ2FycmF5J1xuICAgIHwgJ2VudW0nXG4gICAgfCAnbm8tc2NoZW1hJyA9IEluZmVyU2NoZW1hPFNDSEVNQT4gZXh0ZW5kcyBzdHJpbmcgPyAnZW51bScgOiAnb2JqZWN0JyxcbiAgUkVTVUxUID0gT1VUUFVUIGV4dGVuZHMgJ2FycmF5J1xuICAgID8gQXJyYXk8SW5mZXJTY2hlbWE8U0NIRU1BPj5cbiAgICA6IEluZmVyU2NoZW1hPFNDSEVNQT4sXG4+KFxuICBvcHRpb25zOiBPbWl0PENhbGxTZXR0aW5ncywgJ3N0b3BTZXF1ZW5jZXMnPiAmXG4gICAgUHJvbXB0ICZcbiAgICAoT1VUUFVUIGV4dGVuZHMgJ2VudW0nXG4gICAgICA/IHtcbiAgICAgICAgICAvKipcblRoZSBlbnVtIHZhbHVlcyB0aGF0IHRoZSBtb2RlbCBzaG91bGQgdXNlLlxuICAgICAgICAqL1xuICAgICAgICAgIGVudW06IEFycmF5PFJFU1VMVD47XG4gICAgICAgICAgbW9kZT86ICdqc29uJztcbiAgICAgICAgICBvdXRwdXQ6ICdlbnVtJztcbiAgICAgICAgfVxuICAgICAgOiBPVVRQVVQgZXh0ZW5kcyAnbm8tc2NoZW1hJ1xuICAgICAgICA/IHt9XG4gICAgICAgIDoge1xuICAgICAgICAgICAgLyoqXG5UaGUgc2NoZW1hIG9mIHRoZSBvYmplY3QgdGhhdCB0aGUgbW9kZWwgc2hvdWxkIGdlbmVyYXRlLlxuICAgICAgICAqL1xuICAgICAgICAgICAgc2NoZW1hOiBTQ0hFTUE7XG5cbiAgICAgICAgICAgIC8qKlxuT3B0aW9uYWwgbmFtZSBvZiB0aGUgb3V0cHV0IHRoYXQgc2hvdWxkIGJlIGdlbmVyYXRlZC5cblVzZWQgYnkgc29tZSBwcm92aWRlcnMgZm9yIGFkZGl0aW9uYWwgTExNIGd1aWRhbmNlLCBlLmcuXG52aWEgdG9vbCBvciBzY2hlbWEgbmFtZS5cbiAgICAgICAgKi9cbiAgICAgICAgICAgIHNjaGVtYU5hbWU/OiBzdHJpbmc7XG5cbiAgICAgICAgICAgIC8qKlxuT3B0aW9uYWwgZGVzY3JpcHRpb24gb2YgdGhlIG91dHB1dCB0aGF0IHNob3VsZCBiZSBnZW5lcmF0ZWQuXG5Vc2VkIGJ5IHNvbWUgcHJvdmlkZXJzIGZvciBhZGRpdGlvbmFsIExMTSBndWlkYW5jZSwgZS5nLlxudmlhIHRvb2wgb3Igc2NoZW1hIGRlc2NyaXB0aW9uLlxuICAgICAgICAqL1xuICAgICAgICAgICAgc2NoZW1hRGVzY3JpcHRpb24/OiBzdHJpbmc7XG5cbiAgICAgICAgICAgIC8qKlxuVGhlIG1vZGUgdG8gdXNlIGZvciBvYmplY3QgZ2VuZXJhdGlvbi5cblxuVGhlIHNjaGVtYSBpcyBjb252ZXJ0ZWQgaW50byBhIEpTT04gc2NoZW1hIGFuZCB1c2VkIGluIG9uZSBvZiB0aGUgZm9sbG93aW5nIHdheXNcblxuLSAnYXV0byc6IFRoZSBwcm92aWRlciB3aWxsIGNob29zZSB0aGUgYmVzdCBtb2RlIGZvciB0aGUgbW9kZWwuXG4tICd0b29sJzogQSB0b29sIHdpdGggdGhlIEpTT04gc2NoZW1hIGFzIHBhcmFtZXRlcnMgaXMgcHJvdmlkZWQgYW5kIHRoZSBwcm92aWRlciBpcyBpbnN0cnVjdGVkIHRvIHVzZSBpdC5cbi0gJ2pzb24nOiBUaGUgSlNPTiBzY2hlbWEgYW5kIGFuIGluc3RydWN0aW9uIGFyZSBpbmplY3RlZCBpbnRvIHRoZSBwcm9tcHQuIElmIHRoZSBwcm92aWRlciBzdXBwb3J0cyBKU09OIG1vZGUsIGl0IGlzIGVuYWJsZWQuIElmIHRoZSBwcm92aWRlciBzdXBwb3J0cyBKU09OIGdyYW1tYXJzLCB0aGUgZ3JhbW1hciBpcyB1c2VkLlxuXG5QbGVhc2Ugbm90ZSB0aGF0IG1vc3QgcHJvdmlkZXJzIGRvIG5vdCBzdXBwb3J0IGFsbCBtb2Rlcy5cblxuRGVmYXVsdCBhbmQgcmVjb21tZW5kZWQ6ICdhdXRvJyAoYmVzdCBtb2RlIGZvciB0aGUgbW9kZWwpLlxuICAgICAgICAqL1xuICAgICAgICAgICAgbW9kZT86ICdhdXRvJyB8ICdqc29uJyB8ICd0b29sJztcbiAgICAgICAgICB9KSAmIHtcbiAgICAgIG91dHB1dD86IE9VVFBVVDtcblxuICAgICAgLyoqXG4gIFRoZSBsYW5ndWFnZSBtb2RlbCB0byB1c2UuXG4gICAgICAgKi9cbiAgICAgIG1vZGVsOiBMYW5ndWFnZU1vZGVsO1xuICAgICAgLyoqXG4gIEEgZnVuY3Rpb24gdGhhdCBhdHRlbXB0cyB0byByZXBhaXIgdGhlIHJhdyBvdXRwdXQgb2YgdGhlIG1vZGVsXG4gIHRvIGVuYWJsZSBKU09OIHBhcnNpbmcuXG4gICAgICAgKi9cbiAgICAgIGV4cGVyaW1lbnRhbF9yZXBhaXJUZXh0PzogUmVwYWlyVGV4dEZ1bmN0aW9uO1xuXG4gICAgICAvKipcbiAgT3B0aW9uYWwgdGVsZW1ldHJ5IGNvbmZpZ3VyYXRpb24gKGV4cGVyaW1lbnRhbCkuXG4gICAgICAgICAqL1xuXG4gICAgICBleHBlcmltZW50YWxfdGVsZW1ldHJ5PzogVGVsZW1ldHJ5U2V0dGluZ3M7XG5cbiAgICAgIC8qKlxuICBDdXN0b20gZG93bmxvYWQgZnVuY3Rpb24gdG8gdXNlIGZvciBVUkxzLlxuXG4gIEJ5IGRlZmF1bHQsIGZpbGVzIGFyZSBkb3dubG9hZGVkIGlmIHRoZSBtb2RlbCBkb2VzIG5vdCBzdXBwb3J0IHRoZSBVUkwgZm9yIHRoZSBnaXZlbiBtZWRpYSB0eXBlLlxuICAgICAgICovXG4gICAgICBleHBlcmltZW50YWxfZG93bmxvYWQ/OiBEb3dubG9hZEZ1bmN0aW9uIHwgdW5kZWZpbmVkO1xuXG4gICAgICAvKipcbiAgQWRkaXRpb25hbCBwcm92aWRlci1zcGVjaWZpYyBvcHRpb25zLiBUaGV5IGFyZSBwYXNzZWQgdGhyb3VnaFxuICB0byB0aGUgcHJvdmlkZXIgZnJvbSB0aGUgQUkgU0RLIGFuZCBlbmFibGUgcHJvdmlkZXItc3BlY2lmaWNcbiAgZnVuY3Rpb25hbGl0eSB0aGF0IGNhbiBiZSBmdWxseSBlbmNhcHN1bGF0ZWQgaW4gdGhlIHByb3ZpZGVyLlxuICAgKi9cbiAgICAgIHByb3ZpZGVyT3B0aW9ucz86IFByb3ZpZGVyT3B0aW9ucztcblxuICAgICAgLyoqXG4gICAgICAgKiBJbnRlcm5hbC4gRm9yIHRlc3QgdXNlIG9ubHkuIE1heSBjaGFuZ2Ugd2l0aG91dCBub3RpY2UuXG4gICAgICAgKi9cbiAgICAgIF9pbnRlcm5hbD86IHtcbiAgICAgICAgZ2VuZXJhdGVJZD86ICgpID0+IHN0cmluZztcbiAgICAgICAgY3VycmVudERhdGU/OiAoKSA9PiBEYXRlO1xuICAgICAgfTtcbiAgICB9LFxuKTogUHJvbWlzZTxHZW5lcmF0ZU9iamVjdFJlc3VsdDxSRVNVTFQ+PiB7XG4gIGNvbnN0IHtcbiAgICBtb2RlbDogbW9kZWxBcmcsXG4gICAgb3V0cHV0ID0gJ29iamVjdCcsXG4gICAgc3lzdGVtLFxuICAgIHByb21wdCxcbiAgICBtZXNzYWdlcyxcbiAgICBtYXhSZXRyaWVzOiBtYXhSZXRyaWVzQXJnLFxuICAgIGFib3J0U2lnbmFsLFxuICAgIGhlYWRlcnMsXG4gICAgZXhwZXJpbWVudGFsX3JlcGFpclRleHQ6IHJlcGFpclRleHQsXG4gICAgZXhwZXJpbWVudGFsX3RlbGVtZXRyeTogdGVsZW1ldHJ5LFxuICAgIGV4cGVyaW1lbnRhbF9kb3dubG9hZDogZG93bmxvYWQsXG4gICAgcHJvdmlkZXJPcHRpb25zLFxuICAgIF9pbnRlcm5hbDoge1xuICAgICAgZ2VuZXJhdGVJZCA9IG9yaWdpbmFsR2VuZXJhdGVJZCxcbiAgICAgIGN1cnJlbnREYXRlID0gKCkgPT4gbmV3IERhdGUoKSxcbiAgICB9ID0ge30sXG4gICAgLi4uc2V0dGluZ3NcbiAgfSA9IG9wdGlvbnM7XG5cbiAgY29uc3QgbW9kZWwgPSByZXNvbHZlTGFuZ3VhZ2VNb2RlbChtb2RlbEFyZyk7XG5cbiAgY29uc3QgZW51bVZhbHVlcyA9ICdlbnVtJyBpbiBvcHRpb25zID8gb3B0aW9ucy5lbnVtIDogdW5kZWZpbmVkO1xuICBjb25zdCB7XG4gICAgc2NoZW1hOiBpbnB1dFNjaGVtYSxcbiAgICBzY2hlbWFEZXNjcmlwdGlvbixcbiAgICBzY2hlbWFOYW1lLFxuICB9ID0gJ3NjaGVtYScgaW4gb3B0aW9ucyA/IG9wdGlvbnMgOiB7fTtcblxuICB2YWxpZGF0ZU9iamVjdEdlbmVyYXRpb25JbnB1dCh7XG4gICAgb3V0cHV0LFxuICAgIHNjaGVtYTogaW5wdXRTY2hlbWEsXG4gICAgc2NoZW1hTmFtZSxcbiAgICBzY2hlbWFEZXNjcmlwdGlvbixcbiAgICBlbnVtVmFsdWVzLFxuICB9KTtcblxuICBjb25zdCB7IG1heFJldHJpZXMsIHJldHJ5IH0gPSBwcmVwYXJlUmV0cmllcyh7XG4gICAgbWF4UmV0cmllczogbWF4UmV0cmllc0FyZyxcbiAgICBhYm9ydFNpZ25hbCxcbiAgfSk7XG5cbiAgY29uc3Qgb3V0cHV0U3RyYXRlZ3kgPSBnZXRPdXRwdXRTdHJhdGVneSh7XG4gICAgb3V0cHV0LFxuICAgIHNjaGVtYTogaW5wdXRTY2hlbWEsXG4gICAgZW51bVZhbHVlcyxcbiAgfSk7XG5cbiAgY29uc3QgY2FsbFNldHRpbmdzID0gcHJlcGFyZUNhbGxTZXR0aW5ncyhzZXR0aW5ncyk7XG5cbiAgY29uc3QgaGVhZGVyc1dpdGhVc2VyQWdlbnQgPSB3aXRoVXNlckFnZW50U3VmZml4KFxuICAgIGhlYWRlcnMgPz8ge30sXG4gICAgYGFpLyR7VkVSU0lPTn1gLFxuICApO1xuXG4gIGNvbnN0IGJhc2VUZWxlbWV0cnlBdHRyaWJ1dGVzID0gZ2V0QmFzZVRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgIG1vZGVsLFxuICAgIHRlbGVtZXRyeSxcbiAgICBoZWFkZXJzOiBoZWFkZXJzV2l0aFVzZXJBZ2VudCxcbiAgICBzZXR0aW5nczogeyAuLi5jYWxsU2V0dGluZ3MsIG1heFJldHJpZXMgfSxcbiAgfSk7XG5cbiAgY29uc3QgdHJhY2VyID0gZ2V0VHJhY2VyKHRlbGVtZXRyeSk7XG5cbiAgdHJ5IHtcbiAgICByZXR1cm4gYXdhaXQgcmVjb3JkU3Bhbih7XG4gICAgICBuYW1lOiAnYWkuZ2VuZXJhdGVPYmplY3QnLFxuICAgICAgYXR0cmlidXRlczogc2VsZWN0VGVsZW1ldHJ5QXR0cmlidXRlcyh7XG4gICAgICAgIHRlbGVtZXRyeSxcbiAgICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAgIC4uLmFzc2VtYmxlT3BlcmF0aW9uTmFtZSh7XG4gICAgICAgICAgICBvcGVyYXRpb25JZDogJ2FpLmdlbmVyYXRlT2JqZWN0JyxcbiAgICAgICAgICAgIHRlbGVtZXRyeSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICAuLi5iYXNlVGVsZW1ldHJ5QXR0cmlidXRlcyxcbiAgICAgICAgICAvLyBzcGVjaWZpYyBzZXR0aW5ncyB0aGF0IG9ubHkgbWFrZSBzZW5zZSBvbiB0aGUgb3V0ZXIgbGV2ZWw6XG4gICAgICAgICAgJ2FpLnByb21wdCc6IHtcbiAgICAgICAgICAgIGlucHV0OiAoKSA9PiBKU09OLnN0cmluZ2lmeSh7IHN5c3RlbSwgcHJvbXB0LCBtZXNzYWdlcyB9KSxcbiAgICAgICAgICB9LFxuICAgICAgICAgICdhaS5zY2hlbWEnOlxuICAgICAgICAgICAgb3V0cHV0U3RyYXRlZ3kuanNvblNjaGVtYSAhPSBudWxsXG4gICAgICAgICAgICAgID8geyBpbnB1dDogKCkgPT4gSlNPTi5zdHJpbmdpZnkob3V0cHV0U3RyYXRlZ3kuanNvblNjaGVtYSkgfVxuICAgICAgICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAnYWkuc2NoZW1hLm5hbWUnOiBzY2hlbWFOYW1lLFxuICAgICAgICAgICdhaS5zY2hlbWEuZGVzY3JpcHRpb24nOiBzY2hlbWFEZXNjcmlwdGlvbixcbiAgICAgICAgICAnYWkuc2V0dGluZ3Mub3V0cHV0Jzogb3V0cHV0U3RyYXRlZ3kudHlwZSxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgICAgdHJhY2VyLFxuICAgICAgZm46IGFzeW5jIHNwYW4gPT4ge1xuICAgICAgICBsZXQgcmVzdWx0OiBzdHJpbmc7XG4gICAgICAgIGxldCBmaW5pc2hSZWFzb246IEZpbmlzaFJlYXNvbjtcbiAgICAgICAgbGV0IHVzYWdlOiBMYW5ndWFnZU1vZGVsVXNhZ2U7XG4gICAgICAgIGxldCB3YXJuaW5nczogQ2FsbFdhcm5pbmdbXSB8IHVuZGVmaW5lZDtcbiAgICAgICAgbGV0IHJlc3BvbnNlOiBMYW5ndWFnZU1vZGVsUmVzcG9uc2VNZXRhZGF0YTtcbiAgICAgICAgbGV0IHJlcXVlc3Q6IExhbmd1YWdlTW9kZWxSZXF1ZXN0TWV0YWRhdGE7XG4gICAgICAgIGxldCByZXN1bHRQcm92aWRlck1ldGFkYXRhOiBQcm92aWRlck1ldGFkYXRhIHwgdW5kZWZpbmVkO1xuICAgICAgICBsZXQgcmVhc29uaW5nOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAgICAgY29uc3Qgc3RhbmRhcmRpemVkUHJvbXB0ID0gYXdhaXQgc3RhbmRhcmRpemVQcm9tcHQoe1xuICAgICAgICAgIHN5c3RlbSxcbiAgICAgICAgICBwcm9tcHQsXG4gICAgICAgICAgbWVzc2FnZXMsXG4gICAgICAgIH0gYXMgUHJvbXB0KTtcblxuICAgICAgICBjb25zdCBwcm9tcHRNZXNzYWdlcyA9IGF3YWl0IGNvbnZlcnRUb0xhbmd1YWdlTW9kZWxQcm9tcHQoe1xuICAgICAgICAgIHByb21wdDogc3RhbmRhcmRpemVkUHJvbXB0LFxuICAgICAgICAgIHN1cHBvcnRlZFVybHM6IGF3YWl0IG1vZGVsLnN1cHBvcnRlZFVybHMsXG4gICAgICAgICAgZG93bmxvYWQsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGdlbmVyYXRlUmVzdWx0ID0gYXdhaXQgcmV0cnkoKCkgPT5cbiAgICAgICAgICByZWNvcmRTcGFuKHtcbiAgICAgICAgICAgIG5hbWU6ICdhaS5nZW5lcmF0ZU9iamVjdC5kb0dlbmVyYXRlJyxcbiAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgICB0ZWxlbWV0cnksXG4gICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgICAgICAgICAuLi5hc3NlbWJsZU9wZXJhdGlvbk5hbWUoe1xuICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uSWQ6ICdhaS5nZW5lcmF0ZU9iamVjdC5kb0dlbmVyYXRlJyxcbiAgICAgICAgICAgICAgICAgIHRlbGVtZXRyeSxcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAuLi5iYXNlVGVsZW1ldHJ5QXR0cmlidXRlcyxcbiAgICAgICAgICAgICAgICAnYWkucHJvbXB0Lm1lc3NhZ2VzJzoge1xuICAgICAgICAgICAgICAgICAgaW5wdXQ6ICgpID0+IHN0cmluZ2lmeUZvclRlbGVtZXRyeShwcm9tcHRNZXNzYWdlcyksXG4gICAgICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgICAgIC8vIHN0YW5kYXJkaXplZCBnZW4tYWkgbGxtIHNwYW4gYXR0cmlidXRlczpcbiAgICAgICAgICAgICAgICAnZ2VuX2FpLnN5c3RlbSc6IG1vZGVsLnByb3ZpZGVyLFxuICAgICAgICAgICAgICAgICdnZW5fYWkucmVxdWVzdC5tb2RlbCc6IG1vZGVsLm1vZGVsSWQsXG4gICAgICAgICAgICAgICAgJ2dlbl9haS5yZXF1ZXN0LmZyZXF1ZW5jeV9wZW5hbHR5JzpcbiAgICAgICAgICAgICAgICAgIGNhbGxTZXR0aW5ncy5mcmVxdWVuY3lQZW5hbHR5LFxuICAgICAgICAgICAgICAgICdnZW5fYWkucmVxdWVzdC5tYXhfdG9rZW5zJzogY2FsbFNldHRpbmdzLm1heE91dHB1dFRva2VucyxcbiAgICAgICAgICAgICAgICAnZ2VuX2FpLnJlcXVlc3QucHJlc2VuY2VfcGVuYWx0eSc6IGNhbGxTZXR0aW5ncy5wcmVzZW5jZVBlbmFsdHksXG4gICAgICAgICAgICAgICAgJ2dlbl9haS5yZXF1ZXN0LnRlbXBlcmF0dXJlJzogY2FsbFNldHRpbmdzLnRlbXBlcmF0dXJlLFxuICAgICAgICAgICAgICAgICdnZW5fYWkucmVxdWVzdC50b3Bfayc6IGNhbGxTZXR0aW5ncy50b3BLLFxuICAgICAgICAgICAgICAgICdnZW5fYWkucmVxdWVzdC50b3BfcCc6IGNhbGxTZXR0aW5ncy50b3BQLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB0cmFjZXIsXG4gICAgICAgICAgICBmbjogYXN5bmMgc3BhbiA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IG1vZGVsLmRvR2VuZXJhdGUoe1xuICAgICAgICAgICAgICAgIHJlc3BvbnNlRm9ybWF0OiB7XG4gICAgICAgICAgICAgICAgICB0eXBlOiAnanNvbicsXG4gICAgICAgICAgICAgICAgICBzY2hlbWE6IG91dHB1dFN0cmF0ZWd5Lmpzb25TY2hlbWEsXG4gICAgICAgICAgICAgICAgICBuYW1lOiBzY2hlbWFOYW1lLFxuICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246IHNjaGVtYURlc2NyaXB0aW9uLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgLi4ucHJlcGFyZUNhbGxTZXR0aW5ncyhzZXR0aW5ncyksXG4gICAgICAgICAgICAgICAgcHJvbXB0OiBwcm9tcHRNZXNzYWdlcyxcbiAgICAgICAgICAgICAgICBwcm92aWRlck9wdGlvbnMsXG4gICAgICAgICAgICAgICAgYWJvcnRTaWduYWwsXG4gICAgICAgICAgICAgICAgaGVhZGVyczogaGVhZGVyc1dpdGhVc2VyQWdlbnQsXG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlRGF0YSA9IHtcbiAgICAgICAgICAgICAgICBpZDogcmVzdWx0LnJlc3BvbnNlPy5pZCA/PyBnZW5lcmF0ZUlkKCksXG4gICAgICAgICAgICAgICAgdGltZXN0YW1wOiByZXN1bHQucmVzcG9uc2U/LnRpbWVzdGFtcCA/PyBjdXJyZW50RGF0ZSgpLFxuICAgICAgICAgICAgICAgIG1vZGVsSWQ6IHJlc3VsdC5yZXNwb25zZT8ubW9kZWxJZCA/PyBtb2RlbC5tb2RlbElkLFxuICAgICAgICAgICAgICAgIGhlYWRlcnM6IHJlc3VsdC5yZXNwb25zZT8uaGVhZGVycyxcbiAgICAgICAgICAgICAgICBib2R5OiByZXN1bHQucmVzcG9uc2U/LmJvZHksXG4gICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgY29uc3QgdGV4dCA9IGV4dHJhY3RUZXh0Q29udGVudChyZXN1bHQuY29udGVudCk7XG4gICAgICAgICAgICAgIGNvbnN0IHJlYXNvbmluZyA9IGV4dHJhY3RSZWFzb25pbmdDb250ZW50KHJlc3VsdC5jb250ZW50KTtcblxuICAgICAgICAgICAgICBpZiAodGV4dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vT2JqZWN0R2VuZXJhdGVkRXJyb3Ioe1xuICAgICAgICAgICAgICAgICAgbWVzc2FnZTpcbiAgICAgICAgICAgICAgICAgICAgJ05vIG9iamVjdCBnZW5lcmF0ZWQ6IHRoZSBtb2RlbCBkaWQgbm90IHJldHVybiBhIHJlc3BvbnNlLicsXG4gICAgICAgICAgICAgICAgICByZXNwb25zZTogcmVzcG9uc2VEYXRhLFxuICAgICAgICAgICAgICAgICAgdXNhZ2U6IHJlc3VsdC51c2FnZSxcbiAgICAgICAgICAgICAgICAgIGZpbmlzaFJlYXNvbjogcmVzdWx0LmZpbmlzaFJlYXNvbixcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIC8vIEFkZCByZXNwb25zZSBpbmZvcm1hdGlvbiB0byB0aGUgc3BhbjpcbiAgICAgICAgICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGVzKFxuICAgICAgICAgICAgICAgIHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICAgICAgICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAgICAgICAgICAgICAnYWkucmVzcG9uc2UuZmluaXNoUmVhc29uJzogcmVzdWx0LmZpbmlzaFJlYXNvbixcbiAgICAgICAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLm9iamVjdCc6IHsgb3V0cHV0OiAoKSA9PiB0ZXh0IH0sXG4gICAgICAgICAgICAgICAgICAgICdhaS5yZXNwb25zZS5pZCc6IHJlc3BvbnNlRGF0YS5pZCxcbiAgICAgICAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLm1vZGVsJzogcmVzcG9uc2VEYXRhLm1vZGVsSWQsXG4gICAgICAgICAgICAgICAgICAgICdhaS5yZXNwb25zZS50aW1lc3RhbXAnOlxuICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlRGF0YS50aW1lc3RhbXAudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLnByb3ZpZGVyTWV0YWRhdGEnOiBKU09OLnN0cmluZ2lmeShcbiAgICAgICAgICAgICAgICAgICAgICByZXN1bHQucHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgICAgICAgICAgICAgKSxcblxuICAgICAgICAgICAgICAgICAgICAvLyBUT0RPIHJlbmFtZSB0ZWxlbWV0cnkgYXR0cmlidXRlcyB0byBpbnB1dFRva2VucyBhbmQgb3V0cHV0VG9rZW5zXG4gICAgICAgICAgICAgICAgICAgICdhaS51c2FnZS5wcm9tcHRUb2tlbnMnOiByZXN1bHQudXNhZ2UuaW5wdXRUb2tlbnMsXG4gICAgICAgICAgICAgICAgICAgICdhaS51c2FnZS5jb21wbGV0aW9uVG9rZW5zJzogcmVzdWx0LnVzYWdlLm91dHB1dFRva2VucyxcblxuICAgICAgICAgICAgICAgICAgICAvLyBzdGFuZGFyZGl6ZWQgZ2VuLWFpIGxsbSBzcGFuIGF0dHJpYnV0ZXM6XG4gICAgICAgICAgICAgICAgICAgICdnZW5fYWkucmVzcG9uc2UuZmluaXNoX3JlYXNvbnMnOiBbcmVzdWx0LmZpbmlzaFJlYXNvbl0sXG4gICAgICAgICAgICAgICAgICAgICdnZW5fYWkucmVzcG9uc2UuaWQnOiByZXNwb25zZURhdGEuaWQsXG4gICAgICAgICAgICAgICAgICAgICdnZW5fYWkucmVzcG9uc2UubW9kZWwnOiByZXNwb25zZURhdGEubW9kZWxJZCxcbiAgICAgICAgICAgICAgICAgICAgJ2dlbl9haS51c2FnZS5pbnB1dF90b2tlbnMnOiByZXN1bHQudXNhZ2UuaW5wdXRUb2tlbnMsXG4gICAgICAgICAgICAgICAgICAgICdnZW5fYWkudXNhZ2Uub3V0cHV0X3Rva2Vucyc6IHJlc3VsdC51c2FnZS5vdXRwdXRUb2tlbnMsXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgLi4ucmVzdWx0LFxuICAgICAgICAgICAgICAgIG9iamVjdFRleHQ6IHRleHQsXG4gICAgICAgICAgICAgICAgcmVhc29uaW5nLFxuICAgICAgICAgICAgICAgIHJlc3BvbnNlRGF0YSxcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG5cbiAgICAgICAgcmVzdWx0ID0gZ2VuZXJhdGVSZXN1bHQub2JqZWN0VGV4dDtcbiAgICAgICAgZmluaXNoUmVhc29uID0gZ2VuZXJhdGVSZXN1bHQuZmluaXNoUmVhc29uO1xuICAgICAgICB1c2FnZSA9IGdlbmVyYXRlUmVzdWx0LnVzYWdlO1xuICAgICAgICB3YXJuaW5ncyA9IGdlbmVyYXRlUmVzdWx0Lndhcm5pbmdzO1xuICAgICAgICByZXN1bHRQcm92aWRlck1ldGFkYXRhID0gZ2VuZXJhdGVSZXN1bHQucHJvdmlkZXJNZXRhZGF0YTtcbiAgICAgICAgcmVxdWVzdCA9IGdlbmVyYXRlUmVzdWx0LnJlcXVlc3QgPz8ge307XG4gICAgICAgIHJlc3BvbnNlID0gZ2VuZXJhdGVSZXN1bHQucmVzcG9uc2VEYXRhO1xuICAgICAgICByZWFzb25pbmcgPSBnZW5lcmF0ZVJlc3VsdC5yZWFzb25pbmc7XG5cbiAgICAgICAgbG9nV2FybmluZ3Mod2FybmluZ3MpO1xuXG4gICAgICAgIGNvbnN0IG9iamVjdCA9IGF3YWl0IHBhcnNlQW5kVmFsaWRhdGVPYmplY3RSZXN1bHRXaXRoUmVwYWlyKFxuICAgICAgICAgIHJlc3VsdCxcbiAgICAgICAgICBvdXRwdXRTdHJhdGVneSxcbiAgICAgICAgICByZXBhaXJUZXh0LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHJlc3BvbnNlLFxuICAgICAgICAgICAgdXNhZ2UsXG4gICAgICAgICAgICBmaW5pc2hSZWFzb24sXG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcblxuICAgICAgICAvLyBBZGQgcmVzcG9uc2UgaW5mb3JtYXRpb24gdG8gdGhlIHNwYW46XG4gICAgICAgIHNwYW4uc2V0QXR0cmlidXRlcyhcbiAgICAgICAgICBzZWxlY3RUZWxlbWV0cnlBdHRyaWJ1dGVzKHtcbiAgICAgICAgICAgIHRlbGVtZXRyeSxcbiAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLmZpbmlzaFJlYXNvbic6IGZpbmlzaFJlYXNvbixcbiAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLm9iamVjdCc6IHtcbiAgICAgICAgICAgICAgICBvdXRwdXQ6ICgpID0+IEpTT04uc3RyaW5naWZ5KG9iamVjdCksXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICdhaS5yZXNwb25zZS5wcm92aWRlck1ldGFkYXRhJzogSlNPTi5zdHJpbmdpZnkoXG4gICAgICAgICAgICAgICAgcmVzdWx0UHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgICAgICAgKSxcblxuICAgICAgICAgICAgICAvLyBUT0RPIHJlbmFtZSB0ZWxlbWV0cnkgYXR0cmlidXRlcyB0byBpbnB1dFRva2VucyBhbmQgb3V0cHV0VG9rZW5zXG4gICAgICAgICAgICAgICdhaS51c2FnZS5wcm9tcHRUb2tlbnMnOiB1c2FnZS5pbnB1dFRva2VucyxcbiAgICAgICAgICAgICAgJ2FpLnVzYWdlLmNvbXBsZXRpb25Ub2tlbnMnOiB1c2FnZS5vdXRwdXRUb2tlbnMsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuXG4gICAgICAgIHJldHVybiBuZXcgRGVmYXVsdEdlbmVyYXRlT2JqZWN0UmVzdWx0KHtcbiAgICAgICAgICBvYmplY3QsXG4gICAgICAgICAgcmVhc29uaW5nLFxuICAgICAgICAgIGZpbmlzaFJlYXNvbixcbiAgICAgICAgICB1c2FnZSxcbiAgICAgICAgICB3YXJuaW5ncyxcbiAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgIHJlc3BvbnNlLFxuICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHJlc3VsdFByb3ZpZGVyTWV0YWRhdGEsXG4gICAgICAgIH0pO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICB0aHJvdyB3cmFwR2F0ZXdheUVycm9yKGVycm9yKTtcbiAgfVxufVxuXG5jbGFzcyBEZWZhdWx0R2VuZXJhdGVPYmplY3RSZXN1bHQ8VD4gaW1wbGVtZW50cyBHZW5lcmF0ZU9iamVjdFJlc3VsdDxUPiB7XG4gIHJlYWRvbmx5IG9iamVjdDogR2VuZXJhdGVPYmplY3RSZXN1bHQ8VD5bJ29iamVjdCddO1xuICByZWFkb25seSBmaW5pc2hSZWFzb246IEdlbmVyYXRlT2JqZWN0UmVzdWx0PFQ+WydmaW5pc2hSZWFzb24nXTtcbiAgcmVhZG9ubHkgdXNhZ2U6IEdlbmVyYXRlT2JqZWN0UmVzdWx0PFQ+Wyd1c2FnZSddO1xuICByZWFkb25seSB3YXJuaW5nczogR2VuZXJhdGVPYmplY3RSZXN1bHQ8VD5bJ3dhcm5pbmdzJ107XG4gIHJlYWRvbmx5IHByb3ZpZGVyTWV0YWRhdGE6IEdlbmVyYXRlT2JqZWN0UmVzdWx0PFQ+Wydwcm92aWRlck1ldGFkYXRhJ107XG4gIHJlYWRvbmx5IHJlc3BvbnNlOiBHZW5lcmF0ZU9iamVjdFJlc3VsdDxUPlsncmVzcG9uc2UnXTtcbiAgcmVhZG9ubHkgcmVxdWVzdDogR2VuZXJhdGVPYmplY3RSZXN1bHQ8VD5bJ3JlcXVlc3QnXTtcbiAgcmVhZG9ubHkgcmVhc29uaW5nOiBHZW5lcmF0ZU9iamVjdFJlc3VsdDxUPlsncmVhc29uaW5nJ107XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczoge1xuICAgIG9iamVjdDogR2VuZXJhdGVPYmplY3RSZXN1bHQ8VD5bJ29iamVjdCddO1xuICAgIGZpbmlzaFJlYXNvbjogR2VuZXJhdGVPYmplY3RSZXN1bHQ8VD5bJ2ZpbmlzaFJlYXNvbiddO1xuICAgIHVzYWdlOiBHZW5lcmF0ZU9iamVjdFJlc3VsdDxUPlsndXNhZ2UnXTtcbiAgICB3YXJuaW5nczogR2VuZXJhdGVPYmplY3RSZXN1bHQ8VD5bJ3dhcm5pbmdzJ107XG4gICAgcHJvdmlkZXJNZXRhZGF0YTogR2VuZXJhdGVPYmplY3RSZXN1bHQ8VD5bJ3Byb3ZpZGVyTWV0YWRhdGEnXTtcbiAgICByZXNwb25zZTogR2VuZXJhdGVPYmplY3RSZXN1bHQ8VD5bJ3Jlc3BvbnNlJ107XG4gICAgcmVxdWVzdDogR2VuZXJhdGVPYmplY3RSZXN1bHQ8VD5bJ3JlcXVlc3QnXTtcbiAgICByZWFzb25pbmc6IEdlbmVyYXRlT2JqZWN0UmVzdWx0PFQ+WydyZWFzb25pbmcnXTtcbiAgfSkge1xuICAgIHRoaXMub2JqZWN0ID0gb3B0aW9ucy5vYmplY3Q7XG4gICAgdGhpcy5maW5pc2hSZWFzb24gPSBvcHRpb25zLmZpbmlzaFJlYXNvbjtcbiAgICB0aGlzLnVzYWdlID0gb3B0aW9ucy51c2FnZTtcbiAgICB0aGlzLndhcm5pbmdzID0gb3B0aW9ucy53YXJuaW5ncztcbiAgICB0aGlzLnByb3ZpZGVyTWV0YWRhdGEgPSBvcHRpb25zLnByb3ZpZGVyTWV0YWRhdGE7XG4gICAgdGhpcy5yZXNwb25zZSA9IG9wdGlvbnMucmVzcG9uc2U7XG4gICAgdGhpcy5yZXF1ZXN0ID0gb3B0aW9ucy5yZXF1ZXN0O1xuICAgIHRoaXMucmVhc29uaW5nID0gb3B0aW9ucy5yZWFzb25pbmc7XG4gIH1cblxuICB0b0pzb25SZXNwb25zZShpbml0PzogUmVzcG9uc2VJbml0KTogUmVzcG9uc2Uge1xuICAgIHJldHVybiBuZXcgUmVzcG9uc2UoSlNPTi5zdHJpbmdpZnkodGhpcy5vYmplY3QpLCB7XG4gICAgICBzdGF0dXM6IGluaXQ/LnN0YXR1cyA/PyAyMDAsXG4gICAgICBoZWFkZXJzOiBwcmVwYXJlSGVhZGVycyhpbml0Py5oZWFkZXJzLCB7XG4gICAgICAgICdjb250ZW50LXR5cGUnOiAnYXBwbGljYXRpb24vanNvbjsgY2hhcnNldD11dGYtOCcsXG4gICAgICB9KSxcbiAgICB9KTtcbiAgfVxufVxuIiwgImltcG9ydCB7XG4gIExhbmd1YWdlTW9kZWxWMkNvbnRlbnQsXG4gIExhbmd1YWdlTW9kZWxWMlJlYXNvbmluZyxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5cbmV4cG9ydCBmdW5jdGlvbiBleHRyYWN0UmVhc29uaW5nQ29udGVudChcbiAgY29udGVudDogTGFuZ3VhZ2VNb2RlbFYyQ29udGVudFtdLFxuKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgcGFydHMgPSBjb250ZW50LmZpbHRlcihcbiAgICAoY29udGVudCk6IGNvbnRlbnQgaXMgTGFuZ3VhZ2VNb2RlbFYyUmVhc29uaW5nID0+XG4gICAgICBjb250ZW50LnR5cGUgPT09ICdyZWFzb25pbmcnLFxuICApO1xuXG4gIHJldHVybiBwYXJ0cy5sZW5ndGggPT09IDBcbiAgICA/IHVuZGVmaW5lZFxuICAgIDogcGFydHMubWFwKGNvbnRlbnQgPT4gY29udGVudC50ZXh0KS5qb2luKCdcXG4nKTtcbn1cbiIsICJpbXBvcnQge1xuICBpc0pTT05BcnJheSxcbiAgaXNKU09OT2JqZWN0LFxuICBKU09OT2JqZWN0LFxuICBKU09OU2NoZW1hNyxcbiAgSlNPTlZhbHVlLFxuICBUeXBlVmFsaWRhdGlvbkVycm9yLFxuICBVbnN1cHBvcnRlZEZ1bmN0aW9uYWxpdHlFcnJvcixcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQge1xuICBhc1NjaGVtYSxcbiAgRmxleGlibGVTY2hlbWEsXG4gIHNhZmVWYWxpZGF0ZVR5cGVzLFxuICBTY2hlbWEsXG4gIFZhbGlkYXRpb25SZXN1bHQsXG59IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXItdXRpbHMnO1xuaW1wb3J0IHsgTm9PYmplY3RHZW5lcmF0ZWRFcnJvciB9IGZyb20gJy4uL2Vycm9yL25vLW9iamVjdC1nZW5lcmF0ZWQtZXJyb3InO1xuaW1wb3J0IHtcbiAgRmluaXNoUmVhc29uLFxuICBMYW5ndWFnZU1vZGVsUmVzcG9uc2VNZXRhZGF0YSxcbiAgTGFuZ3VhZ2VNb2RlbFVzYWdlLFxufSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQge1xuICBBc3luY0l0ZXJhYmxlU3RyZWFtLFxuICBjcmVhdGVBc3luY0l0ZXJhYmxlU3RyZWFtLFxufSBmcm9tICcuLi91dGlsL2FzeW5jLWl0ZXJhYmxlLXN0cmVhbSc7XG5pbXBvcnQgeyBEZWVwUGFydGlhbCB9IGZyb20gJy4uL3V0aWwvZGVlcC1wYXJ0aWFsJztcbmltcG9ydCB7IE9iamVjdFN0cmVhbVBhcnQgfSBmcm9tICcuL3N0cmVhbS1vYmplY3QtcmVzdWx0JztcblxuZXhwb3J0IGludGVyZmFjZSBPdXRwdXRTdHJhdGVneTxQQVJUSUFMLCBSRVNVTFQsIEVMRU1FTlRfU1RSRUFNPiB7XG4gIHJlYWRvbmx5IHR5cGU6ICdvYmplY3QnIHwgJ2FycmF5JyB8ICdlbnVtJyB8ICduby1zY2hlbWEnO1xuICByZWFkb25seSBqc29uU2NoZW1hOiBKU09OU2NoZW1hNyB8IHVuZGVmaW5lZDtcblxuICB2YWxpZGF0ZVBhcnRpYWxSZXN1bHQoe1xuICAgIHZhbHVlLFxuICAgIHRleHREZWx0YSxcbiAgICBpc0ZpbmFsRGVsdGEsXG4gIH06IHtcbiAgICB2YWx1ZTogSlNPTlZhbHVlO1xuICAgIHRleHREZWx0YTogc3RyaW5nO1xuICAgIGlzRmlyc3REZWx0YTogYm9vbGVhbjtcbiAgICBpc0ZpbmFsRGVsdGE6IGJvb2xlYW47XG4gICAgbGF0ZXN0T2JqZWN0OiBQQVJUSUFMIHwgdW5kZWZpbmVkO1xuICB9KTogUHJvbWlzZTxcbiAgICBWYWxpZGF0aW9uUmVzdWx0PHtcbiAgICAgIHBhcnRpYWw6IFBBUlRJQUw7XG4gICAgICB0ZXh0RGVsdGE6IHN0cmluZztcbiAgICB9PlxuICA+O1xuICB2YWxpZGF0ZUZpbmFsUmVzdWx0KFxuICAgIHZhbHVlOiBKU09OVmFsdWUgfCB1bmRlZmluZWQsXG4gICAgY29udGV4dDoge1xuICAgICAgdGV4dDogc3RyaW5nO1xuICAgICAgcmVzcG9uc2U6IExhbmd1YWdlTW9kZWxSZXNwb25zZU1ldGFkYXRhO1xuICAgICAgdXNhZ2U6IExhbmd1YWdlTW9kZWxVc2FnZTtcbiAgICB9LFxuICApOiBQcm9taXNlPFZhbGlkYXRpb25SZXN1bHQ8UkVTVUxUPj47XG5cbiAgY3JlYXRlRWxlbWVudFN0cmVhbShcbiAgICBvcmlnaW5hbFN0cmVhbTogUmVhZGFibGVTdHJlYW08T2JqZWN0U3RyZWFtUGFydDxQQVJUSUFMPj4sXG4gICk6IEVMRU1FTlRfU1RSRUFNO1xufVxuXG5jb25zdCBub1NjaGVtYU91dHB1dFN0cmF0ZWd5OiBPdXRwdXRTdHJhdGVneTxKU09OVmFsdWUsIEpTT05WYWx1ZSwgbmV2ZXI+ID0ge1xuICB0eXBlOiAnbm8tc2NoZW1hJyxcbiAganNvblNjaGVtYTogdW5kZWZpbmVkLFxuXG4gIGFzeW5jIHZhbGlkYXRlUGFydGlhbFJlc3VsdCh7IHZhbHVlLCB0ZXh0RGVsdGEgfSkge1xuICAgIHJldHVybiB7IHN1Y2Nlc3M6IHRydWUsIHZhbHVlOiB7IHBhcnRpYWw6IHZhbHVlLCB0ZXh0RGVsdGEgfSB9O1xuICB9LFxuXG4gIGFzeW5jIHZhbGlkYXRlRmluYWxSZXN1bHQoXG4gICAgdmFsdWU6IEpTT05WYWx1ZSB8IHVuZGVmaW5lZCxcbiAgICBjb250ZXh0OiB7XG4gICAgICB0ZXh0OiBzdHJpbmc7XG4gICAgICByZXNwb25zZTogTGFuZ3VhZ2VNb2RlbFJlc3BvbnNlTWV0YWRhdGE7XG4gICAgICB1c2FnZTogTGFuZ3VhZ2VNb2RlbFVzYWdlO1xuICAgICAgZmluaXNoUmVhc29uOiBGaW5pc2hSZWFzb247XG4gICAgfSxcbiAgKTogUHJvbWlzZTxWYWxpZGF0aW9uUmVzdWx0PEpTT05WYWx1ZT4+IHtcbiAgICByZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZFxuICAgICAgPyB7XG4gICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgZXJyb3I6IG5ldyBOb09iamVjdEdlbmVyYXRlZEVycm9yKHtcbiAgICAgICAgICAgIG1lc3NhZ2U6ICdObyBvYmplY3QgZ2VuZXJhdGVkOiByZXNwb25zZSBkaWQgbm90IG1hdGNoIHNjaGVtYS4nLFxuICAgICAgICAgICAgdGV4dDogY29udGV4dC50ZXh0LFxuICAgICAgICAgICAgcmVzcG9uc2U6IGNvbnRleHQucmVzcG9uc2UsXG4gICAgICAgICAgICB1c2FnZTogY29udGV4dC51c2FnZSxcbiAgICAgICAgICAgIGZpbmlzaFJlYXNvbjogY29udGV4dC5maW5pc2hSZWFzb24sXG4gICAgICAgICAgfSksXG4gICAgICAgIH1cbiAgICAgIDogeyBzdWNjZXNzOiB0cnVlLCB2YWx1ZSB9O1xuICB9LFxuXG4gIGNyZWF0ZUVsZW1lbnRTdHJlYW0oKSB7XG4gICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRnVuY3Rpb25hbGl0eUVycm9yKHtcbiAgICAgIGZ1bmN0aW9uYWxpdHk6ICdlbGVtZW50IHN0cmVhbXMgaW4gbm8tc2NoZW1hIG1vZGUnLFxuICAgIH0pO1xuICB9LFxufTtcblxuY29uc3Qgb2JqZWN0T3V0cHV0U3RyYXRlZ3kgPSA8T0JKRUNUPihcbiAgc2NoZW1hOiBTY2hlbWE8T0JKRUNUPixcbik6IE91dHB1dFN0cmF0ZWd5PERlZXBQYXJ0aWFsPE9CSkVDVD4sIE9CSkVDVCwgbmV2ZXI+ID0+ICh7XG4gIHR5cGU6ICdvYmplY3QnLFxuICBqc29uU2NoZW1hOiBzY2hlbWEuanNvblNjaGVtYSxcblxuICBhc3luYyB2YWxpZGF0ZVBhcnRpYWxSZXN1bHQoeyB2YWx1ZSwgdGV4dERlbHRhIH0pIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgIHZhbHVlOiB7XG4gICAgICAgIC8vIE5vdGU6IGN1cnJlbnRseSBubyB2YWxpZGF0aW9uIG9mIHBhcnRpYWwgcmVzdWx0czpcbiAgICAgICAgcGFydGlhbDogdmFsdWUgYXMgRGVlcFBhcnRpYWw8T0JKRUNUPixcbiAgICAgICAgdGV4dERlbHRhLFxuICAgICAgfSxcbiAgICB9O1xuICB9LFxuXG4gIGFzeW5jIHZhbGlkYXRlRmluYWxSZXN1bHQoXG4gICAgdmFsdWU6IEpTT05WYWx1ZSB8IHVuZGVmaW5lZCxcbiAgKTogUHJvbWlzZTxWYWxpZGF0aW9uUmVzdWx0PE9CSkVDVD4+IHtcbiAgICByZXR1cm4gc2FmZVZhbGlkYXRlVHlwZXMoeyB2YWx1ZSwgc2NoZW1hIH0pO1xuICB9LFxuXG4gIGNyZWF0ZUVsZW1lbnRTdHJlYW0oKSB7XG4gICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRnVuY3Rpb25hbGl0eUVycm9yKHtcbiAgICAgIGZ1bmN0aW9uYWxpdHk6ICdlbGVtZW50IHN0cmVhbXMgaW4gb2JqZWN0IG1vZGUnLFxuICAgIH0pO1xuICB9LFxufSk7XG5cbmNvbnN0IGFycmF5T3V0cHV0U3RyYXRlZ3kgPSA8RUxFTUVOVD4oXG4gIHNjaGVtYTogU2NoZW1hPEVMRU1FTlQ+LFxuKTogT3V0cHV0U3RyYXRlZ3k8RUxFTUVOVFtdLCBFTEVNRU5UW10sIEFzeW5jSXRlcmFibGVTdHJlYW08RUxFTUVOVD4+ID0+IHtcbiAgLy8gcmVtb3ZlICRzY2hlbWEgZnJvbSBzY2hlbWEuanNvblNjaGVtYTpcbiAgY29uc3QgeyAkc2NoZW1hLCAuLi5pdGVtU2NoZW1hIH0gPSBzY2hlbWEuanNvblNjaGVtYTtcblxuICByZXR1cm4ge1xuICAgIHR5cGU6ICdlbnVtJyxcblxuICAgIC8vIHdyYXAgaW4gb2JqZWN0IHRoYXQgY29udGFpbnMgYXJyYXkgb2YgZWxlbWVudHMsIHNpbmNlIG1vc3QgTExNcyB3aWxsIG5vdFxuICAgIC8vIGJlIGFibGUgdG8gZ2VuZXJhdGUgYW4gYXJyYXkgZGlyZWN0bHk6XG4gICAgLy8gcG9zc2libGUgZnV0dXJlIG9wdGltaXphdGlvbjogdXNlIGFycmF5cyBkaXJlY3RseSB3aGVuIG1vZGVsIHN1cHBvcnRzIGdyYW1tYXItZ3VpZGVkIGdlbmVyYXRpb25cbiAgICBqc29uU2NoZW1hOiB7XG4gICAgICAkc2NoZW1hOiAnaHR0cDovL2pzb24tc2NoZW1hLm9yZy9kcmFmdC0wNy9zY2hlbWEjJyxcbiAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBlbGVtZW50czogeyB0eXBlOiAnYXJyYXknLCBpdGVtczogaXRlbVNjaGVtYSB9LFxuICAgICAgfSxcbiAgICAgIHJlcXVpcmVkOiBbJ2VsZW1lbnRzJ10sXG4gICAgICBhZGRpdGlvbmFsUHJvcGVydGllczogZmFsc2UsXG4gICAgfSxcblxuICAgIGFzeW5jIHZhbGlkYXRlUGFydGlhbFJlc3VsdCh7XG4gICAgICB2YWx1ZSxcbiAgICAgIGxhdGVzdE9iamVjdCxcbiAgICAgIGlzRmlyc3REZWx0YSxcbiAgICAgIGlzRmluYWxEZWx0YSxcbiAgICB9KSB7XG4gICAgICAvLyBjaGVjayB0aGF0IHRoZSB2YWx1ZSBpcyBhbiBvYmplY3QgdGhhdCBjb250YWlucyBhbiBhcnJheSBvZiBlbGVtZW50czpcbiAgICAgIGlmICghaXNKU09OT2JqZWN0KHZhbHVlKSB8fCAhaXNKU09OQXJyYXkodmFsdWUuZWxlbWVudHMpKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgZXJyb3I6IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKHtcbiAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgY2F1c2U6ICd2YWx1ZSBtdXN0IGJlIGFuIG9iamVjdCB0aGF0IGNvbnRhaW5zIGFuIGFycmF5IG9mIGVsZW1lbnRzJyxcbiAgICAgICAgICB9KSxcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgaW5wdXRBcnJheSA9IHZhbHVlLmVsZW1lbnRzIGFzIEFycmF5PEpTT05PYmplY3Q+O1xuICAgICAgY29uc3QgcmVzdWx0QXJyYXk6IEFycmF5PEVMRU1FTlQ+ID0gW107XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXRBcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gaW5wdXRBcnJheVtpXTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc2FmZVZhbGlkYXRlVHlwZXMoeyB2YWx1ZTogZWxlbWVudCwgc2NoZW1hIH0pO1xuXG4gICAgICAgIC8vIHNwZWNpYWwgdHJlYXRtZW50IGZvciBsYXN0IHByb2Nlc3NlZCBlbGVtZW50OlxuICAgICAgICAvLyBpZ25vcmUgcGFyc2Ugb3IgdmFsaWRhdGlvbiBmYWlsdXJlcywgc2luY2UgdGhleSBpbmRpY2F0ZSB0aGF0IHRoZVxuICAgICAgICAvLyBsYXN0IGVsZW1lbnQgaXMgaW5jb21wbGV0ZSBhbmQgc2hvdWxkIG5vdCBiZSBpbmNsdWRlZCBpbiB0aGUgcmVzdWx0LFxuICAgICAgICAvLyB1bmxlc3MgaXQgaXMgdGhlIGZpbmFsIGRlbHRhXG4gICAgICAgIGlmIChpID09PSBpbnB1dEFycmF5Lmxlbmd0aCAtIDEgJiYgIWlzRmluYWxEZWx0YSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFyZXN1bHQuc3VjY2Vzcykge1xuICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXN1bHRBcnJheS5wdXNoKHJlc3VsdC52YWx1ZSk7XG4gICAgICB9XG5cbiAgICAgIC8vIGNhbGN1bGF0ZSBkZWx0YTpcbiAgICAgIGNvbnN0IHB1Ymxpc2hlZEVsZW1lbnRDb3VudCA9IGxhdGVzdE9iamVjdD8ubGVuZ3RoID8/IDA7XG5cbiAgICAgIGxldCB0ZXh0RGVsdGEgPSAnJztcblxuICAgICAgaWYgKGlzRmlyc3REZWx0YSkge1xuICAgICAgICB0ZXh0RGVsdGEgKz0gJ1snO1xuICAgICAgfVxuXG4gICAgICBpZiAocHVibGlzaGVkRWxlbWVudENvdW50ID4gMCkge1xuICAgICAgICB0ZXh0RGVsdGEgKz0gJywnO1xuICAgICAgfVxuXG4gICAgICB0ZXh0RGVsdGEgKz0gcmVzdWx0QXJyYXlcbiAgICAgICAgLnNsaWNlKHB1Ymxpc2hlZEVsZW1lbnRDb3VudCkgLy8gb25seSBuZXcgZWxlbWVudHNcbiAgICAgICAgLm1hcChlbGVtZW50ID0+IEpTT04uc3RyaW5naWZ5KGVsZW1lbnQpKVxuICAgICAgICAuam9pbignLCcpO1xuXG4gICAgICBpZiAoaXNGaW5hbERlbHRhKSB7XG4gICAgICAgIHRleHREZWx0YSArPSAnXSc7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgcGFydGlhbDogcmVzdWx0QXJyYXksXG4gICAgICAgICAgdGV4dERlbHRhLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9LFxuXG4gICAgYXN5bmMgdmFsaWRhdGVGaW5hbFJlc3VsdChcbiAgICAgIHZhbHVlOiBKU09OVmFsdWUgfCB1bmRlZmluZWQsXG4gICAgKTogUHJvbWlzZTxWYWxpZGF0aW9uUmVzdWx0PEFycmF5PEVMRU1FTlQ+Pj4ge1xuICAgICAgLy8gY2hlY2sgdGhhdCB0aGUgdmFsdWUgaXMgYW4gb2JqZWN0IHRoYXQgY29udGFpbnMgYW4gYXJyYXkgb2YgZWxlbWVudHM6XG4gICAgICBpZiAoIWlzSlNPTk9iamVjdCh2YWx1ZSkgfHwgIWlzSlNPTkFycmF5KHZhbHVlLmVsZW1lbnRzKSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgIGVycm9yOiBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcih7XG4gICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgIGNhdXNlOiAndmFsdWUgbXVzdCBiZSBhbiBvYmplY3QgdGhhdCBjb250YWlucyBhbiBhcnJheSBvZiBlbGVtZW50cycsXG4gICAgICAgICAgfSksXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGlucHV0QXJyYXkgPSB2YWx1ZS5lbGVtZW50cyBhcyBBcnJheTxKU09OT2JqZWN0PjtcblxuICAgICAgLy8gY2hlY2sgdGhhdCBlYWNoIGVsZW1lbnQgaW4gdGhlIGFycmF5IGlzIG9mIHRoZSBjb3JyZWN0IHR5cGU6XG4gICAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgaW5wdXRBcnJheSkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzYWZlVmFsaWRhdGVUeXBlcyh7IHZhbHVlOiBlbGVtZW50LCBzY2hlbWEgfSk7XG4gICAgICAgIGlmICghcmVzdWx0LnN1Y2Nlc3MpIHtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7IHN1Y2Nlc3M6IHRydWUsIHZhbHVlOiBpbnB1dEFycmF5IGFzIEFycmF5PEVMRU1FTlQ+IH07XG4gICAgfSxcblxuICAgIGNyZWF0ZUVsZW1lbnRTdHJlYW0oXG4gICAgICBvcmlnaW5hbFN0cmVhbTogUmVhZGFibGVTdHJlYW08T2JqZWN0U3RyZWFtUGFydDxFTEVNRU5UW10+PixcbiAgICApIHtcbiAgICAgIGxldCBwdWJsaXNoZWRFbGVtZW50cyA9IDA7XG5cbiAgICAgIHJldHVybiBjcmVhdGVBc3luY0l0ZXJhYmxlU3RyZWFtKFxuICAgICAgICBvcmlnaW5hbFN0cmVhbS5waXBlVGhyb3VnaChcbiAgICAgICAgICBuZXcgVHJhbnNmb3JtU3RyZWFtPE9iamVjdFN0cmVhbVBhcnQ8RUxFTUVOVFtdPiwgRUxFTUVOVD4oe1xuICAgICAgICAgICAgdHJhbnNmb3JtKGNodW5rLCBjb250cm9sbGVyKSB7XG4gICAgICAgICAgICAgIHN3aXRjaCAoY2h1bmsudHlwZSkge1xuICAgICAgICAgICAgICAgIGNhc2UgJ29iamVjdCc6IHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGFycmF5ID0gY2h1bmsub2JqZWN0O1xuXG4gICAgICAgICAgICAgICAgICAvLyBwdWJsaXNoIG5ldyBlbGVtZW50cyBvbmUgYnkgb25lOlxuICAgICAgICAgICAgICAgICAgZm9yIChcbiAgICAgICAgICAgICAgICAgICAgO1xuICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZWRFbGVtZW50cyA8IGFycmF5Lmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgcHVibGlzaGVkRWxlbWVudHMrK1xuICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShhcnJheVtwdWJsaXNoZWRFbGVtZW50c10pO1xuICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjYXNlICd0ZXh0LWRlbHRhJzpcbiAgICAgICAgICAgICAgICBjYXNlICdmaW5pc2gnOlxuICAgICAgICAgICAgICAgIGNhc2UgJ2Vycm9yJzogLy8gc3VwcHJlc3MgZXJyb3IgKHVzZSBvbkVycm9yIGluc3RlYWQpXG4gICAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IF9leGhhdXN0aXZlQ2hlY2s6IG5ldmVyID0gY2h1bms7XG4gICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIGBVbnN1cHBvcnRlZCBjaHVuayB0eXBlOiAke19leGhhdXN0aXZlQ2hlY2t9YCxcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pLFxuICAgICAgICApLFxuICAgICAgKTtcbiAgICB9LFxuICB9O1xufTtcblxuY29uc3QgZW51bU91dHB1dFN0cmF0ZWd5ID0gPEVOVU0gZXh0ZW5kcyBzdHJpbmc+KFxuICBlbnVtVmFsdWVzOiBBcnJheTxFTlVNPixcbik6IE91dHB1dFN0cmF0ZWd5PHN0cmluZywgRU5VTSwgbmV2ZXI+ID0+IHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAnZW51bScsXG5cbiAgICAvLyB3cmFwIGluIG9iamVjdCB0aGF0IGNvbnRhaW5zIHJlc3VsdCwgc2luY2UgbW9zdCBMTE1zIHdpbGwgbm90XG4gICAgLy8gYmUgYWJsZSB0byBnZW5lcmF0ZSBhbiBlbnVtIHZhbHVlIGRpcmVjdGx5OlxuICAgIC8vIHBvc3NpYmxlIGZ1dHVyZSBvcHRpbWl6YXRpb246IHVzZSBlbnVtcyBkaXJlY3RseSB3aGVuIG1vZGVsIHN1cHBvcnRzIHRvcC1sZXZlbCBlbnVtc1xuICAgIGpzb25TY2hlbWE6IHtcbiAgICAgICRzY2hlbWE6ICdodHRwOi8vanNvbi1zY2hlbWEub3JnL2RyYWZ0LTA3L3NjaGVtYSMnLFxuICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIHJlc3VsdDogeyB0eXBlOiAnc3RyaW5nJywgZW51bTogZW51bVZhbHVlcyB9LFxuICAgICAgfSxcbiAgICAgIHJlcXVpcmVkOiBbJ3Jlc3VsdCddLFxuICAgICAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlLFxuICAgIH0sXG5cbiAgICBhc3luYyB2YWxpZGF0ZUZpbmFsUmVzdWx0KFxuICAgICAgdmFsdWU6IEpTT05WYWx1ZSB8IHVuZGVmaW5lZCxcbiAgICApOiBQcm9taXNlPFZhbGlkYXRpb25SZXN1bHQ8RU5VTT4+IHtcbiAgICAgIC8vIGNoZWNrIHRoYXQgdGhlIHZhbHVlIGlzIGFuIG9iamVjdCB0aGF0IGNvbnRhaW5zIGFuIGFycmF5IG9mIGVsZW1lbnRzOlxuICAgICAgaWYgKCFpc0pTT05PYmplY3QodmFsdWUpIHx8IHR5cGVvZiB2YWx1ZS5yZXN1bHQgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgZXJyb3I6IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKHtcbiAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgY2F1c2U6XG4gICAgICAgICAgICAgICd2YWx1ZSBtdXN0IGJlIGFuIG9iamVjdCB0aGF0IGNvbnRhaW5zIGEgc3RyaW5nIGluIHRoZSBcInJlc3VsdFwiIHByb3BlcnR5LicsXG4gICAgICAgICAgfSksXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IHZhbHVlLnJlc3VsdCBhcyBzdHJpbmc7XG5cbiAgICAgIHJldHVybiBlbnVtVmFsdWVzLmluY2x1ZGVzKHJlc3VsdCBhcyBFTlVNKVxuICAgICAgICA/IHsgc3VjY2VzczogdHJ1ZSwgdmFsdWU6IHJlc3VsdCBhcyBFTlVNIH1cbiAgICAgICAgOiB7XG4gICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgIGVycm9yOiBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcih7XG4gICAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgICBjYXVzZTogJ3ZhbHVlIG11c3QgYmUgYSBzdHJpbmcgaW4gdGhlIGVudW0nLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgYXN5bmMgdmFsaWRhdGVQYXJ0aWFsUmVzdWx0KHsgdmFsdWUsIHRleHREZWx0YSB9KSB7XG4gICAgICBpZiAoIWlzSlNPTk9iamVjdCh2YWx1ZSkgfHwgdHlwZW9mIHZhbHVlLnJlc3VsdCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICBlcnJvcjogbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3Ioe1xuICAgICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgICBjYXVzZTpcbiAgICAgICAgICAgICAgJ3ZhbHVlIG11c3QgYmUgYW4gb2JqZWN0IHRoYXQgY29udGFpbnMgYSBzdHJpbmcgaW4gdGhlIFwicmVzdWx0XCIgcHJvcGVydHkuJyxcbiAgICAgICAgICB9KSxcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVzdWx0ID0gdmFsdWUucmVzdWx0IGFzIHN0cmluZztcbiAgICAgIGNvbnN0IHBvc3NpYmxlRW51bVZhbHVlcyA9IGVudW1WYWx1ZXMuZmlsdGVyKGVudW1WYWx1ZSA9PlxuICAgICAgICBlbnVtVmFsdWUuc3RhcnRzV2l0aChyZXN1bHQpLFxuICAgICAgKTtcblxuICAgICAgaWYgKHZhbHVlLnJlc3VsdC5sZW5ndGggPT09IDAgfHwgcG9zc2libGVFbnVtVmFsdWVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgIGVycm9yOiBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcih7XG4gICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgIGNhdXNlOiAndmFsdWUgbXVzdCBiZSBhIHN0cmluZyBpbiB0aGUgZW51bScsXG4gICAgICAgICAgfSksXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgcGFydGlhbDpcbiAgICAgICAgICAgIHBvc3NpYmxlRW51bVZhbHVlcy5sZW5ndGggPiAxID8gcmVzdWx0IDogcG9zc2libGVFbnVtVmFsdWVzWzBdLFxuICAgICAgICAgIHRleHREZWx0YSxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfSxcblxuICAgIGNyZWF0ZUVsZW1lbnRTdHJlYW0oKSB7XG4gICAgICAvLyBubyBzdHJlYW1pbmcgaW4gZW51bSBtb2RlXG4gICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRGdW5jdGlvbmFsaXR5RXJyb3Ioe1xuICAgICAgICBmdW5jdGlvbmFsaXR5OiAnZWxlbWVudCBzdHJlYW1zIGluIGVudW0gbW9kZScsXG4gICAgICB9KTtcbiAgICB9LFxuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldE91dHB1dFN0cmF0ZWd5PFNDSEVNQT4oe1xuICBvdXRwdXQsXG4gIHNjaGVtYSxcbiAgZW51bVZhbHVlcyxcbn06IHtcbiAgb3V0cHV0OiAnb2JqZWN0JyB8ICdhcnJheScgfCAnZW51bScgfCAnbm8tc2NoZW1hJztcbiAgc2NoZW1hPzogRmxleGlibGVTY2hlbWE8U0NIRU1BPjtcbiAgZW51bVZhbHVlcz86IEFycmF5PFNDSEVNQT47XG59KTogT3V0cHV0U3RyYXRlZ3k8YW55LCBhbnksIGFueT4ge1xuICBzd2l0Y2ggKG91dHB1dCkge1xuICAgIGNhc2UgJ29iamVjdCc6XG4gICAgICByZXR1cm4gb2JqZWN0T3V0cHV0U3RyYXRlZ3koYXNTY2hlbWEoc2NoZW1hISkpO1xuICAgIGNhc2UgJ2FycmF5JzpcbiAgICAgIHJldHVybiBhcnJheU91dHB1dFN0cmF0ZWd5KGFzU2NoZW1hKHNjaGVtYSEpKTtcbiAgICBjYXNlICdlbnVtJzpcbiAgICAgIHJldHVybiBlbnVtT3V0cHV0U3RyYXRlZ3koZW51bVZhbHVlcyEgYXMgQXJyYXk8c3RyaW5nPik7XG4gICAgY2FzZSAnbm8tc2NoZW1hJzpcbiAgICAgIHJldHVybiBub1NjaGVtYU91dHB1dFN0cmF0ZWd5O1xuICAgIGRlZmF1bHQ6IHtcbiAgICAgIGNvbnN0IF9leGhhdXN0aXZlQ2hlY2s6IG5ldmVyID0gb3V0cHV0O1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBvdXRwdXQ6ICR7X2V4aGF1c3RpdmVDaGVja31gKTtcbiAgICB9XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBKU09OUGFyc2VFcnJvciwgVHlwZVZhbGlkYXRpb25FcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgc2FmZVBhcnNlSlNPTiB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXItdXRpbHMnO1xuaW1wb3J0IHsgTm9PYmplY3RHZW5lcmF0ZWRFcnJvciB9IGZyb20gJy4uL2Vycm9yL25vLW9iamVjdC1nZW5lcmF0ZWQtZXJyb3InO1xuaW1wb3J0IHR5cGUge1xuICBGaW5pc2hSZWFzb24sXG4gIExhbmd1YWdlTW9kZWxSZXNwb25zZU1ldGFkYXRhLFxuICBMYW5ndWFnZU1vZGVsVXNhZ2UsXG59IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB0eXBlIHsgT3V0cHV0U3RyYXRlZ3kgfSBmcm9tICcuL291dHB1dC1zdHJhdGVneSc7XG5pbXBvcnQgeyBSZXBhaXJUZXh0RnVuY3Rpb24gfSBmcm9tICcuL3JlcGFpci10ZXh0JztcblxuLyoqXG4gKiBQYXJzZXMgYW5kIHZhbGlkYXRlcyBhIHJlc3VsdCBzdHJpbmcgYnkgcGFyc2luZyBpdCBhcyBKU09OIGFuZCB2YWxpZGF0aW5nIGFnYWluc3QgdGhlIG91dHB1dCBzdHJhdGVneS5cbiAqXG4gKiBAcGFyYW0gcmVzdWx0IC0gVGhlIHJlc3VsdCBzdHJpbmcgdG8gcGFyc2UgYW5kIHZhbGlkYXRlXG4gKiBAcGFyYW0gb3V0cHV0U3RyYXRlZ3kgLSBUaGUgb3V0cHV0IHN0cmF0ZWd5IGNvbnRhaW5pbmcgdmFsaWRhdGlvbiBsb2dpY1xuICogQHBhcmFtIGNvbnRleHQgLSBBZGRpdGlvbmFsIGNvbnRleHQgZm9yIGVycm9yIHJlcG9ydGluZ1xuICogQHJldHVybnMgVGhlIHZhbGlkYXRlZCByZXN1bHRcbiAqIEB0aHJvd3MgTm9PYmplY3RHZW5lcmF0ZWRFcnJvciBpZiBwYXJzaW5nIG9yIHZhbGlkYXRpb24gZmFpbHNcbiAqL1xuYXN5bmMgZnVuY3Rpb24gcGFyc2VBbmRWYWxpZGF0ZU9iamVjdFJlc3VsdDxSRVNVTFQ+KFxuICByZXN1bHQ6IHN0cmluZyxcbiAgb3V0cHV0U3RyYXRlZ3k6IE91dHB1dFN0cmF0ZWd5PGFueSwgUkVTVUxULCBhbnk+LFxuICBjb250ZXh0OiB7XG4gICAgcmVzcG9uc2U6IExhbmd1YWdlTW9kZWxSZXNwb25zZU1ldGFkYXRhO1xuICAgIHVzYWdlOiBMYW5ndWFnZU1vZGVsVXNhZ2U7XG4gICAgZmluaXNoUmVhc29uOiBGaW5pc2hSZWFzb247XG4gIH0sXG4pOiBQcm9taXNlPFJFU1VMVD4ge1xuICBjb25zdCBwYXJzZVJlc3VsdCA9IGF3YWl0IHNhZmVQYXJzZUpTT04oeyB0ZXh0OiByZXN1bHQgfSk7XG5cbiAgaWYgKCFwYXJzZVJlc3VsdC5zdWNjZXNzKSB7XG4gICAgdGhyb3cgbmV3IE5vT2JqZWN0R2VuZXJhdGVkRXJyb3Ioe1xuICAgICAgbWVzc2FnZTogJ05vIG9iamVjdCBnZW5lcmF0ZWQ6IGNvdWxkIG5vdCBwYXJzZSB0aGUgcmVzcG9uc2UuJyxcbiAgICAgIGNhdXNlOiBwYXJzZVJlc3VsdC5lcnJvcixcbiAgICAgIHRleHQ6IHJlc3VsdCxcbiAgICAgIHJlc3BvbnNlOiBjb250ZXh0LnJlc3BvbnNlLFxuICAgICAgdXNhZ2U6IGNvbnRleHQudXNhZ2UsXG4gICAgICBmaW5pc2hSZWFzb246IGNvbnRleHQuZmluaXNoUmVhc29uLFxuICAgIH0pO1xuICB9XG5cbiAgY29uc3QgdmFsaWRhdGlvblJlc3VsdCA9IGF3YWl0IG91dHB1dFN0cmF0ZWd5LnZhbGlkYXRlRmluYWxSZXN1bHQoXG4gICAgcGFyc2VSZXN1bHQudmFsdWUsXG4gICAge1xuICAgICAgdGV4dDogcmVzdWx0LFxuICAgICAgcmVzcG9uc2U6IGNvbnRleHQucmVzcG9uc2UsXG4gICAgICB1c2FnZTogY29udGV4dC51c2FnZSxcbiAgICB9LFxuICApO1xuXG4gIGlmICghdmFsaWRhdGlvblJlc3VsdC5zdWNjZXNzKSB7XG4gICAgdGhyb3cgbmV3IE5vT2JqZWN0R2VuZXJhdGVkRXJyb3Ioe1xuICAgICAgbWVzc2FnZTogJ05vIG9iamVjdCBnZW5lcmF0ZWQ6IHJlc3BvbnNlIGRpZCBub3QgbWF0Y2ggc2NoZW1hLicsXG4gICAgICBjYXVzZTogdmFsaWRhdGlvblJlc3VsdC5lcnJvcixcbiAgICAgIHRleHQ6IHJlc3VsdCxcbiAgICAgIHJlc3BvbnNlOiBjb250ZXh0LnJlc3BvbnNlLFxuICAgICAgdXNhZ2U6IGNvbnRleHQudXNhZ2UsXG4gICAgICBmaW5pc2hSZWFzb246IGNvbnRleHQuZmluaXNoUmVhc29uLFxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHZhbGlkYXRpb25SZXN1bHQudmFsdWU7XG59XG5cbi8qKlxuICogUGFyc2VzIGFuZCB2YWxpZGF0ZXMgYSByZXN1bHQgc3RyaW5nIGJ5IHBhcnNpbmcgaXQgYXMgSlNPTiBhbmQgdmFsaWRhdGluZyBhZ2FpbnN0IHRoZSBvdXRwdXQgc3RyYXRlZ3kuXG4gKiBJZiB0aGUgcmVzdWx0IGNhbm5vdCBiZSBwYXJzZWQsIGl0IGF0dGVtcHRzIHRvIHJlcGFpciB0aGUgcmVzdWx0IHVzaW5nIHRoZSByZXBhaXJUZXh0IGZ1bmN0aW9uLlxuICpcbiAqIEBwYXJhbSByZXN1bHQgLSBUaGUgcmVzdWx0IHN0cmluZyB0byBwYXJzZSBhbmQgdmFsaWRhdGVcbiAqIEBwYXJhbSBvdXRwdXRTdHJhdGVneSAtIFRoZSBvdXRwdXQgc3RyYXRlZ3kgY29udGFpbmluZyB2YWxpZGF0aW9uIGxvZ2ljXG4gKiBAcGFyYW0gcmVwYWlyVGV4dCAtIEEgZnVuY3Rpb24gdGhhdCBhdHRlbXB0cyB0byByZXBhaXIgdGhlIHJlc3VsdCBzdHJpbmdcbiAqIEBwYXJhbSBjb250ZXh0IC0gQWRkaXRpb25hbCBjb250ZXh0IGZvciBlcnJvciByZXBvcnRpbmdcbiAqIEByZXR1cm5zIFRoZSB2YWxpZGF0ZWQgcmVzdWx0XG4gKiBAdGhyb3dzIE5vT2JqZWN0R2VuZXJhdGVkRXJyb3IgaWYgcGFyc2luZyBvciB2YWxpZGF0aW9uIGZhaWxzXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwYXJzZUFuZFZhbGlkYXRlT2JqZWN0UmVzdWx0V2l0aFJlcGFpcjxSRVNVTFQ+KFxuICByZXN1bHQ6IHN0cmluZyxcbiAgb3V0cHV0U3RyYXRlZ3k6IE91dHB1dFN0cmF0ZWd5PGFueSwgUkVTVUxULCBhbnk+LFxuICByZXBhaXJUZXh0OiBSZXBhaXJUZXh0RnVuY3Rpb24gfCB1bmRlZmluZWQsXG4gIGNvbnRleHQ6IHtcbiAgICByZXNwb25zZTogTGFuZ3VhZ2VNb2RlbFJlc3BvbnNlTWV0YWRhdGE7XG4gICAgdXNhZ2U6IExhbmd1YWdlTW9kZWxVc2FnZTtcbiAgICBmaW5pc2hSZWFzb246IEZpbmlzaFJlYXNvbjtcbiAgfSxcbik6IFByb21pc2U8UkVTVUxUPiB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGF3YWl0IHBhcnNlQW5kVmFsaWRhdGVPYmplY3RSZXN1bHQocmVzdWx0LCBvdXRwdXRTdHJhdGVneSwgY29udGV4dCk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgaWYgKFxuICAgICAgcmVwYWlyVGV4dCAhPSBudWxsICYmXG4gICAgICBOb09iamVjdEdlbmVyYXRlZEVycm9yLmlzSW5zdGFuY2UoZXJyb3IpICYmXG4gICAgICAoSlNPTlBhcnNlRXJyb3IuaXNJbnN0YW5jZShlcnJvci5jYXVzZSkgfHxcbiAgICAgICAgVHlwZVZhbGlkYXRpb25FcnJvci5pc0luc3RhbmNlKGVycm9yLmNhdXNlKSlcbiAgICApIHtcbiAgICAgIGNvbnN0IHJlcGFpcmVkVGV4dCA9IGF3YWl0IHJlcGFpclRleHQoe1xuICAgICAgICB0ZXh0OiByZXN1bHQsXG4gICAgICAgIGVycm9yOiBlcnJvci5jYXVzZSxcbiAgICAgIH0pO1xuICAgICAgaWYgKHJlcGFpcmVkVGV4dCA9PT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhd2FpdCBwYXJzZUFuZFZhbGlkYXRlT2JqZWN0UmVzdWx0KFxuICAgICAgICByZXBhaXJlZFRleHQsXG4gICAgICAgIG91dHB1dFN0cmF0ZWd5LFxuICAgICAgICBjb250ZXh0LFxuICAgICAgKTtcbiAgICB9XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBGbGV4aWJsZVNjaGVtYSB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXItdXRpbHMnO1xuaW1wb3J0IHsgSW52YWxpZEFyZ3VtZW50RXJyb3IgfSBmcm9tICcuLi9lcnJvci9pbnZhbGlkLWFyZ3VtZW50LWVycm9yJztcblxuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlT2JqZWN0R2VuZXJhdGlvbklucHV0KHtcbiAgb3V0cHV0LFxuICBzY2hlbWEsXG4gIHNjaGVtYU5hbWUsXG4gIHNjaGVtYURlc2NyaXB0aW9uLFxuICBlbnVtVmFsdWVzLFxufToge1xuICBvdXRwdXQ/OiAnb2JqZWN0JyB8ICdhcnJheScgfCAnZW51bScgfCAnbm8tc2NoZW1hJztcbiAgc2NoZW1hPzogRmxleGlibGVTY2hlbWE8dW5rbm93bj47XG4gIHNjaGVtYU5hbWU/OiBzdHJpbmc7XG4gIHNjaGVtYURlc2NyaXB0aW9uPzogc3RyaW5nO1xuICBlbnVtVmFsdWVzPzogQXJyYXk8dW5rbm93bj47XG59KSB7XG4gIGlmIChcbiAgICBvdXRwdXQgIT0gbnVsbCAmJlxuICAgIG91dHB1dCAhPT0gJ29iamVjdCcgJiZcbiAgICBvdXRwdXQgIT09ICdhcnJheScgJiZcbiAgICBvdXRwdXQgIT09ICdlbnVtJyAmJlxuICAgIG91dHB1dCAhPT0gJ25vLXNjaGVtYSdcbiAgKSB7XG4gICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEVycm9yKHtcbiAgICAgIHBhcmFtZXRlcjogJ291dHB1dCcsXG4gICAgICB2YWx1ZTogb3V0cHV0LFxuICAgICAgbWVzc2FnZTogJ0ludmFsaWQgb3V0cHV0IHR5cGUuJyxcbiAgICB9KTtcbiAgfVxuXG4gIGlmIChvdXRwdXQgPT09ICduby1zY2hlbWEnKSB7XG4gICAgaWYgKHNjaGVtYSAhPSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3Ioe1xuICAgICAgICBwYXJhbWV0ZXI6ICdzY2hlbWEnLFxuICAgICAgICB2YWx1ZTogc2NoZW1hLFxuICAgICAgICBtZXNzYWdlOiAnU2NoZW1hIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIG5vLXNjaGVtYSBvdXRwdXQuJyxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChzY2hlbWFEZXNjcmlwdGlvbiAhPSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3Ioe1xuICAgICAgICBwYXJhbWV0ZXI6ICdzY2hlbWFEZXNjcmlwdGlvbicsXG4gICAgICAgIHZhbHVlOiBzY2hlbWFEZXNjcmlwdGlvbixcbiAgICAgICAgbWVzc2FnZTogJ1NjaGVtYSBkZXNjcmlwdGlvbiBpcyBub3Qgc3VwcG9ydGVkIGZvciBuby1zY2hlbWEgb3V0cHV0LicsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoc2NoZW1hTmFtZSAhPSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3Ioe1xuICAgICAgICBwYXJhbWV0ZXI6ICdzY2hlbWFOYW1lJyxcbiAgICAgICAgdmFsdWU6IHNjaGVtYU5hbWUsXG4gICAgICAgIG1lc3NhZ2U6ICdTY2hlbWEgbmFtZSBpcyBub3Qgc3VwcG9ydGVkIGZvciBuby1zY2hlbWEgb3V0cHV0LicsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoZW51bVZhbHVlcyAhPSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3Ioe1xuICAgICAgICBwYXJhbWV0ZXI6ICdlbnVtVmFsdWVzJyxcbiAgICAgICAgdmFsdWU6IGVudW1WYWx1ZXMsXG4gICAgICAgIG1lc3NhZ2U6ICdFbnVtIHZhbHVlcyBhcmUgbm90IHN1cHBvcnRlZCBmb3Igbm8tc2NoZW1hIG91dHB1dC4nLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgaWYgKG91dHB1dCA9PT0gJ29iamVjdCcpIHtcbiAgICBpZiAoc2NoZW1hID09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFcnJvcih7XG4gICAgICAgIHBhcmFtZXRlcjogJ3NjaGVtYScsXG4gICAgICAgIHZhbHVlOiBzY2hlbWEsXG4gICAgICAgIG1lc3NhZ2U6ICdTY2hlbWEgaXMgcmVxdWlyZWQgZm9yIG9iamVjdCBvdXRwdXQuJyxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChlbnVtVmFsdWVzICE9IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFcnJvcih7XG4gICAgICAgIHBhcmFtZXRlcjogJ2VudW1WYWx1ZXMnLFxuICAgICAgICB2YWx1ZTogZW51bVZhbHVlcyxcbiAgICAgICAgbWVzc2FnZTogJ0VudW0gdmFsdWVzIGFyZSBub3Qgc3VwcG9ydGVkIGZvciBvYmplY3Qgb3V0cHV0LicsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBpZiAob3V0cHV0ID09PSAnYXJyYXknKSB7XG4gICAgaWYgKHNjaGVtYSA9PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3Ioe1xuICAgICAgICBwYXJhbWV0ZXI6ICdzY2hlbWEnLFxuICAgICAgICB2YWx1ZTogc2NoZW1hLFxuICAgICAgICBtZXNzYWdlOiAnRWxlbWVudCBzY2hlbWEgaXMgcmVxdWlyZWQgZm9yIGFycmF5IG91dHB1dC4nLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKGVudW1WYWx1ZXMgIT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEVycm9yKHtcbiAgICAgICAgcGFyYW1ldGVyOiAnZW51bVZhbHVlcycsXG4gICAgICAgIHZhbHVlOiBlbnVtVmFsdWVzLFxuICAgICAgICBtZXNzYWdlOiAnRW51bSB2YWx1ZXMgYXJlIG5vdCBzdXBwb3J0ZWQgZm9yIGFycmF5IG91dHB1dC4nLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgaWYgKG91dHB1dCA9PT0gJ2VudW0nKSB7XG4gICAgaWYgKHNjaGVtYSAhPSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3Ioe1xuICAgICAgICBwYXJhbWV0ZXI6ICdzY2hlbWEnLFxuICAgICAgICB2YWx1ZTogc2NoZW1hLFxuICAgICAgICBtZXNzYWdlOiAnU2NoZW1hIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIGVudW0gb3V0cHV0LicsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoc2NoZW1hRGVzY3JpcHRpb24gIT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEVycm9yKHtcbiAgICAgICAgcGFyYW1ldGVyOiAnc2NoZW1hRGVzY3JpcHRpb24nLFxuICAgICAgICB2YWx1ZTogc2NoZW1hRGVzY3JpcHRpb24sXG4gICAgICAgIG1lc3NhZ2U6ICdTY2hlbWEgZGVzY3JpcHRpb24gaXMgbm90IHN1cHBvcnRlZCBmb3IgZW51bSBvdXRwdXQuJyxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChzY2hlbWFOYW1lICE9IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFcnJvcih7XG4gICAgICAgIHBhcmFtZXRlcjogJ3NjaGVtYU5hbWUnLFxuICAgICAgICB2YWx1ZTogc2NoZW1hTmFtZSxcbiAgICAgICAgbWVzc2FnZTogJ1NjaGVtYSBuYW1lIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIGVudW0gb3V0cHV0LicsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoZW51bVZhbHVlcyA9PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3Ioe1xuICAgICAgICBwYXJhbWV0ZXI6ICdlbnVtVmFsdWVzJyxcbiAgICAgICAgdmFsdWU6IGVudW1WYWx1ZXMsXG4gICAgICAgIG1lc3NhZ2U6ICdFbnVtIHZhbHVlcyBhcmUgcmVxdWlyZWQgZm9yIGVudW0gb3V0cHV0LicsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHZhbHVlIG9mIGVudW1WYWx1ZXMpIHtcbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFcnJvcih7XG4gICAgICAgICAgcGFyYW1ldGVyOiAnZW51bVZhbHVlcycsXG4gICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgbWVzc2FnZTogJ0VudW0gdmFsdWVzIG11c3QgYmUgc3RyaW5ncy4nLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbiIsICJpbXBvcnQge1xuICBKU09OVmFsdWUsXG4gIExhbmd1YWdlTW9kZWxWMkNhbGxXYXJuaW5nLFxuICBMYW5ndWFnZU1vZGVsVjJGaW5pc2hSZWFzb24sXG4gIExhbmd1YWdlTW9kZWxWMlN0cmVhbVBhcnQsXG4gIExhbmd1YWdlTW9kZWxWMlVzYWdlLFxuICBTaGFyZWRWMlByb3ZpZGVyTWV0YWRhdGEsXG59IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHtcbiAgY3JlYXRlSWRHZW5lcmF0b3IsXG4gIEZsZXhpYmxlU2NoZW1hLFxuICBQcm92aWRlck9wdGlvbnMsXG4gIHR5cGUgSW5mZXJTY2hlbWEsXG59IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXItdXRpbHMnO1xuaW1wb3J0IHsgU2VydmVyUmVzcG9uc2UgfSBmcm9tICdodHRwJztcbmltcG9ydCB7IGxvZ1dhcm5pbmdzIH0gZnJvbSAnLi4vbG9nZ2VyL2xvZy13YXJuaW5ncyc7XG5pbXBvcnQgeyByZXNvbHZlTGFuZ3VhZ2VNb2RlbCB9IGZyb20gJy4uL21vZGVsL3Jlc29sdmUtbW9kZWwnO1xuaW1wb3J0IHsgQ2FsbFNldHRpbmdzIH0gZnJvbSAnLi4vcHJvbXB0L2NhbGwtc2V0dGluZ3MnO1xuaW1wb3J0IHsgY29udmVydFRvTGFuZ3VhZ2VNb2RlbFByb21wdCB9IGZyb20gJy4uL3Byb21wdC9jb252ZXJ0LXRvLWxhbmd1YWdlLW1vZGVsLXByb21wdCc7XG5pbXBvcnQgeyBwcmVwYXJlQ2FsbFNldHRpbmdzIH0gZnJvbSAnLi4vcHJvbXB0L3ByZXBhcmUtY2FsbC1zZXR0aW5ncyc7XG5pbXBvcnQgeyBQcm9tcHQgfSBmcm9tICcuLi9wcm9tcHQvcHJvbXB0JztcbmltcG9ydCB7IHN0YW5kYXJkaXplUHJvbXB0IH0gZnJvbSAnLi4vcHJvbXB0L3N0YW5kYXJkaXplLXByb21wdCc7XG5pbXBvcnQgeyB3cmFwR2F0ZXdheUVycm9yIH0gZnJvbSAnLi4vcHJvbXB0L3dyYXAtZ2F0ZXdheS1lcnJvcic7XG5pbXBvcnQgeyBhc3NlbWJsZU9wZXJhdGlvbk5hbWUgfSBmcm9tICcuLi90ZWxlbWV0cnkvYXNzZW1ibGUtb3BlcmF0aW9uLW5hbWUnO1xuaW1wb3J0IHsgZ2V0QmFzZVRlbGVtZXRyeUF0dHJpYnV0ZXMgfSBmcm9tICcuLi90ZWxlbWV0cnkvZ2V0LWJhc2UtdGVsZW1ldHJ5LWF0dHJpYnV0ZXMnO1xuaW1wb3J0IHsgZ2V0VHJhY2VyIH0gZnJvbSAnLi4vdGVsZW1ldHJ5L2dldC10cmFjZXInO1xuaW1wb3J0IHsgcmVjb3JkU3BhbiB9IGZyb20gJy4uL3RlbGVtZXRyeS9yZWNvcmQtc3Bhbic7XG5pbXBvcnQgeyBzZWxlY3RUZWxlbWV0cnlBdHRyaWJ1dGVzIH0gZnJvbSAnLi4vdGVsZW1ldHJ5L3NlbGVjdC10ZWxlbWV0cnktYXR0cmlidXRlcyc7XG5pbXBvcnQgeyBzdHJpbmdpZnlGb3JUZWxlbWV0cnkgfSBmcm9tICcuLi90ZWxlbWV0cnkvc3RyaW5naWZ5LWZvci10ZWxlbWV0cnknO1xuaW1wb3J0IHsgVGVsZW1ldHJ5U2V0dGluZ3MgfSBmcm9tICcuLi90ZWxlbWV0cnkvdGVsZW1ldHJ5LXNldHRpbmdzJztcbmltcG9ydCB7IGNyZWF0ZVRleHRTdHJlYW1SZXNwb25zZSB9IGZyb20gJy4uL3RleHQtc3RyZWFtL2NyZWF0ZS10ZXh0LXN0cmVhbS1yZXNwb25zZSc7XG5pbXBvcnQgeyBwaXBlVGV4dFN0cmVhbVRvUmVzcG9uc2UgfSBmcm9tICcuLi90ZXh0LXN0cmVhbS9waXBlLXRleHQtc3RyZWFtLXRvLXJlc3BvbnNlJztcbmltcG9ydCB7XG4gIENhbGxXYXJuaW5nLFxuICBGaW5pc2hSZWFzb24sXG4gIExhbmd1YWdlTW9kZWwsXG59IGZyb20gJy4uL3R5cGVzL2xhbmd1YWdlLW1vZGVsJztcbmltcG9ydCB7IExhbmd1YWdlTW9kZWxSZXF1ZXN0TWV0YWRhdGEgfSBmcm9tICcuLi90eXBlcy9sYW5ndWFnZS1tb2RlbC1yZXF1ZXN0LW1ldGFkYXRhJztcbmltcG9ydCB7IExhbmd1YWdlTW9kZWxSZXNwb25zZU1ldGFkYXRhIH0gZnJvbSAnLi4vdHlwZXMvbGFuZ3VhZ2UtbW9kZWwtcmVzcG9uc2UtbWV0YWRhdGEnO1xuaW1wb3J0IHsgUHJvdmlkZXJNZXRhZGF0YSB9IGZyb20gJy4uL3R5cGVzL3Byb3ZpZGVyLW1ldGFkYXRhJztcbmltcG9ydCB7IExhbmd1YWdlTW9kZWxVc2FnZSB9IGZyb20gJy4uL3R5cGVzL3VzYWdlJztcbmltcG9ydCB7IERlZXBQYXJ0aWFsLCBpc0RlZXBFcXVhbERhdGEsIHBhcnNlUGFydGlhbEpzb24gfSBmcm9tICcuLi91dGlsJztcbmltcG9ydCB7XG4gIEFzeW5jSXRlcmFibGVTdHJlYW0sXG4gIGNyZWF0ZUFzeW5jSXRlcmFibGVTdHJlYW0sXG59IGZyb20gJy4uL3V0aWwvYXN5bmMtaXRlcmFibGUtc3RyZWFtJztcbmltcG9ydCB7IGNyZWF0ZVN0aXRjaGFibGVTdHJlYW0gfSBmcm9tICcuLi91dGlsL2NyZWF0ZS1zdGl0Y2hhYmxlLXN0cmVhbSc7XG5pbXBvcnQgeyBEZWxheWVkUHJvbWlzZSB9IGZyb20gJy4uL3V0aWwvZGVsYXllZC1wcm9taXNlJztcbmltcG9ydCB7IERvd25sb2FkRnVuY3Rpb24gfSBmcm9tICcuLi91dGlsL2Rvd25sb2FkL2Rvd25sb2FkLWZ1bmN0aW9uJztcbmltcG9ydCB7IG5vdyBhcyBvcmlnaW5hbE5vdyB9IGZyb20gJy4uL3V0aWwvbm93JztcbmltcG9ydCB7IHByZXBhcmVSZXRyaWVzIH0gZnJvbSAnLi4vdXRpbC9wcmVwYXJlLXJldHJpZXMnO1xuaW1wb3J0IHsgZ2V0T3V0cHV0U3RyYXRlZ3ksIE91dHB1dFN0cmF0ZWd5IH0gZnJvbSAnLi9vdXRwdXQtc3RyYXRlZ3knO1xuaW1wb3J0IHsgcGFyc2VBbmRWYWxpZGF0ZU9iamVjdFJlc3VsdFdpdGhSZXBhaXIgfSBmcm9tICcuL3BhcnNlLWFuZC12YWxpZGF0ZS1vYmplY3QtcmVzdWx0JztcbmltcG9ydCB7IFJlcGFpclRleHRGdW5jdGlvbiB9IGZyb20gJy4vcmVwYWlyLXRleHQnO1xuaW1wb3J0IHsgT2JqZWN0U3RyZWFtUGFydCwgU3RyZWFtT2JqZWN0UmVzdWx0IH0gZnJvbSAnLi9zdHJlYW0tb2JqZWN0LXJlc3VsdCc7XG5pbXBvcnQgeyB2YWxpZGF0ZU9iamVjdEdlbmVyYXRpb25JbnB1dCB9IGZyb20gJy4vdmFsaWRhdGUtb2JqZWN0LWdlbmVyYXRpb24taW5wdXQnO1xuXG5jb25zdCBvcmlnaW5hbEdlbmVyYXRlSWQgPSBjcmVhdGVJZEdlbmVyYXRvcih7IHByZWZpeDogJ2Fpb2JqJywgc2l6ZTogMjQgfSk7XG5cbi8qKlxuQ2FsbGJhY2sgdGhhdCBpcyBzZXQgdXNpbmcgdGhlIGBvbkVycm9yYCBvcHRpb24uXG5cbkBwYXJhbSBldmVudCAtIFRoZSBldmVudCB0aGF0IGlzIHBhc3NlZCB0byB0aGUgY2FsbGJhY2suXG4gKi9cbmV4cG9ydCB0eXBlIFN0cmVhbU9iamVjdE9uRXJyb3JDYWxsYmFjayA9IChldmVudDoge1xuICBlcnJvcjogdW5rbm93bjtcbn0pID0+IFByb21pc2U8dm9pZD4gfCB2b2lkO1xuXG4vKipcbkNhbGxiYWNrIHRoYXQgaXMgc2V0IHVzaW5nIHRoZSBgb25GaW5pc2hgIG9wdGlvbi5cblxuQHBhcmFtIGV2ZW50IC0gVGhlIGV2ZW50IHRoYXQgaXMgcGFzc2VkIHRvIHRoZSBjYWxsYmFjay5cbiAqL1xuZXhwb3J0IHR5cGUgU3RyZWFtT2JqZWN0T25GaW5pc2hDYWxsYmFjazxSRVNVTFQ+ID0gKGV2ZW50OiB7XG4gIC8qKlxuVGhlIHRva2VuIHVzYWdlIG9mIHRoZSBnZW5lcmF0ZWQgcmVzcG9uc2UuXG4qL1xuICB1c2FnZTogTGFuZ3VhZ2VNb2RlbFVzYWdlO1xuXG4gIC8qKlxuVGhlIGdlbmVyYXRlZCBvYmplY3QuIENhbiBiZSB1bmRlZmluZWQgaWYgdGhlIGZpbmFsIG9iamVjdCBkb2VzIG5vdCBtYXRjaCB0aGUgc2NoZW1hLlxuKi9cbiAgb2JqZWN0OiBSRVNVTFQgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG5PcHRpb25hbCBlcnJvciBvYmplY3QuIFRoaXMgaXMgZS5nLiBhIFR5cGVWYWxpZGF0aW9uRXJyb3Igd2hlbiB0aGUgZmluYWwgb2JqZWN0IGRvZXMgbm90IG1hdGNoIHRoZSBzY2hlbWEuXG4qL1xuICBlcnJvcjogdW5rbm93biB8IHVuZGVmaW5lZDtcblxuICAvKipcblJlc3BvbnNlIG1ldGFkYXRhLlxuICovXG4gIHJlc3BvbnNlOiBMYW5ndWFnZU1vZGVsUmVzcG9uc2VNZXRhZGF0YTtcblxuICAvKipcbldhcm5pbmdzIGZyb20gdGhlIG1vZGVsIHByb3ZpZGVyIChlLmcuIHVuc3VwcG9ydGVkIHNldHRpbmdzKS5cbiovXG4gIHdhcm5pbmdzPzogQ2FsbFdhcm5pbmdbXTtcblxuICAvKipcbkFkZGl0aW9uYWwgcHJvdmlkZXItc3BlY2lmaWMgbWV0YWRhdGEuIFRoZXkgYXJlIHBhc3NlZCB0aHJvdWdoXG50byB0aGUgcHJvdmlkZXIgZnJvbSB0aGUgQUkgU0RLIGFuZCBlbmFibGUgcHJvdmlkZXItc3BlY2lmaWNcbmZ1bmN0aW9uYWxpdHkgdGhhdCBjYW4gYmUgZnVsbHkgZW5jYXBzdWxhdGVkIGluIHRoZSBwcm92aWRlci5cbiovXG4gIHByb3ZpZGVyTWV0YWRhdGE6IFByb3ZpZGVyTWV0YWRhdGEgfCB1bmRlZmluZWQ7XG59KSA9PiBQcm9taXNlPHZvaWQ+IHwgdm9pZDtcblxuLyoqXG5HZW5lcmF0ZSBhIHN0cnVjdHVyZWQsIHR5cGVkIG9iamVjdCBmb3IgYSBnaXZlbiBwcm9tcHQgYW5kIHNjaGVtYSB1c2luZyBhIGxhbmd1YWdlIG1vZGVsLlxuXG5UaGlzIGZ1bmN0aW9uIHN0cmVhbXMgdGhlIG91dHB1dC4gSWYgeW91IGRvIG5vdCB3YW50IHRvIHN0cmVhbSB0aGUgb3V0cHV0LCB1c2UgYGdlbmVyYXRlT2JqZWN0YCBpbnN0ZWFkLlxuXG5AcGFyYW0gbW9kZWwgLSBUaGUgbGFuZ3VhZ2UgbW9kZWwgdG8gdXNlLlxuQHBhcmFtIHRvb2xzIC0gVG9vbHMgdGhhdCBhcmUgYWNjZXNzaWJsZSB0byBhbmQgY2FuIGJlIGNhbGxlZCBieSB0aGUgbW9kZWwuIFRoZSBtb2RlbCBuZWVkcyB0byBzdXBwb3J0IGNhbGxpbmcgdG9vbHMuXG5cbkBwYXJhbSBzeXN0ZW0gLSBBIHN5c3RlbSBtZXNzYWdlIHRoYXQgd2lsbCBiZSBwYXJ0IG9mIHRoZSBwcm9tcHQuXG5AcGFyYW0gcHJvbXB0IC0gQSBzaW1wbGUgdGV4dCBwcm9tcHQuIFlvdSBjYW4gZWl0aGVyIHVzZSBgcHJvbXB0YCBvciBgbWVzc2FnZXNgIGJ1dCBub3QgYm90aC5cbkBwYXJhbSBtZXNzYWdlcyAtIEEgbGlzdCBvZiBtZXNzYWdlcy4gWW91IGNhbiBlaXRoZXIgdXNlIGBwcm9tcHRgIG9yIGBtZXNzYWdlc2AgYnV0IG5vdCBib3RoLlxuXG5AcGFyYW0gbWF4T3V0cHV0VG9rZW5zIC0gTWF4aW11bSBudW1iZXIgb2YgdG9rZW5zIHRvIGdlbmVyYXRlLlxuQHBhcmFtIHRlbXBlcmF0dXJlIC0gVGVtcGVyYXR1cmUgc2V0dGluZy5cblRoZSB2YWx1ZSBpcyBwYXNzZWQgdGhyb3VnaCB0byB0aGUgcHJvdmlkZXIuIFRoZSByYW5nZSBkZXBlbmRzIG9uIHRoZSBwcm92aWRlciBhbmQgbW9kZWwuXG5JdCBpcyByZWNvbW1lbmRlZCB0byBzZXQgZWl0aGVyIGB0ZW1wZXJhdHVyZWAgb3IgYHRvcFBgLCBidXQgbm90IGJvdGguXG5AcGFyYW0gdG9wUCAtIE51Y2xldXMgc2FtcGxpbmcuXG5UaGUgdmFsdWUgaXMgcGFzc2VkIHRocm91Z2ggdG8gdGhlIHByb3ZpZGVyLiBUaGUgcmFuZ2UgZGVwZW5kcyBvbiB0aGUgcHJvdmlkZXIgYW5kIG1vZGVsLlxuSXQgaXMgcmVjb21tZW5kZWQgdG8gc2V0IGVpdGhlciBgdGVtcGVyYXR1cmVgIG9yIGB0b3BQYCwgYnV0IG5vdCBib3RoLlxuQHBhcmFtIHRvcEsgLSBPbmx5IHNhbXBsZSBmcm9tIHRoZSB0b3AgSyBvcHRpb25zIGZvciBlYWNoIHN1YnNlcXVlbnQgdG9rZW4uXG5Vc2VkIHRvIHJlbW92ZSBcImxvbmcgdGFpbFwiIGxvdyBwcm9iYWJpbGl0eSByZXNwb25zZXMuXG5SZWNvbW1lbmRlZCBmb3IgYWR2YW5jZWQgdXNlIGNhc2VzIG9ubHkuIFlvdSB1c3VhbGx5IG9ubHkgbmVlZCB0byB1c2UgdGVtcGVyYXR1cmUuXG5AcGFyYW0gcHJlc2VuY2VQZW5hbHR5IC0gUHJlc2VuY2UgcGVuYWx0eSBzZXR0aW5nLlxuSXQgYWZmZWN0cyB0aGUgbGlrZWxpaG9vZCBvZiB0aGUgbW9kZWwgdG8gcmVwZWF0IGluZm9ybWF0aW9uIHRoYXQgaXMgYWxyZWFkeSBpbiB0aGUgcHJvbXB0LlxuVGhlIHZhbHVlIGlzIHBhc3NlZCB0aHJvdWdoIHRvIHRoZSBwcm92aWRlci4gVGhlIHJhbmdlIGRlcGVuZHMgb24gdGhlIHByb3ZpZGVyIGFuZCBtb2RlbC5cbkBwYXJhbSBmcmVxdWVuY3lQZW5hbHR5IC0gRnJlcXVlbmN5IHBlbmFsdHkgc2V0dGluZy5cbkl0IGFmZmVjdHMgdGhlIGxpa2VsaWhvb2Qgb2YgdGhlIG1vZGVsIHRvIHJlcGVhdGVkbHkgdXNlIHRoZSBzYW1lIHdvcmRzIG9yIHBocmFzZXMuXG5UaGUgdmFsdWUgaXMgcGFzc2VkIHRocm91Z2ggdG8gdGhlIHByb3ZpZGVyLiBUaGUgcmFuZ2UgZGVwZW5kcyBvbiB0aGUgcHJvdmlkZXIgYW5kIG1vZGVsLlxuQHBhcmFtIHN0b3BTZXF1ZW5jZXMgLSBTdG9wIHNlcXVlbmNlcy5cbklmIHNldCwgdGhlIG1vZGVsIHdpbGwgc3RvcCBnZW5lcmF0aW5nIHRleHQgd2hlbiBvbmUgb2YgdGhlIHN0b3Agc2VxdWVuY2VzIGlzIGdlbmVyYXRlZC5cbkBwYXJhbSBzZWVkIC0gVGhlIHNlZWQgKGludGVnZXIpIHRvIHVzZSBmb3IgcmFuZG9tIHNhbXBsaW5nLlxuSWYgc2V0IGFuZCBzdXBwb3J0ZWQgYnkgdGhlIG1vZGVsLCBjYWxscyB3aWxsIGdlbmVyYXRlIGRldGVybWluaXN0aWMgcmVzdWx0cy5cblxuQHBhcmFtIG1heFJldHJpZXMgLSBNYXhpbXVtIG51bWJlciBvZiByZXRyaWVzLiBTZXQgdG8gMCB0byBkaXNhYmxlIHJldHJpZXMuIERlZmF1bHQ6IDIuXG5AcGFyYW0gYWJvcnRTaWduYWwgLSBBbiBvcHRpb25hbCBhYm9ydCBzaWduYWwgdGhhdCBjYW4gYmUgdXNlZCB0byBjYW5jZWwgdGhlIGNhbGwuXG5AcGFyYW0gaGVhZGVycyAtIEFkZGl0aW9uYWwgSFRUUCBoZWFkZXJzIHRvIGJlIHNlbnQgd2l0aCB0aGUgcmVxdWVzdC4gT25seSBhcHBsaWNhYmxlIGZvciBIVFRQLWJhc2VkIHByb3ZpZGVycy5cblxuQHBhcmFtIHNjaGVtYSAtIFRoZSBzY2hlbWEgb2YgdGhlIG9iamVjdCB0aGF0IHRoZSBtb2RlbCBzaG91bGQgZ2VuZXJhdGUuXG5AcGFyYW0gc2NoZW1hTmFtZSAtIE9wdGlvbmFsIG5hbWUgb2YgdGhlIG91dHB1dCB0aGF0IHNob3VsZCBiZSBnZW5lcmF0ZWQuXG5Vc2VkIGJ5IHNvbWUgcHJvdmlkZXJzIGZvciBhZGRpdGlvbmFsIExMTSBndWlkYW5jZSwgZS5nLlxudmlhIHRvb2wgb3Igc2NoZW1hIG5hbWUuXG5AcGFyYW0gc2NoZW1hRGVzY3JpcHRpb24gLSBPcHRpb25hbCBkZXNjcmlwdGlvbiBvZiB0aGUgb3V0cHV0IHRoYXQgc2hvdWxkIGJlIGdlbmVyYXRlZC5cblVzZWQgYnkgc29tZSBwcm92aWRlcnMgZm9yIGFkZGl0aW9uYWwgTExNIGd1aWRhbmNlLCBlLmcuXG52aWEgdG9vbCBvciBzY2hlbWEgZGVzY3JpcHRpb24uXG5cbkBwYXJhbSBvdXRwdXQgLSBUaGUgdHlwZSBvZiB0aGUgb3V0cHV0LlxuXG4tICdvYmplY3QnOiBUaGUgb3V0cHV0IGlzIGFuIG9iamVjdC5cbi0gJ2FycmF5JzogVGhlIG91dHB1dCBpcyBhbiBhcnJheS5cbi0gJ2VudW0nOiBUaGUgb3V0cHV0IGlzIGFuIGVudW0uXG4tICduby1zY2hlbWEnOiBUaGUgb3V0cHV0IGlzIG5vdCBhIHNjaGVtYS5cblxuQHBhcmFtIGV4cGVyaW1lbnRhbF90ZWxlbWV0cnkgLSBPcHRpb25hbCB0ZWxlbWV0cnkgY29uZmlndXJhdGlvbiAoZXhwZXJpbWVudGFsKS5cblxuQHBhcmFtIHByb3ZpZGVyT3B0aW9ucyAtIEFkZGl0aW9uYWwgcHJvdmlkZXItc3BlY2lmaWMgb3B0aW9ucy4gVGhleSBhcmUgcGFzc2VkIHRocm91Z2hcbnRvIHRoZSBwcm92aWRlciBmcm9tIHRoZSBBSSBTREsgYW5kIGVuYWJsZSBwcm92aWRlci1zcGVjaWZpY1xuZnVuY3Rpb25hbGl0eSB0aGF0IGNhbiBiZSBmdWxseSBlbmNhcHN1bGF0ZWQgaW4gdGhlIHByb3ZpZGVyLlxuXG5AcmV0dXJuc1xuQSByZXN1bHQgb2JqZWN0IGZvciBhY2Nlc3NpbmcgdGhlIHBhcnRpYWwgb2JqZWN0IHN0cmVhbSBhbmQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN0cmVhbU9iamVjdDxcbiAgU0NIRU1BIGV4dGVuZHMgRmxleGlibGVTY2hlbWE8dW5rbm93bj4gPSBGbGV4aWJsZVNjaGVtYTxKU09OVmFsdWU+LFxuICBPVVRQVVQgZXh0ZW5kc1xuICAgIHwgJ29iamVjdCdcbiAgICB8ICdhcnJheSdcbiAgICB8ICdlbnVtJ1xuICAgIHwgJ25vLXNjaGVtYScgPSBJbmZlclNjaGVtYTxTQ0hFTUE+IGV4dGVuZHMgc3RyaW5nID8gJ2VudW0nIDogJ29iamVjdCcsXG4gIFJFU1VMVCA9IE9VVFBVVCBleHRlbmRzICdhcnJheSdcbiAgICA/IEFycmF5PEluZmVyU2NoZW1hPFNDSEVNQT4+XG4gICAgOiBJbmZlclNjaGVtYTxTQ0hFTUE+LFxuPihcbiAgb3B0aW9uczogT21pdDxDYWxsU2V0dGluZ3MsICdzdG9wU2VxdWVuY2VzJz4gJlxuICAgIFByb21wdCAmXG4gICAgKE9VVFBVVCBleHRlbmRzICdlbnVtJ1xuICAgICAgPyB7XG4gICAgICAgICAgLyoqXG5UaGUgZW51bSB2YWx1ZXMgdGhhdCB0aGUgbW9kZWwgc2hvdWxkIHVzZS5cbiAgICAgICAgKi9cbiAgICAgICAgICBlbnVtOiBBcnJheTxSRVNVTFQ+O1xuICAgICAgICAgIG1vZGU/OiAnanNvbic7XG4gICAgICAgICAgb3V0cHV0OiAnZW51bSc7XG4gICAgICAgIH1cbiAgICAgIDogT1VUUFVUIGV4dGVuZHMgJ25vLXNjaGVtYSdcbiAgICAgICAgPyB7fVxuICAgICAgICA6IHtcbiAgICAgICAgICAgIC8qKlxuVGhlIHNjaGVtYSBvZiB0aGUgb2JqZWN0IHRoYXQgdGhlIG1vZGVsIHNob3VsZCBnZW5lcmF0ZS5cbiAgICAgICovXG4gICAgICAgICAgICBzY2hlbWE6IFNDSEVNQTtcblxuICAgICAgICAgICAgLyoqXG5PcHRpb25hbCBuYW1lIG9mIHRoZSBvdXRwdXQgdGhhdCBzaG91bGQgYmUgZ2VuZXJhdGVkLlxuVXNlZCBieSBzb21lIHByb3ZpZGVycyBmb3IgYWRkaXRpb25hbCBMTE0gZ3VpZGFuY2UsIGUuZy5cbnZpYSB0b29sIG9yIHNjaGVtYSBuYW1lLlxuICAgICAgKi9cbiAgICAgICAgICAgIHNjaGVtYU5hbWU/OiBzdHJpbmc7XG5cbiAgICAgICAgICAgIC8qKlxuT3B0aW9uYWwgZGVzY3JpcHRpb24gb2YgdGhlIG91dHB1dCB0aGF0IHNob3VsZCBiZSBnZW5lcmF0ZWQuXG5Vc2VkIGJ5IHNvbWUgcHJvdmlkZXJzIGZvciBhZGRpdGlvbmFsIExMTSBndWlkYW5jZSwgZS5nLlxudmlhIHRvb2wgb3Igc2NoZW1hIGRlc2NyaXB0aW9uLlxuICAgICAgKi9cbiAgICAgICAgICAgIHNjaGVtYURlc2NyaXB0aW9uPzogc3RyaW5nO1xuXG4gICAgICAgICAgICAvKipcblRoZSBtb2RlIHRvIHVzZSBmb3Igb2JqZWN0IGdlbmVyYXRpb24uXG5cblRoZSBzY2hlbWEgaXMgY29udmVydGVkIGludG8gYSBKU09OIHNjaGVtYSBhbmQgdXNlZCBpbiBvbmUgb2YgdGhlIGZvbGxvd2luZyB3YXlzXG5cbi0gJ2F1dG8nOiBUaGUgcHJvdmlkZXIgd2lsbCBjaG9vc2UgdGhlIGJlc3QgbW9kZSBmb3IgdGhlIG1vZGVsLlxuLSAndG9vbCc6IEEgdG9vbCB3aXRoIHRoZSBKU09OIHNjaGVtYSBhcyBwYXJhbWV0ZXJzIGlzIHByb3ZpZGVkIGFuZCB0aGUgcHJvdmlkZXIgaXMgaW5zdHJ1Y3RlZCB0byB1c2UgaXQuXG4tICdqc29uJzogVGhlIEpTT04gc2NoZW1hIGFuZCBhbiBpbnN0cnVjdGlvbiBhcmUgaW5qZWN0ZWQgaW50byB0aGUgcHJvbXB0LiBJZiB0aGUgcHJvdmlkZXIgc3VwcG9ydHMgSlNPTiBtb2RlLCBpdCBpcyBlbmFibGVkLiBJZiB0aGUgcHJvdmlkZXIgc3VwcG9ydHMgSlNPTiBncmFtbWFycywgdGhlIGdyYW1tYXIgaXMgdXNlZC5cblxuUGxlYXNlIG5vdGUgdGhhdCBtb3N0IHByb3ZpZGVycyBkbyBub3Qgc3VwcG9ydCBhbGwgbW9kZXMuXG5cbkRlZmF1bHQgYW5kIHJlY29tbWVuZGVkOiAnYXV0bycgKGJlc3QgbW9kZSBmb3IgdGhlIG1vZGVsKS5cbiAgICAgICovXG4gICAgICAgICAgICBtb2RlPzogJ2F1dG8nIHwgJ2pzb24nIHwgJ3Rvb2wnO1xuICAgICAgICAgIH0pICYge1xuICAgICAgb3V0cHV0PzogT1VUUFVUO1xuXG4gICAgICAvKipcblRoZSBsYW5ndWFnZSBtb2RlbCB0byB1c2UuXG4gICAgICovXG4gICAgICBtb2RlbDogTGFuZ3VhZ2VNb2RlbDtcblxuICAgICAgLyoqXG5BIGZ1bmN0aW9uIHRoYXQgYXR0ZW1wdHMgdG8gcmVwYWlyIHRoZSByYXcgb3V0cHV0IG9mIHRoZSBtb2RlbFxudG8gZW5hYmxlIEpTT04gcGFyc2luZy5cbiAgICAgICAqL1xuICAgICAgZXhwZXJpbWVudGFsX3JlcGFpclRleHQ/OiBSZXBhaXJUZXh0RnVuY3Rpb247XG5cbiAgICAgIC8qKlxuT3B0aW9uYWwgdGVsZW1ldHJ5IGNvbmZpZ3VyYXRpb24gKGV4cGVyaW1lbnRhbCkuXG4gICAgICAgKi9cblxuICAgICAgZXhwZXJpbWVudGFsX3RlbGVtZXRyeT86IFRlbGVtZXRyeVNldHRpbmdzO1xuXG4gICAgICAvKipcbiAgQ3VzdG9tIGRvd25sb2FkIGZ1bmN0aW9uIHRvIHVzZSBmb3IgVVJMcy5cblxuICBCeSBkZWZhdWx0LCBmaWxlcyBhcmUgZG93bmxvYWRlZCBpZiB0aGUgbW9kZWwgZG9lcyBub3Qgc3VwcG9ydCB0aGUgVVJMIGZvciB0aGUgZ2l2ZW4gbWVkaWEgdHlwZS5cbiAgICAgICAqL1xuICAgICAgZXhwZXJpbWVudGFsX2Rvd25sb2FkPzogRG93bmxvYWRGdW5jdGlvbiB8IHVuZGVmaW5lZDtcblxuICAgICAgLyoqXG5BZGRpdGlvbmFsIHByb3ZpZGVyLXNwZWNpZmljIG9wdGlvbnMuIFRoZXkgYXJlIHBhc3NlZCB0aHJvdWdoXG50byB0aGUgcHJvdmlkZXIgZnJvbSB0aGUgQUkgU0RLIGFuZCBlbmFibGUgcHJvdmlkZXItc3BlY2lmaWNcbmZ1bmN0aW9uYWxpdHkgdGhhdCBjYW4gYmUgZnVsbHkgZW5jYXBzdWxhdGVkIGluIHRoZSBwcm92aWRlci5cbiAqL1xuICAgICAgcHJvdmlkZXJPcHRpb25zPzogUHJvdmlkZXJPcHRpb25zO1xuXG4gICAgICAvKipcbkNhbGxiYWNrIHRoYXQgaXMgaW52b2tlZCB3aGVuIGFuIGVycm9yIG9jY3VycyBkdXJpbmcgc3RyZWFtaW5nLlxuWW91IGNhbiB1c2UgaXQgdG8gbG9nIGVycm9ycy5cblRoZSBzdHJlYW0gcHJvY2Vzc2luZyB3aWxsIHBhdXNlIHVudGlsIHRoZSBjYWxsYmFjayBwcm9taXNlIGlzIHJlc29sdmVkLlxuICAgICAqL1xuICAgICAgb25FcnJvcj86IFN0cmVhbU9iamVjdE9uRXJyb3JDYWxsYmFjaztcblxuICAgICAgLyoqXG5DYWxsYmFjayB0aGF0IGlzIGNhbGxlZCB3aGVuIHRoZSBMTE0gcmVzcG9uc2UgYW5kIHRoZSBmaW5hbCBvYmplY3QgdmFsaWRhdGlvbiBhcmUgZmluaXNoZWQuXG4qL1xuICAgICAgb25GaW5pc2g/OiBTdHJlYW1PYmplY3RPbkZpbmlzaENhbGxiYWNrPFJFU1VMVD47XG5cbiAgICAgIC8qKlxuICAgICAgICogSW50ZXJuYWwuIEZvciB0ZXN0IHVzZSBvbmx5LiBNYXkgY2hhbmdlIHdpdGhvdXQgbm90aWNlLlxuICAgICAgICovXG4gICAgICBfaW50ZXJuYWw/OiB7XG4gICAgICAgIGdlbmVyYXRlSWQ/OiAoKSA9PiBzdHJpbmc7XG4gICAgICAgIGN1cnJlbnREYXRlPzogKCkgPT4gRGF0ZTtcbiAgICAgICAgbm93PzogKCkgPT4gbnVtYmVyO1xuICAgICAgfTtcbiAgICB9LFxuKTogU3RyZWFtT2JqZWN0UmVzdWx0PFxuICBPVVRQVVQgZXh0ZW5kcyAnZW51bSdcbiAgICA/IHN0cmluZ1xuICAgIDogT1VUUFVUIGV4dGVuZHMgJ2FycmF5J1xuICAgICAgPyBSRVNVTFRcbiAgICAgIDogRGVlcFBhcnRpYWw8UkVTVUxUPixcbiAgT1VUUFVUIGV4dGVuZHMgJ2FycmF5JyA/IFJFU1VMVCA6IFJFU1VMVCxcbiAgT1VUUFVUIGV4dGVuZHMgJ2FycmF5J1xuICAgID8gUkVTVUxUIGV4dGVuZHMgQXJyYXk8aW5mZXIgVT5cbiAgICAgID8gQXN5bmNJdGVyYWJsZVN0cmVhbTxVPlxuICAgICAgOiBuZXZlclxuICAgIDogbmV2ZXJcbj4ge1xuICBjb25zdCB7XG4gICAgbW9kZWwsXG4gICAgb3V0cHV0ID0gJ29iamVjdCcsXG4gICAgc3lzdGVtLFxuICAgIHByb21wdCxcbiAgICBtZXNzYWdlcyxcbiAgICBtYXhSZXRyaWVzLFxuICAgIGFib3J0U2lnbmFsLFxuICAgIGhlYWRlcnMsXG4gICAgZXhwZXJpbWVudGFsX3JlcGFpclRleHQ6IHJlcGFpclRleHQsXG4gICAgZXhwZXJpbWVudGFsX3RlbGVtZXRyeTogdGVsZW1ldHJ5LFxuICAgIGV4cGVyaW1lbnRhbF9kb3dubG9hZDogZG93bmxvYWQsXG4gICAgcHJvdmlkZXJPcHRpb25zLFxuICAgIG9uRXJyb3IgPSAoeyBlcnJvciB9OiB7IGVycm9yOiB1bmtub3duIH0pID0+IHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgIH0sXG4gICAgb25GaW5pc2gsXG4gICAgX2ludGVybmFsOiB7XG4gICAgICBnZW5lcmF0ZUlkID0gb3JpZ2luYWxHZW5lcmF0ZUlkLFxuICAgICAgY3VycmVudERhdGUgPSAoKSA9PiBuZXcgRGF0ZSgpLFxuICAgICAgbm93ID0gb3JpZ2luYWxOb3csXG4gICAgfSA9IHt9LFxuICAgIC4uLnNldHRpbmdzXG4gIH0gPSBvcHRpb25zO1xuXG4gIGNvbnN0IGVudW1WYWx1ZXMgPVxuICAgICdlbnVtJyBpbiBvcHRpb25zICYmIG9wdGlvbnMuZW51bSA/IG9wdGlvbnMuZW51bSA6IHVuZGVmaW5lZDtcblxuICBjb25zdCB7XG4gICAgc2NoZW1hOiBpbnB1dFNjaGVtYSxcbiAgICBzY2hlbWFEZXNjcmlwdGlvbixcbiAgICBzY2hlbWFOYW1lLFxuICB9ID0gJ3NjaGVtYScgaW4gb3B0aW9ucyA/IG9wdGlvbnMgOiB7fTtcblxuICB2YWxpZGF0ZU9iamVjdEdlbmVyYXRpb25JbnB1dCh7XG4gICAgb3V0cHV0LFxuICAgIHNjaGVtYTogaW5wdXRTY2hlbWEsXG4gICAgc2NoZW1hTmFtZSxcbiAgICBzY2hlbWFEZXNjcmlwdGlvbixcbiAgICBlbnVtVmFsdWVzLFxuICB9KTtcblxuICBjb25zdCBvdXRwdXRTdHJhdGVneSA9IGdldE91dHB1dFN0cmF0ZWd5KHtcbiAgICBvdXRwdXQsXG4gICAgc2NoZW1hOiBpbnB1dFNjaGVtYSxcbiAgICBlbnVtVmFsdWVzLFxuICB9KTtcblxuICByZXR1cm4gbmV3IERlZmF1bHRTdHJlYW1PYmplY3RSZXN1bHQoe1xuICAgIG1vZGVsLFxuICAgIHRlbGVtZXRyeSxcbiAgICBoZWFkZXJzLFxuICAgIHNldHRpbmdzLFxuICAgIG1heFJldHJpZXMsXG4gICAgYWJvcnRTaWduYWwsXG4gICAgb3V0cHV0U3RyYXRlZ3ksXG4gICAgc3lzdGVtLFxuICAgIHByb21wdCxcbiAgICBtZXNzYWdlcyxcbiAgICBzY2hlbWFOYW1lLFxuICAgIHNjaGVtYURlc2NyaXB0aW9uLFxuICAgIHByb3ZpZGVyT3B0aW9ucyxcbiAgICByZXBhaXJUZXh0LFxuICAgIG9uRXJyb3IsXG4gICAgb25GaW5pc2gsXG4gICAgZG93bmxvYWQsXG4gICAgZ2VuZXJhdGVJZCxcbiAgICBjdXJyZW50RGF0ZSxcbiAgICBub3csXG4gIH0pO1xufVxuXG5jbGFzcyBEZWZhdWx0U3RyZWFtT2JqZWN0UmVzdWx0PFBBUlRJQUwsIFJFU1VMVCwgRUxFTUVOVF9TVFJFQU0+XG4gIGltcGxlbWVudHMgU3RyZWFtT2JqZWN0UmVzdWx0PFBBUlRJQUwsIFJFU1VMVCwgRUxFTUVOVF9TVFJFQU0+XG57XG4gIHByaXZhdGUgcmVhZG9ubHkgX29iamVjdCA9IG5ldyBEZWxheWVkUHJvbWlzZTxSRVNVTFQ+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX3VzYWdlID0gbmV3IERlbGF5ZWRQcm9taXNlPExhbmd1YWdlTW9kZWxVc2FnZT4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfcHJvdmlkZXJNZXRhZGF0YSA9IG5ldyBEZWxheWVkUHJvbWlzZTxcbiAgICBQcm92aWRlck1ldGFkYXRhIHwgdW5kZWZpbmVkXG4gID4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfd2FybmluZ3MgPSBuZXcgRGVsYXllZFByb21pc2U8Q2FsbFdhcm5pbmdbXSB8IHVuZGVmaW5lZD4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfcmVxdWVzdCA9XG4gICAgbmV3IERlbGF5ZWRQcm9taXNlPExhbmd1YWdlTW9kZWxSZXF1ZXN0TWV0YWRhdGE+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX3Jlc3BvbnNlID1cbiAgICBuZXcgRGVsYXllZFByb21pc2U8TGFuZ3VhZ2VNb2RlbFJlc3BvbnNlTWV0YWRhdGE+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2ZpbmlzaFJlYXNvbiA9IG5ldyBEZWxheWVkUHJvbWlzZTxGaW5pc2hSZWFzb24+KCk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBiYXNlU3RyZWFtOiBSZWFkYWJsZVN0cmVhbTxPYmplY3RTdHJlYW1QYXJ0PFBBUlRJQUw+PjtcblxuICBwcml2YXRlIHJlYWRvbmx5IG91dHB1dFN0cmF0ZWd5OiBPdXRwdXRTdHJhdGVneTxcbiAgICBQQVJUSUFMLFxuICAgIFJFU1VMVCxcbiAgICBFTEVNRU5UX1NUUkVBTVxuICA+O1xuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICBtb2RlbDogbW9kZWxBcmcsXG4gICAgaGVhZGVycyxcbiAgICB0ZWxlbWV0cnksXG4gICAgc2V0dGluZ3MsXG4gICAgbWF4UmV0cmllczogbWF4UmV0cmllc0FyZyxcbiAgICBhYm9ydFNpZ25hbCxcbiAgICBvdXRwdXRTdHJhdGVneSxcbiAgICBzeXN0ZW0sXG4gICAgcHJvbXB0LFxuICAgIG1lc3NhZ2VzLFxuICAgIHNjaGVtYU5hbWUsXG4gICAgc2NoZW1hRGVzY3JpcHRpb24sXG4gICAgcHJvdmlkZXJPcHRpb25zLFxuICAgIHJlcGFpclRleHQsXG4gICAgb25FcnJvcixcbiAgICBvbkZpbmlzaCxcbiAgICBkb3dubG9hZCxcbiAgICBnZW5lcmF0ZUlkLFxuICAgIGN1cnJlbnREYXRlLFxuICAgIG5vdyxcbiAgfToge1xuICAgIG1vZGVsOiBMYW5ndWFnZU1vZGVsO1xuICAgIHRlbGVtZXRyeTogVGVsZW1ldHJ5U2V0dGluZ3MgfCB1bmRlZmluZWQ7XG4gICAgaGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPiB8IHVuZGVmaW5lZDtcbiAgICBzZXR0aW5nczogT21pdDxDYWxsU2V0dGluZ3MsICdhYm9ydFNpZ25hbCcgfCAnaGVhZGVycyc+O1xuICAgIG1heFJldHJpZXM6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgICBhYm9ydFNpZ25hbDogQWJvcnRTaWduYWwgfCB1bmRlZmluZWQ7XG4gICAgb3V0cHV0U3RyYXRlZ3k6IE91dHB1dFN0cmF0ZWd5PFBBUlRJQUwsIFJFU1VMVCwgRUxFTUVOVF9TVFJFQU0+O1xuICAgIHN5c3RlbTogUHJvbXB0WydzeXN0ZW0nXTtcbiAgICBwcm9tcHQ6IFByb21wdFsncHJvbXB0J107XG4gICAgbWVzc2FnZXM6IFByb21wdFsnbWVzc2FnZXMnXTtcbiAgICBzY2hlbWFOYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgc2NoZW1hRGVzY3JpcHRpb246IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICBwcm92aWRlck9wdGlvbnM6IFByb3ZpZGVyT3B0aW9ucyB8IHVuZGVmaW5lZDtcbiAgICByZXBhaXJUZXh0OiBSZXBhaXJUZXh0RnVuY3Rpb24gfCB1bmRlZmluZWQ7XG4gICAgb25FcnJvcjogU3RyZWFtT2JqZWN0T25FcnJvckNhbGxiYWNrO1xuICAgIG9uRmluaXNoOiBTdHJlYW1PYmplY3RPbkZpbmlzaENhbGxiYWNrPFJFU1VMVD4gfCB1bmRlZmluZWQ7XG4gICAgZG93bmxvYWQ6IERvd25sb2FkRnVuY3Rpb24gfCB1bmRlZmluZWQ7XG4gICAgZ2VuZXJhdGVJZDogKCkgPT4gc3RyaW5nO1xuICAgIGN1cnJlbnREYXRlOiAoKSA9PiBEYXRlO1xuICAgIG5vdzogKCkgPT4gbnVtYmVyO1xuICB9KSB7XG4gICAgY29uc3QgbW9kZWwgPSByZXNvbHZlTGFuZ3VhZ2VNb2RlbChtb2RlbEFyZyk7XG5cbiAgICBjb25zdCB7IG1heFJldHJpZXMsIHJldHJ5IH0gPSBwcmVwYXJlUmV0cmllcyh7XG4gICAgICBtYXhSZXRyaWVzOiBtYXhSZXRyaWVzQXJnLFxuICAgICAgYWJvcnRTaWduYWwsXG4gICAgfSk7XG5cbiAgICBjb25zdCBjYWxsU2V0dGluZ3MgPSBwcmVwYXJlQ2FsbFNldHRpbmdzKHNldHRpbmdzKTtcblxuICAgIGNvbnN0IGJhc2VUZWxlbWV0cnlBdHRyaWJ1dGVzID0gZ2V0QmFzZVRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgbW9kZWwsXG4gICAgICB0ZWxlbWV0cnksXG4gICAgICBoZWFkZXJzLFxuICAgICAgc2V0dGluZ3M6IHsgLi4uY2FsbFNldHRpbmdzLCBtYXhSZXRyaWVzIH0sXG4gICAgfSk7XG5cbiAgICBjb25zdCB0cmFjZXIgPSBnZXRUcmFjZXIodGVsZW1ldHJ5KTtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIGNvbnN0IHN0aXRjaGFibGVTdHJlYW0gPVxuICAgICAgY3JlYXRlU3RpdGNoYWJsZVN0cmVhbTxPYmplY3RTdHJlYW1QYXJ0PFBBUlRJQUw+PigpO1xuXG4gICAgY29uc3QgZXZlbnRQcm9jZXNzb3IgPSBuZXcgVHJhbnNmb3JtU3RyZWFtPFxuICAgICAgT2JqZWN0U3RyZWFtUGFydDxQQVJUSUFMPixcbiAgICAgIE9iamVjdFN0cmVhbVBhcnQ8UEFSVElBTD5cbiAgICA+KHtcbiAgICAgIHRyYW5zZm9ybShjaHVuaywgY29udHJvbGxlcikge1xuICAgICAgICBjb250cm9sbGVyLmVucXVldWUoY2h1bmspO1xuXG4gICAgICAgIGlmIChjaHVuay50eXBlID09PSAnZXJyb3InKSB7XG4gICAgICAgICAgb25FcnJvcih7IGVycm9yOiB3cmFwR2F0ZXdheUVycm9yKGNodW5rLmVycm9yKSB9KTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIHRoaXMuYmFzZVN0cmVhbSA9IHN0aXRjaGFibGVTdHJlYW0uc3RyZWFtLnBpcGVUaHJvdWdoKGV2ZW50UHJvY2Vzc29yKTtcblxuICAgIHJlY29yZFNwYW4oe1xuICAgICAgbmFtZTogJ2FpLnN0cmVhbU9iamVjdCcsXG4gICAgICBhdHRyaWJ1dGVzOiBzZWxlY3RUZWxlbWV0cnlBdHRyaWJ1dGVzKHtcbiAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgLi4uYXNzZW1ibGVPcGVyYXRpb25OYW1lKHtcbiAgICAgICAgICAgIG9wZXJhdGlvbklkOiAnYWkuc3RyZWFtT2JqZWN0JyxcbiAgICAgICAgICAgIHRlbGVtZXRyeSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICAuLi5iYXNlVGVsZW1ldHJ5QXR0cmlidXRlcyxcbiAgICAgICAgICAvLyBzcGVjaWZpYyBzZXR0aW5ncyB0aGF0IG9ubHkgbWFrZSBzZW5zZSBvbiB0aGUgb3V0ZXIgbGV2ZWw6XG4gICAgICAgICAgJ2FpLnByb21wdCc6IHtcbiAgICAgICAgICAgIGlucHV0OiAoKSA9PiBKU09OLnN0cmluZ2lmeSh7IHN5c3RlbSwgcHJvbXB0LCBtZXNzYWdlcyB9KSxcbiAgICAgICAgICB9LFxuICAgICAgICAgICdhaS5zY2hlbWEnOlxuICAgICAgICAgICAgb3V0cHV0U3RyYXRlZ3kuanNvblNjaGVtYSAhPSBudWxsXG4gICAgICAgICAgICAgID8geyBpbnB1dDogKCkgPT4gSlNPTi5zdHJpbmdpZnkob3V0cHV0U3RyYXRlZ3kuanNvblNjaGVtYSkgfVxuICAgICAgICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAnYWkuc2NoZW1hLm5hbWUnOiBzY2hlbWFOYW1lLFxuICAgICAgICAgICdhaS5zY2hlbWEuZGVzY3JpcHRpb24nOiBzY2hlbWFEZXNjcmlwdGlvbixcbiAgICAgICAgICAnYWkuc2V0dGluZ3Mub3V0cHV0Jzogb3V0cHV0U3RyYXRlZ3kudHlwZSxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgICAgdHJhY2VyLFxuICAgICAgZW5kV2hlbkRvbmU6IGZhbHNlLFxuICAgICAgZm46IGFzeW5jIHJvb3RTcGFuID0+IHtcbiAgICAgICAgY29uc3Qgc3RhbmRhcmRpemVkUHJvbXB0ID0gYXdhaXQgc3RhbmRhcmRpemVQcm9tcHQoe1xuICAgICAgICAgIHN5c3RlbSxcbiAgICAgICAgICBwcm9tcHQsXG4gICAgICAgICAgbWVzc2FnZXMsXG4gICAgICAgIH0gYXMgUHJvbXB0KTtcblxuICAgICAgICBjb25zdCBjYWxsT3B0aW9ucyA9IHtcbiAgICAgICAgICByZXNwb25zZUZvcm1hdDoge1xuICAgICAgICAgICAgdHlwZTogJ2pzb24nIGFzIGNvbnN0LFxuICAgICAgICAgICAgc2NoZW1hOiBvdXRwdXRTdHJhdGVneS5qc29uU2NoZW1hLFxuICAgICAgICAgICAgbmFtZTogc2NoZW1hTmFtZSxcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBzY2hlbWFEZXNjcmlwdGlvbixcbiAgICAgICAgICB9LFxuICAgICAgICAgIC4uLnByZXBhcmVDYWxsU2V0dGluZ3Moc2V0dGluZ3MpLFxuICAgICAgICAgIHByb21wdDogYXdhaXQgY29udmVydFRvTGFuZ3VhZ2VNb2RlbFByb21wdCh7XG4gICAgICAgICAgICBwcm9tcHQ6IHN0YW5kYXJkaXplZFByb21wdCxcbiAgICAgICAgICAgIHN1cHBvcnRlZFVybHM6IGF3YWl0IG1vZGVsLnN1cHBvcnRlZFVybHMsXG4gICAgICAgICAgICBkb3dubG9hZCxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBwcm92aWRlck9wdGlvbnMsXG4gICAgICAgICAgYWJvcnRTaWduYWwsXG4gICAgICAgICAgaGVhZGVycyxcbiAgICAgICAgICBpbmNsdWRlUmF3Q2h1bmtzOiBmYWxzZSxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCB0cmFuc2Zvcm1lcjogVHJhbnNmb3JtZXI8XG4gICAgICAgICAgTGFuZ3VhZ2VNb2RlbFYyU3RyZWFtUGFydCxcbiAgICAgICAgICBPYmplY3RTdHJlYW1JbnB1dFBhcnRcbiAgICAgICAgPiA9IHtcbiAgICAgICAgICB0cmFuc2Zvcm06IChjaHVuaywgY29udHJvbGxlcikgPT4ge1xuICAgICAgICAgICAgc3dpdGNoIChjaHVuay50eXBlKSB7XG4gICAgICAgICAgICAgIGNhc2UgJ3RleHQtZGVsdGEnOlxuICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShjaHVuay5kZWx0YSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgJ3Jlc3BvbnNlLW1ldGFkYXRhJzpcbiAgICAgICAgICAgICAgY2FzZSAnZmluaXNoJzpcbiAgICAgICAgICAgICAgY2FzZSAnZXJyb3InOlxuICAgICAgICAgICAgICBjYXNlICdzdHJlYW0tc3RhcnQnOlxuICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShjaHVuayk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCB7XG4gICAgICAgICAgcmVzdWx0OiB7IHN0cmVhbSwgcmVzcG9uc2UsIHJlcXVlc3QgfSxcbiAgICAgICAgICBkb1N0cmVhbVNwYW4sXG4gICAgICAgICAgc3RhcnRUaW1lc3RhbXBNcyxcbiAgICAgICAgfSA9IGF3YWl0IHJldHJ5KCgpID0+XG4gICAgICAgICAgcmVjb3JkU3Bhbih7XG4gICAgICAgICAgICBuYW1lOiAnYWkuc3RyZWFtT2JqZWN0LmRvU3RyZWFtJyxcbiAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHNlbGVjdFRlbGVtZXRyeUF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgICB0ZWxlbWV0cnksXG4gICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgICAgICAgICAuLi5hc3NlbWJsZU9wZXJhdGlvbk5hbWUoe1xuICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uSWQ6ICdhaS5zdHJlYW1PYmplY3QuZG9TdHJlYW0nLFxuICAgICAgICAgICAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIC4uLmJhc2VUZWxlbWV0cnlBdHRyaWJ1dGVzLFxuICAgICAgICAgICAgICAgICdhaS5wcm9tcHQubWVzc2FnZXMnOiB7XG4gICAgICAgICAgICAgICAgICBpbnB1dDogKCkgPT4gc3RyaW5naWZ5Rm9yVGVsZW1ldHJ5KGNhbGxPcHRpb25zLnByb21wdCksXG4gICAgICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgICAgIC8vIHN0YW5kYXJkaXplZCBnZW4tYWkgbGxtIHNwYW4gYXR0cmlidXRlczpcbiAgICAgICAgICAgICAgICAnZ2VuX2FpLnN5c3RlbSc6IG1vZGVsLnByb3ZpZGVyLFxuICAgICAgICAgICAgICAgICdnZW5fYWkucmVxdWVzdC5tb2RlbCc6IG1vZGVsLm1vZGVsSWQsXG4gICAgICAgICAgICAgICAgJ2dlbl9haS5yZXF1ZXN0LmZyZXF1ZW5jeV9wZW5hbHR5JzpcbiAgICAgICAgICAgICAgICAgIGNhbGxTZXR0aW5ncy5mcmVxdWVuY3lQZW5hbHR5LFxuICAgICAgICAgICAgICAgICdnZW5fYWkucmVxdWVzdC5tYXhfdG9rZW5zJzogY2FsbFNldHRpbmdzLm1heE91dHB1dFRva2VucyxcbiAgICAgICAgICAgICAgICAnZ2VuX2FpLnJlcXVlc3QucHJlc2VuY2VfcGVuYWx0eSc6IGNhbGxTZXR0aW5ncy5wcmVzZW5jZVBlbmFsdHksXG4gICAgICAgICAgICAgICAgJ2dlbl9haS5yZXF1ZXN0LnRlbXBlcmF0dXJlJzogY2FsbFNldHRpbmdzLnRlbXBlcmF0dXJlLFxuICAgICAgICAgICAgICAgICdnZW5fYWkucmVxdWVzdC50b3Bfayc6IGNhbGxTZXR0aW5ncy50b3BLLFxuICAgICAgICAgICAgICAgICdnZW5fYWkucmVxdWVzdC50b3BfcCc6IGNhbGxTZXR0aW5ncy50b3BQLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB0cmFjZXIsXG4gICAgICAgICAgICBlbmRXaGVuRG9uZTogZmFsc2UsXG4gICAgICAgICAgICBmbjogYXN5bmMgZG9TdHJlYW1TcGFuID0+ICh7XG4gICAgICAgICAgICAgIHN0YXJ0VGltZXN0YW1wTXM6IG5vdygpLFxuICAgICAgICAgICAgICBkb1N0cmVhbVNwYW4sXG4gICAgICAgICAgICAgIHJlc3VsdDogYXdhaXQgbW9kZWwuZG9TdHJlYW0oY2FsbE9wdGlvbnMpLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG5cbiAgICAgICAgc2VsZi5fcmVxdWVzdC5yZXNvbHZlKHJlcXVlc3QgPz8ge30pO1xuXG4gICAgICAgIC8vIHN0b3JlIGluZm9ybWF0aW9uIGZvciBvbkZpbmlzaCBjYWxsYmFjazpcbiAgICAgICAgbGV0IHdhcm5pbmdzOiBMYW5ndWFnZU1vZGVsVjJDYWxsV2FybmluZ1tdIHwgdW5kZWZpbmVkO1xuICAgICAgICBsZXQgdXNhZ2U6IExhbmd1YWdlTW9kZWxVc2FnZSA9IHtcbiAgICAgICAgICBpbnB1dFRva2VuczogdW5kZWZpbmVkLFxuICAgICAgICAgIG91dHB1dFRva2VuczogdW5kZWZpbmVkLFxuICAgICAgICAgIHRvdGFsVG9rZW5zOiB1bmRlZmluZWQsXG4gICAgICAgIH07XG4gICAgICAgIGxldCBmaW5pc2hSZWFzb246IExhbmd1YWdlTW9kZWxWMkZpbmlzaFJlYXNvbiB8IHVuZGVmaW5lZDtcbiAgICAgICAgbGV0IHByb3ZpZGVyTWV0YWRhdGE6IFByb3ZpZGVyTWV0YWRhdGEgfCB1bmRlZmluZWQ7XG4gICAgICAgIGxldCBvYmplY3Q6IFJFU1VMVCB8IHVuZGVmaW5lZDtcbiAgICAgICAgbGV0IGVycm9yOiB1bmtub3duIHwgdW5kZWZpbmVkO1xuXG4gICAgICAgIC8vIHBpcGUgY2h1bmtzIHRocm91Z2ggYSB0cmFuc2Zvcm1hdGlvbiBzdHJlYW0gdGhhdCBleHRyYWN0cyBtZXRhZGF0YTpcbiAgICAgICAgbGV0IGFjY3VtdWxhdGVkVGV4dCA9ICcnO1xuICAgICAgICBsZXQgdGV4dERlbHRhID0gJyc7XG4gICAgICAgIGxldCBmdWxsUmVzcG9uc2U6IHtcbiAgICAgICAgICBpZDogc3RyaW5nO1xuICAgICAgICAgIHRpbWVzdGFtcDogRGF0ZTtcbiAgICAgICAgICBtb2RlbElkOiBzdHJpbmc7XG4gICAgICAgIH0gPSB7XG4gICAgICAgICAgaWQ6IGdlbmVyYXRlSWQoKSxcbiAgICAgICAgICB0aW1lc3RhbXA6IGN1cnJlbnREYXRlKCksXG4gICAgICAgICAgbW9kZWxJZDogbW9kZWwubW9kZWxJZCxcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBLZWVwIHRyYWNrIG9mIHJhdyBwYXJzZSByZXN1bHQgYmVmb3JlIHR5cGUgdmFsaWRhdGlvbiwgc2luY2UgZS5nLiBab2QgbWlnaHRcbiAgICAgICAgLy8gY2hhbmdlIHRoZSBvYmplY3QgYnkgbWFwcGluZyBwcm9wZXJ0aWVzLlxuICAgICAgICBsZXQgbGF0ZXN0T2JqZWN0SnNvbjogSlNPTlZhbHVlIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgICAgICBsZXQgbGF0ZXN0T2JqZWN0OiBQQVJUSUFMIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgICAgICBsZXQgaXNGaXJzdENodW5rID0gdHJ1ZTtcbiAgICAgICAgbGV0IGlzRmlyc3REZWx0YSA9IHRydWU7XG5cbiAgICAgICAgY29uc3QgdHJhbnNmb3JtZWRTdHJlYW0gPSBzdHJlYW1cbiAgICAgICAgICAucGlwZVRocm91Z2gobmV3IFRyYW5zZm9ybVN0cmVhbSh0cmFuc2Zvcm1lcikpXG4gICAgICAgICAgLnBpcGVUaHJvdWdoKFxuICAgICAgICAgICAgbmV3IFRyYW5zZm9ybVN0cmVhbTxcbiAgICAgICAgICAgICAgc3RyaW5nIHwgT2JqZWN0U3RyZWFtSW5wdXRQYXJ0LFxuICAgICAgICAgICAgICBPYmplY3RTdHJlYW1QYXJ0PFBBUlRJQUw+XG4gICAgICAgICAgICA+KHtcbiAgICAgICAgICAgICAgYXN5bmMgdHJhbnNmb3JtKGNodW5rLCBjb250cm9sbGVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgdHlwZW9mIGNodW5rID09PSAnb2JqZWN0JyAmJlxuICAgICAgICAgICAgICAgICAgY2h1bmsudHlwZSA9PT0gJ3N0cmVhbS1zdGFydCdcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgIHdhcm5pbmdzID0gY2h1bmsud2FybmluZ3M7XG4gICAgICAgICAgICAgICAgICByZXR1cm47IC8vIHN0cmVhbSBzdGFydCBjaHVua3MgYXJlIHNlbnQgaW1tZWRpYXRlbHkgYW5kIGRvIG5vdCBjb3VudCBhcyBmaXJzdCBjaHVua1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIFRlbGVtZXRyeSBldmVudCBmb3IgZmlyc3QgY2h1bms6XG4gICAgICAgICAgICAgICAgaWYgKGlzRmlyc3RDaHVuaykge1xuICAgICAgICAgICAgICAgICAgY29uc3QgbXNUb0ZpcnN0Q2h1bmsgPSBub3coKSAtIHN0YXJ0VGltZXN0YW1wTXM7XG5cbiAgICAgICAgICAgICAgICAgIGlzRmlyc3RDaHVuayA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgICBkb1N0cmVhbVNwYW4uYWRkRXZlbnQoJ2FpLnN0cmVhbS5maXJzdENodW5rJywge1xuICAgICAgICAgICAgICAgICAgICAnYWkuc3RyZWFtLm1zVG9GaXJzdENodW5rJzogbXNUb0ZpcnN0Q2h1bmssXG4gICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgZG9TdHJlYW1TcGFuLnNldEF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgICAgICAgICAnYWkuc3RyZWFtLm1zVG9GaXJzdENodW5rJzogbXNUb0ZpcnN0Q2h1bmssXG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBwcm9jZXNzIHBhcnRpYWwgdGV4dCBjaHVua3NcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGNodW5rID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgICAgYWNjdW11bGF0ZWRUZXh0ICs9IGNodW5rO1xuICAgICAgICAgICAgICAgICAgdGV4dERlbHRhICs9IGNodW5rO1xuXG4gICAgICAgICAgICAgICAgICBjb25zdCB7IHZhbHVlOiBjdXJyZW50T2JqZWN0SnNvbiwgc3RhdGU6IHBhcnNlU3RhdGUgfSA9XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHBhcnNlUGFydGlhbEpzb24oYWNjdW11bGF0ZWRUZXh0KTtcblxuICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICBjdXJyZW50T2JqZWN0SnNvbiAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAgICAgICAgICAgICAgICFpc0RlZXBFcXVhbERhdGEobGF0ZXN0T2JqZWN0SnNvbiwgY3VycmVudE9iamVjdEpzb24pXG4gICAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsaWRhdGlvblJlc3VsdCA9XG4gICAgICAgICAgICAgICAgICAgICAgYXdhaXQgb3V0cHV0U3RyYXRlZ3kudmFsaWRhdGVQYXJ0aWFsUmVzdWx0KHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiBjdXJyZW50T2JqZWN0SnNvbixcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHREZWx0YSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGxhdGVzdE9iamVjdCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzRmlyc3REZWx0YSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzRmluYWxEZWx0YTogcGFyc2VTdGF0ZSA9PT0gJ3N1Y2Nlc3NmdWwtcGFyc2UnLFxuICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uUmVzdWx0LnN1Y2Nlc3MgJiZcbiAgICAgICAgICAgICAgICAgICAgICAhaXNEZWVwRXF1YWxEYXRhKFxuICAgICAgICAgICAgICAgICAgICAgICAgbGF0ZXN0T2JqZWN0LFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGlvblJlc3VsdC52YWx1ZS5wYXJ0aWFsLFxuICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgLy8gaW5zaWRlIGlubmVyIGNoZWNrIHRvIGNvcnJlY3RseSBwYXJzZSB0aGUgZmluYWwgZWxlbWVudCBpbiBhcnJheSBtb2RlOlxuICAgICAgICAgICAgICAgICAgICAgIGxhdGVzdE9iamVjdEpzb24gPSBjdXJyZW50T2JqZWN0SnNvbjtcbiAgICAgICAgICAgICAgICAgICAgICBsYXRlc3RPYmplY3QgPSB2YWxpZGF0aW9uUmVzdWx0LnZhbHVlLnBhcnRpYWw7XG5cbiAgICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICBvYmplY3Q6IGxhdGVzdE9iamVjdCxcbiAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAndGV4dC1kZWx0YScsXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0RGVsdGE6IHZhbGlkYXRpb25SZXN1bHQudmFsdWUudGV4dERlbHRhLFxuICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgdGV4dERlbHRhID0gJyc7XG4gICAgICAgICAgICAgICAgICAgICAgaXNGaXJzdERlbHRhID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHN3aXRjaCAoY2h1bmsudHlwZSkge1xuICAgICAgICAgICAgICAgICAgY2FzZSAncmVzcG9uc2UtbWV0YWRhdGEnOiB7XG4gICAgICAgICAgICAgICAgICAgIGZ1bGxSZXNwb25zZSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICBpZDogY2h1bmsuaWQgPz8gZnVsbFJlc3BvbnNlLmlkLFxuICAgICAgICAgICAgICAgICAgICAgIHRpbWVzdGFtcDogY2h1bmsudGltZXN0YW1wID8/IGZ1bGxSZXNwb25zZS50aW1lc3RhbXAsXG4gICAgICAgICAgICAgICAgICAgICAgbW9kZWxJZDogY2h1bmsubW9kZWxJZCA/PyBmdWxsUmVzcG9uc2UubW9kZWxJZCxcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgIGNhc2UgJ2ZpbmlzaCc6IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gc2VuZCBmaW5hbCB0ZXh0IGRlbHRhOlxuICAgICAgICAgICAgICAgICAgICBpZiAodGV4dERlbHRhICE9PSAnJykge1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7IHR5cGU6ICd0ZXh0LWRlbHRhJywgdGV4dERlbHRhIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gc3RvcmUgZmluaXNoIHJlYXNvbiBmb3IgdGVsZW1ldHJ5OlxuICAgICAgICAgICAgICAgICAgICBmaW5pc2hSZWFzb24gPSBjaHVuay5maW5pc2hSZWFzb247XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gc3RvcmUgdXNhZ2UgYW5kIG1ldGFkYXRhIGZvciBwcm9taXNlcyBhbmQgb25GaW5pc2ggY2FsbGJhY2s6XG4gICAgICAgICAgICAgICAgICAgIHVzYWdlID0gY2h1bmsudXNhZ2U7XG4gICAgICAgICAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGEgPSBjaHVuay5wcm92aWRlck1ldGFkYXRhO1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgLi4uY2h1bmssXG4gICAgICAgICAgICAgICAgICAgICAgdXNhZ2UsXG4gICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2U6IGZ1bGxSZXNwb25zZSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gbG9nIHdhcm5pbmdzOlxuICAgICAgICAgICAgICAgICAgICBsb2dXYXJuaW5ncyh3YXJuaW5ncyA/PyBbXSk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gcmVzb2x2ZSBwcm9taXNlcyB0aGF0IGNhbiBiZSByZXNvbHZlZCBub3c6XG4gICAgICAgICAgICAgICAgICAgIHNlbGYuX3VzYWdlLnJlc29sdmUodXNhZ2UpO1xuICAgICAgICAgICAgICAgICAgICBzZWxmLl9wcm92aWRlck1ldGFkYXRhLnJlc29sdmUocHJvdmlkZXJNZXRhZGF0YSk7XG4gICAgICAgICAgICAgICAgICAgIHNlbGYuX3dhcm5pbmdzLnJlc29sdmUod2FybmluZ3MpO1xuICAgICAgICAgICAgICAgICAgICBzZWxmLl9yZXNwb25zZS5yZXNvbHZlKHtcbiAgICAgICAgICAgICAgICAgICAgICAuLi5mdWxsUmVzcG9uc2UsXG4gICAgICAgICAgICAgICAgICAgICAgaGVhZGVyczogcmVzcG9uc2U/LmhlYWRlcnMsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzZWxmLl9maW5pc2hSZWFzb24ucmVzb2x2ZShmaW5pc2hSZWFzb24gPz8gJ3Vua25vd24nKTtcblxuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgIG9iamVjdCA9IGF3YWl0IHBhcnNlQW5kVmFsaWRhdGVPYmplY3RSZXN1bHRXaXRoUmVwYWlyKFxuICAgICAgICAgICAgICAgICAgICAgICAgYWNjdW11bGF0ZWRUZXh0LFxuICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0U3RyYXRlZ3ksXG4gICAgICAgICAgICAgICAgICAgICAgICByZXBhaXJUZXh0LFxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZTogZnVsbFJlc3BvbnNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICB1c2FnZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZmluaXNoUmVhc29uLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX29iamVjdC5yZXNvbHZlKG9iamVjdCk7XG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9IGU7XG4gICAgICAgICAgICAgICAgICAgICAgc2VsZi5fb2JqZWN0LnJlamVjdChlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoY2h1bmspO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgICAgLy8gaW52b2tlIG9uRmluaXNoIGNhbGxiYWNrIGFuZCByZXNvbHZlIHRvb2xSZXN1bHRzIHByb21pc2Ugd2hlbiB0aGUgc3RyZWFtIGlzIGFib3V0IHRvIGNsb3NlOlxuICAgICAgICAgICAgICBhc3luYyBmbHVzaChjb250cm9sbGVyKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGZpbmFsVXNhZ2UgPSB1c2FnZSA/PyB7XG4gICAgICAgICAgICAgICAgICAgIHByb21wdFRva2VuczogTmFOLFxuICAgICAgICAgICAgICAgICAgICBjb21wbGV0aW9uVG9rZW5zOiBOYU4sXG4gICAgICAgICAgICAgICAgICAgIHRvdGFsVG9rZW5zOiBOYU4sXG4gICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICBkb1N0cmVhbVNwYW4uc2V0QXR0cmlidXRlcyhcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0VGVsZW1ldHJ5QXR0cmlidXRlcyh7XG4gICAgICAgICAgICAgICAgICAgICAgdGVsZW1ldHJ5LFxuICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICdhaS5yZXNwb25zZS5maW5pc2hSZWFzb24nOiBmaW5pc2hSZWFzb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAnYWkucmVzcG9uc2Uub2JqZWN0Jzoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQ6ICgpID0+IEpTT04uc3RyaW5naWZ5KG9iamVjdCksXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLmlkJzogZnVsbFJlc3BvbnNlLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLm1vZGVsJzogZnVsbFJlc3BvbnNlLm1vZGVsSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAnYWkucmVzcG9uc2UudGltZXN0YW1wJzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZnVsbFJlc3BvbnNlLnRpbWVzdGFtcC50b0lTT1N0cmluZygpLFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLnByb3ZpZGVyTWV0YWRhdGEnOlxuICAgICAgICAgICAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeShwcm92aWRlck1ldGFkYXRhKSxcblxuICAgICAgICAgICAgICAgICAgICAgICAgJ2FpLnVzYWdlLmlucHV0VG9rZW5zJzogZmluYWxVc2FnZS5pbnB1dFRva2VucyxcbiAgICAgICAgICAgICAgICAgICAgICAgICdhaS51c2FnZS5vdXRwdXRUb2tlbnMnOiBmaW5hbFVzYWdlLm91dHB1dFRva2VucyxcbiAgICAgICAgICAgICAgICAgICAgICAgICdhaS51c2FnZS50b3RhbFRva2Vucyc6IGZpbmFsVXNhZ2UudG90YWxUb2tlbnMsXG4gICAgICAgICAgICAgICAgICAgICAgICAnYWkudXNhZ2UucmVhc29uaW5nVG9rZW5zJzogZmluYWxVc2FnZS5yZWFzb25pbmdUb2tlbnMsXG4gICAgICAgICAgICAgICAgICAgICAgICAnYWkudXNhZ2UuY2FjaGVkSW5wdXRUb2tlbnMnOlxuICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFVzYWdlLmNhY2hlZElucHV0VG9rZW5zLFxuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBzdGFuZGFyZGl6ZWQgZ2VuLWFpIGxsbSBzcGFuIGF0dHJpYnV0ZXM6XG4gICAgICAgICAgICAgICAgICAgICAgICAnZ2VuX2FpLnJlc3BvbnNlLmZpbmlzaF9yZWFzb25zJzogW2ZpbmlzaFJlYXNvbl0sXG4gICAgICAgICAgICAgICAgICAgICAgICAnZ2VuX2FpLnJlc3BvbnNlLmlkJzogZnVsbFJlc3BvbnNlLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2dlbl9haS5yZXNwb25zZS5tb2RlbCc6IGZ1bGxSZXNwb25zZS5tb2RlbElkLFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2dlbl9haS51c2FnZS5pbnB1dF90b2tlbnMnOiBmaW5hbFVzYWdlLmlucHV0VG9rZW5zLFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2dlbl9haS51c2FnZS5vdXRwdXRfdG9rZW5zJzogZmluYWxVc2FnZS5vdXRwdXRUb2tlbnMsXG4gICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgICAvLyBmaW5pc2ggZG9TdHJlYW1TcGFuIGJlZm9yZSBvdGhlciBvcGVyYXRpb25zIGZvciBjb3JyZWN0IHRpbWluZzpcbiAgICAgICAgICAgICAgICAgIGRvU3RyZWFtU3Bhbi5lbmQoKTtcblxuICAgICAgICAgICAgICAgICAgLy8gQWRkIHJlc3BvbnNlIGluZm9ybWF0aW9uIHRvIHRoZSByb290IHNwYW46XG4gICAgICAgICAgICAgICAgICByb290U3Bhbi5zZXRBdHRyaWJ1dGVzKFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RUZWxlbWV0cnlBdHRyaWJ1dGVzKHtcbiAgICAgICAgICAgICAgICAgICAgICB0ZWxlbWV0cnksXG4gICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAgICAgICAgICAgICAgICAgJ2FpLnVzYWdlLmlucHV0VG9rZW5zJzogZmluYWxVc2FnZS5pbnB1dFRva2VucyxcbiAgICAgICAgICAgICAgICAgICAgICAgICdhaS51c2FnZS5vdXRwdXRUb2tlbnMnOiBmaW5hbFVzYWdlLm91dHB1dFRva2VucyxcbiAgICAgICAgICAgICAgICAgICAgICAgICdhaS51c2FnZS50b3RhbFRva2Vucyc6IGZpbmFsVXNhZ2UudG90YWxUb2tlbnMsXG4gICAgICAgICAgICAgICAgICAgICAgICAnYWkudXNhZ2UucmVhc29uaW5nVG9rZW5zJzogZmluYWxVc2FnZS5yZWFzb25pbmdUb2tlbnMsXG4gICAgICAgICAgICAgICAgICAgICAgICAnYWkudXNhZ2UuY2FjaGVkSW5wdXRUb2tlbnMnOlxuICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFVzYWdlLmNhY2hlZElucHV0VG9rZW5zLFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2FpLnJlc3BvbnNlLm9iamVjdCc6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0OiAoKSA9PiBKU09OLnN0cmluZ2lmeShvYmplY3QpLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICdhaS5yZXNwb25zZS5wcm92aWRlck1ldGFkYXRhJzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkocHJvdmlkZXJNZXRhZGF0YSksXG4gICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgICAvLyBjYWxsIG9uRmluaXNoIGNhbGxiYWNrOlxuICAgICAgICAgICAgICAgICAgYXdhaXQgb25GaW5pc2g/Lih7XG4gICAgICAgICAgICAgICAgICAgIHVzYWdlOiBmaW5hbFVzYWdlLFxuICAgICAgICAgICAgICAgICAgICBvYmplY3QsXG4gICAgICAgICAgICAgICAgICAgIGVycm9yLFxuICAgICAgICAgICAgICAgICAgICByZXNwb25zZToge1xuICAgICAgICAgICAgICAgICAgICAgIC4uLmZ1bGxSZXNwb25zZSxcbiAgICAgICAgICAgICAgICAgICAgICBoZWFkZXJzOiByZXNwb25zZT8uaGVhZGVycyxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgd2FybmluZ3MsXG4gICAgICAgICAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGEsXG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHsgdHlwZTogJ2Vycm9yJywgZXJyb3IgfSk7XG4gICAgICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICAgIHJvb3RTcGFuLmVuZCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICk7XG5cbiAgICAgICAgc3RpdGNoYWJsZVN0cmVhbS5hZGRTdHJlYW0odHJhbnNmb3JtZWRTdHJlYW0pO1xuICAgICAgfSxcbiAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgLy8gYWRkIGFuIGVtcHR5IHN0cmVhbSB3aXRoIGFuIGVycm9yIHRvIGJyZWFrIHRoZSBzdHJlYW06XG4gICAgICAgIHN0aXRjaGFibGVTdHJlYW0uYWRkU3RyZWFtKFxuICAgICAgICAgIG5ldyBSZWFkYWJsZVN0cmVhbSh7XG4gICAgICAgICAgICBzdGFydChjb250cm9sbGVyKSB7XG4gICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7IHR5cGU6ICdlcnJvcicsIGVycm9yIH0pO1xuICAgICAgICAgICAgICBjb250cm9sbGVyLmNsb3NlKCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgfSlcbiAgICAgIC5maW5hbGx5KCgpID0+IHtcbiAgICAgICAgc3RpdGNoYWJsZVN0cmVhbS5jbG9zZSgpO1xuICAgICAgfSk7XG5cbiAgICB0aGlzLm91dHB1dFN0cmF0ZWd5ID0gb3V0cHV0U3RyYXRlZ3k7XG4gIH1cblxuICBnZXQgb2JqZWN0KCkge1xuICAgIHJldHVybiB0aGlzLl9vYmplY3QucHJvbWlzZTtcbiAgfVxuXG4gIGdldCB1c2FnZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fdXNhZ2UucHJvbWlzZTtcbiAgfVxuXG4gIGdldCBwcm92aWRlck1ldGFkYXRhKCkge1xuICAgIHJldHVybiB0aGlzLl9wcm92aWRlck1ldGFkYXRhLnByb21pc2U7XG4gIH1cblxuICBnZXQgd2FybmluZ3MoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3dhcm5pbmdzLnByb21pc2U7XG4gIH1cblxuICBnZXQgcmVxdWVzdCgpIHtcbiAgICByZXR1cm4gdGhpcy5fcmVxdWVzdC5wcm9taXNlO1xuICB9XG5cbiAgZ2V0IHJlc3BvbnNlKCkge1xuICAgIHJldHVybiB0aGlzLl9yZXNwb25zZS5wcm9taXNlO1xuICB9XG5cbiAgZ2V0IGZpbmlzaFJlYXNvbigpIHtcbiAgICByZXR1cm4gdGhpcy5fZmluaXNoUmVhc29uLnByb21pc2U7XG4gIH1cblxuICBnZXQgcGFydGlhbE9iamVjdFN0cmVhbSgpOiBBc3luY0l0ZXJhYmxlU3RyZWFtPFBBUlRJQUw+IHtcbiAgICByZXR1cm4gY3JlYXRlQXN5bmNJdGVyYWJsZVN0cmVhbShcbiAgICAgIHRoaXMuYmFzZVN0cmVhbS5waXBlVGhyb3VnaChcbiAgICAgICAgbmV3IFRyYW5zZm9ybVN0cmVhbTxPYmplY3RTdHJlYW1QYXJ0PFBBUlRJQUw+LCBQQVJUSUFMPih7XG4gICAgICAgICAgdHJhbnNmb3JtKGNodW5rLCBjb250cm9sbGVyKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKGNodW5rLnR5cGUpIHtcbiAgICAgICAgICAgICAgY2FzZSAnb2JqZWN0JzpcbiAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoY2h1bmsub2JqZWN0KTtcbiAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICBjYXNlICd0ZXh0LWRlbHRhJzpcbiAgICAgICAgICAgICAgY2FzZSAnZmluaXNoJzpcbiAgICAgICAgICAgICAgY2FzZSAnZXJyb3InOiAvLyBzdXBwcmVzcyBlcnJvciAodXNlIG9uRXJyb3IgaW5zdGVhZClcbiAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgY29uc3QgX2V4aGF1c3RpdmVDaGVjazogbmV2ZXIgPSBjaHVuaztcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIGNodW5rIHR5cGU6ICR7X2V4aGF1c3RpdmVDaGVja31gKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgKSxcbiAgICApO1xuICB9XG5cbiAgZ2V0IGVsZW1lbnRTdHJlYW0oKTogRUxFTUVOVF9TVFJFQU0ge1xuICAgIHJldHVybiB0aGlzLm91dHB1dFN0cmF0ZWd5LmNyZWF0ZUVsZW1lbnRTdHJlYW0odGhpcy5iYXNlU3RyZWFtKTtcbiAgfVxuXG4gIGdldCB0ZXh0U3RyZWFtKCk6IEFzeW5jSXRlcmFibGVTdHJlYW08c3RyaW5nPiB7XG4gICAgcmV0dXJuIGNyZWF0ZUFzeW5jSXRlcmFibGVTdHJlYW0oXG4gICAgICB0aGlzLmJhc2VTdHJlYW0ucGlwZVRocm91Z2goXG4gICAgICAgIG5ldyBUcmFuc2Zvcm1TdHJlYW08T2JqZWN0U3RyZWFtUGFydDxQQVJUSUFMPiwgc3RyaW5nPih7XG4gICAgICAgICAgdHJhbnNmb3JtKGNodW5rLCBjb250cm9sbGVyKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKGNodW5rLnR5cGUpIHtcbiAgICAgICAgICAgICAgY2FzZSAndGV4dC1kZWx0YSc6XG4gICAgICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKGNodW5rLnRleHREZWx0YSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgICAgY2FzZSAnb2JqZWN0JzpcbiAgICAgICAgICAgICAgY2FzZSAnZmluaXNoJzpcbiAgICAgICAgICAgICAgY2FzZSAnZXJyb3InOiAvLyBzdXBwcmVzcyBlcnJvciAodXNlIG9uRXJyb3IgaW5zdGVhZClcbiAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgY29uc3QgX2V4aGF1c3RpdmVDaGVjazogbmV2ZXIgPSBjaHVuaztcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIGNodW5rIHR5cGU6ICR7X2V4aGF1c3RpdmVDaGVja31gKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgKSxcbiAgICApO1xuICB9XG5cbiAgZ2V0IGZ1bGxTdHJlYW0oKTogQXN5bmNJdGVyYWJsZVN0cmVhbTxPYmplY3RTdHJlYW1QYXJ0PFBBUlRJQUw+PiB7XG4gICAgcmV0dXJuIGNyZWF0ZUFzeW5jSXRlcmFibGVTdHJlYW0odGhpcy5iYXNlU3RyZWFtKTtcbiAgfVxuXG4gIHBpcGVUZXh0U3RyZWFtVG9SZXNwb25zZShyZXNwb25zZTogU2VydmVyUmVzcG9uc2UsIGluaXQ/OiBSZXNwb25zZUluaXQpIHtcbiAgICBwaXBlVGV4dFN0cmVhbVRvUmVzcG9uc2Uoe1xuICAgICAgcmVzcG9uc2UsXG4gICAgICB0ZXh0U3RyZWFtOiB0aGlzLnRleHRTdHJlYW0sXG4gICAgICAuLi5pbml0LFxuICAgIH0pO1xuICB9XG5cbiAgdG9UZXh0U3RyZWFtUmVzcG9uc2UoaW5pdD86IFJlc3BvbnNlSW5pdCk6IFJlc3BvbnNlIHtcbiAgICByZXR1cm4gY3JlYXRlVGV4dFN0cmVhbVJlc3BvbnNlKHtcbiAgICAgIHRleHRTdHJlYW06IHRoaXMudGV4dFN0cmVhbSxcbiAgICAgIC4uLmluaXQsXG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0IHR5cGUgT2JqZWN0U3RyZWFtSW5wdXRQYXJ0ID1cbiAgfCBzdHJpbmdcbiAgfCB7XG4gICAgICB0eXBlOiAnc3RyZWFtLXN0YXJ0JztcbiAgICAgIHdhcm5pbmdzOiBMYW5ndWFnZU1vZGVsVjJDYWxsV2FybmluZ1tdO1xuICAgIH1cbiAgfCB7XG4gICAgICB0eXBlOiAnZXJyb3InO1xuICAgICAgZXJyb3I6IHVua25vd247XG4gICAgfVxuICB8IHtcbiAgICAgIHR5cGU6ICdyZXNwb25zZS1tZXRhZGF0YSc7XG4gICAgICBpZD86IHN0cmluZztcbiAgICAgIHRpbWVzdGFtcD86IERhdGU7XG4gICAgICBtb2RlbElkPzogc3RyaW5nO1xuICAgIH1cbiAgfCB7XG4gICAgICB0eXBlOiAnZmluaXNoJztcbiAgICAgIGZpbmlzaFJlYXNvbjogTGFuZ3VhZ2VNb2RlbFYyRmluaXNoUmVhc29uO1xuICAgICAgdXNhZ2U6IExhbmd1YWdlTW9kZWxWMlVzYWdlO1xuICAgICAgcHJvdmlkZXJNZXRhZGF0YT86IFNoYXJlZFYyUHJvdmlkZXJNZXRhZGF0YTtcbiAgICB9O1xuIiwgImltcG9ydCB7IEludmFsaWRBcmd1bWVudEVycm9yIH0gZnJvbSAnLi4vZXJyb3IvaW52YWxpZC1hcmd1bWVudC1lcnJvcic7XG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgY29zaW5lIHNpbWlsYXJpdHkgYmV0d2VlbiB0d28gdmVjdG9ycy4gVGhpcyBpcyBhIHVzZWZ1bCBtZXRyaWMgZm9yXG4gKiBjb21wYXJpbmcgdGhlIHNpbWlsYXJpdHkgb2YgdHdvIHZlY3RvcnMgc3VjaCBhcyBlbWJlZGRpbmdzLlxuICpcbiAqIEBwYXJhbSB2ZWN0b3IxIC0gVGhlIGZpcnN0IHZlY3Rvci5cbiAqIEBwYXJhbSB2ZWN0b3IyIC0gVGhlIHNlY29uZCB2ZWN0b3IuXG4gKlxuICogQHJldHVybnMgVGhlIGNvc2luZSBzaW1pbGFyaXR5IGJldHdlZW4gdmVjdG9yMSBhbmQgdmVjdG9yMi5cbiAqIEByZXR1cm5zIDAgaWYgZWl0aGVyIHZlY3RvciBpcyB0aGUgemVybyB2ZWN0b3IuXG4gKlxuICogQHRocm93cyB7SW52YWxpZEFyZ3VtZW50RXJyb3J9IElmIHRoZSB2ZWN0b3JzIGRvIG5vdCBoYXZlIHRoZSBzYW1lIGxlbmd0aC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvc2luZVNpbWlsYXJpdHkodmVjdG9yMTogbnVtYmVyW10sIHZlY3RvcjI6IG51bWJlcltdKTogbnVtYmVyIHtcbiAgaWYgKHZlY3RvcjEubGVuZ3RoICE9PSB2ZWN0b3IyLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFcnJvcih7XG4gICAgICBwYXJhbWV0ZXI6ICd2ZWN0b3IxLHZlY3RvcjInLFxuICAgICAgdmFsdWU6IHsgdmVjdG9yMUxlbmd0aDogdmVjdG9yMS5sZW5ndGgsIHZlY3RvcjJMZW5ndGg6IHZlY3RvcjIubGVuZ3RoIH0sXG4gICAgICBtZXNzYWdlOiBgVmVjdG9ycyBtdXN0IGhhdmUgdGhlIHNhbWUgbGVuZ3RoYCxcbiAgICB9KTtcbiAgfVxuXG4gIGNvbnN0IG4gPSB2ZWN0b3IxLmxlbmd0aDtcblxuICBpZiAobiA9PT0gMCkge1xuICAgIHJldHVybiAwOyAvLyBSZXR1cm4gMCBmb3IgZW1wdHkgdmVjdG9ycyBpZiBubyBlcnJvciBpcyB0aHJvd25cbiAgfVxuXG4gIGxldCBtYWduaXR1ZGVTcXVhcmVkMSA9IDA7XG4gIGxldCBtYWduaXR1ZGVTcXVhcmVkMiA9IDA7XG4gIGxldCBkb3RQcm9kdWN0ID0gMDtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykge1xuICAgIGNvbnN0IHZhbHVlMSA9IHZlY3RvcjFbaV07XG4gICAgY29uc3QgdmFsdWUyID0gdmVjdG9yMltpXTtcblxuICAgIG1hZ25pdHVkZVNxdWFyZWQxICs9IHZhbHVlMSAqIHZhbHVlMTtcbiAgICBtYWduaXR1ZGVTcXVhcmVkMiArPSB2YWx1ZTIgKiB2YWx1ZTI7XG4gICAgZG90UHJvZHVjdCArPSB2YWx1ZTEgKiB2YWx1ZTI7XG4gIH1cblxuICByZXR1cm4gbWFnbml0dWRlU3F1YXJlZDEgPT09IDAgfHwgbWFnbml0dWRlU3F1YXJlZDIgPT09IDBcbiAgICA/IDBcbiAgICA6IGRvdFByb2R1Y3QgL1xuICAgICAgICAoTWF0aC5zcXJ0KG1hZ25pdHVkZVNxdWFyZWQxKSAqIE1hdGguc3FydChtYWduaXR1ZGVTcXVhcmVkMikpO1xufVxuIiwgIi8qKlxuICogQ29udmVydHMgYSBkYXRhIFVSTCBvZiB0eXBlIHRleHQvKiB0byBhIHRleHQgc3RyaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VGV4dEZyb21EYXRhVXJsKGRhdGFVcmw6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IFtoZWFkZXIsIGJhc2U2NENvbnRlbnRdID0gZGF0YVVybC5zcGxpdCgnLCcpO1xuICBjb25zdCBtZWRpYVR5cGUgPSBoZWFkZXIuc3BsaXQoJzsnKVswXS5zcGxpdCgnOicpWzFdO1xuXG4gIGlmIChtZWRpYVR5cGUgPT0gbnVsbCB8fCBiYXNlNjRDb250ZW50ID09IG51bGwpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgZGF0YSBVUkwgZm9ybWF0Jyk7XG4gIH1cblxuICB0cnkge1xuICAgIHJldHVybiB3aW5kb3cuYXRvYihiYXNlNjRDb250ZW50KTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEVycm9yIGRlY29kaW5nIGRhdGEgVVJMYCk7XG4gIH1cbn1cbiIsICIvKipcbiAqIFBlcmZvcm1zIGEgZGVlcC1lcXVhbCBjb21wYXJpc29uIG9mIHR3byBwYXJzZWQgSlNPTiBvYmplY3RzLlxuICpcbiAqIEBwYXJhbSB7YW55fSBvYmoxIC0gVGhlIGZpcnN0IG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHthbnl9IG9iajIgLSBUaGUgc2Vjb25kIG9iamVjdCB0byBjb21wYXJlLlxuICogQHJldHVybnMge2Jvb2xlYW59IC0gUmV0dXJucyB0cnVlIGlmIHRoZSB0d28gb2JqZWN0cyBhcmUgZGVlcGx5IGVxdWFsLCBmYWxzZSBvdGhlcndpc2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0RlZXBFcXVhbERhdGEob2JqMTogYW55LCBvYmoyOiBhbnkpOiBib29sZWFuIHtcbiAgLy8gQ2hlY2sgZm9yIHN0cmljdCBlcXVhbGl0eSBmaXJzdFxuICBpZiAob2JqMSA9PT0gb2JqMikgcmV0dXJuIHRydWU7XG5cbiAgLy8gQ2hlY2sgaWYgZWl0aGVyIGlzIG51bGwgb3IgdW5kZWZpbmVkXG4gIGlmIChvYmoxID09IG51bGwgfHwgb2JqMiA9PSBudWxsKSByZXR1cm4gZmFsc2U7XG5cbiAgLy8gQ2hlY2sgaWYgYm90aCBhcmUgb2JqZWN0c1xuICBpZiAodHlwZW9mIG9iajEgIT09ICdvYmplY3QnICYmIHR5cGVvZiBvYmoyICE9PSAnb2JqZWN0JylcbiAgICByZXR1cm4gb2JqMSA9PT0gb2JqMjtcblxuICAvLyBJZiB0aGV5IGFyZSBub3Qgc3RyaWN0bHkgZXF1YWwsIHRoZXkgYm90aCBuZWVkIHRvIGJlIE9iamVjdHNcbiAgaWYgKG9iajEuY29uc3RydWN0b3IgIT09IG9iajIuY29uc3RydWN0b3IpIHJldHVybiBmYWxzZTtcblxuICAvLyBTcGVjaWFsIGhhbmRsaW5nIGZvciBEYXRlIG9iamVjdHNcbiAgaWYgKG9iajEgaW5zdGFuY2VvZiBEYXRlICYmIG9iajIgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgcmV0dXJuIG9iajEuZ2V0VGltZSgpID09PSBvYmoyLmdldFRpbWUoKTtcbiAgfVxuXG4gIC8vIEhhbmRsZSBhcnJheXM6IGNvbXBhcmUgbGVuZ3RoIGFuZCB0aGVuIHBlcmZvcm0gYSByZWN1cnNpdmUgZGVlcCBjb21wYXJpc29uIG9uIGVhY2ggaXRlbVxuICBpZiAoQXJyYXkuaXNBcnJheShvYmoxKSkge1xuICAgIGlmIChvYmoxLmxlbmd0aCAhPT0gb2JqMi5sZW5ndGgpIHJldHVybiBmYWxzZTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9iajEubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmICghaXNEZWVwRXF1YWxEYXRhKG9iajFbaV0sIG9iajJbaV0pKSByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlOyAvLyBBbGwgYXJyYXkgZWxlbWVudHMgbWF0Y2hlZFxuICB9XG5cbiAgLy8gQ29tcGFyZSB0aGUgc2V0IG9mIGtleXMgaW4gZWFjaCBvYmplY3RcbiAgY29uc3Qga2V5czEgPSBPYmplY3Qua2V5cyhvYmoxKTtcbiAgY29uc3Qga2V5czIgPSBPYmplY3Qua2V5cyhvYmoyKTtcbiAgaWYgKGtleXMxLmxlbmd0aCAhPT0ga2V5czIubGVuZ3RoKSByZXR1cm4gZmFsc2U7XG5cbiAgLy8gQ2hlY2sgZWFjaCBrZXktdmFsdWUgcGFpciByZWN1cnNpdmVseVxuICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzMSkge1xuICAgIGlmICgha2V5czIuaW5jbHVkZXMoa2V5KSkgcmV0dXJuIGZhbHNlO1xuICAgIGlmICghaXNEZWVwRXF1YWxEYXRhKG9iajFba2V5XSwgb2JqMltrZXldKSkgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7IC8vIEFsbCBrZXlzIGFuZCB2YWx1ZXMgbWF0Y2hlZFxufVxuIiwgImltcG9ydCB7IEpvYiB9IGZyb20gJy4vam9iJztcblxuZXhwb3J0IGNsYXNzIFNlcmlhbEpvYkV4ZWN1dG9yIHtcbiAgcHJpdmF0ZSBxdWV1ZTogQXJyYXk8Sm9iPiA9IFtdO1xuICBwcml2YXRlIGlzUHJvY2Vzc2luZyA9IGZhbHNlO1xuXG4gIHByaXZhdGUgYXN5bmMgcHJvY2Vzc1F1ZXVlKCkge1xuICAgIGlmICh0aGlzLmlzUHJvY2Vzc2luZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuaXNQcm9jZXNzaW5nID0gdHJ1ZTtcblxuICAgIHdoaWxlICh0aGlzLnF1ZXVlLmxlbmd0aCA+IDApIHtcbiAgICAgIGF3YWl0IHRoaXMucXVldWVbMF0oKTtcbiAgICAgIHRoaXMucXVldWUuc2hpZnQoKTtcbiAgICB9XG5cbiAgICB0aGlzLmlzUHJvY2Vzc2luZyA9IGZhbHNlO1xuICB9XG5cbiAgYXN5bmMgcnVuKGpvYjogSm9iKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMucXVldWUucHVzaChhc3luYyAoKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgam9iKCk7XG4gICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICB2b2lkIHRoaXMucHJvY2Vzc1F1ZXVlKCk7XG4gICAgfSk7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBkZWxheSBhcyBkZWxheUZ1bmN0aW9uIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5cbi8qKlxuICogQ3JlYXRlcyBhIFJlYWRhYmxlU3RyZWFtIHRoYXQgZW1pdHMgdGhlIHByb3ZpZGVkIHZhbHVlcyB3aXRoIGFuIG9wdGlvbmFsIGRlbGF5IGJldHdlZW4gZWFjaCB2YWx1ZS5cbiAqXG4gKiBAcGFyYW0gb3B0aW9ucyAtIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnNcbiAqIEBwYXJhbSBvcHRpb25zLmNodW5rcyAtIEFycmF5IG9mIHZhbHVlcyB0byBiZSBlbWl0dGVkIGJ5IHRoZSBzdHJlYW1cbiAqIEBwYXJhbSBvcHRpb25zLmluaXRpYWxEZWxheUluTXMgLSBPcHRpb25hbCBpbml0aWFsIGRlbGF5IGluIG1pbGxpc2Vjb25kcyBiZWZvcmUgZW1pdHRpbmcgdGhlIGZpcnN0IHZhbHVlIChkZWZhdWx0OiAwKS4gQ2FuIGJlIHNldCB0byBgbnVsbGAgdG8gc2tpcCB0aGUgaW5pdGlhbCBkZWxheS4gVGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBgaW5pdGlhbERlbGF5SW5NczogbnVsbGAgYW5kIGBpbml0aWFsRGVsYXlJbk1zOiAwYCBpcyB0aGF0IGBpbml0aWFsRGVsYXlJbk1zOiBudWxsYCB3aWxsIGVtaXQgdGhlIHZhbHVlcyB3aXRob3V0IGFueSBkZWxheSwgd2hpbGUgYGluaXRpYWxEZWxheUluTXM6IDBgIHdpbGwgZW1pdCB0aGUgdmFsdWVzIHdpdGggYSBkZWxheSBvZiAwIG1pbGxpc2Vjb25kcy5cbiAqIEBwYXJhbSBvcHRpb25zLmNodW5rRGVsYXlJbk1zIC0gT3B0aW9uYWwgZGVsYXkgaW4gbWlsbGlzZWNvbmRzIGJldHdlZW4gZW1pdHRpbmcgZWFjaCB2YWx1ZSAoZGVmYXVsdDogMCkuIENhbiBiZSBzZXQgdG8gYG51bGxgIHRvIHNraXAgdGhlIGRlbGF5LiBUaGUgZGlmZmVyZW5jZSBiZXR3ZWVuIGBjaHVua0RlbGF5SW5NczogbnVsbGAgYW5kIGBjaHVua0RlbGF5SW5NczogMGAgaXMgdGhhdCBgY2h1bmtEZWxheUluTXM6IG51bGxgIHdpbGwgZW1pdCB0aGUgdmFsdWVzIHdpdGhvdXQgYW55IGRlbGF5LCB3aGlsZSBgY2h1bmtEZWxheUluTXM6IDBgIHdpbGwgZW1pdCB0aGUgdmFsdWVzIHdpdGggYSBkZWxheSBvZiAwIG1pbGxpc2Vjb25kcy5cbiAqIEByZXR1cm5zIEEgUmVhZGFibGVTdHJlYW0gdGhhdCBlbWl0cyB0aGUgcHJvdmlkZWQgdmFsdWVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzaW11bGF0ZVJlYWRhYmxlU3RyZWFtPFQ+KHtcbiAgY2h1bmtzLFxuICBpbml0aWFsRGVsYXlJbk1zID0gMCxcbiAgY2h1bmtEZWxheUluTXMgPSAwLFxuICBfaW50ZXJuYWwsXG59OiB7XG4gIGNodW5rczogVFtdO1xuICBpbml0aWFsRGVsYXlJbk1zPzogbnVtYmVyIHwgbnVsbDtcbiAgY2h1bmtEZWxheUluTXM/OiBudW1iZXIgfCBudWxsO1xuICBfaW50ZXJuYWw/OiB7XG4gICAgZGVsYXk/OiAobXM6IG51bWJlciB8IG51bGwpID0+IFByb21pc2U8dm9pZD47XG4gIH07XG59KTogUmVhZGFibGVTdHJlYW08VD4ge1xuICBjb25zdCBkZWxheSA9IF9pbnRlcm5hbD8uZGVsYXkgPz8gZGVsYXlGdW5jdGlvbjtcblxuICBsZXQgaW5kZXggPSAwO1xuXG4gIHJldHVybiBuZXcgUmVhZGFibGVTdHJlYW0oe1xuICAgIGFzeW5jIHB1bGwoY29udHJvbGxlcikge1xuICAgICAgaWYgKGluZGV4IDwgY2h1bmtzLmxlbmd0aCkge1xuICAgICAgICBhd2FpdCBkZWxheShpbmRleCA9PT0gMCA/IGluaXRpYWxEZWxheUluTXMgOiBjaHVua0RlbGF5SW5Ncyk7XG4gICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShjaHVua3NbaW5kZXgrK10pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29udHJvbGxlci5jbG9zZSgpO1xuICAgICAgfVxuICAgIH0sXG4gIH0pO1xufVxuIiwgImltcG9ydCB7IEpTT05WYWx1ZSwgU3BlZWNoTW9kZWxWMiB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgUHJvdmlkZXJPcHRpb25zLCB3aXRoVXNlckFnZW50U3VmZml4IH0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyBOb1NwZWVjaEdlbmVyYXRlZEVycm9yIH0gZnJvbSAnLi4vZXJyb3Ivbm8tc3BlZWNoLWdlbmVyYXRlZC1lcnJvcic7XG5pbXBvcnQgeyBVbnN1cHBvcnRlZE1vZGVsVmVyc2lvbkVycm9yIH0gZnJvbSAnLi4vZXJyb3IvdW5zdXBwb3J0ZWQtbW9kZWwtdmVyc2lvbi1lcnJvcic7XG5pbXBvcnQgeyBsb2dXYXJuaW5ncyB9IGZyb20gJy4uL2xvZ2dlci9sb2ctd2FybmluZ3MnO1xuaW1wb3J0IHsgU3BlZWNoV2FybmluZyB9IGZyb20gJy4uL3R5cGVzL3NwZWVjaC1tb2RlbCc7XG5pbXBvcnQgeyBTcGVlY2hNb2RlbFJlc3BvbnNlTWV0YWRhdGEgfSBmcm9tICcuLi90eXBlcy9zcGVlY2gtbW9kZWwtcmVzcG9uc2UtbWV0YWRhdGEnO1xuaW1wb3J0IHtcbiAgYXVkaW9NZWRpYVR5cGVTaWduYXR1cmVzLFxuICBkZXRlY3RNZWRpYVR5cGUsXG59IGZyb20gJy4uL3V0aWwvZGV0ZWN0LW1lZGlhLXR5cGUnO1xuaW1wb3J0IHsgcHJlcGFyZVJldHJpZXMgfSBmcm9tICcuLi91dGlsL3ByZXBhcmUtcmV0cmllcyc7XG5pbXBvcnQgeyBTcGVlY2hSZXN1bHQgfSBmcm9tICcuL2dlbmVyYXRlLXNwZWVjaC1yZXN1bHQnO1xuaW1wb3J0IHtcbiAgRGVmYXVsdEdlbmVyYXRlZEF1ZGlvRmlsZSxcbiAgR2VuZXJhdGVkQXVkaW9GaWxlLFxufSBmcm9tICcuL2dlbmVyYXRlZC1hdWRpby1maWxlJztcbmltcG9ydCB7IFZFUlNJT04gfSBmcm9tICcuLi92ZXJzaW9uJztcbi8qKlxuR2VuZXJhdGVzIHNwZWVjaCBhdWRpbyB1c2luZyBhIHNwZWVjaCBtb2RlbC5cblxuQHBhcmFtIG1vZGVsIC0gVGhlIHNwZWVjaCBtb2RlbCB0byB1c2UuXG5AcGFyYW0gdGV4dCAtIFRoZSB0ZXh0IHRvIGNvbnZlcnQgdG8gc3BlZWNoLlxuQHBhcmFtIHZvaWNlIC0gVGhlIHZvaWNlIHRvIHVzZSBmb3Igc3BlZWNoIGdlbmVyYXRpb24uXG5AcGFyYW0gb3V0cHV0Rm9ybWF0IC0gVGhlIG91dHB1dCBmb3JtYXQgdG8gdXNlIGZvciBzcGVlY2ggZ2VuZXJhdGlvbiBlLmcuIFwibXAzXCIsIFwid2F2XCIsIGV0Yy5cbkBwYXJhbSBpbnN0cnVjdGlvbnMgLSBJbnN0cnVjdGlvbnMgZm9yIHRoZSBzcGVlY2ggZ2VuZXJhdGlvbiBlLmcuIFwiU3BlYWsgaW4gYSBzbG93IGFuZCBzdGVhZHkgdG9uZVwiLlxuQHBhcmFtIHNwZWVkIC0gVGhlIHNwZWVkIG9mIHRoZSBzcGVlY2ggZ2VuZXJhdGlvbi5cbkBwYXJhbSBwcm92aWRlck9wdGlvbnMgLSBBZGRpdGlvbmFsIHByb3ZpZGVyLXNwZWNpZmljIG9wdGlvbnMgdGhhdCBhcmUgcGFzc2VkIHRocm91Z2ggdG8gdGhlIHByb3ZpZGVyXG5hcyBib2R5IHBhcmFtZXRlcnMuXG5AcGFyYW0gbWF4UmV0cmllcyAtIE1heGltdW0gbnVtYmVyIG9mIHJldHJpZXMuIFNldCB0byAwIHRvIGRpc2FibGUgcmV0cmllcy4gRGVmYXVsdDogMi5cbkBwYXJhbSBhYm9ydFNpZ25hbCAtIEFuIG9wdGlvbmFsIGFib3J0IHNpZ25hbCB0aGF0IGNhbiBiZSB1c2VkIHRvIGNhbmNlbCB0aGUgY2FsbC5cbkBwYXJhbSBoZWFkZXJzIC0gQWRkaXRpb25hbCBIVFRQIGhlYWRlcnMgdG8gYmUgc2VudCB3aXRoIHRoZSByZXF1ZXN0LiBPbmx5IGFwcGxpY2FibGUgZm9yIEhUVFAtYmFzZWQgcHJvdmlkZXJzLlxuXG5AcmV0dXJucyBBIHJlc3VsdCBvYmplY3QgdGhhdCBjb250YWlucyB0aGUgZ2VuZXJhdGVkIGF1ZGlvIGRhdGEuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZW5lcmF0ZVNwZWVjaCh7XG4gIG1vZGVsLFxuICB0ZXh0LFxuICB2b2ljZSxcbiAgb3V0cHV0Rm9ybWF0LFxuICBpbnN0cnVjdGlvbnMsXG4gIHNwZWVkLFxuICBsYW5ndWFnZSxcbiAgcHJvdmlkZXJPcHRpb25zID0ge30sXG4gIG1heFJldHJpZXM6IG1heFJldHJpZXNBcmcsXG4gIGFib3J0U2lnbmFsLFxuICBoZWFkZXJzLFxufToge1xuICAvKipcblRoZSBzcGVlY2ggbW9kZWwgdG8gdXNlLlxuICAgICAqL1xuICBtb2RlbDogU3BlZWNoTW9kZWxWMjtcblxuICAvKipcblRoZSB0ZXh0IHRvIGNvbnZlcnQgdG8gc3BlZWNoLlxuICAgKi9cbiAgdGV4dDogc3RyaW5nO1xuXG4gIC8qKlxuVGhlIHZvaWNlIHRvIHVzZSBmb3Igc3BlZWNoIGdlbmVyYXRpb24uXG4gICAqL1xuICB2b2ljZT86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGRlc2lyZWQgb3V0cHV0IGZvcm1hdCBmb3IgdGhlIGF1ZGlvIGUuZy4gXCJtcDNcIiwgXCJ3YXZcIiwgZXRjLlxuICAgKi9cbiAgb3V0cHV0Rm9ybWF0PzogJ21wMycgfCAnd2F2JyB8IChzdHJpbmcgJiB7fSk7XG5cbiAgLyoqXG4gICAgSW5zdHJ1Y3Rpb25zIGZvciB0aGUgc3BlZWNoIGdlbmVyYXRpb24gZS5nLiBcIlNwZWFrIGluIGEgc2xvdyBhbmQgc3RlYWR5IHRvbmVcIi5cbiAgKi9cbiAgaW5zdHJ1Y3Rpb25zPzogc3RyaW5nO1xuXG4gIC8qKlxuICBUaGUgc3BlZWQgb2YgdGhlIHNwZWVjaCBnZW5lcmF0aW9uLlxuICAgKi9cbiAgc3BlZWQ/OiBudW1iZXI7XG5cbiAgLyoqXG4gIFRoZSBsYW5ndWFnZSBmb3Igc3BlZWNoIGdlbmVyYXRpb24uIFRoaXMgc2hvdWxkIGJlIGFuIElTTyA2MzktMSBsYW5ndWFnZSBjb2RlIChlLmcuIFwiZW5cIiwgXCJlc1wiLCBcImZyXCIpXG4gIG9yIFwiYXV0b1wiIGZvciBhdXRvbWF0aWMgbGFuZ3VhZ2UgZGV0ZWN0aW9uLiBQcm92aWRlciBzdXBwb3J0IHZhcmllcy5cbiAgICovXG4gIGxhbmd1YWdlPzogc3RyaW5nO1xuXG4gIC8qKlxuQWRkaXRpb25hbCBwcm92aWRlci1zcGVjaWZpYyBvcHRpb25zIHRoYXQgYXJlIHBhc3NlZCB0aHJvdWdoIHRvIHRoZSBwcm92aWRlclxuYXMgYm9keSBwYXJhbWV0ZXJzLlxuXG5UaGUgb3V0ZXIgcmVjb3JkIGlzIGtleWVkIGJ5IHRoZSBwcm92aWRlciBuYW1lLCBhbmQgdGhlIGlubmVyXG5yZWNvcmQgaXMga2V5ZWQgYnkgdGhlIHByb3ZpZGVyLXNwZWNpZmljIG1ldGFkYXRhIGtleS5cbmBgYHRzXG57XG4gIFwib3BlbmFpXCI6IHt9XG59XG5gYGBcbiAgICAgKi9cbiAgcHJvdmlkZXJPcHRpb25zPzogUHJvdmlkZXJPcHRpb25zO1xuXG4gIC8qKlxuTWF4aW11bSBudW1iZXIgb2YgcmV0cmllcyBwZXIgc3BlZWNoIG1vZGVsIGNhbGwuIFNldCB0byAwIHRvIGRpc2FibGUgcmV0cmllcy5cblxuQGRlZmF1bHQgMlxuICAgKi9cbiAgbWF4UmV0cmllcz86IG51bWJlcjtcblxuICAvKipcbkFib3J0IHNpZ25hbC5cbiAqL1xuICBhYm9ydFNpZ25hbD86IEFib3J0U2lnbmFsO1xuXG4gIC8qKlxuQWRkaXRpb25hbCBoZWFkZXJzIHRvIGluY2x1ZGUgaW4gdGhlIHJlcXVlc3QuXG5Pbmx5IGFwcGxpY2FibGUgZm9yIEhUVFAtYmFzZWQgcHJvdmlkZXJzLlxuICovXG4gIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xufSk6IFByb21pc2U8U3BlZWNoUmVzdWx0PiB7XG4gIGlmIChtb2RlbC5zcGVjaWZpY2F0aW9uVmVyc2lvbiAhPT0gJ3YyJykge1xuICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE1vZGVsVmVyc2lvbkVycm9yKHtcbiAgICAgIHZlcnNpb246IG1vZGVsLnNwZWNpZmljYXRpb25WZXJzaW9uLFxuICAgICAgcHJvdmlkZXI6IG1vZGVsLnByb3ZpZGVyLFxuICAgICAgbW9kZWxJZDogbW9kZWwubW9kZWxJZCxcbiAgICB9KTtcbiAgfVxuXG4gIGNvbnN0IGhlYWRlcnNXaXRoVXNlckFnZW50ID0gd2l0aFVzZXJBZ2VudFN1ZmZpeChcbiAgICBoZWFkZXJzID8/IHt9LFxuICAgIGBhaS8ke1ZFUlNJT059YCxcbiAgKTtcblxuICBjb25zdCB7IHJldHJ5IH0gPSBwcmVwYXJlUmV0cmllcyh7XG4gICAgbWF4UmV0cmllczogbWF4UmV0cmllc0FyZyxcbiAgICBhYm9ydFNpZ25hbCxcbiAgfSk7XG5cbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmV0cnkoKCkgPT5cbiAgICBtb2RlbC5kb0dlbmVyYXRlKHtcbiAgICAgIHRleHQsXG4gICAgICB2b2ljZSxcbiAgICAgIG91dHB1dEZvcm1hdCxcbiAgICAgIGluc3RydWN0aW9ucyxcbiAgICAgIHNwZWVkLFxuICAgICAgbGFuZ3VhZ2UsXG4gICAgICBhYm9ydFNpZ25hbCxcbiAgICAgIGhlYWRlcnM6IGhlYWRlcnNXaXRoVXNlckFnZW50LFxuICAgICAgcHJvdmlkZXJPcHRpb25zLFxuICAgIH0pLFxuICApO1xuXG4gIGlmICghcmVzdWx0LmF1ZGlvIHx8IHJlc3VsdC5hdWRpby5sZW5ndGggPT09IDApIHtcbiAgICB0aHJvdyBuZXcgTm9TcGVlY2hHZW5lcmF0ZWRFcnJvcih7IHJlc3BvbnNlczogW3Jlc3VsdC5yZXNwb25zZV0gfSk7XG4gIH1cblxuICBsb2dXYXJuaW5ncyhyZXN1bHQud2FybmluZ3MpO1xuXG4gIHJldHVybiBuZXcgRGVmYXVsdFNwZWVjaFJlc3VsdCh7XG4gICAgYXVkaW86IG5ldyBEZWZhdWx0R2VuZXJhdGVkQXVkaW9GaWxlKHtcbiAgICAgIGRhdGE6IHJlc3VsdC5hdWRpbyxcbiAgICAgIG1lZGlhVHlwZTpcbiAgICAgICAgZGV0ZWN0TWVkaWFUeXBlKHtcbiAgICAgICAgICBkYXRhOiByZXN1bHQuYXVkaW8sXG4gICAgICAgICAgc2lnbmF0dXJlczogYXVkaW9NZWRpYVR5cGVTaWduYXR1cmVzLFxuICAgICAgICB9KSA/PyAnYXVkaW8vbXAzJyxcbiAgICB9KSxcbiAgICB3YXJuaW5nczogcmVzdWx0Lndhcm5pbmdzLFxuICAgIHJlc3BvbnNlczogW3Jlc3VsdC5yZXNwb25zZV0sXG4gICAgcHJvdmlkZXJNZXRhZGF0YTogcmVzdWx0LnByb3ZpZGVyTWV0YWRhdGEsXG4gIH0pO1xufVxuXG5jbGFzcyBEZWZhdWx0U3BlZWNoUmVzdWx0IGltcGxlbWVudHMgU3BlZWNoUmVzdWx0IHtcbiAgcmVhZG9ubHkgYXVkaW86IEdlbmVyYXRlZEF1ZGlvRmlsZTtcbiAgcmVhZG9ubHkgd2FybmluZ3M6IEFycmF5PFNwZWVjaFdhcm5pbmc+O1xuICByZWFkb25seSByZXNwb25zZXM6IEFycmF5PFNwZWVjaE1vZGVsUmVzcG9uc2VNZXRhZGF0YT47XG4gIHJlYWRvbmx5IHByb3ZpZGVyTWV0YWRhdGE6IFJlY29yZDxzdHJpbmcsIFJlY29yZDxzdHJpbmcsIEpTT05WYWx1ZT4+O1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IHtcbiAgICBhdWRpbzogR2VuZXJhdGVkQXVkaW9GaWxlO1xuICAgIHdhcm5pbmdzOiBBcnJheTxTcGVlY2hXYXJuaW5nPjtcbiAgICByZXNwb25zZXM6IEFycmF5PFNwZWVjaE1vZGVsUmVzcG9uc2VNZXRhZGF0YT47XG4gICAgcHJvdmlkZXJNZXRhZGF0YTogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgSlNPTlZhbHVlPj4gfCB1bmRlZmluZWQ7XG4gIH0pIHtcbiAgICB0aGlzLmF1ZGlvID0gb3B0aW9ucy5hdWRpbztcbiAgICB0aGlzLndhcm5pbmdzID0gb3B0aW9ucy53YXJuaW5ncztcbiAgICB0aGlzLnJlc3BvbnNlcyA9IG9wdGlvbnMucmVzcG9uc2VzO1xuICAgIHRoaXMucHJvdmlkZXJNZXRhZGF0YSA9IG9wdGlvbnMucHJvdmlkZXJNZXRhZGF0YSA/PyB7fTtcbiAgfVxufVxuIiwgImltcG9ydCB7XG4gIEdlbmVyYXRlZEZpbGUsXG4gIERlZmF1bHRHZW5lcmF0ZWRGaWxlLFxufSBmcm9tICcuLi9nZW5lcmF0ZS10ZXh0L2dlbmVyYXRlZC1maWxlJztcblxuLyoqXG4gKiBBIGdlbmVyYXRlZCBhdWRpbyBmaWxlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEdlbmVyYXRlZEF1ZGlvRmlsZSBleHRlbmRzIEdlbmVyYXRlZEZpbGUge1xuICAvKipcbiAgICogQXVkaW8gZm9ybWF0IG9mIHRoZSBmaWxlIChlLmcuLCAnbXAzJywgJ3dhdicsIGV0Yy4pXG4gICAqL1xuICByZWFkb25seSBmb3JtYXQ6IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIERlZmF1bHRHZW5lcmF0ZWRBdWRpb0ZpbGVcbiAgZXh0ZW5kcyBEZWZhdWx0R2VuZXJhdGVkRmlsZVxuICBpbXBsZW1lbnRzIEdlbmVyYXRlZEF1ZGlvRmlsZVxue1xuICByZWFkb25seSBmb3JtYXQ6IHN0cmluZztcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgZGF0YSxcbiAgICBtZWRpYVR5cGUsXG4gIH06IHtcbiAgICBkYXRhOiBzdHJpbmcgfCBVaW50OEFycmF5O1xuICAgIG1lZGlhVHlwZTogc3RyaW5nO1xuICB9KSB7XG4gICAgc3VwZXIoeyBkYXRhLCBtZWRpYVR5cGUgfSk7XG4gICAgbGV0IGZvcm1hdCA9ICdtcDMnO1xuXG4gICAgLy8gSWYgZm9ybWF0IGlzIG5vdCBwcm92aWRlZCwgdHJ5IHRvIGRldGVybWluZSBpdCBmcm9tIHRoZSBtZWRpYSB0eXBlXG4gICAgaWYgKG1lZGlhVHlwZSkge1xuICAgICAgY29uc3QgbWVkaWFUeXBlUGFydHMgPSBtZWRpYVR5cGUuc3BsaXQoJy8nKTtcblxuICAgICAgaWYgKG1lZGlhVHlwZVBhcnRzLmxlbmd0aCA9PT0gMikge1xuICAgICAgICAvLyBIYW5kbGUgc3BlY2lhbCBjYXNlcyBmb3IgYXVkaW8gZm9ybWF0c1xuICAgICAgICBpZiAobWVkaWFUeXBlICE9PSAnYXVkaW8vbXBlZycpIHtcbiAgICAgICAgICBmb3JtYXQgPSBtZWRpYVR5cGVQYXJ0c1sxXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghZm9ybWF0KSB7XG4gICAgICAvLyBUT0RPIHRoaXMgc2hvdWxkIGJlIGFuIEFJIFNESyBlcnJvclxuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnQXVkaW8gZm9ybWF0IG11c3QgYmUgcHJvdmlkZWQgb3IgZGV0ZXJtaW5hYmxlIGZyb20gbWVkaWEgdHlwZScsXG4gICAgICApO1xuICAgIH1cblxuICAgIHRoaXMuZm9ybWF0ID0gZm9ybWF0O1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBEZWZhdWx0R2VuZXJhdGVkQXVkaW9GaWxlV2l0aFR5cGUgZXh0ZW5kcyBEZWZhdWx0R2VuZXJhdGVkQXVkaW9GaWxlIHtcbiAgcmVhZG9ubHkgdHlwZSA9ICdhdWRpbyc7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczoge1xuICAgIGRhdGE6IHN0cmluZyB8IFVpbnQ4QXJyYXk7XG4gICAgbWVkaWFUeXBlOiBzdHJpbmc7XG4gICAgZm9ybWF0OiBzdHJpbmc7XG4gIH0pIHtcbiAgICBzdXBlcihvcHRpb25zKTtcbiAgfVxufVxuIiwgImltcG9ydCB7IExhbmd1YWdlTW9kZWxWMkNhbGxPcHRpb25zIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQge1xuICBhc1NjaGVtYSxcbiAgRmxleGlibGVTY2hlbWEsXG4gIHNhZmVQYXJzZUpTT04sXG4gIHNhZmVWYWxpZGF0ZVR5cGVzLFxufSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyLXV0aWxzJztcbmltcG9ydCB7IE5vT2JqZWN0R2VuZXJhdGVkRXJyb3IgfSBmcm9tICcuLi9lcnJvci9uby1vYmplY3QtZ2VuZXJhdGVkLWVycm9yJztcbmltcG9ydCB7IEZpbmlzaFJlYXNvbiB9IGZyb20gJy4uL3R5cGVzL2xhbmd1YWdlLW1vZGVsJztcbmltcG9ydCB7IExhbmd1YWdlTW9kZWxSZXNwb25zZU1ldGFkYXRhIH0gZnJvbSAnLi4vdHlwZXMvbGFuZ3VhZ2UtbW9kZWwtcmVzcG9uc2UtbWV0YWRhdGEnO1xuaW1wb3J0IHsgTGFuZ3VhZ2VNb2RlbFVzYWdlIH0gZnJvbSAnLi4vdHlwZXMvdXNhZ2UnO1xuaW1wb3J0IHsgRGVlcFBhcnRpYWwgfSBmcm9tICcuLi91dGlsL2RlZXAtcGFydGlhbCc7XG5pbXBvcnQgeyBwYXJzZVBhcnRpYWxKc29uIH0gZnJvbSAnLi4vdXRpbC9wYXJzZS1wYXJ0aWFsLWpzb24nO1xuXG5leHBvcnQgaW50ZXJmYWNlIE91dHB1dDxPVVRQVVQsIFBBUlRJQUw+IHtcbiAgcmVhZG9ubHkgdHlwZTogJ29iamVjdCcgfCAndGV4dCc7XG5cbiAgcmVzcG9uc2VGb3JtYXQ6IExhbmd1YWdlTW9kZWxWMkNhbGxPcHRpb25zWydyZXNwb25zZUZvcm1hdCddO1xuXG4gIHBhcnNlUGFydGlhbChvcHRpb25zOiB7XG4gICAgdGV4dDogc3RyaW5nO1xuICB9KTogUHJvbWlzZTx7IHBhcnRpYWw6IFBBUlRJQUwgfSB8IHVuZGVmaW5lZD47XG5cbiAgcGFyc2VPdXRwdXQoXG4gICAgb3B0aW9uczogeyB0ZXh0OiBzdHJpbmcgfSxcbiAgICBjb250ZXh0OiB7XG4gICAgICByZXNwb25zZTogTGFuZ3VhZ2VNb2RlbFJlc3BvbnNlTWV0YWRhdGE7XG4gICAgICB1c2FnZTogTGFuZ3VhZ2VNb2RlbFVzYWdlO1xuICAgICAgZmluaXNoUmVhc29uOiBGaW5pc2hSZWFzb247XG4gICAgfSxcbiAgKTogUHJvbWlzZTxPVVRQVVQ+O1xufVxuXG5leHBvcnQgY29uc3QgdGV4dCA9ICgpOiBPdXRwdXQ8c3RyaW5nLCBzdHJpbmc+ID0+ICh7XG4gIHR5cGU6ICd0ZXh0JyxcblxuICByZXNwb25zZUZvcm1hdDogeyB0eXBlOiAndGV4dCcgfSxcblxuICBhc3luYyBwYXJzZVBhcnRpYWwoeyB0ZXh0IH06IHsgdGV4dDogc3RyaW5nIH0pIHtcbiAgICByZXR1cm4geyBwYXJ0aWFsOiB0ZXh0IH07XG4gIH0sXG5cbiAgYXN5bmMgcGFyc2VPdXRwdXQoeyB0ZXh0IH06IHsgdGV4dDogc3RyaW5nIH0pIHtcbiAgICByZXR1cm4gdGV4dDtcbiAgfSxcbn0pO1xuXG5leHBvcnQgY29uc3Qgb2JqZWN0ID0gPE9VVFBVVD4oe1xuICBzY2hlbWE6IGlucHV0U2NoZW1hLFxufToge1xuICBzY2hlbWE6IEZsZXhpYmxlU2NoZW1hPE9VVFBVVD47XG59KTogT3V0cHV0PE9VVFBVVCwgRGVlcFBhcnRpYWw8T1VUUFVUPj4gPT4ge1xuICBjb25zdCBzY2hlbWEgPSBhc1NjaGVtYShpbnB1dFNjaGVtYSk7XG5cbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAnb2JqZWN0JyxcblxuICAgIHJlc3BvbnNlRm9ybWF0OiB7XG4gICAgICB0eXBlOiAnanNvbicsXG4gICAgICBzY2hlbWE6IHNjaGVtYS5qc29uU2NoZW1hLFxuICAgIH0sXG5cbiAgICBhc3luYyBwYXJzZVBhcnRpYWwoeyB0ZXh0IH06IHsgdGV4dDogc3RyaW5nIH0pIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHBhcnNlUGFydGlhbEpzb24odGV4dCk7XG5cbiAgICAgIHN3aXRjaCAocmVzdWx0LnN0YXRlKSB7XG4gICAgICAgIGNhc2UgJ2ZhaWxlZC1wYXJzZSc6XG4gICAgICAgIGNhc2UgJ3VuZGVmaW5lZC1pbnB1dCc6XG4gICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgICAgICBjYXNlICdyZXBhaXJlZC1wYXJzZSc6XG4gICAgICAgIGNhc2UgJ3N1Y2Nlc3NmdWwtcGFyc2UnOlxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAvLyBOb3RlOiBjdXJyZW50bHkgbm8gdmFsaWRhdGlvbiBvZiBwYXJ0aWFsIHJlc3VsdHM6XG4gICAgICAgICAgICBwYXJ0aWFsOiByZXN1bHQudmFsdWUgYXMgRGVlcFBhcnRpYWw8T1VUUFVUPixcbiAgICAgICAgICB9O1xuXG4gICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICBjb25zdCBfZXhoYXVzdGl2ZUNoZWNrOiBuZXZlciA9IHJlc3VsdC5zdGF0ZTtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIHBhcnNlIHN0YXRlOiAke19leGhhdXN0aXZlQ2hlY2t9YCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuXG4gICAgYXN5bmMgcGFyc2VPdXRwdXQoXG4gICAgICB7IHRleHQgfTogeyB0ZXh0OiBzdHJpbmcgfSxcbiAgICAgIGNvbnRleHQ6IHtcbiAgICAgICAgcmVzcG9uc2U6IExhbmd1YWdlTW9kZWxSZXNwb25zZU1ldGFkYXRhO1xuICAgICAgICB1c2FnZTogTGFuZ3VhZ2VNb2RlbFVzYWdlO1xuICAgICAgICBmaW5pc2hSZWFzb246IEZpbmlzaFJlYXNvbjtcbiAgICAgIH0sXG4gICAgKSB7XG4gICAgICBjb25zdCBwYXJzZVJlc3VsdCA9IGF3YWl0IHNhZmVQYXJzZUpTT04oeyB0ZXh0IH0pO1xuXG4gICAgICBpZiAoIXBhcnNlUmVzdWx0LnN1Y2Nlc3MpIHtcbiAgICAgICAgdGhyb3cgbmV3IE5vT2JqZWN0R2VuZXJhdGVkRXJyb3Ioe1xuICAgICAgICAgIG1lc3NhZ2U6ICdObyBvYmplY3QgZ2VuZXJhdGVkOiBjb3VsZCBub3QgcGFyc2UgdGhlIHJlc3BvbnNlLicsXG4gICAgICAgICAgY2F1c2U6IHBhcnNlUmVzdWx0LmVycm9yLFxuICAgICAgICAgIHRleHQsXG4gICAgICAgICAgcmVzcG9uc2U6IGNvbnRleHQucmVzcG9uc2UsXG4gICAgICAgICAgdXNhZ2U6IGNvbnRleHQudXNhZ2UsXG4gICAgICAgICAgZmluaXNoUmVhc29uOiBjb250ZXh0LmZpbmlzaFJlYXNvbixcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHZhbGlkYXRpb25SZXN1bHQgPSBhd2FpdCBzYWZlVmFsaWRhdGVUeXBlcyh7XG4gICAgICAgIHZhbHVlOiBwYXJzZVJlc3VsdC52YWx1ZSxcbiAgICAgICAgc2NoZW1hLFxuICAgICAgfSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvblJlc3VsdC5zdWNjZXNzKSB7XG4gICAgICAgIHRocm93IG5ldyBOb09iamVjdEdlbmVyYXRlZEVycm9yKHtcbiAgICAgICAgICBtZXNzYWdlOiAnTm8gb2JqZWN0IGdlbmVyYXRlZDogcmVzcG9uc2UgZGlkIG5vdCBtYXRjaCBzY2hlbWEuJyxcbiAgICAgICAgICBjYXVzZTogdmFsaWRhdGlvblJlc3VsdC5lcnJvcixcbiAgICAgICAgICB0ZXh0LFxuICAgICAgICAgIHJlc3BvbnNlOiBjb250ZXh0LnJlc3BvbnNlLFxuICAgICAgICAgIHVzYWdlOiBjb250ZXh0LnVzYWdlLFxuICAgICAgICAgIGZpbmlzaFJlYXNvbjogY29udGV4dC5maW5pc2hSZWFzb24sXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdmFsaWRhdGlvblJlc3VsdC52YWx1ZTtcbiAgICB9LFxuICB9O1xufTtcbiIsICJpbXBvcnQge1xuICBBc3Npc3RhbnRNb2RlbE1lc3NhZ2UsXG4gIE1vZGVsTWVzc2FnZSxcbiAgVG9vbE1vZGVsTWVzc2FnZSxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5cbi8qKlxuICogUHJ1bmVzIG1vZGVsIG1lc3NhZ2VzIGZyb20gYSBsaXN0IG9mIG1vZGVsIG1lc3NhZ2VzLlxuICpcbiAqIEBwYXJhbSBtZXNzYWdlcyAtIFRoZSBsaXN0IG9mIG1vZGVsIG1lc3NhZ2VzIHRvIHBydW5lLlxuICogQHBhcmFtIHJlYXNvbmluZyAtIEhvdyB0byByZW1vdmUgcmVhc29uaW5nIGNvbnRlbnQgZnJvbSBhc3Npc3RhbnQgbWVzc2FnZXMuIERlZmF1bHQgaXMgYCdub25lJ2AuXG4gKiBAcGFyYW0gdG9vbENhbGxzIC0gSG93IHRvIHBydW5lIHRvb2wgY2FsbC9yZXN1bHRzL2FwcHJvdmFsIGNvbnRlbnQuIERlZmF1bHQgaXMgYFtdYC5cbiAqIEBwYXJhbSBlbXB0eU1lc3NhZ2VzIC0gV2hldGhlciB0byBrZWVwIG9yIHJlbW92ZSBtZXNzYWdlcyB3aG9zZSBjb250ZW50IGlzIGVtcHR5IGFmdGVyIHBydW5pbmcuIERlZmF1bHQgaXMgYCdyZW1vdmUnYC5cbiAqXG4gKiBAcmV0dXJucyBUaGUgcHJ1bmVkIGxpc3Qgb2YgbW9kZWwgbWVzc2FnZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcnVuZU1lc3NhZ2VzKHtcbiAgbWVzc2FnZXMsXG4gIHJlYXNvbmluZyA9ICdub25lJyxcbiAgdG9vbENhbGxzID0gW10sXG4gIGVtcHR5TWVzc2FnZXMgPSAncmVtb3ZlJyxcbn06IHtcbiAgbWVzc2FnZXM6IE1vZGVsTWVzc2FnZVtdO1xuICByZWFzb25pbmc/OiAnYWxsJyB8ICdiZWZvcmUtbGFzdC1tZXNzYWdlJyB8ICdub25lJztcbiAgdG9vbENhbGxzPzpcbiAgICB8ICdhbGwnXG4gICAgfCAnYmVmb3JlLWxhc3QtbWVzc2FnZSdcbiAgICB8IGBiZWZvcmUtbGFzdC0ke251bWJlcn0tbWVzc2FnZXNgXG4gICAgfCAnbm9uZSdcbiAgICB8IEFycmF5PHtcbiAgICAgICAgdHlwZTogJ2FsbCcgfCAnYmVmb3JlLWxhc3QtbWVzc2FnZScgfCBgYmVmb3JlLWxhc3QtJHtudW1iZXJ9LW1lc3NhZ2VzYDtcbiAgICAgICAgdG9vbHM/OiBzdHJpbmdbXTtcbiAgICAgIH0+O1xuICBlbXB0eU1lc3NhZ2VzPzogJ2tlZXAnIHwgJ3JlbW92ZSc7XG59KTogTW9kZWxNZXNzYWdlW10ge1xuICAvLyBmaWx0ZXIgcmVhc29uaW5nIHBhcnRzOlxuICBpZiAocmVhc29uaW5nID09PSAnYWxsJyB8fCByZWFzb25pbmcgPT09ICdiZWZvcmUtbGFzdC1tZXNzYWdlJykge1xuICAgIG1lc3NhZ2VzID0gbWVzc2FnZXMubWFwKChtZXNzYWdlLCBtZXNzYWdlSW5kZXgpID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgbWVzc2FnZS5yb2xlICE9PSAnYXNzaXN0YW50JyB8fFxuICAgICAgICB0eXBlb2YgbWVzc2FnZS5jb250ZW50ID09PSAnc3RyaW5nJyB8fFxuICAgICAgICAocmVhc29uaW5nID09PSAnYmVmb3JlLWxhc3QtbWVzc2FnZScgJiZcbiAgICAgICAgICBtZXNzYWdlSW5kZXggPT09IG1lc3NhZ2VzLmxlbmd0aCAtIDEpXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLm1lc3NhZ2UsXG4gICAgICAgIGNvbnRlbnQ6IG1lc3NhZ2UuY29udGVudC5maWx0ZXIocGFydCA9PiBwYXJ0LnR5cGUgIT09ICdyZWFzb25pbmcnKSxcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICAvLyBmaWx0ZXIgdG9vbCBjYWxscywgcmVzdWx0cywgZXJyb3JzLCBhbmQgYXBwcm92YWxzOlxuICBpZiAodG9vbENhbGxzID09PSAnbm9uZScpIHtcbiAgICB0b29sQ2FsbHMgPSBbXTtcbiAgfSBlbHNlIGlmICh0b29sQ2FsbHMgPT09ICdhbGwnKSB7XG4gICAgdG9vbENhbGxzID0gW3sgdHlwZTogJ2FsbCcgfV07XG4gIH0gZWxzZSBpZiAodG9vbENhbGxzID09PSAnYmVmb3JlLWxhc3QtbWVzc2FnZScpIHtcbiAgICB0b29sQ2FsbHMgPSBbeyB0eXBlOiAnYmVmb3JlLWxhc3QtbWVzc2FnZScgfV07XG4gIH0gZWxzZSBpZiAodHlwZW9mIHRvb2xDYWxscyA9PT0gJ3N0cmluZycpIHtcbiAgICB0b29sQ2FsbHMgPSBbeyB0eXBlOiB0b29sQ2FsbHMgfV07XG4gIH1cblxuICBmb3IgKGNvbnN0IHRvb2xDYWxsIG9mIHRvb2xDYWxscykge1xuICAgIC8vIGRldGVybWluZSBob3cgbWFueSB0cmFpbGluZyBtZXNzYWdlcyB0byBrZWVwOlxuICAgIGNvbnN0IGtlZXBMYXN0TWVzc2FnZXNDb3VudCA9XG4gICAgICB0b29sQ2FsbC50eXBlID09PSAnYWxsJ1xuICAgICAgICA/IHVuZGVmaW5lZFxuICAgICAgICA6IHRvb2xDYWxsLnR5cGUgPT09ICdiZWZvcmUtbGFzdC1tZXNzYWdlJ1xuICAgICAgICAgID8gMVxuICAgICAgICAgIDogTnVtYmVyKFxuICAgICAgICAgICAgICB0b29sQ2FsbC50eXBlXG4gICAgICAgICAgICAgICAgLnNsaWNlKCdiZWZvcmUtbGFzdC0nLmxlbmd0aClcbiAgICAgICAgICAgICAgICAuc2xpY2UoMCwgLSctbWVzc2FnZXMnLmxlbmd0aCksXG4gICAgICAgICAgICApO1xuXG4gICAgLy8gc2NhbiBrZXB0IG1lc3NhZ2VzIHRvIGlkZW50aWZ5IHRvb2wgY2FsbHMgYW5kIGFwcHJvdmFscyB0aGF0IG5lZWQgdG8gYmUga2VwdDpcbiAgICBjb25zdCBrZXB0VG9vbENhbGxJZHM6IFNldDxzdHJpbmc+ID0gbmV3IFNldCgpO1xuICAgIGNvbnN0IGtlcHRBcHByb3ZhbElkczogU2V0PHN0cmluZz4gPSBuZXcgU2V0KCk7XG5cbiAgICBpZiAoa2VlcExhc3RNZXNzYWdlc0NvdW50ICE9IG51bGwpIHtcbiAgICAgIGZvciAoY29uc3QgbWVzc2FnZSBvZiBtZXNzYWdlcy5zbGljZSgwLCAta2VlcExhc3RNZXNzYWdlc0NvdW50KSkge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgKG1lc3NhZ2Uucm9sZSA9PT0gJ2Fzc2lzdGFudCcgfHwgbWVzc2FnZS5yb2xlID09PSAndG9vbCcpICYmXG4gICAgICAgICAgdHlwZW9mIG1lc3NhZ2UuY29udGVudCAhPT0gJ3N0cmluZydcbiAgICAgICAgKSB7XG4gICAgICAgICAgZm9yIChjb25zdCBwYXJ0IG9mIG1lc3NhZ2UuY29udGVudCkge1xuICAgICAgICAgICAgaWYgKHBhcnQudHlwZSA9PT0gJ3Rvb2wtY2FsbCcgfHwgcGFydC50eXBlID09PSAndG9vbC1yZXN1bHQnKSB7XG4gICAgICAgICAgICAgIGtlcHRUb29sQ2FsbElkcy5hZGQocGFydC50b29sQ2FsbElkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBtZXNzYWdlcyA9IG1lc3NhZ2VzLm1hcCgobWVzc2FnZSwgbWVzc2FnZUluZGV4KSA9PiB7XG4gICAgICBpZiAoXG4gICAgICAgIChtZXNzYWdlLnJvbGUgIT09ICdhc3Npc3RhbnQnICYmIG1lc3NhZ2Uucm9sZSAhPT0gJ3Rvb2wnKSB8fFxuICAgICAgICB0eXBlb2YgbWVzc2FnZS5jb250ZW50ID09PSAnc3RyaW5nJyB8fFxuICAgICAgICAoa2VlcExhc3RNZXNzYWdlc0NvdW50ICYmXG4gICAgICAgICAgbWVzc2FnZUluZGV4ID49IG1lc3NhZ2VzLmxlbmd0aCAtIGtlZXBMYXN0TWVzc2FnZXNDb3VudClcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgdG9vbENhbGxJZFRvVG9vbE5hbWU6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ubWVzc2FnZSxcbiAgICAgICAgY29udGVudDogbWVzc2FnZS5jb250ZW50LmZpbHRlcihwYXJ0ID0+IHtcbiAgICAgICAgICAvLyBrZWVwIG5vbi10b29sIHBhcnRzOlxuICAgICAgICAgIGlmIChwYXJ0LnR5cGUgIT09ICd0b29sLWNhbGwnICYmIHBhcnQudHlwZSAhPT0gJ3Rvb2wtcmVzdWx0Jykge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gdHJhY2sgdG9vbCBjYWxscyBhbmQgYXBwcm92YWxzOlxuICAgICAgICAgIGlmIChwYXJ0LnR5cGUgPT09ICd0b29sLWNhbGwnKSB7XG4gICAgICAgICAgICB0b29sQ2FsbElkVG9Ub29sTmFtZVtwYXJ0LnRvb2xDYWxsSWRdID0gcGFydC50b29sTmFtZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBrZWVwIHBhcnRzIHRoYXQgYXJlIGFzc29jaWF0ZWQgd2l0aCBhIHRvb2wgY2FsbCBvciBhcHByb3ZhbCB0aGF0IG5lZWRzIHRvIGJlIGtlcHQ6XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgKHBhcnQudHlwZSA9PT0gJ3Rvb2wtY2FsbCcgfHwgcGFydC50eXBlID09PSAndG9vbC1yZXN1bHQnKSAmJlxuICAgICAgICAgICAga2VwdFRvb2xDYWxsSWRzLmhhcyhwYXJ0LnRvb2xDYWxsSWQpXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBrZWVwIHBhcnRzIHRoYXQgYXJlIG5vdCBhc3NvY2lhdGVkIHdpdGggYSB0b29sIHRoYXQgc2hvdWxkIGJlIHJlbW92ZWQ6XG4gICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIHRvb2xDYWxsLnRvb2xzICE9IG51bGwgJiYgIXRvb2xDYWxsLnRvb2xzLmluY2x1ZGVzKHBhcnQudG9vbE5hbWUpXG4gICAgICAgICAgKTtcbiAgICAgICAgfSksXG4gICAgICB9IGFzIEFzc2lzdGFudE1vZGVsTWVzc2FnZSB8IFRvb2xNb2RlbE1lc3NhZ2U7XG4gICAgfSk7XG4gIH1cblxuICBpZiAoZW1wdHlNZXNzYWdlcyA9PT0gJ3JlbW92ZScpIHtcbiAgICBtZXNzYWdlcyA9IG1lc3NhZ2VzLmZpbHRlcihtZXNzYWdlID0+IG1lc3NhZ2UuY29udGVudC5sZW5ndGggPiAwKTtcbiAgfVxuXG4gIHJldHVybiBtZXNzYWdlcztcbn1cbiIsICJpbXBvcnQgeyBkZWxheSBhcyBvcmlnaW5hbERlbGF5IH0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyBUZXh0U3RyZWFtUGFydCB9IGZyb20gJy4vc3RyZWFtLXRleHQtcmVzdWx0JztcbmltcG9ydCB7IFRvb2xTZXQgfSBmcm9tICcuL3Rvb2wtc2V0JztcbmltcG9ydCB7IEludmFsaWRBcmd1bWVudEVycm9yIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5cbmNvbnN0IENIVU5LSU5HX1JFR0VYUFMgPSB7XG4gIHdvcmQ6IC9cXFMrXFxzKy9tLFxuICBsaW5lOiAvXFxuKy9tLFxufTtcblxuLyoqXG4gKiBEZXRlY3RzIHRoZSBmaXJzdCBjaHVuayBpbiBhIGJ1ZmZlci5cbiAqXG4gKiBAcGFyYW0gYnVmZmVyIC0gVGhlIGJ1ZmZlciB0byBkZXRlY3QgdGhlIGZpcnN0IGNodW5rIGluLlxuICpcbiAqIEByZXR1cm5zIFRoZSBmaXJzdCBkZXRlY3RlZCBjaHVuaywgb3IgYHVuZGVmaW5lZGAgaWYgbm8gY2h1bmsgd2FzIGRldGVjdGVkLlxuICovXG5leHBvcnQgdHlwZSBDaHVua0RldGVjdG9yID0gKGJ1ZmZlcjogc3RyaW5nKSA9PiBzdHJpbmcgfCB1bmRlZmluZWQgfCBudWxsO1xuXG4vKipcbiAqIFNtb290aHMgdGV4dCBzdHJlYW1pbmcgb3V0cHV0LlxuICpcbiAqIEBwYXJhbSBkZWxheUluTXMgLSBUaGUgZGVsYXkgaW4gbWlsbGlzZWNvbmRzIGJldHdlZW4gZWFjaCBjaHVuay4gRGVmYXVsdHMgdG8gMTBtcy4gQ2FuIGJlIHNldCB0byBgbnVsbGAgdG8gc2tpcCB0aGUgZGVsYXkuXG4gKiBAcGFyYW0gY2h1bmtpbmcgLSBDb250cm9scyBob3cgdGhlIHRleHQgaXMgY2h1bmtlZCBmb3Igc3RyZWFtaW5nLiBVc2UgXCJ3b3JkXCIgdG8gc3RyZWFtIHdvcmQgYnkgd29yZCAoZGVmYXVsdCksIFwibGluZVwiIHRvIHN0cmVhbSBsaW5lIGJ5IGxpbmUsIG9yIHByb3ZpZGUgYSBjdXN0b20gUmVnRXhwIHBhdHRlcm4gZm9yIGN1c3RvbSBjaHVua2luZy5cbiAqXG4gKiBAcmV0dXJucyBBIHRyYW5zZm9ybSBzdHJlYW0gdGhhdCBzbW9vdGhzIHRleHQgc3RyZWFtaW5nIG91dHB1dC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNtb290aFN0cmVhbTxUT09MUyBleHRlbmRzIFRvb2xTZXQ+KHtcbiAgZGVsYXlJbk1zID0gMTAsXG4gIGNodW5raW5nID0gJ3dvcmQnLFxuICBfaW50ZXJuYWw6IHsgZGVsYXkgPSBvcmlnaW5hbERlbGF5IH0gPSB7fSxcbn06IHtcbiAgZGVsYXlJbk1zPzogbnVtYmVyIHwgbnVsbDtcbiAgY2h1bmtpbmc/OiAnd29yZCcgfCAnbGluZScgfCBSZWdFeHAgfCBDaHVua0RldGVjdG9yO1xuICAvKipcbiAgICogSW50ZXJuYWwuIEZvciB0ZXN0IHVzZSBvbmx5LiBNYXkgY2hhbmdlIHdpdGhvdXQgbm90aWNlLlxuICAgKi9cbiAgX2ludGVybmFsPzoge1xuICAgIGRlbGF5PzogKGRlbGF5SW5NczogbnVtYmVyIHwgbnVsbCkgPT4gUHJvbWlzZTx2b2lkPjtcbiAgfTtcbn0gPSB7fSk6IChvcHRpb25zOiB7XG4gIHRvb2xzOiBUT09MUztcbn0pID0+IFRyYW5zZm9ybVN0cmVhbTxUZXh0U3RyZWFtUGFydDxUT09MUz4sIFRleHRTdHJlYW1QYXJ0PFRPT0xTPj4ge1xuICBsZXQgZGV0ZWN0Q2h1bms6IENodW5rRGV0ZWN0b3I7XG5cbiAgaWYgKHR5cGVvZiBjaHVua2luZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGRldGVjdENodW5rID0gYnVmZmVyID0+IHtcbiAgICAgIGNvbnN0IG1hdGNoID0gY2h1bmtpbmcoYnVmZmVyKTtcblxuICAgICAgaWYgKG1hdGNoID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICAgIGlmICghbWF0Y2gubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2h1bmtpbmcgZnVuY3Rpb24gbXVzdCByZXR1cm4gYSBub24tZW1wdHkgc3RyaW5nLmApO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWJ1ZmZlci5zdGFydHNXaXRoKG1hdGNoKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYENodW5raW5nIGZ1bmN0aW9uIG11c3QgcmV0dXJuIGEgbWF0Y2ggdGhhdCBpcyBhIHByZWZpeCBvZiB0aGUgYnVmZmVyLiBSZWNlaXZlZDogXCIke21hdGNofVwiIGV4cGVjdGVkIHRvIHN0YXJ0IHdpdGggXCIke2J1ZmZlcn1cImAsXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBtYXRjaDtcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IGNodW5raW5nUmVnZXggPVxuICAgICAgdHlwZW9mIGNodW5raW5nID09PSAnc3RyaW5nJyA/IENIVU5LSU5HX1JFR0VYUFNbY2h1bmtpbmddIDogY2h1bmtpbmc7XG5cbiAgICBpZiAoY2h1bmtpbmdSZWdleCA9PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3Ioe1xuICAgICAgICBhcmd1bWVudDogJ2NodW5raW5nJyxcbiAgICAgICAgbWVzc2FnZTogYENodW5raW5nIG11c3QgYmUgXCJ3b3JkXCIgb3IgXCJsaW5lXCIgb3IgYSBSZWdFeHAuIFJlY2VpdmVkOiAke2NodW5raW5nfWAsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBkZXRlY3RDaHVuayA9IGJ1ZmZlciA9PiB7XG4gICAgICBjb25zdCBtYXRjaCA9IGNodW5raW5nUmVnZXguZXhlYyhidWZmZXIpO1xuXG4gICAgICBpZiAoIW1hdGNoKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gYnVmZmVyLnNsaWNlKDAsIG1hdGNoLmluZGV4KSArIG1hdGNoPy5bMF07XG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiAoKSA9PiB7XG4gICAgbGV0IGJ1ZmZlciA9ICcnO1xuICAgIGxldCBpZCA9ICcnO1xuXG4gICAgcmV0dXJuIG5ldyBUcmFuc2Zvcm1TdHJlYW08VGV4dFN0cmVhbVBhcnQ8VE9PTFM+LCBUZXh0U3RyZWFtUGFydDxUT09MUz4+KHtcbiAgICAgIGFzeW5jIHRyYW5zZm9ybShjaHVuaywgY29udHJvbGxlcikge1xuICAgICAgICBpZiAoY2h1bmsudHlwZSAhPT0gJ3RleHQtZGVsdGEnKSB7XG4gICAgICAgICAgaWYgKGJ1ZmZlci5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoeyB0eXBlOiAndGV4dC1kZWx0YScsIHRleHQ6IGJ1ZmZlciwgaWQgfSk7XG4gICAgICAgICAgICBidWZmZXIgPSAnJztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoY2h1bmspO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjaHVuay5pZCAhPT0gaWQgJiYgYnVmZmVyLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoeyB0eXBlOiAndGV4dC1kZWx0YScsIHRleHQ6IGJ1ZmZlciwgaWQgfSk7XG4gICAgICAgICAgYnVmZmVyID0gJyc7XG4gICAgICAgIH1cblxuICAgICAgICBidWZmZXIgKz0gY2h1bmsudGV4dDtcbiAgICAgICAgaWQgPSBjaHVuay5pZDtcblxuICAgICAgICBsZXQgbWF0Y2g7XG5cbiAgICAgICAgd2hpbGUgKChtYXRjaCA9IGRldGVjdENodW5rKGJ1ZmZlcikpICE9IG51bGwpIHtcbiAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoeyB0eXBlOiAndGV4dC1kZWx0YScsIHRleHQ6IG1hdGNoLCBpZCB9KTtcbiAgICAgICAgICBidWZmZXIgPSBidWZmZXIuc2xpY2UobWF0Y2gubGVuZ3RoKTtcblxuICAgICAgICAgIGF3YWl0IGRlbGF5KGRlbGF5SW5Ncyk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSk7XG4gIH07XG59XG4iLCAiaW1wb3J0IHsgTGFuZ3VhZ2VNb2RlbFYyQ2FsbE9wdGlvbnMgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcbmltcG9ydCB7IExhbmd1YWdlTW9kZWxNaWRkbGV3YXJlIH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHsgbWVyZ2VPYmplY3RzIH0gZnJvbSAnLi4vdXRpbC9tZXJnZS1vYmplY3RzJztcblxuLyoqXG4gKiBBcHBsaWVzIGRlZmF1bHQgc2V0dGluZ3MgZm9yIGEgbGFuZ3VhZ2UgbW9kZWwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWZhdWx0U2V0dGluZ3NNaWRkbGV3YXJlKHtcbiAgc2V0dGluZ3MsXG59OiB7XG4gIHNldHRpbmdzOiBQYXJ0aWFsPHtcbiAgICBtYXhPdXRwdXRUb2tlbnM/OiBMYW5ndWFnZU1vZGVsVjJDYWxsT3B0aW9uc1snbWF4T3V0cHV0VG9rZW5zJ107XG4gICAgdGVtcGVyYXR1cmU/OiBMYW5ndWFnZU1vZGVsVjJDYWxsT3B0aW9uc1sndGVtcGVyYXR1cmUnXTtcbiAgICBzdG9wU2VxdWVuY2VzPzogTGFuZ3VhZ2VNb2RlbFYyQ2FsbE9wdGlvbnNbJ3N0b3BTZXF1ZW5jZXMnXTtcbiAgICB0b3BQPzogTGFuZ3VhZ2VNb2RlbFYyQ2FsbE9wdGlvbnNbJ3RvcFAnXTtcbiAgICB0b3BLPzogTGFuZ3VhZ2VNb2RlbFYyQ2FsbE9wdGlvbnNbJ3RvcEsnXTtcbiAgICBwcmVzZW5jZVBlbmFsdHk/OiBMYW5ndWFnZU1vZGVsVjJDYWxsT3B0aW9uc1sncHJlc2VuY2VQZW5hbHR5J107XG4gICAgZnJlcXVlbmN5UGVuYWx0eT86IExhbmd1YWdlTW9kZWxWMkNhbGxPcHRpb25zWydmcmVxdWVuY3lQZW5hbHR5J107XG4gICAgcmVzcG9uc2VGb3JtYXQ/OiBMYW5ndWFnZU1vZGVsVjJDYWxsT3B0aW9uc1sncmVzcG9uc2VGb3JtYXQnXTtcbiAgICBzZWVkPzogTGFuZ3VhZ2VNb2RlbFYyQ2FsbE9wdGlvbnNbJ3NlZWQnXTtcbiAgICB0b29scz86IExhbmd1YWdlTW9kZWxWMkNhbGxPcHRpb25zWyd0b29scyddO1xuICAgIHRvb2xDaG9pY2U/OiBMYW5ndWFnZU1vZGVsVjJDYWxsT3B0aW9uc1sndG9vbENob2ljZSddO1xuICAgIGhlYWRlcnM/OiBMYW5ndWFnZU1vZGVsVjJDYWxsT3B0aW9uc1snaGVhZGVycyddO1xuICAgIHByb3ZpZGVyT3B0aW9ucz86IExhbmd1YWdlTW9kZWxWMkNhbGxPcHRpb25zWydwcm92aWRlck9wdGlvbnMnXTtcbiAgfT47XG59KTogTGFuZ3VhZ2VNb2RlbE1pZGRsZXdhcmUge1xuICByZXR1cm4ge1xuICAgIG1pZGRsZXdhcmVWZXJzaW9uOiAndjInLFxuICAgIHRyYW5zZm9ybVBhcmFtczogYXN5bmMgKHsgcGFyYW1zIH0pID0+IHtcbiAgICAgIHJldHVybiBtZXJnZU9iamVjdHMoc2V0dGluZ3MsIHBhcmFtcykgYXMgTGFuZ3VhZ2VNb2RlbFYyQ2FsbE9wdGlvbnM7XG4gICAgfSxcbiAgfTtcbn1cbiIsICIvKipcbiAqIFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBzdGFydCBvZiB0aGUgc2VhcmNoZWRUZXh0IGluIHRoZSB0ZXh0LCBvciBudWxsIGlmIGl0XG4gKiBpcyBub3QgZm91bmQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRQb3RlbnRpYWxTdGFydEluZGV4KFxuICB0ZXh0OiBzdHJpbmcsXG4gIHNlYXJjaGVkVGV4dDogc3RyaW5nLFxuKTogbnVtYmVyIHwgbnVsbCB7XG4gIC8vIFJldHVybiBudWxsIGltbWVkaWF0ZWx5IGlmIHNlYXJjaGVkVGV4dCBpcyBlbXB0eS5cbiAgaWYgKHNlYXJjaGVkVGV4dC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8vIENoZWNrIGlmIHRoZSBzZWFyY2hlZFRleHQgZXhpc3RzIGFzIGEgZGlyZWN0IHN1YnN0cmluZyBvZiB0ZXh0LlxuICBjb25zdCBkaXJlY3RJbmRleCA9IHRleHQuaW5kZXhPZihzZWFyY2hlZFRleHQpO1xuICBpZiAoZGlyZWN0SW5kZXggIT09IC0xKSB7XG4gICAgcmV0dXJuIGRpcmVjdEluZGV4O1xuICB9XG5cbiAgLy8gT3RoZXJ3aXNlLCBsb29rIGZvciB0aGUgbGFyZ2VzdCBzdWZmaXggb2YgXCJ0ZXh0XCIgdGhhdCBtYXRjaGVzXG4gIC8vIGEgcHJlZml4IG9mIFwic2VhcmNoZWRUZXh0XCIuIFdlIGdvIGZyb20gdGhlIGVuZCBvZiB0ZXh0IGlud2FyZC5cbiAgZm9yIChsZXQgaSA9IHRleHQubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBjb25zdCBzdWZmaXggPSB0ZXh0LnN1YnN0cmluZyhpKTtcbiAgICBpZiAoc2VhcmNoZWRUZXh0LnN0YXJ0c1dpdGgoc3VmZml4KSkge1xuICAgICAgcmV0dXJuIGk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG4iLCAiaW1wb3J0IHR5cGUge1xuICBMYW5ndWFnZU1vZGVsVjJDb250ZW50LFxuICBMYW5ndWFnZU1vZGVsVjJTdHJlYW1QYXJ0LFxufSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcbmltcG9ydCB7IExhbmd1YWdlTW9kZWxNaWRkbGV3YXJlIH0gZnJvbSAnLi4vdHlwZXMvbGFuZ3VhZ2UtbW9kZWwtbWlkZGxld2FyZSc7XG5pbXBvcnQgeyBnZXRQb3RlbnRpYWxTdGFydEluZGV4IH0gZnJvbSAnLi4vdXRpbC9nZXQtcG90ZW50aWFsLXN0YXJ0LWluZGV4JztcblxuLyoqXG4gKiBFeHRyYWN0IGFuIFhNTC10YWdnZWQgcmVhc29uaW5nIHNlY3Rpb24gZnJvbSB0aGUgZ2VuZXJhdGVkIHRleHQgYW5kIGV4cG9zZXMgaXRcbiAqIGFzIGEgYHJlYXNvbmluZ2AgcHJvcGVydHkgb24gdGhlIHJlc3VsdC5cbiAqXG4gKiBAcGFyYW0gdGFnTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBYTUwgdGFnIHRvIGV4dHJhY3QgcmVhc29uaW5nIGZyb20uXG4gKiBAcGFyYW0gc2VwYXJhdG9yIC0gVGhlIHNlcGFyYXRvciB0byB1c2UgYmV0d2VlbiByZWFzb25pbmcgYW5kIHRleHQgc2VjdGlvbnMuXG4gKiBAcGFyYW0gc3RhcnRXaXRoUmVhc29uaW5nIC0gV2hldGhlciB0byBzdGFydCB3aXRoIHJlYXNvbmluZyB0b2tlbnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBleHRyYWN0UmVhc29uaW5nTWlkZGxld2FyZSh7XG4gIHRhZ05hbWUsXG4gIHNlcGFyYXRvciA9ICdcXG4nLFxuICBzdGFydFdpdGhSZWFzb25pbmcgPSBmYWxzZSxcbn06IHtcbiAgdGFnTmFtZTogc3RyaW5nO1xuICBzZXBhcmF0b3I/OiBzdHJpbmc7XG4gIHN0YXJ0V2l0aFJlYXNvbmluZz86IGJvb2xlYW47XG59KTogTGFuZ3VhZ2VNb2RlbE1pZGRsZXdhcmUge1xuICBjb25zdCBvcGVuaW5nVGFnID0gYDwke3RhZ05hbWV9PmA7XG4gIGNvbnN0IGNsb3NpbmdUYWcgPSBgPFxcLyR7dGFnTmFtZX0+YDtcblxuICByZXR1cm4ge1xuICAgIG1pZGRsZXdhcmVWZXJzaW9uOiAndjInLFxuICAgIHdyYXBHZW5lcmF0ZTogYXN5bmMgKHsgZG9HZW5lcmF0ZSB9KSA9PiB7XG4gICAgICBjb25zdCB7IGNvbnRlbnQsIC4uLnJlc3QgfSA9IGF3YWl0IGRvR2VuZXJhdGUoKTtcblxuICAgICAgY29uc3QgdHJhbnNmb3JtZWRDb250ZW50OiBMYW5ndWFnZU1vZGVsVjJDb250ZW50W10gPSBbXTtcbiAgICAgIGZvciAoY29uc3QgcGFydCBvZiBjb250ZW50KSB7XG4gICAgICAgIGlmIChwYXJ0LnR5cGUgIT09ICd0ZXh0Jykge1xuICAgICAgICAgIHRyYW5zZm9ybWVkQ29udGVudC5wdXNoKHBhcnQpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdGV4dCA9IHN0YXJ0V2l0aFJlYXNvbmluZyA/IG9wZW5pbmdUYWcgKyBwYXJ0LnRleHQgOiBwYXJ0LnRleHQ7XG5cbiAgICAgICAgY29uc3QgcmVnZXhwID0gbmV3IFJlZ0V4cChgJHtvcGVuaW5nVGFnfSguKj8pJHtjbG9zaW5nVGFnfWAsICdncycpO1xuICAgICAgICBjb25zdCBtYXRjaGVzID0gQXJyYXkuZnJvbSh0ZXh0Lm1hdGNoQWxsKHJlZ2V4cCkpO1xuXG4gICAgICAgIGlmICghbWF0Y2hlcy5sZW5ndGgpIHtcbiAgICAgICAgICB0cmFuc2Zvcm1lZENvbnRlbnQucHVzaChwYXJ0KTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlYXNvbmluZ1RleHQgPSBtYXRjaGVzLm1hcChtYXRjaCA9PiBtYXRjaFsxXSkuam9pbihzZXBhcmF0b3IpO1xuXG4gICAgICAgIGxldCB0ZXh0V2l0aG91dFJlYXNvbmluZyA9IHRleHQ7XG4gICAgICAgIGZvciAobGV0IGkgPSBtYXRjaGVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgY29uc3QgbWF0Y2ggPSBtYXRjaGVzW2ldO1xuXG4gICAgICAgICAgY29uc3QgYmVmb3JlTWF0Y2ggPSB0ZXh0V2l0aG91dFJlYXNvbmluZy5zbGljZSgwLCBtYXRjaC5pbmRleCk7XG4gICAgICAgICAgY29uc3QgYWZ0ZXJNYXRjaCA9IHRleHRXaXRob3V0UmVhc29uaW5nLnNsaWNlKFxuICAgICAgICAgICAgbWF0Y2guaW5kZXghICsgbWF0Y2hbMF0ubGVuZ3RoLFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICB0ZXh0V2l0aG91dFJlYXNvbmluZyA9XG4gICAgICAgICAgICBiZWZvcmVNYXRjaCArXG4gICAgICAgICAgICAoYmVmb3JlTWF0Y2gubGVuZ3RoID4gMCAmJiBhZnRlck1hdGNoLmxlbmd0aCA+IDAgPyBzZXBhcmF0b3IgOiAnJykgK1xuICAgICAgICAgICAgYWZ0ZXJNYXRjaDtcbiAgICAgICAgfVxuXG4gICAgICAgIHRyYW5zZm9ybWVkQ29udGVudC5wdXNoKHtcbiAgICAgICAgICB0eXBlOiAncmVhc29uaW5nJyxcbiAgICAgICAgICB0ZXh0OiByZWFzb25pbmdUZXh0LFxuICAgICAgICB9KTtcblxuICAgICAgICB0cmFuc2Zvcm1lZENvbnRlbnQucHVzaCh7XG4gICAgICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgICAgIHRleHQ6IHRleHRXaXRob3V0UmVhc29uaW5nLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHsgY29udGVudDogdHJhbnNmb3JtZWRDb250ZW50LCAuLi5yZXN0IH07XG4gICAgfSxcblxuICAgIHdyYXBTdHJlYW06IGFzeW5jICh7IGRvU3RyZWFtIH0pID0+IHtcbiAgICAgIGNvbnN0IHsgc3RyZWFtLCAuLi5yZXN0IH0gPSBhd2FpdCBkb1N0cmVhbSgpO1xuXG4gICAgICBjb25zdCByZWFzb25pbmdFeHRyYWN0aW9uczogUmVjb3JkPFxuICAgICAgICBzdHJpbmcsXG4gICAgICAgIHtcbiAgICAgICAgICBpc0ZpcnN0UmVhc29uaW5nOiBib29sZWFuO1xuICAgICAgICAgIGlzRmlyc3RUZXh0OiBib29sZWFuO1xuICAgICAgICAgIGFmdGVyU3dpdGNoOiBib29sZWFuO1xuICAgICAgICAgIGlzUmVhc29uaW5nOiBib29sZWFuO1xuICAgICAgICAgIGJ1ZmZlcjogc3RyaW5nO1xuICAgICAgICAgIGlkQ291bnRlcjogbnVtYmVyO1xuICAgICAgICAgIHRleHRJZDogc3RyaW5nO1xuICAgICAgICB9XG4gICAgICA+ID0ge307XG5cbiAgICAgIGxldCBkZWxheWVkVGV4dFN0YXJ0OiBMYW5ndWFnZU1vZGVsVjJTdHJlYW1QYXJ0IHwgdW5kZWZpbmVkO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBzdHJlYW06IHN0cmVhbS5waXBlVGhyb3VnaChcbiAgICAgICAgICBuZXcgVHJhbnNmb3JtU3RyZWFtPFxuICAgICAgICAgICAgTGFuZ3VhZ2VNb2RlbFYyU3RyZWFtUGFydCxcbiAgICAgICAgICAgIExhbmd1YWdlTW9kZWxWMlN0cmVhbVBhcnRcbiAgICAgICAgICA+KHtcbiAgICAgICAgICAgIHRyYW5zZm9ybTogKGNodW5rLCBjb250cm9sbGVyKSA9PiB7XG4gICAgICAgICAgICAgIC8vIGRvIG5vdCBzZW5kIGB0ZXh0LXN0YXJ0YCBiZWZvcmUgYHJlYXNvbmluZy1zdGFydGBcbiAgICAgICAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL3ZlcmNlbC9haS9pc3N1ZXMvNzc3NFxuICAgICAgICAgICAgICBpZiAoY2h1bmsudHlwZSA9PT0gJ3RleHQtc3RhcnQnKSB7XG4gICAgICAgICAgICAgICAgZGVsYXllZFRleHRTdGFydCA9IGNodW5rO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmIChjaHVuay50eXBlID09PSAndGV4dC1lbmQnICYmIGRlbGF5ZWRUZXh0U3RhcnQpIHtcbiAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoZGVsYXllZFRleHRTdGFydCk7XG4gICAgICAgICAgICAgICAgZGVsYXllZFRleHRTdGFydCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmIChjaHVuay50eXBlICE9PSAndGV4dC1kZWx0YScpIHtcbiAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoY2h1bmspO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmIChyZWFzb25pbmdFeHRyYWN0aW9uc1tjaHVuay5pZF0gPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJlYXNvbmluZ0V4dHJhY3Rpb25zW2NodW5rLmlkXSA9IHtcbiAgICAgICAgICAgICAgICAgIGlzRmlyc3RSZWFzb25pbmc6IHRydWUsXG4gICAgICAgICAgICAgICAgICBpc0ZpcnN0VGV4dDogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgIGFmdGVyU3dpdGNoOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgIGlzUmVhc29uaW5nOiBzdGFydFdpdGhSZWFzb25pbmcsXG4gICAgICAgICAgICAgICAgICBidWZmZXI6ICcnLFxuICAgICAgICAgICAgICAgICAgaWRDb3VudGVyOiAwLFxuICAgICAgICAgICAgICAgICAgdGV4dElkOiBjaHVuay5pZCxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgY29uc3QgYWN0aXZlRXh0cmFjdGlvbiA9IHJlYXNvbmluZ0V4dHJhY3Rpb25zW2NodW5rLmlkXTtcblxuICAgICAgICAgICAgICBhY3RpdmVFeHRyYWN0aW9uLmJ1ZmZlciArPSBjaHVuay5kZWx0YTtcblxuICAgICAgICAgICAgICBmdW5jdGlvbiBwdWJsaXNoKHRleHQ6IHN0cmluZykge1xuICAgICAgICAgICAgICAgIGlmICh0ZXh0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHByZWZpeCA9XG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZUV4dHJhY3Rpb24uYWZ0ZXJTd2l0Y2ggJiZcbiAgICAgICAgICAgICAgICAgICAgKGFjdGl2ZUV4dHJhY3Rpb24uaXNSZWFzb25pbmdcbiAgICAgICAgICAgICAgICAgICAgICA/ICFhY3RpdmVFeHRyYWN0aW9uLmlzRmlyc3RSZWFzb25pbmdcbiAgICAgICAgICAgICAgICAgICAgICA6ICFhY3RpdmVFeHRyYWN0aW9uLmlzRmlyc3RUZXh0KVxuICAgICAgICAgICAgICAgICAgICAgID8gc2VwYXJhdG9yXG4gICAgICAgICAgICAgICAgICAgICAgOiAnJztcblxuICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICBhY3RpdmVFeHRyYWN0aW9uLmlzUmVhc29uaW5nICYmXG4gICAgICAgICAgICAgICAgICAgIChhY3RpdmVFeHRyYWN0aW9uLmFmdGVyU3dpdGNoIHx8XG4gICAgICAgICAgICAgICAgICAgICAgYWN0aXZlRXh0cmFjdGlvbi5pc0ZpcnN0UmVhc29uaW5nKVxuICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3JlYXNvbmluZy1zdGFydCcsXG4gICAgICAgICAgICAgICAgICAgICAgaWQ6IGByZWFzb25pbmctJHthY3RpdmVFeHRyYWN0aW9uLmlkQ291bnRlcn1gLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgaWYgKGFjdGl2ZUV4dHJhY3Rpb24uaXNSZWFzb25pbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHtcbiAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAncmVhc29uaW5nLWRlbHRhJyxcbiAgICAgICAgICAgICAgICAgICAgICBkZWx0YTogcHJlZml4ICsgdGV4dCxcbiAgICAgICAgICAgICAgICAgICAgICBpZDogYHJlYXNvbmluZy0ke2FjdGl2ZUV4dHJhY3Rpb24uaWRDb3VudGVyfWAsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRlbGF5ZWRUZXh0U3RhcnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoZGVsYXllZFRleHRTdGFydCk7XG4gICAgICAgICAgICAgICAgICAgICAgZGVsYXllZFRleHRTdGFydCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICd0ZXh0LWRlbHRhJyxcbiAgICAgICAgICAgICAgICAgICAgICBkZWx0YTogcHJlZml4ICsgdGV4dCxcbiAgICAgICAgICAgICAgICAgICAgICBpZDogYWN0aXZlRXh0cmFjdGlvbi50ZXh0SWQsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgYWN0aXZlRXh0cmFjdGlvbi5hZnRlclN3aXRjaCA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgICBpZiAoYWN0aXZlRXh0cmFjdGlvbi5pc1JlYXNvbmluZykge1xuICAgICAgICAgICAgICAgICAgICBhY3RpdmVFeHRyYWN0aW9uLmlzRmlyc3RSZWFzb25pbmcgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZUV4dHJhY3Rpb24uaXNGaXJzdFRleHQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBkbyB7XG4gICAgICAgICAgICAgICAgY29uc3QgbmV4dFRhZyA9IGFjdGl2ZUV4dHJhY3Rpb24uaXNSZWFzb25pbmdcbiAgICAgICAgICAgICAgICAgID8gY2xvc2luZ1RhZ1xuICAgICAgICAgICAgICAgICAgOiBvcGVuaW5nVGFnO1xuXG4gICAgICAgICAgICAgICAgY29uc3Qgc3RhcnRJbmRleCA9IGdldFBvdGVudGlhbFN0YXJ0SW5kZXgoXG4gICAgICAgICAgICAgICAgICBhY3RpdmVFeHRyYWN0aW9uLmJ1ZmZlcixcbiAgICAgICAgICAgICAgICAgIG5leHRUYWcsXG4gICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgIC8vIG5vIG9wZW5pbmcgb3IgY2xvc2luZyB0YWcgZm91bmQsIHB1Ymxpc2ggdGhlIGJ1ZmZlclxuICAgICAgICAgICAgICAgIGlmIChzdGFydEluZGV4ID09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgIHB1Ymxpc2goYWN0aXZlRXh0cmFjdGlvbi5idWZmZXIpO1xuICAgICAgICAgICAgICAgICAgYWN0aXZlRXh0cmFjdGlvbi5idWZmZXIgPSAnJztcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIHB1Ymxpc2ggdGV4dCBiZWZvcmUgdGhlIHRhZ1xuICAgICAgICAgICAgICAgIHB1Ymxpc2goYWN0aXZlRXh0cmFjdGlvbi5idWZmZXIuc2xpY2UoMCwgc3RhcnRJbmRleCkpO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgZm91bmRGdWxsTWF0Y2ggPVxuICAgICAgICAgICAgICAgICAgc3RhcnRJbmRleCArIG5leHRUYWcubGVuZ3RoIDw9IGFjdGl2ZUV4dHJhY3Rpb24uYnVmZmVyLmxlbmd0aDtcblxuICAgICAgICAgICAgICAgIGlmIChmb3VuZEZ1bGxNYXRjaCkge1xuICAgICAgICAgICAgICAgICAgYWN0aXZlRXh0cmFjdGlvbi5idWZmZXIgPSBhY3RpdmVFeHRyYWN0aW9uLmJ1ZmZlci5zbGljZShcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRJbmRleCArIG5leHRUYWcubGVuZ3RoLFxuICAgICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgICAgLy8gcmVhc29uaW5nIHBhcnQgZmluaXNoZWQ6XG4gICAgICAgICAgICAgICAgICBpZiAoYWN0aXZlRXh0cmFjdGlvbi5pc1JlYXNvbmluZykge1xuICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdyZWFzb25pbmctZW5kJyxcbiAgICAgICAgICAgICAgICAgICAgICBpZDogYHJlYXNvbmluZy0ke2FjdGl2ZUV4dHJhY3Rpb24uaWRDb3VudGVyKyt9YCxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgIGFjdGl2ZUV4dHJhY3Rpb24uaXNSZWFzb25pbmcgPSAhYWN0aXZlRXh0cmFjdGlvbi5pc1JlYXNvbmluZztcbiAgICAgICAgICAgICAgICAgIGFjdGl2ZUV4dHJhY3Rpb24uYWZ0ZXJTd2l0Y2ggPSB0cnVlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBhY3RpdmVFeHRyYWN0aW9uLmJ1ZmZlciA9XG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZUV4dHJhY3Rpb24uYnVmZmVyLnNsaWNlKHN0YXJ0SW5kZXgpO1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IHdoaWxlICh0cnVlKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSksXG4gICAgICAgICksXG4gICAgICAgIC4uLnJlc3QsXG4gICAgICB9O1xuICAgIH0sXG4gIH07XG59XG4iLCAiaW1wb3J0IHR5cGUgeyBMYW5ndWFnZU1vZGVsVjJTdHJlYW1QYXJ0IH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQgeyBMYW5ndWFnZU1vZGVsTWlkZGxld2FyZSB9IGZyb20gJy4uL3R5cGVzJztcblxuLyoqXG4gKiBTaW11bGF0ZXMgc3RyZWFtaW5nIGNodW5rcyB3aXRoIHRoZSByZXNwb25zZSBmcm9tIGEgZ2VuZXJhdGUgY2FsbC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNpbXVsYXRlU3RyZWFtaW5nTWlkZGxld2FyZSgpOiBMYW5ndWFnZU1vZGVsTWlkZGxld2FyZSB7XG4gIHJldHVybiB7XG4gICAgbWlkZGxld2FyZVZlcnNpb246ICd2MicsXG4gICAgd3JhcFN0cmVhbTogYXN5bmMgKHsgZG9HZW5lcmF0ZSB9KSA9PiB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBkb0dlbmVyYXRlKCk7XG5cbiAgICAgIGxldCBpZCA9IDA7XG5cbiAgICAgIGNvbnN0IHNpbXVsYXRlZFN0cmVhbSA9IG5ldyBSZWFkYWJsZVN0cmVhbTxMYW5ndWFnZU1vZGVsVjJTdHJlYW1QYXJ0Pih7XG4gICAgICAgIHN0YXJ0KGNvbnRyb2xsZXIpIHtcbiAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoe1xuICAgICAgICAgICAgdHlwZTogJ3N0cmVhbS1zdGFydCcsXG4gICAgICAgICAgICB3YXJuaW5nczogcmVzdWx0Lndhcm5pbmdzLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHsgdHlwZTogJ3Jlc3BvbnNlLW1ldGFkYXRhJywgLi4ucmVzdWx0LnJlc3BvbnNlIH0pO1xuXG4gICAgICAgICAgZm9yIChjb25zdCBwYXJ0IG9mIHJlc3VsdC5jb250ZW50KSB7XG4gICAgICAgICAgICBzd2l0Y2ggKHBhcnQudHlwZSkge1xuICAgICAgICAgICAgICBjYXNlICd0ZXh0Jzoge1xuICAgICAgICAgICAgICAgIGlmIChwYXJ0LnRleHQubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHsgdHlwZTogJ3RleHQtc3RhcnQnLCBpZDogU3RyaW5nKGlkKSB9KTtcbiAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICd0ZXh0LWRlbHRhJyxcbiAgICAgICAgICAgICAgICAgICAgaWQ6IFN0cmluZyhpZCksXG4gICAgICAgICAgICAgICAgICAgIGRlbHRhOiBwYXJ0LnRleHQsXG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7IHR5cGU6ICd0ZXh0LWVuZCcsIGlkOiBTdHJpbmcoaWQpIH0pO1xuICAgICAgICAgICAgICAgICAgaWQrKztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgY2FzZSAncmVhc29uaW5nJzoge1xuICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgICAgICB0eXBlOiAncmVhc29uaW5nLXN0YXJ0JyxcbiAgICAgICAgICAgICAgICAgIGlkOiBTdHJpbmcoaWQpLFxuICAgICAgICAgICAgICAgICAgcHJvdmlkZXJNZXRhZGF0YTogcGFydC5wcm92aWRlck1ldGFkYXRhLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICAgICAgICB0eXBlOiAncmVhc29uaW5nLWRlbHRhJyxcbiAgICAgICAgICAgICAgICAgIGlkOiBTdHJpbmcoaWQpLFxuICAgICAgICAgICAgICAgICAgZGVsdGE6IHBhcnQudGV4dCxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoeyB0eXBlOiAncmVhc29uaW5nLWVuZCcsIGlkOiBTdHJpbmcoaWQpIH0pO1xuICAgICAgICAgICAgICAgIGlkKys7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShwYXJ0KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7XG4gICAgICAgICAgICB0eXBlOiAnZmluaXNoJyxcbiAgICAgICAgICAgIGZpbmlzaFJlYXNvbjogcmVzdWx0LmZpbmlzaFJlYXNvbixcbiAgICAgICAgICAgIHVzYWdlOiByZXN1bHQudXNhZ2UsXG4gICAgICAgICAgICBwcm92aWRlck1ldGFkYXRhOiByZXN1bHQucHJvdmlkZXJNZXRhZGF0YSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNvbnRyb2xsZXIuY2xvc2UoKTtcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBzdHJlYW06IHNpbXVsYXRlZFN0cmVhbSxcbiAgICAgICAgcmVxdWVzdDogcmVzdWx0LnJlcXVlc3QsXG4gICAgICAgIHJlc3BvbnNlOiByZXN1bHQucmVzcG9uc2UsXG4gICAgICB9O1xuICAgIH0sXG4gIH07XG59XG4iLCAiaW1wb3J0IHsgTGFuZ3VhZ2VNb2RlbFYyLCBMYW5ndWFnZU1vZGVsVjJDYWxsT3B0aW9ucyB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgTGFuZ3VhZ2VNb2RlbE1pZGRsZXdhcmUgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgeyBhc0FycmF5IH0gZnJvbSAnLi4vdXRpbC9hcy1hcnJheSc7XG5cbi8qKlxuICogV3JhcHMgYSBMYW5ndWFnZU1vZGVsVjIgaW5zdGFuY2Ugd2l0aCBtaWRkbGV3YXJlIGZ1bmN0aW9uYWxpdHkuXG4gKiBUaGlzIGZ1bmN0aW9uIGFsbG93cyB5b3UgdG8gYXBwbHkgbWlkZGxld2FyZSB0byB0cmFuc2Zvcm0gcGFyYW1ldGVycyxcbiAqIHdyYXAgZ2VuZXJhdGUgb3BlcmF0aW9ucywgYW5kIHdyYXAgc3RyZWFtIG9wZXJhdGlvbnMgb2YgYSBsYW5ndWFnZSBtb2RlbC5cbiAqXG4gKiBAcGFyYW0gb3B0aW9ucyAtIENvbmZpZ3VyYXRpb24gb3B0aW9ucyBmb3Igd3JhcHBpbmcgdGhlIGxhbmd1YWdlIG1vZGVsLlxuICogQHBhcmFtIG9wdGlvbnMubW9kZWwgLSBUaGUgb3JpZ2luYWwgTGFuZ3VhZ2VNb2RlbFYyIGluc3RhbmNlIHRvIGJlIHdyYXBwZWQuXG4gKiBAcGFyYW0gb3B0aW9ucy5taWRkbGV3YXJlIC0gVGhlIG1pZGRsZXdhcmUgdG8gYmUgYXBwbGllZCB0byB0aGUgbGFuZ3VhZ2UgbW9kZWwuIFdoZW4gbXVsdGlwbGUgbWlkZGxld2FyZXMgYXJlIHByb3ZpZGVkLCB0aGUgZmlyc3QgbWlkZGxld2FyZSB3aWxsIHRyYW5zZm9ybSB0aGUgaW5wdXQgZmlyc3QsIGFuZCB0aGUgbGFzdCBtaWRkbGV3YXJlIHdpbGwgYmUgd3JhcHBlZCBkaXJlY3RseSBhcm91bmQgdGhlIG1vZGVsLlxuICogQHBhcmFtIG9wdGlvbnMubW9kZWxJZCAtIE9wdGlvbmFsIGN1c3RvbSBtb2RlbCBJRCB0byBvdmVycmlkZSB0aGUgb3JpZ2luYWwgbW9kZWwncyBJRC5cbiAqIEBwYXJhbSBvcHRpb25zLnByb3ZpZGVySWQgLSBPcHRpb25hbCBjdXN0b20gcHJvdmlkZXIgSUQgdG8gb3ZlcnJpZGUgdGhlIG9yaWdpbmFsIG1vZGVsJ3MgcHJvdmlkZXIgSUQuXG4gKiBAcmV0dXJucyBBIG5ldyBMYW5ndWFnZU1vZGVsVjIgaW5zdGFuY2Ugd2l0aCBtaWRkbGV3YXJlIGFwcGxpZWQuXG4gKi9cbmV4cG9ydCBjb25zdCB3cmFwTGFuZ3VhZ2VNb2RlbCA9ICh7XG4gIG1vZGVsLFxuICBtaWRkbGV3YXJlOiBtaWRkbGV3YXJlQXJnLFxuICBtb2RlbElkLFxuICBwcm92aWRlcklkLFxufToge1xuICBtb2RlbDogTGFuZ3VhZ2VNb2RlbFYyO1xuICBtaWRkbGV3YXJlOiBMYW5ndWFnZU1vZGVsTWlkZGxld2FyZSB8IExhbmd1YWdlTW9kZWxNaWRkbGV3YXJlW107XG4gIG1vZGVsSWQ/OiBzdHJpbmc7XG4gIHByb3ZpZGVySWQ/OiBzdHJpbmc7XG59KTogTGFuZ3VhZ2VNb2RlbFYyID0+IHtcbiAgcmV0dXJuIGFzQXJyYXkobWlkZGxld2FyZUFyZylcbiAgICAucmV2ZXJzZSgpXG4gICAgLnJlZHVjZSgod3JhcHBlZE1vZGVsLCBtaWRkbGV3YXJlKSA9PiB7XG4gICAgICByZXR1cm4gZG9XcmFwKHsgbW9kZWw6IHdyYXBwZWRNb2RlbCwgbWlkZGxld2FyZSwgbW9kZWxJZCwgcHJvdmlkZXJJZCB9KTtcbiAgICB9LCBtb2RlbCk7XG59O1xuXG5jb25zdCBkb1dyYXAgPSAoe1xuICBtb2RlbCxcbiAgbWlkZGxld2FyZToge1xuICAgIHRyYW5zZm9ybVBhcmFtcyxcbiAgICB3cmFwR2VuZXJhdGUsXG4gICAgd3JhcFN0cmVhbSxcbiAgICBvdmVycmlkZVByb3ZpZGVyLFxuICAgIG92ZXJyaWRlTW9kZWxJZCxcbiAgICBvdmVycmlkZVN1cHBvcnRlZFVybHMsXG4gIH0sXG4gIG1vZGVsSWQsXG4gIHByb3ZpZGVySWQsXG59OiB7XG4gIG1vZGVsOiBMYW5ndWFnZU1vZGVsVjI7XG4gIG1pZGRsZXdhcmU6IExhbmd1YWdlTW9kZWxNaWRkbGV3YXJlO1xuICBtb2RlbElkPzogc3RyaW5nO1xuICBwcm92aWRlcklkPzogc3RyaW5nO1xufSk6IExhbmd1YWdlTW9kZWxWMiA9PiB7XG4gIGFzeW5jIGZ1bmN0aW9uIGRvVHJhbnNmb3JtKHtcbiAgICBwYXJhbXMsXG4gICAgdHlwZSxcbiAgfToge1xuICAgIHBhcmFtczogTGFuZ3VhZ2VNb2RlbFYyQ2FsbE9wdGlvbnM7XG4gICAgdHlwZTogJ2dlbmVyYXRlJyB8ICdzdHJlYW0nO1xuICB9KSB7XG4gICAgcmV0dXJuIHRyYW5zZm9ybVBhcmFtc1xuICAgICAgPyBhd2FpdCB0cmFuc2Zvcm1QYXJhbXMoeyBwYXJhbXMsIHR5cGUsIG1vZGVsIH0pXG4gICAgICA6IHBhcmFtcztcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgc3BlY2lmaWNhdGlvblZlcnNpb246ICd2MicsXG5cbiAgICBwcm92aWRlcjogcHJvdmlkZXJJZCA/PyBvdmVycmlkZVByb3ZpZGVyPy4oeyBtb2RlbCB9KSA/PyBtb2RlbC5wcm92aWRlcixcbiAgICBtb2RlbElkOiBtb2RlbElkID8/IG92ZXJyaWRlTW9kZWxJZD8uKHsgbW9kZWwgfSkgPz8gbW9kZWwubW9kZWxJZCxcbiAgICBzdXBwb3J0ZWRVcmxzOiBvdmVycmlkZVN1cHBvcnRlZFVybHM/Lih7IG1vZGVsIH0pID8/IG1vZGVsLnN1cHBvcnRlZFVybHMsXG5cbiAgICBhc3luYyBkb0dlbmVyYXRlKFxuICAgICAgcGFyYW1zOiBMYW5ndWFnZU1vZGVsVjJDYWxsT3B0aW9ucyxcbiAgICApOiBQcm9taXNlPEF3YWl0ZWQ8UmV0dXJuVHlwZTxMYW5ndWFnZU1vZGVsVjJbJ2RvR2VuZXJhdGUnXT4+PiB7XG4gICAgICBjb25zdCB0cmFuc2Zvcm1lZFBhcmFtcyA9IGF3YWl0IGRvVHJhbnNmb3JtKHsgcGFyYW1zLCB0eXBlOiAnZ2VuZXJhdGUnIH0pO1xuICAgICAgY29uc3QgZG9HZW5lcmF0ZSA9IGFzeW5jICgpID0+IG1vZGVsLmRvR2VuZXJhdGUodHJhbnNmb3JtZWRQYXJhbXMpO1xuICAgICAgY29uc3QgZG9TdHJlYW0gPSBhc3luYyAoKSA9PiBtb2RlbC5kb1N0cmVhbSh0cmFuc2Zvcm1lZFBhcmFtcyk7XG4gICAgICByZXR1cm4gd3JhcEdlbmVyYXRlXG4gICAgICAgID8gd3JhcEdlbmVyYXRlKHtcbiAgICAgICAgICAgIGRvR2VuZXJhdGUsXG4gICAgICAgICAgICBkb1N0cmVhbSxcbiAgICAgICAgICAgIHBhcmFtczogdHJhbnNmb3JtZWRQYXJhbXMsXG4gICAgICAgICAgICBtb2RlbCxcbiAgICAgICAgICB9KVxuICAgICAgICA6IGRvR2VuZXJhdGUoKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZG9TdHJlYW0oXG4gICAgICBwYXJhbXM6IExhbmd1YWdlTW9kZWxWMkNhbGxPcHRpb25zLFxuICAgICk6IFByb21pc2U8QXdhaXRlZDxSZXR1cm5UeXBlPExhbmd1YWdlTW9kZWxWMlsnZG9TdHJlYW0nXT4+PiB7XG4gICAgICBjb25zdCB0cmFuc2Zvcm1lZFBhcmFtcyA9IGF3YWl0IGRvVHJhbnNmb3JtKHsgcGFyYW1zLCB0eXBlOiAnc3RyZWFtJyB9KTtcbiAgICAgIGNvbnN0IGRvR2VuZXJhdGUgPSBhc3luYyAoKSA9PiBtb2RlbC5kb0dlbmVyYXRlKHRyYW5zZm9ybWVkUGFyYW1zKTtcbiAgICAgIGNvbnN0IGRvU3RyZWFtID0gYXN5bmMgKCkgPT4gbW9kZWwuZG9TdHJlYW0odHJhbnNmb3JtZWRQYXJhbXMpO1xuICAgICAgcmV0dXJuIHdyYXBTdHJlYW1cbiAgICAgICAgPyB3cmFwU3RyZWFtKHsgZG9HZW5lcmF0ZSwgZG9TdHJlYW0sIHBhcmFtczogdHJhbnNmb3JtZWRQYXJhbXMsIG1vZGVsIH0pXG4gICAgICAgIDogZG9TdHJlYW0oKTtcbiAgICB9LFxuICB9O1xufTtcbiIsICJpbXBvcnQgdHlwZSB7IFByb3ZpZGVyVjIgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcbmltcG9ydCB7IExhbmd1YWdlTW9kZWxNaWRkbGV3YXJlIH0gZnJvbSAnLi4vdHlwZXMvbGFuZ3VhZ2UtbW9kZWwtbWlkZGxld2FyZSc7XG5pbXBvcnQgeyB3cmFwTGFuZ3VhZ2VNb2RlbCB9IGZyb20gJy4vd3JhcC1sYW5ndWFnZS1tb2RlbCc7XG5cbi8qKlxuICogV3JhcHMgYSBQcm92aWRlclYyIGluc3RhbmNlIHdpdGggbWlkZGxld2FyZSBmdW5jdGlvbmFsaXR5LlxuICogVGhpcyBmdW5jdGlvbiBhbGxvd3MgeW91IHRvIGFwcGx5IG1pZGRsZXdhcmUgdG8gYWxsIGxhbmd1YWdlIG1vZGVsc1xuICogZnJvbSB0aGUgcHJvdmlkZXIsIGVuYWJsaW5nIHlvdSB0byB0cmFuc2Zvcm0gcGFyYW1ldGVycywgd3JhcCBnZW5lcmF0ZVxuICogb3BlcmF0aW9ucywgYW5kIHdyYXAgc3RyZWFtIG9wZXJhdGlvbnMgZm9yIGV2ZXJ5IGxhbmd1YWdlIG1vZGVsLlxuICpcbiAqIEBwYXJhbSBvcHRpb25zIC0gQ29uZmlndXJhdGlvbiBvcHRpb25zIGZvciB3cmFwcGluZyB0aGUgcHJvdmlkZXIuXG4gKiBAcGFyYW0gb3B0aW9ucy5wcm92aWRlciAtIFRoZSBvcmlnaW5hbCBQcm92aWRlclYyIGluc3RhbmNlIHRvIGJlIHdyYXBwZWQuXG4gKiBAcGFyYW0gb3B0aW9ucy5sYW5ndWFnZU1vZGVsTWlkZGxld2FyZSAtIFRoZSBtaWRkbGV3YXJlIHRvIGJlIGFwcGxpZWQgdG8gYWxsIGxhbmd1YWdlIG1vZGVscyBmcm9tIHRoZSBwcm92aWRlci4gV2hlbiBtdWx0aXBsZSBtaWRkbGV3YXJlcyBhcmUgcHJvdmlkZWQsIHRoZSBmaXJzdCBtaWRkbGV3YXJlIHdpbGwgdHJhbnNmb3JtIHRoZSBpbnB1dCBmaXJzdCwgYW5kIHRoZSBsYXN0IG1pZGRsZXdhcmUgd2lsbCBiZSB3cmFwcGVkIGRpcmVjdGx5IGFyb3VuZCB0aGUgbW9kZWwuXG4gKiBAcmV0dXJucyBBIG5ldyBQcm92aWRlclYyIGluc3RhbmNlIHdpdGggbWlkZGxld2FyZSBhcHBsaWVkIHRvIGFsbCBsYW5ndWFnZSBtb2RlbHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3cmFwUHJvdmlkZXIoe1xuICBwcm92aWRlcixcbiAgbGFuZ3VhZ2VNb2RlbE1pZGRsZXdhcmUsXG59OiB7XG4gIHByb3ZpZGVyOiBQcm92aWRlclYyO1xuICBsYW5ndWFnZU1vZGVsTWlkZGxld2FyZTogTGFuZ3VhZ2VNb2RlbE1pZGRsZXdhcmUgfCBMYW5ndWFnZU1vZGVsTWlkZGxld2FyZVtdO1xufSk6IFByb3ZpZGVyVjIge1xuICBjb25zdCB3cmFwcGVkUHJvdmlkZXIgPSB7XG4gICAgbGFuZ3VhZ2VNb2RlbChtb2RlbElkOiBzdHJpbmcpIHtcbiAgICAgIGxldCBtb2RlbCA9IHByb3ZpZGVyLmxhbmd1YWdlTW9kZWwobW9kZWxJZCk7XG4gICAgICBtb2RlbCA9IHdyYXBMYW5ndWFnZU1vZGVsKHtcbiAgICAgICAgbW9kZWwsXG4gICAgICAgIG1pZGRsZXdhcmU6IGxhbmd1YWdlTW9kZWxNaWRkbGV3YXJlLFxuICAgICAgfSk7XG4gICAgICByZXR1cm4gbW9kZWw7XG4gICAgfSxcbiAgICB0ZXh0RW1iZWRkaW5nTW9kZWw6IHByb3ZpZGVyLnRleHRFbWJlZGRpbmdNb2RlbCxcbiAgICBpbWFnZU1vZGVsOiBwcm92aWRlci5pbWFnZU1vZGVsLFxuICAgIHRyYW5zY3JpcHRpb25Nb2RlbDogcHJvdmlkZXIudHJhbnNjcmlwdGlvbk1vZGVsLFxuICAgIHNwZWVjaE1vZGVsOiBwcm92aWRlci5zcGVlY2hNb2RlbCxcbiAgfTtcblxuICByZXR1cm4gd3JhcHBlZFByb3ZpZGVyO1xufVxuIiwgImltcG9ydCB7XG4gIEVtYmVkZGluZ01vZGVsVjIsXG4gIEltYWdlTW9kZWxWMixcbiAgTGFuZ3VhZ2VNb2RlbFYyLFxuICBOb1N1Y2hNb2RlbEVycm9yLFxuICBQcm92aWRlclYyLFxuICBTcGVlY2hNb2RlbFYyLFxuICBUcmFuc2NyaXB0aW9uTW9kZWxWMixcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGN1c3RvbSBwcm92aWRlciB3aXRoIHNwZWNpZmllZCBsYW5ndWFnZSBtb2RlbHMsIHRleHQgZW1iZWRkaW5nIG1vZGVscywgaW1hZ2UgbW9kZWxzLCB0cmFuc2NyaXB0aW9uIG1vZGVscywgc3BlZWNoIG1vZGVscywgYW5kIGFuIG9wdGlvbmFsIGZhbGxiYWNrIHByb3ZpZGVyLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gVGhlIG9wdGlvbnMgZm9yIGNyZWF0aW5nIHRoZSBjdXN0b20gcHJvdmlkZXIuXG4gKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIExhbmd1YWdlTW9kZWw+fSBbb3B0aW9ucy5sYW5ndWFnZU1vZGVsc10gLSBBIHJlY29yZCBvZiBsYW5ndWFnZSBtb2RlbHMsIHdoZXJlIGtleXMgYXJlIG1vZGVsIElEcyBhbmQgdmFsdWVzIGFyZSBMYW5ndWFnZU1vZGVsIGluc3RhbmNlcy5cbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgRW1iZWRkaW5nTW9kZWw8c3RyaW5nPj59IFtvcHRpb25zLnRleHRFbWJlZGRpbmdNb2RlbHNdIC0gQSByZWNvcmQgb2YgdGV4dCBlbWJlZGRpbmcgbW9kZWxzLCB3aGVyZSBrZXlzIGFyZSBtb2RlbCBJRHMgYW5kIHZhbHVlcyBhcmUgRW1iZWRkaW5nTW9kZWw8c3RyaW5nPiBpbnN0YW5jZXMuXG4gKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIEltYWdlTW9kZWw+fSBbb3B0aW9ucy5pbWFnZU1vZGVsc10gLSBBIHJlY29yZCBvZiBpbWFnZSBtb2RlbHMsIHdoZXJlIGtleXMgYXJlIG1vZGVsIElEcyBhbmQgdmFsdWVzIGFyZSBJbWFnZU1vZGVsIGluc3RhbmNlcy5cbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgVHJhbnNjcmlwdGlvbk1vZGVsPn0gW29wdGlvbnMudHJhbnNjcmlwdGlvbk1vZGVsc10gLSBBIHJlY29yZCBvZiB0cmFuc2NyaXB0aW9uIG1vZGVscywgd2hlcmUga2V5cyBhcmUgbW9kZWwgSURzIGFuZCB2YWx1ZXMgYXJlIFRyYW5zY3JpcHRpb25Nb2RlbCBpbnN0YW5jZXMuXG4gKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIFNwZWVjaE1vZGVsPn0gW29wdGlvbnMuc3BlZWNoTW9kZWxzXSAtIEEgcmVjb3JkIG9mIHNwZWVjaCBtb2RlbHMsIHdoZXJlIGtleXMgYXJlIG1vZGVsIElEcyBhbmQgdmFsdWVzIGFyZSBTcGVlY2hNb2RlbCBpbnN0YW5jZXMuXG4gKiBAcGFyYW0ge1Byb3ZpZGVyfSBbb3B0aW9ucy5mYWxsYmFja1Byb3ZpZGVyXSAtIEFuIG9wdGlvbmFsIGZhbGxiYWNrIHByb3ZpZGVyIHRvIHVzZSB3aGVuIGEgcmVxdWVzdGVkIG1vZGVsIGlzIG5vdCBmb3VuZCBpbiB0aGUgY3VzdG9tIHByb3ZpZGVyLlxuICogQHJldHVybnMge1Byb3ZpZGVyfSBBIFByb3ZpZGVyIG9iamVjdCB3aXRoIGxhbmd1YWdlTW9kZWwsIHRleHRFbWJlZGRpbmdNb2RlbCwgaW1hZ2VNb2RlbCwgdHJhbnNjcmlwdGlvbk1vZGVsLCBhbmQgc3BlZWNoTW9kZWwgbWV0aG9kcy5cbiAqXG4gKiBAdGhyb3dzIHtOb1N1Y2hNb2RlbEVycm9yfSBUaHJvd3Mgd2hlbiBhIHJlcXVlc3RlZCBtb2RlbCBpcyBub3QgZm91bmQgYW5kIG5vIGZhbGxiYWNrIHByb3ZpZGVyIGlzIGF2YWlsYWJsZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGN1c3RvbVByb3ZpZGVyPFxuICBMQU5HVUFHRV9NT0RFTFMgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBMYW5ndWFnZU1vZGVsVjI+LFxuICBFTUJFRERJTkdfTU9ERUxTIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgRW1iZWRkaW5nTW9kZWxWMjxzdHJpbmc+PixcbiAgSU1BR0VfTU9ERUxTIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgSW1hZ2VNb2RlbFYyPixcbiAgVFJBTlNDUklQVElPTl9NT0RFTFMgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBUcmFuc2NyaXB0aW9uTW9kZWxWMj4sXG4gIFNQRUVDSF9NT0RFTFMgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBTcGVlY2hNb2RlbFYyPixcbj4oe1xuICBsYW5ndWFnZU1vZGVscyxcbiAgdGV4dEVtYmVkZGluZ01vZGVscyxcbiAgaW1hZ2VNb2RlbHMsXG4gIHRyYW5zY3JpcHRpb25Nb2RlbHMsXG4gIHNwZWVjaE1vZGVscyxcbiAgZmFsbGJhY2tQcm92aWRlcixcbn06IHtcbiAgbGFuZ3VhZ2VNb2RlbHM/OiBMQU5HVUFHRV9NT0RFTFM7XG4gIHRleHRFbWJlZGRpbmdNb2RlbHM/OiBFTUJFRERJTkdfTU9ERUxTO1xuICBpbWFnZU1vZGVscz86IElNQUdFX01PREVMUztcbiAgdHJhbnNjcmlwdGlvbk1vZGVscz86IFRSQU5TQ1JJUFRJT05fTU9ERUxTO1xuICBzcGVlY2hNb2RlbHM/OiBTUEVFQ0hfTU9ERUxTO1xuICBmYWxsYmFja1Byb3ZpZGVyPzogUHJvdmlkZXJWMjtcbn0pOiBQcm92aWRlclYyICYge1xuICBsYW5ndWFnZU1vZGVsKG1vZGVsSWQ6IEV4dHJhY3RNb2RlbElkPExBTkdVQUdFX01PREVMUz4pOiBMYW5ndWFnZU1vZGVsVjI7XG4gIHRleHRFbWJlZGRpbmdNb2RlbChcbiAgICBtb2RlbElkOiBFeHRyYWN0TW9kZWxJZDxFTUJFRERJTkdfTU9ERUxTPixcbiAgKTogRW1iZWRkaW5nTW9kZWxWMjxzdHJpbmc+O1xuICBpbWFnZU1vZGVsKG1vZGVsSWQ6IEV4dHJhY3RNb2RlbElkPElNQUdFX01PREVMUz4pOiBJbWFnZU1vZGVsVjI7XG4gIHRyYW5zY3JpcHRpb25Nb2RlbChcbiAgICBtb2RlbElkOiBFeHRyYWN0TW9kZWxJZDxUUkFOU0NSSVBUSU9OX01PREVMUz4sXG4gICk6IFRyYW5zY3JpcHRpb25Nb2RlbFYyO1xuICBzcGVlY2hNb2RlbChtb2RlbElkOiBFeHRyYWN0TW9kZWxJZDxTUEVFQ0hfTU9ERUxTPik6IFNwZWVjaE1vZGVsVjI7XG59IHtcbiAgcmV0dXJuIHtcbiAgICBsYW5ndWFnZU1vZGVsKG1vZGVsSWQ6IEV4dHJhY3RNb2RlbElkPExBTkdVQUdFX01PREVMUz4pOiBMYW5ndWFnZU1vZGVsVjIge1xuICAgICAgaWYgKGxhbmd1YWdlTW9kZWxzICE9IG51bGwgJiYgbW9kZWxJZCBpbiBsYW5ndWFnZU1vZGVscykge1xuICAgICAgICByZXR1cm4gbGFuZ3VhZ2VNb2RlbHNbbW9kZWxJZF07XG4gICAgICB9XG5cbiAgICAgIGlmIChmYWxsYmFja1Byb3ZpZGVyKSB7XG4gICAgICAgIHJldHVybiBmYWxsYmFja1Byb3ZpZGVyLmxhbmd1YWdlTW9kZWwobW9kZWxJZCk7XG4gICAgICB9XG5cbiAgICAgIHRocm93IG5ldyBOb1N1Y2hNb2RlbEVycm9yKHsgbW9kZWxJZCwgbW9kZWxUeXBlOiAnbGFuZ3VhZ2VNb2RlbCcgfSk7XG4gICAgfSxcblxuICAgIHRleHRFbWJlZGRpbmdNb2RlbChcbiAgICAgIG1vZGVsSWQ6IEV4dHJhY3RNb2RlbElkPEVNQkVERElOR19NT0RFTFM+LFxuICAgICk6IEVtYmVkZGluZ01vZGVsVjI8c3RyaW5nPiB7XG4gICAgICBpZiAodGV4dEVtYmVkZGluZ01vZGVscyAhPSBudWxsICYmIG1vZGVsSWQgaW4gdGV4dEVtYmVkZGluZ01vZGVscykge1xuICAgICAgICByZXR1cm4gdGV4dEVtYmVkZGluZ01vZGVsc1ttb2RlbElkXTtcbiAgICAgIH1cblxuICAgICAgaWYgKGZhbGxiYWNrUHJvdmlkZXIpIHtcbiAgICAgICAgcmV0dXJuIGZhbGxiYWNrUHJvdmlkZXIudGV4dEVtYmVkZGluZ01vZGVsKG1vZGVsSWQpO1xuICAgICAgfVxuXG4gICAgICB0aHJvdyBuZXcgTm9TdWNoTW9kZWxFcnJvcih7IG1vZGVsSWQsIG1vZGVsVHlwZTogJ3RleHRFbWJlZGRpbmdNb2RlbCcgfSk7XG4gICAgfSxcblxuICAgIGltYWdlTW9kZWwobW9kZWxJZDogRXh0cmFjdE1vZGVsSWQ8SU1BR0VfTU9ERUxTPik6IEltYWdlTW9kZWxWMiB7XG4gICAgICBpZiAoaW1hZ2VNb2RlbHMgIT0gbnVsbCAmJiBtb2RlbElkIGluIGltYWdlTW9kZWxzKSB7XG4gICAgICAgIHJldHVybiBpbWFnZU1vZGVsc1ttb2RlbElkXTtcbiAgICAgIH1cblxuICAgICAgaWYgKGZhbGxiYWNrUHJvdmlkZXI/LmltYWdlTW9kZWwpIHtcbiAgICAgICAgcmV0dXJuIGZhbGxiYWNrUHJvdmlkZXIuaW1hZ2VNb2RlbChtb2RlbElkKTtcbiAgICAgIH1cblxuICAgICAgdGhyb3cgbmV3IE5vU3VjaE1vZGVsRXJyb3IoeyBtb2RlbElkLCBtb2RlbFR5cGU6ICdpbWFnZU1vZGVsJyB9KTtcbiAgICB9LFxuXG4gICAgdHJhbnNjcmlwdGlvbk1vZGVsKFxuICAgICAgbW9kZWxJZDogRXh0cmFjdE1vZGVsSWQ8VFJBTlNDUklQVElPTl9NT0RFTFM+LFxuICAgICk6IFRyYW5zY3JpcHRpb25Nb2RlbFYyIHtcbiAgICAgIGlmICh0cmFuc2NyaXB0aW9uTW9kZWxzICE9IG51bGwgJiYgbW9kZWxJZCBpbiB0cmFuc2NyaXB0aW9uTW9kZWxzKSB7XG4gICAgICAgIHJldHVybiB0cmFuc2NyaXB0aW9uTW9kZWxzW21vZGVsSWRdO1xuICAgICAgfVxuXG4gICAgICBpZiAoZmFsbGJhY2tQcm92aWRlcj8udHJhbnNjcmlwdGlvbk1vZGVsKSB7XG4gICAgICAgIHJldHVybiBmYWxsYmFja1Byb3ZpZGVyLnRyYW5zY3JpcHRpb25Nb2RlbChtb2RlbElkKTtcbiAgICAgIH1cblxuICAgICAgdGhyb3cgbmV3IE5vU3VjaE1vZGVsRXJyb3IoeyBtb2RlbElkLCBtb2RlbFR5cGU6ICd0cmFuc2NyaXB0aW9uTW9kZWwnIH0pO1xuICAgIH0sXG5cbiAgICBzcGVlY2hNb2RlbChtb2RlbElkOiBFeHRyYWN0TW9kZWxJZDxTUEVFQ0hfTU9ERUxTPik6IFNwZWVjaE1vZGVsVjIge1xuICAgICAgaWYgKHNwZWVjaE1vZGVscyAhPSBudWxsICYmIG1vZGVsSWQgaW4gc3BlZWNoTW9kZWxzKSB7XG4gICAgICAgIHJldHVybiBzcGVlY2hNb2RlbHNbbW9kZWxJZF07XG4gICAgICB9XG5cbiAgICAgIGlmIChmYWxsYmFja1Byb3ZpZGVyPy5zcGVlY2hNb2RlbCkge1xuICAgICAgICByZXR1cm4gZmFsbGJhY2tQcm92aWRlci5zcGVlY2hNb2RlbChtb2RlbElkKTtcbiAgICAgIH1cblxuICAgICAgdGhyb3cgbmV3IE5vU3VjaE1vZGVsRXJyb3IoeyBtb2RlbElkLCBtb2RlbFR5cGU6ICdzcGVlY2hNb2RlbCcgfSk7XG4gICAgfSxcbiAgfTtcbn1cblxuLyoqXG4gKiBAZGVwcmVjYXRlZCBVc2UgYGN1c3RvbVByb3ZpZGVyYCBpbnN0ZWFkLlxuICovXG5leHBvcnQgY29uc3QgZXhwZXJpbWVudGFsX2N1c3RvbVByb3ZpZGVyID0gY3VzdG9tUHJvdmlkZXI7XG5cbnR5cGUgRXh0cmFjdE1vZGVsSWQ8TU9ERUxTIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4+ID0gRXh0cmFjdDxcbiAga2V5b2YgTU9ERUxTLFxuICBzdHJpbmdcbj47XG4iLCAiaW1wb3J0IHsgQUlTREtFcnJvciwgTm9TdWNoTW9kZWxFcnJvciB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuXG5jb25zdCBuYW1lID0gJ0FJX05vU3VjaFByb3ZpZGVyRXJyb3InO1xuY29uc3QgbWFya2VyID0gYHZlcmNlbC5haS5lcnJvci4ke25hbWV9YDtcbmNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IobWFya2VyKTtcblxuZXhwb3J0IGNsYXNzIE5vU3VjaFByb3ZpZGVyRXJyb3IgZXh0ZW5kcyBOb1N1Y2hNb2RlbEVycm9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBbc3ltYm9sXSA9IHRydWU7IC8vIHVzZWQgaW4gaXNJbnN0YW5jZVxuXG4gIHJlYWRvbmx5IHByb3ZpZGVySWQ6IHN0cmluZztcbiAgcmVhZG9ubHkgYXZhaWxhYmxlUHJvdmlkZXJzOiBzdHJpbmdbXTtcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgbW9kZWxJZCxcbiAgICBtb2RlbFR5cGUsXG4gICAgcHJvdmlkZXJJZCxcbiAgICBhdmFpbGFibGVQcm92aWRlcnMsXG4gICAgbWVzc2FnZSA9IGBObyBzdWNoIHByb3ZpZGVyOiAke3Byb3ZpZGVySWR9IChhdmFpbGFibGUgcHJvdmlkZXJzOiAke2F2YWlsYWJsZVByb3ZpZGVycy5qb2luKCl9KWAsXG4gIH06IHtcbiAgICBtb2RlbElkOiBzdHJpbmc7XG4gICAgbW9kZWxUeXBlOlxuICAgICAgfCAnbGFuZ3VhZ2VNb2RlbCdcbiAgICAgIHwgJ3RleHRFbWJlZGRpbmdNb2RlbCdcbiAgICAgIHwgJ2ltYWdlTW9kZWwnXG4gICAgICB8ICd0cmFuc2NyaXB0aW9uTW9kZWwnXG4gICAgICB8ICdzcGVlY2hNb2RlbCc7XG4gICAgcHJvdmlkZXJJZDogc3RyaW5nO1xuICAgIGF2YWlsYWJsZVByb3ZpZGVyczogc3RyaW5nW107XG4gICAgbWVzc2FnZT86IHN0cmluZztcbiAgfSkge1xuICAgIHN1cGVyKHsgZXJyb3JOYW1lOiBuYW1lLCBtb2RlbElkLCBtb2RlbFR5cGUsIG1lc3NhZ2UgfSk7XG5cbiAgICB0aGlzLnByb3ZpZGVySWQgPSBwcm92aWRlcklkO1xuICAgIHRoaXMuYXZhaWxhYmxlUHJvdmlkZXJzID0gYXZhaWxhYmxlUHJvdmlkZXJzO1xuICB9XG5cbiAgc3RhdGljIGlzSW5zdGFuY2UoZXJyb3I6IHVua25vd24pOiBlcnJvciBpcyBOb1N1Y2hQcm92aWRlckVycm9yIHtcbiAgICByZXR1cm4gQUlTREtFcnJvci5oYXNNYXJrZXIoZXJyb3IsIG1hcmtlcik7XG4gIH1cbn1cbiIsICJpbXBvcnQge1xuICBFbWJlZGRpbmdNb2RlbFYyLFxuICBJbWFnZU1vZGVsVjIsXG4gIExhbmd1YWdlTW9kZWxWMixcbiAgTm9TdWNoTW9kZWxFcnJvcixcbiAgUHJvdmlkZXJWMixcbiAgU3BlZWNoTW9kZWxWMixcbiAgVHJhbnNjcmlwdGlvbk1vZGVsVjIsXG59IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgd3JhcExhbmd1YWdlTW9kZWwgfSBmcm9tICcuLi9taWRkbGV3YXJlL3dyYXAtbGFuZ3VhZ2UtbW9kZWwnO1xuaW1wb3J0IHsgTGFuZ3VhZ2VNb2RlbE1pZGRsZXdhcmUgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgeyBOb1N1Y2hQcm92aWRlckVycm9yIH0gZnJvbSAnLi9uby1zdWNoLXByb3ZpZGVyLWVycm9yJztcblxudHlwZSBFeHRyYWN0TGl0ZXJhbFVuaW9uPFQ+ID0gVCBleHRlbmRzIHN0cmluZ1xuICA/IHN0cmluZyBleHRlbmRzIFRcbiAgICA/IG5ldmVyXG4gICAgOiBUXG4gIDogbmV2ZXI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUHJvdmlkZXJSZWdpc3RyeVByb3ZpZGVyPFxuICBQUk9WSURFUlMgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBQcm92aWRlclYyPiA9IFJlY29yZDxzdHJpbmcsIFByb3ZpZGVyVjI+LFxuICBTRVBBUkFUT1IgZXh0ZW5kcyBzdHJpbmcgPSAnOicsXG4+IHtcbiAgbGFuZ3VhZ2VNb2RlbDxLRVkgZXh0ZW5kcyBrZXlvZiBQUk9WSURFUlM+KFxuICAgIGlkOiBLRVkgZXh0ZW5kcyBzdHJpbmdcbiAgICAgID8gYCR7S0VZICYgc3RyaW5nfSR7U0VQQVJBVE9SfSR7RXh0cmFjdExpdGVyYWxVbmlvbjxQYXJhbWV0ZXJzPE5vbk51bGxhYmxlPFBST1ZJREVSU1tLRVldWydsYW5ndWFnZU1vZGVsJ10+PlswXT59YFxuICAgICAgOiBuZXZlcixcbiAgKTogTGFuZ3VhZ2VNb2RlbFYyO1xuICBsYW5ndWFnZU1vZGVsPEtFWSBleHRlbmRzIGtleW9mIFBST1ZJREVSUz4oXG4gICAgaWQ6IEtFWSBleHRlbmRzIHN0cmluZyA/IGAke0tFWSAmIHN0cmluZ30ke1NFUEFSQVRPUn0ke3N0cmluZ31gIDogbmV2ZXIsXG4gICk6IExhbmd1YWdlTW9kZWxWMjtcblxuICB0ZXh0RW1iZWRkaW5nTW9kZWw8S0VZIGV4dGVuZHMga2V5b2YgUFJPVklERVJTPihcbiAgICBpZDogS0VZIGV4dGVuZHMgc3RyaW5nXG4gICAgICA/IGAke0tFWSAmIHN0cmluZ30ke1NFUEFSQVRPUn0ke0V4dHJhY3RMaXRlcmFsVW5pb248UGFyYW1ldGVyczxOb25OdWxsYWJsZTxQUk9WSURFUlNbS0VZXVsndGV4dEVtYmVkZGluZ01vZGVsJ10+PlswXT59YFxuICAgICAgOiBuZXZlcixcbiAgKTogRW1iZWRkaW5nTW9kZWxWMjxzdHJpbmc+O1xuICB0ZXh0RW1iZWRkaW5nTW9kZWw8S0VZIGV4dGVuZHMga2V5b2YgUFJPVklERVJTPihcbiAgICBpZDogS0VZIGV4dGVuZHMgc3RyaW5nID8gYCR7S0VZICYgc3RyaW5nfSR7U0VQQVJBVE9SfSR7c3RyaW5nfWAgOiBuZXZlcixcbiAgKTogRW1iZWRkaW5nTW9kZWxWMjxzdHJpbmc+O1xuXG4gIGltYWdlTW9kZWw8S0VZIGV4dGVuZHMga2V5b2YgUFJPVklERVJTPihcbiAgICBpZDogS0VZIGV4dGVuZHMgc3RyaW5nXG4gICAgICA/IGAke0tFWSAmIHN0cmluZ30ke1NFUEFSQVRPUn0ke0V4dHJhY3RMaXRlcmFsVW5pb248UGFyYW1ldGVyczxOb25OdWxsYWJsZTxQUk9WSURFUlNbS0VZXVsnaW1hZ2VNb2RlbCddPj5bMF0+fWBcbiAgICAgIDogbmV2ZXIsXG4gICk6IEltYWdlTW9kZWxWMjtcbiAgaW1hZ2VNb2RlbDxLRVkgZXh0ZW5kcyBrZXlvZiBQUk9WSURFUlM+KFxuICAgIGlkOiBLRVkgZXh0ZW5kcyBzdHJpbmcgPyBgJHtLRVkgJiBzdHJpbmd9JHtTRVBBUkFUT1J9JHtzdHJpbmd9YCA6IG5ldmVyLFxuICApOiBJbWFnZU1vZGVsVjI7XG5cbiAgdHJhbnNjcmlwdGlvbk1vZGVsPEtFWSBleHRlbmRzIGtleW9mIFBST1ZJREVSUz4oXG4gICAgaWQ6IEtFWSBleHRlbmRzIHN0cmluZ1xuICAgICAgPyBgJHtLRVkgJiBzdHJpbmd9JHtTRVBBUkFUT1J9JHtFeHRyYWN0TGl0ZXJhbFVuaW9uPFBhcmFtZXRlcnM8Tm9uTnVsbGFibGU8UFJPVklERVJTW0tFWV1bJ3RyYW5zY3JpcHRpb25Nb2RlbCddPj5bMF0+fWBcbiAgICAgIDogbmV2ZXIsXG4gICk6IFRyYW5zY3JpcHRpb25Nb2RlbFYyO1xuICB0cmFuc2NyaXB0aW9uTW9kZWw8S0VZIGV4dGVuZHMga2V5b2YgUFJPVklERVJTPihcbiAgICBpZDogS0VZIGV4dGVuZHMgc3RyaW5nID8gYCR7S0VZICYgc3RyaW5nfSR7U0VQQVJBVE9SfSR7c3RyaW5nfWAgOiBuZXZlcixcbiAgKTogVHJhbnNjcmlwdGlvbk1vZGVsVjI7XG5cbiAgc3BlZWNoTW9kZWw8S0VZIGV4dGVuZHMga2V5b2YgUFJPVklERVJTPihcbiAgICBpZDogS0VZIGV4dGVuZHMgc3RyaW5nXG4gICAgICA/IGAke0tFWSAmIHN0cmluZ30ke1NFUEFSQVRPUn0ke0V4dHJhY3RMaXRlcmFsVW5pb248UGFyYW1ldGVyczxOb25OdWxsYWJsZTxQUk9WSURFUlNbS0VZXVsnc3BlZWNoTW9kZWwnXT4+WzBdPn1gXG4gICAgICA6IG5ldmVyLFxuICApOiBTcGVlY2hNb2RlbFYyO1xuICBzcGVlY2hNb2RlbDxLRVkgZXh0ZW5kcyBrZXlvZiBQUk9WSURFUlM+KFxuICAgIGlkOiBLRVkgZXh0ZW5kcyBzdHJpbmcgPyBgJHtLRVkgJiBzdHJpbmd9JHtTRVBBUkFUT1J9JHtzdHJpbmd9YCA6IG5ldmVyLFxuICApOiBTcGVlY2hNb2RlbFYyO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSByZWdpc3RyeSBmb3IgdGhlIGdpdmVuIHByb3ZpZGVycyB3aXRoIG9wdGlvbmFsIG1pZGRsZXdhcmUgZnVuY3Rpb25hbGl0eS5cbiAqIFRoaXMgZnVuY3Rpb24gYWxsb3dzIHlvdSB0byByZWdpc3RlciBtdWx0aXBsZSBwcm92aWRlcnMgYW5kIG9wdGlvbmFsbHkgYXBwbHkgbWlkZGxld2FyZVxuICogdG8gYWxsIGxhbmd1YWdlIG1vZGVscyBmcm9tIHRoZSByZWdpc3RyeSwgZW5hYmxpbmcgeW91IHRvIHRyYW5zZm9ybSBwYXJhbWV0ZXJzLCB3cmFwIGdlbmVyYXRlXG4gKiBvcGVyYXRpb25zLCBhbmQgd3JhcCBzdHJlYW0gb3BlcmF0aW9ucyBmb3IgZXZlcnkgbGFuZ3VhZ2UgbW9kZWwgYWNjZXNzZWQgdGhyb3VnaCB0aGUgcmVnaXN0cnkuXG4gKlxuICogQHBhcmFtIHByb3ZpZGVycyAtIEEgcmVjb3JkIG9mIHByb3ZpZGVyIGluc3RhbmNlcyB0byBiZSByZWdpc3RlcmVkIGluIHRoZSByZWdpc3RyeS5cbiAqIEBwYXJhbSBvcHRpb25zIC0gQ29uZmlndXJhdGlvbiBvcHRpb25zIGZvciB0aGUgcHJvdmlkZXIgcmVnaXN0cnkuXG4gKiBAcGFyYW0gb3B0aW9ucy5zZXBhcmF0b3IgLSBUaGUgc2VwYXJhdG9yIHVzZWQgYmV0d2VlbiBwcm92aWRlciBJRCBhbmQgbW9kZWwgSUQgaW4gdGhlIGNvbWJpbmVkIGlkZW50aWZpZXIuIERlZmF1bHRzIHRvICc6Jy5cbiAqIEBwYXJhbSBvcHRpb25zLmxhbmd1YWdlTW9kZWxNaWRkbGV3YXJlIC0gT3B0aW9uYWwgbWlkZGxld2FyZSB0byBiZSBhcHBsaWVkIHRvIGFsbCBsYW5ndWFnZSBtb2RlbHMgZnJvbSB0aGUgcmVnaXN0cnkuIFdoZW4gbXVsdGlwbGUgbWlkZGxld2FyZXMgYXJlIHByb3ZpZGVkLCB0aGUgZmlyc3QgbWlkZGxld2FyZSB3aWxsIHRyYW5zZm9ybSB0aGUgaW5wdXQgZmlyc3QsIGFuZCB0aGUgbGFzdCBtaWRkbGV3YXJlIHdpbGwgYmUgd3JhcHBlZCBkaXJlY3RseSBhcm91bmQgdGhlIG1vZGVsLlxuICogQHJldHVybnMgQSBuZXcgUHJvdmlkZXJSZWdpc3RyeVByb3ZpZGVyIGluc3RhbmNlIHRoYXQgcHJvdmlkZXMgYWNjZXNzIHRvIGFsbCByZWdpc3RlcmVkIHByb3ZpZGVycyB3aXRoIG9wdGlvbmFsIG1pZGRsZXdhcmUgYXBwbGllZCB0byBsYW5ndWFnZSBtb2RlbHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVQcm92aWRlclJlZ2lzdHJ5PFxuICBQUk9WSURFUlMgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBQcm92aWRlclYyPixcbiAgU0VQQVJBVE9SIGV4dGVuZHMgc3RyaW5nID0gJzonLFxuPihcbiAgcHJvdmlkZXJzOiBQUk9WSURFUlMsXG4gIHtcbiAgICBzZXBhcmF0b3IgPSAnOicgYXMgU0VQQVJBVE9SLFxuICAgIGxhbmd1YWdlTW9kZWxNaWRkbGV3YXJlLFxuICB9OiB7XG4gICAgc2VwYXJhdG9yPzogU0VQQVJBVE9SO1xuICAgIGxhbmd1YWdlTW9kZWxNaWRkbGV3YXJlPzpcbiAgICAgIHwgTGFuZ3VhZ2VNb2RlbE1pZGRsZXdhcmVcbiAgICAgIHwgTGFuZ3VhZ2VNb2RlbE1pZGRsZXdhcmVbXTtcbiAgfSA9IHt9LFxuKTogUHJvdmlkZXJSZWdpc3RyeVByb3ZpZGVyPFBST1ZJREVSUywgU0VQQVJBVE9SPiB7XG4gIGNvbnN0IHJlZ2lzdHJ5ID0gbmV3IERlZmF1bHRQcm92aWRlclJlZ2lzdHJ5PFBST1ZJREVSUywgU0VQQVJBVE9SPih7XG4gICAgc2VwYXJhdG9yLFxuICAgIGxhbmd1YWdlTW9kZWxNaWRkbGV3YXJlLFxuICB9KTtcblxuICBmb3IgKGNvbnN0IFtpZCwgcHJvdmlkZXJdIG9mIE9iamVjdC5lbnRyaWVzKHByb3ZpZGVycykpIHtcbiAgICByZWdpc3RyeS5yZWdpc3RlclByb3ZpZGVyKHsgaWQsIHByb3ZpZGVyIH0gYXMge1xuICAgICAgaWQ6IGtleW9mIFBST1ZJREVSUztcbiAgICAgIHByb3ZpZGVyOiBQUk9WSURFUlNba2V5b2YgUFJPVklERVJTXTtcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiByZWdpc3RyeTtcbn1cblxuLyoqXG4gKiBAZGVwcmVjYXRlZCBVc2UgYGNyZWF0ZVByb3ZpZGVyUmVnaXN0cnlgIGluc3RlYWQuXG4gKi9cbmV4cG9ydCBjb25zdCBleHBlcmltZW50YWxfY3JlYXRlUHJvdmlkZXJSZWdpc3RyeSA9IGNyZWF0ZVByb3ZpZGVyUmVnaXN0cnk7XG5cbmNsYXNzIERlZmF1bHRQcm92aWRlclJlZ2lzdHJ5PFxuICBQUk9WSURFUlMgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBQcm92aWRlclYyPixcbiAgU0VQQVJBVE9SIGV4dGVuZHMgc3RyaW5nLFxuPiBpbXBsZW1lbnRzIFByb3ZpZGVyUmVnaXN0cnlQcm92aWRlcjxQUk9WSURFUlMsIFNFUEFSQVRPUj5cbntcbiAgcHJpdmF0ZSBwcm92aWRlcnM6IFBST1ZJREVSUyA9IHt9IGFzIFBST1ZJREVSUztcbiAgcHJpdmF0ZSBzZXBhcmF0b3I6IFNFUEFSQVRPUjtcbiAgcHJpdmF0ZSBsYW5ndWFnZU1vZGVsTWlkZGxld2FyZT86XG4gICAgfCBMYW5ndWFnZU1vZGVsTWlkZGxld2FyZVxuICAgIHwgTGFuZ3VhZ2VNb2RlbE1pZGRsZXdhcmVbXTtcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgc2VwYXJhdG9yLFxuICAgIGxhbmd1YWdlTW9kZWxNaWRkbGV3YXJlLFxuICB9OiB7XG4gICAgc2VwYXJhdG9yOiBTRVBBUkFUT1I7XG4gICAgbGFuZ3VhZ2VNb2RlbE1pZGRsZXdhcmU/OlxuICAgICAgfCBMYW5ndWFnZU1vZGVsTWlkZGxld2FyZVxuICAgICAgfCBMYW5ndWFnZU1vZGVsTWlkZGxld2FyZVtdO1xuICB9KSB7XG4gICAgdGhpcy5zZXBhcmF0b3IgPSBzZXBhcmF0b3I7XG4gICAgdGhpcy5sYW5ndWFnZU1vZGVsTWlkZGxld2FyZSA9IGxhbmd1YWdlTW9kZWxNaWRkbGV3YXJlO1xuICB9XG5cbiAgcmVnaXN0ZXJQcm92aWRlcjxLIGV4dGVuZHMga2V5b2YgUFJPVklERVJTPih7XG4gICAgaWQsXG4gICAgcHJvdmlkZXIsXG4gIH06IHtcbiAgICBpZDogSztcbiAgICBwcm92aWRlcjogUFJPVklERVJTW0tdO1xuICB9KTogdm9pZCB7XG4gICAgdGhpcy5wcm92aWRlcnNbaWRdID0gcHJvdmlkZXI7XG4gIH1cblxuICBwcml2YXRlIGdldFByb3ZpZGVyKFxuICAgIGlkOiBzdHJpbmcsXG4gICAgbW9kZWxUeXBlOlxuICAgICAgfCAnbGFuZ3VhZ2VNb2RlbCdcbiAgICAgIHwgJ3RleHRFbWJlZGRpbmdNb2RlbCdcbiAgICAgIHwgJ2ltYWdlTW9kZWwnXG4gICAgICB8ICd0cmFuc2NyaXB0aW9uTW9kZWwnXG4gICAgICB8ICdzcGVlY2hNb2RlbCcsXG4gICk6IFByb3ZpZGVyVjIge1xuICAgIGNvbnN0IHByb3ZpZGVyID0gdGhpcy5wcm92aWRlcnNbaWQgYXMga2V5b2YgUFJPVklERVJTXTtcblxuICAgIGlmIChwcm92aWRlciA9PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgTm9TdWNoUHJvdmlkZXJFcnJvcih7XG4gICAgICAgIG1vZGVsSWQ6IGlkLFxuICAgICAgICBtb2RlbFR5cGUsXG4gICAgICAgIHByb3ZpZGVySWQ6IGlkLFxuICAgICAgICBhdmFpbGFibGVQcm92aWRlcnM6IE9iamVjdC5rZXlzKHRoaXMucHJvdmlkZXJzKSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBwcm92aWRlcjtcbiAgfVxuXG4gIHByaXZhdGUgc3BsaXRJZChcbiAgICBpZDogc3RyaW5nLFxuICAgIG1vZGVsVHlwZTpcbiAgICAgIHwgJ2xhbmd1YWdlTW9kZWwnXG4gICAgICB8ICd0ZXh0RW1iZWRkaW5nTW9kZWwnXG4gICAgICB8ICdpbWFnZU1vZGVsJ1xuICAgICAgfCAndHJhbnNjcmlwdGlvbk1vZGVsJ1xuICAgICAgfCAnc3BlZWNoTW9kZWwnLFxuICApOiBbc3RyaW5nLCBzdHJpbmddIHtcbiAgICBjb25zdCBpbmRleCA9IGlkLmluZGV4T2YodGhpcy5zZXBhcmF0b3IpO1xuXG4gICAgaWYgKGluZGV4ID09PSAtMSkge1xuICAgICAgdGhyb3cgbmV3IE5vU3VjaE1vZGVsRXJyb3Ioe1xuICAgICAgICBtb2RlbElkOiBpZCxcbiAgICAgICAgbW9kZWxUeXBlLFxuICAgICAgICBtZXNzYWdlOlxuICAgICAgICAgIGBJbnZhbGlkICR7bW9kZWxUeXBlfSBpZCBmb3IgcmVnaXN0cnk6ICR7aWR9IGAgK1xuICAgICAgICAgIGAobXVzdCBiZSBpbiB0aGUgZm9ybWF0IFwicHJvdmlkZXJJZCR7dGhpcy5zZXBhcmF0b3J9bW9kZWxJZFwiKWAsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gW2lkLnNsaWNlKDAsIGluZGV4KSwgaWQuc2xpY2UoaW5kZXggKyB0aGlzLnNlcGFyYXRvci5sZW5ndGgpXTtcbiAgfVxuXG4gIGxhbmd1YWdlTW9kZWw8S0VZIGV4dGVuZHMga2V5b2YgUFJPVklERVJTPihcbiAgICBpZDogYCR7S0VZICYgc3RyaW5nfSR7U0VQQVJBVE9SfSR7c3RyaW5nfWAsXG4gICk6IExhbmd1YWdlTW9kZWxWMiB7XG4gICAgY29uc3QgW3Byb3ZpZGVySWQsIG1vZGVsSWRdID0gdGhpcy5zcGxpdElkKGlkLCAnbGFuZ3VhZ2VNb2RlbCcpO1xuICAgIGxldCBtb2RlbCA9IHRoaXMuZ2V0UHJvdmlkZXIocHJvdmlkZXJJZCwgJ2xhbmd1YWdlTW9kZWwnKS5sYW5ndWFnZU1vZGVsPy4oXG4gICAgICBtb2RlbElkLFxuICAgICk7XG5cbiAgICBpZiAobW9kZWwgPT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IE5vU3VjaE1vZGVsRXJyb3IoeyBtb2RlbElkOiBpZCwgbW9kZWxUeXBlOiAnbGFuZ3VhZ2VNb2RlbCcgfSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubGFuZ3VhZ2VNb2RlbE1pZGRsZXdhcmUgIT0gbnVsbCkge1xuICAgICAgbW9kZWwgPSB3cmFwTGFuZ3VhZ2VNb2RlbCh7XG4gICAgICAgIG1vZGVsLFxuICAgICAgICBtaWRkbGV3YXJlOiB0aGlzLmxhbmd1YWdlTW9kZWxNaWRkbGV3YXJlLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1vZGVsO1xuICB9XG5cbiAgdGV4dEVtYmVkZGluZ01vZGVsPEtFWSBleHRlbmRzIGtleW9mIFBST1ZJREVSUz4oXG4gICAgaWQ6IGAke0tFWSAmIHN0cmluZ30ke1NFUEFSQVRPUn0ke3N0cmluZ31gLFxuICApOiBFbWJlZGRpbmdNb2RlbFYyPHN0cmluZz4ge1xuICAgIGNvbnN0IFtwcm92aWRlcklkLCBtb2RlbElkXSA9IHRoaXMuc3BsaXRJZChpZCwgJ3RleHRFbWJlZGRpbmdNb2RlbCcpO1xuICAgIGNvbnN0IHByb3ZpZGVyID0gdGhpcy5nZXRQcm92aWRlcihwcm92aWRlcklkLCAndGV4dEVtYmVkZGluZ01vZGVsJyk7XG5cbiAgICBjb25zdCBtb2RlbCA9IHByb3ZpZGVyLnRleHRFbWJlZGRpbmdNb2RlbD8uKG1vZGVsSWQpO1xuXG4gICAgaWYgKG1vZGVsID09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBOb1N1Y2hNb2RlbEVycm9yKHtcbiAgICAgICAgbW9kZWxJZDogaWQsXG4gICAgICAgIG1vZGVsVHlwZTogJ3RleHRFbWJlZGRpbmdNb2RlbCcsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gbW9kZWw7XG4gIH1cblxuICBpbWFnZU1vZGVsPEtFWSBleHRlbmRzIGtleW9mIFBST1ZJREVSUz4oXG4gICAgaWQ6IGAke0tFWSAmIHN0cmluZ30ke1NFUEFSQVRPUn0ke3N0cmluZ31gLFxuICApOiBJbWFnZU1vZGVsVjIge1xuICAgIGNvbnN0IFtwcm92aWRlcklkLCBtb2RlbElkXSA9IHRoaXMuc3BsaXRJZChpZCwgJ2ltYWdlTW9kZWwnKTtcbiAgICBjb25zdCBwcm92aWRlciA9IHRoaXMuZ2V0UHJvdmlkZXIocHJvdmlkZXJJZCwgJ2ltYWdlTW9kZWwnKTtcblxuICAgIGNvbnN0IG1vZGVsID0gcHJvdmlkZXIuaW1hZ2VNb2RlbD8uKG1vZGVsSWQpO1xuXG4gICAgaWYgKG1vZGVsID09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBOb1N1Y2hNb2RlbEVycm9yKHsgbW9kZWxJZDogaWQsIG1vZGVsVHlwZTogJ2ltYWdlTW9kZWwnIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBtb2RlbDtcbiAgfVxuXG4gIHRyYW5zY3JpcHRpb25Nb2RlbDxLRVkgZXh0ZW5kcyBrZXlvZiBQUk9WSURFUlM+KFxuICAgIGlkOiBgJHtLRVkgJiBzdHJpbmd9JHtTRVBBUkFUT1J9JHtzdHJpbmd9YCxcbiAgKTogVHJhbnNjcmlwdGlvbk1vZGVsVjIge1xuICAgIGNvbnN0IFtwcm92aWRlcklkLCBtb2RlbElkXSA9IHRoaXMuc3BsaXRJZChpZCwgJ3RyYW5zY3JpcHRpb25Nb2RlbCcpO1xuICAgIGNvbnN0IHByb3ZpZGVyID0gdGhpcy5nZXRQcm92aWRlcihwcm92aWRlcklkLCAndHJhbnNjcmlwdGlvbk1vZGVsJyk7XG5cbiAgICBjb25zdCBtb2RlbCA9IHByb3ZpZGVyLnRyYW5zY3JpcHRpb25Nb2RlbD8uKG1vZGVsSWQpO1xuXG4gICAgaWYgKG1vZGVsID09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBOb1N1Y2hNb2RlbEVycm9yKHtcbiAgICAgICAgbW9kZWxJZDogaWQsXG4gICAgICAgIG1vZGVsVHlwZTogJ3RyYW5zY3JpcHRpb25Nb2RlbCcsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gbW9kZWw7XG4gIH1cblxuICBzcGVlY2hNb2RlbDxLRVkgZXh0ZW5kcyBrZXlvZiBQUk9WSURFUlM+KFxuICAgIGlkOiBgJHtLRVkgJiBzdHJpbmd9JHtTRVBBUkFUT1J9JHtzdHJpbmd9YCxcbiAgKTogU3BlZWNoTW9kZWxWMiB7XG4gICAgY29uc3QgW3Byb3ZpZGVySWQsIG1vZGVsSWRdID0gdGhpcy5zcGxpdElkKGlkLCAnc3BlZWNoTW9kZWwnKTtcbiAgICBjb25zdCBwcm92aWRlciA9IHRoaXMuZ2V0UHJvdmlkZXIocHJvdmlkZXJJZCwgJ3NwZWVjaE1vZGVsJyk7XG5cbiAgICBjb25zdCBtb2RlbCA9IHByb3ZpZGVyLnNwZWVjaE1vZGVsPy4obW9kZWxJZCk7XG5cbiAgICBpZiAobW9kZWwgPT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IE5vU3VjaE1vZGVsRXJyb3IoeyBtb2RlbElkOiBpZCwgbW9kZWxUeXBlOiAnc3BlZWNoTW9kZWwnIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBtb2RlbDtcbiAgfVxufVxuIiwgImltcG9ydCB7IEpTT05TY2hlbWE3IH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQge1xuICBkeW5hbWljVG9vbCxcbiAganNvblNjaGVtYSxcbiAgVG9vbCxcbiAgdG9vbCxcbiAgVG9vbENhbGxPcHRpb25zLFxufSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyLXV0aWxzJztcbmltcG9ydCB7IHogfSBmcm9tICd6b2QvdjQnO1xuaW1wb3J0IHsgTUNQQ2xpZW50RXJyb3IgfSBmcm9tICcuLi8uLi9lcnJvci9tY3AtY2xpZW50LWVycm9yJztcbmltcG9ydCB7XG4gIEpTT05SUENFcnJvcixcbiAgSlNPTlJQQ05vdGlmaWNhdGlvbixcbiAgSlNPTlJQQ1JlcXVlc3QsXG4gIEpTT05SUENSZXNwb25zZSxcbn0gZnJvbSAnLi9qc29uLXJwYy1tZXNzYWdlJztcbmltcG9ydCB7XG4gIGNyZWF0ZU1jcFRyYW5zcG9ydCxcbiAgaXNDdXN0b21NY3BUcmFuc3BvcnQsXG4gIE1DUFRyYW5zcG9ydCxcbiAgTUNQVHJhbnNwb3J0Q29uZmlnLFxufSBmcm9tICcuL21jcC10cmFuc3BvcnQnO1xuaW1wb3J0IHtcbiAgQ2FsbFRvb2xSZXN1bHQsXG4gIENhbGxUb29sUmVzdWx0U2NoZW1hLFxuICBDb25maWd1cmF0aW9uIGFzIENsaWVudENvbmZpZ3VyYXRpb24sXG4gIEluaXRpYWxpemVSZXN1bHRTY2hlbWEsXG4gIExBVEVTVF9QUk9UT0NPTF9WRVJTSU9OLFxuICBMaXN0VG9vbHNSZXN1bHQsXG4gIExpc3RUb29sc1Jlc3VsdFNjaGVtYSxcbiAgTWNwVG9vbFNldCxcbiAgTm90aWZpY2F0aW9uLFxuICBQYWdpbmF0ZWRSZXF1ZXN0LFxuICBSZXF1ZXN0LFxuICBSZXF1ZXN0T3B0aW9ucyxcbiAgU2VydmVyQ2FwYWJpbGl0aWVzLFxuICBTVVBQT1JURURfUFJPVE9DT0xfVkVSU0lPTlMsXG4gIFRvb2xTY2hlbWFzLFxufSBmcm9tICcuL3R5cGVzJztcblxuY29uc3QgQ0xJRU5UX1ZFUlNJT04gPSAnMS4wLjAnO1xuXG5leHBvcnQgaW50ZXJmYWNlIE1DUENsaWVudENvbmZpZyB7XG4gIC8qKiBUcmFuc3BvcnQgY29uZmlndXJhdGlvbiBmb3IgY29ubmVjdGluZyB0byB0aGUgTUNQIHNlcnZlciAqL1xuICB0cmFuc3BvcnQ6IE1DUFRyYW5zcG9ydENvbmZpZyB8IE1DUFRyYW5zcG9ydDtcbiAgLyoqIE9wdGlvbmFsIGNhbGxiYWNrIGZvciB1bmNhdWdodCBlcnJvcnMgKi9cbiAgb25VbmNhdWdodEVycm9yPzogKGVycm9yOiB1bmtub3duKSA9PiB2b2lkO1xuICAvKiogT3B0aW9uYWwgY2xpZW50IG5hbWUsIGRlZmF1bHRzIHRvICdhaS1zZGstbWNwLWNsaWVudCcgKi9cbiAgbmFtZT86IHN0cmluZztcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZU1DUENsaWVudChcbiAgY29uZmlnOiBNQ1BDbGllbnRDb25maWcsXG4pOiBQcm9taXNlPE1DUENsaWVudD4ge1xuICBjb25zdCBjbGllbnQgPSBuZXcgRGVmYXVsdE1DUENsaWVudChjb25maWcpO1xuICBhd2FpdCBjbGllbnQuaW5pdCgpO1xuICByZXR1cm4gY2xpZW50O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE1DUENsaWVudCB7XG4gIHRvb2xzPFRPT0xfU0NIRU1BUyBleHRlbmRzIFRvb2xTY2hlbWFzID0gJ2F1dG9tYXRpYyc+KG9wdGlvbnM/OiB7XG4gICAgc2NoZW1hcz86IFRPT0xfU0NIRU1BUztcbiAgfSk6IFByb21pc2U8TWNwVG9vbFNldDxUT09MX1NDSEVNQVM+PjtcblxuICBjbG9zZTogKCkgPT4gUHJvbWlzZTx2b2lkPjtcbn1cblxuLyoqXG4gKiBBIGxpZ2h0d2VpZ2h0IE1DUCBDbGllbnQgaW1wbGVtZW50YXRpb25cbiAqXG4gKiBUaGUgcHJpbWFyeSBwdXJwb3NlIG9mIHRoaXMgY2xpZW50IGlzIHRvb2wgY29udmVyc2lvbiBiZXR3ZWVuIE1DUDw+QUkgU0RLXG4gKiBidXQgY2FuIGxhdGVyIGJlIGV4dGVuZGVkIHRvIHN1cHBvcnQgb3RoZXIgTUNQIGZlYXR1cmVzXG4gKlxuICogVG9vbCBwYXJhbWV0ZXJzIGFyZSBhdXRvbWF0aWNhbGx5IGluZmVycmVkIGZyb20gdGhlIHNlcnZlcidzIEpTT04gc2NoZW1hXG4gKiBpZiBub3QgZXhwbGljaXRseSBwcm92aWRlZCBpbiB0aGUgdG9vbHMgY29uZmlndXJhdGlvblxuICpcbiAqIFRoaXMgY2xpZW50IGlzIG1lYW50IHRvIGJlIHVzZWQgdG8gY29tbXVuaWNhdGUgd2l0aCBhIHNpbmdsZSBzZXJ2ZXIuIFRvIGNvbW11bmljYXRlIGFuZCBmZXRjaCB0b29scyBhY3Jvc3MgbXVsdGlwbGUgc2VydmVycywgaXQncyByZWNvbW1lbmRlZCB0byBjcmVhdGUgYSBuZXcgY2xpZW50IGluc3RhbmNlIHBlciBzZXJ2ZXIuXG4gKlxuICogTm90IHN1cHBvcnRlZDpcbiAqIC0gQ2xpZW50IG9wdGlvbnMgKGUuZy4gc2FtcGxpbmcsIHJvb3RzKSBhcyB0aGV5IGFyZSBub3QgbmVlZGVkIGZvciB0b29sIGNvbnZlcnNpb25cbiAqIC0gQWNjZXB0aW5nIG5vdGlmaWNhdGlvbnNcbiAqIC0gU2Vzc2lvbiBtYW5hZ2VtZW50ICh3aGVuIHBhc3NpbmcgYSBzZXNzaW9uSWQgdG8gYW4gaW5zdGFuY2Ugb2YgdGhlIFN0cmVhbWFibGUgSFRUUCB0cmFuc3BvcnQpXG4gKiAtIFJlc3VtYWJsZSBTU0Ugc3RyZWFtc1xuICovXG5jbGFzcyBEZWZhdWx0TUNQQ2xpZW50IGltcGxlbWVudHMgTUNQQ2xpZW50IHtcbiAgcHJpdmF0ZSB0cmFuc3BvcnQ6IE1DUFRyYW5zcG9ydDtcbiAgcHJpdmF0ZSBvblVuY2F1Z2h0RXJyb3I/OiAoZXJyb3I6IHVua25vd24pID0+IHZvaWQ7XG4gIHByaXZhdGUgY2xpZW50SW5mbzogQ2xpZW50Q29uZmlndXJhdGlvbjtcbiAgcHJpdmF0ZSByZXF1ZXN0TWVzc2FnZUlkID0gMDtcbiAgcHJpdmF0ZSByZXNwb25zZUhhbmRsZXJzOiBNYXA8XG4gICAgbnVtYmVyLFxuICAgIChyZXNwb25zZTogSlNPTlJQQ1Jlc3BvbnNlIHwgRXJyb3IpID0+IHZvaWRcbiAgPiA9IG5ldyBNYXAoKTtcbiAgcHJpdmF0ZSBzZXJ2ZXJDYXBhYmlsaXRpZXM6IFNlcnZlckNhcGFiaWxpdGllcyA9IHt9O1xuICBwcml2YXRlIGlzQ2xvc2VkID0gdHJ1ZTtcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgdHJhbnNwb3J0OiB0cmFuc3BvcnRDb25maWcsXG4gICAgbmFtZSA9ICdhaS1zZGstbWNwLWNsaWVudCcsXG4gICAgb25VbmNhdWdodEVycm9yLFxuICB9OiBNQ1BDbGllbnRDb25maWcpIHtcbiAgICB0aGlzLm9uVW5jYXVnaHRFcnJvciA9IG9uVW5jYXVnaHRFcnJvcjtcblxuICAgIGlmIChpc0N1c3RvbU1jcFRyYW5zcG9ydCh0cmFuc3BvcnRDb25maWcpKSB7XG4gICAgICB0aGlzLnRyYW5zcG9ydCA9IHRyYW5zcG9ydENvbmZpZztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy50cmFuc3BvcnQgPSBjcmVhdGVNY3BUcmFuc3BvcnQodHJhbnNwb3J0Q29uZmlnKTtcbiAgICB9XG5cbiAgICB0aGlzLnRyYW5zcG9ydC5vbmNsb3NlID0gKCkgPT4gdGhpcy5vbkNsb3NlKCk7XG4gICAgdGhpcy50cmFuc3BvcnQub25lcnJvciA9IChlcnJvcjogRXJyb3IpID0+IHRoaXMub25FcnJvcihlcnJvcik7XG4gICAgdGhpcy50cmFuc3BvcnQub25tZXNzYWdlID0gbWVzc2FnZSA9PiB7XG4gICAgICBpZiAoJ21ldGhvZCcgaW4gbWVzc2FnZSkge1xuICAgICAgICAvLyBUaGlzIGxpZ2h0d2VpZ2h0IGNsaWVudCBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0XG4gICAgICAgIC8vIHJlY2VpdmluZyBub3RpZmljYXRpb25zIG9yIHJlcXVlc3RzIGZyb20gc2VydmVyLlxuICAgICAgICAvLyBJZiB3ZSBnZXQgYW4gdW5zdXBwb3J0ZWQgbWVzc2FnZSwgd2UgY2FuIHNhZmVseSBpZ25vcmUgaXQgYW5kIHBhc3MgdG8gdGhlIG9uRXJyb3IgaGFuZGxlcjpcbiAgICAgICAgdGhpcy5vbkVycm9yKFxuICAgICAgICAgIG5ldyBNQ1BDbGllbnRFcnJvcih7XG4gICAgICAgICAgICBtZXNzYWdlOiAnVW5zdXBwb3J0ZWQgbWVzc2FnZSB0eXBlJyxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0aGlzLm9uUmVzcG9uc2UobWVzc2FnZSk7XG4gICAgfTtcblxuICAgIHRoaXMuY2xpZW50SW5mbyA9IHtcbiAgICAgIG5hbWUsXG4gICAgICB2ZXJzaW9uOiBDTElFTlRfVkVSU0lPTixcbiAgICB9O1xuICB9XG5cbiAgYXN5bmMgaW5pdCgpOiBQcm9taXNlPHRoaXM+IHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy50cmFuc3BvcnQuc3RhcnQoKTtcbiAgICAgIHRoaXMuaXNDbG9zZWQgPSBmYWxzZTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5yZXF1ZXN0KHtcbiAgICAgICAgcmVxdWVzdDoge1xuICAgICAgICAgIG1ldGhvZDogJ2luaXRpYWxpemUnLFxuICAgICAgICAgIHBhcmFtczoge1xuICAgICAgICAgICAgcHJvdG9jb2xWZXJzaW9uOiBMQVRFU1RfUFJPVE9DT0xfVkVSU0lPTixcbiAgICAgICAgICAgIGNhcGFiaWxpdGllczoge30sXG4gICAgICAgICAgICBjbGllbnRJbmZvOiB0aGlzLmNsaWVudEluZm8sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgcmVzdWx0U2NoZW1hOiBJbml0aWFsaXplUmVzdWx0U2NoZW1hLFxuICAgICAgfSk7XG5cbiAgICAgIGlmIChyZXN1bHQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBuZXcgTUNQQ2xpZW50RXJyb3Ioe1xuICAgICAgICAgIG1lc3NhZ2U6ICdTZXJ2ZXIgc2VudCBpbnZhbGlkIGluaXRpYWxpemUgcmVzdWx0JyxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmICghU1VQUE9SVEVEX1BST1RPQ09MX1ZFUlNJT05TLmluY2x1ZGVzKHJlc3VsdC5wcm90b2NvbFZlcnNpb24pKSB7XG4gICAgICAgIHRocm93IG5ldyBNQ1BDbGllbnRFcnJvcih7XG4gICAgICAgICAgbWVzc2FnZTogYFNlcnZlcidzIHByb3RvY29sIHZlcnNpb24gaXMgbm90IHN1cHBvcnRlZDogJHtyZXN1bHQucHJvdG9jb2xWZXJzaW9ufWAsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnNlcnZlckNhcGFiaWxpdGllcyA9IHJlc3VsdC5jYXBhYmlsaXRpZXM7XG5cbiAgICAgIC8vIENvbXBsZXRlIGluaXRpYWxpemF0aW9uIGhhbmRzaGFrZTpcbiAgICAgIGF3YWl0IHRoaXMubm90aWZpY2F0aW9uKHtcbiAgICAgICAgbWV0aG9kOiAnbm90aWZpY2F0aW9ucy9pbml0aWFsaXplZCcsXG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGF3YWl0IHRoaXMuY2xvc2UoKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGNsb3NlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLmlzQ2xvc2VkKSByZXR1cm47XG4gICAgYXdhaXQgdGhpcy50cmFuc3BvcnQ/LmNsb3NlKCk7XG4gICAgdGhpcy5vbkNsb3NlKCk7XG4gIH1cblxuICBwcml2YXRlIGFzc2VydENhcGFiaWxpdHkobWV0aG9kOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBzd2l0Y2ggKG1ldGhvZCkge1xuICAgICAgY2FzZSAnaW5pdGlhbGl6ZSc6XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAndG9vbHMvbGlzdCc6XG4gICAgICBjYXNlICd0b29scy9jYWxsJzpcbiAgICAgICAgaWYgKCF0aGlzLnNlcnZlckNhcGFiaWxpdGllcy50b29scykge1xuICAgICAgICAgIHRocm93IG5ldyBNQ1BDbGllbnRFcnJvcih7XG4gICAgICAgICAgICBtZXNzYWdlOiBgU2VydmVyIGRvZXMgbm90IHN1cHBvcnQgdG9vbHNgLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IE1DUENsaWVudEVycm9yKHtcbiAgICAgICAgICBtZXNzYWdlOiBgVW5zdXBwb3J0ZWQgbWV0aG9kOiAke21ldGhvZH1gLFxuICAgICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJlcXVlc3Q8VCBleHRlbmRzIHouWm9kVHlwZTxvYmplY3Q+Pih7XG4gICAgcmVxdWVzdCxcbiAgICByZXN1bHRTY2hlbWEsXG4gICAgb3B0aW9ucyxcbiAgfToge1xuICAgIHJlcXVlc3Q6IFJlcXVlc3Q7XG4gICAgcmVzdWx0U2NoZW1hOiBUO1xuICAgIG9wdGlvbnM/OiBSZXF1ZXN0T3B0aW9ucztcbiAgfSk6IFByb21pc2U8ei5pbmZlcjxUPj4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBpZiAodGhpcy5pc0Nsb3NlZCkge1xuICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgIG5ldyBNQ1BDbGllbnRFcnJvcih7XG4gICAgICAgICAgICBtZXNzYWdlOiAnQXR0ZW1wdGVkIHRvIHNlbmQgYSByZXF1ZXN0IGZyb20gYSBjbG9zZWQgY2xpZW50JyxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5hc3NlcnRDYXBhYmlsaXR5KHJlcXVlc3QubWV0aG9kKTtcblxuICAgICAgY29uc3Qgc2lnbmFsID0gb3B0aW9ucz8uc2lnbmFsO1xuICAgICAgc2lnbmFsPy50aHJvd0lmQWJvcnRlZCgpO1xuXG4gICAgICBjb25zdCBtZXNzYWdlSWQgPSB0aGlzLnJlcXVlc3RNZXNzYWdlSWQrKztcbiAgICAgIGNvbnN0IGpzb25ycGNSZXF1ZXN0OiBKU09OUlBDUmVxdWVzdCA9IHtcbiAgICAgICAgLi4ucmVxdWVzdCxcbiAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgIGlkOiBtZXNzYWdlSWQsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBjbGVhbnVwID0gKCkgPT4ge1xuICAgICAgICB0aGlzLnJlc3BvbnNlSGFuZGxlcnMuZGVsZXRlKG1lc3NhZ2VJZCk7XG4gICAgICB9O1xuXG4gICAgICB0aGlzLnJlc3BvbnNlSGFuZGxlcnMuc2V0KG1lc3NhZ2VJZCwgcmVzcG9uc2UgPT4ge1xuICAgICAgICBpZiAoc2lnbmFsPy5hYm9ydGVkKSB7XG4gICAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICAgIG5ldyBNQ1BDbGllbnRFcnJvcih7XG4gICAgICAgICAgICAgIG1lc3NhZ2U6ICdSZXF1ZXN0IHdhcyBhYm9ydGVkJyxcbiAgICAgICAgICAgICAgY2F1c2U6IHNpZ25hbC5yZWFzb24sXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHJlc3BvbnNlIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gcmVqZWN0KHJlc3BvbnNlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gcmVzdWx0U2NoZW1hLnBhcnNlKHJlc3BvbnNlLnJlc3VsdCk7XG4gICAgICAgICAgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIGNvbnN0IHBhcnNlRXJyb3IgPSBuZXcgTUNQQ2xpZW50RXJyb3Ioe1xuICAgICAgICAgICAgbWVzc2FnZTogJ0ZhaWxlZCB0byBwYXJzZSBzZXJ2ZXIgcmVzcG9uc2UnLFxuICAgICAgICAgICAgY2F1c2U6IGVycm9yLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJlamVjdChwYXJzZUVycm9yKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHRoaXMudHJhbnNwb3J0LnNlbmQoanNvbnJwY1JlcXVlc3QpLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgY2xlYW51cCgpO1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGxpc3RUb29scyh7XG4gICAgcGFyYW1zLFxuICAgIG9wdGlvbnMsXG4gIH06IHtcbiAgICBwYXJhbXM/OiBQYWdpbmF0ZWRSZXF1ZXN0WydwYXJhbXMnXTtcbiAgICBvcHRpb25zPzogUmVxdWVzdE9wdGlvbnM7XG4gIH0gPSB7fSk6IFByb21pc2U8TGlzdFRvb2xzUmVzdWx0PiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiB0aGlzLnJlcXVlc3Qoe1xuICAgICAgICByZXF1ZXN0OiB7IG1ldGhvZDogJ3Rvb2xzL2xpc3QnLCBwYXJhbXMgfSxcbiAgICAgICAgcmVzdWx0U2NoZW1hOiBMaXN0VG9vbHNSZXN1bHRTY2hlbWEsXG4gICAgICAgIG9wdGlvbnMsXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBjYWxsVG9vbCh7XG4gICAgbmFtZSxcbiAgICBhcmdzLFxuICAgIG9wdGlvbnMsXG4gIH06IHtcbiAgICBuYW1lOiBzdHJpbmc7XG4gICAgYXJnczogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgb3B0aW9ucz86IFRvb2xDYWxsT3B0aW9ucztcbiAgfSk6IFByb21pc2U8Q2FsbFRvb2xSZXN1bHQ+IHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHRoaXMucmVxdWVzdCh7XG4gICAgICAgIHJlcXVlc3Q6IHsgbWV0aG9kOiAndG9vbHMvY2FsbCcsIHBhcmFtczogeyBuYW1lLCBhcmd1bWVudHM6IGFyZ3MgfSB9LFxuICAgICAgICByZXN1bHRTY2hlbWE6IENhbGxUb29sUmVzdWx0U2NoZW1hLFxuICAgICAgICBvcHRpb25zOiB7XG4gICAgICAgICAgc2lnbmFsOiBvcHRpb25zPy5hYm9ydFNpZ25hbCxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIG5vdGlmaWNhdGlvbihub3RpZmljYXRpb246IE5vdGlmaWNhdGlvbik6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGpzb25ycGNOb3RpZmljYXRpb246IEpTT05SUENOb3RpZmljYXRpb24gPSB7XG4gICAgICAuLi5ub3RpZmljYXRpb24sXG4gICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICB9O1xuICAgIGF3YWl0IHRoaXMudHJhbnNwb3J0LnNlbmQoanNvbnJwY05vdGlmaWNhdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIHNldCBvZiBBSSBTREsgdG9vbHMgZnJvbSB0aGUgTUNQIHNlcnZlclxuICAgKiBAcmV0dXJucyBBIHJlY29yZCBvZiB0b29sIG5hbWVzIHRvIHRoZWlyIGltcGxlbWVudGF0aW9uc1xuICAgKi9cbiAgYXN5bmMgdG9vbHM8VE9PTF9TQ0hFTUFTIGV4dGVuZHMgVG9vbFNjaGVtYXMgPSAnYXV0b21hdGljJz4oe1xuICAgIHNjaGVtYXMgPSAnYXV0b21hdGljJyxcbiAgfToge1xuICAgIHNjaGVtYXM/OiBUT09MX1NDSEVNQVM7XG4gIH0gPSB7fSk6IFByb21pc2U8TWNwVG9vbFNldDxUT09MX1NDSEVNQVM+PiB7XG4gICAgY29uc3QgdG9vbHM6IFJlY29yZDxzdHJpbmcsIFRvb2w+ID0ge307XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgbGlzdFRvb2xzUmVzdWx0ID0gYXdhaXQgdGhpcy5saXN0VG9vbHMoKTtcblxuICAgICAgZm9yIChjb25zdCB7IG5hbWUsIGRlc2NyaXB0aW9uLCBpbnB1dFNjaGVtYSB9IG9mIGxpc3RUb29sc1Jlc3VsdC50b29scykge1xuICAgICAgICBpZiAoc2NoZW1hcyAhPT0gJ2F1dG9tYXRpYycgJiYgIShuYW1lIGluIHNjaGVtYXMpKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgICAgICBjb25zdCBleGVjdXRlID0gYXN5bmMgKFxuICAgICAgICAgIGFyZ3M6IGFueSxcbiAgICAgICAgICBvcHRpb25zOiBUb29sQ2FsbE9wdGlvbnMsXG4gICAgICAgICk6IFByb21pc2U8Q2FsbFRvb2xSZXN1bHQ+ID0+IHtcbiAgICAgICAgICBvcHRpb25zPy5hYm9ydFNpZ25hbD8udGhyb3dJZkFib3J0ZWQoKTtcbiAgICAgICAgICByZXR1cm4gc2VsZi5jYWxsVG9vbCh7IG5hbWUsIGFyZ3MsIG9wdGlvbnMgfSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgdG9vbFdpdGhFeGVjdXRlID1cbiAgICAgICAgICBzY2hlbWFzID09PSAnYXV0b21hdGljJ1xuICAgICAgICAgICAgPyBkeW5hbWljVG9vbCh7XG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb24sXG4gICAgICAgICAgICAgICAgaW5wdXRTY2hlbWE6IGpzb25TY2hlbWEoe1xuICAgICAgICAgICAgICAgICAgLi4uaW5wdXRTY2hlbWEsXG4gICAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzOiBpbnB1dFNjaGVtYS5wcm9wZXJ0aWVzID8/IHt9LFxuICAgICAgICAgICAgICAgICAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH0gYXMgSlNPTlNjaGVtYTcpLFxuICAgICAgICAgICAgICAgIGV4ZWN1dGUsXG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICA6IHRvb2woe1xuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uLFxuICAgICAgICAgICAgICAgIGlucHV0U2NoZW1hOiBzY2hlbWFzW25hbWVdLmlucHV0U2NoZW1hLFxuICAgICAgICAgICAgICAgIGV4ZWN1dGUsXG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIHRvb2xzW25hbWVdID0gdG9vbFdpdGhFeGVjdXRlO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdG9vbHMgYXMgTWNwVG9vbFNldDxUT09MX1NDSEVNQVM+O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG9uQ2xvc2UoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNDbG9zZWQpIHJldHVybjtcblxuICAgIHRoaXMuaXNDbG9zZWQgPSB0cnVlO1xuICAgIGNvbnN0IGVycm9yID0gbmV3IE1DUENsaWVudEVycm9yKHtcbiAgICAgIG1lc3NhZ2U6ICdDb25uZWN0aW9uIGNsb3NlZCcsXG4gICAgfSk7XG5cbiAgICBmb3IgKGNvbnN0IGhhbmRsZXIgb2YgdGhpcy5yZXNwb25zZUhhbmRsZXJzLnZhbHVlcygpKSB7XG4gICAgICBoYW5kbGVyKGVycm9yKTtcbiAgICB9XG5cbiAgICB0aGlzLnJlc3BvbnNlSGFuZGxlcnMuY2xlYXIoKTtcbiAgfVxuXG4gIHByaXZhdGUgb25FcnJvcihlcnJvcjogdW5rbm93bik6IHZvaWQge1xuICAgIGlmICh0aGlzLm9uVW5jYXVnaHRFcnJvcikge1xuICAgICAgdGhpcy5vblVuY2F1Z2h0RXJyb3IoZXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgb25SZXNwb25zZShyZXNwb25zZTogSlNPTlJQQ1Jlc3BvbnNlIHwgSlNPTlJQQ0Vycm9yKTogdm9pZCB7XG4gICAgY29uc3QgbWVzc2FnZUlkID0gTnVtYmVyKHJlc3BvbnNlLmlkKTtcbiAgICBjb25zdCBoYW5kbGVyID0gdGhpcy5yZXNwb25zZUhhbmRsZXJzLmdldChtZXNzYWdlSWQpO1xuXG4gICAgaWYgKGhhbmRsZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IE1DUENsaWVudEVycm9yKHtcbiAgICAgICAgbWVzc2FnZTogYFByb3RvY29sIGVycm9yOiBSZWNlaXZlZCBhIHJlc3BvbnNlIGZvciBhbiB1bmtub3duIG1lc3NhZ2UgSUQ6ICR7SlNPTi5zdHJpbmdpZnkoXG4gICAgICAgICAgcmVzcG9uc2UsXG4gICAgICAgICl9YCxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMucmVzcG9uc2VIYW5kbGVycy5kZWxldGUobWVzc2FnZUlkKTtcblxuICAgIGhhbmRsZXIoXG4gICAgICAncmVzdWx0JyBpbiByZXNwb25zZVxuICAgICAgICA/IHJlc3BvbnNlXG4gICAgICAgIDogbmV3IE1DUENsaWVudEVycm9yKHtcbiAgICAgICAgICAgIG1lc3NhZ2U6IHJlc3BvbnNlLmVycm9yLm1lc3NhZ2UsXG4gICAgICAgICAgICBjb2RlOiByZXNwb25zZS5lcnJvci5jb2RlLFxuICAgICAgICAgICAgZGF0YTogcmVzcG9uc2UuZXJyb3IuZGF0YSxcbiAgICAgICAgICAgIGNhdXNlOiByZXNwb25zZS5lcnJvcixcbiAgICAgICAgICB9KSxcbiAgICApO1xuICB9XG59XG4iLCAiaW1wb3J0IHtcbiAgRXZlbnRTb3VyY2VQYXJzZXJTdHJlYW0sXG4gIHdpdGhVc2VyQWdlbnRTdWZmaXgsXG4gIGdldFJ1bnRpbWVFbnZpcm9ubWVudFVzZXJBZ2VudCxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyBNQ1BDbGllbnRFcnJvciB9IGZyb20gJy4uLy4uL2Vycm9yL21jcC1jbGllbnQtZXJyb3InO1xuaW1wb3J0IHsgSlNPTlJQQ01lc3NhZ2UsIEpTT05SUENNZXNzYWdlU2NoZW1hIH0gZnJvbSAnLi9qc29uLXJwYy1tZXNzYWdlJztcbmltcG9ydCB7IE1DUFRyYW5zcG9ydCB9IGZyb20gJy4vbWNwLXRyYW5zcG9ydCc7XG5pbXBvcnQgeyBWRVJTSU9OIH0gZnJvbSAnLi4vLi4vdmVyc2lvbic7XG5cbmV4cG9ydCBjbGFzcyBTc2VNQ1BUcmFuc3BvcnQgaW1wbGVtZW50cyBNQ1BUcmFuc3BvcnQge1xuICBwcml2YXRlIGVuZHBvaW50PzogVVJMO1xuICBwcml2YXRlIGFib3J0Q29udHJvbGxlcj86IEFib3J0Q29udHJvbGxlcjtcbiAgcHJpdmF0ZSB1cmw6IFVSTDtcbiAgcHJpdmF0ZSBjb25uZWN0ZWQgPSBmYWxzZTtcbiAgcHJpdmF0ZSBzc2VDb25uZWN0aW9uPzoge1xuICAgIGNsb3NlOiAoKSA9PiB2b2lkO1xuICB9O1xuICBwcml2YXRlIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuXG4gIG9uY2xvc2U/OiAoKSA9PiB2b2lkO1xuICBvbmVycm9yPzogKGVycm9yOiB1bmtub3duKSA9PiB2b2lkO1xuICBvbm1lc3NhZ2U/OiAobWVzc2FnZTogSlNPTlJQQ01lc3NhZ2UpID0+IHZvaWQ7XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIHVybCxcbiAgICBoZWFkZXJzLFxuICB9OiB7XG4gICAgdXJsOiBzdHJpbmc7XG4gICAgaGVhZGVycz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIH0pIHtcbiAgICB0aGlzLnVybCA9IG5ldyBVUkwodXJsKTtcbiAgICB0aGlzLmhlYWRlcnMgPSBoZWFkZXJzO1xuICB9XG5cbiAgYXN5bmMgc3RhcnQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGlmICh0aGlzLmNvbm5lY3RlZCkge1xuICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmFib3J0Q29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcblxuICAgICAgY29uc3QgZXN0YWJsaXNoQ29ubmVjdGlvbiA9IGFzeW5jICgpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBoZWFkZXJzID0gd2l0aFVzZXJBZ2VudFN1ZmZpeChcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgLi4udGhpcy5oZWFkZXJzLFxuICAgICAgICAgICAgICBBY2NlcHQ6ICd0ZXh0L2V2ZW50LXN0cmVhbScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYGFpLXNkay8ke1ZFUlNJT059YCxcbiAgICAgICAgICAgIGdldFJ1bnRpbWVFbnZpcm9ubWVudFVzZXJBZ2VudCgpLFxuICAgICAgICAgICk7XG4gICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh0aGlzLnVybC5ocmVmLCB7XG4gICAgICAgICAgICBoZWFkZXJzLFxuICAgICAgICAgICAgc2lnbmFsOiB0aGlzLmFib3J0Q29udHJvbGxlcj8uc2lnbmFsLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaWYgKCFyZXNwb25zZS5vayB8fCAhcmVzcG9uc2UuYm9keSkge1xuICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgTUNQQ2xpZW50RXJyb3Ioe1xuICAgICAgICAgICAgICBtZXNzYWdlOiBgTUNQIFNTRSBUcmFuc3BvcnQgRXJyb3I6ICR7cmVzcG9uc2Uuc3RhdHVzfSAke3Jlc3BvbnNlLnN0YXR1c1RleHR9YCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5vbmVycm9yPy4oZXJyb3IpO1xuICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3Qgc3RyZWFtID0gcmVzcG9uc2UuYm9keVxuICAgICAgICAgICAgLnBpcGVUaHJvdWdoKG5ldyBUZXh0RGVjb2RlclN0cmVhbSgpKVxuICAgICAgICAgICAgLnBpcGVUaHJvdWdoKG5ldyBFdmVudFNvdXJjZVBhcnNlclN0cmVhbSgpKTtcblxuICAgICAgICAgIGNvbnN0IHJlYWRlciA9IHN0cmVhbS5nZXRSZWFkZXIoKTtcblxuICAgICAgICAgIGNvbnN0IHByb2Nlc3NFdmVudHMgPSBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHsgZG9uZSwgdmFsdWUgfSA9IGF3YWl0IHJlYWRlci5yZWFkKCk7XG5cbiAgICAgICAgICAgICAgICBpZiAoZG9uZSkge1xuICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuY29ubmVjdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBNQ1BDbGllbnRFcnJvcih7XG4gICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTpcbiAgICAgICAgICAgICAgICAgICAgICAgICdNQ1AgU1NFIFRyYW5zcG9ydCBFcnJvcjogQ29ubmVjdGlvbiBjbG9zZWQgdW5leHBlY3RlZGx5JyxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY29uc3QgeyBldmVudCwgZGF0YSB9ID0gdmFsdWU7XG5cbiAgICAgICAgICAgICAgICBpZiAoZXZlbnQgPT09ICdlbmRwb2ludCcpIHtcbiAgICAgICAgICAgICAgICAgIHRoaXMuZW5kcG9pbnQgPSBuZXcgVVJMKGRhdGEsIHRoaXMudXJsKTtcblxuICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZW5kcG9pbnQub3JpZ2luICE9PSB0aGlzLnVybC5vcmlnaW4pIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE1DUENsaWVudEVycm9yKHtcbiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBgTUNQIFNTRSBUcmFuc3BvcnQgRXJyb3I6IEVuZHBvaW50IG9yaWdpbiBkb2VzIG5vdCBtYXRjaCBjb25uZWN0aW9uIG9yaWdpbjogJHt0aGlzLmVuZHBvaW50Lm9yaWdpbn1gLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZXZlbnQgPT09ICdtZXNzYWdlJykge1xuICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbWVzc2FnZSA9IEpTT05SUENNZXNzYWdlU2NoZW1hLnBhcnNlKFxuICAgICAgICAgICAgICAgICAgICAgIEpTT04ucGFyc2UoZGF0YSksXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25tZXNzYWdlPy4obWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlID0gbmV3IE1DUENsaWVudEVycm9yKHtcbiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOlxuICAgICAgICAgICAgICAgICAgICAgICAgJ01DUCBTU0UgVHJhbnNwb3J0IEVycm9yOiBGYWlsZWQgdG8gcGFyc2UgbWVzc2FnZScsXG4gICAgICAgICAgICAgICAgICAgICAgY2F1c2U6IGVycm9yLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vbmVycm9yPy4oZSk7XG4gICAgICAgICAgICAgICAgICAgIC8vIFdlIGRvIG5vdCB0aHJvdyBoZXJlIHNvIHdlIGNvbnRpbnVlIHByb2Nlc3NpbmcgZXZlbnRzIGFmdGVyIHJlcG9ydGluZyB0aGUgZXJyb3JcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yICYmIGVycm9yLm5hbWUgPT09ICdBYm9ydEVycm9yJykge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIHRoaXMub25lcnJvcj8uKGVycm9yKTtcbiAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgdGhpcy5zc2VDb25uZWN0aW9uID0ge1xuICAgICAgICAgICAgY2xvc2U6ICgpID0+IHJlYWRlci5jYW5jZWwoKSxcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgcHJvY2Vzc0V2ZW50cygpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yICYmIGVycm9yLm5hbWUgPT09ICdBYm9ydEVycm9yJykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRoaXMub25lcnJvcj8uKGVycm9yKTtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBlc3RhYmxpc2hDb25uZWN0aW9uKCk7XG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBjbG9zZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLmNvbm5lY3RlZCA9IGZhbHNlO1xuICAgIHRoaXMuc3NlQ29ubmVjdGlvbj8uY2xvc2UoKTtcbiAgICB0aGlzLmFib3J0Q29udHJvbGxlcj8uYWJvcnQoKTtcbiAgICB0aGlzLm9uY2xvc2U/LigpO1xuICB9XG5cbiAgYXN5bmMgc2VuZChtZXNzYWdlOiBKU09OUlBDTWVzc2FnZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghdGhpcy5lbmRwb2ludCB8fCAhdGhpcy5jb25uZWN0ZWQpIHtcbiAgICAgIHRocm93IG5ldyBNQ1BDbGllbnRFcnJvcih7XG4gICAgICAgIG1lc3NhZ2U6ICdNQ1AgU1NFIFRyYW5zcG9ydCBFcnJvcjogTm90IGNvbm5lY3RlZCcsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgaGVhZGVycyA9IHdpdGhVc2VyQWdlbnRTdWZmaXgoXG4gICAgICAgIHtcbiAgICAgICAgICAuLi50aGlzLmhlYWRlcnMsXG4gICAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgfSxcbiAgICAgICAgYGFpLXNkay8ke1ZFUlNJT059YCxcbiAgICAgICAgZ2V0UnVudGltZUVudmlyb25tZW50VXNlckFnZW50KCksXG4gICAgICApO1xuICAgICAgY29uc3QgaW5pdCA9IHtcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGhlYWRlcnMsXG4gICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KG1lc3NhZ2UpLFxuICAgICAgICBzaWduYWw6IHRoaXMuYWJvcnRDb250cm9sbGVyPy5zaWduYWwsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHRoaXMuZW5kcG9pbnQsIGluaXQpO1xuXG4gICAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICAgIGNvbnN0IHRleHQgPSBhd2FpdCByZXNwb25zZS50ZXh0KCkuY2F0Y2goKCkgPT4gbnVsbCk7XG4gICAgICAgIGNvbnN0IGVycm9yID0gbmV3IE1DUENsaWVudEVycm9yKHtcbiAgICAgICAgICBtZXNzYWdlOiBgTUNQIFNTRSBUcmFuc3BvcnQgRXJyb3I6IFBPU1RpbmcgdG8gZW5kcG9pbnQgKEhUVFAgJHtyZXNwb25zZS5zdGF0dXN9KTogJHt0ZXh0fWAsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm9uZXJyb3I/LihlcnJvcik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhpcy5vbmVycm9yPy4oZXJyb3IpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZGVzZXJpYWxpemVNZXNzYWdlKGxpbmU6IHN0cmluZyk6IEpTT05SUENNZXNzYWdlIHtcbiAgcmV0dXJuIEpTT05SUENNZXNzYWdlU2NoZW1hLnBhcnNlKEpTT04ucGFyc2UobGluZSkpO1xufVxuIiwgImltcG9ydCB7IHogfSBmcm9tICd6b2QvdjQnO1xuaW1wb3J0IHsgQmFzZVBhcmFtc1NjaGVtYSwgUmVxdWVzdFNjaGVtYSwgUmVzdWx0U2NoZW1hIH0gZnJvbSAnLi90eXBlcyc7XG5cbmNvbnN0IEpTT05SUENfVkVSU0lPTiA9ICcyLjAnO1xuXG5jb25zdCBKU09OUlBDUmVxdWVzdFNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAganNvbnJwYzogei5saXRlcmFsKEpTT05SUENfVkVSU0lPTiksXG4gICAgaWQ6IHoudW5pb24oW3ouc3RyaW5nKCksIHoubnVtYmVyKCkuaW50KCldKSxcbiAgfSlcbiAgLm1lcmdlKFJlcXVlc3RTY2hlbWEpXG4gIC5zdHJpY3QoKTtcblxuZXhwb3J0IHR5cGUgSlNPTlJQQ1JlcXVlc3QgPSB6LmluZmVyPHR5cGVvZiBKU09OUlBDUmVxdWVzdFNjaGVtYT47XG5cbmNvbnN0IEpTT05SUENSZXNwb25zZVNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAganNvbnJwYzogei5saXRlcmFsKEpTT05SUENfVkVSU0lPTiksXG4gICAgaWQ6IHoudW5pb24oW3ouc3RyaW5nKCksIHoubnVtYmVyKCkuaW50KCldKSxcbiAgICByZXN1bHQ6IFJlc3VsdFNjaGVtYSxcbiAgfSlcbiAgLnN0cmljdCgpO1xuXG5leHBvcnQgdHlwZSBKU09OUlBDUmVzcG9uc2UgPSB6LmluZmVyPHR5cGVvZiBKU09OUlBDUmVzcG9uc2VTY2hlbWE+O1xuXG5jb25zdCBKU09OUlBDRXJyb3JTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIGpzb25ycGM6IHoubGl0ZXJhbChKU09OUlBDX1ZFUlNJT04pLFxuICAgIGlkOiB6LnVuaW9uKFt6LnN0cmluZygpLCB6Lm51bWJlcigpLmludCgpXSksXG4gICAgZXJyb3I6IHoub2JqZWN0KHtcbiAgICAgIGNvZGU6IHoubnVtYmVyKCkuaW50KCksXG4gICAgICBtZXNzYWdlOiB6LnN0cmluZygpLFxuICAgICAgZGF0YTogei5vcHRpb25hbCh6LnVua25vd24oKSksXG4gICAgfSksXG4gIH0pXG4gIC5zdHJpY3QoKTtcblxuZXhwb3J0IHR5cGUgSlNPTlJQQ0Vycm9yID0gei5pbmZlcjx0eXBlb2YgSlNPTlJQQ0Vycm9yU2NoZW1hPjtcblxuY29uc3QgSlNPTlJQQ05vdGlmaWNhdGlvblNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAganNvbnJwYzogei5saXRlcmFsKEpTT05SUENfVkVSU0lPTiksXG4gIH0pXG4gIC5tZXJnZShcbiAgICB6Lm9iamVjdCh7XG4gICAgICBtZXRob2Q6IHouc3RyaW5nKCksXG4gICAgICBwYXJhbXM6IHoub3B0aW9uYWwoQmFzZVBhcmFtc1NjaGVtYSksXG4gICAgfSksXG4gIClcbiAgLnN0cmljdCgpO1xuXG5leHBvcnQgdHlwZSBKU09OUlBDTm90aWZpY2F0aW9uID0gei5pbmZlcjx0eXBlb2YgSlNPTlJQQ05vdGlmaWNhdGlvblNjaGVtYT47XG5cbmV4cG9ydCBjb25zdCBKU09OUlBDTWVzc2FnZVNjaGVtYSA9IHoudW5pb24oW1xuICBKU09OUlBDUmVxdWVzdFNjaGVtYSxcbiAgSlNPTlJQQ05vdGlmaWNhdGlvblNjaGVtYSxcbiAgSlNPTlJQQ1Jlc3BvbnNlU2NoZW1hLFxuICBKU09OUlBDRXJyb3JTY2hlbWEsXG5dKTtcblxuZXhwb3J0IHR5cGUgSlNPTlJQQ01lc3NhZ2UgPSB6LmluZmVyPHR5cGVvZiBKU09OUlBDTWVzc2FnZVNjaGVtYT47XG4iLCAiaW1wb3J0IHsgeiB9IGZyb20gJ3pvZC92NCc7XG5pbXBvcnQgeyBKU09OT2JqZWN0IH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQgeyBGbGV4aWJsZVNjaGVtYSwgVG9vbCB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXItdXRpbHMnO1xuXG5leHBvcnQgY29uc3QgTEFURVNUX1BST1RPQ09MX1ZFUlNJT04gPSAnMjAyNS0wNi0xOCc7XG5leHBvcnQgY29uc3QgU1VQUE9SVEVEX1BST1RPQ09MX1ZFUlNJT05TID0gW1xuICBMQVRFU1RfUFJPVE9DT0xfVkVSU0lPTixcbiAgJzIwMjUtMDMtMjYnLFxuICAnMjAyNC0xMS0wNScsXG5dO1xuXG5leHBvcnQgdHlwZSBUb29sU2NoZW1hcyA9XG4gIHwgUmVjb3JkPHN0cmluZywgeyBpbnB1dFNjaGVtYTogRmxleGlibGVTY2hlbWE8SlNPTk9iamVjdCB8IHVua25vd24+IH0+XG4gIHwgJ2F1dG9tYXRpYydcbiAgfCB1bmRlZmluZWQ7XG5cbmV4cG9ydCB0eXBlIE1jcFRvb2xTZXQ8VE9PTF9TQ0hFTUFTIGV4dGVuZHMgVG9vbFNjaGVtYXMgPSAnYXV0b21hdGljJz4gPVxuICBUT09MX1NDSEVNQVMgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCB7IGlucHV0U2NoZW1hOiBGbGV4aWJsZVNjaGVtYTxhbnk+IH0+XG4gICAgPyB7XG4gICAgICAgIFtLIGluIGtleW9mIFRPT0xfU0NIRU1BU106IFRPT0xfU0NIRU1BU1tLXSBleHRlbmRzIHtcbiAgICAgICAgICBpbnB1dFNjaGVtYTogRmxleGlibGVTY2hlbWE8aW5mZXIgSU5QVVQ+O1xuICAgICAgICB9XG4gICAgICAgICAgPyBUb29sPElOUFVULCBDYWxsVG9vbFJlc3VsdD4gJlxuICAgICAgICAgICAgICBSZXF1aXJlZDxQaWNrPFRvb2w8SU5QVVQsIENhbGxUb29sUmVzdWx0PiwgJ2V4ZWN1dGUnPj5cbiAgICAgICAgICA6IG5ldmVyO1xuICAgICAgfVxuICAgIDogTWNwVG9vbFNldDxSZWNvcmQ8c3RyaW5nLCB7IGlucHV0U2NoZW1hOiBGbGV4aWJsZVNjaGVtYTx1bmtub3duPiB9Pj47XG5cbmNvbnN0IENsaWVudE9yU2VydmVySW1wbGVtZW50YXRpb25TY2hlbWEgPSB6Lmxvb3NlT2JqZWN0KHtcbiAgbmFtZTogei5zdHJpbmcoKSxcbiAgdmVyc2lvbjogei5zdHJpbmcoKSxcbn0pO1xuXG5leHBvcnQgdHlwZSBDb25maWd1cmF0aW9uID0gei5pbmZlcjx0eXBlb2YgQ2xpZW50T3JTZXJ2ZXJJbXBsZW1lbnRhdGlvblNjaGVtYT47XG5cbmV4cG9ydCBjb25zdCBCYXNlUGFyYW1zU2NoZW1hID0gei5sb29zZU9iamVjdCh7XG4gIF9tZXRhOiB6Lm9wdGlvbmFsKHoub2JqZWN0KHt9KS5sb29zZSgpKSxcbn0pO1xudHlwZSBCYXNlUGFyYW1zID0gei5pbmZlcjx0eXBlb2YgQmFzZVBhcmFtc1NjaGVtYT47XG5leHBvcnQgY29uc3QgUmVzdWx0U2NoZW1hID0gQmFzZVBhcmFtc1NjaGVtYTtcblxuZXhwb3J0IGNvbnN0IFJlcXVlc3RTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIG1ldGhvZDogei5zdHJpbmcoKSxcbiAgcGFyYW1zOiB6Lm9wdGlvbmFsKEJhc2VQYXJhbXNTY2hlbWEpLFxufSk7XG5leHBvcnQgdHlwZSBSZXF1ZXN0ID0gei5pbmZlcjx0eXBlb2YgUmVxdWVzdFNjaGVtYT47XG5leHBvcnQgdHlwZSBSZXF1ZXN0T3B0aW9ucyA9IHtcbiAgc2lnbmFsPzogQWJvcnRTaWduYWw7XG4gIHRpbWVvdXQ/OiBudW1iZXI7XG4gIG1heFRvdGFsVGltZW91dD86IG51bWJlcjtcbn07XG5cbmV4cG9ydCB0eXBlIE5vdGlmaWNhdGlvbiA9IHouaW5mZXI8dHlwZW9mIFJlcXVlc3RTY2hlbWE+O1xuXG5jb25zdCBTZXJ2ZXJDYXBhYmlsaXRpZXNTY2hlbWEgPSB6Lmxvb3NlT2JqZWN0KHtcbiAgZXhwZXJpbWVudGFsOiB6Lm9wdGlvbmFsKHoub2JqZWN0KHt9KS5sb29zZSgpKSxcbiAgbG9nZ2luZzogei5vcHRpb25hbCh6Lm9iamVjdCh7fSkubG9vc2UoKSksXG4gIHByb21wdHM6IHoub3B0aW9uYWwoXG4gICAgei5sb29zZU9iamVjdCh7XG4gICAgICBsaXN0Q2hhbmdlZDogei5vcHRpb25hbCh6LmJvb2xlYW4oKSksXG4gICAgfSksXG4gICksXG4gIHJlc291cmNlczogei5vcHRpb25hbChcbiAgICB6Lmxvb3NlT2JqZWN0KHtcbiAgICAgIHN1YnNjcmliZTogei5vcHRpb25hbCh6LmJvb2xlYW4oKSksXG4gICAgICBsaXN0Q2hhbmdlZDogei5vcHRpb25hbCh6LmJvb2xlYW4oKSksXG4gICAgfSksXG4gICksXG4gIHRvb2xzOiB6Lm9wdGlvbmFsKFxuICAgIHoubG9vc2VPYmplY3Qoe1xuICAgICAgbGlzdENoYW5nZWQ6IHoub3B0aW9uYWwoei5ib29sZWFuKCkpLFxuICAgIH0pLFxuICApLFxufSk7XG5cbmV4cG9ydCB0eXBlIFNlcnZlckNhcGFiaWxpdGllcyA9IHouaW5mZXI8dHlwZW9mIFNlcnZlckNhcGFiaWxpdGllc1NjaGVtYT47XG5cbmV4cG9ydCBjb25zdCBJbml0aWFsaXplUmVzdWx0U2NoZW1hID0gUmVzdWx0U2NoZW1hLmV4dGVuZCh7XG4gIHByb3RvY29sVmVyc2lvbjogei5zdHJpbmcoKSxcbiAgY2FwYWJpbGl0aWVzOiBTZXJ2ZXJDYXBhYmlsaXRpZXNTY2hlbWEsXG4gIHNlcnZlckluZm86IENsaWVudE9yU2VydmVySW1wbGVtZW50YXRpb25TY2hlbWEsXG4gIGluc3RydWN0aW9uczogei5vcHRpb25hbCh6LnN0cmluZygpKSxcbn0pO1xuZXhwb3J0IHR5cGUgSW5pdGlhbGl6ZVJlc3VsdCA9IHouaW5mZXI8dHlwZW9mIEluaXRpYWxpemVSZXN1bHRTY2hlbWE+O1xuXG5leHBvcnQgdHlwZSBQYWdpbmF0ZWRSZXF1ZXN0ID0gUmVxdWVzdCAmIHtcbiAgcGFyYW1zPzogQmFzZVBhcmFtcyAmIHtcbiAgICBjdXJzb3I/OiBzdHJpbmc7XG4gIH07XG59O1xuXG5jb25zdCBQYWdpbmF0ZWRSZXN1bHRTY2hlbWEgPSBSZXN1bHRTY2hlbWEuZXh0ZW5kKHtcbiAgbmV4dEN1cnNvcjogei5vcHRpb25hbCh6LnN0cmluZygpKSxcbn0pO1xuXG5jb25zdCBUb29sU2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICBuYW1lOiB6LnN0cmluZygpLFxuICAgIGRlc2NyaXB0aW9uOiB6Lm9wdGlvbmFsKHouc3RyaW5nKCkpLFxuICAgIGlucHV0U2NoZW1hOiB6XG4gICAgICAub2JqZWN0KHtcbiAgICAgICAgdHlwZTogei5saXRlcmFsKCdvYmplY3QnKSxcbiAgICAgICAgcHJvcGVydGllczogei5vcHRpb25hbCh6Lm9iamVjdCh7fSkubG9vc2UoKSksXG4gICAgICB9KVxuICAgICAgLmxvb3NlKCksXG4gIH0pXG4gIC5sb29zZSgpO1xuZXhwb3J0IHR5cGUgTUNQVG9vbCA9IHouaW5mZXI8dHlwZW9mIFRvb2xTY2hlbWE+O1xuZXhwb3J0IGNvbnN0IExpc3RUb29sc1Jlc3VsdFNjaGVtYSA9IFBhZ2luYXRlZFJlc3VsdFNjaGVtYS5leHRlbmQoe1xuICB0b29sczogei5hcnJheShUb29sU2NoZW1hKSxcbn0pO1xuZXhwb3J0IHR5cGUgTGlzdFRvb2xzUmVzdWx0ID0gei5pbmZlcjx0eXBlb2YgTGlzdFRvb2xzUmVzdWx0U2NoZW1hPjtcblxuY29uc3QgVGV4dENvbnRlbnRTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIHR5cGU6IHoubGl0ZXJhbCgndGV4dCcpLFxuICAgIHRleHQ6IHouc3RyaW5nKCksXG4gIH0pXG4gIC5sb29zZSgpO1xuY29uc3QgSW1hZ2VDb250ZW50U2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICB0eXBlOiB6LmxpdGVyYWwoJ2ltYWdlJyksXG4gICAgZGF0YTogei5iYXNlNjQoKSxcbiAgICBtaW1lVHlwZTogei5zdHJpbmcoKSxcbiAgfSlcbiAgLmxvb3NlKCk7XG5jb25zdCBSZXNvdXJjZUNvbnRlbnRzU2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICAvKipcbiAgICAgKiBUaGUgVVJJIG9mIHRoaXMgcmVzb3VyY2UuXG4gICAgICovXG4gICAgdXJpOiB6LnN0cmluZygpLFxuICAgIC8qKlxuICAgICAqIFRoZSBNSU1FIHR5cGUgb2YgdGhpcyByZXNvdXJjZSwgaWYga25vd24uXG4gICAgICovXG4gICAgbWltZVR5cGU6IHoub3B0aW9uYWwoei5zdHJpbmcoKSksXG4gIH0pXG4gIC5sb29zZSgpO1xuY29uc3QgVGV4dFJlc291cmNlQ29udGVudHNTY2hlbWEgPSBSZXNvdXJjZUNvbnRlbnRzU2NoZW1hLmV4dGVuZCh7XG4gIHRleHQ6IHouc3RyaW5nKCksXG59KTtcbmNvbnN0IEJsb2JSZXNvdXJjZUNvbnRlbnRzU2NoZW1hID0gUmVzb3VyY2VDb250ZW50c1NjaGVtYS5leHRlbmQoe1xuICBibG9iOiB6LmJhc2U2NCgpLFxufSk7XG5jb25zdCBFbWJlZGRlZFJlc291cmNlU2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICB0eXBlOiB6LmxpdGVyYWwoJ3Jlc291cmNlJyksXG4gICAgcmVzb3VyY2U6IHoudW5pb24oW1RleHRSZXNvdXJjZUNvbnRlbnRzU2NoZW1hLCBCbG9iUmVzb3VyY2VDb250ZW50c1NjaGVtYV0pLFxuICB9KVxuICAubG9vc2UoKTtcblxuZXhwb3J0IGNvbnN0IENhbGxUb29sUmVzdWx0U2NoZW1hID0gUmVzdWx0U2NoZW1hLmV4dGVuZCh7XG4gIGNvbnRlbnQ6IHouYXJyYXkoXG4gICAgei51bmlvbihbVGV4dENvbnRlbnRTY2hlbWEsIEltYWdlQ29udGVudFNjaGVtYSwgRW1iZWRkZWRSZXNvdXJjZVNjaGVtYV0pLFxuICApLFxuICBpc0Vycm9yOiB6LmJvb2xlYW4oKS5kZWZhdWx0KGZhbHNlKS5vcHRpb25hbCgpLFxufSkub3IoXG4gIFJlc3VsdFNjaGVtYS5leHRlbmQoe1xuICAgIHRvb2xSZXN1bHQ6IHoudW5rbm93bigpLFxuICB9KSxcbik7XG5leHBvcnQgdHlwZSBDYWxsVG9vbFJlc3VsdCA9IHouaW5mZXI8dHlwZW9mIENhbGxUb29sUmVzdWx0U2NoZW1hPjtcbiIsICJpbXBvcnQgeyBNQ1BDbGllbnRFcnJvciB9IGZyb20gJy4uLy4uL2Vycm9yL21jcC1jbGllbnQtZXJyb3InO1xuaW1wb3J0IHsgSlNPTlJQQ01lc3NhZ2UgfSBmcm9tICcuL2pzb24tcnBjLW1lc3NhZ2UnO1xuaW1wb3J0IHsgU3NlTUNQVHJhbnNwb3J0IH0gZnJvbSAnLi9tY3Atc3NlLXRyYW5zcG9ydCc7XG5cbi8qKlxuICogVHJhbnNwb3J0IGludGVyZmFjZSBmb3IgTUNQIChNb2RlbCBDb250ZXh0IFByb3RvY29sKSBjb21tdW5pY2F0aW9uLlxuICogTWFwcyB0byB0aGUgYFRyYW5zcG9ydGAgaW50ZXJmYWNlIGluIHRoZSBNQ1Agc3BlYy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBNQ1BUcmFuc3BvcnQge1xuICAvKipcbiAgICogSW5pdGlhbGl6ZSBhbmQgc3RhcnQgdGhlIHRyYW5zcG9ydFxuICAgKi9cbiAgc3RhcnQoKTogUHJvbWlzZTx2b2lkPjtcblxuICAvKipcbiAgICogU2VuZCBhIEpTT04tUlBDIG1lc3NhZ2UgdGhyb3VnaCB0aGUgdHJhbnNwb3J0XG4gICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBKU09OLVJQQyBtZXNzYWdlIHRvIHNlbmRcbiAgICovXG4gIHNlbmQobWVzc2FnZTogSlNPTlJQQ01lc3NhZ2UpOiBQcm9taXNlPHZvaWQ+O1xuXG4gIC8qKlxuICAgKiBDbGVhbiB1cCBhbmQgY2xvc2UgdGhlIHRyYW5zcG9ydFxuICAgKi9cbiAgY2xvc2UoKTogUHJvbWlzZTx2b2lkPjtcblxuICAvKipcbiAgICogRXZlbnQgaGFuZGxlciBmb3IgdHJhbnNwb3J0IGNsb3N1cmVcbiAgICovXG4gIG9uY2xvc2U/OiAoKSA9PiB2b2lkO1xuXG4gIC8qKlxuICAgKiBFdmVudCBoYW5kbGVyIGZvciB0cmFuc3BvcnQgZXJyb3JzXG4gICAqL1xuICBvbmVycm9yPzogKGVycm9yOiBFcnJvcikgPT4gdm9pZDtcblxuICAvKipcbiAgICogRXZlbnQgaGFuZGxlciBmb3IgcmVjZWl2ZWQgbWVzc2FnZXNcbiAgICovXG4gIG9ubWVzc2FnZT86IChtZXNzYWdlOiBKU09OUlBDTWVzc2FnZSkgPT4gdm9pZDtcbn1cblxuZXhwb3J0IHR5cGUgTUNQVHJhbnNwb3J0Q29uZmlnID0ge1xuICB0eXBlOiAnc3NlJztcblxuICAvKipcbiAgICogVGhlIFVSTCBvZiB0aGUgTUNQIHNlcnZlci5cbiAgICovXG4gIHVybDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBZGRpdGlvbmFsIEhUVFAgaGVhZGVycyB0byBiZSBzZW50IHdpdGggcmVxdWVzdHMuXG4gICAqL1xuICBoZWFkZXJzPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVNY3BUcmFuc3BvcnQoY29uZmlnOiBNQ1BUcmFuc3BvcnRDb25maWcpOiBNQ1BUcmFuc3BvcnQge1xuICBpZiAoY29uZmlnLnR5cGUgIT09ICdzc2UnKSB7XG4gICAgdGhyb3cgbmV3IE1DUENsaWVudEVycm9yKHtcbiAgICAgIG1lc3NhZ2U6XG4gICAgICAgICdVbnN1cHBvcnRlZCBvciBpbnZhbGlkIHRyYW5zcG9ydCBjb25maWd1cmF0aW9uLiBJZiB5b3UgYXJlIHVzaW5nIGEgY3VzdG9tIHRyYW5zcG9ydCwgbWFrZSBzdXJlIGl0IGltcGxlbWVudHMgdGhlIE1DUFRyYW5zcG9ydCBpbnRlcmZhY2UuJyxcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBuZXcgU3NlTUNQVHJhbnNwb3J0KGNvbmZpZyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0N1c3RvbU1jcFRyYW5zcG9ydChcbiAgdHJhbnNwb3J0OiBNQ1BUcmFuc3BvcnRDb25maWcgfCBNQ1BUcmFuc3BvcnQsXG4pOiB0cmFuc3BvcnQgaXMgTUNQVHJhbnNwb3J0IHtcbiAgcmV0dXJuIChcbiAgICAnc3RhcnQnIGluIHRyYW5zcG9ydCAmJlxuICAgIHR5cGVvZiB0cmFuc3BvcnQuc3RhcnQgPT09ICdmdW5jdGlvbicgJiZcbiAgICAnc2VuZCcgaW4gdHJhbnNwb3J0ICYmXG4gICAgdHlwZW9mIHRyYW5zcG9ydC5zZW5kID09PSAnZnVuY3Rpb24nICYmXG4gICAgJ2Nsb3NlJyBpbiB0cmFuc3BvcnQgJiZcbiAgICB0eXBlb2YgdHJhbnNwb3J0LmNsb3NlID09PSAnZnVuY3Rpb24nXG4gICk7XG59XG4iLCAiaW1wb3J0IHsgSlNPTlZhbHVlLCBUcmFuc2NyaXB0aW9uTW9kZWxWMiB9IGZyb20gJ0BhaS1zZGsvcHJvdmlkZXInO1xuaW1wb3J0IHsgUHJvdmlkZXJPcHRpb25zLCB3aXRoVXNlckFnZW50U3VmZml4IH0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyBOb1RyYW5zY3JpcHRHZW5lcmF0ZWRFcnJvciB9IGZyb20gJy4uL2Vycm9yL25vLXRyYW5zY3JpcHQtZ2VuZXJhdGVkLWVycm9yJztcbmltcG9ydCB7IFVuc3VwcG9ydGVkTW9kZWxWZXJzaW9uRXJyb3IgfSBmcm9tICcuLi9lcnJvci91bnN1cHBvcnRlZC1tb2RlbC12ZXJzaW9uLWVycm9yJztcbmltcG9ydCB7IGxvZ1dhcm5pbmdzIH0gZnJvbSAnLi4vbG9nZ2VyL2xvZy13YXJuaW5ncyc7XG5pbXBvcnQgeyBEYXRhQ29udGVudCB9IGZyb20gJy4uL3Byb21wdCc7XG5pbXBvcnQgeyBjb252ZXJ0RGF0YUNvbnRlbnRUb1VpbnQ4QXJyYXkgfSBmcm9tICcuLi9wcm9tcHQvZGF0YS1jb250ZW50JztcbmltcG9ydCB7IFRyYW5zY3JpcHRpb25XYXJuaW5nIH0gZnJvbSAnLi4vdHlwZXMvdHJhbnNjcmlwdGlvbi1tb2RlbCc7XG5pbXBvcnQgeyBUcmFuc2NyaXB0aW9uTW9kZWxSZXNwb25zZU1ldGFkYXRhIH0gZnJvbSAnLi4vdHlwZXMvdHJhbnNjcmlwdGlvbi1tb2RlbC1yZXNwb25zZS1tZXRhZGF0YSc7XG5pbXBvcnQge1xuICBhdWRpb01lZGlhVHlwZVNpZ25hdHVyZXMsXG4gIGRldGVjdE1lZGlhVHlwZSxcbn0gZnJvbSAnLi4vdXRpbC9kZXRlY3QtbWVkaWEtdHlwZSc7XG5pbXBvcnQgeyBkb3dubG9hZCB9IGZyb20gJy4uL3V0aWwvZG93bmxvYWQvZG93bmxvYWQnO1xuaW1wb3J0IHsgcHJlcGFyZVJldHJpZXMgfSBmcm9tICcuLi91dGlsL3ByZXBhcmUtcmV0cmllcyc7XG5pbXBvcnQgeyBUcmFuc2NyaXB0aW9uUmVzdWx0IH0gZnJvbSAnLi90cmFuc2NyaWJlLXJlc3VsdCc7XG5pbXBvcnQgeyBWRVJTSU9OIH0gZnJvbSAnLi4vdmVyc2lvbic7XG4vKipcbkdlbmVyYXRlcyB0cmFuc2NyaXB0cyB1c2luZyBhIHRyYW5zY3JpcHRpb24gbW9kZWwuXG5cbkBwYXJhbSBtb2RlbCAtIFRoZSB0cmFuc2NyaXB0aW9uIG1vZGVsIHRvIHVzZS5cbkBwYXJhbSBhdWRpbyAtIFRoZSBhdWRpbyBkYXRhIHRvIHRyYW5zY3JpYmUgYXMgRGF0YUNvbnRlbnQgKHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBBcnJheUJ1ZmZlciB8IEJ1ZmZlcikgb3IgYSBVUkwuXG5AcGFyYW0gcHJvdmlkZXJPcHRpb25zIC0gQWRkaXRpb25hbCBwcm92aWRlci1zcGVjaWZpYyBvcHRpb25zIHRoYXQgYXJlIHBhc3NlZCB0aHJvdWdoIHRvIHRoZSBwcm92aWRlclxuYXMgYm9keSBwYXJhbWV0ZXJzLlxuQHBhcmFtIG1heFJldHJpZXMgLSBNYXhpbXVtIG51bWJlciBvZiByZXRyaWVzLiBTZXQgdG8gMCB0byBkaXNhYmxlIHJldHJpZXMuIERlZmF1bHQ6IDIuXG5AcGFyYW0gYWJvcnRTaWduYWwgLSBBbiBvcHRpb25hbCBhYm9ydCBzaWduYWwgdGhhdCBjYW4gYmUgdXNlZCB0byBjYW5jZWwgdGhlIGNhbGwuXG5AcGFyYW0gaGVhZGVycyAtIEFkZGl0aW9uYWwgSFRUUCBoZWFkZXJzIHRvIGJlIHNlbnQgd2l0aCB0aGUgcmVxdWVzdC4gT25seSBhcHBsaWNhYmxlIGZvciBIVFRQLWJhc2VkIHByb3ZpZGVycy5cblxuQHJldHVybnMgQSByZXN1bHQgb2JqZWN0IHRoYXQgY29udGFpbnMgdGhlIGdlbmVyYXRlZCB0cmFuc2NyaXB0LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gdHJhbnNjcmliZSh7XG4gIG1vZGVsLFxuICBhdWRpbyxcbiAgcHJvdmlkZXJPcHRpb25zID0ge30sXG4gIG1heFJldHJpZXM6IG1heFJldHJpZXNBcmcsXG4gIGFib3J0U2lnbmFsLFxuICBoZWFkZXJzLFxufToge1xuICAvKipcblRoZSB0cmFuc2NyaXB0aW9uIG1vZGVsIHRvIHVzZS5cbiAgICAgKi9cbiAgbW9kZWw6IFRyYW5zY3JpcHRpb25Nb2RlbFYyO1xuXG4gIC8qKlxuVGhlIGF1ZGlvIGRhdGEgdG8gdHJhbnNjcmliZS5cbiAgICovXG4gIGF1ZGlvOiBEYXRhQ29udGVudCB8IFVSTDtcblxuICAvKipcbkFkZGl0aW9uYWwgcHJvdmlkZXItc3BlY2lmaWMgb3B0aW9ucyB0aGF0IGFyZSBwYXNzZWQgdGhyb3VnaCB0byB0aGUgcHJvdmlkZXJcbmFzIGJvZHkgcGFyYW1ldGVycy5cblxuVGhlIG91dGVyIHJlY29yZCBpcyBrZXllZCBieSB0aGUgcHJvdmlkZXIgbmFtZSwgYW5kIHRoZSBpbm5lclxucmVjb3JkIGlzIGtleWVkIGJ5IHRoZSBwcm92aWRlci1zcGVjaWZpYyBtZXRhZGF0YSBrZXkuXG5gYGB0c1xue1xuICBcIm9wZW5haVwiOiB7XG4gICAgXCJ0ZW1wZXJhdHVyZVwiOiAwXG4gIH1cbn1cbmBgYFxuICAgICAqL1xuICBwcm92aWRlck9wdGlvbnM/OiBQcm92aWRlck9wdGlvbnM7XG5cbiAgLyoqXG5NYXhpbXVtIG51bWJlciBvZiByZXRyaWVzIHBlciB0cmFuc2NyaXB0IG1vZGVsIGNhbGwuIFNldCB0byAwIHRvIGRpc2FibGUgcmV0cmllcy5cblxuQGRlZmF1bHQgMlxuICAgKi9cbiAgbWF4UmV0cmllcz86IG51bWJlcjtcblxuICAvKipcbkFib3J0IHNpZ25hbC5cbiAqL1xuICBhYm9ydFNpZ25hbD86IEFib3J0U2lnbmFsO1xuXG4gIC8qKlxuQWRkaXRpb25hbCBoZWFkZXJzIHRvIGluY2x1ZGUgaW4gdGhlIHJlcXVlc3QuXG5Pbmx5IGFwcGxpY2FibGUgZm9yIEhUVFAtYmFzZWQgcHJvdmlkZXJzLlxuICovXG4gIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xufSk6IFByb21pc2U8VHJhbnNjcmlwdGlvblJlc3VsdD4ge1xuICBpZiAobW9kZWwuc3BlY2lmaWNhdGlvblZlcnNpb24gIT09ICd2MicpIHtcbiAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRNb2RlbFZlcnNpb25FcnJvcih7XG4gICAgICB2ZXJzaW9uOiBtb2RlbC5zcGVjaWZpY2F0aW9uVmVyc2lvbixcbiAgICAgIHByb3ZpZGVyOiBtb2RlbC5wcm92aWRlcixcbiAgICAgIG1vZGVsSWQ6IG1vZGVsLm1vZGVsSWQsXG4gICAgfSk7XG4gIH1cblxuICBjb25zdCB7IHJldHJ5IH0gPSBwcmVwYXJlUmV0cmllcyh7XG4gICAgbWF4UmV0cmllczogbWF4UmV0cmllc0FyZyxcbiAgICBhYm9ydFNpZ25hbCxcbiAgfSk7XG5cbiAgY29uc3QgaGVhZGVyc1dpdGhVc2VyQWdlbnQgPSB3aXRoVXNlckFnZW50U3VmZml4KFxuICAgIGhlYWRlcnMgPz8ge30sXG4gICAgYGFpLyR7VkVSU0lPTn1gLFxuICApO1xuXG4gIGNvbnN0IGF1ZGlvRGF0YSA9XG4gICAgYXVkaW8gaW5zdGFuY2VvZiBVUkxcbiAgICAgID8gKGF3YWl0IGRvd25sb2FkKHsgdXJsOiBhdWRpbyB9KSkuZGF0YVxuICAgICAgOiBjb252ZXJ0RGF0YUNvbnRlbnRUb1VpbnQ4QXJyYXkoYXVkaW8pO1xuXG4gIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJldHJ5KCgpID0+XG4gICAgbW9kZWwuZG9HZW5lcmF0ZSh7XG4gICAgICBhdWRpbzogYXVkaW9EYXRhLFxuICAgICAgYWJvcnRTaWduYWwsXG4gICAgICBoZWFkZXJzOiBoZWFkZXJzV2l0aFVzZXJBZ2VudCxcbiAgICAgIHByb3ZpZGVyT3B0aW9ucyxcbiAgICAgIG1lZGlhVHlwZTpcbiAgICAgICAgZGV0ZWN0TWVkaWFUeXBlKHtcbiAgICAgICAgICBkYXRhOiBhdWRpb0RhdGEsXG4gICAgICAgICAgc2lnbmF0dXJlczogYXVkaW9NZWRpYVR5cGVTaWduYXR1cmVzLFxuICAgICAgICB9KSA/PyAnYXVkaW8vd2F2JyxcbiAgICB9KSxcbiAgKTtcblxuICBsb2dXYXJuaW5ncyhyZXN1bHQud2FybmluZ3MpO1xuXG4gIGlmICghcmVzdWx0LnRleHQpIHtcbiAgICB0aHJvdyBuZXcgTm9UcmFuc2NyaXB0R2VuZXJhdGVkRXJyb3IoeyByZXNwb25zZXM6IFtyZXN1bHQucmVzcG9uc2VdIH0pO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBEZWZhdWx0VHJhbnNjcmlwdGlvblJlc3VsdCh7XG4gICAgdGV4dDogcmVzdWx0LnRleHQsXG4gICAgc2VnbWVudHM6IHJlc3VsdC5zZWdtZW50cyxcbiAgICBsYW5ndWFnZTogcmVzdWx0Lmxhbmd1YWdlLFxuICAgIGR1cmF0aW9uSW5TZWNvbmRzOiByZXN1bHQuZHVyYXRpb25JblNlY29uZHMsXG4gICAgd2FybmluZ3M6IHJlc3VsdC53YXJuaW5ncyxcbiAgICByZXNwb25zZXM6IFtyZXN1bHQucmVzcG9uc2VdLFxuICAgIHByb3ZpZGVyTWV0YWRhdGE6IHJlc3VsdC5wcm92aWRlck1ldGFkYXRhLFxuICB9KTtcbn1cblxuY2xhc3MgRGVmYXVsdFRyYW5zY3JpcHRpb25SZXN1bHQgaW1wbGVtZW50cyBUcmFuc2NyaXB0aW9uUmVzdWx0IHtcbiAgcmVhZG9ubHkgdGV4dDogc3RyaW5nO1xuICByZWFkb25seSBzZWdtZW50czogQXJyYXk8e1xuICAgIHRleHQ6IHN0cmluZztcbiAgICBzdGFydFNlY29uZDogbnVtYmVyO1xuICAgIGVuZFNlY29uZDogbnVtYmVyO1xuICB9PjtcbiAgcmVhZG9ubHkgbGFuZ3VhZ2U6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgcmVhZG9ubHkgZHVyYXRpb25JblNlY29uZHM6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgcmVhZG9ubHkgd2FybmluZ3M6IEFycmF5PFRyYW5zY3JpcHRpb25XYXJuaW5nPjtcbiAgcmVhZG9ubHkgcmVzcG9uc2VzOiBBcnJheTxUcmFuc2NyaXB0aW9uTW9kZWxSZXNwb25zZU1ldGFkYXRhPjtcbiAgcmVhZG9ubHkgcHJvdmlkZXJNZXRhZGF0YTogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgSlNPTlZhbHVlPj47XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczoge1xuICAgIHRleHQ6IHN0cmluZztcbiAgICBzZWdtZW50czogQXJyYXk8e1xuICAgICAgdGV4dDogc3RyaW5nO1xuICAgICAgc3RhcnRTZWNvbmQ6IG51bWJlcjtcbiAgICAgIGVuZFNlY29uZDogbnVtYmVyO1xuICAgIH0+O1xuICAgIGxhbmd1YWdlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgZHVyYXRpb25JblNlY29uZHM6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgICB3YXJuaW5nczogQXJyYXk8VHJhbnNjcmlwdGlvbldhcm5pbmc+O1xuICAgIHJlc3BvbnNlczogQXJyYXk8VHJhbnNjcmlwdGlvbk1vZGVsUmVzcG9uc2VNZXRhZGF0YT47XG4gICAgcHJvdmlkZXJNZXRhZGF0YTogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgSlNPTlZhbHVlPj4gfCB1bmRlZmluZWQ7XG4gIH0pIHtcbiAgICB0aGlzLnRleHQgPSBvcHRpb25zLnRleHQ7XG4gICAgdGhpcy5zZWdtZW50cyA9IG9wdGlvbnMuc2VnbWVudHM7XG4gICAgdGhpcy5sYW5ndWFnZSA9IG9wdGlvbnMubGFuZ3VhZ2U7XG4gICAgdGhpcy5kdXJhdGlvbkluU2Vjb25kcyA9IG9wdGlvbnMuZHVyYXRpb25JblNlY29uZHM7XG4gICAgdGhpcy53YXJuaW5ncyA9IG9wdGlvbnMud2FybmluZ3M7XG4gICAgdGhpcy5yZXNwb25zZXMgPSBvcHRpb25zLnJlc3BvbnNlcztcbiAgICB0aGlzLnByb3ZpZGVyTWV0YWRhdGEgPSBvcHRpb25zLnByb3ZpZGVyTWV0YWRhdGEgPz8ge307XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBBSVNES0Vycm9yIH0gZnJvbSAnQGFpLXNkay9wcm92aWRlcic7XG5pbXBvcnQgeyBUcmFuc2NyaXB0aW9uTW9kZWxSZXNwb25zZU1ldGFkYXRhIH0gZnJvbSAnLi4vdHlwZXMvdHJhbnNjcmlwdGlvbi1tb2RlbC1yZXNwb25zZS1tZXRhZGF0YSc7XG5cbi8qKlxuRXJyb3IgdGhhdCBpcyB0aHJvd24gd2hlbiBubyB0cmFuc2NyaXB0IHdhcyBnZW5lcmF0ZWQuXG4gKi9cbmV4cG9ydCBjbGFzcyBOb1RyYW5zY3JpcHRHZW5lcmF0ZWRFcnJvciBleHRlbmRzIEFJU0RLRXJyb3Ige1xuICByZWFkb25seSByZXNwb25zZXM6IEFycmF5PFRyYW5zY3JpcHRpb25Nb2RlbFJlc3BvbnNlTWV0YWRhdGE+O1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IHtcbiAgICByZXNwb25zZXM6IEFycmF5PFRyYW5zY3JpcHRpb25Nb2RlbFJlc3BvbnNlTWV0YWRhdGE+O1xuICB9KSB7XG4gICAgc3VwZXIoe1xuICAgICAgbmFtZTogJ0FJX05vVHJhbnNjcmlwdEdlbmVyYXRlZEVycm9yJyxcbiAgICAgIG1lc3NhZ2U6ICdObyB0cmFuc2NyaXB0IGdlbmVyYXRlZC4nLFxuICAgIH0pO1xuXG4gICAgdGhpcy5yZXNwb25zZXMgPSBvcHRpb25zLnJlc3BvbnNlcztcbiAgfVxufVxuIiwgImltcG9ydCB7XG4gIHBhcnNlSnNvbkV2ZW50U3RyZWFtLFxuICBQYXJzZVJlc3VsdCxcbiAgd2l0aFVzZXJBZ2VudFN1ZmZpeCxcbiAgZ2V0UnVudGltZUVudmlyb25tZW50VXNlckFnZW50LFxufSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyLXV0aWxzJztcbmltcG9ydCB7XG4gIFVJTWVzc2FnZUNodW5rLFxuICB1aU1lc3NhZ2VDaHVua1NjaGVtYSxcbn0gZnJvbSAnLi4vdWktbWVzc2FnZS1zdHJlYW0vdWktbWVzc2FnZS1jaHVua3MnO1xuaW1wb3J0IHsgY29uc3VtZVN0cmVhbSB9IGZyb20gJy4uL3V0aWwvY29uc3VtZS1zdHJlYW0nO1xuaW1wb3J0IHsgcHJvY2Vzc1RleHRTdHJlYW0gfSBmcm9tICcuL3Byb2Nlc3MtdGV4dC1zdHJlYW0nO1xuaW1wb3J0IHsgVkVSU0lPTiB9IGZyb20gJy4uL3ZlcnNpb24nO1xuXG4vLyB1c2UgZnVuY3Rpb24gdG8gYWxsb3cgZm9yIG1vY2tpbmcgaW4gdGVzdHM6XG5jb25zdCBnZXRPcmlnaW5hbEZldGNoID0gKCkgPT4gZmV0Y2g7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjYWxsQ29tcGxldGlvbkFwaSh7XG4gIGFwaSxcbiAgcHJvbXB0LFxuICBjcmVkZW50aWFscyxcbiAgaGVhZGVycyxcbiAgYm9keSxcbiAgc3RyZWFtUHJvdG9jb2wgPSAnZGF0YScsXG4gIHNldENvbXBsZXRpb24sXG4gIHNldExvYWRpbmcsXG4gIHNldEVycm9yLFxuICBzZXRBYm9ydENvbnRyb2xsZXIsXG4gIG9uRmluaXNoLFxuICBvbkVycm9yLFxuICBmZXRjaCA9IGdldE9yaWdpbmFsRmV0Y2goKSxcbn06IHtcbiAgYXBpOiBzdHJpbmc7XG4gIHByb21wdDogc3RyaW5nO1xuICBjcmVkZW50aWFsczogUmVxdWVzdENyZWRlbnRpYWxzIHwgdW5kZWZpbmVkO1xuICBoZWFkZXJzOiBIZWFkZXJzSW5pdCB8IHVuZGVmaW5lZDtcbiAgYm9keTogUmVjb3JkPHN0cmluZywgYW55PjtcbiAgc3RyZWFtUHJvdG9jb2w6ICdkYXRhJyB8ICd0ZXh0JyB8IHVuZGVmaW5lZDtcbiAgc2V0Q29tcGxldGlvbjogKGNvbXBsZXRpb246IHN0cmluZykgPT4gdm9pZDtcbiAgc2V0TG9hZGluZzogKGxvYWRpbmc6IGJvb2xlYW4pID0+IHZvaWQ7XG4gIHNldEVycm9yOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkO1xuICBzZXRBYm9ydENvbnRyb2xsZXI6IChhYm9ydENvbnRyb2xsZXI6IEFib3J0Q29udHJvbGxlciB8IG51bGwpID0+IHZvaWQ7XG4gIG9uRmluaXNoOiAoKHByb21wdDogc3RyaW5nLCBjb21wbGV0aW9uOiBzdHJpbmcpID0+IHZvaWQpIHwgdW5kZWZpbmVkO1xuICBvbkVycm9yOiAoKGVycm9yOiBFcnJvcikgPT4gdm9pZCkgfCB1bmRlZmluZWQ7XG4gIGZldGNoOiBSZXR1cm5UeXBlPHR5cGVvZiBnZXRPcmlnaW5hbEZldGNoPiB8IHVuZGVmaW5lZDtcbn0pIHtcbiAgdHJ5IHtcbiAgICBzZXRMb2FkaW5nKHRydWUpO1xuICAgIHNldEVycm9yKHVuZGVmaW5lZCk7XG5cbiAgICBjb25zdCBhYm9ydENvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgc2V0QWJvcnRDb250cm9sbGVyKGFib3J0Q29udHJvbGxlcik7XG5cbiAgICAvLyBFbXB0eSB0aGUgY29tcGxldGlvbiBpbW1lZGlhdGVseS5cbiAgICBzZXRDb21wbGV0aW9uKCcnKTtcblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goYXBpLCB7XG4gICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgcHJvbXB0LFxuICAgICAgICAuLi5ib2R5LFxuICAgICAgfSksXG4gICAgICBjcmVkZW50aWFscyxcbiAgICAgIGhlYWRlcnM6IHdpdGhVc2VyQWdlbnRTdWZmaXgoXG4gICAgICAgIHtcbiAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICAgIC4uLmhlYWRlcnMsXG4gICAgICAgIH0sXG4gICAgICAgIGBhaS1zZGsvJHtWRVJTSU9OfWAsXG4gICAgICAgIGdldFJ1bnRpbWVFbnZpcm9ubWVudFVzZXJBZ2VudCgpLFxuICAgICAgKSxcbiAgICAgIHNpZ25hbDogYWJvcnRDb250cm9sbGVyLnNpZ25hbCxcbiAgICB9KS5jYXRjaChlcnIgPT4ge1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH0pO1xuXG4gICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAoYXdhaXQgcmVzcG9uc2UudGV4dCgpKSA/PyAnRmFpbGVkIHRvIGZldGNoIHRoZSBjaGF0IHJlc3BvbnNlLicsXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICghcmVzcG9uc2UuYm9keSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgcmVzcG9uc2UgYm9keSBpcyBlbXB0eS4nKTtcbiAgICB9XG5cbiAgICBsZXQgcmVzdWx0ID0gJyc7XG5cbiAgICBzd2l0Y2ggKHN0cmVhbVByb3RvY29sKSB7XG4gICAgICBjYXNlICd0ZXh0Jzoge1xuICAgICAgICBhd2FpdCBwcm9jZXNzVGV4dFN0cmVhbSh7XG4gICAgICAgICAgc3RyZWFtOiByZXNwb25zZS5ib2R5LFxuICAgICAgICAgIG9uVGV4dFBhcnQ6IGNodW5rID0+IHtcbiAgICAgICAgICAgIHJlc3VsdCArPSBjaHVuaztcbiAgICAgICAgICAgIHNldENvbXBsZXRpb24ocmVzdWx0KTtcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdkYXRhJzoge1xuICAgICAgICBhd2FpdCBjb25zdW1lU3RyZWFtKHtcbiAgICAgICAgICBzdHJlYW06IHBhcnNlSnNvbkV2ZW50U3RyZWFtKHtcbiAgICAgICAgICAgIHN0cmVhbTogcmVzcG9uc2UuYm9keSxcbiAgICAgICAgICAgIHNjaGVtYTogdWlNZXNzYWdlQ2h1bmtTY2hlbWEsXG4gICAgICAgICAgfSkucGlwZVRocm91Z2goXG4gICAgICAgICAgICBuZXcgVHJhbnNmb3JtU3RyZWFtPFBhcnNlUmVzdWx0PFVJTWVzc2FnZUNodW5rPiwgVUlNZXNzYWdlQ2h1bms+KHtcbiAgICAgICAgICAgICAgYXN5bmMgdHJhbnNmb3JtKHBhcnQpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXBhcnQuc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgICAgdGhyb3cgcGFydC5lcnJvcjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW1QYXJ0ID0gcGFydC52YWx1ZTtcbiAgICAgICAgICAgICAgICBpZiAoc3RyZWFtUGFydC50eXBlID09PSAndGV4dC1kZWx0YScpIHtcbiAgICAgICAgICAgICAgICAgIHJlc3VsdCArPSBzdHJlYW1QYXJ0LmRlbHRhO1xuICAgICAgICAgICAgICAgICAgc2V0Q29tcGxldGlvbihyZXN1bHQpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc3RyZWFtUGFydC50eXBlID09PSAnZXJyb3InKSB7XG4gICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3Ioc3RyZWFtUGFydC5lcnJvclRleHQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICksXG4gICAgICAgICAgb25FcnJvcjogZXJyb3IgPT4ge1xuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgZGVmYXVsdDoge1xuICAgICAgICBjb25zdCBleGhhdXN0aXZlQ2hlY2s6IG5ldmVyID0gc3RyZWFtUHJvdG9jb2w7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBzdHJlYW0gcHJvdG9jb2w6ICR7ZXhoYXVzdGl2ZUNoZWNrfWApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChvbkZpbmlzaCkge1xuICAgICAgb25GaW5pc2gocHJvbXB0LCByZXN1bHQpO1xuICAgIH1cblxuICAgIHNldEFib3J0Q29udHJvbGxlcihudWxsKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICAvLyBJZ25vcmUgYWJvcnQgZXJyb3JzIGFzIHRoZXkgYXJlIGV4cGVjdGVkLlxuICAgIGlmICgoZXJyIGFzIGFueSkubmFtZSA9PT0gJ0Fib3J0RXJyb3InKSB7XG4gICAgICBzZXRBYm9ydENvbnRyb2xsZXIobnVsbCk7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAoZXJyIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIGlmIChvbkVycm9yKSB7XG4gICAgICAgIG9uRXJyb3IoZXJyKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBzZXRFcnJvcihlcnIgYXMgRXJyb3IpO1xuICB9IGZpbmFsbHkge1xuICAgIHNldExvYWRpbmcoZmFsc2UpO1xuICB9XG59XG4iLCAiZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHByb2Nlc3NUZXh0U3RyZWFtKHtcbiAgc3RyZWFtLFxuICBvblRleHRQYXJ0LFxufToge1xuICBzdHJlYW06IFJlYWRhYmxlU3RyZWFtPFVpbnQ4QXJyYXk+O1xuICBvblRleHRQYXJ0OiAoY2h1bms6IHN0cmluZykgPT4gUHJvbWlzZTx2b2lkPiB8IHZvaWQ7XG59KTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHJlYWRlciA9IHN0cmVhbS5waXBlVGhyb3VnaChuZXcgVGV4dERlY29kZXJTdHJlYW0oKSkuZ2V0UmVhZGVyKCk7XG4gIHdoaWxlICh0cnVlKSB7XG4gICAgY29uc3QgeyBkb25lLCB2YWx1ZSB9ID0gYXdhaXQgcmVhZGVyLnJlYWQoKTtcbiAgICBpZiAoZG9uZSkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGF3YWl0IG9uVGV4dFBhcnQodmFsdWUpO1xuICB9XG59XG4iLCAiaW1wb3J0IHtcbiAgZ2VuZXJhdGVJZCBhcyBnZW5lcmF0ZUlkRnVuYyxcbiAgSWRHZW5lcmF0b3IsXG4gIFN0YW5kYXJkU2NoZW1hVjEsXG4gIFZhbGlkYXRvcixcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyBVSU1lc3NhZ2VDaHVuayB9IGZyb20gJy4uL3VpLW1lc3NhZ2Utc3RyZWFtL3VpLW1lc3NhZ2UtY2h1bmtzJztcbmltcG9ydCB7IGNvbnN1bWVTdHJlYW0gfSBmcm9tICcuLi91dGlsL2NvbnN1bWUtc3RyZWFtJztcbmltcG9ydCB7IFNlcmlhbEpvYkV4ZWN1dG9yIH0gZnJvbSAnLi4vdXRpbC9zZXJpYWwtam9iLWV4ZWN1dG9yJztcbmltcG9ydCB7IENoYXRUcmFuc3BvcnQgfSBmcm9tICcuL2NoYXQtdHJhbnNwb3J0JztcbmltcG9ydCB7IGNvbnZlcnRGaWxlTGlzdFRvRmlsZVVJUGFydHMgfSBmcm9tICcuL2NvbnZlcnQtZmlsZS1saXN0LXRvLWZpbGUtdWktcGFydHMnO1xuaW1wb3J0IHsgRGVmYXVsdENoYXRUcmFuc3BvcnQgfSBmcm9tICcuL2RlZmF1bHQtY2hhdC10cmFuc3BvcnQnO1xuaW1wb3J0IHtcbiAgY3JlYXRlU3RyZWFtaW5nVUlNZXNzYWdlU3RhdGUsXG4gIHByb2Nlc3NVSU1lc3NhZ2VTdHJlYW0sXG4gIFN0cmVhbWluZ1VJTWVzc2FnZVN0YXRlLFxufSBmcm9tICcuL3Byb2Nlc3MtdWktbWVzc2FnZS1zdHJlYW0nO1xuaW1wb3J0IHtcbiAgSW5mZXJVSU1lc3NhZ2VUb29sQ2FsbCxcbiAgaXNUb29sT3JEeW5hbWljVG9vbFVJUGFydCxcbiAgVG9vbFVJUGFydCxcbiAgdHlwZSBEYXRhVUlQYXJ0LFxuICB0eXBlIEZpbGVVSVBhcnQsXG4gIHR5cGUgSW5mZXJVSU1lc3NhZ2VEYXRhLFxuICB0eXBlIEluZmVyVUlNZXNzYWdlTWV0YWRhdGEsXG4gIHR5cGUgSW5mZXJVSU1lc3NhZ2VUb29scyxcbiAgdHlwZSBVSURhdGFUeXBlcyxcbiAgdHlwZSBVSU1lc3NhZ2UsXG59IGZyb20gJy4vdWktbWVzc2FnZXMnO1xuXG5leHBvcnQgdHlwZSBDcmVhdGVVSU1lc3NhZ2U8VUlfTUVTU0FHRSBleHRlbmRzIFVJTWVzc2FnZT4gPSBPbWl0PFxuICBVSV9NRVNTQUdFLFxuICAnaWQnIHwgJ3JvbGUnXG4+ICYge1xuICBpZD86IFVJX01FU1NBR0VbJ2lkJ107XG4gIHJvbGU/OiBVSV9NRVNTQUdFWydyb2xlJ107XG59O1xuXG5leHBvcnQgdHlwZSBVSURhdGFQYXJ0U2NoZW1hcyA9IFJlY29yZDxcbiAgc3RyaW5nLFxuICBWYWxpZGF0b3I8YW55PiB8IFN0YW5kYXJkU2NoZW1hVjE8YW55PlxuPjtcblxuZXhwb3J0IHR5cGUgVUlEYXRhVHlwZXNUb1NjaGVtYXM8VCBleHRlbmRzIFVJRGF0YVR5cGVzPiA9IHtcbiAgW0sgaW4ga2V5b2YgVF06IFZhbGlkYXRvcjxUW0tdPiB8IFN0YW5kYXJkU2NoZW1hVjE8VFtLXT47XG59O1xuXG5leHBvcnQgdHlwZSBJbmZlclVJRGF0YVBhcnRzPFQgZXh0ZW5kcyBVSURhdGFQYXJ0U2NoZW1hcz4gPSB7XG4gIFtLIGluIGtleW9mIFRdOiBUW0tdIGV4dGVuZHMgVmFsaWRhdG9yPGluZmVyIFU+XG4gICAgPyBVXG4gICAgOiBUW0tdIGV4dGVuZHMgU3RhbmRhcmRTY2hlbWFWMTxpbmZlciBVPlxuICAgICAgPyBVXG4gICAgICA6IHVua25vd247XG59O1xuXG5leHBvcnQgdHlwZSBDaGF0UmVxdWVzdE9wdGlvbnMgPSB7XG4gIC8qKlxuICBBZGRpdGlvbmFsIGhlYWRlcnMgdGhhdCBzaG91bGQgYmUgdG8gYmUgcGFzc2VkIHRvIHRoZSBBUEkgZW5kcG9pbnQuXG4gICAqL1xuICBoZWFkZXJzPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB8IEhlYWRlcnM7XG5cbiAgLyoqXG4gIEFkZGl0aW9uYWwgYm9keSBKU09OIHByb3BlcnRpZXMgdGhhdCBzaG91bGQgYmUgc2VudCB0byB0aGUgQVBJIGVuZHBvaW50LlxuICAgKi9cbiAgYm9keT86IG9iamVjdDsgLy8gVE9ETyBKU09OU3RyaW5naWZ5YWJsZVxuXG4gIG1ldGFkYXRhPzogdW5rbm93bjtcbn07XG5cbmV4cG9ydCB0eXBlIENoYXRTdGF0dXMgPSAnc3VibWl0dGVkJyB8ICdzdHJlYW1pbmcnIHwgJ3JlYWR5JyB8ICdlcnJvcic7XG5cbnR5cGUgQWN0aXZlUmVzcG9uc2U8VUlfTUVTU0FHRSBleHRlbmRzIFVJTWVzc2FnZT4gPSB7XG4gIHN0YXRlOiBTdHJlYW1pbmdVSU1lc3NhZ2VTdGF0ZTxVSV9NRVNTQUdFPjtcbiAgYWJvcnRDb250cm9sbGVyOiBBYm9ydENvbnRyb2xsZXI7XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIENoYXRTdGF0ZTxVSV9NRVNTQUdFIGV4dGVuZHMgVUlNZXNzYWdlPiB7XG4gIHN0YXR1czogQ2hhdFN0YXR1cztcblxuICBlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQ7XG5cbiAgbWVzc2FnZXM6IFVJX01FU1NBR0VbXTtcbiAgcHVzaE1lc3NhZ2U6IChtZXNzYWdlOiBVSV9NRVNTQUdFKSA9PiB2b2lkO1xuICBwb3BNZXNzYWdlOiAoKSA9PiB2b2lkO1xuICByZXBsYWNlTWVzc2FnZTogKGluZGV4OiBudW1iZXIsIG1lc3NhZ2U6IFVJX01FU1NBR0UpID0+IHZvaWQ7XG5cbiAgc25hcHNob3Q6IDxUPih0aGluZzogVCkgPT4gVDtcbn1cblxuZXhwb3J0IHR5cGUgQ2hhdE9uRXJyb3JDYWxsYmFjayA9IChlcnJvcjogRXJyb3IpID0+IHZvaWQ7XG5cbmV4cG9ydCB0eXBlIENoYXRPblRvb2xDYWxsQ2FsbGJhY2s8VUlfTUVTU0FHRSBleHRlbmRzIFVJTWVzc2FnZSA9IFVJTWVzc2FnZT4gPVxuICAob3B0aW9uczoge1xuICAgIHRvb2xDYWxsOiBJbmZlclVJTWVzc2FnZVRvb2xDYWxsPFVJX01FU1NBR0U+O1xuICB9KSA9PiB2b2lkIHwgUHJvbWlzZUxpa2U8dm9pZD47XG5cbmV4cG9ydCB0eXBlIENoYXRPbkRhdGFDYWxsYmFjazxVSV9NRVNTQUdFIGV4dGVuZHMgVUlNZXNzYWdlPiA9IChcbiAgZGF0YVBhcnQ6IERhdGFVSVBhcnQ8SW5mZXJVSU1lc3NhZ2VEYXRhPFVJX01FU1NBR0U+PixcbikgPT4gdm9pZDtcblxuLyoqXG4gKiBGdW5jdGlvbiB0aGF0IGlzIGNhbGxlZCB3aGVuIHRoZSBhc3Npc3RhbnQgcmVzcG9uc2UgaGFzIGZpbmlzaGVkIHN0cmVhbWluZy5cbiAqXG4gKiBAcGFyYW0gbWVzc2FnZSBUaGUgYXNzaXN0YW50IG1lc3NhZ2UgdGhhdCB3YXMgc3RyZWFtZWQuXG4gKiBAcGFyYW0gbWVzc2FnZXMgVGhlIGZ1bGwgY2hhdCBoaXN0b3J5LCBpbmNsdWRpbmcgdGhlIGFzc2lzdGFudCBtZXNzYWdlLlxuICpcbiAqIEBwYXJhbSBpc0Fib3J0IEluZGljYXRlcyB3aGV0aGVyIHRoZSByZXF1ZXN0IGhhcyBiZWVuIGFib3J0ZWQuXG4gKiBAcGFyYW0gaXNEaXNjb25uZWN0IEluZGljYXRlcyB3aGV0aGVyIHRoZSByZXF1ZXN0IGhhcyBiZWVuIGVuZGVkIGJ5IGEgbmV0d29yayBlcnJvci5cbiAqIEBwYXJhbSBpc0Vycm9yIEluZGljYXRlcyB3aGV0aGVyIHRoZSByZXF1ZXN0IGhhcyBiZWVuIGVuZGVkIGJ5IGFuIGVycm9yLlxuICovXG5leHBvcnQgdHlwZSBDaGF0T25GaW5pc2hDYWxsYmFjazxVSV9NRVNTQUdFIGV4dGVuZHMgVUlNZXNzYWdlPiA9IChvcHRpb25zOiB7XG4gIG1lc3NhZ2U6IFVJX01FU1NBR0U7XG4gIG1lc3NhZ2VzOiBVSV9NRVNTQUdFW107XG4gIGlzQWJvcnQ6IGJvb2xlYW47XG4gIGlzRGlzY29ubmVjdDogYm9vbGVhbjtcbiAgaXNFcnJvcjogYm9vbGVhbjtcbn0pID0+IHZvaWQ7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2hhdEluaXQ8VUlfTUVTU0FHRSBleHRlbmRzIFVJTWVzc2FnZT4ge1xuICAvKipcbiAgICogQSB1bmlxdWUgaWRlbnRpZmllciBmb3IgdGhlIGNoYXQuIElmIG5vdCBwcm92aWRlZCwgYSByYW5kb20gb25lIHdpbGwgYmVcbiAgICogZ2VuZXJhdGVkLlxuICAgKi9cbiAgaWQ/OiBzdHJpbmc7XG5cbiAgbWVzc2FnZU1ldGFkYXRhU2NoZW1hPzpcbiAgICB8IFZhbGlkYXRvcjxJbmZlclVJTWVzc2FnZU1ldGFkYXRhPFVJX01FU1NBR0U+PlxuICAgIHwgU3RhbmRhcmRTY2hlbWFWMTxJbmZlclVJTWVzc2FnZU1ldGFkYXRhPFVJX01FU1NBR0U+PjtcbiAgZGF0YVBhcnRTY2hlbWFzPzogVUlEYXRhVHlwZXNUb1NjaGVtYXM8SW5mZXJVSU1lc3NhZ2VEYXRhPFVJX01FU1NBR0U+PjtcblxuICBtZXNzYWdlcz86IFVJX01FU1NBR0VbXTtcblxuICAvKipcbiAgICogQSB3YXkgdG8gcHJvdmlkZSBhIGZ1bmN0aW9uIHRoYXQgaXMgZ29pbmcgdG8gYmUgdXNlZCBmb3IgaWRzIGZvciBtZXNzYWdlcyBhbmQgdGhlIGNoYXQuXG4gICAqIElmIG5vdCBwcm92aWRlZCB0aGUgZGVmYXVsdCBBSSBTREsgYGdlbmVyYXRlSWRgIGlzIHVzZWQuXG4gICAqL1xuICBnZW5lcmF0ZUlkPzogSWRHZW5lcmF0b3I7XG5cbiAgdHJhbnNwb3J0PzogQ2hhdFRyYW5zcG9ydDxVSV9NRVNTQUdFPjtcblxuICAvKipcbiAgICogQ2FsbGJhY2sgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdoZW4gYW4gZXJyb3IgaXMgZW5jb3VudGVyZWQuXG4gICAqL1xuICBvbkVycm9yPzogQ2hhdE9uRXJyb3JDYWxsYmFjaztcblxuICAvKipcbiAgT3B0aW9uYWwgY2FsbGJhY2sgZnVuY3Rpb24gdGhhdCBpcyBpbnZva2VkIHdoZW4gYSB0b29sIGNhbGwgaXMgcmVjZWl2ZWQuXG4gIEludGVuZGVkIGZvciBhdXRvbWF0aWMgY2xpZW50LXNpZGUgdG9vbCBleGVjdXRpb24uXG5cbiAgWW91IGNhbiBvcHRpb25hbGx5IHJldHVybiBhIHJlc3VsdCBmb3IgdGhlIHRvb2wgY2FsbCxcbiAgZWl0aGVyIHN5bmNocm9ub3VzbHkgb3IgYXN5bmNocm9ub3VzbHkuXG4gICAgICovXG4gIG9uVG9vbENhbGw/OiBDaGF0T25Ub29sQ2FsbENhbGxiYWNrPFVJX01FU1NBR0U+O1xuXG4gIC8qKlxuICAgKiBGdW5jdGlvbiB0aGF0IGlzIGNhbGxlZCB3aGVuIHRoZSBhc3Npc3RhbnQgcmVzcG9uc2UgaGFzIGZpbmlzaGVkIHN0cmVhbWluZy5cbiAgICovXG4gIG9uRmluaXNoPzogQ2hhdE9uRmluaXNoQ2FsbGJhY2s8VUlfTUVTU0FHRT47XG5cbiAgLyoqXG4gICAqIE9wdGlvbmFsIGNhbGxiYWNrIGZ1bmN0aW9uIHRoYXQgaXMgY2FsbGVkIHdoZW4gYSBkYXRhIHBhcnQgaXMgcmVjZWl2ZWQuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRhIFRoZSBkYXRhIHBhcnQgdGhhdCB3YXMgcmVjZWl2ZWQuXG4gICAqL1xuICBvbkRhdGE/OiBDaGF0T25EYXRhQ2FsbGJhY2s8VUlfTUVTU0FHRT47XG5cbiAgLyoqXG4gICAqIFdoZW4gcHJvdmlkZWQsIHRoaXMgZnVuY3Rpb24gd2lsbCBiZSBjYWxsZWQgd2hlbiB0aGUgc3RyZWFtIGlzIGZpbmlzaGVkIG9yIGEgdG9vbCBjYWxsIGlzIGFkZGVkXG4gICAqIHRvIGRldGVybWluZSBpZiB0aGUgY3VycmVudCBtZXNzYWdlcyBzaG91bGQgYmUgcmVzdWJtaXR0ZWQuXG4gICAqL1xuICBzZW5kQXV0b21hdGljYWxseVdoZW4/OiAob3B0aW9uczoge1xuICAgIG1lc3NhZ2VzOiBVSV9NRVNTQUdFW107XG4gIH0pID0+IGJvb2xlYW4gfCBQcm9taXNlTGlrZTxib29sZWFuPjtcbn1cblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEFic3RyYWN0Q2hhdDxVSV9NRVNTQUdFIGV4dGVuZHMgVUlNZXNzYWdlPiB7XG4gIHJlYWRvbmx5IGlkOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGdlbmVyYXRlSWQ6IElkR2VuZXJhdG9yO1xuXG4gIHByb3RlY3RlZCBzdGF0ZTogQ2hhdFN0YXRlPFVJX01FU1NBR0U+O1xuXG4gIHByaXZhdGUgbWVzc2FnZU1ldGFkYXRhU2NoZW1hOlxuICAgIHwgVmFsaWRhdG9yPEluZmVyVUlNZXNzYWdlTWV0YWRhdGE8VUlfTUVTU0FHRT4+XG4gICAgfCBTdGFuZGFyZFNjaGVtYVYxPEluZmVyVUlNZXNzYWdlTWV0YWRhdGE8VUlfTUVTU0FHRT4+XG4gICAgfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgZGF0YVBhcnRTY2hlbWFzOlxuICAgIHwgVUlEYXRhVHlwZXNUb1NjaGVtYXM8SW5mZXJVSU1lc3NhZ2VEYXRhPFVJX01FU1NBR0U+PlxuICAgIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIHJlYWRvbmx5IHRyYW5zcG9ydDogQ2hhdFRyYW5zcG9ydDxVSV9NRVNTQUdFPjtcbiAgcHJpdmF0ZSBvbkVycm9yPzogQ2hhdEluaXQ8VUlfTUVTU0FHRT5bJ29uRXJyb3InXTtcbiAgcHJpdmF0ZSBvblRvb2xDYWxsPzogQ2hhdEluaXQ8VUlfTUVTU0FHRT5bJ29uVG9vbENhbGwnXTtcbiAgcHJpdmF0ZSBvbkZpbmlzaD86IENoYXRJbml0PFVJX01FU1NBR0U+WydvbkZpbmlzaCddO1xuICBwcml2YXRlIG9uRGF0YT86IENoYXRJbml0PFVJX01FU1NBR0U+WydvbkRhdGEnXTtcbiAgcHJpdmF0ZSBzZW5kQXV0b21hdGljYWxseVdoZW4/OiBDaGF0SW5pdDxVSV9NRVNTQUdFPlsnc2VuZEF1dG9tYXRpY2FsbHlXaGVuJ107XG5cbiAgcHJpdmF0ZSBhY3RpdmVSZXNwb25zZTogQWN0aXZlUmVzcG9uc2U8VUlfTUVTU0FHRT4gfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gIHByaXZhdGUgam9iRXhlY3V0b3IgPSBuZXcgU2VyaWFsSm9iRXhlY3V0b3IoKTtcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgZ2VuZXJhdGVJZCA9IGdlbmVyYXRlSWRGdW5jLFxuICAgIGlkID0gZ2VuZXJhdGVJZCgpLFxuICAgIHRyYW5zcG9ydCA9IG5ldyBEZWZhdWx0Q2hhdFRyYW5zcG9ydCgpLFxuICAgIG1lc3NhZ2VNZXRhZGF0YVNjaGVtYSxcbiAgICBkYXRhUGFydFNjaGVtYXMsXG4gICAgc3RhdGUsXG4gICAgb25FcnJvcixcbiAgICBvblRvb2xDYWxsLFxuICAgIG9uRmluaXNoLFxuICAgIG9uRGF0YSxcbiAgICBzZW5kQXV0b21hdGljYWxseVdoZW4sXG4gIH06IE9taXQ8Q2hhdEluaXQ8VUlfTUVTU0FHRT4sICdtZXNzYWdlcyc+ICYge1xuICAgIHN0YXRlOiBDaGF0U3RhdGU8VUlfTUVTU0FHRT47XG4gIH0pIHtcbiAgICB0aGlzLmlkID0gaWQ7XG4gICAgdGhpcy50cmFuc3BvcnQgPSB0cmFuc3BvcnQ7XG4gICAgdGhpcy5nZW5lcmF0ZUlkID0gZ2VuZXJhdGVJZDtcbiAgICB0aGlzLm1lc3NhZ2VNZXRhZGF0YVNjaGVtYSA9IG1lc3NhZ2VNZXRhZGF0YVNjaGVtYTtcbiAgICB0aGlzLmRhdGFQYXJ0U2NoZW1hcyA9IGRhdGFQYXJ0U2NoZW1hcztcbiAgICB0aGlzLnN0YXRlID0gc3RhdGU7XG4gICAgdGhpcy5vbkVycm9yID0gb25FcnJvcjtcbiAgICB0aGlzLm9uVG9vbENhbGwgPSBvblRvb2xDYWxsO1xuICAgIHRoaXMub25GaW5pc2ggPSBvbkZpbmlzaDtcbiAgICB0aGlzLm9uRGF0YSA9IG9uRGF0YTtcbiAgICB0aGlzLnNlbmRBdXRvbWF0aWNhbGx5V2hlbiA9IHNlbmRBdXRvbWF0aWNhbGx5V2hlbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBIb29rIHN0YXR1czpcbiAgICpcbiAgICogLSBgc3VibWl0dGVkYDogVGhlIG1lc3NhZ2UgaGFzIGJlZW4gc2VudCB0byB0aGUgQVBJIGFuZCB3ZSdyZSBhd2FpdGluZyB0aGUgc3RhcnQgb2YgdGhlIHJlc3BvbnNlIHN0cmVhbS5cbiAgICogLSBgc3RyZWFtaW5nYDogVGhlIHJlc3BvbnNlIGlzIGFjdGl2ZWx5IHN0cmVhbWluZyBpbiBmcm9tIHRoZSBBUEksIHJlY2VpdmluZyBjaHVua3Mgb2YgZGF0YS5cbiAgICogLSBgcmVhZHlgOiBUaGUgZnVsbCByZXNwb25zZSBoYXMgYmVlbiByZWNlaXZlZCBhbmQgcHJvY2Vzc2VkOyBhIG5ldyB1c2VyIG1lc3NhZ2UgY2FuIGJlIHN1Ym1pdHRlZC5cbiAgICogLSBgZXJyb3JgOiBBbiBlcnJvciBvY2N1cnJlZCBkdXJpbmcgdGhlIEFQSSByZXF1ZXN0LCBwcmV2ZW50aW5nIHN1Y2Nlc3NmdWwgY29tcGxldGlvbi5cbiAgICovXG4gIGdldCBzdGF0dXMoKTogQ2hhdFN0YXR1cyB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdGUuc3RhdHVzO1xuICB9XG5cbiAgcHJvdGVjdGVkIHNldFN0YXR1cyh7XG4gICAgc3RhdHVzLFxuICAgIGVycm9yLFxuICB9OiB7XG4gICAgc3RhdHVzOiBDaGF0U3RhdHVzO1xuICAgIGVycm9yPzogRXJyb3I7XG4gIH0pIHtcbiAgICBpZiAodGhpcy5zdGF0dXMgPT09IHN0YXR1cykgcmV0dXJuO1xuXG4gICAgdGhpcy5zdGF0ZS5zdGF0dXMgPSBzdGF0dXM7XG4gICAgdGhpcy5zdGF0ZS5lcnJvciA9IGVycm9yO1xuICB9XG5cbiAgZ2V0IGVycm9yKCkge1xuICAgIHJldHVybiB0aGlzLnN0YXRlLmVycm9yO1xuICB9XG5cbiAgZ2V0IG1lc3NhZ2VzKCk6IFVJX01FU1NBR0VbXSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdGUubWVzc2FnZXM7XG4gIH1cblxuICBnZXQgbGFzdE1lc3NhZ2UoKTogVUlfTUVTU0FHRSB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdGUubWVzc2FnZXNbdGhpcy5zdGF0ZS5tZXNzYWdlcy5sZW5ndGggLSAxXTtcbiAgfVxuXG4gIHNldCBtZXNzYWdlcyhtZXNzYWdlczogVUlfTUVTU0FHRVtdKSB7XG4gICAgdGhpcy5zdGF0ZS5tZXNzYWdlcyA9IG1lc3NhZ2VzO1xuICB9XG5cbiAgLyoqXG4gICAqIEFwcGVuZHMgb3IgcmVwbGFjZXMgYSB1c2VyIG1lc3NhZ2UgdG8gdGhlIGNoYXQgbGlzdC4gVGhpcyB0cmlnZ2VycyB0aGUgQVBJIGNhbGwgdG8gZmV0Y2hcbiAgICogdGhlIGFzc2lzdGFudCdzIHJlc3BvbnNlLlxuICAgKlxuICAgKiBJZiBhIG1lc3NhZ2VJZCBpcyBwcm92aWRlZCwgdGhlIG1lc3NhZ2Ugd2lsbCBiZSByZXBsYWNlZC5cbiAgICovXG4gIHNlbmRNZXNzYWdlID0gYXN5bmMgKFxuICAgIG1lc3NhZ2U/OlxuICAgICAgfCAoQ3JlYXRlVUlNZXNzYWdlPFVJX01FU1NBR0U+ICYge1xuICAgICAgICAgIHRleHQ/OiBuZXZlcjtcbiAgICAgICAgICBmaWxlcz86IG5ldmVyO1xuICAgICAgICAgIG1lc3NhZ2VJZD86IHN0cmluZztcbiAgICAgICAgfSlcbiAgICAgIHwge1xuICAgICAgICAgIHRleHQ6IHN0cmluZztcbiAgICAgICAgICBmaWxlcz86IEZpbGVMaXN0IHwgRmlsZVVJUGFydFtdO1xuICAgICAgICAgIG1ldGFkYXRhPzogSW5mZXJVSU1lc3NhZ2VNZXRhZGF0YTxVSV9NRVNTQUdFPjtcbiAgICAgICAgICBwYXJ0cz86IG5ldmVyO1xuICAgICAgICAgIG1lc3NhZ2VJZD86IHN0cmluZztcbiAgICAgICAgfVxuICAgICAgfCB7XG4gICAgICAgICAgZmlsZXM6IEZpbGVMaXN0IHwgRmlsZVVJUGFydFtdO1xuICAgICAgICAgIG1ldGFkYXRhPzogSW5mZXJVSU1lc3NhZ2VNZXRhZGF0YTxVSV9NRVNTQUdFPjtcbiAgICAgICAgICBwYXJ0cz86IG5ldmVyO1xuICAgICAgICAgIG1lc3NhZ2VJZD86IHN0cmluZztcbiAgICAgICAgfSxcbiAgICBvcHRpb25zPzogQ2hhdFJlcXVlc3RPcHRpb25zLFxuICApOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICBpZiAobWVzc2FnZSA9PSBudWxsKSB7XG4gICAgICBhd2FpdCB0aGlzLm1ha2VSZXF1ZXN0KHtcbiAgICAgICAgdHJpZ2dlcjogJ3N1Ym1pdC1tZXNzYWdlJyxcbiAgICAgICAgbWVzc2FnZUlkOiB0aGlzLmxhc3RNZXNzYWdlPy5pZCxcbiAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCB1aU1lc3NhZ2U6IENyZWF0ZVVJTWVzc2FnZTxVSV9NRVNTQUdFPjtcblxuICAgIGlmICgndGV4dCcgaW4gbWVzc2FnZSB8fCAnZmlsZXMnIGluIG1lc3NhZ2UpIHtcbiAgICAgIGNvbnN0IGZpbGVQYXJ0cyA9IEFycmF5LmlzQXJyYXkobWVzc2FnZS5maWxlcylcbiAgICAgICAgPyBtZXNzYWdlLmZpbGVzXG4gICAgICAgIDogYXdhaXQgY29udmVydEZpbGVMaXN0VG9GaWxlVUlQYXJ0cyhtZXNzYWdlLmZpbGVzKTtcblxuICAgICAgdWlNZXNzYWdlID0ge1xuICAgICAgICBwYXJ0czogW1xuICAgICAgICAgIC4uLmZpbGVQYXJ0cyxcbiAgICAgICAgICAuLi4oJ3RleHQnIGluIG1lc3NhZ2UgJiYgbWVzc2FnZS50ZXh0ICE9IG51bGxcbiAgICAgICAgICAgID8gW3sgdHlwZTogJ3RleHQnIGFzIGNvbnN0LCB0ZXh0OiBtZXNzYWdlLnRleHQgfV1cbiAgICAgICAgICAgIDogW10pLFxuICAgICAgICBdLFxuICAgICAgfSBhcyBVSV9NRVNTQUdFO1xuICAgIH0gZWxzZSB7XG4gICAgICB1aU1lc3NhZ2UgPSBtZXNzYWdlO1xuICAgIH1cblxuICAgIGlmIChtZXNzYWdlLm1lc3NhZ2VJZCAhPSBudWxsKSB7XG4gICAgICBjb25zdCBtZXNzYWdlSW5kZXggPSB0aGlzLnN0YXRlLm1lc3NhZ2VzLmZpbmRJbmRleChcbiAgICAgICAgbSA9PiBtLmlkID09PSBtZXNzYWdlLm1lc3NhZ2VJZCxcbiAgICAgICk7XG5cbiAgICAgIGlmIChtZXNzYWdlSW5kZXggPT09IC0xKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgbWVzc2FnZSB3aXRoIGlkICR7bWVzc2FnZS5tZXNzYWdlSWR9IG5vdCBmb3VuZGApO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5zdGF0ZS5tZXNzYWdlc1ttZXNzYWdlSW5kZXhdLnJvbGUgIT09ICd1c2VyJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYG1lc3NhZ2Ugd2l0aCBpZCAke21lc3NhZ2UubWVzc2FnZUlkfSBpcyBub3QgYSB1c2VyIG1lc3NhZ2VgLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICAvLyByZW1vdmUgYWxsIG1lc3NhZ2VzIGFmdGVyIHRoZSBtZXNzYWdlIHdpdGggdGhlIGdpdmVuIGlkXG4gICAgICB0aGlzLnN0YXRlLm1lc3NhZ2VzID0gdGhpcy5zdGF0ZS5tZXNzYWdlcy5zbGljZSgwLCBtZXNzYWdlSW5kZXggKyAxKTtcblxuICAgICAgLy8gdXBkYXRlIHRoZSBtZXNzYWdlIHdpdGggdGhlIG5ldyBjb250ZW50XG4gICAgICB0aGlzLnN0YXRlLnJlcGxhY2VNZXNzYWdlKG1lc3NhZ2VJbmRleCwge1xuICAgICAgICAuLi51aU1lc3NhZ2UsXG4gICAgICAgIGlkOiBtZXNzYWdlLm1lc3NhZ2VJZCxcbiAgICAgICAgcm9sZTogdWlNZXNzYWdlLnJvbGUgPz8gJ3VzZXInLFxuICAgICAgICBtZXRhZGF0YTogbWVzc2FnZS5tZXRhZGF0YSxcbiAgICAgIH0gYXMgVUlfTUVTU0FHRSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc3RhdGUucHVzaE1lc3NhZ2Uoe1xuICAgICAgICAuLi51aU1lc3NhZ2UsXG4gICAgICAgIGlkOiB1aU1lc3NhZ2UuaWQgPz8gdGhpcy5nZW5lcmF0ZUlkKCksXG4gICAgICAgIHJvbGU6IHVpTWVzc2FnZS5yb2xlID8/ICd1c2VyJyxcbiAgICAgICAgbWV0YWRhdGE6IG1lc3NhZ2UubWV0YWRhdGEsXG4gICAgICB9IGFzIFVJX01FU1NBR0UpO1xuICAgIH1cblxuICAgIGF3YWl0IHRoaXMubWFrZVJlcXVlc3Qoe1xuICAgICAgdHJpZ2dlcjogJ3N1Ym1pdC1tZXNzYWdlJyxcbiAgICAgIG1lc3NhZ2VJZDogbWVzc2FnZS5tZXNzYWdlSWQsXG4gICAgICAuLi5vcHRpb25zLFxuICAgIH0pO1xuICB9O1xuXG4gIC8qKlxuICAgKiBSZWdlbmVyYXRlIHRoZSBhc3Npc3RhbnQgbWVzc2FnZSB3aXRoIHRoZSBwcm92aWRlZCBtZXNzYWdlIGlkLlxuICAgKiBJZiBubyBtZXNzYWdlIGlkIGlzIHByb3ZpZGVkLCB0aGUgbGFzdCBhc3Npc3RhbnQgbWVzc2FnZSB3aWxsIGJlIHJlZ2VuZXJhdGVkLlxuICAgKi9cbiAgcmVnZW5lcmF0ZSA9IGFzeW5jICh7XG4gICAgbWVzc2FnZUlkLFxuICAgIC4uLm9wdGlvbnNcbiAgfToge1xuICAgIG1lc3NhZ2VJZD86IHN0cmluZztcbiAgfSAmIENoYXRSZXF1ZXN0T3B0aW9ucyA9IHt9KTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgY29uc3QgbWVzc2FnZUluZGV4ID1cbiAgICAgIG1lc3NhZ2VJZCA9PSBudWxsXG4gICAgICAgID8gdGhpcy5zdGF0ZS5tZXNzYWdlcy5sZW5ndGggLSAxXG4gICAgICAgIDogdGhpcy5zdGF0ZS5tZXNzYWdlcy5maW5kSW5kZXgobWVzc2FnZSA9PiBtZXNzYWdlLmlkID09PSBtZXNzYWdlSWQpO1xuXG4gICAgaWYgKG1lc3NhZ2VJbmRleCA9PT0gLTEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgbWVzc2FnZSAke21lc3NhZ2VJZH0gbm90IGZvdW5kYCk7XG4gICAgfVxuXG4gICAgLy8gc2V0IHRoZSBtZXNzYWdlcyB0byB0aGUgbWVzc2FnZSBiZWZvcmUgdGhlIGFzc2lzdGFudCBtZXNzYWdlXG4gICAgdGhpcy5zdGF0ZS5tZXNzYWdlcyA9IHRoaXMuc3RhdGUubWVzc2FnZXMuc2xpY2UoXG4gICAgICAwLFxuICAgICAgLy8gaWYgdGhlIG1lc3NhZ2UgaXMgYSB1c2VyIG1lc3NhZ2UsIHdlIG5lZWQgdG8gaW5jbHVkZSBpdCBpbiB0aGUgcmVxdWVzdDpcbiAgICAgIHRoaXMubWVzc2FnZXNbbWVzc2FnZUluZGV4XS5yb2xlID09PSAnYXNzaXN0YW50J1xuICAgICAgICA/IG1lc3NhZ2VJbmRleFxuICAgICAgICA6IG1lc3NhZ2VJbmRleCArIDEsXG4gICAgKTtcblxuICAgIGF3YWl0IHRoaXMubWFrZVJlcXVlc3Qoe1xuICAgICAgdHJpZ2dlcjogJ3JlZ2VuZXJhdGUtbWVzc2FnZScsXG4gICAgICBtZXNzYWdlSWQsXG4gICAgICAuLi5vcHRpb25zLFxuICAgIH0pO1xuICB9O1xuXG4gIC8qKlxuICAgKiBBdHRlbXB0IHRvIHJlc3VtZSBhbiBvbmdvaW5nIHN0cmVhbWluZyByZXNwb25zZS5cbiAgICovXG4gIHJlc3VtZVN0cmVhbSA9IGFzeW5jIChvcHRpb25zOiBDaGF0UmVxdWVzdE9wdGlvbnMgPSB7fSk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIGF3YWl0IHRoaXMubWFrZVJlcXVlc3QoeyB0cmlnZ2VyOiAncmVzdW1lLXN0cmVhbScsIC4uLm9wdGlvbnMgfSk7XG4gIH07XG5cbiAgLyoqXG4gICAqIENsZWFyIHRoZSBlcnJvciBzdGF0ZSBhbmQgc2V0IHRoZSBzdGF0dXMgdG8gcmVhZHkgaWYgdGhlIGNoYXQgaXMgaW4gYW4gZXJyb3Igc3RhdGUuXG4gICAqL1xuICBjbGVhckVycm9yID0gKCkgPT4ge1xuICAgIGlmICh0aGlzLnN0YXR1cyA9PT0gJ2Vycm9yJykge1xuICAgICAgdGhpcy5zdGF0ZS5lcnJvciA9IHVuZGVmaW5lZDtcbiAgICAgIHRoaXMuc2V0U3RhdHVzKHsgc3RhdHVzOiAncmVhZHknIH0pO1xuICAgIH1cbiAgfTtcblxuICBhZGRUb29sUmVzdWx0ID0gYXN5bmMgPFRPT0wgZXh0ZW5kcyBrZXlvZiBJbmZlclVJTWVzc2FnZVRvb2xzPFVJX01FU1NBR0U+Pih7XG4gICAgc3RhdGUgPSAnb3V0cHV0LWF2YWlsYWJsZScsXG4gICAgdG9vbCxcbiAgICB0b29sQ2FsbElkLFxuICAgIG91dHB1dCxcbiAgICBlcnJvclRleHQsXG4gIH06XG4gICAgfCB7XG4gICAgICAgIHN0YXRlPzogJ291dHB1dC1hdmFpbGFibGUnO1xuICAgICAgICB0b29sOiBUT09MO1xuICAgICAgICB0b29sQ2FsbElkOiBzdHJpbmc7XG4gICAgICAgIG91dHB1dDogSW5mZXJVSU1lc3NhZ2VUb29sczxVSV9NRVNTQUdFPltUT09MXVsnb3V0cHV0J107XG4gICAgICAgIGVycm9yVGV4dD86IG5ldmVyO1xuICAgICAgfVxuICAgIHwge1xuICAgICAgICBzdGF0ZTogJ291dHB1dC1lcnJvcic7XG4gICAgICAgIHRvb2w6IFRPT0w7XG4gICAgICAgIHRvb2xDYWxsSWQ6IHN0cmluZztcbiAgICAgICAgb3V0cHV0PzogbmV2ZXI7XG4gICAgICAgIGVycm9yVGV4dDogc3RyaW5nO1xuICAgICAgfSkgPT5cbiAgICB0aGlzLmpvYkV4ZWN1dG9yLnJ1bihhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBtZXNzYWdlcyA9IHRoaXMuc3RhdGUubWVzc2FnZXM7XG4gICAgICBjb25zdCBsYXN0TWVzc2FnZSA9IG1lc3NhZ2VzW21lc3NhZ2VzLmxlbmd0aCAtIDFdO1xuXG4gICAgICB0aGlzLnN0YXRlLnJlcGxhY2VNZXNzYWdlKG1lc3NhZ2VzLmxlbmd0aCAtIDEsIHtcbiAgICAgICAgLi4ubGFzdE1lc3NhZ2UsXG4gICAgICAgIHBhcnRzOiBsYXN0TWVzc2FnZS5wYXJ0cy5tYXAocGFydCA9PlxuICAgICAgICAgIGlzVG9vbE9yRHluYW1pY1Rvb2xVSVBhcnQocGFydCkgJiYgcGFydC50b29sQ2FsbElkID09PSB0b29sQ2FsbElkXG4gICAgICAgICAgICA/IHsgLi4ucGFydCwgc3RhdGUsIG91dHB1dCwgZXJyb3JUZXh0IH1cbiAgICAgICAgICAgIDogcGFydCxcbiAgICAgICAgKSxcbiAgICAgIH0pO1xuXG4gICAgICAvLyB1cGRhdGUgdGhlIGFjdGl2ZSByZXNwb25zZSBpZiBpdCBleGlzdHNcbiAgICAgIGlmICh0aGlzLmFjdGl2ZVJlc3BvbnNlKSB7XG4gICAgICAgIHRoaXMuYWN0aXZlUmVzcG9uc2Uuc3RhdGUubWVzc2FnZS5wYXJ0cyA9XG4gICAgICAgICAgdGhpcy5hY3RpdmVSZXNwb25zZS5zdGF0ZS5tZXNzYWdlLnBhcnRzLm1hcChwYXJ0ID0+XG4gICAgICAgICAgICBpc1Rvb2xPckR5bmFtaWNUb29sVUlQYXJ0KHBhcnQpICYmIHBhcnQudG9vbENhbGxJZCA9PT0gdG9vbENhbGxJZFxuICAgICAgICAgICAgICA/ICh7XG4gICAgICAgICAgICAgICAgICAuLi5wYXJ0LFxuICAgICAgICAgICAgICAgICAgc3RhdGUsXG4gICAgICAgICAgICAgICAgICBvdXRwdXQsXG4gICAgICAgICAgICAgICAgICBlcnJvclRleHQsXG4gICAgICAgICAgICAgICAgfSBhcyB0eXBlb2YgcGFydClcbiAgICAgICAgICAgICAgOiBwYXJ0LFxuICAgICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIC8vIGF1dG9tYXRpY2FsbHkgc2VuZCB0aGUgbWVzc2FnZSBpZiB0aGUgc2VuZEF1dG9tYXRpY2FsbHlXaGVuIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZVxuICAgICAgaWYgKFxuICAgICAgICB0aGlzLnN0YXR1cyAhPT0gJ3N0cmVhbWluZycgJiZcbiAgICAgICAgdGhpcy5zdGF0dXMgIT09ICdzdWJtaXR0ZWQnICYmXG4gICAgICAgIHRoaXMuc2VuZEF1dG9tYXRpY2FsbHlXaGVuPy4oeyBtZXNzYWdlczogdGhpcy5zdGF0ZS5tZXNzYWdlcyB9KVxuICAgICAgKSB7XG4gICAgICAgIC8vIG5vIGF3YWl0IHRvIGF2b2lkIGRlYWRsb2NraW5nXG4gICAgICAgIHRoaXMubWFrZVJlcXVlc3Qoe1xuICAgICAgICAgIHRyaWdnZXI6ICdzdWJtaXQtbWVzc2FnZScsXG4gICAgICAgICAgbWVzc2FnZUlkOiB0aGlzLmxhc3RNZXNzYWdlPy5pZCxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgLyoqXG4gICAqIEFib3J0IHRoZSBjdXJyZW50IHJlcXVlc3QgaW1tZWRpYXRlbHksIGtlZXAgdGhlIGdlbmVyYXRlZCB0b2tlbnMgaWYgYW55LlxuICAgKi9cbiAgc3RvcCA9IGFzeW5jICgpID0+IHtcbiAgICBpZiAodGhpcy5zdGF0dXMgIT09ICdzdHJlYW1pbmcnICYmIHRoaXMuc3RhdHVzICE9PSAnc3VibWl0dGVkJykgcmV0dXJuO1xuXG4gICAgaWYgKHRoaXMuYWN0aXZlUmVzcG9uc2U/LmFib3J0Q29udHJvbGxlcikge1xuICAgICAgdGhpcy5hY3RpdmVSZXNwb25zZS5hYm9ydENvbnRyb2xsZXIuYWJvcnQoKTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBhc3luYyBtYWtlUmVxdWVzdCh7XG4gICAgdHJpZ2dlcixcbiAgICBtZXRhZGF0YSxcbiAgICBoZWFkZXJzLFxuICAgIGJvZHksXG4gICAgbWVzc2FnZUlkLFxuICB9OiB7XG4gICAgdHJpZ2dlcjogJ3N1Ym1pdC1tZXNzYWdlJyB8ICdyZXN1bWUtc3RyZWFtJyB8ICdyZWdlbmVyYXRlLW1lc3NhZ2UnO1xuICAgIG1lc3NhZ2VJZD86IHN0cmluZztcbiAgfSAmIENoYXRSZXF1ZXN0T3B0aW9ucykge1xuICAgIHRoaXMuc2V0U3RhdHVzKHsgc3RhdHVzOiAnc3VibWl0dGVkJywgZXJyb3I6IHVuZGVmaW5lZCB9KTtcblxuICAgIGNvbnN0IGxhc3RNZXNzYWdlID0gdGhpcy5sYXN0TWVzc2FnZTtcblxuICAgIGxldCBpc0Fib3J0ID0gZmFsc2U7XG4gICAgbGV0IGlzRGlzY29ubmVjdCA9IGZhbHNlO1xuICAgIGxldCBpc0Vycm9yID0gZmFsc2U7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgYWN0aXZlUmVzcG9uc2UgPSB7XG4gICAgICAgIHN0YXRlOiBjcmVhdGVTdHJlYW1pbmdVSU1lc3NhZ2VTdGF0ZSh7XG4gICAgICAgICAgbGFzdE1lc3NhZ2U6IHRoaXMuc3RhdGUuc25hcHNob3QobGFzdE1lc3NhZ2UpLFxuICAgICAgICAgIG1lc3NhZ2VJZDogdGhpcy5nZW5lcmF0ZUlkKCksXG4gICAgICAgIH0pLFxuICAgICAgICBhYm9ydENvbnRyb2xsZXI6IG5ldyBBYm9ydENvbnRyb2xsZXIoKSxcbiAgICAgIH0gYXMgQWN0aXZlUmVzcG9uc2U8VUlfTUVTU0FHRT47XG5cbiAgICAgIGFjdGl2ZVJlc3BvbnNlLmFib3J0Q29udHJvbGxlci5zaWduYWwuYWRkRXZlbnRMaXN0ZW5lcignYWJvcnQnLCAoKSA9PiB7XG4gICAgICAgIGlzQWJvcnQgPSB0cnVlO1xuICAgICAgfSk7XG5cbiAgICAgIHRoaXMuYWN0aXZlUmVzcG9uc2UgPSBhY3RpdmVSZXNwb25zZTtcblxuICAgICAgbGV0IHN0cmVhbTogUmVhZGFibGVTdHJlYW08VUlNZXNzYWdlQ2h1bms+O1xuXG4gICAgICBpZiAodHJpZ2dlciA9PT0gJ3Jlc3VtZS1zdHJlYW0nKSB7XG4gICAgICAgIGNvbnN0IHJlY29ubmVjdCA9IGF3YWl0IHRoaXMudHJhbnNwb3J0LnJlY29ubmVjdFRvU3RyZWFtKHtcbiAgICAgICAgICBjaGF0SWQ6IHRoaXMuaWQsXG4gICAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgICAgaGVhZGVycyxcbiAgICAgICAgICBib2R5LFxuICAgICAgICB9KTtcblxuICAgICAgICBpZiAocmVjb25uZWN0ID09IG51bGwpIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXR1cyh7IHN0YXR1czogJ3JlYWR5JyB9KTtcbiAgICAgICAgICByZXR1cm47IC8vIG5vIGFjdGl2ZSBzdHJlYW0gZm91bmQsIHNvIHdlIGRvIG5vdCByZXN1bWVcbiAgICAgICAgfVxuXG4gICAgICAgIHN0cmVhbSA9IHJlY29ubmVjdDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0cmVhbSA9IGF3YWl0IHRoaXMudHJhbnNwb3J0LnNlbmRNZXNzYWdlcyh7XG4gICAgICAgICAgY2hhdElkOiB0aGlzLmlkLFxuICAgICAgICAgIG1lc3NhZ2VzOiB0aGlzLnN0YXRlLm1lc3NhZ2VzLFxuICAgICAgICAgIGFib3J0U2lnbmFsOiBhY3RpdmVSZXNwb25zZS5hYm9ydENvbnRyb2xsZXIuc2lnbmFsLFxuICAgICAgICAgIG1ldGFkYXRhLFxuICAgICAgICAgIGhlYWRlcnMsXG4gICAgICAgICAgYm9keSxcbiAgICAgICAgICB0cmlnZ2VyLFxuICAgICAgICAgIG1lc3NhZ2VJZCxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJ1blVwZGF0ZU1lc3NhZ2VKb2IgPSAoXG4gICAgICAgIGpvYjogKG9wdGlvbnM6IHtcbiAgICAgICAgICBzdGF0ZTogU3RyZWFtaW5nVUlNZXNzYWdlU3RhdGU8VUlfTUVTU0FHRT47XG4gICAgICAgICAgd3JpdGU6ICgpID0+IHZvaWQ7XG4gICAgICAgIH0pID0+IFByb21pc2U8dm9pZD4sXG4gICAgICApID0+XG4gICAgICAgIC8vIHNlcmlhbGl6ZSB0aGUgam9iIGV4ZWN1dGlvbiB0byBhdm9pZCByYWNlIGNvbmRpdGlvbnM6XG4gICAgICAgIHRoaXMuam9iRXhlY3V0b3IucnVuKCgpID0+XG4gICAgICAgICAgam9iKHtcbiAgICAgICAgICAgIHN0YXRlOiBhY3RpdmVSZXNwb25zZS5zdGF0ZSxcbiAgICAgICAgICAgIHdyaXRlOiAoKSA9PiB7XG4gICAgICAgICAgICAgIC8vIHN0cmVhbWluZyBpcyBzZXQgb24gZmlyc3Qgd3JpdGUgKGJlZm9yZSBpdCBzaG91bGQgYmUgXCJzdWJtaXR0ZWRcIilcbiAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0dXMoeyBzdGF0dXM6ICdzdHJlYW1pbmcnIH0pO1xuXG4gICAgICAgICAgICAgIGNvbnN0IHJlcGxhY2VMYXN0TWVzc2FnZSA9XG4gICAgICAgICAgICAgICAgYWN0aXZlUmVzcG9uc2Uuc3RhdGUubWVzc2FnZS5pZCA9PT0gdGhpcy5sYXN0TWVzc2FnZT8uaWQ7XG5cbiAgICAgICAgICAgICAgaWYgKHJlcGxhY2VMYXN0TWVzc2FnZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUucmVwbGFjZU1lc3NhZ2UoXG4gICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLm1lc3NhZ2VzLmxlbmd0aCAtIDEsXG4gICAgICAgICAgICAgICAgICBhY3RpdmVSZXNwb25zZS5zdGF0ZS5tZXNzYWdlLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5wdXNoTWVzc2FnZShhY3RpdmVSZXNwb25zZS5zdGF0ZS5tZXNzYWdlKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcblxuICAgICAgYXdhaXQgY29uc3VtZVN0cmVhbSh7XG4gICAgICAgIHN0cmVhbTogcHJvY2Vzc1VJTWVzc2FnZVN0cmVhbSh7XG4gICAgICAgICAgc3RyZWFtLFxuICAgICAgICAgIG9uVG9vbENhbGw6IHRoaXMub25Ub29sQ2FsbCxcbiAgICAgICAgICBvbkRhdGE6IHRoaXMub25EYXRhLFxuICAgICAgICAgIG1lc3NhZ2VNZXRhZGF0YVNjaGVtYTogdGhpcy5tZXNzYWdlTWV0YWRhdGFTY2hlbWEsXG4gICAgICAgICAgZGF0YVBhcnRTY2hlbWFzOiB0aGlzLmRhdGFQYXJ0U2NoZW1hcyxcbiAgICAgICAgICBydW5VcGRhdGVNZXNzYWdlSm9iLFxuICAgICAgICAgIG9uRXJyb3I6IGVycm9yID0+IHtcbiAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgICBvbkVycm9yOiBlcnJvciA9PiB7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgdGhpcy5zZXRTdGF0dXMoeyBzdGF0dXM6ICdyZWFkeScgfSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAvLyBJZ25vcmUgYWJvcnQgZXJyb3JzIGFzIHRoZXkgYXJlIGV4cGVjdGVkLlxuICAgICAgaWYgKGlzQWJvcnQgfHwgKGVyciBhcyBhbnkpLm5hbWUgPT09ICdBYm9ydEVycm9yJykge1xuICAgICAgICBpc0Fib3J0ID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5zZXRTdGF0dXMoeyBzdGF0dXM6ICdyZWFkeScgfSk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgICBpc0Vycm9yID0gdHJ1ZTtcblxuICAgICAgLy8gTmV0d29yayBlcnJvcnMgc3VjaCBhcyBkaXNjb25uZWN0ZWQsIHRpbWVvdXQsIGV0Yy5cbiAgICAgIGlmIChcbiAgICAgICAgZXJyIGluc3RhbmNlb2YgVHlwZUVycm9yICYmXG4gICAgICAgIChlcnIubWVzc2FnZS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKCdmZXRjaCcpIHx8XG4gICAgICAgICAgZXJyLm1lc3NhZ2UudG9Mb3dlckNhc2UoKS5pbmNsdWRlcygnbmV0d29yaycpKVxuICAgICAgKSB7XG4gICAgICAgIGlzRGlzY29ubmVjdCA9IHRydWU7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLm9uRXJyb3IgJiYgZXJyIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgdGhpcy5vbkVycm9yKGVycik7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc2V0U3RhdHVzKHsgc3RhdHVzOiAnZXJyb3InLCBlcnJvcjogZXJyIGFzIEVycm9yIH0pO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0cnkge1xuICAgICAgICB0aGlzLm9uRmluaXNoPy4oe1xuICAgICAgICAgIG1lc3NhZ2U6IHRoaXMuYWN0aXZlUmVzcG9uc2UhLnN0YXRlLm1lc3NhZ2UsXG4gICAgICAgICAgbWVzc2FnZXM6IHRoaXMuc3RhdGUubWVzc2FnZXMsXG4gICAgICAgICAgaXNBYm9ydCxcbiAgICAgICAgICBpc0Rpc2Nvbm5lY3QsXG4gICAgICAgICAgaXNFcnJvcixcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmFjdGl2ZVJlc3BvbnNlID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8vIGF1dG9tYXRpY2FsbHkgc2VuZCB0aGUgbWVzc2FnZSBpZiB0aGUgc2VuZEF1dG9tYXRpY2FsbHlXaGVuIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZVxuICAgIGlmIChcbiAgICAgIHRoaXMuc2VuZEF1dG9tYXRpY2FsbHlXaGVuPy4oeyBtZXNzYWdlczogdGhpcy5zdGF0ZS5tZXNzYWdlcyB9KSAmJlxuICAgICAgIWlzRXJyb3JcbiAgICApIHtcbiAgICAgIGF3YWl0IHRoaXMubWFrZVJlcXVlc3Qoe1xuICAgICAgICB0cmlnZ2VyOiAnc3VibWl0LW1lc3NhZ2UnLFxuICAgICAgICBtZXNzYWdlSWQ6IHRoaXMubGFzdE1lc3NhZ2U/LmlkLFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAgaGVhZGVycyxcbiAgICAgICAgYm9keSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufVxuIiwgImltcG9ydCB7IEZpbGVVSVBhcnQgfSBmcm9tICcuL3VpLW1lc3NhZ2VzJztcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNvbnZlcnRGaWxlTGlzdFRvRmlsZVVJUGFydHMoXG4gIGZpbGVzOiBGaWxlTGlzdCB8IHVuZGVmaW5lZCxcbik6IFByb21pc2U8QXJyYXk8RmlsZVVJUGFydD4+IHtcbiAgaWYgKGZpbGVzID09IG51bGwpIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICAvLyBSZWFjdC1uYXRpdmUgZG9lc24ndCBoYXZlIGEgRmlsZUxpc3QgZ2xvYmFsOlxuICBpZiAoIWdsb2JhbFRoaXMuRmlsZUxpc3QgfHwgIShmaWxlcyBpbnN0YW5jZW9mIGdsb2JhbFRoaXMuRmlsZUxpc3QpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdGaWxlTGlzdCBpcyBub3Qgc3VwcG9ydGVkIGluIHRoZSBjdXJyZW50IGVudmlyb25tZW50Jyk7XG4gIH1cblxuICByZXR1cm4gUHJvbWlzZS5hbGwoXG4gICAgQXJyYXkuZnJvbShmaWxlcykubWFwKGFzeW5jIGZpbGUgPT4ge1xuICAgICAgY29uc3QgeyBuYW1lLCB0eXBlIH0gPSBmaWxlO1xuXG4gICAgICBjb25zdCBkYXRhVXJsID0gYXdhaXQgbmV3IFByb21pc2U8c3RyaW5nPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgICAgIHJlYWRlci5vbmxvYWQgPSByZWFkZXJFdmVudCA9PiB7XG4gICAgICAgICAgcmVzb2x2ZShyZWFkZXJFdmVudC50YXJnZXQ/LnJlc3VsdCBhcyBzdHJpbmcpO1xuICAgICAgICB9O1xuICAgICAgICByZWFkZXIub25lcnJvciA9IGVycm9yID0+IHJlamVjdChlcnJvcik7XG4gICAgICAgIHJlYWRlci5yZWFkQXNEYXRhVVJMKGZpbGUpO1xuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6ICdmaWxlJyxcbiAgICAgICAgbWVkaWFUeXBlOiB0eXBlLFxuICAgICAgICBmaWxlbmFtZTogbmFtZSxcbiAgICAgICAgdXJsOiBkYXRhVXJsLFxuICAgICAgfTtcbiAgICB9KSxcbiAgKTtcbn1cbiIsICJpbXBvcnQgeyBwYXJzZUpzb25FdmVudFN0cmVhbSwgUGFyc2VSZXN1bHQgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyLXV0aWxzJztcbmltcG9ydCB7XG4gIFVJTWVzc2FnZUNodW5rLFxuICB1aU1lc3NhZ2VDaHVua1NjaGVtYSxcbn0gZnJvbSAnLi4vdWktbWVzc2FnZS1zdHJlYW0vdWktbWVzc2FnZS1jaHVua3MnO1xuaW1wb3J0IHtcbiAgSHR0cENoYXRUcmFuc3BvcnQsXG4gIEh0dHBDaGF0VHJhbnNwb3J0SW5pdE9wdGlvbnMsXG59IGZyb20gJy4vaHR0cC1jaGF0LXRyYW5zcG9ydCc7XG5pbXBvcnQgeyBVSU1lc3NhZ2UgfSBmcm9tICcuL3VpLW1lc3NhZ2VzJztcblxuZXhwb3J0IGNsYXNzIERlZmF1bHRDaGF0VHJhbnNwb3J0PFxuICBVSV9NRVNTQUdFIGV4dGVuZHMgVUlNZXNzYWdlLFxuPiBleHRlbmRzIEh0dHBDaGF0VHJhbnNwb3J0PFVJX01FU1NBR0U+IHtcbiAgY29uc3RydWN0b3Iob3B0aW9uczogSHR0cENoYXRUcmFuc3BvcnRJbml0T3B0aW9uczxVSV9NRVNTQUdFPiA9IHt9KSB7XG4gICAgc3VwZXIob3B0aW9ucyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgcHJvY2Vzc1Jlc3BvbnNlU3RyZWFtKFxuICAgIHN0cmVhbTogUmVhZGFibGVTdHJlYW08VWludDhBcnJheTxBcnJheUJ1ZmZlckxpa2U+PixcbiAgKTogUmVhZGFibGVTdHJlYW08VUlNZXNzYWdlQ2h1bms+IHtcbiAgICByZXR1cm4gcGFyc2VKc29uRXZlbnRTdHJlYW0oe1xuICAgICAgc3RyZWFtLFxuICAgICAgc2NoZW1hOiB1aU1lc3NhZ2VDaHVua1NjaGVtYSxcbiAgICB9KS5waXBlVGhyb3VnaChcbiAgICAgIG5ldyBUcmFuc2Zvcm1TdHJlYW08UGFyc2VSZXN1bHQ8VUlNZXNzYWdlQ2h1bms+LCBVSU1lc3NhZ2VDaHVuaz4oe1xuICAgICAgICBhc3luYyB0cmFuc2Zvcm0oY2h1bmssIGNvbnRyb2xsZXIpIHtcbiAgICAgICAgICBpZiAoIWNodW5rLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgIHRocm93IGNodW5rLmVycm9yO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoY2h1bmsudmFsdWUpO1xuICAgICAgICB9LFxuICAgICAgfSksXG4gICAgKTtcbiAgfVxufVxuIiwgImltcG9ydCB7XG4gIEZldGNoRnVuY3Rpb24sXG4gIFJlc29sdmFibGUsXG4gIHJlc29sdmUsXG4gIHdpdGhVc2VyQWdlbnRTdWZmaXgsXG4gIGdldFJ1bnRpbWVFbnZpcm9ubWVudFVzZXJBZ2VudCxcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyBVSU1lc3NhZ2VDaHVuayB9IGZyb20gJy4uL3VpLW1lc3NhZ2Utc3RyZWFtL3VpLW1lc3NhZ2UtY2h1bmtzJztcbmltcG9ydCB7IENoYXRUcmFuc3BvcnQgfSBmcm9tICcuL2NoYXQtdHJhbnNwb3J0JztcbmltcG9ydCB7IFVJTWVzc2FnZSB9IGZyb20gJy4vdWktbWVzc2FnZXMnO1xuaW1wb3J0IHsgVkVSU0lPTiB9IGZyb20gJy4uL3ZlcnNpb24nO1xuXG5leHBvcnQgdHlwZSBQcmVwYXJlU2VuZE1lc3NhZ2VzUmVxdWVzdDxVSV9NRVNTQUdFIGV4dGVuZHMgVUlNZXNzYWdlPiA9IChcbiAgb3B0aW9uczoge1xuICAgIGlkOiBzdHJpbmc7XG4gICAgbWVzc2FnZXM6IFVJX01FU1NBR0VbXTtcbiAgICByZXF1ZXN0TWV0YWRhdGE6IHVua25vd247XG4gICAgYm9keTogUmVjb3JkPHN0cmluZywgYW55PiB8IHVuZGVmaW5lZDtcbiAgICBjcmVkZW50aWFsczogUmVxdWVzdENyZWRlbnRpYWxzIHwgdW5kZWZpbmVkO1xuICAgIGhlYWRlcnM6IEhlYWRlcnNJbml0IHwgdW5kZWZpbmVkO1xuICAgIGFwaTogc3RyaW5nO1xuICB9ICYge1xuICAgIHRyaWdnZXI6ICdzdWJtaXQtbWVzc2FnZScgfCAncmVnZW5lcmF0ZS1tZXNzYWdlJztcbiAgICBtZXNzYWdlSWQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgfSxcbikgPT5cbiAgfCB7XG4gICAgICBib2R5OiBvYmplY3Q7XG4gICAgICBoZWFkZXJzPzogSGVhZGVyc0luaXQ7XG4gICAgICBjcmVkZW50aWFscz86IFJlcXVlc3RDcmVkZW50aWFscztcbiAgICAgIGFwaT86IHN0cmluZztcbiAgICB9XG4gIHwgUHJvbWlzZUxpa2U8e1xuICAgICAgYm9keTogb2JqZWN0O1xuICAgICAgaGVhZGVycz86IEhlYWRlcnNJbml0O1xuICAgICAgY3JlZGVudGlhbHM/OiBSZXF1ZXN0Q3JlZGVudGlhbHM7XG4gICAgICBhcGk/OiBzdHJpbmc7XG4gICAgfT47XG5cbmV4cG9ydCB0eXBlIFByZXBhcmVSZWNvbm5lY3RUb1N0cmVhbVJlcXVlc3QgPSAob3B0aW9uczoge1xuICBpZDogc3RyaW5nO1xuICByZXF1ZXN0TWV0YWRhdGE6IHVua25vd247XG4gIGJvZHk6IFJlY29yZDxzdHJpbmcsIGFueT4gfCB1bmRlZmluZWQ7XG4gIGNyZWRlbnRpYWxzOiBSZXF1ZXN0Q3JlZGVudGlhbHMgfCB1bmRlZmluZWQ7XG4gIGhlYWRlcnM6IEhlYWRlcnNJbml0IHwgdW5kZWZpbmVkO1xuICBhcGk6IHN0cmluZztcbn0pID0+XG4gIHwge1xuICAgICAgaGVhZGVycz86IEhlYWRlcnNJbml0O1xuICAgICAgY3JlZGVudGlhbHM/OiBSZXF1ZXN0Q3JlZGVudGlhbHM7XG4gICAgICBhcGk/OiBzdHJpbmc7XG4gICAgfVxuICB8IFByb21pc2VMaWtlPHtcbiAgICAgIGhlYWRlcnM/OiBIZWFkZXJzSW5pdDtcbiAgICAgIGNyZWRlbnRpYWxzPzogUmVxdWVzdENyZWRlbnRpYWxzO1xuICAgICAgYXBpPzogc3RyaW5nO1xuICAgIH0+O1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHRoZSBgSHR0cENoYXRUcmFuc3BvcnRgIGNsYXNzLlxuICpcbiAqIEBwYXJhbSBVSV9NRVNTQUdFIC0gVGhlIHR5cGUgb2YgbWVzc2FnZSB0byBiZSB1c2VkIGluIHRoZSBjaGF0LlxuICovXG5leHBvcnQgdHlwZSBIdHRwQ2hhdFRyYW5zcG9ydEluaXRPcHRpb25zPFVJX01FU1NBR0UgZXh0ZW5kcyBVSU1lc3NhZ2U+ID0ge1xuICAvKipcbiAgICogVGhlIEFQSSBVUkwgdG8gYmUgdXNlZCBmb3IgdGhlIGNoYXQgdHJhbnNwb3J0LlxuICAgKiBEZWZhdWx0cyB0byAnL2FwaS9jaGF0Jy5cbiAgICovXG4gIGFwaT86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGNyZWRlbnRpYWxzIG1vZGUgdG8gYmUgdXNlZCBmb3IgdGhlIGZldGNoIHJlcXVlc3QuXG4gICAqIFBvc3NpYmxlIHZhbHVlcyBhcmU6ICdvbWl0JywgJ3NhbWUtb3JpZ2luJywgJ2luY2x1ZGUnLlxuICAgKiBEZWZhdWx0cyB0byAnc2FtZS1vcmlnaW4nLlxuICAgKi9cbiAgY3JlZGVudGlhbHM/OiBSZXNvbHZhYmxlPFJlcXVlc3RDcmVkZW50aWFscz47XG5cbiAgLyoqXG4gICAqIEhUVFAgaGVhZGVycyB0byBiZSBzZW50IHdpdGggdGhlIEFQSSByZXF1ZXN0LlxuICAgKi9cbiAgaGVhZGVycz86IFJlc29sdmFibGU8UmVjb3JkPHN0cmluZywgc3RyaW5nPiB8IEhlYWRlcnM+O1xuXG4gIC8qKlxuICAgKiBFeHRyYSBib2R5IG9iamVjdCB0byBiZSBzZW50IHdpdGggdGhlIEFQSSByZXF1ZXN0LlxuICAgKiBAZXhhbXBsZVxuICAgKiBTZW5kIGEgYHNlc3Npb25JZGAgdG8gdGhlIEFQSSBhbG9uZyB3aXRoIHRoZSBtZXNzYWdlcy5cbiAgICogYGBganNcbiAgICogdXNlQ2hhdCh7XG4gICAqICAgYm9keToge1xuICAgKiAgICAgc2Vzc2lvbklkOiAnMTIzJyxcbiAgICogICB9XG4gICAqIH0pXG4gICAqIGBgYFxuICAgKi9cbiAgYm9keT86IFJlc29sdmFibGU8b2JqZWN0PjtcblxuICAvKipcbiAgQ3VzdG9tIGZldGNoIGltcGxlbWVudGF0aW9uLiBZb3UgY2FuIHVzZSBpdCBhcyBhIG1pZGRsZXdhcmUgdG8gaW50ZXJjZXB0IHJlcXVlc3RzLFxuICBvciB0byBwcm92aWRlIGEgY3VzdG9tIGZldGNoIGltcGxlbWVudGF0aW9uIGZvciBlLmcuIHRlc3RpbmcuXG4gICAgICAqL1xuICBmZXRjaD86IEZldGNoRnVuY3Rpb247XG5cbiAgLyoqXG4gICAqIFdoZW4gYSBmdW5jdGlvbiBpcyBwcm92aWRlZCwgaXQgd2lsbCBiZSB1c2VkXG4gICAqIHRvIHByZXBhcmUgdGhlIHJlcXVlc3QgYm9keSBmb3IgdGhlIGNoYXQgQVBJLiBUaGlzIGNhbiBiZSB1c2VmdWwgZm9yXG4gICAqIGN1c3RvbWl6aW5nIHRoZSByZXF1ZXN0IGJvZHkgYmFzZWQgb24gdGhlIG1lc3NhZ2VzIGFuZCBkYXRhIGluIHRoZSBjaGF0LlxuICAgKlxuICAgKiBAcGFyYW0gaWQgVGhlIGlkIG9mIHRoZSBjaGF0LlxuICAgKiBAcGFyYW0gbWVzc2FnZXMgVGhlIGN1cnJlbnQgbWVzc2FnZXMgaW4gdGhlIGNoYXQuXG4gICAqIEBwYXJhbSByZXF1ZXN0Qm9keSBUaGUgcmVxdWVzdCBib2R5IG9iamVjdCBwYXNzZWQgaW4gdGhlIGNoYXQgcmVxdWVzdC5cbiAgICovXG4gIHByZXBhcmVTZW5kTWVzc2FnZXNSZXF1ZXN0PzogUHJlcGFyZVNlbmRNZXNzYWdlc1JlcXVlc3Q8VUlfTUVTU0FHRT47XG5cbiAgLyoqXG4gICAqIFdoZW4gYSBmdW5jdGlvbiBpcyBwcm92aWRlZCwgaXQgd2lsbCBiZSB1c2VkXG4gICAqIHRvIHByZXBhcmUgdGhlIHJlcXVlc3QgYm9keSBmb3IgdGhlIGNoYXQgQVBJLiBUaGlzIGNhbiBiZSB1c2VmdWwgZm9yXG4gICAqIGN1c3RvbWl6aW5nIHRoZSByZXF1ZXN0IGJvZHkgYmFzZWQgb24gdGhlIG1lc3NhZ2VzIGFuZCBkYXRhIGluIHRoZSBjaGF0LlxuICAgKlxuICAgKiBAcGFyYW0gaWQgVGhlIGlkIG9mIHRoZSBjaGF0LlxuICAgKiBAcGFyYW0gbWVzc2FnZXMgVGhlIGN1cnJlbnQgbWVzc2FnZXMgaW4gdGhlIGNoYXQuXG4gICAqIEBwYXJhbSByZXF1ZXN0Qm9keSBUaGUgcmVxdWVzdCBib2R5IG9iamVjdCBwYXNzZWQgaW4gdGhlIGNoYXQgcmVxdWVzdC5cbiAgICovXG4gIHByZXBhcmVSZWNvbm5lY3RUb1N0cmVhbVJlcXVlc3Q/OiBQcmVwYXJlUmVjb25uZWN0VG9TdHJlYW1SZXF1ZXN0O1xufTtcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEh0dHBDaGF0VHJhbnNwb3J0PFVJX01FU1NBR0UgZXh0ZW5kcyBVSU1lc3NhZ2U+XG4gIGltcGxlbWVudHMgQ2hhdFRyYW5zcG9ydDxVSV9NRVNTQUdFPlxue1xuICBwcm90ZWN0ZWQgYXBpOiBzdHJpbmc7XG4gIHByb3RlY3RlZCBjcmVkZW50aWFsczogSHR0cENoYXRUcmFuc3BvcnRJbml0T3B0aW9uczxVSV9NRVNTQUdFPlsnY3JlZGVudGlhbHMnXTtcbiAgcHJvdGVjdGVkIGhlYWRlcnM6IEh0dHBDaGF0VHJhbnNwb3J0SW5pdE9wdGlvbnM8VUlfTUVTU0FHRT5bJ2hlYWRlcnMnXTtcbiAgcHJvdGVjdGVkIGJvZHk6IEh0dHBDaGF0VHJhbnNwb3J0SW5pdE9wdGlvbnM8VUlfTUVTU0FHRT5bJ2JvZHknXTtcbiAgcHJvdGVjdGVkIGZldGNoPzogRmV0Y2hGdW5jdGlvbjtcbiAgcHJvdGVjdGVkIHByZXBhcmVTZW5kTWVzc2FnZXNSZXF1ZXN0PzogUHJlcGFyZVNlbmRNZXNzYWdlc1JlcXVlc3Q8VUlfTUVTU0FHRT47XG4gIHByb3RlY3RlZCBwcmVwYXJlUmVjb25uZWN0VG9TdHJlYW1SZXF1ZXN0PzogUHJlcGFyZVJlY29ubmVjdFRvU3RyZWFtUmVxdWVzdDtcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgYXBpID0gJy9hcGkvY2hhdCcsXG4gICAgY3JlZGVudGlhbHMsXG4gICAgaGVhZGVycyxcbiAgICBib2R5LFxuICAgIGZldGNoLFxuICAgIHByZXBhcmVTZW5kTWVzc2FnZXNSZXF1ZXN0LFxuICAgIHByZXBhcmVSZWNvbm5lY3RUb1N0cmVhbVJlcXVlc3QsXG4gIH06IEh0dHBDaGF0VHJhbnNwb3J0SW5pdE9wdGlvbnM8VUlfTUVTU0FHRT4pIHtcbiAgICB0aGlzLmFwaSA9IGFwaTtcbiAgICB0aGlzLmNyZWRlbnRpYWxzID0gY3JlZGVudGlhbHM7XG4gICAgdGhpcy5oZWFkZXJzID0gaGVhZGVycztcbiAgICB0aGlzLmJvZHkgPSBib2R5O1xuICAgIHRoaXMuZmV0Y2ggPSBmZXRjaDtcbiAgICB0aGlzLnByZXBhcmVTZW5kTWVzc2FnZXNSZXF1ZXN0ID0gcHJlcGFyZVNlbmRNZXNzYWdlc1JlcXVlc3Q7XG4gICAgdGhpcy5wcmVwYXJlUmVjb25uZWN0VG9TdHJlYW1SZXF1ZXN0ID0gcHJlcGFyZVJlY29ubmVjdFRvU3RyZWFtUmVxdWVzdDtcbiAgfVxuXG4gIGFzeW5jIHNlbmRNZXNzYWdlcyh7XG4gICAgYWJvcnRTaWduYWwsXG4gICAgLi4ub3B0aW9uc1xuICB9OiBQYXJhbWV0ZXJzPENoYXRUcmFuc3BvcnQ8VUlfTUVTU0FHRT5bJ3NlbmRNZXNzYWdlcyddPlswXSkge1xuICAgIGNvbnN0IHJlc29sdmVkQm9keSA9IGF3YWl0IHJlc29sdmUodGhpcy5ib2R5KTtcbiAgICBjb25zdCByZXNvbHZlZEhlYWRlcnMgPSBhd2FpdCByZXNvbHZlKHRoaXMuaGVhZGVycyk7XG4gICAgY29uc3QgcmVzb2x2ZWRDcmVkZW50aWFscyA9IGF3YWl0IHJlc29sdmUodGhpcy5jcmVkZW50aWFscyk7XG5cbiAgICBjb25zdCBwcmVwYXJlZFJlcXVlc3QgPSBhd2FpdCB0aGlzLnByZXBhcmVTZW5kTWVzc2FnZXNSZXF1ZXN0Py4oe1xuICAgICAgYXBpOiB0aGlzLmFwaSxcbiAgICAgIGlkOiBvcHRpb25zLmNoYXRJZCxcbiAgICAgIG1lc3NhZ2VzOiBvcHRpb25zLm1lc3NhZ2VzLFxuICAgICAgYm9keTogeyAuLi5yZXNvbHZlZEJvZHksIC4uLm9wdGlvbnMuYm9keSB9LFxuICAgICAgaGVhZGVyczogeyAuLi5yZXNvbHZlZEhlYWRlcnMsIC4uLm9wdGlvbnMuaGVhZGVycyB9LFxuICAgICAgY3JlZGVudGlhbHM6IHJlc29sdmVkQ3JlZGVudGlhbHMsXG4gICAgICByZXF1ZXN0TWV0YWRhdGE6IG9wdGlvbnMubWV0YWRhdGEsXG4gICAgICB0cmlnZ2VyOiBvcHRpb25zLnRyaWdnZXIsXG4gICAgICBtZXNzYWdlSWQ6IG9wdGlvbnMubWVzc2FnZUlkLFxuICAgIH0pO1xuXG4gICAgY29uc3QgYXBpID0gcHJlcGFyZWRSZXF1ZXN0Py5hcGkgPz8gdGhpcy5hcGk7XG4gICAgY29uc3QgaGVhZGVycyA9XG4gICAgICBwcmVwYXJlZFJlcXVlc3Q/LmhlYWRlcnMgIT09IHVuZGVmaW5lZFxuICAgICAgICA/IHByZXBhcmVkUmVxdWVzdC5oZWFkZXJzXG4gICAgICAgIDogeyAuLi5yZXNvbHZlZEhlYWRlcnMsIC4uLm9wdGlvbnMuaGVhZGVycyB9O1xuICAgIGNvbnN0IGJvZHkgPVxuICAgICAgcHJlcGFyZWRSZXF1ZXN0Py5ib2R5ICE9PSB1bmRlZmluZWRcbiAgICAgICAgPyBwcmVwYXJlZFJlcXVlc3QuYm9keVxuICAgICAgICA6IHtcbiAgICAgICAgICAgIC4uLnJlc29sdmVkQm9keSxcbiAgICAgICAgICAgIC4uLm9wdGlvbnMuYm9keSxcbiAgICAgICAgICAgIGlkOiBvcHRpb25zLmNoYXRJZCxcbiAgICAgICAgICAgIG1lc3NhZ2VzOiBvcHRpb25zLm1lc3NhZ2VzLFxuICAgICAgICAgICAgdHJpZ2dlcjogb3B0aW9ucy50cmlnZ2VyLFxuICAgICAgICAgICAgbWVzc2FnZUlkOiBvcHRpb25zLm1lc3NhZ2VJZCxcbiAgICAgICAgICB9O1xuICAgIGNvbnN0IGNyZWRlbnRpYWxzID0gcHJlcGFyZWRSZXF1ZXN0Py5jcmVkZW50aWFscyA/PyByZXNvbHZlZENyZWRlbnRpYWxzO1xuXG4gICAgLy8gYXZvaWQgY2FjaGluZyBnbG9iYWxUaGlzLmZldGNoIGluIGNhc2UgaXQgaXMgcGF0Y2hlZCBieSBvdGhlciBsaWJyYXJpZXNcbiAgICBjb25zdCBmZXRjaCA9IHRoaXMuZmV0Y2ggPz8gZ2xvYmFsVGhpcy5mZXRjaDtcblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goYXBpLCB7XG4gICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgIGhlYWRlcnM6IHdpdGhVc2VyQWdlbnRTdWZmaXgoXG4gICAgICAgIHtcbiAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICAgIC4uLmhlYWRlcnMsXG4gICAgICAgIH0sXG4gICAgICAgIGBhaS1zZGsvJHtWRVJTSU9OfWAsXG4gICAgICAgIGdldFJ1bnRpbWVFbnZpcm9ubWVudFVzZXJBZ2VudCgpLFxuICAgICAgKSxcbiAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KGJvZHkpLFxuICAgICAgY3JlZGVudGlhbHMsXG4gICAgICBzaWduYWw6IGFib3J0U2lnbmFsLFxuICAgIH0pO1xuXG4gICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAoYXdhaXQgcmVzcG9uc2UudGV4dCgpKSA/PyAnRmFpbGVkIHRvIGZldGNoIHRoZSBjaGF0IHJlc3BvbnNlLicsXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICghcmVzcG9uc2UuYm9keSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgcmVzcG9uc2UgYm9keSBpcyBlbXB0eS4nKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5wcm9jZXNzUmVzcG9uc2VTdHJlYW0ocmVzcG9uc2UuYm9keSk7XG4gIH1cblxuICBhc3luYyByZWNvbm5lY3RUb1N0cmVhbShcbiAgICBvcHRpb25zOiBQYXJhbWV0ZXJzPENoYXRUcmFuc3BvcnQ8VUlfTUVTU0FHRT5bJ3JlY29ubmVjdFRvU3RyZWFtJ10+WzBdLFxuICApOiBQcm9taXNlPFJlYWRhYmxlU3RyZWFtPFVJTWVzc2FnZUNodW5rPiB8IG51bGw+IHtcbiAgICBjb25zdCByZXNvbHZlZEJvZHkgPSBhd2FpdCByZXNvbHZlKHRoaXMuYm9keSk7XG4gICAgY29uc3QgcmVzb2x2ZWRIZWFkZXJzID0gYXdhaXQgcmVzb2x2ZSh0aGlzLmhlYWRlcnMpO1xuICAgIGNvbnN0IHJlc29sdmVkQ3JlZGVudGlhbHMgPSBhd2FpdCByZXNvbHZlKHRoaXMuY3JlZGVudGlhbHMpO1xuXG4gICAgY29uc3QgcHJlcGFyZWRSZXF1ZXN0ID0gYXdhaXQgdGhpcy5wcmVwYXJlUmVjb25uZWN0VG9TdHJlYW1SZXF1ZXN0Py4oe1xuICAgICAgYXBpOiB0aGlzLmFwaSxcbiAgICAgIGlkOiBvcHRpb25zLmNoYXRJZCxcbiAgICAgIGJvZHk6IHsgLi4ucmVzb2x2ZWRCb2R5LCAuLi5vcHRpb25zLmJvZHkgfSxcbiAgICAgIGhlYWRlcnM6IHsgLi4ucmVzb2x2ZWRIZWFkZXJzLCAuLi5vcHRpb25zLmhlYWRlcnMgfSxcbiAgICAgIGNyZWRlbnRpYWxzOiByZXNvbHZlZENyZWRlbnRpYWxzLFxuICAgICAgcmVxdWVzdE1ldGFkYXRhOiBvcHRpb25zLm1ldGFkYXRhLFxuICAgIH0pO1xuXG4gICAgY29uc3QgYXBpID0gcHJlcGFyZWRSZXF1ZXN0Py5hcGkgPz8gYCR7dGhpcy5hcGl9LyR7b3B0aW9ucy5jaGF0SWR9L3N0cmVhbWA7XG4gICAgY29uc3QgaGVhZGVycyA9XG4gICAgICBwcmVwYXJlZFJlcXVlc3Q/LmhlYWRlcnMgIT09IHVuZGVmaW5lZFxuICAgICAgICA/IHByZXBhcmVkUmVxdWVzdC5oZWFkZXJzXG4gICAgICAgIDogeyAuLi5yZXNvbHZlZEhlYWRlcnMsIC4uLm9wdGlvbnMuaGVhZGVycyB9O1xuICAgIGNvbnN0IGNyZWRlbnRpYWxzID0gcHJlcGFyZWRSZXF1ZXN0Py5jcmVkZW50aWFscyA/PyByZXNvbHZlZENyZWRlbnRpYWxzO1xuXG4gICAgLy8gYXZvaWQgY2FjaGluZyBnbG9iYWxUaGlzLmZldGNoIGluIGNhc2UgaXQgaXMgcGF0Y2hlZCBieSBvdGhlciBsaWJyYXJpZXNcbiAgICBjb25zdCBmZXRjaCA9IHRoaXMuZmV0Y2ggPz8gZ2xvYmFsVGhpcy5mZXRjaDtcblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goYXBpLCB7XG4gICAgICBtZXRob2Q6ICdHRVQnLFxuICAgICAgaGVhZGVyczogd2l0aFVzZXJBZ2VudFN1ZmZpeChcbiAgICAgICAgaGVhZGVycyxcbiAgICAgICAgYGFpLXNkay8ke1ZFUlNJT059YCxcbiAgICAgICAgZ2V0UnVudGltZUVudmlyb25tZW50VXNlckFnZW50KCksXG4gICAgICApLFxuICAgICAgY3JlZGVudGlhbHMsXG4gICAgfSk7XG5cbiAgICAvLyBubyBhY3RpdmUgc3RyZWFtIGZvdW5kLCBzbyB3ZSBkbyBub3QgcmVzdW1lXG4gICAgaWYgKHJlc3BvbnNlLnN0YXR1cyA9PT0gMjA0KSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIChhd2FpdCByZXNwb25zZS50ZXh0KCkpID8/ICdGYWlsZWQgdG8gZmV0Y2ggdGhlIGNoYXQgcmVzcG9uc2UuJyxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKCFyZXNwb25zZS5ib2R5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSByZXNwb25zZSBib2R5IGlzIGVtcHR5LicpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnByb2Nlc3NSZXNwb25zZVN0cmVhbShyZXNwb25zZS5ib2R5KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBwcm9jZXNzUmVzcG9uc2VTdHJlYW0oXG4gICAgc3RyZWFtOiBSZWFkYWJsZVN0cmVhbTxVaW50OEFycmF5PEFycmF5QnVmZmVyTGlrZT4+LFxuICApOiBSZWFkYWJsZVN0cmVhbTxVSU1lc3NhZ2VDaHVuaz47XG59XG4iLCAiaW1wb3J0IHsgaXNUb29sT3JEeW5hbWljVG9vbFVJUGFydCwgdHlwZSBVSU1lc3NhZ2UgfSBmcm9tICcuL3VpLW1lc3NhZ2VzJztcblxuLyoqXG5DaGVjayBpZiB0aGUgbWVzc2FnZSBpcyBhbiBhc3Npc3RhbnQgbWVzc2FnZSB3aXRoIGNvbXBsZXRlZCB0b29sIGNhbGxzLlxuVGhlIGxhc3Qgc3RlcCBvZiB0aGUgbWVzc2FnZSBtdXN0IGhhdmUgYXQgbGVhc3Qgb25lIHRvb2wgaW52b2NhdGlvbiBhbmRcbmFsbCB0b29sIGludm9jYXRpb25zIG11c3QgaGF2ZSBhIHJlc3VsdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxhc3RBc3Npc3RhbnRNZXNzYWdlSXNDb21wbGV0ZVdpdGhUb29sQ2FsbHMoe1xuICBtZXNzYWdlcyxcbn06IHtcbiAgbWVzc2FnZXM6IFVJTWVzc2FnZVtdO1xufSk6IGJvb2xlYW4ge1xuICBjb25zdCBtZXNzYWdlID0gbWVzc2FnZXNbbWVzc2FnZXMubGVuZ3RoIC0gMV07XG5cbiAgaWYgKCFtZXNzYWdlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKG1lc3NhZ2Uucm9sZSAhPT0gJ2Fzc2lzdGFudCcpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBsYXN0U3RlcFN0YXJ0SW5kZXggPSBtZXNzYWdlLnBhcnRzLnJlZHVjZSgobGFzdEluZGV4LCBwYXJ0LCBpbmRleCkgPT4ge1xuICAgIHJldHVybiBwYXJ0LnR5cGUgPT09ICdzdGVwLXN0YXJ0JyA/IGluZGV4IDogbGFzdEluZGV4O1xuICB9LCAtMSk7XG5cbiAgY29uc3QgbGFzdFN0ZXBUb29sSW52b2NhdGlvbnMgPSBtZXNzYWdlLnBhcnRzXG4gICAgLnNsaWNlKGxhc3RTdGVwU3RhcnRJbmRleCArIDEpXG4gICAgLmZpbHRlcihpc1Rvb2xPckR5bmFtaWNUb29sVUlQYXJ0KTtcblxuICByZXR1cm4gKFxuICAgIGxhc3RTdGVwVG9vbEludm9jYXRpb25zLmxlbmd0aCA+IDAgJiZcbiAgICBsYXN0U3RlcFRvb2xJbnZvY2F0aW9ucy5ldmVyeShcbiAgICAgIHBhcnQgPT5cbiAgICAgICAgcGFydC5zdGF0ZSA9PT0gJ291dHB1dC1hdmFpbGFibGUnIHx8IHBhcnQuc3RhdGUgPT09ICdvdXRwdXQtZXJyb3InLFxuICAgIClcbiAgKTtcbn1cbiIsICJpbXBvcnQgeyBVSU1lc3NhZ2VDaHVuayB9IGZyb20gJy4uL3VpLW1lc3NhZ2Utc3RyZWFtL3VpLW1lc3NhZ2UtY2h1bmtzJztcblxuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zZm9ybVRleHRUb1VpTWVzc2FnZVN0cmVhbSh7XG4gIHN0cmVhbSxcbn06IHtcbiAgc3RyZWFtOiBSZWFkYWJsZVN0cmVhbTxzdHJpbmc+O1xufSkge1xuICByZXR1cm4gc3RyZWFtLnBpcGVUaHJvdWdoKFxuICAgIG5ldyBUcmFuc2Zvcm1TdHJlYW08c3RyaW5nLCBVSU1lc3NhZ2VDaHVuaz4oe1xuICAgICAgc3RhcnQoY29udHJvbGxlcikge1xuICAgICAgICBjb250cm9sbGVyLmVucXVldWUoeyB0eXBlOiAnc3RhcnQnIH0pO1xuICAgICAgICBjb250cm9sbGVyLmVucXVldWUoeyB0eXBlOiAnc3RhcnQtc3RlcCcgfSk7XG4gICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7IHR5cGU6ICd0ZXh0LXN0YXJ0JywgaWQ6ICd0ZXh0LTEnIH0pO1xuICAgICAgfSxcblxuICAgICAgYXN5bmMgdHJhbnNmb3JtKHBhcnQsIGNvbnRyb2xsZXIpIHtcbiAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHsgdHlwZTogJ3RleHQtZGVsdGEnLCBpZDogJ3RleHQtMScsIGRlbHRhOiBwYXJ0IH0pO1xuICAgICAgfSxcblxuICAgICAgYXN5bmMgZmx1c2goY29udHJvbGxlcikge1xuICAgICAgICBjb250cm9sbGVyLmVucXVldWUoeyB0eXBlOiAndGV4dC1lbmQnLCBpZDogJ3RleHQtMScgfSk7XG4gICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7IHR5cGU6ICdmaW5pc2gtc3RlcCcgfSk7XG4gICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh7IHR5cGU6ICdmaW5pc2gnIH0pO1xuICAgICAgfSxcbiAgICB9KSxcbiAgKTtcbn1cbiIsICJpbXBvcnQgeyBVSU1lc3NhZ2VDaHVuayB9IGZyb20gJy4uL3VpLW1lc3NhZ2Utc3RyZWFtL3VpLW1lc3NhZ2UtY2h1bmtzJztcbmltcG9ydCB7XG4gIEh0dHBDaGF0VHJhbnNwb3J0LFxuICBIdHRwQ2hhdFRyYW5zcG9ydEluaXRPcHRpb25zLFxufSBmcm9tICcuL2h0dHAtY2hhdC10cmFuc3BvcnQnO1xuaW1wb3J0IHsgdHJhbnNmb3JtVGV4dFRvVWlNZXNzYWdlU3RyZWFtIH0gZnJvbSAnLi90cmFuc2Zvcm0tdGV4dC10by11aS1tZXNzYWdlLXN0cmVhbSc7XG5pbXBvcnQgeyBVSU1lc3NhZ2UgfSBmcm9tICcuL3VpLW1lc3NhZ2VzJztcblxuZXhwb3J0IGNsYXNzIFRleHRTdHJlYW1DaGF0VHJhbnNwb3J0PFxuICBVSV9NRVNTQUdFIGV4dGVuZHMgVUlNZXNzYWdlLFxuPiBleHRlbmRzIEh0dHBDaGF0VHJhbnNwb3J0PFVJX01FU1NBR0U+IHtcbiAgY29uc3RydWN0b3Iob3B0aW9uczogSHR0cENoYXRUcmFuc3BvcnRJbml0T3B0aW9uczxVSV9NRVNTQUdFPiA9IHt9KSB7XG4gICAgc3VwZXIob3B0aW9ucyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgcHJvY2Vzc1Jlc3BvbnNlU3RyZWFtKFxuICAgIHN0cmVhbTogUmVhZGFibGVTdHJlYW08VWludDhBcnJheTxBcnJheUJ1ZmZlckxpa2U+PixcbiAgKTogUmVhZGFibGVTdHJlYW08VUlNZXNzYWdlQ2h1bms+IHtcbiAgICByZXR1cm4gdHJhbnNmb3JtVGV4dFRvVWlNZXNzYWdlU3RyZWFtKHtcbiAgICAgIHN0cmVhbTogc3RyZWFtLnBpcGVUaHJvdWdoKG5ldyBUZXh0RGVjb2RlclN0cmVhbSgpKSxcbiAgICB9KTtcbiAgfVxufVxuIiwgImltcG9ydCB7IFR5cGVWYWxpZGF0aW9uRXJyb3IgfSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyJztcbmltcG9ydCB7XG4gIGxhenlWYWxpZGF0b3IsXG4gIFN0YW5kYXJkU2NoZW1hVjEsXG4gIFRvb2wsXG4gIHZhbGlkYXRlVHlwZXMsXG4gIFZhbGlkYXRvcixcbiAgem9kU2NoZW1hLFxufSBmcm9tICdAYWktc2RrL3Byb3ZpZGVyLXV0aWxzJztcbmltcG9ydCB7IHogfSBmcm9tICd6b2QvdjQnO1xuaW1wb3J0IHsgSW52YWxpZEFyZ3VtZW50RXJyb3IgfSBmcm9tICcuLi9lcnJvcic7XG5pbXBvcnQgeyBwcm92aWRlck1ldGFkYXRhU2NoZW1hIH0gZnJvbSAnLi4vdHlwZXMvcHJvdmlkZXItbWV0YWRhdGEnO1xuaW1wb3J0IHtcbiAgRGF0YVVJUGFydCxcbiAgSW5mZXJVSU1lc3NhZ2VEYXRhLFxuICBJbmZlclVJTWVzc2FnZVRvb2xzLFxuICBUb29sVUlQYXJ0LFxuICBVSU1lc3NhZ2UsXG59IGZyb20gJy4vdWktbWVzc2FnZXMnO1xuXG5jb25zdCB1aU1lc3NhZ2VzU2NoZW1hID0gbGF6eVZhbGlkYXRvcigoKSA9PlxuICB6b2RTY2hlbWEoXG4gICAgei5hcnJheShcbiAgICAgIHoub2JqZWN0KHtcbiAgICAgICAgaWQ6IHouc3RyaW5nKCksXG4gICAgICAgIHJvbGU6IHouZW51bShbJ3N5c3RlbScsICd1c2VyJywgJ2Fzc2lzdGFudCddKSxcbiAgICAgICAgbWV0YWRhdGE6IHoudW5rbm93bigpLm9wdGlvbmFsKCksXG4gICAgICAgIHBhcnRzOiB6LmFycmF5KFxuICAgICAgICAgIHoudW5pb24oW1xuICAgICAgICAgICAgei5vYmplY3Qoe1xuICAgICAgICAgICAgICB0eXBlOiB6LmxpdGVyYWwoJ3RleHQnKSxcbiAgICAgICAgICAgICAgdGV4dDogei5zdHJpbmcoKSxcbiAgICAgICAgICAgICAgc3RhdGU6IHouZW51bShbJ3N0cmVhbWluZycsICdkb25lJ10pLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgei5vYmplY3Qoe1xuICAgICAgICAgICAgICB0eXBlOiB6LmxpdGVyYWwoJ3JlYXNvbmluZycpLFxuICAgICAgICAgICAgICB0ZXh0OiB6LnN0cmluZygpLFxuICAgICAgICAgICAgICBzdGF0ZTogei5lbnVtKFsnc3RyZWFtaW5nJywgJ2RvbmUnXSkub3B0aW9uYWwoKSxcbiAgICAgICAgICAgICAgcHJvdmlkZXJNZXRhZGF0YTogcHJvdmlkZXJNZXRhZGF0YVNjaGVtYS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB6Lm9iamVjdCh7XG4gICAgICAgICAgICAgIHR5cGU6IHoubGl0ZXJhbCgnc291cmNlLXVybCcpLFxuICAgICAgICAgICAgICBzb3VyY2VJZDogei5zdHJpbmcoKSxcbiAgICAgICAgICAgICAgdXJsOiB6LnN0cmluZygpLFxuICAgICAgICAgICAgICB0aXRsZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBwcm92aWRlck1ldGFkYXRhOiBwcm92aWRlck1ldGFkYXRhU2NoZW1hLm9wdGlvbmFsKCksXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIHoub2JqZWN0KHtcbiAgICAgICAgICAgICAgdHlwZTogei5saXRlcmFsKCdzb3VyY2UtZG9jdW1lbnQnKSxcbiAgICAgICAgICAgICAgc291cmNlSWQ6IHouc3RyaW5nKCksXG4gICAgICAgICAgICAgIG1lZGlhVHlwZTogei5zdHJpbmcoKSxcbiAgICAgICAgICAgICAgdGl0bGU6IHouc3RyaW5nKCksXG4gICAgICAgICAgICAgIGZpbGVuYW1lOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgei5vYmplY3Qoe1xuICAgICAgICAgICAgICB0eXBlOiB6LmxpdGVyYWwoJ2ZpbGUnKSxcbiAgICAgICAgICAgICAgbWVkaWFUeXBlOiB6LnN0cmluZygpLFxuICAgICAgICAgICAgICBmaWxlbmFtZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICB1cmw6IHouc3RyaW5nKCksXG4gICAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHByb3ZpZGVyTWV0YWRhdGFTY2hlbWEub3B0aW9uYWwoKSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgei5vYmplY3Qoe1xuICAgICAgICAgICAgICB0eXBlOiB6LmxpdGVyYWwoJ3N0ZXAtc3RhcnQnKSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgei5vYmplY3Qoe1xuICAgICAgICAgICAgICB0eXBlOiB6LnN0cmluZygpLnN0YXJ0c1dpdGgoJ2RhdGEtJyksXG4gICAgICAgICAgICAgIGlkOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIGRhdGE6IHoudW5rbm93bigpLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB6Lm9iamVjdCh7XG4gICAgICAgICAgICAgIHR5cGU6IHoubGl0ZXJhbCgnZHluYW1pYy10b29sJyksXG4gICAgICAgICAgICAgIHRvb2xOYW1lOiB6LnN0cmluZygpLFxuICAgICAgICAgICAgICB0b29sQ2FsbElkOiB6LnN0cmluZygpLFxuICAgICAgICAgICAgICBzdGF0ZTogei5saXRlcmFsKCdpbnB1dC1zdHJlYW1pbmcnKSxcbiAgICAgICAgICAgICAgaW5wdXQ6IHoudW5rbm93bigpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIG91dHB1dDogei5uZXZlcigpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIGVycm9yVGV4dDogei5uZXZlcigpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIHoub2JqZWN0KHtcbiAgICAgICAgICAgICAgdHlwZTogei5saXRlcmFsKCdkeW5hbWljLXRvb2wnKSxcbiAgICAgICAgICAgICAgdG9vbE5hbWU6IHouc3RyaW5nKCksXG4gICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IHouc3RyaW5nKCksXG4gICAgICAgICAgICAgIHN0YXRlOiB6LmxpdGVyYWwoJ2lucHV0LWF2YWlsYWJsZScpLFxuICAgICAgICAgICAgICBpbnB1dDogei51bmtub3duKCksXG4gICAgICAgICAgICAgIG91dHB1dDogei5uZXZlcigpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIGVycm9yVGV4dDogei5uZXZlcigpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIGNhbGxQcm92aWRlck1ldGFkYXRhOiBwcm92aWRlck1ldGFkYXRhU2NoZW1hLm9wdGlvbmFsKCksXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIHoub2JqZWN0KHtcbiAgICAgICAgICAgICAgdHlwZTogei5saXRlcmFsKCdkeW5hbWljLXRvb2wnKSxcbiAgICAgICAgICAgICAgdG9vbE5hbWU6IHouc3RyaW5nKCksXG4gICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IHouc3RyaW5nKCksXG4gICAgICAgICAgICAgIHN0YXRlOiB6LmxpdGVyYWwoJ291dHB1dC1hdmFpbGFibGUnKSxcbiAgICAgICAgICAgICAgaW5wdXQ6IHoudW5rbm93bigpLFxuICAgICAgICAgICAgICBvdXRwdXQ6IHoudW5rbm93bigpLFxuICAgICAgICAgICAgICBlcnJvclRleHQ6IHoubmV2ZXIoKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBjYWxsUHJvdmlkZXJNZXRhZGF0YTogcHJvdmlkZXJNZXRhZGF0YVNjaGVtYS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBwcmVsaW1pbmFyeTogei5ib29sZWFuKCkub3B0aW9uYWwoKSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgei5vYmplY3Qoe1xuICAgICAgICAgICAgICB0eXBlOiB6LmxpdGVyYWwoJ2R5bmFtaWMtdG9vbCcpLFxuICAgICAgICAgICAgICB0b29sTmFtZTogei5zdHJpbmcoKSxcbiAgICAgICAgICAgICAgdG9vbENhbGxJZDogei5zdHJpbmcoKSxcbiAgICAgICAgICAgICAgc3RhdGU6IHoubGl0ZXJhbCgnb3V0cHV0LWVycm9yJyksXG4gICAgICAgICAgICAgIGlucHV0OiB6LnVua25vd24oKSxcbiAgICAgICAgICAgICAgb3V0cHV0OiB6Lm5ldmVyKCkub3B0aW9uYWwoKSxcbiAgICAgICAgICAgICAgZXJyb3JUZXh0OiB6LnN0cmluZygpLFxuICAgICAgICAgICAgICBjYWxsUHJvdmlkZXJNZXRhZGF0YTogcHJvdmlkZXJNZXRhZGF0YVNjaGVtYS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB6Lm9iamVjdCh7XG4gICAgICAgICAgICAgIHR5cGU6IHouc3RyaW5nKCkuc3RhcnRzV2l0aCgndG9vbC0nKSxcbiAgICAgICAgICAgICAgdG9vbENhbGxJZDogei5zdHJpbmcoKSxcbiAgICAgICAgICAgICAgc3RhdGU6IHoubGl0ZXJhbCgnaW5wdXQtc3RyZWFtaW5nJyksXG4gICAgICAgICAgICAgIHByb3ZpZGVyRXhlY3V0ZWQ6IHouYm9vbGVhbigpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIGlucHV0OiB6LnVua25vd24oKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBvdXRwdXQ6IHoubmV2ZXIoKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBlcnJvclRleHQ6IHoubmV2ZXIoKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBhcHByb3ZhbDogei5uZXZlcigpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIHoub2JqZWN0KHtcbiAgICAgICAgICAgICAgdHlwZTogei5zdHJpbmcoKS5zdGFydHNXaXRoKCd0b29sLScpLFxuICAgICAgICAgICAgICB0b29sQ2FsbElkOiB6LnN0cmluZygpLFxuICAgICAgICAgICAgICBzdGF0ZTogei5saXRlcmFsKCdpbnB1dC1hdmFpbGFibGUnKSxcbiAgICAgICAgICAgICAgcHJvdmlkZXJFeGVjdXRlZDogei5ib29sZWFuKCkub3B0aW9uYWwoKSxcbiAgICAgICAgICAgICAgaW5wdXQ6IHoudW5rbm93bigpLFxuICAgICAgICAgICAgICBvdXRwdXQ6IHoubmV2ZXIoKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBlcnJvclRleHQ6IHoubmV2ZXIoKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBjYWxsUHJvdmlkZXJNZXRhZGF0YTogcHJvdmlkZXJNZXRhZGF0YVNjaGVtYS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBhcHByb3ZhbDogei5uZXZlcigpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIHoub2JqZWN0KHtcbiAgICAgICAgICAgICAgdHlwZTogei5zdHJpbmcoKS5zdGFydHNXaXRoKCd0b29sLScpLFxuICAgICAgICAgICAgICB0b29sQ2FsbElkOiB6LnN0cmluZygpLFxuICAgICAgICAgICAgICBzdGF0ZTogei5saXRlcmFsKCdhcHByb3ZhbC1yZXF1ZXN0ZWQnKSxcbiAgICAgICAgICAgICAgaW5wdXQ6IHoudW5rbm93bigpLFxuICAgICAgICAgICAgICBwcm92aWRlckV4ZWN1dGVkOiB6LmJvb2xlYW4oKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBvdXRwdXQ6IHoubmV2ZXIoKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBlcnJvclRleHQ6IHoubmV2ZXIoKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBjYWxsUHJvdmlkZXJNZXRhZGF0YTogcHJvdmlkZXJNZXRhZGF0YVNjaGVtYS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBhcHByb3ZhbDogei5vYmplY3Qoe1xuICAgICAgICAgICAgICAgIGlkOiB6LnN0cmluZygpLFxuICAgICAgICAgICAgICAgIGFwcHJvdmVkOiB6Lm5ldmVyKCkub3B0aW9uYWwoKSxcbiAgICAgICAgICAgICAgICByZWFzb246IHoubmV2ZXIoKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgei5vYmplY3Qoe1xuICAgICAgICAgICAgICB0eXBlOiB6LnN0cmluZygpLnN0YXJ0c1dpdGgoJ3Rvb2wtJyksXG4gICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IHouc3RyaW5nKCksXG4gICAgICAgICAgICAgIHN0YXRlOiB6LmxpdGVyYWwoJ2FwcHJvdmFsLXJlc3BvbmRlZCcpLFxuICAgICAgICAgICAgICBpbnB1dDogei51bmtub3duKCksXG4gICAgICAgICAgICAgIHByb3ZpZGVyRXhlY3V0ZWQ6IHouYm9vbGVhbigpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIG91dHB1dDogei5uZXZlcigpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIGVycm9yVGV4dDogei5uZXZlcigpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIGNhbGxQcm92aWRlck1ldGFkYXRhOiBwcm92aWRlck1ldGFkYXRhU2NoZW1hLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIGFwcHJvdmFsOiB6Lm9iamVjdCh7XG4gICAgICAgICAgICAgICAgaWQ6IHouc3RyaW5nKCksXG4gICAgICAgICAgICAgICAgYXBwcm92ZWQ6IHouYm9vbGVhbigpLFxuICAgICAgICAgICAgICAgIHJlYXNvbjogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgei5vYmplY3Qoe1xuICAgICAgICAgICAgICB0eXBlOiB6LnN0cmluZygpLnN0YXJ0c1dpdGgoJ3Rvb2wtJyksXG4gICAgICAgICAgICAgIHRvb2xDYWxsSWQ6IHouc3RyaW5nKCksXG4gICAgICAgICAgICAgIHN0YXRlOiB6LmxpdGVyYWwoJ291dHB1dC1hdmFpbGFibGUnKSxcbiAgICAgICAgICAgICAgcHJvdmlkZXJFeGVjdXRlZDogei5ib29sZWFuKCkub3B0aW9uYWwoKSxcbiAgICAgICAgICAgICAgaW5wdXQ6IHoudW5rbm93bigpLFxuICAgICAgICAgICAgICBvdXRwdXQ6IHoudW5rbm93bigpLFxuICAgICAgICAgICAgICBlcnJvclRleHQ6IHoubmV2ZXIoKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBjYWxsUHJvdmlkZXJNZXRhZGF0YTogcHJvdmlkZXJNZXRhZGF0YVNjaGVtYS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBwcmVsaW1pbmFyeTogei5ib29sZWFuKCkub3B0aW9uYWwoKSxcbiAgICAgICAgICAgICAgYXBwcm92YWw6IHpcbiAgICAgICAgICAgICAgICAub2JqZWN0KHtcbiAgICAgICAgICAgICAgICAgIGlkOiB6LnN0cmluZygpLFxuICAgICAgICAgICAgICAgICAgYXBwcm92ZWQ6IHoubGl0ZXJhbCh0cnVlKSxcbiAgICAgICAgICAgICAgICAgIHJlYXNvbjogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLm9wdGlvbmFsKCksXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIHoub2JqZWN0KHtcbiAgICAgICAgICAgICAgdHlwZTogei5zdHJpbmcoKS5zdGFydHNXaXRoKCd0b29sLScpLFxuICAgICAgICAgICAgICB0b29sQ2FsbElkOiB6LnN0cmluZygpLFxuICAgICAgICAgICAgICBzdGF0ZTogei5saXRlcmFsKCdvdXRwdXQtZXJyb3InKSxcbiAgICAgICAgICAgICAgcHJvdmlkZXJFeGVjdXRlZDogei5ib29sZWFuKCkub3B0aW9uYWwoKSxcbiAgICAgICAgICAgICAgaW5wdXQ6IHoudW5rbm93bigpLFxuICAgICAgICAgICAgICBvdXRwdXQ6IHoubmV2ZXIoKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBlcnJvclRleHQ6IHouc3RyaW5nKCksXG4gICAgICAgICAgICAgIGNhbGxQcm92aWRlck1ldGFkYXRhOiBwcm92aWRlck1ldGFkYXRhU2NoZW1hLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIGFwcHJvdmFsOiB6XG4gICAgICAgICAgICAgICAgLm9iamVjdCh7XG4gICAgICAgICAgICAgICAgICBpZDogei5zdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgIGFwcHJvdmVkOiB6LmxpdGVyYWwodHJ1ZSksXG4gICAgICAgICAgICAgICAgICByZWFzb246IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5vcHRpb25hbCgpLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB6Lm9iamVjdCh7XG4gICAgICAgICAgICAgIHR5cGU6IHouc3RyaW5nKCkuc3RhcnRzV2l0aCgndG9vbC0nKSxcbiAgICAgICAgICAgICAgdG9vbENhbGxJZDogei5zdHJpbmcoKSxcbiAgICAgICAgICAgICAgc3RhdGU6IHoubGl0ZXJhbCgnb3V0cHV0LWRlbmllZCcpLFxuICAgICAgICAgICAgICBwcm92aWRlckV4ZWN1dGVkOiB6LmJvb2xlYW4oKS5vcHRpb25hbCgpLFxuICAgICAgICAgICAgICBpbnB1dDogei51bmtub3duKCksXG4gICAgICAgICAgICAgIG91dHB1dDogei5uZXZlcigpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIGVycm9yVGV4dDogei5uZXZlcigpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIGNhbGxQcm92aWRlck1ldGFkYXRhOiBwcm92aWRlck1ldGFkYXRhU2NoZW1hLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIGFwcHJvdmFsOiB6Lm9iamVjdCh7XG4gICAgICAgICAgICAgICAgaWQ6IHouc3RyaW5nKCksXG4gICAgICAgICAgICAgICAgYXBwcm92ZWQ6IHoubGl0ZXJhbChmYWxzZSksXG4gICAgICAgICAgICAgICAgcmVhc29uOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgXSksXG4gICAgICAgICksXG4gICAgICB9KSxcbiAgICApLFxuICApLFxuKTtcblxuZXhwb3J0IHR5cGUgU2FmZVZhbGlkYXRlVUlNZXNzYWdlc1Jlc3VsdDxVSV9NRVNTQUdFIGV4dGVuZHMgVUlNZXNzYWdlPiA9XG4gIHwge1xuICAgICAgc3VjY2VzczogdHJ1ZTtcbiAgICAgIGRhdGE6IEFycmF5PFVJX01FU1NBR0U+O1xuICAgIH1cbiAgfCB7XG4gICAgICBzdWNjZXNzOiBmYWxzZTtcbiAgICAgIGVycm9yOiBFcnJvcjtcbiAgICB9O1xuXG4vKipcbiAqIFZhbGlkYXRlcyBhIGxpc3Qgb2YgVUkgbWVzc2FnZXMgbGlrZSBgdmFsaWRhdGVVSU1lc3NhZ2VzYCxcbiAqIGJ1dCBpbnN0ZWFkIG9mIHRocm93aW5nIGl0IHJldHVybnMgYHsgc3VjY2VzczogdHJ1ZSwgZGF0YSB9YFxuICogb3IgYHsgc3VjY2VzczogZmFsc2UsIGVycm9yIH1gLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc2FmZVZhbGlkYXRlVUlNZXNzYWdlczxVSV9NRVNTQUdFIGV4dGVuZHMgVUlNZXNzYWdlPih7XG4gIG1lc3NhZ2VzLFxuICBtZXRhZGF0YVNjaGVtYSxcbiAgZGF0YVNjaGVtYXMsXG4gIHRvb2xzLFxufToge1xuICBtZXNzYWdlczogdW5rbm93bjtcbiAgbWV0YWRhdGFTY2hlbWE/OlxuICAgIHwgVmFsaWRhdG9yPFVJTWVzc2FnZVsnbWV0YWRhdGEnXT5cbiAgICB8IFN0YW5kYXJkU2NoZW1hVjE8dW5rbm93biwgVUlfTUVTU0FHRVsnbWV0YWRhdGEnXT47XG4gIGRhdGFTY2hlbWFzPzoge1xuICAgIFtOQU1FIGluIGtleW9mIEluZmVyVUlNZXNzYWdlRGF0YTxVSV9NRVNTQUdFPiAmIHN0cmluZ10/OlxuICAgICAgfCBWYWxpZGF0b3I8SW5mZXJVSU1lc3NhZ2VEYXRhPFVJX01FU1NBR0U+W05BTUVdPlxuICAgICAgfCBTdGFuZGFyZFNjaGVtYVYxPHVua25vd24sIEluZmVyVUlNZXNzYWdlRGF0YTxVSV9NRVNTQUdFPltOQU1FXT47XG4gIH07XG4gIHRvb2xzPzoge1xuICAgIFtOQU1FIGluIGtleW9mIEluZmVyVUlNZXNzYWdlVG9vbHM8VUlfTUVTU0FHRT4gJiBzdHJpbmddPzogVG9vbDxcbiAgICAgIEluZmVyVUlNZXNzYWdlVG9vbHM8VUlfTUVTU0FHRT5bTkFNRV1bJ2lucHV0J10sXG4gICAgICBJbmZlclVJTWVzc2FnZVRvb2xzPFVJX01FU1NBR0U+W05BTUVdWydvdXRwdXQnXVxuICAgID47XG4gIH07XG59KTogUHJvbWlzZTxTYWZlVmFsaWRhdGVVSU1lc3NhZ2VzUmVzdWx0PFVJX01FU1NBR0U+PiB7XG4gIHRyeSB7XG4gICAgaWYgKG1lc3NhZ2VzID09IG51bGwpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICBlcnJvcjogbmV3IEludmFsaWRBcmd1bWVudEVycm9yKHtcbiAgICAgICAgICBwYXJhbWV0ZXI6ICdtZXNzYWdlcycsXG4gICAgICAgICAgdmFsdWU6IG1lc3NhZ2VzLFxuICAgICAgICAgIG1lc3NhZ2U6ICdtZXNzYWdlcyBwYXJhbWV0ZXIgbXVzdCBiZSBwcm92aWRlZCcsXG4gICAgICAgIH0pLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCB2YWxpZGF0ZWRNZXNzYWdlcyA9IGF3YWl0IHZhbGlkYXRlVHlwZXMoe1xuICAgICAgdmFsdWU6IG1lc3NhZ2VzLFxuICAgICAgc2NoZW1hOiB1aU1lc3NhZ2VzU2NoZW1hLFxuICAgIH0pO1xuXG4gICAgaWYgKG1ldGFkYXRhU2NoZW1hKSB7XG4gICAgICBmb3IgKGNvbnN0IG1lc3NhZ2Ugb2YgdmFsaWRhdGVkTWVzc2FnZXMpIHtcbiAgICAgICAgYXdhaXQgdmFsaWRhdGVUeXBlcyh7XG4gICAgICAgICAgdmFsdWU6IG1lc3NhZ2UubWV0YWRhdGEsXG4gICAgICAgICAgc2NoZW1hOiBtZXRhZGF0YVNjaGVtYSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGRhdGFTY2hlbWFzKSB7XG4gICAgICBmb3IgKGNvbnN0IG1lc3NhZ2Ugb2YgdmFsaWRhdGVkTWVzc2FnZXMpIHtcbiAgICAgICAgY29uc3QgZGF0YVBhcnRzID0gbWVzc2FnZS5wYXJ0cy5maWx0ZXIocGFydCA9PlxuICAgICAgICAgIHBhcnQudHlwZS5zdGFydHNXaXRoKCdkYXRhLScpLFxuICAgICAgICApIGFzIERhdGFVSVBhcnQ8SW5mZXJVSU1lc3NhZ2VEYXRhPFVJX01FU1NBR0U+PltdO1xuXG4gICAgICAgIGZvciAoY29uc3QgZGF0YVBhcnQgb2YgZGF0YVBhcnRzKSB7XG4gICAgICAgICAgY29uc3QgZGF0YU5hbWUgPSBkYXRhUGFydC50eXBlLnNsaWNlKDUpO1xuICAgICAgICAgIGNvbnN0IGRhdGFTY2hlbWEgPSBkYXRhU2NoZW1hc1tkYXRhTmFtZV07XG5cbiAgICAgICAgICBpZiAoIWRhdGFTY2hlbWEpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgICAgICBlcnJvcjogbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3Ioe1xuICAgICAgICAgICAgICAgIHZhbHVlOiBkYXRhUGFydC5kYXRhLFxuICAgICAgICAgICAgICAgIGNhdXNlOiBgTm8gZGF0YSBzY2hlbWEgZm91bmQgZm9yIGRhdGEgcGFydCAke2RhdGFOYW1lfWAsXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBhd2FpdCB2YWxpZGF0ZVR5cGVzKHtcbiAgICAgICAgICAgIHZhbHVlOiBkYXRhUGFydC5kYXRhLFxuICAgICAgICAgICAgc2NoZW1hOiBkYXRhU2NoZW1hLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRvb2xzKSB7XG4gICAgICBmb3IgKGNvbnN0IG1lc3NhZ2Ugb2YgdmFsaWRhdGVkTWVzc2FnZXMpIHtcbiAgICAgICAgY29uc3QgdG9vbFBhcnRzID0gbWVzc2FnZS5wYXJ0cy5maWx0ZXIocGFydCA9PlxuICAgICAgICAgIHBhcnQudHlwZS5zdGFydHNXaXRoKCd0b29sLScpLFxuICAgICAgICApIGFzIFRvb2xVSVBhcnQ8SW5mZXJVSU1lc3NhZ2VUb29sczxVSV9NRVNTQUdFPj5bXTtcblxuICAgICAgICBmb3IgKGNvbnN0IHRvb2xQYXJ0IG9mIHRvb2xQYXJ0cykge1xuICAgICAgICAgIGNvbnN0IHRvb2xOYW1lID0gdG9vbFBhcnQudHlwZS5zbGljZSg1KTtcbiAgICAgICAgICBjb25zdCB0b29sID0gdG9vbHNbdG9vbE5hbWVdO1xuXG4gICAgICAgICAgaWYgKCF0b29sKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgICAgZXJyb3I6IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKHtcbiAgICAgICAgICAgICAgICB2YWx1ZTogdG9vbFBhcnQuaW5wdXQsXG4gICAgICAgICAgICAgICAgY2F1c2U6IGBObyB0b29sIHNjaGVtYSBmb3VuZCBmb3IgdG9vbCBwYXJ0ICR7dG9vbE5hbWV9YCxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHRvb2xQYXJ0LnN0YXRlID09PSAnaW5wdXQtYXZhaWxhYmxlJyB8fFxuICAgICAgICAgICAgdG9vbFBhcnQuc3RhdGUgPT09ICdvdXRwdXQtYXZhaWxhYmxlJyB8fFxuICAgICAgICAgICAgdG9vbFBhcnQuc3RhdGUgPT09ICdvdXRwdXQtZXJyb3InXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBhd2FpdCB2YWxpZGF0ZVR5cGVzKHtcbiAgICAgICAgICAgICAgdmFsdWU6IHRvb2xQYXJ0LmlucHV0LFxuICAgICAgICAgICAgICBzY2hlbWE6IHRvb2wuaW5wdXRTY2hlbWEsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodG9vbFBhcnQuc3RhdGUgPT09ICdvdXRwdXQtYXZhaWxhYmxlJyAmJiB0b29sLm91dHB1dFNjaGVtYSkge1xuICAgICAgICAgICAgYXdhaXQgdmFsaWRhdGVUeXBlcyh7XG4gICAgICAgICAgICAgIHZhbHVlOiB0b29sUGFydC5vdXRwdXQsXG4gICAgICAgICAgICAgIHNjaGVtYTogdG9vbC5vdXRwdXRTY2hlbWEsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgIGRhdGE6IHZhbGlkYXRlZE1lc3NhZ2VzIGFzIEFycmF5PFVJX01FU1NBR0U+LFxuICAgIH07XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY29uc3QgZXJyID0gZXJyb3IgYXMgRXJyb3I7XG5cbiAgICByZXR1cm4ge1xuICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICBlcnJvcjogZXJyLFxuICAgIH07XG4gIH1cbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgYSBsaXN0IG9mIFVJIG1lc3NhZ2VzLlxuICpcbiAqIE1ldGFkYXRhLCBkYXRhIHBhcnRzLCBhbmQgZ2VuZXJpYyB0b29sIGNhbGwgc3RydWN0dXJlcyBhcmUgb25seSB2YWxpZGF0ZWQgaWZcbiAqIHRoZSBjb3JyZXNwb25kaW5nIHNjaGVtYXMgYXJlIHByb3ZpZGVkLiBPdGhlcndpc2UsIHRoZXkgYXJlIGFzc3VtZWQgdG8gYmVcbiAqIHZhbGlkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gdmFsaWRhdGVVSU1lc3NhZ2VzPFVJX01FU1NBR0UgZXh0ZW5kcyBVSU1lc3NhZ2U+KHtcbiAgbWVzc2FnZXMsXG4gIG1ldGFkYXRhU2NoZW1hLFxuICBkYXRhU2NoZW1hcyxcbiAgdG9vbHMsXG59OiB7XG4gIG1lc3NhZ2VzOiB1bmtub3duO1xuICBtZXRhZGF0YVNjaGVtYT86XG4gICAgfCBWYWxpZGF0b3I8VUlNZXNzYWdlWydtZXRhZGF0YSddPlxuICAgIHwgU3RhbmRhcmRTY2hlbWFWMTx1bmtub3duLCBVSV9NRVNTQUdFWydtZXRhZGF0YSddPjtcbiAgZGF0YVNjaGVtYXM/OiB7XG4gICAgW05BTUUgaW4ga2V5b2YgSW5mZXJVSU1lc3NhZ2VEYXRhPFVJX01FU1NBR0U+ICYgc3RyaW5nXT86XG4gICAgICB8IFZhbGlkYXRvcjxJbmZlclVJTWVzc2FnZURhdGE8VUlfTUVTU0FHRT5bTkFNRV0+XG4gICAgICB8IFN0YW5kYXJkU2NoZW1hVjE8dW5rbm93biwgSW5mZXJVSU1lc3NhZ2VEYXRhPFVJX01FU1NBR0U+W05BTUVdPjtcbiAgfTtcbiAgdG9vbHM/OiB7XG4gICAgW05BTUUgaW4ga2V5b2YgSW5mZXJVSU1lc3NhZ2VUb29sczxVSV9NRVNTQUdFPiAmIHN0cmluZ10/OiBUb29sPFxuICAgICAgSW5mZXJVSU1lc3NhZ2VUb29sczxVSV9NRVNTQUdFPltOQU1FXVsnaW5wdXQnXSxcbiAgICAgIEluZmVyVUlNZXNzYWdlVG9vbHM8VUlfTUVTU0FHRT5bTkFNRV1bJ291dHB1dCddXG4gICAgPjtcbiAgfTtcbn0pOiBQcm9taXNlPEFycmF5PFVJX01FU1NBR0U+PiB7XG4gIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgc2FmZVZhbGlkYXRlVUlNZXNzYWdlcyh7XG4gICAgbWVzc2FnZXMsXG4gICAgbWV0YWRhdGFTY2hlbWEsXG4gICAgZGF0YVNjaGVtYXMsXG4gICAgdG9vbHMsXG4gIH0pO1xuXG4gIGlmICghcmVzcG9uc2Uuc3VjY2VzcykgdGhyb3cgcmVzcG9uc2UuZXJyb3I7XG5cbiAgcmV0dXJuIHJlc3BvbnNlLmRhdGE7XG59XG4iLCAiaW1wb3J0IHtcbiAgZ2VuZXJhdGVJZCBhcyBnZW5lcmF0ZUlkRnVuYyxcbiAgZ2V0RXJyb3JNZXNzYWdlLFxuICBJZEdlbmVyYXRvcixcbn0gZnJvbSAnQGFpLXNkay9wcm92aWRlci11dGlscyc7XG5pbXBvcnQgeyBVSU1lc3NhZ2UgfSBmcm9tICcuLi91aS91aS1tZXNzYWdlcyc7XG5pbXBvcnQgeyBoYW5kbGVVSU1lc3NhZ2VTdHJlYW1GaW5pc2ggfSBmcm9tICcuL2hhbmRsZS11aS1tZXNzYWdlLXN0cmVhbS1maW5pc2gnO1xuaW1wb3J0IHsgSW5mZXJVSU1lc3NhZ2VDaHVuayB9IGZyb20gJy4vdWktbWVzc2FnZS1jaHVua3MnO1xuaW1wb3J0IHsgVUlNZXNzYWdlU3RyZWFtT25GaW5pc2hDYWxsYmFjayB9IGZyb20gJy4vdWktbWVzc2FnZS1zdHJlYW0tb24tZmluaXNoLWNhbGxiYWNrJztcbmltcG9ydCB7IFVJTWVzc2FnZVN0cmVhbVdyaXRlciB9IGZyb20gJy4vdWktbWVzc2FnZS1zdHJlYW0td3JpdGVyJztcblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVVJTWVzc2FnZVN0cmVhbTxVSV9NRVNTQUdFIGV4dGVuZHMgVUlNZXNzYWdlPih7XG4gIGV4ZWN1dGUsXG4gIG9uRXJyb3IgPSBnZXRFcnJvck1lc3NhZ2UsXG4gIG9yaWdpbmFsTWVzc2FnZXMsXG4gIG9uRmluaXNoLFxuICBnZW5lcmF0ZUlkID0gZ2VuZXJhdGVJZEZ1bmMsXG59OiB7XG4gIGV4ZWN1dGU6IChvcHRpb25zOiB7XG4gICAgd3JpdGVyOiBVSU1lc3NhZ2VTdHJlYW1Xcml0ZXI8VUlfTUVTU0FHRT47XG4gIH0pID0+IFByb21pc2U8dm9pZD4gfCB2b2lkO1xuICBvbkVycm9yPzogKGVycm9yOiB1bmtub3duKSA9PiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBvcmlnaW5hbCBtZXNzYWdlcy4gSWYgdGhleSBhcmUgcHJvdmlkZWQsIHBlcnNpc3RlbmNlIG1vZGUgaXMgYXNzdW1lZCxcbiAgICogYW5kIGEgbWVzc2FnZSBJRCBpcyBwcm92aWRlZCBmb3IgdGhlIHJlc3BvbnNlIG1lc3NhZ2UuXG4gICAqL1xuICBvcmlnaW5hbE1lc3NhZ2VzPzogVUlfTUVTU0FHRVtdO1xuXG4gIG9uRmluaXNoPzogVUlNZXNzYWdlU3RyZWFtT25GaW5pc2hDYWxsYmFjazxVSV9NRVNTQUdFPjtcblxuICBnZW5lcmF0ZUlkPzogSWRHZW5lcmF0b3I7XG59KTogUmVhZGFibGVTdHJlYW08SW5mZXJVSU1lc3NhZ2VDaHVuazxVSV9NRVNTQUdFPj4ge1xuICBsZXQgY29udHJvbGxlciE6IFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXI8XG4gICAgSW5mZXJVSU1lc3NhZ2VDaHVuazxVSV9NRVNTQUdFPlxuICA+O1xuXG4gIGNvbnN0IG9uZ29pbmdTdHJlYW1Qcm9taXNlczogUHJvbWlzZTx2b2lkPltdID0gW107XG5cbiAgY29uc3Qgc3RyZWFtID0gbmV3IFJlYWRhYmxlU3RyZWFtKHtcbiAgICBzdGFydChjb250cm9sbGVyQXJnKSB7XG4gICAgICBjb250cm9sbGVyID0gY29udHJvbGxlckFyZztcbiAgICB9LFxuICB9KTtcblxuICBmdW5jdGlvbiBzYWZlRW5xdWV1ZShkYXRhOiBJbmZlclVJTWVzc2FnZUNodW5rPFVJX01FU1NBR0U+KSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShkYXRhKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLy8gc3VwcHJlc3MgZXJyb3JzIHdoZW4gdGhlIHN0cmVhbSBoYXMgYmVlbiBjbG9zZWRcbiAgICB9XG4gIH1cblxuICB0cnkge1xuICAgIGNvbnN0IHJlc3VsdCA9IGV4ZWN1dGUoe1xuICAgICAgd3JpdGVyOiB7XG4gICAgICAgIHdyaXRlKHBhcnQ6IEluZmVyVUlNZXNzYWdlQ2h1bms8VUlfTUVTU0FHRT4pIHtcbiAgICAgICAgICBzYWZlRW5xdWV1ZShwYXJ0KTtcbiAgICAgICAgfSxcbiAgICAgICAgbWVyZ2Uoc3RyZWFtQXJnKSB7XG4gICAgICAgICAgb25nb2luZ1N0cmVhbVByb21pc2VzLnB1c2goXG4gICAgICAgICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCByZWFkZXIgPSBzdHJlYW1BcmcuZ2V0UmVhZGVyKCk7XG4gICAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgeyBkb25lLCB2YWx1ZSB9ID0gYXdhaXQgcmVhZGVyLnJlYWQoKTtcbiAgICAgICAgICAgICAgICBpZiAoZG9uZSkgYnJlYWs7XG4gICAgICAgICAgICAgICAgc2FmZUVucXVldWUodmFsdWUpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KSgpLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgc2FmZUVucXVldWUoe1xuICAgICAgICAgICAgICAgIHR5cGU6ICdlcnJvcicsXG4gICAgICAgICAgICAgICAgZXJyb3JUZXh0OiBvbkVycm9yKGVycm9yKSxcbiAgICAgICAgICAgICAgfSBhcyBJbmZlclVJTWVzc2FnZUNodW5rPFVJX01FU1NBR0U+KTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICk7XG4gICAgICAgIH0sXG4gICAgICAgIG9uRXJyb3IsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgaWYgKHJlc3VsdCkge1xuICAgICAgb25nb2luZ1N0cmVhbVByb21pc2VzLnB1c2goXG4gICAgICAgIHJlc3VsdC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgc2FmZUVucXVldWUoe1xuICAgICAgICAgICAgdHlwZTogJ2Vycm9yJyxcbiAgICAgICAgICAgIGVycm9yVGV4dDogb25FcnJvcihlcnJvciksXG4gICAgICAgICAgfSBhcyBJbmZlclVJTWVzc2FnZUNodW5rPFVJX01FU1NBR0U+KTtcbiAgICAgICAgfSksXG4gICAgICApO1xuICAgIH1cbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBzYWZlRW5xdWV1ZSh7XG4gICAgICB0eXBlOiAnZXJyb3InLFxuICAgICAgZXJyb3JUZXh0OiBvbkVycm9yKGVycm9yKSxcbiAgICB9IGFzIEluZmVyVUlNZXNzYWdlQ2h1bms8VUlfTUVTU0FHRT4pO1xuICB9XG5cbiAgLy8gV2FpdCB1bnRpbCBhbGwgb25nb2luZyBzdHJlYW1zIGFyZSBkb25lLiBUaGlzIGFwcHJvYWNoIGVuYWJsZXMgbWVyZ2luZ1xuICAvLyBzdHJlYW1zIGV2ZW4gYWZ0ZXIgZXhlY3V0ZSBoYXMgcmV0dXJuZWQsIGFzIGxvbmcgYXMgdGhlcmUgaXMgc3RpbGwgYW5cbiAgLy8gb3BlbiBtZXJnZWQgc3RyZWFtLiBUaGlzIGlzIGltcG9ydGFudCB0byBlLmcuIGZvcndhcmQgbmV3IHN0cmVhbXMgYW5kXG4gIC8vIGZyb20gY2FsbGJhY2tzLlxuICBjb25zdCB3YWl0Rm9yU3RyZWFtczogUHJvbWlzZTx2b2lkPiA9IG5ldyBQcm9taXNlKGFzeW5jIHJlc29sdmUgPT4ge1xuICAgIHdoaWxlIChvbmdvaW5nU3RyZWFtUHJvbWlzZXMubGVuZ3RoID4gMCkge1xuICAgICAgYXdhaXQgb25nb2luZ1N0cmVhbVByb21pc2VzLnNoaWZ0KCk7XG4gICAgfVxuICAgIHJlc29sdmUoKTtcbiAgfSk7XG5cbiAgd2FpdEZvclN0cmVhbXMuZmluYWxseSgoKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnRyb2xsZXIuY2xvc2UoKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLy8gc3VwcHJlc3MgZXJyb3JzIHdoZW4gdGhlIHN0cmVhbSBoYXMgYmVlbiBjbG9zZWRcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBoYW5kbGVVSU1lc3NhZ2VTdHJlYW1GaW5pc2g8VUlfTUVTU0FHRT4oe1xuICAgIHN0cmVhbSxcbiAgICBtZXNzYWdlSWQ6IGdlbmVyYXRlSWQoKSxcbiAgICBvcmlnaW5hbE1lc3NhZ2VzLFxuICAgIG9uRmluaXNoLFxuICAgIG9uRXJyb3IsXG4gIH0pO1xufVxuIiwgImltcG9ydCB7IFVJTWVzc2FnZSB9IGZyb20gJy4uL3VpL3VpLW1lc3NhZ2VzJztcbmltcG9ydCB7IFVJTWVzc2FnZUNodW5rIH0gZnJvbSAnLi91aS1tZXNzYWdlLWNodW5rcyc7XG5pbXBvcnQge1xuICBjcmVhdGVTdHJlYW1pbmdVSU1lc3NhZ2VTdGF0ZSxcbiAgcHJvY2Vzc1VJTWVzc2FnZVN0cmVhbSxcbiAgU3RyZWFtaW5nVUlNZXNzYWdlU3RhdGUsXG59IGZyb20gJy4uL3VpL3Byb2Nlc3MtdWktbWVzc2FnZS1zdHJlYW0nO1xuaW1wb3J0IHtcbiAgQXN5bmNJdGVyYWJsZVN0cmVhbSxcbiAgY3JlYXRlQXN5bmNJdGVyYWJsZVN0cmVhbSxcbn0gZnJvbSAnLi4vdXRpbC9hc3luYy1pdGVyYWJsZS1zdHJlYW0nO1xuaW1wb3J0IHsgY29uc3VtZVN0cmVhbSB9IGZyb20gJy4uL3V0aWwvY29uc3VtZS1zdHJlYW0nO1xuXG4vKipcbiAqIFRyYW5zZm9ybXMgYSBzdHJlYW0gb2YgYFVJTWVzc2FnZUNodW5rYHMgaW50byBhbiBgQXN5bmNJdGVyYWJsZVN0cmVhbWAgb2YgYFVJTWVzc2FnZWBzLlxuICpcbiAqIEBwYXJhbSBvcHRpb25zLm1lc3NhZ2UgLSBUaGUgbGFzdCBhc3Npc3RhbnQgbWVzc2FnZSB0byB1c2UgYXMgYSBzdGFydGluZyBwb2ludCB3aGVuIHRoZSBjb252ZXJzYXRpb24gaXMgcmVzdW1lZC4gT3RoZXJ3aXNlIHVuZGVmaW5lZC5cbiAqIEBwYXJhbSBvcHRpb25zLnN0cmVhbSAtIFRoZSBzdHJlYW0gb2YgYFVJTWVzc2FnZUNodW5rYHMgdG8gcmVhZC5cbiAqIEBwYXJhbSBvcHRpb25zLnRlcm1pbmF0ZU9uRXJyb3IgLSBXaGV0aGVyIHRvIHRlcm1pbmF0ZSB0aGUgc3RyZWFtIGlmIGFuIGVycm9yIG9jY3Vycy5cbiAqIEBwYXJhbSBvcHRpb25zLm9uRXJyb3IgLSBBIGZ1bmN0aW9uIHRoYXQgaXMgY2FsbGVkIHdoZW4gYW4gZXJyb3Igb2NjdXJzLlxuICpcbiAqIEByZXR1cm5zIEFuIGBBc3luY0l0ZXJhYmxlU3RyZWFtYCBvZiBgVUlNZXNzYWdlYHMuIEVhY2ggc3RyZWFtIHBhcnQgaXMgYSBkaWZmZXJlbnQgc3RhdGUgb2YgdGhlIHNhbWUgbWVzc2FnZVxuICogYXMgaXQgaXMgYmVpbmcgY29tcGxldGVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVhZFVJTWVzc2FnZVN0cmVhbTxVSV9NRVNTQUdFIGV4dGVuZHMgVUlNZXNzYWdlPih7XG4gIG1lc3NhZ2UsXG4gIHN0cmVhbSxcbiAgb25FcnJvcixcbiAgdGVybWluYXRlT25FcnJvciA9IGZhbHNlLFxufToge1xuICBtZXNzYWdlPzogVUlfTUVTU0FHRTtcbiAgc3RyZWFtOiBSZWFkYWJsZVN0cmVhbTxVSU1lc3NhZ2VDaHVuaz47XG4gIG9uRXJyb3I/OiAoZXJyb3I6IHVua25vd24pID0+IHZvaWQ7XG4gIHRlcm1pbmF0ZU9uRXJyb3I/OiBib29sZWFuO1xufSk6IEFzeW5jSXRlcmFibGVTdHJlYW08VUlfTUVTU0FHRT4ge1xuICBsZXQgY29udHJvbGxlcjogUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcjxVSV9NRVNTQUdFPiB8IHVuZGVmaW5lZDtcbiAgbGV0IGhhc0Vycm9yZWQgPSBmYWxzZTtcblxuICBjb25zdCBvdXRwdXRTdHJlYW0gPSBuZXcgUmVhZGFibGVTdHJlYW08VUlfTUVTU0FHRT4oe1xuICAgIHN0YXJ0KGNvbnRyb2xsZXJQYXJhbSkge1xuICAgICAgY29udHJvbGxlciA9IGNvbnRyb2xsZXJQYXJhbTtcbiAgICB9LFxuICB9KTtcblxuICBjb25zdCBzdGF0ZSA9IGNyZWF0ZVN0cmVhbWluZ1VJTWVzc2FnZVN0YXRlPFVJX01FU1NBR0U+KHtcbiAgICBtZXNzYWdlSWQ6IG1lc3NhZ2U/LmlkID8/ICcnLFxuICAgIGxhc3RNZXNzYWdlOiBtZXNzYWdlLFxuICB9KTtcblxuICBjb25zdCBoYW5kbGVFcnJvciA9IChlcnJvcjogdW5rbm93bikgPT4ge1xuICAgIG9uRXJyb3I/LihlcnJvcik7XG5cbiAgICBpZiAoIWhhc0Vycm9yZWQgJiYgdGVybWluYXRlT25FcnJvcikge1xuICAgICAgaGFzRXJyb3JlZCA9IHRydWU7XG4gICAgICBjb250cm9sbGVyPy5lcnJvcihlcnJvcik7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN1bWVTdHJlYW0oe1xuICAgIHN0cmVhbTogcHJvY2Vzc1VJTWVzc2FnZVN0cmVhbSh7XG4gICAgICBzdHJlYW0sXG4gICAgICBydW5VcGRhdGVNZXNzYWdlSm9iKFxuICAgICAgICBqb2I6IChvcHRpb25zOiB7XG4gICAgICAgICAgc3RhdGU6IFN0cmVhbWluZ1VJTWVzc2FnZVN0YXRlPFVJX01FU1NBR0U+O1xuICAgICAgICAgIHdyaXRlOiAoKSA9PiB2b2lkO1xuICAgICAgICB9KSA9PiBQcm9taXNlPHZvaWQ+LFxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBqb2Ioe1xuICAgICAgICAgIHN0YXRlLFxuICAgICAgICAgIHdyaXRlOiAoKSA9PiB7XG4gICAgICAgICAgICBjb250cm9sbGVyPy5lbnF1ZXVlKHN0cnVjdHVyZWRDbG9uZShzdGF0ZS5tZXNzYWdlKSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICAgb25FcnJvcjogaGFuZGxlRXJyb3IsXG4gICAgfSksXG4gICAgb25FcnJvcjogaGFuZGxlRXJyb3IsXG4gIH0pLmZpbmFsbHkoKCkgPT4ge1xuICAgIC8vIE9ubHkgY2xvc2UgaWYgbm8gZXJyb3Igb2NjdXJyZWQuIENhbGxpbmcgY2xvc2UoKSBvbiBhbiBlcnJvcmVkIGNvbnRyb2xsZXJcbiAgICAvLyB0aHJvd3MgXCJJbnZhbGlkIHN0YXRlOiBDb250cm9sbGVyIGlzIGFscmVhZHkgY2xvc2VkXCIgVHlwZUVycm9yLlxuICAgIGlmICghaGFzRXJyb3JlZCkge1xuICAgICAgY29udHJvbGxlcj8uY2xvc2UoKTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBjcmVhdGVBc3luY0l0ZXJhYmxlU3RyZWFtKG91dHB1dFN0cmVhbSk7XG59XG4iLCAiLyoqX19pbnRlcm5hbF93b3JrZmxvd3N7XCJ3b3JrZmxvd3NcIjp7XCJleGFtcGxlL3dvcmtmbG93cy8zX3N0cmVhbXMudHNcIjp7XCJzdHJlYW1zXCI6e1wid29ya2Zsb3dJZFwiOlwid29ya2Zsb3cvL2V4YW1wbGUvd29ya2Zsb3dzLzNfc3RyZWFtcy50cy8vc3RyZWFtc1wifX19LFwic3RlcHNcIjp7XCJleGFtcGxlL3dvcmtmbG93cy8zX3N0cmVhbXMudHNcIjp7XCJjb25zdW1lU3RyZWFtc1wiOntcInN0ZXBJZFwiOlwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvM19zdHJlYW1zLnRzLy9jb25zdW1lU3RyZWFtc1wifSxcImdlblN0cmVhbVwiOntcInN0ZXBJZFwiOlwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvM19zdHJlYW1zLnRzLy9nZW5TdHJlYW1cIn19fX0qLztcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZW5TdHJlYW0oKSB7XG4gICAgcmV0dXJuIGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1VTRV9TVEVQXCIpXShcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzNfc3RyZWFtcy50cy8vZ2VuU3RyZWFtXCIpKCk7XG59XG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY29uc3VtZVN0cmVhbXMoLi4uc3RyZWFtcykge1xuICAgIHJldHVybiBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19VU0VfU1RFUFwiKV0oXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy8zX3N0cmVhbXMudHMvL2NvbnN1bWVTdHJlYW1zXCIpKC4uLnN0cmVhbXMpO1xufVxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHN0cmVhbXMoKSB7XG4gICAgY29uc29sZS5sb2coJ1N0cmVhbXMgd29ya2Zsb3cgc3RhcnRlZCcpO1xuICAgIGNvbnN0IFtzMSwgczJdID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICBnZW5TdHJlYW0oKSxcbiAgICAgICAgZ2VuU3RyZWFtKClcbiAgICBdKTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjb25zdW1lU3RyZWFtcyhzMSwgczIpO1xuICAgIGNvbnNvbGUubG9nKGBTdHJlYW1zIHdvcmtmbG93IGNvbXBsZXRlZC4gUmVzdWx0OiAke3Jlc3VsdC5zbGljZSgwLCAxMDApfWApO1xuICAgIHJldHVybiB7XG4gICAgICAgIG1lc3NhZ2U6ICdTdHJlYW1zIHByb2Nlc3NlZCBzdWNjZXNzZnVsbHknLFxuICAgICAgICBkYXRhTGVuZ3RoOiByZXN1bHQubGVuZ3RoLFxuICAgICAgICBwcmV2aWV3OiByZXN1bHQuc2xpY2UoMCwgMTAwKVxuICAgIH07XG59XG5zdHJlYW1zLndvcmtmbG93SWQgPSBcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy8zX3N0cmVhbXMudHMvL3N0cmVhbXNcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShnZW5TdHJlYW0sIFN5bWJvbC5mb3IoXCJXT1JLRkxPV19TVEVQX0ZVTkNUSU9OX05BTUVcIiksIHtcbiAgICB2YWx1ZTogXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy8zX3N0cmVhbXMudHMvL2dlblN0cmVhbVwiLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlXG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb25zdW1lU3RyZWFtcywgU3ltYm9sLmZvcihcIldPUktGTE9XX1NURVBfRlVOQ1RJT05fTkFNRVwiKSwge1xuICAgIHZhbHVlOiBcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzNfc3RyZWFtcy50cy8vY29uc3VtZVN0cmVhbXNcIixcbiAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiBmYWxzZVxufSk7XG4iLCAiaW1wb3J0IHsgY3JlYXRlV2ViaG9vaywgc2xlZXAgfSBmcm9tIFwid29ya2Zsb3dcIjtcbi8qKl9faW50ZXJuYWxfd29ya2Zsb3dze1wid29ya2Zsb3dzXCI6e1wiZXhhbXBsZS93b3JrZmxvd3MvN19mdWxsLnRzXCI6e1wiaGFuZGxlVXNlclNpZ251cFwiOntcIndvcmtmbG93SWRcIjpcIndvcmtmbG93Ly9leGFtcGxlL3dvcmtmbG93cy83X2Z1bGwudHMvL2hhbmRsZVVzZXJTaWdudXBcIn19fSxcInN0ZXBzXCI6e1wiZXhhbXBsZS93b3JrZmxvd3MvN19mdWxsLnRzXCI6e1wiY3JlYXRlVXNlclwiOntcInN0ZXBJZFwiOlwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvN19mdWxsLnRzLy9jcmVhdGVVc2VyXCJ9LFwic2VuZE9uYm9hcmRpbmdFbWFpbFwiOntcInN0ZXBJZFwiOlwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvN19mdWxsLnRzLy9zZW5kT25ib2FyZGluZ0VtYWlsXCJ9LFwic2VuZFdlbGNvbWVFbWFpbFwiOntcInN0ZXBJZFwiOlwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvN19mdWxsLnRzLy9zZW5kV2VsY29tZUVtYWlsXCJ9fX19Ki87XG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaGFuZGxlVXNlclNpZ251cChlbWFpbCkge1xuICAgIGNvbnN0IHVzZXIgPSBhd2FpdCBjcmVhdGVVc2VyKGVtYWlsKTtcbiAgICBhd2FpdCBzZW5kV2VsY29tZUVtYWlsKHVzZXIpO1xuICAgIGF3YWl0IHNsZWVwKCc1cycpO1xuICAgIGNvbnN0IHdlYmhvb2sgPSBjcmVhdGVXZWJob29rKCk7XG4gICAgYXdhaXQgc2VuZE9uYm9hcmRpbmdFbWFpbCh1c2VyLCB3ZWJob29rLnVybCk7XG4gICAgYXdhaXQgd2ViaG9vaztcbiAgICBjb25zb2xlLmxvZygnV2ViaG9vayBSZXNvbHZlZCcpO1xuICAgIHJldHVybiB7XG4gICAgICAgIHVzZXJJZDogdXNlci5pZCxcbiAgICAgICAgc3RhdHVzOiAnb25ib2FyZGVkJ1xuICAgIH07XG59XG5hc3luYyBmdW5jdGlvbiBjcmVhdGVVc2VyKGVtYWlsKSB7XG4gICAgcmV0dXJuIGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1VTRV9TVEVQXCIpXShcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzdfZnVsbC50cy8vY3JlYXRlVXNlclwiKShlbWFpbCk7XG59XG5hc3luYyBmdW5jdGlvbiBzZW5kV2VsY29tZUVtYWlsKHVzZXIpIHtcbiAgICByZXR1cm4gZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildKFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvN19mdWxsLnRzLy9zZW5kV2VsY29tZUVtYWlsXCIpKHVzZXIpO1xufVxuYXN5bmMgZnVuY3Rpb24gc2VuZE9uYm9hcmRpbmdFbWFpbCh1c2VyLCBjYWxsYmFjaykge1xuICAgIHJldHVybiBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19VU0VfU1RFUFwiKV0oXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy83X2Z1bGwudHMvL3NlbmRPbmJvYXJkaW5nRW1haWxcIikodXNlciwgY2FsbGJhY2spO1xufVxuaGFuZGxlVXNlclNpZ251cC53b3JrZmxvd0lkID0gXCJ3b3JrZmxvdy8vZXhhbXBsZS93b3JrZmxvd3MvN19mdWxsLnRzLy9oYW5kbGVVc2VyU2lnbnVwXCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoY3JlYXRlVXNlciwgU3ltYm9sLmZvcihcIldPUktGTE9XX1NURVBfRlVOQ1RJT05fTkFNRVwiKSwge1xuICAgIHZhbHVlOiBcInN0ZXAvL2V4YW1wbGUvd29ya2Zsb3dzLzdfZnVsbC50cy8vY3JlYXRlVXNlclwiLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlXG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShzZW5kV2VsY29tZUVtYWlsLCBTeW1ib2wuZm9yKFwiV09SS0ZMT1dfU1RFUF9GVU5DVElPTl9OQU1FXCIpLCB7XG4gICAgdmFsdWU6IFwic3RlcC8vZXhhbXBsZS93b3JrZmxvd3MvN19mdWxsLnRzLy9zZW5kV2VsY29tZUVtYWlsXCIsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2Vcbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHNlbmRPbmJvYXJkaW5nRW1haWwsIFN5bWJvbC5mb3IoXCJXT1JLRkxPV19TVEVQX0ZVTkNUSU9OX05BTUVcIiksIHtcbiAgICB2YWx1ZTogXCJzdGVwLy9leGFtcGxlL3dvcmtmbG93cy83X2Z1bGwudHMvL3NlbmRPbmJvYXJkaW5nRW1haWxcIixcbiAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiBmYWxzZVxufSk7XG4iLCAiZ2xvYmFsVGhpcy5fX3ByaXZhdGVfd29ya2Zsb3dzID0gbmV3IE1hcCgpO1xuaW1wb3J0ICogYXMgd29ya2Zsb3dGaWxlMCBmcm9tICcuLi9leGFtcGxlL3dvcmtmbG93cy85OV9lMmUudHMnO1xuICAgICAgICAgICAgT2JqZWN0LnZhbHVlcyh3b3JrZmxvd0ZpbGUwKS5tYXAoaXRlbSA9PiBpdGVtPy53b3JrZmxvd0lkICYmIGdsb2JhbFRoaXMuX19wcml2YXRlX3dvcmtmbG93cy5zZXQoaXRlbS53b3JrZmxvd0lkLCBpdGVtKSlcbmltcG9ydCAqIGFzIHdvcmtmbG93RmlsZTEgZnJvbSAnLi4vZXhhbXBsZS93b3JrZmxvd3MvMl9jb250cm9sX2Zsb3cudHMnO1xuICAgICAgICAgICAgT2JqZWN0LnZhbHVlcyh3b3JrZmxvd0ZpbGUxKS5tYXAoaXRlbSA9PiBpdGVtPy53b3JrZmxvd0lkICYmIGdsb2JhbFRoaXMuX19wcml2YXRlX3dvcmtmbG93cy5zZXQoaXRlbS53b3JrZmxvd0lkLCBpdGVtKSlcbmltcG9ydCAqIGFzIHdvcmtmbG93RmlsZTIgZnJvbSAnLi4vbml0cm8tdjMvd29ya2Zsb3dzLzBfZGVtby50cyc7XG4gICAgICAgICAgICBPYmplY3QudmFsdWVzKHdvcmtmbG93RmlsZTIpLm1hcChpdGVtID0+IGl0ZW0/LndvcmtmbG93SWQgJiYgZ2xvYmFsVGhpcy5fX3ByaXZhdGVfd29ya2Zsb3dzLnNldChpdGVtLndvcmtmbG93SWQsIGl0ZW0pKVxuaW1wb3J0ICogYXMgd29ya2Zsb3dGaWxlMyBmcm9tICcuLi9leGFtcGxlL3dvcmtmbG93cy85OF9kdXBsaWNhdGVfY2FzZS50cyc7XG4gICAgICAgICAgICBPYmplY3QudmFsdWVzKHdvcmtmbG93RmlsZTMpLm1hcChpdGVtID0+IGl0ZW0/LndvcmtmbG93SWQgJiYgZ2xvYmFsVGhpcy5fX3ByaXZhdGVfd29ya2Zsb3dzLnNldChpdGVtLndvcmtmbG93SWQsIGl0ZW0pKVxuaW1wb3J0ICogYXMgd29ya2Zsb3dGaWxlNCBmcm9tICcuLi9leGFtcGxlL3dvcmtmbG93cy82X2JhdGNoaW5nLnRzJztcbiAgICAgICAgICAgIE9iamVjdC52YWx1ZXMod29ya2Zsb3dGaWxlNCkubWFwKGl0ZW0gPT4gaXRlbT8ud29ya2Zsb3dJZCAmJiBnbG9iYWxUaGlzLl9fcHJpdmF0ZV93b3JrZmxvd3Muc2V0KGl0ZW0ud29ya2Zsb3dJZCwgaXRlbSkpXG5pbXBvcnQgKiBhcyB3b3JrZmxvd0ZpbGU1IGZyb20gJy4uL2V4YW1wbGUvd29ya2Zsb3dzLzFfc2ltcGxlLnRzJztcbiAgICAgICAgICAgIE9iamVjdC52YWx1ZXMod29ya2Zsb3dGaWxlNSkubWFwKGl0ZW0gPT4gaXRlbT8ud29ya2Zsb3dJZCAmJiBnbG9iYWxUaGlzLl9fcHJpdmF0ZV93b3JrZmxvd3Muc2V0KGl0ZW0ud29ya2Zsb3dJZCwgaXRlbSkpXG5pbXBvcnQgKiBhcyB3b3JrZmxvd0ZpbGU2IGZyb20gJy4uL2V4YW1wbGUvd29ya2Zsb3dzLzVfaG9va3MudHMnO1xuICAgICAgICAgICAgT2JqZWN0LnZhbHVlcyh3b3JrZmxvd0ZpbGU2KS5tYXAoaXRlbSA9PiBpdGVtPy53b3JrZmxvd0lkICYmIGdsb2JhbFRoaXMuX19wcml2YXRlX3dvcmtmbG93cy5zZXQoaXRlbS53b3JrZmxvd0lkLCBpdGVtKSlcbmltcG9ydCAqIGFzIHdvcmtmbG93RmlsZTcgZnJvbSAnLi4vZXhhbXBsZS93b3JrZmxvd3MvNF9haS50cyc7XG4gICAgICAgICAgICBPYmplY3QudmFsdWVzKHdvcmtmbG93RmlsZTcpLm1hcChpdGVtID0+IGl0ZW0/LndvcmtmbG93SWQgJiYgZ2xvYmFsVGhpcy5fX3ByaXZhdGVfd29ya2Zsb3dzLnNldChpdGVtLndvcmtmbG93SWQsIGl0ZW0pKVxuaW1wb3J0ICogYXMgd29ya2Zsb3dGaWxlOCBmcm9tICcuLi9leGFtcGxlL3dvcmtmbG93cy8zX3N0cmVhbXMudHMnO1xuICAgICAgICAgICAgT2JqZWN0LnZhbHVlcyh3b3JrZmxvd0ZpbGU4KS5tYXAoaXRlbSA9PiBpdGVtPy53b3JrZmxvd0lkICYmIGdsb2JhbFRoaXMuX19wcml2YXRlX3dvcmtmbG93cy5zZXQoaXRlbS53b3JrZmxvd0lkLCBpdGVtKSlcbmltcG9ydCAqIGFzIHdvcmtmbG93RmlsZTkgZnJvbSAnLi4vZXhhbXBsZS93b3JrZmxvd3MvN19mdWxsLnRzJztcbiAgICAgICAgICAgIE9iamVjdC52YWx1ZXMod29ya2Zsb3dGaWxlOSkubWFwKGl0ZW0gPT4gaXRlbT8ud29ya2Zsb3dJZCAmJiBnbG9iYWxUaGlzLl9fcHJpdmF0ZV93b3JrZmxvd3Muc2V0KGl0ZW0ud29ya2Zsb3dJZCwgaXRlbSkpIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBLHdFQUFBQSxTQUFBO0FBRUksUUFBSSxJQUFJO0FBQ1osUUFB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QTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxrQkFBQUM7QUFBQSxFQUFBO0FBQUE7QUFBQTtBQUFBLGdCQUFBQztBQUFBLEVBQUEsaUJBQUFDO0FBQUEsRUFBQSxjQUFBQztBQUFBLEVBQUEsZUFBQUM7QUFBQSxFQUFBLGFBQUFDO0FBQUEsRUFBQTtBQUFBLGdCQUFBQztBQUFBLEVBQUEsY0FBQUM7QUFBQSxFQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsY0FBQUM7QUFBQSxFQUFBLFlBQUFDO0FBQUEsRUFBQSxhQUFBQztBQUFBLEVBQUE7QUFBQSxjQUFBQztBQUFBLEVBQUEsY0FBQUM7QUFBQSxFQUFBLG1CQUFBQztBQUFBLEVBQUE7QUFBQSxjQUFBQztBQUFBLEVBQUEsYUFBQUM7QUFBQSxFQUFBLGFBQUFDO0FBQUEsRUFBQSxjQUFBQztBQUFBLEVBQUEsbUJBQUFDO0FBQUEsRUFBQTtBQUFBLGNBQUFDO0FBQUEsRUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLGNBQUFDO0FBQUEsRUFBQTtBQUFBLGFBQUFDO0FBQUEsRUFBQSxnQkFBQUM7QUFBQSxFQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsY0FBQUM7QUFBQSxFQUFBLFlBQUFDO0FBQUEsRUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLGVBQUFDO0FBQUEsRUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLGdCQUFBQztBQUFBLEVBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxjQUFBQztBQUFBLEVBQUE7QUFBQSxpQkFBQUM7QUFBQSxFQUFBLGNBQUFDO0FBQUEsRUFBQTtBQUFBO0FBQUE7QUFBQSxlQUFBQztBQUFBLEVBQUEsa0JBQUFDO0FBQUEsRUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsb0JBQUFDO0FBQUEsRUFBQSx1QkFBQUM7QUFBQSxFQUFBLGtCQUFBQztBQUFBLEVBQUEsdUJBQUFDO0FBQUEsRUFBQSxpQkFBQUM7QUFBQSxFQUFBLHNCQUFBQztBQUFBLEVBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLGdCQUFBQztBQUFBLEVBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxnQkFBQUM7QUFBQSxFQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsY0FBQUM7QUFBQSxFQUFBLGlCQUFBQztBQUFBLEVBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLGNBQUFDO0FBQUEsRUFBQTtBQUFBO0FBQUE7QUFBQSxjQUFBQztBQUFBLEVBQUEsV0FBQUM7QUFBQTs7O0FDQUEsSUFBQUMsZ0JBQUE7QUFBQSxTQUFBQSxlQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLGdCQUFBQztBQUFBLEVBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLGVBQUFDO0FBQUEsRUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtB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Q3JEOUMsU0FBUyxRQUFRRyxRQUFPLFFBQVE7QUFDbkMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBTGdCO0FBTVQsU0FBUyxlQUFlQSxRQUFPLFFBQVE7QUFDMUMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBTmdCO0FBT1QsU0FBUyxPQUFPQSxRQUFPLFFBQVE7QUFDbEMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBUyxNQUFNQSxRQUFPLFFBQVE7QUFDakMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBUyxNQUFNQSxRQUFPLFFBQVE7QUFDakMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBUyxRQUFRQSxRQUFPLFFBQVE7QUFDbkMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxTQUFTO0FBQUEsSUFDVCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBVGdCO0FBVVQsU0FBUyxRQUFRQSxRQUFPLFFBQVE7QUFDbkMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxTQUFTO0FBQUEsSUFDVCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBVGdCO0FBVVQsU0FBUyxRQUFRQSxRQUFPLFFBQVE7QUFDbkMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxTQUFTO0FBQUEsSUFDVCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBVGdCO0FBVVQsU0FBUyxLQUFLQSxRQUFPLFFBQVE7QUFDaEMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBU0MsUUFBT0QsUUFBTyxRQUFRO0FBQ2xDLFNBQU8sSUFBSUEsT0FBTTtBQUFBLElBQ2IsTUFBTTtBQUFBLElBQ04sUUFBUTtBQUFBLElBQ1IsT0FBTztBQUFBLElBQ1AsT0FBTztBQUFBLElBQ1AsR0FBUSxnQkFBZ0IsTUFBTTtBQUFBLEVBQ2xDLENBQUM7QUFDTDtBQVJnQixPQUFBQyxTQUFBO0FBU1QsU0FBUyxRQUFRRCxRQUFPLFFBQVE7QUFDbkMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBUyxNQUFNQSxRQUFPLFFBQVE7QUFDakMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBUyxPQUFPQSxRQUFPLFFBQVE7QUFDbEMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBUyxNQUFNQSxRQUFPLFFBQVE7QUFDakMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBUyxLQUFLQSxRQUFPLFFBQVE7QUFDaEMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBUyxPQUFPQSxRQUFPLFFBQVE7QUFDbEMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBUyxNQUFNQSxRQUFPLFFBQVE7QUFDakMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBUyxNQUFNQSxRQUFPLFFBQVE7QUFDakMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBUyxRQUFRQSxRQUFPLFFBQVE7QUFDbkMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBUyxRQUFRQSxRQUFPLFFBQVE7QUFDbkMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBUyxRQUFRQSxRQUFPLFFBQVE7QUFDbkMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBUyxXQUFXQSxRQUFPLFFBQVE7QUFDdEMsU0FBTyxJQUFJQSxPQUFNO0FBQUEsSUFDYixNQUFNO0FBQUEsSUFDTixRQUFRO0FBQUEsSUFDUixPQUFPO0FBQUEsSUFDUCxPQUFPO0FBQUEsSUFDUCxHQUFRLGdCQUFnQixNQUFNO0FBQUEsRUFDbEMsQ0FBQztBQUNMO0FBUmdCO0FBU1QsU0FBUyxNQUFNQSxRQUFPLFFBQVE7QUFDakMsU0FBTyxJQUFJQSxPQUFNO0FBQUEs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QU0sQ0FBQztBQUM1RCxPQUFLLE9BQU8sQ0FBQyxXQUFTLEtBQUssTUFBVyxNQUFNLFNBQVMsTUFBTSxDQUFDO0FBQzVELE9BQUssUUFBUSxDQUFDLFdBQVMsS0FBSyxNQUFXLE9BQU8sVUFBVSxNQUFNLENBQUM7QUFDL0QsT0FBSyxPQUFPLENBQUMsV0FBUyxLQUFLLE1BQVcsTUFBTSxTQUFTLE1BQU0sQ0FBQztBQUM1RCxPQUFLLFNBQVMsQ0FBQyxXQUFTLEtBQUssTUFBVyxRQUFRLFdBQVcsTUFBTSxDQUFDO0FBQ2xFLE9BQUssWUFBWSxDQUFDLFdBQVMsS0FBSyxNQUFXLFdBQVcsY0FBYyxNQUFNLENBQUM7QUFDM0UsT0FBSyxNQUFNLENBQUMsV0FBUyxLQUFLLE1BQVcsS0FBSyxRQUFRLE1BQU0sQ0FBQztBQUN6RCxPQUFLLFFBQVEsQ0FBQyxXQUFTLEtBQUssTUFBVyxPQUFPLFVBQVUsTUFBTSxDQUFDO0FBQy9ELE9BQUssT0FBTyxDQUFDLFdBQVMsS0FBSyxNQUFXLE1BQU0sU0FBUyxNQUFNLENBQUM7QUFDNUQsT0FBSyxPQUFPLENBQUMsV0FBUyxLQUFLLE1BQVcsTUFBTSxTQUFTLE1BQU0sQ0FBQztBQUM1RCxPQUFLLFNBQVMsQ0FBQyxXQUFTLEtBQUssTUFBVyxRQUFRLFdBQVcsTUFBTSxDQUFDO0FBQ2xFLE9BQUssU0FBUyxDQUFDLFdBQVMsS0FBSyxNQUFXLFFBQVEsV0FBVyxNQUFNLENBQUM7QUFDbEUsT0FBSyxPQUFPLENBQUMsV0FBUyxLQUFLLE1BQVcsTUFBTSxTQUFTLE1BQU0sQ0FBQztBQUU1RCxPQUFLLFdBQVcsQ0FBQyxXQUFTLEtBQUssTUFBVUMsVUFBUyxNQUFNLENBQUM7QUFDekQsT0FBSyxPQUFPLENBQUMsV0FBUyxLQUFLLE1BQVVDLE1BQUssTUFBTSxDQUFDO0FBQ2pELE9BQUssT0FBTyxDQUFDLFdBQVMsS0FBSyxNQUFVQyxNQUFLLE1BQU0sQ0FBQztBQUNqRCxPQUFLLFdBQVcsQ0FBQyxXQUFTLEtBQUssTUFBVUMsVUFBUyxNQUFNLENBQUM7QUFDN0QsQ0FBQztB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QUM1RDtBQUFBLEVBQ0EsSUFBSSxRQUFRO0FBQ1IsV0FBTyxDQUFDLENBQUMsS0FBSyxLQUFLLE9BQU8sS0FBSyxDQUFDLE9BQUssR0FBRyxTQUFTLEtBQUs7QUFBQSxFQUMxRDtBQUFBLEVBQ0EsSUFBSSxVQUFVO0FBQ1YsV0FBTyxDQUFDLENBQUMsS0FBSyxLQUFLLE9BQU8sS0FBSyxDQUFDLE9BQUssR0FBRyxTQUFTLE9BQU87QUFBQSxFQUM1RDtBQUFBLEVBQ0EsSUFBSSxTQUFTO0FBQ1QsV0FBTyxDQUFDLENBQUMsS0FBSyxLQUFLLE9BQU8sS0FBSyxDQUFDLE9BQUssR0FBRyxTQUFTLE1BQU07QUFBQSxFQUMzRDtBQUFBLEVBQ0EsSUFBSSxXQUFXO0FBQ1gsV0FBTyxDQUFDLENBQUMsS0FBSyxLQUFLLE9BQU8sS0FBSyxDQUFDLE9BQUssR0FBRyxTQUFTLFFBQVE7QUFBQSxFQUM3RDtBQUFBLEVBQ0EsSUFBSSxTQUFTO0FBQ1QsV0FBTyxDQUFDLENBQUMsS0FBSyxLQUFLLE9BQU8sS0FBSyxDQUFDLE9BQUssR0FBRyxTQUFTLE1BQU07QUFBQSxFQUMzRDtBQUFBLEVBQ0EsSUFBSSxVQUFVO0FBQ1YsV0FBTyxDQUFDLENBQUMsS0FBSyxLQUFLLE9BQU8sS0FBSyxDQUFDLE9BQUssR0FBRyxTQUFTLE9BQU87QUFBQSxFQUM1RDtBQUFBLEVBQ0EsSUFBSSxTQUFTO0FBQ1QsV0FBTyxDQUFDLENBQUMsS0FBSyxLQUFLLE9BQU8sS0FBSyxDQUFDLE9BQUssR0FBRyxTQUFTLE1BQU07QUFBQSxFQUMzRDtBQUFBLEVBQ0EsSUFBSSxPQUFPO0FBQ1AsV0FBTyxDQUFDLENBQUMsS0FBSyxLQUFLLE9BQU8sS0FBSyxDQUFDLE9BQUssR0FBRyxTQUFTLElBQUk7QUFBQSxFQUN6RDtBQUFBLEVBQ0EsSUFBSSxTQUFTO0FBQ1QsV0FBTyxDQUFDLENBQUMsS0FBSyxLQUFLLE9BQU8sS0FBSyxDQUFDLE9BQUssR0FBRyxTQUFTLE1BQU07QUFBQSxFQUMzRDtBQUFBLEVBQ0EsSUFBSSxXQUFXO0FBQ1gsV0FBTyxD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SSxLQUFLLFlBQVksSUFBSSxDQUFDO0FBRXRILE9BQU8sT0FBTyxjQUFhLEVBQUUsSUFBSSxVQUFRLE1BQU0sY0FBYyxXQUFXLG9CQUFvQixJQUFJLEtBQUssWUFBWSxJQUFJLENBQUM7QUFFdEgsT0FBTyxPQUFPLGFBQWEsRUFBRSxJQUFJLFVBQVEsTUFBTSxjQUFjLFdBQVcsb0JBQW9CLElBQUksS0FBSyxZQUFZLElBQUksQ0FBQztBQUV0SCxPQUFPLE9BQU8sVUFBYSxFQUFFLElBQUksVUFBUSxNQUFNLGNBQWMsV0FBVyxvQkFBb0IsSUFBSSxLQUFLLFlBQVksSUFBSSxDQUFDO0FBRXRILE9BQU8sT0FBTyxlQUFhLEVBQUUsSUFBSSxVQUFRLE1BQU0sY0FBYyxXQUFXLG9CQUFvQixJQUFJLEtBQUssWUFBWSxJQUFJLENBQUM7QUFFdEgsT0FBTyxPQUFPLFlBQWEsRUFBRSxJQUFJLFVBQVEsTUFBTSxjQUFjLFdBQVcsb0JBQW9CLElBQUksS0FBSyxZQUFZLElBQUksQ0FBQzsiLAogICJuYW1lcyI6IFsibW9kdWxlIiwgInBhcnNlIiwgIm1zIiwgIm5hbWUiLCAibW9kdWxlIiwgImFycmF5IiwgIm9iamVjdCIsICJpc09iamVjdCIsICJjaHVuayIsICJtb2R1bGUiLCAiX19kZWZQcm9wIiwgIl9fZ2V0T3duUHJvcERlc2MiLCAiX19nZXRPd25Qcm9wTmFtZXMiLCAiX19oYXNPd25Qcm9wIiwgIl9fZXhwb3J0IiwgIm5hbWUiLCAiX19jb3B5UHJvcHMiLCAiZ2V0Q29udGV4dCIsICJtb2R1bGUiLCAiX19kZWZQcm9wIiwgIl9fZ2V0T3duUHJvcERlc2MiLCAiX19nZXRPd25Qcm9wTmFtZXMiLCAiX19oYXNPd25Qcm9wIiwgIl9fZXhwb3J0IiwgIm5hbWUiLCAiX19jb3B5UHJvcHMiLCAiZ2V0VmVyY2VsT2lkY1Rva2VuIiwgIl9hIiwgIl9iIiwgIkRpYWdMb2dMZXZlbCIsICJfYSIsICJfYiIsICJWYWx1ZVR5cGUiLCAiVHJhY2VGbGFncyIsICJfYSIsICJuYW1lIiwgIm5hbWUiLCAidmVyc2lvbiIsICJuYW1lIiwgInZlcnNpb24iLCAiX2EiLCAiU2FtcGxpbmdEZWNpc2lvbiIsICJTcGFuS2luZCIsICJTcGFuU3RhdHVzQ29kZSIsICJuYW1lIiwgInZlcnNpb24iLCAic3VjY2VzcyIsICJuYW1lIiwgInZlcnNpb24iLCAibmFtZSIsICJmZXRjaCIsICJkZWxheSIsICJ0ZXh0IiwgImZldGNoIiwgImVycm9yIiwgIm1zIiwgImFkZCIsICJlcnJvciIsICJhZGQiLCAiYWRkVGVuV29ya2Zsb3ciLCAiYWRkVGVuV29ya2Zsb3ciLCAiYWRkIiwgImNodW5rIiwgImFkZCIsICJ0ZXh0IiwgIl9BSVNES0Vycm9yIiwgIm5hbWUxNCIsICJuYW1lIiwgImVycm9yIiwgIm1hcmtlcjE1IiwgIm1hcmtlciIsICJzeW1ib2wiLCAiX2EiLCAidXJsIiwgInN5bWJvbCIsICJuYW1lIiwgIl9hIiwgInRleHQiLCAiZXJyb3IiLCAibWFya2VyIiwgIm5hbWUiLCAic3ltYm9sIiwgIl9hIiwgInN5bWJvbCIsICJzeW1ib2wiLCAibmFtZSIsICJtYXJrZXIiLCAiZXJyb3IiLCAiX2EiLCAibmFtZSIsICJfVHlwZVZhbGlkYXRpb25FcnJvciIsICJfYSIsICJjaHVuayIsICJlcnJvciIsICJjaHVuayIsICJfZGVmYXVsdCIsICJiYXNlNjQiLCAiYmFzZTY0dXJsIiwgImJpZ2ludCIsICJib29sZWFuIiwgIl9jYXRjaCIsICJjaWRydjQiLCAiY2lkcnY2IiwgImNvcmVfZXhwb3J0cyIsICJjdWlkIiwgImN1aWQyIiwgImRhdGUiLCAiZGVjb2RlIiwgImRlY29kZUFzeW5jIiwgImUxNjQiLCAiZW1haWwiLCAiZW1vamkiLCAiZW5jb2RlIiwgImVuY29kZUFzeW5jIiwgIl9lbnVtIiwgImd1aWQiLCAiaGV4IiwgImhvc3RuYW1lIiwgImlwdjQiLCAiaXB2NiIsICJrc3VpZCIsICJuYW5vaWQiLCAiX251bGwiLCAibnVsbGlzaCIsICJudW1iZXIiLCAicGFyc2UiLCAicGFyc2VBc3luYyIsICJzYWZlRGVjb2RlIiwgInNhZmVEZWNvZGVBc3luYyIsICJzYWZlRW5jb2RlIiwgInNhZmVFbmNvZGVBc3luYyIsICJzYWZlUGFyc2UiLCAic2FmZVBhcnNlQXN5bmMiLCAic3RyaW5nIiwgInN5bWJvbCIsICJ1bGlkIiwgIl91bmRlZmluZWQiLCAidXVpZCIsICJfdm9pZCIsICJ4aWQiLCAiY29yZV9leHBvcnRzIiwgIl9lbW9qaSIsICJfbnVsbCIsICJfdW5kZWZpbmVkIiwgIm5hbWUiLCAiaW5pdGlhbGl6ZXIiLCAiX2EiLCAiYXJyYXkiLCAic2V0IiwgIm9iamVjdCIsICJDbGFzcyIsICJfYSIsICJjb25maWciLCAiYmFzZTY0IiwgImJhc2U2NHVybCIsICJoZXgiLCAiZXJyb3IiLCAiaXNzdWUiLCAiX2EiLCAiX2IiLCAidmVyc2lvbiIsICJ0aW1lIiwgInRpbWVSZWdleCIsICJfYSIsICJpbnN0IiwgIl9iIiwgInJlc3VsdCIsICJfYSIsICJjaGVja3MiLCAiaXNBYm9ydGVkIiwgImNoZWNrUmVzdWx0IiwgImNhbmFyeSIsICJyZXN1bHQiLCAiXyIsICJ1cmwiLCAiaW5zdCIsICJiYXNlNjQiLCAiciIsICJpc09iamVjdCIsICJhbGxvd3NFdmFsIiwgInJlc3VsdHMiLCAibWFwIiwgImxlZnQiLCAicmlnaHQiLCAia2V5UmVzdWx0IiwgInZhbHVlUmVzdWx0IiwgIm91dHB1dCIsICJwYXJzZWRUeXBlIiwgImlzc3VlIiwgImVycm9yIiwgInBhcnNlZFR5cGUiLCAiaXNzdWUiLCAiZXJyb3IiLCAicGFyc2VkVHlwZSIsICJpc3N1ZSIsICJlcnJvciIsICJwYXJzZWRUeXBlIiwgImlzc3VlIiwgImVycm9yIiwgInBhcnNlZFR5cGUiLCAiaXNzdWUiLCAiZXJyb3IiLCAicGFyc2VkVHlwZSIsICJpc3N1ZSIsICJlcnJvciIsICJwYXJzZWRUeXBlIiwgImlzc3VlIiwgImVycm9yIiwgImlzc3VlIiwgInBhcnNlZFR5cGUiLCAiZXJyb3IiLCAiaXNzdWUiLCAiZXJyb3IiLCAicGFyc2VkVHlwZSIsICJpc3N1ZSIsICJlcnJvciIsICJwYXJzZWRUeXBlIiwgImlzc3VlIiwgImVycm9yIiwgInBhcnNlZFR5cGUiLCAiaXNzdWUiLCAiZXJyb3IiLCAicGFyc2VkVHlwZSIsICJpc3N1ZSIsICJlcnJvciIsICJwYXJzZWRUeXBlIiwgImlzc3VlIiwgImVycm9yIiwgInBhcnNlZFR5cGUiLCAiaXNzdWUiLCAiZXJyb3IiLCAicGFyc2VkVHlwZSIsICJpc3N1ZSIsICJlcnJvciIsICJwYXJzZWRUeXBlIiwgImlzc3VlIiwgInBhcnNlZFR5cGUiLCAiZXJyb3IiLCAiaXNzdWUiLCAiZXJyb3IiLCAicGFyc2VkVHlwZSIsICJpc3N1ZSIsICJlcnJvciIsICJwYXJzZWRUeXBlIiwgImlzc3VlIiwgInBhcnNlZFR5cGUiLCAiZXJyb3IiLCAiaXNzdWUiLCAiZXJyb3IiLCAicGFyc2VkVHlwZSIsICJpc3N1ZSIsICJlcnJvciIsICJwYXJzZWRUeXBlIiwgImlzc3VlIiwgInBhcnNlZFR5cGUiLCAidGV4dCIsICJudW1iZXIiLCAiZXJyb3IiLCAiaXNzdWUiLCAiZXJyb3IiLCAicGFyc2VkVHlwZSIsICJpc3N1ZSIsICJlcnJvciIsICJwYXJzZWRUeXBlIiwgImlzc3VlIiwgImVycm9yIiwgInBhcnNlZFR5cGUiLCAiaXNzdWUiLCAiZXJyb3IiLCAicGFyc2VkVHlwZSIsICJpc3N1ZSIsICJlcnJvciIsICJwYXJzZWRUeXBlIiwgImlzc3VlIiwgImVycm9yIiwgInBhcnNlZFR5cGUiLCAiaXNzdWUiLCAiZXJyb3IiLCAicGFyc2VkVHlwZSIsICJpc3N1ZSIsICJlcnJvciIsICJwYXJzZWRUeXBlIiwgImlzc3VlIiwgImVycm9yIiwgInBhcnNlZFR5cGUiLCAiaXNzdWUiLCAiZXJyb3IiLCAicGFyc2VkVHlwZSIsICJpc3N1ZSIsICJlcnJvciIsICJwYXJzZWRUeXBlIiwgImlzc3VlIiwgImVycm9yIiwgInBhcnNlZFR5cGUiLCAiaXNzdWUiLCAiZXJyb3IiLCAicGFyc2VkVHlwZSIsICJpc3N1ZSIsICJwYXJzZWRUeXBlIiwgImVycm9yIiwgImlzc3VlIiwgImVycm9yIiwgInBhcnNlZFR5cGUiLCAiaXNzdWUiLCAiZXJyb3IiLCAicGFyc2VkVHlwZSIsICJpc3N1ZSIsICJlcnJvciIsICJwYXJzZWRUeXBlIiwgImlzc3VlIiwgImVycm9yIiwgInBhcnNlZFR5cGUiLCAiaXNzdWUiLCAiZXJyb3IiLCAicGFyc2VkVHlwZSIsICJpc3N1ZSIsICJlcnJvciIsICJwYXJzZWRUeXBlIiwgImlzc3VlIiwgIkNsYXNzIiwgIl9lbW9qaSIsICJfdW5kZWZpbmVkIiwgIl9udWxsIiwgIkNsYXNzIiwgImlzc3VlIiwgImNvZGVjIiwgIl9hIiwgImpzb24iLCAiZmlsZSIsICJpZCIsICJzY2hlbWEiLCAiem9kU2NoZW1hIiwgInBhcmFtcyIsICJnZW4iLCAiZGF0ZSIsICJkYXRldGltZSIsICJkdXJhdGlvbiIsICJ0aW1lIiwgImRhdGV0aW1lIiwgImRhdGUiLCAidGltZSIsICJkdXJhdGlvbiIsICJpbml0aWFsaXplciIsICJpc3N1ZSIsICJpc3N1ZXMiLCAicGFyc2UiLCAicGFyc2VBc3luYyIsICJzYWZlUGFyc2UiLCAic2FmZVBhcnNlQXN5bmMiLCAiZW5jb2RlIiwgImRlY29kZSIsICJlbmNvZGVBc3luYyIsICJkZWNvZGVBc3luYyIsICJzYWZlRW5jb2RlIiwgInNhZmVEZWNvZGUiLCAic2FmZUVuY29kZUFzeW5jIiwgInNhZmVEZWNvZGVBc3luYyIsICJkZWYiLCAicGFyc2UiLCAic2FmZVBhcnNlIiwgInBhcnNlQXN5bmMiLCAic2FmZVBhcnNlQXN5bmMiLCAiZW5jb2RlIiwgImRlY29kZSIsICJlbmNvZGVBc3luYyIsICJkZWNvZGVBc3luYyIsICJzYWZlRW5jb2RlIiwgInNhZmVEZWNvZGUiLCAic2FmZUVuY29kZUFzeW5jIiwgInNhZmVEZWNvZGVBc3luYyIsICJjaGVjayIsICJfZGVmYXVsdCIsICJfY2F0Y2giLCAiX2Vtb2ppIiwgImRhdGV0aW1lIiwgImRhdGUiLCAidGltZSIsICJkdXJhdGlvbiIsICJzdHJpbmciLCAiZW1haWwiLCAiZ3VpZCIsICJ1dWlkIiwgImVtb2ppIiwgIm5hbm9pZCIsICJjdWlkIiwgImN1aWQyIiwgInVsaWQiLCAieGlkIiwgImtzdWlkIiwgImlwdjQiLCAiaXB2NiIsICJjaWRydjQiLCAiY2lkcnY2IiwgImJhc2U2NCIsICJiYXNlNjR1cmwiLCAiZTE2NCIsICJob3N0bmFtZSIsICJoZXgiLCAibnVtYmVyIiwgImJvb2xlYW4iLCAiYmlnaW50IiwgInN5bWJvbCIsICJfdW5kZWZpbmVkIiwgIl9udWxsIiwgIl92b2lkIiwgImRhdGUiLCAiX2VudW0iLCAiaXNzdWUiLCAib3V0cHV0IiwgIm51bGxpc2giLCAiX2RlZmF1bHQiLCAiX2NhdGNoIiwgImpzb25TY2hlbWEiLCAic3RyaW5nIiwgIm51bWJlciIsICJib29sZWFuIiwgIl9udWxsIiwgIm1hcCIsICJab2RGaXJzdFBhcnR5VHlwZUtpbmQiLCAiYmlnaW50IiwgImJvb2xlYW4iLCAiZGF0ZSIsICJudW1iZXIiLCAic3RyaW5nIiwgInN0cmluZyIsICJudW1iZXIiLCAiYm9vbGVhbiIsICJiaWdpbnQiLCAiZGF0ZSIsICJ1dGlsIiwgImFzc2VydElzIiwgImFzc2VydE5ldmVyIiwgIm9iamVjdCIsICJqb2luVmFsdWVzIiwgImFycmF5IiwgIm9iamVjdFV0aWwiLCAiZ2V0UGFyc2VkVHlwZSIsICJab2RJc3N1ZUNvZGUiLCAiWm9kRXJyb3IiLCAiaXNzdWUiLCAiZXJyb3IiLCAiaXNzdWUiLCAiWm9kSXNzdWVDb2RlIiwgImVuX2RlZmF1bHQiLCAiZW5fZGVmYXVsdCIsICJnZXRFcnJvck1hcCIsICJtYXAiLCAiZ2V0RXJyb3JNYXAiLCAiaXNzdWUiLCAiZW5fZGVmYXVsdCIsICJlcnJvclV0aWwiLCAiZXJyb3IiLCAiWm9kRXJyb3IiLCAiZXJyb3JNYXAiLCAiWm9kVHlwZSIsICJnZXRQYXJzZWRUeXBlIiwgImNoZWNrIiwgIlpvZElzc3VlQ29kZSIsICJab2RGaXJzdFBhcnR5VHlwZUtpbmQiLCAiWm9kT3B0aW9uYWwiLCAiWm9kTnVsbGFibGUiLCAiWm9kQXJyYXkiLCAiWm9kUHJvbWlzZSIsICJab2RVbmlvbiIsICJab2RJbnRlcnNlY3Rpb24iLCAidHJhbnNmb3JtIiwgIlpvZERlZmF1bHQiLCAiWm9kQ2F0Y2giLCAiWm9kUmVhZG9ubHkiLCAidmVyc2lvbiIsICJpc1ZhbGlkSldUIiwgImp3dCIsICJiYXNlNjQiLCAiWm9kU3RyaW5nIiwgIl9ab2RTdHJpbmciLCAicGFyc2VkVHlwZSIsICJjdHgiLCAiZmxvYXRTYWZlUmVtYWluZGVyIiwgIlpvZE51bWJlciIsICJab2RCaWdJbnQiLCAiWm9kQm9vbGVhbiIsICJab2REYXRlIiwgIlpvZFN5bWJvbCIsICJab2RVbmRlZmluZWQiLCAiWm9kTnVsbCIsICJab2RBbnkiLCAiWm9kVW5rbm93biIsICJab2ROZXZlciIsICJab2RWb2lkIiwgInJlc3VsdCIsICJab2RPYmplY3QiLCAiWm9kVHVwbGUiLCAiaXNzdWUiLCAiaXNzdWVzIiwgIlpvZExhenkiLCAiWm9kTGl0ZXJhbCIsICJab2RFbnVtIiwgIlpvZERpc2NyaW1pbmF0ZWRVbmlvbiIsICJtZXJnZVZhbHVlcyIsICJab2RSZWNvcmQiLCAiWm9kTWFwIiwgIlpvZFNldCIsICJlbGVtZW50cyIsICJab2RGdW5jdGlvbiIsICJnZXRFcnJvck1hcCIsICJlbl9kZWZhdWx0IiwgInByb2Nlc3NlZCIsICJwcmVwcm9jZXNzIiwgIlpvZE9wdGlvbmFsIiwgIlpvZFR5cGUiLCAicGFyc2VkVHlwZSIsICJab2RGaXJzdFBhcnR5VHlwZUtpbmQiLCAiWm9kTnVsbGFibGUiLCAiWm9kRGVmYXVsdCIsICJab2RDYXRjaCIsICJyZXN1bHQiLCAiWm9kRXJyb3IiLCAiWm9kTmFOIiwgIlpvZElzc3VlQ29kZSIsICJab2RSZWFkb25seSIsICJab2RPYmplY3QiLCAiWm9kRmlyc3RQYXJ0eVR5cGVLaW5kIiwgIlpvZFN0cmluZyIsICJab2ROdW1iZXIiLCAiWm9kTmFOIiwgIlpvZEJpZ0ludCIsICJab2RCb29sZWFuIiwgIlpvZERhdGUiLCAiWm9kU3ltYm9sIiwgIlpvZFVuZGVmaW5lZCIsICJab2ROdWxsIiwgIlpvZEFueSIsICJab2RVbmtub3duIiwgIlpvZE5ldmVyIiwgIlpvZFZvaWQiLCAiWm9kQXJyYXkiLCAiWm9kT2JqZWN0IiwgIlpvZFVuaW9uIiwgIlpvZERpc2NyaW1pbmF0ZWRVbmlvbiIsICJab2RJbnRlcnNlY3Rpb24iLCAiWm9kVHVwbGUiLCAiWm9kUmVjb3JkIiwgIlpvZE1hcCIsICJab2RTZXQiLCAiWm9kRnVuY3Rpb24iLCAiWm9kTGF6eSIsICJab2RMaXRlcmFsIiwgIlpvZEVudW0iLCAiWm9kUHJvbWlzZSIsICJab2RPcHRpb25hbCIsICJab2ROdWxsYWJsZSIsICJyZXNvbHZlIiwgImdldEVycm9yTWVzc2FnZSIsICJlcnJvciIsICJ1cmwiLCAiX2EiLCAiX2IiLCAicmVjb3JkIiwgImZldGNoIiwgInVybCIsICJtZWRpYVR5cGUiLCAiX3BhcnNlIiwgInRleHQiLCAiVHlwZVZhbGlkYXRpb25FcnJvciIsICJ2YWxpZGF0b3IiLCAiZXJyb3IiLCAidXJsIiwgImZldGNoIiwgInVybCIsICJmZXRjaCIsICJJbnZhbGlkQXJndW1lbnRFcnJvciIsICJlcnJvciIsICJBUElDYWxsRXJyb3IiLCAiZ2V0T3JpZ2luYWxGZXRjaCIsICJ1cmwiLCAiQVBJQ2FsbEVycm9yIiwgInRvb2wiLCAidXJsIiwgIl9hIiwgIl9iIiwgIlpvZEZpcnN0UGFydHlUeXBlS2luZCIsICJBUElDYWxsRXJyb3IiLCAiY2hlY2siLCAicGFyc2VkVHlwZSIsICJlbW9qaVJlZ2V4IiwgImxpdGVyYWwiLCAib2JqZWN0IiwgInJlcXVpcmVkIiwgIm5hbWUiLCAianNvblNjaGVtYSIsICJuYW1lMiIsICJfYTIiLCAic2NoZW1hIiwgInNhZmVQYXJzZUFzeW5jIiwgInpvZFNjaGVtYSIsICJidG9hIiwgImF0b2IiLCAiYXJyYXkiLCAidXJsIiwgInpvZFNjaGVtYSIsICJpbXBvcnRfb2lkYyIsICJtYXJrZXIiLCAieiIsICJfYSIsICJzeW1ib2wiLCAiZXJyb3IiLCAibmFtZSIsICJtYXJrZXIyIiwgInN5bWJvbDIiLCAiX2EyIiwgIm5hbWUyIiwgIm1hcmtlcjMiLCAic3ltYm9sMyIsICJfYTMiLCAibmFtZTMiLCAiX2IiLCAiX2E0IiwgInN5bWJvbDQiLCAic3ltYm9sNSIsICJtYXJrZXI1IiwgIl9hNSIsICJuYW1lNCIsICJuYW1lNSIsICJtYXJrZXI2IiwgInN5bWJvbDYiLCAiX2E2IiwgIm5hbWU2IiwgIm1hcmtlcjciLCAic3ltYm9sNyIsICJfYTciLCAibGF6eVZhbGlkYXRvciIsICJ6b2RTY2hlbWEiLCAiX2E4IiwgImNvbmZpZyIsICJyZXNvbHZlIiwgImNodW5rIiwgImNyZWF0ZUpzb25SZXNwb25zZUhhbmRsZXIiLCAiY3JlYXRlSnNvbkVycm9yUmVzcG9uc2VIYW5kbGVyIiwgImNvbWJpbmVIZWFkZXJzIiwgInBvc3RKc29uVG9BcGkiLCAiVkVSU0lPTiIsICJub3ciLCAiaW1wb3J0X2FwaSIsICJuYW1lIiwgIm1hcmtlciIsICJ0b29sIiwgInN5bWJvbCIsICJ6b2RTY2hlbWEiLCAiX2EiLCAiZXJyb3IiLCAibmFtZTIiLCAibWFya2VyMiIsICJzeW1ib2wyIiwgIl9hMiIsICJuYW1lMyIsICJtYXJrZXIzIiwgIl9hMyIsICJzeW1ib2wzIiwgIm5hbWU0IiwgIm1hcmtlcjQiLCAic3ltYm9sNCIsICJfYTQiLCAibWFya2VyIiwgInN5bWJvbCIsICJuYW1lIiwgIl9hIiwgImVycm9yIiwgIm5hbWU1IiwgIm1hcmtlcjUiLCAic3ltYm9sNSIsICJfYTUiLCAiX2E1IiwgInN5bWJvbDUiLCAibmFtZTYiLCAiX2EiLCAibWFya2VyNiIsICJzeW1ib2w2IiwgIl9hNiIsICJfYTYiLCAic3ltYm9sNiIsICJuYW1lNyIsICJtYXJrZXI3IiwgInN5bWJvbDciLCAiX2E3IiwgIkFJU0RLRXJyb3IiLCAic3ltYm9sIiwgIm5hbWUiLCAibWFya2VyIiwgImVycm9yIiwgIl9hIiwgIm5hbWU4IiwgIm1hcmtlcjgiLCAic3ltYm9sOCIsICJfYTgiLCAiX2E4IiwgInN5bWJvbDgiLCAibmFtZTkiLCAibWFya2VyOSIsICJzeW1ib2w5IiwgIl9hOSIsICJzeW1ib2wiLCAibmFtZSIsICJtYXJrZXIiLCAiX2EiLCAiZXJyb3IiLCAibmFtZTEwIiwgIm1hcmtlcjEwIiwgInN5bWJvbDEwIiwgIl9hMTAiLCAiQUlTREtFcnJvciIsICJuYW1lMTEiLCAibWFya2VyMTEiLCAic3ltYm9sMTEiLCAiX2ExMSIsICJfYTExIiwgInN5bWJvbDExIiwgIm5hbWUxMiIsICJtYXJrZXIxMiIsICJfYSIsICJzeW1ib2wxMiIsICJfYTEyIiwgIkFJU0RLRXJyb3IiLCAic3ltYm9sIiwgImVycm9yIiwgIm5hbWUxMyIsICJtYXJrZXIxMyIsICJzeW1ib2wxMyIsICJfYTEzIiwgInN5bWJvbDEzIiwgIm5hbWUxNCIsICJtYXJrZXIxNCIsICJBSVNES0Vycm9yIiwgInN5bWJvbDE0IiwgIl9hMTQiLCAiX2EiLCAic3ltYm9sIiwgIm5hbWUiLCAibWFya2VyIiwgInVybCIsICJlcnJvciIsICJuYW1lMTUiLCAibWFya2VyMTUiLCAiX2ExNSIsICJzeW1ib2wxNSIsICJfYSIsICJzeW1ib2wiLCAibWFya2VyIiwgIkFJU0RLRXJyb3IiLCAiVkVSU0lPTiIsICJ1cmwiLCAiX2EiLCAiZXJyb3IiLCAiX2IiLCAiZG93bmxvYWQiLCAiX2EiLCAiZmlsZSIsICJJbnZhbGlkQXJndW1lbnRFcnJvciIsICJvYmplY3QyIiwgIm9iamVjdCIsICJuYW1lIiwgInoiLCAieiIsICJ6IiwgInoiLCAiSW52YWxpZFByb21wdEVycm9yIiwgImVycm9yIiwgIl9hIiwgIm5hbWUiLCAiYXR0cmlidXRlcyIsICJtcyIsICJBUElDYWxsRXJyb3IiLCAiSW52YWxpZEFyZ3VtZW50RXJyb3IiLCAiZXJyb3IiLCAiY29udGVudCIsICJjb252ZXJ0VWludDhBcnJheVRvQmFzZTY0IiwgImFzU2NoZW1hIiwgIl9hIiwgImdldEVycm9yTWVzc2FnZSIsICJ0b29sIiwgIlZFUlNJT04iLCAiX2IiLCAiX2IyIiwgImRvd25sb2FkIiwgIndpdGhVc2VyQWdlbnRTdWZmaXgiLCAiY2FsbFNldHRpbmdzIiwgImVycm9yIiwgInRvb2xDYWxsIiwgImdldEVycm9yTWVzc2FnZSIsICJpc0Fib3J0RXJyb3IiLCAicmVzb2x2ZSIsICJ6IiwgInNhZmVQYXJzZUpTT04iLCAiX19leHBvcnQiLCAib2JqZWN0IiwgIl9hIiwgIm1hcmtlcjE2IiwgInN5bWJvbDE2IiwgIl9hMTYiLCAic3ltYm9sMTYiLCAiX2EiLCAiZmV0Y2giLCAid2l0aFVzZXJBZ2VudFN1ZmZpeCIsICJnZXRSdW50aW1lRW52aXJvbm1lbnRVc2VyQWdlbnQiLCAiX2EiLCAicGFyc2VKc29uRXZlbnRTdHJlYW0iLCAiZ2VuZXJhdGVJZCIsICJ0ZXh0IiwgInN0cmVhbXMiLCAiZW1haWwiXQp9Cg== -`; - - -async function normalizeRequestConverter(request) { - const options = { - method: request.method, - headers: new Headers(request.headers) - }; - if (!['GET', 'HEAD', 'OPTIONS', 'TRACE', 'CONNECT'].includes(request.method)) { - options.body = await request.arrayBuffer(); - } - return new Request(request.url, options); -} - -const POST = async ({request}) => { - const normalRequest = await normalizeRequestConverter(request); - return workflowEntrypoint(workflowCode)(normalRequest); -}; - -const prerender = false; - -const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - POST, - prerender -}, Symbol.toStringTag, { value: 'Module' })); - -const page = () => _page; - -export { page }; diff --git a/workbench/astro/dist/server/pages/.well-known/workflow/v1/step.astro.mjs b/workbench/astro/dist/server/pages/.well-known/workflow/v1/step.astro.mjs deleted file mode 100644 index 415ac7fad..000000000 --- a/workbench/astro/dist/server/pages/.well-known/workflow/v1/step.astro.mjs +++ /dev/null @@ -1,7609 +0,0 @@ -import { g as getWorkflowRunStreamId, a as getSerializeStream, b as getExternalReducers, W as WorkflowServerWritableStream, r as registerStepFunction } from '../../../../chunks/index_ePTMDSOu.mjs'; -import ms from 'ms'; -import { c as contextStorage, s as stepEntrypoint } from '../../../../chunks/runtime_CxdH0OC2.mjs'; -export { renderers } from '../../../../renderers.mjs'; - -/** - * Returns metadata available in the current step function. - * It uses `AsyncLocalStorage` to store the context and - * retrieve it in the step function. - */ -function getStepMetadata() { - const ctx = contextStorage.getStore(); - if (!ctx) { - throw new Error('`getStepMetadata()` can only be called inside a step function'); - } - return ctx.stepMetadata; -} - -/** - * Returns metadata available in the current workflow run inside a step function. - */ -function getWorkflowMetadata() { - const ctx = contextStorage.getStore(); - if (!ctx) { - throw new Error('`getWorkflowMetadata()` can only be called inside a workflow or step function'); - } - return ctx.workflowMetadata; -} - -/** - * Retrieves a writable stream that is associated with the current workflow. - * - * The writable stream is intended to be used within step functions to write - * data that can be read outside the workflow by using the readable method of getRun. - * - * @param options - Optional configuration for the writable stream - * @returns The writable stream associated with the current workflow run - * @throws Error if called outside a workflow or step function - */ -function getWritable(options = {}) { - const ctx = contextStorage.getStore(); - if (!ctx) { - throw new Error('`getWritable()` can only be called inside a workflow or step function'); - } - const { namespace } = options; - const name = getWorkflowRunStreamId(ctx.workflowMetadata.workflowRunId, namespace); - // Create a transform stream that serializes chunks and pipes to the workflow server - const serialize = getSerializeStream(getExternalReducers(globalThis, ctx.ops)); - // Pipe the serialized data to the workflow server stream - // Register this async operation with the runtime's ops array so it's awaited via waitUntil - ctx.ops.push(serialize.readable.pipeTo(new WorkflowServerWritableStream(name))); - // Return the writable side of the transform stream - return serialize.writable; -} - -function __classPrivateFieldSet(receiver, state, value, kind, f) { - if (typeof state === "function" ? receiver !== state || true : !state.has(receiver)) - throw new TypeError("Cannot write private member to an object whose class did not declare it"); - return state.set(receiver, value), value; -} -function __classPrivateFieldGet(receiver, state, kind, f) { - if (kind === "a" && !f) - throw new TypeError("Private accessor was defined without a getter"); - if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) - throw new TypeError("Cannot read private member from an object whose class did not declare it"); - return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -/** - * https://stackoverflow.com/a/2117523 - */ -let uuid4 = function () { - const { crypto } = globalThis; - if (crypto?.randomUUID) { - uuid4 = crypto.randomUUID.bind(crypto); - return crypto.randomUUID(); - } - const u8 = new Uint8Array(1); - const randomByte = crypto ? () => crypto.getRandomValues(u8)[0] : () => (Math.random() * 0xff) & 0xff; - return '10000000-1000-4000-8000-100000000000'.replace(/[018]/g, (c) => (+c ^ (randomByte() & (15 >> (+c / 4)))).toString(16)); -}; - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -function isAbortError(err) { - return (typeof err === 'object' && - err !== null && - // Spec-compliant fetch implementations - (('name' in err && err.name === 'AbortError') || - // Expo fetch - ('message' in err && String(err.message).includes('FetchRequestCanceledException')))); -} -const castToError = (err) => { - if (err instanceof Error) - return err; - if (typeof err === 'object' && err !== null) { - try { - if (Object.prototype.toString.call(err) === '[object Error]') { - // @ts-ignore - not all envs have native support for cause yet - const error = new Error(err.message, err.cause ? { cause: err.cause } : {}); - if (err.stack) - error.stack = err.stack; - // @ts-ignore - not all envs have native support for cause yet - if (err.cause && !error.cause) - error.cause = err.cause; - if (err.name) - error.name = err.name; - return error; - } - } - catch { } - try { - return new Error(JSON.stringify(err)); - } - catch { } - } - return new Error(err); -}; - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class OpenAIError extends Error { -} -class APIError extends OpenAIError { - constructor(status, error, message, headers) { - super(`${APIError.makeMessage(status, error, message)}`); - this.status = status; - this.headers = headers; - this.requestID = headers?.get('x-request-id'); - this.error = error; - const data = error; - this.code = data?.['code']; - this.param = data?.['param']; - this.type = data?.['type']; - } - static makeMessage(status, error, message) { - const msg = error?.message ? - typeof error.message === 'string' ? - error.message - : JSON.stringify(error.message) - : error ? JSON.stringify(error) - : message; - if (status && msg) { - return `${status} ${msg}`; - } - if (status) { - return `${status} status code (no body)`; - } - if (msg) { - return msg; - } - return '(no status code or body)'; - } - static generate(status, errorResponse, message, headers) { - if (!status || !headers) { - return new APIConnectionError({ message, cause: castToError(errorResponse) }); - } - const error = errorResponse?.['error']; - if (status === 400) { - return new BadRequestError(status, error, message, headers); - } - if (status === 401) { - return new AuthenticationError(status, error, message, headers); - } - if (status === 403) { - return new PermissionDeniedError(status, error, message, headers); - } - if (status === 404) { - return new NotFoundError(status, error, message, headers); - } - if (status === 409) { - return new ConflictError(status, error, message, headers); - } - if (status === 422) { - return new UnprocessableEntityError(status, error, message, headers); - } - if (status === 429) { - return new RateLimitError(status, error, message, headers); - } - if (status >= 500) { - return new InternalServerError(status, error, message, headers); - } - return new APIError(status, error, message, headers); - } -} -class APIUserAbortError extends APIError { - constructor({ message } = {}) { - super(undefined, undefined, message || 'Request was aborted.', undefined); - } -} -class APIConnectionError extends APIError { - constructor({ message, cause }) { - super(undefined, undefined, message || 'Connection error.', undefined); - // in some environments the 'cause' property is already declared - // @ts-ignore - if (cause) - this.cause = cause; - } -} -class APIConnectionTimeoutError extends APIConnectionError { - constructor({ message } = {}) { - super({ message: message ?? 'Request timed out.' }); - } -} -class BadRequestError extends APIError { -} -class AuthenticationError extends APIError { -} -class PermissionDeniedError extends APIError { -} -class NotFoundError extends APIError { -} -class ConflictError extends APIError { -} -class UnprocessableEntityError extends APIError { -} -class RateLimitError extends APIError { -} -class InternalServerError extends APIError { -} -class LengthFinishReasonError extends OpenAIError { - constructor() { - super(`Could not parse response content as the length limit was reached`); - } -} -class ContentFilterFinishReasonError extends OpenAIError { - constructor() { - super(`Could not parse response content as the request was rejected by the content filter`); - } -} -class InvalidWebhookSignatureError extends Error { - constructor(message) { - super(message); - } -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -// https://url.spec.whatwg.org/#url-scheme-string -const startsWithSchemeRegexp = /^[a-z][a-z0-9+.-]*:/i; -const isAbsoluteURL = (url) => { - return startsWithSchemeRegexp.test(url); -}; -let isArray = (val) => ((isArray = Array.isArray), isArray(val)); -let isReadonlyArray = isArray; -/** Returns an object if the given value isn't an object, otherwise returns as-is */ -function maybeObj(x) { - if (typeof x !== 'object') { - return {}; - } - return x ?? {}; -} -// https://stackoverflow.com/a/34491287 -function isEmptyObj(obj) { - if (!obj) - return true; - for (const _k in obj) - return false; - return true; -} -// https://eslint.org/docs/latest/rules/no-prototype-builtins -function hasOwn(obj, key) { - return Object.prototype.hasOwnProperty.call(obj, key); -} -function isObj(obj) { - return obj != null && typeof obj === 'object' && !Array.isArray(obj); -} -const validatePositiveInteger = (name, n) => { - if (typeof n !== 'number' || !Number.isInteger(n)) { - throw new OpenAIError(`${name} must be an integer`); - } - if (n < 0) { - throw new OpenAIError(`${name} must be a positive integer`); - } - return n; -}; -const safeJSON = (text) => { - try { - return JSON.parse(text); - } - catch (err) { - return undefined; - } -}; - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); - -const VERSION = '6.1.0'; // x-release-please-version - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -const isRunningInBrowser = () => { - return ( - // @ts-ignore - typeof window !== 'undefined' && - // @ts-ignore - typeof window.document !== 'undefined' && - // @ts-ignore - typeof navigator !== 'undefined'); -}; -/** - * Note this does not detect 'browser'; for that, use getBrowserInfo(). - */ -function getDetectedPlatform() { - if (typeof Deno !== 'undefined' && Deno.build != null) { - return 'deno'; - } - if (typeof EdgeRuntime !== 'undefined') { - return 'edge'; - } - if (Object.prototype.toString.call(typeof globalThis.process !== 'undefined' ? globalThis.process : 0) === '[object process]') { - return 'node'; - } - return 'unknown'; -} -const getPlatformProperties = () => { - const detectedPlatform = getDetectedPlatform(); - if (detectedPlatform === 'deno') { - return { - 'X-Stainless-Lang': 'js', - 'X-Stainless-Package-Version': VERSION, - 'X-Stainless-OS': normalizePlatform(Deno.build.os), - 'X-Stainless-Arch': normalizeArch(Deno.build.arch), - 'X-Stainless-Runtime': 'deno', - 'X-Stainless-Runtime-Version': typeof Deno.version === 'string' ? Deno.version : Deno.version?.deno ?? 'unknown', - }; - } - if (typeof EdgeRuntime !== 'undefined') { - return { - 'X-Stainless-Lang': 'js', - 'X-Stainless-Package-Version': VERSION, - 'X-Stainless-OS': 'Unknown', - 'X-Stainless-Arch': `other:${EdgeRuntime}`, - 'X-Stainless-Runtime': 'edge', - 'X-Stainless-Runtime-Version': globalThis.process.version, - }; - } - // Check if Node.js - if (detectedPlatform === 'node') { - return { - 'X-Stainless-Lang': 'js', - 'X-Stainless-Package-Version': VERSION, - 'X-Stainless-OS': normalizePlatform(globalThis.process.platform ?? 'unknown'), - 'X-Stainless-Arch': normalizeArch(globalThis.process.arch ?? 'unknown'), - 'X-Stainless-Runtime': 'node', - 'X-Stainless-Runtime-Version': globalThis.process.version ?? 'unknown', - }; - } - const browserInfo = getBrowserInfo(); - if (browserInfo) { - return { - 'X-Stainless-Lang': 'js', - 'X-Stainless-Package-Version': VERSION, - 'X-Stainless-OS': 'Unknown', - 'X-Stainless-Arch': 'unknown', - 'X-Stainless-Runtime': `browser:${browserInfo.browser}`, - 'X-Stainless-Runtime-Version': browserInfo.version, - }; - } - // TODO add support for Cloudflare workers, etc. - return { - 'X-Stainless-Lang': 'js', - 'X-Stainless-Package-Version': VERSION, - 'X-Stainless-OS': 'Unknown', - 'X-Stainless-Arch': 'unknown', - 'X-Stainless-Runtime': 'unknown', - 'X-Stainless-Runtime-Version': 'unknown', - }; -}; -// Note: modified from https://github.com/JS-DevTools/host-environment/blob/b1ab79ecde37db5d6e163c050e54fe7d287d7c92/src/isomorphic.browser.ts -function getBrowserInfo() { - if (typeof navigator === 'undefined' || !navigator) { - return null; - } - // NOTE: The order matters here! - const browserPatterns = [ - { key: 'edge', pattern: /Edge(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ }, - { key: 'ie', pattern: /MSIE(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ }, - { key: 'ie', pattern: /Trident(?:.*rv\:(\d+)\.(\d+)(?:\.(\d+))?)?/ }, - { key: 'chrome', pattern: /Chrome(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ }, - { key: 'firefox', pattern: /Firefox(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ }, - { key: 'safari', pattern: /(?:Version\W+(\d+)\.(\d+)(?:\.(\d+))?)?(?:\W+Mobile\S*)?\W+Safari/ }, - ]; - // Find the FIRST matching browser - for (const { key, pattern } of browserPatterns) { - const match = pattern.exec(navigator.userAgent); - if (match) { - const major = match[1] || 0; - const minor = match[2] || 0; - const patch = match[3] || 0; - return { browser: key, version: `${major}.${minor}.${patch}` }; - } - } - return null; -} -const normalizeArch = (arch) => { - // Node docs: - // - https://nodejs.org/api/process.html#processarch - // Deno docs: - // - https://doc.deno.land/deno/stable/~/Deno.build - if (arch === 'x32') - return 'x32'; - if (arch === 'x86_64' || arch === 'x64') - return 'x64'; - if (arch === 'arm') - return 'arm'; - if (arch === 'aarch64' || arch === 'arm64') - return 'arm64'; - if (arch) - return `other:${arch}`; - return 'unknown'; -}; -const normalizePlatform = (platform) => { - // Node platforms: - // - https://nodejs.org/api/process.html#processplatform - // Deno platforms: - // - https://doc.deno.land/deno/stable/~/Deno.build - // - https://github.com/denoland/deno/issues/14799 - platform = platform.toLowerCase(); - // NOTE: this iOS check is untested and may not work - // Node does not work natively on IOS, there is a fork at - // https://github.com/nodejs-mobile/nodejs-mobile - // however it is unknown at the time of writing how to detect if it is running - if (platform.includes('ios')) - return 'iOS'; - if (platform === 'android') - return 'Android'; - if (platform === 'darwin') - return 'MacOS'; - if (platform === 'win32') - return 'Windows'; - if (platform === 'freebsd') - return 'FreeBSD'; - if (platform === 'openbsd') - return 'OpenBSD'; - if (platform === 'linux') - return 'Linux'; - if (platform) - return `Other:${platform}`; - return 'Unknown'; -}; -let _platformHeaders; -const getPlatformHeaders = () => { - return (_platformHeaders ?? (_platformHeaders = getPlatformProperties())); -}; - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -function getDefaultFetch() { - if (typeof fetch !== 'undefined') { - return fetch; - } - throw new Error('`fetch` is not defined as a global; Either pass `fetch` to the client, `new OpenAI({ fetch })` or polyfill the global, `globalThis.fetch = fetch`'); -} -function makeReadableStream(...args) { - const ReadableStream = globalThis.ReadableStream; - if (typeof ReadableStream === 'undefined') { - // Note: All of the platforms / runtimes we officially support already define - // `ReadableStream` as a global, so this should only ever be hit on unsupported runtimes. - throw new Error('`ReadableStream` is not defined as a global; You will need to polyfill it, `globalThis.ReadableStream = ReadableStream`'); - } - return new ReadableStream(...args); -} -function ReadableStreamFrom(iterable) { - let iter = Symbol.asyncIterator in iterable ? iterable[Symbol.asyncIterator]() : iterable[Symbol.iterator](); - return makeReadableStream({ - start() { }, - async pull(controller) { - const { done, value } = await iter.next(); - if (done) { - controller.close(); - } - else { - controller.enqueue(value); - } - }, - async cancel() { - await iter.return?.(); - }, - }); -} -/** - * Most browsers don't yet have async iterable support for ReadableStream, - * and Node has a very different way of reading bytes from its "ReadableStream". - * - * This polyfill was pulled from https://github.com/MattiasBuelens/web-streams-polyfill/pull/122#issuecomment-1627354490 - */ -function ReadableStreamToAsyncIterable(stream) { - if (stream[Symbol.asyncIterator]) - return stream; - const reader = stream.getReader(); - return { - async next() { - try { - const result = await reader.read(); - if (result?.done) - reader.releaseLock(); // release lock when stream becomes closed - return result; - } - catch (e) { - reader.releaseLock(); // release lock when stream becomes errored - throw e; - } - }, - async return() { - const cancelPromise = reader.cancel(); - reader.releaseLock(); - await cancelPromise; - return { done: true, value: undefined }; - }, - [Symbol.asyncIterator]() { - return this; - }, - }; -} -/** - * Cancels a ReadableStream we don't need to consume. - * See https://undici.nodejs.org/#/?id=garbage-collection - */ -async function CancelReadableStream(stream) { - if (stream === null || typeof stream !== 'object') - return; - if (stream[Symbol.asyncIterator]) { - await stream[Symbol.asyncIterator]().return?.(); - return; - } - const reader = stream.getReader(); - const cancelPromise = reader.cancel(); - reader.releaseLock(); - await cancelPromise; -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -const FallbackEncoder = ({ headers, body }) => { - return { - bodyHeaders: { - 'content-type': 'application/json', - }, - body: JSON.stringify(body), - }; -}; - -const default_format = 'RFC3986'; -const default_formatter = (v) => String(v); -const formatters = { - RFC1738: (v) => String(v).replace(/%20/g, '+'), - RFC3986: default_formatter, -}; -const RFC1738 = 'RFC1738'; - -let has = (obj, key) => ((has = Object.hasOwn ?? Function.prototype.call.bind(Object.prototype.hasOwnProperty)), - has(obj, key)); -const hex_table = /* @__PURE__ */ (() => { - const array = []; - for (let i = 0; i < 256; ++i) { - array.push('%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase()); - } - return array; -})(); -const limit = 1024; -const encode = (str, _defaultEncoder, charset, _kind, format) => { - // This code was originally written by Brian White for the io.js core querystring library. - // It has been adapted here for stricter adherence to RFC 3986 - if (str.length === 0) { - return str; - } - let string = str; - if (typeof str === 'symbol') { - string = Symbol.prototype.toString.call(str); - } - else if (typeof str !== 'string') { - string = String(str); - } - if (charset === 'iso-8859-1') { - return escape(string).replace(/%u[0-9a-f]{4}/gi, function ($0) { - return '%26%23' + parseInt($0.slice(2), 16) + '%3B'; - }); - } - let out = ''; - for (let j = 0; j < string.length; j += limit) { - const segment = string.length >= limit ? string.slice(j, j + limit) : string; - const arr = []; - for (let i = 0; i < segment.length; ++i) { - let c = segment.charCodeAt(i); - if (c === 0x2d || // - - c === 0x2e || // . - c === 0x5f || // _ - c === 0x7e || // ~ - (c >= 0x30 && c <= 0x39) || // 0-9 - (c >= 0x41 && c <= 0x5a) || // a-z - (c >= 0x61 && c <= 0x7a) || // A-Z - (format === RFC1738 && (c === 0x28 || c === 0x29)) // ( ) - ) { - arr[arr.length] = segment.charAt(i); - continue; - } - if (c < 0x80) { - arr[arr.length] = hex_table[c]; - continue; - } - if (c < 0x800) { - arr[arr.length] = hex_table[0xc0 | (c >> 6)] + hex_table[0x80 | (c & 0x3f)]; - continue; - } - if (c < 0xd800 || c >= 0xe000) { - arr[arr.length] = - hex_table[0xe0 | (c >> 12)] + hex_table[0x80 | ((c >> 6) & 0x3f)] + hex_table[0x80 | (c & 0x3f)]; - continue; - } - i += 1; - c = 0x10000 + (((c & 0x3ff) << 10) | (segment.charCodeAt(i) & 0x3ff)); - arr[arr.length] = - hex_table[0xf0 | (c >> 18)] + - hex_table[0x80 | ((c >> 12) & 0x3f)] + - hex_table[0x80 | ((c >> 6) & 0x3f)] + - hex_table[0x80 | (c & 0x3f)]; - } - out += arr.join(''); - } - return out; -}; -function is_buffer(obj) { - if (!obj || typeof obj !== 'object') { - return false; - } - return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj)); -} -function maybe_map(val, fn) { - if (isArray(val)) { - const mapped = []; - for (let i = 0; i < val.length; i += 1) { - mapped.push(fn(val[i])); - } - return mapped; - } - return fn(val); -} - -const array_prefix_generators = { - brackets(prefix) { - return String(prefix) + '[]'; - }, - comma: 'comma', - indices(prefix, key) { - return String(prefix) + '[' + key + ']'; - }, - repeat(prefix) { - return String(prefix); - }, -}; -const push_to_array = function (arr, value_or_array) { - Array.prototype.push.apply(arr, isArray(value_or_array) ? value_or_array : [value_or_array]); -}; -let toISOString; -const defaults = { - addQueryPrefix: false, - allowDots: false, - allowEmptyArrays: false, - arrayFormat: 'indices', - charset: 'utf-8', - charsetSentinel: false, - delimiter: '&', - encode: true, - encodeDotInKeys: false, - encoder: encode, - encodeValuesOnly: false, - format: default_format, - formatter: default_formatter, - /** @deprecated */ - indices: false, - serializeDate(date) { - return (toISOString ?? (toISOString = Function.prototype.call.bind(Date.prototype.toISOString)))(date); - }, - skipNulls: false, - strictNullHandling: false, -}; -function is_non_nullish_primitive(v) { - return (typeof v === 'string' || - typeof v === 'number' || - typeof v === 'boolean' || - typeof v === 'symbol' || - typeof v === 'bigint'); -} -const sentinel = {}; -function inner_stringify(object, prefix, generateArrayPrefix, commaRoundTrip, allowEmptyArrays, strictNullHandling, skipNulls, encodeDotInKeys, encoder, filter, sort, allowDots, serializeDate, format, formatter, encodeValuesOnly, charset, sideChannel) { - let obj = object; - let tmp_sc = sideChannel; - let step = 0; - let find_flag = false; - while ((tmp_sc = tmp_sc.get(sentinel)) !== void undefined && !find_flag) { - // Where object last appeared in the ref tree - const pos = tmp_sc.get(object); - step += 1; - if (typeof pos !== 'undefined') { - if (pos === step) { - throw new RangeError('Cyclic object value'); - } - else { - find_flag = true; // Break while - } - } - if (typeof tmp_sc.get(sentinel) === 'undefined') { - step = 0; - } - } - if (typeof filter === 'function') { - obj = filter(prefix, obj); - } - else if (obj instanceof Date) { - obj = serializeDate?.(obj); - } - else if (generateArrayPrefix === 'comma' && isArray(obj)) { - obj = maybe_map(obj, function (value) { - if (value instanceof Date) { - return serializeDate?.(value); - } - return value; - }); - } - if (obj === null) { - if (strictNullHandling) { - return encoder && !encodeValuesOnly ? - // @ts-expect-error - encoder(prefix, defaults.encoder, charset, 'key', format) - : prefix; - } - obj = ''; - } - if (is_non_nullish_primitive(obj) || is_buffer(obj)) { - if (encoder) { - const key_value = encodeValuesOnly ? prefix - // @ts-expect-error - : encoder(prefix, defaults.encoder, charset, 'key', format); - return [ - formatter?.(key_value) + - '=' + - // @ts-expect-error - formatter?.(encoder(obj, defaults.encoder, charset, 'value', format)), - ]; - } - return [formatter?.(prefix) + '=' + formatter?.(String(obj))]; - } - const values = []; - if (typeof obj === 'undefined') { - return values; - } - let obj_keys; - if (generateArrayPrefix === 'comma' && isArray(obj)) { - // we need to join elements in - if (encodeValuesOnly && encoder) { - // @ts-expect-error values only - obj = maybe_map(obj, encoder); - } - obj_keys = [{ value: obj.length > 0 ? obj.join(',') || null : void undefined }]; - } - else if (isArray(filter)) { - obj_keys = filter; - } - else { - const keys = Object.keys(obj); - obj_keys = sort ? keys.sort(sort) : keys; - } - const encoded_prefix = encodeDotInKeys ? String(prefix).replace(/\./g, '%2E') : String(prefix); - const adjusted_prefix = commaRoundTrip && isArray(obj) && obj.length === 1 ? encoded_prefix + '[]' : encoded_prefix; - if (allowEmptyArrays && isArray(obj) && obj.length === 0) { - return adjusted_prefix + '[]'; - } - for (let j = 0; j < obj_keys.length; ++j) { - const key = obj_keys[j]; - const value = - // @ts-ignore - typeof key === 'object' && typeof key.value !== 'undefined' ? key.value : obj[key]; - if (skipNulls && value === null) { - continue; - } - // @ts-ignore - const encoded_key = allowDots && encodeDotInKeys ? key.replace(/\./g, '%2E') : key; - const key_prefix = isArray(obj) ? - typeof generateArrayPrefix === 'function' ? - generateArrayPrefix(adjusted_prefix, encoded_key) - : adjusted_prefix - : adjusted_prefix + (allowDots ? '.' + encoded_key : '[' + encoded_key + ']'); - sideChannel.set(object, step); - const valueSideChannel = new WeakMap(); - valueSideChannel.set(sentinel, sideChannel); - push_to_array(values, inner_stringify(value, key_prefix, generateArrayPrefix, commaRoundTrip, allowEmptyArrays, strictNullHandling, skipNulls, encodeDotInKeys, - // @ts-ignore - generateArrayPrefix === 'comma' && encodeValuesOnly && isArray(obj) ? null : encoder, filter, sort, allowDots, serializeDate, format, formatter, encodeValuesOnly, charset, valueSideChannel)); - } - return values; -} -function normalize_stringify_options(opts = defaults) { - if (typeof opts.allowEmptyArrays !== 'undefined' && typeof opts.allowEmptyArrays !== 'boolean') { - throw new TypeError('`allowEmptyArrays` option can only be `true` or `false`, when provided'); - } - if (typeof opts.encodeDotInKeys !== 'undefined' && typeof opts.encodeDotInKeys !== 'boolean') { - throw new TypeError('`encodeDotInKeys` option can only be `true` or `false`, when provided'); - } - if (opts.encoder !== null && typeof opts.encoder !== 'undefined' && typeof opts.encoder !== 'function') { - throw new TypeError('Encoder has to be a function.'); - } - const charset = opts.charset || defaults.charset; - if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') { - throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined'); - } - let format = default_format; - if (typeof opts.format !== 'undefined') { - if (!has(formatters, opts.format)) { - throw new TypeError('Unknown format option provided.'); - } - format = opts.format; - } - const formatter = formatters[format]; - let filter = defaults.filter; - if (typeof opts.filter === 'function' || isArray(opts.filter)) { - filter = opts.filter; - } - let arrayFormat; - if (opts.arrayFormat && opts.arrayFormat in array_prefix_generators) { - arrayFormat = opts.arrayFormat; - } - else if ('indices' in opts) { - arrayFormat = opts.indices ? 'indices' : 'repeat'; - } - else { - arrayFormat = defaults.arrayFormat; - } - if ('commaRoundTrip' in opts && typeof opts.commaRoundTrip !== 'boolean') { - throw new TypeError('`commaRoundTrip` must be a boolean, or absent'); - } - const allowDots = typeof opts.allowDots === 'undefined' ? - !!opts.encodeDotInKeys === true ? - true - : defaults.allowDots - : !!opts.allowDots; - return { - addQueryPrefix: typeof opts.addQueryPrefix === 'boolean' ? opts.addQueryPrefix : defaults.addQueryPrefix, - // @ts-ignore - allowDots: allowDots, - allowEmptyArrays: typeof opts.allowEmptyArrays === 'boolean' ? !!opts.allowEmptyArrays : defaults.allowEmptyArrays, - arrayFormat: arrayFormat, - charset: charset, - charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel, - commaRoundTrip: !!opts.commaRoundTrip, - delimiter: typeof opts.delimiter === 'undefined' ? defaults.delimiter : opts.delimiter, - encode: typeof opts.encode === 'boolean' ? opts.encode : defaults.encode, - encodeDotInKeys: typeof opts.encodeDotInKeys === 'boolean' ? opts.encodeDotInKeys : defaults.encodeDotInKeys, - encoder: typeof opts.encoder === 'function' ? opts.encoder : defaults.encoder, - encodeValuesOnly: typeof opts.encodeValuesOnly === 'boolean' ? opts.encodeValuesOnly : defaults.encodeValuesOnly, - filter: filter, - format: format, - formatter: formatter, - serializeDate: typeof opts.serializeDate === 'function' ? opts.serializeDate : defaults.serializeDate, - skipNulls: typeof opts.skipNulls === 'boolean' ? opts.skipNulls : defaults.skipNulls, - // @ts-ignore - sort: typeof opts.sort === 'function' ? opts.sort : null, - strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling, - }; -} -function stringify(object, opts = {}) { - let obj = object; - const options = normalize_stringify_options(opts); - let obj_keys; - let filter; - if (typeof options.filter === 'function') { - filter = options.filter; - obj = filter('', obj); - } - else if (isArray(options.filter)) { - filter = options.filter; - obj_keys = filter; - } - const keys = []; - if (typeof obj !== 'object' || obj === null) { - return ''; - } - const generateArrayPrefix = array_prefix_generators[options.arrayFormat]; - const commaRoundTrip = generateArrayPrefix === 'comma' && options.commaRoundTrip; - if (!obj_keys) { - obj_keys = Object.keys(obj); - } - if (options.sort) { - obj_keys.sort(options.sort); - } - const sideChannel = new WeakMap(); - for (let i = 0; i < obj_keys.length; ++i) { - const key = obj_keys[i]; - if (options.skipNulls && obj[key] === null) { - continue; - } - push_to_array(keys, inner_stringify(obj[key], key, - // @ts-expect-error - generateArrayPrefix, commaRoundTrip, options.allowEmptyArrays, options.strictNullHandling, options.skipNulls, options.encodeDotInKeys, options.encode ? options.encoder : null, options.filter, options.sort, options.allowDots, options.serializeDate, options.format, options.formatter, options.encodeValuesOnly, options.charset, sideChannel)); - } - const joined = keys.join(options.delimiter); - let prefix = options.addQueryPrefix === true ? '?' : ''; - if (options.charsetSentinel) { - if (options.charset === 'iso-8859-1') { - // encodeURIComponent('✓'), the "numeric entity" representation of a checkmark - prefix += 'utf8=%26%2310003%3B&'; - } - else { - // encodeURIComponent('✓') - prefix += 'utf8=%E2%9C%93&'; - } - } - return joined.length > 0 ? prefix + joined : ''; -} - -function concatBytes(buffers) { - let length = 0; - for (const buffer of buffers) { - length += buffer.length; - } - const output = new Uint8Array(length); - let index = 0; - for (const buffer of buffers) { - output.set(buffer, index); - index += buffer.length; - } - return output; -} -let encodeUTF8_; -function encodeUTF8(str) { - let encoder; - return (encodeUTF8_ ?? - ((encoder = new globalThis.TextEncoder()), (encodeUTF8_ = encoder.encode.bind(encoder))))(str); -} -let decodeUTF8_; -function decodeUTF8(bytes) { - let decoder; - return (decodeUTF8_ ?? - ((decoder = new globalThis.TextDecoder()), (decodeUTF8_ = decoder.decode.bind(decoder))))(bytes); -} - -var _LineDecoder_buffer, _LineDecoder_carriageReturnIndex; -/** - * A re-implementation of httpx's `LineDecoder` in Python that handles incrementally - * reading lines from text. - * - * https://github.com/encode/httpx/blob/920333ea98118e9cf617f246905d7b202510941c/httpx/_decoders.py#L258 - */ -class LineDecoder { - constructor() { - _LineDecoder_buffer.set(this, void 0); - _LineDecoder_carriageReturnIndex.set(this, void 0); - __classPrivateFieldSet(this, _LineDecoder_buffer, new Uint8Array()); - __classPrivateFieldSet(this, _LineDecoder_carriageReturnIndex, null); - } - decode(chunk) { - if (chunk == null) { - return []; - } - const binaryChunk = chunk instanceof ArrayBuffer ? new Uint8Array(chunk) - : typeof chunk === 'string' ? encodeUTF8(chunk) - : chunk; - __classPrivateFieldSet(this, _LineDecoder_buffer, concatBytes([__classPrivateFieldGet(this, _LineDecoder_buffer, "f"), binaryChunk])); - const lines = []; - let patternIndex; - while ((patternIndex = findNewlineIndex(__classPrivateFieldGet(this, _LineDecoder_buffer, "f"), __classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f"))) != null) { - if (patternIndex.carriage && __classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f") == null) { - // skip until we either get a corresponding `\n`, a new `\r` or nothing - __classPrivateFieldSet(this, _LineDecoder_carriageReturnIndex, patternIndex.index); - continue; - } - // we got double \r or \rtext\n - if (__classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f") != null && - (patternIndex.index !== __classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f") + 1 || patternIndex.carriage)) { - lines.push(decodeUTF8(__classPrivateFieldGet(this, _LineDecoder_buffer, "f").subarray(0, __classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f") - 1))); - __classPrivateFieldSet(this, _LineDecoder_buffer, __classPrivateFieldGet(this, _LineDecoder_buffer, "f").subarray(__classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f"))); - __classPrivateFieldSet(this, _LineDecoder_carriageReturnIndex, null); - continue; - } - const endIndex = __classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f") !== null ? patternIndex.preceding - 1 : patternIndex.preceding; - const line = decodeUTF8(__classPrivateFieldGet(this, _LineDecoder_buffer, "f").subarray(0, endIndex)); - lines.push(line); - __classPrivateFieldSet(this, _LineDecoder_buffer, __classPrivateFieldGet(this, _LineDecoder_buffer, "f").subarray(patternIndex.index)); - __classPrivateFieldSet(this, _LineDecoder_carriageReturnIndex, null); - } - return lines; - } - flush() { - if (!__classPrivateFieldGet(this, _LineDecoder_buffer, "f").length) { - return []; - } - return this.decode('\n'); - } -} -_LineDecoder_buffer = new WeakMap(), _LineDecoder_carriageReturnIndex = new WeakMap(); -// prettier-ignore -LineDecoder.NEWLINE_CHARS = new Set(['\n', '\r']); -LineDecoder.NEWLINE_REGEXP = /\r\n|[\n\r]/g; -/** - * This function searches the buffer for the end patterns, (\r or \n) - * and returns an object with the index preceding the matched newline and the - * index after the newline char. `null` is returned if no new line is found. - * - * ```ts - * findNewLineIndex('abc\ndef') -> { preceding: 2, index: 3 } - * ``` - */ -function findNewlineIndex(buffer, startIndex) { - const newline = 0x0a; // \n - const carriage = 0x0d; // \r - for (let i = startIndex ?? 0; i < buffer.length; i++) { - if (buffer[i] === newline) { - return { preceding: i, index: i + 1, carriage: false }; - } - if (buffer[i] === carriage) { - return { preceding: i, index: i + 1, carriage: true }; - } - } - return null; -} -function findDoubleNewlineIndex(buffer) { - // This function searches the buffer for the end patterns (\r\r, \n\n, \r\n\r\n) - // and returns the index right after the first occurrence of any pattern, - // or -1 if none of the patterns are found. - const newline = 0x0a; // \n - const carriage = 0x0d; // \r - for (let i = 0; i < buffer.length - 1; i++) { - if (buffer[i] === newline && buffer[i + 1] === newline) { - // \n\n - return i + 2; - } - if (buffer[i] === carriage && buffer[i + 1] === carriage) { - // \r\r - return i + 2; - } - if (buffer[i] === carriage && - buffer[i + 1] === newline && - i + 3 < buffer.length && - buffer[i + 2] === carriage && - buffer[i + 3] === newline) { - // \r\n\r\n - return i + 4; - } - } - return -1; -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -const levelNumbers = { - off: 0, - error: 200, - warn: 300, - info: 400, - debug: 500, -}; -const parseLogLevel = (maybeLevel, sourceName, client) => { - if (!maybeLevel) { - return undefined; - } - if (hasOwn(levelNumbers, maybeLevel)) { - return maybeLevel; - } - loggerFor(client).warn(`${sourceName} was set to ${JSON.stringify(maybeLevel)}, expected one of ${JSON.stringify(Object.keys(levelNumbers))}`); - return undefined; -}; -function noop() { } -function makeLogFn(fnLevel, logger, logLevel) { - if (!logger || levelNumbers[fnLevel] > levelNumbers[logLevel]) { - return noop; - } - else { - // Don't wrap logger functions, we want the stacktrace intact! - return logger[fnLevel].bind(logger); - } -} -const noopLogger = { - error: noop, - warn: noop, - info: noop, - debug: noop, -}; -let cachedLoggers = /* @__PURE__ */ new WeakMap(); -function loggerFor(client) { - const logger = client.logger; - const logLevel = client.logLevel ?? 'off'; - if (!logger) { - return noopLogger; - } - const cachedLogger = cachedLoggers.get(logger); - if (cachedLogger && cachedLogger[0] === logLevel) { - return cachedLogger[1]; - } - const levelLogger = { - error: makeLogFn('error', logger, logLevel), - warn: makeLogFn('warn', logger, logLevel), - info: makeLogFn('info', logger, logLevel), - debug: makeLogFn('debug', logger, logLevel), - }; - cachedLoggers.set(logger, [logLevel, levelLogger]); - return levelLogger; -} -const formatRequestDetails = (details) => { - if (details.options) { - details.options = { ...details.options }; - delete details.options['headers']; // redundant + leaks internals - } - if (details.headers) { - details.headers = Object.fromEntries((details.headers instanceof Headers ? [...details.headers] : Object.entries(details.headers)).map(([name, value]) => [ - name, - (name.toLowerCase() === 'authorization' || - name.toLowerCase() === 'cookie' || - name.toLowerCase() === 'set-cookie') ? - '***' - : value, - ])); - } - if ('retryOfRequestLogID' in details) { - if (details.retryOfRequestLogID) { - details.retryOf = details.retryOfRequestLogID; - } - delete details.retryOfRequestLogID; - } - return details; -}; - -var _Stream_client; -class Stream { - constructor(iterator, controller, client) { - this.iterator = iterator; - _Stream_client.set(this, void 0); - this.controller = controller; - __classPrivateFieldSet(this, _Stream_client, client); - } - static fromSSEResponse(response, controller, client) { - let consumed = false; - const logger = client ? loggerFor(client) : console; - async function* iterator() { - if (consumed) { - throw new OpenAIError('Cannot iterate over a consumed stream, use `.tee()` to split the stream.'); - } - consumed = true; - let done = false; - try { - for await (const sse of _iterSSEMessages(response, controller)) { - if (done) - continue; - if (sse.data.startsWith('[DONE]')) { - done = true; - continue; - } - if (sse.event === null || !sse.event.startsWith('thread.')) { - let data; - try { - data = JSON.parse(sse.data); - } - catch (e) { - logger.error(`Could not parse message into JSON:`, sse.data); - logger.error(`From chunk:`, sse.raw); - throw e; - } - if (data && data.error) { - throw new APIError(undefined, data.error, undefined, response.headers); - } - yield data; - } - else { - let data; - try { - data = JSON.parse(sse.data); - } - catch (e) { - console.error(`Could not parse message into JSON:`, sse.data); - console.error(`From chunk:`, sse.raw); - throw e; - } - // TODO: Is this where the error should be thrown? - if (sse.event == 'error') { - throw new APIError(undefined, data.error, data.message, undefined); - } - yield { event: sse.event, data: data }; - } - } - done = true; - } - catch (e) { - // If the user calls `stream.controller.abort()`, we should exit without throwing. - if (isAbortError(e)) - return; - throw e; - } - finally { - // If the user `break`s, abort the ongoing request. - if (!done) - controller.abort(); - } - } - return new Stream(iterator, controller, client); - } - /** - * Generates a Stream from a newline-separated ReadableStream - * where each item is a JSON value. - */ - static fromReadableStream(readableStream, controller, client) { - let consumed = false; - async function* iterLines() { - const lineDecoder = new LineDecoder(); - const iter = ReadableStreamToAsyncIterable(readableStream); - for await (const chunk of iter) { - for (const line of lineDecoder.decode(chunk)) { - yield line; - } - } - for (const line of lineDecoder.flush()) { - yield line; - } - } - async function* iterator() { - if (consumed) { - throw new OpenAIError('Cannot iterate over a consumed stream, use `.tee()` to split the stream.'); - } - consumed = true; - let done = false; - try { - for await (const line of iterLines()) { - if (done) - continue; - if (line) - yield JSON.parse(line); - } - done = true; - } - catch (e) { - // If the user calls `stream.controller.abort()`, we should exit without throwing. - if (isAbortError(e)) - return; - throw e; - } - finally { - // If the user `break`s, abort the ongoing request. - if (!done) - controller.abort(); - } - } - return new Stream(iterator, controller, client); - } - [(_Stream_client = new WeakMap(), Symbol.asyncIterator)]() { - return this.iterator(); - } - /** - * Splits the stream into two streams which can be - * independently read from at different speeds. - */ - tee() { - const left = []; - const right = []; - const iterator = this.iterator(); - const teeIterator = (queue) => { - return { - next: () => { - if (queue.length === 0) { - const result = iterator.next(); - left.push(result); - right.push(result); - } - return queue.shift(); - }, - }; - }; - return [ - new Stream(() => teeIterator(left), this.controller, __classPrivateFieldGet(this, _Stream_client, "f")), - new Stream(() => teeIterator(right), this.controller, __classPrivateFieldGet(this, _Stream_client, "f")), - ]; - } - /** - * Converts this stream to a newline-separated ReadableStream of - * JSON stringified values in the stream - * which can be turned back into a Stream with `Stream.fromReadableStream()`. - */ - toReadableStream() { - const self = this; - let iter; - return makeReadableStream({ - async start() { - iter = self[Symbol.asyncIterator](); - }, - async pull(ctrl) { - try { - const { value, done } = await iter.next(); - if (done) - return ctrl.close(); - const bytes = encodeUTF8(JSON.stringify(value) + '\n'); - ctrl.enqueue(bytes); - } - catch (err) { - ctrl.error(err); - } - }, - async cancel() { - await iter.return?.(); - }, - }); - } -} -async function* _iterSSEMessages(response, controller) { - if (!response.body) { - controller.abort(); - if (typeof globalThis.navigator !== 'undefined' && - globalThis.navigator.product === 'ReactNative') { - throw new OpenAIError(`The default react-native fetch implementation does not support streaming. Please use expo/fetch: https://docs.expo.dev/versions/latest/sdk/expo/#expofetch-api`); - } - throw new OpenAIError(`Attempted to iterate over a response with no body`); - } - const sseDecoder = new SSEDecoder(); - const lineDecoder = new LineDecoder(); - const iter = ReadableStreamToAsyncIterable(response.body); - for await (const sseChunk of iterSSEChunks(iter)) { - for (const line of lineDecoder.decode(sseChunk)) { - const sse = sseDecoder.decode(line); - if (sse) - yield sse; - } - } - for (const line of lineDecoder.flush()) { - const sse = sseDecoder.decode(line); - if (sse) - yield sse; - } -} -/** - * Given an async iterable iterator, iterates over it and yields full - * SSE chunks, i.e. yields when a double new-line is encountered. - */ -async function* iterSSEChunks(iterator) { - let data = new Uint8Array(); - for await (const chunk of iterator) { - if (chunk == null) { - continue; - } - const binaryChunk = chunk instanceof ArrayBuffer ? new Uint8Array(chunk) - : typeof chunk === 'string' ? encodeUTF8(chunk) - : chunk; - let newData = new Uint8Array(data.length + binaryChunk.length); - newData.set(data); - newData.set(binaryChunk, data.length); - data = newData; - let patternIndex; - while ((patternIndex = findDoubleNewlineIndex(data)) !== -1) { - yield data.slice(0, patternIndex); - data = data.slice(patternIndex); - } - } - if (data.length > 0) { - yield data; - } -} -class SSEDecoder { - constructor() { - this.event = null; - this.data = []; - this.chunks = []; - } - decode(line) { - if (line.endsWith('\r')) { - line = line.substring(0, line.length - 1); - } - if (!line) { - // empty line and we didn't previously encounter any messages - if (!this.event && !this.data.length) - return null; - const sse = { - event: this.event, - data: this.data.join('\n'), - raw: this.chunks, - }; - this.event = null; - this.data = []; - this.chunks = []; - return sse; - } - this.chunks.push(line); - if (line.startsWith(':')) { - return null; - } - let [fieldname, _, value] = partition(line, ':'); - if (value.startsWith(' ')) { - value = value.substring(1); - } - if (fieldname === 'event') { - this.event = value; - } - else if (fieldname === 'data') { - this.data.push(value); - } - return null; - } -} -function partition(str, delimiter) { - const index = str.indexOf(delimiter); - if (index !== -1) { - return [str.substring(0, index), delimiter, str.substring(index + delimiter.length)]; - } - return [str, '', '']; -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -async function defaultParseResponse(client, props) { - const { response, requestLogID, retryOfRequestLogID, startTime } = props; - const body = await (async () => { - if (props.options.stream) { - loggerFor(client).debug('response', response.status, response.url, response.headers, response.body); - // Note: there is an invariant here that isn't represented in the type system - // that if you set `stream: true` the response type must also be `Stream` - if (props.options.__streamClass) { - return props.options.__streamClass.fromSSEResponse(response, props.controller, client); - } - return Stream.fromSSEResponse(response, props.controller, client); - } - // fetch refuses to read the body when the status code is 204. - if (response.status === 204) { - return null; - } - if (props.options.__binaryResponse) { - return response; - } - const contentType = response.headers.get('content-type'); - const mediaType = contentType?.split(';')[0]?.trim(); - const isJSON = mediaType?.includes('application/json') || mediaType?.endsWith('+json'); - if (isJSON) { - const json = await response.json(); - return addRequestID(json, response); - } - const text = await response.text(); - return text; - })(); - loggerFor(client).debug(`[${requestLogID}] response parsed`, formatRequestDetails({ - retryOfRequestLogID, - url: response.url, - status: response.status, - body, - durationMs: Date.now() - startTime, - })); - return body; -} -function addRequestID(value, response) { - if (!value || typeof value !== 'object' || Array.isArray(value)) { - return value; - } - return Object.defineProperty(value, '_request_id', { - value: response.headers.get('x-request-id'), - enumerable: false, - }); -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -var _APIPromise_client; -/** - * A subclass of `Promise` providing additional helper methods - * for interacting with the SDK. - */ -class APIPromise extends Promise { - constructor(client, responsePromise, parseResponse = defaultParseResponse) { - super((resolve) => { - // this is maybe a bit weird but this has to be a no-op to not implicitly - // parse the response body; instead .then, .catch, .finally are overridden - // to parse the response - resolve(null); - }); - this.responsePromise = responsePromise; - this.parseResponse = parseResponse; - _APIPromise_client.set(this, void 0); - __classPrivateFieldSet(this, _APIPromise_client, client); - } - _thenUnwrap(transform) { - return new APIPromise(__classPrivateFieldGet(this, _APIPromise_client, "f"), this.responsePromise, async (client, props) => addRequestID(transform(await this.parseResponse(client, props), props), props.response)); - } - /** - * Gets the raw `Response` instance instead of parsing the response - * data. - * - * If you want to parse the response body but still get the `Response` - * instance, you can use {@link withResponse()}. - * - * 👋 Getting the wrong TypeScript type for `Response`? - * Try setting `"moduleResolution": "NodeNext"` or add `"lib": ["DOM"]` - * to your `tsconfig.json`. - */ - asResponse() { - return this.responsePromise.then((p) => p.response); - } - /** - * Gets the parsed response data, the raw `Response` instance and the ID of the request, - * returned via the X-Request-ID header which is useful for debugging requests and reporting - * issues to OpenAI. - * - * If you just want to get the raw `Response` instance without parsing it, - * you can use {@link asResponse()}. - * - * 👋 Getting the wrong TypeScript type for `Response`? - * Try setting `"moduleResolution": "NodeNext"` or add `"lib": ["DOM"]` - * to your `tsconfig.json`. - */ - async withResponse() { - const [data, response] = await Promise.all([this.parse(), this.asResponse()]); - return { data, response, request_id: response.headers.get('x-request-id') }; - } - parse() { - if (!this.parsedPromise) { - this.parsedPromise = this.responsePromise.then((data) => this.parseResponse(__classPrivateFieldGet(this, _APIPromise_client, "f"), data)); - } - return this.parsedPromise; - } - then(onfulfilled, onrejected) { - return this.parse().then(onfulfilled, onrejected); - } - catch(onrejected) { - return this.parse().catch(onrejected); - } - finally(onfinally) { - return this.parse().finally(onfinally); - } -} -_APIPromise_client = new WeakMap(); - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -var _AbstractPage_client; -class AbstractPage { - constructor(client, response, body, options) { - _AbstractPage_client.set(this, void 0); - __classPrivateFieldSet(this, _AbstractPage_client, client); - this.options = options; - this.response = response; - this.body = body; - } - hasNextPage() { - const items = this.getPaginatedItems(); - if (!items.length) - return false; - return this.nextPageRequestOptions() != null; - } - async getNextPage() { - const nextOptions = this.nextPageRequestOptions(); - if (!nextOptions) { - throw new OpenAIError('No next page expected; please check `.hasNextPage()` before calling `.getNextPage()`.'); - } - return await __classPrivateFieldGet(this, _AbstractPage_client, "f").requestAPIList(this.constructor, nextOptions); - } - async *iterPages() { - let page = this; - yield page; - while (page.hasNextPage()) { - page = await page.getNextPage(); - yield page; - } - } - async *[(_AbstractPage_client = new WeakMap(), Symbol.asyncIterator)]() { - for await (const page of this.iterPages()) { - for (const item of page.getPaginatedItems()) { - yield item; - } - } - } -} -/** - * This subclass of Promise will resolve to an instantiated Page once the request completes. - * - * It also implements AsyncIterable to allow auto-paginating iteration on an unawaited list call, eg: - * - * for await (const item of client.items.list()) { - * console.log(item) - * } - */ -class PagePromise extends APIPromise { - constructor(client, request, Page) { - super(client, request, async (client, props) => new Page(client, props.response, await defaultParseResponse(client, props), props.options)); - } - /** - * Allow auto-paginating iteration on an unawaited list call, eg: - * - * for await (const item of client.items.list()) { - * console.log(item) - * } - */ - async *[Symbol.asyncIterator]() { - const page = await this; - for await (const item of page) { - yield item; - } - } -} -/** - * Note: no pagination actually occurs yet, this is for forwards-compatibility. - */ -class Page extends AbstractPage { - constructor(client, response, body, options) { - super(client, response, body, options); - this.data = body.data || []; - this.object = body.object; - } - getPaginatedItems() { - return this.data ?? []; - } - nextPageRequestOptions() { - return null; - } -} -class CursorPage extends AbstractPage { - constructor(client, response, body, options) { - super(client, response, body, options); - this.data = body.data || []; - this.has_more = body.has_more || false; - } - getPaginatedItems() { - return this.data ?? []; - } - hasNextPage() { - if (this.has_more === false) { - return false; - } - return super.hasNextPage(); - } - nextPageRequestOptions() { - const data = this.getPaginatedItems(); - const id = data[data.length - 1]?.id; - if (!id) { - return null; - } - return { - ...this.options, - query: { - ...maybeObj(this.options.query), - after: id, - }, - }; - } -} -class ConversationCursorPage extends AbstractPage { - constructor(client, response, body, options) { - super(client, response, body, options); - this.data = body.data || []; - this.has_more = body.has_more || false; - this.last_id = body.last_id || ''; - } - getPaginatedItems() { - return this.data ?? []; - } - hasNextPage() { - if (this.has_more === false) { - return false; - } - return super.hasNextPage(); - } - nextPageRequestOptions() { - const cursor = this.last_id; - if (!cursor) { - return null; - } - return { - ...this.options, - query: { - ...maybeObj(this.options.query), - after: cursor, - }, - }; - } -} - -const checkFileSupport = () => { - if (typeof File === 'undefined') { - const { process } = globalThis; - const isOldNode = typeof process?.versions?.node === 'string' && parseInt(process.versions.node.split('.')) < 20; - throw new Error('`File` is not defined as a global, which is required for file uploads.' + - (isOldNode ? - " Update to Node 20 LTS or newer, or set `globalThis.File` to `import('node:buffer').File`." - : '')); - } -}; -/** - * Construct a `File` instance. This is used to ensure a helpful error is thrown - * for environments that don't define a global `File` yet. - */ -function makeFile(fileBits, fileName, options) { - checkFileSupport(); - return new File(fileBits, fileName ?? 'unknown_file', options); -} -function getName(value) { - return (((typeof value === 'object' && - value !== null && - (('name' in value && value.name && String(value.name)) || - ('url' in value && value.url && String(value.url)) || - ('filename' in value && value.filename && String(value.filename)) || - ('path' in value && value.path && String(value.path)))) || - '') - .split(/[\\/]/) - .pop() || undefined); -} -const isAsyncIterable = (value) => value != null && typeof value === 'object' && typeof value[Symbol.asyncIterator] === 'function'; -const multipartFormRequestOptions = async (opts, fetch) => { - return { ...opts, body: await createForm(opts.body, fetch) }; -}; -const supportsFormDataMap = /* @__PURE__ */ new WeakMap(); -/** - * node-fetch doesn't support the global FormData object in recent node versions. Instead of sending - * properly-encoded form data, it just stringifies the object, resulting in a request body of "[object FormData]". - * This function detects if the fetch function provided supports the global FormData object to avoid - * confusing error messages later on. - */ -function supportsFormData(fetchObject) { - const fetch = typeof fetchObject === 'function' ? fetchObject : fetchObject.fetch; - const cached = supportsFormDataMap.get(fetch); - if (cached) - return cached; - const promise = (async () => { - try { - const FetchResponse = ('Response' in fetch ? - fetch.Response - : (await fetch('data:,')).constructor); - const data = new FormData(); - if (data.toString() === (await new FetchResponse(data).text())) { - return false; - } - return true; - } - catch { - // avoid false negatives - return true; - } - })(); - supportsFormDataMap.set(fetch, promise); - return promise; -} -const createForm = async (body, fetch) => { - if (!(await supportsFormData(fetch))) { - throw new TypeError('The provided fetch function does not support file uploads with the current global FormData class.'); - } - const form = new FormData(); - await Promise.all(Object.entries(body || {}).map(([key, value]) => addFormValue(form, key, value))); - return form; -}; -// We check for Blob not File because Bun.File doesn't inherit from File, -// but they both inherit from Blob and have a `name` property at runtime. -const isNamedBlob = (value) => value instanceof Blob && 'name' in value; -const addFormValue = async (form, key, value) => { - if (value === undefined) - return; - if (value == null) { - throw new TypeError(`Received null for "${key}"; to pass null in FormData, you must use the string 'null'`); - } - // TODO: make nested formats configurable - if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') { - form.append(key, String(value)); - } - else if (value instanceof Response) { - form.append(key, makeFile([await value.blob()], getName(value))); - } - else if (isAsyncIterable(value)) { - form.append(key, makeFile([await new Response(ReadableStreamFrom(value)).blob()], getName(value))); - } - else if (isNamedBlob(value)) { - form.append(key, value, getName(value)); - } - else if (Array.isArray(value)) { - await Promise.all(value.map((entry) => addFormValue(form, key + '[]', entry))); - } - else if (typeof value === 'object') { - await Promise.all(Object.entries(value).map(([name, prop]) => addFormValue(form, `${key}[${name}]`, prop))); - } - else { - throw new TypeError(`Invalid value given to form, expected a string, number, boolean, object, Array, File or Blob but got ${value} instead`); - } -}; - -/** - * This check adds the arrayBuffer() method type because it is available and used at runtime - */ -const isBlobLike = (value) => value != null && - typeof value === 'object' && - typeof value.size === 'number' && - typeof value.type === 'string' && - typeof value.text === 'function' && - typeof value.slice === 'function' && - typeof value.arrayBuffer === 'function'; -/** - * This check adds the arrayBuffer() method type because it is available and used at runtime - */ -const isFileLike = (value) => value != null && - typeof value === 'object' && - typeof value.name === 'string' && - typeof value.lastModified === 'number' && - isBlobLike(value); -const isResponseLike = (value) => value != null && - typeof value === 'object' && - typeof value.url === 'string' && - typeof value.blob === 'function'; -/** - * Helper for creating a {@link File} to pass to an SDK upload method from a variety of different data formats - * @param value the raw content of the file. Can be an {@link Uploadable}, {@link BlobLikePart}, or {@link AsyncIterable} of {@link BlobLikePart}s - * @param {string=} name the name of the file. If omitted, toFile will try to determine a file name from bits if possible - * @param {Object=} options additional properties - * @param {string=} options.type the MIME type of the content - * @param {number=} options.lastModified the last modified timestamp - * @returns a {@link File} with the given properties - */ -async function toFile(value, name, options) { - checkFileSupport(); - // If it's a promise, resolve it. - value = await value; - // If we've been given a `File` we don't need to do anything - if (isFileLike(value)) { - if (value instanceof File) { - return value; - } - return makeFile([await value.arrayBuffer()], value.name); - } - if (isResponseLike(value)) { - const blob = await value.blob(); - name || (name = new URL(value.url).pathname.split(/[\\/]/).pop()); - return makeFile(await getBytes(blob), name, options); - } - const parts = await getBytes(value); - name || (name = getName(value)); - if (!options?.type) { - const type = parts.find((part) => typeof part === 'object' && 'type' in part && part.type); - if (typeof type === 'string') { - options = { ...options, type }; - } - } - return makeFile(parts, name, options); -} -async function getBytes(value) { - let parts = []; - if (typeof value === 'string' || - ArrayBuffer.isView(value) || // includes Uint8Array, Buffer, etc. - value instanceof ArrayBuffer) { - parts.push(value); - } - else if (isBlobLike(value)) { - parts.push(value instanceof Blob ? value : await value.arrayBuffer()); - } - else if (isAsyncIterable(value) // includes Readable, ReadableStream, etc. - ) { - for await (const chunk of value) { - parts.push(...(await getBytes(chunk))); // TODO, consider validating? - } - } - else { - const constructor = value?.constructor?.name; - throw new Error(`Unexpected data type: ${typeof value}${constructor ? `; constructor: ${constructor}` : ''}${propsForError(value)}`); - } - return parts; -} -function propsForError(value) { - if (typeof value !== 'object' || value === null) - return ''; - const props = Object.getOwnPropertyNames(value); - return `; props: [${props.map((p) => `"${p}"`).join(', ')}]`; -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class APIResource { - constructor(client) { - this._client = client; - } -} - -/** - * Percent-encode everything that isn't safe to have in a path without encoding safe chars. - * - * Taken from https://datatracker.ietf.org/doc/html/rfc3986#section-3.3: - * > unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" - * > sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "=" - * > pchar = unreserved / pct-encoded / sub-delims / ":" / "@" - */ -function encodeURIPath(str) { - return str.replace(/[^A-Za-z0-9\-._~!$&'()*+,;=:@]+/g, encodeURIComponent); -} -const EMPTY = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.create(null)); -const createPathTagFunction = (pathEncoder = encodeURIPath) => function path(statics, ...params) { - // If there are no params, no processing is needed. - if (statics.length === 1) - return statics[0]; - let postPath = false; - const invalidSegments = []; - const path = statics.reduce((previousValue, currentValue, index) => { - if (/[?#]/.test(currentValue)) { - postPath = true; - } - const value = params[index]; - let encoded = (postPath ? encodeURIComponent : pathEncoder)('' + value); - if (index !== params.length && - (value == null || - (typeof value === 'object' && - // handle values from other realms - value.toString === - Object.getPrototypeOf(Object.getPrototypeOf(value.hasOwnProperty ?? EMPTY) ?? EMPTY) - ?.toString))) { - encoded = value + ''; - invalidSegments.push({ - start: previousValue.length + currentValue.length, - length: encoded.length, - error: `Value of type ${Object.prototype.toString - .call(value) - .slice(8, -1)} is not a valid path parameter`, - }); - } - return previousValue + currentValue + (index === params.length ? '' : encoded); - }, ''); - const pathOnly = path.split(/[?#]/, 1)[0]; - const invalidSegmentPattern = /(?<=^|\/)(?:\.|%2e){1,2}(?=\/|$)/gi; - let match; - // Find all invalid segments - while ((match = invalidSegmentPattern.exec(pathOnly)) !== null) { - invalidSegments.push({ - start: match.index, - length: match[0].length, - error: `Value "${match[0]}" can\'t be safely passed as a path parameter`, - }); - } - invalidSegments.sort((a, b) => a.start - b.start); - if (invalidSegments.length > 0) { - let lastEnd = 0; - const underline = invalidSegments.reduce((acc, segment) => { - const spaces = ' '.repeat(segment.start - lastEnd); - const arrows = '^'.repeat(segment.length); - lastEnd = segment.start + segment.length; - return acc + spaces + arrows; - }, ''); - throw new OpenAIError(`Path parameters result in path with invalid segments:\n${invalidSegments - .map((e) => e.error) - .join('\n')}\n${path}\n${underline}`); - } - return path; -}; -/** - * URI-encodes path params and ensures no unsafe /./ or /../ path segments are introduced. - */ -const path = /* @__PURE__ */ createPathTagFunction(encodeURIPath); - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -let Messages$1 = class Messages extends APIResource { - /** - * Get the messages in a stored chat completion. Only Chat Completions that have - * been created with the `store` parameter set to `true` will be returned. - * - * @example - * ```ts - * // Automatically fetches more pages as needed. - * for await (const chatCompletionStoreMessage of client.chat.completions.messages.list( - * 'completion_id', - * )) { - * // ... - * } - * ``` - */ - list(completionID, query = {}, options) { - return this._client.getAPIList(path `/chat/completions/${completionID}/messages`, (CursorPage), { query, ...options }); - } -}; - -function isChatCompletionFunctionTool(tool) { - return tool !== undefined && 'function' in tool && tool.function !== undefined; -} -function isAutoParsableResponseFormat(response_format) { - return response_format?.['$brand'] === 'auto-parseable-response-format'; -} -function isAutoParsableTool$1(tool) { - return tool?.['$brand'] === 'auto-parseable-tool'; -} -function maybeParseChatCompletion(completion, params) { - if (!params || !hasAutoParseableInput$1(params)) { - return { - ...completion, - choices: completion.choices.map((choice) => { - assertToolCallsAreChatCompletionFunctionToolCalls(choice.message.tool_calls); - return { - ...choice, - message: { - ...choice.message, - parsed: null, - ...(choice.message.tool_calls ? - { - tool_calls: choice.message.tool_calls, - } - : undefined), - }, - }; - }), - }; - } - return parseChatCompletion(completion, params); -} -function parseChatCompletion(completion, params) { - const choices = completion.choices.map((choice) => { - if (choice.finish_reason === 'length') { - throw new LengthFinishReasonError(); - } - if (choice.finish_reason === 'content_filter') { - throw new ContentFilterFinishReasonError(); - } - assertToolCallsAreChatCompletionFunctionToolCalls(choice.message.tool_calls); - return { - ...choice, - message: { - ...choice.message, - ...(choice.message.tool_calls ? - { - tool_calls: choice.message.tool_calls?.map((toolCall) => parseToolCall$1(params, toolCall)) ?? undefined, - } - : undefined), - parsed: choice.message.content && !choice.message.refusal ? - parseResponseFormat(params, choice.message.content) - : null, - }, - }; - }); - return { ...completion, choices }; -} -function parseResponseFormat(params, content) { - if (params.response_format?.type !== 'json_schema') { - return null; - } - if (params.response_format?.type === 'json_schema') { - if ('$parseRaw' in params.response_format) { - const response_format = params.response_format; - return response_format.$parseRaw(content); - } - return JSON.parse(content); - } - return null; -} -function parseToolCall$1(params, toolCall) { - const inputTool = params.tools?.find((inputTool) => isChatCompletionFunctionTool(inputTool) && inputTool.function?.name === toolCall.function.name); // TS doesn't narrow based on isChatCompletionTool - return { - ...toolCall, - function: { - ...toolCall.function, - parsed_arguments: isAutoParsableTool$1(inputTool) ? inputTool.$parseRaw(toolCall.function.arguments) - : inputTool?.function.strict ? JSON.parse(toolCall.function.arguments) - : null, - }, - }; -} -function shouldParseToolCall(params, toolCall) { - if (!params || !('tools' in params) || !params.tools) { - return false; - } - const inputTool = params.tools?.find((inputTool) => isChatCompletionFunctionTool(inputTool) && inputTool.function?.name === toolCall.function.name); - return (isChatCompletionFunctionTool(inputTool) && - (isAutoParsableTool$1(inputTool) || inputTool?.function.strict || false)); -} -function hasAutoParseableInput$1(params) { - if (isAutoParsableResponseFormat(params.response_format)) { - return true; - } - return (params.tools?.some((t) => isAutoParsableTool$1(t) || (t.type === 'function' && t.function.strict === true)) ?? false); -} -function assertToolCallsAreChatCompletionFunctionToolCalls(toolCalls) { - for (const toolCall of toolCalls || []) { - if (toolCall.type !== 'function') { - throw new OpenAIError(`Currently only \`function\` tool calls are supported; Received \`${toolCall.type}\``); - } - } -} -function validateInputTools(tools) { - for (const tool of tools ?? []) { - if (tool.type !== 'function') { - throw new OpenAIError(`Currently only \`function\` tool types support auto-parsing; Received \`${tool.type}\``); - } - if (tool.function.strict !== true) { - throw new OpenAIError(`The \`${tool.function.name}\` tool is not marked with \`strict: true\`. Only strict function tools can be auto-parsed`); - } - } -} - -const isAssistantMessage = (message) => { - return message?.role === 'assistant'; -}; -const isToolMessage = (message) => { - return message?.role === 'tool'; -}; - -var _EventStream_instances, _EventStream_connectedPromise, _EventStream_resolveConnectedPromise, _EventStream_rejectConnectedPromise, _EventStream_endPromise, _EventStream_resolveEndPromise, _EventStream_rejectEndPromise, _EventStream_listeners, _EventStream_ended, _EventStream_errored, _EventStream_aborted, _EventStream_catchingPromiseCreated, _EventStream_handleError; -class EventStream { - constructor() { - _EventStream_instances.add(this); - this.controller = new AbortController(); - _EventStream_connectedPromise.set(this, void 0); - _EventStream_resolveConnectedPromise.set(this, () => { }); - _EventStream_rejectConnectedPromise.set(this, () => { }); - _EventStream_endPromise.set(this, void 0); - _EventStream_resolveEndPromise.set(this, () => { }); - _EventStream_rejectEndPromise.set(this, () => { }); - _EventStream_listeners.set(this, {}); - _EventStream_ended.set(this, false); - _EventStream_errored.set(this, false); - _EventStream_aborted.set(this, false); - _EventStream_catchingPromiseCreated.set(this, false); - __classPrivateFieldSet(this, _EventStream_connectedPromise, new Promise((resolve, reject) => { - __classPrivateFieldSet(this, _EventStream_resolveConnectedPromise, resolve, "f"); - __classPrivateFieldSet(this, _EventStream_rejectConnectedPromise, reject, "f"); - })); - __classPrivateFieldSet(this, _EventStream_endPromise, new Promise((resolve, reject) => { - __classPrivateFieldSet(this, _EventStream_resolveEndPromise, resolve, "f"); - __classPrivateFieldSet(this, _EventStream_rejectEndPromise, reject, "f"); - })); - // Don't let these promises cause unhandled rejection errors. - // we will manually cause an unhandled rejection error later - // if the user hasn't registered any error listener or called - // any promise-returning method. - __classPrivateFieldGet(this, _EventStream_connectedPromise, "f").catch(() => { }); - __classPrivateFieldGet(this, _EventStream_endPromise, "f").catch(() => { }); - } - _run(executor) { - // Unfortunately if we call `executor()` immediately we get runtime errors about - // references to `this` before the `super()` constructor call returns. - setTimeout(() => { - executor().then(() => { - this._emitFinal(); - this._emit('end'); - }, __classPrivateFieldGet(this, _EventStream_instances, "m", _EventStream_handleError).bind(this)); - }, 0); - } - _connected() { - if (this.ended) - return; - __classPrivateFieldGet(this, _EventStream_resolveConnectedPromise, "f").call(this); - this._emit('connect'); - } - get ended() { - return __classPrivateFieldGet(this, _EventStream_ended, "f"); - } - get errored() { - return __classPrivateFieldGet(this, _EventStream_errored, "f"); - } - get aborted() { - return __classPrivateFieldGet(this, _EventStream_aborted, "f"); - } - abort() { - this.controller.abort(); - } - /** - * Adds the listener function to the end of the listeners array for the event. - * No checks are made to see if the listener has already been added. Multiple calls passing - * the same combination of event and listener will result in the listener being added, and - * called, multiple times. - * @returns this ChatCompletionStream, so that calls can be chained - */ - on(event, listener) { - const listeners = __classPrivateFieldGet(this, _EventStream_listeners, "f")[event] || (__classPrivateFieldGet(this, _EventStream_listeners, "f")[event] = []); - listeners.push({ listener }); - return this; - } - /** - * Removes the specified listener from the listener array for the event. - * off() will remove, at most, one instance of a listener from the listener array. If any single - * listener has been added multiple times to the listener array for the specified event, then - * off() must be called multiple times to remove each instance. - * @returns this ChatCompletionStream, so that calls can be chained - */ - off(event, listener) { - const listeners = __classPrivateFieldGet(this, _EventStream_listeners, "f")[event]; - if (!listeners) - return this; - const index = listeners.findIndex((l) => l.listener === listener); - if (index >= 0) - listeners.splice(index, 1); - return this; - } - /** - * Adds a one-time listener function for the event. The next time the event is triggered, - * this listener is removed and then invoked. - * @returns this ChatCompletionStream, so that calls can be chained - */ - once(event, listener) { - const listeners = __classPrivateFieldGet(this, _EventStream_listeners, "f")[event] || (__classPrivateFieldGet(this, _EventStream_listeners, "f")[event] = []); - listeners.push({ listener, once: true }); - return this; - } - /** - * This is similar to `.once()`, but returns a Promise that resolves the next time - * the event is triggered, instead of calling a listener callback. - * @returns a Promise that resolves the next time given event is triggered, - * or rejects if an error is emitted. (If you request the 'error' event, - * returns a promise that resolves with the error). - * - * Example: - * - * const message = await stream.emitted('message') // rejects if the stream errors - */ - emitted(event) { - return new Promise((resolve, reject) => { - __classPrivateFieldSet(this, _EventStream_catchingPromiseCreated, true); - if (event !== 'error') - this.once('error', reject); - this.once(event, resolve); - }); - } - async done() { - __classPrivateFieldSet(this, _EventStream_catchingPromiseCreated, true); - await __classPrivateFieldGet(this, _EventStream_endPromise, "f"); - } - _emit(event, ...args) { - // make sure we don't emit any events after end - if (__classPrivateFieldGet(this, _EventStream_ended, "f")) { - return; - } - if (event === 'end') { - __classPrivateFieldSet(this, _EventStream_ended, true); - __classPrivateFieldGet(this, _EventStream_resolveEndPromise, "f").call(this); - } - const listeners = __classPrivateFieldGet(this, _EventStream_listeners, "f")[event]; - if (listeners) { - __classPrivateFieldGet(this, _EventStream_listeners, "f")[event] = listeners.filter((l) => !l.once); - listeners.forEach(({ listener }) => listener(...args)); - } - if (event === 'abort') { - const error = args[0]; - if (!__classPrivateFieldGet(this, _EventStream_catchingPromiseCreated, "f") && !listeners?.length) { - Promise.reject(error); - } - __classPrivateFieldGet(this, _EventStream_rejectConnectedPromise, "f").call(this, error); - __classPrivateFieldGet(this, _EventStream_rejectEndPromise, "f").call(this, error); - this._emit('end'); - return; - } - if (event === 'error') { - // NOTE: _emit('error', error) should only be called from #handleError(). - const error = args[0]; - if (!__classPrivateFieldGet(this, _EventStream_catchingPromiseCreated, "f") && !listeners?.length) { - // Trigger an unhandled rejection if the user hasn't registered any error handlers. - // If you are seeing stack traces here, make sure to handle errors via either: - // - runner.on('error', () => ...) - // - await runner.done() - // - await runner.finalChatCompletion() - // - etc. - Promise.reject(error); - } - __classPrivateFieldGet(this, _EventStream_rejectConnectedPromise, "f").call(this, error); - __classPrivateFieldGet(this, _EventStream_rejectEndPromise, "f").call(this, error); - this._emit('end'); - } - } - _emitFinal() { } -} -_EventStream_connectedPromise = new WeakMap(), _EventStream_resolveConnectedPromise = new WeakMap(), _EventStream_rejectConnectedPromise = new WeakMap(), _EventStream_endPromise = new WeakMap(), _EventStream_resolveEndPromise = new WeakMap(), _EventStream_rejectEndPromise = new WeakMap(), _EventStream_listeners = new WeakMap(), _EventStream_ended = new WeakMap(), _EventStream_errored = new WeakMap(), _EventStream_aborted = new WeakMap(), _EventStream_catchingPromiseCreated = new WeakMap(), _EventStream_instances = new WeakSet(), _EventStream_handleError = function _EventStream_handleError(error) { - __classPrivateFieldSet(this, _EventStream_errored, true); - if (error instanceof Error && error.name === 'AbortError') { - error = new APIUserAbortError(); - } - if (error instanceof APIUserAbortError) { - __classPrivateFieldSet(this, _EventStream_aborted, true); - return this._emit('abort', error); - } - if (error instanceof OpenAIError) { - return this._emit('error', error); - } - if (error instanceof Error) { - const openAIError = new OpenAIError(error.message); - // @ts-ignore - openAIError.cause = error; - return this._emit('error', openAIError); - } - return this._emit('error', new OpenAIError(String(error))); -}; - -function isRunnableFunctionWithParse(fn) { - return typeof fn.parse === 'function'; -} - -var _AbstractChatCompletionRunner_instances, _AbstractChatCompletionRunner_getFinalContent, _AbstractChatCompletionRunner_getFinalMessage, _AbstractChatCompletionRunner_getFinalFunctionToolCall, _AbstractChatCompletionRunner_getFinalFunctionToolCallResult, _AbstractChatCompletionRunner_calculateTotalUsage, _AbstractChatCompletionRunner_validateParams, _AbstractChatCompletionRunner_stringifyFunctionCallResult; -const DEFAULT_MAX_CHAT_COMPLETIONS = 10; -class AbstractChatCompletionRunner extends EventStream { - constructor() { - super(...arguments); - _AbstractChatCompletionRunner_instances.add(this); - this._chatCompletions = []; - this.messages = []; - } - _addChatCompletion(chatCompletion) { - this._chatCompletions.push(chatCompletion); - this._emit('chatCompletion', chatCompletion); - const message = chatCompletion.choices[0]?.message; - if (message) - this._addMessage(message); - return chatCompletion; - } - _addMessage(message, emit = true) { - if (!('content' in message)) - message.content = null; - this.messages.push(message); - if (emit) { - this._emit('message', message); - if (isToolMessage(message) && message.content) { - // Note, this assumes that {role: 'tool', content: …} is always the result of a call of tool of type=function. - this._emit('functionToolCallResult', message.content); - } - else if (isAssistantMessage(message) && message.tool_calls) { - for (const tool_call of message.tool_calls) { - if (tool_call.type === 'function') { - this._emit('functionToolCall', tool_call.function); - } - } - } - } - } - /** - * @returns a promise that resolves with the final ChatCompletion, or rejects - * if an error occurred or the stream ended prematurely without producing a ChatCompletion. - */ - async finalChatCompletion() { - await this.done(); - const completion = this._chatCompletions[this._chatCompletions.length - 1]; - if (!completion) - throw new OpenAIError('stream ended without producing a ChatCompletion'); - return completion; - } - /** - * @returns a promise that resolves with the content of the final ChatCompletionMessage, or rejects - * if an error occurred or the stream ended prematurely without producing a ChatCompletionMessage. - */ - async finalContent() { - await this.done(); - return __classPrivateFieldGet(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalContent).call(this); - } - /** - * @returns a promise that resolves with the the final assistant ChatCompletionMessage response, - * or rejects if an error occurred or the stream ended prematurely without producing a ChatCompletionMessage. - */ - async finalMessage() { - await this.done(); - return __classPrivateFieldGet(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalMessage).call(this); - } - /** - * @returns a promise that resolves with the content of the final FunctionCall, or rejects - * if an error occurred or the stream ended prematurely without producing a ChatCompletionMessage. - */ - async finalFunctionToolCall() { - await this.done(); - return __classPrivateFieldGet(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalFunctionToolCall).call(this); - } - async finalFunctionToolCallResult() { - await this.done(); - return __classPrivateFieldGet(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalFunctionToolCallResult).call(this); - } - async totalUsage() { - await this.done(); - return __classPrivateFieldGet(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_calculateTotalUsage).call(this); - } - allChatCompletions() { - return [...this._chatCompletions]; - } - _emitFinal() { - const completion = this._chatCompletions[this._chatCompletions.length - 1]; - if (completion) - this._emit('finalChatCompletion', completion); - const finalMessage = __classPrivateFieldGet(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalMessage).call(this); - if (finalMessage) - this._emit('finalMessage', finalMessage); - const finalContent = __classPrivateFieldGet(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalContent).call(this); - if (finalContent) - this._emit('finalContent', finalContent); - const finalFunctionCall = __classPrivateFieldGet(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalFunctionToolCall).call(this); - if (finalFunctionCall) - this._emit('finalFunctionToolCall', finalFunctionCall); - const finalFunctionCallResult = __classPrivateFieldGet(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalFunctionToolCallResult).call(this); - if (finalFunctionCallResult != null) - this._emit('finalFunctionToolCallResult', finalFunctionCallResult); - if (this._chatCompletions.some((c) => c.usage)) { - this._emit('totalUsage', __classPrivateFieldGet(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_calculateTotalUsage).call(this)); - } - } - async _createChatCompletion(client, params, options) { - const signal = options?.signal; - if (signal) { - if (signal.aborted) - this.controller.abort(); - signal.addEventListener('abort', () => this.controller.abort()); - } - __classPrivateFieldGet(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_validateParams).call(this, params); - const chatCompletion = await client.chat.completions.create({ ...params, stream: false }, { ...options, signal: this.controller.signal }); - this._connected(); - return this._addChatCompletion(parseChatCompletion(chatCompletion, params)); - } - async _runChatCompletion(client, params, options) { - for (const message of params.messages) { - this._addMessage(message, false); - } - return await this._createChatCompletion(client, params, options); - } - async _runTools(client, params, options) { - const role = 'tool'; - const { tool_choice = 'auto', stream, ...restParams } = params; - const singleFunctionToCall = typeof tool_choice !== 'string' && tool_choice.type === 'function' && tool_choice?.function?.name; - const { maxChatCompletions = DEFAULT_MAX_CHAT_COMPLETIONS } = options || {}; - // TODO(someday): clean this logic up - const inputTools = params.tools.map((tool) => { - if (isAutoParsableTool$1(tool)) { - if (!tool.$callback) { - throw new OpenAIError('Tool given to `.runTools()` that does not have an associated function'); - } - return { - type: 'function', - function: { - function: tool.$callback, - name: tool.function.name, - description: tool.function.description || '', - parameters: tool.function.parameters, - parse: tool.$parseRaw, - strict: true, - }, - }; - } - return tool; - }); - const functionsByName = {}; - for (const f of inputTools) { - if (f.type === 'function') { - functionsByName[f.function.name || f.function.function.name] = f.function; - } - } - const tools = 'tools' in params ? - inputTools.map((t) => t.type === 'function' ? - { - type: 'function', - function: { - name: t.function.name || t.function.function.name, - parameters: t.function.parameters, - description: t.function.description, - strict: t.function.strict, - }, - } - : t) - : undefined; - for (const message of params.messages) { - this._addMessage(message, false); - } - for (let i = 0; i < maxChatCompletions; ++i) { - const chatCompletion = await this._createChatCompletion(client, { - ...restParams, - tool_choice, - tools, - messages: [...this.messages], - }, options); - const message = chatCompletion.choices[0]?.message; - if (!message) { - throw new OpenAIError(`missing message in ChatCompletion response`); - } - if (!message.tool_calls?.length) { - return; - } - for (const tool_call of message.tool_calls) { - if (tool_call.type !== 'function') - continue; - const tool_call_id = tool_call.id; - const { name, arguments: args } = tool_call.function; - const fn = functionsByName[name]; - if (!fn) { - const content = `Invalid tool_call: ${JSON.stringify(name)}. Available options are: ${Object.keys(functionsByName) - .map((name) => JSON.stringify(name)) - .join(', ')}. Please try again`; - this._addMessage({ role, tool_call_id, content }); - continue; - } - else if (singleFunctionToCall && singleFunctionToCall !== name) { - const content = `Invalid tool_call: ${JSON.stringify(name)}. ${JSON.stringify(singleFunctionToCall)} requested. Please try again`; - this._addMessage({ role, tool_call_id, content }); - continue; - } - let parsed; - try { - parsed = isRunnableFunctionWithParse(fn) ? await fn.parse(args) : args; - } - catch (error) { - const content = error instanceof Error ? error.message : String(error); - this._addMessage({ role, tool_call_id, content }); - continue; - } - // @ts-expect-error it can't rule out `never` type. - const rawContent = await fn.function(parsed, this); - const content = __classPrivateFieldGet(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_stringifyFunctionCallResult).call(this, rawContent); - this._addMessage({ role, tool_call_id, content }); - if (singleFunctionToCall) { - return; - } - } - } - return; - } -} -_AbstractChatCompletionRunner_instances = new WeakSet(), _AbstractChatCompletionRunner_getFinalContent = function _AbstractChatCompletionRunner_getFinalContent() { - return __classPrivateFieldGet(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalMessage).call(this).content ?? null; -}, _AbstractChatCompletionRunner_getFinalMessage = function _AbstractChatCompletionRunner_getFinalMessage() { - let i = this.messages.length; - while (i-- > 0) { - const message = this.messages[i]; - if (isAssistantMessage(message)) { - // TODO: support audio here - const ret = { - ...message, - content: message.content ?? null, - refusal: message.refusal ?? null, - }; - return ret; - } - } - throw new OpenAIError('stream ended without producing a ChatCompletionMessage with role=assistant'); -}, _AbstractChatCompletionRunner_getFinalFunctionToolCall = function _AbstractChatCompletionRunner_getFinalFunctionToolCall() { - for (let i = this.messages.length - 1; i >= 0; i--) { - const message = this.messages[i]; - if (isAssistantMessage(message) && message?.tool_calls?.length) { - return message.tool_calls.filter((x) => x.type === 'function').at(-1)?.function; - } - } - return; -}, _AbstractChatCompletionRunner_getFinalFunctionToolCallResult = function _AbstractChatCompletionRunner_getFinalFunctionToolCallResult() { - for (let i = this.messages.length - 1; i >= 0; i--) { - const message = this.messages[i]; - if (isToolMessage(message) && - message.content != null && - typeof message.content === 'string' && - this.messages.some((x) => x.role === 'assistant' && - x.tool_calls?.some((y) => y.type === 'function' && y.id === message.tool_call_id))) { - return message.content; - } - } - return; -}, _AbstractChatCompletionRunner_calculateTotalUsage = function _AbstractChatCompletionRunner_calculateTotalUsage() { - const total = { - completion_tokens: 0, - prompt_tokens: 0, - total_tokens: 0, - }; - for (const { usage } of this._chatCompletions) { - if (usage) { - total.completion_tokens += usage.completion_tokens; - total.prompt_tokens += usage.prompt_tokens; - total.total_tokens += usage.total_tokens; - } - } - return total; -}, _AbstractChatCompletionRunner_validateParams = function _AbstractChatCompletionRunner_validateParams(params) { - if (params.n != null && params.n > 1) { - throw new OpenAIError('ChatCompletion convenience helpers only support n=1 at this time. To use n>1, please use chat.completions.create() directly.'); - } -}, _AbstractChatCompletionRunner_stringifyFunctionCallResult = function _AbstractChatCompletionRunner_stringifyFunctionCallResult(rawContent) { - return (typeof rawContent === 'string' ? rawContent - : rawContent === undefined ? 'undefined' - : JSON.stringify(rawContent)); -}; - -class ChatCompletionRunner extends AbstractChatCompletionRunner { - static runTools(client, params, options) { - const runner = new ChatCompletionRunner(); - const opts = { - ...options, - headers: { ...options?.headers, 'X-Stainless-Helper-Method': 'runTools' }, - }; - runner._run(() => runner._runTools(client, params, opts)); - return runner; - } - _addMessage(message, emit = true) { - super._addMessage(message, emit); - if (isAssistantMessage(message) && message.content) { - this._emit('content', message.content); - } - } -} - -const STR = 0b000000001; -const NUM = 0b000000010; -const ARR = 0b000000100; -const OBJ = 0b000001000; -const NULL = 0b000010000; -const BOOL = 0b000100000; -const NAN = 0b001000000; -const INFINITY = 0b010000000; -const MINUS_INFINITY = 0b100000000; -const INF = INFINITY | MINUS_INFINITY; -const SPECIAL = NULL | BOOL | INF | NAN; -const ATOM = STR | NUM | SPECIAL; -const COLLECTION = ARR | OBJ; -const ALL = ATOM | COLLECTION; -const Allow = { - STR, - NUM, - ARR, - OBJ, - NULL, - BOOL, - NAN, - INFINITY, - MINUS_INFINITY, - INF, - SPECIAL, - ATOM, - COLLECTION, - ALL, -}; -// The JSON string segment was unable to be parsed completely -class PartialJSON extends Error { -} -class MalformedJSON extends Error { -} -/** - * Parse incomplete JSON - * @param {string} jsonString Partial JSON to be parsed - * @param {number} allowPartial Specify what types are allowed to be partial, see {@link Allow} for details - * @returns The parsed JSON - * @throws {PartialJSON} If the JSON is incomplete (related to the `allow` parameter) - * @throws {MalformedJSON} If the JSON is malformed - */ -function parseJSON(jsonString, allowPartial = Allow.ALL) { - if (typeof jsonString !== 'string') { - throw new TypeError(`expecting str, got ${typeof jsonString}`); - } - if (!jsonString.trim()) { - throw new Error(`${jsonString} is empty`); - } - return _parseJSON(jsonString.trim(), allowPartial); -} -const _parseJSON = (jsonString, allow) => { - const length = jsonString.length; - let index = 0; - const markPartialJSON = (msg) => { - throw new PartialJSON(`${msg} at position ${index}`); - }; - const throwMalformedError = (msg) => { - throw new MalformedJSON(`${msg} at position ${index}`); - }; - const parseAny = () => { - skipBlank(); - if (index >= length) - markPartialJSON('Unexpected end of input'); - if (jsonString[index] === '"') - return parseStr(); - if (jsonString[index] === '{') - return parseObj(); - if (jsonString[index] === '[') - return parseArr(); - if (jsonString.substring(index, index + 4) === 'null' || - (Allow.NULL & allow && length - index < 4 && 'null'.startsWith(jsonString.substring(index)))) { - index += 4; - return null; - } - if (jsonString.substring(index, index + 4) === 'true' || - (Allow.BOOL & allow && length - index < 4 && 'true'.startsWith(jsonString.substring(index)))) { - index += 4; - return true; - } - if (jsonString.substring(index, index + 5) === 'false' || - (Allow.BOOL & allow && length - index < 5 && 'false'.startsWith(jsonString.substring(index)))) { - index += 5; - return false; - } - if (jsonString.substring(index, index + 8) === 'Infinity' || - (Allow.INFINITY & allow && length - index < 8 && 'Infinity'.startsWith(jsonString.substring(index)))) { - index += 8; - return Infinity; - } - if (jsonString.substring(index, index + 9) === '-Infinity' || - (Allow.MINUS_INFINITY & allow && - 1 < length - index && - length - index < 9 && - '-Infinity'.startsWith(jsonString.substring(index)))) { - index += 9; - return -Infinity; - } - if (jsonString.substring(index, index + 3) === 'NaN' || - (Allow.NAN & allow && length - index < 3 && 'NaN'.startsWith(jsonString.substring(index)))) { - index += 3; - return NaN; - } - return parseNum(); - }; - const parseStr = () => { - const start = index; - let escape = false; - index++; // skip initial quote - while (index < length && (jsonString[index] !== '"' || (escape && jsonString[index - 1] === '\\'))) { - escape = jsonString[index] === '\\' ? !escape : false; - index++; - } - if (jsonString.charAt(index) == '"') { - try { - return JSON.parse(jsonString.substring(start, ++index - Number(escape))); - } - catch (e) { - throwMalformedError(String(e)); - } - } - else if (Allow.STR & allow) { - try { - return JSON.parse(jsonString.substring(start, index - Number(escape)) + '"'); - } - catch (e) { - // SyntaxError: Invalid escape sequence - return JSON.parse(jsonString.substring(start, jsonString.lastIndexOf('\\')) + '"'); - } - } - markPartialJSON('Unterminated string literal'); - }; - const parseObj = () => { - index++; // skip initial brace - skipBlank(); - const obj = {}; - try { - while (jsonString[index] !== '}') { - skipBlank(); - if (index >= length && Allow.OBJ & allow) - return obj; - const key = parseStr(); - skipBlank(); - index++; // skip colon - try { - const value = parseAny(); - Object.defineProperty(obj, key, { value, writable: true, enumerable: true, configurable: true }); - } - catch (e) { - if (Allow.OBJ & allow) - return obj; - else - throw e; - } - skipBlank(); - if (jsonString[index] === ',') - index++; // skip comma - } - } - catch (e) { - if (Allow.OBJ & allow) - return obj; - else - markPartialJSON("Expected '}' at end of object"); - } - index++; // skip final brace - return obj; - }; - const parseArr = () => { - index++; // skip initial bracket - const arr = []; - try { - while (jsonString[index] !== ']') { - arr.push(parseAny()); - skipBlank(); - if (jsonString[index] === ',') { - index++; // skip comma - } - } - } - catch (e) { - if (Allow.ARR & allow) { - return arr; - } - markPartialJSON("Expected ']' at end of array"); - } - index++; // skip final bracket - return arr; - }; - const parseNum = () => { - if (index === 0) { - if (jsonString === '-' && Allow.NUM & allow) - markPartialJSON("Not sure what '-' is"); - try { - return JSON.parse(jsonString); - } - catch (e) { - if (Allow.NUM & allow) { - try { - if ('.' === jsonString[jsonString.length - 1]) - return JSON.parse(jsonString.substring(0, jsonString.lastIndexOf('.'))); - return JSON.parse(jsonString.substring(0, jsonString.lastIndexOf('e'))); - } - catch (e) { } - } - throwMalformedError(String(e)); - } - } - const start = index; - if (jsonString[index] === '-') - index++; - while (jsonString[index] && !',]}'.includes(jsonString[index])) - index++; - if (index == length && !(Allow.NUM & allow)) - markPartialJSON('Unterminated number literal'); - try { - return JSON.parse(jsonString.substring(start, index)); - } - catch (e) { - if (jsonString.substring(start, index) === '-' && Allow.NUM & allow) - markPartialJSON("Not sure what '-' is"); - try { - return JSON.parse(jsonString.substring(start, jsonString.lastIndexOf('e'))); - } - catch (e) { - throwMalformedError(String(e)); - } - } - }; - const skipBlank = () => { - while (index < length && ' \n\r\t'.includes(jsonString[index])) { - index++; - } - }; - return parseAny(); -}; -// using this function with malformed JSON is undefined behavior -const partialParse = (input) => parseJSON(input, Allow.ALL ^ Allow.NUM); - -var _ChatCompletionStream_instances, _ChatCompletionStream_params, _ChatCompletionStream_choiceEventStates, _ChatCompletionStream_currentChatCompletionSnapshot, _ChatCompletionStream_beginRequest, _ChatCompletionStream_getChoiceEventState, _ChatCompletionStream_addChunk, _ChatCompletionStream_emitToolCallDoneEvent, _ChatCompletionStream_emitContentDoneEvents, _ChatCompletionStream_endRequest, _ChatCompletionStream_getAutoParseableResponseFormat, _ChatCompletionStream_accumulateChatCompletion; -class ChatCompletionStream extends AbstractChatCompletionRunner { - constructor(params) { - super(); - _ChatCompletionStream_instances.add(this); - _ChatCompletionStream_params.set(this, void 0); - _ChatCompletionStream_choiceEventStates.set(this, void 0); - _ChatCompletionStream_currentChatCompletionSnapshot.set(this, void 0); - __classPrivateFieldSet(this, _ChatCompletionStream_params, params); - __classPrivateFieldSet(this, _ChatCompletionStream_choiceEventStates, []); - } - get currentChatCompletionSnapshot() { - return __classPrivateFieldGet(this, _ChatCompletionStream_currentChatCompletionSnapshot, "f"); - } - /** - * Intended for use on the frontend, consuming a stream produced with - * `.toReadableStream()` on the backend. - * - * Note that messages sent to the model do not appear in `.on('message')` - * in this context. - */ - static fromReadableStream(stream) { - const runner = new ChatCompletionStream(null); - runner._run(() => runner._fromReadableStream(stream)); - return runner; - } - static createChatCompletion(client, params, options) { - const runner = new ChatCompletionStream(params); - runner._run(() => runner._runChatCompletion(client, { ...params, stream: true }, { ...options, headers: { ...options?.headers, 'X-Stainless-Helper-Method': 'stream' } })); - return runner; - } - async _createChatCompletion(client, params, options) { - super._createChatCompletion; - const signal = options?.signal; - if (signal) { - if (signal.aborted) - this.controller.abort(); - signal.addEventListener('abort', () => this.controller.abort()); - } - __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_beginRequest).call(this); - const stream = await client.chat.completions.create({ ...params, stream: true }, { ...options, signal: this.controller.signal }); - this._connected(); - for await (const chunk of stream) { - __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_addChunk).call(this, chunk); - } - if (stream.controller.signal?.aborted) { - throw new APIUserAbortError(); - } - return this._addChatCompletion(__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_endRequest).call(this)); - } - async _fromReadableStream(readableStream, options) { - const signal = options?.signal; - if (signal) { - if (signal.aborted) - this.controller.abort(); - signal.addEventListener('abort', () => this.controller.abort()); - } - __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_beginRequest).call(this); - this._connected(); - const stream = Stream.fromReadableStream(readableStream, this.controller); - let chatId; - for await (const chunk of stream) { - if (chatId && chatId !== chunk.id) { - // A new request has been made. - this._addChatCompletion(__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_endRequest).call(this)); - } - __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_addChunk).call(this, chunk); - chatId = chunk.id; - } - if (stream.controller.signal?.aborted) { - throw new APIUserAbortError(); - } - return this._addChatCompletion(__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_endRequest).call(this)); - } - [(_ChatCompletionStream_params = new WeakMap(), _ChatCompletionStream_choiceEventStates = new WeakMap(), _ChatCompletionStream_currentChatCompletionSnapshot = new WeakMap(), _ChatCompletionStream_instances = new WeakSet(), _ChatCompletionStream_beginRequest = function _ChatCompletionStream_beginRequest() { - if (this.ended) - return; - __classPrivateFieldSet(this, _ChatCompletionStream_currentChatCompletionSnapshot, undefined); - }, _ChatCompletionStream_getChoiceEventState = function _ChatCompletionStream_getChoiceEventState(choice) { - let state = __classPrivateFieldGet(this, _ChatCompletionStream_choiceEventStates, "f")[choice.index]; - if (state) { - return state; - } - state = { - content_done: false, - refusal_done: false, - logprobs_content_done: false, - logprobs_refusal_done: false, - done_tool_calls: new Set(), - current_tool_call_index: null, - }; - __classPrivateFieldGet(this, _ChatCompletionStream_choiceEventStates, "f")[choice.index] = state; - return state; - }, _ChatCompletionStream_addChunk = function _ChatCompletionStream_addChunk(chunk) { - if (this.ended) - return; - const completion = __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_accumulateChatCompletion).call(this, chunk); - this._emit('chunk', chunk, completion); - for (const choice of chunk.choices) { - const choiceSnapshot = completion.choices[choice.index]; - if (choice.delta.content != null && - choiceSnapshot.message?.role === 'assistant' && - choiceSnapshot.message?.content) { - this._emit('content', choice.delta.content, choiceSnapshot.message.content); - this._emit('content.delta', { - delta: choice.delta.content, - snapshot: choiceSnapshot.message.content, - parsed: choiceSnapshot.message.parsed, - }); - } - if (choice.delta.refusal != null && - choiceSnapshot.message?.role === 'assistant' && - choiceSnapshot.message?.refusal) { - this._emit('refusal.delta', { - delta: choice.delta.refusal, - snapshot: choiceSnapshot.message.refusal, - }); - } - if (choice.logprobs?.content != null && choiceSnapshot.message?.role === 'assistant') { - this._emit('logprobs.content.delta', { - content: choice.logprobs?.content, - snapshot: choiceSnapshot.logprobs?.content ?? [], - }); - } - if (choice.logprobs?.refusal != null && choiceSnapshot.message?.role === 'assistant') { - this._emit('logprobs.refusal.delta', { - refusal: choice.logprobs?.refusal, - snapshot: choiceSnapshot.logprobs?.refusal ?? [], - }); - } - const state = __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getChoiceEventState).call(this, choiceSnapshot); - if (choiceSnapshot.finish_reason) { - __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_emitContentDoneEvents).call(this, choiceSnapshot); - if (state.current_tool_call_index != null) { - __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_emitToolCallDoneEvent).call(this, choiceSnapshot, state.current_tool_call_index); - } - } - for (const toolCall of choice.delta.tool_calls ?? []) { - if (state.current_tool_call_index !== toolCall.index) { - __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_emitContentDoneEvents).call(this, choiceSnapshot); - // new tool call started, the previous one is done - if (state.current_tool_call_index != null) { - __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_emitToolCallDoneEvent).call(this, choiceSnapshot, state.current_tool_call_index); - } - } - state.current_tool_call_index = toolCall.index; - } - for (const toolCallDelta of choice.delta.tool_calls ?? []) { - const toolCallSnapshot = choiceSnapshot.message.tool_calls?.[toolCallDelta.index]; - if (!toolCallSnapshot?.type) { - continue; - } - if (toolCallSnapshot?.type === 'function') { - this._emit('tool_calls.function.arguments.delta', { - name: toolCallSnapshot.function?.name, - index: toolCallDelta.index, - arguments: toolCallSnapshot.function.arguments, - parsed_arguments: toolCallSnapshot.function.parsed_arguments, - arguments_delta: toolCallDelta.function?.arguments ?? '', - }); - } - else { - assertNever(toolCallSnapshot?.type); - } - } - } - }, _ChatCompletionStream_emitToolCallDoneEvent = function _ChatCompletionStream_emitToolCallDoneEvent(choiceSnapshot, toolCallIndex) { - const state = __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getChoiceEventState).call(this, choiceSnapshot); - if (state.done_tool_calls.has(toolCallIndex)) { - // we've already fired the done event - return; - } - const toolCallSnapshot = choiceSnapshot.message.tool_calls?.[toolCallIndex]; - if (!toolCallSnapshot) { - throw new Error('no tool call snapshot'); - } - if (!toolCallSnapshot.type) { - throw new Error('tool call snapshot missing `type`'); - } - if (toolCallSnapshot.type === 'function') { - const inputTool = __classPrivateFieldGet(this, _ChatCompletionStream_params, "f")?.tools?.find((tool) => isChatCompletionFunctionTool(tool) && tool.function.name === toolCallSnapshot.function.name); // TS doesn't narrow based on isChatCompletionTool - this._emit('tool_calls.function.arguments.done', { - name: toolCallSnapshot.function.name, - index: toolCallIndex, - arguments: toolCallSnapshot.function.arguments, - parsed_arguments: isAutoParsableTool$1(inputTool) ? inputTool.$parseRaw(toolCallSnapshot.function.arguments) - : inputTool?.function.strict ? JSON.parse(toolCallSnapshot.function.arguments) - : null, - }); - } - else { - assertNever(toolCallSnapshot.type); - } - }, _ChatCompletionStream_emitContentDoneEvents = function _ChatCompletionStream_emitContentDoneEvents(choiceSnapshot) { - const state = __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getChoiceEventState).call(this, choiceSnapshot); - if (choiceSnapshot.message.content && !state.content_done) { - state.content_done = true; - const responseFormat = __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getAutoParseableResponseFormat).call(this); - this._emit('content.done', { - content: choiceSnapshot.message.content, - parsed: responseFormat ? responseFormat.$parseRaw(choiceSnapshot.message.content) : null, - }); - } - if (choiceSnapshot.message.refusal && !state.refusal_done) { - state.refusal_done = true; - this._emit('refusal.done', { refusal: choiceSnapshot.message.refusal }); - } - if (choiceSnapshot.logprobs?.content && !state.logprobs_content_done) { - state.logprobs_content_done = true; - this._emit('logprobs.content.done', { content: choiceSnapshot.logprobs.content }); - } - if (choiceSnapshot.logprobs?.refusal && !state.logprobs_refusal_done) { - state.logprobs_refusal_done = true; - this._emit('logprobs.refusal.done', { refusal: choiceSnapshot.logprobs.refusal }); - } - }, _ChatCompletionStream_endRequest = function _ChatCompletionStream_endRequest() { - if (this.ended) { - throw new OpenAIError(`stream has ended, this shouldn't happen`); - } - const snapshot = __classPrivateFieldGet(this, _ChatCompletionStream_currentChatCompletionSnapshot, "f"); - if (!snapshot) { - throw new OpenAIError(`request ended without sending any chunks`); - } - __classPrivateFieldSet(this, _ChatCompletionStream_currentChatCompletionSnapshot, undefined); - __classPrivateFieldSet(this, _ChatCompletionStream_choiceEventStates, []); - return finalizeChatCompletion(snapshot, __classPrivateFieldGet(this, _ChatCompletionStream_params, "f")); - }, _ChatCompletionStream_getAutoParseableResponseFormat = function _ChatCompletionStream_getAutoParseableResponseFormat() { - const responseFormat = __classPrivateFieldGet(this, _ChatCompletionStream_params, "f")?.response_format; - if (isAutoParsableResponseFormat(responseFormat)) { - return responseFormat; - } - return null; - }, _ChatCompletionStream_accumulateChatCompletion = function _ChatCompletionStream_accumulateChatCompletion(chunk) { - var _a, _b, _c, _d; - let snapshot = __classPrivateFieldGet(this, _ChatCompletionStream_currentChatCompletionSnapshot, "f"); - const { choices, ...rest } = chunk; - if (!snapshot) { - snapshot = __classPrivateFieldSet(this, _ChatCompletionStream_currentChatCompletionSnapshot, { - ...rest, - choices: [], - }); - } - else { - Object.assign(snapshot, rest); - } - for (const { delta, finish_reason, index, logprobs = null, ...other } of chunk.choices) { - let choice = snapshot.choices[index]; - if (!choice) { - choice = snapshot.choices[index] = { finish_reason, index, message: {}, logprobs, ...other }; - } - if (logprobs) { - if (!choice.logprobs) { - choice.logprobs = Object.assign({}, logprobs); - } - else { - const { content, refusal, ...rest } = logprobs; - Object.assign(choice.logprobs, rest); - if (content) { - (_a = choice.logprobs).content ?? (_a.content = []); - choice.logprobs.content.push(...content); - } - if (refusal) { - (_b = choice.logprobs).refusal ?? (_b.refusal = []); - choice.logprobs.refusal.push(...refusal); - } - } - } - if (finish_reason) { - choice.finish_reason = finish_reason; - if (__classPrivateFieldGet(this, _ChatCompletionStream_params, "f") && hasAutoParseableInput$1(__classPrivateFieldGet(this, _ChatCompletionStream_params, "f"))) { - if (finish_reason === 'length') { - throw new LengthFinishReasonError(); - } - if (finish_reason === 'content_filter') { - throw new ContentFilterFinishReasonError(); - } - } - } - Object.assign(choice, other); - if (!delta) - continue; // Shouldn't happen; just in case. - const { content, refusal, function_call, role, tool_calls, ...rest } = delta; - Object.assign(choice.message, rest); - if (refusal) { - choice.message.refusal = (choice.message.refusal || '') + refusal; - } - if (role) - choice.message.role = role; - if (function_call) { - if (!choice.message.function_call) { - choice.message.function_call = function_call; - } - else { - if (function_call.name) - choice.message.function_call.name = function_call.name; - if (function_call.arguments) { - (_c = choice.message.function_call).arguments ?? (_c.arguments = ''); - choice.message.function_call.arguments += function_call.arguments; - } - } - } - if (content) { - choice.message.content = (choice.message.content || '') + content; - if (!choice.message.refusal && __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getAutoParseableResponseFormat).call(this)) { - choice.message.parsed = partialParse(choice.message.content); - } - } - if (tool_calls) { - if (!choice.message.tool_calls) - choice.message.tool_calls = []; - for (const { index, id, type, function: fn, ...rest } of tool_calls) { - const tool_call = ((_d = choice.message.tool_calls)[index] ?? (_d[index] = {})); - Object.assign(tool_call, rest); - if (id) - tool_call.id = id; - if (type) - tool_call.type = type; - if (fn) - tool_call.function ?? (tool_call.function = { name: fn.name ?? '', arguments: '' }); - if (fn?.name) - tool_call.function.name = fn.name; - if (fn?.arguments) { - tool_call.function.arguments += fn.arguments; - if (shouldParseToolCall(__classPrivateFieldGet(this, _ChatCompletionStream_params, "f"), tool_call)) { - tool_call.function.parsed_arguments = partialParse(tool_call.function.arguments); - } - } - } - } - } - return snapshot; - }, Symbol.asyncIterator)]() { - const pushQueue = []; - const readQueue = []; - let done = false; - this.on('chunk', (chunk) => { - const reader = readQueue.shift(); - if (reader) { - reader.resolve(chunk); - } - else { - pushQueue.push(chunk); - } - }); - this.on('end', () => { - done = true; - for (const reader of readQueue) { - reader.resolve(undefined); - } - readQueue.length = 0; - }); - this.on('abort', (err) => { - done = true; - for (const reader of readQueue) { - reader.reject(err); - } - readQueue.length = 0; - }); - this.on('error', (err) => { - done = true; - for (const reader of readQueue) { - reader.reject(err); - } - readQueue.length = 0; - }); - return { - next: async () => { - if (!pushQueue.length) { - if (done) { - return { value: undefined, done: true }; - } - return new Promise((resolve, reject) => readQueue.push({ resolve, reject })).then((chunk) => (chunk ? { value: chunk, done: false } : { value: undefined, done: true })); - } - const chunk = pushQueue.shift(); - return { value: chunk, done: false }; - }, - return: async () => { - this.abort(); - return { value: undefined, done: true }; - }, - }; - } - toReadableStream() { - const stream = new Stream(this[Symbol.asyncIterator].bind(this), this.controller); - return stream.toReadableStream(); - } -} -function finalizeChatCompletion(snapshot, params) { - const { id, choices, created, model, system_fingerprint, ...rest } = snapshot; - const completion = { - ...rest, - id, - choices: choices.map(({ message, finish_reason, index, logprobs, ...choiceRest }) => { - if (!finish_reason) { - throw new OpenAIError(`missing finish_reason for choice ${index}`); - } - const { content = null, function_call, tool_calls, ...messageRest } = message; - const role = message.role; // this is what we expect; in theory it could be different which would make our types a slight lie but would be fine. - if (!role) { - throw new OpenAIError(`missing role for choice ${index}`); - } - if (function_call) { - const { arguments: args, name } = function_call; - if (args == null) { - throw new OpenAIError(`missing function_call.arguments for choice ${index}`); - } - if (!name) { - throw new OpenAIError(`missing function_call.name for choice ${index}`); - } - return { - ...choiceRest, - message: { - content, - function_call: { arguments: args, name }, - role, - refusal: message.refusal ?? null, - }, - finish_reason, - index, - logprobs, - }; - } - if (tool_calls) { - return { - ...choiceRest, - index, - finish_reason, - logprobs, - message: { - ...messageRest, - role, - content, - refusal: message.refusal ?? null, - tool_calls: tool_calls.map((tool_call, i) => { - const { function: fn, type, id, ...toolRest } = tool_call; - const { arguments: args, name, ...fnRest } = fn || {}; - if (id == null) { - throw new OpenAIError(`missing choices[${index}].tool_calls[${i}].id\n${str(snapshot)}`); - } - if (type == null) { - throw new OpenAIError(`missing choices[${index}].tool_calls[${i}].type\n${str(snapshot)}`); - } - if (name == null) { - throw new OpenAIError(`missing choices[${index}].tool_calls[${i}].function.name\n${str(snapshot)}`); - } - if (args == null) { - throw new OpenAIError(`missing choices[${index}].tool_calls[${i}].function.arguments\n${str(snapshot)}`); - } - return { ...toolRest, id, type, function: { ...fnRest, name, arguments: args } }; - }), - }, - }; - } - return { - ...choiceRest, - message: { ...messageRest, content, role, refusal: message.refusal ?? null }, - finish_reason, - index, - logprobs, - }; - }), - created, - model, - object: 'chat.completion', - ...(system_fingerprint ? { system_fingerprint } : {}), - }; - return maybeParseChatCompletion(completion, params); -} -function str(x) { - return JSON.stringify(x); -} -function assertNever(_x) { } - -class ChatCompletionStreamingRunner extends ChatCompletionStream { - static fromReadableStream(stream) { - const runner = new ChatCompletionStreamingRunner(null); - runner._run(() => runner._fromReadableStream(stream)); - return runner; - } - static runTools(client, params, options) { - const runner = new ChatCompletionStreamingRunner( - // @ts-expect-error TODO these types are incompatible - params); - const opts = { - ...options, - headers: { ...options?.headers, 'X-Stainless-Helper-Method': 'runTools' }, - }; - runner._run(() => runner._runTools(client, params, opts)); - return runner; - } -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -let Completions$1 = class Completions extends APIResource { - constructor() { - super(...arguments); - this.messages = new Messages$1(this._client); - } - create(body, options) { - return this._client.post('/chat/completions', { body, ...options, stream: body.stream ?? false }); - } - /** - * Get a stored chat completion. Only Chat Completions that have been created with - * the `store` parameter set to `true` will be returned. - * - * @example - * ```ts - * const chatCompletion = - * await client.chat.completions.retrieve('completion_id'); - * ``` - */ - retrieve(completionID, options) { - return this._client.get(path `/chat/completions/${completionID}`, options); - } - /** - * Modify a stored chat completion. Only Chat Completions that have been created - * with the `store` parameter set to `true` can be modified. Currently, the only - * supported modification is to update the `metadata` field. - * - * @example - * ```ts - * const chatCompletion = await client.chat.completions.update( - * 'completion_id', - * { metadata: { foo: 'string' } }, - * ); - * ``` - */ - update(completionID, body, options) { - return this._client.post(path `/chat/completions/${completionID}`, { body, ...options }); - } - /** - * List stored Chat Completions. Only Chat Completions that have been stored with - * the `store` parameter set to `true` will be returned. - * - * @example - * ```ts - * // Automatically fetches more pages as needed. - * for await (const chatCompletion of client.chat.completions.list()) { - * // ... - * } - * ``` - */ - list(query = {}, options) { - return this._client.getAPIList('/chat/completions', (CursorPage), { query, ...options }); - } - /** - * Delete a stored chat completion. Only Chat Completions that have been created - * with the `store` parameter set to `true` can be deleted. - * - * @example - * ```ts - * const chatCompletionDeleted = - * await client.chat.completions.delete('completion_id'); - * ``` - */ - delete(completionID, options) { - return this._client.delete(path `/chat/completions/${completionID}`, options); - } - parse(body, options) { - validateInputTools(body.tools); - return this._client.chat.completions - .create(body, { - ...options, - headers: { - ...options?.headers, - 'X-Stainless-Helper-Method': 'chat.completions.parse', - }, - }) - ._thenUnwrap((completion) => parseChatCompletion(completion, body)); - } - runTools(body, options) { - if (body.stream) { - return ChatCompletionStreamingRunner.runTools(this._client, body, options); - } - return ChatCompletionRunner.runTools(this._client, body, options); - } - /** - * Creates a chat completion stream - */ - stream(body, options) { - return ChatCompletionStream.createChatCompletion(this._client, body, options); - } -}; -Completions$1.Messages = Messages$1; - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Chat extends APIResource { - constructor() { - super(...arguments); - this.completions = new Completions$1(this._client); - } -} -Chat.Completions = Completions$1; - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -const brand_privateNullableHeaders = /* @__PURE__ */ Symbol('brand.privateNullableHeaders'); -function* iterateHeaders(headers) { - if (!headers) - return; - if (brand_privateNullableHeaders in headers) { - const { values, nulls } = headers; - yield* values.entries(); - for (const name of nulls) { - yield [name, null]; - } - return; - } - let shouldClear = false; - let iter; - if (headers instanceof Headers) { - iter = headers.entries(); - } - else if (isReadonlyArray(headers)) { - iter = headers; - } - else { - shouldClear = true; - iter = Object.entries(headers ?? {}); - } - for (let row of iter) { - const name = row[0]; - if (typeof name !== 'string') - throw new TypeError('expected header name to be a string'); - const values = isReadonlyArray(row[1]) ? row[1] : [row[1]]; - let didClear = false; - for (const value of values) { - if (value === undefined) - continue; - // Objects keys always overwrite older headers, they never append. - // Yield a null to clear the header before adding the new values. - if (shouldClear && !didClear) { - didClear = true; - yield [name, null]; - } - yield [name, value]; - } - } -} -const buildHeaders = (newHeaders) => { - const targetHeaders = new Headers(); - const nullHeaders = new Set(); - for (const headers of newHeaders) { - const seenHeaders = new Set(); - for (const [name, value] of iterateHeaders(headers)) { - const lowerName = name.toLowerCase(); - if (!seenHeaders.has(lowerName)) { - targetHeaders.delete(name); - seenHeaders.add(lowerName); - } - if (value === null) { - targetHeaders.delete(name); - nullHeaders.add(lowerName); - } - else { - targetHeaders.append(name, value); - nullHeaders.delete(lowerName); - } - } - } - return { [brand_privateNullableHeaders]: true, values: targetHeaders, nulls: nullHeaders }; -}; - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Speech extends APIResource { - /** - * Generates audio from the input text. - * - * @example - * ```ts - * const speech = await client.audio.speech.create({ - * input: 'input', - * model: 'string', - * voice: 'ash', - * }); - * - * const content = await speech.blob(); - * console.log(content); - * ``` - */ - create(body, options) { - return this._client.post('/audio/speech', { - body, - ...options, - headers: buildHeaders([{ Accept: 'application/octet-stream' }, options?.headers]), - __binaryResponse: true, - }); - } -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Transcriptions extends APIResource { - create(body, options) { - return this._client.post('/audio/transcriptions', multipartFormRequestOptions({ - body, - ...options, - stream: body.stream ?? false, - __metadata: { model: body.model }, - }, this._client)); - } -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Translations extends APIResource { - create(body, options) { - return this._client.post('/audio/translations', multipartFormRequestOptions({ body, ...options, __metadata: { model: body.model } }, this._client)); - } -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Audio extends APIResource { - constructor() { - super(...arguments); - this.transcriptions = new Transcriptions(this._client); - this.translations = new Translations(this._client); - this.speech = new Speech(this._client); - } -} -Audio.Transcriptions = Transcriptions; -Audio.Translations = Translations; -Audio.Speech = Speech; - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Batches extends APIResource { - /** - * Creates and executes a batch from an uploaded file of requests - */ - create(body, options) { - return this._client.post('/batches', { body, ...options }); - } - /** - * Retrieves a batch. - */ - retrieve(batchID, options) { - return this._client.get(path `/batches/${batchID}`, options); - } - /** - * List your organization's batches. - */ - list(query = {}, options) { - return this._client.getAPIList('/batches', (CursorPage), { query, ...options }); - } - /** - * Cancels an in-progress batch. The batch will be in status `cancelling` for up to - * 10 minutes, before changing to `cancelled`, where it will have partial results - * (if any) available in the output file. - */ - cancel(batchID, options) { - return this._client.post(path `/batches/${batchID}/cancel`, options); - } -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Assistants extends APIResource { - /** - * Create an assistant with a model and instructions. - * - * @example - * ```ts - * const assistant = await client.beta.assistants.create({ - * model: 'gpt-4o', - * }); - * ``` - */ - create(body, options) { - return this._client.post('/assistants', { - body, - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } - /** - * Retrieves an assistant. - * - * @example - * ```ts - * const assistant = await client.beta.assistants.retrieve( - * 'assistant_id', - * ); - * ``` - */ - retrieve(assistantID, options) { - return this._client.get(path `/assistants/${assistantID}`, { - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } - /** - * Modifies an assistant. - * - * @example - * ```ts - * const assistant = await client.beta.assistants.update( - * 'assistant_id', - * ); - * ``` - */ - update(assistantID, body, options) { - return this._client.post(path `/assistants/${assistantID}`, { - body, - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } - /** - * Returns a list of assistants. - * - * @example - * ```ts - * // Automatically fetches more pages as needed. - * for await (const assistant of client.beta.assistants.list()) { - * // ... - * } - * ``` - */ - list(query = {}, options) { - return this._client.getAPIList('/assistants', (CursorPage), { - query, - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } - /** - * Delete an assistant. - * - * @example - * ```ts - * const assistantDeleted = - * await client.beta.assistants.delete('assistant_id'); - * ``` - */ - delete(assistantID, options) { - return this._client.delete(path `/assistants/${assistantID}`, { - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Sessions extends APIResource { - /** - * Create an ephemeral API token for use in client-side applications with the - * Realtime API. Can be configured with the same session parameters as the - * `session.update` client event. - * - * It responds with a session object, plus a `client_secret` key which contains a - * usable ephemeral API token that can be used to authenticate browser clients for - * the Realtime API. - * - * @example - * ```ts - * const session = - * await client.beta.realtime.sessions.create(); - * ``` - */ - create(body, options) { - return this._client.post('/realtime/sessions', { - body, - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class TranscriptionSessions extends APIResource { - /** - * Create an ephemeral API token for use in client-side applications with the - * Realtime API specifically for realtime transcriptions. Can be configured with - * the same session parameters as the `transcription_session.update` client event. - * - * It responds with a session object, plus a `client_secret` key which contains a - * usable ephemeral API token that can be used to authenticate browser clients for - * the Realtime API. - * - * @example - * ```ts - * const transcriptionSession = - * await client.beta.realtime.transcriptionSessions.create(); - * ``` - */ - create(body, options) { - return this._client.post('/realtime/transcription_sessions', { - body, - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -/** - * @deprecated Realtime has now launched and is generally available. The old beta API is now deprecated. - */ -let Realtime$1 = class Realtime extends APIResource { - constructor() { - super(...arguments); - this.sessions = new Sessions(this._client); - this.transcriptionSessions = new TranscriptionSessions(this._client); - } -}; -Realtime$1.Sessions = Sessions; -Realtime$1.TranscriptionSessions = TranscriptionSessions; - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -/** - * @deprecated The Assistants API is deprecated in favor of the Responses API - */ -class Messages extends APIResource { - /** - * Create a message. - * - * @deprecated The Assistants API is deprecated in favor of the Responses API - */ - create(threadID, body, options) { - return this._client.post(path `/threads/${threadID}/messages`, { - body, - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } - /** - * Retrieve a message. - * - * @deprecated The Assistants API is deprecated in favor of the Responses API - */ - retrieve(messageID, params, options) { - const { thread_id } = params; - return this._client.get(path `/threads/${thread_id}/messages/${messageID}`, { - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } - /** - * Modifies a message. - * - * @deprecated The Assistants API is deprecated in favor of the Responses API - */ - update(messageID, params, options) { - const { thread_id, ...body } = params; - return this._client.post(path `/threads/${thread_id}/messages/${messageID}`, { - body, - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } - /** - * Returns a list of messages for a given thread. - * - * @deprecated The Assistants API is deprecated in favor of the Responses API - */ - list(threadID, query = {}, options) { - return this._client.getAPIList(path `/threads/${threadID}/messages`, (CursorPage), { - query, - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } - /** - * Deletes a message. - * - * @deprecated The Assistants API is deprecated in favor of the Responses API - */ - delete(messageID, params, options) { - const { thread_id } = params; - return this._client.delete(path `/threads/${thread_id}/messages/${messageID}`, { - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -/** - * @deprecated The Assistants API is deprecated in favor of the Responses API - */ -class Steps extends APIResource { - /** - * Retrieves a run step. - * - * @deprecated The Assistants API is deprecated in favor of the Responses API - */ - retrieve(stepID, params, options) { - const { thread_id, run_id, ...query } = params; - return this._client.get(path `/threads/${thread_id}/runs/${run_id}/steps/${stepID}`, { - query, - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } - /** - * Returns a list of run steps belonging to a run. - * - * @deprecated The Assistants API is deprecated in favor of the Responses API - */ - list(runID, params, options) { - const { thread_id, ...query } = params; - return this._client.getAPIList(path `/threads/${thread_id}/runs/${runID}/steps`, (CursorPage), { - query, - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -/** - * Converts a Base64 encoded string to a Float32Array. - * @param base64Str - The Base64 encoded string. - * @returns An Array of numbers interpreted as Float32 values. - */ -const toFloat32Array = (base64Str) => { - if (typeof Buffer !== 'undefined') { - // for Node.js environment - const buf = Buffer.from(base64Str, 'base64'); - return Array.from(new Float32Array(buf.buffer, buf.byteOffset, buf.length / Float32Array.BYTES_PER_ELEMENT)); - } - else { - // for legacy web platform APIs - const binaryStr = atob(base64Str); - const len = binaryStr.length; - const bytes = new Uint8Array(len); - for (let i = 0; i < len; i++) { - bytes[i] = binaryStr.charCodeAt(i); - } - return Array.from(new Float32Array(bytes.buffer)); - } -}; - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -/** - * Read an environment variable. - * - * Trims beginning and trailing whitespace. - * - * Will return undefined if the environment variable doesn't exist or cannot be accessed. - */ -const readEnv = (env) => { - if (typeof globalThis.process !== 'undefined') { - return globalThis.process.env?.[env]?.trim() ?? undefined; - } - if (typeof globalThis.Deno !== 'undefined') { - return globalThis.Deno.env?.get?.(env)?.trim(); - } - return undefined; -}; - -var _AssistantStream_instances, _a$1, _AssistantStream_events, _AssistantStream_runStepSnapshots, _AssistantStream_messageSnapshots, _AssistantStream_messageSnapshot, _AssistantStream_finalRun, _AssistantStream_currentContentIndex, _AssistantStream_currentContent, _AssistantStream_currentToolCallIndex, _AssistantStream_currentToolCall, _AssistantStream_currentEvent, _AssistantStream_currentRunSnapshot, _AssistantStream_currentRunStepSnapshot, _AssistantStream_addEvent, _AssistantStream_endRequest, _AssistantStream_handleMessage, _AssistantStream_handleRunStep, _AssistantStream_handleEvent, _AssistantStream_accumulateRunStep, _AssistantStream_accumulateMessage, _AssistantStream_accumulateContent, _AssistantStream_handleRun; -class AssistantStream extends EventStream { - constructor() { - super(...arguments); - _AssistantStream_instances.add(this); - //Track all events in a single list for reference - _AssistantStream_events.set(this, []); - //Used to accumulate deltas - //We are accumulating many types so the value here is not strict - _AssistantStream_runStepSnapshots.set(this, {}); - _AssistantStream_messageSnapshots.set(this, {}); - _AssistantStream_messageSnapshot.set(this, void 0); - _AssistantStream_finalRun.set(this, void 0); - _AssistantStream_currentContentIndex.set(this, void 0); - _AssistantStream_currentContent.set(this, void 0); - _AssistantStream_currentToolCallIndex.set(this, void 0); - _AssistantStream_currentToolCall.set(this, void 0); - //For current snapshot methods - _AssistantStream_currentEvent.set(this, void 0); - _AssistantStream_currentRunSnapshot.set(this, void 0); - _AssistantStream_currentRunStepSnapshot.set(this, void 0); - } - [(_AssistantStream_events = new WeakMap(), _AssistantStream_runStepSnapshots = new WeakMap(), _AssistantStream_messageSnapshots = new WeakMap(), _AssistantStream_messageSnapshot = new WeakMap(), _AssistantStream_finalRun = new WeakMap(), _AssistantStream_currentContentIndex = new WeakMap(), _AssistantStream_currentContent = new WeakMap(), _AssistantStream_currentToolCallIndex = new WeakMap(), _AssistantStream_currentToolCall = new WeakMap(), _AssistantStream_currentEvent = new WeakMap(), _AssistantStream_currentRunSnapshot = new WeakMap(), _AssistantStream_currentRunStepSnapshot = new WeakMap(), _AssistantStream_instances = new WeakSet(), Symbol.asyncIterator)]() { - const pushQueue = []; - const readQueue = []; - let done = false; - //Catch all for passing along all events - this.on('event', (event) => { - const reader = readQueue.shift(); - if (reader) { - reader.resolve(event); - } - else { - pushQueue.push(event); - } - }); - this.on('end', () => { - done = true; - for (const reader of readQueue) { - reader.resolve(undefined); - } - readQueue.length = 0; - }); - this.on('abort', (err) => { - done = true; - for (const reader of readQueue) { - reader.reject(err); - } - readQueue.length = 0; - }); - this.on('error', (err) => { - done = true; - for (const reader of readQueue) { - reader.reject(err); - } - readQueue.length = 0; - }); - return { - next: async () => { - if (!pushQueue.length) { - if (done) { - return { value: undefined, done: true }; - } - return new Promise((resolve, reject) => readQueue.push({ resolve, reject })).then((chunk) => (chunk ? { value: chunk, done: false } : { value: undefined, done: true })); - } - const chunk = pushQueue.shift(); - return { value: chunk, done: false }; - }, - return: async () => { - this.abort(); - return { value: undefined, done: true }; - }, - }; - } - static fromReadableStream(stream) { - const runner = new _a$1(); - runner._run(() => runner._fromReadableStream(stream)); - return runner; - } - async _fromReadableStream(readableStream, options) { - const signal = options?.signal; - if (signal) { - if (signal.aborted) - this.controller.abort(); - signal.addEventListener('abort', () => this.controller.abort()); - } - this._connected(); - const stream = Stream.fromReadableStream(readableStream, this.controller); - for await (const event of stream) { - __classPrivateFieldGet(this, _AssistantStream_instances, "m", _AssistantStream_addEvent).call(this, event); - } - if (stream.controller.signal?.aborted) { - throw new APIUserAbortError(); - } - return this._addRun(__classPrivateFieldGet(this, _AssistantStream_instances, "m", _AssistantStream_endRequest).call(this)); - } - toReadableStream() { - const stream = new Stream(this[Symbol.asyncIterator].bind(this), this.controller); - return stream.toReadableStream(); - } - static createToolAssistantStream(runId, runs, params, options) { - const runner = new _a$1(); - runner._run(() => runner._runToolAssistantStream(runId, runs, params, { - ...options, - headers: { ...options?.headers, 'X-Stainless-Helper-Method': 'stream' }, - })); - return runner; - } - async _createToolAssistantStream(run, runId, params, options) { - const signal = options?.signal; - if (signal) { - if (signal.aborted) - this.controller.abort(); - signal.addEventListener('abort', () => this.controller.abort()); - } - const body = { ...params, stream: true }; - const stream = await run.submitToolOutputs(runId, body, { - ...options, - signal: this.controller.signal, - }); - this._connected(); - for await (const event of stream) { - __classPrivateFieldGet(this, _AssistantStream_instances, "m", _AssistantStream_addEvent).call(this, event); - } - if (stream.controller.signal?.aborted) { - throw new APIUserAbortError(); - } - return this._addRun(__classPrivateFieldGet(this, _AssistantStream_instances, "m", _AssistantStream_endRequest).call(this)); - } - static createThreadAssistantStream(params, thread, options) { - const runner = new _a$1(); - runner._run(() => runner._threadAssistantStream(params, thread, { - ...options, - headers: { ...options?.headers, 'X-Stainless-Helper-Method': 'stream' }, - })); - return runner; - } - static createAssistantStream(threadId, runs, params, options) { - const runner = new _a$1(); - runner._run(() => runner._runAssistantStream(threadId, runs, params, { - ...options, - headers: { ...options?.headers, 'X-Stainless-Helper-Method': 'stream' }, - })); - return runner; - } - currentEvent() { - return __classPrivateFieldGet(this, _AssistantStream_currentEvent, "f"); - } - currentRun() { - return __classPrivateFieldGet(this, _AssistantStream_currentRunSnapshot, "f"); - } - currentMessageSnapshot() { - return __classPrivateFieldGet(this, _AssistantStream_messageSnapshot, "f"); - } - currentRunStepSnapshot() { - return __classPrivateFieldGet(this, _AssistantStream_currentRunStepSnapshot, "f"); - } - async finalRunSteps() { - await this.done(); - return Object.values(__classPrivateFieldGet(this, _AssistantStream_runStepSnapshots, "f")); - } - async finalMessages() { - await this.done(); - return Object.values(__classPrivateFieldGet(this, _AssistantStream_messageSnapshots, "f")); - } - async finalRun() { - await this.done(); - if (!__classPrivateFieldGet(this, _AssistantStream_finalRun, "f")) - throw Error('Final run was not received.'); - return __classPrivateFieldGet(this, _AssistantStream_finalRun, "f"); - } - async _createThreadAssistantStream(thread, params, options) { - const signal = options?.signal; - if (signal) { - if (signal.aborted) - this.controller.abort(); - signal.addEventListener('abort', () => this.controller.abort()); - } - const body = { ...params, stream: true }; - const stream = await thread.createAndRun(body, { ...options, signal: this.controller.signal }); - this._connected(); - for await (const event of stream) { - __classPrivateFieldGet(this, _AssistantStream_instances, "m", _AssistantStream_addEvent).call(this, event); - } - if (stream.controller.signal?.aborted) { - throw new APIUserAbortError(); - } - return this._addRun(__classPrivateFieldGet(this, _AssistantStream_instances, "m", _AssistantStream_endRequest).call(this)); - } - async _createAssistantStream(run, threadId, params, options) { - const signal = options?.signal; - if (signal) { - if (signal.aborted) - this.controller.abort(); - signal.addEventListener('abort', () => this.controller.abort()); - } - const body = { ...params, stream: true }; - const stream = await run.create(threadId, body, { ...options, signal: this.controller.signal }); - this._connected(); - for await (const event of stream) { - __classPrivateFieldGet(this, _AssistantStream_instances, "m", _AssistantStream_addEvent).call(this, event); - } - if (stream.controller.signal?.aborted) { - throw new APIUserAbortError(); - } - return this._addRun(__classPrivateFieldGet(this, _AssistantStream_instances, "m", _AssistantStream_endRequest).call(this)); - } - static accumulateDelta(acc, delta) { - for (const [key, deltaValue] of Object.entries(delta)) { - if (!acc.hasOwnProperty(key)) { - acc[key] = deltaValue; - continue; - } - let accValue = acc[key]; - if (accValue === null || accValue === undefined) { - acc[key] = deltaValue; - continue; - } - // We don't accumulate these special properties - if (key === 'index' || key === 'type') { - acc[key] = deltaValue; - continue; - } - // Type-specific accumulation logic - if (typeof accValue === 'string' && typeof deltaValue === 'string') { - accValue += deltaValue; - } - else if (typeof accValue === 'number' && typeof deltaValue === 'number') { - accValue += deltaValue; - } - else if (isObj(accValue) && isObj(deltaValue)) { - accValue = this.accumulateDelta(accValue, deltaValue); - } - else if (Array.isArray(accValue) && Array.isArray(deltaValue)) { - if (accValue.every((x) => typeof x === 'string' || typeof x === 'number')) { - accValue.push(...deltaValue); // Use spread syntax for efficient addition - continue; - } - for (const deltaEntry of deltaValue) { - if (!isObj(deltaEntry)) { - throw new Error(`Expected array delta entry to be an object but got: ${deltaEntry}`); - } - const index = deltaEntry['index']; - if (index == null) { - console.error(deltaEntry); - throw new Error('Expected array delta entry to have an `index` property'); - } - if (typeof index !== 'number') { - throw new Error(`Expected array delta entry \`index\` property to be a number but got ${index}`); - } - const accEntry = accValue[index]; - if (accEntry == null) { - accValue.push(deltaEntry); - } - else { - accValue[index] = this.accumulateDelta(accEntry, deltaEntry); - } - } - continue; - } - else { - throw Error(`Unhandled record type: ${key}, deltaValue: ${deltaValue}, accValue: ${accValue}`); - } - acc[key] = accValue; - } - return acc; - } - _addRun(run) { - return run; - } - async _threadAssistantStream(params, thread, options) { - return await this._createThreadAssistantStream(thread, params, options); - } - async _runAssistantStream(threadId, runs, params, options) { - return await this._createAssistantStream(runs, threadId, params, options); - } - async _runToolAssistantStream(runId, runs, params, options) { - return await this._createToolAssistantStream(runs, runId, params, options); - } -} -_a$1 = AssistantStream, _AssistantStream_addEvent = function _AssistantStream_addEvent(event) { - if (this.ended) - return; - __classPrivateFieldSet(this, _AssistantStream_currentEvent, event); - __classPrivateFieldGet(this, _AssistantStream_instances, "m", _AssistantStream_handleEvent).call(this, event); - switch (event.event) { - case 'thread.created': - //No action on this event. - break; - case 'thread.run.created': - case 'thread.run.queued': - case 'thread.run.in_progress': - case 'thread.run.requires_action': - case 'thread.run.completed': - case 'thread.run.incomplete': - case 'thread.run.failed': - case 'thread.run.cancelling': - case 'thread.run.cancelled': - case 'thread.run.expired': - __classPrivateFieldGet(this, _AssistantStream_instances, "m", _AssistantStream_handleRun).call(this, event); - break; - case 'thread.run.step.created': - case 'thread.run.step.in_progress': - case 'thread.run.step.delta': - case 'thread.run.step.completed': - case 'thread.run.step.failed': - case 'thread.run.step.cancelled': - case 'thread.run.step.expired': - __classPrivateFieldGet(this, _AssistantStream_instances, "m", _AssistantStream_handleRunStep).call(this, event); - break; - case 'thread.message.created': - case 'thread.message.in_progress': - case 'thread.message.delta': - case 'thread.message.completed': - case 'thread.message.incomplete': - __classPrivateFieldGet(this, _AssistantStream_instances, "m", _AssistantStream_handleMessage).call(this, event); - break; - case 'error': - //This is included for completeness, but errors are processed in the SSE event processing so this should not occur - throw new Error('Encountered an error event in event processing - errors should be processed earlier'); - } -}, _AssistantStream_endRequest = function _AssistantStream_endRequest() { - if (this.ended) { - throw new OpenAIError(`stream has ended, this shouldn't happen`); - } - if (!__classPrivateFieldGet(this, _AssistantStream_finalRun, "f")) - throw Error('Final run has not been received'); - return __classPrivateFieldGet(this, _AssistantStream_finalRun, "f"); -}, _AssistantStream_handleMessage = function _AssistantStream_handleMessage(event) { - const [accumulatedMessage, newContent] = __classPrivateFieldGet(this, _AssistantStream_instances, "m", _AssistantStream_accumulateMessage).call(this, event, __classPrivateFieldGet(this, _AssistantStream_messageSnapshot, "f")); - __classPrivateFieldSet(this, _AssistantStream_messageSnapshot, accumulatedMessage); - __classPrivateFieldGet(this, _AssistantStream_messageSnapshots, "f")[accumulatedMessage.id] = accumulatedMessage; - for (const content of newContent) { - const snapshotContent = accumulatedMessage.content[content.index]; - if (snapshotContent?.type == 'text') { - this._emit('textCreated', snapshotContent.text); - } - } - switch (event.event) { - case 'thread.message.created': - this._emit('messageCreated', event.data); - break; - case 'thread.message.in_progress': - break; - case 'thread.message.delta': - this._emit('messageDelta', event.data.delta, accumulatedMessage); - if (event.data.delta.content) { - for (const content of event.data.delta.content) { - //If it is text delta, emit a text delta event - if (content.type == 'text' && content.text) { - let textDelta = content.text; - let snapshot = accumulatedMessage.content[content.index]; - if (snapshot && snapshot.type == 'text') { - this._emit('textDelta', textDelta, snapshot.text); - } - else { - throw Error('The snapshot associated with this text delta is not text or missing'); - } - } - if (content.index != __classPrivateFieldGet(this, _AssistantStream_currentContentIndex, "f")) { - //See if we have in progress content - if (__classPrivateFieldGet(this, _AssistantStream_currentContent, "f")) { - switch (__classPrivateFieldGet(this, _AssistantStream_currentContent, "f").type) { - case 'text': - this._emit('textDone', __classPrivateFieldGet(this, _AssistantStream_currentContent, "f").text, __classPrivateFieldGet(this, _AssistantStream_messageSnapshot, "f")); - break; - case 'image_file': - this._emit('imageFileDone', __classPrivateFieldGet(this, _AssistantStream_currentContent, "f").image_file, __classPrivateFieldGet(this, _AssistantStream_messageSnapshot, "f")); - break; - } - } - __classPrivateFieldSet(this, _AssistantStream_currentContentIndex, content.index); - } - __classPrivateFieldSet(this, _AssistantStream_currentContent, accumulatedMessage.content[content.index]); - } - } - break; - case 'thread.message.completed': - case 'thread.message.incomplete': - //We emit the latest content we were working on on completion (including incomplete) - if (__classPrivateFieldGet(this, _AssistantStream_currentContentIndex, "f") !== undefined) { - const currentContent = event.data.content[__classPrivateFieldGet(this, _AssistantStream_currentContentIndex, "f")]; - if (currentContent) { - switch (currentContent.type) { - case 'image_file': - this._emit('imageFileDone', currentContent.image_file, __classPrivateFieldGet(this, _AssistantStream_messageSnapshot, "f")); - break; - case 'text': - this._emit('textDone', currentContent.text, __classPrivateFieldGet(this, _AssistantStream_messageSnapshot, "f")); - break; - } - } - } - if (__classPrivateFieldGet(this, _AssistantStream_messageSnapshot, "f")) { - this._emit('messageDone', event.data); - } - __classPrivateFieldSet(this, _AssistantStream_messageSnapshot, undefined); - } -}, _AssistantStream_handleRunStep = function _AssistantStream_handleRunStep(event) { - const accumulatedRunStep = __classPrivateFieldGet(this, _AssistantStream_instances, "m", _AssistantStream_accumulateRunStep).call(this, event); - __classPrivateFieldSet(this, _AssistantStream_currentRunStepSnapshot, accumulatedRunStep); - switch (event.event) { - case 'thread.run.step.created': - this._emit('runStepCreated', event.data); - break; - case 'thread.run.step.delta': - const delta = event.data.delta; - if (delta.step_details && - delta.step_details.type == 'tool_calls' && - delta.step_details.tool_calls && - accumulatedRunStep.step_details.type == 'tool_calls') { - for (const toolCall of delta.step_details.tool_calls) { - if (toolCall.index == __classPrivateFieldGet(this, _AssistantStream_currentToolCallIndex, "f")) { - this._emit('toolCallDelta', toolCall, accumulatedRunStep.step_details.tool_calls[toolCall.index]); - } - else { - if (__classPrivateFieldGet(this, _AssistantStream_currentToolCall, "f")) { - this._emit('toolCallDone', __classPrivateFieldGet(this, _AssistantStream_currentToolCall, "f")); - } - __classPrivateFieldSet(this, _AssistantStream_currentToolCallIndex, toolCall.index); - __classPrivateFieldSet(this, _AssistantStream_currentToolCall, accumulatedRunStep.step_details.tool_calls[toolCall.index]); - if (__classPrivateFieldGet(this, _AssistantStream_currentToolCall, "f")) - this._emit('toolCallCreated', __classPrivateFieldGet(this, _AssistantStream_currentToolCall, "f")); - } - } - } - this._emit('runStepDelta', event.data.delta, accumulatedRunStep); - break; - case 'thread.run.step.completed': - case 'thread.run.step.failed': - case 'thread.run.step.cancelled': - case 'thread.run.step.expired': - __classPrivateFieldSet(this, _AssistantStream_currentRunStepSnapshot, undefined); - const details = event.data.step_details; - if (details.type == 'tool_calls') { - if (__classPrivateFieldGet(this, _AssistantStream_currentToolCall, "f")) { - this._emit('toolCallDone', __classPrivateFieldGet(this, _AssistantStream_currentToolCall, "f")); - __classPrivateFieldSet(this, _AssistantStream_currentToolCall, undefined); - } - } - this._emit('runStepDone', event.data, accumulatedRunStep); - break; - } -}, _AssistantStream_handleEvent = function _AssistantStream_handleEvent(event) { - __classPrivateFieldGet(this, _AssistantStream_events, "f").push(event); - this._emit('event', event); -}, _AssistantStream_accumulateRunStep = function _AssistantStream_accumulateRunStep(event) { - switch (event.event) { - case 'thread.run.step.created': - __classPrivateFieldGet(this, _AssistantStream_runStepSnapshots, "f")[event.data.id] = event.data; - return event.data; - case 'thread.run.step.delta': - let snapshot = __classPrivateFieldGet(this, _AssistantStream_runStepSnapshots, "f")[event.data.id]; - if (!snapshot) { - throw Error('Received a RunStepDelta before creation of a snapshot'); - } - let data = event.data; - if (data.delta) { - const accumulated = _a$1.accumulateDelta(snapshot, data.delta); - __classPrivateFieldGet(this, _AssistantStream_runStepSnapshots, "f")[event.data.id] = accumulated; - } - return __classPrivateFieldGet(this, _AssistantStream_runStepSnapshots, "f")[event.data.id]; - case 'thread.run.step.completed': - case 'thread.run.step.failed': - case 'thread.run.step.cancelled': - case 'thread.run.step.expired': - case 'thread.run.step.in_progress': - __classPrivateFieldGet(this, _AssistantStream_runStepSnapshots, "f")[event.data.id] = event.data; - break; - } - if (__classPrivateFieldGet(this, _AssistantStream_runStepSnapshots, "f")[event.data.id]) - return __classPrivateFieldGet(this, _AssistantStream_runStepSnapshots, "f")[event.data.id]; - throw new Error('No snapshot available'); -}, _AssistantStream_accumulateMessage = function _AssistantStream_accumulateMessage(event, snapshot) { - let newContent = []; - switch (event.event) { - case 'thread.message.created': - //On creation the snapshot is just the initial message - return [event.data, newContent]; - case 'thread.message.delta': - if (!snapshot) { - throw Error('Received a delta with no existing snapshot (there should be one from message creation)'); - } - let data = event.data; - //If this delta does not have content, nothing to process - if (data.delta.content) { - for (const contentElement of data.delta.content) { - if (contentElement.index in snapshot.content) { - let currentContent = snapshot.content[contentElement.index]; - snapshot.content[contentElement.index] = __classPrivateFieldGet(this, _AssistantStream_instances, "m", _AssistantStream_accumulateContent).call(this, contentElement, currentContent); - } - else { - snapshot.content[contentElement.index] = contentElement; - // This is a new element - newContent.push(contentElement); - } - } - } - return [snapshot, newContent]; - case 'thread.message.in_progress': - case 'thread.message.completed': - case 'thread.message.incomplete': - //No changes on other thread events - if (snapshot) { - return [snapshot, newContent]; - } - else { - throw Error('Received thread message event with no existing snapshot'); - } - } - throw Error('Tried to accumulate a non-message event'); -}, _AssistantStream_accumulateContent = function _AssistantStream_accumulateContent(contentElement, currentContent) { - return _a$1.accumulateDelta(currentContent, contentElement); -}, _AssistantStream_handleRun = function _AssistantStream_handleRun(event) { - __classPrivateFieldSet(this, _AssistantStream_currentRunSnapshot, event.data); - switch (event.event) { - case 'thread.run.created': - break; - case 'thread.run.queued': - break; - case 'thread.run.in_progress': - break; - case 'thread.run.requires_action': - case 'thread.run.cancelled': - case 'thread.run.failed': - case 'thread.run.completed': - case 'thread.run.expired': - case 'thread.run.incomplete': - __classPrivateFieldSet(this, _AssistantStream_finalRun, event.data); - if (__classPrivateFieldGet(this, _AssistantStream_currentToolCall, "f")) { - this._emit('toolCallDone', __classPrivateFieldGet(this, _AssistantStream_currentToolCall, "f")); - __classPrivateFieldSet(this, _AssistantStream_currentToolCall, undefined); - } - break; - } -}; - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -/** - * @deprecated The Assistants API is deprecated in favor of the Responses API - */ -let Runs$1 = class Runs extends APIResource { - constructor() { - super(...arguments); - this.steps = new Steps(this._client); - } - create(threadID, params, options) { - const { include, ...body } = params; - return this._client.post(path `/threads/${threadID}/runs`, { - query: { include }, - body, - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - stream: params.stream ?? false, - }); - } - /** - * Retrieves a run. - * - * @deprecated The Assistants API is deprecated in favor of the Responses API - */ - retrieve(runID, params, options) { - const { thread_id } = params; - return this._client.get(path `/threads/${thread_id}/runs/${runID}`, { - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } - /** - * Modifies a run. - * - * @deprecated The Assistants API is deprecated in favor of the Responses API - */ - update(runID, params, options) { - const { thread_id, ...body } = params; - return this._client.post(path `/threads/${thread_id}/runs/${runID}`, { - body, - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } - /** - * Returns a list of runs belonging to a thread. - * - * @deprecated The Assistants API is deprecated in favor of the Responses API - */ - list(threadID, query = {}, options) { - return this._client.getAPIList(path `/threads/${threadID}/runs`, (CursorPage), { - query, - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } - /** - * Cancels a run that is `in_progress`. - * - * @deprecated The Assistants API is deprecated in favor of the Responses API - */ - cancel(runID, params, options) { - const { thread_id } = params; - return this._client.post(path `/threads/${thread_id}/runs/${runID}/cancel`, { - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } - /** - * A helper to create a run an poll for a terminal state. More information on Run - * lifecycles can be found here: - * https://platform.openai.com/docs/assistants/how-it-works/runs-and-run-steps - */ - async createAndPoll(threadId, body, options) { - const run = await this.create(threadId, body, options); - return await this.poll(run.id, { thread_id: threadId }, options); - } - /** - * Create a Run stream - * - * @deprecated use `stream` instead - */ - createAndStream(threadId, body, options) { - return AssistantStream.createAssistantStream(threadId, this._client.beta.threads.runs, body, options); - } - /** - * A helper to poll a run status until it reaches a terminal state. More - * information on Run lifecycles can be found here: - * https://platform.openai.com/docs/assistants/how-it-works/runs-and-run-steps - */ - async poll(runId, params, options) { - const headers = buildHeaders([ - options?.headers, - { - 'X-Stainless-Poll-Helper': 'true', - 'X-Stainless-Custom-Poll-Interval': options?.pollIntervalMs?.toString() ?? undefined, - }, - ]); - while (true) { - const { data: run, response } = await this.retrieve(runId, params, { - ...options, - headers: { ...options?.headers, ...headers }, - }).withResponse(); - switch (run.status) { - //If we are in any sort of intermediate state we poll - case 'queued': - case 'in_progress': - case 'cancelling': - let sleepInterval = 5000; - if (options?.pollIntervalMs) { - sleepInterval = options.pollIntervalMs; - } - else { - const headerInterval = response.headers.get('openai-poll-after-ms'); - if (headerInterval) { - const headerIntervalMs = parseInt(headerInterval); - if (!isNaN(headerIntervalMs)) { - sleepInterval = headerIntervalMs; - } - } - } - await sleep(sleepInterval); - break; - //We return the run in any terminal state. - case 'requires_action': - case 'incomplete': - case 'cancelled': - case 'completed': - case 'failed': - case 'expired': - return run; - } - } - } - /** - * Create a Run stream - */ - stream(threadId, body, options) { - return AssistantStream.createAssistantStream(threadId, this._client.beta.threads.runs, body, options); - } - submitToolOutputs(runID, params, options) { - const { thread_id, ...body } = params; - return this._client.post(path `/threads/${thread_id}/runs/${runID}/submit_tool_outputs`, { - body, - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - stream: params.stream ?? false, - }); - } - /** - * A helper to submit a tool output to a run and poll for a terminal run state. - * More information on Run lifecycles can be found here: - * https://platform.openai.com/docs/assistants/how-it-works/runs-and-run-steps - */ - async submitToolOutputsAndPoll(runId, params, options) { - const run = await this.submitToolOutputs(runId, params, options); - return await this.poll(run.id, params, options); - } - /** - * Submit the tool outputs from a previous run and stream the run to a terminal - * state. More information on Run lifecycles can be found here: - * https://platform.openai.com/docs/assistants/how-it-works/runs-and-run-steps - */ - submitToolOutputsStream(runId, params, options) { - return AssistantStream.createToolAssistantStream(runId, this._client.beta.threads.runs, params, options); - } -}; -Runs$1.Steps = Steps; - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -/** - * @deprecated The Assistants API is deprecated in favor of the Responses API - */ -class Threads extends APIResource { - constructor() { - super(...arguments); - this.runs = new Runs$1(this._client); - this.messages = new Messages(this._client); - } - /** - * Create a thread. - * - * @deprecated The Assistants API is deprecated in favor of the Responses API - */ - create(body = {}, options) { - return this._client.post('/threads', { - body, - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } - /** - * Retrieves a thread. - * - * @deprecated The Assistants API is deprecated in favor of the Responses API - */ - retrieve(threadID, options) { - return this._client.get(path `/threads/${threadID}`, { - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } - /** - * Modifies a thread. - * - * @deprecated The Assistants API is deprecated in favor of the Responses API - */ - update(threadID, body, options) { - return this._client.post(path `/threads/${threadID}`, { - body, - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } - /** - * Delete a thread. - * - * @deprecated The Assistants API is deprecated in favor of the Responses API - */ - delete(threadID, options) { - return this._client.delete(path `/threads/${threadID}`, { - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } - createAndRun(body, options) { - return this._client.post('/threads/runs', { - body, - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - stream: body.stream ?? false, - }); - } - /** - * A helper to create a thread, start a run and then poll for a terminal state. - * More information on Run lifecycles can be found here: - * https://platform.openai.com/docs/assistants/how-it-works/runs-and-run-steps - */ - async createAndRunPoll(body, options) { - const run = await this.createAndRun(body, options); - return await this.runs.poll(run.id, { thread_id: run.thread_id }, options); - } - /** - * Create a thread and stream the run back - */ - createAndRunStream(body, options) { - return AssistantStream.createThreadAssistantStream(body, this._client.beta.threads, options); - } -} -Threads.Runs = Runs$1; -Threads.Messages = Messages; - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Beta extends APIResource { - constructor() { - super(...arguments); - this.realtime = new Realtime$1(this._client); - this.assistants = new Assistants(this._client); - this.threads = new Threads(this._client); - } -} -Beta.Realtime = Realtime$1; -Beta.Assistants = Assistants; -Beta.Threads = Threads; - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Completions extends APIResource { - create(body, options) { - return this._client.post('/completions', { body, ...options, stream: body.stream ?? false }); - } -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Content extends APIResource { - /** - * Retrieve Container File Content - */ - retrieve(fileID, params, options) { - const { container_id } = params; - return this._client.get(path `/containers/${container_id}/files/${fileID}/content`, { - ...options, - headers: buildHeaders([{ Accept: 'application/binary' }, options?.headers]), - __binaryResponse: true, - }); - } -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -let Files$2 = class Files extends APIResource { - constructor() { - super(...arguments); - this.content = new Content(this._client); - } - /** - * Create a Container File - * - * You can send either a multipart/form-data request with the raw file content, or - * a JSON request with a file ID. - */ - create(containerID, body, options) { - return this._client.post(path `/containers/${containerID}/files`, multipartFormRequestOptions({ body, ...options }, this._client)); - } - /** - * Retrieve Container File - */ - retrieve(fileID, params, options) { - const { container_id } = params; - return this._client.get(path `/containers/${container_id}/files/${fileID}`, options); - } - /** - * List Container files - */ - list(containerID, query = {}, options) { - return this._client.getAPIList(path `/containers/${containerID}/files`, (CursorPage), { - query, - ...options, - }); - } - /** - * Delete Container File - */ - delete(fileID, params, options) { - const { container_id } = params; - return this._client.delete(path `/containers/${container_id}/files/${fileID}`, { - ...options, - headers: buildHeaders([{ Accept: '*/*' }, options?.headers]), - }); - } -}; -Files$2.Content = Content; - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Containers extends APIResource { - constructor() { - super(...arguments); - this.files = new Files$2(this._client); - } - /** - * Create Container - */ - create(body, options) { - return this._client.post('/containers', { body, ...options }); - } - /** - * Retrieve Container - */ - retrieve(containerID, options) { - return this._client.get(path `/containers/${containerID}`, options); - } - /** - * List Containers - */ - list(query = {}, options) { - return this._client.getAPIList('/containers', (CursorPage), { query, ...options }); - } - /** - * Delete Container - */ - delete(containerID, options) { - return this._client.delete(path `/containers/${containerID}`, { - ...options, - headers: buildHeaders([{ Accept: '*/*' }, options?.headers]), - }); - } -} -Containers.Files = Files$2; - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Items extends APIResource { - /** - * Create items in a conversation with the given ID. - */ - create(conversationID, params, options) { - const { include, ...body } = params; - return this._client.post(path `/conversations/${conversationID}/items`, { - query: { include }, - body, - ...options, - }); - } - /** - * Get a single item from a conversation with the given IDs. - */ - retrieve(itemID, params, options) { - const { conversation_id, ...query } = params; - return this._client.get(path `/conversations/${conversation_id}/items/${itemID}`, { query, ...options }); - } - /** - * List all items for a conversation with the given ID. - */ - list(conversationID, query = {}, options) { - return this._client.getAPIList(path `/conversations/${conversationID}/items`, (ConversationCursorPage), { query, ...options }); - } - /** - * Delete an item from a conversation with the given IDs. - */ - delete(itemID, params, options) { - const { conversation_id } = params; - return this._client.delete(path `/conversations/${conversation_id}/items/${itemID}`, options); - } -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Conversations extends APIResource { - constructor() { - super(...arguments); - this.items = new Items(this._client); - } - /** - * Create a conversation. - */ - create(body = {}, options) { - return this._client.post('/conversations', { body, ...options }); - } - /** - * Get a conversation - */ - retrieve(conversationID, options) { - return this._client.get(path `/conversations/${conversationID}`, options); - } - /** - * Update a conversation - */ - update(conversationID, body, options) { - return this._client.post(path `/conversations/${conversationID}`, { body, ...options }); - } - /** - * Delete a conversation. Items in the conversation will not be deleted. - */ - delete(conversationID, options) { - return this._client.delete(path `/conversations/${conversationID}`, options); - } -} -Conversations.Items = Items; - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Embeddings extends APIResource { - /** - * Creates an embedding vector representing the input text. - * - * @example - * ```ts - * const createEmbeddingResponse = - * await client.embeddings.create({ - * input: 'The quick brown fox jumped over the lazy dog', - * model: 'text-embedding-3-small', - * }); - * ``` - */ - create(body, options) { - const hasUserProvidedEncodingFormat = !!body.encoding_format; - // No encoding_format specified, defaulting to base64 for performance reasons - // See https://github.com/openai/openai-node/pull/1312 - let encoding_format = hasUserProvidedEncodingFormat ? body.encoding_format : 'base64'; - if (hasUserProvidedEncodingFormat) { - loggerFor(this._client).debug('embeddings/user defined encoding_format:', body.encoding_format); - } - const response = this._client.post('/embeddings', { - body: { - ...body, - encoding_format: encoding_format, - }, - ...options, - }); - // if the user specified an encoding_format, return the response as-is - if (hasUserProvidedEncodingFormat) { - return response; - } - // in this stage, we are sure the user did not specify an encoding_format - // and we defaulted to base64 for performance reasons - // we are sure then that the response is base64 encoded, let's decode it - // the returned result will be a float32 array since this is OpenAI API's default encoding - loggerFor(this._client).debug('embeddings/decoding base64 embeddings from base64'); - return response._thenUnwrap((response) => { - if (response && response.data) { - response.data.forEach((embeddingBase64Obj) => { - const embeddingBase64Str = embeddingBase64Obj.embedding; - embeddingBase64Obj.embedding = toFloat32Array(embeddingBase64Str); - }); - } - return response; - }); - } -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class OutputItems extends APIResource { - /** - * Get an evaluation run output item by ID. - */ - retrieve(outputItemID, params, options) { - const { eval_id, run_id } = params; - return this._client.get(path `/evals/${eval_id}/runs/${run_id}/output_items/${outputItemID}`, options); - } - /** - * Get a list of output items for an evaluation run. - */ - list(runID, params, options) { - const { eval_id, ...query } = params; - return this._client.getAPIList(path `/evals/${eval_id}/runs/${runID}/output_items`, (CursorPage), { query, ...options }); - } -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Runs extends APIResource { - constructor() { - super(...arguments); - this.outputItems = new OutputItems(this._client); - } - /** - * Kicks off a new run for a given evaluation, specifying the data source, and what - * model configuration to use to test. The datasource will be validated against the - * schema specified in the config of the evaluation. - */ - create(evalID, body, options) { - return this._client.post(path `/evals/${evalID}/runs`, { body, ...options }); - } - /** - * Get an evaluation run by ID. - */ - retrieve(runID, params, options) { - const { eval_id } = params; - return this._client.get(path `/evals/${eval_id}/runs/${runID}`, options); - } - /** - * Get a list of runs for an evaluation. - */ - list(evalID, query = {}, options) { - return this._client.getAPIList(path `/evals/${evalID}/runs`, (CursorPage), { - query, - ...options, - }); - } - /** - * Delete an eval run. - */ - delete(runID, params, options) { - const { eval_id } = params; - return this._client.delete(path `/evals/${eval_id}/runs/${runID}`, options); - } - /** - * Cancel an ongoing evaluation run. - */ - cancel(runID, params, options) { - const { eval_id } = params; - return this._client.post(path `/evals/${eval_id}/runs/${runID}`, options); - } -} -Runs.OutputItems = OutputItems; - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Evals extends APIResource { - constructor() { - super(...arguments); - this.runs = new Runs(this._client); - } - /** - * Create the structure of an evaluation that can be used to test a model's - * performance. An evaluation is a set of testing criteria and the config for a - * data source, which dictates the schema of the data used in the evaluation. After - * creating an evaluation, you can run it on different models and model parameters. - * We support several types of graders and datasources. For more information, see - * the [Evals guide](https://platform.openai.com/docs/guides/evals). - */ - create(body, options) { - return this._client.post('/evals', { body, ...options }); - } - /** - * Get an evaluation by ID. - */ - retrieve(evalID, options) { - return this._client.get(path `/evals/${evalID}`, options); - } - /** - * Update certain properties of an evaluation. - */ - update(evalID, body, options) { - return this._client.post(path `/evals/${evalID}`, { body, ...options }); - } - /** - * List evaluations for a project. - */ - list(query = {}, options) { - return this._client.getAPIList('/evals', (CursorPage), { query, ...options }); - } - /** - * Delete an evaluation. - */ - delete(evalID, options) { - return this._client.delete(path `/evals/${evalID}`, options); - } -} -Evals.Runs = Runs; - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -let Files$1 = class Files extends APIResource { - /** - * Upload a file that can be used across various endpoints. Individual files can be - * up to 512 MB, and the size of all files uploaded by one organization can be up - * to 1 TB. - * - * The Assistants API supports files up to 2 million tokens and of specific file - * types. See the - * [Assistants Tools guide](https://platform.openai.com/docs/assistants/tools) for - * details. - * - * The Fine-tuning API only supports `.jsonl` files. The input also has certain - * required formats for fine-tuning - * [chat](https://platform.openai.com/docs/api-reference/fine-tuning/chat-input) or - * [completions](https://platform.openai.com/docs/api-reference/fine-tuning/completions-input) - * models. - * - * The Batch API only supports `.jsonl` files up to 200 MB in size. The input also - * has a specific required - * [format](https://platform.openai.com/docs/api-reference/batch/request-input). - * - * Please [contact us](https://help.openai.com/) if you need to increase these - * storage limits. - */ - create(body, options) { - return this._client.post('/files', multipartFormRequestOptions({ body, ...options }, this._client)); - } - /** - * Returns information about a specific file. - */ - retrieve(fileID, options) { - return this._client.get(path `/files/${fileID}`, options); - } - /** - * Returns a list of files. - */ - list(query = {}, options) { - return this._client.getAPIList('/files', (CursorPage), { query, ...options }); - } - /** - * Delete a file. - */ - delete(fileID, options) { - return this._client.delete(path `/files/${fileID}`, options); - } - /** - * Returns the contents of the specified file. - */ - content(fileID, options) { - return this._client.get(path `/files/${fileID}/content`, { - ...options, - headers: buildHeaders([{ Accept: 'application/binary' }, options?.headers]), - __binaryResponse: true, - }); - } - /** - * Waits for the given file to be processed, default timeout is 30 mins. - */ - async waitForProcessing(id, { pollInterval = 5000, maxWait = 30 * 60 * 1000 } = {}) { - const TERMINAL_STATES = new Set(['processed', 'error', 'deleted']); - const start = Date.now(); - let file = await this.retrieve(id); - while (!file.status || !TERMINAL_STATES.has(file.status)) { - await sleep(pollInterval); - file = await this.retrieve(id); - if (Date.now() - start > maxWait) { - throw new APIConnectionTimeoutError({ - message: `Giving up on waiting for file ${id} to finish processing after ${maxWait} milliseconds.`, - }); - } - } - return file; - } -}; - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Methods extends APIResource { -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -let Graders$1 = class Graders extends APIResource { - /** - * Run a grader. - * - * @example - * ```ts - * const response = await client.fineTuning.alpha.graders.run({ - * grader: { - * input: 'input', - * name: 'name', - * operation: 'eq', - * reference: 'reference', - * type: 'string_check', - * }, - * model_sample: 'model_sample', - * }); - * ``` - */ - run(body, options) { - return this._client.post('/fine_tuning/alpha/graders/run', { body, ...options }); - } - /** - * Validate a grader. - * - * @example - * ```ts - * const response = - * await client.fineTuning.alpha.graders.validate({ - * grader: { - * input: 'input', - * name: 'name', - * operation: 'eq', - * reference: 'reference', - * type: 'string_check', - * }, - * }); - * ``` - */ - validate(body, options) { - return this._client.post('/fine_tuning/alpha/graders/validate', { body, ...options }); - } -}; - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Alpha extends APIResource { - constructor() { - super(...arguments); - this.graders = new Graders$1(this._client); - } -} -Alpha.Graders = Graders$1; - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Permissions extends APIResource { - /** - * **NOTE:** Calling this endpoint requires an [admin API key](../admin-api-keys). - * - * This enables organization owners to share fine-tuned models with other projects - * in their organization. - * - * @example - * ```ts - * // Automatically fetches more pages as needed. - * for await (const permissionCreateResponse of client.fineTuning.checkpoints.permissions.create( - * 'ft:gpt-4o-mini-2024-07-18:org:weather:B7R9VjQd', - * { project_ids: ['string'] }, - * )) { - * // ... - * } - * ``` - */ - create(fineTunedModelCheckpoint, body, options) { - return this._client.getAPIList(path `/fine_tuning/checkpoints/${fineTunedModelCheckpoint}/permissions`, (Page), { body, method: 'post', ...options }); - } - /** - * **NOTE:** This endpoint requires an [admin API key](../admin-api-keys). - * - * Organization owners can use this endpoint to view all permissions for a - * fine-tuned model checkpoint. - * - * @example - * ```ts - * const permission = - * await client.fineTuning.checkpoints.permissions.retrieve( - * 'ft-AF1WoRqd3aJAHsqc9NY7iL8F', - * ); - * ``` - */ - retrieve(fineTunedModelCheckpoint, query = {}, options) { - return this._client.get(path `/fine_tuning/checkpoints/${fineTunedModelCheckpoint}/permissions`, { - query, - ...options, - }); - } - /** - * **NOTE:** This endpoint requires an [admin API key](../admin-api-keys). - * - * Organization owners can use this endpoint to delete a permission for a - * fine-tuned model checkpoint. - * - * @example - * ```ts - * const permission = - * await client.fineTuning.checkpoints.permissions.delete( - * 'cp_zc4Q7MP6XxulcVzj4MZdwsAB', - * { - * fine_tuned_model_checkpoint: - * 'ft:gpt-4o-mini-2024-07-18:org:weather:B7R9VjQd', - * }, - * ); - * ``` - */ - delete(permissionID, params, options) { - const { fine_tuned_model_checkpoint } = params; - return this._client.delete(path `/fine_tuning/checkpoints/${fine_tuned_model_checkpoint}/permissions/${permissionID}`, options); - } -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -let Checkpoints$1 = class Checkpoints extends APIResource { - constructor() { - super(...arguments); - this.permissions = new Permissions(this._client); - } -}; -Checkpoints$1.Permissions = Permissions; - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Checkpoints extends APIResource { - /** - * List checkpoints for a fine-tuning job. - * - * @example - * ```ts - * // Automatically fetches more pages as needed. - * for await (const fineTuningJobCheckpoint of client.fineTuning.jobs.checkpoints.list( - * 'ft-AF1WoRqd3aJAHsqc9NY7iL8F', - * )) { - * // ... - * } - * ``` - */ - list(fineTuningJobID, query = {}, options) { - return this._client.getAPIList(path `/fine_tuning/jobs/${fineTuningJobID}/checkpoints`, (CursorPage), { query, ...options }); - } -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Jobs extends APIResource { - constructor() { - super(...arguments); - this.checkpoints = new Checkpoints(this._client); - } - /** - * Creates a fine-tuning job which begins the process of creating a new model from - * a given dataset. - * - * Response includes details of the enqueued job including job status and the name - * of the fine-tuned models once complete. - * - * [Learn more about fine-tuning](https://platform.openai.com/docs/guides/model-optimization) - * - * @example - * ```ts - * const fineTuningJob = await client.fineTuning.jobs.create({ - * model: 'gpt-4o-mini', - * training_file: 'file-abc123', - * }); - * ``` - */ - create(body, options) { - return this._client.post('/fine_tuning/jobs', { body, ...options }); - } - /** - * Get info about a fine-tuning job. - * - * [Learn more about fine-tuning](https://platform.openai.com/docs/guides/model-optimization) - * - * @example - * ```ts - * const fineTuningJob = await client.fineTuning.jobs.retrieve( - * 'ft-AF1WoRqd3aJAHsqc9NY7iL8F', - * ); - * ``` - */ - retrieve(fineTuningJobID, options) { - return this._client.get(path `/fine_tuning/jobs/${fineTuningJobID}`, options); - } - /** - * List your organization's fine-tuning jobs - * - * @example - * ```ts - * // Automatically fetches more pages as needed. - * for await (const fineTuningJob of client.fineTuning.jobs.list()) { - * // ... - * } - * ``` - */ - list(query = {}, options) { - return this._client.getAPIList('/fine_tuning/jobs', (CursorPage), { query, ...options }); - } - /** - * Immediately cancel a fine-tune job. - * - * @example - * ```ts - * const fineTuningJob = await client.fineTuning.jobs.cancel( - * 'ft-AF1WoRqd3aJAHsqc9NY7iL8F', - * ); - * ``` - */ - cancel(fineTuningJobID, options) { - return this._client.post(path `/fine_tuning/jobs/${fineTuningJobID}/cancel`, options); - } - /** - * Get status updates for a fine-tuning job. - * - * @example - * ```ts - * // Automatically fetches more pages as needed. - * for await (const fineTuningJobEvent of client.fineTuning.jobs.listEvents( - * 'ft-AF1WoRqd3aJAHsqc9NY7iL8F', - * )) { - * // ... - * } - * ``` - */ - listEvents(fineTuningJobID, query = {}, options) { - return this._client.getAPIList(path `/fine_tuning/jobs/${fineTuningJobID}/events`, (CursorPage), { query, ...options }); - } - /** - * Pause a fine-tune job. - * - * @example - * ```ts - * const fineTuningJob = await client.fineTuning.jobs.pause( - * 'ft-AF1WoRqd3aJAHsqc9NY7iL8F', - * ); - * ``` - */ - pause(fineTuningJobID, options) { - return this._client.post(path `/fine_tuning/jobs/${fineTuningJobID}/pause`, options); - } - /** - * Resume a fine-tune job. - * - * @example - * ```ts - * const fineTuningJob = await client.fineTuning.jobs.resume( - * 'ft-AF1WoRqd3aJAHsqc9NY7iL8F', - * ); - * ``` - */ - resume(fineTuningJobID, options) { - return this._client.post(path `/fine_tuning/jobs/${fineTuningJobID}/resume`, options); - } -} -Jobs.Checkpoints = Checkpoints; - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class FineTuning extends APIResource { - constructor() { - super(...arguments); - this.methods = new Methods(this._client); - this.jobs = new Jobs(this._client); - this.checkpoints = new Checkpoints$1(this._client); - this.alpha = new Alpha(this._client); - } -} -FineTuning.Methods = Methods; -FineTuning.Jobs = Jobs; -FineTuning.Checkpoints = Checkpoints$1; -FineTuning.Alpha = Alpha; - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class GraderModels extends APIResource { -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Graders extends APIResource { - constructor() { - super(...arguments); - this.graderModels = new GraderModels(this._client); - } -} -Graders.GraderModels = GraderModels; - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Images extends APIResource { - /** - * Creates a variation of a given image. This endpoint only supports `dall-e-2`. - * - * @example - * ```ts - * const imagesResponse = await client.images.createVariation({ - * image: fs.createReadStream('otter.png'), - * }); - * ``` - */ - createVariation(body, options) { - return this._client.post('/images/variations', multipartFormRequestOptions({ body, ...options }, this._client)); - } - edit(body, options) { - return this._client.post('/images/edits', multipartFormRequestOptions({ body, ...options, stream: body.stream ?? false }, this._client)); - } - generate(body, options) { - return this._client.post('/images/generations', { body, ...options, stream: body.stream ?? false }); - } -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Models extends APIResource { - /** - * Retrieves a model instance, providing basic information about the model such as - * the owner and permissioning. - */ - retrieve(model, options) { - return this._client.get(path `/models/${model}`, options); - } - /** - * Lists the currently available models, and provides basic information about each - * one such as the owner and availability. - */ - list(options) { - return this._client.getAPIList('/models', (Page), options); - } - /** - * Delete a fine-tuned model. You must have the Owner role in your organization to - * delete a model. - */ - delete(model, options) { - return this._client.delete(path `/models/${model}`, options); - } -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Moderations extends APIResource { - /** - * Classifies if text and/or image inputs are potentially harmful. Learn more in - * the [moderation guide](https://platform.openai.com/docs/guides/moderation). - */ - create(body, options) { - return this._client.post('/moderations', { body, ...options }); - } -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Calls extends APIResource { - /** - * Accept an incoming SIP call and configure the realtime session that will handle - * it. - * - * @example - * ```ts - * await client.realtime.calls.accept('call_id', { - * type: 'realtime', - * }); - * ``` - */ - accept(callID, body, options) { - return this._client.post(path `/realtime/calls/${callID}/accept`, { - body, - ...options, - headers: buildHeaders([{ Accept: '*/*' }, options?.headers]), - }); - } - /** - * End an active Realtime API call, whether it was initiated over SIP or WebRTC. - * - * @example - * ```ts - * await client.realtime.calls.hangup('call_id'); - * ``` - */ - hangup(callID, options) { - return this._client.post(path `/realtime/calls/${callID}/hangup`, { - ...options, - headers: buildHeaders([{ Accept: '*/*' }, options?.headers]), - }); - } - /** - * Transfer an active SIP call to a new destination using the SIP REFER verb. - * - * @example - * ```ts - * await client.realtime.calls.refer('call_id', { - * target_uri: 'tel:+14155550123', - * }); - * ``` - */ - refer(callID, body, options) { - return this._client.post(path `/realtime/calls/${callID}/refer`, { - body, - ...options, - headers: buildHeaders([{ Accept: '*/*' }, options?.headers]), - }); - } - /** - * Decline an incoming SIP call by returning a SIP status code to the caller. - * - * @example - * ```ts - * await client.realtime.calls.reject('call_id'); - * ``` - */ - reject(callID, body = {}, options) { - return this._client.post(path `/realtime/calls/${callID}/reject`, { - body, - ...options, - headers: buildHeaders([{ Accept: '*/*' }, options?.headers]), - }); - } -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class ClientSecrets extends APIResource { - /** - * Create a Realtime client secret with an associated session configuration. - * - * @example - * ```ts - * const clientSecret = - * await client.realtime.clientSecrets.create(); - * ``` - */ - create(body, options) { - return this._client.post('/realtime/client_secrets', { body, ...options }); - } -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Realtime extends APIResource { - constructor() { - super(...arguments); - this.clientSecrets = new ClientSecrets(this._client); - this.calls = new Calls(this._client); - } -} -Realtime.ClientSecrets = ClientSecrets; -Realtime.Calls = Calls; - -function maybeParseResponse(response, params) { - if (!params || !hasAutoParseableInput(params)) { - return { - ...response, - output_parsed: null, - output: response.output.map((item) => { - if (item.type === 'function_call') { - return { - ...item, - parsed_arguments: null, - }; - } - if (item.type === 'message') { - return { - ...item, - content: item.content.map((content) => ({ - ...content, - parsed: null, - })), - }; - } - else { - return item; - } - }), - }; - } - return parseResponse(response, params); -} -function parseResponse(response, params) { - const output = response.output.map((item) => { - if (item.type === 'function_call') { - return { - ...item, - parsed_arguments: parseToolCall(params, item), - }; - } - if (item.type === 'message') { - const content = item.content.map((content) => { - if (content.type === 'output_text') { - return { - ...content, - parsed: parseTextFormat(params, content.text), - }; - } - return content; - }); - return { - ...item, - content, - }; - } - return item; - }); - const parsed = Object.assign({}, response, { output }); - if (!Object.getOwnPropertyDescriptor(response, 'output_text')) { - addOutputText(parsed); - } - Object.defineProperty(parsed, 'output_parsed', { - enumerable: true, - get() { - for (const output of parsed.output) { - if (output.type !== 'message') { - continue; - } - for (const content of output.content) { - if (content.type === 'output_text' && content.parsed !== null) { - return content.parsed; - } - } - } - return null; - }, - }); - return parsed; -} -function parseTextFormat(params, content) { - if (params.text?.format?.type !== 'json_schema') { - return null; - } - if ('$parseRaw' in params.text?.format) { - const text_format = params.text?.format; - return text_format.$parseRaw(content); - } - return JSON.parse(content); -} -function hasAutoParseableInput(params) { - if (isAutoParsableResponseFormat(params.text?.format)) { - return true; - } - return false; -} -function isAutoParsableTool(tool) { - return tool?.['$brand'] === 'auto-parseable-tool'; -} -function getInputToolByName(input_tools, name) { - return input_tools.find((tool) => tool.type === 'function' && tool.name === name); -} -function parseToolCall(params, toolCall) { - const inputTool = getInputToolByName(params.tools ?? [], toolCall.name); - return { - ...toolCall, - ...toolCall, - parsed_arguments: isAutoParsableTool(inputTool) ? inputTool.$parseRaw(toolCall.arguments) - : inputTool?.strict ? JSON.parse(toolCall.arguments) - : null, - }; -} -function addOutputText(rsp) { - const texts = []; - for (const output of rsp.output) { - if (output.type !== 'message') { - continue; - } - for (const content of output.content) { - if (content.type === 'output_text') { - texts.push(content.text); - } - } - } - rsp.output_text = texts.join(''); -} - -var _ResponseStream_instances, _ResponseStream_params, _ResponseStream_currentResponseSnapshot, _ResponseStream_finalResponse, _ResponseStream_beginRequest, _ResponseStream_addEvent, _ResponseStream_endRequest, _ResponseStream_accumulateResponse; -class ResponseStream extends EventStream { - constructor(params) { - super(); - _ResponseStream_instances.add(this); - _ResponseStream_params.set(this, void 0); - _ResponseStream_currentResponseSnapshot.set(this, void 0); - _ResponseStream_finalResponse.set(this, void 0); - __classPrivateFieldSet(this, _ResponseStream_params, params); - } - static createResponse(client, params, options) { - const runner = new ResponseStream(params); - runner._run(() => runner._createOrRetrieveResponse(client, params, { - ...options, - headers: { ...options?.headers, 'X-Stainless-Helper-Method': 'stream' }, - })); - return runner; - } - async _createOrRetrieveResponse(client, params, options) { - const signal = options?.signal; - if (signal) { - if (signal.aborted) - this.controller.abort(); - signal.addEventListener('abort', () => this.controller.abort()); - } - __classPrivateFieldGet(this, _ResponseStream_instances, "m", _ResponseStream_beginRequest).call(this); - let stream; - let starting_after = null; - if ('response_id' in params) { - stream = await client.responses.retrieve(params.response_id, { stream: true }, { ...options, signal: this.controller.signal, stream: true }); - starting_after = params.starting_after ?? null; - } - else { - stream = await client.responses.create({ ...params, stream: true }, { ...options, signal: this.controller.signal }); - } - this._connected(); - for await (const event of stream) { - __classPrivateFieldGet(this, _ResponseStream_instances, "m", _ResponseStream_addEvent).call(this, event, starting_after); - } - if (stream.controller.signal?.aborted) { - throw new APIUserAbortError(); - } - return __classPrivateFieldGet(this, _ResponseStream_instances, "m", _ResponseStream_endRequest).call(this); - } - [(_ResponseStream_params = new WeakMap(), _ResponseStream_currentResponseSnapshot = new WeakMap(), _ResponseStream_finalResponse = new WeakMap(), _ResponseStream_instances = new WeakSet(), _ResponseStream_beginRequest = function _ResponseStream_beginRequest() { - if (this.ended) - return; - __classPrivateFieldSet(this, _ResponseStream_currentResponseSnapshot, undefined); - }, _ResponseStream_addEvent = function _ResponseStream_addEvent(event, starting_after) { - if (this.ended) - return; - const maybeEmit = (name, event) => { - if (starting_after == null || event.sequence_number > starting_after) { - this._emit(name, event); - } - }; - const response = __classPrivateFieldGet(this, _ResponseStream_instances, "m", _ResponseStream_accumulateResponse).call(this, event); - maybeEmit('event', event); - switch (event.type) { - case 'response.output_text.delta': { - const output = response.output[event.output_index]; - if (!output) { - throw new OpenAIError(`missing output at index ${event.output_index}`); - } - if (output.type === 'message') { - const content = output.content[event.content_index]; - if (!content) { - throw new OpenAIError(`missing content at index ${event.content_index}`); - } - if (content.type !== 'output_text') { - throw new OpenAIError(`expected content to be 'output_text', got ${content.type}`); - } - maybeEmit('response.output_text.delta', { - ...event, - snapshot: content.text, - }); - } - break; - } - case 'response.function_call_arguments.delta': { - const output = response.output[event.output_index]; - if (!output) { - throw new OpenAIError(`missing output at index ${event.output_index}`); - } - if (output.type === 'function_call') { - maybeEmit('response.function_call_arguments.delta', { - ...event, - snapshot: output.arguments, - }); - } - break; - } - default: - maybeEmit(event.type, event); - break; - } - }, _ResponseStream_endRequest = function _ResponseStream_endRequest() { - if (this.ended) { - throw new OpenAIError(`stream has ended, this shouldn't happen`); - } - const snapshot = __classPrivateFieldGet(this, _ResponseStream_currentResponseSnapshot, "f"); - if (!snapshot) { - throw new OpenAIError(`request ended without sending any events`); - } - __classPrivateFieldSet(this, _ResponseStream_currentResponseSnapshot, undefined); - const parsedResponse = finalizeResponse(snapshot, __classPrivateFieldGet(this, _ResponseStream_params, "f")); - __classPrivateFieldSet(this, _ResponseStream_finalResponse, parsedResponse); - return parsedResponse; - }, _ResponseStream_accumulateResponse = function _ResponseStream_accumulateResponse(event) { - let snapshot = __classPrivateFieldGet(this, _ResponseStream_currentResponseSnapshot, "f"); - if (!snapshot) { - if (event.type !== 'response.created') { - throw new OpenAIError(`When snapshot hasn't been set yet, expected 'response.created' event, got ${event.type}`); - } - snapshot = __classPrivateFieldSet(this, _ResponseStream_currentResponseSnapshot, event.response); - return snapshot; - } - switch (event.type) { - case 'response.output_item.added': { - snapshot.output.push(event.item); - break; - } - case 'response.content_part.added': { - const output = snapshot.output[event.output_index]; - if (!output) { - throw new OpenAIError(`missing output at index ${event.output_index}`); - } - const type = output.type; - const part = event.part; - if (type === 'message' && part.type !== 'reasoning_text') { - output.content.push(part); - } - else if (type === 'reasoning' && part.type === 'reasoning_text') { - if (!output.content) { - output.content = []; - } - output.content.push(part); - } - break; - } - case 'response.output_text.delta': { - const output = snapshot.output[event.output_index]; - if (!output) { - throw new OpenAIError(`missing output at index ${event.output_index}`); - } - if (output.type === 'message') { - const content = output.content[event.content_index]; - if (!content) { - throw new OpenAIError(`missing content at index ${event.content_index}`); - } - if (content.type !== 'output_text') { - throw new OpenAIError(`expected content to be 'output_text', got ${content.type}`); - } - content.text += event.delta; - } - break; - } - case 'response.function_call_arguments.delta': { - const output = snapshot.output[event.output_index]; - if (!output) { - throw new OpenAIError(`missing output at index ${event.output_index}`); - } - if (output.type === 'function_call') { - output.arguments += event.delta; - } - break; - } - case 'response.reasoning_text.delta': { - const output = snapshot.output[event.output_index]; - if (!output) { - throw new OpenAIError(`missing output at index ${event.output_index}`); - } - if (output.type === 'reasoning') { - const content = output.content?.[event.content_index]; - if (!content) { - throw new OpenAIError(`missing content at index ${event.content_index}`); - } - if (content.type !== 'reasoning_text') { - throw new OpenAIError(`expected content to be 'reasoning_text', got ${content.type}`); - } - content.text += event.delta; - } - break; - } - case 'response.completed': { - __classPrivateFieldSet(this, _ResponseStream_currentResponseSnapshot, event.response); - break; - } - } - return snapshot; - }, Symbol.asyncIterator)]() { - const pushQueue = []; - const readQueue = []; - let done = false; - this.on('event', (event) => { - const reader = readQueue.shift(); - if (reader) { - reader.resolve(event); - } - else { - pushQueue.push(event); - } - }); - this.on('end', () => { - done = true; - for (const reader of readQueue) { - reader.resolve(undefined); - } - readQueue.length = 0; - }); - this.on('abort', (err) => { - done = true; - for (const reader of readQueue) { - reader.reject(err); - } - readQueue.length = 0; - }); - this.on('error', (err) => { - done = true; - for (const reader of readQueue) { - reader.reject(err); - } - readQueue.length = 0; - }); - return { - next: async () => { - if (!pushQueue.length) { - if (done) { - return { value: undefined, done: true }; - } - return new Promise((resolve, reject) => readQueue.push({ resolve, reject })).then((event) => (event ? { value: event, done: false } : { value: undefined, done: true })); - } - const event = pushQueue.shift(); - return { value: event, done: false }; - }, - return: async () => { - this.abort(); - return { value: undefined, done: true }; - }, - }; - } - /** - * @returns a promise that resolves with the final Response, or rejects - * if an error occurred or the stream ended prematurely without producing a REsponse. - */ - async finalResponse() { - await this.done(); - const response = __classPrivateFieldGet(this, _ResponseStream_finalResponse, "f"); - if (!response) - throw new OpenAIError('stream ended without producing a ChatCompletion'); - return response; - } -} -function finalizeResponse(snapshot, params) { - return maybeParseResponse(snapshot, params); -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class InputItems extends APIResource { - /** - * Returns a list of input items for a given response. - * - * @example - * ```ts - * // Automatically fetches more pages as needed. - * for await (const responseItem of client.responses.inputItems.list( - * 'response_id', - * )) { - * // ... - * } - * ``` - */ - list(responseID, query = {}, options) { - return this._client.getAPIList(path `/responses/${responseID}/input_items`, (CursorPage), { query, ...options }); - } -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Responses extends APIResource { - constructor() { - super(...arguments); - this.inputItems = new InputItems(this._client); - } - create(body, options) { - return this._client.post('/responses', { body, ...options, stream: body.stream ?? false })._thenUnwrap((rsp) => { - if ('object' in rsp && rsp.object === 'response') { - addOutputText(rsp); - } - return rsp; - }); - } - retrieve(responseID, query = {}, options) { - return this._client.get(path `/responses/${responseID}`, { - query, - ...options, - stream: query?.stream ?? false, - })._thenUnwrap((rsp) => { - if ('object' in rsp && rsp.object === 'response') { - addOutputText(rsp); - } - return rsp; - }); - } - /** - * Deletes a model response with the given ID. - * - * @example - * ```ts - * await client.responses.delete( - * 'resp_677efb5139a88190b512bc3fef8e535d', - * ); - * ``` - */ - delete(responseID, options) { - return this._client.delete(path `/responses/${responseID}`, { - ...options, - headers: buildHeaders([{ Accept: '*/*' }, options?.headers]), - }); - } - parse(body, options) { - return this._client.responses - .create(body, options) - ._thenUnwrap((response) => parseResponse(response, body)); - } - /** - * Creates a model response stream - */ - stream(body, options) { - return ResponseStream.createResponse(this._client, body, options); - } - /** - * Cancels a model response with the given ID. Only responses created with the - * `background` parameter set to `true` can be cancelled. - * [Learn more](https://platform.openai.com/docs/guides/background). - * - * @example - * ```ts - * const response = await client.responses.cancel( - * 'resp_677efb5139a88190b512bc3fef8e535d', - * ); - * ``` - */ - cancel(responseID, options) { - return this._client.post(path `/responses/${responseID}/cancel`, options); - } -} -Responses.InputItems = InputItems; - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Parts extends APIResource { - /** - * Adds a - * [Part](https://platform.openai.com/docs/api-reference/uploads/part-object) to an - * [Upload](https://platform.openai.com/docs/api-reference/uploads/object) object. - * A Part represents a chunk of bytes from the file you are trying to upload. - * - * Each Part can be at most 64 MB, and you can add Parts until you hit the Upload - * maximum of 8 GB. - * - * It is possible to add multiple Parts in parallel. You can decide the intended - * order of the Parts when you - * [complete the Upload](https://platform.openai.com/docs/api-reference/uploads/complete). - */ - create(uploadID, body, options) { - return this._client.post(path `/uploads/${uploadID}/parts`, multipartFormRequestOptions({ body, ...options }, this._client)); - } -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Uploads extends APIResource { - constructor() { - super(...arguments); - this.parts = new Parts(this._client); - } - /** - * Creates an intermediate - * [Upload](https://platform.openai.com/docs/api-reference/uploads/object) object - * that you can add - * [Parts](https://platform.openai.com/docs/api-reference/uploads/part-object) to. - * Currently, an Upload can accept at most 8 GB in total and expires after an hour - * after you create it. - * - * Once you complete the Upload, we will create a - * [File](https://platform.openai.com/docs/api-reference/files/object) object that - * contains all the parts you uploaded. This File is usable in the rest of our - * platform as a regular File object. - * - * For certain `purpose` values, the correct `mime_type` must be specified. Please - * refer to documentation for the - * [supported MIME types for your use case](https://platform.openai.com/docs/assistants/tools/file-search#supported-files). - * - * For guidance on the proper filename extensions for each purpose, please follow - * the documentation on - * [creating a File](https://platform.openai.com/docs/api-reference/files/create). - */ - create(body, options) { - return this._client.post('/uploads', { body, ...options }); - } - /** - * Cancels the Upload. No Parts may be added after an Upload is cancelled. - */ - cancel(uploadID, options) { - return this._client.post(path `/uploads/${uploadID}/cancel`, options); - } - /** - * Completes the - * [Upload](https://platform.openai.com/docs/api-reference/uploads/object). - * - * Within the returned Upload object, there is a nested - * [File](https://platform.openai.com/docs/api-reference/files/object) object that - * is ready to use in the rest of the platform. - * - * You can specify the order of the Parts by passing in an ordered list of the Part - * IDs. - * - * The number of bytes uploaded upon completion must match the number of bytes - * initially specified when creating the Upload object. No Parts may be added after - * an Upload is completed. - */ - complete(uploadID, body, options) { - return this._client.post(path `/uploads/${uploadID}/complete`, { body, ...options }); - } -} -Uploads.Parts = Parts; - -/** - * Like `Promise.allSettled()` but throws an error if any promises are rejected. - */ -const allSettledWithThrow = async (promises) => { - const results = await Promise.allSettled(promises); - const rejected = results.filter((result) => result.status === 'rejected'); - if (rejected.length) { - for (const result of rejected) { - console.error(result.reason); - } - throw new Error(`${rejected.length} promise(s) failed - see the above errors`); - } - // Note: TS was complaining about using `.filter().map()` here for some reason - const values = []; - for (const result of results) { - if (result.status === 'fulfilled') { - values.push(result.value); - } - } - return values; -}; - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class FileBatches extends APIResource { - /** - * Create a vector store file batch. - */ - create(vectorStoreID, body, options) { - return this._client.post(path `/vector_stores/${vectorStoreID}/file_batches`, { - body, - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } - /** - * Retrieves a vector store file batch. - */ - retrieve(batchID, params, options) { - const { vector_store_id } = params; - return this._client.get(path `/vector_stores/${vector_store_id}/file_batches/${batchID}`, { - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } - /** - * Cancel a vector store file batch. This attempts to cancel the processing of - * files in this batch as soon as possible. - */ - cancel(batchID, params, options) { - const { vector_store_id } = params; - return this._client.post(path `/vector_stores/${vector_store_id}/file_batches/${batchID}/cancel`, { - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } - /** - * Create a vector store batch and poll until all files have been processed. - */ - async createAndPoll(vectorStoreId, body, options) { - const batch = await this.create(vectorStoreId, body); - return await this.poll(vectorStoreId, batch.id, options); - } - /** - * Returns a list of vector store files in a batch. - */ - listFiles(batchID, params, options) { - const { vector_store_id, ...query } = params; - return this._client.getAPIList(path `/vector_stores/${vector_store_id}/file_batches/${batchID}/files`, (CursorPage), { query, ...options, headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]) }); - } - /** - * Wait for the given file batch to be processed. - * - * Note: this will return even if one of the files failed to process, you need to - * check batch.file_counts.failed_count to handle this case. - */ - async poll(vectorStoreID, batchID, options) { - const headers = buildHeaders([ - options?.headers, - { - 'X-Stainless-Poll-Helper': 'true', - 'X-Stainless-Custom-Poll-Interval': options?.pollIntervalMs?.toString() ?? undefined, - }, - ]); - while (true) { - const { data: batch, response } = await this.retrieve(batchID, { vector_store_id: vectorStoreID }, { - ...options, - headers, - }).withResponse(); - switch (batch.status) { - case 'in_progress': - let sleepInterval = 5000; - if (options?.pollIntervalMs) { - sleepInterval = options.pollIntervalMs; - } - else { - const headerInterval = response.headers.get('openai-poll-after-ms'); - if (headerInterval) { - const headerIntervalMs = parseInt(headerInterval); - if (!isNaN(headerIntervalMs)) { - sleepInterval = headerIntervalMs; - } - } - } - await sleep(sleepInterval); - break; - case 'failed': - case 'cancelled': - case 'completed': - return batch; - } - } - } - /** - * Uploads the given files concurrently and then creates a vector store file batch. - * - * The concurrency limit is configurable using the `maxConcurrency` parameter. - */ - async uploadAndPoll(vectorStoreId, { files, fileIds = [] }, options) { - if (files == null || files.length == 0) { - throw new Error(`No \`files\` provided to process. If you've already uploaded files you should use \`.createAndPoll()\` instead`); - } - const configuredConcurrency = options?.maxConcurrency ?? 5; - // We cap the number of workers at the number of files (so we don't start any unnecessary workers) - const concurrencyLimit = Math.min(configuredConcurrency, files.length); - const client = this._client; - const fileIterator = files.values(); - const allFileIds = [...fileIds]; - // This code is based on this design. The libraries don't accommodate our environment limits. - // https://stackoverflow.com/questions/40639432/what-is-the-best-way-to-limit-concurrency-when-using-es6s-promise-all - async function processFiles(iterator) { - for (let item of iterator) { - const fileObj = await client.files.create({ file: item, purpose: 'assistants' }, options); - allFileIds.push(fileObj.id); - } - } - // Start workers to process results - const workers = Array(concurrencyLimit).fill(fileIterator).map(processFiles); - // Wait for all processing to complete. - await allSettledWithThrow(workers); - return await this.createAndPoll(vectorStoreId, { - file_ids: allFileIds, - }); - } -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class Files extends APIResource { - /** - * Create a vector store file by attaching a - * [File](https://platform.openai.com/docs/api-reference/files) to a - * [vector store](https://platform.openai.com/docs/api-reference/vector-stores/object). - */ - create(vectorStoreID, body, options) { - return this._client.post(path `/vector_stores/${vectorStoreID}/files`, { - body, - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } - /** - * Retrieves a vector store file. - */ - retrieve(fileID, params, options) { - const { vector_store_id } = params; - return this._client.get(path `/vector_stores/${vector_store_id}/files/${fileID}`, { - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } - /** - * Update attributes on a vector store file. - */ - update(fileID, params, options) { - const { vector_store_id, ...body } = params; - return this._client.post(path `/vector_stores/${vector_store_id}/files/${fileID}`, { - body, - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } - /** - * Returns a list of vector store files. - */ - list(vectorStoreID, query = {}, options) { - return this._client.getAPIList(path `/vector_stores/${vectorStoreID}/files`, (CursorPage), { - query, - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } - /** - * Delete a vector store file. This will remove the file from the vector store but - * the file itself will not be deleted. To delete the file, use the - * [delete file](https://platform.openai.com/docs/api-reference/files/delete) - * endpoint. - */ - delete(fileID, params, options) { - const { vector_store_id } = params; - return this._client.delete(path `/vector_stores/${vector_store_id}/files/${fileID}`, { - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } - /** - * Attach a file to the given vector store and wait for it to be processed. - */ - async createAndPoll(vectorStoreId, body, options) { - const file = await this.create(vectorStoreId, body, options); - return await this.poll(vectorStoreId, file.id, options); - } - /** - * Wait for the vector store file to finish processing. - * - * Note: this will return even if the file failed to process, you need to check - * file.last_error and file.status to handle these cases - */ - async poll(vectorStoreID, fileID, options) { - const headers = buildHeaders([ - options?.headers, - { - 'X-Stainless-Poll-Helper': 'true', - 'X-Stainless-Custom-Poll-Interval': options?.pollIntervalMs?.toString() ?? undefined, - }, - ]); - while (true) { - const fileResponse = await this.retrieve(fileID, { - vector_store_id: vectorStoreID, - }, { ...options, headers }).withResponse(); - const file = fileResponse.data; - switch (file.status) { - case 'in_progress': - let sleepInterval = 5000; - if (options?.pollIntervalMs) { - sleepInterval = options.pollIntervalMs; - } - else { - const headerInterval = fileResponse.response.headers.get('openai-poll-after-ms'); - if (headerInterval) { - const headerIntervalMs = parseInt(headerInterval); - if (!isNaN(headerIntervalMs)) { - sleepInterval = headerIntervalMs; - } - } - } - await sleep(sleepInterval); - break; - case 'failed': - case 'completed': - return file; - } - } - } - /** - * Upload a file to the `files` API and then attach it to the given vector store. - * - * Note the file will be asynchronously processed (you can use the alternative - * polling helper method to wait for processing to complete). - */ - async upload(vectorStoreId, file, options) { - const fileInfo = await this._client.files.create({ file: file, purpose: 'assistants' }, options); - return this.create(vectorStoreId, { file_id: fileInfo.id }, options); - } - /** - * Add a file to a vector store and poll until processing is complete. - */ - async uploadAndPoll(vectorStoreId, file, options) { - const fileInfo = await this.upload(vectorStoreId, file, options); - return await this.poll(vectorStoreId, fileInfo.id, options); - } - /** - * Retrieve the parsed contents of a vector store file. - */ - content(fileID, params, options) { - const { vector_store_id } = params; - return this._client.getAPIList(path `/vector_stores/${vector_store_id}/files/${fileID}/content`, (Page), { ...options, headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]) }); - } -} - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -class VectorStores extends APIResource { - constructor() { - super(...arguments); - this.files = new Files(this._client); - this.fileBatches = new FileBatches(this._client); - } - /** - * Create a vector store. - */ - create(body, options) { - return this._client.post('/vector_stores', { - body, - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } - /** - * Retrieves a vector store. - */ - retrieve(vectorStoreID, options) { - return this._client.get(path `/vector_stores/${vectorStoreID}`, { - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } - /** - * Modifies a vector store. - */ - update(vectorStoreID, body, options) { - return this._client.post(path `/vector_stores/${vectorStoreID}`, { - body, - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } - /** - * Returns a list of vector stores. - */ - list(query = {}, options) { - return this._client.getAPIList('/vector_stores', (CursorPage), { - query, - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } - /** - * Delete a vector store. - */ - delete(vectorStoreID, options) { - return this._client.delete(path `/vector_stores/${vectorStoreID}`, { - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } - /** - * Search a vector store for relevant chunks based on a query and file attributes - * filter. - */ - search(vectorStoreID, body, options) { - return this._client.getAPIList(path `/vector_stores/${vectorStoreID}/search`, (Page), { - body, - method: 'post', - ...options, - headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]), - }); - } -} -VectorStores.Files = Files; -VectorStores.FileBatches = FileBatches; - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -var _Webhooks_instances, _Webhooks_validateSecret, _Webhooks_getRequiredHeader; -class Webhooks extends APIResource { - constructor() { - super(...arguments); - _Webhooks_instances.add(this); - } - /** - * Validates that the given payload was sent by OpenAI and parses the payload. - */ - async unwrap(payload, headers, secret = this._client.webhookSecret, tolerance = 300) { - await this.verifySignature(payload, headers, secret, tolerance); - return JSON.parse(payload); - } - /** - * Validates whether or not the webhook payload was sent by OpenAI. - * - * An error will be raised if the webhook payload was not sent by OpenAI. - * - * @param payload - The webhook payload - * @param headers - The webhook headers - * @param secret - The webhook secret (optional, will use client secret if not provided) - * @param tolerance - Maximum age of the webhook in seconds (default: 300 = 5 minutes) - */ - async verifySignature(payload, headers, secret = this._client.webhookSecret, tolerance = 300) { - if (typeof crypto === 'undefined' || - typeof crypto.subtle.importKey !== 'function' || - typeof crypto.subtle.verify !== 'function') { - throw new Error('Webhook signature verification is only supported when the `crypto` global is defined'); - } - __classPrivateFieldGet(this, _Webhooks_instances, "m", _Webhooks_validateSecret).call(this, secret); - const headersObj = buildHeaders([headers]).values; - const signatureHeader = __classPrivateFieldGet(this, _Webhooks_instances, "m", _Webhooks_getRequiredHeader).call(this, headersObj, 'webhook-signature'); - const timestamp = __classPrivateFieldGet(this, _Webhooks_instances, "m", _Webhooks_getRequiredHeader).call(this, headersObj, 'webhook-timestamp'); - const webhookId = __classPrivateFieldGet(this, _Webhooks_instances, "m", _Webhooks_getRequiredHeader).call(this, headersObj, 'webhook-id'); - // Validate timestamp to prevent replay attacks - const timestampSeconds = parseInt(timestamp, 10); - if (isNaN(timestampSeconds)) { - throw new InvalidWebhookSignatureError('Invalid webhook timestamp format'); - } - const nowSeconds = Math.floor(Date.now() / 1000); - if (nowSeconds - timestampSeconds > tolerance) { - throw new InvalidWebhookSignatureError('Webhook timestamp is too old'); - } - if (timestampSeconds > nowSeconds + tolerance) { - throw new InvalidWebhookSignatureError('Webhook timestamp is too new'); - } - // Extract signatures from v1, format - // The signature header can have multiple values, separated by spaces. - // Each value is in the format v1,. We should accept if any match. - const signatures = signatureHeader - .split(' ') - .map((part) => (part.startsWith('v1,') ? part.substring(3) : part)); - // Decode the secret if it starts with whsec_ - const decodedSecret = secret.startsWith('whsec_') ? - Buffer.from(secret.replace('whsec_', ''), 'base64') - : Buffer.from(secret, 'utf-8'); - // Create the signed payload: {webhook_id}.{timestamp}.{payload} - const signedPayload = webhookId ? `${webhookId}.${timestamp}.${payload}` : `${timestamp}.${payload}`; - // Import the secret as a cryptographic key for HMAC - const key = await crypto.subtle.importKey('raw', decodedSecret, { name: 'HMAC', hash: 'SHA-256' }, false, ['verify']); - // Check if any signature matches using timing-safe WebCrypto verify - for (const signature of signatures) { - try { - const signatureBytes = Buffer.from(signature, 'base64'); - const isValid = await crypto.subtle.verify('HMAC', key, signatureBytes, new TextEncoder().encode(signedPayload)); - if (isValid) { - return; // Valid signature found - } - } - catch { - // Invalid base64 or signature format, continue to next signature - continue; - } - } - throw new InvalidWebhookSignatureError('The given webhook signature does not match the expected signature'); - } -} -_Webhooks_instances = new WeakSet(), _Webhooks_validateSecret = function _Webhooks_validateSecret(secret) { - if (typeof secret !== 'string' || secret.length === 0) { - throw new Error(`The webhook secret must either be set using the env var, OPENAI_WEBHOOK_SECRET, on the client class, OpenAI({ webhookSecret: '123' }), or passed to this function`); - } -}, _Webhooks_getRequiredHeader = function _Webhooks_getRequiredHeader(headers, name) { - if (!headers) { - throw new Error(`Headers are required`); - } - const value = headers.get(name); - if (value === null || value === undefined) { - throw new Error(`Missing required header: ${name}`); - } - return value; -}; - -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -var _OpenAI_instances, _a, _OpenAI_encoder, _OpenAI_baseURLOverridden; -/** - * API Client for interfacing with the OpenAI API. - */ -class OpenAI { - /** - * API Client for interfacing with the OpenAI API. - * - * @param {string | undefined} [opts.apiKey=process.env['OPENAI_API_KEY'] ?? undefined] - * @param {string | null | undefined} [opts.organization=process.env['OPENAI_ORG_ID'] ?? null] - * @param {string | null | undefined} [opts.project=process.env['OPENAI_PROJECT_ID'] ?? null] - * @param {string | null | undefined} [opts.webhookSecret=process.env['OPENAI_WEBHOOK_SECRET'] ?? null] - * @param {string} [opts.baseURL=process.env['OPENAI_BASE_URL'] ?? https://api.openai.com/v1] - Override the default base URL for the API. - * @param {number} [opts.timeout=10 minutes] - The maximum amount of time (in milliseconds) the client will wait for a response before timing out. - * @param {MergedRequestInit} [opts.fetchOptions] - Additional `RequestInit` options to be passed to `fetch` calls. - * @param {Fetch} [opts.fetch] - Specify a custom `fetch` function implementation. - * @param {number} [opts.maxRetries=2] - The maximum number of times the client will retry a request. - * @param {HeadersLike} opts.defaultHeaders - Default headers to include with every request to the API. - * @param {Record} opts.defaultQuery - Default query parameters to include with every request to the API. - * @param {boolean} [opts.dangerouslyAllowBrowser=false] - By default, client-side use of this library is not allowed, as it risks exposing your secret API credentials to attackers. - */ - constructor({ baseURL = readEnv('OPENAI_BASE_URL'), apiKey = readEnv('OPENAI_API_KEY'), organization = readEnv('OPENAI_ORG_ID') ?? null, project = readEnv('OPENAI_PROJECT_ID') ?? null, webhookSecret = readEnv('OPENAI_WEBHOOK_SECRET') ?? null, ...opts } = {}) { - _OpenAI_instances.add(this); - _OpenAI_encoder.set(this, void 0); - this.completions = new Completions(this); - this.chat = new Chat(this); - this.embeddings = new Embeddings(this); - this.files = new Files$1(this); - this.images = new Images(this); - this.audio = new Audio(this); - this.moderations = new Moderations(this); - this.models = new Models(this); - this.fineTuning = new FineTuning(this); - this.graders = new Graders(this); - this.vectorStores = new VectorStores(this); - this.webhooks = new Webhooks(this); - this.beta = new Beta(this); - this.batches = new Batches(this); - this.uploads = new Uploads(this); - this.responses = new Responses(this); - this.realtime = new Realtime(this); - this.conversations = new Conversations(this); - this.evals = new Evals(this); - this.containers = new Containers(this); - if (apiKey === undefined) { - throw new OpenAIError('Missing credentials. Please pass an `apiKey`, or set the `OPENAI_API_KEY` environment variable.'); - } - const options = { - apiKey, - organization, - project, - webhookSecret, - ...opts, - baseURL: baseURL || `https://api.openai.com/v1`, - }; - if (!options.dangerouslyAllowBrowser && isRunningInBrowser()) { - throw new OpenAIError("It looks like you're running in a browser-like environment.\n\nThis is disabled by default, as it risks exposing your secret API credentials to attackers.\nIf you understand the risks and have appropriate mitigations in place,\nyou can set the `dangerouslyAllowBrowser` option to `true`, e.g.,\n\nnew OpenAI({ apiKey, dangerouslyAllowBrowser: true });\n\nhttps://help.openai.com/en/articles/5112595-best-practices-for-api-key-safety\n"); - } - this.baseURL = options.baseURL; - this.timeout = options.timeout ?? _a.DEFAULT_TIMEOUT /* 10 minutes */; - this.logger = options.logger ?? console; - const defaultLogLevel = 'warn'; - // Set default logLevel early so that we can log a warning in parseLogLevel. - this.logLevel = defaultLogLevel; - this.logLevel = - parseLogLevel(options.logLevel, 'ClientOptions.logLevel', this) ?? - parseLogLevel(readEnv('OPENAI_LOG'), "process.env['OPENAI_LOG']", this) ?? - defaultLogLevel; - this.fetchOptions = options.fetchOptions; - this.maxRetries = options.maxRetries ?? 2; - this.fetch = options.fetch ?? getDefaultFetch(); - __classPrivateFieldSet(this, _OpenAI_encoder, FallbackEncoder); - this._options = options; - this.apiKey = typeof apiKey === 'string' ? apiKey : 'Missing Key'; - this.organization = organization; - this.project = project; - this.webhookSecret = webhookSecret; - } - /** - * Create a new client instance re-using the same options given to the current client with optional overriding. - */ - withOptions(options) { - const client = new this.constructor({ - ...this._options, - baseURL: this.baseURL, - maxRetries: this.maxRetries, - timeout: this.timeout, - logger: this.logger, - logLevel: this.logLevel, - fetch: this.fetch, - fetchOptions: this.fetchOptions, - apiKey: this.apiKey, - organization: this.organization, - project: this.project, - webhookSecret: this.webhookSecret, - ...options, - }); - return client; - } - defaultQuery() { - return this._options.defaultQuery; - } - validateHeaders({ values, nulls }) { - return; - } - async authHeaders(opts) { - return buildHeaders([{ Authorization: `Bearer ${this.apiKey}` }]); - } - stringifyQuery(query) { - return stringify(query, { arrayFormat: 'brackets' }); - } - getUserAgent() { - return `${this.constructor.name}/JS ${VERSION}`; - } - defaultIdempotencyKey() { - return `stainless-node-retry-${uuid4()}`; - } - makeStatusError(status, error, message, headers) { - return APIError.generate(status, error, message, headers); - } - async _callApiKey() { - const apiKey = this._options.apiKey; - if (typeof apiKey !== 'function') - return false; - let token; - try { - token = await apiKey(); - } - catch (err) { - if (err instanceof OpenAIError) - throw err; - throw new OpenAIError(`Failed to get token from 'apiKey' function: ${err.message}`, - // @ts-ignore - { cause: err }); - } - if (typeof token !== 'string' || !token) { - throw new OpenAIError(`Expected 'apiKey' function argument to return a string but it returned ${token}`); - } - this.apiKey = token; - return true; - } - buildURL(path, query, defaultBaseURL) { - const baseURL = (!__classPrivateFieldGet(this, _OpenAI_instances, "m", _OpenAI_baseURLOverridden).call(this) && defaultBaseURL) || this.baseURL; - const url = isAbsoluteURL(path) ? - new URL(path) - : new URL(baseURL + (baseURL.endsWith('/') && path.startsWith('/') ? path.slice(1) : path)); - const defaultQuery = this.defaultQuery(); - if (!isEmptyObj(defaultQuery)) { - query = { ...defaultQuery, ...query }; - } - if (typeof query === 'object' && query && !Array.isArray(query)) { - url.search = this.stringifyQuery(query); - } - return url.toString(); - } - /** - * Used as a callback for mutating the given `FinalRequestOptions` object. - */ - async prepareOptions(options) { - await this._callApiKey(); - } - /** - * Used as a callback for mutating the given `RequestInit` object. - * - * This is useful for cases where you want to add certain headers based off of - * the request properties, e.g. `method` or `url`. - */ - async prepareRequest(request, { url, options }) { } - get(path, opts) { - return this.methodRequest('get', path, opts); - } - post(path, opts) { - return this.methodRequest('post', path, opts); - } - patch(path, opts) { - return this.methodRequest('patch', path, opts); - } - put(path, opts) { - return this.methodRequest('put', path, opts); - } - delete(path, opts) { - return this.methodRequest('delete', path, opts); - } - methodRequest(method, path, opts) { - return this.request(Promise.resolve(opts).then((opts) => { - return { method, path, ...opts }; - })); - } - request(options, remainingRetries = null) { - return new APIPromise(this, this.makeRequest(options, remainingRetries, undefined)); - } - async makeRequest(optionsInput, retriesRemaining, retryOfRequestLogID) { - const options = await optionsInput; - const maxRetries = options.maxRetries ?? this.maxRetries; - if (retriesRemaining == null) { - retriesRemaining = maxRetries; - } - await this.prepareOptions(options); - const { req, url, timeout } = await this.buildRequest(options, { - retryCount: maxRetries - retriesRemaining, - }); - await this.prepareRequest(req, { url, options }); - /** Not an API request ID, just for correlating local log entries. */ - const requestLogID = 'log_' + ((Math.random() * (1 << 24)) | 0).toString(16).padStart(6, '0'); - const retryLogStr = retryOfRequestLogID === undefined ? '' : `, retryOf: ${retryOfRequestLogID}`; - const startTime = Date.now(); - loggerFor(this).debug(`[${requestLogID}] sending request`, formatRequestDetails({ - retryOfRequestLogID, - method: options.method, - url, - options, - headers: req.headers, - })); - if (options.signal?.aborted) { - throw new APIUserAbortError(); - } - const controller = new AbortController(); - const response = await this.fetchWithTimeout(url, req, timeout, controller).catch(castToError); - const headersTime = Date.now(); - if (response instanceof globalThis.Error) { - const retryMessage = `retrying, ${retriesRemaining} attempts remaining`; - if (options.signal?.aborted) { - throw new APIUserAbortError(); - } - // detect native connection timeout errors - // deno throws "TypeError: error sending request for url (https://example/): client error (Connect): tcp connect error: Operation timed out (os error 60): Operation timed out (os error 60)" - // undici throws "TypeError: fetch failed" with cause "ConnectTimeoutError: Connect Timeout Error (attempted address: example:443, timeout: 1ms)" - // others do not provide enough information to distinguish timeouts from other connection errors - const isTimeout = isAbortError(response) || - /timed? ?out/i.test(String(response) + ('cause' in response ? String(response.cause) : '')); - if (retriesRemaining) { - loggerFor(this).info(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} - ${retryMessage}`); - loggerFor(this).debug(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (${retryMessage})`, formatRequestDetails({ - retryOfRequestLogID, - url, - durationMs: headersTime - startTime, - message: response.message, - })); - return this.retryRequest(options, retriesRemaining, retryOfRequestLogID ?? requestLogID); - } - loggerFor(this).info(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} - error; no more retries left`); - loggerFor(this).debug(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (error; no more retries left)`, formatRequestDetails({ - retryOfRequestLogID, - url, - durationMs: headersTime - startTime, - message: response.message, - })); - if (isTimeout) { - throw new APIConnectionTimeoutError(); - } - throw new APIConnectionError({ cause: response }); - } - const specialHeaders = [...response.headers.entries()] - .filter(([name]) => name === 'x-request-id') - .map(([name, value]) => ', ' + name + ': ' + JSON.stringify(value)) - .join(''); - const responseInfo = `[${requestLogID}${retryLogStr}${specialHeaders}] ${req.method} ${url} ${response.ok ? 'succeeded' : 'failed'} with status ${response.status} in ${headersTime - startTime}ms`; - if (!response.ok) { - const shouldRetry = await this.shouldRetry(response); - if (retriesRemaining && shouldRetry) { - const retryMessage = `retrying, ${retriesRemaining} attempts remaining`; - // We don't need the body of this response. - await CancelReadableStream(response.body); - loggerFor(this).info(`${responseInfo} - ${retryMessage}`); - loggerFor(this).debug(`[${requestLogID}] response error (${retryMessage})`, formatRequestDetails({ - retryOfRequestLogID, - url: response.url, - status: response.status, - headers: response.headers, - durationMs: headersTime - startTime, - })); - return this.retryRequest(options, retriesRemaining, retryOfRequestLogID ?? requestLogID, response.headers); - } - const retryMessage = shouldRetry ? `error; no more retries left` : `error; not retryable`; - loggerFor(this).info(`${responseInfo} - ${retryMessage}`); - const errText = await response.text().catch((err) => castToError(err).message); - const errJSON = safeJSON(errText); - const errMessage = errJSON ? undefined : errText; - loggerFor(this).debug(`[${requestLogID}] response error (${retryMessage})`, formatRequestDetails({ - retryOfRequestLogID, - url: response.url, - status: response.status, - headers: response.headers, - message: errMessage, - durationMs: Date.now() - startTime, - })); - const err = this.makeStatusError(response.status, errJSON, errMessage, response.headers); - throw err; - } - loggerFor(this).info(responseInfo); - loggerFor(this).debug(`[${requestLogID}] response start`, formatRequestDetails({ - retryOfRequestLogID, - url: response.url, - status: response.status, - headers: response.headers, - durationMs: headersTime - startTime, - })); - return { response, options, controller, requestLogID, retryOfRequestLogID, startTime }; - } - getAPIList(path, Page, opts) { - return this.requestAPIList(Page, { method: 'get', path, ...opts }); - } - requestAPIList(Page, options) { - const request = this.makeRequest(options, null, undefined); - return new PagePromise(this, request, Page); - } - async fetchWithTimeout(url, init, ms, controller) { - const { signal, method, ...options } = init || {}; - if (signal) - signal.addEventListener('abort', () => controller.abort()); - const timeout = setTimeout(() => controller.abort(), ms); - const isReadableBody = (globalThis.ReadableStream && options.body instanceof globalThis.ReadableStream) || - (typeof options.body === 'object' && options.body !== null && Symbol.asyncIterator in options.body); - const fetchOptions = { - signal: controller.signal, - ...(isReadableBody ? { duplex: 'half' } : {}), - method: 'GET', - ...options, - }; - if (method) { - // Custom methods like 'patch' need to be uppercased - // See https://github.com/nodejs/undici/issues/2294 - fetchOptions.method = method.toUpperCase(); - } - try { - // use undefined this binding; fetch errors if bound to something else in browser/cloudflare - return await this.fetch.call(undefined, url, fetchOptions); - } - finally { - clearTimeout(timeout); - } - } - async shouldRetry(response) { - // Note this is not a standard header. - const shouldRetryHeader = response.headers.get('x-should-retry'); - // If the server explicitly says whether or not to retry, obey. - if (shouldRetryHeader === 'true') - return true; - if (shouldRetryHeader === 'false') - return false; - // Retry on request timeouts. - if (response.status === 408) - return true; - // Retry on lock timeouts. - if (response.status === 409) - return true; - // Retry on rate limits. - if (response.status === 429) - return true; - // Retry internal errors. - if (response.status >= 500) - return true; - return false; - } - async retryRequest(options, retriesRemaining, requestLogID, responseHeaders) { - let timeoutMillis; - // Note the `retry-after-ms` header may not be standard, but is a good idea and we'd like proactive support for it. - const retryAfterMillisHeader = responseHeaders?.get('retry-after-ms'); - if (retryAfterMillisHeader) { - const timeoutMs = parseFloat(retryAfterMillisHeader); - if (!Number.isNaN(timeoutMs)) { - timeoutMillis = timeoutMs; - } - } - // About the Retry-After header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After - const retryAfterHeader = responseHeaders?.get('retry-after'); - if (retryAfterHeader && !timeoutMillis) { - const timeoutSeconds = parseFloat(retryAfterHeader); - if (!Number.isNaN(timeoutSeconds)) { - timeoutMillis = timeoutSeconds * 1000; - } - else { - timeoutMillis = Date.parse(retryAfterHeader) - Date.now(); - } - } - // If the API asks us to wait a certain amount of time (and it's a reasonable amount), - // just do what it says, but otherwise calculate a default - if (!(timeoutMillis && 0 <= timeoutMillis && timeoutMillis < 60 * 1000)) { - const maxRetries = options.maxRetries ?? this.maxRetries; - timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries); - } - await sleep(timeoutMillis); - return this.makeRequest(options, retriesRemaining - 1, requestLogID); - } - calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries) { - const initialRetryDelay = 0.5; - const maxRetryDelay = 8.0; - const numRetries = maxRetries - retriesRemaining; - // Apply exponential backoff, but not more than the max. - const sleepSeconds = Math.min(initialRetryDelay * Math.pow(2, numRetries), maxRetryDelay); - // Apply some jitter, take up to at most 25 percent of the retry time. - const jitter = 1 - Math.random() * 0.25; - return sleepSeconds * jitter * 1000; - } - async buildRequest(inputOptions, { retryCount = 0 } = {}) { - const options = { ...inputOptions }; - const { method, path, query, defaultBaseURL } = options; - const url = this.buildURL(path, query, defaultBaseURL); - if ('timeout' in options) - validatePositiveInteger('timeout', options.timeout); - options.timeout = options.timeout ?? this.timeout; - const { bodyHeaders, body } = this.buildBody({ options }); - const reqHeaders = await this.buildHeaders({ options: inputOptions, method, bodyHeaders, retryCount }); - const req = { - method, - headers: reqHeaders, - ...(options.signal && { signal: options.signal }), - ...(globalThis.ReadableStream && - body instanceof globalThis.ReadableStream && { duplex: 'half' }), - ...(body && { body }), - ...(this.fetchOptions ?? {}), - ...(options.fetchOptions ?? {}), - }; - return { req, url, timeout: options.timeout }; - } - async buildHeaders({ options, method, bodyHeaders, retryCount, }) { - let idempotencyHeaders = {}; - if (this.idempotencyHeader && method !== 'get') { - if (!options.idempotencyKey) - options.idempotencyKey = this.defaultIdempotencyKey(); - idempotencyHeaders[this.idempotencyHeader] = options.idempotencyKey; - } - const headers = buildHeaders([ - idempotencyHeaders, - { - Accept: 'application/json', - 'User-Agent': this.getUserAgent(), - 'X-Stainless-Retry-Count': String(retryCount), - ...(options.timeout ? { 'X-Stainless-Timeout': String(Math.trunc(options.timeout / 1000)) } : {}), - ...getPlatformHeaders(), - 'OpenAI-Organization': this.organization, - 'OpenAI-Project': this.project, - }, - await this.authHeaders(options), - this._options.defaultHeaders, - bodyHeaders, - options.headers, - ]); - this.validateHeaders(headers); - return headers.values; - } - buildBody({ options: { body, headers: rawHeaders } }) { - if (!body) { - return { bodyHeaders: undefined, body: undefined }; - } - const headers = buildHeaders([rawHeaders]); - if ( - // Pass raw type verbatim - ArrayBuffer.isView(body) || - body instanceof ArrayBuffer || - body instanceof DataView || - (typeof body === 'string' && - // Preserve legacy string encoding behavior for now - headers.values.has('content-type')) || - // `Blob` is superset of `File` - (globalThis.Blob && body instanceof globalThis.Blob) || - // `FormData` -> `multipart/form-data` - body instanceof FormData || - // `URLSearchParams` -> `application/x-www-form-urlencoded` - body instanceof URLSearchParams || - // Send chunked stream (each chunk has own `length`) - (globalThis.ReadableStream && body instanceof globalThis.ReadableStream)) { - return { bodyHeaders: undefined, body: body }; - } - else if (typeof body === 'object' && - (Symbol.asyncIterator in body || - (Symbol.iterator in body && 'next' in body && typeof body.next === 'function'))) { - return { bodyHeaders: undefined, body: ReadableStreamFrom(body) }; - } - else { - return __classPrivateFieldGet(this, _OpenAI_encoder, "f").call(this, { body, headers }); - } - } -} -_a = OpenAI, _OpenAI_encoder = new WeakMap(), _OpenAI_instances = new WeakSet(), _OpenAI_baseURLOverridden = function _OpenAI_baseURLOverridden() { - return this.baseURL !== 'https://api.openai.com/v1'; -}; -OpenAI.OpenAI = _a; -OpenAI.DEFAULT_TIMEOUT = 600000; // 10 minutes -OpenAI.OpenAIError = OpenAIError; -OpenAI.APIError = APIError; -OpenAI.APIConnectionError = APIConnectionError; -OpenAI.APIConnectionTimeoutError = APIConnectionTimeoutError; -OpenAI.APIUserAbortError = APIUserAbortError; -OpenAI.NotFoundError = NotFoundError; -OpenAI.ConflictError = ConflictError; -OpenAI.RateLimitError = RateLimitError; -OpenAI.BadRequestError = BadRequestError; -OpenAI.AuthenticationError = AuthenticationError; -OpenAI.InternalServerError = InternalServerError; -OpenAI.PermissionDeniedError = PermissionDeniedError; -OpenAI.UnprocessableEntityError = UnprocessableEntityError; -OpenAI.InvalidWebhookSignatureError = InvalidWebhookSignatureError; -OpenAI.toFile = toFile; -OpenAI.Completions = Completions; -OpenAI.Chat = Chat; -OpenAI.Embeddings = Embeddings; -OpenAI.Files = Files$1; -OpenAI.Images = Images; -OpenAI.Audio = Audio; -OpenAI.Moderations = Moderations; -OpenAI.Models = Models; -OpenAI.FineTuning = FineTuning; -OpenAI.Graders = Graders; -OpenAI.VectorStores = VectorStores; -OpenAI.Webhooks = Webhooks; -OpenAI.Beta = Beta; -OpenAI.Batches = Batches; -OpenAI.Uploads = Uploads; -OpenAI.Responses = Responses; -OpenAI.Realtime = Realtime; -OpenAI.Conversations = Conversations; -OpenAI.Evals = Evals; -OpenAI.Containers = Containers; - -// biome-ignore-all lint: generated file -/* eslint-disable */ - -var __create = Object.create; -var __defProp = Object.defineProperty; -var __getOwnPropDesc = Object.getOwnPropertyDescriptor; -var __getOwnPropNames = Object.getOwnPropertyNames; -var __getProtoOf = Object.getPrototypeOf; -var __hasOwnProp = Object.prototype.hasOwnProperty; -var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); -var __commonJS = (cb, mod) => function __require() { - return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; -}; -var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; -}; -var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( - // If the importer is in node compatibility mode or this is not an ESM - // file that has been converted to a CommonJS file using a Babel- - // compatible transform (i.e. "__esModule" has not been set), then set - // "default" to the CommonJS "module.exports" for node compatibility. - __defProp(target, "default", { value: mod, enumerable: true }) , - mod -)); - -// ../../node_modules/.pnpm/lodash.chunk@4.2.0/node_modules/lodash.chunk/index.js -var require_lodash = __commonJS({ - "../../node_modules/.pnpm/lodash.chunk@4.2.0/node_modules/lodash.chunk/index.js"(exports, module) { - var INFINITY = 1 / 0; - var MAX_SAFE_INTEGER = 9007199254740991; - var MAX_INTEGER = 17976931348623157e292; - var NAN = 0 / 0; - var funcTag = "[object Function]"; - var genTag = "[object GeneratorFunction]"; - var symbolTag = "[object Symbol]"; - var reTrim = /^\s+|\s+$/g; - var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; - var reIsBinary = /^0b[01]+$/i; - var reIsOctal = /^0o[0-7]+$/i; - var reIsUint = /^(?:0|[1-9]\d*)$/; - var freeParseInt = parseInt; - var objectProto = Object.prototype; - var objectToString = objectProto.toString; - var nativeCeil = Math.ceil; - var nativeMax = Math.max; - function baseSlice(array, start, end) { - var index = -1, length = array.length; - if (start < 0) { - start = -start > length ? 0 : length + start; - } - end = end > length ? length : end; - if (end < 0) { - end += length; - } - length = start > end ? 0 : end - start >>> 0; - start >>>= 0; - var result = Array(length); - while (++index < length) { - result[index] = array[index + start]; - } - return result; - } - __name(baseSlice, "baseSlice"); - function isIndex(value, length) { - length = length == null ? MAX_SAFE_INTEGER : length; - return !!length && (typeof value == "number" || reIsUint.test(value)) && value > -1 && value % 1 == 0 && value < length; - } - __name(isIndex, "isIndex"); - function isIterateeCall(value, index, object) { - if (!isObject(object)) { - return false; - } - var type = typeof index; - if (type == "number" ? isArrayLike(object) && isIndex(index, object.length) : type == "string" && index in object) { - return eq(object[index], value); - } - return false; - } - __name(isIterateeCall, "isIterateeCall"); - function chunk2(array, size, guard) { - if (guard ? isIterateeCall(array, size, guard) : size === void 0) { - size = 1; - } else { - size = nativeMax(toInteger(size), 0); - } - var length = array ? array.length : 0; - if (!length || size < 1) { - return []; - } - var index = 0, resIndex = 0, result = Array(nativeCeil(length / size)); - while (index < length) { - result[resIndex++] = baseSlice(array, index, index += size); - } - return result; - } - __name(chunk2, "chunk"); - function eq(value, other) { - return value === other || value !== value && other !== other; - } - __name(eq, "eq"); - function isArrayLike(value) { - return value != null && isLength(value.length) && !isFunction(value); - } - __name(isArrayLike, "isArrayLike"); - function isFunction(value) { - var tag = isObject(value) ? objectToString.call(value) : ""; - return tag == funcTag || tag == genTag; - } - __name(isFunction, "isFunction"); - function isLength(value) { - return typeof value == "number" && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; - } - __name(isLength, "isLength"); - function isObject(value) { - var type = typeof value; - return !!value && (type == "object" || type == "function"); - } - __name(isObject, "isObject"); - function isObjectLike(value) { - return !!value && typeof value == "object"; - } - __name(isObjectLike, "isObjectLike"); - function isSymbol(value) { - return typeof value == "symbol" || isObjectLike(value) && objectToString.call(value) == symbolTag; - } - __name(isSymbol, "isSymbol"); - function toFinite(value) { - if (!value) { - return value === 0 ? value : 0; - } - value = toNumber(value); - if (value === INFINITY || value === -INFINITY) { - var sign = value < 0 ? -1 : 1; - return sign * MAX_INTEGER; - } - return value === value ? value : 0; - } - __name(toFinite, "toFinite"); - function toInteger(value) { - var result = toFinite(value), remainder = result % 1; - return result === result ? remainder ? result - remainder : result : 0; - } - __name(toInteger, "toInteger"); - function toNumber(value) { - if (typeof value == "number") { - return value; - } - if (isSymbol(value)) { - return NAN; - } - if (isObject(value)) { - var other = typeof value.valueOf == "function" ? value.valueOf() : value; - value = isObject(other) ? other + "" : other; - } - if (typeof value != "string") { - return value === 0 ? value : +value; - } - value = value.replace(reTrim, ""); - var isBinary = reIsBinary.test(value); - return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value; - } - __name(toNumber, "toNumber"); - module.exports = chunk2; - } -}); -async function __builtin_response_array_buffer(res) { - return res.arrayBuffer(); -} -__name(__builtin_response_array_buffer, "__builtin_response_array_buffer"); -async function __builtin_response_json(res) { - return res.json(); -} -__name(__builtin_response_json, "__builtin_response_json"); -async function __builtin_response_text(res) { - return res.text(); -} -__name(__builtin_response_text, "__builtin_response_text"); -registerStepFunction("__builtin_response_array_buffer", __builtin_response_array_buffer); -registerStepFunction("__builtin_response_json", __builtin_response_json); -registerStepFunction("__builtin_response_text", __builtin_response_text); -function parseDurationToDate(param) { - if (typeof param === "string") { - const durationMs = ms(param); - if (typeof durationMs !== "number" || durationMs < 0) { - throw new Error(`Invalid duration: "${param}". Expected a valid duration string like "1s", "1m", "1h", etc.`); - } - return new Date(Date.now() + durationMs); - } else if (typeof param === "number") { - if (param < 0 || !Number.isFinite(param)) { - throw new Error(`Invalid duration: ${param}. Expected a non-negative finite number of milliseconds.`); - } - return new Date(Date.now() + param); - } else if (param instanceof Date || param && typeof param === "object" && typeof param.getTime === "function") { - return param instanceof Date ? param : new Date(param.getTime()); - } else { - throw new Error(`Invalid duration parameter. Expected a duration string, number (milliseconds), or Date object.`); - } -} -__name(parseDurationToDate, "parseDurationToDate"); - -// ../../packages/errors/dist/index.js -function isError(value) { - return typeof value === "object" && value !== null && "name" in value && "message" in value; -} -__name(isError, "isError"); -var FatalError = class extends Error { - static { - __name(this, "FatalError"); - } - fatal = true; - constructor(message) { - super(message); - this.name = "FatalError"; - } - static is(value) { - return isError(value) && value.name === "FatalError"; - } -}; -var RetryableError = class extends Error { - static { - __name(this, "RetryableError"); - } - /** - * The Date when the step should be retried. - */ - retryAfter; - constructor(message, options = {}) { - super(message); - this.name = "RetryableError"; - if (options.retryAfter !== void 0) { - this.retryAfter = parseDurationToDate(options.retryAfter); - } else { - this.retryAfter = new Date(Date.now() + 1e3); - } - } - static is(value) { - return isError(value) && value.name === "RetryableError"; - } -}; -async function fetch$1(...args) { - return globalThis.fetch(...args); -} -__name(fetch$1, "fetch"); -registerStepFunction("step//packages/workflow/dist/stdlib.js//fetch", fetch$1); - -// ../example/workflows/99_e2e.ts -async function add(a, b) { - return a + b; -} -__name(add, "add"); -async function randomDelay(v) { - await new Promise((resolve) => setTimeout(resolve, Math.random() * 3e3)); - return v.toUpperCase(); -} -__name(randomDelay, "randomDelay"); -async function specificDelay(delay, v) { - await new Promise((resolve) => setTimeout(resolve, delay)); - return v.toUpperCase(); -} -__name(specificDelay, "specificDelay"); -async function stepThatFails() { - throw new FatalError("step failed"); -} -__name(stepThatFails, "stepThatFails"); -async function genReadableStream() { - const encoder = new TextEncoder(); - return new ReadableStream({ - async start(controller) { - for (let i = 0; i < 10; i++) { - console.log("enqueueing", i); - controller.enqueue(encoder.encode(`${i} -`)); - await new Promise((resolve) => setTimeout(resolve, 1e3)); - } - console.log("closing controller"); - controller.close(); - } - }); -} -__name(genReadableStream, "genReadableStream"); -async function sendWebhookResponse(req) { - const body = await req.text(); - await req.respondWith(new Response("Hello from webhook!")); - return body; -} -__name(sendWebhookResponse, "sendWebhookResponse"); -async function nullByteStep() { - return "null byte \0"; -} -__name(nullByteStep, "nullByteStep"); -async function stepWithMetadata() { - const stepMetadata = getStepMetadata(); - const workflowMetadata = getWorkflowMetadata(); - return { - stepMetadata, - workflowMetadata - }; -} -__name(stepWithMetadata, "stepWithMetadata"); -async function stepWithOutputStreamBinary(writable, text) { - const writer = writable.getWriter(); - await writer.write(new TextEncoder().encode(text)); - writer.releaseLock(); -} -__name(stepWithOutputStreamBinary, "stepWithOutputStreamBinary"); -async function stepWithOutputStreamObject(writable, obj) { - const writer = writable.getWriter(); - await writer.write(obj); - writer.releaseLock(); -} -__name(stepWithOutputStreamObject, "stepWithOutputStreamObject"); -async function stepCloseOutputStream(writable) { - await writable.close(); -} -__name(stepCloseOutputStream, "stepCloseOutputStream"); -async function stepWithOutputStreamInsideStep(text) { - const writable = getWritable(); - const writer = writable.getWriter(); - await writer.write(new TextEncoder().encode(text)); - writer.releaseLock(); -} -__name(stepWithOutputStreamInsideStep, "stepWithOutputStreamInsideStep"); -async function stepWithNamedOutputStreamInsideStep(namespace, obj) { - const writable = getWritable({ - namespace - }); - const writer = writable.getWriter(); - await writer.write(obj); - writer.releaseLock(); -} -__name(stepWithNamedOutputStreamInsideStep, "stepWithNamedOutputStreamInsideStep"); -async function stepCloseOutputStreamInsideStep(namespace) { - const writable = getWritable({ - namespace - }); - await writable.close(); -} -__name(stepCloseOutputStreamInsideStep, "stepCloseOutputStreamInsideStep"); -async function promiseRaceStressTestDelayStep(dur, resp) { - console.log(`sleep`, resp, `/`, dur); - await new Promise((resolve) => setTimeout(resolve, dur)); - console.log(resp, `done`); - return resp; -} -__name(promiseRaceStressTestDelayStep, "promiseRaceStressTestDelayStep"); -async function stepThatRetriesAndSucceeds() { - const { attempt } = getStepMetadata(); - console.log(`stepThatRetriesAndSucceeds - attempt: ${attempt}`); - if (attempt < 3) { - console.log(`Attempt ${attempt} - throwing error to trigger retry`); - throw new Error(`Failed on attempt ${attempt}`); - } - console.log(`Attempt ${attempt} - succeeding`); - return attempt; -} -__name(stepThatRetriesAndSucceeds, "stepThatRetriesAndSucceeds"); -async function stepThatThrowsRetryableError() { - const { attempt, stepStartedAt } = getStepMetadata(); - if (attempt === 1) { - throw new RetryableError("Retryable error", { - retryAfter: "10s" - }); - } - return { - attempt, - stepStartedAt, - duration: Date.now() - stepStartedAt.getTime() - }; -} -__name(stepThatThrowsRetryableError, "stepThatThrowsRetryableError"); -async function stepWithStepFunctionArg(stepFn) { - const result = await stepFn(10); - return result * 2; -} -__name(stepWithStepFunctionArg, "stepWithStepFunctionArg"); -async function doubleNumber(x) { - return x * 2; -} -__name(doubleNumber, "doubleNumber"); -registerStepFunction("step//example/workflows/99_e2e.ts//add", add); -registerStepFunction("step//example/workflows/99_e2e.ts//randomDelay", randomDelay); -registerStepFunction("step//example/workflows/99_e2e.ts//specificDelay", specificDelay); -registerStepFunction("step//example/workflows/99_e2e.ts//stepThatFails", stepThatFails); -registerStepFunction("step//example/workflows/99_e2e.ts//genReadableStream", genReadableStream); -registerStepFunction("step//example/workflows/99_e2e.ts//sendWebhookResponse", sendWebhookResponse); -registerStepFunction("step//example/workflows/99_e2e.ts//nullByteStep", nullByteStep); -registerStepFunction("step//example/workflows/99_e2e.ts//stepWithMetadata", stepWithMetadata); -registerStepFunction("step//example/workflows/99_e2e.ts//stepWithOutputStreamBinary", stepWithOutputStreamBinary); -registerStepFunction("step//example/workflows/99_e2e.ts//stepWithOutputStreamObject", stepWithOutputStreamObject); -registerStepFunction("step//example/workflows/99_e2e.ts//stepCloseOutputStream", stepCloseOutputStream); -registerStepFunction("step//example/workflows/99_e2e.ts//stepWithOutputStreamInsideStep", stepWithOutputStreamInsideStep); -registerStepFunction("step//example/workflows/99_e2e.ts//stepWithNamedOutputStreamInsideStep", stepWithNamedOutputStreamInsideStep); -registerStepFunction("step//example/workflows/99_e2e.ts//stepCloseOutputStreamInsideStep", stepCloseOutputStreamInsideStep); -registerStepFunction("step//example/workflows/99_e2e.ts//promiseRaceStressTestDelayStep", promiseRaceStressTestDelayStep); -registerStepFunction("step//example/workflows/99_e2e.ts//stepThatRetriesAndSucceeds", stepThatRetriesAndSucceeds); -registerStepFunction("step//example/workflows/99_e2e.ts//stepThatThrowsRetryableError", stepThatThrowsRetryableError); -registerStepFunction("step//example/workflows/99_e2e.ts//stepWithStepFunctionArg", stepWithStepFunctionArg); -registerStepFunction("step//example/workflows/99_e2e.ts//doubleNumber", doubleNumber); -async function delayedMessage(ms2, message) { - console.log(`Sleeping for ${ms2}ms and returning ${message}`); - await new Promise((resolve) => setTimeout(resolve, ms2)); - return `${message} (sent: ${(/* @__PURE__ */ new Date()).toISOString()})`; -} -__name(delayedMessage, "delayedMessage"); -async function add2(a, b) { - console.log(`Adding ${a} and ${b} (sent: ${(/* @__PURE__ */ new Date()).toISOString()})`); - return a + b; -} -__name(add2, "add"); -async function failingStep() { - throw new FatalError(`A failed step (sent: ${(/* @__PURE__ */ new Date()).toISOString()})`); -} -__name(failingStep, "failingStep"); -async function retryableStep() { - const { attempt } = getStepMetadata(); - console.log("retryableStep attempt:", attempt); - if (attempt === 1) { - console.log("Throwing retryable error - this will be retried after 5 seconds"); - throw new RetryableError("Retryable error", { - // Retry after 5 seconds - retryAfter: "5s" - }); - } - console.log("Completing successfully"); - return "Success"; -} -__name(retryableStep, "retryableStep"); -registerStepFunction("step//example/workflows/2_control_flow.ts//delayedMessage", delayedMessage); -registerStepFunction("step//example/workflows/2_control_flow.ts//add", add2); -registerStepFunction("step//example/workflows/2_control_flow.ts//failingStep", failingStep); -registerStepFunction("step//example/workflows/2_control_flow.ts//retryableStep", retryableStep); -async function pow(a) { - console.log("Running step pow with arg:", a); - return a * a; -} -__name(pow, "pow"); -registerStepFunction("step//nitro-v3/workflows/0_demo.ts//pow", pow); -async function add3(a, b) { - return a + b; -} -__name(add3, "add"); -registerStepFunction("step//example/workflows/98_duplicate_case.ts//add", add3); - -// ../example/workflows/6_batching.ts -__toESM(require_lodash()); -async function logItem(item) { - console.log(item, Date.now()); -} -__name(logItem, "logItem"); -async function processItems(items) { - await Promise.all(items.map(async (item) => { - console.log(item, Date.now()); - })); -} -__name(processItems, "processItems"); -registerStepFunction("step//example/workflows/6_batching.ts//logItem", logItem); -registerStepFunction("step//example/workflows/6_batching.ts//processItems", processItems); -async function add4(a, b) { - if (Math.random() < 0.5) { - throw new Error("Retryable error"); - } - if (Math.random() < 0.05) { - throw new FatalError("We're cooked yo!"); - } - return a + b; -} -__name(add4, "add"); -registerStepFunction("step//example/workflows/1_simple.ts//add", add4); - -// ../example/workflows/5_hooks.ts -async function stepWithGetMetadata() { - const ctx = getStepMetadata(); - console.log("step context", ctx); - if (Math.random() < 0.5) { - throw new Error("Retryable error"); - } -} -__name(stepWithGetMetadata, "stepWithGetMetadata"); -async function initiateOpenAIResponse() { - const openai = new OpenAI(); - const resp = await openai.responses.create({ - model: "o3", - input: "Write a very long novel about otters in space.", - background: true - }); - console.log("OpenAI response:", resp); - return resp.id; -} -__name(initiateOpenAIResponse, "initiateOpenAIResponse"); -async function getOpenAIResponse(respId) { - const openai = new OpenAI(); - const resp = await openai.responses.retrieve(respId); - return resp.output_text; -} -__name(getOpenAIResponse, "getOpenAIResponse"); -registerStepFunction("step//example/workflows/5_hooks.ts//stepWithGetMetadata", stepWithGetMetadata); -registerStepFunction("step//example/workflows/5_hooks.ts//initiateOpenAIResponse", initiateOpenAIResponse); -registerStepFunction("step//example/workflows/5_hooks.ts//getOpenAIResponse", getOpenAIResponse); -async function getWeatherInformation({ city }) { - console.log("Getting the weather for city: ", city); - if (Math.random() < 0.5) { - throw new Error("Retryable error"); - } - if (Math.random() < 0.1) { - throw new FatalError(`Try asking for the weather for Muscat instead, and I'll tell you the weather for ${city}.`); - } - const weatherOptions = [ - "sunny", - "cloudy", - "rainy", - "snowy", - "windy" - ]; - return weatherOptions[Math.floor(Math.random() * weatherOptions.length)]; -} -__name(getWeatherInformation, "getWeatherInformation"); -registerStepFunction("step//example/workflows/4_ai.ts//getWeatherInformation", getWeatherInformation); -async function genStream() { - const stream = new ReadableStream({ - async start(controller) { - const encoder = new TextEncoder(); - for (let i = 0; i < 30; i++) { - const chunk2 = encoder.encode(`${i} -`); - controller.enqueue(chunk2); - console.log(`Enqueued number: ${i}`); - await new Promise((resolve) => setTimeout(resolve, 2500)); - } - controller.close(); - } - }); - return stream; -} -__name(genStream, "genStream"); -async function consumeStreams(...streams) { - const parts = []; - console.log("Consuming streams", streams); - await Promise.all(streams.map(async (s, i) => { - const reader = s.getReader(); - while (true) { - const result = await reader.read(); - if (result.done) break; - console.log(`Received ${result.value.length} bytes from stream ${i}: ${JSON.stringify(new TextDecoder().decode(result.value))}`); - parts.push(result.value); - } - })); - return Buffer.concat(parts).toString("utf8"); -} -__name(consumeStreams, "consumeStreams"); -registerStepFunction("step//example/workflows/3_streams.ts//genStream", genStream); -registerStepFunction("step//example/workflows/3_streams.ts//consumeStreams", consumeStreams); -async function createUser(email) { - console.log(`Creating a new user with email: ${email}`); - return { - id: crypto.randomUUID(), - email - }; -} -__name(createUser, "createUser"); -async function sendWelcomeEmail(user) { - console.log(`Sending welcome email to user: ${user.id}`); -} -__name(sendWelcomeEmail, "sendWelcomeEmail"); -async function sendOnboardingEmail(user, callback) { - console.log(`Sending onboarding email to user: ${user.id}`); - console.log(`Click this link to resolve the webhook: ${callback}`); -} -__name(sendOnboardingEmail, "sendOnboardingEmail"); -registerStepFunction("step//example/workflows/7_full.ts//createUser", createUser); -registerStepFunction("step//example/workflows/7_full.ts//sendWelcomeEmail", sendWelcomeEmail); -registerStepFunction("step//example/workflows/7_full.ts//sendOnboardingEmail", sendOnboardingEmail); - -async function normalizeRequestConverter(request) { - const options = { - method: request.method, - headers: new Headers(request.headers) - }; - if (!['GET', 'HEAD', 'OPTIONS', 'TRACE', 'CONNECT'].includes(request.method)) { - options.body = await request.arrayBuffer(); - } - return new Request(request.url, options); -} - -const POST = async ({request}) => { - const normalRequest = await normalizeRequestConverter(request); - return stepEntrypoint(normalRequest); -}; - -const prerender = false; - -const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - POST, - prerender -}, Symbol.toStringTag, { value: 'Module' })); - -const page = () => _page; - -export { page }; diff --git a/workbench/astro/dist/server/pages/.well-known/workflow/v1/webhook/_token_.astro.mjs b/workbench/astro/dist/server/pages/.well-known/workflow/v1/webhook/_token_.astro.mjs deleted file mode 100644 index 20d205d82..000000000 --- a/workbench/astro/dist/server/pages/.well-known/workflow/v1/webhook/_token_.astro.mjs +++ /dev/null @@ -1,67 +0,0 @@ -import '../../../../../chunks/index_ePTMDSOu.mjs'; -import 'ms'; -import '@jridgewell/sourcemap-codec'; -import { r as resumeWebhook } from '../../../../../chunks/resume-hook_BHshEMMl.mjs'; -export { renderers } from '../../../../../renderers.mjs'; - -process.on("unhandledRejection", (reason) => { if (reason !== undefined) console.error("Unhandled rejection detected", reason); }); - -async function handler(request, token) { - - if (!token) { - return new Response('Missing token', { status: 400 }); - } - - try { - const response = await resumeWebhook(token, request); - return response; - } catch (error) { - // TODO: differentiate between invalid token and other errors - console.error('Error during resumeWebhook', error); - return new Response(null, { status: 404 }); - } -} - - -async function normalizeRequestConverter(request) { - const options = { - method: request.method, - headers: new Headers(request.headers) - }; - if (!['GET', 'HEAD', 'OPTIONS', 'TRACE', 'CONNECT'].includes(request.method)) { - options.body = await request.arrayBuffer(); - } - return new Request(request.url, options); -} - -const createHandler = (method) => async ({ request, params, platform }) => { - const normalRequest = await normalizeRequestConverter(request); - const response = await handler(normalRequest, params.token); - return response; -}; - -const GET = createHandler(); -const POST = createHandler(); -const PUT = createHandler(); -const PATCH = createHandler(); -const DELETE = createHandler(); -const HEAD = createHandler(); -const OPTIONS = createHandler(); - -const prerender = false; - -const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - DELETE, - GET, - HEAD, - OPTIONS, - PATCH, - POST, - PUT, - prerender -}, Symbol.toStringTag, { value: 'Module' })); - -const page = () => _page; - -export { page }; diff --git a/workbench/astro/dist/server/pages/_image.astro.mjs b/workbench/astro/dist/server/pages/_image.astro.mjs deleted file mode 100644 index 0f11d9345..000000000 --- a/workbench/astro/dist/server/pages/_image.astro.mjs +++ /dev/null @@ -1,2 +0,0 @@ -export { a as page } from '../chunks/node_C2n6Z2oQ.mjs'; -export { renderers } from '../renderers.mjs'; diff --git a/workbench/astro/dist/server/pages/api/hook.astro.mjs b/workbench/astro/dist/server/pages/api/hook.astro.mjs deleted file mode 100644 index c5ff330ed..000000000 --- a/workbench/astro/dist/server/pages/api/hook.astro.mjs +++ /dev/null @@ -1,34 +0,0 @@ -import '../../chunks/index_ePTMDSOu.mjs'; -import 'ms'; -import '@jridgewell/sourcemap-codec'; -import { g as getHookByToken, a as resumeHook } from '../../chunks/resume-hook_BHshEMMl.mjs'; -export { renderers } from '../../renderers.mjs'; - -const POST = async ({ request }) => { - const { token, data } = await request.json(); - let hook; - try { - hook = await getHookByToken(token); - console.log("hook", hook); - } catch (error) { - console.log("error during getHookByToken", error); - return Response.json(null, { status: 404 }); - } - await resumeHook(hook.token, { - ...data, - // @ts-expect-error metadata is not typed - customData: hook.metadata?.customData - }); - return Response.json(hook); -}; -const prerender = false; - -const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - POST, - prerender -}, Symbol.toStringTag, { value: 'Module' })); - -const page = () => _page; - -export { page }; diff --git a/workbench/astro/dist/server/pages/api/test-direct-step-call.astro.mjs b/workbench/astro/dist/server/pages/api/test-direct-step-call.astro.mjs deleted file mode 100644 index 0843ea870..000000000 --- a/workbench/astro/dist/server/pages/api/test-direct-step-call.astro.mjs +++ /dev/null @@ -1,22 +0,0 @@ -import { a as add } from '../../chunks/99_e2e_DTaFFPMr.mjs'; -export { renderers } from '../../renderers.mjs'; - -async function POST({ request }) { - const body = await request.json(); - const { x, y } = body; - console.log(`Calling step function directly with x=${x}, y=${y}`); - const result = await add(x, y); - console.log(`add(${x}, ${y}) = ${result}`); - return Response.json({ result }); -} -const prerender = false; - -const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - POST, - prerender -}, Symbol.toStringTag, { value: 'Module' })); - -const page = () => _page; - -export { page }; diff --git a/workbench/astro/dist/server/pages/api/trigger.astro.mjs b/workbench/astro/dist/server/pages/api/trigger.astro.mjs deleted file mode 100644 index d05c287d0..000000000 --- a/workbench/astro/dist/server/pages/api/trigger.astro.mjs +++ /dev/null @@ -1,341 +0,0 @@ -import { R as Run, g as getRun } from '../../chunks/runtime_CxdH0OC2.mjs'; -import { w as waitedUntil, e as WorkflowRuntimeError, t as trace, o as WorkflowOperation, l as WorkflowName, p as WorkflowArgumentsCount, c as getWorld, q as dehydrateWorkflowArguments, s as serializeTraceCarrier, k as functionsExports, D as DeploymentId, u as WorkflowRunStatus, f as WorkflowRunId, v as hydrateWorkflowArguments, x as WorkflowRunNotCompletedError, y as WorkflowRunFailedError } from '../../chunks/index_ePTMDSOu.mjs'; -import { w as workflow_99_e2e } from '../../chunks/99_e2e_DTaFFPMr.mjs'; -export { renderers } from '../../renderers.mjs'; - -async function start(workflow, argsOrOptions, options) { - return await waitedUntil(()=>{ - // @ts-expect-error this field is added by our client transform - const workflowName = workflow.workflowId; - if (!workflowName) { - throw new WorkflowRuntimeError(`'start' received an invalid workflow function. Ensure the Workflow Development Kit is configured correctly and the function includes a 'use workflow' directive.`, { - slug: 'start-invalid-workflow-function' - }); - } - return trace(`WORKFLOW.start ${workflowName}`, async (span)=>{ - span?.setAttributes({ - ...WorkflowName(workflowName), - ...WorkflowOperation('start') - }); - let args = []; - let opts = {}; - if (Array.isArray(argsOrOptions)) { - args = argsOrOptions; - } else if (typeof argsOrOptions === 'object') { - opts = argsOrOptions; - } - span?.setAttributes({ - ...WorkflowArgumentsCount(args.length) - }); - const world = getWorld(); - const deploymentId = opts.deploymentId ?? await world.getDeploymentId(); - const ops = []; - const workflowArguments = dehydrateWorkflowArguments(args, ops); - // Serialize current trace context to propagate across queue boundary - const traceCarrier = await serializeTraceCarrier(); - const runResponse = await world.runs.create({ - deploymentId: deploymentId, - workflowName: workflowName, - input: workflowArguments, - executionContext: { - traceCarrier - } - }); - functionsExports.waitUntil(Promise.all(ops)); - span?.setAttributes({ - ...WorkflowRunId(runResponse.runId), - ...WorkflowRunStatus(runResponse.status), - ...DeploymentId(deploymentId) - }); - await world.queue(`__wkf_workflow_${workflowName}`, { - runId: runResponse.runId, - traceCarrier - }, { - deploymentId - }); - return new Run(runResponse.runId); - }); - }); -} - -async function calc(n) { - throw new Error("You attempted to execute workflow calc function directly. To start a workflow, use start(calc) from workflow/api"); -} -calc.workflowId = "workflow//nitro-v3/workflows/0_demo.ts//calc"; - -const workflow_0_demo = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - calc -}, Symbol.toStringTag, { value: 'Module' })); - -async function simple(i) { - throw new Error("You attempted to execute workflow simple function directly. To start a workflow, use start(simple) from workflow/api"); -} -simple.workflowId = "workflow//example/workflows/1_simple.ts//simple"; - -const workflow_1_simple = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - simple -}, Symbol.toStringTag, { value: 'Module' })); - -async function control_flow() { - throw new Error("You attempted to execute workflow control_flow function directly. To start a workflow, use start(control_flow) from workflow/api"); -} -control_flow.workflowId = "workflow//example/workflows/2_control_flow.ts//control_flow"; - -const workflow_2_control_flow = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - control_flow -}, Symbol.toStringTag, { value: 'Module' })); - -async function genStream() { - const stream = new ReadableStream({ - async start (controller) { - const encoder = new TextEncoder(); - for(let i = 0; i < 30; i++){ - const chunk = encoder.encode(`${i} -`); - controller.enqueue(chunk); - console.log(`Enqueued number: ${i}`); - await new Promise((resolve)=>setTimeout(resolve, 2500)); - } - controller.close(); - } - }); - return stream; -} -async function consumeStreams(...streams2) { - const parts = []; - console.log("Consuming streams", streams2); - await Promise.all(streams2.map(async (s, i)=>{ - const reader = s.getReader(); - while(true){ - const result = await reader.read(); - if (result.done) break; - console.log(`Received ${result.value.length} bytes from stream ${i}: ${JSON.stringify(new TextDecoder().decode(result.value))}`); - parts.push(result.value); - } - })); - return Buffer.concat(parts).toString("utf8"); -} -async function streams() { - throw new Error("You attempted to execute workflow streams function directly. To start a workflow, use start(streams) from workflow/api"); -} -streams.workflowId = "workflow//example/workflows/3_streams.ts//streams"; - -const workflow_3_streams = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - consumeStreams, - genStream, - streams -}, Symbol.toStringTag, { value: 'Module' })); - -async function ai(prompt) { - throw new Error("You attempted to execute workflow ai function directly. To start a workflow, use start(ai) from workflow/api"); -} -ai.workflowId = "workflow//example/workflows/4_ai.ts//ai"; -async function agent(prompt) { - throw new Error("You attempted to execute workflow agent function directly. To start a workflow, use start(agent) from workflow/api"); -} -agent.workflowId = "workflow//example/workflows/4_ai.ts//agent"; - -const workflow_4_ai = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - agent, - ai -}, Symbol.toStringTag, { value: 'Module' })); - -async function withWorkflowMetadata() { - throw new Error("You attempted to execute workflow withWorkflowMetadata function directly. To start a workflow, use start(withWorkflowMetadata) from workflow/api"); -} -withWorkflowMetadata.workflowId = "workflow//example/workflows/5_hooks.ts//withWorkflowMetadata"; -async function withCreateHook() { - throw new Error("You attempted to execute workflow withCreateHook function directly. To start a workflow, use start(withCreateHook) from workflow/api"); -} -withCreateHook.workflowId = "workflow//example/workflows/5_hooks.ts//withCreateHook"; - -const workflow_5_hooks = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - withCreateHook, - withWorkflowMetadata -}, Symbol.toStringTag, { value: 'Module' })); - -async function batchOverSteps() { - throw new Error("You attempted to execute workflow batchOverSteps function directly. To start a workflow, use start(batchOverSteps) from workflow/api"); -} -batchOverSteps.workflowId = "workflow//example/workflows/6_batching.ts//batchOverSteps"; -async function batchInStep() { - throw new Error("You attempted to execute workflow batchInStep function directly. To start a workflow, use start(batchInStep) from workflow/api"); -} -batchInStep.workflowId = "workflow//example/workflows/6_batching.ts//batchInStep"; - -const workflow_6_batching = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - batchInStep, - batchOverSteps -}, Symbol.toStringTag, { value: 'Module' })); - -async function handleUserSignup(email) { - throw new Error("You attempted to execute workflow handleUserSignup function directly. To start a workflow, use start(handleUserSignup) from workflow/api"); -} -handleUserSignup.workflowId = "workflow//example/workflows/7_full.ts//handleUserSignup"; - -const workflow_7_full = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - handleUserSignup -}, Symbol.toStringTag, { value: 'Module' })); - -async function addTenWorkflow(input) { - throw new Error("You attempted to execute workflow addTenWorkflow function directly. To start a workflow, use start(addTenWorkflow) from workflow/api"); -} -addTenWorkflow.workflowId = "workflow//example/workflows/98_duplicate_case.ts//addTenWorkflow"; -async function add(a, b) { - return a + b; -} - -const workflow_98_duplicate_case = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - add, - addTenWorkflow -}, Symbol.toStringTag, { value: 'Module' })); - -const allWorkflows = { - "workflows/0_demo.ts": workflow_0_demo, - "workflows/1_simple.ts": workflow_1_simple, - "workflows/2_control_flow.ts": workflow_2_control_flow, - "workflows/3_streams.ts": workflow_3_streams, - "workflows/4_ai.ts": workflow_4_ai, - "workflows/5_hooks.ts": workflow_5_hooks, - "workflows/6_batching.ts": workflow_6_batching, - "workflows/7_full.ts": workflow_7_full, - "workflows/98_duplicate_case.ts": workflow_98_duplicate_case, - "workflows/99_e2e.ts": workflow_99_e2e -}; - -async function POST({ request }) { - const url = new URL(request.url); - const workflowFile = url.searchParams.get("workflowFile") || "workflows/99_e2e.ts"; - const workflows = allWorkflows[workflowFile]; - if (!workflows) { - return new Response(`Workflow file "${workflowFile}" not found`, { - status: 400 - }); - } - const workflowFn = url.searchParams.get("workflowFn") || "simple"; - const workflow = workflows[workflowFn]; - if (!workflow) { - return new Response(`Workflow "${workflowFn}" not found`, { status: 400 }); - } - let args = []; - const argsParam = url.searchParams.get("args"); - if (argsParam) { - args = argsParam.split(",").map((arg) => { - const num = parseFloat(arg); - return Number.isNaN(num) ? arg.trim() : num; - }); - } else { - const body = await request.text(); - if (body) { - args = hydrateWorkflowArguments(JSON.parse(body), globalThis); - } else { - args = [42]; - } - } - console.log(`Starting "${workflowFn}" workflow with args: ${args}`); - try { - const run = await start(workflow, args); - console.log("Run:", run); - return Response.json(run); - } catch (err) { - console.error(`Failed to start!!`, err); - throw err; - } -} -const GET = async ({ request }) => { - const url = new URL(request.url); - const runId = url.searchParams.get("runId"); - if (!runId) { - return new Response("No runId provided", { status: 400 }); - } - const outputStreamParam = url.searchParams.get("output-stream"); - if (outputStreamParam) { - const namespace = outputStreamParam === "1" ? void 0 : outputStreamParam; - const run = getRun(runId); - const stream = run.getReadable({ - namespace - }); - const streamWithFraming = new TransformStream({ - transform(chunk, controller) { - const data = chunk instanceof Uint8Array ? { data: Buffer.from(chunk).toString("base64") } : chunk; - controller.enqueue(`${JSON.stringify(data)} -`); - } - }); - return new Response(stream.pipeThrough(streamWithFraming), { - headers: { - "Content-Type": "application/octet-stream" - } - }); - } - try { - const run = getRun(runId); - const returnValue = await run.returnValue; - console.log("Return value:", returnValue); - return returnValue instanceof ReadableStream ? new Response(returnValue, { - headers: { - "Content-Type": "application/octet-stream" - } - }) : Response.json(returnValue); - } catch (error) { - if (error instanceof Error) { - if (WorkflowRunNotCompletedError.is(error)) { - return Response.json( - { - ...error, - name: error.name, - message: error.message - }, - { status: 202 } - ); - } - if (WorkflowRunFailedError.is(error)) { - const cause = error.cause; - return Response.json( - { - ...error, - name: error.name, - message: error.message, - cause: { - message: cause.message, - stack: cause.stack, - code: cause.code - } - }, - { status: 400 } - ); - } - } - console.error( - "Unexpected error while getting workflow return value:", - error - ); - return Response.json( - { - error: "Internal server error" - }, - { status: 500 } - ); - } -}; -const prerender = false; - -const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - GET, - POST, - prerender -}, Symbol.toStringTag, { value: 'Module' })); - -const page = () => _page; - -export { page }; diff --git a/workbench/astro/dist/server/pages/index.astro.mjs b/workbench/astro/dist/server/pages/index.astro.mjs deleted file mode 100644 index e8ff7a486..000000000 --- a/workbench/astro/dist/server/pages/index.astro.mjs +++ /dev/null @@ -1 +0,0 @@ -// Contents removed by Astro as it's used for prerendering only \ No newline at end of file diff --git a/workbench/astro/dist/server/renderers.mjs b/workbench/astro/dist/server/renderers.mjs deleted file mode 100644 index a97849f70..000000000 --- a/workbench/astro/dist/server/renderers.mjs +++ /dev/null @@ -1,3 +0,0 @@ -const renderers = []; - -export { renderers }; From 69d8f13dd3fa683f6d5ca400722370d7deb43b2e Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 11:13:47 -0800 Subject: [PATCH 12/61] test: add astro --- .github/workflows/tests.yml | 4 ++-- scripts/create-test-matrix.mjs | 6 ++++++ workbench/astro/src/pages/api/chat.ts | 12 ++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 workbench/astro/src/pages/api/chat.ts diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index de981ccb5..e163410af 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -193,7 +193,7 @@ jobs: run: cd workbench/${{ matrix.app.name }} && pnpm dev & echo "starting tests in 10 seconds" && sleep 10 && pnpm vitest run packages/core/e2e/dev.test.ts && pnpm run test:e2e env: APP_NAME: ${{ matrix.app.name }} - DEPLOYMENT_URL: "http://localhost:${{ matrix.app.name == 'sveltekit' && '5173' || '3000' }}" + DEPLOYMENT_URL: "http://localhost:${{ matrix.app.name == 'sveltekit' && '5173' || (matrix.app.name == 'astro' && '4321' || '3000') }}" DEV_TEST_CONFIG: ${{ toJSON(matrix.app) }} e2e-local-prod: @@ -245,7 +245,7 @@ jobs: run: cd workbench/${{ matrix.app.name }} && pnpm start & echo "starting tests in 10 seconds" && sleep 10 && pnpm run test:e2e env: APP_NAME: ${{ matrix.app.name }} - DEPLOYMENT_URL: "http://localhost:${{ matrix.app.name == 'sveltekit' && '4173' || '3000' }}" + DEPLOYMENT_URL: "http://localhost:${{ matrix.app.name == 'sveltekit' && '4173' || (matrix.app.name == 'astro' && '4321' || '3000') }}" e2e-local-postgres: name: E2E Local Postgres Tests (${{ matrix.app.name }} - ${{ matrix.app.canary && 'canary' || 'stable' }}) diff --git a/scripts/create-test-matrix.mjs b/scripts/create-test-matrix.mjs index 369ec344d..c7f9b6cdc 100644 --- a/scripts/create-test-matrix.mjs +++ b/scripts/create-test-matrix.mjs @@ -49,6 +49,12 @@ const DEV_TEST_CONFIGS = { apiFilePath: './src/index.ts', apiFileImportPath: '..', }, + astro: { + generatedStepPath: 'src/pages/.well-known/workflow/v1/step.js', + generatedWorkflowPath: 'src/pages/.well-known/workflow/v1/flow.js', + apiFilePath: 'src/pages/api/chat.ts', + apiFileImportPath: '../..', + }, }; const matrix = { diff --git a/workbench/astro/src/pages/api/chat.ts b/workbench/astro/src/pages/api/chat.ts new file mode 100644 index 000000000..420339e43 --- /dev/null +++ b/workbench/astro/src/pages/api/chat.ts @@ -0,0 +1,12 @@ +// THIS FILE IS JUST FOR TESTING HMR AS AN ENTRY NEEDS +// TO IMPORT THE WORKFLOWS TO DISCOVER THEM AND WATCH + +import type { APIRoute } from 'astro'; +import * as workflows from '../../workflows/3_streams'; + +export const POST: APIRoute = async ({ request }: { request: Request }) => { + console.log(workflows); + return Response.json('hello world'); +}; + +export const prerender = false; From e0429ef2374271c6a74df4c01daa100f5996e92d Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 11:21:36 -0800 Subject: [PATCH 13/61] fix: add astro deps --- pnpm-lock.yaml | 65 ++++++++---------------------------- workbench/astro/package.json | 7 ++-- 2 files changed, 18 insertions(+), 54 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 68c02a064..e2de9bfe0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1133,15 +1133,24 @@ importers: '@astrojs/vercel': specifier: ^9.0.0 version: 9.0.1(@aws-sdk/credential-provider-web-identity@3.844.0)(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(astro@5.16.0(@netlify/blobs@9.1.2)(@types/node@24.6.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1))(next@16.0.3(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(rollup@4.53.3)(svelte@5.43.3)(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) + ai: + specifier: 'catalog:' + version: 5.0.76(zod@4.1.11) astro: specifier: ^5.15.6 version: 5.16.0(@netlify/blobs@9.1.2)(@types/node@24.6.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1) - nitro: - specifier: 'catalog:' - version: 3.0.1-alpha.1(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(ioredis@5.8.2)(lru-cache@11.2.2)(rollup@4.53.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + lodash.chunk: + specifier: ^4.2.0 + version: 4.2.0 + openai: + specifier: 6.9.0 + version: 6.9.0(ws@8.18.3)(zod@4.1.11) workflow: specifier: workspace:* version: link:../../packages/workflow + zod: + specifier: 'catalog:' + version: 4.1.11 workbench/example: dependencies: @@ -14295,7 +14304,7 @@ snapshots: globals: 14.0.0 ignore: 5.3.2 import-fresh: 3.3.1 - js-yaml: 4.1.0 + js-yaml: 4.1.1 minimatch: 3.1.2 strip-json-comments: 3.1.1 transitivePeerDependencies: @@ -22893,54 +22902,6 @@ snapshots: nf3@0.1.12: {} - nitro@3.0.1-alpha.1(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(ioredis@5.8.2)(lru-cache@11.2.2)(rollup@4.53.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): - dependencies: - consola: 3.4.2 - crossws: 0.4.1(srvx@0.9.6) - db0: 0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)) - h3: 2.0.1-rc.5(crossws@0.4.1(srvx@0.9.6)) - jiti: 2.6.1 - nf3: 0.1.12 - ofetch: 2.0.0-alpha.3 - ohash: 2.0.11 - oxc-minify: 0.96.0 - oxc-transform: 0.96.0 - srvx: 0.9.6 - undici: 7.16.0 - unenv: 2.0.0-rc.24 - unstorage: 2.0.0-alpha.4(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(chokidar@4.0.3)(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(lru-cache@11.2.2)(ofetch@2.0.0-alpha.3) - optionalDependencies: - rollup: 4.53.3 - vite: 6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@electric-sql/pglite' - - '@libsql/client' - - '@netlify/blobs' - - '@planetscale/database' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - better-sqlite3 - - chokidar - - drizzle-orm - - idb-keyval - - ioredis - - lru-cache - - mongodb - - mysql2 - - sqlite3 - - uploadthing - nitro@3.0.1-alpha.1(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(ioredis@5.8.2)(lru-cache@11.2.2)(rollup@4.53.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): dependencies: consola: 3.4.2 diff --git a/workbench/astro/package.json b/workbench/astro/package.json index daf3e2865..0c3a012ed 100644 --- a/workbench/astro/package.json +++ b/workbench/astro/package.json @@ -14,8 +14,11 @@ "dependencies": { "@astrojs/node": "9.5.0", "@astrojs/vercel": "^9.0.0", + "ai": "catalog:", "astro": "^5.15.6", - "nitro": "catalog:", - "workflow": "workspace:*" + "lodash.chunk": "^4.2.0", + "openai": "6.9.0", + "workflow": "workspace:*", + "zod": "catalog:" } } From 4220272aa8be2db17a6bd2b286f161aa86650972 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 11:24:39 -0800 Subject: [PATCH 14/61] fix(astro): add vercel.json to ensure pnpm version detection --- workbench/astro/vercel.json | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 workbench/astro/vercel.json diff --git a/workbench/astro/vercel.json b/workbench/astro/vercel.json new file mode 100644 index 000000000..701b09407 --- /dev/null +++ b/workbench/astro/vercel.json @@ -0,0 +1,3 @@ +{ + "installCommand": "pnpm install" +} From 46f1efca6879814648200a168611ccc462885743 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 11:27:09 -0800 Subject: [PATCH 15/61] update project id on astro --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index e163410af..23a54eed6 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -76,7 +76,7 @@ jobs: - name: "express" project-id: "prj_cCZjpBy92VRbKHHbarDMhOHtkuIr" - name: "astro" - project-id: "prj_DvOcT5MdgZo3mw8lpkSXcr7XM7pv" + project-id: "prj_YDAXj3K8LM0hgejuIMhioz2yLgTI" env: TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} TURBO_TEAM: ${{ vars.TURBO_TEAM }} From 5bdb657a75052d189ff3704868c3da601fb4ecfc Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 11:34:45 -0800 Subject: [PATCH 16/61] fix(astro): add .npmrc with engine-strict to enforce pnpm version --- workbench/astro/.npmrc | 1 + 1 file changed, 1 insertion(+) create mode 100644 workbench/astro/.npmrc diff --git a/workbench/astro/.npmrc b/workbench/astro/.npmrc new file mode 100644 index 000000000..b6f27f135 --- /dev/null +++ b/workbench/astro/.npmrc @@ -0,0 +1 @@ +engine-strict=true From e5de41ff24368d746d0016c475a690c6a52e0575 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 11:37:48 -0800 Subject: [PATCH 17/61] cleanup --- workbench/astro/vercel.json | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 workbench/astro/vercel.json diff --git a/workbench/astro/vercel.json b/workbench/astro/vercel.json deleted file mode 100644 index 701b09407..000000000 --- a/workbench/astro/vercel.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "installCommand": "pnpm install" -} From d1edbcb152277559e9e7b037ceee3570e64caa4a Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 11:40:34 -0800 Subject: [PATCH 18/61] remove package lock --- workbench/astro/package-lock.json | 4883 ----------------------------- 1 file changed, 4883 deletions(-) delete mode 100644 workbench/astro/package-lock.json diff --git a/workbench/astro/package-lock.json b/workbench/astro/package-lock.json deleted file mode 100644 index 1fa3d718f..000000000 --- a/workbench/astro/package-lock.json +++ /dev/null @@ -1,4883 +0,0 @@ -{ - "name": "astro", - "version": "0.0.1", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "astro", - "version": "0.0.1", - "dependencies": { - "astro": "^5.15.6" - } - }, - "node_modules/@astrojs/compiler": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-2.13.0.tgz", - "integrity": "sha512-mqVORhUJViA28fwHYaWmsXSzLO9osbdZ5ImUfxBarqsYdMlPbqAqGJCxsNzvppp1BEzc1mJNjOVvQqeDN8Vspw==", - "license": "MIT" - }, - "node_modules/@astrojs/internal-helpers": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.7.4.tgz", - "integrity": "sha512-lDA9MqE8WGi7T/t2BMi+EAXhs4Vcvr94Gqx3q15cFEz8oFZMO4/SFBqYr/UcmNlvW+35alowkVj+w9VhLvs5Cw==", - "license": "MIT" - }, - "node_modules/@astrojs/markdown-remark": { - "version": "6.3.8", - "resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-6.3.8.tgz", - "integrity": "sha512-uFNyFWadnULWK2cOw4n0hLKeu+xaVWeuECdP10cQ3K2fkybtTlhb7J7TcScdjmS8Yps7oje9S/ehYMfZrhrgCg==", - "license": "MIT", - "dependencies": { - "@astrojs/internal-helpers": "0.7.4", - "@astrojs/prism": "3.3.0", - "github-slugger": "^2.0.0", - "hast-util-from-html": "^2.0.3", - "hast-util-to-text": "^4.0.2", - "import-meta-resolve": "^4.2.0", - "js-yaml": "^4.1.0", - "mdast-util-definitions": "^6.0.0", - "rehype-raw": "^7.0.0", - "rehype-stringify": "^10.0.1", - "remark-gfm": "^4.0.1", - "remark-parse": "^11.0.0", - "remark-rehype": "^11.1.2", - "remark-smartypants": "^3.0.2", - "shiki": "^3.13.0", - "smol-toml": "^1.4.2", - "unified": "^11.0.5", - "unist-util-remove-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "unist-util-visit-parents": "^6.0.1", - "vfile": "^6.0.3" - } - }, - "node_modules/@astrojs/prism": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@astrojs/prism/-/prism-3.3.0.tgz", - "integrity": "sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ==", - "license": "MIT", - "dependencies": { - "prismjs": "^1.30.0" - }, - "engines": { - "node": "18.20.8 || ^20.3.0 || >=22.0.0" - } - }, - "node_modules/@astrojs/telemetry": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.3.0.tgz", - "integrity": "sha512-UFBgfeldP06qu6khs/yY+q1cDAaArM2/7AEIqQ9Cuvf7B1hNLq0xDrZkct+QoIGyjq56y8IaE2I3CTvG99mlhQ==", - "license": "MIT", - "dependencies": { - "ci-info": "^4.2.0", - "debug": "^4.4.0", - "dlv": "^1.1.3", - "dset": "^3.1.4", - "is-docker": "^3.0.0", - "is-wsl": "^3.1.0", - "which-pm-runs": "^1.1.0" - }, - "engines": { - "node": "18.20.8 || ^20.3.0 || >=22.0.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", - "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.28.5" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/types": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", - "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@capsizecss/unpack": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@capsizecss/unpack/-/unpack-3.0.1.tgz", - "integrity": "sha512-8XqW8xGn++Eqqbz3e9wKuK7mxryeRjs4LOHLxbh2lwKeSbuNR4NFifDZT4KzvjU6HMOPbiNTsWpniK5EJfTWkg==", - "license": "MIT", - "dependencies": { - "fontkit": "^2.0.2" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@emnapi/runtime": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.7.1.tgz", - "integrity": "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==", - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", - "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", - "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", - "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", - "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", - "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", - "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", - "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", - "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", - "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", - "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", - "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", - "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", - "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", - "cpu": [ - "mips64el" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", - "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", - "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", - "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", - "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", - "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", - "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", - "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", - "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", - "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", - "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", - "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", - "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", - "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@img/colour": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.0.0.tgz", - "integrity": "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@img/sharp-darwin-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", - "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.2.4" - } - }, - "node_modules/@img/sharp-darwin-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", - "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.2.4" - } - }, - "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", - "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", - "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", - "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", - "cpu": [ - "arm" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", - "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-ppc64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", - "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", - "cpu": [ - "ppc64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-riscv64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", - "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", - "cpu": [ - "riscv64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", - "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", - "cpu": [ - "s390x" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", - "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", - "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", - "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-linux-arm": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", - "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", - "cpu": [ - "arm" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", - "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-ppc64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", - "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", - "cpu": [ - "ppc64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-ppc64": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-riscv64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", - "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", - "cpu": [ - "riscv64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-riscv64": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-s390x": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", - "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", - "cpu": [ - "s390x" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", - "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.2.4" - } - }, - "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", - "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" - } - }, - "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", - "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.2.4" - } - }, - "node_modules/@img/sharp-wasm32": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", - "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", - "cpu": [ - "wasm32" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", - "optional": true, - "dependencies": { - "@emnapi/runtime": "^1.7.0" - }, - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", - "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-ia32": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", - "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", - "cpu": [ - "ia32" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", - "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "license": "MIT" - }, - "node_modules/@oslojs/encoding": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@oslojs/encoding/-/encoding-1.1.0.tgz", - "integrity": "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==", - "license": "MIT" - }, - "node_modules/@rollup/pluginutils": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", - "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^4.0.2" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/pluginutils/node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "license": "MIT" - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.2.tgz", - "integrity": "sha512-yDPzwsgiFO26RJA4nZo8I+xqzh7sJTZIWQOxn+/XOdPE31lAvLIYCKqjV+lNH/vxE2L2iH3plKxDCRK6i+CwhA==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.2.tgz", - "integrity": "sha512-k8FontTxIE7b0/OGKeSN5B6j25EuppBcWM33Z19JoVT7UTXFSo3D9CdU39wGTeb29NO3XxpMNauh09B+Ibw+9g==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.2.tgz", - "integrity": "sha512-A6s4gJpomNBtJ2yioj8bflM2oogDwzUiMl2yNJ2v9E7++sHrSrsQ29fOfn5DM/iCzpWcebNYEdXpaK4tr2RhfQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.2.tgz", - "integrity": "sha512-e6XqVmXlHrBlG56obu9gDRPW3O3hLxpwHpLsBJvuI8qqnsrtSZ9ERoWUXtPOkY8c78WghyPHZdmPhHLWNdAGEw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.2.tgz", - "integrity": "sha512-v0E9lJW8VsrwPux5Qe5CwmH/CF/2mQs6xU1MF3nmUxmZUCHazCjLgYvToOk+YuuUqLQBio1qkkREhxhc656ViA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.2.tgz", - "integrity": "sha512-ClAmAPx3ZCHtp6ysl4XEhWU69GUB1D+s7G9YjHGhIGCSrsg00nEGRRZHmINYxkdoJehde8VIsDC5t9C0gb6yqA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.2.tgz", - "integrity": "sha512-EPlb95nUsz6Dd9Qy13fI5kUPXNSljaG9FiJ4YUGU1O/Q77i5DYFW5KR8g1OzTcdZUqQQ1KdDqsTohdFVwCwjqg==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.2.tgz", - "integrity": "sha512-BOmnVW+khAUX+YZvNfa0tGTEMVVEerOxN0pDk2E6N6DsEIa2Ctj48FOMfNDdrwinocKaC7YXUZ1pHlKpnkja/Q==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.2.tgz", - "integrity": "sha512-Xt2byDZ+6OVNuREgBXr4+CZDJtrVso5woFtpKdGPhpTPHcNG7D8YXeQzpNbFRxzTVqJf7kvPMCub/pcGUWgBjA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.2.tgz", - "integrity": "sha512-+LdZSldy/I9N8+klim/Y1HsKbJ3BbInHav5qE9Iy77dtHC/pibw1SR/fXlWyAk0ThnpRKoODwnAuSjqxFRDHUQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.2.tgz", - "integrity": "sha512-8ms8sjmyc1jWJS6WdNSA23rEfdjWB30LH8Wqj0Cqvv7qSHnvw6kgMMXRdop6hkmGPlyYBdRPkjJnj3KCUHV/uQ==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.2.tgz", - "integrity": "sha512-3HRQLUQbpBDMmzoxPJYd3W6vrVHOo2cVW8RUo87Xz0JPJcBLBr5kZ1pGcQAhdZgX9VV7NbGNipah1omKKe23/g==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.2.tgz", - "integrity": "sha512-fMjKi+ojnmIvhk34gZP94vjogXNNUKMEYs+EDaB/5TG/wUkoeua7p7VCHnE6T2Tx+iaghAqQX8teQzcvrYpaQA==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.2.tgz", - "integrity": "sha512-XuGFGU+VwUUV5kLvoAdi0Wz5Xbh2SrjIxCtZj6Wq8MDp4bflb/+ThZsVxokM7n0pcbkEr2h5/pzqzDYI7cCgLQ==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.2.tgz", - "integrity": "sha512-w6yjZF0P+NGzWR3AXWX9zc0DNEGdtvykB03uhonSHMRa+oWA6novflo2WaJr6JZakG2ucsyb+rvhrKac6NIy+w==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.2.tgz", - "integrity": "sha512-yo8d6tdfdeBArzC7T/PnHd7OypfI9cbuZzPnzLJIyKYFhAQ8SvlkKtKBMbXDxe1h03Rcr7u++nFS7tqXz87Gtw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.2.tgz", - "integrity": "sha512-ah59c1YkCxKExPP8O9PwOvs+XRLKwh/mV+3YdKqQ5AMQ0r4M4ZDuOrpWkUaqO7fzAHdINzV9tEVu8vNw48z0lA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.2.tgz", - "integrity": "sha512-4VEd19Wmhr+Zy7hbUsFZ6YXEiP48hE//KPLCSVNY5RMGX2/7HZ+QkN55a3atM1C/BZCGIgqN+xrVgtdak2S9+A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.2.tgz", - "integrity": "sha512-IlbHFYc/pQCgew/d5fslcy1KEaYVCJ44G8pajugd8VoOEI8ODhtb/j8XMhLpwHCMB3yk2J07ctup10gpw2nyMA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.2.tgz", - "integrity": "sha512-lNlPEGgdUfSzdCWU176ku/dQRnA7W+Gp8d+cWv73jYrb8uT7HTVVxq62DUYxjbaByuf1Yk0RIIAbDzp+CnOTFg==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.2.tgz", - "integrity": "sha512-S6YojNVrHybQis2lYov1sd+uj7K0Q05NxHcGktuMMdIQ2VixGwAfbJ23NnlvvVV1bdpR2m5MsNBViHJKcA4ADw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.2.tgz", - "integrity": "sha512-k+/Rkcyx//P6fetPoLMb8pBeqJBNGx81uuf7iljX9++yNBVRDQgD04L+SVXmXmh5ZP4/WOp4mWF0kmi06PW2tA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@shikijs/core": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-3.15.0.tgz", - "integrity": "sha512-8TOG6yG557q+fMsSVa8nkEDOZNTSxjbbR8l6lF2gyr6Np+jrPlslqDxQkN6rMXCECQ3isNPZAGszAfYoJOPGlg==", - "license": "MIT", - "dependencies": { - "@shikijs/types": "3.15.0", - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4", - "hast-util-to-html": "^9.0.5" - } - }, - "node_modules/@shikijs/engine-javascript": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-3.15.0.tgz", - "integrity": "sha512-ZedbOFpopibdLmvTz2sJPJgns8Xvyabe2QbmqMTz07kt1pTzfEvKZc5IqPVO/XFiEbbNyaOpjPBkkr1vlwS+qg==", - "license": "MIT", - "dependencies": { - "@shikijs/types": "3.15.0", - "@shikijs/vscode-textmate": "^10.0.2", - "oniguruma-to-es": "^4.3.3" - } - }, - "node_modules/@shikijs/engine-oniguruma": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.15.0.tgz", - "integrity": "sha512-HnqFsV11skAHvOArMZdLBZZApRSYS4LSztk2K3016Y9VCyZISnlYUYsL2hzlS7tPqKHvNqmI5JSUJZprXloMvA==", - "license": "MIT", - "dependencies": { - "@shikijs/types": "3.15.0", - "@shikijs/vscode-textmate": "^10.0.2" - } - }, - "node_modules/@shikijs/langs": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.15.0.tgz", - "integrity": "sha512-WpRvEFvkVvO65uKYW4Rzxs+IG0gToyM8SARQMtGGsH4GDMNZrr60qdggXrFOsdfOVssG/QQGEl3FnJ3EZ+8w8A==", - "license": "MIT", - "dependencies": { - "@shikijs/types": "3.15.0" - } - }, - "node_modules/@shikijs/themes": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.15.0.tgz", - "integrity": "sha512-8ow2zWb1IDvCKjYb0KiLNrK4offFdkfNVPXb1OZykpLCzRU6j+efkY+Y7VQjNlNFXonSw+4AOdGYtmqykDbRiQ==", - "license": "MIT", - "dependencies": { - "@shikijs/types": "3.15.0" - } - }, - "node_modules/@shikijs/types": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.15.0.tgz", - "integrity": "sha512-BnP+y/EQnhihgHy4oIAN+6FFtmfTekwOLsQbRw9hOKwqgNy8Bdsjq8B05oAt/ZgvIWWFrshV71ytOrlPfYjIJw==", - "license": "MIT", - "dependencies": { - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4" - } - }, - "node_modules/@shikijs/vscode-textmate": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", - "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", - "license": "MIT" - }, - "node_modules/@swc/helpers": { - "version": "0.5.17", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz", - "integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.8.0" - } - }, - "node_modules/@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", - "license": "MIT", - "dependencies": { - "@types/ms": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "license": "MIT" - }, - "node_modules/@types/fontkit": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/@types/fontkit/-/fontkit-2.0.8.tgz", - "integrity": "sha512-wN+8bYxIpJf+5oZdrdtaX04qUuWHcKxcDEgRS9Qm9ZClSHjzEn13SxUC+5eRM+4yXIeTYk8mTzLAWGF64847ew==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/hast": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", - "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", - "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", - "license": "MIT" - }, - "node_modules/@types/nlcst": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/nlcst/-/nlcst-2.0.3.tgz", - "integrity": "sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==", - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/node": { - "version": "24.10.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz", - "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==", - "license": "MIT", - "dependencies": { - "undici-types": "~7.16.0" - } - }, - "node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", - "license": "MIT" - }, - "node_modules/@ungap/structured-clone": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", - "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", - "license": "ISC" - }, - "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "license": "ISC", - "dependencies": { - "string-width": "^4.1.0" - } - }, - "node_modules/ansi-align/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-align/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/ansi-align/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-align/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/anymatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "license": "Python-2.0" - }, - "node_modules/aria-query": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", - "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", - "license": "Apache-2.0", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/array-iterate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-2.0.1.tgz", - "integrity": "sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/astro": { - "version": "5.15.6", - "resolved": "https://registry.npmjs.org/astro/-/astro-5.15.6.tgz", - "integrity": "sha512-luLcw+FGkeUHYTfbmYjIWHB4T0D+3VSjCy8DKTXglJ2O3lU40AbwmPVBcnqhRnA1SneKzP5V5pzqjsHzUZ1+Rg==", - "license": "MIT", - "dependencies": { - "@astrojs/compiler": "^2.13.0", - "@astrojs/internal-helpers": "0.7.4", - "@astrojs/markdown-remark": "6.3.8", - "@astrojs/telemetry": "3.3.0", - "@capsizecss/unpack": "^3.0.0", - "@oslojs/encoding": "^1.1.0", - "@rollup/pluginutils": "^5.3.0", - "acorn": "^8.15.0", - "aria-query": "^5.3.2", - "axobject-query": "^4.1.0", - "boxen": "8.0.1", - "ci-info": "^4.3.1", - "clsx": "^2.1.1", - "common-ancestor-path": "^1.0.1", - "cookie": "^1.0.2", - "cssesc": "^3.0.0", - "debug": "^4.4.3", - "deterministic-object-hash": "^2.0.2", - "devalue": "^5.4.2", - "diff": "^5.2.0", - "dlv": "^1.1.3", - "dset": "^3.1.4", - "es-module-lexer": "^1.7.0", - "esbuild": "^0.25.0", - "estree-walker": "^3.0.3", - "flattie": "^1.1.1", - "fontace": "~0.3.1", - "github-slugger": "^2.0.0", - "html-escaper": "3.0.3", - "http-cache-semantics": "^4.2.0", - "import-meta-resolve": "^4.2.0", - "js-yaml": "^4.1.0", - "magic-string": "^0.30.21", - "magicast": "^0.5.1", - "mrmime": "^2.0.1", - "neotraverse": "^0.6.18", - "p-limit": "^6.2.0", - "p-queue": "^8.1.1", - "package-manager-detector": "^1.5.0", - "picocolors": "^1.1.1", - "picomatch": "^4.0.3", - "prompts": "^2.4.2", - "rehype": "^13.0.2", - "semver": "^7.7.3", - "shiki": "^3.15.0", - "smol-toml": "^1.4.2", - "tinyexec": "^1.0.2", - "tinyglobby": "^0.2.15", - "tsconfck": "^3.1.6", - "ultrahtml": "^1.6.0", - "unifont": "~0.6.0", - "unist-util-visit": "^5.0.0", - "unstorage": "^1.17.2", - "vfile": "^6.0.3", - "vite": "^6.4.1", - "vitefu": "^1.1.1", - "xxhash-wasm": "^1.1.0", - "yargs-parser": "^21.1.1", - "yocto-spinner": "^0.2.3", - "zod": "^3.25.76", - "zod-to-json-schema": "^3.24.6", - "zod-to-ts": "^1.2.0" - }, - "bin": { - "astro": "astro.js" - }, - "engines": { - "node": "18.20.8 || ^20.3.0 || >=22.0.0", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/astrodotbuild" - }, - "optionalDependencies": { - "sharp": "^0.34.0" - } - }, - "node_modules/axobject-query": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", - "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", - "license": "Apache-2.0", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/bail": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", - "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/base-64": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz", - "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==", - "license": "MIT" - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/boxen": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-8.0.1.tgz", - "integrity": "sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw==", - "license": "MIT", - "dependencies": { - "ansi-align": "^3.0.1", - "camelcase": "^8.0.0", - "chalk": "^5.3.0", - "cli-boxes": "^3.0.0", - "string-width": "^7.2.0", - "type-fest": "^4.21.0", - "widest-line": "^5.0.0", - "wrap-ansi": "^9.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/brotli": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/brotli/-/brotli-1.3.3.tgz", - "integrity": "sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==", - "license": "MIT", - "dependencies": { - "base64-js": "^1.1.2" - } - }, - "node_modules/camelcase": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz", - "integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==", - "license": "MIT", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ccount": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", - "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/chalk": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", - "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/character-entities": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", - "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-html4": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", - "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-legacy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", - "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "license": "MIT", - "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/ci-info": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", - "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-boxes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", - "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/clsx": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/comma-separated-tokens": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", - "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/common-ancestor-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz", - "integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==", - "license": "ISC" - }, - "node_modules/cookie": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", - "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/cookie-es": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-1.2.2.tgz", - "integrity": "sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==", - "license": "MIT" - }, - "node_modules/crossws": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/crossws/-/crossws-0.3.5.tgz", - "integrity": "sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==", - "license": "MIT", - "dependencies": { - "uncrypto": "^0.1.3" - } - }, - "node_modules/css-tree": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", - "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", - "license": "MIT", - "dependencies": { - "mdn-data": "2.12.2", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" - } - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decode-named-character-reference": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz", - "integrity": "sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==", - "license": "MIT", - "dependencies": { - "character-entities": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/defu": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", - "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", - "license": "MIT" - }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/destr": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.5.tgz", - "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==", - "license": "MIT" - }, - "node_modules/detect-libc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "license": "Apache-2.0", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/deterministic-object-hash": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/deterministic-object-hash/-/deterministic-object-hash-2.0.2.tgz", - "integrity": "sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ==", - "license": "MIT", - "dependencies": { - "base-64": "^1.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/devalue": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.5.0.tgz", - "integrity": "sha512-69sM5yrHfFLJt0AZ9QqZXGCPfJ7fQjvpln3Rq5+PS03LD32Ost1Q9N+eEnaQwGRIriKkMImXD56ocjQmfjbV3w==", - "license": "MIT" - }, - "node_modules/devlop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", - "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", - "license": "MIT", - "dependencies": { - "dequal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/dfa": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/dfa/-/dfa-1.2.0.tgz", - "integrity": "sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q==", - "license": "MIT" - }, - "node_modules/diff": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "license": "MIT" - }, - "node_modules/dset": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.4.tgz", - "integrity": "sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/emoji-regex": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", - "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", - "license": "MIT" - }, - "node_modules/entities": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", - "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/es-module-lexer": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", - "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", - "license": "MIT" - }, - "node_modules/esbuild": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", - "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.12", - "@esbuild/android-arm": "0.25.12", - "@esbuild/android-arm64": "0.25.12", - "@esbuild/android-x64": "0.25.12", - "@esbuild/darwin-arm64": "0.25.12", - "@esbuild/darwin-x64": "0.25.12", - "@esbuild/freebsd-arm64": "0.25.12", - "@esbuild/freebsd-x64": "0.25.12", - "@esbuild/linux-arm": "0.25.12", - "@esbuild/linux-arm64": "0.25.12", - "@esbuild/linux-ia32": "0.25.12", - "@esbuild/linux-loong64": "0.25.12", - "@esbuild/linux-mips64el": "0.25.12", - "@esbuild/linux-ppc64": "0.25.12", - "@esbuild/linux-riscv64": "0.25.12", - "@esbuild/linux-s390x": "0.25.12", - "@esbuild/linux-x64": "0.25.12", - "@esbuild/netbsd-arm64": "0.25.12", - "@esbuild/netbsd-x64": "0.25.12", - "@esbuild/openbsd-arm64": "0.25.12", - "@esbuild/openbsd-x64": "0.25.12", - "@esbuild/openharmony-arm64": "0.25.12", - "@esbuild/sunos-x64": "0.25.12", - "@esbuild/win32-arm64": "0.25.12", - "@esbuild/win32-ia32": "0.25.12", - "@esbuild/win32-x64": "0.25.12" - } - }, - "node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" - } - }, - "node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "license": "MIT" - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "license": "MIT" - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "license": "MIT" - }, - "node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/flattie": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flattie/-/flattie-1.1.1.tgz", - "integrity": "sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/fontace": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/fontace/-/fontace-0.3.1.tgz", - "integrity": "sha512-9f5g4feWT1jWT8+SbL85aLIRLIXUaDygaM2xPXRmzPYxrOMNok79Lr3FGJoKVNKibE0WCunNiEVG2mwuE+2qEg==", - "license": "MIT", - "dependencies": { - "@types/fontkit": "^2.0.8", - "fontkit": "^2.0.4" - } - }, - "node_modules/fontkit": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/fontkit/-/fontkit-2.0.4.tgz", - "integrity": "sha512-syetQadaUEDNdxdugga9CpEYVaQIxOwk7GlwZWWZ19//qW4zE5bknOKeMBDYAASwnpaSHKJITRLMF9m1fp3s6g==", - "license": "MIT", - "dependencies": { - "@swc/helpers": "^0.5.12", - "brotli": "^1.3.2", - "clone": "^2.1.2", - "dfa": "^1.2.0", - "fast-deep-equal": "^3.1.3", - "restructure": "^3.0.0", - "tiny-inflate": "^1.0.3", - "unicode-properties": "^1.4.0", - "unicode-trie": "^2.0.0" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/get-east-asian-width": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", - "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/github-slugger": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", - "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", - "license": "ISC" - }, - "node_modules/h3": { - "version": "1.15.4", - "resolved": "https://registry.npmjs.org/h3/-/h3-1.15.4.tgz", - "integrity": "sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ==", - "license": "MIT", - "dependencies": { - "cookie-es": "^1.2.2", - "crossws": "^0.3.5", - "defu": "^6.1.4", - "destr": "^2.0.5", - "iron-webcrypto": "^1.2.1", - "node-mock-http": "^1.0.2", - "radix3": "^1.1.2", - "ufo": "^1.6.1", - "uncrypto": "^0.1.3" - } - }, - "node_modules/hast-util-from-html": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz", - "integrity": "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "devlop": "^1.1.0", - "hast-util-from-parse5": "^8.0.0", - "parse5": "^7.0.0", - "vfile": "^6.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-parse5": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz", - "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "hastscript": "^9.0.0", - "property-information": "^7.0.0", - "vfile": "^6.0.0", - "vfile-location": "^5.0.0", - "web-namespaces": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-is-element": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", - "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-parse-selector": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", - "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-raw": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.1.0.tgz", - "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "@ungap/structured-clone": "^1.0.0", - "hast-util-from-parse5": "^8.0.0", - "hast-util-to-parse5": "^8.0.0", - "html-void-elements": "^3.0.0", - "mdast-util-to-hast": "^13.0.0", - "parse5": "^7.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-html": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", - "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "ccount": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-whitespace": "^3.0.0", - "html-void-elements": "^3.0.0", - "mdast-util-to-hast": "^13.0.0", - "property-information": "^7.0.0", - "space-separated-tokens": "^2.0.0", - "stringify-entities": "^4.0.0", - "zwitch": "^2.0.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-parse5": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz", - "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-parse5/node_modules/property-information": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", - "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/hast-util-to-text": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", - "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "hast-util-is-element": "^3.0.0", - "unist-util-find-after": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-whitespace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", - "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hastscript": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.1.tgz", - "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-parse-selector": "^4.0.0", - "property-information": "^7.0.0", - "space-separated-tokens": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/html-escaper": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", - "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==", - "license": "MIT" - }, - "node_modules/html-void-elements": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", - "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/http-cache-semantics": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", - "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", - "license": "BSD-2-Clause" - }, - "node_modules/import-meta-resolve": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", - "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/iron-webcrypto": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz", - "integrity": "sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/brc-dd" - } - }, - "node_modules/is-docker": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", - "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", - "license": "MIT", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-inside-container": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", - "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", - "license": "MIT", - "dependencies": { - "is-docker": "^3.0.0" - }, - "bin": { - "is-inside-container": "cli.js" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-plain-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-wsl": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", - "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", - "license": "MIT", - "dependencies": { - "is-inside-container": "^1.0.0" - }, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/longest-streak": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", - "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "license": "ISC" - }, - "node_modules/magic-string": { - "version": "0.30.21", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", - "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" - } - }, - "node_modules/magicast": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.1.tgz", - "integrity": "sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==", - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.28.5", - "@babel/types": "^7.28.5", - "source-map-js": "^1.2.1" - } - }, - "node_modules/markdown-table": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", - "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/mdast-util-definitions": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-6.0.0.tgz", - "integrity": "sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "unist-util-visit": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-find-and-replace": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", - "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "escape-string-regexp": "^5.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-from-markdown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", - "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark": "^4.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", - "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", - "license": "MIT", - "dependencies": { - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-gfm-autolink-literal": "^2.0.0", - "mdast-util-gfm-footnote": "^2.0.0", - "mdast-util-gfm-strikethrough": "^2.0.0", - "mdast-util-gfm-table": "^2.0.0", - "mdast-util-gfm-task-list-item": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-autolink-literal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", - "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "ccount": "^2.0.0", - "devlop": "^1.0.0", - "mdast-util-find-and-replace": "^3.0.0", - "micromark-util-character": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-footnote": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", - "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-strikethrough": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", - "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", - "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "markdown-table": "^3.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-task-list-item": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", - "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-phrasing": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", - "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-hast": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", - "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@ungap/structured-clone": "^1.0.0", - "devlop": "^1.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "trim-lines": "^3.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-markdown": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", - "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "longest-streak": "^3.0.0", - "mdast-util-phrasing": "^4.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "unist-util-visit": "^5.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdn-data": { - "version": "2.12.2", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", - "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", - "license": "CC0-1.0" - }, - "node_modules/micromark": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", - "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", - "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-destination": "^2.0.0", - "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-title": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", - "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", - "license": "MIT", - "dependencies": { - "micromark-extension-gfm-autolink-literal": "^2.0.0", - "micromark-extension-gfm-footnote": "^2.0.0", - "micromark-extension-gfm-strikethrough": "^2.0.0", - "micromark-extension-gfm-table": "^2.0.0", - "micromark-extension-gfm-tagfilter": "^2.0.0", - "micromark-extension-gfm-task-list-item": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-autolink-literal": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", - "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-footnote": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", - "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-strikethrough": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", - "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-table": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", - "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-tagfilter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", - "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", - "license": "MIT", - "dependencies": { - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-task-list-item": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", - "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-factory-destination": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", - "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-label": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", - "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-title": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", - "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-whitespace": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", - "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-chunked": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", - "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-classify-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", - "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-combine-extensions": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", - "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", - "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-string": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", - "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-encode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", - "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-html-tag-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", - "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-normalize-identifier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", - "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-resolve-all": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", - "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-sanitize-uri": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", - "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-subtokenize": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", - "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", - "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/mrmime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", - "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/neotraverse": { - "version": "0.6.18", - "resolved": "https://registry.npmjs.org/neotraverse/-/neotraverse-0.6.18.tgz", - "integrity": "sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==", - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/nlcst-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/nlcst-to-string/-/nlcst-to-string-4.0.0.tgz", - "integrity": "sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==", - "license": "MIT", - "dependencies": { - "@types/nlcst": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/node-fetch-native": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.7.tgz", - "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==", - "license": "MIT" - }, - "node_modules/node-mock-http": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/node-mock-http/-/node-mock-http-1.0.3.tgz", - "integrity": "sha512-jN8dK25fsfnMrVsEhluUTPkBFY+6ybu7jSB1n+ri/vOGjJxU8J9CZhpSGkHXSkFjtUhbmoncG/YG9ta5Ludqog==", - "license": "MIT" - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ofetch": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/ofetch/-/ofetch-1.5.1.tgz", - "integrity": "sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==", - "license": "MIT", - "dependencies": { - "destr": "^2.0.5", - "node-fetch-native": "^1.6.7", - "ufo": "^1.6.1" - } - }, - "node_modules/ohash": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz", - "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", - "license": "MIT" - }, - "node_modules/oniguruma-parser": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/oniguruma-parser/-/oniguruma-parser-0.12.1.tgz", - "integrity": "sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==", - "license": "MIT" - }, - "node_modules/oniguruma-to-es": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-4.3.3.tgz", - "integrity": "sha512-rPiZhzC3wXwE59YQMRDodUwwT9FZ9nNBwQQfsd1wfdtlKEyCdRV0avrTcSZ5xlIvGRVPd/cx6ZN45ECmS39xvg==", - "license": "MIT", - "dependencies": { - "oniguruma-parser": "^0.12.1", - "regex": "^6.0.1", - "regex-recursion": "^6.0.2" - } - }, - "node_modules/p-limit": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-6.2.0.tgz", - "integrity": "sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==", - "license": "MIT", - "dependencies": { - "yocto-queue": "^1.1.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-queue": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-8.1.1.tgz", - "integrity": "sha512-aNZ+VfjobsWryoiPnEApGGmf5WmNsCo9xu8dfaYamG5qaLP7ClhLN6NgsFe6SwJ2UbLEBK5dv9x8Mn5+RVhMWQ==", - "license": "MIT", - "dependencies": { - "eventemitter3": "^5.0.1", - "p-timeout": "^6.1.2" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-timeout": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.4.tgz", - "integrity": "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==", - "license": "MIT", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/package-manager-detector": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.5.0.tgz", - "integrity": "sha512-uBj69dVlYe/+wxj8JOpr97XfsxH/eumMt6HqjNTmJDf/6NO9s+0uxeOneIz3AsPt2m6y9PqzDzd3ATcU17MNfw==", - "license": "MIT" - }, - "node_modules/pako": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", - "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==", - "license": "MIT" - }, - "node_modules/parse-latin": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse-latin/-/parse-latin-7.0.0.tgz", - "integrity": "sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==", - "license": "MIT", - "dependencies": { - "@types/nlcst": "^2.0.0", - "@types/unist": "^3.0.0", - "nlcst-to-string": "^4.0.0", - "unist-util-modify-children": "^4.0.0", - "unist-util-visit-children": "^3.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/parse5": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", - "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", - "license": "MIT", - "dependencies": { - "entities": "^6.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.11", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/prismjs": { - "version": "1.30.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", - "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "license": "MIT", - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/property-information": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", - "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/radix3": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/radix3/-/radix3-1.1.2.tgz", - "integrity": "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==", - "license": "MIT" - }, - "node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "license": "MIT", - "engines": { - "node": ">= 14.18.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/regex/-/regex-6.0.1.tgz", - "integrity": "sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==", - "license": "MIT", - "dependencies": { - "regex-utilities": "^2.3.0" - } - }, - "node_modules/regex-recursion": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz", - "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==", - "license": "MIT", - "dependencies": { - "regex-utilities": "^2.3.0" - } - }, - "node_modules/regex-utilities": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz", - "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==", - "license": "MIT" - }, - "node_modules/rehype": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/rehype/-/rehype-13.0.2.tgz", - "integrity": "sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "rehype-parse": "^9.0.0", - "rehype-stringify": "^10.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-parse": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-9.0.1.tgz", - "integrity": "sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-from-html": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-raw": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", - "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-raw": "^9.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-stringify": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-10.0.1.tgz", - "integrity": "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-to-html": "^9.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-gfm": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", - "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-gfm": "^3.0.0", - "micromark-extension-gfm": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-stringify": "^11.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-parse": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", - "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-rehype": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", - "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "mdast-util-to-hast": "^13.0.0", - "unified": "^11.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-smartypants": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/remark-smartypants/-/remark-smartypants-3.0.2.tgz", - "integrity": "sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==", - "license": "MIT", - "dependencies": { - "retext": "^9.0.0", - "retext-smartypants": "^6.0.0", - "unified": "^11.0.4", - "unist-util-visit": "^5.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/remark-stringify": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", - "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-to-markdown": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/restructure": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/restructure/-/restructure-3.0.2.tgz", - "integrity": "sha512-gSfoiOEA0VPE6Tukkrr7I0RBdE0s7H1eFCDBk05l1KIQT1UIKNc5JZy6jdyW6eYH3aR3g5b3PuL77rq0hvwtAw==", - "license": "MIT" - }, - "node_modules/retext": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/retext/-/retext-9.0.0.tgz", - "integrity": "sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==", - "license": "MIT", - "dependencies": { - "@types/nlcst": "^2.0.0", - "retext-latin": "^4.0.0", - "retext-stringify": "^4.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/retext-latin": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/retext-latin/-/retext-latin-4.0.0.tgz", - "integrity": "sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==", - "license": "MIT", - "dependencies": { - "@types/nlcst": "^2.0.0", - "parse-latin": "^7.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/retext-smartypants": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/retext-smartypants/-/retext-smartypants-6.2.0.tgz", - "integrity": "sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==", - "license": "MIT", - "dependencies": { - "@types/nlcst": "^2.0.0", - "nlcst-to-string": "^4.0.0", - "unist-util-visit": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/retext-stringify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/retext-stringify/-/retext-stringify-4.0.0.tgz", - "integrity": "sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==", - "license": "MIT", - "dependencies": { - "@types/nlcst": "^2.0.0", - "nlcst-to-string": "^4.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rollup": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.2.tgz", - "integrity": "sha512-MHngMYwGJVi6Fmnk6ISmnk7JAHRNF0UkuucA0CUW3N3a4KnONPEZz+vUanQP/ZC/iY1Qkf3bwPWzyY84wEks1g==", - "license": "MIT", - "dependencies": { - "@types/estree": "1.0.8" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.53.2", - "@rollup/rollup-android-arm64": "4.53.2", - "@rollup/rollup-darwin-arm64": "4.53.2", - "@rollup/rollup-darwin-x64": "4.53.2", - "@rollup/rollup-freebsd-arm64": "4.53.2", - "@rollup/rollup-freebsd-x64": "4.53.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.53.2", - "@rollup/rollup-linux-arm-musleabihf": "4.53.2", - "@rollup/rollup-linux-arm64-gnu": "4.53.2", - "@rollup/rollup-linux-arm64-musl": "4.53.2", - "@rollup/rollup-linux-loong64-gnu": "4.53.2", - "@rollup/rollup-linux-ppc64-gnu": "4.53.2", - "@rollup/rollup-linux-riscv64-gnu": "4.53.2", - "@rollup/rollup-linux-riscv64-musl": "4.53.2", - "@rollup/rollup-linux-s390x-gnu": "4.53.2", - "@rollup/rollup-linux-x64-gnu": "4.53.2", - "@rollup/rollup-linux-x64-musl": "4.53.2", - "@rollup/rollup-openharmony-arm64": "4.53.2", - "@rollup/rollup-win32-arm64-msvc": "4.53.2", - "@rollup/rollup-win32-ia32-msvc": "4.53.2", - "@rollup/rollup-win32-x64-gnu": "4.53.2", - "@rollup/rollup-win32-x64-msvc": "4.53.2", - "fsevents": "~2.3.2" - } - }, - "node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/sharp": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", - "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", - "hasInstallScript": true, - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "@img/colour": "^1.0.0", - "detect-libc": "^2.1.2", - "semver": "^7.7.3" - }, - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-darwin-arm64": "0.34.5", - "@img/sharp-darwin-x64": "0.34.5", - "@img/sharp-libvips-darwin-arm64": "1.2.4", - "@img/sharp-libvips-darwin-x64": "1.2.4", - "@img/sharp-libvips-linux-arm": "1.2.4", - "@img/sharp-libvips-linux-arm64": "1.2.4", - "@img/sharp-libvips-linux-ppc64": "1.2.4", - "@img/sharp-libvips-linux-riscv64": "1.2.4", - "@img/sharp-libvips-linux-s390x": "1.2.4", - "@img/sharp-libvips-linux-x64": "1.2.4", - "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", - "@img/sharp-libvips-linuxmusl-x64": "1.2.4", - "@img/sharp-linux-arm": "0.34.5", - "@img/sharp-linux-arm64": "0.34.5", - "@img/sharp-linux-ppc64": "0.34.5", - "@img/sharp-linux-riscv64": "0.34.5", - "@img/sharp-linux-s390x": "0.34.5", - "@img/sharp-linux-x64": "0.34.5", - "@img/sharp-linuxmusl-arm64": "0.34.5", - "@img/sharp-linuxmusl-x64": "0.34.5", - "@img/sharp-wasm32": "0.34.5", - "@img/sharp-win32-arm64": "0.34.5", - "@img/sharp-win32-ia32": "0.34.5", - "@img/sharp-win32-x64": "0.34.5" - } - }, - "node_modules/shiki": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-3.15.0.tgz", - "integrity": "sha512-kLdkY6iV3dYbtPwS9KXU7mjfmDm25f5m0IPNFnaXO7TBPcvbUOY72PYXSuSqDzwp+vlH/d7MXpHlKO/x+QoLXw==", - "license": "MIT", - "dependencies": { - "@shikijs/core": "3.15.0", - "@shikijs/engine-javascript": "3.15.0", - "@shikijs/engine-oniguruma": "3.15.0", - "@shikijs/langs": "3.15.0", - "@shikijs/themes": "3.15.0", - "@shikijs/types": "3.15.0", - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4" - } - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "license": "MIT" - }, - "node_modules/smol-toml": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.5.0.tgz", - "integrity": "sha512-Jjsa8LZ+DyLbZ7gVi9d18bS8oxq0PQrTlVDfvYXgh7gxLwbW9QWgvakHD+hBLUtr5NahfStd8LQLGSPchaEJ8Q==", - "license": "BSD-3-Clause", - "engines": { - "node": ">= 18" - }, - "funding": { - "url": "https://github.com/sponsors/cyyynthia" - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/space-separated-tokens": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", - "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/string-width": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/stringify-entities": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", - "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", - "license": "MIT", - "dependencies": { - "character-entities-html4": "^2.0.0", - "character-entities-legacy": "^3.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/tiny-inflate": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", - "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==", - "license": "MIT" - }, - "node_modules/tinyexec": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", - "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", - "license": "MIT", - "dependencies": { - "fdir": "^6.5.0", - "picomatch": "^4.0.3" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" - } - }, - "node_modules/trim-lines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", - "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/trough": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", - "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/tsconfck": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.6.tgz", - "integrity": "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==", - "license": "MIT", - "bin": { - "tsconfck": "bin/tsconfck.js" - }, - "engines": { - "node": "^18 || >=20" - }, - "peerDependencies": { - "typescript": "^5.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, - "node_modules/type-fest": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", - "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "license": "Apache-2.0", - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/ufo": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", - "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", - "license": "MIT" - }, - "node_modules/ultrahtml": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ultrahtml/-/ultrahtml-1.6.0.tgz", - "integrity": "sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==", - "license": "MIT" - }, - "node_modules/uncrypto": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/uncrypto/-/uncrypto-0.1.3.tgz", - "integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==", - "license": "MIT" - }, - "node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", - "license": "MIT" - }, - "node_modules/unicode-properties": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/unicode-properties/-/unicode-properties-1.4.1.tgz", - "integrity": "sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg==", - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.0", - "unicode-trie": "^2.0.0" - } - }, - "node_modules/unicode-trie": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-2.0.0.tgz", - "integrity": "sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==", - "license": "MIT", - "dependencies": { - "pako": "^0.2.5", - "tiny-inflate": "^1.0.0" - } - }, - "node_modules/unified": { - "version": "11.0.5", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", - "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "bail": "^2.0.0", - "devlop": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unifont": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/unifont/-/unifont-0.6.0.tgz", - "integrity": "sha512-5Fx50fFQMQL5aeHyWnZX9122sSLckcDvcfFiBf3QYeHa7a1MKJooUy52b67moi2MJYkrfo/TWY+CoLdr/w0tTA==", - "license": "MIT", - "dependencies": { - "css-tree": "^3.0.0", - "ofetch": "^1.4.1", - "ohash": "^2.0.0" - } - }, - "node_modules/unist-util-find-after": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", - "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-is": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", - "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-modify-children": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-modify-children/-/unist-util-modify-children-4.0.0.tgz", - "integrity": "sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "array-iterate": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", - "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-remove-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", - "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-visit": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit-children": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit-children/-/unist-util-visit-children-3.0.0.tgz", - "integrity": "sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit-parents": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", - "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unstorage": { - "version": "1.17.2", - "resolved": "https://registry.npmjs.org/unstorage/-/unstorage-1.17.2.tgz", - "integrity": "sha512-cKEsD6iBWJgOMJ6vW1ID/SYuqNf8oN4yqRk8OYqaVQ3nnkJXOT1PSpaMh2QfzLs78UN5kSNRD2c/mgjT8tX7+w==", - "license": "MIT", - "dependencies": { - "anymatch": "^3.1.3", - "chokidar": "^4.0.3", - "destr": "^2.0.5", - "h3": "^1.15.4", - "lru-cache": "^10.4.3", - "node-fetch-native": "^1.6.7", - "ofetch": "^1.5.0", - "ufo": "^1.6.1" - }, - "peerDependencies": { - "@azure/app-configuration": "^1.8.0", - "@azure/cosmos": "^4.2.0", - "@azure/data-tables": "^13.3.0", - "@azure/identity": "^4.6.0", - "@azure/keyvault-secrets": "^4.9.0", - "@azure/storage-blob": "^12.26.0", - "@capacitor/preferences": "^6.0.3 || ^7.0.0", - "@deno/kv": ">=0.9.0", - "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", - "@planetscale/database": "^1.19.0", - "@upstash/redis": "^1.34.3", - "@vercel/blob": ">=0.27.1", - "@vercel/functions": "^2.2.12 || ^3.0.0", - "@vercel/kv": "^1.0.1", - "aws4fetch": "^1.0.20", - "db0": ">=0.2.1", - "idb-keyval": "^6.2.1", - "ioredis": "^5.4.2", - "uploadthing": "^7.4.4" - }, - "peerDependenciesMeta": { - "@azure/app-configuration": { - "optional": true - }, - "@azure/cosmos": { - "optional": true - }, - "@azure/data-tables": { - "optional": true - }, - "@azure/identity": { - "optional": true - }, - "@azure/keyvault-secrets": { - "optional": true - }, - "@azure/storage-blob": { - "optional": true - }, - "@capacitor/preferences": { - "optional": true - }, - "@deno/kv": { - "optional": true - }, - "@netlify/blobs": { - "optional": true - }, - "@planetscale/database": { - "optional": true - }, - "@upstash/redis": { - "optional": true - }, - "@vercel/blob": { - "optional": true - }, - "@vercel/functions": { - "optional": true - }, - "@vercel/kv": { - "optional": true - }, - "aws4fetch": { - "optional": true - }, - "db0": { - "optional": true - }, - "idb-keyval": { - "optional": true - }, - "ioredis": { - "optional": true - }, - "uploadthing": { - "optional": true - } - } - }, - "node_modules/vfile": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", - "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-location": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", - "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-message": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", - "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vite": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", - "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", - "license": "MIT", - "dependencies": { - "esbuild": "^0.25.0", - "fdir": "^6.4.4", - "picomatch": "^4.0.2", - "postcss": "^8.5.3", - "rollup": "^4.34.9", - "tinyglobby": "^0.2.13" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "jiti": ">=1.21.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.16.0", - "tsx": "^4.8.1", - "yaml": "^2.4.2" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "jiti": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } - } - }, - "node_modules/vitefu": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.1.tgz", - "integrity": "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==", - "license": "MIT", - "workspaces": [ - "tests/deps/*", - "tests/projects/*", - "tests/projects/workspace/packages/*" - ], - "peerDependencies": { - "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" - }, - "peerDependenciesMeta": { - "vite": { - "optional": true - } - } - }, - "node_modules/web-namespaces": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", - "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/which-pm-runs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz", - "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/widest-line": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-5.0.0.tgz", - "integrity": "sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==", - "license": "MIT", - "dependencies": { - "string-width": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/wrap-ansi": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", - "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/xxhash-wasm": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-1.1.0.tgz", - "integrity": "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==", - "license": "MIT" - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/yocto-queue": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", - "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", - "license": "MIT", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yocto-spinner": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/yocto-spinner/-/yocto-spinner-0.2.3.tgz", - "integrity": "sha512-sqBChb33loEnkoXte1bLg45bEBsOP9N1kzQh5JZNKj/0rik4zAPTNSAVPj3uQAdc6slYJ0Ksc403G2XgxsJQFQ==", - "license": "MIT", - "dependencies": { - "yoctocolors": "^2.1.1" - }, - "engines": { - "node": ">=18.19" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yoctocolors": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", - "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/zod": { - "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/zod-to-json-schema": { - "version": "3.24.6", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.6.tgz", - "integrity": "sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==", - "license": "ISC", - "peerDependencies": { - "zod": "^3.24.1" - } - }, - "node_modules/zod-to-ts": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/zod-to-ts/-/zod-to-ts-1.2.0.tgz", - "integrity": "sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA==", - "peerDependencies": { - "typescript": "^4.9.4 || ^5.0.2", - "zod": "^3" - } - }, - "node_modules/zwitch": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", - "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - } - } -} From d4be48ac69067219d4a606e7922ec3cd37c628a1 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 11:44:31 -0800 Subject: [PATCH 19/61] fix: disable cross site origin check --- workbench/astro/astro.config.mjs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/workbench/astro/astro.config.mjs b/workbench/astro/astro.config.mjs index 4107d7e52..5207c6670 100644 --- a/workbench/astro/astro.config.mjs +++ b/workbench/astro/astro.config.mjs @@ -14,4 +14,7 @@ const adapter = process.env.VERCEL_DEPLOYMENT_ID export default defineConfig({ vite: { plugins: [workflowPlugin()] }, adapter: adapter, + security: { + checkOrigin: false, + }, }); From d7d482a4208ac19be7a3e6681e78ab9905ea028b Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 11:48:04 -0800 Subject: [PATCH 20/61] . --- scripts/create-test-matrix.mjs | 119 +++++++++++++++++---------------- 1 file changed, 61 insertions(+), 58 deletions(-) diff --git a/scripts/create-test-matrix.mjs b/scripts/create-test-matrix.mjs index c7f9b6cdc..4ba3881a3 100644 --- a/scripts/create-test-matrix.mjs +++ b/scripts/create-test-matrix.mjs @@ -1,78 +1,78 @@ // Framework-specific dev test configurations const DEV_TEST_CONFIGS = { - 'nextjs-turbopack': { - generatedStepPath: 'app/.well-known/workflow/v1/step/route.js', - generatedWorkflowPath: 'app/.well-known/workflow/v1/flow/route.js', - apiFilePath: 'app/api/chat/route.ts', - apiFileImportPath: '../../..', + "nextjs-turbopack": { + generatedStepPath: "app/.well-known/workflow/v1/step/route.js", + generatedWorkflowPath: "app/.well-known/workflow/v1/flow/route.js", + apiFilePath: "app/api/chat/route.ts", + apiFileImportPath: "../../..", }, - 'nextjs-webpack': { - generatedStepPath: 'app/.well-known/workflow/v1/step/route.js', - generatedWorkflowPath: 'app/.well-known/workflow/v1/flow/route.js', - apiFilePath: 'app/api/chat/route.ts', - apiFileImportPath: '../../..', + "nextjs-webpack": { + generatedStepPath: "app/.well-known/workflow/v1/step/route.js", + generatedWorkflowPath: "app/.well-known/workflow/v1/flow/route.js", + apiFilePath: "app/api/chat/route.ts", + apiFileImportPath: "../../..", }, nitro: { - generatedStepPath: 'node_modules/.nitro/workflow/steps.mjs', - generatedWorkflowPath: 'node_modules/.nitro/workflow/workflows.mjs', - apiFilePath: 'routes/api/chat.post.ts', - apiFileImportPath: '../..', + generatedStepPath: "node_modules/.nitro/workflow/steps.mjs", + generatedWorkflowPath: "node_modules/.nitro/workflow/workflows.mjs", + apiFilePath: "routes/api/chat.post.ts", + apiFileImportPath: "../..", }, nuxt: { - generatedStepPath: '.nuxt/workflow/steps.mjs', - generatedWorkflowPath: '.nuxt/workflow/workflows.mjs', - apiFilePath: 'server/api/chat.post.ts', - apiFileImportPath: '../..', + generatedStepPath: ".nuxt/workflow/steps.mjs", + generatedWorkflowPath: ".nuxt/workflow/workflows.mjs", + apiFilePath: "server/api/chat.post.ts", + apiFileImportPath: "../..", }, sveltekit: { - generatedStepPath: 'src/routes/.well-known/workflow/v1/step/+server.js', - generatedWorkflowPath: 'src/routes/.well-known/workflow/v1/flow/+server.js', - apiFilePath: 'src/routes/api/chat/+server.ts', - apiFileImportPath: '../../../..', - workflowsDir: 'src/workflows', + generatedStepPath: "src/routes/.well-known/workflow/v1/step/+server.js", + generatedWorkflowPath: "src/routes/.well-known/workflow/v1/flow/+server.js", + apiFilePath: "src/routes/api/chat/+server.ts", + apiFileImportPath: "../../../..", + workflowsDir: "src/workflows", }, vite: { - generatedStepPath: 'node_modules/.nitro/workflow/steps.mjs', - generatedWorkflowPath: 'node_modules/.nitro/workflow/workflows.mjs', - apiFilePath: 'routes/api/trigger.post.ts', - apiFileImportPath: '../..', + generatedStepPath: "node_modules/.nitro/workflow/steps.mjs", + generatedWorkflowPath: "node_modules/.nitro/workflow/workflows.mjs", + apiFilePath: "routes/api/trigger.post.ts", + apiFileImportPath: "../..", }, hono: { - generatedStepPath: 'node_modules/.nitro/workflow/steps.mjs', - generatedWorkflowPath: 'node_modules/.nitro/workflow/workflows.mjs', - apiFilePath: './src/index.ts', - apiFileImportPath: '..', + generatedStepPath: "node_modules/.nitro/workflow/steps.mjs", + generatedWorkflowPath: "node_modules/.nitro/workflow/workflows.mjs", + apiFilePath: "./src/index.ts", + apiFileImportPath: "..", }, express: { - generatedStepPath: 'node_modules/.nitro/workflow/steps.mjs', - generatedWorkflowPath: 'node_modules/.nitro/workflow/workflows.mjs', - apiFilePath: './src/index.ts', - apiFileImportPath: '..', + generatedStepPath: "node_modules/.nitro/workflow/steps.mjs", + generatedWorkflowPath: "node_modules/.nitro/workflow/workflows.mjs", + apiFilePath: "./src/index.ts", + apiFileImportPath: "..", }, astro: { - generatedStepPath: 'src/pages/.well-known/workflow/v1/step.js', - generatedWorkflowPath: 'src/pages/.well-known/workflow/v1/flow.js', - apiFilePath: 'src/pages/api/chat.ts', - apiFileImportPath: '../..', + generatedStepPath: "src/pages/.well-known/workflow/v1/step.js", + generatedWorkflowPath: "src/pages/.well-known/workflow/v1/flow.js", + apiFilePath: "src/pages/api/chat.ts", + apiFileImportPath: "../..", }, }; const matrix = { app: [ { - name: 'nextjs-turbopack', - project: 'example-nextjs-workflow-turbopack', - ...DEV_TEST_CONFIGS['nextjs-turbopack'], + name: "nextjs-turbopack", + project: "example-nextjs-workflow-turbopack", + ...DEV_TEST_CONFIGS["nextjs-turbopack"], }, { - name: 'nextjs-webpack', - project: 'example-nextjs-workflow-webpack', - ...DEV_TEST_CONFIGS['nextjs-webpack'], + name: "nextjs-webpack", + project: "example-nextjs-workflow-webpack", + ...DEV_TEST_CONFIGS["nextjs-webpack"], }, ], }; -if (process.env.GITHUB_REF === 'refs/heads/main') { +if (process.env.GITHUB_REF === "refs/heads/main") { const newItems = []; for (const item of matrix.app) { @@ -83,39 +83,42 @@ if (process.env.GITHUB_REF === 'refs/heads/main') { // Manually add nitro matrix.app.push({ - name: 'nitro', - project: 'workbench-nitro-workflow', + name: "nitro", + project: "workbench-nitro-workflow", ...DEV_TEST_CONFIGS.nitro, }); matrix.app.push({ - name: 'sveltekit', - project: 'workbench-sveltekit-workflow', + name: "sveltekit", + project: "workbench-sveltekit-workflow", ...DEV_TEST_CONFIGS.sveltekit, }); matrix.app.push({ - name: 'nuxt', - project: 'workbench-nuxt-workflow', + name: "nuxt", + project: "workbench-nuxt-workflow", ...DEV_TEST_CONFIGS.nuxt, }); matrix.app.push({ - name: 'hono', - project: 'workbench-hono-workflow', + name: "hono", + project: "workbench-hono-workflow", ...DEV_TEST_CONFIGS.hono, }); matrix.app.push({ - name: 'vite', - project: 'workbench-vite-workflow', + name: "vite", + project: "workbench-vite-workflow", ...DEV_TEST_CONFIGS.vite, }); matrix.app.push({ - name: 'express', - project: 'workbench-express-workflow', + name: "express", + project: "workbench-express-workflow", ...DEV_TEST_CONFIGS.express, + name: "astro", + project: "workbench-astro-workflow", + ...DEV_TEST_CONFIGS.vite, }); console.log(JSON.stringify(matrix)); From 33403eb9e9f39a4eb080f3687a168307cf2c78a8 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 11:54:46 -0800 Subject: [PATCH 21/61] add astro start command --- workbench/astro/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/workbench/astro/package.json b/workbench/astro/package.json index 0c3a012ed..83e9cadfb 100644 --- a/workbench/astro/package.json +++ b/workbench/astro/package.json @@ -9,7 +9,8 @@ "dev": "astro dev", "build": "astro build", "preview": "astro preview", - "astro": "astro" + "astro": "astro", + "start": "node dist/server/entry.mjs" }, "dependencies": { "@astrojs/node": "9.5.0", From ddaba6573b9bbf7a7a63135db60d3752c991297c Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 11:57:24 -0800 Subject: [PATCH 22/61] update symlink --- workbench/astro/src/workflows | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workbench/astro/src/workflows b/workbench/astro/src/workflows index 5cdd2a9ca..13ef4d4f6 120000 --- a/workbench/astro/src/workflows +++ b/workbench/astro/src/workflows @@ -1 +1 @@ -../../nitro-v3/workflows \ No newline at end of file +../../example/workflows \ No newline at end of file From b8c6355bcff3a06113d8d5e1c5dd49b6f5eaa06d Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 12:01:06 -0800 Subject: [PATCH 23/61] fix astro test config --- docs/app/(home)/components/frameworks.tsx | 74 +++++------ packages/sveltekit/src/builder.ts | 64 ++++----- scripts/create-test-matrix.mjs | 125 +++++++++--------- workbench/example/workflows/7_full.ts | 18 +-- .../nextjs-turbopack/app/api/trigger/route.ts | 50 +++---- .../nextjs-webpack/app/api/trigger/route.ts | 54 ++++---- .../src/routes/api/trigger/+server.ts | 52 ++++---- .../sveltekit/src/workflows/user-signup.ts | 18 +-- workbench/vite/routes/api/hook.post.ts | 6 +- 9 files changed, 232 insertions(+), 229 deletions(-) diff --git a/docs/app/(home)/components/frameworks.tsx b/docs/app/(home)/components/frameworks.tsx index 1d21d9755..041871417 100644 --- a/docs/app/(home)/components/frameworks.tsx +++ b/docs/app/(home)/components/frameworks.tsx @@ -1,12 +1,12 @@ -"use client"; +'use client'; -import { track } from "@vercel/analytics"; -import Link from "next/link"; -import type { ComponentProps } from "react"; -import { toast } from "sonner"; -import { Badge } from "@/components/ui/badge"; +import { track } from '@vercel/analytics'; +import Link from 'next/link'; +import type { ComponentProps } from 'react'; +import { toast } from 'sonner'; +import { Badge } from '@/components/ui/badge'; -export const Express = (props: ComponentProps<"svg">) => ( +export const Express = (props: ComponentProps<'svg'>) => ( ) => ( ); -export const AstroDark = (props: ComponentProps<"svg">) => ( +export const AstroDark = (props: ComponentProps<'svg'>) => ( ) => ( ); -export const AstroLight = (props: ComponentProps<"svg">) => ( +export const AstroLight = (props: ComponentProps<'svg'>) => ( ) => ( ); -export const AstroGray = (props: ComponentProps<"svg">) => ( +export const AstroGray = (props: ComponentProps<'svg'>) => ( ) => ( ); -export const TanStack = (props: ComponentProps<"svg">) => ( +export const TanStack = (props: ComponentProps<'svg'>) => ( ) => ( ); -export const TanStackGray = (props: ComponentProps<"svg">) => ( +export const TanStackGray = (props: ComponentProps<'svg'>) => ( ) => ( ); -export const Vite = (props: ComponentProps<"svg">) => ( +export const Vite = (props: ComponentProps<'svg'>) => ( ) => ( ); -export const Nitro = (props: ComponentProps<"svg">) => ( +export const Nitro = (props: ComponentProps<'svg'>) => ( ) => ( /> ) => ( ); -export const SvelteKit = (props: ComponentProps<"svg">) => ( +export const SvelteKit = (props: ComponentProps<'svg'>) => ( ) => ( ); -export const SvelteKitGray = (props: ComponentProps<"svg">) => ( +export const SvelteKitGray = (props: ComponentProps<'svg'>) => ( ) => ( ); -export const Nuxt = (props: ComponentProps<"svg">) => ( +export const Nuxt = (props: ComponentProps<'svg'>) => ( ) => ( ); -export const NuxtGray = (props: ComponentProps<"svg">) => ( +export const NuxtGray = (props: ComponentProps<'svg'>) => ( ) => ( ); -export const Hono = (props: ComponentProps<"svg">) => ( +export const Hono = (props: ComponentProps<'svg'>) => ( Hono ) => ( ); -export const HonoGray = (props: ComponentProps<"svg">) => ( +export const HonoGray = (props: ComponentProps<'svg'>) => ( Hono ) => ( ); -export const Bun = (props: ComponentProps<"svg">) => ( +export const Bun = (props: ComponentProps<'svg'>) => ( ) => ( id="Top" d="M35.12,5.53A16.41,16.41,0,0,1,29.49,18c-.28.25-.06.73.3.59,3.37-1.31,7.92-5.23,6-13.14C35.71,5,35.12,5.12,35.12,5.53Zm2.27,0A16.24,16.24,0,0,1,39,19c-.12.35.31.65.55.36C41.74,16.56,43.65,11,37.93,5,37.64,4.74,37.19,5.14,37.39,5.49Zm2.76-.17A16.42,16.42,0,0,1,47,17.12a.33.33,0,0,0,.65.11c.92-3.49.4-9.44-7.17-12.53C40.08,4.54,39.82,5.08,40.15,5.32ZM21.69,15.76a16.94,16.94,0,0,0,10.47-9c.18-.36.75-.22.66.18-1.73,8-7.52,9.67-11.12,9.45C21.32,16.4,21.33,15.87,21.69,15.76Z" fill="#ccbea7" - style={{ fillRule: "evenodd" }} + style={{ fillRule: 'evenodd' }} /> ) => ( ); -export const BunGray = (props: ComponentProps<"svg">) => ( +export const BunGray = (props: ComponentProps<'svg'>) => ( ) => ( id="Top" d="M35.12,5.53A16.41,16.41,0,0,1,29.49,18c-.28.25-.06.73.3.59,3.37-1.31,7.92-5.23,6-13.14C35.71,5,35.12,5.12,35.12,5.53Zm2.27,0A16.24,16.24,0,0,1,39,19c-.12.35.31.65.55.36C41.74,16.56,43.65,11,37.93,5,37.64,4.74,37.19,5.14,37.39,5.49Zm2.76-.17A16.42,16.42,0,0,1,47,17.12a.33.33,0,0,0,.65.11c.92-3.49.4-9.44-7.17-12.53C40.08,4.54,39.82,5.08,40.15,5.32ZM21.69,15.76a16.94,16.94,0,0,0,10.47-9c.18-.36.75-.22.66.18-1.73,8-7.52,9.67-11.12,9.45C21.32,16.4,21.33,15.87,21.69,15.76Z" fill="var(--color-background)" - style={{ fillRule: "evenodd" }} + style={{ fillRule: 'evenodd' }} /> ) => ( ); -export const Nest = (props: ComponentProps<"svg">) => ( +export const Nest = (props: ComponentProps<'svg'>) => ( ) => ( ); -export const NestGray = (props: ComponentProps<"svg">) => ( +export const NestGray = (props: ComponentProps<'svg'>) => ( ) => ( ); -export const Next = (props: ComponentProps<"svg">) => ( +export const Next = (props: ComponentProps<'svg'>) => ( Next.js @@ -681,8 +681,8 @@ export const Next = (props: ComponentProps<"svg">) => ( export const Frameworks = () => { const handleRequest = (framework: string) => { - track("Framework requested", { framework: framework.toLowerCase() }); - toast.success("Request received", { + track('Framework requested', { framework: framework.toLowerCase() }); + toast.success('Request received', { description: `Thanks for expressing interest in ${framework}. We will be adding support for it soon.`, }); }; @@ -742,21 +742,21 @@ export const Frameworks = () => {
handleRequest("NestJS")} + onClick={() => handleRequest('NestJS')} >
handleRequest("TanStack")} + onClick={() => handleRequest('TanStack')} >
handleRequest("Astro")} + onClick={() => handleRequest('Astro')} > diff --git a/packages/sveltekit/src/builder.ts b/packages/sveltekit/src/builder.ts index 5a9e0ace6..52b4c8895 100644 --- a/packages/sveltekit/src/builder.ts +++ b/packages/sveltekit/src/builder.ts @@ -1,7 +1,7 @@ -import { constants } from "node:fs"; -import { access, mkdir, readFile, stat, writeFile } from "node:fs/promises"; -import { join, resolve } from "node:path"; -import { BaseBuilder, type SvelteKitConfig } from "@workflow/builders"; +import { constants } from 'node:fs'; +import { access, mkdir, readFile, stat, writeFile } from 'node:fs/promises'; +import { join, resolve } from 'node:path'; +import { BaseBuilder, type SvelteKitConfig } from '@workflow/builders'; // Helper function code for converting SvelteKit requests to standard Request objects const SVELTEKIT_REQUEST_CONVERTER = ` @@ -23,11 +23,11 @@ export class SvelteKitBuilder extends BaseBuilder { super({ ...config, - dirs: ["workflows", "src/workflows", "routes", "src/routes"], - buildTarget: "sveltekit" as const, - stepsBundlePath: "", // unused in base - workflowsBundlePath: "", // unused in base - webhookBundlePath: "", // unused in base + dirs: ['workflows', 'src/workflows', 'routes', 'src/routes'], + buildTarget: 'sveltekit' as const, + stepsBundlePath: '', // unused in base + workflowsBundlePath: '', // unused in base + webhookBundlePath: '', // unused in base workingDir, }); } @@ -35,14 +35,14 @@ export class SvelteKitBuilder extends BaseBuilder { override async build(): Promise { // Find SvelteKit routes directory (src/routes or routes) const routesDir = await this.findRoutesDirectory(); - const workflowGeneratedDir = join(routesDir, ".well-known/workflow/v1"); + const workflowGeneratedDir = join(routesDir, '.well-known/workflow/v1'); // Ensure output directories exist await mkdir(workflowGeneratedDir, { recursive: true }); // Add .gitignore to exclude generated files from version control if (process.env.VERCEL_DEPLOYMENT_ID === undefined) { - await writeFile(join(workflowGeneratedDir, ".gitignore"), "*"); + await writeFile(join(workflowGeneratedDir, '.gitignore'), '*'); } // Get workflow and step files to bundle @@ -74,21 +74,21 @@ export class SvelteKitBuilder extends BaseBuilder { tsPaths?: Record; }) { // Create steps route: .well-known/workflow/v1/step/+server.js - const stepsRouteDir = join(workflowGeneratedDir, "step"); + const stepsRouteDir = join(workflowGeneratedDir, 'step'); await mkdir(stepsRouteDir, { recursive: true }); await this.createStepsBundle({ - format: "esm", + format: 'esm', inputFiles, - outfile: join(stepsRouteDir, "+server.js"), + outfile: join(stepsRouteDir, '+server.js'), externalizeNonSteps: true, tsBaseUrl, tsPaths, }); // Post-process the generated file to wrap with SvelteKit request converter - const stepsRouteFile = join(stepsRouteDir, "+server.js"); - let stepsRouteContent = await readFile(stepsRouteFile, "utf-8"); + const stepsRouteFile = join(stepsRouteDir, '+server.js'); + let stepsRouteContent = await readFile(stepsRouteFile, 'utf-8'); // Replace the default export with SvelteKit-compatible handler stepsRouteContent = stepsRouteContent.replace( @@ -97,7 +97,7 @@ export class SvelteKitBuilder extends BaseBuilder { export const POST = async ({request}) => { const normalRequest = await convertSvelteKitRequest(request); return stepEntrypoint(normalRequest); -}`, +}` ); await writeFile(stepsRouteFile, stepsRouteContent); @@ -115,12 +115,12 @@ export const POST = async ({request}) => { tsPaths?: Record; }) { // Create workflows route: .well-known/workflow/v1/flow/+server.js - const workflowsRouteDir = join(workflowGeneratedDir, "flow"); + const workflowsRouteDir = join(workflowGeneratedDir, 'flow'); await mkdir(workflowsRouteDir, { recursive: true }); await this.createWorkflowsBundle({ - format: "esm", - outfile: join(workflowsRouteDir, "+server.js"), + format: 'esm', + outfile: join(workflowsRouteDir, '+server.js'), bundleFinalOutput: false, inputFiles, tsBaseUrl, @@ -128,8 +128,8 @@ export const POST = async ({request}) => { }); // Post-process the generated file to wrap with SvelteKit request converter - const workflowsRouteFile = join(workflowsRouteDir, "+server.js"); - let workflowsRouteContent = await readFile(workflowsRouteFile, "utf-8"); + const workflowsRouteFile = join(workflowsRouteDir, '+server.js'); + let workflowsRouteContent = await readFile(workflowsRouteFile, 'utf-8'); // Replace the default export with SvelteKit-compatible handler workflowsRouteContent = workflowsRouteContent.replace( @@ -138,7 +138,7 @@ export const POST = async ({request}) => { export const POST = async ({request}) => { const normalRequest = await convertSvelteKitRequest(request); return workflowEntrypoint(workflowCode)(normalRequest); -}`, +}` ); await writeFile(workflowsRouteFile, workflowsRouteContent); } @@ -151,7 +151,7 @@ export const POST = async ({request}) => { // Create webhook route: .well-known/workflow/v1/webhook/[token]/+server.js const webhookRouteFile = join( workflowGeneratedDir, - "webhook/[token]/+server.js", + 'webhook/[token]/+server.js' ); await this.createWebhookBundle({ @@ -160,18 +160,18 @@ export const POST = async ({request}) => { }); // Post-process the generated file to wrap with SvelteKit request converter - let webhookRouteContent = await readFile(webhookRouteFile, "utf-8"); + let webhookRouteContent = await readFile(webhookRouteFile, 'utf-8'); // Update handler signature to accept token as parameter webhookRouteContent = webhookRouteContent.replace( /async function handler\(request\) \{[\s\S]*?const token = decodeURIComponent\(pathParts\[pathParts\.length - 1\]\);/, - `async function handler(request, token) {`, + `async function handler(request, token) {` ); // Remove the URL parsing code since we get token from params webhookRouteContent = webhookRouteContent.replace( /const url = new URL\(request\.url\);[\s\S]*?const pathParts = url\.pathname\.split\('\/'\);[\s\S]*?\n/, - "", + '' ); // Replace all HTTP method exports with SvelteKit-compatible handlers @@ -190,15 +190,15 @@ export const PUT = createSvelteKitHandler('PUT'); export const PATCH = createSvelteKitHandler('PATCH'); export const DELETE = createSvelteKitHandler('DELETE'); export const HEAD = createSvelteKitHandler('HEAD'); -export const OPTIONS = createSvelteKitHandler('OPTIONS');`, +export const OPTIONS = createSvelteKitHandler('OPTIONS');` ); await writeFile(webhookRouteFile, webhookRouteContent); } private async findRoutesDirectory(): Promise { - const routesDir = resolve(this.config.workingDir, "src/routes"); - const rootRoutesDir = resolve(this.config.workingDir, "routes"); + const routesDir = resolve(this.config.workingDir, 'src/routes'); + const rootRoutesDir = resolve(this.config.workingDir, 'routes'); // Try src/routes first (standard SvelteKit convention) try { @@ -215,13 +215,13 @@ export const OPTIONS = createSvelteKitHandler('OPTIONS');`, const rootRoutesStats = await stat(rootRoutesDir); if (!rootRoutesStats.isDirectory()) { throw new Error( - `Path exists but is not a directory: ${rootRoutesDir}`, + `Path exists but is not a directory: ${rootRoutesDir}` ); } return rootRoutesDir; } catch { throw new Error( - 'Could not find SvelteKit routes directory. Expected either "src/routes" or "routes" to exist.', + 'Could not find SvelteKit routes directory. Expected either "src/routes" or "routes" to exist.' ); } } diff --git a/scripts/create-test-matrix.mjs b/scripts/create-test-matrix.mjs index 4ba3881a3..ab1cb9e04 100644 --- a/scripts/create-test-matrix.mjs +++ b/scripts/create-test-matrix.mjs @@ -1,78 +1,78 @@ // Framework-specific dev test configurations const DEV_TEST_CONFIGS = { - "nextjs-turbopack": { - generatedStepPath: "app/.well-known/workflow/v1/step/route.js", - generatedWorkflowPath: "app/.well-known/workflow/v1/flow/route.js", - apiFilePath: "app/api/chat/route.ts", - apiFileImportPath: "../../..", + 'nextjs-turbopack': { + generatedStepPath: 'app/.well-known/workflow/v1/step/route.js', + generatedWorkflowPath: 'app/.well-known/workflow/v1/flow/route.js', + apiFilePath: 'app/api/chat/route.ts', + apiFileImportPath: '../../..', }, - "nextjs-webpack": { - generatedStepPath: "app/.well-known/workflow/v1/step/route.js", - generatedWorkflowPath: "app/.well-known/workflow/v1/flow/route.js", - apiFilePath: "app/api/chat/route.ts", - apiFileImportPath: "../../..", + 'nextjs-webpack': { + generatedStepPath: 'app/.well-known/workflow/v1/step/route.js', + generatedWorkflowPath: 'app/.well-known/workflow/v1/flow/route.js', + apiFilePath: 'app/api/chat/route.ts', + apiFileImportPath: '../../..', }, nitro: { - generatedStepPath: "node_modules/.nitro/workflow/steps.mjs", - generatedWorkflowPath: "node_modules/.nitro/workflow/workflows.mjs", - apiFilePath: "routes/api/chat.post.ts", - apiFileImportPath: "../..", + generatedStepPath: 'node_modules/.nitro/workflow/steps.mjs', + generatedWorkflowPath: 'node_modules/.nitro/workflow/workflows.mjs', + apiFilePath: 'routes/api/chat.post.ts', + apiFileImportPath: '../..', }, nuxt: { - generatedStepPath: ".nuxt/workflow/steps.mjs", - generatedWorkflowPath: ".nuxt/workflow/workflows.mjs", - apiFilePath: "server/api/chat.post.ts", - apiFileImportPath: "../..", + generatedStepPath: '.nuxt/workflow/steps.mjs', + generatedWorkflowPath: '.nuxt/workflow/workflows.mjs', + apiFilePath: 'server/api/chat.post.ts', + apiFileImportPath: '../..', }, sveltekit: { - generatedStepPath: "src/routes/.well-known/workflow/v1/step/+server.js", - generatedWorkflowPath: "src/routes/.well-known/workflow/v1/flow/+server.js", - apiFilePath: "src/routes/api/chat/+server.ts", - apiFileImportPath: "../../../..", - workflowsDir: "src/workflows", + generatedStepPath: 'src/routes/.well-known/workflow/v1/step/+server.js', + generatedWorkflowPath: 'src/routes/.well-known/workflow/v1/flow/+server.js', + apiFilePath: 'src/routes/api/chat/+server.ts', + apiFileImportPath: '../../../..', + workflowsDir: 'src/workflows', }, vite: { - generatedStepPath: "node_modules/.nitro/workflow/steps.mjs", - generatedWorkflowPath: "node_modules/.nitro/workflow/workflows.mjs", - apiFilePath: "routes/api/trigger.post.ts", - apiFileImportPath: "../..", + generatedStepPath: 'node_modules/.nitro/workflow/steps.mjs', + generatedWorkflowPath: 'node_modules/.nitro/workflow/workflows.mjs', + apiFilePath: 'routes/api/trigger.post.ts', + apiFileImportPath: '../..', }, hono: { - generatedStepPath: "node_modules/.nitro/workflow/steps.mjs", - generatedWorkflowPath: "node_modules/.nitro/workflow/workflows.mjs", - apiFilePath: "./src/index.ts", - apiFileImportPath: "..", + generatedStepPath: 'node_modules/.nitro/workflow/steps.mjs', + generatedWorkflowPath: 'node_modules/.nitro/workflow/workflows.mjs', + apiFilePath: './src/index.ts', + apiFileImportPath: '..', }, express: { - generatedStepPath: "node_modules/.nitro/workflow/steps.mjs", - generatedWorkflowPath: "node_modules/.nitro/workflow/workflows.mjs", - apiFilePath: "./src/index.ts", - apiFileImportPath: "..", + generatedStepPath: 'node_modules/.nitro/workflow/steps.mjs', + generatedWorkflowPath: 'node_modules/.nitro/workflow/workflows.mjs', + apiFilePath: './src/index.ts', + apiFileImportPath: '..', }, astro: { - generatedStepPath: "src/pages/.well-known/workflow/v1/step.js", - generatedWorkflowPath: "src/pages/.well-known/workflow/v1/flow.js", - apiFilePath: "src/pages/api/chat.ts", - apiFileImportPath: "../..", + generatedStepPath: 'src/pages/.well-known/workflow/v1/step.js', + generatedWorkflowPath: 'src/pages/.well-known/workflow/v1/flow.js', + apiFilePath: 'src/pages/api/chat.ts', + apiFileImportPath: '../..', }, }; const matrix = { app: [ { - name: "nextjs-turbopack", - project: "example-nextjs-workflow-turbopack", - ...DEV_TEST_CONFIGS["nextjs-turbopack"], + name: 'nextjs-turbopack', + project: 'example-nextjs-workflow-turbopack', + ...DEV_TEST_CONFIGS['nextjs-turbopack'], }, { - name: "nextjs-webpack", - project: "example-nextjs-workflow-webpack", - ...DEV_TEST_CONFIGS["nextjs-webpack"], + name: 'nextjs-webpack', + project: 'example-nextjs-workflow-webpack', + ...DEV_TEST_CONFIGS['nextjs-webpack'], }, ], }; -if (process.env.GITHUB_REF === "refs/heads/main") { +if (process.env.GITHUB_REF === 'refs/heads/main') { const newItems = []; for (const item of matrix.app) { @@ -83,42 +83,45 @@ if (process.env.GITHUB_REF === "refs/heads/main") { // Manually add nitro matrix.app.push({ - name: "nitro", - project: "workbench-nitro-workflow", + name: 'nitro', + project: 'workbench-nitro-workflow', ...DEV_TEST_CONFIGS.nitro, }); matrix.app.push({ - name: "sveltekit", - project: "workbench-sveltekit-workflow", + name: 'sveltekit', + project: 'workbench-sveltekit-workflow', ...DEV_TEST_CONFIGS.sveltekit, }); matrix.app.push({ - name: "nuxt", - project: "workbench-nuxt-workflow", + name: 'nuxt', + project: 'workbench-nuxt-workflow', ...DEV_TEST_CONFIGS.nuxt, }); matrix.app.push({ - name: "hono", - project: "workbench-hono-workflow", + name: 'hono', + project: 'workbench-hono-workflow', ...DEV_TEST_CONFIGS.hono, }); matrix.app.push({ - name: "vite", - project: "workbench-vite-workflow", + name: 'vite', + project: 'workbench-vite-workflow', ...DEV_TEST_CONFIGS.vite, }); matrix.app.push({ - name: "express", - project: "workbench-express-workflow", + name: 'express', + project: 'workbench-express-workflow', ...DEV_TEST_CONFIGS.express, - name: "astro", - project: "workbench-astro-workflow", - ...DEV_TEST_CONFIGS.vite, +}); + +matrix.app.push({ + name: 'astro', + project: 'workbench-astro-workflow', + ...DEV_TEST_CONFIGS.astro, }); console.log(JSON.stringify(matrix)); diff --git a/workbench/example/workflows/7_full.ts b/workbench/example/workflows/7_full.ts index c035c2c67..173c7196e 100644 --- a/workbench/example/workflows/7_full.ts +++ b/workbench/example/workflows/7_full.ts @@ -1,24 +1,24 @@ -import { createWebhook, sleep } from "workflow"; +import { createWebhook, sleep } from 'workflow'; export async function handleUserSignup(email: string) { - "use workflow"; + 'use workflow'; const user = await createUser(email); await sendWelcomeEmail(user); - await sleep("5s"); + await sleep('5s'); const webhook = createWebhook(); await sendOnboardingEmail(user, webhook.url); await webhook; - console.log("Webhook Resolved"); + console.log('Webhook Resolved'); - return { userId: user.id, status: "onboarded" }; + return { userId: user.id, status: 'onboarded' }; } async function createUser(email: string) { - "use step"; + 'use step'; console.log(`Creating a new user with email: ${email}`); @@ -26,16 +26,16 @@ async function createUser(email: string) { } async function sendWelcomeEmail(user: { id: string; email: string }) { - "use step"; + 'use step'; console.log(`Sending welcome email to user: ${user.id}`); } async function sendOnboardingEmail( user: { id: string; email: string }, - callback: string, + callback: string ) { - "use step"; + 'use step'; console.log(`Sending onboarding email to user: ${user.id}`); diff --git a/workbench/nextjs-turbopack/app/api/trigger/route.ts b/workbench/nextjs-turbopack/app/api/trigger/route.ts index ac559d5d1..f9b8d5ef4 100644 --- a/workbench/nextjs-turbopack/app/api/trigger/route.ts +++ b/workbench/nextjs-turbopack/app/api/trigger/route.ts @@ -1,17 +1,17 @@ -import { getRun, start } from "workflow/api"; +import { getRun, start } from 'workflow/api'; import { WorkflowRunFailedError, WorkflowRunNotCompletedError, -} from "workflow/internal/errors"; -import { hydrateWorkflowArguments } from "workflow/internal/serialization"; -import { allWorkflows } from "@/_workflows"; +} from 'workflow/internal/errors'; +import { hydrateWorkflowArguments } from 'workflow/internal/serialization'; +import { allWorkflows } from '@/_workflows'; export async function POST(req: Request) { const url = new URL(req.url); const workflowFile = - url.searchParams.get("workflowFile") || "workflows/99_e2e.ts"; + url.searchParams.get('workflowFile') || 'workflows/99_e2e.ts'; if (!workflowFile) { - return new Response("No workflowFile query parameter provided", { + return new Response('No workflowFile query parameter provided', { status: 400, }); } @@ -22,9 +22,9 @@ export async function POST(req: Request) { }); } - const workflowFn = url.searchParams.get("workflowFn") || "simple"; + const workflowFn = url.searchParams.get('workflowFn') || 'simple'; if (!workflowFn) { - return new Response("No workflow query parameter provided", { + return new Response('No workflow query parameter provided', { status: 400, }); } @@ -36,9 +36,9 @@ export async function POST(req: Request) { let args: any[] = []; // Args from query string - const argsParam = url.searchParams.get("args"); + const argsParam = url.searchParams.get('args'); if (argsParam) { - args = argsParam.split(",").map((arg) => { + args = argsParam.split(',').map((arg) => { const num = parseFloat(arg); return Number.isNaN(num) ? arg.trim() : num; }); @@ -55,7 +55,7 @@ export async function POST(req: Request) { try { const run = await start(workflow as any, args as any); - console.log("Run:", run); + console.log('Run:', run); return Response.json(run); } catch (err) { console.error(`Failed to start!!`, err); @@ -65,14 +65,14 @@ export async function POST(req: Request) { export async function GET(req: Request) { const url = new URL(req.url); - const runId = url.searchParams.get("runId"); + const runId = url.searchParams.get('runId'); if (!runId) { - return new Response("No runId provided", { status: 400 }); + return new Response('No runId provided', { status: 400 }); } - const outputStreamParam = url.searchParams.get("output-stream"); + const outputStreamParam = url.searchParams.get('output-stream'); if (outputStreamParam) { - const namespace = outputStreamParam === "1" ? undefined : outputStreamParam; + const namespace = outputStreamParam === '1' ? undefined : outputStreamParam; const run = getRun(runId); const stream = run.getReadable({ namespace, @@ -82,14 +82,14 @@ export async function GET(req: Request) { transform(chunk, controller) { const data = chunk instanceof Uint8Array - ? { data: Buffer.from(chunk).toString("base64") } + ? { data: Buffer.from(chunk).toString('base64') } : chunk; controller.enqueue(`${JSON.stringify(data)}\n`); }, }); return new Response(stream.pipeThrough(streamWithFraming), { headers: { - "Content-Type": "application/octet-stream", + 'Content-Type': 'application/octet-stream', }, }); } @@ -97,11 +97,11 @@ export async function GET(req: Request) { try { const run = getRun(runId); const returnValue = await run.returnValue; - console.log("Return value:", returnValue); + console.log('Return value:', returnValue); return returnValue instanceof ReadableStream ? new Response(returnValue, { headers: { - "Content-Type": "application/octet-stream", + 'Content-Type': 'application/octet-stream', }, }) : Response.json(returnValue); @@ -114,7 +114,7 @@ export async function GET(req: Request) { name: error.name, message: error.message, }, - { status: 202 }, + { status: 202 } ); } @@ -131,20 +131,20 @@ export async function GET(req: Request) { code: cause.code, }, }, - { status: 400 }, + { status: 400 } ); } } console.error( - "Unexpected error while getting workflow return value:", - error, + 'Unexpected error while getting workflow return value:', + error ); return Response.json( { - error: "Internal server error", + error: 'Internal server error', }, - { status: 500 }, + { status: 500 } ); } } diff --git a/workbench/nextjs-webpack/app/api/trigger/route.ts b/workbench/nextjs-webpack/app/api/trigger/route.ts index 76737ef22..d1dafb427 100644 --- a/workbench/nextjs-webpack/app/api/trigger/route.ts +++ b/workbench/nextjs-webpack/app/api/trigger/route.ts @@ -1,25 +1,25 @@ -import { getRun, start } from "workflow/api"; +import { getRun, start } from 'workflow/api'; import { WorkflowRunFailedError, WorkflowRunNotCompletedError, -} from "workflow/internal/errors"; -import { hydrateWorkflowArguments } from "workflow/internal/serialization"; -import { allWorkflows } from "@/_workflows"; +} from 'workflow/internal/errors'; +import { hydrateWorkflowArguments } from 'workflow/internal/serialization'; +import { allWorkflows } from '@/_workflows'; export async function POST(req: Request) { const url = new URL(req.url); const workflowFile = - url.searchParams.get("workflowFile") || "workflows/99_e2e.ts"; - const workflowFn = url.searchParams.get("workflowFn") || "simple"; + url.searchParams.get('workflowFile') || 'workflows/99_e2e.ts'; + const workflowFn = url.searchParams.get('workflowFn') || 'simple'; - console.log("calling workflow", { workflowFile, workflowFn }); + console.log('calling workflow', { workflowFile, workflowFn }); let args: any[] = []; // Args from query string - const argsParam = url.searchParams.get("args"); + const argsParam = url.searchParams.get('args'); if (argsParam) { - args = argsParam.split(",").map((arg) => { + args = argsParam.split(',').map((arg) => { const num = parseFloat(arg); return Number.isNaN(num) ? arg.trim() : num; }); @@ -33,7 +33,7 @@ export async function POST(req: Request) { } } console.log( - `Starting "${workflowFile}/${workflowFn}" workflow with args: ${args}`, + `Starting "${workflowFile}/${workflowFn}" workflow with args: ${args}` ); try { @@ -41,7 +41,7 @@ export async function POST(req: Request) { if (!workflows) { return Response.json( { error: `Workflow file "${workflowFile}" not found` }, - { status: 404 }, + { status: 404 } ); } @@ -49,12 +49,12 @@ export async function POST(req: Request) { if (!workflow) { return Response.json( { error: `Function "${workflowFn}" not found in ${workflowFile}` }, - { status: 400 }, + { status: 400 } ); } const run = await start(workflow as any, args); - console.log("Run:", run); + console.log('Run:', run); return Response.json(run); } catch (err) { console.error(`Failed to start!!`, err); @@ -64,14 +64,14 @@ export async function POST(req: Request) { export async function GET(req: Request) { const url = new URL(req.url); - const runId = url.searchParams.get("runId"); + const runId = url.searchParams.get('runId'); if (!runId) { - return new Response("No runId provided", { status: 400 }); + return new Response('No runId provided', { status: 400 }); } - const outputStreamParam = url.searchParams.get("output-stream"); + const outputStreamParam = url.searchParams.get('output-stream'); if (outputStreamParam) { - const namespace = outputStreamParam === "1" ? undefined : outputStreamParam; + const namespace = outputStreamParam === '1' ? undefined : outputStreamParam; const run = getRun(runId); const stream = run.getReadable({ namespace, @@ -81,14 +81,14 @@ export async function GET(req: Request) { transform(chunk, controller) { const data = chunk instanceof Uint8Array - ? { data: Buffer.from(chunk).toString("base64") } + ? { data: Buffer.from(chunk).toString('base64') } : chunk; controller.enqueue(`${JSON.stringify(data)}\n`); }, }); return new Response(stream.pipeThrough(streamWithFraming), { headers: { - "Content-Type": "application/octet-stream", + 'Content-Type': 'application/octet-stream', }, }); } @@ -96,11 +96,11 @@ export async function GET(req: Request) { try { const run = getRun(runId); const returnValue = await run.returnValue; - console.log("Return value:", returnValue); + console.log('Return value:', returnValue); return returnValue instanceof ReadableStream ? new Response(returnValue, { headers: { - "Content-Type": "application/octet-stream", + 'Content-Type': 'application/octet-stream', }, }) : Response.json(returnValue); @@ -113,7 +113,7 @@ export async function GET(req: Request) { name: error.name, message: error.message, }, - { status: 202 }, + { status: 202 } ); } @@ -130,20 +130,20 @@ export async function GET(req: Request) { code: cause.code, }, }, - { status: 400 }, + { status: 400 } ); } } console.error( - "Unexpected error while getting workflow return value:", - error, + 'Unexpected error while getting workflow return value:', + error ); return Response.json( { - error: "Internal server error", + error: 'Internal server error', }, - { status: 500 }, + { status: 500 } ); } } diff --git a/workbench/sveltekit/src/routes/api/trigger/+server.ts b/workbench/sveltekit/src/routes/api/trigger/+server.ts index bf1801826..6492f436d 100644 --- a/workbench/sveltekit/src/routes/api/trigger/+server.ts +++ b/workbench/sveltekit/src/routes/api/trigger/+server.ts @@ -1,18 +1,18 @@ -import type { RequestHandler } from "@sveltejs/kit"; -import { getRun, start } from "workflow/api"; +import type { RequestHandler } from '@sveltejs/kit'; +import { getRun, start } from 'workflow/api'; import { WorkflowRunFailedError, WorkflowRunNotCompletedError, -} from "workflow/internal/errors"; -import { hydrateWorkflowArguments } from "workflow/internal/serialization"; -import { allWorkflows } from "$lib/_workflows.js"; +} from 'workflow/internal/errors'; +import { hydrateWorkflowArguments } from 'workflow/internal/serialization'; +import { allWorkflows } from '$lib/_workflows.js'; export const POST: RequestHandler = async ({ request }) => { const url = new URL(request.url); const workflowFile = - url.searchParams.get("workflowFile") || "workflows/99_e2e.ts"; + url.searchParams.get('workflowFile') || 'workflows/99_e2e.ts'; if (!workflowFile) { - return new Response("No workflowFile query parameter provided", { + return new Response('No workflowFile query parameter provided', { status: 400, }); } @@ -23,9 +23,9 @@ export const POST: RequestHandler = async ({ request }) => { }); } - const workflowFn = url.searchParams.get("workflowFn") || "simple"; + const workflowFn = url.searchParams.get('workflowFn') || 'simple'; if (!workflowFn) { - return new Response("No workflow query parameter provided", { + return new Response('No workflow query parameter provided', { status: 400, }); } @@ -37,9 +37,9 @@ export const POST: RequestHandler = async ({ request }) => { let args: any[] = []; // Args from query string - const argsParam = url.searchParams.get("args"); + const argsParam = url.searchParams.get('args'); if (argsParam) { - args = argsParam.split(",").map((arg) => { + args = argsParam.split(',').map((arg) => { const num = parseFloat(arg); return Number.isNaN(num) ? arg.trim() : num; }); @@ -56,7 +56,7 @@ export const POST: RequestHandler = async ({ request }) => { try { const run = await start(workflow as any, args as any); - console.log("Run:", run); + console.log('Run:', run); return Response.json(run); } catch (err) { console.error(`Failed to start!!`, err); @@ -66,14 +66,14 @@ export const POST: RequestHandler = async ({ request }) => { export const GET: RequestHandler = async ({ request }) => { const url = new URL(request.url); - const runId = url.searchParams.get("runId"); + const runId = url.searchParams.get('runId'); if (!runId) { - return new Response("No runId provided", { status: 400 }); + return new Response('No runId provided', { status: 400 }); } - const outputStreamParam = url.searchParams.get("output-stream"); + const outputStreamParam = url.searchParams.get('output-stream'); if (outputStreamParam) { - const namespace = outputStreamParam === "1" ? undefined : outputStreamParam; + const namespace = outputStreamParam === '1' ? undefined : outputStreamParam; const run = getRun(runId); const stream = run.getReadable({ namespace, @@ -83,14 +83,14 @@ export const GET: RequestHandler = async ({ request }) => { transform(chunk, controller) { const data = chunk instanceof Uint8Array - ? { data: Buffer.from(chunk).toString("base64") } + ? { data: Buffer.from(chunk).toString('base64') } : chunk; controller.enqueue(`${JSON.stringify(data)}\n`); }, }); return new Response(stream.pipeThrough(streamWithFraming), { headers: { - "Content-Type": "application/octet-stream", + 'Content-Type': 'application/octet-stream', }, }); } @@ -98,11 +98,11 @@ export const GET: RequestHandler = async ({ request }) => { try { const run = getRun(runId); const returnValue = await run.returnValue; - console.log("Return value:", returnValue); + console.log('Return value:', returnValue); return returnValue instanceof ReadableStream ? new Response(returnValue, { headers: { - "Content-Type": "application/octet-stream", + 'Content-Type': 'application/octet-stream', }, }) : Response.json(returnValue); @@ -115,7 +115,7 @@ export const GET: RequestHandler = async ({ request }) => { name: error.name, message: error.message, }, - { status: 202 }, + { status: 202 } ); } @@ -132,20 +132,20 @@ export const GET: RequestHandler = async ({ request }) => { code: cause.code, }, }, - { status: 400 }, + { status: 400 } ); } } console.error( - "Unexpected error while getting workflow return value:", - error, + 'Unexpected error while getting workflow return value:', + error ); return Response.json( { - error: "Internal server error", + error: 'Internal server error', }, - { status: 500 }, + { status: 500 } ); } }; diff --git a/workbench/sveltekit/src/workflows/user-signup.ts b/workbench/sveltekit/src/workflows/user-signup.ts index c035c2c67..173c7196e 100644 --- a/workbench/sveltekit/src/workflows/user-signup.ts +++ b/workbench/sveltekit/src/workflows/user-signup.ts @@ -1,24 +1,24 @@ -import { createWebhook, sleep } from "workflow"; +import { createWebhook, sleep } from 'workflow'; export async function handleUserSignup(email: string) { - "use workflow"; + 'use workflow'; const user = await createUser(email); await sendWelcomeEmail(user); - await sleep("5s"); + await sleep('5s'); const webhook = createWebhook(); await sendOnboardingEmail(user, webhook.url); await webhook; - console.log("Webhook Resolved"); + console.log('Webhook Resolved'); - return { userId: user.id, status: "onboarded" }; + return { userId: user.id, status: 'onboarded' }; } async function createUser(email: string) { - "use step"; + 'use step'; console.log(`Creating a new user with email: ${email}`); @@ -26,16 +26,16 @@ async function createUser(email: string) { } async function sendWelcomeEmail(user: { id: string; email: string }) { - "use step"; + 'use step'; console.log(`Sending welcome email to user: ${user.id}`); } async function sendOnboardingEmail( user: { id: string; email: string }, - callback: string, + callback: string ) { - "use step"; + 'use step'; console.log(`Sending onboarding email to user: ${user.id}`); diff --git a/workbench/vite/routes/api/hook.post.ts b/workbench/vite/routes/api/hook.post.ts index 3065b8b6d..ecbdc636c 100644 --- a/workbench/vite/routes/api/hook.post.ts +++ b/workbench/vite/routes/api/hook.post.ts @@ -1,4 +1,4 @@ -import { getHookByToken, resumeHook } from "workflow/api"; +import { getHookByToken, resumeHook } from 'workflow/api'; export default async ({ req }: { req: Request }) => { const { token, data } = await req.json(); @@ -6,9 +6,9 @@ export default async ({ req }: { req: Request }) => { let hook: Awaited>; try { hook = await getHookByToken(token); - console.log("hook", hook); + console.log('hook', hook); } catch (error) { - console.log("error during getHookByToken", error); + console.log('error during getHookByToken', error); // TODO: `WorkflowAPIError` is not exported, so for now // we'll return 422 assuming it's the "invalid" token test case // NOTE: Need to return 422 because Nitro passes 404 requests to the dev server to handle. From 671ad64718572e86f7dc181263c59cc23f81a1b1 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 12:03:34 -0800 Subject: [PATCH 24/61] fix: override path-to-regexp to patched version 6.3.0 to resolve CVE --- package.json | 3 ++- pnpm-lock.yaml | 19 +++++-------------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 5e80e2d39..f5e934c8e 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,8 @@ "packageManager": "pnpm@10.20.0+sha512.cf9998222162dd85864d0a8102e7892e7ba4ceadebbf5a31f9c2fce48dfce317a9c53b9f6464d1ef9042cba2e02ae02a9f7c143a2b438cd93c91840f0192b9dd", "pnpm": { "overrides": { - "rfc6902": "5.1.2" + "rfc6902": "5.1.2", + "path-to-regexp": "6.3.0" }, "onlyBuiltDependencies": [ "bun" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e2de9bfe0..81f136ad9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -45,6 +45,7 @@ catalogs: overrides: rfc6902: 5.1.2 + path-to-regexp: 6.3.0 importers: @@ -10551,15 +10552,9 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} - path-to-regexp@6.1.0: - resolution: {integrity: sha512-h9DqehX3zZZDCEm+xbfU0ZmwCGFCAAraPJWMXJ4+v32NjZJilVg3k1TcKsRgIb8IQ/izZSaydDc1OhJCZvs2Dw==} - path-to-regexp@6.3.0: resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} - path-to-regexp@8.3.0: - resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} - path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -18690,7 +18685,7 @@ snapshots: '@vercel/routing-utils@5.3.0': dependencies: - path-to-regexp: 6.1.0 + path-to-regexp: 6.3.0 path-to-regexp-updated: path-to-regexp@6.3.0 optionalDependencies: ajv: 6.12.6 @@ -20990,7 +20985,7 @@ snapshots: image-size: 2.0.2 negotiator: 1.0.0 npm-to-yarn: 3.0.1 - path-to-regexp: 8.3.0 + path-to-regexp: 6.3.0 remark: 15.0.1 remark-gfm: 4.0.1 remark-rehype: 11.1.2 @@ -21019,7 +21014,7 @@ snapshots: image-size: 2.0.2 negotiator: 1.0.0 npm-to-yarn: 3.0.1 - path-to-regexp: 8.3.0 + path-to-regexp: 6.3.0 remark: 15.0.1 remark-gfm: 4.0.1 remark-rehype: 11.1.2 @@ -23959,12 +23954,8 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.2 - path-to-regexp@6.1.0: {} - path-to-regexp@6.3.0: {} - path-to-regexp@8.3.0: {} - path-type@4.0.0: {} path-type@6.0.0: {} @@ -25038,7 +25029,7 @@ snapshots: depd: 2.0.0 is-promise: 4.0.0 parseurl: 1.3.3 - path-to-regexp: 8.3.0 + path-to-regexp: 6.3.0 transitivePeerDependencies: - supports-color From b902021533d017f98b34a92e062dfb7ffbf48aae Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 12:49:10 -0800 Subject: [PATCH 25/61] fix: missing vercel functions on astro builder --- packages/astro/package.json | 6 +- packages/astro/src/builder.ts | 34 ++++++++- packages/astro/src/index.ts | 12 +-- packages/astro/src/plugin.ts | 46 ++++++----- pnpm-lock.yaml | 126 +++++++++++++++++++++++++++++++ workbench/astro/astro.config.mjs | 2 +- 6 files changed, 198 insertions(+), 28 deletions(-) diff --git a/packages/astro/package.json b/packages/astro/package.json index 29bddf9e4..ebab8a172 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -28,14 +28,18 @@ "@swc/core": "1.11.24", "@workflow/builders": "workspace:*", "@workflow/swc-plugin": "workspace:*", - "fs-extra": "^11.3.2", "exsolve": "^1.0.7", + "fs-extra": "^11.3.2", "pathe": "^2.0.3" }, "devDependencies": { "@types/fs-extra": "11.0.4", "@types/node": "catalog:", "@workflow/tsconfig": "workspace:*", + "astro": "^5.15.6", "vite": "7.1.11" + }, + "peerDependencies": { + "astro": "^5.0.0" } } diff --git a/packages/astro/src/builder.ts b/packages/astro/src/builder.ts index d8baad64d..52eb5d3b3 100644 --- a/packages/astro/src/builder.ts +++ b/packages/astro/src/builder.ts @@ -1,6 +1,11 @@ import { mkdir, readFile, rename, writeFile } from 'node:fs/promises'; import { join, resolve } from 'node:path'; -import { BaseBuilder, type AstroConfig } from '@workflow/builders'; +import { + BaseBuilder, + VercelBuildOutputAPIBuilder, + createBaseBuilderConfig, + type AstroConfig, +} from '@workflow/builders'; // NOTE: This is the same as SvelteKit request converter, should merge const NORMALIZE_REQUEST_CONVERTER = ` @@ -22,7 +27,7 @@ const DEBUG_FILES = [ 'step.js.debug.json', ]; -export class AstroBuilder extends BaseBuilder { +export class LocalBuilder extends BaseBuilder { constructor(config?: Partial) { const workingDir = config?.workingDir || process.cwd(); @@ -200,3 +205,28 @@ export const prerender = false;` await writeFile(webhookRouteFile, webhookRouteContent); } } + +export class VercelBuilder extends VercelBuildOutputAPIBuilder { + constructor(config?: Partial) { + const workingDir = config?.workingDir || process.cwd(); + super({ + ...createBaseBuilderConfig({ + workingDir, + dirs: ['src/pages'], + }), + buildTarget: 'vercel-build-output-api', + }); + } + override async build(): Promise { + // const configPath = join( + // this.config.workingDir, + // ".vercel/output/config.json", + // ); + // const originalConfig = JSON.parse(await readFile(configPath, "utf-8")); + await super.build(); + console.log('built vercel build output api'); + // const newConfig = JSON.parse(await readFile(configPath, "utf-8")); + // originalConfig.routes.unshift(...newConfig.routes); + // await writeFile(configPath, JSON.stringify(originalConfig, null, 2)); + } +} diff --git a/packages/astro/src/index.ts b/packages/astro/src/index.ts index fc75a122d..818cb5802 100644 --- a/packages/astro/src/index.ts +++ b/packages/astro/src/index.ts @@ -1,10 +1,10 @@ -import { AstroBuilder } from './builder.js'; +// import { LocalBuilder } from "./builder.js"; -const builder = new AstroBuilder(); +// const builder = new LocalBuilder(); -// This needs to be in the top-level as we need to create these -// entries before svelte plugin is started or the entries are -// a race to be created before svelte discovers entries -await builder.build(); +// // This needs to be in the top-level as we need to create these +// // entries before astro plugin is started or the entries are +// // a race to be created before astro discovers entries +// await builder.build(); export { workflowPlugin } from './plugin.js'; diff --git a/packages/astro/src/plugin.ts b/packages/astro/src/plugin.ts index 48096dd01..18b02d4f3 100644 --- a/packages/astro/src/plugin.ts +++ b/packages/astro/src/plugin.ts @@ -1,22 +1,38 @@ import { relative } from 'node:path'; import { transform } from '@swc/core'; import { resolveModulePath } from 'exsolve'; -import type { HotUpdateOptions, Plugin } from 'vite'; -import { AstroBuilder } from './builder.js'; - -export interface WorkflowPluginOptions { - /** - * Directories to scan for workflow files. - * If not specified, defaults to ['workflows', 'src/workflows', 'routes', 'src/routes'] - */ - dirs?: string[]; -} +import type { HotUpdateOptions, PluginOption } from 'vite'; +import type { AstroIntegration } from 'astro'; +import { LocalBuilder, VercelBuilder } from './builder.js'; -export function workflowPlugin(options?: WorkflowPluginOptions): Plugin { - let builder: AstroBuilder; +export function workflowPlugin(): AstroIntegration { + const builder = new LocalBuilder(); return { name: 'workflow:astro', + hooks: { + 'astro:config:setup': async ({ updateConfig }) => { + await builder.build(); + updateConfig({ + vite: { + plugins: [createVitePlugin(builder) as any], + }, + }); + }, + 'astro:build:done': async () => { + // Check if we're building for Vercel + if (process.env.VERCEL_DEPLOYMENT_ID) { + const vercelBuilder = new VercelBuilder(); + await vercelBuilder.build(); + } + }, + }, + }; +} + +function createVitePlugin(builder: LocalBuilder): PluginOption { + return { + name: 'workflow:astro:vite', // TODO: Move this to @workflow/vite or something since this is vite specific // Transform workflow files with SWC @@ -96,12 +112,6 @@ export function workflowPlugin(options?: WorkflowPluginOptions): Plugin { }; }, - configResolved() { - builder = new AstroBuilder({ - dirs: options?.dirs, - }); - }, - // TODO: Move this to @workflow/vite or something since this is vite specific async hotUpdate(options: HotUpdateOptions) { const { file, server, read } = options; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 81f136ad9..10a0b51fc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -345,6 +345,9 @@ importers: '@workflow/tsconfig': specifier: workspace:* version: link:../tsconfig + astro: + specifier: ^5.15.6 + version: 5.16.0(@netlify/blobs@9.1.2)(@types/node@22.19.0)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1) vite: specifier: 7.1.11 version: 7.1.11(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) @@ -19120,6 +19123,108 @@ snapshots: astring@1.9.0: {} + astro@5.16.0(@netlify/blobs@9.1.2)(@types/node@22.19.0)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1): + dependencies: + '@astrojs/compiler': 2.13.0 + '@astrojs/internal-helpers': 0.7.5 + '@astrojs/markdown-remark': 6.3.9 + '@astrojs/telemetry': 3.3.0 + '@capsizecss/unpack': 3.0.1 + '@oslojs/encoding': 1.1.0 + '@rollup/pluginutils': 5.3.0(rollup@4.53.3) + acorn: 8.15.0 + aria-query: 5.3.2 + axobject-query: 4.1.0 + boxen: 8.0.1 + ci-info: 4.3.1 + clsx: 2.1.1 + common-ancestor-path: 1.0.1 + cookie: 1.0.2 + cssesc: 3.0.0 + debug: 4.4.3(supports-color@8.1.1) + deterministic-object-hash: 2.0.2 + devalue: 5.5.0 + diff: 5.2.0 + dlv: 1.1.3 + dset: 3.1.4 + es-module-lexer: 1.7.0 + esbuild: 0.25.12 + estree-walker: 3.0.3 + flattie: 1.1.1 + fontace: 0.3.1 + github-slugger: 2.0.0 + html-escaper: 3.0.3 + http-cache-semantics: 4.2.0 + import-meta-resolve: 4.2.0 + js-yaml: 4.1.1 + magic-string: 0.30.21 + magicast: 0.5.1 + mrmime: 2.0.1 + neotraverse: 0.6.18 + p-limit: 6.2.0 + p-queue: 8.1.1 + package-manager-detector: 1.5.0 + piccolore: 0.1.3 + picomatch: 4.0.3 + prompts: 2.4.2 + rehype: 13.0.2 + semver: 7.7.3 + shiki: 3.15.0 + smol-toml: 1.5.2 + svgo: 4.0.0 + tinyexec: 1.0.2 + tinyglobby: 0.2.15 + tsconfck: 3.1.6(typescript@5.9.3) + ultrahtml: 1.6.0 + unifont: 0.6.0 + unist-util-visit: 5.0.0 + unstorage: 1.17.3(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2) + vfile: 6.0.3 + vite: 6.4.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vitefu: 1.1.1(vite@6.4.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + xxhash-wasm: 1.1.0 + yargs-parser: 21.1.1 + yocto-spinner: 0.2.3 + zod: 3.25.76 + zod-to-json-schema: 3.25.0(zod@3.25.76) + zod-to-ts: 1.2.0(typescript@5.9.3)(zod@3.25.76) + optionalDependencies: + sharp: 0.34.4 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@types/node' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - db0 + - idb-keyval + - ioredis + - jiti + - less + - lightningcss + - rollup + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - typescript + - uploadthing + - yaml + astro@5.16.0(@netlify/blobs@9.1.2)(@types/node@24.6.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1): dependencies: '@astrojs/compiler': 2.13.0 @@ -26376,6 +26481,23 @@ snapshots: vite: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vue: 3.5.22(typescript@5.9.3) + vite@6.4.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): + dependencies: + esbuild: 0.25.12 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.53.3 + tinyglobby: 0.2.14 + optionalDependencies: + '@types/node': 22.19.0 + fsevents: 2.3.3 + jiti: 2.6.1 + lightningcss: 1.30.1 + terser: 5.44.0 + tsx: 4.20.6 + yaml: 2.8.1 + vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): dependencies: esbuild: 0.25.12 @@ -26444,6 +26566,10 @@ snapshots: tsx: 4.20.6 yaml: 2.8.1 + vitefu@1.1.1(vite@6.4.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): + optionalDependencies: + vite: 6.4.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vitefu@1.1.1(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): optionalDependencies: vite: 6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) diff --git a/workbench/astro/astro.config.mjs b/workbench/astro/astro.config.mjs index 5207c6670..dc02faed2 100644 --- a/workbench/astro/astro.config.mjs +++ b/workbench/astro/astro.config.mjs @@ -12,7 +12,7 @@ const adapter = process.env.VERCEL_DEPLOYMENT_ID // https://astro.build/config export default defineConfig({ - vite: { plugins: [workflowPlugin()] }, + integrations: [workflowPlugin()], adapter: adapter, security: { checkOrigin: false, From db060ce655b2ffb3e34761f3a9b4ac35afbfcfeb Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 13:26:40 -0800 Subject: [PATCH 26/61] test --- packages/astro/src/builder.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/astro/src/builder.ts b/packages/astro/src/builder.ts index 52eb5d3b3..cb6cfa801 100644 --- a/packages/astro/src/builder.ts +++ b/packages/astro/src/builder.ts @@ -71,11 +71,11 @@ export class LocalBuilder extends BaseBuilder { await this.buildWebhookRoute({ workflowGeneratedDir }); // Astro requires non-api routes to be prefixed with _ (debug files) - for (const file of DEBUG_FILES) { - const filePath = join(workflowGeneratedDir, file); - const prefixedFilePath = join(workflowGeneratedDir, `_${file}`); - await rename(filePath, prefixedFilePath); - } + // for (const file of DEBUG_FILES) { + // const filePath = join(workflowGeneratedDir, file); + // const prefixedFilePath = join(workflowGeneratedDir, `_${file}`); + // await rename(filePath, prefixedFilePath); + // } } private async buildStepsRoute({ From db3777abcb96c8d48f45f18cfc8dcf29d6402a27 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 13:28:29 -0800 Subject: [PATCH 27/61] test --- packages/astro/src/builder.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/astro/src/builder.ts b/packages/astro/src/builder.ts index cb6cfa801..b89dabf0f 100644 --- a/packages/astro/src/builder.ts +++ b/packages/astro/src/builder.ts @@ -1,4 +1,4 @@ -import { mkdir, readFile, rename, writeFile } from 'node:fs/promises'; +import { mkdir, readFile, writeFile } from 'node:fs/promises'; import { join, resolve } from 'node:path'; import { BaseBuilder, @@ -21,11 +21,11 @@ async function normalizeRequestConverter(request) { } `; -const DEBUG_FILES = [ - 'flow.js.debug.json', - 'manifest.debug.json', - 'step.js.debug.json', -]; +// const DEBUG_FILES = [ +// "flow.js.debug.json", +// "manifest.debug.json", +// "step.js.debug.json", +// ]; export class LocalBuilder extends BaseBuilder { constructor(config?: Partial) { From 33f4e89409990f54e424d91ebf09837e52bb9626 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 13:58:36 -0800 Subject: [PATCH 28/61] fix: dev tests --- packages/astro/src/builder.ts | 4 ++-- packages/core/e2e/dev.test.ts | 1 + workbench/astro/src/lib/_workflows.ts | 2 -- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/astro/src/builder.ts b/packages/astro/src/builder.ts index b89dabf0f..7370b8712 100644 --- a/packages/astro/src/builder.ts +++ b/packages/astro/src/builder.ts @@ -33,7 +33,7 @@ export class LocalBuilder extends BaseBuilder { super({ ...config, - dirs: ['src/pages'], + dirs: ['src/pages', 'src/workflows'], buildTarget: 'astro' as const, stepsBundlePath: '', // unused in base workflowsBundlePath: '', // unused in base @@ -212,7 +212,7 @@ export class VercelBuilder extends VercelBuildOutputAPIBuilder { super({ ...createBaseBuilderConfig({ workingDir, - dirs: ['src/pages'], + dirs: ['src/pages', 'src/workflows'], }), buildTarget: 'vercel-build-output-api', }); diff --git a/packages/core/e2e/dev.test.ts b/packages/core/e2e/dev.test.ts index 04052c040..8efe97462 100644 --- a/packages/core/e2e/dev.test.ts +++ b/packages/core/e2e/dev.test.ts @@ -122,6 +122,7 @@ export async function myNewStep() { workflowsDir, 'new-workflow.ts' ); + console.log(workflowFile); await fs.writeFile( workflowFile, diff --git a/workbench/astro/src/lib/_workflows.ts b/workbench/astro/src/lib/_workflows.ts index 809ff2c0c..5c0c66834 100644 --- a/workbench/astro/src/lib/_workflows.ts +++ b/workbench/astro/src/lib/_workflows.ts @@ -1,7 +1,6 @@ // Auto-generated by workbench/scripts/generate-workflows-registry.js // Do not edit this file manually - it will be regenerated on build -import * as workflow_0_demo from '../workflows/0_demo'; import * as workflow_1_simple from '../workflows/1_simple'; import * as workflow_2_control_flow from '../workflows/2_control_flow'; import * as workflow_3_streams from '../workflows/3_streams'; @@ -13,7 +12,6 @@ import * as workflow_98_duplicate_case from '../workflows/98_duplicate_case'; import * as workflow_99_e2e from '../workflows/99_e2e'; export const allWorkflows = { - 'workflows/0_demo.ts': workflow_0_demo, 'workflows/1_simple.ts': workflow_1_simple, 'workflows/2_control_flow.ts': workflow_2_control_flow, 'workflows/3_streams.ts': workflow_3_streams, From 2cbb493cacbcf23c7a7a5d0c4624df8093daab4a Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 14:09:02 -0800 Subject: [PATCH 29/61] add astro to local build --- packages/core/e2e/local-build.test.ts | 33 ++++++++++++++------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/packages/core/e2e/local-build.test.ts b/packages/core/e2e/local-build.test.ts index 4daca2b01..c96aa9a7d 100644 --- a/packages/core/e2e/local-build.test.ts +++ b/packages/core/e2e/local-build.test.ts @@ -1,30 +1,31 @@ -import { exec as execOriginal } from 'child_process'; -import { promisify } from 'util'; -import { describe, expect, test } from 'vitest'; -import { getWorkbenchAppPath } from './utils'; +import { exec as execOriginal } from "child_process"; +import { promisify } from "util"; +import { describe, expect, test } from "vitest"; +import { getWorkbenchAppPath } from "./utils"; const exec = promisify(execOriginal); describe.each([ - 'nextjs-webpack', - 'nextjs-turbopack', - 'nitro', - 'vite', - 'sveltekit', - 'nuxt', - 'hono', - 'express', -])('e2e', (project) => { - test('builds without errors', { timeout: 180_000 }, async () => { + "nextjs-webpack", + "nextjs-turbopack", + "nitro", + "vite", + "sveltekit", + "nuxt", + "hono", + "express", + "astro", +])("e2e", (project) => { + test("builds without errors", { timeout: 180_000 }, async () => { // skip if we're targeting specific app to test if (process.env.APP_NAME && project !== process.env.APP_NAME) { return; } - const result = await exec('pnpm build', { + const result = await exec("pnpm build", { cwd: getWorkbenchAppPath(project), }); - expect(result.stderr).not.toContain('Error:'); + expect(result.stderr).not.toContain("Error:"); }); }); From 1c50a054fce498bc59d58f337975c1788c115639 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 14:36:04 -0800 Subject: [PATCH 30/61] fix: add prefixes to debug files in local builder --- packages/astro/src/builder.ts | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/astro/src/builder.ts b/packages/astro/src/builder.ts index 7370b8712..5151395b2 100644 --- a/packages/astro/src/builder.ts +++ b/packages/astro/src/builder.ts @@ -1,4 +1,4 @@ -import { mkdir, readFile, writeFile } from 'node:fs/promises'; +import { mkdir, readFile, rename, writeFile } from 'node:fs/promises'; import { join, resolve } from 'node:path'; import { BaseBuilder, @@ -21,11 +21,11 @@ async function normalizeRequestConverter(request) { } `; -// const DEBUG_FILES = [ -// "flow.js.debug.json", -// "manifest.debug.json", -// "step.js.debug.json", -// ]; +const DEBUG_FILES = [ + 'flow.js.debug.json', + 'manifest.debug.json', + 'step.js.debug.json', +]; export class LocalBuilder extends BaseBuilder { constructor(config?: Partial) { @@ -71,11 +71,11 @@ export class LocalBuilder extends BaseBuilder { await this.buildWebhookRoute({ workflowGeneratedDir }); // Astro requires non-api routes to be prefixed with _ (debug files) - // for (const file of DEBUG_FILES) { - // const filePath = join(workflowGeneratedDir, file); - // const prefixedFilePath = join(workflowGeneratedDir, `_${file}`); - // await rename(filePath, prefixedFilePath); - // } + for (const file of DEBUG_FILES) { + const filePath = join(workflowGeneratedDir, file); + const prefixedFilePath = join(workflowGeneratedDir, `_${file}`); + await rename(filePath, prefixedFilePath); + } } private async buildStepsRoute({ From 35ea400d1900cf3dd6eea1e0055c318f9d75879d Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 14:43:22 -0800 Subject: [PATCH 31/61] add index to astro workbench for demoing --- workbench/astro/src/pages/index.astro | 146 +++++++++++++++++++++++--- workbench/example/workflows/0_calc.ts | 15 +++ 2 files changed, 149 insertions(+), 12 deletions(-) create mode 100644 workbench/example/workflows/0_calc.ts diff --git a/workbench/astro/src/pages/index.astro b/workbench/astro/src/pages/index.astro index 2d1410736..45a53644c 100644 --- a/workbench/astro/src/pages/index.astro +++ b/workbench/astro/src/pages/index.astro @@ -1,16 +1,138 @@ --- - +// No server-side code needed for this page --- - - - - - - - Astro - - -

Astro

- + + + + + Workflow DevKit + Astro Example + + + + +

Workflow DevKit + Nitro Example

+
+ + + + diff --git a/workbench/example/workflows/0_calc.ts b/workbench/example/workflows/0_calc.ts new file mode 100644 index 000000000..3323945e6 --- /dev/null +++ b/workbench/example/workflows/0_calc.ts @@ -0,0 +1,15 @@ +// import { FatalError } from 'workflow'; + +export async function calc(n: number) { + 'use workflow'; + console.log('Simple workflow started'); + n = await pow(n); + console.log('Simple workflow finished'); + return n; +} + +async function pow(a: number): Promise { + 'use step'; + console.log('Running step pow with arg:', a); + return a * a; +} From ec23071eb6cf20f25386b2f0c53673ed6bff7509 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 14:51:10 -0800 Subject: [PATCH 32/61] add output to astro config --- workbench/astro/astro.config.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/workbench/astro/astro.config.mjs b/workbench/astro/astro.config.mjs index dc02faed2..53e153969 100644 --- a/workbench/astro/astro.config.mjs +++ b/workbench/astro/astro.config.mjs @@ -12,6 +12,7 @@ const adapter = process.env.VERCEL_DEPLOYMENT_ID // https://astro.build/config export default defineConfig({ + output: 'server', integrations: [workflowPlugin()], adapter: adapter, security: { From d4205c72c775847991c854bcffa61bd93bc03bac Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 15:38:06 -0800 Subject: [PATCH 33/61] fix: astro vercel adapter overwriting vercel workflow config --- packages/astro/src/builder.ts | 48 ++++++++++++++++++++++++++++------- packages/astro/src/plugin.ts | 3 +-- 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/packages/astro/src/builder.ts b/packages/astro/src/builder.ts index 5151395b2..e46def997 100644 --- a/packages/astro/src/builder.ts +++ b/packages/astro/src/builder.ts @@ -27,6 +27,21 @@ const DEBUG_FILES = [ 'step.js.debug.json', ]; +const WORKFLOW_ROUTES = [ + { + src: '^/\\.well-known/workflow/v1/flow/?$', + dest: '/.well-known/workflow/v1/flow', + }, + { + src: '^/\\.well-known/workflow/v1/step/?$', + dest: '/.well-known/workflow/v1/step', + }, + { + src: '^/\\.well-known/workflow/v1/webhook/([^/]+?)/?$', + dest: '/.well-known/workflow/v1/webhook/[token]', + }, +]; + export class LocalBuilder extends BaseBuilder { constructor(config?: Partial) { const workingDir = config?.workingDir || process.cwd(); @@ -217,16 +232,31 @@ export class VercelBuilder extends VercelBuildOutputAPIBuilder { buildTarget: 'vercel-build-output-api', }); } + override async build(): Promise { - // const configPath = join( - // this.config.workingDir, - // ".vercel/output/config.json", - // ); - // const originalConfig = JSON.parse(await readFile(configPath, "utf-8")); + const configPath = join( + this.config.workingDir, + '.vercel/output/config.json' + ); + + // The config output by astro + const config = JSON.parse(await readFile(configPath, 'utf-8')); + + // Filter out existing workflow routes (wrong `dest` mapping) + config.routes = config.routes.filter( + (route: { src?: string; dest: string }) => + !route.src?.includes('.well-known/workflow') + ); + + // Add new workflow routes + for (const route of WORKFLOW_ROUTES) { + config.routes.push(route); + } + + // Bundles workflows for vercel but overwrites vercel's astro config await super.build(); - console.log('built vercel build output api'); - // const newConfig = JSON.parse(await readFile(configPath, "utf-8")); - // originalConfig.routes.unshift(...newConfig.routes); - // await writeFile(configPath, JSON.stringify(originalConfig, null, 2)); + + // Use old astro config + await writeFile(configPath, JSON.stringify(config, null, 2)); } } diff --git a/packages/astro/src/plugin.ts b/packages/astro/src/plugin.ts index 18b02d4f3..8366199a0 100644 --- a/packages/astro/src/plugin.ts +++ b/packages/astro/src/plugin.ts @@ -20,8 +20,7 @@ export function workflowPlugin(): AstroIntegration { }); }, 'astro:build:done': async () => { - // Check if we're building for Vercel - if (process.env.VERCEL_DEPLOYMENT_ID) { + if (process.env.VERCEL_DEPLOYMENT_URL) { const vercelBuilder = new VercelBuilder(); await vercelBuilder.build(); } From 3e965bfc41405d32270b5a1e75948135b820930a Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 16:17:45 -0800 Subject: [PATCH 34/61] testing astro bundling --- packages/astro/src/index.ts | 12 ++++++------ packages/astro/src/plugin.ts | 16 ++++++++-------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/astro/src/index.ts b/packages/astro/src/index.ts index 818cb5802..9ed3c4c25 100644 --- a/packages/astro/src/index.ts +++ b/packages/astro/src/index.ts @@ -1,10 +1,10 @@ -// import { LocalBuilder } from "./builder.js"; +import { LocalBuilder } from './builder.js'; -// const builder = new LocalBuilder(); +const builder = new LocalBuilder(); -// // This needs to be in the top-level as we need to create these -// // entries before astro plugin is started or the entries are -// // a race to be created before astro discovers entries -// await builder.build(); +// This needs to be in the top-level as we need to create these +// entries before astro plugin is started or the entries are +// a race to be created before astro discovers entries +await builder.build(); export { workflowPlugin } from './plugin.js'; diff --git a/packages/astro/src/plugin.ts b/packages/astro/src/plugin.ts index 8366199a0..862858383 100644 --- a/packages/astro/src/plugin.ts +++ b/packages/astro/src/plugin.ts @@ -3,7 +3,7 @@ import { transform } from '@swc/core'; import { resolveModulePath } from 'exsolve'; import type { HotUpdateOptions, PluginOption } from 'vite'; import type { AstroIntegration } from 'astro'; -import { LocalBuilder, VercelBuilder } from './builder.js'; +import { LocalBuilder } from './builder.js'; export function workflowPlugin(): AstroIntegration { const builder = new LocalBuilder(); @@ -12,19 +12,19 @@ export function workflowPlugin(): AstroIntegration { name: 'workflow:astro', hooks: { 'astro:config:setup': async ({ updateConfig }) => { - await builder.build(); + // await builder.build(); updateConfig({ vite: { plugins: [createVitePlugin(builder) as any], }, }); }, - 'astro:build:done': async () => { - if (process.env.VERCEL_DEPLOYMENT_URL) { - const vercelBuilder = new VercelBuilder(); - await vercelBuilder.build(); - } - }, + // "astro:build:done": async () => { + // if (process.env.VERCEL_DEPLOYMENT_URL) { + // const vercelBuilder = new VercelBuilder(); + // await vercelBuilder.build(); + // } + // }, }, }; } From 89302a275b943c8f9ef089c4046008985f6494a8 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 16:28:12 -0800 Subject: [PATCH 35/61] update vercel workflow output route ordering --- packages/astro/src/builder.ts | 17 ++++++++++++++--- packages/astro/src/index.ts | 12 ++++++------ packages/astro/src/plugin.ts | 14 +++++++------- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/packages/astro/src/builder.ts b/packages/astro/src/builder.ts index e46def997..b361ea43b 100644 --- a/packages/astro/src/builder.ts +++ b/packages/astro/src/builder.ts @@ -248,11 +248,22 @@ export class VercelBuilder extends VercelBuildOutputAPIBuilder { !route.src?.includes('.well-known/workflow') ); - // Add new workflow routes - for (const route of WORKFLOW_ROUTES) { - config.routes.push(route); + // Find the index right after the "filesystem" handler and "continue: true" routes + let insertIndex = config.routes.findIndex( + (route: any) => route.handle === 'filesystem' + ); + + // Move past any routes with "continue: true" (like _astro cache headers) + while ( + insertIndex < config.routes.length - 1 && + config.routes[insertIndex + 1]?.continue === true + ) { + insertIndex++; } + // Insert workflow routes right after + config.routes.splice(insertIndex + 1, 0, ...WORKFLOW_ROUTES); + // Bundles workflows for vercel but overwrites vercel's astro config await super.build(); diff --git a/packages/astro/src/index.ts b/packages/astro/src/index.ts index 9ed3c4c25..c83db26ed 100644 --- a/packages/astro/src/index.ts +++ b/packages/astro/src/index.ts @@ -1,10 +1,10 @@ -import { LocalBuilder } from './builder.js'; +// import { LocalBuilder } from './builder.js'; -const builder = new LocalBuilder(); +// const builder = new LocalBuilder(); -// This needs to be in the top-level as we need to create these -// entries before astro plugin is started or the entries are -// a race to be created before astro discovers entries -await builder.build(); +// // This needs to be in the top-level as we need to create these +// // entries before astro plugin is started or the entries are +// // a race to be created before astro discovers entries +// await builder.build(); export { workflowPlugin } from './plugin.js'; diff --git a/packages/astro/src/plugin.ts b/packages/astro/src/plugin.ts index 862858383..f1d5ab0b5 100644 --- a/packages/astro/src/plugin.ts +++ b/packages/astro/src/plugin.ts @@ -3,7 +3,7 @@ import { transform } from '@swc/core'; import { resolveModulePath } from 'exsolve'; import type { HotUpdateOptions, PluginOption } from 'vite'; import type { AstroIntegration } from 'astro'; -import { LocalBuilder } from './builder.js'; +import { LocalBuilder, VercelBuilder } from './builder.js'; export function workflowPlugin(): AstroIntegration { const builder = new LocalBuilder(); @@ -19,12 +19,12 @@ export function workflowPlugin(): AstroIntegration { }, }); }, - // "astro:build:done": async () => { - // if (process.env.VERCEL_DEPLOYMENT_URL) { - // const vercelBuilder = new VercelBuilder(); - // await vercelBuilder.build(); - // } - // }, + 'astro:build:done': async () => { + // if (process.env.VERCEL_DEPLOYMENT_URL) { + const vercelBuilder = new VercelBuilder(); + await vercelBuilder.build(); + // } + }, }, }; } From 7745954c79591c2a9893677fa5f4f0f8fc5ff5a5 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 16:52:42 -0800 Subject: [PATCH 36/61] fix: check vercel env var for astro vercel builder --- packages/astro/src/plugin.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/astro/src/plugin.ts b/packages/astro/src/plugin.ts index f1d5ab0b5..cd0769088 100644 --- a/packages/astro/src/plugin.ts +++ b/packages/astro/src/plugin.ts @@ -20,10 +20,10 @@ export function workflowPlugin(): AstroIntegration { }); }, 'astro:build:done': async () => { - // if (process.env.VERCEL_DEPLOYMENT_URL) { - const vercelBuilder = new VercelBuilder(); - await vercelBuilder.build(); - // } + if (process.env.VERCEL_DEPLOYMENT_ID) { + const vercelBuilder = new VercelBuilder(); + await vercelBuilder.build(); + } }, }, }; From 7f50e4464e1930cde0d016331dc0b5f378f587bb Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 16:58:54 -0800 Subject: [PATCH 37/61] fix: not building workflows locally --- packages/astro/src/plugin.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/astro/src/plugin.ts b/packages/astro/src/plugin.ts index cd0769088..de6cf7bae 100644 --- a/packages/astro/src/plugin.ts +++ b/packages/astro/src/plugin.ts @@ -12,7 +12,10 @@ export function workflowPlugin(): AstroIntegration { name: 'workflow:astro', hooks: { 'astro:config:setup': async ({ updateConfig }) => { - // await builder.build(); + // Use local builder + if (!process.env.VERCEL_DEPLOYMENT_ID) { + await builder.build(); + } updateConfig({ vite: { plugins: [createVitePlugin(builder) as any], From fd257c19cc325faa55b2c0662bdb2183b4a3c0e6 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 18:26:06 -0800 Subject: [PATCH 38/61] chore: remove generated _workflow.ts --- workbench/astro/src/lib/_workflows.ts | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 workbench/astro/src/lib/_workflows.ts diff --git a/workbench/astro/src/lib/_workflows.ts b/workbench/astro/src/lib/_workflows.ts deleted file mode 100644 index 5c0c66834..000000000 --- a/workbench/astro/src/lib/_workflows.ts +++ /dev/null @@ -1,24 +0,0 @@ -// Auto-generated by workbench/scripts/generate-workflows-registry.js -// Do not edit this file manually - it will be regenerated on build - -import * as workflow_1_simple from '../workflows/1_simple'; -import * as workflow_2_control_flow from '../workflows/2_control_flow'; -import * as workflow_3_streams from '../workflows/3_streams'; -import * as workflow_4_ai from '../workflows/4_ai'; -import * as workflow_5_hooks from '../workflows/5_hooks'; -import * as workflow_6_batching from '../workflows/6_batching'; -import * as workflow_7_full from '../workflows/7_full'; -import * as workflow_98_duplicate_case from '../workflows/98_duplicate_case'; -import * as workflow_99_e2e from '../workflows/99_e2e'; - -export const allWorkflows = { - 'workflows/1_simple.ts': workflow_1_simple, - 'workflows/2_control_flow.ts': workflow_2_control_flow, - 'workflows/3_streams.ts': workflow_3_streams, - 'workflows/4_ai.ts': workflow_4_ai, - 'workflows/5_hooks.ts': workflow_5_hooks, - 'workflows/6_batching.ts': workflow_6_batching, - 'workflows/7_full.ts': workflow_7_full, - 'workflows/98_duplicate_case.ts': workflow_98_duplicate_case, - 'workflows/99_e2e.ts': workflow_99_e2e, -} as const; From 04c34b60ef0e3df8949758bb6495d8df107f6d05 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 18:48:44 -0800 Subject: [PATCH 39/61] chore: cleanup --- packages/astro/src/builder.ts | 19 +-- packages/astro/src/index.ts | 9 - packages/astro/src/plugin.ts | 298 ++++++++++++++++++---------------- 3 files changed, 166 insertions(+), 160 deletions(-) diff --git a/packages/astro/src/builder.ts b/packages/astro/src/builder.ts index b361ea43b..048197970 100644 --- a/packages/astro/src/builder.ts +++ b/packages/astro/src/builder.ts @@ -43,17 +43,14 @@ const WORKFLOW_ROUTES = [ ]; export class LocalBuilder extends BaseBuilder { - constructor(config?: Partial) { - const workingDir = config?.workingDir || process.cwd(); - + constructor() { super({ - ...config, dirs: ['src/pages', 'src/workflows'], buildTarget: 'astro' as const, stepsBundlePath: '', // unused in base workflowsBundlePath: '', // unused in base webhookBundlePath: '', // unused in base - workingDir, + workingDir: process.cwd(), }); } @@ -115,8 +112,9 @@ export class LocalBuilder extends BaseBuilder { tsPaths, }); - // Post-process the generated file to wrap with SvelteKit request converter let stepsRouteContent = await readFile(stepsRouteFile, 'utf-8'); + + // Normalize request, needed for preserving request through astro stepsRouteContent = stepsRouteContent.replace( /export\s*\{\s*stepEntrypoint\s+as\s+POST\s*\}\s*;?$/m, `${NORMALIZE_REQUEST_CONVERTER} @@ -152,8 +150,9 @@ export const prerender = false;` tsPaths, }); - // Post-process the generated file to wrap with SvelteKit request converter let workflowsRouteContent = await readFile(workflowsRouteFile, 'utf-8'); + + // Normalize request, needed for preserving request through astro workflowsRouteContent = workflowsRouteContent.replace( /export const POST = workflowEntrypoint\(workflowCode\);?$/m, `${NORMALIZE_REQUEST_CONVERTER} @@ -196,7 +195,7 @@ export const prerender = false;` '' ); - // Replace all HTTP method exports with SvelteKit-compatible handlers + // Normalize request, needed for preserving request through astro webhookRouteContent = webhookRouteContent.replace( /export const GET = handler;\nexport const POST = handler;\nexport const PUT = handler;\nexport const PATCH = handler;\nexport const DELETE = handler;\nexport const HEAD = handler;\nexport const OPTIONS = handler;/, `${NORMALIZE_REQUEST_CONVERTER} @@ -264,10 +263,10 @@ export class VercelBuilder extends VercelBuildOutputAPIBuilder { // Insert workflow routes right after config.routes.splice(insertIndex + 1, 0, ...WORKFLOW_ROUTES); - // Bundles workflows for vercel but overwrites vercel's astro config + // Bundles workflows for vercel await super.build(); - // Use old astro config + // Use old astro config with updated routes await writeFile(configPath, JSON.stringify(config, null, 2)); } } diff --git a/packages/astro/src/index.ts b/packages/astro/src/index.ts index c83db26ed..5ea10d3fd 100644 --- a/packages/astro/src/index.ts +++ b/packages/astro/src/index.ts @@ -1,10 +1 @@ -// import { LocalBuilder } from './builder.js'; - -// const builder = new LocalBuilder(); - -// // This needs to be in the top-level as we need to create these -// // entries before astro plugin is started or the entries are -// // a race to be created before astro discovers entries -// await builder.build(); - export { workflowPlugin } from './plugin.js'; diff --git a/packages/astro/src/plugin.ts b/packages/astro/src/plugin.ts index de6cf7bae..79a1186e1 100644 --- a/packages/astro/src/plugin.ts +++ b/packages/astro/src/plugin.ts @@ -11,14 +11,169 @@ export function workflowPlugin(): AstroIntegration { return { name: 'workflow:astro', hooks: { - 'astro:config:setup': async ({ updateConfig }) => { + 'astro:config:setup': async ({ updateConfig }: any) => { // Use local builder if (!process.env.VERCEL_DEPLOYMENT_ID) { await builder.build(); } updateConfig({ vite: { - plugins: [createVitePlugin(builder) as any], + plugins: [ + { + name: 'workflow:astro:vite', + + // TODO: Move this to @workflow/vite or something since this is vite specific + // Transform workflow files with SWC + async transform(code: string, id: string) { + // Only apply the transform if file needs it + if (!code.match(/(use step|use workflow)/)) { + return null; + } + + const isTypeScript = + id.endsWith('.ts') || id.endsWith('.tsx'); + const isTsx = id.endsWith('.tsx'); + + const swcPlugin = resolveModulePath('@workflow/swc-plugin', { + from: [import.meta.url], + }); + + // Calculate relative filename for SWC plugin + // The SWC plugin uses filename to generate workflowId, so it must be relative + const workingDir = process.cwd(); + const normalizedWorkingDir = workingDir + .replace(/\\/g, '/') + .replace(/\/$/, ''); + const normalizedFilepath = id.replace(/\\/g, '/'); + + // Windows fix: Use case-insensitive comparison to work around drive letter casing issues + const lowerWd = normalizedWorkingDir.toLowerCase(); + const lowerPath = normalizedFilepath.toLowerCase(); + + let relativeFilename: string; + if (lowerPath.startsWith(lowerWd + '/')) { + // File is under working directory - manually calculate relative path + relativeFilename = normalizedFilepath.substring( + normalizedWorkingDir.length + 1 + ); + } else if (lowerPath === lowerWd) { + // File IS the working directory (shouldn't happen) + relativeFilename = '.'; + } else { + // Use relative() for files outside working directory + relativeFilename = relative(workingDir, id).replace( + /\\/g, + '/' + ); + + if (relativeFilename.startsWith('../')) { + relativeFilename = relativeFilename + .split('/') + .filter((part) => part !== '..') + .join('/'); + } + } + + // Final safety check - ensure we never pass an absolute path to SWC + if ( + relativeFilename.includes(':') || + relativeFilename.startsWith('/') + ) { + // This should rarely happen, but use filename split as last resort + relativeFilename = + normalizedFilepath.split('/').pop() || 'unknown.ts'; + } + + // Transform with SWC + const result = await transform(code, { + filename: relativeFilename, + jsc: { + parser: { + syntax: isTypeScript ? 'typescript' : 'ecmascript', + tsx: isTsx, + }, + target: 'es2022', + experimental: { + plugins: [[swcPlugin, { mode: 'client' }]], + }, + }, + minify: false, + sourceMaps: true, + inlineSourcesContent: true, + }); + + return { + code: result.code, + map: result.map ? JSON.parse(result.map) : null, + }; + }, + + // TODO: Move this to @workflow/vite or something since this is vite specific + async hotUpdate(options: HotUpdateOptions) { + const { file, server, read } = options; + + // Check if this is a TS/JS file that might contain workflow directives + const jsTsRegex = /\.(ts|tsx|js|jsx|mjs|cjs)$/; + if (!jsTsRegex.test(file)) { + return; + } + + // Read the file to check for workflow/step directives + let content: string; + try { + content = await read(); + } catch { + // File might have been deleted - trigger rebuild to update generated routes + console.log( + 'Workflow file deleted, regenerating routes...' + ); + try { + await builder.build(); + } catch (buildError) { + // Build might fail if files are being deleted during test cleanup + // Log but don't crash - the next successful change will trigger a rebuild + console.error( + 'Build failed during file deletion:', + buildError + ); + } + + server.ws.send({ type: 'full-reload', path: '*' }); + return []; + } + + const useWorkflowPattern = /^\s*(['"])use workflow\1;?\s*$/m; + const useStepPattern = /^\s*(['"])use step\1;?\s*$/m; + + if ( + !useWorkflowPattern.test(content) && + !useStepPattern.test(content) + ) { + return; + } + + // Rebuild everything - simpler and more reliable than tracking individual files + console.log('Workflow file changed, regenerating routes...'); + try { + await builder.build(); + } catch (buildError) { + // Build might fail if files are being modified/deleted during test cleanup + // Log but don't crash - the next successful change will trigger a rebuild + console.error('Build failed during HMR:', buildError); + return []; + } + + // Trigger full reload of workflow routes + server.ws.send({ + type: 'full-reload', + path: '*', + }); + + // Prevent Vite from processing this HMR update + return []; + }, + } as PluginOption, + ], }, }); }, @@ -31,142 +186,3 @@ export function workflowPlugin(): AstroIntegration { }, }; } - -function createVitePlugin(builder: LocalBuilder): PluginOption { - return { - name: 'workflow:astro:vite', - - // TODO: Move this to @workflow/vite or something since this is vite specific - // Transform workflow files with SWC - async transform(code: string, id: string) { - // Only apply the transform if file needs it - if (!code.match(/(use step|use workflow)/)) { - return null; - } - - const isTypeScript = id.endsWith('.ts') || id.endsWith('.tsx'); - const isTsx = id.endsWith('.tsx'); - - const swcPlugin = resolveModulePath('@workflow/swc-plugin', { - from: [import.meta.url], - }); - - // Calculate relative filename for SWC plugin - // The SWC plugin uses filename to generate workflowId, so it must be relative - const workingDir = process.cwd(); - const normalizedWorkingDir = workingDir - .replace(/\\/g, '/') - .replace(/\/$/, ''); - const normalizedFilepath = id.replace(/\\/g, '/'); - - // Windows fix: Use case-insensitive comparison to work around drive letter casing issues - const lowerWd = normalizedWorkingDir.toLowerCase(); - const lowerPath = normalizedFilepath.toLowerCase(); - - let relativeFilename: string; - if (lowerPath.startsWith(lowerWd + '/')) { - // File is under working directory - manually calculate relative path - relativeFilename = normalizedFilepath.substring( - normalizedWorkingDir.length + 1 - ); - } else if (lowerPath === lowerWd) { - // File IS the working directory (shouldn't happen) - relativeFilename = '.'; - } else { - // Use relative() for files outside working directory - relativeFilename = relative(workingDir, id).replace(/\\/g, '/'); - - if (relativeFilename.startsWith('../')) { - relativeFilename = relativeFilename - .split('/') - .filter((part) => part !== '..') - .join('/'); - } - } - - // Final safety check - ensure we never pass an absolute path to SWC - if (relativeFilename.includes(':') || relativeFilename.startsWith('/')) { - // This should rarely happen, but use filename split as last resort - relativeFilename = normalizedFilepath.split('/').pop() || 'unknown.ts'; - } - - // Transform with SWC - const result = await transform(code, { - filename: relativeFilename, - jsc: { - parser: { - syntax: isTypeScript ? 'typescript' : 'ecmascript', - tsx: isTsx, - }, - target: 'es2022', - experimental: { - plugins: [[swcPlugin, { mode: 'client' }]], - }, - }, - minify: false, - sourceMaps: true, - inlineSourcesContent: true, - }); - - return { - code: result.code, - map: result.map ? JSON.parse(result.map) : null, - }; - }, - - // TODO: Move this to @workflow/vite or something since this is vite specific - async hotUpdate(options: HotUpdateOptions) { - const { file, server, read } = options; - - // Check if this is a TS/JS file that might contain workflow directives - const jsTsRegex = /\.(ts|tsx|js|jsx|mjs|cjs)$/; - if (!jsTsRegex.test(file)) { - return; - } - - // Read the file to check for workflow/step directives - let content: string; - try { - content = await read(); - } catch { - // File might have been deleted - trigger rebuild to update generated routes - console.log('Workflow file deleted, regenerating routes...'); - try { - await builder.build(); - } catch (buildError) { - // Build might fail if files are being deleted during test cleanup - // Log but don't crash - the next successful change will trigger a rebuild - console.error('Build failed during file deletion:', buildError); - } - return; - } - - const useWorkflowPattern = /^\s*(['"])use workflow\1;?\s*$/m; - const useStepPattern = /^\s*(['"])use step\1;?\s*$/m; - - if (!useWorkflowPattern.test(content) && !useStepPattern.test(content)) { - return; - } - - // Rebuild everything - simpler and more reliable than tracking individual files - console.log('Workflow file changed, regenerating routes...'); - try { - await builder.build(); - } catch (buildError) { - // Build might fail if files are being modified/deleted during test cleanup - // Log but don't crash - the next successful change will trigger a rebuild - console.error('Build failed during HMR:', buildError); - return; - } - - // Trigger full reload of workflow routes - server.ws.send({ - type: 'full-reload', - path: '*', - }); - - // Let Vite handle the normal HMR for the changed file - return; - }, - }; -} From 25488423051b1423ab66a6093e1fc035fcc8f0b7 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 19:02:16 -0800 Subject: [PATCH 40/61] chore(deps): lock deps --- packages/astro/package.json | 7 ++---- pnpm-lock.yaml | 49 +++++++++++++++++++++++++++++++------ 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/packages/astro/package.json b/packages/astro/package.json index ebab8a172..78d1df348 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -29,17 +29,14 @@ "@workflow/builders": "workspace:*", "@workflow/swc-plugin": "workspace:*", "exsolve": "^1.0.7", - "fs-extra": "^11.3.2", + "fs-extra": "11.3.2", "pathe": "^2.0.3" }, "devDependencies": { "@types/fs-extra": "11.0.4", "@types/node": "catalog:", "@workflow/tsconfig": "workspace:*", - "astro": "^5.15.6", + "astro": "5.15.6", "vite": "7.1.11" - }, - "peerDependencies": { - "astro": "^5.0.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 10a0b51fc..52c189b2b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -330,7 +330,7 @@ importers: specifier: ^1.0.7 version: 1.0.7 fs-extra: - specifier: ^11.3.2 + specifier: 11.3.2 version: 11.3.2 pathe: specifier: ^2.0.3 @@ -346,8 +346,8 @@ importers: specifier: workspace:* version: link:../tsconfig astro: - specifier: ^5.15.6 - version: 5.16.0(@netlify/blobs@9.1.2)(@types/node@22.19.0)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1) + specifier: 5.15.6 + version: 5.15.6(@netlify/blobs@9.1.2)(@types/node@22.19.0)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1) vite: specifier: 7.1.11 version: 7.1.11(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) @@ -1639,6 +1639,9 @@ packages: '@astrojs/internal-helpers@0.7.5': resolution: {integrity: sha512-vreGnYSSKhAjFJCWAwe/CNhONvoc5lokxtRoZims+0wa3KbHBdPHSSthJsKxPd8d/aic6lWKpRTYGY/hsgK6EA==} + '@astrojs/markdown-remark@6.3.8': + resolution: {integrity: sha512-uFNyFWadnULWK2cOw4n0hLKeu+xaVWeuECdP10cQ3K2fkybtTlhb7J7TcScdjmS8Yps7oje9S/ehYMfZrhrgCg==} + '@astrojs/markdown-remark@6.3.9': resolution: {integrity: sha512-hX2cLC/KW74Io1zIbn92kI482j9J7LleBLGCVU9EP3BeH5MVrnFawOnqD0t/q6D1Z+ZNeQG2gNKMslCcO36wng==} @@ -6882,6 +6885,11 @@ packages: resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} hasBin: true + astro@5.15.6: + resolution: {integrity: sha512-luLcw+FGkeUHYTfbmYjIWHB4T0D+3VSjCy8DKTXglJ2O3lU40AbwmPVBcnqhRnA1SneKzP5V5pzqjsHzUZ1+Rg==} + engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'} + hasBin: true + astro@5.16.0: resolution: {integrity: sha512-GaDRs2Mngpw3dr2vc085GnORh98NiXxwIjg/EoQQQl/icZt3Z7s0BRsYHDZ8swkZbOA6wZsqWJdrNirl+iKcDg==} engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'} @@ -13102,6 +13110,32 @@ snapshots: '@astrojs/internal-helpers@0.7.5': {} + '@astrojs/markdown-remark@6.3.8': + dependencies: + '@astrojs/internal-helpers': 0.7.4 + '@astrojs/prism': 3.3.0 + github-slugger: 2.0.0 + hast-util-from-html: 2.0.3 + hast-util-to-text: 4.0.2 + import-meta-resolve: 4.2.0 + js-yaml: 4.1.1 + mdast-util-definitions: 6.0.0 + rehype-raw: 7.0.0 + rehype-stringify: 10.0.1 + remark-gfm: 4.0.1 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + remark-smartypants: 3.0.2 + shiki: 3.13.0 + smol-toml: 1.5.2 + unified: 11.0.5 + unist-util-remove-position: 5.0.0 + unist-util-visit: 5.0.0 + unist-util-visit-parents: 6.0.2 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + '@astrojs/markdown-remark@6.3.9': dependencies: '@astrojs/internal-helpers': 0.7.5 @@ -19123,11 +19157,11 @@ snapshots: astring@1.9.0: {} - astro@5.16.0(@netlify/blobs@9.1.2)(@types/node@22.19.0)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1): + astro@5.15.6(@netlify/blobs@9.1.2)(@types/node@22.19.0)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1): dependencies: '@astrojs/compiler': 2.13.0 - '@astrojs/internal-helpers': 0.7.5 - '@astrojs/markdown-remark': 6.3.9 + '@astrojs/internal-helpers': 0.7.4 + '@astrojs/markdown-remark': 6.3.8 '@astrojs/telemetry': 3.3.0 '@capsizecss/unpack': 3.0.1 '@oslojs/encoding': 1.1.0 @@ -19164,14 +19198,13 @@ snapshots: p-limit: 6.2.0 p-queue: 8.1.1 package-manager-detector: 1.5.0 - piccolore: 0.1.3 + picocolors: 1.1.1 picomatch: 4.0.3 prompts: 2.4.2 rehype: 13.0.2 semver: 7.7.3 shiki: 3.15.0 smol-toml: 1.5.2 - svgo: 4.0.0 tinyexec: 1.0.2 tinyglobby: 0.2.15 tsconfck: 3.1.6(typescript@5.9.3) From 86a2c0fe4f0508af615640da85b7383caeada247 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 19:07:37 -0800 Subject: [PATCH 41/61] changeset stuff --- .changeset/config.json | 3 ++- .changeset/pre.json | 1 + workbench/astro/package.json | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.changeset/config.json b/.changeset/config.json index cc6eee0cf..3fbd70973 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -18,6 +18,7 @@ "@workflow/example-nitro-v2", "@workflow/example-nuxt", "@workflow/example-vite", - "@workflow/example-sveltekit" + "@workflow/example-sveltekit", + "@workflow/example-astro" ] } diff --git a/.changeset/pre.json b/.changeset/pre.json index bbad97e60..e0a2ade2e 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -31,6 +31,7 @@ "@workflow/example-nuxt": "0.0.0", "@workflow/example-vite": "0.0.0", "@workflow/example-sveltekit": "0.0.0", + "@workflow/example-astro": "0.0.0", "@workflow/builders": "4.0.1-beta.3", "@workflow/sveltekit": "4.0.0-beta.1", "@workflow/nuxt": "4.0.1-beta.6" diff --git a/workbench/astro/package.json b/workbench/astro/package.json index 83e9cadfb..68c53855c 100644 --- a/workbench/astro/package.json +++ b/workbench/astro/package.json @@ -1,7 +1,7 @@ { - "name": "astro", + "name": "@workflow/example-astro", "type": "module", - "version": "0.0.1", + "version": "0.0.0", "scripts": { "generate:workflows": "node ../scripts/generate-workflows-registry.js ./src/workflows src/lib/_workflows.ts", "predev": "pnpm generate:workflows", From b19cb54b965f970def6aa29479eadf21044e5384 Mon Sep 17 00:00:00 2001 From: Adrian Date: Fri, 14 Nov 2025 19:07:25 -0800 Subject: [PATCH 42/61] Apply suggestion from @vercel[bot] Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com> --- packages/world-local/src/queue.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/world-local/src/queue.ts b/packages/world-local/src/queue.ts index b186c1327..d103baa02 100644 --- a/packages/world-local/src/queue.ts +++ b/packages/world-local/src/queue.ts @@ -127,8 +127,6 @@ export function createQueue(config: Partial): Queue { const headers = HeaderParser.safeParse(Object.fromEntries(req.headers)); if (!headers.success || !req.body) { - console.log(!headers.success); - console.log(!req.body); return Response.json( { error: !req.body From 012a504d0ae15bbb75ff6a9054eba1d1f4a2feea Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 14 Nov 2025 19:09:07 -0800 Subject: [PATCH 43/61] changeset --- .changeset/grumpy-ties-sort.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changeset/grumpy-ties-sort.md diff --git a/.changeset/grumpy-ties-sort.md b/.changeset/grumpy-ties-sort.md new file mode 100644 index 000000000..97cc879fc --- /dev/null +++ b/.changeset/grumpy-ties-sort.md @@ -0,0 +1,7 @@ +--- +"@workflow/builders": patch +"workflow": patch +"@workflow/astro": patch +--- + +Add @workflow/astro package From bee50464d0f4c716d2c6058af13c556fbc7a53ae Mon Sep 17 00:00:00 2001 From: Adrian Date: Thu, 20 Nov 2025 20:56:24 -0800 Subject: [PATCH 44/61] Apply suggestions from code review Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com> --- packages/astro/src/builder.ts | 2 +- packages/core/e2e/dev.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/astro/src/builder.ts b/packages/astro/src/builder.ts index 048197970..9957913a0 100644 --- a/packages/astro/src/builder.ts +++ b/packages/astro/src/builder.ts @@ -180,7 +180,7 @@ export const prerender = false;` suppressUndefinedRejections: true, }); - // // Post-process the gen // Post-process the generated file to wrap with SvelteKit request converter + // Post-process the generated file to wrap with Astro request converter let webhookRouteContent = await readFile(webhookRouteFile, 'utf-8'); // Update handler signature to accept token as parameter diff --git a/packages/core/e2e/dev.test.ts b/packages/core/e2e/dev.test.ts index 8efe97462..fef47453c 100644 --- a/packages/core/e2e/dev.test.ts +++ b/packages/core/e2e/dev.test.ts @@ -122,7 +122,7 @@ export async function myNewStep() { workflowsDir, 'new-workflow.ts' ); - console.log(workflowFile); + await fs.writeFile( workflowFile, From 515802f70d896aa0bc8013a7ab94c62cd4df0a2f Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Thu, 20 Nov 2025 20:59:30 -0800 Subject: [PATCH 45/61] format --- packages/astro/src/builder.ts | 1 - packages/core/e2e/dev.test.ts | 1 - packages/core/e2e/local-build.test.ts | 34 +++++++++++++-------------- 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/packages/astro/src/builder.ts b/packages/astro/src/builder.ts index 9957913a0..76769f039 100644 --- a/packages/astro/src/builder.ts +++ b/packages/astro/src/builder.ts @@ -177,7 +177,6 @@ export const prerender = false;` await this.createWebhookBundle({ outfile: webhookRouteFile, bundle: false, - suppressUndefinedRejections: true, }); // Post-process the generated file to wrap with Astro request converter diff --git a/packages/core/e2e/dev.test.ts b/packages/core/e2e/dev.test.ts index fef47453c..04052c040 100644 --- a/packages/core/e2e/dev.test.ts +++ b/packages/core/e2e/dev.test.ts @@ -123,7 +123,6 @@ export async function myNewStep() { 'new-workflow.ts' ); - await fs.writeFile( workflowFile, `export async function newWorkflowFile() { diff --git a/packages/core/e2e/local-build.test.ts b/packages/core/e2e/local-build.test.ts index c96aa9a7d..b65b64e96 100644 --- a/packages/core/e2e/local-build.test.ts +++ b/packages/core/e2e/local-build.test.ts @@ -1,31 +1,31 @@ -import { exec as execOriginal } from "child_process"; -import { promisify } from "util"; -import { describe, expect, test } from "vitest"; -import { getWorkbenchAppPath } from "./utils"; +import { exec as execOriginal } from 'child_process'; +import { promisify } from 'util'; +import { describe, expect, test } from 'vitest'; +import { getWorkbenchAppPath } from './utils'; const exec = promisify(execOriginal); describe.each([ - "nextjs-webpack", - "nextjs-turbopack", - "nitro", - "vite", - "sveltekit", - "nuxt", - "hono", - "express", - "astro", -])("e2e", (project) => { - test("builds without errors", { timeout: 180_000 }, async () => { + 'nextjs-webpack', + 'nextjs-turbopack', + 'nitro', + 'vite', + 'sveltekit', + 'nuxt', + 'hono', + 'express', + 'astro', +])('e2e', (project) => { + test('builds without errors', { timeout: 180_000 }, async () => { // skip if we're targeting specific app to test if (process.env.APP_NAME && project !== process.env.APP_NAME) { return; } - const result = await exec("pnpm build", { + const result = await exec('pnpm build', { cwd: getWorkbenchAppPath(project), }); - expect(result.stderr).not.toContain("Error:"); + expect(result.stderr).not.toContain('Error:'); }); }); From 5594f7039857e3614fddc04f9dfeb0df2bb4f9da Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 21 Nov 2025 09:41:51 -0800 Subject: [PATCH 46/61] refactor: cleanup astro plugin name and add comment on csrf protectiopn --- packages/astro/src/index.ts | 2 +- packages/astro/src/plugin.ts | 2 +- workbench/astro/astro.config.mjs | 8 ++++++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/astro/src/index.ts b/packages/astro/src/index.ts index 5ea10d3fd..0aee8949f 100644 --- a/packages/astro/src/index.ts +++ b/packages/astro/src/index.ts @@ -1 +1 @@ -export { workflowPlugin } from './plugin.js'; +export { workflow } from './plugin.js'; diff --git a/packages/astro/src/plugin.ts b/packages/astro/src/plugin.ts index 79a1186e1..8fdce1186 100644 --- a/packages/astro/src/plugin.ts +++ b/packages/astro/src/plugin.ts @@ -5,7 +5,7 @@ import type { HotUpdateOptions, PluginOption } from 'vite'; import type { AstroIntegration } from 'astro'; import { LocalBuilder, VercelBuilder } from './builder.js'; -export function workflowPlugin(): AstroIntegration { +export function workflow(): AstroIntegration { const builder = new LocalBuilder(); return { diff --git a/workbench/astro/astro.config.mjs b/workbench/astro/astro.config.mjs index 53e153969..5087a1f12 100644 --- a/workbench/astro/astro.config.mjs +++ b/workbench/astro/astro.config.mjs @@ -1,5 +1,5 @@ import { defineConfig } from 'astro/config'; -import { workflowPlugin } from 'workflow/astro'; +import { workflow } from 'workflow/astro'; import node from '@astrojs/node'; import vercel from '@astrojs/vercel'; @@ -13,8 +13,12 @@ const adapter = process.env.VERCEL_DEPLOYMENT_ID // https://astro.build/config export default defineConfig({ output: 'server', - integrations: [workflowPlugin()], + integrations: [workflow()], adapter: adapter, + // WARNING: CSRF protection is disabled for testing/development purposes. + // This configuration trusts all origins and should NOT be used in production. + // In production, specify only trusted origins or remove this configuration + // to use Astro's default CSRF protection. security: { checkOrigin: false, }, From a97a9baf812a8e432fa66928e0da79203b66f8fc Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 21 Nov 2025 09:50:07 -0800 Subject: [PATCH 47/61] chore(deps): cleanup astro deps --- packages/astro/package.json | 4 +- pnpm-lock.yaml | 1513 ++++++++++++++++++++++------------- 2 files changed, 950 insertions(+), 567 deletions(-) diff --git a/packages/astro/package.json b/packages/astro/package.json index 78d1df348..657e4596f 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -29,14 +29,12 @@ "@workflow/builders": "workspace:*", "@workflow/swc-plugin": "workspace:*", "exsolve": "^1.0.7", - "fs-extra": "11.3.2", "pathe": "^2.0.3" }, "devDependencies": { - "@types/fs-extra": "11.0.4", "@types/node": "catalog:", "@workflow/tsconfig": "workspace:*", - "astro": "5.15.6", + "astro": "5.16.0", "vite": "7.1.11" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 52c189b2b..ec8a0d22c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,42 +6,9 @@ settings: catalogs: default: - '@biomejs/biome': - specifier: ^2.2.7 - version: 2.3.3 '@types/node': specifier: 22.19.0 version: 22.19.0 - '@vercel/functions': - specifier: ^3.1.4 - version: 3.1.4 - '@vercel/oidc': - specifier: 3.0.5 - version: 3.0.5 - '@vercel/queue': - specifier: 0.0.0-alpha.29 - version: 0.0.0-alpha.29 - '@vitest/coverage-v8': - specifier: ^3.2.4 - version: 3.2.4 - ai: - specifier: 5.0.76 - version: 5.0.76 - esbuild: - specifier: ^0.25.11 - version: 0.25.11 - nitro: - specifier: 3.0.1-alpha.1 - version: 3.0.1-alpha.1 - typescript: - specifier: ^5.9.3 - version: 5.9.3 - vitest: - specifier: ^3.2.4 - version: 3.2.4 - zod: - specifier: 4.1.11 - version: 4.1.11 overrides: rfc6902: 5.1.2 @@ -119,13 +86,13 @@ importers: version: 19.1.9(@types/react@19.1.13) '@vercel/analytics': specifier: ^1.5.0 - version: 1.5.0(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(svelte@5.43.3)(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) + version: 1.5.0(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(svelte@5.43.3)(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) '@vercel/edge-config': specifier: ^1.4.0 version: 1.4.0(@opentelemetry/api@1.9.0) '@vercel/speed-insights': specifier: 1.2.0 - version: 1.2.0(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(svelte@5.43.3)(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) + version: 1.2.0(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(svelte@5.43.3)(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) '@workflow/ai': specifier: workspace:* version: link:../packages/ai @@ -188,7 +155,7 @@ importers: version: 16.0.15(@types/react@19.1.13)(lucide-react@0.544.0(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) fumadocs-mdx: specifier: 13.0.8 - version: 13.0.8(fumadocs-core@16.0.15(@types/react@19.1.13)(lucide-react@0.544.0(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 13.0.8(fumadocs-core@16.0.15(@types/react@19.1.13)(lucide-react@0.544.0(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) fumadocs-typescript: specifier: ^4.0.13 version: 4.0.13(@types/react@19.1.13)(fumadocs-core@16.0.15(@types/react@19.1.13)(lucide-react@0.544.0(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(fumadocs-ui@16.0.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(lucide-react@0.544.0(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(tailwindcss@4.1.13))(typescript@5.9.3) @@ -319,7 +286,7 @@ importers: dependencies: '@swc/core': specifier: 1.11.24 - version: 1.11.24 + version: 1.11.24(@swc/helpers@0.5.17) '@workflow/builders': specifier: workspace:* version: link:../builders @@ -329,16 +296,10 @@ importers: exsolve: specifier: ^1.0.7 version: 1.0.7 - fs-extra: - specifier: 11.3.2 - version: 11.3.2 pathe: specifier: ^2.0.3 version: 2.0.3 devDependencies: - '@types/fs-extra': - specifier: 11.0.4 - version: 11.0.4 '@types/node': specifier: 'catalog:' version: 22.19.0 @@ -346,8 +307,8 @@ importers: specifier: workspace:* version: link:../tsconfig astro: - specifier: 5.15.6 - version: 5.15.6(@netlify/blobs@9.1.2)(@types/node@22.19.0)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1) + specifier: 5.16.0 + version: 5.16.0(@netlify/blobs@9.1.2)(@types/node@22.19.0)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1) vite: specifier: 7.1.11 version: 7.1.11(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) @@ -356,7 +317,7 @@ importers: dependencies: '@swc/core': specifier: 1.11.24 - version: 1.11.24 + version: 1.11.24(@swc/helpers@0.5.17) '@workflow/core': specifier: workspace:* version: link:../core @@ -405,7 +366,7 @@ importers: version: 6.2.31(typescript@5.9.3) '@swc/core': specifier: 1.11.24 - version: 1.11.24 + version: 1.11.24(@swc/helpers@0.5.17) '@workflow/builders': specifier: workspace:* version: link:../builders @@ -588,7 +549,7 @@ importers: dependencies: '@swc/core': specifier: 1.11.24 - version: 1.11.24 + version: 1.11.24(@swc/helpers@0.5.17) '@workflow/builders': specifier: workspace:* version: link:../builders @@ -625,7 +586,7 @@ importers: dependencies: '@swc/core': specifier: 1.11.24 - version: 1.11.24 + version: 1.11.24(@swc/helpers@0.5.17) '@workflow/builders': specifier: workspace:* version: link:../builders @@ -666,7 +627,7 @@ importers: devDependencies: '@nuxt/module-builder': specifier: 1.0.2 - version: 1.0.2(@nuxt/cli@3.29.3(magicast@0.3.5))(@vue/compiler-core@3.5.22)(esbuild@0.25.12)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3)) + version: 1.0.2(@nuxt/cli@3.29.3(magicast@0.3.5))(@vue/compiler-core@3.5.22)(esbuild@0.25.11)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3)) '@nuxt/schema': specifier: 4.2.0 version: 4.2.0 @@ -678,13 +639,13 @@ importers: version: link:../tsconfig nuxt: specifier: 4.0.0 - version: 4.0.0(@biomejs/biome@2.3.3)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@22.19.0)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(@vue/compiler-sfc@3.5.22)(better-sqlite3@11.10.0)(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(yaml@2.8.1) + version: 4.0.0(@biomejs/biome@2.3.3)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@22.19.0)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(@vue/compiler-sfc@3.5.22)(better-sqlite3@11.10.0)(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(yaml@2.8.1) packages/sveltekit: dependencies: '@swc/core': specifier: 1.11.24 - version: 1.11.24 + version: 1.11.24(@swc/helpers@0.5.17) '@workflow/builders': specifier: workspace:* version: link:../builders @@ -718,7 +679,7 @@ importers: dependencies: '@swc/core': specifier: 1.11.24 - version: 1.11.24 + version: 1.11.24(@swc/helpers@0.5.17) packages/tsconfig: {} @@ -1136,7 +1097,7 @@ importers: version: 9.5.0(astro@5.16.0(@netlify/blobs@9.1.2)(@types/node@24.6.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1)) '@astrojs/vercel': specifier: ^9.0.0 - version: 9.0.1(@aws-sdk/credential-provider-web-identity@3.844.0)(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(astro@5.16.0(@netlify/blobs@9.1.2)(@types/node@24.6.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1))(next@16.0.3(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(rollup@4.53.3)(svelte@5.43.3)(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) + version: 9.0.1(@aws-sdk/credential-provider-web-identity@3.844.0)(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(astro@5.16.0(@netlify/blobs@9.1.2)(@types/node@24.6.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1))(next@16.0.3(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(rollup@4.53.3)(svelte@5.43.3)(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) ai: specifier: 'catalog:' version: 5.0.76(zod@4.1.11) @@ -1203,7 +1164,7 @@ importers: version: 5.1.0 nitro: specifier: 'catalog:' - version: 3.0.1-alpha.1(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(ioredis@5.8.2)(lru-cache@11.2.2)(rollup@4.53.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 3.0.1-alpha.1(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(ioredis@5.8.2)(lru-cache@11.2.2)(rollup@4.53.3)(vite@7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) srvx: specifier: ^0.9.2 version: 0.9.4 @@ -1240,7 +1201,7 @@ importers: version: 4.2.0 nitro: specifier: 'catalog:' - version: 3.0.1-alpha.1(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(ioredis@5.8.2)(lru-cache@11.2.2)(rollup@4.53.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 3.0.1-alpha.1(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(ioredis@5.8.2)(lru-cache@11.2.2)(rollup@4.53.3)(vite@7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) openai: specifier: ^6.6.0 version: 6.6.0(ws@8.18.3)(zod@4.1.11) @@ -1393,7 +1354,7 @@ importers: version: 4.2.0 nitro: specifier: 'catalog:' - version: 3.0.1-alpha.1(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(ioredis@5.8.2)(lru-cache@11.2.2)(rollup@4.53.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 3.0.1-alpha.1(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(ioredis@5.8.2)(lru-cache@11.2.2)(rollup@4.53.3)(vite@7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) openai: specifier: ^6.1.0 version: 6.6.0(ws@8.18.3)(zod@4.1.11) @@ -1448,7 +1409,7 @@ importers: version: 4.2.0 nitro: specifier: 'catalog:' - version: 3.0.1-alpha.1(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(ioredis@5.8.2)(lru-cache@11.2.2)(rollup@4.53.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 3.0.1-alpha.1(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(ioredis@5.8.2)(lru-cache@11.2.2)(rollup@4.53.3)(vite@7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) openai: specifier: ^6.1.0 version: 6.6.0(ws@8.18.3)(zod@4.1.11) @@ -1482,7 +1443,7 @@ importers: version: 4.2.0 nuxt: specifier: ^4.1.3 - version: 4.1.3(@biomejs/biome@2.3.3)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@22.19.0)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(@vue/compiler-sfc@3.5.22)(better-sqlite3@11.10.0)(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(yaml@2.8.1) + version: 4.1.3(@biomejs/biome@2.3.3)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@22.19.0)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(@vue/compiler-sfc@3.5.22)(better-sqlite3@11.10.0)(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(yaml@2.8.1) openai: specifier: ^6.6.0 version: 6.6.0(ws@8.18.3)(zod@4.1.11) @@ -1512,7 +1473,7 @@ importers: version: 6.1.1(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(rollup@4.53.3) '@swc/core': specifier: 1.11.24 - version: 1.11.24 + version: 1.11.24(@swc/helpers@0.5.17) '@vercel/otel': specifier: ^1.13.0 version: 1.13.0(@opentelemetry/api-logs@0.57.2)(@opentelemetry/api@1.9.0)(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/resources@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-logs@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-metrics@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0)) @@ -1639,9 +1600,6 @@ packages: '@astrojs/internal-helpers@0.7.5': resolution: {integrity: sha512-vreGnYSSKhAjFJCWAwe/CNhONvoc5lokxtRoZims+0wa3KbHBdPHSSthJsKxPd8d/aic6lWKpRTYGY/hsgK6EA==} - '@astrojs/markdown-remark@6.3.8': - resolution: {integrity: sha512-uFNyFWadnULWK2cOw4n0hLKeu+xaVWeuECdP10cQ3K2fkybtTlhb7J7TcScdjmS8Yps7oje9S/ehYMfZrhrgCg==} - '@astrojs/markdown-remark@6.3.9': resolution: {integrity: sha512-hX2cLC/KW74Io1zIbn92kI482j9J7LleBLGCVU9EP3BeH5MVrnFawOnqD0t/q6D1Z+ZNeQG2gNKMslCcO36wng==} @@ -2075,6 +2033,9 @@ packages: '@emnapi/runtime@1.5.0': resolution: {integrity: sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==} + '@emnapi/runtime@1.7.1': + resolution: {integrity: sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==} + '@emnapi/wasi-threads@1.1.0': resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} @@ -2697,14 +2658,18 @@ packages: resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/config-helpers@0.4.1': - resolution: {integrity: sha512-csZAzkNhsgwb0I/UAV6/RGFTbiakPCf0ZrGmrIxQpYvGZ00PhTkSnyKNolphgIvmnJeGw6rcGVEXfTzUnFuEvw==} + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/core@0.16.0': resolution: {integrity: sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/eslintrc@3.3.1': resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2717,8 +2682,8 @@ packages: resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/plugin-kit@0.4.0': - resolution: {integrity: sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==} + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@fastify/busboy@3.2.0': @@ -2804,122 +2769,255 @@ packages: cpu: [arm64] os: [darwin] + '@img/sharp-darwin-arm64@0.34.5': + resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + '@img/sharp-darwin-x64@0.34.4': resolution: {integrity: sha512-rZheupWIoa3+SOdF/IcUe1ah4ZDpKBGWcsPX6MT0lYniH9micvIU7HQkYTfrx5Xi8u+YqwLtxC/3vl8TQN6rMg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [darwin] + '@img/sharp-darwin-x64@0.34.5': + resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + '@img/sharp-libvips-darwin-arm64@1.2.3': resolution: {integrity: sha512-QzWAKo7kpHxbuHqUC28DZ9pIKpSi2ts2OJnoIGI26+HMgq92ZZ4vk8iJd4XsxN+tYfNJxzH6W62X5eTcsBymHw==} cpu: [arm64] os: [darwin] + '@img/sharp-libvips-darwin-arm64@1.2.4': + resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} + cpu: [arm64] + os: [darwin] + '@img/sharp-libvips-darwin-x64@1.2.3': resolution: {integrity: sha512-Ju+g2xn1E2AKO6YBhxjj+ACcsPQRHT0bhpglxcEf+3uyPY+/gL8veniKoo96335ZaPo03bdDXMv0t+BBFAbmRA==} cpu: [x64] os: [darwin] + '@img/sharp-libvips-darwin-x64@1.2.4': + resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==} + cpu: [x64] + os: [darwin] + '@img/sharp-libvips-linux-arm64@1.2.3': resolution: {integrity: sha512-I4RxkXU90cpufazhGPyVujYwfIm9Nk1QDEmiIsaPwdnm013F7RIceaCc87kAH+oUB1ezqEvC6ga4m7MSlqsJvQ==} cpu: [arm64] os: [linux] + '@img/sharp-libvips-linux-arm64@1.2.4': + resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} + cpu: [arm64] + os: [linux] + '@img/sharp-libvips-linux-arm@1.2.3': resolution: {integrity: sha512-x1uE93lyP6wEwGvgAIV0gP6zmaL/a0tGzJs/BIDDG0zeBhMnuUPm7ptxGhUbcGs4okDJrk4nxgrmxpib9g6HpA==} cpu: [arm] os: [linux] + '@img/sharp-libvips-linux-arm@1.2.4': + resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} + cpu: [arm] + os: [linux] + '@img/sharp-libvips-linux-ppc64@1.2.3': resolution: {integrity: sha512-Y2T7IsQvJLMCBM+pmPbM3bKT/yYJvVtLJGfCs4Sp95SjvnFIjynbjzsa7dY1fRJX45FTSfDksbTp6AGWudiyCg==} cpu: [ppc64] os: [linux] + '@img/sharp-libvips-linux-ppc64@1.2.4': + resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} + cpu: [ppc64] + os: [linux] + + '@img/sharp-libvips-linux-riscv64@1.2.4': + resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} + cpu: [riscv64] + os: [linux] + '@img/sharp-libvips-linux-s390x@1.2.3': resolution: {integrity: sha512-RgWrs/gVU7f+K7P+KeHFaBAJlNkD1nIZuVXdQv6S+fNA6syCcoboNjsV2Pou7zNlVdNQoQUpQTk8SWDHUA3y/w==} cpu: [s390x] os: [linux] + '@img/sharp-libvips-linux-s390x@1.2.4': + resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} + cpu: [s390x] + os: [linux] + '@img/sharp-libvips-linux-x64@1.2.3': resolution: {integrity: sha512-3JU7LmR85K6bBiRzSUc/Ff9JBVIFVvq6bomKE0e63UXGeRw2HPVEjoJke1Yx+iU4rL7/7kUjES4dZ/81Qjhyxg==} cpu: [x64] os: [linux] + '@img/sharp-libvips-linux-x64@1.2.4': + resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} + cpu: [x64] + os: [linux] + '@img/sharp-libvips-linuxmusl-arm64@1.2.3': resolution: {integrity: sha512-F9q83RZ8yaCwENw1GieztSfj5msz7GGykG/BA+MOUefvER69K/ubgFHNeSyUu64amHIYKGDs4sRCMzXVj8sEyw==} cpu: [arm64] os: [linux] + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} + cpu: [arm64] + os: [linux] + '@img/sharp-libvips-linuxmusl-x64@1.2.3': resolution: {integrity: sha512-U5PUY5jbc45ANM6tSJpsgqmBF/VsL6LnxJmIf11kB7J5DctHgqm0SkuXzVWtIY90GnJxKnC/JT251TDnk1fu/g==} cpu: [x64] os: [linux] + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} + cpu: [x64] + os: [linux] + '@img/sharp-linux-arm64@0.34.4': resolution: {integrity: sha512-YXU1F/mN/Wu786tl72CyJjP/Ngl8mGHN1hST4BGl+hiW5jhCnV2uRVTNOcaYPs73NeT/H8Upm3y9582JVuZHrQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + '@img/sharp-linux-arm64@0.34.5': + resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + '@img/sharp-linux-arm@0.34.4': resolution: {integrity: sha512-Xyam4mlqM0KkTHYVSuc6wXRmM7LGN0P12li03jAnZ3EJWZqj83+hi8Y9UxZUbxsgsK1qOEwg7O0Bc0LjqQVtxA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm] os: [linux] + '@img/sharp-linux-arm@0.34.5': + resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + '@img/sharp-linux-ppc64@0.34.4': resolution: {integrity: sha512-F4PDtF4Cy8L8hXA2p3TO6s4aDt93v+LKmpcYFLAVdkkD3hSxZzee0rh6/+94FpAynsuMpLX5h+LRsSG3rIciUQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ppc64] os: [linux] + '@img/sharp-linux-ppc64@0.34.5': + resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ppc64] + os: [linux] + + '@img/sharp-linux-riscv64@0.34.5': + resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [riscv64] + os: [linux] + '@img/sharp-linux-s390x@0.34.4': resolution: {integrity: sha512-qVrZKE9Bsnzy+myf7lFKvng6bQzhNUAYcVORq2P7bDlvmF6u2sCmK2KyEQEBdYk+u3T01pVsPrkj943T1aJAsw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [s390x] os: [linux] + '@img/sharp-linux-s390x@0.34.5': + resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + '@img/sharp-linux-x64@0.34.4': resolution: {integrity: sha512-ZfGtcp2xS51iG79c6Vhw9CWqQC8l2Ot8dygxoDoIQPTat/Ov3qAa8qpxSrtAEAJW+UjTXc4yxCjNfxm4h6Xm2A==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + '@img/sharp-linux-x64@0.34.5': + resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + '@img/sharp-linuxmusl-arm64@0.34.4': resolution: {integrity: sha512-8hDVvW9eu4yHWnjaOOR8kHVrew1iIX+MUgwxSuH2XyYeNRtLUe4VNioSqbNkB7ZYQJj9rUTT4PyRscyk2PXFKA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + '@img/sharp-linuxmusl-arm64@0.34.5': + resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + '@img/sharp-linuxmusl-x64@0.34.4': resolution: {integrity: sha512-lU0aA5L8QTlfKjpDCEFOZsTYGn3AEiO6db8W5aQDxj0nQkVrZWmN3ZP9sYKWJdtq3PWPhUNlqehWyXpYDcI9Sg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + '@img/sharp-linuxmusl-x64@0.34.5': + resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + '@img/sharp-wasm32@0.34.4': resolution: {integrity: sha512-33QL6ZO/qpRyG7woB/HUALz28WnTMI2W1jgX3Nu2bypqLIKx/QKMILLJzJjI+SIbvXdG9fUnmrxR7vbi1sTBeA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [wasm32] + '@img/sharp-wasm32@0.34.5': + resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + '@img/sharp-win32-arm64@0.34.4': resolution: {integrity: sha512-2Q250do/5WXTwxW3zjsEuMSv5sUU4Tq9VThWKlU2EYLm4MB7ZeMwF+SFJutldYODXF6jzc6YEOC+VfX0SZQPqA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [win32] + '@img/sharp-win32-arm64@0.34.5': + resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [win32] + '@img/sharp-win32-ia32@0.34.4': resolution: {integrity: sha512-3ZeLue5V82dT92CNL6rsal6I2weKw1cYu+rGKm8fOCCtJTR2gYeUfY3FqUnIJsMUPIH68oS5jmZ0NiJ508YpEw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ia32] os: [win32] + '@img/sharp-win32-ia32@0.34.5': + resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + '@img/sharp-win32-x64@0.34.4': resolution: {integrity: sha512-xIyj4wpYs8J18sVN3mSQjwrw7fKUqRw+Z5rnHNCy5fYTxigBz81u5mOMPmFumwjcn8+ld1ppptMBCLic1nz6ig==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [win32] + '@img/sharp-win32-x64@0.34.5': + resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + '@ioredis/commands@1.4.0': resolution: {integrity: sha512-aFT2yemJJo+TZCmieA7qnYGQooOS7QfNmYrzGtsYd3g9j5iDP8AimYYAesf79ohjbLG12XxC4nG5DyEnC88AsQ==} @@ -5736,32 +5834,32 @@ packages: resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} engines: {node: '>=18'} - '@smithy/abort-controller@4.2.3': - resolution: {integrity: sha512-xWL9Mf8b7tIFuAlpjKtRPnHrR8XVrwTj5NPYO/QwZPtc0SDLsPxb56V5tzi5yspSMytISHybifez+4jlrx0vkQ==} + '@smithy/abort-controller@4.2.5': + resolution: {integrity: sha512-j7HwVkBw68YW8UmFRcjZOmssE77Rvk0GWAIN1oFBhsaovQmZWYCIcGa9/pwRB0ExI8Sk9MWNALTjftjHZea7VA==} engines: {node: '>=18.0.0'} - '@smithy/config-resolver@4.3.3': - resolution: {integrity: sha512-xSql8A1Bl41O9JvGU/CtgiLBlwkvpHTSKRlvz9zOBvBCPjXghZ6ZkcVzmV2f7FLAA+80+aqKmIOmy8pEDrtCaw==} + '@smithy/config-resolver@4.4.3': + resolution: {integrity: sha512-ezHLe1tKLUxDJo2LHtDuEDyWXolw8WGOR92qb4bQdWq/zKenO5BvctZGrVJBK08zjezSk7bmbKFOXIVyChvDLw==} engines: {node: '>=18.0.0'} - '@smithy/core@3.17.0': - resolution: {integrity: sha512-Tir3DbfoTO97fEGUZjzGeoXgcQAUBRDTmuH9A8lxuP8ATrgezrAJ6cLuRvwdKN4ZbYNlHgKlBX69Hyu3THYhtg==} + '@smithy/core@3.18.5': + resolution: {integrity: sha512-6gnIz3h+PEPQGDj8MnRSjDvKBah042jEoPgjFGJ4iJLBE78L4lY/n98x14XyPF4u3lN179Ub/ZKFY5za9GeLQw==} engines: {node: '>=18.0.0'} - '@smithy/credential-provider-imds@4.2.3': - resolution: {integrity: sha512-hA1MQ/WAHly4SYltJKitEsIDVsNmXcQfYBRv2e+q04fnqtAX5qXaybxy/fhUeAMCnQIdAjaGDb04fMHQefWRhw==} + '@smithy/credential-provider-imds@4.2.5': + resolution: {integrity: sha512-BZwotjoZWn9+36nimwm/OLIcVe+KYRwzMjfhd4QT7QxPm9WY0HiOV8t/Wlh+HVUif0SBVV7ksq8//hPaBC/okQ==} engines: {node: '>=18.0.0'} - '@smithy/fetch-http-handler@5.3.4': - resolution: {integrity: sha512-bwigPylvivpRLCm+YK9I5wRIYjFESSVwl8JQ1vVx/XhCw0PtCi558NwTnT2DaVCl5pYlImGuQTSwMsZ+pIavRw==} + '@smithy/fetch-http-handler@5.3.6': + resolution: {integrity: sha512-3+RG3EA6BBJ/ofZUeTFJA7mHfSYrZtQIrDP9dI8Lf7X6Jbos2jptuLrAAteDiFVrmbEmLSuRG/bUKzfAXk7dhg==} engines: {node: '>=18.0.0'} - '@smithy/hash-node@4.2.3': - resolution: {integrity: sha512-6+NOdZDbfuU6s1ISp3UOk5Rg953RJ2aBLNLLBEcamLjHAg1Po9Ha7QIB5ZWhdRUVuOUrT8BVFR+O2KIPmw027g==} + '@smithy/hash-node@4.2.5': + resolution: {integrity: sha512-DpYX914YOfA3UDT9CN1BM787PcHfWRBB43fFGCYrZFUH0Jv+5t8yYl+Pd5PW4+QzoGEDvn5d5QIO4j2HyYZQSA==} engines: {node: '>=18.0.0'} - '@smithy/invalid-dependency@4.2.3': - resolution: {integrity: sha512-Cc9W5DwDuebXEDMpOpl4iERo8I0KFjTnomK2RMdhhR87GwrSmUmwMxS4P5JdRf+LsjOdIqumcerwRgYMr/tZ9Q==} + '@smithy/invalid-dependency@4.2.5': + resolution: {integrity: sha512-2L2erASEro1WC5nV+plwIMxrTXpvpfzl4e+Nre6vBVRR2HKeGGcvpJyyL3/PpiSg+cJG2KpTmZmq934Olb6e5A==} engines: {node: '>=18.0.0'} '@smithy/is-array-buffer@2.2.0': @@ -5772,80 +5870,80 @@ packages: resolution: {integrity: sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ==} engines: {node: '>=18.0.0'} - '@smithy/middleware-content-length@4.2.3': - resolution: {integrity: sha512-/atXLsT88GwKtfp5Jr0Ks1CSa4+lB+IgRnkNrrYP0h1wL4swHNb0YONEvTceNKNdZGJsye+W2HH8W7olbcPUeA==} + '@smithy/middleware-content-length@4.2.5': + resolution: {integrity: sha512-Y/RabVa5vbl5FuHYV2vUCwvh/dqzrEY/K2yWPSqvhFUwIY0atLqO4TienjBXakoy4zrKAMCZwg+YEqmH7jaN7A==} engines: {node: '>=18.0.0'} - '@smithy/middleware-endpoint@4.3.4': - resolution: {integrity: sha512-/RJhpYkMOaUZoJEkddamGPPIYeKICKXOu/ojhn85dKDM0n5iDIhjvYAQLP3K5FPhgB203O3GpWzoK2OehEoIUw==} + '@smithy/middleware-endpoint@4.3.12': + resolution: {integrity: sha512-9pAX/H+VQPzNbouhDhkW723igBMLgrI8OtX+++M7iKJgg/zY/Ig3i1e6seCcx22FWhE6Q/S61BRdi2wXBORT+A==} engines: {node: '>=18.0.0'} - '@smithy/middleware-retry@4.4.4': - resolution: {integrity: sha512-vSgABQAkuUHRO03AhR2rWxVQ1un284lkBn+NFawzdahmzksAoOeVMnXXsuPViL4GlhRHXqFaMlc8Mj04OfQk1w==} + '@smithy/middleware-retry@4.4.12': + resolution: {integrity: sha512-S4kWNKFowYd0lID7/DBqWHOQxmxlsf0jBaos9chQZUWTVOjSW1Ogyh8/ib5tM+agFDJ/TCxuCTvrnlc+9cIBcQ==} engines: {node: '>=18.0.0'} - '@smithy/middleware-serde@4.2.3': - resolution: {integrity: sha512-8g4NuUINpYccxiCXM5s1/V+uLtts8NcX4+sPEbvYQDZk4XoJfDpq5y2FQxfmUL89syoldpzNzA0R9nhzdtdKnQ==} + '@smithy/middleware-serde@4.2.6': + resolution: {integrity: sha512-VkLoE/z7e2g8pirwisLz8XJWedUSY8my/qrp81VmAdyrhi94T+riBfwP+AOEEFR9rFTSonC/5D2eWNmFabHyGQ==} engines: {node: '>=18.0.0'} - '@smithy/middleware-stack@4.2.3': - resolution: {integrity: sha512-iGuOJkH71faPNgOj/gWuEGS6xvQashpLwWB1HjHq1lNNiVfbiJLpZVbhddPuDbx9l4Cgl0vPLq5ltRfSaHfspA==} + '@smithy/middleware-stack@4.2.5': + resolution: {integrity: sha512-bYrutc+neOyWxtZdbB2USbQttZN0mXaOyYLIsaTbJhFsfpXyGWUxJpEuO1rJ8IIJm2qH4+xJT0mxUSsEDTYwdQ==} engines: {node: '>=18.0.0'} - '@smithy/node-config-provider@4.3.3': - resolution: {integrity: sha512-NzI1eBpBSViOav8NVy1fqOlSfkLgkUjUTlohUSgAEhHaFWA3XJiLditvavIP7OpvTjDp5u2LhtlBhkBlEisMwA==} + '@smithy/node-config-provider@4.3.5': + resolution: {integrity: sha512-UTurh1C4qkVCtqggI36DGbLB2Kv8UlcFdMXDcWMbqVY2uRg0XmT9Pb4Vj6oSQ34eizO1fvR0RnFV4Axw4IrrAg==} engines: {node: '>=18.0.0'} - '@smithy/node-http-handler@4.4.2': - resolution: {integrity: sha512-MHFvTjts24cjGo1byXqhXrbqm7uznFD/ESFx8npHMWTFQVdBZjrT1hKottmp69LBTRm/JQzP/sn1vPt0/r6AYQ==} + '@smithy/node-http-handler@4.4.5': + resolution: {integrity: sha512-CMnzM9R2WqlqXQGtIlsHMEZfXKJVTIrqCNoSd/QpAyp+Dw0a1Vps13l6ma1fH8g7zSPNsA59B/kWgeylFuA/lw==} engines: {node: '>=18.0.0'} '@smithy/property-provider@3.1.11': resolution: {integrity: sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==} engines: {node: '>=16.0.0'} - '@smithy/property-provider@4.2.3': - resolution: {integrity: sha512-+1EZ+Y+njiefCohjlhyOcy1UNYjT+1PwGFHCxA/gYctjg3DQWAU19WigOXAco/Ql8hZokNehpzLd0/+3uCreqQ==} + '@smithy/property-provider@4.2.5': + resolution: {integrity: sha512-8iLN1XSE1rl4MuxvQ+5OSk/Zb5El7NJZ1td6Tn+8dQQHIjp59Lwl6bd0+nzw6SKm2wSSriH2v/I9LPzUic7EOg==} engines: {node: '>=18.0.0'} - '@smithy/protocol-http@5.3.3': - resolution: {integrity: sha512-Mn7f/1aN2/jecywDcRDvWWWJF4uwg/A0XjFMJtj72DsgHTByfjRltSqcT9NyE9RTdBSN6X1RSXrhn/YWQl8xlw==} + '@smithy/protocol-http@5.3.5': + resolution: {integrity: sha512-RlaL+sA0LNMp03bf7XPbFmT5gN+w3besXSWMkA8rcmxLSVfiEXElQi4O2IWwPfxzcHkxqrwBFMbngB8yx/RvaQ==} engines: {node: '>=18.0.0'} - '@smithy/querystring-builder@4.2.3': - resolution: {integrity: sha512-LOVCGCmwMahYUM/P0YnU/AlDQFjcu+gWbFJooC417QRB/lDJlWSn8qmPSDp+s4YVAHOgtgbNG4sR+SxF/VOcJQ==} + '@smithy/querystring-builder@4.2.5': + resolution: {integrity: sha512-y98otMI1saoajeik2kLfGyRp11e5U/iJYH/wLCh3aTV/XutbGT9nziKGkgCaMD1ghK7p6htHMm6b6scl9JRUWg==} engines: {node: '>=18.0.0'} - '@smithy/querystring-parser@4.2.3': - resolution: {integrity: sha512-cYlSNHcTAX/wc1rpblli3aUlLMGgKZ/Oqn8hhjFASXMCXjIqeuQBei0cnq2JR8t4RtU9FpG6uyl6PxyArTiwKA==} + '@smithy/querystring-parser@4.2.5': + resolution: {integrity: sha512-031WCTdPYgiQRYNPXznHXof2YM0GwL6SeaSyTH/P72M1Vz73TvCNH2Nq8Iu2IEPq9QP2yx0/nrw5YmSeAi/AjQ==} engines: {node: '>=18.0.0'} - '@smithy/service-error-classification@4.2.3': - resolution: {integrity: sha512-NkxsAxFWwsPsQiwFG2MzJ/T7uIR6AQNh1SzcxSUnmmIqIQMlLRQDKhc17M7IYjiuBXhrQRjQTo3CxX+DobS93g==} + '@smithy/service-error-classification@4.2.5': + resolution: {integrity: sha512-8fEvK+WPE3wUAcDvqDQG1Vk3ANLR8Px979te96m84CbKAjBVf25rPYSzb4xU4hlTyho7VhOGnh5i62D/JVF0JQ==} engines: {node: '>=18.0.0'} - '@smithy/shared-ini-file-loader@4.3.3': - resolution: {integrity: sha512-9f9Ixej0hFhroOK2TxZfUUDR13WVa8tQzhSzPDgXe5jGL3KmaM9s8XN7RQwqtEypI82q9KHnKS71CJ+q/1xLtQ==} + '@smithy/shared-ini-file-loader@4.4.0': + resolution: {integrity: sha512-5WmZ5+kJgJDjwXXIzr1vDTG+RhF9wzSODQBfkrQ2VVkYALKGvZX1lgVSxEkgicSAFnFhPj5rudJV0zoinqS0bA==} engines: {node: '>=18.0.0'} - '@smithy/signature-v4@5.3.3': - resolution: {integrity: sha512-CmSlUy+eEYbIEYN5N3vvQTRfqt0lJlQkaQUIf+oizu7BbDut0pozfDjBGecfcfWf7c62Yis4JIEgqQ/TCfodaA==} + '@smithy/signature-v4@5.3.5': + resolution: {integrity: sha512-xSUfMu1FT7ccfSXkoLl/QRQBi2rOvi3tiBZU2Tdy3I6cgvZ6SEi9QNey+lqps/sJRnogIS+lq+B1gxxbra2a/w==} engines: {node: '>=18.0.0'} - '@smithy/smithy-client@4.9.0': - resolution: {integrity: sha512-qz7RTd15GGdwJ3ZCeBKLDQuUQ88m+skh2hJwcpPm1VqLeKzgZvXf6SrNbxvx7uOqvvkjCMXqx3YB5PDJyk00ww==} + '@smithy/smithy-client@4.9.8': + resolution: {integrity: sha512-8xgq3LgKDEFoIrLWBho/oYKyWByw9/corz7vuh1upv7ZBm0ZMjGYBhbn6v643WoIqA9UTcx5A5htEp/YatUwMA==} engines: {node: '>=18.0.0'} '@smithy/types@3.7.2': resolution: {integrity: sha512-bNwBYYmN8Eh9RyjS1p2gW6MIhSO2rl7X9QeLM8iTdcGRP+eDiIWDt66c9IysCc22gefKszZv+ubV9qZc7hdESg==} engines: {node: '>=16.0.0'} - '@smithy/types@4.8.0': - resolution: {integrity: sha512-QpELEHLO8SsQVtqP+MkEgCYTFW0pleGozfs3cZ183ZBj9z3VC1CX1/wtFMK64p+5bhtZo41SeLK1rBRtd25nHQ==} + '@smithy/types@4.9.0': + resolution: {integrity: sha512-MvUbdnXDTwykR8cB1WZvNNwqoWVaTRA0RLlLmf/cIFNMM2cKWz01X4Ly6SMC4Kks30r8tT3Cty0jmeWfiuyHTA==} engines: {node: '>=18.0.0'} - '@smithy/url-parser@4.2.3': - resolution: {integrity: sha512-I066AigYvY3d9VlU3zG9XzZg1yT10aNqvCaBTw9EPgu5GrsEl1aUkcMvhkIXascYH1A8W0LQo3B1Kr1cJNcQEw==} + '@smithy/url-parser@4.2.5': + resolution: {integrity: sha512-VaxMGsilqFnK1CeBX+LXnSuaMx4sTL/6znSZh2829txWieazdVxr54HmiyTsIbpOTLcf5nYpq9lpzmwRdxj6rQ==} engines: {node: '>=18.0.0'} '@smithy/util-base64@4.3.0': @@ -5872,32 +5970,32 @@ packages: resolution: {integrity: sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-browser@4.3.3': - resolution: {integrity: sha512-vqHoybAuZXbFXZqgzquiUXtdY+UT/aU33sxa4GBPkiYklmR20LlCn+d3Wc3yA5ZM13gQ92SZe/D8xh6hkjx+IQ==} + '@smithy/util-defaults-mode-browser@4.3.11': + resolution: {integrity: sha512-yHv+r6wSQXEXTPVCIQTNmXVWs7ekBTpMVErjqZoWkYN75HIFN5y9+/+sYOejfAuvxWGvgzgxbTHa/oz61YTbKw==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-node@4.2.4': - resolution: {integrity: sha512-X5/xrPHedifo7hJUUWKlpxVb2oDOiqPUXlvsZv1EZSjILoutLiJyWva3coBpn00e/gPSpH8Rn2eIbgdwHQdW7Q==} + '@smithy/util-defaults-mode-node@4.2.14': + resolution: {integrity: sha512-ljZN3iRvaJUgulfvobIuG97q1iUuCMrvXAlkZ4msY+ZuVHQHDIqn7FKZCEj+bx8omz6kF5yQXms/xhzjIO5XiA==} engines: {node: '>=18.0.0'} - '@smithy/util-endpoints@3.2.3': - resolution: {integrity: sha512-aCfxUOVv0CzBIkU10TubdgKSx5uRvzH064kaiPEWfNIvKOtNpu642P4FP1hgOFkjQIkDObrfIDnKMKkeyrejvQ==} + '@smithy/util-endpoints@3.2.5': + resolution: {integrity: sha512-3O63AAWu2cSNQZp+ayl9I3NapW1p1rR5mlVHcF6hAB1dPZUQFfRPYtplWX/3xrzWthPGj5FqB12taJJCfH6s8A==} engines: {node: '>=18.0.0'} '@smithy/util-hex-encoding@4.2.0': resolution: {integrity: sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw==} engines: {node: '>=18.0.0'} - '@smithy/util-middleware@4.2.3': - resolution: {integrity: sha512-v5ObKlSe8PWUHCqEiX2fy1gNv6goiw6E5I/PN2aXg3Fb/hse0xeaAnSpXDiWl7x6LamVKq7senB+m5LOYHUAHw==} + '@smithy/util-middleware@4.2.5': + resolution: {integrity: sha512-6Y3+rvBF7+PZOc40ybeZMcGln6xJGVeY60E7jy9Mv5iKpMJpHgRE6dKy9ScsVxvfAYuEX4Q9a65DQX90KaQ3bA==} engines: {node: '>=18.0.0'} - '@smithy/util-retry@4.2.3': - resolution: {integrity: sha512-lLPWnakjC0q9z+OtiXk+9RPQiYPNAovt2IXD3CP4LkOnd9NpUsxOjMx1SnoUVB7Orb7fZp67cQMtTBKMFDvOGg==} + '@smithy/util-retry@4.2.5': + resolution: {integrity: sha512-GBj3+EZBbN4NAqJ/7pAhsXdfzdlznOh8PydUijy6FpNIMnHPSMO2/rP4HKu+UFeikJxShERk528oy7GT79YiJg==} engines: {node: '>=18.0.0'} - '@smithy/util-stream@4.5.3': - resolution: {integrity: sha512-oZvn8a5bwwQBNYHT2eNo0EU8Kkby3jeIg1P2Lu9EQtqDxki1LIjGRJM6dJ5CZUig8QmLxWxqOKWvg3mVoOBs5A==} + '@smithy/util-stream@4.5.6': + resolution: {integrity: sha512-qWw/UM59TiaFrPevefOZ8CNBKbYEP6wBAIlLqxn3VAIo9rgnTNc4ASbVrqDmhuwI87usnjhdQrxodzAGFFzbRQ==} engines: {node: '>=18.0.0'} '@smithy/util-uri-escape@4.2.0': @@ -6050,6 +6148,9 @@ packages: '@swc/helpers@0.5.15': resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + '@swc/helpers@0.5.17': + resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} + '@swc/types@0.1.23': resolution: {integrity: sha512-u1iIVZV9Q0jxY+yM2vw/hZGDNudsN85bBpTqzAQ9rzkxW9D+e3aEM4Han+ow518gSewkXgjmEK0BD79ZcNVgPw==} @@ -6885,11 +6986,6 @@ packages: resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} hasBin: true - astro@5.15.6: - resolution: {integrity: sha512-luLcw+FGkeUHYTfbmYjIWHB4T0D+3VSjCy8DKTXglJ2O3lU40AbwmPVBcnqhRnA1SneKzP5V5pzqjsHzUZ1+Rg==} - engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'} - hasBin: true - astro@5.16.0: resolution: {integrity: sha512-GaDRs2Mngpw3dr2vc085GnORh98NiXxwIjg/EoQQQl/icZt3Z7s0BRsYHDZ8swkZbOA6wZsqWJdrNirl+iKcDg==} engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'} @@ -8729,6 +8825,9 @@ packages: get-tsconfig@4.12.0: resolution: {integrity: sha512-LScr2aNr2FbjAjZh2C6X6BxRx1/x+aTDExct/xyq2XKbYOiG5c0aK7pMsSuyc0brz3ibr/lbQiHD9jzt4lccJw==} + get-tsconfig@4.13.0: + resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} + giget@2.0.0: resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==} hasBin: true @@ -9272,8 +9371,8 @@ packages: js-tokens@9.0.1: resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} - js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + js-yaml@3.14.2: + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} hasBin: true js-yaml@4.1.0: @@ -10141,8 +10240,8 @@ packages: nlcst-to-string@4.0.0: resolution: {integrity: sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==} - node-abi@3.78.0: - resolution: {integrity: sha512-E2wEyrgX/CqvicaQYU3Ze1PFGjc4QYPGsjUrlYkqAE0WjHEZwgOsGMPMzkMse4LjJbDmaEuDX3CM036j5K2DSQ==} + node-abi@3.85.0: + resolution: {integrity: sha512-zsFhmbkAzwhTft6nd3VxcG0cvJsT70rL+BIGHWVq5fi6MwGrHwzqKaxXE+Hl2GmnGItnDKPPkO5/LQqjVkIdFg==} engines: {node: '>=10'} node-addon-api@7.1.1: @@ -10310,6 +10409,9 @@ packages: oniguruma-to-es@4.3.3: resolution: {integrity: sha512-rPiZhzC3wXwE59YQMRDodUwwT9FZ9nNBwQQfsd1wfdtlKEyCdRV0avrTcSZ5xlIvGRVPd/cx6ZN45ECmS39xvg==} + oniguruma-to-es@4.3.4: + resolution: {integrity: sha512-3VhUGN3w2eYxnTzHn+ikMI+fp/96KoRSVK9/kMTcFqj1NRDh2IhQCKvYxDnWePKRXY/AqH+Fuiyb7VHSzBjHfA==} + open@10.2.0: resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==} engines: {node: '>=18'} @@ -11279,6 +11381,11 @@ packages: engines: {node: '>= 0.4'} hasBin: true + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} + engines: {node: '>= 0.4'} + hasBin: true + resolve@2.0.0-next.5: resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} hasBin: true @@ -11389,6 +11496,9 @@ packages: sax@1.4.1: resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} + sax@1.4.3: + resolution: {integrity: sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==} + scheduler@0.26.0: resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} @@ -11453,6 +11563,10 @@ packages: resolution: {integrity: sha512-FUH39xp3SBPnxWvd5iib1X8XY7J0K0X7d93sie9CJg2PO8/7gmg89Nve6OjItK53/MlAushNNxteBYfM6DEuoA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + sharp@0.34.5: + resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -11878,9 +11992,6 @@ packages: tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} - tinyexec@1.0.1: - resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==} - tinyexec@1.0.2: resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} engines: {node: '>=18'} @@ -12142,8 +12253,8 @@ packages: unist-util-find-after@5.0.0: resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==} - unist-util-is@6.0.0: - resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} unist-util-modify-children@4.0.0: resolution: {integrity: sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==} @@ -12511,6 +12622,9 @@ packages: vfile-message@4.0.2: resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} @@ -12747,6 +12861,46 @@ packages: yaml: optional: true + vite@7.2.4: + resolution: {integrity: sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + vitefu@1.1.1: resolution: {integrity: sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==} peerDependencies: @@ -12995,8 +13149,8 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} - yocto-queue@1.2.1: - resolution: {integrity: sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==} + yocto-queue@1.2.2: + resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} engines: {node: '>=12.20'} yocto-spinner@0.2.3: @@ -13110,32 +13264,6 @@ snapshots: '@astrojs/internal-helpers@0.7.5': {} - '@astrojs/markdown-remark@6.3.8': - dependencies: - '@astrojs/internal-helpers': 0.7.4 - '@astrojs/prism': 3.3.0 - github-slugger: 2.0.0 - hast-util-from-html: 2.0.3 - hast-util-to-text: 4.0.2 - import-meta-resolve: 4.2.0 - js-yaml: 4.1.1 - mdast-util-definitions: 6.0.0 - rehype-raw: 7.0.0 - rehype-stringify: 10.0.1 - remark-gfm: 4.0.1 - remark-parse: 11.0.0 - remark-rehype: 11.1.2 - remark-smartypants: 3.0.2 - shiki: 3.13.0 - smol-toml: 1.5.2 - unified: 11.0.5 - unist-util-remove-position: 5.0.0 - unist-util-visit: 5.0.0 - unist-util-visit-parents: 6.0.2 - vfile: 6.0.3 - transitivePeerDependencies: - - supports-color - '@astrojs/markdown-remark@6.3.9': dependencies: '@astrojs/internal-helpers': 0.7.5 @@ -13152,7 +13280,7 @@ snapshots: remark-parse: 11.0.0 remark-rehype: 11.1.2 remark-smartypants: 3.0.2 - shiki: 3.13.0 + shiki: 3.15.0 smol-toml: 1.5.2 unified: 11.0.5 unist-util-remove-position: 5.0.0 @@ -13178,7 +13306,7 @@ snapshots: '@astrojs/telemetry@3.3.0': dependencies: ci-info: 4.3.1 - debug: 4.4.3(supports-color@8.1.1) + debug: 4.4.3 dlv: 1.1.3 dset: 3.1.4 is-docker: 3.0.0 @@ -13187,10 +13315,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@astrojs/vercel@9.0.1(@aws-sdk/credential-provider-web-identity@3.844.0)(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(astro@5.16.0(@netlify/blobs@9.1.2)(@types/node@24.6.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1))(next@16.0.3(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(rollup@4.53.3)(svelte@5.43.3)(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))': + '@astrojs/vercel@9.0.1(@aws-sdk/credential-provider-web-identity@3.844.0)(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(astro@5.16.0(@netlify/blobs@9.1.2)(@types/node@24.6.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1))(next@16.0.3(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(rollup@4.53.3)(svelte@5.43.3)(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))': dependencies: '@astrojs/internal-helpers': 0.7.5 - '@vercel/analytics': 1.5.0(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(next@16.0.3(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(svelte@5.43.3)(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) + '@vercel/analytics': 1.5.0(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(next@16.0.3(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(svelte@5.43.3)(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) '@vercel/functions': 2.2.13(@aws-sdk/credential-provider-web-identity@3.844.0) '@vercel/nft': 0.30.3(rollup@4.53.3) '@vercel/routing-utils': 5.3.0 @@ -13250,30 +13378,30 @@ snapshots: '@aws-sdk/util-endpoints': 3.844.0 '@aws-sdk/util-user-agent-browser': 3.840.0 '@aws-sdk/util-user-agent-node': 3.844.0 - '@smithy/config-resolver': 4.3.3 - '@smithy/core': 3.17.0 - '@smithy/fetch-http-handler': 5.3.4 - '@smithy/hash-node': 4.2.3 - '@smithy/invalid-dependency': 4.2.3 - '@smithy/middleware-content-length': 4.2.3 - '@smithy/middleware-endpoint': 4.3.4 - '@smithy/middleware-retry': 4.4.4 - '@smithy/middleware-serde': 4.2.3 - '@smithy/middleware-stack': 4.2.3 - '@smithy/node-config-provider': 4.3.3 - '@smithy/node-http-handler': 4.4.2 - '@smithy/protocol-http': 5.3.3 - '@smithy/smithy-client': 4.9.0 - '@smithy/types': 4.8.0 - '@smithy/url-parser': 4.2.3 + '@smithy/config-resolver': 4.4.3 + '@smithy/core': 3.18.5 + '@smithy/fetch-http-handler': 5.3.6 + '@smithy/hash-node': 4.2.5 + '@smithy/invalid-dependency': 4.2.5 + '@smithy/middleware-content-length': 4.2.5 + '@smithy/middleware-endpoint': 4.3.12 + '@smithy/middleware-retry': 4.4.12 + '@smithy/middleware-serde': 4.2.6 + '@smithy/middleware-stack': 4.2.5 + '@smithy/node-config-provider': 4.3.5 + '@smithy/node-http-handler': 4.4.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/smithy-client': 4.9.8 + '@smithy/types': 4.9.0 + '@smithy/url-parser': 4.2.5 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.3 - '@smithy/util-defaults-mode-node': 4.2.4 - '@smithy/util-endpoints': 3.2.3 - '@smithy/util-middleware': 4.2.3 - '@smithy/util-retry': 4.2.3 + '@smithy/util-defaults-mode-browser': 4.3.11 + '@smithy/util-defaults-mode-node': 4.2.14 + '@smithy/util-endpoints': 3.2.5 + '@smithy/util-middleware': 4.2.5 + '@smithy/util-retry': 4.2.5 '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 transitivePeerDependencies: @@ -13294,30 +13422,30 @@ snapshots: '@aws-sdk/util-endpoints': 3.844.0 '@aws-sdk/util-user-agent-browser': 3.840.0 '@aws-sdk/util-user-agent-node': 3.844.0 - '@smithy/config-resolver': 4.3.3 - '@smithy/core': 3.17.0 - '@smithy/fetch-http-handler': 5.3.4 - '@smithy/hash-node': 4.2.3 - '@smithy/invalid-dependency': 4.2.3 - '@smithy/middleware-content-length': 4.2.3 - '@smithy/middleware-endpoint': 4.3.4 - '@smithy/middleware-retry': 4.4.4 - '@smithy/middleware-serde': 4.2.3 - '@smithy/middleware-stack': 4.2.3 - '@smithy/node-config-provider': 4.3.3 - '@smithy/node-http-handler': 4.4.2 - '@smithy/protocol-http': 5.3.3 - '@smithy/smithy-client': 4.9.0 - '@smithy/types': 4.8.0 - '@smithy/url-parser': 4.2.3 + '@smithy/config-resolver': 4.4.3 + '@smithy/core': 3.18.5 + '@smithy/fetch-http-handler': 5.3.6 + '@smithy/hash-node': 4.2.5 + '@smithy/invalid-dependency': 4.2.5 + '@smithy/middleware-content-length': 4.2.5 + '@smithy/middleware-endpoint': 4.3.12 + '@smithy/middleware-retry': 4.4.12 + '@smithy/middleware-serde': 4.2.6 + '@smithy/middleware-stack': 4.2.5 + '@smithy/node-config-provider': 4.3.5 + '@smithy/node-http-handler': 4.4.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/smithy-client': 4.9.8 + '@smithy/types': 4.9.0 + '@smithy/url-parser': 4.2.5 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.3 - '@smithy/util-defaults-mode-node': 4.2.4 - '@smithy/util-endpoints': 3.2.3 - '@smithy/util-middleware': 4.2.3 - '@smithy/util-retry': 4.2.3 + '@smithy/util-defaults-mode-browser': 4.3.11 + '@smithy/util-defaults-mode-node': 4.2.14 + '@smithy/util-endpoints': 3.2.5 + '@smithy/util-middleware': 4.2.5 + '@smithy/util-retry': 4.2.5 '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 transitivePeerDependencies: @@ -13327,16 +13455,16 @@ snapshots: dependencies: '@aws-sdk/types': 3.840.0 '@aws-sdk/xml-builder': 3.821.0 - '@smithy/core': 3.17.0 - '@smithy/node-config-provider': 4.3.3 - '@smithy/property-provider': 4.2.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/signature-v4': 5.3.3 - '@smithy/smithy-client': 4.9.0 - '@smithy/types': 4.8.0 + '@smithy/core': 3.18.5 + '@smithy/node-config-provider': 4.3.5 + '@smithy/property-provider': 4.2.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/signature-v4': 5.3.5 + '@smithy/smithy-client': 4.9.8 + '@smithy/types': 4.9.0 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 - '@smithy/util-middleware': 4.2.3 + '@smithy/util-middleware': 4.2.5 '@smithy/util-utf8': 4.2.0 fast-xml-parser: 5.2.5 tslib: 2.8.1 @@ -13345,21 +13473,21 @@ snapshots: dependencies: '@aws-sdk/core': 3.844.0 '@aws-sdk/types': 3.840.0 - '@smithy/property-provider': 4.2.3 - '@smithy/types': 4.8.0 + '@smithy/property-provider': 4.2.5 + '@smithy/types': 4.9.0 tslib: 2.8.1 '@aws-sdk/credential-provider-http@3.844.0': dependencies: '@aws-sdk/core': 3.844.0 '@aws-sdk/types': 3.840.0 - '@smithy/fetch-http-handler': 5.3.4 - '@smithy/node-http-handler': 4.4.2 - '@smithy/property-provider': 4.2.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/smithy-client': 4.9.0 - '@smithy/types': 4.8.0 - '@smithy/util-stream': 4.5.3 + '@smithy/fetch-http-handler': 5.3.6 + '@smithy/node-http-handler': 4.4.5 + '@smithy/property-provider': 4.2.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/smithy-client': 4.9.8 + '@smithy/types': 4.9.0 + '@smithy/util-stream': 4.5.6 tslib: 2.8.1 '@aws-sdk/credential-provider-ini@3.844.0': @@ -13372,10 +13500,10 @@ snapshots: '@aws-sdk/credential-provider-web-identity': 3.844.0 '@aws-sdk/nested-clients': 3.844.0 '@aws-sdk/types': 3.840.0 - '@smithy/credential-provider-imds': 4.2.3 - '@smithy/property-provider': 4.2.3 - '@smithy/shared-ini-file-loader': 4.3.3 - '@smithy/types': 4.8.0 + '@smithy/credential-provider-imds': 4.2.5 + '@smithy/property-provider': 4.2.5 + '@smithy/shared-ini-file-loader': 4.4.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt @@ -13389,10 +13517,10 @@ snapshots: '@aws-sdk/credential-provider-sso': 3.844.0 '@aws-sdk/credential-provider-web-identity': 3.844.0 '@aws-sdk/types': 3.840.0 - '@smithy/credential-provider-imds': 4.2.3 - '@smithy/property-provider': 4.2.3 - '@smithy/shared-ini-file-loader': 4.3.3 - '@smithy/types': 4.8.0 + '@smithy/credential-provider-imds': 4.2.5 + '@smithy/property-provider': 4.2.5 + '@smithy/shared-ini-file-loader': 4.4.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt @@ -13401,9 +13529,9 @@ snapshots: dependencies: '@aws-sdk/core': 3.844.0 '@aws-sdk/types': 3.840.0 - '@smithy/property-provider': 4.2.3 - '@smithy/shared-ini-file-loader': 4.3.3 - '@smithy/types': 4.8.0 + '@smithy/property-provider': 4.2.5 + '@smithy/shared-ini-file-loader': 4.4.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 '@aws-sdk/credential-provider-sso@3.844.0': @@ -13412,9 +13540,9 @@ snapshots: '@aws-sdk/core': 3.844.0 '@aws-sdk/token-providers': 3.844.0 '@aws-sdk/types': 3.840.0 - '@smithy/property-provider': 4.2.3 - '@smithy/shared-ini-file-loader': 4.3.3 - '@smithy/types': 4.8.0 + '@smithy/property-provider': 4.2.5 + '@smithy/shared-ini-file-loader': 4.4.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt @@ -13432,8 +13560,8 @@ snapshots: '@aws-sdk/core': 3.844.0 '@aws-sdk/nested-clients': 3.844.0 '@aws-sdk/types': 3.840.0 - '@smithy/property-provider': 4.2.3 - '@smithy/types': 4.8.0 + '@smithy/property-provider': 4.2.5 + '@smithy/types': 4.9.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt @@ -13441,21 +13569,21 @@ snapshots: '@aws-sdk/middleware-host-header@3.840.0': dependencies: '@aws-sdk/types': 3.840.0 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 + '@smithy/protocol-http': 5.3.5 + '@smithy/types': 4.9.0 tslib: 2.8.1 '@aws-sdk/middleware-logger@3.840.0': dependencies: '@aws-sdk/types': 3.840.0 - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 '@aws-sdk/middleware-recursion-detection@3.840.0': dependencies: '@aws-sdk/types': 3.840.0 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 + '@smithy/protocol-http': 5.3.5 + '@smithy/types': 4.9.0 tslib: 2.8.1 '@aws-sdk/middleware-user-agent@3.844.0': @@ -13463,9 +13591,9 @@ snapshots: '@aws-sdk/core': 3.844.0 '@aws-sdk/types': 3.840.0 '@aws-sdk/util-endpoints': 3.844.0 - '@smithy/core': 3.17.0 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 + '@smithy/core': 3.18.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/types': 4.9.0 tslib: 2.8.1 '@aws-sdk/nested-clients@3.844.0': @@ -13482,30 +13610,30 @@ snapshots: '@aws-sdk/util-endpoints': 3.844.0 '@aws-sdk/util-user-agent-browser': 3.840.0 '@aws-sdk/util-user-agent-node': 3.844.0 - '@smithy/config-resolver': 4.3.3 - '@smithy/core': 3.17.0 - '@smithy/fetch-http-handler': 5.3.4 - '@smithy/hash-node': 4.2.3 - '@smithy/invalid-dependency': 4.2.3 - '@smithy/middleware-content-length': 4.2.3 - '@smithy/middleware-endpoint': 4.3.4 - '@smithy/middleware-retry': 4.4.4 - '@smithy/middleware-serde': 4.2.3 - '@smithy/middleware-stack': 4.2.3 - '@smithy/node-config-provider': 4.3.3 - '@smithy/node-http-handler': 4.4.2 - '@smithy/protocol-http': 5.3.3 - '@smithy/smithy-client': 4.9.0 - '@smithy/types': 4.8.0 - '@smithy/url-parser': 4.2.3 + '@smithy/config-resolver': 4.4.3 + '@smithy/core': 3.18.5 + '@smithy/fetch-http-handler': 5.3.6 + '@smithy/hash-node': 4.2.5 + '@smithy/invalid-dependency': 4.2.5 + '@smithy/middleware-content-length': 4.2.5 + '@smithy/middleware-endpoint': 4.3.12 + '@smithy/middleware-retry': 4.4.12 + '@smithy/middleware-serde': 4.2.6 + '@smithy/middleware-stack': 4.2.5 + '@smithy/node-config-provider': 4.3.5 + '@smithy/node-http-handler': 4.4.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/smithy-client': 4.9.8 + '@smithy/types': 4.9.0 + '@smithy/url-parser': 4.2.5 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.3 - '@smithy/util-defaults-mode-node': 4.2.4 - '@smithy/util-endpoints': 3.2.3 - '@smithy/util-middleware': 4.2.3 - '@smithy/util-retry': 4.2.3 + '@smithy/util-defaults-mode-browser': 4.3.11 + '@smithy/util-defaults-mode-node': 4.2.14 + '@smithy/util-endpoints': 3.2.5 + '@smithy/util-middleware': 4.2.5 + '@smithy/util-retry': 4.2.5 '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 transitivePeerDependencies: @@ -13514,10 +13642,10 @@ snapshots: '@aws-sdk/region-config-resolver@3.840.0': dependencies: '@aws-sdk/types': 3.840.0 - '@smithy/node-config-provider': 4.3.3 - '@smithy/types': 4.8.0 + '@smithy/node-config-provider': 4.3.5 + '@smithy/types': 4.9.0 '@smithy/util-config-provider': 4.2.0 - '@smithy/util-middleware': 4.2.3 + '@smithy/util-middleware': 4.2.5 tslib: 2.8.1 '@aws-sdk/token-providers@3.844.0': @@ -13525,9 +13653,9 @@ snapshots: '@aws-sdk/core': 3.844.0 '@aws-sdk/nested-clients': 3.844.0 '@aws-sdk/types': 3.840.0 - '@smithy/property-provider': 4.2.3 - '@smithy/shared-ini-file-loader': 4.3.3 - '@smithy/types': 4.8.0 + '@smithy/property-provider': 4.2.5 + '@smithy/shared-ini-file-loader': 4.4.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt @@ -13539,15 +13667,15 @@ snapshots: '@aws-sdk/types@3.840.0': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 '@aws-sdk/util-endpoints@3.844.0': dependencies: '@aws-sdk/types': 3.840.0 - '@smithy/types': 4.8.0 - '@smithy/url-parser': 4.2.3 - '@smithy/util-endpoints': 3.2.3 + '@smithy/types': 4.9.0 + '@smithy/url-parser': 4.2.5 + '@smithy/util-endpoints': 3.2.5 tslib: 2.8.1 '@aws-sdk/util-locate-window@3.893.0': @@ -13557,7 +13685,7 @@ snapshots: '@aws-sdk/util-user-agent-browser@3.840.0': dependencies: '@aws-sdk/types': 3.840.0 - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 bowser: 2.12.1 tslib: 2.8.1 @@ -13565,13 +13693,13 @@ snapshots: dependencies: '@aws-sdk/middleware-user-agent': 3.844.0 '@aws-sdk/types': 3.840.0 - '@smithy/node-config-provider': 4.3.3 - '@smithy/types': 4.8.0 + '@smithy/node-config-provider': 4.3.5 + '@smithy/types': 4.9.0 tslib: 2.8.1 '@aws-sdk/xml-builder@3.821.0': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 '@babel/code-frame@7.27.1': @@ -13902,7 +14030,7 @@ snapshots: '@changesets/parse@0.4.1': dependencies: '@changesets/types': 6.1.0 - js-yaml: 3.14.1 + js-yaml: 3.14.2 '@changesets/pre@2.0.2': dependencies: @@ -13986,6 +14114,11 @@ snapshots: tslib: 2.8.1 optional: true + '@emnapi/runtime@1.7.1': + dependencies: + tslib: 2.8.1 + optional: true + '@emnapi/wasi-threads@1.1.0': dependencies: tslib: 2.8.1 @@ -14318,9 +14451,9 @@ snapshots: - supports-color optional: true - '@eslint/config-helpers@0.4.1': + '@eslint/config-helpers@0.4.2': dependencies: - '@eslint/core': 0.16.0 + '@eslint/core': 0.17.0 optional: true '@eslint/core@0.16.0': @@ -14328,6 +14461,11 @@ snapshots: '@types/json-schema': 7.0.15 optional: true + '@eslint/core@0.17.0': + dependencies: + '@types/json-schema': 7.0.15 + optional: true + '@eslint/eslintrc@3.3.1': dependencies: ajv: 6.12.6 @@ -14349,9 +14487,9 @@ snapshots: '@eslint/object-schema@2.1.7': optional: true - '@eslint/plugin-kit@0.4.0': + '@eslint/plugin-kit@0.4.1': dependencies: - '@eslint/core': 0.16.0 + '@eslint/core': 0.17.0 levn: 0.4.1 optional: true @@ -14454,87 +14592,181 @@ snapshots: '@img/sharp-libvips-darwin-arm64': 1.2.3 optional: true + '@img/sharp-darwin-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.2.4 + optional: true + '@img/sharp-darwin-x64@0.34.4': optionalDependencies: '@img/sharp-libvips-darwin-x64': 1.2.3 optional: true + '@img/sharp-darwin-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.2.4 + optional: true + '@img/sharp-libvips-darwin-arm64@1.2.3': optional: true + '@img/sharp-libvips-darwin-arm64@1.2.4': + optional: true + '@img/sharp-libvips-darwin-x64@1.2.3': optional: true + '@img/sharp-libvips-darwin-x64@1.2.4': + optional: true + '@img/sharp-libvips-linux-arm64@1.2.3': optional: true + '@img/sharp-libvips-linux-arm64@1.2.4': + optional: true + '@img/sharp-libvips-linux-arm@1.2.3': optional: true + '@img/sharp-libvips-linux-arm@1.2.4': + optional: true + '@img/sharp-libvips-linux-ppc64@1.2.3': optional: true + '@img/sharp-libvips-linux-ppc64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-riscv64@1.2.4': + optional: true + '@img/sharp-libvips-linux-s390x@1.2.3': optional: true + '@img/sharp-libvips-linux-s390x@1.2.4': + optional: true + '@img/sharp-libvips-linux-x64@1.2.3': optional: true + '@img/sharp-libvips-linux-x64@1.2.4': + optional: true + '@img/sharp-libvips-linuxmusl-arm64@1.2.3': optional: true + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + optional: true + '@img/sharp-libvips-linuxmusl-x64@1.2.3': optional: true + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + optional: true + '@img/sharp-linux-arm64@0.34.4': optionalDependencies: '@img/sharp-libvips-linux-arm64': 1.2.3 optional: true + '@img/sharp-linux-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.2.4 + optional: true + '@img/sharp-linux-arm@0.34.4': optionalDependencies: '@img/sharp-libvips-linux-arm': 1.2.3 optional: true + '@img/sharp-linux-arm@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.2.4 + optional: true + '@img/sharp-linux-ppc64@0.34.4': optionalDependencies: '@img/sharp-libvips-linux-ppc64': 1.2.3 optional: true + '@img/sharp-linux-ppc64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-ppc64': 1.2.4 + optional: true + + '@img/sharp-linux-riscv64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-riscv64': 1.2.4 + optional: true + '@img/sharp-linux-s390x@0.34.4': optionalDependencies: '@img/sharp-libvips-linux-s390x': 1.2.3 optional: true + '@img/sharp-linux-s390x@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.2.4 + optional: true + '@img/sharp-linux-x64@0.34.4': optionalDependencies: '@img/sharp-libvips-linux-x64': 1.2.3 optional: true + '@img/sharp-linux-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.2.4 + optional: true + '@img/sharp-linuxmusl-arm64@0.34.4': optionalDependencies: '@img/sharp-libvips-linuxmusl-arm64': 1.2.3 optional: true + '@img/sharp-linuxmusl-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + optional: true + '@img/sharp-linuxmusl-x64@0.34.4': optionalDependencies: '@img/sharp-libvips-linuxmusl-x64': 1.2.3 optional: true + '@img/sharp-linuxmusl-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + optional: true + '@img/sharp-wasm32@0.34.4': dependencies: '@emnapi/runtime': 1.5.0 optional: true + '@img/sharp-wasm32@0.34.5': + dependencies: + '@emnapi/runtime': 1.7.1 + optional: true + '@img/sharp-win32-arm64@0.34.4': optional: true + '@img/sharp-win32-arm64@0.34.5': + optional: true + '@img/sharp-win32-ia32@0.34.4': optional: true + '@img/sharp-win32-ia32@0.34.5': + optional: true + '@img/sharp-win32-x64@0.34.4': optional: true + '@img/sharp-win32-x64@0.34.5': + optional: true + '@ioredis/commands@1.4.0': {} '@isaacs/balanced-match@4.0.1': {} @@ -14974,7 +15206,7 @@ snapshots: semver: 7.7.3 srvx: 0.8.16 std-env: 3.10.0 - tinyexec: 1.0.1 + tinyexec: 1.0.2 ufo: 1.6.1 undici: 7.16.0 youch: 4.1.0-beta.11 @@ -14983,11 +15215,11 @@ snapshots: '@nuxt/devalue@2.0.2': {} - '@nuxt/devtools-kit@2.6.5(magicast@0.3.5)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': + '@nuxt/devtools-kit@2.6.5(magicast@0.3.5)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@nuxt/kit': 3.19.3(magicast@0.3.5) execa: 8.0.1 - vite: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - magicast @@ -15002,12 +15234,12 @@ snapshots: prompts: 2.4.2 semver: 7.7.3 - '@nuxt/devtools@2.6.5(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3))': + '@nuxt/devtools@2.6.5(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3))': dependencies: - '@nuxt/devtools-kit': 2.6.5(magicast@0.3.5)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + '@nuxt/devtools-kit': 2.6.5(magicast@0.3.5)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) '@nuxt/devtools-wizard': 2.6.5 '@nuxt/kit': 3.19.3(magicast@0.3.5) - '@vue/devtools-core': 7.7.7(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) + '@vue/devtools-core': 7.7.7(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) '@vue/devtools-kit': 7.7.7 birpc: 2.6.1 consola: 3.4.2 @@ -15032,9 +15264,9 @@ snapshots: sirv: 3.0.2 structured-clone-es: 1.0.0 tinyglobby: 0.2.15 - vite: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) - vite-plugin-inspect: 11.3.3(@nuxt/kit@3.19.3(magicast@0.3.5))(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) - vite-plugin-vue-tracer: 1.0.1(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) + vite: 7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite-plugin-inspect: 11.3.3(@nuxt/kit@3.19.3(magicast@0.3.5))(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + vite-plugin-vue-tracer: 1.0.1(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) which: 5.0.0 ws: 8.18.3 transitivePeerDependencies: @@ -15149,7 +15381,7 @@ snapshots: transitivePeerDependencies: - magicast - '@nuxt/module-builder@1.0.2(@nuxt/cli@3.29.3(magicast@0.3.5))(@vue/compiler-core@3.5.22)(esbuild@0.25.12)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3))': + '@nuxt/module-builder@1.0.2(@nuxt/cli@3.29.3(magicast@0.3.5))(@vue/compiler-core@3.5.22)(esbuild@0.25.11)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3))': dependencies: '@nuxt/cli': 3.29.3(magicast@0.3.5) citty: 0.1.6 @@ -15157,14 +15389,14 @@ snapshots: defu: 6.1.4 jiti: 2.6.1 magic-regexp: 0.10.0 - mkdist: 2.4.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.12)(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) + mkdist: 2.4.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.11)(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) mlly: 1.8.0 pathe: 2.0.3 pkg-types: 2.3.0 tsconfck: 3.1.6(typescript@5.9.3) typescript: 5.9.3 - unbuild: 3.6.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.12)(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) - vue-sfc-transformer: 0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.12)(vue@3.5.22(typescript@5.9.3)) + unbuild: 3.6.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.11)(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) + vue-sfc-transformer: 0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.11)(vue@3.5.22(typescript@5.9.3)) transitivePeerDependencies: - '@vue/compiler-core' - esbuild @@ -15219,8 +15451,8 @@ snapshots: dependencies: '@nuxt/kit': 4.0.0(magicast@0.3.5) '@rollup/plugin-replace': 6.0.2(rollup@4.53.3) - '@vitejs/plugin-vue': 6.0.1(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) - '@vitejs/plugin-vue-jsx': 5.1.1(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) + '@vitejs/plugin-vue': 6.0.1(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) + '@vitejs/plugin-vue-jsx': 5.1.1(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) autoprefixer: 10.4.21(postcss@8.5.6) consola: 3.4.2 cssnano: 7.1.1(postcss@8.5.6) @@ -15243,9 +15475,9 @@ snapshots: std-env: 3.10.0 ufo: 1.6.1 unenv: 2.0.0-rc.24 - vite: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vite-node: 3.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) - vite-plugin-checker: 0.10.3(@biomejs/biome@2.3.3)(eslint@9.38.0(jiti@2.6.1))(optionator@0.9.4)(typescript@5.9.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + vite-plugin-checker: 0.10.3(@biomejs/biome@2.3.3)(eslint@9.38.0(jiti@2.6.1))(optionator@0.9.4)(typescript@5.9.3)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) vue: 3.5.22(typescript@5.9.3) vue-bundle-renderer: 2.2.0 transitivePeerDependencies: @@ -15304,8 +15536,8 @@ snapshots: dependencies: '@nuxt/kit': 4.1.3(magicast@0.3.5) '@rollup/plugin-replace': 6.0.2(rollup@4.53.3) - '@vitejs/plugin-vue': 6.0.1(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) - '@vitejs/plugin-vue-jsx': 5.1.1(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) + '@vitejs/plugin-vue': 6.0.1(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) + '@vitejs/plugin-vue-jsx': 5.1.1(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) autoprefixer: 10.4.21(postcss@8.5.6) consola: 3.4.2 cssnano: 7.1.1(postcss@8.5.6) @@ -15317,7 +15549,7 @@ snapshots: h3: 1.15.4 jiti: 2.6.1 knitwork: 1.2.0 - magic-string: 0.30.21 + magic-string: 0.30.19 mlly: 1.8.0 mocked-exports: 0.1.1 pathe: 2.0.3 @@ -15327,9 +15559,9 @@ snapshots: std-env: 3.10.0 ufo: 1.6.1 unenv: 2.0.0-rc.21 - vite: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vite-node: 3.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) - vite-plugin-checker: 0.11.0(@biomejs/biome@2.3.3)(eslint@9.38.0(jiti@2.6.1))(optionator@0.9.4)(typescript@5.9.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + vite-plugin-checker: 0.11.0(@biomejs/biome@2.3.3)(eslint@9.38.0(jiti@2.6.1))(optionator@0.9.4)(typescript@5.9.3)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) vue: 3.5.22(typescript@5.9.3) vue-bundle-renderer: 2.2.0 transitivePeerDependencies: @@ -17306,7 +17538,7 @@ snapshots: estree-walker: 2.0.2 fdir: 6.5.0(picomatch@4.0.3) is-reference: 1.2.1 - magic-string: 0.30.21 + magic-string: 0.30.19 picomatch: 4.0.3 optionalDependencies: rollup: 4.52.5 @@ -17327,7 +17559,7 @@ snapshots: dependencies: '@rollup/pluginutils': 5.3.0(rollup@4.52.5) estree-walker: 2.0.2 - magic-string: 0.30.21 + magic-string: 0.30.19 optionalDependencies: rollup: 4.52.5 @@ -17335,7 +17567,7 @@ snapshots: dependencies: '@rollup/pluginutils': 5.3.0(rollup@4.53.3) estree-walker: 2.0.2 - magic-string: 0.30.21 + magic-string: 0.30.19 optionalDependencies: rollup: 4.53.3 @@ -17374,14 +17606,14 @@ snapshots: '@rollup/plugin-replace@6.0.2(rollup@4.52.5)': dependencies: '@rollup/pluginutils': 5.3.0(rollup@4.52.5) - magic-string: 0.30.21 + magic-string: 0.30.19 optionalDependencies: rollup: 4.52.5 '@rollup/plugin-replace@6.0.2(rollup@4.53.3)': dependencies: '@rollup/pluginutils': 5.3.0(rollup@4.53.3) - magic-string: 0.30.21 + magic-string: 0.30.19 optionalDependencies: rollup: 4.53.3 @@ -17575,7 +17807,7 @@ snapshots: dependencies: '@shikijs/types': 3.15.0 '@shikijs/vscode-textmate': 10.0.2 - oniguruma-to-es: 4.3.3 + oniguruma-to-es: 4.3.4 '@shikijs/engine-oniguruma@3.13.0': dependencies: @@ -17635,58 +17867,59 @@ snapshots: '@sindresorhus/merge-streams@4.0.0': {} - '@smithy/abort-controller@4.2.3': + '@smithy/abort-controller@4.2.5': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@smithy/config-resolver@4.3.3': + '@smithy/config-resolver@4.4.3': dependencies: - '@smithy/node-config-provider': 4.3.3 - '@smithy/types': 4.8.0 + '@smithy/node-config-provider': 4.3.5 + '@smithy/types': 4.9.0 '@smithy/util-config-provider': 4.2.0 - '@smithy/util-middleware': 4.2.3 + '@smithy/util-endpoints': 3.2.5 + '@smithy/util-middleware': 4.2.5 tslib: 2.8.1 - '@smithy/core@3.17.0': + '@smithy/core@3.18.5': dependencies: - '@smithy/middleware-serde': 4.2.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 + '@smithy/middleware-serde': 4.2.6 + '@smithy/protocol-http': 5.3.5 + '@smithy/types': 4.9.0 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 - '@smithy/util-middleware': 4.2.3 - '@smithy/util-stream': 4.5.3 + '@smithy/util-middleware': 4.2.5 + '@smithy/util-stream': 4.5.6 '@smithy/util-utf8': 4.2.0 '@smithy/uuid': 1.1.0 tslib: 2.8.1 - '@smithy/credential-provider-imds@4.2.3': + '@smithy/credential-provider-imds@4.2.5': dependencies: - '@smithy/node-config-provider': 4.3.3 - '@smithy/property-provider': 4.2.3 - '@smithy/types': 4.8.0 - '@smithy/url-parser': 4.2.3 + '@smithy/node-config-provider': 4.3.5 + '@smithy/property-provider': 4.2.5 + '@smithy/types': 4.9.0 + '@smithy/url-parser': 4.2.5 tslib: 2.8.1 - '@smithy/fetch-http-handler@5.3.4': + '@smithy/fetch-http-handler@5.3.6': dependencies: - '@smithy/protocol-http': 5.3.3 - '@smithy/querystring-builder': 4.2.3 - '@smithy/types': 4.8.0 + '@smithy/protocol-http': 5.3.5 + '@smithy/querystring-builder': 4.2.5 + '@smithy/types': 4.9.0 '@smithy/util-base64': 4.3.0 tslib: 2.8.1 - '@smithy/hash-node@4.2.3': + '@smithy/hash-node@4.2.5': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 '@smithy/util-buffer-from': 4.2.0 '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 - '@smithy/invalid-dependency@4.2.3': + '@smithy/invalid-dependency@4.2.5': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 '@smithy/is-array-buffer@2.2.0': @@ -17697,59 +17930,59 @@ snapshots: dependencies: tslib: 2.8.1 - '@smithy/middleware-content-length@4.2.3': + '@smithy/middleware-content-length@4.2.5': dependencies: - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 + '@smithy/protocol-http': 5.3.5 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@smithy/middleware-endpoint@4.3.4': + '@smithy/middleware-endpoint@4.3.12': dependencies: - '@smithy/core': 3.17.0 - '@smithy/middleware-serde': 4.2.3 - '@smithy/node-config-provider': 4.3.3 - '@smithy/shared-ini-file-loader': 4.3.3 - '@smithy/types': 4.8.0 - '@smithy/url-parser': 4.2.3 - '@smithy/util-middleware': 4.2.3 + '@smithy/core': 3.18.5 + '@smithy/middleware-serde': 4.2.6 + '@smithy/node-config-provider': 4.3.5 + '@smithy/shared-ini-file-loader': 4.4.0 + '@smithy/types': 4.9.0 + '@smithy/url-parser': 4.2.5 + '@smithy/util-middleware': 4.2.5 tslib: 2.8.1 - '@smithy/middleware-retry@4.4.4': + '@smithy/middleware-retry@4.4.12': dependencies: - '@smithy/node-config-provider': 4.3.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/service-error-classification': 4.2.3 - '@smithy/smithy-client': 4.9.0 - '@smithy/types': 4.8.0 - '@smithy/util-middleware': 4.2.3 - '@smithy/util-retry': 4.2.3 + '@smithy/node-config-provider': 4.3.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/service-error-classification': 4.2.5 + '@smithy/smithy-client': 4.9.8 + '@smithy/types': 4.9.0 + '@smithy/util-middleware': 4.2.5 + '@smithy/util-retry': 4.2.5 '@smithy/uuid': 1.1.0 tslib: 2.8.1 - '@smithy/middleware-serde@4.2.3': + '@smithy/middleware-serde@4.2.6': dependencies: - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 + '@smithy/protocol-http': 5.3.5 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@smithy/middleware-stack@4.2.3': + '@smithy/middleware-stack@4.2.5': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@smithy/node-config-provider@4.3.3': + '@smithy/node-config-provider@4.3.5': dependencies: - '@smithy/property-provider': 4.2.3 - '@smithy/shared-ini-file-loader': 4.3.3 - '@smithy/types': 4.8.0 + '@smithy/property-provider': 4.2.5 + '@smithy/shared-ini-file-loader': 4.4.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@smithy/node-http-handler@4.4.2': + '@smithy/node-http-handler@4.4.5': dependencies: - '@smithy/abort-controller': 4.2.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/querystring-builder': 4.2.3 - '@smithy/types': 4.8.0 + '@smithy/abort-controller': 4.2.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/querystring-builder': 4.2.5 + '@smithy/types': 4.9.0 tslib: 2.8.1 '@smithy/property-provider@3.1.11': @@ -17757,69 +17990,69 @@ snapshots: '@smithy/types': 3.7.2 tslib: 2.8.1 - '@smithy/property-provider@4.2.3': + '@smithy/property-provider@4.2.5': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@smithy/protocol-http@5.3.3': + '@smithy/protocol-http@5.3.5': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@smithy/querystring-builder@4.2.3': + '@smithy/querystring-builder@4.2.5': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 '@smithy/util-uri-escape': 4.2.0 tslib: 2.8.1 - '@smithy/querystring-parser@4.2.3': + '@smithy/querystring-parser@4.2.5': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@smithy/service-error-classification@4.2.3': + '@smithy/service-error-classification@4.2.5': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 - '@smithy/shared-ini-file-loader@4.3.3': + '@smithy/shared-ini-file-loader@4.4.0': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@smithy/signature-v4@5.3.3': + '@smithy/signature-v4@5.3.5': dependencies: '@smithy/is-array-buffer': 4.2.0 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 + '@smithy/protocol-http': 5.3.5 + '@smithy/types': 4.9.0 '@smithy/util-hex-encoding': 4.2.0 - '@smithy/util-middleware': 4.2.3 + '@smithy/util-middleware': 4.2.5 '@smithy/util-uri-escape': 4.2.0 '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 - '@smithy/smithy-client@4.9.0': + '@smithy/smithy-client@4.9.8': dependencies: - '@smithy/core': 3.17.0 - '@smithy/middleware-endpoint': 4.3.4 - '@smithy/middleware-stack': 4.2.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 - '@smithy/util-stream': 4.5.3 + '@smithy/core': 3.18.5 + '@smithy/middleware-endpoint': 4.3.12 + '@smithy/middleware-stack': 4.2.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/types': 4.9.0 + '@smithy/util-stream': 4.5.6 tslib: 2.8.1 '@smithy/types@3.7.2': dependencies: tslib: 2.8.1 - '@smithy/types@4.8.0': + '@smithy/types@4.9.0': dependencies: tslib: 2.8.1 - '@smithy/url-parser@4.2.3': + '@smithy/url-parser@4.2.5': dependencies: - '@smithy/querystring-parser': 4.2.3 - '@smithy/types': 4.8.0 + '@smithy/querystring-parser': 4.2.5 + '@smithy/types': 4.9.0 tslib: 2.8.1 '@smithy/util-base64@4.3.0': @@ -17850,49 +18083,49 @@ snapshots: dependencies: tslib: 2.8.1 - '@smithy/util-defaults-mode-browser@4.3.3': + '@smithy/util-defaults-mode-browser@4.3.11': dependencies: - '@smithy/property-provider': 4.2.3 - '@smithy/smithy-client': 4.9.0 - '@smithy/types': 4.8.0 + '@smithy/property-provider': 4.2.5 + '@smithy/smithy-client': 4.9.8 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@smithy/util-defaults-mode-node@4.2.4': + '@smithy/util-defaults-mode-node@4.2.14': dependencies: - '@smithy/config-resolver': 4.3.3 - '@smithy/credential-provider-imds': 4.2.3 - '@smithy/node-config-provider': 4.3.3 - '@smithy/property-provider': 4.2.3 - '@smithy/smithy-client': 4.9.0 - '@smithy/types': 4.8.0 + '@smithy/config-resolver': 4.4.3 + '@smithy/credential-provider-imds': 4.2.5 + '@smithy/node-config-provider': 4.3.5 + '@smithy/property-provider': 4.2.5 + '@smithy/smithy-client': 4.9.8 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@smithy/util-endpoints@3.2.3': + '@smithy/util-endpoints@3.2.5': dependencies: - '@smithy/node-config-provider': 4.3.3 - '@smithy/types': 4.8.0 + '@smithy/node-config-provider': 4.3.5 + '@smithy/types': 4.9.0 tslib: 2.8.1 '@smithy/util-hex-encoding@4.2.0': dependencies: tslib: 2.8.1 - '@smithy/util-middleware@4.2.3': + '@smithy/util-middleware@4.2.5': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@smithy/util-retry@4.2.3': + '@smithy/util-retry@4.2.5': dependencies: - '@smithy/service-error-classification': 4.2.3 - '@smithy/types': 4.8.0 + '@smithy/service-error-classification': 4.2.5 + '@smithy/types': 4.9.0 tslib: 2.8.1 - '@smithy/util-stream@4.5.3': + '@smithy/util-stream@4.5.6': dependencies: - '@smithy/fetch-http-handler': 5.3.4 - '@smithy/node-http-handler': 4.4.2 - '@smithy/types': 4.8.0 + '@smithy/fetch-http-handler': 5.3.6 + '@smithy/node-http-handler': 4.4.5 + '@smithy/types': 4.9.0 '@smithy/util-base64': 4.3.0 '@smithy/util-buffer-from': 4.2.0 '@smithy/util-hex-encoding': 4.2.0 @@ -17950,11 +18183,11 @@ snapshots: - rollup - supports-color - '@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': + '@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@standard-schema/spec': 1.0.0 '@sveltejs/acorn-typescript': 1.0.6(acorn@8.15.0) - '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) '@types/cookie': 0.6.0 acorn: 8.15.0 cookie: 0.6.0 @@ -17967,16 +18200,15 @@ snapshots: set-cookie-parser: 2.7.2 sirv: 3.0.2 svelte: 5.43.3 - vite: 6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) optionalDependencies: '@opentelemetry/api': 1.9.0 - optional: true - '@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': + '@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@standard-schema/spec': 1.0.0 '@sveltejs/acorn-typescript': 1.0.6(acorn@8.15.0) - '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.43.3)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) '@types/cookie': 0.6.0 acorn: 8.15.0 cookie: 0.6.0 @@ -17989,16 +18221,16 @@ snapshots: set-cookie-parser: 2.7.2 sirv: 3.0.2 svelte: 5.43.3 - vite: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) optionalDependencies: '@opentelemetry/api': 1.9.0 optional: true - '@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': + '@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@standard-schema/spec': 1.0.0 '@sveltejs/acorn-typescript': 1.0.6(acorn@8.15.0) - '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.43.3)(vite@7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) '@types/cookie': 0.6.0 acorn: 8.15.0 cookie: 0.6.0 @@ -18011,76 +18243,77 @@ snapshots: set-cookie-parser: 2.7.2 sirv: 3.0.2 svelte: 5.43.3 - vite: 7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) optionalDependencies: '@opentelemetry/api': 1.9.0 + optional: true - '@sveltejs/vite-plugin-svelte-inspector@5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': + '@sveltejs/vite-plugin-svelte-inspector@5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: - '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) debug: 4.4.3(supports-color@8.1.1) svelte: 5.43.3 - vite: 6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - supports-color - optional: true - '@sveltejs/vite-plugin-svelte-inspector@5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': + '@sveltejs/vite-plugin-svelte-inspector@5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: - '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.43.3)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) debug: 4.4.3(supports-color@8.1.1) svelte: 5.43.3 - vite: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - supports-color optional: true - '@sveltejs/vite-plugin-svelte-inspector@5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': + '@sveltejs/vite-plugin-svelte-inspector@5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: - '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.43.3)(vite@7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) debug: 4.4.3(supports-color@8.1.1) svelte: 5.43.3 - vite: 7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - supports-color + optional: true - '@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': + '@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + '@sveltejs/vite-plugin-svelte-inspector': 5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) debug: 4.4.3(supports-color@8.1.1) deepmerge: 4.3.1 magic-string: 0.30.21 svelte: 5.43.3 - vite: 6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) - vitefu: 1.1.1(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + vite: 7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vitefu: 1.1.1(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) transitivePeerDependencies: - supports-color - optional: true - '@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': + '@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + '@sveltejs/vite-plugin-svelte-inspector': 5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) debug: 4.4.3(supports-color@8.1.1) deepmerge: 4.3.1 magic-string: 0.30.21 svelte: 5.43.3 - vite: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) - vitefu: 1.1.1(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + vite: 7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vitefu: 1.1.1(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) transitivePeerDependencies: - supports-color optional: true - '@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': + '@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + '@sveltejs/vite-plugin-svelte-inspector': 5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) debug: 4.4.3(supports-color@8.1.1) deepmerge: 4.3.1 magic-string: 0.30.21 svelte: 5.43.3 - vite: 7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) - vitefu: 1.1.1(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + vite: 7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vitefu: 1.1.1(vite@7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) transitivePeerDependencies: - supports-color + optional: true '@svta/common-media-library@0.12.4': {} @@ -18114,7 +18347,7 @@ snapshots: '@swc/core-win32-x64-msvc@1.11.24': optional: true - '@swc/core@1.11.24': + '@swc/core@1.11.24(@swc/helpers@0.5.17)': dependencies: '@swc/counter': 0.1.3 '@swc/types': 0.1.23 @@ -18129,6 +18362,7 @@ snapshots: '@swc/core-win32-arm64-msvc': 1.11.24 '@swc/core-win32-ia32-msvc': 1.11.24 '@swc/core-win32-x64-msvc': 1.11.24 + '@swc/helpers': 0.5.17 '@swc/counter@0.1.3': {} @@ -18136,6 +18370,10 @@ snapshots: dependencies: tslib: 2.8.1 + '@swc/helpers@0.5.17': + dependencies: + tslib: 2.8.1 + '@swc/types@0.1.23': dependencies: '@swc/counter': 0.1.3 @@ -18225,13 +18463,13 @@ snapshots: dependencies: minimatch: 10.0.3 path-browserify: 1.0.1 - tinyglobby: 0.2.14 + tinyglobby: 0.2.15 '@ts-morph/common@0.28.1': dependencies: minimatch: 10.0.3 path-browserify: 1.0.1 - tinyglobby: 0.2.14 + tinyglobby: 0.2.15 '@tybys/wasm-util@0.10.1': dependencies: @@ -18410,7 +18648,7 @@ snapshots: '@types/fontkit@2.0.8': dependencies: - '@types/node': 24.6.2 + '@types/node': 22.19.0 '@types/fs-extra@11.0.4': dependencies: @@ -18521,7 +18759,7 @@ snapshots: '@types/ssh2-streams@0.1.12': dependencies: - '@types/node': 24.6.2 + '@types/node': 22.19.0 '@types/ssh2@0.5.52': dependencies: @@ -18548,7 +18786,7 @@ snapshots: '@types/yauzl@2.10.3': dependencies: - '@types/node': 24.6.2 + '@types/node': 22.19.0 optional: true '@typescript-eslint/project-service@8.46.4(typescript@5.9.3)': @@ -18595,18 +18833,18 @@ snapshots: unhead: 2.0.19 vue: 3.5.22(typescript@5.9.3) - '@vercel/analytics@1.5.0(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(next@16.0.3(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(svelte@5.43.3)(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))': + '@vercel/analytics@1.5.0(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(svelte@5.43.3)(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))': optionalDependencies: - '@sveltejs/kit': 2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + '@sveltejs/kit': 2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) next: 16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) react: 19.2.0 svelte: 5.43.3 vue: 3.5.22(typescript@5.9.3) vue-router: 4.6.3(vue@3.5.22(typescript@5.9.3)) - '@vercel/analytics@1.5.0(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(svelte@5.43.3)(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))': + '@vercel/analytics@1.5.0(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(next@16.0.3(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(svelte@5.43.3)(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))': optionalDependencies: - '@sveltejs/kit': 2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + '@sveltejs/kit': 2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) next: 16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) react: 19.2.0 svelte: 5.43.3 @@ -18727,9 +18965,9 @@ snapshots: optionalDependencies: ajv: 6.12.6 - '@vercel/speed-insights@1.2.0(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(svelte@5.43.3)(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))': + '@vercel/speed-insights@1.2.0(@sveltejs/kit@2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(svelte@5.43.3)(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))': optionalDependencies: - '@sveltejs/kit': 2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + '@sveltejs/kit': 2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) next: 16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) react: 19.2.0 svelte: 5.43.3 @@ -18741,22 +18979,22 @@ snapshots: native-promise-only: 0.8.1 weakmap-polyfill: 2.0.4 - '@vitejs/plugin-vue-jsx@5.1.1(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3))': + '@vitejs/plugin-vue-jsx@5.1.1(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3))': dependencies: '@babel/core': 7.28.4 '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.4) '@babel/plugin-transform-typescript': 7.28.0(@babel/core@7.28.4) '@rolldown/pluginutils': 1.0.0-beta.44 '@vue/babel-plugin-jsx': 1.5.0(@babel/core@7.28.4) - vite: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vue: 3.5.22(typescript@5.9.3) transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue@6.0.1(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3))': + '@vitejs/plugin-vue@6.0.1(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3))': dependencies: '@rolldown/pluginutils': 1.0.0-beta.29 - vite: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vue: 3.5.22(typescript@5.9.3) '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': @@ -18926,14 +19164,14 @@ snapshots: '@vue/devtools-api@6.6.4': {} - '@vue/devtools-core@7.7.7(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3))': + '@vue/devtools-core@7.7.7(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3))': dependencies: '@vue/devtools-kit': 7.7.7 '@vue/devtools-shared': 7.7.7 mitt: 3.0.1 nanoid: 5.1.6 pathe: 2.0.3 - vite-hot-client: 2.1.0(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + vite-hot-client: 2.1.0(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) vue: 3.5.22(typescript@5.9.3) transitivePeerDependencies: - vite @@ -19157,11 +19395,11 @@ snapshots: astring@1.9.0: {} - astro@5.15.6(@netlify/blobs@9.1.2)(@types/node@22.19.0)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1): + astro@5.16.0(@netlify/blobs@9.1.2)(@types/node@22.19.0)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1): dependencies: '@astrojs/compiler': 2.13.0 - '@astrojs/internal-helpers': 0.7.4 - '@astrojs/markdown-remark': 6.3.8 + '@astrojs/internal-helpers': 0.7.5 + '@astrojs/markdown-remark': 6.3.9 '@astrojs/telemetry': 3.3.0 '@capsizecss/unpack': 3.0.1 '@oslojs/encoding': 1.1.0 @@ -19175,7 +19413,7 @@ snapshots: common-ancestor-path: 1.0.1 cookie: 1.0.2 cssesc: 3.0.0 - debug: 4.4.3(supports-color@8.1.1) + debug: 4.4.3 deterministic-object-hash: 2.0.2 devalue: 5.5.0 diff: 5.2.0 @@ -19198,13 +19436,14 @@ snapshots: p-limit: 6.2.0 p-queue: 8.1.1 package-manager-detector: 1.5.0 - picocolors: 1.1.1 + piccolore: 0.1.3 picomatch: 4.0.3 prompts: 2.4.2 rehype: 13.0.2 semver: 7.7.3 shiki: 3.15.0 smol-toml: 1.5.2 + svgo: 4.0.0 tinyexec: 1.0.2 tinyglobby: 0.2.15 tsconfck: 3.1.6(typescript@5.9.3) @@ -19222,7 +19461,7 @@ snapshots: zod-to-json-schema: 3.25.0(zod@3.25.76) zod-to-ts: 1.2.0(typescript@5.9.3)(zod@3.25.76) optionalDependencies: - sharp: 0.34.4 + sharp: 0.34.5 transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -19324,7 +19563,7 @@ snapshots: zod-to-json-schema: 3.25.0(zod@3.25.76) zod-to-ts: 1.2.0(typescript@5.9.3)(zod@3.25.76) optionalDependencies: - sharp: 0.34.4 + sharp: 0.34.5 transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -20212,6 +20451,10 @@ snapshots: better-sqlite3: 11.10.0 drizzle-orm: 0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7) + debug@4.4.3: + dependencies: + ms: 2.1.3 + debug@4.4.3(supports-color@8.1.1): dependencies: ms: 2.1.3 @@ -20556,7 +20799,7 @@ snapshots: '@types/estree-jsx': 1.0.5 acorn: 8.15.0 esast-util-from-estree: 2.0.0 - vfile-message: 4.0.2 + vfile-message: 4.0.3 esbuild-register@3.6.0(esbuild@0.25.11): dependencies: @@ -20708,11 +20951,11 @@ snapshots: '@eslint-community/eslint-utils': 4.9.0(eslint@9.38.0(jiti@2.6.1)) '@eslint-community/regexpp': 4.12.2 '@eslint/config-array': 0.21.1 - '@eslint/config-helpers': 0.4.1 + '@eslint/config-helpers': 0.4.2 '@eslint/core': 0.16.0 '@eslint/eslintrc': 3.3.1 '@eslint/js': 9.38.0 - '@eslint/plugin-kit': 0.4.0 + '@eslint/plugin-kit': 0.4.1 '@humanfs/node': 0.16.7 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 @@ -21053,7 +21296,7 @@ snapshots: fontkit@2.0.4: dependencies: - '@swc/helpers': 0.5.15 + '@swc/helpers': 0.5.17 brotli: 1.3.3 clone: 2.1.2 dfa: 1.2.0 @@ -21168,7 +21411,7 @@ snapshots: transitivePeerDependencies: - supports-color - fumadocs-mdx@13.0.8(fumadocs-core@16.0.15(@types/react@19.1.13)(lucide-react@0.544.0(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): + fumadocs-mdx@13.0.8(fumadocs-core@16.0.15(@types/react@19.1.13)(lucide-react@0.544.0(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(next@16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): dependencies: '@mdx-js/mdx': 3.1.1 '@standard-schema/spec': 1.0.0 @@ -21191,7 +21434,7 @@ snapshots: optionalDependencies: next: 16.0.3(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) react: 19.2.0 - vite: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - supports-color @@ -21312,6 +21555,11 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 + get-tsconfig@4.13.0: + dependencies: + resolve-pkg-maps: 1.0.0 + optional: true + giget@2.0.0: dependencies: citty: 0.1.6 @@ -21401,7 +21649,7 @@ snapshots: gray-matter@4.0.3: dependencies: - js-yaml: 3.14.1 + js-yaml: 3.14.2 kind-of: 6.0.3 section-matter: 1.0.0 strip-bom-string: 1.0.0 @@ -21463,7 +21711,7 @@ snapshots: hast-util-from-parse5: 8.0.3 parse5: 7.3.0 vfile: 6.0.3 - vfile-message: 4.0.2 + vfile-message: 4.0.3 hast-util-from-parse5@8.0.3: dependencies: @@ -21721,7 +21969,7 @@ snapshots: dependencies: '@ioredis/commands': 1.4.0 cluster-key-slot: 1.1.2 - debug: 4.4.3(supports-color@8.1.1) + debug: 4.4.3 denque: 2.1.0 lodash.defaults: 4.2.0 lodash.isarguments: 3.1.0 @@ -21902,7 +22150,7 @@ snapshots: js-tokens@9.0.1: {} - js-yaml@3.14.1: + js-yaml@3.14.2: dependencies: argparse: 1.0.10 esprima: 4.0.1 @@ -22261,8 +22509,8 @@ snapshots: dependencies: '@types/mdast': 4.0.4 escape-string-regexp: 5.0.0 - unist-util-is: 6.0.0 - unist-util-visit-parents: 6.0.1 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 mdast-util-from-markdown@2.0.2: dependencies: @@ -22402,7 +22650,7 @@ snapshots: mdast-util-phrasing@4.1.0: dependencies: '@types/mdast': 4.0.4 - unist-util-is: 6.0.0 + unist-util-is: 6.0.1 mdast-util-to-hast@13.2.0: dependencies: @@ -22598,7 +22846,7 @@ snapshots: micromark-util-events-to-acorn: 2.0.3 micromark-util-symbol: 2.0.1 micromark-util-types: 2.0.2 - vfile-message: 4.0.2 + vfile-message: 4.0.3 micromark-extension-mdx-md@2.0.0: dependencies: @@ -22614,7 +22862,7 @@ snapshots: micromark-util-symbol: 2.0.1 micromark-util-types: 2.0.2 unist-util-position-from-estree: 2.0.0 - vfile-message: 4.0.2 + vfile-message: 4.0.3 micromark-extension-mdxjs@3.0.0: dependencies: @@ -22650,7 +22898,7 @@ snapshots: micromark-util-symbol: 2.0.1 micromark-util-types: 2.0.2 unist-util-position-from-estree: 2.0.0 - vfile-message: 4.0.2 + vfile-message: 4.0.3 micromark-factory-space@2.0.1: dependencies: @@ -22712,7 +22960,7 @@ snapshots: estree-util-visit: 2.0.0 micromark-util-symbol: 2.0.1 micromark-util-types: 2.0.2 - vfile-message: 4.0.2 + vfile-message: 4.0.3 micromark-util-html-tag-name@2.0.1: {} @@ -22744,7 +22992,7 @@ snapshots: micromark@4.0.2: dependencies: '@types/debug': 4.1.12 - debug: 4.4.3(supports-color@8.1.1) + debug: 4.4.3 decode-named-character-reference: 1.2.0 devlop: 1.1.0 micromark-core-commonmark: 2.0.3 @@ -22821,13 +23069,13 @@ snapshots: mkdirp@3.0.1: {} - mkdist@2.4.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.12)(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)): + mkdist@2.4.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.11)(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)): dependencies: autoprefixer: 10.4.21(postcss@8.5.6) citty: 0.1.6 cssnano: 7.1.1(postcss@8.5.6) defu: 6.1.4 - esbuild: 0.25.11 + esbuild: 0.25.12 jiti: 1.21.7 mlly: 1.8.0 pathe: 2.0.3 @@ -22839,7 +23087,7 @@ snapshots: optionalDependencies: typescript: 5.9.3 vue: 3.5.22(typescript@5.9.3) - vue-sfc-transformer: 0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.12)(vue@3.5.22(typescript@5.9.3)) + vue-sfc-transformer: 0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.11)(vue@3.5.22(typescript@5.9.3)) mlly@1.8.0: dependencies: @@ -23131,6 +23379,54 @@ snapshots: - sqlite3 - uploadthing + nitro@3.0.1-alpha.1(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(ioredis@5.8.2)(lru-cache@11.2.2)(rollup@4.53.3)(vite@7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): + dependencies: + consola: 3.4.2 + crossws: 0.4.1(srvx@0.9.6) + db0: 0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)) + h3: 2.0.1-rc.5(crossws@0.4.1(srvx@0.9.6)) + jiti: 2.6.1 + nf3: 0.1.12 + ofetch: 2.0.0-alpha.3 + ohash: 2.0.11 + oxc-minify: 0.96.0 + oxc-transform: 0.96.0 + srvx: 0.9.6 + undici: 7.16.0 + unenv: 2.0.0-rc.24 + unstorage: 2.0.0-alpha.4(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(chokidar@4.0.3)(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(lru-cache@11.2.2)(ofetch@2.0.0-alpha.3) + optionalDependencies: + rollup: 4.53.3 + vite: 7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@electric-sql/pglite' + - '@libsql/client' + - '@netlify/blobs' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - better-sqlite3 + - chokidar + - drizzle-orm + - idb-keyval + - ioredis + - lru-cache + - mongodb + - mysql2 + - sqlite3 + - uploadthing + nitropack@2.12.0(@netlify/blobs@9.1.2)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)): dependencies: '@cloudflare/kv-asset-handler': 0.4.0 @@ -23340,7 +23636,7 @@ snapshots: dependencies: '@types/nlcst': 2.0.3 - node-abi@3.78.0: + node-abi@3.85.0: dependencies: semver: 7.7.3 optional: true @@ -23406,11 +23702,11 @@ snapshots: dependencies: boolbase: 1.0.0 - nuxt@4.0.0(@biomejs/biome@2.3.3)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@22.19.0)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(@vue/compiler-sfc@3.5.22)(better-sqlite3@11.10.0)(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(yaml@2.8.1): + nuxt@4.0.0(@biomejs/biome@2.3.3)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@22.19.0)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(@vue/compiler-sfc@3.5.22)(better-sqlite3@11.10.0)(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(yaml@2.8.1): dependencies: '@nuxt/cli': 3.29.3(magicast@0.3.5) '@nuxt/devalue': 2.0.2 - '@nuxt/devtools': 2.6.5(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) + '@nuxt/devtools': 2.6.5(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) '@nuxt/kit': 4.0.0(magicast@0.3.5) '@nuxt/schema': 4.0.0 '@nuxt/telemetry': 2.6.6(magicast@0.3.5) @@ -23532,11 +23828,11 @@ snapshots: - xml2js - yaml - nuxt@4.1.3(@biomejs/biome@2.3.3)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@22.19.0)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(@vue/compiler-sfc@3.5.22)(better-sqlite3@11.10.0)(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(yaml@2.8.1): + nuxt@4.1.3(@biomejs/biome@2.3.3)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@22.19.0)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(@vue/compiler-sfc@3.5.22)(better-sqlite3@11.10.0)(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7))(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(yaml@2.8.1): dependencies: '@nuxt/cli': 3.29.3(magicast@0.3.5) '@nuxt/devalue': 2.0.2 - '@nuxt/devtools': 2.6.5(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) + '@nuxt/devtools': 2.6.5(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) '@nuxt/kit': 4.1.3(magicast@0.3.5) '@nuxt/schema': 4.1.3 '@nuxt/telemetry': 2.6.6(magicast@0.3.5) @@ -23664,7 +23960,7 @@ snapshots: consola: 3.4.2 pathe: 2.0.3 pkg-types: 2.3.0 - tinyexec: 1.0.1 + tinyexec: 1.0.2 object-assign@4.1.1: {} @@ -23732,6 +24028,12 @@ snapshots: regex: 6.0.1 regex-recursion: 6.0.2 + oniguruma-to-es@4.3.4: + dependencies: + oniguruma-parser: 0.12.1 + regex: 6.0.1 + regex-recursion: 6.0.2 + open@10.2.0: dependencies: default-browser: 5.2.1 @@ -23966,11 +24268,11 @@ snapshots: p-limit@4.0.0: dependencies: - yocto-queue: 1.2.1 + yocto-queue: 1.2.2 p-limit@6.2.0: dependencies: - yocto-queue: 1.2.1 + yocto-queue: 1.2.2 p-locate@4.1.0: dependencies: @@ -24394,7 +24696,7 @@ snapshots: minimist: 1.2.8 mkdirp-classic: 0.5.3 napi-build-utils: 2.0.0 - node-abi: 3.78.0 + node-abi: 3.85.0 pump: 3.0.3 rc: 1.2.8 simple-get: 4.0.1 @@ -24787,7 +25089,7 @@ snapshots: read-yaml-file@1.1.0: dependencies: graceful-fs: 4.2.11 - js-yaml: 3.14.1 + js-yaml: 3.14.2 pify: 4.0.1 strip-bom: 3.0.0 @@ -25006,7 +25308,7 @@ snapshots: dependencies: debug: 4.4.3(supports-color@8.1.1) module-details-from-path: 1.0.4 - resolve: 1.22.10 + resolve: 1.22.11 transitivePeerDependencies: - supports-color @@ -25024,6 +25326,12 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + resolve@1.22.11: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + resolve@2.0.0-next.5: dependencies: is-core-module: 2.16.1 @@ -25195,6 +25503,8 @@ snapshots: sax@1.4.1: {} + sax@1.4.3: {} + scheduler@0.26.0: {} scheduler@0.27.0: {} @@ -25291,6 +25601,38 @@ snapshots: '@img/sharp-win32-x64': 0.34.4 optional: true + sharp@0.34.5: + dependencies: + '@img/colour': 1.0.0 + detect-libc: 2.1.2 + semver: 7.7.3 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.34.5 + '@img/sharp-darwin-x64': 0.34.5 + '@img/sharp-libvips-darwin-arm64': 1.2.4 + '@img/sharp-libvips-darwin-x64': 1.2.4 + '@img/sharp-libvips-linux-arm': 1.2.4 + '@img/sharp-libvips-linux-arm64': 1.2.4 + '@img/sharp-libvips-linux-ppc64': 1.2.4 + '@img/sharp-libvips-linux-riscv64': 1.2.4 + '@img/sharp-libvips-linux-s390x': 1.2.4 + '@img/sharp-libvips-linux-x64': 1.2.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + '@img/sharp-linux-arm': 0.34.5 + '@img/sharp-linux-arm64': 0.34.5 + '@img/sharp-linux-ppc64': 0.34.5 + '@img/sharp-linux-riscv64': 0.34.5 + '@img/sharp-linux-s390x': 0.34.5 + '@img/sharp-linux-x64': 0.34.5 + '@img/sharp-linuxmusl-arm64': 0.34.5 + '@img/sharp-linuxmusl-x64': 0.34.5 + '@img/sharp-wasm32': 0.34.5 + '@img/sharp-win32-arm64': 0.34.5 + '@img/sharp-win32-ia32': 0.34.5 + '@img/sharp-win32-x64': 0.34.5 + optional: true + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -25673,7 +26015,7 @@ snapshots: css-what: 6.2.2 csso: 5.0.5 picocolors: 1.1.1 - sax: 1.4.1 + sax: 1.4.3 swr@2.3.6(react@19.1.0): dependencies: @@ -25813,8 +26155,6 @@ snapshots: tinyexec@0.3.2: {} - tinyexec@1.0.1: {} - tinyexec@1.0.2: {} tinyglobby@0.2.14: @@ -25888,7 +26228,7 @@ snapshots: tsx@4.20.6: dependencies: esbuild: 0.25.12 - get-tsconfig: 4.12.0 + get-tsconfig: 4.13.0 optionalDependencies: fsevents: 2.3.3 optional: true @@ -25964,7 +26304,7 @@ snapshots: ultrahtml@1.6.0: {} - unbuild@3.6.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.12)(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)): + unbuild@3.6.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.11)(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)): dependencies: '@rollup/plugin-alias': 5.1.1(rollup@4.53.3) '@rollup/plugin-commonjs': 28.0.9(rollup@4.53.3) @@ -25975,12 +26315,12 @@ snapshots: citty: 0.1.6 consola: 3.4.2 defu: 6.1.4 - esbuild: 0.25.11 + esbuild: 0.25.12 fix-dts-default-cjs-exports: 1.0.1 hookable: 5.5.3 jiti: 2.6.1 magic-string: 0.30.21 - mkdist: 2.4.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.12)(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) + mkdist: 2.4.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.11)(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) mlly: 1.8.0 pathe: 2.0.3 pkg-types: 2.3.0 @@ -25988,7 +26328,7 @@ snapshots: rollup: 4.53.3 rollup-plugin-dts: 6.2.3(rollup@4.53.3)(typescript@5.9.3) scule: 1.3.0 - tinyglobby: 0.2.14 + tinyglobby: 0.2.15 untyped: 2.0.0 optionalDependencies: typescript: 5.9.3 @@ -26083,9 +26423,9 @@ snapshots: unist-util-find-after@5.0.0: dependencies: '@types/unist': 3.0.3 - unist-util-is: 6.0.0 + unist-util-is: 6.0.1 - unist-util-is@6.0.0: + unist-util-is@6.0.1: dependencies: '@types/unist': 3.0.3 @@ -26118,18 +26458,18 @@ snapshots: unist-util-visit-parents@6.0.1: dependencies: '@types/unist': 3.0.3 - unist-util-is: 6.0.0 + unist-util-is: 6.0.1 unist-util-visit-parents@6.0.2: dependencies: '@types/unist': 3.0.3 - unist-util-is: 6.0.0 + unist-util-is: 6.0.1 unist-util-visit@5.0.0: dependencies: '@types/unist': 3.0.3 - unist-util-is: 6.0.0 - unist-util-visit-parents: 6.0.1 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 universal-github-app-jwt@2.2.2: {} @@ -26186,13 +26526,13 @@ snapshots: chokidar: 4.0.3 json5: 2.2.3 local-pkg: 1.1.2 - magic-string: 0.30.21 + magic-string: 0.30.19 mlly: 1.8.0 muggle-string: 0.4.1 pathe: 2.0.3 picomatch: 4.0.3 scule: 1.3.0 - tinyglobby: 0.2.14 + tinyglobby: 0.2.15 unplugin: 2.3.10 unplugin-utils: 0.2.5 yaml: 2.8.0 @@ -26268,7 +26608,7 @@ snapshots: unwasm@0.3.11: dependencies: knitwork: 1.2.0 - magic-string: 0.30.21 + magic-string: 0.30.19 mlly: 1.8.0 pathe: 2.0.3 pkg-types: 2.3.0 @@ -26369,10 +26709,15 @@ snapshots: '@types/unist': 3.0.3 unist-util-stringify-position: 4.0.0 + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + vfile@6.0.3: dependencies: '@types/unist': 3.0.3 - vfile-message: 4.0.2 + vfile-message: 4.0.3 victory-vendor@36.9.2: dependencies: @@ -26395,15 +26740,15 @@ snapshots: dependencies: '@vimeo/player': 2.29.0 - vite-dev-rpc@1.1.0(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): + vite-dev-rpc@1.1.0(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): dependencies: birpc: 2.6.1 - vite: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) - vite-hot-client: 2.1.0(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + vite: 7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite-hot-client: 2.1.0(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) - vite-hot-client@2.1.0(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): + vite-hot-client@2.1.0(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): dependencies: - vite: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vite-node@3.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): dependencies: @@ -26447,7 +26792,7 @@ snapshots: - tsx - yaml - vite-plugin-checker@0.10.3(@biomejs/biome@2.3.3)(eslint@9.38.0(jiti@2.6.1))(optionator@0.9.4)(typescript@5.9.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): + vite-plugin-checker@0.10.3(@biomejs/biome@2.3.3)(eslint@9.38.0(jiti@2.6.1))(optionator@0.9.4)(typescript@5.9.3)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): dependencies: '@babel/code-frame': 7.27.1 chokidar: 4.0.3 @@ -26457,7 +26802,7 @@ snapshots: strip-ansi: 7.1.0 tiny-invariant: 1.3.3 tinyglobby: 0.2.14 - vite: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vscode-uri: 3.1.0 optionalDependencies: '@biomejs/biome': 2.3.3 @@ -26465,7 +26810,7 @@ snapshots: optionator: 0.9.4 typescript: 5.9.3 - vite-plugin-checker@0.11.0(@biomejs/biome@2.3.3)(eslint@9.38.0(jiti@2.6.1))(optionator@0.9.4)(typescript@5.9.3)(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): + vite-plugin-checker@0.11.0(@biomejs/biome@2.3.3)(eslint@9.38.0(jiti@2.6.1))(optionator@0.9.4)(typescript@5.9.3)(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): dependencies: '@babel/code-frame': 7.27.1 chokidar: 4.0.3 @@ -26473,8 +26818,8 @@ snapshots: picocolors: 1.1.1 picomatch: 4.0.3 tiny-invariant: 1.3.3 - tinyglobby: 0.2.14 - vite: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + tinyglobby: 0.2.15 + vite: 7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vscode-uri: 3.1.0 optionalDependencies: '@biomejs/biome': 2.3.3 @@ -26487,7 +26832,7 @@ snapshots: uuid: 11.1.0 vite: 7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) - vite-plugin-inspect@11.3.3(@nuxt/kit@3.19.3(magicast@0.3.5))(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): + vite-plugin-inspect@11.3.3(@nuxt/kit@3.19.3(magicast@0.3.5))(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): dependencies: ansis: 4.2.0 debug: 4.4.3(supports-color@8.1.1) @@ -26497,21 +26842,21 @@ snapshots: perfect-debounce: 2.0.0 sirv: 3.0.2 unplugin-utils: 0.3.1 - vite: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) - vite-dev-rpc: 1.1.0(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + vite: 7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite-dev-rpc: 1.1.0(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) optionalDependencies: '@nuxt/kit': 3.19.3(magicast@0.3.5) transitivePeerDependencies: - supports-color - vite-plugin-vue-tracer@1.0.1(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)): + vite-plugin-vue-tracer@1.0.1(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)): dependencies: estree-walker: 3.0.3 exsolve: 1.0.7 magic-string: 0.30.21 pathe: 2.0.3 source-map-js: 1.2.1 - vite: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vue: 3.5.22(typescript@5.9.3) vite@6.4.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): @@ -26521,7 +26866,7 @@ snapshots: picomatch: 4.0.3 postcss: 8.5.6 rollup: 4.53.3 - tinyglobby: 0.2.14 + tinyglobby: 0.2.15 optionalDependencies: '@types/node': 22.19.0 fsevents: 2.3.3 @@ -26538,7 +26883,7 @@ snapshots: picomatch: 4.0.3 postcss: 8.5.6 rollup: 4.53.3 - tinyglobby: 0.2.14 + tinyglobby: 0.2.15 optionalDependencies: '@types/node': 24.6.2 fsevents: 2.3.3 @@ -26599,6 +26944,41 @@ snapshots: tsx: 4.20.6 yaml: 2.8.1 + vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): + dependencies: + esbuild: 0.25.11 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.53.3 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 22.19.0 + fsevents: 2.3.3 + jiti: 2.6.1 + lightningcss: 1.30.1 + terser: 5.44.0 + tsx: 4.20.6 + yaml: 2.8.1 + + vite@7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): + dependencies: + esbuild: 0.25.11 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.53.3 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 24.6.2 + fsevents: 2.3.3 + jiti: 2.6.1 + lightningcss: 1.30.1 + terser: 5.44.0 + tsx: 4.20.6 + yaml: 2.8.1 + optional: true + vitefu@1.1.1(vite@6.4.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): optionalDependencies: vite: 6.4.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) @@ -26607,14 +26987,19 @@ snapshots: optionalDependencies: vite: 6.4.1(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) - vitefu@1.1.1(vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): + vitefu@1.1.1(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): optionalDependencies: - vite: 7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + + vitefu@1.1.1(vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): + optionalDependencies: + vite: 7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) optional: true - vitefu@1.1.1(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): + vitefu@1.1.1(vite@7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): optionalDependencies: - vite: 7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + optional: true vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): dependencies: @@ -26730,11 +27115,11 @@ snapshots: '@vue/devtools-api': 6.6.4 vue: 3.5.22(typescript@5.9.3) - vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.12)(vue@3.5.22(typescript@5.9.3)): + vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.11)(vue@3.5.22(typescript@5.9.3)): dependencies: '@babel/parser': 7.28.5 '@vue/compiler-core': 3.5.22 - esbuild: 0.25.12 + esbuild: 0.25.11 vue: 3.5.22(typescript@5.9.3) vue@3.5.22(typescript@5.9.3): @@ -26901,7 +27286,7 @@ snapshots: yocto-queue@0.1.0: optional: true - yocto-queue@1.2.1: {} + yocto-queue@1.2.2: {} yocto-spinner@0.2.3: dependencies: From d0748c89f75c29cfb829885aa80dbcfcf3c7944d Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 21 Nov 2025 10:01:42 -0800 Subject: [PATCH 48/61] revert docs frameworks page From 09ac372710ae221515dcde26e669c91cc7d8c634 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 21 Nov 2025 10:02:44 -0800 Subject: [PATCH 49/61] format --- packages/core/src/runtime/resume-hook.ts | 46 ++++++++++++------------ 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/packages/core/src/runtime/resume-hook.ts b/packages/core/src/runtime/resume-hook.ts index a0eeb8bf4..9ae5146b8 100644 --- a/packages/core/src/runtime/resume-hook.ts +++ b/packages/core/src/runtime/resume-hook.ts @@ -1,16 +1,16 @@ -import { waitUntil } from "@vercel/functions"; -import { ERROR_SLUGS, WorkflowRuntimeError } from "@workflow/errors"; -import type { Hook } from "@workflow/world"; -import type { WorkflowInvokePayload } from "../schemas.js"; +import { waitUntil } from '@vercel/functions'; +import { ERROR_SLUGS, WorkflowRuntimeError } from '@workflow/errors'; +import type { Hook } from '@workflow/world'; +import type { WorkflowInvokePayload } from '../schemas.js'; import { dehydrateStepReturnValue, hydrateStepArguments, -} from "../serialization.js"; -import { WEBHOOK_RESPONSE_WRITABLE } from "../symbols.js"; -import * as Attribute from "../telemetry/semantic-conventions.js"; -import { getSpanContextForTraceCarrier, trace } from "../telemetry.js"; -import { waitedUntil } from "../util.js"; -import { getWorld } from "./world.js"; +} from '../serialization.js'; +import { WEBHOOK_RESPONSE_WRITABLE } from '../symbols.js'; +import * as Attribute from '../telemetry/semantic-conventions.js'; +import { getSpanContextForTraceCarrier, trace } from '../telemetry.js'; +import { waitedUntil } from '../util.js'; +import { getWorld } from './world.js'; /** * Get the hook by token to find the associated workflow run, @@ -22,7 +22,7 @@ import { getWorld } from "./world.js"; export async function getHookByToken(token: string): Promise { const world = getWorld(); const hook = await world.hooks.getByToken(token); - if (typeof hook.metadata !== "undefined") { + if (typeof hook.metadata !== 'undefined') { hook.metadata = hydrateStepArguments(hook.metadata as any, [], hook.runId); } return hook; @@ -59,10 +59,10 @@ export async function getHookByToken(token: string): Promise { */ export async function resumeHook( token: string, - payload: T, + payload: T ): Promise { return await waitedUntil(() => { - return trace("HOOK.resume", async (span) => { + return trace('HOOK.resume', async (span) => { const world = getWorld(); try { @@ -79,18 +79,18 @@ export async function resumeHook( const dehydratedPayload = dehydrateStepReturnValue( payload, ops, - hook.runId, + hook.runId ); // NOTE: Workaround instead of injecting catching undefined unhandled rejections in webhook bundle waitUntil( Promise.all(ops).catch((err) => { if (err !== undefined) throw err; - }), + }) ); // Create a hook_received event with the payload await world.events.create(hook.runId, { - eventType: "hook_received", + eventType: 'hook_received', correlationId: hook.hookId, eventData: { payload: dehydratedPayload, @@ -124,7 +124,7 @@ export async function resumeHook( } satisfies WorkflowInvokePayload, { deploymentId: workflowRun.deploymentId, - }, + } ); return hook; @@ -176,7 +176,7 @@ export async function resumeHook( */ export async function resumeWebhook( token: string, - request: Request, + request: Request ): Promise { const hook = await getHookByToken(token); @@ -184,10 +184,10 @@ export async function resumeWebhook( let responseReadable: ReadableStream | undefined; if ( hook.metadata && - typeof hook.metadata === "object" && - "respondWith" in hook.metadata + typeof hook.metadata === 'object' && + 'respondWith' in hook.metadata ) { - if (hook.metadata.respondWith === "manual") { + if (hook.metadata.respondWith === 'manual') { const { readable, writable } = new TransformStream(); responseReadable = readable; @@ -199,7 +199,7 @@ export async function resumeWebhook( } else { throw new WorkflowRuntimeError( `Invalid \`respondWith\` value: ${hook.metadata.respondWith}`, - { slug: ERROR_SLUGS.WEBHOOK_INVALID_RESPOND_WITH_VALUE }, + { slug: ERROR_SLUGS.WEBHOOK_INVALID_RESPOND_WITH_VALUE } ); } } else { @@ -221,7 +221,7 @@ export async function resumeWebhook( } if (!response) { - throw new WorkflowRuntimeError("Workflow run did not send a response", { + throw new WorkflowRuntimeError('Workflow run did not send a response', { slug: ERROR_SLUGS.WEBHOOK_RESPONSE_NOT_SENT, }); } From 6e75c8092c7717d868caa85d7579871fe3f204f4 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 21 Nov 2025 10:51:52 -0800 Subject: [PATCH 50/61] docs: update supported frameworks and index --- docs/app/(home)/components/frameworks.tsx | 167 +++++++++++--------- docs/content/docs/getting-started/index.mdx | 31 ++-- 2 files changed, 113 insertions(+), 85 deletions(-) diff --git a/docs/app/(home)/components/frameworks.tsx b/docs/app/(home)/components/frameworks.tsx index 041871417..6d47cc91b 100644 --- a/docs/app/(home)/components/frameworks.tsx +++ b/docs/app/(home)/components/frameworks.tsx @@ -30,7 +30,8 @@ export const AstroDark = (props: ComponentProps<'svg'>) => ( xmlns="http://www.w3.org/2000/svg" {...props} > - + Astro + ) => ( y2="84.9468" gradientUnits="userSpaceOnUse" > - - + + @@ -70,7 +71,8 @@ export const AstroLight = (props: ComponentProps<'svg'>) => ( xmlns="http://www.w3.org/2000/svg" {...props} > - + Astro + ) => ( xmlns="http://www.w3.org/2000/svg" {...props} > - + Astro + ) => ( xmlns="http://www.w3.org/2000/svg" {...props} > - + TanStack + ) => ( > ); @@ -695,72 +699,93 @@ export const Frameworks = () => { with the frameworks you already use with more coming soon.
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + Coming soon + +
+
handleRequest('NestJS')} + > + + +
+
handleRequest('TanStack')} > - Coming soon - - - Click on a framework to request support for it - - - Click a framework to request support - + + +
-
-
handleRequest('NestJS')} - > - - -
-
handleRequest('TanStack')} - > - - -
-
handleRequest('Astro')} - > - - - +

+ Click a framework to request support for it +

diff --git a/docs/content/docs/getting-started/index.mdx b/docs/content/docs/getting-started/index.mdx index 11a399aea..7f52fd3b3 100644 --- a/docs/content/docs/getting-started/index.mdx +++ b/docs/content/docs/getting-started/index.mdx @@ -3,56 +3,59 @@ title: Getting Started description: Start by choosing your framework. Each guide will walk you through the steps to install the dependencies and start running your first workflow. --- -import { Next, Nitro, SvelteKit, Nuxt, Hono, Bun, AstroDark, AstroLight, TanStack, Vite, Express } from '@/app/(home)/components/frameworks'; +import { Next, Nitro, SvelteKit, Nuxt, Hono, Bun, AstroDark, AstroLight, TanStack, Vite, Express, Nest } from '@/app/(home)/components/frameworks'; -
- - Next.js -
+
Next.js
-
+
Vite
+ +
+ + + Astro +
+
-
+
Express
-
+
Hono
-
+
Nitro
-
+
Nuxt
-
+
SvelteKit
- - - Astro + + NestJS Coming soon
From 674700679dd27d9d5344d13b80ce75d35c088de9 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 21 Nov 2025 11:25:23 -0800 Subject: [PATCH 51/61] docs: add astro getting started --- docs/content/docs/getting-started/astro.mdx | 233 ++++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 docs/content/docs/getting-started/astro.mdx diff --git a/docs/content/docs/getting-started/astro.mdx b/docs/content/docs/getting-started/astro.mdx new file mode 100644 index 000000000..459d2b84a --- /dev/null +++ b/docs/content/docs/getting-started/astro.mdx @@ -0,0 +1,233 @@ +--- +title: Astro +--- + +This guide will walk through setting up your first workflow in an Astro app. Along the way, you'll learn more about the concepts that are fundamental to using the development kit in your own projects. + +--- + + + + +## Create Your Astro Project + +Start by creating a new Astro project. This command will create a new directory named `my-workflow-app` and setup a minimal Astro project inside it. + +```bash +npm create astro@latest my-workflow-app -- --template minimal --install --yes +``` + +Enter the newly made directory: + +```bash +cd my-workflow-app +``` + +### Install `workflow` + +```package-install +npm i workflow +``` + +### Configure Astro + +Add `workflow()` to your Astro config. This enables usage of the `"use workflow"` and `"use step"` directives. + +```typescript title="astro.config.mjs" lineNumbers +// @ts-check +import { defineConfig } from "astro/config"; +import { workflow } from "workflow/astro"; + +// https://astro.build/config +export default defineConfig({ + integrations: [workflow()], +}); +``` + + + + + ### Setup IntelliSense for TypeScript (Optional) + + + +To enable helpful hints in your IDE, setup the workflow plugin in `tsconfig.json`: + +```json title="tsconfig.json" lineNumbers +{ + "compilerOptions": { + // ... rest of your TypeScript config + "plugins": [ + { + "name": "workflow" // [!code highlight] + } + ] + } +} +``` + + + + + + + + + +## Create Your First Workflow + +Create a new file for our first workflow: + +```typescript title="src/workflows/user-signup.ts" lineNumbers +import { sleep } from "workflow"; + +export async function handleUserSignup(email: string) { + "use workflow"; // [!code highlight] + + const user = await createUser(email); + await sendWelcomeEmail(user); + + await sleep("5s"); // Pause for 5s - doesn't consume any resources + await sendOnboardingEmail(user); + + return { userId: user.id, status: "onboarded" }; +} + +``` + +We'll fill in those functions next, but let's take a look at this code: + +* We define a **workflow** function with the directive `"use workflow"`. Think of the workflow function as the _orchestrator_ of individual **steps**. +* The Workflow DevKit's `sleep` function allows us to suspend execution of the workflow without using up any resources. A sleep can be a few seconds, hours, days, or even months long. + +## Create Your Workflow Steps + +Let's now define those missing functions. + +```typescript title="src/workflows/user-signup.ts" lineNumbers +import { FatalError } from "workflow" + +// Our workflow function defined earlier + +async function createUser(email: string) { + "use step"; // [!code highlight] + + console.log(`Creating user with email: ${email}`); + + // Full Node.js access - database calls, APIs, etc. + return { id: crypto.randomUUID(), email }; +} + +async function sendWelcomeEmail(user: { id: string; email: string; }) { + "use step"; // [!code highlight] + + console.log(`Sending welcome email to user: ${user.id}`); + + if (Math.random() < 0.3) { + // By default, steps will be retried for unhandled errors + throw new Error("Retryable!"); + } +} + +async function sendOnboardingEmail(user: { id: string; email: string}) { + "use step"; // [!code highlight] + + if (!user.email.includes("@")) { + // To skip retrying, throw a FatalError instead + throw new FatalError("Invalid Email"); + } + + console.log(`Sending onboarding email to user: ${user.id}`); +} +``` + +Taking a look at this code: + +* Business logic lives inside **steps**. When a step is invoked inside a **workflow**, it gets enqueued to run on a separate request while the workflow is suspended, just like `sleep`. +* If a step throws an error, like in `sendWelcomeEmail`, the step will automatically be retried until it succeeds (or hits the step's max retry count). +* Steps can throw a `FatalError` if an error is intentional and should not be retried. + + +We'll dive deeper into workflows, steps, and other ways to suspend or handle events in [Foundations](/docs/foundations). + + + + + + +## Create Your Route Handler + +To invoke your new workflow, we'll have to add your workflow to a `POST` API route handler, `src/pages/api/signup.ts` with the following code: + +```typescript title="src/pages/api/signup.ts" +import type { APIRoute } from "astro"; +import { start } from "workflow/api"; +import { handleUserSignup } from "../../workflows/user-signup"; + +export const POST: APIRoute = async ({ request }: { request: Request }) => { + const { email } = await request.json(); + + // Executes asynchronously and doesn't block your app + await start(handleUserSignup, [email]); + return Response.json({ + message: "User signup workflow started", + }); +}; + +export const prerender = false; // Don't prerender this page since it's an API route +``` + +This route handler creates a `POST` request endpoint at `/api/signup` that will trigger your workflow. + + +Workflows can be triggered from API routes or any server-side code. + + + + + + +## Run in Development + +To start your development server, run the following command in your terminal in the Vite root directory: + +```bash +npm run dev +``` + +Once your development server is running, you can trigger your workflow by running this command in the terminal: + +```bash +curl -X POST --json '{"email":"hello@example.com"}' http://localhost:5173/api/signup +``` + +Check the Astro development server logs to see your workflow execute as well as the steps that are being processed. + +Additionally, you can use the [Workflow DevKit CLI or Web UI](/docs/observability) to inspect your workflow runs and steps in detail. + +```bash +npx workflow inspect runs +# or add '--web' for an interactive Web based UI +``` + +Workflow DevKit Web UI + +--- + +## Deploying to Production + +Workflow DevKit apps currently work best when deployed to [Vercel](https://vercel.com/home) and needs no special configuration. + +To deploy your Astro project to Vercel, ensure that the [Astro Vercel adapter](https://docs.astro.build/en/guides/integrations-guide/vercel) is configured: + +```bash +npx astro add vercel +``` + +Additionally, check the [Deploying](/docs/deploying) section to learn how your workflows can be deployed elsewhere. + +## Next Steps + +* Learn more about the [Foundations](/docs/foundations). +* Check [Errors](/docs/errors) if you encounter issues. +* Explore the [API Reference](/docs/api-reference). From 14a0da7d38bb17c9a16490c5bdec8fcbb02d5fb2 Mon Sep 17 00:00:00 2001 From: Adrian Date: Fri, 21 Nov 2025 11:31:13 -0800 Subject: [PATCH 52/61] Update packages/astro/src/builder.ts Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com> --- packages/astro/src/builder.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/astro/src/builder.ts b/packages/astro/src/builder.ts index 76769f039..cae059d52 100644 --- a/packages/astro/src/builder.ts +++ b/packages/astro/src/builder.ts @@ -86,7 +86,15 @@ export class LocalBuilder extends BaseBuilder { for (const file of DEBUG_FILES) { const filePath = join(workflowGeneratedDir, file); const prefixedFilePath = join(workflowGeneratedDir, `_${file}`); - await rename(filePath, prefixedFilePath); + try { + await rename(filePath, prefixedFilePath); + } catch (error: unknown) { + // Silently ignore if debug file doesn't exist + // (writeDebugFile may have silently failed due to filesystem errors) + if ((error as NodeJS.ErrnoException).code !== 'ENOENT') { + throw error; + } + } } } From 6b3bfe588b8ee52041cebf11485c18abe9613d34 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 21 Nov 2025 12:14:59 -0800 Subject: [PATCH 53/61] test: add astro dev test workflowsDir --- scripts/create-test-matrix.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/create-test-matrix.mjs b/scripts/create-test-matrix.mjs index ab1cb9e04..fb07f268c 100644 --- a/scripts/create-test-matrix.mjs +++ b/scripts/create-test-matrix.mjs @@ -54,6 +54,7 @@ const DEV_TEST_CONFIGS = { generatedWorkflowPath: 'src/pages/.well-known/workflow/v1/flow.js', apiFilePath: 'src/pages/api/chat.ts', apiFileImportPath: '../..', + workflowsDir: 'src/workflows', }, }; From 9d49861f48220297f27a967e2c6c3cce3537a75a Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 21 Nov 2025 12:15:31 -0800 Subject: [PATCH 54/61] fix: update base builder to accept debug prefix --- packages/astro/package.json | 3 +-- packages/astro/src/builder.ts | 25 +++---------------------- packages/astro/src/plugin.ts | 13 +++++++------ packages/builders/src/base-builder.ts | 9 ++++++--- packages/builders/src/types.ts | 3 +++ 5 files changed, 20 insertions(+), 33 deletions(-) diff --git a/packages/astro/package.json b/packages/astro/package.json index 657e4596f..dfd49b7ce 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -34,7 +34,6 @@ "devDependencies": { "@types/node": "catalog:", "@workflow/tsconfig": "workspace:*", - "astro": "5.16.0", - "vite": "7.1.11" + "astro": "5.16.0" } } diff --git a/packages/astro/src/builder.ts b/packages/astro/src/builder.ts index cae059d52..94f9852df 100644 --- a/packages/astro/src/builder.ts +++ b/packages/astro/src/builder.ts @@ -1,4 +1,4 @@ -import { mkdir, readFile, rename, writeFile } from 'node:fs/promises'; +import { mkdir, readFile, writeFile } from 'node:fs/promises'; import { join, resolve } from 'node:path'; import { BaseBuilder, @@ -21,12 +21,6 @@ async function normalizeRequestConverter(request) { } `; -const DEBUG_FILES = [ - 'flow.js.debug.json', - 'manifest.debug.json', - 'step.js.debug.json', -]; - const WORKFLOW_ROUTES = [ { src: '^/\\.well-known/workflow/v1/flow/?$', @@ -51,6 +45,7 @@ export class LocalBuilder extends BaseBuilder { workflowsBundlePath: '', // unused in base webhookBundlePath: '', // unused in base workingDir: process.cwd(), + debugFilePrefix: '_', // Prefix with underscore so Astro ignores debug files }); } @@ -81,21 +76,6 @@ export class LocalBuilder extends BaseBuilder { await this.buildStepsRoute(options); await this.buildWorkflowsRoute(options); await this.buildWebhookRoute({ workflowGeneratedDir }); - - // Astro requires non-api routes to be prefixed with _ (debug files) - for (const file of DEBUG_FILES) { - const filePath = join(workflowGeneratedDir, file); - const prefixedFilePath = join(workflowGeneratedDir, `_${file}`); - try { - await rename(filePath, prefixedFilePath); - } catch (error: unknown) { - // Silently ignore if debug file doesn't exist - // (writeDebugFile may have silently failed due to filesystem errors) - if ((error as NodeJS.ErrnoException).code !== 'ENOENT') { - throw error; - } - } - } } private async buildStepsRoute({ @@ -236,6 +216,7 @@ export class VercelBuilder extends VercelBuildOutputAPIBuilder { dirs: ['src/pages', 'src/workflows'], }), buildTarget: 'vercel-build-output-api', + debugFilePrefix: '_', }); } diff --git a/packages/astro/src/plugin.ts b/packages/astro/src/plugin.ts index 8fdce1186..85005bf61 100644 --- a/packages/astro/src/plugin.ts +++ b/packages/astro/src/plugin.ts @@ -1,8 +1,7 @@ import { relative } from 'node:path'; import { transform } from '@swc/core'; import { resolveModulePath } from 'exsolve'; -import type { HotUpdateOptions, PluginOption } from 'vite'; -import type { AstroIntegration } from 'astro'; +import type { AstroIntegration, HookParameters } from 'astro'; import { LocalBuilder, VercelBuilder } from './builder.js'; export function workflow(): AstroIntegration { @@ -11,7 +10,9 @@ export function workflow(): AstroIntegration { return { name: 'workflow:astro', hooks: { - 'astro:config:setup': async ({ updateConfig }: any) => { + 'astro:config:setup': async ({ + updateConfig, + }: HookParameters<'astro:config:setup'>) => { // Use local builder if (!process.env.VERCEL_DEPLOYMENT_ID) { await builder.build(); @@ -20,7 +21,7 @@ export function workflow(): AstroIntegration { vite: { plugins: [ { - name: 'workflow:astro:vite', + name: 'workflow:vite', // TODO: Move this to @workflow/vite or something since this is vite specific // Transform workflow files with SWC @@ -109,7 +110,7 @@ export function workflow(): AstroIntegration { }, // TODO: Move this to @workflow/vite or something since this is vite specific - async hotUpdate(options: HotUpdateOptions) { + async hotUpdate(options) { const { file, server, read } = options; // Check if this is a TS/JS file that might contain workflow directives @@ -172,7 +173,7 @@ export function workflow(): AstroIntegration { // Prevent Vite from processing this HMR update return []; }, - } as PluginOption, + }, ], }, }); diff --git a/packages/builders/src/base-builder.ts b/packages/builders/src/base-builder.ts index 4319251d2..21d1c0000 100644 --- a/packages/builders/src/base-builder.ts +++ b/packages/builders/src/base-builder.ts @@ -1,5 +1,5 @@ import { mkdir, readFile, writeFile } from 'node:fs/promises'; -import { dirname, join, relative, resolve } from 'node:path'; +import { basename, dirname, join, relative, resolve } from 'node:path'; import { promisify } from 'node:util'; import chalk from 'chalk'; import { parse } from 'comment-json'; @@ -184,14 +184,17 @@ export abstract class BaseBuilder { merge?: boolean ): Promise { try { + const prefix = this.config.debugFilePrefix || ''; + const debugFileName = `${dirname(outfile)}/${prefix}${basename(outfile)}.debug.json`; + let existing = {}; if (merge) { existing = JSON.parse( - await readFile(`${outfile}.debug.json`, 'utf8').catch(() => '{}') + await readFile(debugFileName, 'utf8').catch(() => '{}') ); } await writeFile( - `${outfile}.debug.json`, + debugFileName, JSON.stringify( { ...existing, diff --git a/packages/builders/src/types.ts b/packages/builders/src/types.ts index d0db71912..87c0d5428 100644 --- a/packages/builders/src/types.ts +++ b/packages/builders/src/types.ts @@ -23,6 +23,9 @@ interface BaseWorkflowConfig { externalPackages?: string[]; workflowManifestPath?: string; + + // Optional prefix for debug files (e.g., "_" for Astro to ignore them) + debugFilePrefix?: string; } /** From c233221a508bb77934bba90160453940bb95e921 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 21 Nov 2025 12:15:34 -0800 Subject: [PATCH 55/61] lockfile --- pnpm-lock.yaml | 394 ++++++++++--------------------------------------- 1 file changed, 76 insertions(+), 318 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ec8a0d22c..985c68fa0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,9 +6,42 @@ settings: catalogs: default: + '@biomejs/biome': + specifier: ^2.2.7 + version: 2.3.3 '@types/node': specifier: 22.19.0 version: 22.19.0 + '@vercel/functions': + specifier: ^3.1.4 + version: 3.1.4 + '@vercel/oidc': + specifier: 3.0.5 + version: 3.0.5 + '@vercel/queue': + specifier: 0.0.0-alpha.29 + version: 0.0.0-alpha.29 + '@vitest/coverage-v8': + specifier: ^3.2.4 + version: 3.2.4 + ai: + specifier: 5.0.76 + version: 5.0.76 + esbuild: + specifier: ^0.25.11 + version: 0.25.12 + nitro: + specifier: 3.0.1-alpha.1 + version: 3.0.1-alpha.1 + typescript: + specifier: ^5.9.3 + version: 5.9.3 + vitest: + specifier: ^3.2.4 + version: 3.2.4 + zod: + specifier: 4.1.11 + version: 4.1.11 overrides: rfc6902: 5.1.2 @@ -29,7 +62,7 @@ importers: version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) esbuild: specifier: 'catalog:' - version: 0.25.11 + version: 0.25.12 husky: specifier: ^9.1.7 version: 9.1.7 @@ -309,9 +342,6 @@ importers: astro: specifier: 5.16.0 version: 5.16.0(@netlify/blobs@9.1.2)(@types/node@22.19.0)(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(db0@0.3.4(better-sqlite3@11.10.0)(drizzle-orm@0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)))(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.53.3)(terser@5.44.0)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1) - vite: - specifier: 7.1.11 - version: 7.1.11(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) packages/builders: dependencies: @@ -341,7 +371,7 @@ importers: version: 5.18.2 esbuild: specifier: 'catalog:' - version: 0.25.11 + version: 0.25.12 find-up: specifier: 7.0.0 version: 7.0.0 @@ -417,7 +447,7 @@ importers: version: 5.18.2 esbuild: specifier: 'catalog:' - version: 0.25.11 + version: 0.25.12 find-up: specifier: 7.0.0 version: 7.0.0 @@ -627,7 +657,7 @@ importers: devDependencies: '@nuxt/module-builder': specifier: 1.0.2 - version: 1.0.2(@nuxt/cli@3.29.3(magicast@0.3.5))(@vue/compiler-core@3.5.22)(esbuild@0.25.11)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3)) + version: 1.0.2(@nuxt/cli@3.29.3(magicast@0.3.5))(@vue/compiler-core@3.5.22)(esbuild@0.25.12)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3)) '@nuxt/schema': specifier: 4.2.0 version: 4.2.0 @@ -1155,7 +1185,7 @@ importers: version: link:../../packages/cli esbuild: specifier: 'catalog:' - version: 0.25.11 + version: 0.25.12 workbench/express: dependencies: @@ -2050,12 +2080,6 @@ packages: resolution: {integrity: sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==} deprecated: 'Merged into tsx: https://tsx.is' - '@esbuild/aix-ppc64@0.25.11': - resolution: {integrity: sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - '@esbuild/aix-ppc64@0.25.12': resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} engines: {node: '>=18'} @@ -2074,12 +2098,6 @@ packages: cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.25.11': - resolution: {integrity: sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - '@esbuild/android-arm64@0.25.12': resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} engines: {node: '>=18'} @@ -2098,12 +2116,6 @@ packages: cpu: [arm] os: [android] - '@esbuild/android-arm@0.25.11': - resolution: {integrity: sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - '@esbuild/android-arm@0.25.12': resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} engines: {node: '>=18'} @@ -2122,12 +2134,6 @@ packages: cpu: [x64] os: [android] - '@esbuild/android-x64@0.25.11': - resolution: {integrity: sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - '@esbuild/android-x64@0.25.12': resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} engines: {node: '>=18'} @@ -2146,12 +2152,6 @@ packages: cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.25.11': - resolution: {integrity: sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - '@esbuild/darwin-arm64@0.25.12': resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} engines: {node: '>=18'} @@ -2170,12 +2170,6 @@ packages: cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.25.11': - resolution: {integrity: sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - '@esbuild/darwin-x64@0.25.12': resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} engines: {node: '>=18'} @@ -2194,12 +2188,6 @@ packages: cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.25.11': - resolution: {integrity: sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - '@esbuild/freebsd-arm64@0.25.12': resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} engines: {node: '>=18'} @@ -2218,12 +2206,6 @@ packages: cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.25.11': - resolution: {integrity: sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - '@esbuild/freebsd-x64@0.25.12': resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} engines: {node: '>=18'} @@ -2242,12 +2224,6 @@ packages: cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.25.11': - resolution: {integrity: sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - '@esbuild/linux-arm64@0.25.12': resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} engines: {node: '>=18'} @@ -2266,12 +2242,6 @@ packages: cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.25.11': - resolution: {integrity: sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - '@esbuild/linux-arm@0.25.12': resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} engines: {node: '>=18'} @@ -2290,12 +2260,6 @@ packages: cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.25.11': - resolution: {integrity: sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - '@esbuild/linux-ia32@0.25.12': resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} engines: {node: '>=18'} @@ -2314,12 +2278,6 @@ packages: cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.25.11': - resolution: {integrity: sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - '@esbuild/linux-loong64@0.25.12': resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} engines: {node: '>=18'} @@ -2338,12 +2296,6 @@ packages: cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.25.11': - resolution: {integrity: sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - '@esbuild/linux-mips64el@0.25.12': resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} engines: {node: '>=18'} @@ -2362,12 +2314,6 @@ packages: cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.25.11': - resolution: {integrity: sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - '@esbuild/linux-ppc64@0.25.12': resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} engines: {node: '>=18'} @@ -2386,12 +2332,6 @@ packages: cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.25.11': - resolution: {integrity: sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - '@esbuild/linux-riscv64@0.25.12': resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} engines: {node: '>=18'} @@ -2410,12 +2350,6 @@ packages: cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.25.11': - resolution: {integrity: sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - '@esbuild/linux-s390x@0.25.12': resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} engines: {node: '>=18'} @@ -2434,12 +2368,6 @@ packages: cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.25.11': - resolution: {integrity: sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - '@esbuild/linux-x64@0.25.12': resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} engines: {node: '>=18'} @@ -2452,12 +2380,6 @@ packages: cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.25.11': - resolution: {integrity: sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - '@esbuild/netbsd-arm64@0.25.12': resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} engines: {node: '>=18'} @@ -2476,12 +2398,6 @@ packages: cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.25.11': - resolution: {integrity: sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - '@esbuild/netbsd-x64@0.25.12': resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} engines: {node: '>=18'} @@ -2494,12 +2410,6 @@ packages: cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.25.11': - resolution: {integrity: sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - '@esbuild/openbsd-arm64@0.25.12': resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} engines: {node: '>=18'} @@ -2518,12 +2428,6 @@ packages: cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.25.11': - resolution: {integrity: sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - '@esbuild/openbsd-x64@0.25.12': resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} engines: {node: '>=18'} @@ -2536,12 +2440,6 @@ packages: cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.25.11': - resolution: {integrity: sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - '@esbuild/openharmony-arm64@0.25.12': resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} engines: {node: '>=18'} @@ -2554,12 +2452,6 @@ packages: cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.25.11': - resolution: {integrity: sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - '@esbuild/sunos-x64@0.25.12': resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} engines: {node: '>=18'} @@ -2578,12 +2470,6 @@ packages: cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.25.11': - resolution: {integrity: sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - '@esbuild/win32-arm64@0.25.12': resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} engines: {node: '>=18'} @@ -2602,12 +2488,6 @@ packages: cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.25.11': - resolution: {integrity: sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - '@esbuild/win32-ia32@0.25.12': resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} engines: {node: '>=18'} @@ -2626,12 +2506,6 @@ packages: cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.25.11': - resolution: {integrity: sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - '@esbuild/win32-x64@0.25.12': resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} engines: {node: '>=18'} @@ -8276,11 +8150,6 @@ packages: engines: {node: '>=12'} hasBin: true - esbuild@0.25.11: - resolution: {integrity: sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==} - engines: {node: '>=18'} - hasBin: true - esbuild@0.25.12: resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} engines: {node: '>=18'} @@ -13306,7 +13175,7 @@ snapshots: '@astrojs/telemetry@3.3.0': dependencies: ci-info: 4.3.1 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) dlv: 1.1.3 dset: 3.1.4 is-docker: 3.0.0 @@ -14136,9 +14005,6 @@ snapshots: '@esbuild-kit/core-utils': 3.3.2 get-tsconfig: 4.12.0 - '@esbuild/aix-ppc64@0.25.11': - optional: true - '@esbuild/aix-ppc64@0.25.12': optional: true @@ -14148,9 +14014,6 @@ snapshots: '@esbuild/android-arm64@0.18.20': optional: true - '@esbuild/android-arm64@0.25.11': - optional: true - '@esbuild/android-arm64@0.25.12': optional: true @@ -14160,9 +14023,6 @@ snapshots: '@esbuild/android-arm@0.18.20': optional: true - '@esbuild/android-arm@0.25.11': - optional: true - '@esbuild/android-arm@0.25.12': optional: true @@ -14172,9 +14032,6 @@ snapshots: '@esbuild/android-x64@0.18.20': optional: true - '@esbuild/android-x64@0.25.11': - optional: true - '@esbuild/android-x64@0.25.12': optional: true @@ -14184,9 +14041,6 @@ snapshots: '@esbuild/darwin-arm64@0.18.20': optional: true - '@esbuild/darwin-arm64@0.25.11': - optional: true - '@esbuild/darwin-arm64@0.25.12': optional: true @@ -14196,9 +14050,6 @@ snapshots: '@esbuild/darwin-x64@0.18.20': optional: true - '@esbuild/darwin-x64@0.25.11': - optional: true - '@esbuild/darwin-x64@0.25.12': optional: true @@ -14208,9 +14059,6 @@ snapshots: '@esbuild/freebsd-arm64@0.18.20': optional: true - '@esbuild/freebsd-arm64@0.25.11': - optional: true - '@esbuild/freebsd-arm64@0.25.12': optional: true @@ -14220,9 +14068,6 @@ snapshots: '@esbuild/freebsd-x64@0.18.20': optional: true - '@esbuild/freebsd-x64@0.25.11': - optional: true - '@esbuild/freebsd-x64@0.25.12': optional: true @@ -14232,9 +14077,6 @@ snapshots: '@esbuild/linux-arm64@0.18.20': optional: true - '@esbuild/linux-arm64@0.25.11': - optional: true - '@esbuild/linux-arm64@0.25.12': optional: true @@ -14244,9 +14086,6 @@ snapshots: '@esbuild/linux-arm@0.18.20': optional: true - '@esbuild/linux-arm@0.25.11': - optional: true - '@esbuild/linux-arm@0.25.12': optional: true @@ -14256,9 +14095,6 @@ snapshots: '@esbuild/linux-ia32@0.18.20': optional: true - '@esbuild/linux-ia32@0.25.11': - optional: true - '@esbuild/linux-ia32@0.25.12': optional: true @@ -14268,9 +14104,6 @@ snapshots: '@esbuild/linux-loong64@0.18.20': optional: true - '@esbuild/linux-loong64@0.25.11': - optional: true - '@esbuild/linux-loong64@0.25.12': optional: true @@ -14280,9 +14113,6 @@ snapshots: '@esbuild/linux-mips64el@0.18.20': optional: true - '@esbuild/linux-mips64el@0.25.11': - optional: true - '@esbuild/linux-mips64el@0.25.12': optional: true @@ -14292,9 +14122,6 @@ snapshots: '@esbuild/linux-ppc64@0.18.20': optional: true - '@esbuild/linux-ppc64@0.25.11': - optional: true - '@esbuild/linux-ppc64@0.25.12': optional: true @@ -14304,9 +14131,6 @@ snapshots: '@esbuild/linux-riscv64@0.18.20': optional: true - '@esbuild/linux-riscv64@0.25.11': - optional: true - '@esbuild/linux-riscv64@0.25.12': optional: true @@ -14316,9 +14140,6 @@ snapshots: '@esbuild/linux-s390x@0.18.20': optional: true - '@esbuild/linux-s390x@0.25.11': - optional: true - '@esbuild/linux-s390x@0.25.12': optional: true @@ -14328,18 +14149,12 @@ snapshots: '@esbuild/linux-x64@0.18.20': optional: true - '@esbuild/linux-x64@0.25.11': - optional: true - '@esbuild/linux-x64@0.25.12': optional: true '@esbuild/linux-x64@0.25.5': optional: true - '@esbuild/netbsd-arm64@0.25.11': - optional: true - '@esbuild/netbsd-arm64@0.25.12': optional: true @@ -14349,18 +14164,12 @@ snapshots: '@esbuild/netbsd-x64@0.18.20': optional: true - '@esbuild/netbsd-x64@0.25.11': - optional: true - '@esbuild/netbsd-x64@0.25.12': optional: true '@esbuild/netbsd-x64@0.25.5': optional: true - '@esbuild/openbsd-arm64@0.25.11': - optional: true - '@esbuild/openbsd-arm64@0.25.12': optional: true @@ -14370,27 +14179,18 @@ snapshots: '@esbuild/openbsd-x64@0.18.20': optional: true - '@esbuild/openbsd-x64@0.25.11': - optional: true - '@esbuild/openbsd-x64@0.25.12': optional: true '@esbuild/openbsd-x64@0.25.5': optional: true - '@esbuild/openharmony-arm64@0.25.11': - optional: true - '@esbuild/openharmony-arm64@0.25.12': optional: true '@esbuild/sunos-x64@0.18.20': optional: true - '@esbuild/sunos-x64@0.25.11': - optional: true - '@esbuild/sunos-x64@0.25.12': optional: true @@ -14400,9 +14200,6 @@ snapshots: '@esbuild/win32-arm64@0.18.20': optional: true - '@esbuild/win32-arm64@0.25.11': - optional: true - '@esbuild/win32-arm64@0.25.12': optional: true @@ -14412,9 +14209,6 @@ snapshots: '@esbuild/win32-ia32@0.18.20': optional: true - '@esbuild/win32-ia32@0.25.11': - optional: true - '@esbuild/win32-ia32@0.25.12': optional: true @@ -14424,9 +14218,6 @@ snapshots: '@esbuild/win32-x64@0.18.20': optional: true - '@esbuild/win32-x64@0.25.11': - optional: true - '@esbuild/win32-x64@0.25.12': optional: true @@ -15381,7 +15172,7 @@ snapshots: transitivePeerDependencies: - magicast - '@nuxt/module-builder@1.0.2(@nuxt/cli@3.29.3(magicast@0.3.5))(@vue/compiler-core@3.5.22)(esbuild@0.25.11)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3))': + '@nuxt/module-builder@1.0.2(@nuxt/cli@3.29.3(magicast@0.3.5))(@vue/compiler-core@3.5.22)(esbuild@0.25.12)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3))': dependencies: '@nuxt/cli': 3.29.3(magicast@0.3.5) citty: 0.1.6 @@ -15389,14 +15180,14 @@ snapshots: defu: 6.1.4 jiti: 2.6.1 magic-regexp: 0.10.0 - mkdist: 2.4.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.11)(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) + mkdist: 2.4.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.12)(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) mlly: 1.8.0 pathe: 2.0.3 pkg-types: 2.3.0 tsconfck: 3.1.6(typescript@5.9.3) typescript: 5.9.3 - unbuild: 3.6.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.11)(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) - vue-sfc-transformer: 0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.11)(vue@3.5.22(typescript@5.9.3)) + unbuild: 3.6.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.12)(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) + vue-sfc-transformer: 0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.12)(vue@3.5.22(typescript@5.9.3)) transitivePeerDependencies: - '@vue/compiler-core' - esbuild @@ -15457,7 +15248,7 @@ snapshots: consola: 3.4.2 cssnano: 7.1.1(postcss@8.5.6) defu: 6.1.4 - esbuild: 0.25.11 + esbuild: 0.25.12 escape-string-regexp: 5.0.0 exsolve: 1.0.7 get-port-please: 3.2.0 @@ -15542,14 +15333,14 @@ snapshots: consola: 3.4.2 cssnano: 7.1.1(postcss@8.5.6) defu: 6.1.4 - esbuild: 0.25.11 + esbuild: 0.25.12 escape-string-regexp: 5.0.0 exsolve: 1.0.7 get-port-please: 3.2.0 h3: 1.15.4 jiti: 2.6.1 knitwork: 1.2.0 - magic-string: 0.30.19 + magic-string: 0.30.21 mlly: 1.8.0 mocked-exports: 0.1.1 pathe: 2.0.3 @@ -17538,7 +17329,7 @@ snapshots: estree-walker: 2.0.2 fdir: 6.5.0(picomatch@4.0.3) is-reference: 1.2.1 - magic-string: 0.30.19 + magic-string: 0.30.21 picomatch: 4.0.3 optionalDependencies: rollup: 4.52.5 @@ -17559,7 +17350,7 @@ snapshots: dependencies: '@rollup/pluginutils': 5.3.0(rollup@4.52.5) estree-walker: 2.0.2 - magic-string: 0.30.19 + magic-string: 0.30.21 optionalDependencies: rollup: 4.52.5 @@ -17567,7 +17358,7 @@ snapshots: dependencies: '@rollup/pluginutils': 5.3.0(rollup@4.53.3) estree-walker: 2.0.2 - magic-string: 0.30.19 + magic-string: 0.30.21 optionalDependencies: rollup: 4.53.3 @@ -17606,14 +17397,14 @@ snapshots: '@rollup/plugin-replace@6.0.2(rollup@4.52.5)': dependencies: '@rollup/pluginutils': 5.3.0(rollup@4.52.5) - magic-string: 0.30.19 + magic-string: 0.30.21 optionalDependencies: rollup: 4.52.5 '@rollup/plugin-replace@6.0.2(rollup@4.53.3)': dependencies: '@rollup/pluginutils': 5.3.0(rollup@4.53.3) - magic-string: 0.30.19 + magic-string: 0.30.21 optionalDependencies: rollup: 4.53.3 @@ -18177,7 +17968,7 @@ snapshots: dependencies: '@sveltejs/kit': 2.48.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)))(svelte@5.43.3)(vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) '@vercel/nft': 0.30.3(rollup@4.53.3) - esbuild: 0.25.11 + esbuild: 0.25.12 transitivePeerDependencies: - encoding - rollup @@ -19413,7 +19204,7 @@ snapshots: common-ancestor-path: 1.0.1 cookie: 1.0.2 cssesc: 3.0.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) deterministic-object-hash: 2.0.2 devalue: 5.5.0 diff: 5.2.0 @@ -20451,10 +20242,6 @@ snapshots: better-sqlite3: 11.10.0 drizzle-orm: 0.44.7(@opentelemetry/api@1.9.0)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7) - debug@4.4.3: - dependencies: - ms: 2.1.3 - debug@4.4.3(supports-color@8.1.1): dependencies: ms: 2.1.3 @@ -20680,8 +20467,8 @@ snapshots: dependencies: '@drizzle-team/brocli': 0.10.2 '@esbuild-kit/esm-loader': 2.6.5 - esbuild: 0.25.11 - esbuild-register: 3.6.0(esbuild@0.25.11) + esbuild: 0.25.12 + esbuild-register: 3.6.0(esbuild@0.25.12) transitivePeerDependencies: - supports-color @@ -20801,10 +20588,10 @@ snapshots: esast-util-from-estree: 2.0.0 vfile-message: 4.0.3 - esbuild-register@3.6.0(esbuild@0.25.11): + esbuild-register@3.6.0(esbuild@0.25.12): dependencies: debug: 4.4.3(supports-color@8.1.1) - esbuild: 0.25.11 + esbuild: 0.25.12 transitivePeerDependencies: - supports-color @@ -20833,35 +20620,6 @@ snapshots: '@esbuild/win32-ia32': 0.18.20 '@esbuild/win32-x64': 0.18.20 - esbuild@0.25.11: - optionalDependencies: - '@esbuild/aix-ppc64': 0.25.11 - '@esbuild/android-arm': 0.25.11 - '@esbuild/android-arm64': 0.25.11 - '@esbuild/android-x64': 0.25.11 - '@esbuild/darwin-arm64': 0.25.11 - '@esbuild/darwin-x64': 0.25.11 - '@esbuild/freebsd-arm64': 0.25.11 - '@esbuild/freebsd-x64': 0.25.11 - '@esbuild/linux-arm': 0.25.11 - '@esbuild/linux-arm64': 0.25.11 - '@esbuild/linux-ia32': 0.25.11 - '@esbuild/linux-loong64': 0.25.11 - '@esbuild/linux-mips64el': 0.25.11 - '@esbuild/linux-ppc64': 0.25.11 - '@esbuild/linux-riscv64': 0.25.11 - '@esbuild/linux-s390x': 0.25.11 - '@esbuild/linux-x64': 0.25.11 - '@esbuild/netbsd-arm64': 0.25.11 - '@esbuild/netbsd-x64': 0.25.11 - '@esbuild/openbsd-arm64': 0.25.11 - '@esbuild/openbsd-x64': 0.25.11 - '@esbuild/openharmony-arm64': 0.25.11 - '@esbuild/sunos-x64': 0.25.11 - '@esbuild/win32-arm64': 0.25.11 - '@esbuild/win32-ia32': 0.25.11 - '@esbuild/win32-x64': 0.25.11 - esbuild@0.25.12: optionalDependencies: '@esbuild/aix-ppc64': 0.25.12 @@ -21969,7 +21727,7 @@ snapshots: dependencies: '@ioredis/commands': 1.4.0 cluster-key-slot: 1.1.2 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) denque: 2.1.0 lodash.defaults: 4.2.0 lodash.isarguments: 3.1.0 @@ -22992,7 +22750,7 @@ snapshots: micromark@4.0.2: dependencies: '@types/debug': 4.1.12 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) decode-named-character-reference: 1.2.0 devlop: 1.1.0 micromark-core-commonmark: 2.0.3 @@ -23069,7 +22827,7 @@ snapshots: mkdirp@3.0.1: {} - mkdist@2.4.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.11)(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)): + mkdist@2.4.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.12)(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)): dependencies: autoprefixer: 10.4.21(postcss@8.5.6) citty: 0.1.6 @@ -23087,7 +22845,7 @@ snapshots: optionalDependencies: typescript: 5.9.3 vue: 3.5.22(typescript@5.9.3) - vue-sfc-transformer: 0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.11)(vue@3.5.22(typescript@5.9.3)) + vue-sfc-transformer: 0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.12)(vue@3.5.22(typescript@5.9.3)) mlly@1.8.0: dependencies: @@ -23453,7 +23211,7 @@ snapshots: defu: 6.1.4 destr: 2.0.5 dot-prop: 9.0.0 - esbuild: 0.25.11 + esbuild: 0.25.12 escape-string-regexp: 5.0.0 etag: 1.8.1 exsolve: 1.0.7 @@ -23555,7 +23313,7 @@ snapshots: defu: 6.1.4 destr: 2.0.5 dot-prop: 10.1.0 - esbuild: 0.25.11 + esbuild: 0.25.12 escape-string-regexp: 5.0.0 etag: 1.8.1 exsolve: 1.0.7 @@ -23722,7 +23480,7 @@ snapshots: destr: 2.0.5 devalue: 5.5.0 errx: 0.1.0 - esbuild: 0.25.11 + esbuild: 0.25.12 escape-string-regexp: 5.0.0 estree-walker: 3.0.3 exsolve: 1.0.7 @@ -23848,7 +23606,7 @@ snapshots: destr: 2.0.5 devalue: 5.5.0 errx: 0.1.0 - esbuild: 0.25.11 + esbuild: 0.25.12 escape-string-regexp: 5.0.0 estree-walker: 3.0.3 exsolve: 1.0.7 @@ -26304,7 +26062,7 @@ snapshots: ultrahtml@1.6.0: {} - unbuild@3.6.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.11)(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)): + unbuild@3.6.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.12)(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)): dependencies: '@rollup/plugin-alias': 5.1.1(rollup@4.53.3) '@rollup/plugin-commonjs': 28.0.9(rollup@4.53.3) @@ -26320,7 +26078,7 @@ snapshots: hookable: 5.5.3 jiti: 2.6.1 magic-string: 0.30.21 - mkdist: 2.4.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.11)(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) + mkdist: 2.4.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.12)(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) mlly: 1.8.0 pathe: 2.0.3 pkg-types: 2.3.0 @@ -26526,7 +26284,7 @@ snapshots: chokidar: 4.0.3 json5: 2.2.3 local-pkg: 1.1.2 - magic-string: 0.30.19 + magic-string: 0.30.21 mlly: 1.8.0 muggle-string: 0.4.1 pathe: 2.0.3 @@ -26608,7 +26366,7 @@ snapshots: unwasm@0.3.11: dependencies: knitwork: 1.2.0 - magic-string: 0.30.19 + magic-string: 0.30.21 mlly: 1.8.0 pathe: 2.0.3 pkg-types: 2.3.0 @@ -26895,7 +26653,7 @@ snapshots: vite@7.1.11(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): dependencies: - esbuild: 0.25.11 + esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 @@ -26912,7 +26670,7 @@ snapshots: vite@7.1.12(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): dependencies: - esbuild: 0.25.11 + esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 @@ -26929,7 +26687,7 @@ snapshots: vite@7.1.12(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): dependencies: - esbuild: 0.25.11 + esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 @@ -26946,7 +26704,7 @@ snapshots: vite@7.2.4(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): dependencies: - esbuild: 0.25.11 + esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 @@ -26963,7 +26721,7 @@ snapshots: vite@7.2.4(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): dependencies: - esbuild: 0.25.11 + esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 @@ -27115,11 +26873,11 @@ snapshots: '@vue/devtools-api': 6.6.4 vue: 3.5.22(typescript@5.9.3) - vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.11)(vue@3.5.22(typescript@5.9.3)): + vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.22)(esbuild@0.25.12)(vue@3.5.22(typescript@5.9.3)): dependencies: '@babel/parser': 7.28.5 '@vue/compiler-core': 3.5.22 - esbuild: 0.25.11 + esbuild: 0.25.12 vue: 3.5.22(typescript@5.9.3) vue@3.5.22(typescript@5.9.3): From 70f0d4b1b03ad47f352af183f3444f492e4c9bbf Mon Sep 17 00:00:00 2001 From: Adrian Date: Fri, 21 Nov 2025 12:56:29 -0800 Subject: [PATCH 56/61] Update packages/astro/src/plugin.ts Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com> --- packages/astro/src/plugin.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/astro/src/plugin.ts b/packages/astro/src/plugin.ts index 85005bf61..b96506ab8 100644 --- a/packages/astro/src/plugin.ts +++ b/packages/astro/src/plugin.ts @@ -15,7 +15,14 @@ export function workflow(): AstroIntegration { }: HookParameters<'astro:config:setup'>) => { // Use local builder if (!process.env.VERCEL_DEPLOYMENT_ID) { - await builder.build(); + try { + await builder.build(); + } catch (buildError) { + // Build might fail due to invalid workflow files or missing dependencies + // Log the error and rethrow to properly propagate to Astro + console.error('Build failed during config setup:', buildError); + throw buildError; + } } updateConfig({ vite: { From c5658f727232cf9c3c714eddea075465246ed799 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 21 Nov 2025 12:59:38 -0800 Subject: [PATCH 57/61] test: add astro to cross file test --- packages/core/e2e/e2e.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/core/e2e/e2e.test.ts b/packages/core/e2e/e2e.test.ts index 27cfaeba3..0ac6e71dc 100644 --- a/packages/core/e2e/e2e.test.ts +++ b/packages/core/e2e/e2e.test.ts @@ -600,7 +600,8 @@ describe('e2e', () => { // TODO: Investigate esbuild source map generation for bundled modules const isViteBasedFrameworkDevMode = (process.env.APP_NAME === 'sveltekit' || - process.env.APP_NAME === 'vite') && + process.env.APP_NAME === 'vite' || + process.env.APP_NAME === 'astro') && isLocalDeployment(); if (!isViteBasedFrameworkDevMode) { From 54b4be40f113a24b90c435ec2e26bcb9726af112 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 21 Nov 2025 13:06:28 -0800 Subject: [PATCH 58/61] fix astro symlink --- workbench/astro/src/pages/index.astro | 2 +- workbench/astro/src/workflows | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/workbench/astro/src/pages/index.astro b/workbench/astro/src/pages/index.astro index 45a53644c..c7991c7a3 100644 --- a/workbench/astro/src/pages/index.astro +++ b/workbench/astro/src/pages/index.astro @@ -76,7 +76,7 @@ async function main() { const { runId } = await fetchAndLog( - "/api/trigger?workflowFile=workflows/0_calc.ts&workflowFn=calc&args=2", + "/api/trigger?workflowFile=workflows/0_demo.ts&workflowFn=calc&args=2", { method: "POST", headers: { "Content-Type": "application/json" }, diff --git a/workbench/astro/src/workflows b/workbench/astro/src/workflows index 13ef4d4f6..5cdd2a9ca 120000 --- a/workbench/astro/src/workflows +++ b/workbench/astro/src/workflows @@ -1 +1 @@ -../../example/workflows \ No newline at end of file +../../nitro-v3/workflows \ No newline at end of file From 514ca35640ce1db6cf0970d7eb33d79b2ab57522 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 21 Nov 2025 13:07:01 -0800 Subject: [PATCH 59/61] remove example worklfow hack --- workbench/example/workflows/0_calc.ts | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 workbench/example/workflows/0_calc.ts diff --git a/workbench/example/workflows/0_calc.ts b/workbench/example/workflows/0_calc.ts deleted file mode 100644 index 3323945e6..000000000 --- a/workbench/example/workflows/0_calc.ts +++ /dev/null @@ -1,15 +0,0 @@ -// import { FatalError } from 'workflow'; - -export async function calc(n: number) { - 'use workflow'; - console.log('Simple workflow started'); - n = await pow(n); - console.log('Simple workflow finished'); - return n; -} - -async function pow(a: number): Promise { - 'use step'; - console.log('Running step pow with arg:', a); - return a * a; -} From 85ce395494a169aaae51ced47f11fb9be5ccbf5e Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 21 Nov 2025 13:27:51 -0800 Subject: [PATCH 60/61] fix symlink --- workbench/astro/src/workflows | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workbench/astro/src/workflows b/workbench/astro/src/workflows index 5cdd2a9ca..8a9aab9c9 120000 --- a/workbench/astro/src/workflows +++ b/workbench/astro/src/workflows @@ -1 +1 @@ -../../nitro-v3/workflows \ No newline at end of file +../../sveltekit/src/workflows \ No newline at end of file From cdfbe27666ff8ad7bcbb44474d701ffae9bab85c Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Fri, 21 Nov 2025 13:33:18 -0800 Subject: [PATCH 61/61] fix index astrofile --- workbench/astro/src/pages/index.astro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workbench/astro/src/pages/index.astro b/workbench/astro/src/pages/index.astro index c7991c7a3..45a53644c 100644 --- a/workbench/astro/src/pages/index.astro +++ b/workbench/astro/src/pages/index.astro @@ -76,7 +76,7 @@ async function main() { const { runId } = await fetchAndLog( - "/api/trigger?workflowFile=workflows/0_demo.ts&workflowFn=calc&args=2", + "/api/trigger?workflowFile=workflows/0_calc.ts&workflowFn=calc&args=2", { method: "POST", headers: { "Content-Type": "application/json" },